kst-2.0.3/cmake/CMakeLists.txt.user000644 001750 001750 00000053566 11544160206 017504 0ustar00synthsynth000000 000000 ProjectExplorer.Project.ActiveTarget 0 ProjectExplorer.Project.EditorSettings System ProjectExplorer.Project.Target.0 Desktop CMakeProjectManager.DefaultCMakeTarget 0 0 /home/synth/sandbox/kst/_cmake false Make CMakeProjectManager.MakeStep 1 clean true Make CMakeProjectManager.MakeStep 1 false all CMakeProjectManager.CMakeBuildConfiguration 1 2 false false $BUILDDIR Benutzerdefinierte, ausführbare Datei ProjectExplorer.CustomExecutableRunConfiguration 2 kst2 /home/synth/sandbox/kst/_cmake/build/bin/kst2 false /home/synth/sandbox/kst/_cmake/build/bin kst2 CMakeProjectManager.CMakeRunConfiguration. 2 test_labelparser /home/synth/sandbox/kst/_cmake/build/bin/test_labelparser false /home/synth/sandbox/kst/_cmake/build/bin test_labelparser CMakeProjectManager.CMakeRunConfiguration. 2 test_matrix /home/synth/sandbox/kst/_cmake/build/bin/test_matrix false /home/synth/sandbox/kst/_cmake/build/bin test_matrix CMakeProjectManager.CMakeRunConfiguration. 2 test_objectstore /home/synth/sandbox/kst/_cmake/build/bin/test_objectstore false /home/synth/sandbox/kst/_cmake/build/bin test_objectstore CMakeProjectManager.CMakeRunConfiguration. 2 test_psd /home/synth/sandbox/kst/_cmake/build/bin/test_psd false /home/synth/sandbox/kst/_cmake/build/bin test_psd CMakeProjectManager.CMakeRunConfiguration. 2 test_scalar /home/synth/sandbox/kst/_cmake/build/bin/test_scalar false /home/synth/sandbox/kst/_cmake/build/bin test_scalar CMakeProjectManager.CMakeRunConfiguration. 2 test_vector /home/synth/sandbox/kst/_cmake/build/bin/test_vector false /home/synth/sandbox/kst/_cmake/build/bin test_vector CMakeProjectManager.CMakeRunConfiguration. 2 test_csd /home/synth/sandbox/kst/_cmake/build/bin/test_csd false /home/synth/sandbox/kst/_cmake/build/bin test_csd CMakeProjectManager.CMakeRunConfiguration. 2 test_datamatrix /home/synth/sandbox/kst/_cmake/build/bin/test_datamatrix false /home/synth/sandbox/kst/_cmake/build/bin test_datamatrix CMakeProjectManager.CMakeRunConfiguration. 2 test_datasource /home/synth/sandbox/kst/_cmake/build/bin/test_datasource false /home/synth/sandbox/kst/_cmake/build/bin test_datasource CMakeProjectManager.CMakeRunConfiguration. 2 test_editablematrix /home/synth/sandbox/kst/_cmake/build/bin/test_editablematrix false /home/synth/sandbox/kst/_cmake/build/bin test_editablematrix CMakeProjectManager.CMakeRunConfiguration. 2 test_eqparser /home/synth/sandbox/kst/_cmake/build/bin/test_eqparser false /home/synth/sandbox/kst/_cmake/build/bin test_eqparser CMakeProjectManager.CMakeRunConfiguration. 2 test_generatedmatrix /home/synth/sandbox/kst/_cmake/build/bin/test_generatedmatrix false /home/synth/sandbox/kst/_cmake/build/bin test_generatedmatrix CMakeProjectManager.CMakeRunConfiguration. 2 test_generatedvector /home/synth/sandbox/kst/_cmake/build/bin/test_generatedvector false /home/synth/sandbox/kst/_cmake/build/bin test_generatedvector CMakeProjectManager.CMakeRunConfiguration. 2 test_histogram /home/synth/sandbox/kst/_cmake/build/bin/test_histogram false /home/synth/sandbox/kst/_cmake/build/bin test_histogram CMakeProjectManager.CMakeRunConfiguration. 16 ProjectExplorer.Project.TargetCount 1 ProjectExplorer.Project.Updater.FileVersion 4 kst-2.0.3/cmake/modules/FindGsl.cmake000644 001750 001750 00000002035 11544160206 017750 0ustar00synthsynth000000 000000 # use pkg to find the library name and pathes, # but use this iformation in find_* only include(FindPkgConfig) pkg_check_modules(PKGGSL QUIET gsl) if(NOT PKGGSL_LIBRARIES) set(PKGGSL_LIBRARIES gsl) if (UNIX) set(PKGGSL_LIBRARIES ${PKGGSL_LIBRARIES} m gslcblas) endif() endif() set(GSL_INCLUDEDIR GSL_INCLUDEDIR-NOTFOUND CACHE STRING "" FORCE) find_path(GSL_INCLUDEDIR gsl_version.h HINTS ENV GSL_DIR PATH_SUFFIXES include/gsl include PATHS ${kst_3rdparty_dir} ${PKGGSL_INCLUDEDIR}) foreach(it ${PKGGSL_LIBRARIES}) set(lib lib-NOTFOUND CACHE STRING "" FORCE) FIND_LIBRARY(lib ${it} HINTS ENV GSL_DIR PATH_SUFFIXES lib PATHS ${kst_3rdparty_dir} ${PKGGSL_LIBRARY_DIRS}) list(APPEND GSL_LIBRARIES ${lib}) endforeach() if(GSL_INCLUDEDIR AND GSL_LIBRARIES) set(GSL_INCLUDE_DIR ${GSL_INCLUDEDIR} ${GSL_INCLUDEDIR}/..) set(gsl 1) message(STATUS "Found Gsl:") message(STATUS " includes : ${GSL_INCLUDE_DIR}") message(STATUS " libraries: ${GSL_LIBRARIES}") else() message(STATUS "Not found: Gsl, set GSL_DIR") endif() kst-2.0.3/cmake/modules/FindDmc.cmake000644 001750 001750 00000002335 11544160206 017731 0ustar00synthsynth000000 000000 #include(FindPkgConfig) #pkg_check_modules(PostgreSQL libpq-dev) if(DMC_INCLUDEDIR AND DMC_LIBRARIES) set(DMC_LIBRARY -L${DMC_LIBRARY_DIRS} ${DMC_LIBRARIES}) else() set(DMC_INCLUDEDIR DMC_INCLUDEDIR-NOTFOUND CACHE STRING "" FORCE) FIND_PATH(PQ_DIR libpq-fe.h HINTS ENV PQ_DIR PATH_SUFFIXES include PATHS) FIND_PATH(PIO_DB PIODB.h HINTS ENV DMC_DIR PATH_SUFFIXES HL2_DMC include/HL2_DMC PATHS) FIND_PATH(PIO_ERR PIOErr.h HINTS ENV DMC_DIR PATH_SUFFIXES HL2_PIOLIB include/HL2_PIOLIB PATHS) if(PIO_DB AND PIO_ERR AND PQ_DIR) set(DMC_INCLUDEDIR ${PIO_DB}/..) endif() if(NOT PIO_DB STREQUAL PIO_ERR) set(DMC_INCLUDEDIR ${DMC_INCLUDEDIR} ${PIO_ERR}/..) endif() FIND_LIBRARY(DMC_LIBRARY piolib HINTS ENV DMC_DIR PATH_SUFFIXES lib lib/Linux-x86_64 PATHS) endif() #message(STATUS "PIO_DB ${PIO_DB}") #message(STATUS "PIO_ERR ${PIO_ERR}") #message(STATUS "PQ_H ${PQ_H}") IF(DMC_INCLUDEDIR AND DMC_LIBRARY AND PQ_DIR) MESSAGE(STATUS "DMC found at ${DMC_INCLUDEDIR}") SET(DMC_INCLUDE_DIR ${DMC_INCLUDEDIR} ${PQ_DIR}) SET(DMC_LIBRARIES ${DMC_LIBRARY}) SET(dmc 1) ELSE() MESSAGE(STATUS "DMC not found.") ENDIF() #message(STATUS "DMC: ${DMC_INCLUDEDIR}") #message(STATUS "DMC: ${DMC_LIBRARIES}") kst-2.0.3/cmake/modules/SubversionGenerator.cmake000644 001750 001750 00000003163 11544160206 022433 0ustar00synthsynth000000 000000 find_package(Subversion) if(SUBVERSION_FOUND) # try with 'svnversion' get_filename_component(svn_dir ${Subversion_SVN_EXECUTABLE} PATH) find_program(svnversion_bin svnversion PATH ${svn_dir}) if(svnversion_bin) execute_process( COMMAND ${svnversion_bin} ${source_dir} OUTPUT_VARIABLE _revision ERROR_VARIABLE _error RESULT_VARIABLE _result OUTPUT_STRIP_TRAILING_WHITESPACE) else() # extract revision Subversion_WC_INFO(${source_dir} src) set(_revision "${src_WC_REVISION}") # check for modifications execute_process( COMMAND ${Subversion_SVN_EXECUTABLE} status ${source_dir} OUTPUT_VARIABLE src_WC_STATUS ERROR_VARIABLE _error RESULT_VARIABLE _result OUTPUT_STRIP_TRAILING_WHITESPACE) # problems with multiple lines, # http://www.mail-archive.com/cmake@cmake.org/msg07254.html string(REGEX REPLACE "\r?\n" ";" lines "${src_WC_STATUS}") set(_modified) foreach(line ${lines}) string(REGEX MATCH "^(.*\n)?M ([^\n]+).*" _found "${line}") if(_found) #message(STATUS "Modified file: ${_found}") set(_modified ${_modified} _found) endif() endforeach() if(_modified) set(_revision "${_revision}${modified_str}") endif() endif() # write a file with the SVN_REVISION define file(WRITE ${header_file}.tmp "#define SVN_REVISION \"${_revision}\"\n") else() file(WRITE ${header_file}.tmp "#define SVN_REVISION \"unknown\"\n") endif() message(STATUS "Revision: ${_revision}") # copy the file to the final header only if # the version changes reduces needless rebuilds execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${header_file}.tmp ${header_file}) kst-2.0.3/cmake/modules/FindGetdata.cmake000644 001750 001750 00000003674 11544160206 020606 0ustar00synthsynth000000 000000 include(FindPkgConfig) pkg_check_modules(PKGGETDATA QUIET getdata>=0.6.0) #message(STATUS "GD inc: ${PKGGETDATA_INCLUDEDIR}") #message(STATUS "GD libs: ${PKGGETDATA_LIBRARIES}") # Apple: install getdata with --prefix /opt/local # FIXME: GETDATA_INCLUDEDIR AND GETDATA_LIBRARIES are set by pkg_check_modules, but # GETDATA_LIBRARY_C and GETDATA_LIBRARY_CPP are not. # Ubuntu: maybe /usr/local/lib/pkgconfig/getdata.pc is not correct #if(NOT PKGGETDATA_LIBRARIES) set(PKGGETDATA_LIBRARIES getdata++ getdata) if (UNIX) SET(PKGGETDATA_LIBRARIES ${PKGGETDATA_LIBRARIES} m) endif() #endif() set(GETDATA_INCLUDEDIR GETDATA_INCLUDEDIR-NOTFOUND CACHE STRING "" FORCE) FIND_PATH(GETDATA_INCLUDEDIR getdata.h HINTS ENV GETDATA_DIR PATH_SUFFIXES include/getdata include PATHS ${kst_3rdparty_dir} ${GETDATA_INCLUDEDIR}) foreach(it ${PKGGETDATA_LIBRARIES}) set(lib_release lib_release-NOTFOUND CACHE STRING "" FORCE) FIND_LIBRARY(lib_release ${it} HINTS ENV GETDATA_DIR PATH_SUFFIXES lib PATHS ${kst_3rdparty_dir} ${PKGGETDATA_LIBRARY_DIRS}) list(APPEND GETDATA_LIBRARIES_RELEASE ${lib_release}) list(APPEND GETDATA_LIBRARIES_BOTH optimized ${lib_release}) set(lib_debug lib_debug-NOTFOUND CACHE STRING "" FORCE) FIND_LIBRARY(lib_debug ${it}d HINTS ENV GETDATA_DIR PATH_SUFFIXES lib PATHS ${kst_3rdparty_dir} ${PKGGETDATA_LIBRARY_DIRS}) list(APPEND GETDATA_LIBRARIES_DEBUG ${lib_debug}) list(APPEND GETDATA_LIBRARIES_BOTH debug ${lib_debug}) endforeach() if(GETDATA_LIBRARIES_DEBUG AND GETDATA_LIBRARIES_RELEASE) set(GETDATA_LIBRARIES ${GETDATA_LIBRARIES_BOTH}) else() set(GETDATA_LIBRARIES ${GETDATA_LIBRARIES_RELEASE}) endif() IF(GETDATA_INCLUDEDIR AND GETDATA_INCLUDEDIR) SET(GETDATA_INCLUDE_DIR ${GETDATA_INCLUDEDIR}) SET(getdata 1) message(STATUS "Found GetData:") message(STATUS " includes : ${GETDATA_INCLUDE_DIR}") message(STATUS " libraries: ${GETDATA_LIBRARIES}") ELSE() MESSAGE(STATUS "Not found: Getdata, GETDATA_DIR") ENDIF() kst-2.0.3/cmake/modules/SubversionHeader.cmake000644 001750 001750 00000001071 11544160206 021671 0ustar00synthsynth000000 000000 macro(SubversionHeader source_dir target_name header_file modified_str) # a custom target that is always built # creates ${header_file} using SubversionGenerator.cmake script add_custom_target(${target_name} ALL COMMAND ${CMAKE_COMMAND} -Dsource_dir="${source_dir}" -Dheader_file="${header_file}" -Dmodified_str="${modified_str}" -P ${CMAKE_CURRENT_SOURCE_DIR}/modules/SubversionGenerator.cmake) # ${header_file} is a generated file set_source_files_properties(${header_file} PROPERTIES GENERATED TRUE HEADER_FILE_ONLY TRUE) endmacro() kst-2.0.3/cmake/modules/FindCFITSIO.cmake000644 001750 001750 00000002076 11544160206 020330 0ustar00synthsynth000000 000000 include(FindPkgConfig) pkg_check_modules(cfitsio QUIET cfitsio) if(CFITSIO_INCLUDEDIR AND CFITSIO_LIBRARIES) set(CFITSIO_LIBRARY -L${CFITSIO_LIBRARY_DIRS} ${CFITSIO_LIBRARIES}) else() set(CFITSIO_INCLUDEDIR CFITSIO_INCLUDEDIR-NOTFOUND CACHE STRING "" FORCE) FIND_PATH(CFITSIO_INCLUDEDIR fitsio.h HINTS ENV CFITSIO_DIR PATH_SUFFIXES include include/cfitsio include/libcfitsio0 PATHS ${kst_3rdparty_dir} ) FIND_LIBRARY(CFITSIO_LIBRARIES cfitsio HINTS ENV CFITSIO_DIR PATH_SUFFIXES lib PATHS ${kst_3rdparty_dir} ) endif() #message(STATUS "CFITSIO: ${CFITSIO_INCLUDEDIR}") #message(STATUS "CFITSIO: ${CFITSIO_LIBRARIES}") IF(CFITSIO_INCLUDEDIR AND CFITSIO_LIBRARIES) SET(CFITSIO_INCLUDE_DIR ${CFITSIO_INCLUDEDIR} ${CFITSIO_INCLUDEDIR}/..) if (UNIX) SET(CFITSIO_LIBRARIES ${CFITSIO_LIBRARIES} m) endif() SET(CFITSIO 1) SET(cfitsio 1) message(STATUS "Found CFITSIO:") message(STATUS " includes : ${CFITSIO_INCLUDE_DIR}") message(STATUS " libraries: ${CFITSIO_LIBRARIES}") ELSE() MESSAGE(STATUS "Not found: CFITSIO, set CFITSIO_DIR") ENDIF() kst-2.0.3/cmake/modules/KstPchSupport.cmake000644 001750 001750 00000005660 11544160206 021222 0ustar00synthsynth000000 000000 # Not supported officially my cmake # but there is a cmake ticket with examples # http://www.vtk.org/Bug/view.php?id=1260 # use this macro before # # _header : header to make a .gch # _sources: the variable name (do not use ${..}) which contains a # a list of sources (a.cpp b.cpp c.cpp ...) # This macro will append a header file to it, then this # src_list can be used in # # Now a .gch file should be generated and gcc should use it. # (add -Winvalid-pch to the cpp flags to verify) # # make clean should delete the pch file # # example : kst_add_pch_rule(pch.h source_list_name SHARED) macro(kst_add_pch_rule _header _sources _lib_type) if(CMAKE_COMPILER_IS_GNUCC) # first we have to find all compiler arguments get_directory_property(_definitions COMPILE_DEFINITIONS) foreach (_it ${_definitions}) list(APPEND _args "-D${_it}") endforeach() list(APPEND _args ${CMAKE_CXX_FLAGS}) if(CMAKE_BUILD_TYPE MATCHES Release) list(APPEND _args ${CMAKE_CXX_FLAGS_RELEASE}) get_directory_property(_definitions_type COMPILE_DEFINITIONS_RELEASE) else() list(APPEND _args ${CMAKE_CXX_FLAGS_DEBUG}) get_directory_property(_definitions_type COMPILE_DEFINITIONS_DEBUG) endif() if(${_lib_type} MATCHES SHARED) list(APPEND _args ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) endif() list(APPEND _args -D${_definitions_type}) #message(STATUS "pch: ${_args}") get_directory_property(DIRINC INCLUDE_DIRECTORIES) foreach (_inc ${DIRINC}) LIST(APPEND _args "-I" ${_inc}) endforeach(_inc ${DIRINC}) set(_gch_filename "${_header}.gch") list(APPEND ${_sources} ${_gch_filename}) list(APPEND _args -c ${_header} -o ${_gch_filename}) separate_arguments(_args) # now build the pch with the compiler arguments add_custom_command(OUTPUT ${_gch_filename} COMMAND ${CMAKE_COMMAND} -E remove ${_gch_filename} COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${_args} DEPENDS ${_header}) # all other files should use the pch set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Winvalid-pch -include ${_header}") else() file(WRITE ${_header}.tmp "#include \"${_header}\"\n") execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${_header}.tmp ${_header}.cpp) if(MSVC_IDE) set(use_pch "/Fp${_header}.\$(Configuration).pch") else() set(use_pch /Fp${_header}.pch) endif() set_source_files_properties(${_header}.cpp PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" ${use_pch}") # Bug in cmake: next line also compile .c files with pchs #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FI${_header} /Yu${_header} ${use_pch}") foreach(it ${${_sources}}) get_filename_component(ext ${it} EXT) if(ext STREQUAL .c) else() set_source_files_properties(${it} PROPERTIES COMPILE_FLAGS "/FI${_header} /Yu${_header} ${use_pch}") endif() endforeach() list(APPEND ${_sources} ${_header} ${_header}.cpp) endif() endmacro() kst-2.0.3/cmake/modules/KstMacros.cmake000644 001750 001750 00000022216 11544160206 020333 0ustar00synthsynth000000 000000 include(MergedFilesBuild) include(KstPchSupport) macro(kst_dbg) foreach(it ${ARGN}) message(STATUS "dgb: ${it} = ${${it}}") endforeach() endmacro() macro(kst_init prefix name_base) set(kst_name ${prefix}${name_base}) set(kst_name_base ${name_base}) set(kst_${kst_name}_dont_merge) set(kst_${kst_name}_ignore) set(kst_${kst_name}_info_files) endmacro() macro(kst_revision_project_name name) set(kst_revision_project ${name}) endmacro() macro(kst_revision_add_dependency) if(kst_revision_project) add_dependencies(${kst_name} ${kst_revision_project}) endif() endmacro() macro(kst_files_find folder) set(_folder ${kst_dir}/${folder}) file(GLOB _sources ${_folder}/*.c) file(GLOB _sources_cpp ${_folder}/*.cpp) file(GLOB _headers ${_folder}/*.h) file(GLOB _ui_files ${_folder}/*.ui) set(kst_${kst_name}_folder ${_folder}) kst_files_remove(_sources ${kst_${kst_name}_ignore}) kst_files_remove(_sources_cpp ${kst_${kst_name}_ignore}) kst_files_remove(_headers ${kst_${kst_name}_ignore}) set(_mocs) qt4_wrap_cpp(_mocs ${_headers} OPTIONS "-nw") set(_uis) qt4_wrap_ui(_uis ${_ui_files}) set(kst_${kst_name}_sources_not_generated ${_sources} ${_sources_cpp}) set(kst_${kst_name}_sources ${_sources} ${_sources_cpp} ${_mocs} ${_uis}) set(kst_${kst_name}_headers ${_headers}) set(kst_${kst_name}_mocs ${_mocs}) set(kst_${kst_name}_ui_files ${_ui_files}) set(kst_${kst_name}_uis ${_uis}) set(kst_${kst_name}_includes ${_folder} ${CMAKE_CURRENT_BINARY_DIR} CACHE STRING "Include dir for ${kst_name}" FORCE) source_group("Ui" FILES ${_mocs} ${_ui_files}) source_group("Generated" FILES ${_mocs} ${_uis}) endmacro() macro(kst_dont_merge) set(kst_${kst_name}_dont_merge) foreach(_it ${ARGV}) set(kst_${kst_name}_dont_merge ${kst_${kst_name}_dont_merge} ${kst_${kst_name}_folder}/${_it}) endforeach() endmacro() macro(kst_add_executable) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${kst_build_dir}/bin) include_directories(${kst_${kst_name}_folder} ${CMAKE_CURRENT_BINARY_DIR}) add_executable(${kst_name} ${ARGN} ${kst_${kst_name}_sources} ${kst_${kst_name}_headers} ${kst_${kst_name}_info_files}) target_link_libraries(${kst_name} ${kst_qtmain_library}) set_property(TARGET ${kst_name} PROPERTY DEBUG_POSTFIX ${kst_debug_postfix}) kst_revision_add_dependency() kst_flat_source_group(${kst_${kst_name}_headers} ${kst_${kst_name}_sources_not_generated}) endmacro() macro(kst_install_executable) install(TARGETS ${kst_name} RUNTIME DESTINATION bin BUNDLE DESTINATION .) endmacro() macro(kst_add_library type) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${kst_build_dir}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${kst_build_dir}/${kst_install_libdir}) include_directories(${kst_${kst_name}_folder} ${CMAKE_CURRENT_BINARY_DIR}) string(TOUPPER BUILD_kst${kst_name_base} _build_macro) add_definitions(-D${_build_macro}) if(kst_pch) set(pch kst${kst_name_base}_pch) configure_file(${kst_${kst_name}_folder}/${pch} ${CMAKE_CURRENT_BINARY_DIR}/${pch}.h COPYONLY) #add_definitions(-DKST_PCH_RECURSIVE) # only some percents faster kst_add_pch_rule(${CMAKE_CURRENT_BINARY_DIR}/${pch}.h kst_${kst_name}_sources ${type}) endif() if(kst_merge_files) if(kst_merge_rebuild) set(merged_files_rebuild 1) endif() kst_files_remove(kst_${kst_name}_sources ${kst_${kst_name}_dont_merge}) kst_files_remove(kst_${kst_name}_dont_merge ${kst_${kst_name}_ignore}) kst_files_remove(kst_${kst_name}_sources_not_generated ${kst_${kst_name}_dont_merge}) merged_files_build(merged kst_${kst_name}_sources) set(depends_moc_uic ${kst_${kst_name}_headers} ${kst_${kst_name}_uis} ${kst_${kst_name}_ui_files} ${kst_${kst_name}_mocs}) set_source_files_properties(merged_const.cpp PROPERTIES OBJECT_DEPENDS "${depends_moc_uic}") set_source_files_properties(merged_touched.cpp PROPERTIES OBJECT_DEPENDS "${depends_moc_uic}") add_library(${kst_name} ${type} ${merged_files} ${kst_${kst_name}_dont_merge} ${kst_${kst_name}_headers} ${kst_${kst_name}_uis} ${kst_${kst_name}_sources_not_generated} ${svnversion_h}) foreach(_it ${kst_${kst_name}_sources_not_generated}) set_source_files_properties(${_it} PROPERTIES HEADER_FILE_ONLY TRUE) endforeach() source_group("Source Files" Files) source_group("Header Files" Files) else() add_library(${kst_name} ${type} ${kst_${kst_name}_sources} ${kst_${kst_name}_headers} ${svnversion_h}) kst_flat_source_group(${kst_${kst_name}_headers} ${kst_${kst_name}_sources_not_generated}) endif() set(lib${kst_name_base} ${kst_name} CACHE STRING "actual ${kst_name} name" FORCE) set_property(TARGET ${kst_name} PROPERTY DEBUG_POSTFIX ${kst_debug_postfix}) set_target_properties(${kst_name} PROPERTIES VERSION ${kst_version} SOVERSION ${kst_version_major}) kst_revision_add_dependency() if(WIN32) if(NOT ${type} STREQUAL "STATIC") install(TARGETS ${kst_name} RUNTIME DESTINATION bin) endif() elseif(NOT APPLE) install(TARGETS ${kst_name} DESTINATION ${kst_install_libdir}) endif() endmacro() macro(kst_init_plugin dir) if(APPLE AND NOT CMAKE_GENERATOR STREQUAL Xcode) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${kst_build_dir}/bin/${kst_binary_name}.app/Contents/plugins) else() set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${kst_build_dir}/${kst_install_plugins}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${kst_build_dir}/${kst_install_plugins}) endif() include_directories(${CMAKE_BINARY_DIR}/${dir}) kst_include_directories(core math widgets) set(kst_plugin_dir ${dir}) set(kst_plugin_prefix ${ARGN}) endmacro() macro(kst_add_plugin folder name) set(_name _${kst_plugin_prefix}_${folder}_${name}) string(REPLACE . _ _name ${_name}) string(REPLACE / _ _name ${_name}) string(REPLACE __ _ _name ${_name}) string(REPLACE __ _ _name ${_name}) kst_init(${kst_binary_name} ${_name}) kst_files_find(${kst_plugin_dir}/${folder}/${name}) add_library(${kst_name} MODULE ${kst_${kst_name}_sources} ${kst_${kst_name}_headers}) kst_link(${libcore} ${libmath} ${libwidgets}) if(NOT APPLE) install(TARGETS ${kst_name} LIBRARY DESTINATION ${kst_install_plugins}) kst_find_install_desktop_file(${kst_plugin_dir}/${folder}/${name}) endif() add_dependencies(${kst_binary_name} ${kst_name}) kst_flat_source_group(${kst_${kst_name}_headers} ${kst_${kst_name}_sources_not_generated}) if(kst_verbose) message(STATUS "Building plugin ${kst_name}") endif() endmacro() macro(kst_include_directories) foreach(_it ${ARGV}) include_directories(${kst_${kst_binary_name}${_it}_includes}) endforeach() endmacro() macro(kst_find_install_desktop_file folder) if(UNIX) file(GLOB _desktop_file ${kst_dir}/${folder}/*.desktop) install(FILES ${_desktop_file} DESTINATION ${kst_install_plugin_desktop_file_path}) endif() endmacro() macro(kst_link) target_link_libraries(${kst_name} ${ARGV} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${QT_QTSVG_LIBRARY}) endmacro() macro(kst_files_ignore) set(kst_${kst_name}_ignore ${kst_${kst_name}_ignore} ${ARGV}) endmacro() macro(kst_files_remove list) foreach(_item ${ARGN}) set(_file ${kst_${kst_name}_folder}/${_item}) if(${list}) list(REMOVE_ITEM ${list} ${_item} ${_file} ${_file}.cpp ${_file}.c ${_file}.h) endif() endforeach() endmacro() macro(kst_add_files) set(kst_${kst_name}_sources ${kst_${kst_name}_sources} ${ARGN}) endmacro() macro(kst_add_resources filepath) qt4_add_resources(_rcc ${kst_dir}/${filepath}) kst_add_files(${_rcc}) endmacro() macro(kst_option_init) set(kst_options) endmacro() macro(kst_option _name _description _default _sys) set(_msg OFF) if(${_sys} MATCHES "gcc") set(_system CMAKE_COMPILER_IS_GNUCXX) elseif(${_sys} MATCHES "win") set(_system WIN32) else() set(_system ${_sys}) endif() if(${_system} MATCHES "all") option(kst_${_name} ${_description} ${_default}) set(_msg ON) else() if(${${_system}}) option(kst_${_name} ${_description} ${_default}) set(_msg ON) endif() endif() list(APPEND kst_options kst_${_name}) set(kst_${_name}_description ${_description}) set(kst_${_name}_show_message ${_msg}) endmacro() macro(kst_option_list_all) foreach(_option ${kst_options}) if(${${_option}_show_message}) string(SUBSTRING "${_option} " 0 25 _var) if(${_option}) set(_isset ON) else() set(_isset OFF) endif() string(SUBSTRING "${_isset} " 0 4 _val) message(STATUS "${_var}= ${_val} : ${${_option}_description}") endif() endforeach() endmacro() macro(kst_add_info_files group) foreach(_it ${ARGN}) if(NOT IS_DIRECTORY ${_it}) get_filename_component(name ${_it} NAME) if(NOT ${_it} MATCHES "^/\\\\..*$;~$") set_source_files_properties(${_it} PROPERTIES HEADER_FILE_ONLY TRUE) set(kst_${group}_info_files ${kst_${group}_info_files} ${_it}) endif() endif() endforeach() source_group(${group} FILES ${kst_${group}_info_files}) set(kst_${kst_name}_info_files ${kst_${kst_name}_info_files} ${kst_${group}_info_files}) endmacro() macro(kst_find_info_files group files) file(GLOB _filelist ${files}) kst_add_info_files(${group} ${_filelist}) endmacro() macro(kst_flat_source_group) source_group("Source Files" Files) source_group("Header Files" Files) source_group("CMakeLists" FILES CMakeLists.txt) source_group("Headers/Sources" FILES ${ARGN}) endmacro() kst-2.0.3/cmake/modules/MergedFilesBuild.cmake000644 001750 001750 00000004504 11544160206 021573 0ustar00synthsynth000000 000000 macro(merged_files_build _allinone_name _list) set(_file_list ${_allinone_name}_files) set(_file_const ${CMAKE_CURRENT_BINARY_DIR}/${_allinone_name}_const.cpp) set(_file_touched ${CMAKE_CURRENT_BINARY_DIR}/${_allinone_name}_touched.cpp) # don't touch exisiting or non-empty file, # so a cmake re-run doesn't touch all created files set(_rebuild_file_const 0) if (NOT EXISTS ${_file_const}) set(_rebuild_file_const 1) else() FILE(READ ${_file_const} _file_content) if (NOT _file_content) set(_rebuild_file_const 1) endif() endif() set(_rebuild_file_touched 0) if (NOT EXISTS ${_file_touched}) set(_rebuild_file_touched 1) else() FILE(READ ${_file_touched} _file_content) if (NOT _file_content) set(_rebuild_file_touched 1) endif() endif() if (merged_files_rebuild) set(_rebuild_file_const 1) set(_rebuild_file_touched 1) endif() if (_rebuild_file_const) file(WRITE ${_file_const} "// autogenerated file \n//\n") file(APPEND ${_file_const} "// * clear or delete this file to build it again by cmake \n//\n\n") endif() if (_rebuild_file_touched) file(WRITE ${_file_touched} "// autogenerated file \n//\n") file(APPEND ${_file_touched} "// * clear or delete this file to build it again by cmake \n//\n") file(APPEND ${_file_touched} "// * don't touch this file \n//\n\n") file(APPEND ${_file_touched} "#define DONT_INCLUDE_CONST_FILES\n") file(APPEND ${_file_touched} "#include \"${_file_const}\"\n\n\n") endif() set(${_file_list} ${_file_const} ${_file_touched}) foreach (_current_FILE ${${_list}}) get_filename_component(_abs_FILE ${_current_FILE} ABSOLUTE) GET_FILENAME_COMPONENT(_file_name ${_abs_FILE} NAME_WE) STRING(REGEX REPLACE "-" "_" _file_name "${_file_name}") set(__macro_name ${_file_name}___ASSUME_CONST) if (_rebuild_file_const) file(APPEND ${_file_const} "#define ${__macro_name}\n") file(APPEND ${_file_const} "#if defined(${__macro_name}) && !defined(DONT_INCLUDE_CONST_FILES)\n") file(APPEND ${_file_const} "#include \"${_abs_FILE}\"\n") file(APPEND ${_file_const} "#endif\n\n") endif() if (_rebuild_file_touched) file(APPEND ${_file_touched} "#ifndef ${__macro_name}\n") file(APPEND ${_file_touched} "#include \"${_abs_FILE}\"\n") file(APPEND ${_file_touched} "#endif\n\n") endif() endforeach (_current_FILE) endmacro() kst-2.0.3/cmake/modules/FindNetcdf.cmake000644 001750 001750 00000003370 11544160206 020431 0ustar00synthsynth000000 000000 include(FindPkgConfig) pkg_check_modules(NETCDF QUIET netcdf) if(NETCDF_INCLUDEDIR AND NETCDF_LIBRARIES) FIND_LIBRARY(NETCDF_LIBRARY_CPP netcdf_c++ HINTS ${NETCDF_LIBRARY_DIRS}) set(NETCDF_LIBRARY_C -L${NETCDF_LIBRARY_DIRS} ${NETCDF_LIBRARIES}) else() set(NETCDF_INCLUDEDIR NETCDF_INCLUDEDIR-NOTFOUND CACHE STRING "" FORCE) FIND_PATH(NETCDF_INCLUDEDIR netcdf.h HINTS ENV NETCDF_DIR PATH_SUFFIXES include PATHS ${kst_3rdparty_dir} ~/Library/Frameworks /Library/Frameworks ) macro(find_netcdf_lib var libname) FIND_LIBRARY(${var} ${libname} HINTS ENV NETCDF_DIR PATH_SUFFIXES lib PATHS ${kst_3rdparty_dir}) endmacro() find_netcdf_lib(netcdf_c netcdf) find_netcdf_lib(netcdf_c_debug netcdfd) find_netcdf_lib(netcdf_cpp netcdf_c++) find_netcdf_lib(netcdf_cpp_debug netcdf_c++d) if(netcdf_c AND netcdf_c_debug) set(NETCDF_LIBRARY_C optimized ${netcdf_c} debug ${netcdf_c_debug}) endif() if(netcdf_cpp AND netcdf_cpp_debug) set(NETCDF_LIBRARY_CPP optimized ${netcdf_cpp} debug ${netcdf_cpp_debug}) endif() if(NOT MSVC) # only msvc needs debug and release set(NETCDF_LIBRARY_C ${netcdf_c}) set(NETCDF_LIBRARY_CPP ${netcdf_cpp}) endif() endif() #message(STATUS "NETCDF: ${NETCDF_INCLUDEDIR}") #message(STATUS "NETCDF: ${NETCDF_LIBRARY_C}") #message(STATUS "NETCDF: ${NETCDF_LIBRARY_CPP}") IF(NETCDF_INCLUDEDIR AND NETCDF_LIBRARY_C AND NETCDF_LIBRARY_CPP) SET(NETCDF_LIBRARIES ${NETCDF_LIBRARY_CPP} ${NETCDF_LIBRARY_C}) SET(NETCDF_INCLUDE_DIR ${NETCDF_INCLUDEDIR}) SET(netcdf 1) message(STATUS "Found NetCDF:") message(STATUS " includes : ${NETCDF_INCLUDE_DIR}") message(STATUS " libraries: ${NETCDF_LIBRARIES}") ELSE() MESSAGE(STATUS "Not found: NetCDF, set NETCDF_DIR") ENDIF() kst-2.0.3/cmake/tests/allinone/CMakeLists.txt000644 001750 001750 00000000326 11544160206 021454 0ustar00synthsynth000000 000000 kst_init(${kst_binary_name} tests) kst_files_find(tests) kst_include_directories(core math) remove_definitions(-DKST_USE_QTEST_MAIN) kst_add_executable() kst_link(${libcore} ${libmath} ${QT_QTTEST_LIBRARY}) kst-2.0.3/cmake/tests/CMakeLists.txt000644 001750 001750 00000001746 11544160206 017662 0ustar00synthsynth000000 000000 project(ksttests) file(GLOB test_headers ${kst_dir}/tests/*.h) list(REMOVE_ITEM test_headers ${kst_dir}/tests/ksttest.h) kst_include_directories(core math) add_definitions(-DKST_USE_QTEST_MAIN -DKST_SRC_DIR=${kst_dir}) foreach(header ${test_headers}) get_filename_component(filename ${header} NAME_WE) string(REPLACE test test_ testname ${filename}) if(kst_verbose) message(STATUS "Building test ${testname}") endif() kst_init(${testname} "") set(moc_file) qt4_wrap_cpp(moc_file ${header} OPTIONS "-nw") kst_add_executable( ${kst_dir}/tests/ksttest.h ${kst_dir}/tests/${filename}.cpp ${header} ${moc_file}) kst_link(${libcore} ${libmath} ${QT_QTTEST_LIBRARY}) add_test(NAME ${testname} COMMAND ${testname}) # Some file grouping in Studio kst_flat_source_group() source_group(Generated FILES ${moc_file}) endforeach() message(STATUS) message(STATUS "Tests added, to run them call 'make test'") message(STATUS) # like done with qmake #add_subdirectory(allinone) kst-2.0.3/cmake/CMakeLists.txt000644 001750 001750 00000022514 11544160206 016514 0ustar00synthsynth000000 000000 cmake_minimum_required(VERSION 2.8) project(Kst) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/modules") include(KstMacros) get_filename_component(kst_dir ${CMAKE_SOURCE_DIR}/.. ABSOLUTE) get_filename_component(kst_build_dir ${CMAKE_BINARY_DIR}/build ABSOLUTE) set(kst_version_major 2) set(kst_version_minor 0) set(kst_version_patch 3) set(kst_version ${kst_version_major}.${kst_version_minor}.${kst_version_patch}) set(kst_binary_name kst2) kst_option_init() kst_option(release "Build release version: optimize for speed, don't embedded debug symbols" OFF all) kst_option(merge_files "Merge files to speedup build about factor 5" OFF all) kst_option(merge_rebuild "Rebuild generated files from merged files build" OFF all) kst_option(verbose "Make verbose CMake run and Makefiles" OFF all) kst_option(install_prefix "Install path for Kst, using a default if not set" OFF all) kst_option(install_libdir "Install directory name for libraries" OFF all) kst_option(3rdparty "Build plugins depending on 3rd party libraries" ON all) kst_option(dataobjects "Build dataobject plugins" ON all) kst_option(test "Build unit tests" OFF all) kst_option(pch "Use precompiled headers" ON all) kst_option(svnversion "Use svnversion's output for Kst's version information" ON all) kst_option(rpath "Use rpath" ON gcc) kst_option(3rdparty_download "Download precompiled 3rd party libraries" OFF win) kst_option(console "Open console on Windows" OFF win) kst_option(edit_cont "Enable \"Edit and Continue\" for Visual Studio" OFF win) message(STATUS) if(kst_3rdparty_download) message(STATUS "Checking downloaded 3rd party binaries.") set(_deps kst-3rdparty-win32-deps) set(_file ${_deps}.tar.bz2) set(_downloaded _downloaded-NOTFOUND CACHE PATH "3rd party binaries already downloaded" FORCE) find_file(_downloaded ${_file} ${CMAKE_BINARY_DIR}) if (NOT _downloaded) # TODO move to sf.net, but sf.net is broken atm (Jan 30 2011) file(DOWNLOAD http://kst-plot.kde.org/download/${_file} ${CMAKE_BINARY_DIR}/${_file} EXPECTED_MD5 d2ffdb6dad509fe40f1cc9f60c88ddd5 SHOW_PROGRESS) execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xfj ${CMAKE_BINARY_DIR}/${_file}) endif() set(kst_3rdparty_dir ${CMAKE_BINARY_DIR}/${_deps}-1.0) endif() kst_revision_project_name(Revision) add_definitions(-DKST_HAVE_SVN_REVISION_H) if(kst_svnversion) include(SubversionHeader) SubversionHeader(${kst_dir} ${kst_revision_project} ${CMAKE_BINARY_DIR}/svnrevision.h _modified) else() file(WRITE ${CMAKE_BINARY_DIR}/svnrevision.h.tmp "#define SVN_REVISION \"unknown\"\n") configure_file(${CMAKE_BINARY_DIR}/svnrevision.h.tmp ${CMAKE_BINARY_DIR}/svnrevision.h COPYONLY) endif() # Find 3rd party libraries find_package(Qt4 REQUIRED) include(${QT_USE_FILE}) if(MINGW) # seems there is a bug in FindQt4 macro(fix_it) foreach(_it ${ARGN}) if(QT_${_it}_LIBRARY_DEBUG AND QT_${_it}_LIBRARY_RELEASE) set(QT_${_it}_LIBRARY debug ${QT_${_it}_LIBRARY_DEBUG} optimized ${QT_${_it}_LIBRARY_RELEASE} CACHE STRING "Fixed ${_it}" FORCE) endif() endforeach() endmacro() fix_it(QTCORE QTGUI QTXML QTSVG QTOPENGL) endif() message(STATUS) if(kst_3rdparty) message(STATUS "3rd party libs for plugins--------------------") find_package(Getdata) find_package(Gsl) find_package(Netcdf) find_package(CFITSIO) #find_package(Dmc) message(STATUS "----------------------------------------------") else() message(STATUS "Building plugins depending on 3rd party libraries suppressed") endif() message(STATUS) # React on options if(kst_release) set(CMAKE_BUILD_TYPE Release) else() set(CMAKE_BUILD_TYPE Debug) endif() if(kst_verbose) set(CMAKE_VERBOSE_MAKEFILE 1) else() set(CMAKE_VERBOSE_MAKEFILE 0) endif() if(kst_install_prefix) set(CMAKE_INSTALL_PREFIX ${kst_install_prefix} CACHE PATH "User's choice for install prefix" FORCE) set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) else() set(kst_install_prefix INSTALLED) set(CMAKE_INSTALL_PREFIX ${kst_install_prefix} CACHE PATH "Kst's default install prefix" FORCE) endif() if(NOT kst_install_libdir) set(kst_install_libdir lib) endif() if(NOT kst_install_plugins) set(kst_install_plugins ${kst_install_libdir}/${kst_binary_name}/plugins) endif() if(kst_rpath) # the RPATH to be used when installing set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${kst_install_libdir}") endif() #path to install the .desktop files set(kst_install_plugin_desktop_file_path share/services/kst) if(NOT kst_console) set(kst_win32 WIN32) set(kst_qtmain_library ${QT_QTMAIN_LIBRARY}) endif() if(APPLE AND NOT CMAKE_GENERATOR STREQUAL Xcode) set(kst_win32 MACOSX_BUNDLE) endif() if(APPLE) set(kst_pch 0 CACHE BOOL "Disable pch on Mac, not supported yet" FORCE) endif() if(kst_merge_files) set(kst_pch 0 CACHE BOOL "Disable pch because we build merged" FORCE) endif() if(MSVC) add_definitions(-D_USE_MATH_DEFINES) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") endif() if(MSVC_IDE AND kst_edit_cont) # Enable in Visual Studio set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /ZI") if(kst_pch) # Studio bug: set(kst_pch 0 CACHE BOOL "Disable pch because of Edit&Continue" FORCE) endif() endif() if(WIN32) set(kst_debug_postfix d) endif() configure_file(${kst_dir}/cmake/config.h.cmake ${CMAKE_BINARY_DIR}/config.h) include_directories(${CMAKE_BINARY_DIR} ${QT_INCLUDES}) message(STATUS "Build summary----------------------------------") message(STATUS) message(STATUS "Version : ${kst_version}") message(STATUS "Path to source: ${kst_dir}") message(STATUS "Installation :") message(STATUS " ${kst_install_prefix}/bin") message(STATUS " ${kst_install_prefix}/${kst_install_libdir}") message(STATUS " ${kst_install_prefix}/${kst_install_plugins}") message(STATUS) message(STATUS "Options:") kst_option_list_all() message(STATUS) message(STATUS "-----------------------------------------------") message(STATUS) add_subdirectory(src) if(kst_test) enable_testing() add_subdirectory(tests) endif() if (NOT APPLE) add_subdirectory(misc) endif() # CPack packaging # # http://cmake.org/cmake/help/cmake-2-8-docs.html#module:CPack if(WIN32) set(CPACK_GENERATOR NSIS ZIP) set(CPACK_BINARY_ZIP 1) if (kst_install_prefix) set(CPACK_NSIS_PACKAGE_NAME ${kst_install_prefix}) endif() endif() if (kst_install_prefix) set(CPACK_PACKAGE_FILE_NAME ${kst_install_prefix}-binary) set(CPACK_SOURCE_PACKAGE_FILE_NAME ${kst_install_prefix}) else() set(CPACK_SOURCE_PACKAGE_FILE_NAME Kst-${kst_version}) endif() set(CPACK_INSTALL_PREFIX "") set(CPACK_PACKAGE_NAME Kst) set(CPACK_PACKAGE_EXECUTABLES ${kst_binary_name} Kst2) set(CPACK_PACKAGE_VENDOR "The Kst Team") set(CPACK_PACKAGE_VERSION_MAJOR ${kst_version_major}) set(CPACK_PACKAGE_VERSION_MINOR ${kst_version_minor}) set(CPACK_PACKAGE_VERSION_PATCH ${kst_version_patch}) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Kst 2") set(CPACK_PACKAGE_DESCRIPTION_FILE ${kst_dir}/README) set(CPACK_PACKAGE_CONTACT "http://bugs.kde.org}") set(CPACK_PACKAGE_INSTALL_DIRECTORY "Kst ${kst_version}") set(CPACK_STRIP_FILES 1) # cmake bug, problems with the quotes in the gpl, fixed in 2.8.4 set(CPACK_RESOURCE_FILE_LICENSE "${kst_dir}/COPYING") # sources set(CPACK_SOURCE_INSTALLED_DIRECTORIES "${kst_dir};/") # http://www.mail-archive.com/cmake@cmake.org/msg33720.html set(CPACK_SOURCE_GENERATOR TGZ ZIP TBZ2) # rpm set(CPACK_SET_DESTDIR "ON") FILE(READ ${CPACK_RESOURCE_FILE_LICENSE} CPACK_RPM_PACKAGE_LICENSE) set(CPACK_RPM_PACKAGE_GROUP "Applications/Science") set(CPACK_RPM_PACKAGE_VENDOR ${CPACK_PACKAGE_VENDOR}) # deb # This is experimental # check also for plugin's 3rdparty libraries? set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqtgui4 (>= 4.4.3-0)") # Usage # # Source only .targz, .tar.bz2, .zip: # make package_source # # Binary .tar.gz and install .sh: # make package # # Binary .deb: # create : cpack -G DEB --config CPackConfig.cmake # list : dpkg-deb -c Kst-*.deb # install: dpkg -i Kst-*.deb # # Binary .rpm: # create : cpack -G RPM --config CPackConfig.cmake # list : rpm -qlp Kst-*.rpm # install: rpm -U Kst-*.rpm # CPack and Ubuntu # Found this: # http://www.purplekarrot.net/blog/dputCMake.html if(APPLE) # We start from build/bin/kst2.app, all is build into the final bundle folder # On the mac the pathes to needed shared libraries are hardcoded in the binary/library # which could be changed by the macro 'fixup_bundle' # libs which are hardcoded are resolved automatically # but the plugins must be passed as extra argument because they are not hardcoded in the binary set(bundle_dir ${kst_build_dir}/bin) set(contents_dir ${kst_binary_name}.app/Contents) set(app ${bundle_dir}/${kst_binary_name}.app) install(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION ${bundle_dir}/${contents_dir}/plugins COMPONENT Runtime) install(CODE "file(GLOB qt_plugins \"${bundle_dir}/${contents_dir}/plugins/imageformats/*${CMAKE_SHARED_LIBRARY_SUFFIX}\") file(GLOB kst_plugins \"${bundle_dir}/${contents_dir}/plugins/*${CMAKE_SHARED_MODULE_SUFFIX}\") set(libs \${qt_plugins} \${kst_plugins}) include(BundleUtilities) fixup_bundle(\"${app}\" \"\${libs}\" \"${dir}\") " COMPONENT RUNTIME) file(WRITE ${CMAKE_BINARY_DIR}/qt.conf "") install(FILES ${CMAKE_BINARY_DIR}/qt.conf DESTINATION ${contents_dir}/Resources COMPONENT Runtime) set(CPACK_GENERATOR DragNDrop) endif() include(CPack) kst-2.0.3/cmake/misc/CMakeLists.txt000644 001750 001750 00000003215 11544160206 017444 0ustar00synthsynth000000 000000 # install runtime files if(WIN32) install(FILES ${QT_BINARY_DIR}/QtCore4.dll ${QT_BINARY_DIR}/QtGui4.dll ${QT_BINARY_DIR}/QtXml4.dll ${QT_BINARY_DIR}/QtOpenGL4.dll ${QT_BINARY_DIR}/QtSvg4.dll DESTINATION bin CONFIGURATIONS Release) install(FILES ${QT_BINARY_DIR}/QtCored4.dll ${QT_BINARY_DIR}/QtGuid4.dll ${QT_BINARY_DIR}/QtXmld4.dll ${QT_BINARY_DIR}/QtOpenGLd4.dll ${QT_BINARY_DIR}/QtSvgd4.dll DESTINATION bin CONFIGURATIONS Debug) endif() if(MINGW) get_filename_component(MINGW_BIN_PATH ${CMAKE_CXX_COMPILER} PATH) install(FILES ${MINGW_BIN_PATH}/libgcc_s_dw2-1.dll ${MINGW_BIN_PATH}/mingwm10.dll DESTINATION bin) endif() if(WIN32) set(color_folder colors) set(tutorial_folder tutorial) set(font_folder fonts) else() set(color_folder share/config/colors) set(tutorial_folder share/apps/kst/tutorial) SET(font_folder share/apps/kst/fonts) endif() # install data files if(UNIX) if(NOT gyrodata) configure_file(${kst_dir}/sample_data/GYRODATA+free-width+whitespace+unixEOL+dot-decimal-separator.txt.gz ${CMAKE_BINARY_DIR}/gyrodata.dat.gz COPYONLY) execute_process(WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND gunzip gyrodata.dat.gz) set(gyrodata ${CMAKE_BINARY_DIR}/gyrodata.dat CACHE STRING "gyrodata decompressed") endif() endif() file(GLOB dat_files ${kst_dir}/misc/tutorial/*.dat) install(FILES ${dat_files} ${gyrodata} DESTINATION ${tutorial_folder}) # install colors file(GLOB idl_files ${kst_dir}/misc/IDL*) install(FILES ${idl_files} DESTINATION ${color_folder}) #install fonts if(UNIX) file(GLOB fonts ${kst_dir}/misc/fonts/*.gz) install(FILES ${fonts} DESTINATION ${font_folder}) endif() kst-2.0.3/cmake/config.h.cmake000644 001750 001750 00000000405 11544160206 016444 0ustar00synthsynth000000 000000 #ifndef KST_CONFIG_H #define KST_CONFIG_H // obligatory flags //#define QT_NO_STL //#define QT_NO_KEYWORDS #define KSTVERSION "${kst_version}" #define KST_INSTALL_LIBDIR "${kst_install_libdir}" #define KST_INSTALL_PLUGINS "${kst_install_plugins}" #endif kst-2.0.3/cmake/src/libkstmath/CMakeLists.txt000644 001750 001750 00000000305 11544160206 021437 0ustar00synthsynth000000 000000 kst_init(${kst_binary_name} math) kst_files_find(src/libkstmath) kst_dont_merge(eparse.cpp escan.cpp fftsg_h.c) kst_include_directories(core math) kst_add_library(SHARED) kst_link(${libcore}) kst-2.0.3/cmake/src/libkstapp/CMakeLists.txt000644 001750 001750 00000001213 11544160206 021265 0ustar00synthsynth000000 000000 kst_init(${kst_binary_name} app) kst_files_find(src/libkstapp) kst_include_directories(core math widgets) set(AUTHORS ${kst_dir}/AUTHORS) set_source_files_properties(${AUTHORS} PROPERTIES GENERATED TRUE HEADER_FILE_ONLY TRUE) file(READ ${AUTHORS} data) string(REPLACE "\n" ";" kst_authors ${data}) file(WRITE ${CMAKE_BINARY_DIR}/authors.h.tmp "static const char* kst_authors = \"${kst_authors}\";\n") execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_BINARY_DIR}/authors.h.tmp ${CMAKE_BINARY_DIR}/authors.h) kst_add_library(STATIC ${CMAKE_BINARY_DIR}/authors.h ${AUTHORS}) kst_link(${libcore} ${libmath} ${libwidgets}) kst-2.0.3/cmake/src/plugins/CMakeLists.txt000644 001750 001750 00000004455 11544160206 020770 0ustar00synthsynth000000 000000 kst_init_plugin(src/plugins) kst_add_plugin(dataobject bin) kst_add_plugin(dataobject chop) kst_add_plugin(dataobject linefit) kst_add_plugin(dataobject lockin) kst_add_plugin(dataobject phase) kst_add_plugin(dataobject shift) kst_add_plugin(dataobject statistics) kst_add_plugin(dataobject syncbin) kst_add_plugin(dataobject crossspectrum) kst_add_plugin(dataobject differentiation) kst_add_plugin(dataobject effectivebandwidth) kst_add_plugin(dataobject genericfilter) kst_add_plugin(filters cumulativesum) kst_add_plugin(filters despike) kst_add_plugin(filters differentiation) if(gsl) include_directories(${GSL_INCLUDE_DIR}) macro(kst_add_gsl_plugin dir name) kst_add_plugin(${dir} ${name}) kst_link(${GSL_LIBRARIES}) endmacro() kst_add_gsl_plugin(dataobject/convolution convolve) kst_add_gsl_plugin(dataobject/convolution deconvolve) kst_add_gsl_plugin(dataobject/correlation autocorrelation) kst_add_gsl_plugin(dataobject/correlation crosscorrelation) kst_add_gsl_plugin(dataobject/interpolations akima) kst_add_gsl_plugin(dataobject/interpolations akimaperiodic) kst_add_gsl_plugin(dataobject/interpolations cspline) kst_add_gsl_plugin(dataobject/interpolations csplineperiodic) kst_add_gsl_plugin(dataobject/interpolations linear) kst_add_gsl_plugin(dataobject/interpolations polynomial) kst_add_gsl_plugin(dataobject noiseaddition) kst_add_gsl_plugin(dataobject periodogram) kst_add_gsl_plugin(filters butterworth_bandpass) kst_add_gsl_plugin(filters butterworth_bandstop) kst_add_gsl_plugin(filters butterworth_highpass) kst_add_gsl_plugin(filters butterworth_lowpass) kst_add_gsl_plugin(fits exponential_unweighted) kst_add_gsl_plugin(fits exponential_weighted) kst_add_gsl_plugin(fits gaussian_unweighted) kst_add_gsl_plugin(fits gaussian_weighted) kst_add_gsl_plugin(fits gradient_unweighted) kst_add_gsl_plugin(fits gradient_weighted) kst_add_gsl_plugin(fits kneefrequency) kst_add_gsl_plugin(fits linear_unweighted) kst_add_gsl_plugin(fits linear_weighted) kst_add_gsl_plugin(fits lorentzian_unweighted) kst_add_gsl_plugin(fits lorentzian_weighted) kst_add_gsl_plugin(fits polynomial_unweighted) kst_add_gsl_plugin(fits polynomial_weighted) kst_add_gsl_plugin(fits sinusoid_unweighted) kst_add_gsl_plugin(fits sinusoid_weighted) endif() kst-2.0.3/cmake/src/CMakeLists.txt000644 001750 001750 00000000413 11544160206 017275 0ustar00synthsynth000000 000000 add_subdirectory(libkst) add_subdirectory(libkstmath) add_subdirectory(widgets) add_subdirectory(libkstapp) add_subdirectory(kst) add_subdirectory(datasources) if(kst_dataobjects) add_subdirectory(plugins) endif() #add_subdirectory(d2asc) #add_subdirectory(d2d) kst-2.0.3/cmake/src/datasources/CMakeLists.txt000644 001750 001750 00000001635 11544160206 021621 0ustar00synthsynth000000 000000 kst_init_plugin(src/datasources datasource) if(MSVC OR MINGW) add_definitions(-DKST_USE_KST_ATOF) endif() if(UNIX) # speedup on Linux x2.7 add_definitions(-DKST_USE_KST_ATOF) endif() kst_add_plugin(. ascii) kst_add_plugin(. qimagesource) kst_add_plugin(. sampledatasource) if(getdata) include_directories(${GETDATA_INCLUDE_DIR}) kst_add_plugin(. dirfilesource) kst_link(${GETDATA_LIBRARIES}) endif() if(cfitsio) include_directories(${CFITSIO_INCLUDE_DIR}) kst_add_plugin(. fitsimage) kst_link(${CFITSIO_LIBRARIES}) endif() if(healpix) kst_add_plugin(. healpix) endif() if(lfioo) kst_add_plugin(. lfiio) endif() if(netcdf) include_directories(${NETCDF_INCLUDE_DIR}) kst_add_plugin(. netcdf) kst_link(${NETCDF_LIBRARIES}) endif() if(planckIDEF) kst_add_plugin(. planckIDEF) endif() if(dmc) include_directories(${DMC_INCLUDE_DIR}) kst_add_plugin(. dmc) #kst_link(${DMC_LIBRARIES}) endif() kst-2.0.3/cmake/src/libkst/CMakeLists.txt000644 001750 001750 00000000525 11544160206 020571 0ustar00synthsynth000000 000000 kst_init(${kst_binary_name} core) kst_files_ignore(stdinsource timezones) if(WIN32 OR APPLE OR ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") kst_files_ignore(sysinfo psversion) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lrt") endif() kst_files_find(src/libkst) kst_dont_merge(sysinfo.c psversion.c) kst_add_library(SHARED) kst_link() kst-2.0.3/cmake/src/kst/CMakeLists.txt000644 001750 001750 00000003453 11544160206 020105 0ustar00synthsynth000000 000000 kst_init(${kst_binary_name} "") kst_files_ignore(main-vld) kst_files_find(src/kst) if(WIN32) if(MINGW) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/kst_icon.o COMMAND windres.exe -I${CMAKE_CURRENT_BINARY_DIR} -i${kst_dir}/src/kst/kst_icon.rc -o ${CMAKE_CURRENT_BINARY_DIR}/kst_icon.o) set(rc_file ${CMAKE_CURRENT_BINARY_DIR}/kst_icon.o) else() set(rc_file ${kst_dir}/src/kst/kst_icon.rc) endif() endif() kst_add_resources(src/images/images.qrc) kst_find_info_files(KstCMakeFiles ${kst_dir}/cmake/*) kst_find_info_files(KstCMakeFiles ${kst_dir}/cmake/modules/*) kst_add_info_files(KstInfoFiles ${kst_dir}/INSTALL ${kst_dir}/NEWS ${kst_dir}/README) kst_include_directories(app) kst_add_executable(${kst_win32} ${rc_file}) kst_link(${libcore} ${libmath} ${libapp} ${libwidgets}) kst_install_executable() if(UNIX AND NOT APPLE) set(man ${CMAKE_BINARY_DIR}/${kst_binary_name}.1) configure_file(${kst_dir}/src/kst/kst.1.txt ${man}) install(CODE "execute_process(COMMAND gzip ${man})") set_source_files_properties(${man}.gz PROPERTIES GENERATED TRUE) install(FILES ${man}.gz DESTINATION share/man/man1) set(k ${kst_dir}/src/kst) install(FILES ${k}/kstplugin.desktop ${k}/kstdatasourceplugin.desktop ${k}/kstdataobjectplugin.desktop ${k}/kstbasicplugin.desktop ${k}/kstfilter.desktop ${k}/kstextension.desktop DESTINATION share/servicetypes/kst) install(FILES ${k}/kst.desktop DESTINATION share/applnk/Graphics) install(FILES ${k}/kstui.rc DESTINATION share/apps/kst) install(FILES ${k}/x-kst.desktop DESTINATION share/mimelink/application) install(FILES ${k}/kst.desktop DESTINATION share/applications) endif() kst-2.0.3/cmake/src/d2asc/CMakeLists.txt000644 001750 001750 00000000245 11544160206 020274 0ustar00synthsynth000000 000000 kst_init(d2asc) kst_files_find(src/d2asc) kst_include_directories(core math) kst_add_executable() kst_link(${libcore} ${libmath}) kst_install_executable() kst-2.0.3/cmake/src/d2d/CMakeLists.txt000644 001750 001750 00000000237 11544160206 017752 0ustar00synthsynth000000 000000 kst_init(d2d "") kst_files_find(src/d2d) kst_include_directories(core math) kst_add_executable() kst_link(${libcore} ${libmath}) kst_install_executable() kst-2.0.3/cmake/src/widgets/CMakeLists.txt000644 001750 001750 00000000243 11544160206 020744 0ustar00synthsynth000000 000000 kst_init(${kst_binary_name} widgets) kst_files_find(src/widgets) kst_include_directories(core app math) kst_add_library(SHARED) kst_link(${libcore} ${libmath})kst-2.0.3/gdb-kst000755 001750 001750 00000000160 11544160206 014146 0ustar00synthsynth000000 000000 #!/bin/sh cd `dirname $0` export SCRIPTDIR=$PWD export BUILDDIR=$PWD/build gdb --args $BUILDDIR/bin/kst "$@" kst-2.0.3/NEWS000644 001750 001750 00000000065 11544160206 013370 0ustar00synthsynth000000 000000 For news, see the kst web page http://kst.kde.org/ kst-2.0.3/devel-docs/notes/tool_mode_changes000644 001750 001750 00000006320 11544160206 021442 0ustar00synthsynth000000 000000 Layout Mode comments: (July 28, 07) Overall: Lets copy inkscape's UI as much as is reasonable. BUT: remember, we are annotating plots, not making icons! -in layout mode, we need a toolbar to select the various tools. Handles: -need mouseover feedback on handles (inkscape changes colours) -need feedback on potential selection. Inkscape uses mouse feedback, but since most objects will over a plot, this is mostly useless. I think showing ghost handles would be better. -Handle dimensions should be fixed and should not depend on window/object/ parent size. (It could be cool to have the the size fixed relative to the screen size.) -Handles should lie outside the object so that they are accesible with 0 size objects (eg, horizontal line). -Handles need to have some indication what they are/do (like inkscape). -to get to rotate mode, you have to click twice, which is too much like a double click (which calls up the properties dialog). So, get rid of double click to properties dialog. Instead get it from the rmb or from button 2. -On resize, you should be able flip through zero to mirror the object. This is especially important for lines. -Sometimes clicking on an object does not bring up the handles. Is this a bug, or just a different mode? Line Properties: -By default, line properties should depend on the size (width + height) of the page/TopLevelView/Window and should not depend on the aspect ratio of the object, or its parent or the TLV. This includes: -line widths -dash dimensions -arrow dimensions -Ends of wide lines - (should be always perpendicular to line) so, -resizing an object and not the window should not change its line widths. NOTE: this is not the same behavior as inkscape. -The vertical and horizontal lines of a box should always be equal regardless of any resizing. -For 2.x, we should consider a per-object option to allow the line properties to be a function of the parent size, rather than the TLV size. -Line property units should be 'points, if printed to US Letter' Aspect ratio -All objects except lines should have a 'preserve aspect ratio' option. -Fonts and Pictures should default to having this set. -All others should default to this unset. -When it is set, changing the aspect ratio of the object's parent or TLV will not change the aspect ratio of the objects -When it is set, moving the grab boxes should uniformly scale the object (but not Line Properties). -When it is set, rotations need to be in display space, to preserve relative angle. SO: -rectangles stay rectangles -fonts don't get distorted -When it is not set, rotations are in the (0-1, 0-1) space, so objects will only preserve their apparent aspect ratio if the TLV is square. Object Specific changes: Labels: -To create a lable, click to location, which pops up the dialog (same as 1.4) Apply/OK on dialog draws the label. In the first instance, we don't need to support in-place text editing. Dialogs: -Inkscape uses multiple dialogs to edit different properties of an object. We should not. Use tabbed dialogs instead. -They need to support everything the 1.4 dialogs support. kst-2.0.3/devel-docs/using_git000644 001750 001750 00000002077 11544160206 016636 0ustar00synthsynth000000 000000 Using Git as subversion client http://git-scm.com/ (Newer packages for Ubuntu: http://ppa.launchpad.net/pdoes/ppa/ubuntu karmic main) Set up git repository, done only once -------------------------------------- Init your git repository with the svn path git svn init svn+ssh://YOU_USERNAME@svn.kde.org/home/kde/branches/work/kst/portto4 Get an old revision as starting point (git slang: basepoint) e.g http://mail.kde.org/pipermail/kst/2008-January/015217.html git svn fetch -r768342 (without the revision it starts checking for commit at revsion 100, but also only getting all changes from january takes a while) Update ------ Update your local clone git svn fetch Update your local branch 'master' (git slang: move basepoint of master to HEAD of the fetched data) git checkout master git svn rebase History ------- Browse history offline with a git-GUI gitk, gitg, qgit, ... Commiting ---------- Commit your changes to your local repository git commit "message" -a Commit to public svn repository git svn dcommit kst-2.0.3/devel-docs/general_1.x/branches.txt000644 001750 001750 00000001447 11544160206 021354 0ustar00synthsynth000000 000000 Branch: svn.kde.org/home/kde/branches/kst/1.1/ Description: Stable branch for Kst 1.1.x Branch: svn.kde.org/home/kde/branches/kst/1.2/ Description: Stable branch for Kst 1.2.x Branch: svn.kde.org/home/kde/branches/kst/hfi_calib/ Description: Branch for use by HFI. Restricted to George only for commits. Branch: svn.kde.org/home/kde/branches/kst/branches/work/kst/* Description: Branches for development of new features outside of trunk. You make a branch with: svn cp https://svn.kde.org/home/kde/trunk/extragear/graphics https://svn.kde.org/home/kde/branches/work/kst/ You can then check out your branch from that URL. It's best to remove the parts of the branch that you do not need. Simply check it out with: svn co https://svn.kde.org/home/kde/branches/work/kst/ kst-2.0.3/devel-docs/general_1.x/mimetypes.txt000644 001750 001750 00000002143 11544160206 021575 0ustar00synthsynth000000 000000 List of mimetypes we provide and their definitions: application/x-kst: A Kst XML file in full application/x-kst-fragment: A Kst XML fragment that can be read and interpreted, but does not describe a full Kst session. Unimplemented. application/x-kst-plot-list: A list of plot names encoded as a qstringlist. Used primarily for drag and drop in the plot dialog. application/x-kst-plot-names: A list of plot names encoded as a qstringlist, preceded by a window. Used for drag and drop of plots between windows in Kst 1.1.0 only. DEPRECATED application/x-kst-legend: A plot legend. Contains the window name, the plot name, and the hotspot. DEPRECATED application/x-kst-label-number: A plot label. Contains the window name, the plot name, the label number in the internal list, and the hotspot. DEPRECATED application/x-kst-plots: Unimplemented, reserved for plot dragging. Do not implement support for drag and drop or copy and paste for the deprecated mimetypes in any new applications. They are almost entirely useless there, and these types will be removed from Kst starting in version 1.2.0. kst-2.0.3/devel-docs/general_1.x/datatypes.txt000644 001750 001750 00000003752 11544160206 021566 0ustar00synthsynth000000 000000 Kst contains types, just as a typical computer application. In C++, there are primitive types (POD) and derived types (classes). In Kst, we have the following categorization: Primitive Types Derived Types Interpretations ------------------------------------------------------------------------- KstScalar KstPSD KstVCurve KstString KstEquation KstImage* KstVector KstHistogram KstRVector KstPlugin KstAVector KstCSD KstSVector KstMatrix* KstRMatrix KstAMatrix KstSMatrix KstMatrix and KstImage are presently wrong in Kst. They are both derived types, and yet one represents primitive underived data (though it is not implemented that way), and the other is used directly to interpret that data as a visualization. Primitive types can be created by the user, or loaded from storage. The present data loading mechanism is flawed in that it only supports loading one type of data from disk: vectors. KstDataSource needs to be expanded with a keyed plugin mechanism and needs to drop binary compatibility issues [-internally- -only-] so that it can be extended to support these other primitive types. This key is implemented in the development code. The next step is to create Kst?Matrix classes which behave as close as possible to the same way Kst?Vector does, with an interface as close as possible to that of Kst?Vector. Once this is done, the KstDataSource interface can be extended to support loading them (as well as all other primitive types). The Matrix dialog will become an equivalent to the Vector dialog. Note that Matrix needs to be a primitive type internally too. It should not use KstVector. After matrices are renovated, KstImage needs to be converted into a KstBaseCurve and adjusted somewhat to be a generic curve with a matrix for storing data. It is desired at some point to be able to render all sort of different image formats easily with this class. This change, however, depends on changes to Kst2DPlot to an extent, and should wait for those changes. (they are minor) kst-2.0.3/devel-docs/general_1.x/testplan.txt000644 001750 001750 00000022322 11544160206 021414 0ustar00synthsynth000000 000000 Kst Test Plan ============= This is a test plan designed to test basic functionality of the entire Kst application as a whole, from a user perspective. Only certain combinations of certain actions are tested. In the following steps, each action should produce an expected result. Results deviating from the expected results should be recorded. Results not deviating from the expected result should be recorded as well. The following perl script is used: datagenerator.pl under kst/tests/ I. Compiling and Installing --------------------------- 1. Make sure CFITSIO and GSL libraries are installed. 2. Download and untar the Kst source. 3. Do the following: ./configure --prefix=`kde-config --prefix` make make install Expected Result: Kst is installed. 4. Run Kst: kst Expected Result: Kst starts. Main window is shown. II. Basic Functionality ----------------------- 0. Run: datagenerator.pl testdata Wait 30 seconds. Terminate execution of datagenerator.pl. 1. Select Data->Data Wizard. Browse to "testdata". Click Next. Expected Result: 2nd window of Data Wizard is displayed. 4 fields should be selectable. 2. Type * in the Search box. Expected Result: All fields should be highlighted. 3. Remove * from the Search box and highlight fields 2, 3, and 4. Click Check Selected. Expected Result: Fields 2,3,4 should be checked. Field 1 should not be checked. 4. Check the Read to end checkbox. Select XY and Power Spectrum for Plot Type. Click Next. Select 1 plot per curve. Click Finish. Expected Result: 6 plots are displayed. 5. Drag a rectangle on a plot. Expected Result: Plot zooms in. 6. Hold down shift and drag a rectangle on a plot. Expected Result: Plot zooms in on y axis only. 7. Hold down ctrl and drag a rectangle on a plot. Expected Result: Plot zooms in on x axis only. 8. Hold cursor over a plot and hit left, right, up, down arrow keys. Expected Result: Plot scrolls left, right, up, down respectively. 9. Right-click on a plot and select Edit->(Curve Name). Change Y Axis Vector and change curve colour. Click Apply Edits. Expected Result: Plot changes to reflect new vector and colour. 10. Select Data->Data Manager. Click Vector button under New: and choose field 2. Click Apply As New. Click Close. Expected Result: New vector V5-2 should be created. 11. Click Curve. Select V0-INDEX as X axis vector and V1-2 as Y axis vector. Click Apply As New. Click Close. Expected Result: New Curve and plot are created. 12. Click Equation. Enter the equation: [V1-2]+SIN([V2-3]) Click Apply As New. Click Close. Expected Result: New Equation is created. 13. Click Histogram. Select V3-4 as the vector. Click Apply As New. Click Close. Expected Result: New Histogram is created. 14. Click Power Spectra. Select V1-2 as the vector. Click Apply As New. Click Close. Expected Result: New Power Spectrum is created. 15. Click Plugin. Select Fit polynomial as the plugin. Select V0-INDEX as the X Array and V1-2 as the Y Array. Enter 2 as the order. Click Apply As New and then Close. Expected Result: New Plugin is created. 16. Expand the listing for the new plugin in Data Manager and right-click on ...-Y Fitted. Select Make Curve. Click Apply As New and click Close. Expected Result: New Curve showing the fit is created. 17. Click Event. Select V1-2 as the vector. Append >0 to the expression. Select Log As and choose Warning. Click Apply As New and click Close. Expected Result: New Event is created. 18. Right-click C2-V2-3 and choose Remove From Plot->(plot name). Right-click PSD3-V2-3 and choose Remove From Plot->(plot name). Click the Purge button. Expected Result: C2-V2-3, PSD3-V2-3 and V2-3 are removed from Data Manager. 19. Close Data Manager. Goto Help->Debug Kst. Select Log tab. Expected Result: There are 13 Event Monitor Warnings. 20. Close Kst Debug Dialog. Select Plots->Label Editor. Click on any plot. Expected Result: Label Editor dialog appears. 21. Enter arbitrary label text. Select a font and enter 30 for rotation. Click OK. Expected Result: Label is created, rotated 30 degrees clockwise. 22. Drag the label. Expected Result: Label moves to new location. 23. Click on the label. Expected Result: Label Editor Dialog appears with settings for this label. 24. Click Ok. Select Plots->Layout Mode. Drag the plots around and resize by dragging edges of the plots. Expected Result: Plots are rearranged and resized. 25. Select Plots->Layout Mode. Select Plots->XY Mouse Zoom. 26. Select File->Print. Click Print. Expected Result: Current window is printed in landscape orientation, with footer. 27. Select File->Save Vectors to Disk. Select V3-4 and click Save. Enter a filename and click Save, then Close. Select File->Export to Graphics File. Select a Save Location and click Save Once. Expected Result: Vector and Graphics files are saved to specified locations. 28. Right-click and plot and select Delete. Expected Result: The plot is removed from window. 29. Select File->New Window. Enter 1234 and click OK. Select File->New Window. Enter abcdef and click OK. Expected Result: Two new windows are created. 30. Select Window->MDI Mode->Toplevel. Expected Result: Windows are arranged in Toplevel mode. 31. Select Window->MDI Mode->Childframe. Select Window->Tile...->Tile Non-overlapped Expected Result: Windows are arranged in Childframe mode, tiled. 32. Select Window->MDI Mode->Tab Page Mode. Expected Result: Windows are arranged in Tab Page mode. 33. Select Window->MDI Mode->IDEAl mode. Expected Result: Windows are arranged in IDEAl mode. 34. Select File->Save. Save file to a location. Select File->New Expected Result: All windows are cleared. 35. Select Data->Data Manager. Expected Result: No data objects are present. 36. Select File->Quit. Expected Result: Kst exits. 37. Start Kst. Select File->Open. Browse to file saved in step 34. Expected Result: All windows, plot layouts, data objects saved are open. 38. Select Settings->Plugins. Highlight Autocorrelation and click Remove, then Yes. Highlight Chop and click Remove, then Yes. Highlight Linefit and click Remove, then Yes. Expected Result: Autocorrelation, Chop, Linefit are removed from list. 39. Click Rescan. Expected Result: Autocorrelation, Chop, Linefit are added to list. 40. Click Close. Select File->Quit. Expected Result: Plugin Manager is closed. Kst exits. 41. Delete testdata. Streaming Data ============== 0. During the following steps, note any slowless or strange behaviour. 1. Run: datagenerator.pl teststream 2. Start Kst. Select Data->Data Manager. Click Vector. Browse to teststream for File name, select Field 1. Check Read to End. Click Apply as New. Select Field 2. Check Read to End. Click Apply as New. Click Close. Expected Result: Vectors V1-1 and V2-2 are created. 3. Click Curve. Select V1-1 for X axis vector, V2-2 for Y axis vector. Click New... under Curve Placement. Type 1234 and click OK. Check Place in new plot. Click Apply as New. Expected Result: New Curve is created in new window and plot. 4. Watch plot for 10 seconds. Expected Result: Plot updates as new data is written. 5. Select Range->Pause. Watch plot for 10 seconds. Expected Result: Plot does not update. 6. Select Range->Read from End. Watch plot for 10 seconds. Expected Result: Plot updates with new data. 7. Select Plots->XY Mouse Zoom. Draw a rectangle on plot. Watch plot for 10 seconds. Expected Result: Plot zooms in to rectangular area, does not update. 8. Right-click on plot, select Zoom->Zoom Maximum. Watch plot for 10 seconds. Expected Result: Plot updates with new data. 9. Select Plots->Y Mouse Zoom. Draw rectangular area on plot. Watch plot for 10 seconds. Expected Result: Plot zooms in on y axis, plot continues to update. 10. Select Plots->X Mouse Zoom. Draw rectangular area smaller than current plot size. Watch plot for 10 seconds. Expected Result: Plot zooms in on y axis, plot does not update. 11. Right-click on plot, select Zoom->Zoom Maximum. Click plot and hit right arrow key 5 times. Watch plot for 10 seconds. Expected Result: Plot scrolls to right, revealing blank area. Plot updates and draws curves to blank area. 12. Right-click on plot, select Zoom->Zoom Maximum. Select Plots->Edit Plots. Select Limits tab. Under X Axis, choose AC: Range, and enter 9000. Click Apply Edits and click Close. Watch plot for 10 seconds. Expected Result: X axis changes to 9000 length, plot updates, lower x axis value updates accordingly to keep 9000 length. 13. Select Data->Edit Equation. Create equation: [V1-2]*5 Select V0-1 for Use Existing Vector under Independent Variable. Select Place in new plot under Curve Placement, click Apply as New. Expected Result: New curve and plot is created, 14. Watch plot for 10 seconds. Expected Result: New curve and plot updates simultaneously with original plot. 15. Select File->Quit, click No. Expected Result: Kst exits. 16. Terminate execution of datagenerator.pl, delete teststream. kst-2.0.3/devel-docs/general_1.x/plotmarkers.txt000644 001750 001750 00000002403 11544160206 022123 0ustar00synthsynth000000 000000 For plot marking: ================= - use Alt-Left Click to created a plot marker at the current position - use a vertical dotted foreground-colour line to mark the plot. - all other zooming/data mode actions are still available. Add to Plot Dialog ------------------ - plot markers will be part of plots, not curves. - have a new tab on the Plot Dialog called Markers - on the tab will be a list of plot markers (probably in x-coordinate form) - underneath/beside the list of plot markers will be 3 buttons: - Add (to manually add a plot marker by entering the value) - Remove (this will remove selected plot marker(s)) - Remove All Add to Plot Context Menu ------------------------ - add a separater to the bottom of the Scroll submenu in the context menu - underneath the separater, add two entries: - Next Plot Marker - Previous Plot Marker - suggested shortcuts - Alt+Right arrow/Alt+Left arrow, PgUp/PgDown,... - moving to plot markers is a scrolling action, it will not change the zoom "level" Additional Details ------------------ - there will be public functions for adding, removing, and retrieving plot markers from plots (event monitors could use these to add markers, given that a plot is specified to be associated with the event). kst-2.0.3/devel-docs/general_1.x/objectnaming.txt000644 001750 001750 00000011613 11544160206 022223 0ustar00synthsynth000000 000000 All data objects (objects derived from KstObject) should be globally accessible from a hierarchical namespace. The general idea is to change tags to be a path instead of a simple name. A full path should uniquely specify a particular object in the hierarchy. We use separate hierarchies for different object types to allow, for example, a vector and a string to have the same name. The relationship of a KstObject being below another KstObject in the hierarchy means that the parent object CREATED the child object. Note that this is not the same thing as data PROVIDERS, which form a dependency graph (perhaps with cycles) rather than a tree. For example, a PSD created with the PSD button in the Data Manager is placed after its source vectors in the provider graph, but is a Level 1 object (i.e. not below its source vectors) in the naming hierarchy. Level 0 ------- An implied single root with no name. It is probably better to show Level 1 objects as multiple roots and have no Level 0 object. Level 1 ------- - Providers/Data Sources. - Global constants. A CONSTANTS namespace can be used (maybe with a full hierarchy of constant types). - Global (user-created) KstPrimitives - e.g. generated KstVector, KstMatrix - user-created KstDataObjects - curves, equations, power spectra, etc. Level 2 ------- - Data vectors read from a data source (e.g. KstVector::tagName()). These names will not collide as long as there are unique names in each data source. - Data source metadata strings, scalars (author, dataset description, numFields, etc.) Level 3 ------- - KstObjects generated from level 2 objects (e.g. KstScalars for min, max, etc.). - Data object metadata strings, scalars (units, field description, etc.) In labels, one can use the full path to specify a field (e.g. [DataSource1/Field1/max]), or start with any globally-unique name and go from there, which is compatible with the current model (e.g. [Field1/max]). Using '/' as a path separator allows compatibility with existing .kst files, but will cause conflicts with datasources using '/' within field names. For now, I'm converting '/' to '-'. In addition to the global lists of scalars, vectors, matrices, etc., we can view the data as a tree of KstObjects: - DataSource1 \ + Field1 + Field2 - DataSource2 \ + Field1 - Field1-2 \ - min - max <========== [DataSource2/Field1-2/max] or [Field1-2/max] - Field2 \ - min - max - units - description + Field3 - Field4 \ - min - max - units - description We have separate trees to show only scalars or strings (or whatever) in an organized way. IMPLEMENTATION DETAILS ====================== Instead of tags being QStrings, they are now KstObjectTag objects. These objects contain a QString tag (the last part of the hierarchical tag) and a QStringList context. The static constant KstObjectTag::globalTagContext represents global tags (i.e. Level 1). KstObjectTag::constantTagContext represents a namespace for constants. For an empty tag in the global namespace, use KstObjectTag::invalidTag. Unless otherwise specified, the context is assumed to be the global context. Display Tags ------------ In situations where we display a flat list of object tags (i.e. the primitive selector comboboxes), we can use display tags. Inside a KstObjectTag there are two variables: _minDisplayComponents and _uniqueDisplayComponents. _minDisplayComponents is the minimum number of path components used to form the display tag. It is set by the user and has a default value of 1. When a tag is created in the context of another tag, the default value takes one components of the context tag. _uniqueDisplayComponents is the number of path components needed to ensure that the display tag is unique. It is kept up-to-date by the KstObjectCollection containing the KstObject. The display tag is formed by taking the last MAX(_minDisplayComponents, _uniqueDisplayComponents) components of the full tag. e.g.: These 4 scalars exist in the system: - The global constant CONST_PI. The full tag is "CONSTANTS/CONST_PI". The display tag is "CONST_PI". - The Max scalar for field GYRO1 in datasource DS-dirfile1. The full tag is "DS-dirfile1/GYRO1/Max". Since the tag was created in the context of the GYRO1 vector's tag (DS-dirfile1/GYRO1), _minDisplayComponents is 2. The display tag is "GYRO1/Max". - The Max scalar for field GYRO2 in datasource DS-dirfile1. The full tag is "DS-dirfile1/GYRO2/Max". Again, _minDisplayComponents is 2. Since there is also a GYRO2 vector from datasource DS-dirfile2, _uniqueDisplayComponents is 3 (since "GYRO2/Max" is not unique). Therefore, the display tag is "DS-dirfile1/GYRO2/Max". - The Max scalar for field GYRO2 in datasource DS-dirfile2. The full tag is "DS-dirfile2/GYRO2/Max". The display tag is "DS-dirfile2/GYRO2/Max". The flat list of scalars will be: CONST_PI DS-dirfile1/GYRO2/Max DS-dirfile2/GYRO2/Max GYRO1/Max kst-2.0.3/devel-docs/general_1.x/datamodel.txt000644 001750 001750 00000001265 11544160206 021517 0ustar00synthsynth000000 000000 A Kst session consists of a data model along with a graphical representation of some or all of that data model. The data comes from various places known as data sources. A data source is a file, network, or other resource that provides one or more primitives. A primitive is (presently) a string, scalar, vector or matrix. These can be composed with mathematical algorithms by a data object. Data objects also output one or more primitives. Primitives can then be associated as relations, such as a curve. Relations and primitives can then be used in graphical representations known as views and view items. Dialogs and wizards are used to hide these representations from the user. kst-2.0.3/devel-docs/general_1.x/memory.txt000644 001750 001750 00000007462 11544160206 021102 0ustar00synthsynth000000 000000 1) Allocation malloc() and realloc() are defined to return null pointers in some cases and this should be tested for. In particular, we need to test for it when we do big allocations. However we may not always prevent bad situations like this. Actually, in most cases we probably won't. This is because Linux will allocate memory to us even when it's not *really* available, and the machine will go into "swap hell" or the app will be killed by the kernel. Linux is the main platform for Kst so it is the primary concern. This behaviour is actually ideal as well, since OOM is generally quite uncommon now, and many apps allocate more memory than they really need. We are a special case and we really do use lots of memory. As a C++ application, we use the C++ allocator whenever possible. For data vectors, we use malloc() and realloc(), and checking for failed allocations is important since users may tried to load in data so huge that it can't possibly be dealt with. Unfortunately it is probably more likely that the user loads in enough to go into heavy swap but not enough to actually fail the malloc. Therefore we have code on Linux that checks the system memory and tries to guess if we will enter this situation. If so, the malloc is denied. You must use the Kst malloc replacement in order to get this behaviour. In general malloc() is deprecated and discouraged in Kst. C++ objects (widgets, containers, other classes) are allocated with the C++ allocator in Kst. That is, Foo *foo = new Foo;. The C++ allocator has one of two behaviours when allocations fail: 1) throw an exception 2) return null We don't use exceptions in Kst, so 1 is not suitable. By default g++ doesn't do 2 so it is not suitable at this time. Furthermore, even if we did start using exceptions or hardcoded the g++ flags in the makefile to do 2, we still would crash. Here's why: It is at least 50% likely that this call will fail in a place that guarantees a crash: QListView *l = new QListView(this); The reason is that internally, it uses [at least one] "d-pointer" which is allocated without checking the return code. If an exception is thrown, we don't really know where it failed, and it's likely we will crash due to null or dangling pointers deep inside one of these classes. If null is returned, it's not checked in Qt and it's likely that it will crash since it assumes that the allocation succeeded. Furthermore, these allocations are generally small, so if they fail, it is because the OS [being most likely Linux] is so far into swap or out of memory that it is doomed to fail no matter what we do, including trying to recover, save data, or notify the user. We're just plain toast at this point. Not only that, but we are multithreaded and we have no mechanism to be able to prevent those other threads from stomping us out of existance too. Therefore, code that checks for null return from operator new is just adding extra indent and making the code messy and complicated for no gain. In most cases, Kst will be horribly inconsistent internally if we do check for null because we just don't expect this anywhere in the ~70,000 lines of code we have so far. Finally, it's important to note that failed operator new is exceedingly rare in the KDE world. Practice shows that there is no tangible gain in checking for this case, and more time should be spent making the code more stable in other ways. 2) Deallocation free() expects a non-null pointer delete and delete[] -check- the pointer for null before deallocating. There is never a need to do: if (foo) delete foo; This is equivalent to writing: if (foo) { if (foo) { free(foo); } } It's just silly. Never, ever, ever mix malloc/free, new/delete, or new[]/delete[]. They are all different and mixing them will just result in crashes. Make sure you match them properly in all cases. kst-2.0.3/devel-docs/general_1.x/codingstyle.txt000644 001750 001750 00000011753 11544160206 022114 0ustar00synthsynth000000 000000 - indenting is emacs style 2 space, no tabs - all files should have appropriate vim modelines at the end: // vim: ts=2 sw=2 et - bracing and structure style is as follows: for (int x = 1; x < 10; ++x) { val *= x; } if (x == y) { z(); } else if (q < r) { } else { } switch (expression) { case 1: foo(); break; case 2: default: } rettype Class::method(type var, type var, ...) { type var; type var2 = val, var3; function(); etc return var; } - class layout example: class X : public Y, private Z { Q_OBJECT public: X(); virtual ~X(); private: public slots: }; - all include files must be guarded: #ifndef FILENAME_H #define FILENAME_H #endif - avoid inline methods - it makes things difficult to modify later - designer .ui.h files use designer default indenting format - don't use superfluous semicolons. It causes compile problems with some compilers. - all .c, .cpp, .h files must have license and copyright headers - all files must be licensed *GPL* unless it derives from non-GPL compatible code, in which case you must contact the Kst developers and maintainers before integrating it - no C++ exceptions will be used - the present hard requirements for compilation are KDE 3.3.0. No new hard requirements may be added, though conditional compilation is fine. - be very sensitive of performance (both startup time and runtime) of all Kst components. profile often - don't make constant unnecessary changes as part of other commits since it destroys cvs annotations - variables do not use "Hungarian notation" pchlzpstrMyVariable style of naming. Qt/KDE style naming is preferred: type myVariableName; type _myMethodName; - public variables should be avoided as much as possible as they eventually will cause problems (circumvents locking). Naming can be myPublicName or MyPublicName. Both are common in Kst. Perhaps this should be standardized in the future. - global variables must be namespaced in some way, and can use myGlobalName or MyGlobalName naming styles as appropriate - methods should use Qt-style myMethodName() naming style. functions should use myFunctionName() or (less preferably) MyFunctionName() - DCOP methods are public, and therefore must always be 100% clean. Do not use short forms, be consistent in nomenclature, and follow the most preferred and already-used capitalization schemes. - Text literals must use i18n(). Be conscious of the fact that translators do not know anything about Kst or perhaps about things like "PSD"s and "fit"s, and that different languages have very different geometry, pluralization, and word-order requirements. Consult KDE developer documentation for more information. - Kst is now nicely component-ized after much hard work. Let's keep it that way. No huge monolithic/multipurpose classes. Use abstract interfaces and concrete implementations, where applicable as KDE-style plugins. - Discuss changes of design on the list first. Commit second. Sometimes a concrete implementation as a branch or a patch set can be very convincing. - Remember portability. Kst runs on many hardware and software platforms, is compiled with various compilers, and is run in all kinds of strange environments now. Just because it works on Linux or GCC doesn't mean it will work anywhere else. - Don't use char to store numbers, use int bitfields. Char is signed on some platforms and unsigned on others, leading to all kinds of strange bugs. - Make methods const where applicable to allow use of const objects and pointers. Keep in mind if something may need to be non-const in the future so that we don't break existing code. - Don't use unnecessary const_cast - much effort was put into making the code "const correct". - Pass arguments and return values as const& where applicable for performance reasons. - Early returns to avoid huge nesting of blocks is -good-. It makes the code easy to understand. Do it, and don't remove it. Use judgement to avoid making soup. - Have care to push class instantiations down as far as possible in scope. Some are quite expensive to instantiate and there is no value in following the old C-style declarations. Instantiating objects that aren't used just slows down Kst. - If you fix a bug for code that has substantial testing support in tests/, you must add a testcase to avoid regressions in the future. - Methods and functions that return their values through references are -banned-. Do not add these as new code, and try to clean up old ones as you go. If you must return multiple values individually, use a pointer. It's too confusing to use references and leads to many hard-to-trace bugs. Ideally use a single structure/class to encapsulate the data and return. - Why do we do this? To make coding on Kst faster, easier, more consistent, and more efficient. kst-2.0.3/devel-docs/general_1.x/appdesign.txt000644 001750 001750 00000002572 11544160206 021541 0ustar00synthsynth000000 000000 Kst is designed as a multi-layer application. The core is intended to be small and well-focused on the core functionality. Additional features and functionality are implemented as plugins, extensions, or datasource plugins. libkst ------ This contains the bare minimum required by Kst extensions in order for them to cleanly link and be sufficiently powerful to perform their tasks. It should not contain any data or view object code at this time. libkstmath ---------- All non-gui dependent math code and data objects (equations, PSDs, etc) go here. This is not presently installed. d2asc ----- A command line utility to convert any kst supported data file into ascii. kst --- This is the core executable. It links to libkst, qt, KDE, and not much else. kst proper contains only main.cpp. The rest is in libkstapp. extensions ---------- Kst extensions allow developers to add functionality that may not be required by all Kst users, or is more of a peripheral or optional component. Extensions are loaded on demand of the user. datasources ----------- These are runtime loaded plugins which add support in Kst for loading files of various formats. plugins ------- Plugins are Kst-independent loadable modules that implement new mathematical algorithms for use inside Kst. These are often of limited or no value to most users, so they should be implemented as plugins to avoid bloat. kst-2.0.3/devel-docs/general_1.x/threading.txt000644 001750 001750 00000006160 11544160206 021531 0ustar00synthsynth000000 000000 Notes on threading: - you must lock and unlock global and shared objects to avoid races - KstObject classes are also locks internally, so you can just ->readLock(), ->writeUnlock() etc on them directly. - KstObjectList and Map classes have locks accessible with .lock() - KstWriteLocker and KstReadLocker are useful to lock an object and ensure that the object is unlocked when (and only when) the locker instance falls out of scope. Only put these on the stack. - KstShared objects must always be used by KstSharedPtr, NOT Foo*. If you use Foo*, you will not get proper reference counting. In most cases a typedef exists to make this easy. - some Qt objects are shared: - QMemarray - QMap - QString - QValueList - QValueVector You need to make -deep- copies of these in particular when using globals. example: KstDataObjectList mine = QDeepCopy(KST::dataObjectList); This could crash if the dataObjectList is modified while mine is being used. KST::dataObjectList is global and used from all threads in general. You need to make a deep copy of the list. - Use a write lock iff there is a possibility that you will modify the object. - Don't make your locks too finegrained. If looping, either copy the data you need in the loop temporarily, or lock around the outside of the loop instead of constantly locking and unlocking inside the loop. - Maximum recursion depth of read locks is 30. Maximum recursion of write locks is 0. Locking for writing twice in the same thread is a guaranteed deadlock. - Locking is generally "explicit" in that if you are accessing object "x", you must x->readLock(); /* read from x */ x->readUnlock(). x will not lock itself when it needs to read members. The only implicit locking happens in a few special cases, and in shared pointer reference counting (semaphore is used). ------------------------------------------------------------------- 08/10/06 How to fix our deadlock issues. Recent changes to object complexity and performance of locking in Kst have brought some old deadlock scenarios up in frequency and made Kst appear far less stable. Past fixes for these deadlocks were apparently insufficient and only fixes some cases. The most common scenario is this: Thread 1 locks Object A Object A starts to lock dependencies Context switch Thread 2 locks Object B Object B starts to lock dependencies and eventually blocks on Object A Context switch Object A continues to lock dependencies and blocks on an object locked by B -> deadlock The general solution for this is to lock all objects in a consistent order, such as pointer value of object or lock. We do this presently, but only at each level, which is insufficient in complex object structures. One possible solution is for KstDataObject to first obtain all pointers requiring locks, recursively, and then sort and lock them iteratively. The problem is that in order to obtain these pointers, we will need to have locks on the objects, thus defeating the goal. It is proposed to split locking into shallow and deep locking, allowing a shallow lock for tree reading, and a deep lock for more complex operations. kst-2.0.3/devel-docs/general_1.x/i18n.txt000644 001750 001750 00000002130 11544160206 020334 0ustar00synthsynth000000 000000 Kst is now being actively translated by the KDE translation team. As such, we should do our best to help them with their task. This means: 1) Make sure you i18n() or I18N_NOOP() your strings as appropriate. 2) Keep in mind that some languages are Right-To-Left. You cannot do things like: QString foo = i18n("My first statement."); foo += i18n("\nmore text"); 3) There are three variants of i18n() and I18N_NOOP(). We need to make heavy use of the "comment" ones because the translators do not understand all of our terminology: i18n(const char *string); i18n(const char *comment, const char *string); i18n(const char *singular_form, const char *plural_form, unsigned long n); The comment one looks like this: i18n("A curve that represents a \"best fit\" for another curve.", "Fit Curve"); 4) Don't change i18n()s if you don't have to. It introduces "fuzzies" and makes life difficult for translators. 5) Be aware of non-language issues for translation, such as dates (different calendar systems), currencies, numerics, and units. KDE provides various facilities to deal with some of these issues. kst-2.0.3/devel-docs/doxygen/Doxyfile.doxy000644 001750 001750 00000203676 11544160206 021100 0ustar00synthsynth000000 000000 # Doxyfile 1.6.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = kst # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 2.0 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = . # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/ # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set # FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = YES # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ../../src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.c \ *.cc \ *.cxx \ *.cpp \ *.c++ \ *.d \ *.java \ *.ii \ *.ixx \ *.ipp \ *.i++ \ *.inl \ *.h \ *.hh \ *.hxx \ *.hpp \ *.h++ \ *.idl \ *.odl \ *.cs \ *.php \ *.php3 \ *.inc \ *.m \ *.mm \ *.dox \ *.py \ *.f90 \ *.f \ *.vhd \ *.vhdl # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = .svn # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = YES # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvances is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = YES # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = YES # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = NO # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES kst-2.0.3/devel-docs/krazy2.out000644 001750 001750 00000116225 11544160206 016677 0ustar00synthsynth000000 000000 krazy2 Analysis Checkers Run = 45 Files Processed = 752 Total Issues = 717 ...as of October 04 2010 10:07:12 EDT ==>For File Type c++<== 1. Check for TRUE and FALSE macros [captruefalse]... Ok! 2. Check for methods that return 'const' refs in public classes [constref]... Ok! 3. Check for an acceptable copyright [copyright]... 5 issues found ./plugins/dataobject/genericfilter/filter.h: missing tags: email address(line 7) (1) ./plugins/dataobject/genericfilter/polynom.h: missing tags: email address(line 7) (1) ./libkst/sysinfo.c: missing tags: email address(line 2) (1) ./libkstapp/gridlayouthelper.h: missing tags: email address(line 25) (1) ./libkstapp/gridlayouthelper.cpp: missing tags: email address(line 25) (1) All source files must contain a copyright header which identifies the copyright holder(s) together with a e-mail address that can be used to reach the copyright holder. One copyright holder per line, with real email addresses please. For details regarding KDE's licensing policy please visit . A typical copyright looks like: "Copyright 2002,2005-2006 Joe Hacker " 4. Check for cpp macros and usage [cpp]... 32 issues found ./widgets/curveappearance.cpp: O/S or Compiler specific macro line#377[Q_WS_WIN32] (1) ./libkstmath/basicplugin.cpp: O/S or Compiler specific macro line#17[Q_WS_WIN32] (1) ./libkstmath/labelparser.h: O/S or Compiler specific macro line#67[Q_WS_WIN32] (1) ./libkstmath/curve.cpp: O/S or Compiler specific macro line#43[__GNUC__],555[Q_WS_WIN32] (2) ./libkstmath/enodes.cpp: O/S or Compiler specific macro line#23[Q_WS_WIN32],389[Q_WS_WIN32] (2) ./libkstmath/escan.cpp: O/S or Compiler specific macro line#511[Q_WS_WIN32],1498[Q_WS_WIN32],1526[Q_WS_WIN32] (3) ./libkstmath/eventmonitorentry.cpp: O/S or Compiler specific macro line#34[Q_WS_WIN32] (1) ./libkst/kst_inf.h: O/S or Compiler specific macro line#21[__sun] (1) ./libkst/psversion.h: O/S or Compiler specific macro line#2[__linux__] (1) ./libkst/procps.h: O/S or Compiler specific macro line#58[__GNUC__,__GNUC_MINOR__],66[__GNUC__,__GNUC_MINOR__],83[__GNUC__,__GNUC_MINOR__] (3) ./libkst/procps.h: Guard #warning with '#ifdef __GNUC__' line#61 (1) ./libkst/datacollection.cpp: O/S or Compiler specific macro line#33[__linux__],47[__linux__] (2) ./libkst/sysinfo.h: O/S or Compiler specific macro line#12[__linux__] (1) ./libkst/ksttimers.h: Unknown HAVE_FOO macro line#18[HAVE_KST_USE_TIMERS] (1) ./libkst/datasourcepluginmanager.cpp: O/S or Compiler specific macro line#247[Q_WS_WIN32],282[Q_WS_WIN32] (2) ./libkst/math_kst.h: O/S or Compiler specific macro line#23[__sun],63[__APPLE__],82[__SVR4,__sun],86[Q_WS_WIN32] (4) ./libkstapp/memorywidget.cpp: O/S or Compiler specific macro line#34[__linux__] (1) ./libkstapp/bugreportwizard.cpp: O/S or Compiler specific macro line#35[Q_WS_WIN32],37[Q_WS_WIN64] (2) ./libkstapp/viewitemdialog.cpp: O/S or Compiler specific macro line#297[Q_WS_WIN32] (1) ./libkstapp/datawizard.cpp: O/S or Compiler specific macro line#718[__linux__] (1) C++ source files and non-installed headers should NOT use cpp conditionals that check for a certain O/S or compiler; instead use CMake HAVE_foo macros. We want to check for features discovered during CMake time rather than for a specific O/S. 5. Check for code that should be considered crashy. [crashy]... Ok! 6. Check single-char QString operations for efficiency [doublequote_chars]... 8 issues found ./plugins/dataobject/effectivebandwidth/effectivebandwidth.cpp: line#24 (1) ./plugins/dataobject/syncbin/syncbin.cpp: line#36 (1) ./plugins/dataobject/linefit/linefit.cpp: line#27,28 (2) ./libkstmath/equation.cpp: line#48,50 (2) ./libkstmath/eventmonitorentry.cpp: line#60,61 (2) Adding single characters to a QString is faster if the characters are QChars and not QStrings. For example: QString path = oldpath + "/" + base is better written as QString path = oldpath + '/' + base. Same holds for arguments to QString::startsWith(), QString::endsWith(), QString::remove(), QString::section(), and QString::split(). Use QString::remove() instead of QString::replace(foo,"") 7. Check for unwanted doxygen tags in major versions [doxytags]... Ok! 8. Check public classes with private members or d-pointer issues [dpointer]... Ok! 9. Check for QString compares to "" [emptystrcompare]... Ok! 10. Check that file ends with a newline [endswithnewline]... Ok! 11. Check for C++ ctors that should be declared 'explicit' [explicit]... Ok! 12. Check for foreach loop issues [foreach]... 62 issues found X ./widgets/gradienteditor.cpp: non-const ref iterator line#76,146,199,211 (4) X ./widgets/stringselector.cpp: non-const ref iterator line#131 (1) X ./widgets/vectorselector.cpp: non-const ref iterator line#194 (1) X ./widgets/curveselector.cpp: non-const ref iterator line#122 (1) X ./widgets/matrixselector.cpp: non-const ref iterator line#132 (1) ./widgets/scalarselector.cpp: non-const ref iterator line#215 (1) ./libkstmath/objectfactory.cpp: non-const ref iterator line#49 (1) ./libkstmath/relationfactory.cpp: non-const ref iterator line#49 (1) ./libkstmath/dataobject.cpp: non-const ref iterator line#102,104 (2) ./datasources/qimagesource/qimagesource.cpp: non-const ref iterator line#538 (1) ./libkst/datasourcefactory.cpp: non-const ref iterator line#49 (1) ./libkst/datasourcepluginmanager.cpp: non-const ref iterator line#136,138 (2) ./libkst/primitivefactory.cpp: non-const ref iterator line#49 (1) ./libkstapp/powerspectrumdialog.cpp: non-const ref iterator line#286 (1) ./libkstapp/legenditem.cpp: non-const ref iterator line#143,251 (2) ./libkstapp/matrixdialog.cpp: non-const ref iterator line#808,869 (2) ./libkstapp/exportgraphicsdialog.cpp: non-const ref iterator line#37 (1) ./libkstapp/viewgridlayout.cpp: non-const ref iterator line#151,318,415,519,548,601,641,657,686 (9) ./libkstapp/imagedialog.cpp: non-const ref iterator line#501 (1) ./libkstapp/plotitemdialog.cpp: non-const ref iterator line#462 (1) ./libkstapp/vectordialog.cpp: non-const ref iterator line#471,524 (2) ./libkstapp/histogramdialog.cpp: non-const ref iterator line#428 (1) ./libkstapp/csddialog.cpp: non-const ref iterator line#278 (1) ./libkstapp/labelrenderer.cpp: non-const ref iterator line#232 (1) ./libkstapp/applicationsettings.cpp: non-const ref iterator line#278 (1) ./libkstapp/graphicsfactory.cpp: non-const ref iterator line#49 (1) ./libkstapp/curvedialog.cpp: non-const ref iterator line#453 (1) ./libkstapp/mainwindow.cpp: non-const ref iterator line#1065,1070,1075 (3) ./libkstapp/plotitem.cpp: non-const ref iterator line#1358,1388,1415,3344,3759,3769 (6) ./libkstapp/changefiledialog.cpp: values or keys iteration line#423,452 (2) ./libkstapp/logwidget.cpp: non-const ref iterator line#115 (1) ./libkstapp/equationdialog.cpp: non-const ref iterator line#363 (1) ./libkstapp/viewitem.cpp: non-const ref iterator line#192 (1) ./libkstapp/viewitemdialog.cpp: non-const ref iterator line#147 (1) ./libkstapp/eventmonitordialog.cpp: non-const ref iterator line#341 (1) ./libkstapp/scalarmodel.cpp: non-const ref iterator line#198 (1) ./libkstapp/legenditemdialog.cpp: non-const ref iterator line#158 (1) ./libkstapp/debugdialog.cpp: non-const ref iterator line#85 (1) When not using POD types (int, double, pointer, ...) you should use const & for your foreach variables. There are two reasons for this: 1) Prevents you from the mistake of writing foreach loops that modify the list, that is 'foreach(Foo f, list) f.a = f.b = f.c = 0;' compiles but does not modify the contents of list 2) Saves a copy constructor call for each of the list elements 13. Check validity of i18n calls [i18ncheckarg]... 103 issues found ./plugins/filters/differentiation/differentiation.cpp: wrong argument count, have 0 need 2 line#137 ./plugins/filters/differentiation/differentiation.cpp: wrong argument count, have 0 need 1 line#139 ./plugins/filters/despike/filterdespike.cpp: wrong argument count, have 0 need 1 line#155 ./plugins/filters/despike/filterdespike.cpp: wrong argument count, have 0 need 3 line#153 ./plugins/filters/cumulativesum/cumulativesum.cpp: wrong argument count, have 0 need 2 line#137 ./plugins/filters/cumulativesum/cumulativesum.cpp: wrong argument count, have 0 need 1 line#139 ./widgets/labelbuilder.cpp: malformed markup (unmatched tags, etc.) line#24 ./libkstmath/basicplugin.cpp: wrong argument count, have 0 need 1 line#231,402 ./libkstmath/curve.cpp: wrong argument count, have 0 need 2 line#381,1540,1565 ./libkstmath/curve.cpp: wrong argument count, have 0 need 1 line#1549,1553,1557,1561,1569 ./libkstmath/curve.cpp: wrong argument count, have 0 need 3 line#1546 ./libkstmath/enodes.cpp: wrong argument count, have 0 need 1 line#752 ./libkstmath/equation.cpp: wrong argument count, have 0 need 3 line#614 ./libkstmath/equation.cpp: wrong argument count, have 0 need 1 line#155,179,228,235,237 ./libkstmath/histogram.cpp: wrong argument count, have 0 need 3 line#426 ./libkstmath/histogram.cpp: wrong argument count, have 0 need 1 line#316,422,428 ./libkstmath/psd.cpp: wrong argument count, have 0 need 2 line#452 ./libkstmath/psd.cpp: wrong argument count, have 0 need 1 line#460 ./libkstmath/psd.cpp: single adjective as message, probably ambiguous; use context call to explain what it refers to line#456 ./libkstmath/plotdefines.h: malformed markup (unmatched tags, etc.) line#63,64 ./libkstmath/csd.cpp: wrong argument count, have 0 need 2 line#90,357,360,381 ./libkstmath/csd.cpp: wrong argument count, have 0 need 1 line#92,198,363,366,389 ./libkstmath/csd.cpp: single adjective as message, probably ambiguous; use context call to explain what it refers to line#385 ./libkstmath/eventmonitorentry.cpp: wrong argument count, have 0 need 1 line#518 ./libkstmath/eventmonitorentry.cpp: reported ambiguous message by translators; use context call to explain what it refers to line#514,518 ./libkstmath/image.cpp: wrong argument count, have 0 need 1 line#142,799 ./libkstmath/dataobject.cpp: wrong argument count, have 0 need 3 line#424 ./datasources/ascii/asciisource.cpp: wrong argument count, have 0 need 1 line#610 ./libkst/datastring.cpp: wrong argument count, have 0 need 2 line#151 ./libkst/datastring.cpp: wrong argument count, have 0 need 4 line#142 ./libkst/debug.cpp: wrong argument count, have 0 need 1 line#137 ./libkst/string_kst.cpp: wrong argument count, have 0 need 1 line#101 ./libkst/datavector.cpp: wrong argument count, have 0 need 2 line#735 ./libkst/datavector.cpp: wrong argument count, have 0 need 1 line#731,733,739,741 ./libkst/datavector.cpp: wrong argument count, have 0 need 3 line#725 ./libkst/datavector.cpp: wrong argument count, have 0 need 4 line#748 ./libkst/datamatrix.cpp: wrong argument count, have 0 need 5 line#632 ./libkst/datamatrix.cpp: wrong argument count, have 0 need 2 line#640 ./libkst/datamatrix.cpp: wrong argument count, have 0 need 1 line#174 ./libkst/datascalar.cpp: wrong argument count, have 0 need 3 line#151 ./libkst/datascalar.cpp: wrong argument count, have 0 need 4 line#142 ./libkst/generatedvector.cpp: wrong argument count, have 0 need 3 line#92 ./libkst/generatedvector.cpp: wrong argument count, have 0 need 4 line#87 ./libkst/vscalar.cpp: wrong argument count, have 0 need 5 line#172 ./libkst/vscalar.cpp: wrong argument count, have 0 need 4 line#193 ./libkst/vector.cpp: wrong argument count, have 0 need 3 line#617 ./libkst/matrix.cpp: wrong argument count, have 0 need 3 line#625 ./libkst/scalar.cpp: wrong argument count, have 0 need 2 line#139 ./libkst/scalar.cpp: wrong argument count, have 0 need 1 line#156 ./libkst/scalar.cpp: wrong argument count, have 0 need 3 line#137 ./libkst/editablevector.cpp: wrong argument count, have 0 need 2 line#82 ./libkst/datasource.cpp: single adjective as message, probably ambiguous; use context call to explain what it refers to line#77 ./libkstapp/legenditem.cpp: wrong argument count, have 0 need 2 line#423 ./libkstapp/plotaxis.cpp: reported ambiguous message by translators; use context call to explain what it refers to line#785 ./libkstapp/labelpropertiestab.cpp: malformed markup (unmatched tags, etc.) line#30 ./libkstapp/plotitem.cpp: wrong argument count, have 0 need 2 line#3264 ./libkstapp/logwidget.cpp: wrong argument count, have 0 need 3 line#57 ./libkstapp/debugdialog.cpp: wrong argument count, have 0 need 2 line#41 ./libkstapp/debugdialog.cpp: wrong argument count, have 0 need 1 line#43 ./libkstapp/datawizard.cpp: wrong argument count, have 0 need 2 line#772 ./libkstapp/commandlineparser.cpp: wrong argument count, have 0 need 1 line#420,463,504,544 ./libkstapp/commandlineparser.cpp: malformed markup (unmatched tags, etc.) line#371,373,375,380,402,404,406,409,456,497,538,565,567 Make the translators' job easier and detect problems in the usage of the i18n() calls. When the fix is not clear, check the Techbase article at for more information. 14. Check for invalid icon names [iconnames]... Ok! 15. Check for proper include directives [includes]... 71 issues found ./plugins/dataobject/interpolations/interpolations.h: missing or improper include guard in header ./plugins/fits/non_linear.h: missing or improper include guard in header ./plugins/fits/non_linear_weighted.h: missing or improper include guard in header ./plugins/fits/linear_weighted.h: missing or improper include guard in header ./plugins/fits/common.h: missing or improper include guard in header ./plugins/fits/linear.h: missing or improper include guard in header ./plugins/fits/kneefrequency/fitkneefrequency.h: missing or improper include guard in header ./plugins/filters/filters.h: missing or improper include guard in header ./libkstmath/basicplugin.cpp: include own header first line#24 ./libkstmath/curve.cpp: include own header first line#32 ./libkstmath/enodes.cpp: include own header first line#34 ./libkstmath/equation.cpp: include own header first line#34 ./libkstmath/histogram.cpp: include own header first line#28 ./libkstmath/psd.cpp: include own header first line#33 ./libkstmath/psdcalculator.cpp: include own header first line#26 ./libkstmath/colorsequence.h: using leading or trailing underscores on include guard in header ./libkstmath/EosA.h: missing or improper include guard in header ./libkstmath/EosB.h: missing or improper include guard in header ./libkstmath/Spectrum.h: missing or improper include guard in header ./libkstmath/palette.h: using leading or trailing underscores on include guard in header ./libkstmath/emailthread.cpp: include own header first line#22 ./libkstmath/settings.cpp: include own header first line#21 ./libkstmath/doublecompare.h: missing or improper include guard in header ./libkstmath/escan.cpp: duplicate includes line#24,490(stdio.h);25,491(string.h);27,489(stdlib.h) ./libkstmath/RED-Temperature.h: missing or improper include guard in header ./libkstmath/csd.cpp: include own header first line#27 ./libkstmath/eventmonitorentry.cpp: include own header first line#27 ./libkstmath/image.cpp: include own header first line#18 ./datasources/netcdf/kstnetcdf.cpp: include own header first line#23 ./libkst/datastring.cpp: include own header first line#22 ./libkst/primitive.cpp: include own header first line#25 ./libkst/psversion.h: put config.h in angle brackets line#1 ./libkst/debug.cpp: include own header first line#14 ./libkst/stdinsource.h: missing or improper include guard in header ./libkst/datacollection.cpp: include own header first line#23 ./libkst/string_kst.cpp: include own header first line#22 ./libkst/datavector.cpp: include own header first line#30 ./libkst/datamatrix.cpp: include own header first line#26 ./libkst/datascalar.cpp: include own header first line#22 ./libkst/object.cpp: include own header first line#20 ./libkst/generatedvector.cpp: include own header first line#22 ./libkst/timezones.h: using leading or trailing underscores on include guard in header ./libkst/objectstore.cpp: include own header first line#23 ./libkst/generatedmatrix.cpp: include own header first line#20 ./libkst/vscalar.cpp: include own header first line#22 ./libkst/vector.cpp: include own header first line#30 ./libkst/datasourcepluginmanager.cpp: duplicate includes line#13,42(datasourcepluginmanager.h) ./libkst/matrix.cpp: include own header first line#24 ./libkst/scalar.cpp: include own header first line#24 ./libkst/editablevector.cpp: include own header first line#19 ./libkst/stdinsource.cpp: include own header first line#20 ./libkst/stdinsource.cpp: put config.h in angle brackets line#19 ./libkstapp/plotitem.h: duplicate includes line#19,27(namedobject.h) ./libkstapp/memorywidget.cpp: put config.h in angle brackets line#13 ./libkstapp/stringdialog.cpp: include own header first line#14 ./libkstapp/dialog.cpp: include own header first line#13 ./libkstapp/generaltab.cpp: include own header first line#14 ./libkstapp/rangetab.cpp: include own header first line#18 ./libkstapp/datadialog.cpp: include own header first line#21 ./libkstapp/overridelabeltab.h: missing or improper include guard in header ./libkstapp/vectordialog.cpp: include own header first line#13 ./libkstapp/scalardialog.cpp: include own header first line#15 ./libkstapp/defaultlabelpropertiestab.cpp: include own header first line#13 ./libkstapp/plotmarkers.h: using leading or trailing underscores on include guard in header ./libkstapp/mainwindow.cpp: do not include QtModules line#59(QtGui) ./libkstapp/bugreportwizard.cpp: put config.h in angle brackets line#14 ./libkstapp/aboutdialog.cpp: put config.h in angle brackets line#13 ./libkstapp/plotrenderitem.cpp: duplicate includes line#16,20(application.h) ./libkstapp/dimensionstab.cpp: include own header first line#13 Use <..> to include installed headers; to include Qt headers from installed headers; cpp file should include their own headers first (but below config.h); other rules apply, see . Use include guards in headers with appropriatedly encoded macro names. 16. Check for inline methods in public classes [inline]... Ok! 17. Check for an acceptable license [license]... 10 issues found ./plugins/dataobject/crossspectrum/fftsg_h.c: missing license ./plugins/dataobject/genericfilter/filter.h: missing license ./plugins/dataobject/genericfilter/polynom.h: missing license ./libkstmath/fftsg_h.c: missing license ./datasources/ascii/kst_atof.cpp: missing license ./datasources/ascii/kst_atof.h: missing license ./kst/main-vld.cpp: missing license ./libkst/sharedptr.h: LGPL (v2) (wrong address) ./libkstapp/gridlayouthelper.h: GPL v3+ or v2-only is not compatible with Qt or KDE licensing ./libkstapp/gridlayouthelper.cpp: GPL v3+ or v2-only is not compatible with Qt or KDE licensing Each source file must contain a license or a reference to a license which states under which terms the software may be used, modified and redistributed. For details regarding KDE's licensing policy please visit . 18. Check for assignments to QString::null [nullstrassign]... 13 issues found ./libkstmath/emailthread.h: line#33,34 (2) ./datasources/lfiio/lfiio.cpp: line#32 (1) ./datasources/lfiio/lfiio.h: line#40 (1) ./datasources/planckIDEF/planckIDEF.h: line#54 (1) ./datasources/planckIDEF/planckIDEF.cpp: line#35 (1) ./datasources/healpix/healpix.h: line#44 (1) ./datasources/healpix/healpix.cpp: line#50 (1) ./libkst/dataprimitive.cpp: line#62 (1) ./libkst/stdinsource.h: line#48 (1) ./libkst/dataplugin.h: line#36 (1) ./libkst/stdinsource.cpp: line#159 (1) ./libkstapp/debugdialog.cpp: line#93 (1) Do not assign QString::null or QString() to a QString. Instead use the .clear() method. For example, "str = QString::null" becomes "str.clear()". When returning an empty string from a method use "return QString()" When passing an empty string use "QString()". 19. Check for compares to QString::null or QString() [nullstrcompare]... Ok! 20. Check for C++ operators that should be 'const' [operators]... Ok! 21. Check for inappropriate pass-by-value function args [passbyvalue]... Ok! 22. Check for postfix usage of ++ and -- [postfixop]... 142 issues found ./plugins/dataobject/crossspectrum/crossspectrum.cpp: line#218,232,240,256,273,283 (6) ./plugins/dataobject/periodogram/periodogram.cpp: line#378,382,490,535,541,602,611,619,737,749,756,761,774 (13) ./plugins/dataobject/linefit/linefit.cpp: line#187,201,217 (3) ./plugins/fits/gradient_weighted/fitgradient_weighted.cpp: line#205 (1) ./plugins/fits/kneefrequency/fitkneefrequency.cpp: line#277,292,315,320,325 (5) ./plugins/fits/linear_weighted/fitlinear_weighted.cpp: line#208 (1) ./plugins/fits/linear_unweighted/fitlinear_unweighted.cpp: line#191 (1) ./plugins/fits/gradient_unweighted/fitgradient_unweighted.cpp: line#188 (1) ./plugins/filters/despike/filterdespike.cpp: line#193,205,228,252 (4) ./widgets/stringselector.cpp: line#74 (1) ./widgets/vectorselector.cpp: line#89 (1) ./widgets/curveselector.cpp: line#62 (1) ./widgets/scalarselector.cpp: line#146 (1) ./d2asc/d2asc.cpp: line#61,65,103,116,125,126 (6) ./libkstmath/curve.cpp: line#518,1094,1106,1209,1299 (5) ./libkstmath/histogram.cpp: line#142,156,202 (3) ./libkstmath/psdcalculator.cpp: line#193,213,222,226,230,234,238,242,246,250,261,286,293,299,305 (15) ./datasources/fitsimage/fitsimage.cpp: line#274,275,281,282,288,289,295,296 (8) ./datasources/lfiio/lfiio.cpp: line#169,253,258,311,550 (5) ./datasources/ascii/asciisource.cpp: line#422 (1) ./datasources/planckIDEF/planckIDEF.cpp: line#315,375,528,623,746,814,1320 (7) ./datasources/healpix/healpix_tools_pix.cpp: line#83,87,765,771,776,782 (6) ./datasources/healpix/healpix_tools_fits.cpp: line#55,64,92,101 (4) ./datasources/qimagesource/qimagesource.cpp: line#121,127,133,139 (4) ./libkst/datavector.cpp: line#454,508,569 (3) ./libkst/vector.cpp: line#398,436,475 (3) ./libkst/matrix.cpp: line#216,225,228,236,245,253 (6) ./libkst/timezones.cpp: line#746,750,755,761,786,791,796 (7) ./libkstapp/gridlayouthelper.cpp: line#351,359,372,383,390,403,415,421,434,445,451,464,484,490,491,504,508,513,518,523 (20) You should use ++ and -- as prefix whenever possible as these are more efficient than postfix operators. Prefix increments first and then uses the variable, postfix uses the actual; the variable is incremented as well. Because of this, the prefix operators are inherently more efficient. *WARNING* Make sure that you don't introduce off-by-one errors when changing i++ to ++i. 23. Check for dangerous or inefficient QByteArray usage [qbytearray]... Ok! 24. Check for Qt classes that should not be used [qclasses]... 52 issues found ./widgets/filerequester.cpp: QLineEdit[KLineEdit],QFileDialog[KFileDialog],QFileDialog[KFileDialog] (3) ./widgets/gradienteditor.cpp: QColorDialog[KColorDialog] (1) ./widgets/labellineedit.cpp: QLineEdit[KLineEdit] (1) ./widgets/datasourceselector.cpp: QLineEdit[KLineEdit] (1) ./widgets/combobox.h: QComboBox[KComboBox] (1) ./widgets/datasourceselectordialog.h: QFileDialog[KFileDialog] (1) ./widgets/colorbutton.cpp: QColorDialog[KColorDialog] (1) ./widgets/combobox.cpp: QLineEdit[KLineEdit] (1) ./widgets/datasourceselectordialog.cpp: QMessageBox[KMessageBox],QFileDialog[KFileDialog] (2) ./widgets/labellineedit.h: QLineEdit[KLineEdit] (1) ./libkst/datasourcepluginmanager.cpp: QUrl[KUrl] (1) ./libkstapp/pictureitem.cpp: QFileDialog[KFileDialog] (1) ./libkstapp/dialog.cpp: QDialog[KDialog] (1) ./libkstapp/filterfitdialog.cpp: QMessageBox[KMessageBox] (1) ./libkstapp/svgitem.cpp: QFileDialog[KFileDialog] (1) ./libkstapp/datadialog.cpp: QLineEdit[KLineEdit] (1) ./libkstapp/logwidget.h: QTextBrowser[KTextBrowser] (1) ./libkstapp/choosecolordialog.cpp: QDialog[KDialog],QLineEdit[KLineEdit],QLineEdit[KLineEdit] (3) ./libkstapp/mainwindow.cpp: QMessageBox[KMessageBox],QFileDialog[KFileDialog],QMessageBox[KMessageBox],QFileDialog[KFileDialog],QMessageBox[KMessageBox] (5) ./libkstapp/changefiledialog.cpp: QDialog[KDialog],QMessageBox[KMessageBox],QMessageBox[KMessageBox],QMessageBox[KMessageBox] (4) ./libkstapp/differentiatecurvesdialog.cpp: QDialog[KDialog] (1) ./libkstapp/dialogpage.cpp: QTabWidget[KTabWidget] (1) ./libkstapp/basicplugindialog.cpp: QMessageBox[KMessageBox] (1) ./libkstapp/viewitem.cpp: QInputDialog[KInputDialog] (1) ./libkstapp/datamanager.cpp: QDialog[KDialog] (1) ./libkstapp/viewvectordialog.cpp: QDialog[KDialog] (1) ./libkstapp/viewmatrixdialog.cpp: QDialog[KDialog] (1) ./libkstapp/markerstab.cpp: QMessageBox[KMessageBox],QMessageBox[KMessageBox] (2) ./libkstapp/viewitemdialog.cpp: QLineEdit[KLineEdit] (1) ./libkstapp/changedatasampledialog.cpp: QDialog[KDialog] (1) ./libkstapp/view.cpp: QInputDialog[KInputDialog] (1) ./libkstapp/tabwidget.cpp: QTabBar[KTabBar],QTabBar[KTabBar],QInputDialog[KInputDialog],QTabBar[KTabBar] (4) ./libkstapp/debugdialog.cpp: QDialog[KDialog],QDialog[KDialog] (2) ./libkstapp/tabwidget.h: QTabWidget[KTabWidget] (1) ./libkstapp/datawizard.cpp: QMessageBox[KMessageBox] (1) Don't use Qt 4 classes that are deprecated. Additionally make sure to use the KDE version of some Qt GUI elements to provide a consistent look and feel for the KDE desktop. The KDE classes are not just adding functionalities to the Qt base class and are mostly not even based on the Qt class. *Please* *refer* *to* *the* *API* *documentation* *for* *details* *before* *porting* *to* *the* *K* *classes*. 25. Check for Qt methods that should be avoided [qmethods]... Ok! 26. Check for QMIN and QMAX macros [qminmax]... Ok! 27. Check for classes that should use the 'Q_OBJECT' macro [qobject]... Ok! 28. Check for signals: and slots: [sigsandslots]... Ok! 29. Check for spelling errors [spelling]... 24 issues found ./plugins/dataobject/genericfilter/polynom.h: line#20[acces],60[acces] (2) ./plugins/sampleplugin/sampleplugin.cpp: line#93[everytime],104[everytime],145[occured] (3) ./widgets/dialogdefaults.h: line#41[retreived] (1) ./libkstmath/equation.cpp: line#493[occurences],543[occurences],546[occurences],571[occurences] (4) ./libkstmath/histogram.cpp: line#148[boundry],149[boundry] (2) ./libkstmath/eventmonitorentry.cpp: line#418[occurences],460[occurences],463[occurences],480[occurences] (4) ./libkst/datavector.cpp: line#366[devided] (1) ./libkst/timezones.h: line#206[customised] (1) ./libkst/objectstore.cpp: line#59[existant],65[existant] (2) ./libkst/timezones.cpp: line#777[abbrevations] (1) ./libkst/updatemanager.cpp: line#81[progess] (1) ./libkstapp/labelitem.cpp: line#78[noticable] (1) ./libkstapp/viewitem.h: line#522[aquired] (1) Spelling errors in comments and strings should be fixed as they may show up later in API documentation, handbooks, etc. Misspelled strings make the translator's job harder. Please use US English. 30. Check for strings used improperly or should be i18n. [strings]... 35 issues found ./libkstmath/labelparser.cpp: QLatin1String issues line#210,214,225,229,239,243,247,257,261,275,279,283,293,297,337,349,353,357,371,375,379,383,397,414,426,438,442,460,464,468,478,490 (32) ./libkst/datasourcepluginmanager.cpp: QLatin1String issues line#140 (1) ./libkst/timezones.cpp: QLatin1String issues line#594 (1) ./libkstapp/document.cpp: QLatin1String issues line#63 (1) Some QString methods (like startsWith() and endsWith()) are more efficient if they are passed a QLatin1String, avoiding an implicit conversion from const char *. 31. Check for system calls to replace by KDE or Qt equivalents [syscalls]... 5 issues found ./libkst/timezones.cpp: line#276 getenv[qgetenv],325 getenv[qgetenv],422 getenv[qgetenv],518 getenv[qgetenv] (4) ./libkstapp/document.cpp: line#148 open[KDE_open] (1) Some system calls are not portable, please use the suggested portable wrapper instead. See kde_file.h 32. Check for typedefs that should be replaced by Qt typedefs [typedefs]... 3 issues found ./libkstmath/escan.cpp: line#48 int8_t[qint8],#50 int16_t[qint16],#52 int32_t[qint32] (3) Please use Qt typedefs (like qint32 and qreal) as defined in QGlobals. These typedefs are guaranteed to have the size in bits that the name states on all platforms. ==>For File Type designer<== 1. Check that file ends with a newline [endswithnewline]... Ok! 2. Check for files that need to be fixed by 'fixuifiles' [fixuifiles]... 14 issues found ./libkstapp/overridelabeltab.ui: fixuifiles needs to be run on this file ./libkstapp/datawizardpagevectors.ui: fixuifiles needs to be run on this file ./libkstapp/contenttab.ui: fixuifiles needs to be run on this file ./libkstapp/labelcreator.ui: fixuifiles needs to be run on this file ./libkstapp/labelpropertiestab.ui: fixuifiles needs to be run on this file ./libkstapp/legendtab.ui: fixuifiles needs to be run on this file ./libkstapp/labeltab.ui: fixuifiles needs to be run on this file Please run the trunk/kdesdk/fixuifiles on all your .ui files as there are some artifacts created by Qt designer that are undesireable for KDE. 3. Check validity of i18n calls [i18ncheckarg]... 55 issues found ./plugins/fits/gradient_weighted/fitgradient_weightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#29 ./plugins/fits/polynomial_unweighted/fitpolynomial_unweightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#31 ./plugins/fits/linear_unweighted/fitlinear_unweightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#31 ./plugins/fits/exponential_weighted/fitexponential_weightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#23 ./plugins/fits/exponential_unweighted/fitexponential_unweightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#31 ./plugins/fits/gaussian_unweighted/fitgaussian_unweightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#31 ./plugins/fits/gradient_unweighted/fitgradient_unweightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#31 ./plugins/fits/sinusoid_unweighted/fitsinusoid_unweightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#29 ./plugins/fits/gaussian_weighted/fitgaussian_weightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#29 ./plugins/fits/lorentzian_unweighted/fitlorentzian_unweightedconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#31 ./widgets/curveappearance.ui: reported ambiguous message by translators; use context call to explain what it refers to line#187 ./widgets/curveappearance.ui: single adjective as message, probably ambiguous; use context call to explain what it refers to line#192,197,202,361 ./widgets/fftoptions.ui: reported ambiguous message by translators; use context call to explain what it refers to line#44 ./widgets/scalarlistselector.ui: reported ambiguous message by translators; use context call to explain what it refers to line#41 ./widgets/vectorselector.ui: reported ambiguous message by translators; use context call to explain what it refers to line#33 ./widgets/matrixselector.ui: reported ambiguous message by translators; use context call to explain what it refers to line#27 ./datasources/healpix/healpixconfig.ui: reported ambiguous message by translators; use context call to explain what it refers to line#34 ./libkstapp/editmultiplewidget.ui: single adjective as message, probably ambiguous; use context call to explain what it refers to line#65 ./libkstapp/differentiatecurvesdialog.ui: reported ambiguous message by translators; use context call to explain what it refers to line#245 ./libkstapp/differentiatecurvesdialog.ui: single adjective as message, probably ambiguous; use context call to explain what it refers to line#110,130,250,255,260 ./libkstapp/matrixtab.ui: single adjective as message, probably ambiguous; use context call to explain what it refers to line#669 ./libkstapp/overridelabeltab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#20 ./libkstapp/stroketab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/gridtab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/eventmonitortab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#169 ./libkstapp/eventmonitortab.ui: single adjective as message, probably ambiguous; use context call to explain what it refers to line#199 ./libkstapp/labelcreator.ui: reported ambiguous message by translators; use context call to explain what it refers to line#80 ./libkstapp/labelcreator.ui: single adjective as message, probably ambiguous; use context call to explain what it refers to line#87,103 ./libkstapp/dimensionstab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/imagetab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/layouttab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/filltab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#20 ./libkstapp/axistab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/labelpropertiestab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#17 ./libkstapp/labelpropertiestab.ui: single adjective as message, probably ambiguous; use context call to explain what it refers to line#70,89 ./libkstapp/generaltab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/legendtab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#19 ./libkstapp/dialogpage.ui: reported ambiguous message by translators; use context call to explain what it refers to line#13 ./libkstapp/defaultlabelpropertiestab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14,164 ./libkstapp/arrowpropertiestab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#16 ./libkstapp/labeltab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/rangetab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 ./libkstapp/childviewoptionstab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#13 ./libkstapp/histogramtab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#110 ./libkstapp/markerstab.ui: reported ambiguous message by translators; use context call to explain what it refers to line#14 Make the translators' job easier and detect problems in the usage of the i18n() calls. When the fix is not clear, check the Techbase article at for more information. 4. Check for Qt classes that should not be used [qclasses]... 82 issues found ./widgets/colorpalette.ui: QComboBox[KComboBox] (1) ./widgets/curveappearance.ui: QComboBox[KComboBox],QComboBox[KComboBox],QComboBox[KComboBox],QComboBox[KComboBox] (4) ./widgets/fftoptions.ui: QComboBox[KComboBox],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QComboBox[KComboBox] (5) ./widgets/scalarlistselector.ui: QLineEdit[KLineEdit] (1) ./widgets/curveplacement.ui: QComboBox[KComboBox] (1) ./widgets/datarange.ui: QLineEdit[KLineEdit],QLineEdit[KLineEdit],QComboBox[KComboBox],QComboBox[KComboBox] (4) ./datasources/ascii/asciiconfig.ui: QLineEdit[KLineEdit],QLineEdit[KLineEdit],QComboBox[KComboBox],QComboBox[KComboBox],QLineEdit[KLineEdit] (5) ./datasources/healpix/healpixconfig.ui: QComboBox[KComboBox],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QComboBox[KComboBox],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QComboBox[KComboBox],QComboBox[KComboBox],QLineEdit[KLineEdit] (9) ./libkstapp/stringtab.ui: QLineEdit[KLineEdit] (1) ./libkstapp/editmultiplewidget.ui: QLineEdit[KLineEdit] (1) ./libkstapp/differentiatecurvesdialog.ui: QComboBox[KComboBox] (1) ./libkstapp/exportgraphicsdialog.ui: QComboBox[KComboBox] (1) ./libkstapp/matrixtab.ui: QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit] (6) ./libkstapp/datawizardpagevectors.ui: QLineEdit[KLineEdit] (1) ./libkstapp/equationtab.ui: QComboBox[KComboBox],QLineEdit[KLineEdit] (2) ./libkstapp/stroketab.ui: QComboBox[KComboBox],QComboBox[KComboBox],QComboBox[KComboBox],QComboBox[KComboBox] (4) ./libkstapp/eventmonitortab.ui: QLineEdit[KLineEdit],QComboBox[KComboBox],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QTextEdit[KTextEdit] (5) ./libkstapp/debugdialog.ui: QTabWidget[KTabWidget] (1) ./libkstapp/imagetab.ui: QLineEdit[KLineEdit],QLineEdit[KLineEdit] (2) ./libkstapp/filltab.ui: QComboBox[KComboBox] (1) ./libkstapp/axistab.ui: QComboBox[KComboBox],QComboBox[KComboBox],QComboBox[KComboBox],QComboBox[KComboBox],QComboBox[KComboBox] (5) ./libkstapp/vectortab.ui: QLineEdit[KLineEdit],QLineEdit[KLineEdit],QComboBox[KComboBox] (3) ./libkstapp/legendtab.ui: QLineEdit[KLineEdit] (1) ./libkstapp/dialogpage.ui: QTabWidget[KTabWidget] (1) ./libkstapp/defaultlabelpropertiestab.ui: QComboBox[KComboBox] (1) ./libkstapp/datawizardpagedatasource.ui: QComboBox[KComboBox] (1) ./libkstapp/rangetab.ui: QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit],QLineEdit[KLineEdit] (6) ./libkstapp/histogramtab.ui: QLineEdit[KLineEdit],QLineEdit[KLineEdit] (2) ./libkstapp/markerstab.ui: QLineEdit[KLineEdit],QComboBox[KComboBox] (2) ./libkstapp/filterfittab.ui: QComboBox[KComboBox] (1) ./libkstapp/aboutdialog.ui: QTextBrowser[KTextBrowser] (1) ./libkstapp/scalartab.ui: QLineEdit[KLineEdit],QLineEdit[KLineEdit] (2) Don't use Qt 4 classes that are deprecated. Additionally make sure to use the KDE version of some Qt GUI elements to provide a consistent look and feel for the KDE desktop. The KDE classes are not just adding functionalities to the Qt base class and are mostly not even based on the Qt class. *Please* *refer* *to* *the* *API* *documentation* *for* *details* *before* *porting* *to* *the* *K* *classes*. 5. Check for spelling errors [spelling]... Ok! ==>For File Type desktop<== 1. Check that file ends with a newline [endswithnewline]... Ok! 2. Check for invalid icon names [iconnames]... Ok! 3. Check for spelling errors [spelling]... Ok! 4. Validates desktop files using 'desktop-file-validate' [validate]... Ok! ==>For File Type kpartgui<== 1. Check that file ends with a newline [endswithnewline]... Ok! 2. Check validity of i18n calls [i18ncheckarg]... Ok! 3. Check for spelling errors [spelling]... Ok! 4. Validates kpartgui files using 'xmllint' [validate]... 1 issue found ./kst/kst_icon.rc: 1: parser error : Start tag expected, '<' not found Please make sure your .rc files conform to the XSD schema found in kdelibs/kdeui/xmlgui/kxmlgui.xsd kst-2.0.3/devel-docs/plugins/StartHere000644 001750 001750 00000004412 11544160206 020223 0ustar00synthsynth000000 000000 How To Make Kst Plugins ----------------------- KstPlugins are modules that can be loaded into Kst to provide additional functionality. KstPlugins are presently implemented as: - KstDataSource plugins + These provide the ability to read in different file formats or data "sources". - KstDataObject plugins + These are advanced data plugins that provide their own configuration dialog. - KstBasicPlugin plugins + These are basic data plugins that inherit KstDataObject plugins, but are provided with a default configuration dialog. - KstCPlugin plugins + These are deprecated data plugins replaced by KstBasicPlugins. - Kst Extensions + These allow entire subsystems to be added to Kst without touching the Kst core. All KstPlugins except KstCPlugins are KDE style plugins and therefore require a .desktop file and must be installed in the KDE standard plugins directories. They derive from the base servicetype "Kst/Plugin". This base type includes two kst specific properties: X-Kst-Plugin-Author: A string containing the name of the author. X-Kst-Plugin-Version: A string containing the version of the plugin. ,desktop files also have additional properties. Here are the required ones: Name: A string containing the name of the plugin. For instance, "My Plugin". ServiceTypes: For KstDataSource this is "Kst Data Source" and for KstDataObjects this is "Kst Data Object" etc, etc... X-KDE-ModuleType: This should be set to "Plugin". X-KDE-Library: The library name. This is not the filename, but a name that is used to construct it. For instance, it could be "kstobject_myplugin" where the library might be named "kstobject_myplugin.so". This must also be a legal C variable name as it is used to construct the function names inside the library. Note: for KstDataSource plugins the name here is shortened even further: the actual library name is kstdata_myplugin.so, but you should put "myplugin" as the value for this property. Some other .desktop properties are also common to all plugins: Comment: The description of the plugin. To find out more about creating these plugins look in the respective file for the type of plugin you are interested in creating. kst-2.0.3/devel-docs/plugins/KstBasicPlugins000644 001750 001750 00000007246 11544160206 021377 0ustar00synthsynth000000 000000 KstBasicPlugin Plugins ---------------------- The purpose of a KstBasicPlugin plugin is to provide an implementation of the virtual class "KstDataObject" via the abstract class "KstBasicPlugin." Plugin writers need to provide a class that inherits "KstBasicPlugin" and a .desktop file. Here is an example of the .desktop file named 'kstobject_myplugin.desktop': [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=kstobject_fooplugin X-Kst-Plugin-Author=Your Name X-Kst-Plugin-Version=0.1 Name=Foo Comment=A plugin that provides Foo algorithm. Your C++ class should inherit KstBasicPlugin and provide implementations of the pure virtual methods found in KstBasicPlugin: //The implementation of the algorithm the plugin provides. //Operates on the inputVectors, inputScalars, and inputStrings //to produce the outputVectors, outputScalars, and outputStrings. virtual bool algorithm() = 0; //String lists of the names of the expected inputs. virtual QStringList inputVectorList() const = 0; virtual QStringList inputScalarList() const = 0; virtual QStringList inputStringList() const = 0; //String lists of the names of the expected outputs. virtual QStringList outputVectorList() const = 0; virtual QStringList outputScalarList() const = 0; virtual QStringList outputStringList() const = 0; Here is an example of a plugins header file: #ifndef FOOPLUGIN_H #define FOOPLUGIN_H #include class FooPlugin : public KstBasicPlugin { Q_OBJECT public: FooPlugin(QObject *parent, const char *name, const QStringList &args); virtual ~FooPlugin(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; }; And here is an example of a plugins cpp file: #include "fooplugin.h" #include static const QString& VECTOR_IN = KGlobal::staticQString("Vector In"); static const QString& SCALAR_IN = KGlobal::staticQString("Scalar In"); static const QString& STRING_IN = KGlobal::staticQString("String In"); static const QString& VECTOR_OUT = KGlobal::staticQString("Vector Out"); static const QString& SCALAR_OUT = KGlobal::staticQString("Scalar Out"); static const QString& STRING_OUT = KGlobal::staticQString("String Out"); K_EXPORT_COMPONENT_FACTORY( kstobject_fooplugin, KGenericFactory( "kstobject_fooplugin" ) ) FooPlugin::FooPlugin( QObject */*parent*/, const char */*name*/, const QStringList &/*args*/ ) : KstBasicPlugin() { } FooPlugin::~FooPlugin() { } bool FooPlugin::algorithm() { //Do something... return true; } QStringList FooPlugin::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList FooPlugin::inputScalarList() const { return QStringList( SCALAR_IN ); } QStringList FooPlugin::inputStringList() const { return QStringList( STRING_IN ); } QStringList FooPlugin::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList FooPlugin::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FooPlugin::outputStringList() const { return QStringList( STRING_OUT ); } #include "fooplugin.moc" The KstBasicPlugin takes care of providing almost everything, including the configuration widget for your plugin. The one thing it doesn't do is provide the actual algorithm or the names of the inputs/outputs. See the Line Fit plugin for an example implementation. kst-2.0.3/devel-docs/plugins/KstCPlugins000644 001750 001750 00000014404 11544160206 020532 0ustar00synthsynth000000 000000 ***************************************************************************** WARNING!!! These plugins are now deprecated. Plugin writers should instead consider writing such plugins by inheriting either KstDataObject or KstBasicPlugin. See the KstPlugin file for more info. ***************************************************************************** KstCPlugin Plugins ------------ Kst C plugins consist of two files, an XML file and a shared object. The XML file describes the contents of the shared object file. The shared object file contains the actual plugin code, and must export a C-style function. XML FILE -------- See linefit/linefit.xml for an example of an XML file. Each XML file contains an node with the following information: All but are required. The module also contains an node which describes the interface to the plugin. This node has children of type and for inputs and outputs respectively. It may contain any number of these, but they must be in the order that the plugin expects them. They are considered to be sequential inputs and outputs respectively. Inputs and ouputs can be or . No other data types are supported at this time. All
nodes must be tables of floats. An array input looks like this:
A float (scalar) output looks like this: SHARED OBJECT ------------- The shared object must export a C linkage symbol: int symbol(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]) "symbol" would be the same as the attribute "name" of the node "modulename" in the XML file. The plugin must return 0 on success, or non-zero on error. It must be prepared to deal with inputs that are not what it expects (empty arrays, etc). Just return an error if that is the case. See below for a list of error codes. If you return arrays, you must set outArrayLens[] appropriately. You must always return the exact number of arrays and scalars as the XML file indicates. outArrayLens[] will be set when your plugin is called, but you may need to resize the arrays. You must only do this with realloc(). Do not use any other memory allocator as it could cause internal memory problems in Kst. Finally, do not, ever, cast away the constness of input variables. This will result in inconsistencies in Kst internally. The input variables are const for a reason and must remain as such. HOW TO BUILD THE C PLUGIN ----------------------- If you write your plugin in C with GNU-style tools, you can compile your plugin like this: cc -Wall -c -o myplugin.o myplugin.c -fPIC -DPIC ld -o myplugin.so -shared myplugin.o You should put the .so file and the .xml file in a common directory. Then the plugin manager in Kst can be used to browse to that directory and install the plugin in Kst automatically. Matrices -------- C Plugins can manipulate matrices by putting this in the XML file. In this case, two vectors will be exported in the vector lists, the first being the parameters of the matrix, the second being the entire matrix in a linear vector. Curve Hints ----------- C Plugins can provide curve hints like this in the module node: Note: Curve hints are automatically generated for filters, as defined below. Filters ------- Filters are plugins that process a given input vector (along with one or more auxiliary vectors and scalars), and produce an output vector (along with one or more auxiliary vectors and scalars). The production of the output vector from the input vector is considered to be the main action of the plugin, and this simple definition allows filters to be easily added to vectors on the fly. A filter is marked by adding the following node to the intro node of the XML file: PID --- A special input node can be specified of type "pid". This will be equivalent to a scalar but it receives the process ID of the main Kst process, since this is different than the one the plugin runs in. Localdata --------- C Plugins that require the ability to store data across calls -cannot- use static memory. This would lead to race conditions and inconsistency. Instead, plugins must use a "localdata" facility. Simply specify the node in the intro node of the plugin XML file and change your plugin signature to this: int symbol(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[], void **localdata) On first call, this will be null. It is your responsibility to populate it with what you like, and it will be passed back to you on each call, with a separate one for each instance of the plugin in Kst. If you free() it, set it to null! For memory allocation, be sure to use only system malloc() and realloc(). If you allocate something more than a simple free() can cleanup, you must clean up the localdata yourself. To do this, export a symbol: void freeLocalData(void**) that does the cleanup. It will be called when the plugin is being destroyed. Parameter Names --------------- Undocumented Error Codes ----------- > 0 Custom error, you must provide a symbol const char *errorCodes(int) which will be called to obtain a string representing the error. Make these strings static! -1 Generic error -2 Input error (something is wrong with the inputs) -3 Memory error (such as malloc failure) < -3 RESERVED kst-2.0.3/devel-docs/plugins/KstDataSources000644 001750 001750 00000002351 11544160206 021221 0ustar00synthsynth000000 000000 KstDataSource Plugins --------------------- The purpose of a KstDataSource plugin is to provide an implementation of the virtual class "KstDataSource". By default this class does nothing, which means that there is no direct way to load external data into Kst. Such a plugin provides three symbols: extern "C" { // Create a data source. KstDataSource *create_(const QString& filename, const QString& type); // Does this plugin understand the file indicated by the argument? bool understands_(const QString& filename); // Which types of data does this plugin provide a data source for? QStringList provides_(); } Generally you will have to create one or more derived classes of KstDataSource which implement your I/O system. Along with the shared object, you must also create a desktop file: => kstdata_myplugin.desktop [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=myplugin X-Kst-Plugin-Author=Your Name X-Kst-Plugin-Version=0.1 Name=My Plugin Comment=A long description of what this thing actually does. You can find a template datasource plugin in kst/datasources/template/. It includes a proper Makefile.am, source files, and a desktop service file. kst-2.0.3/devel-docs/plugins/KstExtensions000644 001750 001750 00000000442 11544160206 021142 0ustar00synthsynth000000 000000 Kst Extensions -------------- These are presently private but will become public once the interface is fully defined. They allow entire subsystems to be added to Kst without touching the Kst core. These are optional subsystems so they do not affect the UI or performance if not enabled. kst-2.0.3/devel-docs/plugins/KstDataObjects000644 001750 001750 00000002665 11544160206 021177 0ustar00synthsynth000000 000000 KstDataObject Plugins --------------------- The purpose of a KstDataObject plugin is to provide an implementation of the virtual class "KstDataObject." Plugin writers need to provide a class that inherits "KstDataObject" directly. You will also need to provide a .desktop file and a configuration widget for this plugin. The benefit of this type of plugin over KstBasicPlugin plugins is the degree of control you'll have over the implementation. Most plugins should probably use KstBasicPlugin, but if you need a custom dialog for instance, this is the type of plugin for you. Here is an example of the .desktop file named 'kstobject_myplugin.desktop': [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=kstobject_fooplugin X-Kst-Plugin-Author=Your Name X-Kst-Plugin-Version=0.1 Name=Foo Comment=A plugin that provides Foo algorithm. You C++ class should inherit KstDataObject and provide implementations of the pure virtual methods found in KstDataObject: virtual UpdateType update(int updateCounter = -1) = 0; virtual QString propertyString() const = 0; virtual void showNewDialog() = 0; virtual void showEditDialog() = 0; There is also a number of regular virtual methods that can be reimplemented as needed. See the Cross Power Spectrum plugin for an example implementation and the KstDataObject header file for API declarations. kst-2.0.3/devel-docs/deprecated/scripting.txt000644 001750 001750 00000004035 11544160206 021562 0ustar00synthsynth000000 000000 Javascript Definition: Overview: A planck-HFI reqirement is that kst support scripting to allow flexable generation of complex plots. We plan to use JavaScript as excellent facilities for this exist within KDE. Requirements: - Complete bindings to all objects - everything that can be done in a .kst file can be done with a javascript - DCOP based commandline tool with konsole - will provide a 'command line' to kst (like sm or idl) - Can be commanded from either an embedded konsole, or an external konsole. - Multiple ways of entering scripts - from command line when starting kst eg: kst -J "file=\"data.dat\";field=\"N15C2\"" bolo.js - From file menue - From DCOP/command line tool. - We will not use automatic bindings. Instead, we will "ideal" bindings and implement them as internal calls to our internal objects - The update thread doesn't run if the interpreter is running, and blocks the interpreter from starting up during an update There will be a force update/repaint mechanism to allow updates during script interpretation. - vectors can be referenced as strings (tagname) everywhere too Open Questions: - kjsembed or qsa? Examples: A plot with points + error bars, and a line fit. The X axis vector has to be re-scaled. var f = new DataSource("Data.dat"); if (!f) { alert("error"); } var Vx = new DataVector(f, "1"); string Vn = (new DataVector(f, "2", start, end)).tagName(); var Vp = new DataVector(f, "3", start, end, skip); var Vm = new DataVector(f, "4", start, end, skip, ave); // After here is unimplemented so far var Ex = Equation("[" + Vx.tag + "] * 0.0042", Vx); var C = Curve(Ex.sv, Vn); C.hasPoint = true; C.hasLines = false; C.setYError(Vp, Vm); C.setPointType(6);. var lfit = fit("kstfit_linear_unweighted", Ex.sv, Vn); var Cf = Curve(Ex.sv, lfit.Y_Fitted); var P = Plot(); P.addCurve(C); // ordering etc............. P.curves.append() etc? P.addCurve(Cf); P.xLabel.text = "x axis"; P.yLabel.text = "y axis"; L = PlotLabel(lfit.parameterstring); L.setPos(0.2, 0.8); P.addLabel(L); Window().addPlot(P); kst-2.0.3/devel-docs/deprecated/manpage.txt000644 001750 001750 00000000662 11544160206 021172 0ustar00synthsynth000000 000000 How to regenerate the manpage before a release: 1. Get the latest docbook-xsl package from: http://sourceforge.net/project/showfiles.php?group_id=21935 Untar it somewhere, let's call it $XSLDIR 2. In the Kst doc dir, run: meinproc -o kst.1 --stylesheet \ $XSLDIR/manpages/docbook.xsl index.docbook The output file is kst.1 . The message about 'unable to parse index.docbook' appears to be harmless. -- Philip Rodrigues 2005-01-17kst-2.0.3/devel-docs/deprecated/install.kst2000644 001750 001750 00000000254 11544160206 021271 0ustar00synthsynth000000 000000 1. Download or otherwise install Qt 4.3. 2. Make sure your QTDIR is set to that Qt 4.3 installation. 3. cd /path/branches/work/kst/portto4/kst 4. ./build-kst 5. ./run-kst kst-2.0.3/devel-docs/deprecated/triggers.txt000644 001750 001750 00000001253 11544160206 021405 0ustar00synthsynth000000 000000 For triggers: ============= Add to Vectors -------------- - triggering will be a property of vectors - add a grouped option section to the Edit Vector dialog called "Update Options" - have two mutually exclusive options in this section - Read from file continuously - Only update when triggered Add to Events ------------- - in the Event Monitor dialog, in addition to Kst Debug Log and E-Mail Notification, add a section called "Vector Triggering" - in the Vector Triggering section, have a checkbox called "Trigger:" - to the right of the check box, have a drop-down list of triggerable vectors (i.e. vectors for which "only update when triggered" have been checked).kst-2.0.3/devel-docs/deprecated/Kst2000644 001750 001750 00000001515 11544160206 017565 0ustar00synthsynth000000 000000 List of items to consider for Kst2 - mostly because they break backwards compatibility or require hacks right now: - Make data sources also data writers so we can save to formats other than ASCII. - Clean up data types for plugins. - rework update() to be two functions, one which does the "infrastructure" part and one which is reimplemented to do the things specific to each type of object - move isValid() up to KstObject so that KstVector can use it - remove duplicated tagNames() (the non-const one) from KstObject and make the const one virtual - kstdatasource.cpp : configWidget() needs to be non-const - kstdatasource.cpp : obtainFile() needs to take a widget - KstObject: setDirty(bool) needs to be virtual. Maybe also dirty() - Rename rwlock.h to avoid global namespace issues - data sources: fix the load/create/save mess kst-2.0.3/devel-docs/deprecated/whatiswrongwithkst2dplot.txt000644 001750 001750 00000005003 11544160206 024673 0ustar00synthsynth000000 000000 Kst2DPlot is a monstrosity. Here's why: 1) No single person understands it. Some people understand some of it. No-one understands all of it. it is quite possible that there are some parts of it that no-one understands. 2) It's HUGE. The header file alone is 630 lines. The source file is over ten times that. 3) It has all kinds of functions that are unclear or have side effects. Example: setBorders(xleft_bdr_px, xright_bdr_px, ytop_bdr_px, ybot_bdr_px, tpx, tpy, p, offsetX, offsetY, xtick_len_px, ytick_len_px); Can you guess what that does? It actually -gets- some values, for instance. 4) Can you guess what any of the variables in (3) mean/are? 5) It's C masquerading as C++. It's a whole bunch of function calls that call eachother in seemingly unconnected ways. Change one, you break something elsewhere. 6) Too many ways to do things, or too many things that look the same but aren't: void setCursorPos(QWidget *view); void unsetCursorPos(QWidget *view); void drawCursorPos(QWidget *view); void drawCursorPos(QPainter& p); void updateMousePos(const QPoint& pos); 7) Too many different internal states that get flipped back and forth externally. Display and state need to be separated. Caches should not be an internal part of the object, they should be abstract. 8) It doesn't come close to following our coding conventions. 9) Shortforms abound: setXTransformedExp, etcetera 10) Lack of verbosity: bool suppressRight() const; void setSuppressTop(bool yes); 11) Implementations in the header file. Makes it hard to fix things properly: int xMinorTicks() const { return _xMinorTicks - 1; } int yMinorTicks() const { return _yMinorTicks - 1; } bool xMinorTicksAuto() const { return _reqXMinorTicks < 0; } bool yMinorTicksAuto() const { return _reqYMinorTicks < 0; } 12) Passing return values by reference parameters! Evil! 13) Public methods that should be private 14) Way too many things in one class - there's no reason for it to do time conversions inside, for instance 15) Public member variables!! 16) Pointless virtuals 17) Count them: 107 member variables. 18) No design documentation 19) Inefficiencies all over 20) Algorithms are undocumented and unclear at best, mostly voodoo 21) Too many options are causing way too many branches and nested branches. This makes testing particularly difficult. 22) float<->int conversions are not well defined, happen far too often 23) C-style casts all over 24) Magic numbers like 1.666666. 25) Dumping grounds are just not cool kst-2.0.3/devel-docs/deprecated/future.kwd000644 001750 001750 00000051003 11544160206 021035 0ustar00synthsynth000000 000000 PKv1(/`mimetypeapplication/x-kwordPKv1;d!% maindoc.xml]{SH{Sr60LMvg\p;wV[j=jMw9ݒm!ȁ@S;A/_Gǫ m_/*%&@2^z>ZZ_{og eg[lim}A]YR__?]G+ qlן}m @^Iɀ[Zvˌc˯>iTBi~{_cvHziVԷjr=QVp Q~<ەzĺJu(oBpvϷ :{yUi)`֍$zٜ6maOZca[0`]-^g2V{^uǭCDgX8^0* I{CX^pxC{s2_v`y-kC5zX>szt黽݋C7yM2NXxħmyfr_y1=ͨe}\PP"dǵax7f'jXaU(Q{\ m~#I4| v?ڻ7lҫ}#w jP=I,V?i^Z1K@$AqF(&~8RA $m 2vm#iRpcV@w=ՠaQ3vCc4 -ÌWpRl^B Luy&@ B/ +VAVh@ELv3]U%I;  ç(DisDh`7M2|TW;x\r…ۑ5 ,'0_KFG}qN$ܤ2o;EYe-\@&AhRVoeتgA,Nj:_o67Nw.T ; [ƸDDBN x!? ă~zA_1*xv 9։6Q#bRAN0O5xA_pOIAQk5Wk$V@k8 5=+ҵpfTfDsq3zۘsSC ^k`;i_d.u:lރOݔ@5.[L}~Uv_ZJPՍc|i`˂Oj?;:#Tf^?ԪJ{ʡp-Ho['̀Y(H:yi9Cy&A\PT@, sjbNS3TvcOk5 2Z=]W0#b#с4f@7[P); U"3K'cwA՗ƪ}q#ϰn'3hA5TIl؅ظ }ٵ("J*8AgLp3^rj0Iaj_Xt$ })ACLJJYbF.˂b+Xqɜ}Pދ,E}U\Q+Rx ؃ԚǽJkLE$̨ DDD(eeœ.lSFr溼>UK 6>Iu6J3 ٟ)gx H^E\ЇLǍ(oچסOLjSE K/!!@X-&p< !LŘ|3ƥɎe驜 D4kf>Y|j}N͙fU2OeYE음a2Z#C Bx!$'Kd9Xz[# Oxr!arg*,6yb 07*5C(Pyp >t os Ҡ0D/0^TCnk{a5C:Q!}ktAl Θ2P_XF&gϡqJ`$0N,c@=MqZ/3zBuƓ9, JCoE_VJA.<(屰=>ʄ:KkG 52<l^[a˙#H JLL D?EP(뻨Mm|Z}qj==\$?Z[9A5" x \9V^+ts"Q.TxBC^GF 8IUn/=W'~-;KX%w?e%Us<k+f,be)B/dbLR7`@p AV 0q~Z1C"|D#իTfo\*| ۤl!̩+5ęj<@ӹD~t*7HYPvSOCg  :'td ѕOp:[܏1 EJ-SzQ P3*^X{vK ,7 VsrAp}qp4C ^-Рp:BbS/1 ;Cqx"Fb|H,qH@%>oR]6"M"MGr l> }nOA>E0<4}!2cj)R; r!D(]q2U j3$/DlAP{%<>™ ե)[DwU2+3A Oivh+c_"N![wFfpA( ;Ã4Ij1r/]\t ,0ъ Ŧ8S˄J MhX.-g^Pjc1{>B_c^Gԕ_.}2iiGԺ6xM 9ˠ[,@b?Q?DP:kr!x~J-KDfaLaE=-'4WU>˯!=XV5sE"s;^21 37:y.B6H'8=W_ϋ>[%g.t e#d`ɠf<)fY', *XNqI$.9qG:Y@DR}aa [ʨdNjI@@؝HJ9_pQt+D(BHш @ViՉp)r 1+E2<2(^ܗ[9VH0R<&QvAg/ގ! li0eb5Oğ?HaC KET O1Jr(X~RAvEC^HА2| 3z| 7B@fm ('au׉#2ƱwL$f2̠ 6LQ&8 !uRB,k ,x,7'sXDSf5--t8 4ĻDƟ( ~  :%PP"gMDz*"t?8W,M~{k&rpv^W3X5]5#Y*v&݁+ @G@V+x{Pi٠h c& Ϭ2&tw/c[;: eczνx=FmW]]'V 2/>-L%a@Z 6nR'k.8ewg?kya@ 1[n1V$f~4wVe+@õW5Ts@neC:T}-3h|6)v,4 =uFVuf\0N嚽s0&e Ljz-/t96dU#•ҼwKu _h/Nf /! 5vrA _gy @[6О.RTYZIm蒇ǑvPT(pU"Yo g{`mCg|vAXTmT;ߡҙdH~%EUj]j,Kڕ3aJ]x_:l.ťy9ek$~ɑR1!쫩v& 8i0`uℰݛlE_vuG-fef @"K^M1LKs!> *c@~.W8:b!xdd;U+*OZa GR~~( [~Cs>i]fjHcなJs}1:ŽDN{!Ch#{ r٥O厲V ^/m+kMơM YX 6xjվ:Ɇ1τWڸ ajW3k6ELx%^^7!)xY*~[e=KyK%>6!b دŠv|g˯SGF(n%91jH(2ɭwo껍n//hw/zMkjݑI!9PA\ 6H83=֝$ cu:nWrF/i'7˧τDOOx=$G"'#;c81֟-1|!|$t,],z}9þu|}:wFrGXQg}1BPfHA">KsCb3y7fg6A"i+6Yeu'eM)ifã9|~6aְ/:iJH_B;mo~"׿x pc ?o 5Hܸc_[ߟȅxE>W*J1=ÿMbqMgF7ADmW*p}I\|;gxpIK[lho^6fvw(vH |!7[h}k}AUF'XhQdPp57aiŖ}R}w5R^:W{wx5|^|4oON:__n/ Čef7_{=zo<|V_P]~cdx'ѼlHEg75}s/:K띵/Wv[իPKv1w[2Wdocumentinfo.xmlQn0 =q٪ʀ(RժeCLUǎK;P:t=?|g鱶CnG g4n7!@y\}$U-WϏs!YRґp8ᆰLS", ZJ^ga;~IGH "RmPTSF e?h6Vb _7}"wBZ{{gzPGט;hc^D6e#_@0P}47CK=ڢ@,7t&?|PKv1qB1?-(. preview.pnguZUT\ ww%Y,Kp ,}<~ӧ̙PVFC!Dh2 ߠ{'@Y^]v    A0зV `@_P @(Ab6VC!@ mkA` AX&  C`Z! ` B(ix%MۤWWf蛠A }:5A` }5  k- A! (͌7^_x}M++W7bBbAߜ{KƯCߌ|:5@諯r_Y&P }m+7oyzk}777зACVV zv{5UB7@7B@?B%?&AÂW /^&"%>6r{qB[;0^fea_[5~'&&Vɭ㧧<|'K =+d$ 6ꦶ޶JwH#c󁁁e 9@V⳺Gw<IJK'"~DF:wf~{ov-&jߐ S_idp[\&O;/ry{Wxo<>>} ֩v*֕ϳP *"/4Sy5T٭`PH@z՞f+zouz-S,*(.?Jg/6/z_.$W]4ƞۆy)lĉ KlO\F-'OnsFKnb dE< dc,~}Lj?o&#?B7J9jNNjEk*į,{~A_AлfNS$thYN/dgal\?%6j^ gyxqW"ϥsvf#%и&e%-A38/ܹt& %9IOӄ+@A>i,;bNHeLu4acamwS)wȬA8:Ird8O*D{?rߙ-tgr<ːTb),+5Dҳw~PP%elmpo7&ѾE"M)R`ZE-(EgԤ@Jz*¤{>g7H-]µtͥ'WZ@u^k?qd S. _ew'RM?\|~f]53-bCrIwՖ6O;Gtؒ۬\*X"]ORםvFyJ j{=2y 6is;ßd'VeA~x~k\}'W5,Jѳ.e+xTe{pI׆$2F6&e߳u_[[7wdX0S3S}B@`/3hgX]N=kx|8ݩ&{/4݉:* ɳٔ";yّZ7(%PP b ^* )]2` ,"2d88Y/"zQ0! 2}_5UeUxRqI;VN*sXeGD{Yu_GN?3uGaVHmV %Lf}|q` ;q¼0 ~Ư 6G3wf`0 ubrzPݨH6"n kX<-à:#LAY[lmc6u):nm g߉V-EzAg}&0bjݖX *.NQhtѬLJu0üOQX`C%\[jgҞٿ@'Aw+_kwLWRl>=x)9 8ܫ%1e;Uu;vD#%+ ~3 }\ r*FVdٸ>'p=9!#LFa3 (D‚zY'/)#w1%bOTe?6-ϣ TJEJ~ok nw(,u̘1)z65=?_H&E1~{zr^vІ@#8zw oJ)Od*lqd~v fi"@|SjS|R'3Ƭi$4EUʞh&_K◲()/f8E%E2"0{:tށ ;,hjhYpCr)O>zAt`khgB©'-3!/q)W7eS+ej`dcZw(NF\勻 5o8eTPܛb;T,{eb\_Eβ*$dpmz.|H2`C[¸1EZ[bdNn ѕ̞ Ǫ{I1ѡT B0OMV t9q3I&hB5kXV3;L"5⧾3_Lt3JIZ۶hA1<{x K 4#< 3TEb@SM\+}OْkR))Frk%@sXX$8WN mZ0x'Krq{:o'`3@Η!-\ ){̧Y0K5(**kQJ AB~nN6 MBoNkS쯤*+R}0Da"mV8(ҨM(㖘?7OjojX9-VBYOWy@e ()z_ԭYE8p0K  qbm 1OeiAHXjl!|池l( Zΰvk}yi̇j q:82e/8-۔hX]NOG1-V^C. )=ꯤLJ'R[1*;{iu\ZCڔe՗{׼X]ۏPMޗu Jݮ|?˥U j>7=*R8 */O<)tW֛ 俋i)hw1F1\˵=,:,C:h|dKdֱ ukG҂iY_6+kYjd" _("4N!&.^/n7lyF%ғDO(ԄH%JP5?!'P&ːMRb.4lh l#RTVPydya$̺?PS&.܎[ f]uQQlX> l+U}5r|D'-$:-}99#0ˆp=(?./F?b`m[I B#a_6`etrG ^hT10 5ṯ5b*Tb>_[Dd^% *>VY| Qi7ϲQ ͯwp'rZme E[gHTrz\OD^aƫu0jZeYsgKj"jF*W e&/vO5VǑ *lΰr_$踋dT,Ԣ?[(< Ge+Z9a]w<ulM*h$JM[Ǒ [0*/l!.?HtĽ:I"jL~SN<+z ߫Mwׁn"W![\SHH+*%H4O9;&feX@gcFi*52.%'هBJ/81I$ŵn'D"!3d ^s٩IY[apy q& ?VFǬRV|]AY,g;Ye7ċ'$z`YՉ^!7|ۯ)ۿj赃,+(+MV>b<YmՐ3r}쪊H5^":s.fF,F-YKA[/c>-| 5$~ηՠF2jmgbݼWE '[khIf=(l=?Ǘe<9*W{Cfu!4Sp k'XCyehs³ Rv!es`5iWjLY, ާ2;z'yB4tif'3_wOj' "Gflx|nYɖ]ݿEɏCQNvVVj2f2ӇG&+ <=>D>U TޕMzw0?#jH2,]ۦmLOa M=n^eMihZ;2uAv~ |k4YQ!0{v>|{DXC42_>/tY X."h;oVtD0`X𬭟ZLZFyjh7Ff| lKk91U~YobuNm_R4%Ĭza!AeAp@. v-kyfvm볽A%ӖV_drUm8ʔօKbśy2c>ցdB"?bZa3ԉmaʉo":xZ~Hn*}胗쟑uY:z-^| Ƣ?׵HE$ZގP}FyjU*VL8 ^%RCQΓ &y;F=mDW5+&/fsBI&ڮp;Ula/ֽ!f[QB_{yN]\CaX4i$VվhIkor|mSOSԦͥ%&R#trW5vgH kh4חɕ-5VF nUYf~DX`r7̆{N\[h{Nm50LfݳM*8{~t.,u u!YN>U]4~PDyihmО32O"e߸e& rBaC,077HIg+N89.WŃ';0fz}y0~o&i d gF$sC8d>/RIE_+FB)l=I؎vH~GlVp,3f]wӾ,ڮܤW 㙡Nc[#>𰠳1dI桪dE,uEB2ϥ~:|v ^4yI1n4 ã'YmIc}cFt @ki%=J)?3Jpm`*euOt53h$Qb, \[OXiUj^7ClOKUF>~"j" RTѯfc42U\{b jz%c4iQ$|<_ֹ2؛N#W I`y4mS])ݴ;3AgB -nkL뺁&'b61RUVSֶ3Glh8xL)nQ-ѝh\ p%&S: LSz$cFi9ɵ_SF(?L0wv H≷L?座T{PVM;4|\ 8L3JP ShdIPfNٿ!T~Ϝ;ͪ_xƨrb ?k' m0xX8G#5 a [&vag=b{_]e-dz'&8e׊y>MyVN<$9Pea}LskT~"U?8R J#/eL7ޡ+ @g0?T"Gx2G>ſ7\:vwaJTLOxɪe fQ1\NǠĖn?ާ830+4 ǽ)&F`eЯ)hbی5쬹4~wcO?'A$t|+^%@@ΓnDXCn@mwuXh C.uj-> ]њjC]Яkl9bh'tO|7m V\|451_ ?UO©Vȍwc[5`u_p"x>J9NggG$ >#J7:8kKKm<%Ea~/=QfN[\# ]P> 7D KT3 EWoi e׮bB@9|䀶ݧ͐ZYf&Lof Lr-o&(LPe;Nj;YNyY*Ŗ&Aɔ\Ƞ!v5KK_"ǵ;~Nbq1;e%V3od4}CH]ćut Hjjpt=}v#pⶪ˘NvRr̜6G$,I y™<t%lzt47-/34&Pn ^,)L1ݳgN4#Q-|\}h>N`e+O':^74VRs]YಲHoy=$=.QKg*gc Ͽ%ZDV W!eڗ $y/V&!)On*{V|eY>M"5Z)l0)e+(P²ًLstg9t ɓCtV[iLarz\p>`l }Y~ևNPźTB/4&r37Ww4Cld3paӑfc+7ETԢW1LP$4[oy->7!RM׺]F~aj-͟hx>(a4KO9fFz_p ҋkeV7CwD֌7{9o` Ɉb#CFl%CأRՑk QUvphrZ__,F~[+pҲ#~j ?g_5/*ka2cm6p^Cwxoy!hI@s} 80K Qo?r˛\П,X7UȣVwydsAҞ18H?cr 1d.wQC2.4ȩp_|v9;RVDAHs@%4#<&]ʙ6xkХnk20o=>"(JWkR@wDB?8 y\CaPEeÙ3B:Q!;M Vqo1ew6c>*;7NiWr *"Rgu94Fc8ة.jAY{m-F^Fb4\8 v'M<+~ۃ4>?xybgkьKoc ;,m[O؍}r"JLXd5 d0SP,_ 8I^^jrQ~[sp43@6&i~=tǍ+Y잱s5@ E)M+, RIN6pCУR\X}mjsd'N[|Qb\ 7?3luQ(i'$ 3˜6펿^RQqb^mZ"H/Os#6>aH]X_*6d,II45m{?8!'aa )KJ $W0s\oEY?yc`$69RdNf@[8bQ3K<j`YG'd; O*;!?g$PI-k'hC-bz hӒFǟn ^vjlm]޳y^VxrIz+#ҜRgHkw;Wdnj{9Km7-N1R2f3)5{dJȜm6m1ň4)S(JSE-?)]ܺʝQμ(-ko 9jh; ]].oe{gŭoMkਉd!F!CN_Cǧ ۄa '!93jB]KELu[/v Ž2nO'u;ᱺ4%TSH\< ZgM1}jRdX-J܊7R"L0YlEߟ20 7{w*㲐i" 78wܫ]o.~G̫ |z2gXbóA$>$M}>+qy~_BO~]YuJݳʛI#n6R}1f 6fzrC*;A r@mO瞏mZ|BpS&M:'[1ιt-%dWXP[weX.,Hge' $oYIEJ1PKv1(/` mimetypeUT_APKv1;d!% 9maindoc.xmlUT_APKv1w[2W !documentinfo.xmlUT_APKv1qB1?-(. &#preview.pngUT_APK Pkst-2.0.3/devel-docs/deprecated/whatisrightaboutkst2dplot.txt000644 001750 001750 00000002602 11544160206 025015 0ustar00synthsynth000000 000000 Kst2Dplot rocks: Here's why: (loosing just one of these, while fixing every single item in whatiswrongwithkst2dplot.txt would be a loss). 1) Well spaced and scaled axis labels 2) Well placed and scaled axis numbers 3) great default tick size and spacing 4) good control over tick density 5) rotateable axis numbers 6) Time interpretation for axis numbers (many sources, many output formats) 7) rotatable axis numbers 8) Optional major and minor grid lines 9) adjustable forground, background colors 10) adjustable major and minor gridline colors 11) surpressable borders for adjacent plots 12) easy interface to log-log, log-linear, and linear-log plots 13) Transformable top and right axis 14) Convenient autoscale 15) auto-border mode for plots 16) Spike insensitive autoscale for glitchy data 17) Fixed scale mode. 18) Excellent mouse interface to fixed scale mode 19) convenient ability to change only X or Y zooming with the mouse 20) rmb interface to match axes between plots 21) plots borders auto-align when plots are in a grid 22) plot markers 23) rmb access to filtering or fitting curves 24) exponetial notation in log plots, when reasonable 25) plots can display curves and images 26) clicking outside the plot region brings up plot dialog on useful page 27) very useful keyboard interface: (lots of items here) 28) plots inherit all the coolness of view objects. kst-2.0.3/devel-docs/deprecated/future.txt000644 001750 001750 00000020331 11544160206 021067 0ustar00synthsynth000000 000000 kst: Long Term Goals Barth Netterfield Nov. 18, 2004 1. Overview: Our goal should be to develop kst into the premier data viewing, plotting, and light data analysis tool, prioritized in that order. In particular, we would like to directly compete with (and eventually surpass) sm, pgplot, and xmgrace. The rational is to have one tool (kst) be used for data display at all stages of an experiment's life, from real time data collection to data analysis, to publication. As our most important specific case, I would like this to be true for the Planck-HFI. I believe that we have created a framework in kst which is capable of attaining this goal, if we remain disciplined about both UI design and code structure. What follows is an incomplete list of the types of features we would need to add to kst to fully achieve this lofty goal. While the priority of many of these features may be relatively low, nothing should be done to the kst code base which would impede later upgrades to these features. 2. New Capabilities 2.1. Data Viewing Currently, kst is very strong in many aspects of data viewing. However, there are a couple of important areas where it can be improved. i ) advanced Image based data representations: * Waterfall plots (builtin?) * focal Plane visual representations (instrument specific plugins) * simple binned maps (plugin) ii ) UI enhancements: These require some discussion * Better auto-labeling * add-curve from context menu * edit parent data object of curves from context menu * QuickStats(tm) label in context menu * X-axis sensitive Y auto scaling * X-axis sensitive curve fitting iii ) Colour co-ordination: psds and histograms should default to the same colour as their curves iv ) Shift/scale for RVectors: to, eg, allow easy/fast calibration for datasources that don't otherwise support it. v ) Time Awareness (input) * Data sources need to have a (configurable) TIME_ field, which is A* + B. could be, eg, INDEX. The configuration should be on a data-source by data-source basis, and should be cached (how to avoid this growing to \infinity?) * Vector limits everywhere need to be able to accept time rather than INDEX for ranges. 2.2. Plotting The goal here is to make kst suitable for publication quality plots for a sufficiently large fraction of cases, so that a second tool needed. i ) Asymetric error bars: currently only symetric errors are supported. We need a mechanism for s+ != s-. ii ) Floating labels: labels outside of plots iii ) Alternate axis limits: (eg, wavenumber on bottom, frequency on top) iv ) shared axis: (eg, Stack several plots vertically so they are touching, all with the same X Axis, only labeled on the bottom plot) v ) sparse symbols as suggested by nicolas vi ) Configurable legends: * Ability to add text (including latex) * change curve name text * change listed order * Floating legends (shared between multiple plots) vii ) Drawing elements: * lines & arrows * Shapes (boxes, circles) * fills (eg, shade, hatch, or blank regions of the plot) * curves viii ) R to L language support (?) ix ) Better control over symbols * sm options (#vertex, star or polygon, filled or open, size) * png (etc) import * select indexed from a list (V[0] uses png[0], V[1] uses png[1] etc. x ) Better latex support in labels * more math symbols (sqrt, matrix related) * vertically positioned integral and sum limits * multi-row equation support, not just 'inline' equations. xi ) Axis property control: In an 'advanced' dialog... * line width * tick lengths * line colour different from label colour * t type axis rather than box axis xii ) Layout mode magnetic borders xiii ) Alternal base for axis (eg, hex) xiv ) Other types of plots (eg, Polar) 2.3. Data Analysis i ) A spreadsheet mode for looking at and hand editing data vectors ii ) Improved data export capability: * Multi vector * Subsets defined by X vector * Subsets defined by current plot ranges * Output to other formats than ascii * Interoplation in export iii ) Scripting environment * Loops & branches * subroutines and functions (which can take all data objects) * Natural format equations (ie, e2 = i*v1 + s1*v2^2) * String handling * String lists for creating data object lists * Data source list, Vector list and scalar list indexing * Vector element access * Convenient access to plugins from scripts * Script command prompt * Scripts from files * Access to command line arguments in scripts * Ability to extend UI from scripts * Access to timer system from scripts * Full control over labels, plots, windows iv ) plugins * Despike * Deconvolve * Gausian fit to negative gaussians * Differentiation * Integration * FIR time domain filtering * Fit to RC modeled Cosmic Rays * Fits to arbitrary equations v ) data processing optionally limited to current view * Fits * Stats vi ) UI for creating functions (and perhaps subroutines) as mentioned in Scripting Environment. (this has previously been referred to a 'filter sets') vii ) Math in labels (ie, [S1_BOLO1-rms]*2.0) viii ) consider allowing non-power of 2 FFTs (use gsl or fftw?) 2.4. Other features i ) Access to data sources using KIO: This will work like an indirect file, and will allow reading of archived data only. ii ) Embed/attach vector data in kst file (option at save time) iii ) Allow saving and loading of kst files via KIO: Particularly useful w/ embedded data. iv ) Drag and Drop * Drop in other apps as png/ps/pdf (think KWord or KMail...) * Drag between MDI windows * Drag between kst sessions v ) 'Database' system for scalars: we need to be able to turn off the MKS constants (rarely needed in the general case) and add other experiment specific scalar lists. vi ) Make a KstPlotLib to allow kst to be used from C++ programs (reverse scripting....) vii ) Make .kst files a recognized MIME type: This will be very useful when combined with embedded data. viii ) Make kst a kpart: to allow embedding in konq (kst as embedded viewer) or kpresenter (allow interactive plots in a presentation) ix ) Eye Candy: possibly completely useless frills.... except maybe for kpresenter/ppt use or for less serious publications. * Import background from a PNG/jpeg, etc * raised/shadowed/embossed lines and labels * raised/shadowed/embossed bar graph bars, pie charts, etcgraph * rounded corners on plots * Raised/shadowed plots * Use alpha channel to allow semi-transparent plots * Make all of the above themable 3. Library and Class changes In order to do all of these things, it will be important to keep careful control over the code structure of kst. However, all changes we make to the class structure has to be specifically motivated by a tangable goal. As I see it, the following items will require some noticeable/significant re-architecturing. All re-architecturing needs to be done in an incremental way (3 day steps max), rather than via a re-write, to avoid long code development stagnations! 3.1. Data viewing i ) a Waterfall Plot DataObject class and UI needs to be created. It should use the same structure as psds and histograms do. ii ) Plugins need to export matrixes to allow experiment specific image stuff. 3.2. Plot upgrades: i ) Floating labels (outside of plots) require ViewObject label. Axis and tick labels work better under current model. We don't want to support 2 rendering engines. So - the label rendering engine needs to be pulled out of Kst[View]Label and shared by both classes. Current floating label model needs to be replaced. ii ) Floating legends require legends to become ViewObjects iii ) New Legend classs needs to use new lable rendering class to allow equations and R to L without code duplication iv ) Optionally floating ViewObjects requires the ViewObjects to be attached to a 'parent' or be free (ie, attached to the top level view). v ) ViewObject classes for lines, etc must be created. vi ) Refactoring of renderer may be useful to ease addition of extended point properties and axis properties. 3.3. Data Analysis i ) Class to represent subroutines (generalized filter sets). Should inherit from a 'kstplugin'.... ii ) subvectors: For working on visible part of plots * Must be efficient (produced by plots during drawing?) * should appear as a kstvector. 3.4. Other stuff i ) making KstPlotLib will require changes beyond the scope of human comprehension. ii ) Making kst a Kpart will be hard also. kst-2.0.3/devel-docs/deprecated/updatecycleexplanation000644 001750 001750 00000022030 11544160206 023502 0ustar00synthsynth000000 000000 Overview of Update Cycle Process Overview The basic idea behind the update cycle is that the DataSource detects an update and then emits a signal telling all objects that are dependent on it to update and the loop continues until all updates are complete. Creation of connections The connections are all created by the dependent objects connecting to the source's signal. Each object is responsible for knowing what objects it depends on and creating and disconnecting the links as necessary when changes are made to the object. Processing of updates Processing of updates is triggered by the UpdateManager each time the Timer for the minimum update cycle has triggered. If a change was detected the update cycle for the datasources that requested updates begins, otherwise it waits for another minimum update cycle. Detecting change Detecting the change to the datasource is the responsibility of the plugin. There are two common ways to check. Timer Timer based detecting means that the plugin checks if the datasource has each each time the timer is triggered. File Based File or Data based detecting does not use a timer but is still constrained by the update cycle timer. This uses QFileSystemWatcher to monitor the files on disk and when the file changes the update request is triggered. Requesing Update The update manager controls all updates, as such, if any object wants to update it must ask the UpdateManager. When the DataSource detects a change it tells the UpdateManager who, when the timer triggers, begins the update cycle by telling the DataSource it can notify it's dependents. Each Dependent then requests from the UpdateManager to update, and waits for permission to begin, this continues down the line until all objects are updated. The UpdateManager also requires each object indicate when it's update has started and finished and uses this information to ensure that each type of update is completed before continuing to the next. All DataVectors must be updated before any DataObjects and it continues for Relations and Plots until everything is updated in such a way as to prevent any data inconsistencies or reprocessing of data. Processing an Update Each object processes the update using it's update function and is entirely dependent on the object type. In doing an update it must follow the following steps. 0. Get an update Signal from parent object. 1. Request Update from the UpdateManager 2. Wait for permission to begin. 3. Notify the UpdateManager it is starting. 4. Update the object. 5. emit the Update cycle for dependents to pick up. 6. Notify the UpdateManager it is finished. Debugging Debugging output is configured in updatemanager.h and provides two levels of debugging. 1 UpdateManager based. This outputs all data from the UpdateManager. Lines denoted with UM - 2 Full Debugging. This also includes output from all Updatable objects as they are updating. Lines denoted with UP - Sample Output from full debugging. UM - Allow updates triggered UM - Beginning update for "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" # Beginning Update Cycle based on DataSource change. UM - Update beginning for "DS-dm.cur" for update "DS-dm.cur" update count 1 UP - Data Source update required by Vector "V1" for update of "DS-dm.cur" # DataSource has 3 Vectors configured for it. Once update begins each Vector must be updated. # As each Vector begins updating the update count is incremented and when it finished is # decremented. UM - Update beginning for "V1" for update "DS-dm.cur" update count 2 UP - Vector "V1" has been updated as part of update of "DS-dm.cur" informing dependents UP - Curve update ready for "DS-dm.cur" # This vector has two curves associated with it. After it updates, both request updates. UM - Curve "C1" requested update requested for "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" Current dependent update list QMap((DirFileSource(0x80ff448) , (Kst::Curve(0xb420a298) ) ) ) UP - Curve update ready for "DS-dm.cur" UM - Curve "C2" requested update requested for "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" Current dependent update list QMap((DirFileSource(0x80ff448) , (Kst::Curve(0xb420a298) , Kst::Curve(0xb420a998) ) ) ) UM - Update finish notification from "V1" for update "DS-dm.cur" update count 1 # Vector update is finished update count is reduced. UP - Data Source update required by Vector "V2" for update of "DS-dm.cur" UM - Update beginning for "V2" for update "DS-dm.cur" update count 2 UP - Vector "V2" has been updated as part of update of "DS-dm.cur" informing dependents # Second Vector updating UP - Curve update ready for "DS-dm.cur" # One curve associated. Overlaps V1, no effective change. UM - Curve "C1" requested update requested for "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" Current dependent update list QMap((DirFileSource(0x80ff448) , (Kst::Curve(0xb420a298) , Kst::Curve(0xb420a998) ) ) ) UM - Update finish notification from "V2" for update "DS-dm.cur" update count 1 UP - Data Source update required by Vector "V3" for update of "DS-dm.cur" UM - Update beginning for "V3" for update "DS-dm.cur" update count 2 UP - Vector "V3" has been updated as part of update of "DS-dm.cur" informing dependents # Third Vector Updating UP - Curve update ready for "DS-dm.cur" # One curve associated. Overlaps V1, no effective change. UM - Curve "C2" requested update requested for "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" Current dependent update list QMap((DirFileSource(0x80ff448) , (Kst::Curve(0xb420a298) , Kst::Curve(0xb420a998) ) ) ) UM - Update finish notification from "V3" for update "DS-dm.cur" update count 1 UM - Update finish notification from "DS-dm.cur" for update "DS-dm.cur" update count 0 # All Vectors have now been updated. The Primitives have all been updated and update count is 0. Moving on to relations. UM - All primitive updates complete updating relations for update of "DS-dm.cur" Current dependentUpdate requests QMap((DirFileSource(0x80ff448) , (Kst::Curve(0xb420a298) , Kst::Curve(0xb420a998) ) ) ) # Relation Map has been built during Primitive Updates. Update Manager triggers each. UP - Relation "C1" is processing update of "DS-dm.cur" UM - Update beginning for "C1" for update "DS-dm.cur" update count 1 UP - Relation "C1" has been updated as part of update of "DS-dm.cur" informing dependents # Updating Curve 1, Plots containing Curve request updates. Update count is tracked. UP - Curve update required by Plot for update of "DS-dm.cur" UM - Plot update requested for "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" Current display update list QMap((DirFileSource(0x80ff448) , (0x80d535c) ) ) UM - Update finish notification from "C1" for update "DS-dm.cur" update count 0 UP - Relation "C2" is processing update of "DS-dm.cur" # Finished Updating Curve, Update count reduced. UM - Update beginning for "C2" for update "DS-dm.cur" update count 1 UP - Relation "C2" has been updated as part of update of "DS-dm.cur" informing dependents # Repeating for Curve 2 UP - Curve update required by Plot for update of "DS-dm.cur" UM - Plot update requested for "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" Current display update list QMap((DirFileSource(0x80ff448) , (0x80d535c, 0x81e0d64) ) ) UM - Update finish notification from "C2" for update "DS-dm.cur" update count 0 UM - All relation updates complete, updating plots for update of "DS-dm.cur" # All relations updated, use Map of Plots to trigger update. No display object is updated until all objects are updated. Current display update list QMap((DirFileSource(0x80ff448) , (0x80d535c, 0x81e0d64) ) ) UP - Updating Plot UP - Updating Plot Projection Rect - X and Y Maximum # Plot is updated and if necessary zoom is changed. UP - Updating Plot UP - Updating Plot Projection Rect - X and Y Maximum UM - All Plot updates completed for update of "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" # Finish of all Plot Updates. UM - Update Complete for "/home/kst2/kst/tests/dirfile_maker/dm.cur (DS-dm.cur)" # Finish of Update Cycle UM - Delaying for 2000 ms before allowing next update # Delay until next update.kst-2.0.3/devel-docs/deprecated/RELEASE000644 001750 001750 00000002704 11544160206 020023 0ustar00synthsynth000000 000000 How to make a Kst release: - update from SVN - svn copy to a branch - edit RELEASE.NOTES - run a regression test and make sure it completely passes - update configure.in.in to set the version number and the libkst interface version - update ../doc - make sure documentation has correct version for the tag of index.docbook and correct version of KST, QT, and KDE in the installation instructions of install-chapter.docbook - update the manpage - prepare for a KDE 3.3 install! Set min config appropriately - svn copy to a tag - make sure configure has been run so that the spec file is created (with the appropriate prefix, otherwise it must be editted after) - disable unsermake - svn2dist /path/to/extragear/graphics kst -b -n kst -v --svn-root https://svn.kde.org/home/kde/trunk/ -l svn2dist.log --i18n-module extragear-graphics - unpack, remove any files that shouldn't be there, make sure docs and i18n are packaged properly, and edit any paths necessary (ex: spec file) - generate the srpm: rpm -ts kst-version.tar.gz - generate rpms as needed: rpm -tb kst-version.tar.gz or rpm --rebuild kst-version.rpm - SuSE and RedHat style are typically generated. - TEST - update www/areas/extragear/inc/appinfo.inc - update www/areas/extragear/apps/kst/ - upload packages and lsm to upload.kde.org - mail ftpadmin@kde.org to notify them - update kde-apps.org - add version number to bugs.kde.org product kst-2.0.3/devel-docs/deprecated/RELEASE_PLAN000644 001750 001750 00000006403 11544160206 020635 0ustar00synthsynth000000 000000 Kst 1.4 is the next major release of Kst. There is no set date and the scope is not yet defined. Our current feature list and feature plan is as follows: Pending major changes: - merge and activate multi-threaded updates New work: - kst2dplot needs to be redesigned and refactored Some reasons: - tick interval calculations wrong - merging axes on plots just erases borders - printing needs to be redesigned: - Resize/Revert concept is not workable, and is the cause of the legend printing issues - It's slow - It's confusing to write view objects because of this - view objects need to be simplified - Too many mis-functions and mis-features crept into the base class - Sizing and positioning are confusing - Top level view is over-complicated and also suffers feature-creep - port loading to SAX depending on results of benchmarking - Test with 500kb+ xml files and see how it compares to - spreadsheet mode - This is almost certainly dependent on a KDE4 port - add UI support for specifying X and Y separately as functions for a curve - ie: parametric - ongoing scripting fixes and scripting work - expose String datatype somehow - needs thought/research and a design plan - scalar work - top-level dialog for scalars, similar to the vector and matrix ones - making scalars easy to edit - adding scalars without providers to the data manager - note the UI concerns that might come up - data source work - design and then implement metadata enhancements - add support for parallel (interlaced?) reads - add getinfo() type of function for fields - implement low-resolution preloading - add data sink support - ability to write out vectors in any format - implement KstIndex across Kst and support time as a primary indexing mechanism - implement a default TIMEINDEX field - port to KDE4 once KDE4 beta 1 is released - use fast malloc for data areas where malloc calls are repeated and costly - calltree profiles show this - add a generic system for supporting units, especially as provided by datasources - make fits and filters usable from equations by having them export a hint that can be used to add an entry to the operator list - needs a carefully thought-out plan - allow fit outputs to use arbitrary X vectors for higher (or lower?) resolution - data subsets - write up a plan for this - create a UI for doing this - allow subsets to reflect flagged data (or unflagged data) - allow selected ranges to be fit to as a subset, etc - static mode - a new save mode that saves vector data to the kst file as CDATA - UI to convert from static back to data source mode - brings up interesting issue: no way to cleanly convert data types of KstObjects - map manipulation work - undo/redo in layout mode - must be done -properly- using serialization - also the solution should apply to drag and drop and copy/paste - Barth's combobox idea :-) - Label syntax validator to make label writing easier - Ongoing doc updates - Fit and filter plugins share a number of common algorithms that are specific to the C plugin API. Build parallel API for regular C++ plugins?? - Get rid of fit/filter specific code in KstCPlugins Other possible ideas to consider but not approved: - Object templates and complex object construction - KstScript session generator kst-2.0.3/devel-docs/deprecated/kst-meeting-04-2006.kwd000644 001750 001750 00000037446 11544160206 022577 0ustar00synthsynth000000 000000 PK4(/`mimetypeapplication/x-kwordPK4', maindoc.xml]mS8Bˇݞ-䍆%PC3-V-dB/[s$;t |8%[~霣_Wq.6R%V&@2}Z>XZ׏O[ g_w>*j:^a+}kׇaBu2{x;u N6\ƱM|e+,H]_e?Qb/QBi>PieZԶp@){UbIoWk *s7Q~ͯ 7*[x~{4ݘ|p1*J xt8=co֭eͻ'uluvδfesڊDw⨣U14]4ЖUuu~iw[Md?Iuw~û&:6>HQ0 ŕ;hc3ás_x;⁕@Xŕe!͞r{`Z [sJ3+EGS- w->ZV66o%6Ʌ{8Pq }hޯoрhCۉ 7/5\NN'{Xĥ<lP zG1iF6v` ~{faU"򛿿#Kid'clg#w]f܆7~WTkAU7okp9sڬoWjnVoT6;jTjs\6*kjRկ{>9|s;dۭڸR|Y0Ѐ})0?ىG;>x~9f|_s$}Otred7P&{xگ?.-` ջ A`\hٝ2=a@v^1GMy y[pyxm'( pfȟ ׂ7O=m2H'aN۲I05 |ฟ06F2Y7MgL%#0 anɁ`.,1b-ii8łngqqD4"- ֥Gn9 tja_}TZމwxprt׹s ܑ$L0 1ߞ;׋T6W6n\l&~MVB+Jh%Z 7@&nV-ij' N_@U n*AA5ó#HBXWȀRd(X_ 2}}xF%0Ƽ@݄MFA^2tt "}Xj e&'⎅@.3xpBZ"++F&WRR( ~_r)`]"\C+Vbi'~ܙŝӓv*~s;u*N`K.آ!{s* R11:fJwYs/L^9nW 90 >,Vݤޟoܤʅzin05_ca^B<<@YqF;ą qbx<'jh.{.pOX$){\[[DvQi1!d)9C& "+SsC0ŝHn]ݰH^])6A x `b`ks^Z fpi\ǎnE,52D=!IXP`L~U2H>'`=wۗ#q4 ƋW '٬R/>!͊E4R3~X@ N4|7&cqW]屙5'^ʬ9/ڒGV.J̤IЏ(LćZ`(}  e :oVq]UeRS " C E3(,,4,n_&T`G*-T-$fi/5ܓpV$AUjM-6h+N'BE\c`ww߄Ěl `}]nR:!;S5t L{nkth32V °'YӀNw{lY ^M䗷,lpVtbv]%ɢK)N/A]h;IV٥WWY̭$?.)zǗoI#0F$V(!{'. OD NZs1HVX+{l(Þe\jd%=^K*!seJO^u]+,З]3$!v&| D⁊ `>kW"j"Ƅ!Ҹ`ϣ<*6aEnqkyE۫巂vk_/\ 406.0"1wɆ}NM}N^`7oAxe9Mׄyu:.Q$}4}~ZRE/R#Kar`Ń@Ђq-ְ5YHux "0ӕQ  'Luħ z42Ȯ!IDSK/#(pTN.4pAi1gn0h w|ͷ6-nWD f˺Uh0/StM` ͗L]Nᚤk2eAp"~q@$0ͮQ8RBt %[ h#-J( ȧz[]$ݡ/(Pl2?lF Bd݅X\9#eI QSF VVY"wD|eć<ԕ72z#)uCI |+DXiBGsl^&4 D~rf h{kH`R0*H] @$n #p&t#pNf|C0o0nX c`cՂw-$u$}<,Ɣ>}H(:wAw?wH-Bw(99-pz;ĥbəw}yך̗}ʼ=LsOkzWa3ڻ'gP~^"|铮=io מ<[36ȅxA?0'r r r&k>z= nngWOQ Ov$,QϯOQ*h fG+>! 퓇!"&d@9/Jwq#|m-iyIX~g/41H?Œ#P#Fzٷ;G㇭W;[Otk~\b ݞ{mk{}}HpΫ[^o0}݃(xϻ`6EwB<>yfý׳9ї}\?/PK4O;idocumentinfo.xmlQ=o0&{U BeB &qcGΥ9+U.wޝlt,FASIK'bF26JXM_$)}Kf&W P:$('JC7y.Ssڑ(2lQu=(EDX(j^x-d.ͥP+Z*f @ߎIMYq}B+J.UoUqeZG k4(X(QFWɄciOGLӏh~$[ c]Hhrq V@  C/.i|-ߢ_OrlPw^^MrlDsFmWߋu<PK4U!! preview.pngZUXT ] nCΕNaXBIAZBJw̙s܇}41(09 АTd<@@(Cd@ ! !  !z!@@(CB(PG`P F@ñnb"@@ 0ZxA  ,E!P  P BapQ A0(CPFhӂ! 6XaB"@0>Zx P g/B! (I{A0`3fv $,aph8  @`#k Y!lF\E CEC@B!nB#a!A=/7Aa0ؿްU`|s;?w`)&?,ؿnؿ}|bjjK[WCCCLLX@@HoGeuamm ;`p76.p7//mmk+33⺦z8`wޠ|(I坈 X4 qp;N}g4G3N4]$ L]mMAEZRVwNXKIo, r# g! ɱ`11997g˒ʎ y?g-ՏQ3lKhw3[볚*nuWg>Gn=ݛ2 i޽CC˾CL6PY=KۅFN~6}0կ=<.'#(WSF4bVk{+wlooҷH^I$j} /dy~N"+ԏM[N8/PFjP Y)~(Zkv+_X6@Bl!>Uw&~`_0-&!w,v>I7r*  vmݷ+zȿʵަ\9$,]1pnΣ.0UU SvKmZ3.0!V?mbX2CT0̹O Q;rcBPe)rfH"%h&%y5/\KK&[$bA EiD{Y7*ȴ|0[N`f8ڊ^SQ9hT޵%f]{j\=]&}7noz.ڗW#Y  |vpkt< #ow{ &4u^9d!hz 4&K}_L Q=T|M_&W5hz >|[>¥N{mCwmWcʳA;)-u $&'pv=;q b1qUָ!P_,k|E'^W_oEo{WPmE08TL yu]ߌA}B_y/jzR.L|҈2wG$8ҎTXE bEqtU7#>gԟiP),u}4 7,\UEM.&}'IF0Y'h*!ٙ1Z)Lߘw"a 'd˿Y!VU.2c&.<7-JˡB6<[ml?"6EOV54%ivO2(Tέ20DgĆO\dw$j)8 GtE=_ WOD6= D~4J:ꭶV }qe8.oPl/L=O5[UKpv"єx{e)7)tֻ=h86D\^=&${6 `ju\Cy^ ezOAdb};F0U ]^|2uۿ9t)AS5_WgjHq@[%M3naZ_ u&e/\FU-t+svFil!>Ș#wIZԩ|S3 I}˸Sy;m5Ynj%>S @ɞF^zC Fg&:1COk+Ƿ/prTbO:|a_K1Y=ImQynPhNd 0J tZ1hkEY<=p#q#1\Mt'= ,a͋I1NlNIEkғ|E\W̟ yze#V6ooqb?jWyy!+2w]Ը>;D WKR?\V'S]'5T m;4=Ow- w9-qd ç /#_4{NdEka۶j'U *[͔A1V9$Sjd,XFy}GkũrVW-ON^IUK m2 ZQqtj)QQws0C`(-D4sⳌd)Z~, ލOouzΨ"RǑ jgS 9ڄ'UL^EeL:6L&$IJaB Oۅx|6"INZ/~Z3'/wmw7y[iUO|;gepڣ5Iw%Ϋ`g=*1KzvƹFgsl~ E*tu[Q$y}7Ő=MZ\)c jowp:;@a g4Ll$e .j&(*/jfEO jXz%?(:a+nZOc(FOIK%"Ѻc,^F'^˛*r =,|R$*B |7P=R3=9Ҿ銓$(xd(2z#J'&҉P l6hH/441s߶Uů.jRy Qz&xr _L_+hcPbmAYHcmEa)#Y:aFe viWԺkaLrɱưi,iTk\(@60ǭAͥG|+E&G'/'m%}׻ PS_mD_4{&ސklU/XOߪ;Gϗ7U})Ij|S(`?"8i#;M<] uD?pra?\]kkjeXFZgpvKTo1%JE/8UuY3,7ف#\]2ވD}ϛWa#$zՐ<vJ\>{b_\cN*@ SȾAUV[#Sϴk/ 71ZOrDPzU;q"DAҾL*^k]N rZPT%OANqkkCOwcY_Y^Z1P@et8O`vwZNPfH1zuIe?hGBA巢鰸Bhęb+6*~#G[*B綗JZX\]8zNirfh9R .S]jYma:3O5xnyt!ZX{gbS&3bGʃ\qI9>[{$LS)-Ja;G4owZ3(:o/ރ]nZW<̄y-_-Cp8;E* }^ubiY]rn 4?A o(["G!^x Gy~jC5hzSoX=Ǐ,&HX8iYѧvCd'FUI$ԫ!Q?OD:zAlh %RvxPOϸJ}s{nlc }5+ ]xG|RRY*ڟ)ѩk% 4)RB#%jJ\_cV~ HJ4QYL lU_/:''`LXͯͅs}r$i10K|/)F Ǹz3I!j`)QuඅbnvJV/>n04N*z !ޭk{cA1P14ie7TPVvR( hpZCky]\ ayS~<_2rCW\yEND`(#jȤ`JR!k/拳NjLgk̺S8ߤ㍍f;>`;-+W1PcktSr4h5K{lUF,33(^HZ˙^0~$O 8 k'֟+ZHNT%BaLPWI ] jez҇К5Q=[P؈5>5 Z#UK(i?x<վ ʌ(W$ЬiatyFFEh&ŕ @Y6 y|w]5 b0^|~[6U֕MMn)iitΣTvHO?crZ=񖧭O{OJXawm^3Z ^=j(4r:q6#Keġ&7Ź~&Vog^ )2Ty`NPDG1~S,'Zhg'BHU2.~J jzmgy66 ATLdBCY=nVZEInsrMٜb6'Ȓ哭l(WdQ#(h~c2FY kTRO\n3FbX7ƒ-g0-_}o_Ip,6 rmFPA {TջySEcdH8/PvRUU)C۪`I<Ҕ9d{̅{=֊_ٛb!EQ TqMveͥ|$%=~ ԣ|2.C bp|&AS91v/Qưn#zkM(3cƮq?b'H9} $ Ot?C^u@.hc$Ӈ`Y%tj.l!&! A/m!ϔ 5]1Y8U: bP6\4EObԸ-}dl1kɽQ-v'!7ZW)5$0I]upk*q&m 6~!9{`}҆$idLҤsf)^*Ǎ瞩M'#atOTu4NRٮ[ZWSP-6IQiȍ߂>R}|)%U,1*׬YcRŻ QT I-(.iTR=<\_Zgll8m:J( `Nl)0%GO0y/1pLbҖ;G6!V pnXr,q S?S&Z5[riCw8cL|Y&ӵubA2C)` Yj%>Hӧ#F|ZL!X _c, ,uw## L7=A:2pàKk#46;:5`$1 ,#[P>ژ"$G`u`OW$_s>-x|TZ3velP^ѾoH2c`mRI[O(: *&Uqz^$]v>@ ȰmP;9Wy(J3R/)Hؔ7 o ,r9<4ߴ,dثn֠UYh(h1\/w뤨1klpK?||(e4SчrްRvﺊB ,]!w4-akBfO>345d"PK4(/` mimetypeUTYMDPK4', 9maindoc.xmlUTYMDPK4O;i documentinfo.xmlUTYMDPK4U!! preview.pngUTYMDPK >kst-2.0.3/devel-docs/deprecated/kst2drenderer_proposal.txt000644 001750 001750 00000030510 11544160206 024252 0ustar00synthsynth000000 000000 Here is a more detailed proposal to accomodate painting data in non-cartesian coordinate systems. Also includes some refactoring of Kst2DPlot. Basically I have tried to go through all the existing code and determine what kind of class interface is needed and then have tried to create that class. Background ----------- A) Current configuration. The painting code is currently set up like this: KstApp : KMdiMainFrm \ ---> KstViewWindow : KMdiChildFrm \ ---> KstTopLevelView (friend) KstViewWidget o The top level view has an instance of a QPainter which is set to draw on the KstViewWidget. o The top level view has a list of KstViewObjects which it calls on to paint on the QPainter. B) One such descendent of KstViewObject is Kst2DPlot : KstPlotBase : KstMetaPlot : KstBorderedViewObject : KstViewObject C) Kst2DPlot draws the axes, legends, tick marks, etc and then calls on all KstBaseCurves to paint themselves. The base curves are provided with the QPainter reference to paint to. Definitions ------------ 1. For this discussion, 2D "rendering" is the act of taking data lying in a general 2D coordinate space (U,V) and drawing it (using QPainter primitives) in a section of the cartesian (window space) plane. 2. For this discussion, 3D "rendering" is the act of taking data lying in a general 3D coordinate space (U,V,W) and drawing it (using, e.g. OpenGL) in a section of cartesian space. So when I say "render", what I really mean is a combination of a coordinate transformation/projection to cartesian space and then painting this cartesian data to a window. Proposal ---------- I propose the creation of a new Kst2DRenderer (3D will come later, once we have Kst3DPlot working). This new object will wrap a QPainter and provide an interface for drawing in terms of native U/V coordinates. The goals are the following: a) Remove all notion of "X and Y" coordinates-- unless we decide to keep calling it "X" and "Y" when we mean U/V, in order to minimize code changes. All work is done in native (U,V) coordinates and the window coordinates of a QPainter. The currently selected Kst2DRenderer determines how things in (U,V) space are drawn to the QPainter. b) All QPainter commands in 2DPlot and the basecurves that involve (U,V) space coordinates are converted into calls to a Kst2DRenderer. This does not affect things like drawing the legend or other calls to the QPainter that are in terms of pixels. This new Kst2DRenderer will have the following members/methods: 0. Normal QDom handling and save/load/etc functionality 1. Coordinate Range. The current Min/Max values of the (U,V) coordinate space. There is no a priori restriction on these values, since in some cases Min > Max, e.g. a plot of spherical data centered on the prime meridian where phi=(3Pi/2...Pi/2). 2. Range checking methods. Each descendent of Kst2DRenderer should check that the current range makes sense for the specific type of rendering. Also include methods to check individual U/V values for validity. If values are out of range, return sensible default for this type of rendering. Also provide test functions to determine if a value lies within the current range. 3. Simple functions for doing coordinate transformations for a single ordered pair (U,V) <--> (Xwindow,Ywindow), given the currently specified range of the (U,V) space and the current window coordinates of the QPainter. 4. Graphics primitives, given in terms of (U,V) coordinates, including: drawPoint drawLine drawRect drawEllipse drawPixmap drawPolyLine Others? 5. config dialog, with options specific to the type of rendering being done. See attached files for a rough definition of this class. In order to support polylines in (U,V) coordinates, I have also created a simple QValueVector of pairs of doubles-- does such a class already exist? If so, we could just use that instead of the DPointArray I came up with. Typical Useage --------------- Here is a typical example of useage from within Kst2DPlot: 1. In Kst2DPlot, the Kst2DRenderer is allocated in the constructor and set to the default type (cartesian). 2. A combobox in the plotdialog is used to select the desired type of Renderer. Kst2DPlot has a method (called by the dialog) to switch to a new type of Renderer (allocate the new and delete the old). 3. In the paint/draw functions, the Kst2DRenderer._painter is set to the current painter. The U/V range is set based on the min/max values stored in 2DPlot. The painter window and viewport are set up as they are now. The Kst2DRenderer._pSpace is set to the desired sub-rectangle (in window coordinates) of the QPainter All U/V drawing functions perform the necessary projection/painting based on the U/V range and the current subsection of the QPainter.window. Implementation (including some unrelated refactoring of Kst2DPlot) ---------------------------------------------------- Implementation requires some refactoring of Kst2DPlot and modifications to the basecurves. However, I think things will be simpler in the long run ;-) Here is (I think) a mostly complete list of the changes needed to implement this: 0. Do we want to actually rename X and Y in the code to U/V or something else? If not, then "X" and "Y" become our generalized coordinates- they are no longer assumed to be cartesian. 1. Add a member to Kst2DPlot that is an instance of a Kst2DRenderer. 2. Create descendents of Kst2DRenderer for the existing types of plots (cartesian and Log). 3. Create config dialogs for the cartesian and Log renderers which contain the options currently found in the Plotdialog->{X,Y} Axis->Scale block (i.e. time display, reversal, etc). 4. In Plotdialog.ui, combine the X Axis and Y Axis tabs into a single "Axes" tab. This is similar to how the "Range" tab is set up. Remove the "Scale" sub blocks from these. Using the resulting extra space in the "Axes" tab, add a combobox to choose between the available Kst2DRenderers. Beneath this combo box, have a "configure" button, that can pop up a detailed config dialog depending on the selected type of Rendering. Cartesian and Log renderers would have options like displaying interpreted axis labels. Spherical/Sinusoidal renderer might have options like display in RA/DEC, lat/long, or radians. 5. In Kst2DPlot, we no longer need the (many) xlog and ylog boolean flags. As far as 2DPlot is concerned, it always draws in U,V coordinates. Remove members _xLog and _yLog. Remove bools from common constructor. 6. In Kst2DPlot, commonConstructor: call range checking functions in the Renderer instead. 7. In Kst2DPlot, Move CheckRange and CheckLRange to their respective Renderers. 8. In Kst2DPlot, have setScale, setXScale and setYscale call the range functions in the Renderer. Remove setLScale, setLXScale and setLYScale. 9. In Kst2DPlot, updateScale: remove all reference to boolean _xLog and _yLog. Simply query basecurves for min/max values. The autoborder option will create a border in U,V coordinates. Use Renderer's checkRange functions. 10. In Kst2DPlot, time functions: Can't we move all this time stuff to a "KstTime" class? We could remove ~330 lines here alone. I can do this at some point, but it's low priority now... 11. In Kst2DPlot, time functions and genAxisTick*Label : Remove log mode stuff- "z" will always be either just a number in U/V coordinates or interpretted. 12. TICK MARKS: there is a ton of crazy stuff going on in 2DPlot for computing where to draw ticks. There may need to be some changes. The basic method should be: determine desired U/V tick spacing, check that ticks are not too close or far apart in pixel space, if so then autotick, draw ticks at locations determined by calling the renderer's UVtoPix function. 13. In Kst2DPlot::draw, KstCurveRenderContext should contain a reference to the Kst2DRenderer, rather than the raw QPainter. Basecurves should never be drawing directly in pixel coordinates (except for specifying certain pixel-sized features in the renderer's primitives). 14. In Kst2DPlot, setTicks: Again, we need to figure out a reworking of the tick handling that calls the render object to find out how far apart the ticks will be in pixel space. 15. In Kst2DPlot, setCursorPos: getNearestDataPoint finds the closest point in U/V space. Set _cursor_x and _cursor_y by calling render object to convert mouse.tracker coordinates to data coordinates. 16. In Kst2DPlot, updateMousePos: use render object to find xpos and ypos 17. In Kst2DPlot, getNearestDataPoint: Use render object to compute the current mouse location in U,V coordinates. 18. In Kst2DPlot, highlightNearestDataPoint: Use render object primitive to draw highlighted point. 19. In Kst2DPlot, mouseReleaseEvent: Call the render object's coordinate transforms to figure out the new U/V range values based on the mouse's QRect. 20. In Kst2DPlot, remove menuXLogSlot and menuYLogSlot. 21. In Kst2DPlot, moveToNextMarker/moveToPrevMarker: mostly OK, need to remove log stuff. currCenter and newCenter are in terms of U/V coordinates. 22. In Kst2DPlot, zoomSelfYLocalMax: Curves return their min/max as currently coded. Call render object for range checking and to get sensible values. 23. In Kst2DPlot, xZoomNormal/yZoomNormal: Use renderobject's functions to compute new min/max. 24. In Kst2DPlot, plotMarkers: call render object to determine if marker value is within the current range. 25. In Kst2DPlot, plotPlotMarkers: call render object's drawLine primitive instead. 26. In Kst2DPlot, plotAxes: More tick issues. Assuming we have already determined the correct major/minor spacing in (U,V) coordinates (i.e. in setTicks), all we need to do here is for each tick, find the pixel location by calling the renderobject's conversion, then draw the tick at this location in pixel space using the QPainter.drawLine primitive. Lots of code saving from removing all the Log-based stuff. 27. In Kst2DPlot, plotGridLines: simply call the renderobject's drawLine function instead of the QPainter one. 28. In Kst2DPlot, mouseDoubleClickEvent: Use renderobject to find mouse location in U/V coordinates. 29. In Kst2DPlot, draw: The KstCurveRenderContext contains too much info. We don't need the x_min, y_min, etc that are used for log plots. We also don't need the L/H/m/b variables, since basecurves should not need to know about the conversion from U,V to pixels. All they need is the min/max U/V range and a pointer to the Kst2DRenderer. 29. In KstBaseCurve: Change KstCurveRenderContext to contain a pointer to a Kst2DRenderer. Remove useless members. 30. In KstVCurve: When painting, call renderobject's primitives. Use DPointArray (see attached files) of U/V values for polyline function. This should clean out a ton of code in this function, since we don't need to do any pixelspace stuff. For some drawing, we may want objects that have a fixed size in pixels (error bar ends, plot symbols, etc). We can then use the "fixed" drawing primitives in Kst2DRenderer. 31. In KstImage, paint function: For colormap, rather than building up a QImage and painting it, we should draw each matrix element as a filled rectangle in (U,V) space using Kst2DRenderer->fillRect. This allows the renderer to morph each rectangle into some other shape based on the type of rendering. Remove all the pixel crap. Simply iterate through all matrix elements and call fillRect based on the U/V range. 32. In KstImage, paint function: For contours, we have a problem. The contour step is currently specified in pixels. I don't know what to do here- any suggestions? Aside from this, I think we just need to call Kst2DRenderer->drawLine instead of using the QPainter. 33. Add Kst2DRenderers for other types of display (polar coordinates, spherical/sinusoidal, spherical/polar, etc) Future Benefits -------------------- OpenGL for 3D and 2D: one could imagine having KstViewWidget inherit from QGLWidget instead of QWidget. In this case, all KstViewObjects (including Kst2DPlot) would have a QGLContext rather than a QPainter reference. We could then modify Kst2DRenderer to draw primitives with OpenGL commands, and all basecurve painting would immediately benefit from this enhancement.kst-2.0.3/devel-docs/fits_datasource.txt000644 001750 001750 00000015500 11544160206 020636 0ustar00synthsynth000000 000000 FITS Datasource Design ============================ Revision History ---------------------------- 2006 05 29 : Ted K. More details about FITS helper library 2006 05 04 : Ted K. Added info about WCS 2006 05 03 : Ted K. Initial proposal ---------------------------- This is a proposal for a new general FITS datasource (called fitsfile). There are some auxillary issues that also need to be dealt with in the healpix and LFIIO datasources. Utility library -------------------------------------------------------------------- The cfitsio library has low level functions to access the FITS file. It would be convenient to have a library of higher level functions that could be called from all datasources that deal with FITS files. Examples of possible functions would be: fetch all keys, build combined fieldlist from all extensions, build matrixlist from all extensions, etc. In order to be really useful, this utility library needs to be accessible from the understands_*, fieldList_* and matrixList_* functions. I'm not sure of the best place to put such a library in the buildsystem- maybe kst/src/datasources/libfitsfile/ ? Proposed Functions: 1. fitsNHDU( fitsfile *fp ) Returns the number of HDU's in the FITS file. 2. fitsDim( fitsfile *fp, int HDU ) Returns the dimensions of the the image or table contained in the current HDU. In the case of binary tables with "wide" columns (each column entry is a vector), the column entries will be "unrolled" and the returned number of rows will reflect this new size. 3. fitsKeys( fitsfile *fp, int HDU ) Returns a list of FITS keys. This list will contain any keywords in the file header, and then the keys contained in the specified HDU. 4. fitsNames( fitsfile *fp, int HDU ) Returns a QStringList of the names of all columns in the HDU (if the HDU contains a table), or the label of the image. 5. fitsUnits( fitsfile *fp, int HDU ) Returns a QStringList of the units of all columns in the HDU (if the HDU contains a table), or the units of the image. 6. fitsFields( fitsfile *fp, int HDU ) Returns a fieldlist for the current HDU. Some datasources may wish to construct their own fieldlist using the information returned from fitsNames and fitsUnits. 7. fitsMatrices( fitsfile *fp, int HDU ) Returns a matrixlist for the current HDU. Some datasources may wish to construct their own fieldlist using the information returned from fitsNames and fitsUnits. Overview of the fitsfile datasource -------------------------------------------------------------------- The overall behaviour of the datasource will be to offer up all data in the FITS file as both vectors and matrices. The datasource will scan through the current extension (HDU) in the FITS file and build up a list of available fields. The current HDU will default to the first one, and be selectable from the config dialog. The INDEX field length will be determined based on the size of the current HDU. A. Vector List. The datasource would call a function in libfitsfile to build the fieldlist for the current HDU. For an image extension, it will read the units and add 2 fields to the fieldlist that represent the pixel index (row major) and the flat-packed pixel values from the image. For a table extension, it will read the names and units of the columns and combine them to create a field name to add to the fieldlist. B. Matrix List. The datasource would call a function in libfitsfile to build the matrixlist for the current HDU. For an image extension, it will read the units and add a field to the matrixlist which represents the rectangular image data. For a table extension, it will read the names and units of all columns and combine them to create a field name to add to the matrixlist. So for a table extension, the corresponding matrix field has the same dimensions as the table. C. Dealing with corrupt or "poorly created" files. Unfortunately, not all FITS files "in the wild" are of the same quality. Sometimes files become truncated or the software creating the file has made a mistake. In my experience, a more robust way of handling these issues is to use the very low level functions of cfitsio to read the file. This makes it easier to handle errors with a subset of the data in the file, while keeping any data that is good. The higher level functions tend to just give up if they encounter a problem. D. Configuration. The initial config widget will be very simple, and allow the user to choose which HDU to use in the file. E. Command line. The command line switches -x, -y, and -z will determine how the fitsfile datasource returns data to be plotted. If the -z option is not specified, all further actions pertain to the first HDU. If the -z option is specified alone, the value will be taken as the HDU to plot as an image. If the -x and -y options are specified, then their values correspond to the columns of the fieldlist to use. If no -x is specified, data is plotted versus the INDEX field for the selected HDU. WCS Extensions -------------------------------------------------------------------- The WCS system provides a way of specifying the coordinates of each pixel value in a FITS image. This can be done by specifying mapping parameters, or even by specifying every pixel's coordinates in a binary table extension. This is great, but what can we do with this information? The best we can do at this point is maybe support some limited types of coordinate mappings (rectangular ones). Full support of WCS projections will not be possible with kst until we have a complete 3D display framework. Note that WCS is implemented as an external library. It is small and GPL'd, so it may be easier to just include the files we wish within the fitsfile datasource. This can be discussed more later. Healpix, LFIIO, and Miscellaneous -------------------------------------------------------------------- A. The healpix datasource needs to support the use case of reading the pixel values straight out of the binary table as vectors. I will do this by adding some additional fields to the fieldlist that have the form "(RAW) ", so that the user knows what they are getting. B. The LFIIO datasource needs to support interleaved data in tables. My hope is that it can make use of some of the existing utility functions in libfitsfile. For example, it could call the function to read all keys and then check if there are special keys to indicate that the file is an LFIIO fits file. Then it could call another function to build the fieldlist and simply add/remove a couple fields to deal with the interleaving. So basically LFIIO would support all the functionality of the fitsfile datasource (through the use of libfitsfile), with some "extra" functionality built on top. C. Notes: Need to properly handle null pixel values in images. kst-2.0.3/devel-docs/RELEASE000644 001750 001750 00000004132 11544160206 015720 0ustar00synthsynth000000 000000 How to make a Kst release: Create and Update Branch 1. Update code from SVN (svn update) 2. Create branch for release (svn cp) eg, svn cp https://svn.kde.org/home/kde/branches/work/kst/portto4 https://svn.kde.org/home/kde/branches/work/kst/2.0.0-beta3 3. In the branch, update the RELEASE.NOTES (kst/RELEASE.NOTES) 4. Update the version number in config.h and kst.pri [NOTE: This step should be moved to immediately after the release and be done in the working directory, not the branch] 5. Build Kst in the branch ensuring no errors occur. (kst/build-kst) 6. Run Kst tests ensuring no errors occur. (kst/run-tests) [NOTE: A number of tests will report that the test has always failed. However, none should actually fail] Packaging for Linux Note: Linux package is distributed as a source tarball. 1. Export the source from the created branch to a clean directory (svn export) 2. Remove all old_ and admin directories from the exported source tree. 3. Create a tarball of the source tree (tar -cf kst-2.0.0.tar sourcetree/kst) / (gzip -9 kst-2.0.0.tar) Packaging for Windows Note: Windows package is distributed as a binary zip file. 1. Get the latest source from the branch. 2. Build Kst in Release Mode 3. Create kst/bin and kst/plugin directories to package from. 4. Copy built kst.exe and current mingwm10.dll QtCore4.dll QtGui4.dll QtOpenGL4.dll QtSvg4.dll QtXml4.dll into kst/bin 5. Copy DataSource and DataObject Plugins to kst/plugin 6. Verify that Kst current currently from the packaged directory. 7. Create a zip file of kst directory. Test, Distribute and Announce the Release 1. Open the tarball and build the source / run tests. 2. Upload tarball to uploads.kst.org and e-mail ftpadmin@kst.org to notify them of the new file. 3. Update website information to indicate the new release. [SVN location - svn.kde.org/home/kde/trunk/www/areas/extragear/apps/kst] 4. Update the windows binary zip file available on the website with the build package. 5. Login to kde-apps.org and update the version and upload the file. 6. E-mail the kst List notifying everyone of the release. kst-2.0.3/devel-docs/DEVNOTES000644 001750 001750 00000002742 11544160206 016074 0ustar00synthsynth000000 000000 General development notes for future reference: For Additional notes regarding the BuildSystem see Kst2Specs/BuildSystemOverview For Additional notes regarding the update system see Kst2Specs/updatecycleexplanation How to update the Windows Icon If kst.png changes the windows icon should also be updated. Open kst.png in gimp and save it as kst.ico, from the dropdown for format select "32 bpp, 8-bit alpha, no palette" and ensure that compressed is not checked. Additional notes: .ico files can contain both a 32x32 and 16x16 icon. The current version is scaling down the 32x32 on the fly which decreases the quality of the icon. Future icons should be created in both 16x16 and 32x32 to optimize the appearance of the icon. Locks All Objects in Kst support writeLock and unlock commands to prevent access when updates are occuring. No lock is required during read. DataSources DataSources (specifically the files) must be locked and unlocked when the primitive (Vector, Matrix, Scalar or String) is being updated. DataObjects, Primitives and Relations All DataObjects, Primitives and Relations require locks for the following actions, updating the data either from creation of the object, or from an update cycle. Editing of the object making a change. In DataObject there are helper functions writeLockInputsAndOutputs() and unlockInputsAndOutputs() which server the purpose of locking dependent objects within the DataObject's update cycle. kst-2.0.3/devel-docs/Kst2Specs/Bugs000644 001750 001750 00000001306 11544160206 017361 0ustar00synthsynth000000 000000 Draw an ellipse that spans many plots. It ends up in the back, and can't be brought to the front. -------------------- Artifacts when resizing large arrowheads. -------------------- Curves are rendered slightly above where they should be. Take a plot that it is of very boring data (like always exactly zero) and it'll be drawn one pixel above the axis tick mark for zero. (This is not always the same - sometimes above, sometimes below, sometimes right.) So: it appears that ticks and curves use different rounding Probably related bug: points don't always appear centered on the line. -------------------- Select box tool. Escape to cancel. Mouse zooms don't work until you actually draw a box. kst-2.0.3/devel-docs/Kst2Specs/Layout mode.pdf000644 001750 001750 00002176206 11544160206 021431 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream xZI7_[ahA!'gK~$vg`hzUէRG2e?#?Lϗ P8I*6}x_N3Yit=if끜fnb+;ʽ\cKNV~M.kX׽Ṷ 0oӢ7:5^|< 3XXhE> +U2ZlDѢuVpkv=TN q%lkc٫ %^c7oxIB%%׎\1I5CI$Yǻx%ʐd2LB̠7T)PY\Y"0OF, u !h+܍:z!ߓ=nO<=AjW[cIFX9fkb6_v)wg6CB#=s vb,P` sX?X#j5c z~gxyφY,leaǖhV1ZȮ4Tfu6 4եG] M@I:Ww9U7nQTKl̥-~(IV2 *ZP!JAEd4FNnJ'W$ғPr?*0 ZaX,(v[Rr%)5w ݯ+,թЦl@էL0'$9DEVU4|0xVB&ODK$ǘsrdɃ@rdeVރB)=y&O8hsP4.-KfPxDOvOpu;5O#w*o|wwBwCKcnezL=/% M!4+)+*R<ϠZk E)қ:yLXӈ])X̺Y9!wf3&2-R瑉hٕSᡮ.;ڨ0]H%- zxzʸ]{kc9h֙5aͩ.]$ng۾w, sAMY3fmZˑL+>{R]WT[El2Ry\+3$\G[M!Hl)iBM?&+ FZ'4)ʣހa0/aPصH38]6XPRY+;B,jGG"@4[Eh|9ݏOOyh/0>Fq̀K wȎ )KKߔ䟢$zNbq )Bg,e k3s}ւwG=@ȯhӦH$f2BEYmxrʻY>|MV|r/ϷTK@ҏR%Bg`5&Ԗ֩>N_|bt)Tho}2M>|3nL6WˆYcmy v-%q5=P endstream endobj 3 0 obj 2006 endobj 5 0 obj <> stream x$Gy'gr{ao DYDl hI2cdAda6Hd!@!H '#Lw{=~JVW72 )@`ZB:cuj YuIKC/R C6[udF'8xx xO"cՁ>?V/Rݷ0rD9`XO !3$9Qx Rѫ"X."‡{0+Eī[6řU6`Ln؈}PUR:{WcoBFZ85xyqDa$N!A+M GflS06nsRFD("uºaːʶO\µ"΃%-u,K_$+.No40F."d[XA\rQ5{BR!R'IT,ػa_>;"D!돽tY4"fvިkSrF%^Vu--V'ڬvt(&p Qܰt@ NވHq9 g;nY2vޠh F,CdWu4َVKrpt8kƎk,C:7,S#p䃖L,,ZĿۛjvƞm0Q4%W5`r"/Xff-̟f6L5K*8!$E\TDƦ#К#]B >Vǵ'13%@Cƞ;̠lTڔ, k44koؔxefʃ!j5`ovن03%@CDLKN{UD܁6ݖr Qo#"i "85CZv?0hpn;RDt]DH1zAݖr Q4éK %"VMC("z:6DUDyY}f6}HH3Yzz̀jc&咍Mor:MkP>CXv񽩨n @TL*.)zRZ7]/T369`lPnX: 3h-.p3$^dֲm0 ,>8F.A{,iXcͺpF13KOHE uMl ڗ K3F8ZDД$XF3;K6 h9,> ^.A{i[3kD̺p&%}HTuuMl 8 K3FDZDД$RF] RH*Rh9,> F.")D^3SZv̺p&KHZԺ8Hn+(Zpᒻ{ &4% >,Q^YbYu^AO#PZ RՔȫgX))0x}~ZDѬٍ%@ʂ$pnTKZXV_-bE7AB$T5u#l`G%Q,`բ+%f5ܰ/O(47".r$$pn˧"DДJp ͤ⒙W"͊;#UAwF,c$8Fxsþt?-hހvna-c1gE;ᆠ D5 ͤ⒙WnQwFʠGXQ~}GtXoYD!h*QMB35٤GֱdVQ<)O(47T@>}hqEޠ%[c|ϊw ASijy*m:jzc~ʔ!9epH~ZDѦٽC4훨.aLW|h憬TG5xxe72)댠5SqIh/KīfS# $>xs !>8N#oо6H3<Sց5j*"nf]ئ3DLY6V$,A{=?$ći ڷ-YQV7"\; ؀QuQ{YˬȫI(SUpfCpQcWPv)4Q ZVܲh]߬q]tˆfU!9wkUձO,+nЏ'L V-%  U}uq^e%Eow|-k0]{llfiRf`fgJHCcM+zӓ+%bJBłASRqID׵&뀙)K\:=0ֲq홮:`fG؋GUHȫOTR^Nh]19 ^\{[ďa1s XB[۱w#xE떮re6aĬ.ʲR9j>UѭS;8f^Z>D1 N7.IF9mͩ((X`nB?Z8Ue ݊+ZDLvZbW53b|o6[QE)嘥n/Vw+eގ٨#\8^J߮b$^-7+Z=֎^8}{ت81-bD߫;=tW_x foG[Zpq)Ќ ufZVAGttu Rxh_X먈o޸'Ux{7 4}2v@h&WUopKW`_MXKD=݅"Qw֢/TZRt@CűcƵ?l1gմu}lq.eC{(X#-݋(TZ VMcM VV"$C%"IsiA*%‮c'o예q wul|pT5k-!t-;iMekܳ{%:H9\*D]qC5T$x5E S#z8`p;&bܿ\iY UnYn%fՔA u}+"Bk Nȵ*>,O+e\ٽRx.嘠qo>ۗfYzi惣$RٽRڠ[S*I6" ,Dz¿ Հ Eg76\l JUqN1-[_h6Ri<@ HIC:Dx~@GI@+''H999<@BPLΛ]F\"i dvtB2=U%E;R~h4>],)]4(@C2ƧmA}R_-YAHNd< sDkMl@0X y0`MDl@$依XBv \|şg>򑏄vn`7 @ 䎝LC6*@by^V:mR q`ޫ;|2l>餓^";Ke}F(jT,YLf* 6<򑏬ST)=.9DgMd.233S0p`g-ݙ]7PSD"@XsH[[M7TǯL2p1Ëg*.;^td:sW?=zT*1Q]d.l''ءMًLjY5-oQ]4eMzW*7d22٫xfggG?3B {2L&+>Y5{,..^:ϋc@Xu=t솖Mjd2Y)٣ns9'b-cix52ڮakhԌF&DP^xa#GՌGupC^]ӢKJIhf[܂nѮ P=Y=_uɍG !uj:V(҃2CtpJCߜ̚po)؀ȖY"zzֳUN ;ŵ\rb`DA+GGXs( @ H' KNw]/ 8\&UH :/誱h43;d4>ؗ+땍?E;#eD400PxR!kSE#^(3dVNGh;.B9rؽ4D1T.vOSyqOM&hӬStE3 ުhGA/ΈmD<>f V9: m*:n2d ʼnCP [" [ŴzWo;{6m섺nfyˊH퉠ϱd2qg,5li77[}{]ZӸzYZ30ho؂nޥmB-#.2bѦ˲`KyqAdUGf K̇uN=}scW)c]Ӈi\MZ`ľ neMnh$ +-bQM[2,dؙpJ~Yg}z><-kv\m鳻⚕n^A7ĉ!auUnta);*#kGT=s`3\rIq0u]`Qі>{.NˈTdM٣e ". aJZ zl'>Ǐ3d^sY7P' ׵&Uf׬F,oWf`,xHXT$SNm@y^V7r'}}sqOŅW~9 -Ocy ~3~HLk`PևL@fX;'DLA+9FK˷LtU60M0+\f]Vnq hO/Sw[bw䳥}4< @fX;!DLunZ3\mrxL!pF7K ~J-EB=+UҪ`ZM>;o DLnU#GjW^p+V<3Z<mm|.jk3v.z\s=QRF ԫq: [nr\ǮS xLYR9<-o7E lFWM7Ţ]7+ELoԭ}L\DU SgT5 ܽpyrgԯKf9>ݞj~NoloɷaYw"xmMw:\ Nf> Beօ6ϵ;̽]6J{}/ǮݥnL[|0K;?Zu.̔zu @$Ƶӽjuჱf7:s chM s-o,|͵+=}_N#ɛG!mxå%,ڎ8~Ҋdt…Mq`S;[nV)8 Y>lv#<2$,>Ɂ{uToWZg WE<뎈#.,:Ȭ8A-k-U> Beօ6ϵ>[9?\Oa41E0 ;RXW:;]6!UE2c"K*䠘{xq~K.;fei9ެRDh动Mī/.Z-&s%✄`KDnI* [af07_W-4b7+.G5ni9 H?DiAf3"P)|!Cwmdxr0eӻrE]~C$NǸF*=AĠKF,mA $Cp֨dJ"p, Mq<(Θl?,65RDƦOĝB=GٻY2b-¥f- dnX"nV[l)OlҠx@#$݁Z`voXY)WhgDY ڷrhS7;ccAEll@ |zDɆGɗ6TȦMI2 9|Z۠>2di'x.,lH YȠ$^kmetxfN$.b GNN]BVʲ4q!9呹&0ģrz.oM?o(呡2 M#{.=صkc}CTF&YjT=6szn<2TF&i<fP{, VE%_3|FyU 2  K_Q**ii]E#4"|Fi> ߊ`n$N_QZT(}iWƂZP37sJワ(-:J~*to -jMy3xHuH%S{pWQr$ (9Ӕ>4"d3m@#+}iGGPMs&<D} ¢i馩|IO+E.9L_[Qd;J]Eh"fNui.4T:m{??;5TAP&qt_OQ4 ?m}`pWP,>V /TcTh4>2Ҩ҄҇^<U=s|f};(>ҨCM$? ݿ3H]|>~>y~,"*ʅ&҉Rɧ*}i+Pf?Q?= OxB}\,F+ @*Q'r2T!?]E(FǦۙ9Rl=gϞ[®"TҪ:ik(Jnʷw|9tTpo֦3T&̏~-H*kJC>CAy?.Pf/(toy#Ql/R27ٳ\V簖bw~x,J~<7Etߝӌ]{[oU]. |~T_~ꩧ/cy,5?ppWTN|>پ/WTwjE/ZVW 3Ro/(*TO'P3l|`}v~_e. ###?Wu]?>_һ\^%o&ƚDGbǦ"Tǧ Yرc,{ Eo~Ws9g׮]**'{PSm{҇F+5Ӗ7tw3P,{օN:; =Huچ W5ē>M]Ed7ws饗^{\q% R=鍊nZyE]t'.@5w("JGxpWj.vǤ===]vY}=Sb֤-"@Jŷmg>Ǐo;N|oWH׋ҋG*h)^:?Sϟo}[czoLD*{ԣU?UW]Ї>mEi(}i]U:6UL?wf^n՜tIW%rqQ5h?,`T###~W|ƍk/.Ӡֽ҇/J:6y޹4!_:t;Vގ.>a핿ϜY2$Ss RJϱ]6U|5mN=a|ɟ,vwK Ln|Di⯔>TJ{-O*ޜv/G-2MmAw_z 2bO>OMQb3J~~H>|_h,8kX}_c*Rط|ngmߕ J-Te/(EZ>~IWՌg;.VwrĺtTֶBg~k _}$XaI2op/R؋;wsE" Gio/'*?Ϸ?[3{.57-<@њO, OQnT1OG,F3|K=G*#RNбmKz?Ff~x  ߿|[CrPbyO+CMߵчsMOʶHO}'~izct~v馩 Y(mP :֋ B}^4b=#i9O?7N[žىS0[hϯY%\fB4 4[=o\s2>F7wdߝIef4rgϡ2#)N_,/إa;gh^P5|nڊvʾ^s^g}橮JĪBK&:0ICZP ~>JVYD_|qAm9{OSDϜR܌w.\0ۦ7kOi(i .M Cut<^*?/t巼ջ/=|1+GY"+Ţat<Zkğǒ/nx}e]f{ْoMo:ccaUSP楻;_;PHlGY(=sXFHU۞N߹^x玶NMu|zN)fe; *KEk. XҺ(a箘S{|5oj#-LxX CCKs?)nLJUΨoF3P@/=dãt?>nf_ҍSOP:]J.CKC`9fb|FJEОt.#plwZ˓ŝ; 2^V;=Q jJ~{[*ѫb]Km֍пБw-\cyb/Ru3?jMֽ҇O'z*OY۬U? i '#D.)Akn >ᣖ>Sn=sGNM)Vցo)}iI=1M4m۬ǧg2-:RO쨕-J~ި%~4wjJ8O~\⯽~uci_WTPP6 A5QkJ~tnߖӌU k} 7pwOǢIw9a0/LPb{nүfݩ} OoT);SӠlJwi[i/ fU{}i\{ Uڌ|[nK> k)}DUSŅN,@ZК߂҇6f`Ս( ߱mߗǂTЏ&Wr-eŲ tS7BS̗~r_]ObܐGv-۬+5pOUG+x!Mf+]  tyY뚻r;B۝}xB z#V",߾Nu'g-f-ֽ!l}OUN3pӠҶr.Нմv Y6 ߾m0oԶRt4^\4b#ģ5ekOsEFֵx}x'! tW*ts2Buul16J ݿS?lpB>B-.1G Fw >#T5J~2w<{D:ִ}iF ? (npȪ 0B+?>M!7[W&ۆUlip4Yk28JM?W0yѾsRzepoJ,<$y)ċ*9OZ ?3iKaEۆ W<txax%|*ZUJiޗqJݚ HU҇T9T>xqRf]?TN3 d(u4,|Eh|v4_~M=wYRN3X i2jX]j+Jqϧ6k] VJEŊ$p{R-\;Wm^_h~,?jf}iO-BJ&NњpϨ= osv~Du;M0w4Nwnj 6[|vt!K/drxUx,BGcj-RTNSMt|zWƦwꯆ_wTb Oe;HQu{KMsY9oأT vɧUSzsz^SR&䉐Mo|u˗Ƌ?1޷8؈b\+4Ǧw|p.=?GoR*usU_nVi3'cm O}+)G[d;͞Ov( &+WCAiJ"N#'Ltlzk6.oc>{DXޜ'l季z@;'jAv˅l=sk--u ,^? JƋo Z9$ P jSUȞp]eV9)I#ts#B-'*oK.j's{o `^XfF_|VDӣ9,b7|i4ԾplP*e.-*O'CZPjئnzvoUgrkwI|?B~d.0] (gBZPOQLtNNs.4^{Tw p ^ZPK7LulQNZ4/fzoO?`OΫsmsWXZt|C5t4'E|J6uFk*a-S!cko21B-/)n8)t^,dU{}s3{Br|@КrnܮT|E !Ԃ+4=Ja>_|Ix?|3-2ʭo"%jAʘ tw/r}!ԂZ>:յK̞gM¶w ˺͇W:)$q|B5|FliV\8U kG*m1oN<3Qfeװ <:P jj/Kߔyt]JE6_AY8bDȝW|£5OVoڧf eބⱖ ܽ1á]P]#ª.B-(5^y{4p.툐k iB-KJOͷ/fǓ{xs%.g!?2jX$a|^B|tA4bin:CJ ]Mg >&Qב? ޚyVHI z:ݵ|TtcN8||zUk=\>xcgƔxR9xk"Y4{Fkԁoji}_vO(f?5Reu/SSБ~V?b>5۾-x"_YA4 hBc=seŔx9'ɧëoxcfhtAB6E(< U[ZS;m8*]KK7 m:6)mvqV_o^Bc|9}߫ٸ4~QK2Uȑ$|A5M% i,px#pgAO 5oϓ-os)+&[ȑFkHpBUDwN-|▷5&Tjm'1{Qw1:wox?ek' 9xh BWFxcmK7InjJ~O霙ez}E 6;p|in"9x@q<dB?Gʕ{,_͜';d68ԽЩX^_(˷MFb^"lMX*\ݧ#A%P^B p]e,'%mv=fg?w+6s2׿<,ǧS 659B>e!BwXBsҍi{GQӛ^7Px,+&ѳtCLM;R5ba{N18'^cybgut-Z- UT+DwliIS sW}=HБ6%FfE kgP((bwOo~@G|>7_5x,Cww:~1A+ix>BY^#pX > Bijx]>7?5Sq#K~{v=NAva@cV-7=Bui|]Kb_K+\w}Wbpe]㏏x?m,S`+ך+O:tYv Ɂ{ŜTqF~^i о˷*ݳAMQ4sQPg PX_k5vQw+ڦrٺ|p6B?et3;jPfeoԱKa@B(O~~<9x_rU.ՎfAz.v[F)!u/Egۜ:Cmz#~ GYr>6b\B)bFj8^2 >9 ?I[ 9{H:987Ԙ9֝_ű| ;jPH7hU&B(9Zum jûb{Lw&Cȳ\%̪U&B(Q9o,6w]BF4ue!tv5eH;RODiboL}P Poå1#hu0) d5&gP5tb}Ǿ毩<4~KbO~ jR+QZ]DkjfADQ%~5{f= X%A.RDqu|tjn E-<6%ߖ~^]{K{]?Lc 2c!P'xG ݯgܾXhSjWw* ޷c=^70s%POcdFk\iX>_톟神|jOfB(iFV + @G:ʒf/Sڋ}&Vwi+dUmoXv5Å* ?:Wٌ簣2^V|l뚉J|V/'"=A܏C6OX?M];jSǝhgl Pe԰ˉRV>QS;r,MҾ9;]6/ŷq\y醐ۢTwvP3쨩ƼsG[m?{7C)4 KvXǧoH{4=vŪrzJ3 =3+̻?5VԴʏ/ʟi__R(MfVanV-.(9ogԉӵD2DK7NulS"ˍ<+x&/-olx{>=[c^<2un^yRC?#=QSçuKSck:l۷hWi(>/Yn6u,r%޽aFm{P:/b4J[k.JO+yK~v(>k RhHs&6On/{&}wQ35UyQ0Jn>`QÅwI1΅Hf6QZ|۴ȩդ]ׁk+[6w@]"nQRcӣb*8kxۇ3_z`~|1Cd멡ttbw~{^,t+ckeG zÅ#ȅz >Qjt|zV{i)W/}2_htީLyz/ѱ7Gf0 oC&d+R-e+i7@m~S_ܕ3k*QPgT=6gָ,-I|}dGmzOш zObG jf>kNj >|衴hgG·ɗ0Z{=s4~{(Ҩ˛wr{ia]Sݻ̓/,]{wlxVgzw}t$M8J 2]bBLQ*Μ`ʞGpi؟vt 6;\83Mw1)ܞ>2MBn'A-'|)GJ=յ4ݳ_xi\u'8&}mV']㻝:qg^o+UUhtT?uۃ/Bd5YgaVhu Efyf Y'>@ĞRyH!gi_Wt}M|{5vԜ^v@a9a燇/O[O-j8CЎb =X=k1'֚OF#N= 5A:Z[?R|wߓyXԎ|173~"ī&;^R+&ܳ!!_"gVD{i/S=vN}GꎚmRkoiAOK7NEQ7v t:y].Bб;k[],/:A9|MWw2O"TMY׽cj6_*.^sǦx6t8WwUٖߓA*U.5&hBЦj߹pm)iiܱ'TVQiS8nGgh|CmӆqK_y!B&SNS2n|ThI]5 $SJ?svtwYs{{ʹ5Fʳw5gEL>FI_w Toǁ[C,Y0iJ5ΟZJiP!7A Uv~xTݡЕ/O}1t|}]y2fJ]ws_ěu뻆\e=[:-"At @UwJ\d+?[_3_RM>#kҡN|8CA3_9'iOvSB"wԔ.^;3_ʯ{Q_dGHWWdQ JnجwPSpB5? *J&<~7{)Mwxz}=nJ=jGwTiŮ@ol.F;)(-FDQmyJ~]ش03玵 Z,F'9fGͶ |(2KjXrкhBR)WwOZUh8h5VsgۡcOGBG^_t0f׾X[.R/h;RсҢ/SL9jL>-}nt"T}}1(!bG`+̫n.ֺJ@n{qyTL?o(Q:0 @iuGK7oV537-:\fйtcP2>:5P1jP¥e.9he[GBJvLFRjSROV|zQH*vE~V/U@(ʲGN|,h&]I4kzOe{kOnGM5<5~V/Sdg| R#$LvW=w;Z "$fu,=2Z$@)3pQt>*OoYOah6mpk*= '֨kDh˛cF&76/涼]K3hMt;IRYGp6N3P-V׮Qsp#'v^:ѱM5.vw}\oOZ`v|qmX甪jݻ)Yt4\2˪)4H3)mQ-j_#Sx}cokO.Ҹ4+cZt2z'#vϑjN)|IWi!xG#5Nځ[JesRqYj馩.]+ktli!H0mt4ƬѾZN9[ zgQ|~_ğ)mZW;>4C ]-o>}%=sM>yw5k|`OU@iE-*]-ANҥ=gΆWw^ޣRݟwYÇ Z?!'6(oEWM+&K{tۦǟq0fSӾ!{)ckG2@R'+崹P|w}퟇e.~] IQ5+M-j ߛK7N ?w*FwZI=1[9ܥLt[?xF)ɧwXB ~cEdmMW^m_ ϳ:٩w1˶WzUƬS9:]o%t8j>xFӁo;/i=Hӫj?nL!MVl"9tdNsפvCv)EdFmyW{+%o4~?͗_gYjH.Й6?=g[xw*M7nPe䳈n+(R:ZEETOd~I̡{?|kƬѹetEopoboޑ?FT6lxeF2E[ޮ+!wm_<"k&ebOWn-z fhY8c`RG+TIOBjR=]= eΟjo4~aǪn)R.25+_ҍBH@"oh].RMg|Vv 2Ctt*\:K"~쨙B+꿛+\7Atp;'Jޱ-RͲpm4fKNL˷NWNh>ǪG޾aT8>ꜷNUSHk7QghARham͘Ngw-|mX>%˪7E3jF-_^d3U%!l5'lL9SL`=u]/E"gx;ID:ɉܪ_Yq 68ˍ.6?Wڊ=N46?~g*!]SD R~Boݏo|}f[˩}Pr"?:&!=9ѹڪtc$ ߚ[=VөM*!")"& Q~AHZ7Vz7|:^-ɭu쯥 "GpYq&6"ɲ6ׇ&ȧ!t)b)'PzFxu|-O}RjӏUUt0$.J &9Z D2?S!䖞:_oKNRFu%>;zp  QS5&3jj'>[of{5?kbK^/3UBqIla:#/31O%-.T3WgXC[ϣdU7R-[[ [7KN=RIaf#zr?S!xCno/sWI֜'9ѐzDVPxfUO(|x Vls {ͷSV0\+'05K zϵ| N>UeďFN.4$&9/'/̨ps"ZH*?@!ELr /*='PIr3T'OoN$[B _4pґ&3j64|e^PW…^q|db*0_NЫRf}t4') _)[-UFS=iBE&>4.Oz TB]!k2وCodW]/s]N"Z7vOAZH'6َ4pu?7 Ntu~auʱ;'],14Fj P~ A1b5~ᄃyLLߖR_}ǥ~@[U vʘQ~e ҿn `j= lgw TN=zO[z%^ut &-],aPG esLXYbs{r`L7VvrէIHyjmױMYx#SP#mNU 4^">'ny=曭O]OcKl"*廐6S;w`r^ PӔt'QY[B[K۬QMFGG=K/t۶mu9]|`Can"i7Z]_L/aIbD{Οmvl8#>Btj=j;<`^{֤^U;m:m}e⛡eG[ZŚs%ȵ>&g=w^KL=?A%9"J~~'+%I2_/ذVZXEٕ$MJ v'_W`]F'FiƆoԖ.+{C#+VHkb:iN}B;_< /3Eo~rH\+ĞdإP~_-J29V<H!O^[q//wVMe%FCpHFNٱt/odi'fP=_xf:M.{_gu])֭[/c9fxxشK'+v -5Dx|c>NG%|j{kԛtӋRޙ$i:ROr͙'Vkk!m7r :\KDbnn?SkpeXrcAo:qsk)Tjb5AZ}rrNib_clZ"6N(0_o!,guB&o?묳^Wwvv 4$%Hx+C5D_:T ,1bINgIȇGo,ju*dJZ7X^Vd0<&<G /6nAt1md0pC%.eMsTUOH<58?&ZjbѺ k/G)ĆBA̷ =n˛&,.y'NMMBߌ[lHiLxy>Zq2u:%h;cV=St=5E"[Y8{\ X~9$OϜ3;gݛ"eEB؞NoM'+vrʷw|A6o裏|fhX:A:ԓRNfr_e~iof9>:4M(GZ^XrdYJP:dLsvGu9a ل ~h%Vǩibx^8Ywy%~JLY%ABeN}H \t!]WǴ5f.&Zz1`/ns@?RcΗGB= _Rjuڊ85E H;kkJN5Mzr{ O.$ю}_YU $Gl@q_BWȚ.bYe9@3ĕ_*JwzKuevJv,] # @V%=*j0znUP[**u:©Bj9RPKs]CZRMeNI*4Ľe}A;C*NNj1ByKAKt=q\kdqw mhYϺ $l_gb嚞/tP~IBv& 1W]@:fSxm1vG_P~!Ѝ*c?m%(x l)o.#i^Y7 y_[FA" [ B+G )_BU;:F kWZRL8KIlw;^RklzCRF Z‘/ZЫNSdKWIV45T}t.oϞa: ȑX '4~W޳e4e0[>_/cD7B!кTXG@LW%뜼Rd_S]hQ.B>FެHXT B}U ]i*#͗ VT,G!m"GȕuCH<4:6[uAh/Hw]t:6 {򥋬"S:N>P ,䮯qČћh+*̶jtͳ?]5b%!,k4p)"Uərx8bvʌ*I5֒/:q/CYsBn)&!t'"Z#V,q|ӏ|uꂯEz<8BjrB(qʄ9N>X ئN|mj&,ҙؠlFcy!#-d%2DE_:9*\Yi'vHzB4 hEEݠQBg:NǾQj')VoT~:yGB:Y@ 8rPSWB%ZJ@qJ~[?:rm!l=Y)7R´Jk0BH2Ab(!ڟTOTU:tIΞ '+ӗU^]DXcXLB984x@t7WG$|9>VVtr*lOx:R]qbN!r$o|R.=]|'o'$'[>NKQ7JCC"u7kLBf927kCtVdLT6n+Y̓~ 92R4K*?qBF94q[B\wy NofsEJQu:Mtup LBf4,xơiw7V;Y4fSa)SY[9a>ido-4wi!ݴ(m`;BK]i;̮Ywy>T3E R{4Bȣ\9indN?V MR`]BlLozlo]5 *?/B:Y3 !uW %"{>OJq^y,?W[NX!9ߓSӬ@!|#`q{BK%HNQ|troeJ[_ ͽ7 yG7_KFmrv %nݕ)Jw?}>-xiK\<_Kkv6HΡybZ4-N!%`MxkItȷ\=>J̈́SX0OݗxItfEHPCZw9@!W#8G!Z@Z45'%=eN);4T^[yZdkcFԦpE~Q{>1tqn.%!T+_őwkILkz6+-#gga9iwV'Ȋ?t٧k+]ن>B'jsP^o"%Z=>E3e|>xw3|ۺb骞ߚ ~ Һ &N#%O(d#T _)9A7JpUi/J?:H|};YBn+ MMPr2bd^W$𾳩i•ԣӬ@_咃Xp7rB.9+ KVrΗSis*++={ʁ o C?:I=Hh/sz_J6Ėݏ:&w4fz&p\p!|{4L%( 䃕u{>Q;1]z{"xD彩S3?xkuלKNSO=$g:ׅDGP1@kB+2{GSV¶բ, i.YKP~AU'Qf rsHz|j/z3O>]q4rua7#j''!-?6tI.wPg{85ނ5Bږ)`|;B/t_"9?ߕ|'} #gB -͋PBIW- P:rӔN2O )?;^rlJ zC7&ݕߕ]J]șNNz"HmQ.ة`]MaʗV؇uХEf];zCQ 3LSGtJ?KķkCy̯\AOt5@◮B9P%T Ox3OTcAb:ZH$gS(=dA+G.đKbV~B"sX+Lab hr~;9_z aN7zCQQDR7wT~B /$OO'a:Џs 9af[59a YY@J$Lӑ;B';H%\rDV2fGJj߷Q]'B.ތ '8ЙDNRj"ϐ?8>Mo壒OEr:EV~C4[%LpKQcxYBlYqfIp9oA]myNFv!N?V1@>GJl]NkcR>kO݌\]P~!5!5 L]+%rӌ\S h@(ūņLNL+?BˑƃqlֆPkFN-a:n˄/'ʘ5sZY~w8i!| {6+i:wW~C t/˙Nz U.6GgS!Jᕵ96[<:&󢈬J Raeщ{?RBqBkEP~Ch3@RN=ZLER3{R>?1ƧLe`^%uW~6!Δ)[KjT# >~QڷS{N V:|BnQ~B!D82 H[|6v'\S &OH 2W w3hǑCKT3Tӷ_1mէ3x+?4BX/_•Y#{eY<:M2v"u_X>5'kr.RP}Z!/EOho}c) 'R̶q9;+NJÉh+?֪D5+gOړ0}/NRp\i6=$¡qb+&6=ON7\d {i~'!j]Xn 屮]^&+,OUe/b80cy}gw<_rէ2e&Bj]Xq,f]yG!&Qm}_&M=Ra-y-i%HMכK5B kžhYKP]6tj:XƞR?l?Nl>|W;1Ao-m H?Rn%l+kO-7Qx|G#{+ǦLkϿ:1XLM= ~%W6-B9xhX,]lGo(.@NA\=ǵX5ͻf.W&7ȪOeQcf{c':3LzU֔c|`-vvGq`َǚ$z_z;uEz(yu`b<ݍR{=z΂31i[oB=9BHMWy7=*d2w`|ͷ#n/YtiE-bOsj[x#gx,J.T)}ǔ_B 5S =GWd+ѾԣK0Y9|_I^}Re6i_ 9~K3XiYKPޫ@/9#&qH8|%/9_BG #HQ^(vgCM+kB-v<F dAodM?Ϫcw2{=7rlʺ\>}0]d]IЪtzV_v^¦2%@᛾]=dJ)+}gus #LYqKZ:)3Ih%3pE!?$YŒt^JeL!kC&"Pʻj|#d{_ȪO[6?שG*KX]}M{˝Y~WffeKáL>` r$9@C'}w t'yh3,\^ѾqP_qe@ooU£)S i]Ĥ) !l/sAߏʻj.KH)mB-*nV}Ή{ʝ/|,/W٧=-#N慑e!KXs\oItӏUJG&f_64]}|tW=˺?%4}Wh&⨪s -gȥz*xk)w`(rmI٧p2PE3^kmjrv?"5 DssX>hRA;RT(gZ- gRo>'v,YsyKƆB;8S;K 7 \ (iUu@ &}_=t;kW|>WdyJ|5N?L.Ι有Ц9M=bͷG~]n&< WyO7pQĀ+JɴN zəU=]XxPE&leamZ;d[v7[לt:ɰ!l9R`+ⷭ B{\iHNg%򑕁-<>_1|z|_:E]߶(mpf{@>gdv8 /|Nm99|(ed^ɼ0 c5cJd|p3| B=Nة*>4?Y4T ޙA}01_wvgx SaIiWnc!p+-uvg-fKէC?qLs>0|Yt]ԺfUfVT>*iQq=k8&}w9zSQ Sm '-<>t %0Xׄ#NY4 B|>{pMMBw_ZdibY}_EgWa\Z'T]U _]h^[Zfzs5ȿ)dH+[19JPމAh;k=@S壓zOuf[=/kgB o g BSױ4V S!{3;`86‰=]b}:G%\,q~YW"_WiCx,-Dڀ Bn}1 .Di?+"۔v[~%LѪ_I[MIJt-.J]y\2ϴK|$4ruAy؍vQaTՎ}IƆB3-TzD;AX'ǀΛ\CӁre}ʾ(tUo=9'`S~WREgvnC9yY'%Fs2{9%gB끄V@zqr<9˲8q6-l۪}/k$;̚sCG7s"~+ 膛nփY)+J_ňmx >Ay,'QNN1/¡_+3?y!Tj֪-G(1tgN_7N|6P&uC}GV-a:beR-`Bz\ei'>t v2֍81P v6)ĆBzrywuqNSGWVް?j~it_7̓N!H5BY]E̫ZXK?/nߢeK&!>a}B>0oLcf^FJ3P󵾯t >O#Zl رoxxbBԧ7WIog%Ԧ缃0;zj}guFUefUki*t9hy{ Cy,'_{}\03;uߚPތu-[>j:=+/Nd =3'6[: BLC"l:]:wrbE,']1&>b"̯.VtZϞ@O:F w^y#@ q﫼{Pk/˥Yu F U#lmtJ_Nsu:MMli[M,,Gr@td*Ay? D"OQ+^aIO>;zZ4wZ {;*%O Not9b14%(*!놛ŷ%qI.).5$Y5Ǟ2HԤbB,}&rzκuW v%VY"AM^u}_d[Sz^1XY(9!±J$kd0F|UVuʝ{ۯLDӛ1:BAև44}ZĽ/w^y<' OSZX¢k/)?7aIjݕZ|m-E=/5_Zs:,q\yS7\L -T| @G7r 4~)35a8;?X>\ 8yVr 3#(Q!t3OV)YOdjXL0?=Cyn£xÐ(Z!tejs5w Shݧffw6_\Sd$B~_T&>P1MMcT3WK͊NiD ǧf*9塐GOp"9"gU:5'S3Yf춒?NN3L_oWD{~Sѐ{('|良~gwTͧ|k*ZzOtŌK?/ʱ=/ތMK>p'}_5[|K4Vg4wJkWޛR]r |'qd]y My =i Z2{St`2+7MKIN}S@7qw4Ļ5}8SBGJCNb'"]bDC|¶cC4NyONo;ͧ$3Ooj]@:f͹ iz?cp90(@9Byծ8)MroM(Վ}lʾy:MS WX^]u Qiw;9D5q$i:I[WsJgtȦE c7S vsOsČRPv_u4M$O=4Ak<!/"o4_ne M6e4/*M!)!- ijNU1'k4O|_! i<pw;|Eg"#Ľ`u:MٝpVvuʻ};xAf=gЂ{RN{,/4b: t|נޡTBVG}@(Ms#&x6~@G7f1wAJ:)^ }r0KNs@GhŸ`BfV 3>_l әL#ƙ;v`;(w,.ꕏJt+Յٝ9@%E{;`=#3?}_yZ<|@(˙'gtDֱYNW9j;@wdP<(i@] Ljwfl$N7ETi<-3zCt3Qk``AB\[4~<~^DV:=v{YDG Bn<|ZW{j)eTY 9indУP=.8"mvzk ů8@ Z<{ׅ[,}1B1c?ng>s٬`24x_mѐ4peIϔ@LV)Іcxh?{xࠃBG>$#np?ʦP )z::=ܺg?YOOx65k-qH8ߝysy. =Se~{'x 9A+ӌ}+ʇK:eI_O gwbis=~ItCRDDLЙ͟v|MBɎPlrtt[3}O&x= ^oHZ\Ӫ ,<;fw(j|$zG}͛w}+^ kUxntLC U`]P Bϸ$j /g>+^2CRiqG?{iN0 ᒙͿV}00C>UMM U_{)~B /۷/> GZBx4|eg6iٺuk TĽp622 B%\V^}W,u_]P |,C3OT}&i4Mꪫv|׻eqXtPEV^ǩG*C8r!_|\p 7HQ_ǠbQG˯k$Aʿ1|lmMlN- 8\X~i1(PUVmٲeq۷ o'7z7Z2}q= C߀-?Mae] '`s:.:y99E}uS4PJ裏.ncǎ)mnLNlmo-yC.a PrE-r'nN3W)R6t=8^PF7 K%|͡g3D8W[4w96َ!=pSJRG>wߵkĄ6~gI !ű7{,OAyEv¶t Gy-~in{f1Bk=_$Z>T$t]>ÿ\s45>WB7:vG)w5mNd-xbq}-277{oHhcc: t󵾳:e5UyA [&u#HӴsYO7M{Ntz.w䙿:߅4Mi<qs{w$&O?iw\xx L uUe{# \1?|>~oPeE֚8a2U9\.v@s9gxmݦ~b^1BZ٩AI0(SBl4sph ) o/|$Bl-ȁs!t Wu7ry.;)ک YZ QPpora=m\N-)_B !ԑJ힁5-E#\.g͛ \$#W>Brg&dehM7p5zۼ[EAB-뒁[5ט{# orn9-3xrʇZ!B.T3FVt^f\.g͛ \(p!P|'{ Kվw^VD4f 4(X,GMaEcE@k h 5r.JtE?"1hKuIKq! 6i<|T*b Oo lFPw_!deA{!iĢGnPx!d1JԺ4E K/Ё!B_HV 70Rn#1r9ancHC!L$c 2"0C`زړ9.*5؀;S$BiFYLBd{VЦX6dE޸66:+5Zmc ǹ ntKqB)vہ͈\9|H sY2'l&R(Meψt;|tBcY;@RDTG$Y׹ȕTgcj(e58n?eP>LCa+A#r(a/u)#lE{2E˽JKM+2͘Ʊ S|F:@N)"E9 dC|kqӊcKYfLcE +A[m !蔏B [7aX9fx3݌};FKfL%LѱBhHV`# YIKlԞqtW"b!ZAYNsX@$+"zr$nԘ67ͬ8e^B+!m(GAvGB"br$nԘ6  qfLeOS;a=pc:}ָzGԧ1HDN[VCqDeO`oGz2ͤ1ndB[X;4!)vp/r7E5U*7fmL<W>ChmjU9JkUgPpw"6 fsAܬ}h<Ыr]Ɓ "YT#a բ)aMbTJ7FӢw'BSnZfgi =c`{E>ڑ| 8kRʑec5ڞ~7 n&|ЇzI:L ;rO 6爜`uLQ3ir7X[!BkvS!w+;*)RcʶD}w'BŠj3@M\x;(O pnRSMU2дXMy&!tLtRy2!t=xASyV!t|=WϾBW#wi@ O38"*O' ,BMR;$Pi<ڠuBc-| E!=|B(W Ga̖%vHGW_!lg9z {4} :.}hcT@E%zM e|Y؆F鴺ڒG<Kvz /V--"Q@Y%8\{ր]wmf?:i Į/Ậ ib ڭWyr! "eMH Nk}_) @#ew]X4!|=W/pݕﺀ u(X urnu"p/4"M-E ǥȽ.7_96ܭдLYKTQ;0/YњVDκhR;#~ wW7<@ix\ctG2)q+mUG$xx19{'Օ)^Bc!RYwል#*$%[U'%NHlirf?QB=pr,+d lOtX :L%B,>JrZaEH)Չ_04،~LSb mD^yJa[iE?D(c%H܆6R@ n,Ǖ1q6LaHن^˷ wB)XĨv]zv"渣xIԵ۬q L40X;j5n`l"5Bo;j,M$*"%r vv]_<Pη;eK C|ݖL7Hƻ vYСBurqKeT6#4wTu7Q9|Ǣ<Ɂrܼ苀렌E*lW`<HX6tDmi]8*F5@Wy'sy;i>W#^M 6u `'&5F%}VSZFGu ^JTL[]BwH{|4[J6WJ]ap.RXh.L"%H͘(05WH )5*DA)| |w. ,GIqִLew"X @IiQqwRZRFEGhxN@?z@661VLEhZi-ƺxL-z7c xQQi.`UktuGqʳ ݫ4jm:X:vslQHH<@ʁK$JE)-E `{ MVNaBQ5`cZDb(GRX3EB?^qbj96HNLա<)]ޕ\5b01ql "ʑx'& 6Fe.ЏWeDGuу^Id-JVNLBqKrȄuے;`.dq;3q-9`TXnws7p(o Bw?r܌ȅc'/rjiwuLlFlz ɱ1t}rqKȉ[J梗fQ`"5#U&AdY6y} aiYu"KkU}3 ķfm"2|狻:͌GrGELb.'K:P;C|v9jatJۊ)ӫoF^vo [RFYQXQ FDZ@yoYx8 Z*k4݆0kLMW/hq`뢇d 1K5= ӢXwXSHt"/0vn w!~s'E7)@)w!J ^H Z$ }֒[RJ!Ew7(#ȉpLG%F!~'tb؃zR龦U8 nFzR1ݠ@ct/‰pnH`ZBʁ+ϣ T%Ǎw`RD;GUY`!r{f)^ϗ3w`HYXJy6p薁ᾼT)݄Ӣ[F$PYAh|w xx֋\yM#*2JY㮋Xn֦ S˳#qFbZ)w`ڞ)bjmXghlo(|-0( zrʠ4Cހ%_  +eXji܁m,46Z-YAdC n>p\:S/<WYP2 8%dWpZ8.J|x-:V5݌R6Ŋ70=(x/^\.>l1PLjK[Du1#r8RJ"lZxSX!CDGKiL;AN7 R^TzLq7 |!KW'"'x63aWk4B\? )χ(a?z-.ENHyV.N I4i"m~ؐtҁ(O"y;)Xb#vN-mcVu,_Nj rr:hܼYӪZA52Cɜg erj 4TY SǶ$+\ϒ>Y+P[sɡ] Ia8MUK[ )Ͱ{G-H2haC]yخ6OTnɐ|yI- p]ڂ20nUhe}@Ǒm*5Ӥ W6&Qs2ջ̩-6w˭)^Xsn <TOw 1Ӯx@IsrS)Hu9 zi9dE*kw@x>j"yth71\ʐrb\mA(h}QXf;^MEw@">j<8 ]fUvQ֕UdQnCjݴ[{y+nʣx ~-ħ!ep;ZYT}Skܯ8 $C$[x7}; \Og{+Ex"]0F5YWjCP˻ISȝܼ"[+>|tTˋ{@ 猰^|S+=vOBw+v $wZ]<}@A ^J~O;vJ~]Uo(PU: BCA@9*Oa3ا.|Ir0~R|ZR>^Uu *s"j"&GumB_~!o߾h-Z@̩f(BW+l =/1O3_5asϩSZxM| l(|X>_2q+W 7؁U2< 0>/tdk?>o7OF߿?u-MͶ N'g_']ߎǷuտr}`jÙ hEA9r~-.\_̸c|HV dx*븓wp7?n=<=_uĉϑ 3Ff>~nq‚0s$4zw ֪oyy9*w<Ǔp6&կ̏wލVVVI3H埖n>vҥlx Ǐ+;F#gϞŋdx8 ?߾} G!|qq1YȿV)a` ɓUG^UZҖ>2;;_{yUB nhh˗7o$%3u<.Ioo/(-_z5011AJfO/?|pjh'ES;w[8bHٌnܸ*BѣGQǏ@Mckʝ;w^ c3gʹ9b<PY1qٳg@%ϣ+ׯ_'uF,--:C@&FyG߄:1Y endstream endobj 6 0 obj 53324 endobj 7 0 obj <> stream xxE'HQDl *vJQA@AA({Bݝٻi{%۹ܖ;;;GDgS0Nr -uwW@u>T*Ow?_r{(qN&8L]|$cWyOɼӇjOy('ǴM %7fʶ0žfKnһGK/}ۻT҂V:?'츗N'EndW>wٿNŰYZy-ڤiљvPp]l>Ş5.){Ob?jgd.,煅 5'v`_׻Q)b_Eڋv7}{/Ғ?لT`oc 9U`vHN;'g\qF㰱#ߑͪ6w!YZ77 o :eÑ8F.܋SZ73 p^uiN[hC̚_Tw|QӂȊ*=1I[Y<|$+r[Swz\ bg^e_j[FyI莛V_xB}xW|9|^3xR2#N/;{fSPX} QzɶSUvK6&Fz|8\KeA4ci9p|mK^<,O|#kt?>WҍYuA~"80UYf7ko+|}(c,:t'))D$_(n۲_-I0_b ѝP؊=t?wH<[@;XmbwW!b/Q' Kq;-Xo9% T W//lRI NAUTQحľjPϊWl`eb;m<(>~ (Ni'IZ.B}+;w圹eXNg7.3kb;nZi_ĞU_׵ '58~ns+G6>k֣W<ud[=w/ jo A3Հt/S+Lv{un"lx[mf06VM! 2ᎹfJ7}x*e.W2N~[|{l~oL]L߽9p׈`Q:]wgfzŴݺ4nRwE_/bN2C}fb])PJvr{>|2'WV߬BMt/qq #}L"s=Lzse܉1.iy9GK[7p=p3yjur'y~de3C pvB}b]Er~?|-0xҪY:'e7l}Q.Wy?:`+\0$K}LYLMz#`\ܹTǕ+]p[M A+A}ϛa1;H[=qn];Fk;,*(:p#_~gd%۾L6V=rrG{ΰ"b]X|g|DrK@0u=;&]ǂz"Zާq3~)gp~ro}G we)JdBIK_ oIV6!r%M~'z}:z%{I9U|L(.ICusÿC [rM N_w;t!b7Vku3yy{Rk]zE_ uIL)S fj@׺*hϟ܆=RP|Ad'uj>278y Y92ɸ!6$Ul%cM'/,pq[;g&[~TC'+#yW%o;x q,=9qĩW᜞Th^M+~Y !h ?uGuA=LCc5)Fzy/_KEJ`rM'{rV|: csJjv to˝cqơpVC]y⊫Ř~Bnx*_ŒB3[?0-y`qQ*/u0]mo|6ێMq.x/y PGp^OxC쥙nXrĎeY%ܓW1U94) jXiLG,OEDZZ9Xs5~4;{xMw8@'zq~0k1,{oQyvt`y76|nzFb'OaLF~ju7KB:sV */b?[ԸЭ!ο+pTG'r(;p[`'MiU\4n 9#yn5l\4)b/v!سq;?2p&c"Gh~]MLq[3n`l\?=*pk44T^Z (M #2 ƍ 6kbt+xz:}0$mcr=}0kvwb][nm>8sd| 9 سȀ7cg5lm3I{lIȍfeqI~waGA& G7وxi {n>Gq~*m= 9sqYUӅ̝lv%/3;TG&#p~{&ӣ؅jWp|g=>D&U=OEx:z^ ~ft)L.-v)=r[pti dbwdރJ=E?L\I>BD._gȍٍ:•/|QQ@Z6욍"b!RYxf@̓7F_჈lo r6 /jPx#5 zwՁeH؅p~> ]iѕ &vkۇ&YY0nWa2NY.ȃ+g$Α F띭ފ9ލtꮗ@_\ EF}{l*ho\45!҅s+*.|,loyTfGIoľOeɈ z$b//NӉ[P&W"?"Zd-*C [I6I Iw:O&v2Ƿ4b#%wx)%d3mJ hOwK($";fcg%0d7`(d`i1gŢ-ވݜXڋdIXd2%b'=od{qbP]-6r`ߤdb'~O"q#3 IZbbE<+f#Rh;- >+S$.I!/?b']UWK68p.7b'1QY/>L.K81$bg8pSq:N65hfaЈ];eJZK#:? !;iζ*G$eN l"N&] {|Li\ҩ{ddDb6ȇؗ,㲭N#y[/@?"'YcWd//zKis@%2B6OLi&_u$EH bhfG=pMN~ eHe]jb_1zB${'͜KD~{#]9#@8a}KʓIyI i&||Ț'vsm 6'LHb' 4BW6sڏ ^G[ x$kHE9j~$7d#ՠv+͝\E{؇yQwq$K܋OېȾX.bĠ#ޑIt(vӗl4Y^kW+s5jh#_pkez.r,e.j>^oԔxΏd#N'&kZ3{?/8M Iو/b7Xt`}܈NN5^\37I=?-v8qO<;%b'Sp7 #Lb)d7,g7ob?H>R1dh@<@ٕ;wbKpb7*\$)*}P v湧]Ƶ܈R)t(vjKp=W=/*sfV*/ 9j叜.ѕ[?'Uqch5%vg|.0=CUwCWkyaV^g2E.\ Bpt(v2^"A|-v?1G[ M ]>QL 7b'sw}<%0!$dq69/{` ɟF#;dۊ{/vӏ2[\0m aKOI()D[Tͩ?y.bO#&P}8b7sx'.;"J #F`nil'd;#~7BcWGʷmF<;Na5$wWH`5ZR',#btE=7t,n˖09HO GC"$cif6P& -Mu.Uٌ5aL~uZdHODll$~v{'y˘ibMd?TKO 0W2Rםah~.IfIMW2ndaq"/HXfLd[f]3C%H8J}حǤ.⏜' Qaba|28 BP3#L2: ;/)z|Y!نr&d䦹_~LūD5}"'s`dh944va\i\bz;\$A$=t }{|t7d ./mmyHْg I,5dcX2אT.*n}Ґ0ORY)g'4`%Bi\g1蘐.xqgz |^dqҮzM"jPYnN`hI i>l"!=t~=Rb@;p I+钍/qq2N#5]!c+v;iY"Lj-l!b9o0sK8vNe]\2V,i ÂQdoF!ْ6:Ŋ8)*Ll,w⏭ҒЫrį7K 0Ɋ8F_"^r0."yH$Dg" t"%z' <휵sDOG$y4e.DËWs)gjُ[w$eF7`W:L!FUfzVG %fɷ 3*6W&vԺN9Ho_&ëStNYր.ux-3_G-&Ь[re"Ɠ%4 mUcf^w"_fopmHB,sSݩf8y* 'Cko&W9-1{Tϋ.9HrxHSFE{ ,#bs c^$^yƤ3E&Rǭ0"ۙf v]#֞EY?Tеy!M6IHY*~i`m8Npb3iKDQψm#?; ѥQ 3I\/埶Oly6`H>ZeB]3#NvWa֩?La 7v,T;*gthVy'M&0cK)UҸ;:eUqˋL4eNl%ʾבMԙ>;&)d>hsU: !ڔ/؎\Vٙ:$r#A}>K 1E Ȳ/8hFɘ,q0/gc>I: <~j3"6{缦|st Aw(t|Fʼn^;//'즷 bxlWr6tQ ZuM~62 l}JorCUC OKwߠ5K>܂1JƂhoI!FfsoY:mNj窐__#rxbďfzɷ%3)Rd5γ;WcgH xq,K|g|z#]wUߕ) gb9E]qky12>D18Ne􅳑;LZ8NSZYO.c/AxgPP268{{2GZH~:{[.?y(?˪q7M>ӢC?nwfxxڃVP2 @N_w$خCKew;u;B95[M_y FC^w&x f ~춎mrVZ,/lqo=vKLJ_h܉]w}lo(`wuvݭ7A v`X$؁7!%.ر >iX=tcb6- @(ԷWu: ]TRV F{˫b)!j5_8v%"8|:އ9$r~|#_*%!rvƽ6O*Loz1p厃Wz. @6 7[WPw/pljV} [Zh/w/Mf#¨ꓐǸm^UB-55q=+ԪMox&کa)ҹo͏v$2og/#t jH, k3/V"`E{N-!^)ݞñ?zIgͰtP迮q#\\BN~"hzͮ@ӧbw|<~O >gt㩔ȮbPk*&іՎXc0ƿ}T`;M)^p;BSTSqRbT^O'ކ~ȱ> {{OEw; \ .vhm1?/(ߵ=IX2~ڴ{=5zi?\bGK<,bw|!WGgh)d%vcish)MJݗLsX쎛]m>YzPI4Og;;Mղ}aø;m']Y컍GtJ' CITmZ/8nvW8W`=c'sJ' 6}5ot#v?2-W,v: /ĞOyaV{<3#iObB@8m!u;.-'w{iq &yI5,慊KiچR 6duY0&ݕ_V݉}:BؒKs=em7#=1Y1]+>=@Mq%Sa2܉sŎK[]CNYIzyAo6zndk\O:oJ7ߡmȋ&>7du3s.Ǚ?E|?j1&/ @Ήs1{w;&Ք?[)%!ņ%FoM\x~F1$,UtjHOi%…~I.b>Ot@\iFÌ"g^oTqAXr$oEVsx-21g*Y ĊsT_ȧto8)}q_Ecoq>G"gvw N^mWyQ|OgG\6q+M5F.yB BJ/(QK%~".}![{6i}-$Խl8B*/4CxР,;s1uYyr~@Q&KDE56naWiw=yB MzQ9]L~ɀ:-%%|L ږbH nbӫtO&W엛SJ݈y gɟ.;KMMuJue\>vw@mq#sq:Ysb ٓWEFOOI7g?(>) &sf5݄ic ϩ8EW>}ίɑ,:W';gv%dro^ K(8z>?@G! _N 4w} _hM酒8  M9# ^5|З, b_dҟ?yt)2R0C8!{u>} ʧє$%#1Z=x+x2ZA _!~T3X`h93;\xԫth~%g6qyQXXd4moDpv'VZqkQuɔFO2)kqfԜx-d0n?U@﷫a6-NGYsV4s2#*򟍷%x@¹(7$B?7͞Il1Y{Z"*,n! &l^.p| b$F -2 ؝2 _e>:M;3HX{Nbcn.<_l ΁ױM$z`ǪDoeKz\ddVuֈ<<- FJ4; ^)$ >ެ~"]yirggvД19EN:Qޓ潪wt32\ lכў&:).07'y$K![?ޅd\M x'HjdlQNxO0b7f%%3y-!]d_eUDvT\6CB\BIвoxM~oܓy^c5nڗ $7s,k2+c2#\$r`$sNoIn 7bAˢIWOÙ_>&~\W5;i6rCx־ҡ7~p[\HK3ZpIH/w%> :})Y 'OHΛ$א\7l!w %cx227fcD[i`OWhmEማZO>k@&_,|<}թ|+B'x{-ԅb?$;x[w,8!_a-;';,=${Z=NejfKfpҨ|/M+ֵNOKau}lHYp177ФM7N{H 59{/ -`shx7AXK֟c?rg5T dd^\dZ;h_ }^(W|%&3VJ6\ٕpg~q2>[$xRf^wӍx;9pJU.v!o4o]+ɊJ܋ Z5C- d潿ZȖag#f1%a hە_sj["Ğ(qd#nNgw>(`ɐ|Fi5|wIiDdJlq P0VoHZAWgwhT,Q,~ѕ^.Ǟ|ydf^pwb7ŧ6vq# q6[%'̋5\%=fv_xYQ7;/.+go37.V,vK ߖR$#2+|vsW>p9fW0ZTt#/m4\R(=ߠ s> i9Ra~k9 wpH5ulN2bu'݀?+=9#^cb .b%?P6C+x9}d{MX*3f&khz$Ϩ( {:yX{/G'.ג>ŸU6b7cUզ{922ean>-)B D\KսԺF=U{?HGhgY!o}S-s-N-nAdƗV#; 93IJgIu n kWXzoeY]tYƮdB~qM`,i%v2kM zs8qK#!w=[d k#pz#/VzG@R-2oڲ >? *4p' 8Sz80`_BOIi!g 뀔b d4B$l92j;-[( BbQs;IzR%Q/bd8c{Kt_2|D|j]kgmIDd?0D1Sj4-!t~| c["W̹MH,&/W͕}+~hܘ-N麗m`E?o;{x3@Į'+kKj]n w>j[G:#gqxNki~v]RKN%0rBǢ1SjٕI-ĞGu\6lY("ynV2$I6a 3R˩eS]/Vq+vLP)֜绂b'gÿgfHnm 2b_ X_"ro#z< MN+BaQ2δVV[ $OHt.#|tUةV^V݋b_´JK|:ؗvMB#vsPz4_ wTX=U@.v+ĞM‘Q~z}-l%b7ĀFE5مwxwMdnb__S܋SekXu6YhVaSn9Ou5 壶ōTa Q2sZe~4SVqݷ/r2%٩}[OY20;'Cz[I~BBrë$G'hcͤ'TH}CJ%kWu_*%pG|<ϛ^fNxKz#$Nu{|OݎStxysMRs93x~&i3L9a0f#;:_h;…6^(~h<ؖP=|˜P|]FB$,{60K٣Uob#Z4Yͷ禝rb㯟YQ9ՓJ[׬-'o+v}iHyDطSޑ 4!=E$jGcט)TUBK>/q.f?ozhg+ x##hf^i|NzS쎟d9JGɯkJ% n]')Ws~cUCIe;YEk;vBļ(n~܃kTV1JY&#}OwVk.;2G~rl&YObw8~mėh͙bwNU%-9܉ ]:])0{6'IwN8w7sGI7V~3@\# ?{uʃek5I3-4 @Lo9oTH) X`XQ?WmuJrӌ|ۏ+Jq• +u~> mk*ɢ9ͺC\~#lqFc6o ,ɽ[ds01U4*u oj9-WS@~K8PMs}k]vѝC1c3@8kޚ"3bݶz Z>(%\} D/|{!yV~949-u[~Cx?{UC;V卯0/l(­նUw1%XfR4`9C,״Gգ-kg^H#2{P3u)c CrZi)(O0*Z ܢ5%G9T;JwU*Koϩp+ T ptB,ac[P(Q;/"Q4_bwgky3^f@d*O)P$ tl/"OlԺF !*m@9yIMW(}n@k}ymֺFΙk} /ή]4~#7`xjiV?zZ ;B+lyfMhPhطNW@%^.J*k_͝=RQ(v:*- ?U5r PK@`ZG(evef<>ֺF\1T`.BQ{vB7#,m3ΖGZM/δƪY,rbz"ss/[=>GV*yjTίn5 CUeߪ7Ǔu[!z8tJ9KV7O%qڝ6V#]Tk[BO~}YhP%vU [JYjc=@K2! `ؗf#Sh$rO04|JP-؂j;suyt]/0D"!ԄGZ JPAy7YG(n+Wj[kӿL=gk@б%ʨZ ~L#z]V,iҗUO4^䗩5Z ' w+;d*m2a2֨ @Shzre*9O:VR딉g$jU|ZXAI€Dβ>@yzTHQպ Rm*N_u϶^@AYlO*}bM/¾t;BŏߨT0x[wߖ@K]oj6+yjA5d1w| +*@Pw*OžT:鹣@ ZZ`A v l%W2j!D0wa!%hB(/T RhU_5y bԜuE1ߊ8g@@nZDM\P*@ؓ]`j,f36-D yzg8i\#ӊl5 RD3m&m?CO_do2B([#3.Dž\?O!E%ӏ[G[msBiW*jX`o̪Zf4B@(wM>~Nufs" ->{;'jsp!kr_e0|m#T;Pc r;s7nC*o!զg/7i>S!y4+zӕm4!TMj+psP /ͬ%q|VcsVˆW]kU[8@9~uA ?cU7PvUrm}aʞd p͒Vf H)xw/r}8kvԅJߠڨ+ܸ1rVJRU[4`Mq7/x]E3J31 ^>O*uZ[4F<¦g1H-* bNk)FB)fӞ֒Ji#3UXm¯ lDR'9mQ ļ鲌ܸ"Lm 2L$VaMw$樶H `D6. ]XE"5g:a4:vUmc@0HI"vqWABi@D WwxgWm@OBoҧ4È w& =>G& HBe6 ~mܩG2T$ ^n羗!,Rm@'b6@qBJ/1s-Zn?Ԙ{U$Hr=N՘s_`n<@Sk{˷/s֍8@\%O*s2{mް_JңM3{>Zϭ"<3B C U~~%-) mT#h<}EPP;:I1<|lC+_B*4V=7 \pO9s[)лTFMՆl\+Z'6`73^^Rm=ŚߵQOZѪn'[evc)6=~:˜fQ2o6<@ŦVc_C&"ҕ\Ȥ!6.Y}u)h+@H,Foj.@shx[급`Ncc}jRx"` =w"c˾Ui}LD%@豧(jM5@5ɟ/}S7iCِ'=B8զl?ѼK |\+MU $Xr+/6?STU[$Si{E.PZJmWmc@Phdc){;"& rl TBAD팩M]s a *Frh-7;`'&BO)N@X=1զZq@psBc(Ն#7f3YVK M[JLTmV@P.q.yocvs%s۪6* Xi5߇VBιU[ľ!^Wl4W oR/Wj7Ur9f!:71e&3I-RnO@j[:Y{|`ⳛdՖ?/'O>zz zF&ڎ@=GX5ı bGڈ!K1[F|^v%VmC@PΘ7|WTFQ\tgW5a[rC'-T+!& xTETj<~q#%߁VՖ%K>~]3 .rbST 8[֘Oo`J'(.jФϜeݡg-I!?P <Ď]z!T{pÙr;J`̏u}uT_{pÇ-JtoX3Ά0ۨݪqJ}'41 W^9J}T^>BAj3K6 ( kVG빼 =.J=20 OasT$¾sE$rT[\`m"ė~M[?嬯[8Z(jUAL>'ELf@xIlzjsšB#Ti>B'fT]?p6~/`/#OjKŸ!}bG&J]Hf0I Aih1xJA{٬s+rN@YH MI2خUU[9ľÆ<bGRѻt9(ak첳\iеTz 4[7ʌPlAV݃\=q[y=qWjH}6Q}$U.:1 ^)?Q,hHj嬲b"/fR}Ӂ%o:cg}˪o9X"۞L]?ЈE"oF(e;ZL_W}H'NuI= LN+ҫbTj<҅UPK #UTgu1^D m,+AAXA`Yh3Nάo08)kG07?MS}fGA'7ĩPz&k+y rE%h;FZ BSTW)?pscjF\JnW}[@=G9-eMS+~zW ׬nle6W.TTA%fl7Xz mM;JlKP}?SX=B+L *3c~Ѫ3C'1߬vRߨ;W/l\ BS\cU/QahG䘋sQ}gTS玴Ug շlts#v]H x<oaK -]UposܰBe?8 JjuӜj _*:E]iGj{,j-b0G4Wr;灓FZN 9qNU} U)' aêBo.[l@|MZn2]ӻ}C'ϖW}6SeBP ˣQ,USuXV Ff(ߡTW>mE\yN']8v]UW=Ld0VZkBkֻ|Bu|$R⼄Q. T:g.깵[>o%|J5tJc1b37V]qlt[#"!EQ+~7#9wvBKT6$c1MOcm,BnE= 9"ٕ^ x IŽ_s+Mv﹒5W3װmyh>dUW2 r컣!ĴԌU1 ͷH23I3dV]4~D*^Q]L4)dpuЈ8.:UT[e!J^j hʹb}gNQ~7VqBȺ3B1\1Vy#jЫTV}u I뙜v.hŹuAͷ\R]NNM=wbU'//2۫jAn6 wUC."`ϻTzc:Oa b\i z`EME%iO)M2Xu%@hPe+Mz(`rbWrK*P.>۫_X]J4W]:TU;忴wkB⒏n6؞ (?WZnU-@'sZ99>ͪj>xN!{ )3_̡v* n@$ZIFX/*^-{s,{mTW(g{ܜnvGMʟs%?R]aw\XC!n:*!D/Quu@Sb:/$-;%m>T-}> #!Z+j )6jFؓ |Ug-NQɼk IksG5I[Xq>U 7KˍzfG;<5w_pD.:Fvjdv컨 jkŠzn'#7U6*M E‹Of3cmqZ_Tuԙ\ܬN Skfy8ulf_T y,b:%%`ѫc ԩSQ42nfC ;.m4~de0܊&|lg^]`9.M󚅦yle0mވM4w3 3k2&kk<5q~f5f0܁(..{؇7XcT`TJ ,@**"6{XL 4>*XogZK`J "n2R86xi/6a"58r4Uhw} x%Y_(^9wжo˝EvV-T@˯f_sQBxZTξL~a[5.`OjuyIJ8-E}̾ VkFnBO1$aM%qi;?/=a,?Q *=|M_ f_{Hj%RxC%huo-73x. w .>}70MQD5"60[ #̾ ! $/of6/QwiK rR6725Dc`0\LUjq%q 5k_$f`0\au 79:`.>[k=wp!⾟X0Lr&r=fgM`t'Qz3ɟ; ̾# k_4<5`]xנ& ϥ;+ .Q3jZkZWn̜fUżf+7^ija0K?BhWpQ:_C;9 ).눥1s?.4E[00NgUș^"-'ifb0DolRefٷp i1N\Ɠn5yq^y,;4TyizQ:Qr[NvNkVɔ~.;}}9 OҦ;}`٪.ϏK|dƸٷ8=9hWB˚DWī3_cɷ0%/Zx_uE̾e FLR۳O>113MI*CtAlx{|20_Z'kvHk5V2)Rzl7c7H/Bghó̾ CޣJPH Cv7p@TQ%/Fţ ڈ7 ;*Hx6pZfTCzm20xe5aDВ^dC~޹&fYC"M]6A**Ce% --su`woӶSu̾ BnUrln4>zjS+W$t`mZ_nX,ȵ7 E ˍ+Y[va%. Ewb{ ."R33ߵ7o{BN_4>@plp6ը _53wBOY ^ϮrnEe0U#ƕr4\ֺܵمU@3N,m+ uY]>ރ!tMcKAҪ:ϛ]B^tٺS3UMdY h˳.# 3s 5CW=TPK oNf8`ޕ5C.( ϧ?UE7Kr[iG]RNjz:bk>[dgM1h|vbe +ӌY@z?QdP5\݆5(6%dvax,eUn`qf\A4C%x`d*1܃xg30<5%FeF zņၔyjB fSX']re;U63I"h˅fUzC&)-xJnUo-yZ٥Iz.>[-s ,Œ4Swf`٢.;OJdg=nɝvն3ivbx C,*tb-7zexD *Anܢf#'QS}}˰_4@41ܟ.WF&xܷ9oaf%S)ŕmxm.L fĽp7~f{?]nTaPȨ ޢcngvb-頋~_&VxڶhMe.S 7e5UPj5\=Y˯6LcovcKNBA$O~c5.} czjBc>_.~ c)0_M[N21p~WDBq'.qLŏa,%7s\T*s !^{x٥a0=hD6 2 &.WkM0\%a B{{zf>d|cK™$Yښ<)0? -4^lhvck1I< ;T yz BL)v 38^qvfB131nrۙg42 Ea?lor0Ɨ7Ll=S#fD9a&ɍop]oivQd6D 0K#uX}TBF`[Ir;h7ۘ]".Ѽf4<5L2\C>" s0=F]* Mu| ~(ax%UB5R^RMe+yj-,lgȋ*>&L;+mq!`dv6\Ö ~ rS ee. n\JDZn​D ݈c X'MkZSKíD2p^>/w@oXHXlibj +;<} ݫ:daW-&{ӏI {-%.A/X0D1ܛ.LK};c fVar:+g`ό2%apX^ ,etedX~urr ;?NWƎ̳3n磪˔kMVDFv }Od(pwGFsD;9/d ;S@r]7\2[ Xvjn[(H) K2(vȰ b'I` q>sܙʅq2d#D)Ğ/v4FޜH3h4|1&vgQ PDNX࣒z5(؝AFXOTiu?# 1 2*M(?4HT|MZfJ5EJRb3Ğ&2*v JabqffFkRb7qeȾæn*(/7hҿvL9`vms>15?^9.5>z~&NÄ1n| GDόعkocik@3K4 8Q3`rٖ(5Gf~!jW3vE\azs8<C}mدt!UU|Ns~G"W5nЌևBWZ;ϙ">h$'j92EG]\n"ž[^P(=ϫC5~wyYq1sؗMc蒂ح!'UlEC"R]E }_~4iVȜ hKcw~nő6xbU&|3:zG>[vv\|{h>u @~fl셦9'qw&(tFI<';A6)k uQXٿkM#/ `9%q9cl\mPf~Vc=]HO~s8{x}|wn&}0dƊ$=P(|y${=&/(|IAIXG o`YW짃ꋷ6y6_{<W=Ot4J=APoWUp>[QrK/ kU\",8RE=pmZх`O[z.X0e@%>dծk_qjEZc:OȠiUޜDS=-%IJujJ2֛lv2|*$S+g]N5j'GoU?R  ?#zwWk_K~lTE uՊZp) !ۈ}d,J:C] rwCD0!TFtaFnX~~lq+_0ZWh7ٱ< pW")b!f;{OPS X~dy7Ļ e|hW+@).F!kЏwH8|,I.I'71NIwC!2Hk^Yad8ԥ߱Y{3$(mZpg!o&șMVo xwG%E[SӖWM:?F6\97<F| bG!6ŋdz1 u2gMS~*/.˞}kesltV.Xa=9i%;G3]&ӹK}Ll5[YPHϮ]p6^:H[|j_l>:@ ';MȀ VӔ{pex uo''n:#k?Rf 8ow gsan~'_x`H$OMb{%ᵄ\2&30;iӯ}V2Νru3F3_2h1[lYx% )6(`5NMFėsE=a0\H >l^FD]A5-0 SX\^a$O顉u&boaZ|vX\3aFo}e0츉K]fk[7a1vgZkT1#u^i8X isUC/~0C'(adRxjSO0n8o+O}FO6[,N VnBG~\=W#3#ʒ™_8&lx4'2 N:ܦt$.K܏bUr{t]t H/< 8Ny{##ǁľqדs.z ŧ-Y",%@[Ϣp a5jѐ:夜Ccr>]%Ha:;yjc=ɢTXǻD&>쪎̉pkɜN~ BsF%yrpʥG5jpY'=SټxbgSթGk]m, )u?ŞV,y4q0U9`OZ]NyLuĪvKK^nbv<8>Av3ٺjeUno\x~;5¼m W.fo#LYuLصJ5bĞmw,xjaS{C".]<.zK?9gH?OV~FJ*܃?=>GRHBɎ9${%ɦoUtk-%IWU}G6RO'O1l\Ϡ'OԎn.|`>~fEKk]9¯MS04tZcz< _tO(KIs@q%Zʢj?@ʱ8(IMB4T;f]{L%Rߕ .6"Q<{^HS,{ƋI&\g]Zil vb&\OSܱ/dbF3V;nzPDzfi3:*ǒ,H^<  x+%j7}>Kt=|?uNwH @_CV56їi4R E9ߓsHx=ya%S~ytbM-(]Y|K],=p;&_5Ac$ra*$Ub_Gu]H_xu*nbľ|TM}w,]!?ImZG/%~;A_싈TPK,{?>M L8{kٔ jhp@Yj(v7[~e_XLGP%9_{IP{W]E)}0PJp ߅4B6F?>Dm_l}ͷ*=A_]`\C4{9~t>q:BІd WUITca0|x~rz8?6gJC1*);(`'z q Ћر~S&BW?(z arr(vlۢTc@_XoQ9zD@.ݾe;pGR{ҟHc|J3SǓ4Rt zWsޤs5G_ߦ1GcBou bǩiIX&.ר :AVϫ,+([p B:9+v|IPH [K#8A"qSDbRjwDJQM6jб؏J)+yePPN5.͏ߵѠGOBPGChwi;_QK8ǡؿu=OBR`I/nE&ݚAs /!6Jg}L%Vy  @;M[(sBzL$*7~Iw9JH,@!Wa)Њ{ߕv9C2U˝A/-C\Jof)}N+FMyy;@MsjWVj~/X-/ (H} 5q"?'j%ᅡ.)}4'OTZj-gOZ+{*\^Ù&恜4$ Qz٤K|Ydb? mE8~v9rXG2|FGaBTGa%_>n Nu7leqқEyr (ЙW5ڴMq پjyRn  ycf>/:[9 |7~E([cvDUH5 OHi \mp(DnaʱT>Ut ֮6Qt i"-FFB zMYm^x\m[$KGQH5E_@@^.=w'aZkl_HXK] NZo][AAH=ߞ[[H} do4V}d)9z@&z/C9:]PYWmD/p\v@t_i J75?`r˛^~US>dϵY#P%nw+~E:$6=HFtԻc5=y ;Dޅ~z$lz3$P[8ek1B_!/Nۻڿnn( 'm<gohÿv޷㨮  ئoZw^{I߲PCD_vpضhvH'| 5n_V W_= ?D뼛]4YV_ ^[Dv7pw=Em-;S` Y:@A ^zzjL =;s4Ywe7/d1Xd8}@\j `& 0[{&A<YIR< ](@,uz~{x+ D^J{MqwZSDJ^ > tmO/\}:oן|0KVe06dIdvlP` ͎g2[.bW&F_`x/mٲt te,h2MgiVuU u=TtY 56/-.ojFn2[Ng61?Nʹ3 Yp ~ᤁu?*ˁgD}i;5,U&ϛ .$Z9mʪ~xÑhqJ@ UEо ?XKO-vE t=SDQϱ:n[9b BOh1F츐uHo(PP8=l;1bSe1McuS?)> N|abOƈ{ڋyUaSu S)"Li vkh;Sg$( 8;{x2xui#~^vGm~jRN?mp 4A7QFQA׸C+ǾQkG689#yFk(~qV8[dwYBcmQSŚY&P?/Xt^ 2B?eb }6t>R0|AOUWJw 'Lz[6T } P8>>44LH 'Nܡxt uCh= igRIjL/o/|8@!QM0~o*h*lɋGª?й( x.hgn c!f…ôb p5b)Კ`VU>!H+vQA`S?ųus.~/+:FǷ6~!9~%-#vE{OMMh)._'gD E~[ôI~d,ѓJ䘾5ƍ%Cɖlن0fJٖC6'! >m1h5;cODNjm&l~DyO@b2oȟ D":f[ o${oA*|O%xlM&x4.xIA)[.) Xl[qWS&#Tn- Hon?@޼-ɫlgO՜vޖG-B\H:.9k::9䘅G- r쫔AҊA?솴?B&䓲>Ob_8zO()ҧOYD=~E;yk5(}ieŲ6H^D`}ڏ,/ݯĴ^qE$s(mAk3'EwPC!f6H$'o 9Y9$ "u/Qu{eHTX۔=R׈IϐW]U<%/P+}H*sōAeoXE'?Xw( &Jۜ$żʸ4Jo(vܼ1V`giR@Jk~+I+άdbo߿#f6ӟf%sc"f /=tJ H)KNbR*S=JJ%T%vW;R^7`Q|5a_GjrN(ehjcRiu5%9ާ:i<"b޵O*xE4.EF_P,H PKHl O< ͥ*vrIw3Ú (cRFȠkgC^cjR)%'c2Y{XOmB[Ik>Cj:W;(Y|Su+'EW'_1  JM>Ǥ᧼{mO~J?$hĎޥʣ uU#IF >T9\3;TjR7KK31Br-P~r+ BZ z&(C%JWGޒ(wOl!}P =g":pP`7 ;-MBFR>OUgAZE+t7IM쵤e{O_I:X[(:Թ(t%m jjEHU3=Բa2lP0X{ޮN B No/$KRo*' rh"h- WP^C/)m/]oR5Y%,ZHrK8=/D,Z&y.\NGKu@? 544ֹR=(;6٪}C yvc=< Bc3<ುbW@l5!skkUuUy,BmG+>EpQ_t.0Zp y~.%E]'ފ:?9YM[{|wPQ*bfqX}z{a91?@Ik;fX948'w9vҐ+4 Wޠjb¨F쏟'V<&;ƌ \2;X>.S tv1[]dIo=n(Έb-qգر}]*?ᒋqgj\m"U=AV"~:m}^ٜ;-@Rɑ=;vI=4pwjn$UQT$Mp[Pu,G yJ(N+ZHA;׎Z(f8n\[eu7ŁJ!PUouϩž.4}r lT{IX;h&Wc 9?=kȆypD3D}jn37:vY I$_Q9`j݈%l_c'@X@Ǎ_tP*]_=i&;hD݊Uv*Q6HH1ܐ8r&:b5%V_K| DDL=gEAP;&GϽ]nx aXMtgt- Y j ^TTbn'Փ A $e8tͻrg輻\=E2bUYAI.WQv '@=y?G v?*J3+;}#<8?kJIAlN<1xUwh>-_PuS-5'D &Nn?Lߋi7T=o f%p<)]"0W#)'}Ii ay`/GRȽp&D'grw[,٥.ՙ,y $z؉y9ɞBDX|Tǹ'$,=ZE@|(ZU"2H:zBU΃^>R\-vIS09@,Ƌg0_I[Gw:Pem\ 7tmXz|JyH7?ѷǽ@vb :vO %P0ly^7b~RɁb5(`&vbWqRwշ+z% `w,v.2Xh`C-ȃGY<$5CC-vl`s4xaرGdmh},& .&Ǻ&ZB:N~yo&zj#5T-=pg{87N*}P)?j Ob䋠jǣ |b{mUܙ9OR;*6dOHBu;VkJZV Ew흄gA^tW0[ww$VPq Op};,'}Lϑv [ Fmm*e:W)gKỏg?wXM]jSlw=NҤAF8TLK/iVKꑧLjݭ (e}>uo&q)1+ji"Ņ7Zo*XxP#N-v.);K~y Vjk@ۼ^Ѷ @) l&M;OVM@/ôrN +E{?8 й/-ʑK:XyA헧 JjhހC{Ϛe giv3/;CNw/ul'r:ߗvD8r}u__qwbEK= s]mIqTX`?uTkɘ!qOM~w5sOWz K~UB R`QėZv?1ot__R۬#~,&G)3Z*g}+ѡN ]tї:#fquڃ+r: go8FujNv;~ק6o=c黻]~GGQw@۳qS.+۷F9lLr諴|}MQ.V}r8؈V#cJp'1Z419pjM{r#7cփfF&K\c5d:eG0XÆJ$\KCA/z&trAqYqO]vM9bAչ-;{Z(!EvCZsr-uLd{C*/MX78OGZ4HiK0ܑ!E;6#+4ȝ SsuV|$nܯg6R b. 72S=sB> #FcLj;=C=a$ŞU<&{FHxQ󍏫/ZEK1( 8{&`b3qFZr.;zB5{`bW hK}ɏ&Ğ3Hz+e|繩@JlGb>oȈe'[Ǭݸuɽ?4:7]7l-ߘU)#v~tI+2gEk-q-ߩ/nk _Mb޼%i7&G,gEPlyX &*|6> vn?sU x?*,c褽NRUR[ܻ3'a4G+r|VDSEj\jaO+r:ߧm_HSBSM|Gb"U@1'@᎓G %`i T/AIUޤziKb/[)QѕRi~ܱPԊ=K{f\RռYj=? 1&v'0 \9 \ L+\!7ۖlOɕ:gCD#{/h8Ujrsѝ/fl6,*R| g:\DN\Fir*9ND8|*Ho~#u:o"Lr%_䑖D$O&5=Me$O&|>ߌqٟ'mDD/>*@:T,2.po/ygI !yڈ B\Trt|F;v> b .^,v)IIK]ËamLrI@+{Nzs긛3G].tb=IN)IfGkR2'S?9FC٠Gr[4;l9]^#$|zDeP L *tdJϠ2siw&s@!b-R e 6209 eI&v h޹ _ՇLz4s {/un_̷([%YD߃RjJf?!Hyg>}. ;|*1lPBؤ)h=9alr)iMO.cO2uɽs$Q@5MnS MK'W*BO%tH[&v\uq1adVg9nUv(N |A$w#v>] V9Ty.[#$ͮm ӲZ,ʏM ,eeLN""kK9[洞MsU="gPVs8R=̧B|*ǩ<4fRLt/0@eVDŔ EY[rV&Bo LNbI^3/gJ3} FM4Rv 3aSΞ SKURnӹYb0I1b'RQMaDI$b|_žZ$V hǏ '4!{Ƶ`FK<QjԧsRxJnEԣ3Wܪ15h jxW!%RkpCSUBHҾOžزPCC_\&Ps~FbH3 bGw4jqLm(FE>N+zBONhl>JzNz yNBeBZ;9*vt:&v:6%O ɘXwG| i;6x08=ChJMR!/!k6]$?YHW>؇Až|tb[f&vg],ZFސj̲k3TUH6'A7:I`FR ؀>FjA2U;GZ %!b(_ Ķ?{,I.u9P&vrCrٙgHփ/":Us.svN6|Tl*zeBD٭}:%t38ueЯP^Ё.`dg/8y@UٱEކK!ՎeFQsYY\q}zЀsQBց$BP= |&*'T.@]9s"7 Pׂ"-簣@FTn >X?Tf\ZBy"GiƟSTf&#e0qsrKJ>p0(La,a@#N&SԾ-Uv H[;4 %CkEz Jϡ$SZ+b/U>Xc<e':/cщg e^MךCY[a3N9Gb OZ;r4zy|Fz1MدuE鵿Ud#?yJ|OEcǚK8m'Yo;|ޔ)/bz!@ 1^lOzK8Q;buZo@sJ!aXXVZV+i$L0oy8@TQ}C~%޳V+Nrio[I :|1>P}(faNG{:;H>䔟=Yy5<2p;7|S%pJ~8#Ayق!6}9(MXtxfrp-]eS7I `F|KuBr!IWiWN!_%;ɣyecb8p}m*w8]Z-w壜YT>jsIBDi'Eo(%޴U>q>m1 ft-ʓ9"#%~.H7e2|"g۫|bΎb"G 8>]+4ׯxޥ^Ԣ8(|i'J5V/H{OUO * unpvqc8XoMP|U1g$_gyOyE'2k]Z[#v}kQ$ݹiwfn A!#C$t}%RS%_/5צH#[!_cToOYTȚ$n9ti ҺU0%ӕb5n繄p8gF*2pˆ!OR+(QLYNN9ʶ myu^גּ<w waڣ,͈C>[qպ9gY8"@ws@M|uES{1PF _^3LO4TщÝ0N} 7c :[Z7HA5/8 Ý_Yo^`W`0BNvC& 09Cmլ)h=%ȼ3e04)h=}A 0RH b_qG6qpCoBSzS 'p(O^^-`x<ױckJtJCcnc Ϝ ox uyl+}Am, $M]=Jh$ qIz;g0aZ5 + nfp 4k_zb0h\ϒCR 70 _zCz/ȟefp Oq4_a mί,/ϙ}. ÅZ||O`zڛ9:~wς`wbZ uaD endstream endobj 8 0 obj 49742 endobj 4 0 obj <> stream x ,Uy{}ܹs4qMhиED\#[Q܈ "* \ץN:uwΩ~}$UGuW@):M01f6N*,1ߑ;XZ#")IrLO}VIAHߎџmVc\"[Tm d8UD 6+˱tbޔ|{xB<7@.NG%,A-҆Ż2I<="IrgkO ~Zc;(韭HVcH ҃$}dL$QX=y0|" y'#M4P wK, eXL[Ї,w;ҰDfU({l461e3AV`.>\riY$7waLUq\M;0=d`>cIUNRDpӷxV'T%U/%@p16Hڊ%LO&;DJNA^J8~˧%Qd" 5Nw@);x)f3.-PDŒ%l2i){^-S`6N?ra ET,Yj擆B@<\ S`6?㲾a ET,Yj'`FL)K 0j?5|jXBKZ2Rd o0w,MF?^o Cy]դI-%Ӝ! !o$u~:4VgDV>5OD$4ŠLR(D#:+ "k9~I?:;ZaGaGN*4z5@pW&,sMF$zA%VԪr\#!f: n ?-mT*LDǎ]2e%DP'4x W~\,qPGI>%C +;# 8=.89(q |ܟmkv"sӶv )dWZLSn3SNxN|D evLC'"k y4HIv"RΉDKzDLJ|fj8EbI8Z(P.2YI]F<?f6 h?`^'OJid6iHMAdO2ԪO\"c\$fD$yYIqnTP\Ptfs%?۲ȶ/e427N۪K@j,MQܽj~WOf)`HPHXՂ8= (vX<#2B&"@8F׉UM"#,qDO4F$ 8Zy ~N"8= (gM<$?}Nډ9]b_UE%4esHGSy iM@dE2QD3}2N`t.<(m]UȢ-QzRSDpmBYf54GD%`\L$,C ь37 (꤈' LD6yH,`FWU6,'5/Ld9H&W*S9x[2>,7q &os1>=+NL㴥F>=yd"A2RI˜]`szFO`i'cvRD6O J8mQfiX()t1DDV )6 {l%#$ h9qi'P (6p}ܬLD<9EeR`沓L#fp Iq*L@6PɈIZN\ dNik3Hu2ixLYvRiLyc,O2.^0# 9dNJzP.VuΞtix(쌌 48w#ZҰL@#`6/q4;B6l\`P( eq116q~& M>f'*FteIC9c"邘MGjN$ʩH@JIWi޳ܥa,.8F*-lcvbDNY4o >&ϕl."z"vlVNERDH:q1^(E.0S s4fcvzđ,i0>~c6 H!S(,#,iɋ#;fqBd\n!HJf'_qd,Krv|X1>D[i&M'xҹf.!3IĀ럒ԙxF0SaD1X|i!`69&\*+f/ۉUZZ"gnP믓ix U >}>'<u2ix4љ/TjW8bj:JdPmd5s" 9 w[O>b1>D' C.W5Q%aw1^؜H,Q^KӬDM2%s/f>s҆-lwaa8j9G XfkC.W5 />,JlJ-TY[H:\eӶ\GrRO mͶXh?D%`CPF:aY(,P1@T&5lΖYhH@jvEmf44OD<P~V b:NQ$z 6P*bJ2.V>i4 {~>/،y" IΑ]UCyC)،"IPR+fxHOvه9]|F\Iѥr6H ~4՞?/UL`fYUU1i(IeY*\')؜.q\Q2:fN?/,ӰZp"69؏$:GyUb6?v@Wj1(68S<: P $8BE ~4& kA)}hFV>Ex&6y$|VblJfAj}bt̓5Gm`fQ"a" H~b9%J@G}A& X9;bQ #>}&asbOߜ-PgYD]?BQ&%5{:Uw e|ɪ 'WD'yǒMPpf'M@dh#M d)RR5 x:(Azp媺 n0|HW~Nq^i N> ~7dG4\,RӁD&e6/n \i ė:Pq L()2LJdv>iK4!O8|]Dtz t5YL`3;6]m~f$2)NVy&ZO\ǷD*aNl,ozh4$v"ez2$D'am@uI:O׋|'8t. @mB?P䃤m @>MDAy,;.ADպٍAb >B3P 8t&t .Lk!}f+gH~5eωV?)97o9DPҪ'X <tAai dNmb d=Aς1}c63fYm)5aRNgV!7+Yd+U 0=WO iYr3px XPQKvLe\.٘Ԯn)Afv=+lYr6E ^PGN8t߲l: :A||~'~W:CrY7#Qࢠ|x~c7srY7#]"2+;Ը#˒I%+{;Ƞ%˒I1Nk)_!2hFu^`S$|uQ҄*ʊuN:8B=t>Ϛ iap]*;-Z0` phfQ-CS?bRC;0\yH3+NZA5Ge twT]#N2.=s> AvH?]L%_0U3ey8udMB%>= T| Y:ċ%J,P*FL^6[dH:A͆PD$#R+0Z}JCahF|9:ao%Y\!D"@VpZl8BL2eCsmN7NghˉǞn9#(r6Hx,iDzh'-KI>2d e(s-39Wtwm0ȂMDLs6}4dl(5[4,HȖa CxdPFIc1(9e6C!fbh"OJ$DAsPD<u>@PH (dJe,-sNze؜":iXۼA3H5Iu2 2zrE!dPIO]hj JG4s7^DXxC!$:&d "" B9].bs~2,Av\ 'Qh9/KqdG<%ـRkqph6h`CLrm `ۂEsxtcܥ$[Nu1p_,w` -GKO-QqNg'@_+fgķO2J&Q@!Q,O NL8[?$+ /#%`A#&dcl0BM.fmSgvY%gsf`R"S8dcH2brEfy#d:(IW0Z'(}X9T$lBRGE&I9eC/R+`k&&d N3_pAJ?bJ^,RE`D&iOfb2H 3sǕ,P'UI\7˱Wr\;w+<xN*6r%ʿZ9 O:.|7M9#5鿦Mjr;SG?Q]] hЇfNye{ !jJYrGb]Ndu~rpr!1CS/~]ꫯVsAD.xk缻Ass%\R)H?n޼Y2z#-yeUNٳgsDĊgYR~+D5KgQ)Ev?^)(KVڽ{<AD~ _('?O"֚wWk]5ޫrC==mX1<˛5\8~ܿ|k_;ty[ޢ_ZZdD@TU}T~+;u]8~֜|{'xbҥ S$Qʹ<?"b~s\ya􃈵~*J|.QRwi)n7pCﱏ}l~g~-!?"֚~p͚5wuW޸ڒ-e|VY#龺`?Qz "VO9r 7(D5-R4nJe@0Z/^_{y܋CSbl?x'woQq bW^yeƸ;W\iP]Td vٲev[%3; b?OoYq bm_*}7==mV.[fժUwqG%Ա3o 9i0<Ƶ^8~|7{pD2[aڵof޴_8CSKzڢvk_T}̖  "+^S.Qw{-i D3: ""bϞ;1" """b)o`{fcokA5:emfmC? BmblB? HmblB3On|GDDD@ """fK@y95 """bԯpD&A?SADDD̜" p?DDD̚ 2XQ!X1t$X1t'v #"""VS OJ DDD̜E\O1sW8u@ޠDDD)R """fNf """fMچ~@n|GDDDY|GDDD[|GDDD[ [+)j'gcx"""fN"Gb'􃈈9+Ѻ o"""b)o~3Hy3O~mC?Fg #"""VԬmD#"""V-] #"""V-]h-oHADDlR1ڸ#V4xh[lxO#ڋSFDD̐+#Ђohi㛵Z?ŷNipR֭d_""fHoe@SV;,J\/[.?'x#_ytPlё+#Ђo(X:Oj=vmKCTѝ$|3vXm ֛ >2cg,r*&|B?XnAa L׃GdKM -""S`m&ƪiQ]zD8xð7]9WtI=:UDz;=?xTfgV;&N;VסԆ϶lӵ8VsOlѩ 2M*A-6j5omwOat#[7Oz4j'Bچ~@>ể:UIJ %>vp '#oy x^kF/+:KmzukN <"꺅~@>eUNDضA+SQ08 %R}[tmmw>Gof(v?pz6|w0 1Ɩ.mC{o¨)!^ttcd~)sWOa\:t6/:5_ux`ߺ.'hzס ?d}rX (2DqLm]8qHQ ‘W$Y^\:7-mKt]yyy70#Q[o' #{Y`nZ증ӻ9xh@ivl:k.zwoO nI47߃H'Ngc' #WէY3;"K2LU?zn-?g_.5˴O4a~NTƜa}t侫oZWAuRKJcCgN()u-8K}w̻PG{{5٬Kw _a\)o@s ;G_RKqnߏ*HQw` e9Vwv}o\/Q+'2ާ'~O7!~&NhHy33|Gwn;A[źmN>ҲFw9X*?8r_|y6;- K~mSP[ѩ퓍:5sNY= zl?V~p#-+'atY ;'Dݟ@{CG%,גּs2e=^exqT:9컋ų2q'Km][26yza%h#W~P]M.4&od_(mZP7G%[cGzwS#7^{My/s]:b2EqLm]Ͳy>tՐȈAeK𤼨_m@n7H^jլmEٛ|o;n@4yaQo$[oT) sG5N/>DD ޤ?8#u4DmZ:ۙ /CWĿ(ԮǪQlkۂ:2/kY@ST;,\pTglQj.nM6RԻx%rÓ'kop5u|;eᗵۧL3ءkSQCD][qz?DUƜBa}[F zYQ"\no'֙zW?\WJ>oQKy]x旴V߾m6;1>uOSPz< "7aя]uc[V}sW{6=Zw}7\:XXǘ_"~hjh/Eb37u(◚;{꘺js(5Hy33|G?<7-#Ky=[D>g?s,mS,zYOm7Mվ]uٵ_y7^6.?OJW;5~mSP[я;ֺ]=p%5h~~0jtVIh]/k~lߜ.|׾;+5.U.| ?.2("լmʈMHm9r7ԹcTkrs-VDnTac]'_4 {/oXK1\+NeDG9$~&eu˜?=?@ 77@kΕSt[?8 Ƣ~pq,_w,:xa䕪Q./\upC?#Е@~*covǖ}B#UX~E?d,n斟 &ֱֲQ/-&#갳,8и;co4*rlM y[o+ O'3Zlz=>rn^eцa[8b7|'&f׌\rج8}I싘W}K9fNR>zv_Yߴc14'~9U稾۲*v!bKk 2i ʬ9AO/#u\}C?.thLv{5aǔŏF7Cvrߺ[ .,2;P)#Z7"} b*`wl磵;d~a0yUHOoi];^ߧZjWxyej>J5`\[ )rLm.5i^ni]ª3^aqLg},h>?g?K>?ؿ??1?[bVoT/ԽU9l?.49La cK2 1Svexh=v4c+un9 uzc:?=jlU֩ )291{="* ]JŢ8&P#x1yŷ|X'TO߮*>usboCu ļL7sj1: (&"\wnMW<谚A͇Md?XnȰO9{7MvTE%CD>kS@ST;,m^Uך\x̯?j\v֏13AI,NksX˜rm>M 4~"֠h7- c@3Q "{ԢD+5߭3L`Nsoψ=1qURsq1WO.Mʡwt~"֠" hn} /GZ+rj^2+5]ޭVg~0u\W t1%]*ܘ}eV9piLD4PGՎ cX{njf|g>PG΅`=vEt)"L;VlP]\4b,|Uu#M~@n|ǰ:#Nex7–>a\x4_]wT͊.׺*y"߫.2Y MѺ  cX+ŖKޯC7~Uq.wd"0үwrxEOz~XvQ?BTPfqX9~%||/mލ@7i(q?=݋u?#ZVL1muUAh̭A}_w s(cD5tz(rOm骡ҷ̦+ 7_eޠLp{]OҺyΖyopq }t^vPx;_j\2EqLm`!#a;(nsV "3]侎y]uz\V.}0i Έy[oT/ c\Ao<6wRcmvh]`]v)uc昷A0y~86Y~s$ST9xY,9KÂogDKԽ~L3kq[yK UBblV_ Gnsj1%j~S7Oj=vpEm>lGSswsusmOYqroL7^Ѽ> #X47>D)X_$Sl|NͲau_h?n`살{埌3#I3f*s;"^?h ֚" hn}L{ƛh='b0zc[VZs/η;mHݺV't q=/Pf^D$70E1Gײ| }^"GD5k2u@-|Ǯù"\}M^~p-?:h6rMkg&FǦŪ k U{" [I)rLmS"F^1JM/E<<-k5_e?n6%ǫjϧqEgXPf55tX Ɩ.Ge@ c\z84_1b֕U_0c~p?m;zxGWٛ#_!<_>z U{~+?rVe֜|am ?T 1}L;4V#;;*~WQ3"Zީkgϋ7w|3u]7^n1o.V[;/b(IfNS>͡\W)gfJz ~0yEs#ռɖOvCAV~cu dҺ^}V;jY,9eLÂo67\uXWcߝa6]MWͽ KޯuR 7 b4ը.3G++#n̡eJDTƜ2a}LFY}OOPWڶ+~pѺvQ7 Ak0XՍ њsb9L:7a1F^la\xӻ~oXV##&E8/8ԬcVS+* )QG47>_ co9T~WpкDXl(=?w\uF_Rw'W g1hCD㚂'b-(R E un?u }:?C+SV}N- o9&F}g2~A,zwM\E fmSFnEoNW)>a/yw?ִ({epW-N ?P*ßŵm9j5!ҬMcB)u˜?L?@ c:~haHQ8^'r}X`o~Ub]aỺw{]u >~pp/WcGd~y:XRe>_#Ě5taz(rOmSe_!-ѬRDȯNztݭk^s=/~lT&ݏo6NBD` ?T*1}L}babA;Fuyת٭[_ߌtoϓU.:+6^kZP'ɢctڹ?K>2 )f|41ُG%c~0rF58kZwZݑuꞱu ,8}{cW?o^_&+҈r%BĊ>%3vXmz2?|m4 Tu\놧U=nGc|{mkPR༸exojs#)Q~#Z79LÂof-߂b=<ܙԼu]C -+ԕ sw?zRy$ ZS 3)wf|Ћ$gl~0r#QfpNkOܴFx&K?m>O EAE0or]dԶ MڂS>斮qF<9G^.Ɩ ϶[/S"Bf(wyiA ݲ>|~p{߲`Nx/=W"d_m^w2bY۔j>߅o7ȢtϼlZx K{ίn*Kj5_+C/MמkGu2/Oco~b$si]n0,s/qؖ oگrtS{W޷_("" """b)o~3Hy3_fmC? Bmn%X1t$X1te """fKoe@9}K9~3~#Z7 ADDD̜" """b)o~3Hy3_fmC? Bmn%X1t$X1te """fKoe@9}K9~3~#Z7 ADDD̜" """b)o~3Hy3_SS{Ś୦+?v*%skG~0t . ""b(.2ΞskGA?hn?v """M~?ADDDL_􃈈6@?i~:eDDDREDDDuEXbڵ6mX` ?F|̣N_~W_}p rßzHzysK3F}l| ""bl"EUW]% ǘ}}s """\j_ڵ먣o1U>}fi_8 .8s/qz>O; //+?u]w7zwqǝwyww}wyz@DD|H?sCفpQcof4pWĹw@DDQ]h211qtM_O~/䒋.?s:N;O'?y '|}`п-Ugmzhc "3tetZmm#+?7 RlPj,vM;|Gk1$|3xvXmSG|cѰSwU'587jϴ" "gco cj]}vumŁnPYDĠW8u@ޘSU;,s65$DyJ?~~*R|T5a:t?yφC- ڸxEiV 3)qmo\Sj..|g+D{Y}V_<170=1}L+?oqPgnhxh# Z_ cXw =x Hz| H?9%?@ c@'5M[>}!OB?H?6KL=} +&QUjYY߶;msCRk|gI磛h# Z2O^1} b Z`{PuFw|/F}c`uE}b٪=jyKH?H?6$3÷1}M3XV||Gnʰl[n^l#:;Mڱ1j- h~#Z79 O'587Q׶ଢ଼Sȷ` ={zνV~FAT 3ޜ5fp7ƭ?vغ Gw t hHyfm96n;.Cn w hHy3Og3ɚ3>dk]gi-omj* h~mS&h{Ȕ SC?ψ'6@?h# Z[漗K9&VkTXuFRm -V+ hilRy#y(rOm]DՒwMxzx6&+zADЕ@~|* Sw5-JpڃᎬu]~C/i=vDAj$3÷1}t겏wUvn:njԤb}aMbŠD~-Y)9 ;kZ{q0j6x(xγ].#_*5. h~#Z79 ;~[ZvWw7wxǎFmd.:wGbߢc1s F^z|iD%O>;+N]xt/kx^k[:W+OH4;4ڡ/;g1omWh֑Wѹ迺vHPDKE0o=M u/6EesåS,Z[w7#-+_JΦu CJBw``mxlr/{}GϺBh]8w׉pۣߦF-|{L[?=ѧ" p?ڶ-5a{'\ͭ7  ehl-_[)8Vӽ>^K Zw7/l*DvMݓpz؊{۶&ݮB?>?j5[N)C??k 5}toF $[vBz/=HmlΦֵNJ? ҴQO5k b-v5VsjY_ўϋ'n?;b$6=AtnS,>pwi//uDš]RoԿi@(r4TѫŮFϓ'~u&͂#.E?-]*2 х4iRoukcM3CK tSN?86vK? u yx`l̺ 5te*co(F?J3="옶h~pzXϓo(H?6;IF6%^r\֟mvY [{fbV;&Bfղ>xnyXsRQ.&Ut=iAW-a~pn&_w@]GH~R1s>1|Gq^# o׽ZdyKDUmua &}SGKRs* VƜOjQ\o`l&^d`z~pyl,~׻޽[眽nǥ?9 +?:?M(IݮP~=] ouG_ٶf;1!y.F:%/NwR$o+&^?>_;9y+ +fm"jtv~g^ ]F8f a?xk{|itۮܗ֎{y3#ߑ:W?x͟)2o)~/]֝E>豹twK}tq#6AOtS{/΢[\y׈~>򥁚= CU2ʤᆙ}GbS٣ ҹ/ 82 AM ǶBsЧr 5[~/ٯ,^9!Yя|u}RGfӗ+O]2~ŋg>?羴v;wv`c7otů5Z& s?gKy3Mm;+ ?#7(v}[mk}I)?vwD>wv >jvEShʼn]ҒG6_۹3ΤDy%m:d8#,,{Pr.{2~=MqUɂ+fy6xQ>٥NG޻KőΕ|(]N|]?eAWeZXh1ٷ}d+7N޲'{:"iװz6(1%?cv/s_\d6}hנb؜c^0ȉ?;^1oxMU< Yy?M?r[tRe@ɾ#[ oY?:;ě{2;0EݨoBܿ]#>+&l"N^ xA E>}O7##U-W(R+#н:loPg>#Uڿ+I(~#:{w86fad2.yAȎgYkrOGƒ?\(RI[f}G:a[w\S'GOcv~a~Y^Un GОeM̱GX`{ J T@r-3˾#Cya+?'+G;{0*Ciʴ[DߨcӓbukF咟x{%A)ycZ7-2>2ԥ\֙ԼMljZ#'N`wS:=FǦW.~Ͻ,Vѧx)sϙE5zS}T(R& 7>2%ϗ~pڦu"A}O0ѳ6opOjS#eow߯hR1/.U:q;H7 0oP?c~RhWS ӕy8sTq;w[- (ZڦC?MmjǙi#s!߸n< _?jlnDMUJ&x]/nǂ8s0k&E?"2h+& &2L{х~go[v3nj<Y\{pWsyKkr^(u[~EJ^Mmcŷ, {I=91 OtMnkvx9ɀ`ctZN,e~pwxϟu$yA/}Lrg Iy 3 u+e&~25jR8SR~PFFO4}hթ4oKn0Q?sA^W~?fI¡׊n^~̧zEgP(Rҥ*(ZOmjt_dxv^bw~za?x yqwJ‹yXC~L#엤+eYTD]a}G9,>es|1F~NUɂja?}bC3M F`q:$/W(RI[f}GZ~Ny{k"ɭ57yJ#cP+#O|\4~!A\|̲oV-}EOk^9FwC̓#}>~>xGvKo~BS 1ƖoYmKa׸;m#Q羘E!- O 4 5v#D 0oVo޼qtfy:7&~g_/zkM/z/DJJ&ߑ?2]'{:֦'o/}{~<碻6<|[٫KA)ycZ7-2>J#.mlGL*&c8v>ιC~ˣ4%g3C Iy 3R鮀O=:}n<@.w`v *jwWN=R3-~# *Iy 3˗$&k7F xȸGhѣU9D$ ^%ZU_=vѧs4+;o=NT[7d^o_/觮_ܫ&}`=\v[IBb?S<w''GfyWemtFkث~^o -?|i?EI%m:dQR]//Z1o ]é4og>*i%w|dYA?Xh>d=v\H{2t. $֓}Gu]7-鱿>/-|蓣M&v̪aa`MVw$1K5`q'ϼ;fRg:ݵoos'&z{bǷ"k完Cɾ ߝurA+.`Ї~3?=KIQM?x!'yפ?GQo%o*;gJ${-ɾ tW%{22ֹU?YoCwc8 v|Ϭ{nyTi9+#Ɉg>: Zcs#'>Lg?6,x4[WnԊ5LbUY)-2>F^#VO%Zg翼a /^,S< Թ/ 1mgm7[Y?X蒟~X66֚o.'VNY?P5/AWwAK^Mmc˕,*YؽwsFe̪]kǍ?S+:[$<}]lG,.ymӡ&W ooOQ+޶ȊNkwl௭vh?!I?Xa?ZӓW}8 ~wm|2+ۉ7N~bO-g&򎢝 }WdO߾d<V`>{tZtgݳ'?m:}Y797Mctfdf.E_L-{N/g+󥈲]lY<K-&Vw/##ۿzjߓ~΢,ϭ^{pmsL8jl 4੿;6Hg맊ܿc.:/Z>$J?gMMe/OJK_]٢1Toh]3¿}1w|hC'O,}11x[Bc,Sҥ{+(ZOm҉L]}2[hl3G&&ƶŵo  7-J"-=mwww?=E}o엖m(Uw3)\`[`behvZ([t[Wuw-yEx م{OƊ!l !OHF[=Cqvy|_ }#w|o%<<}n3/!S=t/>ʨ3^XXaCH- ?N4`M޼gm1 \i;V<]DK?>UV&+fMmUdDgtzkwT~p}_ё}Yyw|T~Љ"<_/l~l~ʏ?4J lbeQtůS{ԤR  }7o?W ҟ,t׉ N,Ns w[&3eO Ǵnhfٷ}T'KّK~v*pO2wJ]3qִ7C?6~XI.NŞ,8b:j'fmJ~c܉RF6nr=7mu>?๤^T]{tW6v;}?I$DEuFg5¶nG/!O& 7>syWG;3{cUAtt{~ 10ZTdV঎{y9<~ST¯nѩ[݊GV:wIs k`Q~S!IyO*j>Xk4gR*jiϳJ^հ7OWyӕnvd?X)ކ#;wbҟ_*Z3:-d>j~hI7lM~w̾fu)*Ң\~w,#L}qমLƇ5ImrM=y{ FO~ؘoLy s۹ɋO 2|ŋ{9tm'|be8˺E[bW1 )ٷ},{{O?8tYwvgԵell~Vgy?U%Ţ>(L̝EcrV.ܕje:W.K4 iOBV:>jDUI~+ɾ#j_|rl~!JUVJ-fKVf}GJq/f!V+Ӻ m":W{q"*B ]v{3DU& ":Ɲ~pDU& s?P?wq"*ymC?ŻUfBʏy7-f!Vy ACoZir;޻+{[}GGg>=TP[2heBсeB&:1o?e!bUY)-%\Ym!T -L7-BW8u@۠D u_vତ9ŵ#Z,B^]{?wab,Xy(_EIyl 7t,{_~~#kx%\BIyO!-H?t='j V}GU~ptj-{O!zy ACo i1,B oB?`Hm!T"MQPE]_ϲo wBhHTYzz+2>B)ξ'lpWBã*+%+3˾#*>4~חG6+Ӻ m" /?e!42)o~!ԕcDBeR BNoԦ=M;kf{/_:~n5{!t~AB5Kچ~w̾#Bu-l ɾ#Bu-] ɾ#Bu2heB!Lh=O!BR@y!ji6B!87@?BɤAB5N& s?B5Mچ~w̾#Bu%)lȾ#Bu-] ɾ#Bu%^$Hz}G!ꪲ2 p?B5KUVJ-M BqW8u@۠D!PdR B!'B!87dB!4kA/2B!ԕ"B!ԕt0$B!ԕz Ym!B$dB!,UY)7BI^Mm~!BIy!jLD!PdR:A!P$mxw>B!PW†~>B!PW҅~>B!PWN@gٷ}B*+ZA!PTebxB!'ycZ7 AB5N& "Bq2)o~!BIyO!BM-o!B]I A+o!B]yKACo!B]I:A eB!Lh=O!BR@y!ji6B!87@?BɤAB5N& s?B5Mچ~w̾#Bu%)lȾ#Bu-] ɾ#Bu%^$Hz}G!ꪲ2 p?B5KUVJ-M BqW8u@۠D!PdR B!'B!87dB!4kA/2B!ԕ"B!ԕt0$B!ԕz Ym!B$dB!,UY)7BI^Mm~!BIy!jLD!PdR:A!P$mxw>B!PW†~>B!PW҅~>B!PWN@gٷ}B*+ZA!PTebxB!'ycZ7 AB5N& "Bq2)o~!BIyO!BM-o!B]I A+o!B]yKACo!B]I:A eB!Lh=O!BR@y!ji6B!87`~߻~],!BIy1c eڶg7?~rykBbyg/8tɳ6?}"'\xkֶ0nv}WP]bϞ=wNdB(~qw7ijj*>%cbؗ]?M7~AAU,w?x7nnrÌ~!k_ҭ(wLN} 6'< N^Przֳ6oaF?АI-*MLL-TWN4zz馛Dhgn_f7߬n Me@Cm}ҮرGGG; 3͍;t"{M7+ Jk)&cnwwgff6_DhowuÌ~!Tn=Py866ZTZK4ݵࢋ.O|WB>=~!/-W~W~EnR]Q@B7ŏoփ"4rOyS${ BE/X^n2EAee@N'''wx-6 (B`K_ޢկ~%htdd};~_ BC(w?'=u8E?//-|+W/TWW4^}C"4rO|[-`瞖{+C m +w#}#kg>̒~!|=&''B0:Wy^-]zh2]]wյ|k^0Dhw723A~sOK׾n馛+Kz…/}K]{uJ=q=~Be`X} ^:vnmSY)\Çӟ}ݾ}c"4ryc\ Bvi Wy_f\]p6ҕ[nkO}jmmͱKovWP5Smn$ef#AՁe[29y@ )&S}#}=v{fZ{OOt-182cbbo}kQܱs~%[4/pGw-= a199=i- nx+w} ̮ 0G=Q]˥%v(C^lLMM]=~[B3q{|sfN{BLwey{zJ?%A;3.pGt-]78%^k:[^wuwqGoН]`q ûvb2U^'7p{ @(OyS/tCn2u-WVV= ]177| >Ov;]n2?ivm{@c~~w~w~-ln׽noK/T!n^hʫy_u?UzѣGfuZkz*g۶mЇ6Ege/;tPH^Mj׀WyHjfU^ռ155<ʨxcզ5U^Uɫ7*ƿk]lںyW4UD^U^*_U_m @[q-C 6~@A\lp=crp=br\pI~$h$@?MK ,$B3@"pUH JA?@pt\b 0 Y0 Y00 craQv1 I0ᾒrdAr @?P%k(\AjrjH*~ 1N.P\:@eXau A?Mh|>WLh W7~\@p\p&xB MD~20Ah"/t[~qؤ @$\Lp)4_p1 Ah(\bJ K@ \Ip +)4.ajhpPJ MK@ \Ip PC3ͅKAh.\pU @ Qh4\t @Bk(4.d:@BeW14t h M Ah:\põ @Ph\B 'Ph\B @Ph\B Z3Pz@;r hApv K'WOh"\ Ah\ +@\:5pEC3 &6u @HE&4.jrn@k & .jBhMp]E5!\4ep]@3mA!f`oA!f`BhA!f`Bhf~`BhA!f`Z6nl\O [V 4ju]hj;nx-,?h(&BkxOM lPOX{P]XCmaZ3LDH+䗰/vF۸ 9?YY4Ah.0Ah4;hjю 6n뀦C3Eq ,YmtXr\ iVmq[4AC-@[iM$u)<~rkቂQ)7*WU#σbDٙØi 㱚-!B!].$9VP[ /($Ɂ^t:XOgŸ1;$:.EH!m"Tc/{l*U D8L]TRKTiR VRA1Gc *@`R5,Ƞ,\h{HٿG4|RPf$##Mە7p&%P!&u^K+B.G(%M6̈́;)k- Zvijdh]xQ &\NPc5NJ8\:?/BRWx]GTT gj ygCd-/NG.u1I6t%&̕%N"$PDhp%Kw j xePi$D8.02AzQxN6h GȰ0"P!Id,yn#%t0$]fx- $A1; Qa& 47!K l*K4DOhf0S!8Od5d^BB-Az :cÎ" jU(A!Y j>IB; ʦ*8 I%;thlἣrj@ o Qxs4?qM2F7ITx]&!LR:a3BWGrE{DaLV 0H-I 7<&nq°G7IBt!BDsAQ8 dN&+V$VcW&膨 -!/% rei޳Ћb WNкr[z]2cCi;A+oYG8D}::}ďhx$YE0$E<&CXN>NrˁefޔZ}HpٝC2vg^kr֕*h,DX\ Q @ R_f&D8AE<>M|TkY['_%Tv&(NnPN_ mQ)FphSo8k!R}PbHr(dkYpc6\fV8Iηm歂Ͱ竚-{->C Ah.Ig ~S6vHe/ =TvY2)b)-FzT)fphÃjpc'uQ$?zp+cO3hh^"psE$9Z!@O,$ar'^Bz2?NMۡL1I^"GqX]EP$0x#ʓc l':ԅ[0 Nl4O{ ^+Yl1NmVS31Vn=>EՁmI` CeEٸ񙑌%7Zj^c۬beCƶEQ|@D8Vd͂Ά2ueN@|mƣ0,LFD.xW#LHoIyrDCL<Ȁ(M!f$@+QE%ڛ06u1tw8QBÅȏz&I X¬)3 h Z(Lz,U'&> G"~8ۀ$j儆g@)4uQ$9P^)̄Ro&σ~fB%~8ۀs%?,92@CQE΅ o1Q7TM@N6ZEVMe9ruQ$9Pܶuu L2cDGȌy :cu XUMj EC]I4޼c TOa&Wd<X)' XUE$qX( }"Ɂ¢K^ C Q8Ge"W&Ʃm B:'y^Kۉ w,bS0!K$@_5YƵ l ͊ț3ơ>SfA FL2:A[E&]f1(re;VM(s~y:l5\e\Ҭh{14y#~ [>P:'R{+3]c3^3@16AmƲqݗ@&1̳òӇId06IJ*r[3äS2w_̈́D)mn?S::A8,cuϕܬl؎e:}'.hD)$V>n3@16nE7 1#Gn,(BW񹒛U2[`M-()1L2JM[uCnցCtfAq >trofftw8 X L@BY_fDb(uBݪP',t.ea{Q+20>l|䠑djBcI))1L2JM[uk,{Om& @0\ Te##MM% %AXuW#(&ҭ u6v{zPDofP?V{4K d=ؚI28fjV$YP]cV]quDŽ?`f&Ic5hH3yz5 Yvy&S&XͼCDUW\%a q$9ԏՠ"LR*cBLL7rp C"dCVkEdz^+nncr?^K+ǫc8)Ǽ:} Mm:l*r[w5/DiFg@y[Cb_qlPץQ7l]r 2ɕL>T2/Kj?=@(YYP!_< 'uV9kɛ4-#q0ɱ1nxo0p6msO7\NEA+\ ̈́ӴJw8y/10ux:EaLηX*ŏ tJw@㐗=+m(A~Ř)3Ϙ:0EN"3J2gFn;:@q7'2u[zNJ1.EFt:m(M#c6"rY茂PLj23oe|*m chT :bh)/ڃ残a EP u͛ȴ[F2#&߄e/ OaBu,{5QCmܘJmlf"S @K*N6~y)oOl t%QM=Gw\yB^Ko0-r\\t~B_h.zIb,4h5˃OpNGt#O`鈉PU)IJ:}8ڇF PRd4hdHBtyNbf;AODZƝA6N06ЎW"O?"WŘNm 3v cw"^^cB'kdhǫ%J"`/V~jEhT9&Ӽu@$fTtUPnAh+ Lb_7΀p:1~jEhT9&Ӽu@$fTt$TA:jΕ׾2oγGtbԊz)s8LTy] FB?1Il'8ֳpЁ ƛa`ʼI :W1~jEhT9%bO$fTtk9tȁlk8&y 8UZbLTğ.dv cm=bPeXÉN06!Q2cԍt5[:-&L\g~'P-t  kڛ$jo^$$4Z撮sx -Q4~'*Տ(Yd%xh0jotbr,ddӇRm#78* 00᠆)N*yYr R7 !y]2 U! -+0h&$y W`,Mn ' O.xIImf˜c̼&X]"ͥOt*MX8J|vQ$3dE: Z!y,!YHL!I{q *;[fr+σU|Ďw6o w̨s" Ls$x H<8`ǛBf IU$u[ B fl IAٹ! цRMҬzGT}`hl1uP/1P,2`z,0l8nٰ6\R=-Wl6:U.: ϋ@QA;YG8pФ΂C&m`^AO|0PWnaUZ S%*l?ت΋laÇc6\)'wh1LEmZ3^x lVR3H@(>{mVvD𡭤g6\ْ+VZ/mVvDRC8zq}HK ***|*u(G>y?@(AeFh]TeV H Mpvy#eh0Q`rRԃhrN*AϛauBWɘEZ -t"6]p^jΩ2қm& ώ"~om PFP5NQlefnQl1 W"4sQtVnHT+9gG7z(#'),~ueb.EN"8$;Vs rc[4TͿa<Q;HP-NR.&5f¨f171I`£ra; r+7 $jWA @ 4IMYL+1 '(wv>0ȭXb&41>{oOו~* q%E&.mG)!X&vtʍ%fBo94Ƨ"~oSc8 q%E&.m#ZB 7ڛ8u̗yQ?Ьx2dLqK"m=Agkb}UiJ+ǠoU")y{YFz3_AtX*L<>p{F CJGdͼk>Q1jOCNI5%~Żoo^OYaT1f )J7|F&2SGr"$fBoef1Y%@nVY<@NuR4T+vBoA+>#u[x3]Ig'KlomC 2S̱ߏyH&tK³}!hy'D~`hjWAGIF+wde],o$, aH0xKVF$JuJ%)Ȧs҈)7m>0& 9"jTwv+#Ш$l"Q"="̤.fo$Y!-9̋DԻn;uXf!MRPpQ$:XRdHޣlr$-դaxgP} dGK ^WC-w6O*]B"uHA1{܃HmjIg Bw\q4w1%f:W{mw%  8,@cyHz7[W˜kf5ďDB3,.oB{dG1Djnӌ XgjTvPG00,.oB{ӡ>*#rIJȃP4i3YLQf;pf.o$nBB|&Åȏw.&<v`UBaoH'4WZ*@Vʑm]HɏdazF!H,I;@*fA5^7t`'4WZ:$0 ϶ډI$cƓΉ 2y$դTDkP+t6s%q+ R1bٱ\GWA{(KfPKw Hhi$,o᱊-,jL<(&/g>.E .uA*tYUzSkBibl/&-@e[ԅ j:#+ #h )˳Q =4yG C-h ]Tޜ),;5Ä Mi\Lniʈ,!,6!:dlHnǧk.0@ "DJpDGvI(B",Hz׬ BS Ph&A>8tB7T@cp dᄷ0p6CyìU"ʘjuة^P%4.opVT)T %1(hĠ~PA'*rX8wT1N$Bp7 2\fsbbO\=#L4S؂z:D|Р9>)yυp"Abj~c *TDZ^W' Ĕ '~S@3@?х#0]y(f.PZ]m9J^FT8.O|⒐~Q ODU\\ymLxq%[ We%s1)l⭯5xӍ?L'Qtj\% @1bj3oB 'HhVpv^Å{hx„GQpѪͲ,uiz5G9uU@ kAe.HHΈďd8wJmf2/MYc^U2?¹= Ghi5SxIvfFk/29X#d& 2r&{dCH)@(3n࿤8;bHXR۵%q܈ $5 %YێwH^xuXq9-_U:1C*Li>8ʅ]URwW;^bԊS#ƤaưI?Lw}LOqe?U6sxY?aJ[ mղrbΛtUWooƍ0 e"}jRL6a?wƅwxks}?>gFkr|?åzkBeRڵvk1xI}ˈưe7]ץKĻpӷ|v&mOd|P%[UwYB;p<McU0=(I~>{>X}ZFKZoqIK6m[#ͣا~̋cKZ캾1swa%뽶̘3uT 2NmU)-9cc؟?/oL]xoƍ3ĜJWqpeTݪwڷTcHNSqNe)=w47ٵL;RcY}*6RIF1SaAFf_p&M 5KˮK3:[֧[y}K.bV,c^VyAr]=7`&t}SaWlXkvBqeLZR=/* #/W_w}.Em NAQl`,ZqOB/\짞Pho.dx7Rz ]x֎qPNE;rB/b?Dq2,f筬^ʓֲ4/T9ή5NwhZ_ePQ짞P('M)JRmzP$o\aƺxRNo {X 6a)1Si+ZTIef k-rtx:k9aߵL;8QiVLUKղJ}.0c]_K|‷gjg+ݞwa6ߠYY!Y8u}zJ7G$ ySj+t7> –5|dGz8fӌURI3Z^"f,Ģ(3<~y'"mGѸ|_9{E,mj4#k3]3U -_#^ʜ8vh ;yaϸʣh<ɛb' =۳؃TTr7 h ZJ%7Smv~o_Wik{>ƝBWghSW;Tu vhF E>qWvDwݗF|.Nb~Kq5  ؍ d(ۿβyZCoMxE{ojFT8Zz 1V.%:hǃczÍSΖk/Ւr2r]FqQcdO1,W<6e*-j/fϖH[g k0<3IZuט7R^OiE;o3wj7lS._udj >kxv7^wqW)qYȳVxl^]%u˴zݸ1`vm 6Uԩy)_qLy$z1gFtqYl6ۦ[-üw=?N F^.9S ER}.[m\1M(j\Z6Fl~e"1jgP ya[+iBpezNK?o/ɶ.f3tU$l\fWTD/ 72OPkY 7%W>`/Ob®uST\(+vm7a3mkT!6 nj5Tte=;cToŠ ܺ.白fo9Wn)6 .4bq/kv.6hTV?2MS=k_e/ %l(f~iR kgo{-z;J*]z_Ƶq 3=.evjÂqŮSˋ gV2v+aodmTq,?bppߏ0%+Vl^=ee~Jل݊1zXeW7y* #| gG\$˓,O7]v"ftMxJbf4`_%.T6IHH}I)u'.]w=oV9꿽v/E7co*&i]޲Oɴf*G1><+*=IĄzeі %/3 (>+I(]yil-Es^"aТr򬜇*1J m\Q̦W"gY5 hQ9vƇ޷b/泝R]e>LMgwm?yV9s*'ƣo yG[vVi*6(ofTrV9só@,W9$\}m;4 52l$81Co s\1lٹO;5S߃ŝǩ_gxʁS<~MTѹX"^kd+Vu{U̲Vc0`8[ӸwP;xav--VXjTpEI}3ź8[9!yƞ[R+Q CI}3ҽT-g揜<0E)a46[K%$ke[VT8[9E0޲(1,+qBe*+? 0a}抩zp@ Y,}E>u_b1f4uò'X4ԏ}vl=/ 5` hu>rB+a-IfvTAl'BKt]Jwb֒dY ;k`vGV.of|=Pzj^+w{ngZ%LO*S,:S]U2oƛ8)}rC=~K\suRn[#l S%v^I/%zWClI}輷d[=5Wwͮ.viiFٞŝfK(]-{+nt6ώ4V,Zl~>Eusw 4S5 nކ/8Fxzz%*zX*t1*e2'X:;'4oʱ75_ nކ/8FI;\OuU{-<<ّ.w~Sw5ۭ >FKWFKW< /jګ5]0ZI4=xWkvAp)G $6\2fHw JGGhղ}y-u?YVjJ^r]7`gn9;-MG#&jS] uY↋݌=($o̶о.Su5cO nփV9.zUl'*92OtW'JrPc?-3f.vsJ%rʍ9<ۯ%CHO6s=7e_S㏗(v ,2&DoXG̖eIݛ=&>sb]ΈԵ4i$ٺ8XB(1#%;,nf~R&lvEǘRkRpq7~G/GVl,Ka-T!=ț95Q,:4gЇ:_<-F/5)3]xb#ڇM-Pv+^=%g[TћXt5^nU<_<'o$bG@LLQi<˰[׭^dڤѰʾ5FL l]uIm?xY*9<˰}te4ܵlW3Mٺ/nl #qwu[&W|8N,Yr^dvbN1OlfJby'դqd79ǭ.)/O .냧}'eJc19"R'Ht%gvۗJյ}q&-0ΰU¨(_mRY 'ZIJe+D̳ ;k{XҾ7)Zʶ&[Q/zI/h|xl]s 'ZIJeSy{ZGlM#c,wm()r]yVv>= ]Is a?2*az۳lAZk0+$+)mI[EAYrnפz ۧGe+?|p.WD)'x<[ u\z<2UƬ,TUJi@*OǷ8톳LZ݋T!}!ŞMzY_"|AKD!ľ=G:n\x~bW趱y>3H{c]~̓A\|v?_876ێx>'7>|>m]Ե{a4&aK彭 K76pAKR.sv57lӵbdٱg%RwnU)j.۝{i&>0olaq }aW3TKn;-i$qQOFXBm_I0k ħ8Sl Do2}m;o)lzE[\٫(;.krj%l|i9Ys,[;ƲY^r+}@%,h5ΏMfZ5jxB|_ɲG唥ײk` ,hAwloټAi@o#r -Pber[nx>|0S\%2_%N++ EZ1A-“(F̼f@!UΎGhĘ c-נk@qú^(nN|jgGGJۆ7akrYzKV Ϧf1hg5H1,؆7a{䃛)IZNRm<~4TNbˣ1BV Ű`bb*#̞z߀EEvf S,)Ċ~R͋#{~x}U˗[/)'$͛hYwJ>njrAJ9bVS.vE.G> ³wҦR%mW3-IfZiEʞgzo_W:;|[]0;K1#n(f݀ߌw#D;ʹYfsvӒ$0]멲 6U*f-K;4f4|l÷q=Z)O׵~s\]1gp95ۻހY5t~Aųw7ಾ %Sl ]nr%Sm ]nr%[>ۯ{ _PyZCoMxE{ojfNf\55؏ѤSo'~xIsM/^>f78K;k/Ւr2r]FqQcdO1,W<6 (7_d\Yi.oпY굲=[uu;mhz]v'kl6Uw jo|gCryZ5<P;s\vYqXe6/.T罖u1-y`}J>/D'' ~QN(aF;pٸb9]hqo}d#[͙)׼gT^bؤ |'0O-Uc7'T+VKlqubTz6b3vbfy 6$xû\"NG-$v͘U8qub]Q6Khl&76ac~1N4$xrm3/)&Z1E%'b׆{8 3Z-Nbs$x񠥟*Ǫ1>uʖ7VLصmxٲcܻ:1hWWlUUT)>&3'Q$+[.Hҵ%ńAl]Mnʫ۲hKW[0M{J8 N"6)V$xcUV^^Zb`TƅwLmLЌW^-fɘR:SM75 ~ʊy.k-^RLָ̘#I- tK3:WJqI&#'Ա*[0T64Dv&fQe3Η_}{;w㊍M ll<3CZK`K u&]%kýzWlSzߍ+6f4)V? lq(dtڗqu5A/[Kpb;jIݸbcFbc {M|/Ǔf,{ƑTٷS]2tUd+vm7a[j?ڏ?1zNTJ{n1[cϓE7hy.P>\0 #R/ %IG)]PRDF6}꟎j/1wkfo5OY@6ٌfl1K=|v3W1?0%Bת$]5`*l-J,1I WyA1: K=d+?|vgPy'(dޒY@pUˀJJTfLQ5kS̘NZqEڀQ]f4=6>[/<%o#w?'k_(PffS +uIBvccob|6mS02U{|Kbx\k$FJlke 4^'e"fqpg1^q@#sq-I$lFJ%˺YހJd*݉AfP-U8'Y|<ϼ FtKqBހb-%pwYz;˥Kg*i`;>HM_̆e Oxw|N~`$[QO6ÁޯG3{<5K~vgZ<]e@ѳV=] V3S9[gs4;ގ}*Lm^b%-=!r~5bK>z6;.SټRIgy{0c$JYUt%X/۝NR^~?{.l 3gC_3u,Of^X%ٵa^cŴJed1}!Ŷ-Ϗ?u^~Pz6g)[Ru5w7YGgx0c(MhK#o*7[]Z `{#MSN"HGQ|\{K BRYV[ڌWmXпM1zii/O7x$H=w,OO] b–]T=1rqY!y |ӝx*H=;'H?Jd*嘛"YkÂTWTOխ☠Ɨ9/mK7R!UΎGhĘ c-נk@qú}>g7Ja n9vTfioCLeS]ŵR'@deXcAa%`1fOo@}Ɋll-JC,,{LcArm0{}KmŵR'q9h D ..ކ7d{Q\K*ucw4ВG 6zmCLeSX5(Zrx ~hb3#y`6TF=u%+^b.<}=9waY-{S S%Rik~6(F?A%Il]S]J[^K1Vˡ>.c+gb1K&]Q\2V<o!!xf=u=aK^>KccbJoq>NJ>Bccp ݧ ?>g <^v= -{ IR {/WnV `q [G }xn=my=C=$o̾~#e_K`Wےab*qLbcJX%qlVv՘>MH$f۷/q?Fo3r,ɞ[OJh*޺(U=݌މ!h5+밒d_o#b-ov$gxU2;qg}E[+UZbdqe-1R%wev5f;@c7 fX?靧k %RZB6[hfT߲l**KJ3J*{qgzú:oil)Sʉ-aٹyM,2+%כ\j1еye ;o K-jGŮmPʉ-aٹz)T1EFZ1آg\Rƀʖ~gnNRyKXjQ;*6.N%eZƋ)^mėaqg[6q<"#,ttvU~z)~PƲ #\b/qem|DZXUކήbXjQ+f1,JcV+^K}ZRƀyE_gzK'R:_0Chwe/,ʮ׳R[{-ENuaJo;SE6N-^b[TX;[6wykp{0Ɗ˻G)/EAku%1VQ[6f̂$zϕf_g흷K=Nik]>S벯"ginYJrSٔ`;dyU9TsA0ފJ+1 xe-z|V\t^ˢD}ňZE(' 4ƮJU1%RQJXHlޘ*[U*O7=LbӤ\+ٌa-I..|}- +v/O{K+QnavT9{f8bboAAry}XrRY'#iNBwtJQ6oӻ xUO*̛8f~7,΍\|YH=8 lANoc[c\k =nCwnϳ=`;}d8~3j|juMAy_e߱'YQS=3{;>CYr}x_ _p|?NnODGVpru _p|?^.#]GV/kޗ@c緽dtCpS?%.{d/l6߃]y n߃OYj<A'*'I1C*kT8p?bWٹJAZ*m+S{SˉvS{9A>Y[kSɻZGʘ+t_6QHIޘm}'o]jƞ{=>m=Yi,OB1W%v~>(xIVsJ%rʍ5=;m=V)i zDzڷa-.ӘkdƏgvQqRef xLѷ0kiHuiqD1r:Pg+<Ƽ]<[pdj<=EߖVيe;cT*O1ƟEdSoCJ\/di5zIi-H}aS ]nw?)Ȯ-UVH}]7sM|lG@LLQi_<˰g/ {7el%zM|Lueg{,ӕYw免7F>[D?7dg]gԑ/+[΋̎Y)ӘY(vU OǧqK,K<U|˄*csy}7>~1,;cU`;?)S}XȷLXi2f1'׏~/Z*]ԌqLjQqҤ%vIǪԑow9/2[Sl%bWŰ%C!޷s%vI)>.5V_V,EfsyaiTfv)oDovKK<}k9|yFJN12@?oLkte(.յbK%vIN ̓VL5gv .h_ SNzyyc-e[ڤBc3~y..v-G˗RRTⰖ$'Z6/@cʶ΃XPn=oʰ*OSpOqE?e5mϲU7iI"vS?kT~77LirSk5S.f'PO"*7;ܢI?=(^uBeR{1>~J;^7l%U*x ӻsI=Z"B! ^yetq2fe ޘ'[=p+%mx=ߠq2ݎwsyyN3{ULt2+e/{[|5[ߒA~px~u%x .̶_(KͰ̟DoXPtwYFZe'-I C mq.D<7~.~$˗SmÂI6lȦ\m ș0x{`r%ѱl.~V=,;L͢e3dwް'vN*6P2&T s*w4 / f*݃oW)g} BJeb >x&Գyi`$fy~J}4\SLd]l RXDud5[?_{(mgP"4\2Y 6M@E˹QO6-lגrdkuޯ {HgPYlc\VLs*_+]oÔ?)]5"n D6}pq&LEŜb,ʅ;*֚ hހ׃TŖžm8΢bN1kϞK Ob## qbe*aconA8u3M,ֵ/\)}" "t b;]SIb6/lFѮ񜙊Z7)NEnYkPGo)g}vlp]9sfAfi~ SM1o#=ifb솳-1 v2OS?&Ϟy_fI.9\P=B1r3[N̦_ `nJ35W8x;L@z0ܯ|l`q.҆q7ٵlg%HcPg%~ ^ްe?~nx6|n[}G5鴷ҏQEX.\i%WN%t Ⅹ`e"mv~9-3>]S\~envMv[*3qq7)Zy۽n0ЎO\V~jn^]@;>p{Xy9k@b}.k75j5FǮt\, NK*]-gf3 K/pwn >Z7I?ke~N%^{ 92#+}yfvA͠tmlFpy%cEVŮ<bVg45A1o.X\W^'f;7\QN-ӎ[g<ؖl#7Xͫ2%ހz1ϟK]Eg#Zm,yav?:-*J12.f̘ VaR"-{:Kr2F 3Ic]REx#*mO m 4Vl$r1x(aH==^(Xe6ҳ<-KHͤjܶQNVgC\"3՟J?o/ɶ.f3tU$l\fWT.cF2%%*;WPԙrm~\gk]*ʟ]flxDomk#bpWM0fk9PyJvk^N -Օ%I*UeWƮz{ޗ- CWV\koK ٺe.We3A3^іD-IRrv%8;W- ʞI[Ue/)& fLek\m~$^ݖxE[$IRƕ.)є`cza?Kl^Z*Ʋ35.6cnff-]ZReoܒؼ]K ~;N_gerG&#OAlobvu[6||~$I:<8]KKJkgKo*{Xfk)x^24ص71ﺭ-]v~]-נؼ]K nܹB޳DZ4ص;ekiwub}WKT8L('fk;W7> #ј=|7@G.Se_D{6^v˘UYkPصlƆy5#ؘ*DGyhL՞ pˀ3<*o ++*^YȦOq[%7R]Zvն׌X͞NYX\#g?ڳnxG;xeGkU̮qWJ^V_%uܘJa_Ɗ0f45e]1-~y $bLWgU-*+yRa"/1g (nFXNSd1@,7ow%J>R x0II/xavm6>հRwDA,d76&gƌ> ?m,SǷ˦R-Kl,we7ZK~΋;>R x#{3DiҳA8xɖ$TzY6zs#|Gb'r  |ާbS*[u0إ[T.ky-E۹XY}m-匮ع||gcS*[_UҌX\%w{Sp"_vUs^Ato4z ] m7΢ ]g[ NhՙưX7lKl=iI%R=mwM`${Xo)7rg?H%js1[h}z#2a|oC=[b16g(?seW {aJW Aóql|Jꋕ2(xql3M">0F3ŰucBnVl~a|Y7oecd5Rxo7&iic_>nt ooR2RLy8|;6ڈ#W3~s"JSP],wKE*?\D\-&)ZRhYZ{4wղ<Fx1[KXvƟl|VikBRq+1^l&#*K Oڹf758 \_rl-aT6뵌Vכrĭx1[Kز >\,E ǣuMrjAQ9Tb?*K{5u]nEZ7seiA+E /7' }$gxd ~)(gd}z]7s%,Ov/+$ A*W.!UK]7PY pޑ8N"ꊩTS7Xs%&n۫յ@/7~M :+j%~ةREJN[Wq=/V e;ٗDy؄7M&'@$d>{'( lF ۧ{N%16`^7|8zn=,sJ1v/UO1M* R>r%|wARG߭I<_+=,}œ m &7J>O܊/wqyl>+[Z B7-|(}O=ifAc7=[   yɼ$3zW-3xEFk)6c(IZH3i[ NrmeixWU2doZKŗU96k*}M%w\l)VX*[q]٣{]tgL ֳ;4y~y~_2bܒ2RLCճKpW{L͢D vbm2 ˨y얶~jŰʉTI5 J[\TD)J-%~)1HoŮzύmpK{b>ۏƑl%nϨ;#e 8jsǹZIhmk-S4]G360S'ᮢ>[x{rQ8HZZ˶=ν60_z{b> Ĕ$J%ٌUj,,~S#;5W`Dj$3ۀr8WӧȮH+aٶg[wߩ'R#Io;VӧbDl۳;OYx^ O=>rWLZlKl۳5W`j$!܋Ĥ.ZRE+aٶg9ku"+1K>TѥƊqk7tهhOr7FX7Rov8jѫ+AakS[&:lqd$΍;kx˙VfɆ+:Y1+Oj6;Ίcx-WPSߏP_^Wa=/Lt应}zyFfrx'*ϷkEĺDJMUF(*<-uU.2[M.SՋ.{PZһZ޻l}-/]\\*?-{ .i9^Vκ;L],WO/w-b9+ƺF֒mFQ: endstream endobj 9 0 obj 70927 endobj 10 0 obj <> stream xw5sA 6,(( a+ lX EQTT $Lfovo6w2ٙ^l&y02_" 0qJz_6]7{ 0D P1IY'A&u8X. Њ g} tcgn%MB&g(&%Sd{ҕg(GHk?@UOڤܓ}oKb'@'>?$R2tV̑q\F-3& bRV*7pwBkH^:S{yD&Iԫ# bӫ )Q8,z%S 2V;^CwUR9J9 Ы URw6T^E(^ zuN~)^%U\svUb:rMPJ?YOlO z1yG3;nrx}}ޚXS֛Q}>xx{>x) _LvUo=q#S`WAO)'b{{ xsj56*q*?hD8R]{mKԽyL[?>tdGϝu|~o{:^}[,\J1j>ӹH蘯b߯qXBRCnsyhl=+%,udA5avW+nd=A՛9r17ECTh7(߲dEL,Nozm H,ܗk'DѫO(&n9MVۏ羐ΫSٕxN=ґڧFJxX,|JϤEV8Bl).='&x^ $eّ{˄䨹(O8R#zpV82=8_*}l79սsR0gAR2&W磬oz$rVsŚdNuפY"ycX^}U_qVk7Rc֫Vslâjtmdf!^5!^f K+^#r_$rzUEՊV uʒdLޔQĐ^( ߩ[x^_үhem'kԙWswr7}&2&-f]u1z%v&\#y,IbDΌmi.9(#yVzzU(zAּYjϓ$ekyۙ{vja纒޴W염=gq-^¥\G+O]^g={z{i'?M۞R Dr/;gL[IyGh()!^ 0/"ޝZxZ+IrAKUzO=Lҳߖ#5 ۾nLa+(jQ6™+]Zq,}wU^Dk`iof-:RIJxGD}]>OgeC/3w kwOV˹8z™nKJ(?A|&K"%L- nu C-_"0;r(wן S !b~a/{r.^iWU6w3Lc@Wb$V%35m%[%x-b+i'_v}FzV-^Uo&:J(n [A^itygU:Ǫ j-6^ufN+1LUK1$`Lw>ʝМf^A{8J+xRm"5OWybM1|'UEU?0>ѣ_( *~DqC&\,]|Y !\+ai։^c6>-wjެGMU|Q.AoDvBī*)GT1GTU*vYqG5"ybE9MW3%X3:z!e?jB)k_?v+^YKbSV$q-bc fGzZW%BpÉ1<5sYީ {+D^F/s6^8޽vOo P|X : T7Y <KJ8+NduYTDyԜbMSɵJ UuUv1($#2gJV.G5.]jPWoO蕪{&r5Ӽz%Xֱ[cU;FNʑΊ֓s,3S>nnM/M%Py׫CT'fk;1]`[)s+JI.1'e[\_JX(*O\y9ͫWւ7e8~jWzۣa1^fbYr<*+1~ӡ*f_G-u}rURq%+jqň ZKuBp‹p(g_ꁹ*<[of FUTCNzUru=zeO+ƳAؘz ΏVHh^Z*o)_N bӅbDqňCj ԫ#.(\>_1;)H_Nߵ:h/ D!J{="ҼzտzY,]|^iOٕ!2H:#/>QU M/ϟhzu}"59z?^eO2tVgV;.5fyP/L6q#D9pPM s"*+JvkW'_q҉|k4B}>93]B,&b Eu_KyVx%++D>9S3'3e?^ydzq:*(5wC2'ez(rJ9L (ze^W2j<ӓABJb(ȯ: .!fDtyeoǃ^_b5!ғb?\[Jz%|ZG+S O._{uދ0_U^)EXޝQyC) h3=W V.Y{ҋ"qd2]׌! JPwEgW|JLsUk&L +#h.뷥B;_c:~+};Vh Ek'dݓ(W֛ګW =lY):kƮk"lVPp\<#b_,L.bM8WA)YyŗJdŸ!QhsjһY Ħ[U=79A(j+D*WzeMYtQ il#sЫc~c^kK+*X4zu1|'q7o0zu ?K(wYBmE fkm+qT1nؗci^dzhsN^ cXwaĻ#JtëW[{m -1d^ fig- },b3z%Vǰ_vk^,!pI<_ŹKW8Bu{R蕘sR-*rbnBإR8|1GogzL\"RpQJ9LF׏U'&NCWKIJ5 ݾNjXTqkIڋ&s-;YWb,/ Tz<GM0(0ex#z[y\uW{?P GRbQFшeVL;@RST8b9]HJcH^c]Bh γwuW+m L줷8صVްoCMb,WcK@ű B.U|Z̯~pֶ{^^)" DH]_u\Y˂g+Pva*\'‡T5yWoB,VyUE>*\v^ɳ+1ֿDJL'qrkSQA: ^-U}7DF%0Ͷ :*1wH.l9c9x\wV?UvJU ޮy@U'Sxf;7yi#\J%k=".<rM/unl× 로) Zv8қU^^,uf(JlgPOenrGְ+#,0SWg(^] ÜBC+ul)`-d^d.1Tpy_  W9\@ڈVv/PAFKg8@Μ Yi~" SH&|r̞(5 Ty)#/_Xx{_.Xi/R_(_GlQs:c#w\=+:\M 㿼7_F݋=KL!n$ZXKUPU7v ǝj |9fI~k>FXE^lWv[[«^3=l7I}͵ecb6S]ze)c7Fvڑ~9]i>Y-簡 Kp|^%~4k|E.pP^w_ymm+jnxjj1Omٿv+"7y}+6%t0_p5Ayk9cLw}iq֫o,u%\r {ζ9#}`.Kx.MZm_^EoN*hTpIFzto?*n=XpwUt@K2^>zex/?_ܛ,SDɾ65[ys':~$ H8ϻMڝ iȜʍL+cъWQ UOEvHSz. =vzs;~S("o镱4)W(5y7]yZu); u;wKxVQze~x|Z?I}]y Gc14Hs5L\ze)[\^owOjL؎!=\K4XrQv]ze>^)_?H퉋#Ax3g-*a[‘&EP(+VrY]~xv'IƱ=?a+Kw5ħFܾۿ31;r_vmc?Z§]"?K싅{u߯~z{Dʝt2޼5LQW]zYY'7^xlxzBG+G~E֍af$'[&ߊ\&+?ĴsʲFD!CM^Ͼ̢;⛦}2S/;3jF L w3}̠'G y_b~~{Lc}g_7Kz1g;^Q6j݆o{7V%fi F=WPV^RbE ׫"b@=l0ُE*zl(uga\@@z%ϫ@z }w7' +!SN* ӫVIgp~D&1zW$P$/Eə%l۝pUE=gWך̏S 5?^D $3$j# !oKFᚋmJܸ<\G ^qĩW1|ƈd2ڔRyh:z]~.OB7/ 0?v7+m,#cn Eg]YU|WX-I:=[*,[EԳY6 ze 6P [լNCTMR/_evJNHzUesc"Yˮ^wE *"D6ڭ:WƗiMN(QA=3]WWԜǧ^mk^e}VJ(WFW&O(qvTzUukJ9˰^E^OLH+)UeF4? azeD\X8ͼH )IJVRWyQ+ҕ^͟z7SSA>dW6!E 9,`P}1Uo(0sP#5gv @Y]hze5ʴ(/ؼ?roٞJz8?slsƬW;|.p%ǢW[y:/XXVe;M~2kߺiri|Efp^^1qnV}~'f秷T?![uBC?֒ψAviizח{z~3f'^נ"jˇ7?VjxuG;e鋦WߋFY[ -,RFW+h#GN!+}ns/-'l#jaxh|Gϔ[]^h-fRƚK6],i ^@i!`hzh*97{)^~5QM'[ ҫuwdsPP^׉ϿՊjW74[nue?3^wҙ.Оs|PP&-'w*^#em_ꇞ{Q"k>t#G9ndKEՌxjvy*j_[/q?0'^}R^9w4Ы"͉LXڡXX%6(W\@oe^}r⚃Yb?yC&KiΣ߬Zf^cs/ $Ϗ C,l >F4zH4 \'Vb\y#)-_\bsW]/`iiӜy?Yo>IO^+Mz?s5Wټ xC>#[ ;Ov>U5w"rOՋ[@#|3ն|owZSWi%֫E/"-\g}+*,;ФWW'b.9Mj:G:/-Sem(w:qg^`Uf:lwb?QdzAkvHv|;_A5bomot ,qgMSń^oU}J?>lWNbNw絼!zf{~?^WGDŊuQ( Wu.вyyhN `,' K{2(^!r gxmQ"Յ$f̫W䛽Q!Ky~ԫ'y<ٷ?WmW!(slRQ/}%PIǵ':zpԨQWmu~{^1Bs#?c.^"F`j>zN(b9]Y-֩WD?cgTgSUO @chVeUV˓GS[b^W.y2.U@xG8h+.V$92ewn|])f% /\yrn;J=)|v7_NXQTW>Uqtg/R HxR"b+YscZx4R9++v/7is#^SQ݀{Gcz"k?^4pZ9RqJl{ @|,AWg̛2򩦖bݩ9$>⧪ Yh&ޞڻI*q;z"X i .S\~TT~|" RyWO`5+(L ^qjZքVŵ-\Sz;K$ޅ{ǶCK)zgL_Zl 2]Aw^WPh`bT_^TJU _dR/ŹծVR^E &@Qgi(WYCsHY^O^xK\'Wd]׋(sm7S @XD;_t>wa'-MFdz)Ym^^,EQz_Cqn}x^MnnYT,PKl~8_/E'V֫y1<+m; PZqo&Z? E#}w\zӅEqRR4(ŭW3I^Y['2XUFW2 Q]}&}P{B 8\I}!z&?; [ 񺒪Փ㽒u $WTW 8XFT2}ZDիC(Y.^}S%^$LgsjQ8/"x5 +cDJyZR& NhnF6:Yտs4:yn" Vَ1Cur8r+^2NvWT`8;?\(U*-OpW*V*ާ?$N7wkQXvl|?1E扈[BЫqGNSze9(7qojܩzOY|KT9.6f׫"ITHbT$Kn1nWzj>kz৯)QqdzUx-,gn^mO1%y*_C{wT(s|3Dn`9ݦ @3NW=ON׫kEvbF{9%,N^ uY#2]l(hϵEhf~equ/Ol6(e ?Eg&SyW^%Et+V\DXKNw+pu^ֱ]Q1Bi ;ts<ǿ7m?/+Υo!0QLfF%r`?)ZwS0"kNn0ckTzeφz<|j4O}뾶"5 wyƿs>Dщ*m>"^):Xgˉĸg% ~uԅԘ_@ѫb|#l14PU#^W[(w#2q@{i&ٻ&BcTgGU1*1*{>^VgE}>2J=1zU(\ӿuXɖπpo*?<(rY|׹7x +s?ORUx 5g*P*lnQjh8%1%EW;\z%6#z'` wgɶ^Gh^"*zֿ,ZE)YsR-@ʯug{BQPklQʰ9;O]􈇐WᇰzXmT^MW+cw?/1!h^Yu&]NOaL8@d|t8gm&|@dyVm*jXu6ӡWb3ܹFFWj>z僯^mW˻N 9CLȺ͞t~oE*^(NPax})땽#tZ,UZ;@g.w#vBD_r蕱D4M ty0 +c&hxm[G+)/>VJs6!)hX?EU1۰A-?" H.쾟ɞ|PRЫĝU zeVrØ\(zoAgUG'3GhWֽUEȑ+ze|(|.eru;Hqzy|~0Cx1VG-~vgik`Du.tpˍX5reW${ki^h<1F[(h+cbaXB3ഛs93/ Z\%{Ax,NNXg6YD|oUt=ossK @c #پwJگ={l{Cr~SEA|7ΏkIa>1ze~'GWcX$^]<_Nv7F=\YkD+cK ́E̲VͿRXTWO'XxcuGOyEe R687z2wAR+qg[^6a:hE+Xյ$عwlpV}i=۞P/3Jx}_߿|gCke̚ZF{=Iz^AG̛pffkv?Ebz퐋NVɹi/Y۟X?T>脛m_#~^nExi@)]0륚ضO1fŋzP@zVZt1@2;] 66~nz8 ytp2j(8UG'%(̯Pq4bP"f2GJ ]JȚ3*h*ǹxK. ᓠJ_2@q$*Pj} r* =MdMhx]MTKџ%c/jv]0WU7",+|2y=;VZf}MԺeeu2vFŷS-en3`ZwQjJ{u ZNݨu!j]жMn6ePkԺO˺a}{NV.e[3ij]mD~ZNyjZ_Gk#PO5>Y9:Ym՝Z2~j]̬uvYP:fLu `VGj1Rc=`u:Z1`zY-sWr[S cO97RҚ[YFzN#m0ÔobjƬa:Y/SfByLySҾc#f^Hi3k5>HOLkCcZK(pm|~DHՉX1j /Vձv 3W|llڲܤE%ӗQ>_98M73MMEW*Y) *@^6RiЫdJQꏠJ%ЫdJ+q(*@E) Ы$J~zՒ4t@ɀ^%Uӫ? hVmJ}ZQ ~7@I'@[W;ڲe~a _Q593J $ ES8*5(@{/ zکoOU|,]wH6ЫT%/3@ٲ0vJ/ڲઠ#6WdTүa$ "RT=²W@[WZ哕 "Jz8' hWi08>+-^혴3FC^m@h) ӿ;zšWK@B(^u @@@8jA{R@WZe2ۆ^mv@8{"/@|l+-Ղ',leuЫoi _Y.#hk ~W HzDk[+-Ղ0 ҂ /mIV h<~ i;V hW[oml#@_T zgv?+;ZEA8Jram  A8%UzFDz+-o{}>+-^mxs` A<@W:`OW@[z>- $p 5^hm ^E\R?ˆ^m^i76 h ۵zEooN D"ћkd >GLjA춶 ҁlBY+-v^) EA8zrEm  A8K*¿J g+-o{]>+-^{R Q-Xbۆ^m^A8pն4/ WҮ ^p Zz5A8MKW@[WZ╿mzEҫH,+-xZH+-^.F _T TҶW@[W:_^N~K zu[F^Khl nE%^d+-+-_z"7%5v@^mjkkd a@_T ^qmC@t 8j[H@֫n ^pv;Ղ3HBˆ^m^i~lzEҫe:"Uoy~p520W@[/k^o+-+/O/ hCr@"(^u+9zW IÀ{Jv/-H|ˆ^m^i6 h ۵zEooBn ";hiPm $juom^$DQdzbopQ-hA2z s6 h ۵z^ h>׷zWZ0ö ҁʄn@@tW z|'hk ~W HzA6/+/M? h J fuo+-+^m*!\3 zE+ ^mL8qۆ^m^@ABX+-+C@@@8pg x^p+(<0҂_nk+-+^m̍53 W@[+-xZ/ۆ^m^A8^@8jpghk ~W Hz _A8^i7mv@Hz[dn"NH+-҂gmT#/zz@֫aG^p B@@@8ELzznW@[W"HH+-]~ +-u_ۆ^m^A8^@8j /@@@8@@8LmC@z"NmJPm $_ismV'i Yn>8zW[H9@@8Nȯ h J -ۆ^m^i hW꒴53 W@[ɝ +-]$" h JJW@[:W:vWZ6 hK6JW $]W 4:zAǠ(!^ z$i ЫW z-FJ lu@@(UJR؈ ЫdE6 UaaMЍ &@*.j@Rt%c\5srO9$(c9$ÃnxD@@9J _$z`~UJ) @^zB*E?!Ыc5pIW?2JD۠IaToO{V R @t @tzW{j*6J I Łx^p0<+W:AW:8 z58+$ڑN*m ́W:0)  S+-t^i h^:"ia` $ _iN6 h J 됌% h JL'%^MW  _@h@@`lz+-^AH+-Gmm e^m,5^m^iA=̲W@[W:+dOhk ~W Hz3TDkW:PP>|ˆ^m^i hW"f hg+-+^m3T!d3) he+-+=^mv@󃽪t{*83rmC_T N%UY6 h JW+' Hz{j :WI h El҃=o!@ҫY, ">RN>+-oׂ.A)J jvˆ^m^~:^mj'_ٿ6iDk:W h EGF ҃_ٿ=45XW@[nnhΩKlzZ @t zaؿ5?@o zu _T z;lʷMI6] W@[{Tq ۆ^m&5vZ6 h JW__EA8*>94_@Yz˿}N K^yBW@[/NC<?+=v$ژAH,+-`=^m_i+-ՂsJWG, (!oOQW ]E9@Wz&6W@[߮+-`+ߞ@8@}ζW@[/Zb*_X+-^m}gUm EA8*9) IùA6/لLW@[/]ɉ[-zzBW @SzE%ēI}W@[W[(OZo+-Ղ JWG(oOQW ]E. @WztmB];W@[NSՆo66 h E"R{eC@to:^mjGm}/ ~$i zu 7J,S_4UtM $Ыe񌠫IeT!@ #@Rx- /fJ ƺ [(S]}H*nt\Bj]}H*Ы%7-@k<&pcQoOQW tCߞmQ2@R]}H*oOe/ kyoOUW \L4V¿=U砫IU_ 4UAKS^FAM?nV.LӫiP/:"*WM1JIWzTo+ JЫW# ESIU^%~1z,WIO>L# J8U^%?z MЫdJ*~zXW)J'Uߤg >ZR=5β/5dm4v muZSk&Ӛ֛Z,3^XfPUN7j=ܴxʲVZlY5zvm-0E}rri-雓ӗEIjeZ~99}f,Z?'_ֺ5ݲզsr̷奜8m/Skm}eZ;P k(v{^'iNQNk[zi厤HfkZ{zUjoYM#j#U"~NW"UgWɪYaY/؛ZݘdVOjdzYRP?fu fH!̺Z1jj˨.hfjM:Z3 {8Y- N-e*=5T̘ YG59:yu(0mK2L6Xʬ6*6qZZkuYiU~GyӪ0vW2*K02l슋hgVVϗ^zKYZCC `v֔CY jάĴҧQXfƴ/[j,Sd_—jͬjìjǬՁY$]Ƭu%^5zZ3ka2yZ]LN7jfVEŨ:#u]9*6tذ{u(cYu@J+mԺY7V%ZW0aU+ՉYu+.0J܆Z]ʰ*zY- dXUbVcҿé<V%O̪kX6άV%oUT0^g*qNK2Zҿ ;+V+×R|I -Z”P?#|S cC6&VzvU`8K,!ʭ, eZgUo/^ՈYuBHjìCyZ݃Z1A?SseVUuӮU1f`Wc4J: a3ƍ_M;ƿgSyZl[ZSRh9\j];ֵV{S6[lk[jGYfGaץ:(캬Iƭi5^IVоj9ZugʳN:|)ղ ֩NGSCS5n:Pmc7nn6smV!䱖՗Z' ƍoZ@j5k WkP~|sۚt2nNVgTf)h[?F_mkԺΰgR%ԚgVSulk: 6V%*~:Ǯ:{+ѪH)V9}e"Y9L+b@tx:i<@8X 0'.YlsK 9y6B ?O)O\ Xt  1*"$ !Al(@@)&jt@Pf] ;ˏ+rmЅ)"Gڳ _t@J]?{.ӫ.HHW iwQUK>ɛ] *긠<2A=o Ttgbe^ PLb5w H ,>УW.(|t@hXrt@eHVpֽS.(l{ K%W+,{].( T+Hr7""} z_I;{Ku$w $ s Vի\t@d=+(r*^EH_=C>l@Yfa+T!$ h,(XI`i=ZӆGןdVk:A@dȑSv#f@)ӡW 1L˻Li@ Q+TO 0 x: $3詊@;_z<H"fd#6] |GW^0ֱ: %cC=B*%-@@k&fRiVХ)JˌBk D@gfW&$KRT+P,1;RTev6! ZG@@) 'RTew>=r7: Or9RZql+7.s.bp;n  UYXk. 9To  Uל4L-K.HY聠 BT=R *W'c?]~HH7A,j;,Iat)@RКv 3  uyVNAft.H]~ KBAT()!A\t)@rA.vKRWu\A&RTfۡd  :] ֡.ێUKR(u{\t)sSmХ!] E+cAhMk:Rf,Dg] ?1/Rfy B/ @&A4g'AϜ  yU gAt)@j}:!M] =[r3Rf#ѫOХڳ%' BZ] =WЊ67bf EW]?Њ?@\&ѶK hmХ#%Ry7Z /B& ?] C<؀R*d`[K +Rc YZ.t)@9!igJl>c1E )I!RiU$)&[eIZ*(2][vF:=}ތafϧs{-,l8UՀ'Iظq!=ӳױ{6/Hv"׆# Yظ"/,lqcsz6nv '?sz6:ѳ9= 7;$?{sz6:bNMA,lu. %ga&|A?,lyhzc_1ӳq3`S9=79NT!t5$gaÆ >qrz6lذ 6lijbh6l~ "tuɜ 6ldBWmo/6l~, gN† 6|bm@Y͆ W9= 6lc ]YذaÆO$!t3gaÆ >Қ9= 6l]5ӳaÆ O9= 6lO ]<ӳaÆ ӳaÆ X,ga#OOf:~1>.BY9= y7ಱ/}έ@ާ̞kh]L|oaة'}gtr '7~NFEH|/ëYWePف%))Ϳ'$,\ Wrz6,ҟ#?3_ծX^,_/oYqqzY2YztϾ 㫫--=jۉ*ƒЫgW%P#J_P4ϦBȎk |圞Y[sZ_}Fd2X^Nx!f7p5>Q(ZWK {QL?o*fOK̲Me-U?6lv;֘R=#5!"_"3wS XYCص8H1& #F˚6Ujk?GtSjI(YXL/%|jPW'꒶7qP2#c_޾(tC y *e߆VBL k|<"$_(v䄷=4ٚčVhN竟B ~a6P hbjKG"G:y Wxl _b4@-gn$z p^JnOZʚW%bZJ_|CiOP޾T)UZ_#w BCW+)_]"]Q*Bw&}>aE4!_sȭ};@: ٘RTLQOOJm1Zm~FTZʠ,v9?}DrBIW] 쎓7*]Djς yʠTn>SP ]F^desq;A/ U*gRDU@M ]\_ܙi[?V|5X)_A*WQͨ')73W M#f|Eֺ5`!9H+|5R]jg E$7wUpmd2ƅW"\|L")O['A&iu~FwUTa#O!yrXK*RBJ[ _=+US }ŽjޓGҊZjf@WJD .,,'j+|Ո$_#_ۇT䫐|5 ΛIn=S#_oIeu$Kx_Ƽ.(tR)ٰ!-hhQ+s@-lq5CAcƴ| o_)֜xȑ +zt@/S|u1v/"h;K H:Yt {ai7^1eE4;t,t^%J<ᝑ: *FYʆ܋_5:U$*N({ю _SmM,:^*̸6JYZD۷x֡+prn& @EvƜPLt-~PE<4`[n:Wڌ yzg\Wb4] vXLBŒJ( y W2JWWLQ jf+}m|%lW!j}~'OӴ%|FxRoHWbs?|PűQgSP+s}x@c7!J0cHWJj<*h&ep/ $]H{_֑͂R23գ,yh!M4yg]_y6dԴUҏ4Vt+7j[G M(AԤl쁢MSÀ곒E,dU9_B8%S+Z_춺 7No/;4a?,ԴZgi l<=iTe(|UL0Sx+yduj;&J!F"oWI>Vڋ$-fO5폸4и_y=hЊ>0T%h}+y{pS,+KH3g?lr¡#o˴EJǤ?&hU[V0+ 5NJ<0Wv*khقLN|{*t vL}G_7_ C7jK~a ~y =ƄZh@/U Dy`}l{W4F<Pw3 K/=Hf̛y p9ѕϕ" sp;V^ꏟy?("3KU CSuVJ_1[T@SJ?7Xn{8e0ҽ%rBc/iB#ZӉbTm\iL$RC iӉ$T|Tu:?8ÜDC;ӲuS r?lNN~[]I+x~m΅8ntRvKX!r⎌̒4N\EӉGNEH$(P zy4Q0Km3OV;CkOASnl1Q/ N''ca9霪]|]JҬ8Rޅm m% Wp \ y.\A4zK𥈇L@^v\"p щa?n!)WdT;79.ECrj EϨ+"ZNAןq¸j^&K,Fx4D\I]\uv`Uv+..ֱV$k7--C{(x#_s a+.7-mUw˷E1 %:$ 8 5y%:i{DeM6x^5sмk XY)<]-CMoD~Ȣma];$DrAU3EO=ZVZm(cr}  mj6_el!A~S$3w!N1h&wOq;_>ﰉی禯Q16Z7N(u~>M|ɻMr\s0iHߑӏk;.2,sķx0 :>罾C<7oOϰ*c%r Fv'_*)Ъ =}MUgq.oW곁+Mӫ֨'Q M*Mt57ӡSd.ʴeYkcFD8/5AϺ‚E~ao8\iWd8-apƵ'_ft7>ԉ%zG#k% i$ͷ4}ϔ>uݚ-1Ijw<}B 7u)57Kd!- $R&vԂ1K;WGoWcׄ?ٰJ3@Pjyb_ҿUr7l :Ѻ r;:@cҊ|۸&oї(6=))IN&\DY c}pd?KB^Eu:y3m`:t+foN(mȄfC1+/Oo*-&M6.H{a.##R&J*[쥢;[z$V+kOSC2P<KA =JԻh[P%t`|Qb2"v;+4!x(X&@BS;Mt 2GQϐQ(+%$#Ae1Sc-W)^^JFfO = aߝϠEJgW[:O `:u7s:!=&W-e4ZF؛d>z%vW~{HEX c5 _nw$c,fQY|pnswGYUD>++B2Bz/hh+O+ 0&]Ѡ0X3wZkxLHGDI;t>謹U}du ,yaFW5y2|_VZ Ku [CgѪX8s6ma?{ѫ@zJ ]H"P]qzޜN,zaHi(ly -_c~mW"&C>FBS % V2|RKG tE6_ٰ_jW!Wys[iD6FKfcjW(GvI6Y_$NjgB[Q^s|x߹7uSߓT|%Tf( '5#_a1r ╼m4Γ]1#`FlWP2 Cѫ+3/dW3\ ΍ߚ{|7!MHߍ.;Ͻ= G4lCJ7LuRol KvR 7z(+Α|FJ.4 {Q_̎![[JF|sB(vnuj N{WB/eW8n,LIOv-̶ᴻn > j  !)c1?'D0 ơ/i}´|53Fx 4CVV7|eÆBCbjJmW,^R%twy 5U 1zGս+9|pij8\WV|eÆp? 'RK`]P O9F7W쟇Iv;$QywO3l7mB^{WG>”V\i&Y?T\S}&0:Vt_ #0?x-#]ט99J"_mOHpfNHxٔΐ Q&4Zk$E(@$bS+/pPV$k dRywpnC@@Կk)r`&&,B!eq,Ə `ƅz؟ El \4hlѾV0*W|ej],\G|q ]#*ӣBPJ,/⸡wwOޤl0n odGbqJ!4?ngݦ$ qa\+DtJ,F}W% .Fcr\\\>q 4Ð,;gq\fJs=[i*MTUT{^(E_;-Fjir`,y8 bNŏtBm3opH ߴGtܥ6'+5/G^W>np9\%]֕t ƫWG߂n;,s+</O 7_-Y5EYbL/6"u8ak~5Y&td?O蓼eJ<8W57G j 2xUpjklt漏=Se қ\v/*Aa竜_|e l0 lN|u=a 8)2-Q݉xl{m̻l孭W3lI^4?:ݫj~i6|)Z7xegՁ756=OnJ:4hmy 5<մ/5nn+oPOCYVOj=tTZ?H+ok|<&Y7}Ώy &|װG7hk/\6 ]W)ԣ-xj+?C竿+3wwCmvZTɽ|B) /.T{8gWo]ijVݣ83K}Xڹ_hqe)>LԱ0cX j&oZox:7Ȝ<݃gϦRÚ y8ȫC_"I0(s"h%^D^|$!{ͯV~gjB8Q0 "(_6|}A竗 %UMJo!Slo"/x!\trP?j PWbbd_Dr;7KԧH읿&|:P;?D,FĔ|59&^11xwO+jƃ>^=؟Ws2s?yT=coBd/yvm݈(Qjo0z}YD8B3ç2vV 3 Y,zF Z$iS  rL$tRZMЈѣȮjwWUrJZQߒu= L3&ő^Ndhɹ4$WEzaWk ]NՋUZH# `,eFFo ]@E_EER+dUl/T{ _ ="/`R?ͯHE֞F$+ORp'SӗY૨"A v9 gp H&*dX~ pD1tFWG[UY0Qm[w9So{XtgW+[J _ nKI V07U#ċdU,R!]-MTu(!i'd`.*|YmWDIDLJ/Jo0k|u;`Ѵ|„21 ̦g-OϤV}l%_aqWT8[1QR+\2p& ~Ql &(Ѐ6PKkBW^%*`d" qWx2҂u &Pj-!Pq_ ~7p\0C_`p~WY۰AFlx0w.+!|U'^NSkz MUt#_mBuYzpodԯji8+dA1^bq$8aS(G%CW(P)yNǏ{[kF¼0!ȯ/6 !RWD*}+me5`I'?PW(v0ǝ 9WL.8KiH\Jz7pi&+0,9}&a#`P+0-54\rW ZIP%rWZE|)l`׹bl+=\_hns:yRRȦOO!HDi|5 acimFBm]C{vdv{޵n(PAّ |EpnFuGL, Zk@E+N;&}W긶J._MWvS_W,UJL36 lظ07h+URQ^+_kZyF3Г,pYT}[V6 (=(= WߪᕯN~T`V%P;GYalظ SwXI AZ*=AS&qMJAR"૽T`S7074S+H&(WPϿ_BE3| 1ih[A fp+.qW4&936}&@fmGдƊ Wj_,S [[VYʉ}Wc rum ,f3DNIqoodWQْ)h/w>zdٝJq{fX63Ay/orڱ'*n?z-J7?rS-I2sw zú7Ө ]G6s`|b=~ %_4Ôߺ- 3m =2)*HQB4QQ3t]RcLmm@ЄJ%t棽zKqzCWcAI8q1#HeT31cq=q yjC Īސ@+\ 'URaq4 7~|V_P~@WK; $xL.W#Օ/:^^;+|r|-6ӏ f|ʩ u+\Lf$BPE&RG_T\bO]hMKp"?h*[N:h.x9u`BZHJe2^7Nl3<2bRy>" &|]z%Uh ~85QƲlη:huE0j-]&CRnZJL PdZB댒-`WYG+:v2P8*{ǦAT<\BdG!m*8Y9Ti}3Iq% +Io[-wtP=7&ChG1yk!' v.NnW<J4|* f-W6l*j|u\w&ϱʆđF4~-PƲ1'nkS_hcO^ﴡo[fWwM)+KEO0to^Dn~_|e$_]?oY<~ZZ|eŊ{>cf6j@˯CydVڳa#/#7+=Y{3PW Ck1l~FM`9أcލ(D|~KCPkw6%W^'_&6΅"K [58yb 鐁_,)@Xal탯LFJK 1+0kq7<^- 6A}`UAT84Yl+jrB]`~]_((aZ!'%%5|u.)+rEXXJN$#D¡k1(򽄭Y$|q zP$_-vHg̿&pzQW6nEe6Y'*@04ϓfv=>`n8|Q ^跊åf-\XW% 6-YIieR2 K|%⍼/K\Zɡ6"A|Ub.̝8)j h"+>UZF|Ib`y6pWhʩ;+ڲ'Ƙ]+ URLjL,$T1_) }2y4d;F¯@J m\rq+4|%\%-Y@EE b}:˒<ǥ*AǙ%૿=gGÀFm.g[.(axv)+x_8}%C睯D]Wh"|[UqN5ݿ=l_2 1d2з9NEK$1% -3muW6_ٸxJ)DLF Wq52Q=a&VE_Jz+^lֈSڞ1竎oi z˷] 򃯶rUW/4u2G2 4&1e(bW^#x;4bPA ]*0^Aflܚ n ͉?_0j0Dt?H*Wi@QO? c\v]:e0m7X_Y?I+&\ODM0!Ow2JG;#QLYh[_/x V倡;,DlDR+3C_Ҏ;+Bd2}$30E2 qBƜvI"_=.3xYf|Ff `Ԋjypw鉉~Fa## @@" a $fCAɫ<S ŋE+L,W{ .#|ǜI^=o Yl$fAwV+'O%@˅(|Aw-k`ݹPJb؁v74vXX׀t\K`-7uN.4z e`~&zҴ޴׾{^/ &_ a* P/ PŀZ Ј [ͬN4,UҗqTcjLU=ah(T$W"+uY=e 7^3X>IWͩ=!4EQj_%fȇ)$K|yͭHlI Fn,(y t\}ٹUk{<ӱ~f{|.-?th7\IJ\D~As܂#*1!aW {#0_i?R}P֓)@4Cz]Tܒ{Vpc6M0p+Er\:PcAӝE "**$Gf6_z jBDg04KPN(3Z6Forͺ Ў5##ưj|-&F C^4|Ӧ6I,ņRd1ГCӆYi04m6G7i5-Aڂ`kdW-kpp{O~ʀYjڂ6zfӹ,cOI&Q dIGuf+-X݂51ݡѝU&+Uѣ"Wk5\ |KefRɒ\mWڳ]S<_۰xŮ4,gŒ!&,myի&e%?}<斴5ŭ.5'<ɓ~^W7_=~C]uĒms/yMqekzf0㹂l_9pxWs;eR];_W.n7xr"nZ@kYW6n >bΉD蛳S%у׸f|ebq7/#-}g#O|<4`|uv p7nQd(5-c35qm>n-zK[cgƵP6\5E: M;4S&%[4cPJD6MW(C{F|\8U6Qj=SMyam>`6K!~O&a)4> \jr Y"fxAm{4N$x:DZhGRquu%m_2}CX__K|1G2nLFOIͮ/Ct |Bk5R>]ZMgݒzCi{2 WeKF޺3G=.߽*_r95)<5&6AqW/SQāp"Zg22n"!.΢_o6w|iW;Bt%E)qXV6K}:F&all, JWĔVjy;^|kİrW[ ׭rB6 5 f2!-nxFܮեpZm2:_JZ#573ַ `lw=Dj؁t!|> iZTD”7 0݄ª8dl1h)M; TMP__[ ]ēV/wMW]h^U7d =&C5w]80nnМZ:#Ս򔖱AJnC _i=!`۸qpc Bɏ :B|ʾ*+%@q?摷H dٚ3x#iN鲗_e +#n=GPBy3WgBa^,Q,!_E=~ݝ.ᙌ|E+\"Toj:7_CHNUJ(oyw6l!`Tb:_|T)a#ϊNd%K oV|/]y;؈җJ+<_Ms~-1GuPSPBaw+l9?Eg_WIµ6=ڃ.£ yz~kYEgL-+Ͳg*\Dj$*W\i|1Avep"Ă0܆DZ8 &S&D b,|I+-W /|7>% ur3& y "#/+96%#y6.ĪUg^+ 27j|$Jψ']p EDG/|J-_3+յ׫Yտj`F T* a|Xaœ&C i$B R_bMkmW?pF`|=uB,E?+7+g-,u+8yŚlb J=5&)_aa#/pBJx%G`( |UOTJ%pϛo+^}9'XL^K<]}J!KWKŸ%-:"_JBvy`;_ eP2Mʾf yIFb@u_@mh/sԭFw$y bL {ma,vq~{h,337Jwt׬!=}$nZ WS8Ltj_v~9_i("mhH`R_S`,T^ oFz 8ʊ[8j*q0J돩-n?ptopO=[?33lnzЀCf24c?JZVL>G\2=mb$|9J*'BF4Sf}WztQǔ&! y{JG}Rx9`*x+Lۉ_-_1[iܭv8̻"&-YUb Y j4T'+HřMsM Djƌs[&*q#1c>D2UZYB?`@nL'_S;'LaG(@%̹s!RLƩ5 |J|tyqȈ'T<=\ufy*() &[tWzBYtc{L~wp%Kg4GWgP " 8>^O "|ܙZM|#M ,5pѪj2DU$?xGaW}66YLL@9y-q9N.+T39ث;/E#_ax~.a/}.v:|m$3eFɵ!:vB]v/O!}MrZ!31;_icI,Ր3s ~e;sIf9 yZՅEX]P!A3muDhY`^ |NHlv1J2OW)%2' kN$W /I!DW@>}!^|'?|u]{5uӻW݈r/s:QR9&;ӹW8 Hy߰# S{Sk%n9v|<: J~ Nh4dj+h?sv"?(ew_ztR,>ڼwOn"-kQ]c.(q$8ө\t>ur:;((p:QjtNдNL餲pb5lO{DawV99|og ޞJ6"JۻFV'Md_i;_^Ge4&tKPda" aQ3ܤϏ>V), wsEnXRlhFb_ **/塚+o+DT`wP )L3(SA4mD5jMEN2-1*fi8:I!?X+Kr,q$QN`U /R!ygl[OORzdvB^^$^lP5/S>QΊmw= =F6)/h:~ ƊYKBA`YmyEQD3\Ҳ\`pzop[C_l~3&x;V Ӵ2B6_AP 8kUT\p0Q!s߸_ &2||u{L=S*]uxff?>FmE֍a8p (3i#_+F]EY}5zb -'ss =RKkڪkVO\WW"{5OdB#N*yv?XAiD'CbзS>oU|Y[dlϣ׳Tlխ"!Y4}Š&=_O7᪆n 0Oo+/ЈW>'G'&%Q߳cSF@4%0%<[)û.&%6=839Amg:2kII$_:=LjKMh]lW]xY>W|"VtrR^eFKOs_o-XUт] X(3M0ߪ],JNU+Qn|E!d4t̏4@T4-K_OrP +!={0I_Aϖ]2ծ@r ɕ`6c_mժ<#5%|fNO' Jܽ{*^B+(d_ ;/oOQpPWR,u}ee|ӿ2aJ(ROnsHcJ{/UNW)⼥u0W|uk c6)MDx5˚t(*M&06wҵʆ +$+c!Sk =j+Q>^3^fo%Wmw_|%ԅ-B᫇I1u/x6RUHȃnB_ǔਫ਼})kZ o+6,Jl$ ZJ=\rU{&h3,> ce)zHBNf_VA[Kžô'PC#8@+_ͧ+.Cސݕ.+13²ʆ "* 4Li|-6 J- +"@6UJBn]W2s[9?J>45pj))jWA~ b ϡ0H_$lO+6PH¸=՛  F^+!d:fS PxH@J33?_ii[:(c5FOI'}Daz!ɽ[JV= QK ZʆL͓HfJ`!7w D$_H\v?գIXiaJ^m{qХTq܃t00kjIf-kYs hhG&4'nT|hLYN4t~Czmࠛd;й9׍Մ7+Lu&Yb%$̼&J'V+ T_ބbW)с~_.=c6-=Z_/WnPXhTFSB29 Lh%zA{bڝ g$CTEAw>lҲ}ȿXhN?B.@ZdS@N.>AvPvf^j?\lb-v7^jZLզx[ICEc ԒT:ܨ`m'VQ}H ѧZir f7k&֬T2nv`^73t: @,ԩEK=FV˭'C{jCqn#U5 YNP;]Ζ]аҷ[Í!a)NÖiBc9j-WYCߗ<{q_65;ߚe{1Ʉ7#ڙ{'$u5;%3H-tSFvlJ™+6n)0ʆ[ 6_|eF^W6_ٰq1 /Ut[uԴ#mqw9LvUzZ7}=nkأHxޢ~ܵ*Ӯ Ӝi4xIZ٪i'ưi+=Ӳc}'oʸg=o]t;Zk  SJ[P kVWkBu[M&.;Ս~ύF$Ɓ n)dy"Mφ [eOA^Kne+&m INc h%&& 4L;ðGfzr%Ws7!w~ay;/6@_|/>S&(WR &|u,:ׇBpmX>bb|՟T:Gk'Xt;Ϩ<1 _V%#-]j p>M;元R Ho_Az}P+ N\WI<=AQF!h{]֢8]Z&ɳWu1R m6 SXxjWvz R[ӕdRnzO6l |UeTՐo'e+G RS'LD25A; 4"4D9J}X*MW՞_ zٱ **f}PwI0#D`~Z[)H&.|%( d$2b<&&Zٰa _e ^ @('E!ZH% k 2ilQJ /2+^ =W[p)*$fWP= }T*T 6lXo MDNWN_;ca1+A.90ϴGA"I|1 A5I:A+`u#iKf%WZ J3%MLJ}YKd.C>5AaÆK;(6N{QZE@""*DA@zGT@>D XE@z =߼3;ev/23;;{d}  1 JYy9h.8a׶A0啈YL0bP#ylkx6TnRhs#޼ 89MN`arѸoﻎX偡W%CURUsj%T1V%wuk9!/G-=Ʌ[.LD"tFecFWgQJ tGd*PAKCa(y%a>sik(.ZzOi3%WE(.[^,N%<枴5E"2 _' .n'c Y$j8Ӫ*FJ3R]B2Vy>$b6+!&7@8pWQsW8R,*0w:8ÞW.a@vVBr`XRKK0.dHLzzʛW܆ZՅ2X,SNJo{vD`U]*G>oקlnǞATJ^3(5A,Y^؋F^۔΂WV枴&fxez s+9rG\Vh5ʾ0+}-2_ I񌵫S`2R a)TYR!Txe=W".'ZGkhii 7jrӧ@yXۗa['AYTFUx$G^2<yEtrm$и3NpRY틆VBla(p9x˚@˅P+I\JC^hON> EfWD_ #6m%%4yuX(tly%`^a!Ga }9;4,P0ubȫ٠E:+C2yj5)H^zxշV.fejӦ+ٯzm/ߕj>Z7FG,ʫ䴂u,B.!#MkG49(xED%kN z݆D+[fWpJf,yL ߖ <'6GL8@Dmal?⭨/N3Ӆ9Ӆ~4T`fc3D!YӾѺ Oz1aѺj+:>m ӊr܁WԤ[|V(>J)KTOC]«0@bNDwZxUrq+> 5l.gSf^Xby jO 2·CqNgbr0yJb{Cbh1ݯ,nK&O~Y6m0vHQռK/Xw!'+*{, W*^ &u1/l. DgA( īY[a ]oumeEk^v\tvq B| ۵a U=ڵkBNI1/k׊4E&xU^LSyoW7G}N7hv;I>ճĉWH!s`C$g wm8+VM fY'AodPxe"HQMJ~->h I_ {8̢ͫqfc,g{$5|)\UQ+iyMdeE|?!Gsf#󍒌ly::G;M A%x>MuxߡZxVR% '%sn%Qּ-j7纅" 4sZDvt e9L kìEW˟K}]K\hE5W{ЦdtOv5ڔ7/{B3_PiFg+xam fk x ]\!$h ʫmu|'([J>m2dSYmU +N)߆ hIa[Ն!ͫVu|gu.K5י~N׎~rU*vv~o x;+zҲJ`Bls`C#ԀRxU9΢/|xe,U9<:v0iZEgpl8Z^JE}Py5U׵s\xʱWd+xKmDfZ&'f|"^k3~y6;BWP@MF--EO|4j/*Q-F^*Cf6e_g7#Y9i9 t^Dɫم=v x8+a+;bO3m-rƒTK2~aKFyzoKf;umhi ]!$McS|rs*epyEhH+-A^e\L*XMP3b.P&[RY̻]Y9L:S+R`>gDdM.5r6_q~8X"<'m 5NWu #\ )TM{PdMBϢ4*|. iҷ]P[ JDY6A&0gu&@굈zPXґt J:+#]#9s~9lAb5)\ɓ,va(lX$l&<2ȫ>BP˜.E>OhbH|z4 epH;^;9J}mGu Yl2i{@dPVP+_ix *r;gW"3+M#f=(C ݋;V'aZ0)L4F^f)pZZwv« 7U'F we-r-*AjYqNeDiA^lV`vfVG8O]iF^SZ~zdӲ y%&s=5|t<$Us[LpJqMWnØBpSm +^67jL%e)W[VbR^}+--_]=|>Pll %ESks.RLIVWkH)at aplv|xZNTXIv 4Wvh6I.pwB!ĵ ͢|}\1 s8yEz1ӥ4e1-|}xf}l:D3H+@)5 Fj 3_a)ѐ Nr1%v~ чW􅁒iไB=""i^ii ] E?)5j!iy]TbyZTƟЄ#NJ%`s'l%=&qXH. *|&+ = " f#݌yuyFn6Tsy'k!UO#*D"Bw%ۚW@ؑuLVs^uȍf\MN26U(=ā~ ;[ hgFٟ }yN3߉eز`(58 #r@=ňͫU'ε>bc?\շf:Ts@r=VJ(zi[^-xpקY #Mr:#"xLDm sTGp_'i:Y0 ]fu%y|8M%por-FۋA=@{<zhٲj~hbF8Oiv>7sOuIqjÌƍ;:eƯ4vԇ Sѓ, |ibu=CDO,{js#|YyM9m8:1ʰy/$KdQq+USY+?(7O_FW#7u̥3!!Íמ,.Wָ%]?9~??}yϪwZ?tQʶU˶[>{B}ne]G^;?`:2*п2+c@ o5} 7)Xx=ɫXm6+F-NZw4敩aMXr\AlҼ HW\/>OjXf?KYO6լ57RWh_Vx>𙖵[t6|z780mն^l>.Aia$yA3_º]1#_mnr^k5WjoR݆q0a=Jˋvjyu:d&u~mMƫϻ[k"h?;|p7=ZjYە* #qzgξbuM6[\J>uiB6ώ[ɾˬ̯G'/zet7פ N7Tژ=iZHXe~CHf6ol,J|}r7ɓrءt_h&uQFn6(?;{uc̑RQ^\sZ9U_65м@z| 3~)J5v*cifTo[N߻~9+Ҽ|^gG:~Vɾѿ7OoSiez._o(4IW:F;[y`6Vbgzt wNj11r a,'?BU^!Gc'L4;tB^瀠 p8I-bcBA#9.&Hz?/-Ãcz4%bbZƌ*Яͻ~P cSy JE("}qhU`Nll-yP^-#yNL تHH9јOxAD3U| RJ6n.Ϋ# e q}?}V)2 J(Il6;PZx5QapCdZe 叇UQWثo!uWOmBy wHxv/-K{@"ϰ0#\VQ;;`I|*n<cT+.Jѹ4o>ƃ1 d*!{[5ӮLK+[\εLFǻ&B5I~d֍imxyrA¹h+1D\ [/x0lh?(Py;aQK~*eN~x1Sg5ȫ\,n C^EwtNp2wc"$ Xρf+ܯy]< '+n`y*Ut$ ށWE2 4Ȩ\L**x^ M_Zn!Z$L # /̯gI:LKrL@K"yURp@^|=RY<@0"Q8*L)qw@3QASH!D#pۼe%VN+?zJ\2jy@|{-%pKJM^̿I%ާB eٺ=.ִfQxd<9d|"Q-fm+!=q\ȫLaU#a2-8^*sRíefa^OZKŝwӯyUl{ڼ4 gC@^zx*+7w/)>{%0~0?k+k]nWOFF/iֶdL> ?ٖ«QWVtՄ-0S8aȔfZU޾AYXY6^W(ʅ<܋4-^Ky%gϵOUvYÌ]YyU٫7D07\1IJ ~W(cV&V̠R#dTaW-1m: - %(y%bpKf^E#4.ebLE&NW}[FeޛBy-TϨpQ%+1 8@Y~wp6"GK '7D^EB a«8ՐjOpë `Iag.6 B^=1U}f&pW_p+[yWmpW†_^VzK.:n5 +"Ļx8ނ7 ~+LX.B)Akl/?l@LnR a9*:n3VPxs>쏴m[?¡R|*y'n uډWJuL2W }i8oK]/&ַ8P^'2N4r94hm9~ %:{l X.ؼGFoϫxMXeY1p^)87txESb,CSWdڹ4^j. bɵܤ΍ +%W ԇ]NN%y Wpd? oyew&3y4ZU2QvrZ_W>bߛWe/9)t}Z^UpRg"-leVBTjlR F#W܊0'8gKNdF.v";ӒW_C6iPtwS͇WP0@2Z@m  6 3ba¿f$wQD>6(0&Z^Ѽ"9wr=FXȭ^Q 3eWyD\-;c*,Ҵ2ȇWSQQ2ZXWXSn'3* 5%L77ͲUrfZƟPlFL޶dP.2%Oc=yu@^nN}ҳ,8pd2=zw WUC[ \5o%9!ʫ*ܶ}{B2qCg60:P#YDxYj\@Poa؈mO4Zﴐ6ۚ`C$.hΨz 6fKFp=F(@4.[l_)(K1W: O.9sCaJ=;h*RzB0gT?^iwI{ёbgф6+xD1^-+Y1cL١iwX^(XQPV$ps(Y؋4Q Ҽ{@E'G5\:C }e@T1[q|{r6z+BjS=\.90e,J{|jiie] ٗa%o¦ũSKKK-S{akXQ"f6<fe7yߓ0mٲZTΠ~7׸ErChii0P^#ޖGN xeC-XKKhA5e Q'˫hR}Һuy3 ~ 6n4;/ Һty5Wr*U"iQO ëH5\-Q1ʘJx}gznnoCzS~Q%F^UpjsJa ~ѴSɏ{d/^Z-}7bgo'͏h5Xe |ZZZ6Nmh_j9Ex; ūqEC^]G&.Cae:JM/|Yv1aFb{V*+i&US3l^zKXiҬTքR*󹼴R~#=:MWD}(iRGC,#ddm敖V&_WgW^^L9"*+c 9R<9#XqGxʫ7 eHȖrꞫ畁ןW'9P5209)[0뎼JiH Pk!o^1sxME~y#ڿd{b 2.;jv Ax'G^]) N~[Cn9"G'N>D+khN5 NEPaG޸r)Ȍu\r޸%@ߙn7E}Gi}#$z9rCV#?1̃e04hq6?Dz5ݸT&tF'n' @y;ҌC ̠midTf'ŝJw\#ikosi^i0ySa$vߢbΉ~%-º}gY/űQVN56Koبp(ʝؖi0;,V%M5=d(*LK.VϾǜQe/+u .{|8.*x=#bs@hfk;jŀ|h[1/i K1Sf-?lku8*dѺHT6]ӾV2zc@L3EeaDƫEi+cqCٸ؝Lf棍UʌcrEC 7W&dUWs\yZZZ7TNJ{?Q䑿 . <&ʫ)j!ճi 96WT$5†w@mμ:U *“tiB)oLPt) ʫCU=2XBnx5O/2DjF/mGD^-*=%$xeфƌ%!!!C?Bwցb'HTr:9,TjqҗЏ 4%S(䂞۰ŒWGMXKK?`>ByrtJ (Uن4b>D%G< fi[6"\DήhnI- q#%!+@${[+ *zgʫd=J?\KKʁWPt8|4/8x4 x-~…{Y\ E<`q'U ^a(*o@MZ-/f+ć/([]֜ZZZx5,&O/V<}$$$Y- DR2dڍS 'E,ǁp_N} BO-vRץ8(o;oUI.q%9mҺqr╰+" e/B\ȫ6Q!1pV| D'TV{^a֤0itð<ܩF򾠬 E$WV1KWKK뿑!J>df_xLutqD*6 @fa<=rg|AbE P3-oIҺrUNQPڐǴGӮuy%I{. =C ^N Ɗhz=pP^ӆ?I?%Wod&^orA}jjii(9Jd7 ^5euv«pJ'ã&xk丏UJ̪Yl]z RKKʏ?U yL+6iS /AW_'#IT0=.lNR?7pi172tA(n憖 !8ʁWJ˻xE6v JZd6 > jZZZ7YZ@ +^#xEa4՛8ŹjJ'z 켽O^!OI4#x~b+)Wd5֍Wx^(~0-ŁW=AT+^ gtIaL`Lv @ 1G9 ":ȭrm0TKK+JH-vƫәx t o@"a 3M@/ɈaQKKSxeŋ=mxfC.4^ӉWB*98HS^j-`᪅Uh[q4ûVhMw@1s4~O^[i݁]ջ)>N3>Б"n΁W|zL@\MiC S|`46DV9/^ ^%6ˉdݝk){GlwPgʥ?Npn6/у(]/=*W/Vx&4Xڴ/i=?7^x/C0!7<= Pt~ Ac1e!&`_ǃA>x[ǃɚ!Ű Tx$ 7Z2ˤBfKxN«S֩!!?^kz䉓}pЃY_;U0aU?lӷ8+.qס2ƫ}P^ ZdDloī?MUj+xN lt U(?̶8ou|j>. *Aa /l4F2A4?k`B^`a,ڶe)r/Kñ8Gkg͵wAo*u ^E͋Do!t.(K@x|,\,Fx5eˇ3x!{^ U~2+4qj6{a{䣌jQ˖--!I^ گ{xS3RyHto>LJ~n.iD\/.y2eKD3ώ|c_P#`^ Eƞ1lK^P_69ct}j<~% ^@pS+U[ QyG2tAWw꟡Hy69ap3xuuJ޺>A?mJN.YOYw\9%[.O0k؉U@"ӋFv2~onf㕱V~ud$^iiȯxy?}U1exͼJ_W7BWZZ'qwp>*@q׼>ҼҒ:45f4n4njݹ7Z--&Ņqd-]\l{w>"TLW̆WB=mwUz?x*o* OXH򯑞Z;qV /*`У lyzf+u@~Y vNvXᎬJ6ZZFpL LO9|la'x-@zL`Q\ڇWI@v(TFݗWG ?Q ?ɢp#PG5Y`˷]`lN]|Avl­ǣYf@%WȎW"ʔgny'2, (?MpRmջ`oDzMybKrl5[^xxUϳ K 9t$I^r|+y@3 '^D}3ɫu]R%:+/xy *^%}̫*+G'V)WNEqH F_*WmٖVfq.*0KEySs`d* 8 _78W GӱAYxJN4L%^P^ Wye~Px^S%0e+Ly^`fǫ09^ #e@͑ Uz2=O J0sx0ʫn9 w,ڍ4Q>3C`]z~+/Eϋe{IQCNH/WQ)+P$L;bw]6xURTrmVœ-h 'V/q \#!i(v9v[%: : -qYFqoA^g0 UmۣW^=.` y%iZ3w͐_B)տ6_n*ZY|~c?(y5t8*3JڎdF^1zɏ.%BtxY3|lu2gsK,!K^5!o1%3YzX [GahieZC:[+\4(|i^ <7[l0' Y%H^Ņ'+y&Rtᔛ^ Wu|p5 BMZσ6+*e?\J pNU6ȫg2bY8WV+W$`btxEIdU1P%"5, K(\VU=V۞WIp83iʉWdB#T {rb%J?-?xEUkǨ+)L.4%fZ5/kʫ7\ P_tq Xl[kp΋{KL+bU-O:mGccwB#Se-7ӂ.ײ%{[(q>#"vm򪴺:,yڋ^x5i #y7XVClx/aLIy0^ߥꭡXC>֠|b \.α!|3*Ǯp1U,`wCջ9F,Zy +-̝kCd^ B:xu2 ؠO+Xdw߹)WU[uAkƫTqifVq0ƋH^' Vw-@@o YV5^i\^^ G`aL5'՟-[uTɓd^͙<-ūw.rUxu8@쉂|uh2boL}@Icx1zxsIx/«c Kqμ Kh/V^ KtE krttVxEils?rV7ϜxK|~J'ڵkWvnEp/yoYQ>yE4~Iѡld.3gg+CHmw_j9M=99#bɃm7/33d6EDl~y3 "HWG03u:V7ۋH8FYVɴ"[Q/~PC2VvG.^ Y!+?9k2J_ۙW'7.}i2%VzW>pʦn7s9vKvv ,):oGqhZAL%h)vE'.4hjoCΏV^aEԝ,::o|S~?7?lXko}͑>l{윙?fx423hL(ռMuilYXVnڥjRʢ|qT.s{Ha5x%Ͷq_fW]0v|~he%3F!%3HAbRƏh! c ZC ~HF)L/^- ˗XcUuP/Sȴ<^5sFe)KͯfͫU%?庽=e(ˋJ7< VLWW:W9ٸNX˫oʫ ?4et(*$^}Ưd5*«C(RC=>upp2,WI)3!U7w&9:d~uy1sylS"ԏK4nSSn U쪴lī-d?KYU&&&% 1?EƫsUk*Z -|sk $}YcxLHH4+laGwW~, Wgb%$EDZh-)oFWp,BH|bڥ*>I~ rb"Ƥ[%ː?n+tQV;`=Lf f"!kQt5nOajfF$@A} yhW7ΫKd;a އL=Aɲ- xgR-c?l8S]G_0 (vjҹ{sE do)AW^L#Ac*D +eU7AfsUk*W%W˕7+/KFB)%/aſryB4nO ͞x:דXej8:seL O>Hx#W ]ZxS~LynAšf*Hg+ⱷd~F $7pv@%% `὆3EV05C ȑW|9ݎW"# 74|<^C W~1vweϫ¤(~){j!x%0.IȮ|1#W}K`b3dbLzWux&]C9y2 Pap!s;]  1y[M^{ yCe'8Bnb'h#K[ދߡ§>M^$5dE -Wƅȯw]c޼A[4ltna:!&]l%8iLr4xYŗ)«25^ItPfX#䕏d3RT 9<敖~p+lIW9ϳ ᮖ+7樃c^ ˀWH9kā%Wاu%EkQ+ _Q !pոKiQ4JF+.n}Z{3ռr.e8|OxUUz"g$mojX@ ou^Ȝjngw"V) Ăf(`rl'%㤯Vnah 0w0Y0yr+--o^}ާbД~1UuA >.K e!޼Rl$d}i+E?Q+?W>蚆` Vڑf4+/.ѐ0?.Z("U-:y䏃%(rBT΂pC[[cͫY{N ^+W U)Ӫf_.+J^!t ta#؛ŗx%K^~|m/e85XB4 Pn))2HTGĂ9*&^ᓭ8  W4=xSK R*|ة W5x~ze+|XUCP^ƓxEכdw"yn mJˡV+BNyYP^ K>4Ec#1BZ^GB`Lb,UqA3WS@xRԼr-) g4oURV2({ 9_^K qm..A(+^Gb>ִV2dzT n(:]$t l7,߷Wh"ce2WZw_a mq_o^a8}hZ䆈q3VsI9D@xEײ*:]X~*EXbYآ`[tP|WK,DAJKˑWhfىWiW|x3I:Cy.*2qМ4; ^J; ohˮիzdbsWNNv)~yu,W#]4--~O--Gd).|xEȽf.SZ CB7ϫ#ʘq* dDKWt نY,+c1aEâ<Gr,4^_" <`FDAvWkiՙ估|+53]ur;m\{bRYQn.y< OYo4"S ir+PP3#?)9%/׫.Y &Aka *JS `24[Ϯ|FCpS6!.|/=r̒Qt2 f')$N#Tjpے&%?N%H.U;2W܎s.d u>x4LV-x5^1rh cMòjdLGHV\ܦsA0h'9Be8W놸Jfg$ 6'KʹdbXb2Ey+x9U"Gø"@Z[Wk: .@EW#H g^i\UBԗYϟ4q'j욖ST=x~[[-[T#шrQEi!Tl9l_^1&7Nv=;ݭ)Jܽ-TtPPt%'(4RbI<>pyRPLzhc-.ery<%x8;XauO:g1`ZEʹ:ғ@g@Z\/]:5 Da7Q{$ (y%8ݻfF舉ލcn~aO NoYls ;Vjm,Y;O_ f3ky1nlZrD{#xgJZ?jWrԘ*o5heJ]O^i]-pZnIKKJ*U>7kw]KK*xV]&к#jXf?'j}57RWh_Vxœ]L- eFUaW=4oqxdm6}]NHx}go(º]1#_mZj{IݎCw%vZTˋvju:d&u~ٱA6x+t*,🩝ɏF$?H#WHk$@Cv;QJL+㫩=79i_מ)m'}9@ZV7o|!ϟ}x2?j41ow.ƵEX6EMe_ycc V`kf/?l4mNj0?ktHVR)ώlߙ#7&~k*b{7U&J!hwYґW[$=0:Y]?\MʅbbZƌ*Ż~P :k7yB RV@(#7Z}oˆ`zcP6fԋ)GV411 N 0gcb0k7OCGXNu|C[4Zcx}11y9vQW&W]V֏yj;N ceJiN:` }n_3t" *Rq_UxQc6+ToOEݕS2GۅP|&pz4*]0R2^Kx=xP"YWHZJN<.S|e#u]):JW2yYEu@isF[U>2uKE"w4_8C9_B5%z5,Oc__;Kc;~WG+Q0`OT W䧒iH9>ZιȡW\죯?a y}ґW8܍~L8BsīJ9,B *´m/GAr:AfDϱ\7R3fs+פ.2fNHxl(2FJ1WwBIj # IZ´ڹ!@xu9w|2W,G&ѫ&W!ۂ.OAq&N+y^a 3Յ.]N"LX,0w݁Q]]:^D !t+R4DEPPRl BPA*EJiBr͛w{Kffggg7_޼y%u!+eKdՏ {3W2M0zMY=-*K}SG__ $ek|<Boy-Xm WrrA#UA Z%~.W٨SA%q)h~ Ukiy1O _ <O8/xŒx Z)֥"b=Ěԇ@RSZ61x9) + -U\FeZ--K,Ɖ& MGZ[fmd|ګxA*/1|Ǘ@7k!G>ĴKٕ;~ W+F(g_y &E.znh R9}XJ%h1E~6KG҆?_ŪE[8NNk*N3cfJp/fH+4c*"ѐdj㇯؎/!_틼YCp po f)<1bK/&d=pCPrG" J}N šk`ySOoTGb䕺 O.h]ЇXrXA+YYeup(- 2WH=Ў`Z?|ucD2|UigbW8ۼC 59+ǧpj%:4 Ϸ(|UlaP}f!*&:U2޽IuCk,<|Ւ*YM-{"_iY?1A ?3|ep3b .';vp|C)w cLT 9(ۉg[ Qe q|Wձ+[4ӧ29]㙡%Wzp(vu.[U}l,+l_`(kز._͟D~Mr B}O|쳮 DOq"ݎ71K\vOjp0K:*¯=יl SW4TCgPo ^l?| /QVSNjJQ) şϏ!>_W؊enRTEr Aj/"N曇 Ƨ3nsaرՎ{Bwf?7s|0vl+Wj?F TStA?)yMc~pZk?h ˙+79X~5?frw [E]|"O֥y+\GFtE٠(bqd cJ7dERt ZIK>@6(e ה,!T ;A[od:Kd79#XO;ީ`*r=N,Ғ<~c>SZGff(4r7]2 wZ~JNe!wL);2skSG\nTuWw'[}[p |vSd?TJolhZL$boxk%_}vcn7#cSࢻI+GIM6xn7Fxnv3 5Aui;Ǻ y7kI~w6gu!=, HY .i|5Nh2zi (I!;R@}uϹݨzvH+%] bypZX\|BS@aW-vA@se6d`EDg4$Bd=a;&箿U#LREo05dL0a=gCe4VcI}OtA0LۜE(3 E!ܹhBM'O?]va뀘\Y1n`S%B@Q3xQ1Jtj<*Mb̲ $JQ87mPW݄Sx3\r.uHثyx/eh~"s~P$yݯ?|A ^~2|e63: x-ΕuNC|0~H79(]ZKC&ԶkCWN5}cɛ.xko/t?8>1`)v$x)aǼ4嶿5>|ux[`qG |3~_zʱoyH҅wx7n X#Vh7zz'`c>*k{Z$RgIKSk;q7oQOS" r $c]WXSbDk+<ն!^> JWkrcBf5V"Q17 i+`d߾ M[둯<0^|5@|`+<|u5yyrE馶 پ嫟D>LWs趤9'>_)fzmLoiUdWis+ơmփ5ANmm|A2]'|7 \6|L4|uh}WdԔN޹4G Ճj?ɲ\[!Z\xU&Cqk|w;㫔LľpcglY˃|uRH.]縳o .Wӈr=`E8P:Nՙ&%MA }gU/C~̪h+QJrT,@WYP#,N';>_YW74fp_۸x1Fx;g!T[ _5OxQU*b44"Ӗ8ڲWof';{~nФ RV̿|HW 4!Bu+&?RD3P` mնazN2ˑlNP)Rt0?G68b4~Ս ;vXv嚟 YFDs=+D1jNF*Jv WA|h2<9"s`kCo|Yyf T|%۔2 TL+B+ը",1OY[.͂ՈJ6 _H[3@kOz<~,K~ OWNhf9D#;3^^4 G/Od櫢\0IٱT)dU9A?rB6QW(&:Feld~Nn8iW›?yS94w}z7>z! '0Z=P0FY|[晓n_=zv.խ7_UЗ]$r d6IfjA,WAw'**WxXu"k%J5a?od'KeW6ji+[܌\1ng?C3mZ;p|w+fEq;iQ_Ѡ )WppxꔆVI6*A]x՛lhEuLwJtZxZο_f:gEWMvVkd jAl,+N{+P7_i,UJ~ S"4+Lri{oMD rpW+I)J YjJ" _ `$Wze%53 -$O%+T$ŠJQ|[X5f~ml^:vxI_xHӎ+Bʋnkc\)W |5Alhi񕅞8+UuҌ*.ʩ+r-VuYQf9L"P{W K܃3_HZ۩%P5os2bZ~UYݣ;& WKH)jWor3R\Dd"ܔg 2f+gB 6|ip"HU WxΦ}C݋V2Vt|u;l911Ԗ`jdd$UWS::HP* #hj.=h4<{W |uyTp0 , CZߓN@z4)8 K9 罛ղS -!G 7hW@"HC>3000: 94JWC$0C?%ZIv"rQdK|x^QC.+)U%K 5FTF"++KEW#(JHIHј *~;nOM$8^n ZqLi25Jè62Z;ļ/?)t6lZY*ҹn=쨳٨{^#`Z_|A& TJJ>|EOQ:KCe@ωW  */5nV0|Eam+|u_o ˉ WEK4z|D;<|gf0P ұ/a#he%ԾlN=sU3TˈxӞx "OҁF!<w+@ 򟦙GiM)s|X,5Ycs*-2 zۊ)GrkҼHw;{ؚ!lswǣ84*>c.޴3%61D@g]mX)_V.GuڧLE^-L٘qf9xfAؚ*'11sR$n8_`:fSL'U.\SdG?ϫc*&B# ?ݥ>ƅ[!ULl BR~άY Zj?HhV 4 QM1@sN.}ch}&k#eesGh_}-2IOwbP^nz |x\Wlc8_Q sOq̽SeCnAMJۺ+Σ7u=ڿ<횷[sO8$bw+&t|ek'~PKn[kY1y͔nC O5#co5ak)̟9˝f\?EG|ȼ(c;1 !e`ᫌ?,?x%= W.XIpZh!]9ɧ5工?Bˎ[.ꠑ=}9O}#p1-S 4K DrN`7ŵIv%&D?PHqTXfj7&e׹oӇNt~h|pg \2m?deMJais+b&+a.toBhsk6oK.诚'?[Lǒ]vvFKe5W ܄Qw#k|uXrbc;03-|K^}ǐ_lh E:af,͵.'+ɚ2n/&P?@6O*Qet/ H+V0p~欬DKRݩmej/$a&;W%E!i9㜁11y[GZ^lm{A⃚j >@@Q%Rb8;5ei3_s]V\2t7([c DU%{0Q_F34D̮K _\o ‚We 2r'wgg@j/*SL[d!g EhjnqHpJ݂lә0ϋdp[/րJ[WCN|S1w?,;>{Kr [Ɗiإxi0MKuoYL65|eqx췇`f=뻸Nml]8q(^NO.;Sҫ*;{>@=dz)Y)v p+"egdO/Jr+{gw`K?BMbVQoU>R_-Q0i glLWYK0+}JoJ}=#U:6WdtJut+WvK< ~$:H!M$S1t Yb`ztjfQ?Do8UsY!1CR`YCAW QG0`_&ztAVy L WrjZ i8{ /6 V6W}׏ՋWz nyPSOfI,xzͩ8$_E>'lsJ RQnA5!0Wo>~ WYʴ:+)+T+(.CH/Du|kW7@+,j $w; TIScڿ1| ,V C~WXקD%$fn uʵ2*|u,;?džC|5_a-V)'eEF٬6y}cQŠp"` ;Z1lq MgQ5}9Wy3>ԡAy2Wl[` >V=gE졂C| -{"5 jz瀍dj̋wV KӧT+Z@JF _diIu)>R[™pg7 NӰ!ő"mM2:&TŸ;,_u'b]!rB w_%`l; WY&+gPV&THI|) Ңy1_Г c=diՔYk^l,ys%8O&(olЁ[Yez5*Wf/ eXji.x,1. _da&z˫?'s$dB"*Mm{W!\g:&\L$f,?KL5u~"$uljK0 6 eʬ#!TH t]?n"|vFۍbvbNz9TUooKQ`>aY{yCǗeIO=  5>Шt@ ^(On^c֏\ nn >7 4͍12t\U|Z97@x.p7F_9A2000Ȃ Ӎ_yh5000k'g````````````````````````````````````````````````pU4E`hlk3=fzG}hÞ-~  $:o9ɦ /=ыR'79׈fmcmֻPC0a4Z.Ϲ~/AVvu&fĸ01j b^/7'l5iUՄj:_t%omAoLhZ_=11^</pU >&:N'KZ,&^;+l||/=9{׊1r,}!11ȐsG:^hALߩ`rW7'^h3,o/Vmʖ%Y.{@Z'r+:_uVKw{~A+>h&5ljK.Wk㎮<ݠSuWe`i\]f'r-V^zo%20q0 &dmwӀNb#55\t Ƒ^O竏Iyqa_(lWy1=_TY 4GZInwz #D"0 'BopD~(Q͇xpI 房n_Jh\ _|D [1O*Hr_<7wo7yR$|uOsKVW=aK} :zN|KV 6d%$1WR}#Le9OS|n'H5車x9U2R)|,؞obhQW*Bj0ZՈR fN‰Ww~mhu GtFӏD n,_{b&#CG@3Ex48~>25}{jLe{|;8U$_e```y^S|QP롃嫝 'bWtO+>/_Yopy -T+2ڿC` R}@~7=_qXN8\W簿&^i+z~+}cя!Kz|E_氿gKWa`psc?xQZ9))<\|B::3oGZޡ?U7庤0a+螐_=FZQݞ|E_IfG|aN>zY,{*B%us"cuhWqtH{ѿ3_Ybt _ ˤ,_ m(M +%I\ }b)MۋV"v+bWhdN[?1. 4g)M'zsҡ{+*BkiaYU_ .I$嫵Z뱱-a:Od7CYʔw_qj CtQD:P~7 KY! j|ԕxW䠅Ӗ{v(LZyrI g4g^(= ,`E5[´CHK—)&8L"7$ba46jڶB4HرcKd"Pe;A"' .A^MǩWKB)*ݡNYrm|!)į@] @_V4fҗcx%ajKl[8Ao/=ck,_mph3l)׮_:qK1&Yq;MϚ㧭+RE=.֟ӲjvJA s:$I4y,$EqB[Tzyϋ֮6R#=>}GV_|QIdF.䫳qf&FKrTթD_W:R务C9mx'BDpLձXBNzSlWjz;;?=B֎@{-[N`_"6wȭ@*J Uoni5A |>UJE4wVs DH_kx =)*_3Dl,HB_?{)vڻ&?dX\~Fr+=A1;̫~%_S̽x*G rWpozboѽQ WLJE K2~"e6,Q"4"őʃNisƅW VM gA&_8~]0Jrwkpyڷ'-Z9_Ѵ2Qu<`+C ce烸F 34ICWET!3OF)W]䫼70`j%$[7 H̆P~bkt#^|Z* bI|op"+"8GL%2Y IŶ:L:D&ot'\y9*"ՕSHϺ1Rd LtB?BV](=%T ۽A*hez+t~v#.bAjY c@} ߼o6 zdz$+)HR `C{l 2!3Pj Kp$|Uu) \VNQYdjUda8ik9J+6Z".ɹ<0)wQ|>+ `ہҴq\g|h_hH~} %C^{ʐ柯ƀ/x /EJizi|5*ޘb%*8qR30{?D+v#|:(f}+Z𤠼t =btNդTķM~=IEM,$ΌNgvL <ѤE9<`<_aHSDs @C }p! J`0h'qt,MZSUJ(J Ҽ_]NQ&M z P:+t&먒|T27mԉX|P~GL('HjOeܛ0[Jҁfߎ|i ~%0wŸIrgM b+ { տ~nBlr8;@Q|IǗꣳP(WLj85mRMp<39VieֽCg=Wn`mAKbe|Q}țKSLO n(뱷P,M+LA30E;&y|{x|i+rMa:_@ tW[FSx'hPq* Pr DE.|E~v36@N]~=޷MsN2{stak||j5=O*-1ctF$nNބxG\"t հ >0^Hi͎<&>A)oe]hX2KDq(R@1xCM:U3o2ke|<B,1L ;bxt4>9ꃊ@9Z LE%&f}wZ#H(_A]t5dgp 1q+T*~Dk/1㛆z1r.Z*<-a)a'bƶ[W'&xT5e]h e]PmkՌ47`rj45LjH|HeI]my#_Bb'O}AvyѽNvU>m[0 tVO ?)oƄP~dKߡ-ЖIa˽1L;ch\0V4|5ہTM#qxMP|#M*cy5#oS7`PIARk,gWP᭔Tέ9V3ad [z[n8}BvU$UwzgV2EBz6c𻿳 _S_>wAN OKW_fvQ)?]߯ө}dGſ[pb*o6OkؖS[_w _o|e힚5Ϯ N'D}ٵƕ䫛np{E!`g _1som浝e?ՍZyXpNiJePjXM=_#wmvgG>w|j@ǺھCV'j7o (&lc}vb[?"`ȯB[rqYKȇ׮ >;{;;w{unTWXvZtlw϶n*:3>XYtOxɝm{4竤׽lS̵IʦikSxs uCo1m[C7_{R==b 6rQړv*1ǪҔ[._o 륎e[ŝUSԔ7vchjYXgiuq8M~{Y[˰Reh0>cf$||b FɻXuRCM!F(?oȍ*T<*nu5WrwWfB79Ր{ ֐J~"m(<#=^sz 1X}exqx~њEEi<-IUH{W l9^]{( Dg;_afSPFMI)6, inPZr_WWo~3rUb^L[JҤ<6Wdߒ]VzݵtTQ`|iAv>xNꅄ9ErPAWhM]ڬ$픷H֕Ҏ Lv܊ ֥EAe5/&VY"dz> M r{qA<ٔ4*|lVcp&_*7fb!ǵ̀eD9Qf'.xB竍 Crre} ֆ$!VgKɞLn'+{#_ g|e5ASeYq1:x_}j- 5￱2UQ~NX,+9Wkw(F&]t B`OkHQyC Ei* JrbZ-P1]S RXڷT W=ԅj!_ٛ+T4u]e (?;ʮL/W'5L7F~lj|w|?J+?}Gڥ|%"Ye$ol*R5wՕ|רS^2%v `gt_A0EQcP]]|%mZ} vh0r}ۯ|%>;PƷgW1V:u'ˋ|jyN9PzaaWb Z_|l}H%%_b~+{uNsM0^`l~>_3]GQ+W^&?V 005+ʴ/{1uhH`nn7NǧpKRO uP)~t**gg&3W{pFx@U*ޤ5VV ЌoBkE{0|lJ;Y#K>/R9zǞPI]UO(#ewU}E Pdí R<b& D3_if`%B2~r$!" _Hܫ)J,6?IۅZ<:u=ne#_PZ)ږ3WjW*f,jʻbY1DQNW[lX0|gԸ=vɅJ.Y }QB.e ug2+C6DN,7A_'ӉWhVTu., c|Ci'jy3Wc-UMm %TM>MWcI[( (cq_zLY_ED _ZoKػp[|dwurfj _?؅ƾ4aWNڅrlBN 2*=ߟ ײ K:%2s&0|=mmP|C~2 YPVl.۳S~#WI9IiUzbi4懯BR )=[L:|;7|~?nYǎWƎ[ȑ3KմcBhρT5PgF".>0,w Qё,梟uMWW˺XW*Rv u\_Dld'LkŻ?;YZ:_"*oF# x2d(B"^F櫳wzE}<]g5\׸u)?ZFq_Fv&¬АZ{@MRQh.*Y _t}MiIac>SZGf>n[̛.;-?a%'v22BXx"o 78ih anPb%GznMrjp;kۍnd:vF5-UK@@.Zt{E~ZW߻ݸv3Z1kܤ>&]tEe%=H2qAK H2-eۍґt)<S7#.nzBnwe0Zgɢu+%m* _:)ԝuqunU<=54jd2P݀-hlvcޢ\zh I {a$ȃcyB (͓Cq<zrOkN( J'QC|Q%LoCًCs=Є6x|^b ӷĚQ(I'd>r$:QT  ?9Ҙ>,񉶢섲E\tnF<ŕ'`|@(BE]7v W:lum/Q!伭"7fZ9}IWH=r:wkQ>[T ) wiە=f.SUWt5>ۅbrAdŸ'l* xݏrQۮWkWFod'""mu)<)>zOI~n9j:%H֩D)"^]![NVez\?rM_lV[q0|e˗/sksom"+[eTf=n,_x2ԛ"MO^^XR}gpBY k=gȶ7z>O0fNRpcxչF̺._I;|t7ejW||'COہ)_޽׿)|WʱZ'!u16@k7XyPż%Ocr{DڬguW^br>)=ZQT7im#,6Iؿ]d֬"GYԠ{YZkwWC?N:7NVGs-jsmyLL׉o!pduAB6-@a"p`QLE[UpA|a(n|'j ϔBj;d/ WTz郩/ckQL3W{KOCAΥ 2~S<dw-'y4rB~1b1FǯH7N MJrK:_]Dj+?)_E~HmWm|EdYDP*JUhK1pa 낦<ӌPU"I|u'D P~twW'SlY@AAE |"#XbÚ8E{zdϐFB h[x=`x̵}ʲ.XE#'"/;(7a`la5 | 5e Ҽ#Pa=UKR/^TN3ȝ4R7t0')jCX) w 4Ǩj 0fN.d9.&r(%UJ84B9j1##_M'r*$̿{R-51׸૪ZvD-1ӥ L?c|q֙ 0R)3EݷAF25I/7W j,p*g@Rv^}R"sS#_} 梁D̞ 8el|&604zօy B!vڀH> uhIi da))eG W҃bXN9ְ8x&L/x-2ʥ uSҚKA77G:9, 2gGk|uwu?՘qwI$v%@#]-kxQs@4@ղϣp27>vJ|<7RޭP->>ru|<*?E9LGܲm ! 3oUx Oc2RQf [_[k*G"%=/@Gh[IE w'aĵŷ(Uм,@e|og}J{8I 0K`kYƾM z>gL;5BIEx~ W‘ 7@mbY1 G-\+(rl降ߴ۹|^Dh{^uJ:ç hdUgdB %,_eI200|200|20fؘ 2B<][\|uDz.Nִv\\j@zNɷ&$܋jzpʀGmihmJHh J.)KkSnVHo˺i?oHc~$54i#s=R:&<4o{s'W8޻l``pphNj"sKO%x?kKJ Kԉ;u]rxޯecgCg".W/H+#)=yv-JOVUwviysscgϜ{sWj޽vp95 Ƹs6ww=]+v?SD@CnEE32pYyp R S*+%R]YW2rֶpX'r_Ȣie3|}LȺ}}ͫjYӶvWSQ]jK*.w9st^U[m__ Jm[RTɄ[=T0;|FftȮyLzfמ#ߝ+Y3?kݼ5,P?ԣ6&f]#Y'$TΫԛz0~ U+f|_4dݜ'oʯdWgKu!lg Gn͔_V[u\07V8"S*X @W.DJ,jI^5`./-u=-6+7TDGyO'tm"*uwO[¶U·ܰ2w*y)4/Xޜ9ux5zV\k嶏4/zH-T +ؕV^碍Ez6k3(5L:ں9sKuִ~ʫ=UmY; PG^\sW4V1NeV&|i_}u^3twLS'\Yi) !$>)נoᢔNWKղhP'^|bg5:j~櫦Ά@OϐVUxnT)|Cv3O&ڼ*-G?φd^-L^tYi͑Y:J^9NMқLS~!-O}$;&D4h+|VenT6Qv9h @HR$w/ɫ;d@]7ۛfJ^|kͼiS5+Pٵh}LSjT5hgD9/:Uo Z2jtQ,@]%k#~f2S_@$Jjn϶Ş$; |3}N^UV|ɨo–2ikw(y}TZnuwr+ڼnb7(wr !W;S))+Lx|J?hsv^+]9h8ʫc}@օ8?p0+Q;1敔 t̴ ɱ^vӻ'K2.WGg[x SN^D?#,RT+dVihzyyY㳑i/}zo Gn _޽t R2K͝{n~d^SU+X?ji+ɥk.\>a{H:hxɼNiWjsm9y%gM)Tjɼj'3zU'u3զ m.rE%>m;tsBh ɼzH GMZN9y%s <)Uy%_r[y5R9̬pDꟺu֮5'œ*w+h ɼvʹN9yY9|=LŒn\Z; `3/yLMNA["agr|S *+_N}u2F|&o{G9yU#_h+TRM9pKךz":Lq^S*ҍWU-{<U1dtGC&W Zhwug9,Ui4g> ɔIߦأ̛[¢iUPrL!W5'V~dӓzk`t}n^Rb|V ,ȩdWtGO7Q Mu>hޞu@,'~س> Nn8)7Lx ^QFW_TfBT6y,)8yU2ie<敿H^ )orn,7&׼vvfV]]GaX* N.߶RU1;=xny:7X/HJ 8诊d&Y]tC26ӻLNฏK?zjrߪ[C<:qyɺ@3xyXy_[y<ϙVxz,O+mvc<,Bc[U}l-}e Jƛjyp{Ti4E%Bȣy: trd#RP )U-UrLT.(O2my>ZcCR *ݖqئxcX{EasQVsTP<(> stream x[K6ϯ9iCw $BNyA`v/Q$Uɒ,l6!0mIV}UC,> ,欇Y ۓn4yxeU Box﫸rQ'quO0l?3Yս F ̳-㠫`X^֓,<󯅂/4WK[iK%Q?Oo?=} - 6鈘e0OK'{(7䤄XI4'!XXY`FqI^I:M ~VqK8b1 TS{@UMTՎQ4* lͳW Ʒ SȐyE0y2bFSX&VW鬻msО)xڝ{\CXF(|& OɝVL dFDe/3wjeQ\2Zȡ H˘jǝ%خH"'em!÷eւK /KmI xG*X J, 5oǁ2>@lyl+ {~r"*3!+tQkKN\ȘRBveǰʔ3,Kdd"Z<*w/0yl1x
IK> IN1;~H$ \nI K[ 3`Bp' M>@@l<k%:6x%:8LIpԐ[)U:e6Tz: 8mgiEܤO[d3Y ,xXq V-o9!XȆM2VvsuԵQ" %W;I*khYx>b%xid\+/GHтTXP9! \:uw#@>_ 3S$N=6>­܄h&_w2(o9AuxNm,pϢLʷ#≯%+Lx=^J.d֤ i;JB0*-c6XFo{~?JUADsLcC4MO.,m2X 8.Aкy/~ٴxMB텚7<2PݘaՈO -Ʀ[ Gi*`JLNn;}^i{ƣZqiٲP(s⧿2LZӂeKWӃ,?;E]C^=f܂ ?PU*At*yv_)o Q.Fn/S\9%DD^>I>BFeH]k zPۊL䲟S̜&ms:f!Q0:"r)NO=wLWJDD7,FhƓƮ>ú[OkwRٖ=mSS4={1]@8/oՓuBsmI jϛKjЁG>xC|n]sNMk=Jz` SV@)~5 $vy'bɅ9C PB<-ᤂoSvQcxlNݱz_u<>qttAJ:ݗpQ®6k:vHq91; .YQ*|߶mkK.&eT\]klgPhTh5:KNYRz{9 nK2$g8jևwKs;="`-KDq;>_PѽԢ1ٮL?W$A$jx_+~rqo*L/W)bQax9J_s$#~ {%M?545tu('o8vEBlt ::ڜ)5(]E7m˾$FlOr wϋ…&(_fϮd0_CXD5:)ۖ=!,_a5KaN1C$ǭ-Fj3jMMlܷ dŧ^Vq endstream endobj 14 0 obj 2447 endobj 18 0 obj <> stream xێ于 A3օLk=rP$EKnL鹧s3:wx77*-5dvCMqwf>7s vMtwN>7syĝR?Cu?s9ɺSn݇..1f0͹H֝t>O>`ˮ8?/eW+qDZ1t>=gK^_ՙՋ睽-Ujֻ.?K7h4C[O>7%\_n۹tb ,|u=oi٦rWzpW7d(O4#ߛLҋįVah&RjيvA+x12޾nsy%0x`sFK8%B'I;Rhb+$&&3}Zzd+kXNJ^^J׽N 1T{a0x6WwU?Hb喸h_ĪGW\Dd&~C\ɤ"M*T[1/ōdVOL>7f?Ϻ7-,v:xrK\}(dc؞L6>dQӫ4t" ש:aJI woP,|]£LXDYjsz8\9 tHOH||!+ҘN~.9Z+S >/t`w"kf-Xx3f#K'(FzRڦ`& \b(M0o2.%FM< ro0F*S8LEݎ<7fxY"U̡H|rK٠:]`?O41PqmtU,ݠ4Jm}t;}FYf`ڣ f3d&ZXKb-ښN'3XzBF\IWL;E s7[m%D޿JJ{S(Rtʚ!9џ 8Bdt87/ YE!=TP $}F;^ճ EՆnO9LJ9Y=Ya]#qva"x ӈGq*իO|n&Vd:ZD mxC.~xo?;WQn[Eһhr$ζ"Lt)An)z\A+R |g`+h\Wm:tܞ\v:nSWϊUBn`Jhiӻp0Ξ#4͎)}{-M)7R޳ʊVg%-=mv:MYK+Zvlg!M8O: 7; ZҶKNx*+Zض8{ x:lۦ e..XJ!3Yq6$aCunvL!o|o ,s:7,_(%`Vbq;Ջ|KNm꺭:KL }2'k,ݠ2kwg 늙_Ml,0+8+:).U'1ojnCz+fL }2+#l.ÈoՍEp\>u딛hCK/ JJ̬h΢nG\9N c܆,--Xu8)d$=g]+"l.9sc!M|\s>kZh=c^Z"%lVzsqVg] SHz ::SKJN'm3NJgF3Yj(ɋg"qzo .ÔLn)kgv K*trJrO-ZLԒsA;'kI #mIih&K %yLVE/! i/yW64o+N*$YyEK{Oc("d-hkzjLI)fZdIO{] ea4 @/D0Ѷ00*YKa4 ,d?պhkLI)fZg*L7$ޥ|].mx2{wJAקĺ&K;JV{hԆO0FZe2Ѣj]]5Ye&ӱj3fYqr^aCuN>ƽ@ē! z77zۺDVsqVjO'qwmӷnkһ]$xjГjOYqr^aCuNB__m.rNl¢8+z ܸ;q۶[̂]]5.O)qndllEK7(+ 疞NB`Ȋ!6後a{Z+؁9Y8ۿf&u]D+u[xu:-\d;VH"l.ùdxz"羌a;Z?Z|!Iiݢhs6t&۶`WnMbtlE[DYqVaCu-=E'CJj(ZʢǗ(g/'%&p{-Lr뺈VK&b'0d4ubR.v4ZYUh]d*C <}p⊝т'vo+%NV/LT4muKwғL6j]oFLms&붯ќ%Yq&Xdh50@?\|NKW0z$^x-1Ӄ$ sM'_҂ɤ0?hsA1ty:"bC'6vO-+N饫48ࣿ?\isˊu:EK[Z.ݙ||Ce5:EM^g(3OtF5 [V\YU+qЦOɼ?z t`<\D\ZF xY$+r '66WL [VtӉ/"{zhr|'?(?[HKi/$>Ϣ۟?fc""r;<RY_=yO;x9_:poNYu:>** ua켿JUT*8UvyoAwnp{+* -x5wqB嬻 7** x57rB主 ErJ%z.bb#7pRg;&)RQdFχoO&5+6ޱ˷QC>xg#c,[\J'xׇlTcEaK$o7}{[YJh#lq)#+:UKh1, ?{asƥQ"3S$㔫Fo\J%Ot1_v~r؈78+UQd<SGq** <ёYqUb#7TE':/; ?NJlƕT2DGSeg)Wx#߸RJ浾Xd֜ϧYč6t坽.~Սiބ{Qa%6ju;W]b͍Zju-CauNEv=uWҿtses%GVoVannCF۸"u9̅ai+rWH3k.|YZhK\qZ "uue5'%ɼDw-w_Fםa"d&?^od {:6AYնB3_houfQK/J81uW2ZQ3ºWsy4D.̛ u~n[3DWe:x)lNIi!Y'-rq=?xuWdҹR -,=y4hVLLٵ$ؐE#$kJ#OIiTԷ 矛:bFC$NǏZ=++]tWi?vu>YQBKEkF 2EYЮ7]TJCRdNz2 t)Ws=q(s$'}~ ѶGú Zbusv]VXQKg9"e Uį"ݠH=ilnHYE{%z0ffNt#tKw3N ܛCJK]4pݛkຍHI2Rlnɬy3O$Rt?sldsOrH)0Ҩx-DOpnƟEu'1Ů/fZ} ,suMג=iE^D"\39#ݵ+֝8ۂ|bz_rNIx̬| Z΍Z(iǟ_э"\4vu7 -o1|g;sV??ɬ[]8ۂ|{E)>-|]'˶>H2q>f^ѷVHgCeU[̲ ,jh;svo#*IlE̚eR*ζ RdO۹867Y+b[W$Jz | s+{/bM si /fT|ݥD̬b,:I8ۂoJ]>UVo|Fbf3!׶Ռ xg͝5tQbFdֺMk̹"i\ؙatcI+s::cf[gѡLJdŦTSev.ηiY10x.ECm3:3tQbFf Wט'"i\ؓat3\Wtz)uu*΢C'ȢM˧m t׶Ռ vE ^W$`b)vXDf Ӂ9EҸ!Oci~xK؉.:I8{,ڔ |D=aw4"kjƌlf\bsr.[HFSJlNO>TL>Q{:0HVg8}+\W\zbťeR*Ξ 6.*&RVә_VW3f$`O‘%;g(颾Ōa4oSέqž)ƅNlܺ$XqC'ȢM˧m錙\\VW3f$`3*sHti۝ ɧ=R<(ƅfMº C[_t(RqY)vTY?01YQWĶ>K5Pn9ڈ`9l؝^7=ݞ@4.0q RۈV4?ʤTmAVlJ]>UVo|yWR]);AY=w6=tzڣ[J›ؙõu&nAJu1ފ'C-HSev.η o$fV>+Eyfus31rؿ;/gC/[g;sHcge9%ԺN#YsѡLJ$}Sz;ΘY" $r07= UŦhL`giں #Z}a$1#.]t]Kl }z-3u"ד芋?`V!̀ܙDeφ^$?hں #Z}a$]8ۂ|bz_r30Y"܀ס?hJΰ9$.,C=zp'әgE9[abP6"^zם^z.TVKl gS30Y"_{Z1\+ʹ+P)g v9%º #Zr-ZV; 8;$nʷPst"k`I,*Ŋ|Њ릷b4ZJ顦m(gSuEYmѢ)F#Dv?oQrWg|8;|+$'UVoqg]F]:qRHQڳV/҄X||sTD 4 "D9 LYmdڔ8͙$ɲ"EX4kS BeRt Y EHVsTV#_E \$+ KYHbod_eyˊeE>+=) DVqBikwG"Ƚ %|/x ?};w>%|U}E={xru= `/uWw< +w< +w< o^+w< o^+w< o^+w< o^(R9$n͵ ZwQsHܚk=xH87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P 2T`sT󇂌"Cܰ H87,@5>((R9$ P z(V΍!eacFTyݭaOsD$=~.X @A5GM68'CPMww?^v 6y7I q 'Zw R8qn~^uJ84PיbJ^kĹa-ٴd, f[w''/U{GqϢ޵ĹaqdCET,IAq9s{ˇt(2^Ĺazmn@^F ko|^ADܰofA ko{o_)D^~þT,գ[F{p$miNA:o2fkX#ް*6EsTx(h(xoĽ}O+4gF?!+FAG{H$7jܣ9< sYyO.Dv_-S0 EAG{%oH$U7U'=^% <uo~Ds\Z5͡ QnnH$%7uל.PQ|֜{=wr$Ȣ9c6ᕡ9nH$ 7E=Qsl em9nH$ 7y="ׄ{#o9ӚoӇܫ#o9sWCm]ǑH7IQ!~{F!.H$Z^쁄N~{F!ήH$B^ౄW[~{F ڦs$w {L!upµ3M6#So3#G.4Of~{F &r$w {Fב jfH$Ց h̦H$v5Ofs~F p$w {@ 8otlo(?8G"qGް@'f "9;}zL8oylo(dD⎼a?fީy2g0o4G"qݰOϟFj&6<ǑHy7'IS4Ofc~Fm퍞H$='f ROp$w Y 'e ^r$w Y9l͓в߆Q|x{8;}tvҨslbo(vĝw>:y8i9Rd6a:y8u࡚'id h_p$w 㤗i6/7Dλa<^,͓߆Q4}#nاO5'=Ms$r8 '`mh缤oDpÞW:5dHd6sDpÞWg;M_d6s7D^rÞWg;}y29|N G"q/a,Jry29|#ܰGVry29F=9{ {j]wO͓Q4gwϑH{nS =Gdyzg#Wݰ?ֳ͓Q4D^u\/qK_͓پQ4AD^uÞ]/q{ʏJ<=:{ {vuK7k̶6i;DvÞ]'fh;4Ľ=@% 5Of~GѴǝwh8{ {|K^۷ivOqXĽ}Cǫ^ޗhOqXĽ}Cʫ7h6nE⤣ÑHkoؗɫ>[dw('D^{þLUo'me[Fg9p$=*/|1t$U*/|<&2f>t$U6/|t$m6/|<#5f>g#87m^?]dw(\O#87/ NW'dFzz?Ĺa|}y2>q}G$Dܰj^/4Of{~7~:sy7<8&?s[H$ ?-y͓ٖ߽hs=0q$7ۼey2/wM~'Dܰy{e͓f߽h=DܰxyWlQ4+ +}}͓hyVWoCFx!'@ְ͓_Q4+<`0<L~͓پ_Q ,VC {A7x'lSد(zyPc+!O熽^َ͓_Q 𠳥hnkk5Of~EF[S[dy47lZ.͓^_Q,C COx-g-'`:-X'L9ܰ=735Of~uF[#N:ssa; of7k̶ꌢa3<f'_Q"Sur^Mdy+5^unk搇r^+Gdy+5'p-5<vr^ '_Q=Um9ܰsP< ~Smy"7]oR͓Yٯ(VT{[my"7o:͓Yٯ(VTES9qܰ 4OffX!SOqF84Vh~GHۂsa# ~ 4OfMfX$#9<6HNjy20"i`{k!↍4"j~5GN&G*ޚsȳaS8@5OfeX'!Mo (OdX+;9OC EPɬWvK%sj-;<6/ ͓YKٯ(J<[yy 7l. /BXdR<9LVC NNj<*b|S琧pîEh̚~GZ>GpîwaNdI+>S:IC N_ޅ ͓Yٯ(L$E[ f_ޅQ͓Yٯ(E[ ~a\dC?5:F֟CsîE<515:F>b) aDd={(M 987 ?^n͓YX63Th#ܰ{-E<2s;}Rv M͓Y)X9ާ!aw^ڡy2=h+v{9,7f: ?^ɬcQ,!ead"\j~=ڽ9&7-~5Ofbgb >k {/͓YYX?GϚCjrHE;'FF~u-}R[^?Q|VϲϝCpVc7Ow{=ws:ܰ^7O=z쟄G!Eaky2!TQ|\CpÖe;x7d~[Cb0<} [^;͓Uݠs~͍}R8›v'{ZAO';97l}7{7O:Ň]0 7{7ORŇ]0 vz7O74jf^ܶ1 6z7O74jf^ܶ1 ,z7O;@Anj⣓/k[WCn};j'S1caNN|vt(>=9.nYKfy2\;e4OϿ=]=ioo̧Ne%T!p>]m0͓©Q<69n8ioGVMqU!a`xGy2Y5ŝ7gTQʆ7=U|^w(SHy$v8{ԛ'aG1ԱG!acyy2V/p(TKy<8xΛ'IIT!;aOe+ySy2T,Oq(V69d7l(op7Oc*AʹfRQ<-msnVwx7O3Y*f=};|@ Ԟ!qnXx;{ދ|vu:~Oy"8;kTCܰ\1Lxsehϖ sH|?1ts-ݻ`sa/u oKF@AFwa0Ĺa`|-72 xI0Ĺa={MwBAF$pB<]w17" 2Gzq]$ T7߃. xۥj6P`dߣ^W΍pT<gE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !qnXj|PQsH?dE*0ĹaCAF !q=,}{:F !qkeֺu"C\uE*0ĭXۃ׹{Or0ۃ׹{Or0ۃ׹{Or0ۃ׹{Or0{᫻_`/u~3xgw_[}]9+(w;[Q _~/>Y%;ΪpBN?gԢ/B宸?]3+Cw[=UOpE ?\X8R+ʿyowͬ7oe6x`f͊? vd5ymAGAboɟ)zvd'0ڽ"fȥ8XKܠP %6z''0ڽ"füe9k{ hm tH<`f5р,1l&V|Kq˙3k>{vpDQfĊo~)n9Wtqxڧ{UޓU~0lX/-gB4CtfM/ۿFNi4hȊ}C5>?BJQ_c-p4B^HoAhH |"R-8Kv"xJoSZ̡3t2\3H?I6T u(ҴC E%B'C1e>mg.wkgUL'3SJ,?x$󞄯eպ'G-1C3MԘ^g?@O9\ޖVL۹GkC3V*LkӋ ^\󁞘vpO6c%@l/6=Gf>|d:'\1$%ČԒqvd"-ݿPl?ӵS"9VG# I;h JdhxKOR:?ꂫӎGV4?"&ySb'#%|dO̡s9FkUWe_u5~>3'B@өN ߿Ov YD:Wk銣mP& di2?Rc=mnDF0bVYDΟON-mr_w(L:I٦CG|豔MǹN)v?ߛ_3 zfE'J>6TOv 8ׁ&LɼĴ9y4xĆ4Îvci2,\-H>ۡ$*)g,+ns[#=W\Ju?hu\]Oz 0vB?Hu4'Z)[6TQ =3gr8O1d4`־,OVYɉ<k hݹd"_<ÆVʰEMX'CMO2e8k.ɡhE2 H9 2І^gմH' u`.\4=6 +yӢMxC}pJΣ"ϬZ:SuJ2 5\+*oء$'* pޮ1jcA&njFƅNdHV .[+>ptY2$h>*<"H';-ġNW:S[:~+jv`2Iq!C#7Ҋ&Vh`sݹޮ1jcA&nv9itf2Xg5f!^¯53B 圕LJ96Z@V {dE8QJ 1%;]\7Na:0DCkmE`3ԊZ&2kQbbqơdFU-.J'ӏ4qP2ph?-2DSr 2tވoOHfp TxlEOvZC̪Zt`. ~*hE=zd&UPMYq)NK\3ԺǦL<4;3mE3 d Y9'.du|8ϊ؊#ah:U˵K։>n=ed&V^whoku&3׮nϧ] 7ߗOP<O^?s~,:רx4;]Xxϛmb󱡪'x:ڇotZz4&nP2ۓ)5vfғ?W:p;OٻE{~>q= ҿ)s6tJAFãw^MT3C _DNbg'-tovxOn~,='{-`ɋd0|Y D9 ?Dq&~2_)5dc*m2Ŋbm_k(r%.7u'>Dn|{2^\_<|f՝UwӳbgCE} pn댳ɟϵh妓(-بȯRĹjΰ|g'MNq~}`^nEr:#;= u.\]XEa"HӅg~3N3O#y3s|NVPb'9U~ |&%ȷ'ki>sZ& PsK2e+h 2@3[vFYƖ?>4'ِgRj uFɪ󙋬-LJ>*L3xO9y,%_GؓCgCʪ3/ u`neysY%fҌI3Z;lT1LYu.Z"áZFCE*8É5Ͱ?D\%D:#gRcz?|̟vhL"=g4_w(B3-EkRrh? ]DbFVOi]Vsa{j>9P k|~((:l=:W0XK;dc+\>[9ץ Be0?'ȫKs[_j-Elzbf:7ӥ]\wi;Kz:H'++DCW5gΟtOxA.ӳn${ܯҋVOk>38WHV&#qz$o'ܯ3i*e},OOS~{~M1jϰ~ϳzl]fi_xGm?˭]iLwz]#6\1joHyv#*^yHsv )*wHsK/.Lk9RlL, Q`v^= mzo/º-p~_fl;5}|@ k"ASm}[%s(eTh6׭/Y@)%/:gƜl{ioSPr2H"%c(eTE|Pc(eTE|Pcψ8;ӻmbIPo|u}؟cڙgn_gޟU3x0o_VT;.^\ȢC}g-D L4a(%CiiI."]d.x|`.y&R8si7j&k&VYk4h8=k0R?O)=F պ QPpe*+JG]?F׽Ni.^3⌦Y:+틬l[zP) .d:ʊ߿ߢErHI 摕rE̡Ү3~2ҹf>h3Gy.)kz =|&Z]Қ/Xx푔cÑx'PQY]sJ3:v |6yv=? 5LVy[ziPu=1}3`bVә>0Ң 3~c])E4PV-m(?)u \_5CR96+${?ɉ}K)'$?3-ҹP?)}{Z*OGKO/=K[ɬY緷/u fP8묛3q7(Ul'R3E2yv6gc\Vsόvi*YE%ԓs'EZ'M 6CRpbzC?:ӓv m }F ƲTR_xk&ŕGERw1]R }5H!SWY6ykVV4AYjI*gM֝rVo(>R 0a[]ȹ 4C?J9wzW$; mfZs25ËȺsŇnt'7_cVMd6+9.ЏR|EΝabm5]zIˡwleEfZs25ËȼvJѧ"]}*0|ewU_V}*Q;4C?J9wQg;t&/ ~|"ʎn%>'^3HL`/2)>,GR #Wv~Y5GL3eW'PdFsG{"01 %DrHV'2ϪQAtk }Pj7zCa~inY~>x/FWc:˝w p~+rߖ=r#kN$_=/ 0ITdg yC_lŭvFo(>,D #ˏQ'lD7E;;eߚWKQ 0yVj2q|i*ޝh7z=Nj(D^\ ?_yww'nxmYwn䰋CkYw wriVvM;Vu0z&DY*L]xزHk]&YȋPdFs|+mū?/NmN$]!&;+2۪R#^/[wS[hZbBteى^Hz;QʶyZLMӻ!jÂƬzbgL.ӳo+t/HX)S<^e(`j3[:uSq!,hխ9|e1:}tէ*8iw9Ŏ7-l}ʞa>xFc;&E?S|unPS~wΓ/2TzOH oG/f?>H7 sHK endstream endobj 19 0 obj 25627 endobj 20 0 obj <> stream xy ǟw5{J$R!SJ)D)m?$")ҢTڑʖJHג;ٳ//29gΜ3sܹ>?x3<3ww 8CAb>i,A"wЀ%n66=̣)@gwo<}I|BﲜE%C ;-+5wv9k/(?5OX߮Dy[D4W^uxjRBCiiQTlaET--hmm݃V!N氇UΠmLz.1ei(*8W9r.۫>XVQ)r/[ggu*aV]\DL!i(*11ܾ&LrEV s߈:{>5tF!Nヨ#3(*nb"*TUYMREٴRc7Yi^Alm9en׎9T dNbh#Ǻ.I~fOE?}pq)'.$ME%}KLi0l_|\ss3S >}K8QYLoFA'}cogT}>(yߏx&CXʙviE.=ZqqŐS)$Gװ|ՕkO{[L:EbI?knoRʷtɜee1("&QIöޙIn>{:s8e[c9G}.kw16!$H盘RHS@$ݕޱ`ݯ^V( W‰Sbcc+_K]%{NqFTvf[k)5 (E\LCse1ʵ:3N 8sFT]ΗWC]q<%;-* 5]%*ZyKQ5#}x;G\7|Y_>Ikiٌ/E rYV+*ʙ,ʦj\ QI_J ~%}#*?ϬѤnq5I@od7цҥtQޒPos'P#*J1A!]iQ!.*h,rGTfsR (g45rY_?(u}~"\Dl;rJX2`̬!P=7(q uVTnAOO&K}DJI#*SHgPg^Mmgf REڷ "~AE\d _ζHuVbΗ+NQJRU.jce9$(]=HG.CQ "2oke69|u}$֗J \?\M͵􊔛މ[4_gUT3U"n9KU141eҌ )IRcʫGIPGvo]LMAE2-ISK[ˆƩ^r&i߅$m6NY F0\ cF5Ƞ+*op6CmzYzv5w)1-]v#1'IeDT՟]'*z /*Ajb5$\G+f=8O*ÒV[*APE&@}K$~6IJ:E~\CJ|ٗhDe5iU rb2;LEEG[ٺmfrJ&hVfF&iIʇwNN?htYTc^K(yd_쑵 ]qN B)$B-ۢr[Vf]‹J1^EGNg3IB4Ea CSϕ:=QQjn8$$U]<ιMXi'"BR{r6 tCrƷtET^gROdK;BE/?tg䜶TQKz?l+&Qy0=$QǡOv2KE+TTRh&RoϠșWG$'l/tޟ~ *̠1ReF$]\٫bL ܹɼ} 7.vkkƗA~wsTTSn۶M~I|ƷRmKTDZ3Er'z\HeUЁ]7M걏bΏITՒ/`yІY*"^fTi3ȷbu0Q]( >s E%k޽.f_(dbdH6Ozld:SP~rU-VDGo>,dڤNEu "G%RQfnaKThjGjҥO0Qahd*9;c)"JJw/.6בυ7E6sAxn*&K/XyQFLJAjr誈e{CEe9u0(oP ?MHgRm }{lHN&&]̞lyćiT@CE%%$:‡&CUԏG KdQQf DQ6.IR‡; *o2,"OEC=ɡ6JI0 .`_. b31V)φ"ùSWD\@bձyXȓva,Ev6oz L~Nʬ44xJDQQ wL/*C];M@A jNb0bPknVaGp}94@X 1D>!yjI"*qȮQ6rܔhhJhg䷅U oY,'[@I[E0ۚ]CFE[M=QYC&H7a7А7cnYTpE~*9m7JnyާBSnohod3mDi/j?pat}FTS@7CEeU75| CtO=2&5J+6Bka厦7**\쌨AQ& dAj6UlvƋQT,a{ o/u?w#AT`)^T8Wz@+*hF"{!rwDebHk83ŴFQߤft\TTֱͱ2uJ j$A^R'CIT&rrUoQVk$;CcNBs0>9= t^T^"dJ٢.^iɋLщ ﹦և){R#u0+V7A7|,(d rTT"u|$4]\ϟӂB6=*QZ@i\|1dQBE`ރY#oEOچlb6|O-*D)*˕O/>pŇ:!kųW~u?щN _n% E/N}ɕLA5U)CdDeNkvILQ9HGfӕY?4GFȝy?,s'*hPRc0#GhDm5`iQj:ly[amAZa\Ǫ79-M>TpJ|RDe=]ZOdQZpQU-'TP8QI3LYTP2(|BCL-Q12_j/1hKTrQ7kvz%*<ʈ2~A08'QkNº$QşPyoGY '*4{_u̢*mE %*Fu|۹i+["Шfވ@J5.ؒ}R]-ᓨ(/_MТNХ*Qa^FUTRu梲Ja\b%Hj Zɖq#%qk4|`m ͯC4#Qg kR%}XYz?{ IT3.JtQ9IWM=Pثn^k**h4ҊeE%7XIVw̖t18D)O3 {De)9QZ,=)[C~cxDzF-*k;ZbuL3\8J̢"0_Z%-Q#?Pg|ƞ !gɡG"TOBI+BOMz?qNl::9^&[ҵT]#]_۴f8!.*/4t xχ%*z< zq86EE (͚ Q\?NbN$}Ee@ECbZPک}Ef6QG?͙3rvt{x !D좢s+7[O RB[C`:) e_P[r^&ҷJT3U^ ӸdOM2;*E(U) K|dtF'鈺VjfplVRnXTv5Zedd |]T,2 HͪGm a.=nB1|֖(- cԍ1nxdhrRSNδ\cQK,*DFH\QQ{:7,vިBT_sM й92Y{s"9!KBnm pH˦k:r9'*HӰQxyxKt::Qou"޻T̈́vߒz? cQ"j`ɔP9fQɥMlKc&Gz*h%k ".̒kх) CQd:7De3Yc6)r/BThȈZl$[`~BwPY=jOTAɾz}NT+e_LMB;sJ72tRET[=(A$ڲL`QQCiS.~jHh$'/#QD+.:Ybv*N %d$qыMZ ٜBJgbYG'*Yn0J),yWӍV5RADEtf]>YTPt O̕WzW Qncr [k[k *h3.wCT1ж@d1jr=3`щJHxZ̗$e,4jQQwf>r(d#Е{0Zu(I\WՍcSq 9)QGi"ÊoxLdwxʕ)(`$}%#1Gkw~.X;OiUֈ/4:sciƀ]lNTzO@ftu4ܤ)+mOT~+%sI+W~C옴4 h"*NQ}?GbYP9{A8Q|OE% uhD>a}I0ч6y͓Q'ԗ͜ 27މgx$t"*3hJ>J0]MdW[WjL%e}s4 OUe\s$*eeryW7Zt=ڼg\nY!%?^&_|t VdM1?G>Ɖ]$D'|2_{O!p4[#WO8`l-KR/!I:YlT.#6*+hQg/Ib [)"[.0p{+%lUGH[CLxUyiQÿ%R|6 qiEe= ,?O|z(5|}{n*z[>XX]a(k`Xrۯvacs҅4Qnl :w(TiF՟" (}]]"vme䷥;bZsse]mW5{}9=ک.kT>Iݵ+V7oQ~F?#̥*QBk,7ab!xC@Q7AӔ:ɷwUVӰOG>m8I`+_3 |++A=LeG ْZW-=QQ-)swd ϡA@";ԘLS:(*º),inقvרܯ*Aez,YMt7sE JA5I='ԛ{|EJk2 Ԅh:S8K¡OH v2Xp}!S5?ݻ L*ļG"Ti̕uIzgy?6ZcՅJq{! ‡r-[]8Ɛ)_Ås6I7 !*`MX%:fy/֘T3i@7_uݝLXgٶYnCthRbVlp}8ɜo>۾ŭ]L1VPԬ~Mf;[u{qe[iy? [xWg6dzgkym] I0h\o#t01j { H8%s~ u׮g 3Z i2TF_8=PT$_ |2qf0 (*/Df0PT$_ GiqZEm|K H~{\vd%*N O+YD*rtfE^Ս tPV~{LYy';qg#,3Z$?i"#*pWltu:.;S&(*8]Wd@JڼNG΃                    (ڼb~tQU~e^Җ>b,mv+l|S'%]9"E4km \kw9xn)+}6{k6Mm@|2)y7#fJ~̨/w'*Ǧ?KuP31[i⻽ݰ8JO|%WDbkPT`}Lxm"*duɪ=%O ]~PJTs_@j\JEɞb&Nd**]rQT9W#E%*C/(*2(*ƴoL3\IomCQUC~0Y6aᱳtdwNT:gs#l"C)t7~F ~p)iD <[=RT3_m(*B >ޚI')#\'ߗV͛7&Ԇ`_ɠ_TZJo=I щi1s%\:}(*A٧ak]9'8AhPTz&XE%@POB<"b |_m (*(*@Q (*AE (*E%蠨X!QE䢯^~Dt;}}fǬOxUQ{y"*NxW!d0#w׺6ngGTr7}ƋO>#=!kΚ֭F*ԑ}})G"e9)#={w:;"*[&C>>QLx'g ϔMTNs]_"k'R'^xŜÚ #*[G.Ȏ˧/w{o+z+*O 񲜲ROܳ;V2Bڵob3|)Z)%we F~)#*RԥULVNړ79y>OVQ'Kk-Zl%%cGIъJ!- AJGwif6L+õuXJzm%szIaDhYڡroQ{On;Q޿k~些c5| .[yjjIYRPW+B}5lD.YJwR}%H,^ڼĈtU5L@T  Z%^ϮSѝ;,W}cAKh4z\[үWɑG/qN}FsE|+-&Qy~V8&$cٯg'nZ9|YXzj3 \ݱWvQ%y,*ϑF0B2LTj]>lF7ȁiK/oOY"8GE<HUT6Ki7樔Kzv&JazZrz{VU,I$?C$,v;lCTM#4^_ӅFVVBInG>>Jѯ&̤{If\X1I(1w-لGHڗohpwa*N)ҿz|4uNTY:q1 X--! 'CEӼi9*ъ06ӤJo١PHW?K\M_S|5QJ &{Mr ScɌRu?P.[$y]bKSVN,4:%D+!5_$*UO:Y_>4;2/O jqlVM-|'KJT'TսV4 CTě;Z:XL]ͤ_n Wk_gh'*QJH SI+!h-B )(Dkm"y6*2uxR!#镴K'žf}SJuNTzt!{\Sņ" c"wdj6irj+ sEG#*4w 3gl!*bKG9rXע=ӧTT /]$e)!Y$fLd˥ Ri|i$>Qs\*эmUe؜LTg141ɪ{oIR]n:KupNT s6U J2.lCTz{ŽRI&BGJM٦VL"fV%.$U3z]ETE5&F/*vw Հϲ&LRgRҮ/76UJ>S2UEKd,*ѩ2E|ܻ6iAu3V:y !SE8y$Zq8Liȭ9ET.g/(De )9WZ/Ry"ôi[-!92Pʏ9Dܫ[6ц(ogC. ⧷shBrh<Z 32Eܙ3I")vuhƍWRQhR:'6"GBz5$ NJ6 gϜ1a UEJGM>7dpAx9G 3 ԑSS8BTȨ\YCdD;I֍QӠ.JaL Y6ю,̩K6Jc˓{t2Hj撤G#LE#@u0v%ؚtNAIQ:/^T7Er9T$[Ɛ|iF nm"*ۘ.*{#ETѸ-4x䡡jy-Q9E N B D˼Cr5(rVVz}&,IT2 U렢 4ՐJs8r@et U^[SXHNc#BG-*{ ;ɖI&F&[zfʸwuQ^ 6 P'/_DW i3ԹsB_ЧD**O0孧l*]e5nVΣi)@wyK8!*E6%ެ|?:YWCIz VIT٥PQaGݣ:ih{n68lp**׳/eluQC5O/Qa;t$Y;;1*.ѵbpseEƠ`OTԱkWu*4r(_LUI%@#͟>iWITGy`ռi5jQԢBFfҫޮ4{ b(NE 뇨s7?# iTT.6Y SlJޭTs m^kP)m!*tiEeaN+p-:&[2X}&"Wz#XJCgIԀ:H&[ꎨ!*\pQN=gt093|6k465س?;h ,$t4Ԧ.*RDt+ XJ΅1:FփYe6{ E3{ϐpW(~#n$ᆨN +$pa+]e9Xx|lDnc;m ^ ck#I]tNiSYh {(h+B"@aڊ5 d**lJ^Hta=/7DFدpJTL] p~!g'*4\y#ɡʹLG_iEe^,! cL?sې qk(ƚDEqa0`Lǒ+*t{*տ.>H0?HH}'趨PtŊFEb>W]t:|C\i9)rCTr!fQQf678K1ͫ&%ۥ{rrXQCG' f~WQ[YF8-H1< $Y3t]QQrZQ2*2jl'Mݜkh*ÙRr v,Ъ ]c@xQO|YQDcfѩ,"?B.A6JwyȦNɁQ:rO秨ȻK^?feI6x ; B[K=EFwS"*Q)`E`y0ɩuJQD-<\Ќ'7F>zZ.N oE;}İEY<]ɊJ &hՓHTN^l'uV DhǸ(*JV.P}]XT6Gnݡ`짨I~3׫lgRqקҵ>K VD;CvDBJ)RAӵ;T~r󥵸EKUU[ ? /*81Aϊ q y_}^eM2&N׻X̍fˊ'ihAP:mV-~F9?^5@rz`9\X+9ly 嬪ÍC MOU+47c_$nF=jsaiB4rDliflDwUR)5X!. =y?V U%cOl1R@;.#`&B0O%R띪ެB͹4J|t@PtH:7N [.TK-jN\RW7P$}AjW$w,].-Ŗ;MBM̢iϒG&wVJ*9+(!Ct2IY_U|-g-K=C;N5E@NK\P }SZ _#ؖn>D*Pyo-^JCP"-WbrBJNx4qm9۽W83JlHm`V:W ?{[OdyT>|0y^?Q"mAT5N7-ϭЏV=˸/~VRt=Kmxcj(8JGT6 UmoltiN>_5cPKw/oß&rݵ|4:8YAQiyCvU ֖Ƃ=Q;O$DEAh`ԐVkw٣HDeF.r1VrQ6o m$QQb}S>gR2ɓvB٢d?ˇ|"wFTr3Yɭ"̪i`̵F$L90O艨Wf8 ć&Ø%r$*c; k-wE'*¢KuU^]CP Y8J5AFͻlˠ/BZ=cdz<\yur aQTouvuy+Fe &aߴFFTu_B3ҳ⭨LI:Vs^z%[J+b9;g @6t)4lݛ3 *;";^+<-x!~mSB)Iz|B[D%7j2m7Ló*?Zn[ƆL*2/}Q%[X%7\-|\~wK!KZK{N66RUW~Ue''t ͒ j6W2˞mg.ɒ^d-Vc z d_vϙ8Ԣ ~O@eQ_=osAGNA94wC zgt9Z&?&{.pvO?o6FmuC>oܲQo4 ʋc8Xg~zFN7 OFwfByG4bǏ(a!01jAEAGAQAQPTqAEAGAQAQPTqA ~!- )\ AQAQPTqǛs0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk!~"w%v}gcdCNu7qι~?g.wM7ﻇx~?gΓ[*3{x~?hγ{.}g~g]z}~?iTPT|+*e3BQAN~4u AE%^O;PT$*6q(* dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AE%AQA J8E 2(*q dPT$Ƞ!(*HAQCPT  AEňr9PT쒽{cM>ɊkSPTxTj3@>s(*Qr|7#^xe%|cܼ-Y^8>+jV Jܳa %np{o6mO!kx_Ν9eWNO=i(*4K-N%MUgvmWUT?9g\8g[WIN$2(*\9oJ|匃JvX6P=1.tIZ7TaaE}C'?9d, ̽'U.xϟ9?kO]S4joD̹V}8կ1,FPTk}R͓_Zy㐥zP oD,n'+VPTLA.59Nˇ}`:EEoj-٬AQ1R_0-[I'+9߂"s9kw3! ߽VPT9ZH_o*t;PTDAbE]&!+kH?FJAؘ Y.{(;-&bEň UXy<_KNcta1EEnOGQRo-PT xC*ƃNgº )->~1(*¶d*~:q JŢͯ7(*B8?ʡל}\1Hޙ"cU4…{UirLd/ӡ"V bI~v(y2riwMC8=(*_Cơ苞[2gU젨0MʼnϧJk8_b N·avNt=;th=%0$X`W"@ w9\|]Tც/1 adg )E%|c%XUPTB40PHnx@1AQQ80fMDVs0\nz;QNc1b "g]ޖސrtG>u K(]\eCdt%ޒ࢒e73rZAwkQT(8d+l"Sm$ǙN5B˜)*2(*bk2%6ve@=~[-*`-(š"ByhTX!Ȳ̧ PʱʶZnrP!dm;"+&H<йږ&lB!eM[{`RrpH<҃B2eV-J]G}SU'3Ewi5y,+IlQ:Z#Ţw4O*K/: q{m %6;Z!(*+7O&HlQvC=kQTd:eG}tu3nIlQ ^pi"yPToTr"8_s߆GbJ3x:G]TE@=,W~g^آ^w.>ZJs KOO"$ԃWJE.,Q̟p-*k] zkN((]~I~-*53L5 Zǜ{vwZnIlQq#2 ;7U@Q!t)`e 4$xAvc#E Fy7BI7chE0^_wv8Kb+-\\8BxSđnR(a qn0% wJ@Q!|E6o;$E6Nd zOnHlQy M:{*EpD<Lɲ/܅m3$\sp FER ,Oal;M[T@#j wdJuY;Jg$uNnj^2 )Y?9 K70E+(b RB@QtEA`ם)ˉ-*CzCr7EQ|L"ݓ|d%Ee6?S.qc] ES!񇥛R[툉idB(* $/xo;b EE( ]YHRQTáv}4o;R倲keَ@F~C 1tgۨp .*-ޣ$+(,;Gۯ>o;l = ce(dI"I~6JSHpQM\d hthnuĢtwj/;$| 6$x"QTTw1 oOj852R]$MΖ"TYIc]#5XQࢲ NTfήCQQ9H+io;%E%'fn/N/GQ Z>Xkª{tO-EHpQpx:X夲BVR#]NtQi oǁ塨8["w"ia~ .*/y89/K}ۥtg-JtQ<0$R?b!S0))u. $K%(JCQR\wEU;f H'I߽0 qn:- HCWk$5a(`4U-R>ݤuNr;<-@c%QTt46Rb :4@ /*zOlmz PTtH{1Apk~<IxQ 1fQ|PQ(*:{1m T)QV^Tx]Cm(*zZ:@9gI5 3i0kp{EE,w('w5] /*BC1Xퟎp@8;bR kp#0|#4Ɖ‥,P~ў8LʼnrPTr/Npxے"6PT9 ;1ȆXTGJun\FQ- 1Gl&9 El%+)).PXbf"\?Ce^0(*oE߁1B0EEM=Fbk: % x2\$(*wΤf< \ O,g&ビȏ@v"X9K8(*< PYqAޠ$]h(*P >›dOlqo3xPT.5poe#5*w ^,MA{a e<@FQTxX,-!.u5'  ,`yW51b7(h/~J t\c+EŐWtt[k2Hk5*alr*@eA%. w-;p֨,uc& p`g]+PTDVl;AL}(j_#6#H^sTV|(*&,K3w7dPAQh ܷFÝpI,M3:$x' PӹUI{EŌ 4Iie!~\9z7G]pq )E~lX)ԋ"Su-%Dgr @Ζ̔Vxo3$PTd֮[nc?$92_r`E9/ ¯EEs(mtu}2Jvи`K-~V(*2;b_%m JV4.V8Xm 5z$PDQ G_W/5.8ux홾 B ݶ\dDžu$HެE`Y SQT²,%a;@0@i>;עrny&Jx^H j PT(av2dI oǢd89,N{'D`,Q;@¨d|4Er<=6:E%Rh+%_4ҿQTnܵ#x։(*Ȫ abxg]xEE]W*|n:JD$|/EW(* [=wC;硨DX.cEEN0YV 33(**pi4 H: [?Bݵ|γWE [yE5U sw}PTT,s׊> 7!&QTB<i!ى+b2xXEXVBO{_/Jk4LjI03PTs@m*QVaբhv7QbiX% V EEC/EkE{Er5|f AgQ!$v1a}r*ChAQʿe jgV:@ǫPTܳƄWԙ(OAQ/b 6 cUhyjg atX%.lF%46+3DŽ(@QNub%\Iy[%ףc¨W2Db۵}.ɻPTt 5\Ɣ@t'DÜ^MyRv{V\3nj!@T'Dim7uoEEEO}5.EuJT x;[pW`(*z^Rg2ǔJN4QT`u<(i!] =)NLhD?ER/ov]AQa nsɚ0Ɏ-3R󤪠r"nw*ɐ%s̙l5UE*aXi O k\i9/M6L D;ܭEGHk~윅bbwzVTgd.u Qy8C^5jQTrX> Ɗ.7k@Q1Tm6*XE6AX!#`Nx&gSyc wx p1 wFZ@9QTbii b,HZ9iGDQ~,To4׊GQ1(k9QTbbkՅJttCF@17Xˈ~xvpCa Z\_+}Q]{Ke8sښ-fUE%V g$N(*Ƭ9lq}J.ٟ"nwhZ@[ϐb)JtO ;% z\Ik#9(*wXyZ \r.FQ1! p < ZɆٷ_ZA$RD7EPT\ic&$[PT@_DdySQ[/EŌ}ievixB6Gjdы9_2Ij9)kk,BQqZ rTSeÎ1, 8z^>d]&ހo.EŜ렙X! E)5M|l)P-9QT̙ +w7h9ci$paÞ,^pXb$G@QqcWF>&q` ^WqAsp |1h!ZQͅ8r%9Z$JrA7ͱ.b'9}hFe{rDpG s(gnhy|}w@p* 3&EުEYζ )o3*QT2Jye\,(*V~߉WJX3HYPT&GZ\rf\q(*y {rH(*hK~Rs(*ٞVd*DtEQq<ɤL R^JCQ@Ž܌ GȁO֤x<H;Ov02"S!-B W o+PY* E%mMS"3PTѠ '|+^S(*X҈HN3OEn~ psh z E-MIGag&X!&"(*Y c1*6̀j6Lȅ@/Wb(*aIvѬ6{(Ĵ26ح:KfQTE]~[= ~܁rPTjxT#FQqO$G<^ڋM4"@Xas*|9ֹ?|(.QrXiuo3fG&bMϡD8/^Y\Z-~5ͮPT,5>ˈ sE}6+fxɊ3+E*ٵ#Y&a~E3N#bh%CQΔd~ w J˩?EQN3h(`.%SfM?Tu$yXr Ӄ(*F TW˝K(*Qf9UV$n(* ax'Δ.PT`k:TYhfEcrzJ>|o;RV4~*G3<E%z.҈M۟(*>Z:=5mbw ye|LMdZKEީ(*6ȮWp kAQߤ@cx+- v'PT0/6˜K@(*` ~7REQE(RjPT@Ҷ@Co*(*8RntT[PTz\o;!|{²G>(*l ?wQTlr?F^fPTZE\o;` @)[rbC堕jQE%8zR-:o;\`xahe2ۙ fB(*A*uܱo;T! (*i %}0^}(=(]HiAJc0 m6L9 `j E%`PNi+8y(*:{V( QTҵT0SPTb(sЭ%j'(*c\ j'9PTb`Oq{}N`E%Rjd#6NCQ\+\:Æ(*4 _6NCQVPl{ QT6ZYqJLMs\+}0\gT&Uo8ދQDAbARD mҥ"ݓ=qu~ս]xv2doKR+WX V9G6JcpY iS_EΕe}?8cΓ K[p-$MNo$*aK5dvjf> {/WYv1vex;lB{삧M/Ăamϓ*˹1270Ɨb,vYҐ,|=h{D%`IUvAV3vO.#Q)}Z;)wM&Qx.=#xN"%Qu U!聨B u b~M_%Q8>`[U9xG.3LaQ:ܚ)2wkǑj(TFXe]WKo8$*éFUKXJ [ӛ8+ Kvޟ|J8,圚2[$*&g6Ϯһ?kƓ}co 9$*Ɵ5s, Qe2\*ꂪXmH ?'IT2K2vVgI/Cr+s}^uxuL:)vLduHT2?;ŽUfalCrsoQn):o5q9y(9l"J00cw'˱ D2"f Φ.M#[ױ$Qd:2v8%YdaJ>ͧRϭ.kOך#Qtv?UvUlXɆ@BhҡN.f%lz~Qv]}3k߹;PD% X#r J0cR`BBoNŘ'%|^6oK6}[\!QLO'.\O4vOkHJSr5 aǩE>_)-GnJsdەQM4- ȵ˿ ;IpMޚbC*7tEJ#Q!ơUE;okۦu˧8h-'ӳR Qb߱qՒZDgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%!Q!DgHTŸ!Q @HTD%DSNf⦆D%P Q!@DnZQ +vQ@ ܴrBB;$*F;"s) 8PzeuaYyDfdV' esVGo:x:#t:V3:vߵ:V' aSnNՑ.&$Od(:oDFjğjsr"#FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqlbv^ /peC6tT:,G!LӇh+^Wd36$&Ī3A%qk$|V/NTԉ,8UTc4 < .o +)*euo @Q8t%ʴqNLl>m=Qע$*tM;De-g-M~n'*R\J U`XQ~ST]DQ,jXޫ$I>I0)kDJL1ƞҮԋJ,\O܄!*+#< o˼GY$@ԋSy܌roT6=hNryӋJ FDşE%xJy;$QCHTbQ^n_oqџ3o[|K&}1q?v/ }>KQ]>i}{WсXb>N>Hk ז53xD/ޣǰ/':yF=W15ST1fYx^o]vϒM:ʯv5|G~w}-0H8î#:3u7X7nt.Cfz%>SI? '~ul~]G㛜1󀯖G}]?>ZwUTxp`Z1ۘeq~jG]GТ"*. RֿX~NʡTp^ZK; fYƊ*Fߕo[d~nq朱8j(ί/##*R!Gwman}4@Pc﫧:h4FL\p>?cX! j}2 XSW̃UO/#ܿz%֔JGky9.*Y_Sx {VO9$3^%4!*ǞE*!SJu|B]zV(CM>廵oqi5O Zw hXYT"[+LUg<&OܚE%fd#m)q΢rh}*Rk-r'zXaGlJzȼ\ɝRv[DMqK)nM3/>K.DNQQLowSz7oVw)Q4xV>PcF4*(Q*o'DeOZTtf [ HV=~jZxv t xٟ2M UO`\>_HVT:.C =w{~ׯ嘗QoNXk #GT}hO};S>k8EeAV]f$Ee)W}2MDDe \#˷%s8^Ya 0O?BHuME:H%0ޠa)(Slc'|_4o&*A›о2XN| $cY~j:C"7}ϴ[pđKc׃k:xKLR뷘Bj4ςF%#* s+ۛϵ h& ],0 6܀3𮵣,3,b5U{F>\cǬ|+FE-^l9TTO czA\RJ<,%7ڃWg|%BaV|;ŏDףk#OQQGeGùabRJfMvdNIN:׍v !Pc!m4RL GrQb(u۪{35yQƮU<|PTF3-Akϛ.!mU% S'Q2PT>uѵñ3S5IT6`mp~U@{Q6Ee]8x-ȝa^|OоOD/_#BdplOn: *,dxXM?"Nc8]s\@]#O @3CBVKX6c-*\kQg?/8zu Oo}:yRU]ฎ{p9c߲ $C+HS٠x<jl0]_2%梂s/:7+[-6??쨽hʗ PQA.S);/)j*_/&tƬRTNQi j7S@m=Cþxٯ=`2d Û>LuDRQql *7?&;`)*0WMlh#*:L'D$wv5Єr gUukJTbjC%<{8)*uTUq5K**OC)Z$bكᲇ: ue% !nؗSF mDF%4*+uğg2KG.-*lDh͏% ^UJDZj\i^KŠ6 ʮzS; m GQzWN#Ki<󘥧$i u GQBZ?lkԈ@%)*W&8|X]UrYEU}_M[u[BLUZ7t]ǖpp:D9iGQarnǘPp~T[L:Iz_%*_X.,S^RmE^Tun c=EHQjtmrw+TX = oS|)*Tr8v` }lUT 6pC./@$)*w؃Ovy{fPZ5Cg5m AOޡ40U90U#բ]MƖ pdhTKT0-pz3ut|#bl~솣ncmoe#*X˘\/;RiVTIs)cE%&Ij'ḬMRTN㍎Q΍bgBޖv%]TNtk+ѩ!;TTg$ ~vZTK{zb*/QAoD,Ս,r8@b56Qa'oLGy~cLxԊI1ɩ̭7cE%g E42CᯇX+fk ;|&*P`Za^ τDN \ 'ae[̺JmE$V3 PFҜjQRS#*P4s]/QB#\iah[bD'Qlf^t[wi/*r)*5wl.ۄf Ο24SHԊQLҌn߀6nJy=L;-`%)*=rC"Z@EeJ3`%n=ltх-#"x{JsJ%ڬLn8u+sm8bY OEesȿ4"}AsaS-*8.lNQRo*Tl^CDFYʕ_]8X СbXOK4hDD }06oo>Ee?*:VF %q%{փ(/VT j}i{dAݝDѫUv7!*t+ .Y ,LW~TWGQ79i1877[3u6tbnVRQ$ Lez~8}E'񾜳haj8 ړYB½7lZʜ Q8բ›r(!t Dc2!l:UDZAh"6$>rohMrsmt;u7e@.;QzYs/E۵k%4|%&+w,ơ~iZqOwj^ʓjQf~E c- 'QHڐnKKHT{L@:'IQ1`YcSudGQI6nbEFA{gϴ>ZN&\ ,?` 2$Ex(tw4+ "!7De-&X3]1iawGQ١2"`R44R^pLh=URbUN3: fx,%(D% %M>oĨtj6`z=LGST;ɒ8./B?H~Eܭ magťͯ$B;)9Qe^`>g;`;sdK1-_㶢)j|6ԂN=Y^_ XiUXNtܪǩichzVTxZE'nj@l*j/*WK9ƽQON\2m g)α %G!E@ f~,30p .j?眓B=GZ~t?iS̯';Z+qN+\+=].Q;I<$c W "˅j,r*0V_halk'έB\v4G%X~oHج~'3.v$rˮvE<ܦ2$'8}Tqrq5.&A.&.*Y ٹ)\.εwL:zDlM-֤Qa5 PE7F4cJ0v:C1|ZTq T-K<}g靝U~k[*{K͹.Wuzf;C Ԝ*KBX9: ZU"hA觡rmF6h}j=װ8rzls=&^ 'n|-<;]doJ0mO+] &o kaE.-SM<콠.ulo[JADr3Cp'Y0cjAkۈ8wV jYZt8Cv@wP2@{"e] MtibJiHTgc&}B\;Z FȚ\+r6^i",jOuXKm&v ,EF*T#{636PkMK5ݹ|^+y3´'( 2ͫ84Hqڹ i?0Bm un%6n4D4v;[nKҜ/BGkgPX7mxL+軪΍uopϽS\--5L6-lԎМЎeI;Od_8,O_Uۥ;77;$sֱQuĚu~1;RRQĭC2~W_ny3%>vw[ꟶFe0Ƌ f^i'6{1HxR5{qXY4Wpj)^m.#_Ά1\et įʵNR@eNpCso82ӏٻ= ^ٺhm ,Y*4~ek"m%ixW+VJ_ͻsé-s8oG%HncmwVTppoRйm7 w-_~k:j=ӟo_7ӋCk=JOZ6]AӛoN7vX5'Ňݷ|ٞlrrN:<&j-ҵ.A̳w<+ Q1]٨#6 mِU[ 2Qb 2.Z= EBcֻ%O(S݀qf6_ `gK()SsY*o@ g5kc~MZpd1 Q!z;z"nT2yp{~ǖ _༑Ϭ= &"=NmNQCiQɗϬxV?Mhy!/$7$Dq}ĉ5DTfMETnq[=@{z% 2e0bfn+xq >j "M:t佹.r3j b%Z`ykG&+I[Ћ|>,*'*WV'XpdWLz"@EZە3}AdD喢GGe44;`Z3y{߷Ӏf3"A\s#O|էߜ]McgT˖9z}qkg2v98w'ྸ ;\t_?)*ggcdW֭C8͠C~u&[ݽg- lj+pܣ_2U^YbφjTѿN1ax" Y/ί.OlnE+OUZ|gp]6ݫyC1_p@0]۽lѷs@Z.osyuvYD8;dƌ9.}7BÜj1?j|~VRO)#U'O†1F,o[ү3vKtuRn_9-6w/ZiqJ\/qCVۋd޴[g[qU_$ZiMɼ*ϚyyɳBJd9RqAx|2}kQ5^ 4 eA5{6nb]]MJMihȯO7(>{u|Ej[]D1*FbTTONk8Wc3 *߱g8Iە<,܉p>w *$UA~v]xS<$vE <5nʰ$ 5 qP[.'i&wH(MO[B΢SVr#72b0vs⧪hTҀ4Ǩ̲ YU?SbA;QOk/II6a p{.9 x54ؽCp^FI蝁gǦ7df(X.'~MLpNpQjMWoydk(ZWzWlCT `ڏlm.8>7cϊørP750f[!X6"G4zT$$(\&]SQ[1+qRs#\fEE8lZ&XD^b]\ Uk6gMyeN-ZQQ՝p_X@64PV M ʁ)F&TT6Wb҅RQݴ-\D/ֲÈ ldVT(k#)۲e{K*v6.CFys)zOgVWޏ[F]5ø/IQQouoWܢ#7-T jPO8罂)*g(pE1G9]CobA1GARIR+**qSK$ 'O sa͊;V?gL#Ϣ0~$**ŨvkdۊJr<룸i?wڍU]NҀL_&O.G7 bGknMDˆjU+<57b.$3rV4$*~B,>fz؉Y,5 . $*-˗g(R**Xd62ATv0:xM%DS[;LAӠ[LE՞Z,.d#/QVxG1 S2QH탰ta7xb}:IQppHT;MX] +r=#"8J"Nϵ,p<"´r z;0Fg۾!ne:H>3e *Wf\qfavȕ%ڬh#uM8E·0C=@Tp3KDǜ`R"VFF|De1s5DDHkMGዑpO}"Þ"#y}AT0km_p>4 5>G SYn,AѬcr}E+̰j 'QihHfrWu%U1k8]ػzۓa+ *QQTP eX^ʪ\o lnĕBS(*h+W##i, :A\_uE0^fܴIT1s`38ʱ/WK5`Չ|5:zPy>/OTÛyбw*(*f^B,1VPſӖmg9'?%X]%!*8,{W; ?1]p(* Γ'd`C>4[\hwbdg]y)on9у$ek"w;Ն]tQNA_KUX΢bgi{TXV 77ə*M+eZD{nqa(*" 6 Ycu[qX7 U..[>Z) ftD4c ˶pPf8o>o\Ѽo.$. hcKh4UM֖T3ra{u0\h>k\ .1;\ SQx{s.v7DtB}*s4v Sm&2Ptza+,g~noY·L!ۯn(a\ >އp*su KObx9JQ cл?Sco+émxXǶK_@sPWhYn˯lkd{nZ+,>oAGvڡ%>{Y c@v Wk)?١!12]|N{jo`W s*p/%I4CKfcǼ}bQГ=g W2.$CZ&Ÿbgu9rym ch-sU&h ACJ'[?*jdN"3mm\C-Era)`OؿfדmsBnXD4q|-~pŊ xh:$Ⱥ{Wt膅k'Ń?sjn^PUݰhڕF4&fru˷9\0PucAzHT)$*A |n{Z'> stream xێ$nxcUԅbH#(Yg?әDrnPe?3έ깙C1_,hPxzG:G'\@CMJ9sYb*jkk}sxnPe OE1έṙC1%2Hrn,1@⯈7osKwnPe (r[svnPej aXw? }v@7_a>?j|{/DneXR5wgqY k',2Ž6.m .+.@6k/7jc4搒Ͷ2{7.1պm#}ǢT0go/NV`>neO2%籰pnE4\|z]|,`+FEhuOL1g*0{;dK7R|cas}%kuKO{ڏӾzedNV/E(quͶ%+0xSK Uy{v2pZ*NWOӘ@e]wT=_NJ~z+~+PcWJ{~_k8j5o`gna,/~ UsJOgl {[|nGzb8dOD}}G4F}~&-3o8wћI֎M)f{d~ ,}7xr A4Mև&ky}]ۣMn%I3fry)d]K sŮP)L&Pzjt Rq/Np'}k2̻(E^ TfޢY4s 5CYYQ [%3zJ3q_`[_8Nz8)Kϼ>znq"ɴGκ WfޢYLs3_72d>o%j,Jܧͦl91@ YIN7H·BWx/Aj^Nb2d;"܀Y7ƙLxrAǪnád& ;'% Vw/T&3SugrhY5~&-M)7`Y) -^ꬬԔe8ڳˊ󝉓J83dE2EoYE`+_.+RZǁW&w7p*+JXYʤAe,p'C2p3Y̢|J ^X b.XK,*uVneqj2pOƶJ8ɧ@JdVfw7e{-sĺV_?eY I̊R؀o%7|)A*d%0= 梔>=9Cb. |2hr3lKg3+8YTR.ڟ㴇J>%HY-dQ2a{XV.5ZaQ2nYw2f]pdME%ZW4R%Q+Lf,ΧkŠd¶?ӕFbMn5 )Vӊq62YyYTu5̡7řўOLWMRRƬUd" Ǚ߸hqt{\PW'ǫdZgQ}8dVgRcJ_Ί3vJ8ޚ)˧[XLW3I>J沂,d\b]ړjMEZ]XQI)}M8+L)A|zk,oaE2a["o$ql({|G(w&U5eT,UA{WtԒpc6qiXA& %@]ٗn+ǶfJ,Nzj?kVƙV1'+1¶Dh ޒLS.MR Hi,frY9I/WY x|/cY5fg8 qH L7l=dҿw*oEc~V'^j*= qH Lb8N{8{`O߻ONO#kŔ qV| Kx|/ugr)e:8^.Ld&i <ĺR͊3pJ8^LdѺo~kj|2k̃+d"ڳ  8Y 5,1Ju[Nۢre*1 @8Yq8Ԣ?YM+Ժg>^z__#qp&԰vK H+Ϭ8)XP[%+xVNn}JRf7gVI{خ,K%4ەsQ-A3Sݱ͘d,lJ X&d+~bV<-]73io0~ d̙뮰;%8K 2gr2؋񊍲SӾE#t=s+) b[1+|n~#~DV>[˪dJ8;eͤ%3(H}Yqغf62}T To%S$IlWw.klxS_OվnVlWJ>+8'޲n:u/#O.8AJI%kx',3,Vog8c+f%OVn+ el.+XjZ1%Hb-[p Kd`(P&zO>ɬ[}ymr~%oGT_[vX*.j|8\v(0קk/ WXVX7p'ng0fOg i)U2[xVShdMoY[MUgm5JxnV*q?Cn[M*%r[\܇o-V%*X/u?'Va[˲UJ(K` U}xֲlUeXsovpq^,[hdGXsovpq^,[hdC9 ;/ZJU2[\܇o-V%*P~N.Ëem pu?'Va[˲UJ8Ժ~e٪D[%j U}xֲlUDoOo&H`Y*ϥ*uWz~id^G 4 $s{Ʌ&E$籷wY'^| `-/&6g vѵto_{J|Mf敬" ,5LKaי+ûH/}_{㧬ҾhKwWh|V@NW$@JEGcdf^*B_hua oj ` }]fVؾՃ)ȳ}Y&6=+6h+YEX(.κEim]t%ә_\h:Mg^#;j<@ʦ&_8)Ƙ̼Uj_w"Ԥ5,[+}ljfZ73oj8T['_h)>1]tEMefd|jtzW0e]AZbbkq3/&h|n3Ê/p/`SOA"׾PJy.Ԙ^7!%c)Z=S"hLVV" / &?=A8[+Boz7dl$gtڗs2BW_cG 3ARrLhXVJAF&3P3 +B+Boz)uNɰdl$Χ=Bl>U KLi&NVM2V8̧' )?7){L1& J)~+&SMS̔  !1T|/p3 f>=Gg&NYquOc7HLVJgMGZ I`D3v]nARv$+m5 >7_̺qa6r4eg.s{ +;h5 +NVm8ɷd]zqF&S[kb6S䬀釕p8z_Ĝ8اYq o қɺ l$~Dv)jZ`C_8c_ܺOdJzq&}Jc^FlyLa5&#%T|pQ{"83>Е)HfQ'H=|b[\] (DvWV8rz4~&I|}SK3Si|L%"] (DvWVp/EGd (^baH)uFj*WV¹9fkcM-Mb+QyjiLd}W ^b1V?n#e$V,%dw7fkcM-Mb+~jAoD13][eLI/1ΘOd+pn2Cmfrx|SK؊jZ-7m#?]qfA)uŔI\ٍ%)L𙘹$FU;$V'[= Zn!F8L&<d&I\ٍ%)L𙘹$FUဉ9p[qĉ1?EX6w>]_CI&gLn2,8hV7hdzw 8-idoD"1*AfM/1Θ՟He2g`n~ ۛ@nw4f$kG_#߈EVUL&^b1?d>?mLCn-&ۙr s5D"+*A_^b1?d ɬ}Mnjr7صhKO9[˭IJsס3w ]/M/1Θˊeu2zMuZbbqM&˼Ĕfd$e/]&oDV%Z+k 8zV6ҘnK׭| )Hk]95%nq&$MC7"+tuL= BFZR*X"ni?ߘRʾ)Z[[c)z7%%} eKpcztuL1ʍdUdR~2Hknkҵ|z[.Q@&sKLM,$gK nl}2|>csiӸr}ʰͶ{JghLn>Eɡc7%-}ZK ^V\3YgIL&+fmg8dm`" |NW'9|YpAAOXJج⤛Is~I.g24W|rz}8'wZL%5>W1ˊLbnd,|!}ɽd1 /^+NJ/+:[{6 ֆ9c/&f;N+[}2xozcI| 0.Zwf(H㩃^nwc= *<4OR@?,wyƳdOX g O!K1렀[F(f@ehKM=]2bF1DgO7tpˈtyC4'n1v϶2렀[F(ELo:(3iOcRM=]2bF1_mLo:(3jϮЮM=]2bF1[Bf7tpˈMkuP-#f)͠oy'ӛz eČb~uV'h]^n1NlۘuP-#fs{@*7tpˈ pM=]2bF1sM\uP-#fNO7tpˈ뾣n1?7/-Lo:(3u52렀[F(~7J7tpˈon1^x/23렀[F(~&7tpˈ/~M=]2bF8?Lo:(3Ks:ӛz eČWq9M=]2bF{8ܟ<2렀[F(~ 'P7tpˈoXc:uP-#f_ϙ6n1n+ALo:(3/@(0렀[F(tn1VrLo:(3ln1>1Lo:(3/sln1&oeC7tpˈpvKn1 VLo:(3/ʸ#n1tN ӛz eČ9zn ;0렀[F(>zLo:(3尞,ӛz eČC9M8bzSOAQ|"ǴGuP-#fmݡM=]2bFYж\uP-#fl M=]2bF)eLo:(3hⰨazSOAQ|rW7tpˈs(rp,ezSOAQ9'r4wuLo:(3w8.ZM=]2bF5,V0렀[F(ޓE:ӛz eČ 9+_2렀[F(ލS%M=]2bFV1YLo:(3o࢑n1x*Lo:(37/1n1xZ.Lo:(3/1n1Y 1n1A}2렀[F(~j-Aӛz eČG(53렀[F(~:0렀[F(|2M=]2bFq1Hn1ŕ$`zSOAQ\FmVM=]2bFq eɯLo:(3 *M~2렀[F(^MIIzӛz eČ⥔\ډ1o3ROҹ{R[F(^G1YUtSTU2bF"*Rn+7tSU2bF HLoGUa5[F(Nqgkynn18R̵}-ӛzX\[[F(Nz<}'ӛzRKaJn18,67t]:eČJ᫘u5zK.3ЍazSO[F(hlE~ ӛznz:keČI*Ɔ70떚/㸃[F(\luM=]Nb%2bF0bsnLourP3(Gp/fzSO-\n1x*qV7t t3{)'rczSOץ[]=t"QE8M=]t8n1p:=|ӛz.QeY2bFq;5Lo,EsRqˈōTkw0R=eOMo𪮻xkep{ncnŧr7Wizstݭ^rv(>:yA^uWnY ׌s38zlA^uh wCӆr[19lnY[Ƥ F9Û:jvs8wM{e ݷy .ӛulds7"2R=n⮻cmQ|PΚ99wzs[-Y[FCG)ynʮ;=)e:q'stut-#q$.7N&/72V8n!0r7uݹ_q5EśL CӾC;n4w Ȳ Aӛk\u'S;n2M H,)ӛu%*'vT nK1 Xgq#7^~L2VoP`ω79J7ѷ*m8JGw)y?uWso5v[%0n'vb6u-؞x43vnuUGy-ކx=m2vzguι1=z-6änӛ78MIo8SnOjkQj[Mo^⠮3+RluYNejLo㔮0%rxYesNoiۮ!uSyǃXC^{pzZ{v 1ņ<5u#{>vOMolî{<rG?v#X+{v:=OtV Տb}O^ݺNӇV bMԸW=m5?S muzMV 6?T@z{v r-c+b n@szsmn4x-cb j4vzsnLxE--ch<]U2\o]| պ >wnpm-q?g8LKӛueVg1 8u&tݞYq:SF(VMoqVmG+諃n8w!@͘:kzsn8NM;u˨w(3Iqӛ ug)[F FyoS9NޜЮ;"I6WB'2*1wNxthv)y9QQp6ӛCuV[FG3AtDwYٲG[FGO{d]09]w\tv2Mowe] 2ra`CL+76i+ondrf[ww5a> p-#{F;H{ze1UMj\?n'~-c G5*6F0KMɆg[ƌw⛶pdztݭ/{Kn^;/Ξ=ӛ}.|sQ|tWMo6񶮻{w/1=Yvo]w_h}-Q|NaOwNoڮ{_e}-Q<]^os|-Qo<]|-Q-_1^>y{~/sٽQ]2Lo?;A3 7tݿ޹룝u^n1_o;𯳆M=]_q;)Q?/>q˛~-#fEN7tO*CO-#f*wӛzWs-#fJ)%ν7t'갛O-#fpM=]P}n18 p/M=]SM~ n18&pӯM=]BAuA2bFWRu)wT-#fPk2)[F(n8pk.M=]Eq*TjQEh7_ӛzԸn1*.7t%ZeČ ǹښucTi+k3Ǩ kzSOPt[F(\p+M=]7IrZOQun3) l 7˥z^R.QK q/7t]:lBeČtz4Qï^U"QJ#^uLouT2ʸeČEҙuK)^XQzB]7ӛzn5; 3RR‹fzSOPzg)2bFqyLo-#fP[X7+o޾[F(.w+ھvrˈŕT6u^X'Q\L!{dzSO=UE~Nn1:$tS^R7책[F(~R t݃/ݻ30M=]}ƸeČg)8tqe{ܕrS32bF)ezSOm⦚k2bFTrGbzSO߱\n1x'ӛzn+qˈP{+ӛzn7GWsˈ[q7ӛznC9qˈŻq ?CqpV2bFq1uA2bF1ӛzns-#f̉Z:+ӛzn;ιm-#foΡBzM=]w=eϬ3\x;n[>sˈGp4>ogzSOd'SeČS8ûugtv,n1 ^7tq? 1-#fq%=;Sg7ƸeČ8&.ǘu?&1-#faq <;Zan1\΋ a7tjKKLrˈGsdM0.KuI9>m-#f 9-!\n1>=0Lo[͜H3(ِezSO]l( n1VNt7tzO/3/@ل>\^:u2bFݜ)Ӂu/LRn1zuLoՉ3]M=]*.3_RLfzSO׽~3_RC0^YsˈoYM0Asˈ/YGw1^)WrˈYD_1렀[F(~-M:Un1͜8R1ӛz eČsELo:(3qL?0렀[F(揿sbzSOAQhziuP-#f_zvY7tpˈEB<n1t_ǙuP-#f+@@on1O0렀[F(&%~؇M=]2bF11]脭uP-#fBovczSOAQL#f~C7tpˈŴ!dzSOAQLM6N|[7tpˈ'⬷ezSOAQNyg7tpˈŌ-s3렀[F(fݟM=]2bF1}Lo:(3sn(OazSOAQL sxӛz eČb9uP-#fH n1\PN87tpˈŤHq^'2렀[F(ft'u(ӛz eČbNsF2렀[F(f)M3Gs4ӛz eČbVW{r(3렀[F(ڍ㸀M=]2bF15t>Lo:(3)vazSOAQL%=,M=]2bF1ŴكT&7tpˈiP˘uP-#fVIczSOAQ̃\ EM=]2bF1u)Lo:(3y[Ga/fzSOAQ Jz7ӛz eČb6rLo:(3ه̢o`zSOAQV4a 5|ӛz eČb6g(KuP-#f'8Fn1mi^*7tpˈLOS1렀[F(fsڲM=]2bF1ә1y'ӛz eČb9?Q2렀[F('5y3ӛz eČb΢EK5n1h)˙uP-#fs"  eČbv}/ӛz eČbΎ}M=]2bF1G{[ӾjLo:(39{%ۤM=]2bF1xCat1렀[F(wwݻcM=]2bF17Lo:(3}m|vbzSOAQ}nk6B:ӛz eČbtG3_1렀[F(VSn1҇M%ӛz eČbvbW00렀[F(zg5A,ӛz eČb^>"I6azSOAQ{lᛧnLo:(3y|ؓM=]2bF1ogo3렀[F(vk7tpˈż>ݾIn1ڡOsuP-#ff ӛz eČbx5&uP-#fß5uP-#fÿE#M=]2bF1OpHazSOAQ bd1렀[F(Lo:(3w"M=]2bF1*:Y3렀[F(@ʍpXn1bbӛz eČbjjSczSOAQ -n R7tpˈШM,ezSOAQ j7tpˈХ嚸G0렀[F(^MqazSOAQ >]727tpˈ0Aڏz eČbӛz eČbӛz eČbPn1R53렀[F(8M=]2bF1Lo:(3NdzSOAQ p"ӛz eČbuP-#fn1D7tpˈ'2렀[F(8M=]2bF1Lo:(3NdzSOAQ p"ӛz eČbuP-#fn1D7tpˈ'2렀[F(8M=]2b_G1'z…tpˈ%L`/O^n zNO^M wz…njl(ӟ.tSf;F1p01 =Ԁt wz6 tk==@'W{zp{=}8ӿau?<woR+9V ToZW}n`s>UNۯEܷϾ{z,~Xފ`C}מc/ *,OMage{\~9ħzf^u K)rrVns {|_d)UzY*-qz=u.PvXYJyܽsVú-\(R7_5^wsu?? 5^׋3&;FJKdg +*9sQ9\uUⲔ]BUq5řLo}O#wiCW>1p%I$kOq~v)C"[)t]v;߯q~>В^o[Z&Z\ 'ƶXZ?J{éI/׾hJ)h@JAXW9}`]i-5H* 4&,58߮Zx`ze׳噁 3_Ϣx.-=93{iy&屟l~ ~s|J` HKހ_Km[ܯI̡1e>g8H㓍biϧwS{Oƻl櫁u=l[5Bom6i\論]ɤdB֨=`_iK~[k\trm翮rk';SKjK5ZE!>V{?I77 T7Ǿ>q%m~>R-hSJv@Bד-Afr*>OBqV(| صt>;+8ZNa&84J<ϴ#X.@F|xee>7ہ'S4s3_ϫc;jɶ%8Cl\3i'0YWa~ ]e8 V)IzMQN'NpW{O$1Wl᫁hyf>W<֢xNm ZZcqɖuiLXʦƲVTcY T" DߍΰWoƒI94t-su=u?_KZ-Zh+<8?1pz^qc>\{I"qG>+ ޵TE荜$[D- tOqfvў*j96mb-qzcV5mŖg6g88pz]XWjO1h5Tofӕp]ۘۧh`ѮLfvIt_Ȱ*)O$g ҕFW3{5@siކpW|mXȍY <@[Lr[W<^̬zׇ+uP] Ong,ĔfkLS3Q~{hýlkBo+΄j̤+ӞWHx.A <־p]]oV5mŖg62SO7ly,^+?s 3UF:zi_+h,g;ϧ8k9^+Mg'W-q2{7 ldc)sxտfյTyP}Lꉡk_tsnJוOCʊV]{jRj~L3ɍ6v{2?Km7ۮ׿f8kdrs_+rcY5گRƄB !W4CotLc)v:go9+''hWRV},]2\SR~ϯ) DkəcOKm+LzcmၔRvѵυrs_L׸LJگAڗBT/*Ov]۽3 ĺKBKVOgmdEhWRV},]2\]Eɧj{FцޥO+Mv%ܥ}_<YIyRW+M g۸D{䯙47@JpoU[H/Barw[p}%ד]YЛ5f3O\tfݸuk?^X[8NJn{γqcY5FkYn~ǔ|LPo2{w:l{3xѯN5eޒ~]exk (X2N'{{[ ݯQK|=wsH>x7k q䁅R|V$k4X ۵Z-w-Y-J2XWo`љ&k-Yrh;BMv&E 1yAUZm%JȽdj>H׋} ՘gc]LJUMw+^Ł^@j9eG֝mɂM'%ހ;}7~> ϖ e1ⰱ6ؒcU nVW3)5'ǶٶNJ~RfNs 8xƁтsع7Nޣqys4Q׎ڹ7Nޣw6t|N~vm"p: ?q}6Cnذc{lɭk8Oy~}+0Jʺ3_cղdį$ưg+ëǯ1-o`ݮ៶3-Q8*f%Ӿ-07e%R"K'6tB<:2|kLz75~oy6םp-+rci7>?Oӹt+]l0]׾6ѯ+ΧƖJÆ>YįƑgLr ͶqOO6I-9 '3TW*QjI~6{wڞjJiVW3 /d;ʷkޢZи@Vz1۸@} Wo_#<`>I3_үAV_os5+ܾߖ'nvfٞFj/˰$3oZ-o2E4 sR'$<ܻgM?Kݕ^ooЦuFN>JˎK[T+wԾװq%ޞjc&h ԢN%+zi&X:r$h&3lz#|z ?+0\gfv?5&U_ociX.o\n Ľ3g~S˩eP+1Vӛpe;ZmL>kKzw۸Tkn_ jI &5jӾ Yk,{um_l`__N]3_i`Yte޻z۳m\t8'CWYf!^.qjnaD b2𒓴 'U#ӻ9]V6 fqRD$8+iZ`PDBP} 7yy@G5ڑɶ֒ogwYxiΩ55){X.4rX3JX!ʂ{|zzTgMX~KeR-l 2͔㚗 a_\P)YM!܅kk}t)5VrPDM+br5nTPfSe=> yYc.I05MsBĴu m!j , ȓ$ ZNկ&%כ`];,ȗ[L-*_щ)䲮dZ*7cuE VӨ#$ |BASʻiTVit1JGb^F5oM!WaR#*>MY!F3槰,ȧ,;KT|ϊ-w_BHC>oߦ4*.)HL3V^"u&Њb<&˴CŦ,9q5/SV8 jAJ?2]w!?ctQP!7^_]e4=)>'A Y)U/Z׀H&@A5tVS#<5 #x"j,K ͑%y*m?k,ސ!?gLvGxZP #7ZjtdȩtK A0Le/" ,Z[SӴ >(%.‘ AHpi \nҨ??^澩Wk1wGC4RxbB06 HQM*Fƹ@0m/"F H t1UԊdYJRP}G+ O<l{Fc ?s'znFM?_xJ_3iѨ_ԱE=79Wj4F7xxJ4iѨ_ԸK_8vev<7yWj4>pq}WM޽jѨؗnt/,nxn,^1L>>sG/d.p{.HG^MX{~W#xn,^qgw3x_#;~1BvFj<D}m sxeo^/7%w{0R'?mhS0V<+K5~W^8zoҦ]>=膑F?Q?vm sxeo G/_ 0R'_Ǧ[grN"YTDbM]")e} Qpju:Dur7)v$o}_/vy[}=iS~v,ΩzYf*o]k @À#w둌@ e̖)pV'*3IJȻxZ$֋k.@^믔X\ SC"[);5^l$0<d%[NBZߺ~/*h`:CH`ugiHpJv|jGbeTɠ`XΉe\Pg^i9=`JS.n:'O\F ;V-6lZJXi|k ؚScQm].i-|'SrZD(;*㾖䈯&ZzZN V*#TyJ 9}˸m^zaC!`P"%.6Wp#=>b4 VbG{ X2ʴ(.5Ǜu)aU9=5v Jgrxq"R:fST]I_!TkА Ӎgq&.eIG) [ked%40uѐ΅Ht𔀃 d&"yHJrIG><\p YvXRZ AN.o\8 l2S/Lj.FK `e}8Z) T^ʩY NnHi:`JA/"f{ RYA[Ѯ]8r\߲0He!H !+ )GV *I^Nq>dL݊)w,V:Z)8`e]PLKѥ[95PZI-٤z",[lp=!K1 1UKq5 >qdRcBJO;S wZ9ʻ ˵Rbþwbhit޺(hɸeRʂ7bRq>! yjwrݨ&_Ml'yj*e=/NvLErbrKqɷ?;O1A 9bLH T.xUPÏkþ+n{R4cJ6:Fiq; \ .f黒ՊHcԣ 3[\&P\̺Z~"ي&dzͩw'lrTN5Yo$\3 Uvo Yh`;Lcl'/&`XYKt:("oJ>PfRzTԊ̺:`Ԣ }ʬ{,8B@+,? ( E`Lcx ZҨ1v^wVi-4ZeOt$#vb-FPolll]@ԴBf:IԊN K)˛:/&䡺 .GD3f (M6)R1MK]GY73Up9"13U+툷JklѨv8ői~m!VRj~a0MS S!MeR+]f(jE'ŕ+Rl[.056JMf )ؕ\{nGǫg-Fx̀)e7%Z[P:̱FvZ#;`XYKm17MEVd6L,77 )NQa@T+EbMBzPhM ()MEv"#,jA*duS-$-pGZʨUQ6$ijﮘyr RT? i dZh`#EZr9<*9Ȳki8R7")Kz*/hj:r4ޅt,]c"b*$r4mkVD]W3M-Q+jq* E:,ȷg3FA1u_(^1ԩZŷxBy 똺dGfdjё {i`78U D64}_;-:*W4-^%H^qd4XEvwFĈ: M+d*?JauMe[9uPV"FB5i,}-`u,9*.1VN}S %# F@9#juMeWMWNr%C׌R)SN[)Cˆ(h|!L0:Bz_]H<uJƨ(h|!6Ex%xe )Pc8FpViF\П?<޹8ឩFi45W_Lh4,x?2m=oV>eho4L?yoKո?D0R?Fџ?} ո?gp8 h4snh|1iLѷ_DGdUFaDh Hj_J6/FA@OVR&7Os7?.oFcxV&o<5O>_r`z} Y.h@3v#;8 ̗=o|=q<)j4v#A]bHxOs7[×sMb552.+kF*gMxn;0.t/nKw:/揺 qAp/ Gxaѳ.Ft~zN潄xw"nGX€y+S=z=7`.t/7xw"nGX€y+S=z=7e d|!ޝ4?.V0G T~uGM~t1z}Nvyt2nu_3(zj,O=0fy퟈M1[B{n`s鲋a |Ό=1n|+f|Kȯ<0w> OoBq쵀i5^vL5{:8=̨IE"yZ#Rk 8i΅5CF8OK,bJJJrkE`sLЈ-T@tRjqX(VM8c3R > žh)x5HPWmȶ?l0alEm(ı)GfѱtghY‰,AlgJ .Nq̕9|a:KT*wdK!R77 pQlJ36EHxik- l\*hbG@F,N^ ᾲuXQ1\PVʩP RK2]ij/.i/!L@pA)P<:#F5;V<]haLXI8cFq:dQAJ ˕"+#GZls`ZNdP+{zϘl; H.NKAk'ƋvB5t`/}(ܩ/o<7 p '+hnX.ˬV2qX55Úi](㘚ھW`r89=4wdY컦v"H`ީ)mHZP/O_TEh ]]SL;i$0vH] }NG ,߻70`u* NdO+>clӟpK]5kgJD+> LNpjr)ŕ w\([He7="_%.T0r\B,5bcfQ+/ ֜뺽gL>2?.):BtOYc :Fzda⒲{$&⳸+}!y"T+} IOY. ]އY]ԯe J!3W`[R,}I qKk1t4%zw|;ΊOelRІie@STF,}@R|68} !G@bKSP)S[@hhSAgA PtckOV3rIM_dp CI 4V/b&p@)zw|8N|$=e)B"pj1M,INR}W:ˎ3FBN mʈSc)+vBxViܟ'T(zGΕ59+p*ׇ`KĈ/ iWEa{R%Ndă iq,!d0A0v6x[,eHȊ\m^mpGR ^IL9娠fUPs L9X}M+(^Ee5#׽jr}882BZ)(|֮\95{"- H }KB}VDEdAǵ"#;>/䀆VBƤY(]֖qp'%NhP8"gMW_Dg*a)>)H;mkw}4[j*`SbTtCnVn*pMƚZ mzqACd!A;> stream xwg78zM)EA@bA@TQ](( ADA" ({_&;meLf^&)o)3;IpcU JQ,x;Efљ vΣ_DG/Q>s(̀C6U[a??=y>_:{]͋D ࢄP.MufzO&{OYAcEǀ(F*3YT>`9|Eࢧ}ܳnJ>Y_Ӻf:z =z^SԢAD"s*'/;TxJ+L*/\MX(1̕TZ-{GO-zQFQ뵨*V}`u}٩ʽ(,JZ*J={. J%J€(H>tN! `1Di9mS@XL Q:EE ]+ tQ,&(D z J%&{ڬ?nm{we~;(]ݿfw5}E0R]ЛrT}i *LXWK 2^c-GrzkaYBRqqer;*/ qV?_oQ;V9,SĆ#lH{c^J6.M'K躘L@Q^&7 y狢O;Oc f( D w{I* H!ba>vu_^~J;qP@bI8OYaWy JrGYf kgbCrOwK +W%`G]Y8ogZx| ]1(PV+^`W^wa`^A:z7$|,&*'3xzi> ګw DRCV;IHX-ld)}GŹ>SP!y8"˟6FhTW^y [}I,J(?i${bs_(N^\A>Mf4 ,խ).n9Z,a@8,J9q 6W7A> ItG]_ӿ޵C}E¨Ib-(K[_ LQMF˟xLhDn&'ҟ*6G(eо$kD`QJAOV&!̼|1DIKo ս* "xzРX{+_)("6+.kdD)7mWd)ҩ+g)S(MN(.0(UNiX \𨵌IEJ쯮_HV>Q,A&RM/MKѳM\XYQ:CFAڨ.gs_o((UG5gΓ⣀w{D>4V,%DiXADiN' hJ-I]$J.Y)HgkdA}~fK8(TUl+GQ.4/C$Gɉ{Bz2tB |X$X ^?9!.k7~[/'==]Q%ӧO >B+$D>cgBZ,%=ΚDIED( xL]E||Q:,ӎ:~O*=Oti##JtQd~J׉ 4\L TwEEQzDagHnd#w:霍P|[*J= IENߊYɸ ;)H,Do4+;RYi_4G QZO9H`cZ#W"Vb9Wr/+{clfWAE)) (ERZ`z}sbgߧo.\@80y'$O+Q.'y?EQtf ARQ:I{EtM rO/BՎBA(ѫɆkXc?Ald%mbT3I-]{ P=4qJzXM }N<Hbef ak&QʻQ*J4?Ktį݉UN`â6 9פĽ=˾& Цmw, f`G^+k(|e**PMn$Joc˦4Z4Í7qxŰfQPI[NCz0_OgXYzQe{~lo@.ÔJf{[VIWE)NōqJ1ڑ`d/z05(͕&(qG2 W5Kgx'h doǥ]Nz#̮5, fL%:ƽ #s|Qʤȝ ;;bvO7ׂlwTizsA޸W%|?e*~UZ"HRtbT 71LS#J(ޥY6%;k7,H۰;WSgְ(QOqI*J %)%B ].m-.;JvDoE).ڎ< 0Rʰ'JtE)\%ڥ׸(mL$_PouEi<9 틵FW=ÐrBD/}]ʈ ev-8 #$*MF\\V厡ZQX^D iJ0.JtW̾ՋREъK=4B;*jcY$S2Qzؒ圡#},Y g'{Mq+){ KF[TEޯtt%%Q .|-%u5ߩJYhtsޘ]cK%a/ b(Q! |HlQ&1-C(](@[,qO`L0;n4^Yl I\tQAvZq%R^a^V/JSS'DŒsЦ]}}=.SM%}/-(c Lv+I y»t_% {,=A $J9tR&ݔG)s>fJؓt"766 odED UFj%S@kl  Uq1.JzHo2Dkqg$)m?E{'7Dr~Ml2khyXD]7a&/JS#io?c(Ѱ1[FX I£Enj#~lOx gQ"{Qd=Rb,"풣dJ%ۚ=~\JkV}lDUшIb'(WL%}!]a(ݠ3$sk%]+pQS@v6D)~7g_Vf:Q& ^QwugQs+<&EIC X"JjfoS!,hvGE+0dhnc(q;yg/,9tdM®w*҅G\"y_iGt5Wao2x5bɋ}a{) R`+ɬJH&eO.{D!/G=gv:?Zc!W%-2cs#D~{T% k\% r^!w~6^/ZK?7F'!T/|&y^B Hșhdn";ݍk|Kȧl_ PT;ʾd)~Gښ^ÕMʷw/K#\ !$]rD,gMfȤqfO)fxJjcWOV6"6rwDWTʴGM&27΀J=7tufvs⼤*OSG n̗+/sL)gTb&>s7Sq 4mp¿ Ti$WOI&˺QbFSKy$BͯT-JjN/.7WqjM(1=8srF%?*%;!ѧot7?6&%ȑ&~;%)&rRl#L$JLz_ѣE6OIgF,J[-ٱ8EQ+e#ZXY5G[$dj/» <\n!֡qnӂ}VӏI}hɺǃ&grv+Y_7yvw n!ˮ> -2z5 ZǓlv ӟ+}fdډݨሼY.'a{5/w'/?ï3 ~n.g8#w݈=5н߄-ʻ3G7=o!ѯwoA㏒C˦+?@֏¸S>bWe=ڵJ!0"JXoh~x7; ߺv.FLa`?v>tƤN`%(I#-(eeC~&+Jq'Md('<xֻ&4x u#@Vl5`-4pIJԐq햲Ip)hJuz6w}0D#b^~,mH^S8 ֎zjEbR[; [ӓ d787n }?%-d޸Q+}O/?0'iدDi@0'4 J@?r6WX(9 VzʓV(9DqŒq,)ǝ4\eR|D [^kpTr^.h)h >-D Jٛsd%^+(D D J`6 JQQ2 !@l@ fd%0M^z)}˔o6KfKi/?3`؄Wi>?jD x_G9JQ`W{M̯wDi=֨N;ݯ;_5lgl7Mg9//J3#J꓇BD"!|rXˍ|Ey|+ȝ1¾Vv[L;\gwfįw٣z w L?eh_QEOP<ZYQJ׈+,t僎|"`d lj�^jJ1x7kϞZ^'˱_OU%zO,U>/J Jϯz޾,(mYweɚ)J\aLȯB fKZ@շ ]) Ҫ,U8bU~dh+>? +TzD/kI]n(-(|GY{Ţ(7UWcEyVރ^\(SɈX_˜gqQ3tR+J0StO/k{ !(}C,:KDoj#"{qpҏV?@~QZAƣ\e2~'҂njט3/C e R%J?fҶߝťN Hn;};c2W(=/SwtNw*EOG+G#mQ$l^l7{U&WxWYa$_IIUVaN.oޟh΄ØpHD+5==[YhM\^f7 (M#TjT;>wֻD<սk5{TRPo^Axyl c\DZc.kNQʘY6lzg$lgϊi\^)'Y#V|1 2{a<-#Enij+/[{EQg=~,o:O 4_֒ L@oD>ض%BRVwRY'F}ڟ7otKΡƽ)HQvIu8}GC;9w]F q{ 7kuu[zuBN$fD^BC6ÊJyA] O7ѫ"1+ ~Uzt_"IziI0Ql{bs Qʹ$ٻȴH䮯FQBОA/BP³Bkgw}؏BE\xT`./͎-oBkf?5@XJ'(| ("%$ z`Jb%ND'v~#i-fhheCLDY4rm<o"F(xC> *7$J:c$tY4ANX/_t"$! )o`4Vj&D@D_N'3R[5ȼS1\^Y2sL=кNe{&KG,C@ҧ$}1$JHgIIug|}-"|9,t Io $Jy2sGd JIRQ隚Ig25TuNQZ I$?LWZCi)IJQ!ptLwR4BEQЭooDbE% Ri-"Zmv*JUȷX@&IHS[7zW.QJ*^Z%ː%uΙ$4gNg_UYz2٤+,ӌ)!Vʉ7"J v cT=)B]MMdq"~aYHFWQzY*mL QʣZ&!5[o[ͳ.Qn:nM])1\dÉ=?jJ0e0!-S:[/Íx ~FPQ:2;W|-a$=T(ʢV+6yK#]]$'JoK k+)v:sp;¼Pl~ć%I1]XvN7?eS,ېx%7V{wLYy=I޿&ew .Q!:u,M߆ É-vַ0'~HDOVo;ɍ)ކDI2EihW6{FK7-Mv/n36KW4+GY')r5Z2Yg2Ih-\zH#Ʌ^$oEzwo]qAg J6"J?joo{u{MZܧӔU㙂͏P|GIJJ/Z$u -[nx/Q~Iߒ9:Oޏ$)[qN~9pȽЋ?KRىl[M.;ihCkvR6I(J Ӈ<$|x)WLM!MʣvKA{r8v-/9L ٿbl 6M:f(!It M $Jt!*6\0Hԫ5 uˇyDK>Пr CvI:K7n<:ݏO{\ï#ro#n4X]BĽ &YQޔӡ ZE>I'k e(t\17ib/4Q! ! yDMPƻ}LJʌ:%JtaTQKKgsP Ey&eQ!k Q}$vD_*IS$p]r)-@¢Җ9G&u@ 2y.N~}H}3Y:Q2l(O\" M Jt 'hR)To\YKf$JkMEm9H~"M⢽aJvb#5M=D l$z(yI}L%ګ&J7.h3)R_"]UH&tBLxNqWtRo$+^$[BY&JQk|cQnϾ̍AvHȸtD3EiB%+_Llç(Jhfi<5S$7+{7ca7D$3e'|tb 6.tYJǀ%V(l}<;M{!Q5>$ 7Ub2I/[6EQJOBIcZE^U_uuHk~-%J3߹eq^BHK-"Z-px ٱ~@g:O| EQ"oSθ((-/^1Un$2B9CkӦ߁ϷDkf5IJ {wA'HCk<)̾劉Vtzmi)kHJ84 1&ɺHm;$_ 5FQZcT%:N:|M(IoE/|NoGtbdE,bї}o:#BׅD;KNNQzTC{yMW')O^*<\J׀p%<4cwǮ("?_AHhP7@c(}BrƋfR^dVyp2b}xX$y}dE)C{1%ҞqIȕ9S"œ#` :Kv)Oq&nwp wgWظVA&"M8dm2DCHQ0Mw QXif +Q,ϹoI卵/QĐ R{v?:* W'|QkB6z+ q[KD| dqaϓ]d|EW6j-_tRC6~E^Gzj]XIDm^~ "¾n'Ǡ.Z^Ha(ўTn wpVc(-~3 f(1H&Ibw)\ܷ}B3 \r;7o Dnry2& U}vo[9~.Q_\]xQvzm&/⾢=엤27^xy]1;Ȼ$܂<[؅MчҼ[,ޝؿ0]? ec ýEHA7c-#OSH_'zn~d9h@Vezצt.R9yr/n=Wzބ Nm/4"q~X^i\Tr4Yw7֑14Jyfot dTva,Lj7$TYr?'.m-:*Qc֮e o?m_"?#p'k//`5ߐ=ݓb|$~.-CPE \N<ǖ2j y>9u\?& xp!_OY+KQFƜ=ή5fЗW}/9Ll_ Pu;'{ sp ó R~N[ӷr*if:;}˙njFN7fL&pMgnB[/&^pۙMg;ݒz9\Mgn|/@Gt2qK J#\Di 鋥%>@D}SQjg4ȧiWKwO-dQBp/v%TQB%2 J.D e@\ʀ(% Qr! J@(B@PDɅ( QB%2 J.D e@\Rp, J.DyDrڇPDɅ(9ά|O(%YMpiGB%0 !)Ϥ9] E@\,ObU8LB@J|/3;mrڝDɅ(9If+| ]rn>iB% y4;/w$g =@\'P+1{>jtQr! J1_Q|s J.D1~ Tp'߲ Qt E@\S,A(vж(>q($Qr! Jo B398C Qr 6 Q@\#\\8%o U@\7î?'$NfB%a[g)%S=PB@vUqlW_\ Q tͰˡDɅ({YSgjyB%d7_,מjáDɅ(?IE 8eC QűߨyjB%d+bW7;: J.DNn܎]~Jmqt(Qr! J6{^o_zoy QgÍ46=CqwB@c0ݖ^ơ| Q bv4>+(%PݎQN*gC%dZKw,l J.D+^߱lu(B@ltEz}9L J.Dî5P0v`G(%j=} HSq*"_B@'vΛ 3 r s.v+5@\UANkʾzRk )@\EP JbbU QmEj]yoDɅ(Y‘طQVuoT B@b ڛW[[ŵ8 Qwb%fe*q%d>9`Z۰.ve]W J.D|b^ںr!@\|ݪpڞ.ĕZmOeNB@f^j`Ͳ:Qr! J& ՗Ǯk_B@eS"BsmrQ延Vi J.DT>}cs?J{e\=(%39W4jJնf{6B@Lz#T]5[ Q2ء|Fa׵TDB@)O}]Rt3[ Q2;U9UθNUo J.D,aopvuKD%ds"J . Q255eNL-'a/LDɅ(žBؗIN{,Hnt&B@Ty'N{(ori7DɅ(ؓvNyCNa J.D8`G::;0 %dǰwLGuv^yNa J.D05.:텟lvfyNa J.D(_a/Jq rϧN{a J.D 3"J"Ey)Dz B@<vBʜx6g8q@\!vJ?9,kٜw9a@\.p%9ks (% ;0 QOFsyz+ΔNa %GC39;i7 B@teN;nDɅ(S\{U؍*fp@\N~ď{Nծ鱸t ݀(%},F(vCkay n{8^@\.@(WgȎҸn;:Qr! Jz8TW=ڑsMU~nDɅ(B5\NԬ8.@\vn4?q =(%tɲb侈]:Qr! J郫wz );a} Qʇ m(SOe;V@\F&J ﵻVX\{nhDɅ(ic~Blu m(%MlH@(ru!v&CN %}EqmLγsnt -(% kdg&s͐i74B@si+4g)D}Qr! JnE|N{%ӹLQTi6.[vʾ9N%l wpmUVu䁛N%sD)_JJ)=:U]N%SjZKn [ JA(yŕ8ljڸ t e@ ;j (7ۼP R@ u8喸 p E@TEۨ@lOAU8MfW܊: J&0 80)F`Aps+k^'1i7Q2(%@Ė ̥[pZXA9Q囡 9aE.~Vty{\Q "pj.?3}"$7"Q2ʚsDUB*([B;kP܊D ;S7d>^ JJK}ٲCmlY܌DGˠ{϶()0^UG 9!.P|\du(3ˢCM^b@p zDxDz(ɲ( Pg>qsƇږ JnV)8"A؜PDοq{Fئ J^Qp ,4(p8.k+Jm>a[t^QTIӮ%Bg~ sUqoYPp3 Ci`%|yKGQ8 % 7rN?{YϽCU)h=&oJg3Q&$7bF J:Y+ŘV@ƥ p >*vDI#:pNz%pCpjmk[fݠ(bOa4Fn/Q2Y8$ Bd;`%=(}j%y%D'~7ldK5ѳp'Ѩ J|% N3mڐDI;79F H2q(CL7>خ@*c{ڥ)9+p(}Mufigbng,/9@0ޑ{xgY5S*n> ﳧ+DIYkLqI#'N q(mLD(7}r7y;QRdE\#|C\FQ>S_퓛W `C644JCÅt2rbiiXqnX_KOrI_,+}t!>L4Ƶv~DIsUѫўV:Qnjkb#QZCW$~v(=oRY\ YmP;n/fm>i+|rcٍ*kIQ!;jdL!U`8|H[3ps>d J22#WZJVj-p(s( ypdZ nnV<Qqvڹ:|5qKDKAK}r5Kqb~ J~ۣ{BtwQlJs(MIl//F #jpL`|dhr(-E(j>Qnł(X$H4[ o hy s)nBM.Dc*aGOl.t4g^U@f[(e'yU.[P3Sv Qt+>/kj JQˬ4.5Gx {QJ z0$RÏ!%yAOdtC6/&E)a!?ٍ*{eW ˞h.Gޛ(xpq[ X^ (aNCX钙2\>YJ'b6v 0j-uT% N oQA(y=>Ueߤ@MOtc1-P a-JYjO\c|]n00NgnVC- (m)g]>; 0ߔ@Bu-XSh)[DcQ:TaOqGM4(׋ۨR,T+J 16PE+T̬9;돒}t؊ҍ&8[rQSԽGGRN'xwFqsd8vEiqt_6d uWQzվlO%hr`)MIpAO{+SQ';aOE~X!nmq"WAt(}SRw t=|Jl1TET=.Y;P-='(͏D(n>Wb#EW.Ae|ڪp E̴'@JEh׊Rzs9R2*P1Ȑ&VQywFFD}3m}d/KUid)ơA ;QV[{: ϯb<]P2(1ŖD;s]LOp(R,̏Z5Vd?Mo;(>K3ńB\݋*/QbX56Cl`%p(1?x>u%RW*(1ccB=`%@&Qbr~bQJ ;Qb0G0mR%fgYt0hp%fM!l&\Jw(1'뢆n W2'M<2=`1E>H.sv2r (J)V6=`9y&JLӨ[v?Q5KQbID߀]%PW|ɕ6LH%&;2=`ez Р EV#ITX<;LE{ĝ3Q%E3Ķp% {vAkQLw(1K~ ')2(1 mb:*ܪNQbF'G (1RMJ(TRQbF擣lH΢[y&}dvWI)[Eꉊ''[MZc"_%4׊ Dq3qINCU-J̥MJ"7(bQb&FR8V *1(1#}vK L]d%,J̢$jxln侈tmbRvPbjQbDS܏fIa/J M{/RE9Z.zFr@)z6le~$B 2\.JLZKTUE,ɻy9DYc{N' LE| FRe\!J?7ld_|}Kq(1yw#y +QbUC7 {l|.9☸ I.%|m{64%ٔ9[)-4mbEV[|eSIJz4V+&(&FgM}%YSSAv(1j7l|Qʎ (.5GY\Hv(1F"՛0_ʏ%+**l&hDnbQNQ{%̈S&X0>4-%/rO ] JX]=lO%E:n)@qcڭ>?R@VBmB~C%5*s *xA@PF!Z J99aB9r*z[ J s.vylJB(b#@p*bs\kx&A\Rf@1jQ F(/SJ6>(侀eJYV~G1 J=ŤL'Ss0%P7Tz#Ľ4ؐ YY@(piJvɃ(aE*z&$XQXkxC*@?OmpMQ J]ݫmg>@|l.˫{ڼqV ߗ J8]S.F&sUqX" nڢP]fhUQ:DƸk,27 :QRKNTp%dGAO͏Qs#.2~e 6zQREhi7(޸o--[uCA4c'&6r8~R@D bKU p~X%-,MAυn'tQ3!tHȟ\Y(ibgYj&^t9 J%r;¥ Z76NE O0'PculHsBǍA4rNJU?op%Kr])߉DI+Oԕ#ǃ(q.PpC8x%|bUmi=w*DImpى )Ë@(`r͏[e%yGMt"FJQÒdϩ}&D} @[lXU+Q!ϏQ~݃ ]H4Y J|?=Qn 2@q6j|-.DIp5i5qh%\i*(,.ފ^2^ RVheKFsx}QKVOTx5Hqj§R vU04­>tŀ(g *dwD3M(D) 'j:Jnep:bƋQ2ĨVj`J8i\n+I}Bp>f%#,JB7R&bN:R2ŵlu5aTB)fl d%уvԌ44uR0^xFX^O8$efd5Fƪg'yIE(g^*Ud~Ym_!%kz4΁%{@8*k#MlH0oDI %Z^|υ긱TaA-co4μ@T$ {*ܼ7Uw>vALȈіVp<lbq J8RWVvMcr uS輀(D>ѴZ(❸6CfiŁ(J7C: DI-7;l7Ry7Q25PSqw(&/w D$.5GZRrotC@ J-Qś4D,2b-(]TE(ia~w s6$WIsGAL# 0RGbQء6,?ō?sQ2cM.r'iE(ieS1\i=WÂpӼgr Jf27ijÒ%fGQȁ*֊ y5 ٥(ʆb#e<+V5~5Q>#^,f],GW2,> JkAa$ ^,\hn1)]sJpő9ty7Ie Q2GP S/߆zQ%=V=ȑC=ZDtr_C/&?x1r(H\wo{P+"Jbf0jfU]%}̉ǕwtfgcuBQ&D fţw N x2\ NƵ7>TB)l%KX[=n( Tκb Jz[W_՚5pC|dQ Jְ 2ڱˮE(T]\q'3U(Y&QLgD(jk@"=2[FjD:nvFt46zQ2@؃N4ypa~ J*/dϏf;#Dyo> qgϿQ/LeRD 3bZ=ŃP6kDRVB,Z:*QnX=YPtx(YJg2[/dQ2̎2؏[t_ jm Js}\u.@s&vvݰifq% JVs*jX8diͱ';톽\Vd99ϣd2v|(A#ؕ+",)?b# |V5n kVdj}a@L35lTm4Q`j+"m dS;] Ń? ZF~@awy.vS69dK `Zzh>ӂ; D&NGuOH?\ %Z;TۺW!"Rܖ@zTV\U/=*i7fsB3 D6r i(Ʌ;KvZ'i&2(#?A? jm!@LاNa%S|î@\5Q2Scv:n4'm J4F}Uu %umZ*d/;ˢׇmuDt~NzsxB(ɺi;bbs%#;ΏpϬ)+QPݼs#Vl,=i7g>{DvF~Z9n@`eZvlE"*ACEؑ^?%m}+b}.9 =$zj 5\;nE)}cs J$=0jD"E~q">DFn\݆0~2(Y{,gՂ(9ڨQ[tadQU># jϥHQr+e%QqߒzgH<@#k@Of(YBl˞w 㼅ϣ( J.DR>V=FϢ'jQr! Jr}-MT B@,J+eҟNaE-pn%d5ݱ?8~v'`Fb@\:jVfs,cjQr! J6%Qe?'r-{_ǪQr! Jv0=Pn &(%[X}mvi74(Λ9B@[:V^^׸ J.D&݊-esc>< J.D..݅U܂4$ɃPVG]Qr! J07P_1߿DɅ(GaHPdO;B@d;amHIQr! J2%-i7TpFH Q?w;O 7~vq~: Qctڍ <#(%9T ]nwNX+i/%Wd;o~vڍ@|=,{i/X@\ܸ;gWp^xQr! J,w!z/R^D^ *UCQHQATTl(>(* AZ^CONٻI.G27;;7o޼#tD00SS!CRB?z?d!hRStSa""%iT B"6;f(R @(R3ްC.b5GSEJEJgᐍn moHN+) )|4>Txωp""%cOyH~M%5 PP p6? K.܊H)H)7bJ}@~ë~g(R @(RHy y_^ rBfl/KϷ3""܂ʱh9|9j>) )| 镔]FH9YߠH)H) 9]Ks>CRBR.ҐZGrG7g'r Y*+P 8:?xPPp^R ^h}""܅ Saskkr^;) )2d< P{ ߪy>gucPP05!'.y>TЍCRBR`؀l6B ) )B|9k{)}!k#7 EJEJ[!k1'[b[(R @(Rʕ8T Vao6~0ޜl@@RBRę"e[gC-,""\k]!wgW ~9wPP[d>?[Nn-qg-) )^L N̎Cu/fGY EJEJoAfqS rDz<""܌"!w_X߅H H r56<68q~ W,2H)H)wJ*0M }Wfa EJEJ'\ߜe/ee7) )v\Mv %(""\EYוא<`4ɡH)H)91v:fAL9EJEJy7M0V(R @(RXy7&cy "t*KSPP7dɹ ?Y""< 5o"`1ғCPPWpd~pB) )\l 0N&('H)H) /d8z) )!8cۋ7ź,OPCRBRl}-5r> L΃leO\p]< T;M ^(R @(RkQ ]u1^>m V(R @(Rs6wٿ|FHԖlLPvBRBRB?zm(!!ek CVve) )E_!俥!lOPARBRt!yOcr"AEJEJy!SJjn[\EJEJyA]$iS)(R @(Rʳ^B5r,AEJEJyBTsr0AEJEJyg(_wh2v"o )PPA_GOPVCRBR$,Ine?'H)H) (Ϡ1$(KH)H)(WGWQ?S{<EJEJyBA48mm5!KH)HI!7CRBBn""% EJEJ r3) ))f(R @(RRPPH)HI!7CRBBn""% EJEJ r3) ))f(R @(RRPPH)HI!7CR"R 2*R b>͹"%_ŗ9Q)2x"=CRpHIZCo]><3x{XXs_>P),&*I酰g՝7D(Q)Rcx>7h;{!+}K5 iKx FRQȞ=?=T8zDę5yEJy OA:R끷J/)R~"%h ƩH)`;II[Ҏ^R;EJ7 EJ\JJe"%ߡHI! 5$.a.$<& n֤L;HH@JiW]H5yI)%Z鞔6,i#ɉiq景vt|#8vE}ܢe|zO ue堦 m.HÎjBKo>[^UhX/s鍡ybF4APaLM8h+Eۈ=G+kAjdFjIiĐ/zs4گӪ<Qs<*GBJ[ _, dMTfMOⓟBgd`"kPLO.ķC1R*p7z oj3􉘶Oq'77x2XNN s7TK>4ă!Y k>uxil Q BgCGVͨwM6)?3y.zP"*_&k>u>ƢuɚWDn$zk(RM  4`14PxF|3U4U_k׫\5,Sp! ;}WXtHK8?@fС[ Fp5j}7~(O?;YZV#E? >cC;'I y牭0/I)'Ό}˭@ ; ;_Z>t83VOsx[: j,׿>`d_W|#RGe_LQ?NI3딜ʝ㉔0I%B)I4"Gq_06:AkK&Gagڏ Rl²!q vO39QA'0*N}ac-`~AJ(,Ο`ؽG5&A0ƒFƓFZ-X)q (%=HV9I()!@ԁF4|W-Q~MٍWN.%H/W_CǵFJ )aq:0ѝgacϿ&^I~'~IiONV뽐? ҵMxYAqH'&0UDRWKݻI u!")O~Kz{R D4?)նPg֤GHiDܯb0&Rp^{!`}Va g<ehn*I~Ii @ mT/rRZğB:{̍do>\ 2%f77CPH,RP2r):TQ|3U_:7@crG2EN Kd%I5^:jPJJ5 4@lGy'z %`Cxx/1< t~ݤdȇr7RQ4`dxHJ#zAJؤobg}xkMJK\?) RDxdRzJ<'lASV [Ds!1鄩x>λϐkxU!)5 f8R9M0~J~3W[1e@"֐d" +?d| !; R\iCR 1,[ _K;#A|347R0$'c*<^H(z{̤2dm+Tg^@aWR!?bȩ<~]BGԷk'Y5z#tQZeUFuK =͐RyBp7R )37 uP;c"pin RBFVV+C\=LJ(OEf xdR*ISBDYY %$q(`h^,4d4|1u")AW7t .B&֘F?{s+dkN X0y͈>~?O`[Jig ^RuLeCUHΦ0 <ޝ|0cdV4uI {l%u?x+)t$Bp0pwRJ_c[cAn%H:PV\n|獐R9z_ # z+,Uw.xw)a )a|h^4$lPpd[ WfŸ! Am1Sv()$p`uъGfㆊOo߇g`OH$>pmk>qHJrv!k og.-żT6=TËԹFncoR(ߗ0\$΄ fVbK#jբ[Ts5 W 'SH N[,01'q&%?V*C)#&h7蕔d&]"dD6CXop%d?el~Y%/ M1s2#IvG]|<6 % :T=+C_R:̬;6YF8n.g)~{N hӗȱ1\ $\eo񊕥)II/ 6")}#Ÿn3Gi#!:^9#,Tm/HJj&Ik?`F1X{ݓrqpgQwW|G сͻBX*ȍGJ|+ܾ9ӅvNX葔Nw@?6]VO\4 pR*^ZBJ#Pn'5~MJqbPbܕb.42?l%eTؽzX[}uISEkk9IBPϩbP&ͬr ;7HA3>hʤ߲*t4IiE" Ii2ɢe2ۙcl=,S!)}ꒈ4.X|]}oHmL˹"ˮo."!aEWS ȏACZ.E%mKpyM枯Ĥ:4C^6N:w4˝OjHBRTͤ#x&%}bцt'1 $ AmZfR+]>HIߋ@Z'RH bǀϤuZ[t-ҙǨ#nA!w[w4RMbȑ)SRBfwRbY9E)u %X{:dv;"{!%TLަzc6F.7%ZLJ#3@.IY)n?$:^/&EZV~yADܮW dIJ^ӟsd|2pϩP_{JX<@J2NĴq9r')i[h-m&R¡&LJC\H%5) -H} p}$]A\LJ|rTsH 3 -H)&큔:䚲>.I۶q )?4HiKRBGSB&Ï1]],hMSB/?Iz_тPoZj c)Iigf7Rc*Fejq4ohtleIJNQ"/5F8Q$'*pق4d cT6:pZ׉$eQAsG.%C$Q L^BYc%3#ԕ?6}b qWU>})IΞ;)&"ބlD*3,Ll.fM򁔖EAJl/6A @Jΐ3)}>&`$%tk%11 Re6Ig(9L1"ٷeh`X3LJz_-Fv * ֍qeE33)0OI2SɞIɰX a VnH;G4Cl0+&2ZY͛E*,5:t wW RjJH&4->(v݌qaT(}`Z )Mʋ0Վ %%9!6[FfHl,RPZ}7NJAAPf ڢ\C F~̈C,Q32%kbgR- @JU6 Ϥ4$48iHJFv6D(y[[Sjg6=MUε8y6]2AR*X!͑~K|]z !eF%ʔ$[oH&; xO&1{bϤTF9*,_lRD45p8ߵ/One) [R@J(TEv.*ns! [3b$R EgoQ8,xX|™8JSIP<%rt6~FʒIɉÿ`F16R./yDJLjrY+uRjޡ@k|ōBKm9v+ t*&\Oݚt3+*yq$Oʺ*B],RkG:[T8h¶^ #JBu1F,ny cp%%]cJ3t[sonP'kW;S= ο]>Y4H4>*Kg!l3Az~M+&O_TEb bbp,"ޅgtyaXf4oDz0o ْ_M4V|]1鎇|AܩČ[xNOtpe;%rdF!G߇!{7=ddtYBiMLL-V f'n`8wϳGP{Hύ4cE&%5U{~[NbpmЂ?lS01-Şϫ"&Ϸq&$P X0Bp@?kb=wcbp"Dfdzrľ~۶|X0 rVM-mC}[q=jշ~ܻA! h=g;yucAWUѨz7UT|Q[ۼ sa)l7(}C~U(ukt3i*qi$ONRe#[ǥH&?f?_ bƱX4)@іXQp?G̤4FOT[H=>~:kyO3W7pfB5lrDJoI`,{8q~"==88l!݉MFL4EQR.;eX>$2i|YoYO'g2ψ40(mAԫ5ҿ\@n.m݅?-:t#ZBo.4Gl*PeweW]vzˈTy[[7pgF՗H$U8}Y׭Q>v_=6ep×rH[>w}%ӷ:{ѴkR־Q@uURulѻe.sYW~Wթ)b;/>آey oq;+;; &j&ukqIVo7A?>?C@65fe<“MI& sLմ5̤9ګE!W\rLF]ƽnH?CAӹyݱEФcy=ۡI;AGDɮu hu.;MyWQ|+6m;ٕg'oմFi35k0voy_Magmt3KQj֭s?tҊv-OϪ!ڣ|SkvhtdW-ꗻVWcgՔX[YV*Tr\I)D+\҈>X![zҹ>BB jwУ?qT.$D7,p\݊ZYv@B mSRwAfqwBk:]ysIТ }~\Mw8^LH(t;5qw[ج_ql^M:7 ܷVgVّ܄ )nyue4 n<9wvÓjCJ^yмDT̰qtȪ۱2 ׇ}{u-qPpߍDp5 $x0KrEM6 D&r[]{SYg27n?l?dr-QaNKH^k[](HɄC-jI肖z&76:1їH'`:)]&C"׻G2!%)~ <d6I|Ny㳢>!KHaٟcC8Tu+Rr!%툻?Q<2X {CP-l (RNJ EJ"[nEJyWL1gRJ?lȄVO3 lf%] z#ŒJ.fnϤNWL+-?|!Yr]sF9r&_tn-g=56!`~=KI)=U+[)9/XFq:ii/FH?ݺr(4Wp8<1}M{$،O[R.jY>"))uA 4 hڱI5ˆ\JTc:4egG8д@9D {ɑk ZD{k4G%.n0GjII)i~L8)Us2CADQHy 1ؽү_m#U~#bM;3v괁E5BW..F\$WhmKs㓚s=фDǰcR>uC>N5u #$_Gv?P4X*!4"z#CJz]NHB miy3_οIlٵR1O85}&](x^InХ)_nn+'xҁcx|yx@pSkg-v]hͬ:¥q?ߊC܈wWRV5_l*mMƩ.GDm@()2>O }a hLpQih@h%c۰.P LYЛ !RKL؉q~Y^ߌϟu< )}ot(,wتŧ9O'BIip,k2Khȃ^ ڀy[ v;Eߓ 40Jۄ7~٠՟^c$zALpNJإznMӎ."Ra 9)-*lmvv9xJ3e&x$u55q`m ^.R^ ޺Rkg&?JJ_.㭁Pvqo>Q;1d~!I<-p@\e9j<3ԭx={t)͓Hi#THI }eD,R6ħ#1J$OЖڴBBx׾LjyDJV'ރ4yrRBԆ\YR? qa~q2#u;?rNil~O&-V8>Be}AT[^;l&nr/nl"%/aT+r~K,$3P񲾮":7c9TT'dz%V's0ʺum0LJxxk$5..襑xzLw)i:c'Ұt?$ŋdORh$B))CA{ZZp7WRcRmDw^n:%5`34g=oTxu*s}m5-z,-0ޔjj+AqP#~1sJmsz%$]W@(Tጔll9a@̼huP,C@wչX6$Y/rbNJxf}>p%%{>&yek\(F٨߳;)x'/0լUsxVэ l݇[LHJwZQ$ ;ߪd~A!TL!3%%0g FE_K5yH5? oF\lҴLONJWEokxa69#1i  HJ@(K _9;)sJH?R:zH;)2 n&%PJ}D1_X[ n#(AI.|,fJJݧ5_:)qb.ȧV\+Rrx:Q.imRII1?f)!Lͤt\6w.>EYӘMh$dNs0~%8: /{ļrW闚 WkM? =Cl3K)S<@oeuݝPR2uq%%c,:|uuXר㽍P_xGHr,X\`B/(TTy<] jԉ$O8,;JA$[h7So{wRBe>mHw&:B~e"{H[`:mu/B1ُ\lA5CaT%b߅LrXbEFJl!:M %~ eϞȇ.[0 H G/mxƯģdq: IApa~Xf21:JTu}nh̕ZFJhhḍt$_F N~\ōLOq#$3YI\D J$ )Y"͒2~SҴRu#4[3 hS͈ 'T3Ѧu ) R0'eI '$YyK5n\9I dVp$EH;/+HthgPAf9.Hg}x7Rz\_YgSCi3T*upR#GV?qC>BeJJ$GJJͅ % -=ѡIEWh>dX-\HtCX1aC箋vI#Jz6~FLSH #=61xJ{ R:e`+Mw=4=*s%%m]{+IX5Hh/-I軉m>8,n*:y4~Ws_wӀCa%w$EJJ(^ XgS3ٵ )%bBJh^xI nz3br!%4ԧNSю~ˇ(d)1\3Ɨ1WRnH__7&[0Ỡ'>gOJJh$u],jTW=һR3; JJ-,{Y'߯ / %p%z|$%4cZ39Cv}@$].>EWRBUh&?3BJ`2$:$q7KJOBt&&AOXD䕔t%YDJ?a-A !Z)|EӸlY#)eHMruZ7Dž`"eMJhWR⻃̝b7R*ia -.A}܊mp%%'PP+Oc߾-츱 T2=Gԕ^& wd|z&nVf&%Wp1r񅔺fI +>TTСnnx암B˸+㈙p/t90.)-3qgut˛.Vp%%dہIiLJi4M䍔ƼsPy,8F# .V$V;7.m&7_FJ1y_6` J:vzgfo.UΤ$C Q ,L#yKh_HiYvi|0-E|칆ڡ7R2YjE PgROp#%A2H/C1m7*sӑD^ԴĆVӳpcRwI 4Y令Õ&& ub2Thj㑔t兤!Gqp&6C_+)x_;4-xkv /o7\I)=(^)ْگŻDJ2z+qs۷o7!I 88m /Ű4AKJJJS uki6#u+ʅ2%%o֤t~X'R¢/y@R*ERC3p o+bg 3)grͅXw3s7RJdM|5fJHZv*4EέTFŪ]RH)d,/;Ś)%6;-t\qBpc8Rҥ;/v'R>=UR&T$J8-&T4;)i 5,'(Ϥ{P̛"ANJ1: ؍ρ"6Qz;#%]I~%#eIPFGb"L ?DGRa,T/dFJ1hV%hmXC7v8k2MKQU鯥dRB;Zi!2r[j,c>θRV7R ڭaqI"rHuhvUd%FZn^t}qD=EOm4RuAbb?Qc>ܹ||Q(3cY{8&(ϓxK;@[t6``\547fH.4ǵsc~'K(F-ܺ}E)&ԋ<ꘘ:C "I11hFZ iJӱK4+"p7ϲ_S|qL (+ӐZ]6fgày۳~̳1mo]loB s%EHO)ӣxh( ?#UWbF)ɴ%D?ZP \H cY=A^d[g+;v!:ޚd}xq~24|ˣU㟾0b]U=2vBA{ ¦]Ը~ $3_o7:O*R11^WWi|l1)4YӿfN88\"/1 mmGD#Q]0 㥽 lRf&ȫAg>;kSXH[ϭF|/ XBF6m/o<ezTUy&HJZTǻ5ɩ?r~w{dtw=0]Ys ܭ=gGۿ@ U0w\-n|Hw/ٸi'Ap\|֭yuOh翵<'Hz/'v%.U󄞍;dԛw} 1޸(Aqܿ߷Y~/A}q>7Kû]mvJt,?r74j'17C2=Y)֚pff> ؗyL)y\ۥg Ya$̃ehA&;ð;C(RR^W֛=LJy0r'ס}$"%wAsE7 +CC3J\kۑEJ ٌo~{:ts7h]pNN5"Vot$g^ {KV(Paaz, `Q+r="%t鍣˕I"`:aZ%hZz!kՉN9!$8fzOGH /Wd߆_HIKFEJEJڹB^̗Rz|iD/EJYH 4 rMJۈ$g<Ҟ`EJYHIk*U+ؤAZ޵}sLJgjZBRGRTDal7HJW,8͂ ˖.z: 7RYf 1=X'Й`q/" =GRJ2[>3!s&ץA0Ip=ҹpB{2sRr)kR|]SPoÙ૥EsH;ouEߒ<7dQ#d/e))폫Fno`x/NjY=/.&!A"h'Gz .#M'w>ra !;ySRr^F^f[JHT(и8tnsQHim:Q$Jh5M0BlMuIPV~cј mt`B vx\+*mG̈+OH ļIҴzz$C:ֈ[L^`x }aEv#*A ug5xF7jbqK{GB#?>NfzGІ m`qqqxz3E}r,s3nȔۈ;5f0 ?^H-B/dW?h\ܣ۝nG(38-IQ:;C[zHpor)n;lV35ꂆ^3> ^'fb2^ڝ-V4-vNlSW;.3DeuBj5 8[JJ}g#z #E= ;œހ0zAw ]J'\AIi2{VHeq4q_:)]Gӹ(~2jmy8ls'K$~x{-~z}iLWxT9IEv ݭx>=$%_T>`|3n'e*8^/jvXtm,eghlQ]ć`( 41t|rk[|rSHCTV=$Cgׇ̃)G{i5c$L3gs*ZtUEYI|Yy^ fo Q e@0H+-ߵokt"2$9 #BKkML46ZaFe%bfC3e{ o!^PPB4sX؆=:?I)AߩQ2j9R9)?l^AIiÁlk[A]=; )Fԯ 4`{%8iHE7[NJ;/a2mc{kbsk'!]|`AK@9~tyo0 čq֊οˆsM$zw8a,"VN{"tZ_ќG gOv8Gi^g˺$8fhf'<26q%5xDIu8>AJ@\vDK\W["XB{ EN1{|K*A ޚv{Ha*ȽkZ.,]X&ͅ~ ? `Cbuv8p/1ME][ѕMJ 6t&R:^~"PR*]ؾ ~\AJ ٯ[4< ʝװ+ ?\C14q I (XkG3f͵smu؝fϡ=R09hn&i4g႔;:hVڰ^)OzZc8_d]D8SwǓxrNd) u)$1tds>BG߸sC0%%MΨƝJ2bq '0{",HIs)I WO5W<Ƥoa7Jk /2SoqpkWFW8fjj8i3r/k2;<ِks< }^>8 y]5זga] !zI Ncsйv /@zB[&S_'<_ZހrP:wsg!)ޜ#u(W HDM^ IIPK*Y(ǂ7WvL*${)+wዃ |H_9KxU7'x&.~;){/.`d\z#yB~ILR܈53)&hn3&hejBY(M{zIIџuKRôh5mS\8BAԒ8%AϤT@(qR-\!А_ǪtcR;-ݮxR+#)Cy>y;w[y&!ܙv#aȨE9)=!QL#% qN{HJI8gdf!)e~T6,mtRcB#?F11 Xrm%)5PAzdLJcJfՅvq>Ɓ 5PDdcv0v>d(ރ=c^Hi8?,^'.N[ቔvvzVHB.N,RTWEM3 z!%[ˢFaRWk j`>K F^v}$%ęz" x_m`j.$v'cw2)G=/˴ȈgDUTi)L+EX+~Ϥt_ID&CD`c./vJʞbnTv?T]؎fo_wMD96b1fDu1K,I WLcI ' ɢt)an6yZN hiB[_6dZ-BqG 7Oz"%+7QSd"i'V RscrRzTCWR]HJ*"nBR=_u]"k`09BRoxqS-”ДL$LHc/Yb5+O)7*M-fZ~#U\)iy$ 'Y3%%u煔JB7 '#nx2Z@.lMNଈի^I)W+_?VT#ExrKЁ/NZ'Rc:GRJj=fxf#)Թ㩫4 4>oCEM&n |uѱȳ}h`=/{1{Bh u+ox %TJEe^2xL%iS0 II.8Ϣ ؗp,x-f[HJ 6s\O"dҔP!QW{5E_<塎Dl!c&IIS> b8B:#+,))t#:cqu%3)|H!ߚǝW~{k|$aBXҎ=I"~a,>N?e(i+)-\)ŚF w3ߛKǝ}XZ:Ҙ1 W֣K '$%Y+ ^wbv}NJOyPd*" k9͸r& { %kkήn$&hoBR=;)*c µP M*O~g3GÀ%B$/<D$dވH"hʼnA7R;q€rWOѡ&03)J.avܷZ$*WRJ^Bн:NZ:3ں=3RTĀmQ(m4~T-I '&$_I*kSn.N"okOs%MDJrp`")%bTuTEU bb/Q%J]'qe+45Pb!x0BnaVzꜦ}B\ӧ0H\e}bbIIZ|UCxhHi$/4E|"o5q*mewyNL\H<.J|AyAEVVιAjaQR%dBJ2 _ýtQL$ÓHf:WRҴNυΔǶȫa䓗&l@a-e- ע]q`tJ-Z 8a1 =\) c<~:OZqTn'P"!`(jJȠufX̷\H Ц(D[^ƑJ> whyT\:%I8 .'O'ߚQ=a'ur3aH uYd:hp~7쑙Q72)۩9:$Pf \jfH W䥡ڲtA $'RBrX"?𝔴oY+̤VOjas"+ *M@hҤz(hI+EEQD)HUJB7}.#ݛ̛Wa7:JSKwI_?,Eaȅ ۙ-<(Y6Ĵ4^g @ 71>@nqY[lS7gk1( t2J;7`!(MUbq [k}??3Q qI(mnJ,pWdgİ]uP.x|*5Ma=r%$$;DPdmU뜒g"r N%|ARh|(0PKMABnli%Qm-p 6O+3ApYrIAiw<9Ѷs-<5)9(a.ݾeL-"-묠Ji#, +^+ǃ;2]\Bis}DǮ&QYCte,6J*P=V.}R7by{ձNv. @laav%JRAEbw9pDMPTGWyLEl3VӇVп7'iVl Jc)J AI -16= JLr4rvfdT`Ղ-A oA8?OMr`G[@ 7Om;t͙@Jy$v@A~Ai{6tG&simI?҃ѠL1!},J|Xeo(Kb QHno&6j{ADj͹{@ _@-9 APj$Dk0w%h1 Npjʅ&⨑/P:u9 n&R‰c DeH'/'o QjNRg\ay J'41m@~4?dٕi@`dm4\ gK kcoJ2Qy8.ZyktbT;zR!Jn)#;8n3NyMa%`HܣoXPt"KwV(E!DܴJ8K:(a^K\M0# :7 VPVG!ӦDeڋ!x AG+K4DlP@)+XiVs;sFhF亇l pud!2DZU)sU_DksLi-s͙c8AVIx7;"`pxq$0P%d JQz (N,iPfKHrY!n p;)r}-uP zmB痜*=PB/yܹT^Js m J{ҞtU ]$J J0\a5mVk2kU]! V`Z KiJ lFcpJ6qgNR1D/4isGng("|rUTHZRP=iXXڨMJ??,JE%NEx`9thCzʹBJ]{Di=SKkb),'(}.07 @>$(]IL(=p皫g`+&R>pZWbxүhD%bp5R`qfgWp:  @ v-,R$B f@)v' s %W84x2N #Ìq9缷/Pکi|̬҄"DH~/bWs0+/ZLFP >9u?;~uaZ-PP+@N.8!0X4~s"CY0fSP" _0 )=Gr7yv8m`'@dgMYѰ#!?V&SVS\$ss6a·Rw5',~ۓ'8 = ]7<@g ^;V6qJGAؒ6 \yޅRxp,5F#C!|t4ԬP߅6*[iYG{)8>v6jLe8j m7n?O w1Za8`}-a`d2.m?>iЙl3ya}w~$)H eF2y C:i-5!]~ȩ0;-~.^ahQpR.*qRte1_fuϐ%ȷ[+괕a{$ѬZײV<[XG.xrc?(%? RUصvC*iį_{pKd8\"3+pzuKR6.)6{"yԆHb$Z(]svh ipQu~8BX#ޢ| [qvvډOG\mk1}1[&]u]dT-HoM'-I[ uᢵud>A~@[FkM)>/s5;xm, ^I'b\,%gTPs_`&򉇢Zh랺 ]./2t2pKMw5)6'JOMMX>Vw`3gv,~n$)~H> 5$/-]. '\ెu:>Xn&R&Kj~Lƽ'YyBIŲzfEh?M~x7"9=.2=O#Igz9ye@ɋ鎙--r&sF'nn_~0JGnFݷ#%lGdn8<͂z'ppexx\rCA2ad&NʸPB bY*,0S@ɥ TW0P%RdwB !p&'J7Bvg\Jg頄sߨʲ@ɤ|Ye3adH,@F@(%2>`Y䋞&u-pAP1J7rÏ,45wR>HYL f;() J)Y/` v@)Os~܍ .:Z^;P諘~͢eIgyv+&R䁀Uۛ#oPJ>oVJEJ):xvJzmz =jm_փQeerlW+ òwGQ7Va:LylL)5SߏA 6(>x܂.^[H w[,nV<50*)ꩩ ViVqe;ܔnkpJb58(kG Yܭx^U- R6/@Hö8\!O#xN(|W 8a`a򝝁r*qkTW`ZQ}< 7J~A(^,d(U7->GTUXzS2-_= Bwԙs(ou*"Hqՙ,e.TR +uzUOcN/@8^'"l:ˎFǣ[ozq5ְ0|/>7qW%J'tUZkZc:k|8_2d.7OަJnGeݱ4w*DB*v~ GW}H}=j/m/>xLR~#]|fjHF wҐE$gxhUC(B}޶XO[0MI \1+&//>#}*f4ȞoWoUj&XR`QPJbZ0/sPP:+l"'0K)i02>+}I. 7YdEԘb!M2A`)š'06U+%O>q97n/ۤ pr/,,azXWAG9*VD8\_xKb%7*Χ K9y~\8^m~~q &` $icFZp?)OgΏ?w9{ڛyRR+[II!bяc0'FAym$ˋYB5wIx/-'(AJwT24{ǜHi%Se鿏Caq'䥣]Y>>E ˲~x:ك!ɗP[/Va@N=zc6/P ْbMx@y[VXꭁ |,A${ޱpS }Kք  AiK~>;DEawļ}O>N=C:z0%p龞^ur/׶# rZ vӈ& =BSxBSH*r#~yǃ*{Ş!ø% 177GR {9-7b0[<#nJ]mەf^; VŁSLeo#Jݻ栄}Le$Fݚ$_AM1tqm<6pZu jރ[@OB E%󠢝pG?1c=0!rh=dqLiۄ !`Qjz_.LƓ>/;ke2)Sj_ K ;`S! fPS) J\|887)e>dЛL0ࠐ8j3PE,E%ObNҧ-)!/Ss$Zp:HbeA("B9 (\`D!( FdF3 JP6Rzf&qWdܝNp'~h?t;i,-W0!Y֋R-TfD$DO 'Q`vA1qZCj& -$蒸GLH+YP2]7)lQ"̛H$HHaܭ~L}IhH1/0dG?_ҥOŊGvL]SghWHxNg'Prx] c$tCe֖#(k1p\ĉ#*-~[7DSbP{ MbGd]ϻB֨] a-cJi!DP*'CZ- }=ކw\19ΫD1>]BIP""B  Ը=fN A-j2*Ǽ}e)̴$>Ӂ{I[_4zy<S- Rw\BBiPBOB K)=3Y @c^6v|" MF[ctPz GSE[vL W|Jի>j%h?G` 3uSexîzk\jh#(IXE[ Jbr'+רJ؛1M,y`g1lES PijG1JC9u:Ь2 J1d('Ka&zukkj `5O#s8h9=?vJ ,pL^ ?/9k:?PJ(|@Y2aNj'*"0T_KSgu ,ISꦭs@ w _y>NVd$CNӏ[d渚OĭEZkjx2ܘl6Y8ui1L(,w[ Jj!;BZKfrn1qinfJtczn .Cfj J=Sux< 6߭7jEt"HWo )9X^!PP&'PR&7OśV8[P2\EžukB#az 4D|6gReyRMvOIC~nX1h2RAݚ_qJsOPr @\8T̢7iq}'d2J”.%(o $L/ZmVqMtmS!NCm *cfAig7K, ;B|+Ui>RZC up_ ;͵]~A*Z=RG(Y|> K ;ʹگ/ ypJ)۴~޵!(iN*kopfL>/D/FV\C$lC|(U$^%FY`K_pFrIw14Ejۜ$}SC$6߷m d]%,DÉ )yJ"]wˀS# &yW'<ʚ:o2 "af'OsyW؇ROuB|o3A uXn 8 J(h ˪ "ȿG; a,@>LEcSՈ/-#CPF1%"qldSQzhLNmk'5PB#(Qm̏ZINI}Te]鰱-YFp,Z9m߉ZeupÜA"c!PJ"C _M>1\aԃ_ M5(jY;J4Fdu؆pXJq X@AiuYWvM#s㡚, _?PBU Jǃ)9/?&%iCY&n; JihE:Q~A ۜG(ٻaUdcp<%u}+夎JpFL\ -\S_׋Q6;Q ?b4 tQ&)q)+GsĥpRbHY Hp֔.M f0[((5 R$9?)Xiҋ[ClNû=K PB0b.j< DpJ|"(S^Cr J̾ `2JtJ+ĄwYׯ"[F3B^! JZwa& F#Np~@ ޹.?G/P:; _ mry<\]\ިY@/MPZ"ffW\:?OPwXA CĭpE3GM'(sS{X yo#Tly"NT}߳Jv<ۥL(:(qJ^I5( .$LI>"+zpiqh1ݲG<p(QZZݤCm5NBGrDԦt JΆZcS8\/e .=B*m[d^kL|"Aؿ* S@kڵIPz /Pһ⇣IS> J-9+77(<e { /\>$9Yt'.ы{^sxP7OP(EnOBey3~AL I1JnLi|v(uk_-8Xi4[YIP +U+Xb0 ;\DG{aڎT|(7s(C૊ޑr%? VJCI S;ELVsG@(Sd.݀mӦaPeN,qvcl}R_' J5+3Us+EHN|#5e3\:%c@)8,Py* rSPJQmrHkB} uP̆#pM/)@V8:7줾k(G6ު{h˵`$;Jmȃ[`VZOSJHpҗt(QsG8JIJk 6AB6/vPKY4L5]9Dڏ[阋9xğrLi:'fˢW&~"/P2gAɶ6i`:{x"fq"z$*%*m@(w|RMp}?4҅,C=it;t8Ɂn N8.-Vx=fw`۹m/{v=ޕ/%6 0ua7Y  F]ۉt}mH[!O3;|h1bh[}7@Ս޷:;m1%Ms3 R+aIZje O@OP_P_q'rQ!&Lsu1,~6 C NRhb7c&yQrU& bBt"_hX0TM)L12c|5II/;+Uh]>fma,mo{0kEvgݣjqt-bm|0К4ݽkIv( -~ ]}0S{>EM WE{J 3Kw^MG/VreeHS_l2 ؎&I0=R/{Xaҽ_̀ỉҪcSی: Ϗ/I\kajhjP`L\(\f{ּ\Xj=P0`ym /wlIȫ8&IRC./aRhGe"giŭeA>lh]mBry0bvwSoPkno(1Rd?rv[ig48/4q J߈4m$7K E[D[rQ2~ {c/Ԑ F^̮10}ҍ;TUsrrfi'=nSEHMqOq/mk[R_x=pz%`W\-6v$ ag#fG4; з1d~IQ4VcEȈ}>W˱>,*qJoWJ57b4uQz"tL6 .bE&Ev%0W(FL > K˾H^c8QmNu'=yvAQJoӡ^lܸr}#{DLCnfz>-Z!l2}ӎɏ4f*ifu?!vqY$'f^^>Ut/nu)_uy+ nݰcT~^o|qݮϼa J.1 z=6Ő59VUt#[cz64Ue1L6h_^hݬTʇ70riz1Fws21,mtpuM <V#`mk7;e/s hQ-̑ղ"Ѭ5$'5aː0XcS`,YTVnc>h0PW/o>}# *eS7Ck}RbfQ]/5uVeJ,ʢ;*|,i5`ٔJYtRL[l>=\JYt)I?2,( ΥS;3+fxRf?B;!YE1<4w SVG ΢,R'Ȭ{IwJ]jz endstream endobj 24 0 obj 66605 endobj 16 0 obj <> stream x?oG1$z}@&ZD0((ZhgF% ilB-R(DJD&7pp=3kٳ~sgf˘݉֕bx8`ߏMlġc1_˯c 'gLhgmWЊWRidS@o %%9F6m^o) CɶM#6,oV&䄿GhX736IU1L1?GȆ89I @Dc/~qus>cT5C ) ~qus>csVأ)G{_q`ݜ؜Uv'nX736gUS| ;u| ;u| ;R\[[ 5lڶڵwGUU> Z']p O WnJ^^R>wN|j ;~%LmDRxq#վt޼VRVU9PcD{ T?^Ƥ hD[C O5iFIq[U{zz{ fj&I^DiD^CN5::U}qo j1f96y#U6/"o*YUU:ꈌ6U$?^k9F/^^T+!#*U%c_&T$JXdwkUώNr䈂JUI;VX>ƒl!3$CJJjH7s_ZIQݵD.ϾV҈$W3ݕ 8S#yRU"ɉu<|*^}|$^XlUGp$JU$'"?yDf;[HVrbk8S6M[ԜJ.]䕧^;C#|5NrJUIj{ȑs@٬$gTvF ,[S6M[#Tuo#0`Dt,^KXCuT`S@yRU=IoS0?g0먤^@ h%!:kq)wHoڀ5;Fv$RUU) xIHezl"K?}G6-9xQZUIN;0gp bRY$}JUKxZc` ݲhNE%XU%9t 8IUA޶QиrSE(XU%9ˈWG#Y(ec x#񄑍$uqq/hD.XU%92z+ɻ;AʗA~KreG#Ido%喐]e$I+VUIj{NRe @}DWYZӼHokTYʋU/U)IE~>aNWڞ{qPw?GqH*k}QLH(F]M+CoysvJR)ďk𲗽엿嗾8>/C$n4U#wXSw%*nABR)<3puo~_\ŋo9 9G/2mid6%(WkEjג#iJu8?x%u~C:[CMR3ſ~Iߓ25;` kݍ/5RyI1T3︼뮻g9]s]pa~~c* ڼ nSnb}t}'>qv_YyM7=# 7Ϟ^׿_ۿ/^ܶ/۩}>wv?n{G/]tiX^W_:]O_{W~x뭷>#/Y΋/O-o::Zxw}7|_.mӜ3K|g_|x;,`anJ?3X0dL(uIrHŐYf@2M>dVv$ "iNK2! ϙcLK ,Gys!6 Ґ=d /J[8ϘțSeC&l!`*!mCfe I2"Cfi#a8|!s5!`6Qpؐ` 0g2KX iCfeU8FQÐ 0!9fdMɭ>aJfBFM9U?6fL̙gF#1C&l!`BIC`ꐹŐ 0!(8ldM3-$ ISeC&R@Lh-u,c:e]Tp˛es&2F1C&S%Nd&MLH.dDT S{!s5!`6ys!6!mCfiI,"Fy s&2 s5!`BQpl 0g2+[H7 2K 4(L ΁ƒ:Є[Yʏ .oH2K49̙JuRd!S^-TJC.dD ^!3j\6@+u03 :b,"@а/odP:d2f:bPYi{2K[c7 2K6όeC&!`6dVv$ be 0!9fd_( b:b,J[:d0gL(oL2i gNO@NB2}N X;w@勣z*%°︕#Y:w p{qʛ?qq'XO/`(7jԜoM]Վ?ϑ/MoL{1^;7}xW 8x;}V _-ud_;:SjZ>&ǫE:7JGZI^^uwwӁi*KIsd)b5g_o4uc_uwwӁi*s`)S./u+.|-;r]?yWv}Vz3fJdk qg:Py5=jLk ~Sk&$]VY\r } &cוgR섚i?zKrv/]`$~F}Ҍ+{ӄ˸L۾{SyN)ArJu͐e9k|Qrpޞ6v4WWvhc=㾾‚i]Zxs.ӞeS{tn1ب7Qey6:Z]uŎ"GfyS$R9|Λ\9;Olgk5E=Xtljw̙T2[_eYFso#cTי4;JʻػkL>G~u[ߛ348Oz+l߸Ԯ"i %K=榖WR!Ŏ珝Z>JQ{`W~P- F, E8)zUI%Y{="ޑe;ی'8ʾ1w՟ۗYvq/kIq5t-9ayTI^j1܋]khw.#]oi0fYе̮7~gb7hܔQ}Ao J|[=4Ջ, <0>ZXUjϳ]]S}f%껸wHeA2@͊q߈el)Y~w%ڠQ}f͕Zjs/^_iXmׁw7[hU<ܪc-{8uo4MtVI}ߌ'oLڷc Չ9NIuP$ k,2[ I^.|} I9r?JFoAU&:+wf/U'!fY9_Ij3j.Vc+˚W֗dp''=`81p}q3M 6JS;~Gg\,=J{w,]|!]vm[HG?i9eM7}!Ū9<RS]{y' S =˅&<kwnTZcX{Z)ָ^ֻoW%$~ f_ƍj,/w#w֯ .kkĸ]K9Qd^w57hđ:LǎJwaӈGi S%{kI왥 {{Z_ImM}fxww9%eC,݅O2;Dz8XҚګ2lAfdwvqX=x#;)?uԧ'0I9AUy0ymFv]o3\"[z%XpmCד+k^nX\}$Ltrs|~0rS:p0j|,ejeF&ɥ΁` &T8Y" Ũ `ysڀ!0vDmF`H4Fˌt 2&m-ƀ7Z@\P1<⛃MywG<-I2w/`Cf)? ޛ}|4vx-GGISˏyįE>8JI/<|O&Ql-@he_Ʈ _+\;"&ޝɄ=:J΁py 8ߓ {t4[ >fڇ'#"n1=GGIҭR%#U䃳DFBZI6-+V<]g܂1ݝ_o*_UR꨸ I <' yɪ] q4Fr,A-eZvܪ;zGyz,[c(xI^r_ngz?u[哴7^K+Qнh>!Ge'WFSc Wf'<`;6иW::̸]5ΉqO{^y <&jx 3G][4UXiY$ޑ"%YJl.3l{P2um׬zG;]dхھ45weB+[o4Ηӕ(ޑލ'c.QeʃswDe9޲]}5plm}{{<{eu/a26{79q >rʹ HUz1ߝoWE/IZ6Z]i/@s뼷&]Ww%Ir|wHR}Bo[M"u&in_e|[DEYLNZşxzo~%TrK3:ɮkݻD:R) RdFNy uݗX*RգqY5W:Epߌ.I#L*S=ʍQ|Hv^O^[w?,X_v`龎Vt1.vtq4XreԹ}P6>{e)YGT>慾خv$RLW`ׅ=Gbeor/ؗ5n%e|] Ug+}S_VRu41wd_fJA=2m챾L{QeiZtqG0FS<-Q]ݩΪH '_4G% ^|3`ɏ8ݲe»8vT]$խ'WĪ.cq"%e]Tnz$ge1XL]s UjeJ=pyix#kB2wq}׾㻘Yxwc8d҃ayYj.z,UOrc,g)Srq}x˺rjAC[e-r/ں+rd_K-שׁd!Gs;xdY&2n]QQSYd")۵v-CʵeT,UY<]܋Y͔Wv}̬>}re'+tKQ*YF96*c6EK:JEY prYc]쎱_w22q˳ɲƾkҵ3)ź/)&u/U돇׻lV\\Yꫫ}MT}Jj0{2K[cy!*949k_|_8 <g2KLH if}#a8|1\.Lk0`90u!#!|N!Hu!*^-!su$7wag\F1 2i|OnKp}k'-@/Jx0B Y/Yf#3_c#,:H%V߾_/;Wi>˗ HT~9atWn,/GExvWU+<5=*3a#Yvi֕eʻ*QpW(I K^?\xn^>؝Kѻ`_xƒ$|R[WMQe#u6XPY>?xvC=TYy-|ͫ$/5|6+5ewO굍X[lK34n\PrO:瞻prwO\Y{ѾUcM\ٻ]}fG]sv,ZTmsi,_؊{xۿ]|GۿBz./0.D_y׎RkPݯGGߴ믿oUWWW~xm=c.]:^Ї>$jH20tmodb_Nw8ryaujN@<م_y+SA;/7 L^\_`Y,|9r;V^RcvY~\p;]/\SOmo૛ |v67,}nc*ܣBIUu:zg:W?+?|;߹zIQgo\wC=M}WJ*o/i%U 9MZ|ӯvM7}+_xUoR &_`Yo%/d.㲯T,^fq5K2+2rΛ azU{J_ 8/roX%R=ghPRcv$Y~^?g3兽>{}wzV.9w̨ɨ ԧ>`O?/}7]Z~*߁w#TGr,ѸXRwڮ[sb=?ǮzSO=ub܅-_yMܿvqUNU=d!޳TnY)XNnً>}w_~o}[gk_9}jzN.**U*/vU^߮ɷci*KR \ZP09}~Wz?x/5|5Op߬KceK! 7u3I!NdJ twqGsSi |!5{IBVtu.$/Wr;JsvdSboқ?xsS_w'1^+EȫʘߵLҲpq7G?ѕ.]]Xq'6, ʚzrq ֵ,{Y^So}[}np2mu_(i> stream x]w`E\: IKJAKG@iiE)(J*XQzws͛-w7܅IΛߴ=EI9kͫaJH/1G6=ZK 8$L6l-_>ƹp[+?/_7^}o4&7dP𢤨Dj&-"݂xRqu=?N&$Dj(* =$H}!m&lȉ3_'\wY.&^%PTV"r^‹4>]V4ϋܪwxIpsz5u>$H,Lw'j$NbC'ycY=ԅ}{HbT%v dcVm=x5niΒ>'gxWjEo4+ݲQ;BbYwɎs.5~4 \Gxo^M/22nz+71ЫHb ot6!+T6.5:&/*:D]Vu1lPtV7ۣx?5@O/nL70.*NO&e8^k׀شxp겨iᏘxO?+}FQmE9Fg;~6fl]|;$vcKPvز=rB2SInwǛLaEF/K4N38D[w,ɹ6m3oJEhao|ST_l])==vK_У7%rHKCR2M;D; WJCє StA3OQuxNqMfu@ro47DVO@:LIbO=CiDl*N *Y%O=SҔΜwx;#]De=Qoij7^(x%^pl7d*4q+cfҴ|` Ԅ~d-',Svǣ/[(yW&MnmLcMJF*K<K=[8[4):5H;ݤ3nyɪ+6&؍#KE(c[ShljQ@#*h%^,{?Lo<ֹM^ȜTɘ!^3])9 )2C?@H8fYs{6w@spH^-M *Ƥ4NS\"m l`\= 8;ĊSDo*Ssl{ǂ6H^ ^Ѹ"F"̦]56c,8ěDz2)F8wBHq8e/X>xv{\ C^V]ҙh%^;/nc AM[fO@pTd.>+d۟ͱBrsOckSh\&5hu:^rp.: K]!񜸣j ƑHS<=DB}xѐ릌r&%'V휄;Z> W'~x% elX̾CMӬq [iKHcO4k~:#L C++pf,YJOζe'. cJ_[(pVAUċqHk *v;.WB2>MĻϼ FՎT87px3Eү{OOzXr}ԡB(V ;l,xg3nw 8fmrf JS ayv©4 eP\!(tjب:CW*rg'[%q&(ˀ (9c$[MrPOY=/[%SvʒXtr-J2*-îU"N>كVi|[fWik.mK۞U"kVzx&;BlZ}&:9^yյńsJ8 |UL3tPyģlr&7VYjt@a3nBJ[x9Kp4yE{Z8<#~Ńe{8s`3 X1m.L~ MAfbZ~%J|N{yJ ViSEYcŭgX=2=Վ2ާNj>43.O72eJO; oCuְɮtN00WĿYd^ɽh~5CP*%cȒZptEWy^dl3. i.V;{ɋJj!rZܙ`0îtU/p{{vEdSRBSJk!hZ|Ub6qNgGꅒzf3ԁMQzɮt@fI ߷s$<^ې8Кv|L%K.5nqkZHcjoy]C_zg6!qp/'bV%?uo} GÞv6R%Ϗק{uk-tV/>]?_Zw|Cb"WݲFܔD [Y瑿=OZׯ֨ xlJhP<8㶵kyK V2<\~~*ݞDʼ$5"N SΛD<L5<M՗:4vEV6E#HHHh8I:|/ y~ACM\򩤝sxy~㹢vcBPq bxꑻ>߿Ӵ$6$S8Db%q5~>R, N!!!>= ݉pJ\cpNMv"HS;>F Fy$,&Ws++&!^߽M#1I{_$ZVB Qm7 A^,,8ʿPp dkOow7zCY;.w HH8Ye.(404lN! -r~zΟOm]@ׅpC,ys^ H}ef#V̵@ŦD|JǷeƏo*nn+usm.OhncGAgٕ5p;,+K.,KeL㒺IH+bqeݟ>7-+k(!ᆸĪ{'YNӡsY*IH"mM Q 4'j;WVPB|rT ]_"+]V? wa-|VQ^NFhWlW1wloWYVPBa[)\ѳ ꅛ ?! 1H/yvFk}<*=]&X~|e nMS1{0,Ю0HK,IH#,|1qwyڼ~䒊S s#ԟЮ\鎞{$$$CZ%{BKw`4Υp?<.H^M<<"[UrKHHp MwLGJxr e$4Nf xxE".\Qaj{{~I 1;Ԝx0y{"SBy{fp$"mX$$$xChg Ba\B?cNJHHKclDhCԲ BRU.!bFkX.Ø'G4KB!^e}_.$~!DZŦ Z+ROJ9Pv *= }ٶwr͙u"Tڈ.k]NBky#z}Jųa>NBBBW#-+m?+O.ZlJHH+\сdEŷxWU,/rJHHpq<+O!~?z3A~rgڄvX\rK&!ᮈ$>F T% OM^iF)!V6T.Hz!fYFrPw>#*'3eqMv\Y? CԢr#Į*Fhu)>b)=IH8m0o',+HhsW~ yY5IH#^䋸΀ %!, Ԍk1'']e1 7e\Z7 ef7pv/e%+J(Xl.t]$$Q_Ci]y6>yX1yu=IH+zLGhW'ڼTحW]YA wD3|>]*|_&\Z9 ai.riwgp]݂ˇpaFB"_ cNJHHpx[^KhהDw)\XA w,̫\xF-Xsi -!4Nȕru;zF_}.\W= w_*kC<yu9'ʱ,6vI$$}WƒF>=/qf?Ws-6%$$DHʠ/{+T[Gr;u 82.CY;εuQNf~W)!! [d*f 5U{/Wd ]z!j~|Gb@9v'ul=IH"{>S\[ \ny=G0zQBġE!dk&!XA>hEMhW`17r䣑Yʀʿg]YA wLLN$3Yw2v/Lpi$$Ə|(OޞOLhW8?\Spw HdLB2?=wwALJ .^}>lA6sW>( 1'%$$Dʷ/$nX ]+wFK+'!ᆸ-n!+p^L$$ƙPz/uX B(dn'! ԕJsnظUsbG(xnuqّoĢ,it)!p JDW|O|< Z?YQWsYTDNBBB@jHs$(?EA0 b:B:Eh0U@ԥp;XW [wĥ/W(h@\SOBB-2rvF#iUw,6%$$8 !M|_qk̈́v&<#^%,ʓ~[.봗+7&f.!|No<[ډ fiABs"_zWPB>5 BeEҨy }-T<6!AI >,^50b6 Gԁc.;ηyS[U/<4/+_[ut|FB;:+V M$$i#tvPbNmX$$$G"N2q_Y]m\?cNJHHo WtajݼN![0rc G>vM]绬zKw0N qђotyuG g$$÷@췸<Or#pL($c#.WviVMBQ-߉Z}x0yIp> gp"YQ'l*FHH8g$npۄvir~qkK{; PoF۫ڥw@{fvi$$+ۃןZ7U Pp=l>upCXDȓE&0V+Pb*1XܚvY&?#fW( IHH0]\26ʝ=rm'3Ov*Ƿp،CwDKLPv `lvEVp]<j"L[\ J  4õp?<Fszvz0z2:=]TWVPBp#4?{E0]-!b\L»SrqFr)SB)\upe7?'ׇnoB]Y7 ED ty/]+ennrL:_M\4?(< \dupCnၐH~3u҆#~ ꣬S_zZ@wk'W*pſA @wX.p>6{ĕ'=IH~m?+FQ \nBVT|{]\ޞZIHH*ЙCo EJ; gfoއ]5 ꅸjv(1+6I+ 08kkeBau V?p1!L땦:,ƲvF}>(D"fI~FqkGhiS;`58#8Ʈ,Jhm׵X҃s Q pD/y.Vvm$$UQ:{u4OēpGg@;y EvDEt h 6@ |1% ]U\} `=8}{~I 7鸌vsw.ۢ!z'x4"Ю ws/9Ĕp ?楢nʓ,-]m˃׮"#`$һ@hW -c= IH%J~~v _'ښ BL ӱW30`)Q]LzH|P0n5{aLGF^x}:xkT!G N"Q$N?pG`n2=E<<"|&*4F ix?$mb\E Unlpp$55xT{}bn-Bf89 t5H芵IGb(g'٣辤( QO 爷e|VĕWs\FUV90Z};֟OД^ ] kpj;SQ9r1.l*y( g[ӌK\_mn]s-!x&)YwZ7x~(*:kHN~񯾝sž>xJ'%VSvBS56Jw#H1l*Ptۄvi CuY5ƄxI k)Kn!GxUF FC5}k;lH^_\Qc$!^K|e7K͐# Q |?W 5]ZtsjIxBwy<_J<}q<ß"_~A#^ υDfԇ A_SEe})B c??H:ḄOyB`ϖx|\S[ˏsOZ&C0<2E~1\s|H _*V?f@?[>} >4Bƫׇ1|OFcΧhi 3EpBKIs_W"ƲUT'?/< }ilєoeqqbi ~{FCK{Y=c|{pl(sNkwWEbkaa^ki8rBhtA/||o]1pEJ ~Rz)<+(j K=;@VȻTזi)F'FCSb:*]-e ֮ ͇*''@K(wl}];g0 éxPpݾS.!Wyq&eF$Nz/86cAwT[8:7/OB31J°Uu{Xc>xxS dC9"83j Vݘ5Ļ.!a_X:fȂԗ/fc*R1:-e \9 =`UR w- &u^k=!X{Xs9xz*kO< .]Nb28Lo?)D|}׻5}uI*`nl"EP`1?݅ 5w Dű6&$UoOJ`Z8vG1E򼮖4!}d;♚e <,ѵ^`Ϯza6iOI5Pr4N mR3Z' |>cOBevT*GOki*ikPegz@6:x"]vW=`<_Z?Z0x-;♺ѾeԀG#ï/g#D(" -1פ-x61n^Luy=bNW ]jCXP TKpcCPihG-\",.ˎd].R5_C'z6uf@V =䰽sL~@mcei[yS,ݭ{=jm${:HbƓI=ycN2NMDsBKZ\ĺZS3s}:5i ě?`?LۥI3bwukċNݨ425<܁H;k-ELF-'~dK ^ Bzj:> wZQtq̏ԍA9?*_֨דl>eMx ?h)Uox+*Lݝ2`ٞ*)|aeR yT+d+ʯH0d T42kwBϻK< $'jȠk܁8lx ifdK_'*(M~VM Lfj*o4Fxzy VX/*{+}P@ƚ\ JjqceL2!އqX bF£_oRFka7Z!仯!Z5t\Wng3 қ53/3y`xx/:KBV'"KwlC[崳+wh+3zgpNyVlÂkr=4VijZM3z֜&4$= ؿ{=PgЪaNkH.~9zTFq[W$Oh]qh(賤dZ#f,уe=rN;<*eʼw 5-=ivx 4xVj{ҷk0Blg0? +SM_I ?,U%΂;L%oLR|X8Ӳ\boVS'^Y1 b 6Oe r/ ʱ62F{{7X灞eX}wKf% xX\ V*6 &&Xu&kE ݭ r66=%yXE`E! ^%\d&nBFr*/t'>Ox6j"6`"B˰`腗#4%.7 &װ U3Rbs:b⁂~Iv}tX⍅hW-tKNʒo2hMɆx|[Y- `8l>mƱ9Qj3k|+L+)C"׈0EO. c- g՝mH6 I. 01,3s(TMN ^^a?Ds e6J3IBZZS 6l]P& Zn9H3̜1Ԫַ%>eP 숷U j56,$' _"gL \R ݬEַajWN"{q&C=`Y:c*GZ,ͪ2Ľ_ q U%' \E5H$MRP "+2391T R.hcf{r f8C!]G,޸꭬8n{/9EѾ tUy֓Ge{,EQ_-,P;D@¯'Ccf3lcl6WqO21Uh&ٌ|悈W94=K. Rha}Uln>KaW|F>s9taEP<2C ށwP_)i5=޹[ H:hw0s͸5i6[h=<_8}n'U'i[9>f3,44ŷ ~wb|k/'49Q \ۧiZl]gmIs-~֬4S̞OWy_l:voXVMZv9$]6Dn-G!7LqC.:G/>YjO ?]U 3sZ_$,W.jUFeFar%nG~\ەڄ-juc֪BxN|V=ƹ3Z(bݳGW x~S ;-)mjUy[n|}r rn,t{ veBlDn+`2nolL 6xfavpCDAtj$ܤH \!jyt|o!wllB&ϣeI&єk>*?6_ kr%]Z9$$^u;:Sd_-p0JBI"VX:Z/V@^$L cfXf39ʈ]NYhD>BhW A+;hpI$5Jju۫zHɵ74-U| _/p 0הHb&ȿT"Ipe4%(@Ꜧ{!hG%1!pc }w[ !:;y v##@Y:FpTT-[3>wڜ c\{w>!)`q/Π(ɂE5YL8)Gä~pp+?R Rz.ľأ%tL6,wenE<yr'ɈnzR>NH,㹃SW*1kEs_ߜs"^LvmwZ~I9Moͭk)x#$iI~xu D^+DQw/)<{'wlq8*5װk8M<$g‰g!q4%S;u ~]g[lv9DH.`I<'?Ol@h׏+X*U݉! `<~73* LڄviIlȗ%$x nmi_|?wr*]ڡ"=M/ & nO#ǖ:yd'aq{\@mKg; }[#ޏ5 [Py^g=ALy?}fchhw Tjcl׃<^hg_ v%MPX/4^hh\PCd<Z@y:Nc̈BaG3IS7'49#"PX*JgSnhhdJ#B5%q_9Dy^ߐ͡࠷%}4Jժ V@}*N0yJV x\y& 1h<762fupcؙ\ L^xͰ&~.5_xP6[\>j+ >vRh@ɮhS#9Fit6.*?@\[:p }VO% xf z t٨py p-ET)yhB8 Y;!^_$55̻)į[FsxMuxM)'07NQ =(ěE1Gū6;ĕJ"g*3.`c:-M0”gӳqҭ54e"}gԗRߊyW.f*>5%ޏ8s7^3匑lFfΣΞ0LjlID<3)-^xXA m(kE%-_-4x&q$4D3fW3ե Ѻ&T 9d ,_= @-[N)K$*_B#^N vƚ NЗ#=ZR\k%mկ ic"Ü63"aTw Mx> ;J8BVLp7)ҝ.sD@r#cYY=`-z2PXhuK,OyAYgnBLBүۃ%4;<Ю8o.xZ7uQ8Z`U0^.cWX=hgS!>) f/D{N<#jmBj8K$BEoC0Y}HbAh=A) S|obQz6/f'я.a&'ny | *wռ` o*.\7IIZ!{*_`X]-\ jhk 'O)`zb|o faΧ[ln5hU"d:O:GDeGj=c g3x|1٧W MdgMTv,g A46:: 46TWo0r82Dϯ,LBմ@<-VxPS E;2PW ȥYvY vgwu%TZwo#"^[ {ԉiK@'K tuYKS! #P=~xCμ 8ik= ~F^S7#qwbpK`XqZj[ϩ).*f@uU\ۉQp(w)FjPSD2vvpxtUH=mOt äORLYL džxҹb37t :! W\2],D."u=~& vpx`6[BRo*)xg(2\hpxd`G9@<ķѯFK-oo;' "8 47JOQ"-f6hh 4zrɃ(."Rqi² )卫]Gŵwx`׃[$$^<Ќseg:r ʾ5TG*#"x_amRGX9Ib F<GMٯUtc0]yW;ïq]bEdÈECb7 ݻ 3W!椀xdjbG(6![lD%~>8;8ކz0o ͘J*qxvֳdCy{I޺P\UIGeՉEM]'յD)m 579/כAQ|}~OGo~#?M z9Aj]s D-D9IiؽdY7hUfl^{CT/f`rG1-;:jF<>d͉= J!Ts-LFO"~&fƷ3bn 5[7w.8R?)T)<Ȕaݳ@fQ24~ޗiB~&bD77V@}d oO]β8^%%76M-Ȫf"~M&t1CϲP!ؠĹbB9'i ~Z" yE@T/ I< lo:Ft(>~O08ŏ9BO1&s{[ԻݵH@\Fpz{Ou88%*xO-x/UGt>"ݏm/3[x8j @xT!iup3Wfxe&\obWL;l0|۶;VTm3ba>/䙻z親aakP@3rB[mx27.dF`vS#Ň-?iBI䑵;|çD[k'~.725,-< ׭Dˆ5}NcE; DCτ 纔-1FV<}.Xmޅ\iPz@s^;$3Z,$^\R37;2ïQv/6xxe^vi»%s4.ߡC[qq{DTHVQFvYU2; 6|[ œNy!_fdctWD(XIZ=1ocKpzK{\guoҢ}n#|>jD c㸇̡M #Tlp8ږxl` 2 Uy[;s<AFCCv9fqbB_M/* P}韡x{cL6SZ"Խu*Cl5=4ǰcrjeL=3yѹ[\6>L pz`|Z pǩ{s !wy "}FbgJ>F<>RH A⟈>TxT[ yrj E7Ϛr u ~_:s4ױq)kcA.Bs <ɦ#Pk #zr2^|Lw aZ}\HV 2 i'}+x!Ļ-t'T x>^UiA$sP !lWOۈokjBse"tN|©NGD1&n}3[nKk3:cXO> H=t>U} `yŧ1D Ja!*&gS%CĀ/CZ Mf%3_5A")D y.YbXpcj0>'aSV==| C:r"C+:%G}!z(-t Tyh xf >0mL9yYx9!',@0dc'Lp98-O+!زE'0 Q6ӬPy.$^-q-S'a4&ޒ͚x,zk{5L1`K%ݱE3^iϛs-6[>0bJKs@WA5᳁Wjm "`-f?a5x'lt-4z iPuTOOܦ7?I { PRx^שּFgeăc PG<2ܮZOsCI< ̛L| t#D > у l`ڧ2 tT{)xq)&LlHh $O2?PIo^e_}$WF+ֈև+DDA(+&:.6"(#WbWOt ;N$zz.0]F%HSa&<(dXoGXկO{G>@5y Y@%ߴް/B[Td#M'xOu`ࢮS'x°֣B+PB|DhBU4X;Qڂٱm5a3jr ڄ,B-D&6YRh>}k_-o PdX] OߦJD_UJ|7v#맛%4y8@<4q7'a kxvxoTf,67.Ol//Ɠ辯GvA@zl1On_>uCX)?#!Mdd]G38_2 ^k|Pp\Çy f9`mA`n҆#@B_jh{Aho6!TƠFy0VckPmA1'Sef%X?a|l'|8AM_:EPJq\]/Bna|3~9uxS<8h~KF˼hBT9 s\fsiB%of*4bp%ұ՗cXs7{(M|l룖}MG2N(N.KJV H ai}Ɲl N֗;K۲vY=eՔ| )Xrh}8 MˬN^~a5urCdo&NO5Q85W[ĵ'Ai&ި-2%DRYJbG[M9^+ ްB34?5# jtfލ+\ zԩv S\ w6|#e|b} fO2c4|K_;s<:j3!a"4t>L7:BǬF/.CQ0 30Q0 FV( ԯn'xҌ(01Ea?Q@#ۛ3&ae`p( endstream endobj 27 0 obj 26048 endobj 15 0 obj <> stream x$Wu;LOy{lޝݝݝc@haDc$ ?$c"M09c2&Qݿf nOթ{Ͻ;U{*}]u֑#(Y9BX} Ez.(VHg)ir@B ԬBQ6+|W4m i*(=9k;^*5S_P6Cʲ-|P6eojP-H2(FJ;rv?5G/P` r[ʠ,vL^VpL8&;soE@5͞NKiQJ(;2M% je0F~jj^T DCU=+\䃲#>Y13pH%S) %̦m( UB.l_hmfJNuis7G/iwBiB\x11Gǂi-) %Z)w4^dr˩~'*hgE@9ڻI)Ji$xgQpb5iK)"K9C)JiH&xgQXt[Ahk:ݫ` 9n2Y) +?{nC9HmM{u~Dr5S2M& =Eg7So.#)RznݏRw&PvJR&<`ZAThkr\`MLhdH7Q(5okO桚 wa,ɸc**Sۢ)trhzG |3l7}L T"aV׮㫴.\K==.7iVZͥ,o %G}L%-*+YQiȾ-i5k2Or}F#* H2.iE]ZJb}QlbVV u,M'©"qZ-j% >JCZ"m;CL&gH]w#ۤa%yp]\)nUS&ͩҺ kb(MaL\Oۖq,enG͎$F_S-tָ2iQ҆rW(Pf Ȼ ZiI<7'o]J+&/$#65Ql]/WI%N &^EGp]LqUWT,\$fVsbFOjuie*ՅW rO,7횥d>HM 뭪1 ؔEDMQ,;huy9'պf*B'`z&i&CY+Vn4Ѝ^U9xVnZ]ImײJrn(I P8s Z1٬@QLn4GiVU? ؔHK1JO_68M=cֵdK4 ^= PLn@̍0hLxLu`"mWU7SM&Eʛ6$mKY:+཰$q h&v{aztD71J b3i)> P(.t 8[2g9جXɨo-;.iqrt?Sf+A]]Ur+m+ˬ#БT n*T dDd_(w9dBI nG+umR2[1EC*.#ՎxE14M1wJ*6+8RoZ=mV X$ʠzv|>+A}h SB/ƅf%YIrn,]j6VO&u?# g92^v >{JG.SB=m\V811aiJyG]mI >Ub֍,i%;xE @|YLBI#ƅlu -Vj4U4[W @L."ĬYJxb>+zHs^U da3 uĸP.*vimT7m˔ R|aIEdu#[nt2d^Hshʪ\1%ƅ9ԊVi[feJindam&Y)҆}USԭn4Oi/l *ǃVJQnZl*/hq0N2Ȓ~ .fz/^IPEhF󠘄]w*V?btsfbAcH^P=gGnlX1O $.dUu׊ilZqV(JJWQSlE1gP6W>m4BY*r.ۯ>;b$rYQdT5&qw<(>mw]lE7Iס "k#I6>OG7"4Xİ6U,TZ*T&mwEϊO[ybݗ7[L@>O >}ZJӴZ޲-mz^I%JQN0EMϩ\Pi#X6g_8Zy:dQ>*+KWHݘ'2k(GJSG:m(Sqvuʬ_`#Ӳm˲vxI]OuD+zqs݊X0pN )Ӯni\Uy6Mhu31PqBrhu9m3 hJGTr٨~iuS77?}TG\$Q?Re%yM0D+l(v֠!IYHsg=N1+?X*xG'ࡹU .WH]2u<$$RO lB!D\B!,B! !BR*BcaB! !BR*C!BU*k)BaB! B!JhVZ CB!$ >B!PxB!셛B!V !B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!BcBBn+tR5P5BfjJCX #ԔjB UcP3I~,*;|f+BfPs( $^>Kg61j"4t5 i*VTf]wt,i%Ub:N+e.-ڴ\P $9v%i(Gh,"PJlCޢcB9٦Q]ݬllZV|VP=]Be9?d*&4g޷@^7cӺ<>\W<֒Vi[1-~E]娃nAc|ZiU7dd\$mZ=p7sbI24REP)4%A-gAfm+Ȗ2^8],}XV9ĴMS1 f*)1 WW}2YNȖaZ=p)6s21>M8*qqVJ M۸!Nn)III[XV<DN!69#bGsWdn8%]!&14&BJq3>q4ݮYi4K YJMkkM7h~14&BJ3$zUR"ݮypK@LӶl¦;5h\(t 5" 9.%g%e~je"_xmnKVL%' BMBTOFE*Us'd"_R}|8R+zN&PO6yT%oK=mbdjSξ YR>sPOi2" l"\d^$zħVw,*Z8qE}ѪMUr03"0Azm&[HGi3O58j.r0 yB&Jg}XG &%琩t^i[gٸ/ZUMEcq!ϽC RiB~"bWFidGIˠuI/ "1ɸ!jpi5uQ?هeV*v)E%i,%+5VISmT [&` yB&b*}L%>IǑ̒4Auʾ *$B{A؄9DDdV7 *Bb>6ʎz_ݘ}Rb8*"qy8t?59:لMFw*qfSˬG151}mT1]`QAt ʸ<DM\&'>}c0S2QLYt$b:*!BiMEmRLƾ8샤$>〙qbʢP%%y˘>sPO>!BiMEmb*&5Puv2""GS'U&61}z]?~e\"Mfz>p*;EN2}6dAHuSU !BG"MSru?f*bbRY7M4,Ww*T>Y`M1a⨤jCۙ$Udݬ\$IP]I&fݰ6Tr\EPge4S1MnN>ŷpayV 5I.󠌤q|&)l)'>TXFHӀfiPO6vuF YҠ&J-1Yׄٚ-IJ'=LRdA(=u[4& B\*ǔl/K8*kz*;z+}Ci[tS$I՜A21ZR9TI޾uݱ2u3hKKIgJ՜ni#x+-4,"eX:?h}.b\>spW:TTmf϶0X ,#`s,Q2f9MC2QƙXMK8e=lV89-m.brHOQn $ #|Cz\ ![Y5P !X&7jJqzGȳ8Bĉ CP9t!@ .Ajtq&G(#0Dp#FjPqF!B!B!B!B!B!B!B!B!B!B!B!do2.__3e_+uՏayWG]ZW*ف_u]#~eл\oW*k.򿮴@#FG*&+_._WZ׆eo~yy!Bͪ+raaGyT yttEʍ7g!jb=5TukӨT)(篹暚O:22M+%wS{nm /pݺu1 m{ Dkt'p 5rYgfSI7Q[>2_4V ]ȷ]'|7|ȗF4TBCPm;w]%]](տCUÇ?񖖖yL^W--,>vko-'-,'< KK/f+` CH/x l^:+ nq{,M9Gn;J 46 ~y _(Y%j|_nkkHc ]+${|>wcƜz1Tu=_>A}C 4،}c5r?YpS{s9]tц R։}KE_j^o>䓳f kI"}Ao-H=Bsg 7p'2QXwСC'tRZ7ձeznOw944[暥ϸ7TK3r)iT%=sBQ.;:u9)>O:tH1nj__~hzu֝qv&_|SK*qSȖ~b&{[LzZ^vh2X|@*4Tr[=Ӻ/841>C[{S k3ڱ%sWi_޷ی?OC%TԈ7-uSG0T} ж.xjH$|t5$0TXx]a{Pa!{ @]ƿ_,xjM ^:%n 2CoPcRfP@cmtBm.ro`"6>QIt5MKf dD߂'-# ^:~QIt5M DߒM7uC!-# ^:~QIt5M DߒM7uC!-# ^:~QIt5M DߒM7uC!-# ^:L}c6myNo<` a5sIgG< `o+ A @C!6<9T}X};>QGG`P L *\0<۴Ll\Ի\P*Bm0Tύ-Ǻ6-g{7}x|( @!6 PK+J,G֖٦P"Zh*"޴`k+q><[9;>lj|@b4 @[馎`"1hxX+?wU%1 mHh႗l}{KY`r]dG) h xTZ~Y,x-xHђ~av}qDC@xIraVWZ Jmt}aQ@ @mtZ%?K@rd}B?%[/ K1T xTU3GMH(*OM?U8_j1T `@]% iߔ nEO1xv|z8x _ VRM[ -roP t`hGfwB{vH2PccLi7-*p"7R_E72{I9*t[馎`>/,>/p垳Ƃg mHh႗TX:!wO>Ѹ=;xTZ~Y,x@dss ~_:ԆW&ɅZmL=.%k &-rwx]aV!='Ⱦ۲Q,X)MxTUȦHI]_ʄT>2$y'~ɑ{ cJK4ò2!E> 7"6*pJ$؝&T3I$<'xX:wey‰O\\^pgf ^:eחG$$Ҧ?!9?殮Ⱥ=mm+։b"}S_>='޴`'[$OH9%~V&?#5VyJOt)/K޿jxF%n_Xr5m[B{$l#fddܾ_[V$\/"2BK;1(+ʉ4Rp}D#}CA(& -C;~u\0!ѱ!''SŮϳi7u)?f۴;oݳɳs[4a s0 ?)1/`+N`R-Pi]-_H̚R}fKж5{Ž9׿Ot{+6| o6IxbK.N;f<]_0Sj'#+츖JEiv~.ŇWoɞeΡϫT{T/@~g!A2Zˆ2bnlс-ARhKV/ܨk3#69/L 7Tvbwv|rxlL16vބu~Eߠs|M1G$Tҁ;f/+'l?+`dp) e{k:F]ӥ7 mdlv}e$*i>qȤYvp-Bgx57PH-KGJKN_Ӷ{WZE7UFP2T#U~I}'g"}cV NY>UgLވYA!5*'-c<~Dhug|Z_C b6!}ZzN #2"deYP0).O6qg_?(jÏGJybKn9Tm[+`>&꿣hŹ(HO6̧͙6޾Am]+S]?5]/97fZ~,tU]dΟnlx, USNUI̅]Ӣ(ljɏ5v%\?{t¨<9Djr9fUѕxⵠ7jEO[KQφjGԙx4swQyMɷ $Ə܎e_?{ !HCmDmrC黭󞃭NȤ{ajW;D[;?;"8pWTO߾AcweUrq˸Ρ7 ){ ҡq5!פO~ ͧ^QZa'dsO{ 6}cIK}S\5] wß8dnM0T*0֤2v]%~R\Y]sT~UR2@frK&d~&2{7~1̅ 9!Wx6hz&0:jZ{f6m̀}ͻm ô ŻY9D}0-oZ98% ZM;>ĭFg ȃ_y+uHÛf3H~-JD^n'$6EB[;)!$o^4*^S5˅w)OqfJH>e3RvL=CV{}o/cI/ɡ3 mhH_,xM4kAd Мj&6lz{R~ px9 Dbb}5'i+L 'd/4we9k|)4+~F1I[o4x'L4Sӻ$z-Ү8:CO"M}5w5d}nnoPw~!agS!R}Dʑ{PA8nTyMоv.`6=\!73xr?UKh[TGK|bKALD{ նu 'vv&׆j'7 myR'ZT>7=ٸw{FusD(Po YRiQXA$eմ&_@<.iw &ĵVӆDC''ρ<#2//4}rGٿ &ɵY,x 퓢 +O1M= iAsm6ѷ)n%M,OM3Kpm՟I5iqޙtsvwl"hCEc&2Jˠ߆ӥE$DjG׆J7²M^|H i~q؁X9Դm7xȓ) tɇ}#uMHu9%I3=}ŵZJ[~Wi:$={+>j[c^mNzU4'V9e0R)x ,{+{t}PMA4oWw-WԟHj9ISH'y ߹0!R&2HKh[TGK~bKڛBSN꽵/6T[?$F&dao|};Or^{&j7 -~EnoF}GG|L6#>.qm"oJ˫<%M5=a&tl_W`CV3roc*R~ͧ">Q]`zdke)ٝzou8DթolݶM1O*Dmr* 6T:~=ʃxh}xz18V 7Ho~$6LH j{ 2IYyޱpsuBֽ`$kGU-޿5TGx 7T?m6mꛣ9j@U26UAFhdz%ebT 0C5}k;7YDpW?O9n?)b ^:cJFdHO8Am2:,?_<Ac?~=oLsȭPěMky fृL1uѝEJ@:CP{iT~Uxb57,NQ>5iiULFII5b"7zIb|KYc`|-OaOMԵ/ Ogu̚~ZNC~/;w_e&ޖQjkȽMy H&}=jJi4i`f"F!z`ibN*'ތoLX)27@0Tmf.H[5H>&PEB&U5ҟ0|}:1깯a mYݝ > UD";:j~ְ.{4v|WcgSη+y"s|c&2ȶ Y^}kǧB~̳Z[`ʼn#|nח+ӥґ9 VӏS*x G%Zj-}'tƩ0 u՜m-tW"XJ1/dtxU[^1T3'eoK.W>w={՝+;>=\}fOt)SCѹP=iT򞰒"[D7$AbKe kӿ]PE;w4b8p'߲0rD[?84/^V{YúRrm&/x¯xz]@noF2ܕeJuU]K UĞƭ^ss= Z"s֮RǶjfjrm} H6mD0> {PA0򠸏k쑙PE?ockgP]QΧ7.}t a`"69 4;0bpikg<C1{iMkC=z<^d~ӈɴiDVp`B&p}ݕ:\ۓCȡ Y U߰san{=!kr&2Su/ yL}c4k\w|lOd~\d2pWgnQo@"#ԏS*x D)܁e5LGol|]D6jޙRW )n ܭQ&^՟J;߰eR)x !ݏ5CUcNJ͑jR"~GiAk#8o*Bۢ:Z:'/t}'C~(CoEePX?{l'PsG]_ iŵ/gΞBo~fZՆJO 1/d+k׻29/ĜkLl8m7=kӿU'~!jAa&;?>xIrak+S_vvMZR"'־mc]_x @F1I[P4.Ś>{|WFv|fxGgp nym 7O0TXȽ .roxFLH46A DKP#ѷdMP@fmHh႗J J›M C9&i*hކy"6*Ƚ .royU2KP#1T/@DߒM7uC!-# ^:~xXbWv#16 DK)0T*Hoɦ:S,ضmxuV3Gt ?sQ]O>g6':>}%x0T*Hh[TGB t(]U82TH|\cM}utᆌ+  #`bKgyk_=Ӛ/PĶ7 ^^`wxIr-?,tM(o|] kЖ:cۇKy^Pa (r{瘤-7t5f/)W[KPNZ6m`P%vC{PAV\yjO=Xo|@Uc ]_xf/փ~roPA&ҨR+@**!:xw]_ 'da cxρoU31TPA *Dmr̔Ybc 0:6 c  X"16KsL ^:ơjY*` VC$ɃGJृ ]U[Bn {TC} ĀKBۢ:Zu ^:ܕ垹^US{&8#gՕwUP؀K&pi,ݭpa&\$CȽMCsX=mvvnÁ':U5]ZA?C  *Dmr̔~Yڵ'W|9{I{&݀5џ C` ,%9&/fKR.sWWTR~C$ɃGJ;w<þ{v7 '֥O=۪0  XҮXҁS2=[7nj%2VM1[P؀KxTZ,tے_;yo΀JNbi8P؀K$1/g!x- r)O~ݿMC퍞chҁ#bXnHu3.W^ܯ9cΟ ,{P$%{7Yyطɷ itnR)]ށoRu/틮fonL}ct+9U*v%|Q-ު䞭}y }'tG}is|RT5L澟;CȽMC~'doQájt}C 2Tn掚Ȇ\:x+^1wMeԑvc޺m 6;?;2~JPdӵCt;W=Zw3 !|Ӏ:roP{KfP^T.Ulo56t}DKчwZU+?}XWGB[>%j|jOˀTZ7u y r2Iȼ@)3mE>퀋u!I5|`6jFYh3чͦ}Ii?ʹv%2{?6td{cQIn*p,I1)(x@w$|t$U=ob9ƆjGUdP^Z{L[+L-h >-?v{Rh3P;}#Rҁ:wN9̽wCY>Wk {SMlmM=8a ,r{瘤-7tKhgy_ő2YN%7TE-}8RߴݫcAwk(/oj K+V+:zv,Eme]O{{cQASؾ%:Dim_00T18cڑoeyWNliHjW{oXkoi|glsWW)ݒQ@AZP]Y6sSŞ׽oꛣөhn#3ZR,5Q37U+ ܱS(џv9uf)Bb&4(ˢKRVZ=#nj -roP3. {5x8dSVpzЩ;R;HU&8vf۶PEQv꟔EԨFFoҵ5t/ۗ2wEyU!7xm2,;>9<&  X"69 8ckO mZ7{gsFb\þ։ⶏNn0wMeq\U_ R.P W紌*C5weY>'?id#,ZNtБb;s;1yJCaI-K;JKs~%勹iDzm^}Fd>TPE4{chooV0_kT:ߒs=ɮcIkљanbжvłX|O-5`g.6mPonBc%><$yWV6.PјpCݾUyh74_ g= 0T`Jޘł;րŎqc40TR~\=B-?I:GedgC5trk}ozboLvbV7pSHcV{ X&ɵ|Y,x@ YFxg¡6W|CU}{V'E(pv*C}Cնuɚ L2TZ.bw=%P΃綧#0T`)P~Hg8xf>\:gѮ/S|FHo?1T~.z#uk<=w~VHi؈cїP%c$=Ǥ-&I~$Pi*{2&j1Vp1TNl3ɇ'򓺃Z X[v$){lL}UShޙx4ncMZ/g\_ԾjV?jn$Oũwl;Y`жvł{0}߅PM}ӷ/~wr|bOPEn֯+ʒICZ X#7f-"L{4?B[@-M5fs`#@!O/]_ Rr(0T`7$7f-*OJxK۷zg`Wd 6䴖w*[ nxhƝd X"7zIb|KZytڄli#x PpO1PU:]{3>-чn;pB쀡K&]:{0TwOvŞߠ<Xm: *Dmr*pI?=%UgPw$߿5w# U׾dOض8ΈƒoAGy~-(}:"} {?1x[EZ'QsV훒_rJ X"69 aGi :MZl)#4Tc,zU8CU)H*}M}MNinAv*]0T`)ܰLwW5CrUT7wBCaƺHU8kC5}ERކMҙa4 %9&/hq)O<@ŌKEWH;(4Tsׄ8$ߠsm&ŧ3ퟐ-s<*DJhҁ"~.k3@ΝV# G#H6C4(}ڌJZZޑqvFD1( &[ ^:p_:kbtK5<Ӧ!<̨~|/!:Of-}Q?7YdO X"69 d蘭pz#=_+1hӐPMƎy^'ٝn|}3&Zb*t-0T`)\]$Hn E#p<h\OI~ձ}Sq|׆jƊdSyN3Lqɭ;*tKĉ܁Zyol8M}ﲺfݓ@*{_ۚ҆ j9ImN8;`D߲#yHt5mxuc<9!]SPjsB NOo#kq/1'P%mQ-/3[[p<{bno@UChFM|)yS]C5&Z,GxTXT-P%~4[ r eE[v;Gz0T_)zMu.`4> ,fZ,t}6j}\8oi\!7w& z`wrx0TTҋ/hq{(2C'7،ǃKF1I[o4xيtrRvOn>̗*_|\nǧ}yaY8jJ^VuJTBGOB9cP%*FWF\0{yYri8y 2qɐ^nOZChݳV>ă+Uc*D1Sxg*Ь#ȽM= 6=#7䓔4א^_r;m1Tk<=iY>ŲĆW<9l4S&/\8Q) 缜m~9RfDH{,OKC%|sR\ywh谝4̇TM򍸭jO .roctE=xM4gf h~07unOLiSk+ CѾQ4[cm5kn&LY~нmy3Tk+zfjEn,ٯ\0|W'CD߲#yHtu/kʷO OL1+ߚcn U˔ 7V7lo*u<#f/)D?+zL<>-jEhbBۢ:Zu ^:pMծiTV{|fW!Қ+WNk"~e`3Ǜ襃Bg~~%F$ 'k_#n ?ÏGJ{obK󝱼~*~?kӿRu*ZNk"NPE*;?7R>m݊:r:w6sp&֣C)*`{|A*#;7o` ,I1)(x?6*w[}aE'?w|f򔞮*s4毭L}mtG+W0T)-WP!roiK`YvEKoY[0x*,yHg}xhꛣ8PusXTMoXޡ{wDQvt ۥ'\<#[?0yL^^bF;ƁND?@v}ed o8?:$H2ab/yжj\2K#Z1SdIP]QnߜΕFpZ,ln5TW+OT^kwk9:OĒ~Wnn[Nz[Ό.sK"o{Nf6^>ϴ?_4OIbSd ΗF?yogճ%=UAh'mu7K5kR?6t2YOZ[֗':X|4<}Yne-bܿm+ /2`8转SG`+k.⯡'N­RJБ|-^ZW˾kk__h \a ߹٫ZwSzJֳs mv|cGWTOw<=cwKPu/T]CNW/liY}U|WuySEX{{r~K4^,N#\܃GG~Kۼ!O !.۔9_:M޻+M4?|rފ-F{dQH >9Vpl=?G/  oa+s#6kۅ_TGNAR7ݜ/ȑ( @FYIP77:'Z%7tD w" U&PtPPBuEyUncSQZm Vɻ @j-y;P ZyUncP|푅j|_ encP |GqM!PMDdoIgPǢe8Iuߦ{{"T8L ;I)2:_:ih늦BKESPì$y(TQe7zO@ sI:" @K)5TC>@ AFPDZ{xU)/~GzHXT*|cκvo?ZYlɻ e9WH/T9_:I_r t~!j,T8_:I_~U%mjBԁ몖_z .۔9_:IS/+)HJ4B}M˦iSVPi|kn]ezc1IGPuNP ˾7|ꐑnc6*>Q5tnn^Pv>auKmu* _cG.#|auySO,Y)ɻ /T9_:X$Η[٦f)T 5$~G~ C$t-j<*-zc1IGPL0m̆BEmx'@ yPw*|7Kv"{K:, oSd>ZMBE^o5&* FP@Ȼ $6*@ncP||nccT8_:_doIgPԐTm S‡@XIP@덹$B2H1 y݆BHmݜ/Om,JK-lS*bM#?!v RP:k5I y1ט#R@&6fC"6< PɻB QI||%mjBRCR])~2NAR Jb&C"7tD #l(T [݆{w @ y_wst>a1*I//MR@jH6ŏ@)HJC [$y(T [\cH`ۘ d`O@nC$6 UnΗ'6?F%EtY H Iuߦ$#:_:v>ZMBE^o5&* FP@Ȼ $6*@ncP||nccT8_:_xiImPԐTmJ2YhGC [$y(T [\cH`ۘ d`O@nC$6 UnΗ'6?F%ԶY H Iuߦ$#:_:v>ZMBE^o5&* FلZ4ҥշ;[ώ:_IPsP=M|ԕ##ww* ;|m@ rjt7z{TW$)TmO%rg빱K]GĄB5?=ܲeT;%|@-ס⚂^9}6u9?~饗jtU>0c+M}oLyYd^xQ۔7c.]Zmoy*7Ŝ{~O7l6gjjO>wPT״8 @mtue{ ;~{9yW\QPy+O>oݭک&ͳ_i~-^+qRp >|X,*ޟmsB{C9wz{{|M9sk Ucǎ .[BA{/-gx:1xSR_ٳgoƐ]*/v*Oҏ{xȦꫯ-ܹs7tS c=&/Tqr̙:2Y3>z뭑-T^v]OlՁv!vmfPr'x=#w8E@?Z )/I.\pKjI Ƨ~w9%w%U}^Sss>[.$v*/---/7*l|Owyrum*=KGGkg]wu!;VWd=rM HO:m۶4LB!5F8PPjS),T ѣGN8199I"Bo 8R^X⣏>*B!6㏗|mf3Q'c=:::J"B#!!`7;hIגj !$%q+9[wI/|Yj !ye4n6'e?ѾL֧n6G!'urܴMՍXczERC"Pş^ PC"4IRBUϡPBE!)NEJո)*<*BIO,w* 88\o'"e?aϬz`yH% ?C-!o)r#?ʏ6sÕN4ҁ <ڧ(Y'K$q#NB63FQ^xFTc\-/Ҕ>Q==s= !$>YW%'s 55x!iLX3ObD#H!$鄿!WT;E\~-ov 3x`f,uJF-!㑼+ih,*#WQyHZPXBV#9p8372 h4nJ{*^GuY VU#9pĘldb+ !!"7ָYHW:UDϦqJ3~`YLTepb O !$; rӛPň NXc7ܴ281! 1~sg3ل5³i\Ẻ9P^lqfejb_5B!~a$?ޞ&(!4D;rہٌ\-OxG3u!gӸs+(|"ǒv)+B!l޺+܃:Ղ?Tcj*]Hrˢ<'(? 9|LLi^B!f-EmPr21S_&!D,yG&N=ҸM5,zɣ}B /لsj;Ĝl!$j;B!K{V;VuА9nʏ0zS;PxHȩåmb ;pkJ!T7 "9u?|8jjJ lUT6,>!;F-<ȍ@g3|88& U![]cb;ǙX*?5 endstream endobj 28 0 obj 32491 endobj 29 0 obj <> stream xwDMbC ETĆ`᳂bGlXQ<"( 4 RєWMKvLv+d$IfbMR j ʽssPAyl'vfB#zb/ʑE#{ȓʽIzm[ D1o=qﭝJdc;{u/5-W#'Wi h>Ma4y ik@otG)s%'JWfzߓSӐQ6牢/iܭydO:Ҭf&1p EΔ6RtOϭT iɓyoB|y8uPHCMK\a.?UN.]uL@xN|qXPQ]NoLۼǿ{YʫJ`ܙqq Jy.ST0i\*Ocڛ-x׋VAӯ*^3sHc;vؼ2KYb$"ViN{9%Qe "DJ?:[˂rÂIyߘU# ҰO٥EM-&}8CY`|+{&g'jKu{TU)! ɹP "REM՗(tn8*zSJ_w}0idJ7yȩoKGP"e6=7&iԀ-]6sk^2Y`,/64`0:vss@DƝ<6AdYiD" ƽQe r3=s:mP!QU68H#B i*QwV 9;68MpYD[]1ǩ4yF@0Im|ꙂW^ȧ09/;|+7qJcҟ iX[R7Kzho =CMŖ4zgQSтXZoVMb06)v8{a% pv܉2Gב39wA˯!e#L;$]Xz?m:4~9~=]ڞ$]ZDʼn&t=>A/ڎա׉?B@iX#NaQSj=%}vH~^ҕlIDdYABi|ZKj%GW{jnƚkxpa5ԧ#X.t=-Icez۶$IS z£t|dgxx;EW#]Kc`b1G~ƒƊKܙ4HIU󀷕AX$JYujIC,IWƐ1.,M܏r,>a_ӰQ>r?fo1.|ITy<fN5&)|IcW+v|$ªٳ<ϩ4XWa]%ޗU,w|Y5d5(vŋ.)~Kxw$lq)OwgG/myʔEmMWS(a2i<."X+IOu]vf#GVe}o'Ѿ"}~)qJ4ԩy-*b>9#4 WSJv]H}AepM=TsEᲽG8Gr*+h4T{)q]J4f-,=lKMronGב75HGJh+6WJ+!'6Q(N9'j+W}ۤ!1(VM4 yd&M KcSn-T]?jT=4_<+ W_FK0 i`4֋WK% ?rz [9)2}-Q*IX )7;ΡFN;q_B?IC8|{Qθ 4!*7:B E '9KҐ-pGa+eqBlWVDڿD5{<LơgLJ5i7GzWױs04ZQgy3(Ҙ/421KSi[FىEa/6:i|)SZ:#5[Q~</M$Y Bf-i*3l1Ev-$ҠP Ng&Ymz}hR. zs$n{V:z~QQYD plWnVϿ99)4nSCk\^7P#ɞ]ĔQ3DؓJ)?꧊96} Ͳc^2 ;YR:ijm+tecYON  ֿqPViNJD֗ƒl0ǦHG`NK_B^q(j o'ͬ cmu5Ґ_R7<*c./JBjGB2J?^C$)֛?v, >iSr(L_ tK#[t?\:eMjĻ8d;hʵhaVYt+7ʦg:>I[CDL/8]ѻdB.a<,ﶣ6,ХHC~8+˯`5L=GzD"Y6%82z%A7wpnMif˕nVX$Ϫ^k(6jiPr= Ӎ4||ک-r2{FHLj4wکS] ? ޱ-UB]zY%E4~=IgKi6sMce,0 I9.EcvkWv->(e?KsIqvbvHyڊpKìECU KɩZF9c2+H6 ˤEA“ۤ!BF[rehW%yE/0{_M?s FlW6yG%\ eI"}J̔rer-44Ij7- YJ|غ~^7ʌe.=F͚ԙ6&Ґ-aKỦf*ܤI#[/ezjO Ҩ`Ez5:[6~bF}P@rL%/6QJ[W- S@>@p>\ʃ4yVe.안=22dׇ[rZuC'!=*w0gL.iPZi^Q#RIJ/*{Su Klix*!F;rDMj1ͽJl*j|&\O" ۮI-\:ѭ贌&zd^Y҃͌*4c[54 d SM0֧JZ}e랇b wM_ݐ]p>LsYfiaHm162Zb"z4k.#~MV;533k04]]|20)|%.!'=fZ|f>e@YOA,K󞶚 Hmy,kOvE-O5r[ig y");Y>Q' YW9KS#6h ѮJ5%q7UŊ5Y!'rhYnb?zZiEݳy-brtk2wTdMx\etwoґ|Ds,4ȕ4&Jcr/ʧf*i^-hs_τw rښhMi$̷%g:zP2x_QuAّ"kt>ն h[+#*VF;2!WT-XUia(g;'DM֕qX(pmjw50fS+g[9ٞ_ְ-=tFDeL_Pqzxnvy(k}pC7ނtՃsk i?ɶ>Y<1P+Dryg{7[X/°GDR5'ht\6ǽ:;qVyziSؿsxu=Tbml^<.-.'t6pr}M֟CJ0IcSHRsNAK_i oضmʒv2$>k"~rz3ٗYdOSdN |8!\l-r|OM)X̡󱆏Hv|Id+H抷"kg"MDk~}Mc>ulb狲smeZs@ YeH%ĥ㼤^`cLs61Fv_n3QY3Ĺ(b!UoNJs! \5SX{J:{Ws~[tL '>#9a9{%#/|eD {lX6jO3(W|"ƚrąҟ#i 햽:~{Lq\gt}6EdGDEi|RRJi,_!{bCMms?fxvA(g$z !PlG;gyqɕ6\ǺSd6Ǖ{61mfOyHV7;$޸ۚB㞎! ct_溏Dgi%( >-O QL(^9E1x_&V؉pl \:XGFdyXI"X뺮W7mZGh+gʡęu+jkPq+5c{vw&iȓ4I^#hKyl'U=I9N\> ׼"<w#=']. ㇊΃4{xIØinD7:yƺI|ziJŤX|Nj^:^~3%˼g+a{o3A!Yv,^ 4;UuOJ6& s}}bJ0VސLP?J^ޗ+hوɡA`ӾB0֝e?5yJ8rۧv,;We_|[W;w#ϋg9j9oՓ(gHhWP6FnźxLF7nlպÝ}~:o1e^se֌Sc}ycqxyՅmoݟl{nsA=>`V~+ZDtѤAYkѦC^tc7_{Nf7\va_twSbHx@˯Bjs._N @Xb+,<-rY͞0i aw= 0i(b>I#)2Rs1c0.,/,p, \|͗SJa!AzSκvrG-ݮ}D\J@<:74cp⃿rZdRnfG$8fQ<)z4g ; w ۳tx~_~f*{y3b?ҸTo ̭A%zR)^sruT?uZ!g[B`3x)Eܴ/yts>n?\e{Qil S-WȝA ! BjO/,8Q&.Ѡ!GiK_,s>eK$dU*G,MR-N(=+OŘdzPfM4t^º1i&M6,Y~?qc)U]\ʫaK?.ߞ+\dzP.'y- #if3 &/yKqv-K/{F%hbt`lۥOi1R0JgH_Y #߱&駋򒆑ݬSӵSiTi|'0>La>24 |^~I.DI8Ɨ~8Fvvr'Or'#I,$ǝ4VιII;ag7_:6x}f4iIR.'ǝ4mk[rq!YJʗ<{#Md!yMuI/ƪ9)aю iƬ-;WhJX0nG4Dijh MGMF1YFteO?I#~6w"X)O| ?DƑQTN] k#ZDI-hd>Bw{ăHIU[>gzD|#x#hULi,ڏ4a#4&M^^ɵl Sgѥ1z|(W]+ijMw|ߑ[m߃x8!1SEޟ4dGUadbJ I /Ɉ!TR4#qIRhZsZ?zݔS{1)s+&kcGegۦ闧d,շ[meC}4s4YڮK!Nyuc_C&A;rK jk,3#4&i­9VRv'=|y;.حX"-ۓsI b^xx..=GD,lsg^9mfH波$V-(ÛNU)B+go˭Gꉔy߱6|XҰ|J37Mi|#>B.Rws%:wx.GJ/i-F[!Old];Crg(A:{́$S{vK}D.ʺ?sQ{6K1uV~s&"zXm+HR ;,?8>+Bu+TKcuiqJFqEJ  @eDn7=T+֑84ʯІҐ}JclR/'DN޼U K^MOi/}XSyh}B9>Bhqlbz=M-{:k#Yo-f;Ig<>\Tu1ufG64\cyh~-p8ҐDkYIc|*̀+Ґ^?.N5xOUu9GqWO l;J&8T 2^sꦆF84G4zt=Բ+ۤa6kM%Z iHc@[u'1aO0<לGoQ4-w$^ʃih&Ygݑ(ǻB|s72dg _cl_L/GGt'.6[;<4~"Y#@^pEg7D4F@)o_%uCL+E\YSւOD*>nT36} b+fCGO9ìhMM4eZw}D(}K|FC(v㔆ٰm5>-V]N/ 9Jh(#G'_ۇ}ܨO슈~P'?5A; B:a`iUAB4Qb]߅KfO5a P#Ґ20dMT#.>nTyb}!ƀQyKTLl_D+,:Osvot%@__ajEyDǐDYNo9>UrS}g7jRzlTUSDY+/Y/CE}%bumb#a mQ/_ad`ÑŅQeTKJ$懧GZޒc㜣"K^)Zg2eOͣӃqf;OpHL(2JE99dgNXۻ8!r}JZ|N"_N4b\ͤ]2d{bXZS$G\怙S޴w+'twfu)ic+{9/?ܞ HiӼDC1d_;?q\V[E7r.[#y)]唩4{N+glSEŽ}=*#Kv3&ۼsrݭDto<{N࿫ih s=gPe+erO;c'p,mxߵgb.PN=~ĢGw,yx/j`iZY) k)>मHdyѹ!MWumB9`Y| xZ؏ZM#ZCwڭe`ZCڭR_̭5Zjn֠vkc;g֘nmhZ[nm{?-rcpZ{K-OfBvkZ.[>|k8-߯v'ne|jfۭ#5nEV:7%u1[V1M{[Wlζ mb ׈b=cݽ%blnֺBOq^'^['lK-/­YVNUVKov6%o55q>ʲjl~i2nS՚jjL jT?q%-9`[Z,(ËVb\Xƕb}.: s#G2XK%v-a{;uzb-u=:PFn]c^cawe]blWG~'[Msayan07jbm XVjƭz[ը*枰Qkeed;O=kU<\֚z%RW$37 Lenn<b;P[ۆBVZЏRa-s]hD a͡BLtXn}}o8N!.bDnDIkTb{Plvy} :*VNE`kKkl|Xm$eĮ&o{idY\@b|$y"s=oЗKr~eZԎlɟQpϖ51fߘu%N5Q-{,?P%Z-^yZWYڳՊ}әՂr6MP_lfj^9[v]~a/%Z{"V*bmu$u-WӡM+*j5f{ #R{I`Z7V֍j8YRB} 곽=o5.ԪǾ9wqOԺ|㽖0j~[M jͬ'ŷvQ#5 zβzQFV}ɲ^;ZY jU[5ŦRV[XVZzfpfNMz?~hYꤦV9L$Fgj7Qm&?i߇'(3@߹ kb6xcW&IIvؤ4M '.{}QٗyI/_&9H3 OW twp,$=~Guc / s Eod;|0{Ga>m9 Iai# xzl(BGqro 0-y3!q5Ko]z>\~53HagO[2So|_Z>z@AkK| W(PP(S/k i@l0~{} g;wE_HH;.@ [2A (8zg>E94z! jKcmB hQ P-%_c .*xpؽoA kH HᚴHxo8Zy/ i XHxo8ZidS@/7hɅ7 p(YV 瞛*%_cI?Q$,4@7-7 7-]~'2'4^z6Bh7-jO=6TBKpқA xТH#iiDB4\x[7ҰQP$ o8vFuiܯC! ~KDppk!{HE,Hxo8Z[P-pEOEs o8xВ ox p(RTV vjiܯ# ~K6I\ io8ZTo @o8Z5j2 '4Ɲ=pv+=5i8#_#?pO@Hc!Bp @ h7-7o8v*%@ Fpφ7 h7-"ߖ>hQ/X~} i\ h{GhiDoo8~| i\xo8Zۯ32 Z @ h7-4r^;gF Ki'2 @Kpi:AxA7-46! 8jTBKpƿO4@ .$)p>4~L4@ .O{pTBKpƖ ~ @ hQE 4R%o8Zr } ERHx=T#:P-۞i\IH\yG?%4k3ޟ4pk2'4io8Z @Ciiܯ ~ @ hQ1In%?4Rp%hQLJhk@ .P{92 Z5v<'4N'E6A U\ o8xܯQo zKʝB xТP}ǀʀ4@h lHxo8ZTi||n%?4 DHpE' P{P-{́4@ .fHxbەi?%W#} TH\xó@Ao8Z @Kpƾwc ;pؼ7L' @Q ר@א=n9xAo8Z P{P-%4!E@ Ucn3EK pFWO.[@AHcu")qԇ4T ;j;- @ܯq! ~K)pxܯQ=VA  ;Eʀ4@h 88d!Opi47E~' @Qz-@ 7-ѧ oxFN.PP(X@@z iܯ?q)'W/ zTi|}O?%_ !>EpiZ^Hxo8ZP-/4@ .xpҘu?i"  @Kpip~r ߯OSP<;C*} _xjqFpƑOWB FRr'BOpi$2Gƴ @o8Z5JBOpiL:?@A o>xAo8Z~_4@ .K hQ |HuD(GH#%4^Llo8?ʌ؅} EK ) o8ꙆTBKpFu?q9)f8?EƬ' @o8Z5JAɅ7| 7-%_#kzHho8 @b px@ƪDr*5J2'47 /o8{*pHH$d,B*_[C.?(Xo8&%pr& Y v((i,!aP)PP=Tւ7I._ i\א{! z @ h7- i\&! zr G v(( @Cխꐀʀ4@h Ȟ'4xТJc }HEkSEҟ{4Zpo8 #O.E>"?I7Cuꀀʀ4@h nOpi\O4@ɕ7KHU z!  @Kpox1T@< i'8p=TVx72 Zr ٔ %4n7EƢWW4%gC @Kn 'D>"$gJagB\߀ʀ4@h 0~ i\! zK# {x@Ɵop7]~]I-=/L׀4@h7-jUR}*%yP8 VxA<o8ZTi,C.?(P i 7- i\9`*i'$ pjM%^ H\x3 򻃤FQ.dB4@QWu>A /o8&E iw'/BOpid/T>-} xТPu*;2 Zl~Xv((7Eƪ|HEJ! )x ˯ Bh7-jU*8Kx nFag"W =4p$74xO7\x(PP(ҘGH!R7-/Qv((#C xb_i pxjV@ wJm4@ .s qhQ{'=P-6oLH. hQ px@ƿeExВoxUxAɅ7|ֶȏ>"_ I7C.{@e@ }aU6Opߣvdy>Epi2GƆ[}H^pL{Ó @pH=1Civ(( @C6ɀʀ4@h5|lWFYo8'u p px@Ɩ5@4o8&o8?q#? ;4~!$!jB" BFNsr_@e@ }Av((^L8-'42GƶI>&ER pw]G i\{Ư(PPތt H_cl>Ep_ p>i@:; >(kxjÇjR>cyƎW>7M+,hl&c^e) 6'=K$=S ơNNeY_>ٕL-O4l>Z[ }n-Нvk>nbV­Rk VSkvk{iio[5h؟Z5[Pk-ր5vk@j[OKnLv ֟n0-݅vkGԚoY1ii~[?/ZԚawv+ j}kZiS5ִ$5ZVDj[9Pkli˚JٖZgڭݚE5[?Z~Ȳ=^XKڔQiYcOwJ]qz;a8n]EՖZu!"5}$?ίԚ#[QkNSF֙Z& c _1rj@:x] PkêENVnUa; UnnRu㏱fZVUq#-eUZ-(Me[ךVUTaV ZFLMbjͬ;@04_taV"SyZ1+b{_ |%[ֵbKaԺ[Cՙ[S+P^nQanMn(^SzZݹՓZ/pyjVwjʭ':Q/Veֽȭ>:+0qg)"I8ޗ4iϥ֓4ΤjbYS"Pn156QnUnUA*G }o|̭T#U>VQf[)~$ZV.Ø"n-3ē]E?4sE ¢EybG`h]`Zk5OcYn}}o+|і6.b2 L.S2~:/>T1_Yn V9n Z.RjX'yZ'q5zZ "NVj5jʭ s#Ժ[S%tX*nDku#Vjȭku+vn]FVkjíz[5c1CEql_z{찬]-Mkֲاwo*g~:ЖZM_8dYWQ1[PeYQhj5b/M+j5FEK}KCuitV=ʹô{QŒ{U>zZzzjjzY/3GԚ/09EcU^>ѴޠV2- [35cע?[?vjjÈUǴS={lguu''QmgYSf$˚Q+FV7дLlcS#j]öAٲ6֕e-KRG)`&ljRr,OE Z-z̔FEA!DB*˴7iwȷ"۷o##h:u:餯bmҖY4|[47Cat ф'?>6#z,Al*?4ݿq`iH#G& [rm6s+ cŇ}H䊬_v{!AF~iܱHbdviQ4֨- HκpgHFW4yczh!3`̙DCg2̥vw|m-k"Μzthn\^]ԼӏEUq[/9!C_tץ\yf+hoԜ޵M:ֽٱy!-Co䜶]>=p,3uhS;ц:sI[WPyԽWuc!/I6ʾ-k@s#x]w {ŵ&%ҘpCIE[76vV/dt7Rrx4i~6F ˸}lx|4ڼn4[TG }n$ObkB}5VLgδS>ҩŚKB/vNiiڇcI7 ^l3ige Fb=G J\ m&>CD{IW~ushCz g̍V^N(,F_ٻlW&viIjDFk劽LIews%_&6[ZX?4!Yi`yiWֹ^gI#,3/h%LѤтM;4X@$3Lzf"M5'I곥+E!-,E7X۾! DD?UrG$b۳3Y495طx^=)u`M" R[? IxBs?X1×YꎠH6[9[[ҘO+DRcZl2FfZ֙u%=O]Xg42H58*D4X4%ϑjmNQJt6V }&^^hpn3oz?JeIM4^bQu.^JUҨF&F"˗F>f>dʴai '3vi@e|:yܴK_֓S hǑbT~I6""n?`_I˧C?zi07h}@pxYLlHY14~F {Şuf>I5ObHݭ,V 4ҟIrRԾ*ź)eK-Oi#/PIɊ#WmziLأ=pe\>! bHaKn[?i0`_wOwƒL̩Țf)= <81NN6Ck2:6Cd#1!Zl%i ?ׄabwD9E]rR>IGjbN!l`)C1r͞NiEωUP Ө3NeeTs2RHc[T&4ψ_d觥OMҦD๰F<^%Ƅ$mFlB*X ("'Hn;"!*6kOU9YOd K`MqtӥHø-R\f-zEdGYTp.liKKWZaPu0[768sZsP[ѐ4`/b"7؟bpBj[qfAWWLXmui[=wf֧e캒$/6,tZ&_g-zlmU47mal֍V?[~4k=/g&F_BKvNRlԃݺ2rht5Ez[Tz};3I'ҭ8c?wU'fi|_Cf[qD]zN2ħݠ$g9c a P >!rt a>{Vvܑq_ {.oa;qaL7D%iJ/1H%-C^^DiOo)+]a}UN$N}wۑ:7*P"~4zI c GN &To3EetҧUR t+Hnj١d\_?Rظ()ݲ1MD5rD}_=]TF*_D`K p_i F;" endstream endobj 30 0 obj 25771 endobj 32 0 obj <> stream x[K, ϯu;gUA3ӳ@!< @&?$[$!3%d}z3_oL[^/\AO_f} \t헾'헊ے\ pWj}>}>*j߽⏓ OJ/|\"wrr>>#X:79uZ0xUS$]}̤S>Aj<+r.q5߿9x>ã-Hܳt|D<sH 4rED~!NLYG.؞Wt ?CP^pW>f}4=xt$4xDπA!!BȀ8R< Aąf`s҆Y0ɾBYf%Va53-ckt {na41 gq|W zGJ#W5-JP5SCXBd@S n&^<:gPJ'+,'--]8.Uvd{nV/Hf@z83JN%5'8Y,uBƤѦ+| %ȃJN:|%Tߌ l L!M7"Q0I:zF!]kOvM؟li}8gi?ɉpRY |#)ze[CvPJj`JDa X@{ xAVg|ۋ%Wwm 115*.m/^d٧LWe*>ܚZcɺmL[ Z)8=Oѝ.m\ov\ju[. }PQ%וAˌFsG7ӁlyiNt>FN>]l7=lwgJ%n6x1k` ]_I,hRk ܍i2;g`۟ӗw@bC^D p2hrN~&IK\~U9rQYT JSf3i+b{:v;4}2/hYxe+A8l,oZe;x;猦3Ken0&$rQ}JݳTy͈s!Hs\+zN""N Z=::KL @8sk^KM%|~^E]]CxCM[.XD[upI[nNDyi)N_>&sGMoE܎پߴk endstream endobj 33 0 obj 2752 endobj 35 0 obj <> stream xSj0S%=EC.G&$E0͛l ^3`|3%\ N\mJXZ[[$Ow^uAHmʣ y4I1"@0qaZc!_%DW M'2 Z-̈ emIr2ጜonY290=LA (^E5C᾿:.eW搥&؁M Z#9$3?60g\OR 08OĊOb^>wM }-i TsY_ЬEݢ-߶o)> endstream endobj 36 0 obj 338 endobj 38 0 obj <> stream xռ |0|Μ=2X LBLe7!!$>QDPK"U`5ǪkV+VRԟdxn.H} s9_ #ڊ5vw*L:Jţ|zӽWZ$ n լ&n/^2ʩI7 hg4¢Q١H:;tv(nM'[x4& +/[6[rM` !m "9M4ZQ/H3PżK\|Q]_" +gXgY},ɊMCG7WΨ#ruփVamrA5ٙ $[xilI);_ )?J2ZAwQ8&ަ'~N YOj,^{i.h2˝,]0w  bŋa Z$mI:DNJdd8TKr)zQ{(nAÇ~`][__vV1dw#~%%JdNt#aa1n7mnszPXN. (_^0g}[ɛM&a-tf7T0!m65Z~'=ݤ޿1v?1wV-K9eGq2g*;$ R] (+B+ =KD$^$R\LJ| K>s,cӬL"ǀ,(5KK^`4LN`y>:(t}yг۶3nl0&'1YMҥXmTT]/.Z݅`Zhjc4Ve&eʙə)kk kkLkkפJݞ]ޞ=e{꾤}})R''N9蛶eړ'Ot?diiiihY33rp6.9 xvFp%Фd[]wrݵ鷿=]}Z/{7]]rt5;HuNzgޘG ȍhQv8@@/ .>-LJ96!b)Ӂ=wCT3|R >…?7*8O(o pʓ.橎1P:sr:$MFutC:̔`F*ɝëPuUË[o W6=soC>M/Q?(SKB,-o<7<{l!CE(}6'F>{)lm.*&`JF}.^rהWkG:NuJ$/OM^1 ]V tp LSQQdrUvڳg K~˗W3?ic_){h%H2v@֯8ⴒ{u(,c>u~ڃ2hUDǴ1E: m%~w@~=dNkTԨQc=(g.3o6Lymdlcs2BS9d;=-AZ hE-@Xdmd1& -<:`vd2:QK*`vJg_wҰ 5_yZIQY碮 n{iثb K2}Fv?. b3/ZF5E';褑nQ%M0]v#MY }a4՚npEBn!Y/jjty99BG *bD_b(3JRk^U*TUBJ[%VUG:O|P։udopԹzFm&>Oӧ}I} KkE콎uwϸ6Ba;8U6혼mPV.+x@yӋ~E%4s iNDssя}En5&JHfց8Ag.3xek,t_NN3Ӽ3مXQ*y)7vN ;'9̀#_s9wNܛ7 oߌ;[}b4 ~ w.鶃=s,{aͷXYyv-`vA-]h䳐zޢi荓΂S[?K#lHl>W1gNEyaayŜ9-s*+|= =n$$d;co<=XPA𤸦f̅H5sbK!p4Lnrf*? >Ý!0tgğhV0!:SmjwF»R]wv]=vi]3+W~?th /+y-ox'+LcI4i+h'f(Ϳ==uǃ{/8'{񢜜㉑?7 ^$;gѢ0"9an"~9?pg2d6gC-a9 @l[tDYLsXQ4c96ɥn;N8L =\dӹ,Cy!7P`.7Wq1Ԛ; ~󭆈%b GNI4x]@ug7g e,>͔a.fY٦2TE/6,5.1oB7U܍&~a&::ium}c p YhtfCo [,RÅG k,HX+LDzQΏ-M!rҷK>g\S O|UVJ8ا>/FDHzO/:vz-ҒH1{%iM- ilfheH9̌X|(V P'Ғ+ FgJBǔ]'MMZҬ7kJ8tixfmSCOnn߾olB~7b?~U٢@9lao@ 'ZHg֛ V-il̲di#;v!I=A Nhu6${V>kY$&?Hovs:j^7ͫMIbnq=f8љ4!^h(|zҾ +݅ڔ^evk+^{)0jJTǣždraԆ n}HN  uG Y ɞJƐ|AchipLqyPT2PAFO;,N 4EbbZ4@HXH2Ҕ#wpqF>s=o‰O+Hǔ)P+?x4MiFվN6Vmn+u8dj ūE㰸]ƜY.(>n]O4oy^ئj٦M;<["4POѽT-Hw!i,|#7=F5d>|s<7KXR>/U*S`Fwޯ({`!xգ`uz 7'N5j"٤KgBJ&5|Lrtk:$ɸt,ژ;uqsp5/JZF:V%`u5{Mȳ#>p>ǗgOwK6<(Z#mV(_~LL#8Mk6jMeLdŘ4&qa&cn%nⰽ4 қ $4~-!ffogƲm8>1rEc#yFʕ +=q{OL?f£ϟx{>>xx{'O?t/we}%:,<2rz T,Ag93"Jp3F<8&7CG|6fV *voY ZBB&!i%;rHYl4*eѼeR̲Kbb_̿H7}R&NG-,jB >5ܩ˧X32V[OcrɒHtnWnʧ%MwAeɄJ*7I{Tl;jhnFI;wur!]6hak.͊׭$#Ǚҙ3B0>D!u7]9+IO=iEE.c2,KkU.o4͖fWWӵzA0 &5nph]6]on%Ӓs]StSS ,tiumr$222JB„(Bu 7ZVZWV[tM&5Kz[=hr%0֍ ~={w9rNg'=;?a8eE(+a-e#Çg> \گ0}7l߃q   QcY8ӷA HƱW@ՙ{:mW,N΂,6-1 YkBRկHw$A;jZ״jZTp*{v2dLYIYrVrV]~aq\8yn\ynraʜ2}aTT&%֯666W'Niյ 6S[RܞܞLݤddd3oJ$oJޔҗ:ണ8>=}|rJƩp}Ob/w>̣?^g/BqvGf+zǧc4Gwݶ~9{yЕE1MY9g ya:ףU яxP85p9iȪ%iBQb=s}\Sej0iOţ1_aDΆė91P4tEYK]ѐQ@ ^+de@ubbY MCwJ z1 dQ<=B;R!gć,m|jAe3/x!ޜf)mj+%꣨GKiK_S^cCWD\.7$PÏ=cQl'JS}V9⮆?=rxg#8{Hy~SR܊}ӌ#Oe޷^-uW>4ӗnۑn H$(d\u6el8M"V]8 1$]> R$y:).,ZܗpV&Mc(YFVt+=}O_R.+w6<ē dß*?Q'*9[[Tcs 9n΍Qk~Eߨq[<{ۨVE 4#398 [ŠjԉfIg_44<\Xq:SgAk/qܩTQ"|pw䶅O~~S=?7f<iPOx(3bn-&qN\_oV);Ր4c4hSP e7#Ja%!Iwt*a&qgs0h&='=SY".+LO[ۯT'PjY #φ:8Œ9Ag'v{v]J(` U/X;6{rpZ3&|_\+Pvt5 ?}Ш7ez|d-f'= NjhTV*?ar2:r 0ԣI+ H}3 4td% 7:F l t[)Y/ׇá`='C=H}l)" ׄ"݁,Iw;i 00 l&x`gc{bz"LG0߭ra<%+w]= pw^fN[@0:FɿjiDYm u|}CSOw',`!9ឆ@c۫քq&bdye\ƢbF^lI9SeW0vD.\-__V+.WeUeWV|Œʥ"WV./(( zq)\-*+/]Kj+)Z$WUז-^Q^T-WZ^S 0ʲʒjX@W.[ZZIkWU_.e6$rJ:\^TV[S[]\TAR,\^AyrIQmJyQ1RX HY\^TVᕗU--[3:aiqequQW*^\FDzŵl$8Q]bK@J@@[0cWNQTn,)Ee5.'̠4~RUF2}_EgG \R\Tk(_xcc+B;j䪓dU^35^ &4@!xNpJo' S6N7f#vX fY£hN4X`”`\\hH)\w +!ޗ ci\c;BQ#sc4"73~ <ݜB}!mA$)e92\!E0&FT:zP'φVjCFգ*~u82ZFCPQTng|{h`5h챹ӿ5^AF?mEXyݨ B_Zcߓ 鿵T5觊`1-^ J_3[Q,)&v70b#̠84CbXv] Z8BF^9JOc1]+Vnd:` =Vqos#jKFa0 ҹ~v3aN}>>V YN?Mjgrc8@A#OhO|`6~FA\܍5 ^&7*vI/ӃQtwOMC8vgL]0l?;Jg@ꆫ0QN7S㜊mרFGҺ1z?: 1khٜ웮egʉVc17Jgzb>bL:a|$j cc2Ƶ~`<]VC3cr$L)dgt3- Em%N1|'ƭoO7JC gGOQ|xS)b<(l^*?ÖʬsGa%=Η3-Ru8< K:MgrL\j~\ 7oTl^zw^z£ZH 8˨)׈)t_=Eޔ4MbM8|{h#ugԢP#Y=e¼(M\WT6j"Yy͆1Y$Gs茉fwsTjj|d:?9U Q[DcnbrT WtpUn +>rj@&"vOay#)h¨o {5P2WJEUlbVFV3[8:c1k^hvW j yZ[u"VelfpU KwvG2Nv(%QL(d s1`Tήh 8W"Fm%3 TI-sMG,jtH/ҳͧ^zU̖GLcPT_9r _ =L6E?7;KQ=Z+b|XVXQ.R~'Ō_Tn%l"ƑkR6Q:Ҏ K}ŌSlt ƗXh] S{U'qw1JX8SEwP-?F*q<~eTGei׹r#b6ɺf %~+a19Q&7fGqwbkOOQ kFbq||&9E|@K؎ƍ~Z_c5\,e#Wk񙰟jNR8TzݱVl/U)θǵֳ7)R]]1vدڑhB뉎WUWUYJ1Z5VqQ(VrJcGEW祔0G%bE6{0 mxW yN^L^}`yD^|!SxO^$g֒ӛr@N<NxBU3 B)䩣K.Kɓ yb3B~j&?9b~ GyG~dr(1<'gNn Q|/sp@!}DHd?o&}C0!yh+L*=&~;8ts#_w,>I k%]5礰S!ܽV$g+]k>.trpdr+g|WV 'Kp d/lUȖvIOnln#M;d!Hlԓ {l$lI$I$n2 e"]>>tv,:Hf%Ҿo36 K^&BP!-ke+ܔ.4%>)`P2I4(^!u벅:&7+dBs=i3YK*ܨ' IܐG[dTrY'e)P摥DIsz8,Ylŋ$a,*2$R Ec pYOT;'2ӓ6aZR8*+m"R0!(df] yz!Nf<=S3CGrs%$')đ3|d$[:0}Ns4 bLS~5%W*"S)$N ɘKMqBZjjH*LKT"d9NH^K$  %YIV~Ld$O|!5>) ⒈ma qx`${ $-"߲Y!&`#&oT. 9mDcODUDk%!Ol&rzkR>viC_#O endstream endobj 39 0 obj 13824 endobj 40 0 obj <> endobj 41 0 obj <> stream x]͎0y,Qk'$Ab0$ a}q?; o}n}z~H].Ik3%Y=>n^'̏iӍ'%ɾϝ>>M%͓N;|mog|~y<ɧφ*Դ~nOy^NG3RJpu`Q._\r%BYrpu Xp]{W\߂7d=땬{nY;r~cW&ӿZ_`_п,uZC 9 r3sp_zcýBatu0Y4NofT endstream endobj 42 0 obj <> endobj 43 0 obj <> stream x{ xTչZ{=#L2yĀ<$ HHB0QѼ&$dL(&*jjĔBQmA^G[jV۔ZlޓR=0{~Bԏ 6u4D2gw¶nq7B7=Y?%Bd;ٵ=ֲoݏoA(mSk9ZaLڮ9Oi޸ڵ ~p?~пac߅ GxAhuzdXmv3NNz4JiY9?fO=[Zc`V܍f֖[ .oex+|2x`܂mE{7[~3߂. F~EɄ[i'( 0Cb#CZO9|`-aׂA(S*œGh=| AY \i5"|~]h}^ft_'"#gT6IYJ}#NS u Reփ?FA+FtCЭתI>{*Cxs>ařhƥK_ Xy<}!VAoMVvc/KԾj|, Еe{3S"%$L!'5 O&b"'仸T3,ťdZ.~KVۜ9@/IoHg#s9ެBgaB00i"/K휑0g3}>/ϧ_Wck3͚ 8_qt,u*9g=m4qjZwt8|75}]PܕO9i()xyŌR F:%)smOA) ۝ M(s%-fsY,E'& RHA,CIC)OJ+i75nţBnMmX.X0@ZîE:7GpcO|#F DNA|"2ZLH; 'O)I,IW;V%JJ5C,@W*ibLً˻;:sdѢ 43ʅi^{= 4.'CU`UzBӃv4`P  D9OHLȰR˖`R}r]"ZP{rG#ܼ~U: / lN\!̩qs{4JvfP[П`aȄi"x$.M-\*1-ԩ._Oj09=NI3GS4,$b_zb1>y/hU9JCet;HCr-XT`^ _)7L#n/I`(?!nlM .J; ׷uVE>F1(o:Xu~ɱGc;W,d#ejOE΂44ɀ{XhfVU x 9=3``!ͩǽvKhvFs̾~' K\ljz #* gHoS/rA.5ئZɃr)oSlS2TőM/l<@p S-ˎYY1d^t[뭻nnu_ۯWSa|'!!56{]_Ng^A`)Z43hS iy4dQHg|10,"02{3cz"l+;~X,&&i+%)iNz@x "A[|;WBR d W~pٌ:?CloM җGNTvu6zO =K\XQ#[<'?-$<iQHO<+ h*S<bUԹx4RJ-DcX3jz^ zޤ/$SrYbNW3Lu:.W_][_kXk\kZ]+M[[ߩݩ۩iii)Lߧݧۧggg'K?=;?l8l$fB&%Y/NNZ޴gk{x/n{oz@{8X+ҟ> [K|7MYpgzc^~*6^17 jC Z]匐o'T%Z.@z2-5Ck~-\^ WTtwscik},Y!Vǂ9ndHp=LYF{Rn1pE21RrOz$И T/0fxw{y+n' Јd5][WkFV v=}; 4~7%kЧz9'^4-am39CG99؝3xȜ'Ÿ).w7k;(VwRU^/C0d3L 1#-×៫kkk+Mk ZSVMיy׉xGҎONONONzO'NN +gVMI )}9ݡΣy< }s/=H?''w~7>u׿#5-}/~*Z!lr@Ѕ\h0hI$ٔop#U B+ rnq79O 4ۦHu'b-vje/b=MYY;:O\<{ &#Zې㐅Tn.%Y°G2k޵u.714ZdEE8\")UY`=,+ v;Tϳ0=\iA% V䉟4y:P=Loq+):YV\?ht#}r\ЕEF]ϽbS}ɨ6m;:;,AL wYh71V*;-j1|:9jAM#(|o5+dV0{Mi?n\x/R=~_={ߌϟ<'?nul{v+~(|`AkPVfħ`z_rQ{YiGKj +Nz_~kӜGR8_qK#RViwClO\O<`B<:dʛa)lT䅠4rN>vXߡVgdg W6χh" _;ܼsiTBľ{p6SmΒۀV#M^UC 9Z/ЋJ<"ݩ&=+╃v Jg'Kp.LZЬ"<86 m4َ=cf*tpFd*ͯG C@m T0r\_z(~?L*_9tUB8[UUqc*uMIoW#~.0`5i<~+6^Kq :߸]N:\+*xFІ0mwnNmHt6ԗt:|Oo(:('ܺͧ?}ĉS4ȏJշx. +ҫ҉~ R3xު~@# ? Ж\l7* ^e58*eA#PCdj*#Yϙ-ޑUXXa٤Rx-Ќ9|_&"VWZf-b#6»7K;3h=?%@-4ZM- 7:BZ$_0a+-$'fc|ˎi8vwHadW &v`r`Pia՛̄G(]rRxxCygoy6DO!'xz^_yrZmpfgL%eوbԂzIT&LF^a1U>A'Bšұ:d%/T$;a7Z[ń[!L|s]ϐV %PQfoьCf_ꐨ;4vGxCi&vf~U J9q)0~))g9f#=~|ˌnHW]}m-mS7m͇4h -CW٤֨XѨ Up ڞ*șLrse , BƝ@) D3d%'ɨWX6YD٩\W;{uGfLtz^g0FIcPAy^טb&Yt6d3M$ۗ< 91^o*Xg%rR;nƷqUƛ77:7l(4e |vŻ.Kukҟ{Goxҍ{[:83%%J{Sª*#竂{>7E\ mnU6Z1 ; IkbcdwjT2vK!FE5ޠlŶ]iуO>mWMWpc>)iٲ/={?Hu@;qv3=-]exFc'_ DƼpJ9iz_╂h`I= ϓ~,IҷR tÿpG7I-`k'Ӑ^| (-BmoG>~/[*,5-^U{&wxܛ/c[T.1l?3-b%Deuد [_?EܳPSߏg=Σ7~(=-^:?q2<[qF Y:QE0ACVw^}B"lLMȲ*&Єq^PyINy/]^z>!`t/<0 {vs)ȩчb-f)<`yU6"L\2 C-J\IE,O}KDKƔE35?vlc/_Χ ^D: H`wk__p+/wCm}T=˂wچBflb^^DS(fryW_4ۧ&y&Fra?fOUFx ϣ *a/{@?㷢Z2zM oQ ]:cGh@)>JFgn2/v/h߅ |`r^uZk>r ,^ lV|}᷸tnH#yOO.>U-U=G4+WFM$d(466d.33fg9H*̈́)*)5T3Bl1bs6xT D*C{ۮUp_i)m ?Wz>QFRjx-uQnFwTiнyhNi (QU(Wը^֠)2~_, Gb]mkZŌL1/6ąmPCGXٔ+UtUT EC]ܱ5PWXjkYnoָUPC4$̝7aK_co[TlC ]p36lؐm w|#捺kqogI2ꌺPWG[4[C]!;Ԝ#tBtcSkCךP:cb$ ζ5 +[CbKkh~".nmMNjef! 75>9nb6 ]!_&+ 746`;h!Glljilhn t1m "K&zNb\Gzۢ9pP3]b4m@U)q6Bݭ!N@bb4#F{׆,PSKZ A%F˜!tAQy%2nmmC܀NaN.#&bw,jiDq&w4(ps[K5n0?h؆fƽ,>@izPmM'#dM{,64((z5&e5_'N84 =&M2u`+D(%MEB`w! F}y}@;e4(e76FZhc754=J1 bkC :'KЍx٬[|2_(DIn:FHCӺ5cgx,|sӚ joZZ,T׈%57UbeUŪŋE_Q5}9M5K+VֈN(esʪjJ,]^YVZ cV..-_".}5bYZS*J)UBhaiYiM]XRZSNa"tʲ*reUeEu1X `KKKb`-*]&6`XSUxyQղJa\%%@%WKą55UEZ*%˩V/.)(+E ˊeڀEeEsEˋW#vA7,)./**+ȱxQ [ I1rUWX ."Fcإpj*jH8G,*$TUTIWKuDǾjV\\\T)_YxcS(M[qr9H*Gfr03^ +&4@r\!(ApJrn A$Ґ>AeC[;Î vۢcdNvxbt ]mRĆjۤ.%e]r5]h2V[o= kh^cu:֙cio]kr"FC] A(5LxCТ@D aM7· P@90Z:a}.P;|D㰢w³V~V Ъf6 ;(l-U=S]R8omufw1Dwe|-s4"7%]5A fg[\Ho (V al50h 3*;U0j7̵A~(4)fTP\a[滉뀕28ZMS 811 ҽet5?t.:O ڙ(8?P&8.:g0:ǩift3kn610Qî1l`v {>*668I)Sd3A;uV52Q؝7s@^ň1mT'k빎KN62fWY8G<:7]Zl8f8rػp=fS~L/fFqB1Qv60zƥՈ NZqME[dMH5:Ŭ(Hj1z[X$s"O㡃yaxdw+Orm'saXd/U3sD:Q25!60+m8jE.Oc]$Kk`zLsFgBiLa.Xw%f,b<Ԗ3J`^楘Q kBh+7]aTPL5!g1O.c2ei{J"K*Uce50RtSp㶳AX>fG+EL B6GHY6jV1yQQ3LEL"$mveq KLRelu5ȱ֗Xx]V)۽leH5+6Ud7 C(\(R&l\v麂YWrbzL %+`aq=TbQ|728\LzLx*?c{r&XIWkќ 1wbe G%lmUG8-3ZW#r J+fV5atJHxRf|:`+& YjXr*-z i~]a_Ʋ*ף㛮:%w]u{:QXmL´Uvym\&T-l*[6]]R@y0/rC>Ey^1]& 1lMzaG:/HD%$LpH8tJC"nY#Y#k|K m! ۴4 [HDnK faDnZP7zMJOjBR&Un2AXN*M2TEʗ[R<,el&YFq )5Kt-d)^lXVbY0QX,L$EAPgi2d&72y|7&K$s脹62GGmBff2%|uBr]V.k=B4 4<^K%3d 3f4JX{Hɱ %YS5BdIfϘf2i06J O)4aJ&/!iFHӑ~^1{a֛E/Z s'l!NID2:Lt38lO#6kBu:t,1Ü9,9Ġ' 7,՝ ZѨQۉ D!&.b#$s$#oxyb endstream endobj 44 0 obj 11455 endobj 45 0 obj <> endobj 46 0 obj <> stream x]n0 }ƤP%C?ְJ#B96i/~ nڮ7;͡ms =;X2m׌Jͩ4O[$}{1\Ͳ|/Xzw/>MTi(_!k0 ?> endobj 48 0 obj <> stream xSKkQI >6aUۅ1"t!BZh0"d:yf:BP|AzjkqۿsTw> endobj 51 0 obj <> stream x]Ak0s=,Q7eC? & I1k[!Mt=u~`{L0zrKX" 8yRetD%Z7] Nm/_c)Arϳ/fFKix"Buyb%lhBUE($;a%YJzht~ڀ]I=WCܩm endstream endobj 52 0 obj <> endobj 53 0 obj <> endobj 54 0 obj <> /ProcSet[/PDF/Text/ImageC/ImageI/ImageB] >> endobj 1 0 obj <>/Contents 2 0 R>> endobj 12 0 obj <>/Contents 13 0 R>> endobj 31 0 obj <>/Contents 32 0 R>> endobj 34 0 obj <>/Contents 35 0 R>> endobj 37 0 obj <> endobj 55 0 obj <> endobj 56 0 obj < /Creator /Producer /CreationDate(D:20080627214510-04'00')>> endobj xref 0 57 0000000000 65535 f 0000586532 00000 n 0000000019 00000 n 0000002096 00000 n 0000105587 00000 n 0000002117 00000 n 0000055619 00000 n 0000055641 00000 n 0000105565 00000 n 0000176694 00000 n 0000176716 00000 n 0000283189 00000 n 0000586676 00000 n 0000283213 00000 n 0000285733 00000 n 0000495304 00000 n 0000456467 00000 n 0000357115 00000 n 0000285755 00000 n 0000311563 00000 n 0000311586 00000 n 0000357092 00000 n 0000389632 00000 n 0000389655 00000 n 0000456444 00000 n 0000469027 00000 n 0000469050 00000 n 0000495281 00000 n 0000527975 00000 n 0000527998 00000 n 0000553952 00000 n 0000586822 00000 n 0000553975 00000 n 0000556800 00000 n 0000586968 00000 n 0000556822 00000 n 0000557233 00000 n 0000587114 00000 n 0000557254 00000 n 0000571165 00000 n 0000571188 00000 n 0000571393 00000 n 0000571959 00000 n 0000572381 00000 n 0000583923 00000 n 0000583946 00000 n 0000584150 00000 n 0000584643 00000 n 0000584996 00000 n 0000585657 00000 n 0000585678 00000 n 0000585869 00000 n 0000586161 00000 n 0000586322 00000 n 0000586375 00000 n 0000587235 00000 n 0000587320 00000 n trailer < <53D5D9E1ACC687C61D7675B33DC00BD4> ] /DocChecksum /95FF5C7A703733EA2762F25EB6924660 >> startxref 587589 %%EOF kst-2.0.3/devel-docs/Kst2Specs/Automatic Labels.pdf000644 001750 001750 00000107620 11544160206 022350 0ustar00synthsynth000000 000000 %PDF-1.4 1 0 obj << /Title (Automatic Labels.odt) /Creator (KWord 2.3.1) /Producer (Qt 4.7.0 \(C\) 2010 Nokia Corporation and/or its subsidiary\(-ies\)) /CreationDate (D:20110207133730) >> endobj 2 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 4 0 obj << /Type /ExtGState /SA true /SM 0.02 /ca 1.0 /CA 1.0 /AIS false /SMask /None>> endobj 5 0 obj [/Pattern /DeviceRGB] endobj 6 0 obj << /Type /Page /Parent 3 0 R /Contents 11 0 R /Resources 13 0 R /Annots 14 0 R /MediaBox [0 0 612 792] >> endobj 13 0 obj << /ColorSpace << /PCSp 5 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 4 0 R >> /Pattern << >> /Font << /F7 7 0 R /F8 8 0 R /F9 9 0 R /F10 10 0 R >> /XObject << >> >> endobj 14 0 obj [ ] endobj 11 0 obj << /Length 12 0 R /Filter /FlateDecode >> stream x]K6Wl`h"g< `rؿJ"%RdٔZ=nI,VU_{k_ FO˷}m'}H|kq_G)qxK˻{_H8H)ls$Eq) ) % iҧr1`#l8㪵ZRm-3e_h1/ߛ'[2}l ϲ}}>Kr{eȡCARt>G!NI5P6+M 9 a"$ swL=ZiXoL#> r>2B{ME̓yy|}݆EL Fz`ԔO} |fJRq_M"4tRt9XC6NSj7&~?N0 F@.&(C Сc(07så^Ky Qȧ%R׏BWGSO^ 'HH'K಺ ]Ġc?aw.G9)h0L2:Kfl LXW9$HBrC$A~(J WfP@?C,|qA(vPΡ"9:0 7X%|7g}h(Ў6vf`Ή:8 AS;#(VC*Lf$} ƃ(L SQ㐜cƙTUNiPYu55@7S/p Y{-:Mn(X$|vLu#]PE-NHQ}d3mWަ1! i;a:ѹԑ[F5-;-cJ}iBE!](=ke:F ШrR J}iֈrApVzԗ,o(YQ=iE{K <`ՑSXƓs n2dfyB#y?d=;%%(p[G(z3M*T[)5pxJȬIl &>TϹQK&rwX&8!%엔bR!Õq,C$”20:1tı -s2eHNtDTOo\y~˘K[2Ό>t 9f;U@ u2u+w_մ҈z'%5MEv .~%',H6Lu]Kwh<[ Uk41hsD:LbrXe'!i'cx\gQv4p[ ,BJ(Lrx;SAj%G#13iC,"PgT 5u"WrTzפxV|*Kô$YbJBš /p ,pdi+q zUQ`d'\ZͿukZ7+" xnͿu{D ^`콩IyaĬ3W1d~si_ʘqd&p2\#|>L1|C0tD1ɶdNtDTOo\y~҃(s9<ٸS7*gPD.9xp.^-Yc:4 KT!̷Nm ok5$%0)um;FFS/QTr%NM;%'\T8La9!tE;"2!2Rc>{*9JHtKcJzȕ}.-k]kMp>if27Tn`[o8-\kmMKK8Yȱq>r,KG-{"kF1HaPr:GbpڨdLtDTOo\y~Յ)p8R*ۻV񱮒/jvllQ+sV,w18 |UM.ʫߦ\r:Jy 1\kxSCe`+DAcsLmuu;? ;Qz)?\C,=oj4J.fb 2`8n @%KnaŖ½3%BWo(4NJ'd'2uV7SB;cjNXNO9nq5>>8d:Bp[؅;b]&'os y]ac^0u~so]T?H-|vA7ex,y&nk\_!^rYi K1j5 6 +JM T ʠjrq#$&HD'^Hڒῤ疜T4% %ȹΛΛ<* 9 p"ҭ,re[ w$,\uLv7gV̖qu!4/&vbhOvfyj_wϷFux4kF.r}jendstream endobj 12 0 obj 3203 endobj 15 0 obj << /Type /Page /Parent 3 0 R /Contents 16 0 R /Resources 18 0 R /Annots 19 0 R /MediaBox [0 0 612 792] >> endobj 18 0 obj << /ColorSpace << /PCSp 5 0 R /CSp /DeviceRGB /CSpg /DeviceGray >> /ExtGState << /GSa 4 0 R >> /Pattern << >> /Font << /F8 8 0 R /F7 7 0 R /F9 9 0 R /F10 10 0 R >> /XObject << >> >> endobj 19 0 obj [ ] endobj 16 0 obj << /Length 17 0 R /Filter /FlateDecode >> stream x\Mo6W\@d P H=Ybh"ے28 'Z$3Ù73~[y|L7E%HV[ް^Os\wsw5\[\~=Tn?Ot%^\/.~ffuCI'U%Օ7em 4a/RVߐB2j{70ڷpBf{kaiA5ږi0Ms-oE1kWQCq$ˇ?(UT(-jHpV0WVjOmo\`O{EAKݴ(ᶳ:27OeS+#@MK=0I}dmB$r&Qzdl۵|hZ՘i*5ӆWzVJ!mhKCܡkFttQcNIuL8']\0I0v#ֆO98 cN܂i 3R0C#6fSк/廀G>3_F0k3w69\<1y>0{i+:DjTMoSoNLX06%LVuAl)`LJj9aAL7rD6b`LLSuuA0X> znsǹ~ڧ_p -5lѰ;vf _ePV~JI*tcVr͐G& 2@}T\2Є fJM0wfS"&D2)4\''݇Mr)ʋx=:'GGFc$7]%A\)pQ.pd?XNG*QF݆Θ?JOp`>6Z5f6$e*Vrٚ4m.{9l,)%R2?"64P4LЋȨ=կ])NJ>4lv2#-ݤEVfz|PN0$#aCϳKm5140KsBQ}xw'f0/1'k;u7B[ėsJY @2rDWgJHڤF]5,Z7Q\I7< `~ '<GwÉcR %b#vSweppk\VqNgqt :Cĉ0V?} a,9N ʰ?\Xlg+qPs{5X~ΡΛ,=YoXoyZ< ϒ,s9 v 8Ebq9ad\a3IfPMऐxdNB{pUNa;bGtozy5\%oNɃ2p8/08:I̔<^݀ȦՏ$6,Q:oNL"wouS_[iendstream endobj 17 0 obj 1743 endobj 20 0 obj << /Type /FontDescriptor /FontName /QUAAAA+DejaVuSerif-Bold /Flags 4 /FontBBox [-835.937500 -389.160156 1795.89843 1234.86328 ] /ItalicAngle 0 /Ascent 938.964843 /Descent -235.839843 /CapHeight 938.964843 /StemV 43.9453125 /FontFile2 21 0 R >> endobj 21 0 obj << /Length1 12048 /Length 24 0 R /Filter /FlateDecode >> stream xZ t[}>Ǽ|D,4ٖmYr$َiJr-]Y7teݫ8ԥRqB!ene==te([S#н8t wWLȡۙKߧ ZAfᎮ鿿nXy~'f}rb@hgF#IXM?ߜH̿LR ڼ `9%̠h3U| x–EȊ(BcU7]ɶlYM&t19_kA$7#rm9C4L(-Y3e B5mhk[|7U묭 ľo Z@cëmn4wۚ;M]a|]w?cgyL>;ySi :.n҂> :*Vck4\ukus҉7'4PS_ĞF2sr!_{-x6|K=x,'FB{]PCɮ=t'[wûvRצ釅@~׮-rlv86vv똼nE`ͨ,-Ow ir=n輞 $Njԙ){Ҟۺlߖ;fs|Z{XeXtV~1چęgnߍ/lۺ}^-'X^x][.|;s!w>r S@]tmXos1iL ,Gc;Lh:AhAvC]S6=ݖ#͹7{ Zy.s Sm{x߱ cJ\s[.1񷿎'gA %kUFGE1o9ϟoKz:_r¢ٰNOMZ-=;^ß~}nC69gS1؞un[Ҋ!Qk痖ZËyV(&$ay ]ICPL(K:=mZaö+CO9-u8'OGM_^3@F&UC|1vXZ-ڴ7xx.%Mio(]߹0֛?;f/ JC?ЂNT㶃[7<~#OODV7>w=YWS c,^3->?~T{ha}{ASxE>ݫ A1_3_ium~KkNԻzuB}n 増4pۃlr+`,|s7᷾~x7WkoZݔJp*_l>~ ~C~Q]=ٽ|1핇PxfN-N?}׺ڳFpK䦮n+9uMX +֠`t}Ul0kyEVY/ՙIӈTQ0OjJɳ~Dk>}?gkm۩ N|d陈ܽ}[8Ȏǿamloj}W!`HqQ[,uCJזCs&2m֩CxՅs]xe f{lŕ7AԻXM7t+iOBzYwjo}47 kZM ;!biE.P@D-.+~>LgV {;͜G9wM$yc{#-mdʅ}nM&uwímKK؊mZo -SυCxr_MNp[ E/ѭ>Wx/w7-G}מxUkv· g^՞=`weΞ(D|E|󊼂Nk"X:w{8t3½ dgavc-лɵ Lq{p,)c=g͞лǎ;_ڿNp?p8Cq<0jsabpNg%vUe5nRf/<}B B*Hzk ]_<h;1..\4O,6ŷ3:"+ѐE̵h 1 >YOk__@-=o} -=m6! fTc VJ>^L;x%||UW?5#됅Fl6N]  C+ ePef B*tV'p{nMA@"~HDJ!P0$ e)l&§<=hFAEh2( |Ri+~ l9J3 FHצMd:O%UQr_:$d(BB"f1g_ȑhBHψ "$NJQSÆ$dH.\NJwN$IRxIt{h&}9{LS߰'.[G,*Dm3W82+g")2yYs'%T5#B䜊FŸi,0rKsѼYऌ恖fNL]VF6_Zk?wyK>KE),~8~vDdtG2@N6Sh*J3>KJbv #gR㥘XIFmWyWtK)gq~Q-:^9"0>ã+] Qo|-[C=z:Q>Ч0h9 .oIj\d|ezw ٗk(4y+"0ϼ1~2碽w57N]{Y:gYex=82 9+:/Xgm|$X'S6,?_tt7Ǩ*^UR\y ?l*M'FEo$9*%fXF ~.^MQ/"5LO`FaAp =υ`gf:a;tΪqTb3YSSBe6@Y׋v3^f!&{VtcVaNÈFu}ڡ|VZc Fa#|}L@!naD%S`8|]a>Ce-1M)jpJ3֝lU,ȣL%)Nn9Ë0#a|C;Lh1ƙCig{EH*ËƍZ>4y"e=1UFg04 3 )?^W|1_8L=;|Z<< J/ #e(:ȲRT&Y-z:\Da(|,Ì8 -ר#Jz.]AO~na{ε(v]~{,J^[~л0MUѕVY> /FontDescriptor 20 0 R /CIDToGIDMap /Identity /W [0 [595 770 721 458 662 1050 643 377 604 345 698 694 631 377 558 591 366 716 694 523 576 937 694 756 694 721 746 694 ] ] >> endobj 23 0 obj << /Length 553 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <001B> [<0041> <0075> <0074> <006F> <006D> <0061> <0069> <0063> <0020> <004C> <0062> <0065> <006C> <0073> <0078> <003A> <0053> <0070> <0072> <0079> <0048> <0067> <0045> <0071> <006E> <0050> <0064> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 7 0 obj << /Type /Font /Subtype /Type0 /BaseFont /DejaVuSerif-Bold /Encoding /Identity-H /DescendantFonts [22 0 R] /ToUnicode 23 0 R>> endobj 25 0 obj << /Type /FontDescriptor /FontName /QZAAAA+DejaVuSans /Flags 4 /FontBBox [-1020.50781 -415.039062 1680.66406 1166.50390 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 928.222656 /StemV 43.9453125 /FontFile2 26 0 R >> endobj 26 0 obj << /Length1 19056 /Length 29 0 R /Filter /FlateDecode >> stream x[ tՙw$ 8ql'N$;p NQlٖ%#v x,,ŒFЄGi@iK,1RJ$ǡ@SNna)t<$a;$!e[w|s-#nG&<ںc4~á{+0wKb0D `nI&]Mއf%gx3pGr@F?Iv 4#4 i\IG:v5/B dYn 3LŜ`~ՌGwpB!G-Gtt4S+{(l7,O,([QR2鲓d_чJsEbVUmVsxѣzVP 4FK*m%UYEȼDGaFcUQRURQd #[`z0yU//s'J#T<ۼ-% KʁyUEEa>8zo{&׷mߵzn2mmi#J$zkz,vaml}6T/4MeZ\@Y i᢮xUY\TltЏ#R/YvG9WL֬y/مexLo?K__gN<lcr{5pU w٬R_ pa|k)dɁ=zK>/n hmmO/ՁoBW{v~Lp^5^gǍ7l%]y}A\kgO"~u9fVUf@%L6mz`uˮ;Z ~]Nm̄GX7 Mwټ RT3@z^ 8GPzt[w]ێn{p-MPɤzsǎ{ܱ ];L\cLв Q!̈́A<7d7'ӟ͛-2ؚ~bKuc [ [A+Ai6uCh]|4} M,"gm_.޽׭ew!|X^{o]s_ׯl6ۆkbc$?흱.q#ҲʙuU%rSe9r]Xr@@x%ϮNO6ahtqǯ0 Vѷ+Ab9Ƕ#p YT=e_~de8gU J{:oY†O<Z\~=P{P #;%Ӂ/V5+wñ6Z7m +W5'rpronݙ2uEf&u\.7ӪyWk,/mza1~~^lhQh+\Vm*PPP]dƯsƛ<9hM#nwnN(oX:v#TTH_bm&U&SU?sOͼq>FӷLakټּݼiՖf*#*ȸK1濁1FSX@f|LTLaܨ-W!"ܥJOEMf윿Z_ZڧKKy@"6C\E\:cTcMcg ؂.Zq*bx SQ>6E}|! 7~_%h@MHF 4A(“d-:^6E+&TQDCVu8Ȏț+ %X3@I&!uIV$ &L|20Z Q (@+rn_!r(pQX/t#5ɉa%Nn"+"I5HbJ@ G˨TTI5d%l_t>fi؝T**i"hP8hVh´'b#LF2G0pCRԈu5Ņ0HVs|#ΐQGIZ#<Ԃ4'%O>Ad2X[UN))$+RM\-y1bl`XIâ0Ʊ9'P+'hhW^ߦߵo'ݺr^Νa83M_.x:mִusZfkyBӨ ;A6h&ɯSZ=|=z=4^fKMwVa}c_#vZ97htq1lyb~c7sIvoBK nޙ(:HVB+rqjzgvFG'IZŽPv&CnnOOg'rs,ߚeE9^Z_)nIS'@;d&ezgKl1Ox }`2Q琏П"aO|d<0ahn1^Eֈƞ*0 4r Lqٟ:3y)8y}zAd zσȤ΃ ;@Nrr'\;W"w;ayD v\Ly8W"+,:?J4\OzӹS& NvD8kmL숌;;9Q ?;"t|?ݳ#zGC'\:vf'>$t&9r;i \A@}T}-8:_$'E5tlDXXBVR9F4̐?H>H/nIZx~ۛG4A)&*TBH"*\DaI@V"t+f2@L闬4)S1>L/ E@iɰdȱ3dR\*9$ Y*""#A9Id"Qp|Ƒ/>9+pM)T@l0,җJJLR nDSAP$SIP&1 %M@̱ҘĬ&<@԰5OɬJcD3m$t\PkPJ@/ TTMI6 Q6fP@#?A[EW q9 nPYD.{T (t@ N9qИHM )$M»1q# 41Ѓ0AnKPQRQQ!LPPR#qFE&*[a裎X3z丁z09a(XN*H bNR!Y 2LqT䐁g\zIIk |0#YŤI*&^b_Tb74ہ3SbE8JLX;HSpNU•, a'JopP R"+Dfd(L-0&k{U(U,8J1 Ԭ E0D`ɐIB1b fȭ6,`RrA_RA):\ ˸&xHVb@h3I"+5qu4y87} z&}A 2ҋ|sR=c5װ镨+GD4?|jz%r{%J/8^WH^P$UDvUD ύe"quDiDyDƶLLZ&2aD?IDvSvFY~61#z6uGdMwĂ Q9eC?ACNI4>7>74I~9oH ՜ sggAWaX;FXIz<_=endstream endobj 29 0 obj 6643 endobj 27 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /DejaVuSans /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 25 0 R /CIDToGIDMap /Identity /W [0 [595 315 387 387 606 276 966 610 517 689 607 389 608 629 334 293 630 587 742 629 630 408 598 811 630 630 545 276 764 587 679 746 521 631 315 571 630 ] ] >> endobj 28 0 obj << /Length 616 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <0024> [<0020> <005B> <005D> <0054> <0069> <006D> <0065> <0073> <0052> <006F> <0074> <0061> <006E> <002F> <0049> <0064> <0078> <004E> <0075> <0062> <0072> <0050> <0077> <0053> <0070> <0063> <006C> <0044> <0079> <0056> <0048> <007A> <0032> <002E> <0046> <0071> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 10 0 obj << /Type /Font /Subtype /Type0 /BaseFont /DejaVuSans /Encoding /Identity-H /DescendantFonts [27 0 R] /ToUnicode 28 0 R>> endobj 30 0 obj << /Type /FontDescriptor /FontName /QEBAAA+DejaVuSerif /Flags 4 /FontBBox [-769.531250 -346.679687 1679.19921 1242.18750 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 928.222656 /StemV 43.9453125 /FontFile2 31 0 R >> endobj 31 0 obj << /Length1 13480 /Length 34 0 R /Filter /FlateDecode >> stream xZ |Tՙ?#Q!dI H A$̄Ixnfd3;C@Q[ R- *VYm (Z_RڪRZlWZ 7sϝG=|8߽at+ t/0~"5W wQ{- ss0qyeS ZeW[p:*K٨pDŽដW~)BS?#BzW8sW"^qw7B8[ED|h!GGx OAh*_~P+ @ZQyr4W{W~+AMMc Ш+ʋK]dzql?~z w:;1ҞOF.B?4 6FUUzrٳfG~qݲv'6^?xŊwt C#&3J(ġZU!b8m֊JdrYi}i^_WW@W ss-^Ƞ߰v0rɿvۯmwv&ư,هzVkR\I[shrU7 g44ʊPDn(/70H[M׬Yjh"˳xㆣ=.߶/ڼ 㶖m5ϟ[G \\vnDcCg<4η',opͷEm@)^!4H&M@` ױhQ}u`~ߩ-[n{7ctw;F1IAe7&+SrJeD npՒZw/p. =mw'\&(8oL,44F~UTU^¾ڄ(-8D<y D %޽oO`(DB`˭ѝ@f)x8U\Y^;X[^ѾCgUVTTΪ-4L1  b{YI%ReO pI!mK= wqаg*oHgӍ7͚u76I5Ϋ5.=kɿ򪴬}F1\z$=j|SK-KټPJZ0$!KB5j6fS ,-Rhǵ᥍6l|i3Gٷlikmm۲F+yWgx3g3{B8OOf6>NBʈ|m 3 m_sˑC5 g9OCEwC%=6s╆[fͮsVW | `=[NjOXLύ5 c~1|/ОՄ,[I|pB`5o*GG>;rׅީ%>.trN"L1rɈVg-{>9oby\Wǎg(o/GZWã'i9nȯ7cj^0ͨa p:Ѻ |in <;<̵ b A0TbQe1Ǔ#>>4JuRiHC+,r `3 %cbZܜP0ûs#y9A5? j0 &jB73MVY?,Kyt b_Z57ͩ_zZji=h &vW0hszUy,ڋiJ9;:8BS=zC{afa(>ۿ{U.TƚY̿Q0rn {9. l؈!>ylmzH>Ӈ؇?CxHp6*I7Q4 M*oZ,֡O+ý#/xC؇'6q _p=5rz?J誁? seKygz)mj 5p׏v ө?v\L]psRJ~aˢ˧}^< =OQe9T:nځNQ_\ӹ}iՅ/j/@,2%a95G#{U+iZtSUWcӍ3$xz劉:x _HLVB3<|\q |`|7{~7 #LդQ zj4J+L9IܾY.#[t76qwpXM^ R֌A r*m\[]UZផ|g!0+wIsD?Ԉi-ܽ/?u+v/vѓ= 8S1cNޤnk笯by֯aP |YPgIA"P * ۅ]<ĉTٹc+xxvyX8|z1^΢;4z4"~\$G|^Onu E| 94!D4 9!6JmBN-Gr~ʛB{&75|EZ֧W ]Ϊ 6v^םW7Ev*RT|"#%G;ksu@8xt!uR~Q- ]]}TJFU1#MmWj,e qbҨPl2U)E~^@`UZ]$%9QRA=GUzyaSb Q\RtEH 8'|AJG-HX]Ue|%/h\Lh hMH1dt."2/*mCCw8J:6|.񔳒 C5ZEN6ԘZ4@^5ƘbD&2 JShr8ª!/4;=l2d}[_ b@b ѪE,TonTr3gk~\/R`ykȘԅL3Gii.bUOQ4%r|uE(x@_4X`sɜ*QbW1 mʭqšx:#t_U=*HUgLdy3Y<0@㜋 [mJ9gzistM|P=V &u(@+ّE gLVz^%H#EnNVӔ*PsYVOfQdz$ۑ1A#: }cʹ؎?/*[r$EVdrwD3I%45"=CEF4RIf{\KTn/:T ->ERG33J<کS{%&sеPgT)3. %CY+ٷ%̻4Ge E2S_3(4`wD.Όfy]LPx=h4tgbJ;L?slWrjmn'TJCUrfeyr{N.)Yݯ}([y6~}OWzA)ӕ(G<ә 왮< F)ED*َR&NO z+R8:b_ђ[<'e1!(oc>­C }9Ǖ7iDf!BeyEI^sf^o3$Q{H|_ Mcaavsxs5j ~ W~ ȧO 0RX)&AꀘAV_RD'x'DBlOI 6{S`p0R4LD^SzTHbL+($5 zQ1RD0 IRL$㾴Wl|A0,؛NT 7M@<eA&'(mZzbj_)`ȑa 2kI^@UcDmbQAx t2E祸ҽ!ћ"3 Ib7RcaZZDU x )+l(k^j@ yvcI>Oͧ_AFEը0HG㾠?HM `LZ@GKH^鈐|Q5"D6D";T}) c}.Yb,2BLJ俀SZ27jwb@#_?h-[K;G}gF0CA(댉@/k࡟endstream endobj 34 0 obj 6763 endobj 32 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /DejaVuSerif /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 30 0 R /CIDToGIDMap /Identity /W [0 [595 662 639 587 315 635 597 591 317 317 509 399 560 639 941 556 635 315 474 635 716 335 639 315 392 849 635 560 308 387 387 334 662 273 635 367 655 559 836 868 729 706 795 680 667 759 ] ] >> endobj 33 0 obj << /Length 679 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <002D> [<0054> <0068> <0065> <0020> <0067> <006F> <0061> <006C> <0069> <0073> <0074> <0076> <0075> <006D> <0063> <0062> <002C> <0072> <0064> <0056> <002D> <006E> <002E> <0049> <0077> <0070> <0079> <006A> <0028> <0029> <002F> <0027> <0071> <0066> <0059> <0078> <0055> <004E> <0042> <0058> <0044> <0053> <0050> <0043> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 8 0 obj << /Type /Font /Subtype /Type0 /BaseFont /DejaVuSerif /Encoding /Identity-H /DescendantFonts [32 0 R] /ToUnicode 33 0 R>> endobj 35 0 obj << /Type /FontDescriptor /FontName /QJBAAA+DejaVuSansMono /Flags 4 /FontBBox [-557.617187 -374.511718 717.773437 1041.50390 ] /ItalicAngle 0 /Ascent 928.222656 /Descent -235.839843 /CapHeight 928.222656 /StemV 43.9453125 /FontFile2 36 0 R >> endobj 36 0 obj << /Length1 10096 /Length 39 0 R /Filter /FlateDecode >> stream xZl}GQĎ[V[XLdIkȓD"ڳ}ŋ;(YI휶Hs4FvƐ?"4+3em}/+n|L 3/{f=MQsSigxtL: OJ {fNXFXRNIO55vC$ҟv?*!'w{$yϣGVy=/OzHd*/䳄޿[W]'](I?;E;wU!7+;YT_w_K KRFǚm'9B{ %GKۖ{꭫ץ թ{zlw[zFzw{:|kn#Þ [q3t3Kŷ_D/F#^F6HM+7᯺X77qCm4/WUty7xO^f`:c[|-ֵ=~I_Hϔ&u7ƏY{g̞s}!{-##C#׿uhX8814 {幱ϟNKҁWx_w_3ӓ'ON?bN9TwgPt9?)iNk]RgM۰aϵukmS^ 앺t~ awҞYy\vmw&Ly1+=Ʃg|WFzb_O`HwP_'/]gmiGkտpgv Hө `F}#d518N"{RiɐJ׮yO-.\hD(Tgg:um2b9" J`Bc9(:v륩Pp%ť[RaF{B&V$YvTުxz⪴]~9o_>7nѱ<۾3|>P/Nf۸i}UކLADbZ/S߳WRϔl!nTԙPN/>v\ϟ o2lX!;H\$?VCNI=4jXM[5KKcJ(m0bU1n'I?cYY-ƫHb(yYW?r}n6{*)-m0c/LǤG6J)ƫ߳Q%{=)1^vx )l.1I,dC(\9.x ( Clx[D# )ƈA!"ENհl[=d'@!ȁ((Ia)Y, Ga z\$$b-}mt`׮A]c;4f4\,iJ5k^SQeBsŘlX ZdzfI P4<Iabt4`fM2ӜHa z eA]T<:".io8;$/U`FmA$5ij0A`)8Nyo(|%h+MkV ,50pss05 ,,cܹf FNx16‹́zuLqaM!^ yͱ fQY"NW6ame"CEp &:":f%'XC@RUds=)\E.Քm}h0nk¾DօWծ8r-[(=S a֠QO#πDLcEt#C*2ӽXKD;C=;;tQ v[+u5}mVD 4 "%\SE&Odƿէc-qwD3)Ƭs/( s-R)YcĜCVjScS2L-`e&Zǀ{+tuKt pnݴ"wZS*95[w0y7dx9ź7VD=U}i4]?ZmGc9+-8jQ/ܺz8[T*m\c ?j=3^unE;b;˘s9+"E}zѱ>تG&z$WLO20Op-sR2WQb\¸Xad8F >Qa!O+#C4J{f- 9#3pݍr} ؕa4uͬbe6 W)a!@OqsL0 2Ì8^i436s a ֹ-22"=8 )#$h!'C8˙%Eٸ=G4QXmc mrL<' ލ,OVYT}lƿn@X|F|V~BD7RuAZQ*N׼0;)O7difu=LXF1aKs-wZn>w^x'8ʖZ과?3nwQݯ^Юݕìݙ,jLK({Fܲъ/[`e =ײcGܙ0*B?jUa1pm0[MdPZ}V Ujz=^z|0\OҘNBa{ɞ֞mѬV4C< vv7hB9rk:;?YڢYԱU+)5(SUm| @׬haljT1iYl`f0X7fAKH3IJ.g 4%RŶ͜>`R Gq^ocͼ>oG&VLF0=[q4д!Q+*c;.1y`+63s_h`:CEm :P淨fסYzp CbPÍIm3@J-"$3(gvvf`IɚZ Ԓ0gYT k.(`TV^Jyaђii˚MŲW@Qj^-) dz^gH=h9w/^b"UYimbf;\>v&q*wRlh\.uDhޔ`efdqKDӸ _E?.P?+]? 5ՠj71UCrJL55/* o+~nJ"l  B@e%7̂aPYXMiEg&d:Ldh:99N4SL,*G?ke& p"s&h8q%*J4Mhlr*a.ħ8}dc fU@4S e s @t*"pNMi0%RE$bldfR<N 0I09EQ$,3lsz"X&II&˼3HN2M'L,2˜c Ot] 6 9hzJKɑ JqI&0r Ȅ*0Afh~e8d*Sr84Txf4/!na`T0h< %ie(nMRx܀s8|“wzq#9 /kpkmJ>LLt+)=[)2U~a]\PXtز`4T`ҟG%V Vfbd-v!țVI9{YWpӚ _ECx<9<.F0oC -szHvx:X.C'%endstream endobj 39 0 obj 4520 endobj 37 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /DejaVuSansMono /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 35 0 R /CIDToGIDMap /Identity /DW 597 >> endobj 38 0 obj << /Length 448 >> stream /CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> endcodespacerange 2 beginbfrange <0000> <0000> <0000> <0001> <000C> [<003C> <0051> <0075> <0061> <006E> <0074> <0069> <0079> <003E> <0055> <0073> <0071> ] endbfrange endcmap CMapName currentdict /CMap defineresource pop end end endstream endobj 9 0 obj << /Type /Font /Subtype /Type0 /BaseFont /DejaVuSansMono /Encoding /Identity-H /DescendantFonts [37 0 R] /ToUnicode 38 0 R>> endobj 3 0 obj << /Type /Pages /Kids [ 6 0 R 15 0 R ] /Count 2 /ProcSet [/PDF /Text /ImageB /ImageC] >> endobj xref 0 40 0000000000 65535 f 0000000009 00000 n 0000000296 00000 n 0000035768 00000 n 0000000345 00000 n 0000000440 00000 n 0000000477 00000 n 0000013305 00000 n 0000029885 00000 n 0000035628 00000 n 0000021487 00000 n 0000000816 00000 n 0000004094 00000 n 0000000598 00000 n 0000000796 00000 n 0000004115 00000 n 0000004455 00000 n 0000006273 00000 n 0000004237 00000 n 0000004435 00000 n 0000006294 00000 n 0000006560 00000 n 0000012372 00000 n 0000012701 00000 n 0000012351 00000 n 0000013447 00000 n 0000013707 00000 n 0000020462 00000 n 0000020820 00000 n 0000020441 00000 n 0000021624 00000 n 0000021885 00000 n 0000028760 00000 n 0000029155 00000 n 0000028739 00000 n 0000030022 00000 n 0000030286 00000 n 0000034918 00000 n 0000035129 00000 n 0000034897 00000 n trailer << /Size 40 /Info 1 0 R /Root 2 0 R >> startxref 35873 %%EOF kst-2.0.3/devel-docs/Kst2Specs/Fonts.pdf000644 001750 001750 00000573243 11544160206 020340 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream xZɮ6߯:uHÀE\ wIEM~ : gKuN9 '`~=a]q;|r~dXp2Ӟ7D2\N8v??_?6`ẽٟg?yɈK7~^ލǴ4ӑ7嶴CɃ>)Msy:$i}hx!dlV7-?GZ%ӵh |~m,$ Vc΄P OZi%~_G tAD:-ܬ a"Bs cY`ERLK"YY[IpgKDnL C`9 $?/:``HѓHcrw1ztAWU)>+^H Cm^0ƒ?f tk tah^PyoZzf]OU.F$n1#imupCKQ0|ݘNMrSĤ(DaK7ԣ#ٷJaA5+j_"R @CƧ~n]]jƍF!R7IW0 l.9~ڒ5{'$]ۛ7)BsZ2g!<'Jƶ!@)\,kWo0W %lڼXPɹ?wznu`Y:-U/K*yd 4*qYMxI/&荦ӌֻճՀGy#Kmttƀ&A.#v>j.Ve qCW+e0eXZJHUv:ApMZ%? Q)7Rpfb +na08>Pmmmt)>E[BUĕ^aJ8dַzmyX=ݰzaCYi6u&5rR.T D<뻹Xcc lYki5tf')G?޴4_Es'AיRvob"^yP i,^g%eMPcƵK)CA+nSиyruWE&}Oiw5S+AkƺK u VVw>?R ՅHy_aMes}t%xNr[Zlǻ8-vX[@74J} <(]B<:~#~??mD 3 S 'sch:z,"pTDyA,OvCI$*!b6>}T dxNouIw"YqP [ĢAũ^T4Ղ(4L)d(4:*|2g@)pPIi13KHNjCKրBY 32}ޏYGN?O޳}> stream xoUƿ;c;iMLEitATAR*5(R$:iy:l@bú=ڗ?gm:>~ cm/z+iow۪`h|ʮYW22svҷ<5htG N*҇Y<+yyxX* t[jr嗪j(5-6ZB|S'rX|{bBy~Ϙ|őbg3 )n34klo<_FV08ApyQ|=33)xg4\Y&i.\:D;e@ML/4g 4σ7cW5ӚM\&śE]3+M<' 쎈-Y/5j6+# h4 T fmE65_R q'N=w1TR[ KVءb'emVu]YA+¶ce%iE5-Pȹf$X|;aX&< MT,ũr|J55n+5$s4PߊwȳRS;Lz$JR>T 2t|w]\SHB(O)r+ \YU/iR|^X1:'P8ϸ9^>#:R=-fpaq^| z"vhesט^Zȼ=iG|4 endstream endobj 8 0 obj 865 endobj 9 0 obj <> endobj 10 0 obj <> stream x]Ak0s=,Q7eC? & I1k[!Mt=u~`{L0zrKX" 8yRetD%Z7] Nm/_c)Arϳ/fFKix"Buyb%lhBUE($;a%YJzht~ڀ]I=WCܩm endstream endobj 11 0 obj <> endobj 12 0 obj <> stream xܼy|ŵ/^U=ݳfz4ffFȲF7YHƛd[X;, 00Vb,V l`$$|C'qHrmͼS=1Vw-UW=S~ ҡ! y+{V^Bؼju_t!~!ڿm B]qSF[2:Z5+WVg#BkF!C:n\l\] }bU+@zO=BfCZfksHG(}}k[Be‘h,^Hҙlm] <<<)?.-Bҕ哌.Pt7 Ӹ4u,.ڇ h ~(fgQA3sh-G$v[l紡~dG'plGwUԊ^l xq@C8TޏfC#dBQ }ѕsPŷOP<;\ MA/p;:}a&v@e1ZO* J|'iۃ$ASѥh%}-%]$ʑ@s 5${~?rC&Эo@E/q@m9P-s;n=8~y˖Zֲrՠn(n 5qu_/\G'OzwVlPQ#Mh3 g|w7n#({'\}74{&,W4KexމcQ Ɍ20a9O#7Bm,zm8SE)dl$2w0;sܝOKgÈ)p=zjOe+AG!L)0әLsv}7[ɽ,]Si|;(rEQQZ| [W0>*z Zyj;/m;9H5l1ROZH+I֑;`{ / sE,˖:fsws{U1~6s5=-Pʋ[aBi(v(.a{$>`/́;q! ւg9u-m ^ J|^61%i%*W8k䗨lɛmmWP{IIbAVo'M?!ݨsgp s {&HO5~!r9)q'ԏD2>!eyD5JLߏ9A=8Bl&N0%݄9+k@ Q6@:Dޟ)}"6>w7ٓL]@7~[7աABY+z ]69rKL,ԇh~yoُ5h}y# w<3|Ӳ,L͹~4љ̀jZk4$گBT QG?vLJ8ښ$PQWp-(n[zk~w O ГJU+FQQcB*Uk k{DtE_B:zQfe})1$<ڽf͹A cOJMjo0NFt#k.Sb4~مzŴD9 * Joj5hxU#\ w0n _ra1( A?rUXQ*% Ο&55T@VhQ(4%]H%7`(AՇnW4eڼw Hﮤ%t3QG?ƶ:}AC7b"Ҷi/Tη/_- Mm/*/ Q6 55'wn\xfmClP5(㨥JxQ /<&uYlX1^Vr4sT]9hǛʧ]Jm4ڔrzʗ_*nҾpKfX  J3WJbp(tow{Fg7Ӷ`ϘG >F '@;F{AFcTܫp Ǒ_/G΄yD掉fqjSxNb9tq?ɍcC7˽9VpVV ~ T;s@PA,8]~aH8)0eg.O`VDž#C& 7ĥށ4'WM$¶@!WƔF`yduqXvaĩ,i]q5R"k.S{@Sm-4}(җ?+ BZvv^js}wWnܩԯЭɩ6gm3=e1쑽B-t!iߵ}hz~c39)."U@X Y,xȂEZ[NXNZT> ;hAƢ[qqj gTK3)lrbm ^4-hsu 9*XLB}}C}{X`)zõ)G}]*bYoY|هjW']Ib6em1c!Nkbx_?7SscX{ѿcx#FB$?b? ~$5${פ&wd'3dry;R;z#6 ֩[o/c*WܓܥޥyL?xHkNcɹ܊܍w }|ŅZzgÉv˦MO^ӓfs(ײƨp>Ԃkx.s)[_ج%?2cl~7aO&0Xem#F8eWJ,$wGq_?:eh6J/Ӭv~*gʼnށ)f1DQ)8?2N8n2;ZeM( V^ݐNo8ٙA,ĕhmuhR~SUq$E|bHD+PY}\t6A 4ӵ&G#gĻ7`"i3Lcǒ\o|lI:*bYS${hnd:gn1H|STW14V:XI,sYF3 0sZ62c=}i٬؝&eGbS0 Vlvt ਗ਼rvv|$:d$aŒ}rCxmoSnșDWz+cUuOƳw~⒁GFcz0 L\S4PH#;xD#Pƾ~%7bIp}1(Sq_tn&q_d1`!f`)ZPU壑$j\ΐzDG5بּa5c9BPڟJSPj$EFSԉkxfh6Q )4ſ ?Ur./7_ ,R90; bJc{NPTraܱ/X \f4FʹRԠim6sN\qS,x)|g{y Y4ߘ`}ʧFT6 VQZeVٗw?~[vmos1xGXКY* 2Oc#(b?pR],qZ؂vp;st㈅_>f XOO<% TWÆ {#*b2Z%Rj9yY= lZ\&+x1t=^u&M; &7jh*z`*:ڃST4Q4+t֫6ݛmтU[7b=}熞[-OV{w>QmyoRmGl^ofgK[t`(6\%6٢A0 UU`h5Zm|ulx7~X2,#2Q C4 D^vH4w3^ j.(Bk4yn/MʋWրPkppyzRSoiHzf=-ۋK&~{x}蒞{uxl~/m aϩ"P6K#r|efrSqJ;Ww9r9#=p!8SE֨~gaCWiu.Lɏpu#=:Nw~4*hddnSi!_B]Ywc&l=;}qcU(n^ȏR}FWQ l֬|D:ߗf223ECg}\.{~*wֹyA!'~)by%{YM:Qݖ+K;;דߘg)8#0"};-qP4Ĝ1lZ=*Arj iiͧP鑤@ 0 }M *}6F1{H0ZR'L |DɆ |3z8զ/XQ@I_pgy5U9|jZlb p/S|oʍ|m6c9_8=Ya[MKKfʄjkQ5 Ph$'t:I!DA.M0i;en>3uM|:2ª"B:b֌PYm-0R`.})'N"7Gˉi'<"*}+xH|@*?h)t]~1z>kLirvz5Q>7fV^zfJ)0!-.zFW>\a4y.H}bs~µ5< RwpkY.ݞn/ !ϛ $=nb"`ϻ96k18O}5OS`5/1[ & PX_>yU! *җ T}`mՇFlg*, Fs~NNpU3""~4FqtiA_Mx0UDʪdjn=J*8H(`yvRکOh={jy!$:i#"'ELEH,Jjx ru{z"RXiC}37m߮MNS?KxaՇcΎH&bͽɧζPSgv@[סdIzlšgG49aފDwk.&eU{qTmR[&eG15ss Ms.Ѯޡ]sָ~[V>!x* { ǏX KGd8I 6X]b\[tpnr26'qf4'P dʋզp/rz.ՅEVCHçd(H+4}\'SeCQ⻀*0"O|k{ǴxBÉ͠L@lTT=^3u4U rFR R5QE ,^dz/N^(%\k^ы phR5{PBGyKA<v[5o15dCi10Q  t48)kEN-zi[[@c5hPBAa_*0 8_Ԕ(b-l Lz]f_ϖ,h GH&Ό)^auMdōnꕭ3n\ڱ:ٔ˧$(}+on|hٕ+^AǶf2-{f{Ñ] J QU-- 65\_ݹ0xйs=rrN.;l9`/ s[<z jŪ@ ajZewx_0OȆr•zyd.+C\17ˊcX8"TZqS+\s5r HLjS'Ǝ2YHN17ewfwglfa h9ǎNҲ2yn®v>4Ϭh﷿ Ėz]-6t1BAWUGNfe/0ip&'C)1141{  :J0ى(m3MР <3K 0LTuN1 +MKBoÉH6WeT#t&8ЋS|^^%EBS/JuxeŋKx&\ΕpBLZ%f/43ߋKU^qG]:ޫ).k"@A4S?<فԿ tN NEvQM W&;; xm}' cxzƬ?dj+?ZS_OmyWJdVr\K̩S:b&gNl`}K%UZr}MO,dK/9\w8mvngU hy =%od#uFƯ\W`?զqg0G|H1Y%!D0   5B~_C҈D$JqB/wMPXxQ0t}"6_/@(P^W8- ٖZL+%fV4>G5OZ6kҜyQO(AS^g:oA \%O[eaf03t]w0wGYIm FnєZTҝM-gxLGGnIϘy U'C،+;{Tb]%]<.`@ln9~UNmLG4amH7^QmJֳEl15FZb|iS4͉̋Ůᮦmm666ǃnqiXgdLEɟkLFlZ^ZFNb4/h:]ΩQ+/sy=c¦N몶|ؗ o n t1K<un-aχ ak٣lNgt@j# &0<_0lL&mIM& <͂H|*n d4LAɅ]TbtbAvNNXqhλzC<^w/͆o} !C @.^X٢->)jxI Dgn!A([44-C GC=5G1#}#bX25ԋ2.Qz%wG$ D{s@"| v ޭh,)&e[BmE{%0SgFO[^cYk1IŸlV;A;}߿rT=zY؀nwT\Thw{x Oo]E[O-],u\gR_<ǿ=wT恰ׯ_UÌzpoilK- Y Go,39$U7mlה^-=Q;\'\#e1:-dmC6Y70S\U&v+39*CRB5@au;K/$wvYj)W;+V j: ĒOWݡ"j5g\[#9$qe^^Z^YQآ}#ЉUAZH$55,> J hL>sD\nwFc DH-XՉƭf5BBF-ALQ#1Bi`ʘw8.ٳS?Ԝp?iuzQoT{F @&vHL%I\$I\ T3gz{&.m[3#1q*Qi 3 N@H1ĉq,G^*-FA aҨZ,JUd -V]g-/R?6BuׄcNtwS5dŘ7+419hUT+3pu -箹ɚ8g79Ou2)AoNQ EpTJHoP? G1\ǟU.Ӭ&RIFEνAn5D;<ffF;b!q]CGcثo>;#e0UTUl5uq񋝗whww9wv J;tl0zuAĂ聉5&(> œ>d|F<(Ģ@oeg8$ C5A YAmtBU Ce]@0P,p $ßcDdQtJLp 1 C+31q&n=.¯u}b\21yI2Ɗ WQ:Y'k2+"X EHd vH5^xGH(bcz^8R\ƏOx_lq:rOly=RFܐOf7ZwLQ]Tp#sQG++Õ KGD/[*:. 48}Q WlM}aQUW̊9̓idp<7;f|h*x-x'ߗ.4yɉ?omov001hM,>7̙x!srz^dAMr!^SD4Mli.\i :#HAD U>G-y}~s6:9kjf|Vz }`BHm !{?ٙlꡣ = 6Fnj!"k}*c8L}1F(8= yZpQcBߢBC.có/ᛓ\8hyffAzP +~4 !N a4<{ǒy]dct =3F` Z/pЁSy2(ZE'Zх!3ԪC:>t/6 g ":;Q&H[y }ix!VSso}@O-5[]\j!yE-Hv\tPέ ETF?[mԬ^qc{[JKv(P<\Mڕ9n2ȫ %zpa=SNa 8xJ ,Nv7[;X^_[߅]6: eF}.m>:U:$q!OZe5bgvqu*qh4d@,&' IwqV/ޝq8:Cew!3Y8(14c٘F?b-f9b.N~|Qo2F p2`CThsW6[5Qߡ&feѷ/(#OOO]932B,]oh,3}rCxuUkF3#O|, ,{VUm7kЁ{PBhN ~==@0ix;R(A1a39L;h""F8 &?GT*?;y*L5Pz"r&5J*VG`"T@*8q>, JS0MɥBo}Q'KmwFJfk'^\cYt#o*:KXeq~E=1 ERNШy&*fRM>( \Ha{ժ*!$1]s=5hmggfٞn[tمTrͪf͍ڛu7ol(]Gޕ+>~~]G<<}Vx^yW /i܇?S\?3kkwFF&5)v FXfcdz$3?t]R-Hh^{EZ jT|Rfe➘Yg򘣾'Zm=Z M5+NSk4cmB7S%ٌ5ԂgZHZXX4#h@SP=] ~@.RgI H*Վ2+jjӵBԗi=ڗd-1.bћds&[`#ee=w 0lIh7MZUFf>(|B#Z- d`D_}cLTvs}c.uWX:IT/ʌh@ƕSZ67L[D%K>S} 2񲒞~O!m@=N:9z+wAm~O:PL TGZO {R`#L:UՐt*z&-DVc:[_DjUd8oY4 j W}yb&]!Qg<җ y3M\kV}'oOʶ,&$Gew "aT,&NK| <;=VoV]W]tmi`?GoMKRj*|* :p{W~V=@wF!0F5N ah1q]h$v§t'VX$Aiu/3|L֘eMy Nb)ik`mme\/^4@k[c>ha4Fz"ײCoWz}a왭p8/ :erNPq=,[egsENI6;1L x:R=1J\8>2 9E6` Ԃ0ew|l65n3Y2 S P @ 1+fhRY_@ i<7`i^^"}v v/a탍TD~@[F<~U^wD bH 1jG³P7D6n7kJo # "IC6t;'t{)Lh_?)M1w]۔nʮ mhjbEjyA;5A$áP5VDB/5yxΌ&<͏ƺXUtc݊ʁ \_ $OV.tG{rGq:ä>(]4v@b`r ]EvFmIשj}A8pdCY._ +w|;}Zq2k.=}X,fEcUՉ@W;YRȬ/@e@\psJȼı(w~tnū~ݷ5"7K똍4["֑_ݶn4TqWFDvLbZ #Cq.щ;4g'݌]\Z^Qqz΀j7i_gl3ۍϲD> U|U!3$J>r4f]Y_֟ LO-ϮY]_"./NTxr~sknyny~yayx6qj)lӠyв#HfWk5Oo:dThMij ކ1~1h-A*w=jI$uNgHj lD @He1e_ucGpP3WMCLLE_Bͤw?i&-*w!ΦwLT3sZzut`1hh9ؕ_Z}=p~u}([bmRCqc$C8YHjRꒉXFC&l搐QQh>?+_a?kU RN4٬'g)>r~F+ r>Rh$xԊy!l}q>Δ{nWoh-w@]UJlsr[^G?Ts- }_}iڤ{ݳ\4E>TES-R%g+EP؞ug-5NQvPNt=ҚM+jn|m;_KEqU 7]=˜z€aKh ed>ÜdT1-;7- 1DždZօ?TBD^e`0ƧwT6EtYRXAH+x%[TݾJC>`ؾEK^oËƹƙ_gǸD\d]i\'mavqy.c]|GGWG}(UC߯??U%v|U|^AQ۽] G32xMotRRAUO#FaY'Ff ZF ]tJrO;H)5X;32^e Xn7ßBZ1.j/e0Muy+JG_]0b욏>3gk>O6Hz xQGcv=66ldd#a 3jNYVXU1ͼ`yA`X^_HxJ-Tt1<]keZmdnf#.;q xU2ye|/PI ]H{ZaӉfSѤnO')Fx Ķ)h p=k.{KCWCXA=ҹA[B|G|2}MKfl27ny"sQKf3= DSj&I;}Dzy/*s-v<< Jt.9Tm Oi=W[7?rזN+;:|rւA˽{dG22wcOd!6$GQB&}:u[bKcӱH1\NeK顴qo_{gc }}?iH啃U1ǷQ];oYH҇I-;N Nlb)FdcuQ .64qdHMM}}n-5hν3$Poxɹ̹{9~̝+Z;K^]>/jKka:+rppt$jG7h_839 K1>_Sn.pkl!+jye_soF+mUuedySA4UNX(6v=8*'ܗdyY^e ];ɪ'`Uc6}vpu?sbfz'{g 7 _?끞">oYৌNsܗ8$7Y|բK^r1YŮ V[r]4=Zir{v"HWbd嬂^$A/8=}zeQO{)8gi-\;J pYYdߑ=aD޿z"j5Fd9fRh7k36mܲRU[bcb q T>he^0mUaˆ%Sd-6rTc)B3+ $¡{@\# tjm;i_Y?-MPp[0҇:.FϷ l5[<;Ά++-2 N6K77~SCъfEս.Zf{;]W>.`I'7#/a̒EpÂY%rVkS:;/SdcrD/nBȉ7?{>Y 0{a(]#n&B;1s C%o!βY{ ).rFsV%Ht~h>UH.5 kZ|0OV[LJ;w~iiْ9&^*uN\50hn0>b ĭyT &7eC4/[D=Grso}rUXj4<ɩ.|VQgElIFo lːMxU.e!.e pzAϘֵ&_ִ窠wwO#A嬏u 5" dS(:_̳EP/?ܼJ?L6 z߫nrُl>ʑ[~;AAd^VsӼ+ ͮr3_+ CD{  9+$r^s j}>8#ڵ Km.Np&‡ᄉm1iwV+~`was=]GqM׋݉%%+Bi݋]hҹ[i̷j 3@`](B; T{Q/=&nH0r_6_~H+{SuMt-@Vw^hOa.z{h,#$rvv! M=8Ț؟NoRyJ{A?caI2gAQYue;lM*]%sתS}c+PU_5h79<3kBp6unfw*g#Ǩ^4W!.WpzW Rp Rp-;סj Gc~f7e/@4PBt#{Of ٲVt*8,= *XSp Xf\b9ס"kFkc֔Q[k~VPp/D~ۛ V-W]Pz#ŵFqŻ)'6)8ȱSFw(8񞂃E 6rlܢ`*(8بUyjlyPF 6Lq#iK.PHVs-)N7P)^BIPg(ny@q'esQ')SYWRQP?#N]uc)Nm4A>'D(D4B( D߂(VR0(~:)=XRӒd,HW*J}PkF B#632imPBF(4mx$ %-Xgr _vКIA(B{R"B-u*m9g9G?hr |KFl *>JZTr OZ)u;H($?5)RQjW"!'B}\)dJ@D$N$H}MQƖ*=bʴm)(;(KG4m">ZirВ%%#E'жEz̕Y+{FqI rS%JaIiJ Ѳ"LTb!7 ϸ#A\߉Ty!e&hH+f$7J{g0L(o̐eiDS捬D=KP,C&R|/(2y=br=RkXQ\4D#Hz2fZ̨eɴ$͛ӪEt\D)Ԓ-K'cr6Pϑ:$엲xREeP %eh:iY4CyJ?T'rfyh4x8cH7wu|fE!Ғx@Riwu% ǔqt FVZc\M%EM~rsZ#4ajE6H]It-QPr'~d;Q8!uQVhBkᎂ)/3c."-͇Iq4'qQؒ'@6&RD*&B2 t05„D,C(|ښ!h -:6m$&`tB┰-1o2P*W%}1%J[Z-p*!%Fu$H [/=* Bq"'$F?BJJi1%Fh\H?-B_#ĩq`/JB|(tBSc4 P<&N 7;t"%R1nJ 94tΖєBɤRd$$&͒mM#Т8%%CI1 B SM S!IRt,.FНƁ"eF$qdM #b81! H#JbIHR&%i4 Hu(AiDhX4 0& B&Sk05:,O$Cqq ޜRtRFĪ%S "*h2$ͤ w4h\^ e,mI)t 2As! ΄H~1әX(#D,"Hi0mx< A^(- KHFO(J aC9,b1ёh,30MEX" $&AшH$$*Dh,tK4.JWDiHI3r s(&%([$*%ciS(i׫ {eg]l;̪yGN5W61s3745j~^MRsPsXsD'?%5&,gƠߨHǝB p@:0 UD `A7=g>3P@5AHR$TRJ.?ORj 7 p~6m۴mMC6144Ӱ:hMM;yS+o0G1Ԏ6аN> endobj 15 0 obj <> stream x]n0E .E qJCcǀi:Y]$޹L ta㐜RtaIbN{wnsØX1-qݥ4]iZgX.nttߒƳy96ōɒ1;:oT}XcHq[tSs9ߎg1ݮIVƔjChM`Q p,|.'pEށkƔ'od&_ސ5w:+mGLGԴ*p􇳥ҿF}ELz h./t_ZX_п K8п%DD|u/Kw._c3s|5r '7&݆v{jsݼ-J{]=ﻛYx endstream endobj 16 0 obj <> endobj 17 0 obj <> stream x|}\[9޼AKHn /Ix-[(VBPJӮ8eZtVUnv:6t}۷tԹM9^(Tn˹9ysssHhԇhb;)LOA!һ3ŸZS. ?20d:΋!ҁx_|ߌv~<ɛrg)}/".YhWCMC]#B«fC꿩UC!j$؎"Թ|#?Ǡ %|` 6r2BJHTkPV#3lv@(;(2*l;az݌Ԋ\h;A1TƿBTc hc/Zu32=W_c#݁QKԋArt'vRe/Jt:o<~b7Y}pOV@5؀p5A])tѩNehDQÜ2ÿ`aNt#g#Ԉ+G2"AKP} ݎ~x)[ΝDXZsWv$< =Gc3[eߜ}iQ$܃nD@ 6ķŧgatӂV{Зauɋ8_orkfOg_@֍h ]kt9LkV#3QXG @$qv%es-sy=gc9`ikHpz![?;mF|eҘG_p^;JmP1* \V,NsG7؈k762~y-{M6~Ü&Q|;{6X]*ԃ}a'4WK*6/.| ޏ{K fdFXV6gr?~--q>w"7 K@N~e7\7'Zς׾.ƀ[p>nk#X_x_G񛌎`rC̗1N?cg,Q悫M=*|Iѣx@ÙvV=͟XGgh9_<\ ӆV@h"\У,xOߢ:^˾N.֔ o= ߁Q|??ÿ/WzϤ0L)SŴ0˙5z1#^v.){`_2b̲`Vv^g?g}tÁ,qw'&;wmc)WrEbbIE"t!d? ڀs_D6@Dw@,m y}M<8ۖ#(Հ=18&t9e". Ṇۘހ[ "dƯol?`~'89Y%dz(Q1ý^bjMl1 Wβh-:ԅ_J0y[aV:AǙ37ehiЛ2V2UGrCl? L]7\;q3-O#}V3x3ja[ę@;;Kl V?^` vHuL=ꗽXƙf/^t ᷘ,л0)Yrh>ё+ ΎBy or{* ^%8 gΏ=QLAh_Zv:KEv[5›M9Ƭ C>-5%YըTJ\Ʊ Fŭe[}k[W(!mQPD_L)eEH)Sb_JV+QM:G)N/PX֌>e;'Z f_BI1:`"@Qu86c 0 Rj@h5im!DY[/v]gkb*)^kOYIJ4QysTAd5FxtgCgn.2Gmv˸)͝ى ?O:ZȽ xXƶl2D ,E\J0[Q:8m+#k"֏[&WPV+?j6]ޖihbTg.))>Ky\$jB7G!JND"J(˃$VXH5Do5 èhU5o<tV~]fN0r]D@spP4!Azڮ()c޴x@}hm' -[,Ī7ubG=I$:VsfG (}pG$]zj`mLOo밶ɷNlt۶aQK쯞hjs'kd$1Xm2VIbFkK`A`δm41oeV~ o,'i:gXԍw"qm cp\pQG\cT$gQ{L\>)WнW7Sw:Y-6ƈ>328+S >rHyCW%<<>< o^O%s_7l\-sXC.c )rs810Zu4Iq4c7䰅0dJBtﵟֽw5̜K1ds P7X*PjenUWV]y*3 }7]iu 폚=7f(]7xCǯlog_n!OvA {&42 ux#{ꪄ'=qYq{cLf3F?v̤R !7&cE<"!g\ft)D5p:ŞQbpBU-2;NIi}5z6 ;ZmMu%&s\ =_ieNp>2+T&m :%ҡ\b TEj JJՊ+W6nݟ:=f.Wr) JR%3"Jϣ LsFhL(d|mެgYp̍v_Gv_h6xx;#G΁vO锚n4kM ()n $R;bP''4(ZAj'"vHb OJ޼WVU/Gq_-_[7]͑_?qk_a\K:V.-J.xesQ3?XgSIKt  ĥ +geZ=H[hҡd@r[n س ͅI 9=gZGڿ|կ{\pʦS*_צMvbUVBF|n#'5}Z]_QQӎjdz.8|dsYܵr-[<b&ܥբ,CY:/[[1--<\jXcorIp -jYƴ,=/!F%e,w1KW|ݏ`AgPi% `XbbDqB8.Q]Y)BJ6491ӝer'ϧ{&_(MH΋ $_8Lυ\,"@A>{ )Q#rܡVX }χ^E*X]^Ѯkg|^2iW&t7|g o\YY9{<Dwf&={vv!ݜlq{@GѤȟI]U:޵9A}mG%!C+-E[nw>~̑XFҶA3ExF 9W-hI_ 5-viV T '_jg1&NO7vZ_ҹr};cE~^n.qػ4^ Q8q ,]i&OfAփGĬz1mP&;*O1Q18P ʁxrɁ=V E2ݵɠ dД+S3*Iu>n] }8c!9%Y:7s=3+R?BC⑯-ZyiT9@)O ܍ٹ#MR PH;8Zom׬^yVi)w=8JJVrrm;R>n em<в_njs8xAh)Z[Ky(hךYM9mz<՜Mm\7vgm$sUIzKfBcݓҷ gyŊּL)U[V|[QB٨ cU(l&[{%` !UIxt'dɃ.k`Bbt3`,=3 i8jKxNj^3W'uHtCt`H'WRؐVv@hPDA W`Lo9޶߽k~Y0^\wжkŎ[jm)먻o ,a+K?;0,%vOEϵ/ptR9 6UoWLk7=̌"Mzo{t5eq!υ!Ye"O͗$Z`R܀-ð% gPBWȌGL!1'/9@`obgI *k퇳&2ɠG/OEPŒ7LqM)܂]?GMnY]R!]ӎϟvM;ީ#>_w~u,ytISijlT iuuבQ^+dRZz+wJ2 ),؍r'43R-z [e3>XdYmե9+fFGg_25*Ȝ)yZfa~"׏;͟nݖwJ*kSso(w2 RIB),HW<!ij9 L]M.96'>ԠN.z 2kaWT*?Tݓ0 ɬE툥0HGqI88z K8mtgK0Fps uP>+rT# "`%3$Xn`$8Av9 ND!y V~[JU}[h.4ݽK0FI yf fQur1N !urT(#I V@%XRS V N`&F8[Knn ְH93 ֵ2!rG$ty )$ |V!UľY%k`7`qX}3%].`l}sj$웳E9`u}H07/UER8a`ЉC7i-!#La5p̡2^suA©!/1~?+N'V_LL§AOI~L ΡSLOSLK0y*)ꭈH0Qd]Jyt]_I0S)}iBaj5 v)݂6q4|yQ/<& h(D$*5C+0{<`0 P {CNzht& PP(F^c@N~4Dq< 1JMѵr:kx~Djxø?}Ӓַ&U\m߷3XXF:]xhu#˃d|IC~ʣwADP1>lu4,I:<#ffC^">F0N/š#7BiU4+ 4whB}bL\]ѯ~)aX5.\ݣT"QvqεwA^Y kR~)Y̑T+ H^7H I.L-?(~$d$SAKs]`)@ Pƥ\+r=[.1gJ1>:ø.*jh`nJC<_Q4 /'|4/}D=RS?d Nτb&RFfR46%_ %jZ܏?x:o/K>^S5 0 w2 zj_(B1F$MǭkBd^qV}3Y_;'# Fx;_}/ sh+8 /Dw?<@0%|G; !88\_Cjo7]a Ȝ]pdYa}aXx; 0ؠwG1oþ>' v qaG1 P K{|0? p/tA K 3~N0BсA  ;}H*@# T3I,?!Dss>b0]7 Ka|^4G{#@4&#B#Ȩڀw8;E5G@i{!/no ?@ Ȃ=?2hAL%84R_!GâT!w"@#(zh_wT\"!AJ"o/:#ұ1琤H'N`d(P:!y]:! tO9p H\fe+7\sfzese|m$hh @ctU~X2hxp @tY4D#CgށG`ؠxA`E6E#Z.ڎ|Ώ#DB~p` bJѹ% JU1?`/)" G;)s5IˇG|~p-c}}~!?t撋 S:መQdp hO$/QC ?jdT≨>V_XBHva: M/4, $MÃQ֐o6^>K NX$tk`Dy%?-y~@/#%;aS)TU%e2jc =WʊM? F*ģqHI_y?ik7TcSo_Ӎiq h{'؇)${]D{ҥJ^*]ztҥJ^*]ztҥJ^*]ztҥJ^*]zK%o{S/%Ha_f~̅j?H߂A+9>y /hj^_jۮqY1w?y,Fs}EmҷMyIѮEAqSg10ͻ~' }I6OTۚ[}'n3S.!IɂBؑewkLe@G>P @|r2HG&$ZJ\/7&1'!QSNۍqJcO֚ ұWA)2ġp(}pfN`r;Uy/We̖'(30"10A<~3̱rI)P bmu6OIHIPK+̱Z aLڗd?C.TD'̂mun7lNw4fJ&]Kp.[wKMֹ?Z?(/])NJ4r1EBZԕ0\wm;VqKg{\r[[ Bĭ-u=d;e{lveVײ60|Vmd ٔHЙDx.3h.sê{a_!U ߅dM'9iwBw`Ohw4ᶵǕyXF$Xx g/DGW4M6 vQ9PKƵSr55RWIcI#w&]ZukX`.acghV-](?Rh8%`h.%nofnmrf["~4A EkTAᰃs8FExODQRAaŁA{ΰ;'o qGh%rSN5 endstream endobj 18 0 obj 12288 endobj 19 0 obj <> endobj 20 0 obj <> stream x]n <bj$:ERp$ ·/\msh؛E JK ˼ZQiT*nb an\Fw{#JJtQnWc`('eI% μt0tm{o\74:Yb:#KI@$~K9s|DΐCyCy,9=ȧIWu MrZ ~fP~&p}_ endstream endobj 21 0 obj <> endobj 22 0 obj <> stream x xŵ8>s%KdJkɶdY~ȱ8ā [Mph-R(2*PZzh%i (چgf׎½}23gfΜ9sΙsfv-gxp$ h/bؾs֭D.8BMg/nFHBʕzF;/ +qbsf~ 4tAÖQ5BbP1|O]MPkoۿKc;.X>"@m=FCgPB}x3'PB ÇT:**F&3g'Gy=*Д~=ޚ]=r;f/;Φ2$>B7P â:6!v"bpjr %֡l$Ԅh5z!T2@7E } +Fq7zFߏEsz4nAcB s!t5z ft PiBg޹Gx3>o.BRt+ =NkB9׊V48gݏJh..VϽDunHAEEw#w؉dB1]JXcx>ĚՔv4$S`n7b~tz=vlZW :i }$CO^M|Fq6Ɨ2™FAX4VsQbcb.e#يJA*@/A_\ʎ+FQbz}X ؆y\K`e{$=&v+{HyWla t%zE@B8 FFad%n_71GsٛfŃ*>VZ?q:ӂ:n|A,vcPZW-_~O8c(3f!}ASVm&csṢsߜ{unj!,Հum@7?~~ vw~N@aX 8cg\Xݹxޅ=Y{| b0˙wY+UE-/*FyP u@w̼6fgoclQ{.V;|N d$MC(G?}>Q~mI4f1Tb |$A35`-8>{+V܁&D*f9iy>ļ'˱fu6v?`bZTT)V*+SVRJEٮVy*g233~ O8@[ I.>s9BZڽ E]zIC?q%2ŕf1j` ]/}Q~i=~yY y݆8.:kQGz?ͭ":STNRУxsLܟ`_^e Qt/zk^Ŭ~σ#=SE&ѣl mVGgUWSLA=: Q:^?c?HEokG;^fG_G50%q (@ݰ~{…x338|8wmfe^)^NJ4`>U_g;$'BiNʇ?P\U.]{h$D ,A[ݓ X 1ifD58 ] 2 *`?}b0G?@q>o5@ZBwCK؄KaٛNOCo瘣|e׎F2̰5è~XZT˾@]aZ6L()_ ʝ];WtOT& ٗ AvϮ@ec&wDQX^liYiIq ? rL㽞twHRl2:FR*X:O[reԅ6hh[КࡩLJ31E(a Qy$k~o^ |b>@a#> ]|u]ZkaF"NC?naiT"MKZA Եu$ou|͑i&P0) $T5 5&As'_7aCvL氄aڄc *lzq_IuH 4`,o_S_Bl8٘+7%0%OVBV%/.ԑ V_ I۟@giisQZ&t mmhY.w=Y$6e`\ (D pւd1HXydk*%Yo/4i0*NhkZsKI;P8! =MnQ,Ép8 Q׀N Z/`9 jٶ5/}>k'D*7Iumu' 7'V39c?Y*%?D4&̥u-Mooe۰ጚ_'CM!^0Ie!?5 `>fM}@F0eg`ϰAaugՃڿ^oۻU9apZ_:щǮu'kEt|\F1zՈ)HxE:\}W!-NϔN7ΔJ!+Y|d)<;D!^1InpR w\ .W*JdlPA:^Nߩ۩Jgڝs aúgT;<ә _3~p}n-^4Qp3mz=L~AV:# @Z"ngh6yM" 3Ux<͞dlјi3ed2vM$ [>QjDUVOs\r,Z>M+ nfZAT-Z&&E cn]}2.-pƖ%KJ,B0([jjQW\TXdI%FZ}7+(0EY!۳5eeei&}*rLC;Vμds3 &{m;>>ȇ7p[՘FԎZgITTp̬4 ŴX!/[#M SQh;F0[V*N鱞 Ҥ.èl)F ]lf*3<8Uk :# [ ,aMsxPґqLP8 /$d2ЮF ~՘awU` W77ǜ7opjp jh-0$jgcV_]XkV_<ѢU~e^ēei3<+_][ ;eJ@aF(RͽL҆V* 4֮*V3KM`aqC`;m^h3>!= ⷢ]fIT {oO=,ntQ*W!&*mb3\mGmM[56l)K /,,+2&d/d%ٰm?.DF#LD(Pk[%%СenT5Z-*s=I6(++H- %^4Fh-EmFf,]{s°asaedK8|~P00-*rrQDV}%O'*"dj 4UO\[n 0/YRT ap"p! ï>%?rߚ.qYYN۸:x6k˒U7vEo33W;>8T3.p4b27+frhAހ\ _`׋zV? ;MbRĐ 2+JFJIl)VB$ecєɔ6ŕ7($3v-wqrD RD'1Gڭlw2;s>Կ#ƥx%^>ivǙ}r-)Ϸ陙Y~Dy|~A<imy֖; i4Z 9_sUVY`f1YUX4囈$AMͦ#(cnqkn>9B4 T.CA ("jb#>!թT;# T>$ $mBD3 F-2A-E#L07_oν*%t5CFlW Q2b*%iŢ5e̺ jf?~_rž%MWt;s4":FBi/[Y͛7g -#p F#T[e;Gm>Yy/__Q7f~9CQ H<OFp9UAiTXCCp $|LP:vbVQj-vefN|k3\]9;.;xS`wuZ| ǿRz)c6|l3f"Db铱 x0 c mTm{6]|6XZ5eAܔkf^__qK㻆Jf.t_rfhWq\ ص7(f+ȢKFWH+#ԫSV;VortjnBwG4"5[q7 =bqҧ &bxRحvfG"pnv87)/z"VQ蒢YEOGMp2ƧkF4 FLF[͝{5?Fkܚ~ kjX1 Ŝ貕L-%eb^gN!SN1Ώ)9כͭUԘ^8PT[>UP0Hi-1yN[Lvlwe7eWι;Jn X%MVBZ^zs\I}V'Op2HNN@lO͜<Qvl%,reJ :UA_@, !@`[ʖxn`R2B 8Z pȱ8$P,m"z&QŢ U^t.vUe {fLs{ 6m֍."o^/$'{ukV^Q?Pe&J5 7뗔 n)cCxfeȊfGwCL*SץnTjƫV8:S1*R9W (wכ9a.020R8<ǃD32.LjJqfdf-wC0=.ヘ!(fql|]rbhqVAqL`v4&Òg;9pu夓-%g j$ya%܏V9)v"nsRrf HӣCfΒ^IxVF ;)ԛ+JJ !2g,%%tH]Rcs̽}Oq 斖$B6zwKl3M2Aك(*zZf tr*G:{oZ 83QvRĖJDؐZtZ"thv fCNĹ/-&8/h⠥|#`{DOR}%gC:FM3RqS3 "fp#lf2&l`3+R(C03f pgf֫i5T 8Ox+?< \&h9L7rҕ8w5|*O#W8qY$ Yզ8'8'Z~>GI&w;r 㓢\DaQd1(*+e U*8cQlgýSpP)$t&-LJҨɱV *Q/kx1 XIM:1aBC,װMK#*@9&vQpݑWU Uo.SY%+29&*E ffhl]lK/6;SŬfWhD A\6ΦceȳNr pb5p.$ Ј6_.@*. d >^:h@w&Z ZR&(OP N`2 1UBl!+!a`J e)"{)XJ< .ߘ>9wdzsTY* $ ksƥ 7@P{Q@ Ly%G|!D טfZrQmi"+ ܖcQ ܚtea/*go}>]Eon5>=]%nWsn\{sSH_[ʯ_qaY=f~,kv" EF5fR#Wũ9*% _CWMޏ3 r3OdCmBdV^ sib|)|;6L0bASA@*pA44& SvFUi9"ZBDMJ2%9WQ @F-Xz>"HK$ (4i:=@8 :spY(-Y-<`<_)V $syƂcaۘ?b?k,|:f-<ȼ]GlOdZkZkЃ`EV_ 3 |MAѪ۾d%B,(ƫ޳2 }+䣗?ݳlûi^uLu-ƷU8Sz~Xxu˄lz;ۼ;;u[R=1Ǟ Ěҧq)|Cv})v[ վ =Ma,?; uF w:1CZ#plJMʔ-[ȫR91H+Mp4: FԶ),>>l$VV{^ڃu*ÛmXUP΋GqڳO}7ծte"'GnjCΔ3#߁2r(k!ljrǁQXڇY4{BQY859`O?JO. ea,ݙb sc| DYW`xwmjS']EwΒsfˮݿkw1#uO?}d[+ͩ^6\6+ ˬsWvP*ߠ{sۮseNuZn)l*ڎ4BH,j*/[t`QHC|uW4W^:'3Ht堬hQZ AEDk].Vsii=rmY8 cqX3,|/G Λ3 DEA7=bwFͧGˌFɶd3z}9-BuN.Zà)4)rT*!b:Z[p*~()G"r2s:6νgҜ3iںx->9Z,F~Z:JeOCpZv3RÖ9M]AD/B3@̐4ؚ_P\C)Yy@jj|.1lܬ%"fE~]WXU|cwFWN&f 7|t{7+ξ^?+#ga\fujݱsRnsuzN!7jiV+o QJf2@¿"E3 Vd4939 X>^w=v1] (]MzǢl41'/B?P2!d2cKS^294!x80 {   *d 2|`P\|4?E{ w`U'S܉(&w*|iP[}9$B_JI9x y\!b%RV";>f7v5ŇZ<\0p,f?[7'h/0_Z=0y~izOn1uCb]!+~NMef?bƉD|ZF=<)?׀2.v1gco6~D5ZyFOY5_&jy ohxG =0Aa%J(*5Zq{502j0aXF5 zzrVj:dsaMl&M1X^syXg+CDs#律@8BO:rρ +6mkOg< NOe7sP_2U~Vfn1bA ?ƺk1Νb* rAd|poPJzJތhFe E/<,=={/EQ+\Dc4LYtUμYR9MZ-XF}Ig=@o0n_׊%pMaϺnꨴ\pA $X_#4#Tڙ|-wm1lh;UE\ݢp~GRVky8F^x3W͐[Cn&;;.Ǩ/hS)$ŽrrNd0LJw|'^pVmNE(qPHd(&nSpR}"_mNIi*e:ÖOb!cJf@0*k0;+'Q` ! X|Y8^̈́!zSDt27Yw:Ƅ=#oI#s55L3tw|+K8c)_J 98qJ)YW?޵ᮚeZC~իh,޴Vv|/wǪpԌUۼ߼`a7XeZ.K!cX'כfN@SNH̡lʙasĜ9uɄ.q,Vq^M%>IdAqǖE)j#,JXb#_V~aZ@aT24F Ÿ3 .p`AiF43^(䛭p_ϏeެOyr͕ZfL1nVޒwflYtU fZ@["C|hu~5;u"O[hU533W/+>%fmZ/7-sx$@:cww ]yA"?Q0YtH_Dd;[`GbKbE}eEK|nr{ZAK[L\ .̄`^B@"=^x9n!zZ~2>VAZ5OK-%UCؼrs M, b\JYSno$o*g?.Uk%;`[fcQ5/N3x[?_\ƥ߽ͦpwK8ouqpu@hb3 @p[ވW:}CJaP!@/ k0v0s@n mۊەݪoj8B{P7_ix*~זOVoPN]h9b)IUz[6nYtZc( NaXV"'aS2FeX2 kU?eXa=Լ$ԩ])FC˰ m]lY. RX0XdXldX eXR-ʰXa Jf˰Xɰyz Q=gEyތfM2lBy R72dX\a +]ja )v2@A׍VaЅi kz[(!Di>2 te뮓a>,à_od ~3d>?7-àߌd ~n Ge:"1Y)vk- TP@"xM7Ȱ0GaBN!2May6On ?C-w +P,W+?#vQ94yaz g~"{d\Fa/ſO LbWel G |Rd'0B iXQ &ywS Zz`|@I)Ά43m仒| >("C F@y< Qg!H;qstGkEq Wy;>/\6نVG+G@0=C:~_==^}zl1hM>gSt@iDۡp?+qH7:L@C T^yQ:pHŁKYj;|:ֳHj<_Ev8$6/Ikۨ؎3t?D,Z_B,nJ}юJH;[,aIF2 mijP#.jk'-CIFR[?;/UɊvRϱsaOYs.hh}rIrb{LZ]5ɮRCϔdsTuP KFڥ9(-Bq&Xk-3Y򑣔:bG.6yAߑ Q͏dHV)郬 ~t+ݨk%JhOg˺c$Y xtQYFV:v̫$!"mvSb)}u) =}gj_#ghqr}uPSA%4He;<J'E"M;j't0 yLGrr,!2I{2.3X'd?=C|~*s#0Ğy TJ6 c<Pm9)'D3z '&%p(bQDb<2E?!xa?o}} w=y|mp E 1쾞2įqee m]CYxdž!~m|Vߎ꾞yK?ǓΥCd¼B>}os8糐~覽MgGL>1~~`[G|Gv_o;^~P9ojF~]gg{⻺-oHo`[8_;ضw gG\~cwp m#; -*=۶y}vv m6GNJ,i5}`. 3n⻇]mC|G|{[o#W ]24u(>0<[};|_o#71FCC#=5}0Ne8#mݽm=|!~jGz;⃟B0=o:I'1 ^ lC;8*@}UξD#0z,h;ܼLW6#AC/غ8HoqQ[ii=wKbNQPm{W`jCI?mmp#~Q{,ltkwO(L<Hm}}`KߎQ8(rdH}}ۇ(C;ڶIV10 >B;G%䶞>=6*5vwu /FwڕCdNkxGOt0C[Ɏ#_pxD:d WTmXn-_nu|Պn0:w6 @b`̟e骺a -b~}#dd{N $%t@O;k{@X޶m0'aXW(opHw3ħ킍ǻJ&J =ܷ-.)8P`76ݹȀe`,ba0mζRچËG2: X x{7ȧW΃oc::>?HB.iLt-}94,dbyo8葭=C]d%{$%3%tDT:O/BpvCt4^y2yo6`|g7b^>Ma{-؂ a1YXug,/ h5>Oi^J9 Jvi$/)(s1 /YR\V\f_nFR}HK4rGgbl?wiN/%x32{ $#)ޘO~D_ ї/|A /_}D_ ї/|A /__hL7<@)Ypmz9WS@mh;gӑ|-(_t#6RIX+WII}3=J(|֘Z**5%RXhP}b}w Lj y13/ E؂ 9c7{ռ}4CϠytnRPh)ɴ',sЀnڃ2TCcU:BCbHGQy<u"3Ƥxl̸9P&H J$$1H JF Dqi/KsrL"$xJ*!ǤBK$`s6U?ϳDsPf@, {\^ۀmvBy?{)rS$MɾAbW¾R;dZn Iv/{9eT@#3{<7n7@ MAz66-X@o7 ͏UISIv%,}%ʤOy^10ud\wxٵtk^AjN(PJS3j)b81氼иQc\JTD YR>B$^8Y;Bv!jtRY腠Bt%%h \>@{t hχZ!?QsZ!t$ Q6o CR1|w>r7Xh16q)Ccxcc1n̢$#Y6d%~^-MZZ|[X~ժZZwZKU EG15jx5{Xc7G_;G#"GXѽd c(b ǎ7 /e+~^=K9?O'SzeB5RW}R6ZU*WUWE⃪UAh$S~[!u& ~ x{!?y>C!?a~#3L3?S3Dd&3Yyr p   $} x/S@ y?Dț($@O Pbr1w- $E!GkfȽE½ 8C(RᑊtZ Tہ@vJv t;$s[ޖ\.KUA$܆Ab:PJ 8z¸-"x^H 3ZwzB8Z4 d;<$)Rt`WֈO;i Ks? *eB4L[g34ޝi|7okT6OL4Oc{3xolKy@iߤ-4/~$fƌ1c 4# CFV Ux'X--_1Ez w,(ҒP$oVi3> '/c‡54$CA^*4P(2M(>Jvf@dS Wd緀<~e(<Df $ {0O/ʄ^v2dgJvſ%;O@q{2л eS: -nH6 (}b('+~Ew `ݸ(mBZP6>S+D$H 5䀇aJEL" B\\y3 Ei2dK-'!yg =Hdgdgn2Jg ʔ%"X\2{Rԡ w~T17&'48[6G6nqw`?x{ P_P{:}i0DPw"qx{KtnaI ;xo '_@Шe0ƯxB fY.X6m m-_bNUceYz:*Ip ?Nd"fsJ` 㽐0νnR_fYi~F*uKg8|F-#qsٛd4' 0ܐ!'Lsa]vR4ozw1=ugvU h(`j$1 /BÇpE&HiQRb$Z\Cjk)ҷ CL(Д=(D' ){(Rg. `!^;[wIƧ(Hg2ـ'^?ǗD/V.5q.gbV?ܻSO.[ۻHOⵉ^?|gto"˅hS݆M7rqyV<ҁ3\}R2ځ k\d2Zq-jдU?GDqF5Wrt,9/u?@~7' ButE"U 42Tr^~ /wqlѰ $Y;pa`LmpXECMݵ俭'p asª?Ԣ_7a#;IOSӓ$ 8^N6N5צ^;;%2Coh?#ᡑ!Wj麡: %jaJ?R;*ᅱ9BHC w? endstream endobj 23 0 obj 17981 endobj 24 0 obj <> endobj 25 0 obj <> stream x]n0 yCEBBbm841Q~q6iώ?KTkѫU3zL)Wɘ^kjh-YtcͯM[X4[ V\C< mr?/[/+x_,8ĒQd[57`ϫ``8!ɵSҗ d8pV!/I}rFyO)|$% {=R||sBrEJAZKVtǽD&;<$KC.p)Jψ;D N7fhQols9 endstream endobj 26 0 obj <> endobj 27 0 obj <> stream x| xS̽Wdɲl-+E; 0˶l+ؖdIJ %mC.!i?$Rh&iiiHJڴ%zg^}3gfΜ9s9se mC, dgMQ>tO!$~`lp$Ij'V6dP=Y2_A(љm2@e D`fެvC} Cd|XD7AxEhrX(! B=Sd|,o24 }>G HerR$huWᱲ@_4.rW2_"r =G6~8ʵ0 q}`h -~NiЍw[Vt :ar*T 7ѽh glc&T}ѷ}Xæ "ԍF!tNH>D+_X +]m]`` X b.q+[?$WJn<$2N[:l] V?z|:EE"| ׂ~ kq?- >_į7{2錇bjz| >edelF؛' d~d/Uz~YlW?{u3Ι=3ߏg㏂$M`9:ؓ P oCe/4 ~5M~` ϣD@Fb,*ȆO> [rL d032w33?bxyyyձl38 ?3ʽȝ$I$$wK3)Fpˤ%< fU]Qw2;7&.>7OE\5՘BI. 'EeOZ2RV k?Ů4slCf=5D/!TOfc;A0K,n-.c. =/Ewq_-lExĿBQ&ˤ0{p8+DGAE~\I0ȁ"i)ˤ,K`˘0ko2b-3rY4q1!n`I 'n^86t){+D]Ǧ]\7 7 1)L:w+('|}~ɻR~ } @/W>zfG? Fca j΄O1p癉?KG Yē[]].A _]mMuU ?/ZLw45b6S ID6AV)rT± FΖ>㲜 摶y=1Zlj=? 9LQu^.c'tY779i Sx75;0o6 517Z6 lirTFgc@(UcS16W`\L,ΦD8XDzTcM^n 79{cӺ) jĤ1]ݠ];oҡ_cknX)frt ]珦;MA4w\5A5ke2[zv7! >ي\{@1|1iO!K3ե: hfo>$/.Q5(:ږω b|t9a#T}?k0̊1EcN]%$Sw~@w=L8 gs]Ac-mnb^sx@| ,;D|m˺6zS'&#+ȶّ=N0߇%"9&Ϛե$5Upg ζev;{Dٶu+D(Ŧ2"Ĥt,q2itc\&RKi[bBFp|IS,Z&t߮:}{,0e1mܩMiutE*f垒b8dRgzV3]ʜIRhg7o{WiAZfNn)CW(U|vWT\5Ru+m)5-Z.f Z'_u}}uK9J#3xV 7STKuRF(rSնtKH}pUa:syQ_L.#dJ~RSiJoqW-.} Kj:R9cZ|JMn0 %݂TS3IUu$̥kx=-[h*LԆ)*Dݠ*M6{ʍR"ײR}(eL]˂xARܤX+v /s26(n GzWۥM+Swm3x^TG͢"i&+߸N+ـ*VTglO/(Ϩ+*V*R[qsysEWjgygE_ m SO}2)ӗ1ؓ ǔ`*N1o *ו3StcB3zݒjH%"XR[D083=0ª{ śjtNZބ)wOufeN1 g1{-FWxqjgͧMuuI8; .VW֝x{q -LZv[t4J'KUKWuo cau >!M6=Ir@- 8e%24;/n_+LHie}ɳmMYgt:ځ[lLWn]P$1'}i3KRT|dki)]JcgmYTt[[IM.]*~;m.F[0 #k?s4pڢ<wf:(PѢC3^7I5DU8MOip%zt4w6ͩQ ^JlZ4V=U_]{}eb6VT93%^yT]F /cά8ܿcfeER'%X+t g1+9FMV6o㳬Tc$$K.)IG>IOZFE^DNbK!UHEjXU< Ѹ&@HXA\#lLa wg1D!䱒4e_] 8Ue5L\;t"߭NzZt9ܿk^kt杫z Kg?y83NiN.-IVt7[$،RauLiIffXI4RRN4gtmc=VFj9O3SlR)#M>OvFe>iJ9i2&XrlV]^Pa/-BOѣSUWSCA6v#eVL9.<04YolȪs`Lf*8=L:`/=)5Q "XRfLkSQk/ 9)4wȮmy.x:BfiA5wgRu|žBtEqyӞWVxKp>`zdf2Ka]hT.r8/dO{ g/A}kΨo8؅ܪ;ÕUj2jÍ~IVPTHf步{L{H2Zi18KAg)!$u-tȊA>٬UgOWd2'$y~YK* rV[zBwаbKYI eG3ni7ըBbLiD/&LH8lP^.xMΌ\+ODEr&8F]jP۲no*t+zmgr^~Ce-giej=YvsU^˞^QxHh]+c2i37,+(]($=S358FjUe׫Z(*1|'٩NNISIMQ4+iPT,ajjE, xkYc̩jj;:I%^3aޮ3c3I+*%$ z$.$Bp/-06Ϟy<&/❷-{$Mwsp"' (qn̴(#l(F$mDn9I&%z4IP%V]SdYbY +|ߏ6rZKɳk9Xl۰wu +)J,y;=37yϗV:<ݐk/If-h(ξr&) |?z>\U\\[i#G4!K};*F#usR6hh*[-z胢e؜dtes!yvREH.uӬO"[Ykf}*O7U%)`X$&0 SY_|ҲzRԷ^yuIaw|cK2>އspm OCjPvu"`ϾDYYDkyR11JH;2fʯk˯ԱwU ٚY;k ϴ|+f s;=Y|E-yQ5‚}ûSTy>U1a2ѫ+%ֲ$Xjo_A)w`kSJ7XZ'w;i]YYQQn pXA*Y'(ewʝ)\%!ˬ rF낹-rB[][L3pF;D؀%I5#s~WjW^zebb^]mַ'2d9BaUM*̔$~,6;SqN9ܡ/gסl0<8j ɵ]){VU+벹L UVn9kZX.;ȼ<{Kn$RIOkf^TNjD,"\-nasLMȀ1M3Cf1‰.k4kI|–fg#M+!OeW5d~c <S@ n"irm%⮃8b" y[K#_xvx/xMho@zױr+sR-jn`o|ߓ:izǁ%X`ZMjMiys/iSachR&<} .IZ1`YZ:tϚ1QkJ*w˹[5$ 2*}tb&'s">w>>͙h* 4x*Q2yܵtW#3/qk.)s*r-/f.vf>^7SX~)`k k#<$TPoֻ0<ó 6]aͰ2l&mnyu֚ZVP !scE({J̻,moYd1اГSwXd2U&Sld3hM=lkOp'IO!JL=Cr]/a7s b$)a KrL:پd"t}ZԧzKIӦ&?H6&X;Nw܍\peZnrXx *8xN<ɹ-9O^I=:5tzU>|_GSmϼ9{c$%8W\1\V-.z1/sOV 7wm?zz7ؒ eB=A:OiF~%Ąd ]ԋ 9ٛQA= r(.ʁzk/ZR/2^ C_6V3~sq.Zc~Ewy=)^H P=Ѥ>zn MzhRUY0<",A&KQ,eJVBVJVDX рbk+NpZ朴֝af*ZfQM"̡ğa)&YehXa9JO5oa%yV!o-I>(ߋp7GEC(,~g"̡Ji K`IaZ),#z 0r儎eRY +~S" r" t" V0дN0~mHAY|oNAiao^A׋07O" uAa%" 5QXDCM[(&{s_pӋ0RXy"̡N"2NQPudO?_p ?%PL-(aX©ς=" |(l#6P'(M"̡ |^+g OE _(G"AKYXN?E )LUt{a/vz)aWqDh >y?oȎ;*ЩD('+QBp0g-UQhϛv;?:'1FJ5=a(O3HqfyQʥ !H-< u Oc;Xjo3jpnݠWyԒa"Tsgŏ~]BG$9JD,n2+e?꥔9y5#LӽQ8K}=5.oQ*Saq)}PQ㧴)M⟣!vyp"TW0Le >jwרXϷ͔bńHJ&h ϓO=/0#"o6Hs}-XOOq*gB( 7#z)gۉ| 29#1gL^+tQMfPCAFB;+U6(i'9 m /cv_KAip{JX4N.AiQϋ+W?9x5 1rr&DhuCT~qݰ"Tx,xj>ȾhG{M;V Qj!1Od Ǔ^:wȫ !"AxPb)cu #bh?8KOczh~*10TzͧYB+!(O>-2_:@EZN32n7SMs,/o2#/^=-4zfY%ɝZDoO;DϹs'lмX0&Jyb.2Sۚ~^g$;4/+egid X֨HO3U0bkՈwn/A4fpRp^ OB " Ig}$L=|.b􊚙v^8/),U|rя 1yL\xCƁ/YzOsq'(HKAT_?c) (RNJ<&1a`gh 烣u v~@>Ñ!@˟ cC|Sؿ98:HAWyt80{= ϡ3/~ v[߂]`-o.~ v[߂]`-olmR )wQ} Ԃ(o~HEh% ~y?}f #6a? >AO q^f]v/_OJ? }r?}f˿ i#EdΆϥi*kȁY_@S5wA'ĉ 3?w[w_{(@?FWmq<??\웂ڝOɜŇ%q8 vdJ*y|A<pЕWZ}>r:`N~Se6ɢAkI>Vg ibPz(Pu,ebX߉b_;`?mtQvR{]r~<[P&=G`IC0a߇: }\wQ=*7 %$ RDOpVzL\15 'K!K CUnlO'7LP ԕ%gґ VA07gG _,_Zuu aj`G=.Vs (OUM1ɅU'eR _ɗ^ϰ=Qhυٓv70FM8,?ʬF2<}![% e dYL/3r> endobj 30 0 obj <> stream x]n0 yCE-]%A+q 1]xqI;$(}&ق6<ݜUf\iQYo SQ=f::N+_}Tmۛ_0\ sg_Z7*_WpY,,)}EN fIp+(yq> Ks\(MC EwyK|Boș@;&E>TO+ҏ553顩"ocNU9~wj'xn endstream endobj 31 0 obj <> endobj 32 0 obj <> stream x|s|]߻-llp'ٱm۶8il۶F=~k191צ UTa65J8102@FΎʶ r @3g_Bdr@C'Ug @ h `cps|c23GZhlgg(m#sw;Ք5h a7G x ImS6g rNNv͗ߌo7xZ$J :1+5K['qrUY[n;Ld4C;'6_7W[ДǯL?l3ƂȳaP04$`kI{3ټdA"B ~7?Zn$NG7oJRiι 6^/"s oϼ`].+)Iۈ4  fޥ/{|a{&#ڔJ9y{o|G~8zì8s#%.y*N} #օ&|v\*1%ͬ xk.u+^Exԇy ȫ @JB_[jk8yojѠjo(T"Lry(İI;1mTv0W)ĚN?)|4 ozykW4%;Y,}ThNK'zRn|hFsXZKK |vRL`ϱ@xͫB*W'M/]=ׇ+z]Vqc]ۦ)~'5W΁%kҦVY~XVUǙ(ζ*nOYoJ8`u^[ߛ˴fJnQb4>eoa27d lr)ջlNrz;1rpkp KZ86C!{sqS6ch3 1mM֘g"~R q&K82ZxT7 $`)X)U%'\"ug}*,CiD|b+"髁`IU-õ!s`,ʲw19 '摅sy<]Zbѕ cdμa@hkOf8C}~7Wz 'a~7w pµ6 A"G'9]9nv^JϠ8~Wd–qMB 2m)m-)3ht=Ӆ;"oT2VYakHP E a=8zu5 Tg?MBn,ұ08+23\|a&/hͲk6Zm ,U(S{ XFrxl(zնa/F"<֩ND:d+3)1}™|xvX 2p.e{7D20p_ʭNC-ejW2zѱ>a𽢡h$'WkjI*ng83?njǧ)iÙ!lwƧZeCIOFyZnP]&@/sGgX46^壣_鍕7t'։:5_XWvm3Z+7LvQ ¦FΎ jd0StwIZU)V&oð< Eh?% ]qR3W67&B磸2:دB"(׎t>:_IKS'#oA ܃@Y:>.AeY_ S`[m4-譅*<ԣiY!<~.-d5܁s2a.1y32{u> tVO>}A%*w z?kֵ U^aTv/is$z:zɭ})yhw\8QEI*덙%iĚ + CR8!WX0Z,22ݝ_d|0qRhJ z {[K,1P^(h sXysڮwNWL~F"EJpDW# | .^ =fʥ{I^Hqdx;s[̬?U"$4J2{\, ZBYe:C=hyg>r#܎UJ -<"52m#k!Ҟy+.PU&0x),"4W@+JtA.6Y n-L,x&=U4KXhSqT[C~{k}&qVlfy oئ!H rcc%zҭڐ|䅐L=+wK-c`L^~ ] لUƻ8C/V& M{SJLHfKqmEAu``:MGK3`f\&٘PKv'#yi&&|'x^&*"4F"FG2总|tr U5yQNX>]B''Eޡa_0Xh,cyD5"--v^I.J@\jf-ukaNCA>LΞA0q#ݍ?~jy{b0@H)I@qVqWoq'EC*5D 4 ʝ@%kP..~${Ԥ`/F%trULR>N<a-y<;hb}'̆+ll+눱$ʥsڬ534..cFr w2Xa=:Ac,`|(@ 驩GZbmxIH݉z2Luko~x` چx s%eti?mpˊ<[ER|3Ndo).nQ+RBʹo_4mIamvԕfy7]K3,{$* eo~~^!/?v]CV-\s(H}\|hU .f, `HY.f]9`;!JUIZ%+f 6g:9P#`=s:ѯpWIv&q%- ?W*ןWNo#RrӷȾͬEF0 '8iUOeƞ0G&hٽ>#Z9yTzhY(V{+$fgBPxJWG6aG;WExNOQ9EAm5 pzf4\6*M\waGPy D`r̞vi54>N[s'ԢiM8jVPoC׮_3 G8M0y8WJ<4y8VPJcՐ-WUN?(auGX({3}U,Vf̊$pM,UmFxŠ'-F cmWiE<yWnko֚ٓ GhBS`D3oل9bP䙊z'3#iVL Rz յf']%UR":>DwO3k7m5achl(4#RWIO|9wl ;M;ج/v2 36̞zmm @ɿ-25ۅ%'18K3rNDAӪ^ v7IB͝t Vx6WNe[7hCFeSο%KD} "SmnhwM?I7*Jz.rRMP`]PMB{~eo#žu*.C)Oc%41F %ˎ4hKlq&n {vӘoT`cWD{"Nt`& EbZ"e.iNhm u1<HAt|Nnkq#E?;/Ph O&?UJU 2'Ku{hvFYsw۷ QhGLBv`!~:ā_͛E 2{r1GS\jġ:FA@WN>X⍨QS_^븍D^]E eO8v)_*0y-u;c.xZGc]| myuQoΞQMRwߓ j}ݸAhJϕG!AU$lG0O>seV SgL2%N -:m7nR;zi T89xTOQDN\KI r"YQٜQBIz̜:} pJ<B`)nBЅc}<)g(gb#kׯs,H(RGYKyr"<፩QD#mލxCY* ?gZ/B.Εj?>xku\'U-Q+K{0d=M-GgY" [k"\\2yӝ /CKaU< _!&sѬq@F$D! t9wVa~UHPWvfڜfMZIENI_!Þ>0q4zf)*D42_4rM< Y?5sT=ɟeo#.?]a-"&l.C!2wtKp¡ YhZ}=͔/Rs)/ sLRٗG>:b#$9~ozWŗB@ pl9G(I 8̍A1KڇGYƱ,#H)̹ >v{-M)vc f/znv KÊcÚ`~BqJM0,G[;5Fqzr)(uA!А~7M6he9'+MQ-Yzp3TM*Iٺ |EJn~11燈ZЩYl>=:kQ̫]hZo@?u֛VbϪpTV\GRԘۥ+)SHDە:r\ 0^lA Dr8%x0HVe=50c&'fECFY N!([ Ll)cd58`fi6@n3|%W͏$62>VþǦGPy@:ƎYXbHDJ'#,h=xwuf8IVza͟T]JqL2%IyYSL4~}:׶X<[j37|:'XͶ8-+2^ˊ SA8zIlaElWiQ~%$`B[&Zu2e/R:bvZir?\˱a7wLh*Z~~,|($2J(>" ,i9Δ}(~ i`xFvRi * vwZx~ 1sBIU-`x^oV=Ԙ*6Gg&8 sp$iW#P61Jk1?G)[7/ٻF : Pcǯ-;D=RkgZOgCL3|Ҋ#A}+-R3G Oa&ΣjAKQ R@21ǍH~* WK: ;1*gݶ *sPZs TkJ2ZZJŲ@T:eol/rhbS"e~(#aKkY;} UFUYs&ŸN`GICxrsoF#ɯ1 ""}~ ۘņ,{;f޲UmMT黛D1ˮdl2 3QoX[R3X@O˻DyQceFnXCa ;ʓ]R:24^ZclI^B@/K9^(|K&E4ojG'tţUL .s2fDSX-0S.ŠϜWH0@ug tm'zYr$|N_m瓇[ WǿUpZ -(<7@b´ d# uuWlm͢рgMjdxT$Y ։bJwz%$|[?P4)}?8"2$F skuzRK4yhPRO^W߅:Ŧ}Ԝ"1D-9O$`lC]L|)ao5o$Ȭ?-s LB-gA"%uYzEza]wAϕ-8#O'֩ b+&F?Vv,{q%F_: UٓCl[O-]({Ik'yH%-IsjZNـi.3iGo@H+b+)YdfD,voR4/g!Ƃ|AvSlY86`tG3Qnu:vT9K+;b`oj]e0{T' 2S&+{AKWVa2[K=F~Q\[|B7Cl^*-Cs8'2Bg7W& -_[Hl ̸%Rn A}mAZ6j#qrH9e2UMw!.*@rɛ^KbA٭9]](JFT`;2˄g64"dl/Z0 eS=\,h*go͹ٶpq~w3 .2+ઞHo Ʈ,_}K+ K%{H,hۼU_ܰj9s6*_•#mEU߇l-w/j>Ŷ4FQ XGzǁXa\֪]7֭f k<YPx!Ku6!uPs2L衲~URպ;`(*UN>Nz;>jo[K]*tE>޶Ky#']ј3BHY^Ud8r\mNG:x2YGZc\+ %Aء \YoW([#r>79?kVe_ʭ1'`mEbm_PN)4$QiԿYYTeCZfv%N'H$Q͵^!RBG86 Ƀpz1q!pS& ,GݱDcw H/k:Y6~w1ʄLiaVh$WcςӇNdh}|<J9&8 [N߅}l)qɓٍ6g %RӷwMy++Zm H"H.m(lZsTT<-(l;1j躄P!D#$^D;]'/Du+1 8Şo훟p?%.e*?iqv؍?11/ُ̕$8BgŔa*|"!d%5G5MQjLJ3:)ʟi-RIh{X|DϔI2gQ0׻&ϕ3@2$p&JEVԏ*S߱ pD3Zb| qn'cFRZM Ђ" :6ԧY!ct`w ܴfW0F3?]T(P$%\|\1FIUXӂ}fWp@>KUl6muXz8(qYdeo@)q5FkD f2Ao[ &€.2#G Znc:&.ŐIoC8^/ydY+ L褨菀]o FDZlSG쁇囙QuΔ=Tey[&tx0WvaL#|uwu+eێI{#1*Eц]1W vЄqkU7) X˫+'=Hz0TCCS~mdj o|ڲ OE GYi~~{%Xĥ_`mXm=oGr*H,m{^c6pܢӪ{Uʩ Y'bAme*␎^$"35eрoA?Ѿd}脦(V"Q_TO"Z#)K@D}Fmo pTQ/PG215[@!58Cğ~1v0'z5vȯʮm*$zB45:BDži?1s⬑HU&刘v%hlY mɾy1nQ/G!]-[ =?uksEF e3NxGf { 1;J:-%Cu eplc6}|Qƣ[Cb|:sOo앷&T#o4)kCÒZ/_5TbӍ]=0(s'B`)w?I ䷎!a/Dr!ɽؿp/. % rj8.}+y>5t+1t),sXS,JW\x':ʼ4`sK*#DjsC@ˊ!'2ۅ)Tם5Nh}qJ"R"ҧ2eOe&S}aVi7I]a~8̊I#Mq/- l[bbL.7A!ne?ތ r3uGk:oWL=]*۾=M)/55L*A}m9=[Bv:mJYȟTt~|QL#ywd}|%U>) ;u,K$Ja N,r!l/q0qE 0_jb$:y 8s 7+#J7 hOҒYTEFR[آ^>j[Aށ.~sLxPD~<"su 88Vۇ/hunnV+ɗ vDٽo~RȪ58@}cwp~>Ic{䇽Q0G6Ta zՐq9_}i!vMS m$װ0vD_04 NM,ʤ'1ܣbhv1mxkܵd46M` &&@^;Lj8>2Ph@4Kg5q<w}z_@b Qo?ߢ ]!YDfΤӋ,:_Lf|$/:d>S˼M 5QC*H{h3*Ejn 7pLgŀ SXcqĔt,|e#YhjE'T@ҷƵt;.dNVa%=OԟAY9(ޡ^:Iob?Zįb`qCՓ!u:偣I̳Q %J݃o3#ty9.17QuZHjx>k-*c$⡥׆!h > NXB\ÆqH߯v/2BiS̋ٸUL^=hEb3/--{k9[%l@5)~eR>CLZîa^/nk#͒ۼR16C~7_/RR_XLQuTyzݻ-݁ /_3*gu]RVfZ8HwuOnrq"paKyCM:?6~eޱ8 ld]}j'E6_fSŊNuO0uF4vSBG:1y1AˎG8נԯvPʩV^#3M4xM>d4@R'rQU@RMTؑ 5)De`Ov^IoJ$.  1tt ǩ :Y#937͓0 t̚DžX)<6FIN9ĝ{wxK@Mڗ5 6:!|2c߆ƪ8 DXolyaTDd}m*$'K,dnxK-C(vCP`9YDOtg]m#u$|R'HBMx TXsƦ"=(@V~&|=maJvL[p<,g7os|R[ _T\5La 0`P i|Y%9F'4PQQ2R\a><┋i>{]AРW~,<DZ;'vi;sQoGmC1+흳V`G-+~"Q`Ɯ޹ltUsyyI|*/>ڸ?R :/'a&) !&mfVxP~yeѲ<;ÀhZj6,ĶkW5Xm,-BFdGPP0ɾdlU xiDGLaCN|cof /[/5=Ŋ2(PD |HCI[ws/>!Ky2UaUީ>ZA'Vk8 [9}Z6&tܜH,^X&*&<,H9Xv2N]j:_=(Ua* MʱU7M1 o[2o" nd4_ KtSYkȼG*~0ÿq"Qi7kka@utElؓ|j1m؝Lrm9&)7qxٙ,=khbZypyڮHTZfmфw*<@9 ;7~*Pԭ>ev|"ϳkގg>u=> > ${,p ["U_Q L\s`5}l-J @4dưB$Wo(g.s瘃vQ'i->|+Q B>_wF}CE ێw>;hU&l@SVf( e<89{0IPYK_[kqD̂s[ 2b#ȗ+x??w/N"Yk`#9kJl"_\yH[H̝(Q*;gAg.5|-(-YNCqYJX7 8*!9hSʊlzB g5jhV u5y x{Σv"'BV.6h!X rş\И$`b.ߨؗOW&4A=JY!J}7K=libg C;Rv@#VNWS1gnw ":S3[3@{O7M~mvWsbc@ΦUqS4{Ew%lm-#gsqOՙghX&0Ki e>PiږycY GItE6 "ܬB&&=iYCHԷm!>[=Jv"rHԯ>enb;h-]YB| #sXCmYݜ9F/Q$s1G}&UfEmBK_jꃞgN^gjhD#U O|wȋGW w0p"耓5ZDaaciBEZ3Mibm='eY.] R? }-3 jM! ?ǒíqfU~hw&,k}FC a7qN=l!i߀!SMOlg/txWǁ;3lnVodt_r&nŐd&X-<`!~R"U* ǕEC$Z2u2iYF"Grض`ozdn[Bťcv+X G(U J"GN3^ %^tm]<)],SF+ml6:LB$wUf:sFrE|ɡj1/x.p!+W*t7SpQ2`Gݕ%\qyD R 8D+%ܐU=ODC^"5CZhJk4X\O[>'T#.\JޜdY-c,&PEa?AUԇݭy&5]Ѕ'_L^ov?tIxc蜪4qҶ Brs ٮy竷^CEbywjY˶Wc\ !-!D6!<H*g^rhSLgvjդ@ 2o S0r^֓Sd^E( y $*w/ w;FyDp+7[<;UwiH7p?U&S* 6ha󋄭&jŲ%0|kcIwС74-HJIǣ6T՟&R ʱ,ϒ^s,rf4+GO$wnJ!iVth7J:m=Zs_Z5*1*/}ׯaIۢB1@7ȸ^$DS]~ъdCbvőRims RI?3ic:K^}X5>Z9N8 1l5:o.[DsJ/ ɥ%e;Iߍ\n17C🲯)vrWݽx՘D,dK{@$iPR܃܎-FZ)F7c-Rff]-uuq=&3c"I |, i[DFu<5f ܳϧ{Wt[< @"cy pJ) ㄗL{I90 Œ@ޫ*rD?"L>{aWX+9OXPv (J"`Z5a?x#?k7Q.6(=|Nˉ\""tqQ#kɝk8BJ <_oO !`枚g.8̇$jMNĿ-@cYB9lsd񋝧vJu>˥/PU9nXhΧǾD ix^]cNcSM!~ʚ̅QFt0uH-2Dv.ty5Eg ]>slHQ[toQ2!{ɍ]E%* 33QRa |Ln -Z3c<*_̫7)/~w$,'Ј6Ȱ9MÒa#N贅[6#qlh@( s@9SIDB WA_ aB4`vۅKbŮ<'h\ʪca2'ƔĘAEQPC3n$Qߨ8-9YD~0/$fD/j{rc^/yU3FK(] B#az1Ӥq2Bm/2*feTGYCf0E] o9C+ezn |<% sJTצj(ϼ_7d VX}z^F"Yma఩=̦>z87=rüc`yT3U{l\$;Ac@rG:- l>&Dnk랸IHy VS9>vQqk[yMɋ=1&148Dg%K{Aٜ G]:Q{o)?m{ކBF{ᤒ7sAŖKZsa(?S% (/nϰoӦeDѬ4<1A&PKMϝҺ-k;vəDŽjYe׳ɤ"`-.=x-DpH0_jlUdTXr@$ojG&׫*QǑlŚ_e2$A\S\'Q%)4yPD_*S,;Eh/X8v}*'s=/@"'O\CBޡww%Q$n==xq?Bd?\V8ڦkۯ^>'C2>|֮N5@:ͩ*~ѭ?ZnB YjY4:rsv|cD`‹Gέ-G} ǚ⌖ ?xsd¬)Xqylݯd{]Duq_B7~.H{p,}ċ J/ack* K[/QnV}?oۑgD'>̲{]VSnNNdцxYK"{{W!]-[/sQ5u,3B@N`MlGb_^+>WJK<1$7EL'as.l>298p38< [bc.HNRZ%ϛG9t= Fci cJ>_$O]i[0^/GcUI6;A]w k_G Oޒ4`s|;{¨`RL p(;A$c'YpuF֖ ^m?"LVz~J]Z@8mI"Y o8Uځ&3'7ɉ: ZlL*/ccf絳:H\y^8MGk& G!R+{&y.@XM$ %ƛacT$_P65_o+<SCb)QyUJ5麰x.aˠkT)nz4 !CYgGs:V"D@kO,/$Նɍ;-ՄSFGV&g%+9>Kz}oJ%dtO4 kw8nxH/jO"YՋ]<jy&jB& ١HH@L !8bq?s~ԨD$8eZ~У&~z-5WnH/"r]]\¢37B5ۭɎ`K!7(*I$ AɶɃZ> 4-rE-/;Q`Q6r 8+-a>{)(vّ>(FpsAk(nkIEhԸ2Q+oL[åt>(^lR>+i0i ̶%)60KdJ,ae$4vhr7P(vcAJYϏ/{Prlu$Z9R|)Qh'zf!H7"d)r8{ 3⮅al6k.-??\N{Ũ?Wt+~E{G2ƅ]g}UTR mQ8ԛ\_Xg"gQiQr ³#Tǣa^eqTym1apz â S:U?Ysm OEW.@$V|c7XߺO80&J!aaWa$ܡUjy?SL[)㎸T-.jq^VicPsJ/;㷡Poz7ȗ١'zRTL[˾xLTS) 9@lB3L`-I\ AtorO&NyuUYz}bz\ @u-C H$-k 3R:g\(eF@nK:ydDA5dX״_IՋe7iD]\t0l6v.yX,Nbe3f4A"Lr&3virM{lYy4 7ѫ#|LH}Uhi~ƒy]@%^`zq`J]*"&pf<$7ç庣,2v!~hUyK(~p0vuZפSyS#x,2S`XtpBzPАOM{XX,ʐ؟C|$+[-J67$5ԂT+;rfLyYVѶ:~ˌa;cwbssC2u$UQ?n7VٗV=62Yqt/|wK6}MoxO/塅M, vx Q 1>{-LY>cL[ߤs1_XƤ5(5#ÝOy3]] *~ (7̥?V]#Pә{(6IGW7PhX[,%KUgHMAmUf gM;}.0!‘{E(rDYƑh`Nƭ#E6A{q BE<MQJ@v PV' SyUE?=˟먩u0zA$t/aqALW++di6X$U%C rtQQDCHʉ 6!_n1[jwWVv@n>! t_M*Pv^q }Y {#xTEbiv I naVBEBfB],gH缉98^_S#&Q`Ծ* )˗ebٮt8'! kNU<iT{I)CԍQ_[N杊ӱ97i/R zol;b@H ,X}N _yU؁`)xK!7符jy7F+d _.4^")K_ v#_s ~(ǀP&ШL*Y77)^c[/dYg)Z1hU](XH_Wֳ%<͞2%1&o gojF|jOW'-qCV~ J=Wo&y̾!!Y39 NxJLʿ0 1 &.e_K}3 d \uzl]BX:̸SL|9xSXjm4[}]{.)JdKn=>d-SˆgP7X},H '>ߒxvB˵'̆&`=jՄ{\?(D$ x1Sqe^hFH5!\p'Nc|gNOr≱r0vm\NW:ZJ% zїt{"rZJYaڇl9Ax[oGX +u>Oǿ?nlP#~Kp9f_KHv3+I0n=bAO4R7ȩOd꣜Ң#(eٱt #Դ$&pm.W].Y Hu6^/× ‚hJq"f7cJ!=[Q5ا )`+18C0J)L|:/l2oyS- NT\|fEK=rR`#ɐKyJo,ݧSf"vbKWN-3vx1aH34Λ7~6`;p-ᣝMkC ζ`0*JxQҍ:\x3sp|{>%yP n'f}Fuή\pZT  ̍o#WBj.[iǪ2 ɏ8Jws^ aڷMBV90me,:Ic 僬&=l9Z \)~[c*VPpKzcJPka\lhcgCwW_Rw)!L=?GuI~U-bwMic"]yJ ^m4MH3\+y&ҷۼbs1f!˛(5FTmfn[UGӦE'jkz6*ޅ`KAh\uLMB@$5VܩyEGy:\TEsi'~$ed(8oVQ@lȋj _A2TA sr1<d |G2\YVg+թ6䋏A "gFQ#'g%Ýi=Sb]#ǟBu =р𩬽_b^e\3-;3ך޲JLUDJKEbNs?jfUdž-}!G,JN| bdjWgbz{g5W60l>`Ӕ+(ys[(tM%(ծSH&c@6@\{~V_"*MT-!"oT /gR3zip$%qΝ@0H_HIq6ifpI3D8~d.AOLop3Rz$)-jNHY}H:BMY"*?CE"!mQgl]I խv/ `ҎXjy"cg"jSSh%X6&t^TMK0U-R/ˬ Ts=#Zz|`S:}b %5Sw?hl-`3X޸n- 9?VK;gv6ds[`h4 H+'HogNefOx{)r JINsL"޲׸{ a'lyI y5IDٶk-;ײGW |qEA>0**!!mZsRg5.[睘C`Pݣ6J꠷U׬J@2ϔPG`osվ8¾؟sE0Rc:ψBxJrbb1'Ni־v*%pw:`Rq짹ѣ(Z= .пP5Jp^~ fz)~CP}"5l}%@>g(!ȋWL5Zvy-@P`UI8#(1Y|H5cx$m%cqxL'z#)&^$fy,F!-xud]}}Cmnծ*G)H!@@Jዪ 2,OѣԿܿGh[[,{oAvPzPZD=Y Y\^{Y)clc^F%$rXNQTD[5H)@ҕ!4JrAX\ ɗdIeHK@`*HFR4+[+A'p cLKtl"y"?gL| f4q$WbaId E hhP4DV9f0g)zD_Q 4Ỡ7d!Is~beWێ; JC mL(x z鷨QZ;MI_go<&$bc+RfSXcbbrϜ0.?Gj}:NKb$Te Wd\d-ʢ$%"?4/>Qkџ,b(bhݝ7(=i]ڇ/ 7#+bv  / `>< IO$$s}NJĺ2 Cef4T\|@NW4uZpōyYZNobxB/h_c yz>[ʡsFנ%%E\V1D(aI 9S_J2I/Hȁͅ %ؠ7zLlI_9=B(ܩG}.:鰐#q<#K`94 VT֜o*8MߙԃBf ZY=!LȖNH<(>Li` lR-Qn֕,E_5q\e0}lD܎ B l032X۳FUxwT_i.>{+j+-V: $ۆ{}AҴSбM wZ&4)@|u$ǪekZ`o͂/6#| 9x)(, b]%}ڲa˗SrӃ2bbOUO/ O 2pܛ=I,- EPaw杪wC,KbMO%(< { 0ir`Z# < #}.vpbr}'ijUc.+->Gy'/ ֫7XSyN(NjM;).p2Ly@ [ I]by6gCAX+斱Zomf+!xQ4սY3 ?:X+ D\3Wߙ]D,.)i]^)H3 v&Yea2L#,,I?Ǯ[/C7LZlNo0Up4`~_t2&"#-̈\an]~NVf(ob= (goha|_DKc>%Zl,~Smk܉ tk/&n] s`I~:B(V܉)@y!cP覩&~ѵMrRYl}eu1<IG#!3xe9WI$JzȎ}+>}י.M9s^7R<$NOjm7r׮1 {Py*'>'fd-/~]w 7*پdcM||'U\ܺF.m4;떽RU;/U?"I9D`- z.^Ҽߕ ;$p' ]qR5~m¤Qo*!e*R T3,JRiR|M7u6dw{ ZI %ll[Ӕ| Y{vx„ܝu!jmL_&T+ϫ>C: O(Jt^21,g:Z*04ewx): 3=w 1LP閽?}!.B`z&8t;*W)K%o-7{Hܔ 29 kQS: =3RxxUP;0Ez"Qz@mRw'uGewr3G~G&&3G#hX4wBAB&5"(]9ϐ{0c=^l5Q7㢋VM3"]L5=tH%lq T&:A'q ,ˍ]hyQ6e Os9F8ն<{Dp(LtL?pI,·.`Rα;t\̻*pƮʼi9[ }vuͽ3Hᵕ}ǑFO#n=MixVPhn62&W.VX6fU^qJF"qKe<$ 4$ i, ߑ:GocWc٨❍@OѤ|s7G]Z9\ _V'09|H1@{LJ}/-܏Ǜ5E2e4\g2ِs؜/+ 0/͕zhb]mDT*?̲~?"w ,!L;m3Y;1ӇX<<]q6^j@h }vgki*AkSsX{T+c(' @tRB("1?]_գR Ӂjg\AA C!R~ih_S撬=H+rAӷW(糍 HT\9?"Gsf-Ʈ<=UWߴgUp(^]ȣ [9bW 1-" %e5 @;=k[塓_5ԕw<vopC (mon~p#a/@;-EL5yQݠw@@pK`Y/z?k-8qaQab ͂ɓmZ 3<`ƍz@+w?t~h$a.f-FPobsB<]iz#l=&[FX 9itώj©IvIbmq.ZFԠP;KzNġַ_oW)͝z7蕇08'{Pg+6/y[7jul,UtO~aA;6Ro0Z> ;b!q-6Kv [_ "O\;5Xȳh7('=3e.ŀTмUNUv)XIֈwlZ $ڹT:ag=5u)WO w2"yo x;Q2-F٥79q?hńͧ{8[ɤbr7xiFb/6zK$İ!ƚUɪ0q`d SK'Q2RA̓(\c)5rn]Ry ͍ݳdiR.wJxȝf{8V018ѹV81n{U#'fb# U=[\7eܚni̳AO6a*[kΈof []z@fZ{/2uNSZqm\ep/|]Ujѵg1ҼVkf-v'=5 ge6<ml_2C>Yl ObT3d TOshĴv@>+I͢LJd u0EYq¥'YclwRsBEo2>`,=ſ8ɒP|qHTQ$[{-sϠ6_Xmt  6Q[dRӹ6rE‘pkqNRI.9ڶ 5޹nfn#\q^O19I; [V,ט g?X#Re@=fGaC.4"fXReR58Oaf*_8Ֆ"o$f S̎kk3/x_=g ߇gu[wCR}?i1' ("uObXTX*J12o|Ԋ %OAt?6+ۆ;w ;mE :JOwsVp!Semmb`!>G:y?磉p;7t=!E^Oh@ܕ|d77mז=]W $Feo &ל" c> a|²o?zPց0CDg |eB`gQWpN8T;A2칔riU@µNsC<=Ċxq)}mlGSx(KU/F6/#Cch!քI)8f-JOmeXXq`)DA l겼F6aE~u%cm9.VoR9 3M''="T\z:"ϡe&PgON3~RyH0q\ݩw|QL{$MڰB3-Gϸ[˺ybTC.W.? ᱕a?% HM?:DD?vxida*Sb8v ~\5B{pxfLT۷+Q M[2T(?bl'yH* "!,ZK80C2U0a>J3Ù젦!ʯ Ĺ7vIT S2r})[}H[E~R;^+/CPf\lɂ/[Ub9qE.Rz/`'6[7շsqxm-fb|s(O!*H2>NxqE-?Xyrko|3~,Ғl9Ѹ]mLx8s- J\8zٽhpD.9eY]z)@j_rQ)_PeKD58p`] "NZ&oZxEю*8͔erc2޼{]~{cm28cHJ{Rp8Rs*2<d !PD|iiM0(>8)h':XMk94in̡`IJXCÂBc?H7сQiԒǂ4yHt==퐸l|GIK=Ipi^3~8nDڸ'yH,!횷t.ASA]],a~l<@`ü,S%|W@ l[b01ٟIiVp ,"M f b'؍DWlR̗Դ _48ɱ+skj9)9Io/P`[ihN~Nʏ 9g{MfZd_։+=g۸Y3>Pe׺0}h-qT)GsxJxJ x Q5:[sSsHCTÂyAs jIl{;mYeO;shQ:703@Eb_뭵ְL:ͷBkqDS' 7~˟RKMgT^4^OD8Z?w4RFV\2GS .搗^rotLfcX\! w4yr !@Q@||p {(зFf]ime : R: :ÏV_bw+^’'5Ř8IT8#IX]mD} |RU;҅X *rfL nd7foϦctwP:`hu{峆85/>DXz­V8]?V=<<6.O ˕Jg=8Sv]8*MdG'_6:Q<3DF#G8MvSYR %OT𠭂g<%D/P7PC:`JSo9%U@P  "֥3D? hdQڪT@miŒ} iYq$|h"):Ab_\G Nj;YhkH&\~ܱ͘fek᫽^;@#U씬f놎/HyRx㖯Ga[@dN/Fc`ϭlp߈pʛo3v\X;^#Nj^>UۿC%O,8dQc Og9@ !d޷EYf{2K7b,(3+ć6xuaSu|o՗<} xQJ=J|D֋m\50"\$#h1u`j :ίb;gSexqfH ;.@?Aj`-8^OOBҎ(ȯGlK u>6Yl_A)g{G7;Fn@exy ٱ܄PV|/zonz6'_A [ h@m갳0&?-{[eU֑A#;[WB^Ze>hUY*`- z; اUBH^E9qi WFDbeΥۄx> _W_``:Nxn&QsURf#$u;bgF/p|vda5CkV>3'pRގr 7Fo#pf DH wfu KUt<^HxbY&Q('gٲ}ioyrgk#c\xkvH8+VRTpU{}7=xB^{*0)pS]ZdjG[ jǓtG=F\n8X6X4Ԉ M/tM?AvdfUqS8nxN`c"sK\vΧxG7KV@0 PB󮑇4w'8ɝfuTpkv N`GSGEy(h5N퇠p6e o .؁ rC_?aC;)rRB"ޑG oj[2O2w]c`'Cg^13hwLզ#45Ln'y.PFwro|@PҀ@Hra 05/j8ۏC5:# ^\LN*JF TЃ"ˣ𢡄d" U73cEtZ+W1q\͟ctp]~eV1azqJO v 5ICӁ+&&%GAsۡmQ@)7D}'r-Y렮vb\x>%5ZmO)f&Ql55-6A) ʚz8_, pX?h~HeM$'@oFPMb=$מؾYepKb׊?l)0sՎ}Uڅ._o:/&J*_zoʨt.MdE~~ 9?y 0zǚշ3(ɱYx r4œ&vH|D;dDtp!ϕ${Eݍ(WP8H ~s2o4ǫs(cKw`Y6&]2-,!`J܅׈a YG<̜v=3X}l hQIxLj6n|t7QJ ppր~W-NrC7hChoI6CvkX^'u%b:RTٹ>=,}٘c&WNAb(F^$ {& ɔ6."^ŅGۧ4Q,rRYc{<d&GW $SQĺoq`]ަܢ{$[;|;~|`[m",;؅;Lc}LmuBp^:G*g^ A ky$G.D"+61IG'g_to: X#;l8%~TD㫰m\&f;flڈhk*?(T+CpIU^lpS .ϓЩtIOPBK~,xR] 0Xp7w*zk{QڲDϓ_ۇKQZV^)cSUT]м O-|v}dUxƭ` V:p69> Z۸n =+Itsk AFـMQ!yiz9 j"(*jXȭy}4scysv+y=Y>7]{NJnHgWi[ HN-G9R6m)ROr6:m6`G.,te%z@XL+aΘXA +/F2K{a3y!5ϒo]'A #C+-QtYdh$3e#= "c! Ϲr-_ܠDմ}󔷧gНD%촘0+.fi:{XqǍ%hnl\ξN:1x8*g.6R92nˬEIJz@oln{<;30tt\g>k_8k{YP H%}AnI NA5źV\긁OC~Mz#9b*Z?νLy1-}b?c_ PG^wb(paXbfrKU[]xSf&gMΤ-NĹ"HXlɏLgZJ4XeG'T-0eE̦#oUΧ%P%yObei!xr^7W0 QrO bc9UyxuoFx[1t&$MS!bQCեp #ZSRtÔY9D Db4vnǞw0i`@EpbI<'_"2;$,f <{:f4iIl|Q!y96B5ojEB*'c5c uډmL^/Ķ9hxR7՜%D5jaJ7Ė?GU1gK)|i5p_Q cN.D O;ٓ8B$cec@jC,Xlk_g]*)H4ɒegub\-sxloHDB;K*.cze$ >e UX>6ʊ/f$\SM"z|wr_A\ ͽ3K$:dq$:ǃn%Ȥl/'dxj(d_txڜ^`"FsDWs8_whnaފ۠f;=0!0\ D:f\mz tet%hϧTkE\&NB2BCB AsJ=s ηE5V:S0= :wpS֯KU"s;gW R3krNsJv?xэl,'|_D1TE%کZtԞ@ 0Ρ\# \| ϩ"'29`1Pg82†}}bjݖFN O sA|5H7}\P*keG)H|԰, _34r>9i)MκhCZƕD[ȝ58il[ԉQ^dYh5ZX|J߉Elx1SbYk\y,Grg< n0C_VWiݪ(IBE1QpH4lhY)IDtdcM䃏}o")B0_WZkDBexX,=U8ba1eyP(Ovb,4uZGu͵Lȼ˘05[9Ey+.?nNa:M}Ewֆ7LhKf ) <,dW#; uqaD+K8Ft?UEUߗc3u0,u+3D&hh3!He t~ Gz.?Yo XBجW}!4SQ?8PI۪ Ogftwe#) CpD1qulf W:J*)X餫6\MݜaTP޳Mσ)||APY:dy@G.܄3l[d_uCSN銦R:pt4O轃TG]m7FP|L dq>`,ulhرU$esӟK4օ#=34:nC.gq:J]iEVus ]]IՂ yA ;Eroi*A訲 5X㤔qoOxp0ܰD>E"%OGa~nDp ~`ik?+I8AP \OɯnкiUph \@7/3c+=[cOЂ`áG)P 3*A}IcJXK7H=O1f,ɗl}7,,v CZ-j'wv&{#مo.+ 6hӑ].hF0cOdc~ťEwl9g{2WnL">3uGPfo Ќ\қv%@(4stUbKKèHuPes$n:|=2+DžQd䑌H=剌䇸NW@x&q1$%A6yQZ]Yϸzwl V9!޹! Ȝ6u=F="Yg.8Oufc<#Ǝzws¤Da7N[ k)L^9h}H!iCZn4!8;]N?VO(?R=w)J/4W*~$2lJ#K7|t=|E^ōCq~δ';l):~w<]eݪsHcJu5xgq M[Nvۡ-N5 wqZwmb_0ad-`0*BJx K6Ώ_~\c6'kR]?4ۦQh.0Dmcl B#Q2&C¡T{^ZT|[X\ƒ$#beSH#el0#XmhsRe[&asvc =>F!Ys\H'@O?T+QO"r$%h _&ˈZS! " 6x) .=YYC|V%5Ɯaiu̼ MδM9)KD|ɠ4;Pƙ*,JNmMD$;S ~=n|k4%d.mދ1 :å4sb 14e(+0HNLA5٨iԧ <è4+3a<Ԅލ6R4aD>iR@b 0zUjeԩY3]͓}~TҊ$\T\cXuug/)+7H`,LkidAI`q 8>W~=uɸDO-lq[x$fnb omJ t?5sl`nۭU@o&Dwpi=_ &噊mIsr&d%bҼT"AҸNb.$!f\!*JB,Y.cYbM1 ,>~lEAQw}2ͣ}@p]oӮ[:~#eBo;(n -p5{L=w Im-ZojB<,5}B@ETWjjGYG'mQ27zIgGO%;;<'h k 2AWY=2)iW)γs4(3r0x:k5'b2*~)H mNaOa9FC{:neB+~1RejVAǯ6xpN!@5f -2$͉O:1qa)!ԯ>cu=eǽx[T=RϿpF<۬zBwXq¼|.YwsGpXUlEγ-Z>Y(2Ȋ<:7co͢mc֣$ѦsuLqMXENaDעt+6L=eogFڃ_:*x7!9k}؉Is`YVNJB/f% ۩k{FU#!Ci.'sEƵ2{H"M> -;:f7R^XwpK˔ ['Оj/kk: u$V` X~")ӜNm}P EyBIKX ,8.wCzGgmE x c(ӊЩ{oq`-m-=lHJ#J?([)&4z.*q,FM$$y1H!rUq"[a+(a6iܥ7tkN-sS^x;r/ggZ ^5Ek5j{3{V1٥(.o<p|dR6@ I>o!?!@ld:ݖ.[*<(|.%ԟ :*4iC+\kgpa>ʹN9\ -zw>R]r}C؟ށ-+`3z˒4/o'"(L'K5>̖0 'l}MV/4M ϊkP'w"ȢyJ.hvs*X|2Z&cpP_4/L}n0ihv'tҞs!y`f0[]r;8䀡ԩxN#x`[zjߩ0sIjcԔ!0!gϳՎcGgՄ!ǫPФO^Щ ֦fYdINf{hQM)'x2ːac 5 #nVIլ&@9/EP0e#GbsT'~b$jl PaƂ܈_ʟAS*#l8zv Y1j'"LRp>>Z ԑs8VZ&[/:8A$Rk9x.JYg,ΠuEa5_Lڑ)棑\ $@mu"`B1֘fv&ԠL&*38kVnJONIdƞlBBO^є=Wir^2į:hwv" Yyr5frVZkb?s riet#L`ZEV-~f-Ƀ^uFY73Cާ(5jI )ҕ-qU  G6Vj{PF^]SE|khdD$/m.)`Y}\i=uf>_Of …"w&QWcw<~3\ ۫ѡ` nA谬:8(sl(i #?5B?n;HUȀ@pҭg_ClcΪ!B$JT6r4巜M3di ]W*m5EQzL:Bo2#RDMA(5 2R\aw=|b>p ӓjф"Q0hf6Oȝ '?D 11*Fai$ *_(;xU&{y8j TNb6ٍͽ+#Bf..JBɺ-M8fh kԍw[DmI4Bs󀲓?la5,| g. ް!tU \e(} /oҧ[R:=]f {5Z[ߨhȓMWb(_&51 zO=@üܩ^ -SX hܢ "`3̑M{W)<# #b֚V~üy!c.i #Uߏ3[z{/ᖣ|NC5 $&,+)6j=/0Yf6Isw?Z g"*ǒM絖ji ,u]N' FJ%$Z+XȹJ,U C%3tHKA+ߦ`wاvx(ϐE ..^٪jLk HĦuԙڏ ӟYmAjhϲ0N6tH3]y.>*ڥlRr״N *BfX ajѓ%PI Z4, Tc!zuȊ}U@WIt~ GPj]8tb#-Ϣ:lK?yf#CZNžA| .\jkQ|r~\/1t\ee}.5՝\Rz\: e]*y|cZAޱ@\|TaRm``[1ZEipBudyVEZ)D+Rq1,x8Hė#6D  ` }NJ B`-E7rlx)$|0QHMmw˨k`騜[|u;5ư7O!*a>*y}3^]Dln'LkfɅ>Qscñk8#zw[ TlufVTGj}Xkꥑ@g>wr܍'`mP=`(O;CJPdZ"W)ibe]gwX(d#X/\%"Y)D?fv?3Qh|p.1eU;`xε!$pQ bmtE&n"nc*)x+k:9:z7c~~jK3ot_VUd |^ W/OM?繁G @G<> $}'E 4nc~, 1+ut@IÀHs1͞g{ VtŮ$ Z*%׍Y >FF}jsH$YC_9cSQ;vuV#8W{nR@.&bzxA-7lؔ107ط#\ďm<[cPP#O' K2֝: }= $`st\,YoGxȺE+ll(/Z5 MGQZQCL*'. ۔΁!w& IG& BwoU#@X\oGt=)NUi_R(VF5gV ةp:bB{(n̰gz*raM?7N%Iq|!ꍫfa _<8BԠO·FcG,QaA%MB(VGm~u=vLqCE1D^RK #-Oۭ 1Yy߯\Z0D -}+ riQӕ=<} 2ȡ_mK #OB㲂Ǣs*X S \6Wis8尡!q(&CRB_{+44ݧÅж˜떏. #:̋Qiϵ+e|tpTe;&ƒֿA?,D -ԡ`\c@ʤ]P>^ `S hEdp&ho?'Q{#bsg`e7=:+ߏ>\ۇ?v|=m8k0X~wkw!čj f&')g Kt"$8<1B똶X75EcQ2S NC.?_t[#Ph9(\*"vZgےUQ b30\zl!`^UAkM˝i)=Dd!3Xh|ڙĒoz+`E xj|?q RUooKbQCRC VT3}9fg-jlm >c,R  x> |3315D12"=\H)ǧh>Wfs̑HZ -߁+/ʨǺnJrƑ}6}sDA򅨏(<1mai^tHǣTU{Ϭ 'NᛤԤETLd>MzObM^iB;:*sUx0Q+LuXyxX+'$ LTu'rt5RXR ?XQ2p:,kH2AJVČzlskoy tSD^0gK¶(ИpTJ# ݵBqtD|@G|VAgMq\;OLvSH(D;lCg 'H-d:j ]"Mذe]ҷH1O[stT|w;Ƈɣ.F3ӂ(ky + xF&Elw֮9dTBer]=I$αH9aJK.W̙JhDٲv9.a*m4sy!9\E׫f>9\ '} zJYF?lg+5?4KzK ?`afuqp{|39As'K""C_4-l ]SwCiburneP5^ LR%fx,WNL1yVb,%A<͏ZǙ RWoB_:Κ֎+V1}ljd$ZS}8@Fxy8"~XC -bsF S9&[x_~Und(Z4Rۊ$:޵m7j,jF/9q؞ŋFXi$Y}Qxөs;b64a[3⡧FY)ae`{Hj&1GVf^#Kz,>siqChЍDp5}$t70H2-S3adV|LŪ9LyBOVa-wĜ姿YW!C:Y;pם? hV@PMճƺq{h.8x( C{{'̮^~CGC[bDдO-Qc5ƧE$jv`(F2))3ip~܀ bn #٠m2rƫƪ5>9UZJǂGz+A'vڭ9j=cu-QqWc֒ # ٽKWNP]YC7} ڡd&%v‚\f.:afBj6UbN -OsAax,+Of4.n TfN,-2L4m$,6< =jg*TiJ_4sxS[]Wje, -}~x p OXX zzSJq Y$ާwRص`ض8L)V:|v Ni.7o V i C>qm!BxGEΔeE]+,`3&rF tsO@$-I¿5j6)c!`5E,4&%Y6#E@6XnJ ܈Dm.=$kH‚7q;"{N`!'t< c;9N9ܳ:KXE 8!1N2pu-YNƋulV !b> HWϲp w )taJY-3wl">.m’z8U^x"HQ5.xOw!1`[wrdjnMA!I;Ɵ|@u 5'rpj|NE[J{(@" r NVorm6)ZKl .B9hJWmmwSvaf&Q9.n DaB|,VEƂz5w?~& pO Yu2d~Ʀ$> 0 P"0ۼ܌eK E{`ɫlUrbו\^hB>o x Ҭ!3ї4M\*7Շ\" %\6 3QpCRھvem_GZOkVSc[nyq_$NG(hye+Y; u崅S59IY^ ٢2vU2%Z(_@y%]yL0V)ʶ!NH"K͌3~Ր6Ekil6oy^a;bB\ r}p6]ҋ{6^3H"-Ff*'u]͙иDj:rѯ2,^_paDۨdz$:,첑 &mC 7j_x.s=[>eWML0_=h񷖪,4+Z9ZyB7 E."{/;vUW$G6&S(#7"̓?2DZlr7u,{)=խAFa"Nsi@j9̨F^P)} G #At"c-o}%E~jO{!FL;;VQ(lB#-.N*d)4)S!bgZdb 5*n;0ݍ}L"orEX @]:ʖmfVN@1Jk]h]U[{d"|7ڊ hi1uNuV.Vks"!mc3 3wEB- o2 }g|oY`)3B&Ir;"$?Ɵ4XԚi[V!v7Eb7/I“z+ CD.L\:T9jJ xnY6O >Kײ T;ͮ׌ [9€aETi 3K H=I"0"ܐo^9I: I鄯zX(v, l{O퍩m2&<1dmYAkS:]V4>SӃ}YdB#d Q\ XVfNlt٢y'W]uDEw=;a3&#{;ٴ9fl)R,X:sm~P)'׽)Au]9+&%A?MܪDR| 1!ѥ.aq"0523|O}0<QΗCKà=%\e\kLSșZG~yuz\ Sb`#SaFdwqO@Hz4g)F{ƻya@ciەjSx3YPUXJm+DA ln|woߎkrt{ Ň\V%8f!Z/|`|WFд(sV WU- ~5`+.Ţ1n $_/$_˰LYkF5+>*#(1Y gm87.3}%IЛL>1剨EeJ (-95ݭ}h=6jCz<SĎabu=9K^MV$stpNQ'ޙB (W9{!G.+雫0HUUISQ;a%zAp!@asJJ%7걩Ce@ 1qZh [0Rrfڠ[g "rD1d?I=_j >(ѴF"ܚl*"o%F6 "GŒhg+ٷ Hp @7vK %ۏi Q^&chty )]5'uf,P/?0dMBFZK!W0265Ș eyyq1+Y!co H;4Bռi~Ѩ_;2jyeo!/UX [_+~>q©|pLN.< HJ/NX☡ޭCޓ_Q`*vJx\a.ֲ5,S cXaV<^̳-{$ yQ{sɁv ;^{Q:)L[q+ ?jrv *E9_;O}R _Q(φڑ1%%Gt=2|.̗wN5mW*Wa10娲Qwlʴ7M*L\}6V @6p-7L~` z5HV-nZs} ʋ,,ײ,D+g3${ 6quh(:7C1O (F~<ŷ|qLw-IWě%k=LL*RH=nE>Ov}?Qk{|]1+Z3'w J% ~bGڥi𐍏 8;w v6+5y_BnQZm򰉂^+Hq1;MN\"d)2e`y\Θgta:.3<~܌3&~7hΕWaS vFi%.a^L;y=Y!8lE-ҩicF<˫W}(Xt$̕vy6`q}~*HTpAKT ߼K%L]^%{k{T|yM-QB$|01D7/ݺ JX~FM ![?мzz Acq rj!sɚ fʮ@[jϢSH4|"/yΰ$~C'*ȘSlLQO?&}t qp!\^ \l3{}Vr޾e6u36&"*NVMde}\{.$&Gk ( EZ_JZJfW UyhK/ǩJYQ,v6NGV:Y\u:i/l.Ff԰`rLy1>? >_ nߏ7[P# #F$"wTo7vyp4,tP>0ѿ# g~;X/eb<ߠeۖVjNO\4"Hwj_P|,fUv`;-!Y *Nbl5#rO -eyBo>U輦|T0 'kE2:U!^]9181NƦ~7F4BJteE pDv--c좓'OQ{ ?.l1?<ܳ Dӵ@6Da **oӀ*ϬZ@ ?HV)NQðG"D&jKձ/)SP=a2gW72Ai^P~AM 4z,yJC\#̲D){L0>q* gS؎Fu5քV_WН,:&m0z<pERT]oFR #lsFd@"~ط}kl;'9 Erj ; 6E6ʦ.NG`1bm)Bc=nQ37*7;ap#+dphy\nU2%`?j+v0b tiL5]mC0BIEg3UASk@Bh>0vwc ƈAh<{P B&t7QX%W*v0'E!w&pږăuq{G퇝娦ZpR2cmƂXW ݙLFz~6ubS⒰[E+ly1'S 0G:Ll#r9K#M0d';L36'37u"! YFʫF߈oDZeAK36u*0N{|])ڀzp\dYOh7[L; 9|ߦ |5%JX5.r/Z !σ@+6G4oaT0$;_ jGAu&u.=46]hzs>BUP.;kAx~n1=a$HB؛Rsr׏G7m;.%m55_/`|C;ܠ_zicq] n;ߢh(ad`| > 8Xw([Wo*cWZw-P0 CWAᣨhGSBÞC8ԭa%yHQqZL `ࠔLsJY:NX9Y #ECǭ3C.&@?>[=KfJJ$>V}e4vGǻ$⼏⹒O <?a"n;t: MUrAwF6ꆛ|ޱE CPb6rK٥ໍfځ6"0q`oQ$ȱ3ȎRzP8m`kŬ߉zAv IEx piEcaQ"e$&9Z5톅cˊ}&3MZګ%@԰0M-,_!b(w_b% ;<clT3KbF JUuL3s% ˏ6zf3 ȄVXmARtnJಋ&@C4@OK[!C~?=W~h>#dP ?kh2?M|_A&g&Gfs3;[k :^8AszA/" [J,6 BcULa%'ʈO-}}k7t 7EW hMocM<ʂo D&޽ysSj?nbAtz'Q)?A+? €֐j{->6vvٌЧۈ ijhN쩦5p d}`2?vUcJ=YVNI^D̤^0Gm wv ' 6)'=S*`m оf< njCϲN_wSܢDYYO; lݖanT֛O%7kz)qixStJj`Rs0}ST#ѿI)v5>!ZCjo޼P]le֝ WߎV2tTsoHt>aΌ\X)Rf&9(??K0 C]p>-@c +x(grxeUvH3`YhH$ )+zh09t5,v[uA?@zH怂ҏF%S7\46ttcȵy,˘ռ\^v=1'KH&"xŖ|hN\%LH7q%!aR'GBD̓ HrV¿f H-hb﫵B'@ nWL},tBQ55ɮ %Jf#ՠS󑜕2fθ"?o%?10̓Ly$F'i?3l;p:_;WbYs4iJJ Rǒ>B]oVaϟL`KkŖm Z[RBJO-DZLqח0LW;\#ojB1t0Q3Wr`J-I,OX@Wa\YGSCczFмOWc^4O:UD1]ff2LWz qcNcJ~CRi a4=nx8:P仦nE@eg9c*pued~nE\5c/P5e)40_2<(XW>ç!ڍS7kR|u1V6g0Yzqbo,}XeK`o>K`wc-XpO#EC%膧W Xfve*WΕs,E42Cgk;"鳃< w= ag` Y&L8[ ygAw1MbkD] t-2FemId#oat 1W\b Nnm9&zchQY"*ЧmVtɉvچZ1]ܺf:mA8c}nV!W;@>I|UPY&8O;% ֮̌FNOU}v.7WʹeAJGɕ~h9`G< K | ʍ܆ ny흧C_})6 Nl\*n8E{hbyX ˝z9oB]_jc aշ)D2O> V!qBW[s^w mfx51%лDzµl9(H̚*_,1hg6t1Uo^_k"I63i +J)D9ȫS(d,zB^ҁ*٪=!"Xdzb%H)9GJ Nv;¬8eZf+O5xǂ.Φ~3;%Xs[_IL KWꉹKU׫# ^@迣çV0<q25I<(.N\vm67Fsc6rvQ{"0:WAlx<檾߃]VG*%zd#S~QKH%Ek*bΕLg{Ik)κ`^wZ@wdm2Xd{Ks>Ή%|}x UUi)vu#wY lk|+a3Z̙pV>ֹ*Z\6ƥWXVl?P~bXV?7/xX%Y{_…sl q0fU*Tj @>"6}="X,`d:l+dNr92_gj|$ssYjIl Bn 0.ݨ&7<7>fT _DAx[k0cܽ q@ZH\(nmtũ.Vr/=Ftxߚo]t)tz HDtl? l~[bk%N,!߃J&.F͟\Z'(~Z_^_etK4.{ 8,~egsgWo6"׸MNRT"{Uf m3|qM{e˞nsVjfڢ_`ߙ08GwqULx _99T$[6A|Isay|G̻4=ZSF%_m]|Kd=ebE&1'V3y˱I?k/@g-7st<7#bLnZW ^DL-SyYo¹hO3t~|7u1RRsj^g|5 d&Ux1Ovw1fxj]u!v$!WUz`U E{Z~L;߫!蘏ė7 ]%9pYϒ9FfdfTɼ!;hM2.'~lvWbH3!-B߂c `jB.\m?i^m8O4>'* `iQUStĄm"|_/~,֤xE5>*|p_c\ia{n]+wi.qoɧp]s@dcE6T0Ī:{K1yӱSn1 H+-`hEрk[a6B -ք~oӻC.T-КWJWq"} Qa[J>77?P11r f~.blmXuB 7j1x^ J z~${W[ȆX.%93N +y~ϢOsuG@zU0nZ)r+4-I~]'Mё@[kav 'fj!0 [5[CϘ򙡠1GOmmh|V圮0\#t;B:>n S# }y@>Trgdz$eO#}1Wq(T9Z3Dq R~5wN,Gی|Վ 37pA$1-YryV iV@aƅ$⊕w5doCȒN08 :rnߤ/{{ ǀU6n xV_s&BHӄ"t2}`v?W?Qi`Nr=*sl)IܰhJ{C}{2,p_0%=T Y#BܑJ2YZ4yq*љqʰ2Tlxi"T+S&W%{+Ff3ʳ 7g(aFQŗZ5: 4SNaD^rGX"vJB- T4'kt`e@ ;:ҐR 8P׷-,_UE' t9is/A;X~i*Ql#C(gE$w̛'UBq$E)*-nd6(^Bx,59D(.BQ $Y:-n", IPĥMf7zQ߹| ALv3P Sy_M护UY 2HS!+eI!t4Nӷ8kHfp݌nߥ+䰋Ts aRRtO,]~$gPvGyMLOh/p4lkqZ]&**i;he*%HR߉yX'0꓈*HNz9jaG7Wdџ޲_I= xdq49t:kșNA5zd|Q^A۵΋wj竣BrA@* UX XYYyuZZ#lg6r?QVlQ{VVe2.bWK> a԰?c qyΛ\PSvxتzAä:'( -qhRS?y؈..0뗗Y&ZX)$` "ʰێx&W~t#3RtDs#c>6">  ?MMfvyu+{Yp>?`J|E2j [ &Vb2؅.Nf tl9}1nc:L,_H^WR'Ja` O]m-[3#;D{PCbK6=\x%8I/1:S l%yk8rTY?|UMRhK%l#JK[zLNU;f|g(j7,f9; c$G<8SNYAC$2UoDWÖ< ϿvhX"uE8LDzz\%+PFT1x?~?:k6`V;Јލ, /QB|!&g'L;a5{o35 [rtl ⡫ فeѠ$kB/WHx)0Ox}LEO&YSsKu|{{= IbL{9n aNjxքL#~nmgO%;lf,%T #eވ5-/ s|3a *QFx@i$\;UmNKyjbN*nC|i]W]iֲ$+1* 8#BKys;wͣέzAܾ -QaOd]{BTEFl̀j io`Tݙ+w"+~:Mp-P.=cJ=s-Hh;C.`L``8Bڽ6-T!]i,]ݭ\^{=Y"4n$5Ӟ]dFOFZ.]n|8Xu"=[Xoo;Cc( 7J\H"]gm؟{:mjT!ϒJ$*'kpu@"o)IgƟA@6nd^$}WΘxgMS + YԦgqqrɧL=?z]0nI@ExU!|P|9gb48~nRhRWRMp8xF K\Naqm5h/tw>J)I)xتE|Н(N^?CE$-Nkӽdg4Fz`lD6I9ۢ=ނ=nL^)c=lX۔/rF3SanmCoC@ j'zD?1DHsy]~KX<"yj, U~-K#o. gwe >7,6cΣM^TAlc:LΏOsYid(VeR&J)M,f8v"EQQ[To6._x!=ba 5,Wlb"`\Yä b3j#-`bAZp#Pl^Jea;odQvENګبFk@VZ* ze^LD1)7J"=]2-q,G=(9f30N[ Թ.jSbYF^[S" qgRDVDzٻ" [jřo=%QtEpe*Ơ7PyELλ{s2d`4Lx^S,>AI""+{iڥw<+v v>p=c?f0p ؕ_ sSfs+!H de%,|T) \>:cIx 2٭Wl/Bfۥ?Mңtц*Na37dFDxeʿP&qx迋̰J2c&,Y5dX=Qep!"&1C`8xv{Kh҃qLr%v ,SxI}Tĺ39hŔLQF m|T-9;^߫뒅;QFb5myF1z~?0MV9%`za]MMJSAw1j(@ʨx}| Y!a#á yJB46/C- CaL2!!w(&NU =;.ck^ AiF3[G.KdL-eaM0bh>7u'+S,C5$b U&)/~t _ֽeB,ԓHqI%[&L6zAkX;fzrz4DF^w#`k) FG~2?mxƀ.J0=95tGݬUK{HjQ'Up.ff?I!" z? Z]ŽCAapIRWѫ:Vy9jv8q)AԞf'5䷱ {xԣ*kuӃ"_eH+g y؞U\T?P GT䃞m MXsZo[\fdpo{\jkQD5b~!~spZM/lb$s*mr 6DI}*?斷˾pɞ0xO^JKgưlp^%Yi3;8qiƶᮿG6)@p̙#;CAJƥO R׃C GZߜVm (NE!ji&zT;!Z#SX8b(\Y缂֧~ m$瞶XIWR]vI ưKGQ )L6ӫDh"vfҩR֡F@G9Bț)^v$Փp{aVER2yqZdŲ'%}2 ]A|bD&yvgյ!wdhTM^ {RItyh}c`?e"$s]%_ [8z a$kNDg 0c̅Xr\pH ̊.V0 >Ce [Eǩ=x)(h=Q$vOQAf1WMU-el5;!'@uW:|oCF֘恰r#) Yx<~zF $(_%Iy _Mh>1K=te]BiNm]4id~{/|[mtЙsڌeRkUq-(mG;A$]D7,;ՋuǛ!TGeJ:!׿Jx.;0ׯpG= ]m> ޔp"h hUpN5bCoҥS/Ls%Vg? D7~ ,, ̒ v3c*hV1tz)z|ŅVĵc 22cX} zH-9 (+۷fw_ue'?9iWP˱;۪C7%TUޭaUI0YiubTnˎkkȏ}[hw}d# g3@> J/Ɋ[R"+GIo2Kj(>/.1\ 8r.9S|PDD  A :^ǎyȸ˼rr Q4(t͎OcY0BSEd"a=3(/C.mD_F/gҏz ơۻJmv=E*׺bAׯ/+g|:Iꏀ]Z# Y~)^\pv67gțgŇ|Ks$LţQR;2l"iw$FCh +ױue%,Yvoi̺ g+|U P)v)pK5 $P!&6kj΢@,xQ:ys|KK FH9-`xb%]KkҭK^!<&!09 l9ēKme(l+xB\NuUV7&H>Nh2ۘc*˳އ 7CB  1295pP2Vu`ƕw!l D?jFm'AE<&uF5LP]]gb5^z׽{^/=_oOw#!gw+SMu<1p Ɠ~_܊̱Uv3&$BmsmRgm2}cTzުVӻ#L0BTyy#S:KAݦ|vDɥe ډ߾YFp6\Gd[F5b&s>tq'7E~ǙF-Y뉗1u0u%e:\uR-lͫeÙ1mezD&C. mva_[qvTN_!]jQ~W][pW08U~C 7 ̇Wwc`!y\d46> ].7vcO4$e؛=@ztFy)CQكKٸjx"}n5t\%Fw fr)޾}:H/s$t ]j=||0R8].qwB1@##,Ϻ>mnIc$4dpE uTNG/m\oHvUۯhҟ?QjIK.Kʂ#@vlVP9f= ۦlT5@[)x2_)$^A(M p-rp'ұ^LP>lM($GXTKo vK>ٴRiH1&.b欲(U6ٶ $Eezyz:(\2 vi(xn~ESmNd3yZvM %QIM|j.ҷ#3h;՛.dK%~3e k桾],9`j -6MMأӌӠwʕ%!Vt:4AgKc9rgWnR58۬\SlG>A zI*1Y$uu5 T^ )RNhm(VW"dLT'ĹCQ꟩qPBvGq4O ;^^e  –񄺷a~Whu*I,|Ha9ISgcV/p& v,뤾Y&~Z;qp]N`qʍ-~~\ ! TUҎ}zJr|tHw`(&sCμf3Q%3T2'9ueRNuk7[nh(ѧtc}H -wgf؎Soqz>8߰VԴ9Ǩ 0ge9DDT2]K2gj I X5\i$j};$3dSYH82<iL)%綛M45X׵«Tםqt8g&zz q,\d3w;l5+-'IdG?3ޤWE/#(zkz(O?i~z`obdeS-ӧoش`gEU [̡QCC,#r 1%"c35 }DGTNR%JA1A<ߧz+*2}4~^68_H >qɘ=Wj,8qK!DxFX& E>FGTn{}~ee)Xaȩ#٦8? 7Wru ɼ͒ISzMǔQ]pp$,3mǿ:n".ȡ~dVmj/ 402st8 _1"6xߨwN\5K_ P5doKax6j3DX l-L#QcHՅj@1jGc o$I(ֳ>ˁzi*Znn\;o,q6{=xU~mT_!t9$-f[U@JB phsP(P0S}eRJڜIn{/Nu Hܘyn)-6R8b$+A=Axr-!79"mnԯP #α @: qH8Aͭ҂N1Gj9a W׈!/%SпcZ;gҜ:`,]5;@r-JB424c/ ?Ž/DĹf#A\[!P-[hUP&`M~Sia{5ͅ-ɭ,fF6TzAQNY0d[&!_npˬ56~mk D\/뼮*$N8t&dְABߘ#/,xxV߁D*&%x(-Pل  R5 lǀjt%ls<FRLx sׂ |[sYfbWX&>K{#`:C3y%_ #><KNIl).\gYw-D'Q}exA ܅W_ -~!؍\_j0MSxD#L?ȟs.ԞmGp8 ~ivX){0^[[F3jyZoI-XQls)ģzqMOo.h P!U-L9z{7rَG;*=v"ȷ|]/G稰ѭ- P }U;\~wyJKGT$kq1C(6}h鮹"| oҥ~[Gf@O9QDKA-OC~kN7-="q "ղ)30`HZ AJwi9 _V=R|lѭW7GVKݮgbpjAQZ rE2Պ{bY> g􆼾 1vY;N7Jv! TR&۔|u3o*U(XIJՙCXkn(okqOdsuA,^gv>tp2$VR$w*'hR?np$E6z/@roK IY'j ]_Dp)#`ËGϋ x;0Sb)SLANz0ͳQaԺq=9a/cÒ:䣌@|9 hJ 43ɦ[Ѕ\NuNrOl@}%EP%ilAʙ!Ȥ!ק.#ptXG7q?7AԳ.F۾y@{m(llndK+M (5)uZv,>7jyݳL |Y(+ Άݥ)<{wDN/ߏ>+^7qJ &ȨiO8A8l+oa~LRͫZRgU^s2ߢɛS@k1S]~Т_8.qM q!Jm8hJ-? !59+eTӐ+^oݐӇֲLI0A$vwD-+ {[HUZ;USq<S9qh Nj:һ2]M n,pk?Rc$Rf2 1}ޤ=bI\>K.%j!=?YV65\o}#+K0fLR\rM!I=!|}wq~P8QGP-)9&G>9z%އȊS xr챭 ? lnrY07/7B0B5/'d^d pee˖䏒 n9۪!'(8Ji"]h 9p FA%~ uMah{iM\TPCpXz|+v5Q|Nx#\)j፯I-})2}P{mV-:>6D~?\]#LيV+Yw#Wʩz4+~½I/?A@5샣C_M6G_= m+ {ƿnvuCy}7Xd#O0,`uiC@\]^2MsLXH)f7sQjDu::Dd&l\0ႃ^4i09|?9~,Ȝ@]$.j{k<)\NmPOl.QѡIV"lx|r W$+Q53g.c&!( y `kZC.}VJ7gz*&F5~[D3RX2!N\qwts "짙&8nͺ'Mݦ0wni}.DA0لh|~MHўG  $ܱd a %19sRc\ϙٓ7-H|NWY sMfO_Ҧwv(qp1\HK˽Zr8 ؅R/+\a-2%vC0Jia_}gg-U2'\"zҶ&N/A [9ܮ_pScq|}S#*ZO29Hֹ*34@pYTQє$H0Z&ڢԯTk@c~Ruώg&ndjwNC+*o߹E SPs $ZKA6Sןf2Or=n}ܫwqiޫ@ތIOZ $t6J9I^M@66 "C1ͪ[l F.H :MZJ>-~k"N8\4:_-/Z-`eer7D Sdk\ 5uOb2c_: g9:hBFWv!7yzgP ^;#;wta Tr)Ko$|w3\.<&v2~n"I6؆M]>5 +jAiGȜ5uH"D&r];{C*M]^ A!A'{]~aJ3zT H a3cPIJBa=]$9|9[h:U 86`h>ٰIeFTht `` r*Ȃ`îL4c<@Yh $=Ie?5|Ȝ]vCDaux0anqD݆ݘ&ХgOuTc>ۀ+nd BUƹ̪]KIW~tdͶ>{ .i4\ 7SWhΆ= /U(48`UTiTd3\hݩ LsQHPa3K|8*rhUW^5eJuVɐ* yJq? 8s_0P\@G50o-6}cA;0&u`}[Sm_Fd Ky\2-?Gv.ԮN%=_uP^Cm$HO,sMwC,c&:lFp4+Q{r݉L,8obDS BNHIwHHׄR@H*wa廲+&S(oL/&YXE&3E~c3u"e >>|9)fRŽ utPSFk7 d_=Z:Lwd 4i GguCPM``9?zE[M:gw,'@1 j԰}ʹJڔ Okf"бV@p"b۫3 v͢|n1XZ{c#_`A3=I5$/V3AMqN rw]FSp3A{`S:CrrO!fzGt~fԧmAģN<>'" n֙,%iꂧ"FQIy0=ȔQA)4 Nm"J;+qr\6m~iZ*!4HY(! q6{MD6|І V>M)5H9L9gs`o0b d~M(]sNWDY8žC~B'$2f{؂v&#]7}0}jN`p?2I'\G-n5 (I4Z&Aܾtiuܞ$;Cr@}ae¬?ܨ# ’)sa%RWǕv2ͷ$9϶ MHT %n[zƻ]呷Övˍ ֭<hhA͗bį]b?.z6ѹiWKw\ 8 >,.OomVE¹Gnaﱮ04lJ=I bMkw22׍ب@YF_~򩉯zp_̤\;,nRmQˁM"f2Okrf(Qj+i ]1+6$!BY橣 ΂~O)8 F`YQ]lMդ&Ih{e0T[nse6G)|eS*<(d1%2I`DG4M %p&Ë9AR"ƫVkV5RdOD8O$'7?賐 U%5C7K\a/*DS$Yր|4|͓iNDhc"0`][.}2 دjV\ :2<+ύrb} q|[lϫ'f0 ,5Ci M k[SyqCq~TWIjXOR }&Yxh:r"UG H=ql ͭ2wTFy0`%LtS89 =c,9;BL pמ(]Ϡ^ a4T;53u<7@JMwٚAT}I01Q~LMj#oSRɌڋmx0m7hu*(r(v0;N*(P}\ɸ>!0=QJԅ|.^5Pn k_[}aJI~qSۈ:lYu}\tBZOCa>l@eDG}E\^U7q`3q=;f…jbkɧ0k'kzF>^g[<7oz/hTe0w]y%|!vTh@d/uN6;=R8Z6:e3&$m$m]b_nT;DGs4K~M3&bk?S@=9aJ:H"Oz[$˕+%9+aVjإg i}2 2Dw(wYXN#ixڽX-zV[yosn+*v}L|Fl'GW[._Qy&]ueVoDM.NDSR> bM!]3%/XCIlzx H/՜SIUK"}J!W|0>z"?ual'ډOqf@k%QffѰPvp$u;RAY7M&IX*(%BEǜ<-ֱQ7h`j}J^T`n8h`5VwŃx~lèpsfL0K\){}V:< Cf2dׄTGhBbP,Z0;*=Z 'o4!kI0vK;+)f}MS9fǗa/G[WPjNk!B6E*.} $-$i5m_jM ._=G.P g!1s5Ҝ~#rl93`mRo: Rx<q,ѽ-m ؚ;-0?w\H{-3u\zC-JVخ?!/D&n@N`Qv{\v|W:I'#5 \ҥf$[KM F A~N ΀Wy"a}ڰf c{]ɲsE;sɩaq쁈Tb0GB|>/eLIZ3$>5Gpw*G>Vk=A%<599YRWEeƸ .Xg/ThH%R*{zv\)^~uI|yW%Щ׏({xP3fqpWe>;вG||%7:wyJƣqaw _9HEa-}"5X3Q$];eۿP.UuGr8JCI|.obGgFA#f_k ` P,a^؞dpBlƈ,*PeQcr=eYφG$|c3 SQ49;?Ν 2e D"n )(;8G[)&s?jFL"s=jo-wt;|Ķhg2[7z 3Svsܫ>#J*aƆX jǁ?FGg&*n0Ig=ob<-#<߼<jcl[us -)6ДWi3ex9_>P6ocn3DEZ@Mht>d;̖󦡆tĵ«nucNNt+~gUx*x҄d菝ʸ S;l>D>~ѿE3h[|m//oPvrC]2T-V67VnE;h{~X ҘW9|J%k50$k%nl%UBAi娔ɚ]` zkZϠ\ȿ"^Rͨ:vd18oBә#v0U@J\<D c %I}+1&uϷna#(r fH>g2u]/}0-SU//f!WAWܿFEKLdeDBJ`ԁs3Ǎ:H ;yO3x6z61r].;۽t}'T,3E^Z.ƥP?;[xcTgeʡn+9'>e VF&O*Z[N*/!B:Aw?!kJh7]hFw[uW4!I2X'JLѨEMW,+$`<"r!-hzj[BZKh{8鶜/Vkt]CKp5pFƴ2.h 5U3-2qrB^5 ^ ]^[ێEB.-؂$yNlITokBoT>X1bDHRtZ{;FctVm۳o<UW&b {7#GޝjSI>x9} A֏g&q?u[S*Lx4">Z"iu29HS8?ꁋrO6Rs(EاFVzu0Td}yu P;aM R_wE VBRwcWRS{޽5/AJ҃=1D{l%*y ZPϡ"<`c%l"icX14F|H|;n/+0߼Lehu]Ewua0 59> [f3^^ L{ƌpY` _MWv{V7Lh7du!pi9NT,uV&F|(B jnEmJCfOi 3ڄnш36U5JBḯ#G K'FrAnfso3il~/Y:TװTi$$J ބuw™FS%U8ݻ,ƑDޕ}GTC! mgóU"jIixsZ0ߑ͊`;Xcَd)E^%`6Cv\N@R7 ڝ#`5v/ωGi5\nȃif¤<_]Vg.x'kx;78AP6ɇsroW2AUbIYr:?Vp@u:ą33{HZJUzK)gbСR$ ~ǗɨUt]OB%9O\gm}_eq]KtdMhŌz,r&`fCyH$R/s`#N%uQOz;χΧT$EQ ~w?l Eg:Qv&C5Ѫ_R|WT[$>83Y΋10{PQTZ MoqHڏMa,C7Hh@}_,iNkxtڅoe;lnkoaV05\ \&#nU} R2$M=%X;'"Q/K%wAiwrڧ,rf'OrB3NC8k-1}?GJ{8P4bP*c. pҚ^ϪLmHsgƾ2gehNtd<4ɜ#eTp䨈mi=W 2^R{Wn6aJK<*!CkbU"N%_ѢoS-~k/ eX[<`Hk}* W43iW}FoD1` :o"`.,r,xs dnS8-S ͹C.* PW*1Џ{|rdbu|,_@r]~~* + FdH{6DG IlRt tpadRChadj3n)/!\CҘ{ZL/O<*{yxjۨ)%{H)|b+Fd)1pI(Rߡ_#w/< ];AVHn³-(ԅ}K4h`Ce Lm?_,Fdyza%UVj!fR͞'[˥ROOS*Lb1U*uqfSMȵNQ'x$¤]#-xQ${ #R,JæEns$: $3.b#)t'*38?' }a,V 3VQCqZE+qZ ZO">M'Q?e?D@S)F/{Rx_Ce5tHiXR ;H_VeRgi^K+L*x F{5pS'G53Zօ쾋X_LڒAU ZUlՁ^G{Tk*/Z=]-ϰ_QCN||-B&!i qR/dޛ(Yڐ1~ל8n1)WN.0:co+2hy P+7bA8& *R0NvhXsVEL + >PG{B Sۉj ls|OL`08,etv`u*ZNaHC]m?$1)q[ZTA|vFIgY@ 66ur`.ōq] ovu[x:}'&qt8aֱSo7&j~]ta2L濯L5CD](g }Yg$w F*s( nKlpl,ؼ`Ӳkjr oSCES$Fz15PV9wk0kG0v@M}~ǐUAL4ݒ >0# %͋z\+z HWU|~d!NL?C2`9Ɛ@E20[EyxP&XG:_MFVёH X'ux9u.h=>w;QZ\f;:1q2+O%_TFǷISK/'<â]UO,Ւ_oDy(s:,C"{/|zGgR?e9p(5 2MIaY6s},Iն ;BD>BZnd,e/bdNK!I8't~ƛ栏tr[U 3s7N۹[SDO&II=v+%IU;N1},נY CV3jB65F@$YI8,x 80"!22=Ex"4짟1Btآo<@vM8kJ/IĞclEi >i^#ŕm"Zsw5ULSoVq CfjfIU~~-աkU+7ԓjF{!ۼ*]%6*7wBMfnthN4|R귏 0S0T{M.m-u@{_۷_?fiu[0rH uH4hzW<߶즓ϥQ`1I0+,-ۣX ֵ'#n|wE{b:q!1ws(VlFݰK;MuCgԀW s; p ED2% 9G'*W]hW>旯<O+56 Z# 'v'S\+jZ4w5 :~,VTq>Mr7] Y){lC\IYvhJgFۛkcF4șskvv_Q'#4+.+*m&_w@$ +gBhӪ2\-d7k^Q%P_^Rh ï0$ o>F|dCc=AπQzo@I$VMQuŃzѧ})"Ծd KGQDޯ$JWl$PފmS/w[4 v#"T_xA 2bHR HhN=ۘZl4Q 詹 [<2xUװ)[]H]{8Tf~0"ⶖMzM9bb9g8eBXiAg; E[UG7Ɠ)=.P>JCvIg|čAWPTӣ.ؗ5$bȍ\a8Mƒ:%GlT;VՇ :47>6:xwO}C>w ݃綒QF=tc1+),f,Ȧ3򁍔WΆ'D2صg%noN3:&Cy)vl"f<a ƃuy_ Ԯ.3h;Org@ {®Y+C;)K ^.I/H[8݀S]噊a5sdJbG3_jB 9XT 3E3:,WXe(pås/}Oxanp՗͗Ea9c8w2v 3%U8Bn|&0!-Ӽɏ UXmWQ'59J]GAx!\|. Ho]j2"K(M jp8L{ZWt5I,yC(9t ZA /\S"mGZKCaGik{4q[p6^ai;ov nQq 0NCG1lCd^Z-b-p(([boinSZ}uީMI{ M!KLVY ^&?EA438@wӒ#EkXF Y?B-;8C'x X3 G_=Gq(w{:ڻhkb &Y*.^p*caL7ʨ}v0[tDHO)gºLYlCE|O &Evd DkvΉyu6{JOyBbl tߞ|qbIw62:e%eahyZ Q/L/KMgBRzkHu#09}g#Է,绚\S$]_ BL߮PB֮l+6UPԚǔ:cO`p%Y,8A58ON>I0 Ę] 7f՟,}H+.?oCm*6.N -hZ0ZUDke$3[""Zb1M0QFKT&.,Q8T+BNZ NDv|r1G`NcUqJ$~cz;&x"/1cgXq>֒X-f%ضq-lSt啑{K4O4!X&'}iG_WP?omﻜ%Xb1n][Q5z? Kx3tQۄw6pygQoST^QA إTqAJϘi_65rS~n|׍]"_O[$е+wT+~&l4S42ϯCBj~ilHg?c{o>n_E0SLFff:Ј`:pq3SP3ߑp&i 4b:ǑӃJp %[-1lODQu:ex tXd%و8H8Oc Lx(pF2oy ,X+-\m" PZn)N-zuEaP9F6Ƶ:CEd"vJNJD2 .$f̮HJE`w nJ}9H)ʌvHV5gKW ]72ysA g"ZZ m顡 9|LI!P5P@"dZm5c"ܻ9Q@—u z:`Z;(2d˗%ĈX"r5"? ˵rę!sMHi`@}z,yz)JA޿%D]56PZ!K~]誉F⹝a2ZM5G.Cd<'/wy5U2TY/kzL*: Myb;[~i}w(8ѫ+UzN{S^-v0yOTQ#**NYjr\x6V?LT aέ[^L/cŁpg!|(1/%h&q*ssaws8݅c=>-6VcKMi;h`GHPQ=Lj}uaO߮:xQ.ٮ#JqBDn6*75k~FzeԪ8NZ2Td@ W05紤{f쀠?\un}~c!% d4kO$t3F5QeJ+rѦ$MP?@TTS_KqJ=Fȣ*K ]̖zt1G^ X$psR9iË ӧ6D JKfHڵGˢlhpBy` MD7+-vV~V_i<UP{S6g(~]1-uyCa\q{S2 2_˲I\x'~meTg;.9&+nYD#:~jAeXfM(<ЉvG;rIy0(DxF)T-xZӇ]!Y+`g/{R'fy=-Ԉ\n, fsʰRcÿS7@/C\.Ք4*`RֱY5Q i+SRv~Q@fH~PZg 7XjKH;&֐5KBֲ՟}R Sד۪? NG~ ? P^tT4^߰B[#&AۤΡ% v}Q;TJ4d98FS>x|#vG^&>梥 ZlA>`箇@lxDdt~ЈzC 3a5 bүYkisD#ʺ"F qfEg(Q ~!!ؘASHi]ҀR[KqU3BOND F Cp2`вS-l~c 0σ[yw9{(A.XVr[A.OzQ{u}~צZC&Pc]tQCMBa݆K +5 a ?/?w1_2/,@+ؒ\_k7K19mq~MzJ&ʳS G I )\ Hs4GҴ#1yU<_WKSpJͨ[eq_?œZ1Fۘ⣉aƥ0ׁM`|rL!\]1 6c= JFa'Lr,NT>*]_g4p# Qb /lGY_ޜ$wDN4 Wպ:g5jcK3L<.⍮ǽǝ aFq,Z&b r١9V\xN:.aZCltExCE/{򢧢yw{ݳ' Wwp ԇZԲ@6Y ke(Z᎓!'iߣN% >S;|(bqDj;e>kti=Vg,R2vqX'4̽BD9D 3P=Ȥ7pT;tݝy00*)yK/ )H%e\U:r$UmߒC_y:ĮA3!<794)∻ɢv[Xg s qkkYUI*}$ba5b>%0HugbjvTI!M[VXR/Զ񳁩(5oZ!DvZb|r܀o֥!1 ʝl\y؅{8З@"m߶{~os}Xu` K֊lhR%APk٭X!#//pݺ\üzFEhaI𡂠`$G󑻹dLdq423/~%?".)>j g7q١m+>8#|V^ [=&r;)G'+ByGK"\5#Vu-ۭGHzB&?(JsB1]mśW[ `r:9iGF'PK"F~dbצ<7]|1q?P&ō?8~*>ˤ0 q_mM%5`%ӀD>\/޳t;"_߻S'R OK= I[8z7` uL.7n| Q$J8Fl&-6_&:@}#;ɝx=ۉ/LuPE{Ւė# xUNfsbn.=ցƇ`m+љf7M%V@1nty݁)W S$m5 A 4_z+QC|؄3_Y;`]ˆrJEa>#CIt?ǠGܞcx8Xp~c3ՏF蘄v[QM),yՏIE%48=᯷N1JcQeS#vVA.Ӻ˨(2Ա5#Osv[l^18K`|K_a'"Z7 nԡBKT>j#J2` x VkQ,>aJ$ @Y.Um abPCZJ Z/nL\TR wT"JP-} h$ x.ƠXû+P W!п<<\h3ώ+ M'ìL8T7FtNuR][yY1ި=iUSfHОCר1|LFe5~iJwq 1:5eY GۂшҙQ(SO ](K&^n֕-ܝ|bzg^݅sO`|xY h+^̥i_O UA)aǠqTmB,WʰDLmIs6pYzGSt.+7s=lRo-tE9M7al5=Z8lg.pjA?L 扲|r,QiI4CɚSO.SG_l3P֋'\J+YtM.+'=Z4ze$> °qH~8$unWr3Խ0"v`ghԦEt{qICk+gI-c#2l{ d녉CHvW|$9]M~\xJJ2OtCiT`4LhaydKpS5d.Sbr )!<M#QEgg61S 'lD8i'5Y3 K'/jZvР.p.#$`[H3]_~|/$u;鸼A_*ak]$ͻwp$uSk2Cg!}ſ4p%݁\$lcW6ά_my",Q >X ܍*{-ڡTWSJqlU/\|[8z&P8}΋/ b 8 (#L i.Bب"go22Yy):qRI99RՐ(xߝ΍窀5ca1 7^c9D㱚^uǧe>8HjhCl jV W}շ >"lbxS\vӳ9+&%ҥLgr!tT\,/YrܒV顮L حN1 .y454xkzLɬzcm~2ݢ QFllU (5Pl=e׆?Gȹ.*_3ح(y(C- n-zC* RM "~<셔۶O]ͩ +."vX;LLO֣z7Y=aPDx x&tIBbO 2}WɱQHԬ-<,+Bs[7Aʎ{0^)g O+hS7U&M9i/?5\T+&c!S<-FpC8zm{NHHx#;V5)8JyX̒U@&Vi4zv%e1t6 b~dʶW|6-y.$ֿ;s9(TKXӸsM/.t]fEްEƑl%LP@/ՖXWjo=&`wB*>n v!|qn Xv|A c̫nvl.q +~[LW[ |\uz[;0WwG9I_X)f[uL=XI_DPl7&ҺCVQ<=1͊Ӭ~$ o^Cj0_r/ռ9Χx-h؛C{W"5ڕ/UԑD2'uغ$:D͖gVկp韰oy_e1ǕN+RRAzϨi}De:!W穮cjogdf b`j8//(v9U qˆ6`#SonjAIӉ#N݇_ؙG1U?WP׀o!mMpf(m,-yly;rO-=p^®cqlcrv|bǴ97MdIq+? Zh pB@udBL6T:'͌&JDVQٝ|ә89u3"I?Po{ ?'n`N 3^X5Z`ȉqPX 4+u|K2{Ieq `]zߐ6wD8*,E$ wsP̫0/3ĐHfH$QU:ޣ~BRf{rpѦS6 ݶXW_ ZJXo iF]S̚6hYm3$o FKluD9a AQ`Fc&_tRU*i¦Bu D򪔥2ˆIJ/Ղ6F[|>j/tߵr_i~Q+4KJ;Za3Tg*hHEZma]jZPn MS/ Rg:oƙC`%tHHoDb5_(UN!l/?uB@'YMދ"}Хng7Z&.$ٶR-KF 2Z&NZ,-s- ӕyt /ZķĚ?=Qid_:|S!-,šҤ S*=EK.>kC}b>mW*gvzX4<:oC"9y 1[{ 4W`nZkuި2b2DaDΔP @} ?j"؅Sn %,mWow'mP 5VV_Ea-Q,@D͕jEmoܲNQy\0㚏ro7eeR 3&ٽ79tD,]DtرLWKYn6~Q/7 ;;tV+JYaa I*r B))=4XLx}55# %ڮdk]C5X.j[>sn(b=DOiۥl 'F߃O!8"DYg/*|#C=py-O9V{H i5i)>ۆ{RgvvPý'ٙ \˄q돐YC4_@UΣ^H7c)D#?P3~ ڵph?)-|3{4Muz4dg0l7ooD?ȣm! 8My0K=_ JGBHhs؉!%p<9H-ʩK5ҭECzBm? 3+s{b#_@J^z[uB1Z)Uڥ= ણhh|sRf.f`&`b-+͓`ۭ/a[Wdp1yaC)1:t9Xv4' <-RrU<88 ؏nykgὲ!o(.)O^w, 9ڴ<М5H!by"ܭ#.J}̙hd A7NL8B 2jlpZJ7&=8)飙&՘Np2LgFz>6 JzC : ;@L|u (iz4g݉A$ [B 7'dmz>މܤEF O̐Bux՘ [Ό&daЎj"Y|!.r37;gMSR(p(Q;KUcIUJ^ >E;FV6=RGcZz >51>S%~[ {[L?h1(zs-c׼ˀ5;;ԤsE+ >r-̺ذ$f%VW2Z KU^4P~*SDtipfT<;zmr_I ʭ!j0a TIPj?LrM(CM/U׶^*[uCkfD֯(삤-<ɕsnJt/0;Ó|(3BDx%OU.OFz @mup3*>38㷥識J/LQ]uP"+br62BM(!$ҡc1kwF0EUt)V}ϣ9 ,wc⮍(-qnC V빹͑Zq]LΚk JnAZ D ԟ$GYA:3erqV$d8~,, E 3W>֑t nVqTBpWVpk7Ve?K߸(fρ?}w$y;>Y@ y_yCҹg)N'0MpqwX˲ V¡@y½cnq:xlJleHiScND7~4dNAg@8Rq&*@ q;7TO32owZ`a*AdMAwvy^F\a <, Cq غcZUف tB2?k,(THfa4@d¶t{X: DaxdzE`;l0 iR ˔{`+dhw9aT5T]`h.D?9,Md;zʍl%/:?@ Lfqh`Twh!%/g3r5HxocuD U:V,!/k5*J(HMp/T7Ѡ8fR3A!AN7%MRaL(/IK MMMEMkd==R.8q;l&{63W&Y&anb4q{J4ΫoLgrGfZ?SҎ;$RorD\$]$G2 c{ nxWil=Eh'(|S+ypNFEG )ˮ#\> endobj 35 0 obj <> stream x]n8ཟBvQXO HYi@#WGt>R4uwϷ?oytnW/^}cZNy:Շo|v/yUjNi%]O| _sՖ㆔_cs^mzWmasM]ǧôڶcsS1疹EYY٘ w#rbNsmܳGn@?@?@?@?~_~_~_~_~_~_~_~_W~_W~_W~_W~_W~_W~_W~_W~_ᷚs~7~7~7~R~7~7~7~9w~w~w~w~w~w~w~tF8#Hg3ٶ l+ڲr Y,h6;сDt8. Pi|Fv +KdDTguNm-^F ̸>-AāNą,ua`ʼnALt&8eM<#art˄F{ǁN tޮLvqpvvΙK2=n=azf1OOg$@;<) bwW<}ynS~y.XG) 3,ud@ژ4͛rPvc1Kzp endstream endobj 36 0 obj <> endobj 37 0 obj <> endobj 38 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 6 0 obj <> endobj 4 0 obj <> endobj 5 0 obj <> endobj 39 0 obj <> endobj 40 0 obj < /Creator /Producer /CreationDate(D:20100119225939-05'00')>> endobj xref 0 41 0000000000 65535 f 0000192325 00000 n 0000000019 00000 n 0000002456 00000 n 0000192590 00000 n 0000192707 00000 n 0000192491 00000 n 0000002477 00000 n 0000003426 00000 n 0000003446 00000 n 0000003635 00000 n 0000003927 00000 n 0000004087 00000 n 0000030008 00000 n 0000030031 00000 n 0000030231 00000 n 0000030749 00000 n 0000031118 00000 n 0000043493 00000 n 0000043516 00000 n 0000043726 00000 n 0000044078 00000 n 0000044302 00000 n 0000062370 00000 n 0000062393 00000 n 0000062598 00000 n 0000063001 00000 n 0000063268 00000 n 0000076805 00000 n 0000076828 00000 n 0000077042 00000 n 0000077409 00000 n 0000077649 00000 n 0000190062 00000 n 0000190086 00000 n 0000190277 00000 n 0000191222 00000 n 0000192187 00000 n 0000192270 00000 n 0000192820 00000 n 0000192917 00000 n trailer < <7CA0E5A4CD73A389F20C4D4C0D7D58EC> ] /DocChecksum /FE8ED72B58C5534D08666636603AB621 >> startxref 193186 %%EOF kst-2.0.3/devel-docs/Kst2Specs/kstfile.txt000644 001750 001750 00000022256 11544160206 020747 0ustar00synthsynth000000 000000 File Format for Kst 2 Base64 Encoded qCompressed PNG Data Base64 Encoded qCompressed Svg Data Loading procedure: Documents are parsed once but loaded in a multi-phase routine. First all objects of all types are created, with no data loaded. Any objects that take inputs are loaded in a state such that they know the name of the input but do not have a reference to it. Outputs for any of these objects are created, unpopulated. Then attach() is called on all non-graphics objects which obtains references to the input vectors. Any kstfile-stored data can be loaded as well. Still no updates are run. Then all graphics objects are created but not rendered. Then a render is run. Then updates are started. kst-2.0.3/devel-docs/Kst2Specs/Wishlist000644 001750 001750 00000003361 11544160206 020272 0ustar00synthsynth000000 000000 Export eps to vector format. kst 1.x did this by printing to file a .ps file, and then modifying it by adding the bounding box. ------------ Shared axis from the command line --------- Smarter ASCII reader: should be able to use huristics to get information about the ascii file. (eg, is it a CSV? Does it have a field name header?) these should be used only for new files, and should be used to sed the defaults, which can still be changed with 'configure'. ------------ Fixup line/arrow dimensions tab: x,y instead of length/angle ---------- Scientific notation (instead of C's %e notation) for extreme axis numbers -------- Edit multiple for other view objects (arrow, line, label...) -------- Edit multiple for vectors (or get rid of the option in the dialog) -------- data source text box doesn't recognise initial ~ as a euphemism for the user's home directory (QDirModel doesn't handle this...) (nor QDir, though QDir seems to know about $HOME). ------------ 1.x kst file read compatibility... --------- Thread kst2 -------------------- When you have many plots on a window (like 35), and the numbers in the axis labels are large, they often overwrite each other (so you can't tell any of the numbers apart). -------------------- in or zoom modes the line cursor should appear in all tied plots. -------------------- Tied zoom icon should be a mag glass + paper clip Replace layout mode icon with zoom icon, and invert sense -------------------- Legends can get larger than the plot if there are enought things in them. This should not be. -------- vector selectors in curve dialog can't grow when you extend the window size. ------- Some automagic way of deciding if plugin dialogs can make plots. kst-2.0.3/devel-docs/Kst2Specs/PlotAxis.pdf000644 001750 001750 00000776265 11544160206 021023 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream xTˊ@ +t^Wa ؞qH&d/TnēKc(IU0~;o_}/} %x2zbaÖ||ā#b:'S?T߉5Z/E?ZYb2b:H]\hgVcXmyA\{&)@A",򙧗[%dȐ)*2awQ#/c(#ujbxP4צib`?# *N6< V45 4` /xTohJ"KTb#n7*2av:eƜ{{0wƞG|&17+P kBL2*zHWWCS)O t%fRzozB||zk!Gxr,ĬL['OWGt}z,ݙw:6>t$ܞ;+UpKܪdި5TEUO endstream endobj 3 0 obj 540 endobj 5 0 obj <> stream xUguoL\$AdcZpqL4Zn@q3:ZNN[ʹFLTRM1'*!Tq@Abr%ݻۜn}Zϻ>s>gwzzz߽$MB!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!BB!7tCvv)m#ҵq݈tFܥ6bU&uX'\.XmR|ZR7YݛNgϞ`W_OR&%q-aZ %u}㏍M4IvG###`___XU㯾_{Їϟ6Z]v>7?%R-Y TN9LH%(dzO8шٳkc+"Ol?w??wy_~> 谿"*SrR :~OۧFw_^1~ɨ>_bE:x7cy WDr*UaB*AOVSN}T,5Sj K<+R9*0!'o4dߟΙ3cA X.WDr*UaB*AOV+WLۺukvHWX`׾O`<`>TN9LH%ɪO[vmvp͚5M<oo/}K#G}ׇU8fÄTGGGg:u̙[o[nI?Ƭ*mNzueWY*5VۂU ePY+0!'om۶mذ;2eʎ;'w}&{ >|رc]w>dz̙d2,sJU7Ν;.]x >٧G>}3:4>x 4kJ۷/uַm7k׮ -IՖj! @QTÄT|wTU eP`EՃo҃jj! * _B7SHPo2˩?H2\jnёё9i^$K2\jnё?)zPWQ^_B7SH`SZH" 6YfizTU _Dya& L#UOуjj!(V1!T.\ߴ`SZH"+`uj +*zPmW-~R W5i=6Rr XhGTU _D`,ԣUaEZE U7|@J5r!GFԃKw`EZE0&T.(zW8fa5r!Ga#ԯW;H +uBCG`EZE +uBCG`EZE +uBCG`EZV`_Ub*I*bUjmSW:. +*_ܷU\3_> `Ui쯂GMZvͪVh _* W&-;fU+ WA+'i'W٧ qY_V*xԤeݬj嚁*Ur,H`(ށU0!{-_9oPB+Zh /_wb|F@*aNHWѶ 9{ JU0)+W +,z|W`g0Wb>+ W_Y;_t^+o*++,3MWJ*Մ J5b}fU9__YJL1qWu5b}fU9__YJL1qWuE|k$Qrlg}V{.H_S e5lTWtI9TNK#JI_#OГU۵kJN>ԭ_AWv쯬i/v6<-i\xիWϜ9֜wYMWrBԈU`nJ@񨻰R6_m߾}ʔ)CCC֭6mݻ/[2YOɓ'Og%'DX_UUP_хW'S; |pBm&wEIRh7Jy$7Lp3$tOгhXc$0o޼s福O:??\.F;QT uߒf9TK\,٧Ձ+:_хW'S; |pBm&wEIRh7Jy$7Lp3$tOгƍVZL{>ĉ\AU3Wk68GN; -LiZpWՁHyURGD\[Bߓ\ox ; ^O-7ES^Pϖ>-t3_s(&|a zַZ|yݖ-[7oNG G?>K.\OGq GWm ZkV=Y֕;N ; (*fH_[Bߓ\ox ; ^O-7ES^Pϖ>-t3_s(&ng}Yfݻ7;8<<Ξ=cΜ9sgZ\~Q+vkV=Y֕;N ; (*fH_[Bߓ\ox ; ^O-7ES^Pϖ>-t3_s(&ngMI&hdd$KYW_L<1n8{lԠ<Zm ZkV=Y֕WzWqnIJxS$쯌At`IFaoLyK|FH<"pjԸI-},[gt:kk$p9qD#I6Ɵzꩨٷo߂ ?`Hf)zF'7i!8>[׬In:T ΍b6I o5,=oV}c3%*v9MƅOlc*=<n\['Y*m O YvS,V%.YLs u3Y~p[~%RPJ߿?3gBɓ'c~f+Wb[R.YLs u3Y~p[~%RPjʕit[n>+<rWGI'+ZKZY㷆Ws=nJF  XHDY6Ht2QMh-Q,;)ZS幅,]{A8VU? )ouѭ]6;f͚tpӦM ?gzma~6.W/1Gu_zFՁHvTK]kiYk#+|\_ )rtpGkh-I;N2 %`e8Zv eT/4|ZKԧ4yxNnGYliG=zlkOdB _l۶oÆ wy)Sv1>k4QsOR;<7o^:җvY=z}_+|+ ;9+JNUgwԀ[)}L;7 8֪{ճȑꌪGH!0n9ڱNA  -`91Wx^_EOw*Prb]ODv~v8k_ܹspppҥ/^p>}zȑӧϘ1СC',Y~ݷo͛7_s5^xyWo/6`:.W-kDSfc.cYNʅR\rNk0D/I묑C`rRc"] Zrc(6*:A w;ɟDT&8,]`f8_uTee0bhbJ,}e=IPʕ+_y&#|CC`rRc"] Zrc(6*:A w;ɟDT&8,]`f8_Ȅ7_\5w\1q漢\_ H"b>V\-Q̃sr^%>-'U;)(p  -`91Wx^ŷj'.*mO-?֡˥3A A .k _ϬR?Wח£,([XrEG1yƓ#:TXi*D, 8\Q x-:~=7Oo0_\IWͅG@|-amN+v)t\W2nFdpaA#Q7U'◧  `D!KZn{/| Bs^T@<r*0&W 5huc=dɒJÅgMpo`ߊ Da]΋&K># -ACi8l1ReMCrRFQFnjYPwG:YZ;oh- jkg@PPOVx3gP5H4N LSW3g k%Wuu8/ p,1@NKI)k;dtZ.KA4sZIE`D-jeA PRFd/k Xٷ A@UCu>ZE㉖zKh B >X@ Ѥ;0M:ڴ=+kTqQdxwZ%H.F<8'5[ jD|ZN(#jȍT#\U V\HgJ2"yp[`?} FUCu>ZEjh@<<|YgǓtq)WGG<}4666v7 8F_V1^`0.3 hgpZ#-FT +FPN|Z{(#jȍT#Z$ZB-dD4`˷>ȬU\'{ .[6ֈegP5x44 _9|[=)WuU1@q599bDb +`"0H5-`O%4pRIFd/Oر| Zhu *@ p \ecX6x&x 5`YΎ'N LSNWΙh'%}b+D+ RUo<PrU LYbF]21kVQW-7@ QTJ!z ʲ%Y0rHQ`̷ȥNR\AfzZ\'8(2|Bi:”vڳꁙ']V ӔUOJ>A-VPIU70a8XaruA5227n_W5L(W٧e;X%Za7bVJ;Ö,֠kiurba9ZL*.`% >0h.;Re@CۨVS5S pZ\'8(@|,ϡ$"naJ;R\')#p&œ]7RO<gΝN묟-?> (^7ћ$0tk:TRݶJe >˽7t@`t:G040[!XKg[ qB QVZ2LvX׉cŎG@=偳&*ЬѠdDGH=2QGTPyC>}̙3<ȷW\qE:~wgl _iD$>ׁ|1  ^r_T P/\[nD gnc.TB f順`/n,ĕw%+Du[j0q?`_'mb+v) _ƅRu,BA *hx\p-?U;_mݺ5u`'N, (*==/R 3;WI+}jʰW .'zVOq2PFiکX.1 j.x=Np @w`+Ȕ,5 Ψ,y,; *`=~Fe.I\M?Ɲ袋ӧ/Y?[B9~lM 8qV-ˈX^9Hݢa"ݥ`hBqi \5WG&A~U12ٌ*!*Yx=Q0Yf\zSlMרV3Jd9n b?9ٙm+g&tJyGϟoku[.(ӎ-f 2]J &G-U0Fk,p/:bZeU,pCjULYkzƣY%+Lf)&+"%j3s0-AǙb0';S]z̄.诒շwݿۿ}w]7GGG;]`nݤ֡ "by#uwR- QKe+pUk+`k+ ˁ VlF ܐZa,Sh{VIJ٠6oq H`vrڌ+Lk`+qΔnGc<3;A I&f*ZK!Ne6a[E%Ig,ǚq:tAD]wlGfTCtMoABqi ܣW]FFQ:˱V~U12ٌ*D**Yٴ"QPwǕ&KAmKUAW,EKLfTg++vu`+q8hN,J?h-f kgĪL9M:c9֌ê?2.k;#u,ݢ U88jl.Y#jR[ہ%+p5Ύ%TO~ٴ&+r͵U@.s5-[=ovؑt-oi4W/A'[+\NJI+'*iTZٱ2kRZ%PuSuyTg,Y0=DK%j$,%ʲ SFj/y|U3K Y;Vk7K4jSi MV0'k$\j~-:_w`p\pAzk^#GI?^AjEcNUI"QwXRiMV9ɒNbǚDji G%ZoVRy駚rPrqX fJq<{t(y;~x0ww ǖ.]zĉ8&YϬu]WYk0&ى~A%QdrpBX#RF,)`e'Ȭ̂e\)9Q< XE DjCn*BԷ`G˔P_X. zGZ ֿ Hj\M3vqlCsY<`h{Wתf|sfG/X6R?se._YK-' 2bI+;Afe,L>)Q.Z R+rtU;Zr5|S?(gM\H@UjˌcM(<`G+vEuأLV5+3;_]verߣRBØhg'A - EXmP'5K19 4Yr9q`܊TBu2+'dmȭnjeB+[PIy=#-K 0d!&86!Ԋ9!{Wתf|sfG?g?M7ݔկ~xƌt%J&gu:*r|4 EXmP'X֜UB l.Z hh& dmȭnjeB9Q,z>ȎS?҂'}@+_)UdI'4k4 jV8^V]TWZ)3;_,F-vڵhѢE'e|ƍitV__Ν;w 7)ӧO2|4-[d7oޜ<]'>/| J8鑼n0u-R Laaa͉&ݐ2@jY!qD"8j]?UIݝJy'r  UbþY4J+ }@+_)Y W_Y ^rjiI H(˾孬7fו,3:={fJۻwovpxx8={nGWQe)l4AX{Xs8yI7 0PĨ*tVj,Q2ƥr@OURkwgR^BuȢ~XAoA0M/HʗjJCoWVf&Zb;jR=`!7R+ʲoy+~YueecNk-=&M=H:ח=k׽ΔCIz$vyNt@.+`#]aUy|LȯV-|IkP /Z +MI=#tHr5Y e=[FQAM\4PAuSIu M .bRR?jdj15XUd+X`SBKoԦCKOy-ٳ/ 6x?'NhDwx1SOEX]ӹs-Zm۶LŠgc%]5 >Z{ΙEj( /@CUarC~J`~0!Z!V%20wӢ+xjCsa h& 6xW+d8VF$A. Lbz R] vbdh2v%jolZW؎ί=k"lG}Ci[/}M7t0?r>5z*F'OFX]__^3S1h9NbYHrfB݃bw+p-5:QXnȯYi&D+$*DZ`Z4A~Omq.,Ud5F5jʨ$Z>ȅ)Y WOP.bRR MUmU`UkۑYgUh'K.'vmO:UQi w{ 7NRńEj({ gMc=eS iVδaZEH8QU Yj3 tF5:L`#˚W~BV@X>P]VUSDTW],Ť8cɫ.n(T3HqZ*G?׿?Oi/tWU &tpΜ9 j״půHc̙3ϟgA;_1*6G5(xc5k2A`G߸p-5z9eQ=e򫪛TC3-YKeu#U`G[<#ڐ;JgTSY 6y۩Ӥbd ,N.+)Y WOP.bRR MZ[Eƭ\KwZMUd]{-b+WLlݺ5;+VXP~ȠgVGc7v0/+k?կnf030N[o@db-\2)AP jUgSrGiJu@&UJiQӧ֕G|#\U[3Ue8v'.\( *,>{::zUW͟??;xקvԙ3gn[n%,kG;:>`u֏eSFpqɳLoa]TRU$RAjt@D)꿺5F&-DG`hn$JU*S ȋ;XT;LA@&2O\@K(qP9s/gP5jʕO>'> /Ѣ8z://߶m[__߆ _)Sرc|}{ >|رcэ_eg!& &+ \?z䨟WUDHfrnp \r&S вq?Vz*AQӧwv ҙ #8VdM,e'T#8Pr _`jo5\hN~7~/׿0Ν;.]x >٧G>}3:4>x 4[dIu߾}8WjIDM#׬V\,HkdE询>Ȩ#)e_u@&;.UE?@%'4PQ?@ p̪%%^+wO=&Xb#I\34%>QRqTRF:`-ĻHRf%KF΂'}A3~[lSW_Y{Ӥ>dEaGo#J ~UI&oWɎ sU+pIFɩ: TPF:jIuI:SO% XHabҸW: bGTTd\>UX .RdTO[Uhm%?'d~k+.8}ɊŽFngQ,p[FT$ŷbTݐɎ * q%C˫*Jj׹P@:+2^'`*\.wıkR[&Nʸ|jn=X*"תQ|B).$punٲ(X*6N*J:,'ë | fԆG.Z^U]rUq{֪7骬15D&.Uѧxp5 *`2P.>qFR$FCE TWsAkYrew/n+˂4鰜 N:(`*UlЪpΣ gԂYn'?`ߤd5HWVyXFvրZf2;xTC$ǥ DVKŒ Ȃ S o_u^Yĉܽ|j_4MWI,&=Tw| f0ZX.Z$*PVUo` 5rM\$+<,yOqD;k@-3Td<\}R"bId} dA:_Wպu,0'vD~v g| vrZXG5KOq\@dT,ef dA:hu|"aׯ>ga9rʚ&"`@ =Tw| f0Zec_UOEYf-ZѵvMlfS]%ӄ{e%o).hg e& >XG5KOq\@dT,ef dA:huW7X__>[8/_e/z`%z:^Krr^q~Q G9S5 t)$UӬAk#*E pL~p`OqD{j@G-j(DږvxĒιual0< byWG}{{}AJٳgO]m jW|T)bD?>VCis28a_9{`-6UCB 1߯f E})˥@)XWY_}*H9SktU1:3F;804(E'U5MAI{WK=ZWiЌ3FFFi/ԩS#gϞ?O~;b_UCد =Key]X `YWUNՍҔRŁA>ze\5KU#dkT"` ֦=uv᫥-]뫌4ꦛn`p͚5Ν w7,EU+0'ŏ0܉s߲uد pWx<Kk ODjhxXh}V=Qe#jQYF-5,gKzŁA>zW޼Ot[,}Tрd`VeKCdTkG2eQs)hVw+{`ٳrӧ_Ta? @VMK eb&],-Mz(GբNՍ[jXD lYWY_}*yZ>XXe=HY˖ɨ>֎dˢSjlu%mT lfŦzX-Qw'$.*>1+* "XT+ )cVKD}`-\ uGC\&{jMZCNHbggP4pP ,#OF4ɓ<{Odq9_J0ٺ(Ԛ>@` A/zFYZ#ReiXUBt#P@UL=\XaNVOAeRbr %?*NSE k7d-ਭ壨Vr,]u|3g yf~3I'۟v? &[Z٧"V㖰bߌbrR} 8puz ,dgDO.QTQv* 'Wh8^K 'kGm(Er+vgZ_ը'hu7e/կ~򗿼+U GT㖰j~eiXUBt#P#u\kqdZ-5 +&W18DSEih2\x-F2|ʑ'|˔ dMOWo|rرci.qU"r*PRaUDK;θzFᚑ\.NbYe5Frƪu\kr\=#W].*3(`\u5Z%F5w]`=-onEr 2%Y_K,I}Kozh_f{?O]ve鄴rMnUtZHUA-8҇kF^2r! ;e1 (rUVrq$"@^\u@oqDhIvCSr)~ʑ'|˔ d:~uzfϞ=.—ӧOkxx~+9 k}'EyJ@* b4_U׈"V/ I9A&U э{]*kUZʯjIXabUd3pi KL M sТQ+G-S2@n8:3R, }cU"쯢zWG`Joa^ &#b's]yoμgGޥaZ cWڳ A9GrwVLLPtm"S'ɖ,j&Q>K7Tj\ցeU&U|&쯜FvK_JIGPMXA~͉/ y$kd0<]L.&~x|ȵIzP +DY.MIږ[z*dygp*I4v뎵ctW9Qdbt0N L%j^qkB\kQW V5nmDKjy,?U`z'>UնNe}j (|y%D!~#X/mkm-[j'>b^.f7JO?ʏ&+49[[n$A5HἷXk܊*W]? `4CFƭZ?%X o[lAzR7W )ǍmOv~2 MNnw>IzP r8-JU.OlXmp3;q VOn ֫4*XW )ǍmOv~21Ea\L>IzP J[%Z\VUrkX(V[}2C6Q5[d0<֫4*XW )ǍmOv~21Ea\L>IzP J[%Z\VU4_ߗ5vZz^G>o]nNy+!el Z]@ GL5VQ->d'^Mn\L}h{;LN7^QCWҵU%rfj70&j.9~S{T5"U .ü7g`kNTe(ሩwX)Z &+T~UOJk^ cʣzTҵv,rEziߗQ_7Q#-t ̹ȸfTHerUB0hvOgwyO}_KKUA*"\UN@_y|d|4-[d7oޜ< 8vX:s…Q}_%;v: yK촜}B 6^ZJ> >GMuWrrg<&R5kV޽{ٳ=wWȑ#Q}\_%<_쯢 =ccc&MH:7*.w4DJ:VWI' UtmOWOU8qD#gfӯz*j$_}sW}{_4!aU:쯒L__SWхk_S }ΝkؠԳ_<vgJg-V\Fu<Xc!W'.2lczWU^;3ʳUWڵkk֬I7m䱐O~N~{ߋ zL=;USJ$&,LieUW]5_?Ϝ9s뭷r-`ؘ_>}G ?\|?0p z*`Ym۶mذ;2eʎ;'4T==|pѱcǂG l߾=yg?{Wa_to ЪcR?)_`W;V&1;w\tŋ.\f9rd3f8t_-Y$o߾ ? /}W_w__C.+bntXU2ߔ$W/Q"ʳ;B"`U*zL_o`GWyaEgrHkik%?'y*zLZ_5)_Eײ2NWj@E `xRl u~mԻ"mU `5$+Ͼb[쯺 W.ZHEڽ]7Wy-tj›6_ <_ŧ*Wj:+WiJ)@+ޡľ*>+WiJ)NcU|aE *`SX`D_(JWUaՅ"] +bݰ쯺WkaE,_WՂUR?H* +bݰ .N?"] +bݰ.@&OZH%$Q@դ5Rue*Wi8.Z_ WU`Յ"] +bݰ쯺WkaE,_ aEWĂU 쯺WkaE,_ U"] +Z_U`Յ"] +Z_U`Յ"] +Z_墖UKB_u!~>N]jJ8I"U._U>N_J4\.dUAX(jWiJH3rBB_ 4k *.H3rBB_ 4k *.+H3rBB_ 4k *.H3rBB_ 4k *.H3rBBjI]aE5j|ğ?!6H3rQ-__"TTWX\\/M*+ \TK.Wi|&i@.%+״wڵhѢfϞ=΅G]z̙3?.>ǦO~oK/رcQQSt )jﯜO( ;w1~ɨgu/`t!]+BJZGfBGRk`jgҥ=.XmR?_R:2k4QsOÍGϣU'O~_>=ÕW^yE}[mB!$ sK.^x…>`#GhƌUܹs'OF"BHjƟ:uF}3B!o4dߟΙ3c!B P7ʕ+nݚ|+Vx,"BHjڻ?(>9MXm2W9uYhhj2@%1|@uv~s82^xp|s==ܓ#nÆ u$me WZ.&&fa]^SS3ww}W8-^__dd%Gomig۷ɭ[(5x@17 DI~uxMhjjjN:|͚57npPXX4щ'{e^?pw7,--uM4vh[tk&~/sR;4YgϦ'N3f/CiΜ9#0_#qF5)oDGܓ&Ksڵ}>*-""XFi;+G^nnn6m\3)}g4G}':w5!!!ov]]LVWWK;۷oP;w_*"8`uXAF7s̪ر#((H2'OPFlԨQ>M&;;[C z\JcFYW\"ǎHTT4EF|ff?#}P&%e=4r^HHH?3رݻwUتJ 1nܸ#GfR[0 ""VFV_jΖȑ#$/2+ggΜ`~٬| ܺuK2{E(K?O2E}IileT^]v6ZYd߲eLJO?ݻwӧOJ_vSC]׮]`@@@}&s<Z..4v3)ŋZYY6ͨ4!C̟?humƌR5wMIIQ RsjQ(͛7U:ԾrYVQQ&)LJLL7ʤ4v3*M=$. :kK>6mDDD? Mz+WٳgFF6GewUq?͐7%u떕ObUVV?jJc7ҬXb͚5&nnK`SSS%@igVSS3o޼P9}tLi࣌yu~+i~c٬W׮]4r[={7Iil4E$&)LЪ^h$-ɓ'Ur||cK… `IIccc٬WW^lkmiƎSr fnK#Ν;]4EF9s$o>}_kz/ߍmi^~e?SK.m463:j$^TT/Q[V]*##C7P&}>''G6l׭['l9h6j۶m .tj._r4ѢQ&QiVZ%͛7냗.]$QivWP}L;u@il >\6lXi2cRsιs:5W7o|ͪɼ4N\3)}LJ#TPPs=?jԏbi41?jԧDi'OJTVVaO;lnݺ500f0)ݻ;tлwoNTTTpp 4JcƉs yimֶm˗266vҤI](mKsz(..N"G*2m4IU(--1B&#NiJJJJNN8qرc(p]Xg^y3p (e3?;,f߾}cƌ>r 68R,s4hиqz'|rNAi*,,\hQll_ŋ=zСCf`PPǝ v]BBBRSS͛VաCΝ;˿C}O.^ӥK5U믿޾}{mٳgoڴIͭ[d3<#vM6m˖-؀nūU7\… wܴiZdٲetnݻw駟,nHo)RՂ իW;%N]Ѫ+VȬAݽ{W WN*64jSNE:uTTTw2dʕ+b{WGm۶sM*EVէOjAʈ)K%$$:JII0aB]]ǼW\q8[nΝsMhrUu֩oQ5e眙LKKKOOv AiWPPL<Ν; ܞ={j֭[;w 3oнK.,P_~AM0YB5EZ@hhӾz#<"HKKSꇧ_EڷoE>ymۺtbo߾={ !d vرUQQ̍"F_K&Yڰ3g5j֬Yj v2cRx^N:u֭[eӵQuA眞裏_~5DDD\|dJH[յkWƟGj„ 27++KWJuuuEESp޽AAAZVGP<Ϩ)rPMNNv@+Rd?_yk7TΝ;LMMUټy 6NYZZ*A?[~k+etvYRReDԩS!!!ZDL||E[n3g4u ={Vߵkv3f8RuQVV"dffN:M6G>>… *+W=z8-XSS3~x?P+K.U8pTXXxbuYhѣG ͛?Sܾ}{qEEt8 PС,"wyeoܸ!,-[o?gUW_}O?VURR-ջw˗۵A}߰ endstream endobj 6 0 obj 32660 endobj 4 0 obj <> stream x}y-J"R I!"PD. c[,:&I,RǶ&ꐡU+#r % LA#"""wݯO}<~}k}}/{Ϟj@{ 9cUFҊK&..XXdbb풉i,+Xdbb풉K&..؞2_aK&..XXdbb풉i,󕝊׶ժVk :M,+XC05XGc]&E!`ky|e"yFءFVX."y5C]SD5O0+XgvЪVk :M,+X;ZuЊUX;ZuЊUb0_YѪV:hѪV:|ePP[#\)k'P[#=5EtM]3nJKD_rb+?+J%ը򕖈&]H.YdA*[ V,VZ"*\ݮT2gHmjN`-bhA+֎VbhA+֎V|e|ekGZvkGZvC,j @ubCmp")k`CmpPD5Etv"utM05XG׼e|ekGZvkGZvC,+X;ZuЊUX;ZuЊUbP[3jk75EtM]3jk")k`WO:&`k2_aUX;ZuЊUX;Zu!E:hѪV:hѪWv-Չ5՛"y5C]SD5O0+Xǧcc]utM05ob0_YѪV:hѪV:|e"֎VbhA+֎VbhX+; `&}[YJOrVy?rpqt6>)k'pE1 :&7Wv,bhA+֎VbhA+֎V|e|ekGZvkGZvC,j @ubCmp")k`CmpPD5Etv"XGc]ut͛X+;WvkGZvkG>2_aUX;ZuЊUX;Zu!:1ءFzS]SD5O0ءF8{(k" f;\et`k :M,+X;ZuЊUX;ZuЊUb0_YѪV:hѪV:|ePpxϟlٲŋ۷ ~{CCCͪ75EtM]D۶m۲eKess[~֭[ |#"yf &\wuٳgO6cǎ͘1>ʇ(t`k :MlUWׯu뢋k֬  hen3_YѪV:hѪV:[UUccc|]ܱcGrʒwn/W9ѪV:hѪV:[UդI]#`ky[UԩSkkk;;;0cƌԻ#`ky|e"֎VbhA+֎VbhX+;5-+ڋV V69gVVZ"|؟+?+,Hϔ+-L.YnPCVWZ"R9 j @ubCmp")k`CmpPD5Etv"XGc]ut͛X+;WvkGZvkG>2_aUX;ZuЊUX;Zu!:1ءFzS]SD5O0ءF8{(k" f;\et`k :M,+X;ZuЊUX;ZuЊUb0_YѪV:hѪV:|ePP[#\)k'P[#=5EtM]3u|:F05XGc]&E:hѪV:hѪWv,bhA+֎VbhA+֎V|eCmNvTD5Etv"y_Y:>#`ky|e&}[{їJ&'ẘJKSrgeRr%Ʌ?+mjJJKD65sWvkGZvkG>2_١T'f;Wo*k" f;gEtM]SD< `,butM05XG׼e|ekGZvkGZvC,+X;ZuЊUX;ZuЊUbP[3jk75EtM]3jk")k`WO:&`k2_aUX;ZuЊUX;Zu!E:hѪV:hѪWv-Չ5՛"y5C]SD5O0+Xǧcc]utM05ob0_YѪV:hѪV:|e"֎VbhA+֎VbhX+; `MEtM]SD< `졈)k'Dpk/VZ"[)YnW*pFDT69Er&' RjbQŸMNv9CڭDnSs:\nkGZvkGZvC,+X;ZuЊUX;ZuЊUbP[3jk75EtM]3jk")k`W`k :M,+X;ZuЊUX;ZuЊUb0_YѪV:hѪV:|ePTfwTj+75EtM] =R[9=5EtM] pm =WO:&`k;_͚5 ÇW,bhA+֎VbhA+֎V|wnٱcǀjʓ~E:hѪV:hѪ-r׿m?hѢ~ۥJɽ 'N櫒}{뇝k{MEtM]SD< _6{RY>C]SD5OT s͟?ٲeMMM/޷o_ɻtww?×]vGx+Xǧcc]utM05obmڶm[]]ݖ-[/w{|w^0͙3gРAAF]rbUX;ZuЊUX;Zu!櫎 &\wuٳgO6ؽ~髯ɓ|`~[.f͚`VRSSk]yg3&<-g>{:uj փ[+@A;vW\Y^4[ikk 2vg$TD5Et?O kE[m*X&M cCӧO/?ȑ#]b?gL*[RW%+=ZYʙRXdX)geEsfx{y睋/8؇3g~;ٳg;;;|ݻw?Cgn P;uuu2ߌ Θ#_Y:>#`ky|T̳aÆm[# 0bĈbWWWPQF3k֬믿fWvkGZvkG>;_͙3v֮]~7taÆƍWfHssԩSz뭒[2_YѪV:hѪV:|u󃿎/E$>|8(Œ3Ix嗯W_}s "+K^y]UVѣG暃pWF.))kw8qb/,0aBnÆ ݸqctqڵ֭[{EKSNV.WF8{(k"|gO}Si'U͕W^?~ˣͻ c^gg#<^dɋ/] [sʹ:>#`ky|o}C /޽{?{y͛7ܹ3rӦMC ٽ{wa W ǎTg7xc{{{^wUz~ΏS.wUɊG2YʞK{o,Qbv{$~GUݣF^dTU_l> WcƌI.^tEgu֚5k ֶ8t_D_~ogdE7uX'm/};)GJV5Ŷ7 >HɻXpM2vS_N>}=#|}g:jӧ'ַe*)z~ VOMW~ޭXn@irJޫR5,dJOO&Q8tS ֣gѻ>"d}zlr}?W?Tv%HHFXtpU^ɣdr,rڗ#"C姡ĉ—oƌ3u*!m ؿdsωmx^7KaJ%;0gwmKjb'wMŎŞB4<{bHݷbO6&_s~}IVQ]fN&c-VbGfvZ,KJi~fQ}ܦR1\ڳ8T,Z< $7Hn, ^Rd@RV3M>z9trߊݔq/W g|U9gNɣ7v#6:җs 3i/H_f:۔ñ{=M{KX2N#W/["os0$w8uLْ_v?vn)m!>\b;0>tj1cf%\h{XlW3ZM%F챢gԧz$˒LW0uh\ZR7.Cj`/ԕL'Z+y`$Lʞ%R[32ם~-v]F{';@4%z0>_ 8pȑ }g|7?yfܒUƋ3yع.(q|p%J=_fe1ћRo=7%{QK=]O!YSqj`eߥXL{tb䎥>bI_K6+%d~l=Y(iHv/žL}ԕbRvUM>nMUFOM$g bq(v{+wzmc/*ѕ.%ejOؿe:\uUN*Y{{Ea*0_e0/LW,vR*⊭$oM=gjH)%b~v'NJɝ>ڎfƖI7M23idA9SqF/2SkzXӓof$$  'VbRSk^"ע{RFR7%Vؑ L@"hx,ȱ}K.Xb{XrM<ݔ;SK5ub)U(Vތn`ž{܌";_M[X(6T&nzpEÌsK 6q^שJ>SM.& O!YԍܙԚdp=/Xz_2{t%(MK-H(gF{Zԇ.src^RjˬIj7| 9ܔ^;2w)3^ײ:e%"'w مԻgɝEjlQ/S_h^'v%(Up^Y4Œ ymޚK\]`ƭ%w}ܓ/c+%bw,v>gomSfw+Z𪹒gC| K}AsL>sOv,u72Kʊr?#'ٻTIcO*Vnb_gQtosvܙ[WE7|YG/bŎ}Rx~?JR/v#f]+i>HeG{Ro?2{A;fɗd(69*R;[wbH}7e/puiuS=:;rz\lf6v|5yW_r|tk}Riߓ\,RrHVtT|;TNzzQ3/\73^Ƨ>QlH3-o_^t3M}y`Of%{<_%7+|a#Aq;bHW|ZFl3Se|&ԣw_Iʜoaw;ur7kʓبifo\X*ﱩL%V7Ʊʹ '|Թ+:PEʈ/^|_+ZYgx#GF$^z2_^ PoRml걝_c8RKUke+޾(zAIBW7x㦛n=z7~_UDyADzwyΗ|U@Oz|cǎ/?i>`WWWa=~ӟqzgEtM]cmת?UV6Ї(ZuЊutM0yܵ![ Vm-RC ~"֎VbhA+֎Vbh|'x"w}=|wG7{w~;}=+X;ZuЊUX;ZuЊUbn'|cXե^oo[^s} ~_}wmyܱ`2՛"y‡ /w"y"j…of`,butM05XG׼w5kVggg;`"֎VbhA+֎Vbh|9>5+X;ZuЊUX;ZuЊUbFNp++ +r&x{ѷoߞ.T=3p")kp_*ィk{f졈)k'.=Çr-s\+"|VWO:&`k;_577;p 7;vW#F(m}w,bhA+֎VbhA+֎V|w뮻>ޛ馛=]YfUE:hѪV:hѪWW^y/[lnn8qⓟdTp) /,sˉ'+#\)k'FYfCޙc2C]SD5O; >ϔs$466[N1_YѪV:hѪV:|;pwwwn^:};+X;ZuЊUX;ZuЊUb~ . ؇3g~ߏZ'Onڴiܹ _N?я\UG8q1cjkk NN=Sq")kahmm;vlM{{ɇڞ8{(k" Of'O>Cf o8K8p ]=u|:F05XGc]&֓|ekGZvkGZvC,+X;ZuЊUX;ZuЊUbP[3jk75EtM]3jk")k`WO:&`k2_aUX;ZuЊUX;Zu!Npk/VZ"[)YnWpY1ZiaJlr ?SVJDT0geC Y^iH&;lP[3jk75EtM]3jk")k`O:&`k2_aUX;ZuЊUX;Zu!E:hѪV:hѪWv-Չ5՛"y5C]SD5O0+Xǧcc]utM05ob0_YѪV:hѪV:|e"֎VbhA+֎VbhX+; `MEtM]SD< `졈)k'pE1 :&7Wv,bhA+֎VbhA+֎V|e*s=7e˖555-^x߾}%|ekGZvkGZvC,U9mVWWe˖Çݻ7^ PRGGDŽ ٳMݝqGjk75EtM]3@Iׯnݺ5k;Z"yƠJ.ر#X\re"XGc]ut͛X櫒&MT=xС`qwI;C-ȕ8jJ/'^|8(݌32HmpPD5Et%+]vVʸ#_Y:>#`ky|U҆ *mܸ1v`q֭wdUX;ZuЊUX;Zu!/_<8o޼/LvkGZvkG>2_c;w ܴiӐ!Cvޝ}/j @ub(Skk VXظp={ 5՛"y5C]SD5O0+Xǧcc]utM05ob0_YѪV:hѪV:|e"֎VbhA+֎VbhX+; `MEtM]SD< `졈)k'pE1 :&7Wv,bhA+֎VbhA+֎V|e|ekGZvkGZvC,j @ubCmp")k`S­zpdX)g%W +g gWjN`,butM05XG׼e|ekGZvkGZvC,+X;ZuЊUX;ZuЊUbP[3jkO(k" f;gEtM]SD< `,butM05XG׼e|ekGZvkGZvC,+X;ZuЊUX;ZuЊUbP[3jk75EtM]3jk")k`WO:&`k2_aUX;ZuЊUX;Zu!E:hѪV:hѪWv-Չ5՛"y5C]SD5O0+Xǧcc]utM05ob0_YѪV:hѪV:|e"֎VbhA+֎VbhX+; `&}[YJOrVy?rpqt6>)k'pE1 :&7Wv,bhA+֎VbhA+֎V|e|ekGZvkGZvC,j @ubCmp")k`CmpPD5Etv"XGc]ut͛X+;WvkGZvkG>2_aUX;ZuЊUX;Zu!:1ءFzS]SD5O0ءF8{(k" f;\et`k :M,+X;ZuЊUX;ZuЊUb0_YѪV:hѪV:|ePP[#\)k'P[#=5EtM]3u|:F05XGc]&E:hѪV:hѪWv,bhA+֎VbhA+֎V|eS­ +ʙRs:Wo*k" f;gEtM]SD< `,butM05XG׼e|ekGZvkGZvC,+X;ZuЊUX;ZuЊUbP[3jk75EtM]3jk")k`WO:&`k2_aUX;ZuЊUX;Zu!E:hѪV:hѪWv-Չ5՛"y5C]SD5O0+Xǧcc]utM05ob0_YѪV:hѪV:|e"֎VbhA+֎Vbh*{/[i+y~.8pȑ#8P^UX[oضm[]]ݖ-[/w{|w^0͙3gРAAF]rĪTD5EtU5tttL0뮋.Ξ={ڴiO_}'O |pP3f/_uUj9s}E1 :&7g|URW^y%]UV=z5\sw{͇&X;ZuЊUX;ZuЊUb 6wƍŵk[n;-ZK/EO:U.WvkGZvkG>V|1~˗G͛w~{gg#<^dɋ/] [smؼys}}Ν;/7m4dȐݻw6xǃ <ԩSJ[[ܹsN N2xjmMEtM]SD{ӕ:pȑ`O(Z^ZWWחo|ѵdw3g P2_oʟŸPDARk?O͛7`g?DѵΫpzrk@5||#1bDl1baԨQE$?_͚5믏еdwm+W &[ߚwU%ks0w ]K~NV߃k@u|1~˗G͛wۉMet^dɋ/][XגeߴiSmmm +t-/O|]k@:~xpBmy;w_ {+ޗёsN:s .2e}W،b]{7| ~}'McŶk3dArrt >'NN/ vO<=xlhmm]`+o{Q]JvkMdGFѵ~ݵ/  _СCQtߔyJ]9gϮyϼy/ggÇVlpw# 6_;رcg>0aǏ=zW\q7?ݱ+r]?I/An{{'LpKO>dSSS~gx6l@7x#NyOp3f̡C f۷V護 W>籐}]]ܸqcmmmt*ضml'`;ZF[O|Nzz,&__z޽;vSFY.sO8ܹ3%\nݺg Я%~Ne!R੧ nG>},.OXO>dʙv:sk:;;{:_ܹ3uɒ%% /dWw}?񶶶 o6E{[o|կ~55R6m=zt3W_}5Y9JW᯷JZxUR2櫗_~yذaSL.zo޼裏{|Ww Rr-W~/s=wϞ=e%ww_җ _G·m߿Я_0p4 MTgg?\tA(\zOtȐ!=ɓ >_>\ 9s7.Do{C=/@իgΜ's /~qwawy &iӦۿk6ihhK.~^z7SOV,aڵs9gĉ~3f̀ų:رcw?OoRZwp=+V(riS-:? endstream endobj 7 0 obj 17163 endobj 9 0 obj <> stream x݊0 ^hVa)Lfg>@-e_Ɏdf%-KwxO8xby~|Č 6" 3#AӬqB;<a~'$d4h?k8T"IwsNI{bgKB'q{#JGw&2xCY<N(kD%֌NJTTnQi;Y7/USjXҏ#KćuO5,jl:TW&͙&F91UlaҮtgupUkߛ(7EHAD,mW. s> stream x xTUMQb@FEE(Dƴ ҭ>δJЈ4CCZdlli#؂ "kϟ]ϵR۽u껧I{9USBQZZ:bĈqƍ?>??֭Vxᇳ7ϱf͚fqqqVVVYYYV^JPTUUum̘1!Cׯ6 G4hPFFF$*bpB5 O}GBs-^: a7:N]/H PQ5?Uǣ?^@k۶m׫ɓ'}ܹSNU?x?Lh UYYioܷoj8p`}w1x`kUP-ZVcѯhwY~vJ"!?GO;/XGzzzFF_cyylNBX]]};9~:)cEX",D[W-[kQmݺu~_~w|EEX",D[W͚5k޼_usG9R0_ 6",bE&YrssҪW4hP]N<9`{WXXa+2ɢMd|UTTƵ{n{ƍU)S^֧3za+"VdExjѢEj\/7Μ9S5^:.'OO:U1}ye%EX",D[WUUU]t),,7>O>WWWϞ={ڵ!X*.9T|EX",D[W+WfddlذdɒM667o{ӦMC+k׮9rdQQQAAA^^͛C`Џ++Y| !_9'9*_a&"VE$6sCeWF,^YIn&"VE$6sbW!n$ha+"VdEx 9zxsW`|!_95m+,EXĊd&2fv,,DXĊd&2Br 6",bE&Y+Cr 쐯0_mBrNTs4JE8m",bEXĊLho!_9|EEX",D[W!_a`&"VE$6s+ +琯9+Cr믰hha+"VdEx 9+,,DXĊd&2Br 6",bE&Y<_hAr 쐯C;+q3In&"VE$6Am6z_Jr6",bE&YC¢MEXIm"-+ 쐯C;+琯9¢MEXIm"-+縒BU++-DXĊd&2BrNs:AHa+"VdEx 9zxsW`|!_9G+ sha+"VdEx 9nܢMEXIm"-+琯hha+"VdEx 9.櫰۰F @>+縛BoF9)6lI0x׏_ݒWIn&"VE$6s+1G-DXĊd&2Br 6",bE&Y'_Y sW`|!_9'*pc_%EX",D[W!_a`&"VE$6sWX4Xa+2ɢMd|=W|0\D(+琯9z믒ܢMEXIm"-+hW1 ha+"VdEx 9U̥G-DXĊd&2Br|e,ɐC;+ \ROyto_%EX",D[W!_a`&"VE$6sWX4Xa+2ɢMd|=W^|!_9|vWa m",bEXĊLho!_9|EEX",D[Wџb!?=j&"VE$6s4}Y sW`|UZZ:bĈqƍ?>??֭aw9p]wնm۴]79}tؽ◯|{$;F+ZlXSSۺu\r*Y5lPmƍC+,,DXĊd&2bdj֬YW;wHYYٹ瞫v2dH-WX4Xa+2ɢMd|V]]moܿA"|rKӦMCo|fh{ԢMEXIm"-F櫢"5ݻw7nܨLyT:묳BoWNj@\12_-ZHkƙ3gF\Ӎ76lX❯ۗ| #UUUU.] Çӧz ճg^voK1,Y$--m͚5uqW!%_|Uwc6lni&ͳV:uJə;wnX|$ha+"VdExJvڑ#Gm޼~=tК3&NZRSS{5~|߾}WX4Xa+2ɢMd|  m",bEXĊLho!_9W`|!_9'JgMp9z믒ܢMEXIm"-Uv$|EEX",D[$䫔XIt 6",bE&YHH)>qDT|zn'q B2iҤhwsXBvm1%:~3RJEEE {?~Ć|n=j&"VE$6 됯hha+"VdEx 9+,,DXĊd&2Br9+Cr 쐯+,,DXĊd&2Br 6",bE&YhW۷o_ӟB¢MEXIm"-:͛t颌5~a}>+3\ve}O:bŊo/P1*F5 @:MFw^+++#_Ů&_Cgݸq_o={lUXXm",bEXĊLholJJJƎ{17|3--M[7\'ʭ⑈$֢MEXIm"-:jƌ555~wں:+,,DXĊd&2ޢ3_uҥo߾/Ν;I5b#\%, |muM4} x饗ݫ?= zժU&L8Nxw~w3!] MbD|գG:{+Vߕ^ \TaIEX",D[#GZN%][PWX4Xa+2ɢMdEf~Xtu K.%%%u8+Š$ТMEXIm"-ըQ|?9rnd>|x;VB+d@\tEO,Y}2{[v>˕W^y뭷.[;^|vd&VaIWX4Xa+2ɢMd[J&+,,DXĊd&2"!_n9cƌ$6WX4Xa+2ɢMdEB߿SnVUUuM7iO HW 6lժUvH4i"Ē lW`GBb޽;jjj~S~׃ ۵1.&_%EX",D[$䫩S6s=D 6",bE&YHWy`cЎ}N$<_aIEX",D[$䫠X zU> @ bc؎B;b ] @ U۟}w'jXEEX",D[$ݻڵرCq}$ʢMEXIm"-{+,a+"VdEHĒ{6zҿ'OݬsLHB$䫢H1cF;+#!_>deebŊӧO';Q#a}.#ω`&"VE$6 jݺu&Mj۶g_b͚5~_, m",bEXĊLho,WZ5a„lիw}~m 6",bE&YW>.]:nܸ͛u_"6hIXUuY|رcU?srrX|?~|޼yyyy7Nt_ $_꬛+x"_8rH!uQusha+"VdEx|pDw"VEXIm"-%\gϞD"vd+"`+"VE$6 JI&Ǐ_n,--1bĸqT[Eg͚ջwo vv/9?fBwmHW?я?=s_+>|a5k֤X7BuwkNCȧ&M6a#V}s< @ӭz-m:ǯ]6YNnƌco2dH~B\|^;wCϭZ|U_#|_|n.z饗: .TZ`Q8;Jt_St1NO$rk2Drsha+"VdEx|eQQQ17m[o"O>uճg^v}Սc~F>|:»]$+Mrʌ 6X7,Yi&ScoڴSaÆh#//gϞ/bGU]=?."!_ʼnk׎9@Ť͛7U7;05jԨS,$a?4"!_1դI{]UWOÊ\WƟyX",D[$ Xzn}#WwEXĊd&2"!|Q]]e =n "+'4]",bE&YHH)͛7ώVZ5h@B-+}{O @?RJ诟A;wW{~ hHBbL ,+W;l_*1̻wEXĊd&2BrNSW%+m",bEXĊLhiɻq*BQb,3DXĊd&2Br_n+!_9'yU)@ _9'UT$'+x}U"g޽+"VE$6sWZ\$6",bE&Y*D{l1ɢMEXIm"-UEEٳo;޽رc?>}:] Ez#|iӦ?? ^|_z  _8AHڲeK-Tg}TWW;vtڴi͚5S%!_y}"!_^~*D-_<;wٳg~Ԗ z3cgU-DXĊd&2"!_ZJupecǎ{O["'yU}4Xa+2ɢMdEB/~q뭷lڴi'NПh!_7%c$6",bE&YHW?}'zПhIW+>슊UWW-5'ZWuCp k׮n٥K$6WaH*$ /-ub+ϼ{WEXIm"-U֭;vGjJC~)Կ",DXĊd&2wut f{}$AHW|OT6eX",D[$$ՇFj*~Խ7@z/WHH,W]uU$5jDK`JTO\|3K/3f̈kOb|U"GB:z3チDxƓWfa+2ɢMd|_$;a+"VdEx|cǎ7.YdΜ9?|MM~ȑɓ'wڵSN~޽{0;_EoX",D[$+ -[|ve58pG+3t믿NlWbH:wW_Zjjj*~YgWEEŶmۆ:a„u^W>y>UV[fΜiZd*\|$|HW͚5T9*;;[u{۲W^z_ "VE$6 *33YoZua-;v쨽w!_ _ "VE$6 w_eec&Nh>}f֭@W>Wa+2ɢMdEBbYbEjjj&M6lh$޽{7hРM6?UК?~۶mNև_J`O$ L,v-[#륥GItw@ W_5~+g#ϼ{WEXIm"#-)Gl+|u",bE&Yx+_kEXĊd&2|U[[;n: 0Uee믿~%=I L,|ꩧڵk'|3 3lٲ;LOO2Uff  W~D2 ƟyX",D[Dڕ+W^Vq1kٳg'A!_AX",D[䫊?z2Uzz]wݵuV! EXĊd&2"!<sڷoO:tȺKB+?Hr$YfYG +++wI^XW~0  0Wݻ̙3Omϙ3' EXĊd&2"3_Y־7|sw}.Kt@|i",bE&YHW>˻ᄏq2{@ Hfd&l߾='''ѽ*+EqqqU L$3W2:6_ݻ",bEXĊLhiI>f@Wa+"VdEx 9@Wa+"VdEx 9 d|U L$3+琯l@Br믂z6?]",bE&YC ʣ",bEXĊLho!_9ǚx+|Q",bE&Y'_y&sWAaB i!_9|&Uii#ƍ7~[F믾7fUPXQ",bE&Y֬Y^RRb,..*++ ]1'ƿ+"VE$6#UUUUnƌco2dH~jkkC_>q5-+琯("VE$6#… ո,X`o>}j AMM|EHNWj\۶m7_^5N<9 +W`N 912_qUVVۧIhU ugZZhZi I0322`;uIǯ쏬WDX",D[W-[kVUn: +W _yQEXIm"-Ff͚5oܯ:~չsH*ܢi1]",bE&YrssҪW4hP$+´@bd***Rڽ{qƍqʔ)Tz};)HBW-RZxq̙qՑT _3IK.Çwٳg]6hʣgY9",bE&Y+Wذausɒ%6mm0o<5M:uoߣG"tB@X",D[LWk׎9 //o{C?>w|`SN?uJ!_&X",D[ W`UhH6W!_&0o`$+琯BSv |_&NIa+2ɢMd|Uh'GĊa+2ɢMd|Uh&ǺioLzja+"VdEx 9 o~NAr*,X讷;|P~T^'$;Wa ?K&ФDXĊd&2Br94eWX",D[W!_b!_ a+"VdEx 9̡+ l-X`d0nA3 8WnY\W&&"VE$6sWnYWDXĊd&2BrEK+-Mzja+"VdEx 9̡D|WgȄlEF&W@6ps.!"S]D,9rR_^=EX",D[W!_k Bﮄŋ",bEXĊLho!_9|%+, ha+2ɢMd|uR*[wl!X|"%޽AItw<s(ȁl_ F,%",bEXĊLho!_9|%B’6",D[W!_ɱE,O%Q",bEXĊLho!_99@d0r _aEAC6pDYX""VE$6sW, 0",bEXĊLho!_9|%BCm",D[Wa%r,9̡d"C 89 4C6p[⚯xhܢME$6sW/b$EXIm"-+琯a!)a B}Ί*8< 9v-ھc ÉỪLW,DXĊLho!_9|%ފQA3UY˘If&"VdEx 9+,,u*Z7c86#ľ&M$hd&2Brs:9SERaN0@2@6pshS"\tc9!IL$ec؆ 8WX4XtZ\?6{TtrG;聧E&YC¢MdT立\<_i5F8bxgU#֢Md| m"S-8Bo<1[VjZ@ 4!QZZ:bĈqƍ?>??֭awaTΥ9#EW;q7s>h&Κ5kKJJYYYeeebĢ . cws?a$nݺ38dȐ~ֆؑWX4Xa+2ɢMd|c…j6,X`o>}j 6",bE&Y|ضmqq!v3)cEX",D[W>rrrlTVVۧbǔ`ԝ -)w+(Q*[,KFaᛴXmdz7EYό|Eό||I~j:ubGB6",bEXĊLho!_HMMmٲ_cMM֭[Ѥ'6",bEXĊLho!_h֬YW;wcajCǎR`Y&==ĺY\\UVVW\1p+mlٲ%X?~{U7Vʭ}ڵSOC6iDvڴi[Ċ[cٳgOnniΝchB\gի]yE[ݱX-Rg޽ .x뭷b1re,o={?-6 YYʕlڴITx KSLQyE[a5n暚uSš}^r%GY*汄}ks1$-UUUݺu3fqȐ!h=o5Zn[_~gP5oyrk8˗/kOu9'R?"~y_-[|嗵rk8z8qߪ.Hg5o+k~s=J}jx{G.4*Rn g_S=رRnEտzj{z Y*ϴ[nE' :K;V/Qχ^z\ʭ|'˖-[^wRʭs9Jm6_SN:5aÆ5hРR]]kҤCIO)c b0Hf ugɪɓ'k(駟Nwy=޽{և[*R.GE ~V*~MݙT?T<3wܩS竨J;VѳgO:KU(,,߿R.+TEn9sUsq8*lүK/U5re, 5cطoj8pR?e]Ti֬ҥKR%!*~Q|71XMwq3@=_j.GUhҤ߯믿^|g5re, ؎8,>KF='*{ W>\N?ٺrx6RE>|#F|'K2kktrqZlwoTٳiӦ?яGT<~XCNJ2?۷Wz%N9NԾ썣GሜRNR[ QMG&Ӳ[_J=Ǭȑ#|ep,~Nl\ʕ+'OPÆ U)*޸qcBJ9f_$_9/jrkcԭZ5j\)CCub.|8j-EEE~GH4Ws2S;׿7^wu1m, z?xeΝ;'[o'HWu 877硜rk,s=WU2dHJ<>H>Lmsrb+sS-Dou)QܚL=z)'Ydy?zO9*gR-|WjU3gNEEŞ={yLU-ړtna, >wzj RAT%*{ B+ٵk׀\Y(뤔[6m4Qbɓ''0Pb)wV*Dww}[ܚL'/pXal2Yzn<1tíjN݈#:,WXa}/?]])X{ks1$3֑ݻw7nܨLR*|K6=b+^999 6;,RLmֻwoE\)p~Ç}-3fHW.Vs>w\5 ,X{ks餈+bN6mR4Is91tíjn=/'W_}R16A2SUUեKB{Ö={ڵk>~:33ap *9qرcSI|hURKiɒ%iiik֬G)ϴ3:AKu,.VT\c]رCêŞܭ9}}װaÙ3g:T<]`Td 3-??z:ucpRqΨQ-/hkFR*cQT5U_Uի ۷/~4<5_u,.VTUm߾}ǎwq7|RzfخsUxGWN?_?f'5aixzz 8a[ݱD.b0ƍE-ӿ C9g޽{׮]4i>ƚɓ'__.r .xnjm~P7ZWUTTT&M+^8F[oUUUv~= 2$Qjޚ7o^[[koo_)r5?.8oq[w}SLņ?z0"Y***VXq=VUU=jսѣGw~E-[v7\^zj7ou:cǎj7tSÆ g͚bWW^y^8jԨ3CmӮ]Ht 0PSScǎ.޳Z֯__Z5C=j6mڤ~8pR(=b?y睷{n;N>ҢE p²k׮?fffqfϞ]RRZTկ~uܹӺ9h {9s樟 BO[JN5GСwߍPҰ@ |R-_,}?~xmmm޽_uf*rssW[*pR]]nfddl:s~f!|["yy穖w~E֬YyϞ=* i>=zt b vرcVKmmm؈ 2iٲeJ=6nX7p?OԽ7t%J5M4P?wڦ&BK`_M:5w3kfߞrf|g"Sj]o/ߙUVw1gΜHt j/;|pR|F{,z)kALrmk1͛7[hĈfz |x>3<㻖Bh7i|/RͺTjjСC-E ilof} <)U0p ]*OjD)xG.i7x] /olĉc;*t7hРYflwժU}QySN<ɓ'Ca^xJb?=ڷoߩS[:e{շ'|rT'zhϞ=֖;>lrrr^yh1ziӦE8cM7Ҡ_|u^+{h̙j>|u}Q5\gԉ C%hD!9$|\sMۧ\,H:Hֵe#G 0$]X4h`{(++;u(*++oiԨѮ]ݝnݺ&MX+Əվ)6Txtv dddrB yDsQF{u?S# endstream endobj 13 0 obj 17887 endobj 11 0 obj <> stream x tT$SO=kNssszzzccv.''#GhjjJMM5qyNzyh*RmذA\˗/w=MMME`kkx5k.]*~qҵu9N.IsWǎ3g4>~vn}]gdRK53#d>&Gi䙏+ 19Fq+/33#Nzx)Ϫ}>0#.vܸq'/| mj V*SaÆ z<qyyy' ?7+EP:}05~pgsD@eUaaaZZ?~\\lQQQSΟ??cƌG+EP:}U]]-v1dɒ5ޥ.9r DOjB8 6n(kӦMZ1 swww3);pW+˕_UU,))2enUZZZ 'ʿ_5qE_@_*S;vh7333w?`ڵڇj}bԾZZZ̙S]]]^^^ZZk.fnnYa0}}8zyXCVW PR)5 vEbɎTF_Y}ep@ҡW}e}++G_5QO_+@eW\l뤜Wn P}}++G_gBE_L) HjT+W+@eE+@q2"У̣}e}++@qT+W+@eE+@q2"`$< WW@2/E'8THr޿G_*cE+@q2"У̣}e}++@qT+ĥ 3 P}eи+ IW+W@2zyУKd_`WW_G_*,B_Wc_E<@~y++G_H JIzqH " +mdC_*,B_W}e}++G_gE_<+@e쿲}(TF_YG_*,B_=ʼ(0.HRyУ̣ű P,C}HbJB_*,B_=< WF_\){:IϢ|ᛊ+@e쿲}(TF_YG_*,B_=< WW@2+@e쿲}(TF_Y$}տG` P}eUҢ̣meeeO9q׿#GM0__.\,}@qj_577766j7rrr::: N9rHaae֬Y3\~bq{챈;+@~T+5qyNzÝh"{\۶m+@q2ujÆ ֯_\|… MMMQb999G_*Su۷O?*kjj|'N}وGW@ϑ}UPP O?x118sh|k_wky_J(A%##~#0#X=2%0===bǍ{$55uٿ#W@ϑ}%hذaG\l^^ 555(n| }(NT}Əttt\uUb#+@q2u0--v?..(yw)C5>̖2⋾TN_UWW:|~] .Y$&.3>z쫍7ڴi~V |ɕ . <2> w.}W.+??J?XRR2e-UV*f㧳 Υ#wfddرC)J)33sΝ֮]7O<%Lֻ[PPf͚E_c2u_iZZZ̙S]]]^^^ZZk.fnnY<Y .#7tSee>{رhG_*SG_*,B_=< WYW|L`}e}(Wʤ_vO+@q2i*W+@egt/5gbQWIJYhQx^fu!Db >eY2\cW>27*g;w.3 PI*W+@eE+@q2"У̣}e}++@qT+W+@e2޿zzz^|_׉F|W+@eծ]34_ӧ֤~z iӦ||Aww-[ϟw^1{W|j $2l W_蠯Id V _*}Ucc \Jb:?Ӏn[d޾JSIW^{1cĮ-[*--kV+@qT,ʺ7~aW:[H8 PY͛7}}O},Yjܹhod},))qb =} $4_ #Gs>޿XnzȲkV+'g’ }(WʒeUҡWʤ_~9#WXaLG_*O0u&`> }%0pÇ2d F_=%%vO6 P,&M:pLL%vjQ1XĔ}؋Wʤt{N+@q2i> 9{Z?W|"+@eUHN,}i'z2d aҐ}Č+@e4iҡC^~0xbNl"+@e_4+@2+lŒcdm0޿z2ϟ?ޤ 9rŊVO+'C_9ڲe˅ Nd?=_*v-Z4rH1#F|hnnu2Wʤ+޶mۂ rssŬFc|o+@q2rm޼";;[Lo„ O=IZ2@IW~===_y@W~Ν[vmiiKUi7+,)ʯ) y_%~j|k@bHjÆ vO P}Lھ>wgrUw2iJaȐ!۷o_lkk={vEEx䲲Έg_rɓ߇X^^~gWY׿+oxiܜبݬ0>G5jYfsWDLpkhK|&H_2˵\.ׯ~+6]vYeeeKKK3qyNjo>x^+硇2~dp d`{}'W^yԩS1aq]ׯw#[n;$pOͧLW[o:tC=6ʷu۷O?*kjj%j*`G2n8KX+@eIW/w͉྾>c̙3'|"N 1XJ(  ]3d<#|aČ } F/~ɓ''y׿꫽ќ0Qz)jz*-,#C_޽sWW׋/8fYy睛7oi{jja=xGcƌGFsp2OID1jBWǎK/}&Z<Çbpɒ%O?uw}(G_*ƏzjܸqxM6kkk`SSgΜ߯x8'@d諀7⢡!##cǎ̝;wXvCvwwk#===wuWaa=:7p/l\IWP^2EZZZ̙S]]]^^.2i׮]{Yfߘ;wn f z+/ W?x?2dHg?8_*v 0s}sGIWL_.ٳGk|ORUR\ 2iJ!;;;7jÇ0` 3ׄI|֏(BJ1Ϥqڱ䩔嘾=7 +󒺯|W~`2i_%Y&QxĴeWrbJ^x*M#TWI @_`}e:}r|^)Sb:5WWVNHT+WVNH2") +@eUooUzĈ&Mz^ .=5#k,|0X;*/vy5ׄ=7x'VȾe&B_`$}gϞ/\L쭷:q>{l[[۲e˲ĽvO34*ٯ^-""w yoᆩS#|xnx0`J_> XO@Y2wt\sM|bWv$+MzWpرc>+?*IWӧOΞ=pB˗}vfSڡ2 P}e˖!C 8PR4h;6i$fL?+g~SX&O<`+⩧:BZ֭9r^6N2q&2`X~oۯZ[[[WW cT r)[' @A2iGB+Wʒ^ogDBX﫾^{sfWzrɓ?Q$-F_Y,{yӵ\`A]]]weBP ɿ644|K_ҿaٳVw!WXT&s_?馛JOO׿)WXT&m_};߹+=z /p).}E(NYrUUUU__.}E(NzMMMeee'O=6.'IWhXd .]tҤI˖-;|l :@5T&`+W1M6]pA_z :@5$+o~s3뭷MfBP },?|G,l`,@erKH/(({!WX ʒ:},JNi[WP _R.e뤜P },yK R@)2"U02<*KP}e}P}e}u P,B_j@2"XTF_Y (2 (2 (}6{슊ʲmmm;< :LW鍍ͺ';wnũQ>}kEW+5qyNz NsX<W6l׵~zŠ- &GUyy}[[[`MMM4@_kP#@\W__~رcbp̙tsϜ9#ɉ+ T@_*S9sTWWڵK;k,;E_c\$ Xdr)x*" P,E_*,}E_*,}p <0^H,3汆B_605 IWe0^+$) P}e0O,b Wa (j<m`kG|ӻEX 汆eLwX 汆bWe0BT$E_*,W?>`/ P}e0z)ʿTht m`^sq +?Qb0r)XCWy汆 `_*cEXCIW }k( Wa A_d@ʃȀ605 m`k(~3WeP61}1)`}k(' C_*,ʌ$m`k(3$m`k(9 `y+XWe0)X}k֡Wa }H H,ER.etkD+@汆ɅBܱ P,&6#+@eEXäCb!+@eEXd%m`kEh605t}hcɇ605t0* `2_Y5T2""H,C_*,*DD7hXCXy,hWa Uf -Wa ѿF 8J^2"):v6> \$= *d}G"ෳb '* m`k,~Wub P,j)B6e P}ehWa Hq8vZ4o hXC8F-N%\l D‘,h]Bqzqg]ˡn5t8Z|κ']Yk9rt->g]}eZÇbpɒ%':l t9N.Is8Z|κ']YC_۸qXM6kkk`SS[C']qҵu9N.IsW\.W~~~UU~dʔ)@lI& ;vngffܹY$9sTWWڵ>ɭmeeev@Bm޼9R ,{R,zw009==QYWWa$ԭ:stcXܹs/NMM ya`8qySNzv @"m߾?c8ɇ~RRRBa6l+~zŠ?\8[iiO?}' A<O" ⢼\ؾ}􃭭bƮYH߿ꫯ~'=jX.\_qQPP VO?x118sLf anկ~uڴi *+++kv a===bǍg˔O / J?dȐ{P" "55uذaDzyyyL ?=Z̙3P" BjvvvǏcFl_J2pp}EEaaaZZ?~\,cQQ]`#B:`߰vOab>looK,kV%vԨQva7n+i&`mmljjkVl'W 'B0 ˕_UU,))2e _ 8|gΜ {kV hhhرcv^ܹYHw}WƊndzf͚*~NNN{ xiii3gNuuuyyyii]D]pW\z5׈ׁ{ԩSv UΝ;'3L>K[.D}ѦO>pƌSpѤI&L0d1XRRb-]YYYMM?.F_[n'?by{⋃#>EooxEz\k/ &w\q>Z\\lĒXl׫<V >Auww\}}@p={2.x. .wt@6}%[.I.`I  W 1f͚={<3SN~pBk_;G9eʔ7x#?/[>%KO?,A=Koo-[}BsωO?4A~{GK_ߊkk׮>;vù{w+W4Xxmvu͝;kV3jԨh& <ρMuVmk''N1ckΝ'NDGW_}Çof@$\p!`/g9tsq333bժUbDDAk9xvH#bOzjު??iuuūDvu~3f8歷ފl+r?[ϝ;z'OkI +,,n655䖨H v͌'Oj#G#'N 8eu։ +1+-i?;ait}e ଷ~sUU8`?M@ψ\ٿ7߬+?ۻΜ9#{D}gS_E|GI0R\\ŁOpŀ#O>uWv1El!oE,E4K)}O?q ~{GK_@J??v… >t70 ++K<{ァ?w۶mSL1nܸoϟa]w(/gΜ曗.]}vY߿xbmn=\EbȓO>yȓ'O>#FUPP05w߲eˢ\kOzkP$޽{/mݦ+V766j#%%% ,,,#w6~:0k,Ek|]d|ǧ}'d^:`匄3f466F:.K__[i t!g۷o2d2sStăX1s韅zN0`oi3g̝;kYxHf endstream endobj 14 0 obj 12980 endobj 16 0 obj <> stream xTj0}W9Pgf$Yډ Ґ{Fe׻AX3̿ÐF-{H6?h8׆9@m29^^r ]O 1ќ~Q 9bO|j@m !u:rhdOGx>dk^:yމr=#zQ] HI!Yp$vaSVw(Q zLi;; q߅:yb^6dK#T)Fg.c" HNKe<`D:~*a#8j{ʹLOQz.Sj. 1+8XE d|LV~5ߠws> stream x xU`X Ap0 EBJE\; eYT;R2S T`@RW6Z(b,m^s.onr=<}s?s@^Ink׺}Ddffzn0%\Uuuu/URR)'77וݻWÇ;w([sxүN81p4x3g}Z-Ι3}jb?.\x5׌;jzW&O|UW8pZnvQVV_~I&]}ݺu/Y__ojyyyoy_/[+**ɱѣGMvw0`Dk8-x@W={{uŪ4ƍ;vX 2a:cU-Ǫ#54۷:u?zH=2eJY|ٳxՖ+W;wn~>soi?rtxo/1bsU׮]|I}.A ]h/ ]w6mڴmw>+-2p@cՎƪ ^zVk:}z\苔>|8UVW\qx˖-'q]]KsxuP;zfYlGi~o7xG׮]{챠~vڤbUVV7N}_F:r^'Z}_|qϞ=۔m ֬7{l?~|ҤI:uR_}J_m۶-33S7}t_W+//zkUԎVXM.//owy:BZK^z`AAj)uۜ~G-v̙I*_|w~{JJJ|(_Ihh{;rr_9/vd;2GN{;{AŽ\ّbG}#w侼#_/ȕ9/vd;2GN{;@L"Hb$1D &I@L"Hb1׿korKGbGF">kwSp>d>2DgLUUU]t3xM#&$oC޽WFb2@L"?Яd>2Dm__%1+ +ⓕH ^|W ~W T~+/_|d$1ȺfpGF"iBUK8ۈ@L##(unݺ^WW̷a/[Ym۶󋊊4p>@C߬ن|@@ZGFGF"[l׍ZG6"HbrEZG6"HbrX.[ZjYj?4O-kV|.A+9?h1Ab2@L {uZG6"HbJ4o^|Dl#1D De Amq/W 0*W?h1'.IP-#w#@L##)v mV|Dl#1D X8ЬA+cADmD &b.WIߖyl93o|˕r@h D &%7{?h18ۈ@L##I6o|Dl#1D &=U) iV|FCS3YYzGFGF"izG6"Hb۬,=#g|d$15 =9 l@c>BJj?4`)Bc>"p7d>21 l@c>"l#1DUL|DF.b26+ A0z'IoVl@c>"nш|d$WcRj?4%cAD^=x 1D^LiVIཱི'H/f|HCSqfe?1ۗzG/ݍad>2AtL~hVA?|d$И|r*|Dzb2 .&Y\5|h16+ AmV|^Ma>"|d$1YYzG6h & HcUA`d>2̘5z=jU( YEBc>EҠ?1̼A|d$ 1ѬDc>"pA|d$1QAc>"~A4|d$1ѬDc>4p٪zs4?1ѬZd "nGF"8+>1 1Dp&&UzG)@L##*.zqDc>?YA2!1Ѭ|Dd>2!.1q*z1+3hV?1ЬFc>"pӈd>21QGc>"MAb2ܘhV?1 1D>&.[|ѬEc>YleHA27֭[G?cƌܒoѣM6yA-\̙36|-kkkբz*g=쳭[V 8ח>7c|YÐ!CWo/^lĈjΝ;۷/KOpGF& @D&OBYY}jqĉ?꩷z2F=#g|dd,V$f6ol_,**R0@=uYӧSRR 3qPCUUUzz̙3jWuuu{ ܠ5l0>ظ[njH/}>(Wry?_C{~#ҥK{\h_V,X`=TիUVK,@t[lə5kV~~~vvvqqqੂUVV 1cL>nXbE}}}W|<D & lV$AFb2.V$AFb2+=H4$ʓz 4+?1Ab29jV-+W$AFb29#V$AFb29 = Ďf7=|Dn|d_%A b|Dl#1(q׬Id>2D@D?1@ Df^0@mc>"p7d>2j1@c>"pGFe+b|Dl#1IV+4|ǎ(BBzGFGF4+b|Dl#1B%h1@c>"pGFALkVb| lV|o̼lYz|r?1Ab23Ҭ|=#g|~HJjwLmD &3#AϘġ?1*q x Ec>=4+$A".[!&?18ۈ@L|F(W >zG6"<71y Ah^jVdr'%}ۇc4Ѭ.D &y&#o+m=#g|⍘<|Dl#1OzF޾l =&?10լP AU0Afc܍ 1OVF-Wb-d>)YYs=#g|"2yjz A =&YAwq ܍ 1hV zG6"ʈV"?18ۈ@L3'#ʕ91A|a4+xA37%=YczGFVF4fKId>3U $AFb2ѬZ/%zI6n xII@=B܍ 1/qѬ/%zG6"*R|Dl#1/Ѭ/%zZV3YzV@)GFcF4+g$AFb2_,Q×=#g|-ˈf0D?1Р\aDB"?1e+@|Dn|dDr_J"jjj#=|Dl#1ɌhV&KIg׿^paiii|;Y8ۈ@Lde+s$7֭[G?cƌܒ4hЈ#N8XP@(**JMMݵkpiii6m}YY%\rמ={|hV@HyyyũSfddB۴ish^_|(W@I-lذXXXW^ƍSrK/}>>"ѬLƗW^y%^/5a.F߿_-"mw_y=zXjW"pgeD2_J"\]]To¾EURO=Sj?{V #~R [ +!J6&+!ثNO?4ӧz:bmmZTOnߦM~M6-Z͡~`>.[qJYti׮]?#PuDykȐ!-ml] sիWaMMMvRSS#> qw_]'|2z#Gn|h^j-ĉCҥ}[nɑ^~(W@"֭[wW\~!bر|5k[ؼy}H-njSUUUկv]a8EL mVd$1`B(..nӦMn SM)==}̙|h={nz饗}̙3m۶ Yv&Ml#1#5+2Dp? 4gΜduݻwݨW^;tw^aiiiZZZ7b-]TԢEC/ةSCEzqmD &Ch~ HF"Wo\zTR+A7s=ѿ-[rrrf͚]\\x %%KN<9eʔÇO6mӟ4L%j8Õ0lذqY?k<͚5k?P+}쀓WJ6my䑠_]eYs_uv~ED &W4@L".cǎ9_Fbrլu劌D &\֭s~-C䤖mEF"=@cL@c>\?1RЬs܍ 1%N.[$+^xo ЯDl#1%B| HF"nxΝ@W"p.?$#IW 7PSSc}<~ر#~@Ε0}?_=QD+\s?,[ /ݨ}Ctݐbca@ ÕPWWcsI ea@D 9PHbYfrzwnG}>~e+\?p@b}}s}>w#@Lp\$îu]IXl#1pيD &\wqGɓ'?Pl#1E_ #IԩSz3gX?s;t,Ҭė×\ry׳gϋ/z:q℻fq}>fx ȑ#SNUUVw}A}Äm=#w#@L6+2D?18ۈ@L _"#Idxj #!I;?1YDc>Zr9Ruum>2g>nf巌"&\?W\8˗w}j>DIe+d$1zxꩧ1j~$FZjG| 6"$&Ⓦ#&\]v}gN:e?ҿ*Be+qzC'hݺKG-hVn#ر{WhVB֮];gΜÇ#{oFY\"x/&]^FDL"}Tu$m۶Mj4`cǎ}\_KqXg<U2*b2Vҷ}8_+//_vŋz 6TUUֺ}P_3d>l#b^x)##&۷o/..v(f|œĝw^zΝ;>Y!)ղ=0`fq?{AZw}nA4A1겕ЌDp?לKU,&A48ۈ 1&4+Č|D0?]tG53 mD.[ȷICeeަMk@\#CGY\'Ѭąu֗]v3\~Ǐ?r䈻fq}>AGs}>w#`rL+!Dp?9s&zYYGA48ۈ`lL4c31`lxg>;qlDp?X" re$ @8~Hg0! hVP[[;nܸ*6555vqg5+Ds?7ؿ8~%w#zL4&AL"}ݟ'n̜pŘhVQKIbpرI&~{ǎ[nY\Fb\E/%I??ٞ."8*|)@L2xΛ7OàA۷o?s޽fq}>g׬bǗ$brW^UW mDHhLKIb|ѬȕO8Ӗ_&\0+_| 4 0 \\pСCgϞ;ѣ_"1&.[%_J"~XѣG,Yҽ{Ç[#iJ6"%&UB$1J/nذaĈ\r… ʜ? mD=&U$1`Nطoٳ/1clܸr\g|?YNzǻtb~Ç}D_3g>oQcB8r?|Y 8^2v, P͛7[|GyyyڵM6;HЯDnF+RDp?L>}ƍֿ6رG$mD>&[RDp?is=wڴi& ,mD2&RDp_Λ7ѣYWcl3\ Ϝo ЯgЬx+iЯDFغuQg̘[RR's={lxw#6&ʕQRD@(**JMMݵkpiii6mj7nܨ>8ۈ@|)@L"HyyyũSfdd4xĉ#Gvޝ~mDD2_J"CAAz 6l/իWG &ny}LCI-8p~Y+W|+I4+>!?dffPQQa_T~(KOp1P}d>2D֬Y͛EEEj h'x"I322¾/ 9*==}̙|h={ݠh8f ׯС޽{iii߈tR-ZsW@Qe˖Yfggg*((HIIYjUO_yw#fEL##IlEL##I[Ab2@L" Z@$=>vУ?1  Dc>"p73blVd>2D?188 Vd>2D?18$T~ HL##IqAZ|O4+AqVd>2D?18KB&HL##IMۊGF"=ϳ7\@l> hV/IhV =#w#4+|d$1@c>"pi.[Hb|Dl%w"&$AK$Pa=Ѹf?1!,1D &zG6jVb2@L"mLl@L##I,f6+^?1f?1|7r瘤 #IgAϘd!#Igq1CF"=kV7=so4=CЬ@w#xYy>& #Ig/]pLAF"=#W6^*W ލKHbdG<֬1(W AI4+w#Yy &##IAA~L~@F"=#賍EtL>AF"=e+!APzqGϣ?1܍f%%&?##IAAHL>GF"=#g@FB=QzY?ZVg=#Qw#X͊rʨ@L"mUĄHHb|D0l5&Hb| |$ A@VzGFY7D &zG64ᛂHbd "6\GF"1A %ADc>\|DH48$A Fs"M|d$1@c>"lCJ)D &zohVp /=4+@܍e+pӈHb|Dhن$0)D &zGmhV㛂Hb|fH4=%4+3zG&Fಕ i|d$1@c>"6+CM|d$1@c>"D:Ь7$7֭[G?cƌܒ~ѣ۷o߮]뮻n۶m1Y\PTTk.ݻ6mv>{ӧO;wnVVzmڴٱcG||rpPYYg_:ujFFz*tq}jK5#GFz}CAAz 6l/իWmW_-[̾RVV۷oח>F\FGF"Ä [8p}qjQ=WVV-srr"m }>>64+M|d$1 ?dffPQQa_T[-"mACƬQJ!J6&+!ث\}QoξX[[SM~Oqi6>o3IC Qoھh]nqqW^W_i>Y%?LOpÚ5k[ؼy}H-DÇO2ח> [?|d$1 ?TUUϜ9ӾUWWg ZG;uS֯_K48ۈ@L##IU:tw^aiiiZZZ7b-]TEY;6`{g_̛7/77wʕa_9ۈ@L##Io-[̚5+???;;8TAAAJJʪUǧNׯ_ߠ<~C7#w[ġ?1wѬ[l|\f"Hb|ֲVmD &$A8?l#1D &zmI4{z'(WO?1ĉcn|d$1@c>VmD &$A]"~ Fb2@L"Oq'z'.fEAĎfc͊D &$A/cVmD &dosp|ZrGF"=\mADf|D |de+FGF"=gBjl#1D &z'Cd>2D?1*W|BѬУ?1fDc>Ûw#@L##IiA6"Hb~*d>2Dyh#\`?hs>4+b=͇$@W۬Ab2@L"?#YY8ۈ@L##I|^ l#1D &bHoV!F.[`&|(W$WC$ٸ},f"Hb2Vҷ}8F|<٬,mD &$C"xf>.W m &$gCxc>nV!qۗ0hCoAb2@L"75+ g|d$1 ?8L||ج,mD &$<)e+$?E|(WEDpY`LAb2@L"L`|hVA8ۈ@L##I39 *g|d$1``0Q" d|(WHaN0 Y dχr FGF"ù8U8ۈ@L##I+Y5g|d$1@s~>+_9<@KI쎸ldI͙Pb"Hb~e+8ۈ@L##I^c5+U\pGF"+͇fѯ>Gҋ|(WJ/Y%w#@L##I^\eDl#1D &Wz1·$ 6"Hb~|UJe~Fk|(WJYD &$J/pEmD &$J/ЬFb2@L"Я@f>4+֭[G?cƌܒƑC_ڵz{M6E>t>\2w#@L##I_<ԩS322Sa?%h>+3qGF"WnذXXXW^SYd>2DU0az/߿_-~z4UffzEP-<8$E'K`cVXaVXa'+*D>}/֪ETO|@\? 2Dju*+++j>rLcHbWa<'NS|5Ib2@L"*5k֨yfbQQZ,(()\$1D &|SUUUzz̙3j13d>2D[LׯС޽{iiiAoD &$cڲeKNNάY󳳳5p>d>2D &=9/vd;2GN#' zaG}#wؑ;rr_ۑP vʎ;2GN#' zaG}#wؑ;rr_ۑPIv)//w(;{ }8HJJJNN1c<[[n5jT~~Z-))Ѽ‡~8z۷k۶m^Mi8c{LvsO޽)^ѡC 4bĈ'N(b7Pg<ɓUX9s|:\ve]vYwޝiӦt}sR֦M;vطK9(Ƙ6nܨ^-Я)FgTVVv%\{gϞ .Ƙ֭[תU+){Omf߆44mj+++L:5##C=ƍՖGiF>gS'T:+bQ/믿^vAF1CWtڵm۶m  ]: 6ط),,TWܯjٲepe߾}틜mw &n,1E)AYoͮ(z )33S=n:aEEy}Ͼ 1GBZ բzɽ?-srr시mИV\O74&BjedmZW^ܣGUVmCFKPLoS;vܶmʫK.}b|%ʳ326Z}J]]}Zjr/?OǍ&z &;;CU,Q6mZXٴikoCFKgmݺf zo/?Q_ݺuXwom tf_4cqqW^W_sp& ꫁fq&s9W^k.55վ i8*/6lg}6bYΝg߆o{ߢtFÁz뭛n[#G}،"qK)##K.Qrr}4WO\jooCL$Ew|͚5jembAAA?|)S"[mxHqf})=ZW]voCFKPL PO~AӧSRR EyQ3gڷW={oW8rH^^^Mׯ|&z)B!(%(^z̙3ve"%(aÆWXO'&W<44V:ݻzXZZ0K.Uh"c1o޼ܕ+W^MSѯZ,A:W/bN:dA2^bz XUjժՒ%K/HLDQlْ3k,S)))o9uT~Bt3g%"Fjet)S >|ڴiGӟjdTXXxUW3f7pÊ+BL"∳M|d$1pFR">~x^ /l#b2@LaެY/W!b2@LPWW>sn֯_߿Vu]7o<_,]SN?y;v7΁.,Uy;w /؟nzZZx;c=UPP0l0h9O?;7n }vСt*c=vUSS3iҤ?t'|ҪX}}}ر3gάw`_̛7Ou'AGMOOW)q_]zMW5 &#馛mQ,-NYZCںuQg̘[RR"YcT:s9眠;K,勸կaGӧOSʕ+ B~\s5a񢢢]vYwޝi&4m4X޽X?~ /c?~.++Sx6>YU[o|ٳg[駟\V k׮O>P . 333جfOBǨ(?ܥNqA@}P-^Z͟ رcϷ1bݺu n喁Zj6ׯ_٠zBlP^^zak]=lժW\v;¼KI~<,Xкu;e]غqʔ);w|WΝvء?<䓿կrrrᄚsĉ={vtɆBu7~/{uyGN4hP !+_YFE. $>¨4|7GjԽ{s=wGQHNN3f̛oiuո/_nѣ?۶m{Ξ=[u*UT_[[{I&uI}JWZ98//owye˖Y~YfYǫŰ_0`??Gm}j0ShRLOO9s}1??_-Sg?֭[ׯС޽{iii.%Yl۶u}Ay˖-999f...,W?2U endstream endobj 20 0 obj 17826 endobj 18 0 obj <> stream x xU$EYaQAT AQQgXTep Q@A'(dGA" , Ⱦe_hMݩȩSNu8f…vmyyyn(tiСnHԲeK"'|FdZvnW:;sT|;vj޼y #j߾}]t#9Ms*.._RF eٲe?Q[֭[uGQFկ__6?~>|3<ӽ{oq޽رcΰa.۷355UbΝ[nnݺ)S***̋[pС'O+W:7jϞ=N; @\:-eeerq:|?S7H=j? ݳ>POO>dϴ_|Q3~x@O>|֮]?'ѐd"VAA7߬}С@=~\Ag}KǞ~g}y 6uu5_s`ӽ{ݻwzՊ+nٳgmv;vlZ~p7w;@{h>UOE, EEEjۇtԫ|͚5}Z䐃VTT5o\_~w߭Q0mVaܸqjњ5k|UP@=~\Ag'_Зk_~! _|͛?ڴiӶm[vکWV?C عsI'dd3Ziii=vٸZ-|E}1W_n{1$c;+HO~hYrjy뭷=u'|~qaǎj"޴i_|ѼTo_fܹs}Q}Պ+T8SWYN?tUj*ZNuVx?'x"55aÆW޶m3F)..V?[7RVVFuO4sy믿VyO-z>y橬e` =/Rc~<3SGpNZRRⳝ{r-կ :tP1|N:v^9_?@;|ϡ߿_G W_}ոM1bJ^JjގϏpWa+..3gNRշ8pĽF7x?餓[@"s;xĂ16;p$aG1KvH#|Gzq8wᰣ%f;p$xbŊM6(ՋÑ#l/1#yGɷq这XQ2#IFu$:ڌ3{~|=TG2#HFuJJJWCu$:Q ɨdT{dTG8 $Ց _yՑG$:Q+yꩧ:Q ɨda+*~5ceZbb4 -T'~Z -斧-^_yipH2#SҜ?W <*YW $?0@0A$ '"_y(HFu@QMV?/"|=LAQ(dT]K '"_ySdTG8 $qKV]`p"NyMIYY ~^``_|F*dCU,XOnZ'xb֬Y60J% Q(dT'B=m 0J$IFu*d N`%c G$:Qb{8!8a"U #q-sV'l`8}I0p((HFu@QG8~, dLAQ(dT'BQJV?o`Q2 ɨpH2&wA0pB}ERnDEa./FĊey'0qdTG8 $ձ) 0J$IFuV`Q2 ɨpH2 0 n 0: J#8aEBN[`%ɨpH2IKV dLAQ(dTRj$8a)H2#,#6YiG0Ćd 0m24$G0DU$+`QDA8#,q_J#8a,qxDu@%Bu1YiG0%pH2oW'.`u`F0p@4#L |yxGu@y:~!Dnw F<3yIx#YY 0J)ȫpHxWF0p}NV #vx`$YiG0% Fu@Wu'YiG0hpHxNB2 0J/SPb:Q W'1F0p3  #Z'+``Q2($2#LTuHV>`%5I&:\j dB Eu@I*#F@B!YG0pH$+;`ǥV 0J&Bu@Ÿ:$ 0J dTG8 $Y̪C I&nxG$MuHV%xN[E`$ 0d#FɸD2#pAG0!I`uHV#8aɨpH2G-C`wUC0p#6#F@\ Y d\@"Iju*`%B2#,ꐬb`Q2^ $:Q lVd 3gfeeu933GK,𢢢_~K. [ju]wm߾=3 Y@aÆ5klպe…u֝>}ݻcǎm۶ݰan/TĪ_'|bg F7p MDe*sIRRR/_^o|s TcvTxv F$@08~xF:t ׯ< x`=ɨpH2pJ?uQNNNe8vX͚5j 03G&]tE}0!IfTd%AQE={ {G*xOKKkҤɺu;$+=9rDG[.[L-jժU\vez;W^yEڶm{W6@e XZhZ"oJN%K9į[()).]fZTNjs}c2x`;40`i&ơ׫Ev6u38ÈX۷on0z:Q iɊH`ǎ:Z]~!##5kZ_o3--mvmLAQ([R=8tui~~TRQ////W?ZJ_3hbv#އۘ$:Q !5H`b˖-EsUz| }Q-^hٺukӦMu>|x}0R8`0t$˗h'NT'}uQso7n\m<0QHVq@tرEN_O  0J$."YG2#F A0p<`$[3NvwaK$:E@$H`Q2 ɨp+*r<}$#8a)H2#\4 Dr O`Z\jA0pP`  d\ .dG01IFu @\j<}$#8a)H2#\x"YO`d`HV`Daa jd$,.< ***fΜչs=z,Y$Mm޼yȑ]wԩSmVC<3% Q-E<}$F0Pjذa͚5[znYpaݺuOv8pwu];w@o W1IFu ^ xH`0m4u *S'M|rQ٬e˖ 6\xq0zSdTG@ⴕ<}$@08~xF:tPQQan/((_~VVO_y _|E}0$+Yf=zuQբUV޽{[h^<0ױy  8PrrrE/nMֵkW;g0@* $͛7WGa뢼ӦM6@efLK[F!IU]Hhiyߜ֭[QXYF-SN-t]S^ &|wf~:@#qH`ӦM:_tjjQrrr-4iDOҥKSSS׮][m7}{0رcW֥*U{J@10`Z4tj$+9 .ϯT뭋x 3Ψ> pAzz:-[X͝;W-իW;_\ҺO?՗W qdTujE$:y  :8ĉբ࿁}QY˷֭[m<0$qW(dTG29s4vXW{v~a+VEaLAQ H`PXXؤI]4nX#G KKK+w]vVWϘ1Cs=Wm<0Z1`0eu \ոxbsk`޽͍O?XWB%,d\ YT'N9q dmOo$c ,Awʐ STG2WFJ2 <_x,=È $$f@ H&!?~^֭[暷~NF0p\ž!׃#G222|8ׇHV"z09rdƍǏqƢUVtM/ )$+s=ta>v È DA2i!YV Q\wq{'=È $SN[%@: Nk/w&l#` LBuHVAH(: 뮗_~Xw޿/gy#XH\F!\׃]Zly'}٧~`6mnB0 @Hw뮻TJNNnѢ<~; &h#8aK$quvPHF0p(Sd* <}$: a}/ bSUxHFu2 #  +`i `QHV%'-_L0ŠK$s:$+gHz0=̘1GQv,$#` ꐬG2#_V}HNN6뮛9s È $s:>Q\Z6mڑ#G=Q-:tpWr}E ;;ړ'ԣp>@"Y`p뭷SN 6tS!s}DC //oԨQvR=)//_zu޽տnB0".Q,p*xHFu$ ^yz꩞ԪUKRcǎ? aD LATUH&$>|8//oر?{WXXXVVvB dSdCrOɨd2;TTT̜93++sΙ=zXdI0a7\_0@w\XiӦ^z>p5lذf͚^Z,\nݺӧOK_|K% p @r=$RL6M=De*sIRRRBcǎo^|og\?ϥV~Gln5СWԯ_?+++>|>K.QouHVrHz0{~X60k,uG.߿Zj*֭{+/a ̧:$+ixHFu$ V^ݴiS+8PrrrE/.--MZ)H2:$+xHFu$ n5k\y(6l`]ٳڍumG3\j{\o<\1~e˖EZv;cƌQΧW!+*_hʴBb$+!Zhߜ\n?C۶m {n;ߺu>5k֨Eu ?XѣF 節hs=FM6,CׯWlСC*\H a$+#Hz0(..۾sN;߱cB֥k׮ ~Joyܸq>+/a zIFu$ ^y;xСC֥z/rw)H:Q ɨd;q|ZYŖ-[Ν+c۵k׬Y3ktjݺ13ZH4}Y܇tСC,_M8Q- (  @}0(++ ϙ';ֺhIܿq @r%|'Wضm[TTkҤI׮]}KJJ7nahJn_}Q+سP#H&3|)SԁsssUŋ͍}Q{A0XH笨pH2#য়~[?| 6LMMAhҥ 41V\\l\R+/a 0 Hu@Q\oדרQc!mGEܬ.]dfffgg/Xڃ>Xvz(W@H \*/HUH={qc!q}`z0xg?֬Y3g+Vz]# z0ۍȹ?䓢'|Nrc!q}(DSɊG$: {1Շ ?XٍnB0" g9{ΊG$: ?>hРwy'++K/قp#` rJ4.:Q ɨdG0<.\ 'NN|#Y@\ z33I$++QF]vm֬ȑ#wq曣0VTG8 $Ցf /gϞqƥw߭;%#VIX:Q ɨd.++{-[>3;w}"G)($1 IFu$ n:rO?}-ߕ/ #6 G0agj٫W/{9dΒ v㏟z:Y]tEov|]%a0 \ /زew]vm?"]J2.QDB:Q ɨd{wѢE7pAo?}OB)Ji+#HJ00n QNJ2 39J:Q ɨdnz=c{ޣ|bvP+cǎ?c=+GXr%̟??;* d {B\$N@Q`%K)(.J $Ց`QD%YiVC$: 0BJVaG0p D!8a[R+HG0y$+W(dTG2#Fɼ:{ҼZϠ@QH2q/) ޫP ɨ4I'r;^0"6`m$+#G0*#Fϟ$ $Ց`Q8<8N@Q`%)(nwI4H2# # `KsVyG0 <`Q2ɗ($ԥV~I*)lTG2#FNA 4ՁF$: 0J&p "YVfH2# #l"Y@" 8a+HG0d `Q2/Q YzuHF0p([S^(dTG2#F\HV6!HF0p @0pd$8$t" dѾDd . IFu$#8a,zS*r@G$: 0J)d^ @Q`  0&#Ff`%bUppH2# dLA6^ @Q`% o  pH2# ǐ 8a  rG0@83b̙YYY;wѣǒ%K?lƌ:uU';m|gѓDK\$Q ɨd* 6YfW- .[Iw͈aS]@G$:y#L6MTI&,_ڇ{͛7W׭[jժ^zq:bv:a@SJ^ @Q< ?ިQ:k*((_~VVVsP~JS۶m376tN<0dYf=zuQբUVy'Olmck׮mV@08p:[^ ~)cHV@0h޼: 6XE={ ck֬Qر=0SO(dTGxG߿ߺtٲejQV9%9駟ZefLK[F!O!q%K9į[()).ԩƖozٳ>^O[G$:{0شiW~?$~z(999޽[I&\?އ{ E vءUiiuڵk;uwׯ>^B.ރAqqqJJ:CYqՇ~رcÇHgx زeuܹsբ^z/]v c rڊK$:Q ɨdC~96qDo={.r{a_2)H2#H`o0vXW{v{n:j\m$IFu$@0(,,lҤI׮]}KJJ7naNG_}bcǎsŊϛ7>  c:vXSLQonU/67G5XTTtW>hʕ3gμ 71^y#3hР7ꖥK6h ''ǼZqqqWBXZZz1c7Q>< TҥKfffvv =k~衇#F W}{0JvɨpH2# cTExΊ)H2#HF0p=5)H2#HF0p8./#Fgq`)$+ 0:"JɊK$:Q ɨdG0i+ ɨpH2# cbA ɨpH2#[ݗx¥VE1T\0#FHV#8aí[rdTG8 $Ց`Z.b G$: 0$:Q ɨdG0~p `HVG0pèLV\ IFu$#8a4 ɨpH2#Ć1~O[X0'A%ȿe($x{K$:Q ɨd^ .0zSdTG8 $Ցu>^MVSdTG8 $Ց,ރ;\j7H 4HwH z.GØɊK$:Q ɨdq $aLK$:Q ɨdq ?4 ɨpH2#`$c"'+\!9H2A8+"0#QH% Q(dTG2Q ~FSdTG8 $ՑLN0kV0IFu@Q$pwIVBr[Ø @2#\Fb2aUHDA2#HFrD̆d ɨpH2#I&Z)H2#Ht"Fq|h@4a$YWpvY\ IFu$#_9a$Y9)H2#HFrSH ɨpH2##KWdIVx  # O"_9"a$Y (HFu@QWi9mcLAQ(dTG2#l#LAQ(dTG2VQQ1s̬Ν;gffcɒ%^0Hʪp5lذf͚^Z,\nݺӧOH iӦqP8iҤ˗Ba |uFuС^PPP~,vHK$:Q ɨdYfA=zuQբUVU0r3vi$:Q ɨd䫁A?uQNNNFb@LAQ(dTG2U lذ(//O-ٳgQq h 9Te֥˖-SZjUvz+B -B -ߜ֭[ XYF-SNIaHFu@Q:6mׯ_%''WFᨎdTG8 $Ց,cJKKK׮]+:Q(dTGNqqqJJCYۿ!TG2#HFu lٲźhܹjQ^(ՑG$:QCZG8qZd@ 1Ñ#l/1#yG5g5cǎ.9;;wQ43`+B{رſVDŽ Ԏ͍T'h#GȸNm6Nju^~K. .HOOoժ]wݵ}v:THdO?,RϰaÚ5kzjݲpºuN>ΖӧO$'bise /T++:pwܑ^wh5 dݻcǎm۶ݰanQ ׯ'Xק:@2 iӦv5'M|j|6oW_]nݪU^zƍ}L#z1;vX+W ^[lٰaŋ_YE:7pzx~~q]vTH@Ǐ7jԨC>sEAAzoUi+~TTҥ$(Uß}} 4Pa$E:LNNV-..yޝ8x_:t( fRG>jѪUw'O 걵k׶s:fyyyݺu+++#_YX{hBNW@nUgzׯ7~fOį/TϷ>$'''dPJ+[17iii6vmj]<r:ǎYZm̙3G5^tE֒%`u { j޼j44SzF֬Y۱cG=0wSVV֭[ٳgLVҽm۶-%%EfTZ X >s߯GU[&M[~Oį#G[l2UVaG{mܭΘ1cn6ITW UXz)ԩg^7md'ӧ.۹+-ZԶm۫￷q-)h֭}N:a[nWޞ={l\^=j3 XJ Խ{wzL0o---ݽ{ɓUK͚5x =6w'Ǐ7yMA=n;c_^-JNN35BM\&Mos:JOO_r$`u*+P&M:O,]T=055uڵvzmOngaD~۷~Oĵ;vF5|;TSPyyx+Q/+7|qBLVҽO 0@-:tx?qϚ5Kyf=/oߞd?O(Ob}y>'~Շ~رcÇZS_~(,S)@Jjjjoq>.TV+H[TIX_3hb>{:}Y'uF|Gz⧧-[XwW^K.d׮]A$:ڵk֬9zG[?vu*%HwpO $:/MnڴiSÇI?СC,M8Q-zꩧlaϞ=ꍞϽ\K|[O򝗗g]/[͞x[ٷoެ!ZT7nl'WSرc)1cWU0:թt@%%%Qɓߡ҇~qMJH=*s_]Oܼyl;&`uϋd {.]$;;{|ڵk?CFˈ#dI$VuLVUTTݺuk޼yǎ/?'[Nz%y{nӦM{[o_V'!gLD9"'r9=3rrz"1Q !gL@O| clÆ LA>pH2E4{@ j󟙂|P(dT)Ȑr)>ޅ:Q ɨ X";;{ӦMV9sfVVVΝ333{dڸq]GaÆ5klպe…u֝>}:k͘1{ᇃiӦ*W'M|rQRR$_?~QF:t0ԯ_?++hO5|WfRFm]ԿhժU #H8pZ4|뢜sH5|W͛7W6l`]ٓ5|WGыo}ԲeԢVZ%V֭[֬YթS' 6mڤբ_*Pڱc^TZZj}ڵks8&U|U\\:t|D^*PRբ-[X͝;W-իkdmĉjSO=Ś>9sEcǎ.: ԩSzhԨQ|E&M:SG DW-@W!)))޽FcA6l˖-jG͛7/..p:u̘1# * 0@?G5׬YsNw.X@Wz+lf3*֥'O>>ƖyiӦ:O?5n8UU"6mcE@tE۴ÇhB=N?t;vK |.]ZK/MMM~g|>l6m|W\شjժڭ)mQ߾}߭[3<'̑CvkְaC_[nٵk^gffXfM 2o۷Ooj;:tPs݅^ /?~ܼj<Ԙ>-[T>sL6{;{͚5:tzZRRvZϟ5\S~:ucҥ֭U[G/v΄wIq)6@Ϧؔ2x*օYw;fqZ7_'. v?l0 cZxwzi˟x hЪ-ԩSՀ[Kꫯ~eGcU]8йsgL n=a竼RG9^O>˒~a^?2gz24Nq>ciԏ#FG~C:gg}<,Z vFGG^L_|Ed\:k,c2_`zU/b^|⊴4vA5jPխ[*uΨN2f͚* ة[x vh3_9;Q}`gS,KdօY>o޼_U[R׮]u?aLPf*DdҦy'|aO 1we:ujx\ջ>C5c7>S~}*To|vjၬ[=TǮvTV38: 0#<4 5_-\P{FI6mz d>jY|ʥ[V^~ecG@5՛Ƭ,ըޞ- ,^oWmn׿e^MpI'vu毨בȟauN}6Ŭ:f.V22+V07~ᇪSN1Z" FnINN6Ȥpĉ#tDmm B*JؖTu aopge;%h"c;w?/!CG}4FUvixWFxhvju+h/4hPPPPPX76xiFfPaڷolvw}V_O?M:tzHp>s;IUyVVV6wܛniȡo9s^_QFU{/fwڥ[^\:o<^zF1ی h1hgsIwte(u #_;Q;/ [glW hݺuI5\F޴|>PIRիWv6md\'o( _ +!?ܯ@GIh۶qE}Y^^^6mL}"<4; #_y뽤YOe_[/HIbEYWO-}u=jvF5P}WZK_U") [glWzǏם_xq#Oc؇jQ"W?jϹz;7r3|@@/7AVMվ?q+3WN?WHMMUIMgj$j6~Wʸq㒪.駟ճ>Y7k ;E(O_ve;vػwo߾}6lW_Jۣjת]ߩh*}9HJw?(øT˖-~'Zռy󒓓UjL[O\{ MO>d_~R/--2e s9'Ȧz-}9^"94 /_8p@_0f̘zg ~ A6f3}uSO=e]_Zdc/*_խ[7wUJۣK,Q2_UsQW2Pb A<'(~% ZӂuM>P^ڼys ?o߮~^{6(TA5뗕 2ĸߍ_~>+IaРAzS%%%ɡoxOvijJ Aj7J:z?}F/*NˆU*.E#WQP70 ؔ2PBJ{eGR=͗pZPWV2ZB*Jȑ#۷KU\Y4a۟w7,ָڇz|$U3gÇ{곸F6͇dKr9P_pUV0Ǐ-{]$ܯq- nصk6 Yn}/F֭oce>/^F̍gϮSαcwڮUݲ~z8ЬY3WȟaqIݢ^>SpϦ2PօY58g63nRal6 JߡCk&jN g}jTAWp4Q/C (ƐڼZk]3;uޝ{#.7%Y|D1nCW\aݱcn4y0|^g}ݧ2ߛ$jժէO6mlR=zy6Dxh6kU]j7{ ~$@U/Fj*V}}Ȟ={{UWe|ȸ#6|ݮ&|+T-zjVV΀+xע2ߙȏZ zVW[֟' lY)uPo]HUiSMk";4mTw80& ."_žUpު|gvکu|ɡU[e|I nO/\0'OWQu]›o9|pu\_08g:t۽hժUj"5?RPPyQFTD^V3$r|'tB\3ҬVǸK$ dddȼWzmܸq҉B71c7C&J ƍ[r_,qqvv~j\_w}%k!xΝ;x2O^iÆ 3Zn3[vmnwvQJpuq{~N߾}gj׮}u]K. aE)ަ^ξ{߾ @U" endstream endobj 21 0 obj 23060 endobj 23 0 obj <> stream xUj@+lX+qa!ĆK~?3I Twӽ2gXYo?;;.sb\"#Q!Ow[30MOObX<l?;}xN⤌;qGC]-xVb Rθ8kkA{ iW4=dƊ,h騅/^'Z"~S]8nI#{,Njah4_|U.k{p\Ew`ز/d:"Uy;g+ȥYBA*ҴfYƒGNn=k$fHiHh&bm-w>J+z &bGb|{7maE->>cmY{SY5Jz)жДFD¸eI4 ^,yVy2V.3ħ%0úh6î5U/Pu]N6t#0/=$ޥ,-ripJtѶ V3jV%a]+ʵT"Y%ZզsZ.6_߷e}^h G֚ endstream endobj 24 0 obj 627 endobj 26 0 obj <> stream x a pY .J;A("c+UWu$]o 常 '*q =mEpKmRU]]]o}?ÙyK?OMozjzR)rwx1@!U*Yِ䭰!6T⭰!6T⭰M#*̆$o o o ElrQa6$y+l x+l x+l(e*騆p4H8$=ΈJ:! G3AFd쨒jGA#h;;~RGA pb3*~ǽ BA#h! 3N2$  wʞ,՜Uq GG‘A0JWP%LG*3A8$  W֠J:< h|H853p4H8$=|e T*Y"9A0JWP%w&GA# |% Uq GG‘AtyA p+kP%LG*`:=_;h J|% Uqgp4H8$=.WP%ghp4H>z$TIǙG8$  a*^"9A0JWҔib竲Ef[Q%w&GAѣfq5Ύ3hp4H>;zD"_ICtvy,FA#J0*oNғ*^U (y qW^+iR[$N܇<8+/4UKJŎ{{fG,WWE*0< n#J%%bǵnv(wΔWְJ\P2l@,,Wy#_Ic_d8؀XWW%.y(6 +tS*FUKJŎ{{fG,WE¾*qCpq="_yJ\P2l.v\fGW^+i<  UWW%.y(6 +/U񴵵͟?NҥԩS.e_d8؀XW3{=zL0Сzݻw< ͎Y廆D.]:f̘f0@UK/ ^о*qCpq="_yd_~>l2U={/h_d8\v͎WEҔkd޽z ^о*qCp8_|U2[lQ8qb2?Cڑiikk}9#ڷo߭[N;mƌo>Sgp9r>{JUUՀm۶ /0eWQL<>}8;1#2D9PGrZs2ŋ /7>w޿Uڻwoss5kno}[:uR#K,]۪UTAJ߿nݺh׮qyfz.®]~ޮ]vޭ>;1c\ЩTo _yU]r%YW%.y_d 0GUXr">xwrꩧ.X5w/r׸~jP=4po~=zX|!_dG[y7|U C ٹsg֙UK^13?4*D|jnrMޕdƍ~Ycڴi۷_vmzԄI&yk\={fZľ*qɋܠATI]UHMMMݻwW?w ؿTOCѬG-[̙3ЛL_|̞=[ !C?8xUJv\fGW"_b_E+P%osSN9eY N?w _EȎ{{fGғʻZ "ٲeرckkko5k֨в?g>}z*++~ZW`o~9rk .֭۝w޹vC}߾}{͊ŎkwUxj݃BJ\Tw*8qx ӟ,cs].[lʔ)}iH޽U[tin1#ŎkwU+W%.y(6 +=Eq*vUKJ E@)_$(U< *L _*qCpqo*W`_d8\v͎|WEž*qCpq=*^*{D XJ3c=$ VUxr}@*U"Ll0:_]4T ` UWP%)WA"_E*L3z4H8$=%_OA+Uҙ~ gnY(`f1UN?j WJ:s< AAۣ+}+d5@DK W|&$!_7_wsE¬*|CTIg AAۣ䫸"_E*=$ gn|/fWJ:s< AAۣxUNA%|Ϗ=_Y! /!*?+@L*}?(RʚUbWς|/u_f.򕕨; G3GaU׸rZg*dJ:s< AAۣo _kX{>!3̓4H8$="_YJ/8?~W&xW~'szFy$'f r'9@>_0NI'r r'9@ c7J*̽3!!hp4H>s{|W֠J:s< AA#U!_ň*=$ gnW!Õo H,y|5@h+fSJWyT&W@%!_W2Q%w&$ gn"WOsW)|UWJ:s< AA#Up)*oTIg'!hp4H>C{>BdW3szR+ki|BF&! ^<`U! NZƕ"M"E-N! |Iq^aBJ:CLH$ WyJ:CC{$9_E;_J* =$ ghW'%UqP%gA Q*aT \Ѩ1I/~*GT \왇|u"$@UHsCcܺ)U* CLH$ ŞvA9Ex֐cŸ-SvSL)eCSײeںwaaמ>u<+3m=>]|gV >egݷOK1kpm9ǷPY9Ӵe ޢ>?t2E=|?-Nڝt- hy'm0XUc?(kPk<:3mO-2Oy֐|u 7ĸuWJ hHοTJпXU]]]jkkπ}?}w}[þs-Ly:-x7l5'ڂGm`NMW)[~Q߾<̴_ tz]wGu9Ykk9x?v-=߽u?2[[vw+ݜYK_֧[aߎ_eʕeD_Λ6m'Lf]ĔW{*}^W_=gΜր9;v?~|${嗫_|Eӆڵk/{{*q*Rq d3cOvR*봅 wĉYg5tжc(&fM h|&( T|kJog}uaoh>߯ӯhP%9L<$ gbbB6ꙒJfԩ~'ʕ+UW]`gDA LQA(dD x*ު/PÇX0?LFaFeDrFrԟNREwJ2-U˓5w^U^z,*L MKy^ {̔ZPŨwאUKK3u@cǎ-|sӧό3s=SNF#_]u ?N8H /ԼΧK,رի"_#_]uSO|fVʸqfΜ9u0HzgBr h|(9_]["&~`ڷoO&+gA *⤬W]wRs8O&+gA 푹*VE ;<{`9k׮}]wlWRHf X$˻EbMMMMݺuСO˗ٳ'о}?͞=[=l߾=$_ {]k΀  dJ+**9~{ڵK>sdU w(E*vtg{ETICLH$  !K*W6|܋H۷o;wÝEWu]|MܻTIC_e]g|r?f}7dPJW^9c`UUc=~ty G3GU^$0wܚWAh߾wv=8;ڳgxonORZ{"gA 푨|r?LWޝ/ry晿կ_򗧟~I}>|͛ڽ4b@HUuƞP|uXC׮].ۿ\#_rϬ3sZsO$krٳwo׮֖OJ_n+p䫼H5=?0`ý;,#_ 3!9hp4H>C{);ٗu>k.9??Oڶn:bĈW:Cs{T| NW&ɓ'ǸW:s< AA#ϭR"U4|+y. _BUڵk7a„-[ĸYŞrՐ3WknzWt}…/d}ǥ1@>U֕$$_\`ժUC;v}g0΄A QB_夥ի}ښwgɩy G3GW3=_XrhhhJf'!hp4H>s{Dʺ͛7?vTǎ?XYYI *V|㏫s{Dʺkq۷Ǹa5F!=$ gnWYSxʴi!PWWDȗ|59K1n=<@>U$$_*#_e]OՊ+7Uw&$ gnuظpqaV)Fy G3G%W\bC$_j=W_}g/BzK|3̓4H8$=)_e"_xj&SLijjJ|UQQѹsTs;$_KH{Wz~#kSW\qŶmooKk!_LA XOBgn:`CCkd׮]JS>WS2_!gruqDžٯ_I0; G3GO Ή+_WyҥKimmm:u* _L?X G3GdYAwy'd+3hp4H>{D XOBȑ#gΜuԩSNF+)"W)pɮtTIHs=mmmܹs՜yxt+)WIHڽ{aԨQO> K,=zzk׮d `櫜DTJTR?UUUߪ{ٳgEEEzw];{D1 h||W!+z*S]]裏ƽ"$g h|v|]OUOx:TUU ;zD]UQ=DJX Y_Bf!_|% U|*(TIgǝ A 5KWBJ:;<A ʋ|% Uq gGBxW֠JDuƛF*B"_ICf!_y#_2Uqghp4H>;zdquU|Uc1$ ώ|I!P%g h|v|E*bqJ0 ʋ|% U* D*3b4H8$=*<6DTTTIgǙb4H8$="_ym'tReee.]NؘuU)g h|v|E*ٳgc„ g}v޽{ֈ*LgqH.]:f̘f0@UK/ ^0QUX|E*ӧȲeTz`ʋ|U$*MFݫ*ЫWU3b4H8$=8_q|[lQ8qb2?C-vg&a$a5saF$A j$=z4? HX/Vx%J.hp4H>;zW^~Zd'K.$봄W `UW0dȐ;wf*LD"_ 6 6lӦMaVhe#_y m۶]pׯ¨`vܙ`1$ ώYJ;v?O?ښiV)g h|v|E*ݻwO4iݺu`KKu]G Ɏ3hp4H>;zTDrg0Ia޽G2dȅA͛7/`DU `UWErEXUUնmLT _yJWP%w&X G䳣G+Uq gGW^+iΎ3hp4H>;zD"_ICf8_|% U|E*Bre*U쨒Ύ;,FA#U$_WP%g h|(+k>$3p4H8$=ʊ|Z !@_V3Hr*FrgU |Z !hp4H>z_V3HrLď3p4H8$=Nl*;\M# G$9@0JWP%LG*3A8$  W֠J:< h|H853p4H8$=|e WP%L'J銔Er*3A8$  WW)TIǙG8$  GUq GG‘A0JWP%LG*3A8$  W֠J:< h|H853p4H8$=|e WP%LG*`:4TIǝ h|H8F&}ghp4H>z$|UvVk1# G6_EcmUt+i#_IC0Jhp4H>z$_Y*8GA# iJ# G#_Y*`(T DJX|% Uqgp4H8$=AtyA p+kP%ghp4H>z$\*1*^T ːbG *vT ːbGtܙ  GAQ%ghp4H>z$TIǙG8$  GU2Q%,CU2ؕiޗqgp4H8$=NWepͶJ:< h|H8강BJ:< h|H85!_Ŏ*`U!_Ŏ*3A8$  W֠J:< h|H853p4H8$=|e eWJX|;eWJ:L GGq53p4H8$=|e # G#_Y*`U!_ŋ*`U;A p6|U$7xc׮]NKx\8GA#W-_|+< h|H8dMMM#F!_LM2e]:9Ubh-ZnPH,UGT.+uG$?F~?0#ю _^o^{-`%}P 577{_r={2-* h|H8/oP&J.yA p+Wy# G#_G WJ؇|/}WJ:L GGq53p4H8$=Έ J:! G3AFd쨒jGA#h;; h|H8#dNƎ*騆p4H8$=Έ+J%06ĆJ6ĆJ6aDِ䭰!6T⭰!6T⭰M#*̆$o o o ElrQa6$y+l x+l x+l(e qC&LpUW]{Cy7mڴӧ ~a}W^ygڵkwZ:6N:K.SNmll.е0slV_2oѷz4hÆ ?9sV\z[s_>~xU#Fs9 A]Gyv_~_|vڵiwV̞=GDqgwAM޽+b-P/_^^^ *mڴ/ׯSO=uAף|z꣎:ꗿ3k{LF` ߣ}8q>xYg :{o=.]:f̘f0@ͼKst.kYԷ555i4d*bŊnݺ;wzG[:52Oz믿V#L Zx'_ #^[ӧȲe̞={Gt.kYL|4d2Uf͚5*xoU\Qi裏V|IzDe`5ҫW A|Sseʕj𪫮 ˿>[O\#{uytΆk-Zt 7E+ҥKkP EG $:ڵk3!]3Zv$*t6$=! y:tr]v r|F(DfEG $ǫ;uQΧih|G[l:9sէׯ뮻~:]vYyg9s=38&MZrIjB.] `Ν7p?|jA5PmmwPٹs' dZn]ܻ?aٲe7_=|;Gy۽:s.\F)A?Ay.ӣy7mڴӧO0? XՆ ~9sjouo۶M.9?O؟0+9()5W_UUUNףk׮իׁrW`]v]}*d:پ/iCCCmm:zgnڴ/ׯSO=u._ܵŶA :tS4=z9rk3?~-[};vHW 䫯>}^sZ[[3l/^z'_ _Q֬Y҉'ܜusSLY|yC҃%^m?oנK 󼢚THJ^}ܿupFn뮻8 _yX,vԩ!>rJ5xUW9\4h 5ꫯfТE㯿M6 ?aWTs WVr ~ԡwxٳƍGü~_}饗X,V}}˚/B >W:4VG-kR:wΑlٲ.{^v{N?sO@UէyJ}D`L'Ꚛנ^Uի^>1cƠA~KZZZƌ;kr~IPE2Gwv WjN~Ca'j Pjҥ8kȐ!k֬I?>_lld[^^޹sgנsVnݜO9w߭TНTj}CPqHS=kRO>q҃a'j Py/nN>d5һwѣG3s}s@L'N:y䑮AuRu>m׮]0Xp0vȪUTJ ʖԷa~q*;n0yE5:o߷oߓs^Zt>ywׯ\o/vȔ RQQgej#OUq}v=4776u#zpZdZuUQ<=uB>|We`9j2 S풷z+=r>}=Jٳǹ=r֭A!95^ywq/̙3C_ rjkq>߿:M)*̨s+<}^{͵'tRȝԩS=ҟfݟ+9;v7o^]]wyOU"JOPjܹFr&=Z}'~*G~?S:;w}>[*,uW5C7ַ0hР~={TATj@eWO?zgR ._t֬YS/of|c9:ԡou:9ssiӦGOLՁ3c }s=S?pIcdjb1{9W[TDvm;vf<REŏZG_xᅚ7xtɒ%*Ϭ^Z3{.]8!G+_~|MFwPm{miiimm]hѱ/fٟ0+9 9vڥ"ʄ s 7<[^_yq͜9sԩk:si6iҤ.h֬Y[l t|p[n>o߾/{w.͙3g۶mޙ!'pLA endstream endobj 27 0 obj 16072 endobj 25 0 obj <> stream x abAA.]dFXP&]\Q 5xKVL@D%="a;uEUuus<ޮgkJwyIb{,'='=ݓ{w_A*ݓ{ݓ{=rɻӯ_=rvO=rvkWADJo W .~6W .~6W .&k orÉ.6]lpEvD/9Z܇ѬIlvb+$68*Uf\ .6"HF/y.C ~6W .QWaH:iX%~eV _&6JpvE2*84.6]lpEv N2 *lb g\]$ӯL*t_EVhAJ$4IG2 _Mlvb+dTpiWa]lp%8"~eUf\ .6"HF_U WaH:{ h`H:i8*lb g\]$ӯLC b+Wdɨ+Я&6JpvE2*_ײWAJ$4IG2MMrv*9Zg.V6W >HӟQ7:_~6W -4.6]lpEhѯWabH2կ͊~[ ZqqWn+*d qЯWf|{?sk3 /Or 'oCN:ڵ4iҶm|lÆ GUbСJD|I۶msX}FgĪO)#Y͜a'ٳgX`fŷJ!ٰaCnN9?J۷oϞ=+Vێ=XDzoܸ~zdΜ9-[Lo>k֬/YfVZm޼=/ƍ{+Wܵkݻwݻ*t+;pgbWn~*fѬ0|WY~ R]e|E{ul_UUեKӧ;vq`<~Cos_Yf- _Ey7 _ܨ~N:}_!޽{oܸ1wqcu:3୷??򓟸'Iwmذ5FYVUV;+W ⾨cǎ_|ϕAr\=Z+7U֯_ߵkM6٘~x \s6}ťsƍY=Iz\7%W^\͖.]OA* ٣Er_m۶m_n]oWL/ieee^{z=zF pwznUf_|gLonοǐ~eUv9pԟqY{t*Wp:tK_}Mݟ~i?߮]xny38C~'fYΝm@hU~ݻw2KUUդIWGyy^R3ۃ_w~v͛tvn+++ҥ#ի7x;fxYĂ~9* ٳgN.0`@N#_!5j%]=*** M4WJ车O~С܎Jo7+--YkYQ\=Zӯw{>7թS+]Qz*+E6W.xoϰe˖ᄏC6lؐQܹ3ׯ>Պ _Y UiU+ױcǒg:|sK/1ީS'=駟WbjWds*QoWwu%_YHj۶mG?!uT=zل 903CUWEV{wz~J]HJDtMKCyWVXρ/ѯ<_V0?Uև~Mxjٲezq﷏6}`9vn TUvA8sǽ8 Alݺm۶v(ŷJSѯR|-ĉ.bT9ӯH *ۂA_U$E4*CBJ4ę  g\=*F+wpU_~6W T+Я&6Jpv٣B*~~V AjCds*EB5V +WFaIQ~h+UqUf\ .6"{TbW&+_Mlvb+݅| _W[ѯ&6Jpvqj*HŢ_U~sٯR{ѯ?S 0_H*H-Я=}X%WA*`_Mlvb+~UL_ѯ ~6W >ϧt[үW_Mlvb+/~9UU* X% W>LD*b|UEH*cW__ŅU/*WE&6Jpv_{+9+W_Mlvb+/~Y3W|rnO ~6W >UyW`_;'% dVrZ,g*4X%W?Ȭ&g*4X%ׯ [Ƃ_)6W >W+Wa]lp%8_2ѯ&6JpvW~\y<W,X% W2D_ ǬW`_2_UOBʭbѯWa]lp%8+Hrm+U1_Mlvb+/ʿ/үүrF b+WdY ݯ|*T㿻T]W},xȧ_L9+2P.>S!V `8dUi|v uqw0 㿻TGBs&6JpvCffr{P.S *Uf\ .6"{WZ_A b+Wd*`- *ywE0u}JدU䰻_eU.*Ȗ"Wa]lp%8!3_Y ~,N+UWa]lp%8!_vq,ѯA b+WdYaUsh5+!X%bRQ _eU.C:jCd+V>*]8sUf\ .6"{bo;Jiدy)ͭ]t6֝",Q_L7 q$⧻>?/Byn*]@R;[,#qeM%YtWysp8ݥO7>3{\7PWdv[űs!sdf2WϽѦ(h}q ?$OJ3ntWjt+#[n%kw+3Olv%gC+cbWhذas%^G_y_stw%^9vw *o[7? >m?aQS9d[8sXEntG]ܹs7|nݺ ,lذU}{_8:؛î]tʸٌ3򿮃nz.s9rώ`f\ .6"{b/B 'TG{Ҿ⋌͞=[}g탏>L~6W {T1Sׯ"3|p>.^XN0gGUf\ .6"{bQ*#LcH~Q۶mu^G~Wz[n>;;ڒFaFbWsF=B }$Wnr}"hgGQH<_h*Oóol8q_{_UUU\s߾}s=wѕzRF?1xaM4ѐU kʴ~v5=/-կ_s Z_r)>;rUf\ .6"{H{{ATAUkw\]YcՊ+tyR_)uVZZxMlZw#*lb g\=dzIWaG]ڿiGO>~sNvر|{좋.җmqRznƌg۰a}pҥzpĉ>;ү&6JpvCVBϜ~=۫\*ukҝnݺ/6:u}uY&|~;9_8UV{iVk?~yyk};gΜz-_/pG]ҥK護ׯߘ1c>` Wa]lp%8!3_9߯r^[.6m1g9|p֭#8tWa]lp%8!_8y8ܓϏxҡ_Mlvb+,'}\Ut?V\ͪUN<x r+rR>%~ }Ur^[.6۷7iҤv^{… ݛh?Ə/ر#_ 7v|N+R^~W^yғN:M6'|r͚5S/r*/sND~W_}iӦ8Nƍ_|ŸB'6JpvCopΌ~;vL2[nֿE~ѯ&6JpvCߩsWWY p.6]lpEe|)I֯[dwOtZlYמUef r>[*UȆ'eb%_'RTUUM<94ܯd*c"WR!j#FhѢ'wyܮW)%kG b+̨~R}0ދp|8O\p{]whȐ!ֱumq^J *ȜY+93nկ>иq۷GtJkq `8CUVǙqˬf9Hqnksh޼{SOY棏>zȑg}q9ѯ_$ 89k=ح[7?|GrD8=lb g\=dSJWGmvr /L}{ȑ[v=#;*lb g\=d9WʶW%و8#y\ .6"{Ȓү|6vo|SIWeee5jVZg@+id܂*6]ݻ7f8p`Ǔ `*6>)WJ^xx6?>}zG~0_f8~6W  *e4LW/Wn*lb g\=|a+ЯگG b+Wd}+edJwT鶤_eK_ԩSn&E~?s-W^fAmٲ%Ȉ~0_*C %*[7|֭[MΘ1煬O?4s_G8~xbe˖s9}]nMlvb+~Wz[h#>|85n\pAF b+Wd_JݩWWRAif\ .6"{W'د6o|W[U^zLB +ngRլY:#4hu=p}_z1_ٯmI*~5lذogyUǎ{=-Lѯ_O"_έ*--[ߟn͛7Gy`6W U::*կZjoxѯ&6JpvG8OcZqر#c"?cG b+~qUim!~UQQQUUWدgeRQ67x#k~0*Wa]lp%8Q)`JmLJVjذA> ` *lb g\=*+y /p̘17>|2IIQ~IA5Uj!GC9rs=>eԩS#>6; )W>Ww>1瞳,Þ={̙ӳgO}iƍ= )BWYU.QJ?QNG7mڴM6͛7/--M >$_Mlvb+GŨ~U!5~[-Z(Rnݧ~:_Nlvb+G~GZR>cֿSN;|k׮*lb g\=ZAjX%@үW_U$ s*QX%@Я<_&6Jpv٣eH2+E2*lb g\=Z+ϩWFdDx#@b+WdsP3 uEU$!* WG`B~eV ,+ϩWF.6]lpEhүW_Mlvb+G~F2 *lb g\=Z[WaR~e3 ~eV ,+7iX%@ЯW*2.6]lpEhүW_Mlvb+G~^_@ b+Wdʍ~eV ,+ЯL*~F2 H0UV~eο b+WdV {uӯLC b+Wdʍ~#GL6seee5>|ڵk3E b+Wdʍ~7klРA_|qڵuMfXV t+ЯB2w޽{ٳvݺuڵ+0bEЯW!5j_m7o^͛(jE~F nS}hѢ6W -CQ7:*2[l+0x`J껍%%#0#$h$ Bvس[mʞ1̞Ě={^ oWa]lp%8+|^cPvꪫ2n&|cH2 *:u3n)yIDr_c6ׯڵMLX(b+7U2cm۶[.>FFI1W -CQ7:*T;w8pnܻwÇB b+Wdʍ~ݻw2d͚5I&ѯb$6Jpv٣[x+Ǵվ}z٩Sl СCS(jE~eUH.rOSζm|vJ"@r_U$ ʍ~eο b+Wd!ʨ~eUf\ .6"{Wn+Я&6Jpv٣Er_U$!(+ӰJd_ѯL*~TqUf\ .6"{ WF+Я&6Jpvً1 *Uf\ .6"{_9_*Wi=iJЯz `H_99Wa]lp%8Ez ү( ZFLlvb+dTU=\x*lb g\]$iX%~eV _U W.6]lpEv N2 *lb g\]$ӯLC b+Wdɨ+ӰJ$4IgoV~eV _y_!ο b+Wdɨ+Я&6JpvE2*84.6]lpEv N2 @ѯL*t+ӰJ$46W .QW_Mlvb+dTpiWa]lp%8"~eV _U WaH:i8*lb g\]$ӯLSb޵u'b+Wdɨaj"Wa]lp%8"ܳ_u]X%~eV _U W.6]lpEv N2 *lb g\]$ӂӯB b+Wdɴ+JQX%(E~eο b+Wdɴ+Я&6JpvE2-8(.6]lpEvL n/TرJUX% *vE~;ο b+Wdѯ&6JpvE298*v.6]lpEvLN@_ŎUЯb*PdW+ ZL~:lb g\]$_3+ob+Wd~;Uf\ .6"H&_ŎUЯb*PdWc(2qUf\ .6"H&_Ŏ~6W .W_Mlvb+drpUX% *vE~;V "C_Mlvb+drpUWa]lp%8"~;Uf\ .6"H&_ŎUЯ*P|Wb(>xqUf\ .6"H_dɍ7θ*lb g\]$Ãӯ°p5jЯL 6JpvE2<8o޽{rs p2n,v(bš9s-ܢ_ ֮]ۣGl~[ْڒFaFInc8F~<䨪ݻUoz~I#6JpvE2<8_=_Blvb+dxpUA,[_~Nկ@WYEٳk׮6moI@,UV<1[hyhτ>*{qe5+{ۗ&6JpvE2<8*$~6W .W!_Blvb+dxpUHW JxJUX%*^6W .W_Mlvb+$68*hVIm!6JpvE"8|Я&6JpvE"8|Я&6JpvE"8|Я&6JpvE"8|\<c=G =Gq#;*U#g#gvOKޝ~wO{BwO{\'%N ~UĻ'='=ݓ{w_Q ĦڠA&Lp7׮];nܸ5{zzR߿_o 7\pzƍqJnO>w߽xbk M<ُٞ92mڴΝ;5jhG uiBK,KFWN]аAԋ}G=/˗7h஻'N|g޽;=)6m+۴i__ro- .QgW鳏?YfA/]ެiӦ'YK o֭[wַ 6\jcd Bԭ ^GhѢ&Mme<۷w޽裏+Z3$[AOysWUUY#ӧO#կΐG~С:~f0aϜ9[n_#Js1o߾"PI[x0aB cǎmg\ xnt &<Զmq&Nꫯ`n݂`8c.[?ESmp ]{{wI'K6lخ]?8y]v0`ѣ/8uo|[޽{sN#Gn~, &<Ժu떗;ӽb)9d/lKxG|9K,UVI1c8~ 2b|G:n7 Kws?6yEEUW] &<5jÇ덛4id߯{琽8~ .qKwϙ3gΩq:W{<5k֮]N3J`>^lY~lj$yeeeNIQ{j;8Ǡ)dٯ}gh~ .q%u=W^wiӦY߾u[> e]9~߱cGI''79{VӵkM6H֯_^ ;óy.s)7oެ7޽{LӠA_[,[?F/y}߳_tEw$mmۖ.=-zw\el۶֭v:f=aҥKĉ`5kػ>fkIddOO}7zp?>;P_x=K/x =p 3瘋*{1g{KxG<9/Y$5uV=ҫW3$[tF֮]G~_|O3(ݑ޽{Ȑ![UU&MJ3ӭO ~Q?#vs{]lp%,AH^G=QFyΐb+aE B.68b95k8?oժUɽ.6]T $/b#v j׮p]vwL}Olv!yAf߶5jԫWAַ mOl.F飿]n<k|멧6իC=G?2kNj[NkժUڵkj% cj՚1cƾ}O^ZZX#[n]ߟDW/#s1_}9rcǎf}]j|z]  /رc#mvȐ!/5IoШQ#-x^kvg66lԾ{Hͳs=WXvqcgƌzGw̚5+x0tڴi;w.++ӿr>|ڵmȸq8jԨݻK9;C?oַK,KFw4hիWUUw+Gq?׿do;KKK[j_СCE?TTTx^̖ɓ'T\ֻ9z &|AǏc}s߿_Ǽ.^Q|2Lׯ@:uUVh+(2Ǐo֬~⋭M6mjX˗/oР]wݥc'Nԛ=33TÆ +|ͺu.XR_~StÇ>33,\s<+(=~աCLݻwӯ|6 C:ggicǎ:uJS<׬Ys}4w޽{ٳvݺuڵ#I'5;fҏcƌ__`[n=x`]t9眓z~RiRmٲN~? үo5jԽޛg0~d#͛7OL=NS#iѢc qٳg믟}Y>LҳgϚ5kH(Uj׮KH3:th…Kø3 6 (J>|%aÆIWY1 {6JHXjUݺu ;g"/~O_mzY;'Md}ӯW|WUgڎtcL>]Wr;nܸHÇw2U}R0aRcs=WoSYYwd}~O.ay̙_]U* 5cmڴ))=/<ղeˬv /{ن K~ٷ~;bg}~zo߾E[o5U,of}uW_}uf}[fڵk;ޢK61rN?;V?guQgt3'>UVZvm=#w 3+Y{Ν;ԩ]~*^VV֫Wm۶Yg7mڴVZϣKkl}~mjO̼~zA]GuHRWArgWV+f^7?cG5cƌ+V\}+z5ƍWb|$ݔWASϭ:ȟ'mzF]n%G}w!1XP`?$S˻v˞ZJ;V`]ڦM>RJmf}7tUwEfGUWǗ,YRV-t̘1ClR]esS#/@?[6kLGY7IC>_4u_yzSNٳ}l?AO5eʔ3@TVV!'P͙3SO}dmXaЧ}wq)_LC_~ٰaC;}ntgfUV|z6˖-ׯ}(w!WrY_Ǹk:XӦM{?;ϩ&3m^x=dɒԈis6oެ7޽{jDK.csVTTk:^3;Xodk a3μgºUn*p 8F9̓_=wy']իWreU}:NOwzQv9T̲ԿWϕ҃^jDղeK}W{ A}Ek7dws1g.X<0ömn:E]t)9i}K+UVX뽿Y.]'N0fΜ7 >n"nϰg^hQWT,V-WrY%_w/ɥYT^^+W;w:uvGzoWU7)SX/i={"zGڴic_Gy駭ueIϙW"z'ׯ5X :t8u׵^},tv}P?Z4mڴ>N8vsݭםRE?AGH_/,̪a_8EGg،3?vhr+c{zaqG͟?Yry睧7>S3 + 2d͚5I&Y=Uv֬Y[Uhٲѣ}9묳>a+Hsdlo A_vUZj׮mc &SVO꺫G{6ۿ͛7믻wJK+@>׳gN:]f3`:o GS~nA+}k /|공mۖ?4hg1tK/tzĺhs9[oկ_1c >\׶^)~W>l4xy檪qG]E15;t|g:veI[n5kVр3"ڹsSN9qʓg3su 5CI볭4]c>ӕ+WN4zdرK.SpVȈb~>R_Tռ?TVZEh?Y endstream endobj 28 0 obj 18293 endobj 30 0 obj <> stream xVɊ0WGbAؽ@ lK~?=9j}UZ9<+뉔'g|>S{eǬ͉wI_~Yp{.FQ&m4TןSI[0Խ4FgiXѐcRQn9Naqn?=qezkѡI0(E}flpz%%d7/LM-@ҌˡWoMD𽥋_yI:ϻç'6[=;'r;wN.6>Q~KwiQMgƬ˥`a`W$y$,unPC-s֚o "*b@B5}y+wd/"WH\Zmٚق(L] c4jLU: AB1瘩't?R=bb&_ ͛W^6F̈́TVߘsRS%q./~il4;|pjN8^ڭX"`YǷ 1.S?9JosI,EkwӹLK2Dsm;n(z&7WyyݝK7ˤ/66§\/k endstream endobj 31 0 obj 907 endobj 33 0 obj <> stream xxU}q.1 8H3Y'4b1iȆZbmΧ:ԧfST *bJ.,nX$(E`Jk3NsOr}~>}r=~pr 2dQM\t5ayڇxiWz2h,qrF{͠.Ac rF{͠.Ac rF{͠.c t}0@Nc t}4ܸx9d#½fPNϤDK;;;-[VUUU]] FNƂ 䐍A9=3BP}}} (((Ν;ڬ7o߿H׉eXpaB<^3(g@wwg%n}͛b {%K.\8<<~ d JT_mܸQ-ڰaQ5Ffܬc Wj:rq%Ԣ{ѣGUŋݯ蠱@d5Zh%-FMC -m4jC[&nDUVVVvvvTc__ZΜ9ItQHD"!5rz&%iӢf̘~D5„x9d#½URܼFknjܹItQw胜Wx񃃃cǎKKKݯWjQOOqϞ=qItД;GN+Q}i&h˖-Ʀ&ոc$:)E/7!Aوp/0T*KJJoON „x9d#½fPNϘ^]ښ{ncKKKNN޽{GN,Ƃ 䐍A9=Bкu5P}嵵ݕu0?'`,Ƃ lD tӖ 䐍_ɠ„x9d#½fPN@r> d 냛dXp䐍A9]<Ƃ 䐍A9]<Ƃ 䐍A9]<8zb,Ƃ lD 4\ lD 4\ lD 1@Nc t}0@NׇA/=#!'Ƃ 䐍A9]<Ƃ 䐍A9]<`,0h,qrF{͠.Ac rF{͠DK;;;-[VUUU]] Р„x9d#½fPNG(qWعsgVVV[[qw-c ~,ŭyVXao\d… X 9}tW7nT6l`olllT d ZR-:x𠽱C590] 7!Aوpu***RGU/va?YZh@KQBKz["ЖDUVVVvvvTc__ZΜ9;Lgd4@$^3(&Q}Mh=5c R`("Q}h_͝;yi 9}WǏ7;vL_ZZC^ UZ$jkkբ{={Tիw.z lD IT_mڴI-ڲeI5رy\ lDJDU8.,,7y;&#!5rVz{{Wwikkkvvݻ---999{u'c B֭ _CCCsssD˗VVVVTT۷/鞙T\c t}4ܸx9d#½fPNϠ„x9d#½fPNϠ\ lDxJO2X 9]2aM[nC<^+=4\ lD 4\ lD 1@Nc t}Pv=4ܸx9d#½fPNϠ„x9d#½fPNϠ„x9d#½fPN@r> d 냱@r>  nC<^3(gK30!Aوp/+=4\ lD 1@Nc t}0@NׇAc{GC6"k:iXą rF{M>nxtF\ lDt]wݻ;M~_:::\ltw}H7֡BP}}} pS3.F=OT'kt* '544$=#!5rC䐍A9D#bjBKZ"ZiԤ?hEp@NԨ<H;2+ r_D"䐍W#u 䐍Zs૯juU__?,C䐍_W+,,TG4i__8qjпWA&sUW]uW79}mV\+_W"K^u^.%0e2O4EГO>~yU(Zn]0f2 ={D5>3k֬8c7!Aوpe2z뭧NjO~2~uC[W>rF{-9k E-zg2 mQ_ !L+G9|pj\~=5<vCWܸx9d#½IN 3+.Qq#rF{'Ƃ iD/^$[(gd,ɜ~ z(cVL)fF:I-@e2 _Xƺ-RMyatgh@L* X7ePi\M%36=gD|8:rH_=ГeUq&Ԩ{37.ȁ!½fPNϠ¤ҙ)y)"½aN}ڵk_xᅗ_~ٗ.eca )0Xd0Ϛ52<<|Сۿհi$҈)1ARiӭV\;D-G>K2CñՔl,y4\rٳUh۶mE~*4D̍{g(!~{ͬJQE'0!^T~YQbA+գ>rӞ+XyÎ yXƽC}hѢӧO']-x_} j'+Շ'N>є)S|mgge˪`WWm;::\X:q#ܹ3+++\͛ߟtP(T__TeX:Q_c9}7FuL-~WZZɎyX޸dɒ ;lY,DWܸx^Mvqbv;oƍ6l7666F7oP5!`( ׸tobvW^;RuƎXWWfW2XƽmNסcEEEƣGŋHX -B -ТCVOCDzT̙fRSXT:tmiӦE5ZOU͘1F=50VmַˋjΝfR3H r{TYƽCN?#Gx۱~;g(..?~࠽رco.{"u e2ȓNUQb!5毜󱷵===={իWW4 rJ,.9}u2M6#nٲԤwfRe| -Z{%]?9KJJ"w3׬YwRŹpj|CNzT"?םښ{ncKKKNN޽{#+_^}SN=}tԶjQ~~c0jJ% rU*k۶m݉޾|rսʊ}ٗK.P(nݺ`0h644477'!Ttƍ{yGKäZLyJv;<ՙ3gy;wscc&X",5ONܾ}U Tf͚/}3 3IqaBw}„ :<$f*\tF3. '+"1;;;-[VUUU]] һUGGGYYΌqrn|4sΝ;ڬ7o߿Z B@e  nC<\C~d+5rzzyX޸dɒ :n%$:,jd i4fszQQ:{ѣGUŋӵHX -B -I["(6,hѼeLƾ>̙3'][1;g .4fsz 6mZTԌ3ҵը\n{%Df/\Ct^i比ܼFk&jܹJ&#KՈ7nvA9=Ǐ?88hoZHW8sTgs=o:uUK Å555򒒒țU֬Y>옿DuE :tU\}ժwÇ#q5ښ{ncKKKNN޽{#+_^}?SN=}"z{{.Xč{G#qo,nJ[^!o߾]u#Qqe9t*c^x}嵵/U .]:44~3gu5CVXM*:„x9Rڇ$1{nH{Awymݖto@Xą rx!#[qMj6/:??yW\qE)י&"?8]Z\9}̙IWTkf?~a,;h>*KϘP$)/BkziuI&ׅ.'WkmݞKӾt qrh"ZIo &zIי!Ϙ1ԩSIW>}z%R#ȡ3p\ CND :;R#a:˪&zjrهI&M> 1t:;c¡ LWTgLzгmFwM7ݔEM7 Ng9Lm9]VC:{嚏?=c֊;0J{@<%,w a=,¹|{M;+a10:tlsCN?tО={ZZZ֮]o;ǔOgUhr-X'NZ .x2GpI H;q+ErY_%ߙxeX4-җ400pԩoݺ3ڮ]tw :;/L -r&&C<Q55iӷmL2qDr[>;;5*&FW͛,X0a„_WPZw&oV/hc,׾SOuvv3L L>00SO}5iT>;sz?ߠ gءgN?pwܑeT999Vڼy?q;\lYUUUuuu0JVQVVzE\ܸx9d#½UNnmmԧ>eSNY+Yvܩʳ6룪ߟV. @AA>k5θ0!Aوpi]qVM ]yVXao\d… U V.YWrF{Ms=תf͚o~߶{7nTnذب#NjD{Z_:'xš/]*++Ն7vttƺT鞩4;v ,hjjzuHmU=zT5.^8FW@d5ZhZhE[7>|aw_OO躗ק6gΜT鞥_#  lDO~'OTuo˖-վvZ7iӦE5ZOC9V#\n.LGC6" :_ ⋷rٳ{rannn^^^T54wT鞙 EC6"kF/| 'Ov;6/--MeYbUW_}͚zzz{QWNeYp`VN߼y6md=eoljjR;vHe+C Å555򒒒[׬Y>ܬc'u lD #ښ{ncKKKNN޽{#+_^ԩSO>~+Xz{{!]٠„x9d#½fPN˗VVVVTT۷ϾT},((XtА\ ֭[ †樷2hR 䐍b,`,nr䐍_ɠ„x9d#½fPNϠ„x9d#½fPN@r>i xJO2aXp䐍A9]<Ƃ 䐍A9]<Ƃ 䐍A9]<\<߮'`,Ƃ lD 4\ lD 4\ lD 1@Nc t} dXp䐍A9\\rɁW3h,0!Aوp 5<<|} 0Aوp K/ r~_lذ 1#G]aΝYYYmmm͛7߿?鞩;U87oފ+K,Ypp`,ehh(Q}qFzUDccjh"# -ВH&D5鏡- PR-:x𠽱C5ե帩$3DC6"kIT_EWZY=/^RraB<^`Y*+++;;;O?gΜ7ߑc%iӢf̘R`(毜%rsss帩+Q}U\\<~A{ci9)E/7!Aوp/0,Q}U[[٣W^㦾„x9d#½fPNϘDզMԢ-[T;rw\ lD  Å555򒒒tIE A;Ϗ5;;{ǖ{Ќ2#BкuUv644477GMTioo_|ymmmeeeEEž}0h,qrF{͠.A7m0!Aوp/  .LGC6"kt d 냱@r>i xJO7!Aوp3h,0!Aوp3h,0!Aوpc,\<߮'0h,qrF{͠.Ac rF{͠.Ac rF{͠.c t}0@Nc t} nC<^W8}t__ &#!5rN:oձ_|&#!5r?YoWf,p8\RRSOY@rw:;;,X0a% B3@Noo~s`yMƂ lD F{'W[o9cXpaB<^3(!ы/Bj9x.m0!AوpӍ>77w``a:::-\lYUUUuuu0JO?/Z?Rw|\vP>]aΝYYYmmm͛7߿?wyԩSWXo|cÆ IX 9=w Sqɒ% .t~1K7!Aوp3chh(Q}qF(j&Q5FfR1.?YZh@KQBKz["ЖH2vttƺ7d=rF{͠1ꫢ"(=zT5.^8-ǥP_9KT_eeeeggG5̙㦾;rzDU 6mZT֌3r\^ DUnnn^^^T55wܴ7d7!Aوp3&Q}U\\<~A{ci9)E/&#!毜%jkkբ{={Tիrw\ lD ڴiZe{cSSjܱcGZNWpX^^^RR3?蠷W}'qfgg޽Ғw޴@rzD(Zn]0Ά樷*˗/طo_:`Xp䐍A9]<Ƃ 䐍A9]7Ե6g7{ +A"$p#L6-Ѻw?c 7{ +A"$p#777///osY 2ɐ$Q<;Ǐ7;vL]kn@V D2$IϩFmmzzz{QWvd !IxNw>76mڤ.-[T;쁬dH(Sp8\XXXSSco,///))wppp͚5q@V D2$qx{Ң5;;{ǖ{FVX~TNzm{{{բu I9|޾|ʊ}ٗ꿃.]:44i B֭ jhhhnnzg?"g-ZhĉΚ={vYϿ L֬. s=jޮ.ke^kI߯v~wcS[x{J e*[>UZ뮻,YWnja{{gUGjѤIN>=cW"??_%SNQ_9KTL>]-,CCCjZ!Q);n}477g3fIT8|[p@7P_֭kmm|O|3<駟ꫭEݫW ǎ׿n=DG߶m]wU\\|A7;D矿TO>Oٟ:Gո~zv\y\78q'xKW}u^z7tSK.Ds9MT1044tС^Z:::/ZO }+_ַ6kԢ{|Mj.袞>U$Q-sNTqp#GG?Rsrr֬YVQQZTe\|Ň>uT~^vc}_]+UvɓgV\n3|D-β&{l05~I&E,J*QSDa'{ZƙOgY{9Ko}eݸ|?ClrO?OFy ksU+D=Ŕ5E]ZGdΝ_uU ~~oo V+`aaS%.Ӵi%xٸ]lr?ydǏӟ>vZz7Fv6ݏjL߯~~wGАˣ-qg>'|ޓ+W;|sXRQ[E n߾=xСk׺9Њj?w Ɲ7zCY^gzJe˖=+HXxjO~/z?Gޥ|oS}TfT*,]vѢEJ UҨoc֬YQ4[DRUnjBHՓC3BIx 7X?G}4ꆔnko>U8]~&LU{կ~ev%%%ޘ3g׾{/HPeإ^*|3W^yeCCî]W_v:i|+_y׭5?~w̜9SXEEEjE7|}c?7UI+X<ȵ^k-UjjjRmmmVKyy~QuŪ_v>틄KF*2|.u/: ?O_\;> stream x tTսBL!%Qb@J)REKR@E ZZHie-""U!U,%( E2]qLN|?뮻sfw3/ X=A>V jyI`“_kVi#j}V,WL(X%xk|eo9 ;S )}xyΔ>Cw<<~g1~@i\J> ݑ<#_y}93ܗ>}93ܗ>Cwrg|1 c r+9}6RY #_Qc ZJ}E-W`J}&kAM+0|%}&hA)+0|%G}&k3A EZ|%G>A !+-Ǭ."+0|%%}&h!W`J L@24}PϤ,$Pd۞R}&e6`IYܷ%eLʂI+0Oٹo3@)>mC> - hgRhkM>W`vs_S7׎}&e" C빯I6ZMIY6s_q63) l6e>W`-羂g#b|u}v,<{}u8ϞYKUNeKh9sZ"d5.;%nBK( `s_\ iwGcܗ#̃յ(dit3@W[؏Y]#gBx"_y}93`ܗ>#(Z(bAtdx5Dٷ\s_te$.ܗ>C?b?o"_Z/}%'B+G) @rg؃#U0h/}(?BW:vrg، $`c)qC/}|bI!b rb^1`}93 ԛ,O8W$NQ*cA4jP s_ 8~Xrm,ܗ>Cw~`P>GMZ rgNw @u}93`cD,^rgވX<1π 'cUXܘrg|e /}W&\dB b`AG!bܗ>^wrgWE/}W~ _ܗ>Cw+gbA"bܗ>NF/}0D/}W#_ܗ>Cw䫠 bܗ>0'pߺu!CƎg 03OD,<7mk||;wybqq)SMޗ {sܯر]w8p={\.'8pKDWp_ 7e˖z.Λ7O,_򡪪|G!_ 1ѣGǾo>ża111ʕ+ccco>`ҥ?7.)):ٳG&}P/"Ey;#++kiii;v611155ʽX\\dɒt#Θ1#'':9ϰ_Icܬ獓Qa'A> _㕩j; Xw}yy{\y^jWyTex@u*[nܹs:oUr yꛩjE?yrT<3uSagggq ۚvBjSRv1qVqqq+  WVjS s_ ݑ/}WEܗ> /ֈX@0tGcA;_" 0/R@Aee+,Uee=/]UZZ:k֬>Hf;,L5^eɜ;vHJJذa_O6l?l8%;NIYP̹߫W=z|w%%%k׮7n޽{_~iai$z'R"s7l۪7xcΝ+QL IEȜ)))۶mZ-Zdacj$tDʂdQFy; 4V%W J E""bB2~UUU^?a tGĘPDĂ%d=z̞=T+G.b2ڲeɓ[nݧOs9rDڽ[|y|)09wY2+++7l0a„-Zr-?q2d%? oRQQjժc&$$XX*W 2)2KKK.!37lirg|`;Qdcc|9dݵ{祕a ( dI&NZj2~YYY^>zWa t+  !%yԸ~aeGW#rg|!_!tկU^^xuڵ˒`V]Ooݺʕ+=W\.W~~k5I ,،ssqƝ9sG]t9/%Z//йs6mڈ®ʵkz(--ͪ`za?(8 333/ ~dmm~S@dD,ԗsVZe{|X|`s ~ㅬGyd /^ȂI 뮻… ++WlݺLҷr"ܿnjzjE YVU }+T YMoґ^}crg|Ԉ0̙c燴Q@ W@mXN߻w:6lzBA>B7 Q s_STT Gu"_ s?>.OV0O*N:WUUy.z&~?OniAB@  n*3fT_YfKpp8P'6b9j}wk,l޽/'$T3` e羲fP.*<-?6{8XPa fX7_ }9!B@ 6b9 sSN.szaN UW@}LE?*c0L|>8Fjo@4*޽{?|gHYN*//7sC]LgHYΡ5Njv .X]NHg *-[L;hy<>~iiQFEGG:}d"h)K_\\tҴFY]3@S-5 .OzNWG!e)Bl2K9||he >n8|U }ACIJ s_eH p^Ȳ sn裏{+WN>muQABDĒO?o<㋊?55.ؼym^R,Ԝ{>}zͯs:ufK~YYYNN-Ҹq1c|gr3W=Py4~n(?g `D, Ԝovn{7ʬ.OjLDPSaڵuaaYڴiNV Xj T3 s_*)S*""{׿euuBp#b se˖ 7U\\ܴi +T3_C mΞ=̙3VW|* %U0E ۷_xqEEյ }A슈 *޽{;w*BK>P#"VЩ0WXau !B {/}ON%~PaO6͏^Ig CeB%Qaggg˥BU-P p ꘲T#GwޭBU-P p&٦ƻ.b0E M4I4-!!!""BӫZCwhKܗ>Cw+Y{+"s_ ݑ +eee-;-ZtiԨQޅ .-PJ3 D,uۯ?go.0 2rNQ'|eM6Ť'Ǐ,**ںu̙3OwiuSNYJBQ$b0].׍7(BԚ5kj<]tٳ8RrmB@ |sGjP`oذAQ[2Ʈ[NZUB@hDfĪ1:0z1cy̙3'N(PP@ W4"a>U?O>:믻v*PP8G(7:-Z(++JqzBA>(AX&_sС#BZIg&[=EHըg )?~:M\*͛yٳg$ * r5 ~lI {*(T &$$$NQF*T}+|_U߿3?XQQ1|p }d~* sܹ&?~H+  y_4d!eA;_>U/ܗ>Cw+!æU۶m[rŋ_z饪*c0;;Cڵ7nܑ#G3* Sa^h֬٬Y Ǐw m۶-o*ȡ5owTUU__ve_ۗ:a }r0E 6l\Y`ʕ+݋'O1LvqAB*8VDQ?ud׮]4*<~llliiZ#G4c>}ȶmJ.8T3ݻ>Z^^^TT4qDyye_vmxxxTTTddWi0=zSN*T}+_|yn""".'xEiٲ,,2VKz'|ںukaaI>`aA;_y}93tG.Oz|2].ܼys .}S[7p??y?ߪU0Oߺu!CƎgϞ7`Ũg\jݻw?F0a d6m$N5ܹ3(gO2%<<<11d=j0W`Rsr_o|sQQqENEEEǎ.Ł;^"j#_9W`"s7ڵ|={W޲eĉyĢϪ"_QW` sg+dպuwN2~_yG'۷s1//O,fgg, s…+W?dqM=zT,7Xg7_UcVXaVtYqyr6nܘޭ[ ?X蘘Rqkڵ Y~j?x3:u4sCW^xxxfͼS>PZ߳Wp|Ss,\?(oŊ.\0/^l&Mx-Do>Xg(+0Or>ӑ#Gifڴi|I^̜ҠAJcǎۯ_`E<-&MԨQ#fee#:乸m68u`E5h߿?99̑~Ƣ ƍu H|r3UTT$%%effz.<{+WVV.Zh:˓g0y Јg|Ʒ+Wݾ}K޸q㒒g={Vo+0swqGVVѣvSmbbbjjjUU.^p%Ktƌ999^W%}C<#_y}93ܗ>}93ܗ c3>Cw+0/}W`s_ s08s_ s0<#_y}93tGrp1Gp`A;_y}93tGrg|18s_ s08s_.8ݱ |g|1 cAp`Apcܗ>Cw+0/}W`s_ s08s_ s0;_o||#_y}93tGrg/}9rg/}1 cA;ܗ>}93ܗ>}93t+0/}W`s_>P#_oa?fu9@p`Apcܗ>Cw+0/}W`s_ s08s_ s0<#_y}93tGrg/}9rg/}1 cZG8s_ s08s_ ݱ cA;ܗ>Cw+0/}9rg/}9rgW`s_ ݑ<#_y}93ܗ>}93ܗ>Cwrg|1 cAp`Apcܗ>Cw+0/}W`s_ s0`u- ~r>}93t+0/}W`s_ ݑ<`Ap`A;_y}93tGrg0L93tsw9 ;S )j}V,,)G X'֬FZ=>(X%xk|eoYz|PTK"_2Tj`Ddɯ5򕽅':zmmݺuȐ!cǎHOO߳gON/((xן{U'Àr-\[n GϷ(u|e˖ 4Сo .X]iӦ\˗ܹ̹G{" SL OLL@I&jJ5555***,,/'bi)))3g\dO?ݴiSG.hcǎwu{)->y/BY#trg/Wp5kֈ_ϟ7=x`Ν ƌcma0cɞolذAkҤ%Aw˖-Ϣw}sq޼ybV꫘]nUUU+8JFF?๲n:񿂶mZULpƍ=W\.pV=z o>ż<]YإKq̖-[B_#D4RZZ*WЮ];KA ?.=3V%''gQyyѣGb߾}k;+''Gгg]p'N+}UUU?^s CtttLLb:t8 ---33K.7馛> p -/rC 믭.Ϣf͚y-g7o^Y[ߊ'Xiذ!g 7`{*Pׯ*22R޶mEAWqqqDx}e+;#NBT'C-_<%%Ν;JKlV] 4LJ±c_~%•׫^gΜY|*((ӧϑ#G.[f%ָqc SСC۶mSNȪ*E"""BU(tC3:u;ܹsFK?ONR\K1\A6mcbb>s[񤊍ݾ}KoC'Mwދ'OkN>-xI+^~'NH/)...1cFNNlj"ez)/'Nc.<G۷o_?~\|]^^.r83b7ꪫ:d|{ .x4m+7|S|;vE榥1yw@5FΝ 7\rur&"8,%%vƍ^qK!k+y/ۘ'O++;v:eժUb`%2"ݻ_K߭|:k333ƍ3w@5^yFĕ3_]4ܽ/-?={V0tPΝ;u;WuK[ke"GyޯgagL0ȑ#"KYHaީRj /믿.v"5mk{1s+$Z&M7n| /g\fMN1 _R}ϝ;7[jԠA wv;Ub6E%bE72}tq3Zj\,;6lp//^Tc|Xӧ}voܱ￿UV?۱c p—^zH\^!o߾b133wynj3 k)6i7h|T+یJfee@"҈nn=x-ɰ)""""..Nڗ_~y w.Fv|W "]{"}gϞѣnj3lRYYY߿ʔ)Fm=ܞKD?~aȓ'O>-Z+99W^ʊ#F̜9d?^{mذa4("޽{/fϞ}7?w`k <ظx)))be׮]!!55՝$(:`C·~{뭷?>5BJZW3$'77)DDDx^=tvܩlUˍOiذaAA-[DEE;222unq#(^WSLL;'DDD|VW_gϞ>|W_=eXz endstream endobj 35 0 obj 11715 endobj 37 0 obj <> stream xZۊ-}gCƪL`_cNyJRIս! LTU.?fa _U>o]?|xOMmؾ^mIx'$=ŠL?__\} -Gڟݍ7Dz!)/<>~JRT`a6]vj Ӣz wi"[~Mt7BFl; 1<#2ΰrI_"U">t%LCu bp !둩ZnCgYewv"c,:_KkuS܎N8^c4'P -zbg5`Z&'XZ(dٙ9N5Y_3NvT Wf\qME?-B&3m}6>6Fkۗu;bˬ4=4;,;ф D=xGLB5GIs GssȵZMt~= ӱټWJ:NSJ椽,[lS䢺42d*_\40\N]g ۹˱:ɩnD8PH*c?7.Z=o .p+ uب]ϛ (J*ب 2cXT"ul(Cejć$KLԧI sjL<Н*v$nKS|72zI%ZVsUQ)$-J 7j\LUe~nU{dr}Jw > stream x t[Ls1PIx!ZֲlFeƤ!.)v9+뮗Y-fqq)f e M`M]Z$b2ːϟϙ[&3<~?'s.%E,"%™#N3>a~Rr;L}pvf9̓NSa RGOžWqٙ2O:N5JI?AN_ŝ ggv \.?8(`*TN3gƍ F0 ]3gwLBeD{{{iii .r8]]][y{g}Qe; a<\6*{R8κܠvܙj=lllٷow^rs4$Ide?~x_|q߾}W6?} ^\\g^{m6o04:}ns$-o/9f̘-CAWRs$->裵k׺nMZ– +@)9G˖^XXxW?NؓjA (ڵ:uu]O {v_`T۷/_|7pڵk?$~꠿$ɭ.k֭&MJ2N[#eS ${ ɤH"% ; a<\6*4$Oe(H[#eKpe?rHcǎ%rBx$lUvi.Iy)X khhhÆ o￟%ɦ`@SNmnnx<ۿ[W`epٲe}ߦ+")KM()X/iӦɟɶm|7'kUR)Pe; a<\6+驮Ⱥ_ 6%wm(P$a9G˦`e6Q[n*,,lmmJ\#eSvmޟ{zzXodw}eeeI\< FDM~嗟={wyԩ3:`e㎷zwFVVstd3׮]+u%qv0I. }ܹ#Ns\zk_W`D*TvqM4)74V;ZWVw#0#0HE_j-޿nT3gSoo8TBl~> ]}v@˦Be9s#G<`N:38΍7:kD044t QajJ#oqy"eSԿ$r@HrT)8bje0⅖$ PΝ{̙ ;GB($],DyT555>gڵ*D!:x%~$6?*Tv/Dm۶g&{9I(RVZE)"2 Mj׮]^(3y~;waTw.I؁7c負,~˦Be޾}sssŪNttt}oFjrCKv.33jƎWWnW*D"ķo#R_x%%%Vg9r$J!nQ De)$M8}'x>KM(DKv@Ga7貔B˦Bek(((ذaJZC(DKv@.n1aHrTsϓdR! 0RZcP )KH2 i.P ]DFI;'h6[aqY*Be+---+I!nsx0Le䲩PkkkGQaѹpIspWO9hw$l*T%K߯EsᒄwZK֋$M.֐I&;VNjIfMFM~?RCT)JƤs-PoF|^5=* DAij:?* 4a9,]QI|&w'_F`E; ϡ[0_%<~A sjT Q;Km~WXmXЎ(6 ^ 2wl ,و"A bz+,̦PExo CeWQ,L?!A?"X#yjȧLeWFQs)S-C5`~#7yS+AGoTvi.I@3/ZQyuec…UUU+^{E~ϨQ̻$@9G s0=D]߼'O;voF1/}__8`˗'o/*Tv۷X_.477{O<f֚ QBesG抅{~3.-ATBe; a<\6*{ffh,Yb}~3O% Q$88+zRdyit\#eS?\pYM:O:emRay `&T/UuuА&69MlBxvp8u֝9sWdy4 *ÇgΜrʣG>yyyӈ&]SN?s挵sܸqAwIDTvfΜ)*w}W< Qe; a<\6*{"ѱpʪ*P<=c>s4$}ɒ%OOnqy( \#eӨk7W\!ڪon3gN% ; a<\6*.R|dff>3AwItT7LBe4֎ VVVVUU9Gxo~1jiiؽ{933;W^yoooؔr0L7?ص-Z|޽[C_@ ,pAӹqFÑrN}}}CC߷Z aS:o~͝;wܸq)L6蜙3g^tEiiib,kT9|P'?k??}衇PV#>8}M앛+@Dѷʽe{?~egg{<3gX]#Gw9|4~Q=N.rrrD룿 /T3i$ɯﲸnILՈjx¼aj7 ظqcKKWZ5gΜo&L뮻M /pٯߡ7o}[kM+V 'Nl} eppp۶m{oqqZz x> o-"Vr78G1+XO8[ouܸq/B.^_evms.R1gʔ)<P_3v:t5׼H{{}g}j>*vĦNç~*~}b_|Qo$={okN<ˑ#G~󟋇ׯomm-//#=K.Ò1G4{ 6~VSSW%N:X?L6My7#|:%FRSS}qN\uU/wh Ĵb;-6 ~#~Ɉ2<<,fddk5M81%ė ,;a1syO-W)-/ҋ/軒e˖|EX¼3}vC6lN>~Zʹ=GyyIIɊ+L2gz{Z  ?q5 տ/YOOR,DK=O~Jm֗J.XfܹZ ҈Wcԩ~4C x_R"zBIO!(% %~8[nZO> );Sdk]wގOD4k֬cfeewgF~~~3g6 D'o}ꫯߵkr:kmW:G,1kɓ'ɓ'g-/^re/`g?[ݠh)?Ck'뭭֭['[[[2E ?||`oG4/H7"`Rdk]&kmm|q.cǎwyۧKehhWiƏȑd/ٵkWZZ QCDN__>aرoFWvm\rI]]$%J endstream endobj 40 0 obj 13543 endobj 42 0 obj <> stream xZK$ ϯswD=T?|3@@Aƀ})QJK`x1jD/h1s)BLIo!^)Ys?>`8}snn ,jOǿK}pُ<̚'oX.^qB:Z9rq%.h"7x&̘c@k7@YekEZ*:ob*.X_%>.[A̿4Vdfy;0)2Ŀ\w˿;sI{Vht¢/  {?kE˧ZXICy(2Kf: p(9a5-V>BÙdډ}زm7\ӗYW쪺}0`."֜-pp~_`N*CGol@_O$P;M 6[bt5l(܈B) ݺw:cuvhobj{EG&U3KQXdt.*4lٝ`$SgXxF~Q$WYͲ']p}O4밤1ƧBC π,$a4"KxsC- "ߠDTE m\ (g7&|bt<NZX6z9QY=YE&C欐-#td!&mz\ɪ2v4!Gr:ddR걐m<)*O?>48VIJV(bm`G^HA$}qj ;I?eP&w)ͽ򢔖bnGA m )f}J ӇK$xxHع L7߸ٝ}JW:_Ml'8ab0FM)ke^eUMr9,:ʱ{f4xח;rׇ }|{ d-y1\=gRNssR5R@2r.Po0-lSԊ&{7N1,Gj"ZᄝaVL_[HBUXnrVc=rJ/)dI}0e_ [zX^4)1G.}Bq jhzjvu; {;20""}fI[X6poz``^JHB-,lhBV^@%܆/9VKzA[3UM%mU8Ȗ()n6S]jAqnDm>=+(Ħ}GeJb;Tl'gx C &5U%x۩iE&zqz9֢XQ^{\{TexSo\\R.pBy6#wV9q;]詺Sjnz 8zE#4"y8_MM+OW,b3$μ#C!79i=M>C|нW'!(źvN)%c?>K0 cKPz;nXjR_ìKmfs%-Rz2ڊZF5 Bg.rZ=2g*}_ZSk\AjlOڮ''aIb%*^ kQmu/jE+ id*Hj^xb܌\+yVz2[IB^ހ endstream endobj 43 0 obj 2911 endobj 45 0 obj <> stream xVjA }Ws[I#iv ]{Ph^\NO`vΑ<~;pa@Hb~|p1}Cat.Ogwy8O<,  0"ѣ!x &q)8plVBn!AUVUl`s}+{]xD% u,^yuO^+Jca]| |Ps>q#+k M3X Nv\Θ\c"jMUMxz l 6m{3uW4r0].,,qouwWk>a endstream endobj 46 0 obj 712 endobj 48 0 obj <> stream xSKkQI >6aUۅ1"t!BZh0"d:yf:BP|AzjkqۿsTw> endobj 51 0 obj <> stream x]Ak0s=,Q7eC? & I1k[!Mt=u~`{L0zrKX" 8yRetD%Z7] Nm/_c)Arϳ/fFKix"Buyb%lhBUE($;a%YJzht~ڀ]I=WCܩm endstream endobj 52 0 obj <> endobj 53 0 obj <> stream xռ |ս8~Μ}̾fɆ$7 K@BLc7dڐl "E@@D)Eʥ->-mתbVoUz)k1~sf6|?/9s|ߏ3DzBȌ6"V-݂z !h\/0 gwSv{(ٶGErs>!-b:4C:=vgT"wrsGh>w{lD;C%2;#՝;Bh6\;BЇfh5GxA7EbIvx} Դ̬9s*(hig̜5{NdҲrQ7 *BԂV ?FX @00: p 0 vy׹^đ*hU 2zBϠ#-j6s59ohZ(-v|V}-[:t>8W:҄>B@&ŎRFJǭ5zwl> u#h.G'Az5ktfӯGpw)QZOjB%@mXS:'F~Y2*ݐtMEr}YZ5,qֺ!ltE=۵wwwʗ,,*q;^NK+'3}??5|⤂v(dZ|j}g--̦.oDtK /!$3װәrWڎ۝u~+/ɩφL/Փ-]I.Ŕ*>t b;p8?.DrNh6.,?mcK{ljCʡY[ `MI7=?>v~nW-ה?w_lx;;]3b|LP R$N#к@rd":[oO:{tAo^~I*O;e$\;]7ZZHmH8G$KX n$zE$Yv 8d~EPz&%bohJ B>gšCqO3nA/z!Siȋ3@^hOqPZ1wT[}5q{9r ]W+m΀xC`9 `4XsgK6jx܋<6@M|nuK"\iaNY=z!W%Igӧo] 7{ ) 4p<< 4Mcz >ϓiȶe{ي=m l<^S8ި&,XtVd NKq4;-du\qngq8єiͶMr9I.;ۓ0<2Z,9sʍRK̹ܸL\f޶ԾԱll27YVYCUR })eo>][@ː ?ڪ.?Yk71гlN$-KOm6%%slٴdSx:(}2.G6S 6Cƞ sgtlGw7?:>V~O>bUmQ e_UOק7kզ[kuD;[Ӟ`VFdJS5}%*/|Ћܯ[[JiQux2 zqRoI`9>a5aCl6I6t. aAgs^dHl>y,F&~Dmٕf7e&WYJJU&4g*+U* Zmn)[9,k-SZk%BDW/qLנ^GϸּgHkk|kLl]R^L݇xg_k,QWނD/NpX rNl~ge:鲐OR+Mp68Kސ<nxAFҶ_fl3ǠAhD[\>hSI?O!)cO4:P1Б)PG6&$'fvԛwi;O6N' ,TOL\TFwt 43\)wC@._ecMc /:>qZnV,<7t|;Gp]3Ӫ̔s%2 3Ah@#䝍gaܸ%î{~^즌GE3HH&AA'NXDt<w##0YVsq4XSA"՟&d՟F8Ϙ'T&6DDz1)BQF!.ʯq۝o_sg%9- ]fAQ. aKe1{:UÔy5T|~A J9`@U@xìx jX XN9lU~gV6sY=s~~5g~^wB9Ԏ|y#wQ|?'zX B:)j B:3E :9ΉIȫ3&E')42EZ9`影kl7eD`nlp7d:HBx`6-%&mIfH2Jy( bQ^M CRmypۖ)_F}j>xVl-Z*uHMOW.~' q]{g/]LZ&G ((tdy6Gx@92d}}vMUhLIU:'m$ϵ.&&Qtm6g[iN7M7O['ONK+Lט+, +䊔rrrryycfj3ZZ䶔p:qiy$OR֥M=8i`G=w|>~ DxP³=~s[/6}'_yǔ?*ZwyGޱ-:uFɋ?>ɓqSg= T?+&l qwXA'y8ǴZ4mڢ M+^x"-~u͠;A'Zi' u!Ga}F4I+]qD9-n"Diޟ2 \=cDNq9/,,9g?GJg_ܳC̼PRo7ংHhyPG'yqoow}DH3㇇+Ⱥ[*̱ `dYOo,i6-)ҹp 2{xHufd7O,sxm(KbQ͇|ߐ0p8T2˳mOW/|7 jy-ϵD^y+nދw?~c^ĭIP3yCɶ( eHV7IN2&e(M.9I꓏Xu;,&\(wq1'1>=oGxUDN{⩁ {Y:=I#oO=ݻɦ]ܾm-lAHB x vvYXn8ͶYYf:t 4#f]NUx#@RG;mfb跋 nfFfotx'@ޠ]ݚĕ},31R!S;IyGՍ(:UXG[P7mV-:/t >|$oYܶx;a"?' DK5 L{v|/+9d +rn9Y-[ؖz/-Mh-\ Yo65gSZt3ܬZG]kk<==;VvvVVff;ݑp α&U\;};m{'ީw7p[qakҫLmi{7> %!n==-z ҭh'U84H}=q&uS:K⋿+/wp#wZ !e섀YadBvMn:CO߼_|Ђo_wkKCWP\B\lh] (HD`$ MgM7(]I١4ܱ2s@@$H$$iX-4e2T̔g +YN0RƛO)uJũ9\K/k5z`0& T!ǘ#X|io̺ 5[k^Z۠LK?/)}vdۃ*=[ V2wƯ.~т'#pYhw!y>.@c;l&2$¡uss055IX,j[du=Yg+o~t``̻cm][[gO6{*.^EZԃPM`R%H-~o]#~S(gIg1N̷ i~{90ǿRhmc \z(F:$,(8{tE-3+97.»_^R )G*mn׍&/}3;+8 {?@dpAhAQ4.¢u[A_0 -f2p♙Pd*@ȘmgUxJ6J.}:R^98L8΄}xp)4q>@ScH{US>rw>×ogCbW 7u\(g᯳S#pJ(y#OxqS6']F,xdDY3)W'gf93$!G88wm<]0 -oCq$6lpR]~z!dHRL4mK[b o.H0F+ɘM=lv^:bGlO,ROǴ] lv,2ck/YSYhb~hӓO;E}/y?^mرjciǗ-w7 {TEi\bVW=nmú}3{ $B_w!407`FtrHM.yMPXNddHF~+}8­ϿX >|{K/ܭQzw l6@8gmq>MAho*CӹZ~L'X4tc 3ًe*|bJQߵ*ս} 4Ձ \n)ĜN'8 6%!> zEE85$]H܁$ B8Gg!KӀHMXLIe0Q72OrV##,K )rt9׏8^?}!.{ _ha|ɝzMhj%"E8#NGv=IRuS|A~oY:--,:IA/~| 7epLhV ެXDzAa5Syލ^TJ4)iVg@٦*P{j|>TA)p,PFrPB}pZ8p^bLA.$D "CPJ&UsFCVg.t-9;8tvճ5*a>n׏!K_Q[3)f#%e dI\KzEh03>d,9Cg~aq8Tlc.̱̱α͑ʍ7XPF0X0Xk&;p`G)l!x_lǓ8rClݝpn h] j}8Գ)I2ZR>CDC*(p 4 H5#]ȆBn}i.S(e|{H0،>/158nVh18)g٦u.XJ@bti 6"˖)ͿW?V(nmtKz: :Qg`Dߎm$=H;}1ޘwKt.ٸcO_@mʎd%DMU|bw{[} k3_|lWJP+&>;juK<@:!lsyC6 !?tKDãZDo_ J,ߣzd' IrrJrjUZ{@2؁G*3yN熱M9Ziœɻ뮽?ەCZ:)PSAP!-M $:6؂s%m,3X:?*^\J$Sij"OuRQCsW.s Ry|Ǯ3ϟ{>4O< (?zS؁x|x:X`lhdJ 1ݞ挸AEl:}|ZV^ $[uB<*'2L:Y$U_Nʣz91.Ge8N^:1œC VqwRA op?{{w7T+e-;>Β;u;+v LF= ƍ@mf0 a0pD$h1;E/헔m~5,H5ΆBm0<ׯoGFN$q, [*\ 3}t<7aȁmqTsW in.%M'pҡ^Pފ_{Qu qĹQ eBbh}<%Cb>b+غj|;n||r7'?/g6Byc톰n6qFOZIgVkʼn8 4!  ~ݼE٢-[*z~n`~hyti{[n lMDf:c/nd*_ķlŁt96뱿P5 io'|l3 wu/[Q7v)W"B0;J؟]Ӽrud 5/&n]Ázh]ï|柃q; ;(tf50.g|uQz 7Sœd|v K>W莣whCh5B[Ga|~~"Fu-h9%8듨%EkݪKF:ܯBZx^&~SsHB@6 / GVwj=9μR3&>j؛wڏ;|59stw>)TwK/ͤ7MC+›~ 4"opY12jmڃZ $Nk/hmz0XS& M36AɦRF- Gkd#ijb:)W6A^CZ[~-Z[3 |6F, |0im9K,M6D Mk"M^yj6ä+ 4` 7DC q ƶ Ť7mDߥtxJ_n1|c5"]rwÀFKSl'etTc[9 T M=]`M F_ih 5Fi6PIJPc#ttOZUYbZQHЭRtjzOnB PqtF:@/HWkɖ}zX(WEj> = 7շEA@AF:j_]WO[}[(`hjl7n:#O+TV6@y1\F!m}rxI]!WMIe3]H%7SGl1!RMel,l!D(k"Bk`5r}g'X}C[PW>*7wPxr{:©JJI;F- ^n%6~b[ jkH-(W5k/.+jK+JJԒNW.XV%rIrڊR\F^\-W,ZXQ}.)/υyk*jhb6UUQVC-*.KV,]+j+)rZ"WTV[ZZR] `ʊjXlQ-Z^]1A&B_.)-[TR}bHِ\`eK% s+jkjJѱ;+/jmngsg(iTP}0\^6ʩǧS2/Z_HXmP-떭ރ4 5P@1+2H1X 7WAhnA`#KzCp\x m1׆@veԎ~@),׆5 `:NбQrgH{tQ+C=d:>#ԆJlu sB=4j -c\j eÇaA5Bw̓.FP3"MD((Bh5ͅ1Q .Bu\h68dT=]9k;#ET F[PV2)|tw'ia'[] FMioMKYv`{zo4G5PD(6~ υq8wU!6џ 0B0| ?br=UA0J^_*5ꕈ&ot9qQf뙌W[/GPʪvmTT^Hk[iXibwC#V0 ;NM"5I8̴BQt fa1^aT#ӐN z jR5 N%Lrtn^0^OFv%6M'8llAs(OhO'|G`(6AFAZ܍5yfKY@3ƙv7qZbx#ngz~aЙ k\/o:9^u2~S+ĬИ웮ggʉcq%cjdka :kY1<è Q|tf lecc}y2^TÈߎ Փ<#,Țy3,nkԷͥ<Y_ṛQܣS{TL)Ocd>Vb񋮢Գy1 S*1X(5Z_ZϴGW4iX=a혌_J|~Mml^[zB qpc=#+HHwqeTԯ#t_9E1ڦ+L\{4{Ib  Bh-sfѝpQyȌWqvif^fn Өon5_Uy j{b,fm#9H6cU+4ު0UWubc4R^i:Ux7 B(T(Ѿ٨+5be_ب&.3]adD#o̎bߡŠ=^Lj֌pU}WĵFVDG=6{J1vl&zllF{UƬњglu+V%9h>T߭Fc \{$+QGd$3ewGcZ cnJY6JXj~YϲZp"ԕb'*2J_6_Qw]QU#hGbj00's5](Vr@jBGMGW桔`$5#{]~@_w򲓼4.$/t3 y, y!^IN'ϙȳ&.򴋜( ?US yR!?Q1<10_xO*1J0qﱒ={dw pogEI9#nQe!N`ݧg]Z;۞+d۝+mϒm;fw$w e]ؒD|:pl'`MA|rܶj"AaB6I†xrzpKYo%7 7;:CdHzB%gF&=H&EHB"VHtz>[h%I[YhHFLZ| ,r i^Rh~4oW5eVU)`P I4(^!u7 u )ܨ εdBe ^!K%KR$.r]Zl֓6RYK5ARj*d>NR e(œyN̛+ dnI+Q(1(k9{l~0{5%̺̜! 3]df!aJR<.;4;j!SRtK(RՅNj),B')(@UF'䗒\GNI&Ơ0yOr k$ bL 9zNdOKD@lb>ɂSB2 K9$-H'$r]|OŒ$y#$F&HB: PIBW!].J\NrWw:9%v`]!+ܳ*,q 1)00F\OAbD'DyB?PN$ 8i?%"Sa endstream endobj 54 0 obj 15814 endobj 55 0 obj <> endobj 56 0 obj <> stream x]͎0=Or50#E2Dʢ?j@I@,R`_ɶݡ440opSSt}$mfW\1ɖmCV$<#}ڴ)|JSO?x_9͓:myא٬C<2߀RkGJ36MU~NB9tn~2-CK˥CV g#+A.-K\G~WWfE0!q~c"sLgFM3c]Gu]9ߑ/QE?r+WCC_+Guя:Bb_)e QbKdK˱Kc_B ա__H~>-/0(*jjà{8~=*6{x~oko-4G_QG?/GOG<x=KlLɼO rܧi9eF̲ooYq endstream endobj 57 0 obj <> endobj 58 0 obj <> stream xz xT9;L l$ $@2B :$HTAMQ -PAPTjUk-պ@mmk]9d)\2ݷ;! J(G5,^[B?G'5_(!>mu]"չ ãzd.hF#4:,Ln3-B)9Xh=s4ڨh]Ll\$88yДaG%gd3q9y'L4pigD`#uz *dGf?v~\([<^8p4)?~ BF:6QF`6bGM-b]x[cNvPߧ㱸,#-xhფV7!; ,v~U}En7qD3A~9*?%ghpb5n;)5#2AB5mC F QeVZn] z{jNG1A+vڮbwoo~p{0dFu͏r..M*U2/>2M9O-r'" OLMLMLmu?vr64ci0~yvaD(@^JojahEoO̲`9}Y{u|f !?{RN8sH+|4Ƀmcږ-vҕsfV`ߓ}oΜuKl`ǯfnHҥރL-Z( Bipw?}ry-Y'#h>ȍ8vd؈n)θ|]Xysυ_vޏ-v^jn"B`$ƒZ/^4ewL2[]]ΫUk_χ!#M+7u!;k ?ȯ5rƮ+x F{=]ܺ휟pȣGGٞv;+VH^/B_!!n8c_jC#>jsu`rjE+ Ih jɓ&fQfQ %$m$N޺qa۶x/-0AK [3ߓjY~G[m*_Xj}3BAfe"8/N9b6]8h>{_r&T (jY6NF*&lIo6b=MMOՠ ?eRl~ı\-G._TlB `lY\(8H/7ܗq`88Y\+&n\q w.>fw&(RGrZ6tOz\dHQ#1qKܰʈ؆O*.NXo'H~̢ `_С}jGZҌS {ήY}U5 =nifKicvjZq(xlGH ɋPȧCA5TrpVfgA~rݠ4O7'+ *UF3ֵmz*)2TsY& Ӷv&P P3*dE%c}dQ+O&w1ȧDSCV2o/̐_xI 0d;^ykK/`EG-o%tXS" ʹ7ܐy؀[.X;eR24n;e@ios\[djCRs7(~ᧀ_iOL!n923krc GdRq##@Ɠ_mj4F)m~HDSzc4hBC=7VpMF s2%.YEnqs/-8O0*ʍ_{V uJwR/(2o=*`(dPI@{S[lplTCɩo{Sq15:m,w[>ǣy=xךJAPwVIO24qt\Kɚ0x=1M1mX_/9v^ EsߓpǓQs'd//Ns G*%'<›P;x,Div4x9miCX2+Qmb76&(]CE&-+ȖЯca1w L/Z8;&fqTڏV3eqiNU' g+sMB=GZ"'xkr\(c}'p GjPɅIPɧ7=-byKǏY% -z?A֝CW1G\yz eN{7B,b'Fy:6^ $$}X/$_TȽ]Ə3 ':&Ny+z񱫦鏶ek;޳x]i+ۗhlpA ړ3*~8RoKĆϺ^j?eH3ZK3*N =tz0j1OR{bhOa3o7PccXMg>=|J-vi#= O I|e*IGYcǙ.uC~ Г I鬩b=(L6v?hg?e|!7=r\h2A:a(,YKj<3pz޴s6mc-8B7t%σs pI2v&\kw,ǧ.|&ZTg?;Vx/‡?*w?ybPoڅhiGǧo=!GÅ U:%ムrɣOO߶N&[#ZjCgzl~VLy:ٖ;7޷N%`Y O=̐Z|]|a#'5Nx 􈦙!NNR!$ {0׳mYu'-eSę5/r}]:> 2wWjoGJ˿eO !\89CɊHPC^虣zgf/>8sy9=h=}̖Qg俶Ymv 7slX3pO\z/}Kx/4  顢TC#T,RaC/3y{w4_VN9QclӫL1'ktE!< 0j8צhϏ=+擛2}y﬇w Zc L H!mP? ,rIiw^NX`҈])n F};q\o2c'ݱpP*[}7(4!K힮w= wsr#S~p[3?qGg䆌 _iϽ^T)a.5(TAja(MvH{|jg 򾮔a=v}tlӏxB~~=js=W;sݛ$ yqo*}va)hPf fHBq[768j#=[gFp/_aWqޟ^CP f#}ԘdVzRXh tx/񌢢/_GէlALSMAj|+[gZc;mjO?45Sm,o4oU|I8=8RIm/-/ǖ|By zȋZK1Tyxv.M!ۨ qD VcEL3X$8O\ Y֊ԅdըFٍ\k Kq=u#_njcu)8}==Ek#{pYe׮-u!o^=_fK%MRK3I\j?`rA䜀*j{'BSfLuv\9q) ^9i2hq:w|{u)EE-!‹%"(X:3w.+ߜ6tN3iGٗR.YknxNJ_;LCSջ¤/xJ4Vuy//<ʯޗ]~?{$lē%*A9ow =Fv1TKf/_h޽w>&yA~Ý윟= 6+i`G}X4 o1\!W\=S߽z jpwnA3D ~~BEQ2%3J3ZmrQ0 UpBr7QS8.T ~O Ws ,ԤDĵvXcSh>? %|;-GMh>l/[~#KA3 -+ VM7*8;w~(۬Ifx34vh j~2BȨwXf<.~g-5>Bvtq.J~׹\n [2,"wnrɿJ[Pin4ik^js9ըiQMQOF*Z^5T MULa6$"|uED  OX=E&P}*| [5*L'T8p\O*&֨pVD՝P`;E.0e&(QQ (>&V5(6&E()f413E~L UQ1M* *,A1%BiGT8MKũp[k[@+#䷵6?=D# DDH@NJYYQυd"E[P|/8 ~jLPHwJ¹Fy64il*5g$&J5~J‚I549%8,~(EU iJ<8if3QGYD' /!Dai ݞp+(Z lBUŲ:XY/̯4MbZq=Y lkVS[@ ($:m\ >Ϙ$67[.UufP ,Wt^[islPVzۼyj8I'^L56$K BVZ}@UL)Rq@0f5Xlfie%VVZT 6!VZq#r 䯅`JC F (m9ow+t64'fA AⒻ٧^X+A@;֧,k@$`S%*I9t+!zm F,Q%?P)mammVtHnC՗0FJNӺ&Huv&VX*EEP+jC$1{>W@M! ?,ȅa?bKDuaZ~$]3+ :d `42L`J_*nNе=ҩg\lը'úOo>óI:M@;sS.-bjUj= eUW~.y[H쬏Y-hHp,ZȊ!o~{tzFb@FZ ԗg4%)>/|zK'i`9d &+Y qHB}R6l ?C_?'zdcuGd|PhT͵YNh%ʆV3ݪRG+<ٝZ͌NJEրs"٢z)\CXC䖛z}E4eQ5g6YŲr9TѨ)+ԦGF]Q.@΅42IhOsϪgge]( >D^lU=E7FZ59PbKRԠjx|jd۫5:ؙO&X51Ʋ6)h)4ҾȞ\Z-`<@a1` f(Fxp9Ө¯N5ܡ, ǵTcHyT+b]Q(\LوR4KA*DW^ x̞LgEjC+'J^ )F9Tl!Ss٪"Ye QUmA??̹_obrFa^8~5C ۣV cExًJnbEoIZ(:Bʙ~ff*]v4~exEJkj[JLTEXH={+p51Ul_ %C}Z((V?K#ljջa_װ(UnchfXa+Ja!?6Y}CywjB+ĻM,T tewݿsGN}SiQk#' 3\U>+='rQ %+3}>ڭENV6+?<(LVݾ FU4 'RK (7 y5 e%dB t}̀b߀僐.>oNecdJׇBg}6Pr z_Qj9ڠ5Brq2SZ~V6) k'IzCtnn}чe=9RpJ/eȹY9+9E^XLtS1d 9A8O3|Sɳ29&29U.J29A~"ǓCcCr0($SOZd3^A&ٻJ'$O%{-#ddwydWH&xɮ"p|g<,$}oLܩ$;w ;dg7.*w<vđU/= 1"~@ۦ{ $'Sw1'lٜ(lItPoN$&+xq0l!VaL9uCɝ#m$ՓAdM'YHV*Y.Ip8 H◉O&˽qrx㈷tkv,t \;bKUbk;)dֺXh;I-BbZķd j%F$L-di.Y"2Y4, wvY d2$iIȭfPAjRCXIeZPI*I9I,9`JLz % B% (Z(!EѤڱIf9¬yd 0s.1]'0Et65IL(LM"SIa,I $L,  _'Ih!_GL&M$/( !y/#uBsBN'gq8Wb%cnj1 ؘ$ nY2=d 2$!ñ$^ħETqq_GQdz~,GȰ 2tROա$d N FA0:A b(zxI'I"7Q& pK(!@A$e←">V&1S4At VM DH4B  D9wcmx?Z@Wp endstream endobj 59 0 obj 10110 endobj 60 0 obj <> endobj 61 0 obj <> stream x]ˎ0E|˞E p"tRФ8i ,[3#"ѱ]U?*qX~nI{ws]1)LG]9Bq[0*~ӺNK}xI~ma|󧻺qIiޝCL}XsH]jt\PzwvdMčkUL9և"湭Fz [eKe1 u^k]Fރ7-Ycܓ\_ "PU_ h.Kͥ}_s֤Es_c/&(ӿĽ2K:O5t7C=[x[܅/ՙ{Kǽ-{~tg(p[(G܅_[ͥy۝>?vwCki3kOy 9 endstream endobj 62 0 obj <> endobj 63 0 obj <> stream x{ xTչ{=ǞW&_&BBc(*>vk~Bo]kzc]  ewe? 7ti/g>烽={>|Y@#B9@?w8ކcd><߳e<01p*bW5Z`4fw8S\Yn1ۓ3-w<Xf }h-U0s;Os7jc61{ݎnF?lw FN*`9mA{ops]&igv1`dW>nM0N`|ԅ*Q>Oa>3:@'L.} b4˻b8 D1X.>NUOA0G@}ZR\"sx-r\3Uځ!GvA(7K.<7+\tD7iJ} 21aRe-lrJAȎ^RfT( ܚ-⛭ٳ yx57W^mh|q9&?pYCxJjU[%5H`ƫ*gp]AjHu},^ KllKn%CW"8GPSOC`[|ː!3 *Gltk3--XK|{ʂ%u<˼yQ%輪RK t̬.-+e{9ɶ:p9 17f_K|[1؟x%s "ʎhϪՌpheʐe|pr"l?2^ӻ6nq=Ϭ-ud<{'B?-9@9, 0vX©x&B7U<~q|imi V0=ǣrS"(~߸mݺo_'tB%q1 3ͧI;#I)P3/II"*uLNРQ7UTAmaэӂq g_W. g/yA%̲euh9Rԫo̽;ӆj[m1斚޿|^|B!c?cn^M \u[vLUZ3|+nszhY9!Ŭ5bŘ5Xcf dh"NCbhS!pIiq¸u^ xZ͟@(kh \8eca#wUn89gc1ft>7!qp3P:S XּM՚MjZo`,MVmH Z9Ri.66%1aR#NJFSaـ5]z!MFaZ2W3.&.uZ=/W ̬f`6̧As!Jw mp3L4˒ cɓqy1rv.7ʄ2 i7jת*͕ۘ;;m7MVafa?q7-ݲqI׳;M,&#U=Rcrǽ9MT|Tk &Le,36s"Ehbgsrm ]~$kP0UI |P?pYPj0b5VdZѯřzͥ0)Ϻ 1ᙢ>[cdi2;S|vY&4oBΣKEb LPM?[=>^zި7Շ /+|]P!*U۪kշZVwؚiY][_kXk\kZ^+^YSSSӰӸӴSܙӳ3gvn~aqi/{g_Hϑ`,FLSF1rft3Y lu=[z#5{vǻ[iw|MtU7n&eվjWn=Ζ.W-a#]/>%FPT!h'nC iՌÌ\Qrp:QǸ<-yy瘓%E Y-` >/5qzlJ)c %LS)4"=,=$ #~poQ <*tЬ9wÙ-ӪʝL` pN(Ӗ5x,n c1<::>9=38CN&g;rzo|~*4.12Ŷȡ[k~29 󤷈Y,.9s6Zvp8Tjp!B7] _+gl ؂"s1An?tQzXC yΞ-&0=abL[OΏl2W \bhm oO0jG-9,aU#Liƽ \ ĄbTFUwv8DBp,gNjשj:3Q(yVTʦs?nydGK_,⫁GA| d긃.ٓ5*szsA,S@iq_xiR KJ4ZŧiJisՌ2q ͐b\ڷN^Y{2έNe_=t?t,i9\V4IKi {/~dD1_ˮ6:<;HdŖTe. jT[ED$^$YԹK&]_Bn7r3LŅ͢fxR>&RO`TlPMRw-U+{:&Fsg;?x7c˶{FʑkkW?dq>A;0VUPp+X]& _r$¡~rՅ𺺺ptˈ2}&RF yl$\rs44b\V'Cz^zYʬALuiR1qfP5\ ȷԼM0k5mZ&֙b6;ku yfYGU̎[ʹNeIAK3e\г-8O92~dӤ~tRC9'`v@R))w mFٮwhS2i4}m˴#3ŝ^^n[V+-EnnydԖR'[H*bf>t98Yz[y%}:q:M-ү>ClB3j_9DܴlAf3E74zr/uúL`Hcs̞iC+P½,[ y' *> 8-.er\ p$Jr%/yY$]";/G+qN38z̮;mh)`&6rĕn}Rͧ'nf8&=[{oUj1?oįc?{{H<C&x=_lmD7\z>BY r|Rzi0pħ-ѕK %F.b~,  &丆^&qr,Nl'6 {I^Dݣ8mrD`>}oM9"Gի:9B5ˎߴloI:I=h0FMakB[@z'q;ͽ4LR#`їg |ERVd,fU֜Lъf +Qy.Ǣ|9A_]{zo'hQ˝E K|Kߗ;{Փ Gk󖻇>|u;2`ӱ(±qY4q~aM#]PZ쳢 mHPtӆ҆Χq r|oLMc:vĉSplfe6at;Y2+҉(ǤN!i)QLb隮NAVݨ=H vaSZZ0!R)\^p ^TPkMzőIb&ʌ(3P/!_TcTyň,jX西tb|:^WWٲ#vimx7@Bg#QHnnTf\^&]SsțƌxF\ Nn Flј+Zwh.Wjp{TA~M`l3#Fur.uU\3I1W?q'}⻝PȚ!:emx<)LA&;pӎ4atfF3a35.B.MeɄ'yKpC#zb? IY5&lC6 Y;T.ilpre2i \ dTV5ٚRWeN ~~f/eIlod&?So2 򹟢.ڰUP3~f߂ Yvc')0mA-QDow.ߋQ5{BgTwU|1 u󗑓@Yu־M>Z~t[pݦ1jca߿Ux*'),0z}(>k[˽{sUjnVJVԱ]_E3ÿMYש&lȠ7$ 5B\?8DXaUB_w&t@ߩȂB <_BȭoR`(0m 뿫jJjH _*0FN < BzC`AaR  `U`ЃY9d3GF> (0+0Ԇs ӭ#(0hS`59 SfPHcR)0FI94X tBkEh5E#l"y@@lE:b`/ʔ?d񚝃w=bZ*:]C`/:@Z3: ŮB111 Z(_t3P4 D:(){J<@SG" v (+ :#)]:SNP`G `h0eA!Xwp> FU d#O)TjjHwadЀ ;*_5aȆFC}_\@58ΐ (u .Iw:]3LCC*E` uQp=J.ėЍ:~ƚX;BwY'rNu &.$E`7&:4 Jq !$H. >4=X SL{P;!Bc QC{dB(_cnTGb^`I;=SG, MMG {Ix#=5 b(?~ǚ$-`1EZZ%V5MͷV4V5MbCcʪJSϞB֚+EhknŊVqYM]eXX$75jk`nqʚ%"XWW,,itB[^ոx)e/Խ6U ,ȗ^XI951<%QH&FREtxk(N"QZ`O89jCQ;\$k[H&5!hiФUA6FI'S $P@f#V2l|ieпXHR6_7xmA(]_@\^#y0iO $DbS F:ar5P.{2T)f`dco z'o @OXZ40ՃT8ڀyNq>ms`. ?܃ i_V C7ד$袁`"/)* %>( i7'I!}TF2.J@QQ ZQ(u|{Q \k!EE@G}FkP?TzQcV>5C :T Z F)L@>Àt'siQp_://`c Q~ l4gur]-k$hh( Gpu*C_x!vjh`MuV@Z2܅z%6?c bSuw(/z4|}mOT(y?qj?*^d ^62n:PZCwIt@b7²7RB~>CF WȲt(ӌR.:q []G$yZdTt&.z?K8vbAsNH>C sN*AZ;Fl|/ߡPlRu@7>:,Q:,L=㶞.9 rӼ#Rr<ȴVZkN65^7)zkx4tќٯHHڱ~= }HM$q%{wR it6+@1D3ä sѤ ?DCd n?[DA0[~E)D'}44U<"sJtڙdd/AuRN4@RS}7ǵ|L9sWs2ukr= uJ PЍDkH@w)XO=ש׮ I69vj34CI*@ܯDt.if $V$_#fz# Q_/tdvbM*&i.ن٘(HxD7у (+R S5Ou{m#c}TJDؕRTEGuDft+tDaf V!EL~"kP ݣ 5QFJ{9½J#+Jx&DQy:XLc#Ȝ6S;9[O@2[k(=!|V+VPʄbਖ>ѕpo& *meY(%dý&Kf٩Y,y*z2:*sVXT]|JD寅K7H3MЏӍJayVR*"gm1*t J6:K|UTS X5k4e}6IIJ+`*ŧ*J!GR $MZNℭ멗}Q+XXM -T]p2v\g}Q2S-XIV)+*kM;{J¤\ Yx orTr͚<$p׫\SOvC(} F]\?Bd=ib$"t_YAeŵO[: u 1L뽼z G΄7ל9U} |ʙ*H5L"&uB4 GGDk8T,.)#{7ޯS}o1屓v~E ԎB"og#vw Tt-~Ӌ8_?>Hf<*'7_$?t| wwϻYy~q#\,ܞg ԋX"|xX‡`*OE3 (FO'pOJ ~܈oF|.᝙xǽVܻKaoo6<2lG$.K›7Kni ~7VO#\lC.[c>nC.^?<p4G$<$Ό׍pPpKO½Ypוq}wؿIZoWKڒɷ-V/^M.ynrF^ѐ¯ &oHpw|f/}\92/oٌkxt3^UFڋ* |W&4ŋR{T\3-3aW~s>_~/f|T~4ߔx8߸υsxwe{-?'j3=؛om%=_sqQ/³ -=Zp+5Lo>.oۃg kp.=ٲi8n9A-jlD }f3,,>k>q8͋Sa:UΔ|كS)%;xTl%۲Z7c dЎ a3̙3I?=68Uwk3Fm5'چU@VeǼ>VsbnÌV} +3fF8d+L=3oj&2G endstream endobj 64 0 obj 11525 endobj 65 0 obj <> endobj 66 0 obj <> stream x]n0E|"v 4REj 0IwRc} o5tuj}BMH'ƪqRIk@?uEŵjl#=$Kh(&Cn}EIYNq.rtvOc_ޓ<6Rw ]P3% Kʄ|oi)9*ĨQ3]F<ށs| #QjK>+d0g606̳%X-5ﰏfLj# ,׎X3/lo;|7#n=G[ϱ{џ[wwpG+Ŝ`hOBl/nh+tTG?S endstream endobj 67 0 obj <> endobj 68 0 obj <> stream xZ tՙm'dILdlm(IJ-"d$96%W48JbBCPBJ!4PJݺ }8ݳ))[zwvӳg-<{Wz2R2EtJmjBȏ {u~7X01}OyEAUe87Rm ~Y'RC6]#Z(+;q*KV.8cJT}"kc8n}'jn 8'"Y@¢bkIic!}g7PI'i6Wv 8{|!½"; y od;3'M @B|dt|_)bP p5&yo6Jia3~If0>*HP -喠%HIW)FW$-Rgk 7BtX.z%'ky7~ֳO/EG#MZF-zl<;q!ٓpDilK/W B[ +RPOnj%!Kȳ&gDhh-ʕ 2|,- o/vVbӚ_k--?qrT^nGp-.ƴaG[SPPɻ\o򿼕,̽|_DNj-fMgLB,VXy;WksCKϰ`Fژ216nv*Hq;K^, k|r jõ6T\k:;6tv@t4jo >Y{Q{3/ڠDZډJi{X>,ZzpP&6լַt@h1B_=Mp?[­ƾ ֓tt6HM BC:wGˍS83s-M{CBbRMu`-դA'ni#+n6 з\?7 p#qC*S5ebIZVX. DWe(dY %Ta_|GFV8|'OGիH/`-?DO!\:wFZ;A-Ena\sPvv^| …va O_I9iްtѽ.nij\$wA? Kg).UJ9 d9ഈqNZUN>1K$yeş"9]N.t%)*_4i|Y_@i#*Nd %R^ӅJF dӈ_44%9-g8-/r~ӅdYɏ̪GCɯ8ԖZ9-NKHspT XZz-RTqPz"))+}hg8~">Vijo9m!i@ӜʲRNKl1e8]Hr'˶qZ uK9mA@ഄ\RF{UYÈl:A3giV 0d-S*E3úHxR]mYO'ԠZMF4ŏ`ѱ@P%`KI]d13"DHBB?hT"cPYq3`J$`ؒCDcWRRA`h0in2[DźSM&ɀ&7fb#՝Ymda =3n)ubo<5Lݧ㮑D2Q?"/HLH吢!TJ2VJhh9B; cB+cXqx#;szGz~\n<rfR!gnӷ&9}.هvy9{Fyx3:a]NW8wx> p&<^ǐݳF-t!;Ra}pPv>>Dyit]!Wtnbt+=vMޜɅ ;\}&{=NJ`Gqb1z'/2`*;,c]s{|YS9l8Ԅ>ͥD Ɠ&9sgWrQi`>^jYX]}~5lƪlX1ܸ#qgpEdo}`uid^F[ 8m&at<q~iJT A1-k 90L$:6YIl2I~T-jYhRxRt+&y, 害Mc <㥬U6GkMmQIKt"WD/k}IOOQΩfYz(zШeG.ް2Ǝ $hњE0X0G9gA0Vd@Ӝ!df05 k.7FhO(5A1N{JۯZ,\h#9c^X;Bڤ9їG²/-@AdpeD>GSySeiB]*ކVWcxs;ƹprQ<"Q U5~+GTg8̪#ԙk\A.?G PnvTx7UI# 3kЏUe(:['T񆬍9 Pu fSЙ>%Y`FqUg`{ɏ V!u((W)C[^v(e:5[6wdl;̣:?:9DUh#4dvCP`O)O*zgy8»d&C~;,sK7R "Yg "pv'!w67Wrr2YL0;r|#G;?O.t<-{:/R瓥1Ig폲f{9Ѩ:zi)i /U93^)DQ\ƣ+1ބ\2*zX=}qy-f-oa\art$@*/:73e+3o"*w L0Lqs1B ʟ9u; ΙQy~db/J8N<YլD~MϿcBqUVQӻz8]M1^,r^sAU+s. "$|q|bvc۫QGt~. M\8z8mx5'xVl/ˋF!Mda|RDf2w!uLѼðpvG%zpfǔ'6js*Gm1-|N|LcƲ!y6)JvqK,FbElDgG=|^O;ٴ|ūiQQ7G| 9mCO/ZY272s(<4[AXn숟N?Cf"`ӓ/7jy/dg.Im~v~柃Ejq{1wfgzt2_{xlML͚̋nfj5egC9/ '/fxv{v*;;*^t0.;˵7>#yOwֲ &VF zzxo\w9\;zo?o[iӖkofg|Y?gV;On+-ټnۇٻFwA-{+1Ϗxf2Vsgm08iLYK,2 -Pm"< b FfBKq^:oU/$w d+M\Lh̿nEd=W}mYx1˳<3n=m[x(äEr Yg2/xр[v,|o{3 ` <\$<'/oM7K`րouf*Y+|u)<btO?Bzj * x2NOtKUvx k/ܷJ~Zz>_ (Gz鑍0}v9>*4f)M]pKo>S%ݷ {kNL[ vt = .O- Hwp'3w)XGJHe'2UYpۭm܊NK*7H7pӞ L22Kr|̀ɏ& j8V:`.i,.Hw`qH+uz H"rҀ=gJL[V5 R [z+ Xlut,(ۀk iW;K;Z`{=lk%|]p2&._Zp \0,VP8XRv 篚g [IBLkGo(R鮓z]}.+ʡkJ|Eyו TqE3|:#pj:a>luVHN)bK:idctItK\&pq9\TZ"] 6Km`ZWAJjت%n, ICs4wWIa=έ]"hBYX[ m5Zc@#6NC\$5XaJ@W UU-ҪMP+'ႥC.PYe8Z K%t, rMTl$TKU-Pѩ4*VBy%Oe\i(-.jz(*f ` HVD%) D R L!p[' endstream endobj 69 0 obj 6300 endobj 70 0 obj <> endobj 71 0 obj <> stream x]N0}.ׄ xDoo;jMmjث]DJK YtIiT*¼Wsǥ({ٝ* pC؋`|m| QNʒJ<30t[GohuWl' %-.zI-(>{륉r93 GM5Uۨ=G}>2Ω"?~sk9p-5B?PYLBJ{~ؚ endstream endobj 72 0 obj <> endobj 73 0 obj <> endobj 74 0 obj <> /ProcSet[/PDF/Text/ImageC/ImageI/ImageB] >> endobj 1 0 obj <>/Contents 2 0 R>> endobj 8 0 obj <>/Contents 9 0 R>> endobj 15 0 obj <>/Contents 16 0 R>> endobj 22 0 obj <>/Contents 23 0 R>> endobj 29 0 obj <>/Contents 30 0 R>> endobj 36 0 obj <>/Contents 37 0 R>> endobj 41 0 obj <>/Contents 42 0 R>> endobj 44 0 obj <>/Contents 45 0 R>> endobj 47 0 obj <> endobj 75 0 obj <> endobj 76 0 obj < /Producer /CreationDate(D:20071011083052-04'00')>> endobj xref 0 77 0000000000 65535 f 0000258019 00000 n 0000000019 00000 n 0000000630 00000 n 0000033496 00000 n 0000000650 00000 n 0000033474 00000 n 0000050823 00000 n 0000258163 00000 n 0000050845 00000 n 0000051477 00000 n 0000069574 00000 n 0000051498 00000 n 0000069551 00000 n 0000082720 00000 n 0000258307 00000 n 0000082743 00000 n 0000083424 00000 n 0000101460 00000 n 0000083445 00000 n 0000101437 00000 n 0000124686 00000 n 0000258453 00000 n 0000124709 00000 n 0000125409 00000 n 0000141691 00000 n 0000125430 00000 n 0000141668 00000 n 0000160150 00000 n 0000258599 00000 n 0000160173 00000 n 0000161153 00000 n 0000176050 00000 n 0000161174 00000 n 0000176027 00000 n 0000187931 00000 n 0000258745 00000 n 0000187954 00000 n 0000190466 00000 n 0000190488 00000 n 0000204197 00000 n 0000258891 00000 n 0000204220 00000 n 0000207204 00000 n 0000259037 00000 n 0000207226 00000 n 0000208011 00000 n 0000259183 00000 n 0000208032 00000 n 0000208693 00000 n 0000208714 00000 n 0000208905 00000 n 0000209197 00000 n 0000209358 00000 n 0000225259 00000 n 0000225282 00000 n 0000225476 00000 n 0000226073 00000 n 0000226513 00000 n 0000236710 00000 n 0000236733 00000 n 0000236938 00000 n 0000237491 00000 n 0000237903 00000 n 0000249515 00000 n 0000249538 00000 n 0000249737 00000 n 0000250209 00000 n 0000250535 00000 n 0000256922 00000 n 0000256944 00000 n 0000257153 00000 n 0000257504 00000 n 0000257728 00000 n 0000257801 00000 n 0000259331 00000 n 0000259416 00000 n trailer < <64EA35B1599B42F4651C9CEC548635BB> ] >> startxref 259603 %%EOF kst-2.0.3/devel-docs/Kst2Specs/Data Source Changes.pdf000644 001750 001750 00000146120 11544160206 022660 0ustar00synthsynth000000 000000 %PDF-1.4 %쏢 5 0 obj <> stream x=is7rex((kew%KI03AMmU僙ONTj*+`p4{J* ޠqw7eU]Uuo:-mUߠ~~藣V(6Y;_,TE_PGWuE~6~Uۭ\7o^~smjD)Ƽ =ܕ?V-HKįufȟeCvTrec~;⪪)r:;~Dgo~Cp4ü٢P>a]O}G3TF6hdEv]Y Mh/j>=8tz*Nrt{Lg!<]bZ`{yda&yCoósw9P]XKػa'V0=kW;OďʅvߚS?a2zLoǷ304P]ߒow:AV/·9[ }o+x$iI>Kq~tg!l%E-6/w?߱D9 :8>ܵWN>\C4WSW y[ARi0so3Zյy=v=Fs0qy_vl>ևg(\ 0?W8,{;{պ $ӰVj5_$ @ yx["M gJbt`D=(וbpM,7Xi0dD0YcS< RHA)̠ JIEllc"0p{G7a]O֣ \zw.ڼ;,j"h[uimp،'??s98Bn^_y3No<_%V Z\А)&:b ǗBꁘ-CVVCYZՓzΕCWYCHJx0kwVrJVKc?`%cx6SڙDԔް H+o0eb82Ĺ0h/XK#\GCُq?yt~lIY0(/f Wly9j YfgtImc\MWse kNЂr57Z2|Q]0:"#Riz09 H?776l|J ׹4e$D$JXPƂ1,5ch+6UuXab]!ZJ/[Рp~rɣYX~x5)(1vU$>zT?;E*h9|8I)/&o/u,B/++%y-k F;wQ B< -8 )M#ڲbN06!쏮J\4D@@`"aDrIau,Չ&T0ֹf|՜n޶MGL3CN6sVe('~x6 :@)},k0շ•u+țK?؄HXWugѰ P K#esf6xlM"iLgWfd&ȸFJN/^ G?iU|⎺gbC A(PA,  n@H#P[Рpc[GQB%ٴA,[R>sqN=@]Ef:7jR> Soo`v Nt~'3Ig5XFQO bVfIZodB(%n6H[um5NJcK8u]mWp 7Q߂2G$n%O21:WU?x6Z,=n~Deͬ/;Mn,ZMKYض pRޥxT<޽f=?ppG#`Tˏ^!V߷lAd*z5=UWp 5䛟_ C$p6#4X{=hwtoU{{Y1F+M F^-zI*29"j'1h%I/ $SH/E} ZO鶗Ry~v|'soypar>ݔ"ǣDl6 1=Vἢ[yeMJq6GܿMm'ypFǴıM zd3P(9ńTLo(C0!7HDW@c풐҄ɹmNmh%qP:D C =<6UFqz_-u9d{4ד,Ng"i>Yw)9Z;Ll2khB/W‡RѼ.lbi _a1Lpk廉ѹaZZ-6LcK8Rk[Z Z GI9.mKR[A Rx V4m;5HHpq6(,;QG$9>-2+BorwdǷ@P ׭{B0^Cqu+0 tCuzaz #@)8ݠPy}4ǗHYLBPuQ{? 'ijUQlG;mA3햬̳Bmhavgd>_e$; xp Y,b٣f rO#I8XQpРp)_O( F; Hi &sJ&t)6>qŲ,ەësӯNvX0;vc; ^FjZđ9jF( X8"#2ĝjQhE@1o"n)X?Y`$a=Xvp ~)SicULGr8~hËbT?s;7C8~=wj ԇ85⮫ʃnMcA H'SnF*++{4' &PU(#i4% 3 c3I82BGHiE4xo\j =$ fEgqT[adNH >O݅zp| L?5rɩ/wDQq8!>(ϡX>i88C} tJ]_TDV 8sgt*ћAayU-Uj̎2['0N̶\YDVc~~5 Q&$ Le(o?cѮ [^(*3SЂHԒѠ.34|Sϴ%6`sBϴ$h7g1c?h鼭 H3Ux!$Uf_TwVf_T!#(&KcK8ɪٗPwoAVQ,2G7[d#rWC;cAh Mabb K kN-Lh qA2@ܞ;$+~#p%ɲ6y++ w1.D9,-5$7CJ%p6Mǹk|&m^ Ge2:]ɋ;1JnnKGXJz9 =Zi'd#ᥬuv_)ޗgZ ťћUHl7f/򺠠fg}NJ*=ҥs]z@\?B >X=pZDv~(i GR287NQx1:iOk*aP&MԶVBe j*W͑;f|*ؿealOF߂mk9~>&SMeOcFE?'H´Z )Rg\% +w(gDd p7Jj@2E5SѦnnNS z4s[)A3uYRCxрyaZt^uE`: ' =o"haƦƍ}4_uỽi'¢OJC$e=;\KAqUU@Q`PYb̹r?Ƨ'i4H/\gz.6]S]zKt@3Jꬠ<#tua8N𽛕iO限}wFHbT%_vq+Zb,*QW ,`)}eaY`؋$9 >"LZ&h"f1ԛm`I- s84V[yWH(޹2]TLoƧ'+Wobſ?.cendstream endobj 6 0 obj 7496 endobj 56 0 obj <> stream x]oGNdi眇SܙAѢIK\(q?Ϊ ȦHc~3;;u"^*?g۟fmR?~|ɢrPyFҲT/~k/ V>-.UUVpߔ@VYLjYaft;eZX3N'k} mZefF^YrF;,._^右cѢV(/̞yqoUS*^eξ C;L;O?.-i Hך_cZWX{1Mzkҗ%cPibG֊NO*R cn_Ѣ4}pxpzMDYMԑ>q*NU녾~j6E2YW)n2uKip,O{s5ݼ:y=UlbPSíQl k\pmZ3Ϫ'eU5/gߵx,0hgl!U}@>V `FAV `F(i{ѩ/ODnr|JI7)31?I7)K7]39_xLSkMZw|}Ã59`~%|tOӾ֣s7;fuS [`񁀭pLtԄijo+E G:?>^=}AFgl\1&G8+5T3ܢBA}C8'S`U4R:&w}1Oqaރ83ƕUCVhF P-7,@&r\V.PYⴤ,S,GF|[j${e'UI>twRWk (%,{uZi#5aOdKQ1+qj(M9T!2'&Js*}hIȶ'B4sHa%ԓ=~fu p;}^+>LH{ Q`q/jD` ;eFjpjw= 9d~f 괠k{!\_"w?&eJkrs'2ݑu$Y"@KFk+j`QƩX'g{ X_*oE/ (X6G=G_)̊lؑ)(\j'C_smcеu=A|9v, 3:T<V£:& i索mҺ|x0Q-xSsěA瞩l ^&zX[a|G.CI@fu-0|ʪ |J]SيeFZBY Lw~63“gZ+h`H&-J+O-5È:8rw}k'CRes/ʼ<փ=\)HnG:Eg)s44|GְiXWx;F-bBuAU^`viHFkn4/.b1{D')'=\(jajIORNltM*^ϡ\{~-8bI % Do(qnV2y3K?/T}" 龆0 g묅4 8 /ge\VĤ.XIT{+ Qȑ,;GCA2)Jr^>!MY%O,@trFlY28s뷾}3bX_DRvN;V( BM{b_ ![0:񪪚@5M`%]S~q/.'b/>3~_Pnf W/wBl۾Yd-威VSGxwq)0bV%-k,surp[BX덱߸gGoV0b%@%kl|Gb5 jnc`@rL9γ 3 ";^fPlX-(lYxǨxiQ+ng#*4ݼw,\kAtPe_? 58S2lZgG gIz;ҏ;=zp Y;;Ry}^c46ס&+EE%‹dwćendstream endobj 57 0 obj 4281 endobj 4 0 obj <> /Contents 5 0 R >> endobj 55 0 obj <> /Contents 56 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 55 0 R ] /Count 2 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 53 0 obj <> endobj 54 0 obj <> endobj 82 0 obj <> endobj 83 0 obj <> endobj 75 0 obj <>stream x330R0P04W54T06P04PH12213s`9`9adnѐכJ3 endstream endobj 59 0 obj <>stream xMQ9n1 i[Em(,mJ%O1᥎􆅷6觟K!|VA+̄󅬓d,)" J`dkX1'\5|Ӛu6:^!눅G>Nð@p:zx'zDZRɐJeS֥LBȤl͖IascC6{U|9\}򕽹>stream xEP90 Ν{RtrVrPt1 WC0) o&aE2nM< 3&xSa5hgw!dBV ,-q<7*ܿ M̺I%U\Q~/ yYLmOveTVg::nϋ8 endstream endobj 68 0 obj <>stream x330R0P022S546T016V073PH1\00264CbBeX rFMJk endstream endobj 52 0 obj <>stream xE;nE! D{V1u*(یJ)`!&b&-a%0w ˂iY  !AMg8θk'BYԜoLiG?CryH>C^gqDQ|'YF V^o v6gtd}{ҾSL9tRL8 g&NN=VKq\t,?D"{frkvU endstream endobj 16 0 obj <>stream x591 D>cMyh_=Iu-6~{ZI",jf:V |L]7e tR6ֶiA֚V1nŲh)\txz$AG~v^(ʎMጻ*9N\tHm6T.Ȧb q5a5&'7k0a"H+*xrE'KVR 9p,,mb*&CZPG蹭;ˠo '"EUp^(q(Ҥp0Xu;9h㧕T+/1"?_?, endstream endobj 76 0 obj <>stream xMO;C! s ϕ*Ck*u@v;㩎^*xçP$s{ٱEƀlk7Lx4(x8D ͳ&d#4UK~+a =7>7UBfRfsA; e8goy? 4p endstream endobj 60 0 obj <>stream x-Q91 d{&*6&!B8b"6.Yp5)2 jb,p-t:XGpzHNA̱ÖK Y6m1x:A{Usr9g;*II*v[U()5)S>VqYkFx292].wASUH ٧ofL>stream x51@E{PbO&myߤRG͠ jPn3kBu޳8☭>Lq-x.; endstream endobj 25 0 obj <>stream x330R0P02F @V!H Y&@HȂX0 DTIMWT endstream endobj 69 0 obj <>stream xEP10 ͝0c'NׂkKg QCw3٨Vfsdh Sa}l<7Svpg@~L)Ss6M'U@=ײg-i,<Zd>R+^Ӎ:}}^: endstream endobj 40 0 obj <>stream x330R0B]#cSS L!Ő IR(+M t endstream endobj 17 0 obj <>stream xE=!{O1u*=me5 $ ed|(ϢjQ}btq`(* ١^#rOS%:X!s$%< mmg{ܯA1" endstream endobj 77 0 obj <>stream x=10 ws${RtJVNlR"@C7s#m.Zґ ؛Ǎ,u.0Y덣C] 2\uNz7mEI4-ۃ1/iC\Z4Q|5oZAqI5hyk3hW6I endstream endobj 34 0 obj <>stream x34U0P F )\`%[ʕQ endstream endobj 27 0 obj <>stream xEP=!=ENA62L^?y3j*N Wz~ƙS*ˤQ0tc0w+=ne: endstream endobj 70 0 obj <>stream xMQr1ԩx=I+vhSX)&ӷ 3&?B\("P%dK)OI\dn-],Tm* _quRhZ}A0cn97P0b6wUXnp☼W{7b؆F:8٣u՞,g_ړDW@!Hr,'W $?`!c_rxޫ\7ΒWi5}fQ endstream endobj 41 0 obj <>stream x330R0P02 F )\@>L̀,cSC$625pD^ endstream endobj 18 0 obj <>stream xM;0 Cws'e'EkeM$A'Ew85'i"; ֎ T!cYxDbn\G+ۤ0U邬䕀 YnƼڞhɵ3 endstream endobj 78 0 obj <>stream xER;n0 s y^kI9m@,S.*CvK)R+m%ߍ"KRkH늑pɕ[;.q2]ak?w`fed +̛B)mu)mV^E YP|vTg>M9:`p]}Ha4'[ͮx$!s;gN GAq endstream endobj 63 0 obj <>stream x330R0C.] endstream endobj 30 0 obj <>stream x330R0P02fF )\ 3 &fY Y " btXP9$59\iZ\U endstream endobj 28 0 obj <>stream xMP1+C{ԩpCd m.X0lYҧ1Y5/RP!{ xN %{SE X`!.`H 5{꦳C+U,-?㉙_{R:FW&: Uq_boWm84 endstream endobj 71 0 obj <>stream xEQ9n1 N mHyTMM)'..|b+%D=9D8Vb&+Ɨѓ͢+xa5]8X鱲V@ QMXbFBْx3<}SI;K ȸCt0z%CE[Jw)Z!|!B*Eb[qqVhk?{ub?*\ endstream endobj 35 0 obj <>stream x51@{^AmEN8?V&@\/i>oП^')M{$wrDSzU9| endstream endobj 19 0 obj <>stream xE10{^AmE r[p;15`NEOӆ)fӆq_v]uUMܦr^q! endstream endobj 79 0 obj <>stream xE;0{NAm3}xV_de<]:o rYByG} թK+먗 tN endstream endobj 64 0 obj <>stream x5; D=u*jIEm2JL~׈0 *O Bcx]1$m' ?" endstream endobj 42 0 obj <>stream x330R0P F )\@>L̀,cS$1T0`XJҴC endstream endobj 29 0 obj <>stream xE;0CwN pBT%DMI IhE:_J ~Z0H,ࣾ5h!`3z endstream endobj 72 0 obj <>stream x=10CwNPϩj_ !X0—kI&ʦWrzvZbL5)w,69# endstream endobj 61 0 obj <>stream x=Q9n1 :|gv߆TEjFWSa*/4NN o=/O>CγOSB2!(:OUYl8i=|u]*W/+LJfIѬw %a4XJ}`S6:S,wssaH#* !-|2mqd. Q襚$HyRv`f`Qa#zMk-X Qq!Q~bi endstream endobj 48 0 obj <>stream x330R0P040f F )\ 3, :8HCupiq endstream endobj 36 0 obj <>stream x=;! C{N: 'TocCf,!=p'2jqfL|xp:LVb;B$0-r$CcSa{.:i%Vh;T'bSѡ] \`1J0e=D \ᵏnRQT}Bw4 8X endstream endobj 20 0 obj <>stream xE 1 sU#>")sErW'N8KH2j99jռ]\\zDHzELh2qW㐏٠ .2Ov۞_~/6m&Y endstream endobj 80 0 obj <>stream x=O9@ S#E{@T-#<Ҝ+TpƋ~f"Ҡ&:\ϥ()Z5BlnBQ[U^ a{IDrܻoPZa-L郪2#kk_z?D1> endstream endobj 65 0 obj <>stream x-Q;n0 } XIkI!FTjM;.O[mմow:]iπv1s^gĞ3UVϙ&ߩ TFfcCD$X 4i3THb?Q3Li;اpA,Ɯ Ւ4 e"HC݇ _cX=T2ДHym SIcwI6Ym-}ET7 endstream endobj 43 0 obj <>stream x=0C{NeKH>Ir008lR%B-uIl4Qf^uiEu4iˑ+w endstream endobj 73 0 obj <>stream x330R0P04T546T067S073PH11s,l\!ibY!, Ȝ9\iZ\u) endstream endobj 49 0 obj <>stream xE10w^BNkU|`HN톦SM1HA=d\_$5Y/oJ5<]j$i#ݿ&: endstream endobj 37 0 obj <>stream xMͻ О)\'JƆONC8,V|)>t In"mB/eaL,dכ+Q^M endstream endobj 21 0 obj <>stream xMP9n1 [{6H6f0H2)jOĞİ[FQ=-{$dT  [aaԯ!l* 8ŲH^LFIZ0~3\VjGpYHw$9ʾ/٠Qe`ɍO<5D`YlsF3we~"ݥiY!1xŒJw":)f35r:}jRaZlWϟ{|_[. endstream endobj 81 0 obj <>stream x==C1s'rWuj$j',l> Cf%&c)z%?M=z7] 3G aL,Tr;*!qf6юb^2ynn;HB Xʈf^^ۊn%>stream x=;@ B*_X[ (G]CK' ɳF74q-2oB7J2 endstream endobj 44 0 obj <>stream xMͻ 0О)S'JoV>nNiX4^ OSZdʗT4D6 lI658˘k= ,% endstream endobj 14 0 obj <>stream x330R0P05Pе4R052W07TH12163s`9\&`e9\P9pe9\iZ\&"u endstream endobj 66 0 obj <>stream x5Q9n0 )j <氷Dn.E{Y 3A }r+aS{=!74unT'dHʫV,z©#ADQno-(9iP^^5((ܽJ7 U$v 37$Q9ʰ9H7C!`\T<5}-|l=Z`S endstream endobj 50 0 obj <>stream x-1$1D>E_Pj`&8c!^Fl&*?*=RNYe3 % "A㙣ܯN\-'F3l9!m%]xEQx6A :UyJ/pihw*DPjLfʇz<~b8dluhx yfdĥq[KEijJoi#X>LkaX\m~mV=砢&v'h "Gw&|W~$;H:4/6'8- AMkRX~SM /F}~ 8} endstream endobj 38 0 obj <>stream x-10@NN0bqS}-Q5Y6Z$q8Q.Wx4* "o}3g endstream endobj 22 0 obj <>stream x330R0P02fF & )\C#c@Q*W, endstream endobj 74 0 obj <>stream xMPKN1 Y#|;9 Vp-vU86.#*Y[uR-_\eCq-CLQ-3,+xu[O}w!q84pl^:Վ &TmޔԼDž?䰭aEHA8ȃ9 H8ʍ.<{]k*D+=Ff(B#? M7I5bE̦)2kA5gWypI] endstream endobj 58 0 obj <>stream x5PKn1^WIy&#bam;~_u;8湱a-Od,wl_[XUvF1b#K\WE?]d-sɨ%i|̅O) nS pA"S">oa`u | "ۘNZW'BݑIȴH?15USZ endstream endobj 45 0 obj <>stream x=10CwN JEωĸaS;xf^4H\:=Mvb Y9= endstream endobj 15 0 obj <>stream x5P 1 =<߆qABIyt.[]om[bNkO0"{M]Bŗ r5Y66jg15Q2X<KWl& >^ӱu'<(5p%dz%J`3-%:9Q> 0 Lbd&q>stream xEP91 TI&m:3)lɈCf <*9! ÖP mLyY:_`@o|qLAlI4PnVV[Ʊr0dYO!+P/:==+wFqR +ְ,V+=\_&8 endstream endobj 51 0 obj <>stream x330R0P044& F )\ 3 &fYF,cC*`iE9psҴy endstream endobj 23 0 obj <>stream x5;1#ӏjAV!cRӔ?RY*]R~D*'JVJzH[r&yL"2v_=g=⾧uALGqTY\ܮDi7A1h]=L4a=k&/*zLuL=. 4:18s4 [)8ҷH<[ucغ9cוij'SQIs^Ec.m msYA/ "ncaƵfR,fw( w·=KK(XC#c;7, {tOz}=m{ endstream endobj 32 0 obj <> endobj 88 0 obj <> endobj 10 0 obj <> endobj 89 0 obj <> endobj 8 0 obj <> endobj 90 0 obj <> endobj 91 0 obj <>stream x]n w7Ir"E^ /@91A\n7M҇m$45M7e%P>'=-&eZ~j..}g{-oNhꍑzd穸t#5,(%ļh Z ` k zBe(Yz3 `O# CuF:Q{f (P"3uc9^s>/FontMatrix[0.001 0 0 0.001 0 0]/FontBBox[-557 -374 718 1058]/FirstChar 1/LastChar 14/Widths[ 602 602 602 602 602 602 602 602 602 602 602 602 602 602] /Subtype/Type3>> endobj 92 0 obj <> endobj 93 0 obj <>stream x]M @+MlҰ.4FaQ .X.y3o8]&k"&"ƪۃhXŪaGeë(y–WQO ݹ4?99=lURoq|v$i\G endstream endobj 39 0 obj <>/FontMatrix[0.001 0 0 0.001 0 0]/FontBBox[-182 -235 1287 928]/FirstChar 1/LastChar 5/Widths[ 295 748 770 632 685] /Subtype/Type3>> endobj 94 0 obj <> endobj 95 0 obj <>stream x]An0нOxfDR1`pnhP,QYo`lRGj/^;oӯv:OzPt[szZ ގ?OhnsƩgz^zhOYbey, gP5"EQRPrB9Ԉ SH(O5"P5"CR#RPN5"5"=j5"F$I@DR*iFV7V7+uқ(*][UMJݪfԭJoY[l(ݪ&ԭJofWnUzVQUË5^s J0Z/ln5z 04ҭ2Z/jṷFobZ/tk8XA)[nwkOyx csz r0`׵aW9p` endstream endobj 24 0 obj <>/FontMatrix[0.001 0 0 0.001 0 0]/FontBBox[-4 -235 606 928]/FirstChar 1/LastChar 51/Widths[ 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602 602] /Subtype/Type3>> endobj 96 0 obj <> endobj 12 0 obj <> endobj 97 0 obj <> endobj 98 0 obj <>stream x]O10 ]Z Ѕj8(Nߗ,N>˶uGֱ4%"@cN`Bwޟ@nR6jˠ745$jjkAl=0é Yhp\b$Nh) 8/ S% endstream endobj 26 0 obj <>/FontMatrix[0.001 0 0 0.001 0 0]/FontBBox[-18 -235 606 928]/FirstChar 1/LastChar 1/Widths[ 602] /Subtype/Type3>> endobj 99 0 obj <> endobj 33 0 obj <> endobj 84 0 obj <>stream xeUkTSW!&\%ܴGjZ^!!! $!$G@ Bx"`oemQLikK3]?wuyo61mY&oBMrqMjt:fP̍(u*kj;k>yv(afɗ`Ot ]PUqZs%K͕+W D2$bp)U(er{µnT.K<(##3cn43G^"(|a·-{ug BH.q hdi,_1 gϘ  ÞŚW:,[6b X"{ۍaa+mƸtXCAQA*f}Ξb'F 7 $zT]Zmb?ǟg0|LNշΣX0}$Ha[MF`Raeš.XH*pC=*FL[KNXE2X[QH{YbCB m"3*ǕR\)G O5ƿ&;mopV{1bY{E;s<ՀW*4Aqp.ކ7J~Pq9C_XKaM_{B& ZEu=awOis?s(ZͰ0 f*^CB6Zɭb8feEnֈ7H98<2]8> %^ _3U N\u]"gΎmsh劉\]+HHxK=a0d|gFp(CҺEIE5b0, m֞4Vhy ƿK!W)N&U u$8p h=7R7>C?=W|Kw\zL]9wsob,RxDR@LhRTAkDK_3C-#}᧞-S"m ,zqLGѱNl|<,*\QדmHnNvUCC 8@Unm)#Qu{A;t8KKP7CN,ނ>*}.dec7 -cR񁂨MdwZGsCYX~͠ë́RZEFmn:@9jkj|GE_WV؁rR0r?|*H>eKݲAo@7=Dg|Cʬz ݎ.1p(|s?eqq m`M>4%,m4U*Fe3;+PZS[@R/~|?H[^FU@+#3*d4M[jt<%Vޅvfj 7j6Uֺk%%vS5yFR <#61<3={>D xz<0*Ҽ =>E4\H K> w6M8Fb :Y]ŝyAhImj.`4dEpuz% u8_1mx9MAGa(-[=t˄9nF:ue7 xmMzܠL)Dυ>og9N(=9M2RYQ ڗ4Ԍmh'$2ZX1 |uՓ5x: 5m7wDSA憮:>g]!904G^-JDHkv pKmݭ.;M"ѡf΂!0z `z^K2qE:l5)5o4RkW5&[lG=䳸Ok=QC )(r#Rj K!Lbȷ` ΁G8`L1cY-=jErDޜ@_oȗNpo=_z%D'ٝ`Κ /u endstream endobj 11 0 obj <> endobj 85 0 obj <>stream xuy XS׺!ٻ֡#؄ZV ΊS+ZADA 󐄌0-$$! 0((Zgmci9צ? sIkx[a.+HKOYmڝA/FAxN`JT3gL0åfƕN͆` Iɒt%/]}#Biщo Iɢ  4'"O8 O{+W-}~D&S A{:ə,Xʴ]\wx1^[ 7f-ϝgww{Ɇ7Yt޺c b9:L|H DqI'!|]"M"${bŸxXC,!kD.q!#}vbD' OƒӉyF`4b31`[VxX@!D ! 8Qb.#KF\U33.\NV*d*yM}itjee33,YY3g__ {9Qs&]\?ͽޚ>vr{wW !?;=揺wt/por\pdW.C6.u܍L߁۹HyLs_ = }.1y_kSve(1EY&Я9vQsyYltbR)a ɲ4We|meɆ Tin@%͐BͬYtJ|J_u0$:eʜ"mFjA$k`ja9٘_*B6*rmh YT$Oˁ䔨iPYYiq7O] mKTS)~י̀j6ʂ~*y`>%162TV)I:Y[ Q$ | M'ldp>¶݂'$X3PߣY-GLu3:P+~ۢ2 IՒo]9.80+:Blм'+ de[z 4'(G>WX@$F#/6ja+(n.y1yZ3BZCСկog ~@ձN%آ|*R:#;f'2ӱK6g1'\ ǙwA$T*6';2ܥ}=fR&KP6]Bby%NMEr?KuW^LQ=k=azHq0(|Wۜt 'E>wkz:')0,Oh5%W|PyRc8 e%MFeiM}C'K"rT..5M0$@jMa˅ʠ߃\I:H؜@@!KY6 YOm+6O.e$^hZfB}\7+t@t{4WH> XGwo=Uߟ)L:}赻XgA%=f=eŸ\,@EG'd^I4FW&ˋP=Fu$#ۓhiz½$dFVIRՉ Ά~tH[07:$f-i@̑7P&-JmT!KJ 1Q:BtC<k!yxH.WX{Sr"JqI5n4u$b[&kio)\)&{  QkrKYh=G}$'?rɱ1-ENT%@uS܍g_ Np2UZ摜b|LUdW\z`.ꭃa„Hmɡm=rD!fV#~ݭgѹ !͠߆ܐ-?p%WQxWٹ-К DH0) \Ġ=os͏;{>ɲvwmfCoJ( bCB څ{?EヘUL:6g|1$wpϯgǞ<>4.@@#֭?\ JdSZU*Zf?u$$2#Y\Bzc7"%x]Pe%+r E"/ -_)@H6e9[2?G0 >Ǻ73~)s)^!ždo뭱)*@٫?"L ˍ.@ynv۩S ބpv찶9ef;LG0<LCWڻ`Pޛr|xmr*6 zI ɝ$XޢyQe7dV)ti2# :,yqIC+~#&n;Jf2!OWhUp),T52\!M=&tgCU d3S?ǟc!_xis:cqaB#AFW: \`>4֤7͂JYkT##X-.`ъb8[+kf4߁ُtm&Le(%RbJqBD"%*@ȬPd8a? hb2%vݴVt47(RDx6:H sRL>5[֊/SXJ`ʂ9!snιtlyPfxX]VTy?{?'D%졂\[>{ddon1d73|Z0|Z-pE&U&7ع0֊%L:-(^cK^8 H8 <pNWHprgaxq~oSN+hs4Hc!JŅBs#tӽg; sfTQ<3]g;vwY2*J,Fg2xUJ嚜BCLnrzzRRmzsK]mKsz]"ּ :\>_8 Lv~J%ŰටtXݏ0i\bL$B"F4De }y8+HnE1Z6^\aodo__G/sk']xkJSv=v8FB 3j4f՟VnruܪKxOW=¿<%?Jnu WicAoSVPT=}MM!')-stXSrI<ȀC, {*s'W܂.?GB6ԡiT=[ 7&h3]uv+%]#iBEgv*sZ-OtLL>{FB8]65u:_UAZ`F͆.nedoA=@NKz΅y-Vy_`1`r1uM0)Bزx;Xa#`Ň>$@K J trN R D;L`?^KFZRk L6tL+29͑˕{ţ=Hebo6_<v?4+` G&&k+3b,qyDfC&l;@p}]t՟N3'b2mum n]hYFvjL 2m*yJ孃j͆QF9LFW bX/YBxK5Th&>(,w푑u@~Uz\-kx 5T|(3VA]OANObܘ丝H!!'Fe#}J&p(FwI#.]yK>wAopre P,<">f?ۂ}Yu5Ң"XT TS{mC$ZO{,2#K (NpၚWN^| vB^N2M !a).p05ժMt0&9[p1|A $lMRO2yh&:`l Vgkhqk8MllJ_xb6zqm @Ve0 y_b &-RUJYr/iP ,j1VPh;=ZCl%Pk 2F&),z>A-DG;ήW2?>_~kѕ;O!BwQv1F̠]$()7 uCU]^B[ϩ%6үXVQldO!&_nߔd#SJD%jLJ$~fCئC $=}$P9]3n?Yay%# ~ӜKPƜpd%,3pv}< B̐^5fEtF;X> 2)$4}C<}aYNmS33sF!&/r:7txiiZǼ,o(<'}'0g\Ȯ%:CW,S (H]T@!?_@2}` lMYRCH_n¹(WF=xz̘pdE ա5Ι3>-dj|$_ TTV^SmX,Eg4H Uj@Xm2sAxB_R[;l7 z3hd2")M*JPjy$7J`j+d,eD)0ŕ%dJAFֈ+㺳ـ˲S9Mڮ0kxМR%H2JcJQVVn0 e]NG+& k K(<9"25>& W5R(qy4vb5)ov؄5m.a5;&FP][l$؅y: Wq}^8y\bƤ 85unX/+1P^'EMNǡ;'i)3ϊcDGҍ^foCWFϰə ?"A$ppCf'.FO\FѩɎJik"y:>f"f4q}`M{B&NTxws~RSR[ZRESTsοܱɂ f C&. \}?CqlLE ,L!S;Ρ+ Zq?~$'\?BˏNҨ߃%у=ag.3`^H8+kMP}zP$ xݰ s2 '-τ]c$Rܸao_NPz2h% G]ɺYvQw+#%͒&퍢Z׏wϙpoYɒeҒjCU)5FYD\nzv,G^8NQO8h{ΟYU8Al4 ZuL: UE)rJˆᎯ{Y ǣx鎚<^ߺM+֭]ȗ"7{[R+[)[gO} ޚ%NSfvI(yQRRmsaTݬԁ;^HNN)҂n+ޓ{np9{\à`[r>J ߷1Cw=i4^7ĶZqE7շGz|w¤Q,%C[>oӓ0hYtjP$JN)lpO n DXxY4Ҙq6㤮i7U//5_kwn3UϘI6P~ endstream endobj 9 0 obj <> endobj 86 0 obj <>stream x}V{Tb 'PIB bVף*U.p $HHH /pHVZ]ji/ۺug^wξO涳쟜}.yX"bJIJzd9s `Ql$Wla|a _g`l+ֱWSRD!]flغuHFT+O:BVJ3 , { cbh mbX(vۃc$慱0_E,b<%l1+ձpV mˋ.;=T9|SD%?Z*{?yT9JF=ЛMeQ$Z匜n2-064Q^xX`ზzg߁TVM>nLޱ,7X+@eET6L)]=!ۆg/64T4pPܹS((T&wQs}1H$KLq&B K hAu]CC={`t4ΪS8hcO*n X?5B |9rl*HYbf?9em-1 kLt+ebcpQh%&.yaϧ3B=*bjJI"^P z廕Dg'Z" r=mAQ+065K.0Ny};N73(fglݬߎ鄨{(]ϝ71ƕV1 Т"$Qg!v[''7HPZg(gـ܀P drFÍ=,*.%+r@2h/q!` ib[4!(j \On Q+EVA-JUQW@*~- 5Owp+i&A (_f8@ ~.5O߰v[+io cZ`~Sz\|"+ qEcB_Qxu wM$zA|fWih 8ht#ův5 eb E9@6^-N5K&H<G%;0UM"7bc| ^64YFSޜ(hWBǤ'JHC_*M=\rd~FNqw5^U7\+oN vuI[,)M#Yu_ͯ~x M_z9$;36>l>< WOcH/t奉3C^G;]v!o e"'ڥ夜<{ɷ47P=>0(/-(=e2&1&CÛL~ti@:̌'{V'醲nôޜ䑐TNK]΁nSСomDfY56LBh-gTW$Ӻ+jvZ$-g#G h¿1O8x p7%ŅE)I37F4P*!![<}{G dOtȣz3>.@aaWhx|を3d77/g fE3M4^V*M #ҬwbʛCL .lj m0_a -$o\%qUrR<2< 9qaaiȦ40r2Jb }~o|v>%Uv.Nl0 9)M:^|Nt;R]$Ȣ62NR`n}5Cȁ)@L:t05uRλ 'xwz2N,+Ghsϧ V% jRm񂑌>ΑהF5~WBv[-Gca4.Yz1Ο_5w$w ?rAӥS>p9]7:F]7hmT 8n/(v}|S endstream endobj 13 0 obj <> endobj 87 0 obj <>stream xeVyT%$fjQֺ**PQAHlLr $ ;(BE`i]֞g_w^{c~{=3޹\6q`0bIyҭy&efm,LD>-bԌ ԫL4?}֫X|ݤ &ΘhK PUw͓ 99I;Ο-_\tPѺL8[&Ew<4SVR-ExŽ 7T#o K(#]Fe[sQe:lѯf{ !8)jMׄӨcE`LO~ψo 6DXv 0አHK8|f64,d(2i SŒ{ޡQsbp㫗G.W7$#4(y'[}`# {%==:{8>~Pt!r+!h*x9PY u Do61JעG%;hܯ8A h޺+c:#)v-(ĹUZuSЉCBn Zۃ*3bE BWֶV{dz*.A_c Ssxl\6k9/X` (iAޒ@Nhhו5΂*΁uH$~vp8.N\v15-*b:|6NݒGy=0mhxv#?MxUWwMh'e\N ?ͻ(-GV\'Ldp1w<\)%R"+'S4KE1oLJt]rͬE h@p$z<raR/ Mxw"l/i!}Ֆwa}H 4"`JSw;fI}xMxe/}Hth{̾v{rxVԨ S}B5 0v> B:줍(3mB^X_Лպ{wFl4xt>=FN՞q0-=A柇RҵFo1J8G ǫv݁GݍPsy[$^yݡL̸l bz^7g߇o}ﳇZ$=-*oAڳ?tUvU󆪽'oCO80|lP4d8Ck,dùKC-Y{o­cS{/ЂwCYְ3B`fL,ԥ3Z&v͞ԏré KslQ#]&IB&%T;DX?}M67 aIgXYfY=Rt@g+0Rg-B?EUG>;E7U}/Q~E ZM˹Y{'VV[u":&ntŒ-rMf؝$>^Z&I&9񢰦LW. LVF#u M&,l"b.5hKMW v\~qk i7aK:"D)Xl:Sb՝!d])<{lgKz;􊰰/vm|n(S(n(6|N 7JsVG#RP5q>`';58mSrc `9pi~ t%-Isp{L4B4JY5zE xv 0r2fPi}11n3 3fMSiմ|>aOp Χnm}%BW蓐EC:@>k"R`dwut8]{܈ឦ2VkYR9^_?W [-$icS"_/>"LꁂCvTx\ȭB+׼B7|Kd)l;sد' .t'!m]t J R,/[YweVxkG1X,wE*hݹl@nG@=]$޺fbEI>6(˖i&NsEk,\DrTd{ >J;Ϥ1墩HODؼ$4xٱSm mvMM$SV ՚S]k|Uڠטm#|b.֫/q0b-Fe]\fwvdi[7n1B&,AȤ!ȧS6̏7nnPМ.QBp_8Δ@T/4 endstream endobj 100 0 obj <>stream UnknownApplication Untitled endstream endobj 2 0 obj <>endobj xref 0 101 0000000000 65535 f 0000012363 00000 n 0000050001 00000 n 0000012297 00000 n 0000011975 00000 n 0000000015 00000 n 0000007581 00000 n 0000012429 00000 n 0000025955 00000 n 0000041298 00000 n 0000025093 00000 n 0000033511 00000 n 0000029945 00000 n 0000044867 00000 n 0000021839 00000 n 0000023663 00000 n 0000013827 00000 n 0000015397 00000 n 0000016617 00000 n 0000018134 00000 n 0000019709 00000 n 0000021013 00000 n 0000022812 00000 n 0000024337 00000 n 0000028452 00000 n 0000014917 00000 n 0000030602 00000 n 0000015932 00000 n 0000017449 00000 n 0000018719 00000 n 0000017312 00000 n 0000026730 00000 n 0000024739 00000 n 0000030863 00000 n 0000015825 00000 n 0000017990 00000 n 0000019478 00000 n 0000020865 00000 n 0000022655 00000 n 0000027556 00000 n 0000015289 00000 n 0000016484 00000 n 0000018575 00000 n 0000020414 00000 n 0000021688 00000 n 0000023518 00000 n 0000013157 00000 n 0000014760 00000 n 0000019348 00000 n 0000020706 00000 n 0000022247 00000 n 0000024194 00000 n 0000013528 00000 n 0000012470 00000 n 0000012500 00000 n 0000012135 00000 n 0000007601 00000 n 0000011954 00000 n 0000023229 00000 n 0000012848 00000 n 0000014457 00000 n 0000019025 00000 n 0000021545 00000 n 0000017228 00000 n 0000018435 00000 n 0000020113 00000 n 0000021965 00000 n 0000023964 00000 n 0000013387 00000 n 0000015053 00000 n 0000016166 00000 n 0000017681 00000 n 0000018869 00000 n 0000020569 00000 n 0000022921 00000 n 0000012711 00000 n 0000014231 00000 n 0000015597 00000 n 0000016820 00000 n 0000018290 00000 n 0000019898 00000 n 0000021327 00000 n 0000012607 00000 n 0000012637 00000 n 0000031136 00000 n 0000034060 00000 n 0000041630 00000 n 0000045180 00000 n 0000024968 00000 n 0000025546 00000 n 0000026234 00000 n 0000026425 00000 n 0000027171 00000 n 0000027306 00000 n 0000027834 00000 n 0000027915 00000 n 0000029556 00000 n 0000030210 00000 n 0000030374 00000 n 0000030806 00000 n 0000048630 00000 n trailer << /Size 101 /Root 1 0 R /Info 2 0 R /ID [<199E51D107F4202C1B92897A48B374D5><199E51D107F4202C1B92897A48B374D5>] >> startxref 50128 %%EOF kst-2.0.3/devel-docs/Kst2Specs/Grids and Layout.pdf000644 001750 001750 00000070764 11544160206 022300 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream x[M4 ϯs;%W삦`@Kn d/%ْvU쾄B3.[֣Gg?o> ~O_9߯}X.ɁL '𧯿|`Y:+\i=Ou[1}Iحnkx#>ֿ|F;_ Hvr'788WP4vp19I s@ {[?[7( qȍz 26Jj J:A.=^3+hgˆ*AؼX,OzQ{BpZpKe,_mp2 OE .Xpъv>vUJ]݊=FXgiaNoพ5h~)I)pd:q۰6[3e:׵K=$?ЛYAH7mHapEc4L޻gFCQR_ll25$~Fo~Z1MݜQ9vG70sRTFS~J^;!GFYNy3rো6ڤ#n}x.;#=G'ۢ񥈋~q""=ʮ3W&GoFx)'mMAu۠xZPQb@<́ 4e߂"д-J3.==&Yl udRƌDϗZs4RL;D8Tu~$@49,hf5mk"Q nIjܽbX~$+rP(~K|3jJPЇ(=ti2HK.%2#Ũ<1EZW<>q rStx^%#ƕ6Ùc.؇WL 'bɰzN*6O*#2rJ(bCi?M,i Pҁk;d ZeD@-Y)MNB]T6cy9 TB4gf]h!'"Ns,t+UlD징k!>2jɓce< CHٌu ?Z)L$n Ž_&4GX,Cx =:¶G!7AS=(t?ǽr+CKC\(6 y>i#_)]w:3[֢QF?^g#p7̳3 X,+j<2HAp)f%r%BT)I / `/W`|Jp.wTt]XU=$I\Д,#!"n Zv"Ts,uyHmP9 )@UBDhWEiy7b%_ctkPIӑވ\.ujƷ$[ '_n9UYvʄw+o]6'K#<`")猖 F/34,GnCvaJ+!b>c] + Zef !XNc - vQD{٘Nho#^B0r:ɽ;yݪJ"J,J:3g6KQ {_8 kExSnFzBmiˍ#j܁T8(jT )C1tvuM#B?(TܥKz咪 I]҉2*U܂s`'fckۛV.ejq` 8S킏@etu~<"\|-0AqeEh 8TjY nO479%4uB# am㔎/dM{K:SՃN6YΗɗ9hT#<tk|q/[5>9;hQ21|`Y5D۸V?YoJd=MŦZ_sRSd"T^.ͫ};OXk唞cbv wjkɞIZg0\HZ/m;<(J.]zd|oK]rۥe:#CYB>9&PdX@=7r4-c兮v/s^>.N%4{D >4*$OahlȖS(C=;P}foVضŊ#RATqH.;+C@u& dޱfqP߻DoՉHRSW\)3T; [Mw-Dj؎pvSƒ Z .GuA5G=μR!+͹uGY4 @&fPp]lA:Bu*T9M=] :1~ nV ː>O-SNOC,@/j0j>[F`EqD}H7z.6ր]y'k}U7t\ Ng endstream endobj 3 0 obj 2624 endobj 5 0 obj <> stream x| xTչZ{=Ǟg Iv$& L"IId$ׄ$!A(QGPh5Ӫؗ|="lޓ{wwNk֞  @z9z/t;!>;z-BD掎ݳÏw=$!}&wDܧg؃2:{[Z^{xD'{m_'x> 7ó ^@BDwK,*M4n9 g>s4Z`4-Vfw8]O✤)5-=#3+;'7ow6I\Q BntlE^G/yG@'q.qCbXjez #è8Nlk4:N 5ZدEϢw(~ mCPzJ- ok28R,`?\@ZH;^r8Y ;QW6*| 7q|6>t(7qt G'# %/kjLX݆`u+)jP FCCumI#$sՁquZ:{٣$jqT?nN^TO֏ sInLߛ]UNIe>4WṾvjQZWU6r<*8=yOO,tRmv] O2ɅsB-;YV_^0Ռ`V%Cg ''\8#^ LUu!K,\"ņ7¢iոz q| g,lGl/؄%ŶTW:0^j+v/[r ]q|OM]4O\ Y,N ֌vȨ9n!x԰WDksבm^{=l sg&Μ<#B,9{6d+OlOO!q* s1pI[.`}uVz>4ǝ?vToݱH_^qW^{b> DΗ\H0fC߰5]=ּ9"0`3&'E`/-٥$_$&zɽz3Q짺 -8= \6-|ÇF^X?0wZwҽmbZ~{)Um<ח;6$CFD]mZ M'-cpJmBp,r"yQ][ <>>G|Opܾ8_ HsX8mf`[:/fYK[u.A36>Wg])\Be\zs;4.#uɘ%IK&c$n-tDvu3fߛݒ'MIyV]*gEy⹉g&iԿ۝ŕBLkE˟`eקbѷ.;%[NNN````ސAڐ!m]]Ү]iL;~,t,Xڱ$ss>zXc%|_HlD'Z\UqAGq.UyNw N.&=-+[6=s_>t[`txk?ڸyޯ}̛QGy7]Q#Cs}4fҌQ׎'W;ܤlp7f2br"}8p|$'|1N?3|ke\$L7 |6Ƞ/-Φ1N}yԊ[x/xlSX9s̅%43mH<[$<,yGMr?ܞ8M)>ʜ`V ,*aȽ=*?XpÛX/w=\i{_bPdd;=Qfr؋+ Ҋ.P'.L3 10 p) eN>ŏh}Dh/͋.ShmhTbٽ.d9C^5l@g>=Jӷ`Ϙ(dĠx\#['+[(n?y;s=]]M.B/w\/O\e 6:.ҢkOKeo(L)~w'LxɁ{Nay4G `Vٻo},MMOϟ)p }ZzW/{xJjŋ4t?7vv)`3h}Һ0Cs͢iԩ;dћ>w-Vm޿£]T'O>rp-\GQ!5eBb' ;:p7[7 ­dQTȽZ^_qP9"`OsW!ȗP}6vf nKNk4q:p>jDR\nWK\vj]-u.O9&\d9jz$83U?iEݟٹivyTӛ1. Jd< TmYj[ֹQv;,Nsz7kB$zccvY<d3M9lK5K̲&zKe\)YjRe]֓ h^kYcmv7'4{pE:NS'nA7ɍ%jQ[Թ5L &B{{{M{{,\vyv%^OAc+]M$1>}\sG=pܭ\- R%{?ݭ-RȊѤCZ~ afҡyyd4ǚJ<y4itGvqrAxyvm'\gmH%|Cֵwm{;cٛ<{ΖMM'c^5SoA㲢MEᢻƋ:xW}GXWMqoƟ*oW?>0ժ%c2w%#Nsey(p1np͟6%۷#v=[#^WV-!GN/F$PӒG%^OtPFi=P-$e 3'آgg‰fc;_(.N'g/Q[ROt>^ȉ(p˥cQȗ,ƙ>Ν8C%nˆ7|F{J|@1g6KZ-LhA_?6@߆ϡ.zƌԠO8}k(On׾[wz'p| _UP(ynFy5t_b ds fbM邺5 .eYGp4zN i7~IIFuj3;3 ٟY xo]a}묇ENu'gw-EuJ;UG8fsSa]p 0hln݆7N-xIGd/=SpTs$= L*_]J~>?&,k"MXz.έX=,]5׽Z.[im֭v:θam'u^ J0 fY4VԺzatfExW;Gc1fYr U:\wA|||KX(u-KW*Jz::ZkPΚo[Ag%q~aqTbbrpK RM.V_m>ڊk/^8O={Rx~軀 FM]~b/`pz>'z-9|@$j-ڠ6L\`s)ڧz44nÈnC/!  ؛+# a#e0 PI{Ȝ s;翽|.sўӂNJ zNP-i/pZ1kȤ'M9,f( [\\9[*ϭF:u[6V|һ p|<=4P\VWaruZ!aXEnjjFK'Ȭp ^!!Ex QckIXha&el\),:2~Y8:+6ڼl~yn]Fv^t-n_)3>*5f DA_u GPķ̱Bo:=:Ղu6tuxXrq1K%LZ8mmZP!dɘ%6.qw~'/v@7w!r6`mLB0._BY5ynTsH? &QZPؗm@<aRX̂̅i5p^]b;xQ~ HW r⃾Ih2r̙E!ѷl'rZf BNh2 g!V=6 '}ݾN"jLw ~[yidvåp)F%5fXqK%ce5cdZ: uz֨5,:kJn'N(Kʂ"|9R]M6-0Wj\-'U|qҕx\ϯ37]od$nmorlrnr rAwv}n Nketr2$ 4⍶g3};T5MkG\xnzoǏ?r{>}RkEлwdn}sӵ84(Z-C7Ρvq^T1e//o/sWϣ_l` y9)rȎ]hG@=U6NʦDr!Qy,Bݨ40M:‡5bc/x f8Œ3'gQ;9s$sM9͵k !?b"\|[9w8=;mG$ǟ&u g| ۡC`#jSQ eOJ5tƣ19 UݝT9,}3kڎ ܱCWzK7N&(2۾~ã=㛊{ݻ5 }gE8?8DocM`t[2¾LY|[-v #K&idYGی[ ֔.,)]Xˎ kk u^JF4hºV9=@6-RMEJ8YT3-~aFMO/>b]ZΝ ld^ˡ!L ^g>6?8x{ˣ`їI4I[jSFϢv t-m&"a--b!)p8o[Q_KX{]yRxnV8_ϵ;#B=,ziV6x?5J|9?ĝ@o\ih+ .Gzn "7w%#ϚfDsN{LtxC1Û?5图cW2s)Ӳ2fA|^[m窦Uňi6I rgÜJP1TFuøC [ձţX auMul_cށJ51F91 ꘇ/ձ :֠B[kQJ1ul6^Rf{p@3*JER눴<D^Tז/H *"5#`  Fj@!=A$(]U:]f+RtpNӧhQAp~kl!-6$el0H$ E> ҍmW%߈pk u6`BF;R{<N'UQ\@H-zR 6PO0"Plni`@80dh!-: 2fmJd8 FސJ(x 'Π4 R$ic;ý@>8lc ,E^)2lE==a*P[/rDQ65<d2(Xrp Qf]}@Y"~5  IY3@Kё`ؚzÁP{:' @x80R`$MKm$Bw8\NI񺀢4ϕ{b|LczF,Wq "T6 6ivlAJ* SFMk;P¡)ւ[7 2tR?}}< Tf4E/l$C/,1u;@4ǾT5$.`2ӮRZ]$5jZ[P)U7J +*+FxNJkV^$DCY]ziuTV^ZU]W*7T66JJ+YSQ]BZV7I5յMi5۪lj+Wc^eR}YCSu~MCJQhJem%Wׯo^ `+55UT֖5RW .TL77,W7565TRXukU5UW(ek*@ZTQV[qSřVݰ+5WW豺AA5u׭ d$@2qįq) MSnJe Ս.'2}RթRѹz@ݪe5X_[ڂQj+I%T%z*xE2dž_)YnvU0M#P$ B&Д1Ie8a7ֿ)(șbsvP c@ R$ FՒ<%T. 释 kP_{xW-(KRCQ?A(n'a*\AG[a Z0Q "?E^F}2pESA3Y<jf~5Q0W1S A9@OW=wW+䧣( 7a. LW[?g932|eQn) g8{ z '[ u0J}rIq6Ay9/-̸cJ! X'PiS5e\PZaF[=B+ vޗ')îto#6WCgJ+1èٍb8M?FNL? A47&A\+FjS2QNt G5fJ?07n3Cǽ̞1[T+ϑ;%g`=SCVg[iNʣyݴDL_B,Agb4N5m 3ӏafBmvqR9]4MN?` 1myiZ }U#"2 6/Zf~ZfMHM)f%g 0/ Z0#v (hSLˢ0b:(Q5)3 T}AgbRf}34pTNun`F.3/R|8FrET.0N_t.Ǖx6aB_ d|Lye,n."A5gi~I`ӮPӦ|U޴˘ uL*XWdd(P8*{=Ц+&ԤBzT R]fVVi,.>(72kM0lScxca5L2ՌrFHY30*L_n FiİͶΕ#FaiA7+zjFj&k[On9Z:ZTl)OKXL[>Cg֯S[>e>,+TuX֪a1;QsgW `Tr8/;*ƵOt*Ϯ3;uf/ꝑsgvJ6^`{/UR@3{/z'ӝpQrrV XϮ􄑩.E#NeNwt f""٠r\Jg6R]~bg_2QK t~Se/AL/wz 1 2_;biP ˬ>}"ty_Ju1j0/ 條W͜v~L~ Ld+>~"l&/- /fS ȳF9t[pH&xPD[2w9};rߛI|P8 {vd2dI|]r)~,M{yQF`o{3^qFg;d o$=מLrnp[2SKn w ɭnrAr2# M,MEdܸ* [d -2<$ aH"sH6EID&2o6ˤL}|x]*uޥ$gm"> Hv'gL:;6 ϐ|G{бtLy6i_&-l'7dL\l N&ke Y#ipHjP2rRc$HuN>HVDV8HTr2T;nR\dyQX.2^(3eR~\)\,Yl8@څEIBPj' md̗IND&W; ;HUz@\'Ba)w l]$?O$޹N!:\HnN[FrB ld-"x!s#H $IOӑT)^HH Rl$el >>)̱ I(<$&x8Er:W7q:I> v?Cl^LDˉ$X M21ƒѷưD :'ڈF(4ۈ"2~FdO}xm_B H endstream endobj 6 0 obj 11743 endobj 7 0 obj <> endobj 8 0 obj <> stream x]n0E .E qJCcǀi:Y]5%޹J tapGfaNlN9st'VL?tgwi$uv?U{9ú[ ?_C\n]M4)ykť0cʿѵJ7: ?deYvM|^Q2x~!hEY'pN.r-RY2pxy~~b\s߀d녬57W\_kf`Kf` \^Kj ^ke_֧_З]_Ձ5z/p^_".|%ޏ_Ћпп,W_(??\ZNRgk> endobj 10 0 obj <> stream xz xT{^dIH 01 Ʉd$DL H2)&(ZE5RE+葪,SlV~)U/lg2hwwo_vȀF>_FBgb#opwh}kNٻ7}_PZOe=PV؟Oj-m0<;}#>8d> FWY8cY*F&`gj+=#3+[͛al#Y>gztl|Cmm@7]3XAg3;s;+,Mh:@ius۸n셕#{\{dT§uT}1to24aFhẁ}Q#\dwAs'0B1]Z{*noBSؿXMb@,>3u"`;2n&_G/P}0oFOoq9 ݤ6LĔAWHv(נBv0ˠ"Q8uZ#՞3hTqt_ri η3|q.?ïpnъ5w5 VXkYC2eX%~-Ð1pg,X>76 ΍,9KN7#8}ciªB+Ue`,T1Xvߞfef5`TNcpi. N 񋋖'IdL1Zk{K^yE"7;|'Xҏ:EfafzO̡73L`=U}$o,׃SjO>Jh67XGR [jF0҄KdK.^tK酖R1Ut5nu T %rX9eD̝oR5GD#,w͓nʤWy^9屟7jej*;#ZIOh##aĄVf.Tc R%c_z:>q'Ϭ]3;쪼&+U`s灉3[Wz<<P3ȒtY#qr 3$ʍ%Nw.҅ cľ~J_{&ʯ) y• El : 8.~c_`q{04B`.3^~왏?>رخULCʘ ]s˷ mn&&JwunX31̣=[c 枛ͻ~W/9BS䲫NGtVfF#\oX2c-]*ʂr_p_@< xIQ*U+Zf+^kYpm %geɹ(HI-I۟{];7vA[[Ļ[+R^ i"pu^ƛ{fY csMw"k~~-.hKuRCcY+FG1zb_"BL>l)QȚ,HKe;3PFNG LS)flzA0NTzlZ;XIgf:S6Y*Ҕ\L\y4[NccN )zn+";7jL؆l؎riN`#%ߖo/+iڴ[--- + .SY1[0TY>һ#.ۄf ҼdL0v|2Б e\y,6GFS4Oں4p||$n|%oX7mMנKc\WI>$&fdh5S(RtYzD p,lh; 1#8uy 'Xn׺;E[8,JgXq\zDF (8/x:;%iuA# KKJk6vf7ΉM1Ǐ@x2:AF8VxȸRGRFׂ.3N!4~A8} L2Q0a62R!ۘvk`^ .+ǡ0Lfz^"_}t^z!61Ƈw~QT"UzrB N J\\Aic6Kcq1d2!rf\T觞[Zfi4jGJgժtxlݦRsNy9aβMS7x -$K*NCTLZ_ĝ.YwYTkcrhxNݖm/P lm&W}k@EٶJ!C(.&#nv<c׏NSҼ R|h#Eg➘ggj\~O #F4K4ݮa{(S%ZUӝI2=Tg 'gOfqhT5ՌjGugYYYYY\h4g2|CqD,"\pM9W1=(qkc[h~mMPܣ+2N*$?~O+@D }}n!K=:C8.?#һ9EZy+ c ϳc'۹362A6:}-^G*1x"*h ¹3 1F[9`ʙx4#OL਄XD@:Yu#;#mZ戉)C9ZZ0#RQPq4$lpCE=5IT(3K.{W&CfeJ?iVx3zoO,xW4Ȏݱ]?~foFE()<#La;6y{-SgfU,Q璢\& 4 edhtYbi[DuFii}Jr~${0IMT9o~d޻䆉wSusN~Xr+&R,Kѷ7i^~i2bȋ5x]-=.iwP_p#8wR2s߷'>Kwm['l@֫{c>6$嫌yϐ K3춴m2*.gF^+$I6}q]̟չsO0O#f!/^9)Joܽ@z ͦm֪qVXQ>7ER%n8G,InE`0HQ޿aī|yBZ-c0/3arICA֕ifm/Űxdch22&蘳"6eM=s-ynIbd3k1bPG0 fѠiffU倴*HT\.O^2Am$eBMgSLj¶4*VcHCikҵN}IH)` 3MyBԲxiٓʬ1`jJIb:AaGwOGcO? R&Y= WkͱFŇ193W2e&* !nxj{HCԴp|Z=fѴ͉Wolv\3)U٤#ԌA7lBYj,AF((/! hŜ(d;Iq49zT!.Ր!ZNQ=jmte]&ne~:F}x,v0`|iLfz;&NMS^ \ewBD Tz`4Zo4ft X*̎9tD۬qfF-;3oJr˙e//20XN\uTCylae}3eL5j5n@7h ătCG [{{K>rBL*ї_=u)ibݲ+xZ\06!T5T܄%jd+BZeWݤڥڤ.UWcV[Hw~O!bXo8A%GqsA˜zYHC1hV7*cX>}2VC|Dk RQ*X64A0B/4KSH;1rN(cƿSԇ`|1P/|D"t懧l.2QZ(.18A쥰Wb- 8I,s!EJ3 =?ΒFƶ$R䷉#8W[O)>%Mw p֊(oAe?=" `^fw"O8( Rڲܝ eq Zp_Y&pR ]|u"de)O7z8H<h ՈR Y w P>'Duni|5"j7b^8Օ==@ѵdS|Sv(:dGu:(. 9r0"4G&pNKלm(i^7)oD! CzkE "E0~L Rꤴ(EmUNkI;$I-|9#|TxLj-9$>Zf&MH}M f9g-S巛fKD/ }4 4㙍U"sKڕdd%Q*KE%6Oz#(k\^$ptELɹk9SLx+RlK& |M_$27oS4JE^nM=߼[JmSx㾳bXT*FJa)#Z$O@6'Y؍p^C)UQ\U8ֹw),y)t u먬Պne>Qj*#*U|nr'-P|W'l un^e@cK[ZR|uZgS8728Tpؒ;pu'SoJrBMErnre geo䪜kJ\OVjDr\ wњ] #*EGJe ݝB$JWl@91\gh@Eͯw!zTqTR| ,YmZe-e[S{+@5LboI tӽiV>m^OKx'>AWy\8+៭oK oo?O($2xt>U'%_2ty>Q<ܳ?v?vϸY~!#<' 7>jGNjCY ?#+X&~t$~4?:c$~avᇌx|`-I<P>ҕW=W|x3~=~}#4I> q_w׎>{w#^7ޫ{2%|7{;ߕwdySwl2wРzv oV6]n;omm'mC\lk>[cnk>޲o7x \Lp0%Ɍ7 q`1pKO½޸o ;. {܈;NbvN·z3V7YpL}.^op6=nmqq 7~U>n2 |S nG7uF~e^|<W~v\g˗2Z7x{epTz?^<&j; q'x,Yũ|/^dE u"+^.0n 3^0T|?f&i3]hg¥=_Kf% pq/s,Ypų 4L\hąnL ?k? k3-x+|@ϰ3 q<$ sQp'ja7{6Ȳ;ˍ8S%L)q R ,lO6P-[u;HX6Þ9l 26XX5j96*;upsCf> endobj 13 0 obj <> stream x]n0E|"L$ Cb)R1Ȑ_ m.@p6Q57<ޭq[o< ݫe[] Ytc{ۛIWx&ve}`+ s}}v{Wx_'!%Q< lknAP \rgk]ThY8$B8="1r™9%3|A>rĵ3r33µώe쟢d%?C7!ղny 7oԟctP2ԟ3l9OByO:hq~FFn\h@iNpBz3<V endstream endobj 14 0 obj <> endobj 15 0 obj <> stream xSKkQI >6aUۅ1"t!BZh0"d:yf:BP|AzjkqۿsTw> endobj 18 0 obj <> stream x]Ak0s=,Q7eC? & I1k[!Mt=u~`{L0zrKX" 8yRetD%Z7] Nm/_c)Arϳ/fFKix"Buyb%lhBUE($;a%YJzht~ڀ]I=WCܩm endstream endobj 19 0 obj <> endobj 20 0 obj <> endobj 21 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 22 0 obj <> endobj 23 0 obj < /Producer /CreationDate(D:20080627214547-04'00')>> endobj xref 0 24 0000000000 65535 f 0000027975 00000 n 0000000019 00000 n 0000002714 00000 n 0000028118 00000 n 0000002735 00000 n 0000014563 00000 n 0000014585 00000 n 0000014788 00000 n 0000015282 00000 n 0000015632 00000 n 0000025548 00000 n 0000025570 00000 n 0000025774 00000 n 0000026224 00000 n 0000026542 00000 n 0000027203 00000 n 0000027224 00000 n 0000027415 00000 n 0000027707 00000 n 0000027868 00000 n 0000027920 00000 n 0000028217 00000 n 0000028301 00000 n trailer < <4B0FEADD998CC11CA3000F7E4BE7F1BF> ] /DocChecksum /2B298114E92C48373BC1E71405276B58 >> startxref 28488 %%EOF kst-2.0.3/devel-docs/Kst2Specs/BuildSystemOverview000644 001750 001750 00000011332 11544160206 022454 0ustar00synthsynth000000 000000 Kst Build System Overview The Kst build system is built using qmake. The build starts in /kst/kst.pro which triggers processing of each subdirectory triggering the named .pro that matches the subdirectory name. Building the Main Libraries (libkst, libkstmath, libkstapp, libwidgets) These libs are all built as lib, in windows as static libs, and have fairly straight forward .pro files. All include /kst/kst.pri and pull many of their settings from it. Kst.pri Kst.pri configures the following details and is used by all libs and plugins. INSTALL_PREFIX - The installation location, also sets the default to /usr if not provided. INSTALL_LIBDIR - The installation lib location, also sets the default to lib if not provided. QMAKE_RPATH - The rpath is set if in debug mode to the lib/plugin locations. CONFIG - Debug mode is set if appropriate. VERSION - The version used by the build. DEFINES - The INSTALL_LIBDIR is exported as a define to be used at the code level. Building of the Executable The executable is built using the same Kst.pri settings as the libs and is very similar to the libs except that the base template used is app rather than lib. NOTE: In /kst/kst/kst.pro the LIBS are set separately for windows compared to linux. This is required due to linking errors on windows when in the standard order due to interdependencies between the libs. Building of DataSources DataSources are built starting in datasources.pro, This includes logic to determine which plugins will be built dependent on the system libraries that is determined by including config.pri config.pri config.pri provides the function libExists that is used to test whether required libraries are installed that allow the building of the libraries. Supports the testing for cfitsio, dirfile (getdata), and gsl but could easily be extended for more. Each library can be enabled for Windows or Disabled for linux. If it is not disabled for Linux, pkgconfig is called to test if the library exists. Only if it can be found are the dependent plugins built. Building a DataSource Each datasource has it's own .pro file which includes kst.pri as well as datasourceplugin.pri which contains settings for all datasourceplugins. The .pro file itself is very straightforward. datasourceplugin.pri datasourceplugin.pri is a straightforward grouping of settings used by datasources and serves to put them in a common location making updates easier. It sets the template to lib and includes the plugin config. It also includes the install settings and lib paths. Building of DataObject Plugins DataObject Plugins are built from plugins.pro, dataobject.pro, filters.pro and fits.pro. Each make use of config.pri to determine which of the plugins can be built on the system. Building a DataObject Plugin Just like the DataSources each Dataobject Plugin has it's own .pro file which includes kst.pri as well as dataobjectplugin.pri which has settings specific to DataObject Plugins. dataobjectplugin.pri dataobjectplugin.pri is very straightforward and very similar to datasourceplugin.pri with the main difference being additional include paths as DataObject Plugins are permitted to make use of libkstmath, libkstapp and libwidgets which DataSource plugins do not have access to. It also includes the separate lib defines for windows / linux as references above under Building of the Executable. Build of Tests The tests are built using a similiar configuration to the executable. The config is qtestlib with the template being app to create the test application. See NOTE from executable regarding lib order. Build System Scripts build-kst build-kst is the main build script for the system. It is a basic script that does the following: 1. Parse parameter 1 for debug/release setting. Default is release. 2. Parse parameter 2 for build output directory. 3. Create the build directory (PWD/build) 4. Enter the directory and run qmake on kst.pro 5. Run make (either using Icecream or directly). install-kst is a build and install script for the system. It is very similiar to build-kst with a few added parameters to parse and a call to make install after build is complete. 1. Parse parameter 1 for debug/release setting. Default is release. 2. Parse parameter 2 for INSTALL_PREFIX. Default is /usr 3. Parse parameter 3 for INSTALL_LIBDIR. Default is lib 4. Parse parameter 4 for build output directory. 5. Create the build directory (PWD/build) 6. Enter the directory and run qmake on kst.pro 7. Run make (either using Icecream or directly). 8. Run make install (either using Icecream or directly). kst-2.0.3/devel-docs/Kst2Specs/Plot Geometry.pdf000644 001750 001750 00003223306 11544160206 021734 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream xXˮ6+.`E|K!ז0E] ;R$EZ}Pyș9sA:}<n_~Oo9aAkio?_|f}qڿa{vOr7;5Y\Onſ<~<-V;A$b>+>ƫPn7+F@묅bꢄ\ ?u>~;(7$.Q82lr;G[Ԇ-m" p5BJ,;6X.3:P#R^2^2s_N#"ી\hw3m 7DmJH~u3$i@r^ 1Hr,xd&De>=M}d+}ߣWH4JOPdbJ9AD~*Sahbp15x] (GFɩ7L5:+8€/zN6(8QB92YLł7D"{#)>6eט@{ nNԜPcZ0Gj+ 7Jyz3q'rvGyX(S 2"C+:BdB{MX{wT2BX*;.Џ@Kエnҝa?OVrzRn3:G)iF+\NݠBa/  6L`Tn36TrGY*V2H8;z[[a^R./i}IL2\&7&[Y4`TdN]3Кr8ƜzSlxVq <oV2{2EA19haf_="ԢpT.%&؟{O 59;m!!dO9QƼwt> stream x33T(*T0P52 %,JURJXZ(X(F&z ɹ\ . \ w endstream endobj 6 0 obj 78 endobj 7 0 obj <> stream xvK[+ J) R4$RѤ11MclUbAjLBpߴZO;_X^_k19ǚ~ξ9cfsfuqhf'&=ϙ<&bW0~D}ȓ>oz5xSR)Kp#NgAWO8CH3Ֆ{䏷ڵhWlãQLxhI$X?*Y`Q㓉˳ F<}6~ i_lՆ(I:=&dON禓r-(:CY$ض=ywSA87evbE=pHCaU{u'W?tLj dol==yzNɆ/ץ,d,zfy^ꦓZکj!c3} Y=ʎv_-mXԋo|,%5pNأXq̭n7u.h1*F21G|+@4wnv2]_Wcncчؑ Ǭ8z_UX\ ~lL=[6WYXw`{s1@Q(4Ү ;=-[UX\Lޝj=)z+j(s} F/vaZ ϡ/NoruP>׋W⦓2iG1Lu.qĦ"qZNoϼ߉zz>#OǑdWx 4ԝoﴳqZm<]ϼ]APMxzh1\vuc>~F%lcnWޙ k32 Gh(q&N{E]pަ\i:]`[}zKʹ֓C%lKne8`o4Gѻ qՉqweu\%綜;Nu=UaK=5qSkqɰ4״qn׮OK.<\jY.u{]{8wϿEF T8=v8=Lrbu8.dR\|e_{ =pEvisf]&9BcOW^c]jV5lwʿwBt]+Ng顲hx!1 CIuƟ8ouzoLwRk\F5S|urvL.Z "|:ZcO>i t /c>Ԋ]g#;"B8=(2k#Ss6w43I48j4ɺ٨;~sT]Kpٰ^}ȎWWlص@)9E;ivbCw]dlԝo9vuw5}ϲC5f>[U7E&vm$PqJuuNFc2FҾ*Bw]dlԝo9vu]z H˞ei̡}On6LH┖+Ν4;~e1I!gOl:.RtPzϲ#4&>ջU7E&vm$PqJuuNZ6NɔjTGka:^PnϲOo=ջ?Lh\Wu:ZcOr v4qbqiߪJ#֘+N>uֹ#`i_#siu>J)9, ;鱜l{MVUeWD2}뢭sSȧa:ZcOz'0lDю^;i~Ѹ״oUVKt^W7Ү vK;XN50)+R::%X!z-E^ӾUUDn[-]WsMɯ ԥO =^dյP ?}ŲX*`i_͚ROehkڷ{埊Vߑ;.Ps'M=^ܳCy1{MZ*`,뭻1 CXT[ƽ}`Y]Whuq{**Ү3w|ܳ1+=W-qrˤBS%OྰGWo=l^ӾUEhaۻ6BUqwdO,ͼ:HYc65+;o{z2l(ǜՍEa uR߾SEhߤR Tռ@׽waԈ: RiN#޻1j;<ھ\=:BVe>ls{oמZs~M ʥߺ.Tos'8Tߜ)18..["T8q#tݮ}z$r?-Rs}{z}\iI eu\#Mb<3o7=)2j1”5kzKV21Mqoz9S={ګnYսb?ziWuE^U+]8l.Zdb~ZFTG_q1[NoeZM m8EIV·xe;h;3[آZ:ꑿEuq\uCQiqˮm9¥SKcqn>cqUwiZsɰ_S5-3c Si{{5o=ze[j|^.Ɵ~xٳ|gO̿}nW^yD}stݯa{5o-ݵp6 +N&m͹O4xu32)9L R@K 7ݦa'<}v"PVf݊ v"-PN ЛŰ2Dh|ewv"ԕQ썆p/F1%M#+{a3KƖ/،[=v:jؒ:Szw RA玢/y-@,:G`z2gd fB ঊʜlUb;{IЃK v s;#_Ze Y#Uz(cQj)nV-dH8uzܲ5il QjҖ-S,9kKlScFEUTk-ł##cFEUTkDD +=>%&`J vjĬnlTJ3z܎ѾY*BƨF#(lwLf PDVJR-OwL Cc%0 K`0 Ac-',4x =Mye_q|vw`v&xzko񼲯9OffoPi~ʗ߂ggfoPixLx =My/4x =._D`c9=>681lFMI(7B &EmY ي1;_lRPlARe;0a`ι7J0lA_ZY]ᬵv+P/¥K}IlfWFP6م4ۑiߎo)v D 6,S4nѵx86S鳑%XDM\e*'^f8)n`,͔#3&ڤ&x4[4Tʠ9(ݣ` xnTc=_oM>u0-5!N(Q8z"zbR5D3NX?؈NѐOC 6,s9`U@MxJTİ#)a!d\RRVD lSr+0){46"ο&,;}P`+`0]h`oEvd{ MEN)jmqm-K G 6;k_}K'o}Im^omxv UTq6>hԈAeʎ>(b{3m' AŰ(~n+]mb-žX !kO*_*-_Y$N>L^w?T e?lu"iZ'۸3*?lu:N۸;o[0{?][m`;w.F[cGؾ{b+,l<~˾dq)ߦ-x"2_ە]fv=w8nx|R ௳Ex&cuYg;)V;7tu990^v6glTjHZT~0 E5ޜʇhңKΎwݲ"%#aM;`XCW eW=+*_bG'jl{k9SMW|spgc`gq;0:Ͼk Ml=أWpw~TK5*.\7h/bc;t`ߜ>ۦ"~J]QXƗwa!vRD 6FElvh;UY`tjק(`'^ءOh·Ai?%Xo=n<;N5G'lVbJX%C1I=m#Tu&գ(J%x;(}fDǛ:bGT1VGnPzL*vu-ų·Fbі %Xo=n0#:>-d_%H5KEg&vj|R}ٓ HL%\W7,S]dUD Mvp8j N)Ut|LyW?xlS%Êqo)K5c/J:HƧ"g0b(%42S2;f8(ve88>pHߍ6|8%IR:jKT-Ci H&^I"h q@ O{&6z<<(6S6Ƙ|ZNThw̤DYTGQ-m ;+;DN6hd;6R1]\: iGSv] OPۇ ULiz97J~Aѵx1ӧ(mL' %&_mIv6f` >{S*qQUw {fs+H7>X<79&fH4=]m=fb7SoҷJ?DiT37ٽYv6RCHu lAvs7Uml7 P7j=0F  :jN#`t~:(63mlGJJ*͔N9nV=!(q)(TD?uG.у53F}Zt*:%XQkV”`=u3l#擽/[R2ǫ')2ҶUIͲRP-߿ mE_gJ# 1N+MgXףҒޛW*6;f(Әʎ\:-a6}>^ܔ)R@ Qq]}J: 4ݒ]˾%ۦsɪ"8Eg#F?7H%\lA^Aaǩ/y)ڣY(O>D U"QElFK5deޘ>bu윫L͎KG y}YP#{[쏷Hnte)v2T*sesE /⍮,%؂Vl)* 1\Go;~WF ZPw>#I $Zf. L^}뾯? ."%6/J0 bmǗR?^49`M $u^ ./[ɳo=z['7J=T;Zv% {n],l.k, <{lf`vcd9s~ ] -l._, <{z;PVJY0SJlcJ_*r6zGpG V ~`cѦjȶwIXD=IV::`,J l^Ӳ*3Wq\1S&vp$dF VtK &-ΆLɡ1aҮSmJ#;J Yӻ:_I)J&]{Et.ۻA +ņ`KK0 =Twvv6ٮ+iة;U*<:_=_\ν͹W?#1@)p2 $۵r>ئ~ŋ/ ˤsq򪴍=Fe\w`x5{Q,ԯ㰏Uq(aǮq:%/^xx^9`Fu %Krx%l/@o`Ǫ?K¹+S;_QΜȹfJh#e&,Mk]=k ¹O8仏sE=fv}w,CE Nݵ!̵q 6;#኿.Fh%h` cg-{2Pd=? E d, "<^x« m͞n* 6X`'hG@<mfde7PyqQ#sŁ @ t.3BG?sHjˆdf{yވ|x`F/hdn$YUx%>Pc J0*s2~RGG#+(R'*gG 3/SM 8(.ktKN%H90Rྌ ,u,ѳf zJYEb>-_+m%0R}` WᄊQf;4VygX:$5(R(#a#m,LƄdMBx\uWە`~q< |{r vll0fxVT>1Oc(Lhc16?SaVLqe+&!Ջ>++_YlUhv:p@ =41^~Yٲ Z?:ڙxL;N/cFSROyf Al'eD&STە`?{?p?^Y Dq[~L,L9Qؑ7w%I{Ĕƒ- jL`U&vjhF;IP] o[%u ). tĥSV~R%ro񥁝rEZsQ('?яL^9=<(&cKBcص>RӘ:[ߍ_.p[)߈jf:7N?b-sx[uRS{gOj)v#kTe*1R| w(R޺=b(eD]jh~ui6v:fVS=])H;w@ Ypz,8R 81P\S:p_}'Hpb t g2J0 , \r]d]Nbuv ^?+|Wȡ]R7BS-;cz>z7`6Gj0N)jHγb³a6v খȯI#emߧpLqy_d_^}`߽۠K888d&u+|cJ15ZxE`T8qq|q|qmJG ! Z @M1jy/~쓿ѸM\c)#sGrH쥋OASz8!` B˰L|hk/wGyQ:F*Eͽ^,ЭI_HZWj`%.#ESѫS{8vl|#PP7>E Vz5z cJ+iznTG+)?FS@.wjק(LY{@kCJI F V}ɚ^1SC`cx3[zD{~óRGR1Gf@t*sl8Z9:`#6ڗub%HRU[];)v^A4vdTRWE`}-> یle VtjWk :yl.lw[ʔFNH@Gh|rS}!STvE 6Lr]PQpP]VQ{ & 1ٹ2y Rgލ`|foe}H)ͥ\0%xl؃QpXe °,uJxPi4} RSc6;c+C*QY@vΆT6M v@->-leDCG5@u 6ϭKӳIFU>"lct,MU>oA>ymK#'A.JWdME5K f4ޥ;r.-Q(5sDmF)U4]zt*smJ}#P; ;x~O)FWeqhmri)"՝ /]4#CJ*zeRi*lwQGGd'%Hw,޼r`/&YSv `& gZ10"+g}sqn*أݬt8};͆ϵ.>``)`h&r6~136lآׯԀ@Wua}Ȏ6={3W%Xu[`o>C*ߤRMr0,&W!)X +U'#,K0q%*E-AErUCPު81KɃ ;`dL S_`|QUZJ#>g߭K4Tіbn0,ܡ\ך:?vm~;%XWJ}QE VkMw_NJ0F`}VXp}/~W2{{j\%CR0LJ(D_? q)t=@ ~#I C 6 ,{:a.`7}Q].޽w]] L`PaJa4a%-_`_^F`vҥĆ)ڧ/J7þu6R_)W`6#ʒjShfRpqxn2qq:%X SE v׫W1(`5ʺ]uEvu2E M+hr6ς0%_`w{rc~#+B `Kł~D_ MB4Zl(]d1`+_o_z8%@n|ScX3s3((}sn]3 ߈xcKuw{u[]J0[Jna]sa϶pQA_}JEJuP;,Xx ֔zδKC DfWw%yC=7;^sK vK5Wx/AjPRjTU6GiL(l2J٬7"ѣ/J[V_/z f%-Ժz>׎/fb'r\(,6sOQl)(`M}򏮽#?d(M8:F>㺯~{=oSJ vsJ[_^ܹ|b[(޽I{QB.Bi9̎`v|,k_`|=]uRsA[ fP،$w^#G`KyԷۥKYQeib_fE,v_c~#oDG`|]ݺzŰ4w)`WlfϥklsYK6M|5¢6XX܀_J?`7Ta)K SJ `}Z]| r)<ys%M_۔`ެP/ƫ8`p1}e^STgX PG +lvF =vOJ:K׈쎯 Jg_'_ ς*( TGw*Ayuح믓%cesa=]?/Q@ȷ3[V7}ݺ{r{ vB B%0`+_]x]5J(M^-S(l&ZjM}P|7r0netoJ0K@ v}K0WJ0qSsA `3Ҡ|0dO&]KCL˹? 8`7}ݴxBzvuc*J0[J Y^59?^أd5(BMjBzltWci%-_w,~) R@qE0Ej#uъ*GNw5һ6%M_{`3ki3l4PRpߢJ>vbW{Ɨ`?얯ە`_'ǫP#J0[v].()ֈfQVbW#K0ȱ(nW F>`=rQRQ᠜9KJA%H(2Qjς @ v׍J0/3Y_1 %-e A9r֖`bpx݉>tWJ0 lK\Q`& ⢮v0"OcoF]QlPzںJ  :w/GӍ?&zh HUv 0S)%X %W^>zp4R،Qme)sdR*y3hjدN%?zmSNs9Z`}]([²Ezh1aHǿ DJ0]>ĤZȚ"H% uVu7"e,~wEכSb:J0ƠC?xrQff/~`pSwhJ0lY[(zS_o̽ 3kRzlYk=; awCJ05vjd`wY(Kա[HK0(V$9;8ꯑ^%z'ן@ (0ҬsG v+_Tm5ou*PR e?z}h'3Ɇ2Nד s)be/Ml4.6WK0oEnE&bS /] 5ꯉ^@N? vv^-S(l)\N =G#+95bςGoJ{YmK`se1vjY嘡QRt!+g.c/ʧ"5C%+z꯹h鸔`?vZ-S(lI)^#工L;Za7hدޱ^}`4 3/-BRνK)`#ƒѵ7%m@٘)bG+)g$;^זY9P-BoMqJe %-E`tnIE{P6-%؍M\4:^W[ѽrg)`]Hm8Kog"T$̗^}`77qѠZW#b2 m%u$vQ&Nғ@4go!(-tŗPSo v9!J0[JmaZfa\Wi_6d0K=wE%kYjd% OIU=~W`䡗m pZ_[ mxm.ٳ샐 <؞oUa_+fA k vsoW_`j)% f]L[0(BCRvolb=w\[0؍Lװmw%hPaY< lRKu_`m͞dڢm~{tR|AuS ծ1_kYV~`EJ J9Va`7e+ucFs)x%;JQ"qʘlw1)`A 8]w`ww0J0K /@xGz,'`VJ0gp/wK=CRs(Ė iZ( wT͗VX믓 V({N%X+&_K黢` J0ܗ͗6snٹ`@D -$ Gs"J0ܚΗvH Rz(*{QmKF `=i| lo+T.2m\J0D`Buz,A`_3A_2lP`a]Z}8Wѭ?j\{ë}w)#qӬ{ geEy)%X'%J0fm%#;yx]aw#ѷÛl``gGYJ0)e]߬guKHyPb>SzbzG\\#1x=^1v3;Kg4;N1q[?{8~8~8_Q\v oȴZ eJh/$[bfF84P*ݎS&;lJbSc*zy_=?p?w~|Ys3Ur:` M)9bϜƉvbzGlf;ӳsHu". \ʼncQ4=sN1gz{yoBUvt Y_Km1JSbJsx?R6m6ft8;F1Okdmlt]]z{SXE+R{zR OdW7"N7"xC2sS*@;,;lٙHXT4qbE:YsY UȎr7RO?rAF^1%XQNOـQy*Nu1}hV4Kp`3$:)3cw ``NۗlV1?\Rǹ2%r<,#aՎYѩosWff]平 jb 8`/1<_)k,롗 }BŮz__s_-[ь{vGز=gjūPt5+wuY0 8:zѹV}D'vG#%{ ǯrAWt=Q0F=wCEC|6oW6z z]+/ď\*S(;쉢7"]ˣ^zTaah{.:-D^uJ 1s`Ca剝v޼_Bp5omlm7C*Li{;rPP%1 (cς9%)Yj_u60\qL,Q5K/ѫ6/*iȬʹ׿=\gëP6gq8a 7 e#%T`+:rz ?<(i{]Ec]@(6`0zc_ rjO#o`of҈_jVHaznZ=u@ v0E<4ri5;Rޗk+ PUwH_pVH/tO)g&,A qsȥɔd/믳#Nj`?(*:bŗ3r[pn3/:-~4HUjJ.eJuEx}\?:&\뛸EOæ ̍aUKeੰ)lr0;"qX*&yi0rYUǼ)QK7|y]_:)#K0{@YTԑSmrbK.AGDTYuf4^g28򡯲՞~zY*7y@g2eX r$۠ݵL9+uPq$E9}B9bK S.)m Es-ېGCVҰ^>";6y|}~%:cJ02nv͔*'Y#F!1ak#!_}J`sDxSb:Ut|%x8\ZV\͢+ZA۫n4;|˴2lFp;l/m8alf8\ZA?E lwJ}kK_' -חL|Y1l=hfF(tDeDFz"r=)~K=#wX_ǡh.ӣ¬ M,} G]i~)El,uDMT_Fvѕ>Wc8~( ^ -8h```{UY]g,+_'Z/%^Ģw9T3wMEq\Fpd5 N큋F*a!tzЎ f`~̯ǟCF$ E&yƉvnƤٖ^4~ n\;[4&clf& x`/0_o%n5Fש]MT֥K삙S9F>SJu R}oK O^S7 c|7e|YTPy5z+5~;:#]0>:$_wzQJ 4g@ Gzb׍m%_Úiur5Vqq)v{nzmxtw rW`ûy7\͍]-A)7\ziv{,OGuRk Z;`+b͞\mS{[K 5NVɚ{nQᔛ`2zI *̫՚e**>xswKa;W G] w כ\G.*ifq 1`^`??:)\VJª;=}Yi@%}K7&m|)I`+'wnBދr蚶AP2u.L7g:-h` (^^ʇS.h{ :>^ڠ{#Nܶ\&r -8W>vbI n ѲŸį_ii7T;86vP[V:;' ,Ǟ;e+ꎗ)tY>8 .. |9n?yڡ4&V8ƀF35Vԣ>#.C3:|C]SY]|m_Wq `F*SwHtyk6+xnˈZN0+=v%츔O'"\\cR./`Q)nq)!J]J]"HSG8iz|;[,#1ԈͲ1ũJhOf]2FKeC+/a\eQ/;_+'ŗnK ` 6gO4N4PeU:F#`*{[FcqJUzk'cO1^NC+/a"syr$͂gK͂uR s7JƒaYL*FdU:Ɗ42][ccbNxu|r!tU16#=J_ohX*eL.)ة(YsjrhR-{s;X,=5aFJ b/۟+]f)`}7ߟa>Jzw9k5=hJ-IPM(~}S_^oT/AW(J0|oD^] 3y=º N=eޱ[pQy焛jگlX-hoіw8E5e%Rx\ϡ4쐕E_Rf WT46%߈8΢;uK"{| V6ӷŠ8z>`=R1l} A [%zV4H6%ۊT4ruszK` +*b?//קCK}G #FrϙEG6&s!uJHh.<ͺt*zϲYd%ObnzoD#=l,2^=Qvm31;o) 琧)%XHSjwZLlJzʈĮŃ#JQ DT3g]&MEmFnlbzJK];#*쭣*/ywkS_^Sc 05^i*H=* e(ϢIOy=lz) Sg_FQ76ti6սepMYggufv"OǏU.E2%X+=+u*sY6Ɋ(#5KsKgUOx7uH]P>ӛo))=~zO6%ٟ^M,?zfc}_%+:bǼj#v.%ɺIklHFOO`i6S҈f5+(q o]NT+*mqU$7tEqw5+;[Qg?2XsfpE/?M܃UKnewz]izbEG#ۧƞjͤ}u|Lo:=ܖdnI42R1No~u9?ُM/]Nx m_~/b/eÖ/mNa3zߊ_&C{KE0ƥt]U48vnJϦn8h[왉6 ͌#+Nha©?*Cy#w~{ntF3+ 5WhM_Z]ej%Xq8!tJ=B=*]iL2iɄҎ9K|ѻȆ-OD#K ^A9hcQ(#_wYѥW^7MR`hE,6N <>-E?DZ+^E>v)KHGTT3D_e*= J(]w|.oqq/`vt D um͗ʎmlϏ܃oD|~_Tr蝆|O2û .j(cy4Ės|ˁ[8bn% ([`^M/ZP)^)zߜcQ=:u\ %Ct(u}S9ğ'{ =pB ]/J]pߔYX(mςqXJ2,wRz,خ%X̼#'v/JA;R]2!SGPi6(mrdQa#D9[Ͳ=OѰla{;xKEñ3)^KS:h+r5\G3~L\]h?랉G_;B_[I8wm7+=h3.NCiOvr#3l{2>V`y\D3~LUb.rP"ם6+Mh3Y%TFk3yŻY%K/H V6u]~5ҕ_7]|f*Gލ!)gsPF89fb|;c8ƬQ>PP==pWЩ;dtcƔ)U^+'LOIo,(hJ8J31l4eJKw,X'`(mgzFƔ`G֢]nϞ%&v9"> ^JJ<>G8J31U%89@7MӾJ;^m .ăbxX^0=:T8qFfщv&bT49Ңf5  =юV4#zd#q66?l|{?+6XnUW [zJu)Je J0x,Ali8+uPQ tjike$&4g ;=gG{Z%{7JwI%x4rD4u=h3P}2oӞ{뇟Ez?(EӾQ5K]JmJ;M5+M&LEMmno:vv*ʉ^ғ7ڸLEagiw͞ ۟8K6)җ5Y%j5ճgΡ4[fg mϔJ7K{%~{-Kx`Bmnށ ,Al^:fg,8`l%hy·2L}W[Yn=w知`?l->VKY4`m=k|}f;U?uE%Q_roX6{.%=i 86ہrcK?(|G͞K F vsj 6  6{?{~.0,Ac可疞"}NtGϲ` xFp JGG v p` _6vNmhʵHRi\zJs*4E%ll >Kа~|6;OԩƑTEYmJg8rƖ5ǹ8ⴈUQ /ʍt|7xi aJ0m+8K"%ؑ~>Ѱ?OQ2fux|NRqhՙ[!զrԝ嘀%H]d!<% |6Ec%h| f7nÔ==ۣҵыLk̳͢=V.1Ͷ##={!1Tf琀{#8 ,A;`B&4IY.ˑǺލ|'Ӓ=1Ҏy*THEksHG2Ց`5Wp ;`.;?I@LRiV̦ ^$;Qb4_ɧz1@T6;mm%h,{z#(B0[R*8v#~t#VHvhFK;?mUY8-\/7MYvbL\νù_ww0"+db7ˎ+ڠ=*un09'Ӟ{,A;~YeWaWGB1v3#=+Ǣ6 D+&Uzʡ]rmlž*>=_:_>[η?w"fJ n6NmI Eh(E6ݩmA#%CKtvu)=e3cL&-CxNH@2lIOB 8s(m,ةؗݦ:lLVtm_4Ğ 8LUQb3ةޑѦ%>輪e j@Qs'y/徙0xrn}#MļSPKO^oL VyG 8go7-^;j{&U:f|>=J09{;xx %"n1oQy왘`0J09|;8fJ-KdhUIUV7'Hό2ɞ[\I^zBHy %ϓ6b.Y:|K悔ai(r7Ϊq>jѰJGulp(,<=:jG~vMb~JSmV7T!{uWtvwrV:J@E[xՀv`svP=7&u ĔQEGLZ#ӢTSKfhc*mV1#;* v+#xT{J& ^4K04vDq,b d'*\#OH탍bTrKLzPP+-`] j-J>WXQJFEe'cVfhs<#ĜzfOx67/QMa/ڇ}ڽ.܂Rɠ5K0=`H>j4[;xjM(lƉEc)MI 2v3BJc '.d`SZyc=B[*6gfXТW2WFYѲ*.ǥqb]pq.ͳHi;ce nct %6 WvFKq;=Gajq|C[*oDLw_mJ{L%_7#zթ1E4^K#QMe̛8d[fFשhfKI)^tF 6Q38>Rv4`gI @ %&V>Tla?ة8Ejj'ԹNҮ>QRJƴ=;#`_1Z%l3Y; ҏpḭAŨ**Y)-S3m *'<4;r[Am{b_JJآTF2䈣XlsKO 536egTRVPzԛfbR:'?b$JHيbˋ8q.Aٜ$)ejɤĢoaqeu>?bT =n$R^mD|/_Tu͔0hJnpG 6Q6K9k.1fOԇlhf J erSiؙTK4/S e{:r*}H J s'ҏdr*=3FF%YD\ܘLƒ(qa"ɱ_mQbHԢA){DgMY|RŮ+k,PEHy= ω%lAeG[Lx>_mWM s'j/5vmDeWc](ig.hqW_}nH$@Js) eꙭUtiJ qo$zNMi|:̬<|S'cLJ`#;+ge'sg.ǽ}1w 3Nx/x'8ѝ  㞹޿ ]1q)/ZcS״*8WrKhmwjH)%-`^` SH~CM ӎYOܝ7UR˔,6>AXZyY?Ex>{+'UM 0[Z7%aeIEx^y^Y?rX}ԱTi5ʉd̑4SS:ĢieEd.`x+)q<NĊ;RҔGp5vTڗ?=@SPLÄfiZWy][:@^q@9,:1TGj^TI:@GPTqJuuNѕ=kKq-@^W0q\RĊXwrKGS!4^ٛ&泥"H/K{uޛۭ@`x+XSĊXwr^t*߶9u)yoBڶ3ℵNs{^7ÙEx參\wK?]Iϓ}KшƀjwL?KGWci#Ev#eLϜ:,ZYLYI"Nu/S48Kw~磠8(kz5ClVZӬ(b F+8V_v4Phߵ;LNcޙVnja)ZG˘1*øhjo?"i|יŧgx+QȌc8VRوcN&Yl4=H"0fO"JW[bղϋH'ZmA':jfQ6V)P3ҍ"ۢzs\⅍Ӽo2ºqS$ 9L<:a#8nZ:%HSօU{Ίq_It{ISOæEXSiְ%<%%2/hg>W33xudrWҊf/f#VT:3)HJ_JWtoWsID( | 8_3m]dIE"Z\d9~^t9u nJk* DgDa=[[=MJ-ce^6}XG+v /vg G߃_8޷bN}1ſYXa갩Sm\u]-uj) iM51+FmE#z&0!\'NqB]ک1J³ %o ̛ji/s8Sz%R77@؋`Q3Z#R8;4M{#'zL+ Ni:NWpœA58gE.Y '20-*~4c6gn#r{t~\1DFͽцΚzpZpSƒ(vcRC"t!~8QStWYEQq}c*\ףϱc@H)Co|dGfR3ҊaSj¤9QQ-_>n Moz}nޛ~R?ѯv\ ~ }>Lb1/E!:I=*&͙lq~G1`z@+""^;2疮L Lc-{j& /YQΟN`U9inD1@ම.U'Ӟ,xarEsvR+ׇ3m6nſ8+A/_- m}  X:FeoE\}w } v_  vonO v/WǰTQ48|Y1vg cfqQ'rP;?sȭk`NC'o85#VEš]ힸ8~#GJ ! v+eLcG4F{}sQV_Mъٻ^cƢJz9?lG_~[ei쫡i*/ MGSyD7:+zqM`㺯iʬ;W{?8!ӵ`Y8V}G Vm<~QG3yz.5_ fJ<R/Tg?W̊㢎)W4MWƔcvM>C ՗/*RYaSӘ?u͆Q<]tGxtv: sC'VgXrԴKXL*fJ֏睫9;U;%,r]|\J+v r-cI療~a2+g鴚Xb|xHa}P|"8?|d2fER%Tm4;r;~ 'mThEqe̍pJChWߝ۝m_|-\n/a]Ɖͬ6cR‰9X |QJuaÃ>㊹T41zK>tXĦve[5'i4$T7j)Bٱ`mJ/au]0NH|mUL(e9)EwɊD=|ۻX}JQYH(19tL'~IӰ1"H%*:EC1auJCQPE@:vJA59r121=NVz1 #ҁ'+QH:>KhYdzEGk" m]TOL=/jL)Nsqe6b*n}''+M{ǧӑUL;7LNEwdةLLiSYg9|Œ95%J)7ӑs+tbCPtb8YQ4.4M-LIvj-Zu p,LG_U{ybړa:=߅Zx,u})h[TcV*>](0+d93lOh&*cJJoΎGpK/ӰiӱYwx^¢\X4>q*V:ftat sVv.S?%'J"1q ?/joމEQDHLSDL> =FǿKll]4m'l8N4Ve7wLVk3ylzX}Q=}vzS".ۋ^psHWx258lW0MyK0X67ve]8 :*e;OS/ ѩ-N^%uwqmDl}I[S`q_|!s}Gq,-kN\,\|a/.EfSDGPz*={q ]0]3|v8TPTLmbo0DtJZb Әq1--|=:EuufIESnm-8NGs0aï1뚭E1U#h 66q1ݵ)JsI "`n#qq @NLjlTGP)ݙ0 9DP'j~oJLNT:v%ʴu^D~ĊSYP ~$62U+ zq=FEΫ&4!>6]t\9B4_],{-ѥhhyd2gNp x@ӝ)U{¤< ϗDi5SS\*rV ubdg54}6}%WA9 M-0nik"l\,dX6x +SS=ՄxiYvBlsĦJMF:= ȧAE{"i;颣$ .妲yra1| \Oqq0L{Ny]#rǤ{d:SKf0M +!h*^Ki 5[Y7:{_~ḄŮ#pd4qZpţ@R+O:`ظ)z+EEmnsxP V|^))'%NLXZlD,M2rc٘fMvO1u1,GTamg" jn1C\#)}0W*-vtBE͉LYUF_bwq]];jhMSLK^C7at7x/\LjumT0[j@$;&6ZZqk"Mk/pRU񨯩-GfnM7J?wYrtҳY[y]"[vDZjǸrvѳ?D=3\_I] ޿/rٯMAV5vq}_1y;8z;a/S]sR.sx/~gr;>k>?2'}* Eloet7RTko{CR>kFFS~|$~$+Yܺ}uų~Z"RREd'@Ge}Xve-έ1~D+S͌vU٥䙵ѳ{fo͏Ӊ v"{I |]]=yU 񙵫~"u|[*位OY0&{i}]f _G8yY1Bii%]Z4 걼}S36/)u%]tV:!5U+)~98& L{C~xԡ(YE'{.L'f6Hs9vW/Q4 Eu?͔nL{f+* %%c.? ?F6ê}?i3 QEa45Nů%a$d%q(l G+8_/QP-W\_q8JE틺N.]9s3{4EEw8bRNiz9|Qގ8w:J:E͘-h39bުQY4`r4};Ӟ3 Rm= u^_M| ԛ3lD]u9=;fur'?_Z뷩MNWÎ2'fuᗜ*QҺ3jgE[iF'f}8|.@ӝ)ilPU u5ѥ#Һf9=CQ%mӜӠG<t&iQҦir0MJMELivzN.UJfފPlV9r6Rf| [D {F[2ME;9NjSϗi]Hsebbo)aFUʦ7(ˏ\l19]C"5stӎ=i0{Uzht vĔ gD$49a|%G^S6]M>d7Ez߷`KSEǤ%Uq}ENio)ZS]dMeNۥK&E-i/\7)kܕQ[= }dV){+N qgDiw0'ݟv4 -?8|1{@| /iJ-g~n̦/5|~*T[tE)ko?ݲmDgW oY_Cǜ>GB9zfO\^~睏$D(yNMRѴF5'P7L u'U{vGԔ(sN^1z=t̖1aR*Ŵ=l,j:۾Y.F/+é:NL=1F71tgeJϘ<.m-jAhȀ7R5Qd4銰ZԒnYKRtR}YoՉ4Z$87}UhE.2|^đC0"^kjc6Y-Mcjil.:+IݚXl l8/:Wss!ԄNY%͍Vډ#H?.:iL$bTäo\pVL:\\,JTJ6ܗv$SW+]augN6vp_~;-}2uGn$b):\9%=cpiT4iWi{M4Z(و}k3&;S$m{bG'F(cƌc&m<+jWĴ~htu nNWR~}zP׽*NzspKi`{ 8fb$i."NJ/#jE\"Jjɬu<$-ZOq\wy#mor%щ >q^5aJ]4l7-Y7%7.dKEuptI{2 ^Nhx'(n#^9H̐8[DU^9"uDq5J66N@ M(E*յJ +3L{(]3<X?Ս6.YN GNU6CƓsI&ZыVOaš[Y^v2CӃ6V:Ztd+mrb8%R4K 5.Z1ة;L˥CمYe]>%sEn#JE{^QS%- 8Dz#ŊY<2/i-)7;ava¦=ZaC6;56*> 0JEbTT@"("V|UY1])ݞyv41+&MK+MZ6{OO&́++gs"#^t$Q\㢮fVQJ zuu3"hr"Lۈ̰c@gm6/:1Wz"  9#5N;S)QzJOMQ-_g1ө.-<=\x񎍕Sz^jA$:uW4[ k0GǿK>N!qYaoشâVz{1mrO~[$kFĈ\NR3,].56DRdm"ծv*N`sK|LϩtD-tw@UJ'4xc>hwzFŁ4R;GrcloOK|Kg 2Sa0p-/%kg0w~oJgtv 7<3<(nr>ftW}b~(z3VDzgwda=ZIս]u]wsf9ip KRݺKpF'{9[`;#2zzx\?-v ? ˤfXz;ȮOPɼv]ǿY?ȇCmlퟝ/ئ qj'9DXIeE }~Y)D6ѥQG9nSemT<1uu{tJNr~@oawԔ6m4+VYzڦo[;I _p)wzi 3}h%JNGظYM} iVotZt5u *5Sn?00RTi̢CM.F-V+6}͘Ȟ p#i6}9iFLgٳ$L;s_ Ef~ZwXW5fUmh)Lj,= ǷW5i]їKL1=W͔76 Y=(STYհpp|ZYvӐry|Yfc6]~4Ʃq+kFm9%E1ZpyYtķ4 !ӧ=MZ$5tʥI&uQG|>{Nt#iXԑ+9Nf9%X$8Wf"\dޝFEE4a,f_ucN(5 1}EǥXKj4 q| Po{nRNtzb:)ҰYꔄHy]Lk.͎)%Yq)*NênM(xڅ3dma8cLmiKXKjT{>RIonzɶ_4w,KMjf_sz,Dɚ;u׋ik haH2m5儥R?_9FQюӏ0Hl m=?ѱ`J=ݜ^5Yqd0TEMofEs%'ʘBC|:j%Sfj?EPkx8JVͬX"oj9aO5/sH+>Fwǒ:f1_kM/UMVEJaB=dMژ_wY`SUY =)IR5FVdQaVh-fELUWڴ&Y/rуlcSShМ3iFz&u"aglJTE:laO;iK )۞__vFQ3~駪ch%(vVĞH/ಇS>}ٽ ~iN/Sۻ cWyNֺ@a{7~-oOdK?;7kF5zC`tŷ"Y9:ːDH/_p~7PHf)mnn^WwV΍o[;=oO}@~;o{o˻;ywarf8Ӻ3zFZz{v<۝ηvzj_WNr? jJo{6/-{'+w}#N:oeq^֩\lwy=m[FԾFOd;4u'/dl6Zލ-m޼8.~'Moقܫ^֩\owy=m[FԾFc;6+_gyڿxW26DWiSി>޽:"p>{:Zzhypk>|9#KOϑQ9s4ibj4R˥8%_/gX\3ER5 .Eu۵tʢcZH7TY[ډrE[)5ا88Vә 4z_`z΢yhl(UNstZn̶&|fmD9־,Q/lZaFvⰪ)RNX)=I/*uП&6. ە˵tᔨιqlEKBBз'EM}߼wnȬMN@NF}jz҉mlt2M;4QXoDmcQ1^s*ᴷQYNXaݤ f*8vk.6nnj:p:=[0-Ea>B!uU5_z}5脵Gӟn9[:mK(%OBwk9HG#li]M_^=hĉ}5vg:t0۬vǤt c/6J+:1QG׊Iڃ*B͉yY9|+-GΟw8[G>=FskÏakLoh:RQ?4FLCwZqΡsɀv勯{(ii;W񈄷tf/+`ɬ gK]D;JmO#]ƋFN!FKD:ՔN0g'lҘ$M)U+c6싯%rͰEL`-X]ܴ Šruδr;d~X29ji7}:azԍZ-Q]ldk_Tڹdp*ՖEG7 SlޞvVbOۈœf$%ޮ4ķ3^:4}iQ]K?+cJK4K8t6:tlFHUS**~_)Uǃh:"zgri?ij^%h_x}Myܧ;8I=TMnl]RgU5kԞeUiEoAC,ĬgQT?7o+ xfwQc#w~joWRnV\x*a>x8O~O ?e8=^[|7oy6MGp ۑٞ?k8=.w -8E4x^-Qn@ |ޞ9ܡ~՝ķw5{Ca:z>-N6R2߸t1Cu0Y57Ҕڂ+[v@5L3g&{dڈbE|)QO W*rXfムlL6r)NUcb%Z*4ؙ9LJ-fB$Rͪ:хGG 9 ӥKWӟ"L:2JK(jlP.Nt亸p[͘3yO ;fљ^mUmeA߰Ki8K›ߎ9&_/U J&gWpvp{?h8_ _gl93WW|ܾSyv_0OQGߨ +p+3F}0Oui'MG3~ t oo}.~lމs%s)w÷w^j{ιk[>{j>8w̶JgLLonv9R`A .9 ,ݳq^ v+xMx{|NG0rH`SJWuKަSQ|eVǨg>f(Ia4q-Xkg{]iX4ɕögbq'QqRFtQOuoj ֐Kc-g\Dq2MWfO Gc >tuæ"ʬ|+"xus ܪ[wGTOwBoq6uON~y틔ȃj3`X:z)rWL0#QW5WGN/9#aUBu*~TSebWUJʙbvK|cI}iݪ^WQeg>NJI6̢*:rfiFSƢن4l:1^jyӂN GX'ͣ3MKޅ 'f(Y1Bgکv۞jm7>GaJ*|T*jmS2bV=DK&cxHTaKOGsG0KD8ce},bjl9,bxV0cӭ"So]Gt^]3Q;3i[ZERqeŖ_VRlKUOBiUєp2v:0D:es\¤NWK):"?0bfX$>‘VWG¸ 1ӢbN~UGtꚉڡHҺ'״6O+:fi@#TgA_&TgjIOTx DGӫQJ[iJj)EΊ+}/jEWwAhQm fQ9RthRӜ@$[ *mv|:qWNM*S7Jri_/QQ⴮Z1q<01#~g5RQ4Cz9ҪcFj435NSh,k4)\91ъJ4{iخZv!JVuŦaDpC$NLH4%Ҵ*F<#'rB sQvL̸9e6װYӶֿDsQ?{H5}# 3QG)[Yl z#´gG=4tbֹNK}\Iףqi47MO#{y4G?Uӧp=bqU_2K;aGe7ipZe3Ʊ4h)*Kۉw޴^JvF-RKSRYCR;<{C'6RxNC3OMrU[lXҲm玦7sEzoĴk?q4XuL&w-܍E_|Frnn8h=K{iY]/v?[SgnܔO- 7QO*EtkUgx.ySlY0>0onov/o(_6oٯi䙗{  6{Ox |S_3[`<[x[^ʦ֏SЏû[709\e;Iowd8QW w1pM܍zq̣ȮJܕiEi5&90',;<=wpy F9=Gq;|x+| ` DĈ* )?9j448c5l:7ݫ&:Cޒky4uZ1}U9մl*ȶS͗ "%ϑTpEW6Wcpi+QʊD7Z2m7v#+-11Zz.1-V^`}((~ÉpzԴxҊ<'9g-59RL(QӍ~1Z 47ctbR8܁8QIMs'Iaǿ] <:2sӘUi ߢ914 \i6mGMcL6.RW-_]Y(̙ IT[3ݚiiX4g,ZjoʕrCՀvv .,1'~1é@,kHMu"儙3|3.:CxQ0TV(RWM$F%?-EES'L]acL:"3t)b*^5&L)=Uڑ8;uҰ:)<JDs2{DkɔeQԸtbp*$1D9xs6V6^rܦߟNtr{WCmp%8{iAta&TļDt^wmxS ^b䤡0+fQ9énM{8~HFKi*=MY +<ƓƢS}4P$64>*\z*p~3{}mԓzsF(4x F77}"^v; 9{w` `L?)־T|9[jy|-.whI.Z_/q?8}2>cGf9b6^[[ڸM_sholD ŪLWݾM_~o|;O/+}|:+10 6R4TRNuܢFL4]Q>}~2_Z {NƣFXwF:TM+Lm7> },TupÛOؗT/jQ_Jg:ё3'pOiXYm{ЮS*qĨ)VۙJzM c4 0j_A)Df&Fđaf"=IϮīщqNjQ-()Df&F]Dxu(RcUےKSqwK8 6sUpflNEjL[3[/a%lMFѱ)9^iu>U| ,Qyܞb,1{AF cs/+?k[&p7~dt£tQKt'yƜsm{p+S%ظރ8:~cYf ɖ%['R7h?Ȗٗ/l}ՏYN{ [ڞ~h^`?đW0[k{~gxMHO"Q1)^vS;Mp]JDӹ޻0+I4^z{͜W?x^2x{#Wv^3'y^W0cF6M4i98 pOEB%qSOZj4YK"c|ϼ5ҺGІ,sњuc:LX2{>(e9j."m'LJtM)"rtwY;OX*( %ӔƅsaI1΢YBE35K;:8iL-aφTJpZОfpJ}9SD,z|q-#\ !(l2.N#bL{ Iv)rKxOd ɶyGP>obz+%ώ3qWT6 N?󤑍c89Q1#y3Ӳcl)Wm^48JԶt痎ް-D(tX[*O{yc5Bai|opǿK>:Wr\3`ϕ =m+6BbJIoRF͒=szviQS4Sgzp*ⴐ#~ҍL3 )]"m9MQm)7^diY23zNeE{U.W c~wڀ3̪mI3Xg\ա"5̶y9Dzr"eEn/z<}G-*p7kp pc'`'a x/xk&^;/_,_x>=Xq+zwq,r'U{>;qWu4 şd=L,3lq]Sno(X|f`}4ϳ&bJURkZ6{_FlnJLY+~_&b<4r:5$+[ 6[327 ~9ɗ~JZѱQ?J5}ԉ`7VYGUf~4mݢ%9 @߃>g0_`)Yƒf-YqnĴ(FJY a6$RKǿhKN/Okc4eZ" sΙѹ$̌1NHd,7mZjqUSʍ%-j+fSU?e q Ҹ¦03MBȦE}iO, a`O9o65^S9KzT" s+R aqZ>Dє) NpoJq{j+fSU?EN=œb5\U{6#T\)=MO ьǞ):~kw\JHˊy+pfv7؎Ri1_m`Nq MvcZ7 DG1@D@z$s>R<;Mы(l9Lo7|Ec R/,J&K@td1ZDVSql<=.:i<,};Xb(u #=KJB,pfItmfINS;whAr/9of fou4F5IDu`z0,_\pZGκ"ojQmjO'L8?mQ0U7v~~az8 uE1Ov;ĆNBnXh~!iٱE]ԩӜ'+tuN^R;dvpN`e\Q6[!~XWR꜈gC(ΞS˷wtw9Um 4L)u|^ endstream endobj 8 0 obj 53492 endobj 9 0 obj <> stream xu`ňN!KKp(R)Z)^+AZ,@5{odnvOKrvwvvvV3$;?=Hm!Ŋ<{}|'SrNv zʽ3thѰU':eQ HCaxg ϙ*+m=|+?r= M.%x6$Hםy8b,xfwq*@[.P!?}mTs&$fzJsR \*%D6$Qjrb18g-Y7*As ~y&k(HX9!t:R\Dzem[v _bxQ_?ȳKq1hP&q#7 $0n?#{ :x"nHp['YEwuJ]4/fwG-(W5]n릣$ci*ZQyN%"RPy'hzTz+$S"arI΋v^U&HLU/%qZU $y*ֶ7&e ,@Rr!ɒ>u륫% )@f S"ߛۿIz}SbGYCH ЧBlh$GR_}S-Z$O}Pd+o֧_ I1?+1&' \E֖zBzi`u3$RTͼ=!qWkVKC a wZk+ 1%[TYh?UKgCnJNh=y6cw1ZYY/{}i4~5}/޸r uY U2a]buy3IHlXB~&O,Քm*h@5l:#'lZt_Jw}98e5YUogW!cWQe7KCͷ z^EqQ Eub$@K%L<:/j ?C=1r tӐbc BYcE'qO%C-Nd7e׮{f,@7sg~8p2;]y{6_& R(@ɗ`-E^@f diܣGcd,ђyzd{G7T%UU]?Gb4Ѷ5+@R3EI]ΊLգbQkg;]EyZ8@( ҕBlbr-A4KUV={9Iܳ1G $QmNY1 bz~9@y&aEnv_Z ?.|W^U"8Kqbӥzַgx fCL$NL_R+ŌK(sUpK8=痙j>*^@b f*@Eìջͣq5Bov&Joo+ƭRf!TVӻi!h @l;d1i#ZNTF>`ý;`W!峃WFS~jHa=\f1ڂ} %yXljV:8 /u ?W<<잸#Ƴyc$@Ĺs|G*Qњ;Evč9q!@a.}S=3٘2)qt硵 ?F P,}}MH+pNO  j޾D;"EMs @bp lKҗC&@%q#˟<<,FMmMr]¶lョO[HQf(+5 A˸M<.YBZ,XTFu:wD ͒0#,ݐQo"J7 º=&/ Чf",PE AA&V䡵A1 maZ51Y9A#3Q4Kq) /وn;`ЕƧFcd|QuJ9eI)@/Dr7D?,(FTmT DfOg.M~ H>6p5jvoVtHRȌ#bQNV!I8:<PqAhAiηbK$p:n+RGvJ\(}dBb$@ȢM J;ķD3X$~YO/(TH-QVtY8b4Dh.wYjN[GGU)s)g[Ɓy,H.1ᡍ$ 4n9ewچf(wJ > HXF/)$ףkN\} H-cB 5$K-45xF˟T{d‰Q::Ʊ @&" Yp86}UEl) P$9TENj cƊQ!N+TeRo !@Q?&6EMT#5&YuRSމ,YDLt$ rw~]7?$ d2)Z$`+^ʼn6  UQyyc$@u0gՎ˪$9.*reovb %n;)R 2RdE?BZi&Z W]VPXF,3@LYj6$dO_Ɓڣy*@yv Th2u"2!,3ITD<(f\re)qJV| !1E>G&qLD kL-ɗJeG^8TY{42KF֧b%(й!>Ht$w!@҈s&@YkUb>Hz50LIpRKv/xRl2AV^N[ˎߐ=IM Y9$Q"CJm$Ձ?19k iJgTr7$:-1 "F⸚R_hqtey JH 2% d[$iYD9 GFeD Hj{h8V9Og5!$fG7 ɈG[9sD=ݔ^b/@Eb6 IKb ]Bd$?lw0;Hjƨvd QP&z/r86cPBU&Ya(J2xBS?ML+H$w{T%ȢVDC!Vܐ(f;!Z0 "쎹* ZoH*(X+Hc2^ (4b0#l,j+R{j%; (Ba^jIR Ga<,f[+,U3){7Qv 4`"k0hSz%Њn*@ҨYY*ah^*b%@DvL bI>2&0uN$ftsgmli'$BkP~pS̑S3D P(5vP:ދm 'M#i #>v57 NGٶtGTד akf7.#@Ļ$a}ʴ,\m)v {1E ZXƐcHmY)]1T$i>x>QIu[W=WtI=F"b6ʤWq %hI_~ &Q,xPuk~`l"šm 2y)k*|6UEHj61z;kF>((91Y[ &yxqJ{0+. |tSo c:{6 T^YB@=CDIAg0kaIua*6[at+FScLLZG FÛDt] ?Z>ݯ"g)Bp V޴ug,5n}-f+Gib+VU42(-H[ܵΩM$2W~U`\HM,%@ZZuQU ^1*x$ul`īoG+c\X36`b}D9ev,(ogItwiӎ$ ib%1ߺI)."DXg7-DJDTNҊQuphl'B6ܭNꪹ/94j7XxYi D~e]\-\M IAuTd·B #`43g?1('JH*CzL31fج\rv y&ZPNv.1H>ىU67ML>_QzHUKGt63H=ijK>ۂ2v3[Mͣ n3_?S6 09$MtKO.m=DYӔ!Kfg[֤KU>0*ZIUCCPS_O<|pzi @hzVru'g=M~\ c<Ɏ`QѴz;|Ԝ_/%FaDLnD?|}&%<3.4+յk"}-c&v7 ;my yID{=B.g~1x/S VyΟ *c V ePYDnSim8k9"Vx:^ k{dsoהW: |RV*@#iTYCp}UΆgE>GzASUAYuɳE&MB=9EDYG`΃O.ڔI9]n'sBSq3)F+?,}M kѸ=6=PD%jaAͅ0 EO@v1R j{H-47$r{UO -j$IpNUgg_e/ioE"dkQaL+"ѫrmtA%Q ܱAU2 z+-Mc6W6$YnFm5q#@Wds1 1UI5>d?xI 7_v4ϭwc сu;#eg%ju [ă4jGxh  nW]AJf X!ć2DC%Lj(Nob>sk L7cICҎ =Fu3Y[L41Pq{yk$#vkӦϮNaR pc=?Ѫ੻Y|>nm_xL9֑=ڴ9nG Gpσm0p̌%{Ew7淫rC 3~voD\0֝Nj[vPQ? 6p|hbbk@QYsT "7F5XU;b#<1!,f mHHH"T˪-FL;#1̅rJC.@ " ŲAaʰ$KdJZ f`peٚmD /̋`ݶ72 [!aV]r~ATeOT>* e I0>ADY'<ۏ$Z@9Lߏυ $V|)Zʏ1$qsB(]`H7Б'!9!{_\v::7Hefn4^Xn]qnwљA:Ο: ~;V:cF.zTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$ވ~"ooJAϥc^{I<Y&LTl>ɶs,9?##8$B22e4Qʶ?U\Pil9;iqeAGFmD4&]NGBtH>܏+f4]=Exy//QN<=݊2=?F'@ x3 +hR7j!GS4Bv_ }Q$ $.@t>-?>k-{gct4 @.g犂R&h0wVlFD!@L*huY!aTʇ V P&4D!b&@ydpźԅCYXify0\9>A:GB2LjL:o)h \O"n (4CtuVqw."  5BKIЭZtl/X_`æq8?>tc."  P54p ݪ cmL @7C76P]sCqyO, aH^t9^-Y>K_6G5Ӎ$s^ IU"4$.9`$i^2;IH+Ql B.шH/InZjD94gi)̚I'?6Գ)=&cy,+:%Q1@e}ҶYdY6A9 ͫb8>ֿvyb)ͪ7;hIt9ޢfY?4u;_3QKAAA#!A\8:PGgAʛY-sF/JGgA*ZGAJ ӎ )Y@$/A7PYHltD0;UDR"(@q(@q(@q\R%ZRi8.@Y ="c!Ըpi9sIHr&P+YH(ȿe&[{nyЫ{ϲZîJ?LUv$2BE)@WӞlz-֓Ys̭mϓ Pe )-a%r$hI$Y㮣rQba{MH>޳pHiS>+H$Hh6LttR0j4 *lKMWbsVD,bI4u0뱐xBM;! 7)L"$n$[ݱctK?ӲOu@Mo*$E:xN@q5v7#ΘBҤ/( Zn"d 7q|!$H:: )^0-n>!dm{y_T~05~8%k``3F=^!qK#AFU@t1 xh?t3#dNnJ;g7|D{4,FN`7- Tye-:c Pv sM~PfleRl.i5QA˺]slR86gV!&ުaVP-J VњP Gtxv@u" Py{֟ S qpA?b V؆$@ΰ-A @pcQ=|M+DY"ٺ !ҏwy@v:Ҍ )BKnBV" `Ŏ>3DWPhN׻t^lCŠi} $!I*C|u]| {?ϤHT{\$kOR/KDI I zuH&S*aYPJ Ď|`$@俪f$#fbTI/.UQJ24_EfJߪ)~;"q2Il`~TrE[XL:|U;Dȵ@m/q0<=bVC9Ū*]D/jN+Kr 76?v*"ʘ+(".@p7&F껠Jraߤ#7 /'X穷;Kj8^9w.Vmlc`)~?N|<2" лlYA]Y'HsW,d}?>;67@NDpߠX^Zt϶e( pֳgGtE6bf&e]v ^qD܏,[ypEW/z6F~3?K+6B.9t"6kz|t*R绎f8SqDE| D4I h\yr6b/@ ->]ؘ߽X*9r>b5%C|)ely ێ>h2v @X:LY@$_'g' at8JwE||VxF-sKeM\Ҵ y0*ƞ=_񲶜}BuTh‹_ΰϜjČ ІB)x2ڋtՏOb Zn=DK!!mJEЭLeX9m!pZ &G~;ky1fKr]VʙEM HUIr];P;|z]NO`HȫtL3F8( YstBc$@`iMYsYo-6L@zfE? 9P*ϕpLjG?q̈e8YA6pl 29-\,RzUTTׂz2S1O[$8s quh!ݩdߵF~h 9(@HWՋt-ڜc a;BɄ/!(N]k@q *~K:/_Av^Z?5-@ u69A_?iUz?V3+7!;^зyp9ߪђ%A_j['@.T) ] ֖ XLÐk\u,\O<}Iޏ R*X/Aja_pfK@+vuN!@Ctm@xmKCdM~!A.A4ƨfo$@L<6YqzOK5P]  ׁY(RPԝ"姆'y|nsĹ;~{.@WsoC/IT`{$$$0/V~-)PzE ͟`huc!Buqt/竁y`~`%&@*o < ]]uў6Aok!& /{3TxA?9]`_p2a'}NMt߬͠9Kq 2N KW?@ua?c\C.@^1>' e~ @?ӛ}}} i3{uQf~誰6?Ӥ]{CuE|3[¼зx1E?̂:ƆFtFFoNPBZ{ڽgƋ9Fful%o4^ M14#(?}e4|FluÇ+{!8 PO^BBOgڕ~_9=&{G/2#PeViFԆW>Rhr9W.zˠY6TfՑĈ86E)aF{n"5:恺mx)5Bp*/ +)M?ɍL&4Nm"L`5 ?B94S_y{J&7@nB#:Itmۗ ]M3l [l%бrpR\69DNhjߩ`rW.b.JDd]nۜDV-dgn^yV˃rZC%Hy^O~Hgnu*lTKݭnw2:aW7oY19kuqnU`z?$?{&@aY yD\ʉ5[Ek1]e ļ|0E` 6 7SPH4X 8 6@6q @RR9j?dJJUGyPA"sbDce0m=/:Vt0N'@̈́cP0erA[2S-|ҟ&|q:U.V]02 4n:WXDmn40;SF %A7L?+\cv )_p4"Z0U : YtF$y 4qPEDVmpsyOt-rp"Qs| w \Ek:iupL^7[:H[t+A6lHqӪ4HӯGޜP 7 j~24U=ۄNqC_y9tTD8y  ^ߪh<6}dW&4MrFtGnL/)C" weNJ-Ύc=GawS oҤvbfw9n!Wgة<wJ@S {]1Fk:QP-;t)%q:(^w gL{0sJ\MM.FDvv̿ н.ՑzalvK?_4#5 (C$!@]M0K_j>|Y$@w߾% Pk l!o*|wbTk5Fy"Lc\HQs-DFIibCItTiQBOzM"o_Yӹ?؋66zqgبƊp̐UKa[l Q#' R.E ǹYB~Jw㊲5X\\Vh1 uzb,@IZ&BIh)Eqfümlz+FC;UЌP yH;4'LȴaBrh)\|0gseri/Z5H# fTO`7,:I&@k[aWtK_ZpI̼7䇨Сj:ƨ=<:zS2F]L#SK#UuFs-4)+ ֵeV~yc Tz$\ =kp.2*&V#ODvQ]{PD ??M>]6ɭQeҺpɬy.qEܫ.;M7NXTI]nL)^4)Y/w%a/= Ow:<ϣh?ut(pu἞GںlG]`N9 .EV5l > :zexY8JLf+w5m885)BBsi^9t~p?TaJְ5o}h\-3|_=óe_RW! \07 T0\}nb bן.<G[> SjB$tsL\ru=[ -@rlk k͙MFn.pz f3XܞI\VW_MQ4~q ̡7|qЀ6)ο7E>lN.ut1E޾Vmsۘqc,k0C3YW?'D.@@G JOWJ -@?BHJ(k u1Ȅ;C`G{ޜZ7I!Ae>0[Ezp ǘW,zEӡ{ۆ H`Zs8G pQt5 TIq>1sāLжY!&%=8$9PAbA蛢v H(HO#OĆX P 'ϋ$E{o 9(@H ƛK=7X$<*C@·cOPL zc? ǵV-OinPo@#+iEw-R>`=m 6B\ рjy;F|]3_)B)x! P2$h#;Mx?Thxhٸ"]YNSo 5y7]]>3!}:O}.C[ꉳ "oVVKŭDCWgs_2gTֻ^pG HziX\r$ 9iF7%|1ş)|W*pKc7!~3lѴ2UD K1[I\阹Lk%ߘ(@ɏpbbE] #!*[fڀ3y&̏70 u26^Zf[9%&;,O%?HR .HD]+s8 ړ0'(}cn_6`=DŽYld;U0')(j]~~o rǎ w % P#au} $ Xqjy`r " jFp׬D7 '4G .̹Wԛ\ ^0_ugIKa!q!@tOeD__ann0x Vzau*a>/YL(@pS s'h3֟^FDҰR1s=PH4OiՑ0`' EJ~ā=sVLOr9xs=gcXC4=OТ} r&F|0&4ZXAG Zn3 h"9EQV/%?@)a8,QXE[ {X#1s-WVPRm!T-h /+ $Кwf:cNVZ!D[{},G 43~( P#hX؇NxŽv'nN8*tt)TN{fMN-!Qu=7]ywzF]̰98!724;:8 @&P}I(S4&{@޲j8ʏўZlLr& ſR7<~k<+=0$1 J:Ny?N$B}"nrx;Lth's;X8N$@8݊$ٮMJ#! q @$MvZ L b!!!U!Ή$^ywk'GFP1 >8]jao~YyB> 3>sug\yE2 H*c pՎP/ک!T>-QsiaikmdImhVo>`iޫbZ;Vϭs<}hO(1s\. ,! 7z`j.]r"p%O7 :;(@D[y6p=#x.'[hϜ9K9U̙6^O$)gQ6퀧sH^-"6 (@kRGGg:wn ЊY[]y؟Jrc! ѹh+((4:?ح2JCN2(~- f- еyXWi ^z|ER }EB0(toAAG·~?tnsBNӤ).cSmAA+ڥ1]-[/ E'!h0Ԟl*g!-ӶBR$iʿ:p]{]%y oӿ]$}֗7SZqC-,[gڒƢ%.9 Z^h=&tbgҍv S Ӡu!{B;u^2"Ɔ* 5i,X i?ؑ=5<˰;֏Z87dDR0v7`V&34Pߋ;L(e6P-!=2Ќy ,_w\qIK*9H>Rn#'4Dgq4DZU"=X6:4cS֣97/@;{B^\x1gFO'ua@7oD\açNU2(XUw`m(ݲmx[ e PS]]w1o|;J^5PVjW9ĕr+uO+/ߚfWVDŽ: _ڭ'[79iqr*%'; ӧ) P}!i!o ާ/ sׄ-,U .|NV MbipPD 5 >L h|Bnzx{ќ/_+BxbüME.0BBR1WL] xeq%@v$u+)%DFY?$)8M Ѝe'P]. v BKgRy Nc 4%*$Lj&`ØR ɻpm xa0-])!G8*T8{kL,HYPCU@W2[mcBI~?-d Qnu( P-`E?EMc7?ykyqpĩ9[]vqT%sU} fԴB>u/V٩.m=*Ojԥ֝Z1dڌTbݚiY&lA Jc4%w#xyV1bHۄ^])vX9YDhCU.;rw ͎ z)t֛祄0BZE(ߣ&@rvq2-SIs ?vhÛ#R@!mj|:qF:p*@D{ᒮ$}RAF/6/7 (;\L_ħ@t!/_bK PP_z AC^'`$[lDnq?dXF"Դ6 V co]m`>/piB| }-42x}&B#hU:+ZymtPocc_ G{Jj+wÃA`Vzô{4`Ca/iUbw/>pze"|"[ Tl.CbsSu9A*{|QVoG^WJWڄֆ'[.ڕtbj΂ E[luL8NJjt[@Ȼ^{{) t؅U|R]*{^6՗ٶ9P'S l SX*{ޱv4i@T\6 Vy*{m%AJfo=vŹ7-<$qtN Vi0d·Q#8"23K21;MBD~u|0[ @}×VY: $K)޲hmׯPnzG5w%s 7cufhlX }t7u2J[lQGZ8}ԬP$g:WcT>i3f]VCs(Kt[6E,Ip>ٷaᤞHѽΙ WSυǟmKTɂuJ>+-Ql5u/!h'[h`x)r Q6Wo 9WKR_n?n'o5չ`YKjبfI'w"gljǖ nU9G,tM[@VC,fqj޻nTțFf)U~ZKO# OF}yTȗ*c - 8)$(mBGŲ$R)_ ==֪=w rD¨;oĕpWq'Z%ܵ?*$$V?/oh܄nwwN^;o\v6huV?2Fae=ɺ* vӭy?;DG}AAC#\P0l ~ 0N-;dạ0#(( uߎ&_9 ;z/W Sa+o6Y.ݜuw&tvI ! yS肗KpOz 8{qVdw__A1~q{yVb|16J4_icCqMP 2{^57-#tyxm͏4KKi[Qje{jq<,hD6>Z' _qIqM+.?LeL}Ź=\3>`Y)ʇ郉(>R9OwXny= "M'@-N,bԗ]͖\ga7*)Āx1JJkAʆ08 FbNȳ*N</Qul{LL @\U(F!,hY mbI*f)hsrMj`=XЁduH7fzƦϩ`܎9r+2XIE O."Y0^l@@U_֗U?WULI&{}j&g _?"V wh)<_ Pk^N!q*@!J1ocE#(K!t>Vka*4 S9ZUZԈFPВQy!W|鯶>,ݞΖ5+&,rTY?TuQoh]*j2 c. @? :M&m|[6"Ptݢj^/ >ͥNVۀUhկQ rׁ%qRPDY @O`fr8&Q "z:Iv> Z}m"^і c.@YWu{.u]'qSXkmBۻNDžGa6/&AfPPㄌe݁TZ%6EM:UĀ$@.KW F>h Ux C [HdK(#NhݛȰ0r}Erh^!#a Ԃ0#}pyR(9>9 Gh{[|&Q4݄伫m#NJD6-Ha6!;u}OYM@E@OSZ5&@F?=4zs ^HCH;~S!%[~ANq&K s`DݷM+Ctc!z*LVrxU.L\~i6rG~RX6<]F(~n0 f5 f9ڢ"KXty5$'Af{s&6Le0&(hEMZ2t8x Z:[x*d64&61/@Y~mXl,as]8pոm03njM5ROy S*@{&O׸~(vscMO{GS&izU= %esG$ʹz^5&oC Nh&z|s"L59 >8LkF_4ܷFd !7|20 of'6JĊZ gu3nJU/2!λLmBGN+o0j5Uzee &Mkudm^%O%boAm+B#o3y\ErT~ESg#qGQE鷭tɿ8)Y>MKvr$7؄&O߾~q9̆վoλ!99ϯ1[0Uer^i -SN480Oyf<,c{OxoñĊA$u&qREfW;uax澟&JCx%GX"iY'ٌXډ/I[r=TlB QX+oQqRJMFt (R7 1w@_BAAQ;콷FOO쨨 񬧞]n=ػb BvfS6d[ o$[fg7e?;{/Y@Yz_XgOo{CG1ie2`g_eTQVm+ @VЂzsU(- su;%"ޣ~]ϑ*šc*-12b~Oqx'&9ğ5$Y7=l8;>tSﯞ/Π1^?9  9NjXZP>7mpm(sQ)& (TLHjib+h )C Ishg26QݡNL-yݐ@{hca=l=. xӱ ?xZ^e/0 Ͱp3@Gs؈Qcy5q2 Y @V-->[64 t JU('i?hA@ytI P[WIb&B3 @?ЮN[K'CFbBc~Y$YJ#c I=(B}z@ ף"{z'@ Ӈ&*I~#7 tHM+$᪌Pj32tؐEe/hA6SD}2dRN=|`ߞIoZZa?~[ {dߕzm5[,@9&#\>6ETYZES?[ݰ#^Vd\ؕ@s ?OikL75 '~IHY$1!-(8!1(n3srWB-<*s>}6/!U0OPS'AI}Y!u q! qCe0P11D j/YgPaŕ9|Yu a:ƃX%YɿKHBR5] ƋJufPmiqɡtQ,]B{]fu 0%@vw:-f?T;- dXC-0U^`X)&b?7 obtwY uY22Yq> %녛lүn< z=}֍?ʋg(J؈S(etDW Q 2@f 3H Lo2DH$T`QˠRJv%3eHd&ۃOK_ ^%66jŒ%thk I&=NBhxJ:I jlz]fNIi%[v0qޕDH$eZ 譈4{?+f7-Ѫ¥R+V3R$KI@U`b5 G8 S$KI@joy12Ïf6ohuXL?^QP݈t=͈ 1Q @goGU12꒧)FVɺ5lMP&TІk3pyHtP ^": cB?fe435j/;*h#!<; r@h;ACI\6)X>.w/&̪RNsTd$QI5m(؋ G3_tP +P(`j9|12k%|8)J84EK|e*u$Ov6u(3=i q*s@Q $Y8jbO+JTwgtzUƣ+DvmZq{u=8(ѻ~SևJY!46312D*^h.a}jL0.ڌi Q@֙ @V,Ą4.Bѱ. yE>. %?ETfm5cZ /U;U9B=j/Q5׊PGXHԩ|q%R󟽼9cRHڮU* v;ՔH/N#֘ϨڨS0%`dbMLH}$ɺH8m tjWNZ]Q.=T{S._}4}K5:j`_v WT#]\̟ @U1/Ćd ҉5%O PJj%&(4]ʀ eK`ٿVP 0ME,=S?8: QB'83'U윏Udƨ${ZfX^-殒=&tŚYWbfJj%&[:>|4ƋZ\' q A7Pxv~+*9c>. y [ ]Z+od ]x>@XZl 5X u~C<Ţm8yNq UjdĢ} Ζb*Pz 6"\ZSiP\ExZkLrN@U-1@m` @OQ^ mN1FԚ5S*~&%VfT" [w\#kL貢rҒdbKLP677V=UzP^?wOv :oED pLQ4|&4;0+dbKLPNop= }|h@Tǩ^7PemChLka4P؇^V ɽ=W8k]:-,, iHJ^dXTR1D @,ĄO1FAm&DK-HVu dV:(m#dEko~bfCǠJ  fA!*]e~%gT Z*\xSc /ȊŞLV\ہ< ~jy B\r&}5uܭVm,cb}\{)~[P\={sũ ϙ H^; ɌDUf@EOF}u`2 ޜyʧorTg4 3c/6fJ91U$ /]߉( +)94z?< @b !@[?Uwqnh $Ibb/;%_)=G)@thM,6ӂk.=7("* I?OwN3͍μ!Xq|?udfrURX-sCwHd)(xA5x4DŽN"i+#bf!JؠhW (ҫxփ$R%”f:5i7?,z(@ zl`$YJ t6:v XM~h*-y(cK_ƛԬY"D$K@#t wpqztTd (?~)54rS [orV.yth$H .zi mEWVTz._/~<6'n6VQ$K@1cK9&yrDOz mz!ѿl]솧 ZWǁ+Y!""1,*~Ϫ]< o.MqI9, &i uxr@VZ@K,ZbYMTU%Ag4֗zM3Uj+M>@5&>lV (N4lz&/'K}ym`7gZ ȞCHdq`}Ey蘑Cѿq3?#c,Zю,:1>GO.YpH~yim Z.fkLhyH<;1 @}?x5=)Eɫ8B[ll1o%ȊFTy4x=㤁jegTהCV=_mx 4:"J:- +{Nc) &$Т&$wGħCZo1DysJDW:( @VۊbLIhK@_۸Zfh"JVB"\SzN%˯W=ϫxO\1X)i3T>_h0Oƺ:0!5WF6=֜3yXcB,}ZppZa%î04: f".X} %-є[Pe{?6K7W ǻ|WNZaܠ$/*PP8ЩNv30ݶDt #T@BQRGRꣳ?6ij:hU-@σmLEgG =$Y€ @4Ƃ"p@O}5,:o @q9[:DG~nJ\QP$>Vk'L9u.X;Ѯ @U+ Z Q| xP>O~z-з9pTBwiH55BWS7m?<'J؄,M? ygE+ 4Ϟ"+M NklCĘHU+ .IVTMU-;<#T(J =4n&zq( (Ci#T$L3 \=<3ZN1"KhYBuV >B8 ^hm>>,f ?Vd5jF g @*_=f3w<U(w*9q}O>sK譜QIw!NSl2$YDJh %y\3'snXPF/{v杙=öYQl ~MoT{p鎋4CU89xMB43Q,)Cs]b=@&hP1tU@ $Z@1e*PMQ)f 莢(-T<:y1۷\04Vu, {ZX[+z -@9=WTf x"E/M$;"i(^ iN A5`i_[h]}m!=,Zb;E ̯Q4Fn'd^ ?&UR|}j;*Q݊Վ)?e=PJ_}!֔ :xo"b&S _] `婗/YfR@arjM2T,;/ŢԳ+3\w\kjx*xQhT؆iLM.Xvޏ9ϓ]j&{SLaʺ{#:58㘢 fA^Ŷ.Ԇ Ewp<rS;6E`z~KҊ@tz^@h2}ǂ^Pm=4S *a 2{L-L88mI{rE ]Ea.?kH oxD/rn81F p'**I P-^gHI@/x8H- jm@ ^޲R=?X7K)*W^.8yI^uUDzh9lvzAt#Z5\+Ű-&ʔao`+7:"iZAaPma.}RpMEi@(q|4=<@@T( Ix ۏF|PQ'B=&(7NДOI; >xq&{ȉO$?dL>o`#/k+^zK9%]LY;]Uw8׮֣=˰ o\בt!Gi&еE@MrgĖj"uzWlgơ \nxS}AKM_y^)D֞!lgRbkCW^K0 ~] =~ +a)٨3?F8jZ((^kQCXLzh[{݇OKV`0<'4miy74ǖl۷ REY6n #(UcI" GBQP+2ӎ8xax@\u9P tshK2T"*:vҭG>kZh>.d1)`yĞoX-KﵝE'|K=6E-H$8` ̋&h'2T_@aI{MHfЛ,zi&b!F#|[z=;(yy֙khP Ɲ>!3to +=Y_;+?;bڙt΂dݓ+N.AT"}C4;].yū~M\o=ů 6oҨ~^h,ߩHyɤ֡4oz"-&:47"JB}v> f%55icL@ZﳎNN}OxeN79/ A;V\5ЁBZ1ꑒU30)5]wu{&W.?w( #"ѯ؊S}$TVϟxD\6SZ2on]k =QrqzXDf1a%@/^3ٞD( 4R%UJM5 A8TS H&?~+ZL跻Ь+i+4eB Ue-&7,Y @MDgUDz}ZkQخy aj^ adWU4rܜf~rebBWQc|Y3@.[Aڭ0@h-E" @?uE*a7\:+]?fu=AJ- ʤHJDzu&BY ŌYfs/jga}ʪǞ.LXlӿED1`e_Sg TO[zvRB AW]q ΕP~~Z+u*@cjL?;sE3'2g 4|Elq-G.ljO'd>}VMR+;.^^Wwj°vU~ou(PE.#YЏǬ/7 wh7N2b£ƭUO{f3 WB8T%I9FM@oFg d M.3azhMn4?B#,Ţ/lYݟ]a;"Dh5&|euٱ} nV"nU1qĢ$Z&1: fr9+@T[Y1jkϗkO'B~.T o1T8 kxm:.X辫ߌ9CH7Q$ae U.;EK+| MBo.@CYPͣ#G/3F_tRfG& hF;k=4xw6't 8-Ε@@I9məRzO@,$s$CgܤTÙB;C 9@$2hK}" 'h;8Q&:-1yN~ ^$C,UpvyG D4\@h#ICN|2%NhJb1t  S8iu$ 6J=JՎ_V|h=lekgR@!~E}l_pzFogzvJx?{`B?K @$8mtup NrMC\SG.NiBǸ8T2 "T[:ۡ5I*ts'%6PGu% hĉ@@A|ͻd-P<H EmĴDyt_`ޫi˿I8&٭: T7s,\lŪ57n֍?S0N32 Q 8ψ )ndcG2t@$psp`P"`F'H%* q~8!Ý@dh$%: =rA•4| y ?d&:h6k!c5^dF݋92٦3yVd.1C.k,cg 64V* y~߳jg22#DjVch+ n:Cώ7j2ڝP Zѱ 604O( cЈl&{{*/nD;{h  3@U[m[l޴Qzu"1mSUKKK.3b%4;ƜWa~]3"u^tΞ1}V)baAr(V.I^mB5kEz#G{np=kW rIN"!|> @>7 D_(N]CC^HNt*Q4й  ~U1}* %o!/6UT h侂>÷Du=}͠nYn"TfYrUiVMR^'o;f$zXJOՏE:$#Ci u.drG|>z{` %JCivUEjU` q(q5b|@ i(IU & &&UFؚRFx Hb?N הYpSϫtnGMUw&x*)HJeld @1)$~5pu=+Pd#u(zȥZ Eh3w^pw?B[5_ ҧ!낛GGNM:a{v(e99,B#r7!\PX>գj3'C,V+.ل [zA`Po\_qƓ=ky,E %y+.ـb2'8B.xd/^ckL%4G2(㳁V5h4(ƒɟ_Mk)"#,B~9{Wti}⿔t$z^P?:L,.j>mS~|:R[q Gf<:_{s>[Ac}Ou>$J^u*L>[4zv&JآYQ\yT){K -)* -EMV JnĄqYfҶ) %IʴJ5mR }Rqnz2uOHe>4 Id)@ JmǫJީ̲O2 _j9[h6mH;mB(L*7نJg [GFX6՛tმNa `[3@^R7)N1+T 6yp{DmŠׅIotIdz] +-vG][@ v/(HP7N/u&Hc/?Ihxe, $ @@ >-àNnTJza¾uKha΀ A}Z2ZsvfVݬ I @8: \K}qwi8'/Aw(.B4+jFbLр3p\OW0>/C gvib۴Tt܎n81!tI< ghz&˃0p(;W(MR&/_v X挢kSv_e5YM51,{o+cV3.%G_{!S= [@u(lQ1@q/JA¯=J @ L6"'<+(fC=qzc?/ʒ0W "T\HSa9@`ߝzss=HOTg8g$%~\L?/N;uBRܴ} @JQ]ά"D耗&# '8T2ƣ`p y_f@@kT"A | !NZ%zDq 4#+pj.X4Jnr>P[KS)8="X׆Պ@{(ũ;fzt2#z#.h^@(w{ĒF ^jТ+g XiV9&:z[HR Ms>w @iQ Z6i^ dW| w'zķtHi`USqZ5ȼ%%l鼦p=:~mmoDv 8PԞXr:$jt6ZSP,|ñش"cgЌE$ u[ b>BhY] e-2#wW|h܁'x4́@;9Xqy, f:$i(#.LG+ tqza ]IfWalUU80th =:L%q`%MEF]FYJF}A%0U⸮#7nzb K5Z㬀mJ4;0*nJDqJz?#q}b[9XժE/̭|ѤŞ57ˢ~*m37ǢB\P/fLN^jj!}*J@H{a"X&27 c~^jcZ…,;=&FoQR9#3"[Өr=¯x z'@'IF82&pVx́5\%{:/Mˣ+n5U;sag*/=o70~[ntv ך-#ЖC=@ZC@P<: qԶjUí|;~ }DIC'dKEa7T#-h-o)#չ΢][ @2R?z'wS 8X7G ˾JsĄ͎l[\xS/]0O_fIWH ociDdz.,se >% 2+0 M.P3tZ,iH2N4A@1CQJzr]coG,.@r\` ڥcBOrq*1ˆ+Zz.(Vf 5h-`|DJy;wID/}q2< .XHՕLyl_>=wuNg)_]&#M~f34v}rb>qI}ޯy.l}x[H5H [~p }T1 yYcU(͍A3F/@;8|s5֠W!FQlmM;,@~@_ao@MAؚfPm%V#$_ -/3NfJ^8qNCc6x^/N& @^PokT˖";VO,}|dvYLy1&U̟_"C8u #6p/uI ;Z}>5iRwV|qO~ȡu KF%IĖ #VGJ>S'S%&;L}<٨ColyNQSOH}a$6mNF`0.5Zk[~^ ~^!w 2Cp#K%ixP6h&iM@e8wUz]@M=Mt. 0ЗBh/͇2)ڤ =eۍZqCOy_Y~C,mgW1qdKpVGjR1>~t{ѷe,V=\uRڈ; e(ͻ(MW'@G:byE|˗{.΍k?5q.؀#ũRiTMNo3yr A d7~͗yj#)%jDV [znpꆾ\ֳfVE"b.?N|$j?E5 GuGoN1-"GPߢ3~J%3qLS7(GV iW ]#@şnk^%wڥ]! *ڧMo[QNKE=bG6sޟэ=>tIVu3L,I _ͩ"]STo'jRJ~xp8Ɖj F:qLSHZ @8{$qg@HJ 48m E]Rkb僕Сl)5{bߪP/w&;UN 3-Ykk/yK/\qDd)|6CcJñܞa+Љ@|4܉/8$M+qp@$`(T$j;p;6 DA8po@h먚օܳnŽZōFQu+=p8#{̀~=sW ^ b`(Њ) j  7]w$ Gc;|=Y]3q{7EP&4K tJ95h{ܼu.>6Մb͊o}oef_Z'f Z.{>^"3 8*Ac=T&h!I~&$O #W[s˜Ќ5.IacQhUk79`Lph_3RKxWqWlY0pYX~/Z0Xp@@}v$WXK@*'){e+ժd:5#6o m?.#>$ Ork5HyRuri {oXA05/\r5sn|dIh X@lLHoC J:mRu@a!h/EG몈Ъ&(:6 ;M&„g*:\*oIqϹ ժ<'=lw+(HV*zNV c F9CJ`/vr>|qnQzAF΅zHkd&VVGaL O0UQٵy\}g_t'iԥC^؇?N=eOrl%W Gځ9@^R&{:%tq].k#!jָy$TY/=%F|-OZ >#6բ{B;E)v/8 o[nxz: gդM&Q[05fiM HA/SлPڪ a|a+nED?ߏ͚a!Jp{r{8G%2d@4.*0eiѾjevh#*ně=2@>LM[d`ؑy $_' \%::E~RE:7*.$=bSnY!3n` %J$YrV<^>+͌(®bk1"d|Yō ) %; +LwIgxз-Z^h^EPwãT kdNr)T,f@uߜ Y@h y2cO8LhXܬ&& ̚EǕhD#eժ{˛0Pj2 m#ŕQ&JbJ(nx_wOʙeJe{bΣ7:/Z_HP~s@O3<}r9mr%L6ːX(o#rĭ>lqѣ^ hg\WkS{HbpeZ/4z(p~B.AH<== #f{ ^.3,(9t)4,LP"|܎ J4kaj`%؆ E{dCrU tnK^5"(\Ҏ~>rJlhhׇ.C zd_^%س TTppY.*Zk*̪U$h;v޳t@1=VϚEb>Qd?uEQ:Bv j l2h@gY;_u'__Bf(0ww=6Ws Pm`Ű.?vb>m !cYVM0+cM3J&Xەby.4e9H/,|`iVl7!BR@Hk)䚉5yNPP} r];#" *ZMx'B~? ;1aS\]<+ Љ+Ч$rƱMe Č.`[DefIw3 ZBFz9FV+F:>`U9yRՅb"mmp&db%O؜K@ *4@)P!Fkf4jb?RP >yB xk2@)HP$7 u w}qu(&BH gOB/!-딚),Kb*! 8[hX|{^0Wgm@9 ۱=kc H/RPb#31,pmQ-7Zp_рy?U9KMWcV(AEB@HBtM3" ffi0r.W.'qI"ۭUW4㱋J4{8;- q?.N(0J@dI@ۤFBf2@' SN cB}_8|7/)4[i*;Z4Q2\ųl^x4=pʘ}-1>8Yҟ}+k#΄&S מVhyc=΍+XSC޿%,0P[Z:S*[`AITH*97ݯs(&/rRG-HK2ЦzaBTxrF||.,M0 LaNENԃFqwz)TJDHVTmYiIW*C%AwvJ;H1{ta5&VI1ǰ H$-dŻ(c#)}CwIM.hA#=iւ3jE?ꬒ+_)f`eqØx֬]=m(VW'4_z:[ o< TTGֵGlt/Tۺ#+(@lpiX kgii&!\3碜m脹@=X"[Is55hr0)/aOkkN+4L^pY5Cʖ+C;|;iTw p1I?E2k6d-`S}sOo}1Ġ R5ŗw.0E9W_{Itv8yzSG!(ؒC2B)oHna%Ʃǜqvy~*K̥sĈbE60y^aTmATg=>wl&7DGRTEހMꭁ|}sى:Łj|t7O|}X {rTZpc @+=Db ]bD @H[oM8 ~ n[W$`vR5C)@aa~l[&Ƥ"L聻ӯaa3@Т6's:qBBu!!v>?C@ h g~(q}2:RdCMo&J Z ?*y:F S$qAz2ZOY'`'з.C&%П߄" ΎO_}#* KVucfS@emQ;F=a!,-J^].cf6IkZ@ߺ "~p}~"IQܶ][3==Ĩ`z`Q# 5 @GڣV6%E4-z$LzJP'J.|awc~' 7Iн#<`9~T@qN4 |3aG>LC^+_b](nՠOjh24?pvP\otc0OiX2 :@ {H(ɘQAITqOY^8L΂ix ׶3e8qݫ[q.rc}}ρX${4wcU7eky}/Sv{Zͷmv/GO1ںٮ53?]ˠX\6%kCnөtV\ת}K+7 ny#zVa)vUeI6^0ѬBEnM FF־^uoEF<&,ׄl)5GuԩxBMY@BO7c"ƝNZTRI|-?=+&,%}{"5bgf5Ȥ'9Jwɓ,~M7N{=*8ҧ:"Ez1[cy%ڸO#6夳A5 d^0#iS໡yh1 fweGPb@o@D}`cʣe2DF<ӦŰ$,@o@ay&lY,|}&tcNJv9"sǟ-8B? Ș1@3O9L_rIt)|x+{Nh/M z@ů泼tqY'VrriFQb_\})Ni:4iTѷ#dGǥ-sLضPo[A,oMfiqxKU{lvm$3fn{l6RݮPxfVJVf'J5kf5y>[_=ܮ}y#-Ǭ 9-sh|`X+C{U rG¡_*CU*Ibg(Ȥ> |d2±YV OTq}-o@ˊ@/k` p"!}qM+׭S͓@Wz e(J薒p#>DZlYH@S`lfY6E3(;΋,FX$aҒTs''|PxMz,}_$RuU0@dEl6TazTfkcpQtvSЬo@l-kR-49G/6/&G4%Iz? ͘ @z1-bmbaV哟9Qhǜ86UPw*-yJ0ld@М.;bL 0lل F-unXCȺ(|0Lo Zûf0!V"*&12ak&֢GuM]4]P\g|}z P${ 🦚(~-VH0ŻJ~/d(XƁ%DR_"A(_fXr;0 B1 !6q%gכm ihזDQM,b"eejBdA ;9U/(7pD'?J@E;A\?њ]?@8{`4+Fm+b!V H6;ubFc0}E@j#quzȸ]zLY9^z=c R씏,G+ҎRCM3m @aQϻ@άbc=\%Ϫȍ[a?.FeVl?@aB}ACrDg wG؀.hd]tu@ KfӪC^4cvyRu9w*r@@۲9E;#n==,Y{B29tQ,i=i[$Kse2-9y] Bcʦc!y3ƫOԊ X aRF<&]VT ?qa(y<4 ?yBpQ$(㈪t5X k,4QߍOGBI9lS+gH BN|KԽa5i_Bo|Z۷ 2 Xlv]F^Up.'GF`{E:bg#p] žbMX3~6\H]u $34y*66ҹ7}q6,a +~U'?u#p U^0零̴sY&m2@'q~1{ 7ާ{Vα'F<.(b#k7(3JvY2Axćuh5xKMqN08by ^mLc-F0|ңʐu^HvV|.ϟgbRT3>nT+p}s͗b6؟fT65S<}060{kV* 䡄  ?Rʉ'e-scA{qC}h07j\@XZ} I&yECס9w)NԵ#S 7"G[ຽ'֐PC*0GO`3⻃}—4AuxȕPJ@ǒ׎2)ik3_nF_ J'pX,OW~5kJ=u1ta`FVl `a:mn!qm/ؖҴ' wbu^^a P^ eCe@ XJ"Ip%s.i&Kk=cRMOI VSF<]XOus?4*k9-Hv?)snW ^#:Ί 0M,ng >Jq}J@- W.fK+UY-Qlh wh#07 hLeɈ/@\f-*L4 ,P.?9]^lih d]@v JpxkϯcwMc3u6‹(65 fz$ֽ"m'esqeaC^ø~%!,Ms@~ǯDGUdta'zB a(d3$,v&#$!l,tzu=)+B[uÞ? +_%0Fauhz,n_XA^sު̾[dwh[Vldi]oX}ᄒHGl7?+ٕzO߈YkM3Uιu.YC`){g~Ÿ ekt_^Ć4gBN{[ۡDŏ\ӼEɈ[Ⲙ88,& .!""=3$"Ɨ"#"RڍQcSJy e6v{;9ӻuwP.P5LGs@*mL5;<.JCLf@+kjyiqY M}; mQˮAi3r-2G@\eS=i D$d8 @f(= Y2@[ߑ.Lj.cr@.N\}qiݧgu" '}$k-}1[A?DzW;Xy%ޘ4ꤚ]k6NL??D̳yd8̚nٹ-^#lB %䂬l+[~#qm~ f<*} s`>sd,7!cUU1f~Az{u#?ӺNJĽ~2J/DyGz):趒mnT@: ݶMW#C[u'd>P[&w-'&MVV &X[Zex6eBz˛en`g5-"V /Z>$;okL2G@\hB; 0}k{YaiY\2W LfAo1Ce[+B/XRcB;;. 95|BWoHvhwT™SC$_#N=lC5!Ƣ"Yk`C0oȽ U-ɓ\N-oI @jB+-jT1ėr}O9H JWu[{588SZOesZ2?H?L,, D|SNC%fKNtEuhZ.) 8㺚`Ә`O*Fjܭy1]aPS.z&A'iJF7|E<8=B ]hI01b3n57y7Sfm(M,A]xS,, .3tStshwlj4,WEJ ",M8 '4!> @(01싏|Y)"&$1nh Ƨ,!@{ \$hbi$x| _ ]h&w 1Ӵ4hEI=z9w N@[UlbgΜ|bLY9/3#dT""}p]b,v$a(34b2d6_rky0h99Hb JaY9H ]h"]/IĐ(fǺ(H4Jڙ}!hsSz 0z$ད F\j~;gb=0o-:˭@YFehi4 AJSn]pEE{ Niߊ ʀnT&V W@dpW~m4Q#[S*g5{*mXq m6&  C@ںAa%yi,qF+҆׾c\3 {$-WSRSk! =mtI }+,y `u@.Է`zCv&@b0^WHYl0zIB6ꖦسm:,",=/@@?1ǚ P*Ч1* S|}f@j[8Px?3.{~Uu &+u7i6%Cn,\kE`/FySM 68i25e\aH MO/EɘPv*3z 0}X%~9)YC67hK^,e?Zg^;͘EW!ϼDxnc"V=D| {Km,ӆ53fJ(iju*fA(y჻{`E.]p4d l>B~!!>3]D:E|(E(?,!!Z c8!AVc"YEWV Ր|xe(42 8Tv .TU0-6#p"`\~ ̗qGјADuhШd [ z$0o3Mg]q]-֏- Չ=<)&t1=g_ezz@ؔS ̼HhLqPA|99j`FR3z+u.(Lm jߍ$ոs]s]}=XKzu]A|tm_7鄒6ɮiǥO5JrƣξtvU ag"k8T=W A(y,VCrZ '}sۭ^.wv+Ux3穗69`՟-ha\~,bh5곖>: S6L:ToQ>2YCX6,}<(|+ZDۉ89Y™".27h#?+ -e2Zv]Ͳ$AY7OZ<?kkDz0&Ԁ\Dˢ;.v^6d.>UȈb.נK6@_4taS@daOa"ª-/+o.[JV' z/hy_&)W ̚vS]ݥUw!ԔlcÓމyz1UԙK0;ŭ#ג8$\sO}0ǓET߼w /7cw˔xK0**iSAB Htth)c8h#1b/' ֺ!{ [?xA, Je!i~Cq] +tEB҅!r/P7H(5\a6]6$I3Ty'T;a~^E @3X{N:Gw7-gqGD +Y/Xl E2 -W¡)5fSURN8 rnPD@DrL;zMSJ ӗ/x\ ŧ@N. PJtqYX4$! ߤ)P6[Ѓ@ v970e VK(@81qgz;]}4󡾻ԅ&OuXCa$s(q":^wlmqZ*&}Q`#MXrbCIVe @#ά3Qq<7Lq?kre8ˆ Z$<]?!YiV1b슶z ܙ(6 ݅@OIg}Ӫo#X kЍPt}n 6ֽ4G.iAk4]a8c!+Z3O(D6OoȤ!դ1s5n?[j5k'ϱGaf3R5 8"7fcժ8\W68c^PlZKvR;?9؇sG ~wE p ” @Bj8 5@'QIuK8I4.@\Z]{ r؛F -ds[yuna]ch$V RJ7U\~a+H3D=žrUbl; ,?XJY@G؎Xd'LyfPou8uiy0iIe(ea@ʙ~8  h^?Jf4`@\5=Wy .q(CY]tcmL;p$_t.P*P۱1w"Ɖޢ+YWŹ\IU5kS{}A u5,l=ArQTzH.#% qJ Ӆw6w6}"3ƺn ^=P 4U0Gڃ7ϲyᯊ,($??l<;HY^#Bsc͐K#(Q*ϷjM-,pw8E~ D}'%}ZP$eur OR)jF&ޱ/V$|*TEbzQla u #tF<>q#qTO^1)ag(5h{>FYK70s~#kdEV̅E B4SU/:.PH+Bl8,%hpk_0S+~Cj]#ȝ|iZ\,}g:#v(Jp'ܳ>8Wvkѫ ,!U;'Ǻyhǚ5O dž\yA$ s, }d4~Bnr~be3Zйr:2n<3#6K_ %EtIMoeʛ1`w#",pfgY9?-!Ay+<^++)$Iс׵C|Kq(qg^ɜ^xjOї(~dO곐vIxL弤Ilpxћƕ8C-}!fKtuB`Y;z)B#R60l5 d"q8Pm9ZS|Գf} ԡ8`5 Ҵ^ڗ8Z}Ŝ{lqFYAK_6 3d)qއ\u&tqTĈ ?2t%P0K.Wx2vKRf%d\~BA^@Byt?xߠeb۱q7|J3bgh݃X+N|СĽw;:ьc챆3{O¦AuAu^._MgzÚ^ ^S(8ׄ)ryMljcC]_1#ta|h~ڀ"n:pQ{q.&  ?AA !s/+UYA&ۄFv \&,/_E&iS$Wsrأ;*\o4Ԓޡ@˕-oRoF4s*(Y ѴR-ImΞV͠=UB,5'U5(YZ"{W R2qVm'4"P8ر+Re.[t?~ -4ŀFҎKǔlHQ@\Tct/ ϕuU<1J_[Y>ʆXh"g@ɫ`c씐W}hi':_X1Z/Y?Yh C  v?ƺPԍM2w8[[+cP]9'8 D\NՊ@+c)P]6^~q% ed8GKcft\GG砗؆FIqG!P?L~iqq e.w%Si5[&#ƥQ83 JG35Љ1gd.'Jo"alv։ 4Ľ&C!PЙʃGe!Divh2 @O= \rnx āTn$.̯LރP:?P@@3 Fy+ 2S۵8X7<P]G(1="S.`5qqD<*` yL,D}֒3sXo@ uia)'z XzܭZ-̽ò@w!7kj⃑e`IjL]8ylK8M,(cu \e@Pf -x9BUrkQR 0QPUP3k5GH.Dnf 'b~eQ XwI5?vxC@Ob`y?16-Β$:&\Od"J ƑXOaHZxEݰjT>8^DhMTT5L$qa*F+(m2Hޢ 涀>PFqooO f-i"S$95q/4PԊ.p:0PEHD.T\0\7ls>QQښC1B9z)$:*>A(ۘmx%{h*V F8M׵Xii= JԊ%r*pu w+8PBNf'3#qZxZرQbo>։Aek:{`-n8L>4u17$eJ'=(xB![ղ)6ܻW/[Qf0In p(\e}K+M3P& d|.vGx]̡J}$(%ejwmZ5;fp{"_>P[;BgB/&ҚWcؽ1>99ŋ~q&N=U#NRx_tNEGi 邸RB~)E"q—/\ P4܀/YqqqS%k@/?ͻ|g3 /$...Sl3J(+ T@\\a^/wr!-Y{͍$ԾlG&wvWBq[ȒV /r~|ia1t%=DG_q´ 9%]nC- &+G{Gެ}!kmF;}%kK?; ^4,˯eRn{HW qrlHV"dlk7lEy`}+;ُ 'CIө h_hr-kmKKX#[Bc̹%gKz_"䘬*8;;mZ.TjOeʞ9bQy:l dOp& E *qfV@Q[2OFC۩FYޥsp/#,*#:IX_OJ&ۙ<! IHUFrE# 6D>xB6Bն䑋#Rt9QXKzbD蟟.^1ݲi$mXpj$Q` ]/ZZM9sħa*^<$d|Y]A,R^=[_gN Dc^^tV$A#mIٹ gJMx+d,]!6 喽IDg {Fpm=>:TGIr`dzDXh!]΁ᄨybUY͉tX".'2) lHDzyc*MR'݆[o,NK hLĔmВpqqeZ?hgْ C*3 X"/#nZ:N}\;<7ۡ)AaB&QNV~] & ]/6w; #e` @%xBPcئK5]&@\\èV$ ,ERꠠ ,#lbHT΂Aݠ+Й.zcp5c$Նh31%oDsΖ<f7;0L\}68vDO@\\b}QkbFoCy = @V#H@+sJk;<' w8Bm~!)X9_}2; l0XpS:+ct5nk0_a|+19Ӛ*X1`ֱQRQ,*wZm9(l_zak6a&R)h#4—YI]H06 @\\#>kkQ6uia,3 EԺ:)ڰ l4AuݎE-ѱ?!OBIs`~hyG"H9Ph_9\خ&.]$LVeH yPsF;q*ůp1@ZV VN"P^(ɖ2zxpto?֘;HN|G'!PjQ_rŵ <41\rYF cm'kBOR/5:MDP5&Mնva.Ig[͞Ozd+Xg`B:X|d_U;V;: E|TvᲃGBܭ~>Nmc=Le%*;g=s;WLŕI:&L8v;H %M=w=Hc?'|zpDս'*.{'o_QcT7O~HD31ɲ];黏9w܃sqqqM>NqqqqYHA6@K_RnQ=Upqqqqqqqqqqqqqqqqqqqq͈G2O/#""%}"'(f=h"/  duo{H6bw*0F溷;Z Ls\\\"o6RnQ*D&DA#]`U]|:+=t~-.a".iBt8*W:@\\\&u䞁\˷:LC.W+J.?!\N+Z 荁ѿ#}IȆ~J.GY!4<^ԧj/N 5!&gKؐodЭ}[/Giਃ,@~>A/i|=9;=pz{7kxIOqx<12b!=&W5?v yJC L3˸Q.?kS_pqg4_8T68.r7vr lz%+dPIV &5[TVz >2-殳|~iO[8L8uQISɧ߼0|M [ oϣPB'7M @qփVCH0l1-:CwUcø h>6%/9:B}N' #3>Uf: lV0iS%OE )VHHo+wڃ 'xo\uUxΞluCgzvιv!nPE@vث`Ôv6~Vfr;E^X*9-}~A-%to|d amK2x,ĨgM%V8Z<H 1U,0) o"(1Q,jR{^o8/]fWu+f MaGt^"%a7NS8M$UKiRl7!6`ĿBtdo]1e<24%s$'5.p9ÜlsaC.>hh _T,m(B&6>Y~0݆ԇ} @6T %2!>#*c=SmJAaZF4c1݉XA/6_2B4 i9fX±Bʥy*ҝx~I!#Z |R3`=h϶W >Љ S 4mqI @۵!i띃L` N5l$?\fo)wc @`Z6#X\&e>#ITW j<{Rq}s ĬzqGl5ПЊe(t]mٛ.kRalKvx,pI-׏d5M ڰv#A \SُsaXj .?sqqMH ,H!Ok3NYtyLf-]T+G<7NYxf@DŽ[Xj )ݜE`^XqI-7 fBt#{v0a@8Z@+K+":) [sf\ 0"J.JWSr`/"q_;ĶR֋ VplǗ`yFRFDCYJklcy:Tųht͚5+G8:{GY""^ȃv dJ8gvp.b \r,# IY0>~ E|ns-BI$Q* ;c&߁64Z<K9 KZKK<Ǩ5EDoS.S`5P y(?Di*v|l[ {~N ʎF?8V@{lXQ+zze7j!c#uwwvNDG|B>uM^nZQl yK3-D t}>ױt?j1< eRgKAge+޵k]bi3.3l*#%Sؗ"tp/([Ѫ 1VB-|;a\A* 傼Aߜ,Q?wlAww*Sbp9sC3Ǯfu 8Ln둴23 k[$w(W: $ѱn^aJZ?= s;fqցR<)xk,։d&ŸɧӝSI&Gk> ?L?SI…ɓT7A (" TFIWyÓE!.Gfp5;GF';b(U#\\\\],}\\\YqqqqYH=-}\\\I(ReIݷh_ݖ8"fz\ Wu: `DWnΞD\ː2O>`chz\ WuuzK9VMw4`C:+5NbX]Y:"9 82d0miq"&s\\\&R"4&y @=gwKWHų@^B$T1фĬo1N$ Ar9:5N._>ݛs: ό鯉qrzaKszG7=C& Ų{M£[te }јQn+ͯ dBP#k;Ė/D3jLs6 P ͩyfou,4/4WZ!+AD @ DëSS"bl++bGP Я+),*?@ m'54X$eRk!19Pk%' - (}w(0;Mb[n U|1FCR0jU .E C_\؂Ff$1b~*k}Ǹ@3Fgj kpW0VO|Ls؆}Ǡ:QhU_͍@bX#\ۛņEۑuՙ0 lҔ5`<ԥ,}h͓||Ʉq3Mp-~,=S1ShQޱXo77~͂^ @`%}E* c\\\U @D*Z謥y&(Uo|}*>f%:0hQ1[@֤)Kk$S+VB}ImϲVz\pTK8 s, V &T6m5K΁ <w 2=cq, 45[ 4R2cZϼGE:Z.zx˜}{JZ h#C@Oyt2kSB\ a.-.(wDT< hf<D?7a/KH^l@$gO@kE3v{XJ1h  uLl$9PaRS1j2Qg)~b)(D~ٜ@ӠĢ/3Ě`$v0RYrqq}WI"rZM$it-v҈z膬IK"EgѕpP\A3WE9 E+~Ś(LZϑtj~zb,=4/b=Zi6\F|Xgq#K16T\XI>שzqqq}%WO0!e y:M(_{om2' G$IRusD2Hbg'aru tqx1JR\>N*IrCE@CUibAh)9>8U|!" ǡ]kP+0<͢*)IUhTCP,gnr0)fC2VRtvҾZMyY$j`rpqq}_`kuq~E|kcV!, W9ܪNLphYתyOrZ3p`vUPLXn7ALS8 Q$ꂩgAƘ3{u|UR;_B1$n_ϿB E_Wt"`#N-%yg?*qqq[ڄA& 7  e~taT=hKHx`*F/i*M<6획 ЉM=k:O G2d[E=g.meL``p.n Ide]0 `Rc+`I\8Oc.Q\YŘ&"F%b1Gy@䨑6ڰ7&Xu(!\\\?R-DZ?mwqe@=U @qZ^tPG<{H98@^j=B=v 8>-yZ};0>'h<PdWc2*.},S*%`b68d <ը Ǐ$cJ  4X/[z\`q _JzWI 'a^ci P4.Ln ?"{jWF2x @sw@c(ns@q@7]hEȪ+)\ѤP+qJ'7yC:}qha(I ?#胻@6/=rL;fQߛH 3Kgz; qqq0}1-ALTQ%0z.DLQJTU $nJQ-~z $dTI:ObgX{ e(bDTM"$vP%BKqZ%D$qC-* 1fHB{J&dHJٟ$TE`X,(L g4^Vԭ#]3~:FX j9i-I$@Jθj!vd N{ؾ]ݪx:n:NlS٪=һW&zim_RR}[\i.................Mק !88B, >du0s߲;ׯaލ4KR ][mqA`޼x Ux.kK+>6L֝O;yYmWs =뚾]F߹\\\\C-zxaK:>rlBCO)Ƣ\H ~^4 g8]Vy? i]a\hKR>.TPIN4BTiQ~|vz 5oPA(~Q7>Н%!~A pٲS2e hXaPYe?U܁O)P(njUE.P(}+)) VTw@ ?oa)3ު0%䯆u<8AR-Eva"{da ]mUw6} ]JΎe+~OgC]]x]=GzȊn~WM=}{E0-`=V@{9 螧.F^("٥TQf&ُ&/txQBD%-h!坠PPM^: @neFU4Em:#VhgB*-}tl1*!\[ӕʫ1h>4s|D \f\@`@Ɔ_ XCW(-Je$C._-Ӻ~& 'dvPtỲŠ)C6ҵ2j„s } 䥲,9U7R{D#8|Dͯ1"8ax&V++ ^2 Y(2Nh oa\cvphͮ]3^=S !^j++;nzvp;l 5ڵR 4DEB7\hrx'̃07_:Ϣd Ԡ3D@H[" F{"BX0ʏv=˜uH'₻4/wV Fje[$&eugyDczK_>0ӌ @U) 8J ֘V֟`,Kk85 Fv8 Nao xlLgMQ@ )ALd u7cddSbt0nN,ܰEǜ"oc'>,YͲp {=$d0"X,2%b ׯ+ 2jnY8^2TLd{(XՉ@kAVwIf)ሀRC "6ʠFѝrMܬpe_.7cb^pB!V²pP/6YFi+Ԗm,p~>+=i=;ԁɸ\uxCh@?n@~vH_={ j| Xz`㜝Gh5璬9[0W11EG`r)^5:! )S:Q0/K:yfZQ3"QjXJɖhrTZަM 9Zle){<\aJt-TOGI"xÌu+l7WƏHtf+'%EU(>!f8Vp֐hz!> >g ҩH*==({JPMmJR+i[P\h +A/4e'#\\L3E$8gK:Y}7-HI J&,V`;Pzwكti?:M pNR̍}>UXOdgXLcC5~Cl9! fq.Y=e:}M(JP,/ k @IwD"ݣc%UL" !sfl qU%xNڞsJep ( S)D:\6qv{2feJMl3 (@[Nة8H}D_b3םf'Խ%c i{bH[X/W!!t\2u:뙼/TP-PP?swd8 8<L[&B8XwP0z * v_ox$ EjZbIplX !I3WؠͻP\8} %Z練3zE>3*q6`\{淲*2V8Տm,׿B._B<^bεf%&d,ݕ06mhXj7|A /^[՝kXyIo&+NJ>wsoh\Wnu7%9sy;][1ꆸvXgIW 3BpV._Hz^|YxS%]fMFolt$%H6?I?$z~F(\\\*RSTpp&!T$Dpt],iMppf¤ ^+[GeUe +"yAF !=@Ma !-It$('{=#눱;2TH͞0SϦОNGb<t?0 㛗fi˛z/4l =82=ާٚ)~e`K(j @u-k ކ^bX/h{i'W< 3f Y<g  K' 5S2%/94]llЩ+b!ɿΈgQbCНj(D20}OtK ծ^5:+nJ @{ht[""T(0^dߊMB,t+!y( bz,^87 =yIx5oBѓ~Q(b=4\)rC+B8GѦ'ؼELYp8G*#>3 V(heBKhG7]޽Bdn+M}V"WEt л!J<~&?[md](,KΤYՊCM?F'P*y-Vb6Wm<- KzAyגZ }$%] p rB ߂w~BhLűM0sMe4G'i,?Z\ KeqTbcN~#z˖OheTE>z8_t}U'W|G3]#2mN̵bL:iJuZY.V5u0YZ<hHBȺhHe=?#4(T*U)}8۸~ ~~4wS^uvUT꭛J%̸zD*RoKm/B,G}ey]cr&bɏ5آywfڔ%dhP-r̔^Բ~J.Ar}n _se@0Pmq1a.:Mt΍U0gEc4MAMP>P1@d- _lN N˘cuc, X %"W( 4>it/ H|MCKaf f2 kG@ϝ`o@wU"nաkXV\,tN #tm_zrB%Xᶩ"~*oP`8!ڔen`@Eܬ4yP1ciXP1P<ԫֱ Iz `1g74al8įh64]A $9)hk@aG^n<`5q>\5b[m -'2$w`=CW#0D,E!X`V'(&;rWhXHhH"l0jCN!fX ؚ .$ %!KfPj`M£ JTP *"wI.ޢMdK|_9(,W) xKu?;{ş>`^م_όa]Gjv onfw[ g٬<Ԇw.@J&W0ORQ[9?9kcc-J/V['e H*]{Nb@L jueR/Ďڸ학~*hKEQtHw8!;]X[չ`΃9v]L/œÜX5ͯA[ S)Dq:QzzZ$^;J3m .v2uBck@[vO"8);H@`C%6zs~k(IKp}YcǙ0S~䲐B;V("\";-F$U1S6e !8KNO!kj>Bl2|&3Ns>/*=]Up04 W͉m~0 !loWWԅr+7% p5[yƃt"mt|ݺڭoppKJ m.-~p^C=`aB8pc1uGPX mx/ ~H݄[<~]mME[]7YƓ_xN$mjO< (†~e83uz=5 M>;!. yLw55-B4cݯɭ!${o٭K~2!y8YHFG;q˜ Ypȏ4$Hr,ÖtłgͶe/d,9<.K)'Ir14D4xwMwϦ?M8!V _f:$*G[u)7wpqqqqqqqqqqqqqqqqqqq ʄ1-K~ӛDh/3N+ټ?8xU3[|"TdkpSeUw(wzq2у=ƃe4-9/]὾ \?fLHJ]|JGˀ WM?!1˂,Z2tRշqڈz4qi[0(wRw_~M+wkwYKvUجdbHW|r5A a烼ᶾ Եw3ʴfLH[5 ,̧^ipit{RBvDnzg B3CXE.M' ?lnszI+~ zCQeI omf7wzש5@@@Ѓ}xjKzg!>DQcTEwEc“RG,9-0Z%@)"R6JW h@@tO "FmTC׿GL@Dri LÏ],lf \ D #zWI8}a G.ʢ1 _'2(~6>2@`~sRD4~6qwʤ1a:R(ήP(ZBr9P$voRm6%[6h+(xg%O?;6Ԃ,+k4JXjH Ӵ.5 1yn .]?RG }R2vĒ ]'5R+ A=bГ>~]˹W.+ P:|!qioo9-wiu EoK8k{iv>iKT ) r} };+l;mEٯYbUG}P`*. R"a3`լ`?Cі@*y5YŮUYP%ۿn^<ةsfasc"߾Xcb&kYcϾ.dZSȏgOWmcl+ɫLBjk3-j5?P.Qiw歷:L3uG {֛)j"nNXjyԝMP(fD)[z8\ƽRL&({@#q+! aFɑmͺvr^iT*_飕 ]s;[.۟fR[;Z: km8*X58/fDޔɹ:1Y@1ԧGkarZ)se:?([Y(bNXYf*nPQ}dN gHH霫nm|ξ[vIw񪎰~̃)7cQY>R6BSC@H 0luøs~XVeJ F*]-h3LYP*5Qo;YnEl4LP*/ǎue^| \iR pUiv]-dTDԮCC9 wС3M:ݠWrIAIn+zzb\|þKy핲߅{3Gqz~#X({+Ƅ&Xfw5/zH75N[voⵊn?I"x9M0cCr1@,M'6V"fzP:b,N!ud%Y㉔^J',qg+hmn]QKS沫Rl! HoiY(ٔM,|%`X|׹.=M0DbX1GB*.b;b,&ء\_Bh&EQtz(%lZ|K}s2Ii`L1NyN[h'0BG!$Sk6<`c/\lS&X]G)*R՘ع=8w> }{|􂘙<73_@?D6&L ql鵱ޝ\/5X4s-dz bp 01q@,}G9^kGu!cl@>R)_SSnhVDCI״)ue/"1D>3GEIrf3YœJADY=^]=/dLgiES Zt3aP&T =c7l!΄1X?nr Ԧ;u?8&;I '`#~}0-^&|N}@OڸT:>OeCuYtJd^icAqKj_t>.}A<⢔XLл -m Q]R>@KJ<{:=rYe3i`M2]5oig:gm BV9: NDs@6J>S͞ @gY]?BSl$^J Pn5`gz̕QkCH| 7c="?h4@ G>>N=|fP~cB23@o=`ͅh;e[: AJ@7.>4H@_v*0+\ DFLO ORIPt/aLhp")%l ?8isO`<)`}@Kt R6ƎX oamkHFI,º$}ls-hoc*_R`8ʴ1~}(ngO=(ȶ?d+?i=gk'd bHF5a{U:וG,)wbC]f@S+9=L(La$;cϭ&A$>\,Ѷ5ZS^\h@ Fػ( ,EغdY6PoELd>>]%_ W @/ɕed=9K  f2mL@ =%df }G!'FF[jӮHڰkΠSY@sNkHY|Ιsc5 @(_⚫s܉iDLAز^q6c_j$z#X1GVSu{wv^VuPRI3O렖q(X`mE]M@kچOHܢ#;*Ƅh('7GJhctM.<ɫ ^-라5NVBE^ ~sx^IS&P[VzI#gCM,l \<6}@p#}?w?p{Au0>p;V~h!f+cW;km@SkAN9/RB?ja2Vh&>8^͈bΩ} i8XS{g3؝3(jWw S&l;.zB ްGоrWm&\gX[3y:Ƕu5Y'49j+O<4 IbV #o9,L./I^"K3ve0ScYq_h; b4ie7Jn}9?Q4yl:[z)šfqU\gPo2}C\^3zB<  a)rn&^ `Q]߼"thPsM!65{[)ԆjF=zqp*T?ysLG.o%]+FWB W=K&{qb;\ߤLX¾d:3{ŖW=U4+Ɗ!>oaV|t{M`u\U\вPwUg_;yD\\?hLU83}NZe3 z tŻ}"(@s,5q Bg @aEVsqʢ1?VwPV,㴆 U3S d"9.HY4&G_F4&$a‚&{/Y0TbJMz1|\bdJ%Ev1>.>/S~E 2ϣxB^+|BĜ?5Q(-XGru gE$MsF"ޓV^llG٬`L-ҕZwBN^5%% u8  yַw st5M-轲b# ~Ebu:ls(JQ>_WziB)+'֗C'>b:ʖ0԰웟(}[!PM} 9 4Ҏ;aQt'DK M bu{6PHrq|Ӗ2зچ}E~. ;x>,.^M@_at!ÜI|#Oϖ͆#dsY9UбOO,:W,Tb:,( @%!,Y(8#)`^M\ռYխ.K\ û,r3L2Ao9~e֘p:G绛lYɰ7ǚzܬQ6EKIR #_"@Q&Qo嫢_Bu@k'ӶhBO@O@;$A^^̒ g3]*=3Iz4W ,;^9Zn 2V*Miƶ6z@ř_X='DMvP>#ր-Kab`2}) ƄO\V-?ܠxMpA-U0LYA8"KritY2jg %(ܧn>e1ófܱd脚 T!!5pOt;J4PW{|x:"F֐X@PuM +Xl]Y->)sӫ|c_yWbL :>ARs٥T`ɔz &Ja/ i|'Cn)kQ9(3- 8\lXc!#9; ;;K`7 Vd<ͤy2MN@LFzܖjs`%XF׉5M?-nJ  b7xxlBS.UbLHDž+Su h ;C@@#W irEv` @>1I4PםP@Q9٨@ ]D[G=&JP6sUjO9ȩYO*m->9[_@TguL~Ze֘.v''֧7$˻Js#.{OgNB)O0̚u/[hDn,IO)~UGI˵L kV^N ̢@3`b$s;3pĚI @F+A!=RFP1{27Vɭr @1m}J.^5&lF'A׷{\s ƥ"\uGZa>$L5ĢU6ͿcZ:E4ReSha2t@ƴ/p'. \L@91SDv ?.JM28W|$AQ ]~ ^ 65O(M$)t9z^O~Zeژ7R>9Vsy_H c^Gmi@{I;]`Wx$ma;|E|n0ڗwq'dy%Tk[v݋yvC/Uz<lzP r.̀@?\ V+`խ'N!z'Bu#3QUlmS%@ѿIa5egBqz}^栱icB6ܽ7ے= Y6e򨕻yq3OaKb沗emwQ..K-e{9c+f;>ЖiusAQc 1t*_;47gv:xƙ4>~UK k1w(ޘď8˲3(U[Xk lLbV}p%ƻ{ G>u.`-tR{"[`$aRk*E8 gBZHYemszs*;f&V//Uf%ILx X_4!mRl%ý4vzl@l>z\\x?FVj- IJ(iihF6GFXOr{I>{q0/GV;v' Log+lhaUĺܙSC9& ]u0~87|mSVUf+c%T&DC\\\\\\\\\\\\\\\\\\\'tX_>8T:J% cHǃݰ$8@}.ybrs^U].]m r,@V^aF+ndwZAw o*/`^ݯ͙$G({mhwv-,P)Do:(te݆[@RD}J , Ae @Vf R<^ &F @$3_ќRx@oF6))7.v}P(Fj Eja՗|'ntC+0TԺ/hwlsY')`9lxvF'В~Ƿ<ބt7q5-ySx¨5dl_dl佫mW@YOY&h4 WvN>'-r^e#1D'# :(9# @̯]`#V;@s( } ܞ ֆmv3 Wwg,lf%5^6!S*~ucZ4#dIcت9D&XOUpS&!t+&_nXIZ1DLr0T3f؟j˴bVlt1%o, I0V?2 ir9 u9Tnp} __*c$CPovEc*a l} mh=z.[!!AI@8ޗ& X@Q0HZ,&`dPas؁1X@)Ȏ>gŘ*#D#r;ф^x+S)4+Δb!=S|ԮTsAaU],5|pqn(8à)[@LܲWl6{<z6+m@A3}`>5a,|QPN@c-4#zK]ЬKP#[4IY m (BkX@% 9H ة8«jr[?yehd :h.a,9DDs^LQ*atd%mƪ7 ܣ"\\4Ƅ5K j z:4oIG4 ?65V@{B[U,(4EqzֶH 0z/saE4Wh L㢚d,шk3B(<`@}6B R) ]7 ųFCڐߘ@ÈxelB zX0E@}/c >e6&03#Z5-'x$HBX]=PħI2»i؀Nto` RhPw>zVV ށ%[¼3q~tTdĨ0dȤ@&2M|h%hգkTI*Q*u3gM\\?Ca%-am"$ހ+Y#8 % ª"pln]7nM_Q @žJ@c";.\`-5z} my9&Y؎uGoV^]d@Mdc @`9QڲnWH"qKo/fhF*z%lP l5h~I%KB6%/- 1 jƛ#Wd"ƾ/h}ixu=! ZmhESW `$#f\x ȵʉiʼ9G'dɪvȡMr'۩c97dl,)vđᰇ\jK I$3177HlS8|5U0?f7ZGV_gl|_'):膎烣}\\n5ͺYUp[(. #EJ"]:jUEz%_?7/B?ht(GPqÛO{̫R"x fgn m/ޚaںC@6ޭF! MH$_ 4صBc%{syqʢ vݳ> f<=S83nI5`sM˭ǾT*s(lIN@A݅}T.|wցQ\]?qCOAwXp C3; $~{Νݝd7F۷;+3w\9M9T4Xs[}:ԗS~`6 y:^^O_ ~w\^|Xh*Q7yl]ya/z8Z!tb-㷝 hH<~R>MdnHt3;}_Nrch.UpK:݂5hwOށ㗱([v!۵35 6OL.ˉEOc= zD|3 ჋8WJ#!y3R[DO?j!Ckq+G I5E uug&'?z/=56n.hZO7n=N _ټWa{gs/9`~ڛ~t>cA5~qLSײw{47RTmxM;w8*b^?aS'_*?eT%č C 6V)g-|a,P: '--+&+; l@3 anvNcx%X5*V{c;,80}` =/ZBE:`bAZ2C6x!'&,0GeKE\wouִ2RӓP Wqev&؇r>{OMg5a'3H?8=\"#QCFǽ$1! ZAPtaG Z$76!0_׏y S.Pձɂzҿ@E=~:i}3nl8TbÃ4C9Ѵ@ͥ1TSd*!/}C[-&W4faM3 xd2ym[ƜH}`}`4F͈Y 1@),EEkl*g]X{4AgtUsh9Ff0.M0hdAioRX2Md]ˠAlXmjlh0.kv8C"}? v28/U,1!F$zACfFV1RtS#]M_@VFIZB2?h!VtYZ?buv ja_.hT*& ڔ֥Gv }B!cDS0 ZᦥJW ZDY!UjcST #}vhr 8hִm6:iŭ X6 ҅ٻP?"0[3"퉇zk[uQ%ۘollv"z8mPTv2r =m*t襊3*u/)+Е~u~ذLzrNPJ<a7ڨ$ٓU`b3ڽ"D4+۽Nhnx`/ Č}@!8*~ZC$QrvQՎ\4O]]n31(eD0v5@ahбBʱRSP,f݄4i9h3JY7&MvN.h`8 1*UDYtC]OrI"Aq4AU $ƊD4S4ZM9DD{ b=XCmrX5N>iY.$w*Ri @_AYJ!5(Tb3F} Ȟl8gg5N' Q(([.D͛@:i8Q5G)ʛA3 ]8Y*Uf%ߘC Wa88hnP5.<ώdP no:XKEOBAбY//M9Q0*rSy0{A=iBl3 ԋ8 &q>bCYs3+ @ 'Q edGKU.j_62a{uBs9}g7*IUJ4&¾E~cEo=DѾ5!S<c &Ħؖ{B\!?>!XHoC׶•]bVRBdxjxƞQ "EPIAw/@KOSd"=ᴱr3 e ?[L*Aa,z=kj.ي杵Pq,WOu}Έo%;g@vԇ։zTJ6&šIlI o!YrI98oP83[uΕ!]ŮPPH@c`Hv@`!кWe% ^ep0WfGB?7p^T _YKo^zn;#l @w@ak 3 @Ǡd,PcGzpm@g8^vZZ=:?md6>4>YC5d1h=K`?$ wςЗG*UV cBVϞm4c{]+Fʜ9-Æg`SR`_0;1jKoKN9{l>Yln1(|kܗPJ֊KSciJ!Ha=KQ{G̾.wXqs>#YȉJEaIo&T^>Ph+E~;c+=.Ftڸe޳?K8f~𓞲壵BIsp n3i scbh}}_'R5{̓^Ur6z:A?)&/= ¯GxmlS%`W:}}+%uQ#`J{?jR(Gf޵LCx̑sd-~y}]dV/9S~JWy35B<%d i 4޳zXi3f{V{}y>NHdb'gO&΅ !eGKk`]"΂vY? ţI/nhik1+:?Gx}>g4M7wvsme.ln(>R܃ïsk_:{%Zy6. G3YW!C[ u1u+6 xKk\7šlĊV:^Ӹ$dR?U2EͫOM\2w SԳ\ҿS*の9|gĐ.cOr25Hv!K˄/AU};ٙ5}8 f-i'xm ")VwbcJWENb.JwQo\j1VoDIY~{U}6&-4R S*f`iϒNJշk~iү3 [1re s+}C^M2a|K ~gK;GcZ"f%ϊI'4/8xwJڌ|Wk3UQ K.!m٫!拪/RRkO*#(+|bV4-ԳySVYh[P>U`enjU_byÍ۠ 0;ُw4UҊdemJId=%߃5GAKߦ[߾X/͠]JyA0ڌA9_'"aʕ+Ck9-iOo S:m@U <S,6G_J@ߝ]PohqmB@|6/1aV6H⛂GECCJ @!5Cik4"*R#ބ0{7,T] fYc7nx7(ֺ{ϊ3ڧj:$0XP&8%[|׆G_mϒ dJ |O<ߢ_D:k 4;]B /Y][d}g}gϚR*X2}oJvNsIϒAg ZF sWw.A%c?C{/;[v/OIO'oM1PxC>ёvCC ܺ>S t^^jMFzwS( _ь~67%ʣ 7tuX?B 6D5|[Ɨ>M|Kǚŧ;ƍ佸MkF/#L?^ktww<.67W3njOfM]fgs,LN7P{F_Ppm q<þNAEp~׀Mp56JNEK)C% }q<嵘[\=:׏u?)5!x99U싙nQBEyq^S̔ :>j*(nɳ><8h:S_7-Ua$:Η}a"yĈP"kG¿=VƷ8qxݬۤBў  ǰts|]h|yN 58>X~ԯ^oaruxߏ 6==4ϚOo̤@\ӲWAr-PPo@{¼SE\i_@S%[J @W;Z?u*wl3H*!ky2vj`c @7 E1Хnnmpmx-Vvj<ƶi_L! Pýa4".A='eGa@m+ ٠IYtCyNc/1U\ /os`^"j.9Mя|$,tP\0 :ȁK\+~bᆺ`>7 ڴj_b 5\ mm ]Z uE:hǭA1oWT |rzTrC<{Z` %j>]y /ΆB0p!?L6.  kitͲzzOdZC ˷5/h2Hlv8ܖ;SlZDzC[~xg {It2&chƐ[NY :Fo`2Tߊ ؋)u4cBͨ3`)me! A؁epQ/I;mɚ{zoI>`\44wm|B2iW4,sA6f=0 c@We#1J]:nmC)? S1k#;%]_3VqDwi<?9]WF,׆o֦>A/uv_ `OHmw"! ͋Ԅ;,Ya_=\ ڲ_Nsb;lu܆pA-p\) l6*}YL=+BĈ-u 'E)@h%1wuߦ}0hm,حB_PVҞ 53y`-A[KZ\QZWn``Vz錾{@5ܰǧ5&`wrx )ƸScEYiۘOs.H&&2:`(3!*?yn8_<hu|>Z洄2@g&X൭F[w]'Rޥ k: aua-?^J VxM0]Fgmj%RY"2۴./0>9yqfO HGqWÅXWǤ+1)Yza/^r 7"K! -QC~IpԌdbtxۘ.G@E HtTX|&QUUլRVQaMebk@sZ1CԤ*VLA @k ,. 5]#b@u]BwZr1 l".#m|avaIz<d2Ę fwp(< tz+xM!LDS`:=f[ZF}@i÷5x >wz9Hҝ8z )G 26F :ֆjGIWg`>MzX›$2% %# /3dF t뜿eP >s~>EwS%l1 PU`1|z-bKSKqyLe[w)Z%\ɘ0.W="@`D,PMs?w3'&MM}q 0f T\1s}|EG+a6%Jv2PT~7ѫ  ,J {ifeқɭqt :?p`~^Pd62J ހql=mf K:)1 8@eEnuxSZfEutZЭtŸC qBp@0rrsQm[,#vajAh: IF}y2^kUIWh ÓA^,/3E7'IJE#q7C6 QJQ<}ǚ{Ÿ^Ol]IWNF;4Z sn!TG'{GUcqC^d%{OV-Ƽ ki[ h` Oj&YQ+EJږmai= ['[B'7u㦪8\]0fdLR!݇|uJ;EOqٚ9\Ěie98;x$k3o15NPC7ȣ`67 }* ̢ZJQRjBDvZ? i Xcs8 &7 !l h=c@ axumt2Z`+k,6F% 祅:^"-l/q $+vȰ87<.;3DM1:-Pzay 2 Io#Ky "dQw`ORstKQXRu]MaAWhv7ylb":ںI@A qo7SU*/a ;@OFQfR](01$>fҘC qby<GD!Q#@$-Z ls/[YxOX.Qιi纹(ОL|:j#*s.*.ȁPYhy ,):l4flmؔJ>i3lMn. X(x V 6O@GIIKY^Q ;6 G60v8,:)ʜHK9PC(Wt&!,EmÞ Cj'OkqGP=O+$1:R9 ]xώ*T׎jK@O]ѥݲ{, %`E@!I Gf /"_U0 $tѦ:|6) R|I@X-A(ל.M8FL+h8Sϰ;/P7:XJ @QZ~s)qh߯h#5@l> !r  U){j]BĖ]&u`ܼVi5 /&z?%):3Pi* *dwT|]Ʉ:xeOO6$GR3$m/Fvs&fЫyjzuNۦxCZC)_[j##}<bҗG%lԕ^>¢xh,?a;? l[?P;ڷWjM5rs'"ANq߿1>֐y;J7hw#=+#ZD9U_M =d^׽{\S߸KRI4߆lZa?|>S IOH`i }{BNgϴFR*Q3ahiPI~!A;䍠ӭ[b9r^jp͔ هn*ܙX~ދV0"҃R9Xt5$_w63oe̶oDZ'K%gt:NpIEnǟ|§A/㋻) fu.g|fqtx>MlIeiOܹg~K)LpzV~俈M;= 잪1vhШy,)pKUl!eޮ<#R~3a\Eg8~b}+S?VcK.-}^ BF ^*G5<߇qaE ]t~*U'DwksWT瞸A":"FOɭ$,pmtV Ӊf13}lDFjo}529خV!P²MRq;$6Bkr Ii5,`[k_"!_hJc`wj;)M:d'$Aq _#SZG'?O/=R/N?N7ÓNJ*UTRJ*UTRJܭX(R|EOOy,$3^ mO(,ω&[,8xcJ>GJU4""}Ic{2cjӺ5 *hzHߤKA1RPM k )g/:B2cHK췼±F{׾ /E r_՘ᇤSULPUPGoUK ["[C% ρueE?)TF5b; #mq|aV{~y"shq3/T_r:j!ž :¼P_Б76ZQU/i-)DnXuW8ʘY|#{ ZmX9,{+\U9S=K̦4|IdM5o, @sE,lURoPta5LPb7tIOhp/BA e@J^?z@cDxd/zm_`,H.([S)XTq.Մi'ƞv.TvG@o5=0BSao`1̡{?-iT(g$6}P=6x]MԔlj[8ї{a7|YjЬ*yU~t9âxjڍY+/ёmcľ]m\O|`7OA=',B~g[|OyĎ3@k.4]iM #ENOhWDmMIt]B1a}zh<-1\ݍAgWP\ *)w{וξ:E׏V]}4/|ܻx%0ԇvPڽ~N+nG3;}wz샡 -;&?ws#DF!c @!Ż?]v0iVdxWfk$bJGP8Z<*}4+3/df9et`0}{Aˍ;,) Z `-d{ؒPݣm&ΧQ&. qgG={&d}UM 1o-CIphK=F!.\E 04y[nU>TxɂMѢ/5版n7֛`%##FC_3e3eX1SZ;\vA%K6%QPhb~Aݐ,rR41/OyWާwȕ2- p|kZe1s(a  I.5QF][58 2/>+ tȿfWUWݼ+B ބb!"WzYeS 2 fx υ3tUQvt{݄4@#Ljy>e%]9󺣷+`@h p ulm7v >;(>E̕>@|'09"]/:r>̑cz@)̢]C/Xm}:N#L*q|_c&-ܼni1J}|,A"$  Gq*Pj (>yc2VzZHS*kj>wd Ȟ-FC3bV(LOKȗ%uBw\ LN:VKҹ\KJdo1U0GG P8q4LIiH->\f݇l7Қ _F֒( ;p^ٛd iޯ< o|%2 zJ#cuPa("V)iO>/;sKH&KM KbEj[*e.R*/l' ^饊g&ٱ8hV@/dk&Tj:CBÕuXP=/&_+xTWY@o@BaĹI'2bnA["0 @~f[(;0VgM;aoW#[HԔXJ&TSa']؜/Qh`VDݰ)Ƀ9!@e @ w;;'A5'»~4`f݀l4NFbl=Oa`}n*F{u _3 A2j',~*Q1qĚAzO'SVm>: 64ԝ5"Aj"Ta YaE6U9PLw Q_&l?9~2yv/c(B!K @gmN#ȜܮT*fK'8=^ow,AM{un@cF !"p笸mZRX ޔ@ގlC8 0_c"ZEmx .vbHtTϪGro 9?ޗs/+Bj' H'C8X$WBÿ ^$<Sb]؂Y+ށW5ԓWԻ< V=Vz@䟇&iL*KaC TU{wEK=B('{ eN%<۠o"5JoJY[lOM2= Ew㠟0iU[) CVT*y9裍3"(/%dqPxi~PRzyK/SS<;u5`~yk{6v]W,Ü/k>њo^w1Lx*H׾J~OYl%}xNRcrȽ1phg(EFK! ~ql6'vܗ@끗MO\m:>|:8]JY?a5~Y6gϦڈ6Gt;q g=c/gJ[,)y~pK@N$UJ⏏4g -׺"y;UX}dN|Ͽ,^IPE^3.v(Qi=?CQa-[o tw7Q<4; UZN9=gG:8zR5F}'=;f%;εs3qw7kr\eBK]sb-Q0U&˔֓ysogO K^nՐ9H'sR֛aZG;ߥm߰AERgEBf}hYwCPhU8d״4vsK"n/M{hJտAon~k 7/J*UTRJ*UTRJ*Uf `5LRZlis_Z)D6:<^9Os`yPy ʞh}O$VS[? "{ %_LE 5HEk@‚Zi tA2lzH1&}CT.*qdE*R"@i5J6@à޵aO^.[>#At/➚tm0QW adi+ 5ߘYucx2ԛPoySCn.c4H!JE5W*UJǚ֚#ٕE 4E.l;9iƐ=ESbWMFo;whb^?:rbrh>xc3ZdW0eDD* T޵fPDOt%`ёWԛmh}cR>T'oMEU2L+xO]qQг|`z?5&W!g&K)ѡV~E[Wjy[Qt{+W:I9ۨm=8ioR j.B#&)b'gyKt*ίE)X<@d=[o1љJn~]7_mȑ^' 5xgV(?3§mq{[/kUz[7,%9Nu8Eee*0[(dU|{HS_ZGA䳿o c@Web~hq S Ijc˦Y`O^O\IX`?/C,Pz q.kTơY4@?Yg*^k *gj?+ЉʤYE?+ 3- "0_n\[N:̑{sjG*`0]̱6n_g!]?\5]l~=-Dg̃'9ޣqd N^ vA7nR11İۆT};Yhs3hxET/(gx!C:1pW>:;cqA|&6чUgпd!J*7#s8(NjNֺe<72qew[q}~&ŅХܟ;C-$|Jނ-/v` 43v"#9|>c?VDV4*M_O7 b`/ؓlFؔ ]Fy،+{y>c΀e(4x:&{ Ƃx w b'n(cVХ&xoQZUSyžfTn;,~Q;.2N ef35Sz/N~falndaY[m2|6LלidM_&XF̳~l!WJEi܅nL1t$My# \`wXj)G2}V`)dm= @R +?9ff{cU4@Z'Tp P2ryɁYP[^1)&X!`S%n^ndW+'z7 q,t]f!)\P3h_ )lD*#EI!ZM&d3z6xM:SvʬO/ASV=׊xĞ|Sbr9f[<i)BapԏTw?tf&Ÿi3 7 3\"2b#M..]^(& m!K/N>ٕ5'eDTy qrY =DPC#_y۸Fgl£aM1(@d Y y@]E,$5Th) e" KPa94ao "Fev7MhJ#Ql54c$7>z-5DVnLU⺵m +93C;Y]l&pʋq-+ʊJEz;},ea1~Nf 8Pg(c#^(B|0@:;s ,=8\6])( Xon(0hfCo@J 8dM4^]DG&y^븜ԩe݆ ȅ uZVYr[I!P/, z] ,ĭ D/Xq|i2F8]_E(2T\ mh/ⅦI X8r/yv秝k]ilҐK,Wuӥ.!B=0@8,yaŞ[LUZ\@og,IeZh~"{-+h!7Ed:  ,e*q,.&'<I@~k@BlEL{C^Џ =W\oȟ*hMw9֛Z#IJ.nBns2%젌0h Ȓ4ZƂ7'&6mlLչgZ-v-CcVpP!uiex3l7xb˙z8vGc1P N xX 19ݠ^j}:7oܗJv^ p& [(!+)uK5xT_+iAS6fom U(~J,b3Dk8x xpq7hx ˞i@M9W.]1d\[H4h )vQ<} Xy}W@P;a%VcUcsİD F?|D. gҺZV ZXPqXQ E%"@赽U@t>]Xq.3Uɓ@QѼJNb5k9ssȼڴдw.k+|I5تbYtax_lu}^iM7ܰp =GYk "&~mT:^)F@-6}bP,eEbҧ,|@ T82_nx*_ O]cl6?DLX,[R7+7? ,>H uzFs\n(?,u?:%z6gv)@鮿N; vɆ0ӛ-C1k\E\|u0޸dpY0ߞP192( 85+b;ӧS}QFl G/o bQp_eZ_&z.UZ žq5@hr4tbٓ^'NzIaUvt?1@.hyё ~XQδ8u.5FI%vr42앮L7\fIh}Z7軛] >/x}f)oO^Ώ?6_H~6}AW|w׶ԟg8_]j#{ߓJxgH?AZxdi0>OYz"sxv7A%~}Y CqY8eC{#Qxu= uXsb`s^M2g?r#-(JǞ~j{**<*,aa*ewmSښ~5U28F +t]\ _.#r(2bXQ:o9TIN&p*M~!S O4M,C6xwNQcQM;[뮙mԑdXo?L8ƶe4nM*P- z^6עh=g͍}S-}r~u4~S).>Ne!C&7$>U2־WsUu ϼT)O٤~\Xq.Sax8B1ureMxXE.=j؆U ~VvjUxvqȀzm# &m W\fQtK0/șdrm]+~ox`\ LJ`V`/ ?7N&p"O`z7Ɲc%K2h{q%Bp  P\.@(RzxZi)V =-gqH@q %X@7^rJB{VfgfFv dճt4lx6?\T ox"+g/s`+AZFإ*YJ"oAL5)ow, b8a?u*⽥l-?]_ k(N8"#UrιɑV7Yt u3| :WeDu3%o_O&y|;ޢ飰-)&kk]{2f\vr,ëquykyigWCo@c]o?9*L2Υ     "{ 懆|5#dLhh3Ü]2o{\Yև~7Ÿw?3p0A5BCg mtl+VYm77g/Bx2jut~9!>ҠU̒zY&h}]N ĎhR? b9꛰q4lY+@`0c}zUިib:ݳ E=aI+ߪ_`$í?NF+twfra[c߶*R=-d r'^qzrߨ2=B{EƔ=~ĀdW`va«vzLn']}C?4i56`3_;/3ꎯ!A ZT9<]3ᴡ@wj첊 ̨7x"_c 67" lK $lN'yݕcs#^c3M<%HQA#΁.|y؊-5լ  8(.6h L/.<x[e2`PCi{5l1`mZ]Ϙf&Ȕ/#vPp2cl&ƑWǡCR#'ٮ~a?xJT  Х٠"9!8fJQh&f"B27X-@ Fb?!W;x C\%UȖUEf=6 (@| }`16`f/xQ82]cT!X?~kI¢ DPrDzBo.qr)Q !@P9<^A+"dW`$&? ))F=ϫ,@_zhy50,^ @@?SAZQ P8c WbOPDT67oRjl \ꉠ\E|hahoKA-@ UT8l}8A)Y{[|e K/d#lO1>bi @('* ;pM  / 8$=Q"ˈP2 2 M_.̄Y6a,h%[ /6[,{FZ^0WSd:{@] 'V+*Tc[J0qed ]PFc;Dш[q׆ z.]GQbJ܄?{ j Gna0,@ %/ O웡Y}a]h8)_!8@4 /'Kl VpU*Xl`#VEGM`w` X0&wFAn)wa7aNu hSʌ)ܳp|vi @4t?ISz^bl ADY/(RtX= @u2-2qaeRK6_JTSKN!@I%]D̂=˓ Ÿs> =N{U 렻M&U`r5=1{c6U[{yU ^FhhH=uW 0 ,Q3In-, +mUPlଏ1\/\4f/q.LO/{ %^;!jYSѼ}O9!&G^_ e+7:s$eO'+O~*z1;&Li1cc]WX9}t`I%Ma)g![ءPLX3c =/e5̮*bC`tsާ0J:c8~q\L/+ʰ(k:4\Ib|TÞXa{!ּMr_ɲdh&=g/+>FOՌgF=! _'NޔJA)l/dOe_D ;N:yP.26EpN v n=E,Dv˖+ןd1P$' p`%R+n"Z-1>ۼ}/䧅'32ԟKqܦ@l~3~.߄O{|PjOjړg to'M_p,p$GZ|̾ƝEpً] ~c+Fݣ:' 5HQ)[8up\ k'Nߘ}+f]gwbYO\Pg jكpm8)ǞvFL:*w†sڨ*`IJh@43lngZ;~C`:/Q5xY7x0}ǽ>ś;/dC;qLTp%u ́b,S6oJ.A0Lh)F?r X&Hx؄o]F'Isr=cIc`Wu ~Qu4E!]Ģ\3g򰃇MIY۰,1 ȎA-{55=9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7CCC'=Nx vR'n_ASe[L{7kx]yBTH H䕕mr֛w͸_C󭏥وFuc t^]J}ܾ:Y [(16˶ۉ3F3v^ -| (.+Ch`]vςBz}@VK?Wpu(*IVvvݽ71ߣ!`2 n0+XI_P[er^XsՁ'"{kC '?;pP`[ƴ? " Ѝ0 ƔVY. p4_fc}x T .#) '<|_8Tc%L8ӠCf6K z[=M2 ƞ`!>n>D#i4foTDs\jVܾ ӔƤ?N$Ae qEBVO8fHjz^ֺ^JN Εv /BwTH m)@SʙbIaK)@Y"#,wKD(@5a)o4FnL%@Ovp+@qg2hn pQ,_pJ&")l;bFcpR;mjQ*: 1bGț -PWD kTF4c:& ;lmML;{Z-@̱c#R> (Lo*—(4Xz`u<_^ʮ*Z=!@g?۩i-+LNN}UAo&){Ya*}7.¿KP y(ץʰOve5<`Gg0֨@Ga乸۫J`씔=t9 A}%5tCcZ`T^:ƤN=-pاR"%yKO])c C@)Źlglflv `Qu2~'_3A+/eXl4p,U g$a~;\БrveG%=ޒGt\Ti1ay]K"&)1lz*z.AIepl& O՜*.o^=g=q|6%Φ`&R˽*b1W.%" H~$eÊed [fQ iE7UA<⻾      ?ɶй ./Y>g=S= - % ] 2O4ycQkƢC*E Ipq ?8gb_Hѿ䔮"LFXUw} yŅ"9p9o PkČ3&Ưjo!T'BJ6ͳߕOoj_;u3cKD{8a۔@x# xj9,lk9hLݑG~a]Kь"mp|WfC4e}1pPFb(iVbA21icjlj]@xtʑa:G˴ZWy12h"a U&%&A?æ$өDu=P^ʅuk tBoUկ"U~ѧ1!@-|䘙 K;ϳX a?7+Tի_pSաN7\Ћ>'ck0Uu|9w+_C.R; z-8jWEvmzFκO/n˔akp#Z.?:.:W^ZmD@G .Pֶ|R]wBuG l0_c{Dldc.@k.?/%>WCJn 蜾 ͓&BVŽ mFO1_MV.+*YueEE.&D(/a|o j.Z믭]^%JD0Cn`^A^iʤ \_PGBX5E4 ?p<lg;=kO:h.c#.n_t[zi]}دca y]{_d1v$I\_c(di ~}mal'-aUSr-Gv }\k KCSlY:rOC Zzyݵ+6؀h rŨ18_yld/˛2I^_c% ۍw;bbyV^C( rc D05|$ vhk]tυ-JpXLdagH}"/j"_z{>CwcŦ.M8oN9OWc!b7 = _j0h55. Xg>dW[c (@\+3t^s>Pe Rf srEDxž^ogsǰc) pHك胨詭ʹp'4ֹ9F{mDJ)@j}8zC%q0\b{1N,@r\S BLcPN)gtcksc9E 7b ]P0[u, P'1IܱUqveτZD#FqYD(ULθZ.ld4bk'a~pEA1(|(&?zزDgC %Jl$1D#~O٢+TO=)X+)Hxl }-mEլ*(218-j9Ens-, P^XE 3 s l(r)Pbs(gп&Adłphw0ɼמn:9E# PSDP$@k헚 C 4I/đ.1P|hN@"@u$PJtYBZF@Q9o3(.[3j;,X/PHeȖ#[ls}JR M68F!Ld p`(\[neLfpSv%H|/JCc[98ga-L;ɣ?y3%@?6ÆMx75KĐ 9"@8=wL Ae P'2gI;hĸJEW&\zƎ Xi'e6~m4\yk߻ s}'妄5~Z@9L9 |;ߠ(־A/t)GzVbu[MRM<)+3%@NaR PП!0W[+bY8j8%U"@X+L~tN [4KYsbK$A3v'Y¥=Gj!@\Mp=_4>ljzcUD[3͹QR : %DR51x;ޑ*wkx,#|o8}o Xł\΃z/3/ PbY{yU!6[F]YOK&ˣT߈ l|}d[KSBHH%@yJ'}hvESbRq,#=%#w_CsHwp=7rI'c0LJbLRE~MX M6@޹Wpȁނ`#BM[#%).lA k9p1'lO+68!]?OTfT.SIKA1nS\ +lw͆1OZuel][U6q;5sׄCc)}[,KRIͭvhn:VOgO:JJw_IM`^.N'!6h 'Vڛ} Xz|C* kN'JsƦ7ggJ3ih|mARj"b=ytK^7=$Y]xam~x}&)8o (=g-,K̖.OWՊQۿp<3h.ǟ7ɻ!2G/qKV]r4j-c;uڄps,>rkl춹yvS  jU#Ma %mC8ѯlcnkrhTeWsq^Ѧ⓰ܶko᪁ {mkmaN7+`_-pYv%vknv(jPm.[|3~|a=gc/pٖ} Z'N tq lE OQXQ ;yV\%bgQu723ސZӜ0tv-7nwqL⹚ { x Uٓ,%ZB̂Γz3brgOt-K,}OOς1"dHe uH΄3ADVsM sž       >,9j8Ol)4t~_^] ~'-9 L AX=5o,-^I#Uၐp9e]!J?}jTE`3(AH"{%^iHpcvU$LfRȋNfPA|1|fMtͦl|Z蕟5R ib-yRnڔ0 Gtݺ\z fe|5qBht0iLi!Gʞ́kWxȑvL's*jbWSX`(O3̯Xx^(9s6C6bU$S|]GM+6C6zț RL,fۈlЀt[ Pe4ţ QxIXcPӧٜd2Tzػ| yGܹ6m{~DLS~tƼ(IڠhfM-}f,z| l#$~Yx x PH UTs <=ˍg(^Sq,<-v0U4A5yg* f4k#?X|:WM[#LN`3D5}}Ao9b<ƱF.OU# ЍvNl3^4ʐw}?vҹU%Lg̛!qE+匸HhOg]i=n"cR\+d;z?aɭ˓m:3v_rC:zx^#8!8>||T6V(hXh}e5S(@˾GO<̆+CnP>uv0$xi Я"̶`3EIJbfalLelAC^pa8CBIV Ps`͒1)13\-@0HDzAE"lbx)1PvQɍ{#op(q_Jި ud1 [h )3 )`Q)Pmqu-1<ƊkW{N-@ rͶL1g]AyhҒ=v, Y"K«9 ,V66 _/G0[OvBf? Ru˷] ?v}%k&B4 ld%F+gNN)Gџؗ#PιM*l'7]'z\dؓKIKt䉲`ItQYpro"V}}Bc/Rڊס~-=# a%9I! =:m EU\9%CX7 ko#A|Vr~4;/Ma>Dq&W`d,=ӉY^ ٕNI% ШՁRrZ (@kmg&Q ~2h |F!(@8]-@{df%VF@(l' [88~-~z?W#pngkSpF)2{/ˤ13%4=CzT~CWOqUOѸ}Ecy3|ŽG"n)ha%iU;P+hhEY~(@ck0 ,3J4i5O c*ل;U l;|u`5[CFы91l̦"LUl+>?B^eKIu=ʡ݀XokrS PҾɞF*E ,q ыQ71FtPgZQς%06l% n~IB.[b5.`l FZ w @2$ExY\wD7Zjq{トS1zPT !f]vQ(QOO@0~=*Bɹ9KU\K9l /DԬw5+\TcBS0HGǎ <`p Pm8ϛ fbzfJ.pr(R"]t8kAAAAAěs0444ɩj$G/G7z%#ZMvNX%3 `~ u7/Gs7] ߲燡O\_VD]"ଥ{Jt6 (=ϝMza .'Ț UJW ?Bd/y&N_BcK=^1tB~iHNӤX>)uN7:?axrճR.Ѧ~:ݯ5`ɣ*}>Y_Q_ЮKZ (T@ł |huS tVⴆ UXԺLa8'ءH5+Y{:ݬh\.T8-dkux?V.QqiڷW:yWFI <nN̠2ƋurS;^f/tAMS5MY;|͓^4u-Y& ΀*]ڏv]ΞZ3Tg^^P1aQ(xY_{X4@7& uTvՀ3{h{5GAme \U\0PbX_{7=W\SԤ w{V_;i^s ~k^ {1 v.|m"^^\ND [lSjɆNC6Zs(#M_gfsryn!{ƖzjEko]J*~B" PwyQ]0 <0˗Wl2lq(ڤ7ٱgq"4eUQv/޶h̸G7@_lk\K91t_jl΅CP+_,(1 ~ qŨC"l0&OZ$7 ;6x^@sop.@)`!\]0_20K1Y%@xw CD89 P_g H`vӶZ")6N1k]"z=2Ԅ]*d"@wreu Kk){s+Vh$*V`{^,9\>!@2/ @q'<ǼyTH.`` > Ƅ?rTW7r0Na`"&NLnZw08d_9LsSTP኱YjT##he`ȧv*vӼw̸e띖pBSl{r0CcIhzzʱoduZ+%}ub*#Z$A1ZY])f6mW6p1 P9Caʾj0[ʁc'8){`ߡM$y);HCbIRv|ŇkbS9Wi%p9h*U|]IR5 sD=tŒ =Bh:~=@O1qk.ς Ig!@ל| Fڝ޶A䉖}UK B|'plk/׭V 54fkTJ\-ѱJv'nJ ;K/r׿2jc@ IsŪ&siZOXm2ت"l:~'kq*4+l=Vg%KX+6S.p2ۈ'θݖa<Qnga=5];@gL#W_iC1n)Fwvn6򲰚ku\uDy .j흋99p}Ѫ"?uSO{t,uӁ6:\嗺OID^s.O'cXGgsu8^7oDf]WkcMYΟ7@ljfpK1ӵObA2׳bMRΓd99eJt3:[>]ӫل3ZvA'I<9yXmzc?ü," >vؗnVqV3/1v@AXfSu+O?ߴ_ȵ5 ZD endstream endobj 10 0 obj 130529 endobj 12 0 obj <> stream x33T(*T0P52 %,JURJXZ(XX*F&z ɹ\& . \ 6 endstream endobj 13 0 obj 79 endobj 14 0 obj <> stream x콏v׵s}ڦŔbD0  J 4$-%bJ6m^!mے" t=3kZs^yr|f֬Y3f|;>ќP:*<4x-H/إ8:4,ʺɰY"(f5.ts2+hlo@V'@ʄiR?&`9H}=ؘ+Kqv 9YbeLі^8GL )ݞum[ѼL>jXV+snq; 0'c}{z_qͼeӡ6ըauX]0'Y<Ͼ12o d)$F9-<@S\fߒW\{sn,T[8gSL!7֥Ўs4k3ko-S}.W9 ;bH,j-cؼ[ܚRĥwWuCZPssO\iCxi}cJ.Jq7%ݝ7";#Ǚ[';,f.TЭ#i_cy^M\0nʚZT;#j[#?/oqLi0K3後4nlg* ݥ#^'Khr/zf{Gvâ騞;Ղf뺶G\upR] `rŔՅڥ~QCKƟv Қ=)c\4KlLYExa6fq5UB.ҍ:?[LSւKT#)ٚvk"Rc3 #ew^U@ĬfuKƙv7K[ق8n{p [yV! 6uXٷ,EKVdiҴGUTa]s nTFMo5ëx͂J u>AL;6-TJL5\zv v[W>p}sXٷލ+|-c {7FMӨ~#rۺF;4[OָP"MXzƮ['۬` F-͍]wsXW/Twc`‚KX,F,S#4i+XhڰfE]uiQw^v|9ozOo7Xga M5Ts4֭eZVzn4bc0d\b1bt`Hcfљ[[GQ C}BF\fpzFQkUuʂJ#:`i޴a[ P4Bu\~nW:;.]۱5MuSFZ4oiK؜?l^SeNjR7R[`-u.ai1A=H-#}v~Eލ8ơ^q K)-7j5[m [c-nnݎn nm 5Z1um]ncw`Rk>;UEFgC1&զ>h> >{„-ů}qwтwX_{.s6{„-u&4тwX_{.s64r7.4uC0gԂq&ю3M-xy>|;MGm`eW^ I;:XN }|def]/ȁ+,؇뿑pp/G?6)cK3|+zݳֆM?Et]u>o>dLhS˭ZB\F近pԂʁG1> kÃu?EtQզo>jd&TQ-uha.߂o.aoq6?6)cK3|+zݳ-L#zU~M|dLhSѫ٢Z\~Sa|B]ܖM5߷B]bnd lA¥^jH54۴ch{Ҕc} H7L8y,sXaܮ35j0ց!λ]m/ c>uwǮ)j')|{RPX{%h)S>{ GC*z}z/j(:xeFFn߫(Y(Tx|G:oo-8vZa˥" .Z{%nQ;>덻EO*z.ui(Fy^z4 mF7F9nX(jk̆˲u暚Juoe?qh\v`sSF|}۷T:t]R(,[V_G5-Wsۃ_|[ =w,mR wMڇVdmK[;lyxsثXA*z.uҶh,P_hX{߮5Ks?pv F'aBkcTm0@ V7 SHn\cү"8TE~\[  c/YfBLhaSPmes0ak@AK庁dRM6u!ԈN-Ôf mnP_HūJc^y;5_vzh8Tsۼ4E}g݂ƚ\G0sRl|gQq O/aː~tj9y)K]-}G1em{QS.ػn4T[ۼjt݂*%hooqň%,-\=hJzj#S^|- a jj{-F$4t.mUq{], j Ql|'uGԭ#;i:Q8͛^*tqX3_Ť4EDcyJkj{"Vڝ͏ܨ 7GSc鹀,m! 4'}K&yG%Mif \"a\,Dfdoe\b_(,(YDBd̆|1JBaL|=КPnT+)p7n:6)䠰Ƣ߃lR%0fpNpy  q{F_7fx} O;<<<<<<<<{?{Лigguz3<@oH6 ˡ``;!#l( @ȚSgTp'p $P,i}[HCN H$%f;6sQp'p $P"hdB ;!#l( :&mH Q:,$JR@>z$)BQy٨jE!/ju aCIkV)m-WVRf?ʚBp'p $PR}-OّkferyWTa֍(aY'()mj6@NVNTZS(,-ԄsIWaE;!6 $PRt> = ATE|eeGJ*BQJY;!LT†(S1YM.#;/LQJvFcU]( a4Yn~P@%~4zڟrC)C5ny7[Ԫ(: a6l(  H0z &1+;R+\_;!ɢ $RW5)4x+kPtқuNӲbaCIeŃu]NӲ?ﰡ$['Hœ8?03%(6`BYƓ8wBr H"*`׺@ 䬕P@x(,NPbCI `H`7P@ K,6;!," $2$W.Mup'<ϳ$2Аi@ZLP@ FGy|aN1sdCI4l)nY4ŠL6P@ OYٗZ0mwBX $Pzr诲}M葉_ (s&j6@C)*,jơ:SEv )º$X_P@ E2VSbJY-tzhb:! a]&ul( #LErM} "%,WQPԑ&X̖P@ KV55feǔD_^mA_XwBݲ/ L@D@Cэ(uR*hwBeM}<dz(X 5īmkҎrPФR0, =S5ǺH9ZV:S4:mu7S5-0iqWB5=M3. $'Wff$uʧC6P.xj^"a J р2\dEQ\n-{D CSmS1I+R_hR5wZWhP^<':e-)}VZ54 Sdip+e(G zO f39ڵ%e'.,* ~2]Y@ )y}){Ԧg+ -x֬e xE(%t\RʭgᥰlWr(ޅnRHu!&V $3+z8jg˅x}ISgyԖE/8D Ϛg:t'U'ԱThzIMƙG% @dId]Q7S-ԼT_3՗~Eр2d/E\ƍ#@?xMQ^pFhXu$ɞn5'rҡuL5,DKRq8#ok~>swl!ze l9l~H YXʚXL#eXB7z4"{xaOZd*Z?j]TWuJÝ0\ h^zPlggN> 5!!z)j'xk*"BO ~;גРjB,_yV;/.t$[lX cR @hGpu,q'ohd\-`3kDZG:U:Vu,)$vDO!'>wB6t㈽uu~[ɭlP@#/^יn=$Ј?op'_fx=aCI5]6BtNl( wB؞: $NO2 VЖcs5 ,6:͒@Efq}~8ko?].'S e8~QՖgG}O,͒$Gޮo?$uYk_yUᷖe#YYyxxqqRݫ9CxaLo 2[͒γ,Έ"<,DliM<}f-*"Ҝ{ѭCD4d$PlRwj XXծ/rjҟ&RЄ'Y@`iȂEqY|K%ĪB8!XZ; `Q˩Q&[db:{R+F%%nCu=,Y(Ҡ9D "+D֖l8+75(s8"+UCV^ńfl8agȂEqYN |{%h",{I";> vIp; FX: `Q"KZƂlEd]Adm gd$0[XКp3,`v(N ޅ1_L:`)VrLfI`XД$|ϬYPzfYaNFdɯ"VŌ]g,d{*4͖,B94HY]Ч _M|ߗE%÷R 9"ԩT|$ZА]l1^{KER͒<ɖƆߩ&g?v@dAvƈTD0-.z*G!1:#WHBjаYlp my-> lrY>K+jDx. _N~Wꇅ: | F "PSCvVaePb$0<^<М lfYO,2J1r /,\k<"WJPPhR7^@fI`dџp.U){G?/"Y2NL1recDPG)r&G)'T >*gMY^ h, L{vPkJVǴG" OgXK{"+R>\ m+z٩{a#GO\i9k‚PYmVp 6h@d6$z}ȺGIsϞkrM{aoكXnhR7뽬B^CWgyJB_{ %m#݁Я+TU ?,XtG϶ޓW*u=jQrI(QhZE{ un %2uݲb ͢BUc^-DVpveݭ=rz_*DQd/eS:A_ߊ.( f"oG"!l El"\Dppd >rz_8^+QzʟlC! WrG Ț-fa;儰Ƅ==v%k.X}Ϲ~W`eϥ;-&I2Â7 O| aՍ /j.`Ϲq .+Mi &o\~m՝uωz97v/mq#wa3YS#o5|l9&-𧷸_DAdkp?EPNۿž_ǿf'8ȚG,}ɹ?t$,z~\ĪWYpwGv~Ɓ<,jK/97x[fcHd%j /}z['9IݩJGEN"DDA^ɺɧ'+QmD [f/%rM#32<_uݾ{35,! G8Uo"#wg7NyW/}Ԃ_Jb5ԢlO.\ASȊ-gj!uAߎXa눬;Tۯ[ulvsC~& d`BdҁZֹo"рi!'ݎK+a`d l#6ZwvGsngPTq[9g7 WWXE,v-^ac_NʥGP %0,7Skl ΰeuvphDkyǗ QXY^A+E Y.0>=spzq=یA,]0{,Ux:dT%yCp_RSr :S5ܓwz1|nZdgAt]-UxZBd$^;T\tBzvO5 PMk~,,,d!f9 \Vd+H .D<ȓ/1J^]aYZ; >(x.Ո{-DVcvx=@C#pQ tZN TouY6YIB&QX'+ڡ_.` jr6ɞjڬݿF5>gyuSxZ8P3@uqwKX.{]洣p깃8_RhwΜ K0 ,Z|\0 SӫKцVqT06Yݶg ל)r*X: Vgљ D9}+ 㭼-'u)n/u>!0:?Ē%t[Kdiw\RJ _|"+{PXD PO" '΄ -D ،jpx3 B@7VW/X0OT ܤ."ԥ/3 NP\hN"kBYYNaÚ)Za sD/󧑦Yu;zCo]d w7%834ޓE;,%Ma~HnFo,-v[喃٭ޓu R5Z//$jG$-Ld,]KpOJ bu%:Yuj͊ߏ Mi:w--p:Egw)d조^ZdYάLoB*zp|H 'o}u8 c3u~k9^f|7љ!?dp)uRk:쮃L~ %EȪu4(H.O\p9n(w:Jd/u }Xa4Eg*u6d!SJ6}џ}vA`8-_n!{]/ԱzZF2.5KdHܻHV6K)FMťja){.};| w<"+4rvYz1;,3\^ehb2'Q5qW! "?=Ȫc<[:g\rv:bsֹ/`c" jv*ul/ιuo!FQ}hEq[aX. (wҚU`ہnnGG#[^Tjzw9ME/i_䒦3X]rFhVPdeNIT>*wr/)YriFuk>"%^wߵ&iO䢛ۭ$Hfe 't'\4v׫&EFm=K%ݘVdՙ嶨F3)OVXXvNYd-rɾ隊Q6~/WG Ғþ+ Y+6Q.4 ƅ |fY-'zBNցEd-3Ӌq9 eǵ" X/ QW "kuN(, {3IhY«Bu,."|L%_fYG]:4f9wGaY{mYj"Q!hp-YۧYG\!m9DzkGaq\3/RѶ.wBew$j=$ -qvY/@SGdsg`K|P 1E񝬺ZaNuGCb93Lux,W 6@_- :k~%%Ώ#,p4T/'}Cf:YӦk I2t= U/%΄ /xن«-DV;DrD֕{2Ȏs0 $Ek/A{qd:s^r "K 9GQdd:G묰[2M糸{\"+ՅX{.V̐/PX[2"b/ r^svuF(⹣mX(&-@grvB{ )[s.R%c(ѶwB %.ISL"fHQO3)>hWwKk*Z:SKR'{W:PdBt`DV)#ٽ u hfQ XN5Ddɧd}WY "PYM]hO>!hN*dTS" HXm+w]=4cAd@f&5b3T!^-23EjD-A)d*utV<t&0IGM}%YzSJ'SS6Zhh"b{-f&(h/R5Zs@Nҫ"QK|)&qEd&E*#BPRi۔` oBb8CО6pr>L"u$j;$"D\R"thaOu$PߣR'un֔VGbtN(T3:0 K df@X Ʈ"wU:l˝PODT6d]}US  ŵ~\(TKu!"Ճ [$LSp{Iٽ(G:X dlrru|<*ƒm%Xv 쌐?-ԊuI&s4 `6)Oբ m%{u^o<롲hT5GUԎ0UPNY/ 9WeAaF*r Bd=:?];w."kJs it! 襺ZڅVӯgД&d$5>gܶ^Ϯyk6Rs[4Hy [<*%jqiZEXٗ@{LCEl̓4ckPX]'Xcq̺d)FɘXYk1O^nF+svo@XӒZ IO:]E֙jBHAx-{0큻S%T~ Si{9 (i \3Qr"* UಜBȂ#TI S9Լ59kDV) UY'"˃ْFa㛃{lmwy.8jF^0NCKd7" ̙M{3,ZĿ$Cu1Ȋ+$QG Bd7 " Z|>űZ8bj/q[ )UX}RSu0l,wBUDP|\=3'%pTlXk]ᯩ,dU: Y/8r"k41۰{4."K/MzݻPX!/99 |\0yw1$j}tz+m2m8$.\oeDo+)EX s~ .w 3L՞"k`HD 6S!퓙5y&avfOV"R%KE8+7^Y(ٓ:6z_3 &KƐiq"+#n{F.XJ#Ed \dRŞ1YzUӨqH.S〆dELR F8nX9S۱YDV}D@E"q^Ld(ˏ@sTT쮨NCfԲ#pR [I*5GpE QX{.1ҫYBϫ-"k " vDCq-LV iQyX(dKNh#xE4RP\SM@F'ɾTm;!4{5jgS[lm1\ZOdzit'D}\dՎhIVVZDiذD(ѻD_G:4ȅB+$ڔRT'aAփrv",å'aQ}'3jHGFZMDmRJ+k*ٓTNO_OJ4%7;S0IQْ#לq(Ɖw`xF#z^΄ u-WV+i<#R9M SY?zDC4e`uQk,LG9"eT_@em H~W^l>9t`xɆB8"Kx5VH-HGv&\K;,"ʋh־\i<#4+NN[БrPhMꁔ_ SV'h#-[qv?Cac1{2B! QL6Y,,9'UV>cGpF9XҸTZ]sC0;~>V4UD2gcocMӴSEV֥X!7!ٙs9.׼OsVPZFݖ Qz%?Z_r# _ "υk"LC/fLa])tc:&W&kd$;1-4:5jfJ:*9sȣHٌv) !j*L@*ʏPp!8ڌ5p+ avO52Tt.BhB}Uh)5}9Mt!Vv KkvPr̅j*TPݻBH6J!I XXGc-V,ù-sLœ)%MHvYa%ܖrե\xje]E~f_ +gPR1C-BjUZ"["5n ^YhdQd ZBd(t夲KE&$d郖 r1[|K(O 柢t˝P}f ,%xpբFhT!"YTi_m1(? CFr/P9.T4Kg05-7 nxʯ)_(b4Ohq~'D}6MK}:ֱI%;jV^x5i ؗYNl;H>Y~ qig[`I1ꗖ_*q74UXsex1jJEkaRR4" & ,q%sIL5,-T񯽥?}FPX#(]qa17Y'A5o`N,.h4Ys-0,X"g!-9\ן}EVHkus&?X,#+D J ޓmQddiND"xk&+gQ#7;)ˍBda_N,,=awg/6e=dDRmHvح(CSl.DW7->Zv|{OPXx Ry+Wt>8އ8.֫IcEd"giس= mƺkt(6pPmגX"/8R"K=E0jr5kPK?}qi`ĹELS'FΏ sP*5F۔ _`埛ov'2 (VYRdh^5[9k5( DFQ~uCk,ip }\9/Z G#"Mm駯h BcRR%;aMؕ>]HUK9_j9ۯ`!pB 4͐`mZiꀆjuʪ}DֳS!ݓ;X-YaūE֩XƬQ )uGˋ\JN6«aꇦtEd f+fGNg&GMخPX(Cl.AiYNw+|Ba 6Ep"|j:4iS?ʮK>aMRW1~N$af=a_~"wv:ť/B?r&t g"TdYw%,u"Z#,hu+ \H?hޣu%@SqlRWB5EkBfs'˒=p8/eEY0?_ \.0uPju`)Q;2޴BF[VP QXg~{UDa*^`_zIzYBa5wۈ,$Cp!aT.nkΕ1Oڞ "+4u΄.=]*4xvi̯22Yg#߱6ce=s.'DVO 1KȪp0kf2cՇ%ZYax 6cQ+ƪ-(%es9$;6oT3oVM͟Hd927>a}^% 1z93L&uLe9E6YG߁:qBpUQ#'Q# 0_nAN=5C0}uVQX'"kk7"K,F!t]^gf"V*IhJTm%y Zn4ɶr[dYKd)O}p_WPnSfhfnZ˞plY2#,/&O\%ΏWkYd/T-)TS*1;3&ʫDW`6PcY34xAdULMv+G%zQs4"K('X͟-̟6]d VdKXSSlUcvDvuq=9)ZYY,qv_h_`Q9gW*E2\ QױPǿr܀sх5o% j(wZXیWP;MFӁ|2g7 rKJU]ץv [(Q\_u:XXY(7$ꆲPV73jzONEVώð\id&Y ,s/lnIaBdZ%Kbڀ9DVm #v?[) ju:ckʚ13Qm+.ha$^"w ±sTѰ˝eSH'w1 ^u+4JdhCЙRD;h_j@aP cuҒwY<- _|<@g,&{6C^EYnA@IDֵaרe''pEVsN"X@RS~6~\>Dap9aY.9eCN D֩Y!8~ũ>,Cn# 2"l =hCw4=-F{8\Sl.# 3'_~N Km@O(,%O%(kyRw^ fr2n!"X|1믩WKo45 sE^=6 vPJWNEl7YNY ,Fn"K};Ed~Y{2GU^g7 ǮJWBede!ɓE[NT$p;n/UgwyңQ^=u|pE!Mc&(9pgN%"]36C"\ۃ<#*,Yj%j۴!p]"JYCaDMr S}Cyݬ8YFQ*/"{>j}8 勩Ə if%7C&m}9D%7c`E"+Um"ZWb,Kq[t\ =/~qy nl&n c5 宰8V"Z:X~ j1EyOW)(uCd4%.i8PHd)7u@aV\*f3qQ&[G5 +"d1^)GP X"6Y˽5POq{ (*ev/ nrr$FewA+ܕ5\CqX N9?~8~A)nަnTgQp됨Ia zue |.H'謵xK>?z?\7Ъ*rIս$.Z+,NQl&~?_kuĵx}qα"vK<BdMjþIk&˫;ٸeC>W+dm`88~LyUXgZd(Ȋwȓ늬 0D/e(UuԺOa8~8q|M ªȊt~/~O|C}W'LX?(, pve3>g{ vUxGo7Gz4"+ڰd"k Z,/5'f"v%n=`#o?E(s_eQd e::l&黆 .K]>'2i%_6Y "bwu[z*, l&~wG]ȴ{$Ώ'|yEf&K~it BdٽJm> D=Eln)Z}>}}a }p ߝ(,Y=Ld}񋟎_m`*E#&]}{uM$j3_ է/j؃7A5-"$Q+Wyc`8G|sRA7"% }[G(,-F3$m`*'Qdh `?\NW;`6Y%ߎvd^Ƚ:!,3ފaQ\NA8~q|8~`6Yf S9o,BѩYD,ʜ}k?<~A0{Il{ct6YJHȜ6_q:"뱐Wct6YJHȄ}}8PճGAd=<<7"Iz"뿏obni˳#>vY@;_:<< 7Y<`f;U9/\gMBB@df݆,T%Hbf0c,Ȳ@dN ҈,T%BA n+,؆ Dd"kkD͚M4"?d7š~F-1FZbY_[Dr SNi* w{lst" f8U}!"uΩZl0Ei+٢Vu]>JmWԯþQEcL~K7xENRv" f8U}!H"z cKpYߔ!T PN9l8@;VT"+hS/i|WMsa[yslHWS]/ 555O a,DYbS՗ (RufS/e&wzHR`ƋBɶn`aPO+— џ/]nNbd d*u9@i-YӗE-D݈v!R9 È)Y\nZo9G Wf8U}!B=RpemV%P1TT[r5Xq&Ygl*~^ mވG:e\v5a,W^Rcʯ/ >~DpBH0l.-YhUԣܑj({ayQehNJ^Edݶ楬o6֢y%t/۩}E+t6,T_,UMnEӗ_4uJ92Z.ԔV "K8aTat))4:)aBS_ BaF)|Y0Tu&,* i +g6kGYS㉲Ga +F{uuA!nm% 5I_MsM2ą^Z;g" f8U}! d+}(u57I)]__9X0b'YvG"@fFS+-(eD q$vG"Wf:bY^Am%A7E 4P lp anu!^f 3Q4%GYz3DV;$3!`!>2YߩJSKTYqvYПS" ;UI>(," Dw|`,+f!D#DAh~؉" Dpx86Ԋw`,+f!D#,T%4F_,@V\ψ,GY8t`*V\,GYߩJyi^GyYl ,GYߩJyh",DYqa i-@;;UW޴!"KR XleŅpцZ1ʪ 8ov><-VVeĹ?_?8ny]l{gXY}~9?0 '?ʪ 8/v̛ky3Zst_vϏvg+oϓbeU#/+~2*O`i8/+Gh`F8U愳:q~aDM\ EVkX-Ђ*,L`u8/+^or Hv*V+*L`u8 ۓY=! PB7yEjqLd{*L`u8/dJ]SϷ&ʎRg] -̆hB}US(_jXWΜpLȊVHF$gBpit7eTY5meS]g]ʾ$KjѮH*3é 0!+&X/K^S?j maG:R*lYkaC)+S`BVL&:^,Ƣ CF`^/ةKJuq5:"4_EI#dH9U&< 8b0Foz$F-ósrs$0U'ZXEY, %k9{*,aPJQNU 8ٚ_+x?#šPQD- :݋Z2)`!Wk)"SYXxQֳmtt:Y+~_;^sӊa4Ct S.cw]s$V>*'h@CSD_刡pDž٧VdUQG:h0SJ$ät]urTYQN'guԩ`R]ߦ]8*?>!64z:AV9M@V %Rs p"?uS6_vM`O2EVt~rVŨ@:h0M&Y˓9_'Jg&˧+Ȫ+ Yk:>іKP-\[v4GI s剀A+fn&J /IZmWs,$a:N9xexBE+Yp vt? bs2w E2&^48g! Z#VL:Rq- N"U %}x쉄A+QrRdᥓ2JVQd]" ¯S߆gT0K e {P~~ُEZ18ᜣSdQS}TY/z"@>kI}VOů:@ї{4a* H->" 뢤5(PD<> @yޢ8 ר$p㢷p,IS]ɱaJVctvREPXQWd,*\/÷@y`Q{ٓ(x{` èwSda)VTY/;!Bz۬MVO=Z15{MEPXTTd]"Bzۑh4:(A:h0 ~BVi6uE4&>5A+vb" B9 )ȪtЎa<.Y/EEVȪtЎa N(0j+wdk IF(j+J,;?4HV줃v #E7*F_ĺ(Z3YX(Z3º" sFd)_Yڙl)L3bSȪtdty5Q^͇" 頕ɆE{8c9cyht0d:&7ΗUKllllma(.?|9P^MIb_\7|MvFO&KF;F}VOj L3YRE֭/&ݾj~`t l.ѓb@vQXWPd/ʫ(g&3^Ce !؏ +;\̱F, dg)0ʫ5)g![^'߭4Y:0VZS]VY Yx2,&+ydUUx ͗UI`;6QdaPd \Z"kGp0EvEV ű.ǵP]dEizH O@" Q^a2 Qjaw>M28[X3e;k u֚\OAlcz (_4 s@@ ~Qaሬj&C d` 'Yp '|eExz, dpGPa!dAkC zr=L28Ck(u {:,Rd u&KF,G,#(`ֱȢԚ)ht0a<#?.S qLU]p0=>Қ)ht0aL^B,yTXRNAMf&˪W8XE\OA #E‚rȺֱW'z , dg" QaACUx MU??mh~׾ȚEvKE" cQ^AIVȺ[>w=,>5Y?([-qAAʏ 6w ?m|~&,XșPda7YdEY E*ɲ¡ڂY<ӠnEFB"k,jV8T[pYY/Ǻ|ac"tkhZt/"U.!" "t>0 Y{Z`Fpy5TXdqqnH;' ,&ҹ kPdeV+#-ֺ#,括pzq<*,TU$;V8T[ϳd>cKD" x WPdq gvbM?r˨[|׾/z\ #EE Dm`Ye[0-WFͷ~i@." }Pd:, :!fz؆Awo_G GZNRlxh~[v l' ɆqxJ/yrt¾]x(X;aVwχ,{"玛g920I ͙ZU'(v~7;~fڪurku ~O"Kӟtdh*863U`lTË 2r b aA$kº#[-v{j,YXY}/nRa"" WP[Uvix:p0Rd"_d"k#-Tgta뽧T܁$n%KV3t138W><#!R zX_rUQoCyeMc=.epXIR* "+EO6iLdEΏ"&yIMhF6ӁG" SEV[YGabI+}uL" ", *,Ǐ $2|1Qh/޽կ^ݤ {39Y C/nR: Y;i-On>:^uetaȂ?|QZ-)NRj"RkAʫ'YE[Ӂ#.OG,$+TYi[^=YXϧI5O'm or緋Y×dMPsE[9+"))TX?|\t@uV쐅En-x~ں/(&`pGNq*)!*,XPWd{:UqECvLNROvFSPJ?(#?:-8Yuc`+Zs\^=da7YdN Qa~'>YJihHe)H(38W5S⨰`Gʌ|Yu"k#-FWG<9׹w(1|kSd! TYgՊ:tt0fGu?x:p0RdA PdblF0rHēstaȑRAq<92(Y, 3U^=Y{TTdEx:p0Rd!BBYw8EVm '>:ΪFp%IKJ7)-E)B 2[^T,N6R̦!`o{@ҫZȊO؝TX{uu_ gx|J9R,!`{אZJ[ ǦHc=/ cZ4;YȣD%[ȕg Kf?>w%NW&ʮNVŌא.=,̣x™ )<}kax-_ cl|2˺I>h c3" `!ORv DCb~<28W9Rdf",bdmfEEu WX;Oڕ"kHG6ӁGfQd-u&²bkfV=Eu. #Np彼:S,_OɆ:VtUuH؁Ye-&3YRiYǯOv2f:ha$N`L]̪Y=LVa=駌" ;E,2a)~6ꖓ>"uV[5r;E̘8a~6*EVvVz>PdaPd=lTDXj3 [Y칶N^Q >l qn/I!יӫX_,Rd]tz,G:y/&K+:}TQ^DX"k쏋LU]p8dFr=M28}y^T]d?;/]ԲG" "ޠȚ`ab?Kf˪V>-((,t lc#GJ5 29vN Qda7Yd]yHTV$ L?|JR OJK5 ]iPd@yY{ՌאzCs)#ǥ\j?>=/ c,(EdJ?βpҜ`C?l1218"ˬ՚X_2UE0JY}YAZ Q?oaGl#E}ke&s@_Pd*zc,5ta[lR֤Z<`b k<"=Y&)xTYx:p0^y?RCyd]qcϪ(8?))*3[Ӂ#FJmUmE 2UK!YCY"v@+eC?Yv}ƔO)YKiUdϳ^rB5Y+ބWxvSt`a))) ާh|(w ]1qT4I֬ c3CˢȺIQdejʏ (XDSdu_mErqf)B5cC>?|"EZUSDecCd&ZY "KӟtøTqHᱤCaE6qPd9ey\PGF{% N}*R RYQWF"kRd;\0Ι2Ȳ6L:9#TJ\RA ,d*̪W"K6םx+9SF}D}xmYuTIE;Y PTdܱ͗@yȽ#?PgYc)&q0З*Sd ZY"++JwQ "]JX/kSr3Eo+:t"Sw_ܧh(267&?#T4Y4 /(nR:JYfYI*=; cdGYuߔR?V EYb2Lڍ[_tH"Qى˟|_o^& {бzb2ڍ<(SUX{0u2x:p`U]/^no ~\&DeߦPr 2lAxNLATEG(f.4(nrZd" #KvM1ia}X/d ;O-*2w0U)fuHCKoR_ɭ_EJ X\"guU5K,_-c!E?QuSYԁk3/wW}ۯ7կ?τo{}+7mLukQVȚϐg^@5 yZ?H(l_~{~Ư{__W ×lllͷ[geUPuqe Ț"ke~ݯw_S~~~G~ӛoʨm?MƶV:Cxm˪YQaPVXYܥY=uEgyy-/~Ϳ{ݯϾ?~Jw_~?|_]oط_o#OW7_'`7_±YnڲUK5Åg [| v$N_YUdɎ'_W/y3ySXjpb `&1jo WU Wpau2cY}N;;̐SPևtQa?669f됋mfUy"\>Ekϛ?SaYS:%Y.Rda7Ydg`!̪:D |e/)[-CUc>"=EV`pdYc)&a2UR3^/RdM2,stƚ1OA ecש`Kt9hT[dm'][h/"zaG,:,~0UKG"kA|F͜)YGYbZy uo[^ Rh$(+6E5!_Bg L,|aYSIK71UqО"kE,ՆfU=A9I%O*?-݅it|-:EyP.Ǫha=x^MeZٛ?᎝" LΌg"CQ5:X4v&N`mƳjx_(>CEV49x:p0.` ՑJ+s ÑOvv1x:p$[WN~>lۿmtvz!ZSdAoc>`mw/~˶}ۚڶݶ!ڶOlۿmtvzmK7qhaʭ0dF,x:psEWlllms>mCzmf~qtHp+Ї?m?ߺ c'ʅ_uҲN;Pb<89k6r`cc[g>؇,;>mtvzmmmmSCX/yz+@EE֟,ы66_soImtvzaKHBDXd]z)bA"K~H(^de3R5Yxx~y⁍mg?|hl;>BmtvzIu0m pDДW?|/7@K=oE3T͋EֱenPgّ~wYGz2,Ǥ9ʫgZ'[=?r<}h>OgoD>:b T!)LJjxV=\͍ƕ?Yx:@wWmϪ-qgEVݾ[t#XxV=C?G7,6@hK KYdɷ u+fzwwnK` `2|YY<՚TXߑnpfQd̗ Dm5|YN)fyM_XO8#KíZY e+j)<֮ϳt(0s+;&˪=W8G V+'.n}YRsP^Yc<w@|Y7tXOEE7Ծ淩 #!(l2Ugdj;ԭs+4nN͢F!Q^Yf?֊0T}:|Lt5kYXGghQ[ /}sh{OցtXrc<:*ܚ|}nz\a=#\7Y!#;И,Ɋ2ZmY;EZS0GSbz|ON7BkT`He}m? S:~s0UOOWIPd}Mm}g-F=,;\d̡d!L f< t{[E֮\ ,TX0M9E-2f'5ʫϪa(D.*:_ŊZmWӹ_Nh-:W2UOEfqVdAfbUXJ8uUIwt@)ʫϪQd+Eހ+nj.\~' ydqY9YdR͖zZł_ F HZZ,:+f7 k_v,ʝ-q ag<@f@y Y9Yd=h.fcQ5zX,RdaʫeϪᣨ(RVXq kgI3!Egx: f͵gՊr'YuuVUa=sVUIF108cY2;YGwRoL־mZMͥ(F"`e'v dsYtTWTX;yF'YiCy;ʪ0| i[ t 1U?E}ud>ŭQ)`f7eA\08 c2Ƴj?G-Ou>"EW2eY,BƳjO5U[n^ጧd1j+tfE֨Gx:@S Ey!gB~TdNfuyB𬗍Ji柊'kCb< Ez3bAƳ"ٟJ(" 1vV,xV =EN@gp~R^VaYsI"+!E1W0xVD~',AyUڭEV@`OP[YwͬEn&u^,vDoeŏ ɭß"?+dWpxV W YO 癆bX'ܷfh0`&WpxVJi5P^ Gz~x: @y ϪwEÕ9ymEyU]Yƒ\ambϪEﵥ-wEVևt"% fV^,Ud]RQ^Gb5$~}o]Sdsm\aqWXͬYbSd(, 9}Qi}i@`g3Fߘ7 k`UEmeȩ7۷'" Yx8k0ͬڪȲ\g (#+yaY, dY²Mk@6j:d /!=yv}A, dYjf64Xd /Dh۾r۾Y;YP%.zR&˪mHX0]it, Ay&˪}ןusK!}?}◨<#mmڶ߹m?BQ7p7+@cw~Ƽ7n/u9*}t,&܇ Л,ۏnnǡ`?+OŌ樭 eտ tFUUd͑mmm4Eb@+W@ɲ~bx3 1%Y/j~&K+cuWEe}A #&ip+]PXm1, \+(&&˪DK*3wd:u(&˪S!9pȂL(Ey47YV7zx4bœ8,XD%j+>eoy PJL G (Eym5y?ۗo4fQdf{(>&˪W8wc"i2Sd`eLz,^:nYX? ozS46&K+k;?UoṈs ]D B^h)lYtvD(`A"K8W٩ZΐʳTQ^F]dZtì; 5Y$KmS4E~ `uC+nxAD5wEV"+" 0hTVNY=1 Oh)"k& ],*,a(U>ӰI #ۧrt?FVNgLs>z Ți8i:_QaOҗRf;O]H ȇgVUWNxsH(fr}Z8jeBQou{B gGOn `>Y5;u%\pc~7EL.N avӷe@MoD8dG@S L(0Yu ?8EV>7p+p=PdT/*(gMmTϝX=/nV='*%$e#\?Y38'<ͫkT~[Qu{qLqwd! z Țɕ]S+JW)ak҄U f҉9+Q}D5+B+Eyړ\,{9ٖ[#-UT7HN8C+Yct <)"k&uA6k*baWo3^sw=n1w gqs=QdͤnJSy4ݟ] ͢hS/lcN]ɪ5XF .>z ȚITRm4'"t%j9fXhˊTU\p,0rQqA ؟ D()D!:RS6W*fojp E@ ؟GxծX>/\p3{[Q8)"k2f HU͇W8vP2>)"k2f'G &gUw3.2(&< _)!(`3 fUՃ5n:B߼Ȃ01mՃ~>CPdfrY^ض}jw±3'c 0@M?m_am ǔqt ?SEd,Edܾ9gU+SHsvz Ți<EY='7Y)9p;s=QdM?7WVu±˘\?Y1ȚxtY"-=&K02+q .Z^=LU)b7'dTU ~^qO&T?]p٩iJƿ1G*4Y:~ ,MV 4^ eS9{80|zcݸ&K02{kTK@ПQ>QjS(RUVa*z'˪W861y΁؇)ht?D䥻pl6+ = FY.0r9-&{Sx'˪W8f1szG4Y:޷R.N͂?2T0rW.z@!QiNQLU]pb.wSdEV@T0rEkbΎRg\e=F[84YVu1Pr=MוTc{Z ) z$zR M3Js)c̤͛2YVu±;bvoT ʕ|EIy62Q^*ʕ oReU+˘Nz ,`Ə 4+Eɇ(kMs#g> eʮG'˪W81vSwtL-o 3Fd{G):Qxt;YVu±t\OA6%),rW5gtX^lS=Dg w^ٓ@ijoW_m3|ɶ}ybt; ^p WVǖ«BEѦ=|>,OUKlFVmcXn=2,կEnV@n(jIHϗU؞|,Nt+˪TllllmX`t.\k\^=LU/6W>i:Xv( )fͪWC˱˱׏ݽ5E;e ,Ȫt0),^^=U;`RYaz v(Ty@V줃IYXi#L/̢r=2rNU>TzO'CdkO]5!)(G"]PM? "JRLQTy1\CV]ty6Zx)XU0`VƏȪt0/<CyBV줃yp+Y@[WdUN:%2/+=*`'LmB(cmxDyU IS3Ud M^ U*`'L"k}Nـ IS:YZy-sWבU;`jCH"-jaJO>=6zH}N=)莻7BdUN:ڐTZFy!WNF+z)ܩQSh\}-H5ݽEȪt0QT^uOmR( QʁYщU9xeW_mSX@ײȪt0Q&:9'zlv(~9Q=G^`-FV줃ݽvʮNSA K_Z4Ͳ;ȃPtTڞBy8EVRU^R!M!x;Yv *:M")~k+;/)dnS/Zé*P'& &DV줃ZGeB1֐9Ep`v4eCv+\NCR#h #s};j!vFKSqآkI,Ss;qf#.'ա|' w Շ'=­Ȫt0Qk*a_Gi(Đ]?kUw4PFm/tPRg̎>P|CO*`'̎0%+Ȫt0;`d(#vXӠr Ic1L*`'̎%;dUN: 3)+Ȫt0gAe$pW5!v(n7rDy5*`'̮[ک zR&_b064ȪtՊ,aS^CtoŁj1EdUN:XfKRʫprhmaFWBj0ꮮdP I Wn5N ÝʥcQrhorlDOEW=idxGV줃-{r2Lum:PRPn<2R3&u *HOx􏁩KuaVeccccc?T,5N22u:+6ٵntUToEd{Ά$~IShb6Ϯ iWӱW'_9kxgccccNPhL;OD w-k54MK)~9Tl%jE!Uu+DG'q66666Ɣkcpq(,#sU]j(2զ"%GQt>5=\;:,B6zBE㺮*GÓ8mtBc5 {v+6+,\1;Lǐ=fLCSUF"VOҢC\1KO]' [fv_>Ȣ\pҊk T (-GѐfWqŞ~Nzlܙ\8^98S*OZp^ex{jПʁC|j٫s/労pcN3ZVęV8PӹpNR{ބ0OԴ)"[qgEo|=͵W=#,_dQWF)տ|-ٓkQ*6KžZu` <;"U(K[ax@>2$N0#xc-az^UWh=K:WJ$*,FX(YX+YTXcPdP"UiFl Cud'6QdUuwWי AYELk`)uEV/iV«!>7H(QrT˺0R 2JY[v) B?2KM#F'{l'SSwʳ!Vtd`VjAiکo#y_٧[t!Q~Rm䫮 tR4ʀɧa` S6q Ne$ra3a5FZFFg(,PnS_F h)?Hn#TlEvnMTϝP>5Fۄ("l= /;m{Xӕg_8QXNev+aC=,tfϘApN픛m&@i-GQP6|aO}+Ű/-8& @O^ovj+^T K#fʰNèm8&_й*K>P*Q6S.hKTY@Ҕ;=Do/{8=׍Kw*#)@@]בOql&+wmvU'|ԅ+w( qjN-KPv<& @)jeO]˫\͉m1[f/\'ՉsYh:CIf{)@((Rpacʋ҄K\c/Ʃl#G:u )Re#ѴMR&3\5N@&,G iE H(*^12 U?6#`_ EVC}ſZAGC k? ;B>oͲejOܚSk)6'ut%ObMT53SOf]i*u9ufE/G<`Ai]kQFR;Fg;)R >z9v3 'ZBV4VruCe RU~gQBx:cẈ+S!*)OX0Rd, `AYEdmirʣ`JBuѣ>lW١˶ ́a~IGN~'H#BHNkQF( {\EȕH{+*CG.mG]lF TW.)NSVDHEVQ ʢ© )" @%FXԕ0r$5EHNX.Օ]=ْDh-1; ע T偩6R omjqY5XDQ"?" zeMYK«J`9ں"+|U3`hn@(F`)';[ "f-" e 5*n_*.0²HP[KpM(y0;O!D$l €Yw]Dskh%,I]ˎm1>Spݹ銬=F~UyuTuãe4!R4}hցdQմ5*K֏G:)_?w%>YaFmè4ݦZzߋNz + Ug̾/ RRK_ D;($5r3M?!Etܲ=Zʯ^ܦ2`.uuG_o%(X '*R} UҫpeT>KaSd/AhGyM'cφ |E#qԁW.6{Tȯj® >4Kٝf)4ȗV|gExj)R') nSABFCR#TƐ}5;u\j%V_jg\CztW`5g;ܯ٣9r=MuOyg*Mԁ2}?rlfrWN}xq vٕfbd60ap瞺K\n6/_yTa=M.!|5uE#.af`a \…ȧk;Pf5 I-{R)vʧ+ BQƩΒ갣IЏܿrn# <,!Ҝ+;>ӵ(eJ-{R^&OW|}O%5aGB,3 R2B8\r!s/D>@jl 0R~yҴԴW̞(}40ڢF:ly$5fO )u^*kT=W酤/x]9-@KJwj- b`=u:փYSXY4dQآaI5K}]tu+*:${?--@GXAdmR;\nک9pExE$'KT F wЯ)>2luOtG>兔^f*<}*<\s"9p*ZN~}Gx4-5;# ;ufk{F \"\t<he6IfOQnYէ;T ٛmV <$l&Ǭ?6F,<3'Ej5~}ў/ ISyjmJ'7i&'Ej5~}ѮڣY7?{4MS+.s՝1GG8)p!ʭ^+;<WqlʨưnFr;𢊂ˊ+jV_|lkm ^~EϘkQ+կrYſ2ȧ_VRA ^^dN9{:5aɮmN_/ ;ShN9H_ϒ >zf`jEQV8^^gO\GizcxE)W4K%@`krMW)ҭU@ o< h" bQ/ endstream endobj 15 0 obj 53705 endobj 16 0 obj <> stream xu`G?]wŋESR[;|;rwkw0s+y p+]5>5~vl߉DZIs%aܲaߌcdZ]6>50ϱI%}Q/™/=U)V XITb߉%|@dOV}ؙH;`lvtm.K(Hqb ,`'z}I WYNOSS6D& U߻$A;/qL2o>rvoPJL)ʡW%o].56l8M8T3qH:ce"w)3SF_\g؃X<* C`Y"hCʶ)m%wgI;f&vY{xIlhP]rBϴgM)NHڃ`7|K 5Q[s̶) 'd$ن'70I ;?FZWtw64HAzqs69ҿ=sxlT 1sհ9/ |i}F<;eVzӋĈ]j;'sxlŽ.1^.HQNɐÕQsG->0/H];%4&PiӧVvŻrp2tD C~2{̬.k9YZ5VO4lLCR˰ɕ؉J uw(NoQ߁]s`7io^o&l?͓OZ&b`F;AIojlxfĜke25Ρ U)E7Θ_4J:ϓ^VX]EL+ ^~Az_ZXiŪk3U̷ª&5^pWe1ˎ'8Xk%PsIע]KC{df)lW#kdҙ(ȱ@tj;/@m]hp'PLjGTnXvq$Pq{8Ab$vr|w5cG7ݸfC>En3lη4J-a >w!LOI~ԌQX;1y/^Fۚ*_thQ#g휙+Ƹ_3vndİ;z_8 ʵ=s\6?q)vZΩR+a靀,ivpa Y{ʌVG; {hE[n1J JOzMRx$&EaSXN_z*M[~/E_E1 v^|j RNdk-R]lg4%[U{t:Bp]Y!qGzSDIPاj/Jl1дT2_za RNSCC@h\u)Whm%YLtBIK}*HB }aMHH4ސic8x*x]Frn'7CXFD! -=M$&ejp^vz\(t>YjT4 52[c G7kY::( .UR6ץU +3] [F}SIfH)}Wpa'q^v}B MBYߤc05#JI I׈UyJ B%=!A iK_p~w&HӰT K?HugnC$4k/~KYFgaհN;yKfƎ.I];?;ÿ`p_,F.N> ;]5f윢莇tfm*pIPʐPK?Qèd^iNc2XKa ;[NqU9ðsU[tX$0֟h^H=d$br3%a@qQш*K~COqeCcGǤ ;˰Y~ nTXQ;-da(X8m Aưc$"CuRou׎SB"-dO5VD A$} /c񗔵[VnAOut&]K¼e6:QM&}I (ӱ~ӥaTS*';Vмo+CQCެO񵍠>)NJ?;XFM0_OR𠭻ye!$TXn;TlXTai @) ]dt-/ݤZI>Ŏ֎n,UVe5.;GʢdEZ*wFUNg8lKQR %G{6v> gmc$J\Ry"E[gv~fJO˿xU-N1IĜ*e4tlzG5%ЀIbnժSE9aѕlr:H&Hʰ#&aApMvxUW޴’S;T,c/v$=!{XeؑЈuJ~ߊ7?>i $, cΖEH*COkw.*ZLiVg\AZȣ$<2LkAHiuPLaK}@ug,u)ó )MY[lI-(2 Fi.15cgHKL#$L%F0cûpud$늗mJ?擰fk.i@q°3J < ;j$<(Iɚʐu ;X g_+j7pI+^q4P:I e"Ql{VQeRݧ7K)ib׌$'c$04Z0E% ׌Bd,WX*q5b0M^$Pn.(fj7 & aC} V1U2S<;'hDٳbSi'rThIIE83y6x/؉&Ŏca. L*=xXv z+N5XN/}&%AئlD9e1N"YUFK,<=о(ع-"9-9K"im$#w@cG6} Fj$1MUj3Eۆ_vF1f=\\ bؑ*JI<;>aߔQi;{ZcMm;,+]=v#$ \x)$PdCE?|EYΕ 6z9$ ).JD&SFIV` }6RrᱴZd JO%m~K+;R:j# ,WJ= ;'4}AaȺZ1vXp QA"C` AUI>v#1;$4G(*nVWeȺkEf*\7 *;mr&Zv5QԑY\nҗ[ <:ՙFdP6d0)haA1 SǎRɚڪJ N:BrhtSf7-Q_GfyviN1zT"*eHQia7rB4P*аU$PaFn"P{d $Za}XIT +"5l,< ;Me'F섃J[E4bk؍M^ ; Mg ؑBYGձ#mM֞@vL+V;dnrA!ʨNCUy^j;Mag+$+ż[9TRfUQ[1NciU$PjN [Ǝ /HN&1c;{yML;eG7ވ&/+50шOEؑUPUW!1J<742.\5_;@S ;ÌX;0NxMKZM"̷;r>ʚRu4$2iÎ6I'VCwvi/ڐ8v`^H*UkgBSPwa ;Hg\4eIvsEAv`̩:lNiQuBȦؙJs!P*>2VXϘ N, Q|;̮+b$F4+_iZ` mdƺ ?|"8mV ;_hw5A2GnJC?؁}/IYrZY"SdFd²w$$lCXbwbGfiT v-*Y4 O^ k#+ $CDiI_|F2<"1D7Zu,r.+`}G]R[1fzs64n;&ء .pc}yH5H?Y6t׬&XAF 5r_}:`\ ղ>^/z0t~⦯˘ )ċʈBc6gd!Ayd>a-WV-LRp@c)DѭYAGg7X ЍcnӪB;ѩAЍ&FV`d[_]DT&Z$G$7Yeإ0~l(sv;)Yoǔd^_]Y|a"܎7Jnޡu5&fXx4S 'i,"}^:vIoyzJI5ڦQͳL?l jYe:AdwI |"ML]rYP$YB(v?@=3M]x.GK8:pdE1jq* V C޵W=c9޳xSk*vP~*<Gˇ+A$0kh;A_,oTXEӴx=Wopt"OZqO-i)dsVw,ZzOʻw 8F78*'OO.\JRR[Wgt|r%d{JJzZ@#.VJSO;zd4U GRlT/(ےүLOT~jYoCTzLMerC$M6Ɇ쌔cҖ,M, l MƜt8u!˩enwGi^I}ffÓ3~C&OEOKue1w͸LՄ1D5qrJCU 'y1-(Nø%L̋O$de@2yԫBy n;.E}Wp{UYzɎ=ebK! ob[LN۪9<ѧfм?&=7oͨma}3wjs*C%D9p|/8lފi۶3+*_mѭe^SbFxHrN. ][6Gn$Hi[W˗/+*c, CLT> ?fcQLw yO,..l qaʭ(u/\\\jnp C:wkf0vPs!oPVv2؏Gu7&n`5#AyBL%Wv0q."V7F!Q@\);CGtedWԏͪ̇pqY`Twg&+f{s?Z%QF-3~ گFkL2ۗNK·( 7|ʢ8\_&u4ݹ4 ̪_'wR.~I}K⺪%r-4\\_g s'ı;\nUUn1~i"Βg[ܝǎIq8G^5@E ({꣟՞,y8vLc9P :z V? YQ֞ıcR;Αb1t%ːc? Xi!wO,{wZ{GcǤ8v#NIW*C p*ry\/q<;u] t: g-9wʵQ޼ 5$͙1)cS .+#+r4ȧdkwb vBX߄I E~O>s!0zI C6I$'%o8NGI׈cǤ8v#NuL4^Lo:({A(""΁JB`\ ߚ7ͪ-v)~̓p)Ny~NJO8JWʟ፮:pSH>S:ӷByoqFĦ%Na8vLc9XT|;Wx3,"Ax?Ix=:aY3I K°RX{0Â`{jO8 ʉC ȂDGZ*QϿ%6A@¾Syls!q<; _~&7n. k# j,%^LaYtT.X'QáhkyRfUHvTy/BP7Caq22%q<;ea(#-1{ޢ (xLcUC6q٤xK ˿ZN-lpw"!tP#kiNBu`4٬sNS|J"hRq<;؄N*˖*VB,ՐԝRO6 !xaK-MaS!4 gֹЅ'M F9XHC?l +HsGg@X!4ìvy,vd ocҕ/A#HCP fE "5U*_ j}A\[S&F#t,YYEֳZCzGk(b'c Ӕ8v#N֪rhsP(d`^,dp/>Gqc%MEnm~sAYG=QDAhw1c /ҹ6z5V,Wx֎p-v* +Yc{:9v#NAJWH*"'-נ0<-֗V6gR޾0V&ҕCzcH+*@АDX~f?8H DVq'TNKv5p8G|0 pDXgM(#x @ uJ$e dLgoVbBhzpt/.Q9jHL͸[P!AoHPW} p:-v Ic9LD7mJu;Jɱ)%|wᰋ䩡Jv 0e:8#l%&v Hv=_/rGEwo߸zqkOCv}:_ρtΠJvom8vx^k |3[xi_z,ǎs4kSJ/dYV_A; q5vz֪^RK.=~[J1)culǎs9}A{Rݝ͊ ˕mGr8G;֓=.r̸xtƧm;Wo2ǎsı`'m;Wt6ceck;Αgbi3[] 4ueawm;ΑgbVKnTlc9L99aJlf{w._"yo˧P7 qT_vv9v#OS&w3mg u*KM'^+f2ǎsyw>(>uxoj˟'kNXN9v#OSFUiMQqU8{@X!>Peף;;ΑbU:UnHբ{G)R/l\ԝf!Yŵt&'$5)pгMf`3N詳g8;+s8G~prwd;QpW؃H?2y}>$;9lzܺI莥Ivm69tISyPђi^; ՂF'{(Xm̱y*v\m" = 3߲fL}O?u2Hݟ>UBd&PpP!؆zBw{vش+/]!D/=ې*3]8Xpd,׃9v#OM@UcU?zAN\aP[0r'IN( {QYVNQ0,NPh7BO2¯.Etɕ~P6>z^< `:ceSs hS_5R(ցp%/@N৻ZU)lC>P[B|%%?c`^dx1z8@K;m[ <2LskSh?#hZ6)t͆,5ص'؄x[ճXc9T,d7uT;) (X+Apx*WNBg]z ,E "J:tFB b˟8(iZ>J͹cŷF#X[$7NEFssXc9T\xlIsn.j3ƐXی;LnCI 5ZCG,>^H~$BodςxJZNe4m+Tl(aSWBͽ -C;kEu mI_tK, "7[F}χ+j2acORԟNTeKrG'@f2a.V+s8GsT~M l_u:Es\cӥJLbU/a!oBQK5/VOb\!H mZEۛ=NӨ̒y[^!_~]cpQ gPd3/e \PlզWXvcпejq t:ݔ /ED֍ ťjvXXZ7~-cDp.^Ϟ'B"_g9䟱Xc9TxEAZ{/$<)=QP:B)-Gu| s2C"ݟq /R_#d;[mRũ.R ՛{xTIϯ(IB ~^(^JQ?ybw}b@4vvS()(}֜NTUA8'$jeF{T0Tx^ٴa P4nb;pm_K :mONB4Սfk9v#OIVGQ! %MI2V6T/+'jkPX̴ⷊW.\r6t@xZ_:+M[Ƌy{)4t?u,cPz}TfϘ6e'b(B##>[GD4mVRLC%m _MtU'k~CQU"dmQlto/\bQHnuFݏPd).^&^P@aWCY]Px /Za̱y&v7Re+TV;<\Q0!߫{t} p'8LNj!ޤQ'ar"cmdآjs|:i ~$ ,Fq’ 8AiiQmR/x/Qw +5/}?&5u.h;o3Q-Fv"Ё6OlYqWt]lTE~,'lt 3م+qϻnƟϜ[/®ḠBOV _gfce3szAޥc-DH1oHHƴ h榄ɽ!}޷Jc;&Z.ӕgOpmz6tL=.dJMȆ*IɘFP60$$ǣy 734ϴ8-ةWs}(ZUA@V(<ЁyPe-,Ph|9_HA ˽>ahhkM1@Ӿ$|]  DvB#4 TEA5.;{2&Iw?R?%+qԫ+X]w4+s8G}1N"O8sF~SصmGG 2dcb[z)=5ը)܂$(-eJBwlԳCUlrݭUEHWkf]Dq-{Ѕe20ڜ-M̖sߎVUz5 9~_1?C;4|:+ϛFF}-J-dg7Iy[6+#4[Ui'D }6`  RX>̈́JoV";QCq7;EgCJZ^u6d;rȀzmZ6[^ܖ-#bFEw=&w<{p15/z/WښK%/#V;ڷ }ާXEl uHYj.c mVUYarq!`[x]KEe$&itP[PcҶ2Z9v#BKLk3D8&+:&",:6̱?{5ҝs[.\?|qQ-@OƏvG:~pWz40 4]huBfZy\]RV2ǎsıc^@vkz7gĉ ;rc06P{}nel;ǎYBA9qGt2Ƅi2Vq8vJ7>?fJ>3]ZhS;"~W-;ǎ%c[:{vUhķ-Fq8vNh2Vq8vRqz٦ű9;gItW\aư Ұc. ;o*]ڰs]z$, ZÌ*iXc9rvnWA| Kq@-vj+-a)]+i2̫B]ܘs#x\8f݅w޲4S)ְІ$M;&*4ʎŠ S d{Xo{X)o̅mF!|;Dxm5fA0R@ Bba%[1GaR`,+s8Gf؛HAM^Վ0EI{X 4;TK{ҨЯ6{Vk$Yޚ[+j&ۨPS%ư ;qlӒ'ce {ɧ]avj ]%la6H-l~ͷOKNk婋?=Aʪ9-+s8GN؛N B;I> h䰍Ѫak +VG[HÚlv~Xӭ1jaͭ޼7[ rr0հ=-p`̱9;r8u"lqCgI!HfXy}ֽX;!#c9;{z㔚VCkgyűMj aXAعXs:]Y+!Eygⲩ (`>AEܵm9wcG԰N6m tzs5s6tՈaO'YXDY0zW%M҅rvnt;"7qBWPp΅5&U젱fI_ll*f[e)ٳͨ qcr;qgErvHR-Zݙ.mRǎ9ce`秢 T$ˮ3,,^`,&MߢfervNQl_<;ڤsʎN//ʴM(ocЫl)`N_#֢ëyvׁ~ى;pLh 3ǹb)L`njCs.#ftb?ۜ<1%4$ "''M{DBs\%J 7, _K[iOP$Ve_̽SıcRK~;D;|KP3 ;ԏpvza5bm[ ˌ; 7 ٖyw;X4 E^ O.̠oŢ@p5%O[ʞ|| i+ H<űcZ1%Lh} M#?4&Ѐ}Lſc0/jT˾SıcNZ[ҍZ_(`FZ@/Gd;wʎR2Qv;J 5|r ٦p;Pe0L؈4zLE1 "'2b՟CZ|ջX; &; O*҂BǶ#N4vPuceG`DY?_ ґrJ;#4`j 9#̨%dO <׉wEO 8``Ý_Nv yar8$ wq|DT_p-ilqCfcX90on%=x3g2;C+FgMp}sƓސ`h &m/JxBclcG'ѦOT03ktA&N,:6]ztZP9ߜ"ufs4؀q4ix  Ie ([MX/O7$؉}CS).;_gm* ԌN eK*,fl+$?)دcLW7aP:⑫y~J?{śk9Ҿ0&ڛTFmj ` :z-p`{ǽıQ{a`R;>#?7wXnb"بO aV>n9|Dmݺyժz.͑ i@SI뎤 tb&()sP%SyVhc8,r/#Gӳ_ݝѨk2;HaM(,3)n}aÝB߻ukVW8`2:'ǀ8D ] qL;UdR+;X A;>:#ևUhOJrhC'ژ0Vvv>˝z'`GK9lNT r\fBuwTıMf;Љ._ bZ+`GKyQG9ӨSgux8v2v|!QRM;GYĽ~mtRj̱9;wޛ=*AQ>k8mҀ4Fbñ9;|)oIY2)nǎ6iXc9rvLR֡ {bij֢&̓gm_l/+׬۰?t3ntrߖv9y);XIعq['Ir`hG <;+5mӰZ|NmTlj49r-/-p>v<×r?K*#=p! ׄS&#ux$cϵ^,&8AQOѿIɴ^Ic^l>Bdf+;;;J;;=5ヽCDSM]!.^6=1P<׀BX[i=OF_/s4v1M'gV@,^lVdbv͔{{FYc",Ԅ<ݗskH5bm5+;;A%(}Urvӵ=SQѶ ?pbQ2FF}_/"k7Vv,vBրY^G0sB};iXc L.u|+ňxeƙ5j1җ>گ Ό٠\qrTěiu6o8]/yZ˄|sμwNWa~bU "D~~PyM{o'̓,h530^18 })_oe~K('k\Z;ceGW2@5(b*u\0B3^/J &9t:i #Ӻ?^y"m}/Z&B`> YejPނC6 )]{ʡ [;|(s. OhwlD6=_\Qd xSBvnQx@?:F-3z cGohtbȅ@2(~2qLLw"""P A: MC<3'oSyBkjbL'BwBP[ i8w^]VV ũɵ!m?!4z]j&dY^3-I8vխv hoũf})KŌ6oOulAx׉\?l <ކ%#q+;T^lO}21x~l#Qquu≣v6lng~)<8c y)Լ2dZ-6^qo;9{~ yɃ; g<71嫟PX;Ʉ1)'Gqn5J ;/A?nqBO36U 1भ5tեP{ua|!̻ #F~:KGcAbM" oE6opjB&6^a?;F`r@hJa JӄlƗ7DK;|/^n.XNW26^-?|]hY^h&DXiN[3\( nVQ{ xs00A@"wRύe8Nv% ]-ve: {s-kBb^tq. }5#`B:oHcb#is.Oq%N8;xd9dw #~MWt;;eQ[֎;;;Ñӱx6OGA/*~ҭj9'tǓۻwT,Wĕsdݤ}1S6&&g*3h0К(L8h⊹a4T5H.&@<#'LwOzWG\2cCQїS ?Ȕ#6 5~Ԕ ulߊr MkenX/?J^ƎuiIcn} T\Wt88fĐ,vFޤI3OJ*/Sr*+{ zU%vvT})kټ{~IɿoLj&]j>Bu vBW9h@ lLh gXӨd5vP8C3 B՟MC[H#cĔqkeP&\%l/kljGKV\6Mh=vyvWlsSԞڑYO)sw`EGXtކ;}DKsaQM"E v&B7^6s`mv˷oN C/垆`o;kϙ>嚻saQq;hLviʜ ׸Ƒv|6GR>"Vc})׳ e|4a*PBj{ |ʐnU :} )*%]5 u윝F-Vl>ẖ|fs"&sqfV;`AV\agwL AK.,tAejU.._o(x_:I})4\fy%Rέ q;\;_gTvvN1f R^bCqM;S0HJ`'޳x1BJ)r)` 1`'6vQI'A)* 8rd;g՗C'R]C U4`޳99),v ߲DA}ln.tBt_%JrKLE>sg1p.-z޾}0SKsyVvCkٓM/;U|a؉<󐉋x 8DZX>رrJڵSn;O #"YQΊ4.Z}Z&;spK tjKaA(pAWM d޴WB'LRZNΙ*wkNuv"oS{꾔lLdUEQ}9X@c%vq/ƒY5:;f!:㘑_\#眡Rߟfq#v/p]//es^hT;a9ƎPm^c"B&C?iN"D?~˥qvpOV;}C۰Z+9LݗU~zJy>s j~o=^X]8t rA|kAo 9xȱAou6˺%@cșnXs9QQ^(MvyRزJ]2QMDm>K0`>I!d ͯiMAhIX(4w^A]Ytv vbBؘ,7a~ SHN՗wj߼qLֳTil3V&U\XFp7 w`J>XgYKAѲ-LqYeGj0ONtS鿫C܄6<=TN ‚Վ bi=zN5"ٝ< Rw̚2mKqrįFOSTT[$g^B3tBigӇK`.Un;WVՎ@dr=҇b'-vَa,`n˃KTcllNnŌsC»ˋ:u;#s ! f |ĮraḼBɞb|frɌ0(uN;ctm1] {ydCkjllԃ2\i:rzkz[wA{zRGoOA X "e;y]JmmA 5NYvR67lA?Ѵ0WiݎSs)wڵjTٛ];GO6;(Asv"J|CxO#ǿ$a`BkR`>T#_fq'Z ڠrg=,ӗsC aM7`g&*y:z رXuda\2F uF/ա U)a$S畱I)iedX]_?Pjq|A8%]k(:)vi9jS֢(O!z_'X$U6z\cwV vl3V6*&Khw"ѓ.c[M)VdKYNĉAŬp)IiRlEǀ:vΧ<ތ௱})JK]qiW^رXK"v>{*P9oۀ3#pyݴB:ݵ{E\CK*Oi;(of[j_إx4ձ̧A1s\b)sR`gxz;+knüpX?3G#ommJ:ЯL$S;/YUP/etk#O`;+?dNg>[$T ,yf7M=Gy;BUxkMy&:5z "2dojhDY7RǮ͢U})dtajzjiKW2dhjcbNߤkߪ:{290ldG;O`nH4FP!RtyET{snwF7]O캧sᇊ넵v Z|}Pm3&c0f89SjLlPE5eѩfR+kw#| YzLkc|)]4[viV1uؙng5;aU;bl\ ]OY}>w Ԏ0hX޵簰*'pb⏆-As7'�R}Gj/)ϖ4֙kڟ_ 2=کK٤$P}@bzER/J9eJ<\ ;Rj-h˛ɒ/|_83Н̀5z8hIKo!EOO_KM,g0 9A:ǠʎM EfAU`˒~8WP|&/r~zosNqmWS#ݻSap뻷2\MkN&dPL4vl2Vާi'I9NdVA?h!ZTWuFaGC`s g4YI疔UJ$jg _V6Z ,:0jީRZ*)R;]-w}qw)Pܡ@LH#L&w\%Kcj 5c{>ѯ|CM_VtI>{^%%&*037~[0'hrmk𵂖Nt#̂0Դ(]fԲ3óvhZ5kT^j>K Y= rv?ui)}fsN=|Dס\G{&OL>z'=&eM8~m4&JXȮslk%jAY,%ɼq.Np Ν|ǮWNw-MT}r(ܵ"%F虷8MECq]%OTqEIjlز4W4bt7}欘7!.*F)/ڤIf[lY[^ڽW84ۚVRցS}65"f* Zvo߼a Az}𚗈z%}z5gGvNnazM_ +{ O^#) .\q{:_P%fz_`wBF{|{c6qjY_pyC7lC`If*I2W JT"qOYM7.nj)o5:v֫_YaRVGXc,ک>&OO;&&+oc:@䐆c :?Ge%x\=:T0bï_?yTSkH=!6 ʐ?&*d̆7Y^{Xt[{b_*$vxyEb,9rmU 43;xywfB.%|BS-}!M^7: RpN-<&꒠~ZS:bsƏ >NP Fv5f$,:>hx[;v&Z~YHh)wPwxI#kC;Oݨf&E;z=Ҏ!AMKV?5s> աן]|ZhLPrq Wpd@ٕ_/^$_/{g v/en46[&/tKpsWti[?j ORvτC-Vִ7+Rwvx խC3:s!ch6Z r%lE;s2ݤdePLR}09}\<^jv(hETtə_sf*8qgqIF[js5=NS|(;>&u \6*fk±NW Ťh%4ܻ$<p~'JV'iKIJYE,b!ôEN;҇ݡŋGGz] E9 , kp|E":-~ufFMR2ZqpU_m/^㚶 o{u6Ϣ|nWhJeeK~l>rin=VX){̼LL*)Y`”zwl'ﱬ}xY!=Y-ƊZvS<Eב vr XH%L=I:N[TPBرOp1LҚ2RЫuO ዺ˥ήOZ0$Y9>Ę:,vc~9xWT nj:ޥc;]ZW{w= ı d*>t4gl;veEjAYcկ.; )G;܂[ ;VpXf࿼= j[ Fq&.V>[KYSV.^")WЃ87 ׭^{G,|&l1IdrA;{m]RvФL+b8v椴sk͚KFA;G>}.:6%g+]Zʺa혭IՃ4?휱jMFCvj[ z(J; 6ܸ8վ8IT0vЖ)+! գ?6L2O%: l`x仑K^fHig#oLS 9l97]P ߬ M15Y=8UZkAdfS-e6rN8)ZɪBGVBmv"oVhl8F&C#@AeƘvl@;{c`Ό%ϐhDŽdK"9~V|lNڹs$YMٸ}x3!:y]Wg *%Ʋjn(:h'bbl@;.ۣC7sGIfZҎ aU{41!/ZGі X:iSXX[@>Rfc\L],O1NV7ʘJ(}|3ɪ@.m,?}>~{>(yZW}.QW[}`64؄1 $+M?#ʊ3*3uFcf,?e"&YgAZlD`ƍe=Ւbk.YaβRbd0LgqJ>L;ŴA;[wVaO;&&+rNB/|H4hrZh.߱Z s ڦB=ݻwnߺuI8ʶRf#AuZ~.GMdLIw()Anכ9W.uX (8" 9qŊMlB745&~{gSRt[.}bZp$J\pP7{>[.?!ˊqK$̫r{)k%"^)!`=m_h!:;*tƳ';d+BJ\0xQiiԦѝ;aa)w{-r\i'"k?ܟ|G:\O8A55LqJ Q\GT/Me &]/,d+e)NuUᱛRh?6Rpk+x~Eh&nL}× ׊I{mY{'Q2R.#ylWAMiAĸ 4$59(lyivh=; Xvc{N=7Y۞ YA0!4)RFg5A;ѣ]'wh0hyXXXSeW[]K H_gWP!h'+G@(:^=񲚌y $.T`V˙ǝDޓnMv/\ |餗c i_Ý^L,΢[Pt 7?$09'=>\xovYQЎoڡ}6]j!1XLKS~]F u O:ox?mt9+YR-,nn/|IIՋs$OjkԬZ]`m-N0<4E;& ^l2vXwBXwRnLQy-q~܊.$-=}2'og (.*G֡ 穀g"I8 QB5lZHlҾC/?)p/?Ec߾Wd't"i7 d-ȴIrm^he~$-KnΥW:0j)QZJPb‚/~vh3Hm_+% <^+J;Pg܁'8˾2{K!*`ޝ[7[ʑ>@ꛫEqcRY*r2j-ɌQW@rs0MB;zӧo~0vZM:eI'o$ꦹw D;Js[Lh풅gk,^^^-e^ڴӝbvNNFØN Si|pW>ZD7q=kosQ4+ (OQ v)#]7$JYwрOC:Hi?Cn8p<s-U,^&CB;a`1乒.Mk6auMESn6"@ǡMnlvq ;u'OA_[vr?H3RDf1eYkL; EdAWNP`g*i!nVx3`,A%5sGc1셩7S!CpRG1ghוZ*a_I2 ;hP2W#`5~s@qL: 9#&X' 4~-3yG5*m;5,߳ME'>hYƊn4hgvI^ೕ ]M8RmG5^;ipwR:!}z(JXv"o_2CS@;d4^t6޿m97ۻbN_Uձ_]tP&PnBН+*fWzG s&>iIW YGr-N\FRJѠ.߿n! ]IMg7ʟa>^B=W Ƨ?i~RM=AG-#;)=;%V%DXK@5)L "C[#ĦooM:_V;4<ȵ5,6pbL鴃 zQ87{vȡڶa%-[ݱ:"v sx Z,J8.wU!sHXX'X?} AD1 +ǣCeKj ؏1׬KgNƎcI ccNWNaVtFZ^kؙ`=ҏcDxqL%Ji_efo+ _\fU3':\KyQjiNRD;vtC߷maN׭Z-yؐ>qO,}x^YGc;XQHh YׯX7za}ݖs6ϮԚMCJ0v2]ּ,]+-ҎjYdTc!g':ߘw.4~Ä9&F]i"v6\xp2,EشWt7-=Vxa`-ei:MC(EA:vkŮXܡc$XC-exSHO;oo{>܆}eZ`L. ʬ3-Rؘ= տV÷8.7+/1j]ya J4aL;rtkYNrqDoDFHr԰G;#oM13Ge !jvcm"󵞞;+]oΜEt]Y?`N< VR.f#R>E)ͥ<\S6^.ZR:'V-ڷ">i.W|mکU&<lk]҉f~Rڃk2NNdXo% n߾sYSP}\R6*N/֍XZl$+8={T5:v73a Vu"M.$ Gd=xesB>q\栽r},Qe5bzǵD[9,n&u{_&v|3*:&6N}(e،?O!mLR5vr{SNa 3ZKΰ$ G# Z2ڹG:`BRzYhጝ[9UB pڦ,VZ.;򮽩hIyhćTἡvZ'IwN.aюF}zzZil`>_۟z_F.neV2opq+P5BAp0uډ*ThF qGE*檏gR# 'jcYښjYZ#߇ FxXSK,=)2zi6k?6G.YL$wxZ&< S0ŒqҤ*@s![8TT«2`F8jVYZg6 S rb0;Z 3JYrPA{u"+1cE-DՈo4>DGUT*|d+ khB/,K۷o?*K[YF;0qڴS&O4IkΓdDchNJ9xhx`N>b|!#Dk Ɯ󛼜M ?n;]M =]_D]̩+ʹ?~Y^leEǪ2%!Q?S<rˏ~0z?lؼ k?t5iݧ(tM}JdvP_-F7CIP4>pLQ=FAj" J"uwտI M92[Rk82Lgx`юk iǓ4]@2F G>͗}<sFL~|& k֑$1H`d7r/N=)8by;`ȯGr'V|ç:t3v\SmxV܀Es5\eYwh 7OwY{]Z&4u>ukb|r<{^7^Q֯z/*AK'9DI%rc*h$Z5XdQ7ApݎC/=h"Tf&S_çwRn 82f0 ^72 7Dx&>_Ϝۧ!@$vA(zɏE% Gk|4Jo]9""]i iיITAOm?.wd_t/n3vk.pkˑl=8B腂/^E;0T}F EN9Gt'=Й{A:~ wcSrS(9rmP(Rn n8G@sߺmy ]pgPmA{U8oM;.ܛI0!&9IM,VQϵzu5j YC}osM{y߈Lz6B]od洙Vu"~udVbo׶֯  G~!Gɢ~I'oYUєҵ88w8$':{ S*[ݦhI'wUOR¾I?NVM_1cʥqi'$^ G*LM5sX_X'4b|'aoz)8nRA C͆^-e&̥G!oգ?NEdGݱRK@6/?!zBƴsL{,٘#SoMRc|0 GʰЏ_vj7_f5lTt.ܼc{ޚY ;~\2`ºrF?c\g%v?V~89yf\MJKV)1;cj\]kE q FC̈xʨJ3MՕkB8?QpkNH@K/|ŽnH5?\#f0eravfLgfH:G,Bwno.}Ƥ/vN97KA;@UI{2>*}{oٗw|_?cF ЇX1}&$Y9&;u_ȵTl9Բx/ZZ@=WUЮ ~ZXDk K&=k_7zHbHjvEa=#iKĔ5O2-]C'B::h:>Vb\aPhN.6v(@o7E;_xjFKY)r&VI]qW}poMW8bt\yADKY;oC|5K`@yAvA'#/F-ڙWߍZ]Ԭ׸P^Zӎ #-.S[nv69U)}Ѽdm9휲si5ӧnvhSb SD^·4d]gHi Dܱg;`ڮ{ZSv>?#kYIK9M lфdUiK"S%15SN;hIlyW_F;#)"d(`-I7]}yXQm6%=7~SvB#J|?!SA;&CvVdU$==}gYVROOm y~eH8{=v8$i t$8+8:UD'|%B6P`0׍LUVk)ƙ! څ?W}M~|:ΟB|JZʥy`jga ~S.ry6@R!u*IAlo:S?kgh%Y{5WtHꠝϥsUh7Ix,R֡a.ėι!|Q^,*~=sTv/TY}3-sX>G-}Y}y9!PoXU܌o|R)JXCY`SQAx r;,ߧϘ?km9OSP> (hք P&6h96"uNhƚ5 oA;oSƲ}ZLsyRtp22㙪L_76<DžsyqyIrF:љZcTθ 1!4.? C r_h1lvѻ}=z$|v2g쫩gLwzHyFJCei'L&M5oѢe+:0 ]=~Q 6޺ ә.V/a}7MMM-Ң8 A.A$P런i'jRkr`rj}R?9ǯV9mP,RObQB?HУP{|Q[$gDR]cUTrj؅sN#L8/VRosфws׵a;W$G3V7³YPy]e,YoO  I.SΈܫەiKoܺc)K<:/с;NV k|5YgW&^>Md Vk>&&1K:Hi'c;p'YiGUЎeSQH Hn6t`K; |#5V^[DPDOSE@/;4C=H#X uOIL b[ $|#{qp}-iP{f[(mfQo $fZ}cy1,J ;뛥w;)/(~ z)([BNwkFFFA H*[F͠z&``!&-2 EGM~V$:̚FLȟߌRKaRBWH[ytt~A޽{7md ImOZ`/V\ ]_9]w_@y4)?~<ݺ/gvF%7%~*08[cUn"Db$D?B>ld"q-@bGe6l ϯdWr|INMʲRؚh`GWb9ѕvráz liG,&i)K\ yzt[xO˸/1}yO* cϫ [ hzM)}(j;oEwx@ O s?L6ą 3a9 IPolRɂ/ȿֳKs4/ԿN[=/8*qW]SJa{|ZMcT͑ǝD_ ~!n\;Qc̼98Bh)M}ԣ@<;NQn2U*B%!Ww8cgo]GKyMpaN5 /6shMe.,,V |'w$U({fR HW]@BNjBO͹?QA;䖊9hg=k&^_I\O;qrZRǝ ڡ3ilNQ1pdW8'0]T m+S{ʨO^=m=3.983~܀v'eUc^? vNna0b*PSj\59}!t9 )5t0)x/ڤye 91v ӻ0dQUw'>0O߿w۷nݴ3ҷs^-H4n(OcA[gonu,MzH>kAI/*AI}%^ fIig%vP%7?]^3qA;iGGE{KnT?ش \QFXkK;I&<Hf7qoD$F> sj%tڥ@>"T2gfJi`þ@1F5kqG/4g7tCm5x͋ڷ؉ 9b"3r)2ojr~th5]Oi'!$g'ď{5s7 LV)2 RN%D_PsZ@grn}ʎ4cCvX6ݠ2b[1GYJ;9ǝL.ؖ?56E:hg$Q1jy9ŸZ :|;S\ߢ!n]m`{Gs§-1jkF0JGe8j>ܿQS:vO<:G Jiqi?݁5%}}g!4KB·Ge.=iԷ!ŭi?W{(ڙOκ -Xt:gǖkWҢxn}|}3vw:yiPKY5ƅsZ)I"6]kQ%(v( >n^ l}u.ò"OA1@A;!sj7L%CKM;Ud %4xq.}`,7Vвfg9ܻ<Z^qt +DgCwOu4BeUIT\o7 Sv6Yӎ}eğS>ዕ4(F4!X*Fhm3mhLވ'y<\s|hwA-,t4B5U9Q|NfW)źcs̱|"f=3/u@h'NrFghs+0V:v>uD/^-;)yb8-:i'vT%wZ.dQ9tĞ8z tuU˹kBےg|s;(#5Mj1jVlHχʞzʶ7Y]D?:=Z:ƼQqS#^}S6Y*n}GϹ8I=j~6l79`r3ox+g6&dv&]?\Ei^\RrJ*VP|rʖu]-/˕Dj~+8-c)J9eHKI˷ TYj)P/:oFhlI,>ZR-ٰev޺Cv:|)Yln25| ԧ[ܿ#q~RO֑Fn;yqIF[D^ + +jZ,Br/.XY<FZqv?/Ty͈ 2YKZY, X8 n>׫jPJӠ=P$L4b*e>j)SDS}n^;r\wjF-WkHOF&[&iͩL tc !DM~8eY%t6}8etu n/tpo_{b(vL=QQ?T3.-GIK;Elٺu۶wܹk݁49=Z1^ƣ!l˲h/b! 3ma.dY3<ZAt}$RҩSs7B՞#H5XZK#=Ҩ-t=&ڹ%m3,,۰楋F+@GQmjfcu(dz -vPFJcsH[7˾ϴS&MM e$hx堃vTZD;+|I+y @N;hvEr֚G"4/uSI (<$UÆEtK+ =QA1j)ad'C;RD@^f]i[ U7έMVCN)e„|̨Izb ,{̸/4 /3~S"*Aj)o=_ ,Xp"EFюc  شsn O¿vM`N: ;_FjGq d3oZB".*bzmYiPV0s9 pA, ,L;a۞ly3 j ڡI'cu7trtLjF<8[O1H.k3j*b+@|}ZL<)c[ÜsәB۞v`2RVɲ!\XC& =;d{ R(\&NdݢwHug9c*bgj/"}i7Xĩe,mqQۘmꠝѫ0=CK9aeyQfN¥+߃v.Q\٤,eTh{35e%A|]KlSXpҧ4uKsVrꠝ›Psأei';[KY̤_+j 1OOfӢ+#RGih'֒2{0EH1vUFf\~KF:5XYN߫EO-̺X(v4Ų-[i6ٴtF5<Բ aI*wEB 1̇ѽ$_V/I+cj+.H@&s~,6v?ֈw`y>EW>dNN/[l$BΓguKi碓惭lM;ɝђBoxeRigk䓺 JȒ` h+hYQY!q=~ޭKuQ6/t{@:5^ zh|`i4q JE̅UeRy\m~dCc/.ؼЖfR҅ib:Ȓwث4,<0r \rzX֣6#QOECUͲJXNT–([uKbwϔ| *w|%ig&JPYz`6,uWnˋJܸe'_@: Ə`vISvNٕPt/ig J&jaig\LqUig.d5'<|̘/kaT'#S}C%Csy%yG9B\H9̐۷ag<j;Μq W@j lVwټFyċTZjN6m=^緡o,G;I)q}vCw^֬`FJho< qsC{*FE\BRр*U͍z3Ƅ $| Gaodne, =/1w{ypSȪPkk_~& eR ?$/9! Rf#@FtbvKNPduF#ܙm ~֚hh65tIó̗1kP#zQr6vZjii4BYu7r:QN Ry$q OW.~A/C=3PuT([gLY]8>:,0uWUÓk;MZۏYc^r䴓W @RfUd-qIgl5&)/mY` (n޺}{,Clډ.EvPb6vؘ۩Ujܲ5Lnb$꤂pJ˃JE^җ? ܠ5}KWTpžp3 6Қڞ|&ϙّ{M{mKn \Sh> cƍ;v̘ѣG+muX;$4?@MYx%N lT蠝Ŀ.oj!&NTQitHO$)7xǷ/m9,;RvVkDM,"-7VOe.brģҦ/hƋTI'E]5~AN;A RmY9\rvnbx*ai|Vv]LR-؛ij'v.xfpwq᛽EzYFKYc줆LzBr'@Nq/k""/WEj V;j8of m\qNuD$fTХ ЂPdo}{v:7nYL'.}8+ OќM%Ԩ"oO@x43DXb.ޖ'{%S\F'aN.KK JtPbzӧo~0``G%(u?-4S=QMG3:h'bn.cfLo M|N.v8^ D\j x M,uJggDtin\ U_Eh"r4Bw-nԩ/㞤h.8BN;_,݇pGu︃Q34K BJA-Ĭ[Vڵw>Qc"K Mٴ*Xk)wJjAcJˬӸ@a1cY&|{Q,}-,^_ OQl"⸄%ߍ3>K/N]i ́|݃D{<ۍ .o.pI(y[v5vB'M©)w j=IqN5dN+'74KZ|: AƕJvbq:dM5_Km'n'}[7ig~z]ʱ^ lo2T`1&<5L}vE~?yeJB#rf Vs׸䙻!rxߣCB fP~VmwrfB?Ϸ+ozJNQס+,kvgj:E <­\bW־`"B4?bei'@Ӆf~*,@C;莟%{wx/R>SU{dzZXWj$8f >=<˞,ډ*]Okޗ3z0Cߖj)QuBu ݌ּA;*Nܵ{wz ,@Ɵn k ShΛ9b$%7QI8O0Rk֟:o|>hJ\OfЭ>eZ.=Xd4wuB[V{_{n@oAփjΛ:X=,̊ 2 ׳JXC52v3٤>ib1ؤ7% 7 ̙X r3&bEW>xmBk1i&TI7٩U,:Y Kf˸;r|ڑ:,A;skR0vA46ux!ɭ >nNl2~Fotohx /= $̥|r~Z\TRDzǮ*nj- 8eK$ad@Xv޸gfVSK9<ig>% 0~i+{yi#<ˠ0qCDjLs'~V? dzDXd;GtFMK]h; NdƏ.kUYl W#hf*R+Fny;Y+K;8tN^̵m{eӐv<LaLJ?~/_}`IIDoRY6u`r JZ0-yݳGn]tnQitTY\4E;7Jk0*Xvg1ul-壯EFFo,pw:&lWag: ZsN2%ZrlLY\Uf@qyu1 ͉%^=wevl kjefY3g[I+C;Bw#Z@,yr5зhհ@ð)=m@ mas1~{ *ȥz%d)頝"UT dviMXz/ebN?U^:!V ŵQjŠN~HKYOdy݋մI)ѩeAIӢ#F+goj29$OQ;|Huj){g4.upw]>|p :llc.E6imZ5ד}OD{T:3|=3NzC3*2ic"&9Re8k^77X !z=cfB5+$D/K9 jQf`'N#:S! ;+񍥼BDc/,q-gJ9%Q;Ix`؍׹P[9fNDL\ɹ;R[_8Ո|O:]k11reJvSnB4[`=`;dn*(`QZ[iKҋ|:g^Iaԓk#hJv.栴f+PDe1.S|=Uz:V]uE1WeQvQВHv֜Ea΢;MCC~,T2%GPLNLXMzK#ϞfZ ˖>u(? ş5 M{vNj]rlҎ:SW ZIG,eK:tNIrŕvt6+gzz=3/uiP s8jq-MsR P xf5`mC(29[^RY䘷bPee0XvU+j#FDBT,eolta'9ϧ+6vQhF|iR UlBNCS)%\S9u wOb`OZAM\F%OPf'K$`ƴm7[VCҒvA]tNi]J ;c|vhK7R׽D*%.w W o4é!?pC9rC؁ U!#󭅺g&32,v+{;+Qc.?W,l@|_J9Q?t\Tc':oK͜4 8|)l ;? `'Ӿg($,Kn)7ng,eyUZc;'JrcHbag|!_QEdQQЊza0^Xɺ,?"Tթ}zzc=#+B){k(OuZTdgA4m:S!cOo􀏝=UӺiĽ.9'߁Jpas霺+v(#L,帻KBWYxCW,[mracg'w/yzdUN9b'q hW[v"r^r ;]GJښ#v2SɎ~*NiordnOU\,D©y9o-@El;^kzknA{$MwwU-q{[,tSb"tՈ]2zdR}jrq,Ud(6$qf/Dc= |MNXc";]:C0+-L$_tFhcg8#(X^m9gWh;ƕ ϟ?o9sfϞ5k.jruˤ*,w-] fag3$Qi^joki|ĝэAO4dy̥ciҁO͑g`\% 59)9bW|S=5"rg6oS*&oHj`YIKis; ;=b4aѮ+H\7:zZZfu-NN^KP祕^u\؉HսFuROx%čv*s-5f"$GP|K;ex,NGsbrlw/к3\\WU2 တv0RSJ: ;G=C-sMK9Ŵ;)Z'K:Y'_xqg:h`']o\r ;|A u[u7at7ވeRxوe=j]afTȅ~OUb)ilBq<ȧ/Od38B9%_`GNgT "DQ-Z +Iq:G "\Zr*éqagg߽=l~ԣ%vӡieV6m%] G&r13@`֩#(FyPas9ol ݼn0G+xi^-c!4Q%i{N=׷|mZzC7d`G9%_`1ı/i-.w>$v&b_QtNAC9޸t%6n*D'vTMCb,4QHĉKv3USqPc} sK,_yΠa! Y"KV'vEb'H#iV.Cbv^8=g&vf`Jr5B`ǰ7lAWv#[=葈ϳZ'AI{҉.HrzCݎ#RaqR^0={RuČKŽsJ#;e,\c p0jӭ`c};8Wm ܦHxƕoM2XLWnK#LdגY0KFH쐛:4 O Il" HPUcǁ?sZ@W2}UŽ#Gꗬ[;{4|o$N@㒢0Le`&lˬRrӟ;EaΕ#1;ɏlHߘ<5gD@1Ȣ}iRSj3}S:@גjs7 :I Vj8 7wά**`KmϣΚ5sv 26v"q2S`q&ac_u2|ɥƎ&sw7;~JѩؑA 1"2o[Z1- 5vRN K[Te"f 1k7H1;#1tRǐ6UTYo Nլ7rb艥l=2;bGr5Jւ -E#AK95;ϝS5dDolXFbqlbGr5JւoL~z0.cY3Dt\bq{%Kr5JփnDǖ)ϊlpÊl2 ;ee%GPd= :eTxڊt ; KEK`G-0nGr5Jփ{ _cx\L;2pәƤYf1A9;`cNdߓa'*imx+~[L)$-kk5j@`cGr5JV 1#xi}>wXʘS)f\KFɚ:k`bYxw( ;x⊥)4Y?P'ع'9%}\?2| %aO\5WJe7\Hɪ&vi-.aS9D-Ŏj ;u3uò&Ev09W+sZؑAuaEmo|ITUKY[#Q_9.v$GPde 42Z,9#aODFձ0#wjk;Ӯ#Œ0 ;xY@?\:H SRfhL;,l ;xj&v$GP#%vLKYfzXr'˙҉#q;&P-fzqrϖ'؉,+cbbGr5R`Պsi4W,h ;x2yK4H sRVErT7eج<HG#;9$GPde ni֑/2̀!9-v$GPceQNh2b)I7viaaG,9)N#*.Iv;x҉5vK:<،ך 1e']iaaGr5Z։xÜO՜܁y<鈥&9-,,GYNV8LY* LqRY'6#9-+\lmK$`+sZXؑAbq"5G,ey+g$,䨑zsV4q˯y,3እ< S;#;d,eGRNҡ%1f}Zfd ;rp,\:x 2rLm~xjy'y[#8v^[?$$'/و y76v'yy{i{7Kp[r5Z`!Mɖ;og^yq=;oyz:>o>uv<Y|!y-5+`vC~y+&X;ijH]k66B4BxyYqdד Eȹ9Eğ_:n\T\K﷛96\:όh0v$GP>r4:* I@YGP_z+BoqɼYȉU JG=7١#k4f_l}s8 ҨB(6kJZ@ǑWWr;a-2R#(z!FW"7(MBP+2uIGޒQoH58?;5zۯ$MeT f]A) >$K/Te;J9@oT:r* X=lԸTiuH94ec{RncOC$+eF`.2Dn\p*HmG$NxV͉vZفq^ZnO PGdHuaKey6ֻ5ϻU1r #CĎK"R m^TR:@I' :ջ 5:}gI:,B.IW#;M 5xxʻy(o#;+[M#gc#ڬ?u8S:lI*gthrRi~y5 ;GoQY?Ӛ=b6}Z܂1l7zκx@{ vgkKח>Tm0{0EoW !ʓcqXUY6D^M9wA_osDw@z"w_۷S LCIًvLtB^k41`ˈ-8[GasÊqog?+?M< (s$M O)[[%{=-do,`Ѽ7vzؑAyIVʥ 9*OGT2BݞP|ZzU$vQ?#=&IwSE1ĄsɝK;4BnT( VaÖQٖ[iWxXD @09֕<%{atϳ"XY}ېgmw?ABbږ}஼pI^`gYr9a6wq;@ĝ)lN\N7p  #v$GP~zqcFM%lڐZ_F_q"-rNPg=rLM.T򫐶 /JvA_?US.L&?BY\iM3T._խfCqJb-ȕCxcREz-JyEYnO})Uѭhhd'&MA?O)H< 2qozφOASpGF`[OM`11^45<Í|^[E`.ECψӕW$Z76'ѥMqqI!p : {`Gc;^#(/JKQoTqw{j8|4{p`ӺUN<~pkҸQÓ/Giq[ **Q}kNsB&}"Q3CZT;e! 'ۋ F-tTqƒN=,e.hX 1ac~(jNí^^ u{.M8w޶UHUk]t:wʺuC]Zߎ؀Tvy2q~?(wV \j+4$&rgH,5)h4KY%.9z=O'j,$MŽO"RSEGP,62ϯ_?}|"[ u)fS2ä!FVXL2Dn,VEkW(s~6߶=&ؑAyY@l"N]l, _R,ev$GPtIR,eH?v$GPB+eI2%ؑAJVu3YNjib*ieǎWbd=r r27ȯPG(דZa45$+eH?v$GPrBuu]MCvc5"dlŎ[R gO&n1rkQO)bFChIjŒSz#9Y+ L(sQ=tjڧͻvQ MaF"FkWH5y*c+B[>$J$ҋmP:|F>0u:2t`'~PP6+TjVdlN權MIVvTU3gˆy)w"P'#:DUg@2wF(A h3Jdd 5?",r4W;BAD9FL?MAI;#(o{6JVAhch+C!kиGftPtyzPژwrbFN=WRBqs:TPVgazUj D%g/r=le`vkΟ9s>ʤ;QQ[ gх7ۋ栧zB7dlÎ_d=@Hihu^ZR͠|vϔIڮ1Z{Et@i,7Ҽhu$D6JkPu6I=dwRbdlÎ_RP0}AizB҆pJEMF|5-}dv崈Z uB0Yԓ?QԍJCZZ:{:4Ve&ZNvtJv:H%Aֳ8ni3fC`[+ڣvăQ\*jGQ!2gM]9%hJg"rZj~ʏb)i?.y><6۞LI;#(JhreJ+R0_ٳd 09~>+Q!Sh@;}uB&{fq&Mەt'!|iN7pH@DKtC݈͉Ȟ~IrNTz;LkutHvb\Ѵ{nGS?y Ao^ZTRR/+aJdl J:Z |% L"=Yn.$dJYQJA+dl J\Op(mXBvtJv$Gdߝa]QoIV&AKdQ >b$+eH7v$GHVʒ! ;:;"3Ŗ$ lCI;#hr$f+eIM"ؑA# ;%Y2Ȼ=2G1qe[͊I$IB1v$Id^Iؑ$I%aG$Ify3;:&~.26rZ̏s=L$Y)W6d1{~E&JټY5XֈZ)?B9sɖn}C8 [nfTKWQ=0~4$+eA;&= ]}FE|=:}ຓ2qf<˾ڻ}\u͸ 1 BIlVٞ#5bDŽ 68_xF*DbRa5zes~YeҊ}R>eë^~3KTyEs)B6m}h'ĕYj)WR)t %t5Jy2&Ҥh GY$R6؜#5bDŽVʵ _RhޝCKtOoFtCZܴ,0OvQ[ñ?quwg:`uڬiњ3BZ僎!XaÚ$RxJ,+&Q^9629 zr1қ Z`6ieVٞ#5bDŽV~ #3 > Im[D7UHw'^ςf#6 L Dea z `lG V~ B޺U; XqW&A WxQnՎU r[/aS/1$R6loGPaʄ/pİfAeϙ)Zȝޔٹ')\ȋ+kӶ].=}wtn$>prZ:ǫb]x%Kz;R*d:+Ss~/  K\{+_S}.8:2 ;F*rY;O.X&E M؏ȁpZ$#11|3,1>55!r%J{[ NifW@KxL6]+t"jܦm}0Mc>4AJ9 T&@:)(RiLKLW1Jxv *r+τ&ס'Da  8V҆,֢'#J^=-72#a%6S7ء3;8@yp. rcҋ跹*ә|}֗u"a tRkQMܽ}9#H li}!3}NVʛ,83y3VY ;`*-c3=+tVN{^>ZWEbrF,֜:*o΅j:DTxie]=w$uRsHqwlDy ).[c<'mMMOI,$Mhx?z+]Z/# %BP+@9"G_.Ce?fŀSoXK1V6#ȱsd::+챔S,_Ÿq(H 'N.KϪ}o6*|8aCu/txz֫}iU}݆M[ xZenߖ.3f_`&'He 3MM1EòK$HMzr732a|l *clpGPc{#G4w,ۇ }τП>L Ko߸P.2a U‡>; junױX@?Y4JJ1VoKWAh;[{&}Zl B/AOI{ÄZ239J $F6*z@celkpm%av9;4sLhl ܡVAJ9FtIŽ1褿9;'dMf(4OWWVŽ1RdJ5õ;~{_=V %=֭b ;Fir JV"ΐŬ|nGҰR|]993q&XDN_[YAXЯ^S~V'DAu/~U'_Q}+ur$_T'o'FgD%禎B%uV1>(:y17/?GFя N^s#|fD<7k1u^|/ѥ ʶRFդvSE/6|uIY3(^aM`ntF )cR,|X@NfT ̢Uo||2 3z#Qy^e&[KL.kH5aMfefrZkYa&LN]Lvf2-LVLLE83[dxvӡ)YK؉g@]YyRZV+jR{&+ʻhf/J7hVݎ[4uV ůe@TŽqP,u\"OvUW0;3x3gTs~Tř wR3Lvg&fuoJLWL{33Y h;YM}= 3+zfdYKu53zYEW 5حt`c#೥k ĎJ1SvO8J>P'wGMq9\ؠNAaujGSE}2->Nmxw;fuH\c>onur{(٢NW 8+G[qpQ"$d}[~mQ<թO!lш>r{֖IN;xC{3NQk& _1D#vT%JVa#I9F#/lvĤ \ʄt+Iؑ)1cGfPësv$;T)#O.Iؑ)1coGړ.BUԿȠw.9gE&٩U:7lܴyV۶ةKGO[v󷟾E~UH찖B9av$;y3+f-*>8uFtiX67kO]hbg6d2- ;DGv5~t4UPS[V䳓Ǵ-A7Q;T+qv$;Mf^8;Y fg7LX)P/#7qg 1\ ;ĎEMaz\冐dnSPxm^uZa3(aGر×|5Υ,smuʩp#y=Meo1tP8Cرi:kqjc9vVC7W|&7ϭh o}9?/رaLB=WM=kT$&%*cլkIؑCqySA UGa,Tɽx3,P4g7û `]u1@HנE\"l$c0s';GwMF'G*kRj7nݩC֭Z4mܰ~Z5VXνkz{5?^]/-;9Vwه`Xnq ~:d.=akOEƭ_$[g%B0h߈{6^䊣b?DD%:N?BJ]G ~Lϥ rLKQ|$AŽwʨ JBn&{1+9Y-e 6GtbaуokA ;qYA}N`mDxNٜ,Ce1@R P#/0h=gt* Ox:<.Z-7WrݱS cGƓָx/0̿kO)_j @foOD E.3OŽZ7ű4vvk:dyv.^CT?-sŏZS+TMv_FȞG4"v, 3-n .6eKp(5&W %rh'H<:N,:(\_ e|#n˶b/]֖ "u][ӼBu\̆[%r쌸C;ofxMr67aΘ0|UZI  .":9Q<(dx.߼D^F{xk V62t%R=*9zm*]R+fN&lv/@ 6HԫJJeNSG=r[ ɉT  K ^y3 ;9(%_6T|Myv#sfVicǑMJ |sn9Rj+8{\%yH]u |4 jD+1dZU|ZG?'=)Oȡ~E~EAʶKΛ} .Q%Bt!SӴnӮeSI B9rS5XbΏDfx=EUS0ɇvNRt`Iy^Vu1Y[ny`˜iyf^Qd~z>hq70@%5㺪(m]b )=gC97f"2hVZ/Ye V:ѓ/mSO Plrݭ!=qȱ :-eeudF{n"}wm_S VZWZy\dqQýo2pw㷛}{"tqBT2>ti^>ÀZ-ZmOUH߮ \?zˏhG j-tQ1m _e"T&eS y&q}HoY@cϋĎ~9Z6 RVD:ˏ:k=ic~\8KҢn4|ɟGUų'ɬϞ:vxpoTϳӇ]66Iu܆ͪ:7Vnu`K6qsޚT:WN7 Sxf=k2W!uݹY+m\/&ԁ5S-8CB։k-ի'asE)Lp,/9%%g)#8?)O[BW*t*-aG׷*o\f'M8::E~`4WJkfb#IQN9.q6h04I5v憇b'|rJMȚ0Z9433n;v$aJAyW2&t2\bc'v$;:``AMdҕJSv$IUքNRv$%SVb=_)x.v{{4#8oV $K8oߓܼ,bU/?]g`?e>;5;(}H yBUΕW_;!0c^EX4w?o*;Z;꜌y=~N1 ;u!GXF\r:Uߤ0f~&3DZnڹ}fKr/vm>w:2﹀yd,]Jg%.mQ`wu7\ږUw0o/vdDz<22Z"P } Vl;Y{!yZƳrb7}w50+YRZ&ٍz; ,] ce؉.&OO<[Ŏ&tdC0/2<>Q.HWYLGOG󟟵l;y5<ngkniagˀ `*Bɽt y56vF=;!ݙy6L؍tH ;0(x= y+/J/;1l;_1S+-쬝Dbgd-潝ҕmcog `h BN[Me󏗰K +)NQe{o{ع,]CvXox%ֳ.XXjFz;v8dsع"pQjmu/.v|ZRo_bYJ Y)KsS XZ2Z^x%կrGلGk.H%"l:z~[|aeQcxS.`qiakK1 EU8yj[{YdC;iyb7"\vw&_g*-aǐ>&֟mJd/ɿȱ3">̼Y`h)NFg 5/Qv$C{λȱ1uW6_ Y:d 2{(+`':ֵ2uXNKK_y7}Q6vBQÙ|N|}5ufY2I ;JdpIk0a2o(R]+%Κೋg顦N?WJZ0lxc)'ރ=蠼IET[oX \mL|bOfM`g:ͬh v>Ib)F=w6.}U"4Ym_ sO̳?G\\慰`ND`'qf,?[ߟYtW.*tΧ2^G9_1l;1%UɏKLvu?ʎg+/ v*pR~Zl<gVC*f<+] J2NW85[I=&w&1kb=.NF'M+="?K,ϾֽUIpvvX.|čk#J9BVX:L׻Vbم^c_1 ū17Xh*T,!E#U#m"6%DS;o8VisdE=*YǵG[3XA>i 6ܲX7Xn U!KhY/pv0qUo(;tj^) K6Kzɍl+_zl8C*"?><Rs)k9Qw7A `VHk_Fp3,]!U"z *lZ-^ gt2sDu+*[ m2Pbğ26->4,DQ:Ȭ!5c'Mf{-]X@W^2~vheUI# &mĺ.zZXt[7/3vtȚ3Fd-]Ñk2e2F5 =؊Ce0G؎M&vs(ZL>z+Œsjb//Kׅ̏^>#cc)kcūNna9K5lU^t۽c kW-ڵiYX%Y ;fTdUt]!c'ѝ~0:1ՊJ6 6)T4va}\ٶ+3;'-FJ1UI,0=/44*c3F.LǹVmsW4nő_m'+zw=[vYKVvmVl:U;CTi>an?xU`aѿbJMnPkfvY^V7 ; ?jJb)^G>3(*+yJfCIWcF?Bʱsz:O=;+խW~결ߨKkfyx漢;*([ CG+}J3c)pesݬRTz= ._\YVy5G~Dk'[P˜Ҥ@e/?F/a4b)c~DF1)]bC} &ՈsuL;*bj"!Ţْv$9_HΕ4v}ڱq%//lrӤL#+3ꄉfFE'tJ|G-]sJ0"vV 0/=b.T/pRӭmANUѡMŽ_ID1/%1cg*ۧppt~:t]g Id:섵Ub)C|Iu{M79 ;QM;I/njI_8/P%'Nb!ՉU#> z7֊)]9>5YOk_\ M .[!v+VdG-V)^U&\Mdb`/ZҖף:SpYYSrwobg[QN04/DI VO';p&A_Z~Iɜ՗nq@y vlG~/a{ᄷVUopf"!~ I@N3~3rqF!"ǎj=ډekuyVXl!-[.X櫫(v!x?9 rapR4CIYu<ʲ6DR}7%N<κ}d+{b6;+A2 HV> ]Su#>)rlϷ)mD{;OøԈgmEιa*m: A.u(v>V39R'`JI(}E8(p)kGڞ:KE iO)x+p1ެ"/hM0@\CB:O:wCeb-`lqck:]V2RX`IW/^ة43glJ;w>Nd)x"-e_C}o6,\j9oY3 y2S?C"l%0_ݰJN9D T Ôj'Xy ^5 @,5cU;4}da`Ey[1E_I/f`gqL=bCCh}x ;T]#eh />)NBP0=wӤNGKqŌba'T&=O=q9v}ڵktgfY v.w,*&#%O$Vajasġ7tg,e\hN,u߃>;`W =BKܥ,cIK/_Ѕg%عJEҕTZSSVdd14z&`HͮN_^\ȱd!83:sEMf 6C}xa'q}3; TѫR;_k@'vGw3;_;tEOF yVU,J ;_)k5Ҽ3-5ɈOv W޺M:{`'W,Ĕ{=EW- 9rKn عZh--(@҈vXya-<lSKY^Qs-ОPOVfꭱs? };xamعΠN×[s2J=M&@bgPRfU ;5?F+FWgK,lMb'.~qcQ5~3OعX|hoe]0j)UWoX+9T)ԦZl;UNʏ&%v 8W?%X9v(i};gig{ᓅk ;3MtP6%vL|e)pRׂ9YX3d2?;5ÌY ЖZj=#m[6vj́9J[@jB&&DdiΏEb3jR;{c("rqq̼ŦLHь/KK{M"-\y۱QXa3AgZ@Dptgޅi" :(1=K%XʀΆ-q8!"[2-m:r VkNr 7T|&&!̢mJc&gc)igI(v~qcB 3o7`x&u ƟxG]Jlͺ59vK^JˢN]c؉^ M"U|^s?{gߴ3 w www0\[{^ZU4mnK?hsoo&rs.nQ,v^~rvg- :x 6|MLOS#?s4-BXRF-ڋ#&j:iv'J^V9OQ!3={HJXю"sjˈpT9N(g,ZL/J*p[Q~I JK٠BjmE+dGelr$ۻ_# ; i7;R)v.7 (?xIc _ʆ] #Fnz ,Eɾ .-,\+i]BWlً+)-8",K٠fv4ե0fG#.h!:Jg# .J;lP/FFzR'E%$hEMKā(RS!F^9#_b'R }*~,ݸdzS2ߒc_f#1?Gk־l@ea6+=3Ycy~7,Kِ¿Ly`jB@lu!ա8҇{~rt!tI%tc6ÒY$IWɠc'F>i8Qo8iKǺ|nKwt!a;عX6l`Vxn! ɹ\3p`8iӦ(-'vvEd)`J);ZO0J;8C4~f+K W&ń\ >\fă)g1ck[nj\XF;O&0otUtf0*n'~IˍT6#oݝUUpz?؝|c`Qқq{#ag[NZKJ;*QaT`Ο;U(Uf|Eas :IpykA3)(QWwkyI! 4e[F;Y K 3q-VEjow)jcQRC^{N{f-TemttT%"ʘr!EklW3 ufNP5Nw' ;S=Rkq.DݷI^S1LZA).%;*2Ǫ.9 ConޒUʨߓnΆ+@::ɳQ1tIia';'O\r OdOir&܊1Į(Two|E;H v-j.[dTÕ3[Η2ş{?aK9X+ҮZh̩Ǎ:o.4oҠN~܅Cl\urK_J?[vjap@?K[PJw͒J@(Fk!R>Ggi &Wʪg.Y )Yq-Ğp)(}TkoQةPTkxS&; n|Xw㥷sr3U# Ub+Y#Ǘxp~.wҰ38*\p)XY-@zo|DyJU' * ;adrj$a:ʢ֣}n6zf.ӦIt!8cR M. J+iؙ 77h.%o< 6B`罐n(DrR?Y؉'wLQaŽV ).N-h+9_;9%Mv1v2D-XkF8ewɀ?%~JߚO([[v;?)zc[A;MiJk̞^t`"޿/eF Dv'&v׮^|-,ܸ&IWlݶ}894PAQuA ]r)|2JOvjYc|.9KNY<.h.kCj.9?8D%nkץ!u0`.96^a:b'kEѿv݅%G^CuI"_V_Dc4ۤa'vX!;2KV.- ԊYy 6,f'_PsפIk 踯ᬽ9iKnmyFvsvͺSQNr;岇3al>vHHS`NrB1Nr7P)z·eGq#q;<٩8h%f4P&sGrνւ2+4.WA7޻R.a1pFsw~S>qk ȏlI95$sq ./'Yk-dt4\XTpe8*\T$+xsFwq_FƎ6<y؉nؒ ?Mv0&DEt_&Vʰ~.W+R\, n)O,h];i؉v&rijL_>}uJA֥RA.I%Q}r֮ڕj2%iO$Xc5.I?뒁ԥfKPϾ ]6Kv}KU]cu)z6.j9v X517]j+!E7U/ezuNJ7>"Uj b7 Q'|r/hTYaq֧f1y-Y)UX6<67'M:Ea G5!;G_ز:c:ъD_Sl+결^ذ f*IiJ!)؟2>v';:|mW=&(Zz^HN wȬ>h[1S t,+^_"UzQnF q3_5YR֧f|+WagūdLsE4dag&o DvিC~xǾ[&jk3Y,KY5U↎:5W}\GZf84uLlqu!ki_좑`_Y9zɈVް+~e=pj!+8s"g%Ώ;DR֧ F ~q-Td ]d3֒B+5ɉ?AED҆wPIvlػ N ,{zpO~[(塊UyCec'Z6%OnNCךYPMOo)@:_'5W#/a7C(v]1rHF C(W#V̦mV6/ux * N/\tk=m;ĥZQ8κu21T+@C+]Q(txؕš </cTQ9hūI Aͬeuo[@MƣVNknNZjԎ~;h2(:Y;gܟʘΗթUz6[Y4زIyA تy2Gl檲qШ2R$ɤ\kLh76_ꇚjҤ|bMϾ /ܬ0/][dt}Ϻ>U@GsLNw΢`@_3i{v @5U3 ?Flv5_;)6q)SMQ˖aD\E=u,`1/W<#|)<еa"^/^%[ddl-$zCpmsW&±>$PJgAtUH!U2clֽM`A5 6Tɐ*&87tצ g#+4yةZY|ȑuR/ovg꥽?b/ 0P+E:{kA͸֮=n?b㿾NW+ț^l2.=>a5Z=p$˯\j -cƧ9ܨ֠4+#ڈHC5Q lbZg~T* -NTĽ}]Nt86h][#Lǂ:TX=<1EqsfNamu8Q8:K{Ӷ?{m]!xKjR^c^5ʑzŋ=̺\`k)4TsVӌa+hz5Ja-M3̮+qs&( L_}%9K~ǦPԅb:pɴR ù\Ǯ5^{ Ecp=W[Shw_Qk&b>̛תT9z|ey5) NQ LFkRN|$$ ;^|WFvUlVv8K:TdNJ13c3Z.bN(Fb\eL8sޭH"_sepߘk;:C?+xv&scjLO8i,jխ['ײXghvƏ[Ή%#o [) ۠M$q~="{ǮQY5:m۲Kl) .-6(QiAdj vxިNuȢE;קC';3u]NIYۧoTITg|Z;䂋yܨF ۅGO!E<a`2t 6 qn9_>pй Q7RJv^ΞKYFUV7ޣYsI 0`KuߞfDvVi%::҇hQw2:<2i ?H ifTdjoЭ!ԗ>MfL#`Պ>_wlhy-_kQkYX4;AՒB@JK9F3cq!)u9,w ueJ8~Oȣ<7QԴ Klm%47ngΒ-v_$I1i_cu)$w 藏?vF/OaLJ]25I) ;;z4j(emF17"})mYa]Ct [Rǖ{j8dJf/%>(c„ 5!ٗrB(q:宎ab'n.Rh_H9Qz0S1^ⵝ tFg:HxT=8yup";N ']< rKs|T&v:⺭HeIH5Y&YX:A9v1Qv7d]Фm ;uqa CT$hpvޛ|)z߉dC8eoȝ;/ղ ];P%7΅cw]HZ= g'yqjٜU,<NOT3}zXɄΗ2% /2#pU!i f0xW8jVء;_wA2d3q7z]p&*hh`yjf@4n$TuuRPeW- *>2Y3Phbg~Z+r{c1P(wɐ`0Wώ7SvQo}SUd-7vӹ*N՞y -?tVʂ`Ucb*H6Z+Da`=JJ·/Cg'_C_'D3pFb{PPYt;;ԒڇT .v^Ġi+8) ;aUdY ȣYU>_qmVπ 0ht]ZҨ՜ΥnNCɣTm8액N[g ;w`Ust3GX$ ;#I'xT֏ 35-+CuY~]ua\> RƬ-󞔣Vd0,@.9/궠Da-zƓZ#&%z0^{ :dTբPv,%x=Ee;꼈O*wE n~~+aP+̮a__qHN9:$]pEFxfr虏l'%Vhtƻܱړ3@젫,] e/Da'bq8F5K׺;=JHN>5ko!]2ujώS߂T!e֪ }H#.v^L~J]IؽOX^@F})d/}V,9M7 JJ%:,IuAc]^ ?LzZ`95 5sj6 6F`Ǩ/eըx .;u3R1by[.\eD}2/6blk`R@;|)rٌi=TP+>*sVEd&&RdZG*BEՔu֨EW#!v{]U|Vb$I__|Vvȭmb~Ud>Vc'^Fma 3?ʩ&Yfmb@ZFA3AL$=|fЫ>'Iygyi: '݂jSRsp Fx~%#.E;JC~ 3LDa_ʜvT|`) T#Q$:餣N_ XG=}y؊6.v!3 ؙ ZQٲqrmFkϗr_mlTiݐ7*0:N6GmTՠɱJJk$i t\ pgD5G% )ZS7jkw#OrUbN{{Z?)5v'۱#܎-)4})kCi=a!0Hv'wK1 KK>* Qi N|k][q _fF&mi=:/UBkt]!ląкeOaQRʝNhkF.m{qbu,_2rj=4v:}P"S*5i=9W:V) ;PQثI zYP!jZ쉓N~QAw"^`'6ktR{$ez%QyHRֶKbBCW%|LyikEWfQ(mHTc|E0;3۫Frn H٦vD-/q3Yobؗ!E-SSvBbL1 4&3nh 68 Dbg%:Sl0.QYۅ@aZ6 rIiӘMa}t`' $;:qqK_&ISeFnPTrC]/Oΐ]ʆFl6u ;7TI <"Y 0s=ٗ8]3Dw*vZSvx|BK$s)TM'`սD~fՐ@39K, qj>v~0ˌƥNih\w$q,-j6)J]$.LMrW(i7؇WQtV/sfB:Jets$\cHNq2s]t*@cD Qع.ܗrB]t&zQpg›bJ3bG8y)X\Z6]V$ ;0oV/z{:IY>2ǂ /bfoL|rW J] )%UfժVI!ܗr]*rK~HbH;_YsY‚U؉U .#P< AR_%>DR֨bgR6ӻd`A !;D2{սvg ɫEI\ːxPm]\ =xj#I_Ζ G4"zW;iJTPd-.w ֩82Kӂt7Vf|)m~eAAU(rn¥XH;,8؉(5y b?5U[ s3RxI\oQ_k~/:%? t&Yfy^g㚭unk'՚P8nVX#5Q2waOlG#/JZ%ɰYy+)*4.o#JTAi~Oln.*N64")hJM#u9΋ģx{%d :JxSYB@eKAswNoߝQ=9WwA5Y7q.鰃Gܧ $]p]iËV@(aHB3HEEu@}lH"qؙ zfJ|kbEqkBOO-KҏN @F(vu`umv^vWWHk;;)L˚9%-zl_͚l?䮂{a) ™Jvοء5SMA'v+6iWxш#KYQLG7";aU ZKis6Os +Ul%p+gxc#KH*XQOz@rW:ev62-qkg ʳ-6t |Yυ:._s|K ibP Jc  )(1vkKn92Lb $[<vVRyv_*XGqJS rWÊ9_&Rc(;^ġni3[ٰU;9%pjz͘kb']k(|ivJnH6KȌ|,Rco*˚^nX}*HZ$R/el?3A:r6>"w5,QB /diu$Gx0dytaFX^6v~-^DU 3R5 ? E"S|\NȶVRz0V1[~B1gyNlDٲõPWt?)SXV;C82K±˸Eb—2K (a9MO6}4E`ҙG,u҂lHNrR+PՐG±svP_ʌNNq(e"k{#VA^/9ta%;͜I4D+r{'*9N$7?֙KK9 \kN0ėCUM HN3 9Ǐ/CP3,_av )gpJtߙqcq볰suͨSqvU/4TVh)N!CֹB:YoAMvj0 ry o!VK"3?$4wXxI-vReS 4]3>;a7M ;CG$\ʃjK8v~Wol@US-7ohsݗA|%af4 6UTQkk;1aa(zh]kjXk,0vKUJ LS@!M$ v)dcٹm󆵫/Y8_=~ȷŮ`)HңU,p|) y宂d "vA`Yp/r#.$)N65 T|ArWA"j6~DIN)Ow-׵2VR,R ^~aR POsjT`tIU)VK46ԫ[D9 (,Xb]>?#w5Ȓ$- q< ڞvfV2HR,\b'Ck`foi;sG8n3+g!mNI-ǗpB宁yz781f+<̑$,7.kYp62%#ȂN'бr*k`k yגWvIy㖳NE^m<8mf,X%9;]:Qa\ɑ$6Ia5'^ pGӅPdxWtC!WBҜ{Hm4 Wkogk㼙$7arWABdᆵ;sd;xSg/\nGO_~ыw/Kܛr@-{LÒ@Vibc,Ittm2e#d)bg5zFZII$ľj} \9/w ԲWrWA(H W$ v_OZHU`d9 |H}46#NizrW֌c춢䪕f⏝o=x3}(—1mn}0J*0W܇?xjǃqfJO-[X+H\k& 3x|!\cgO2>3ӗi}HZd`C 7 c lc`CŽ} yT2H7OG;Qz[ a%/^/]Zp7?"XHPa% E]y x`rf6/;-# ⏝h? 3RRg484^6Vd}mV"l2Թ <>jOH;_ Jv# _Tdϕr^2#13a'\ݺxyӠڡ#ǩy'Ն jªp(!ngqpj@vvz&JةI]J@tN|ry pS U4*[ kX蚋8R!UۑpJFj]zIcX}z\#WAF|El Ov竮&aG7]/ v^upשN*.FOTO-@1җ2brEb&J T}~{^6}n@wTxU[;uȁ,1OwyqIr@6*[;E!x4vBUUVpZ;F A0v җ2b#w=tfzj"oP[W`KHO.oBozT jTkVb}A<pQ aT fS2=ݠ&b설c3Խ[H՗\t=7{xE، ~0~#Z,UE$ Cq0q0?_aPNy]"OicS?(cz*oH xZW*|oq1(-n, QaiFim̻ 829#ahWx dִW粨t{՜9x7RW;CD1| %8u2ꝿ[qK(Zݽӝ~+ҕ@pTCRtfA+R+cr UUWz, O#e;?{CCb%\Nw#Ŝa YTKj$~ɘ V4וpg>N7P6o'tBzܨ*@7N?Wsj%`Xdvk `3+a /=Uvb5o4=3qwZoV=w!&}Y>u>fY?BwȷwZMEpv3*^<gUо oaPEf<ӔY J)IY~MρaXJM9 358b9{u(D\҇ 6Vؖd6w";waF0›?8{8kCNº;k.rBRiۂORM\MEV.w]S7ލ=Q1PIH:31S׮wޟ%0c%yJoVU;E/vo^ڦݣ̺/p~;IM=l`WG3x{˗)Yl.V˚)^vmF1'd]+pz95?L;E^saBDvN´i%UY;зbFnnkKk "YlD/M闈/e|>_줮hL{Z0kA/vx], ;MsCIXXܗ2KXL.nNG CR$o-RfL[V:0 wo;UpHz1)oP+ RR+jٳ,_Lhc(CDH:nxɺRLo2_, G1&gf2N"T'KaGYkd[_ԭ%ü?V95uD-}v^?u:RƓAb%Vp5 @+[i|RvKo,G3WrWAv]]PHTP#6v֔m\֗2y|ϿxUoJ['}ZL_N+UEAyl ,nowigL,G fpiKlQ2Stj2n})c*E]մeyT6gR?k]I/h;Q~i^Q{$\3)TtJn MZWI[4lVƮĶ]1h^}?wU#7pnpnf+yXlL'[_ʨtiʿ`ƭ2+bdCӧ{m@ku鷭  )(,d4i36ntx 4,(OX><;#ej3fGmtP nUWP}~y 9Ͱ!~hJlRrrjCm;Ӓ/D;).QP.A}U]I7h2'&NF X:w)y8ߠ_4ѝ"c9tD Btw' \Q̛:-/i0`n4^.-[XOZ8A },r ω; .{Co"Us_UF_q FSYcc{qÈ)גp^>:, nK2`<OOKG:(~A+0 M+hߓ?(h pl;?׎S:2S&Jh$P]ۿP\3?vu"k׶Яu.J\Sf]ԏ!J>fz<~p0D̘TCq9 ;\]֍x6@wG4;ug)NH-1`'(?m*VSJ8=5v.ԯg׎mu3MBܚʩh`A1-Q_;zLPӳL؛@(m7W0bz6:,c+:=jy\a7gn}\A(Co/uk*Lze&LVUjJ5P f`á};mZGL>?~Cow!b봋 Y]7vg}ex ; kR@l(0Q3&T16c;T4^g aE`:Yo41PMF::4B{@3z?;V+ JvI C+PkFåi=WSi0*Byr.JcK+R%W&zh80sfqhgA[_vIM7t4c| 9cq0azY}:X5PT^Q 3Ps\oC `̃⺌>D k4YNkYSƎ68bҿCLKgp(i.9=t&dYq0$+BZ7m &Qunv(]tͼ.ETz8fio^Vp|'`<;FlB#IcX%ڞU+kwFo^"Sye +g =7_¼發ܼyU:/xNDm`ehtO\W9-y"Û̉ݶikgϘJ .lVp(cRBL;BK"UkFy c䮂N_CF63m3ULNzx?։sn/oe"^y[!:qEޢ"yvz$c' :UMRZy!:$_EŽC6,)6 =_8D6vrV,f{ȁN,r!SېR`Cdcvb!-n*֜| 8D6vAJLšR & Cdc|T~;Q.d|ql O ,T`tr`!.s3~02޵VAo?N ?%u |/~#KR❍+pȧF4w=,FޠI'M?Ɲ{00,ڷtrw e;z`@fF;5#v>$=筐*<_nޯ:ѹ7H971T٣@=?V'pa 5lڙ.QhQ.bxFvb]\:26At օ(t)5 =8yiM+m7^U mk8ݚ k|M͈аJu3%o_yFV3`Xm:OԾ SīIέtK분uU4z"Ԋ]醦kA:ї mn|wL! ^#pnܣvXҦeĕI1.L7y' k;_G ՒG%O&`IO$òoQRdcfefI'jutC4Rڮ>FZz(w*z$/9s?5xx!IDc$33!tz1wt,8Wƀ2GM?686^7Kשp}h 5:XmNNGͤC`?tzʥ#/]hFu/$ q/PGV{C{+>Tor}Jw4&S{D52$ⱤM Z6.e'Nـ؊ެT"+EsoWCڻ5=ڟVD]cG[UlTƎ숸.KBLO]2I5#.O~Hj[a`x^=2u9ԄlI?Gm(I'}׵@y0!\/9C;өҢ bƻw չTfF/&[jZ1wSݮe}zGs|t|T PkN~Zs7@ܑJLJRO1?bjKÝS ok oq[ IOF|Glo oKڐs.+j!tv7L'N{:]/x>Ƙ8,W$تyORvt|{eaQmߝA{ :VT[^cgDcOT#z^Y`!8 TےRt#ߝ._GLqT]} ϯΙ9mc4inU<& i#78:g+[bD6vZ9ųUxsoe诳n\+birm߶;]7vE㑏^U+4 Sv<*^#՚ ]̻,Tt%>(^8m|WuU~vG|=#o;uese:,ScF4o_ڵ~:py=oR  y1ۤIWf݆9^.KuR>Q{5.wg[<^üll̇k 9d!}%OH}TND,Gm Ō0ifB8D:vzxDM3Cr)"u/ZAY6+ݛϋNLom8x1t?8|IlO˕`z x>orKXȘm?|^˒rW>H6%tAICcg4SVhtE+KNSv5pGi$`o{ԟ/VWNwI79A8'8dJMKg]}زc/8}˭Yt?|_okX4?PG<-Er_!Hw'v";sWkKV#[]^2|Fh}3Xtz~OnK[s¿TAe0'ڌju6FibT$PzU8!9u:Nd~R'wuG8qRr$Ea;upWKstNG'؇Qzk^\k.Q`߶QkUz|I?ѭVpz tڋ8,Pxۛas1ˀC ~w D _B6nԙ IJ~=T :(En+Γߙ&0RU/lΠdͺ` 5D;-PSZTWaۋo_$vٹTnҘq"FtP"wRR ,%F\ (4LSʾ@ |? cH}DTY)+,P0se~IMEq70v/Ug@qW'246R.ARtklI2vdZ_-5 &ZUOPN r<ա%^/5ۯ-uFGVA[]M&˩x72]JIO3]qKnY-& jG{!h1g*};eYui']n\59c,:SߤcozנiKfB4d}hCͩvfe =mVvSy+U <%ArA8!d@T+T}55XI532zԩyPDȬ"Ph|,+IK/s_Ο4K'C IEkUEAP:uuVjidc̑\ K퀡JY٤[燛n4TLxe'Ww+/n=RIѽCwzע^~MBc~/agvVjMuOyBi#ϐIlG^*|r0Mmj經/`q1H׈;\Clj<<-;r>s!;-]"e)i$v#Uݫ -C`aqo`@nڮ;[b21(h_Jؼ^.R*C?g27#wT0L؆'tT67|J@-SՅă5!gvŏg 5/}eIS45W>UtxHF>+9 `sd- MR%-u'ks=K-oӤ*g5*'jXvD/;-Ry*o,; &~+ wiΐn K ,;L◝ŵ7Wxz}z篥ALu؜; 3/M",t`Sb,%V|1@۬9JsUcli]mݻ~ ,;L◝ٴ{u* /#ZV^YT5|t ~saɭȈ;:[ohp._vDCNQd'ǨDֈ?TEJp_e= MW|V>w 8yzפ"滁xOeISʠۄbb{Q4_ @*78}YYKi0BEƓE}K0o.w1|IjvtQ-_~P~M[J_Kjԗ6@"r jQ^SJ2dP]w76Ȝ^ CWZa*~պ$Mj޻=AL>N8S6<}+ӿ.+oY$׌*͛TMjwȴ>c]Y}Uִ*TzG︬ηuپ]F!1N?008HoYlx֕z^B, CI&ʺM0{t_.TM]AZ Reơ/HJ4 9d'v&4t]]ߦ(}5XS$)*U(NN*dB9oNMs@N6»r-#OQTU,g@-²($fŽ.,c/90Ӯ Pbé:ɎXTK6I(3b&) 9+VY:{TƂ/{_^v'^r k&,CjegdKCafQ~=i/(>"1X֎B+5L!eGF!1|8?8 mIr"M|% ꌥ~1ɚ+B'ޘS_W/_HwhF>9Uϝ=szG((e+U]?ͨxUcl:. _@(΀&=V{ڋ>s\@Z>Q,j\{CiGŹ8Q2Ɯag)ҝF\e7U.mgNMA-pccryt`c8^v46\Mĉh2rA|JQ}mZj"rKxclZ:@>VH8vkBUfGu{0S)]N!?fbaC0[c:WϕvGvqSԢd% [)c?QC4 @vN-)7Qރ ;h+4QcZדtr~A3tD_gi;Y`P%ƭz0@[x#]0DlWPegz L-i4Ŗʞ@:iզ6{1ً*ӂU9h+gpKw\ [e3+s] ґUGt̰ܲ %<CZ6k6Cd(fdE)j `dof*CܖȤQ}N:aj8U;><3keu[w/ˈ( Jo:t;ƲWZgi8Z;|W Øo j(1ƣoO>wvZG᷼T0d`]|V]davnu"?)}W!!)G+`jؑeh/:#|aE-(Uػ:nFv^862ݚTӗoõ_]دAY 0H^$/ Dz'CGp5U=?wؔ!h>ګ +s( 0yi5,ewU1]*cIvJX;UٻQ$6 J75ư;vtk7E^?x*iX襝viðĵL~waN@WK+"2\>HMՔe2ͤ*Û鯫E+b!FlY'Ct:lUΖP¥%K Yl 2Hsn+ؚmsV~'gʖcExFWWoTxM-WbN_sS_ؾHY@ӚDž{o; 1V}oa/Nr pFkidK  5WJKfJ>r_lC/-O^X%> ldGS/D.D x56gr${‘Z?x< VѵY6h[~ncu٦dXH幔QF[bk_=QW6_^Kes!WRZРa{hF%ؤU"B?W]*( :kI2Sp ЇrDE}(,t0z% UO7q]ʼnaO j9=If1Fȩx/cQߧGmG듳Xt0IhOEKZM=V'RgxGDw\jMo}ɤP ̝DLf#j̓Kqܬ(l͛H{' LIiՃl"f&nQN3 ̒m Bp&fQ2}:Ťk(*û@ cZ8j,-74Ӟ Ehb4S@ xuҨF>8ʨ(bea> ҽ`0k{J/bCU$U(HERY]QO~W0 iH0zPGiԷSRsnQ Be?GS> hםL=,Dq*|(&8|FmAZd m(٭`zu(z&44) >Úȉa܇.Kv}+2usW0 CG-}xC 9RB:q'UDl*bI7K 7yccs $m$Y@vR\sit4fS`vN^pCqgN7`2Z>JӮ'vnZ["gu0?Y`VƳ6S/Ɨl#ݗk֍D߃` uf291#LJ=Hœm v#Qv֔2~UrǪ]EJNjeJeVrA9R=Qkn #uaL^r0<՝]HcsFUъ5]} DG}, \tvߚOQs%ZsrW"̲"gZṯ'9]P;Ym=ߪ]< `+k&kNMTj{gjh:c'i6C?391*Y |CID-|khgQb"3ʰ^I훩Øj9Φlr{y}ͦnlj_r:{ʖI2ƈJLdS2D) ܙ=`JzE# |(Z/G3pPޏ?ar]*J爊h9gdX;}qgkPWf Ohf|3|^Y$e9ا;J6ywp~:6gZqAa -c-@[Bcl<}vȹ|pW-ZDG^vlbJ b0Z\2.7@ymze0I7]hlsnџYՠI˟ h8n۹;bx'tg>|*eoyEe0SEq/Heނa ӪCJ> (+ۻ&szqF9ORĺ,wԜ:.OO=z%|NJSfUj*,' g0Z+A+AmSDz:7|[ 9ϼEuq'Δi\kU--ww@<&mlGf %:- dpDY Ve8k\9b07FއX^tKI7VՈT"7`11(-i[/OUnO} ǂ=2Źnn2,}ӡaTd#\4uu[[zdߴy}xen[^İsCpG+h/6Kdkx#+i3B,/<ȊAԊ}aX!Rdo9QАԖ"2Hm2~ؑP@Iԅn Εݼ:3E$`čСvRu5Oni6G{削P0b{83@[]+@C:/Q#<ɞ$W9v6+a0̏t|u788uVX)8VQ@ ÁL 9Biٻp"d#d )b{Yb~J8AZ:)XXkұTKI}~'D="!'JşdFWi3dRgQGH.݅&b{8}ꑍiڧNnN-^_C宏F0̏bGW#iگWNZ5'ih)bm8K hkRMExl\PKZr: \A7h+RvQ3?~ϵF-62E yFzgJMբ]OlUH M*7ܺ%;rjbTuZBtX@c0!UY JZX|f uN !v\la8!Eܹuڕ^ u*@qu\ysd͘6dm`B. 6SPzL5ԹKWAE݋mM(zlޘn{ x+UTk y<%?н_|c:HVm7OVAq.4tb )@`ptsڎ=o=0H<,OK8H v m%5}V|3K]BweUf {2 Ip@>RQ֢Ɓ٘aMyN 8׌IѰJfMI[ BUI'@"R(˺"R-r:z:u>A1 FΡjmVdoHi&OIO)+i>*'a~JdrD{apU ԫJXUE _Z|MmPT\vq38v>|Un`d,21lAoaBrᣡ=0>ti)OvWb!ܑ2gc{ሧn`\jM@*6)edsrE1 %tܷ{MܼbTX$G>4%jU{UE ;'S4j!N<+B ƍtK]͞F '}\ dLu/3- Co.kO< RP(i~B阱Όu%%Kw&9m^"2I|v8 C6/-l |nbwG?wO(f3{t:ba ف[atB:iټ}ga>MGw`aaaaaa'KW0%O_ta_.0 a)̈`w{a|X92pO3ad #XtS3a 0߇F%sJҫ(9V{\;bj(kӱae+PL(#7v/?uyv]0x0 X.C -E 8]*>g\D ʟ>qLݬZ09WVj(Vi9B(/fsۊy&e̖'K*ӂW~Gd&qq;Qx2V2oJsS '01X jJfP0>̺T-a(p+ETad[g:\{X!,e|FO# c BKI:p7@[L $j #qx'9é⣨1 ę }Z㴕ܜ㯱i 4+P^z,a^!9Fl"Sf4E> KD\򐵕 ]e^fk& c?Il3YPzbVrs!hFE3:NUa >ԃSL7^j [TR,6}rJ/?0 29?g9:Y39U>s-54O!ƵԞhSie[rdqĈC{wnYOvwnqҗoAm[659יv_-eHa+;윅Js4v$Ua[0a@|5ՐJE';st*kkAOt?܄-f >ct^3[ ٽ:NudڳfB;G"_3Jyyin+7LGBvVwS Zڳ\*`>2!ۅjڗ乭mxxymUdȀ;sBdGcXI>"*!?P^v{ymzU^^6ܮ`E_heqqr(0 8.쌵\AK4ʦE&[CO[SdCe"Ќ C͠@0)NjGd@G|<0۽j7bi+jv![{ZIv&-MgŽ7(PnQ({c,CQQ MzM,y<-;QhLRQF)4 #oBRf$D:hMtXcNҕn ɝD`[[!Po!);,މtFv\EcTm ԟa@jg]Otԯ>01Zy =ž?eq ;n";5]\>~DQˡڀeEodT8׼ˎh\J-W ﵹW3­O0zYJ;KȨI-&x"5pEqsRUbNf51~ ӿHFK/,Z#;!<_#;-ZLZy k;D+;Ğ";kŁC,in";E $_XS@Nc P& 6o$'2h \_$tiFvV@yFvdP^v& 7o0 ihe@!Wdg8hErEe@4>,2wkN[+߈1eBEʵ6FÑOˎ@zD6i}}`eH)&}Ivܥ_APX 0;ZyJqG7 l ;!s';+E**t"^"c<:tI#lHqї("!tŜ,,PCd); |Kvkm]2s vPEF:FЍd(%v@(.dbA$Dդi|2{`TPYXCܡcFzbE#`S.9bU}m ~s@cN7ƔmʄGbH$D~0K3@d~'FaFv^ٹtu2yp ǕAA|-Bǣ^;mP:c~PoC| 8 ]·D3IF06 UG$hl/5 [k4eguJG ô˾Յn1?BSH.ʟa D[# [?bTS0!P5ͷ}M7Š]aKSHK}ƣFYc@,fB7P8,úXNMF /bq?}ĥ&P]uW-Nxa᮸jL4HmOJa&B,;̟CM'M}B妲+JHH *:G:kz|T/pqO֪a]@,O莪"*9kӔ+HO4ORN I³-TEb mT'|NvZ h 6[?]X'}ˎgH)yLQօ_q#a+נ.dzB̓PM_ejK/bfx"e*h}M!_5 V쑱$HvE)CBvqxկ0MC:̐zzC //{^a<vi1ou0Vn"=z-ӛ^^^w̰`L94żB1 ҌmG+1Ic\M,h U.ʣߢF {\%H?w 0?%.ih> edawCJQd ΂e\ T.v:=tsصS'T.W NPa+C=Kˆ&W 4kLc{K8I&^sh+FT~O<=V,߅B(׻Ћ}לA`&pW%D1M+;8GѨ ^tf Ȏ J-ٍiBB҂hزsYH );F5& >h*x;aKoMGmxi١podp/Q*Z dyY.H 9G쬃&t0WZ>!&2- );tkVy e QWƅ7Jjwj1%eGd烵6CIÛheR$j`$;`dg.I)#qIaL:((OZJ)s@W-7/ T㬗g&D【"Yv)tL28u+LÆP;،Db3 ǒFp2&eƏAa6LynޏaD(iQ ݇aRZ) YWqz|hen!)\- RM%Coőzh^Iy U'\ٯLG}E],r4:i?ٲ@>.rN]]JD/Pt= du,4\R.I"#K1|R7iĎ!+n["@e # h0 #P; |o~鲦T^`φxqv|!73ԕ/b@]xB 0a~*^i U_ 0i, endstream endobj 17 0 obj 113074 endobj 19 0 obj <> stream x33T(*T0P52 %,JUR T(T053W021U0L, f@3 2Fp@Ss=s \f5 endstream endobj 20 0 obj 92 endobj 21 0 obj <> stream xvK~Uw9?2\ _wb{TxOE|0%ȰÖ?tהY dބ]P/CkXSmyC^ xMy>`P#xx9E((TfD)N>5^P=aaffK" ~Xeh G0- }W}nZʰfK" ~Xeh G0-z;kvR70]P/C3 |Zlo}}VNʰð=3%^N ?,2TUE4# ^ȇKɾrX$e،+a؛/}Z" |b/P25D@%\RC4{^ImQC/u_ZۤЮ(X1ק w{[$]Yg}٨ LcE\@ y͈U u0\>5oP[% @26JFB5ѣ4\7@SKʋIbHXCbUXc ؉CV??WX،Xy.WRV (]U3m!eQ3o Vo8ڤQILò9bg&17&c QՋU,0=0kR X0]n޼2sW/IFON_hye~TtEU=I2PsC"N7*0< %qkn͝t4F p>#hkWXzFU/P3vb`b]^zc+ߋK22dWŮ)Z8#h?*%wj!eBdBK@^p *](ޝ_m9%FGt )Gq/B&fCGOoG֝;ck>Dy`V2K6s`@p3Qקe[s2ТπsFknQu^IWd3$)4!49}!q[u'-d1cN t2I]n Ly kcJ& $_ܵLwŝ=73}༟Qgy@P1t+Әjmz>gH {MNwi;i}:ˤʸwMG z律&I $cRܵLwν n8E}! ,JT]z>KE%e̐T>ЧϨ3j& ?B1^0yf*p0`~$-!3}X~F3|@n֔y^sXqW!qgyOQqg$L@CK>pF*[6@jlMޒ>h)a|#\=Lڝ,upIS'R|SwuK ih|AWv( !& ÌEi/u2c*qMhc>3P5{!U,upISe$'>,3 ;Чjl"k2DFx, |^mKnU X1o`3`!]"ՈMLƝ7ݬ0Eߕ@1 .Ui^gjLғt;D+!՘QQY-)2@Ff,b 4$mcun% D9mj|3$Kdɸ5F@rC(FD2{SvpI]Ɔwzd_P ΨymS5?+>Vs"ӌk4gHhp5bqM7k<=|FhE-FATk= ԩMV;p|t!1{r5( up d5$Oym6C?k>Vs"/R"6ȱ)w'&Λnxz" ъ2U(x96U.(LOplϱA Cp!.ϳc5Ǽ- _gZ*IؔqM7k<=|F@"؛ɂULF+t` 0"'9+rv}D9mtźRؼaoI Ok &#Q]-J{ȋMub=>Vs:/O]ȇo9[RoY.˨+VQypIi%8f`zX꽲c>n z~#@W"P qˊED9m7ELؼaoI OeF,[Jj`=&˞w8\$Z' Lˎ̻,- cݶ^%_ۋ>PsK9-7e {Kj~-55*< w8\T5L>dw{Yܻwr26JaU,e+!}찟ޜkef$\?}TZޮn8:ƵQz<&+w8\7bf$f`zX꽲c>3nEWן>(֧ w٢E%;gצXU%~F"')飊vetga,e\ _!f 3ʃdd~~Kr;t32玊bxӧ w٢G";>^UNFI eU] 6"Ҫ5ѽN7M6f7>颓Ξrnc]Nq[}QpO fZ]3Wvjt}ܤgOgY V )ujIt1D>%FLN\p|ٲ/7>ϳ7>qT.W CVmkm+!A·H>hÌLTEDwMt/yM:ԧ! /Q brᲅ&d_$TkLUW3 (rxXu=Ld܋k+ڣ O0@tW;/ߤCq""fӯY8es3uŘ8,Γ%v2VgWpl+u=/LI>k-5j2.n j8yV&'k#\[dCM!9ΨҤՉ5YNW&4SұeQ4/!_!RpFl]n6F TUdݼN~A>Mg`']d\"dyCpm$k*As#^yfI0$bF=PLmku5ZNpRd^Ԯ!_tHI!b%C\3ɫKzˋ{H6POU,'/陂D`HČy&kX]yvY:@2-qgMzwuK6 ՛IJ쌅Kʋ{Rw8VR؛7h,Б^pLpbI?))d@yu1הhI(פpKyAO><5npV!)X1Xjgxp?y1y( R}vXis0$bFćf3p dWc[N t\G/ͣߥt۔e?o()4x @Z*; aR(@Z*0v_Ln ʦ5?T[wX )0SIh>|?>|~>:Ϲb>|snÇ/|?>|~>:n•\QJU+q-|mNM}~c`qhS~m"L鬹^_o9RV޵l} TZT4Lv*H$VXSb[5 D68fw giO[.'z ?bwVNuroq>ؕWT@pr; >N bmYe RlsLʖ-UQW]'cݞ2D7Q᪛r]RLޞhquFI[F CgT%ވ.ʇ2tQ))2CؙڲlsLN-G,sck׉}ȆN\A-]^cqCDV Yqpks`1*Wd8YQϷ^+}(QtLlZѾ ?VmD3m &5ϘP*W"ʬH%b2i0VV=m-uDz(#"bvFb)vaun%N4ў+d&vЦ=e鲱b5O~n,i60)DɌ|ڸBk[n JR.I-{UCNo1 @JSlvkdc`Kvmujs*.Wyڔb5o ʞXҵ]7qPqhtX՚n8l c?: z 7۹K]E`-K1z5}QOu*N4lR}퓱5ʈ-ޫ+TQ5SlAKF,W. %8phܖTxsz0G$o2+.۬:Ȣy+Nt=~͎iؾj'k֐8\[FijA#W.-oJ6&zevC赊و>jӫGYM/b[W+Gיac`?R}k{<0a6%(.r8t1pZ!6߃&22r_T tlNcn"5(E,-Jڪf0buj؏Z߫ǜrG8`_ ׀PUZvj.N%@io906͢rB+QU5ӣ`H*52f)ĻwLl-Uku}?V}*D6;bwaТ["ebku"t #Ne=+]%ƪVx[Z"Y#7DO\PcLTJ*Rb֏FJalC،wT[ ambӘ+{A;z+ٵ@ɪzEve(^abv5Cu2 "OlbIك.UjG Hr1 [T07.mkBZزa?c3:+wʤ@C^ 2J:NpL,- &y*xk pL,-Ax'išq[*4lRq-٘:5 J>6*-;on9mVnt>6`u7eL2*"S̐ h9vjHQn=_||mi?@-lsL - 5C EKu;bc`WiG~Z#\zi$^}ښQ>SZyut~INb%2*~e}܍`c`c^RwsBkWdRp{4 rubGO.Y̡xf]d Dx{MKU+#0vl)4,ZvU4 >YFFj|b!l-ѡ2 #mi]y[K2x.L tjzBtUu a;NZꈑZ7_aƨy+LPU8";ؕWTCw5$C[.(%^vRUF.z-nt;n.C1nUpdcA(-G]+ӫS9US.Nyu%}z ͱV8T;RsuWX֮֡")D1Ő-ʰR팺>Xcux!Bh\s Wcŋ먤V:ԫT$})WKvkҕ$:s,]smJ4~4P][֟Ɵ4$z"LO麵uk6JW ԎEiUtv)ĠԀY7W1o;'ܷIܻ_mROOKp|.:W?* T.g5DzjUc=\VE꼫J/ ~7Ya$ݯvj>b WѵGCW^L+5T+))W.NzdUlsL~3yy/}Ľf-gR>nϟ'zq5]O?j^F昞wZ-;'ܷIܻ_R64-Bn剿0m؉miZa$NKӴTw 'ܷI `'9ir/Oo8-NlsLR-^ s&qZ*昦[ <MT;1MKuxy/}ivbcn!7_6R64-Bn剿0m؉miZa$NKӴTw 'ܷI `'9ir/Oo8-NlsLAKӴThvbc -NlsLRS؉miZ*g?>HZ*昦x Kn `'9i6އ 9i-昦x6T0miZ*ŹY؋miZ*YXv3?~n9{BYlsL,=- }"&elLDzݨ0\64'ާ<#v)mˏDŽJT-ukU lsLsB\C?ZP: mR&r`u1 p $O|h~C,D~0+i?*QLXmi)މzۡrf^vĀ&pxClZ ʕnϯ-U5fѲMS~_KUv-[M۞ml݉CKʘe:x1ͦ0ۛm*jזF)\|j߫r@W\ A@]+%QX].#.m֦.h._mR疽yr[r(#6Tͨ\ysQ,Rjaci ex[mr.b8ڷk-E K!m㋻< ڨWTU {s婭Ru[ rRFtU.-3SD\˲YT/6.N-ØE{:ݯhNx{NV ctZ;-{- GCKD9wh QsZ*hi?VG. ӡJBK,+~[ӏ `4S{@K5GR 8VE$M T(:D{1dD۹͌ꖽ= o'-UựF[ù%F8Iz֓ҳԫAْcwFC3]Swֈ?9bh 2|Ѩp 5qJ+V,mc$ NLmK84Thû_RuY>UFn][,۬dd(vS3؃GN+nՠT6 `YhvŻ_RuSc{UmDZU.#IכQ9ژ0 I]ไN5{ fjc-UY>uݍemosY 䪀lʼn(ߥK7 XDƻ_Ruv=˧8-UxFRx7QZ]qFm, >4So_RuY>UFǽF2T@jxKW ehǑC3-UuMluUbt1mSэ (%jedOikiAKS_R5`9+hJ{@nMtJWFRzhу6cuD %RNTuMDL ~EKe`;G-)=\vS`14m8N&msAKuvυ~mx+Z+ηqg ?o`H'ErE؛kZ +c ~x+Z k )nhYOZ=8 VnT-^-eLmyĖAy!-_$-L-UYA-U˥/xRk|O*Mg:s_AE55U)>6\w2YX1w-ՉziXAl9۬6\@7|ms~ ~WT'Z T9zz=1 +(̓r|!-_ cO}&9+Z*X)j8v=ʶT*λ㧧].]{1WDQi\)JJ  |\i5pD=kHo@|`Yhwƙ؈n *@J.z ŸFeZ®VЀ!Ym*ei*l35IT3$߾+UĠ~EKu@tsyrD7 Li :;GW ՉkDϺ.zn2&*| p;KTŪOA~EKE< \#]{hS3<ۏ2q%WD۹u,+(^Q ! p;3TaOA ~EK=B#t7rҚOkMjxkPtE T^}ė~ -Q2FJʑd#޺f^,W8%2EQb fhStHm2 ( P ZRR ;P3.aOKC?6(h[#ĸ*mob^]ȮYWF7Q[X.1S\7\Š[(,BNKxOKC?6TowO oUfb!,ЕO+ԪA\o Q,٨B@SxňDW7.@觠wbS;`NGrW@7G~Zm]Uoɠx["@/_ͺ*,p݉zbySZdٖox+Z*>jٻ[V4DvjGmEJη ;Q\PoY+e{YS|hOwT.={搃򖠥 '+\-&%8vM `SݯhV"SyXHKkB?.hvNuqLw9Z*x"'TjLYmjTK5$(,\ oscYe ӭ^4d xc[TIh쩤˨R2;+8w C;)ݯhNgOy'kgHZN(2,Re|rOA~EKu^kt[T8~gH[NcA;LxiuOJWEKCKah<fCK-UGc V~ 2R G? +6=bQ+\COgכa ײW5 Vsb>=Yvˌ*}Tfۗ+.)Hݯho]3q#cMQXbKj@ywVקmffԿWj( 6 )Hݯh<ZrеLr~v #ec)QdTdW}2P0dZwu௨ w"V#gn++;w,Eg50]m&jR *K%!ockhzN<{Ĉ2>bћ~RL\1busW|Lqh?\0X |`{,FGPMHP7|Vpv"SJ0j,:4& 'Fӣo7;̆Fݯhg]i$]U- E%) c[Xdr[gHR01]n)]A?WT]zqWtq}fՉQL_ԣ{]}aΪp%îf1}$e O@-US/+q.48*ELLYM!۠gWڊؒq%(U+TR@-AyT;ju%f.UYDt Y)͛BWCխY>u%RogjU3y_FíkĠx+Z*}5reˏ.>ɐDFX:[LOʕBt@[aeOX-Օ\| 7z OeRĚǴOu\#v+؉ -d+؉1]G KᯨbhvbHKD'$)Z*_Q['-௨zhv"RF­їuo T~ JfFnN?VbmTik.#WTp mܬU DOrc]4 KelG^1Y.~ n_*J.pV{ܾde8m]IT/ô6]UZ+* ~MK;1}sa%ְZXoL^Ҧ+^ ܅wzmK2| [E*)ɼ* Ԑ oWTJë46,c6bvd<54b*ߪȨI՛!Ank^}̎.F՛[GeGTh jT_)>&&jvL#ᯨ^ծ-ɋ*Nn O)Ӄvt 0(ͨR`t?Jykw<=!/h+0{WTJnK'U堡0F&eLan8o 1M s n$|Lҹn_Qx][`YVd{kٸ&N fv{>5WL[ǖU+Qа Tp; -U`kV=K190)%hެYѓrefښn+Q k3!nƅmWTJf=y =u5jK*&2VRsʹ5V&R?k𡥂5WTJg}ɤa3; Lɫ@ly*] Dn (ПVĸ6`-RZkȰ;Sl?^3Ϯʈż\2m9e n#G /~ _mRvucW %)=TTy vvVYUJUs#Y%jWň@w[:VVfR;/Uו _jMETmt`=AQߎZIesAѲTqeWn')<=RvFr wڦ2cWrXuw]q/8[~K70OK?$q  »_bWסP2n 1=,x ST l: ^2tb\a{+*X Z*6s) CrLpoKe4*S T^c*OVō='f#iy޴d Ļ_R8-|O2}uCԶ~ܘפ UiBK*# v~ Ļ_R ƷCy p3U-[!oz^  s )Z*~EKu^k ay+ 0[ 1dLwK|T+S+ț<Z*)X~EKu^k wՉi|2ʻ%{ Z{+ț<*c2S/t+S2]ϣbU+qkfhm9 UTnL쎗ޤl~15&ysl9wUȕuR@9YkJ~ Ż_RU)kت [}7V =,RN>SJYVUZ@mmjxYY_D}F?uj To~ jCZ* ZNZ׽)`q֛90kcQ\SZqcb$S_W=U|~ _RUkcN'TQ T61S*̌c:;}=]{__WT"eztrnҦ1ݸ|mmŬjc+7FjVUjtG6,R~Alw9Tͺ#,ەN4KI%tr+O O4Ǻfhτ"6cudH\X)~EKhP#AYzeJi%A)1btew TOvX-\AR5f²Ox+Z0>bӭ#Rb{3VdNN8 QmJU]݊y-W]Ibel kbNs[@hX)~EK%= ymٴ\D,Uv\1n W|7 4M\%5}mRĴ\)a)`c-Heش㧧]%8,22̼AŦjP>C2 SapZpP-K3=3)Z*xJľv/]cT7f~@^%$#rP5bk6E;k]vY-8q0 )~EK%R-l9X,k=lb]a~2"Jlۧԯ ؕ ZW^1b{ ~EK%R=; mQX,ªD$c5r媡b&Ğv‰t(Qd͖*_ ݯh\ p2D[&/@ ϳCMݯh*˧ƪفQ _cRRV&파q&YwV_^Wk ~EKŮgV)^;3CXu2ItQ&0R=_2U'~jo]U|-^Yf w23#CeZSƝ^uYbخ\ĉŲZV-[62-]UĒ yɵT#..aL f~ ތw2ʱer%GLh_] b]Un!?\ַ񊱿W5LWT7@,v,]qE{ۼsO8PRKیE4(gcOg͖ʈr؈Őf~ CKz86cƿ!Z[ -،~-RhNR f`K?#Nib`3E?PBKu+4/3mxP$uo owc9i׳{˜ %&ouetu3 z˥P ˢ , if T_\gwO4SWݯhTr%5N1|EUqCXL-+)UVUnlzYQXI-{#}uY{%:)WT]z*w9+.|cq9EW^oI\7=k]QKF8W* RN `}-Qx s>RnjzKU20oUaNԳ˛h֊X ~t;w{C >&ZC`: ]Qq[Q:R--Nۦ9iJ^nn\Vz@Ku%6vMzx\ULAKo?N0)k To^ BBK20e<CJtKKEhv5Lj^FZ=8 V3e96;[ ah.cXpVl9_RXa-U_Xt@Fu|lܖQg^\Mx" J3ZjCrB`cz=@LKu^kt[T-6Z+@K)-Ռp0Z*1HKuc)R Ǯ@tE?_#bQ+\COgכa ײW5 Vsb>=Yv6tuW[ho]3q#cMQXbKj@ywVקmffcMwbT5pCxÏN{-Kc$HA$4 dcQ,wb3|t-S#VhWvXj]aL դt'T"n)JC lsLW:WTGAT foc:m庍KUfC#64;<~EKսbmF$ſ:4hgZWaUcѡ1q`81O_Ruozv=]ˌBe7A=h$%alkPBtt1VnU[I 9ŭv-Ui]\ߪ}UEv(^yWa-nCX*;\ɰ+JWT]zNXĉDI.31e1b7o֟] ~j+bK (6T NlsL1WTG 2XUBl3X"J:NìMc,l)Wҷ35u*mieX~EKeкO[5r'hpK]Zxi)]tbz^V1&O_R]ŧɼpccuV06_ˋ|f+ݯh`מ6`c -ӛ {1Ͷ O ^n])9ٙ)Rfs@KӴThvbc -NlsLRS؉miZ*x T;1MKO `'9i)R64-<Z*昦@KӴThvbc -NlsLRS؉miZ*x T;1MKO `'9i)R64-<Z*昦@Kon^珹߭-NlsLR0[[׮6R64- Rm pr,bxaecͻkRmgKuTO矢b\E?6够֗/"K0 y?T/cĽ-UyTz%c{qbg7^\,kRmW{TSM(iA@L݈8J? ײ1kug~owzUKet>(&hTm)yeckRmj5JtMIwE\A*!Վ⊘;P|94 m+I ݭӨaoiEzSX?T/cĽN-էXE:׾6{EU yUzz,ɸėS'WV ]>&ci"c)6MCK2Iܻ_jkgcF4H\SZ zh+Q Op^%u[Da![k1ᵉh^6{T?sőĮ~[^ULl?2VCrI$k$PMYOec V p=oƽ6-&q~kKuSkTq+ºOsQ1+ۘ蚵 MYVWL+n7kWl:6t`g؆&z$ݯ-Һ}XM}=kR\u+º΍ u*SB"#1G]jif*5]QXZ~lϮnj^7!vŷIܻ_-CIFl Ӹ,!UN C[aoe#mj3TȞ][cut=QVrmq/ǿv?o+?-[n?z} Pyy] 7q]+.fgJuvGY0dlLj)=cWt8>o;߾[-pn V߿[{ɿuQ8vpҡ%N|d&* oUƂvrwō4R cfvh-WfbgVH1G[Cs!O[+PUFwSq(WUǍLKD]+nj:]a1-}Ճb-VЖgȎe^SRIW gW`%ZtەjƧY[ʘf+Evj] ċ-Jpq] CҬ^OuK7~K_[-?ǟޭ_me\%W?WbtxZ*m^XoӟGj3C= +3Oyقp{+4wMVr-n|pm2W?W%g_v <”+rB~8'?o'W]mWFKpR{%@KM֛kW|ćTp G݊`01﵉h^6RMeqM[h «9m֣5'E2ۿtI9OߝW?TwI] Z2N}UV~ø^y֩mL@̣T@#֣ -GI_$wk&y>GD`be.-UV* y\p6duJP\5U:^QvⵉhUn:sܻ.T%vE~SnG]qyX?Pc\᪫ȴjS *#(nO^ )eƏ܎;WpWi!gۧwilsL_S5ymZDLAa^6Ru,(A,!_W] ba6G1bm[nK*G!8_a8I7^Oø*rM& acZ-kRO.VdYٮEe堲.ݠH>Q-(ll;M(i%@qS&3Fz쮟e7E*=QW 7YEIU c昮KxmZ*c,+KdiZjXQvmZ ڕa-2 ?̞%?8+@}΁JY8VVPw>*-o7.%UQlsLWW%6-ix2Z0Wh˳knϥjUxk[8U|v(rΨn12m)92 ٍrK e{*\D^3[-L@+h2!6BkRsufMU߈e?jJT[s/TiW1C@i:\WՉ(R ?J:jK%]6Ŭ4\U\}[*Z!Z𖫕 TQ c昞]ymZ9n܂b Tnw٫c+QbzP[L-ci:\W`ە"5&kL׫ݪP¶rmWdˡ("o~ߟqoo ;YV4":EV-gUGZf]W-]Tvm?{JQ"'KM+Dl=i.Pfo7輕B9+RU'~+l,TxkUd!)*[[xJ.הM*F aGK =ʬH)R]{JU(t \YsEIBK֧Bsʰ]ͼR[^iWt=ٹt}?J+Y蟡_ L;]k T0nu -뗨۫r (F^QT06S[*#q;6-p/jeERj .R2v]rٯ-\7yoZ^x@ e˛͂-UKLa8@Kf-5Z*XmR} "tt;s[oj긂Y@+TL0 A)Z{o=ռfKu^ i2RN&gQ5v9o,ԐH*"{¸xu>)}VTl #"R|AJas(*&*͊}=xƫq-7SW0p6fyDeՠYya`Ug9F}o > :H,9x%=:1v!;p,MB|گk&jUmnJFFU?rLCDQnP+hSwj"ށ??wu_BW8%V%ͺi*, ?\LQnD*uŞxnݮmo^ C!S@I3Ou Cy2fPiZwU0k hU Dٱ ]X+1#@pIu#f'Fj!ށ?_/ӀCTk>'XZifOc lt2 x-TMiޖuNKTɲ4J矯+2QiJTU^5(9W\So"-ͭRPݝo/^T-+Q}x1 ]LeaC\T4׺38|@U޳bOKբz Loj= CNp@'4IH)ؚ|RuaR`ۿ,?ZQ_-@{[ϸV .&^R5B,2kpJ e3[pVTybE>כ:y}+6co&X%{WT'E6?O *SjrdqyH `w:SOmά2dMSz^|ۼ'Cr'ZT'SOmάW[ S{m#iUrwqaMU&BKucC^9Z*x ݮ괕Run K%iJѣ?ұuɥ'zՎr8I*N)J2e, *~y`}gIK*fݠR*c*rM ⊗#pҵi)$Ŕ" BZ*roq{?aw/H1\l@>51} vВj ]3eEGwM@8T(1eY =Q aoH=~)D߯~7_?*{]]OcR+dD[&nh;/]^7WB&FY[+ѧnS+8($ӝԳ[B؛EZ!>}Wls=[{罒u#Umd`zZAZ!Je]CFW\W΢]՚(f!N|fƈZ@!:D=NbSWnvSv*iyV7VVPWVFfup5kbqiVSlo#nXjެR_H^ix 3f\>=du4zc*?61/CFQ").(ްW0&v Ep p(K.ޖ3m|ɟt?wkx+嗨{z;%Э*lVoש:pM0NZf)=EB,ZwȮJIG d7B؛m}Vy *o/ef+k6{LVfNVuP~ٝu*& ^,ԧQ|:z ِ,7׷T{~_=jlw~h aU},犡֟a'ybY^?-UKc.F8OK!RkSJ*ǻj6JcZfv5F`oolnohû_eZjЁ{عT콕vm?u囬@vn2Ė+54"j{-mU:Jw ۳NK3v{C=jHKu0bݵ"ݸaaʬ6!'mw98[ ani~&ۻE> 𖪪ʨ@k qWK5xY_NKRE{ Կ7ʧmy{Oru5[Bz+xp1].uwۻm>eZjכ|ٴ^7p w?U? ~2fR}N{URH`0<꺷F^^+ K5ds+7;W}o{^iQĄ=8ZV[#/2on/:l~PyA#!q3F^Rޙ5e,r|/Z SKe핷bq'8+YZyg1N-ըq{?r\̮-7Ve8[FWdˡB7sۛH7*Ԉkjo2yftUQjצ_O=v8/TX-ƕo{ihfj8l]zRAG15EX+'JWsbF%1.+ KuKd)A%Wj~Nk{Ecb`x+,R:ii,`R/R= `e,rLoYl}WoKusaw4y-zzmietAݲx~ ^wRUϑ» JnBU,"ރX]l K+WݯTUs0bu#V8Pb*_6X9]V~č2Rs/bKy4*x KePahʯ1 sQIU,ޜ.+?vs1}n,U0V,DK]p+XާzTp1}xrDZTXAbT9trk`,Uw˫W%R-Nʸjsy{8R}՜Aͭ%`+W@FW"u>R % Ke0-Bj5+ˍ j{N7r5]bK /+mM'۹\=ZlEWL@U2nNRZ-#㷆[$û_a G[f~(I텳F\5Ls2F*F5FJI[ J^v]kɔV:PغZF0FDU2QmnTpU~2vRookfCL-.lTWD꜖G>wɞZei}+fo;R+ ۚKx+\#1Jgyi1Z7t$,*ȁwRIkuuS#TףU]W"c]ZUE"[ʻˍUF]ZQQ1K[OK٘`h˰)b :jb)"aY0Vt82L#JÈ(hU*UsydOӫm4ĻtBuUvR#=9 #ԩ6dڔKJ~3Ywdn4X\<~2:L#l ܈/Ju*k 4@\niIjMWi\b]aBᤇݰb+ Ol+;Jk]pyRXWX*ΣGšqZWHpC|u0%{sZKg"L#]pjLb+ ]msz)ouݯTL-b. _aZzJh8-5ۺ“Ӱ[( ?pnnѓk 3WWz8W|DCƩIRӰ[~R+6[VF6r2.(]jOp *~Xwn/ sG4d+4,uo,\܋w-#H 01rՎ޺T ]W[1;ok㸔 oQZI%b#{#ikRo7ؐnjxWi݌F9J\ݾoo<#1i,, nĻ_,}=\1=~{eorOA^~1` Hj@FD"tJ]kɑ6NQ0>vw|Ng2ֱTSb.Ux* ~UT8;p5W9HW)#A1aZ@K!.H]CKkDw)ZLRN{IVsn)=TxCz/ J.42+Vw%)\^ n_]TgV?ڲe5؝07``0ºaǴ(mnL{NЛ9YY ir9P-mJ'K/WݯwF+yIL]¼w+Po,ŗY'V1XvZ@Rq5-[+;YH*N}*[/H?JU7=} os5^h¼MK+EZĊU 4Ǫݥ[^K9ޤk%4ьTs}zNvuCH y ;`Uex.Ux$ / r#`2DHLbJVoU폑N*J h.J:X2~ԛv=WZ* 9r4ĦuV-JC@#óRT>YY)⪮0f[{oq^ݫv1mz(p:%R JI7Nsv]ڄOVk}p+`{{~uyboKPoVSWXCY5wkluhVOk9󤧮z5 %9 4]ƽJczUyxĖ}OyKzX* NK 6-}[HsLc pUpXoط%lw+JE^: C'`w .~phKX./rLwfCpU0,oڼ-n.Ki* >S՞utoJNMN1=  &ݯTo ڑ2բz xWr^V{>ѣܔo)AwDpU0 ~z IgHj\ Wr? ves=%]є[R`` K :Kʼ :Jњ|vfe.=/ȚbKe\ \ݯr[)AZF^;Nu\tJJ2K^\+vD_b h%RzbwJi0*bu*#[8vdB{"C 1=~GN0wJiރ>% v䰤RXo@Fa ܻ@ U^Ɯ%Vg4[LW(F/S^vp/vXH!, \ ݯTvkMG[1,fm7` U.1LoRL9]aޅb@YlyrDҝ钧)UW^Q;!J=d{ZQM VExSU+L k2V <&J HLYZ%;K98Z8M)0h1Rbnj 3J ]**ݯ[ݓuGr:L+ jL n(&BɨNh4ttҐ뤑4ט( 1&qZk!ޘ`a(bS 1=~/N*ݯYZaka\9Ne[JEFt*Hzi:|f˳;c((M@7~+CnJ1Z]cz8 wRł&ƕx4qXXPI}p3;mJo]L0~-6IVE]@QQPok5ܕt;ؐnJ9z[R  x+,s0|΍/<7ʘ3UfN()W7N}SD=Nvɳ;#0.+Jv/Wʫr=sdnLkU~RM bcױAdo݀bN lNkRʐ$N(u?J,4E!hZ9͘h1FbE%0: X].K;|%3U ~Rګ6G끱JwBkZ+iK]uu)E[Q,+X5ǎ,ª;h,yk즮6%&JLfكv0#1aJ-V:s<@ \x+,U7T4B{BWb+)bk'#?…(bO/vP1܈\U"JRj0n] rbN W" K%TN@I2a(<;W5gH)l?gukI%WIʻxY2! ?Dx*PWX*)461=a`pU͖qx)}!TU 2Q}e{]*,epU/KuF͛ ~XLaX\`T%=Kp*hZKu.ЃࡲB火*XG8ʞ M8,`02%&') `ΈY?k-i7r)JZzZ 1=Ez܍/jS[a] pUwJflro6\{m `'@m^}~pUwaox-bn=%mٱ 2pUwRbz"ژ`7pI R\ v,ՙzwU+i&*v͕$|o]f#)5w.W*u* |80pMd0R- t(ML pƿY[(<\W ,N=tuą$#8L.epUWX*=f_tkX:Q?0-N p6_1E)ތwR1ldBWu'I㋩7[]wYOEU~RӦ:َS\F+ ڝt1$ .'Œ դb8މwz:os_;ATzW ;: v.Kp/ݯTS?eLSIg(y1 m`nqHɣOThpUKuq{5@z}LzT''=phBpU/Ku}v887!7Ľowb ^WzX*LKgY!,dWX*ex7Z}_RA2pURd.K~o0&g7$W,@&VKW,@&nT3KYUmncKU%%=^]ܟ۱T\U&T*X*L`v~= \WYU.ad0&'8\ybC ,+z.X*LfX*x!Ku +OΈ!WD[*vcxX*pU{Rd_Oabr;U= ,@&S*,8 q#mGɂ$.𰽙Xj֧⺰TUwJc?|(d}U^oBևl>i:UaTU-wzC?:7[ g hKd[:%{w>n\9NjrZ~RVVGرvR~yo#jM˕wE[~sU WTJ]9zCZ3sJi;hK帘~Āƴ;uarZ~R'}v'K.4] mA/_WۊS-Ja:ӛRu+Ya\UWsP1͞7\kBK;J/M*HK\jx+,1m띛FIҳD[|׳F=-{T]պG]@7uLHV.{y=#vR)1#)AB\e*_2"k"tqR.wJoąCWMJWVLEۙ8d>qVFp j-eZ Tϭi]]HhLk(yFbvZUy[%/WqJ:S2,uC#cWAO91Txe8L l iӺ19؍](Vgg wޮT_xWOTbQ:\gPxBK1孷ܾnKU[`עDΈ}wUukkauSZev%[%۩aޞ+ F؝7ꝷGnTUq҃~Rfa9K-g*bYv-b%WnM.%ALZd R՚VVozĪX](bwȫw.vK® c5~Rf*s%u C):c\+JcDhvgۅ*V1Y#mrI& pu[ƑX](? EpLǞV8WuYJr;6%[Z2S (5GLm$[z;NW]5ʢ6PUպY2ɭvj#RȍwUsʘvQ]*7W݂wz+&ޯjre VCAoz՛+ޕw+oo~%FŘJa#jSZ( H>ô]evKqF@usTscGxWi,UoKd8oUFVUv(qj"1OCu;{'*ӵr]2$)YZյ{NV []uLQvyUoNڻtW j>yAEE.լgDx+WX*;H+r5}5 ^+N6:ٽ6bVҕؒ8oճ:~FV@o:qF^,q.y-:f Wu*Z'W讚ՇpYG7Δ.~pu &< ]5V_2:"?w`0t/aUat >6w{,X ?.\9Oo[vZΞMX}󞊬7^3W[):ҖOt)$ug]>9esay&,wfŜXŻ_eTO/Nwo3Ҟʍ]ڇl NWh4$_uLoNQ*7 K ۠WS]1+UW`o WuF[ I"~&|L>[ @Z0VSWXuXg8ݽJ oĈBotq)l0l?OL7V9wZRlŻr&sR=1TKصl/)q\:[5v#આ)FC@֐W XNU51A7xi"G &^f2+,03գwZRŶm˜$- iFQRj-ZcXֈX*j.{I9ǐZ9]pwvNKSU ]gK!HZ^}uvo؄‰\yLeNIʻ_eT{j*6zc: Uj m[GJIԝ#JN֮(PŵPH4*\DԠ.y&I].zK+{3nٕTT_߶.p7V+~Rd<E~KB1V:&xB2{XjĤX4N Fou* X*N7R\9t~K~eV8gc: @2n7>Xl1K4`q:GRdv:f ,KXKۭ 6O. XT/vC44j31),vp[r%aczwr? |/Ե_i ms%Jnj1^Q,bcz+_okZR촆;R^jyRsL¡/~R[VeZ#ݢs`)9)J/nP=*ƱM9(W*FcrKyWuӃxAx9׸*jAK5%9ijZZt]sLݯֱTSY|P(/JpCa^cNWmJ<9>WY-xI1&2v*sZ3R,rL}E ~RUkV1PFRLU^XX]U*"8c`AjjpyÜrI5l.ٍWi kXwZR]`Q⴮vSwek+{uobcz /UKe;oDvwUgOpLOKOK)`)`21=,<'Z*6XӳRSRdczX*x X*L~LKOKۏY`)k+LXKpJv"'Jk ߱T/#M K4y[JTzu%V)Ux' w֩,[aLkU:9ݻ9A*Al01݈*cmVKc^F½-s6+/#zĪ>(ýՕlz*W]aF֠Q2S (pCab^=Kؠ0ZSFsu;MDR{w^CiR%൅Xp~u9,oa`jeIwD0ڽ WJZy2]\4BuPnU4E_J GSs*%1opeRW\44Vuş*-|R4{4jQ"1[I%JEE-;<@mCpnIq\w6jc7Qy\Vʕ)ZmI{ؕW*Իݍ2U~*XK2ݯTvVjL.;S"^#FvF\ _zꃟq6ss3+>M)6{y+`7]몢\.JyTʓ_[_~Q߻[-_?۶?s/?[_e߯Xt;Pa S)G$7X+sbY鮲'nG8dJ4YlU]x!n|NeoPK57ۭtKVTNX|^\tnBAX*vv+4oۯ_6W` #nQsm}?ųq϶ޭ;qrY_g`;Dx8rr 4G[&X x];$^{ݯTiڛ/'+밆ՉMNizkU떹/^#<,U^[֝wkޑ.VnW~j^yyX*xO=T= X9h\[Չy[2K, 7pWxYjM7tgg F%:R` ={XK5ZscLmX _KYF}k?d_5֝7^]%r+Iם,қֺ덵M6ymbC z>Kg9%ϥC̔ Uojc2,e>W,U}:& *)2\WAo-YŊsZ Ȯ6ͱcnڍԆ)ªe{3zWb_kVSY{R@>5S_x)jzК}7e䐱*61r&Fؑ[Zy(5[dRS-n= WK[Z║mUw ` +;oU2KuPbtCCWW}ȴXu; NW(1("*UT@1MːT-ӥPMwٝ k7|PE{kV< X*HN~RUG\3=Nw*6)u*}߭]V ؝P֕T;CWn|qQc|JiTbH+Ǖ9v!Jx=F-IUĘ4pҌne+z{U.w {rWiv[ĪAKq8wz:uEcҹj6{l?ZpOW44o^y"*իVp- t:aoTt;Q/X*x"5S_xjR괽hjwTsP-UnK 9vVRlqKrE2Mlk;\hdwѼZUJʶJ8ZWCiZYy sj+w֠X( Sj1H+Q%w#؝ Nsi"I|,WFih2Z 3T[\){ -bt>)- t?_nް7kTEeS_`2q/Q/ LɈ8>M`2-R8'8\t}rO\R}a3POWX*L~OK `>8%X*LcgZVR+.*ܦPfqoeQ( (  5U%fάfoP8!nBu^]zSl  ՛-Uja].^*KkUWX`djRcDfgfYOjLoϩpHg)ǎU.7Pr]˫~d0.ZoRu!- lp|*X̓W:SY|9L3Δ]>w 8ɭVsv᭣{_[f+2zCo?ǻyXr.en(0EjU*U1SoOSQZ)骭Ԧ7Hd1 _T+5< ~UT1GcLsU /'5La?3Lf9~RRv'Rk`ufVV^Wߔ[V ]lȾj[*%eRj@wgtFX;(;8?'U>ȧ)/ <9@ħQrb|0Ɨg䉝{[1T뀫ui<~Kmk'Q}Py rK! ﱰ<2bd@|Jyn +X)jW ROٌXm?R&XU]ݯ?WX۲b_x[6<,Rƒ>u,`L p#<{ݯugp93yKң)gkTKcpt13YYSx, na:eg Rj8/K}%6LϾ=:o=SOx* Te7bx.û_6n+9*{"Nt}YPؚ}Wuӳ/uC:D%ΰkJ7vws^ .2UReJtO3ى5wK3]::zE*NS'hGWcv%jy*ۏ/ՙU;NW<]>YoQ99AWb,NSv#WՖ˙ Jl}BdWcU87H7gl'[ά!ƃ,qmI`x.ƻ_l}gNt9b9ęF|eP҈l#XKW1'\8=xQz}@{?U<o0->LNN gv1*r[3(@)Ev(ӺZ9UbӌQaEjrj%Y[9h9JpEjӌ#e+t.¬pLwظ<\x4jM$f#zeUy7YDꃃȮZFFZĢ*D%Um4]=7MsY4v#`\J NU>KeYZ'N2Eivu.MS0(c+^\ vn@VH+cݎ+y[E%-lasƻњيfS\9ǣ.*8[WXv )SНW9nQc[rZZ1nҒKݪek?HKX7=ͮX.*9mhު!:Ǵ*ϖzX* ]x+,`,^#eFwN%ꤑ%y+Ѓt7+Uo7ue0]"vl#:~ﺝ6Y`w5MsYqc\̂gFj0+[ʛ>cL oE*2Q^ww E.VrPso5!,bZD, ^WxlV_T3 ͔vvd-U`RUA^pz ^x`VK;/To"r "w,U5KkT.xTKrw~g")&m,*9Y, Mߥ:<#OH+a.+ <$뀥D LT[oT; zx, ~Ѽ*0X ,@&9GԎ/UARd"vLSLOU%\H, ="X/x<  OL .Y5Rd"R5s_X[U7"X*L`W܂d`2T?w H j>TXRѰT',@&ֱT8zL,ynKD}Ѵ⁥:\-`2q˿KZXZ]vjXU] N g?z(%,pUAsc:lj KkùRdb_O(,:ΆKu,=,թ7tKpXuXJ8\y7fܬa.Wu%`2KpB(Uͅf,@&:~jRj"=`2qR N`!.pUSK5-U,Ս{oK3~r,սFooKu,`,ս,BTXRR*z'X*L,xU|abͰT+rA^ s=Š OرTˀKoK3,`R?oK?L0VݱT3/K0z5NmD\=,@&N K ^WA7`R{LOS5sR _`28K\7tRdbY,U)K[iR%UC ,@&btG./z'uU/,lTwvR!ઞ2S)`217';,U&^P#RdbʿKuӊ\U`,@&bmuDkTUY)`2ToT&WK,"KPLI`2qy5T XsUk%`2Ng( KJTKx5t-JmK)9m}zaWuIyTX,@&bD?KWu[Y_!, s?2\+_\ v+Rd{LWtX*b`21R$KnS0 *G.0X*8pWLX*Ltпؿ` ?1TT׈R ?^Tk7RA۝f tTTe4, f  Z*/b@E$?Ȅhf"c'k f K , l Kk\aT,@&TDcKOK44  ii,<,@&X*x X*L9TTHsLc)`2RSRd"1DcKOK44  ii,<,@&X*x X*L9TTHsLc)`2RSRd"1DcKOK44  ii,<,@&X*x X*L9TTHsLc)`2RSRd"1DcKOK44  ii,<,@&X*x X*L9l^[߭^{sDcKw,jQ8 ii, ߱T=GX*L9T/,|Rc2RKsDcKw,jQ8 ii, ߱T=GX*L9T/,|Rc2RKsDcKw,jQ8 ii, ߱T=GX*L9T/,|Rc2RKsDcKw,jQ8 ii, ߱T=GX*L97oX*IsLZA߰T+显 aV&1}esR 4`Vc`qT+1 8X*X,pL, `e8K2XiR 4`Vc`qT+1 8X*X,pL, `e8K2XiR 4`Vc`qT+1 8X*ᘆ3~)"Y90 `e8_#h~v7\.K2/2q;8RbjVt X*~-fU븪Sò`Vc`Z"X ,pL,  `e8_K8l5 dRŚ`S VaAT+1Zo׊).2&jV:K҇hT+1Zݷw{hYb@<"I3hvjRxX*~-WkUR Tء.G47 ,pL{ukĸ{i<8߸eR kymh{~wW@@5btE K2ӯ%^u"^#Ѝ:oF-J6=RKGX*~-jMKJ|55z\ՊӽͮGSlVK2ӯ^ux5`=?f Fx쫁].m X*~-{UޕxϏYўN2A,h XעW__K,1k`:E8L ;, `e8_^]z%8tث koWʌ5Y_kXײɔ[Aqck> stream xuGߜakqNKr{q +mP~h)Z\{N3&k$d3f Vf'wJ>mon<;3IW &Sbdrǩ=Z7߲Ӏq+O# BV=늓ze<?ٽxوޚ+aM7ew.w30I&഻鸨XU*Bh"^;k~r~XH6Y;"b7\s:S p 8ؕogtZہ ;x\-j~ =ϾbD]S<=g!Ω,cΨ&IB/MǖIAoS97Jɮ| 窳՗Sd⦕dAצf7U/[<{lޣ ? qMR4;·Gskxb[Q+nY"߹y,An&77&4pMh4iopK?P ยrn\MA 6%0p>QRy9Nbi]8A[W'_7e sn&GND,,ØO@DM+p؀DDe8h ?7Y\glpp\Q\G}")c {e;ق8YTU28IG8(.وc}ˮxXpPG#-$Aӂ{R[]!t$83vS@v9 #c1 d$>to_Ywί8W! NX{I2qEqW8B{| +k.{bN̑)=Wظ؝ Z75C.p*BÎ=-_vrϺOĴK7,_7PX4ѫyJMM۽\Λ;֨Ը䭉3"9 oP~y.vʞ[5eUun9p׍o[z!۝ur0c48~[7MӺխ t<^1mZr;o k]580@ƿd:38l/V._8lxn8sPil2V{{˓9龬Y#b$TX~h4VҖc1c:]Pʽ3d/Ƥ榾ߔntx`hyɈ^عHR遲do/UXJ,iY rϩnsbXs/ ai"3C1G6༜M2L9NbO6O+O_OVI>; cVT)65ՅցOH9 \)SAT[.Ove2[wܕ]ȏk{&Dtc3(p,T&MWkgʘq(l$Ȥ:} *iRQ.y\$*ޠu-JKkGhvC,kCAK}ɰ!hҪ~؊͢@cR %Mo3S q0-9i6d?~N>_zD$ß^eS5ZѬ~ ۤMKTMUj~/My%K{ rlhJ[y Np"ZӟYf/1' ڄdH{Cufy1al-w_s^*7+[A@u)(s+ Vm<s*CiIiG6 @zjΥFŜ khmunlaTkfӍ0h8T5]g:@P| !qNHuiK{.hIڜ%8=|*+t}er8!+}8;[Iā^Y{^a_SYN<. t.~lD` ]>DMwxj خ0OaBAjUTFO?;:gmF e740C5{J=i`1e_*?|c ΪE{*[IG+;^+"cTߎYL2ΔKͳ24y%'+,q" n42e-Ej?e F:"V͒&yNjq8ttZ ބV\ֽť2om855wb uom%h( 3ɃX'LCunJ-oHw 80ֱ\i$z@ +hڃ"?\G P`7A#ykJt8Oea5CBLtuB|S_KȁfUgA8QDqNŰpXl*4(**0eqxܻǠR:($(ֺj2|Pn)ULPDU]{꫽ʱeV|tgݯ9y&HtJڒ[eE7v+/v Sd!1D Wcǟʉ k1/-Nl^V4~0RO2̊9s/^-E P%ks8-IOT%\uip]CyM+ʘqNwE`(qt??E=)p|]DIsG^bN)KDZu'jL:mΎQGN3ՓJRvfprGsh4a}lB6:NSJPjCNºgJȂ\N8Me:"}S> ϔF<̊_([PeGU%}>p,wp/r#[i5NSƌ#pT#Ɲzdb;0cOre pVYQ-n-fAm̷,YYU]b@&Yi%]Kq>prU{]&[mfS~Ț3҆)ퟣ̟jb|" oM{/ŀViǚ)Y ƫ*ݑ8ƫbk{b/5[/nZelϯGV*V#:g2p ԯŀ,&JѭQ`dl* O!7r6~MQ<t*4 cbxICf,n/)_b-$.T@)k&+VR%ۯٯZ;֏1(`Bj}` 5kP5AFeV'.FtVnڵ\II͓ek$1E1nɯ mLCW8ISrb,/H}ۤfΖ.-S ^, :` Zo_~5֘!APvuD{xf'C| ̵!]v;uE[S &[<Wd,pbݤQ3fALڔ1yj}Oռ@VQ*K6;|A1pe  zzĦwH/|] M 5.܋qNU(+O:Tا*7锾Q9u]hèv.pc9,`11#z.؈M'CFV mcDWNrZ]]k)jb q 8vnzw\[tyUoY.gQةsQvlc߳3y=-dovbw\+o(HC;@IuGբ;d \^!28 T'v]dR>- mOs8=V\7]Aa姐Tr8|EZS>Z,NeZČ$HBGKlϥR1ਪjlw5VS'R^%*֞F:C?NNb%:^#O'eƧbN6sT_LEh|zv@j՟&tM7Ci!v%w6u=1BhDE՞S7Wm[3r8,~КQK rq~VtpHkE:_+B^!;p~ql Hd dʨjWltB7ϫ%4pPԯ5.k+_]5o]#د\aPnx N*^7tV8]$;0nr8}r& L/T&%Ԝ٩oYdeܵQ܁úHJnpXb=@|Ǭ ktMp`Gr80d=rݵ@3k6sU'NDc=$B.j6nL`q$Ȳޮ4(/FgGIwev:CV=q5pvMڐJ[|mX#mr!-Ab/Gewfһ  LTwB at 8c VvZץMqPp~"c w8UL=h&X٨cah(i68 jN܁s%V 9{#ggakTGXtЏĵ(|EId:b"h#5AQu8Ơp%ja "3EvЪ2.4XusY] ,n)vB\]6I,6* \ϑO'B-wcgp:4r8 I(Z6T 䡡ģ\!cD$' 9Ws*\weF*rٽ pob NbH{ec];yN֔뗍tq]f\-.5pڰߎ13%<+=sD&pbK: N֚1MR5JLƟysc>F]CڙFoX[;j pZٽFlEp|8c86:r$wßLZ:ts8*bݼ-(D1</%7ënD  йv}ݡW;YJ3.qcmu8|ȹz:nbo4]N穿&>GgT8N(, ࠓGO]uWnd4qDյyy%b~O1mW^=d|4cxטp^e pvdϫ];i7[XMb-I;P8wvޭ#eޚwn@ijkkIm;Fsmh+;>hzRsԦ3ٽ[$:ٝGB3=&aIɽ΄;ßrZK:kVmG+LN{lH#ڢ>;XwRv%CvĦ7샱f!~dB,uwCZ4R'X Uɱ. ="/>|ڊ׆golwG BڨS ?+r 8i*>(*yKnޒ'B|"}7pF +H,̿f&tpxM?%Y3'mR]6ғ ѤgAgBET>d?z ~,9 Xq/;Ҍw:G͎$䀹Uϩz+RMw`Al=4SK0=0w@oi<V'Nu'ISztը^*tSy%%>Z {N;8ԫ9Jj!ԋ (QRHflSp28E+࠶toIu BJ$;c>;C8NDļ3fp$.z R d.НsMNr.wVϕŲ ͆eQvB|,GM>Z320pxUy:1ʷ!uvvBP].+M)/>)^]అ~;w.$[V1ɑƼ'Xo'>5Pپ K*_7|$p3'g5!w?7Oe2.p+Qd3'juQ&pA6 dȪsLɚuT6Bd 7Bε4,,K^}d /a!9e%Y[SRPYaU9 AT_ ]@*>jV(,Н6w9c/Gk(% xe?j!-pxz'5R/f=oɹTdpIlʼnƚjgzpgCrU3 _i.|[=ԏi46^sHm>OƪMw}ݚCH0_Nr{_ uRd7.Mm"_d7hT{>U]jɪ!N3ZPc(+^b#![n}GjWR,o>uhƹICm3ɂM+<~f[ܴN5XuV(7 y("CW1)=QuBt^,E4cC?"j.zuBibT1^qڑ^lO-..C&hmD4866D&f6pб5.SXmGFWtLArY<,&>=^mVvfo*;Nv 3pmM\pbg+a;eqq9LwGʮqɑހ3&@RUTzY8vbӵ`Yc5M\Xc8Ob42ruTɒleeMe^2g3:BLA 9eP(=>iqh3튫5gNNteWv]>CIӕڒxBu̚ i:uYu`C%.W5@boʲؚ®ܱE_qb$.ٻClV hE }*m;pJ/Py07zծybiO2ޒ\S9C,zqp>_4os3)p=O-ضUbqj7wh/F=ez-kvZA(AD$ IL % yTd̺?<,2Cxc3!!!!Uc3!!!8)sD ֙!⤍Acd8<#2_H"~^xM8lIgd&BBBBq߄f2"BBBB/nNbːسkmM tϬP'DىQsF]]PRY(Y(:o4!!"J>o4!!~F8BIB %pAJ % ѻ_=wMXXKq;yxŰ+=#\<ۺv5鎞^W. 'V3 ?v/}wJ6pvFVv?o=Ng-.&t.8žB e- A-~ N>>/u]Q÷4Ţ= W3p:d[Kh-JGMy8KZ!+) $mku8p$ė8\8Bn Wy$65 8vȲy\9g֏&ӡM}Fc6wws{0ڛL[o&vv Zo\n}WRMkEۥ1co!Zg2kT4hqAKmLeat2'vڼtpm Zyyw_{礓}S;OO6C#C/"\=ǝ'ގZe2!{tn=f"[8~ed`z-nk79дΓv"y o਴G7Ag ,Y# dْƲycb{ :h4&YZzvHZe7>8$0~ec(fwcS5"U 7>=uO Ö́8!WCsi J)fxک(g .C&L&hKN)Bi𦥶CYu\jycQ؊PPh4bsj)Z1l 74L{K~o )T/Bgt~G%SƜh\X 4cCůC5ӡD߮LUϊ 20|!E|擟 8:aOW.C qB.G:x^F1}MOhs$a("Ur^${†~-1O "Պ w𪡾mٻp{y8CaBP 7 C]`<޾P1;I4ymmU|>4~%/s0VHz ş GD&,H,A(<>,.لCəI/^j+gqtDUX@}4c; ^>- N#Ο9*3U<Շ`]Ku)@2= |5)c8o&:1ReFkCÇs̚uH_8<`\My +/nq  d*ЧpH8Nf> 6 ÔiGԂVi(oQ]hRޠ22?65dyiƪ:w'ڏVAZ 8Sz^@v,4O]8¢$(&u RX8pi ⧇AlՅMh!4Ų\F[X S8=^ +y܀m۵(͂) lRv8]}6:䦿BI8J@zݚTl5m"Fߠ9Ï3%pѪ:aJUh!ހ%>PH:׌|iaB/  <)5 j v&{p^w޶aF-\-s8-^Y)Dؐ%@S@kXy{p{y8]J%p~e^ ̜8o? %{>wWar> p<g+RUt3e^91$J\2ϹÁ3=h 8oXEn?[lȊV[N dAHC44fCF)>G.͏0 ̽>B|Iڱ1N?m*S XS81ei[zd+g^X@%s *n+EƘ Ԭ2O(2Gi;vb֙0ӌ0&L#B st @h}4hJ4s!:GS0GYam$}(rLIyYS_yH4Ү| fYnnĘ+c0&0؀qbGw{xLpϿ~H$Z-o+Ϥ]n@'(\q=bIA QJlf-_hU_IUH]lAɯ2t^Pd+/3{B۠ Pc40GŘ҃2넧g|LUu % ioO^-^F8<ΎS2\!G}*&PCf e1e *Q= XKπYjӻ.0]'m)Ͽdf@;، =E>KN ǿX 2MRԘ%JtCVf[=m%2§ pi+(27d G|EcCSp k.KQTIHuԄ|ާR~v_VȖkOމՐPWSYKΝ<)ۉrgX7 qr*z7 gkey!X{O,52`eP6t_A": W"D |zgWG\e@qKJoOm3>^<($Kzy!8T#O}uNhDءGOV8ặߵɓ7F VyPԙRN-<Ӎ&ܡHOSQ:;~ꐺ<n>~ZesX`OP ~*V]<@*o>kFqRGG.;W^ 7_G mWK]XF8r3pbEbgăڻVKG()9Yr=wC/;.H罗s%,cDӝ0ӿ~S/]e0`W/DZ 'kIIyAt r{u`?i9^I1J罗ө4Q|SM|*ݽaK)V/u+U2( ߎ,f;BWԯ@-,۲/mj;2 ׸pB 1uM@~J#W-_^bFywY16U(- I=mL[uZ|}yˊ$ۍi FShbV͸ٺu<gF_gMSO\k8pv笰xAH٠]c!i4&ӡ J l*qzPOM_JĻTTd"B. Pg>ufZoJG:Zy^sq3WG~G=z׈gRZCl5Rs\o+D٪T#W:R I&Q* G3ΕLDh'Tp{y8/EtS:RrAv7^EeR~3>lS%;`.!5mV}s5W6ƻ &.{Uڒf.W1qaf~a~lI+^g ݡ\R DXG%^|Z S/X3SB>%nA"^8 c? kˮΈb7^m1o47)k \~qCS:* ߰N--]=6%_- ֖@zi V 8o8*y8-TY1ų!KORttϤ$e2tx]R< A/ZȜ[RǪdHqV(|R>1! xS=Ki d8prQ `% 8UW/ppOIf 8HG#g%1x }l'o/_GJsO >^PڭUVS.ywv1?+%d#X8H{ Յs+N1Z-Cڅ(`NnPG%zD}tEppv/\؁3 csK+j[_)kCi;9 ҬPJq'MCtpAmJcSYR؀N3 |Z8ul' 8:!Jt/ Lk6cVʒJze QdAL騋NP 3OJ8e h=]BMZSQĜ Ȝ)k5cYEC|H[p؊5裶?SNg2cyZ *xsc#t/$ Ftyk~6Fņu7P%A:[ I`12+|#>Fϣ5Nj C%L*41: m͖F76YPL7m.`B`fI12;`mhs)`mJFK8 F6|ƙ; hWP~wAIeG\[82^n!ҵE$`2@@͌fhmi4uH[9oGkCd[FR2/LSe碎"^Er4GyȗX Kdd^f>3:yM-I*ؚ#k4';p-@>AjDKqiG9אDe^R8n(]8zwE;}~S{{]>gueIϩv_Td1^lNSE=wP^ҭ"E{2$*9)}2JNpܐkqC8BBI  &7$#$pܐkqC8BBI  &7$#$pܐkqC8BBI  z8E:\e]Io8(v %]%M!+N8BIW8pp; %] $]=u_W/9~P6j/'_EK.[bkAֽFZ~?7m!%a $5;~!yg,PppO>q3UJI|YnԪ{LG( K'Qx׼.=8BIX8?Փa*#%Sžg  U:,,'ny~Ih]-8`C0ހsJN-xQwN]Ջ|88ZMX~b`{{ײW6w8f2mw1n1W8La~mE~7.LWg 3 =ԧ1t%wji&6אAۘͫ%=)Fhhi2BL?Q7+&ݎrJ8񬨝=2;T:[)}zpny_A`)Z3T' |N`M,;Tyj- }֏i.KPE_*B{`K0mY v̓5Ouw| B0\/~De8oI·ՆFh1E&bq` C2l'g,* n{bN|*f{ NƧHIz5#~3BK3ub89E1=LU9\Nw(a'c 2Z=Κ^ZA'Q2UUsDh07h2 Ix~*Տ*UvsbGVB3!?(z( w#ӣ&V p,VJJ s"jംMGWvIp6@Uv05TnZfYS>*]d|A(Bl΂] ,1L?@mTz2 9N|`[XQ>y<8^+)ǒ8ymR'0c̀a);(s7!8@k- d{=4B8w0^ָC)~ ٟd9Aht$1K8unAVDCBImYus$/ztIQtxN۰&@*ޒR nwzQKwUR ې~c5jz9şSk&Lڜw, i tGFv̈́w8]!%?]l#UCrTk9Z gd}7_7TEf/VU HrZ|+m~_o#,!)#atGZ)o%F $p< va&:3YT}Ol#U~u(\.?B^^!ɁsfwGp^C36sj*O Мloi ?s%\'$YiƸ.!/p*gwi-Ϲ$5pB~^7`ۺ10l72p.Q.-]2@O%pLM.z9pNBˁ ڐ]`2R|,?'_ xRG6&NdZ.3I$_lͣMmε`Rsd{{4Ksdy ͸Y[cId4N֏|X d>ب#1BY?tP`]*OU晇:MowiZ`K`42wjO'밅Cv|׿3l/oҺR?e4N|RXdr*d 5)cB)WEd:ǣmWKYS 8ͨSěJ(5Kh 0چ# 2+rFYvP,"6{%"Ti4+q p*UbqFc_GxM#Rz®} s˰&G Z~nU>b > N @3c[p<"*mT& p|un'4?u8`<߃8dßsv5  Xi]3/8?@+u֔iZ0Q#kJ^Kś;OJ%n8AYɀ5ԏݮƈg1t{rm pVBED-FٱJppp mѼ\}'F #3vpsz:BX=pGz/\L"Y~Mn2H,D36Z V`B8d#/ǩ39 =Iv01"mHϓgE8:1y"fm*UTQ?Zo1ڿ9p{^de]ઉGuxd֎pfQH N%L#y l@Qw9Ë́k>V[byƱK\#zY%i߄Kk& vjW"75#/4[5GY]'E oKա9b/_Mޢ_ N#MNde./"Ibw Ũk,1ߕ0. pnBuԮUf5M8d)[bHG Jvd(JaB(Sګ`izZʝ%yMT]FhC֜5J59s<\ ꕥZ\?Zirl$g4_vs֏svU}!{UtA~;zKG*`$pWW9Sq%skL7%[}h[?cݗ.}Io@}Wsq[CNr( pޚ4m[? #8Ol3FUѝVZ8B[oBxWr2H&j-=sdG8BIW-iP'Tɛ*NMlM %UlϝJ\%4e[4}A8+S#fu(4~}>/]SDO.Ƨ p IPrΕT{يE§1BmczT+~k\0ƽ$3isD(>`G-82+xS:VOc||rq|hBX@_gf0Kxs27oEg$|#+p<݌(eL): wIzs!7mݾ W§1u) (z<8_ډy]7f.o&}ۆv⁡c+8VvM|yN$ө=Ne8Ou+wM$& G(bОyKʀBh :2W42D4؍cbl }& =LЉ1ɴ3׊32>/\ܶ㊃nqO<"=~0O "ՊwȪ!loB'迌lS\3uV22v5`J؅2y-j^g@2 mykD\7^[7Pj*>dWb['#7K9Ȁ oZGEO~0؞v*:dLGھl2{- pv'&ڙL󼔜7$v~x?u iLJ瘣P:AS`!"SZ*$yj @^H.ȼPoGYŢ[0neW~>IQT͌>-iI);Xo/5"J<-ػ]M"E$PpՋ_8ľ~8o*y0}gγ֩^ߛzwyt--*]ݝ+s r\LLysƟ AxF6W}‘z}]u`uǓ3Oh!t'_7C'Pχ陌e Aح?BsO,Yɘ'op"yLb}Jl1KC !/qYjmDS;;uʓOIy5%9~^8a|_*-Q}Kg#!>p${ZQ$49x? )KȰM`Hn&MvWt$>T8ZpAkA.Çia? \b[@~`pp#EJ\(΁C]U]J#2u]8$dcV ލ$d6'%\JWy%JibnuIō|%TΛ {`h܃8phx5V>;4>5i,+E8ɧ8Seg 兺١20t9 839,"B9*w:_L&ΎJ".Fi!̖Y_X=/ 9[6 pvpA .b3yOjdO f!rp,~iHQG65{plc8ݥN8$84Umck6@R>t_ MzRvM8'jWYF3DȺd9b '6c8>͐. -ց:~2 hDV7֛͟+i dWgIDuƳ`E3ljЕP%_F1!K)ʲ+34PXOzZ8ۡŘ(5/̋n.b] 2K-0l2'J 1>FNJ@kn[/.bԦ6ͅ>#El!f?9 a{Ϥz}֬yY6qqI)PJA€)^`6 uۊ;ݭ{Ej6qܽwys}Ӯ>m=+5k+NؐBI,H_mB4rYVG-N㜤Oxƒk@4#nYbmr]* nK 1EkT# ƗSp9df|O.iӰRz Mt| >݅uGeJ֡dgN!$o=Iid$qӞmgeS|ޤ2Fcǜ~ ~EZ'pbL7un#Le1z$.I,ब\2MCN8 LlI8_ZQˎ%p6hYrKSU󦐈7M,ktK<)# 0d:KC +o^~9" YRe85 @6 ;kdž/2BL!f)s4^R'%^3R&Z8J^f3AlOe6>[zzz5#? EJqv>_h~NN8 \Tݣ|4^$TpڝYpbxԹIx'Fs%dO&x赱ˀ 4.'ehHfOqN`oE3^ě7|=Ccl`d$'db7l`lS^N5ke{7^ѦMeT7`)Y^T O IOQVouzpG%I&7}Vr';l?>NJQYZT &ror~=F6DyGD:kΌ6d \t4W &>&OyZϐp֔il[Fԯ@@W 8odLϐzhꈏ+Ԛ5늼Pw2IE!:M˻hs^Qև pZ6Z0iu?]ܮJJogb4.0gicC|W7x}&:Ur (ՀkymBn#-f?N,3uV [4ڠ¬=,kXX9ݯ#;8led7_2,Uƛ:3#4f* :.]{mwu+Bl (-U4 '=O]~ # g}tJlg'KiL3x=9Q":qnIuE9nSGu }0{BDCVx pKKߤ82Ήٳtség/PFmVDQ|=)AjƉ|Gpr@ΟE#rߥ˶uk`>Z817BQK-8o9mKQ^!}1zP?&m \aPlPε:Mf0<Ļ=tpz.j6!p8o5:{#!kwyq&4&Pr s,L\¡=pY}G;GJ{{2'lAz 8ڽ:܎c r]쌛2À|\3I-NȝE okοgL,FxUXƸ#!>rQ70/=+"8kL7z k7F~,nn\T2uk:_7ft%dJ2!="Ids݃J+S/hNCWSgse&1i|tԵ?N7Zqeel XF?D[ p6rdžU'Npxa0l[~ Bl kk4)g%!v)5d&}aZNa%)ۢ;p$tSqF 6hP^u딄_b5Ew#| Гpb-$|k% 8Wiܧoׯ{}!m"M2e'YIZp*zjsI+]:=6NI;[pD-8y,|tI+8j.&W^o8ę:3_( 8WN1Wyq:DbSK%G*yHZҰc9+jIf l֮8 c|$H2_8j)sEzr3ItVAhr 8]TS%G*yY@WC7%R[pmxk|$H2_8nGgqXox 8cROm#|^rm!v-8q~ad$H2_%wx K3yId2ξ9QV2$KE4$H2_9x NAyEw+jIFt 8KH$pbhf50 cOO#;m5A,8>d sNFQ3Zzå}Eɸ6xpw.6}gZBT ՝8&h>'ʒE8`u$i=EnAW㴎CMTz}u29{Ȗk  8:3̬R]sFa^^׮a37GO2A?B+}{\6I(^CW6ǟyﴧJHZm&ƱC9% f7?/Id쿾ܿD8p[>S:F~b3KMѤԓ[28_?N ~?"78^{O"pFR2\g5K1"p8N4Rpi(H88h/ЕT(c#O P @QiAif8 RtN1AK;8+M Tg3Wvo_hõ۹zlT`#[mS8Aib 8ǡ8A^_t3zH8zc,c8/!pE <%ߒvgbL*S&≽pe؉T8[fܷWR5C:`5*Wpc2G]W۾ԧ ʥl>:.6 f!29o׫zM'˛O 6ri@wZ\d6+u!'PjN'@UW+%G, ii9"f?3 fpY4!]rs,;d<^9Kw'Mh|!?8;5 cpbO?Zfk?.O=k:?C^-8}q * ?T.<,sݙjnr|JJR} 7U\'Oh(v W$UI2֓Zۥ?u8k,y ~FT|>dglCJ$"9.վ-Q:Yz^% `W_a6$>UB%UQ]q8"{r*xze U7]U!Y0^4~m  ,k.ю7`_&_+Fq3Lb)jF߸dr$7wWo0uK)3ݰoۼ;ϼ81} yT|=SE7+.-scmdsN'(ZzѩJ)1|9,q[w ^#ްw(`jSo 'M^#d%suFQF8܎7Zf_Hkw~AxK#T'o{mS%\H%%+C;6vB|u-8g`6WLU'ELPL>I/C)tnpH޳"SK(XۘrdlꉾPpSFCnu,l+NXj["pV q2^ڶ\e>p`A|ϑ2"8792uf2Z&3Q!diҝTipevWoը4HsI]KL ٵc)Lc' * 4L)ǃaw|NEVO5@h_熟RO_FvtH&{3mNjnR@nTU8w;U6uI5`L< ed8נ;%M 4˚ iY>0ǔ KSDCHQyoVX28nzب I/͟Y,?t0S Ug_eOHN-|vRX*L/ٞ5늠dxNE+^<$D%K.wXpi*@f+ 6phi"d pf4쀓'Hf]-(=2D&K o7i #biFc8( C#S*/.=kn;o@s@95׌5nX>TJ]~^)s(<!S$<Ү46~͡QbB\g%+9~#71nU{fm^xT%Ju+zOZbLV*1rH҆sqz;/W}?|Y:!ֱf;`ayUj cZT/9 M(Ijgh6YaPL*@b Zu^6m6}NZn0|,-Et߂BxJ:uj9/÷U=&x!k3rM}@ m8*7wKN& efQ`+*=(+嬀WіNeP殂e<lk ~c$^Q4`AE~6Eq=+$dM-(hO/礚l] gtHefrO0_p̝?È jC?F€sTc uyVBh g4.=p4ˁ'MT畱b}[K^;F8W\ 9ĸ23*sӂ b7fxn9yp"`.]A1`$E'Kf@Iyc> =Y֓.&N~NQFSe߶i۶N2uf2EY7wb ] }M0=xRP)t_ݘ7Fx :9 kwbJ2aȨױ<{vV >a~ ŀIfap |#wm 6ql S]VxJ3aEXԉ@ejĈ F- ,IDCt5x%N*ks7*f8IMQ8W܏6ؓ8YHk3>g=Ԋ j*pn@;: 8ќY-|ej1(ݴh%RgcNg(Нg[NLޠ%dhR4Z8;)fZwMՒ?#9Mks> Og c-%Iܡ2"!pD:&KN7Q*}uOˑi z1arSP$8.p6xsUp.m]*p/u7xG4AeIr։H;G;sQ^s$qW?}w)KpdOE<ܺrK/?pاce) f(V mq$Q%~v.]I S'-)Oɹ2͏ΒwYx@V(4?.fǣ(j[5!q8lʩJ3No 7UZ&1턞P7NR;L'xFlK>7ubb;lnsK%Z-?ꂅEP%07>SwJEe,Z6!Dᶗ絋 *2jLkr<@uZo~E7d_\͵uM yT'`"L$*S=WsMi%^k4MoCZƑC2crOz8QVrNWcpߌdk1Q7}Pe1pFˉ].Jq/c2vp;4M/Miҝ2|9xC#c63.@8%Ƀ@Zokv$ՓW5ōݺ/o-BNn@~g+6k`^a_(NlbO۪m:LfިV#(VV^(ϕLYuw>Ɨ$O߱dEd ;V(hg`mwp"X>J -3,ZkTMGafZ*ܱd%W%J!sG;V bq߼ulvbE/V4uZA@ub{HzXe  b1'MmkP@3t:i1MCFmVa%/7>U.0ֈy-/NCW. 0eb3F\lh{9rA~8!QNzgp;w\",?([}(8;e&ic:q珧3r$ъ/4j`ts}>%f~yc8UXįX p.; qOv*|$Ѝ?n9Xoֽ{kIJȗʰѸj>QڵkժYFիUZJ ·*S&%'u})pˎz*="g4uA&Φ3ʸPIF@_eGB6Mf\3 r6u.*/ WqS:{6SGe'Qt`XfzV1F?X?ko?5X,8DɝiFsG)6֚劣2dZ¬K{ڶ;QQ [@:Ι1Wl_qn؜GogKoddqRĄ?jmg}ZΕLJK9`Q>GBO `Ã%m $C؋O#tEZpNA?΍)K"2CۥG~lʌN`Q-,'H=Ny"dh,V6yb Σܢ/U4&,Y&dn KiPٌ/Ncfbe@g'17Ln,GUQtϨ08 ?Bve8pҪL/ 8$Cq֡w&70@~ݾ(:?p:;H=eJ. oy&,k~tp1lX#Rߣ9ȞvOtqFi8H>-vO=t]?a]GG>IهgZTŀvuw\-\ ?D=W;Ea3A/y3Oh$>wݩT_Ysw߇} :yGnC.+s1_l/CۦY[O}!״HXnN41oƚ:7,·`76 VWŒz 3V{jZJQև,I|?w0 4BBb 2"?EoG({x8iFΫeIRC<n"WX|} ; 7rRڮEaY~=*ϟW6?]9uƭ),]fXoϜ咅-`u7̨|_*˒z]&W(Fj M)R}ٮI$mO8[H"chΑ(t?Icr#ISGGAQZj8d3WrN\"ԙ=ljrcql=FGG 'SVPyD} -u|HCײ*Ħ7-}Da8tËn !gm'=&ޠ*E<_R5G!U82}hR-pȷmf]S?eq8sV2;K3 }nˌz1{'߻S M\!֤͂c?gLSZ RL (*7-`:FqmH3?g+XJ;^0bZtI$V̭W f 9,A(嶃`3k/Q QO0lP0f&ryg7V[M6S/`~1rt Y0V3rۜq ɓͳ>.?A) Ep-hfF1 8]Ar^PpW +1Iv 8 ;W:6짋P{:sοN"ا4jdw;`+9\19b=jYE&g @A#:^94^ 8h5.jQ<¤=!Cæ,Ax 6s; 9IWO7@ 6d+.FzjKXOq׽ ƻ JQڋH8aOڋ=8{ż1L, i c|8莭fnAg) XD8,Qrq} y SaEa-ֿ0TF׋%@#~Id8-#Pm|c|4=ړ[^]Gb,捾i[`nb)y*2ps8?]xwlNˑcXÇB5Py#1.6HV:i;] a8Ci YN4tthb7fO 89>2VM ˓DcX 8gE2Iغ{҃j6/pIfN5#8eYX r0' kS pp8$$TfE8Sеlt8!\BVb`u~6I8I:! bF \#=l פ,/΀sBƊi}^ 9#ḑ7>Jē#kI!pHѢ4~&R0[lsE̛FV*S`cGFR"~2&эeEUjUإbd:nIf3C{09 HY+ {cأ&m(Qc @Uͅ3 cvB4.$xz àUPX$}2Ԣ{UyN=j"UP^QhlD2ZE[ϷPތ%`O}xA]% z} D7ճ 3Wco9Û2VmI! ;?~=7lؓz..ǓP9lOy5Wҳvo7fp*X~Mp]zinť9PS+Wh }b`:'n'=i0ǐFG՜8Ni{y@=\1ԩB9pl1WV zwcɆj$_QދM)~t aW޵\Ħ-e$p.RöY|7TƭS mZ}&T'#3FޔN]e$T'g܊3ѫƜs_|Fz{~QdwմOo=o6k+'9|4gߊem"M:uʔɓ&M8aa@='pCSpAJ^ݒ2U)z5i4QAK9G3_JHT$DŽ2SceE¨NsfTUf oJVIIQ{!gqS"8UĞw|hNW=ںBaM=s:oBLCmB8f爕6;g4ߒ:"QQwyA72?|TԣTϛ e5k/]/@~‡~˦ơ8ktCś,΄0^χe,77pEIAi3^a= qrR`P+?bE07eid\5 ~ɠN5uG=F X֩N:4 +rT F>yaBlcfD<4)'&_gd~d84=8OESDJ؍\] _1/|h˛OLVGI@W=\_s5piE08'>|?6ǡhΞdW3}H>_?y2T~Ŭs.og^ AsUV+peC]WW&ߐr 8FeXjG4]ʫiFO˛Qog,o4怃>њYm"q13i9&ju huOY*?э]{qʿɉt=  _9lAO@F 1nqi'yldzJcj pvD_/AZ+iIgJh}xRy;sIm.>;HEFzdзja-_yz~vRf{ξq=cONf ZWcX?]6\hyTwLB+*=~(% O+rB b+EE?8&lo2[a6 &yة_%gV;!{a3gcVQFV\ E÷hk+D7f U=l_Bq&sL 9N? 8+rwBq38^'9Z@)޺] p>+:i,D&2B~G hklfrOWJ`^37wweoed0J]|lq30E0#0Ca>8jG 9NBnCyNNO lf.'u1v|ٳ_xo5+a{+L ̢1P//1PC{ >us{1+WOPN-#'fg\ 0T1lqdB.{ s.16üeqYBc^.28Di@KvpҠ4稓ކFp#l,Lm 8w;9Lh4nÙRoxU̫vۺ)49)) ,{N!,zMh? ++Z3D8;Ն}+ 8pWCgE=To'N e2/ xp9Iܝ3Ƞ{3wqҋp0KЭ]Θ<g5Gng$!9@8O4W#e`-~IG-9hqy|v

8Zph a vx2\|D8WT{XCC$};c6l?(Cp o&2ֶC>&nnrUJ;nV6QVCgGa*u:'$L)a:%PY7VBqdm `6 ?6&\ j5 e;c7fgq-Dn %~8R'8k_s^{dz'mvi'T|L4-0p_{50AG>壹Mhn|'`8Ǩ.$\eZl-CXEMٰ үnp'fn\~Ɇu9.{mmrKE?rBk~r%, !lhqt^ײAUʻn8?n%>s╡SNݘhRw{# 46G]O~_.3wׂBo!suBږܹX2T BNiZ`rrϩC4bSOV@d18-νFlK78נ;%M 4˚!!pv%oؙ^%q)jX}a:O2#GGFQmbDWEYUn7of[8ؿݞ,bD38֦@זو$*E^̎Ѿ$h6Tgwe!p珖fK8 8J8o':&e6pޮmhT7sAQ<]<^w6=4Ln8&}SJcxב-m,mUpi='g>ӸbW4|_> ϾJ<OD]-y$o|P7@f1I1ǸmݮI~ 8-4|Xq~_zN(#&}x(=\X$S@d3ELNzsUޜil2)pֆ\8ln|v`dA,`>6s΋ǯa3^M>)JAU"Õ1F};5!gb0navy S9hEIdϪڎ=$(uaP%Zقs6ve5-P'EU8Oap='|]PzʬB Z*l={a6?`+(/!_BV*w#U 6peJˮ @A]Yf^Db{8I6ƍ4?L'訐a}eZL ׉;KqӾ6}^?w+!|T۲}dSiTj2m8CJg |6a8wˮa`Y ؞<*Y7:9ǕȧjE[ *QTE]$i\[RQa}*z""d>4xEDpIRUw 5E/ޞ)DV'%-, CTk*R'<IX Avrho[0@M>536TFN6?qc؎ET jUG60J ,aXuJ8UM2y҄ #WRN/9m)S&O4i iλ'5w!9lE^򪑗2[8#oIq8 Zxűly;Xp8d`UY&Բk>9RGW-ߋ.nu40tWm_N*- dβkJa po.SHq i_5 > ^ݶM[vAG=i vAAM)>]Vc橛r]* nK 1+2$_N|W2Ů| [])J9]`~gL7bpn4oRF2 YZHJǀKuN%87>9$R_8, ]]{~䚱A]֙u(w`dOCO2¸ҏ Iю%NStYXCBJ(YTҎE);-*,UsߗŘ* ؑ)V*Yok9ycI>]X飻2ћ5uwNތMII8_ZQˎ% Pݝ啢7ӫ7Pƣ-R5eJⓗ:y6SwU)%etyS,#Xc[R/z@c}w҃i~s%Q_ɐ/e X>I?OȌ +%AP+s>WN$]㦕fx'hRR!;]!C^\$ЄfOڪT${ B_g V:wPkJz+B~K'&K&]]49(Cj@8 ~^ :ԝZ:]ܮJJogb4.0gicC|W7x}&4;Ur (ՀkymBn#-f?N,3uV [4ڠ¬=,+/pRW`8rvWG|=YvREGty¶;:Tz!p6YBg`(JKIOtSy£_HB.ȼ@Q뉥b^pU7BYR #$J߱Ø3k9N(F&,)z:H9}|l.tyI. n֓zSݰ:?`4zdkg1+3GΧ5pZkΘ"`u&,=/U:, R7=kB^9l>7,8\fU\s>md+ 8V'4(~ 8ҤТى積m:@k>l=!!+NR%2J#p4ŵ'V aPCof*6 Z-Pո?:2 :ћ8xh7)N$XӘ@mЩf'+?xD[*Z}g!+Y4"g0]l Q9yCa/N]Mfض,W2 {\$K?l4] ʹvUg xW&Ēcu2_OcB %]@dBGhgyd-G3 j;ܡ/?g pU27س5>ܓ9A` -΀3X߫c|8y.5θ,3 85$ e&F<*xhcܑ [9ਛL— xP=+"8kL7X$ֆo8Z{kIE5-cY;ucAWA`I8p+X}M .;JLckn d7O *hNl TO 3D9ô'`y hiJ8iI:yϨQ&n/ly HAdEQΨIpOi7\.9Bo cU$MB9ݏORudM( jdkl`M, UIjUO83;|$ pH8,myhJz ?jqA~5U= @bʵvx@t0tRUeQE`fB7z5^Eoʹncu2WOZCƳ47T* 閧"lyȞj5] 9yv\W|r|;4ǍqYBimwY:\Y,tTkyU+dLbɤ;=\b<9-]kG'p?ic,&_K ;T s"anI:Q%oDzsM{I}$cdS{t|}W I~}8߻dKI:pL,u #$́ӣp!%>S6T{o5u>$S6yKQ`cudΒcu#|%$GJI$I+ 8V' 8WpNp$$X$H2_I:Idcu#|%$GJI$I+ 8V' 8WpNp$$X$H2_I:Id2S\.O=5H$Xѧ$SO>mnq=DӛKp$$|fOO`"1**.=љ-U'4JI(`*5]>o -hTݾ$7)jW%OQCk]xa 7K5z s' YX$| p"a/V 0Ȋ ӛCHq%W i&MV'5p#Rdx2b].!5,×{]RIg(ySyC*)PP[I86"X;et֜ICFKp@8K ,*'˩]b'mJ8m^BiTlIX[]KAL k]QAĸvk؍݊ {f`0;;sfSr'}lKE ?pIޯ7l*gP>"/[=Cl0ﱻTZ}_=w\{BjAW蛓S|fܛ{Ȳp\ o܅ FXܠ˞.dXLmuδ~XBٮQNŻ[ o 8-3ha߱bnB4"6?a'A-Us'=3g?%[Rr.LƧ_KN:|< .Ag }F/ѧr=E}se_Lk7; [nKw+`bCn*p*-3V0LѸEj&Vl3\ |֕;/Z8nTM8RSvlto?`u39Dyhʍa1V0zz тaŤРu\n*pTtQHl`&! 8Oٸì(2 ~b{6aάg:p$_mQy5)qi%mD 1iFUd=joU#5$d15\3Jh a=? si><N/т}AL"_D 52Py#4/PtmD2gͻxˏAAz 5q$aw,)/oO/*W% *-nnPs'"$^RRGlX[H%d%ea*ܫ%R#ܒ0v!0&C bI=hKs?Kn#%H*BOiH$exѭG_6UC&H nJZ8ȇ<%h-oWZ$\1]7"mqq[ 1D+?$UkikOKq' ʶ'@,Uכ%h goQ^UJ+`.Ԕ2oar5kg/o9O)1Ӻ>+ `mH_ߺ&?;i[]:,gy6#5]w)?:У!z,sEֳwVdaV'yP9jrnnKXƕ2Ɨb Ύڳ&.^?wcvZcxcM`w[촻w6?Q'\x<֢,Tc' bՍ+`pR6J7Y\D:A'qQ/^8ypצKLدW6MT)SҞs A7(E}ojk%4o>6䡚KṂӷ4{qFǎ۴T_Zp?.*ử~ӞNlw y2}F;pS1}nq?xz]W/3ulP]6{$ ߳neq)-ŀS3P;'Mb4%Bwde_қ⫲:L3YtHpQ&_haP,N}A< 8MIz@6 OG¾Ej{XÝY9>Ӧ,ttGtH8/V5ɐ*Cjr=ks:{}'*=p!8 &ڞL).J5p.tst@%@hJGhP'Ѣ̫RMXaM5p M+JĈ8N¡!#pۥ{Wy*+}@bI1Cwpܙկt6Ex3 [uò93Zl)ʿ㠁Xb1nzon?`Nơ'\"~U8$gb'jDQO*p+DZ{Ʈ7w7_7Nz 8@|o&e.&o#NM?-!P,>Ů6wւci;{gw&;/#ɝcrMCG2pnN,2LW.;fK zC68vv-?L)S_zV Pp0e%p"EeH4gh `gd<_η&6Р1f"H6ƶVʇm5Ԛ;1zY,MfgA1 +XǙwJȈ?HM&4]LDk[5:NgZ108]V)ڥðFԀgU _ҌSNnX,'o+^wxWEc>ȗ1ԚY[ /wLrh{0QY|zЊ~n sEuUTtJnDj XMdRPG$Z@kD-l6&$JTXSPi`?aYdӮg䩁CQ 8CZ`PejFiܼYU$zKFI63.ME+W}w|Id6wnFPxf^EdWʑb?(ofޡ%R'3&w>ypZVZflqXE%B#&j1#VA_EJT*տ>z ъn1䥅m0K5ЛNtŔEwem`BUSK!FJ j"2epM0LS#T,t=s4G61hފPtsrOol SD4خrUjoȏҞ6P&!q:!XhJ%bIfGO>&FwI-[<&ؾ6,iªT&G,]57 yy ioД$'=p!^H ( `Pm4Fe Kɍ101j-%L?l&童 jxlbh8po 0(F 8l n֖T^8EQXeY: rSAYs5v}sĹ%9 IDOw"`f_D<y>;O8 `$!k~1-nO ~mQLpy! ˺ܗ \^u/ϘfhL#p)c֯V? cbTw159pjɎ'RBtY['-#-%7֒Guh9#D>Sk7U0[Zh3&o* 'Zx1#O fA>0SaNW`+ު "y>_!p>={; F`Yn^|k88X#R! Ca>~=puЋ9-NW|K5zzFxM=W$p#lXCʊH[ϋU)8ʮ 6d#3O4o~5;ʨ8 šq'{rTЗrP?TfH /),36֑ y l/`{#҅Ϥ,;{~n@Iycǰ$Ipg'BFc,7 *eXb[F{6}6HG$JJ#Z$U:.$ϞQ,sTS0ƨg&+?`z1o|*<-Hyjl/&LG]~^?Џ |HK5P o`ۊ%$n`j8Yz:7y#+&-^1?]rFDj7% JcoCGL&i 7&&]D!gI̟=$XO$f#`$HXX,^*oɻZ>2Nc=od' d!Dkp4*K\'/~D2F'cI%G`H%~p {b H,2}͂ƈQأcܐJ@w8L哮0B̓8٭oYy4'V).Cu:-:I_Aٯ7zd zw+vi 0O<ԯi8w`道'( 0/πF~kz蕂A{.<'wwzP3&?TX,o ׹'nXX$IbeBk~.|#彇Ф#^^rI,E3>-$O7ڷS,>-;9|Z5 p*/ @.3 wL0|‡zday+,FZz.Cur`8O*JB\H,:aM3eNC) "')԰$_ZM#Lk kE8]FB.,9ae$!hL?LL9%,0qeSBlꙏ:̏g4ed=3e9֑|hS%:H?F(e}4l<.v=Ck>{+b&?WB0ö8 Z:?@ytz$ 'ӥpr87yXf5p ɀӒD  GBm8TYz0>/XdJ3}gLFpF5H1#T9˻`m ӌQm,zI8.݀#-Ͼ)4'%6OOI 89(0 XC' Sv?mỦƲOGȾmnyd,R)SMFH|TLޠ/?%=p2]:V6道%?ȝN! ÞlMBfػ,%%0Yrf昗]q[lyi*]Bay1+#cBD pVrȡB187)dOc]YGp"U 2X̗$78S(q|$9 .e9t}nؚfunȍ2^"Jל-z'Ɏ,JO|,4:̧ 3&Nv<$،y7Jvļ [٨ޤtN?kCD2}i5pR9\JH|AEAL ,5ָOT5 0|6gÿ́t򣅆V^MYg*%*AZ%S/p|3rN g]X9 bXS˺VG͡i(p\g`< w6~%/7~e+ [Q7Y԰'̂bPAmVaEXn< c+7^!}zdwe5f5p/9J]G޸^#n=pIqgUa{+JGHN:k^BlTĶ>RՒz+EEo(fE6eyJtn|ʭ8٬ 8t^r_̹N"˲{=F~K3n*=e73kb<'輫N+`>Ϭ{u>C2V z7mN_=L!0+ t9M6TCᜇ kMc_q89C6ACMIMҫC% OH2f‡g J/8S,d pJ.0W]('HGDKzݚЄCM7g*p*s#iKXLp24 g2hQQFGmAqƽUh4XAZv1~Ls ″mѠ h_M2qH=prȻ 7-NAQ_wavy(Eob)!@ {@o>9g _;AW M ȏ})pb ˡޣO~[f3*m.ït&83{zVRcb^io-ރES%Hr(MYצayJϳA^pfnFkߒ' GR^HLHdw &П]qQ8Jc#w7-- Fׯ8o7c^!g4Z%*؊DlmvKI/;hP+CuކS(4DH4::5SLTsО0t\ , Z%IVT]2 fg!b9dkz[6MC\ 83EPkbTc(:{P_}Vs(ArtUU\ e/U侁`)HztĸV3Pg3`DCCkJ5bw'i1JH[h|*f6hNMB΄UpcW8T do-*( AKaZaYNK=FU㰐`•5Dp)7p6F60h!UErJ%(P%ta΄w =0JV LV_}ұJ-w(ʚt 0OTۘ *ʁc5OJs׊ 3}#k@-&̙E|ʊ+ <=ȁ<idxL'3@˙+ |>)EO p^F w! |Cmpz|:z{.plm_ܡн?Gk[W8 /ˀQ ItIfOB"xWЊř)5?_\#&cz?SCp89KZG?^' 0O.C  $%N |\*psπ-*y X5B  8CH?g +e9?S(<0jS`YU<3U04UZ \2BBl"6HBa >[#pO{D^fqӤ xIO^=yk^Pr q!,\ECJsǐ'n9ʻ ,p p1L"70eiN^*p;p}f92,lO^l"V)(gB]6fFRNհHyGbh]Oy vl9pkv(mվ{]b:zδDj%ݧ;p~>{Y.*39hܬ̠b穀b":*ff|͹IpV"]tKԺ,y>83?`W+%p,J`%wB!SI!EFU[6NEaأ; b^h/ Vj9.;ug6/j!vHlyg kIRŀS81rcMT:rtN=pĹ' 8ovq+U{O^OK=.\GNY$p0Ŀz)-*!UeٰZBB5[2b@>+CaY! Fkd"q$f ,!q%=gia/=$;1$6jH(| e-MJJI]D➏VkT*KX!,/ٯh<gZ4;"pTF: =&ʼEkX{ HdRz8ow h%s`}mì*5O+JGr:Idq/ȻWbeVB6"W>8B?DPZ/XZ=p==&7ft,t(=lZe'ݗ,pbȫ3i4g]/ 1Z<8 0/hh{Rŗ~iΊ,θ%)â)׼qv¸ G+m)]aZ|lVaV:@Rw!-ʹk-ZuʹRY*xR[{+hTY%K=jWӠj$бeAe4([^1jeOBƙ@qe5?b>\9wEn@ N^.;$vS#ۺi-՘Vר&^e _Y2=biUtpGgtN@K9t6ąLRJFh5qϯ–J=,Y\I]bmC\CvN⌇X%<ˏًzEY%2B9IosoN=V{/^4K4e[Qj^I?)GjPU=}|fn8Tߴ+YgkcK+u~8,ܩdžڒz 4n8FOh8Kf,l9`nyv(\ч=濺6%uq:p-jf,3-ÚN&F6ǿ]XF3_JXso*y!wJ{f.l2k8㲾 Kl1**0H9Nzy. 44#'jҏ'9y0gp$tnoN8kک5 '֋jtyGX@Xyl. Ƅ;hG˜_B}_aJ%/#HR"GR(URK CSK<΅\::ۑ)&a+ 歖8e"Oc Q(2٦~p]q91Á7j{Ot:F Fj܇y0V<6sM|~kL Ӭd JN뙣!¤`+Ğg$Js3hv%,t)'#pȉӼ'EB{[]>\:ӿ9 e41_w Zo=(8$]4ZcvXVV%{{aκ0ǩI}#2VVW%HKV,sS'ȵ81E#ޘqĪ;#I쾁㹧Ӛ q%&~8CÓ:J5l-ah|V7/ڨڳcI߿.H%ŧV''mz`(>]+V*e{];w1h~b 6zdwq^\ ZL":7KjG%vmΧ0/"ǀS2^6)'‹ W6J,xGWQk[s6\TUid+s|?i+)wmej~pڢ̹wso9s>oR\>m_"ً| q$Ɯg9rl/]d7rCcyŷRSV3*>لiՃakc\$ڒKHG+oMy3IXDS{B2)-P_^0f,|ƽX{>*rtchuOZ7#Z\} {1\չ$z2QrV2˓\`"Yo#8n:ydP7@ӏ$~;i+f\tA.2c (qB_JVlq%62(6PK˜11'L:ޗ2¹I4M͗kܓ8l8*u6gOZ((E,tۿ3ߑ0.߿f d_8^asTd3գRb0C13!8;Œ~q>d8}E!fV仠A࠙7 =p.5FSykJA2<T.UQ)V-W(ZuSyQI3߻PM:m71W(p582+8``d/;FibB pX|D40gCU؎.$Qf0R΀YΌ{ߢsoOHFFrg#h%|:MuX Mk{S%![ү֥:a!? 聓tN7C?51,c': /v-0~e p{T$9%tWVp+a 8G Usu޽vjI0!8̯b Halm-:BWn_j%Xfuw`ڙ8>o_~ͻ|8ehN9K61px)U{qs;VqA\6pXEY3B>7F7`'58 6|QX6Soc-F^ V|h(WRTg6Apbcmޑ [ufh 8O dA>,L8 닒u䈴B7,lž-q-5Ïgh."oL,U)`/;m"'41mJIG%R}Kۧ^K46!q7D )d+'3M #&q/D* 5u|+w{h!ő0Q=Zqmț„lidEqszJq.xd,W6Hxo/AR~0KI4#Zkⶔr=bIZsJgQ4S(18XE1vU7:OgKT0i\QQʮ3f~L9~,RiPTD|`JިW%|M=TiBpjw|ACQxkk`v;٫eC|T1 d|*''7QҩBpJ?/jiF9zMzd~-P XKJhiS(!s+U ~qk!?фZc3~1ep>O4):444Y/Ճi̝-2za| лdoD&KHUXcTNN[=|e81d_-cv> [u2Hy-!cDDc 8¨{4 vÄ ߗ_d}Kx0#_¡lYyY{VYZ=8x"+Ht9՜({˧A=p}[&6p+SlVOQY!Mg^ XTyfb4GyY gt ŪϙY[/֋L -rQ SP^hxvuNBB;3Bn,de=Ć[B&R 4ŭ 'ZO/S `^*3oιi_!O G+dO_V٨RA̢e9J(;&C|v3Ģt `I\YDpf2YS鲌)S0'C%=0G#BK̕$֬J!p^VlA ~:cWzcPb1̺<܏/aCR/eGYrAfM3!nzqF.SVBXV0K8zEVb'35;Ca(WG fq3,vsȄoTT#{O&-ch_ hBn uv5m858]s8ph; ;S?ոi,쉣xAL0-6_+iDYw+HSm?(:zOPk*2 oi0ZfT4}3x4Hۻ {}*ja.nJoI8 Jr.ɨ_V;6fX/՘vV*&&pB;Ax<ǩ"&Bg1Hզ?$Y~_# $)#pz>t798D)1qWew2MYq #/x-gH4S0Ƹ&䐨Ð&XYWp΁s7hİ^gl'5 e#jro&2vbϰ"#FhlR恳NT16ٿxRpf!3Z<5)9)Raul,&*JM򅉄M ,։v{>iH4pPGĄ[09Aԥx/ Pr|FEƬ8$֊tz:c\{-lFb3͢Pn=).6F(&?K6b`Us^A8/Q pxڧTz.̒!ZFrvb րhuAయ6+X"(Og}#tq6apIphk Ǣ]iNQN\u楈)-"pBee/P_rpB2b&W gnN6)g(S5\?ؠၳ }L:{s3B00?`3M 8fSyH1Ge&7LL!I:'އLzceg9y-&F`yuF!n*IXOºBX(`ڔЋJckۑpquˋ@1Zh &S?4Κ wPW"I|l8lŞ놹8D68r:=(K3;1쥚bͼvevvP N-N}$ ɕ)Z 䛦rzMJuG]!Լt1^ +A1ĀC"(l~I63hTd牬(V/gypd[es,{UU%)AU%K}K=)Rijd[=E˯ g,OL0ɠj adx_Ƣtsچ5YͲJ|Zʖ` _hau+BVd8js\VHVZa6'Z\{$"N_-!GpE^zak͋jhLC$R𳊒) Ax^JFW勤}7Er#xv!Vx"s>>i"ó;5+gS׷7f8{%B[ggqWgiH\Cŋ[.9/QϾr~drptd8ry͟b}.Fc M iڝˀCȮDSʸ=N\$=pR:tώKgb&긘U8m+# q89H\.b Eaۆ=,K/WI(j4]>L#5e8ZiiW4<wxhƠ4++Ab'Zt3r74Tck&Kahhzul44Lc#Ո#8ep.zsܙi&fxvn_}G .R=pu*]^RJM*GTw|Umeku`cjȷ:8ZaJ(o5_{JNkO΍]56Ĩ OIVi'Ѫ,N3M3訦}8䴭qjeZzxɏ_?t7۵ucKwybK+.7\6NMyd)%MO/C=Gi/TP\応AeLuCW2{`>ͷ<3|3+XD[@X|'nv_R _8שC+dUHb^$_odozOӚ qt 8Y%]9B (Sh0;G/?9~P#1wc9}F3<燡"XL?[$ZF?YIG,>̀#;48]B߹UOGtD7RuqebJpdT;}ޝ۰fM72pOϮ4oTV eJvccn^t" #Ht?yovJvbsV6JQ4rB~|Xek9Dy *VL\F1wofuOqtWm' T_\ O"9IfCIA$Zm$* uDE 8ʃ5?omSeL0E1^7(3S2 Ivv_O95^:@R î%(}6(8bEk֬5kk` 8GENG/hjxZ0<H55e,TNf4sW0|޽>h#䡙~9ZTW,P*:\JxQE*MbP:pqM_pjGu{ɫAiܗCUT{ -ZyR&OBE=JWZ^m:t&M55SHze#"MF~*y?_&ȠGQʟ{J5z2 JJ'$kΌ3oSO$)Ѧ5*XB+=eHEG3Dld^j>x* jO{[rLvQbwDy>0T^ʏv߬.Yy,/H5w#9^\.^*U#ReeuO2OoRFt^p<~(RwO/mAQR5 _jˠ%" _RVNel>~n8/GiڞC"=u;? m%K낥+nܺsc_ wߣ v|9#菠8ӹ9ɦ W|ǽ 3-RhE L I3 $~B!-hR;p(PF"tJas3 gOnI |Jҽ{r?_P@]gV^'#!/#g/NA^:m=Rmz'v6@ۍl"x$oU[-VI%5T24m! U;?6̡zzNN:<d5X6f%!pr o$J6M<`-n -pX9(qj#ꭻT% 8wBvM~2UZG'JN(ٰZ'vsFpMc2K) x`Wwm.Y{) [XT䋴3qtd%5}<+c}Y^`EIȊsk C2!prr׾8ɹ/JKN'X;RI`G ;I7Rmi p؆g\dgV!(vutRTli\,[ ")?գw58{Ų)mXb/<p]|` 0: yIsKf K+1H 8n p(p&@cx,]"rf C ~o/E>#&W³\*!AWt9Bi>\|[s4>ц&ܫek@5‚КWsꔾLNuOWyxahChp@}XH3 qt6Fj, V2UДrɪNH^ mu(y+38f|I4UFo8Bppp@:Do5 S{lidy~y:5Z: &3 jovtNyY\e~ʫ $EԺnZ؜ЄNHyY;YTݝiP1yPWC"Xm.)#p~; A-ZGctavՔ/l* Ԃrvཛྷ+J\i=V]EZCoF^vTxiKT3E"ÆtML΢={?pP684-PSzJ=Bl,K<(Lz/h[ EkAUQ$Zp!Cd`tbemG(alj'vV̛gnhdMѲ/驺XTȫh'0<׵F8AUvp]UE*Ro))W5'_!]4á d ѪUO=ֻGơ阃pަdq2HYtoxgB_94R ['f~t &/]Hsٔjo0R2djyn̘BU#1i V=wHEf8=lb‘8ŔYWwoXd pk'D=:p4])3wrH=T(R|Al j+A!1/z^JK.}=Tu-(1\YVk"פyr8$փ8gvAQONԋ߼,*Ż;ק_ԕ*s:;Ź|O[3mNTg?%^w/5zyIZ˚D.Cb'nrjQ[ϫ 0??g8LmU舴Nj9͚J ༅=7wzgUZG'J5LK(8zO:[L^;dקXO$Wz։ UaYϭ^Gh6݉oC~1n34$'8Sы8Rj'&CeS7RuadR[=^vLLhk\l.1=aG"24iF$e ?>`:.g|ےicK61:ᏭuDMO.pOގ0ys' H SOfJzM`9}n؆f| OL/O<@ :y$.OH T <'+nSÚEz.Y%FtOUp'eԺdk/hBl[s(5DN@Ɯ4Sl-.'\ț`JږoW̝ ^nR{Zhn pj:}.I!:6Rj< _jGDbI=%8#v 58Ұ$'!pL)m(C@INaZZB48h͠^ϰr}sF 807A๏ 3[@Ç"(Dfn/UȌwm 9:x5iDg߿tf|9)iT+=+!Gu5ۮRE*LCc`BQR&Gmr|d瑛(O,"O U>*,W=jTt8+8]1r@/C~&v0\k/t=s3Oe͵TɩC ŤGs ΐPgh$kt6Y:Y썞]H?8Ν;Yºr'&ڹҫОYTe 27G@^\n/H͵+a&_*Es8mɀCJ@ +22[0͔2c?8Z:?[xt X=)W^"&j@ü>pNXzVA_E&c:\ff?Zn Ydg]׷48e"Nj@򒺐zw̷}#NzCpפP|o^ 68U?Fj8a2~&sFR-q{?/ 3GeEpfTP+hΚjs6 +ά=Q2 z |%8&M~~~~,J OsB7psuם(OmmSʾgwb͊$ + 35A֞bĕguh31K6sZbӛDD #.~Һpn,MHH+Bn[CfgQ;8J[ǖuH_yG,Cʛ3Ѩ',-^#IgUWOD=DPYK=ᔾ5&y Ξ~et+"65zU0e 8~wr{uF'B9Q /ӑ$*SƨCP4Fݏ/PBo;M'EC5퉣TF- mԣagMm%}XLYI!J!LvĨ٨IJMI^U`z7G\ :-fNg-8:Z aF{!EVʰV gj!po:hE)B ޒpD{?AЎnlSo(Ԛ0e~dwn܀k"pW*.]ܰG)iTAc]|lKyی/A3}wXvo\WZb_wpCt\iϣ6}?4T~͚3NwoiBF[C>UEq!qNo۟h 2 P㪝+qړ™6Y&rRmϒeuV{K (պ2 ZmL՜\]jߣ^ yZ lJOǍFݺk/ebM1vmⶾc^[sŊP4kZ);&Hڵ+LdQ˗IPm ĩ; dY ^a6Ҿ8ClNlqtm臋yq1-C|U3[jYjk leo[nhY]&|^.8dp*C(U3Qm:p1nһ_#zv&w/q#&U8lx.e S蝓۳3F @M-[}MwE_΋P8]Dށ >g~rѮqQ.L0R? M19It\QD:BKJCNa]4CTn7o^Q_t I?K'Y}!N9w,l"_Z<p41=~p ǗCN )%tp͆?ǀ2&6Q [țj $N)QNVFzhɖY鋧1$d"pYOD]y1pHX!qj:jA*blK p>\qcI?LNЀ?|P}g^5]eOܣՄzP%O(\M28-YӢo%8z!qutU*'[1VX֫< [Z!:)*ҵ[^[T;W^mo]2;z[e&O;j-BN*=`޺PD7DGeiXXLYY}BfYu0ũ6o3`AЀΥѭ7 ~+ZZgiߐ.e"pn>G֥w֧ut` 4(RU`dsDd~U@8kC 9E$=m N-SwǢv K\i?z ն R'{%Dx%pІclLR4i}m&p? q,1l(GFGf,>ؠdfds7ơ[0g͙W7g5ĀmJBt6 h9Fx-SRs+/Onpk~znuqfP;gCT/ck4VVj4=O'=V43bPr5t{XFcx Vq,[w&jtfzztOƏ2@8*W(ݴ`K"WWW NF9繼8+MfTp0_`-pp,+&Nw+P XRK% AAn~w|3AFŻ_$3DE37QO_8N? qDUXcY|;pw$AM@O'gVJ^}l]T0Oޛ q 'K22WQyh_RjD4#-; !э~8u8p=PӚkz#Ldf6[3]XeH8-W@vMiɕ e !}") d"p:/ɱb~ ? q}nK3Lf19>Viqt(TRwNfM~X#HchHt\a^XnwJ] U7Q$tֺ"Xq*șh7,Wr Qׁd>âb&Any Xt#:Hd"plX|mw@l/As盢yk_Lc}O53$Ƚs?bG4Cu9+;sWTZPnB !+J5{ 3s hdX-4Rv>`BnWUOlsrdÍȨb~~ 8ћKNkĶywh4Oĩr״Hȅ|czi^Η<9FҝLNBe uCRZJNR8u|DenTu0єc"r*T$)!II Pu|dfD1q!M3mJy$4G#f &>bIO#א$ʐ80._f Ԓ$T&'VKZK?\hݤ$IɑYx띝KHup g^:UHy$Ie"p='C+:!WN\4R-(ID!1;?r!A Si"g1My$Ie"pl#AlݯR̀8%:BB8JQd"p޶CD~Auc| ER#Iœq;#Ys$<28A3;CR^!p0#Y^8L$I)y⚕̮,J_8L1 q6+pz7$T>+4MY~Flݯ Ln?fw.3H$LQ u,p6K41,V Q$龃G/u.pa;}B8;R$K&C ˊ! rZG89$I/Sk([mwU2p7H83#F$ie"p.nyYԀ8i!s'T,Q$R}k`@,ڥ?s%J$28p$yYl/ϐ8_m|1Y$I2LΕޟth_8,P'4S^-NYe"p /)G\ ##-m(Z3 7Owwr(^'Iyяɾ|WlF_q28}橨J1٪:..nXnBNnҥUed )*me󳽄_|FO}覢.c㒊z h[']iCd?fQ1p%z5h4]lk_w 8x3l]賊]2f:ڜFyQmqp<:'84L!pc t5p8=.*̐8i6?0/Y|`k`ssj!(Yfя.uLtKʂi7f~ت68 j{0[Hdmd VKaҌ4$I 8Lt.>%Uvs%x:!CYJsUZ϶{)V C6L_4ݘks\:REny'B"AM'ߥR=2d7H%Y!dJ/tԞ^ry ?zIcK>J۷Yoo%&D#> ׇgH?Ѣ^x`o?]dQUM`J%b;*/Pm T*,a<~6>S >Xkldꁃq?5F*BߺODsb,РX& ]➳_{nb*mԘ\QN['GKqmצE,Go}T*sAwP܊XB>a -^QYAFU-lm5PoM[ JY0y_F]eNjKȤSTFmRfTy\Uqreavj\R_tsl[ʹ;[='[ \CZێZW1~G(W p4{^Bzܖ߾h۷tafC*2XaAsbE *Z:-VZ*Я1o˫fw8._$69-͚o7>1Pf u:eaTEym5RlTfʞ|T mC=|7&Zhrp/GddAqOVֈ L T!ʪۤxN.Pi* ibMJ  py0GL94Y7˽cBV(m]eXJԺWNVuJ2}CO>KuBzhfC3BK:kʛh)j*NwCo W8ѐ6_ H` {qT8,UNd~w*g %S]UtVxfdkb4mH]w8@s"y Yrq*]߇,K:*u&wY1M"j(ReΎor~l 9OҩvvP3SpTeGiG,qvٖ&\Rw&O3[oAFZoٮt^>LqY?8!p!pObGApY H\T_ƌd:<+rt"o=dOM6QqڕS,U"hhG8 89 y/Xe nu , l~嘪WJHܑdFiv5}n&C}s8%Ϝ2F1ݑYWNfLQg _Z[݇K"@2%bps# -Ϻvc28:̌=8ؙI't3H}͂4>. q6 qᎢ)OGGhaHĕ8[Um`5t-_:b W%NPGIcz2p^Do1#jSPUt={i~{,=hF}+4a+2N X]W=}f&)U:koR]At5&c"%TZ攉ql qC]ec!JG$Zj;yfktjpZiep2>̊N6WEh[|8ӀBWl3w"qB6+Gs(bլ18+ڃS^WCܢƬ'sg#lp,w:uwnfiCK6 cTF [~) \Z^ pr~Hti/o89zPf;܎%GLSjPxo7.!VDpnw1Yp&3~.rց vhW1.pF Jx kauvLi|;;-Ȅ*Sܕb$*jpȇ 8@``pX8NEXkL.nFlއ 3xNu.\ Y8m8=G+xM@[sd.F?Gs j+?ݝXJ2JZ8EU q05Xm-p 8w,Ci8zىCkb('-g,!B̋聃Hq} ʀ ւ r ֒~p qSt4p t n\և5]7A:HP7 ް?@8TW3)W 3a_喊mqpО#>pNKh܅D 8Yn4cYok#4ƂDs*2( Kg*&KsFgA,!nU9~v]9zS`k,{.dJ:rW5*br,w″VOō#{ 3Xp$8Cڵ: 89q>Lu1a0KK"C[u.xͧO"6D5AM_uTwKohAb{{P+ cvE6 ǵبH^֐(oBrzܧ9s^s" d(/r7L99<ROƇhm^ߒ~Q:Vn 7#zQcN*2 _)&VkbN;D!X4֐I(ufw5w4z*W e{I\TzKy+|rriui:n 'RԺoe5Sًh=CTXGw\$-[;$v">UBNcՃwb88zM#P\ /cFIR܎S9[QwK$613'Cgh̓&W$iMl[L wMLos>]i# ]#;ֻ=,,jV p@àPbeky6;@e.ҟ{y!f~bdׄ&bYIPv YLCX# ,pSŪEApR "pZ-;=qiU/8^l3b o299(w(yF+o!s#\e-0&X-nq} ې5#,oQ]_rC )&mA \!\"bL3gxYӡkVr;mlD` o(d1+C8mJ\py#NϞٖ֩)l%q2Dж $: 8zѪfNYMD\_MgtE:Ίy5 ;tGypIK }|f= ڈ,Zm$O?S-7DSwqiOIȅ/{W+:.{<='vgˇ\MFܸe2~(*|=>{'Qk*&Ƿr:kլQaupĥYh9M2p[46_~RKA8?bj9's sh*ϛWSz\1.q}StN_}_R&S 2+178kt17~TQi9ns*)ygP~멗cӌR [=!{T=(Nw[''+8PBG<:y!L98Zĕ[M>)byM8yOH}w8`]#GMa8l8O ORg"pHԆ>HIDckC1 pfV/8᫞Y24a^yJ,Z%7Sǃ1Ic*pDu%~Ix-M/\fN  838IU T\n\ pf[|dm|Ѹ Ͳ7Rvq9;x/~lb v=,%|=vop>p4WutuShWhfyᛰU+gyLIXuPU ap']⎳R}U 9$Qn'hӱW:{pg4;Iݧ3\llJU TBCJm)p.u:54C# z俙Uǧ6H{zpΪTtXVT_v\ݧ…#*>{x9{yTaZ==ZpPsaRuw:ݏ\k&}c*k0|^s ~CWcF6]E":|ϠH"2835.JyN 8H4K{&U=mcN*@1r(΢Udy!6ȇsښMX"b.>e8!ʌИ&4֓Fi uZ+f+xKg;֙?gt)cMw]Q<9Aφ+g)p%,^0Nż`{MU&Pol&`Gu9Lİommo+jT-/R +:~URVTyUsw*YVmdc2WY:p+\Tznΐ5  %};UYF_)3;>׏DӛSZCEʴXZ6%YRy$XUף%I~4Z:*_#l{28B7[7+oV6ǔN@iߪg;ʪrnz]Y6*YQV>7D M&g%{qā #ޛ<r0lR9А{VK7sƳX+2Hú}yS,P-ut;5~>aE5~|3=t@=Ҙeb^"e5yyhZ#p>8X@v:B)xaeZS xsg2\[O,c(d~;AQfUɖ~O+4WO7Ltop3Au ff110Ncy E>a } Cmjq(Zyю @n9efpMt4##C'5{TynȾ#[!YpǪE3p"p΋V[J1UG ǦoMT$s=%ǎ,[EZ.5.i,578 2N1[L ^Wn p2]'5Ò[ɝ:"/c_8+eOd=Z$DDT9dgYINo*rY5 y= )aȇ?t֋eB̨j 䁳XPy io3`eBgGi !,nCOM'omحWry'7sv\G,Kn&&.i[b88JWִ&V`sp|_q~c4c 8 E)RA Z,|f Xj3.*#|ryd=ϴ끃㬚R밃Y/-pfSd"pEv$ݩ)B۶ײ4hjqYB\NSX~ fZPPpd,B3$xøoIy녜M2W-.;|!p` 3|f>!pV臟uCoXN2, x1TX"&GvyFM LD& 8exspy &p #qeX-ν. xKB%$QK" 3fNoxn }l;-W6>{1d\3qCLXaL%qY*O* pַP +4 7p|&0o s9q>he,MFMt 1\nxz?QPa+I :L,^]b'jbzjY$p̣ő&w"2p lM]nN$6ԉp^ȋ  V+=\QZذ09\gw^^mn񁳖U퐩_LNX ,wֈf^b*%sQp"2V9u8.TNl܊ND[<%&8h&:8Q9W[01|ʏmcps ZH~Sà656 k9zK s7.ǭS8l {v-g~ =Żhm>d$z3G'RP:DLӮI0Wϓ` c.eoz:pT,tQTE}߸@0+t E1&js`D܁vuun[T7X ְ#p-^BrY 7-&Dh|bHlgHCXSԦ18Q^Y&dz d&%΀)]vP:N⨧kue3Vϕ>F:;Ink Ofs9`ӔSP+ E&0>˞G24t!yceM5FeI&6(Bۖ,hY(gH}: ĩ' <+Kugw2f[?p(tDATK#q3y3Wwɪ*fΆt-[7G<4OH' CWboaowʟ[.,f6?TьlY1Eg}zX#_;N7u$pNl_hSˑmBZgT]6]ZMIcS[3`ٱ5)9՗Byp- >m`D)p}K8?k_?N֟bqv67ռcéwpl"r#rsN5Wa [%*28ѿ爭NPnʥL.W_Y޳T'̲Q6]{w $j28u]*|̆ Ab,V4936(~f('xJI1e pٳwgII&b^O VkҊ]N_vgw.gҙCtleN1p&B.m_oW{[bIJG28ϋrjodrSV|lI4r$28HYmm 9 Vefz+'K˔T\j\ T UN%U%K[V) ]vZYiږ.=}Rӗ6eVFS) kzk\\NzVWuOoz 83tIDIt v i6ϰx BYauDKft!dТ0,UENL14AW˒n#W%wIhUǒ&Ʀ\U7RX⽘(!["s"FӝN׀G,QJf[u1zVpi Lpһ$Ҽ<ÑQWKI21EP 4;Dv!`4 އ%%7tSo,93iu^~fIIwJp^ x즉.E~ʘՄg?n hĨsdRG 8NHd1 #X.ccWCձ䝕\ z҃$;8_dJf] vfk[mۯ0L6ή2?*t[%90:h;bUX2:wF䣍[t 8N)>n@u79|A۳_>:CKE݈& w$')E fO$qIIwJp*8&$Iɕt'Ԉ$I$;8R$$;8\jDI$^pҝR6bkJd.IIwJpb2TM(IKNS s ƦJ$I%')S%J$񒀓P$4$I)tǵdH$$;%8̵Xԓtg5:Q$t3N$I%')ɝ/ub$IVpҝ -$I/ 8N6PN$IJNS$$I)tdxT$IZIIwJ.pHINSrsV$I%')%IxIIwJ.p*e%$;%8j&>;ÀXZ(?`҆hѣ'u$뵿T?Iu?ćmCSzB 8NftiM,0դ %-swfؙVG&[ 4bT-7O#9 Φ?(pl5?w2!H%8SxWFѥʖɿ|*q]2:OL28ߤ@ 8(>Ž@5ifd͓ϥ+ywgl5!u=sks2PJLԷH`/Yci>5y@pq.BoJr0E_Ipf 8°EN 4.aPJ<:VNh5{N'I ZpL3*̀sF'Ύ)PAW*u~\x؆!{hԸHsq@u'.bT4'uB?7dWnSlfKuwT}ވ;"vRXk\1۹ʙiݧQTȉCrۄ3"=㠆JW}W`QW/zM~ƒ96ݞcglE||fe(Y{ĺpݾU`Ju.FlTX@guCJ6AÅ^}1Ϫ6S:"'}xe`F/^/q/8>awz]zO(=gLh5SUz@Cr+W6߻Uwvc1>W59 V+ya㟁 9Viբ"9ٍGu9J{ԵI1䟺ۿ++LE5=UL^ڞ~,bѓ"Pef!/XvUn'gڐGHV(m]p Y^e=,/_G.Ug/)H{h&Yt^; ;͎Ts<<3"ͤQEqSssՎ]PBs!y\U? Yڶo6.B>}l4m}'DJ(@y_%~7&4)J6|xû7 -ov eyRo $N El|#dpuV*{DET(=Ku:Yf64j,4]At`鈝c8GܤY@QyPoi<٫yߵQlq?R8 8kPM d;\M(2':[T5mNQ%'ǰDS Z-( {:druyڔ݀(1 Hp}"JnjtvNn ϗ2ˎqL8R(ˎ9~~|LUklAՓ[OzY80Po`ۑG p rK||K3.k,7J|:IXM^e'G?OEZt>n&(;ӆ% I~?aT $ܡ;YYeǒ[UUÍԥJ"Adh28_I6x$Tbk:}иT+ 8)P:Z؞D>~Qu[ %vyqp[8vݫGT<}|4#p8>;ЌK.CO6 8,Y7 XNn`Yh`v , I<'t.+;̷)̦+Q S5"^h%K H8:D<B[w>V p2Ý8P} 8@+>ixtpB8$1&8ՁBi,!H d4e $+!2l}ђm98d\I?l?OIIpIx%WYU 7N5eF=gf=P飨ͮJ?l 6FhˑpܻG!phK?L*Kd za籍bG'Xx,5OSfcX zs Ja"eip8[Kp#mđ(=tIxQt$`=ej*V!* !pVr9rtaўx /s9[2T1Ȉ n>@9֏. S,D烽v-?aM8+La!pb#Ull)F/x,$G˂P9Q (N1As\Er%g<8qv!aU t.̲Y SV ehKٛ{eӫ;ۉ8&p@Dyy5<ս< f R2i7;B#\>  @IN:u Vv:Y5 f$ tTg@| F$~LR0}T$tteT.'Ilz$ jl'wdےUK7$\6*VUQWFF1Z0x'~%W]c4~@bC :EmQٮx4 虡ؼ[fOy$^9T7 0L'9hUaJC^T&e1IxG-vr)4B5VPCHiW7$i+X\h%$q꿲L-3R"s$)^MKvGx+o.B!u,[B!4Td!I$R6~Gh-$r'F21_˿<_m/}G`k7`#V hMTDSꑛ`}sp1IIpkQRm%9_^ q?V7'{FVwqAjWYΚ^ܹ8-rvPTCDɏtyd_/f)N>YmS;w~` YWgW nH!42Л$)LtU(r3K,TRaIԝ籞%xvEq2!L)yb*gujYKdƹz>1{+A0Zx2]W\u| ;rnݺу du=y0ZYx=U+B_E}5h0L M,X7<77 h0їk];gћHuϛP F&_9nqp軔GI¹cvxRC7LU1/vjnZ?>d0:H|!/IN×ݏ'O34HŏN2:$oI9ECwf| =?xj.݄dO_4rQSwQҍuݎ Ac:pZ]5Sjٸ8TFIQ0%eimߑ$HJR8co,'y ]-VFIQk"%EGG0Jɾ2, }|zM3`XT}KeCeH/UM<2rdDӬh)šRY>Mgc'HOǁlڕ o"<<}^re`1}= 6i77`w sxg p )eiv dˎWx;IM4풀è6)V^ptӮ1?pN+ܤoM9T_(y{.^݊rwU|KN:U[yɡLJpxi$'"Qgf&J_ȤhF9xO8+PT>99]T"rxi7+w)<yl][kf}ྲS*/0[wIm5J剤Ftӯ2f]TN5ےA{ל ӹWts喛sLqc aqSkYT0S?+1τn__CFμ"uRnՅnVTK,㞇fБ&3lS*rBN cblJ?6 JN:EsyLMZCy{r,~٣\.o\v(S`OMr@E31W$iu~OZDEmE̮S=?xtL;ҩ V"BZr/Kr)'*p\= AQDMmu3H{`aJ375&{}}ߝf:ǣ:߭j:Gl:ʢr~Z([vW xvYn8}]\p0yV#pԾI&UlBɷ܀Y$&>mjNQ"ݪg)TaH$澆K,K#F:%:b^02{!t }) iQ4y ArA3&諜!pf8$3AtPsÿ]cz2܆hύ*ф^q#!vdk |emyQye/tgMGmsf2\)b4"!5d) AbHpҡ,XsqƂ7=p!ݗ88j/p3[}|qJ t _&AEq1~CtHİp#U^f%Mpҡ[lZyCqd|߶ skcwV) AsK g-x?>E3^VMcA[heWQ1{B$/P53+->nn.|eBd\ aޥ:N\LrhSzRZt?[Rx/)~Lz3CȒ)Ê ο](50Ͳ+Qm$'8铼ti ܒ-p"`nn&܁N;n9.1y-V{?dUSuE@Cp~Z_ A2?r^9Ge6ϒs~9I(]3Z r'ClDCQ\bIs^V*sMg"8ٌhs#iXr+L*Dx,879RIPB*af+spH^ly=ȇw-Ueo:e N^祲ߣ//3ר&ZI| UjJ \hMÕD'Xm]>!sǑCM~S@ M+76}ٖ尋.Z- 4}GrJpKDq8ڟg/ Ac0IXShʊ!ZDEmhϡ&rZgp}qIp4jU]xSxIIp~*&F HƣXUy=>n)97k=ȾPX;OS]D3є|Oمۧ\ .I~#$?32}kcR8 b)GKcO{H{؎9òn,Cl#bk.%ʹԺ_T;i h^W;rAhP ZYҊT`вO䠫xFUDpmG U(;ڵ9y,AXvUi^pً_^ WYGpin[ߚ}-'N\K/K(`aK#Zހ7@!nXxꊑIwD7ν;<(S㢍*&IX;n[Ox=Kqګ5Y}Æ6'_GKN)be60K Iv,'Υ1>,8dp@"gB\r}%O#IIr8،;>iK- 8YNOZ))INUI,IKNU9†K Ir 8`s$IVpNSWC$I$d9YUGdI$^pϋ$I,'kI0Ir8d! 8YN'g GH$$d9Y;JI$ 8Y@/SuW,]`-jX JKN;V8=C)I/ 8VW})aI% 8R/6.l 6F9|JKNŕdhC­M)I$'IW{*k1pc~%I$d*]+uPմ8kIyYPU8-sIxI,R/j n*Z }0ǶYm6ZLtc5Oф[m74c̡䵑'•ޫ̈́RȚMQAnnT9-PxUҨCS^Z}(ޗzd}MfߢG%'3(yuDjm;8vs,N]$#GMj0>6![ 8+ِM9CgB(g.6L]0i8<* 8ίde! j;+*ΥJĚ\(p <֏잹ɮpjka`6IERŠfB]GZ%u do>1ũ-1֚ll9Z F[146>]'Gǩ$Wn6f4#j)pf?dP0]R➳߰>N†}=Xk8zI f;1f<z9wY(p;{|+ M}_f^*u. M#߃uJ%WqC1CG WriN瑏4G&3ݠTN:b6/Ǯ0[gR}zߛң뺜o xK[GwnҘ<^} m2r8aخC~BU tP*ó1]'z =J*riZܷFyͦ޷$ǹ&mB]6}igEF$U;=U( `[ŒU ke\Gz-£y,X\%^BD@"!Cj˹lϩu=ݛiͱ10*q`~[y6J&`h4͠ՙ9,lbzX;|<*(Fy kA% gߋ3*͘O jtUN6C1̈Кˋ)}#CXTJӀ?͉c 7<>][CV|l! 8ά+uFb[[ lMV&%d>6, A\qO0$F{5e 8A`)dˍm=uY q0 pb7|0wT6? ?Ȏ34a-e&ԓq)ӽ?)pv7ztU~ p$]$%nn5YO=p?N؇drXK 2E~cQ#X)5c.A1ηkar(R"gB>"pXχ:qOAm՝~ wÌ6?;3@87 pFK$DcA"?솶gsDgfOXl5'rpBz=WA[.aM+?FR ^H 8Zrf9a!p>"7_M5 |׼dFP|ШO0TNB<@+ qz6=O1?6'u3 e(,_Llp9 p n@#Fa[4rxh6C4AJ0k1q'1,0wMF* 5Dցh֔p8eY8/%pfvIĸn鵖G ,&(K3 \•c6d_`= xc7%u#|cj SYsIW$”N<?Lp1l`G.z!pjp[|Eٗ8MFe6,K+9`'xcBxI$hJ ]5 T#*ϩ _mpZ+rTy! 32^UhJ8q<+k8k7̮%ZsI}V qAq`)&l(u-IZh$מy"~g{Ѹ"XM(<'䝯1a%OlhXʯ8?!hP2B 3`'8=LE\s.9`)2N9gM0 R1hNU$8UWo޶rˀ)1!+PURxZS+=TDU@A{@4R6ɉdW OIrZ(&0A!uiẦM0n<,$W$@Nhx*Eә寑-U,s!'דK`wݙvu@QÞx4aui5Z8_&J{]oAcc ӵň=D ƄUaJ` 9NШO ɳJM,V !ϲ꜅oha}#0}W04wWxA${y$J)JK^(̀3\QX<Xue)G|Ĵ:@N}A]p+X E#(f݄uuy}rI`ϲ={0sҗv+Naa ͵cI@]!ᐝ3șN؋)[ۡD=@h p9Λ=YغO͈lر Gi* aͦx vA7?".^NΈx oN]]PtV*u*%='a %0<((ߵAo0}Տ3-AdZ>(UF^O׏gpϡF+?T{Ƀz.~g^hǞyB7a!;vϽ(%pmNIbS*jwu ep^ʾHg>{0b3uE0h,]q/400PӵSnl"ǫS$um%B}Tï] | JCN\&D_}Xa>ht|չ㩼ǎycoYr 1RO@-e%· hlpl(XQ%k8[tbbv,vLrT k7N1+&ܪsvxbzG(a\ҖY7!8jMqΛrye_m K5Kf$ZzZ 86ӣ ޙH,N@#-e:VcRK*O^~Ǝ>?jzp|"tD7$#nF!V:#ZIפ%S4O{6ӓ֝6i?q.݈z'~̡Ka5sD)suFi+XixV*!nr$I8qHwc~= c0M:r8q"I%N+2k|maplM(y9K{B%IIa3FH-ŀ7>$y[Z}$ɦG׺B?$@ eV7E$ɱh}=ZkAcCz8[\}$ɦCm&Q?kxV8l2)o_$JuϞ#&c?Q|'7dRY7($1SM euUֶ`ȫYy:h0_m\ԘN_c$IZ"tЭDƢ񟛏tzo>; >/l4,pJMB$Y-p"4IGA-]Yu%NӶ|&כ:5wp^:(%I8-j~ }j8*- m@JuS̢fOXb$IR",ەGAguc#)sf=kԱ4s_-I%%-?FE"|&f?'&NA;kTpKUMI%pH8α8B҂(L0OlqS"YB ;_I-m2\gQ$CCf &;~*p^3Zue!r{f˨g?XL$>՝;M~?U\*JCN[DH|mkS1Ɇ\KH R9eڨ|hx4$7<vFn8=qߒ2L"Yݱ?ӗCȕ҆ ?\gvL Q'٧ӓ$rSt*aWo~Yf/l} §DfcO8`$b3nPz[!B 5޲QadS\k%IX"Dv"+\JwגU4 Nu  `ԁE&)$i8otIl@lҜ̮s`RNpyۧ(IgJ/{v@qUiwg?lT 9Gҕ̫OOARH8W!EU$I0@zF}-X*҅~P3e.CR2l4%ILb4Fa pȃBx¬5aJj앬$I(%pZDU7V<,l@n\;idRNpcWH(sHo@`xu! F9 iU*G/]IKU~YzPaP㋋VQ+CG AZٴPpy^/T/]IK ͿʽK+nբdnZ D} JIc3r؎ Q`kKjnҠgEG6J74p0:~탷W+t>I"ǁ 6xHqc0ߜi?l5p|3ꃰ^7Ş)j~iZlRo 뤑8ݖ-Jngy7=8<b)ֹ>g=9GET~֗:%E7؞i;OdE H Y7}Lx` n%;nw`FC?]e8*&iq7Ԩ] W ! Aڟp|EwaU`%pߛPP`r܇MГۍp/01д+ n)pBsD9n>Z򬄐8)RYO$Vsf)݀E;N`syv-ΐF&s:ZX= ]Bਖ1qQ_ZtsOed2t{hIXq9p:եU yRIvTgY/tZC)fe;웖iLَ8[BFBc~-d8uYNx6^>daqZ >Y $jhp,M\quAQc4Jp]LNGXAp_91i6sY# u:iC\ctz\)w e`ם]{NM]g.-O/_v+7g j̽{)s3lT*9YfR;7WVJ)7rr_χu0m_}Py B((B ו3k u&,ncǮҗ°'0*AA|0*J;( s~ImԚ7K'Ixpp@60 O6B(5=jZ XUj\>wk'+*=Oj_&DU؆?* /;' Hwӷs.*6 9 [:4U8EG1xnvl1qNǐ&+*j wyl1-*7b˶Iwi蕝yǑEQnh-рuT vLLm_ؔd!_0TеoP[YH|~&sƦ'^-p'1P5d#@5z==:mRme}E!(D? ?kЪʋtCqؕ3 /[7\;ȃ|܂ IW@t 26X\ 8;K7 T![f14~'WKv d*NYQJ,3 ÍAp0!+fYO 5vO$p_W N[D[—tiKkp0菛t~(pYyZ |i@"='ޭ+覲+b6>SXêPb~g#-7+NC)rfs3i@NAu<{*C`=Dkp`C~8l`" Nא?%dZihKWlL@Q܅ZP@t!֑n+y=ӷel>ޚ<ɏ\3cصŀ !w/_MXS;o,rA^sC:Ww8rY"wpq;X(SFRFKC0b'nïNn"t208OT``=[Yn`FGH!i= 8п4o ST{GWYL5BK3{_.GO ?j&"i[MZ2^2KFځC_@MeĨcL0 r銗;vuM{KQvMrpm؂~F'N6_(VA_)9mz6LŢtjx2;81E7m95ӝ~ HBoaˠ8Fg?jH#G&.TZ{-=4oo7A&ÂWM%mfuc9gN!jQJWFsڣtzXHDd =ߡY$h 8y$ehV xz9p#fx>_p-pЃZ/(iscA_ȗا:[n:~<ob10 ΏB'7npVC;0QV|Agd *CO# (^NJC?l p0`~{EuMd9B> )nqOC> _BƨRN/tTvڶiӺU҂Ս$a5IydeJ |Nھ 46٠!FGٲ?3lMuX#eZsVV"#Q#/hܖ!l[Ϫp9ڠUtlY7$Z ah/ yt^huP=+]}e9jy݄kOCΗ^+zdb2Mg,g854Mg#f#=;|)ŀ/pP*hI2yܕz|~6 zr0F0p&T^7%61C|䛣7R4!FuB=SD60U.EG7޺9ǝ6u7:-uttޚ|/k>%NO=˗^~7Ŋ"U"KϴmrU@I! *H[UmdEz"fь%+~r[qHYqRT{ɸwU,DŽG*r7gcŲFf3NT~V4ΟNa cx#GmD29 FmZF30,9u-;܇Nֳg?nuN=33jB}t2~+3>-<&TԵɎp[p~kAf8d.*yz~IUKEN~tfm?Mc`8v?i>끠A =d 7 pܡ>?R.45FIŅ/DO [ɦRoS(5Ed0p+OJH-n mc`8ΕANF|p86[T<,.4ѦqJp~:Ew\; 8)p@^f. ۷ p 5TZ!/'=gt|K (m䃲)|>Q$n8wbDQpR1|<^T^{' s}A1 q$%*&я}Fc!y0}ݞJnm+ԡ],a1]Q)Mgrs(pL}.ۺOY\.ǁi_,9|}^3i0Ni~:j{8O>=UJ]úa-#W1ܘ7d'|=MCFTTn%ɻߕf؞s/3עNz߈o mCq?Z֠Ju!4KK1a]i p_FZQQpz) r6^n9ʖK #a)n yU fT6\&p~ˌu" !7+/ʏ890/2?JfCe)/GDN\Q.*5=v!1{q_' W Z3ƽ`/ds-=I=8R0F95wcT5N|l 4֊mׄ}CԄt #?/Y%ٚ**:cڶ$.(3mNu"]TC3lL>Mp2 V2lfreG7Zg8_]/b-D9fxM06m){g v xKFۤ 2QKRk-p(ķ|c IYK-w9YOu\uGlO}`8[!s'z =-%}&U'`>pׯ48 gC/d~47YxB֒Cȫn/ 0 ǐ~lfc?T/٥)le 8X$0N@(}Ss#99DkOh+rvkRa^Lw@M3?rsg8H+ig7DUqD?Ή̀ch8>n>O|a>Meks>ʋ 1h=u q'ss jZe<Оtp>fWP-6(== C\ بs0ʚdCop-y-@8h=h8zmr8ac`8i3J#i3';O޽J e 8lyײf@pV8Ճ1}'pU)GG{'Ga]}<˞ 09Nm.hi\hpNA1v 6&3 `2_Z3vv'2cRh(7v!p 1Oۦpbs&0`Z^p}M8s@$8q2|}KpVr ~` XPyx|-Ee;]sj>K3D S}@0eΰIg5ruSǠRu>ywpQqQ_G8 <p}1Elиg=_#Aߧ.cְgo*FǻniwԤ1(N2j"mUD-]obz<0b}fy/x˞Zg$U NE3/X'^g_no]()pN[>vNB!vtϧg2l"3 f%&|wT݊1D;ei>5u# pr=1P%fƭpAٸTC}t⃘Nxy'0 ]uHWiM:nwa?reSZ/_?{Ic>G]L;ni_ի:7ol6eqA[/%o?lkw8Cp"3ĵcdγВSpf->Vr Mp|Զq[!83$p69̆ 3L"˼!Ef( l8WII"(ap,%cs/o T/ɵ3w~|dt>LJ+mX")/Pđ:8LSZCpă& 8W)~YСv v㷋CpeT&$Hr^Y2/+rnCmܮ!8Lp$9R'zd&4^ğ|۱'p 3bCp2-GJ _pL6u[esrDh8Π.f4L 8Wb|jGȅֲ||nrp 풄-Cp$Hr^!'-M_#c`8VO63 a#y%:Z}Ƀ C^y̲lݴ@pp lbA^3jI+ppkM `Slub[]C J>> ɦp$9D!OCƭK׽}XC@:'B!8ep^$Hr^CvfQ|/ }[z@yKPK~cJipN׌ΌIΫ! {~:s3`p #2-X!'=igϔ*u%}3tI+pbJkF#>̡?goUBt&6 b>%GJa&Ix[9t"~݁íK˾iA!82:3p$9Di]?g$wݾY/$GJF"Fcg"=:C1cehI+p:v{>{/_z:vSCx JuK+e>,0I'XBs#0\i|g~!kիgD#!8Lp$9Dy{~JC%79{Z,0'f,y>_>I$8ŠDm p p?dL5I$8r?PZFĉx-|A2~I+1pvia9%(M9Z|Yr!8Lp$9DT^@#rpFxP}ܜe|I+p"wǤ63!3I+>(u#ADSP}v8Yp$9Lgp^kjR$GJj߮]6[jYQ88H q3c"I+=pslT.ݯw$pfA!K֘#9Y1I+=p&/XEؾj*Ϯw(p88lȌ$GJd٘G ؙ?o߾{kV69GTPνN:.a. >oqH) 8W"\[۽E ?X7ldWuϨ\I+pLZHE+^D%K*]G!1{QnEgPK$i,o$PCT{ Mh82W1B+ 8WC'OT;8dq:C{3})WPIg{hHppP`@gEWѴgcgZ%HT$Hr^YP'Ʈ$CgSh>C%GJ?S/nЯ{! 'a69:ԝns 8W"lӭ`d_ьmc_"Hc@p$9DQ11\8%!HxҵTp$9LG]C.G1c}gpd!qpX rXK$8~]v_?+ ea5&_w8Cz 8A^'AZ# 8W"/La GދRaIn"$N$TANǤi$Hr^Z~)')v=5B0u 91JI'tPBA@0mr{W蓌yV@HH1Z9OlUwILkhVשr-бI(OM+I+pH2E rӡ-Hk{'FIgWNڤc@!w q*1~1K$8A6EN6]qʞ)Gp$9D \ \&h% g;`#NA:Nf Ig/ VM+g r↥H$8[v΍Ë"'=\8ڋvUMyyF$p/)H$8̏۱a@_hOw4a vI6#y%ܺ-%F%y {#XU@ rn( 8W"L=-# tyݽ'Fqq v|I+pmcƬDUbp%&. 8|_"4C*7y@t}etan&{ G+N|lc̀}o -8Vۍ/r 84&}<K)OlhnGzV]ӮHΚlt tlc1)8"%lypr b5)rckiceBp/]p> ?-1l=ya).9`@8d t+_Tv oPݎzuUW^Zv\VuӪܾQp.KB%ͬ3x~4w:>#N6u-N蒊S;F 돈k 8.8)dK n\r]Cz=.ì ﵻ}/]vҏWz+󱇊Ws +Nkݽo+|#VEOE.Mm$X _Pf!GovݷZj{p_:]7nۦ"v q{2-^48uũL?ι8eץxFCp/ 1~U oD/Yק\#jO/5+ruOW ܃S:Uυwm+kG$`I9.u>UJNjRv6ǰG š?. Z]3UmeQ,.-8z#2V u;q:p}!%8'vt{J Εd dsP7(qEq:m|iy4inC\9HG\RBqNC跊1^U 4IS_V=}#r=8Bl_brzGOiwn^B-:c|iHJInEDxSGdN-!&0&Ap/MpzˑД|t#91Ap872r'v(2wK1[p8~) 838Hnx5cU*9dYq2K2UHVvm9?dg`r&ѷK!|m.j#9#ob<!868:.u I_ω~g ΢֭_ц 7Nn/]|JzիY;d&[ݗHAS _~-R56ϐǢ$]:rW8;L[tH\N(r%hbZ(cгt: M6ȋyq)=b#hsF1k8"3ZJv22ZR, q@pg2=g QE RRF3W(FyTjpr}B?RL1t-iHyۀhr;?'ez՟x-Cf○ô?:NmB*S)8)3Si2l9iI!?~Z]o%z_zl]p"JVoB!ʫDT_NoBpG{ȑ#wߕ)8խ)Vن96M'%'pΜ9CP5vhƪ˟3rbY)/ [Sw!VS!"SwCpJc '6)z;(S֠]G.Do, Vg(y-}228R38H,Sj:dGSunpء kD[m@L&9^2M٧\Q Luo.'NCl(ERLA]\ B8ɬN?csiemr0&O<'3bZ飼 5蘼T NagGri2LyC)8JtKUz9C)AY1"{ [wL z8^4m miN=n9qoX:!8I>Ʌ|p᪁vS'-ˤsOy7h3oerZ]<%XԢ[^wwRjIJ4o5>ʷd5VcxMYVnV ^@p]1T| 8eqO<H*>.:>H!8E [uμ9@p<EzATcz@pʐݖ%e0|!8cyX| 8!8cyX| 8!8cyX| 8!8cyX| 8`w;T X,U6%Y endstream endobj 24 0 obj 121368 endobj 26 0 obj <> stream xcte]5vvRm;UTc۶m۶mUl[{y=;ߟvk{9}g_"'L/llkqgf`ț[:;*Zr+Mp*NV-\ hnk_@1*fagS `abD[!߷*U%ujZZ0sss Mmohekg q [YL@8 s+s;;[(d(3?v8r$w#)_0q̜xMB&@ & 6@'ƿ6ƢtO66bbnccg;FUs{g w`gbafe@7#36Vq W`b`67y:N@o7?Wpcs#'!&3pr0wh31Uw mgغ<9,\fq'ۿu/ a`=27-?F`t_55m26;_O0mϩp?:pT!(௢6djeX[tu<7:i'ۘZFsG s7s'#6@+s[G zf&/bfnditt{€6s[Fq#[csS_8;lWZt9 Yi~hdT{2^{hG؂}Wi=,, 4p A//XM}O^+|1Kn@emEIJ bJt?cjxcECCALo ƂAaۇSz3TheeU:-Sȝ~*$bE0X}Y<3gWt?/} 񛷷̜p^E 6:GR¾jJ>sIs7>~m0}R'Hw֜v)<+'[e&8#sYhb7A<}wh$=W4cU\-v/e.e {殴?n_օr' GmJxI74Zҍ0rCڕ}́}EbnzRTi3)M:/9媝_TݲbD di#?A4tPUٯ%]7_In-rb)~ɲEYb`*Ko[J0Amo"-LG*uU>-C6ޣSKj0֡svi .lI AS ltQ#'PSfQ9!!_ RML#ޭMNz"j 4)~E5ֽ>$Q/<ҫҺKH4, }Kq'%F_5ѷa#8+rK 3[>A ]P!tQ>QGrǴqX1Ey[A»T,iR%^̱PerĿ]Iwhnw*cțG'T̓rEӳ 5-v39Sgב{0,4^C`^/h5+B ^~],@8Æ=HoX_m.GpDͬi~ nje}!1v. Fkd v׺( WD/\ݘ$:ǹTa:vYuk46mý,oUv0O+hǙ<+ÀK%¥Yzд.}=;q~ů0:G3ાS\qOxk ;'n&dW<~g]:$8Ⱥb_ S8` \=ON܀aD~,$AkLiȣ^,nQcN]V;I]WmڼhoUJ %HfR&h +A-CE-zxPA0E[Dl<-ܓ49 ё"fkoTo9, 0g{cVLY TziRʟZ\)ׂ=l /U9!ʇ s!;?Qdƃ#H}Mt"N@t釩'hAOPSyAg*[ے3"DHCmЫYv$f_ώ+(gpk[\[W>(Ϸu68_.cQ]iaohn"_Aw8!ybj@& MLwF>HXhe46"iXdٵ O\?%0Ml\ۓ!1ZUmZW Y!41Ъ/BXos&-lt}(W8ch; ~ m10PUy (E+`;5 .+iU{J8 bOK#A_lpk&s!"3p$i|H\B'O7+g/.[|G9 @PG?5 %~I,7\)"ވB_CV,";Rhjv g]H} oMGiT8$~bP7<}>Sf,!M(9I^4L"#h+]菍-S^4#CTa1+IW[haV$QjYsq? 003,Oi4ET&7$[F mw=(LȜ>y1tm4)LJXr@]HK^\B9hGܣjhdpjVӖw `G>XEu4["Y#CE$V2$!?5NkTwP ià b:]ĵچ }*Mٽ]!(7'HHI\#"5ᩥԒ,x˥֕qO,2u>AZRvFifq%k8QCޮG\I2AsD:WxT!SI-X|o=?S,T#ڄO ȷE2 жݴ_9Y@*xnks) jt6}ﳴCgD9%Ϫ^J*sr/a_DZ3i ²W{XݳVLNggE92 &JS n ѿv[0<)N|. lK{m7F" (_I묜YW> ~AE-ɶke&z>}N)lϣ~mlǍ( ii+8\rB3 _,J(s;K9<25/q 9g=³/vM4ZHfL؊:l s$Λ֛pXG~w~/d,S}d+uj 2\p']l07AmqYs0qD~*MjtK'&S~#' Vc ( aS!x$"}  DvQ&n 1 櫹 :!ң'q޵z8 U*6fd2~T)sy~)3HŅ\_@A)^Q ,Oge R(;;AKfL+"G_BoR/3nyXv8!!W:ˣ~J*1x v:>]&ɬPߴ W[7`#\2Sx7ke6wq/ a־#cpnלu[ޣ~\ώK\-EHcFJ_Ƚn0>9f_L5U;dH3뾀 TqͺlѸֲ q68R!W^v [U^G{ ,8P]\A^JbaCy{Kot׍i4MNT!v_{L1 *iǼR-yQ,0ٲI}U u^uZab}MF/W)laQ!&]1EAB醯KO3R-eȳ`g"d+踔Qhd;b=! &sC#bA|C{fӻm+8܉S ,(o]bDۀNvRjVo`5reޯ')m fp$%㠡-0C飹X+a3=9|G]CO11|CE#y t0{hRQE'6z3ʉ͡t-\6 Xc '^(ҫ`83`ÔRVz_b:qVIgCRRt{̬4 -) -<3-&]:>k7E ߙzznW"^|K"T*k$%q)¸%RƥMu 0ebȺj*V,'iW7+܂ވȮV- ~Aq^Η,0.Aq4օBVJY},Rq$0C-gd2&pGvhΝ*oe&6(ن K)e/V .v|eX>⩳=*-/Mc VpV +=-h/r)Ns~7W0'U&QJ7CNVk(NȬwTbx+q!%`RAVW~l֯V^JXx{ E0[L(o̽"FYfs\>R9{9~k9mdMoa.).m]ӨЪ-VV{s`[/M-=-5NB4V)O m=lE]MȽta(M2ae|$9vB#:w4Ӥ->V-(eB&eyCϼUĻ.ZZsE,52 E`=Rq!Hqhڸ÷/]]yk;frg8%oG ӵd ohſ9R*kYutVu&qg7dRl\ v; kv| 73zZ>= F}^.LDÇ_b瓞/ |)9Oe׸:!Od혅*:\g.p7y**,?#zK ⒃j Yf8\^;cptH<~a]CmLs&Ü? {9.":2ae&>A#?l!=BgճŠxԑ &Q0;F쀭 έnj2m㨻&_@eoKHLhA^4մ3F`lv4tUd\#GR7xyL"_~'gx=4\GGS@`ҼDd#YzDJq3 ;.2x#? {YܔTUKǭ*O`Rހt]AK%4znҝt1c@ikOױî"IWljk;Qa#[Ǣ7Tw#A^]ݣ/gͩ]ȎjpX7v/em. <[e:Dޚ h0 b5oneM̦5j= E$]R!5]}gGhZݮBN NG ph Hjo4yϋ|b3bu;q7=wh5]KYm>KюPekN1.Fw܉~" aZov*u F-]UF*h SS:cE }=nԱNc|mҦl!NƊ7jo >G*.C]5Q\^ S31LF_H ̢\ ֘K ,F06"WoSg D^\nR[It)Qzի L2-2k3*y[J_[L^iu-3Iz.CKB|uqhK #}VН{ FLUlM%UOBW>KKE%w'V>ב|ݗT9/TUyXMbB-\qBvMsB ZNK51 kF1_o *ZPА\n>xu0%'ɰʮ!ʕt?ZdQv/ g٩/Czf{,yS">"Ƣ!)/oJT=^Upߪ4!0۸[ѯBE˙{Ȫh **S&GU ~SCӛ.AfnЅף }Ή_ wc-xF~CO;y  r'Y83 qfx!ݞkQTe)J~%% Gu, :0n-HbguI[=꽘; $jB(NyKDz1y횦.GeU! )/֢i? ˷b+G}%\ gkϿ1fSjur,N9Z Z~`0 Z,,'9܌$z_#i*xL!tCm:&Bžȅс> 蔶#6Љ5QHru3DP>#"?#<JA(QH sF*ecQk-`Z! H~hst@sAPC%c_ Ly^'EfJ ~^EhC&z%>7M~7 1kÿyKa3JuPuhv}n*f[]A0MWl̈J},Awv(ogY$xW!ٗ}unTbxu6QC1'Ih:[apRNE1)jb,(y% _( -L@Xp# -ZaۑˉA\}0#M$E(&ћC%ـ?B- V_JpB*!YEcYx:~5ɿY}m2p⚿ qȍOc"7Wc&xi-ז-ŭSMm_(%gWlyewOr1?~0jf $ܚ  X5ZK}kG.1ci&̻ʟbB{nWlDB:Ҳ3]S/(|N+JG`~4C %,0~5A\mt>Y3Y-iuN!TRa3Ц@̑xt’zPXo/ HPm+" M1.u"w,_C2Б!NimKrfiIZSQ з[؊o[2'Jdv[RtwFg;iMh`4VԂpbyA[_E /% _qѩKEB>+"s$aG-hϠ܏Nw}ר0OR+m6W Rs{6o#9#OYʅnZ\4GȾSx-XvG[ws,HPo^o +Iw5)8т3 5 npmnSg-2ÛiVWClNe';lSqМGo;:\C\*+gؓ8.91ם32`EL)q·+|~E(ʷ2y4q;v0`㼽Klbm)0 QJ2~'7|rx"ӡ˹bC88D Ok]%4#Sku#xT?A% Hgŋm\`fGk=$4+yPڵ֮h!_#"$u*bv[[w9@S;Ր|5?IbYWr\'k'[?]bMS ' èreܓn ؘǶ#\cH(ʶX"J}M^p"Хxlesht[}ι7qީ"'c{K@y>d](||#Rzƈ 7GCg{c_gvhf>FO >jCmo@VJ/8Xiw" !cZbRϖ]ta`fjg:xNb4T\XyV2cmiس1`1͠З:~3+F{Fb|i8B[5ؤ{ 1|h1C3KM(0nN2<Yq*=d% DQ03<bFYSItɣ05, zbBEAq|魎 {&!Ch{e m-мrBld.5B eb`þ}/m12rz'Y) 9A1_@e轲P1z`-W,L1";[1s$A~|YyQ6t"gLTyt-R-~3Usj 9&W~eo+ ܆)wLhp^ۊa&|}v}`͹2@DPDŽWdky,e>\H͂@Nne/n=";%tPzKԓfJҎJGcc:MODzkzo4OJ\/ _L, ܶ֏ }ej nFyR}8`ynLc%^cN~;2t6 ]}᠁7hg5RU8h>SΧEƙE* dWE㢰Q"qa$^]QZlD$Ǚv#}ăd$4%,_A%Z<,=cѵw^[P0Əo"TbuH9%67uTuTOKw =jh]VB^AB!uiU.ܒ{bq|?bNdؕm`㙊 L3}G*O\E.48]}1[8ssTb!r/`iK \s0%wPD$<$7ȚUv]ep6-e+ RjOdh0+RP´5eKA[WC9&QH8h-:2UDI9sۭL1Rs/#VM.3^X鯲siG: Rq6HC[EM3@ݮ FwP+뽩R/oFQnYDY6tFLDƹAehG1XӞ䟰L}.3Q5 :p*}e_e(FX8D.N0 W.Jl7Rқʈca ,KKDpd-HІb3=V..on|Ӥ&:SSGBͻ'J է1s6ik'?zkiU ֐ ^9E>/\}qݿ+W}}L\H[KmxNŵ!V,6[sCvf I0 yg,Ŧn!'AaNe ,jxmLDR./4‰k>޵f,< Lÿ`sgYot꘳ެe BZT& \ku"3Jϭs m1< E5iu"Cut^UQR 2y2#$S nM')Ky8LcϚB #b|'i'm`4p6zgp]kWg,]Ow'Xy͈ AG/@5 ( 5wVrf 8qȄJ $''0cP&U L:M<?p2$ΐR'fV͵Dr" 0*xQ$噌AmU[ ЃY}ɱ]iEjP- ٞyMTS%%wKre~|Kِ{-'x).s!ng\_l4Zv{rEn2'w#IcHOw#c0"17| WD S͡HynZWKu2o +'1&88i{f>)4ǽ)y%GV7DTN )s҃!=3u͛)|:x;N'ߌF G RQf[&sM$*Ie?TY:MUZ.DI%,oе'4LF`w `&O@'Io:8In]k'J ]յ@Ԛ{,-8봍ՓW9!o3--&m]A4nt?޾Ut t[#X|g}pyiwƆ&fFM: 5|OӅ.PpF)=f,[d(߸ .=vk1W;=N&р%y{c;*ݡݺՓm_~zR(KV荔c\)~>uFm1}6(@\^ؓ?4/:ݨ?L Q^z8o#Y&#X$a5[[j !>t:819ކ7wӺ0J uMjTSORMW'Q=iDNe)XpgMVl(S@:=tܴ L"\rϕBtI}۴?dPWEY$YFީ2\M8k896Ez~J)=e<nY7')9Q5;T߳Âm +KT^!U𠘞S.i:pd< -Oh{VFQ?@h!&=)n"zb 1a`0:d%ȤG%cU!S{˶=1;:,r4+S0h!yO9~Z vD*gSc \$"BBa%F3S>zҹOvh0;:xz Fi4h15f^*KIg;/M}hIqy tB;xk&ț44|E"OLAL7w>Pۚo40 G7GyĄ%B J_ vA0Sf0ܺi%ML(@Ǽ@ewR7l!  s+~hMOamx N|Jtb:IBю $3B0`CX w8,x p*Z~&$;g9tQ0f*oBCCa^,>j254H1\c6>eЕQPQro*ǰRڏ *P+2mmg$=9ZvX~9;; I  -Z GYDWH^۷H.K(A"NL瞘ِ̈́#؏t;nLv{Wj{=g EH!Y.?zţ-m zm)8k ǒP10C0ZE0u{s19<\,Ve"Źk鍂Viq  8qiϢCmD.4=Ia%HCo'-6e̢W[bP4;6VESQ(oIZ}m0YGʗ Q8:0oz=[R])WHA i#a$@/!h|>̧XԜ1Vrtjisɠg F(b+0'0F'X_7Ko{t @JBb!sm/?/hމ5~3, ycN5}oo2_儛eP7`zZD-b8 UBw2jUkFǎyR3\ȨuSЅiT_<)$B^uÖ>li!c.q5A, &zb8u 簹6ia3lN=AbdrH2v-[7|Eu{u3F&[No0uVc|ߌpCbHq,ڄYd??eQv%0" 6NtdAbf0!QB;;gyF+h˷d/W3Np`!i)9ptp!ۖ=W\;X[miNӸ]2 x qg B{3UG(%D,sdw| 9/#AC+-_ j!VyMpnVȻ,м(–zSi*A@{%R:fht֯hd^heI`UqssޚċCj-] rh.O."2@zxͼ~~{P`Mn 0Yě.Δ|bFv5hL~"R qk~cWa]k|r =>z}_ACYЫÙ_ ؍p Y"n dU hZi"sZ2#TKPtIY0.2 5`veDJRg `BEwc[ 78&5U$0QRTU g;_]*\_5|l_ȣ;BS~~TJVTLI+p@ )9U4{ng@! 9y |KL?ij'4Ib7o":2mccR,͓'blLٍNXZ7zoi._&ҧK$1|Hw7q2JS2EҮ SwٔACE3Py5ľxXxNE UcB&_u׳{χ=mM*;=sj=40L/1/`-ܯ!ѳ`+ 1]Ceb^ٯbQ^=}uwZwвFrĈ"Ͳqv:PZ- =0]N_cs0:TZnGWie7i93F9zl9O}6$2_xǖ"3hM-uw=9$T} X ;&WR.8dPܨΔ&n_!mFۼGYy@!-d 0rCRf^T1% Yl~ZdeDR> 6b*όjo&ga$]$}3 2UcocBU7&.4:H<ŮvcKp-6ڹ2lzS4=u&)rk5nyԩM q`l5(Mtz[FMWn [U R 6t ])$hB/UU&@ٿwqr"ܹ/ٷ#JSy-EUG ";{YŘ &ffFA+[F*/81bj.uuLFQ%HU' Y褛Ru )AQv|\Dp'td)P]5_ ڮ0W8=%D0OiL,k̖ڪ>)wXD&$6OLm׼OMHӌPv+(K K=ŠՕ bһ=S265֙sbPq1&h @gn5b{P`Wop)/JY Ӛ4g=;SOO=B̂z A o!D9`<٦fR)reK?6\/3^ )zB*5=Wܻe?wƻfCArP*U-ɢ=!SA@A&pEg` YK(5zuxo)LZ[=Cx0<\?j+?C"h6/^Y[Rgz߾Ž[*h_9]Œ?hc@v7 5TLT>0ӜEro>$0Z~ireەYvN 0;_ vhIt:P) Ee:_oGŸBjQQ B֟@xnZjzcvMdh4j|Mw ;Uc2f̖\DwgX hؚ4ΓM:ɷ!syAN9D r7ݱXnr NӶQmtzD-Gs\A֮{h4Gvoñ9➲ݘ֔0DAsl a_Hq*FWv@_e;5*/Le[r>gc:[.CŰE[A)G#,yw-Y.#%R¦[}c;W"tԎHgt,fKПA|<1ȗ?AiDz)cX`-<{/+ζ\ͮP}q3MDWz巹q.$ݲ%fU>@fm[4լ##)dr*'+yv2 ¿tYs͌Yhes_0ɹɀμA\ܶ2A+~aQB'zN˖5fc1yA rU/Dk&0\ɛ> 7#P0H%]Cu'k֋SK+6BRR}:w)7ޜ (ӯ v[0}>rvdE  H \`9W_<1Kco@=lCpSK߰iSAĆv4,nyo%LXMIjh$CI/9˲;{YNPSU/{= r9TKdw ;̢-ߟ=S|{::Nn>*S .۽ZM'O)yAAgU /ˊAsMR6F(F8=F͜BkzBb6ah>,U_]7ǟӅg#gK"Pmf+z|yk d:{<?D|5=NdE,Ojvc<eе#R!13>+Ad:I&'ΦPX{cY iL\{.|pV8K AD9rgUw&IW{I\%Is(9& V}iA.ZN45X ڣZ @W}`ABS@ )9 >KěAap |Ssqy2>d}pP~^(RVK<nbHTGw`uuEʹcU*74[C\h1"sR)=h@Hϋ ZWѯk^$ ~}4L֧;D$cz4U' $6>PCz`R)"rx]Km6j M\/b}<;fnOi?:BSp&Ų/7IVՁ@(S9q=.5FF;&YJOKWnVbh4¢|3EWNq-y\v/u|7 P2&ED6X9аBcNΝ ; G9'1 ptĉ>ev/"9AJ#/&F@! N٤ s/`E04*vR> I5uͲ!}͸W\e˪ВI۽ @ AS^S>1J$2\-P/WJ.Q5H \ 83>\Qd-zu :"mM 0%mx:.eC5gu.=Gv)i­Q;A J$ U(S8 ϼqh 3߉J;4>RS6ݬBR(coԥ-夐F [5 %‹RG ~ozrEE*#uHt%{6 4HL\WHҔ`ڷzSq|~:N$ m"=^`Ԑah_耫-}JtQD|/ɞ9 x2kGԣB+ *e^1ReDGKmyp<ꛫ~d4]XK &V@⯞#,PNm+(@jM1x Q֕+E21M |\fVZ%`/>t;V#,WE|k˰D zƌ|I}OIS-'p=|!CuÔGr2گ/_^Q\ 6,"n kwFB%&t[c(Wggdo&ߦlBX @UYE-4[:}A*%B2,!*8 ~Rō9QNHO#asP_D̊_*0g>ȭbo:/. #:LeTp{rv&9Ikx ,"ÀBv+OYZtqX5&M][!_֘($fMu|{t>T.)qQ# w+EK M{&>N\0d[2}üV?L:f4< OL =j&VarX8=XH* Ɍ-4T9%Ռ(^Q2CX,pFKPˋ)aEm.~).?c|նZŀSd*ѩ-ex)ls?H ߔC9hUh텍'CP06 cCꨀA>yypNrήpp],:IzK,s+iD7'+ qWBز.r}1eGAa E'd^ T{s't2kDR)_@EW,o^K~aela J-^%\X3϶\2?  ([* wV@g(U.mP8M;eCF:aJNbd`"6='иsڶJ=k 0S+.Yb|}m\&bCi}֭R)[ il2v*~b֙i^\,\,TNFsyn|dcxL#]/񋑠{9SNL%F6&dl6>㋟*N !e%Dc,Xƅbtfr[I0a0Kw/,׫}ڧh9PrwZn0>i_"@lV=4fP8aIa;4 : F+ 86Ɓ[ 6&e5Ѵ}<cr6FU4y BӫkMxڳfwNE0ڄԮ% NR:)*x4}`8)7anѼ_.#CaE. )4"y%®Clm!{=/7I@|胆Dxț9bLvG(D;dY.zMqegv{8`f``,1œ2~D^d!جnsMɳukf V8/GÊgիpbHcy9ln=QW(/'s&_X5."|CBNV ^ӿ_T-&LaRD? [\>Caq)es݉~GnU[Hl 43/GE:Jmh^.ңgp}-L|qlM InC{.@#PLN ; YG:[U@GQ=FSi/sܡThcœ:`@E(Z~`bqhU(FPΌFIBXף3`QVXv/XDgCU^0,e_3ǒT=Et'ׯz|smnju$ |sN;C3sY\좲t /RD1x$P3OMUhG8%V9d,J I# F[x474 F*0?loЙ椄О(s'iVkz*ku$bߍD6Qh[e®SJ+Y 0 öFM]><ՙ= hFY ~FUeQ>҇2ݛ.v0 lpj{dr䩅`pRu).$k؟eϭIU6o47l7:jL=0.,]."B[|w60khnb&v!TyTueS_0֎G EIACc9`r%O /6@AMfZ`_O+=}7.q2檑*l_\waWdI\ 7 _'^QeGaUYIpo%gS10?}.Uo_HJB)IفMQgNXPjcV(SG{Rlے2nkKmvwnFtF6W $]K4$G#+EѦTwر믰bpbA CFޛ'}3$6~q^gSs8ifC3:0 4 ]e{q@ߢGXZn͗ħ#ҋ#D8e.ZOxҷ,L恌"Q RDe`3se>Kxf K`zJ0+M=xժ_^_IP7E uW%r^X$sw) R@#'Kl?pc.÷o@ӌH+9B7$? ߁}\.5:7F~Wb}1}w3*Q`t'ymXe\GɟQ+d^Q?wbw|Qf xϐnih%;vX]eO#h$ ?T9rB孑wYj˫;[[RVQw{zAVIdscZ#3Q Q] 3ty/|P}+uD9pj5|ڮb EEП.^@p R6@\{ rclܲ_Lve3ߴH$x/e uIIYcNܫ{0Or&%F 7Gg@ݡ[/@{q|כbjU|xޝ{WMsNtKĞMN֑JSWnTN e/G%x&8v|ÉńάvM>M }y 9Z9#"`ǂjw&Fv32'GLf=EpxA^c=Ԓy#F`OdDPJ{YrHud>,j*2Fn?|Jd%KM?#LYF鲵8y̝]Ӱt_Ms=-"2d PΨ4 $[CsE0z GyZZԨOME zyF6 N!| o(y RNMg(MQ_ <:A)U4-u[$AHE6~i%Ō1}\JT-.ߓ#zr_a wFLTip,CVUҦ_ RiA%kȟos8(\tPÉ{ IZQ( !,E>\{UI+k^wLr#eVp%?̽NI^ }cRk'.;$5۞tNY}T.E'ZAĽP9$ <iWeKRث&dwwD囍U.=5OBFb@YM9{q:"qW}p% ޒΛ9yŗZ5[ۥ`vĻkmpI22GC9yw8c2y3V*[aD^YNQr~* 'k֌ GץEtj 8qn +Y5'3+b.[fl7QRoaw{#%SNi 5nRj߸`=bDtѢ`qrD c*TCcpxot0(w&SgGAsQh3/'o x=vg?)ըCu_Oq/::7O:Z9h*tNxO#bt<8#[#Aِdɉ̝/dM3OR9".*b*ţolҼJ]&,.K]Es.mPHԺ?{~s3~iq8ϑ?{( p+qwV[G#ʊ$.w2U8H!M$ EД_W3O|Se#%L%ôIx+΃٫57ιS( iUEE,JmyN` (Ku#r*dֶ аɦ'i+bu =IpO[O%}j;<FkdFޅ.kП3rts򡴃ƴ9uk.HᏀ- ߱^0N@[''"ti!(x&٥)Nr=ZjBK9o6yzO#z qQ gO&dbݗn\kuQH?0цVtsv4k E\h ٥6:_yKb,LƊ&?\4h gU1 t5_:,qv)/'Fu$孝(k _ztdv>7s{~br"͔ln6R άC T&hU/1ٱ֫_ 4798诋x5:/NR/x_ R^lC}Ҫ:>kcrR~LUW˛^z@rey1l<ÏM$b ,]]6ƨsl3bx&&-I5 ϱ~YWT=|(֗7V4}p\Se%U,J?J$]ӳYnhº~Nw:kW,kkWY#{:Y~LkV^ίo.uI|pm<<35oHx;#ni$aAhC.\=Fѻ@" +[^99j1?KE E4pEͣl2y?,h u_ZFӎsoU#N0A;٣-ցeh]`#d#duok{{tCEm9ꉺoص9+dI(4tOfE 9{흅SR+/v&"9"SxvqTDDTN Hl,lԐ)L4& i'>uQ# z={^TtaQr;y&:&ZYKal1C|/3O~2,38RiutL5PS҃U{)"uEsTeP?ٰCC2wԑ"TgvKPC^㠶~ nYt&|޳`5W8pyFaIjTzb -N؝B*,diVim>LVati5 ~OE7n]@o4 $޵eFWY)$}tn-l<_q%+ aI?R( U=z,6߅+pWomjLly{t(j̗h&FV(ow0Ӧ]5 a'jIK[^!Ue&V)/ԑO]!WpGK~h9dԏ %CC3|EqZz5f6J_xXYEقa&G\2ֈ7lD\<\GHr}wNd0iwٱ뜮b9&wB"L˫X@\(}^ʼF%e!M?đTGI;c[a9~ 9#k&COu`&؉ta E<|I;7͞Sk@a^"9Q&0ۿ-u)rCAnk4y $| ~W4j:w hR-+Gًb2G<8zr%1yyhC` s J|ѕ ^AxѪRP5(_=Us%*0}zM-.M G_tܷGc9ᩜ.b$}]^SDnڲF/4#x[n(,<ZqUkc4>l L M Ɏ34CJF <\=8c]|1PX㛴8d }$I_(@rZ:aӠbV;_C.kW'$4ۀB=V0@G$i TM*lC [XؚIa W?ˤh 7.)ѽ߫wU]ReEv8 ''O/&P\Pq$q,bR/Zٗ>̽%G;$ }O-#g*.&C>b<^lm KLfGX;>π-6fmQq3Mk4Yit/}~pVtBY4E djc]PpO.^+}ɣvUv/O3m | ;Yhn*b)ZspN``g^P? -9J&tܞP`mq)N_]].تyr{q4WL%(MHsl@2& YQ';blpj4\?2_φ?<6义Ӡ,`͘\Ҋݴ뀣(Z\K3GY?W,S[ 9w-A+Ưl-PVl@!GXdnt&c bu]cBsjsYi ?8îGѾ_g k =7׵*!oDe&T@ZDu"XJu?lO .!'-$(/4.柗[p]iBٹk;ӪV齺LA-krgL^m0' gXNﴥ͸`0ǯ**|?@t-\\žc/reCz˳(߲;*,X 9λoec۟[Äo2ܾWQI]mhw9k\k<~Zk$ga͋P3$Lpy!ASmsq͆H2DŠG~+k\$xS{bkzxR*O#׹ovسTBʀ53Xm]Q,Ok$PV?sp 2AVk̒Q~H eK<ﳭY^n#JkN;H/rm /T'|'f8! '%]U O|8H#A;ލ(3KiT#Q&@B`j[(}W:LF#;1DK9(L}Y*f8}v1ExK,5.` PTgL4 mB׮T~pzVOY1|b} .F 0sB(ҏ7sRZ2>ˁk\}Kkc?R80I8<i83*MP[ L FC7}E] ^~ (պX{xS#6^^ʫUgDwH7xdQK΀&od _Ì03D@i+DU8q²ﯵgSV5f05h='ytzPĈVvg$Yw. bXLkM3YGj3=edsu>tiXzcwez`O5p:㴥尃ٹ6Mz0 ';/(4c_b8?,6v7lW<<bj=Md$_5-W@.D ^_E>q,G4'^=fXVRnpfunӝvZtP+oPRj|$mG{B=i`z.ӡ,+z=F#7U3,Jh,-Dc݇}O1fҠQ}D@xDҰC.j˜g-ҎmD̏΅ԉ$0!1r&`y?R=Qca[rz$m]tt||{ $\\ (Zw@n:a`.X opQ`Ї#uwb^$3A&uni7aOoGim bQO9:^: '.WNsݥXFOxֈ5gQH {Q U(E_&jhZǣ/BᄼN@~͏8(tڇHْ,~Js|Qs]uֲOEY@ؚ&qΨA,p.J._z֢7?Qr580G2wt> aVuF4M{H (0F:[\hy:m: #W9D% Ӛ5ʳ#uUɵ=u ?ŚXSCLajak)i@MeMkoy%Qc7N!ʣ"{J:Z1T0WװG_4! 8uHc5w[>*y3u' OuߘऱUz]CG[3av͔4GGlXɢEB2\=|a ZT]dj]?e  BG3uQ3Fm0$nj6F8i]iA?Dvg.)Fd{ : EȬu @s:9(埈eSuP}&ugǯ?ȣŚEwG2F2Bf>gHzhbȭTeF --c%\\!"YX ʠb<஗aZ F8XVPgB0{KИ}F_}u6/y_{@:rƯS'~M6I THr3~vj1g`} @񤚭u鷨Vtes 'PבIQY=p w FK4I?N5|n5 #sDoeH{y5t,ЂO6z\!@lznOW{:3ŁH萛onXՇy볲Jo_u_2r8 gu;}U}d2~Vbngw͆pw|3yMy]xxIV4G/\PEH DKZ)dYy.a^pl1扮YI8\?[?]ȶ6ixiA[m*!j38DdD=>7<]祻_Cx,h$pķxLHw6ȣS.ґ.=pځ5mX*GacT2I㼼xT\0jo▻Tu/YU rWhwfa[ 8i0 ϭv>v&@K&xoT}3;{H2cRϤ=Vg53e6N$S9<={9 v>d$k ,DBb99w@_:²R7wYai%sD$_Fv)5>AtZCc^WTiu@ׯwdRKRDT|O'efR7C'j > ^x逌t)Ĉ3PM0"$C2 €s B@>$nt4LJ!5v_;R9׹A1wbPBL(?hлjN4☆FunO BM+2^\^S,h|vgݙ[QF1d R5نFdPMAw; (m b͖θPAcDA6TܾSI7*'cɒ&@Ib]ҭ[Z"mPGSIEk\ȹCt';Ԁ %'Rw'R5e@yΔ[~Izwe]j^qz%]DCQ$ 4Z}lRP!Աlm#PAQ+PM+NS$t4+ p]4ߺ:sB!ݦJO{-nRh%&ݐ 3N#o\,"sj! Z58~2${H=ߖ.K*a3,5Hr2_8 934>#KM{NL8\9fkfpSݱKD1!_ 4˛a_e+}~ؔ 6&uw: )C d"8*n DԎ4YoCaN6A&r?\~gz,P,Kot(?$N?0,n !}pd-_E>jl/ӀL+%*&0[ߖeMcZ*1dȥjûcIV8D|I֙bO9jZ}w|y=ڢy3ʎ:dTU|1%4Y YQghx4B)rt5# vCI8v֙VȁUw) :kOIfN{8ע n#4U82Z %o зp:2R0n6| r-m㥣 jޱCX@YK9AO$$@$#ֺ'.i^ OڟSv*\x1a{̓Q! h3y|e~զ_x_-пl5- DRij6f>%D eM|NeI (H)7b"mjRk4c |[cNXAz[DCΟ W2[Xhl<.&]쐁 tEj!7!yY<0o ~B5&Qmy}Z}O`vn^ ǯ$7<0YtQ"GJɅݙX}b iFHnj ;3;녻q?! O7=|+:?eӼR앷S k:w!}'lbӝH*fWo]04J]\g$ tRz2ʻ)ɑ:;y`F(+m1 8ʻ9!QЮV3B-x~YA){5 ĥ )En[ay+{z'?a(x,\Oh0$ $c0Oj].? ƿ=cwx z)0Dv,HN/Wɪy8j54^p>c)"Co8sf"]xn j}A0Me t+ oKͮ\zh]2%#"`Ӌ\|*(g[\c#'¦l0j3EC+ۜ&^~ip,V 4Q&=&[Yy[]]Ra}BLC(\''8k ~?&Hgx7=AD<^Z5Cv82QGl%KoSYIqv@X X4&V .^l,giG B0^ѬĺȊF7S#0wiEyc\^_t圄-SS?'1~t+A}cL*ӖK?M$P fhVu(bU)]=qLRuʘ6' f5 RC=cm CX9p{Ŷ83c1V,6εOR,3:R{4e "Zb`KpI | rYAR  ȎYTm^G:!6ÞV3|<\:^) .~dt=~z=s%RyXuwj iE*<Ȇl==g , .(jvrޑ3Z Р_ԚR8u W qzawtmW+xw~v B}hqڕ &R!ȤH+{M@͹~G(^`| 8U Cq ) xW &1['h Vb%h7#"4~Ľ@Z:.aчby5dΠ@#J%X?>v,*]c>I p۾<kٝе.bXR(Y ' Ug8o渘{q$d΋tX;G,cp̵? KKG+Qeo€sx"Gg4 1R-ٗotgT>^:kl\!@Q =W_&`UXmL̷q˪.vxzg7^YYgl\iTRFק3h/Hp h~Lᒪ^yyW(?M" |cT-5OWȝUP[ 尉Ip/FUs=ﲅCYL`](߾PS!ca"͒1<߃.% dIFH]98|oKz=IjH ;7 * %Ec->Ց^d]Bu 1iCIfgcM60YODG}mNrOwHUE_$&s=]S?nf"἗zQ%F\W P; Džo=Nؚ##JgmiYefdQN/.Gܳ-Ti&YCjEooz"5]zj̛á܌#§>cPB {:nJPyIfMVOz!_RVqf;`IN|@B}G|ndVp,ϐN 1-<٢j<*($ޒ =c}%;?!ve%k{<(O$3% iâJ?,i75?{/~&?&9~GKRïi #!ķ//Q95<ªL';И% QQ< O\Sn8g}sۮ-J~b/ N icO5º>B\C){$O8x Ɯ;ȎG 7 ,̾rs =_Jƒ|. & { Lm#/ZiRT @$ cʚSNiMh >I}[_0LVLeL>N\4.izT%l[mؼ gﯹ"V+e6T p"9Ucle,:A޺?!rZ+/xt@rQww [=_vtу|j/.y,f.FlEYl]__fKh aen6|h;g #ske09v m_@2`/ 仵UI6Z/9\TZU}ik _μTx ,%sE9,#4<qaJ+QL;:)Ԟ26N kroc4=/#pR͑j0ɑ$d*Lg|4-[>C_uՠ1ƭ XXTmGQ3G:uEHDeLPc=d#5oK9dD6 cDOןK:+h ROvlUZ[+3`{vr,c+QߙΚ ,)OE[$30nVw.Z".z+ĿU:SDivB)V(/"JaQTSK%"Zuw8uu=ߨi([u$ ا@7- {a^0Q1?OU8qY(DO'BPK]Wch#?vnEП4e":1؇P85 oQ}vWff Ք` b'AVVRINFCj\X$!l=67YxTikzĿBBsGI:4_* ߸SB !$4gX2p`Jru)NZ1,iS{*Ok%iIC2L@̟y(nV,hm"kB[^)GjI}=bW }-?̊~Gc/i1w ):V+R 2Ve³ߠ Fw(!UEn ?2~mO߫}j*IR|?۳yӭ9tCF=>PQ:uTU}ɔU9hY/_ʂG@qyy"E,T {n,/ :,s䙖K=.αEe^[(]a@DͣB[PE?G^6cץmUx1@3&-ervt?o_ ;1U2wqH 8+B> #{r s#-]q ~W0ipW|2G3WKF' ͉^4ZuTlfˁ qee=ۂnX/S´ ag[]?84V{Jޚj +yUW 9 ;x޹zaMܸVO kŹt/v-YO`AH)ڿ|p5H,8*L%$$i[R.#:V.`ZV :/%lk}R{B;(On MY|D͖q$ lH$!_qXJW E 6C9u -=Gr_ -?E' 0.lz=f}[]LEwnv"2z)WMPlνɏmh+KϨP*g,jBȍ_MZO˳;Pel@I@H@=7֞&/Ik,_7Ip9#sю@Wia1Ț]?sؾ Fz1L_>?C?\sFG_TΪ-ฝ!_8U=)$/=a@y|XiaB/\R^)Ȣ~i'GMrLⶶS ?-|+I*/l[`װwceWgĔ+4JۢNSʫW牲Htqq|MC.P0M??#zE&2O tBL[@DEy!v5M`ly5Eƀ*[Q$~.C$:y8M5eјҒHw '|Өⷋ9+Hsqn e&|k6U^ܾsSj|kU pN OI8p/-Ю`]/FM2SU[X#)c}2@b)p }̄ܛ4CW*cS)7u$扤|ShNQ,Zɰ?lkNQy7) W$Ej [=qOpsu(`WUב%L6.n)0cA]Ҧ+g[au0‰:GYm<0Sq%92}HbAG+7\m;H73ێkٍj#F#uIFprVeZ d&^ m87 u_H,o48"dWW?Ñ|o/[ ʞP5i?^z`M 9KZDgV.pӒBH:,vvXn>/qY}nqGb@ʅ/:+"XֿrkR ۜWy{mcsjvw |QRWtKy3's)fx@z,lBU/A[o T %YcOc(ؘ}茉FW2+nd4ٮR'd@[W M5IbvT{ O^}QTH&gYv@޾HHhL0`5RFнp1vğ[^o\_\6b}D[zG'lLo5^2T'kNS"Klhqޘ01S"p߅<(ZUFC?nF!,0 N! SJ:r-%ƣD\hB=)$:Y\35_YQscCT]B4 bq4oYp|3>-l\,4hR$밐Eo1M|;8pedQ.:[0d$ujp9w{pSD¸ w7|wx&5XadBJRk 3T􄶭qJPsaO/S] \+Q v[dAܮP]ۦZnjxZ+C Y2|) JޖT~\:Jᐛh\շ 9K2 ?nOQDKJuX5,|9WZ !p $MHΠFGy9t5)+ U|ŏsd}<͆aA\T i] ~t,$NL}&GyZ13W8W@@m' oCq "80x߻P( Rq|#88g-go]8'A뷤ϣ"D^vx:rSnPLHޯV dѠӫ&|CLM֕%= LUe5j.uVqs*r3]c~kiVǍh|'!F8;SXQTI D\ x +6^ӵ~F{mjOy9-"f=5NT)é~+Ђ,U Jh5j<ǯ- .e_\*`ǢH]OhK||aKPW y0s/U FW4<| Ufi0RD[>y'FEW`(n>"Ӌ)Hﺋ+ t̋!")bMC%$TtznUC,GD`in=/eyU4Jd*ܪ|#\+JXYx"@Bˣ]|#xݽ7# u( ?[ =ƑxMGv~OGJ!"CVԴIe3NWAs= EA(]_s?Q' $E_G3` VYڧuW~AB_앧?gD{l'|=HF=p3l.v?MbI$B9bÍ*J:ԙŽϣ__HhͷG?~kYmMl`j}[ingX|?| 6#?N/ +Qk|O SBm(J'v6ݫbiWEf҉-'w(kNV`e#vf9+c &Zv' %18z=ܽ&I!3SY#ɐhhh~`$m܀SyhT[8>Q\\2gv`o/oOPu5lD D F؟(i5Bf"5("A롈hCWMFZ܁"9EB~ۋϺW:{7/Zg}LzY_{XķjYM'_&Cm+&}pnXGpEA*90 lQYz!`٢%2kX$@lvΛEYP3 t I08\{1TL1; Sܿ& \?H c_9\53Tv}s“{eDT)E.g;k]qYŚ;d?ҷUNC~'D$r &Vۆ I4E;'B: ʋmH|E.T9$=r%+Ϳ;aycB \gQ񟡘e=cpZenGBaE[V V}OQQ;nyarX6r @1G;="hVqiM P/c)J^@X\6%s1=$^i!-<_?fcb4-ɿHozü.}}H`;eց\Kꖋ;.UIƺֺIgWq>|xΪܤXY+:xYe å~@4з|^%nADrԩ|a'0kkm`8z 0@F"?4Vy?`u 릐54}@7k4X"\cjǦU=-K"q!AIU1{idSeC j>YL$%`L> U)X-@\@SN JÈk|[gl 7lSjvR\U5E \~$z23m{rfX3m吕FY?dVgK/~t;6TgꬸʼXK~oVg# 6rZAnpJD΁ ԐM[Lfs9 2@<)ւM,UkH.e2IgX i)a+`IS |[^*zu&F*/D9-\ZE~t%A^j Tlr6_),U) cTXi g ;\h 1(OOo%b,jt k|1\Z6X<7m;|t H#ۀJ N}cTAM凎+ZVypg$[掁LY <hМPJ'u E>Q꟟*:[4RLP;J$5FeƖ8*6eDCrHMI{ %K ʾ/K_D`le}5_*}8GӨZsp .\/,Y[F pYZy\'Urpx.@6ҋ%^.i"$'Y3kCȐ{5;aE>iSmKjͿ9G\-?o~̍u`-+jxPn ۔~0`$# @)8dۿ*\D!5Jۃse4[Xszq T.ZKcAAg^A^:Z~ PÒ n3Jr<2.N+{ }]E.R*9b/W]1l,}!#ae>aki/S\OhT_u[Pi]9E(,`YS!_4HC["C V#lwCt:pBd G9~W7Ð Kg6(]HQ J313i Īq*z' 6] `Vxt|[J+qлvӺtgZ.?7B. &&~W䰼܉(r­mHUnSH ]ՖT Z~N~%)ENұw9="CN\ٵ/i'`6m#e! MZ Z)1{&}u; Pj&-T\Yb"ӘR8f-9tzlv=[)~b#U dӦ4.:D3zT xi}`;|,6`QB+\)* "X`G^Ԃ^UG7QTH|4ق!1f@(9opVMNjtr=} C)б@rA_AXH,eamK.a|^tѺpKkNi+QO/|2n^3?V] #Kp\x;+Bۙ84ٍ&(_/XQ| )Wz*G[ټ +PBoha#_h}nRԅ cم S u}`mFHxsk@||+(B@ k-JK %j8%^M$.I[N`}VoL$ʜ 8Mn)?/Ĵ{G]+Y ݶ ئb#UoɲuEȶvlWbɕ@E κ}B02zzsFMF BŮ'̱qʩs8R>W"fܗ ۰G.u$2644\3GAWxz#&x3D/j+ 5>{̄n=T0 mTKwuoDGɾBlIC+7~yx"J7$/v'Ò3dZ$쮗#dk9e e s'^a+yK2ĸ\7o:G&mb?E濅*Ш@rBev|OKfko|i`HOm7IrnuB$| p3*[_jh.R.в%8tP{gVKpw%btL jdP :mgT ӿm xU9QT(?n?δē`cE6ɉ$\mPkߵwb43hqЎTsZ0._m.)D[%=w1!(s=gR[w ݗߺ8l{I4f;_)Xxc"O0,k=YYg$T^g'<׬w8YѶV1᥈uԍifO!Rt]G`44(GrZ`Z[*߯Jp:)MN!abLcoNCt0\|E #ЙN2khֆOb IOb[\b0\rk\AuN?n$uz|t?V~4TA1\, mәl@Nr 6Ҡ3; foߒy R2JPߪ'$pn 9N@&,(RPƤoz.>_nPĦq7(|IqeȔEl'-^|]MKj6 }MR?Ιπ#D8S3!CgB $06G@6˨QMy X( >M=nb=ik1s^{O=U+p =>,f t\_D |SfdmqrG:m~ߦC4h" \g~ŽP +"HupuT PQ-'kYxRaKA:cXX]_1zN:txTa&M}m&A(K3GԿꥧd-5@r!J-ePm"!^|XX`M>v]|Ґ I-lZ^dѐ(#G8 u8-:ZNf$̨QbLR\ޣ)c_u2=DlBWʋ8HN-9*SL؃ZN$P}6U^Z[D_: zpHn~a4J)4Pj[`O!<踽, ΥLE7ls"x·P!ܯ02v;#i:(OpA<>qdPfcmU4 !T*HDU2 Rӆ19`}B} D&R3 QF6h_=RiD4!I^qV{T|$)4%]B̐8:pK:sce*K%D#\?{GF-7ɀ:y6EJ6]ۊUs*nba:~㕇pg~:e.Gfr\g{7 4 ts3WSVG̫Dm3²jk6efڹ8f%Ol|. .y!r|@{ %º 8٢Ǟҫx(o+;>h.,mdCtNvGae}Z2k ѹ3/!zLp}D]ȇjYn>S9`vFn|Ӣr$tAsedF>SDSa1Rxtt8ш(8ڰ#n& ̪σeB^_,>DSHq܇ !9edJi'=0 o%(r^ٽf1]')~΋7b.72kyn4R`yY1nI <]Y5ة;tCP-D䧰ژOvm17?[!G,k&6o^NxbA6i{Ƹq~>ssåT h{8Ɠ!(D7 iV`iKL =Jy73S}N0_Kz-u1cϵ˅kx;BQF:`y^C(w {5]| I%K[~:u瑣d$F{A ypwH =F;=E?~ 򭉽M?AIߣǿڦ_#-Bg'X~9jh|] J.K'Bj=iv׮! -GP;N'C>|Rt6Su򴹀 ,=ȥ+JF%P*r'zÁP'<~`#XH/Gpކ%C$kn9hsf,w,=$ZnF=麙 @mL,sDcaa³~$>IA"{x_}C䶥,<*VdL У,ӵe.Hwv=^thp=}gZ'$l:02O,XQQO'u蠭w1HEumZ|DJh{ A\$~D3PI' dXOZid#厉2~ &BVmh㓂:sW͚ q.k|e҃[ )€V0Nwe$ݳcm5T]ݰr£:8tD ,&'pl2Y-g+ ]H[/3&`ԈR8'&8V=gkc&|2J?F,6ӬeK⍺!O Z7E~ b1ȡB_a73Vk")UaXL^\ṆL87D.7т(slL\LPМ %8û}xBo4x$za8å1”|OUDX&!zmO,r ۍu3BjXY<ɼ2uaKzTX:qkp/Fr](j ϗ\ChtJtM>_9y]2>e Wg@!P цa0`Ua $Ay]1 8 60=1U0ºI鱕$qlY֫K md@2m:jZZ`KL?yVvC*e7i~K'>n$| SvݚzzA 7iCqgaULQysC7z߸[PeT3Y^1(jXָ۬l\ϐ":t`ܲnKњ$cuT0B?ZĿ3j-eVM@e|܅M>o;8˙s$o*@*X*XBΫ7&תegPѴ~|XLr81ĉвỶG,ЁF8o13,3l3=G|*@ֈUN*R !j*2y?̀CH xsckm%GvG?虌3s *#P3B(;v1m"o7",M]hM# 0P|CSV>T6SXUX aqk> e48ֳI}TK2v 3H5-CWz9ٺJ)O$;[,d{xU$eJP[a U7 n=Ceb~~ZE[։1 Y!.w<\h"Km +c0,Z >ƩeƯJHM뵈h=GCe4x7uYtB=;)9P6({p=[) >8!c i=X+3q< fv,{+7غ~?#fOZɣO5sMgh3~bzfR( $ͤ =O>D,OJ{QVX_8 m(` !cn_6BؾL&4&%ưUPikO>gRc ۪94B%?> Y;_,}g8m0Lȷ1HT.ڌswqBS  (C_%`&ٙ*dBlc9#Vo1I8߭>`u1t$ymDZժK΍_؂ LgWo>M7 h~FE"y,SYÌ[鬝kAg}=e JRTBLܽ}Jjyr~h7cѶ4$ڽTVnJN^?NbN">7;YnR"6dݻ- s;Z-ͬ:q=_\8ZF9q_&zV6cɶYS%3e"$[I[q# 4YydfzlNB8'k_s5].Ir]Dv@D74t/f{: Z<Ȯ&h*؈%qѰZFfی3^9כAfOY۶aQo&,?r݈4SQ7DiV֙2L&vaJ-i 2(0P¡JDid5#ދ;Ž$4~pk(C֏)X|^6ӪʎPGfF]=hӭ\mY;D7v>ѥ3•xA=a⸠ ?_u> i(R(%7dA93m&&iܕ:'n- ɗLL71<>U 8sQoi}kjGB0{5G+ne(qP&K&㯖Zs3/]zx(WzkD昕>e IpoHdEMh >p4Yiaysd*L8}3Ӭ)@GLȳAJ<9VBJhVOpt uB(_[->tzIF\B}4&79XA”"Ast:5(k 3Jnr ԨmK+=&f pb9A ^ȥsPvwΌf6"]BEWH@jATMHaRt]`bq"p 2A'ʵVW܀@*tStQrzxw֌&[ܻӶ[e-=wWՒۯy o` kͶ\u#AԽn׵"ni* n'ic/~֪ S1)&Hֽa Wе4/웣OHwoj-|ZQ|A6h<79M](dXR KJ=8ͺy{̾.*A_c*uFjT{GomHN[-n$\D@RhOxG c/MaxmGHZ{%QKziN "yI|^I@܀IV`Tq: \et60_ ;kgڇbB54B:⓪(yYtet dwm]*VW6J~Q.IJu3hz5j&+3jaZ0x"_5b%/4dIeFSPFU(:.z8tv-s'$ ~LNi7JO71ojqhtc~Gu;`OTaU?I +cV '`5?ڬ) )lZ8 -yaqU[Ȥs"%Gz7YuE*w~Sd!xŦNx4}<$m9D} 2Q Ҩo%-ӰK/n.M ЅG_ħ_Iλ"v9v'\ց+àMSm*TI yʲAtQN CԛfTɎɷ5qY%v f!t6rloC~`fIj8դv|0Vƨ?Hg10riŢ%wк5NO C Nu7um}k7 Rup6XK 싆GKsYh6JъŃA3=a55X{h]闠s *_)v4% koY0ͼ +*IS(ؗܠAcd?1 BxI ̷4zDGv-ε|CYHg W@-_"Bzi>~avj+RѢYY ٵ4X.:8Y7O2v#3>|H)}ldxAG4'竆q|!> "O2C`z Bul)cCǸ\ 3`U4z?- tO# yDGӡV7gH+L #AũZLKWg`19@dBozX`xsP [8Y;CLRrV]Gdp rXNd'%zx#X`Kh=U$܀A("x b~v#ڪ_ݲJ:;Gq~(o$~qE)ӛ܉җԔG^FyK3XҎvP6@ip~G;˲*AAq3~](Vg)+9;KE]_Yplge|諺c=\& oop/JOnIQ-dB"CŚE+_Ոp>=7fĎLp~mÃp\[5 T'V G>seZ6 AM`0Z"Z!Ix >^]ɫnQ[@(i&d 6wߴZPh|^L/vB l*$Px ?N{m~4rEn- qi)qtmJ3v^G&#-^p&vLa<zy2%_3w-!J1}A gF$=J8OXպV6Z{*pC1`7",9pE[kU XM Ctt؊@EiRLƅ1ӤOޏk;DS{i\`z]/y: y@?qNJ-7Ys@끻̟σ:)qp/L`,'4pQ>~(Vč.vB ,lhaØom#T~$65ia/q $.LJ);,`HjAJTD4p']2QXA.RZdwBߐѕ 'A4Gy+9’.( kfR g"jΩ )r-]B_iU?`):ߡˆbkۮK =zᅖ4O_ޯVh{ZB+oU6#¦Y :E6{gOew͸uݮ,K8!++./u?])4? Ι>@q),㺂;K,Q&ExЍez aSdrqĀʨ/ bҞ_-& Bv9G%tmJUFYD_Z7׌{7캐G^ K0(:}F!Rp +ϗNi(wF׳5嵸 g\Hb ?޻0BL3GLA>XiI9N:wX1@7y\l3kxxdـ܌ 9BGddt|:i(#‘T빢B JWJrѺ{ 1Ր)u]:z5scun lߜ"/I| BeK[*5d@}j*}2wW]hj7b5M JUJzb{!ݍmqWe Oi!NkK"i rԲuɐ${cH3'|_Akۼ':@ gT9LNhX-EEtf8T$89AA~g߾}BkPElIK[S?+{ȇƻ Jv4v"R9&|N}k'8) 54FBYRI 簾̷OPM{|Z߯Pd +S Jt>(#G\*ug}I0x^6"2_#K$ qFXSpOtċCNZK@j@16^6]>'C}p†|QkxH X dO[*|i B9Lbd4mRUoD}6[FjC8F\ qJN:zaDr^3 CaBYX/2)m W73Y36 5HK^ī=ױdt&м4dZr7Vtw(*4Zk xtyJ$h<`)5pԉ5EI~ԞH*RvH"=D.%;Ft?T?(0@HMAPƟ xe`u e݃S U%~4{ku[a34u5> |C> 8.Qe.GFr_?v\Gt< Ds}1NEřJjE䧷`1$~w4.̀ɕѱ ҾԚs׮et|tN?U*:/8!2-G&:p(g793R?vԸYzRloLN7h,Y~~ .MЌU@#와s͆dAtBtVW;Ʃ;=czS7(vTNMEK%3/e (p꾙oVNYLUJG{!a+=BgGw/+ ^zb5jj?:ɁRKغ׻Fɦ]!а6ٱ>[ѱƠk/N ;-#"J YkH&cʆ8Ty &Dh׼!#HVlr赉 34ɳQ!Jmہ3+(Lj~FK~3,)ǻ8Lp[0/zOR#?(wraxWz20Sm )YQ]w[Ǝ]`OS13QqUwpKIs\u;JTX{L}z @Ɵ"CZPjo= 9"iLu$x$"X8cpGk9Ei!7ӀB${zM$шrd3r{0{,_:yK]:RPD3ShY@I~MHdxeM|q| <7v'qɬR2sN\pޟ"z4|j^Y$ٰѣ>%QW*[ۛdR}@@iOvle{4?X Ztt+zz_@G^`9v 'sA6i]3$A5vu]JaCu?{vRmˆrq,B6Q\OSgPWKP[Dt`jC 8?zi2sfJf+`"=•v靟Z Ũ6(YKqVpi]o}g7Rg"6 (5F6~ '6f[Cq>l2|52hHևBefÓN&L"_f=8-OJZϫ$ ڶB ;k?xfu?}3+>WfiذgY4[BF&14hxLooIík/(^|Q$x`~^ x0v2W)1N w+gK٣U :9FEmmـyrZ,otFxa[d#>nDAi`%d7WiRֵBTd]J/6 NSWÉN#<t+׼ Ff͙0Jߓ~j,Rbm][`0Ϥ^ bsb3Pb$xC .%Л1qU~NT޵ײZ0vFvkTA[:]O ~*t/z %^;>-<!zTC"1k|xzV/E%:&AzvCp8wrϖyę /RQ #y:56&pI \e6?RxА\Y#p-,n}?_j2nnhyM$U?v]58 kB? fb͕gddRṜjfcFި0YD7kVICNJQpҩ-X74Z$p)\rěkʙ'N$E]5anS/~EI[?ͪ_aZ ƒb]*ؠmv)>oqw D>xȦMmhkӦMt]̽f4͘[h\9Iy_^Ǡ{zM*d%6 :UTϾoX?%(d?ɯk/ij^2 IɱCYشh *B4 PoQ,,^J$ݻ)75لB.KFK~ ~(; ?Q_+ijGyhV[sp!FP )Qנ$>͵W^Yt.C6qՐV ah 0Ns`cDWd} ("Rv@]Kt1dY]qn .0< oFb* \Y FZtZYEAvmvΝ LJ[ p`(p.Q+->/Kg!8x-*2󵄼bb];u; (F!<¼(7Li4Hʯ!i J3ډ5?e A=ű:B2xu^DtiYނt2%aFn>܊ϳ%D|ehh)t)d%ȿ#Ƅr&q$`k.#QD ;A#%km~`׶б*aK5$ `LpԼ_N^grB5rk%D Q+p&т(:@(_>zʈ%"ԨmB7}+6۫ W$a w+ g)EY Pm'k0w:P<!Fz0ݠFK~gh1pUNk%Zcw`ߦנ"'/` & ;A `[ f}`5BY^ȝwqhϟdD_l`Qgi痜o rWUC" @IT|&d@Ce%$qNAՃPttyӞnj9Kk@80=1,Dzy-ʡ!q3։\ewuC$Ƀ(> TF"Opلp] V\?@\>?VH{XO/J~uy sxΤv4ͥai3芬5D7V\pQ9 [[3q5ʂ.<_ rc6Tlo5XX 7Y[_QghiA(l\ITHFQO\VY).w;3&ow% r{Rս+HSNʽ3 \N9& I1C5'+U,пc Y :Sy@s9ʴI|\I|PoCy!idO36E9.Rjo;^"/ '7yxm=wن6- O on eޠ]GVlOO gkgiڴИ7yym[, 37V ɑ_,>9uNI4f"!x);l-vr#Q꣑]SFu<ԁ7Qv8ł4 R̆7I%{jƭU[ǽuY=uStO\kͭHćr3hHy4I$ic7Aަ-\)*/a cA <="|gVB(ƞE-U ] ݹqMU\ޏZo(݅Q>$D GxQ6>y4y3)o[z,W^+-AU~00'g2,_܇(y+[swͤ "^t{)sַNRe5K]7 TtPo;*^)e ` Q /8.>{HK#D\MA"MuUcFVgOQTjH3P@ m;2fՋLzOaY(9w܄{2r.K|~pKGBKQHެlC/.wCSűG@RFf}Q?Y eebgR'Uw7UG4q p&:|ͬN_IȠnF^3^:C 2&(..!G8PiʹlUUL:Ո蓰81K7,않?ۙʷo6^g3F6E e8JY^0) "HṵZ߅: fw!JZoShmOwdrn-zr?F r{z7 =gNZt԰_,"#5 |ދt 22@"t<҅65pEOi S+[:Ւvul/gkX>Mle0jMgppѥ]1w#hP(ͯTx:4gDT, t TLuDoP"c}B/O]^Ҍ W؃D~dr 'Fݹ:lݏk d'3TwwV!n(ؚgƉGX] qf1t4%'2Epg~ߣx!1(oL7D74 Np| 5*ÃPE Kyt+JyN>^ch=ۈּ&2FSnTezsɠB9sctqM0_;'mБ5\Rxwm[3?Q ܬS-_4%7逆 VxA &od^T[OY+=~将0Av[Â% bP.BYTJL2=8@k+J(Ҍ,a >JQ-v~E -hl nUMy, \Q6s[QVa/{"!^tkdܣa&f~o)*r0Io _<@agK;TGdG&DțQŒFr;{Ś]xL/_RQ ]ƛPc;q5? w,GNMh/VG?kY,tRWU>Mr[K݉`Z]3$4j \Krg!Į\MPN[@a/T>{yghip4+ʴCPmR _3QglFAU]% uK"XMtɥi˲ܒScG#<5* KDQ`&&CG9:86@.IO\jDwX ]01t&ϸuj@`ȴi .+Qؓ@љ#Pj'Fnܽlϗ>zd3E[#p4@%yΨ6nXh,lڈƨ`F}fbZ[ /,f G ?$t fṫwۇKs?Za{4)BUp2da q @ 4\;^I-{ bCyoUbHFbkS$#"2iRuJX=y _H0N4 tEݣ$ՃJ^9`$I ]l/$ȢC !ϬlI֐`:+ M; t_X b 7/OWYWwĀdnw}nSh~iWGұ|ɮKq}}j $&^As˻6s CCuy9, 0T5)iz7[X2n=֢&1K4 k.B_P;:._J"4-z|vG*:̩x4ZcLV~nAS{-DA(UYV{e9 G2Y2[v1|X80Obd4H>Sse:Q?+ZSD. lVYl3u@xLq}$9K-ӂDx&C? "WEo {v*QymNQ==ҌP D韼.DTXxs^SRE>ң362%ED:g %h?M(]e+|il#nLl崿0;t^zVq@ &vt2k[<d<k׆󖆺Z $ZRTЄfC5l+}_gHllBݺ/-1C:h G✚-]5ހw;E؈N6S침{\pz:׏Ւ yIU&c2+1_ ra&S{89/:jg$S\5e\h' C26hOOo u zi͗alï 4/;I;@[FDtq fOk 1?,T֋Bwގ[g Q<8b!- hscI{x4eȋ%OʎJDs6vo?R[§&ٽm4^^[00 Ѭj=Dr E+vT]5xv<-_1?_{}]H^Y1EUJyE'#P]$"g߲9*dUt݆̍RMر fiJj؊=.c ovm|-43̌$!m^R"hMBb|w$byE Es89ٝeKV(t}{$=a_>h͟w uVw2Q<+sa-`vs=Rp.> ΎZ$Izm%4P%Ȟ%3ЗFP䨖A4%Tg6Α(W{i$ܓZ vgSv$ g346+bAwrR?Xǁri Vq4Z|~@E7VCį0?u ~hFcTo\:&HTwG QK|$;{Ťޗ3p4?V w'Ϯp "E q4{9-vm[:n'*A=Ž;<{#Q[^wI4!lU>V){] ͊ܒ!h7)xб3Xc24+# ;>{bNPhG;MM};3'x W.̄Aci4BzG\ 9y1'1;ȈقdgP51OM$NI,5hMs6B`{ʶWQKa;9@lFabB=2> ꖕʭڪv|̮-b. Q#s'c?S$-kV˵ GE+=r^Jllx1}c [E߀|WI&2﵏r86v R`xluؔ|X yFLua̘*O@_c(s:ԥ~T7<^ Ut4=YIQ4D1TΥ}PwWVT2Н"΀D@0p), P~5%lfj߆ +/̕IAâESG2bvM!=S; 5eaˏe-@t3 <-43 IJ ۡ4tR}'yOM\s,U(D܋;fhL޽݋OpYYZaSהs0mCYM7E7j$K!#Ok*"iV=;e'[32כl+CkhuEᎅeRg#>M`.zmصJ"b}?_0X{(.&ۿ;6GZ&$>ݷ_Qt԰wBU}g mv( ɶlz"9&xhcp?np$ď7*,)]?"4J}tdߦ̼7I ^G?;Q ~+ qEvb5b$"3uK~8xJ](_\(|OL4J$FXȢ~u)8kjް`# 'vD2د^)(~Y81$eevc2y>4%J ęiyNjC0ج6zX㡻km({D5O(Q(u ~BHDVZ @6,b8%&RH^K?7Ⓞ|er{᷸7^Em)? s'П,a*} @ ]H >Ҥ<92"mqils=6u~_ 4yh*Y钀 T"XO&9:\ӳ3DxܼRi&;{q5K{&|j2hqџhwy!Sa5=CG?F(=䷽ɒpqODd.5@G(z-C3?Ig{\cpsRĖhc{h<0}W s!}Mp\?, 5L`{؋?F&PL $ho"rKl}iΊ+(E0~=i©W;76/*ml\#?q%|bA$0=OS8/}9N.ӑsARs5%H]VKof{n޹^뚔?m^T:nZqt*` iq.Jh7̼vu/rvHuyeq/+SoX\^w⓷b$Z7]}*҈Z}y/Lsk)7aG`bch(ǔT_呓o.zdƼx48u_;B6X]D\/Y%tiP8t]i(q6;jZQ:j%[4WɕX&s4kҲ p\;q.zWi"2쑢J0./K(=a:ljx:2rB Qk#HCW=`hAlex{elfr 6.1]%f qg7xٰvTL&U݉\k.u\hXZt\P̓}EYKx6'kHw[)?BZjmYl|nC[F0ORA֝J i P#uSlb̾r4uC{>w[],frr.px?HAWzc O+ <u ^bvHAT/8 b3P-2~EH>1,2GBkMEv11~5܄crcIY5Gyhv,2ױAl=! U6|딿1U"s ( PSsۣ{: P=`Rt ]=2r٧wN1 "WOd{pTy/-ˇhJM TBPmtQ OWEGfGRiܐO.` ` -}=S̄KJFAL}w^Չ-NJЗz5Vz`. %evګ1 @azF@XGC2a9'E=׿aM']D3KSG̕"qRXh5cpzspCaR.4}C~mrUS L;΃HT9'Ζ3bU4sG?)?h]~fy&PTp>:iuxVsk5} J u2d4t­RҰC3,t*V`SH'E,K.eTwZNT ζETEvFVVD\'akf#L#Q7Շ~tkZ[},?0$W->Sh]rEcb[q^< wcyY c,逝\ h7yu]^A^4ր!@*u? d†%A+vŞ=xՎ&Q%[0hF3UF+WᔛCKJr^.M^d}N6&ʇ,D#rM]]V/,RƑ{? *G/R?:'"`Q'߉ yg.hs .cR8 }ĺ}IqnJ!Hx6JE%e8k'4ZH/7hrgFAa1.#2PsdE 5Ӈ`=B3!gTٴ\\iZSm\O\Huw]k4w ^ cBP< &Lڥ㽛)D)PԍQמ-2JsVmHbL@ D$Q_CʎK(# 7,MU[5wKE۹U$-&x퐎{4k+ \eq-P*N:2;Tb4DK:f[Κzޞit;xKn%; nMMqiɴLDG)y:b}-#ߌIM丶8T (id aq1J <I= !qn} |Vʬ{R-v'Q6BG# 1reh[eL:5YdTR-eH" Z曦1aXo|CI'Y >ya՞ّdW1bEA+aQ0nHo=zT4(_%סoueydo#5U:+{/t qG'֫EOeݏΘI7[P@P⯦欯<fDkcq}̈́2swwqb1@/alN i7G"6; OHO%tÎ?-Ė ѽf3 HB)5+ܵJcP ʼn=5ywkRKoFQ(g`Wi'KBvU.6Zɹ-KEtK 2@=Q&>٬GAO^NٲHgn\^*cIcNbMd\ZdzH4l=>{XtYK4Gń̵21sp۹(sv|F!D'\ڢj':Nre,6f\RM6^K0:%UDX{^֠6NS3{0Xbg;0I{?^*ҿ v+ʨ[T}K޲wM2p*d~C_Zd##er8 V  U gSR! 0| @lr'%,P1w/ ?!xxkx2KV0TlC']K&E\EmjtD7~ ~eO*yCd$ IgFm+zOcDJ>a(F1#fmڒ2~5%ʭ6J?P;qD({uZ% Z9xQ<e邏4p4 2OA ӏ-͟H=\vUE$4E9AXx 5q;.\Sʼn^gFxmxI\Ɇ3~Ig_ r>ٱ~|t$O'Wl)>e}b+u<k7(α}0Tm,g ̌p+n%OxD=cTI-fc 8eĵgzK5"S_(VA%y~ 7k2.=3`fgqG"NZ@~qpyTssOa4-1hI^YVX3b;U Z}J?UӼ@eʛ`1mS$!yYd@L'"o'h9YiɉzP]0j)jƄmLlja5lV,b;;T(n'JK_ иQ:4zjQ_o5%k9$Ƙ 88WOOD@A 2rLI`?xՏ&鰋Ts0}-h4ة, L44jIv A"hD2r񵏘jGh%dMJW]'O!R>hocFuYx@S-)3&Kbˑn 9~E u5 qmyq ,e"O,yjvx.[-6W\wJ!A,Gms`X+\YsK UOn/DE7/AFDZo8G4kWZG tJLn[_z/sdTӅ[`ޯ6'G|oy~ <VQ_1=Ud^cU7V7riv\80x53 .D;ñCI)xTlyG("@JO31 i_&_#~"P;b8&›ś_5l9BTB U4 N]}E Hވ6#sgg.] C|hR/3BgY5.[}m?G/`̨?J1/H&~>c8Ri|LJXDzi%O6P0o0#!06{44מȣ3Eey%)_Ș.̊hʵ"u(<{!\+0CiRط0JstS0Y@ɟ>z‹U$~uW{@r/9 vS|cZA%tAzPmC=)7gק8@,;sc5By)rP./驙oZ[A-ʗ:2eUM]k&ܿߡtk8%#(Z,%$ z0jl.-Dӧ!a?m%(]|ae0&՝ Q/+E⨐aY[.\/?>& Xܥ]mMqT&tr`!)E pѼJI3y5' t]7DJ eh$U\0O8(2"{J3":t]µ oǽs9.ecr6}Y @}܏2y+MūWq/8pMZPkh{a1y&tMoN^J-۝[b3'[fcBlH(y;=9Idk'R6"dqt,ߢ]MV>@wM0^F`FղL((Sypӭ˒5y1p{uxO'7+ֺ! c ~EOab]3LQ`Bh xdce 7#,C!AF&U ́ ="+7zս }D6 ?bCfV䝬oJ˙-E4ulYORvTN~g/ǿ-;g,WMܶ|J̀ؼKF)$N\&^ C1s T2,U'\鬘;?^-|$L\|ݿz%a=x9ڮZ7("/t^ aK;"7n.E%gi@@:)[Ѕ .3u?C)tOsJy>Vq/Ǔۅ9[$qQIf<>@2>[ e,݊ih'|I$+cIEtit6E3;ݴ6qIk#Z<: J`d*(a+Z mf'h߮g[֗kx`1×7`< c$(c.=AfX.~q۳A8zi5뵝kRv%ޯ s4_ ;<$!wu&ʼfDfK>PVoN"ᑧ6{ ,"W&Ƨ&RTac\}taj)HyW,Z{EOpk.]3?5k]Al!Bd+y׬ND42мy㙘XLI90ƈŒC薤;v?v[_"<86<\fjq; PC}BUҵN5m]Pu|݂h Ptxq_ENUK FTk. Ki TO-Ez@$cxЫ/6p@VbcRMgeaFb1V&C͡_>/y1c؄=K2=R"o!3'CxHe f(u0C4aysSxU ) $<: FDQ+B$sh ,G5 ʿ`}tWc^N0 *k)}#mnKJNE vS5 /^b7it(>HM$W[s#8#!8z2թLkڸ@K,E M\n./eI aN|]%ʧ/Y2(jߨ>*=;u~ymAuz[#ǟl@xc-l.,[kC nkp5R=\>^bH4秉3'K2A:6Q?}Sτ1r>kfd'}#]>Ɗ~ϏenxfZoXOsmrTSV={A7*spqAiьG4n$uRNv č*h]^t*OTR6@9L>a6jf;% ) McnPCWzQi$ܼA ס<5i$0>; ]/G#+VRPkIYHpUqv9ךnOVQ%ˍMsUUKmLqҬ+ U_z,lkIaM>9DH+_qM :+; iBۃb_eʲGTu:iNVp[Mn(Bm8aIEH ֑^}IlGěrDZtRG)9hF2u: x'2jUXL}mMrd.ٰ[d܀q$.M,0(С=M}(CȵS |bDK6AD{u&pXgi}!q[IFbO9͸pZά~ަ?a'![ajPfqp%wŠrU,5S{/T |BCɌ^(M;CkseD dr^(FsV3֐(NpôlELPE/*!p"F<ɈY#ߧ:wnDQ-Uv ws c!_)"[Zw:pWV_ ;tOTq5W_%+;n6Y虼:D' FP>B_?G)J&d}܌~0$N됃cpVq+CppGe6G,f8z7S[S50cq/_9j%tQSLbkxe3SXGTJ@H+Wup`I] >W*$FZlEfg s*|z7>!I©; ao e5MB+ MFB6|fb }̭^A}Vn؆.j*-;&)AZ7*851{o:g7.L7.EcЋ}tI*I OWŏ'as\l\L6F)pm,PEW0dq]&dV6.c~LC(Mb#EnѻPV!ȑѵ jFJ$cu?4[&:1&O(yD~EžSF=RdYfGͧ;\uJ,J?N"{% vN1DLݶw7:+$)Dx U"q 4S+a:K Q*y5!< |ƒ6\U+ᬮ[eVv{L+])xec溰o?,ěX:O9T:1G4q.tтEHԟ׋ nPU7/cXnc]XPayGx.w}Ǟ\rf`@zJna'sNAGPL6IQk + KTD.yտ}Ĝi1J$d= vt5!(:+Ovl<ih^ j,QY?a塺7bּG PMoTowdy㷜6s\ԅR;Xڻ\s~=TDCCij`Ԭ\_$9jۢ_]L8hBJnXjY86؋YZttnUPGzA+TM1ex4A\ڇ2;WR}!0ehyXbKlw l_%L;88jQg- XAJd~Pl+470hذQ@s<ڶ}ZP񠵘c?ׇXN{Ҿo;@[v)3uEz>B?t_ 9GH|ֲjOHg,[$BC栰JOP_GUV'u/{#Kq~|H8pz28H8*Mw޺ Ep !}1{_Zl;u+,fo-A[HMt*9^щa`B>/C0iN˭ʠCH/9fV.6!v@ !wy;m$iH+]YA|D!j{EZQ5'vguxy#^Q 1AP'4RU]x'>t3Yy.4O߀hap(AX|α[Pkv}W(t?B'qMEQ.EgV _ h:DBO^kU| u xTtWw!BQENZ9PvsA$vɮ?-~:L340= PCV9I{=BK yѲTp~p vD52IaEf9-vImĻR vDo8t7}U@pܸEHՎ[ﴒx#7 > &2V6nNۅ6[TotV![ ]w?r$T]n9?OQOUY34Wox2J@_OeKն~~Y*}+rlz :έ>2yGm ),R~ 9e( t3WZID$hDpYG*qn7TQATFZ+u\7`p$SdSKBKe$<fpag#au.6 ?cQ!;di !SIAi7]K1|bie9:2)\)146?gZgr' 6'BT̰?_D[2-8?%_/1%2;`Q I #ǀFB P UwYd>-e@u^TN &\l6\PPfzg>B!/P>8#PV׫KD#_BQZlJh mO'5ↇ{1W( =&ZNt#2Da=B(xing:ā5ջͯ=a:+j9Q=\]VHYe+3L^_]cvR ґl{!}5e8rN&:|r>Uap/S$ o>rP$UoicYe}i124O.>9%I9ZXϏY}WZ (9|Z*zKiho۲HH6-/>N=`0-hx-#BWNڑޱ/ĉz~I{n]4uSظ~xѡ5:I ⚏RS CKXi!cz2v#+X̏ᰧl+b*#@8(E$I88= _|( 6,vzT2yab3ޯ8 6]H]_P赼=a7$[b呝VD f&ǜ+xb :h /X慸%p Wi 6|4JYƶY*1@mݧ(mN#(?ւ9Cm͑FȟB~£]Nm_RCO\?FIMYY>Klr3Ni٠;ř@7TN qL 0?)L 1n0VҬykKHf{UˌNf`w \>vF3@J}Ǩ?GϏ$g#_}}Qm\ävK37 \ΰ< _Gy,g/tBu6Tkq;5՞?gEpZ^vf( '3JkɖbX#G 8?l8K?Ǧ=w4rTͦB֬$,ɮXy|)3%g[׳h N kGd6:O@Ƈy//+*뤕E)_OT?WKY/@@ews"m׉Ǹʲ:$Vr ;{TS($O wnwFY[SrKun]g'L\ND65SiJ+[f4:, '{h|Ng YgVB+FRTxlHq Gr)?UA.FRiSmӘ'%`]4k@DWt7H+F qʊ{~,M$|F>Ǚwœ DZn#0o0  3~ 8,~IgۈB:̓E$gb/r )%7J-m c/F[C҂tjdü!mq,_Ѣc2?jjEj2Hpo9|}gW1jQ>}Yd:_@ F)ĠbPJX0_ endstream endobj 27 0 obj 100460 endobj 28 0 obj <> endobj 29 0 obj <> stream x]n8ཟBvQXO HYi@#WGt>R4uwϷ?oytnW/^}cZNy:Շo|v/yUjNi%]O| _sՖ㆔_cs^mzWmasM]ǧôڶcsS1疹EYY٘ w#rbNsmܳGn@?@?@?@?~_~_~_~_~_~_~_~_W~_W~_W~_W~_W~_W~_W~_W~_ᷚs~7~7~7~R~7~7~7~9w~w~w~w~w~w~w~tF8#Hg3ٶ l+ڲr Y,h6;сDt8. Pi|Fv +KdDTguNm-^F ̸>-AāNą,ua`ʼnALt&8eM<#art˄F{ǁN tޮLvqpvvΙK2=n=azf1OOg$@;<) bwW<}ynS~y.XG) 3,ud@ژ4͛rPvc1Kzp endstream endobj 30 0 obj <> endobj 31 0 obj <> stream xst%o5vvl۶N:ܱmwm۶mn;jz\k=k͚U{S(1%\XyƮΪ< @sW#_BQh-x;\ h7rn q5X,llVffw9Q;x:Y[u Pբ` @linQ7-΅ 4x:X8LM4Z$-m,b4^o, Op)HtN @md2bt6c0I!ag*foO7pp$[:Mhomgnfvl0uu`ҰttʈW_0s t=L,i@$?ki{v6r\\'+8 hni?@\+8Yz13U;60pE#[ _QoN+3uTd2vf篐5?M4o.&K9ӽlO-*_%]mlCUTWV#;_e1r#kdkie_Z|s]NPؙ ,[:KZzM-]L,ӖEhؙl,Ζ|h13Iu Kk;ߧ;a373鿀hW'?7f=&pVMq (쵒o[G"Nb#ί^N8MY p(l3ՊL; OT˂bѕ $V~%.I *C+zn,o8JUUhS$fa>UP;Λ ?O $pltjUguf@,5Vq=E$ >7r@sQlL|//807F Lm 'ynNݣ wmbAy~3N0yU%,)DlY"5SRB.q3cP݇¼j; % ^Rʙ:%F(pHĬkI,Pk:sE\ZQ>?F31j pP5n.+1' ]t-dqy|W*` vE'2nc9)|Ay88AA?&8 {^! $IkxB[\:кS3EQ9402Ȕ  ߒc 0?TdgQP즅ƈ d{Δ*ڝ+Σpe:[KDùπ1녵A_<0 ROWM:ߪ!ѯФy ϪY*{ tѻϚgJ#S6@h.l 4|_@`1}d垆TШ#Qi12 0`hTQz&vh"4$0 Eq$6Q A-Ѽ"eڥJ/PsKz:7= 4 mOf/S9@ww({D ަgEێ?P-2LZ(.I#ee&+^LAXEs6$ طCH6}?Ux2u./ ePp w9azg8Jx-eb ߩbpkT q&`@4$13!~}d@a]΋sq1kTh$hc̑J̙':;w6*0bQ ea;uz1$LPiXA&Kp9wvc _bR_Nn4$|- e+)B 0ƕ1]4;cs\Zs^Lꛇ`b4ڌЎ!uY lFJϥq\Ú !Ŧ-Y9v/e4_ ('.~~MYsݔ=m H}z/072F yp,im$.E\ADLr05`;nC9|Z=OctZҟrp$Ʋ. hZz(:ל8|}k"Y8cO9wќW/*撑4!/=` FZp.G}Yh!ɲl>kJk2>\'t1npU(U?h HFn.(ؿ\d_F!:yHb[̆^ .o~Mم&Dg?\_ʥGx,^UsaWVR0)JN>O>cn.\kɮ"AZq]d͚vI/G)?`8g42eFd7`*LN]j%5ʥe:jYhrc~m lTǯ:ڻh^zۑ:HZÈ*{>-SIIHLj7?un\dzɵg.(!mO8ſ))Nw۔߷/ܭ-T~NDD)Qӽs%/anm3LDu}^xX!P${-w)o3$ La4M*)gju}3S@T%ȓ{u6G&E.z涁g'ra9 LfQq3"4eL96+K7r--4(̺ӭWmZ7'\zZ |(_ԨIqeGϙ+%o?D2%D rs_N:Arnz' JQT:I㰕ɉLXd+|V:oȱ7 mƆVWXZx6lZY<Ԁx٘H^ (75L\)_sIBA-ŭًBR1)'z$%\u~dJؗX+kWx`زTH^bIx.q}wme6E!]Lz.s'AVC `urF3<@0=tY枲޲zxMޓΖ!鰻 I_ljE÷l/h@T'( W,A{SnwebI/D]xm}v/2,_iMoJZZaj5NX Iea(|0IL4kpj$ʬvlr7X84aZw~d:hNnVTLߗhHʚ>;D-s?fT^-w#J39H#Z0'/๭G!~H* K~y:V9?7&vcA*KRRoיIo,y)y*jbqMQԛ!C|XރJ]?)oEڳ+W]( _J_XMQ KBkmζMyV \Ep=W er Q )gL~~sc ҪWX&eՍXl Sz2JDCf25]ԧk]@D_ OM>LoLA[[@N_t~=y ~Ȓ/QL.T O )v/ʾ6t}85n"\tzy}aip#v PRncq̳Oߤ]C㲈n[Ģ/3aZn͠FGRiT!F#*C 9#z-{#V&2-^3T@Mp<ᑺSgV: WeV# bMȺqW9ñ,#Sb {NUWo1aD4>ofd7k[llEWAR[ _A9kՌ6 r =y&gHo/8ױ.}R~G(uQu/UnJ(^H-[A[((5=v6A-nٶm `. +t> varq m͒;EliTdѼCs챎-y7nri$)٪ z~yJ71-NmSQw;/׌(g4l 8U)gʺڱ;׶Yhg3H(mC4"?9/wf[/&o gbs }I{uRIZSˆGK)9y(uGSa< Y-߇H\F㗨I݂ye -3 ]dґ͔EZ_8_=Nn|n "m ]k? jv)h̻u ^ij-+!aq_yF=0 V}Q& KJ.2xS451ʙt[ӗ~CK2FF* 6z/=mK4@|hF /I]8_dZqMX|2sA(YS1lXIXIu䛢TN}, Bnɘ4gR7ݨek}$>Nóqd;0 xo`u ĭN׍{bfW,h:GuZ{qU'4˭A@cOmԣM_ ;՘nߖE0Y=]$]2rħÈD5#;IeRGtmF0Qy(i3 Vm5U|nh}QNh]deBX:\HR&1[t&G ロcLP+ nuh+y/dadES z4-Qن!ԌE$³Dh6WQl =pwe~~χ D}1gg5Jb}R.8 ꦽ6P+\K~kg(i{I~<եoz69^%%^gJH$\whoQ0!C0!2~.Em*z#R0 nHn'3TTEP cPꠚm3P9RiZ| Hyef~(gF-a aRmAcR$i_f۩Zn}hPbE+RW}<+y&oPнENQ#IʂAuAc)G^߁(t$=XOVQ(Yqq8B]}XwxDEBȽ0&|gB~&O4к 2Du`F iA'xٶq~i?ը>~InXximzQN]c!,`#U "F9s+|v_ xG蘶o7k+:!(Aߗu]`X*AxB>LڽxL)QhDٔ1Q+}z J[8szщ;c(7קdB: ( dq%'T'!.ﭮj L(>Cx[ Bkgrȝ Ovsz9w &+PRƨY*_8!Oz:$z(M>v2?X7wI ݝL8vkMx~qT4m^#65ڂkz.$?SWϞ72ӟrV~ aTj[sxqCRݑXtN4j{ֲoݤW?~* AInjL|8ɷMVC{G>=*5n-CTxz*K06zJmq#%,29R {d~| v6m"Ň?)w\"sdjGͥ^ Ast{ԟ؅dWwu>`Y"Sk*Klީ7qJA4=XZr%HޝJ ܗ S} R\WmM/Oofab}k\ Yw谮P]髵O^Amzi/x>R)?=PASN rUR2L\%C'^P5jtKb:RwL-1/Ҫԑ2zy93x0AHT\AI$")}sה]@q*SԔˁޏgmr"8z 'y3HZ +O#ZMbt!Q 7QAk'9Җ[>{q Eǥ"Կ^/<ʠ3qnIZq vjEєvHEoedml?i ݒ2L ԙx twQ; 3m'@Yt-I:!l6NCr3ُT֊l%$ӷ*tVO&ŚuB|r3F#ġ_b7tzr$yUźQE I\xyܖsV>sg#:.tDs~(p\({ 5#{S seG%n 7rHq8eG^8n!TEF}"駛s^ن&] .p{ƺ _p@}=; g[9DOt=V>'ƇLF)aTY8ߦS7ڋdQE3l ;B|:VѬ|CbH_3c (zxCs]>Jjם=ui3 #6C i");Jpw^qǔ&BЊթJONH*9;](2؝{NnE+gvUND|Z5iP"2l'OG.X9Z''"mИY0jeܮjRno:5|s/< k{c^D9cF\{D>{^u)#q:BJ7|G]HGcF nYŒ7Hq|c`:`\@,UF+A/L2t6\3NKLxƇbq~7xqŲ%pm P;Yr T-S74Ü_$ANr_d :5InF_j1@4/Cc۳ sݏɝ4&ʨ;wsi-T}c8J-\'ოoʵ )'ږ$ZUhZsC/3ddzǪ;.gbp1 JP0ZF$7fN{2Oj=󪯻=` ?|F8nsfHs=_V΋OF2S0p(Czfdk&}Q ) c8P/o'`eE|ݑްr3dx2Ze~ߝiMӄޤP/Z+6·h| Wx16)" iL@K WQ7 3ZyWa q;77j"4`Ie F^"˄xY6߿=[aZ GxpT(4_?oZEq8Wzn$al8EdKӱ^o2^; t|>E% (ilDso/K*ԕYjŘ#J23z)qh6)&lg *9}J&99B?}IN6\$60]@`ꑘ)=RI)uΩa~7Q0eG뽮(Pd,Q7DDkmocWccִmDDدe$Bna+[)$|Lo: ל\HW#?b??`}/Wp mH8_e+U, Qj1ԏ'F8M S LBP i*sͱ: v߷ Di(Nb1]hBcff^]3Y ~/es-C{'#N:i]jL%w1n4g&=B'YA© ΟVqL!#n}4UƈN5P}w/U|bO&hn-fƂGe7—N}[1:T[؀]f/R^|7#qPy|3!DZ찷'=2:-,1{sqKH  [4׳WI8鈡êmW8[[_ &և:!mYF+kѭC:e(h Vt fK~mDDw=e*崤ftʇpp?Nr[;NRS*e-e;*ցA+|ܐ(aͣ'iZIj̬_cϸN*>"^.YBTtwc)=~Lqƽ9J7V?2LY+Naxk! 8$!Eܸ! f9}^ |-M0+.bXԦnt H3s.GT lM_o!`9qʼ^YJp꼈;"j>jWgXɄoQ{;jL8bT,r~H|%i^JBEt&F5zBj6s(? gڒU0 n~āFGunRSl ;H+=o R.iT'Ʌ*;?0) bCѭKQB 0 tPόhX"Rz^4[N@Ced9\pɈ,WyuL77C)q^.>zJU(s͇Ws/!ojy}c(Yr.SX0HpY0}dS%"y/Fߏ}DIòvH48LN:">q7)ްQv)X4_ӐгG12v.{Ōs8gysBSYILULҩlW2BfCȤlbbG#ԨTBQWD{[Al'Taҫ?3b='yVڋ4TI"le &uA=RYntآ@+恭K2BRq^b(vya'7ү:0@ȇsbvav6TAY'Uh3(z 0""_u0.uËTL8g=^G"2/b wOOH9cNalB\ˁk%}W$vڢP2fdy3=d̑ANk# sY 8~{M٥ l}g_U<ovC9=)I'eJ\b V8 xpB^Ѯ:V7[>X`QE3(:,_^NsN/,-Ȟ#ݚ~u蜓15zIĐF* ՙuB;f?ׂZa+EgOX'w?8=r8"?Ɨx{I!|Gxd6KS4.ifmύLBYv3iomޏD`sVŖ@7x'>#ET*\ahG6[3@Rϡ5;-btvkXޘj5tZrroY k,hЇjWOH "N-$?FB3іM1(ޛnwp% wӰ{b-,:_Z[A {I).}++usEn\dpOixdn0'+N1@[$۞~-Qno{E`B =Ak5 g"Nz<έNE^EUV~B[3K@hѼ%]4Db|AuE@[wrc0-ロszyG%'"Jҵ4-O7Q n ͇k 0m ?}C-Mq阤+Xh3`1xTqh}Jy\f_Kqa'R[6!-bq-$%ɔz}y'WšQw3{Xjv ]{trɜj3cv?X%͌qLOyEW),8*) IYG)VRn^^F{ǹ/V̶ @~Dʘs}Lsvʓzhnr܍;/e㴛_j to:k;:͐- QoƷ P~I4ĕ>hW*&THD*UbÅtDSg] LIUux!=` C{{*]Aruf0vI{cCƊ&hfo>뇳 >M1e"W7n^gOpa*^@|rQbsG'K+j5,k'WFG{N ވ=/us?ǫ{"< ^s/hύJoae^I,ԋڈFgAW#H-P2 LDhӃLJ5}w$$ʮھb4eѭZݟUdpu}PGy Cv}.u IiH}خl[.)c?ßk )!+ͻ+4wdh!]t[Vu7~iyǩpl|2 .xSﰄO^y^TJ4:oxWrl^w/i/ա罽i$%9~HSacWNyYN̈$ ڧ8ǁPl)b fQxղ<>-I""W%SqZ+\{K$C-{Ās)pL.`9/r.(+ 㦰UΥhK#`"eJ~>"}5EIUWQ 0U*aPGv΁_E@Φޙ7+]^Ez4"1t5sn*A|UBƾ#\PTHGΣ*uJ {:K~@ZJᏳt鈩[J𯳝7Ɏ+蔨˖pE(&A}^) ɇQSJ!ȤNBnR4 /• Cs;%R#)?ѻNS_ŲMQ|Q˴O~:4hl${&/ƠpuD{s4|]o6*{ c#e*:ivt:1wr /_XqyTTc [l<`ѵϘ).\u֧T|Wz9tB~~'~U\۪-pF2͊po W @x n- N¢{K 9p5a ? 9JcDu#? P yQwQDqfݳ4Ufu.x^;9ddI =y^|D:LET@6Hr6t]j *㮒M+v[8[=a"Y&&贇4Jظ<:@_|7y! ۊR$s i~bHAeS-:L' %\Sى SH dٕ(M2HgB.?'9t,YhQ/c,&C1S}yz\n: GS UƋ֔QS$^p)众u ) fFԗ_s7O@AںZ=&S0'uו^ FEz C.Er„'Q>&}GB^#`fm~i=*RYWEJ#ay=KnkU֚c%Cb_\lg^X S$CBKdCK!bqba2 խx,j<ʎٶܭ4È%nOCk?dU|ZI3ihA% nDkOoEf!TGv1džEes }FY{4mCwt9ҥ-\"AbEUr rY/MM QXo 9Qڌ B2tq{?VŁQ}Sqz .e "u}Gq<)ޥ Nq9,%ݻu9"ݩl"+^&;dU'u~ڧpo(CrXC{_6i[ CuHknBk>/SI,V"Uw{ Elb6(]ڇfP 5-^|/bCߓC6YSu7jrW}C:\"O@ 5[{!pFsC>KT0MZ߯e_'<!M[}YC]uR1yBϦӍk+hQ=H$8; Qu˷|y@5U3Lt 4"hXXc>U?f/yFޡΈmwS#JmlPpz `\RrH&VY ?5 q 1f9ïy飈ϓgAؼ>Bk^yz!*fF9S%{mp<¨i$h'eC{$us`4̮ YٸRtY-.CC.Ƌt@{( cq}f*g>C?/nUCc?R5/1\,:1mpz/WzlBd#&n į/:YұM{e̩D9ER>Km߇ǡa?uH6 a_cgKqwkW$;d!^~VDozH}C;wF*9d<ҧb ;[QD<ݔs@auu6Doj=(}=g=S{ Yd{?sg V.I-P~J$Hcns{sPYÁu%U%$J^3(w"3Wjt}.o@PJp;$xsL?qYP%3Ҫ>;OY5G^HDTYקޒ ,B(B m?*۰^a S?sye 2Y2_gj+Uݘv&pn.l# s{kۇH@_qQ'ցbX}<" m}qЧ0Ō3!nx[J#rlk5>xTvO(s,o>!,G7#1йq SDq7i[\lV"MLE(ʟ~/=$wӬ-/ X?zCpo0nP5GJ-saw}D*oS1"eHEnkl"q2i=ɌKEXgqO@{b䛏X ¶+ɩv! ;g9 l˦i4zg_{&P^T ݚf`g~;;.å̸G* \vn9uå2pb҈^QG\_\ԳYhv1\qC[LO <\#)"ŲU b4S3lIgc2mlf&f?>s D4AV<1 z wA0kYJ&Gʕ]tx>2JW ZE$:繩dd!#}Z )G_"| MLbM\#!ׂT;zw awiCɂu6 ["ILvUo)(Hk(8V521នWf~h_54s8u@XuGM-e rϳʙT"%Y,]zj*#}݌LC[xJGǍZ?/42^(rPd`U]9cn_5mmepP_ZX|HKۯ_ւB<~`:D2R^u'rg3݁FbUv`{Yll-/vapgU1C9LPdDͷww{c=2lfb<]Biin9.뀞 7ۛt*z"| a:{LE]Y7=2z|:]RL6y-5ٕ- qWVAɴNĚTEG2?yЍ{RV( A4P~4n4Q{ `: iONVwj5#y=rk=/R-FP$s1Ь꾍bS+ %wEhXosA%Y5lc:NXǣ)F ' 啱 )h1l`p^ UTG ۶C8|fXv> +D*^ҏ֦.X peP'7kNh%?wE? #3_&+V97eG# :Vv/8R&Z\j 3ATܾJ03ܲa}dc7ʄuX줮ZYR?O~?O',E; .?砣K@NOˁalpK$p ;CU'>È"["e%˻Eاz7~}_3N0\,k.q{!cTH{avUeh H>b"f ƖNp%. zcxQhQ,d8:++ZfClSpe֙Yuv2鿹ANHd]I8鷿TѕZtH6 ww/9YTRn%[>g3Sb ;4eR>Ӧse TmpVĎ 0SZk bRT" ߌtqy1k?:Nn8$MPKMtTܱWR ymŹ;h.4K|>V-R!v:h!aC'ydkRxIiP93${rcd 2ZC:Q  fOQ|Fh18*KtkG6-2d$ d3@`dzOΆBrFLR?#@e/ "YTm KRdX8D\D5⏟HL\TU P;oC>GTz1s%Y29 vI Wby/~Ꜯ!~Rx%*>d@hp(CKKT#3qТS{jij3C#;B:w؉4XѤ\ɏjYjd9Ft, МtҰ{?p1ft%"Nof> Do -l w.&We9hy#UP6DGlpnL{-* #jNT6dpZ \X+]w *2IJo8"wŁ6@?Nʟ7 T A}R9ZbZ¢`ba]aWk"5'M,w%/`G)v; פJPOVmb_:ge1 @&I`Xe/Ů ~<cj ّ-InL"8O 6 NrM11?;L_+(<)BT9@`3|A,hl1h$xo<႓&e񝅞l"5'rNשgEC?c2%n]DEz:is) M #eK X́t<7c~ˉ;;  CuB\G- e4⫨ITmI)i'-%{"hydV~&RCFywӺmqz}ᄯ步[OA`rF| vifw:3^ĴP|#I+G Kpi %9g t [).A$IJ/eOm sCq㉺8ݺZpEEvć>513bE,KE,_?h6Pc@I(2HMw=;!GKEz { PFhub]Oa !>\Phd<4e&a [eB_ 貒duMLBdU2je7)w=#=BI)z"TV5Ǟ%H3!v'%H-fo(nLkzWgXҪQG0V hlS[F?IYFwG0a?9U( prLx[h%1i$x)JcJfoCWc fK7ެگK=z!]kڌZf_guir2(_Ys9iRX$z\iU wyS2U3>GNB: 7+>\'M3]Ř~ #&@őnh._̜̉ H1%g<_g|u]A+zBRNN]~9ᦇ/8WW U6-Y2V,ւp}=0uos c"W#"mR(u?k!!Zk>dUF#ޙY6]#? 0e)d*z5IWzw;h$eiprvђ F.g4g,ǁt$$V"O|a]=Љ: j<8!ﲱEZ4+ϝ8<$΅m_OJڠ΍ۻ~%= ]U,!P o{isqК@94KۇnsM4 zPC !'Y[ӊz!yY siTF z%Gy+ F3;sk' Xf"|H`fyw=us/_0RnՃ׿#ORNjJÛnVd:5 B-jYQpi' *lOýTaP7~d5Q$$S ӈz$b-xv=_;2՟g <5U^|1 +8kLo~;B'KIh8ȌAʶ)$&jV~<[(1-xjƺcPc~N2-LiC7~ }65Y8?|{Ƹ HR.kJٽCmhcU@`]iXP8j@y. ˗h=Rx5?;6Pjz.xp!v̗"*yҡo6T8ݟ,vuΦ$WcD!KzGErmn$ )TqY{֔.:;]ߟnt~Զtsād#T̀ e>@=˸;S|āsЉ/)\{&A 34K>r>\gmpb'0=Ljm8CBTp[`48kC,6D=㖦3v;;n R1W.'ŦcMmJUhh=:vLxh^~CU 4*dN ?$O_g PK\{s!(=ŲT-54ISZ ptF9uz*QSjUРLW|.4t(e+rvn37_RB9JE ]뇲,I+W]Il]Zz5u$Q ;&[~<ٔD)^Οo{,wU]5"?%`ͱ9ȘHRV__": 'T~aٖu wWbH[lJ.; & J|FuR}_p \s5ۄM5 9& )*GLfITS{g=A2wvbG1Lhbx&eǖ0JTôS ~ oX2( ZFr{R]"TZ*Z[ YrMZBo?t@DPzgbPfbhIBI28BmULr·sel-]t1f.,Fv~A+;1ӓk=| I2qgscf;"G4%V= .`iUfTQr";_~W;Sn" Nsy݂mVϡ1Y=iND(`2c4$8HqRrv 3 9zNh_|^}0x99% ׍066fҟU- S l b){} 9@7VʃڈQ+, ϟ*@* =7t/YUU]h8%nA**>ɒInh3ߘ@~K(m{f,XW\^ !vk7U[GJ-b c%㐷/qonE-ǒ2KCkq}c"Oko2^IB@بnIg͸Ӄ²k lA vb1~('(i[\{].ASŵؒC*YԿ$,(nVbzn]&O[ z+IʪWn)p+d)tm묚 dnC]5$lЉʌSk v5]$a@^Hbȕe_1=BԱA+Tܥ{Vcbh+O }ݤjt#΅8 g3À`ƈz)+u?27Å ??EE2>RusQjYWJ\Ӧ54 |d8_&PbP \0y;FZ%V40_ X QcURb.jqq!fj]cKk٬K1= =jBy<)%j}eЀx$вVw3+f1L*wMSc|! d'+(ֹ͏)r}3<h4 {;ʉ<'pi*NeT&_)E`^X [']_Idzw+tH\ |9kDŽZ2#}J]y31IёO/tQ^,TKjeL!OX2DQm1uyLPK^-;&4FWw~f(B5u1pjw~o 7 L9ZrN؝xI`E28(+ sUxH+_)*- qGvJ| Uwk&g:6rq>-2NU^9 aܧV}Nkrk" ׋?Ž6/>{|#*AwP}~șcZ˫ufU%oH_E0uJl8PAu"^r<:ЎmA-%y,MkwB؃R(*O,rNIhՓL6hnjblbEe7dT,)|xv/T4ILw=P2P3XBO+}q໐J Dw޲5?Ti9k p.Sr_筵l>\X UZR_;MPdAH7%?sIhL߶\ꉜfq؇aGV#Cp>,Z/kW$&ZyWKAʯ4&hwhexN[Ԗp+X qݏ3SII^m8x C빃;Q&No& r8&B֣ JP{>=-;$Zj 7I+asCglj ?fv*(ʫ H6"*憂@d452qex 1&ט)܊*F.堶u9>K/sHRlՏ*?(+@K:9TĉÀ:g*f M=p~iyKw#'>tבFFO :C qRVde^. A^b&8B=RB{cP-o b{g=Kcu mܲ/~B.,4YpѱI,3C9xIGOZ>q :EfswW !`\xHI$1j EӖerx2}&KGVoLˍupU 0^|U:`߰~u/:oWJyw*v#$#M:8;);R8:O3\4l;52lzda0'L@s{{zm=.F5{P6& 33 U0u Wwë;mYŕw Ca% Qj*y aLDXt5˦7NYU?)WG[}αPL۶⥗]b0l3tIBHقA5#賰W'3$yT+wn @XR9MFocK&aZz Znq/0? d I 6beLbvizp/1Lɭd$%y ϴZ-–R&vMd/hzk!2ĭkX!?p*xh1$hD j]MmNF%^zp쪧s1a-|Q 3%6{d)T4GSp^>䓲]}LUR~kpNSqD?n~|?҄$% p6w"Zϒ=.\KI@P_EFMX`W f"H:0L mF)` X2̧9 4K>b"\. XC4t7{C17Ĵl֘Ɯj=lcE %QV dx<F.nC Я4po{)9+X(%H5Etb1gE${gO$Z]TsּbV540ɖ oU ҿZd߭y-4Nx `AH &hI61S`Kn3)AbL"0~\&h:K|˥ ^^~!U"M iyet=k+&߉[.w\02&U݁. EY~2h<:&,nrfVC)YU cqZZtIQс**T^群6*,1WwKi Z5e$3]J|`*'AU Q[ ?bdȔ&-TM`_o6š!\z̟T _bބXIo3juﺇ PMlm!#l%2)A*;:Yb_3K>=a* Nϋ4ȓCkT.WP P쾂wc ǴW 1qSiˬfVa7ST* vc_663=wGftBZ%tz?@xkl?InŃ]~#nq?Q7*s c)\fqgcn'|՞-$XhA|B#V5ѺCk1EPX߹͊8jxOJ)A4;oʹYۅY y(Ri5T=l0cPc*=W {!/&'%JirW*Z r=WneذX׫A?m dn>❄A >"{8Ox@~/kfL`"ui||F ym,^6LZ5Λm^L 2eB*q_I=;zGK"Kcz0E'*G .SyVdN'n^ %+ o_6,Q=I߇ j)9cIuW|YG 9#b_V^(^.3UX6yT+G(pzUgϊNmG(6*Hq2p^ǻ5.%vEA)摛׊=BkP2,j,EAdR2ޜ(ni(%|yI9'XHM] Cw?$`z)2ysqvRbyF`}N_dRݍɁ>p/]ˇ2Q^B%-1}vӹ!b dQx, >nGp&4VaϏ",}6L@lKo'7%=Pa+$KZ0H9tJ+[E7͎bjfd\,sƿ蠤eRm9JTUʮlj@\?a6R |"KlK=ǜ 9Vrq QPe)\ Fy~99a8sڨ54_WT~ߔұF%[gPDr| 8aӊв9ȯM5ː,Ȕz'ظ#![&7~ۘl 3O3 ^ÕW4G?<`AOEM-1 Uԡm~>{ye#쌶2_E *ݫR>If w;pœ WZ[ ,A_[߶:I췐&q[WUWAQ+.[@e{)C[3/=?Clxhڟ=L"WRC$ˢm;e?}ڟur? if|ћ[kQuIgKwmTJ,T=ܘ. $W[ZSfF2ԛj(Cӽ $&rJ\6]x'ٜGr^ˆՄ6%L"QGr] UCuJskY9P̬V?xMˆ)ѭ[2PΌeJEg$ PulAKxH;#<("p7|#v#9H x~֠cvBGB[0g`m5N7%\ P1L)]90yqdQy@'*ST` ݽGo2`i/`t/R> \MgkuDeN?cg>퓓v,#TԮ$Ҹ]8DȇfԍߓUWSUږA`~p+˾Kڤ4r鋊PPpd ''s՛-㑰tms'/҆)9ݸi\4DK'Qǁϧ5eU⃲o)`=)x+Q{$f#U9)8t`K87l l//Ζ\#J&| SPF2A>N;Q->ua J¢ߝdXeh ÿ٪> 0/D~D0دS tdS_Yk璓P`B7(*nți73z`PQ0w%$)ӫ@bi~&A+ vꚕxdB77hO!%ZXM| ipX%oK/3vC^5%Hb&Kod=43U j64ϭ_{8M̦,}.E&}kFr Q#}/7{4"/v5ĀV ~/BƙXm znJt7|[t*20~+L{2a"SG$: riϮka>S{ Hs/_p$)gPQ̢?!f!t7Ϻd+b wN9C-X8>BKPxz׈w::ڄqD{< [uQ]zN- Caf=eg+u3 iP(_S W}-.ΔD$5?9W@;4zh6".\D!=Ty]\ `+ؿ opX>ǜ9WIr05 sԃáqZM޺饈JKOxNlgIZ!'8Vi҂3"8IW$x$ _\z׶6 N cdn=Hcܒ!|i<1 q2gؖ%]}&᝹w6a&!c S~kmf紸I1 BO>rhiv  YuW ~zKjމI>P+E"4~=b،U6V슬;d9^ʋkx~Ӵq~TÍ_CB|rRv:t@qN\8\[A=ғV_x?rݷuXˮ.Д+rpw+峦;c+po2ZRgR30OfW lJ&vavLr"^wft|9S#R&MU 9`U BtŦEz,6~<&*[ev?ZLLAfk ?rM`R4t/YU#32ܷbzUJ*@Ht҆oW'uUokyY? }X&xͱL39dN{9.¶Ͳwl3A !R`NLUM[((bLRUNtǰP5a> ZTLl?j %qHNa N/OVC0ǔo ;E<`Eșqew> 0Zȵ% kW%jjk=}= Fϱ)WL%Qм0XQ7@K{AԳ[ջt`nV#Jk7_ VK=qXg|M~~HS2d*,|.W󳡻m+ $PJRm HNpk؂oNMN8Zo pp3ҡ #ukށt/Z`3D>Er}դ`-,HI>+$>MA?}%޹vu 9wۑWqrN}ۇSp)Bj80x5"x?/.r{]*t@4!bG4`^N9`'`/Ԛ>ԋ\([ִX*Xph29+"}& A(zOSgY&OS'w e@¥;WLƿ?×~&|O\L~*bg>olɠؙ+H+#R0-o 'ڠܶB]vD slC83뗩gso?g~5Zy{`*S$Ecqx].}2Oi>lYDAGPaD܌d2@,*qʅ+N̾./+O uBϦ4;՜~hY*۹2m945;VFɩcͼ *UY*e:s,r͒;9lLjCܞH1X@fzM;.:rfI_mIMxm"ԑL(483;s[~_10>9)`-r.YfigE-[ۅcN2OyC90:(]sr!_b-堙#nUL5rXaYh]O eX!r*<}Ku ).궾n]:n:m+'3+N-Q\pAf2iefPElЪCy\Ug@KUV׾Xn;#-/ v2G6x%%nUX q>oQܲDÑs@YrYT>=(Dȍ^\\!"^~CO2XH йxX~0Ď>^ qջVXSC-3$DҰ -|S =*|#s8b 5E+Ќq/XqSV61^JS"#TQ?;jpnwʶ8+BfB;D_l/SH3Vmڄ x0ra&> LGDw; GR?0$uJppM˜ĩ Zr<MLXTMQ&]˚ѩp`I،fs݈J.j#i'P]EpiX]sεNa6҅6O{8b}_S$ Ի/:f(5!ߞ$kw/C gK,*_YP=r2Gf]>0jrMQ^c NSȦd~oo aȰ]SUĈp6CwN~+cao>pnmbgẉ! [ŎA{d)ǻb*w_u ݊JJ~e{t ͞2`qtV Knf'?(S:Ncx!RR7} w.iS`?~ֱI7xF"U.ˬfIS#q@}%A!dPjPWgS7΍Z Vxnw$)O`lKT?)"P҄TH thF09skK"n $g$;9'E%|T%/?ϾfD[Fiku.@Ecd[wx^Ϝ[T,p4;+{=p C'YAvAk_2W|6͒0Qe 3S螩%P6BbpP92(㰧NҮ;b%nc,[p?InpKGK;>(DHfDd`k6C[) CnnfeKxtnm൭-߉\t0q4Nxw(R.CW\jΉ€ J!Q\ԫ iṠfMeLAUQ?-܄2!;>@ AT݀pA7Y4nAD #6KN g45Ӿ`-F2 dl.jcY[L$œ@z`ϕd_Q_@ S*@4^S:TR}1}?#眳'YO ; |U+|j{.X3KK楒z~4"s;@GA_]x4v1)6̼dc/gp`Bj9*{E;=Q8b7z8 ;|.P7`/Z=e4,PCԌG;0-R?8R(a}KGqz(yeO>w% d^, s%wIB'գ *o+0 G9>:#5cUb0z eA!t o 󠐲龐KЮKp2׵B T~+N#[|+SOs(j/#W*CLaӞߏR}ػ645*÷]cl"%ֽ{6MD= 4#97[< fWbyPg羺68Z~P4ƮOKGB>F'N7D{Cϴj'D/!W,R bWvKѲ`Sو| M( NOӐ+ڗÄ૔Xf%E ,7ѹO $d< A-H8 8TRhd?ʸF/!Q\Ldy!\2@iF)2t@#+MHYTKW-zļwzk# Outo`}J=yV[ɘ^9TQ?8/ϼ꺚UZu \z h&[ z]_9h8>ĭ^qVr1鯝<IPwCjfNi"­;R P͆d\΍T{#/")xu)iTJE[MCY 8OqU\us /}M D꧃# >ģL*sj^~Z$U;ȅۻr :Jy&~9y B{{fj\l01 ޭHI]7ԯ2ER'U\q~=d6X#$FG*I _RFK_@3y%#Zkc!a' r"ϲ4Ԙ JU뚆ym `ܤPsM*PQOze 2뛾=u±RlC/Оd0Q}k)+G"e624)ϴz< `$b8ŏLǎPI] v-}Y04j-H74 /ecbBýϖg"~,+EpO^v`}tq1z\>t71\EbAH4sȴ*=Vq܁ծu !*U>`]agE>.м@ N:PE;Bb=\#{YfЏ ĉF1fsd3#En0Qr##5*$&*h_J- գsigoe3tbȄS| ͛ʰDE]rԕ~EUvy: @o?׷Nw ;ny3kZY2\jm9~|tA>!t,[eH;u6"16n=oX=Lt\G6& DBEsN!f,6|rrysxIp*% 9Ec=L3:]}lVi%9{ Z'K  {c7tMT<0bud` E Ļ߉,ŗ6##C6, Yv|a̾CUT6!۟b05 r]гmoƨBLj,As55MT+p$AҜosc8[~p?1Vc?b%*U/}$ôt}9&=yߩK\.@Wbb&5(?韄ʖ?e<.4]k%:m\Ayq}kW##ج>75w@> oy̕xBDHLDXۧ[G s>? NA^\v&: QWK%zXW|ڒ9Nn\ځ@\H Hw --|o?m.#ϛ+ʹk P-lM;(N|fֲc#ώc)rm3Sw8QCBڒT ҔE{]"do $UhKB#s}50;k0ݑRy96rbnև> ˋ! 7'v5upbMwas׀_&'X$cN};,yM1Eg bXM컉WoɦӋ% E=P#jHh\yHj #~~g$R#eӦh3Å;IFXIFnx> SQ6MBЗ1#C Zh~֜&GɥL@f~mEژJ"1%b=dp_V64WDw|`V؏yxOp Y+ܿ]oBD 4zhD.4_s01ҢxeG[6?=UǹREأ>d}_I1@-~5߽m/y4T1_)M Mg,#Yj'qfW>FWXcZ~*-igfK=JM&!c-TJ!Go{L*n*7L.yc`E>:IAM1~B*@/TwAWir+[rJ&FQtNM"㳕6 A~8a&ςRL"iʃUȇhpGYnd̼[kMI_1w#11I'tg캏ڤ!x Gⷬ>HAZ/sT252 [ >0>& ׋1uͅ+(}*_< C NLTݸ dxxQ pZKY!j!-:ğ̢8ӊD0qdH&K?~g5\*;ƻq=>41M̖l A_Z hKg!%K՗[躧8FT1 ?gHDXQ0DqCDݠ[7Рc세Bi۾ȗ!\ye-ֿ3w/mӌʷZ5.֘"VeYD'=Yr~1MYߏ =сgKYSℍnf'qW˶j6fTNnya\Mg!daW Zlb{U5 ĵ?=Y(q5!̫l;v4*ٮի9S}O۶CTf|eYlThj5`ET K ~ځtl$TzGZoD2Au:՚,Gc;9?z`N:7|upgM()D?lUhpɊ ^5F,Q^\;(xqH8++^T/bQ/l*tyEew0kl^5 }l/_O$C\8UC̶冑Cސ._YԌfS3YHu-+ 4FÀwr `.qُqFOA0sעP;A E?u;6 jVikKԻJ4"*@\rpr`$CLƐ$eܽH.4\rBoxϢp3"n#J3/P_VC$qGrQTeP; :ٴ9%ok` nR 'Ȁ Y*  {Gcj^ǫ GKb==6\?3"nտt߆؀ad5 G8t0 uqI`d!|u 7ҟ7TNr#C}\!bm%cJ u&%\\0p WT99Hگ H1qs'UZX +a:bx3[ FA$ J\5y=0ZܴZFwi;|39{82v"q.DufaDJf׍@u˂@#+hoI?=,IeXSpxvj\Vi7#oEӒ%!g&s1z|;Q E7Mc5J-+m9ѻB }ź"'<רFr0#2ٜsΦ>%?mOtkRO֗ iqL$>}r[R I!֯a?~@T؅h͔Zz FSDz,L1/`UhD>W)%^d\ 5siyĞoK00xb:SG[yxoe<"| jbl%@x$mG5`cl(Q̺%XD Di#ۄй)vA)gJūO .JE䇡=@H^;cY*Dm%f XXOGeBY(+3?LY[Urɬ7It}b9=n`g[7l*d.Aސߊ!YƐ&aepA"jpo W*-G*^+PSVAd4+*"{],c|򹨵;_m{Ji6U&H?,ۯipt"ڻy6hA*+=^Ÿ9lr,YBG0ھ5c|KԊAjNiG(2ASR05 R7DGv+/zK>{SgP6r.0 #FkSO=q BGn*GA2-L82ro$"q6=R|H3P݀ VjWsҭ1gIt4ԊM=X5%::HDz(NkC;db YQk~gW&ϐµ̉[UV7ѴHA ͓­|0$]ߟ-ՁnI^LD-|}%iӤBttM^^|IYwEp{ũvavɰNddӆfa+Д^=b[c O:l#fͻ!O"O%dc'0'0o8 h zJbZHg7ɦn 05X#!mO:w&91:VtP=8 檌C` j"&5۱c5=IXQѣ.! p8)OfS/-!!C/ V]ɹΡa3+2O0/Ҕ?OF,{#!Z,VwR͎F"HIl͋DdGc2F< 1|dC=h&B W'Y|̇H*ˉ0 =9'(2^-s@g5> .lt2m!Ld˰~0}>(-ǮSai" =f/nED\h[8ruXӒ"2S0'Z3t 16އLs~;ɩ k JI׸w'oIJ+5%Ok票paJ']ΐçNY|6gC4` z> !CEZIq@u± 0dtK8$HFJ0F[˛ͰH( uήo/4]Da^sNq*ZQcAVna&D3N pWpW/ f^ł֗[J/?nXy hu sE}6ް+ bQ+ o?JfU~Чj+x:{OYHP[vʮXxڟ9iz5Ww$8df93Ôc9ݐ9 RK&Zv@'DlHvL CcfZְgԭM2 B9C"m}ǯ:d!sWŞ؄)fY aמx=xLU\v1gڣKOx4VdO$1bV?[* V]zRݙ º~2[K{#i~QKZ%qŽ(g;`a{SLc4;ixWo KRA8ί>W+gv5)rllpn ew'z(kL1JVK!]#ތ)N8lB4_()K^3x?:FcvIC $_HvJ/>nRr?yciylBR(_ʨ`۳Zwzm,-JME}ؓtb6aT0 F| COH.KEX~~GU5aH23yv=LjSqlӤПH KVJoK:=0sd)CXW CJc%,{AkǓ!CtF7)&,j;8y/9u۰vvy;M艂2!Λu숁w~vەC~uB趶wי!0_LQOPƙT͓u+ 5+ !s 4.|K}FgN9I"'dL7>YPm m1NT"# LSFpF P[+mFU$j{"x?QG:}g9螐Xt^'moE/YI<՛nn6i:۲SM2;|뫕54]nQ؜{U}ȁ-meK* U=7!RK&fE:$.}M)d vKrڠ-+0I0}c2?-mp/yF7̅漟_GWBjA ~rɠC7CY_'dQȽܳ$l37g? R[#1Ӵ~6aeL|9K(f{Q*pޒ Ҫf/vO4 yyǸ3w'g2#&s @(G&B BD-!1br32KD@Xe(^'푪OQ|Δǩ|8]r(PT*V9sXOq*.!CP 9"O2j݁kKNy:6dL=:H%.kTm yqbg* z* 6ui+vr#m(Z'|pPӯ0 (HzXWKLtq@Ŋ!2Mcb[W6Ee"iřP+|@@Vy. &}sC+WoGS֊"=BIًU{/,XBwM}=#?Cc/^Sճeli``؉WP1K.h)Aځ\oi7(wV᭗glɡqaD tHySӮe6OqFr$o~\WAfLu+[=(1 66!`h+hG1X0| xA%{XlyW`9~-k/͗?\EFSKNЏڃq 54>,ñDWAt"v90RbRu,U*MG0Ǔ3:)(i%F::j Bñx*DtXn7?/3]Ŀæ覫j;-I[IuIPmO8>+~?m Q"r|QY5gc_w,EMU6I\۔DBrc""5STm5V~jRc i)+wz7JXZ&+ h0cKf7 q O >IŎf/]gݔړ8 oXMh L_!A [yK/@ڿB'iIW#xu@fU_q^s[U|4ߍO;{1b$[[5|;1}6jyPn"8~,:ڸ݊ld荆~QL%-'u&.g n g/%]Pka1Vs8uAYR> W4َVh07lTsq5'v.wQ}j=R~ԋ&0;p 0 `/vDi`1Ώ[qߪ~$lj?7{ۯ2)U\i,RzHޱƍnm%8!dPH@pDM;ƛӯofO\֑Zޣ!7x=Ql&uKh,Dwc ]X˺yFAMZg T2txu'x q5A̗4ވT!I3P+?U:+7 IS=tO#n,˭\6z$A)T`uEPvIxDGQ@YGkyE^W~Mak4T &z kj;Me"0SԵ^'55leZ& aؔ\cVВga}P+M#zQ)Z4HsV@ w|9I |tZr.lqW aӽ\ť"tV!Gpov?iX,H ;}fCS+sn=N#MZQ-XXD3LB5a-@gZŘvr湝NsoPdj1yM"E6K͙d;#TNŠCV'YD[7C־^!Rsb?]1$a'=YpMC۝=ޟ;*ƈ-ʊ%LNm] J@Eq$V{76m}#6C#G݃4#do~gfvɋܫNr_{ݶL GAdzE֐d푙lA}bnܙGgR ^rNN fqZrLp -N ǥ Tp:!7y$ךhFS0jڣ68"iK戣[lneo ŸPd$.ZdFPJoϠ#rpd  iZg+= zS "HMx8E `F>_ș::|Vg aP~hcW(g;ʘX5D։zNlyj-uC[E2^!: ̭pN,;(xJ}A9̅qPj퇽`ܟFQF5{{*gK޻WO&yA[cϪ(ΨVsƑøi0?Wϵ:x\ZZi:{DE hԺi-RkJOgpADtlu#T6pчEgZU7X7ڐL<[fM yCX,_]PS6,z4Fݔ<Ѡ˜vHXjѵ5 ,qIP.Cj3yҔF/NmR)A-j_,މܐ!@RV/#*BCxvh]12nv/Xp ~ʇӝ@|0pYfbm=0 {u@7CsXZ.SFΖg@K|$*SK*)Lw zhv2ܢ ǩBd{ a\V;o^}Wfp,A1SV`C{9:3Hx֐z/`5JD]ٴaZ"?F`]OӢx\]y IlI>?MvUVZU/ET8ws JepkyIBY+j8yrfYa :BؠIsKo*\ ʵܢ|/|rbq|1 }M+g;sM.\a͖36ݭXd#w,3>놎3Nag,!2Q=`YYe&AS}R]>50|4BJr{:v:'@ `L3`O ` ͍sы>"cAU^"?C4sDoOnKRFeBuD%{ ؛pDY#Q}33?WK2I7B")-! Vϲ}pI%9YΩ]~@QF#pX?ivߑm尾72Or0Su;c4^`NK4r/ZA74,rdYOQr˨{yi[[%tл?ٮ4pAo9S_F>)}m`Le%=]"lތIo+.O\^HMT u !qUKhP撰| g]:GrLVxji+;p昋8ئݻocH0(ZzoxBS*fѕ%?Kp!{6*58}Ӧs[GVlc \~ U-| i?ۤ.Jq(Din$R3]anUK^׷Ewe1"ac܍LnܤuУRa%4'[Ro+XDn瓓YBgCz"T=6V%6cw&Ǩ E`x=7uI<po/z +>Ux],0[t vlCM ؁ß)-X)ANmj1B@K:e8(]H0)7ϯԧWffZ[:EP)O6oȿD~)`udL97׍IlKpH%|~75NaΎ)g\phmH fSb p}M/u=}!wfG+q-YFYKc'&2άx-XD: -XdJFivl֚ĂjɃ Z t'Bx$C̒^47q ^r^H`ZCjh'`A)ih;j~!翺;c^ ?S(quD kt܊IS#H]-hP]V 9+X]GSE])0LڽDSy&h#.8zA2j?,ſGh2 zU^Ar:)pbhME޵'X{o>n׀ْ/j?L~aY䠿*rkF:n Ci wwc6 ?[3c@t<3FV#-g'D.Oȸȼl MGBM&:a33RxTRs׫#AC {(j @g(RG_9HEAO_d'/&ZV&~9wԮ&8SO,?xErະnu/F{U@8'׽ߚX Oj-iS\~;wImf.Jtw%u|pS3AB  6W nFޓPw>±!cQF|fVB Nfӗ!o{>AgA_-?YR-Ukk[ &Ț~]T1HoB-#(&ad/񒷌En.r ^rx_雅 ݤR7_Q|0[eXG_g 45fSUPvu3 o źl5ւ .p`/8a-hJ熕U]P(dIX3\1$2|b|Baϐ]Ӥ IL  3ڽ(x!E:P/Fc7s A7Ky=P̮/jpƏ.n`+ uֵ7H[&P<$2V)#ZUiuƣx|#6L!wT U}#2<wYJ8v*9UXa : \͹; qFr=okzg,gJp ; Lmgz[sq; L?V-񀸑sv5:Az e":]OuD#>ky9@`cDۏZg#3R¤E}wȩP8ga/|7ҷ4ؕ %8w`X4ҧؼ%.0AOμػ :ko-@LF.Oo9e2 '8;SÒ 0Y:-;(exۓPVS#B4ǑټSG?R $1Tװ+HoSVW ޲ djUw3:vB<$Yi*ǻB|̐41P2[Ebpo@iss{A"!|N-w*@fyYӺo}/K8Ե= 2DOL殉>AJoFރG~ƕL39`)3y3d2*;xatZf{h)礔,G!S4ޟG_KB I,_&`A`4 Wޡ\8✵-˛:^f.ҚkD{$2Ů1)p aJqn_Q%#Kx^׀9vC'z Dm_9jX)|%iuhE d ܻ _Z6nJn!VyF$c{{|xvxn)'E%y&.%0ϴf#VˊbĺQDŽ?njۏ43ga2nݩKWZBhNۺ\G;j"cR~dKȯjH:Y'%*Q=!I'[ŋ{ K0n3pYA]dC0 Ii3#i ?~vY5t41o1!Oأ9Q) Mj~ږT mblg3QB27fTFf%s Zh뻼z@"Xz%^ԋ_Ud[$daGL b0”j2Ȟ@o{3b <b~H`K< ? 3z`|{%2٬(3&nJh ~TjH_:4Cdx#"3 %7C27G=.x:c ګՁyDs>oQBSKpKO[^s#~!9{ l!CI5UiW쪝=m ePF(Ч+%)0eހ}MX3 -wr 4s3SJagι Ǧr?{6~͹@A?QGt7V=$DxE4??=c3uftjDt[rud$ qPc,vhTC'[ĻzD/ژnu.si\9I$R):85PNGʹ8d8_շЦ !U =P$AM,r#4o?޹K-P[Xx-#՗^SķIiy*3tf`I-yo2q{f_u$\2v>Վ4CMODN":Mu'%IODδ)Chem`S Oi--1 ԀHPRn"/#$CIM<*u3Ns%On^@Qy(n/Qcz-XjPM7|~ܣ#S(Zr#(_* w 5VrZEߗ:B_k^kBRW QR`H\q`:<=1ԵyNuY I\:L/;*|ps? T8jp^.j2>] Wh2bmR%l%lFgblBT!X&2S"ŘZm0Wϩnĺ2j 9& 쯲؄2e}s $MC FebU;zk(ݵ|?VmT21q0KE}yMV Bdڴ˧U)dV[tZEb+Z\ zaUDotpHHN%"|g`NcDkvz{z1[|im;}aCU9d|PÜmNC` ȹ9Vk;mw<Ԉ=A:a= Kq\Wx.G! \Bg"fKiRv` sS/\Yr9]Y-KKYEҫ (rev쎛/,; >ulkmoZZan [Lp7p}`M7qlXq#% _lh(*0^>1NʨHxsJX4nX K+b͍A}rPE?v^g- P &nYӰ{B_Do1=V+Em֘'Q @ݑ Œ?o@턏q.$@jWƤ[w[jtDrH{N`/9"пv9{-lV߬Sl C1CO> zH/Ms ǯ=dZKt/v\y:6vѤ,zf~V!?)w*^Ee}F$Obۏ_ހx-01܄d>H]B?$wޘ :Q)͠g2r0E::I OQJv+>ICH%5g7aSrS8.q_Qof j b:6)n4#%$@T8{Ğ:Шw|Ņj'MOvĻ@)7t~&_ާ@$ "c{n}&. 32%5<,D=Hpp*. ]|nmٕUID{ o,(!W4 ? sO2jŹ/߃@> y5 k_sl#lKC@A j]զtN=px0.@8'\h^CyD6w܅K)1}<{TTB1#2ڊ-~o`t!ť[۩M-62kw*üƭB6a񍺯ZT5o%abl+%6iic>ł'I18:JQ#3Yb;\!P h;kf #= VSG"QXgEg#屟,[ĕPWz8!t~<ZJM;[P;K%LܸGwljTPe\e1!^s &J Z6wXN͟pކ%gꈀdC}*@2-JE@7Zniko|}OH;ûWֹ-a5 rrNy=&$0~L B9e7%ny䀹vTc1?>^Ʃ*. f;k }Qґ.UC+%Q٭xh'9)c~rn[R~%d)L&]g7FA-nID?Dd6g'CN#I}<nuv0Lg59)Q'S² Z* \g8NWa:M_*\`lO$԰T{h#Hj'tdbQ_.MQ F8z.3ЊF|\+E#9R}7]Qjz5ZxXJ[ig CiDu8HUk"FI.P6c'9%Y]!ߢ=1qE];1M]Kn=v3ooq2[S7BfUCEc%Z,u)@}>G=m:̵vf>5Kma& H+ǖx=i(Ln5tk}}^wvb"jMDGGo*h*bDubX.r{QO  ܑ,iYKeoVz#NV,uH?ʊXp=G?f$ -x dEf>U=/G0O~9:IvԲA<[lMnB\u]l)9vvt+"iޕ }t!ƤrgIXH^۴DLYkyM: K_w0[aˋ73أ^RNbn~WG$S٣C(΋Vѩ;_ոb:4/54^KN =kLc͏eo4l~*1^:|dAOggagp8vԄSqhdV{G-Nڀsە?n! ΃xr(҄4'ҝn\]7]!06GCHłh?2D\YiXN)'ߍLdM z\T9k$p[j08;B>= <ك8_~F8{/䀮 |qG +;DbT%}Xp͑<(@)ȩWPw|Dk/Gq>q.0 -1ٲȸA-44aJۑ5ΪZU'{62a4".Y0`al[TM2jrwd+LDBY`cnc6^?(#0Ȅ֕WHGԁt|2(4@lb]M*HdHs0ᐶA x};].!6yҀX4Z c쎰1@@K!z mbc=c6v*pbgqTN/k<8 U;#Us&_-lRpDȟOdψ/]oXJjIMu W,K3@yĈa2s,, |-7/Ed軈;E;oNw܅5|e3E7ypqDdMꆢVZrbF7=%oH%ñ" R0 ;|)x+@ku[x&q RyUȊEKMbyS(F:&.#B/.;GS#AZv0|Qx>x" Ɠ=mPLYOgRp"2R<@rŴDo3滽#9l'lf}Y# N!ͳe U1NA2fDHGdϬe18~RX*F\O)yÖBU$CQa^~7R¨'FjoYq h,ΦR7߫#QcɖYt͙AvˣJKW\n~D Ø SzT 1HɸPyatIݟP{[ˇ@ڦqTԎ\~ 50Ӑm`Ju%3AMvlo୼ pe\E-:5.fx-iзwm"œBo4[m\/2w;_UO' #0.?}OP*8lݒͩO?k玦3W$ujwWJZG'Fi4d<\v{9ȗj3G38 8p}k[bGEDo~W)\i&ߏ$3+jXB Wέ% Do7(SҢQJۉBjOw!#:[%)ۼcJ&>oqY!X}}D$Tm#gEdXOxվ3B֚Fϐ>x,iEq-I6TF?09R.dHր^-U=|ea:J.+sq|*( qP ̛?E4 S\դ2!7]՚YDczNSYI WіؙNh|pz.E"gN韌C"&xa<17 8rND7{r>bE?IɒL_bk!R}:([?HOSѵVPEB}RŋCx=k+ - X" o橌J4w'J533tJ9θш8e3<HP#IKE 8RB՘C (7ڔ\҈ƅW@D(J&̀V䢵`Q%YP69b8l$2H!,TZslh7+cHmvدvRr^DA*u٢n%-:Ey5_Ay_(=pL+Ic 3//rV܍^^5 N/J kȝ}򥋵6hH75p*F 1Ŗ ԥ#~Q# 36pL*% f? pA[rɋ1 B;V9k!%d.R7f~Jܞi G6 dtQB9C6#neVc<%':rl뵩!œV kr8@r9o[932dE46j֋?ذ pj>I$iPvF3ǀ\\u&7PǵH2+ ]I=5o4ksEu ւA[#n K>P<"s.eŁʼl/6' x7w3̽Bjm±[ 9^#F}NK .HR.Q) {r-@#M$ƮDnDM/.ad7R^Hv7nN5yV&ں~qed&  t߁4""Q[UQ<|5hI¼cSunƲڣdGH+1DWavjOTW'&&evӗ8@爉*@p= zX_M%@=Lua@WpF`NgUS`I\nQQ/Fᝒ۶p+_6yNU,x0ŞL0o)&KS6y@pمs2'cWڢ D)o%r${{p*&av Jiʤ߸ۛ,?6Vsk_׈QT9T%o`neu3m8y138)'ibf8{5Hĵ#*̲*N~8&`VMbsܠl4Em:hd83D9k =@#gRz; /_+p_{Е㿟@+[cdOf4]>FA*;d.`Ct]FRNz yLG?S~&*z>=%޻elJ?o/^e# "2QIX𺪣<_(|}Km=S4x9_ ޫ vMZȄ^{e \ EFmaZ7˾sA`I1+U)Bp2pJU)g3Z( -hBx4)kkҵrP#F:Iۃcwi=Z6BNOlK _ScFqSdIPS_1 h 31|f0R>I:ԁ`t\ dh3ߩi$לE&ٚ+@:њZM˜bev2"C};ʼkG*`J9 GmP忙AKHE3ޡ!')Ce ΄LRX[6#wV6hꃻD$$p؀ Gv.AEsdߔkԼh! CN'ean?X.cqG\ FEAںڈ:xNAJ"cYb =ja񱤧eyIUV%6QJOZb֒kKD nU38F:󵬈7`)anac2QPȦ%q.H0` \fio=BˊǏ(xL-KY SIW2ZXnK !0BrDRiuDb߳JN<P\hO7)H3K݀1\AQG3+I:P {0|4tLmm}+-xYg#d>l6\hL^T%*/yg$(՝%,+o Vs0.[x eF–ɹX/Y a@_ٴ`#x g)<-OQU1ԻOE"||# 4V"5FGC8Pŷ Ƹȶ8㏇Ǽs?E|HDSzeփQPgX eg6cfq ΦiA zɵ\Ŷ**b=00 k>.$z 7kvʙ s.B gK1}:Mg[ 6UӏcgV2"}GWLgFYƚVe\ ܔ%K Qޣ&!i3 ],X\D=ӨSTE'xYmu ԙ`9 霰c6mU{2p]ڱ]S  V̿)oCTʏ+{u%-GZ v< NHc_Z~o'sjڱF!lcXV wsThrԾC 8k55T Y#l9#;CjLFRߚ{GtB9)ZׁAH\m2GOehlr^(+T~AbVAB}{l/͛ګOtzϘeWǩb]Rh_q;G| i??4v1<˓AUi7kGoY!_e zH C%Nܩ05Vuw(EctւY+6A)_)qc%ЉZ~5K?M+\ 8KƒkTg6/+!|3X$Qv$)X߅A"?%uUz4ToWMd+(KX;Tc TwLJU?ÒI-|UvN oR1>n`݃Kҭ^b__, uo^x/PN+%Kwż?Åy:9s*:h(kx~91Hw|Rpһy5>D$J1ݖ6U:'咈%R;'>=MZђ76!B]{mTO%w`"j @rlǜDfWj.]锟l8&!?Q;*ɦ43Q@#O1]j4@{sFee+%^I*kS% 5$̑8Q@7`(;r%Qtv;d096/sZoA!]Z(I=*WVH277[7ŒvLsL1Ɓ l)\le8T⤵Iΰ*L/"R歍*=Z05}K/9iks? nsi_CwXϪ=v p]me#IGy#5uF*-/ҥ?va&>oG 1UkTmtc} Z$Ù0 GWMƼ NȢoYiXZxy7a@d:׭';k-*fՉ-(ecTF޾$y.>W\+TQþ~ 5O"TG9C'nN?γKݑ!}Уgd,5_xaS\+)41(J[mT;I>ҚX@Nofk/tiDY-("-. 0._d43^:UCoM+>*僭 wKw $?'.y1{bKhV O*kr%lv?<\荲d;H#q[-cF8?.Z5L!li,5 p)1_xo ٶE^|pܝjQ"YίLy +e R>a .Vy*ÕW|Lc܇@0i#ǯO Nuרnjsp]9x˺GT &]pLp'ۛBs8l;Q[Y!p*oիyqrk2RIFjhE>؏LyRO k ۝S.p]s6qbJ!qvI}`xP|5 88z;ԣx-y R%φh柷 +R'o'~G!Cp[@Siё^8,6@,G{ƻ(_3T_B`Ȼ`QSC$̳pϦd/4cŬcH̥eċ&ПN%i&|bo_6 {f#utSlu7nΡEj%zznY|Rΐ4.J :مSx˖qG3|!*ڄe'@>E!Q%Wc\:Cپ/ 9_lk k e6^Zjw|fވՁTQ|PMh YhLnE];>Ia`"ЏbktO rJES7)nU? Mj0ҨW2g$Z " $G6zpZ AZ/1Q0ikae+x"XNɘQXKnM/LBn^I?hhmM9$RHAo8s+Ūfza^GY;"ʚE~ y8i`l|L@pW-[2nSǚPzQ $08fu꺻~.0f:m%0 ||kmK7"/Ql=`y$!|'BPi6|E ҆qj}]6m}3K'Ka7P q/i5JOe%`Bf^~I֪0N`wC`YpېZ=r:r2}]PU!S8JMzC\x';f4Tü#bJГwv, :}lBGY:hD~2%@n*/ R ӛus˧v|+ĝy30XߩWXS۟]~\ŐQip q&TTFgqaD#=,ǰJ"ycrREބ?Hq6Nrf:8skI5Uɉ vqPvkŬW!WGc+mqd}L.o\PU%cY]>Rw6mIԟ!,\;ჹu!Z %nU҈S鏊X*c d>^F S(ҷ6zeL?SW|,B"9qPA& /pQ*ƴ mN@5t nYVcǷOoЍ[lX}#Ϸ32*tTXS_Dz.6y1Eb+R Nƥ(M~(F{nN`DaWn)0M_'+•@NkW3&+>;#S$(u+Cg`7~~9uƴ1 hfO/>ۺpS1oA4e A]iy8^EN8&Ҏ|2]08&*+#A;)N?zJP}Jexm9J,S般Ҫ@NkӍ>Ϲ X>,~@(򡦂tr%UMwBujik3H1a!lW5!h-<ċQOGٻ y|G sEqx(&_{@gSrc[$@mOqlff܌dLMɶko|Rj|"II}1o+a;_ҺtY` p{}" j[8\Wb0Ѡu@/]jQOchNS\Z7ftc *=:2}*{V'`[ a*j[a nfQO (ITda\[̢ΌƶVcszXSz}V_4 eHg N m(y&v }y6κXE#Ui9/Af? XC,ˑ03}ץ QAT&|v, ;ۑYY?pqho̮A"m3Dvl΅ث@{.^cnCEAn\ruᑻdXO-.τ)I}p=ɠwѹA3m Iפ& !6B/X5{8I( ))]\ъ]#p' Q>BHS+В׵ܝ?1nh©JYN+<2g?h?+ӗ#+97\e)$cOPXrz$dĨD4|)ݒ+?^aӌ IhHeʋJ}X3ZrFHafnOObAknwȇ4s䒋&ۏ׬PdZY_KȏH)LlW^֨#S1E_sԸc)Ókep0RELyω,QV"WR4TYcz_[)֢a[elqc4,ao6۸/."TEa~q$DOX*=~^XZhG~Pz"I]$@U.>Lk J* oIMd0`䣽pi`Q橊R#*3#SQA [`D@޷ބ%7,9l ^*oſ7/:kT/XQY#ܣ5ݔ^zPb"c-Ժ`!}jS"iF9L4Ik,n}uI+v:ą!f^ݘ,9NoSne;~ LesnʬN*qMCqL\B{r.lf_R/{r^D*O'ukגP<cH ̽-M+ diŵ_e#4c?vfS:>(5#XHE k LDmi6R)a"a'?$|/ ~d̕?>bAf1n_i^m(H>m vD FR"E8Sǀ 9U?#V}(o6#(?lMm#kAK=ܷ4C駧.{ C&G OS%&,{EBZ`H0yz&yIɫ3|K{ΓC-:Uv<({E牃Wͮ\I?fX`t^FK>\hŵQix#滅2j GQSʋ$.甉2J@v*s)$#˷kj 1ˢ] =@nr<_p|2v}?Qooo*Re)m6uq,?7!z⽢C/ C:>_fyρPˣ,A4q Ɛ cw!T|O[~6ވ8\IN4R&ޥn,䮹0:SǺEEPI!IReC6b{.[CtJJ)3Iņ~-u5uS($^<)pFg/\n#ŢI%9W{+iGצY \e-, cQ@\PՄȸ~wYfeX˾F]b`&q2w/9Guzs"+(> Co75X ĩW&ʲ=m6FhC(F~\3Cj>nK1S8.KLy乿^G{Mqzܖi #n;ZŚCW %n-n6!:;ᡜTʼ@|Z)۪s(,č'}O8rB=瑳)7JF܂Am}#0AVk=Y9 `^OyM`!X=VRvK}~z~a:#Ow!W kQ]UY{jZhf Xj%K8#w ŖC+&ul}xǬioDy+}߫!*a-<(.asϺϞ1s;_|q֒ak{F0Y-kL8|{Kw<UQ"а4aВ( 3ؿ| }ڄZ[yh6YrROHH4x 񡎨NN{[&:']n/a4J!o/me5j"U\̩9M0.FV u'Y ?x\Ns@%;[P+760~׭5 _WM숛=z]]7ץ/*3*)%O&.$k7V*sވjrP-BKD3'2zB z%RD[.Mu=\`j &~NIQݢ=1YdMQ]<Ό2,'ByReU|[ ^2x pr)+Qj8|ADmΈo9I$ lez[C%hC<*0&pJGq0lF8R@-L_G`LCcb<:HHfn&L'u(8ɗ )^8ͥ򨴞'l#h~}sfv߁),}Вm\h2) zBATNeXomR-&3SSetd?zE6wZOFgR.ƯUSW nĴYP5,C[Vh H%Zшi6|"C8f{z*Pq*]Z7ТL<'_ٶMh=ud ^#8qc=$f,֘h$| ̹P$oyҁ]>kh^h Lg&9kXSt&Aaz*yOLwbN @IK4uN#Nݒ@._YF@ _һ+O&M;;<&!|ޮ+AסΟ#찥;@}g︟ڡ7!%_t:dŶWVkXBchl,b[T#&(xg'C,*$Y7 ]oCq&9 u~xuHBxPDP_@}"Ϙ-3ZPWH  e0s{  # ||i2޾ >uDDBdl+k\"Z{╕Ko4N0) fOKn:GR "cܧv?N~n|G$k<ދ/V*c`CjvhRN}=_*Ez+E^2; E(<9(iItp>Y,Zi0,o h݇<"!OP؞{4L2jyb Z!SV1~8ؘ-ƫωM5uUkf KܕSV-fҖz)<zrkEJ\n٧ʚgƽKLjw1)6a(W^ M4Bz>/}(DZflkɕśhq&_ei'^h^cwH~< &o%>i r. |Vjeɾh_)9IU!ЩzlX@1ij/{Y`TeR y9|/tY!o6T CTz}DKʳؘFLR\)|f}ޖ %yq]]9|Qgs6u+hV 8<*F?ERrkienVS%_XϝM /G闈@ FA"`f9s=C<]񢷏SH8쯄NbVG_"1@-mmt'RRhuӒLrX)Ɛ. ::Ѐ|: >ddRpߛp6xT'P" 4)uqX*Lbelg8V9S|t^p*>]Q:ج+=%|7.~bWzh4:[ {N%k芮1+|J5iDYV~LTZ8 f#[a0tL2:L7#6 #h~8A[~n…eOEV ~ Շ/NWźn?[= Ĉ<뜲ou=Ey_nK7yܣf:dq) ,>[NEo4j?R*?i`$)%\k).ӅH:B"j&;[X1D6~k܉Y o=]e8$J]ՄaO-v}˸f%xCk{ǮnBS/2qBg\8wcCtčEâ_i츕LJ_NK4e/{I!kY4]KR%>*6/i\~J.vZݘj-+\sz9\93E_Ncq/3ew˔e;yZz ̸eI4UiX#C߽xe$@5i'מJ ᴘ f2*pƈeej5yU2xَըv_h2 v3ԒF@+ܱ2r>bq3ewe UԻx-Ys*ݜ"ݸxS J'f}{q_b~"w '@b1H>PdzOg ڍɜŎ)O{kUxqֲp~n)f#1jf@ Rn_sm<>SFҧj -7^g0ˡJI.ʞ@(+Qun GF]m~^yyUao&ܠďo V9CW+`aCԳFUx7}xR񛴊~:% h?ωF5(VVsMen)#ꌩJ>w 㟐U矿6o U&X\{Xv9gL\<(`䡿/"eT}oIH AVpe8+4wyLF_*C[QCrOucH56QH֗/ n!_.ӱ7V mq?[{aFcV皣',.NTϱ[k30賐;V B(3xdm{^l}VI\kR;EU3D'ce.tʄ ' e*-ZfHR?y;':gS)vReqvl bEc Q G}eW3icwrBx e08& ylz%e8?}TDl]sdlȣI@]/;xfSdsN *jA M '^d{14Md#xb->jZ啵!]~YJg}en:!ȑk%iaW?&Տ}]t髒c,@Jj$mw~&<8L$D%s[%δC8e:ա!kLdP6~|UQ%of2; Cýo!ٿ09Ц@F윰:-ńp^v bg *1&]RPls$Svά(soGQtx `Z  O13Od"ҝW,g6*J|&n0;W޴}̶ZnmFخjC\oRÎD$: ͦËK]?a1Y*WžP:Ŀ0~,49ӻ>ms6(tdnVӽ2ʞC^?}FbTOg~9 Q3PU? Ms|KҸF}V҃E'/K.(aī{3ur%rEˋK%۳2F#cj`3/VYԔΘ KnARU å8d")]6^ FOm/> endobj 34 0 obj <> stream x]n8ཟBvQXO HYi@#WGt>R4uwϷ?oytnW/^}cZNy:Շo|v/yUjNi%]O| _sՖ㆔_cs^mzWmasM]ǧôڶcsS1疹EYY٘ w#rbNsmܳGn@?@?@?@?~_~_~_~_~_~_~_~_W~_W~_W~_W~_W~_W~_W~_W~_ᷚs~7~7~7~R~7~7~7~9w~w~w~w~w~w~w~tF8#Hg3ٶ l+ڲr Y,h6;сDt8. Pi|Fv +KdDTguNm-^F ̸>-AāNą,ua`ʼnALt&8eM<#art˄F{ǁN tޮLvqpvvΙK2=n=azf1OOg$@;<) bwW<}ynS~y.XG) 3,ud@ژ4͛rPvc1Kzp endstream endobj 35 0 obj <> endobj 36 0 obj <> stream xste_ vR1nl۶YolTl['b۶mOuqsZss!'VR67J۹330,m]Um偦89 #:9[W/ f7C jYyy,LLh0s7#wp4p@򝚖fnnn11;\xaK3hO #5@JV(3?v8r$w%#9_0q,\\xRfP f v@ƿ5LEmd1K'=ͭ/ v@i 7ft30q?y8E2ٙx9;̌l>f8/g@++8ff hni@X8Yt* `;ojog F@5#DD^\zV6fLY:B,G.)mgfQjT?m26.;_O0mͩ[u(jc/ACP_EEQZxexHEmL)bwa;sh,a4Ut1'ng t*;[331j&v@g/hg?e3735鿁hW'Bo@;rDXmCFk[uiZЏ ?p_|D vMOp ܧ>|Ry;8S6'w=qj*O;Y$$|^N}we b!hfXZKVfl0O/L>EErXe_ fN=)1l65kWlr{N:ac.q0]L5ni0hN 1kҙ7 EjՓ`SfE@Ļ]&i&˘Bʆa0b(H$=x~hDx2EcSL7e`(cSo(A7l~瘥 NMzO4\1f{_r-UW;9^֔ckjXIYNѐt4}8SpZiۤ@o( G=<@Z=x"*ϿժV嶡a$h[_(3r:"Y|Z``䦗$!ULb2ݏ!{}jYt4 tog|Qک] $NwH~HN=TpC(t"Zy" !j*kc K/T SX`koIFY-5ݝrs,=o'{l{2C߉H` ؕ5q:9$Ҭ-kR䢏It$ u)Х 1jpeObJMN8"$|tʂB2Ż-Xhƀys 8wp_6l]PnY)סr[|6$Q kFL k ʓ H.IO_|M/zh#ySkzu53AKl J3+rXw֑g pAuڇ<נKI*IՄY~zc,e)5-+/xEwfOœ瞨Un.gߚ51C.a/V=.Mc@5HafYxteH㳋G效ه8ڐ:c%}YL.bӇȦTc=SD;B}P }Y$gF1k>}hOayeоϏ¹1'< _E3RI * *@?/&$"3v, ;ȎWdZ($NU7qr W#|8. +5?6:P&?ְE&1 \⇡C\Q2rp wP]!-f/ +e ;|WߡP5⾦w xQHE ű3&\yaCE 7QwKwYCfFU?h>s'=,4eQ\@r޷2X}wj&(Jw7M9EAˋ~c=4cɻ`9^nmP&}d8t/ Ë ~?yJUlZN\Ycӧ4˞/OIpWGʿ%bM8,niApO3"$-PCx} *'׀yX~TC4SK;\dCOW<{EP|BfCfq媱Rwi[4qLD%>; M Jl;zT8P:\w wQhp @m# ~h?5:Pyo^C}j& enU& 7yJ|NEL{\ʌĸz\c;NrCg|ZT٤lق~ݿJc 1I O#Tg1\?b6l(~^*bS]D 4Vp/{l.v0xydx1X]zFxރ "Vg"_~l"Yf9(ƀVзS:Hvj'R"@܁0CH6LcaHm  VH*b_.IV%z^cxF84bhLm6`yG+ ֓ma >dRĵ9:, o3WVSQ@̖d- jɁd1 gpVeL70A2"vUgM!@k ʕE[>[3u3 ܔ>]SG>sVZ +Šxx*(C1CNpR؜>AU WGcЋ4#PG.Z*?St{iߣ{t\NfAϖ &AA62~Rn^Ʌ!(Ecv!F)Qf>)>Ks˄DC* ӼY^%" viVlt + pd^+1ʃvb cGyE/u6 7Ft@][)@CJR%$0$ y$1"p{[[; -5evuQw|(Dj.Csݞk%:kV;xl:Ŵ;ώצ"|LnϺ[HLpaA7LE>m8Rҙ GgR@K27'<BGo؋ufumSe7hRߧz0gqSY*vRv&[LsR: q 2nt2E.D"ǩYJqsEmxMg7s~N.{CpRncO Y,+kZb[6t=>(wp3A:}#eC}@U'jw'=U?nF@SnX&M˟ gYl،&z,J~)l 1(OD=ڋÖ0D\0ᦼ'm W{DX 0_<#F*ЅW6ex L& :{I2*^5~N[߁BtmF"<$FE_N,)F&K,#oiw nX$a%P dP; V:{+Y5EۺisKg%L9hfǮ4'v,S%bź>Xf3]9vG"varnړN6.Mdn5N,I8\4a oK"]g6_&&}=PQ8F B7wxewlP/do.̫p,,azITU2);<\ri,?tk܃ZL7# ȥ2%E)L<=DHt|L[4h`#sȚɭgJvs:`Tx:,R6rJ |P2=4+qCu۰?0iMb JavK녖yuj;XfUwDk)PǧO.X;]w1ͳhu]jkOmU}il+/aal +k˞;g,Fz+Z?|eH2e6BVkOᾛ=(*TgSYVʷQ}dyA6"@ dxh4or:hžY^bziΝ>j&b{FC18v6߶.VQ(Nd4먂J }%L4{?c#S$v}kuu tnF=EјY̏Gķp"gg}}=h${_Qh gݎL"[}:%dMwg-=8ǝBYIUhEr/K:,;p/UՃ(Hg_r.a->+${qQ&?g0R֦sZ*>+3Pny-t{u@L\@v_k,^ ud0*8Y+q=E{gCF쒓f,9G Za^0@-]@Տ»~ lDRѧ6DJݝTD|;mX3@aAɳ]oʏ=`ܮi7gF$i6fјAEY\/M^lH7um.fOvdӥO jq:RUojME/Hj-ǩb$Pg :᮵~HֳI_٪H\j+ |[rslބ١&Jϖ|DʛT#%.' q]q}00VcO͜S͔JiՕ򛚱^X+7gp'=LrB?9ros07} Kɿx/bV.]QAޒ*PCWP@+:Ƈ!p?QX,NM]q*BpRPEܘoilj&۷JYC_V ׭xbv(D+ԕ:R)&a.C|'23M!KS8F0U LӍ7Tu4i'2_}$h Ἄ$#CŧA޵X2YzPLA)c~74 *|-R,Ӄ;I9J,0@>}LEͰtRj W{ϭ:_AeV>Zw0FT,V iAtk &[ N.5qSfFR55 ̓D-Vf=彩g77m@CGx΍j?B7)n##DovE6\ac{:Kc$HwǾBUjεfL1!!*gB i2zz 0eã.N\b5%]$kfqԈCaE)GJqEi 8r3R꧳v6Bo1s\B7RB9bH{"݁Q{.B^ BOG;U2\\&ƳE㛺TmUtdRҷ.jмd".tzHd4aMq/5UUk[O%+ȮWI7]ٜ:46-|#;M7̊=6bSMp_8.Nn)OE")8,HJ6%=\Ǫpﲼs:m"\"pj2Ow!2?9`k$ 9맏}tu16B t0s'vaQIc~_wu{vҹT30)Yy{Fdmj g(zPt`$zcG2KZ< VSu|/֚yAPj7S6|lXJU:D T|1n8Rٛ4V@&[YETc_/$G^sFn[?v-k 0DݼDuD4K0e"AqJ;>r5JڬHNa:b_!")=Ġ=v^KZul\%FǷd]ZWLEEr_Fߥvʉ\RQ>vG,kOڠTlQPX].6on~A'"m6XaeCI~K?M4뫉2:v%aU%427QtɌ$Xpe}ke!X =q`{^"XB3&'kqzoyD3!rT2X/_4/a7#e_n1S0p𫖞')xM90 Q~sTXa+of6C8#3HxhlTCbsf+j4k/K:8&M0x[0[ md]/W/k/"03Q{H)8gl 6cNvLz5FmW35;0N2b?y t6/6^'A>S ^Qms~m+Nfh/2~Yj ʔS>*YD肤 +}e#e(B5&k@%?ٚbDDX~MiotKjPAÒ m\ad욐 Ag@Br;.w>jh&$bA Y\W ʜ7/fEߗ̌WE\D5ʂ TT.T !Iu5I䳚9΍0H{:D(4Fiq@ҟQ}v[SBS1i$X[yQEK~gWJ C@1G%"{tjC;;*c |ǣ:jEֺ" p7b1{dWt#t]ٸ!I+v۶Ί6~dRq-C(ݓ 07T^I6 o~C#-/LWt m\{t%CBȷw)>#)QiJU3$vBYb#=A6# E0Y´EtWU7F!ޓ#5G~zxgҾ$UO0 E;"/3wz;gރ!l=  mWlW9L}P_Q(k~뤯^Ѱ;ZS1FKZrQ|~2/-q"lW0y?iCpad+MJ `!ր$\/|l)0Vb+?*Ggiϫ(&>=z)d/KsZËSΛ_.<`\!%L&Z,@[t!{ %ƻ=a%1i_:Ek]R7TGXId$;sr8oYC4ƿW1FEiJmGDhpJص=-P MS*B(MZM֜IKGhlk/b5SjöGeg@T [ew+`;\Q|ؾ gr)0ʑLLd_ux{ o~ d?DB27LY|b[@vh)2!SKai.d} ("7U/Wc~1P~1J1{A &?,زG(Y5g2=L{};_GF_q(lfgrUTU;_@5Nb]Vϓ;z?,*63?Jd;u?gSZ{x9q0:xbl}15 Z̝x6[EN0 +:+z+2q,f2pzq iG P\VT\.ߔ [*,ri'ǭ弊O?pj:\1"qBRynMu xؐG~)`d\#;}`1f.miwϴx~@i5'vz-͡2&bAs8NA?2?fY9 X>)>wtDbW2^k~oTNy:+#ަMC֎<(äݼC3C3S;]&TŖ-n AJ7no$Ga7'{#Uϔ7 i%ZKq ǒB`QnχkYd"rKHc?FU ]?vmabG\o\'L]BCyY^`1fgRj^XԢ,|MXҷa2hsf?]{o ]YNN  Onf!쇺C+= =qnDO 3owu/ߜ4i<۲h$zdE†G-{~c=}9ڳIؔ-Vy["i +),1#ZE&i]$p+(O}`_GS#LD2@0\ngA"rZyͽ6x-Mt#'e yqSN{YY8N.)+ MEvR^߬C= I<5P~{:O Y:k#y\ 謺iz29֧~C JN竺\d>Gk&WL/~iA&,ɝQ^euNn=O \ٱ %-†H5v^*_Ε< BI ,DqS:&9ynFECxCļ>t  ooW젊އ! pNnfQםP\FJ&{rEX_uBwQ 8A| GZ.!{gz>^nR}rX A96+ N>ɱH4~PT }xpȘȑF[x\32a}tCORˎ^Jޟџ&2u"_Ӈ”1?gY]ǃ]Teb. H hDM|[M$n"0><2I0?-4 4v ŏJ.yGՂ6p_ $rHH#Z<l׆_o0Egw?(xǛqT_Tv'8jaY~S&"he2PD%9Z9-λ$ɚq‰c׵kPW??JSF(&-W- wlX|0ZEI&H8D|mA!GJPP ]TPe}(S1O4>^a)MV+G2 YrjiG80f h2}#-c10K}r؃Q af|!- H{zg|]cO@$Q(`BH> 3q>*B*sT'W&ڤl!mbL+Y̹B[D-,ұu_fŕeˆ %8č]2*º͔dw>rO#" T.*{~4݅q)j׌I?K8?~<kN [UU ]CkI%`3Ñ3(r؇f|8KD+.C5r{wH5+>./Ǥvo  ^RXR( U1U}dm V_qiR?ݖ}5j0L|r %x;:9߈n 5iܱO< }M'vqqV`Uēͽ^r7h7;:ȍMq>u>s:o'1e~#tu4Οy6.\:7.Wq$΂B_b(Mh[hP7UiK0S@Fn>mi`BSuwc wjoB}pj^lffp\s,c{aѬ!2Y}$*Y0@sa92ccGM!p$]fIlqW>wtrlz##B z81!y#-Է#: ة4j$\ Zɳjl&0A2:F뼱"h/U7SgU=B- qʷLYYqS[+pȡoeJ$#l=C4N? 9R}C)2|~" 4_q7m ² գtuRb(ߴeOg&11:]vR i35Q5uBiq䊇1ṻ%ByCI4$jk2ja\fpW_FIG@so'bu%< GD'[{yZHOx eͤIgpi M7X.iUJdA5|uXA=dʵZFLdm8RJ3QM BeE7TMۖ-a{<@NQe>"(\\yB偊Z7x^z\o cL 핖?͎m]#,)|FK ,]K3 $^..,;!hh1h!יIs^mKkSa.P/ !!|ǡz)2+mc1^FSN>* &Ŗ_CߠkrÃ$۵ԑDg{b7M*rz-FP>h¢2j#H- QngD. A+%q#6PהWIm%aO?1j}iroY*]$cM}(n*Ub!K$N))T1&<YaNObt##;8uWX %?z_J|V26 2)\[^]R 6}^ ډ*ma*BhghyqZyo:7׋0M0UDU6r e2f&YБC=s]ŠvĆ|!&83'21MC!GeB3n/UыJڊFztƽ !LWA<?W5Q*u23x)LjqwH!a2G3@=, Μ-rFXuC HUL}!|)BٟtQ8n୞B "OJcgJ!V)*zC;%?@tu#Xg'X㨮17ic믁[U;*'[6@[Sdj鶒;edI9߀CRײknNݾ=O~'sHEt=1[/gy׾@ɭqgNhQٻ$tkmR3Y04T=^NoQT\Z5yݩdhӏI_A$H3:b"ȷ$>AU1sIwg%L3BVn.4-'*Բ>h2"mS6xg˒i|sH[?zdG~:bcgtGNhVZx^$2HԞ'꨷3-O2.p~XA̬; V:,ޙ.B= d@D#/tfpuq%}PWjhؕ.|,1wmJoyioxG=a`^|5J:.8wÛ~Ԁv#(yvGY@?&%^[+9b( T.ykh~ֽ$7ߋ\䘪f Ϣ"ظ ҋ<^L@,AOopvkU Mp֥ףˌl6/lD ZEdx>B 8\c?|Š)@&7~\_ ׬)"JFPp^W]t/ôsC>=_!}[d=Ҝ#EEp1a ZN&ƨ/K0J-v5ߖ?U`!6ÐnAvWoy(q MJnH;HVy Ž)hD6ٗ#*6bR~:{Y>"-(}I_Fg), FY7 jgfTsZ=VAxXGc?7[-mU!de=GOpYU)ؤwiͨ8`yB,|X# JM_NatJ1Oe>QőP)M( 9/?<ED-h_!y?>yAezV < ^9jT^;^ojгGm[L蛋:h W~Mֶc=)VTYZ)+C-_BZAnlm~5ZHcDAS P݊)) $*3?G`{A Fpܠz M0 zIqcz-& ھfbi`{x`ꬺV3* ĎY`ےV~%6?~G xke93R-x|m;n16 +}0$Ҋ#3f0amh@1%;d=ujD:ށm DBHn @E(lZ\OOט˫BpI"]͇86r>4M8-T;jfȂ(197=nErg"xBu}#3<UtD8CֱprA[Q7$PhN&nҍʶD&44.]b6rvیly Z@ $@rOBi ^#w[+|lbf4qIv&蔱 !s5 bbA)Jl-TcoGrŏ30*F%>HI2cj*'Au,y5)q뜥P@?40o^\"]G0|@ qC,SD0k CB%F"Vx#X=ϭCkN5pl,>+ԃ&4L#mH @ķC K&}j52OCZ>Hzo2{IzC~~ژ' dj~\ƑzSuUbM+L҃J9~o.9DnPAaW~S#6M4 ixjж)D0Q1\TAE<~(ibGK'HGٸ+Â131Z"0w.2evD`mC|IRT nWb!t\^,Z8DT93-RPlUM>.Y3L6۾ ѐНHT/7PMCGvT-ЬޡïK"aF\X*(ٲt:TO(Os xm߇/TrO pB 6K?LFtbe-uêȗ$dR00-emkY\ւ^&Ȧl>У<q59 Ӟ-\Vs9֡6ۡ +=rdO7(:qMh>O`CvʽY_јw-Xmc9PLw L(C+=3쎫񫨗Pi7%0M ,Fu_|b;Ve 1'~ր?z,/l(djx@ =G9@ ͧqgԬ%}jE9it8oAUog|(h{ҸĀPѾq 11btQє*i{p/rew* z78l8A[5W&V@2t(ҢΝ,̀j"پƠuK3+Nw1Y(Z.O5>wAs=0,9PTMJ;KA^m2A:K"_U@2~MF?G<ߴ!UNy$šg!9sBXA|=C4O%rp>"H([cĽYN;Iethfݞ9&XRCrVnQ (SjU4cQPY)DKl0Ms| U`S,f">߮ Զ>tM.õ*RS[v?O'g7 0ExyUD-ީG9R6rv4:-(i[Pagf=; 8AG-"QY W,OQ}2k z'1A4NvG<,0=b@WxD+TgqG, Y- x? i*Ǒ|q2KiȜt-πҹfQ Ãr=tAJy݆O| $ڤs9LW`'> UPxB.I*)Z)BɸCdHsuԁA/Q]TqЈ]JczŶJ!,~zON'2óV4!@oVv=YMrV!16 2+vWQn&l{}7U`Ԗ]S<-Atr‚ >Ǽ'L*r22B'9{%}Ke ]wVT eǦDPlΤ=WnSq# @),v/nSap4sY|ˏpCţ+(Z;zL. vQ;8hw "tJ6Y%o`7  .ؚE5]NQ2%<ۜ8Jx۷Y.z0Mr4 j"XdTG))Eo+>dd#\6Ms1C7L&I ^|۹:R`-i6 {KJ^r.ygA4Q\~\s~,'|3 >N7FLKokU_D80ʷx}XfG&7V au0a X6UH@~9wLDJM@x9zKhW&(OT'ɮp4Ή%/CWM3h!3sT'u-QgF=?{il.өIԛaʲKCvRH(i:" H{`.p+~YUQBq&r'钚M(:;>K&MG;Lsned:HB P}v3Q!PU&ǂBumu*^̮:B|0[ ӔE͙kFQQYnZ 2HP}Eln?cB}ycrwTi j[vE{h8EքZ4ԡ9/8EfJ ]3Ra=`m"jpʨ4D2wh!\`ͥlw-`xzI,>wrN͘?#_a `% 2}\1DZ~u43n~Yz{rqPq[kRۇ<5 z5FtD#T+_ 5N,Υ+C uL ¶_ ެ`Vc=%]lyjQHeBM`(C>!>Cџd^ZF~>#g!Gqq~=Qؕ%.bšt+bHhRYMP#k57!Wlbgѽ4_fnM7pVAh9^3>ecs;|qdګ@Cn6y1JNUҺߤ#+f\(l2r_nky?0< p}uW\$Vtq4pmxV蛏+ʷNQNhfk{[ " 暰_/5i"|g14/|(v=IW>vu ʭ/21k}TW;Wv5T八n"zf@?&6WK8?P]NN*# VZB]?]O5bn^ 4wRVL]5*1J 6nqAE42nQi<}X횬]POBH_uqȕķrN>o_h!l}9 ZC zU7trf3<|?s*}O6t?%^U9)3E&4Qopf8P8+:?fjMIP'PAU[|qh*tY*͵"Rqtԝ1M;{5<e(TG◞I)(#ZI'(FI +BqO{աkcȌ7h"aAmj4#wwĠ NKM9` ˳C:^N_AԬKH6|]YHm(ř* 9n!KF>Vb{;Р8 E|W!HvhKt`΁u${X_MC#|.%r~]L-fۊǬZ.fdI\xrOA:.sR~N&|:$P8}f݁ELY{@ KgI;#RɄ9CЎNQ&hClSg MCY_C铥L^X[[?|Ǩ{>E9^^dų5FЀFfH.DI8!p#okdsD﷝AMZʤn-'_lY!{00}F h`_Ԉ2{8^NJH& BkS.³>GJ>f 5m` QxBs!X@ CMa&KqLQ^x3{\ D ֽ0x"!X^OQOOXhTFe4Ch%-Ĝ6ԧr"i(s[0*U{7;}#TAzTX}W%o>;=z[J$ RյXQ d)1`)dam?t)]BĊ]cRdfwJ:hXr*g:z5uq}תj5E9 aӮ[A&J?\؀ F$mЗGvE%}= ԟ^I;rXɸa+.q|HVc^SQ@-.uuIョĮo9ƌA ! LpG 4|e[-hV˰Q `9zR@Wn>ؐzKטR*} hΚ@Hf E`ܾ NP 1ݷב^'/ke0fj |'RKW,׆~ߍc/=@8sB)wyr.wMq]6@NYl:J@%fgKqMCA P759?}2l!>jL&[vCw-ÿK+N_(c 5+`ϛڗʤVڻB.5qL#jyRryt>yf鞊Cyֵ.$!Wö];.Vq>N9]"XM2H5t#x?6n؟,,'*B.A7xgW̟KFm96Jc1^ rPFd(N9Uk̑M rɠUY ~kXF mş ,jvy/u*@Ute>k6փ҄D4^;LO406ib > kDU[j%k1wTWYrAnn(j7٨HM,l .[ċL)=ށ **Y>մEpw,xO ,3CP_>RdamI |^0A":/Ӡ:f9l\[0̃F.0ˤ8 a uz_*幜mL-=Tp6{FGEf +ޮ|!ӼhHw+,@͈9<#__ߩ+=BZef(1ćw/.:/C5;^8=@?HPV?6Ĩ}| OB~ԡz}a˽&рw@) 5^: !_Z4OٞsḸGG>T PGtrLJjv4*X EcKY)" HۏbRoT@gHalgLalT2~FR]\:׷>A] z-J醀 y^2Ltٻ}kU7#Sc}&ZiU+$I!ܭ^CK ۂTLsdz\wLe Ak$y(O}=G륥ᎆIe`$Wό7d q?% u ^J"\N\Ĕ"m^/"W1 rBF̵蝼~'rlK=qSNoN5?@Jgv }AͺLlwd?jKBMfdy _FR#J/LLHoGW$˔s|EpJ/¡KLw͓ G|}kUWE?_4+ ^h.QƔǟ? ?rb,^p`P1-o;iE^^XErPݓo躄Kyش"SdeȮTO }}=hҢ$0S,Y8-OT:zZK-u'DQY!CnGaYnYDD9c"8 :0Pk[Y>'ljqkQc*QQLuD/L":n/)(p w>SUՕ]ÌX(Vx("@ua[E 8ECW>&t2=o6ZATBre!_U jP4JxRr~.ϊDzݑה|c1h}_Nŏ i/nN41\U05w]NwftyGwTxes3=!b!B8~ KJarתʈd&ruyYo5'^N.~$-#g^3usPV=P_2|cJ PqFO0W-Ud:;"eHDˆ^xM[JEԣퟀd-yӝXB˓0\Ao1=#\T8kfv{PhK]E1BK=*Ӱ~{Y_8Ҡ3xd94!):Tƹ\b4N7E 89uMb_.pQVfOkA\ϰsՆ|yt|s,nz쿀^͢BL'>.FH&m샬u~3o9S? ,iќ)҄ ai; JCHyd(vd71"uX sڬL)+x<=53%ܩ(gk5{gKyK^P FRlJWC;;IԈ +Df-2l,zOlלtjڒ.5|W7)4QrFaoX1OK=h8^d1C^zk8]CN8wgz4v-8 ZWR'PuO疒KN,GX0\L~h>7# }+PsӰW@]Qil4Viݪw^OQ:f A`˹`R"p;GĘ[OM`ztz\qī@\@;rŌQ l h:n=6=y]Sd}5Ƶ~`NJTR\CEX_jVH>7k[))ĥf_^pQݩh`nOa2G|klR[qĹ}5Y{ᐥڭD,Ҥf{]0u=\Qwf`"C$!\qD Hi&+_TĶ됦V,O,m>%m 3KZ" `ʢVRϋ=z~:bpwccc1kP?M iqq!pa5zZPwQPZϴH B93j㝿2lJ迟r-ߵ1*KQ0e/d[œo^pVGqB`],4aݱU{\.~,(ɬCLTjuL;I3&)Y,aN(S͌,ΕfU34JtD@ D i^l ]*b![ B.½T[;1LkxWPsMvsoY$! +j>y͓9D"ʏU2+=Nz8ͫXŒ1BM:y2TiحnufG1,@\2P>L%pҽCvV3uQ ܍]ru(;Z4$[_u4!PQ_e$f\? 0*}"3f2R_Chb7କpc%a mcǪvw/ M/zZ %MYVP 3{zOL8>Hp'* AR)!@-6mcWҘ8><b(+s X 2.G!#%o&ǁIh6QؾU);ƈ?'Hr"0P+{~E71o78bӅm@ߩ 5-HfEBiudCwu׮Z,JptT.g<5?f_B%'?R=+" t0y/HQJxSY[ 4|-l-WdҐFb"=jľf0mq "UpǩYkOC+dlTL·i09\6'ܵ7nQF!)CIfx7zХ4/O6m8Xեnl@DFqWB1\SD$nk&O>݇?DLnE; _g! SMЫ Ō_\=i'rY YR 89(b})릾%#jMwqha}}Nobץ,XQ3#Qg$dJ>6 %$K@E+MZ{9#l-Cۙy}~_A;ח5v:j?)d?ǏC_:D[״u}!}4'Jb).8CfA٘Am%8PDLwSuOݵ+oxǶ#^؜gݘ70VB,`rPEIkBU8`U"UI9 L mc˿7GAV?ԧ } -6juz3G #ͺbSx"[3 L7LxL"kDCRw8no_Y?t9 g0<^YZ\ IՋER6(xDc=0 \epv7Dl)8fyM~0V\ v^RHܠZ":O$J<բ-9w&@B}>y~DjGl <^B7?tq ``i\=%3;do{  Lk>I#P='"?ɸ G{lUqm#Qc~Ta^Іif8l<~Cg{G0J9R<ψvp^+b _hIew*!vw~,JsQa^\`w$^}*ap7y4wK'UtN O֩iDmfĠ[J'U p^*0޾i/sJ詬>/ipWDi(^kI &REՂ{O P_۞ x˳m W3lyɰG3~UVV$-SHޠ',F8<tiJkNi 3r}S'H{* ˇGOzd$)FvrˇU Ko6|U']r j AVHyZoԂ Fw? y{)S\a7qƙޯ[)_ќFf_QʒI0 {$!+xN?L.VX:Pp0fϡIbXH>i#o:%&#NZ*1?>GObՅ?N-֑od/׬(聢 :i,\w[|:9=kL5eԻIJh3@RZj[EWo9dZ~h >$T:J/Jb?/ v "\ż4b0{R!| SyӸܲ_Y nWS/wixg.$cOX8EN[epLe~q  !Go8t㉃(d@LMnYEnz-W{z)q2w?ajDwSM)jbUNђ##va G.Q9Y Z׶DK~n u'W85KaY!@Fk[aބ\yj;¥iLu:ۧ77mIiȗ-K S`+sr3x'A/[&:y7^Ӽ5¶H[2U5V$D;^4JG] "|`5 ?Iѱφ* '1wf\D]@|1gL6$ l8|dQi`ϗU1Y[#;x񡷙p< TFN--4m@8󕉞Ȩ]f5j"o}Rݧ;@:Y8c0%U& W\{88i+I*>/`RT'Ӌ7f|c^ŀ U\7.N!֞rsO6m*Wәpٔ{ҋ;pU;63xv%ԅVĒ ·a\"ٿh|ɚ- kƴTKCHPCU`;`)9\ Պ4R# Y fP/5 ^Ē1Z\R=h\qwv"k#Q.fS I;:HWV Q(cx jK Ġ!p,ZpLӢzw ys^EX.nu . u_s΄k!t kB=g Ǜ]_2#uQs2n1%v ֛FYmS%<Š}7$Yin~<!*H .r*Q_~*8KENI)j=qH߉7%փϫ:ĩkaLb^wL1R] 302jE B n0Q .]#^x)ȨO>(`9&m]fN8aR<ۦ,$]a7&jYMnMW;v2Lc W .@5lU>Hald0"&"ћװ`90oMj#o1@οmClG!c&X_l`I Yu,PKXxlyֆ@ŭԏXAof}E4/Z*:[E*;+M~.[A5 &iEv:G]BP\jIh>QsL935smtMI0fD 8XƈAgRa 垵kh w5|f/'c2;Ag{1~R0;\YG 0?cE?lfY {T`OzSq0zn$*XI@."|.uS*B16g- CCn[a:̨#xHAkg^P: jEpYqK=c'K.<o{.1r35|?+O*0#ej6A8-RpJ)qX<i }`-[qr>T#Y>@'\$Os 랩c$UoշFiCFnQT}ӟg+H&HIl4~:+k#@^u?d!@#ErQ{XAk5u;hԜ i7 =mԎ)brY,u^hJ~ӰY R#1v@uT:|(8kxcrkhEE_ I,LJpgX6w:!lkyߵIL5@=& XqtD~K`mxthZ $J-!Ke"s7 l!&# 3̦81pԛ):"ijȷ2\-P90"aPueAղ'Z,3'JʹG e@[}@4b\/ؾ'tҒ;]QPr`_N_j˧J^gm%ܽV-idZ[ʈnf{nGT0\:v&]kk$d(OXY)qz"JNMwoo:6@1.Ət~\<2~_[?77b>D^8ڂf7/35 0i֮)K0ء0Y_<$ -&\j!"[,q.7|Zƨ^v rz)#iMqօ/S+miI(2$e.7+^x&7 ,\2F l-^~ZQ&a l+Fbeu-Z\=9BH{a$de7wD/Zzk̜Ctk,+MқtگR EMu5y j:@]d]3=8mRa?[RTtM:tKus}LY*ynu(Ks%Ub 'w"y#@q|{.II"%[V'cmGvW¹%9-I+|{\+I~'յ2K{#忿A^ˍShP)ڰbZ}q"+t)oΆw74?A\ ]n /Rbw㺁lG 4;Q'_$W,̵\pkK <0cM8L㟲X9l3ѴeKiLo(HGZ6NtN[1S =t0dJ`T1ܿz:f΍\X(%ZNʣ?{Nlh!,ɛ3{~P=QϢ 6"9njX;+,-E7 ,u70VS`p"GYJS#bgy@ QOLn|Wvb:^`/ DM-㡻lC)Ls+Pp/$亂1۱1PFꖓ\a3^*9EY\"}@g2-}xf'77SH䁳G"bW[a3C, !=uj0kNW--nMV52  +ȉRm\@a/ޤDIil?=ʆA 6|ƭHcDAW^㈧XHv@Hz-N<#2lp&}"ÒHpAL)[!3@&mnNa`=:] JZ4UH * A2rap_M]iH | (1$\wH Kjok\% -1νDN\xű4n,j` }m^=0JEv cS~W*\jle,QLTGùr BZjhg5ӶXRQe̡t/ \T+Qu&R6+^my,쉡- Y4, 4Tئ ?3&~r @sߛ$ W䍸i[c G(DSbÎn0:Og ۺ!XM$NS?N>"}Tmg$_#HQd3pEn1YМLeì&+cҎ7;:V']pSbS,\m+ۯׂ֔sVnn,6Ph\CMN`)I~ Bn%obۥADZB+kJFucD;9م }FL^CCV M#ՏQ5uL+M*i.Siy^duOcfn~-Î%oDJ/X0\Qu C𸋰 ^G4dߛ@m~~"$0˙p-Qû]1e)#!h 1yJR!ӎ.kE":m&JPW*&p]0n}p|Al ,鍓 S;7-r]` ̚և)t Q%[f5(4gG}C1 f0^@px: G?(,5p#C@3#'4ywc^%v [Gp=̀r}02!(.?ǚ($P0a8"VJM.89 8%l`{q̖73?ƋWo PkQU8G̦ٲdazDBoꖛ 4!BL?t k_ؑ Z\0txo5ty<71myJb(b)]w}PϼeV(@48,"gL."$ EȀh)evLiEOpio U1mbQbI ޟKl{[PB"[~O:U`QVFcҼ9g&-Sg!*tۿ?>\9ߺb`'c;eStK4ϛתʠqsuHLk7 xsrm"WhMbWA{'r #nv&݀G8_`xk@A;3Wbːp·c1iԋo K7Dy@J5K(;BPbn!=|6n(3br&ӯ iŃ?}-={j}+X\ēE8-'9cW* 0D )n8C6Eʩi[,4m4B5?W׶Ijm}hTOOi8m Dț\FYWc uOIRdȕc&f\6.f΄r-(OTrX+jxp,$ab(D#h90\Cz~:Q3a;Z}XOqWB1^^W<5}[M/k>[--'LuC޿,Eɕt\gA10lxevBC¦?fyr*#H*(N 0d\NYK!d&S %F a~Ev 21[-g)gL&?&U/  ~a|*nz"k>na"%bs1 8ESp\A wqWaa Q&d'hq7{u//%#Vj| 䕆'KoeFɬ2zID-V!p` #,rܒ[,۠ûUNY&ξ%?OfBK]2)%}[O$WX';p 1 794B5*`<쭍(2E#Idϝo]<sL~* NJ; ㋞qFLhpAS6lVH"ӥ}d]#Vn+y9-*ŏҴ(1ov$d1nK xIF995O_3X2%> ְo2E%ʽ௰y*ëiIoNNþĥXۼrjvK&*%$2tcA5 Ɍ$.'K,}ye{O^;'+H!J RCm3E&~BʢUV[$&1}e8k12/Fh>D.U+yBMCQVv " who~p '.a դʟFd n2Vp܋Aق|u7u1ʯ֟t{~H 6DlΆ(s 3 Fa~" 0NWX'6xV OdZ%Vt\;sL^zWSwH[,$1B-S2xs/yl,򌟎 H`+û:t>*è^ʏi ]yU\>@frTZ!WxN(u㓐JrեF®8~u$GNy~iY˗%KCw: W_}lKM1 ^{XTA$ Px#-4N$Οi7ư`MAfpsvÛ6F}CUhp١k(p-uėKb>w|1Бo~+e+x}Wrg,f7͓pryVP9rGuNi"2}~ѠBei*]%ET9m7)"")0 U~Q4E},.ظ;t'yBVjPU (n<&2cxr^HC{0 2۹TmeƒMIKiPq b$&s7KLJKh1B{I{tc+o~-wk*3SFd;)$>>z7vI(@h吞?@8gf`~8= 4G+DKF :@Ε_" O'^͏!]'lo7mRZ春 Zc*\i2활?.k ņ}i(T|} /tC=yU%'H˕W",:l|f"_@'rK-p۬q^T+S^&l1$ >8iж*ޅIfIƋ yϪ v$B\mQ?t(`[Xp\v\ .cOP|}:}Dr-I!oYh5%X]TR'Nm20Uill G&UhR8Qs㈤Յ{Rt^뎗3T> fpĐIm„r)Yİa)@}FWi#l 2 o򾙂B H   ^,Cla٬!)&`BbאDRe3l%#od, !$G;Ua؂y.EϿ4?A.+ jj) $5bI~J$8ˉ)QA'ۥwt&*n=(㳫xυEz5--lE tD-DU+u8+E o 7}E=˺%~FMޱҥ@hq{./=\m91Z ?Cz?)7C26ޘF.6}HJŹ@?Ṗ! YT!I6.H6׹Qq"~r6#h}qK'q^ A[h{gZ DlWuйͳ ƥs!k2-N sG]2 dO(7H/-c:rxC},;uWkv`!Ylr%ߑ\M }9ʭZ- a71jmrYoP # " qF'sTnÚåZχM \#O%._^sc=1%=Ÿ~ RF _sNSc{g(':ŵ:dL0X=T'f+[ 2 ȧ=}]u5ZaEw9;m/Z~*->L\6vPW?g_%#jSMѕ<2C9 [BYj.$m>iCd<YJ?TKXy-m A#*YP .jS׸!<@2]0?`E0 76H]YiNPcx[)#+Qj5G`pr|AV;x1cu¡0؃:z3Gby\'ZtGΏ%$]ЁSW`CX@ԡd,!/%.C=4YG~. ;W/gnN-LA,,՞5"HJA=e}?Z1c0 M!Ud%Ъޮtx}3S>R~e%Tӟ&VT1/_m?O&|Ehb 8*5M7iڊUI@84^jZp = G%궻͋r2!Q/ְ#2Y+tܣ" FY4~KMxDνd'5{#+Gu@Z7JTЧ#U ?*6߿G@TA dחi;a d'OdlуrgfuyN҈Gj҅B J- XE;s!:b+ FD9`hi}*lyva=t΃;'KW T J}Щy\(q:+|L8mGHd3K@ /\'oV `.ߤZTôR~ʫz#ˌ(Ieϔ'_.rCEjM?+H!􏆕zW fg5-<Av>GyDck5t?)"ߔ/?sAd)_u' ̴4'OuI.?|^5Fsԇ(m./-'yc08\WHY!'I:1: |^ dŶ!`fNl{i0zvy$T<Ӑx%B 1+ l#w jVTJH*ȉÈ~\k| ܶ5n^tl69X.R.\K@xdc0]Jag'ߣw0xS:?~c M.\Iٵg2t$/xD3oMfD>::T98z A |Ǘv@ %p=kw|ntʃN^Y u?#՘jҜ:J^_FP;@e8LػzQgOQYIE\rjռ.4ƥ,8b(TN#.2Rr'+ MSVW\~j'ߠjo:3ܥ?[1̦Z H P25"aٷw8R2+?w=V؃*&D}39QΎފ4y琾GhdTJqO4xP\$tM)D@t 1HwwV\LG;NtLh?L?9$Ѫϯ;F l.ݐVƌWɸ@ҍb*I8SSեu;/=dqNk[v9ig@ub[&2&^d)g]y7U7z8sFV(3, E`l6₡ŋ^BJ(lT_{IN2ٞ Nc4OбadjP'~jmNtoK U*@Xp#TjҼ}[jvThQ.;䔩텭O4 G +ydTQs$mĕ ʩGO;[#{Nk=$&vDw2c|9Xȯ_dzφp㎩my^%jm XC^$,Ajj)?"18Ìc/r*19]I?z1HT"GL3-9. ?KaG<8U.IOUCmEeNlm ^$oZ5d3)(J_ +8ܬ$ddM5q)(3acv\ٮ<RcL4#B0aTyGWɜ0":Cs?IwGAx,?B ۉ q'IfOV7߄myܥǑ mHڰA`T Ng>o~&p%9;#;e4Aɹ7 t={sTa#C03ߟ^C,AY̩)*(CkR}&op LWg,D#*Z7𯟰'IÍmlu8U>=ArfU} \0-H~rح^!p*k]yYrϲ+\_֟ zo"a3{^Z0VYUD' :bF7],eHRm|:I3D]+ xgh[7=c xz[LBh3.&7#zRGbԝ u32*$nGp+֌wtDAτ8ɼuՏÊ_&<c0@Bc*ka[7qA=hڹua_ioyOP6[@+.b/8`.eWwOOJ MIz%, :Q2piToQX[ D'(TPY,H[ݢ TchFI* sNWe` 9]3GɫG3rLz/a;n6]q|JӧǤ:4!64ז5>CڻG V,ӻt{}-dAFNܐLs%霯A};x9H[?ݑSCpzΟ 72a% 4ƖAjREkP-Q{d9ETZȏ`UD\R(Wi"4CZy`ǑNGh0`+ส^`B0I-vI5ɝ45bkO;?:\q17Bhj{0,F* s"\7J|>A`F'hOEi ڝ|@"^WmDbئ: ۛr|pc6(oVgp0[mSZA*hzOSgܶQb/!#!{K.¸{JZ&pzG'=jzRv4Jfm-ʜzSOG>E~rh.ׂL #ikԋ9?f U-Rh]̻͙=?]L\1N\\ĝ"`W} VJOGS)fNC0d`3nWo(+*5rv"Wb_'ye¬Dec]y6l&ŞĶ }oe`7FbA'M;(MIKDP5euo3ׯJ28;9o'6lЌo& `$ggq,`~\ۂi4=35־ "2x @ҦP,`i)>&:a!^t?ihYdtkL' !Tt㪳zD'uoϝrz'23yo$-:xt&> (I^ S5rH %^Z]cȑ=T Y W1EZhi(|ڤS>[Yيg<`lCكoP_ޘ6EL\۵>K04Ȩ  dapP?` _L*+Ι%@3y7\,DQPЛgġy}4!iS;cƱ;li\E03YDVlr!8_*r##>}ͯJl݌,q_^8ʐ,ycσsw_BǪF=ϧVZs#F/Ծ6Y[c4z}[qz~ΗyEť^Bp \{Rqڗ=叹„bu"ѳ3;YR+n}-2<=GYh~zvBr녤*V;O/ uyAlƗ]Q>i箭DYNߴvq`]sYGMgѾӸlAd.u3ȜXVazU [_T1drHN~v>%Q` ]9xq (0MǛ.;laL-MeJQTZ.r'ay`~x=~3qJ{׆?b+\~*no}vok D0h9%64i_WPf c0U@+Hߘб1徳yU M؜4D}Ӈ=f<+l6XXKº"ۮPN1$65q\-llZl#XynXUCgu"Ba|j{t33%Y.ؘqXc oϕׄ=c([.t_z`QNbM Yd=yיF7O00&cC\N \rP-xQ|A#U4L2% ɼ~zok`䧙\wxm@ۻ[$1"5G]O:|˻Rƌ,2ګB)-R3\Ա램'zmڞA7Pph~ Y8o0&yD>k'M+&7M3ZKO&吸Qiùu<9Onj 7Y)_MpK| ZubƳ+&nMIG(9Y3$T6l&0$- [G+ޱF$az0TD}e8=R3'jGh3̽R (Ϯ_+<[)jSl1@|-) (^FH>0_}e`h LUIZs,5ߏo49*Kh#\D(_ vmp v!7Kv{<wݲ/ͨrҜӧGfNM]%Փo*o+lY+ǬZHTy 9a]pb O۸3s9 +TQoB$DN@vv"Bi>ek/;Gu0ַl Jק<^CEAq,*ʘ6*c$z_E(:}Q J[ܒAOTM,(#3!7GK3*cXRE[*T(lpQڌi-tlq-)nfk/F,֝";1nb νkLj5p*ײ*B`}ܞ k:+ywrQ03?T-2? zz޷h7sp%{JuX`,;iFa>嶇]@DSf-e0)V3&Ǟ;QP&2i= ܆o%)-zdɔ7}jD6es8@A܈eO=ȏwI0;]agNi&``WnXow#w6GRb`>~R@ƤpI/ 绠WqU^MDk(ƞC~cU)) P6ÕFY(}st.#% ͉IwinÑʴ SZj~:Gy U85j?HI' aqh$v @&T G],>#7(EN'P7{ @\ӪW9r5wyir'K )LA j`$W26ZŸv'qiq #Z1 $'\t-thW4;Wn%?'nCO(PǤ w:*XᤱQ)P<(X< #՛Ss1j !2Ӻ 埃~&8UK?Oe ־ U{&DJ0N -p׷fJ)ΏBi` ͬښ$a*nsJ2q5V@f430s e %_46 f8ɽٯt[tU'Mba=.QMk`:pmhKWuhxt&?PE9t3+!=SHiiB+pr%:#q#V"J1ky׾Js6~?F]I{C_ + Ymx*+_(hxdfmuZ=v9` ߞOua㻥_AT- 1JU(8^\]fOۓK]U9v)_7%NNj=W6Ʒ X~Zҽ!CJ1R+L[fs7.Zӄ6 ?y|>c7 F@a;o6!SDZuL6|@_,@ZP7tzJPBOf);,]I-'GU8%1wePÞ,2e FuO *K򮜷6P沬[18| j-14l F7Vn'9%9i/qe[6ɂ4c!LRo&j5#5,m",z]~6QJ;@࢘CfZ+gEnCwnf>GN>% /&v]Jh ԠC',4*%I:$ؒ?|T&pb,AB"K>gMitPO?sh .Gx[2{a-u00/ތb+do HX3_f )n=l%D~W0aY(('[6Sb X{?LKS࠾JZvj^mtbm&~u>!8-zkZY~|o^2f Uy|y<؋?ԗEj2r[Y*J=A/T,Z Z'|7Z5z~A1%MtUA !ɣf%H;=* &RՆGs 0tRo"Ac!P>@䖣&cږGHM1@eML>kLƲ/wfl !]L܉"Il kbnj⛕ dȵ[Jufhոl=t8 e:* =y;xon +n5Ds2"꠯2d(Z6]H ڞ**Jܳ$CeU*ξBMMk|n{Zڴzu&vTH3%-oE#> >XERD8DUpZ#" ?~/9yLIC!HPTZ!7rV*/eV`' En4|Ku|.Z5ZY*;^5ᗳ}8u,D!( V%8E ߳zb gO3ZxcןuOh*?.1F E *-sqN'pA?qeSEWne3wMXyI3CmQդZ_ѕR79oD;=pp @xRGIZ'c#!3l*(h/nqgwB/lcv, ,mDT\H<yc|{Y_D5%k5^5ěT (fi"MGeU]Ӊo֯@-exQN]4ABqj#>pES}qfv68QĴc$~c]qP^C! +CN tsf<~eDDUIx)eq@J^׹wZzT)hV"YX#1~&fSC]zb?0:FKd&cVtď0ia)Tm)x&}G+.*PˈFFP`M:+C7w3LC)UW5æ '?3S^il6ݵ &yz bxkiz3Qo.Bx߸*/0g!>5X Jj+@mV53f«cCQ9;\1dk:9BgsEזo%z!F{ZJ8 ZL1bF]W(>e  {jӺ$O![m3Ɲ9'T!K9[2 Ca-!FuPs)b][ e'q%3 |fbɛ8WAyLӺs3@Km+M0WG|mݚ{Gs)s6{KX[>̩nl $h vd,$^E>P,TQbnh* bACBdӴO(Uꌁ9zz:QI;--й e}ݢ1\xWFf^l>%XaŹh=PB!{-y

~ۨu!zw^6ye1'D [K Ϸ$&}\"Am]~০JL)AXiR|~! 22Wl$`򮐵{UFڭ_9t"<3B+u5n 繋9ҙϾnJ EQL_` *INQOKG^XT0}6 ;1gp@mfZX'<$U 4r5vJ1LGYs]*s^Җlj >YPq*^A\/(. 64}CZi7Hr-krﺐ{;-T"u u,Eid!7XOݢ4q<)htsjR.rIhe7E**̒Mr'FO[$ilwCu,0ZTb+b Wm1 B TBUf+i:d0B"fW+Sm |DƕK~yz ;oʘFһfQ~r l%^,jZq>qThl6''cAC盵`)ʪ}ýC43r< q0M/ Gn'I<ٻL~'57Dl1={-%|k O-/ AK6-, ƗXGږu!j^/n_cL#WUgdtEk`m0w] J@+o w"yZ$L]Z0ڣrVy6γ H܃E5_V烾2:~2Ikt]o1C} fYU-mlEůÑ:]Zd/,1y y;D컋$~jwϢp ZK,7PLjX:(&iajŰuaw lht^n/LX,n @\ޗ7]@>#d٦DpvvI tKMfoP+QtelP47<)+{(MQ("dTwtd, z;b~`E K.:moRÔuu`?N1s&$Z%E#TK]'"/^pߒW)y)cnD2T;8Nb*ҷzXk2qYBkw$OJ@&wy BR;`hOaF/`JXF9%6/䲥FMyO|ljEo`'XAeU}2\^JLMk7~GVaHbaR15zq\yL6/Tf6st!_V;IQ Ӕd(Jv)Ҏ輟0}:!S:r2 [\2!=C/d ^}sU $|fE(~d5R+HaīG;qčCCfn=(hLDl&AI=CA/f"\42c(za٣:rAVj{:Eu*̫1ÁvDR.. s"o VuY 2y)=>Qv: .'lǁ\' J g0ڗ Th5 !W+Ä֨n!ϐqR#BIBU1&߭ -nfԈ -Xbp_7n]0$ 3Uci^Q#j E͍í?4Yq(;H\/[lwO : Ø-K?gy2OV/C|ɼJYO1˰͒ҳ`0j9d\pSbUWkq,d/)/ `xXhg ¿nX`k>rozM94Is%x"bp_p*VoFs&rTuF=2ՁynGSE]rjڭ@Η`{iWˈ)B3gDNf/֗;)_t1LvW#\7$ch&N7*$cCSt,<-=PVL{%)CE*)BQэUC ߎ0{pѫl$_dATn\EG:誾Z+E-ә[Zi"c'J\Z[Msc܈z\#rde@Xgw')1iy )0'mr XIqQo&\ y N0&A 6 3_^zDw,OhH{'sE_eC'el*i ]iiڠRŭ[& ?T6m_K, 7ngqdd)Pz2oQG>ߋfJ}w \M+de}G>z'W!3fDRaIt"ȁxߓąa.sm+^EDX⠛M>X孉T%Po?pwv;{Àخൺ!lc^(bPy]l}ݍ(d7>I24"8!PV;TUt{nHmolCFńS(FzgP5-)hP7RjjFC2(13jA++d[[ ϩvrvq$x9wZ+WszDw8܉qrS&(\9gMZ>t> َͨ:V !n&#ŝg^$#Zynh8(:N1ԭ>]Fq8FR`,m({/aB+mN.i{6QOdMFkp)3oٯ`k ~E^v=J6sP7!:+>pD֮sxJct絖WK * . FT{W۸u[j?'ъuW>xrHymli$2Xnb8+^逭xPzFWCL\KGXt۩E_̊6xn]A0S8(GSN΃;TŎJCT>Q9>F7aϦ^Slۚuzۋ]*(|ƻG]AIҍyj6H+ [:2/]aڒNt སjU|;BLKQ\۟ 'NJ3F2X&=vw 9")>V7w72S(Jm[s!zx9zG=l/AHq/pnj%jjA틴.ՉCG}v .cve=s&ܨ;]:0\,Y0k0T}ݟH+)œ[w%)Fǔ74H}5*~MS-PeSUcB JK~?7vĆ~O,@v8TpH Oy?퐩iZ.N>ޏцERu7 gF5u֡ޖe4rNAB{+>-;-#}ѡ`{F{_.[4{Wxri0q+G(g>b*!fL{. Vx;6tr]7B}D-,I wa#14 NlД>wܠ 4ω*'Ece%Dy=WK1R5A\7j^ێ+n.JՙI5Sq3_>}haؔԱB5>mcC&:ewr%vQ^jv+vi.'TVO܊gsԑOT G[ ZioTsG8'NP{N1me9ޚۆc 2{!}aYZx'棔/{*#&7P2# nSw|<=~ H}cP&c.Dp)T 7?evTt=c.GADIn#_q[):<7e.ŋ1aa7/5iΞ'RUIOǥW=}hjIhpbM|6z x|I6¨enir>ֵXGa3Im*9aߝZ%=[#vQ}(Oҁ3h VXo>b"i Nj D]ưO%E[džQ p%%ﳬQUG+ʁoB[ L;Y]c;=˥,Y2UJ9``' 7*9lM7p қpIc6 lYS˜vjX3G)؆°H70 o>S-Ms+͌㵭c]&6 -X- 0 (5e 8>Q#E$t$Ҁ8dx2! %]%"C)<̾V+k~F WU&qh˚~vdGk:Qٹģ}yVJ/uAo,1lפޜ3d]()Ps!x5oH_/1lwr%5J(# rϾ V`紬ud7[sHkb+-a+W# AX0-+\]EH(uqhhx/ƿ{w{tFpN?^ ;x8' nI+åeazx8pĢB0!n]fa5L\VB-yc|Cd1_CRlS ߸4У@(XˊVԫQ;yvWI3#Qw[1/Ze6K85} @x|^GGp ܃DCդo c%s5g0YZ~ew6d;hB&R;!kKچǔTn$!/؊ Dpb6?Fǃ{$6(tO)}mK]#.4OBoEsbٳ>e< "R6K3WDJ&d]@6OsC% sQ?8 ([vҝ(Y!+AZ9Mf`;kn#mk.%j Y|5pQ]yeG3ÓxO"-_t3v|tgOm,( S{!Zj9,FY-\9- >-GM@]C0/QBMS9c1 놑(YtI囄Nq*P6*W"->jHvUDRw6A]^7mZ'~w S,Y(-쀾*S18 }43q,L?ӆRӞoe5gWH*4+JKȻʧT$'sDwS)#= *K|.k䜶]D25>1jȦށrt!$ŖFVJR`y˞7g\snȻFJwE&ek@ٜgEP6|{t+ǣX1]r[T;d"l7] NĹ|0ܴ, {;c"s|vRUGr :4? &eb+K.k1wbT)P7]gKDTxTdcw亜$LYRd-N.t\.~-exQ(=QlK煆8xMx!&:Vrk*#$]]xe5C>zYH^w>|%cТhy%T)fɅ녱bs g<ِZٶx !!cU|.Q5nך6J|ǝ:ld;9h3ҭf)m 5+t ɮ !୴3E JmoCVoj 3dQѢGhP}̚7egGXncXe4}ymxCArbY\:L)g?T%(Rz%Wp8mKEQg1#qrWY`>1)LYvح,͜NSFh3LԯKσDpn`%$Jdf48$9=[Pi5(~PA^]xr2jFw4Ghb20`I!s7uz/ͷ0 FC>DnHޕS<zD'~q8 m%^:\ vzrzu.nQB0&mU\q_D90dݲA\XO7.qX-^s9i_,^SP9?}btR v_ nѝ^$!I.i"cgϚYdQH{q F:R~|5vhV UKۊ_qq;xN^TİWMgԗzRg_֥ЂX}dWdp DV G]7SACXeH]ՠ v;q'Um5D5Ad>.a_ I+\ױ;bk[U9< &PWD.EjδOB~p q^Lv_ WalTi }y!5<ߧ?9rX1W՗7#h.p98Ӻ/u_9זH%aXr3z\֬^BdLOٖdžEAY19=B }4ϗmN^Iߥ׻܈Tkh[H޶#3#ʽM $]ST? h?(Ō잘 -ၴ%h{8oƍOZ6 D%D?>nmX+:JFtS qs6f/\7i&ۉM17iGt,YQkdԋw?T/P x*b }oa2}!HTzwTn&8A FڪU]"\Ub@*@pf)N,N¥"(4ث_/6nCJUFG*&NBwZE !ݴ  e'(|mHzJ BTrӗYT#%ٝ&pBsK_Jq_U?cV܌)6]Y|4-M1={EA/Ϩޫ+ro,knfƖ#=.z9qthG[0_i"{ Զ~*1ӽgP{w'?d3L+KN~psyŶ:,bY #*@X3f A%x뼽zZo헤!C<ǩI%˅&q/oG0w{2#ԡmyABR"MeeVG:佼37܈j8 @W|0Bǣ%L,|x|zXѨ%ґT`#\gC$CЙ-EM{͜؀F__kÚ(x/suSZţX;2l,a]ҥ5ENӍ` $1A))U!「,LЖ IԊ82s|"`BZo3D S"4d O`qXl]Fu$K{oOy\!\&15n->_=tML>aM{YؚK68ySWg=u'2 8"Iޢ9_@fgp/T=& oml <+EG859u)?Q}ݏ$ɣW0/|!jΑeqA3쇡"~wQ|Àzi_TnV?RsP.-1:;<H$bEIS:׊$UW Kxw:n* N!--: Z[YRr@!M!J`Tad붾5qrFe]Ф( uM *4#䮘E|" q듐 )"sfqzI7NRT .[2}ޟT/MgX$G@+z·Q@4͔敮<)(&TA>{jx|vv'nSx 7\T0Aӽ$v?mYC|. &\AhZP787Q^%>>%'6Ag_Y k(Pp NcO.~˜ msAI&W8^80*ipBTD `aywrL?5~ѳo?yڡ 28TM'n?Kk=to5mt?o䜾gǿQΗ]˭D/pl]RA-/gPw,3jD;TM ;OܛSˊ ȓv+It Έ pq[aHF foPƙzKxSwK#q9f8OPץ{K|`g_z Kon[#ƃ7G̝b͞ pQd ظφ0.^|8Rw`W77.ڈ}nȑ% ʣC]EP͊QZF1jq;ݩW6+b65QZT8]:wFbp^yܩodQ4Bti:ixoD22El$@akfZdY0Z"v4AA IwsQr"YbER2r뵸>TXGM Y@(@},R෽ SHYB*WYdᘀ4" H{q>i9`-3R i.-1P Ly QmgO=Ƥݝ~$6q8,g3ݢfNۮ~wܢ w>jW;N/`I @~|O65葬m=W=|)"$[06`RLjV-JL\۬NLB5NtR?~X#\]Gos߸~9;㝭8ٖ7.)l@(UkֹgNe}RMq"?$Ӗ< AJD%CIDHmbU dA_(,cY!ˬ#Q"Ռ6pJKC,E |w88uL'X45!sjA  Ht7W j_;MPk`}57h)7QX-9R*iH0;)CE u ֛1X-n X7m3Cpd; zN_u 9gՑNTFe& C17I%CK\_S1RJT!44N>+5[񑆥@/3,Sț\R%=N ڟa0AmR4@_pӊ&V}uƺ J:fr!S>nCMzeC7!$=.xOhJd߲݆F}-Ժ>:hO?bKc`훠#6ץFB\ʟ$4ZϚ 0Pݣ_*VLm:qpcJV/@z"z5w  :U]'▱kItE " 7dibXlA+ӶF` pGe 79q@ҹ6=I4PDIdR_,Ap6ߛZeT3^( 9h[Ā-DvI&tec BvEP &\EKigkAKC,3aTI49XQ}+ xGm?1x**D e,&HVzTNၐNIS|Ydڧ^#ۄV*V3ff+4.XԩK>/fB"6ZP1YEhZOxB><7妋u8B*<i^GcêcP&u;^g%jBBI#h9sY;SŸ?-y8Kv8@Zn[mGTғ+FJPFG!ˑX??8ín':SƵ̑#fA]_{iRAn.ޗ,Z֎ fn>BpFΏAS1ɢ}uh2N䐜ԤPQVEW3З ZTm8΋ /vH ΃e%1;%c+My~:x=dyU98>[t)(~Q2QJu"s`N9Q.2oڈҋ= F|RCh7 z8}ٽ;͙cgh!Pԗ6=%m 2rkVʔ`2 /_ Xτ䕸Qj qrmrJ'l;]9]TP]\('ʂV Z[ew>rߺxDL,\DT.w7ċSl?%7X &rZna7X No6yx]I57*qo{ӄ}Qg[LdNuAS|oB2utgᏉf+iSV4bġ8 Ḍ[MIo%)|WR,& vVXj _-mj\@?l,:/7hwٮa<}9Ц-i>*~\9%0ZI<#3`TzW%b(Y=ӂqww Xcazk ⦝j|YܹX9v;*7I#ɞG9Ds.oj#xLɌX(-&Pmm& G}~iкLźr~I[)` p= iVAinMh;v1u*Ayn BQ/sjG;WJjR*Gz<ྠlϔԹh {[U8npGC'yaDq# {} ;A5&.!hv3Ũ$dW{1R|߁T79XyA yjj-&|}9SP+FI `z7yqgv[uGR]RFUY V 1)OzFjr ma_ a"[ҚJG`~S}f$cy-Q*AJKzv9DZtCX0@h!w8/E Pp? {+^BC Ǿzc<?n|fyJ,Po}17c̈hċҢn/Z}<0dD!, @4cJӠ!0Y(N~JHx=E͎ KW|^.Cx>zGB+˥_@a͹V4BK\Ҿ4 @) w ;an;BzxNۖ}ctܴ#)Ch{/g J/4,1]Ycɘ0(?R.[ ,w@~02).o5wzײ6ۆ03&m0$j1 PwB3tfns|vQx/?5EASC8sWښ o5"rnLY~yX7_l0/> )akXzOyw2̷7z+ewjILfejH4Wִ/q \ uT4㖬B72>mv!WA2:;͆ sA7bXO ~HD؎wLx!n.!k3[ni v*Mrnv_;uR{X6Z8RTDwq<78-JdD?܋"Dad2`Rz\IjkemmdsбM4I~"9Z,_-x2V{~餜84xUӞ=AAe4W 1j<͈{[gᶝ?1}fv <&a鞴`0;?GJw8'9+Qm 9~N UFHy03$/)CǙ'A%]Cy6 {ٺo:*ɇj)[脼L|˅~Ƶ_ըvõ?FUgN?1=m2ˡz!18m{n- GJ@^#R0BC![#SJ~ն]t4N?~qx*$_^!* u\x ]s~7aQQUoXF œa1+bi锌 1R/$|-.MҪb1Bu:d%ҶX#lQQs\ v^S,(?1ΑvKĄDTCҺ}{wʩW\4pcr?X픃j1L-1T[@@;}SVO*Uh,mp vPW4{ >Z"҄aQtyS˝!E\FߔQ~FO SsYG8l*<uJn%Cca5 ś !dIm>3!b6a9UxQKUpS@y;B0m)@XE8jKz눧sxV6z8D<Kd%0w*z+]܄fՁp#&GN膝[\=H-cE~ZkhxZ)*{#! 7IKǜ>Q,}f4 U+G@ihVĈo-my|zma,ǥTR $'."ӫ^kJ4"wWH2Rh^!!Xs!q}r+ .W`Efβ`xX{̯P* F9z|ZGj RH$4$ü.4 t((tT2@|3KtɳFm`KJPiM^9'4R3˃j]yN%L&~\J\8P]$Ƅ5W: !.QLT r6 W;+q P]YC<2LmF\HDaw[twS}ghevVU54^%DCz oܟh!w$\-\y)~,&pk$29s#QF9\KqZ0 Z(8R/RfH5C| |PBFS٫y3(z޾wZG[WТ ]ңWO?AE_cߟLƎkbH1̑ MWȜJ]N0W)TXQ Ah)Ym ~e?rrr 8LGcnjtEwCX&8C/]0f{g8 +6Q;-@pV(i}7mRAf֖I畖EmDyFiɫaSWWؿjQe534/^yp۾=Ms`ɖMũFgf<]Q\`W/v?ukBpDD \) 4OpɦDQTݣ?@b $^x%ڜ1aɛ=WWIEwC#3QFv~* H~Nn7?-&I K^ ']|xOonʵma^_OE-Y/)`HWe ȯ{OaB=#ag5K~U"B%zH݅MDx|"MWӓM&sRT$䔄s!.2z47(0"8$3J  nrH5\,N=Ro@2$ڽ?s͑YDY4@]5K{At$TPEbX& qdA%%hM%Go3 +Y)lzЂ] ُpZ$sjDF.9^` SlAL(`ryta7g^h>˘YI4ItmzoֵppKNӋ$SY$5괽iy( G=H"EZ^i*VRԥsuCb'#@CWb:%/%uC.pƿMD"Xiק|o/E/"!68y:FD>}bua8"m#F4b%j(BY/ܜyGyGD:֣W!NRh7q *γLH1j;4l[_} +'= B*T-SQ ܈Pma{.9Х, LsMٵ`A+AYY-݁RUp8dSkwacF\g(vw10@ZJG8PB/7vle;G@eݦDr}Rk/`~$@8JDoLyqi`xq,CeY%kYnh)>XeI[!=: am hpmzbگ'B{KSOM<W 2ɘwg^ަW0Vu>;ޒڰJ9>>WĶNyX^Chf;S,\mސ^W:PrEK# Ԍy:$اO_pFbFq Iő2*'u"+- bLG b!qFeң/1\g%U\}^pLiІᆀttmӴOuاu|țdk*YGGTTa&sd/m1uCaCo.pM4_5㻜wB/Slzq(?>T\)M0; x؄Q7qFk2A^{I`7kܶ&l +::r;:G V#][9Wضk+aF(P54DE5.3Lڸ{%Raz+i*ݔXZ؟x  q  V*Ks= CEAF}40"֊xEgaOGZUxR?}͛ݞ/8/ z)bla!آegQ=T/g|U [o3$5 cwv֝Fq7)%$[XYxe;Ux\ؼQz(/'[ uP`Un 1mŴeh۰‘"K~i9J-{>xG7*Etݏ ny_b1?/YhZ#ôDسߣ :$8Vku0h(o˕#nCq{oexg]8'.39{FYP&PUݥX<.+rϛLB;gd nƌ]ox|7Hzg9@FN \a/L/ v/ #ő4:Ks6նAa5SW<؝NXv|wjJT3c h$~Npy ӺK7goAǧ+25媙f#u|M;<'VÓ46-)(+i߭] c5S)arFzATN2IHAȔ<#V١C|`z'|?5V¸m-幜8 lY*eS`JMvt㤞J4h:XʉhGw( xZB3kG|̀jiͿ's8~'rHx⇀`lJឥ|p#3d M,E[dYǿFc=/xP!Z^qLIAR|^(8?7ʊγUYw—.X>0aLΗ6쪨bWq&}.fjgS~Al\WY=[҉&6 K_w0W!obym^d#7S98f,NȜuK΅CIr 6bɵ$_AW;́gSD/XlC "~t U@u6 BdKF&P>V0pJ q++؝ G`*6d Q9JOp ĔӘ+5Z#0:vU=GJ_CjؑU׹J'! x6{ԍKy",9z[z[Sf۪&f5yo=L 2a޵k?s _*doÖjmE!` ],ma7!Œp tdJj"oh`Jcff".i6Z wZ)ze+Ayq44SO[ \])Ld%MCib.ܪ}UHve=8̎CܩI-$KP9z9N}b[OG ؠiѿKk .<_rÂ}*m1&}=K\?CU9wl2r'h,4\̀h2s\ZI?}UUwScr0  zNbG3g&mhA>O6bEJ⎮f8ۓS-~rnG+1?cF4qDG 4\UDv3 ٜpP(D@GW Zdޢ5y.AY!@z C55؟@ÒEFiEƴt :EM'fKcf;eQ"ʡdW$Nb%aֈzU\k[h8}.a$.лM\Cp}ݖ]l6CYȱ,F3^j.˲|Rx|=/]stY50 H0AtU0aš {䇝«1 AL5]Bb2jY=YfQށnCm;SE83?YqH 8/k(*Lur΅-.A=TXm<9n/.pڿIٔ(]=I߈9iqL76'. kU2' R@=  t$"וu6_w⎮+zjU?쯵>wC݃si"6? ;*=$";OLgw"dZr284-UD܇iVxvy=UJn99n" *3(,Ɉ- gvM<tt.iZb"xw`iu&R}9({f }3VѕϖQ/UJes#zݔCܳˋ%6w=vNƅ+[F*x4!yOHA>h]^Yx%]q\4prׄZ>^=FL~7ɖ9i>Rd >\ +vG. 9n考 ? [s 528^Lh񴡳|LY&֒k>.ϥjF0FPT2 B9  ĭe/,$-mLIIQR MN09nRÅtT>m7$֜j9/@cmZZQ8VE-[Q 80Eb;4ܵc˫Bg̀^=N k*(\l|QA5{d9]7~lUQcR 31my1~UShS~LCs;ʩaw!¤mBk&Xb80l AtW`VR NH2vϑ]t190mo/4@`7ҥŖ҂ _#{\JfWq!1MF+@Aʽaɒe- h; #/Q7:(R/.f߻*1BS@Ċ矔QBmyZwpF(^E$YYҙ{eNUDߝV-%}KJ\ڍ>bBNI[a0qŒ1} n YZw#w^@d*ڹJePj| Zꗺ"y a?2 ?,r!.0sS LNlg QH6%ʹbi#L+k.jM&VzA1}` -|J5p<'o:OWg`K1vc>bmvqI>cn02V :(^g^3lCs ,6b1QB8lA D (ۢV؍\%G;[x #>ow{ȍqfn)e-.%H❃cGx(rpf 2t&JFEn^8j$) cE@E#Z|J(Bj{3z"St֌>[' h<>?^HԼnuxWj""mq;9Ex&/|\BDzn$I$j0-\voñV~en='ǘi-s<}_1F'=G/ 19!g]&ZVhxmMKD"RqJ%.o^%*@Թ1*.܎~ϝPۮ*wO+O/mӞ&lYNOW+#Br;eXYJrif06pf#ԉV?/xq ~ }$`^f\FIub J;@eЍqj@m,uz6F*{PS'=@z5b"}dcT.,|:foDD׆t&nrə41!t f$N>0<)J{հSՍtpNto!.\9ScjoAUO:Ԇ> O 3X4$;6,Ī.Q4QyEBe[!D=AO(pA *ۊyז,~}f>[TZs%7trPh@>+ei%dhBJ]?K٦Ndž/@ ㈏$tBG^d9ŖGF=uV5.ڊ\gٙ S J8*Gr/Kªj%fdm1$~n*+Pv,Ce0XwwlFId`0O{P7gv ծ ,J*Avp,BIP 㷼oDS&D5L,A=[yfm$Fhe5݆@CT;hئ~6+nARaۚs"!!T.X0.`Ɋm|%k M Cœ6O4 롷¿t9.{X?'-1}H4SQwu|P[9g/Q!H°?|,[7(~^iF<Wy0+_ȿOfRf*v\RWӧІe3>Ϡ ^(\*NHT 9HG 6~,V ry)GR͝S B =yI;f w"db0'5X@o՟'BMy0l`&x=)Ogh"l3h89Ƒ5-X.eu@7 ,[L?4G@8}AV>K}T IoY?`Ri'wܠ>=1r9X&[C,n ~/ԠZ--)kLf*-sDP襤û\B/dh4_TH^۞fW>Av㻶y(%H8u;H7c}HBL;K$M!EO7 `|2[[ﭵwf&46 `@]?$]lu5_=$\{B}z-E$7$jOXAXiv s2AwKSwnՑkt{@#κT(ƻ2iBwJS*aE[}F/'u - &;^ ?|~!|V!24I#)r0VVؾ[1ĥ# {2I}braFCuͣṠ \n 7i,sզY۽}󚘌r ̲d})E9HW{g2t2;[T7{* S؉ yh$ ] cW%$f/1K "sl> ?3JxH+o<3`5ĉK}\^_nr`?I ȣG7i<g>fjAVZğəuq-5IKK1x7*W os7Wab-h3@ux}4YOǴZeݘZ5uL%ȲS)d> @s)*dLv?m`i%Vi)}[2}pFXH)0yuW((wچ8;nOyܫ .{yoب07%R(+hdmp(3UbjYUET%a^H%ZzA l/eb4~ji;,*'5_2$. 99H1 _RӆR;D$Imod >R%Lrj{MO Aw3/F2 >QvG-cyfv^?׉(uZr^ V`Iqoqy΅8U(aѿ0>/ٻXL/% Ouk0xV ͍xr"pa2M58V=p@OzZ\+o%B*.dJ.>ڊvSEfeH:'0RuҒDE}Fz*NY% +/t(I(-l%|­8+ܸKBԍ@/y 5! o݋鮒j(g=͐$҇8mtW &)ޘAthoC `H7jy_ qH4LQ\^킉ZS3j*d1GxkNΟ ^#bTP]Tv.?cR  EibnF1(VmM V޼$ /ƾn˚Êcw4YrpTeI+H@ 웁֞y0&Ai ѳWXE*E+*y{`$MzjHss?Y,3h~S2U *2Rju@$1oYU8 ƩDǂX_>J0*dg[3F'vz#sk' 7?s=x|E #pd$?ln}oi>þ Ņ/o`i87 ?Xcߵlk6(7lPPeDIm"I0mḝyxHr$l r4.t"f8Ap0j4' OQjwq$*iPBb=Ӆ?}0&NOo&>՛hK0 gAx,ή -b aCȜm/twǾm]Af`}OBF7* ' M (@>Wa1Tew8̕BA"b5ڋHE&O?G,Q( ¥kwX6(nfbM:v+zɪ+\cV 7>=vnhr_ * نU\"\:9>.FW0Bn*iYiUq$y'W+:eD'QW)"90Qrml'(QL+ +,P&ƆaiP.$\Vl1A3t@[V9%A_WX8(ݹMX)۱.N҉@O'Zg׼pdiU΄5]Bm`{Vm;˹+|j?"X0vJ0ehSgά;HߠL i 追E}SF}(-\ϧdͱIe}8S<7n~)_ Kߞf7 d&#G&k76Sʥ k& .;ZD= U &r践ί?MbxJ|  ě.+Uϲ"[n6'D9ᦂN~LugDN~G2B-bA`me: f#pbТjj[YZ2.fjߴ|T`Tݿ={20! ˤm\B{ ?!_x-\X8^vͫDpDjGx-ٳ'1\\ CGVF =re-2PAn^9fu{Y!xܻs3+3 ~V.0Ӣ#6aLic"̆Y8O$k=΁C4gGzgr~i nhc擨)/Nʨ[m`nr·=9 1e />=%_JvK`ȡ}rϾE]kæg%eۙ/}TLB5Q @!~4kZo vM٩a= )gI(``v$iX2^K X2A6SCύYT+5`)lې=7lM@I(7sx>:!@}6Fxvk1>`i8#h}{q;I=NJi(uC9]4>qQP>Aaq1 }[@ګk3"Q:[8}Ҁ¥P a*ϖ~8l&ZJPXXqóOf7#[0fLb1 ݏnMO:(DU u,)e+XA '>4S,yZ-gK~-qF: m+?B/-R-VW.EPtgMM˶EK(ЈBl5IxUc*Q`T""`["-U vqrg> [8ܱfqGƱh':*_2WJy=`3GRŽ96(z[cߏЇ[Yi6_7 WJ$"Mse 8Oڙvbef4xC_4/{]J )vXmG3]Y3_kt޳ŃkYڨ-0EcȘVv;tX JowmUvCskF?d-!ɵ5IbUXsf_ב+Җb/jT?!e| ⚶< ô9U|#"o ڪN'E~嶧1ّM9D jA聆HEg\86q=b;9 Fߛ;jBx:&e}`Zq5l7=Gl-U+qu 2 >aԷvG6se jؾ%WPDؐk%`ħLo%_ΏAq\ƸS$A'OlE|O~,TIG2PlE=W|SeSPe)Q`TlL7k,S!@Gv=zI 񍉃%`8pw%p!4|A8RT7yHX?vGB^ӨhY~ceI"Ӟ[#B(]I1̟t3<_}ʰ'? 'sM~\HYiĘz2vBik+]ѴMV&Ljljpʂ!;g g%.џ[rVSCyп!%p\}(xZŤ M.25xX\% Eu4m$hLĀFh2M7NjOz\vG8?>8C&t Puܜ`d6 *ĶŵiS_wZI/hF6]&SZk[ 76߯@p Dq1}Bd@9\8f6>[Ñg3)y+vˮ1*;OqƦ;POvQF ˆ- EOל|gxz~kb8U{DLLQ#x0q<$ mW _RJ eJ8{H&sRlUpF5S`Ir<~mA`9@ RN48 CH5b$"7LvϙD9_1_[cC,!n2 =Ø4ΓG/I,L!Q<&Iz'5+)H5tPCg M4QyS,j 껭íGf^N>tT7`y@^S+ !@;q7d|. .IEԪ!T|I[)p٘޺,/G,jߎ?AnlꏚY+ Yt O-л٢0/yYLV0Y|DSDD\>B5צR 懎輴O#-&¼ۉN ҊIL?n`RA}'Gwn3'dNR&F AC_3'ɿW3l0HF㣘Z ح$#O L?9QhGC=&Zӯ $)&im +X@=U`WvcF6,9憉EY_'$=%k]fnLJ~(ΈE!UQF8!* E[궃 Ḱ߫>g4ġCĈΎgSÑq:*`ty)^1' >~ 4X]_䒁3EA7>yO(/=RPoBpat]='֡ I a>\ JQ_ |)&q#_Ϣ<øQȺv9Zq4-׹tz͛$? eZ}hǀBn$̰|O:g9Dn$D7c^Ynge0hl50R~[W\3La;#^ԕP[te2cmF1d$(B ]JO.7pO=GC!6-6TG۳W>-1|{̢"u M[OX)gخqUo^X%'-J6<60SdV~qvvT XVxH>ضrء_&Kyep`h/I(/.Np=t yGG$؟_EXPHExӛ 1L XѨWx Ub{៉5@x :oo<_-p$** OH7Ĵ߉ыq3GOvLqvLMa2UnM+&rPP<l7._nDFx8~a{ pAerH Zˬ&8:|`seQѓԻrB.H~5W#Sk6Հ hvƫ F^՛z]vW&LC)OI*[ ;`-% <Ŕ$뿬 JY,K$SA_,O^nkW;6l@KXA@ϛS8M#TlWtL#ɩG\̻1?xe\fx.e$閄\_|M/Їҩgnx/*9fdY%g( gw}Ɋ=ߜu|-]y,6X,عrQ5ӹf" Ϗh[tfQPXV{jP.[pޒuUFRdzύ#o|Ck4, 8Wq3M؏߱g(Pȉֵ=SyBȹcRdB=>9a 4ˤu)nK_TC\z hj%ưq}FWCb\ NЃFriwMdYnoU!Z7c ɺ;rFKͽԇ.1H}DL7yBm [, 3Sff _9fP2(=uD( hIb+s^ BP[ 5/)rDJ16 Ke`g0vɄ*Bz)1wV]=p0yq Fj:twZ-l wܡ M{J2Q7"^rlQL%Dc5HI= x܍3-#m*#vj5)MY{ O.t$)!wENYP/Loͭ0.wlR5mL5N78w_%vxSb>/ 988r.aڒRpTĵ5&$)ܗ^ݾ@ӟF~??ѥ8Av.qFp~Њ[s~% ?Cig9 uDJ)g7kG-+!^,C6b9#Ǡ55F:Mi0~b.6YQAL9)x^%W5 dw5]'^(_J*\ƃc;wA_}#h' M/;la [sƾKAq_~:(/zD 7AU d %-gxG} 'I?8ŔDCv~)Uȕb 7f^}rgQ+ĮYe@Մ% CP(Ӧ +N[*ZLn$k|e Q`PtaKDQ-g[2^_Vnl R> LsF*]JowH}Ş1M==ŗ "-#ycU=2yiQ0E]NjD/UcP E5ɻ0Ь˖3jQ{yeӍ*[Gz=#s!N JMJ xgwT#)(-/xMvkeWQ5zg/ԛe3{jx3RdYKi?\Vgt|)iُӏum2sbavP@Y ʦgS TR}1^o C65Xɵm-u8Yq% RcN^yRۨ@eԧE@4J'v+h$܋!C!@풯2PUtZX}nNW_v+Cڱ3XՖʊjaL?c@ҠjNmm̄J;01 JdR{^.l'[o;Tѳz~DT$JX\Z8$!N@D64V >ZkpFʣ[ ʖ" d^QKhపva2pxy#䡪ͅfkwYcKem]lm;c-ғ=ZE`y%ҙf7gGȟdXdh&VUjf$*.={ 81y?>&cy vm; uUE }H̨…6]Ǽ+KΞrڒchQIB N6b`9J ;db Cv%]N̎SJ1 p|,N<3ރ+Yyc(+ q:W,&J#]hho^X~tV: - <Ɛw*@i60#ʪ)cȔczRֿM#BML ct(-SnQB/SfS|uB42_%N @)3  OHI=߅/9ߝP "JcJ\jm WE8SGC$R;_GJ%~k/6nSf >$`ξ "VZ2jFx;HAڭ;O#r4 iCXBn ΰ=m[MZ'0Apm,_0e_& X ~ݏ#ܛo3S 6 *'*({6mY81-(6@IqWyCKсr^AiQ 9Csi2ʝKzZͥed ;Rw&9p ub4V'5arr!1Hhl3bM|ٝ2:  ɣlLUJمcħ쪐߯0*&}7Mf\mj׻ Žb׍ޔeNw 8g«E42ce5}Pv.#5*[jpM ȳ{܌3U"¡7(mjzX8(Uگ m9 ~L*pӐ0q܎|<껚`QjKK>SㄖwYC׷19.n8&F(oinM}PZAbOJǎ%c$?qՊQ(9#HhS5{$VU쒚!vip\Uh5"VZ!Wb=۶n;=N`$a-gMzx5A'ʨ{/AN:)!۾ʽ p/ETݹJ&]mNS*Q𗖰UX9 0h9uizVѿ!^!)y *egT1)BZڿ;hZV*S +I(j}kۡww2Vܥ/j~m[ž(Q9O c^7-&klzvPޛ MEi(KN&fn5xD2wv<۟׽}*XX[L0$`{ocvBzEG *Ckrj2D#Q$u T3l %kB1ibʥ7揞tH HBiR_ܼX߱R Dv[!&23"ӥ lA[.KwB_@ʁcyx{], r26Qq#T!Tu 10B>v}\dK ɞFɮ'zаŒ|}m|pzdu$渱Ln[ HŸ&!]=Ư5mhqzOd0*Aߋ"705H*NGWTn^- قPt9ڻyO |֑csX2A\BN?.uCNjYR쮘@Ba(grNnw SQwFg;Gs8+c{Z>u0/Gko$ԯZ,Jև?m5 zv(81ۓiaz|hI%CTe_6}Uhɴ$E놼colPvߑ?~F8;׮FMUN}nnQJCyA1efNQ-AKOtKJUr,m'ol.£(;S)ǁsç_ =|1x0߿_jP endstream endobj 37 0 obj 100471 endobj 38 0 obj <> endobj 39 0 obj <> stream x]n8ཟBvQXO HYi@#WGt>R4uwϷ?oytnW/^}cZNy:Շo|v/yUjNi%]O| _sՖ㆔_cs^mzWmasM]ǧôڶcsS1疹EYY٘ w#rbNsmܳGn@?@?@?@?~_~_~_~_~_~_~_~_W~_W~_W~_W~_W~_W~_W~_W~_ᷚs~7~7~7~R~7~7~7~9w~w~w~w~w~w~w~tF8#Hg3ٶ l+ڲr Y,h6;сDt8. Pi|Fv +KdDTguNm-^F ̸>-AāNą,ua`ʼnALt&8eM<#art˄F{ǁN tޮLvqpvvΙK2=n=azf1OOg$@;<) bwW<}ynS~y.XG) 3,ud@ژ4͛rPvc1Kzp endstream endobj 40 0 obj <> endobj 41 0 obj <> stream xeX]6LKHw !H0 CI ) H#!H#t4Htu_>۾lX#־ZRs ~Ђ-͠Z*nn8- @ mxjxDDDG(hA`nfP ;(00 dH?U7PT0˫` bn,`g g-A79ᾤfgGxcb8 gg g5 Z`labyC[wg8mpggWUOfmg XgZB,\`o 30;f-s ho_ MÀZËctvΟ8ћ9:{{ֿ@0g'6/|Mx́ 06M ( .OCyYBK6_PU/+W̿ 'v~\.`wf {zZ؛A6+Kr-A0 =<1q%j;/_6m&M@k?-mSO7_>yqxrs×#nn2= w!Qyndhq+m0+7 b/M@!Mo}+~X 7NK+1w7 .MCrq8¹^Ht~k;5۬aڌӇJ^:(m+lQЂOxcpdje*anH,i`jV+<=>X_Nh^~AIi"F2Gt#Zu_K n- u8@PK2TM6R*d%iJLæ<`n oP.:'k'{D#3:!H}]CdYa!&)Hr1`G^c %piTdZ + K[Tr 6W:v4ʄ,+(8hz7뎖Mbސnlp&UqL9񅐺V{Y^Q,̑mXdCH=3G̮?6:ʅ0{;fZG6b]hrpNУ#P/a,q083o,rr7[xTYJ&]uyܖt/4Vw9ݜBeoRkxn(qׄݦaȫ uSM"tBOe9sG*bWϿ,1) ^~Dc6:`{\As_~RCZzgE ;*qUZSʅ*y[5w=[05Uᆫr Q3?.9з^!Emx+q`jS"/ . (iOW8JfSHR*Lc.V4LptѶf5C4E3ezUlj~sn~UQX @iUfH[}0d T}BY]8}>F̛|G iӌseCw&{3W \}*{( %5$L.| ~bV'U>?rs~G$=.wJy~`iNE+ݙ0A+qAX^6>Vxglʍ3A}266`@]f&hd?xeSM5 m 6.fMeU[YɊ$-'kx<ƨ> k~_thk;QWߣ=#'-4ZIWs) v%5iBO'Ҹ Xt B`7*Y!71t@P S9)-(4~ם9Q= OP(psE_ּ6xh]ZNU_3Bq)Dt2p 悧̳3cԮccv j^r q٫r7p0IeN,eC+els6E6̺):|ٝuuxsG%2zB_! 4ռ]V!C]J9%Lʐ"LtЮjVSݸ{@*-Dul`1ӽDZP\)vtDvo_HXը8^:)&'_9` kW/o$:eS;V@X`G~R^ h!I[JhGQQ׿NܡIo!bcv|A'"c~$wD(*1ӵ#=ǥŐd}!39Vdߣ׀F@* .7_ȧ[%5A/uE/ YFsepO5E|>ߎ炕!~L<{0^f~]՘S'|[盤N뫐VAR|'/"Ap鬸KjAz뉞,/r#HǮ[$ۙ1Ƽn [Y*ȓ،{Lܮݥ$. jInOۋg%:%%p睊s"=ؕ ڻqO>mm)WzGDE%D}ڸ6 T\%73Vf#Uh縩WM<р;wds~e_,>"QMʚxH<ư80^'_!G|CQFF*fh&ݐ5PllJSd[WC! s7yl/ 4$ʭ,*wЁfޤ;UtkFo>"R@AUA t#su$" ̫\J=.VRq \Br80u-❙??xW&86äf~ۥcZ 4L5xuQdp9d6FՃt{eG E`xe꯿pp64_Oeƞj1>E<糶@=flk vlms(V19PՑH5x3O+\X\)浫.N,=/?kn[ ѭU2t$1gbbe!/,c0*}zL"kchtIA^qK-zɓZX?OK-r[1v(yqRW3a#\$u'i`8*KB S Y:!0\]2"SH5<^Ir; :BIZ2Qe)TKb&% 4zgx8S!wf340NiR;EwC{4ܽ~BGh?/slkl!\4ƄXH*Qe`}\] 4&oޠYEے~g|pXT:{2\X4(\0Z?PעCjCA,*r vi+Qfޛdy14<-mIn_I+*9X@[ $1iⒼ&Dv҃T7lmNcόmWH0Ѝ86%r``D'/LEMo\v&#SZv Os:5BPˎ$~rRd4Mw7=r"zSkbDgjD+O-]|бoOqxr۵9dKy_mZd0Ŗ>wQZjX#Ueu$U  sw 駽)p X  ƒIRAU(ܖ=o%g5˿jɧپ*pI-zyz9]Qq"UH.bba9zZ}%"_:5s'd CHӅ2W93~re{Hp/R^Z9W/&~7qoο b0o"G2&ҹg3u-*~cbe@1m $?=.qͿ9$暗n-GW[5 ̎#/4UIhu[T/zܼ̀Xɦλ۸ w`( - Py(YҸX˔BL yt)gTD:Sza ,r`$hoJqtZer[Pg}vFy.865vUTȱ}=ʵcGL4;2:~Szs $ qQm)uYim>̇&T~u8$}5ekq2#z\9?=2y):T鰱VyZvcan: $1P^!#ɈC_-4ɡr_y ga;/.PnѐUyf5wFb!O$CuYޘX6K'R%V!kU ˦Fr 1ӿmVcT?rpNutmkϙ{sSPB+X.O9'jL2+UY"9NE=Z#H'o~lR\8}<r_jC\9}”m+}㤇Mei[e/.FYz^7 _IXӲҩ?>-Cn}~n)sj3sYf7>xW9G ס$~t1ݰBGru8^mQ.w EEK7El@n"/C}%XYeFɐ_ "ʱynKD@0"ߧ.#±vگ\/$5J&yYsu6?K*:\6靖T %|J}y¥bqw|8:D sj3GySQҗ|, ǥ.%l=홡h9OpbƩ?=i-)X}i7D4)4A:gmD&O,$ˎ͚p0öwI4O]zڲA\׌%Xk^rHpH"%O:Pϛn¼so]gl-Zz2WjkFk> ,iFZEɢrM:z>R*Txњk:|MV^Ds1?I2baiV[\ᵆBŬa*h)Ig9xٝsw::uFZQ_~TקPͧmВq"ZŒqB`+i `pO_DmE}lض.CEJB&4؞Zqi̮BI FpG?-P| .}!,Eaw\0 a5W&ΰ2ʙ/꺅UNhX}[F1;y_ jzQ-M( mG,iGtW'P/̝ې$ܭ o ٷ:\!T.+%_u7{ԇ-ٷ6ՀnHԦbCHFRFPst-ѹlqM͋ڧy ;}m>sIȵ6UPѠҐI"HF{)B(ZƔslYΒ&NS_JrĔuzcqܲabk 6  r.2ޛ fgUX%N+^t-ZTBI($HկqSHVN Pl3jo&jto< rևm)c%~w$_=|z5n}$U޷,fe(5a{I;^S |I2#V(uOE4^\ ;6'o:܁@v;b-NEH`rLl,sQc$ hz4g>08wlH<ı-K?fP}p 9?NED.ShK4;th&ڱ] R44.בGRF6ڹj>b]vLCuF Tz/[]= Mf+ w{+ ZZkbjm1\ _"UZ⦂mimoO{?=eqI6Đ.m+c>MauP<  yoXk;} ]C>h.LvyvTZ 2Qs7{>~i뢳O/~n7&[xHd31Y%=Ve%\$ W8r s[_sXRxzP4 KX|!:]_Y$"{b/fa[AD1֊ ;ޝKhuטg䞚{kko3eΚ.I? whp+p94TIJ6^kGb"38>[;Q`ՖT:㢶hՏeSz{zkOT VIK3َa"/MdlxL-+*>J ƬQ)vm6}*I_IkL衒-?XPiumM@W4?(R'|lz2A@m=0^U{JBY&5Th8%pG)-~E ^-N#Yx@~0W8EF4} /8WS9z )Awkم֓PcZgz= Qί?Z\7Pf"\rʍ)BZd9hXC\#p#8_i`^Q:~B޴H SԮ~M޻d68s/?Q$4ߙ[pȧ`/ CnxC}*&U||Z+iaAM"E6:9xKBCZU.4iyhu-|B0ۭ34Ԋ6I*lg%1N9^^N|; O. /}RY,8--ֻmdH`FF%OP:Z'W')[Sz9~FDXrB.job4ʙDX%e*)T) 0vܻ¥RBdi.$S7} }yNQ@n&~fhWn UItJv%Vq~E:@R)os҉8tmUa": 5Ѳ &;xރ=, 1|y ڶf-(JfY764S8QgܦA n,s"qc?Wl^qփ?+Kft)%atlJ8MJ5_ȇ ^(o-{0ɱ}uо8Wc_g0T\zGuVQHn mU)qꚙAJ6Ne  ,us 6{Ռy}amh@c*SxY $ =޺+|Ly^^b.d+`)]jۧj~9 yoHIOH CS ˹x6QFX8{Q{=/;5fr^WK<߯ .WIFK2" 9dIaϲ@2>RQ@N&ޙ@+&y?"-y]O0񊞛x|O뛔X|6wIpWd`?Gfw^&f0Kg[ SIh=qE0\K:6=: H vO(l+ynjH-EaQeџUޯL3|YKmDMsXZj$';%m$/.Mc9kwkFRN2̗2UŸ#' c Q66->8|xd1K@ߵ}F57EL+WㄳyoK甔(8DD(4|fhC t8 K^&2m:٤; Fż-ɯl@G?;p\zsgEiN,-N?g0w=/^mT ?O; -M))p I1V8iR24˰tFk*WJ b##$-&?߷[B'3$b8j$tCEC)i!ڏXJB|jOH#Mdk :ӽ&~Pr8) qd`]9KK->0_t4jgs<=jv3?FؾaB2ԩ3OoCBs$:UbG{3Z$ȉ4+ո[fބ"rl,8!N3144"O v!=r|0`Ќ8VuI˙[oxvS`⓼:LOm)Z,)kT?rOGyhTg]cs+/!Fg$ّaܔM? _fgۋ Zs97rU2%q9B#cѿ&4VgoJ}OlPy{0P9i'V0k,);;xZ9QG\{Zt[dw6Uwk+b-5Cjοj$u%Ypjq%XSZ M" 9I3˨oG+;3{-o@$ɠ Kq=_G(BsٰW,/ݘ4-d`ً[SCk)ʩ^IĤ x`Bd #mKhA|tldFRs6KIbCJ?tR+ep(Jvmm1yj:wqLV˄ߺ%Ȃ,|\/f76yt(yG^\S gIXŋ;G'e;*8#rYNyGq&cK)IUUtwHϋ+&>E+Mw 6T.HTJmYPAսDfOtt^y=!t4a ZƑc>wB'\8D:931U K 2Gb<4E"14 ;AfG6Ns3KtߨF rIndZ%H<[h"|aF.W,)>=~/Nᢈ#7zZ.dEa٤gWCӗ>~ewgrSPl>*zI+I{]YpYya;SqoD7MNtA KOsHUe`6uӢ՞+ ? wߩDE]4Z~t0:%OBeE-QEw->, X*Na*sX`h۶m۶m۶mִm۶msnwO#yଫ6uX栔+".ufR͊}q>i_z,aICM~QpP\CY8ʲdL LDPS Ftn2F@k#iƟ^-h@_?MMT^_v2 yk(mBYeJb6b$f7TcQꞱl0f c! J}YB&ں0s+%CܽbհBی3fDl u E"vuǒdwmzޡ')YPyd7y<6IbrLkF BM4E+a)5WgGO7¿2k'ݴ.iSQ*X7 ր4Tø?mCtBz}4-Ff?O-'Tݏ&r]{k ysZD J5<0d{sCKd1BIx%?YȨ -V&X[z{ܯ6"@r7%9`՟$5="hq9mNft`0B^-w׬1 芍#%Dq1=RN&yk@:71\E^g66Sh D~`D_)V5[(S8ǣisf$'Zԍ;hv&qfZL' :M3D)%·7&$vpͺ/7]1nLܻ2B vyC ͉m&Νm] 失 sAy*bĸr>].P }xU{1ȟRTXgazUYO #ʾ+M@e8!IOa=pg:9[zO=[U%K9x~]6^ԏqH^]&s10Z##ʬ"Dg΄F,]`P'N.4|CsS=oHppIUf[p5>Gզt5Sm`/?S`Y "9T쑳P&p>HNxo9K)ؒX<ЮSȁ6\v6]+15pn 1@r}1z8 6R-7G%[$)]l2;# JYa ?>Up_(w^!`m#M?g΄Hts!N~L]CG2+)^Lzr55Hh2]yw\Dƨ} [daG :fBjjli(y 5kڗl8VxvZs-z&Гsw7-' .I%zy (5!e"~wlt^<<ҧ/ū`g- m,)ps-Ueܿ>VfJ/5vgj#Wj G'nf~9!SvN,6 ,9!Dm"BJ%GDr EGX-3~~paWjfw_Ņ6nsJP nWMcxő*&mKa2}FXK\ Q j[AgM] GC15D=]3IL8"{b/x DѮ"m}ǜ6nۨɔmeř1>Fm F[XKje/&ʎ?M/-㯞FK{gC MG` -J\M}NBX&8j܂9ȓ1͐3?sS?32[,q#35݋kK|0"~==r%_=r^=ga89'7.xߤ =bw6^~ԫAY$$<uGwÞgcX1TLax} څ &`-h"^T?98_c`w,g`_p9*yHxL;.7cft(kzXMJLʚ*笈y`;njxTHԕ)(=ֽ#Hӊ-بjsye?d6e ]XX{s7tO9ͨ>В*2TO@_4 \e Ǖ3Zy]*P:ML#hWDY#!>ma[(DCV_ࡦnD /zp=גT`bM%0| :K?2\Iڒrp+umd&J>7.| %Q~ygIj#=;b,))l!LWF_3h=Du& %KկQ?[+"1ovT[+ w>D@"iSJ$l8=_FR欜O+&$c >| Pw,rYt }ye @-MfbOxcS# $8׎o?c9; vџ]zOs?fm_AmWALƋ Y/o* P{+>A,|$Œ4a ]K0yB|wNT ms+bQ'P%5â><8IâMϵ>;&Ќh&ȏفdͼ*+cD< NlT) c6a eOS5ߤlW4D715m?l$R›W˃p cyXyMWK`p%uA,l~B5iĶ:xrk&) Нގ"%~"g7O?d4׺ HAZ# f& A1R*)u|C`&AZA*>̂oT5A;p{.ӭzSeY](땢<*l)` g]n׸sa& | }CQ]yT3BF6vVNC ]?TI?3\Xboo}|*?< Ӯ7\7?HtY6/a樸65KLD vR5eELsXy􏂗 RdؙhoPLG}svB >-(ýn\6 L%4l0cK4GحޖA"Nds5[WPi)jgވ4s\oMǩ.^kQAve@f pD]cd]/S/T;eG_3NQP/ UOw?Lyt.+]a|uqCU }zr5ɝZ ,܅B)u&#@W@_*e*"U[J0St0etS9_o4:I!?5Tx9Hcߜ &uY(OΩ4o}cƊ62z&;j Tˌ9z5Ѐ6V./8r0_[YWy2M'&=) }s걣}]N1ndsA R̋n~#"AuLHt( {T+zDk5dpH MǨ( q6'6Rgͽ$.c \5owCae:]u?S2N+-, hni#awW8!TV?xՑopALLd!;L!d`ȼT/;.J95qbJ"2M8('{o$4k;Pq (M1j3'?yZK ξ YtߛEHzNn&`=d)Z'O[F~}^U#[:ꂏn6IM-&^k9, qIjVANp,#H4cV6R,89/ɲ <U;1`F:]8JnJ+8T7) K" hlǣr(3:esα K* ӵ>@m&"B -4vٱK`NlPiaʟ*pW?M,<` ˦btE4sxLO(+hCgS@6 $$>k[T *rI=0o!nK_5Z 4S-a*n1+<2-Ӫ)i 2>I|FvASRAzݛ˫e1S!JE;ESw`r^[(\4:240=uF<2CͰYxIīGo^#tؐb1l9FЌ+aP1CB>htGM؞@G%cZ# W_K~ $ɵƏcw,5J%N?w,й{m|+3zæaO#C"D-f-v" ;9P#+5r*^t ')W1_8y.>S =&(8zto"3=,yT{õp;8R=,*`E}P0d-F@ݘ7S1<72Rؽ&%_wlVnCX {O fI.ҟA]J.WC~n*3 ə),dݷ5i)nNFݔZ% _rE1yɎ]kqPLF alLQxRqvǚU~a1z8`)4xJsYw&U'=֣d˷JzZܟc:P@,B%qxUm(9c>U Ҏ##stDᲾF |+K5S$RS2Qt9Ʃ2}#3J|Q/x7ڎϾfxۊ֬Rua/;Z+wE8&A8,[nRj?u4cl@ N7 RIacwsNܝru ]4|!+ i=~ 'ղ3tԞA-OǕ?|n+#-2BV,UН"|a}O|(?/[R}ɻ)ic/aB.PqٖH~FR{A *D+]} hJ ]o9͡v[ʮ]J?XXlRQP^zA@Ne!!t\-.9dkH8ο[K/vFdurWT=ݵ;u`ZeBCL wyXr8Nt,/_~-Y#A .X)9x"س{*Dg<41jSո[ ,_uF1;6FXtʒZ`vx3=Vkfɸ xA϶6jՎL7#5.Ig%̵P>hw!Η6qYQp5X"}b׫w`݋#[odS`+ptHv2iAp0Q]MV~zW\2}Z)$4 jVp=i'M\trf{˵QVwUTA=ݮÈ_Bct [[mKV0pSﱾLMٺJ3 sD)*]æH+K^0*y fADJ/VԫRĢtT"+ = _/BzX} (?ReЃ/{&4:m+јn d$nk0L싟̀bva.Hm=^"%v:iGSg31ٽ; cr l` xw=|u"F[I{0uة+ϟ3"f,z8_4^\z S_ϙS9},M}J &:p%ij#&?ȋj xn5Yh9/G'cM׸U+/%]?aGٓGoғ,?8Og{2, 6N+^7ybjJ;EZ/[qaUDi a9d+X:鏔GkLY2ddy.V9/U"CAֵdx^N3 {Y >Vݮ6 l(kaL%xJDPx8(,ef]ҲL91u K8&.=MhŧIG9 U6fA\d޶ѕ䩪3Huh=pKiOXhT})̉\G9 'rJoB)VION6覍 3?ƒ}@5ӔvW {GVgײA`i- ǔb BZIznPyݴZ@#n?' bH\ŶΪD=F9j{²g}@ߌ=6DUۙ:dH7q@5O7Mk{mO [/1%+ZbG%$]sؼxIXa {s. ݉\-ʄ1;쿠qWF]١oHU]p@$CaJRR7,FZ|O{W8 DgW\I|({en¹K5\VĚ4 mKF_FoqCb֞\`Ve;XAaitdPT( BA+r;ȇ\}=4-NbqGQonH+C=_Nl$#]5˒ra?&RnYn{;]SPXS4ĤCY[ }m-]KNO 'k?b\R8vE "ij^?~˘=/ Gt̖Q|ƝHZ0Yw Wj l"C66jj3H:WhC9< 3˵EX\NU!%!%fsrݑAf3?#WkoD S_;ٍv"!gK:<+an1X;9!xˏ>|PМAV\9(% P Wdih 1)La'wq0CDv)-ZBy)__ <N8~wFAF}|nGx!2)ag-2 TzK3 ޅhw1LOYvbX۠NpUc3 @z\ ?rҢ?$>x9g|lR&e&琨1[L8o{/5CJ<䕤V(&" YG01GtJAP)w߁o] ۦb#D,^gd1:twBsPur꿩ȝfwPeK,V2&Y{vآ$Ҝ*h՝큠ل%93ɱB# \e泱YdEL ^:h&n΍16F=^DAIzLlؤY<0iZq';J ڊ19jAumۤ=1@ks}PK}^^"HVk af>d\A=1'wq{HK!a Y%U|)ufg'w+A)d 5<ugg ':-A nW P]i#6eJz ;Y]!K3Ӻѻ_R$CP7"љ 71z&#e^ӯRT(mM/4m7<.'h3ک,v)&rEK(@61Ɯ;Y%WBUOQV׬ⰓOϜFЈ֮8Ҟd2Pβk'7`+Ga4M+*Caoj\yu ~Cf =ê|M/NDFN8Y ?ni:\IN:Ó{O U^swW1۵SƤM }>6֦9EbM!0>8vϷa ۺUJ+Gw"ZHPk8;ѧIdB;kޖܫ-Pi.s!:ex[ȝusxOzPbi*hLC2aX%GΈx''*n.~/F":~e.:(AVf&Z-}p+I ^7YV KP Ŗlr5C aП'Sp3x[;vDiQTí8뱮T$ч.ERf HkҎZC &;q3WLQ]ls]\ (Ij ƗjŕnӓH lqUsߞQaJ8|6(F*seMG@wm[sQb `7i9e=.M]*X]"ъNi$=$tB"Is'c[ 2"dPT~R bw&)B`#B[Q6o^Ʊ\,JQ+\շ[Sf[,kV8OrfiK~!Nn9#Zȡ!b g9MEdw[A%dW;*:WJc)~|\/`3m"%޹_iΧ?m7.g Q1*mlԇ ={2߸;1%M^1lc\Y-1-^:i^j[Nx"&lnyx9 JENXO rs m{ d$䑫/gtrG3$`IqL0M"GW[JzUpO} ` Cl 5FC)ĥNpFSrsN}.ed~58D r7Ge4Kؠ#\axk/a#aDǒndkG$G?ٖdAȔo.M=.9JLg->jlWa#Fꁣ1Nq: ,CA2P3nQS ?' ѓ^/aC{F%?8IMu"0.M@idP谑:,4aN^U+4I^[bpLgN;=fj`1 dO*mQn<0 d5C7c90z0B 3>3t1UK{ %8m)`CP婻ȷ:<$׳(Vwug(jZW؎JB:q ɯ6[ fYa5ҚΩ#NΆC W7o 2 T b+cKvS5">]LCʓk[&BOiJ@J H}SrI&:-H ,U{ ]`0`ػfNS8HgPNd]!1ʻ5=@|H_\SP),!hDNB^oIQԍ:$7j(gqu(kEgxH!դ "΃*̩ղ6L&w&+oo%tK(3Yw b@1 Y:l嶳\ ,sQ*ڏXj'B1BGO[/ j VLe<Oog dRv [jP<l`},kz e}@Zb~Խ<);)S,hpvӝOiU{E:Ӊ0] hPK5BIF BUY:ctb-DѩCDOvoY2Ν t_|he vBl֢3^Jm.lnnfBG!%ؓn8X rǙMukaLZ +Ѧ6{J_T=YIKV NNf3%RR>y-$&`@09'1Y o$WdP.A:׻52n;ֿK_jڝx d]pH90[v;{B᠌른yf[:įzLqk'5`nLđ8u21E\HFA $Dz`sa<iG齌IF:#$N=/W 2>LNX,=WuW#`*~anNޮQ> endobj 44 0 obj <> stream x]n"9=OQ˞E oDB|&3@AE޾gnHrUw\VXOtǴxZܭq}ob9~O/v}:}_~_//WU_> endobj 46 0 obj <> endobj 47 0 obj <> /ProcSet[/PDF/Text/ImageC/ImageI/ImageB] >> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <>/Contents 5 0 R>> endobj 11 0 obj <>/Contents 12 0 R>> endobj 18 0 obj <>/Contents 19 0 R>> endobj 25 0 obj <> endobj 48 0 obj <> endobj 49 0 obj < /Creator /Producer /CreationDate(D:20081107191244-05'00')>> endobj xref 0 50 0000000000 65535 f 0000859662 00000 n 0000000019 00000 n 0000001350 00000 n 0000859806 00000 n 0000001371 00000 n 0000001520 00000 n 0000001539 00000 n 0000055210 00000 n 0000055232 00000 n 0000185945 00000 n 0000859950 00000 n 0000185969 00000 n 0000186121 00000 n 0000186141 00000 n 0000240028 00000 n 0000240051 00000 n 0000353310 00000 n 0000860096 00000 n 0000353334 00000 n 0000353499 00000 n 0000353519 00000 n 0000407257 00000 n 0000407280 00000 n 0000528833 00000 n 0000860242 00000 n 0000528857 00000 n 0000629431 00000 n 0000629455 00000 n 0000629646 00000 n 0000630591 00000 n 0000631556 00000 n 0000722158 00000 n 0000722181 00000 n 0000722379 00000 n 0000723324 00000 n 0000724291 00000 n 0000824876 00000 n 0000824900 00000 n 0000825091 00000 n 0000826036 00000 n 0000827005 00000 n 0000857219 00000 n 0000857242 00000 n 0000857430 00000 n 0000858495 00000 n 0000859476 00000 n 0000859539 00000 n 0000860362 00000 n 0000860460 00000 n trailer < <7344FB0B07DF8A142983DB375391DCD9> ] /DocChecksum /B47B21D30A8614E0432CDC69022B7D8B >> startxref 860689 %%EOF kst-2.0.3/devel-docs/Kst2Specs/FixedBugs000644 001750 001750 00000135034 11544160206 020347 0ustar00synthsynth000000 000000 Zoom Mode Plot Bugs: -Zooming gets slower the more points there are in the curves. It should always be fast. Zoom lines not updated on or what happens: Put the mouse in a plot and depress . Nothing Happens. Now move the mouse. A vertical line appears where the mouse is. Move the mouse around. The line follows the mouse. Now release . The line stays until the mouse is moved again. What should happen: The line should appear when is pressed, and disappear when is released, independent of mouse moves. Tied X-Only () zooms adjust X and Y. What happens: create two plots (eg, 1 of gyrodata.dat col 1 and one from gyrodata.dat col 2). Make sure they have different Y ranges. Tie their zooms. Now adjust the X-range only from one plot with +mouse. Both plots end up with the same X and Y range. What should happen: Only the X range should change. Rotated labels in boxes drift on resize... Create a box in kst. Put a label in the box. Rotate the label. Repeatedly resize the box. What Happens: The location of the label in the box drifts (so when the box is set back to its original position, the label is not in its original position). What Should happen: location of the label should stay fixed relative to the size of the box, so that when the box is returned to its original size, the label returns to its original position. Note: if the text label is not rotated, it doesn't seem to drift. Label Parsing place a special characters in a plot label (eg, \omega in the X axis label). The special character is not interpreted. It should be. Note: it is interpreted properly in floating labels. Plot ranges don't update. Create a plot with a curve of sine vs INDEX from dm.cur. Read from end the last 100 frames. In the plot hit 'm'. What happens: As the curve is updated it dissappears from the plot. Hitting 'm' recenters the curve. What should happen: In 'm' zoom mode, the plot ranges should dynamically update to cover the full range of the curve on every curve update (As if you were holding 'm' down continuously. Try kst1.x for a demonstration of the appropriate behavior. Crash deleting last tab: start kst, and in the only tab, select rmb->close. CRASH! This is especially a problem since this is what TabWidget->clear() does. TabWidget->clear() is used when opening a file to get rid of all of the old tabs. As a temp hack (to allow file opening) clear() is not called on file open, so all of the old tabs linger after opening a file. This should be reverted once the bug is fixed. ----------- Editing a slave vector from a vector selector should bring up the edit dialog for the provider. Instead it brings up a vector edit dialog.... not what is wanted and won't work anyway. (cbn to fix this) ----------- Editing a slave scalar from a scalar selector should bring up the edit dialog for the provider. Instead it brings up a scalar edit dialog.... not what is wanted and won't work anyway. (cbn to fix this) ---------- Cur files no longer work. Select a cur file from dirfile_maker. It thinks its a ascii file. -------- Problems reading files from the command line ascii files can't find any fields from the command line -------- Only dirfiles can be chosen from the data wizard. ascii files can't find any fields -------- Update curve after editing equation Create a plot with a curve from an equation. eg, x = 0..100, y = x Put the plot in auto zoom ('m') mode. Edit the equation to change its Y range eg, x = 0..100, y = 2x On apply, nothing changes. Do something that causes the curve to redraw (eg, resize the window). The curve redraws, but the Y zoom range stays at the old range. 'm' resets to the old zoom range. Now edit the curve, do nothing, and hit OK. Still no change. Now do something to redraw the plot. 'm' mode now works. ------- Butterworth low-pass crashes. create a plot, apply filter with order=4, lowpass = 0.01. Crash. ------- When chosing to filter a curve from the plot rmb, the input vectors should be fixed to the right thing: eg, Butterworth low pass Y vector should be fixed to the Y vector of the curve selected in the RMB menu. ------- Entering a numerical value into a scalar selector should create a scalar of that value, if there is not already a scalar of that name. This is particularly important for plugin entries. It can be created when the scalar that the selector has selected is asked for. -------- Ascii file configure button troubles I: it doesn't work. Configure from the data wizard brings up the configuration dialog, but applying it does nothing. -------- Ascii file configure button troubles I: it crashes Configure from the vector dialog crashes kst -------- Filters should have default values eg, low pass filter should default to order = 4, lowpass = 0.1: see 1.x for defaults. ------- Problems with file selector If you browse to select a dirfile, the name of the previous dirfile has been put into "File name:" entry. So you have to erase it to select a dirfile. Of course, selecting a data file replaces the old name with a new one, but there is no way to clear it selecting a dirfile. If the 'current file' is a dirfile, then the File name entry should be blank. Either: always clear the current file: entry when a directory is changed, and don't fill it in the first place if the default file is a directory Or: Check to see if the current directory is recognized as a valid datasource - if it is, clear the current file entry. -------- Change data sample range tool doesn't use defaults. --------- Accelerators for the plot edit dialog: 'E' should bring up the plot edit dialog --------- Places where text labels are entered need string and scalar selectors to aid in the insertion of strings and scalars (eg, primarily label editor) --------- Missing tabs in plot dialog: -There is no tab to set size, position, and rotation. There should be. *cbn* Top Level View needs rmb menu: -set background properties (colour, gradient, etc) -set tied zoom mode for children (?) -cleanup layout menu option *Mike* --------- Axis labels are not transparent Create a plot with X, or Y or Top axis labels. Change the background of the plot to a gradient. The axis label backgrounds are still white. They should be the color of the background (alpha channel?) *Mike* --------- Axis labels should have configurable colour. A byproduct of making the label backgrounds transparent will be that if the background is set to a colour with a low contrast to black (like black, or close to black) the labels will not be visible and there is currently no way to change them. *Mike* --------- View Object parents not preserved in saving/loading kst file Create a plot. Put a box in the plot. Put a label in the box. move the plot around - verify that the box is a child of the plot. move the box around - verify that the label is a child of the box. save as a .kst file. load the kst file -note that everything is positioned relative to the tlv, and are all children of the tlv. *Mike* --------- Plot dialog label tab has grown out of control! It should be shrunk to fit in 800x600 It needs to shrink. -There needs to be only one scalar and string selection combos, and they need to apply to the most recenly selected label text entry. -The per-label font selection needs to be drastically shrunk. maybe: only the text and the size active, w/ the info in a label, with a button to edit. or maybe: only one font allowed for a plot, and have toggle buttons for U B I. or maybe: only one font and UBI combo for a plot. UBI can be set w/ latex commands in the label. -get rid of all the per-item boxes and use more space efficient separators. *Mike* --------- Missing features in edit label label dialog: there is no mechanism to adjust the font, or Underline Bold Italics (UBI) in the edit label dialog. *Mike* --------- The entire edit label properties tab should be shown when creating a label, not just the label text and the string/scalar selections (ie, incude size, font, UBI, and colour.) *Mike* --------- Labels should have configurable font and UBI. *Mike* --------- Tied zoom problems: (see devel-docs/Kst2Specs/Plot Geometry.pdf, last page). -The tied zoom conditions are not honored -The parent option condition is not honored. In fact, there is no way to set parent options, even if there were parent options. -The plots are not automatically re-sized to have equal size once the axis are shared. *Mike* --------- kst settings dialogue box should select "General" when first opened to indicate that what we're seeing to the right is the General tab. *Mike* -------- Double clicking on a curve in zoom mode should bring up the edit curve dialog (was in 1.x, but was a little buggy). *Mike* ---------- Edit plot dialog format issue: The tab list on the left has a minimum size set in pixels, and is not dependent on the size of the tab names. *Mike* --------- "Change color per file" changes are not shown in plots until the plot is moused over. *Mike* -------- "Differentiate Curves" changes are not shown in plots until the plot is moused over. *Mike* -------- Accelerators for the plot edit dialog: clicking on the plot outside the plot region in zoom mode should bring up the plot edit dialog. if on a label, to the label page if on the numbers to the axis range page (which doesn't yet exist). -------- Missing tabs in plot dialog: -There is no tab to manually set plot zoom ranges. There should be (see 1.x). *cbn* --------- When displaying data that is constant, the range is from about zero to slightly above the curve (meaning the curve is very near the top of the plot. instead, it should center the curve and have a range of �0.1 around the constant value. ---------- Line Endpoints drift relative to plot contents: Create a plot. Put a line in the plot. Resize the plot. The end points of the line don't stay fixed in plot space. It seems to have something to do with the 'centerpoint' of the line. It rotates around an end point. This problem doesn't happen with boxes. *Mike* -------- datawizard generated multiple plots per view have the font size for the lables way too big (so big that, in the case of 24 plots), the axis labels take up >75% of the real estate. �The wizard should chose the font based on the number of plots that will be in the tlv when finished. -------- Clicking in a plot when in *layout* mode brings up the plot edit dialog. This should only happen in *zoom* mode! The way it is now, you can't move or resize plots. -------- No way to cancel a drawing command. Select a drawing tool (say, a box) Change your mind.... tough - you have to draw something. *Mike* -------- No visible feedback as to what drawing mode you are in... Select a drawing tool (say, a box). There is no visible indication that you just selected a drawing tool. The tool should be clearly shown either with the toolbar icon remaining depressed until the action is finished, or in the mouse icon. *Mike* -------- Export as png with a set width and height shows transparency (blank) where extra space is, rather than resizing the view for the export. *Mike* ---------- Should add some more latex mode fields \odot -------- In labels, \textbf{text} and \textit{text} set bold and italics for 'text', but they don't un-set bold and italics after the end of the curley brackets. They should. -------- Negative size drawing considered invalid. Drawing items beginning with any corner other than the top left (negative height / width) results in an invalid viewRect and the item drawn with a nominal size rather than the desired size. This is happening during completion processing as the objects are drawn currently during creation. *Mike* -------- Tied zoom behavior oddness: Tied zoom has been implemented as a toggle button, setting or unsetting all of the zoom ties. However, when in tied zoom, it is still possible to un-tie individual plots (which is good). But: when you un-tie one of several plots, perhaps the tied zoom button should become disabled, as you are no longer in all-tied zoom mode. *Mike* -------- -Superscript and subscript size and position seems off. This should be researched more but wikipedia as an almost reasonable article on it. It suggests both should be scaled by ~60%, and subscripts dropped by 16% and superscripts raised by 44%. OOffice, illustrator, and photoshop use scale 58%, raise 33%, lower 33%. msoffice uses 65%, -14%, +35%. It might also pay to compare w/ TeX. --------- No space allocated for subscripts or superscripts in axis lables The subscript is cut off --------- Number of major ticks bug: Occasionally there will be too few (<2) or too many (serious overlap) in the number of major ticks. This seems to have changed from 1.x *Mike* --------- Plot axis number rounding bug: occasionally, the axis numbers can be something like 0.499999999993 instead of 0.5. It is hard to reproduce. *Mike* --------- Kst should ask about saving the .kst file on exit if the document has changed (basically, any change other than a mouse/arrow zoom). See 1.x. *Mike* ---------- .kst should be appended to the name of a .kst file if it is not already there. *Mike* --------- Reference point (see 1.x, 'c') should be implemented. *Mike* ---------- RMB menu over a plot render item in layout mode doesn't have raise or lower, but but does have the zoom options, etc. the RMB menu should always have raise and lower in layout mode over any raisable or lowerable object. *Mike* -------- Shared axis Box Behavior: box shows in data mode Create a shared axis box around some plots. A grey box appears around the shared plots. It should not when in data mode. In layout mode, when the group it moused over, then a box can appear, as with other data object. Otherwise, no visible box. *Mike* -------- Automatic layout behavior: there are gaps between layed out plots Create some plots and apply cleanup layout. The plots are aligned in a grid, but between the plots, and between the plots and the edge of the tlv there is a gap, presumably to make room for the grips. There should be no space. Instead the plots should touch each other and the edge of the tlv, even if the grips would overlap, and even if the grips would extend partially outside the tlv. This applies to all layoutable objects. *Mike* -------- Shared axis box creation behavior: The shared axis box dimensions are set by the corners of where the box is drawn. This is inconvenient. It would be better if the box dimensions were set by the extents of all plots which have been included in the shared box. *Mike* -------- Shared axis box behavior: resizing separates box Create several plots and put them in a shared axis box. In layout mode, resize the shared axis box. The box ends up on top of the plots, and the plots cease to share axis. The plots should stay in the box. *Mike* -------- Shared axis box creation behavior: no visual feedback There is no visual feedback as to what plots have been selected when drawing the shared axis box. There should be something (eg, the selection rect shown in mouse over mode like in layout mode) *Mike* -------- The size of selector on left of dialogs is too small to fit the entries, though it is resizeable. It should default to a size which fits all of the entries, up to some reasonable maximum, but then be resizeable to either larger or smaller. At one point it was fixed too small. Then it was changed to be resizeable to larger than some fixed minimum. Now it defaults too small, but can be resized. *Mike* --------- Formatting/spacing issues: -The spacing between the X-axis numbers and the axis is too small. -The spacing between the Y-axis numbers and the axis doesn't seem to scale with window size. -The plot selection buttons are too small. --------- Data mode (see 1.x) should be implemented *Mike* ---------- Shared Axis box behavior: different boxes have tied zoom. When more than one shared axis box is created, the zooms seem to be tied between them. The zooms should only be tied if indicated by the tied zoom box, which the shared axis box does not have, but should. By default, each shared axis box has it own zoom. *Mike* ---------- Pointless complaints from Qt: we are getting on the console like "QGraphicsItem::ungrabMouse: not a mouse grabber". These need to be found and killed. *Mike* -------- qgraphicsitem_cast is not setup correctly and causing bugs. A number of bugs are occurring as the result of qgraphicsitem_cast failing. All ViewItem objects will need to be updated to support type and casts re-evaluated. This causes context menu bugs. Object selection bugs. *Mike* --------- General drawing 'flicker' and missing regions in drawing with openGL enabled: OpenGL is qualitatively much faster, but on my laptop with Intel graphics, embedded, and running opengl with kwin, there is lots of flicker, and lots of things simply not drawn. Notes: - We are doing everything correctly according to the Qt documentation. - This can be reproduced using the Qt example code. Corruption extends beyond Kst, and can be seen in all other apps showing drawing problems. while QGLWidget is running. - Sample Qt code: http://labs.trolltech.com/blogs/2008/06/27/accelerate-your-widgets-with-opengl/ - Performance will be improved in future versions of Qt and is a known issue. http://labs.trolltech.com/blogs/2008/02/04/qt-44-and-painting-performance/ - This bug is a platform specific to X11 and is documented by ubuntu with a work around. https://wiki.ubuntu.com/RedirectedDirectRendering - Sample app from Qt runs correctly under Windows, no reported problems with Mac. -------- The first pane of the data wizard should be reading directories in the background, instead of in the foreground where it steals X focus until the directory is read. �I ran into a interminable-focus-stealing problem where kst was attempting to read a dead NFS mount. �Required an X restart. *Mike* -------- Bugs in Build System: -picks up libraries in lib/X11 before local libs -doesn't support 'make install' nor DESTDIR --------- With multiple plots, when zooming one changes the size properties of another (due to axis label changes, for example), the axes labels on the non-modified plot(s) can get garbled until the mouse is moved over them. ---------- PlotMarginStandardization is applied inconsistently. - Note: Fixed many cases. After applying layout, plotBorders are set to Dirty, this may not be correct. A number of margins are not updated within the changed plot currently preventing full validation. *Mike* -------- SharedAxisBox plot sharing occasionally breaks for no apparent reason. Have not identified a pattern or cause as of yet. *Mike* -------- Fragility in moving parents: create a plot. Put a child box in the plot. Rapidly resize the plot. Sometimes the box will either drift or loose parenting altogether. (Editorial: Fundamentally, I think this is because qt's QGraphics system has been used to track placement of objects, and QGraphics doesn't have the right model of what we are doing.) Note: This is still causing parenting to fail. Updates are required to prevent reparenting on parent resize. *Mike* --------- kst reads live dirfiles less efficiently than before. �On a shitty computer (devlin666), kst1.7 can display 200 frames of 24 bolometer channels (100Hz samples; 20 samples per frame) with a 500ms kst update timer, and only use about 20% of the cpu and the computer will still seem 'responsive enough'. �kst2 under the same conditions, except with 2000ms kst update timer uses about 55% of the cpu and the computer (and kst) seem more sluggish. � ------------ Y Axis label placement is wrong Create a plot with 24 curves from the data wizard. The Y axis label is offset vertically. ------------ 'c' mode doesn't show difference. 'c' mode is used to find the offset from a marker to the cursor. Currently, if 'c' is hit, a marker is placed, as it should. However, the difference between the marker and the cursor is not shown anywhere. See 1.x for the correct behavior. ------------ Plot update problem: -from the data wizard create several plots. -Make a change to the plot that changes the size of the plot (eg, change the font size. The plot you changed is happy, but all of the other plots don't get automatically re-aligned. -Move your mouse into one of the plots that is not properly aligned. The curve is re-drawn to be aligned with the other curves, but the plot axis is not re-drawn. ------------ Equation update problem -Create a curve from a datasource. -create an equation from a vector from the curve. -Change the input vector (eg, with the 'back one screen' button) The curve updates, but the equation/equation curve does not. ------------ Plot is not regenerated after 'ok' in the plot dialog axis tabs makes a visual change. -create a plot. -in the plot dialog axis tab change something (eg, the 'draw grid lines' option) and hit 'ok'. The plot is not redrawn to honor this change. (if you do something else to force a redraw, the change is displayed.) ------------- Loading a kst files does not seem to work: -run kst -with the wizard, make a plot with three curves -save it. -restart kst and load the kst file you just created. kst gives an 'invalid Tag' error, and no plots are shown. ------------- Accelerators everywhere. ------------ 'ok' in arrow dialog moves the arrow. draw an arrow. Open the edit dialog. change something and hit apply. The arrow moves. ------------ 6. Unless you've explicitly given it a Unique Name, the edit curve dialog gives no hint as to the name of the curve you're editing. This is a problem when you have, say, twelve curves called "2 vs. 1" in a single plot. In 1.x I can doubleclick on the curve to bring up the edit dialog containing its name to figure out the name of the particular curve "2 vs. 1" I'm interested in. Here, I have to go by trial and error. ------------ 14. The weight of a drawn curve is apparently calculated as: (my weight) + (sum of weights of all lower numbered curves). Being unable to specify negative weights, curves just get heavier and heavier. --------- Loading of a Kst file into a resized window does not adjust the loaded items to fit on the new window size. The View dimensions should be saved as part of the .kst file and if the newly created view on a load of a .kst file doesn't match, the resize logic should be triggered. *Mike* --------- 12. Changing the value of the fixed range limits doesn't active the "Apply" button. ------------ Layout issues in data object dialogs: some dialogs, like histogram, lines up nicely, while others, like image is excessivly indented. I can't see any difference in their implementation., ------------ 16. Text labels have to be entered in a tiny little text box, making decent sized labels frustrating to edit. Furthermore lines, in a label are separated by "\n" now? --------- Auto-labels, and '_' in field names: When plots are using name-based auto-labels, any '_' in field names gets interpreted as a subscript. 'solution'. Append a \_ to _ in field names so the appear correctly in labels. Down side: they are less nice looking in tag names. This is acceptable (unless we end up really board). --------- Drawing problems in resizing view items (eg, arrow) draw an arrow. In layout mode, grab one end and drag it around quickly. The grab point gradually drifts away from the mouse cursor. It is much less pronounced if you move slowly. *Mike* ------------ Base / Offset mode logic change: Base/offset should have three modes: On: Base/offset mode is used, regardless of if it is needed (same as current 'on') Auto: Base/offset mode is used if doing so makes sense (same as current 'off') Off: Base/offset mode is never used. ---------- Error in choice of offset mode. Create a plot with a Y range from -0.032 to 0.041. It goes into base/offset mode and shouldn't. ------------ Crash case: edit vector button is active in vector selectors for error bar vectors which aren't yet set. Clicking crashes. --------- Default X vector field: We need to guess that is wanted for an X vector in dialogs which take an X vector : ------------ 10. In the content tab, double clicking on a curve in 1.x would move it from the list it used to be in of the lists to the other. This saved the tedious click-on-curve, click-arrow-button, click-on-next-curve, click-on-arrow-button 1. data source text box in first panel of data wizard inevitably moves the text cursor to the end of the input after entering a character, making it difficult to edit in the middle of a path======= --------- A spectrum curve created with the data wizard should have the same color as a XY curve simultaneously created from the same data field. ie, if the XY curve of [sine] is red, the spectrum curve of [sine] should also be red. 17. There appears to be no way to change the colour of the plot border and tick marks from black. I though the brush colour under "Stroke" might do it, but nope. Axis Label Rotation: Axis number labels should be rotateable, as in 1.x Edit Multiple for Plots It should be possible to edit the properties of multiple plots at once. The UI used in data objects and in 1.x works well and should be used here. *Mike* 8. Removing a curve from an autoscaled plot and hitting "apply" removes the curve doesn't rescale the plot. The plot is rescaled when "Ok" is hit in the edit plot item dialog. Adding a curve to an autoscaled plot and hitting "apply" does rescale the plot. 3. toggling log-x axis (key 'g') doesn't do anything until you poke at the plot. (My impression is that a re-draw is being missed.) toggling log-y (key 'l') works as expected. (cbn sees: the mouse needs to leave the plot for the plot to be redrawn) 4. toggling log-x doesn't change the x-axis tick labels/positions, even though the curves are drawn on a log scale. Zooming in and pressing "M" fixes this. Again, y-log works as expected. (cbn says 'confirmed') Legends don't appear to work: With the data wizard, create a plot, and select to create a legend. No legend. Edit a plot. In the label tab, select having a legend. Apply No legend... ---------- New tab in Data Wizard: There should be an option in the data wizard to create all of the new plots in a new tab. 1.x has this. ---------- XY Plots and Spectra in separate new tabs in data wizard. If XY plots and Spectra are both being created, there should be an option to create the Specta in a separate new tab. 1.x has this. ---------- 11. When in log mode, the range reported in the range tab of the edit plot item is the logarithm of the range. So if the y-range is 0.1 to 100, the range will be reported as -1 to 2. Despite this, you still have to enter "0.1" and "100" to get this range. Smart selection of minor tick intervals. There needs to be an option to automatically chose the number of minor tick intervals: If the major interval is 1x10^n or 5x10^n there should be 5 minor intervals. If it is 2x10^n, there should be 4. This was in 1.x 7. Adding a curve to a plot in the edit plot item dialog, and hitting "Apply" causes the dialog box to grow wider. Removing a plot does the same thing. The result is an ever-widening dialog box, which can't be re-narrowed since it believes it is as small as it can get. (It's the list of tabs on the left which is doing the growing.) ---------- New Plot Label size mode: autoshrink. Add a an option to plot labels: autoshrink. If selected, the font size used for the axis labels will reduced to the largest size (<= the current size) for which the labels don't overlap or are not truncated (only text width is considered.). The resizing is dynamic. If the window geometry or the label values change so that the label would fit at a larger size, the size is raised. - Last step after base/offset & reduced ticks. ---------- Placement widget (eg, in the curve dialog) needs a create in new tab option. 1.x had a 'create new tab' button. This is similar, but does the creation of the new tab after apply, and uses a default name rather than popping up a new dialog. --- 3. Very often, changing the range settings of a plot does not change anything (I did not find out why it worked sometimes) --------------------------- Shared axis not shared until a redraw. create plots with more than 1 column (eg, 6 plots in two columns). With a shared axis box, select two plots on the same row, so you would expect them to share a Y axis. -the bottom axis is suppresed on both. (they should not be) -The left axis on the right plot is not suppresed. (it should be) until something is done to trigger a redraw (eg, a rescale) at which time the plots are drawn correctly. Sharing is happening however, sharing is based upon plot projectionRect, not on physical location. Ie. in scenario described the Y axis of the two plots do not match but it seems likely that the x axis range does match. This results in an inappropriate sharing of the x axis when the physical location of the plots lends to a natural y axis sharing. The zoom update will trigger the tied zoom code which standardizes all the plots. This proper fix for this will be part of the logic rework for shared axis as it is related directly to the above bug. --------------------------- 'I' key in a plot with an image should adjust the image color scale; see 1.x for correct behavior. --------------------------- Change File Dialog is confusing. It is not clear what the two filters at the top do, and the way they do it is inconsistent: The top is applyed when you hit the all from button. The next one is live, and the button clears the selection. There is no way to combine the options. Better: a file text entry and a regexp text entry, an apply filters button, and an 'and/or' radio pair. --------------------------- Problem with plot range and offsets: Make a plot with the Y range from -0.75 to 0.4. It goes into base/offset mode and it shouldn't. --------- Missing X axis and cut off right edge in tied zoom box: create a tab with 6 plots in two columns make all 6 X axis the same, but with 6 different Y axis Create a shared axis box that encloses all 6. There is no X axis visible. There should be. The right edge of the right collumn is cut off. It shouldn't be. ------------------------------ Selecting 'share Y axis' in shared axis box context menu does not share Y axis. create a tab with 6 plots in two columns make all 6 X axis ranges the same, but with different Y axis ranges. Create a shared axis box that encloses all 6 plots. Notice that X axis is shared and Y isn't. This is the correct default as the Y axis were different. Now, select 'share Y axis' in the context menu. The check box is now marked, but the Y axis aren't shared. What should happen if the Y axis shared box is changed to checked: -The Y axis ranges should be changed to go from the minimum Y min shown to the maximum Y max shown of all of the plots in the box, and the Y axis should be shared if properly aligned. -If all of the plots were in 'm' auto zoom mode, then the shared axis box will be in 'm' auto zoom mode, with all plots going from the minimum Y min to the maximum Y max. Otherwise, the the shared box will be in fixed mode, again going from the current displayed minumum Y min to the current displayed maximum Y max. -hitting 'm' anywhere in the shared axis box will place the shared axis box and all of its plots into 'm' maximum zoom mode. -Doing a mouse zoom in any of the shared plots will do the zoom of any shared axis in all of the plots, and place them all in fixed mode. ------------ unselecting 'share Y axis' in shared axis box context menu does not restore the separate Y axis. create a tab with 6 plots in two columns make all 6 X axis be the same and all 6 y axis be the same. Create a shared axis box that encloses all 6. Notice that both the X axis and Y axis are shared. This is correct. Now, un-select 'share Y axis' in the context menu. The share Y axis is no longer selected, but Y separeate Y axis are not restored. They should be. Note: the Y ranges are no longer tied, even though the axis are still shared. ------------ 7. Even if I don’t modify anything on a kst file (no click at all) kst always ask for saving the changes on closing. ---------------- Font settings in Settings->General do not appear until, eg, the window is resized. Plots should be updated upon 'apply'. ---------------- It is not clear from the dialog that grid and color options are defaults for new plots and don't apply to existing plots. The text should be modified to make this clear. --------------------- Drawing / Standardization Errors with inverted drawing of Plots Draw a plot using the drawing tool in any direction other than down and to the right. - The PlotRenderItem is provided a negative size and not drawn - Plot standardization is triggered and all labels / axis are drawn incorrectly --------------------- LabelCreator Dialog cleanup required. Missing Signal - Object::connect: No such signal QPlainTextEdit::textChanged(const QString &) in ../../../src/widgets/labelbuilder.cpp:23 Object::connect: (sender name: '_label') Object::connect: (receiver name: 'LabelBuilder') Title missing (reads Dialog) --------------------- Make dialogs modeless. Open the „about“ dialog box and click on a link. Nothing happens, everything disappears in the box. If kst was started from the command line, you get: QFSFileEngine::open: No file name specified QTextBrowser: No document for http://kst.kde.org/ Confirmed by CBN/linux *Mike* ---------------- Problems with shared axis boxes: Incorrect feedback in rmb menu. Create a window with 6 plots in 2 columns. The X axis are the same. The Y axis are different. Make a shared axis box with includes all 6. As expected, the X axis are shared, and the Y aren't. "rmb->Shared Axis Box Settings -> Share Plots on Y axis " is checked, even though the Y axis aren't shared. Un check it. The Y axis are now shared, even though the check box says they aren't. Tied Zoom behavior in shared axis boxes: Create a window with 6 plots in 2 columns. Create a shared axis box which shares in X but not in Y. Select the tied zoom box in any two of the plots. Make a Y zoom in one of the tied plots. The plot it is tied to does not re-zoom. It should. Related to above: Create a share X axis box, which contains some, but not all of the plots. Tie a plot inside the share axis box with a plot outside the share axis box. Do a Y zoom on the tied plot inside the share axis box. The one outside does not change its zoom. It should. Extra tied zoom button: There is a tied zoom box associated with shared axis boxes. There shouldn't be. Tied zoom boxes are only associated with plots. I have moved the description of correct behavior which is broken by the above back to here from 'fixed bugs' : ------------------------------ Shared Axis behavioral principles: -All plots have a tied zoom indicator (which may not always be shown). -All plots indicated as tied will have both of their axis tied, regardless if they are shared. -All plots not indicated as tied will only have their axis tied if they are shared. ------------ Bugs based on the above principles: -------------- The tied zoom indicator behavior is as follows: For axis that are selected to be shared: -If any of the plots inside the shared axis box are tied to any plots outside the shared axis box, then the shared axis for all plots in the shared axis box will be tied to the tied plots outside. For axis that are *not* selected to be shared: -The tied zoom for the *unshared* axis behaves exactly as it would if the plot were not in a shared axis box. **Shared axis boxes do not have tied zoom indicators - only the plots do.** Tied zoom indicator location: - If a plot shares *only* an X axis with a plot directly above it: The indicator will be to the right of the plot, with its top even with the top of the plot. - If a plot shares *only* a Y axis with the plot directly to its right: The indicator will be above the plot, with its top even with the right of the plot. - If a plot shares *both* axis with a plot above and a plot to its right: The indicator is not shown - its behavior would be redundant with the indicator on the top right corner. - If a plot is in a shared axis box which shares both X and Y axis: only the plot in the top right corner (alternativly, only plots which don't share an axis with a plot above or to its right) will show its indicator. The indicator would be redundant, anyway, with the indicator in the top right. ------------ Vector selectors in opened dialogs not updated when new vectirs are created. Start kst From the data manager open a curve dialog and a vector dialog. Create a vector in the vector dialog. It does not appear in any of the vector selectors in the curve dialog. It should. Maximum zoom problem after breaking shared axis boxes Create a window with several plots in 2 columns. Each plot should have the same X range, but different Y ranges. Create a shared axis box which includes all the plots. Only X axis are shared, as expected. Now, hit 'm' in one of the plots. It's zoom is what it would be if both X and Y axis were shared (ie, it includes all points in all plots). But, since only the X axis are shared and the Y axis are not shared, the Y zoom should be such that it includes all the points in only the current plot, and not all the plots in the shared box. ie, the Y axis should not be effected by being in a shared box, if Y axis are not shared. In the « edit plot item » dialog: the size of this dialog box is not scalable. Problem is that the size is computed with the longest name of all the curves in the plot. And these names can be very long if automatically generated… It needs a maximum width Intelligent and useful window title: If a kst file has been opened, the window title should be kst plot dialog bug: -doesn't properly fill zoom mode with 'mean centered'. -------------------- Plot Bug: Mean Centered X range doesn't seem to work: create a plot with a curve Mean centered X range -> apply. Does the right thing. Now advance one screen. Plot does not advance. -------------------- plot dialog bugs: -doesn't fill range with enough significant figures *cbn* ---------------- kstdatarc is located relative to the directory from which kst is run. It should be located in the standard config directory. For linux under KDE4, this is `kde4-config --localprefix`/share/config/ For linux, not kde4, consider ~/.kst/ No idea what it should be for windows or mac. --------------------- 4. Reloading a previously saved kst files seems to forget all the “configure ascii file” settings (in particularly “read fields names from”) so that no vector can be generated because kst tries to read an unknown field! This may explain why the relative path names did not work (see bug reported earlier). In the meantime, it has been confirmed that reloading works with the appropriate kstdatarc file in the right place. --------- "kst setting dialog" interface to global ASCII options. kst can currently read default ascii settings from the kstrc file. These settings need to be settable from the kstsettingsdialog. --------- For extreme cases of base/offset mode there are rounding errors related to the subtraction of the base. Rounding problems in base/offset mode: Log axis should never go to base offset mode - instead they should use scientific; powers should be relative to 1. - LogAxis are now using only two significant digits so that scientific notation is used by default. *cbn* --------- Crash Case: crash second time opening config dialog. Start kst. Open the configuration dialog (settings->configure kst), close it, then open it again. Crash! --------- Hitting shift changes into y-zoom mode forever, rather than just changing it while shift is depressed. After doing this it's difficult to get back to xy-zoom mode. (I have to right click twice to open and close the context menu.) (cbn says 'not confirmed - more info needed) - Tested on Windows / Linux and cannot reproduce. -------------------- -In the data wizard or in the data manager, select the data from a file by giving the path relative to the folder where kst was started. The plot appears without problem. Save the kst file in the same folder where kst was started. Close Kst from the same place and reopen the kst file. It cannot plot the data. But if you go in the data manager and edit a specific vector from the file, it will be plotted. -------------------- Offset mode doesn't work in data mode. In a plot in kst, go into data mode. Then use 'c' to leave a marker. It is left in the correct place. Now move the mouse. The offset to the marker is not shown, but it should be. If you leave data mode, then it is. (behavior should be the same as 1.x). -------------------- Showstopper printing problems: - 2.0 needs these fixed. otherwise, another beta :-( Labels in Print to file are not vector quality... they should be. This appears to be related to caching of labels... Increasing the printer resolution to "high resolution" solves this, at the expense of huge pdf files, and very slow print rendering. Printed files should be all vector, not cached pixmaps. ------------------------------ USAGE() does not exit cleanly, so there are issues under windows: For the « kst --help » I first get the message “Runtime Error! Program: c:\Program\klst\bin\kst.exe This application has requested the runtim to terminate it in an unusual way. Please contact the application’s support team for more information.” Then kst closes and and I get the help in the console (cygwin) in the windows cmd.exe I don’t get any help… --------------------- When a new plot is added to an tab which already has plots in it (eg, from the Placement widget), then the label font sizes should be based on the label font sizes of the plots already in the tab. (either 'vote' or use the first one). All font properties replicated. Use the first one. -------------------- Problem resizing plots: resizing a plot from the top or left grip points blanks out part of the plot. Using the bottom right grip does not. -------------------- Save as default should not default to checked in ascii configure dialog. -------------------- The Y axis label drifts when you resize the height of a plot with the top grip. Then, pull up the Plot Edit dialog, dimensions tab. Enable 'apply' by selecting, then unselecting 'fix aspect ratio'. Apply. The plot moves, but the Y label is back where it should be. Enable apply again, and hit apply. The plot is back where it should be, with no problems. -------- Reasonable/sticky defaults for the export dialog. -------------------- Draw a line in a plot. Resize the plot. The line drifts away. ------------ Sensible filter in image dialog -------------------- Rotated axis number label spacing is wrong -------------------- ASCII settings are ignored unless they are the global defaults. -------- Reasonable/sticky defaults for plotDefaults See View::configurePlotFontDefaults for a place to do this... Currently, new plots follow any existing plots, but there is no sensibly set 1st plot default. Probably need to set defaults in the plot dialog *Changed fields (?). But need to figure out order - we want to also save the viewItemDialog set fields. ------------------------------------------------------------------------------------- Fixed after beta 3 ------------------------------------------------------------------------------------- Multi-page printing: The code is in place and commented out, because it gets the size wrong for pages other than the current tab. This bug is also hit in the export widget. -------------------- Need to be able to rebuild the datasource list: Make a list of all dataprimitives and their file names Erase all data sources from the object store. for each dataprimitive { find or create (filename) changeFile(newDatasource) (adds to the store?) } -------------------- Datasources that are browsed are created, remembered, and saved/loaded. ---------- Improve behavior of data wizard selector ------------ Names in multipage graphics file export. name_2.png, not name.png_2, etc -------- Printing from the command line. This existed in 1.x Note: printing still requires parts of Qt which require a window session, so pure scripted headless prints are not possible :-( -------------------- When you plot 48 plots on one screen, the default text size for the plots is way too small to be readable. -------------------- In zoom plot mode (hit 'z' when mouseover a plot) the text does not increase size as the plot expands. This doesn't look proportioned correctly. -------------------- Change data samples range is clumsy to use. I don't think that it should default to having none of the vectors selected. Rather, I think it should default to all preselected (or better, all preselected if you've never used the dialog before, but to remember which were selected from before and default to those). Certainly, when you make some changes and hit apply (without closing the dialog box), the vectors you have selected shouldn't become unselected; they should remain. -------------------- Plot widths with live data are variable depending on the axis numbers position. If, for example, you're plotting live data as a function of INDEX and INDEX is in the hundreds of thousands, when the major tick for INDEX is near the edge of the plot, the plot will get narrower so that the axis number can fit in the window. I don't think that plots should change size at all when data is live. -------------------- 2. When in data mode, the status bar shows the backslashes used to escape characters in curve names. I think that maybe (but maybe not) the status bar should render the names (with subscripts and superscripts, for example). The status bar should certainly not show escaping backslashes. -------------------- 4. When displaying an axis as time, "offset mode" turns on (good), but only displays offsets in seconds (bad). When a day's worth of data is on the screen, the unit shouldn't be seconds, or even minutes. -------------------- 5. When displaying an axis as time and offset mode is on, the offset steps should be natural for the type of units. 100 seconds is not natural (120 would be, or better, 2 minutes; see the bug above). -------------------- 1. When the x axis set to to interpret as standard C time, the time is displayed correctly on the axis labels, but just displays as the raw value in the status bar (on the lower left of the window). This is both in "normal mode" and in "data mode". ------------------ Cleanup layout totally sucks! kst-2.0.3/devel-docs/Kst2Specs/commandline.pdf000644 001750 001750 00000123500 11544160206 021520 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream xZɊ$7WPeJAPo^߷"B I=C3Pd+3X_qى^K'U~x}fayjǻ(WGFy/׌bx(h턷=\/]Oo/K8oŒ$èAC Qp >)n#>˄h)<\$@;PE*i:co.s#bk%lm_ s*X;$Cx!7h1[tCXVi $&E8^ H܎%Ӹ%6} nCzrKr#aA4]K34z9L_u ?sSHBҹ. l< G)?`5G6ǥS >UB x _ȻgģmūR %CIR^Y2.}B+:AlFI[<菄tV`)9{#M|(a58+BBթN)g;ڣ݊dŐ5R-#hT0*ٴdNuSkB1?g4Rb+G#ÝTI=cC6O! OP RJWYV Q)piTvy^Jnﺡ!qARqkʡU piĜ|Hyx_ eCO ss (TU`#mm0 C{UtHNKH]vt(PQem1W"b9K9imUXOb&a j*!4%!=.9AgnHellQӦҹV/)1{fDOa&{(hɫNCU~T5?s!D, ٖs9 fnU"GWTDvc~8-v!Цa t |j&JPBS_hVnc|4lȬf_T(Խ4M[%E(󗶛ʁʰ4Jj^^4QXQ I駠kF11J'{RmCjrECFx>zqjMS:ן;fe0[t6.o gHr]F{>E$^t2;HѦDȜ`Щb^'x@sfgշ[.S*']^?݋6>F30ibr|w endstream endobj 3 0 obj 1868 endobj 5 0 obj <> stream xXK0W\H* B[Bҿ_ClGNnYJ qhdͯF5[~||I</6Nӗ/34˷O{e{_[?{qLOO3Zgh01jyxmwJVj^hCZ8y+AAWp*rc^QXb1qn!q@TVk|wF;XeHG(1 'N&ڳ(v;Kxg<1tPhOTy(B[2cX܂Z\E3!QDME?_BTԎ%Q-$d%OkЯn]b zm "(A9 l&( o ^Bu~Lø4IPmrp&L*FBeC\1Qg^φh)bh@2IY>goH2N)Lr#s% 1lYkᕹ0u_w E---gMZ,,虬i(3fk柛CQD8t5̽:4Fɯ5":_yhmچD >mtSʾ%xV႗S,Qtŕ@SJ%ۊ6m7{.E y]ra\7inn6G>=J.j?}UPj =%>XpslYZ5,wa~I_SM0Z]#"e D83r.rLwŋyw:'oG Eg>ʗCo޲poܘp\dbNTޥrGK:bZJ;lD׵ZsnU!8OoB endstream endobj 6 0 obj 1118 endobj 8 0 obj <> stream x{ \UUZ{ @^ D@<@ GC^kZ`Ե 1s*!B1eXd3<,rZc>GVs9Z{{ڨمP "Z]hw>GTI@Cƕ}4!s^YN迈Pp=PL?'"sDV7CLfKhXȨcbıIOFAk^><ؼn:~XO^ӡk+xmGvL^DxP{` )n =z? 7O;Wh |}m*&9Ԋǹh _@g@]J۸wD;&ԋ |& HghL6 u@Ct1F6@nوB/Bay((E2+WOJѕL0*=NJ>FX|X}$iII)J+naWV`y%4iaܖϞQ$8,UJL5sؼVk}4(EcP8 kMNLIZ{ILϛ 4N0R5d0^s+.dikfXy֬#w uKL3D1'> |QzG ߀K lнxujZ8!".V4ظ1zClZ >5DdoK1?FoѠh׈a 񦫧.-Y_g]1]bȂQ]'T ñ8>ߪ[юg#ߒ?'k4(ws]Zېttw/LJ'3[gɕbX?An5e@( !!;"QF4125H_I&.13,!m;lٱs;_ \ 2hrgz߃-Enan͐%Dk$4NVIЄf !2J30~"6'~k\9>~MHx͛8p@4xjhQ:V$h1eGFz(J9>ʓ^' o g4 (4|($V낀A _0mYr ?WW<ߧm@Wꭣ5Üs5AAO֘QŜd( 9 Ej&pɚE[ikb2 `ĵu< jKb+;_SBW7&o~Ie_ 26Ij@'A@h{2ӌ;: c`N2Nd%Of]ׯ#I#Z @@4G7?404ytYV}B}~8=7ooI~c`C)*gϫ5bm 5҅hD95LsTɕ}&}vog=4Bk`A.'I=A:A 1 LW2,4M@v`+ŏ;W='MSvܾ?k/|u(Z]( tRxRdP5F`|VsK,N33~p|uw+I.w8 }W%ҟHga9ſ_ʿg*a G͚FomGua-c FtDdm1;&80ſ.KBn2=܈%d6!aOVwCJ~KE7OeK_ĉ8 lpfSw8u x GY@Sp;>eX-m{m??|:w{/\}]f{O4s|ceR:#Ab˼COD\NDaYVJ7,(3 ٓOunGN~ꮧ\·΋lë7fTZj 3أ;ы"Z pNۿAnM2!6%$aɜq)lEVgKQ).5-K+iţtz]GߔfYzox_qa c}D4ktPk j:1t=dGt%Pf3=ɟAU`K'a/_I}g}g^8s }aqK93?[o8!?)#/w˞Ƿz$XEZBt5Am9e svXlR<:r~-tu᠊ywTE_+3,̘u,ZB8}ZΧ b&]KקGeGdGfGeGgdBZElѴh[t-CccR ,MP} [<z k='㫳\9}z7i^_bVvߍ,vOI=TWh.o-79Z')\u-+/L@11; Y-4#C Ks2V`^ׂC __ف?۲mgE}{"W䳋w߻{X^pDZ3m5ۋB:gYJJ˗LjÏY[JnJ=Cz5%[Mk+& K"z-|qQ"ćVjD"@' -V9*CZ`! ֣`Ǔ ^8Zb N$$_g5 \;'$fyeZW9"`k DX #D1zsCm2VQtlUuࣔ'j^ם;R4(eY0'E )! >zx8 Æ1FjrZtRg׊ꛃK#ѧP1ZjaQSݚ5xF[#3)%Bv)^u~3u_&{pw/n+:Ѝ_9\?Z@W cG9 .1GXbBf6C"\Sh024ƓfSH0=XJ7{NYYoՕ-GͰ0MkL֬DE'Cffeqz4F<OIjIV'>xY(Em>.9x|qV?O<4'aXu.ڲ:Dh#8n z\KH;8@y -&|ER"dVpZNIMǸMU8Hr 9ԅrx Y4CS ̒ F̉pnN@Q&1I(OwuC&= &2v'ׂX4"cqBt>+URa"7s7ÑS[xq+ ذ9gp%{crV{]=Fh.lՠN6Q%(@J`/,ԤLZc#)?K__=7uϽ{ an} [OuؠȎcccx7jz l_IpF4!MLӤiti4C6\6泅l1[e %p%r/vx7w ݚݺ݆C>"C!8:sqp\<9=;?n(6aTVd9\X..,.QFh,$)/Bo -zG(-ɚ1om>kW+KK(.vɿk8}||n߃[?:|:a<* N1U?3CԄQE&bIB\.n#xawJJD}ɵﮬU#G߹u#/]=,<@ƽ~<)~cz_ ܰO٫kh`k$`؋ Nf(Vˋ!Ac󬴣7mYO.Nx EI"{} OWlB'y9–̺OF:>$G8hhCNS/W&ߵʱYu4ty%GKr7HUujws ^i96u{ԌL}4dfx>_̴4'iNz]5MbQ*I.T󬝐*JA8P@?zdig7(NWiIE/u5ջ A]jrM˙"4 R$Gr4sX3}.qGu Z p$asJSv?@s<5:x<HZU'Ew1})CxPi&;l7?56R}*tZO7P3475C[H^OmZ:pIPzxgQYb(^8Af**<Pʥb;ih=M-5j(Ujz:Jt׸9|zi@Gr59#^XYKQuT/];qN0G# RIa*5?[asiK Υ(J XL 6N3U.&J@Xqs탨b:}Gj^j pTNW ˲^Olf:j(TG3ċbzc%( ޱ"jPslRAIqT^RP(&˥Ҳ|[SibNɂ fW,J <{q~d,-K%e}~ic⼢B)THE ZQ–rJl,otsrE)R,9RiNY=oAQNT4l @ WR^8"U`TQoS6/JX*IlJ*H 4$B|NNQk((̧s):%)F s*%R T-)*yE9)R~B[ :MUgVl+)JKmyve 6$y%̱1@1ɘŠ.SQRVeܖ"˩e% .':.a7Rүs M&k^ {}f*0 yb(%k>H&FխIݪFj@mʽU.6Inr^UWϡ>i%#š(KYuv!GݝXۘ&Jx#ZsIpBF *!\j]g T hyYwYW'ԣ|h #Zh7[`%FSt0O`F)gT(0;/d{ɔZd2CWݜf UQ|L8f50?y:&N*p!hM+g.fI`Aka.KPoYA2hҿ7&bB@+|0۔)T Y%SMs jD7G,+_#ezݽ.Q/v7i35ᛡ* An 1eӿgF?hQA)62^ וŔ}a;]*5F|X@j1>%zO *"'3;IPϕˇ|f>O`Ѹڔb Zh)4Ji/J[b}ڛ]kC e|-MGWv!ը¯VUء,0>uTv/|9mg) ).YJ0)<¼rgYP]lLDyp/tF!U*ԙ)LCO>[Ocd%i{J"as9ӿ>ӿF*mrw ?Za80EYY6*y /j7*y>)&~jís3s(dRElv9hvkBS{'tTa B*rk_Z7/`eDeEl]@|UCO&}_~RH>> 2˟c1O2|$?#?. F:d{!\x_&{w ~'n3 'HޝIz;;owd򶞜ɯeփf?G7eFy5Ix]&FL^ɯdrfgpZ&drR&/;F =2yťKK-ǒ$Lvyt%zN&p#Ns#9l!dl iBF rHoOOM~D~"2L8QG&C=%'2Lv<*㩤wvǎ 2y |cчGGvL#Ih!mmN &lܿ,/f2$sdr7½2g#KM&dLdL}ABsi "BVI&wɤQ&rA ~< J& R{> endobj 11 0 obj <> stream x]n0E|"4REj 0I3RD ~퐾>РNo][IDմ0䷾T}~nHҷxv]MMw$} ֟c}íB~PYRSTՅRIMM> endobj 13 0 obj <> stream xݻ xU0|N^=RIHBBg11v "IIdlҝ$"qqF2sG".jtxEGf"P|9Uљ~|Sy:CȌv ͽwBMu &AQg[vo"1s殡xB93sۡQ#T}hV{wlQ UpAWˬw}[{#U^i]V)Rz#t%Lzb> 3CSG9 :(M;.ǛK<3ENMK5;;g?7/¢疠aE7Pڂv#a/zA{+tg8^8pES0ja/ yDV-q' x~ج7"~R:>IX?*%Q>#ï{aU:yr jES9կ&n(ϥzjSm£0?EbQW!g T{F=GQ4GFnMѬ(b &ā8tt 8HQ v(:W@n>%MHFu= asS*&T:P<)-v8ĥqvM䊯v,E28po_{{[=Шk*|rTyFyV9l3y'*#O)FZZU@I4D,"[+Fz 鈷:,Yd73JU(\ s6%a-:3=ӋS yOOl{/_^ (?{?pu~ҩ3h@Q0ł#Hx:`Y:NN;#1z+ Qcú KK?b2WV#.RG0ۛ{'T`$՝FP>vT*GdܤKF3ȓ;4PI%"E8#z2KH5K)B, Kka9dсܩ‹ax]Nȕ$^lZcDDŎ#Vdw̒L6 fI6.ڣ;#[xTY>Og}1 X=.pvwhcJVɳcHv_9CS:l;;/ /}|!geJLf.YfS,,vwg5&sjkss6dvg%g##;{YrC5DEУ{5vBS9)<`N9;`ΆV10sA9blS9ے-gf3M-ҙSSKWk̕)rejezqiye>u}ZK2u;-)]rWjWZ8}D1G,C֑y$u$m(97<\|Bמtn'[i/F'쫿>ۿؽ3 ?Ə(\Zc+YP9isxaɢz7>/_JFX`3 o`fSR:t5"{B.<tr ~Dxn\1޹4[̒s,XNݢ#ܰGM!Y&hӴcn^/\x[8zSo^2|~;ө=`Mjbs~q/KҹVa1aqy!=6pbި&Ѭs9%I$H:I5H]te8ۘ)r{35-K%d DX[oXv<21YZ*p¸\\n4VW:V:E%|PjubiY&IotM&CE ڜ-&O?ڊmd?$ Æ@ʐq@b7XAi>9]woOy1S HF _],} i@{@=ʫ!Y/s/y1,j>F/1:]%or$in( f^¶tԈz.8ۥKOtNϟ.[4?ٿ?q/]ؒW^t闳;:H]'XԁQ h~'~@T "LS"\*?O|it_j&EsN׬mnJ >wgI|4<-'F9Z t<ޛFEB\ۿ''8Qx_Μ3gҊ*?W-ꏗ.f;FpbVYl'WV 0xrY-l:flmvnپ ":GV^o0IPํn19B1G̱CJ²ºnF~@m5l5nZf vgT0 OsCx2,{]\ sJB5= { {wgnJ MUg% GiA!''mmI5}@p.)B8ԢgY7CCIO?bsun~!ûovt44V}37ȯto `t HMEa2`PA)6F^{ kRK`"D$ܒGJ  > 7,cm4Dfp>Y@QZ!jVݶo7pn+|QIGo.^rߒ_ovnA&nwK$ ܰxOIq ,G]PBDэTS"x8^g]{fl$% (57PIyrYxZ*R_9Oҹ)?R峤H٧r٧)DŽ1ݘ{3=p*B]x–eCIUL^Dz[,ʣw>?ν{v,mjz#7߅_ˎ5_8V `H@k%bd=tX؛2dɜN^l3drm%Y9^1ˬb^%gfeo767X6l7nH[~kʭ򭩷ݚ~ | @ځ#)G#GҎ'lsu}s{4hIIIIɄVZMri"/ri^v{M}?ix?6ac ظ~yUj?ϛcuuˮG~U%`KCLD4]g˰ 46/VeΧ34P/`,+T }̛}ȧyۓF 1aj Mb6G1A{{By'obnuԲ:"˕v^oA}"lÇ>w/g׾׸4%Ys>rÛbfcQ󖄦/*hᓳ~7J ߟCt;0x/y-t __|{ӟo|tz( 1'CM9,]}MͶRHZʲ̢ ,iΞePDz{hTBX%Ouxq]2K1{vٷo{CE_@2|?N.\P^T:;X/@(}N >YIf&L~8NQS\dNXuK~9k?*-Q8Ga T9G[ >0-)T)vh0ObVs\ڎ3_7{6};Tq#rxD3QM+c GȺp#w R[4wh-3Ж@ރ&nbe8h5Zp.Yh.n{A2$3Dc4ok(Z !Aq=sJq$ *7[2C&c,ili77lݳ}e.Wlw{yلĉ zOF<㉖%$HlIɔSZdcG"X=d4x=Fd3 CFŒd-<wf &~X%%:tЁ@n,Î &?)hHCtꔣXl,Nu^%7cJ6E7h3z ^gy2 ٶl<[ԻhXkllin=kHzXh f"fp\z&iqX%ۖJp{=٦Lk-99.;ۓ4<2Z*;KKrksqδhotfl 6KfG3j4%eiXjpt}go9lm_Io/⮹8~>Ye ϸ S ]/Y\}GdLl36%8tjӐhp?M׌%SV)wͫ*-WZUU:}^M tUscZjC+/q{,hF vYc4e}mOs{}[T^Vut(ەGG}^ L!۬I38:dYM"g}"ws3 [*K<94WkT?i-yyvfaq/` OY|E㟄Okrܺ&Wa]? #/_}{ӏN.Ȏt*)uMF}`N%H/ao[l"7^.b2gəj -3?1ى,mr("HzCjyE _d٩LLzٴRUiIMMIi 1%5;Hx"X] 2MLzZpĹt#m:ãYΥ&_5ы/9 9>&QHcO$df:ی.u˽8BK(OB1PBy w@\J£ 3!e=dgͪ7Mfβ@9|HסCIH?1r{܉>.i1ͦn+Нr(1 ŤDdB!advFw7c> PW70}{E+ b+-fՋHQ5XWJZV޺݆vuȽiuѢ O>GMfmKLLfl$ÔamɲfB̴g'fJ%\)YBVJºܶ"i^ϭ'uвֺiLl5&ulַ,Ŷ%mE7 !ˠ5fI1{̵=O'݊n66nݺ˶u[}&]G@kR5~/~`Sqw(]{p[۹qdA2beޏ_/8V2R Vaka#g*vrPՂM,`=ul{:$j(SV3V+}8_ǰʑܯ-cN(OL^O^vH0 -v8au%oAJqoѪWnS^xoM8x%G?>1?,| Ia4S>8Huʈ7,x;TQ9Kyя%?dQ믳`}H3.z[ ~súadD+zhle Boԗaވ[ޡԎ=̵9 wca/Gi-l$mqz/)P?>xQzBf]; {u6vad~Oly,)-ǵ7ZeTy\2ڊ=8Wڕ}J;@7I4zi[Do4/MD~ "1 ‚|$cw ۧ~̖ QXJs %B%#Yzh>Úk-vWXk(oChX#= z=oz!m!AcIzmJʓeLϴ̆Ta8˗<}mRĽ-+BWaYet-wWz*֠zI=zC\ovk{g}Rq .B9huI]NWmJ%|hsdX72l5m5YF7nK7LjskٚF{e95!Ƹ#=/)Javp)~ዣǸQn!/]\1yfb WpTO(J WM&TX̜)(%1h#D3J36~f  Y}gՏEmq]R7rk_k7k7uP/+{ `"fb},Yr9|||CqTj^b.,,.-+MYPrDX<fC[-{="~jR?(KNvp` r߂o=>ҽqΈJЩ@jlfxnI;K9#GRNNvuqŹ씫r#[J`zOR47"fg9y3 Esq.gbwfBX(f 3 avX!:ES7S%m_ܙэ_5+QߟYP]YQsK&v'$$,o_wkx3SJ;E)*˞nټ+VO?sgڎ|};?-ZzDZtnٰhhj wvx~'5 :jv!Ÿ/$-vE" VQS2HԗVT LM\DOU,7/@Ew]Yqƻ]Xg ʳXͰOUyYEW{[X/gǕG؁/ﱻ( GzEts`t;x,EFG \c-S0ذ$3xM nb"& u 86 u > w݁aor0;K'jGD#fD0 -Ο^/cB#er7B@xV6J%5 A8ȡK#;`><Wb^y\n[) nK}OZĽpً>z '+}/]&N}@qkcr(s[v 2Cr<Ә-tΧ3Dof5y5lS+c}tV} _wCX==䳣 ]Zz`3E8|p}wr9g&Obg^Vxx5W^A@zO.(C:a= b&xv%b3 ]M)Ȗl5ۓ3%՛B)u3w(xV lBX7jr+v!%wA:e7*3;*O(ayļy΋Ǜp  ;𩇟MC)vN?3NWGa5a 9Bn%yˎBm$ЂE=BAa= C^t |@mK`5B B%,T6x@}z>Laй=6@>.߂\n軆_g_/%Cf]л't Y{ =J 3^ckk䗼 BK]6Y}a0hi|V7:LM?70nYg }=P/0 1XDn{A0!=K+MGCě[[#ݽ0tR' Nc"I`A9H;kQz] " Gb lFI_/o 1000n鏅 &AK]AJ`81a ߧGaaq ȓ*F}:`1X^QV)_ U59Y(U㧟YW} 2&d~il@` &(tH-E̚ E'ȜP)}zZ*RP,B `lgp[L|73A`ѿfaLGW)r\F.6/ QO@!F_4e,]hWA6? y1mg6Tߩ,ϴ0L_&i  L=G¥ffYC3_=EzF5C̢^T~6j$UyQ=9{E+O1b/NެiL͋=LoDE󑘖&$U0:xw[RƞiBB\0X*:C-{z ,:c8*Z=Y`WCoVheгi{ըf50ߡ(-* ?u:U cj+ehfeLF2 (bww ¸z&2ƳJm a9*8,gTQX?!W]Zz'6gdU:OS+5 `c/7٫g5gMypW\UZOVChjduZ F'5D&*At2n6bz/k3.֗ͬZآW7eW,߫XY;U&~m,lUw٪ ߓw 3 z2OۇIP [ݗi}(:`ʃ՝2S?_gO>1*H Bv . Y𓥐$Ò dl$¬z$=H n$r]|Od)v)>9̰YėX I"@M, RB<q\N"ts v]!HK  VxfUX%bS`^'aĠ ۉN(tۈB0>PN$ 8s?oKFul@ endstream endobj 14 0 obj 13566 endobj 15 0 obj <> endobj 16 0 obj <> stream x]ˎ0E|˞E \[HYC ऑ:YǷ.3#"ѱ]U>.Q;ݜn}jBz OmJk=&Y=>nsZ%xvGnSdߧ6L]I~mq}g~N6cLm_ןH4ő!Yt};0"K^d endstream endobj 17 0 obj <> endobj 18 0 obj <> stream x{ \TwwμsfAA| A%" DfЉ5`bbX45&њMcc|dknRof6ݻn4Mxw 1iȜ7  {/-;1Ρo:~kvwJr8B9=@o#S s{`Vܡנ??k:AP_3xطol r@?{Ch jUd> ׶y0C~tT>9^T5Z`4-V=͑tedfe7gZV :)cBP5Lv^쇵 h ݏƷnf;<'(0rVj P+ڄ75\7f:nfm\i3nT| q8?`rQ\g l7EQ`EQOA 6Sk)u @߄61 02Jb#o]^ TsVl[ (n0quc\t7N Zy+Qb0 )vq5"dC/+x *L'ܺm[YSI)DM'q7ڸ $yNr9_*\&|ZZZڠIz0 5ճ^tn0x%ruEȨ~C.]L^Zb5{̹Cף8q(WB~'kGފ΅l }铫ޡ/rUxį/ e[[]Oe* 6&qsNe&Ko<ӅDQ|@c^ac|Ou9/1O3Ay_%>i=xy+ȁȁfhTԅ"B"/b]+y;9167lUmi 9ɞqMklE|TɸE_:(&Y?$~&OtA.%kJesMcY\OM+椩ӪYs48Ue:4Yf ieӫf>^qUٲ`6*v+L`6uo0{SKKힲRJ:9e;]}x+/9|K˝=㇆5{ӢCߏǙOyHm;@,Ξܦ4?q?J{:qS X0pi,'M\.xCtP]YnWU:*+ \3gj iŎaݰ~0lv Þav-pRm͛^6gBBS,8LRHg=1 vȆhd1jV46w{Ưw6^ܾ+^ v%u| ]61`ŀ1 of.Sˬ&}-\ [ D:8DHb$Ȝ Hh?W[lGM1ZЃ[e4jڗ,~/nGcc㤃gZ%)@W^ 5 3+C!|ڠ,'5;%DAWƄT6<:h ghjZQe}#\Ҩ벇ʾ͝CT4EEEEE_{$+Up9 pu{|3veZ2<~ȉ̸ֿdT ;jUZ#h2Zm^o2gUիǴܘb$fVN0eg̸ lHtxt_Ry&oISmEaK4iƴ4;ZVhijƩͲY6-g33*3k|Fzf>z퇶BeW /@v{OW!fLF3#Hl ZXvsx  ^*[|w'%L>9(Y(KFT 7\!, 5_Uk1Z?v>\5kGU;hߢSpheʐI*GbXNW{R 1/7J9D`ϯ_ltաt%'$O 롆pq !<1a``d1FF!diQ2Fu*7qxC>cG! JSҰwB`9mL]ś+eu$0?Ow0Ԗ|rHnkIZlQ`FftJ4A`ٌ EPLddJ*D[Ώ#WZx{|}=C&3h$y/yٳy7v?}YM#xu>jʤUmED8 ӵO.~zTKNn̤诌<_::::*x'wzA߂)l%^]kԓRO.D&!s΋NT{jo=kΞ>}V)21[8sBlY,f3bx:h<*|枃 )h?D ^RB ))rpQÝɆWr+ss_2r $7@gHߵ]Aȗg:<ޱ]+W^g}sx.lD]0AD5Im%)^64sT \j@3-* pHN*4!:K?1(^~D%~[.=np3" ԛ+-n9R7sllch`٘Ց2㵏ܜ~Ε_Kτ6 θpt!߁XoթRr3HK~xEc&2A }[`tOmwڸԿ=ȹ@9S`}o_ْQ*XNrՠ!kѫPx(ZQ s5$^ G~{s<W8$`KGՈaV8hZyΛӳ1< aAK"m-9M://V0$&~2պAtLߜbܢ,a$?j;Ll;5il (b3FjaZuA) I$TUnк@H (CpdպSnX`'VBm(sHefW!/+.\\WNjpԶk9jiZzV{Rt5[RZU*ݭP*lnR1nQbhIm5 U*cّgu0h[-)+e kߧ[yݪl$]tK=bUBRXu6fuۦ++[mMn:נbr:d F\O ו!udPCkٳls9?wngg]_?ς9{r> |qEߴj&GR% 'K!:oT3-߇v?gwN߇"~@L?vfa ;;VAe N#@Q=ivͨOKϴSoP`՘YtMF^XԖwbj"˄V%|MHxC%!#kQuFΠ2N]3ȭuLiv3rQ@Wuy30 Jv e2\\W=SzEv;s'{']Ѧ-cq}`Aih -0(IQiZ)Z饖#1g*}xq3;=¨q~Lyw '礙xAҗq& ˌ&|zB.;=`/@$)H䢩 (Qs8N*$1hr<&**$ⶍ۹כ;I >nEf?uGi-Gď1U0o/?w}ys~Ư~9ܸ".~:~_CPNv Lg;2Qf{t'n ,B &Ԏ Ɯ٬tGj0\*ST 9t kbu(:f˟3oz+lĦz[Cv.s:&fr2kQ^pUdTd֦:[-髝F= 4y-O8*e[eK޲t^)$Ύap}w;?gVܺ3+w(?8 m;`Ok?"}u98~w@)\tOu`hW$vܬLxlٳ%Nzv7xvITȖ;$Pw?dDiJN%;ԙ'='WuQ\jr CvFݨfM̳G:yNG+8h7-~0^ѣV8:Gh'whW*ʐGG/ט <5:/sp"SE[RPnPRMWT?Wj5ϴl~ZȎz\CnLk}0pهY]I1H=Fšr#3 m#rmV|YW}( hf@nN3&͈<'2E͠tmXniyߐyXIn+*Uȫm-*muGnPrۄݟm3R %p<һ'&u R#.,Ec`P,f**4PHSX=(tB z`G_o$ִ#݋C}]}hoh@JI:7+eqwhz=X ƇHg;Y,j2!-I `_hs~QLl9:ͬhz& SNX$D6 P4`7Jy{ > ۀ``S ÆPG Xtde'(s<r ЁI(0KY`]B  u<``p |{y" c|I$;LW/1 R&m()u vL6zB1@W>HQXO)j*hOaPDAPɟr4A c2A{B_@=tcWH `dž`gH<$uz r @"@R B1CT%R Oh4'D{@TGPJDgh"""-`w*<^h4hR.W x "`wEc}_<%:HHzq]})%p(ŅI$EONZ҈f$L$ztEoĄ%l6k"PAPoX}A2!'zQ8nBû.ad(*FeSA>A^ Á΍@@(?rŚt8-@1MZV#66 -U5u-BSsj[}op[]Uhjhmkvay]CuP\"46 u+j`aI꺆b*׭kt [QӼdt׵ u f-[떬jV575jPP Ԭ"ВƦ溥Z aS+  U5+ f.),PlnYVU_/,kmimZA,mh\AxAX\T-pRWխ(VT-i8,ə`ٰPhiYRGǺ%t%8QO]Rr  e5 -Q\5mu-5BUs] A%UO"_"#2EUdL`uMU=l!h|a-hW͖`8Ft[6n=RW*B^:+&3X<0. eKh7D#v  F+g7J-`H{@_`[4dJplA-R@N$ C ŋ`m3I[2} ). "AZލŽࣶ{ŲB%QEP/Zz>DxJE]@aM E7(Q!֡X_*w gԠjhm 脵M e>ð: ҋy?b5h |ԝf} n[HLP +Gt`} ;4Nžh n%E)9" d Ͱ$L57=Y^Z8Q4!Wh͹=AsE)W7XHֳ…PDShz(sAa]N7 &O$,iS!+D1òK'jLp/ N 1dN!azY-.iRƣ{SK%Gvw {2}vVS(1:O7d=K8qv lAsrOH>Cp s.JAZl/?PNlBx@̙~:JQ~dVJRH<(.: tS#PȒ=H{eNWSm8ѱ)Z7Afʏ脄5tS9 SL9~3 { PKI>K&$IʘSlwbz  | l Ik2TO4dIu$vB$nH< #Ȳ "i MW%<'Km91I#])2OպD"H(/AQŔk aGIwgLOҔ&iXf|5&ϛʗX(˽ =P? nb$̄L"A'I`3$.ztOA'7E$۩g:݇Rp!!! ǂh lax(5ܑ* 篶8F}ḢAj2oU!s2km6*翂LIE2dwL>r:dq;ɩeӈGi^+ f:Wcs0z0ZMREgȼZm&* K v;rXFϨh-te3F]##;*RDQJm#Hĩ'&0[fLurxʘVQ*x7*Jm%Zj($$ &+^ rRRH試ɩ騄Y,eҞR$RƒuJ=<FZl~nBwR+zWEHOXL ?+Sȍ`^MOi)% hs3HWC9UOWk`}]rD:JLI%OJ#J8F֩*ʻTHBB@$go$)Fe_mk**$j1_a 91d&(/ٓ%XM^ư%ɍ?W]5:iKɑ;5{JS_ H^x)]?eĨ䟥5Qp7\*Y'D!n6J~h.dV"ŏP23Lg'bT ^+Q6( K/4[ EoͯPS+0)i;&g&Ay-{JURU9$hsPy嚪rE2Jg ŧEVįs/>?_p9>1W3}-G揊w,, >L4~&?S5v?}?-C.|4PO>4~r{۹k~۹fl7opxse}Z}Q=?p#ثa{x=uޣn ޕGƏA6ߟw@gwOn2ZȰ{`="57M_sw淊Z.%q?%o`F<p, GEo2M#\8TćE*"q o\7hpkz?mK=qi؆׉4Vk׊3nog,|ߺp lJW&oJÍjt|6Nϯ+\1ro݆xR l^5zևku|H"%%t\7U۰%<kZ| qK>XWXr 0/@3y{\?W6'/ۇ9Tŗþ|=l.il\<-/<(*4BShƅ~@gNW3pf>oc3x¹"4fqrD}#x{F8A?YL?mg,܆3NNt;yF|l5=ұl` lf < ;&aΘ &l@3bjNcuV)4VZ*l`qs̍p1؂cŊ ySF`' /}[ endstream endobj 19 0 obj 11092 endobj 20 0 obj <> endobj 21 0 obj <> stream x]n0E|"W#!E* %Ƃ endstream endobj 22 0 obj <> endobj 23 0 obj <> endobj 24 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <>/Contents 5 0 R>> endobj 7 0 obj <> endobj 25 0 obj <> endobj 26 0 obj < /Producer /CreationDate(D:20081112112703-05'00')>> endobj xref 0 27 0000000000 65535 f 0000041397 00000 n 0000000019 00000 n 0000001958 00000 n 0000041540 00000 n 0000001979 00000 n 0000003168 00000 n 0000041683 00000 n 0000003189 00000 n 0000013290 00000 n 0000013312 00000 n 0000013507 00000 n 0000013985 00000 n 0000014315 00000 n 0000027968 00000 n 0000027991 00000 n 0000028185 00000 n 0000028723 00000 n 0000029102 00000 n 0000040281 00000 n 0000040304 00000 n 0000040503 00000 n 0000040967 00000 n 0000041289 00000 n 0000041342 00000 n 0000041788 00000 n 0000041885 00000 n trailer < <09253C500594D283EBAA22861C746D73> ] /DocChecksum /0EDD51417B459ED1DDAC65B6585DE01B >> startxref 42072 %%EOF kst-2.0.3/devel-docs/Kst2Specs/Updates000644 001750 001750 00000007335 11544160206 020076 0ustar00synthsynth000000 000000 Updates are done by explicitly looping through lists of objects and items. Kst::Objects keep track of and/or provide serial: the serial number (from doUpdates()) of the last time it was updated. serialOfLastChange: the serial number of the last time an update actually led to a change. minInputSerial(): the min serial of any input primitives to the object This method querries the inputs. maxInputSerialOfLastChange(): the max serial where on of the input primitives was actually changed. This method also querries the inputs objectUpdate(new_serial): return NoChange if serial == new_serial return Deferred if minInputSerial < new_serial (an input hasn't be updated yet) return Changed after calling internalUpdate() if maxInputSerialOfLastChange > serialOfLastChange return NoChange otherwise internalUpdate(): actually perform an update. ** should only be called by objectUpdate ** ObjectManager::doUpdates(): The loop for updating Kst::Objects. Calls objectUpdate(). doUpdates() is called by: -datasources, by their timer or watcher -dialogs, at the end of apply() or equivalent Algorithm: loop over all datasources set serialOfLastChange if there was new data do loop over all Objects (except data sources) retval = objectUpdate() until no retval's == Deferred MainWindow::updateViewItems(serial): update plotitems and then views called by a signal emitted at the end of doUpdates() loop over all plot items: plotItem::handleChangedInputs() if any plotItems changed _tabwidget->currentView()->update() -------------- ToDo/shortcomings -The object loop in doUpdates is inefficient, in that it may have to go through the loop up to D times, where D is the heirarchy depth. The loop could instead re-sort the objects as it goes, so that for future visits, nothing would be deferred. In practive, objectUpdate(new_serial) where new_serial == _serial is pretty cheap, and probably doesn't produce a noticible slowdown. In practice the heirarchy depth is 2 (curves of dataVectors) or three (curves of PSD's of dataVectors) -The updateViewItems loop only considers plot items to trigger a view update. It does not check if labels have changed. In practice, it is rare to have only labels from a data source, and no plots, but if one were to do this, it would not get real time redrawn. The solution is to add labels to the list it checks. -The updateViewItems loop will update the current view if any plots have changed: if only plots on other tabs had been changed, it would be better to not update the current view. Not common, and the update is pretty fast if the plot didn't change. -doUpdates() could be threaded the data source loop should not be threaded. It's to cheap to be worth the threading overhead. data primitives should be looped over before all other objects whether data primitives updates should be threaded depends on the nature of the datasource and on the media it is being read from to avoid disk thrashing - dirfiles will suffer from threading data primitive reads, but data sources that store their data contiguously will benefit (eg, ascii). Using flash drives should mean all data primitives would benefit from threading. other data object updates can be threaded. suggested algorithm make a pool of threads parcel out the data objects to the threads -updateViewItems() is probably the slowest operation, and could benefit from threading. the loop over plotItems can easily be threaded as with Objects. There is no way to thread the view update call with the current architecture. It is possible that the refresh pixmaps stuff could be threaded, but I don't know how yet. version: cbn Nov 26'09 kst-2.0.3/devel-docs/Kst2Specs/src/MultiPlotGeometry.svg000644 001750 001750 00000101650 11544160206 023516 0ustar00synthsynth000000 000000 image/svg+xml -10.0 10.0 0.0 Plot Geometry and Alignment Requires Large Label Region Requires Large Label Region Requires Large Label Region Requires Large Label Region Requires small Label Region Requires small Label Region -10.0 10.0 0.0 Requires small Label Region Requires small Label Region Requires small Label Region Requires small Label Region Requires small Label Region Requires small Label Region Requires small Label Region Requires small Label Region Requires small Label Region Requires small Label Region All plots with -the same parentand -the same outer box height will have their top and bottom label regions grow so that they have the same height plot region. All plots with -the same parentand -the same outer box width will have their left and right label regions grow so that they have the same width plot region. Tolerance: 1% of the (Width + Height)/2 of the Top Level View kst-2.0.3/devel-docs/Kst2Specs/src/selected_r_handles.svg000644 001750 001750 00000021507 11544160206 023662 0ustar00synthsynth000000 000000 image/svg+xml ViewObject Selected View Object(Rotate Mode) Rotation Handle kst-2.0.3/devel-docs/Kst2Specs/src/Automatic Labels.odt000644 001750 001750 00000013015 11544160206 023146 0ustar00synthsynth000000 000000 PK G^2 ''mimetypeapplication/vnd.oasis.opendocument.textPK G@.* settings.xmlMo0 f#v/CivVl:jI$ɿ/I.LI4h\x*21>dyNS2 hm$*08WQwZHEU 4\u, 4eSsz;k8i_j',ٗn.IVk eDs2T6*lҀH b΅dպJ%Cw k.k]5ɕ FtB*¸ieY y :&|t# S*ꋱ˅*\̸!z7jfN1ZzhgSazh{GA0~0衪eٲYz z*)ic~fe,YJ61~u?!z-pq[O7)Ss`ʘJ(k#6d )o,h&ϝ~)~rRRkg2W? .I] Q(I_X/h(kic>+ۋg/XP|3cq?P|V41)8"|y3gZŝd+[$]t.f3ruswh<,\SJ,IIJ8L\76u](`Kbn{)M:/]ޡ''שz"1 |E'YMG0/R,J >N}M@)PIRP[QQ /ZC.I hw 9'wfxmJE?=9zbh ho[_~9Ooo.6xý!TooAW9W!jbYV.+Yև}φww4==&=N4VBPfNeMp$f G,Uy(shj/T8Ý< )/l'䊄%y$CŠ bH#{+xJHaćI8{Vm2v@ݚ3NT/6D ڏ u^qv%xl~?[T퍡i!5hOc+ꋣƹ^_?!kmK k,ğ!YsB+@WSC` X+e) vJ{M$Z? PnahZe5Gwƾb3j隶)NO(Yc2m@tgbtSYs2J"Ehúi>O{=ӞK_3^Ag򒾼\jE3KBxAZZb< iL Z?WݤxH3w*F",/MwMyz;i`b..-f -A8 FH9)& K%Z S|s%h0_-oA;^-3U⇘frO> 8%K;3wĊWiO8U[ v\j-ܜ Ixy+1Ļ$^x7^*%N0\~/D<2"[Z:F搘WKnB=>Tl}RdئHI1o9?6'(gG%nu2\QՕB51Ӹ=7rW7/JFP_&s'pbY.QLbű [LÚ]|k!ouniD9 @1: '-aڼ15ubX$מb -ݞ4Z3t:\ᬾ@>n qf4avO9uj{hychISw5`-& [8')@eVU}"IbNYVeB}h7=ZK~ޕ%HYt#[ Qi)vb?U}#%'P0"KY5.!vұs:Еүa)3k;ɲ'DײE?WXfĹseTRؚfu"& ĖEb'C˶LYXq\|sL4):1+@y-CgF4?fl>{q %}vt$U9+x&*W,_<'Q1|-?VBˣ؉]{$b{[q\{R吝aL#{a ;]}jx*[@PK G=Ҽ~ styles.xmlY[6~_x'BP#UJ<9}0FlŰda|x ) %,6݅c%<%l߾hmO[e$Qʓ*LZN%2~ bdp ʜJ]hlj.= lsШ8=\-6Dv4F5G0ImK]'JC56mS0)PEۖk4cFαY 塷GB@BhTuK"63lCxa)v`\fk; . RyUH{lz8m"IxŤ={L~',Hv- El_ұYRba=cL mkOpqs 36G50SPt&':9{¬ZA2=/\鉶Zk d=iD"J?/){Wq{i+ M[`8biZ{]nASok`OvE: Ѷ6ꟍT4EYڸum,oGt&+A }f#;Džq[% L>so3KiZV|WQpM.iP%0ad̉8p"ɌAlm$IbQYD7!UY3(]o>Vb3X-Vn0znKnm] \9 W;T]gbqy5jm!\\HH+Q'fλٟ !GW"P6Nh~|PK G!Dmeta.xmlr E ="i#fn:np0GIMJ&Yu{}0ko2X,IPlm*piĥtD#=IU|MӫcAϝ 8#}d/=yolȹ<sgNbublKaJ)KW؇aH( ո^Eq~l㌭?N$OXI ;4%]KBT= 9 #4uOǡ]6,eI_w/9Z;MWPK GcNThumbnails/thumbnail.png sb``p  $%R,N!@PÑsxD30׌fe@.!^:`qdåiluu>  <  aؐ KYNj+) PK Gϥ"META-INF/manifest.xmlj0 y{ma's`&RJs m3VInw*_D R`yjE?u!Z#uI@NOnӭ[x]U)qOGmx`9xg {y Β+a ɖF(2[H,F\Fr\9q#1lZRf<,V] PK G^2 '' mimetypeUTPK G@.* Msettings.xmlUTPK G MH content.xmlUTPK G=Ҽ~ styles.xmlUTPK G!D meta.xmlUTPK GcN >Thumbnails/thumbnail.pngUTPK Gϥ" META-INF/manifest.xmlUTPKkst-2.0.3/devel-docs/Kst2Specs/src/object names.odt000644 001750 001750 00000071275 11544160206 022403 0ustar00synthsynth000000 000000 PKl9^2 ''mimetypeapplication/vnd.oasis.opendocument.textPKl9Configurations2/statusbar/PKl9'Configurations2/accelerator/current.xmlPKPKl9Configurations2/floater/PKl9Configurations2/popupmenu/PKl9Configurations2/progressbar/PKl9Configurations2/menubar/PKl9Configurations2/toolbar/PKl9Configurations2/images/Bitmaps/PKl9 layout-cachecd`d(0d``e`P28 s20$@PK>sy#5PKl9 content.xml]o7p X.$M $/Vr)^AR]rJV~p-͐ʫKΡiwo3!۫0 #+.qUoVWu=|{od=񥗄L'%Zz\IbёTq4dH[u3}$([kv6FڙW~dCot\1}Y j} WǕQA]ƃF 5c$ 5Xp0h[6di,$챸44TZUAi 4.mxV~y!?IYLްqp9'ik&@xP,3$L>bm HRk)䭐sXqǕ祿\ȷsVf-9E.Td"#.(y,h1ږ!ǻYfɮ?zh40^y l,dDc:i4L? C-§_I;DbL !Lgj(a<`Wɱ@*BuA__zҟW&hId9e$jUk:coڽ1{jPjn%1aV#4~J:YF>8 ;ZCV{Zza7 ƒ@ȿk>G^b؇a_+VܛAc &GQG;Oy~ ߪVSؙ_iJ*2p `؏,b;C!.bR$aM%kuYrq=,œ` 5rQ hZUscqnEX,T{H}yZfWq 0OvuwPo=L'AQps~xԣOzQa 0VsA}YgKM[6'Քotnj^*X 6LW'q/(4P>FQ0LF@to z͗)(Lt9ZAtLq59%:릵zݺ<{S+ZtsdMi%i}3@q, G=_,ffQߺyCq>" X<4+TaLn3!#OB*`n(8zni \ݫ(|2$8IHDR_bFiy:[- szI[c0 (+"_p xBHwbcCr%A}=>W; 9P S"ڈ *p&Q2o$?=,H?If%%f#6PқKhVMC O0bBP2/ToSM\HGRbsD{L`4!U .mRG'4#*48e牐~K@6Ҟ]ޗZ* Y_1Q(LxwF\!DG8DEdS%TwqH 99H٣hTcS3>C I5+$ Ān}b3|'8&8kcqZH?SR >z$BRY}ݗ}N.}e., iX9 d{ +'_ x0sF'$bg u{b?YC6_Ir3/1gu khB|a~wfiDatC Y6}88h61vI=N`^C\#0D˲=X/n"G/Ȍ7g tI>pR"[eMmXG iWNN!MHS*'>>Xw)`ArZM}ۇ".@鶸x]kc~%.3QE-1./;7'% rpK\Zj&NyA2RˋhS"VbagKL1qButiaqGV$4fv]̓A %c]qr,K;[71ΰ+-;2-U1CL˨) 7 O/A~#'KBda6w+aak9Pkq6?)]L]$]Y tǴ.58UbfZ Yi*Ym{*IĈ`x0hzΊN kw-%~w,pEB醓vnhGn$[Pva"Rpsb(2-4ح#AI|MUKv \W.:n J6n[_\٢{Z׌(5bz6bo~mLC0PZ,ֹz6ʗM-P+Piy6]徳*2M[low=ʬi wT\,oAWS<7)u\FIz~nfcW1(eZx-5e%]YCa"EߩƖewHމfÝfQ:(_`9R~u074 F.]?Q06$ϳ3e'3 u2UduQN_^ݵݣۙ,|Sf[̣ՕY֫܁Uzul9ߴQfLe+&AU\O[ZwsZ4LoA_<&^",}\]ٞ;0RnVtT߷9:wG ADÔn,4j)#PhMR0/<62s6ymd*`=F3b]hgn;NT@t7䘜S7OLlb.v͡[{d=2bWAsc6nafH[oh6rjd4U6PKt2k$wiPKl9 styles.xml[_۸T\d[^fspɡ&}=m"I|IQdJڻ 9?CϘ cOfaiRBϿFOm6$%e%++r,V2YS;iWz)3lrdmE+k;;h?v‚N6vAdцE $IGCFp'eNd7a|;Z ԸFgX-&$Zl%+º"2_c>Z5Hhx&!>74m޻tyRwn&O@|Ǯ-U%i|X-`T;SA{N$<'(Kjܧ4S@DYiT)I[q A Rd;[p`~+=? s $Iv| &H8f$:ky:3l>Qa(`%'}LRa-y0dRi RoDTegUnP8y1r=baT %#4+B'3DqU*"gO72TfUb9W"m9*v$ -2:UWbζ2:<]rzb]FPq$ @'@t)~HNr=zxVj`{"w6( đ֐CR5 HFb9FЯ &M0\܀ZzOw3VH+#h`iV'bp%nJA TYU/A7#y UpÌD|Iy!XD[T$;|y%T+dP-aR񌠂#UfeQDzo%U Y eTG>X;LkmMӌjLv T;;Lc4P '(9w0&4 @&68֡@xRHk}bKe9g@eI.Tmr m"/H-ͨf^^+pgU7cj*;e}*g~ @M'ߠ-SʘLWex#u{xh'۝lңѧ0f TD-kM勫GlV)*=V!uw2Vc j4QgIS{lfYگd=!Yؠgv /1|H3|e6*l-/obaݞ.efΌ}ߪ]֛/*'w\ q1݂qM.WME~%-M=//1E6ʆYwiV62sR523\oV/dqAt2&;,Nf "{Q9X0^?YYؠG~~ۏZ/N^{Jh+vc8 \eZk?AhSE/xC(*hgG*n1Ԫ{ssдG"RGMU+F]US :)5PoJ}\>Ruwr-nTFzQMrU"D7d[r7 Qo{WMJ8-kU;k+>3JjJ&v@[ܚCm)~h]GԽyv$~-{F2W͕sܯIuW]M~LskޕiIj >ޣЃ震4eOR^xO\Câw?8ADCK _zpuu{?~So9I#&3ׇ,Xk$}&e# # $̹rSVvKQ-@8l2bhij؃AA韥M8qzdsf?N mF1uw 2j4*BDͣ^Tg+sNwOPKmr,@3PKl9Q*M'meta.xml OpenOffice.org/2.4$Linux OpenOffice.org_project/680m17$Build-93102008-02-19T11:22:232008-12-15T11:11:2511P2DT3H53M24SPKl9Thumbnails/thumbnail.pngzUXen!wwwm<[@p']h6.3bw_Գ^j׊VQAG!Ayw;wHVȟ߽ f"-<*UH elڅ1ZJ#[ +e5]B$H Rb#E#K$9!v}uʗZ]c]/v=Ϋ6a$ꤤ龾e$jjwLD88?,Zq'`sl*[m:X+|4ڟ/mCdDTu((;%lj@B8Yn |PT1;hF3_5#ݧxPd[yIkd*  zƧDwž󣁸lT򝯾1d` n4XZPat!h{ނN3xZpDx^c>Rn{ dH`Ƒ~DB'!F_-^_ |ڌ5W:D=pD:3#d9oMʹR:qӱZvߥ̤3ݖg*.˖[rbh'Umh@6p=t5_߇"&nkUP,nhM-ɠ)ʾ9W f$rVLps 'W c F$~ENzwA,FqcE]_]5>[uD-ty̰=S(kx֏'+2L KĭS;]V\ 3GPq/Q@VP m#s6Tyxq|Gɠ{CGoG5  !zhNqQlh~ Eyw@G[_LzeخV17ᦖ*W&__>(n%潼wȘj0Tl`DhyM_wadO%JN.p{>, Iߪ;JoZ{>җ@4zn#ؤK#Tq BgCc*?QP{)aYC;.cϰiJȮfSI_guaQ ) zM1tr0u OMٙ`^n[ =.=.|A|mc %|rxƪ9S$ya>ϒ"?\Ku?;em`fW{j~Zetat?Hv &5|o늜uʮ DG"mm7X*_{[ dz9z ndݟ_R>*JB} w12+ѫ4s*!}[ٙ-e 49+.6r{W~'75cFa1(,F4m:Uuڽ+vsd\4vV 3}!r[|oyRf H22jA/۟_P,QG"/.B">s=OI;]h+c%jQ(9䷃H ͼ?ҺrNt G2-KY @>X_[`'^i3v6GR)*fX.Ui tɡB*ioVJ.%|,D2 nj>mwd\. &(Fn/j"4x! znsb֚tp—0V,"]E\jw$oBk(Jqh 9I>#*s[cV͑bX̔wwrJz?rXQ3| X {{oX82NO7-K,JOƸ0I0Y@)˾["qƫ S1Ed4iV2N4{HIP!)En{RvzKM3U6FQIaQzywm[%!pi6\oW'2'/ŻT_[a%HYQd.{!? <)L_C߰/f-y4 ɄVc H÷6uĺZ#hOu@ݘ93Ob̛Y 7:3S]V=V.#wx腢:NU}x0&y|g/A m};} q/R%(basoqъH &9+ϯ5~Ć#aodED<7=ɇoB>*k9)-xU 3S^/YA(D?yC{=KJ.L?H 嗤V1ƾk7n3)o B[ȯAWETɕy1{Z g N]xtZ?­UwJ۸AuCkIB%IQ,"a!P8s=߈uG PMlѨ FW:cb>-A ]~ uDqr/\A}PDARUPxGQEs^  í^i&藠q60 6˯2z:DbNIw|[~v`}[3x̧ܶQ(Tk/(۲ү3G3_=""%m|Gg-ܔJVۊn@:->D PG(m !?H0^YR1 p-w+dW̤e97EfΏDDj܋o:E#xESHN:އd&?8CLM\zsmZqqW :d(lPΌӲӦȣD,K*4Ћs ǟZL}Nx!u6YBCۓ"Jı(㲴sL ,¿ ҟujDxW8YߒO@y5ʰQ}nŗH3ՋhIhȦLQHlĻ.XiYSQ.s\Xw>703¥b8E}A; iܹtƒx&p{4LgG v*KM?qVU/i>d6DȾ%3ӵs8Q@NیyZL:f1rEIEh~V!kMl0n<s|:Y`_LPV ;ի:ؤ5s? 's+rt€嵍,KbqMv;ǀ΋ZQK @m7$\T@tKL(il[m>u߈uBH95t+Z+S7U @r^hl o'`ӼR|gÛg[HD} gvҐJ-NxOc-3V/x"Orǁ?{:BA $ d9|뺚[4hCS@gy1n09OJ׸^o#MW /l^q.I_E7Du{ + Y$uE}.8'TZ+;'c Gl 6N aGl/s-DTdZqdUgpה{\9QH`N0);i7?{818Vt#|7ʿCƯY_4i)Z|w8`tb3M,50=hlWzE~hr868{B%/mcz3Q\\"tJ&Ȱ ]قlTiDCYF?55m(qb@mr.K3 ,}9OpJ[_KC1h&}C&mf~wqWzFupЦ;R+dNd-פ SZQ{t="` k ս%8Ls\X{(A;J~^a׏gYńØ}W`I{\J|α!ơeHX웦@SAgSBaDwzSN R z(ӟWmfR?(uR2j#}ZB#1ᘻ{ćvTfIqJyS՗̷ xr,>t0@a1jh`'PL>ݿ)ĵMkOWbͿ^m÷vjLfKz` s$3xҷN|BYSuRl#ܨjw*MK FFsjSyUE(V|7չR{{Bd0#[~ufQ;O#4cf_Q4ơ+mK8M@}_Iic5Fҵ8 ŴVjm-/8Kc74:RR.85krQ$I@nHtORq:ɓ)s9:"/3EHcP L p֛݋r5 +q&,zx4BEi$_ڇ.R& Y\Xsb*UCb@Yi 4 Ŷ8嘋a!N~ e(O.5ۆکib>tw!qW aꤜdNH&~jqzμ!o!,*د,FȐɔ ;! GpI_oDAٷuKLBU9{TIJc&z9 azhVv&hmW'D?^S_g}h Oo6 ma)U*s|4EOIkf`>+{.ӗDO=&)l<Xd45~;EE`ף-!kc3Z:Axovj7Bqi02X?ӝ}>'ى @.]tSG~n3AIUT !HFq;}9?ap~XIc36J_;+>hc]좿R螬hۍ)㔮"9̗Bx!7$ʫ #hr-r PUgHf s?+~ss%"XX{YJׄͿnoNG1r"WR]CX'+ݸ¶#OpcZׅD; ehШajӽ)ERqnKsJIaUižI0 }a7H(-bN.}Fj!Dq]#P o v-^sEZ% z+/E Յ'=Wg^gRQlG$b_S;ՓzN.e4g4rDzsŹux:g< hfvJ(2Aԇh]aMm-+aqNʴ|_O15x>1gJyE$ۇ> .Wl=rsmtYL&ԋFլ}|<S=CEv/Rت\DͯՆK78MH9& m΄'"k p2wPu>CޑѫMH]A-JX^KV2 SWr15\Ylѭ;胔kv8H̄Ŕx/#+ EgN6ЖOcI& wGny{Qȧ#;IS{ѕ}s`Qd^ U.5p˝UZ.q!DDL(kmg1ٺ_0Rgu%HAHb#@C|n2%:ua1-uϕo{}_ԉDd7YF09l*V}F@NןCRQ˃bE>]E}&T{<7jUpش*ʉ϶cÅ *Ur2R͎l0#mnݴjuֺXlx-ynE%U)Kltވ jCgdp%a}/ .>a.e1/Bv9c>&sW >P d8^>U~/lUf.SiN`2]nѺ!>TlUsG6D߲Sue1ۮ׉G6y…p&;"zX??yT-x%~@۵rz𭆼N Gi^Z-{GfjZ x<14O:~y!3mn67R'$zo5gDV||W$>\6Pz6%fE+ْ&R:pd"z) zP}aHD,`5 3H$KbY 1i@dϖU&චRv⺇msu\J܀:7n 37f+\lU1xº`9\p=BTzϷX /jDUiChڌH|ZBDtˎƫ3* ^Bw}B *ސ]-LnZoL"L{5fh!MOlKavi{w rEZ͊`k rfn{]9H2'/>˂qs/V}:{eSa?]?~ 0!#s'R.͑Ta?}:Ci-^VdlZ#ҋM0$Ψ!-%- 9t٫s%ԑ,xZ ɬ߫@:2*:\ [1.ˏ&B(je5XܜӗWz*ljp]0TP^9B2 .xND4fR*P_G_#V}ke侇2o,,:E~}="nxhqYt$RY#d~Sr3z3F2hJ%&^xi0|ovA+FAc9RF9Zs $25☮g|1hVG5PKQ-Yq~3N|(;؎8E?$ԞZ~&0I ٷNMo{;EH7kInR^߼=?%C4otLBq#Eaiu]A0)fEntuu"WELT Eژ,sv"̋'<+<սԔuhx|d^+i; $?jIfAݍ+DIdX7(ڕ+4aZZRTh,s9;2$W~H͊Y/vv=*XeBއbq/9!u,PMޖÃC8,HH8,1$w,CLy.ɽ߁ x/v=D=W{=C  '@VL=WԚLQ9{{seMk>Laܯ((ҥMaHxWn $(,GRmW}:!ѵ_zm\۲Is$}O> `Fq[H _4C]1$z=ig>`7ۥ=.V2όȈsw4SP|*#1gV:/ao09#WGI7p,k+j ٧|7@gQo87wFl KWu#r"IeA]` $&W`&5#"m՘B'*4e;e/r7N7)ʶcQCӰPT\XK֥Jy'oK;ucٴ?Zy`]'KhY3twa#W N}B{28"MT/ hTjݐ눤o3Ҏ-+U@l(1㥮L**)uS0>)i]bwE߷:&04#-U[`4k`QKsAG֚kVH:Bx :_}"v6&/ .=Z&d@IQͰkT>V}Ņaaܰ vTVC;K"/V{uA':˳L:|x-E]k3Gyܔ\:O:kӼW,V Guv! VWY6Ǻbϗ2J;/sc)bEt!(Q:UB,EAڛ5  ݱs^qmO? Oޜ1TxM:5ƺ 0+zq`#<rESo>k×,j>.™U2e%振֮fhPXWp` ml>oFGTwi^Gn%\4$SH޼qP;LH8@P@M^ -Cܛ聖OdK C l[̫dBzqҾ̺< Rg?%\W^Y s$iJ;މ#==5+l3.(i V:*Te5kl =/MZ0|<"VQ|8RQҰk]&'2lBgP'r$cZxΘ!\F'=3FJ'P%J]PhGW BZުWl"}S9٥0 3—NŠPػc) "gkH}um/Ⅺ.e&*{k戙Bzpjܰ+p1rl{UxyPGvFjWi(t]=䪅4߲qOvI |wwF=-gL0׏WmB?rOE"KXNwƦhm*DLI:~AΕ%7'#Ix1mG6V- cQzҷOAde=H7dDmV;;g ͗}J#3X8^Xsv4G7fu4[FZN'N,ly%$ereb Z>}Aq a[2,tk=O `ä7|q[ޝfz˕Tx PJ2rTT*g\F5"ʠ*&?qR򢱋{J3@q2VR.60dii9z+)=Ѵ| z>4vc@< XiaTRgXd`#[N i>AMzՇm0hw<6b3|S@K 7V>4KQ30J%x R0uPHt{sMxNRuq/'Id-1QozQ.'Ƥ G^b(1kϮ0JEC@VR˝5

7_ +rO*\oQ=5!t6'x1+a׽vQ2+"%e5'm EiCU@SzBgӡ~,+czIژ8kl.'Ұ[ɯdtB>j9ߨ(!zN{ {\a};՜Tҳ=1B>GŪ=D_ Y*UE򞤽IqLu q׊鷥" ߖR%#ӏ]k7K%4r|&Hny>_j Z:#HdTUp_C!HHٚ;g0Ary]^wMs`06[) ]T&Tx)wLe(K[YZ+Y%}'t,oe )2d,ٚ!kU} &-9ŽaL;UDqu-n# E>r `vDe ;xmj|6hAOL0W_"hIZrEߚ6k\S!u41|{5wBu/ }B kZV02R8Syx;t1|vlDŽ]soQXkgma;0Eg|fv q&l#!9CZʋ<˹k% ,{@}luzȝ*tZ΃I#g%&[~j "-p 1ZTW$ʽDcr{%9#qI:wCqE@A2 &FN݌runhR1P[( !K'!3q2, 'GUdwtMR:Da[&>[?Q>_֘J/ߟgAUv,Kvw`ejZC3DG/Nds$XN4lk<:uMw??/Inigyj磛HDDQDvp2-ZY l!|cA4NK+(yu>uَP\b1VKϵʻ"[/8)?/(#7~w.ZR"C o ){nj`\0k[]Z3丨K?#qN y1R\<<&U aQRnqtJ@\2~GJyS|b\ZODuwCKUtkV'Mm1~^yhը+Y~Q`ryf$:{jn9̬@d+xviZv/@S-RX,Y$RpLY*NoN&0[fa6Lv1ޕ ;̴H7$S@R=O_>дk qV n)&DlWLv`BL!.TPbg MY{_%.7U[_!L@$Ee>M[SIfD,ֆre/WϷ׃RML65Q#"O¤tQߛHnMTtɪt= +8'{H4 }I[5dDb6x7sl,ҧXp.B9H>_~u׬pZ+ȊD&ަúaBKnҩALV)1@v_a,M&6{}  ;bY Ev( {>vc[>X JK S1RY >e4g9K ym ʲYPY(xjpd lp~GĹN=Jgr9: sdCㇹ$e q8^(:8f)ڈ9P]'uU uU+Z}ٴ*'j)jW ړL?ݗ3  irїInRn0& j@c'⼱_s]cNPKv5鸃GHPKl9 settings.xmlYSH~;y+l\\Q(n߆DߞIyB_= H5Da$f[}mui@3 Ai:B5^*ETSTSML@5߮nZeٓ%7:iVt8E9///zibU~ _ aZ|㚺Zam~*WT" I#͗^oFz jWm KT|iz^$%e l^xzvGFs\ ! Μ DLx--S8LǭhK\(vI2_YRDK}U^v\pJK]e2HJFVB2)#TE =vY[]qָRJtƸIfQ.Xlv~`p4]I(䂇orЋOBكT2M6p$3JQGa\p~ H/4zԳ<&!E'z5`nk&PB7JpK (p."_IU q"Ak76q#2t\ 3w% ɀ% tKa ŹtJ@WC8o5660H0{٢$cSY:J!w0? (a3:)*}!P[ y@x! B|+я :]Dt}[R=I' _=*7Le ̮'QgVf46.VQ}11HESWeh&(yG#5GãWm/m$-]TJ Ijw &|@aN%HOW}aX- qqࢭia{VF-K !TQr K$YVJGM>s8D^ȍLà[IߎӾijЎW։ɂhV0ZKTE'ʦ *ٕRVM&8=h3e.mJGӕ)=)m G!>Ƙ]O8fʱu|rt6Xb+L7Z_ f+Ԝ /ɯ*ffLb*v^;˱isݨ9K~D0?}7W>Vw} nPKus bPKl9META-INF/manifest.xmlMn F9ަDj =$ ő6@X)H;ۈAhky+zX`uiP}F`k0 լjѶN-ןדi(.N,0J=67Z:޶U]+*.Sz]#wnS^tñzA)4.HCݕE'3RJgL6G/q'k^PSE]kj|-" TLa'8 NG\ ͎alⰵ I> +o6ӛ{nR~{rWPKOPKl9^2 ''mimetypePKl9MConfigurations2/statusbar/PKl9'Configurations2/accelerator/current.xmlPKl9Configurations2/floater/PKl9Configurations2/popupmenu/PKl9JConfigurations2/progressbar/PKl9Configurations2/menubar/PKl9Configurations2/toolbar/PKl9Configurations2/images/Bitmaps/PKl9>sy#5 -layout-cachePKl9t2k$wi content.xmlPKl9mr,@3 styles.xmlPKl9Q*M'meta.xmlPKl9v5鸃GH Thumbnails/thumbnail.pngPKl9us b gsettings.xmlPKl9OlMETA-INF/manifest.xmlPK(nkst-2.0.3/devel-docs/Kst2Specs/src/selected_line.svg000644 001750 001750 00000014623 11544160206 022653 0ustar00synthsynth000000 000000 image/svg+xml Selected Line Selection Box appears whenthe mouse is over it, whether selected or not. kst-2.0.3/devel-docs/Kst2Specs/src/PlotAxis.odt000644 001750 001750 00000621150 11544160206 021605 0ustar00synthsynth000000 000000 PKl<^2 ''mimetypeapplication/vnd.oasis.opendocument.textPKlks|ޯ^ڬڋשׂr v @2,$# @2,$# @2,$# @2,$# @2,$# @2,$# @2,$# @2,$# @2,$k X(rI,+ .KQ9̦b:H)_Pz C`Hf.GC?*F 7w9XqC` ~3`W0F ,$c٧~,Ӄ 4}(C+ ],X UE#Ґ^8dXN?V`"0;,h7Zdym۶W#tQQӹhѢyatfee-]4:: v3fL~~ȑ#ׯ2dȞ={Ө<~:GZJ1R ս{߿NN;qP՟{\pkԇ .^MR^z"R9X[ q:ĊǏZ[`9n4`5NEEEXXGr9G@Nu@SQ4n>j۶(Dwk׮ǎ3O}ǻ@3GV;ΚmKSz(C{l` <ɓĒ!ĠAS2+ Ґ^!āB7Xa>XV:8XE=$#jX~ۣhC Y3 {u޽cǎ2eJfffzzCnN:8әtR v3fL~~ȑ#ׯܳgO>}|*BAwCGZJ1wq'=py {`F֭[VV?\_#GkǏ_TTc+*$tݺuBh~X~ۣhYHMB۷$n&\Ƚp3I}BIc #uO3E(JsZnt:qqqǏQU޽ xvB#$w BBBڷombmmm-:vxi=xth*o),HBDFF ~K=l.}w:1Vyy0 hH/K <ɓĒ!ĠA|=lF{!p,"8p6qBq,,,c;6>>>77W4|pZ x0"t8ڵk߾mRSSo߮ O8qΝIII>ʴ6 _Et:9s/---,,̝'99y˖- .ܹsee(((HLLlpw"b ` {gF ,?PeR`vX`*GG#`Q9Lrs(헸,XVsFXk `W,?aop#4N dӏU̎ @2f'=9n9 + UX=N?V`"0;,h7ZޱcG}+--w# ~ =sGqHoꫯk5w۶m?YE=bW\ѨJѧOjJN/СC`X!BqYj=jժhz@`=::{Fnݲ~`W(,?aop`+**J]M)$M+El6Lrfp 7ԇ .^>h K7_-% ca"--W`Q/qӺ\4{9nECz`,,*=X555}tTTTa„Yf>|Xh&kSq&''kUUUMUt:rsseeesׯ_ZZZXX٦2t^zm_YCBMV\\~*QQQ&Mzw].ZxqFFFѕuAT2,?aop#4+z~iC~8K.O>[oU[[M֬YcpלnݺdddL0!..)e ڱ[-9XM{JJJzUW=?gۀU`kׇ;w^zڵ_~yFFFZZZNZ {h}Zh1jԨe˖g.((իJh,?aopiY7p 7PQQaP}lLYӸQ\J KaϭZ["Cc: '2g#VrerAx^*rss͛'VDe*Vfۋ-_ʣ&|5i5s̗^zW-*GE#FlݺM6t/OX+F , N5G9-n4k{xx5k<+B+a]&;֗}Sxg <3wQlI "3K.rpJ"Yov Q'aıc׆~K.]tݻwstPTDo{k9X~ҥ+r7S\.׉'^yE8!TA`ÖӦM{g۵k}o߾?,ߴCfE[^tꫯ&&&nݺUR=/3t:GG?pŃ]#!8 vG Gh]~˗/V\yu}O=0444a6tPAԿD큃47,!D_}[n宻ʕ#GR5ÞA|;?4C{0☖^/yׄ{~y7-;w073Nr˿⋖-]w]; {V̟F䝙fˌȑ#&Mt׻]YA1CEh!0)1?L,C,?'5!V=m# &ǸѤ˙^GW 0WGgބ?C }x˖-1cGX`Q!6lذm۶EDDV]]=a„k꭛)"r<8 h&L1KQ-[mN駁ݻGر(NsѢE ~[XX8o޼m۶ X@3a9Xϟ?szȲk׮1cӿ֯_?dȐ={N3++kҥMQQVGY={\pa쯲| .t_zisͰu!!!NSXQQwKP%&&ԟǙWДص+zž?s>|XGUTTy$)Ν3Fl| {3X!p=֫g{OGEEEx$VUU !"##xv;H J#wU;F A.=ڵkKJJ͙3g6mڤV:;N\\%=X@sB =X-u7=}hYhp@{yݭE&oeب`999+Vԩ-ܒqUW䨙aÆmذWG&M4iҤ>qhTT_ '$:tҥK>hcccx{s@8: S?իW[ptmĉW\qE7n0i@.͛7^zÆ [BBBFFnj-4 uf16 r:6lXz_YY)| @! eÞu뭷_ԩSFƲq?"}#wt 8lGO۷Q>NXU {~AzUÞ4=b,@ C{ֹhxxxFFƌ3 l ` v3:''SNǏ+^|_Ub>0Px^,^~e nӧ:thу XWHd,5Boݺ/袋RSSϟ9sFb8a#w+/U|Ͱ[m.첧zZvm.]?޽xm^91 )"w{Aevvzc .EVyΓUxܕ-)%+>{hB6:Xf\֭CBBN6""""..RR'S%V@lչл˽qwf)" 0D5ܹsrrAEvE#=Υ{[T /hH/2VTTTMMGbUU"22R].ĽްN=ji94O4e+>>tzDKœ*w*=X`uu34kunA7`UVV\rܸq=z袋&Nf͚˪kkkO}oə0aBRR?B!8Q!ĸq?z$C~ njݹlٌ{GuoyƍN:(,,;wǯ꯿ZbEǎMMJJ>|cMMʕ+ uW ҃́1D?}ٳEe]`9yvȐ!mڴp/|РA:ʯχ~w^M6EEE} oUVΝ.7unVw/(8 G#G ԣ=@{L2&;?O?뮻 qqq6m۷mF?w[lYpaΝ+++GAAAbb;C߾}cbbKt:Ԏ9s/--{NEX`YjTy*Ec:l0' `'O/Ru{}w%XBaÆmذW#]BI&M4!{12Uc+#=+F~KOedd|':ʇt,?aΫq[E]l%›a+l0_?#sǎ>\j#XQQQINiѢ͌m9%[יG `Ot06 Z3gDD-D̬޷ 4F&VRTܣjGWWX\y"KOug6p:uJGXT4:S={yIDATաi/Ԥi JKK۶m4]vgΜ^c~,:7qO_(:E mӦ1Kt:?|׷  7C%#clF{n>&l7poU*HQ.z,`*>8 ܁ZuFZh6':~}_~VM/++w޵k;ZU3bQIAߴ*}OݹeHЍFu"BtaΜ9zkll1bDqq;ۥ^ZTTNbuMEQ{С5u.Q&K;ǰf-;]a׮]?ٳgUmmmFFFqqq֭W^]QQq^zeggK+GGv@O9Z9ydӫkʕWX}v!Ě5k&NޣGիWRj LT{IyvwJ~i'~yO3 =V6mF_~;wb̙7x;=&&]v G#׭oW;K>b/kPp'r\_~С… =rrT`,Fy{IgWXͫ:{= !}:h}'jSjwzy葡Q609[n3fLXXXMMƍ[vmHȿµ'O9o:;VO}+}D&H>NOֵ^v^z\.hΜ9999誶vo$VԜ |rygDq&hM~￿gϞ={&$$ٳ}r7zcǏ@~fG'O"wՙو˨YD.kƍӦM;}sECUU՛oٿqƕJ/ZJ,_~Ylً/xIX{'66>ydTT׭[w_޽{ǎ;eʔCɺ U4'hh7Zԃr>%Klڴɝ/vmmڴ9p׮]cƌW^~!CӧOdәth? P'=XZ~FiӦ{XqwѕbԩV]]=uԔ5B0 33nj3G.Y$::I@W-\s\r?//+P=.w&B۷rWJBYm},0zz.5:uѣGΝںu &8Uj;Ms^xao֭[DQQ"66V'طo_ w+>tzDB|)w+VcG#`,ݺu{ԩS߾}]`aXRRRRPP0a„`WX|ggϞ'=9n9=R.hժs=(ݻM7 i7MQ' ͛m۶:_ݻw#<ұcGEQNE,ӟU؃tk`9άKFGGיa׮]cƌ9rbC ٳgO>}9pѣGWZ%?~LLLiiG޽{?''ǝ8zhQXX D``ҿ-"ֶhѢKOOw;/K3gܾ}ڧ:Cl½ .h Ir/&E/|`yRkɫV:|p=܉C {kwoڿR~h7ZјEEEBXmb\\b߾}RᎅiU|nȠ֭[8NmbEEEDDD\\ =YPQQ摨;wN#J) 4ECzv"HBDFFJy=XXK\zexc 3g,Fh7Z s5xړ'OjKJJ RJMƥ!p;X)))Bh/7n\p;oauuuϞ=GꫯoSN}gRvrw_mYXEo{2"44t999XBݻwXBh+CXC^Et:rsseeesׯ_ZZvk-[,\sΕ 111xg!`FۣhFs,]B\EѨeLBC"0;,,9X`*`G#Q9VB c!F$w,F͋ 2tQ`5 ,?aop! @2*B쁳̎ @2(" ` lF{Aѐ^8`~SUV>0 bs:W\aܿYdILLL݅;w#3V7T%>>ꫯ]ԇ__[[;u[otFe`Hh7Z尊Sttܹs/;ӝ:u v48qp^XWݻ՗UPXX\߫{;v)S233:T_UVܹS~}Q@}=tfee-]4:: v3fL~~ȑ#ׯ2dȞ={O>뮻?۷O>&L0,HN,s"+ V'=9nCb{@EiĥX`H:8XE=옃6 ]FV@r3O`{4r- `%LB-TU@9n4&dX`J"Oo3C4~}C @ i콍Of3W11'A014# "8J}~4[r#"," @2,$# @2,$# @2,$# @2,ۻwرcL~!-,,LNN6n@Ӡ%N|@>Ѥ\;wFDDl߾]qݺu۷ꫯٳ(111V0-v`{GUWWO:5%%eȑjJjj233].=dɒh%NlϺ? *{不;&Lp'K3gܾ}/>-Z)--5hɰ9|41z,lݺuBh~ɷad؉g>LVTT$& !:g`Y؉'"##´:tBRCo-XVQQ&PSΝ;g`YXTTTMMGbUU"2225|k!xV^^..l|k!֞xܵyfԩSӦMqAIy4ϟ?rȀR{)/(//w\8Nr`5jkk=R[lYYY}bO?b?CbbbmmwNZ[~~K/-++kԍ,ԢEݻc}Zf͚&^WVVv]w !VX @zÇܹsBÇחܹsn >Bжm3fTTTB{o:<?Ì3If"|aaa=.b!O_UԩSuug}֨G4: ٵk }饗<ةS.Q͛W\V !\ @Rg,HרQ6oެ~)S$&&/v^1/NS^^^~Ywy7[nB̝;O?u'~.]L<8qi~-u^ZW_}M6j'ԙ0r-[ !Μ9;"22Fh"ky233/bbj7؍7޸|zJݹcUW]%:uUf͚N?z'[*~Z: t:BvڹS#E=zw1tnccZly%7MwѾO姟~Bk)^g$w@7,MW^IMMUckgXgڽ{wzzmƌjkk/_޷o-Zi&55u{?裤-[zG {6qiժ(:t?rF^SSܪU+#t:ӯ/r#`(uEk׮* !Gff_~x`!$c@?fP?@HIENDB`PKl<9 .>.>-Pictures/1000000000000320000001D0D0271A33.pngPNG  IHDR  IDATxytU!@VHd7l& lyEpg8!8f@APE&(&8, E!F$$z-ݝx<ݷoW_'yUf  @g,tF @g,tF @g,tF @g,tF @g,tF @g,tF @g,tF @g,tF @g,tf vf΀%6l6}b^Ȉ B*/T 9?Wp@g,UЬ]HCݐ5!  @g]E.ZT^ɴ\JNN 5F., '`+'`J}H52 #`茀e~3f 55 D @g\m*BNV,$d!X:#`5o55 D @g\m*BU-!`茀e~\a HrH~Hr, @g,` :˜XEiWVCZ"\h(6"2Q!L;eM|\a HrH~樑.kq,`!`̜XE03.~@M{D<D!XFb/sH *j$9} d,0L9Wۙorv ṟ&*B۷Z|!X@jFӻロXsP#VCh߾SN:u*""B?'&&?~|K. \zkK,Qҕ"!!wBlٲ%Dv7oݻ <<W#eFׯ_|ݻϟ?ocbb4hжmۮ]ݻqս{[wk׮}%:aaa 6|GNZF w>;w;wNQ^{gȑ?=:y䣏>zĉP>x| +Hb0$(ܶe7/Be _e2b !33[n 4xO>}ͼVMh!Ć \nm߾}j6:lĉӟ*UԨQ/:o_߿\\ܬY9rƍ#Gqqq/yڵkÇ  ?wn-XBRͺh гgaÆ|ϟoРAnnܸ}m;wQF;tdvw_"xoܸѡC;… Ϻpwٲek׮9?{թSgǎ,%''{(9jЀܼw >ڵk,X$ƌsʕ>,**ю;N2šqĉڵ#yČ5WWznذ}„ /ԉ(ڵk\ɓ<Ν;>/ԯZ9F7m4tz3rHJ*-X $$dǏW333_}UZgn8p`ҥ jٲ'jj}ڵkWF @]6a„+Vԭ[7cI,[Lѯ_?}5jdw:OK.Ǐ/**zg{nҤI͚5~J6~GBx~|C; YHIΚ2@7n[o6޼y4ܹSѦM?;k֬5knݺUmZZO?4uT6ģG}T۸}v!D=?W頞kO7nܸYf)K%%%ٳB5k9s!&O/\J*<֭['O>}3:t0k,gΜBm =ztp$7&fWwyޒ5BB̟?EW\_Z~BVV… OҫW{?*"##|]aKLVZZZ`0yQFGx(!wWcB4o\jn?/^|y/Rhƍ>|%ŋJg_P8ʫϜ93::zÆ k=!KX8p:$ѣG cFfX(W%QСC|B^ӕa3&`  յk{lgU !.]ZXX6viVr:vXZZژ1c뮊(pQ`]/nܸ222;vرիWWZm[j5d+.]㏷mv޼yytX;1k늋۱cG&Mڴi3sC;wnGn޼yhhr,/I,?5jԺuԣG;v,55u֍7޼yO$/zK6nܸjժ3g <8>>>22uSNϟ;wnFF˝\O} m6Gccc׭[bŊ_}}Glf/ov rEWfR:xy'5L(+Z:HՁ)u؈Ɂ,`C` IH xbPB$gtF zH1@îwX膱XFG%#NB=@Qjs, 4m"WQA!BĚG7y QEk3( 3aBOytX^#g?,tFOytXY L{QS 5g^OytXQ@5 1?`e0*97k HrH~Hra30`MwLyf6؇usg۔}]7~!rǛw@pCݬtO`茀yp+ `k$G$GGP9̚"`AmrA I2Ak5 gڀeM@bIQ`Me\ h9^NLtXJYx@$GG$gGL4I2s~gE÷)\~˞EWJ>妜y9l.BLN0"TJQ@(Ih2 `5okdXcCLL3sc!@~ܭ4TyA6yEO ZE͎xVb!`ϼG2?k.0 $9 $?j$9k3fPw8g[i!EYsn@((T  dX,(2g"`璣@@xʟ`-( Y@,-CH0HA9h V\!9f|w`t_egk o-T{۲1>틇{.BmZzP%rsD= a8D,'ّe~\a HrH~ԨNY 0rNDn iWr!*B:M8)uO``-̀|HWXgB$GGtU U:hX E#``x:f bqsTUʳ_P*BP%`P,5}%*vx@ /P(@[X_#9 $9 $?j$Uއl5PkժUڲl+mw^-zxݫdO0`8uw=J=6n]|OrG<]ۏ1}ϝ=꒗m!wS;\3dv̞^>Zh= M=l`جv~7ʹ/~mt4oTN:u믿-{fσINONiQ- $9 $?j$'@ }oW^*[II׃ZJ×(ڨ~Ulr޾^M|9;4:nr`rڻoS (֧nhh?'*<2_e{OZn?>.}Ǚ˽p+T{]We[n}^{_hKFUad܍.8;s]}6r_4_f8es)77`޽{)z tϞ=)))6-77W_m޼p,0K w.]_~9$[999cƌ)؄bǎ7nѣbڵ]vݹsg˖-u>4ӕ;9 S'+BJQZ?ܺuk̘1Sҕ;v=z4Tc}(($.?VTTֿ_֭[wk wm۶ɟ44jԨ>QQQ~l5k;v6vI}N yF.-Z8qDaaa*U .ԭ[[n'l.vu7P\A>g̘ ,%8röY))U,"""$$$77WXPP"HN./Q >M,yθ7[pb!ԿlܸqݺuQQQZ߿~*U bcc٬|^@_u'%%-^~8z={>{}kpQQQ%%%ʷFFF*NBNHrH~H#/_Ueneށo>Cw}RÇ>o :dl!DBB./y<9\*<''G-׿]\\|ϟ?W^999?3w]ZZzmcffs>k :F LM_ _իWoٲeرmڴVZJbbbڷon޼y˖-+'8xBo"<5 çxgozg}6w{C{l޼y+W,o߾ 6LKK6o(uiodpѧOwHQrŋ{UZ6n.t Vյtrʺ\]ѫWof̙cǎ1b… wվ}{]6nLKIɏI.E(c]ƍv٣Re.5@m+..nÆ ev۸qc͚5F-U րƎѣGǍ7` a\rHrH~ޔG VJ׀5~;>۶myPaaΝ;{:?^`!>]%!/?vVllG}t , ]vdddAAK,Y$&&&0ěo}K>U?_*X?ɓJ[fM߾})es@@l2U˞ٳgw֭ZjBjժu-55ɓ>ރL:,Q"` vP/9IƏ?-W<7 $9 $?j$9POs Ж@H>o$VIIɴiVX@#NpO3Vffȑ#4h0jԨ_~E˗z_]<55Wv{NN# ֢E.]믿Ο?ܹs ,ovϟ?_~~Сl 0y;6 ֺuRSSG}g\_߿?BtmժUj}MY)&%G$Gg"I[ mT=c6>l0mۧc!]o"o+<<<66VRVƍWTwT>}Z1o+**ʹN:k׮0avzmժUt",HrH~& ] rss###[j޵W^/udU6vիW5jxDŅ/{ Vv7nݺUA7֜5 $9 $?p | X{͛=w+** u0@0k|TɊ 5bĈ2ӕJ*III 5;gy˞F}0kkd=-`ݻ7@g@fshXHɷbŊ7|33 $9 $?j$9kȷ%2eʐ!C1Pa ֋/xҥ5knzٲeN:UokȐ!qqq߸qoݷoߟeϴ4=Xsn@((Y V.];vj7lؠ0@9p4U9J*=ӵk8pĉu.]4u%K!Vb]ƇܬP Q Q# i'̬Y B͛7_dIhhhrrիWի} ̀03噃o3X_~eDDDrr[O:tЭjժ>nc0f-[ֿsNW'|RA֜5 $9 $?j{MQ LsVF-[v=xSV- m>Kb4:l Ԩ={UT)@J((-6*|;+99 | X<@`,o#,HrH~Hr,O?=w\>0VVl6f^ /|ŋׯoر@9ŷk !{ܹ!!իըQc۶m5f IɏIΚ2 zǖ.]F+!DݺujԨ{WrI)-`}K,Ѧ+!Dbb6] !FջwoFC0"xbfuڵr ܬP Q F24o+;;ۛnvŋ~If5ҟ~n\C06OףG;cŞ1"33s֭Z9lb[i+/nJUa[қ;ಛYGuO` <?| nϙ3O?MJJcx[3fgϞ+zIDATWԞɞqɓ'=Sz&(geq*5`EFFX",,l֭?x\\\Z5kvGGGoB|0|fB$GG$g]ݺu/_>y/|7Nxx'|2p@ I1cJ|{رShXXX֭_|cǎ9RA`i01j;V*BqOku͎x)&\E2tF2?k.0 $9 $?j$9k` PlblwD ٸ)*Br*B+"`茀e~\a HrH~H*Y Xc\m*B辊PY?tqe_Eb!fXgB$GG$gT< @g\m*BY V{U#``NF2 YsP Q YF&u EЙnڵ\r\\܈#222=(Od_msϥ{;v(,,Y={4hY" [*2=9-}7N:uTDDNLL<~ӗ.]&!˗/YDIWBwyGe˖ ֓O>Yvmm}' zز @@Ff>Dػwo7n!tRsm6v]17 nxyC-xJq#Y$!ehϞ,IHiӳfpx(%`ґN_jlңG8]kƌΟrȃI52I~<'{ln ҫWڵk/[s7XLfmڵYYYk֬ @<"`?~ܡE-_utttE R,ǻӉCk׮M0aŊu  &55 $E;>3nܸz+!!AmyfiiilR,ƍ7k֬ƍ%%%AAasխIvIII/^Ԧ+~駞z'`,]*BZ}aþ[!ÇaaaGΘ"uJKK |&9X(?k.0 $9 $?j$9k3̹ڎUca3C"d @g, ;Ϛ7 IɏIΚ"`|g,sP`}]*B+"`茀e~\a HrH~Hr,Ph(6oGj9 `mF<Q!LUmT=ls0:V?X:#`5o55 D @g\m*BUaЫTLb#`5o55 D @g\m*BNY6qb!X:#`5o55 D @g\m*BUXgB$GG$g{bv5*i wmT=ls0:P@~,Ϛ7 IɏIΚ"`tAЙ9W۱PX:#`5o55 D H͈k0j;V`2"4XgB$GG$gtFЙ9W۱a!tfڀeM|\a HrH~HrȦCuߢ$8 x g,`9W۱a!tF2?io@A$GG$gtFЙ9W۱a!tF2?k.0 $9 $?j$9k3̹ڎUmUE|@((Y iӦ{)`m۶7(`vׯ_OJJڿXXؕ+W=f9vu!n$7nw%7 n{C񤤤 c[qqqbbbzzr7.....gɿ_)999C'HrH~Hr:H|'۷e˖^m?Θ1cڵ!!` 2*PǏ;h"??ҤI+WT!HNݾ]vիWϹr?еk׊/ryY9Q+뮠08 ! $9 $?j$9kH,"""Zh!w2b L N91aa8D3YsP Q Q#Y@,` :+y28'knHIɏI}`茀3Xk*L:| $-'=3X:3) QX ?}9@q@g,tF @g,tF @g,tF @g,{(&4hPCCCgϞ>gϞx͖ꫯ6o\yn?x\0w};3^Zw_4htU-iӦ-Zݣ@effnڴŋ}ҥ!jh 1k֬3g΄OOP02!DjJKKڷoe5kbcc !*`"&LSΠAz]jU!D͚5Ϟ=Mըl9+֭[m6G*;w'hڴʕ+oݺ(5. 3g*˗/vTXUTTԤI!Ch{չsgY@ iӦļYvmm}' 7U^@˗ׯ_{Q }ZÇ-X@j#_ ʿ %%%JKZZbԨQj(Sh(jT9Pxy!DnݼV+˄ H(-͟?ذa=zP[ Ծ}l] \{B<-:rݻϜ9ӻwݻw}QpuaՕ+W~gϞ]TT`L(**J= R>葑ڵk,XmjT6@~]vM0C \.]Zĉmۦ޺u+%%ECkƍCݳgό3l6ۇ~8xb D2 :|F A4W^նq^n*33355믿vXMը;)P~~I.\]sS9BCC#""Ǜ'عsBʣ믓^~v%''_>,,lsUX@\݄Ç_p~jrsٳT{wT[*Wv]6a„+Vԭ[!oFe)O߿k׮z9?vJʩ?D 6<}tiicbbUFQO*))8pro߾o3}ڴi_#))UVsQyS5*@,;ҕ50aB5Nc[bbo-{+W4֫WE-Zh޼yƍ”WwDw=#A„6M>쩧:p@۶mW^\7Vl$++f͚B*U={N:/d۶m{!ĵkתW8qEB*U 'O|ر͛7 !f͛7G=|p%]9 5jo޼ԨQC+!D||zEEEԔ͛7*OWӕy汱BmBTZ^+0(O J*= }t۴i-ZP'Ntiٮ\XW_w?~… }7W@*Cwl.]jРAAAo1eG}GN:UNW:挏wn`ivSq{嗩۷o߲erw͚5=ϝ;O4mtʕn[nuxVZuyС5ԩӽ{w?ݺuq1_~ݏg}VQNƍ3gnsĉΜ93s̙3gm[TTԤI!Ch{չsRm;srr<诿zGFFj_qǎӦMsfQQQ͛mܵkWϞ=5fH<ԩS!!!Bŋ]|VZvViiKF5k֬r 2sRm_!>3m+Plv###۶mW >|֭qqqW`BHHH||ǀ7yVqᑑrB$%%3UVaaaw߶mU\\pƍgϞuhVVk-Zԇ7W@B~=w>ܴir۶mmڴ9x'3X]*0??_<-:rݻϜ9ӻwݻwkڷoߖ-[z+WԩS \>?mڴnݺӧOWf<^}s}i׮bȑk׾뮻ئfRn3gC`XQQQ)ZEEEBHKV:qDBm۶MMMuVJJq׮]% QTTzjΚ6m\Qzj7fȦTh3,P>6M9+##cen}''Nq'VÆ sss2rgL#!DhhhDD2BܹS?iҤ z8͛_>hР2{ׯRJ7nP[W@6Coܸ%rrr SN !Ֆ!C4lذM6}Qo޼#vXTT:fgg[O?tbb{H, .h333;wV6lƍʿY111ժUS߿׮]ճi\zիrʻ;(saaakV[W@999oСCn0`o~"++kΜ9U̙s_]yOSlTMVqoM6#eVvx!a>[nVߏܹr͚5+ZygYNLq!uV`zz!Cx K.{CCC\VfHVL >FmLqKy3fԪU+???'''###..VZEGGLJxdANb u3X߼ѨiJ_'b RLDi|)Ű R\EU1˂\%r X ˰10;,}|~ÂH1m) Â|2㌥FÕg}3 3Xag!>]fG2n ÂH1m) ÂHq d4X'uv d4XzaDiH1m/Dh$]= l$gh$"?)b RLK)dŎ <=+z2u"0;,h?O1,b _J1,W`i R,+t^4Xh.Bt`~E`v4X`Eݤ`Bx_sK)b RLK)*,HD >Ӊ}4۱tPJؑ 1X\@`H.Btz`ϴb#!f.BKҋ?)b RLK)*,h$cgEW`qh64X`#~bX) "ŴAbX)GKO",i..r/|/Y/<=ϰX(Oa O`)YO=4Ubq|iυ/DiH1m/))~` @2v4׷s]̎ @2,S "ŴA6ȗR "U4X`{kHiL`ٳ_~ÇOKKKMM=vX/p_ڵk6j+**2`R ivؑO{-6lXǎ>%gϞ;V:gΜ)S\rg4iE#~bX) "ŴAbX) 2 B#FHJJJHHPm6--m}ٳWX~ٽ{o}/1()`[ɓw۷غ+!DBBBxxx@)f)v6>8qDƍmwݱcϝ;י".\U:~3;4_"T_.B]h5kvرJ*;wN:]tꫯ*P\\]ʕ+ 9}8p`ɟ~i>}֭[;~>g=߼V^^+z_/Z( 000==cǎk˾DiH1m) ÂHq)Z`AA"<BqR)`= ,ʪW}ڵkϙ3:V5""" w4r&ЕoJJJB8p`ff"99:wE\E#3Eկ_ ZUu~iZ}݌ Jw7o.**2ev ?ݫIOOꫯ,X`gGx !˗TҦMtڿ?x]zj"?)b RLK) 2y3fԪU+???'''###..VZEGGLJ!Vz\2)))...>>QF[n]& y,!DΝ?w%ۗo[oe\`]uײs]K>NSh?O1,b _J1,WiY^F ma|3ѣÝɡCZjei0'S"lݺKݕEc@c#Kap+S!Kb HoTz5ڵk^?)b RLK)*- i*}$znH b!K/ÂH1m) ÂHq d4XV͵˛={utrfKNN>uTppgϞ]Z5!ݻ;vEpǎ5 `ȑG`^#~bX) "ŴAbX)r`͛7綾^*! TR@P)?>nݺ/%Kw}+Vy`њ?OCcx>Xzz,=zgϞ4iRFFFf$'S "ŴA6ȗR "UUZppp>}铗Ӏ<3LM*w>C'N4iDh:g8CH_ѣG֪U~iqƽ}{q,`]sСCNN򿊋4^PS "ŴA6ȗR "U+VDFF8nXRRR`a<^n] $\q+q׆K֭[nݺ͛7wtwЯF=rȗ_~J*jժf}<{˘<3j֬Yݺu.\eo5n^#~bX) "ŴAbX)`l1bDVV֝w_vMVppKQjՅ ׭[jݺmۤT:80`ժUW_hG6nf}Ecg ?FBղe˃c G/S~=3.rYȑ#7md;ҷoC_Hhm`ժU}ݭ[_KS "ŴA6ȗR "Ur'!!A&z嗝|o>WӲsΟyXXK׾E˚yrE)**2a.B`EةS>rʎ?tPMbZ`h"(,$$wx5- ւ jժnٲ3nju`^&7s=bX) "ŴAbX)`edd<6l;ԩ#رXSN3gGݺu_?gj05󅅅}ٲe֬Y?iȐ!Cmݺ9o`]e{?~ժUڵ{Wo͛vڗZ{YCsW%% Og :t̘1;vUpϞ=ӧOQb}bccDQ k۷>۠A o5Xc !XLn[|y͚5ߺu_~ss;vHHHx'{E 6cǎvG}tʔ)M4IHH?۟>}ZL<#` :499^ʚ:uڵkի+,,1bDRRRBBz$%%m۶iii n޼ĉ'NXr-[?ެY .L2EL x)- #<>NMMݲeo馔VZ͛7ʕ+.\nɓ'SSS޽۷o/UK,YhQʕ/cbb^{5!֭[]>\ڤY=/ÂH1m) ÂHq44idgΜ2eի֭|WNZfm۶oV۷t|Gn6!D@.,O HbJ*լY3,,,//oŋ/ѣ_|Q +_!ľ}{wQȵkׄ:t0|EQ:4aۺsiXs[Nw\gڴi6zg3/c@ӦM3ɔ聍awv1}#g|AA_Ql*w}feP/Tru5Y@LP#q&͇K=}%Z,0'_YyIv.ʗ\RaA6RaAJ%BogJn5z3Xfyz ٺ+W,{vz9!#/]):O` NV4X>UK/zh)=~bX) ÂHq d4X~ͭ5K,YzC]VZ[n%55AAVA)ocOf,B!DffO8a;rǏ/_UVK.mժȢѣG{qĉ_EEE999w\)LEKR5jZP'o`DiH1m/D4X/^vZO9a#;_t)**JP7pIlue HﱴX,F(JnnnAA [;U%%g',T,=zlܸuC 4*gEܫW/ wj<4X=3fG|ig[{<Ű RLK)*-aZ֊x/^p'L zi֭[gZ㎙3g֩SGQ[+6ժU{ꩧ !.\н{GڞV^{|+E]~d1g !4h7L4IzʕC IDAT+/[,//ĉ͚5:uıxk}݆ ھ\`֭[+V۷q˖-k۶Ax-g"##l_^|yBqƩݕ*::J*n[S "ŴA6ȗR "UZ,EQmǎ{jժ͘13\+..駟.((v?rJ!̙3Uf̙3r =߲eK^*UdZɫWVo֠:w\BBMYAa]={\zufE馛z˗ۺe˖i0 _BlڴiΝM6mڴiժUw_3X` Lr˱޽{Ϝ9sذa۷7awAyaA6RaA>b#=E~?xz 3;ҋ`+0!kT_~ȑ/^ԣ;Xew/XUPPx6m$''_tIz}Ye|o믟;wNbY" ѣG~8w\DDC=f͚={Je#DiH1m/D:(_|+lذv7߼"##E3X-[ 6=GB;V#F6R/e̙3x !ԩ3nܸ1cT^]_",770Z.֩SVZϟ1b[oUR%vZ.5۶mi߾;su#3gn4X,ݻw_ruN<O9sFG<Ű RLDi|)Ű R\mbbb^x4nܸB} sQFٳg^Æ 'NaÆ7|SJ}/˦~iΜ9NAA 7v ˆϼӟ^#GQtiT5z`N:6XB]kfX,cG<Ű RLDi|)Ű Lؑgz/,Ox+=g|tt",ϼc!?B(V ^?)b RLK)*,bY7Љ"*7E`v4XڳgO~z1_{DƦG<Ű RLDi|)Ű R\e"ܱcG^k׮رΝ;[hSLyWWn@}z+,a>S*,,1bDRR] !RRRڶmxO?+T^2.?855>=-"{V탩b$<> <x0}taKq"&&ƙ Bh'Y}ԩ#{bt|)Ű RLDi|)Ű OZ^^^JJT\~# VDDj-q@)N ^[n}С@|]v/+`XE(o .;w`VV]vz$FJJJB8p`ff"993c V~6lj*V֭j}w322<1@-lB}#b RLK)*S4X_|zC,!DzzW_}`UB˗9211Q}!DeGbb͛g̘QV8Zjb;n:իWz[neo' fXrAQ,]% g`YtW8K/D}w_?bX) "ŴAbX)B8wKhPkB*.BTm.BF m pP/:ξ[=\(kwGJO4xK) Â|2E#=O,ξ8VRw @?~g-˰>]0 P,h?O1,b _J1,W`HF\Zł-t"ș³`N");<,* ?qkqkeڹ9b _J1,W`A.rRϣ|\9\,J\ trk!$Aky?dG0?[3?m䢣xf@z,ı2{\<DiH1m/Dh$pt"4̀; <D8c\"ŴA6ȗR "U4X0u eSYAS),uO.B3c_!x"Z!`\lK<= G4}Di|)Ű R\E3XFx)O.BoB1jX,=/.XBvK$7%-K/jw~4~bX) ÂHq ޅ fǭG^Oᬽb;@:vJ@cid8bHpހ5Xza) BXVX/G)b _J1,W}lY |{䏫XW@X. r!1.r!`4XzaR=C~4~bX) ÂHq H=ڨ]Z73,&|Ob>9;Vʳ}? d~`ᘃvm$ByJrs/mG1gھtFYc]Ӽ.Ű RLK)*>(P=T19hJ,wH`дC/h*l@W# Fڨ9xp %(rK,$w"7jx'E5?)Rl[ ]X!CSXaty7|gޱ2Jq3=}WÂHq8K٦=T1%kn^Լ 3sz/p L ٚiIKE1NN ʼO 7s>4~W# gPey>ӳJ̢-X^Ҟ={O^F Œs:~ _e^j\'LfQﱹJD8V`;v+===!!Avڴ;whh"74[ɓw۷{jT^|lذa|'7nl;{;?~ܹИK]RaA6RaA>"=ڋoӰw^!D!K <&끍%L6Mc;fg̼cL6$S6F~@˫1ۥ_ Vʕrss充Ĝ>}RnX) "ŴA6ȗR >**UTz^`EDDX V+l?NAƤ8rcR|? A|ј!gzGx8ďFCt^`5l077D-X^`o߾ܹsڵРJJJB8p`ff"993c]M6ѣ… ms;+vD^` !>󔔔[Ӈ _{zhyw%xkժyzPy}`6^h$ @2,h$ @2,h$˓?!KߚܹH?b:-skϞ=>|xZZZjjc .qF3g1vޝfmdMGQ r-Æ ;}:p_ڵk6j+**2iBɓ'רQ:.;մG5g}vF5_R+WVJtN>=v؁u֭W^[lPjcZ͛w=<:tx'];ܜ?m,H,gZ;vիWzzzBBbڵiii;wlѢawnZlGzf͚:Unn)S^}ի_tI[wJɚθqVZչs;vtM{iРadٳ}IJJjժΝ_64{/Eb5mN_~0ag͚uwۗ5(Wr&MM6ݶmaL'33G&Lxg,('N|嗗,Yr=Tj~:ÇqG}pڵ=zX۷GEEVJ\*&1( 7ng3l0JI? !njL)S9sƥ8ǬV R3|sQO׫WϰRRXXm6#UV5iw߶mۢesܹH8p <}a·~O*~R)sXM[)(,,lٲeFEQFѩS'JIN݅wuWQQzdѢEB)SVMtUV`k֬1MbcPn*&+E_]t1Ԗ-[|:+.E# ~Q… Bm+\Vѣy6;_JtN:»`ZJ\$VVJ.]*h׮J)ժU3ga$N'33322RѧO .ر#::駟uHT8O /PJ\&1(7ZJ /qPۙ7K]xq֬Y3!!!.Ft?NJ9CR)sݻb۷/%e:EEEz:t; ;h$VV!GѲenmRz .8uLguBTZYfGPDJ5Sn]!0@997K3Il ʍR,K铓5j_3III.K%q:~{u2>l}Uݻ#ܜάYW`_JjJ3z&u ޵kGJь1[ouROgQF8Gbp5w3j(!?}BzQJ)ms)OƠh)UL.22+QmРGJXBh_f "o:k֬sW;dEQCկ__Ro߾$j;UJFn5m4@b>P/$y73??jժ^~^ʝlذQFӦMX,B{#iO?TjE9sgBzNV) s)OƠh)UL.... u_UѵkWqF``zkw2sRV˺SJ֏F駟 !BCC=UJt~oHb)?մ<ի*%ܰa~p4OgƍW\~}hhb!;?C۷rʡ~͛խRRޟ6ARzr2++޽{?JEFF֮]ۥfKq{:/_뮻N>RR~4ʕ+{رC8__J\WٟT%***00Ѓiii_,"iFqۑzKhj~?C!DZZK:Ik^$!āfff !=Rŋ׮]ٳKtrrrF=wܘ7n_JFQ.]xiH)_/%G#RЭ['N؎(RXXذaCOf^:55՝"RJiΙ3g#-/_aU˛6mZʕNRKJfr 61b޽{k{.\sNÇgggۿd֬Y {:>vX'xvs)aÆ/RRF)|u,\$VsQo/ڎ:uJ1i$=Jk~z!Ç)Ra)]{}ݶ#'y睮ra?c !/^NtKy$6FKb~}Yxx={/7l7Qjɒ%Bׯ+o>!DDDļy󊊊V~X~} tKBhQKt΍7zb'99e˖RqstRddd|| >Tʰ4 sXRzhyիf{?ג$2l.TJڵ+,,,!!A-^\\SO7Ir),,۝:K1%%6eKQ;w&%%5ONNou*FGGqY1ctMI&III3gμ|;svڇ~8p@ՓO>tRm+,t_PWk:SJ׹3&::bnzӧO_+eo=],]"Xֹsmv=z t*e̯Y~~~*UܥRzOo8p`֭~ 4ȝ5V37mӦMm۶ҥGɿ,۷lٲZjիu&)Eh$]F @2,h$ @2,h$ @2,hHйs`bXի׬Yf͚6j(44bc45KMM6qD!Ĝ9s:uoڴI;>رc&MU۹s9sTmݻwX,5jwJ(1ǎk֬ 88vN:駟&L`[}EK߲eˣ>ںug}v!!Y@:;IDAT!.QdӦMw}СC:td!ҥK-KmΏ=ڿ fV(!!E HMMMMMm޼bSN^^KIUZNСÖ-[#vzGիW4i /ݹsgEQΝ;?^Q;S۪lԨQVVuѶ'8RJ9H}]!DDD˗/><..N}^/c^sss׮]ʙJeРABɓ'ڵvl_֭[wذa.\2dȑ#~-˞… ###Ճ?q\ !\iBpjSQڵ?VvmfoV= ַoϞ=[si]tB1>8q矷Rq:jժ !Tb;rU#-w1jԨN:w}%:u*((N:&8Vz.oŋK_BGR2eJ},rtE@wy'%%E]z9gΜT_}Ujj1cߟxZ LII̴_|3糧oy*U2dHvvv۶m|Ɍ SNb.Z7lҤ3O6x.&,СCNvW*.Khx%!ի=ɓ]zUvvѣGuÇ9,ާ`ŊB,O?PRZ? .jrssOnٲc .rB^쐄999iii}]RR /,ɸD xáIENDB`PKl<}̸r]r]-Pictures/10000000000003200000023FECFC66BD.pngPNG  IHDR ?* IDATxy|T3c["1  % E&j1"UE6QpuaUhE0l" *$`%!L3d&3?.9o={MhOX#`h1X#`h1ƌv1k,d2FaGMbbbF("lԨ?\TT\S8pSNJ6_e˖-[$P!'Op…۟?^QI¯VVVgP{ ??{ ګ7J1_%%%n@@dR͜9d2EGG{~Ν;O4i̙~~~bB{ׯ_3gرc͛׽{G}4//OQPPiӦѣGgϞݻw```ΝLmܸqȑݺukҤɲeˬ6n8`'|rҤI#FXti\\3߫Uնm6p@Q]xq„ O<رc۶m3Ϩ?j|AblwuYf{ʄwu{キAfYQC^xPIqq(bĈٳGq-$%%>}_B=۳fRl2!{ァzg|{Uڕ+Wk^EQrrr5jo'u.I:t'&O\O *//f944رcB٥YrY+,6m*tR"`@_(͛ׯ_k׮aÆ9͛7w}SL2dF*L&SIIɏ?hX=:yd\կ_… xzYI&^͠kjs(QQQև+k7e~i4hРo6444--MݯN++ꫯmkݺg>;sС!zPes r0*bРAB˞~IX2?72b_3h |ʕQFYm߾bҤIGMII?_ݿYYٖ-[׿>]B/B]dO'?~/\xR%먋*L{n׮]jjj׮]/^bŊ9sK.SN ]|)S-[L>`x_M^ԬYW^yʕ+wy 0d+ ,{B?<^eeeAAAs=WVVf}4''硇 [Y5k6{쯿Z w}Ąl])))jՊڳgOo߾&M$&&^pa̜7o"$$d׮]{˖-+))9Onn#n喀֭[^ZmS%--C{ꩧrssUU^jpjժ .X6~ &1^+--U%//\vmhhիodG6t]w8qB`,FDV,eF x7lڴI{e7vmj"44433^z `hK {02m4` 1uA3X}۷/@t&h[m٫tt H!tm7 o"FfTGrHfTG+ӕ` xɯ `yWRN}ʘ?Va@h;E@fN6a !mdFu$GdFu;ԫӕ` +n<Й\a.Bc~q"IYGhf I2q>tB:4ȌHɌLM' xO\Ypqʠtt^"ОWL\!mdFu$GdfO1f6 >kej˭*df:ЊL\EdMX:|Q5g.B zh㍨(|:j+On,`*_&h4X Xyt`8\:,ERtB:AɌHMt坘@:D+oG@"D+ߠ[3(+V0Lkמ3gN=|{qqoGgiܸ3o 4 EQƌu6m!v1p ?ʷիhӦM-ZB9rd.]/:uTXypw+Hz7'N}޽{[v.^xڴiwڵ4hƍ{ܺuC=ԢEcǎL&g `$ĕ 4:t^~=))uֽz?nܸӧ;W\ٴi}ˋ0jxmP2:@2:CIWGqyи>|sssvi%%%F@+Q;Me!DLL!uTJJGFF !y빮;v!ڵkW~}m ,ъttXtggg?~\]nmÆ ի*SO-_\OرW_jժ1 y,/rvZ:urѴ￿QFgϞup¾}~BYf=M6}뭷gQ*xEQ,` 6`C uJav8XQQQBJGi&$$y_>dȐ?\c=\΂,0q%?",--U7*\F*sM7}G 4Pnݺ|F Xk:@^nEu +,,L(//?ZVV&<ݻw8p`rrrHH>tTj6 *<hWE@V ,HFQ@+ӕacL`!'[pw+Bm˭95Ax;E"thՑH]nʇ{` )AL&eۘ? `y3X*wgX'Us X0qA!C̨伷@&OW[T3X|!ZWИ_$ATx!f 9L\ "thՑRy5!su9fnǽCa4, ef:Xn/B!@vD+˭A!$D̨-OP1Ȍ_Ca PS\lG*df: A!@L\7`L7nT8{gX;PA62:sw,WjG6On,&phTA"* A!jD+Eih#3#0Aҕ;c(`XnhF5A@sm .B6xT3>>6lX@R,<@.BEQ֬Yӹs؎;sΝ;UFFٳ;t0tЯ\ۡhՑ\a:PRe̘1[nmӦbǎ .?~|ٳѣG~n2x= OZb{キ}v5] !z/O8{ڵ3'~k׮m۶gϞ/x7C36lؠA#GL&ˆ-[۷z>ܣGEQvնm[W@! Z<kƍ 6)*444..v|~ުF#Po.HWtX[lBԩ"%%f͚u]6#ogy Ѕk޽Bf͚B߿۳֬Y#x駫oD̨Νkyc-~} Ӌܯ]-?Z^=!ĩSaݺufϯvO=ԁ\?166v„ wu#0)b`C IÆ$azŻ_|A VΝ;\RmxzRF3gΨ[RRbB88Cn݄j?q .,YVZk֬qfp /P)#'PGdFudy0t3ɓ'f>K?~6Lf3.YdҤIwգGC{nA!Jv漾0,,Lݨ~eeeB`gBtfn PVVk3Ve VxxYBPC?⫯d - 9O U077ŋ5ʨ|Q]DeY Q91n+̴?%ܹΝ;gVZ-<:~ !:dH{B8po&o5ALWTT԰a͛Y/--lԨ- eee'O뮻=9995Wӧ-;U+W|'^z饿@!oA ^E( IJJڳgϾ}]6//W_}CBBBV"""fΜyܹKZ]QO8_Ct% 2eJppi,J'Yf7n۶m.]'g$G̨gT{1_~~~F5j-ZhѢEM&Sbbbbb{F` ,5K 5XAty0` .{4F}0q0}hфnNdFu ,uJ0q:x0h3xID+@Ba@h;ED+@ZI&l՜q˭#ҡFfTI++ $3c(NM6{w ^ĩ5bw S]&###=0&Ybvi 0`@߾}tTLq0&&s*`?~iii6lHHH8k֬Y@vD+r*`[ѠAO?t}y_]ch#3ca{ Ɍ߿-7j(CFy @\ X/… ˛4i$PKVԚ|Νcǎ=sL:u.]:|pO:uѢE"* /Њwy'55>Bt}Ս5yMlly0qUK+L6 g>XBƍݻwƌ> 9mdfMҕq 䍨8u0::zuuh@,PCN+FV$dХH`h>]h%HWc܀eSY1q<5gܖ@[4̗cy/+_*:Qh~rի_|E?t᥷`E X=ٳgGq8fhE>N۶m[@@[nk߹sgtĬs'-ZTyݻwk1p [n@fNu6lذ^zr";;;::%%%YYYf~P܂.>}3tRӦM ۡj.B''z4.ڵk=z8tGy䣏>RX!Z }n`^:w܂ Ӌ ŋk8,Kg8 IDATp˭H倵}Θ1#:::888$$}~c1>62:D+֨|Qcǎ7i2n&mFN *\~ʕj1 \^5~-[?>((H+gXx)wп… :uˋ/\ h޼޽{oV GV,]o~'O޷o+ޅ>A^%x뭷~W/sMh#3WGV+#3c(^skPFCཌ,,dCn}ʟAz .4Ɲ 5Z @?&t {n<6RӼ:܂A[ȌKQ{{Q>|رg}%M\E\XK.=zc,{ƍ2ĕpy|ƍg͚5|:uXo\w݂.B@/, !5j4a%%%sZ`h8\XM6SVVԮ][!A\`(.z衇y .!fwǻax0"mdVʓ1g w !BCCKJJmڴYp͸&s'xbذa;vPu={ |p if~޽eeeL.·~ԩS'[Ιt%(--U7쏪^:rdKaYnEu$GdFu c=V~U=,,L(//XeeeBޮ(GUybT3XAAAϜy{xxzydؚ5krrrfΜXwj;SpBǯ1gϞuy͚59ҿ|p۶me˖W\S~&7Vg~ /AZ pVF.6m8 gfdddff,!DΝ+{l_ ={Va.{ݪDضmۡC*+--uqB:t3>>8qG?:P!˽Cx)SBBBwu~6KKKm־}vYv;vL]h%,Hu$GdFu ũEl|r,BBBٳo>k׮{WoЪU+sZjr @+._J͝9sÇ_xڵkΟd„ OLLܺuzk]vM:u={$55Um۶"dzh\bvp2d6; vZc6W^rJٳg?ogԩ+V8q믿lp i \>]n>:u_YYܹs~p GV,{?*gϞ&)..nƍB~M>]ap rW[ްaÁSSSհ6`C Ց1GDDoロh@@u`F0kEu$GdFu ũTyfofoȐ!gn׮@0qƩlٲe˖ !BBBL>=**  SkM&SZ~ɓ'{`XF!ǣc4N`if֭8.{jr*`͛7tx8Eqm[:ނɌ Vr+1,@g\cf:!HB.B"Zo#`r+0OFĕ+o@2: !;ødqp3V\,I-'7fA@!V`d,@{,FxuuɌ 3X6& `5ŽC6 LG! "d5A@eXˈV"tdnQӕՁ@r: ,G+X@ՈV.B8hFy0` P)zDTh f m{*{u1f7!&ДA" -f;7`L70eHL\Y;PAm 'X=AIɌFɍ;b ,˭cf: +ct. ZtAoҪyIt9ڠ$GdFu , d@ @m0q AHoEHK.BEQ֬Yӹs؎;sΝο|ʕ111aaaݺu۴iW|C6JAIɌ>3X3&55u֭mڴBر#>>~…Ǐ HMMUXRR{ݻwO4in}86tGO+V{WVӕw/ĉSg̘qUV}… o6!ҥK?Q'@~:4]~aÆ 48rlSaaaDDD˖-`ܹs:to4ibٙߥKg"]^G5G` ƍlRThhh\\܁>ׯOJJNWB&M̚5Kq!wzQgHWCڲe"&&PN)))0fݻw`pe ]tX{B4kPTTb>cƌPB-Zh3Jgܹ,mP@2:.k׮egg !"""֫WOqԩjY}W|}˼E׆$(xذްdOկ_?Q-՝Μʕ+Æ [d]݅,`tEEE 6l޼yZZFAhՑ1.LVzh ms+}VH.BƽC0 ,}z;h#3#9 $3c(`˭0 ,r(vg2$.B+]#ZfV@E&AA62:@2: VM Vpw+`.j[0C"c,3"t܊t4ȌHɌ 3XUc  Tv*b T^^^v9sɷW,@8"BEQƌu6m!vp ԄW`'Nܾ}{޽-;/^|إf- X[lBԩ"%%YfHW@+޷o>~x-lmذazڱc㓘L&Z]-?Z^=!ĩS:!0Ψ(9ll36+f233%%%6G=ڦMBاO)SX*f͚Ν;vرgϞ;wt+W  ֭ۦME~#<ҧO0u$}7Xhd:qN 1{: :*//WS Z%Ktҥu͛7oܸϞ=k#5pt/ŋmQFկ_ȑ#۷X™3[=i$l͛7ކcAAAB _@u*]tiرO|QFk޿멎(o˗ !on7KKKO=TddU~n…vY}?οA6Wkw߭~PeT:rHÆ ?~嗎_I칯:<b޽;?s!D-Hb*7[omݺ?ׯ_]vN*8{mݖi333[oBtcc̘1,S!СCuԩ]Ç=#sSu._^+..yqΝsr$kPS֭[nիW]}ƍl 8p޾~&MXlҤɬYru<>IX۰aɓ'}YW`:(///!!~{뭷ڶm@*"8}u# !XÇ>_u[lBԩ"%%ƌc{ćX?}|-:ԪU+ 7 `AFڵ폪;srrq?VZO>dMgpTg޽?,YP_BtM'N9s}҆{s=nQh?CB/w:t w!`AF5Ů6''?~饗k8B#yu^:rZjcW]ԩS5j1iҤ>l?nZvM7}G 4Pnݺ|F "`AaaačT.IJJ4iR gp5(Ǐ5jT|Qs5Btfn PVVk3Vݻ80999$$Dgdddh:^  .8{ɎzE6mT~~~B W08_~|zf:k֬ə9sfϑ@B6~XW_9|TBdggw}uYh"##YYY=z xҀ ]PoVp( ͽm^xQΞ=ZNKkv˭mVrn!IDAT~2|)"""&2m㐪:B1cdeeZJj۷obcc/^x9sZʹo_7wq祥YYYBΝ;;y/5>P;tI_<8){=s/*aRU'???55UܸiiӦ ,1bb,J $ѯ_?Q-՝Μʕ+Æ [d]݅KjR'NTQ9\ }z-8p~M8 5e%RuҥKnEn֭>Ziimڷo߮];βcǎC 2_7̖-[v厑&Ձ԰@Æ ^~}m쾯ՉT̙3oWw+XMHHHRRҞ={gڵyyy݊Zje}޽{@@wV2>Ձ[հ@3g]~TGrHfTX,ԩ=6?W^_{ #9 $3X!X#`h1X#`h1X#`h1X#`uv^(ʚ5k:w۱cǞ={ܹW (>p@^kfQׯuVX+ ~^1c〵|r!ۭw~~~iiiX3)üdJKK6G_ްa 9rd2YFDDlr߾}~#XK!ݸqc~~~BBM ;pÇy% `Um˖-BC:uBJ`A޽{͚5?%ؿ?*\v-;;[a^zBSN Fڵ폪;srr J`URu# :XU S7폖 ! J`Up???!DAAQuDȯXU R, ]xQޛȯXUBdffBtܙW V'8t!ug||<NB5jZZ75XOYFmR8p_֪)//OiٲW޽[f'OE7mTo}dɒ _| +((5;vBt%77׭#בEK տGׯ_w>|_o*n8 U{_'h5͛7ᷩ㴚WB?ze… lÆ Bo{ɓ)2A-X6l9j6ww_rōk|R/ݻw= ti>NB:a#HuyoVwLznBB?~3gΌx!`N>=v ׯ_رhaa|еkד'O>} LLLt9wK/d(8x`>v-ZLƍ;-_~|^x Ӛ&_[[n1L&[o9r C;vTG׿vرM6ڵ{,TΝ{瞓'O⋍5o޼5kY\\/m1bݻ-dÇԩڳg /zE+_o#|m7XXogJx`¹u8*''gܸqz_SL:UXh(ևEYjСCԩcjiӦ޽{'NBk׮;5jUev[N?ZJ;8su._\ #F|AZje=t^eu곲_;ܲeK^^ޙ3gF![SE3gNddޝ;wFGGz |{mֽ{ *]*|DzĈ*{g E禧WKW޹4u[ ,KKdcM2@qDQ"Ct gA4l Ax8LNyL 0J'iqkomoA Wr^={f$ܹsV& ]fGGt-,,<<<կj({MMҥK_{@$)l،S5`4)^u]XR)7oެ=<*>>>؉(ꭷIII .22)[xnt>EQ 5dՌ2 :88=jZ!`4 JnzН4MGFFhShПZrɮ۷oN^xN:]RY[[;;;vHgg ;.??D轡<$Zu&fQx:X~H$G\8X3 ii8W\amkkc=;+S766c귵uuu>nqX%KU֭[syɸ][,EQC*3IOOe˖iV'7LT*O>KSwT\׸Ͼ۷oEѨ/cd 4ҨokRFwLsb~%%%IN8ammϏ,%4Y5cquualbZ9ɝccc'Z^^+փٹ466qD"h4UUU7o>uQz5:d<** =1R,Y/[ pEZ+7oXsϡh7 >^޿&fb>&b,qi94˨3 ^3( Lƺ&ޔ&6Fh4111nBQJKKϞ=k§8"PNrvV\\\CCC@R%&&^~}܌4M7/W(<ϪpWͼbmk3gΠM&ZA.eFaF $ȧW!'b]48bvSNܨЗ_~/ܼy@6ɪMQ233J//Ç#;&g>>[E7ݻw?~x5c f7č:^^^֭iĘݔɪMQcccwލ@ P(辝bULq5kE|_(ҥK 3;+~)>eiiޑuttuE蒣jfCBB;vm7 @ܗŠp>ho ̛74|Oxk,,,`b>xEkaZlJֆu<5daas#mhhKt/ 2Y ] 2 @fgg)qfx7I%ВۻbŊO޸q#""b`` 22Ι1>pK* .0/BB?k4qW_-={*JwwwHs\Xݽ{T*w^QQ3p~~ #g]̙3ؼqj5Zѣ={.܇踶0fuqoniiZԄ$iLaGQk)V <(]BBB`ڵD_2rj ݻ ^⣚QF]:fth4[l8y(`m89-w0KJJX4668H:BV˶ xO$*Kv}yp ^^^NNN8lEQ)))1(kk눈OOς %KBCC[[[Y3Tc(Y__ }r&ILqqWlkk_JrڵLc=|eǡ)HۋVsׯߺukRR\.Mk*^Ed;wPEQTccc@@@JJ 3@+!Ӂ־rJdu6M)53X𣪪_C$YXAﶴՂ粀Gk֬qrrng}_5F?wFc04##7511QV[t8X3x-Q$?~'8|||<>hmooo3UZZZ @B}ZZ pc7;+C[ 66["888**j2p'P#mll֭[GH$30U,5$$亍pH$e0n}}}-H$!!!EEELw ߻.w^wwwVV+RVV755@]촢rl*GkAAAvvv ,zn]41_릦&OOOKK@+Rl4SkfQgT 1--+-- E??? FFF 1yY@juFFX, k֬A&Qm\444|/> w\aaaSSJ nnnAAA+W~!AbJ@4% s@ L#E `fBl?{IENDB`PKl<e22-Pictures/1000000000000320000001D00F6D3EC4.pngPNG  IHDR  IDATxytU[! !$,B@C(bP< ! aQdGqEQ 8,l$ (, dt:շ߯3gNUV~-f w  @2d,X$#`HF  @2d,X$#`HF  @2d,X$#`HF  @2d,X$#`HF  @2dz`P]&j:(qÀ^./O S$#` X%^T/ @2d,ئN32|KC鞗:`_`tlw<3  @2rrr. @2dsMQJ!lय"$`f1'.?h{"iHX~fX ƗBBŽp U--{RV+!a]*dX Od}$-'?hAX~(aZ5V{B=Muitl}SKg.w| i`jL,O_у':Zd,'AHoos#K@G4:hfA2 bfaN#2HV]YHD<`YHAS,1 /XiXE:=@q 1 #0M.,acxC8a"5F[X a aPᮅ| HцwXX|r,**Bq,@HEE"`,*  f,V5VAE@b!XGXAB^"` a \ fsUT,*A"ܿ|Gz~nAAAjjjA4]?`!ܻw={te޼yZlBƱ4iF&N+!ȑ#SRR܏Oz˖-CPaDD+ e~'Nddd85jԁ>s7'va޼yO? Ș( X֭B8r/$41x4ktrъpsy睻w ^xѓSΟ?_}`|xfyNn"2MjҤIHHbqX`Yb؏/X` lѻNq,uy5`\ as z#FX]tO .,,>S0 3N6TVV\2>>>>>k׮^^_`=*ǽE 6~f>}zѢE/Ic  t! 0bRo哝k5kWIII}"sap {jQ.].]ڽ{[:ozԻ@ V"SV+;$Hu-|w'N,**{~Ჲ2Waaa_ϩ#Xd,KBB4o|ҥn=>3)WCYz%!`ԨweeeCY?ߎ|g },]NN#5`18I ^{5pB GX-k͚5׮]iUUUYA 2|Mˌ(111N{;X,&d  "t4 M7|ɓ'VM|ZΝ뮻$ sLьFվ}w熄p iiiZ ӟ  +)_\Ko6-tsKڌc5-ԅf,`0hƂ/h XǎǏp}Kz̏>HxU@C vڢz*/_qFMUWaAP ;v,!!qv4}V96ڤkXE>QH *ҿ`g۶mM4qLMUXfZzuZ22d/64)͛=z̘1$lS0R0i ޽{x7{qqq>]jjj$A0 5պs܏>ҥKqqqcƌիW,'d f#1!{_媪mۖnݺ:IGMZ,{˱.a1`ٕoڴ)77O>vZΝ333Mwhs)ڹ b|'7o~}? `|e4Xv͛7} 0v2C"&MW*7zXE'Bq Z?Y7zpw!@5n49eʔ޽{ScP/"~jժVZ5Go֯*&CYCK^{}Q!DUUp½{'OӧO` h1CY~fUǏ-[ֺu)S?e˖_VG,VXa):u`3g̛7oڵ<ݻ(hty XVZEFFwuWjjlX&%g@rժU_kHnݞ|qEDDx}c`P 9rk׮{7ްuwϜ9sȐ!E'|"8y?ޮ]zٳ5;vW_}}CEV6mtMɓ'O>]v>PLXEnCL?m۶ӧO4iRf$jD,!D?;6,,LnA.jb w֭QQQ( "K:CaÆ4E `dce X3T2!n3sL g5nXYa ! lԮ,ݛteJ BK{uuuCOl^ K.cH++1-#XgϞm0ѣG5^YgUhR%&& l6[IIj5QW=X+ e]mpLYXSCX 7 3!V0>V.JC` ,Lz˹te+_ `IޅC/yπwVȿ8F.у<^By8of,zF#y 8#,#q)2 L"P Kb2t,Su0QH yr|љ˫+V]eee-ZٳgFFƨQBCC%V"zÓO14Эr<rʤ$j $#I3qvm0J*,,ݻwIIѣ'NثWثW9rdݺuoVHH޽{u&V"`ӄ}w_ d,C,ַoÇY{ӧO6I&& a!!m܌itXh>۷o_]Jq#Gl߾ݻ[sû/~]f͚ &ԕT۷֬Y0D|zPOݽ__~7L0믿Z"|1Q~ӱ=X[.**p4ڦMkMO,Lx꽚iҿVմizӕQFQQQ:sejŒ޼KZz7n3###5\XBcUC_T+e… eeeVZZ/h cyS i X/^^ :I2fRiiR%,,,::&6bTVVU&wt侕Jz2D7mTo{UU՘1c4Uq,C%.Z}*°k>@wSD+a1E^:he{ҕ/h""(..Y~j4hs='`\TW !Zh1{?ڵB?m7pr)BQ۷os֬Yj,,,lҤInnnyyǻt2|O?t#->j"fmذ!;;… 1E@0aee|p뭷1ŋү`puҥ [Νp?]wuX,^xs*((;w5692uHM6ݦ( ,dsUV @2XE:"`HFr9G@qJ=։\@cQ3!`U#d,XE" xp/B#`HF `;1)IDAT!8~q6=X060ʹ*B  L"$#`HZ9XE@`!$#`Չ{XEq/B}Ѓ@^fZ9XE@`!$#`U#d,X+"0:d, 0tD=~GSPPwl%K3,,,66v„ Nһ(x=x &zWzL>Gܹ;} SzZ~'2225!C呮`סCy=zՊ+/_+!DBB›o)رcu~t%0`@TTTH߀[Nxnʥq]rwߵL@?npoРANGʄwq@?/SO=w-"QQQ[h!(**\!D6m"##뮝;wZ0 GyDB>|ŋw]Xz*//wJWBիW:K8pEqРAlcǎUWgo߾|򐐐FL)PO1118-(//l߾ɓ']zʕFGoCu0EQXEϛ7oϞ=2~Ȑ!EEE۶mӻSbbbZռvbڤI{B !J,XyfҕIum_j,=~555Νsaʕcǎmܸ˗###ՃӦM[reAAANl6ی36mTPPn WZZڬY͛zCyy#~gteN8OXܻtR:u:TQjܸq<رc+l4-[<_}EEEii޽{wnBRRRlllrrrDDoqM7effxUUU]wݞ={HWX,ׯWDgϞݳgڻdر[nB8mԸq㬬,}jg7o>v5k֤u=99cǎ;vhӦޥy,  @2d,X$#`HF  @2d,X|o߾aaa(Ҷm.]tҥs;vlܸ(CջFCS?3f̜9SꫯG=~7Ϛ5ѣ꓏=:k֬Ν;۷﫯ZKTTT̘1cW[b@`:zh.]aaa3g}tvN9}tJJJ"##=+W4m466ŋr#X|s͛7B8+!DDDċ/SQf:iҤILLm۶nPBDEEyQ&X|QF.GGG jr ^~Xw +,bŊ۷,,,ɹۯ]6~S'OڦM[o5//Ryyy̜0a„ >>}駟|I{/3Ϩ=NU***ncѣoӦMDDѣKJJ.y/333--;Xbbʕku^XX8jԨ%KxakݺuKOOڵ(qqq~xu xgbccZ'O;nݪٷoc=&hٲY^~ؾ}l}_l6[EEŽ+裏W{g:vXTT~z!Dll UUUNG5k瞛W9}e˄M6}.]cǎ#F!MxsvԩSwu>l˗/B .|衇tN{㫪ǿk||bÆ mX|HMfB(lҲzO۰a{ꏟ}Sު8z_ZuEș3g7x)#+WB/QR3͑#GO8p}tNgmڴxĉBl_6,>hO8l6:x/+@l#G*bXӠUԾBMMӑЊ u,W^BLؽ{w B_~~qy X,j{IIIYY*O^B̙3g߾}?`1>>~„ ϟ3fLvv n>Rrd\tittzj'>_eV^^*| !V^xAcꮻz'ڴic_7ߨ`Æ [x ԝK:N!ĉ?Ù3gG/}K֢E -Yf#-E4hC=ԧOq9տǏv{Ow eX.p(\F2 ,Q` eX.p(\F2 ,Q` eX.p(\F2 ,Q` eX.p(\F2 ,Q` eX.pY@|=P?(~|V_d /2aLXú&  eX~#kdG: uVY +CX.p5$9V"&Y%;Xnܸq=ČID$"k^E2 ,/_NX}dZYa#kdu ͚55ȚDdͫ(\FB Z9HNtBbF$"k5pY@b|rrr f3kB],_CbdvFⳏ:t 2*;OZ3WPbX}dZYa#k!5t"8),,:tḣF:G'}xϦ`iRXXI5ȚDd-A=XjGq kdG: u! ,hNj3ȚDdM"UX.㬣@r,/mID$"k5pF"!lZYa#kdu ##YIDּ eՠD!GF"&Yy(4A a@: uVY +CXЎȚDdM"UX.o]$d"ܸqcnnѣ cǎX#L8M6:'葑ID$"k^հ'źu ZdI߾}7lЭ[7֬YOnZ,,'O3&//ϨRYYY;tФI5kqjGq kdG: u֡..]k׮aÆY iӦ5k8pw<#M43A8BDdM"&Y./^ʲ˼޼y:tp饗j@X 7׵k;v?~q޽{۷o߿v^ƍ3'|@<|#0#)**R[%tլY `eeeӦM322vUUU>q.+WCBID$"k "ޕ9z NE ]`UUU 8qB)V~iII߮wrjGq kdG: u֡.:uTQQTc)222ѣwu̙3SROK*-YIDּ*>}TWWݻ:XZZݻw؛|g%%%gu0.:Hb }Zŋ o噃/7߼z߿p={ J۷+:vشiӰwI$:=77SN-.Z(33K.1YUUꫯl֬YUHᗶ$"k5ȚW%tըQYf-X`ӦMƈ_~}QQU ,;vlvvco5RJeggXbʔ)F9sfIIIffA= pi<ÒA a@: uVY +C ׯoڞ={FQά_HD$"k5Jwġo]$"7##YIDּ eXjGq kdG: u! ,hGDdM"&Y* ,7W.B]ȚDdM"UX.HV[=2Y +>AVX}dQ`A;zd$"k5ȚW x|o\1.WGL 2z]9hk:1}#`c9{i>@\ HNtBzd$"k5ȚWQ`K#Ym6dZYa:D葑ID$"k^E2jE@r##YIDּ eXjGq kdG: u! ,hGDdM"&Y* ,7W.B]ȚDdM"UX.HV[=2Y +>AVX}dQ`A;zd$"k5ȚWQ`t"AVX}dC"uo]$'!=25ȚDdͫ(\FzdAVX}dZYavҖDdM"&Y* ,7W.B]ȚDdM"UX.HV[=2Y +>AVX}dQ`A;zd$"k5ȚWQ`t"b_K˗w7r]H|1}#^Y#C5V8Ac?RRBe#Q1I_~j~wJ uVY +>AVX}dC"u#B7W.B]ȚDdM"UX.H֏+K[Y +>AVX}dQ`A;~iK"&Yy蛫A!IL'4E8HD$"k5U`k tX_|ȂjGq kdG: u֡~9;;ITUUuС'x##YIDּ*o˙6b>g~„ >`JJďnj#4,HNE#(l+T-O BDdM"&Y o1fx"AVX}dv{[nРA~J%KwÆ ݺu՝w޹hѢ~q֭3gΊ+6nرc8HD$"k5J"0h#EEE*nFM:~͛ϟ?k֬͛|ͮ/;;{ŊSLi۶KJJzinУGN;1bʕ+RA)ߤIWf`#s}kԩSJvڥVVV~W*,]477W|uTExUW;)V7|SZZjTW/X]Azd$"k5ȚW愤A}O?t[hjѢEN7\s5nO@Z}s=ׯ/++ eeeׯ{[jDA a@: uVY +CZ>SM!=25ȚDdͫtX< z'בG!ɩKKKo馎;fdd=o^o߾wO<{3xHDIDּ*K.y7SZZ_|dff~M47oU3OQ/b+^~eee?g̘w/ ?^wa4XYmzdu0ºu3ʚAb\OֆpQC9an|d-.¥KN:uԨQ-Zhٲ孷:iҤ p w}Sy欬,MӅD#q.z!tWI=!(kA{p6~zЇVX۶m1buo޼y R~a۶mݜ l%>zq%N%N]|Ʊ2Rw_4i=?z_DULJv]T'>SBcb+6mڲeKH۶m;wܠAӧK76wUԽ$''GǞzL}a] a~ua6u ,}YyӨb]Yް31w)&"l \0A;` ))jXoYo;kR֔xo߾=hp'N Sw}.L0|\c<.}ꊫǞ)...T>PT)U8e|ϻPi ajĺE j,f'{f$=!j>.TVqq)I{TБ$|jwuVv]_^.US ~guuO?t9.Y@AzЛ8L8A̡[kZnuY-;ه6ntmvk.Zc- Aa֥9]7'i;٥C*[",H_cEUl8py_Zb9c3%%M6֭s H]a-Hwju[9(6akQ[u?k<ȸ`ӊ5qkւ1'}A:Bou0 {ajCZg$Akhgd-&{cԏhX14nkv3x؝f6% *`ir-֝KN>f8^m`.Bs6a}z_ksq2z0:Y뾏-hg:,;[;1hÆ [nY֭5jcㆦtP6OA͠ȱkb/E"m)`8 [FޗP6t]GBapPZZ+-`4Ϩ{Bƾ*zspeYЧOs&A[2okQK4Aκ"sjE[%lbN#33oJA+ ~8p8PQQqu׹>׸ [HsG=^=8CeCaA<hBfnf4XwtQ8b7kHB}i赑F a7i ZyPD|c )] Y0vhev3͟o3#FlZH)>E;CuR9 E:ؼ -Wz^SZѠk^I-ҳ6u&}XG"(Ȅ랰G Dxg+t5ZعEici*$qa4hк DߺRAYy=ރR`$]{9,A#g'MXZʌtm\5&Ӟd㺬ͽ}yþxSټr &'!6ptQK[|y/dS2YИ:\y4]'Qg!^>vH3zj37)kt.k>lo⒦iSުw>Z5k1@AGƺ?=N7t?p|SlkU]-LzA; 6t IDAT@q+R7]_p}]1D;6rVF-"+P5ҍYhh;qM_qJ" ~*??&N8iҤg}vĈA_3oڹs$Ym {Qΐxh~|=N^E.kb+rNMZ/9щP #k g̘={rѢEnL^PXX4% ͚*o_EZ b} {YGnV`]tEƅ>(??/>}zuuM 8peܜ&<ī% 訓ψ,S n^x4h[k׮uq!VY +>AVX}dZYajX[<ٳRiiiv1O:}4/&QfJ6k_:uӻt2{ N|[lQJ^o~3yՕRjȑnL^@DdM"&Yڜu9̝;6m۶dp}uzdAVX}dZYa/|ѢE 44x=25ȚDdͫb{kTW蛫a]Eo\1.42#0# =ew+" 0/ABID$"k !9s|wu Xݻw7~pUV&L0~~С"++IKV[=2Y +>AVX}dV`=cJos=7OIIiժUzzzzzz֭?5kָ?YĻ5ȚDdͫb/k}J)վ}ny]veM@Nׯٳ;<%K#W\qㅓHN|?T])+TZZ4/x%YIDּ*f@~|ċ믣nuFvJ!-ƁuVY +>AVXb+.SF쩧ٳgmGF"&YyUlְaÊH'gyfΜ9vczv#G?ҁvm3=ztӦM[rezzΝ;[lgκE@r.7idÇOOOo۶ywg7o<77wʕJ^zI\u}葑ID$"k^o>0o߾oo5~iӦu]4͏=o3f̸ˍ4iңG{g7tۓJV[=2Y +>AVX}dS9f͚z뭷z'##YIDּ6`}s5" 9s!P HD$"k5pF"!lZYa#kdu ##YIDּ_U>ϸ 999)ASs^|s6m 1bY>oLxl7g/!'}蛫A!ɉ.BCDdM"&Y* ,Q`i$-ƁuVY +>AVX(=25ȚDdͫ(\F\ HNtBzd$"k5ȚWQ`K#Ym6dZYa:D葑ID$"k^E2jE@r##YIDּ eXjGq kdG: u! ,hGDdM"&Y=]6niUTT<]tI;u 48P)dɒ 6tVt"ɓcƌ3+T~~~VVVAASGF"&Yy Kڵkذa!Clڴi͚55+</h$ߚGkq+ljȬYj>#C9''GGd1RXXޫcD>oD+ni\>VTT&9M6MMM  @+X}޻wuT)ջwxDV[=2Y +>AVX}dySJmٲ:+\?sJnҖDdM"&Y*X:uZhupѢE\rI} $o}V2>׮]is+HNt:bŊ)S5j̙%%%GF"&YyЯ_~g7J"!lZYa#kdu ##YIDּ eՠD!GF"&Yy(4A a@: uVY +CXЎȚDdM"UX.o]$'!=25ȚDdͫ<[ ~߸c\0ϕc$ṠF:2t˗'|#擾67NGXY +l  kZ„u#BhGDdM"&Y* ,7W.B]ȚDdM"UX.H֏+K[Y +>AVX}dQ`A;zd$"k5ȚWQ`t"AVX(=25ȚDdͫ(\F\ HNtBzd$"k5ȚWQ`K#Ym6dZYa:D葑ID$"k^E2j|>7.waFaXRVDX5M y\&Y% Q`i$-ƁuVY +>AVX(~KD$"k5pu$w'C~iK"&Yy(4A a@: uVY +CXЎȚDdM"UX.o]$'!=25ȚDdͫ(\FzdAVX}dZYavHD$"k5p7>mڴ|>h.]o^y?۶mkѢW___;v]$"\n^{m٣F۷_~i;sҤI{92gΜ>}޽;>sFzd$"k5ȚW%tu1c 8*(()3WXsΝ;w.\pʕ_u׮]7iҤ8$..]k׮aÆY iӦ5kDռyfϞݬY3RV:P"!lZYa#kdu( ŋ+z2 kȑڵ 0@)##YIDּa}OΦMRg}u0##C)yH+F>袋ޣ  Hqqq-ne?R\\\\\\8:t999:"*A{/GȢ"/ 7׬Y `eeeӦM322^\\HD$"k5JҪO8JMMudɒ%9g ] W!N:UTTXeee3*--:uۼysקzdAVX}dZYaJw?s>}lݺu޽:t0*--UJ;j؃~o߾El葑ID$"k^`ByyyJ-[X7ϕRY^^>~iӦY:vXuu˳;yywe+`NNΏ?駟_PUUwҥ_~6G;v#||fڵM6]jŋlr۶m:&~gyСCN;M)_ې8ڷ~۳gω'Ν;wɧ~Rj„ A8sr4^:dM: ,)SLt͉'~__޽{WWWkwr{oРAG1{]*FenC,j뮯~jѢugN_|qjjjЖd(PKUUUQ6,\P)oZO2_u6=z޽{#+WTJu!k"RNl`FFRj3vW>|X)uE#d-UWW?C?o'ki/{ZgϞƍ[[j*--I֮]lْ;k֬umݺzYK@UUUrˋ/Y ,ԏ#1r͘1cĈ4GZbfϞҠA߷o_d-M:577[n6 kGiiiIV'NPJnj K,ٿd-1egg߷_^uU{ݻ&:x>]E_vvv&MOd-|g%%%gu0.NJyG^^Rj˖-?\)5x*//?~iӬ;V]]Ț@YK(o02._pyC}SF/6'NԩӘ1cW]uUff&SM***cSުY?˖-KIIYv9Bꋓ#e1Y ,Ԓq6@wFǴ￟qF˖-KKKܟ+~fcǎ]y={̷xС~F6mڜsN۶mUV8kԨq:k׮]vҥKΝ4ibز[n17>szꩿƵK.-((|7?~ŋu ?RQFYWuՆ R֭3G;ְaCTyy1RYYf͚#G*} _}q/ǏWVVq~;%%E)uUWYvm&M2h@ȫ1(nqרQ'OgM6^{ԣGZ<zx\rСCSRRVZiUV Ç [|P)q޽{[wÇ !|+J73&2ꪠ+lԕW^[o >֫4h&͛7/,, /2O8.((ˣ 9rʔ)J7|^dРAÆ ۹synIII={vͿ?OJ{Gi2C(~u 5fп'|2U=R'Z2Κm}{1\ǎ{UWUWWO2egqF P`H7...޽S8JÇ^YJJJ۶m_{58>g5.ϙ3v($-[.[m۶?+**jȑ#JVZ^evhWUU߿ԨQ6q? /TJ͚5kҥ D twi֬_|q7VUU+0$%%M66?xiiG}*,,ܷo_($^z͟??%%eҥ'NCen? M49sf˖-?~x ,^f+UMzꩧb XZZ:}ݻ_wuQ76~&<3o榛n7o^FFR}/RjҥEEE1@bak)k<pw}6Bٳꫯ|_`kceee&L6Git8}ݻv X<-JsoQJmݺ5M~k6hɓF`YY1R]]m۶z{vچ ziɉ'=z:^VV6m39-IDATڴ[neРALJ vѠӳ|> GoG@.xyԩS|  40ެ3g??O\sE]dy7֬Yc\O{u7O0AۚЋ{p eX.p(\'FIENDB`PKl|uWݼywޮu8999K,<| y䑼BVZشiS96ݺuKѺu/?שS';;$I?p8<(?%%%#sU2O)ƌs=L`!… =X%SXX#Z'lذO裏?.o}]!Daar\«S۷%Ǚ3gW^-ԩbvW2RgvѸqڵk;!vRX~~ݺu륗^z'79rdРAΝ?~|=33v%%%n9sFPWhxν\N999+!ď?X`zfXjrbñcǎ-[4n|;:w| +7n HLL_ԏi*$Ipf:t萒ҰaC̞=[!jI!P&k2@Bw}Z-Xb=X*n7ߔ9ypA|M= *t2k$$$g͛7Ȩr I@Ƥ-cB$g_ise?jdI-kyYЫJDWQgeeT6&wPVW`e?jd(@Gh4ĕ.B1q-0&L6V&MajjO?=~I&}W\|ˣFzG̙SXXP >e?jdten` 0 --uBSNuy۶mݻw/{;y={K]v.\X~@ D++P{+??ȑCӕUV1bD~~~-Zp8??m644>Ro(tejmڴ)>>>))O>ΓIII}ݰaC|||}cǎ}'O?"// ;sLO!@h-3X{Bl}^?i$!ȑ#ǬYׯi&U 2-Rރu9!DÆ ]O !222^?x^xǺuvٺuV$=p8 98@̓ rxy TZTTTzzzIIog%%%6EgϞ-YW~W۵k}Њ^%BCx7[II[gfS&3a``dAAy)[ooxb޽NP= Z+**JquדBȲ/Yd֬Y/޵kW||+W?3ZVAyg}ݺusLIIyꩧ6n8tR׷mĉjBܾ}aÆ%%%WY,4D2(//88xϞ='cccvv]~H^7qc:u4h Nj,UV]633S>f͚!… [j5w\ !VX!x~ܸq*J8w\ cǎӧO2e3fؽ{!!!dt =& X$LeK`v:~@P!zj 25yJtEtB7 b !`̏h.B@)lfG"]L\A+& ]AS,hCLG*r`%(5D0yJ0q& l=wt5*tM#]AX=5@5HidY,0qcHV0EfE(X" !@ ,hCLg9[HYL()a\,th3[]`hD+h"$II t5970`pVPk`P ejS~~~5s !6lz2((HQÇ !"""͛w…#F4hР+Iʞt8CpX''foySapPɁNc̓"V%IҥƍKJJ||~<+))l-Z8{lk׮]~l968p'ڵ+*{X;::o[Eo_PPK !>nݺe/)) tNJuرcsǕP!֘1cOu~]|5nnB\~dnn"22yyym6[ppp~~;C `n=z!4i'5W^ׯwOy={_wb9;ߥG}4;;ݻ'4i{AKQ&)*H 2YǷixWX/H{7ogדB~i.?4hР4+W|K.5+&C.͛:p8\2vX=,hVC=Đj,5AR>-JԾ}ŋ+:0 ykϹHOOߴiSPP7S%\&ҕL5e&gZ˗/x<P6?gj׮]*C z~hѢʯYYYtx]mڴw,ézm۶ wThƌ* kthX&L~駟VnT09zj A29"L&:T~O?T>-ps3; Ay|ܩS~׮[گ]v-EX`8p-[J>>>>}zv=>GR X˗/_|瞛]HW@GEX={Bl}*zVbbbǎ[hp% Sj/ʓOn$()ϟOII| Iʞt8mp; -hp !!AH&JJJl6[-Ξ=[իW7jH!Dhto=tHLG 267UP``y@Qnݲϛ7oȑrmE9r\!D/u}ʔ)Ǐ1cݻ xTCCTy+ʤ(5]ֵk׮]СCKrPsL\ihh0ۖp6o4 @}L\4@M+P FVJP&F@W!`fC͙.BXP t(W, ]a;4@O2e?jdɚX,!`HD+3Eӓ ]r"$??$-Wg`,r̊VAPk`PhұK*tFJ3aTC=XЀ zj-9Z+a252dM,cL\*!P%vA?R&!P PCf빣5D R52dM`X̄K$`MPg`ʋ,E'&nWmfCh xVA(5D3gW} `Xz"Z5G!L\tCb gtB5q~rAh}?jdɚa*0 W1[]Cx=X5X"~`P`AU*>52dM,˂c:B6=w- xԩS;tP3fO tԩ"4(@C HJJʀZn-8uTΝmֽ{;ww}[~zZj};v, XFDh+??iӦӟV\<9f̘̀R<7ߌB8^zi111w. XBm۶옘ד111/_޺ukܹӮ];9] !$Izׅ.\Pgts>52dMj{ !ZlzRq߾}.{Nz~BzȻwa ]LI.s !6lz2((HQӏ?.=zt%HTpm-l1{oySᠢ'{ओX !!AHKQQQ%%%>>Ml-Z={2n`k}Rm۝$$$sܵkjcF8'X{WZ5lذ1cH… g̘1gWzڵo-ӧ#G2mz:lٲɓ'wE~hӦMG^roݺթSSNz~˗/s=e_.Bc60"ߦfNjor)yCLG 2Y3X&(,T rmK8A ܡ1Ub ]ܥScI!P&kbUc PnsGX]P j!`4&!i``%1ʤ(5pK~]b3'X30x hXk`P=5@e&fL5AE26f빳r! ꡋ Z+,cUt*X zj 252dM`xqΙ]L\8+M@@L_i=eH[$yYL銞CLG 2B7i`1k3 ǵtq] &M+L#L\`gQ =5@e&f4ƚ CҒf3ܹ2J!W=X ]`n,eAL,XUe?jdɚRkX 똵js>]u2q!Eh+,%B8fFr=5@e&fC2Vz~! SE$?D+ku;wNѰaCדAAAB 6?_pspV;HHH* VTTTzzzIIoK%%%6EgϞ-(0=` !\O!֭͘?)gI!P&k|ϨQ֭[wҥ>,,,>>~Æ e !P&CLG 2fz)~݉唞.ѣ6cV~z299988866VQTNժUk׮̔Ϥ'&&Y& @۱T ÇZlYDDDQQQVVɓtR,ue2ʤ(!(^&U]?{#5ߋ7^HFjqHKFDP @a&܃@X"P @a,FP @a,FP ,_~zUشڷo?`zi="XP$IƍW^ttt=- xԩS;tP+ddd̘1O?-,,_ҩS'!ľ}>|ڵ+W jj^&W'NLNN>wLQF?C6lРA$5RPte˖z&99N:'Ooիr+̜9BԪU/tiӦѭվ}Sy.]tڵ QհL|$I_bĈP&fPX 3f5/bHHH^^^٧4ܹsn111DFFM հLNׯ_ /(S հFv'Uօ *z jTs5,<=]ڵk^C M &̛7˶mۖz2&&[n-u;wڵk'm"$_B\pAQ[7p8&L`ڵk+0VR8gŅ)5T+R yyy͚5Sb մt 6Ty޽{-[t=)(/-{Nz~Bz,o)11cǎ-Z0-K5_aÆ:ulM6_̈-Ke4ibȑiiic֬Yߴi2X.ysÆ ]O !222|DžG(SRR^~ey>,ؿɓ'kժ5bĈ$Uk]i6l{;uTnݳg϶mV«X;w!]O !n߾]W\9hР^zyixyZI&-]T$uFOk?;{iٲ˅/VeU_/rϞ=? M?ggg)((& (@!DQQWBuVyVVV%KT(K2͛7oȑ5Rp֡NJJJ k׮~~~ǎSC:er8ONNx?gϞ/"""BmhƱ~,7SS3rH!ĥK\_*++K_]xgyfه詩 e:zh߾}]gff:/LQW)$$I&g|}}]PJSwyGqQQ\\/ի5ɠX"JݚEQǎ>gϞ} NB|zjBB}*)--m-\deeeeehѢk׮^\fίң>}]דM4Q:e7ηiF|g^@P կ_={LNNBӧOv999 wzڵK1[Ge0aB;K.?xWiРA%%%iii򏅅W\yꩧTxZ&yƍu rsFwZjڵ5k.\تUsʏ~^{W_}5..2A}(..SN+))Bl߾N:fjiƏ/Xbӧqi1v(M~رcEEEYYYwҥhHHH@@< uVnN:u W~hP ZFIIISLӧODDDvv_|nVQbccwo6n8==>5jvÇb$ EIYj 7oݚLG 2",By׮]~^_~>1LG 2\,(履~%I2e/;eIsss|YˢLG 2\,(,FP @a,FP zڵZEȮ]ڴi#I$Iʧ~|觟~z4hp}ȑ#G Ҿ} zȥE7[n!!!~=}||zǏmڴK.$>Pĝ˕+Wz;w۷',hΝ 6z_ݻr;ϿznCCCJ]t &!2335k<6idѢE$:hJc 4nxB8׮] V{epnxׯc˦+!ĸq*4i_֭+**Zp! 0`93g8qC- xԩS;t`GvZhhhaaaFF "$i2Von۶~nݺ{.55u„ S:]3:r?^LNNSɓ'z߿߸K/ !ƌK.aaanhl999/ѣ6mL>֭[cŊC Bԭ[wȐ!C 9qD%>>>{7o~y3+s,Ñ߰aR+///88l/QgzuTIDATzVPPp8.]$>|RI sX\\zիM&˗ !֭[WrrrBCC,Y"x <#R[YfLNNv) {R'mۖz2&&[n5W iӦqqq˖-ϼcƌq]vkB4nX_W V?/'O8q)>>^wyי={vnn<&>}cVXQS:tO[ Xڻwe˖'gG=L6M߾};uTi|G= x}ݾ};88X{B``8sL~~~ًwѸqc9Qڵo=w:-X>+'k,y۩t$0⣞}~Pڷo߽{~i͚5W5jf+u͑#G t9z233k׮]RR:o^sm3Bݼy޽{o>w\1lذ7nTSЕ[۝;wDm???!oL#> մi8;;vԣ;v숋KMMرcMESN=î 5WW\~{nB{_̙3L0aǎ/¶m۸M`֚ B,((Bԭ[׈z޽{۶m/]Rѷ~m۶Byz%|||U_~Ep8r9s|{BܹyBލo q&M!|}}ׯ_'YƝWs XQQQBׯBDFFQ>?`4$M>]Qj{VZB=z4!!f]vĉ.\<$k߾bر'OܹsGy'ڵkܩSK\g9|ttt7}75k6o޼7o !ŋ?p@?~[[nw߬Y' !&LpISk={_wb9 !zaG=ٳ[neZ`Axx-[+ <_~_r7xCq…>BŋgƍO>ÇgϞݬY_~fݻw~)SV^?i޼y厧A_~e=z?k߾͛}||;k !.\W_}ܥKǏ_ڸqG}$^|b045Z 3wS87.888//ψz_xVXXTgΝ;?={^zIII}90--W_ܹs^:thٲeEEEYYY'Oҥb΀!kmrP @a$ E\rIENDB`PKlrm۶ 0^ھ}{vvڵk_ݻwt7tSԙf l0VXXhxV[[#swqGNNNΝ_r]wuر={)T? H+0//oϞ=鎹(4MKKK۵k͛=ަMfKJJ\+!Ě5k 7 ֭['>|saÄ-=Ƅ .B3glܸ1--lZP/ݻsgAAcM4InB>XvM6.=Ξ=ۡCsy^%ftM~76-USSS__/;;mVVֱN>iӦɓ'{ Y;=x_XA.ēןz`J+&&FrFrg+WH,TL4{ynf-\0))~;zhMӶnz幹Vڲe"55599y„ .'''l0VXXhxV[[#kA^^7sqԩ555O=Tn #|!D޽? 9''gݝ:u;XvB]:wEQZZȓUV !.Gyd̘1;w޽iӎ9q_ 501GA}2^wTwh۶{c\r;tߴiӎ;.B7spnڥr]F rCCCyy駟ֻGEE͚5{=~c=JϭP[[^SS#~cLѽ{wS !rrr%XBD!ĩS?vډ&['Nc8Y ʜ>,5jj6h !ѣG+**r\ XVUsNB!ĤI9%%EɓBGEE0 qQ@ Xƍ߿>ݨ8~x9s̞=ѳM/3fŽ+l߾]1sLi' P*X,˖-۱cի+V8nٲ%33ߴi\Z !wtO>'cӧO/X 55uA<%TK7bĈyeeel$III :ԑX^^&*1cFrr z^xO>y_tEgϞկ~5k,aCf%yh5==(>7LyR~pSzeZY`;K7B 7ej1!^}z~f̘s=}m6{5eʔ+W .<ԩSC7?(`ٳ'==1iiiivڼy۴iǏ{wR?ƿҲ)?pa[u"Mp\o:n XK-R *L ֭['>|saÄy^8rH|||rr>{ȑ3.Bψߤ XB޽{;'s}}+'Nxw>`]]] 4Kn8p@ѵkW.]!JKKƾUVǏ뭷LҺu놆?ϓ'OnhhpSK!1cpQ@Fu^/*VMMM}}"&&9m۶i~7x5\#ذaK/~GOՁMtEhX\sO>>>~ƍC B,]TV:U8!˝!Dll˝ifB/]|N7}=k6 1J](7J}HPm x:d-d%>"J%HLLB:u9Qo߾ҟ1B8!EkB2Ç !F%pHA@=0 ,*عssbaabҤIWTTk!KP! }hJkܸqקuX~ǏY__?gΜٳgCo߾;cŋwB(`Y,e˖رc̅UTTb -[dff>6mrٽBO NjZ{iӦ9sf˖-;v-RF.]C_3^J et3Tr1,?k!;_޵6[w}5bĈyeeel$III :ԑX^^j*3f$''O0!>>^OYh?|ĉzeˢ:}"=nEްaCKv.={hikkVDzDM~ Wd |o0(#> ՏQOǠK3,]&dХr򂗹>w{LqdGt2)I+Л!!X>i H_ٷ=q:Jͪ'a& `U{ԩSn m~( pB4vHENDΙF2Z9pJաo܇ r |fdD@󝑚"#U[5mڴZ[6o3fL p1D;ŷ[n7tS֭oiZ=n `T>"+2%% ʈwhRVRF`̑2TMIGBRk(xKQ 7: 1jwgO5V^ .5scʏ̦ kdee}ǎ={9rޯ_?3,+տI sPJ8 Zs)U-2ӹbB 6g}לݛOL>=33}Jf?OڟTnwϏϜ93vXnjs̙ pE_/0D oroK94:M)7jGt /`ƋG4p-CܱAAYRkΜ9Gںwߝ;wnϞ=wu}I/+Bskc]J%;j$|ybakPo|3f.\k=[nݪU.nXxgΜw RT[|o_n۶mK4iҊ+.A! LbDԿ"| nO=[n `093s G)s\]j03oֹs͖H[eX<޾iwʒg AZƏ!Q‹y+2)#_9dcM3楅 d5C^=H;8=m-Fo yg oGz#G,&;Ӌyr-9rEg=z_E06kɒ%?v^zg*4lS .y<\Ȏe2:s]Pi[5q+r#G\l_i}7ѣ+n]0~{û%>ZjE]g͘1#>>C }ԩSϞ=MVPPУG+W#( R9r'9~mC N/Y ޵䃔蔺! UQVZ}~E_}UUU_}Uiiӧ#Fl߾/XJG_@KZ\C@,]x[lͽ㣣o֜޽{K/(QDirKc.=|UC)72MOp(. NUo/pQ3TViUiVEfEY;`566 A@eA Ξ=CpO|/X6H.g-N=}$y9y9P b)%SM/^9bX*ɓ]v?Qmǚ+G\K3ߦiXfͤI,Y>y//{SNVb8TUU߿)bh,* fW:R\jA6O>;Ծ}{ŏt` b~(,,5jTjj Vȑ#~C\r֬Y=Ё<>x'|*P#/Ǭ7Bg:p_~3fS>}}6͎z2eʕ+9ǟz ;׌'.EvtBb-ZzXgdd"5|MMMmmߙ766N>ر;?`)RW; R7dEr~G^R!s|Z1X捐Qзrtu"'o^R93g,..^tC=z17'>㇎.=f 'p±cǎ1[5eMRSS_III[CaÆ rFrg{}ѧ~{0߯8 IDATp1?{`Z,Rϕ$|-`]veڵkOoݺ5\_:ofۏ;S扉BSN9'X-ڵkץ^ωҐ!CdrV 옌i4'sk['w^zinn\ƽѣG]pÇ !Fw6Gz'N9@S-ӿ)s(!VbΝΉBI&ƍ5TUUe,Xԅh"k76?Z:QQsSQsaN!||]bYlَ;VLSYYYEEE+Vp -ܲeKff?i&+**2`2Jݕ[%KokhhBtyɒ%v[Kϓ}-͈#͛e󓒒$%%%$$h6tPGbyyynnU?g̘x`7;t.={i =O~tr^x>BS^v1vX%wvKR3|\ +EΉ`lڴiܹ.󭛘i lBY"e1\5+*| d IH>1[/Ŏ[#3f7Nz!Tfӳ3Ϙ:aOK|h"Gx:v49C3Xm۶mnݺ#4P~10k&64ol׮iZjM71M6ZSFCUW]վ}wu]:th$===U} =G&XơW:M ]]gix9(4_9q6CqX/b_x7c KJJ-B鹛jZx(\ խOAY"g6C_c)RxX?#o{]x鯿XJo_fԢoֆ ;91**;hӦ#%::zܹ[nSFx&q+֘MID.믿%rI8p}*1`UTTt%1:o\(RP {ѠHNuF η+**of˲f/ R9X`<H%|:HLV q_<=0CFb7m?Fqgq?| sss277?_ERnMj<SO=UUU~ o>џI`Und1ɷ{)++ZNji'OZ;3_FU)\0 +255?K,XgϞF%W_-Z|UW]{A(0|lٲݻcbb?|RYYyY}nݺkCoIM;6Ky(R' C_F> wSTg^Bt>?C:K.d˖-zYLrLV؇̨E~ 'Hc|] ˇ~gb&Oul`J|!NӸJO0` !:w~?x}mݺiݺu^~?K/^P++XxIe`mަ9HR0K1¯yTQ^0+'e ل&4ݨh*Iq}-B+q_o< =hn(;nފX0>€ @`HF~tV/5aӠp>%T(CXUx*M" ?gPV`1n:q B6V1RTff!4$#`rEPm%"H!=!\$# "~9ZVA1LJR ː/Pd`&,N :u/Ge4DPT'>Ȝ<"P(ZXWoj_q$[bTjQ .!])*)U>ͰPB=,ɔ 'NbZVkII;VVV.^811 v}7wԩUVm6ZVaaQRSS7lؐmZGw^{:thʕfz衇86999ٳ/ⷿ 䟃(rFCG {E0'Bf>}z~f̘s=}jիה)SV\}݋//y}'xBM, BV^^ޞ={ik׮͛7{ܽM6nr^bEn)<!،cH"הPG`4t%ER(ZnbΉÆ B]6o /9Qq׷n:N͋W-"gH150RfbM*? Ql|!D޽? kٲe_~*7[Dv]޵kW.]!JKKv5v/x7|{ozPAh'@zǏ͠.>B;X555Bm~^z)))7nܴi<7x1@5Nq9BT ,t`SJds]wmڴ);;{СB^{ <[iNĔT bbb.wjjj.wsy7tӶmF!XtiJߟf 'eԃOgtݘl%R|GF)GA=`dJ%HLLB:u9Qo߾rBJ@(`=ZQVVxa!ĨQnȐ!N)`YV!Ν; &M~'N!n9Fagq_na?~g}}9sfϞ9t|]]ݑ#G\_};Qv)`Y,e˖رc ***Zbch-[233M6^QQ;VVWWdɒիWk ɇGFaVOPeQ݈#͛e󓒒$%%%$$hϳ+//]j3'Lu]}YAA# Էo &ݻ7666g' ɚkfvG +q,mÈ3բV%rm۶ 0^ھ}{vvڵkٳcǎݿ^:vXQQ+;A94uflnժUaaޙn6fZ,n!_jkk,YҮ];[oM6zҤI֭s)T?{q D ce/K^o|ٳ'==1TRӴ]vm޼mڴi6̙3ůJve>"77QTL>|saÄ-=ƾ}}< MKKB3@ꃕ/ݻsgAAَ=ibll/֟*HJe8 ڵsz.]v],{B~lzPze`DA]Dž*VMMR۶mW}إڵܹs=nI8q9pw.=R%r t-?tҕ+WR{LL>BmmszMM"66V+>k֬xR2pJ%HLLB:u9Qo߾=3III<B>ܯ9BQFI9īz̙K Y XVUsNB!ĤI7/|Ia'N8ydf Z f 4K.}#񪫮:sݻ?ngZj弻n׷iT"''?|眣9sҥK[rÔKxI7*eٲecǎ]z-"***ںuch-[233ǏOIIq޽BOmmKy .wq${キ ?ݡٽ{yZnm.\xo=zi[n=UVmٲE|saÄ<P/ݻsgAAAx;U:!vޥK!DiinA-izPze`D $T jjjz'tm:;ݴk: t00 U}ބZ!DlllXn_AK(8usg߾}  XGB9'>|X1jԨ  XVUsNB!ĤIS&)f4hP.]>#GUW]u̙ݻw~a3ϴjywݮofoqR9D3/cX-[cǎիW)YYYEEE+Vp -ܲeKff?i&+**tu2nĈʲluuuIII 4M:t#<77wժU3fHNN0aB||OH#0wxD@$,1)< MTi`HF dX`HFC %M,FY4)`HF dXh?!yM,FY4hf3 ޷!D޽?iGmڴi饼={?ڵko4gΜ)..~Wڵk'X,'O~gf4My8466fdddff6} MS\\zytС4Mi;w$C_4F֭B >9qذaBkz ڷoߣ>1z= ?O7xDӄEccԩSkjjznݺ5 M=oB!UW]IO !z휨YPP6k7pKbll/Sh0ߟ4MX޽SNwygK4aaX̙#?U?p^.]oC֏v]vuN׻TOU=nG{ !nvO&***͛׿,M.7%\#3sݻw6mڑ#G h0zǦOxwc ǎk.=i O?wΝOjjj&'`^6M|]8qB !99-i`kiz):u޽ᥗ^4GG4f=ϒ /wqDӘw~dX\s(lRB!Ǘ.]|rǔ 4M,\pر#Fhi&,~i{{TTԬYǏ?c 'O&''wѣ7xw߭OEӘ֏bbb^555Bؘo ]#n5koFG"M}ѧ~ن ǭݻ;O:U#h:w 7P\\gWo34 `DbbԩSΉ}:x gIJJ;wK:Mz-ڵkץ^ωҐ!CdAӄCLL>7t'Nпip?'x"***11q۶mEEEEMctX?1zh!DYYsÇF~ϫz̙7} =vر/J_~'M 4HqQt=ꊊWˡi¢bȐ!zJsȭYF4GVU2>7ɤIAo~n'Nݻ4#igyyynnUl"HMMMNN0aB||fw7o^֭m6[]]… \fx}]yzܦX-hټ|8VUUàhl۷?~E]tYf, zVmڴ֭[\\\nݮ޵ksڵ~жmۮ?ԩ~hM>}m۶M>u֎]~߬XBf͟?ᚦjjʔ)V A&_nGuN_nޯ_3g4Qwq۷Oo6ѣ+W5jooj!SXiZWΝ+X~3N>ݩS͛7[,͛77eZJ0p5k֤zTWUUw;vlԨQ[n1cƉ'z뭖"< DGGgee%$$lnȑ#du !zXMլ;.]T'B |% EhΝ;l{gT[B҇~ؿP5o޼oY_ȏ*++M:wnÇn׿ر3_{=?@X"by OpI_sعs+SO=՗^z_WVVs=?v>}'|-u`\qqqovN._wy:tiuGydݺuk߾e˄Ǐ9s&E "JӐ%!!aQQQ|O_3f̄ eɒ%999)GIOOLqΜ9S~_ݧ"P0gs466:w?/// ۵kt9s戟F`~Nnݺ555m۶?Dͦw{ov!CΝH>}:11}y^a,R^^믿vNυnԩ.?7n;/] \/=uoqWw]~EEE .t9nǎg͚%JOO(%:9׬Yovmuuu+W?!xe)M߿_ɓ/q^|||ǎkjj4MKHHꪫo>j(Ջ/~w?/ !jjj>bٲeʧ~*3gرc_/}ׯjvvΝ;G}Tjm.H#B$# @2,$nkf#TIENDB`PKl<fHH-Pictures/1000000000000320000001D04C6FC54B.pngPNG  IHDR  IDATxyx7R(e UAE@+o^APA\PPSx(O@EEMYD,\YbK[ZlMI2~d伓}9sj'"7$X#0 H F`0,` `$X#0 H F`0,` `$X#0 H F`0,` `$X#0 H F`0,` `$X#0 "=X,%V3b)d#g=tG|gݫ}}~_8E`0,i.δ8hw1'ecW6pQ8vebW2v7 3X#0XVjNuzQMW%''-LKؕ \]ؕTඩiJ,ˆ`,<12 lX[}ל4 H|7nܸ`!h]Eؕ \]In8,`,<" i L!!UfG`0,ߩ\jl. ǮlBJR6pÑ` `YmG!*B?ҒB`0,ߩ\jl. ǮlBJR6pÑ` ZvTl--־V~y/L.2YD#=Uor+( IV)[my&XB`𬶣ZWӦz`U"0ׅx#E)B`.V\}-lBJ2&), H72³.Eả/DžGM*B"09,`jxƓw/ ^ؕl#0 ­NC!3l@PPEnUJ3{eZΝۤI8q"؃p O?=vؿoڵOXZ@)~ \]I*>D=|nݺG=zdɒ"rɤC;vsZpyJDUoƍ:.wL]maÆ;ڶdggTVYBe*BG~"tzp L}.WH W#aj꧖Cj\r…۷o?{j-SL5jԢE;֪UKQm۶ݴibŊϟKQF׮]njs 77|Gmݺ̙3"RJ;GGtȑ]>|(,/I< %YJЇa)ڃk-eX֐_ƍorq*?pԩVZU^;vصk233C?7o|鸸8YjvYBTFNrrr>ꫯ+Vf͚Νsʕ+ݻwOHH7ނE>w{!o߾n?x ٳիWoժիW_ݹsc6"Rfͬ,5k6oM4Gf̘QLzږVk>|} }"VŊ/^|ȑaÆ9{mݺp ? ԩSSLYfv(-[]_~UTq#FuÇ/Zr,X "]tqM͚5ě7o>tׯ?z#yڵk{>-*Wm~("={to^D?k??+ p!`2dժU]VPPQ!mݺUD6lþ'O._M .]_3fWhQ׮]ml""M6u #0I7?'XC 55n{۴i~{_/^vYf͙3gv hF/ +I ӿ׋Ⱦ}lۣ 1~K,tݒ5BWb̙3֭{߅RSScǎ?CUV|T:--}8I`:Ztib\͚59ԩSG{jnΝ{w W_پZV}?}u9mcH>Ehṛ֭[Ȯ]&L[jDDݻw^i׮脲_xebW ҮqYn_~"ض?"_]6@@`AQ-ZѣǗ_~i/`*"ozhɒ%v3[dc`A] }7ܰa &ݻ7##gΜYrAԩm,a\\ܷ~[f L2YYYYYY2eJ jժaO0Zw$XPڍ7޸z%K?~O>ʕmР1c|'N,\qGVڦqqq7o{5>>~Ŋ-_:wߩS={,X`eʔq~-O@e,N/,pKfAAQ蕙 vT*Bϳ*BГAz^rح1 U&3ϐ`1sW$XSBؕ \]CD3bKnr$XS!1#eA`W.!M ]YmgGcPgl\ÍZogcЫX6[H2*<4 I,T.*:N;w$ʥƮlp.Į$-C`PUT" g``uX.^3[}mX-$?z>xEy0H)+;$XSD]Eؕ \]I)UI T  !/ss*$Ʒtl9%KgY[6:$[j9K ̀FU'wnMUNCvkM N@9Ø Ʈ^u/nBq-?>O=>u -=|У縱ѺAv'\ Ƈnmw3hwէ? a_as|̘1?zb.)ۘ+( +{=y`ua޽nM-e&J7nߪ=wڏof` nh6WӁtO.hx5lFqO)hnc=qI9wq);vLmwաO"W8sݐwz CCqrumCs/4ǒ+Qsz}u,;ovǷs\\}7tFg!)44%ApNp۷yb@w1~rY,I&թS.\`f &XCW%j͛? JD[.DDիWkND/_ޢE[֫Wϐy]yۭ٘\y}ĉ"&ҥKA%77w]tѲ+޽{bbA0Al(±+XEy`*Uꡇ*tݻ4bŊcǎǶgϞ?͛?u~ʐȗ4ԬYmJ*Cv-[&"v09SOgޭ ~IDn&jժΝ;k8'XQtl:'`ƍga做Mf9drfh7nq)<q㴪?W8/$Kc%}\\t{ }ѕ᫯ \)YdDDDFFmcvvvLLLjN8jG&gBB(txvWp &7|Mv%"=z1cŋ60Ν;רQcҥK.mڴi6m??x`;v̓yA;v!WTTԜ9s>sX"z~ܹ0 ejWIp/**ʐ+H֭[7a„|mۚ6mjHEr5&R6vecW6p!v%\]1u^jZ =*((j Ѳe˕+Wy7jժB7[zu}0/'L;ޭ2eo7ԯ_6С??zh#F & a4zu{RE*s"tm "·ݝ)UCOLL|'7o|5[1YfyyyC5pMR!' ڵYf͚Qbgj\7o^2e3` Ny}﫯ҖX={ȑ#NҲe˖uOȕZHؕ \]MsN!xHfIIIԩS[jUti)]tVLrȑ]=HCd`exƦiGNʔ) / Ǝ\x3yj911={*Bɹ*kgމmaxC*<"wGϻ;$U6mzby#0>-Zdx )NpSN=#իWVO>m _ݸʥƮlp.Į$f"6mooٲeϞ=Umַo߳gFGGᇆC] ٳSSSϟvʕ3g9sf֬YVj۶ٳgVO#/fLca[3߶mۿO=2q+VԪU?VZ-YB +TL*B7كU-rAWoȓSh'A"LII߿mСCwܩeW?~ x(û+&&&>>޶B j*V;/^\k?vac)%XJrlTˇn{ sɒ%E)[c" Ǯlp.f@RC7w VjjjFF]clllVҥK_}@IfKBTwitR\\c{͚5 0qayfbDFF.]MAjzjnnn"cmPEaE'[MW"ne˖6lq׃~,B?f}̝;r5:mڴO>[nF  x` jPw*`mhѢM6= *T]M7׹s׋|_4Q_ ecW6p!v%)ἾaVjժiO/\pȑӧOkƉ{e0S%_nܲe˃Μ9}%F4h /iWNð"0 T.P6vecW6p!v%)H *6Vz2Z"tڕvTD`0,ߩ\jl. ǮlBJ*z\t^C`0,SJAvTBUZ}D! "`3y$XSD]Eؕ \]In8,c`,<"KT )g T.P6vecW6p!v|E*W:eR5Ʈlp.Į$e7),ktC >}zjk׮|3EFff!C&O\V-1???999 (BqL]mݭ[sfWVرc>?jGů~Tuzaׯ_/"m4hPpPS'XK. f5Xfr+( +I G`0,gUB"d `$XBnw*Z(±+ p$X_=,gU ת?@E$X#ʥƮlp.Į$e7\d/_gjYP[(. =UMȫVxVQE@E`0,ߩ\jl. ǮlBJR6pÑ` `YmG!*Bѫ`&c#ʥƮlp.Į$e7 H vT괲A~*BE!ɑ`w*Z(±+ p$X#0XxVQE@E`0,ߩ\jl. ǮlBJR6pE{buX*C&XUWۦ '[YmG!i?J*B#0 T.P6vecW6p!v%)HiU``,<" T `$XSBؕ \]ؕl#0 0P^CxVQE@@i$X#ʥƮlp.Į$e7 H vTf"P 6or+( +I-6 <M5X T+lg%<" PE4,`NR ;Ʈlp.Į$e7 H vTf"P H|r+( +I G`0,gUb U"0 T.P6vecW6p!v%)B,z˕+QJ ͛{j?[nv튎x" PEh#FL81:::(Dh$X .Zj۶m=E{;qٳ׮]^Ůj<x$1%`斗=MHHHHH(tĕw1'ecW6p±+ؕds}7;t]Kݺuyŋ@H0Eu뭷ڵX]vm۶J*k -Zb|0ӵf͚5;@^{ܸq㠎J-Tl. ǮlBJR6pÙb˩%K֭[K3X$ĪW*BUB̏S#ʥƮlp.Į$e7  ~Z<0U^Jl. ǮlBJNFa `$X#0 v}^DEyweEl^wؕ ұQ:,`,};+{H Ӿ}{[RSSE^z܌+W\RRRzzo=YþrJ֭ccc]m[]|ڵIII'Nԭ[WD atׯ_kءCoP >};+{X壔9wޢN޽{ʕ+/]4... #FL81::: Λ7dɒjժ"qƠ/VXqر>}6~ڼysFDJ}nS""#Gk-K.sXCeffΚ5K VZm۶H<+Vm뮻D$"" ,[LDmo6PWjՆ z}8}Ʈ zo|ѱGӧOoӦʕ+v>|^xW=4/RRRn;3c 'N̞={ڵH@uѮի"-w 3?tMժU;wgL:sLvvۇӧm06p"aM4ٴiSʕڵk2￟4iRbł=4OERJ>h bbbZne˖`+xw}xKiSO=ɓvqٲeEԩSAH͟zw͚5/CM:T hgϞ۷?~cǎ۷onʔ);wW^|3g߿v=egg;)Z1" Oߑ?*7 V^ݯ_;v7b̝;O>yyyߝ?DO?6]רQ)S?>Cy۶mÇ@o婩f @TRJϧ`\ӷO ?:tȮE[ʚ5ku7iҤI&v[>}V\o=ڟ#5GFF,Ydh.]Dd֭xxVV3}ذa kԨqرN2eJ.!Wڵk۶mUTq|I?hÇ_hQʕ0.S;WZUoV_~vQPP?[˔)?-QQQ~Qb"~a{>H_ӧoذa.]2xdmmڴ9|ѣGk׮[F O^ެY5ji֮6$$xkӇ 2}tۉk׮(Q"J.]Νgk"ҭ[w.229KM~E= 2O5h@D٣Hƍ6@y/tk׮;x%Ku= -33sȐ!'OUޘ~&ܹs5+.]ڴi6mkTΧoKz5,kw}K/zꘘ:uԘ'{h~׼yÇ_ի7or-cƌ /={>>..#GN:cǎZKNNz۷ >#mzKDZl5VRnݺu֭SNZw ԑ`"*@ho:uG;::ZD,~g>Gݽ{wFDҥKʕzj%NRSS˗//"ŋ*UFVQF˗/-[Vk?|pݺuE$''x999F:x z3XB۵k CiٕڵkZ 7 "qqqzv%"ʕe^~]raÆHmw=:uNjmv%"%Jx׊E +VpM>}E]EKKKs75jݎo\\?^HQ8'XVuܹM4JHH0`'9qİaz=hР6m$%%_io?bꫯ;vܹ ԧOÇm?cƌ~=#͛7=zիW … O=TJ+VVI&y~XoޡC/g/M)4.<ˇ3}yFHhݺu޽؉l۶m-O'uԩcǎ۷o 駟NOO^:p = X+UԻw;jʗ/oڵL2&L(((Z?,\бg}6>>>''jnٲ%&&fƍK˖-OII7.((0`@>}Vkzzzbbb&MҊӧ6l//X 99L2"2rHOիW{9myEYi&S["Rtis/ׯ_ߐ*##CD~a0n>|'ERJٶ2dڴiV5!!7Ç뾅 ԅmvڤL'U зi߾ddd-"R^=*UcYׯ|}ݠC~{ɒ%"m6}oVDFQĞyCu[tB'L0aW{|Ywʕ֭[I\<˷Ϝ9cTof͚el$Xn62GFDDȜ9s.\PBH$Xϟ8pɓ  w_ժU *ѣGtV]o7nuY/BD>3 yQbŊiRҥK(Qʕ+>i&W bcc=:(Vk~~?-Ej>C6mJHHߓ#ȓ|"yFJJJLL}DEWjjԩ@[Ǐ=Z{&rD(+l`=+Vm뮻DDF9rvҥKEdv}7xw-"˖-D n6%پ}{ҥmK+Vnݜ͛7sddd۶mm_MMM9rD·U.\XjUN41p=zo_|QD>b Ξ={3Y|]ڮ+((Xnwܡ=^nĉ+VXx^z6ǏVic8wرc~HIJJJJJۏ;6dȐWXiӦK,_JKK{ɓ'iFD 7Bt AZhQPP.-| PN;s?W\YD֭{Akٲe4&&&66nmA?XJ_mի;(=v}}Y,޽?M'OoVoKJJו;&Xس'{yul9ӧOk%K8p'|gϞAH׮]f͚{>"K/i{?~\裏DTR<ȇ~qnݺ͵VU`;$ǿٻvjٲVkNNν+"z͗\pA{[n <,=Zvn޼aÆ{_<*((C}wl߾}{TTs8p*Ulٲvh'˕+=}DW_FcVsϚ 6<6O?yr)իW/Zvf^1c10.=#fAvΜ9JYYYZEQF^W\Ѿ?zvm؋/j-OoB;nܸ 6Ԟj?ptҤI~|H DD4iDDW~=nyw5uTcTI-[ְ՗IDATatUVժUkƍӮصk\}k׮.]jqqquڬIյ㣢͛}JիWg;)))7ttCX{޹sg.]lOE9&X>^lu}ڵ?-ZV|y۽K{{Տ6&X;wSڵU.[L;Qp 6> E .ڵkmԮnw;裏 K$B ɓ'[lXH_+VL/ꫯ[mL2E/۷- 6[u9iݺޒr,Y2::}֭Ӫ$h2=<-L`'{ֳȇ~ MfϞ-"?:TjU-'ԩmyam1**9m9fddkF?ޒ[F RYYYEmgsrrYLsǛoYx/°"]|y-ZzWQ"ҹsӧȼym>Ӛ5k~zwQPPvu)ݬ^zV̼v7|ޯ_?mY}QzӡChWEQhϻvڶm[*U,6.]t%?(^Dѣ6SΞ={_7nX{ ܞ={ӦMӮ׭[iӦ;v_z_{K.Hdd /'//oՃE_~3fٳg[[Tw7֮]Aջ馛ʖ-)wp Ͽzu1Ƭ,IkдUPA{Qd1c<\Ҷ>KI]v-,Y?=[ŋ-qC<(̃X[[\[VS`9c?N:ٍׯZ6lZߢE UV!xöyyyG,J'.^("{tѢE"b[@dZ_^F6w}M6uzaÆ>VK O=Y>ssa#f׳'{yY˷5XQQQ%J9&US?ڕfΜosŮ];wjnZQQQ)%ڵksOÆ ֭[:1&&]v߰1c)W֭zÆ ;vОZTRvrFnnȑ####?vzxb\\\ӦMWZs:u,XâM9^ÞO>.q3?tf#gO矅  \mYE$66Vrrr`AAVpuE[.mۏv2eؾ]VDd|ɨQ4L<ĉ-[ӧXBIۺu~РA*U&K6\|922$p6ٳSї.]7_zݨQ~uܹo߾ҕ+W/[v{ᇻu_fMbbbVs^^O<`X5j4p]ӕW.Xwqx饗-Z第ƍW^ԩSթgGUυgq]sNW"2iҤ#G߿Zs=/߿Ȑ!Z˔)S8p1"2zݻw;vZ&NxСC=⋧O_~[/=---11^ڶmfʕ9s4hPXݻ޽[!!!!**jcǎm߾ѣmq _a;w~*THJJjԨQ{%!!A;#e#, 7ܠ) #/8vС`"8!*?IENDB`PKl<pcY66-Pictures/1000000000000320000001D0B3231DCF.pngPNG  IHDR  IDATx\TUs DAߔH'ŲpERVZl퇚Z~YkV 45 qS+ LĖL,&|ߝfѣ̹sϹWl vdC @g,tF @g,tF @g,tF @g,tF @g,tF @g,tF @g,tF @g,tF @g,y(dt<K#ͦ(JK0͚VHc/u;c\0:_t:!X:` T@39G'4aFtF @g,-ZM<~ 3Xe iu,$xbo789G'7X:c5"@&"u,$9G'7X:c5\㪪/_.HNN+^e!2=HcI$33󩧞JKKv[pYEEŘ1cfϞM-]4""bҤIn>Xx@?CͶv޽{_veڵ?~|EE ;?cYYYJJJaaaaagϞFa59rO>&Ijժy9sƩ "N: !DZ;QQQ{.))Ql={n SRRzu߾}'O̴)Ռ3V^nqm~ GZ,  QQQVسgϘ1c󓓓a>Gy_͛fr*`?~|ݺuQQQMS2eJZZcǎMJJ.,,TEOY|$\ gZ˝^ڸqcffo=a{+f̘sN{jŜN FXE،&͛7 ! /rK54ܗ˅"!Dllca\\bi'O;FFF !JKK(b ңjt%PKΝ; W w*ByE@B"B(*K/õӧO_tEW]uݻ?gСCVkYYc:jȐ!^j4! 8 HOONt+`:&&&9[(!=:Hfdv!dZjUNNzC,!D~~޽{W^Y%//O;wA222o͐,YK.555f !!{a5"@&"u,$9G'7X:c5"@&"u,$9G'7X:c5"@&"u,$9G'7X:c5"@&"u,$9G'7X:c5"@&"u,$9G'7X:c5"@&"u,$9G'7X:c5"@&"u,$9G'7 o7-߱cG۷Gԩ('ӧ4bY` /h={3&???99Y6O>߿uӫ?n:!… ˝*o999ѣGBEQtUĿVc?pS;X8nܸ?X:n逥 h7oB$%%9^~t&,qqqB[ljҀ~us_>ݵ'O;FFF !JKK9Xn3GRB-9wudp40""BQJݻ8qB:N1_oX ՜ΠұjZ YSC ѷ҄t,bnܸQC 4(## O=T.]jjjf?t(XELtf'(hA@&ܦ$9G'7-"ԩ5;|gih5jԨ-[Ç(p& ~饗(] !DF%`i&CKz5UUUa/ Op {k pX O" ,$9G'7Κ X}bTWW?3yyynQ3_8qd2MQL|q{ΝNKnÇgggm0%%ۭCڵkڵk:Ž;;wlیb~!oE7,PQ!9MX,555 "n-R7W` 6` p[|"`_Yրe 4'nлw'N!/++ꪫtl+4v@bsHNn8A7n\] 袋4 `M:͚`h]qfZs7>1 .huȑ޽{Sѣ\rSޥlhRFnbf͚KSsƍ=SxlB{!Yx?=iMNjeBvjODz#y??iӦ{[no?oݺ(b !***Ν;hР`o7 )Y#xKqqq [tR_~-r-niQEAqsf#9xcf\m*BL2a ?]? .u,M/"6'w*6Z տw 4IߐF=.5T3ұxK;v?~ĉGNؒL_"lWעËGK`P`"4DXPP~իWwnʺ+moz͟/;pݍ\ìa2ZOÇ?sw^~o/vuĉYYYC 1rB7X+94 L?p7o6=zP֥^*kb!zz۶mׯ~>}deeIy͘b|:`Y,{o~MM:oYtfȴow=}'I98i~pz'Ftc07-7n8~xwjvQ91c1--6lXLLlfW'-7)>7 ʚ>}ad]*sOb ~UW͞={Ϟ=oFΝO~뭷FFF,GQ,DZb=#{wW\YPPpM7M6m0E6HZ@UjBL۷:t /;v/_?D O$綛l,QswrYsK.g9uԂ 6m?y޽ .HZhYEؔΝ;VWWoƨQ>#O~qbux>Wkkksrr׿:tH-߿>x뭷9X|Ӷ |b7|ӯ_?uY:g>>ݿٵ\"|wĉ^xaժUE8q|p:MS 䵋/}{M6sXhkŬ=-hr,$f :֏?? !u6s;SC: 9*:l9f) ,@w裏r-&IڀUl4f5(i1b< C0%Bh'X76'Vnٲ%--MF \htFıFB[4˝)\u7"ijg͚avi ĪoRlL/ jt~j.^G'7-ϟ?]l6[MMsNkjͣcr8t 恡 h X?fkэKJJ4\ '0{r s| '\rQQo`*++륙,5lh2s}s1I2(M(!`L I†n75ԅ˦"Jo;-2i445\\L#3 ~Ҳ9uGw^u œ;2}ODsꝒSMcLnhlH^Tſ!` 9TVs d.;: _9;R<I4Q:RDxbXAzsH:H4u{0 ^yt*oFK\hBhĜJ\$\l^wiעm<[iطoߣ>کS'EQ,O<ѧO]rȅ߱chLSi]wW_}խ[l͛III_~%{U'!=:hk׮>_׵^h[8pǎGvEEEBX!ߚY Z.ZHݰ5 ;illxeG=SUUvZϟ? .X,աqqqZzdu4s/^lXtfr~ȑ}&M:t; ر?XhZ;ut{Ȓ,,^ZZzW4[meeen3<<ީV֚@3-+<<<$$j'x┄*++KiKۑ4ڵkfP7k:j:x ! ҚY\?CztrΜ9SUUl5|i7&8xcKۑ4#""tij 񹹹jAAAr4<^Ga2ܢaaaSܺukxxno !ڵkw9rJձcf/tfҐFm۶fM8æ|K,ҥKMMl.((HHHW8p`tttbb㩛:%//O誨;wA222Ԙ>-w}X|_wj\r-o>X'fBH'sHNn8=Ϝ9O?/˫=zc=ֵkW \qTF9wܛo966VO?]}jݺu+**袋tl`29XBݻsQӕj*.. ֯__]]}Ѿ}.ZHǶ>hԨQW^yeڴiB[p jٳgN8SS}#X'FڷolٳB̘1Þ:thu *,0-Wo>f̘ !7mڤެAUVV|)*1 kfӦM}l^xܹssrrj_~GѱFH'ݻO>{ر` r{&M4tP)ӕ~ g̳|l-[L:̙38w1 `Vmmo1xrݏt<ٳgW\L>#Xw}wll?\VV>mڴ͛7_s5~ U#X6>znj/|饗n E^{mРAG޺ukhhw]\\,뮻t%2en-0-s{+V>}Zѵk3fL>=**J:?5kDصk.]>}zʔ)/rpp 0:-oڵl6:W^9w-0(sEy睼cǎ%&&Ο?ԩS69G'7ަ!..nҥի׸q[l9믿> f@IDATںuK/ #?lٲW^yVv"@&{0(|w7pzs,l׳gϧ~sM XBczh Op< @gLւI'E/_.HNN+`$Fdff>Siiin 0`93fٳHW,}jkkM&bժU;sS521ҳBqЩS'!D]]RRR@KATTT޽KJJ/ӻk%!=:H SRRzu߾}'O̴F͘1cvAAwܡs[ QŲ`^x!** {3fL~~~rrw6l'|ҿFs=<<믿Λ7sR2dǏ[Npr uuu>b;yK;СCVkYYc:jȐ!^j+--MqA!ӽӦ9G'7Vjjj|||nncannnbbȑ#* 7lB8MRLUV7Bݻw՚WY,܍7 !zAedd8ݚ੧ҥKMMl~Zs^V EXȄ4:Xx@?C @gLւIȄI3Xx@?C @gӂUȄU3Xx@?C @gӂUȄU3Xx@?C @gӂUȄU3Xx@?C @gӂUȄU3Xx@?C @gs/XCcbb,YTUDo %E **u5љ!fO~xŸmܸ133ߞ0apŊ3fعs^SVk```tttyyg xqѥ[ɏ6!m޼YXx_r- ?wH ɸҭGɐqqqB{MOXXtɰ`H!Dii >eHNDŽjɹs"go,,C w*ByEXXoXUVV^HO~c!`СCVkYYcz ~Ȑ!^j7! !eH񹹹#GTW @ `dZjUNNz[!D~~޽{W^(Z3uԔ~iw,h8Y0:3$K@>`ɒ%]t1 NLL Z,<@s4hPFFFå3C2tf?;x!θD3X:#`茀3X:#`茀3X:#`茀30bɤ((ݺu۷o߾}ӳgv)r{>M}233Yf !-[6|pws)))Q+̙3O>#FXlYfΜyW+ҩS'J6 %%%}B֚L&{yMMͬY?{uDDDTTT(b/}tQᘮ!!!O>e$c\!֭[ja[aaah&!XR```۷;ڸ1rP#SR4O#` YYYn膀|;v,..^xСCn-$$䮻R_Mr<877Pcƌʚ4iҤI֭[7|pǏ?ۧO^p: Mf{綾^ZWW_|!!!Ǐt:?)+++--+x7oVtt(Yƍ3LWn٬gdddfffffOQ]VWW?bS__ĉ+bjg}v !̙t#Fl?|ĈOl555^{bƍ-\gϞyyyBh{::8} 8ɓ'_}U!Dxx5kܹ3==]1c ǃ̟?K.*!oa^{5!ȑ#\ow9ٽn:u_~Blٲp @Q@Cejkk|6l6WUUY.lڵj[lB$$$?ڵ)o4L N%Nٳ?^V^^:uJѫW/]%o*5|7 F\u N{m۶;=e!ԩS?7@scǎ%%%9,ͦ`9߿QYYiƎ(bq:NVgixTTSSx^dž=BiӦ? V;]~~[n-;k{^t45BO?᧘z={DDD͞v ! ‚ 6mڴkמ9sFaÆ6^WQQqw !V^^'//GιsGmBEEŹsKx5{7RYYYQQTӧWWWKB7vm9<?0}tuxYppxOC_|B]_~Q޹s纺-:h,o {oϜ9d2Xoܹ^آfҶm^}xbߩoBvK?kԨQ۶mSG}TgϞ^vocLL̤I~駉'N:.R~qp͚5۷W O<ON BϮ !˟x S몫z/bb/BVZ3Ϩw.u}W !LnݺYfӏz)-\Em[ddEѡC{IEEEEQF}>[ou~ĉ]oZ-=sL]~G!DHH)EJ,X:&A^y啱cǪkYl:;޽{333jӧOw?j]j۷o?v8G%&&=#kÔ_/88xĉIII=PAA=˱c>m=XqqqqqՒ9s:uJY^^~]wuYQ>}w y6]V\?yoV}o}gjՌ6mΝju]7~Ǐ;V]@(!(B_p5׼K\r;w}/8|p@@Jſ!`S}}ФiӦ͛7E{UVV{I68 7 nذAa6KKKݜO?m׮([{}}lvyyE}q+b٘:iҤ;vcZM4i֬Y~Ot%I|w,½>;}^ǝ>pNEǩHS4kڵBX~eݲe:v8tP;uI41' l B8pN裏>&=nP5L3f̐]`ƌZF4ҟ?ÿ̘1C ցX#iB7y0sL@41a0,O:ЅF1117ߔ%ϟ8w_54Eׂ&}||j5-eeeV.3gNbb핆!DPPhXYY) l誃[ξh"M`EDD ZX\]UWYY?>|M|3M"B!D믿 ,\p… ޽{u.hq7&.\x;:$HNN}=zVc=r{NUidMĈ$scVVVLL̐!CFҥKw>x`!D@@@dddwkvn@+[nMIIٶm<'3f̘*&&F>aw}ŋ뽉EHq)ͨM&F 7o~۵kWQQQRRm>W^!!!111N<9 hVFIYJ5,Fp3ѨwR1YN 2KE Wvd7,#`LBgwPEuƪ?E+:WKa@,І"QEu&c3w`L*B@x!K"`*NoyC UZGP PEU.2;A pTh @e: XU'37dAx~GÕgeP=ct ~"ldpwTh @e,C!gPLwA@i5`pTh @e,b!===--K~o۷ܹ/\]]퀮6@ v?^dɸq[̙3ÇoժܹsMv~ʔ)=QEcFUUUM0!)))>>^nIIIMOO߷o_C/3gʕ+w.8tп .|7mzib+;;ĉiiiyyy;vѣGӕ">>>00C&ڵk3.//CZ;wMn)B@ m"## ***|||̍EEE:tvjjj~Ν;?3 M){d2g̘!l@Z)M?2Wqp>9shH+ `0X6:u:u>jԨW_}wϷe ŋ  `[]䖲2nݺuɒ%999lx!!Drr1L5557pk*ֳsXYYYYYY111C 4/5Pw͛Mf[AX ,˓[rrrvڵpBU W\B\pe˖}ɑzO>䦛nr"1^x-6o/k׮$777::|B^BBBbbb|}}ZWZӹsm۶oy@,!?쳆~}y󏞞~~萮4&vrw0nZM;;!`a*t@w"LU\sYRpWJօ TPf~ذaׯ #GK#V ة܏*BIU{nRBDEE)xHW9;LJ>4D͕L*臃L422 T`k *--Up*B@ $`ol WP"QHiVTF;Tz*BXH2?`0ϙ3';;pU'O?~9sZn-طo]*B`ɡU>`HHHAAAqqw9yǏ 脵w~כ6m֭bĈ K,tT\-ZyGFFF~~C1=s~;zIѣ}||<<(?TtIZXIڲejjj,瞕+Wڹcښ믿>$$dرwygxx#eWR߮~y@4 6? y_~Eg;*gw8ɂ7iW_Xb͚5={;vѣ۶mzoÉ`@e9lذ9sfʔ)*v*B@ `mG5jԨr;uaͤp???u68?~k׮1ϳ{2F5X֦UVVs=b?܆6iҤߺ`K";wJJJLJ3翋wʕ%IJIIg\X#Uaaaڡ3@Z6TVV._<44444GͼX,9g'wt钓c}Qgdd-[U^f_ur#8hѢ-[XK.Ϳ?*B@Ϝ_Eh={~w&L(,,yRWͿ?kQ!` !ZjhѢ?w۷oW.GUSS#5KOO?ya˗/7 ]p=3HT Kz7xyZÜ|_~|%-.ro۶mFFƦM-z#GӛsBھ}ҥKoVZ-^x۶mͿ?)B@\Њx@7|3ϟ.MIZjՕ+W=rahS9SسgO-Zha`0TTT(R/^T+AanN{lVVV͛קO=zAfTk2gXbӦM߿42Uq b`Z+((讻ZnٳgqF!`o z*B_ܪU+piJK/tջs3 bҔÇw%==}Ϟ=*NX߿?11qiii^b2.\اOooqƝ:uJ8 E)B@ϴ;Ex7fffm655w~ܹ3>>dɒq 8￷~c=6mڴ]_|O?S4\;=M$`;699_/,,>}u:v옞l@j„ IIIrKJJJlllzzn޼Ǐ_jՖ-[;oM6MA4B\裏iii[loڔ^z;/^l O8f٘cǎZlْ%K}]!Ķmۚy4 PSiw]Ι3ӦM[fMhh}ݷk.֮]+lׯW{:˖oQa'BN]d,\i۶yy'|' 6/l¼tҿwyǼ3_ɓ'r-鹼>>>B2;w}t`oJg}֣G'OΛ7oȓ1c~}6AAAFVcee"00ƛ[ܹsVliCS%z!Ct6 O?O? ҕ"""`0XJFΙ3gӦM :}lȼ 9@֯믿 !:vO<-[lN'ۢ; o/>˗/СCs ;tiɒ%?ɓIIIBÇ[6:tHlڒ|߶rJMMM3{5޲eUUUխ[aÆ-Z8jԨg>>FZfyYQQQ||c4.BxbT 4RE8bĈ5kDFFLkg4+Vرc*v~0xr^Blڴiݺu޽{nZj/FF[f͚5nܸ8 +t; " YP),`az-@_%3Lׯ8w=_XUYY'799@^.\?{WTTm\:#X{ %Kg6lG?&LP.BɚYfgϞBtaҤI'NlӦ"|{S=("СCvΞ=;a„?G:%SÇo^RRG3CkIDAT`؃5X$ :tժU'NyN>n"1ݦ!<<|هҥKjjbo?vը߿;v|'Oްa|\]~駹s~G,*4W ˌ?@\]B믿;zhq-Ku^ɎKb+&I$INg3PE@S.Be^\tzƲUGa])zUzFB0" UƻP~˺跊U nQEu,i(`߿?11qiii_o߾ ;3|h];w9rdNNN||bݺuܽ{wTT ôi͛צMGt}[a VUUՄ t%HIIMOO짟~z뭷ڴiå@4QEz괴wyߟ4iҶm̩!555!!!ϟqT6 @ܳpڵBX~e&>LkaaaB㉒$ !$L&y՛nnpp=fΜ)ES?<<ԩSA$ tbƌ/\zS7{Nj[ʜ#4FcJ!D``3zSN .O+""`0XJ,P󃀞9@+..ȲPѿ{FF&IdzUK `V+lDMyCz{3UBX@ЈZA,E!aU]1p3TqR(tm!OZIWd/BHLa2HWVƨ" `StH5a;V4`؏N`SeXA!YBBP PE"pI,(פeX,"T-})<hUp1޺8@8KUo9˨7xTzF!\@v(=< @5X5hci! g/B$)*Z,gHN3{i"WDp9a@,8KDTzF!K"`i+=QEgbXp>2*B@Ϩ".k1 6Xp>&srv_P"2 G!XWG0Wp,hS7=XFv.JtT * z6cԐ?Et]  `'y@ T !WsaVj>`AX{3?cQ"w~jWgXy*B\8I  Xnʌ! Tg`%0?!Rb3|t,+𕜱8#XpOHX+l(7Lc;dL]k )0*B@Ϩ"Tf)Q,KݽlI.i~V+=.$}|X}8J"f+BHӀO hْXئA,4V1 \K,4J f^X1cn z6`;PVv|"XYM<EeL‘TF͙F}U2]a Xp -[ VAܒr[X?SOvuo9mPE@[TOu\T9ex#s^fhh 5[9]LVJ;kmSo`䯩`IeL(eyM\Y|KG4kjۿ̙3I /ܽ{w+:4DE{}[aqΝ;G/Xn]zzݻ\Er=Ep.""" CU\\,p Xqqq555EEEB;Sl|xIIɾ}$Irb8ƞ={[:#~O/BHHk`)'NY6رYHՙ3gvwO6gC'8 "`]Vkد_?#GdggϚ5cǎ]tyg~gw }yx4r taaaB8O0`?8gΜȍ7:_@k<<< ecyyxxS1v>W_---ݻwo>})"IRk t1U^^SQn)++sF85\3uԃvСbڴi'p@0E 2+++g_2opsΕ1XYYYYYY111C qV8d:zhIIe X. 233}/999vZp!_ƚe˖}999]vuv؋Uu ]%}W۵kWQQQRRK/EGG;S쮢'Xf͹st9`o 3 YYYWB<3}=zt tCSDP @e,TFP @e,TFP @e,TF{{{K$IRǎ######w޹sg???IF>jKKK{''O,;wAnݺM2@>`ʔ)ݻw;xs6'|':t$I\s}?odrvH!DeebG/;$E.]$XVVֲe9,,%?sNm˗BBBΟ?Nut޽UVBt%}W)W"ZhBѱcǺˍMJWBftMXTYo{pp<θ9r ^2~Xaر8 }-[l֭g̘wʕ{?>C ۷۷oVVV[eee9rرƍ7nܧ~:h W?O?m^}^xA^^& =b˖-=X޽^z~ŵniӦnmرIII Xlb!!!$W秦z{{/\FGEE=:-----G$uСO'$$$[h4{d曅W6^ܹsaacvv"$$|BUUU-[yBoѢE۶mKNNBL4&=\׮]O:%xM7 !>ɴd!Đ!C,ϟ?oOW I{ﭪP!m|FNudBHߚLҚҥKͧ_^-}ZynJR+4j!D``ӧO !tR뒜s˅o+9=z|°akOg=`YQ몍7'L ȰqBZĉd2#X-h(@LI C4)`5wՒUQQa\ˎBzH̙3555Vr`!:vxҥ&]@`/;wk4СCB={)عsg-@OiB}X6Zv졇jѢҥKϝ;'Xrezzk.] !.\(ϓp0뮻 b2!:ҥKeeeb>ƛ_tZh1q>@z{キ9OT੧:sĉEf|||jվ}{!\go۶mUUhѧ"""ޛܹ|Ox{{Gm۶^ۤn7ƍ/^!OV !LWp+LMװa|||6n(.\0~h!ٳ75/A^^\\\ZZj-Og;SNݻwqҥ?qocƌȰP+Rd\hQpp?+8=xБr///!ŋ& 4/tM7=S۷7?n ̙3G޹JnA1a„O?tW_}ռ}kݺAѲeKs˥KW.J4|РAsOe'OСy~?s^믿 !|}}-.+1mڴu,r슀@}QJJ]F1wZuv]vɧM8r 3888%%СC~111^^^?˗름?=z3fLqqqll3<[]]SN8O}5kV~~~~~ĉ)S>}Z>?p۶m%I޽[+,F=uTu?o6s3g? ~xׇ*v׿L&Ӷm[noSRRK25}0@z `Ĉ|A׮]m9E:  wӕ  K2B.]CM:IW۩K{<9SYYrJ!DIIIaa={IԺu/Mh4fG ={,  !<==׬Y??$==oMJJ={{iX*c@eDP%eIENDB`PKl< content.xml]KFHh0F]HJv5cL X,,2%&OsؽK6"%Rհ%2EDFol[zɜˎܓ:::3LgyMwÛ-Ng6uΜ%geg93?s4@1:QY%U;olgl=7N6N&kGn:/+SuJRRC'HquJtG@ !HOIzsRG^mE]ZVRsffԓBpy]$M2 ;I :̡s~`AsAʢ;?Z#J9ie/-Yvf$F" BU*F(=e4uUI9D0?5Hi?zӡ/iXgIܪ]~-舜WJ^V˯|O sc0^v|!^`ǻǒ(.PXW?zVj^ԻMN!XٚUìML"95g^<~] M.{yWba t2ϩi(xVd~ln T{OpWYD/R9Ugt5W]m^uQYD65.V6K(gJ/Ӭ'okCr_GW|Yn^>KcI.?f 88KcIV[I 5ۢ D\ksu'Vm:?$RoyХW m<-(6/`k+S3{`u!O!;v?ŮBMhݣbJjX8@M,N ^|jXMh.$zMVM||m*vGU% i581š/0&>3?,DϟUZزjn%f~>Z܊|Srg;6ےxaLl âbTL*͓wO0exR6D.sэ6>rkGHY~f̹ fxg<oH$: 3p5 w/?孡c V<ώCDi@ di¡fIlnN+낤z!M4x$.yH|[z::ٶƟތh1k:.DiXJ\M7-lf~T^Awsݦ4HOEJrssٛMbkӥbKm"Zمu)oSW^i`Gj,q5oy3<L„ vcvl_?bO̞Pz1o^e#?L?"O멿̧çgӠ]6a4<>g?ۤt'`'O6M;4=>O6 Q8%n ݕs~ϡICs~OOCs~ϡICs~OOCC@ oKG/]ig@m'5$~̳˳/quA}s>E?nS 0}^lPþx>x} G1lxܘˍ&e9KXs)0OhC9yťQ-cz%l/=LGC^^G/ƣ$S|_c R'$=@@*|fbЛ!ܼm@n[ZvX|S!-Qd5D% m,öe%G|]hQrD^~GV]\v~0`Q/K?E+ϥ|8nz.^U7蚿"E 6K В9&6~'iU B'hW_m`xƞfp+9i+m3#?~ $>-= P-ы(_MyW,`\{٣wIz!> B2܈ަRJc$4v!@8 ‚@XKCXe s%ocFލp1%A Vz=\&riչ˰s&29P@q. <^#ўMT7Jt#$`iOaSe]< s?FG\Orjrx4ܠ2+ Q@߃m`Ě(bJqFGh,6! K-\VYMjw7תv~< M̓e h# Y.@f_1xދGTJme.j)1uD̠ +bK7r"Msؓ໺N7j Q| tX<@_֛|J͟ yѧ9jO8FY>C尥S>`~M|sIWP6Fx *c\WO  u#p8L\ߛ>ՙc@Ḳ,WāėKEW;q] zSI8 Ăgؕz2$WT#CQizs=q+8n I4vp&zFA3K@Mܞȷnogwwb3I@(:i ` )1N%K?IY{T|N9,'a9gK?&j-O`*FM"1,ؔ,0Ce%Cw,uX9 LB+ ]pK   G0넝f6 Ҹt|$mO4IJ7*؀HڀL<ƈokoq} 0(B90t!2HהX+~7f73fS'4 <`R)807W pXid@r5i*ƣ4t_"u8h9SX v ہ2,4h^#o)5n&>m5CA[sx،S!Eoڧ‰ig>$( "6m?®p5sb1#5&X<\z3Uhr\XAjoe eZoQCC1ICg2RX F"窃#F~VBӘ:DR8#ZNr'[G}x)?ذfN.՗moKBTMGapU&:|A{b#X5 R.HuB||aJtp va>WfH{bܐ }<`I#A݂{!*V"'+{W(͢Dˣf9ei*zT[ne=UĖLQ4D\o/ „ʂF+嗣t94'I-L(պcf c9ؽ2 9Oxy}RKyĄ*D_7$c L7}=LF[;Fɴ02v7/ha{ĬG-Zy zE͝nbbaq+݇A1~*`x# xf0Uf^e.(+kWda_MzQ7^@D8-obBxY˵x0;8 K׏y% {H;y5XA6X9o>/^s.3X"ƫP$HKDZQ-JmNc&W\`F v&lh'GA&DA` >!|"q dwA| M<鮀RS%F@uKDm8q\M ?c:_KTIuZNaOUjU;&cO(D2 >ͷa><|xLJgvE- GI 4 +'< I< *ʖHi@{nD$+u)ɪ USWnh% hUѮz7FWZJ>%lUJ! HO.d(^I Q#O\.WuM[FNM?)f6Q|nBT8J'F>#dN,inb:̫vН74+C;+MNT`&' s;@`ѭAɷ݉ϟ̵a*3ģAx( yWlM}/R4_&^z^u՜3Rb}m%X:檒\.Vn'"EO𫜅@ǢV)VP&F6 hPyp}'@ܕv|H)T(bwi'!`=%tm hhggjրy6uRXZTʖ[+Pٶfq/p*cI#wBuORtOXI+|2'`_\,KڹͅK .:UUeʷəf.xSk 1mtgi_SYUʶ_z> \C6F-F5fֈ0&ȳy[C_}P䕓|b mEXUGXAw1l,<- K=Jz?w%D 3I"?ɥyqZ{WeYF!Q_3IHq_M޶nbƇ31}&&tFoPKAPKl< layout-cacheuMJALDE$zqx^@PDҥZ+HxW S m۲q\ BMu]@E()]E 8xRơ)dp@4D)hQMQ|˿M|Cʝ TԦ=+9;Euh 5\Xq]E #hz5'UtiބZ,So~oT(=i)ZYj$< iEj_U9}qp5A6oPKQPKl< styles.xmlZK6WڽA53q-'kvHHBL\I|I_7BY:y`ROb:a" ޓ{+[u"2cBBRVLYkKJ%-x4cZk3!zm#FXv5;̈m 8N=eF,4dʱ"%[IbTǔӽz>?Lu,l\m*V<L^Ud j].s;@kx|4YAC+\䛹bT+_:K?K~@3# +0L#IU⺜st+niHxfߨW>0c:@;PSHQSmd#% ^eFrGO\?(;24"EsC>Pű?F*Eӟd|sESa0bq*4˞S>qCWۦi--Ӫq+v{OMr@inb~=_0M,"롟tHKM` gi Kſhj9j`fI r\m˶4-TQcRxBK-q0i4FbZBྃe2Ti Rk< a=,AsL%4DZnը_@hk3R+0,V|g6W)aTUL g1ɽ}xGr<:R5)zbS%S{z\acaz6tSg:B)HJlfA+wy)b]Z CKK\LP$ᐡ'Y̮W˛:mAyBkl_3p"@+؇Xfsqe ' v(/} 0Ӱ, {vHQB&y1܉0όD{<b]8w":/R=u.u}ş+i<8% үnեQ,fmfVc5֑ڎ+IP) Eo\X*qq@OťpժuxZR,: 1VriYj=p Z>nUn>ߴL /hNZXLj(rt#"6O?0{w[b6ic^΂5=_w̕4ǂobg.V-5y d{ bw㯲|{"%h y'`2_%4n\g ȳC8ix|ƪ=e\L}^? cZgm[5@ESΚ[9ťlM]EMAGr;FmoP17YHYBE 1˟,.I.yᯫLUEtG@ibVxث3Xq1)dʓ g|hbɔϒP˞骮Y܉kZʴ4G nwYCeBx٨bm;&ײL|ZשTuu:z:պ}jݽNVShjBeԬmlw2&O yf+}zGՉ>?дDAX~ƵDǼאdHAޯ5ff?)0.X ^SÌiE"V@,7FZ>Lhvnz6vyM{@[C9?+3RQ4J:OO`rTp溧꫻4w)w$טH#ѯ{ P܉&6@a``@Wn/&xhoŽCܲǫ7n`=*i~]Au(vc"d2l JjDd$9 ZHPKi]Jc-PKl OpenOffice.org/3.1$Unix OpenOffice.org_project/310m21$Build-93192007-09-26T17:51:152010-03-12T11:31:53en-US13PT94H55M48SBarth NetterfieldPKl<Thumbnails/thumbnail.pngV{8m_T$sJz fDIBC&[IB'!u|}| ZmY9k3M@j0+ 71mr@&4om*#m6 OZa \lkI (q0P[3['mXd*<3e~, :aAƷq{ {}*]4LI[5+ԖGFAN]at5իipjW d׆9qէUsGҍCr:ޜ2㤂<IYPm,BFmSK DQ+Z%@S&pN{.s{o݃IA?@VZM!ar4U c3Oo2[*&!͢ITL^p 'OV,/Y ;l}zlao]LLƫ"l0| 9M6# Sج:޺i9Yw'SveT-ƦӮt8!-Gm@间gVSՇ X~^^C̝m-GڔIZ'$]`ٸEcG"O 2tEcH_hEe0W#l+T@(.#_N*gȞ\!]ox.~9J!/ʿ\?3Zh30_i}!s*DMhgkz* 汸e+t3#1AveXlq@dk!)@b|{#FT=>mvk[k]WD&f w.Oay ) ;n%.B2b0BuQG7`Eݘ=뷲eA)FV5ڸrqbduj"ѷ#zi 'XW:v~<-a_nl}D ]3ͪߢL96?'P#=BksX.ۼK[97E4-I;YJF(=X }liǭɯo je^P[l5?Bx$Y2\t(Ɏy.kXR-},rOQ~*AVwdkƶ9'e"fV/p ,4FӺ=] ќALw}&)WiP /wS ))֡[-X Ter{rcq蹚cI]yv$[bp|a3~]UxqDDsNZZtcHNcԄG] _-ţ/|K%Mt&΂}Q^s#ߘE1_ؒK*A߽日ꗿ,Txӆ^Wχ|SQ6F(=bjtbWfFt!h[΀\rZ /qHwDL3JwFʼ,?QcV$t L!Fs7$vյk>=S蔴i֟@ktk`ؽ?{=BnW#HnjctEdi{cPKm11 u PKl<'Configurations2/accelerator/current.xmlPKPKl<Configurations2/progressbar/PKl<Configurations2/floater/PKl<Configurations2/popupmenu/PKl<Configurations2/menubar/PKl<Configurations2/toolbar/PKl<Configurations2/images/Bitmaps/PKl<Configurations2/statusbar/PKl< settings.xmlYr8}߯HrJ2e0˄ Ȥvބ݀7%\~Zf̲zV_N,c~2"^;`:jWn/d1Hc@kZNhPJ@",AmϫVYd#~ʹNb8]\Vkzj߮(&PUϪCِc]VIn'ל{k?p+~*$lLHeckޮ}oFzQLMꮺ-p]ώzSqh:mvV/&}8BJ4h͘0Fe ttDSB3OquJ̒J$BXBYfP}a.*-#lC7juq{~vU/*s(\X7nE)Q5{|}u~Q"#u3(`ÁG|AbN%9@\qrj**R|$a9s+-Z|=BJqaFLD|%A@sZK3Fw=U:L[gL7%w*93jaYp4Tv& s1g1 -{.gTƦRx 1L+R30u9E[59 M;ibIOH̄uN3Wp< uk 9HDI]ڌ] 9꘲{^n]EPK/  PKl<META-INF/manifest.xmlŗ͒ wů׊J40*Kfw&njwbEE놦[-Wjd~:LRP?^˧EM$3 Gie:f:ɝfi\\0vlOvxpjXᒦvW,{*5^CXE7kr`r92 XiUUNbZtDp@㰜'^Ob)q^8K]&@*q0+- Xs^ OduaU>k,Q6j]G|Jt:ܦ?r\t I(GvW5,l̀ .r4V.4"'~R=?:BR&QӶv(U{ EejLcqfNyh4њCM/(!A_mNp_3㾉gj^HwPK p[ PKl<^2 ''mimetypePKl.>-V@Pictures/1000000000000320000001D0D0271A33.pngPKl<މ5G5G-~Pictures/1000000000000320000001D0F1C742FB.pngPKl<}̸r]r]-OPictures/10000000000003200000023FECFC66BD.pngPKl<e22- $Pictures/1000000000000320000001D00F6D3EC4.pngPKlConfigurations2/progressbar/PKl<xConfigurations2/floater/PKl<Configurations2/popupmenu/PKl<Configurations2/menubar/PKl<Configurations2/toolbar/PKl<RConfigurations2/images/Bitmaps/PKl<Configurations2/statusbar/PKl</  settings.xmlPKl< p[ META-INF/manifest.xmlPKAkst-2.0.3/devel-docs/Kst2Specs/src/commandline.odt000644 001750 001750 00000063005 11544160206 022327 0ustar00synthsynth000000 000000 PKSl9^2 ''mimetypeapplication/vnd.oasis.opendocument.textPKSl9Configurations2/statusbar/PKSl9'Configurations2/accelerator/current.xmlPKPKSl9Configurations2/floater/PKSl9Configurations2/popupmenu/PKSl9Configurations2/progressbar/PKSl9Configurations2/menubar/PKSl9Configurations2/toolbar/PKSl9Configurations2/images/Bitmaps/PKSl9 layout-cachecd`d(c``d``Q2PKC:?A ~%"c#)"I+:[m>'<=vLu)Ph9eu~+'`n EږZMStPqAkCf$q%@7F| DFZnUlڨLSpH$37!)Q&_̨7-4.@č4Wm>3l',MhW!v4!n² +zc4%>P<XF%=ײh%x]șp"nB| 6 wH2o5ΙG 8C,BgV _8FfACԂ 3L@_IF8M# zm(3{ b vw}eo"V*/U'Ѻdse%upQ0regr]"4ˣaU)fҠ[L?C!u!?&H@AR]mQ e侕J2RetӶϟwiYCi͘)9PWEH]$UΌO(S)>-Ff)T&Hh3D1EEq `;:Z27 r#1_K{E?g_[/g03OKyԲߨ ~r ['g9ZzKIX!j@X CƋ9..l>BAS }C'QcKl-p9ϥj;vt-EsIuMҘ+0٫=dN-=-z_t,W(  3r}C&M w0DwQrdY+%E;Gڛn .!z^8#)iDa+U;u[} ;go4|X;~{[H/LZ;\ϠznO+F/`2O21c7;a渁ͫkې"XN}ʒ^_g&3>& 2JX]ZܨNUAޢWs (>^0[G{CqSׂ^0CDe\;> ށ (=8}}}8 p,:\s1làʖ*FFmgTM6g;4噹.bupmNpxdWܧkG)ONB<9iTkG4>~Z uZ}o 7Fi2rgm A_/=tʻ~1ܯUmc"Z gQ«}X=ٯ$_PK B$&PKSl9 styles.xmlZ[6~0To-yf;fRlwQtXtD[l$R _7)[3d㹓ԛ_U9{\Fdff,'t}[|7l%^,k*Le,bXCpfHb-51u>Z/eF5?[⃜:Y5?;h?uӷl(-3VHCI觇^/~_-nxlKd,o%OhSm0$щUnGFZ6{"D&2WޒΧV m~T q AzB| ?@wL:H(($^hE2G({W_7C-jJo8Ҏ Yxg$П>- pQBIX(5;`dJ=a ȴj)a{"tD[T 5Hk׏!)55 HaEe]F06#6KGQ)_aXKM ͱDs7@:aY-n4^$DGR3?xϛwvAy>θkDЇ\ ] *~A69zfv8 \P^TEDSt/_*pЛ152>FcߴB-?wƖ(l%T gI1K^A}vtl['$i ]$1P%7#YyAFJHT#eBsm73.%6,}W筿>믦Z?23Ό3RSYG~] @}4Ց,x+p0b2s?Ѫ.sBcڛITYW*VOT්S :ߕRYWwV+R\+usn?OWJq_)dI>Z$P/Rg-!%s˘TC{63eOl*;&fH9@պl;0?HWXg;e?d{)X+tA> N1erme nOL OpenOffice.org/2.4$Linux OpenOffice.org_project/680m17$Build-93102008-01-25T19:46:002008-11-12T11:26:384PT15H35M48SPKSl9Thumbnails/thumbnail.pngweA5۶mNǶmN:mul۶O~{;p:ucUUV9Q080@@@Rb߿C@@@Pߣ=h! qpi1aUϜK=H_tqO}9h(`_s ` PlJ?PPAÀEhUjtc&JMD[ߘFd\ }[\_]\u82"FBBR[@O00C>u/iE;P 6^H)xp]P>0*9z ܦ+.Fd"Z22O],a$%2P$S/P 4XJw.lKpUCv}/vӉrڽG~P8qg!T |!/,[ؽlNY?p>7krA(ܟ}ە"V|<`WK0!g(բ'z_c^%YP~P 9fB+ȀY9 TSD Y,:a8N`-UYnH.UY-DɲhDMWir#9h.eeA?j0;do8cP40}&PHŎ3R/.ai^ig0)b`[.Y?-2v x] Oej~n4e?{ ,&E3؄ 5E@0粡^Fn|S&zGC A{^x+5[pd*T v*LN4Dm5y`4x_%3f}mF%$Cn2 euzM@:TऔQZ}paKL#Qq/BgïV8 !=PRaoA^'{QHU^LzU'oi7OCab7J.W0 y(W\u~3i|[ćMxv'xuCї=4E(ϼDiVWkWE8??38F_ 6 >GdZ갽i]$F*6XUMY;wYA܂ʶrRןP%Ev;u`lݙH[.Dp' kp [qHPjm0XBtCLcP.OςܓnQnp}\ul&iyþ%2}]E"6,ܠ7R*TQ}`8L]8UjfTT>FFɽ’tIO("aݸy?3!Ok]QC˸rap77 cv/y6_qkmܧ9>j뵴SwW ^~-AOo9l~cﬣ%_*i7*oCG)݄ vb=7u1|{f: m̝r;}ͮwtQwM?Y5oU}xpť##|cp ٍyVmJsxf*}CՍ=|R %H0P-蒹/+]N,B+ y{ђ6tI}̦Q{ĐJŐgl.$T z-%1#РPR|~XkAi'W318\V:lA\Hl7UPu|f޻>7r]s&@LbV g'>:`]T}N/'Vqp`>Ni|׫1),> #dgTyyЫk)1j_剟 StV$2/-GԛxA`1`feR0=Mq e]QtMP{=CnJdZ^q"u:_"RIwU h [9C'L_w /o`|c)7ݰxV0D_aI a 2_)~яXW^xg^OJ<Jۣݓzyb?]|F;O9f4ZEr1:}nC3_+ښ>bK=+$o gY]/XOOYtq|`uXe=Gh%aoܙ^_C7tgI @2_;Bg둏Xֺ>:!xcn;moчY#gn\Ub5rFL7gb_ Km(}ظFs6u;w}A &&*ơDzh Q`&xNȯhU3+ȓ ;֫"./ncNAbvԟ/ ] 7{4!<\db4aWljK[>^cOE.Ǝ2ڃ'[`J2м{F_ѭoI~;Wp,1 '^rsijiݗ5Ԅ@P X  ^#תi !MB'`]%~-TK+ q:hؑSuG^F"hÛ_Ixf _6y6獄`#/kMg |Ev[ZHUiE,URԢvjzip\HQ;N3rm7M2Ff8.^9Ɠ2rs$ {k'P25T A'"%>z$h7ut~ H0x攪8{M v}#s,r.[M<&U ~]Z"ǚ H4t8uH9N臭!V X!::ؠ8]s*:}' ŻG-$)<K}VI9S-;\c靪l@^[Ձdez1K꣎S3\ҔH}7 ?iSeyFR!_~q C%X^|xf`pSF^~y=IN(2^!EA.Gz'HOK&B'KЄI?]G s {ܽ)9=/ >2vAvdy/`[LX\=U}DhwͰ)0C;SgMRP Y.& wHMo=  )A;J]3MDϼt(oO~_FƵ&C7A?0ދ_ZZzྉ'p'hhpudV=+6Z~hr ?Hʲ?|zC]Dä@I5hfvjΎ6m7~givLLRǫ<_X"4tt1،K,gvgh@۬N2 >8 >`P%,TDbEpi*'~aX1`y{`;7NMhwrk645JWmAП'*(S%`Uc ?B"~MH('TxR&;g#ɣq q5RI9r6v02F+4IZ_+r6Sne$yQȩt5!P_ 8E .?ce[}J~AS)s]Ԛ;=|,:8n bQԂ>9 a0Ђq iw)/8|ZcT&grt865. ms<:pbjJKR{DE^yCS}KaBADie1^BXcEwX 7+J}ީAlwK Wx-@8)mtz>> ]Cdf~>f3ȝC }9MLZ9PBRBSuN]=G>,Wt+!S<ZtL˰3FrL _b$J;F^Rp$x;O~0FõvY %YZ+z/pP댫+^-trLn`,yA&7QT]0t_lۼr]H2=B%fjזpCI |]ra.rhD*٪c,S&6АTkU~YkTKJ%㱲 g`"/ekO_?g]r*HB @ȓ; 31.J7'4l2ke/,>X4$B "KFPu 6); 0̨CKӮ+ЮHtL0H-Z _;$_J[n( 6pׯx{ʪGhFtR?~&q3Fi _ k(K4![@ xeq;UY+f_y[Ŧ>Vd- `X*>*I8 X,EbT|^QfiKp 3F'KۥIO9Y>ی~S'P39%{I3ݝ7;ؠHzB9?'1]Ot[ϥ; k Tt.zo2X,YF~,ߎ *Hgl/Cptd19yRCx3}yK$'G o{ qEJ :,yB2]h*DHz=m<&oߔM: ڳ3Ծ"GtF<DyWf"ЅPj.@G c4 RKQ3GcO"K@x$yILd$Z=Qr-ppLUn'; mfnEҗx4MMEQMJIUZ(1dtsajޑ5Via5dI}͊~761+E38]\> PIV2'=ɻWj8}7,fQJ0y.XMY2 GXc*0pSPWtrSVtB5A)cSp _ .O:U8ՙeYU+*D*kjEKsBB2fZBZ}#`$#L| M)E \ni)"&G$#$b8wedM2:+l EX'YdjKNRfN&tVx GÞ_Vi1'%Qbb7Dvfv n`tUa^YQfJ%=c<1.B .} +ővʐJU FJMrPTڻ 鋷6'i5#-^ @8fW"$v%gv7']09~I†b׆5MuҬ X35{OL϶E HS>>\ e8Z7{ՉÍ/P0|~s?l&M. ']=dJah#=ozpr0F #}}%{M,9kPc)~a} .1-3+m^wj{\BFMl؀jhe&e km>%|bcܹ, '93Wg:O\6"*t4g#,6A: ԝ *?2 Evx~%Ld_lF;+]_wGHIODd_|S&F҅*nzߖKo#ˣ|- (Pʞ벆/rڌMF$} uS+]VUX~rX%UC{T, y1+{ݼTҡˢPGɺ{fY)},=PeS|OATuEa& ?ǘ51ъ6yɄRs[ڃй'PRA1?*؍TS']rd굉1bh O{/ ŮƥY8-F Ր^h 0b0p [@Mi9 팏nky܋Cck02ndCp8· eYZSq>c %0ATIAvCS)K'E }yd<!Vl~}[k>O,g_gƝZve]<\-Vf~_;*$iivl{OMojY@&98+ Ր%CV~vZ}T3Ӷ ZjzX^ZCY\CL}1t7޽$Tb|8o;@b޶NnOOQQ.W[Y nqpQ=c'k+[sѭA@ER`d^6GM\ Eḟ0QYNj zn3H-'3j! p%hl?C_z(eMB><WnNGf蘮=vd}PNɬ(8?PiޣDi%WJAƏ;mH#cZ(Zy\az9_O姒'囨Q^dn?J2Zt7>E֦UcsP$Jk ;Xuiէb}cCў,;nl M)PQt\&E#eqQ*zN4X@43} m%o8{%?xJeh6h@9j { ]3꧋3Ha-v)h }ޢnoj8U|Wc7_?BWRzy 6Lul>AjX4ͪxQr@jzܾE= 4ު:)fYSjHN#ه+[+INQj=0x' u͐~27(ag1/eVn"v6"j78uxQӉw@`6h,T9;<0H4įp%RjKw(FxZ.qJQ`V ~PO'4?HszlE{p`\x..iggg !+0TkD<'Dul#VC,Ez yܛu!,*GH߳V@6jDqtߚ] 9>d_s_D_upשn0}niڬ(9Y?eRN=omaOuSsqM#ixWYlgٍx?YEuu(AT)ǻH)^I [Pfh}VQV C1!ܖQ*Ojb |fZc.UI#e J}fS@N 7AbXqr~he<r<NJT>wqIIz8=gث9 NRlKHEl SjPL [x-Xp06A3d0rP1TspfG1蓂Pgo .98RHߴ[kftvs_I[|]hרS|B(_Sz.zCBN_"YY1잒 ~J2ƻ=ە4X+ TpC<Ï 福P|{>IBQ9?X,RDP>rRW{mY]  fVibސ)I2m3pC}-P|ܸA6hNY3 . RT_k}2m#nH*k+p|,oj!p#u'<]:ʬה83z!}a[wӿQ/`PFPntqEd%=m؞J KtaKNCI)VU-$6'Sy\-)DSP_mm|R[By:yj$±DiFU+/urBW[?WyT//gK?RNxnEyk3'Xz}vtm[eDRTG6{Sd=x8;La,Qw>I{FVLNR`'+nQhLoFt'y:&Ejl@"}c =U}jk.$x!o4w\0jlഺ E0CAQhhڼh--m 1}i'WuY2~X>WD.+PRgY }&љz,"r|[0>%<LlEm…7Q#:u pgW& Wyv m3w>_O%g%B8͛6vYp`I dKxǒN`#^}`=pB5sx9AGO9 FX .X3 䟟<(PS _V,.>8':>IǗK&X#VSb&NEqk S{b8zgy52Eeg(39dpG?ANFO\R $,ΈPª fby*ea&e;`x;'{mуr2Fj4vg5: %33YbrȈ17Zf$>+Ti_ =w7 X1xD[S)imq Do*7nw F&)$:[\!x50 B#-xţ09@Oz74zWtAY̓!!ušiB:JP}@D-׷clc8)oĝ@(m}6?g;# t7O5O*7.n4d'!lNy8-qP}6dl . bw7-ۖ oE X6 dl{ @3g ^{ 8zo8o+Mu>6s[x1O_n\diF/ԤOF(+>73*_C8; hbě#Rms<\%;ܞTVU|>I.bIkbEڰFD"6Tf`k$8ZA0#mmÈdߧ(z>ENAd;Q ~

8XqtqF3F{x ^ՋY@)}y?ۋnq(mtmܨ]ZO9U%h^p8V>Z Sӛd5.NuhK]r~]rHthw5go#d~Ks ,Sm L;]G w!-wb'Ɩ:ĘhV 4=|zǓqR&~D1þM04l2oM6AHb(vDlڨb4M1kfSpz49s^SxښKԫ߿9ZPVNJx|nF؃M 2 pݍD6\]'ciHntzdP^4 Ep W^6>dSgw_Dfz6}Bֽhng/sӲDWYb:ݒ;'OO{.b Jv)Z}۳ ;$kFA% |&pe]j{5|[{2X^VMomF" bOԻ0VurPĭT & JxgCZ*~~5tl~2kƣ1#7TSMo߃Wg0q! |i_N([w"og-SPN Q%ےg6QA)}jAwAb0#2534Opʰ+k >ҚzZu}䠿o /`oX9}3a %܇T> |":E,l\^]ҏ"bS#IL[Blg&sf?(Gb5Xe/.yl6D?\qU'=5bM ӾgvZO }~ҩ;~,8cZ R=zoE%ٓj#x2*J,'Eab? 6"mC4Xq0!͍.Wp꼷 -kp94ܜE?FSbvxEz@5*B5ӣEbTfdB,9dRW*Ǡ[J0k_fjVhvݮl9i9&^Dנ{]/yJј什nRBkGf)8[C|ϥQi m5"6F,DK?h'Y y$Q\^SQZ5,%&N5~+}GN8U6mrLMLA(ݿ^t-CYk  ׃E-Ebe>I%W޿ojh = F'&3״z)XiӮ[&Q]Nڭ]Oֱ!S}~k"DaWѳ2mz4gw\u̠]{Ożzɷε{wk]U8%^`;9 RWϗmYke#?\ԳVBCwNx.ѯ뎈7]Zc.{[Oſv'c]Үt:|kcԖYcc.áuS򰭽Ud|pޡ]O>~0h㚷*|=:k lvmtLLT|.\cy y5<1QV[/pNBs[/05)ML4X|8J8"-o+f<_/9)!Ў޻=>~dý,[>e¢_vᚒ3gyds~SVљYlXq'ລUF 3 Т!3n1 m<]\9%4PKƾ=D>EPKSl9 settings.xmlYs8 ~w W@nian$r5Vv ';BҀh[d$rO^AōW=x'  #1Fҕ5N&QdBhMK m)TA5tz[U>YHx3FX,N(j^/۷I4WU*D|Sd6*rwk^s퇵LAS4̍oNh7lFx󚗷_ޗF{7zӛHhY=կR܅]:?LsY/DYՋJ )ʠ=cb jC^S- .Ks"m_凘C!Wy.8Ғkh>+~BZ]Ջݕ+WRU4 U\mveyvj\zA?FHfPN6B;,(V+sY C!HzP s]t_@?4Wx>l(1 ,2z{aGDoKZ*;|eՅۉtM& 0!&2š/ou:p+٢7OamǷ2=&nX +o6ӛ{nR~{rWPKOPKSl9^2 ''mimetypePKSl9MConfigurations2/statusbar/PKSl9'Configurations2/accelerator/current.xmlPKSl9Configurations2/floater/PKSl9Configurations2/popupmenu/PKSl9JConfigurations2/progressbar/PKSl9Configurations2/menubar/PKSl9Configurations2/toolbar/PKSl9Configurations2/images/Bitmaps/PKSl9EThumbnails/thumbnail.pngPKSl9DUl [settings.xmlPKSl9O5`META-INF/manifest.xmlPK(akst-2.0.3/devel-docs/Kst2Specs/src/Plot Geometry.odt000644 001750 001750 00002504507 11544160206 022544 0ustar00synthsynth000000 000000 PKH:^2 ''mimetypeapplication/vnd.oasis.opendocument.textPKH:Configurations2/statusbar/PKH:'Configurations2/accelerator/current.xmlPKPKH:Configurations2/floater/PKH:Configurations2/popupmenu/PKH:Configurations2/progressbar/PKH:Configurations2/menubar/PKH:Configurations2/toolbar/PKH:Configurations2/images/Bitmaps/PKH:]-Pictures/1000020100000481000004573171E9D8.pngPNG  IHDRWgQqsBIT|d pHYsgRtEXtSoftwarewww.inkscape.org< IDATxwUCBKH=t)"E@H.Q DX HA:IФ$ qΚslmwk^3gΝy瘻#""ef ձɅ~@#cf7ױɩVGDDDDᝮPgf+f(` 6TirZ\'b=tw[?j0ުH VUD:Vff&Iqzx x"""2($f8 3,` ,pwt_PV.&~It}8E;!x;1N-ڧ 1f6 -Czx;p?V\-EDDdQH@1s< ~2Nf:zw`Ɣ͞v4±4Y2"`Rw&_ؠIw0}9-rhq`X+ХUE=<Hfvp0j L1wq@=NM,>wLi3K΢}vקW6Ny/o3 89g k&af#C ݼ*xMB~`BZM?3pTgEDDdQK &+ʋyC>9QA_v歲0,2^ଜ%xJ3r, ,O23;8@9jmh_"t],j`,<+b3*_ˍveg"@";ρ_ qWWOR7twp;-A:tS>ln<_2-&+{D9f-9_Ӫ>SÃ/WHم\\Z≈ I3t"%vȚl?%SX`-"]ܟ3]%2d~!wᄄy.4amt3p"4G˺+CS(/"""5PHAY5wؔ>8xp3r'YwwQ Ya-OٱsM5? K%LDDD$IA ƭ|!& q܇HqI']8jW}slB,vާIjCA m_е: Zp4))_ty"l5ҁ_Z"MDDD@"(1E^&"JoծH٬ 4 up$"""z 4nLb-ڟ@" V5ԹCzwe˾ﴩm~DDD($Ҁc-#-*WDugyĤǙwsUw'po'"""cx+ ңFUXqAv%Vem۾dykgE+CNj@"XaءO$$Rl`U`)`I`&F>Mu PWwңrqL mƺNճU:?@l`` `8$ONӽ >S6f6ا*nW];-6>h-bptnB8&35v+J0'>, Cn~p26'|~6s]{NYvS+f6o XJ7 $ )@" pIf!C[\q3_R_2O[U:)~#}` L3suff`{N`f'fvv?Qwe[!x,Uf?߹-\K \mEZ|hf繻7 rj,)wߢ4icMu;}s Up<|e IwE'g?K_,XffDw~ YyA&~ɳ{wWNs"Fn)@.f6m`*Ntiusi9RfV눬%] ,^ϻFlAqw:`fqyvZSfw:VD5i< xb:+7[CY˶\L,1…e]_ǶX۟Ug0 p(0Ϡ4㽆DHj+sp85@3  M75=ҁsTM^PpN>h~+7oԹm˶<^S)~ͩz Okq3!rqu{&Yi#gOֱ3m7qMk_j܅:}ҤII-Dw;bbfvt`6̶u'ze`VJ> X̶pgSŧ+'Vyp |Dx[iftzZ EKVYj[jQ-J]JRp+ &r~BW2hfwwoI=ڶZP=U“HpVKY9 qSsf\Ga,yz`M9SrD~x3s&d"/CehuGB 9.4OW ru5g/-K,Ipo^Of &ZtLu8Jl; p,0{f!3?*%>A~2'P&5WdLUz>df3[oB+.»n R] L!@WMD'uةP*?ft xW&]+z-swFRDٗ$ݖ4* X5ga #qV<3qX1QՁ*&H]ϭ|$!ؘWNq^Khľ!ʿ)gEB>[i֯w]4U]{iX&MJENx^ê0l3|xY#y;w#$}2Qޮq$j$y>V?A2p{}u \[[TkYZlI~_.}>O.v%+渐aqC'xh ۙ״TJwɈS2ge6!!a z10w?ֲ>BP&lzWU޽Pwj){* Lo~.!g[3k&䏘z{g ]Zϻ8w~]1-7*7kJEt)-"- H/5n$^5lߘc!̈́ ]Euҹ'!`%F Û^y}+B3}N?%cSr$.*w ]>3YBBۺxx_Y`PXe==u:xLb7Q0=tM׏'p?ъnt[ߝ"f΍A"L>:YC%t|%nm?% _Y<3TlB k G%$&8R#uMl_wC uʡ55ijX|w٬HPHy[c8!;?fef_C̄ s T%Iql~ v1BOܽY?"19gfZZL#YSR3[tKyyJBp+k&R^Ztw m^x^v;` SK+ݔ]ssq_?uH;)BZ|pZ)-uX|2K28v4Xfq?ֱ-5sq!،M4G"ͦH[V-;rd̊ N6X@LwnJOVމo'5P^itO56E'D7%w@'Ȉl]a}C1AfFSJj:H;:듒zvqіqw<~SW D:C}86d?OvzG>wffS10eu _A9'}\ 3 O*fూ*7tA-PaYQ-UCA*7 %P;95ڽ*-ZaP:[32 d%Ww-JoRG@SCkM38ظS:E)$auYYW #,SeY{{!GP#O5{1ge rtSrц:ӆ}`F,QI{MS66 ˆ1wcʬ՜8,L{k*;ݨ- P[}2 HG)1Hq(B>oRefh~vt7ԨXPl[Tij^0**ݬyT̬gkFri~ߢ*3NhiI:W*Ωݨ>}פ4سʶ_f`sݽE Lf-!b*!AU#VΩ/pu*囘!gN,~+ Ȁϓc"pgw&nJ|=EtT:vLW)]y\zM!}ẚO1s̎v+! HsfvpEb>=E>l&yu+UydXCK/I:ț[]E:R;+R7L:+t#*}.3黦+L~hQ`3f:!`=2($;Hp+~4,m7 tR nh/So? s*HijQJNtLws黦 ll+?V!Ddf_53;>]+13(b|env_!}a>{b /UX6T*RH})@Ys:T rbkG+&fx 3ةlŭ@"[ؙ0-_*Om{@t)1'ʂ͖ .@b /"=LA :0!1?\K%fXMmfH*361`Q;wXc+,+tzM,^&䋐:} Ec+,#A|pxZb˻9!8DJ˟/1w² (hVaY]l]cfזM(|i >[>>?}t5w82x.6VY&Z5fV-Y)|Ik'sJɩ+,+K9S&> `T&"- HqZ=ii-Pq8E$nݢ2Zzy,/p?i㲩lzNqkfsa>M}2"+L/EFfbwʦg>q.^Hu]:,wC¾k ^?4ݟK,fg")bfVSMֺWbC?-xC3Ѳcbmݾ 쪒䲂ʖĜP\67˫5 8βK̯:"hfMT]ȿ }yZ8- U=_+8x Su$^ E|LN̯x1%2c^ |>ںl+ "2ʅHyݏ& s(JeD{tI9G6[|13x&uߜo5Zh h|?*.Hob=(b[ ~^pf/i7?h6NؙL:WIV*а5(>tI H*`5[OYTY̶` B\MzT xBPD17oY-0, IDAT.W$gf@3[f*.6GX;hRwqbƷ_>3mktx(w/N:?.i&0ɂo)¨͖=vNjU~'[X619!x2qoI5$MV=e^=7HG0ղmߧQyC1 fg$,~t/L"EH*3K%f't1R~ _l5$dM9X+3lw=Xs@\XMs*`/&p-RkAf6N,MD Jpe2ϝq_`$ƘY9ǻFP$w]^ qfvt3Dl^3tnsDIwklz3] E[n}HNK%0O=`GsIkfGٰ!wm|v &3yx3nf?~YI% $՝>ٝVgh]ǓίU"CkB|jHhyq?j,HH?Pc=$?aIMrdʽ/V$8̼[}\|2xR[a~5`-U >P񄧗؀]n6rge/LzW}*[<0 Nֻ {^H l6d. 3[A΢ R]k3N̼710vIζfϹݫ&ɎY74'?Dg/S`[w̮ Тfm5RBAB.W s.{*d[6ޒֳZhOj!Bw5wS.`Yz Yv+yXS#tDPB %{CDp k/af=5/ C̝d`gw-I螻lbc%?ZWܽ,2lnc}@43{ڮR*ߴ0eégԲb ؿj"|Jh5ᜳ:vfU2-up;}2}ë*q7?}0w?u6swM451ZjHx!ƹ)`wv),2+l<~XV6tl15BN&t=mSY+T U &k7P' O;~ Vxo FQ1Z%>ق/\\@=/+n5~HlL嘜rkfʛz9Bf!a9 E஧Yna ffG_"té9W8qtt%+?ls|،0qOa޷$$ԳDpZ|@ٮoy|=wxmNN1YFWfv+l->˺ewDDZ(6]|Y&7/J>f*B6Fw~,Xif63!!3Ftస,G7߾-ڄn!1}I{9ƺ:S-L})B9-[f$Msߤʄ`K阙bc"a ]lqSV E 0^'| [F17ѧ J܄-4:UL@hBWɄǀ;.h"L-oT}Du)=Mвs{HDDDn%O{*8 /"RD3KBnW@""X""""0Y8CH_yV.O-O%Z@""""0W Յ]dhSHDͬe(o*lVF;R iu~f l~wWK i93ffsiT D awu5n - 0,gM+"""RU Qlfɼ]Kj%"]EA w^u3=oMt3pY3iH`B3[ةl (!H_PHD~gf3պ 7CSr?QDDD7F30?QA[j%" H73-Z4GYU`+wкTu3-bf3H3 Xl;SEi7Ӄj'{5i *lso""""0ՁZd^M"CCċHl l̒Xo|VMEDD ͘3CK ef HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD($""""""" DDDDDDDD@""""""""}@A > HPHDDDDDDD tDD |UV{v 7 Eկf6/0*Hf oy&6[!3XI>"vmU6kzHoPw0i֫3O2[x:^.vsOS;O#| fm;P HS}dG/@Ф8߀ߛg=uBpwݏ~Vl5`UPDDDD HŠ?fHYf61J9{5+lflzv`fs٢f6KݵPHDD9k5Se]d3{v9Js3{.N6X3_nf'z hf3[*P3[.57 3{N7zWgd6}l Т \ASԸDk#cy. ])"8=[ȳm9Sfv> l(O@q& w[;3}j0@CċHhf3=!!r{ eMH\C=Ah]IM:mU\D~hfsەz~_X*e$3x """"}LA i :X):wRf6sl% [Z' |̶C2g-Obl"""""($""s2ȼa\M3)9 B:l2 ,VgMl"""""RHDDY6 q2~_nf{eS/pd&(""""2CH7Vz>-^) f6 MrVNF*y-yd0 3+u?ٕfvTnf3U'""""OOF*ٰ-,_~@Y&șX])1!$3T`33ˆh%Yi3p%r[˶̆ޚP6It}^F3$""""? HSlN3-c7 ۮ-o)~ܮ4!pff{3". 5^eomfvU)@Jc0:7ٹoپfv0p!]f(}2=/*[I3_DDDD6BH>3 8*omWe9vɘ7! (pV잕-{4!a$B}bv̶s$?W20weYY, 't:_Oc ǀQ?U9.NHLl\uZ w HPw0> >ifw"""""RuQVt;\%ZH=v$$WVHDDDD%f' G> X6oD.^ë"""|n l`mחHQN ʼno)$""""қlG`]Tw;$H `*H#Wѝt=wV +nwt}DDNWBDDZGY:] ۀ%ZIDDWDD0\>u)$""GVEDDDDD 0 H}EDDDDow=-^mׂ v>""w""^ Ȕ-t%;٢]t:H4[jbf33+37K٬k]jHQw0)w08*3{"3B9-if3lN?Ƙf$3gf9,GX}kfB*l3{vKA 6 \^7v>""~, , \`w?ǀO1=G%oÀ{f6i`Vk2c g>F8,03{̮.,@DD3LꈈHpGG0``qw>ga&~W\txm6'p:T663{8iݟ/ZK܍l>k2,o%"%teDDQa/{jV#38x8$*sP3[6?U&%H3 ڈH::f 3[YkL[-_ݏn`fKG|v%O?uqނ@nv?7[58D$tk\ X xB@Dw/SƂtaf  \U&5wS>_H `B39H|#7p'Kw/w?<_NYG>U -~V 3؈pϻYl\oSðiHSHRK %08teDDěk˯gRgG AMs9 x07Q<;z!p!8hٲ M0=02N* n^g`ɱsź/Z^@3X ]dfY}ml߸q'뻨%N'Zz ?Ӏ Q|x̖.[_q'jKB!is-VsqiLwcv?~SDW?c]RD$} t>yfiv:wt.""Cӕf25 /t?2lRBe?Vr-3ی&puOx_+? ,'qeFJ}Qk%8)BR*u-BK>-ߟcXm6sKp/f&s?gGw0[@y>~#`tu$C`sw[f#$zbu[{}g/\|c}>>w3O.c:'m <y/rYy -j $"ҧlT7 ( V3g4-c.f"T)J-q^~Y/KF|;y%fɥsp(=Vo]-sv^( Z>W(2ZAѭcd'Bw7!GA  B?߸6wJ"mD:[)6)>hK IDATZvhk\;@ Sɗrna ^Z=Bs=.SCa/m_޲bf_.|d'#_犉)ټCQsYi{f%3-~f/YHOPbh>C """8Bec3/BVcfm`g`]nO~W0v6S3Y ]'G$V[A5Qf{ff-df3/RwRLdf2$ܸ~ = l ) OA銈Ȑta%P_Bcr} 8"=o#ل0% cɞ7aُ"$>(5QɎf)mʝGll%~9'F@1>UO?e.gfr쐩JꄼDcX%s_~P20ZiYZBUBkFZ-`""}v!"z3f澝0 snr. rB+AAlM玙3&=~ݟs\`_3{0J0¨cG=9^B>L%u+ne7ٱ Ň*>|Bqb2=YqwgYy3ۇ]/׸SfX3;8ؒ0r^>C:fv)!5gi< |%n#$>Nwݹf\8Кjow?{g&G,@  ,Ab,.Yd AgkŝAKǹLdAfXmIDZ*6xv/l~ ^WlWI.!ia"nfc%mG4-cg*f]pA7"@I'!3 mOOK&;мMotPh$7T WKJ:8n oC"e5Ѩﲆ (", iM!fo?5֞2.jKrA q[IG"yNiCqn[G˖Xt _ANtOtz,}p~/]Uzs*>xZRRAOP)4#bDҜfe# u(`"GFfD LHp&2y'Y8z.=C PZD\[`1l\(.B8 &b$8 )u =ćfl,pkh̶m4چ &6  hW) JA 3{V~,Ӥ'p?[%$_rAAKG7+X/X_c*۾:A0qInC[}ײ"^IO'guA.4-^tS73:=':wj\ W3OsI[3ͬ2b'{v7yA[1Vv^T:]d2Ch%`xBk~AAP.&iC5`g30Xx !tI:; lVX~0 .v0>;E; :I +FAЕ0tRu?fv._oG*SI7H_ & DRՆAfv^^:fj#Z}HR4f9t=0"/sDFz8دAtY=`mIƀ<I3QB+_p<-4̾h&Ii3{?=MnfjG$-[t} s (%@zRr \PlgfHnK^KR&iKn$I9e7ZxGfSADZ8F7ژ ?^HXch7Iz#ffL i>& 3E3/0.0/ޑLS?:wM`.j|b*N@WI31bK-'v4XҨkn2(iE9r\,.afȵM}KcmI Y| &th:1xTɮ$Mk{qO²[`5 iVP\,:K[Tr$Mk $MS>S39ױ)5%{-[s)#4]`f1f60@0  O')CIJG2m{#i/IJZU郏Wl! 2lIWkr2lWScf%{Gظ$m-% e-(Ns2uC7Mii'05 }s99m`l/M?x|UE$.l18njqVxZI$9x{JDN7 jb^fs;سLJ$ l M0ʌ/Jʕn+s3?⳿s>>qQ4^?x.Er;Sl9DHD|z i6Jc+G)IׇGG뎶0m4/n]sǧ荟ލ6$& S2Wqf1607%Waݏ [ݐo@wٝiݍ߁p鿦 ?O`e3+i(bcƱ-,4N3_ N/ϘY6s{hypf(.00^j2~S BvrH?dfcד*W% m~'=DmO@~}+IC~M6sJIs4ʵxxFtA'>qF f>pUz!CVMIz#fN݅ +] TVq-ZR4Ҟ,,<YQ91+Įڶ3pݤpG^xӎafH(F@ۤmJwfz7T!HDrD_scܾi]h6ǫ#=\- "f6*AC1o+/NS(IONWx>Sv£ė#_'N& Sj.6Һ埙~iɔ"ILG.} 6^ pe_fe~< 3../x$fX iIxDvϻ=~+⿕>ot]DizoѭgNWzڬbqXyfIKn*46D‡fkfbJeoB_>?V3 OxzuN::;i-qpO~i$MK9EL;CH3t`UĤ4Zn]N;eV푤z)LumrI3a:wt}l=cfff6.5%}: ;%.inHO]8X78x$mfc$Ǫrg^MÝYCx}.E뿙+%S8Nd wh %*ٸ@<`<"rJ4ٔ_3(k }ǿ[{wI͊T"9'jV{xx 5oS:/m͖nOW*V]VuTe ㎗rW4KP3B R:~? E&jfIz [DR\z$͏*dAGquIwHi=i{ή=s/`l :86]뱭 :ofJJK7sMR4wvS|0yf W-w_[=OffW6{=R~ΥVv2;^&`g3N^7)t|ƻ͓.N5P8IK1}hf?O+0x$=[G-[)iM\k.A{*f`\,g̳( Tg.?Xi-E݀l +blks4>09pZr:>GݒΑ4P h}B%xa f6dܞ߅;͟Og͇TD5ET>_릢Ɇ&^" CGR(IsೣәY\t.z8je/<%`3Oc *'p[/p~4IUm/3fĝBԙko^?< M^I'1~w]`3ay K}ݝ~_ CS;p;~nOJ95?'~6g7i +3jf7v=ַ?m$*`ɃqjYOԷI#o Gc~~>?])>40^;כEM Wxc% 9\Wۥ8?)g{ߤʸCh%3) ]">MgE3t6=vEq"γ4˭kv%A# sv4 '7qQE5C]W4<`<ڴjQ<U V/'s#;V&=f)JǦ(mKlcnI!o$eUn>1|iIZFbE)d~%<E|^aq€UI_Ҝa*ٻɈz28$i2ӽs츱vl3j>ۜU.Zк̮ٕɴ3 4xmfvQ#+IOq4wH;3s?YTTT]MN(ݓ2Gݖƣx9ĝ@Prm˥] goӧwG; i_BbA0H`M̷p#wX"!tIgʜR ꎙ(i `wZpLJW:jȢOGHqxU9^QIH:Ϝ}{;ryYfSf¦ ZAq%ZQxT˓n/( e:WiLD[pamxHwܫ8ցtwI fo?eaUʸRfm'w,.6%ݟ_T-W̮H3C$]'̊T3K~OgUo /KzI)=l=^DAtGǵNJNB6XnBJdܫ*42}6Aō-IGZwjfH &zQҽb~ q4;`g*\H|?g0R>+D)ڱVn7_nYfSᖨN'~]h?Vқlw4^`t`[|.MIWh$tq(+9-SN>`*Zi y#:@IY@rQNS|l`*׭F1vPʥ5OˉXɮmAP|"*\(rZx |̚9r}\*3|Fq&\ z1PټYIUge_)*imI"3Yu6 AOi*iz=a^ѫyC$]q{xkxlV*R6:(s (RqS$sJ5͖45,v]kIy%3-mSffvqGw1uҤ`u0IGYU7n#IQ!(ٟ LhZ ukڭJ̎1e1aȧLﱵjh*wL; ]RT(ҧ*iM]h&HjSz9awp3pjO D3A:C!)&oy\[LSdS~J}K t)'PF x2ha{!n-;65-%ZjWIakpeNh1(~dTh]33 ZM̖6%i%A_kƦY IDAT*wT"M^wlWo܄uq'POZ, @=lZuw2}$mW(j'hZJF>YsZNo)~㺯Xsq ZT ¼ZSf6̎2f̀t/gFヒ] 4bv~6W1kZhvB+2Y>2렼xf&j_y{3܋RJ SD͙xjBc0E3_kLq^deIJe$]W+m9/ljKYR/I3H WnEvvZ='.T?I9KI]LjxKGO2!\tt^4Xͩx6Bj$i$-"w4G)s"id8\k2,ߡoyZJuɕWYe\ĮNtL̅xֶ)s>ÅQvfvk^6%ML}..ԗ]GsbѤ95VNNA 'P3DweUjrA}xGҡUqSI_'_PY尿 < fvp'v9VBfq<4kXmyrb'o;??ΡqL-?=h^wJl; +R'Jxbf_IZAx6ٰ Ycپw\l]?G5nwbL ifqVaY5mZeϗ=w\x .-k(i~^į;Qh/<6ّOo(iI6W0'.iA#i g4ɉ穴mq] L;/Vɵ.s xBf5E:9vv-$WC_À4|"EIKKZxX80m{==;ΡMs!.Wb1VOD9m97I>,,x}.'8!XܢAL$ y_lP[4?* ݐ/\of4^F309qaOˀF_٪e YV8p[ 3}`f} Ý3k}iy}3;AA)+X,Ofd$M)+קݎM0Nz͎Gd@j9֙k)P+M-We5CRO<]k5~V- R׋$ԶE~Ux5fL_.vT A 'PA4-.h=AA0|We]6k:8(=/llkJrb߄ %)GcMȿKw@`9Lﳴ偻[4#izsj-kWT;f5/6N -ീC l;0~6,Iu{I_5[ڦFzY6Mz%|g`3k"x-i2Gik;k{5.CVrR ! ݈.! `J<,B> 0e mܑ9,(0y73{ywr),-( }m^mxu52^7GQӨOҭɷ]^Jn0 p.ǵkƋ0fk~7KӅu=huʄw4 v5t.7s˛ CK w/3;}x5쳴l$$3X6R{l2ǰX:XI{Ɇ/A.0tݕ֏CHaqH W:ɕ1O$'蜱 p1~MhzXYR|TmE.oat4D$-;–0}&a6kJZ&=@ I}RۡVD:/qA+$*iJIGʞMm ;t%$Lv5͝πlwHZUBMMˢN ǵ?Opy0%`;Oɾq`WWZn_PmԠpAw2lOJ)6@AЍM ޚ~Xhiu$ glY^Q/sg,h66+j+d5>mGQ45'' n p ݈pO>V2HL NCҙXFHٵ6nȄF+*1_XN8) h+Al7xhvx5 3"}9q5$MR `B49)U͜D L8 |k0AP3{K"  ~|H A4i `v\AhVtjRcI£5FA01af.e?%" 讬GSGxJ? hTxaVvI{4֪  j D AqL]fY"0I;'K[Q~`  B.L3{vY`ܢl?Iv3H XX /Ap}f+ޭq_Yu1#i9`G03At'K` q 茔Ӏ ] `Q@9]1e}mx/-GvvHZx wZ.']if kzNNAҾ餳;;NhGz vkfJk$hϟ ALtx$P9NҭZxEfq/K efӪq [;$gP`39ZIKW6#:rj}`e@;x+ 'pY 6ٯϋc$|if4̸ (q )>pmv"$ ,>~of5Ҟ LOFA}h&PJz wDUc34 e$޹5HN~f3}M {fv}h[ vOKhYA7m*dQ3IGJz^{_]d`Aht y$@mk=SfEqp,j&S_a쩴~zr 搤s4W4$-^x"uf^nM,:Ò6F6~>ϙ.mfOs@Y-SfJ㖴0Y 0xFtTueɮM˗ڙPI MsNȡf66׺oo6.ɵ[ץ x) \/(~of?H~ip:@?i fhYA3Oif$ 0&^Ol(KKķ :3;-wiA4:0G`I+Y:0psnY`{"` <{ KR?礿uUܲR~gIZ:XZsB#$k3G&$Q;M^ŵrl)E` yLfN.}^#}k;UcuYr.|%lE%&-5#p;p o#wg Jٶ'O.'*x< ?lx}OxO_[8A3gfGnfm]Af74xFtcJsgRUi?ӷ0F%mp~)Vf)9_Ɠ"B3rƫOz\ݸ3{3Uw`fIw l`fc%2pY*?&}кRf%J9qƝ+e.=WJ̾Mggtt4 0S:pIA;5/f7INҴmSr^;w݌J8JҨ31U[a0I#=lL)XWY,ii<^3۩p̶-? AЍ:?nIA7oso<tҸyT ho Вū]Xvɡp\xr~݃;Av(T&ސ4 5XMt)bYP_;?irە~0ʇȵ?5~~.?aa49唞w^ I=R:=efcN£NHpIO@X x6At+RTfv]'$N]I'H^4uyXےn/'2I/Jz&L+$=!i$d햔4D)9[ב;y5vxZ7Ua1}/*IJz\҅rIZkdiѐ~V+] w^4L.mP9<8*L?%=*ioSI:ZҽFJAmAPg:^>^!cK\ |#i l鉧e\iZ_4axu4|='BnӸdj?KcQH 6zؑ]df jfRgkִ8;fzOx\fKgxZ醻)Ӻk#A͸UҌT #Y1`C{FxI;brN IDAT}u}^f|W*}~:}~ %#ٲ@j7x7-[Gt3ړ6HZ,mDޏr+NdIRhHϳڟKA܍{ZXGC GAt ĚӕS²ȟHX5EIW3D҃0wqGE"Lx Q{j0[zO,˄YW$;Ti3/O)~>Ko@啢>¿羔n\-bf_Tg}$+Ulr~t%pX^;*;>")r{=Œ=.]"] pljf7H&lK7l;tNt:65Kޔ.//\n3#i}`aR39~ɶI=;n6 |u%IDZ>YseEoF5#Βtw^3{x]`nb{y|{pdr);C0s4_4rVH|b{#I33 &HJQ@ΠëA"=RXx4NdLU^'GnKHkȫmm߰iSFɡ3-yI,˪!|_C9Xg?.jAc̎c 3!o*oW3> |;^W+KV^a0"O+6~&i V`fYcy> ]M+ƵO=;[ZZ+, iM+އF7[nBϢ,ʸ Ko39~:ek|4NJ8Yu]É,VJ$9T;,sF\ LhS2OV3.9|W*lee3ZL̰9fHboWj/鷒sn㓗 )}޳㘵ؾf;U,t |'xH%J/fvuOG8m3!iIRk@M\EGVYMFN/5A*MH4t;$//b2#.]/.Ƴ _; %Y_6`lS."l?{'²lb{ܲ;9XO˲( h Oq!5۵iM1% 'i4gqy~\tv&f4)m=X-⻫]uYxDH mi?oCsW_ҝYȦ~7:ܯBC[lI;ٷI4|tp8ޗtpasx7^`(L7-~M&#+UT{7Wߴ݌x,d~͈l? :6_o3[3EN'J4}6D? "iw`Z-l-!p²^@owR*.3m+$O0N]( Z=Iqe{0wBM[\!XW:N3OtjJ c`kY?\I CA{yǛO4 9wMv3+z-S7p^9I7fvXaӝ>%Sk5@-2>|ą?Ӳxa)On4"m{V+l{p^ݴŖ2|*G x`M<5k 1@ 1Ʉ}$=Wϼ'ұ;;N54wZlElW{CRI `y?!ipxxMl5B 6 E  le/\\)5k4^Eʷ}-E,|m^U咮8J&7Sf͂̚$ny[Mfv 0|Y>x9 :/fóknHZ!i<<}.A7"&U '0)+ ;z\`jIi(V d&+*>Ý p"JZXvsp끧 '(DgG/\/i`3Ooދp*iN#Uo_<cU$nʹ)a iCAԁN'ɹQ];;| 4J\9pN-&GGE }+k6%Sʭ d&iC܁yW<4phh74!Q /0 yU}ڈjӛ!; B'RK B1-Pz wSlSelǜeJJ[}==wWGsf~H:/: I[IM6uE h4ֹ͔ɘoߕ4x[o#I/db$fda;3_YxxD$>zp5pws\s:``=3{w욢~kM*p4j\g XmsH_ioiA"JqsN!oV \eQĔQ+a3v Е#i1|%ŊCAH#^5U YlXTtC3ۥľtq4wrf|;DL3;{)EMWs8AѡىixAep)q©fvvj?pIs,9OJ>lmEEHeM6qDŽ-|F Q< of/F|yZ: CMK 6^l$p/Iڊ+հcfRg{Tpw>bQ3,I#)u4U^@)șk9@JK i3`p S8`>vM1;%-hfc$ m5kK3=f*c`qeƅ"S:Ayi'V{ einISv`%(H\#Kw+[' ,^-iA<>gAP$:菴r3$Kܙ9xpC C L)%M8IkUeO0@x:c!]; *!@A`f pjfrp=U󨣪,=3^)*`VIs F`fH:8I;F5\Nxe Q^_5Ӂ/i6KT4\K3,i/ ܕq  A1p+=F`V*w-FzIg"l{ fV3೤w\4zBQ;nmA;8 \"D}\n^ٳ ΂p55n^("T)fvp$E pA TI&UcF7U$$ W"3^ IzTL*ZHg?Ix5I[IOSTHPgd]#Qu"'iV`>3{qkLےhC#xi;IZVrCρՁ(TXiu CA4N%mOhD- kf7UpcJh^)f« N հCv.J (p/*=&i(Zt}5 0v`S7TVQYx3FRl'lv.ITZ6{pkn9[%탲|>5ؖW6bf%]xIʌ\n~ggxǠL`ۂLwFa6v x\#I/~UA;_y xNc.;+:lIKU$큗cJ,.iC-0;q{jiO3CҮfvXkfW;f`E? | tT${n`)<ܹ|Gup I/I;NoN֗,0YGF l;afH%.`:5X6 5M[v0.r זQ՚\nv`-ڢ}hEo\4C%&KkG*5=(`V _6ڌ3{Z2f6Ii{f6Qrs֤U2sf/v$Zp,+I~3fLcfSJyN3[f𴶛J:v&|š/l/tr}ga|=XfrvI23h8Mx7L9oWE;9^K:"=^$~.vtp/Q;4㟥H:\Sc+AI3Ig$qК͆)ţ~ET~TUK>_35+t :[ix]^["sYtnZҜɺ ^uXf&Az Jm X_/M;^I/㎪?&'{J•j'NNDf^\I?5l[ [8!3p2Mϔx xVQڽFE6hqe$]Sum`zd xp>lR;STLHzbfU ܎;k:~/bfc%G͘tx̸gG_Sɜ$ <(3{3lf$jbf{K)pC64䒤&tt\&}F*~}_nS=3@y^5jk.7X5\z~6O)>IK>m7[ps@1%[請w  *=}uj&3{C B@e3OABnӖʱ's^Jc~.\p$p.۰8UVrÒNldA-M=Mm]5>JOw}R9 4g{/Rzę1SyS,"TBL3gFG!#iej*j5g̶Kؖ Luྖ|>>ӍgSz<%jc~4>GX hlf6c^vK=@1oq킸p߭^0Jt]*ogKZٜ;E>Z{A"1'w _4>ٰ>+!<(i:\s .֮X}'RT&ISܬgfoGjxqS-|OJ LƬI1f́O𨐾$ fz.'hݛrs=pf {L̺Z/IikWH2GPVfT:3{O7f̈́x*xіXA{4oGLvfzHܐ,=+&%lZw,SY %]ᱥn*qXKxT5wAigO%S#Я |fLq]RjZл&;_%-r+҈9{skK#6Ҧ"FI҃vlYApŦ777ۚ]w__%ߠ%?%"@jcq}vI%W{Jx[J->a`zK)ڷ5[dO hDKROOKZ.9Ӹٓ5< z!}Jڼ|sǪ<&ue𨦚A/mXy㩁aVQU53{byA!9W.^˽~;m7jt3nBZsqMp Z|MpÔ 2edFY0zxVbY8wf,QtPJ!+GߙD oy{1WwH: w"iݛڏSL΢har2yρſӦI:MHZ*/`FI Tr#ݳR WIvkfHLҡx_Nj`H ; 4ʊ=wH\)?w>麎` )'P=rr''K z33Fk.7^0,gָ8w|i6ʉi"=ӣҢaO&- !P{pvT(ũxT϶^|*C|hʹ=s;075p<{\h q9Gḓ OY Y6~fͬU xDόxA?kx7GmgM} ǯ<')~N8v~#NtZ jX84s%I$Ox Lk.7O:ڟݒϿSqг06J*p9xMm5&TH2Gx!jVY)h& #Oe>OI궲 ;IQ/#K0 'P!P,|UzGAxh[ f]rAP ZxaEʵt+ZokwP'7/#MBV+0 pbfߓD\FLH!(Қ N‹LD4IF:a3h8{3e)ݤG hS!j9mٱ R AK=f6*mk%.nAnZs-pmZ~.z3'LhFb`Ѣծ,~̀ o/pL,z.m"^{RAA 'P"`IH\$?AAKI%…~k8\䴖|+`ـ$.XAߡ_ظ]c[ $ .$ 8a^-\$ APop5;l|b` >h=AvMT *5[wMKGӒϿ^#3Dҏ+I+ YɈVIWךCu,  K箆^!7q1Y2?puT$3m3/hRT h \ޒϿZ\ C3v}@YjgyRAA( >=Xz-io3)M7Ah嚀c?AM.hk !)a`WIEAMfmcL ; qIxxX90-p]Upbx) EX\WbKL疴KוOs' EnS }pXaf(8f$T"O4%XX(u}Q>6l{fv[ f,HZ1[+v^ <kGУhn+4~׭3E?NN0ѵ'4Yh=>׽8A(M #2@ҁg%܉ p>p)ʴJjto`aa qReuY=c |wn Mi Ϙ< _; `ރIGΤ%ˁ;$֑]xI0;00m+ ICpxGe$CTCK&7x©ϓ8Ok?|nAϦw@iflff0 3659Qô )oAZsU8>m7PFZ%p wxl3k63 9 gf ٰj 4$(9n4X>w\of{f}HwQE3ҶK% <̑l8KR++%3ۮSPnL. p5~dts:OqI@xf6\Nv03xXw0ffߧNm~TAtQ=] xyΎ;F?-:Y]xdGֶ)]%E]qtm70<`6WA_5 4M 8%6Vu(it_̾A_ )bdzA4R86gljy f3{nҧ4p NQqC-JRO*pei3P\PR_ҶS 0pnNf=xx:[9>V/pez80+pnS%R@FPG?sAJǣ:i< )SiĜ=O5Ck=NӚMߚ˵:~ђR/P݉?A1ͬôbI+ nC?UcSg|ݢ4+Ԣ5p-z"'Ki069)J:E᡾:8\?>O#~ +qzH+6lmk[::㒖Kţf>-׽LT}#=TmyszFSx:C0&1 O; xogcK>߰Kfۀ6#+  = Jݢyf* c!kQ-j tnt?vVՌpiA\t +ᘂקte  zםGESD"f6x9횷Tg);gftѮu%Ι2^ICJLe+W&`{!YE*#;׋JH:ח!x)ɤs|2˝tff:0?SUTs4^I`, g?m}\n'b:7НؒTQmYCI˙Y1܃WTTβwfYՎ m |Q$\LvI %["0qn6W:_5 -OԬr*7 ?!5O6N*l(i\W.|%F\$x ڢY "9lg6ȉ)iO`U3Ai+lߒW[jKJ)~jfO4ڮ_ cG C2H ؤDq  M?9 9E _"vãΒ4}j\yZ>i˝$Dktc^Lk.w4czmH k mQ&Jzؼk(fv)pC^ŝw i:+~Qzw~Gտk|6*$<I)8W ǿ3$׷iIx%G[Wm[$?K))I/V{X9 /i׏ N.ŝɞ&`Ac8_A TA/5Sk.w&j/۲afKJ4R#Oa_LQn/£Aπk0VAt%W]`T2~iG3ri(x@2fv;[/I'^6 K4\_#cf2NMG+H_q_fG<Wx-]˒IIrf6gK:77.v;mG?+8웴3+A0k$݌fksAM rp:q- l//cw e&8lX[i}Atu6 A4 T}GU~4S3oGt|rj ?|nj‰Nr !9c\nZئ8|yK>|m?fviI*-z?]|D۪H  葄nJAFk.7^ء35(#9VċUT}AA- 'PCIGhi\-I+sXAԜv-V-<\hC  _t".+e# =vہZoʶ$ $ X  Z9AAO5 s' ؤف7$ݒ*lAAtA]4p<A?5;8 ?8`rхu_9I5ؤ HWʍ# :"@Aԋp 0vi8|~|_U2;{% jIAY_A=IAP/S%JFCi>?5[ Pp`K>DXIeG7:~&<ICmPAӧ@|z,h{#)'( x8xW_$-@{e[l!AhVTq$`ז|`fp`II'7ڞS4;GoIE&kZA8} Wz8t{^eM`xm z?{JWvr4l8xxx6A_5WCm/z3KZцU n7X̞FT]mf/l.A3 Cf-)UUIk:]w8`(<\xFÒvJnA1' IDATpS` bi/"οGvI3-i5I6ڦ4{36G N.`fwٝ#z)MDpQT3̶WLo>t@7 >A/ @5 5^o!A|0w?7ߴ 2Jئ`;ρi쪂c6KL < `fS\ˌ;?oQ`P^3{݊2@`q;0vZ7_ѰW4:_1 \\ xxnVOog-&3<5X]DzU$ L653Wc6˦Mc=N-٨rf&ǒǵyv?gQ:gtKfqOҚ8k+wWu`mI%jfQ9w1}Njـ   :{N?+Mx.C|(UpϾ3I|>Ig5N1 0wz}d?[}vPj{ϙޟ,j'\eA\epKH;-!~͟NNr̐wqi瘋q%Qz 8x"+-}4% qaxh<\>RFњ͇VS y`|ϲ=p4> jG) .IZ -tf4K.e|;z8 ԕq  "S9n4X>88t'(8)c .K3{+m;;uɾ++%Fv%N@ (vyqfafq9r_p~OpRم.W*eow2mEPI xYfu|t}aj7/I%J7ڞ^(c7i ]  ӝ@oHjQR% ov$m.)A G;RH2TJx/en-=NjAԉ\'*ض%Li;ΓG &)*AA#h(9 $MFsr<^EpA49L)=ySif \H%5%TQqEb?\I%$idifVD `<ĵ K䤱6afbh[E̾KL_9]S\Ruڙ)mp0#pJ=&$66+AhR}|aO0QuӠ&4#%YCn~C a(B>5=+lkf&+j ƔUJ^M$z4Cp-$;~, w2]G} /u}u Mx J`f/HZO{CҳxEARǵQhxd;x A DgFzS8W'J)H[ca` >>#vJ$ I%WYT4S`?3@t.& `5F+зƋTJ 3,}~(i`a4&0HI2Iyzq FC@f6*ٻzdҸu3"%yp'Ň)-fvSӮkhJgv/IܒxղQXŘ5^1E;K㎭W5ji=#f^QY>sQVy:IQcWN˘7qƱUњ 3f~RI0h G\WkIp#{CAз)%+"9rbJԥmJX3LoIU3x+}$¶ RŰˀOT\:Kcfg%^6e[AdJDN҄Z+ Ow]̾7b\Wn$j|FR ZsqJ bf2%m(in\oGHIK-: X6YRb 43 H z-9T]"\F\LI;UifĶo0nalK~\T6imfwHZ$+4ПifNǪltIoxhkqE``WIj_Ǹf'vfvk{qi`AAH A]s 0;32U[xx_92# yA̞I3s"\gLl * Sojfc$\ />1\Oj w,kf*+Uq$/ N A]]0fv451:M͆ë Ψ0pp藴r?ƫfV-seOPfW࿒fUߒ5U}&3>.af_ٮ( h A=h+jtf'x,K d6,) tFUOZsK;S:K"TQ=$ w+]"<ʴ#B@= h 䁓s7u$hN~"xl?L_8X_w1A1s$ ,i+3V&E  dfl\G zA!Aԕ&*YR6ncKz(f%.0DIIk.7^!77u=AIˀj]HRsڶw',oHΐo bzVM3'//|Tvᢴolt74Sm5R z'f À};qY*l5Y z>7 50 Ә4}=^f`]I K<HMG#,4 k@a|x)m$. ()JOI{JiA@@ޤޛޤ"Rf@D"ğ(PA@Ez-Qޤy'ݽwo۽I̳3̜y|:hRRa/=#<%isBrm_,&45` gmөDUWܜ^7%s d2LIL4N ggJp I;g۾k&ad7<۷ڞL -_Fe2GIZýرV É|(pB?ڒ66"a-!"1WasLk%KՄLh(}z-$uo&d2 38e} Dt!: L8uvǸA~%NE&Rl?!hrI3~f mWvc}w%x8˒FuOIF8嘆1I'$U@ 'sG{k`7mq,S/d2LЙL| \ ۟G߷~g66l?*nIsڦ>`jca9ee"[qI ikeOHtI$}xpX 88z{sZD=S`Vd2Lմ$(u7+ͺpHm\i?=&S-/-{jbTs!&n'WΰXii_Oھ+#S$ٝ!Чx5ldZD';yj*فF84[(j-QTt4Q-ld04Bd|D?gH#.*zD?^nV*e2L&RZ 4 0<(|5/?65$] \LE1/#R_}/>/>%:PjwL{5N`St fgfIBK#GWoX͟1XdHjFkva{&R$%YI7M/ II:^R$LK}*2XҹkIDFlX{CiL}XI߭+;,$ Iw~ھ5k<{"_}O8j&=n Xvq"lْ&yRD'LtIOtT:>S'v=`UojRfb@΄Ң_z$_̵ Hl)i=[Ľm*ln>t8]]&4;p)'D!W}x'4ؖH}oA8^!~KKZ+=:d2^2P4-@"$F*;EҊD%K_$g~ ⡀'T2sbzeiގD$e%PCL̬ll*I NSLf@cjV4gm&au,3q0{Wğ9mJm) }9I)EZed&d2 pywוX " O+׋K8t'iDXZ4i"=Le2":̿0>U3~PWN[2QadA$mILjAHMlYo{i`fvMn,Uh8&vk{,p=` d2L8Nj^h`ujW"{'5 '"UGLhܛpA/+y 52Mr Ćڦ Di)+ڈfHӿm@:`JDȉyOTǼn4/d20P@S֘WtP?j`Erk[LvEjl+xX?9CTֻ4#mLϰWۣ$+iVTJeVB׏dZϱ2Rt'{DqH_)DE֣n`QICӱ1t$M |e2L&D֘7wz}c{3LB8i_o` ޯ$mAGg2# c`.[gko֩LB>aֱ]sppK逍Ǥ%?~ ikoi3d2 yy;X"dR$v*-*BqIt9cxnޮeO > %Ą ۧMmJ]ZoP&Rl&A[o?) ¯IDfX'_ޒtYZmSJeF`NЪyz *[g7vLm@% j}lVd2 ''i]S$ NJ!+B$3rmx= éCچCSOـ%M֡$i ƕM7vQt %/wp?ѡdo""}VҲ_^v}AЏ$H8 8T?QB2 ``نp- ,m{\4aۻٞ/--kL& 'aD4s`k Q-WqMSՊ/K(>{y $/FT);wJ6|-}~%}^6`4"":h8KpCrٿ􌤻 ,wWM]DMcPnHfqA״̤KT_H'UNj)m4D*X#% 2P#B}ꕊd2L&3(@_# h{J_G#:ۈy$G>e{L6 ~WY%T a`^IfoB5ڟ"T©47ZDՎʶ>YҭdL. t~CɱW&;$_lfm۟Oc2_Κ5L&L '0.>+DN#mǫDR#mMTRz,Ɍ=B-`=1QbISL&dӪHD\[tB&1ט7SӭL%4΄&]#4&3`{c%_ M`)ב4+9XXophSD&d2D(?ي}g2L& l)D5EJLF[n7eKfD%qؾ+ûl?ZUX84.\&d&y&P&w$M[#w*x} kI3Hҏۖxo komLؾvN,e\5@$>$M/iT"d2LSNL& zHڬdZ퓈?nQ@ID,^g |=V./Ԇ IDAT9x#8y/7pl;خd2L[z&L f %0LfR#Qz̽R XkomLR \b:7F>$M \ &v{s҈Ʉ~Qo L/h} ,<}g2L&0 d``%52]ۖ /oFGލ"XSl?d2&@L ޴$^r$Pf_l?"i]wr{݉:fX{{~4^4_4u*s)p F8yxDF3F=^[8Nݰ9L&4d2`0=xmdIIH:{JeeQ1L!lQ7`1Ik I'[VyfVD 'Pwu#7ؖL&d꒝@L d~%Ӌmt' a I:VL|.<"K"rz$ m79L&&;2L3LTBd2u1!.m6 6 33Cm4mGU-U &ue2Lf"`P d2—LLwߨ PmOI2$$Mjy#d29(49dhIkoJs۾u*Żɽ433c IƖ'gz}d2LSɑ@L tVhA@h"z:I3u튓2gn4TR?N Hz1MڠL&dj#2L3x8xH(a?nLl)Gߕ4l[ 0~/LޤT3O%]cV"lG֜L&dj@L߱OKi-LMl i6vUxdۗ6f&ol"i{I,|b2L&INd2MAJn4F҃*iAI34{OQ ^V|m#خLwH:M[mOTNI+HC-52d2=9(;I6`4+HIھ8.p[M{ $]h=I{#mF۰Lf,>0 t}>7؄ ,%-[5Vf27a|m`KG~_T*z ;0[8}m_NL& '-G+^4E3R /4{L'$Nm 1~3.3ֱٓV@k"AGK$<)iYۏŁCO/{}lնL ,N8"Ios>"}gUˏc{d?$- 8s]48NFX8晁@Nd2`1*ۿ틀+=4wl:VSD⺙L|ұ^ g_Ieb[Z/={De ]Rf</QSՙ6katq74k?c*hoKi2?p .^SlS͔qIA~_u_#2L3xxj(`:I^#F!q#5RUL6? r& 15i/)O LB@81auI/#EL1vn_!S*cz~63uoږ~D>֬2-&Ge2fp70j{U^j]DG[2L!X>$-&7$m=K3#?V}R@\otnJ`@ҜD3c6/}ZmRI ok\L@d2<`Ia%X׀ÁGl*#3KBa$8Hx H'%-L`ےEhJ&b1P0:=CN q逥% i$] D<,b{"<"ecn<8I>IXrQ4G8ӌ _~W!izIBwICrTMk{x!Dǿm@ҪD/$Ąv `Y`˻N"}!DBed>ۨ6Rff=͟}yذp2JI8{ΗdўplWD5H:lS88CGpB>V"~a{VHJ5)\``Mvn "Ve[I/Ἵ.~n< +e1\K:wI~5|J#i%~Lk{|$scupS "?wO\{~vKO} !OɶeNQfp)ri kߓ Nm1 ɣݙL γma{U+~ulwORYA7V9tX{{gM_1/C3F[4b+i1p1utS}Cml G@ 3+QHZ^WrFD\R)('#s03Qb=: f$ eN~]<& "8X2 P~pɘ~L8e=HGJeX* ̇QKWEa Xptx5 iIMse4K]ծj+hh"ehIBKdbBsQ|´ET'US+? Q˧3~D~$UJS1P1eU=q_kI=ek|:Ӳen4 vD[wfVbnBݵ G5Jտ->#鏒k54H߈Ȭ:DkIs KZyd'P&i[U&DmB % iH0:bji!`%ۛCC$}/l *Yhm_HB+kP!y&iNiLN$-jCy$-'iIKIZ\Ңy%-iITV]˕OSjOr 6gQ`a5""5r!-׮Az߶Ll{@BhBxװi5"k[C h^k߁i[M:9s5!c ȬFk&)aI+ɱTMgFhe9$Ď&s ez'0]KaF(/oz@e2IA%B4yiHZXẼS$?#i-"w5jKTh'ª3FhiWSToPc j [h&&4(^4' Y]z]7TQhSg&RGYc~D)?lBpx$SD<(.i!HN"*bo#BBNJ/%jEQc@Ib5&lwQ=᜹n6ӡX-l'm"m"LӏC pI!;NW $3kqzz>C<;SQ@ቖ d`"$z;b[8nw-z'n⦓RNS|@Q&XQP?f'DH[:QQoX{+IKb~⡣;Kޜ5"n2>):/K3pE!Rc>^%[. 4>'l"'*T'-n&R64AYkI Z@{[";M4c$/il_ӷp`s2!KƗ({zR%JQ%+GoKg kO) axeDTɶ5mGk2*r<Wn}mF(6zNw0N7Mu#mIC%)t`c#:q\c 4 k4!qgl";2L35Q~vDS &!$HR6ݚ-K߳}uoXU* 1F+=AJ<zG@HBQ "&`y۷6ny&Se2 0&=1lob{'^=~(4moj{crٓ+Ic*Ƨ NBz$pKI`)/^lMEV|>Z![?pו(J|О{C,kDE`?uHܹ_z$K8c!e癤臫p`[H,}i^ [cTZgJ'<}ߕ!@Ҷ:uZ}5_RN?:i[S$o%rHڹ1U6SyĕyjQ\WDZS$Q}>Nm,s‘xj? q}^:&EIu0-(~yG?bUq(Rkg8=AR!U ӻ5p#ѡ{ Vg+'>`3mfmCݔ*޾[i3'=-D$[!x^d]oO': JzX`$JPJmª)eAiouѼDwp\֛H˝x8}5t4l}ε m mvs_S!UzD\8^RDmT_0p#}IC}q%MMF$@;Rv??]U^p=kvЙL,C))`QIS>57H:X^BGwxR/I"F'Fb;7~'%tNq{@]G%m u*CH!;oؾ/tkILwD.Jw% ۟5 "vOq~>c G*+lw'u9I dOjim dSi?%Fիv]ӏh #bIGk=]'SQ 1",iI{E2K[3QNQfg l?"VIv־@ԝ4_z v.tjd%!iVl)/'iB>xe2L&ӗd'P&ig@O%]%m*i{II#k oY"oMWHF8 "{bDlz քDx9qwm|BR8 W}m&yDSi.$<|}bwɴ_~5 Xy H_LC 'Г4zJOXH-}#$-gmEw˾f0Б0c'[iO38 \oZ`Ҭ-&&L&D)9lOGpQJ4$(i#I;JW/$$iyl? l|[RE v Qm Zj>R8 P}X{{vDXWLۗgJZ p= lbjɖ5X~aXXP2BK~OIaD=-QN'>HxCZghY\YzO1:!i I'HfC?ԔBı][Nd'P&i;?}ts?5{j}%BD:LXAa҈_%6BɞՈuN7L?V "tj' ko?}#WF ۾8AIt*w`}D5l?%DI{ニ?G8G{rGھ7b4IQCIۿMN>SR w`{ BۭOxt lE8o'$-O7V$ՀT$IGI:zc:@LHGmqLn<ёDWwM`ğKyXҌ]=xWҕn#F&O>U %Q?^IڷO@D}'Lc"l܉4b+)110\rq" *}Ll Cg2,H\؎~!Gu";2L3hc :DND>b8#1+4la?T$폀jL.VSҴ~$,IgJڬ2VԍUځ݆wH'f'aD%mo`;@gzM/[غ  TJFLۋ ,W5oI3ڮd29k:Y:4ǀmqcIS 5ߴA`R < |- @w ͟NSlltk=mt?aMPXDSۏaWf)M^#lū>H8{O`WIg.$Ӂp Iw`zዄU*{m/LD`.Ob ?os)FEw%MGX xz^ypFɶӬmJھv "Rneb ڔNYˆ%z16b{kdꄶ5nNRDtӫoݙOb߿ԶqvRfAFl j;uM R.욭֎ H?7#i-w2pZA6 ,<oɖWmJ˦ *f4odW#Dۯ]=)i>"viX^Om=̥ksF`p}M6m{8It-!Ge2fp"KI'b%Et6~"z$=踞Bt 6H!XْtZr:,Yi>΄oU*bC-Dŭ@zVv#%u)!RV!E - s~YjqU]Hݴw~F}&B4ǵCk iѹv:N?Ҽ]^+T_/mӤ\[56>1]{U6J9FsӲj,~N84˖A8i)͟t0nu,^?#X44|,mgXˉ诙\PuUmHaҼى oV9 ?u8ND,Z5ov(#G7uҦ=]wҼ%14߻AoU54e@Ӧ2gUSME}?.͟!].aS;=?s3M9(4ۧ# NCm_*ۺe$p\Ft #:dGy|ĈlMX뒆W$ֳy-ctW)X9!{XǵC?&:KV[%rU `o.II0W44۟H:tmoJD@浽kdƥSpL4x:[0 XE 6_lتm`+"-ַV.rղ?GptRFGtߺ2r(q9e` wLw:Uh}k~mqե&q4L(ZH=|jqeST˶/.}".d%#MQh(W@iSD8Ԏj_|JLo=LۮVj@:]'t"{ODm?N8Ù xg2ޟbs \C]D&[MRϰRrGTbi˝攫Ftwp.#iz"2D';|X{aLXѝI@=3 1M Is#Klws'W&^=zW}~K)fq"c*ݯem)i43uI~z^e UJ RGg-jiܝ^toI+)~s3KJΈĥAIF~E ]y#՘EQ%,,ivwԓy;^%#54{i*Ġe3xH,;h%Mis&p p 'ߑ񎣮k.t't dIIZ]æ?% lFtRִ9TC%ͨ׮vc nk16eR&ޯ&dOb$ښ4 Wx=iq TgemX,6Ph-;MjoHE睷;73τ3j4 JSw -TD/3qMr-ܢ|EHL0%U|CitW%&ivqt<|ۮu;Q컃j4j Y⼕kj;:Ottu .!u s5=1ZWm8V}9ȑ@L,&i41%1P~藽t?'01һnFKuJp"&B~;wG M* 1p/!8`($].irH}&ߤlj*D؜z ֑g^JTc ̨<":qߔj,]1ʻ#_TLڟpQH=l7rO0:Pkp}ˍ%u`Ni8%4;$kԴ8{ڮNE_bڕifFU7}w488 N\OT[p=j袂ag|2L3LG:Ju)t I#Dg$F$j(K@P7] N4)VJj7PͰOlN&Bd .ޖ4 Ph_t7r$PE7w~EҌD '9UMk=׼B $i] q-?4O{|)WY#'q>t]D@W%=<A'khoKTҪ:L*/$-,H|.0X<XK`ಸ{{Nh$Tj{fzGezZ#YOx6υ[sSj] b80_TGط{8Fz~+R`_f BF 9/Kdn 0Y`r9}&( ؜oG߷skqx0%`mgJ]3q^޷ʼVwӾ A`@ݧ9- Lm ï sWzN4µu}VuxmHyGȽIYf22w_`[e-0oZ=룰H0KgKF~1lZSMʻ#s~ª'& 0ϭ%nv1Kh^Ax+#eҐ-W lVwcI{#CZ>+,fmHUFIӨɅ͆Y}Wdt(NsPCkaO\hyB/Eȷ_Is㎞kW6ٯ%炍Y!i~ܡ}Pb/O-ߋv.; (;L*gدgMKgχ;>LtI[R:[f9(/qZ"iz`aɔM_+Ծ<ѝ@HK#/)>=fM:S ts%VА-2]gt>_sF"@IWf X>))e9cg[>=6wkj%K`e (gӲkh?6|i_-ensPI̬]kftC?Oyw'^~[$t%&| b0z텙}gf;?I=DEځ\nqC:S  lTXen[ iZVT$!D"DtE".u%݋oWX\0. xH 6+Ґ-F@NBe^2x`a'=0l$<͹U)sZ$D"]D:=J_pkِͬꮌ}*2.i# zxږ/źz}>_T?r*q{ t$ ^ 嶔h8HH$D 1(tZ$M'`c= /;y&0֝@ f^5Q֤f4r:ާD1 fv<{i$ҮxJ-YxQG p"H$TD"I% 6W:of0!,4rrKc] wHĴ,^f6F|-iۖ/;|,"Qj$@5fzIڲH$DJtE"vGShsJYJո?ȊfvJ9"+f3YҶjmO6^ IDATg!,܊PvNٕfvjmOpp%[4b#-`mz`D8XD+H$DDD"`f`MI?|1428&߇w964}^kc: ܢ`V,!F}>~Eꠘwʷ1kkmS/n.+K4(᭭8VlҿmR/D"HfD'P$ue;.#hl +\\0nvTx ŒX6OC.1p5lG>@U֪xմni--IH/s3O JS hw]+i$ Ht0WXf&fz{W $ N LDR~ Zӕ9ff-uWλHj҇f6VD> DAp #|f_Ư4=^e_`{tl3Jj ,<`'I+DGParh]ǸU fI%,3vE.L 3528x)SI/6N|4e, п=  p}ֆU-,^*}_{hjI٥X]r^ͪy%M€Tԛ0}6`4TMmu]?Y5%Nou D'P$=B3C_iNAH3Jvv'.ëvԻҐMGmUR޻15%ҕ1%m&|ੜeu]hp 鏖,'iEhN`f 'l!:NjY9'w;99ʹ]F3#ie3xn.r6˃fH<\e`몸8q3{0fkDwYb$P$iw$(,=,(d(/p3GbÑlc3U`K|~ <ԛ3w*m5OڂSO3͡;5qp1l:I'O9t~e@,c8FH+ti9I5Zʊ 8 =_K/I:Y{FˁÂ3c}\r`̺[ lz]\r< `<] DڍPt`GD'N{%Ba+bk (ƙ 0^X$]mXבta! D*!Ӽs{%$bPmϧto>5!\ҐMאwF4X!:ZăUjlG "N%-^ ?k>tmS'<2"!rdfoe8^m2OXǙĮ7ۀU)~I/ ˘[iX%`:]pi%i)p~.o!}Miu"W;&~" D*G6CCWw;ϳࡼeW ?ࡠÝTԶpGoyR4r&!-D`|Ƕ[}0l]IH2Hk0sFGǣ4!"7H# ψcitsP|V@/;̄Nx eSHC, @' ãmncuj~#xr}aM+Q%ZbrIt[/0Lj +ɻs;xZi4O]R ˢϋ1ncz;v3SLͲR~KRޖKO~J]Y>Dk. Ei=AR͚;DCxi^ #=#T"Ge3\RGGKJ҈G͆gG,ICfr:$ ܂xhp[x)3E*ґDZ!i?`|@+;i=?(N!%|40t*Q[If"[>A-T߮?xL֙؝MoOĦGlf[VĮbi<[HZ]k|;3˦<kcR"]ֻDI͇q~fvDX( r<him[ؘ)Gz4"lxh54rrҠ[6Џsfv#.%jmO@o')4or J:IJtS@(\W}kHSWTb iITz(L*0֛vˏS&Y`^Il*dwRmPޞ/!/%9%ۊ}KNCk|vpzB,tO:.퐂;GݏQg!:"HYHZ!T!x8.`fYZSS>y40J3Mi,٩1gyOC.7kC.w6~H;/cJ酇f/^kC"]r*,Uop l:YK@'Q@if$IJ<53$hdO1j&4=OR_QHTa9IkrH@7,ӦML!YY3~OR!QcQcY&ͳ ťKM+tlm\7433wPn]@ԸvQZYm/ ?wͬMZf|ƙ)NH$RI=$m"Q̞ٕ(@$rFh*0PgU;,ME'vHZ zH灏}BE]0S,1%j2A$\[hB9 Nl'?}%Lm?G pq:$$x*ca䷬.l#wON:ᡓ}!4Q2ǫG3ǫwbo qX&Z/+^xAN1whfw6}%wv,5-jiQw 9 %O.KjWu&:V1/h ӌ]tN&@< LA+'%'wx>>C{^ßq+I7~xŸ~i͍#7Cs#R4r BU$Zf&Rvi2=:z~Ova|Ŏ@tE"&H+iw<&%"f64- 3 /'yUKȬ#|x5H9aZ!!; Q=ԈW(F?f6^6rHb{fv0٪͉xE#wS9=[ S|GLJ̀;&uzW Rf?`etGk/5 Sx4W^z '\j]{D&St0´$= \ "SjWz2E]aKFo}7Pkssd?g0` JJL4MX+;o_=IʛCۣK%OH{ӊ8 ms>;c%=(]`g3+dבx7ؑh}Ԝl0`A^Ɔ%^/I\r||/kX4"}QmR89sw%=?4tJ>x8QR3OQwL-L.TѬStiVfхgf|%X&݇+i Vʬ҈336lLQcf4rsvr?#KTyizHK4mvm>b~'\ m(i#\/c_3KX|W#~o6*Pc攡f5:jmaìx5X39 bf$«7-X@. La)3X[R/I{٤RE"`foJ: 3c+#mmnQ_fO|cl+MTM*zima×4)orMREhiOmXv"|#<3@c4V!!d0\@@H zy~8ҝ0:snjҕ\}1$mM#4r3+π*HsfvDЭ>Fl怵YM2BYl3D 0DX3{ (Z8+tR#݂cԳɺinMQv#I]-(fT(8]E.dkUt6ٵJس=Swris ù|$hD"C.)ߕ)-;J#2^e,wԧG_2l*v$ZS2:H?vE"-MIJq1]Ku6-MKD'P$M4,CBn 4۴[q7G] p^2C31fvOE:k:!w4?# $-!4\'Z𱏄l7YmqM'0m \|6[>IGE_/Z/3["N%fǵH"HtE"] 7W0t_ pw;Pѐ0z?>ºpcFc ПvGLtV`=&i3{_ m!.9U%̐KXT:RGWn) / `|>R9^!G'xdlV 4H )PcmHӰGtE"]I 9"o nMhf/!GwُƩU'I+t`h3` 쑖,ߐ#66īEkR&rlIWI"7n[ˢxP3"L;ocfS݁6n?D"V@HC*AFcxK\b{gf/N5aʡ]ss2>rK9r9qxg=>~ݍ8Qҟcvٯ>24}]̚T Δ$ D"@H o;]&nO7'vcj3!<>0 jsyfJeN:4ݖҼƝ>SjpwG/l輌GvaHB˔e~,"0B6D"H$*(H.3~Y OsIR ղHE13t,pazDk4,Ns'H;$ 3[jmSs#Ieo jHefٗ>HC1mpc!i``jX3VDQs K$ tB$k ̈ = ̾myf6^%xZǑfDZҖxGji= \Czc!k}ӼFGIp4 "i%3NH ӂ «% ia[}sƒ׵qۑ"@0 >>pw>0}W+IR/tq*Up"`]/?R0IxVxTlw ; IDATh1HZnllt3{$d}&H8y lwm Vh{k[ fx%#ĵzwx5ڗ$cfuhk87w<>^$3[:>\%;[ @t՘D:V~6ŞƝ&uQ}qgA,s8s]KMJ ^0ӧ M>//zS%-D/M΋;t=mz=KZ8X l'{sOuX;v5Z+sjXm$HY52NB4Q3=+cV3&I[NKizo9쨌2Q?Ɲ@ONœFڟD:(Ay _\C_I: ŘWz$ GtT S:|;;]⒮7JTxt_h۴3{?&n\?"Jr g0Xx%2md0%8)5+;(^ϜbfڎSH$! =σ(=_CZ jÆ{ QU!뉧%,;xѱ*}^RPkc"-Xɕͻ?(1.I!ieŕ6$-;fh),jhfvfx: vbfm0Z3k%iV`XXnpY$IsC(ׁ̬qu~]]Q`aA/Ka@`0w3*LW V쮌}k⎗yjgUq')KxZx:s5|*4Sl4_7ُ6c3#iQ`W``fxT a7GR/5:pGKHXF x{r$6ԲݗRam92IQíK@H!싋=O?D.2oji[XnVXQa%iģfkUU"4rJqiGO򙇎Oǻ>D:f^;m*| oLSWd/͵1C+bgq-.Bt`O:N{ؘF(U~iJiOZGUV|>IDJVND$9=N(wHy(j"O#ABIÀA!g.i`GIǛهEv3DIO B~;ev;Tz̶.Q&fV w!Cㄔ:%ϲpD؝/xo<93QҦdҤAAI/IݶKR|nbfU>ŏË 3F8̶l [IFaHSp H׈| X'%];HZ̾3$σ_c٭!L3B[+͖!f-pgՑd'Pp\;0OqGޥ0ip'ˁf6"L\҃_]>0]gf[wH󄝀À,}?=h],y\ҝmľui :$r)y$0!D GG@bϭe` I0ɟLnmSTX lvdveW`ZӐM̜d%N[,joH|ښlY^zxdIDGPxu?9TU& (wnSEx4'ޙif/WȎT!3Xsxjf;ߐI2[$*l3ku%V0 v"v 488sVff#h\0I *Y0,8Ʀ@ >gԯKhy%%p' 43d༴̾ Q$'G?pGݒ|6-=̮H#~,iW<߉&_#SGQZ|:)i?mfh<2lw3#IdO;C:;S \Ƚm/ʰ2 $?c4 ?K ϭ}/+foItzs[W(j/?ȮŞmH>$O'Q`^=!ޙO9f?ZT/`H UOj4$Nh7QX4J9N?өΉEE]?ۜf%.P4xm$9[O14B ۊ+-;px_ _G]C:8g6U-x@ ?Q| e^I=5$g2l>_IJ8t=̼4 1/DK@l |#\|[g<%qU=9fOj0O3ڣ䉀l1"U "½vs`?.Fu{fZ J6lsٖdppG#1 e}*|4/>*u'T0*iuʉ'Qf[\WP:BFʻFc%}iW-ʱW<50Ww9̈́t Pl.R9\_lfbU t?OyK$5Y`f$M߁vtaXcʽ}*ujfOHZW;sT}HICqW Z^q3[B#i9<X~݅#dHk9>h^I3E$-.iNy~lkfv#3ZwJ-F u4C}>?>߱>8qW]7T%#h1D:f -X9~arIFq,2?)IHA% \{TCG9jd'QI%# 칑OҠSMAayHY ٚLk2b(i<3<*u4{g!٧hfyecfI#JhtPH'A:lsxܻ6^֮&ŝ#i!U]xx/<1 =C4R=Sm4 ˭,TR$%כ[$;'V.j];Vɵ' dAN,cac4pXj YLJð ˴Iֵ4p(u=:א[r2K$OO ?gs&:r3xz`tDA HZ5ra$n,i[W&q=OYXE23'~ ,)-+~ģ!O8<v76Ga\i\+ö j"2-[X~ \$10'4i]N3!1wM|m?錣UzpF{ԛjïp5 H%i;I/~4uZ14#$/IH=<^4RNCC&+y9 ?>P~}zkvaf/}U$MޑT'i<]C`Ηc| ~&+L贬O:0}SǣWlDT{8r]Vڋa>3KZmbg}}%-Z]fvCS.2[};$4TSF]<ڔM&Np|v=C;I֑\sapZ *iԺzGSYX$_ژ0-}'SrSFcRH\ɱZ ?'gGO`I[$]6+Gȿ"3Cx5ysmpGE$;4wNN2t{qffj=πE2kO̞)y܋?`fS=݀p%0%UI-;5 w<$ꑈI;cn4Sm?pOTӝlfeetکi Y_I\lLjfZj*:3*5}F6ŵdի4%];glmf׆u>[uƹ3')@:wLīp O/3|eh mlI.1>ϚxipG#Tis~U0?7d`<k-eꗤ2 M[¯fD$efSdا' :i;/Qf~\@yLff69 Jx×nsro3++eWE:ٕ]{ /Us3)iay1=g,|[ă71wzSE?A ktK: l9̦v jS)'EfGj_HlAIfz4:Nl{(^l̶[ANMO@SGjpf6!3Xmf秦r݌GXmlfes$.}%L _i-vО3e ,@_sdw/Q_m^? v1/痴_j!aϭ;/.)0H F_.Ӌ#js;̬I_{^\FX4:wp5%u X!i`gez#J:{ xtAṙᝲAfm[l T x!OJw=g%t"VAAY/p=^*יleV igxg\GF($x3h:{u]EIU#m0#Lzǯ6g}Ma ςm=ar]8gg'ΆxüNx^fSX$qzH$"[$*pgKpQh"=Lx{KZ?3/4Xniɋ <܊u/>> $Ǭd_g*0Ec^|IS3ww!^|[Ri%]GC^\@|Ħ'r:>ԮN*xZ3+TsZDU wށGF">4Xzfj}H,t,u$=JH1/rڎŖm"8 OzveJd#^xZYxH}hU"[3q]5 O8'&0tpF{"_i@941$k͂;%KkH+yOSd>0ٓh삇fyFCI'pTXG+t̚L |l/|dxIwYn搂v  p7pW-:9B 9IᣤUqu0M_&ɟ|P儎fdɖH%&tH5X .(c^f<#:"H$R3zUοȎ娐S5R˦;+=R:5md선S;Z2bpfȴ+m2;$%)e@wӦ+Eq94m;b6֗4ǣՄkpͅi;ʸB݅}zz9WI읐y5pȠmq!"I ?9 #-e,I#uh* n<7i\Ntxݞ=GJSΝ|=#4W-%3'C։H;2.3P f-^6D"NTұE^WߏoCrۄ*adG@=?I7e[D>)|lqf6I^hr.~_b)\ߍ&>{2?jЍO[H{`xgIszt$}%|6Iwii3[^/H$D@#=[:fu?8)!J~A-ABb[ NpŋLv2;wݽ3F IDAT<ܽg^9ܻw/iy)f``QIKN$=n+!g`I}|zIC$M-i3+bqg1IIIR?IդFuU$- ^NеGq 4gx#b'HZORoI*JGޙ$ 4)cGu9 8Z. 磱En I30KMܱȍvu$=FvXzXNr9I:B|%\U%$]g'7 @m'S;VDM,QcS6I[D"8, @Pø+E.;c~"H$U!3˼ 39+Y\]VOJxE?~)&֒{_o<f+"8|7<⥌;J9.-7xcrxݟ˼dTR">ojaCtx5ݵQYÐFN線"'^lXzJy,jyDIt?3 KV-It~jY"~qoAúK:;O$D#I=Zy#Җڪ=k5G5ccǍs#ͬ44 nkviFڬ1(aGzwFf^ݏN} [o}2u%(H$&NJKăi`|Q˹8J<{f6}o`^`\g?z.f6c&#iJ`J3{;EXb @KvlJ%fz>Jt$M kfip}1%:;᱘79QGj1$"YGl-6GTE\ẼK>&/> prc$=~m&leށ:L3%MUMDL畛}HԚK,H`f KZڑ#6a]^f0$͋j {yF#uf6H莜7 @REOleI9ݘdf?5xBD_m;TkYUҝ@I˧D9/`z)$5^e*vꐛD[.+' &b#P"0zUݎ½m}qxXPb"~xF9bfK{&&Nʌͭ5@ez࿳gVo"=aO$:3{HH$ڛ/G ϊYʉ5bf'͗}Uo݊qsݓȸ{1z+Wx1 >?)^Ph\,Wf.)&K& >5%-}FdG"fV_Ez3o+\7^y!*צ'kp;:WkBрw;?1*)i#`?cfc6,0)n\)MB4DҜfPPe遱f\戱ǍV{am cѐ/ ,r3JZ?gOY7#z58ps}> טُ6+sO손 w{S% +"F~];nZ$D]1f]1~t$&R$-L!`_$48lϭ2i`1p2?*'bBMu(p$q=M_L-8B߭oOKZq'=K$튤M4[X8ytGIt?"$-^K]aoH#oΦ7|y 3++msKCaD}lL ps3O3=.2%-{ /~^6C~#fT~ ,y^{O޸غp,))C2IGa3z -!afJZ 7>7UV!|IO=%_G}% ?%}/鱬qܽfJȧ35 okJz/}'ig_TsH_#e쓐ω'.,p^k,Qw55,Ig[|lByYlㆰ*;R4VztL҂Zs<HLܖX'Z ` ISH\RIB:Ꙩ3fkhSR$%o'""\<\9  $'i]IH3nώ/ N TN=9pP:cf/^≊ @ )&i%܋恜(xXS>cOL<09'ÒWP{^}AZ 77Ev)9gRa4IFn5_#OFU'ޒÍ@Ef?|nM/܋=RDgnͺ`'-ER/oxle4S*2cYكOJdmJvg7Fd:]#e| ?xd_k>YhZ) HF7\oE ^ وsMFDsn3Hk\4f D%zx̎"]I.=f{KIߚY[re4["rÜ{1ifV _ㆣǦO@l h dªzՐU:N}W۬N|{IUssT&/U<9?盦:̬ ڒru4&Mp#pVHt-"J܎6af_ g"jV3[ ,* +᭖{ef4{daM3M] %o >}=.6z,iRI"(x-zcVzqJk/[i$=^Т2ghAvVf1!/wjlKr25wK*Lh40҅$=$/4$=+JIH!i?IJz&4a.i7%=%Ry|sf[طLAm{JMҵ^t"C~si c ;8&.Whפ1MRoIK%PTᅱO j!0'ۢ0V/I{I_tm%M֔V9ɧ/踲%$.5QSҲqݬX&n$]/wrD'^3FDSď DM|eD}ɾ+MZ/ }z#cHQ?IƚlhrINKy;^\Z:ov>f of􏶳HcYdzwωG%zhOZsv}nTo#쒂m|)T?+].܋E$"^`eI(5zX>Ȯ=-{dǖ֚L~ggI[4xی_x~{9.0bM`yshH>zt8\Η`^y};쳔qv߃%-Jǟ2cX↌,_4ncnTe|<ٳyy[7z)+IJ\QOc3ޒ |T5:ͅhRoU74/ivM'#ж?nd۹J3}D>0uN}s4\{wp\;d/}8%fbۮ+l[zlpP8 )+m~KuI[G:4zՑu07z9y1￈{ۀCfw傼,q?y0~s>,Bsaˍs04T(DKeXS3W87vU y΍~d[qNʵ9׾?x'B=5"cYVҴ IK_Ϳ,?j`uQ}h(3;n{%EMUu# /7kYDbż$遗,ubU+py7qjƺ26f2/dPlwc. mL4)nxz%cIbN\㧀㚘ܸ54/ {cjks9py측л8W=^V)9ٔvݎ?/3G ?g!Tg30B>^-[h; G++npDzyq' }* .i_`ܓ KE#7fqŐq#~cjv"6 //c~67nG ksR$gZk1?ㆳn:M@do gf_K-i$>3{2.cqT":Dh,Y9yI]}o7/+HTK!'~z>>MK"8C^aZ=نՍQThvKOmߧzk,&n4n O՗2D6W澎9eiHm)]B2N]bcDβ7Y0=df[А`dbvKگ{j^0}?qӍ*D$7 ~4BA:)a~FR[*&x/c%D"^Fu*u=g畄UvGrcwP+U;KHAҹ*[yXoJC +iψh434ÒIj}H<~.+ lTh6`%Di /8Q[FZ޹[9,9H$D"ѕ!i A=!4{$y$M,srrj4UJʪae_SB&t${̀/&wI&i/!,i\4 I!/g끒v4]\??.i qUX`3` ([p}po+pob܍t99lz蓨IlzH$&ȗy {ԃ4PRਖK"rL%TSeD"i"q|"QKsN\DT | n6,LI;Kц}$*iZI8ϳpeNTАnY.Ά5%fB9uVHvWYD3ԳB\^cǘٿZ1x~Akd"H$:%Kފ$f#0.lxUDW(I+XpX,^f6 ;ErVsPoEH7}lfcЛtYTْ+3㼦*]v k 3 [8xD"HL<\p$しz+hOk)0O;WN`Wz+RrTEfYF⿁:9p߅'P"H$.Bwk*V$Ѯ̈́#wFUL$*bfmofv=]K-~2 llu)axc̾0gOP7OD"H$yu%M0_% =qMtO.7ݚ-.޾ofIZXp!0u)i%` `ptVEoMŁ_kt6p=ٸᕋgSV<`f_%b|=Fb-n%0?;13{X[uq>xkZgY`U`a3'?EfH_BDj#4{3<6:C qqfV8N7uH,,5; o0ѡow*%l,&i+3+J0)p.kmW^0*O H$z+v*iϸL$`fB`м 풦Y8 t0O<Ӗ@o?|yxiyVҪEe$m~K%Mx/tX0Yu/09p29o7BI*1n<8[x^Ҏ}cCk׊# %^6􇶎st}~H{K$e{} h`n!')ڝ l,k[<ǫkW๲܄q;P= !1O/I#qcրXIW<DžQF``&Y 73]Jf% 7Fq%&4*t ܋tMh-fm"ٮ+l[zlpP8 )+m9L L^o=}6K4zՑu07g{/}Ǿ3 s^Gy_<'o$wd9Ox9y;ᩂ6 ٱ|+'{+1'0fZ0N1{9%58O{}&)o~)-LkO!ߣ 8gChA~s._!_>e.ϩ!Qh%79q-pp |{ɾb uB~~I/l`\SM~M 7eAw5}Ę䇆|^ikHҖliDI=s퇆`k87vt]st$[]O"^HZOP[uItE~zHLdpbA6i]RBP/djp`fZ:OqbM|sd:sL݂|P{QG>ץ'7| [~ym<*a{>3̮=/qV i%͒k9"-63{!t 72{97f*3{%k /#/)T6[po]$-\}r}X7ւ)#Ϥyqc1́&ވaQp9/.$}aYc0N%2]umӗbazUҊytKm30J$Z$bRIt;IٖDVef_f ~ٛ7y`ɵ73{: &Y X*7V$fvU1܋{B^ @WuUcHxdߓLPbWp/高Iм;IGH:7 ~+Ygz~,~LNv~|de腇elWl)u}6^+3*=ߊy+nh|(V-|bffB+ c>,Ȳ_KF'K>?yf`MDZ`1ܾ7nlܧX?u =c2ia ^6yŃqWD")fmjf[Dc}z+HLDo3>%>mb,x(J~2 PCyJFWC/VGns%VCw#Q7 (i}*y?GC>mqaf_Fi &3lώ{DeZB:(^x[v %[J K2>ẓk >s6'OԐz{%Q|fvfGMH1eVD"P$-#BD<"DD%#B +y-df-mOzI[=cfk^FƽhlޓT߯n[k 7-jfCl8pFoqgaVE%UeoS+7-ugكchuUxP>io3m)3{XIF.LRy?5oHtj(es?Q{MLd[fv\o]Y*gז,>J#Qe&4 ̞4xNUt[IQ|fQ#4+é^fxy{zB64=領>%da웡TVc+ d5HBҠT![!>37Gc|(yY“ cA?h撳.oZm&8̉?MxwL\~x"/ ƾ 0W0*˲x]H_7*?쬐?'{0^e{KK26Ay;W'1SC=F!L4^\J^EHgojBIlLffK:ؚ" s7qr I3Lٻ4q㉅!EU^<n.VɃueISYxj>3Ym%OƒS1;r}Áğݍ[OhHxg,_ᆉA5<-C#CM/UqGKcqc1F# nzOn}6Kaq^rd`g`ZWF(2<pVs`b$͕eN+coA;3v.kӄbw| /So"̆}%7GhpI#7'7l-x̆)\u= Nk0^E6wے-e[p0kA>ޚw4{oN:^}$iW3{_txóĵz#ZL&lfQfWI7٭&LXj-0\ҝ'엸KýToIrI~;ľ1f8I9r>"{;3$ 7:3l%<(z74S?H' V3DCx$ƭ=cز/9[>F%S:]fC)x8~]~mt>x,JvǯQ_׾O/ eyESq^TW1F~7j3.v +l-LFfFE{K*S|^Q~48Cn>5Dfǁ;)I/?˙S!JnfsO+"*c 3ۺum66+B7]gf1r3qcfHz~n`RYl|8o-fK>ff6/?l̺/7nT6V7 ;㕲np6-ƛxǛlXg)KÁ 7/J=-]k+1ϣf\AHŽ_8.~W[ 1R"q<9g n9"c(<כFt8{n`CgInLȄ^1GFkqϢ̬XaRϻ=Ȑg̏?_0 Cuf6ene^|0Rϖ U$_ۙ٥}W5oA*8o~I^jܱSK'GN縺pnȜ ^3^fvSY4@Atw˳;f6>\.!/ƥ삖藨5eXtXu <3=df+=jNA $o F&گ 5S }(rIzwAlff֨qi,[V03ɻ_J ȹShU3/'?7mIIZSR/ĘMh[d=J23_/ fÞßdԊCx4^.0ͶJU4D=]+`fS0x?sfHsh=nfcZcx1y3ƶ ɔ[\Y40cfك]$%1we}-0csjfofԾ pمGܵR2xL,3}=Hw{7l|/蔧R5ˮ> Z7(a*Yr.cG"i7@_G*I%SCB1o;0IkHYé&`Va-V!qL1Lf.9 Gsk7W$7쉒Vjų#i;K>X^ҏH}zJ$x/Ibs$^Re&fs'D"H$D"h23x`\H7sfi\-l{gٿK$/xy2 &{y102~4_'28^F?%z7{|{49SdW܈sg2Kt[,tx >l昦6 z/#6f^hjf_X OpTJҜCfv_+\/ aȍ7kD? 1I}|#<(и+~=Nv⹾VsS=1}[e`+[׾!;zƄ~aqcqs.i? x7~n.YҖdf}PoҖ-miK[n# p0n8 >WwJ7. n9!۲}~-<, 9QG. &9YOnU8(ȗ !6'ؽn^ܸ0WNjgB~7dSBTygŜ+5l|dۦ/q\Pḏ vC_.ڏ,,]X>C BiW)O,{nP6'?x(qCQx$+w {5Qx}pcЧT91S1|sb諾5 $i[ICc۸F9}\D"H$D'"oժWg@][wܰpdN6cN^h{PJ3{.~o0qB&Iq,]7a>17"ma].ƕ|Hn'BIkvJUKfviɸWO ,B?𞙍 74.T4_*?} Ga*YFv~FZ.L̞Ž|]WuQnlyI7I:FҴn ;-+*=VӒo=/H$D"^Ɛ%}oПP.0k{)IKi3@^pC̔xHKv7E^eeʟJS}_\2Ƹ8 X8̮˄aV,Jίᆞ$= i,,FY-*}-Ow{ffx3R#4+ib3;׃xD`q<9f CQ's={vףzx.{HrL=+7n$oEg 35y'%>OM4>,<qϞ˾=}M/oK#̳"i$.4O<1%SkSg| ?*)- 0Z҃pZ([%sQ58Hta$mWi(Wk|eА5Of9f3MxVxKZ,?Jh3۴_kK"f2M{.HZ̪z,i1<#`8?6gE%t"4xGIkՌZ?[ kT^es_bfۗ> ell6̝f6}&Fdǻ5_Ӱ7~-o絞t`Y4X wu"Htg>ݐWpCq6J:Pٕb%!weO=1~x_&f]0lpN{OHI$:묑HH"6Kـ4HV~5;F}.<G-x^Y:yPJ;̊j࿳T) b+v% n4cOMk11Dc 5**bES9 ܻn{~>;w9;fZV5:BU^5̅it)\Pm,&ȵD'cZ4c%r̬zP~~]bm~4^t쌦p8.," LtH빵ڜ:t{EjOaK,&"/߅?YDwD^9|s$-tEa)"CD. ڜJs~Ey:XT*"7:"SzlFNR'>POVU=GUaяa!cn!w RofkG>@kLֶU C2}|[]흗 Uy~.sux@)zod4U5Ȏ"qjJ͠`fIIDdtw0m xPMD I\`d,d8TPww9ʟrlY_mwn<^|ά%>Tk,Z\Wr͆a5ش2̵Jc7ﻏX@^K<ߍE.KY~ߦ^VŊ4lݩu$Zs;L7}DsÊ"aΑ6BmݜB&=ˋ1& Wz)ï웫+.ܹ; E?B0/s]EXe󥡓ܮ Lr"f.G13lVnEP{=\#"N v~TC :$XĶ?cKiBr{`,p =y5Q{F{w.oD>3*t[r"(Wqh>:=|>v& fK;5˯V6W%Rj>l߉H9D͌Ȯi ^-~Sr/w쮃+}uT\r IUgla&0YAƟ0E'.3'cg[Su1AZG% tJ0S~~]4V{Ss=7 \+,_&ma_|0Jؗbvkoa;$y_gꋏP.M`JǟwҸZ+R'K v9 {w` `\%]/4Ͽ3,2a:]a~^{y:+uϢ=pAA4o`Aa?n,Xߤu)oJ_¯<`2vfu b16`ֵ7qڹ6`?J7(oL2G@;s !%[:?ONm駙 Ω|0~ 2g\O1։؃za/w z{){2Mg/P/=L]PWoOmd= a]nb Ic i/yGW?~L,515(&`k__pk3ůwaRgo?Q>W3RHr0a%ڮk0?e)gdnڬiec}Na¥=})E얫m9/W瀂:WaHɂ5S mW?zu/Tc~c,V&HBnRl ,myw*nL4Gp&3%צo-1(/_"ۗ f`_VSM!ivC)vW0 o !P;M!jBނ;f= <27OnM7po41o >@|`ߤ\;8E+oߌ53?^??TPTb?.0l | 1!k0s?`¶pW+߁k8bE&VGUzqp_$u}l{S M L޾v=0۝E%76&/W\_0tLd_9f`a{RÇH?4 TL槧" q߯zsc6|յ̋\6WPw̨_ m@ڒ*{a;^WȯsO)BU/ZcK~9u\{!{rc"&X)y`~6z/2a}}\׸'P邲[l$ϻ {OI|)ѦHt][̓^}BI?ju+h7)XLj?O B]=Q )ε {z&1$k[>JN:aڎI`X>ԿX;ϿDH=+pO3=7IPF׿$su[]]]׼@'M `)pL.^_r+=L(sJ=rm3湵yb!X.?{VWao/5&<]j="E()RHmSD2Kmq -_,<6V+zuc)7Y-,jOr'cgbj Sm`q'b3wf%!:Y,)92q}L23FMǠ~]P&AATMCeqU‘M|9Lڮf2GD"栱pRS>FlI2m6ٛ }\\+"ԉ@L &eZ"̬9-59Y=}T]yvw^ga`9^Dzys }>tu LYD2%+)qϹԛ $-?.HcwZYDdn UW;cUՍ -9?5& ID-Rճ0SMS)"7|Xn*)S Gh?f׻GD4`ZSDH&ǢeP=]< *\5}'=^g7P؛ű1u'LU}X3Uz{w#6k]7j~p TK y9} {-,:IyH,"̊ PUQf|{>Ͽ.{Y q|'|=)t,X0_ Tu 9fIc !5i<] mau~eW=_x*ƛ\]Lg"\Z "bZ꿱h`$"L>Yh3fvZ]_`N4Ag8e ̑3,ݍƅD3ˍ֩<_;q.Cu/kD0y {,Hw`S$?UAAP̷yzz|\UGS^=,(#6`!~ ? [꿰J ΫXe?qD#]=dwN΁79X{>?k/EFU*p)HY[,I9^> \ϊU"̠>NIέ ~i:HWw܉z3:?ds?ݿK]`X$~`, `L~2&d E#>s2G]cEyuh%EȟL*y]V$"]TujZ|\&""$Of'd"r*zwLs3_N˜wMl]S5hrGbDdon]0AwrL "r_{Ii YPo&)۫jƎ^\"";~ŞXZBޞtMʚ\  'zZA PyS[T?#"16i$-od93Iӌ8R^9LxtȜ!㜘YM7`U}0)DLQ`H^w'#0/frZ8"7jp,sgyUNDT83~4A/ƴBR8m)h%[JuFU x>~inz4+ǝN3\^E;N@U_ZV)! @!<)(pS"`@?UF3˃ӁT*15hmɬFD~gd@等kɶ}//[lE~AA]k7`fYjbAЎy Rq ,͜tF-gWlMo:dlsz"#4  c$#<9vPՏj5 ha-"HAYܼZ#2BAAPzÜ8_r\n\wƢ=f7L}nY7Nlh0-E=g/̩}#<_v0375qg%nV^0翑Ime:Ȏ c~FI1*37J 0^3}@` nFY myǘM-=!U}yoMwRRޅA#^"nt:{f~]Ue bku-f 99zIbZU.ucA#HlT{3gA%`{Rł6ݰ{cc,ͪZhtzI{j sbȷ 1 RA6^IZk #J.mz J҂NY{!"aJvNKa,>Z|skLrK`;V8W4:o88vo{D$]u'asXA9`N}̡ ~|nRnN|e[k:BDMaMLH&JUL5>c{>-0A] yOLsvbB!qw9^g^2e w"ݗ'J쓕am8~;SEȱw L7^}hgl?aҿ\!"cBN]xRD.No??YXd<:jmPH"t74z^"E)RY Ω\6yrü~].v_{x'fWwُN;}Ufbx,*UzLL+L)i6G?| oLr8Oo]tΘN1U67{Z<\ɵ%}4&k&tY$?5y Vo!zKs?6b\mV(Q<+i c-/ Z /9)&$<+Wvruw,[K:L\ݾ>{V  Ǚ4" ,!"&$W+1\U~\(c+\L51M!Լ`??@҉K41Ry%pP~B?A1U90pZU߆>O`>{83&MRU?:m&|{c\C0~.ǵp.7[jci<EY5f:v1f~z U{48L h'PAA1Ls`96p.D]&s4?Ǘh :MMT}]s\ǏxtÔ~\̬z?ya 湼1[Ԃ1LV´rry#0/aJ9 +cLcfe騪s Aטt-09b^} ZWs_Ä#Z{R _4_&ydz֠"ID/˴^kqDA|45g`ѻ1m^@WLؚ48gȚD㽗 ^Rƿh|MRB0}_hx}:hiY|?f+{wa/<GijMkEdږAAAPkn.n Ki;E-hULt;m BFƏKHMvK8-._EU֌ȮM1mڈ`>c`Ѫ:{5ٵ({miS齑]-\P73l1~}4ѼԽi|l_]ľz8U= mjV(  Z fZA>S@-L! _+PU$yS^{`aj[~,6&"3)j'b">EMEDxR: "sHQr,{EJ\dDѾipi/>w˲XD1"vԾnETu3_;R;M   ).̹̏4܍E^e0;?ӽޏmWoEiu_YÃi# a$;aSn,Tw\S?B9'PX:/!+=1')U-"-}SK @D#TsEj^,\zK~PM¾9-jX Dd~w(7,'"ߋL; j\>"\*(  فLgL˪qȝvŜt F1q0BCҧHW7EAUĄTۉLA ~1wnEdwY@D„ 3=|gOXK""1-gkCEdXwgb2'^ ,$o$1~ekR78/[;[`u`E: '*Ddc`t]f꥽nOL^Wje%&SD~S'"QSmTuF3'1!RDƢM4,X.9͞5 )kg>Y85s݀'ץ zOSUMg& ].=zWr7E-5ژ"E񦻡ݠ4)RH"t7 .MpN-Lce`~I.(;44)_3x{˦ Vώi3%oI_c8hs,p`&y?ZnW"LUy̩W*f.5zy $q5&޽3翐c,X̬Nz :`KaѷbE};0vv7y Ƽ ۜTPvl2V_)L48{n^L7q}Y00AQ>Iu'Þ/rsWпK{>W1F:4W:*8lo%汑ǧ&b:@L7&cQ;&t `4vP49~;վOAa`k9XooG`4u5-ri.\u=yW\ aYFj(JYűYt98X[UB#"0Ȧ֩9=u} &@eB'm WoR~&>ׯU*錅Gf޵BVՏZo0 jQrZ;1ʱ:cbL6ҞsyUjos   6CI6w:QiO)7X6CUǴJ""}=TU+^ӂyq˙c|i!ZڗbZ s-f Ԧo\ ?k&+V JW&Z\ؤL1mw5ڔ AAAc>b%tB5Ylik<.7 AAA[̟ɍ"r,9`&y;Uo`K̯j9A   " paU]EDǜovfAAAMzUE @AAAAAAAABAAAA!PAAAA; @AAAA퀈CEzAAR:zA'@At   %    !    h(    Z9A0 *ҵs `dvk= !PAAAA;    !    h(   B    v@    !    h(   B    v@    !    h(   B    v@    !    h(   B    v@ZO   Dd.`$mUe+P󹪎i8sTLUj5YUՑJhAAA0 "E2mjk7/%eWwz-`f뺂-"i8? Dd)BDz.(7W("Gjغ \]۩̾(  ى_*ꃪ:l-`֘Ti%Zcz"U}#d9\t&!'|k'"G@{k9;`AAANLǞU\e`vdvr)pW'T~+"SUZGρ]hAAA0[ "++'y5NFƍǬBU'i4UOUSy#4   ]8&ZVDRf"2/+20vAihry=!`3`K`4pu; OexxJUًg7>WRAߝ03@OCQUuxpA?0퉕I>:)~N`.`{L&p~[vX`20M,sWU[ XԳnR:kx\UGI7z{ҶV^n-/p_6HR/lO翉75|u؞NU'Tπe4UADV6^nΡuGU%u=D$ۏ/Ռ9@AAA \L 2K\ ip.تzO`p40YR&9> 3ixCD1Ѧ[DyukqMDc!Z8> x3y xT] 9׀ݱOϗDdդꂾv{_~yID"roLx6zM%,9PR9Ws= 7+rI̟0̔pfV²> 9xAD-ECDd wckv]_}}L蹉Dè?NT5RH"E)RHj0 1@^PL0ѭDKj= Ǯg$]1Ae In<?/ |=,goK.8?4Ls/>u:$}1@\y_{^LEsôe$|T5^=`)?;I:aO }%Xh0.ɟ:?.\.@ѵkb6+m:as5Y&?WJcH AAժ:@Ud͉=%;bQVgLUv4D2Ƅ%kWdf,|NC.hZ"DxUM݃?e+=s;s14q8WaZ'ǔh{bޤ|U35E8 bU~M+:>IY&Kڿ~ V~cVsm T=p4o,LTu*o1`*TY4{xX=Vc1-!yŮ9UGI   )n)f}nk5X{;J/ KVN_H,ac0!Â4fx,rVfDDVUg&io3J딝'2s24F!"W01MDXD:z~7DD߈ȩ"rfD+1ܡ0aߴ$o?^Oo5D5EU_)8RM{QI("_<ǁoIB   j;2"2(K ܡp[=; oj~L2<2$KU8g1ԜK9#"{0j cŴekt.? ZεąqajvƋ,x&"|̉iue³Tu]VD6>`/OF/i|=%Xn_B5n)E}fפC%Ȯs[0 ;-\i)&kp̼ w#Ek9ޏȜUGG   5cPҾ|Yde8ͣ,ȴSI5hEaѪĄOU|E0/y2푯 *~bcHk;aN}UucL>3 ȹ sLUUؚ2?ʏDs``J]N&(3Evk0eTu#U=ׯf K$VQ-G2S/B   jk] WCO"eјD IDAT|YPDzȀ\fTU 5Q1(6KZ~ŴƴSTpzߍEˋW4F㹦ayN"2?fvYZ}K]%Ed^8 3WDlܛX?U*"yp,25s/(n((#"*"%sWb=7% D4W_0 ZmW0 1!LfVFv~6"[e-L?ީD(\+A !PAA "`hn,>Нvt>F2M ?f~U}35k}뒱`ަf*Y:O]1)9:Nv$Yqi2FG 3:كqv}lIƮKNM}.]1ǒ58^6Ԉ6T>撵%vPl D*b5.ŞI^ML O6yQgiS4RZ_1ljɹ,\Biĝv\F{9rEf*ӘEd?,"|u:55{@v^ruz0:Y1wɔi2e֫b޳'s>RH"E)RHJMҐ Ul {E [(i*%bؽ RWA'm} e>9~A_}|foU{y* ^K}´>'gz_P6`5x*&hx Wp}œAO4˞>] ֦1ҿm΂qDŽ6}eNZK>tL٧>O>ua2IM4^ۑ^nAْWaqqI?W=1󍴐q~ݧaBIݧ {R?plO´z$kNoI   =" NhDDbZ ie%"20 PU?hf?s+`oVcG,Ԃ`=U>zb>`ut-Ł~yE>keSqMԟ~& fkB(  ƈ/E/"R3mm3;7/HK"V@gW!Gnؿ!oYMGl""\-x95(  CCm DdULD7PMϢQTuZ+uGgV3|h aa1G6nNc״:tn͉6aAAAP{Q7scg}p,Y@sd[ufL   jXyA{DUG#[ǿ[i:mJ   ""EQ qBqս#U 9P~U0.I#:OU~왴5ff)p3&)U}vUEd?kU IDVbkp[S`YL^w`_`y3jl, N7\ w \bN/'UJWm1*OSfl, }2Wg|9%|<T2t$lV}"*fb8 S{+l6SUFV`%Y[Izq_Uu/soh`'`e? ?&M˹>BW=:%MĂl}-~DUt#|-6ɡLѹVJ  = &`NՁAL {8@DVƄ0'bnّc[5)[6II~G?vnOm6$e$.V0Dd `&ysh$p&:xWD/ pf2&xx y]M0X.IYr/.X5p\R0F:,"XG99$"bBk`´=%tK''EdtK8\e8h{LRG"R'"gc&,"C+t"~^ b̟6+zˀ }> vDŽȒ3y' d4$"k`8L@&)@Lhq*=N#";x)Ǣ>=cL<0LD]ݽ|NńOjH"E)RH"$`i^&,h3y=v.&v~tw\x3mvqI<6x޹<[o/| [:&sbQy@F)I߁bbZLip.*%0oA/oހ>N`F.oYI^g_ ik{V_>P\ʞ?8<_Z  \ZDUg`o磡NJO8u'U0s8p~7L=BFC>bfا`BTuzf33MuI0 ~bBTl=/pnWuN XDC>1M$Q\[iLp:Tki똞G#Bl+W| f>w,V<`&h|}'7XD:gcez&0? HZ%(  cl'"Gȩ"rŸ%J4Ӿ^sPGe&LC̴<fo+kOYf>H߅iּ&"H//{PU"zRDZ|,"[ok J]oUuT.U?k*&zYUhk „ 4w614{:beA~J,3=+b L6}~yӊYyZMU멪o$KDzOg{uU}VUhjj~ /"ݳT[4Ul/?33"^z`BBAAAAfĝFPH'ҹDFW2#7bo-YЮi0GL\'{|kpkpLC23CDu#i=!3JDUo}_ќ4T3"s$]JJJ@*攭m굔O._-WDUD?)札ISs*5ǽ̯sy/u*BU?R1!)*sY.5z fB   j4Q*m?=z%Lc^ "ӎ(xQOT,DAu8$UIU]ρ=*АXZrS2KW&k~X*I~jNTjA{m|s`^gô(+2*&T@ s΢*t3g㩨gœs3 fAň(Q?mf}7 yѮ1A"S0z 0Uךy4eg;TY[-˪j(    o (   ` @AAAA Oh= SDHFV+`AAAA C4_Tа(   `    fAAAA0 F    Y@AA4ߪFV)Ȋϟf"04>:  FADID/]% ,UՏHzGD.s'jl= "C9ŀ>z|#Ԩv@`.*D8XAAşpp0 CE7\<,dzWP0݁[݀ ُl)"׉j ό@AAA(`lU\tWn€RՉ"rЪQ Y0CwW%<   h  |ͧgF"<   h\7N,F"2Y3@-"aӰ7"2t203 m63B D . fybgv{gxY6&^kbWD$E{ ['"KDڈXMep!0I럂}{I~ϋ X<ǯx3bȍXl͉"2GNꟘAC̠Tm͋] >^VE+~`'칯 <+"׻'u1`Fozs.u1#-@oYm>DdK,wզaC"rFA{bI_tS no==K)_cv{[3vE*޿0'pc* x]DpćGqGqGq4(0;.'k |ytHͰEe[,t ._hy1̙\[,kF~Ղ>s.&'3Nܵ}<+Pte},&y~9.?:>̗\6ρcXb[vv~,3sN.(Su @|}&3-?6J}wNK{um\wmW+s ^.{3ޭDu^eN~O)w~6#<   hj yܝ(`p&!H:[4^VC'`#upI \XN'" F ?S@b`ߐod/=KcZkwGnOPWt3u_BԻRQϘGRs`J6: 3 R&ll_CR J_hfc~<=iaQ5o+gS3Z2 1kשif̶O983wXXz"2{r`KTdxYdX /9f Mww\6:XU3."ֵ@  IȮX(%#Vl'5DYf( "hP_$#K\VY[='f%i LAjCmeA~9`! Zy_BL0 IDAT.S (굔Ϩm~o ~F>Mș_DUE?\锆EzUrds|)J>Zu#mz34 AAASl̻f>^Y"[l*p-Y "ݷ"޻cQ+"KU7EH3&"sװݔl J齀oUm>5BDf'aISJr'eEd}P,7ߵPVndy@m7\MO6BK @N s>Pm|뼜ﻣ{sՕ*I䟕(#PAAM_\YbC~ޮl\?o/pAe+U`FOa0eѝ"UvҪd4oa{S9\Xv'X^j_.V-|m6K}xO†nJQ0)m'= xױާ'Y4f" ŒaEXN74[vɞ6u/X.T7 #PAA4-f"Ҧsw۽ f"ADBFgOK*U/`h c5sĸM'83n]}|<ܤTxC|9s,\-s~$ц4"-uUssyVDp}gLձ7MIֱ~+[Reﭙ'~7/pCf-IVշݹe;UG@;%f@MU@7de~59^Mޣ>8#8#85#EsKU?lWP ZO̫U(@^uccü^^*zXOIc1 Y5_ (lY3^kw\uQ,, 3[@SlIIa[^oP}c7)里<=} WÓv&gz 7Ywr ,kI@?} V7`[A:=E,AG kCf   4,]vG:u[ c{bƒcdybCap]0c0UREݹc]}FcZUGTS=fg̠E븨vϓ|^U{,Q{t¬>Tբ]tt[Xkak~Jm6mwKQY5F    " ^غAM#PAAATLV+Dd1`i`P@,     ̈'PAAATh +:U ZF    Yf@AAAA(   ` @AAAA;XAAMYCS, Uԧ!\wgcSD5L"ZUG7>AxAAATxxux\Ⱥ+" OG+RDzgU6vө`&@AAA4"\'"{Tvf:@U7hl= ,KKsW݁3BTu3GAAAA2p0u &k큻p+깟n4AAA4eg@Ug'f45AAA "ϥDd_%YXx CU: ϖۊʉvog[` ,ͪW~DTeluͨ0rVDdc~uv{*5.{EU6͂ :()o\6 xYU(G9MRgv`g` ?UYg 9_UJYX!]_r;U"AU鱩66o\ Y#c0CmM AAAc{aGrTBDz "BD`ɤ<&"q:t=.no\%MYyU.>5EdUйkп ,<,"H۴/"Oac9x3#"i~V!6CX])o9,OA0DDvOQ1?櫢]znn:z 7ftkHV^i=ӭ5k'"wcj́@'U"iJD_XhZ'78ZDv* GqGqGq4ʁy(pKu6.[BQ[.?&'@ǀ9\x/; ں-( Id{!خ_s# `% !촜~_9.!_ f<[c^1?'fj5ypn׽Mkx?Ck,'G&し湺W{ݞ9.ߧȚc/Wwamw3O   fZ,Bļ&˵q#pUW?_W\| ۩vLahyU3NrRƯ9ٹBv^Uշs9%%/(Q7p`)vU9]?.WU'}Ba;?"]DVNTտJ"8>3ϔ1O9RZX(^Ԙ0AAA00ٲzX™c9bjC +?쇪*ɏf%HU'7 |.Kk$m4/c`1:2WZ]?%"RM;5!?o«V)7Cwq&951ܻ9yo6Y>w #PAA3ꤜ,K웮kyM,MȒ /UG~]W~)M(Q6*!όLTVˤ~J~Lʡ53uׁ̗ d8t.U}RZEU,Ͽ'pN`""s #PAA3cJG;XՑ"ϙV gJ~vgW3^ *3YdxVzAѸ؂oZDrLkjw ST_t/lUյAP0AAA03.*"-ˉd:EӃc+?BWDGς{ /"?""b; "UuȜ>Wz>wf: %@AAA4&YmEd?)+WK_` "CE^PkrB_DVl>XYD$"cxuoV""W_g;]AY&o/̋ry\Uu,]9,F"ҮGd%[QD&|!/4u՟ODj* #PAAIyWij5IDǎxYP!"yjyx2#]vf"%ppf;$}gkI߭1ڷ5yZYVDV¶jm׋cs7˂{o3y5 D3 C׿1/xHIX>ɸLAUSzIK_kC9gPz^+bl=︼EnۈHd<Ǻٮ:9]&kPk:΍ѧ"APG}qGqGq1kY̓V-ң*(k"֯wX"SeuLB}lܗ7E^fJN>$;^X\ г%k  l[sjau>Ķ <̗[/->みI y 8('+rަXُ>bW&u0{?l}I;m)Z>ѴQM.   s,cT \R_-H /}m[Nb؎Y#ZMRuk, |xgբMUuυW}&JX~a:׷vf[Êxk `*a   f:F'(   ` @AAAL)"Á,I'"r_#M   f<98U1 D    f",   ` @AAAAa    h vgUth^WշE@K9HU4> U}ȊƉFUU9b܃   D"`sUݶpsq"RU>݀529@/`UUK[gnW@P6U}!)[XǾ@͋Ł-̍VƈFD_gw# %?תXAAD`7bƆ"ң}rןϯ?ʨժz0D׋ȧ"Rd<X,\&Զ2988Xx^D%\T_ ["B5UuK}""7_c=N e@k`=>L5ZOh<}?þP]x_D(AA TO U [pUY>ͱʛ`G_bd oEd>`W`k3YU$m@;ȓf:b9NU8`Mkb16u[ y6]Ӓ/X^ToQvyxH.yP8~" '+Cl3<#Vv{|lc62y?f ;9n&Gb!nPDd!%_B|6+c?edE )"QDd̑En*"|O0Lfa12<{=X~-;#}kɿ+y1H7xl̆͹;Tɤ~TNJd%u5  Um [_D6*(?O3CĹix~/+'h& Yr>T,>uv"Ln,ϻ"ҹ =N?"9[@|Pbjr~L.z;56^c 7c3[2`9̍%>K_;f`scc.l¾_{Y0lvþ3c߻aؼ   U$:aVB^绂e[>(?,/ȜLE6Swr0A֣ ?Smдxcف[UUsewbFR۞dJʨ ^Wx1o{2V9o߰P:zg 6&x - =90ߔ\YY970VD-XX%X<{ t ˛<-VŕaZ)dPUDdI$`N/.V0,|nf,yקXU*4g4J/y`UMXAibڋ\>)" 钒c2pp IDATD)\d$ɓ1D']0oůA~^ʡS_uU=xX(4ˌD ¾S0﯉mAALA9ʺ8 ?ʥμ-:(&d)b Q&ieFP,F̐ѹUv˽Ï1"r1~U]r׬nȮwCXX`Y,ĩDU+'˼ wȗؽn"+ȣOrF Y"  ߪt,5 P<bUm׆>Eϭ@}^AzK>͸HiJ 9%tByPNrTkJVʤuYNyAYM<~ƍq7aajQiAg?W2"2 3 .}c"r"p-YCAAMj@\_ra?m ds԰TII/ 'ۍhnT/1I,)jؕ& + l:`rlWY_sW׏r_l1UU}oxB^{kS1bU=>-RyYPυ } S̒4uN[DoU}|%("  Du92.4pi^ x(`){%,UG@DZ`>P.H`6_ۚMD.kPN%Dd<O$Jϟ*,zUs圅B\h\Ѹ\K1ӢM4B,Eu!JC2̾_CSEH;;~y[AAA,#F9˛pm _-(t:2"\UDVzaO:-.(;,ӓL= B7c "NJH(f*:3@"lU }ZHDO|ɿw}qp' <آڼLUͩr)KU("T K^*1mk"%zr "ς3yXףX"򩔘Yx4c,"kP;GMy/Uд"l} SY+`F1z4yPgo׿SD6pԵwM祘̯e TR=R?Ffm%؜C Ӻ %`AACMJpcU[atɿ5mObS_ntmہU_y{]NkOc ^mlzaIOʣ^_{&I{szy ,şX"ف-ǑR[Xeۍg9OUq~#^~l!tX{l38G5#g/c^: `[3+w!,Qp,.[ ~9)[Z\:O|\/kfϷ^X8Az6o94_? eZXO^ X>$,TXo[bz1<#o-,Tf ;;f׬dQ̠{_vv<vҚDy5zO<6, 0Fm,dse776{<ߥc1~>fm]mY, <}K<8G`۠t*q}_SHlGzI1C'bl`[aHZş֮/>⻜&8r`>}FPSWi-8vvUջGkZD!*4pVN<*8Ym+ظ.-~i.:i{]1˪X(cYj;m-@_a`WjYɯEd09x x8CUI͆-ącATJZ9ytcO׵E<*$"$hNE-}ϯ˩ [^-Vn%s^7c+uĕ;>@UT쌕~mƤf| ٹ\U,S])c آ p"fkSMq-5oow1R5!"`ffy Ewaط9x3kU;f'̫gA,ͪz[Rfos>;|w=E#/a"fWUr!!"SZaU&=eܮ7 6e?UJDza蕪ڻ  XK4Lg"RjҐmF Uݱ>ӓOum1Ǵ!nm7~S>ַmוS)oHAAB}ySGU]ri1mȾz ԭ)Cm۫uo [.3AAA0F@DC    fk8Xc "SywU(JAAALLo    fp     @AAAAa    #PAAA,@ٙ 쟈W5EDzOzWcTUeoɪztie`DOU'MgDDdo`^9TUhL}RDd `YؘAAA$"-oz݀jN+\"Ct>h0#\ϴ)7]C4 ^vyl>L7#fl , L5?ˁUQ#@17F&쩪o7>AAEm[ ARCkqݸ3, m"@UΓC'"B}\֮߿(`Yz?=mȵ>U=@~o*tzDN"?jq5U PWxZLUT J -؊AA3u {VUf?D;0HUIGֱ:__X} G{PDČB6`Jcx Rկ*ϊm`~L٧cMllEӱϖسZkg8v f 7O(  E'z2 T˾7R9?//"5&AF,\x  V@/^5lp`}`$p>X^we1p]4r."݀pفiXY8XE}T2r  "8X xDU}Dy0[ݪ.Bo΂X|سyT|܃Dt!G@`Iu~%"]#̀KT餭mxU=4)ަ/82 < `Ϧe@{>T$F~ZUujs_U$͍͉-w`Po9X/YQD'aN|l_INؼ^{?`ޢߧS\9:\ػ09|ϧ,iދ~3l~o=ׁ/u['`9̖.T%k#˽'j8x6;45"K\884`M`?,coa5[U_)V犮GGܫ26BG{/+WdݾBjUU_J?k `-x{\  "~QDd|E_%Kfgr~. @<FzLDJ 7/l=E|e7X-س[>Tf2o._-m=/at˗s(;b,亩|f8Sow""Ԍ9N,Vנּ3M0/ųR |@w)Q7^ T+yĕJl \c߉X}͉X `` 7He{\=\?E7R05<3D+";s":6w?;a샽m]v}{83n6o%% x pAAہ-28zy^. W{WC|N,eel"Uw*$>ʮ>z䏹|*묈hƼS9i5]"ooD!gqDvz軧픓s\o-.X< S _sXNqA>9"5|?.ɚ1D\ZmytUخwytr̕r\~IAzYDˎ.҉la=Qg '#ҹeguςɘȕ t R}VQGܼm.0'וW `dN 3&VnjsU^ 3+f[ srds7?[b侷%F+d+zY\f~aklAzjGqGq1s NUsIآAwaiQPV="r-'e\,CP'ˁtV-x3ŒT5=q{P+dڧ!Wck6m)"iXԸʗTzrOuDoy/Z2XCR.Q]Tl 6s]룟}݉?S}mkrfhlHi񢖄;nhBhExϬaߨ39p̃FD6¼;Tհh}9{x^pͅ0 efX媩琪N!ARUQyU\X^E?s߷[K}K]Bcsd*v*'?E R)ga>ju=   6'taUzX]la0ON-P|,25*?bY>VՉe^E[fg=ZF+]GkT1vJ(~RRU )ǰ$)!Rwn*<-ΟUX8c'';r}-8;c`^*P1O>[U""P5bY="rfא|U,""s'JeA[E+,P`ayDd^U]P^(0 vfqwlTB0HˬU$"c"rf }QUG{(述Bp-ɞE2COooma7:MO8~ tny$u: ݃  rCokMXк2d)2tXJ_k#u\Tvs:mE˷:墪cC'a9jrQ( "{{YJBq4,/"8p~\e3{J\-9pmT0#~XRr̔'>A09v<f> IĒ}/Ri 5eLDV]i"2pݐ;%m,33QX&~^|T)d{*ו;ҹϝ({?f/(U=ҟio`_?FXb}G=m@MY =sf*i:8re{,Y$ɷK!"`F Xf~^bY=AABcz$!!%D9' M 1`s4L4`l9LIgw{zkz{kn=0n[%FV4#s"H$DG6lRuLdn'8.Jeac |5¥sQeJZIҦe*iJIIjiE>IsߙUfnè;ټ7_n(n%gdflw\IޘZ"`7kBr^,xdOY9Kl<>0bdI3Ū G3̖Ѿ65*mI3}Oĵ{ (I;b$d m撴[laI%~ef4-qC;Xvn)$ӚzPz%uЪW"هfvb0XҒUsb3@RߨyTe9IцD"H$!]mZ7_ۡleJ,BxwZpZvn<[G\&#iz|ŲqKyPƁ\X({>IݿH 4nz5iO!YquI %ʖJm5/yWu ӿh 7H^]\cq*oXr0D"%Q.=U}[r,L/?;{~|/_o[rlG}5۹ go.ۣNo'ݫpxg|7 Χ1خt M$D"Her.i0@,!f2-A HZ5 c݁>q@q%4Mmkr.yLAG>WHZi,r= (^$mIs+# >ڳJؔy4n8fVDt]_mf * \/㮷+e[li^ϥ!W?c㓓E<ާ@L˴!L3$x=p#O5Dž©"1)zvt%͍n(i +{ۗNW;gc34&syB~^ͼs6\*> guS3X}Wy{ple\Z!(3{$'Îx̼* 6*] P?W8-l!f{;W|~d\>#^nhLAS}K3I$D"HLE HR!:Zk5jO͍1w)UmIՃ+.1_U}jOVst:*J3q=W}]]nD"H$ &P3m-ru5Ԛ~[7>)ʡ-izPoke9S{ʴs'{QitTqArK$D"H?T">H$Xe#m]*U"H$D"H$JIJD"VF[^~mlef/vTD"H$D"(e H$I=pſm'D"H$D"1@D"H$D"H$aD"H$D"H$D$%P"H$D"H$D@R%D"H$D"HLtw0IS;*OBf]!KG!in.z3J$ ߛوN{M`;.물ۃ=i#F#])OI>0R f>0VDkHX=toyG\m U#18W3{4'v.ڶo z̞h|< +zH$6)#Pʛo``~`y`6n$8Dz1s:[`r #]#6fy/-NS3GM@6٧(Wk̆+%.׼N@RIW}߁I:Y ډTx 0piJ I ϙfבQ54QN'< !"^;MA3>f/q@[܃g@]@4a>`RINdf?vw63$]uee$ށy b{ʻ_̃c;Ic;l938,g쵸g/)FySG3^JԞ|: 3ep;ӱH̺V?#;*N`E` \H$n̞HOFπڙWXT`fwwHx䘛N|S['&5 0cis3_HL7c71Hc0KΛ/Ȼ2tB&v+9nV34_ٳRjq|+3<5{)6˫|X;]Pg;3WYfA`g|g[ɞ+G#oŀ)쓮$H$MiJ_ j;wKژW3{#-[?fy-R}NP"^sg([Ƙ]-Gbw#|E"(d*H$Oڴ~v!~e$-?nwɈ 0&@T0H2'19؝v!+ V 6N36%]K$3{%W[7v \f:~m2o{8EWyƌ%ގn̯ Vx\hG)ce̶xhffh/m'feq`Z|[>(_e}.V'OV ` 8+oW' l;}?`U`fJI>0>Nm+ǖ d32(@g/fCi|~,U;ϹF~l=>kfJo[ۇkUKD_9i[u|\d+΍o[ >if)}x̮nY]o+Ь_;k9 Ό_߁3]Qm|vp~.ڍx?yd.l3kZ,A}A mq^?ᶒ)44Cxw7cMH$ ]"~VCWn !i|4mT`*+n9(G⃒ Ib7>->^߃m|@yx;!'H],.!ǦQAp pJ='J3mgck\(~2i%/";Y|m}` $ >ƕ;[HY׿Q1l+?2pF|rt.9_ Rޤ^|GԒ*my)w%'?My6q" yG1+F8Qy:'TJ2:E.ᓠqΨ寥]/+ut-Ѹ֖u_!v|{vi;o>Vx셷 5/|D= .Ґs5׶=>Ar.J˶ 4lgu%>C uExᅬ'0O㓌%Ax]8[rdƞN5f]7F(;vnvz /Rs-z0q_\9aUf"ʁBnEL)=G/C^6.dXx$#kn+\1l<&iuN ~F:kNA], Jwܕ;{ rp|<8W+ێN'ׄGm(J̎?F}3QIS#JZ/Ak |l{+)x.f8rr9#lE\ve.P\-Hl/ZHkvo߮86۲ʷ>b[.gC?ҟW[ o 4uŘH$fV>0`V>· *I1|0?{2nyQ%Gycisᓳ _o|SǶ/K¯ G#6}~L!|1/2pxsQ qp'„2 Xo(/W Kwʅ ?΄+W- g LJsFB`B,^ˎڅ#Gr( .ٵ+ qo.-Ș?#TR) 2@\( }ay^W~o;}uoq:?5`\xw|0Cᜃ"~s8Vlp?/p~{./w0gs6v}Tr^6ؠ$pEhLf\Wq|Bx\q60Y3q9ng\џoWDMk(?9ף a='Ŷ+/,X88vd.lkԷ"ZK"|/&s)=465Bo,з?s*#Vh? ³q ih|o ~̗'z̀- dci-IIꧫWdM]bgK?//IZAYA.7ϲ?fv+~m>^uЕ&-΍۳23{4̲U!HZVf6>9_7|yz7#'=`UWBAh|~:3yšn%y G2ͬ~oy-3[\#N -ff⫗-ϖ7V݂Oc+Yh]u85xT*ȶ^47~l28rSl32UyO(dy)( DVƿqSa?dȯ?~*GoeoCeFr*ob=.% z?/>{U|r>:<,GwLJ/㫽⸱MĶ >egʟ(Ӛ3`ZI}Cyy+e*rr|ئ~6C_.;F{Mݡ&yYs/דw᫷]+G$D*+ⓒqjfDWzKZrA? ?p< rm÷%+'ߙq"u+2v'9I}g%Z?V6Hꋿ _IWn#hT֓Kš=':l>:̾ %擁%݊/5^4I606'.0"}PZ(+Նk![ Vɛe[62RތtJlLIWi-){} oC-s@|`+706^$-7?S «UsV*=k;bU|; Jhlu!˯u_,ުj-vnWLK/q3+D*4: VL)oKiRZknسqӌ=~8IwF_lL"HL\T 7(ZynxQJb1O]b1EIXGZGJoϦ)ěɮy3[Ř@Lϓ{oZWT4Jnlfdo%Pl+^6ar}͈7I:W+]֒4x@/I*('>^0?nL\6n߬UXm$SMD[d%a\cfGCXu]I3Y&3s=tY0Zٱ_y۶TmZ_0_b |ST/m+_4W},S#iVN/A,[E]mɝLvo4ZԇZ;eۼt nZ9K%DE6lR|yu&{[?젤eHJM32#z2$,fJ"YQx%JvJ(i7Iŭ$FR_[l연[]]fңhIfxI$ 0o]V mT×$hOYۓ3,c`f/-?IѳY G(;V-61!ٶb{`wvIUAI 3ss/>Z;${Al>v-Mf$m#Z:LÈvzWݦ{,ĪǬ^gۧ^W PSgno4ɽ5ut~%{>ܙW<for/ ZWVquⶋlWIE%휳_VcOIKfv-o솯L$6 ]-gmVt% Ol\ǒ[!iIאFzvV0V;qM _J _F/ܛDFwڈ]_%-YI&߸UPw9c@ qOAi \:Ӹ*{!X{ZxO{ڳsZ"[]ͩ娼e(:j26Y%ٛŢlSQn םqrRDqhe u oqù=fI * k޲G742QdFvH؀ *ynil.Ձz<\.$g>F\h i*-nl]yG ҇FWlZoB)uD{JY•N8magN0(6i[۔=_bf ~G$^ËM" IDATf4)ӈ@ZW ߦDaʷM-a*K|hRBҕ9V-Q.ïyK5u6Յ E|.w>Y?2J\;(;*bfOi4g!!ig[f'vo81H$&X.7 ^]v=لk\߀8?s+N1;^Íd7{  5Kj1i*;&\H8W`|ݼϯ4wG_kqeM.qMGG>SqXi+{w-d~_h!@Y| O N22ǖ'چJ7nű-uܫ/p#Iڏ!ÜG5**s~6zn?\!|q[kK|\iR|@nQ|g?eC޸W)36up{[Fwطls*{0$YWR|{)x2yr2>*t8ot?Wűz+ގķm_ m0-O#n/|0WvReQ)m9!sϸφ{sZ42X\p36@GYoOB̥ 5~X!w|*ʼgkp%ԖFгʲL'G{vN"eU fȹs5?}N%m 7ޣ_Tk+E:SUY>F';qOGo8#&c2ܐ#k%w40+~nF[/߅~/xܙSKF3#q{>^ȞթQbvƐ2! pE‘R4乾筐oOqZ^-5j}?*;>fz˺qB^?stǻދ_f㽣BMsyz\l\IO߁4ƕy_6 cq6p9Y gCQ>~'t6k%y}A7Sq/ϦԍqqK_q:|u 4 "#""-ǧqzF csqۥ| ;~sw4\EhzT>>̌"imA\H˹7 |of yFٸ7 დwYfQIVl/I f{_ˏqܵn%Y׿;^/ (fE}u\s:m#~qr|bx)s^n\)=32>_#lT.޺Bֲ=iBA3;.OՕV +X!ʂ x[WgW|}+6N4JZ;*" װ@\dv(V,|rgw3ivrtOF1kIPMlܳ^|x^? oZPpcof"I;/z3+; Ǖ"ǐsSI#@=G'mZkJ=;2|ħg/ yJ$LJ 6,i% ։D" hIF/m]$D%sCq-p[D"1@{eD"$ƍw*;%Dʍ7$-i n$N`soD"@`m%D"Q &=M 1wH$*7!H$7I H$D"H$D"1%D"H$D"HL$%P"H$D"H$D@R%D"H$D"HLt{qIS;0;SIKߟ])YsA]%OG#i>`\feWӑHPif#R"imLgm`]nᚦ`=U<D"H$DI Z7 ``~`y`6h;)HJ ^.K  IٟڑT &@uV&h%~=3'mRDZouULk&(%M]-O"H$D"QںL<ѹBf\fmne)"`IHZOp3{-徎ʻN ОDɸgj9OdqjOKI:3u@݅jqάC:#"/Ui?Fy|]-H"H$D"Q/ڻ^3{6#i>0̮υμm}:09P$fA]$B7}Ew&3ڳItk]-H"H$D"Q/ڪ1D"ٛ]-C"11`fIH$D"M&%VCʎIZp\!w\5afVIsSvBn4g q'V튼8̾/I{H{I`vC%QnYp`n.H\}zim|?# zn c܎Hĵ ,<T^2}lfΙ 8$ΙOpqNOمoHkyo3Mfh+A-s=쌗IfHW셖]׉ ]x=])|kf{9%00 o#G條mfJ]282/]v0w 2’6W}}߿\ X6l3B>F>R/kIYVO;}S?Xov]3+p\.;6nlfV%6I~|SrnOP`(/qN` OD3 oG^7as}<ofͶJaK6n| 3;Vҙ4]T|<jfcrq֌8s3`f-״0+cߐH$D"Hv?+p>>W$ibP<[lT`*Icv|2p !|}o!Ӹ7Ӂay)I A=7{u\}' 䥸"$͝KU\9 `@9%k]7ĺ.nd\w5*bb{|By>m+J˝37: _ vdx>/GJlr8 [IZ#p ʲWzyJT.\q8#c2㶶OQI^Or\o_: +~vt_ЀOGgW +eL!Z^F U P`Kc{x}Z#<4*ϪalY.wZo}ɚRI=~ oskJ7~k3;c\{V\SG H`o_I[eiwj%o7^ޗPKDbd8~ϗ/ rυx:o 7-Ioo#v?𼖑=DZ;x,ys%> 7kD"H$ʘY>ƀ[{ *o*x$IUwxD!|OB wBZ~v.;>A!7.ᅸs+.(}saݢ _WP} ٣>, 7?vw\ːBBrIű Dx*W-?%{ ?"O/{)m\ ? 2 EqK@B|:=$Ϭtυ_{OW`B eW(wr;DUC#Q[.@2dfc[\?(=\g^sO=ql*e[)XWZ%i}-/ƪ奅5#~8srzԉ[>noO٩>>>>>tJB%i\O"{MIʅ_+4qo7^5&..|n2#G63;A=+>xx5\5T e^C-2hkU\9JX]^a|LEQX-Q7 }s%Z#P8v|̏US-Wrb f3c:|A-\cf:̶i圽pf6,̷\XEYӭBMf ̷o f66?[m6o0Ez#0sCXfν̊2ZG(363+6+QffO6X=_(ާm[\%n2ryaf߬]Q_]'i6| '2(n?T}hӒPėۄo'S2YX!,ڠ ^eٷ]"$}D^Vnc R+OV~_V(/cV|{nF+^%? %9Y|WS/zLlw2 oS h\iQm"cj ^},Ky^Pv3Ej통.wBa8<[>6+ȵ(B|X]۹OKJ iFWd꼸ʹn ƈf&mZE'୒(3`H1m4$]z[5v-go(H$D"h ؆Y_=|Q{i20%߬C[-)?U5Cu,>!= 8Cv y;>jfⓥYY+3Z6k+|MJ,JS^~ħ8웰t8: 8Imafl5R;)i2يJoPېw5tɿma[(u7J8< v ^{$xe*=i99rlKV_ok+ŕz;t8Ġ,D"H$DUQ݄SiQOw7g[f>qW$+m f*VNJ, ǫ!xpO2mҚ$,3۾*bfH#n@ܠZf/nh[Ic̬B3թZuGq$ b} -+\i; WhԻ ӆ( *?k(ӷ6g=%d7<u {f)OVclX҇wG߄Z0ν"h&Xz"H$D"Q32fJS|ѼJڼ b3÷.܍O֫2vytJM%-Q[ʠBj|U"KToYJ2K߆K"iאU$ ocٷfv mL{ *wI$$iN#s+?]fd򒰶m2ISʆ(W ( )T ѯW=T8\IɓѿB۞#mA/NYvī9DPV7(؂˨ڣ}A >ylfm{2H$D"H6 ]-gK WRMq#"eǏI.fmMۄWNiO_ 3 xc$dIE^l"V܄-ߨ BB%<[17߯- 9-F%,75%e[500Y6q O)(~o_{ #it.WV{]\OV%QWʌ㊱pi4ڕY߲KZ n0s[Ҫ~/ivH$D"HH,a(4{sAUq٪Aq=ӄg"!BٹR(IGWmD]oQqB1}>0S:MҊ&^x99~)/D"H$Dþ\q`ɡ#up&f iK`±f6n'mWgx*s!`;|R4"C\IsB6pOVķq7g(xԢ[X '5 y IDATtӼ,?5s./Ni\Qk-y 8$w#`Y8g8x8 % lo?8̞w;?W| =ҪʣY ^wW LC 3ۮBmf7:7^/i9fvK.83Sp#[wkz/slpJ!fvhJ|v{%܍-]cU 1S]pX3[O4_tv(㲭g]rNȝ]GZ̿'뚤#Eq9'PIo?[ʕ=~v|\cfχ̇me{uv.x?B WX==25s} x5W9+nnW'mˣ3|I:;N df[Z׹c5WfV6%D"H$y&@ͨǠu'QuP tNIʎgZR*Ckq;!ɰbCQlK?vzUF̧ڒ_GE{jBIqv0;$@D"H$z2*ʌ^U 逮.֜s6 r.;7Y'\|:Ib;Q8HO\ qyZqm`Fvrg !|wg"iѸg:f#SneiaH&uIkw,D"H$o0)"fj!3(书e!i\Ցuq?Gz ;M!hf?5\Yy0ޮ'J:5c2 ׁ}-^r q?߫W%yQwsw D"H$o*$>&6gIvFՂ'̄GϮl["c3iftr|ղ$D"H$%hkE_-D"H0̺ZD"H$DD Co\W-+iR|!i!`- fɀ 8w`o!];I[h<4gķ݇D5#헀[pW32{ ?N4יٽX ff/l 1%l < ff9X,$R#w0|kNƁjͦ!fYU]mwKw  wKS8) Kp+)Zm}ur9w;,| N20wEC.1>\zh&f.PķnUs`^] >o"$`c@)7ݦԄAUXwz'z$p<8,o;[? -}`~] 8UR$.x 8/?0UՁKX7&q09 KAGFC%e;]R-Fa) މpquoN+Ov 08S?$ү+@Hkj~Vg-. gą /IE?0\RO,ᶸA~>I'ټ xߋߟF:IHoo"..PXoυ;o ~{x'/pWS  ^9PwqUfux)x93?]qIC4?XDy OC#mīy{\pܑx{<ѵq9mQ[§/#########c,8{mqĹ3L7M}z> QhDu+MUfI&CiM1V!Е@zѨ÷|p? fP" &"q'{&bsVD#pO U&'ehǗm}pJer3;Au7GR0*0I>Y[>nхvnpIP=)p a~sqF tfw?8W ):]^@GYz9egk{ M i B1oيex7'UJ[W"oY_7N_Zlt7х_c3{.{d+\Ufvh)-a?#;fv `'R>oL? WЊGtHZDT[fvd 0xpYwU~!\oCPkouxOLUm~0]>V(p37Gآ[2222222222Dtpp%v?_LN}8BX<?|%zظкm<,N\+jW \ltmH>?nx__F2G96U=s]T%.b'ؼ#4H;2F[\kl\Q'+θQY_3p}lZ(in]55't22&}ۭ_۸/%B㌌1]ϛ=p+ߔoR)XS% 4o8w-LVD|E,!HVҤ㇫a9$FI[H#nFsNI?E%-+i~IG႒oV64$G܈_w.7H_}) ֠?_௓x,8I[k^߁%9m#k7:Ԡ8"]\#ŷ,i!IKBk 617xX( gf>&.+1<+oGZpqIHCі{f1W4QpdžNlq(Ger0I|Dž= (cyZhm5 -G#ɢ>V~vK1U8Xv.IŒގ`}$-ihwV UBQ?t8)O$ cOH 5q >r;pDU[)xi]?2ipm?|\͍ 41^쏒Ρi1 ^7G'Bzq5Gf483ce)\.;̞IŽ kfu!;%cfF 7jJ.~sZ}v7*Jþ?-pQUwfv_oš*!_gfWUu \Hn)I3&xypϕ'Tڛ̮*-km^G\TEh#Hkm6oEppJxu6c4,!I!;7!u~wde!J[ViB#et'N+6x pAȸ.y' L\{+&kNT{ sxL1!lo[c+1ZoWA w`pۣc畞D#>$-% D͈ɻ~BDgBFu#]+=.1f`f`?I(rG=w"{1c@kd7Ur=#########4A?9`.pPblܡu=-[>c̅qG+>]FNG{g*? m"=X! 222F$;x:+cF8Ϟw>J32222222222zY@ @eddddddddddddddd@?;:2 `d3N҄%=fx$d3dd$$-,S"bfߎ.~~ 4>st= %%fng=t1T">hec$L?]d%fToYHZ 3'########kh&$='  A_++ԑhe4 iIwHIx_仹$-|x.DI#vgn?X%YdN@ 4I ~oQV`.AT[ I':]$m+G%x3_o[{~N҃Η/x5xst񐑑zl'`n`GI? `f7N Ӡ|!yI!6}IH?bK K+$nn~\ ?mU?vQD""N<<OFZ,ǚnJx7P!*Ñx<\2f~8fv[7x 4qbnICUxXw~*?yfvy)TO2aft0ktBߘK  2%pudG_3;/~Y >n7pV8.xH\v;=$pp}׀>Vxa$x_Wc3p3DB|xZ~7EAܹpg_wuEYE?\efwq50Z51tTtfZAxُ^EԸFJ;N44|nfV9&ً̉5ܧx}gfOw/.ytB@uZg`W`9ߥ~N3 clf#}:; 0 }l YRWuex<k9͍꣊sc9Q3KQo0++oގ.;zv+>jX Z $i1|}qlfMcYpdg\r cM06O⛰CUC1ww=wMao4`M y7~I\$މp`F\ "\ʑ.Llat.p9=W4LVF7FJ^X|܏1TqM<e- ?YP!*b(mo{=Y1݋ 6F@}\za?  4O)l_fOqx3.̹#L\u |e.ʴ&n,&0&@M|<O} lُqW5b4ukpދuR ^ǩt!c'&yO}qa[߅e1rZK 8  L؍Hw\#2222222~07M[ua&L}NbyD?,Ĺ'W4(M} ~I}&Ts*0I~`H˶c/NNli#'e }o]"Ϊ쿇Uo7s$YCG@?Z%<%A[3 [?IB_4gWw;NZi-K#Iq@`@B_7SE#3D%A?) ~ЯK?щ>trY4߀kʕi}Iޭ|̖;>D? iD:&qVYmZ$!kuߦ4'Նk[Ίu }^\`7K6#.xN,Zu_/MٌNo@ӻ>εy3p=ƪa=s27k{׻j&)w30'y:,eVlfl]TбCc :o:&7ʸl&%3;~Yb\cn$kg20*L"ff)C_DuT/{sS2>EV*nOႠP׮Dž֬xOZ'ykfо5&%af$Bbm+dn %@l8n/7F3R> ff)+ϝ}Kk|c%Afmnm>[ ,T[hf$MiiⵤAI MAIkѶ&tY{POrsf GgήqQWgq`3&AgDži-xb oSYs=cITjI}R]f@p,nBYܸfH\UP/ݜef_Jz}53}QG T3䱌zsZFFFFFFFFC4zyvo6ƪ(%iZ+9>AsHLRgMErPPI2=СeB[A9Yt\t\5!θMgahe24nRROknO_ͬiwVѱMzfT{\Gf Ah I38NPΪOUKqh%H:fdqVꗥj.+cj*m mgl?o$݇۰c6>֎ffy .(= 8LҭMΝ6;4<~^'{&ڤWs5k[gKM4I;lng! ~3 ]ć'$ѳksǩǾ6z{Oi^ԯAZXw_UM[2222222~BhFt%kQIqA1^5G[zTЊ/TKQlP}a" a^pPnyoO@qf|Lމ]Wt@5 Pόp\%(#NTKS 3{nº _gIZԮ."^6ff֕]Qfb3,Iy@2M…ǛYS8Pv f0%Uw7I+eBI6^5Am>+J>'ٙ]FQk/IKCI | ,js&NXhZYnQ -F~efoYYYgUI6b4q>pM3̖ڂ_k`3ϝ]it]}J#i; z<6  Mh¦UïO{ֲfyl ;YKfe[%uԴlFFFFFFFFW-бڊW_$\"6ui&f.B$m1CJB~rc'~ 4 Ҟ*HVI+m}IFBV{sF?q-3>^|0~ #q";UBQg/iNxj<}-q QhQQU>e)\ඥcC` ۩3O11*iȿ!t?-x[I揹oKvrMoXz7 C+JZ:q(.B fYo~ đ -uGBLs9fiBm#$͓̝E"iHco]h=.x Ps@_̝F+vI%M%i\yZ'LoC݁ONQs\=U<Ÿ0x=/%)ijIH37~:y`g,qD8_ZL҉D7]G͊ze/ݨߕ0CP<50 z*g9 9I<6CJ淜A:撴-.Y joQ2y+i|عp]}u-i%jJM)gdddddddujIkH٥I~T 9 1?Tm`Y W׉yI|6??SJ%i+\lRzG㇇ipu[[k߸ߎ2y `k+{m,7rֿ'NM0CVxT&v\=\ز'Lcf$,|of IiqLE^D{ߊƛ8owqM_dz.LEnkthvt%Rg)(iq'.LHٖrS;x9M\3'lwIAQ5fvho"3/\u&wǚ٭%ǵGM;0zr?͋k <ʎ&:w~Ădfv{Lsz\HYh5C̬_GQKz~ce|?q7p͔;Ki\ C{U AyoG;fuwlk6)aTۣU/_o;_);*jf[u0wއϝOG^C&3c7r= &w>W"CJļr>>'܀TƗffq}_$ %uRTס;IfV^q ne\dfg¬مp{jNk 6h*{JNM@[M#˜q|ͻ"ϥpen|z~V {wo;[ܢ}z'[Q1?ޜGz*JhShb Z^iк쑼32222222z cHw?5Ӡ>\+_24n)H(d"F7#edddddN #iNM;dt2;hVv;;QsNu|1yB:<}Hw?>An`q3{{4򖑑%h|e Y22222~R}qn*d!PFFFFFFFFFFFFFFFOcOB(###############'^LҤ6%fTo06BҮCJ'Ώߚ)M6~4k3N1oVy0e|̮oe|+3=W+ R%_{I;=R/J'IsK Ow!i`N3KyO )n6{#&/M1 ɾ^{vV I[HיF??-H8~>mfN~u63{y, ,W"nf_2 ]I3`~u|G#p"¤f~_O[9.p.cǴx_ 4qAm@@TLY@K@Pf@˅@fnf=Z_8 *7r!P)uۆNh 3=ǒ~ 0p 0 y]^GYf-ˁa&ֆG^@`S|k#/-0^Efsb+OB$iE|ﺷ0b p>~.Q @K@;X j&`n߳AwB 7w1 rV&jf{Gy=18$23v"Q^-ATtu3nz HٍQ/$O~v}b+ғ$ъF$2?y)a>|._ I4wA٪=ꑞʣ' 쨛t30sQodfoFޗt^.OZi~0ߌn>F'$6;1}gfDz2yą{fFX%̼X?5H7ez23;?cPﯗdKafx-rM9?⇤pKKw3W Cfـz+ߌ `  pvDFaj\H70^ᣛfWI5ºqՂ~l^5M0+^z~36/fc!cslDINt;-#ôxO(٩Va0g/ \U&ÿż!@|<32p{ff$#Ma~FFFD%Ȍ]N,c$-/ȞbF3$njxo$Kxw.7m*+*!Is?%jpt/>.7W(C?F}5Fԙ}p;p#p q_I3O+-n:pHX2x8>k(@)KP *r3K'I:?^&sE=pmyfv{)̬Jɟk;'?n?se pǛcEb3):>IiJ'T]%7"4X^ G>] լpـGu\69c) ߎ-o%HQ}=ׂ¦|.+Yο}/q5"fv\_ۭoqQ~$L |Ja7xA2/ir\ |Y|-;FA/էvߟZ1V`|z 88F؃ړ$vWa >ޖifVi%i1`7/]T!q?k'Y?罅{痝v^fNT/ר/kQq +u#iBW#q%y_ŗ o΅~,\843qKۯ}Ϝ|%fvu"Lc).jxߡꃉz[27*5u}Y^KY"]mfŻqX}~KܷƃoX)#+9$|+X_47έ;4&W[魤30}?%\(?Y%3;"טٵ%f`|^jfWV2x9^5s4ꭟ!f_)D<,p޿0SfFBaց3Q>py]ϩ4SR+kB|>lų>&$܏;nt3VJ7\{cN3 0 ?t j>6>Ug$ǜV>$a7jA|N|ho}SK:ص8H5J[.at_? ńpUӀ֏$U ܌X|{h?#)+3-Cp|o-ɧ8 ǵ+'/fw~:>ufȷW`^?0\9*ySN;]rl/DMao|{EIx_i~Ok?>4g#̍`VñI7V/LsK*8GUMFd_0" !i0. y?m/G܆%a7ʁm:GE~$X;ޮf|CּijucPlF{ϊ .Դ1#=4W!ax =vx.Қ J_k6wFg|?.9?h>_3x,6fRѱ"laW|s9^&}3oY/4~|2KvSbYEGQ.ץ:?W7Q'$V."kCH܎wStj3cSXoo\Ż_E1M,Nqx}Z"LV]LҠξ6=|쟆oKkm6@Ŝ0~*׀@?ߏP+[r5ޏޗ?V\67.t4ObR콞 7al7bq|}v\xb-"x];x}*OjƑC6 Iu7s?| !̣ib>;/!x?퓄kWCU}Bw/ǻ t8>݁o;AZqpB]4])d"歄V`39..^ S+7u`(y(2M "9xiGm5>}^sZn(c |\}b\ܓWůh??+@jc~pW\AyD)#oA \./F 9C@nBާ6HZ+74)<9.]?_. Kqmϓ{0kس귑\q_K/,;9x{D)H:o8S *_jsi,>׼ax i\p x[0Y̆Scifs|ّY\s.>ug9f{u"xle1;&'Ļ!x~IaZ اA]"%_ߞtWEZY&yX*-^ZxwZv1.IMHWX]nZпHkx~ |@;/,W]/'a/nh\'_SC4CŻ?VL8xO}։>skB/N;D+Һ=]ЧS;G'qJǛ#iuF}v|L_i렿L[ ݀E v1`ID=%;CBI{#N* e?&6Vn*([1W0%e8_Ļ{p`BޞSk/. Z's~URNy:?ۖ[EC}u=ڞ΢Jg #WqSZ|@gR3[Jkk UO:ίH|ޭ l<3WB{_$'hHZOnmՉ;`.UdO^kީ'v.6wdz=>ݝ&^feūCBtMNf~%ġ:80"mwkSK6f67+L:ޟ>ɝx 6%7 hws u6;1N+o׉{~kfu=nfɫKn_}L47zIëlx_i ux]z7|痉&h-Ikǡ~ݟb%Uy3[:sCY<}9߉46/UDžDooy>:j1یUs9hOq.%Ph@V^2rmu~7>ĵ`f'k;:mEٶ|W_Pr츀ܾ{dO>ơ7SWa 5D\Z8EB/T&P.mj,ad4}6ˇ&p6QkvUԳ}%%`nI2E=†\⛱[$oA!M"L`)Csq%u r)}& }.=ېRi;O#)6XF\\6IwM!DI)]A\B&EU]4DOQ3|ݷ/Wڴcԭ73ZHdinjp+Y3Sf6P3h7~Fm* e@aUWK}t*6U 7*dkd~^뿙RIӕyt;_ƿ+LR{f;wGh)k`II>L?Hz]&6 @af6b}ZUbfH?>nEz&^U[*@Uchnp5Xb/9#|R)\?e6?{\L>7UYN=K'n4~h >p s~G+xY>+gЋ5xʄ”<=Pw?]Ofwљ𱚞9Mdv;hɋjY`w/.'@ @B% = ./a EAw~Ꝿ}{fsu9gTUwWWWSm4o'e:ϟ!x^g/iohb7,sbύ暮]Awj2|J Z1>=~['oSUEdU }Pwd.CJNPUK6M" '#&+;P|!p&vRBUG;+sr16^ Qb&@Uwﱫg+ȟ q!ؕg0}m5lSOڑZ& zZB ;GM<51aKG1FP;U UFpX=՞'oM@LDdHiȼX>o}O"I۱[ڨ ru1Gȭ75aSn|O zآ'ѕn?v uf? ? ΡFrHltm9qؕVШoM46iLWP_I*M:t0T9wckk0Me30M]1Ԟa·`^Q?6r46? +_Oj"h-ML!*f`̶ۑ"r#KUmvr;bau~{.tUBD.xImJ5T1QvފC=GX{:׎!sꭢJI?\ ƒFͿν~hxr-ȑRvX,E_>h@<  vkh2`4[FIJK]Y4¤if4tkbu 5Y'=1bRJWj/(!Θ:aĻb"2#6iWM[7`kx˿NOC霈o>0Um0B0fhUuŮghuWS5v/znF6<>"$y|G*T|#g2mFm\Nk CEHV/IfUWU Nm;>;v8}N[!X#=6x itzh  roUmvRZ d#Y BzqҬ/zb }UuԌp7ccP#U ~Xe{'>@n~ ?~)" #0:C}4z.Mk&$ 6Nު >^"rޕx }9}ϱ8;KMgn=v ySUɸL+ 4 '70kau!&DmV1AD zToLի1sۊj1>{:FRՏU޻ml.\z3Wθx>Sz8Li"~U}BUwT7=5Quy-ýnU}UUN\mH &/9QAMo}Ed4JЖ /x|L!0"2MBDGU_QCv{XɅsAGruuOh:c:dCL=OXQQz.M0cDg?%}םTpEd\Y:p]eh}U_4fHEd""AyL`4_& !oǧ7jo#-("HjOrqVKd]6z;y`Ĺɹ&wk&Y-[6Cϊ]jU͓b؂  *v+q{6ډZD{b0!Z)1 0Ln jB+k$/TG5o;d` ?]1yǡc;J T^&9151P_zw)/diڢzS1ȝD4·_% oK{{~]3{z3K^0)1&=pMv[[=o 8|[+6G"9㭼w)szlaNuCB>q '/x"!Ln\='mm`dֆ0_.J{"-<|$>U~;[$-e OOLm`j'ϦϑMo%12s'/6[>^a|gh;6agm,aƣb^8fifo/E#>wwqZl| .옚򧞇91c#Ūz]P`(l rmw7#=qj?@+'Ƌn[qbY8?`m"l1?n< 8O/ÄKc\?Q[Liͩd:Z_ 8*r?Ä7= 3$~zz5jg ϽNx'L8<9UZL$;Y.7~em$:c1A-u|]۴cPi>g)[lm^X y{&%1F0Wdܦ)Izc6&/`:݀c^_xRM0Fq d&Aux $e&㋢0G4Yt6ܷ&诽攳I߹ ~@iZo㑟W6)MLmc}Cڙxæj&/ޢv=0y 2-V_ztL{e8'ǼlaTSnz(u^Ody|%3}4l^Sgۑ؆CGͪTil{shU~Z=c2n'ekb8L]A3Ƨ4t2n`9`\]mvcDy͕Ga܅3M"5&i  ux؛X_y,N[[ۦ{J=y96Ȅ 7<뷰Oq"֟?"%v>%lMp'ՙvX) (3/x;6xtV{1Ӣ2O4Uzۚ-f&LYIu^Ic&t}kxM ؜{&Ş'Hy8k_Z!PAAAABD&{/q^ژՀ$z}FD6oW3ا}Ac  +Cu { cj7qi=Dd;F?rv=yȔLk^jjtcuEj>, ?a,f(O v|f%{:AA fa[UsUPP0CD F͘pf[hUG?i?Q9="*((((h ;E{_Up!"a9tĞwyYU,9GbG"*((((((((((((((( ~G{9UWr9TGoAD~ NSկ{9ͱNEd`t8g֍H[݉ "FTv$)韪PW-7bD:KU>DdK`*^۟.8/(((((((3Њ&l > ?N軈ȳ"2w?e1907p ~AEd>H'0!VGcu4{9l8{ scOfj 9RD#*xk{U9<,A'"OH[DdiRD>>DD2$}b:?D䂞{Ac`A]wʴz?祠GB 7JkU0>Y<`%`ӄ0'0Gws}V%}f{jXg.$q>q<&{.>90i=)"TNLPb7DRct{"aLGU~SȌcTxUw]Ul7Q6>_:2"|wS1BݍĚlnr :3>؁IzǂcB[Mh귪߾ n:cA}(U}~ neU}7W"$t%DžSD=zPշUSPPPPPPPPPP0`m4Z"~\U)McUیikVS7ّ?DQȴɟ-{`j3NB;}+jJF"'0- pB>e1oTςQ=Rsto%O+&G7d%g[SaZL+C{b&nP8wbv PÀuxCW?'Wߕmcm%vIPU}:AصNI^744r'fu`XVUz^`ck}%4xܨ~ŪzF>9BU< 9)ymmDW]?IҺ65lwڱ~:p~~fHr^b6WWS0@FUD^`YL?>sSc.3Oa|:i] ؕ0c读i̝%"4A\4x<4(/|+y_VxUy="~JU+ӎX|]:_3oUNDBXz'GD~xάN:GD/=yv.U[/S_U:3bVʗ5Vg=#?'G.+og<` `y~b40M@;BU? h} ^&8;0'EՁEZ & yq8^[`ѧuGq1O_{N$W#N9:[}w?><DŽYb6˸u@B?xŴ_)0, 5W0NcS}eU `~3<zw~wJs{j*yE;7>̼ Y1aǃq y0gD_gvK39򄾺Hj/bu>fCuӷ7}iB#ve?ڸ\GߜЯ c O O0Fy1s[&?͘2ʴow; S'U -mL3LrN??[e넾y`>)?&͵ӕ2 k:y'ϸM s$nyzEU=;8asXgSb瀁<-pL7UIdy\x }12|X%n:VVOOOOOWm?jW&kEðWS3D#UKU;?-@g:ﮪ\61 7"ҞWlR_L?g"[SwMWc'1-ϸ=IQhulXVE5T5Fh/2m!ID&nH|~'i77;b'b6B^8:Nm&>S3q\5]@ 0?&tADJt!ff:^H~."/3B @]钁i5;abת4G Bߠ9gs`BU27;my0[(7:}5]im֧u{|X /xs[^d֞>v7k lܟ/"aTj0u'u.BˌLkv%]Aei<8Ŵ|9^ [>Ą@S@n?3kMMs*]@͐iq#zeh!+T5 .&tLFeuz[?:xA;TUπtgU\ \1wcU]pW`>UDkGUa6T~JM_0":CI&qj.x4^Ma0c`i25ۍߣFƽ70=UeN +kCO0ZU6&μqfSY@%7['O>h.oׂU@U64m9GYND̹2j↾z$?!h>߳y,w:Ed#,.Ed :ti4s.uLhU+` \ IDAT,fwjWDv*W=B۶e\DuD_"m[ ,Xx}L#/Fx͘Bu#5r 0\]o:n ^x_^v_x k?]Kьgo!"ڳSD6`SBAثo1c%v5+=9W #ԞͿ]lUҫ7O+"kGFUۨ3ayVu\&asNs-%0MЗR@ jSH\ -˰6ϓ=~-y=ݓ6ZE[׷o%B7~z^9vsƙol ҫ1]E }1Z6i^&qޢyPjsn.Y ~Lo"؍lMmܷ9jH=cܛr8ӿӺ=#buo%~iM=xpbχ$ hÀU3( Ȟ$s_aݥy:l!:hv6wb =\ s&"rN&1pAEWƶќ"D2$-PmUE~&"3aZ37Tک H󽙈sL'wE ס^|<2q~&ړHm oYT_JG\5HjiKeKIDzW #~* x+ `l-+&hh'۶QkawoNu?P799XGLMl̕>~0+b/nc!{sI|iLm8.7*؆]L`Ne;u^3Y" f^)xfO'sa̜zz;s2iOONu7 6 ثpb/Mu:&Jm8_/mWOLoAX[[}rgX?Ds[ym c^{ //<v83l[+̖\ O,)))}:l>vuOg>LhҏKz,ꋹ#?dݎɸ͏]HV*mGnĹpN;xk3n+c lfn`-+b&afv/z3{١N>4n!Mv\m,4Ą i^xNθ3-[+y6L6 { X΍=̡%xwD`a$vlf(_扟k2X%Cۈ%QZbML`bpAYwqNcA ۔zt'4̸mi,P!?6a=#q!fL=g?ʿwVVngžԠGX&o L ll Lnb³GA"OP|N˴ߟF`:iOBżPT08%v(L31wP@bs:ih&Xܥ8())) 'YPnB>6y@W뺧HD~'$}0fƔ0'E毻i7 /"#0A$iV18Ӭ^U:]D@L)"mH핺&<P:XAAAA-ݫ05lQ1ϯbn|D.S}#?y"\AAAAAAAA ~$paTkE秷ŒZPPPPPPPPP GM G"*(((((((((((((((`YX~8}2`xVU}WPPP "U&vHý1"8tD:UUWߨ}vA@D^PU=?SPPLlnW'+?]A>9}C`ZAABDDdKA%`c YXD|KTcA!"iEkgn׉c|?Tfu!P7Wk _?9+ Bilv!"=y.n\c#Dd?/r҂/[yzxҿ'K7!"׉^mrsU s8}\w(~G,nqݮ&F:.}8wIGD䖪U=6\PPP0\+(&GwFٱE~88SULj`Dx1 Ex`(G l]UHsC`s`ACI0|։{ 72\ \ 7KʲCD:X b뱺4<6^xɪ`ggo_kaIܳ`cuU˷X8{ +/`q5j`]S^3S`\Q HxYz_wa`oz8[U Dt4QU%hUYk0 'Kb"2 1sl ̭ļU6rbs3zALL45U=64]DdR. L۱uglk=;<|16'N#Uv"'V&BDV":0.c2v Ed(pd!fn66a?(g4>ʵખyq- Pg^n6+(((mt&}#=)i x [h t.6a(h-.Ƅ?7_b珰{mo}la0);DDu` Ͽ;ClѺ7(c#{pl140n.+X>`m3躏#`u 0^x,܁X[~\D~y$os'H;V`́[} ͇zڱ&p1>83[b".\`a3lô &lY7rS:0,Olq00ð^r](L-+yEacglö"(7<&*;c=/'Wrݱ=x7Ob 6F|2>2+`y$)pO4lu'Vӑo hD(<̼x1`nmVjEG < WgX>}"7{˫<[]Hrvsy>;}xL^G|$ oe{&sˀ=3vcoo9"X55>{`r"OWfU`tscu?+OZW 6c4!(O-4Vesy6.4~ A_aullAA@/~ϟ0p@lnbsM"r@i"̻`<`sUئP]exґg]6hS{ 8)L2#:}ΞP&ظc98ygSXYXљxc&oX\Bs{B~ ̚=|aLْb'a%c ࿉Eܯ?OKKkpFm#Sb:qf }i2N$bBK0m{Z+vj긅^-;! ŷ؁iEeYFɬ0׽wt> ZUuD6[|OOtjBw3 0p͙z<- m -DfCid7*uqkU g&UӉU]hiI#N/vHM:&[uZhbN Lxt^?mQ9z2!оuܧv づ@aY6iPȸ<&(lτ ޛBT{򜟉k-FF HP ;g~N~!PV]Sౌ` /(n$ZňvJ\ (̸-n/%p?4K IsH u"ޟ%N&Z:Yo5SuC Y` Nm)]Mm`^3Oo_IFntKN1&ׯJ =>?^Nz N>o I0///Ʈ U.O>l[@:t'z /s%&?Uh;9`p}IozƇEm%FBj'tO~0MIMŒ Bz88 ]ުh:?L ̸nGfS>S>ijHD4&b<}w"`򈶀wkf#L|^:^j`1Cʿ'KvŽ)䴘*L`[/fKa7l1oqb5eO6tTNϨ^}i;>][Pﵒ1[#`5wϬcUE^"r5v5jtepu,߃2e޿5\k0Coen ~w _9넩B|P߽iB5!/5&"/WHruYDךʹ30M0U|Ddl],!.8/)9 +N$®as`h3m^lg {i~ҿ»i~#\ͩ;ظ 5b+"r1vexuL 6r<+Xg CDîyBuz^kDdvoa>\P3Tؼ3IU=_˽YwMG%"jW`0A/V_\BD;Pe5x֯SieLyc&/EdbU$qW0jv&p=SWZ'E|ZfOGCUî?~S{ǦRU> ~Ĩbzy5ƹؕ99Z_'@b|9C /,ԸŮ|^&>pL՝}q`EUIwEDϜ|7ߖqݫ[˂FNS]Ul xxVDVk*\~h@o4H17sqͿoGrfr6m:a h9L\1o!E1F~ӊHU/ɴU0McEw H33ۀiw0h#`6{6^wzO\ ϸhFyze!cgLLcE9j)F`W(R|S}15`;l6붕̄iJ0rZ{3Lxbb9nd~j1l) IDATܩ4ګ;Ԍ~ ffn0Ps3ֆW`W7„cB1{E"2Qkƴ]v&&ϻ)<wy3 v]Fj_cVyL2% 5` 0a=1JM=4CDdmNSf?bT]-c43ᔯބM_EmhҎ/tt"jz;7iAqf"ͿjLBcj {]; f|_̈"K Nq(Ccsb/pZ؆.ꊽƐ -ii1߻UuˮgS|j=c1Bz 7HNGUՏDrLb xM*ʹ#]lF Gz7ЩNT2>.{ha)aء ܐV0œ\]]k } 7N";@c1!뱪zp "9aV3˾` EdyK/O4sa;"a~&"7=1p\]&"b3i]sLk, DעsjE3#k"[>HC5wN+ a0(C /{qw%l6fyKUm/fc)&ǪLzrCP5u1]cuxf$vB3e:ث)>: {E&t ."57-CӐxKUSmv@Ohw=UD:I bsȑaW+Huo` -*KB_ͩA;+e!"WU~U݌ڋ=1?kG)ń~)E([(O>7"93O/5&b\U9@ej@v.] ¿7&q>f)b~f:=t ^܋9B:ҷ;}ɽg$+ea9ÒӒ_2(d$$JADT$J$ KD@Hp~s;wnt|OwJ֭:]u'܋ )ɝe=3_&! DzJFlk]w,󽼆eMO# S^8I}4&ďR{V㮬˄ĩv}|`bSďuS˦nW}~ ်8R#Ⳍ=3lRs:X180ML0c3_3UI(b+GgzNw'QyKqҹoPCH.ub-N*Y439_JcȰN-=0Xv{l鞩Rߨd*~^LKqנdsm+O&Ǽ Cn넏vi&ׄO]_SblY?颼92s\}1>;;fR3R' AL*N"܍|&E>Ÿ1~M4_UH_iOu#RZmK.]uu/qL2U' U?#V<|5y]3M2š TU^>>M|yDRS=j-YQYޯKV_$6q/fnP^fK챼?hP`yoJjޒ0Tg+j:^*cul4џ:Mxp`D4?5 M:I?#є~5.*߻籔6 f<֫;ԣ0-I?F(-Ov_A&iOe#/ q}bL%|e˜6w~mYLLT˺oXԇq$ AebRQk*!pl+}ވxDaݡ&4D5b~ 8D1AEh^'&s[sϰsj¦m^h^ݟy)ݻ+q& /W$ǡgHq.8Ӎj3i6#SLjIPN gwƜJgu˜?XչAqi 91!0^KLf3OOT $cb<8wߛG5wUh[1ko- ހJ$s8sblMy_P_ ;I3=a,0~TFF-^!~WwcMV / jLS! Nܿi6s^7HY,5wٰ_6IXU~^sMXy _(ſ NAo7}$w쫉_.їm~H8Qҡz+z]3^Z?:˰8Ebd·{cf)]-̻RNyt>f651ZGu'l5nwҌ.fv>q\|LO?&FYĤifӴz/t7_ -/۹?HoٍgĈU4/-[a_2zMoi!ĸM_<җa3X^]q.|6AYWV]7 3;,hT(|]Z4GoygOL&HO=5uVfwv'MOS叉x֛;ވX=ps)s4~Ivt @,Ooƪh[Z1n3V!!gt;*q~AsDbcI$3s#-:QbqN\9Њ1/lg$ַ*=٤cg16Ncfd{ &0!UtFzˤv4y'juy_+"B+7\daM{D#,ޛpYpx݇ꍳ2{#f6ks/iSlK[}O_cf'n\3ޒ?smP%!BG?_+}Gg"NyY3pU|!Dcr쟃!bFF !B!B~| !B!BdB!B!$B!B il` eLwz1m̘_.:55KQuƴ~bw}z<}w?/0ŀŀA{g`wgy w/B!bX dfg=f6aѧ~ K*He/1X%D;8æol3ef.= < \M#$}}8uO)֥d?&>?(p?ݠ _oX3[؅_d>'8KH;~owA{y[&ij0p?_π݀u2N5~M͉w63ޮ 3L~})>D8̊g2w/%I什K}d+z !B'WoψҦ߆{ C?ͬpEL*p%p=1IZ%mdddNn> lIL??ɲ?iR9ʕI}d2U"$f-fT3,'FI_h!gYb2d~A-AL"&.#lf6Y΄S{v9h^zNOiǦn,{{O8yf¨wmm3D^QӓX$/͓aNt"Swڿ s(|Cf^8]`f{F/3햄V3;mC)izˆ73%R]S&a&k椭MʆW #vY.g}bܙ%P6(.eoG۹0poifTdf'}@ύ~E׉gv'{'E?,mӼF&AKq/"ƒ́KS⏊Cﭑf(]b])[oݞ 4mEwrGğ$OיYOhkW31aJ #W5B!qo/3Va{W;`ΒENf($ LV_.ϰ;]+_e+SrEW?'$.>aGfKyI3D%RgW4߫ 3`J֙Ms0pCZB5ɉ34e|RpER//Os)Q =iuSLin$&!)߭"xomAg^'WƺI*a_WdFOؠAf(lj_5[?]tҥK.]tk|i4Wxi 7ȏ <\DLw)Pb9|[lYb+^~ [.v= 9Y!ؖuzW:ȆօV.W2>&"beRQ4$C'}ofu|ݴd>`Y3*fXnBLu'Vʖwz^t*$ 3ׄᡈucjbkeB9m{™}M[ZJ^/Fhr?#Vr!hP|[_#B!FFӆ!3J푽]fzC?۱H!HCf6k)~9y|}Ƨ:]-_ٰEzXQ-Ώ M Etp_Eb63قfv 7[_Mf-]-ɮ#V9mRK &@bSSF w|KLX lZ6ޕiVWW {?Ȋ~\E^ռo}Vy+:y2;Id(ucOQ91CtFN Kz-ElŻsUx31^a!¸dJƿѤyu޵vM C%_ fv"Ei5MbqL}+zdt9VҊ}=ї&G$u.VrյjbLڝ8~w?!q~)fyX-3C3vz׀CSfͱf6],-[wϊv*VUc̆]w?>XFgB!Dh3 gF9ea:؂XBtXbG+;KYOw:&Bbu5G OG[ގVŶ5~kAׂiEt1X:Ŀg{]Q+>U a[p crfG1%NYIq6. _MfqnW&dfrs%=ߓGGnϓg˼M8)o_8qyKpٺ&buy4*s ~fi|+j[w 4(pqȮ..i kf8[@;L{c N gS? H'8sRX̊#uoWzٴf-܄B!b||TmG_ F8)JGÀ2ͩyd.J ֍/#~N,Flsa5 g/dN\'|(ـ8z⤠2LȲ/!|,ALձRI e\meb[ɓT卵h;&{5#  ##|)0 a;+Xf0a@$=jmJcL=3dU:CKKL}g}?'T>*e~C88M? X,ӬEqL҄aʑ)}q^YS~gƛ&&!_I-JW2͡s:qxf_煚(cmŷ!NG~.ŝ>'ٖ|vߔ_&FұqɁ_uҥK.]tLkf+NǬH3~ytp+9;!gCtr5>wwUtC*OOL'&9ω?ڿ_ua8,ř`/KLxx^%0bՌv+S#JQ7̲F8"ݿ]M'ELf%%yKUJ؎J&QJ35gV!NJ{XtwafSeUb+嫄@/9c5MJT䷺fv W}k1t=sL\?{aco2bUȚﻄpSwZFنij648pgaW\'4Q{+'$)#ߺx+Ѿo2?Uv"&+W䗻{Eg_NtH:C\0B?ҨmG1SceL;8o,KrL?3 G C58+5QƊyymfKeagqksB(aht*o &G?+(=)s]:qo#`vW9wuD_̖! @_^hg}SݽcB!8NC#1eH=Qh/[e'L^=Qޘ}q{VWY\3;0,ٙ髶ϭ/f^^*c\ҵ'-@>']kf2 !B!BdB!B!$B!BH!B! #B!B!D?@F !B!B~@B!B!B!B!2 !B!BdB!B!$B!BH!B! #B!B!D?@F !B!B~@B!B!B!B!2 !B!BdB!B!$B!BH!B! #B!B!D?@F !B!B~@B!B!B!B!2 !B!BdB!B!$B!BH!B! #B!B!D?@F !B!B~@B!B!B!B!2 !B!BdB!B!$B!BH!B! #B!B!D?@F !B!B~@B!B!B!B!2 !B!BdB!B!$B!BH!B! #B!B!D?@F !B!B~@B!B!B!B!2 !B!BdB!B!$B!BH!B!01YDWהU(70U%~J'V:[ B!BW-{a0lIlg-} ;#2oGahxfp ax Y_l)K 0o%2I*00 |/*盆cikNU`# lJ.6+*?mmc:Wۿk~;YΦQ3;gq}wך2B!Bpvp Ċ~ M5\FuY"/TfVb`Mua`6``I~B^?(U(Ź:^X"[(^]ϯ3lXjl |Xe[`.ҽ]#?,Qou^\^殄W:ב5a/6nˊҔXϕfߒpAȗ˼O_ީȆ5yU)J]R~^M5tҥK.]tҥKW:[ s38ۉәf~g5"20(Wv!0ANx8ݿ*}~8_P~~KEDlW` >%V ܛǐo6Y_>ߝoC%y¥J gUt$e~-@Y90AMV㖬 ~NlݽVabosݞXUT!B!Og>$@Lyx;]$_I_=}׉lX%l|]Aڪu<~K`%X2hN`F~|Zv0=mg?$_-Hl՚bU>?U'wFFVZ臣U %'s 6gaFlj@ueob;I*(B!Йfws;5al#CuSjvՓ:,l.b~ph` cj{tꭝFQ7 [:NdSOQw;qDr%K}҉^lr3߯iɑ:;;B!BVO*0% [-y8on=;k[q f69ϛFh[}3F6y9&I^)hfSa^:&f(tzB!Bѣz:X'xMX#slI+j"-ϼ3]HZ6Yׂđ=I]{Ǡr>[?D_8sL+7!VqA}\ض|>sօj'|-bf52 !B!P2|y-+(h7_ٔf6Mr${$_ofNm&NZN4lb3ۘ8MwԷAB0%3e=[r0yl^3f6[9}[̖ lfqzeM3jfSe>|GםqTdf? 07`"b7pR=aua3fJYϖi&53 `׭bN03)fYƂפ6 X*;æH Jy6YF2{bf60{&m mu߁ l1w]xMkfk#p8k`e3CIlW`ĶKMU귨affegٖ(B!bĊ(f+!)fb!qt"aqtwKMGoۥ87ǺGgqJf[`JOsf$aTZxp`OQ[[8Xql/Ê&7Ve O۳ +9n%6^I\Ua8۹"sq<5?臙l/`J^F[k{ca_R9>YpmfS njUmJoˀ[ ueSqsl`NsoWXla<02 $gL72m+a'UF;{5!B!(VzgJoSw=jLS6mج^%B!b>zޜ0 Ԉ իU[߱B!Btx0Ii >N !B!b,b&3ۂ^tB!B!B@B!B!'B!B!>2 !B!BdB!B!$B!Bf}`h~H ׺-O;WcJ.w|,uJ1%?R1`fs7}B!2)3Y'f~$8uSW1cfl}3|hff6om^,k|h=o#A~ǺوX`>E!Boj;؞ffuwx"!Wcf6< d.=Mu;ŤS7V{oD~fv=_222{uIlla~ 2WfOE!B2 @f((ƔRCYqlg QZLW~~QeJ=f29b3gb)6cZ !B!V:[ ppA<'wQvk.?B!B!DR&$l llfSX3p p?w/ \IS'g=)8*w =66"|LK{pdK]0[x23g흔smk~ %nw`S`:IMRQmqe%~7My,jf疲?lT{O ӗ 8$: ,\ 1NX4w`C3[ ߿eI~3qb E'z,@R{3+:ww$*1jw&1p>$pUitm$p?Z3km "m|??~[Ef63/Myxmg Vp= IDATfxU0p`e Ou/#fwoj Pǟ#JoỲu 3ʎlbv#-'G9Bçn%Hbl|Y#bpS!B4Z 1}xqUObfdF0ƬDLf$ [~T}i?ֻLCL.!&ԥoe{ 댑Lb+пf:1]0LB-9S?x"=ߔ0bnuOV'4QVyݯ/}~vfJbe̾Kݟ.gl[FV/TX54>rw wrvySnZxۭq0BMSlYrckP^v C^ڪf-M X>[rnmLoX6E]Kwo#V .w*|F1m6xunfƄJ( c̊9E}wd^tP݉U&ZyXՓs)Fb_pqϯ ;hCȧ;4ׄs*bMǕ.w_;b\ *vf4KOK#lْ Y8'gO)+w"V1}!B/ =pG UꈝNwiRlZW?jfOkd99܀qa0ڔX!fi;gM o(]7hgtq/YbI |Qa{zF h/+Aw; 3۟OwF3ȞHL[-j}q.𲙝E)u:O4 uv}`3_D7:b;fv NwkׂATVL^w!V ?;_[Xcf*akfy;y]G5A7Kjf7[^N6w{MAڅ33jz4N[4 Pgt ..ŽM ROyhW<;Ux.0o4N=MZXffk߁&VRMm{tQ5\!B@;*G6fv`M w`Q'-^JÔB,v'&I+y$GLB;WW8@ fK٢mީ +ˇ@%V* lfWmAH'%4tul@+k3V'|D~r%VwiNEԭ(ل0 #~]4w3ۊXA X58jR0$_W~R~[=ARW:ِ|]p ]X15 1&uƆa^E$3[#x8hVbig V!_7S^g: XS06+]l5jLl&ySb|LB!Y '8phVn-GĊo1ɉFQ20S-_ObҰ9ڎIR]=xԱu{\a3p򺂙s* +Hvu<73oFSu5V;e'0p:W`32ܙ}]22V3ӀpgoEl:&vӢu)f Fn SѶW3pMUm)>* .eݾCI5q_" yч{_bĸV;m,ŘVg$>8mRE>u:c*7Z3D|O5Cڏ[> }G#% cpf;-Q?'qΒ|edw 8v0-*fB!,Klzp@ 4kF:b@+'fh!Dًx6cF =wd~ <# t[O' \HmY Oe" _q!6ߔNI<ò>N*twf?_ bf3z7wD H-"e$J"D%zI0dA(Fkg=c.kϙ]k햸xxg(7(5gfN TI?j 5v(ɜ8Xߜ=o5Ko4ֻͬh[_ ናFc:;傷lOpE(\qxUXKA˼jfە͎fW͏'Lyf|N4% qnoffǚ"JquqV:+Ύ7U6"]ܚfvs[ ifvpu)i3!UŔǏ^V 2XM\:6>W]^7p(x[M 'x2G ;sf6qmeOqϼt,=Df}ߠ?`fN+vÕ/⊟1/Jb PiL̶VՓv8,,ݍN3K;ke}7߅+&`;3{5/,~UfII7q99`Rڌtjve|lUzy}6$m.)IRF5%])7M7K".t6X{KS`<0A$m֫$I$I$Iҗ`'#2kK[Ưeop~ٛ5sOy3mI.6q2;kI1>kv^ٯ?IC0V!i)6D3[ʚXXbfom/sgiNW~ _{S| Fk!^Vo |8#1 A*II$I$Id QIO⊠asfZXJ55qy4}=%0{bf/K]Aҗp-fvA9^~~vGٓݑ3[ҐHz)iԿ1FLvUEJkfuMnNt;cM$I$IdOC'cÚ"-J;kS*fv•eKf~v1gQ5fvp?p\%y`Ӓ\Y8Ka$I$I$S^u`G<?R6&lJ%q7E/1G;q7y4'c  ^2Ev:Yxw :U)7.0?),p]W#wF+`j@bIÀM?RK8:=0[sT}(iܕRZدVE%.nq/7먤i ,~_U*fKV>lK҉73Ew+uA` 9Kf栏 /i93; Ygw[%I$I$I+c|C?ŋLIsNQJo7Wq0n4}[MWj ظAHt[/73Kq[}\lP ^B^2|M:Txz$rBa6W4l <ʚ;<ܪl}bj[fPHeO\eN[ɫQQt<>_t9Eq]o%OS{I17o7x6ĕ"2E?W DgY + /iv}p+<`jǀuJDFF$1b}܋:vyW`~o'&Tw;;w);gf? <} <#Қv{wq%H߮^k'y57: ' WS(sQ,+?kvyW^yW^yK h iܥJF:-|_7@Tw=oqe\@Wd[PX&Ҝ@_ٍ-s6V{WW< |=:ME;HJ]f՝vtnd)\lYefng͜3Fvyj7{Yj3۫&^.}/\kj}IynRٿkdx,*.K䕙BGIGV~-~Zp%Uu]$Mmmct" uGsuTI-Qyޚy:j+ Hy;f(E{kT%I$I$R)3>tc}|CJq%P  _k\)WfJ| NSY`{I{nm?JZէ]-{ifkufHZ fيC|uu4IglqnPWD1S܎s\U/X:Wͺ5U_[Gw b4)v㚠WO$I$I$I>GJL 3ofWfz-T, wM*(,TTYP xFUm/HZJP3{~[܃[ڬ q%\^gjO"u>/i3{߰N_"gIKIK>wԸQH"ihS3djA.u}I[5!Y %P}i?%iэk ˖k^@Ҁ~ޞC%՝ו\KuBJ]dfktC~$I$I$#+04*y6ƙ)\ ?%x@دK9nzxL][|'i97Q\E$-iNi f G[wvMP"iA܅%7}0_'xJsn/'gB!5w-kj6wgʹ[7*`&4˓"hو12dۚ:bf|&ZIZXKxpAJuVoZ6FR]y>uX]pܞJNRnoW$@$I$I$F)"Ht ʇJ5J &Z:xW݌Lҕv4֍,Z$- i[X,yŜo)[FHp*w` I71#>S~*U$G}i!ܲ"ff!Tݐ$j]y^ZŠgd_}TznAu%M#iIդ/㽏MI3JKwq%Б4;~,bûzcII*iXOK?Bn]ItnJ^՞T}\IZjd=I+F*\FF.Db I'ԬF.Gٛq9eE܅yKp H_]RYr08co+42kIZ5ƷnE0g?kݒQgeHvgER:zT<7O4Q3$-iX'-fvm⭥סב+R<>&I$I$I2IOƥ?p p]@|#{@9nb<X$_TvG;?&7,r+ӀUq%8\1(\,^4o6~(vs-iMWkf? eƒx,_pI_>r#Gxp ]M1ʀ6A'ǁZߜgfwnETx}'nfUŃ`oq?i=S3[Oѳcΐm7>v.[QH?VfvS'cRw*0}% 2lm l5\zDN5v0mKc+þ+o=_?O۩\ɺ2~b8<QY3Eh L^p >~/^=qn89IsBGl`82ibşC/VKZlwXwv4*Vv T]8X| 8$I$I$i>w3'$M=\$LzI3LҢfA6=#fL%3DH`=[Ԡ=Kk%M \.L_$I$I$_@I$fv3[]8qz:hI`$I$I$LJ I1{-z.1;}Z?/!R>uH%l ,<bfՔ``Q`|?]*wk8S~M(4,nk3V <0'p&e כ٥"PvUڹ'i0ohrfÝţC1fj 9kL^n~_?IS_!}8ެp ~3Ff\%[HZ ~,u3qpQ;!c`+`1p3pJ٪CҚΥ+;nK?6(*088_.ǚS!;fvZFraя&a i0(lPgM{RoK.7k]js` `1z _l+MNy_f\jfd/U64w5tw)(3{6/h]{\6SySϙ'I$I$ICLvGKZ')]"oN\tIFG싛p%xLÁc3Wha'\at p :c`ߠYc|vÛoeѧSu ckR߁w+oț6f`;|ӿ6pIXTvIWo`}+)$k=6x:Tt0G`\>p1~_4[lm|# c+B v-p22܏+{V(3k0|\S|<DͰbW(m}=4~Ϸށo}WHm}}.d=?cwCROu1ǕWqEc~\c?#9Q5~Ep1;@a2 p<hf,/QBpe_1?TBbnw+Rѿ Kź{팵V[0U}/K2U)f$I$I$]7,ZI?'҇VOoRАqS;ee._[Uߩ/+nO?.ϏoƅH| , lXI}esbMޝ7U)mHۻRvHQJA[);_&Zȹ&*,\)I8~Iܳ/լ[K !]QgF~K%}A೸/j5q++oԹW^;?WIr*ltqWO*5b\~H_>o%m({\3V{V]ZڶI9Wk!++k2Gῤ4gU/B |}AZ*Qe/ʿ`fF+Ϋ;\ѰO30!fvS%I>|[(떭~ZmV$D?sk)~̦p9*q#6nS3`\V@`-pKk \7f4'nq53{Ubfٜ6paaמ%fqIfsIVcݕ:g>=^̸Ҷ*h3[ձ6wa[.\ ̊zQu&5f6c2M[xV0bYT?7Bz=)$t)n"@$I$I$S<HBۭ&N _Kw^i|G|.-| %lQںS`funhcI-9K2;DԸ͚|n0fdun>/H:0b.#Cp+Q5sXl Qi_Mh\Y1h+"~]!ih*=xRŽMYXf)]gL| F&s :en^Ǫf3Ǟ=m|[Krd+`=Y)80nIXħ*\)یըAw=PxPBTge7"kV K:94t|UMcScxB;U3?\ZEt>mᲷT%IIU6n 72Eשpה5r~ou4p:s  K"~e\mY [X\ (Z)܊fJB2f"~bټq|}x\G@ o4;4:T$-R#w@NuV6~YoX %@: 2_ʅvY `kZQQ 4gu tY vᒮ,VOI$I$I_[pO>j)߁"2+c;h |C24#|9OhkQgUH}y3ኀd԰Km/+G `hVkσ88cb3[tMu1CQMݍQ} \qOo,eSb]⊘eJr71N+Õa:5~^qo拱lQ*W=ceB`(i[|#;8 Cfq㭸*\0ɱ̉ϻSܷi#^X2'd;\< w%|8ނdx``P܍ƺ?Yc}|?kA*`R=㞟}WNח{A7u;p7qEo?"~H.mNܭhy*rVߏkWyߠy<3 I}CK7 ۙuKDEk}Sο'yW^yW^yW.}캶Y9M`-\a3P_ hfMYۄӱ.5$mS5mO5hpo9֍G$3*xF7zx8#/vbͻѭ ,+7[J&d ߃qE1QN3;,\v7 7q1f@E!Rj$)pu2K[}ߔfvs𠿋J1+kfHZW̍ zԞlfWdx?3{cW /g.|+J6j⊟WpaBG[+^5D ߓY̬M IkaO'+D N<[v|-N4;~F1hn+_3KOiocl]7(sw? W~[[y6tmv]ΨefHZW.&I$I$I4do $d-xq%=yyVᱤXJ7R$I$I$lvPIENDB`PKH: =X)X)-Pictures/1000020100000477000004626EB760F8.pngPNG  IHDRwb.3sBIT|d pHYsgRtEXtSoftwarewww.inkscape.org< IDATxw$E]X$I\rP$Hp$ *AA$"DQD,( K$,E"JZ2,Mjܹ}zgzf<3~S93[lWV""RĆC,3 ,;8L 32Y_Ι6ǶX?13 ՁM \u`"""IfYkL?ZuVl5v֏mwC9v!Zla;`{X{8DD#w78j!f6dwm XŧsW -pP"""2 pi]9Z |861dwb2EDE,| q9_РQhN,7vwۚgfs'̚w>U1y_TB0&2 ?v%ɷ?| Wi`:̖tg[z"Ìl3k_HLm TNka<Cfp`άݮnXw=og̮ ?l{: 7yR5͖=|>gT/;f^`!Qr Ͷq''``{“:-Ru?`Z'"i n#z]~VwߝE\bfwv2ă7ع xR>Hk*"""mؓ[ݨL;g.""2)SM:o̬hHҟlmjBˁܽ'] 8DDD9ffM,:أw"¨Ӏ ^MDDiAAB7f)w00o^""N 9$>a*b:X$gRɒ+MMHs }mtCLMk;9`ݪġDyovr!ɷt T7iUhn#""E =H*"efZ݋ZuUݯэm`w8`lVKDD$Pp jQܕU麣yu"ϻ=& -j;HDD;{`b]t- |*1w&ty{"""#L)I  `T,10rDCB;60a(7QJwW% swݬO6;@z`#`Q0k ON&[(0kp?ͺ1+Fa  T4Vbc{jʙٜ"*nk(1u2҄+YB+ѻ}z9}~6/07:[C-QlL.G%ooȤ.ŀ̀% &O~O7cYcigfuuj[hB)q`?ٳJ6!^[YޥǞGU2>B ۀel\p}xpOJUcS>UN8>< L$|/Cjf%wk  9JҘ;훭`[]EAnWೄׯp!pTJpBfrfV&IwlZ?ý 9KU:0DkMeɜlmBȭ'f_{]Mbl58X⺍ksyp3ǖEupR u30o>-󚲿&?5 7;oQrm}dk׭;k xqQOZ(+]<6%,X{%XY~b݁v-6`ɺ~XW*L>u]< `oNlw&׿w= v&u ^˩%?oݺWe]>+BK7K$NA}~{XS[ܯjZ~m\Y7ul`%y\Oѫc9{N-7[H-MJ,:v܄\A2<]l+wuF@+JWb y4B׫ Mm$<ِhBˍgdfsNYB Bq tupaD]dbӁ=ZXuf׵6&T8~7p.~{kv5m hejfwRm3]s(׺D3gZ /,\cf-?Hz9Ng7w~Z|e[lmf;uU/F'[UBO/WV)k ԭM&)9Z3p< W W3]S%\ԛЕ&k&H+l+7,;f+X}:=$[w%DŽ.n0m66jٓ͢/~uh~.^>uZf'00*p!.D8'e;/M&\p. N+f@- 3>W+qiqbf?VZ̶tǚB+l#'vgδ[>I)-LȥPE@W 7y`p;+3wwwsMmo>?(qgKb}AY Fا&OR0KfvLqt`58nG~  \LY8̊~cr;M$;n$!f6^nBN ݳ!=SR~lSBWuLRl5](vfxQµ܉2~EhԖ.$K!̖f`K+b&wX0px{Xp]T3Ps!Gֳkfu4M:ݲSf(nYv7Le&xyXź͛(h؟,:VwLo(]-m. d^貔S܄rjۡ~ \89e,JxStlY#.{x f)s!BmFWw(1`&CV8 ,7nOlomMɄ 1!Ξ̞Jl{2e'wEx}dr&Xم*ل&DHu;z~'M(c\AFt"</,r% KֳnYNOR,B0< X2Vc1ڭԳn[S.@x8Pש!<ʚI] 9s֟gQuAm{o bFxH;wOK|3]KHӁmo"~/͓(g%NlqD7oW+7F?%˫4ChWgZ(Dywc[(;K|l:&ڡMu=%s4oM?EKu+7ܹY9nk1뤟}C.n=> `HbQLw#+kǯ(k Aꃖ Of|xS' -4ndP=|p0fs%㄀I: +S#!zҹRZ<(eBγ6QB\{~gA]h/$zLw$qqfP-,#\/Y*3L^=@G\g;_/q>Pʂ;Zlbs@Ol~ W;^ױ6Z,s,p^j/4*$e ~'{Xf*Va+0+❔hmD -H_}2ŬU*~p%9-edyI4\9>S>J'ܹZN N3如;`p% Dy3 [(o4EpMWuHw'z]F ;ܩK&}c %ފ-JigZk}vϗЂ'آ(+V?O'X^*SۇyyY; lGBCC6XK3G6"$78ptvIJ÷zȭrXb7cNl,\G\|6U=_, 2+^.eB~SQֲ>{{CzoPC.-UÌ;ثn+`P6Qδ9 ANMs Hs힘}!1Wʮ7De)%nvp#ͧϔ-0nVK5팒rۍ#ꄱfW%/dw{z<RlCs"-881}3*fWrWI'u/}Gfv!3~*-W{,,ӅQ-%7ZWjHL؛K0r!Z8Bf|DrZB Q^*?DY*nn$<̚w.3[9Nb ffVXp;ݟ*΅ l3NM2 M% _Bk,N'$St?5髵P;4V lnˆ95S .rׂ)mj*0BbVD:wMud `tB>Φo*1eʊRAļB7 4y`\F0wl-`f+Nfv"G5>ot96+@<@jnw4ߗ-wlkM]̦_AHj&>-IZ*AFIwz"7T/0iw'#'$- I|X B#OCBHX/DwݗvsBN [l֌V[?51}q3)&Wl `?8{mgsgG]*Rzg<H̾4^'ߤ{])>Hv)p{+j1:ّ,kJ]{*Gk#J][[qsR6R;˘}@_ ix%`DyNhj'%5 =m$1}lnD3f1 ڮTEV#}OuC)+O@EOtִb!hɒeI;^݀dJ@Ub^f(8=f7}ԯu XCKwD3r>D^ű lT7IͶ Z22:qVյǧH?hOj)#u4axy-sܩuaBlCEƓn]u[M*PUUqn`b:yzRnu7)WU^n3 WL7hbKTe+w6+F7ª[槵!j>7̅d\f˴)P:NV̡Nޞ9s<4 >L;`5Ћsk3&%w5WuM]{ڲ/uQo-~*n2M;*PH F!syyGKsg%/x7bC؛ K~_3"!J+v,'ӭ#ŭOSM UO7(gl|nEOIuc)sQ Buۓ Go㷣<p"ByӚbfּ@h:Ҕ}܌G5 nVw$d)u fsbT )myp}Vub uꦼ@LQVRe,Azg'KfVz' ~$}bw&Ms/"wd)̫FMe^qfD4:TK,RtJ<5mr'OϠ'9K°7UF#H+zHVP%..y 8x3[nO3"jd2-.OHй0!>/RTNvsݦ vHވ/;f_ ;f. L1'f 0e.JjUQ lapyՖ.1EbÑ5Z= \Vx^R 1*Qf6{U9J(9%z6邢_ͧMJ%+[գb׏y#跾&6̣^N!?m7' 6ra[.dCLQwV.Ys^c:^Ѿ&U+8jFjV;"Tw0*j0xo'bf^(7ݻ1OJQݪnMST^Q=F=wF8RϽwb 3_w-;o(Ӕ Uyl33$xңZug U~f(kt0^^M̛ wp;dμ9Z}_Tˑ1*g^7Vu3&9.X;فrwoHklM&zw|su=O4+jZϵVoN`ļl}w E*~TZStMOPpgxyX31oIP la؊ -`w+S}k( ,3{A3{:z hхpp,o{gg)ҡzZ-O5OJU$〙 |nT`gw4of`8w*t}M*kyOĥX0o 8y[v_a'3ˎP33C!h~Fu[tg+lVZ-$)y~nb.S- \"j5nVdkwW+*vdMᄪ;>afUH "zVAF G;Ip:[EzJebJ; lhÆ?&1{^C9o٩nX0eQ9En$}ݬJYؼF!?lܽy۾3̫غJEtg3aq6Csth=%fIqKf$2t!#;˝GٰmOݑu(!gͬќ:ibbz%lS3s٧?TЖپ9N8M~'ߟ> 8Uk|U9r5uڤム-lyuĶ)ʂEy}CzeHIokf+T3{_ε); #>d(ϺfVE_T'Ie~qzblngOÙ׿VpI_nWQRo%-{u3k|(<7ժcH'[\tZx/T.DUt>m*( {38pvꔢVApVr>c/TC<;U]|:򇒑~4lōc`l:*>oV3+l^kf7^{n~ܐ53հHݪ؆@?&VO fV&aM[Ӂvb;.vԅ]7 [kXgxӏO'?`~"Ti6B׌;ac׆T묥̬ݖjs3Qf/x;sR-2I?taݟ~]u蜲^"/luRE 3(ǃU%YT2'cO~_ױe]bWYW& ncfUP~ }gM;t^o\'oa/VvRbͬ.yQNkF[pW٠{.~OVowQN 74R jڐm]%seZSI'9س봡*08rJ##OvǚU+ . dO)`ȹ1:iߪ*%)3< 3^[^|#1RY&$e~mW"ߖufNm?5ζwD1km`ɤ1!q3k)Kْ׺ā;48aDq7)̶epKE5yݞoڔZͮj(N)Ej?uL (̊[uO6MrՊ}QMWOs}nf R>k'Hjf m꽖3m8L˺R^' Cq8%flKt\`ќ/WI ]l/"t8w :u)V3-ff'ؽo}lBKk'Mqkm nL '`4_>3fR|A^:dY3;s ڴ&kS<- bOmNa]&xocHmӎxVUuZ3r+6+ǖΟ#?Oʼee1\VWQO;_#2pz) Dzy؎t.}_$w4OQV3[NaHKUr&Nɚ p7&%ݍ-U+^8̮o ml3;xd(?QBx`ߕCG!eB/;S]\3}9؊z-BbhHwg~kf)>Dw/-T๜kńyu쟙|?Fr~C ifBf6]@E|Ysכ^ʉ-4bVn +f'N>]VBۚٸդKщ0cfZÿA:@)ØMx[a7ASl12`̬ 9Mr5n3+fC3rs=B׀7)N05oT%9orT_mC/r֝0b![Yfa3^>7dߒЂ`6L-B~M諛Dq1%!$' -5uM+3ۈ?gÀMAK_ dRN9 aN4/źt%~7;.. W;{q< n4dgپV',wf=_ɔyQftC@6x7>ɚH/\_pGhL=e3wgc^ڲs!gS7ޘד EW"'XS-c 3; 8` ~(]8"q̈́әi7 }3;xof2ݧ <`ȿ湑-H/uSsnSV[ wF-~"!gz8!P>5E3ǔ0pܕk& wan['&.sw3;Uۓ?Z ]wo1:RbLහ룧8`m|gwn򒀯oN~ˀyvo\^uuwX-]ճ|W߬"2ɿ֚\3}_w߱gp9#NeN~@pw7gd 8 ,Pهp^nif3GepK={݁;g _rfldߟnyAE8z:X[*%%I(Uޝ'&]EQN-@E1mL'\vI?kBਖ਼s*~.fja غDNmM:B'~j_+hwyF'o7yEl%qE Q2fw6|JAy/Z۝IBxDb*o#앷cN$\?X϶BMc=~GM~ W#\Lg_Ghr^w9߉zX3O;{X=%u^*z*m~{i~/z=SK+( lo"P,2k7Y]+ϖ92g A+(sL;UPf%7SeM#GN$\KXs 0g:\})Q6tJlA2^%~N"j}).[}K6gҝ(sEYvۆ OD.$tzkj@+`\ |݇t®x[BΑO1!Z "ɳ;1Sݬ#4n&W …^-]kf;8oIsC6Fx2;“Fo 2YyMM~^f'gmY:?of?&4߆y^'onɫUx4 {}щ}Ulxfv%Zw?/>؏pkwe~'y;O۬d7q& k6b~&X:GE>:zgE/'^'|햕7>*yEfv!u4Npa֩ _q\JxH5Z}MhTR)mFhӪxY'KΚF8`#0J ;Қb0ݟ] e0ụ ]֟"5aqp.3bM u׮[&_&_wwyyuF3pNO55+t2;"""#HzS(I*"/ gh9,"2Ti(t"`R;"үlf|WevDdQpGDDd'w_%RX*aEDPYDDD Mz0HGl l5xo&wNLED;"""#ç9>k8&!ipW&VP'ӯlnY"""}1kte0,}_vv"">nq4Mrf[HQpGDD?KZMe%䦨TDD)&CnO˙~t劈%wDDDZf6 8$3VGDBoblB: w)wDDD>f6Wbwu_wN""EvNɖbfrf?VUDD;"""oqJ3[ƚh3[NYOD$fm3[$-afYI`w3{])͙t i=EKDl &}x<&tZ X`v)"CS}UGD$);!W }13w^Ay""}M>df'nn] }f+&"R6>l DWy^"pOH%ED;"""}̖" üc#~W'"R(Bk,0yxGAj| 1%"""""""c 1wDDDDDDDD;""""""""}L>HSpGDDDDDDD)#"""""""c 1wDDDDDDDD;""""""""}L>HSpGDDDDDDD)#"""""""c 1wDDDDDDDD;""""""""}L>HSpGDDDDDDD)#"""""""c 1wDDDDDDDD;""""""""}L>HSpGDDDDDDD)#"""""""c 1wDDDDDDDD;""""""""}L>HSpGDDDDDDD)#"""""""c 1wDDDDDDDD;""""""""}L>HSpGDDDDDDD)#"""""""c 1wDDDDDDDD;""""""""}L>HSpGDDDDDDD)#"""""""c 1wDDDDDDDD;""""""""}L>f`^WBDDDznX|tۻוgc3z] ie1wDDDDDDDD;""""""""}lLbY]V"iϠ<"RE""Mnpg{\顋&28 DJm;""K{f/ 05#SG{TU)#ՀI~8m_K~{Y)3[8ݏmmDDDDDDӔPY-wo']k1zT*ml|fueaf43{^3)f=cf~""""""C;2pSwGvZGg>וiI"|OqiPnY2Ԃ;ffv/Fj!>8? #`o3Yk4]&0nڭq;NaV@hwn/ͻ >ffӀK}2Vy~o lOh 5.~^pi-;9wŲƺۭ+""""" HШW -eifqߛ߀s׬N̾<lwZ,Cf`B(8-+B@*7`,p2]2hGc W6Z{2k'K_1k1Z]Jmaf'!S{E1 ㆄۃ|f6?Yt`fA.3խ!X p=᳛عg6%|FKNDDDDDDܑGL'ԯhfvpߚ!]z;qIfe8LkwxjO?;n?cc{ Y{u˝Iܜbfe>3uBhTV-w|:ݟu=0V|S&|+fl,^[%'3 G~ NAsH IDAT7u?N ~{*H;2 JVOo䬻"!<eȬ 7fWpla(EFEk+ neB%-IGjUdf?&|v6':aun5k58>ٱw-w-}:`'wK~!?Ҍڄt#~M,3=ϼ/p]E7V($""C|Hܑ&҄6Yw&`V7}Ow㤃;y(BZE[ cZ7Zޝnlf >̞$|ݽme_'fr`vb@-._v vN ֽ̮&t!瓈xX 0̎ɜ#EDDZw,&Jvqg]6;Нft$@ϓRɻk(jS<) <^P7vV]Z3y]uY;;^fvw'&T^[h!GݿmNpr"$Cvrr;ޖk+E;;H{p5=9zXDDi Hlم4V*lj:(XfTFںbb璄F65,y4uCȻw~BwF:."t4XZ Cȫ40b+b`3AwRbٺ\@:HxY}牯=l]wg5MB{BݼZQ`3yľCj-FXwo;-ww^!9ON-X19v6x[3P<XbB|sywls/s5 Fy6LRج 6ٳDDx] |+NF-j#vwXYcό%yL,S-空&H߫=Txݧ$i;24fim |=y ɋ%8nϯl,j]V53PVe5ܩ jE&f_>G~$)Ho/,[ Z4$ȋ'_ʖHhLDD֠'$_85aCl~Ϭ3;٩fvTvywY03;!n6361C h[cb <~nff#Bry[ 9{~gfZfܵabkfs4 O^gffgGxNK<a`x|oe4-kt2s-qJkb"[qy+Bf ""}_NZȰ;2\!+JJ]lD@Ǜ5'{Kno>wxMv4% ^ lԶwkw53{ -Q07}3;p:ssm\GX!tw"|']fgVEl;BUK@$(Zjfvw7cso7;3'fPH؇73}2}/%"Ժ?]ol"""M )ۻ HbcAwn턼0۸"taZӗ&$[ uj/ #$7kwYXB~"fvdo?}ոrq3`ɍ!O[tw]E(& &a8.vّ/ZnsݓХo ߽b{gO@#.6ȬJۻoڈ !iFm\cHrG }:Gj2$qclk zy^o4ۄ>Eu*cmf}/p|ϛjlo8YZBCBK>>AQ"7kbo$=nvIH|7!M|N""҇gRwuH~Mo -EEC7[ν1^''6..N7ڨhB(y>ns """]ff7oI0EdfyZ߻U'>Bi=)wDo-(SV&tI-CڢX_Έ 7. mbR-Kz]4Bٖ_uK%s p]>""GrGD ~-4aG F""P&yNiSDD):iݟ~zHs[PWIDDZ?{Y]ϻ{#"U4EDAAPQҔ" j!(6dAi*U*JY J"JUv^2;;dN69r$$IaDJw%jg$Iw$I$Id`{" !i$I$I$I$RLy`-v'I$Ț;ɐDҢnDݺ51,cLnṋ jkm5c&I$I2K)I$ Uf>\o.-?[0/FW⎤25[Dm'I$I-,'I3v(I$ IJ8!ZRi?%G;j1t>sVB x!&Z.L[_ Iؾ$I$IciI_iKI$ %k$C5ߝcNNՎ}MkfWA`yBH9> b?$Id(XKڻ$I$wN+ĝ*"n#wj/cFMKʬ-%m؇1S[H$I 0GJ`I$I u AD„r?pl EB S//i6obթi-4ya}_}-pmH$IvΔni$I$@F$C>GH7p+p,0IØ%&)*iIT7.+\I^$؍%463$iI_#IJں["iVIJ@̽(&I$O5C[N$I2Hq'LKZ'K=,p&! ,E^^~R$#^+Na~M˪a $Id(I_l$ \OD,TI#$!UI/JzV’/IwHEұBٿ%.i@1t%$-(.tS$J$IZa-w%jg$IC;P7)G͸ I :%l]5/lvҚD}/[-_E7c{Zj|8:Bʶw*p[ ^+?N, ݁G?+{ԺYf.(>|!!`_$Id@)X;!gH.%I$wNmTT ?i;G fVb` eZa0BD}ucKC=RĹVKqI:xX=wj7>B41Wk~~,iDvk_)7}m?l{Bdo._Uz0 0.o6"H=Wf l{eӓe]\$}DipLJ\ٗYʸCR-ёtڙʼ%-*iV4Ceh$I$Iq'LKIJ $UbeE "NT32v7ȝ{ޱI1]فm`$Ct#D+ؾvռo_ YҒ):iF"zؽE5=]>f(| w j3? lO~k: 7qF'"!%OqƗS;%]#8-iΒ{t4$.iUI+*٩/cFl@_wUI$IZOvJ:}J*i=Wk)C%ʌ$ďz&_&Ďe6 N6&D.6T4pg1"m_'cK)Yt TIh'/7H j_Լo_,[]m9md`˪)MdE#Tw"8CrDlPoH8~ )l|]nJZnΗt%qn*u圷o<5B&?WTGDi <XMeS id붛݀$058$IG;PiYGοmYP"; U\WB<5o#.VG[qrR_R%]QvU C kttitĬ6YܡfzIMl/`Y=`eEd]7CD,=,#dۿYk`sIww':|}-޾ܰG_~dߒ~,LM[f=Oy~]HZ(!4\H*Cϫǡ m?-i#Xu^JtS;fR9'ĝUQV4It_xx]|JZI$0%ŝdӫr1}(*Nv6e5nuS7W>M-ț?[^=wězqjQ RkOSPԋPT4z*tS$I,#i/B yX: I]9;D-m_ \ROf})l !QP@G<8fE1~Oef9^Hش_^llOv_x؅8z<(L"YxP-zu\^/s#]GDy7/Ye$0sw+kl!sl]g;?k=#ifD" Bŏ;7_4F۞ЍӌK}$m9^$I2xɚ;PiYsOmZ:6xOX|NtX2Uj {Y4SOh.] D*˳ԭRP6lOVK%i^&iҲ-fDx>ut/5YHIr>Fk7V)wKZ_!"g Km?[qJ_] ۷kAOԜ_+V%gWؾ8y@"D%Nf ͇?b6zE+BEx"DzsIOʞ$%QZ5GarBI)~L/՛Fu(K% v"BuWNIk,߅8LxyJG$mPn.t$*t$tC_fu$IO;PiYHUx~z;El$i*qC1e- (?i vWN$B$RjLWi :P.b+!U*+ݫl.QU:ֿ,k&,Iaۗ>q=BҪ5,LD|KܘFwT+~jŀL~|i$4jsDtH`II:8w"ăG%,,:x>I'Eb" :,-ib~I;I1!|pc4G;پ< y8wmQl(B}n7Ŵ+aߍ|8PY&">mbg&"Be{eBDtlj{cK櫎N/Vu[lo| ؿSEL5E܉8I$I)$CITW\%fI7J[$. uV/] ,.iE"F#iӜzk&S JS?##Øizn?" ` Ӊ'|NF8HfQez=UfLܹE|||lJWDY~3qȝĝ K܅DG銈8n.QcDw$Hu~7"i7ܽ*+bӒ-E#R.\'Wq5Edd<{o>mDz_Dd֚97I$f U^#B'5K$mB< ކ-^%.6 .G- N`2Σ]$EI,SνJ$CUKzT oJko"%b׉K69љ!r۷Hڝ=͟K\~0t!4I_ jf -۝ډPIWqY[\`Q+ވ;$G}Dùp4sIO9nH/U}ڛ4L~@Q-/BQ/- zQD{.(|&W3FOUvVMG?S`/=\5J̚;88_+N'Ĵg9]BD%toZt'BUVwc$]XD:jCAlj>`eY=w{(?Ԥ"Oߕtz I$: IUDYy+(hǒ_~;'2,Ge8lSr!n<^!:NS:  kߪ{b{2IOza ~%(~}EJH:vWۗEIγ}lKz8Nkh?! UDQlϒn$n|V!D*Θ֒^$ҿ-i+C(?t7M"گ|EҶı6$lA/Ay]bDjl%]MBQĤĆ; jDRdI˚Q|n FJOOo.6dT75I$w$i"FLDJ6ݹ$f 5qr.Uz(WۄT}<)Em)Bj:"r "--"fĵJ),DDX.MD͜g>I'jm?XJD:u5)bFI"]wM"be* LD|D klX KD8Mv#"nH'R"!Ҿ'"] :mB/{JfU`!ŝ$I!ŝ$IZFy~P)ZJ N⎤%q`7֫dFAr⑤㉺H[#i4i{B?3k_M=MDd޶}Q?0!VTE RI$N$-\ >"lUIs.Na'IiDQ!Ĉ{U KqgyQ3m uoi0#piI{N%$I< =IVa"li GB~|˼K$I>Q\l]3ДTӀ%j$I%#w$i S#:I?ѤL$IL7l j?t#%]Y_(I$:$I)E4_q$I$Iz$DukZ'I$CLJ$I$I!끟i;I$; ]\o]coUg_nP뵽 !oo `>{{' Z{k8FOHcW擀j-Mt꫽/[X6V؛ #ڲ$R7ч$Id ;`i4*p/peaZxر;X7M/_g{G/CPQ~p:{ǰ /)p,$p{%}m|nKl?8=;._|:MX}_~ Lu' E.DW??-MeNAn4DAgn?fj7OtZEaikq p }WޫT UWںb+TN$iYٰmiMk@[X-o{36^vdڞP׳k `>H &!_MD>\e[{ v`_o]xѧWҍ=>5m>ID^aifCK,lߏ~%I$-$#w N#¬/F.&~ g{ޯa0b\r..g{K{}WПn 'APDZZ4][E[mmσW˺vS^l?>uKF$I {ޘ;?g#YLK?{[󦽖#p>q}` _{_,飽ޠ&{|G(|(0j&ϝDXoDJc7KqI5v! KeZ z2w?"~ZP~*E$Ii4&,Tm#I#3p/~%ɴ#ݖ kȝ$rg;H$.]n~-T`Wk=ܙ6$-,L$Q=I`Śt$I9-b(s\RIMm[fe]I;J_̭1I$I^(pZLVWI5:يHVE c_a}l$G1N$SO; /!^ llZdpb&%-#iy$I$Iw~ ؉t,zl |GR[O,225աr"Kh1iZIj4@!iIISUX^iʷ$Hq倱h`z$tMO$.I$I Bl9pH֔m׈h-{ؤ&6? m?Q3KOŒ>\;SB|XhɀNcEWIcu$ ؾ|<$S+}K$I)?nn}h,fZԐ]6fEJ%iIQ~"x&imII25$ɀbwJ8 iz$ l0Epj;$ɴax2`wIk?Ì=?ڮy+ӝf m"rٶXfb{QN̾g?$i:v-F\ TE@{Ov87@5|^w0!$\U D$r(!o\Gԙ~٧W4NJ6I7)aפ$tKD^r{uc[Vs9qqVepdc,|n߬.%p`7xr)9I?QZoG goJZɦR}RP2WA ɱ>*<~r}w$kygͪA;^,mzڮ4"Jcb϶o BqmQO׈aR5۬KtL>&)c^ȣ؞(+}O|~ , }H!ŝ$Iߵ&q1r1RtyPLvē{7ԩa4v VQI$ӈ(S[pa{۷T3JϸY(})`2ݪ6c AD9Dj0vW6x6g[>@VDk\R c{P|Ylm >Bj_$t}) p:Qx9Ia75w.*gd`<"-hsI{؝ -IJ=;z"r =Wĥ*bz#ދh_o7wIyKEv:@I{YVL5qzVm[v'$IGU ZukH4v4 7Qhr4vJ>k#I2 ٗ1rdo &}CҚKKf&-|"wҢz*iYDL\ZzЍ#3'OI[* q6} q__҂evLYu'IyG4ד~!ŝ$IZ C࣭*lDW狊=ZHz9/I~kNpfȑd8ml{B`۞Ҳ3oe`mǻSk6[K NK%dz.%&Tζt]#47)Qf~6-(l )$I2؏h~/Jڰ%ÎF 6$I2gZ!-vgQSHnV;L?WZ"-k>V7ئ~HZk5G$--}s"*ن{SG+ \ To,z.l?L;HIҔw$4f:$j$Idpjn$;c J냈$M`?/ڀHZD(I#WJQ--foIs\M]BSE=;ִ-iWIdE`/YPro6S 8mM&7w(Et="=_ȝdQjKoI"NI$I2ߕ ,B%@D@9ԱW/ֹX2I;@hҐ{¿Iŝγlͺg&iUDmcJ.I98,;(*}0n &S ^W/u)cHZ9d哤GJM$uv4"0N(}Tee_%m*Jz?I҈we<)x𛍥Pc|+KK$iۧگ$I$iEi7~a?5=}K1n DLb|ޫcA,\;ƿSX# PRfjo6a3`z P2}/KV$ڲd<&ž!Gl,vJ ŝ؄Hxa`BYM!$i$I?c~ $N۷ح$I$\FtD~t{WndI7~f: <>=D"gZlIvE`6CljHuu6I@;y .iV"4lIIZ&p.oI˷ڡ$I$HcKةoz_12v N":P#m$%#w_=]xU#Q QNؾ=^K$I~  Y &I$-&ŝHcG-w>|~ 􈤏I23XI JZ%I$PuD{赀CZN$IB;Ny#i4Eؾ6wKXҚr OlOC6%V$I$ǡmAm3I$Ý luWmY٥.϶$ K~Gi\_4ZWtL^&~4sжuMd6/0Qxa6xL vnΐR2i>TN^B+IdNcFr^gIc#Z#I)$I}<5$n5hkk,VZŚ9jF7mm/bOUGmfdis;y‘$hkKtE]ŜDև˴z=?I:8%4q^8$0!ŝAÁKZ oھe%ɌIUhkM\.VsJu:yq~4ajvxIAev-'t G:k7FG+5X3wLZ~&> .B[PF瀍mOU`{"w=͚$0"ŝAgȃ9%&+-t1Ifl_/iْ=v|,UΫ7Ogxi/Jc'D_cbaBG[' huǤRf`Wn>C`lDDqɈ.Ӓd )DG$=.&ɠ;3FK[,KS :ү |8GC\@'i"V=[V2Dhk!@7ځ=sSϴإ2dyUJ"ŝ_4+`M'd v p#p %i/.I?Eꎤ?fk=:"ěY[׌H_qF=ӲZS4pr(Zt-DuH鉇[@O>WΒV447V'i^c-+q]Im7=Jv }u0Go2pn}O2 RRܙ.{IK`/Hj6H'IS:w.i@I MG[>l\3{mwlY~D ?eW+#"!i˪/_>@@LHZ&z꣄!C!k; *Fa$G8W[_ FJl%}j_mm>E9Ou&3R$¶L(5pf1rS3-g IDATe&emm#Hg] vׇ糃$]jV;4 5[j: wY;^!ĈZ>_W4u}nEem?QƽZߩY4j&R*^%RRl fBZ/(v~@N_W]}K:&EBD~%}{åvDGlR>p9V#"jc+(鯶_/^S=IR;pIS=$i"Z_wwQ_ጔv$ ۗNtZKG[G_".*o^k2}鮞{vDbڧjӀl[ZS˝@ͼTțj[/K/m?E5lO-e4ElTo+DKuv6B`'J=p01T[o{Bf"mJ?7 RBخBv'GKmw]4_hk[y;<"\zxe6]BO^^4o]ZV$3mmk \zíDmZ%4nW{ ~fv}_J8%4A2k{ըHA38^nԯ5:8vuv(.$;:;w^e}]EM [K5hhgIS|ig+V"ڂ4w+^5YҺL?U違궩[7<_wfR>PSKZY .ʓu$[*҉me'"WR}=1sP)gLg;t4m'I@hCt(1o8"eqD%]h{|O wJ:S3zHi$[S'FfQ_3YOH_(2I2u%-_Y`(]v rWG7;DLjZ1fI$t"x}tF+RF4v }*z;(=VѧhK3:DJ"QyKTJ:N ^ sUzR%@n&ipiQ]YLthODQI3:>4Iwٕ"jU<|HN'Gm?Zg;A{n$%wz%aU!Gص$@i)I+پw-A ͟ 4owlw$I26Q dөD*i3q} -9 -םjflN$^݄0Բyfc$ܒIH XmkmIg7K:x(F۷¯ʒ:W!D.(86./%$F;|fRgܒ!j%Lt$sDje+!+*OJ- {-X7h%$UB|/yuCǩ)CKps8,`CBԮf&+=wsƥdm;6"dI:Gڮ :/Ies":]整4$$ԐNK!C0Q҇I," {Jɒ6.-'ծ6+z/Sv H&$.`YR$IOFDu O`1LۯJ3 > 9y+_!目NIߠIQޚu:>iwʫݷ;Fd~eO#%(o>JD)-\_݀z%D5˶KQ2Aiae^E,؟~SRQze()i;R@$[oIIqw⟾(&6drL%L(/OQ:$G'IwU3*j$"Ūst7I Is7W)*&It}(O=}]U޳kyf_Ɠ;S7"1ضjYMyMc{wk]3r'L=κEy -2-';=Y/mOuQ+3(&f}wcDg[pLߨeP sWVx,.0gDGs|/sH# IK۾? .'0qL}qcdjѯ⎤ف*~2C⤕Z-^M H7kiPL?Q*bzMbٸ2\h$]FvҘ%vcfQ*ETt߀9aՈ͟"2GMPrr_o: t4fQn` i9^fQ*HdQvǕYV$$'ߠ |x/ece2pi;flPRz %i3y3D}6݀ ߻[T&:J]âM/mMwf` xneY}%|9u6ݞ"(4}B?i1^t!Vsmd&~ZP҂kkƒg>H&MȪ ,2A3 a*_#1#" N IHFәEG,+A /V.4ffA{%5ҘO6aU@Q`e~IkfG0Tڑǻ㴶r= ;Mc<0w DEG灓%-?lFd,Ndi-h2LhJ掤ʼn4lO!L4cIH:(waZ$U,IafQ*O ڛkSNaʔw7aU !2 8>Z9;,OM\tJ<=ţΒYo #|"wulODl_\. [> 2#'5@uv6PR_R J:J ie `&O^9{m,i&;Z歱lbx1`luڿ훁ᖡTZ a[{挝%`=+Q)q@aNbbx B/-h0Y ck]lH%3hfa{$&K ߤg%MD7m?g{QJpUpLf84ꅒ6vTEԫ Rkތ޶|6a=Ln63}wrN&3Lhst3#iQ֓M:v؞,i-"uwgLetJ!=br.ֹd2 HzO_ 5e/4`sݬs][<3 8KV, uN%@X* I[_#QmX6u!.#g[ ;̰Y;{צ;f^Mk-*R:J6w[˓ A>( .Z_CB~=Kqnt%-ǁpr8QgzIGW Ѵ"I~p?ntl$\K|V'gK ,+v4%sIJ&1RzytqX>-kf73UPiqh@G$`O¼/L%cGpUl  ˄3]kIgkʴRinV{غ\f\,lj!J!|xM3/t`S`WIپ17mW L-ti=+yS9ΰ])w "l?ݴVnqH@GQ f_k^;ؾ%#)eF4FIփ*'32H+!!:0Q nN"2oƬ-mon{{t4a=&xLxݍM]xOvijUVFߛl3(yL̸*k,̙;0iNX qf#Q[>X]Uc O:JՈV.oV.?ڗ~:e, qe2CI%=#Ľxg/$<ör/PA35aέX _&2roU̒4Vҕ.a߫~"j,zo!gd2Æff`Gs ^%]tl<]$ J8VRi*wT x?Bع)E?6kߙ`'ep m@f}(3I7(f2#Y}%m(=fJS_~u!fRi`nVۭ\~j LRiHEҵwH:$<"=2E nkOe-eŝbLWs/Qz9I&$}xԛ3YNq$G^ vM9v c1WC/hPcFT?~2#Ri&¿p:)=`r ǒ&822a@!e*430G%&'؈b2Ilp=$\(L畴,31~EV3d~7xI۞$i^"D6T&&4[Y"ǃl&{ݪW$ lRhַoM~T5qC[l+[SiWKvdmT@g=mo)DVGK.ge_`%HZq.V=c$LlOtȼX*U/Cۖ5p"%1 u-XRD‹S>'.5qNHݑ$=En ,]td2Cf;oki֯4 '?;JzM"ʌ, R. fujmTFG$'bƿ7hk+k^TDpk'Kh' taFϾ!Dqv"Ls(Dd~kqS[|D)H.t;0W*ב V ӁM]%]gVW@=~;XV;De-7d2ͥYݲf'j7wJveԔx2C 7%ߝ}tTZ ;N1[$m'in7 7ktcIK:X*4듩D%=OxK=/"&z*kX nq+3lX2]5O˶]\x+nPL&3hVYlqۅ#D7Ł5)ly֜iPAtJsb T?`{% ,[Qn(8 X8('Ike T.NSK:O.6$2q .uqC(!| Fݞ!BG4 R L} <0anv"/=G|`d2-Y2K ҬX.=WG\@jgF^. IDAT?}9 町!tJv NAQ R쭎)_ѻn˲$I! 4--D!A>m[!tS]i "Pfв7MX2;9w.BYpZa l_Ndnh2LfD,q$ik|KEw7Ofmw $5+,3H(v~Or^ V.9? }Wפ!0 p4 l1i%>Nkl{5=A%\#voujU&y2Rin"mn s?g@Gވr6)|&uK> ɒz|!dwt]$%iIKZ/)?B3cX6(ۓOfc{%B̂1eRi_s"Gm7h?$ֱͱ=nL۷U-d/b$qD?,は2.7mpYfqWwT0nX͝5E,I^m%y20Ɍd"؞ lN$~}xx3p")`GIkb x0FLku@Q*t6rGIK[cق lqQf3l8r9(~N1^II8m?!.F{aDIl&ɌH֝ LɄi5oGY;č'ңnIW_H^Kr)ɟI` 𠤏:Ls(煞:~[\%1dI-N!:}'idv # %F &|;,/=\~rf\< <OKpM6XC1tnPdF$MM]Lt(q,qyx?hf ]0'q),34 YrЦT:8@d\~unS1Yg5o#5$Sc4AX_,Udh^ND+nIcٿ@7rF̳Q*mJ!V.! V@.'6`7R9XSFڌS$l O]B>:JH]:ዒW4c'3,hf9 Uuiu@DҒz*_}$QF7|i"UYal?ڈ2]ѬBSFey2RGLSs 퉒#nBv+RimT7آ\1)ֶoBJ5+5o 7_nnt] MDQ#ޏDgۆҘ}<&Ko%J#w٣۾/Hl;5%x+^ésq`BuFQ۟)3Đ40Vw-–$u?pF%CzۿiqHJ ǧZauemm/|z BVՒuV zU#qPms sIx le{Ñ&._LK5eIG41 P8iRXʸ_v)pkaZ6" fHa%w8Qd|XgdqgpF}x'X vԧ{sI%Gk^o_j7"kfV Ir4SDFUϧ~A}lOJjOAFGpL|`r ^.G'{}mIwJ%Zh|GyY25^ (hGTt1ZO391 $m"iêUG%!}IJq&iI+}.#N۹raN2XMs:s?cӔp+gn !imIߐ4]lSʲlOmIw~F_"{ˣEƪIٮ>g*ʙbI~l@@e <3>+C&έ I[WfzRժju,++{GKITE]M4 ic`kPe`]`[mH~d#:'W&J!g"<*&Kڒ8|X@R{{IgўV4h}W#Iߖ"韄)8k- |(}ǕetL?!1Cdf]KdQnItj׻uB($o;p{oI}?hUAN>fk3DlO& BXX |/K*>=(Di14[l2Jk(,Zl֗c~W-DzU7z}4 ĉnD El?-iKDo(Q*J\x{Z[j>A7XYXA 2V>&XAI -DE|r:gZ?Kzw<hgdtpuLޒ6"k.VE.L屶)Vp!1o-*B?O4X;(0|Z~D:s2 w = .h#1J:Լ: I+V{rnLWkWשhJƧ[":iWO/QP|NhGw~DtڔJ)+%}6M>M<ku6$&8o۾=:mOۺ4Xz< 2j`eA;]*io:7o iDn",;]$o5b(D=1ة\3~SH|M`VǕT`%I7׷.~/7 SCnVKP2k:M!2JXHx4qwH:(CF(1 qB@s~HdCg9XMR6M_tg$KGV /i |!`?$}w6h{؋6\*\&\Ĺ 1ب8ѹStۈlߗ:-KdIa'Uk.7^'FWı?хb"rv<> UEDC}sk:dlw(`Xw0Nv߮[}YL>|TN- Ot䚉JdEdc[ 0EҗڒR%~itx#*E>LVϜt%B̺5%"b bx' tW'+-Iil&}%_̛[SU0O9a8x0Nk+n=B>VsݞCC g[f@9`-<_$IS5dg!SbHSʁhFr, Q:JYmsu^ "҄شI1Iڻ,p8!N"i\ -CD6Da!0CibV? x?F; U,yqCe6@E״z;N$kɒblh,u}\C;=ALOIP@@9 ?"ĝOVgLW$lDăNϣ$ǾOQÔ-5J>MB϶wX~pmcI ĝ5lyƲF /腷aDi IS$bB#| 88r$X"kBԚ@Up躀8{J3Ӫ+gk"We{^(5(.@B䚋8*ɒ!"cFIrw&<L-nKZmF7Q#5Kn+idO5ZU~YRVo'3tJ{Oxz[Nk`RII4qč1MĄD }8E[HLҧyj||G#ݼ~ҀD5fm ”!zàŒV=X;p~jo:ŝ2wjj-+$Lg6B!.̥&eB oOKT^;1Zm<=A +)~*:SN3M6pv3k)Eu5^G;Q[ܩNB3Gק)w AX'NbeMVr"񲓤l+[NM_!$"%]Ys"1S!s\w T!{li7ӯW ݫr?~_oH: W."W[S)J۫TmS|%2 ޤˁ%GhLbhS&FnJ_'f^=H{3L(YgиS+ç[̠U"ӊL?Q*-@܈;r۲ 8II:86 1cu2pRW7 o3zxI!fNpLjGsؿ#nttJR|mpFV(Lt"&HߑQ2s:1 8u6ۏScf#]G9\YՈQ(jkm;[z8sFWV|D#Z˩GZmgI>+P[yYʅ=XII@L_h*헫֟(5d}"ӥhҴ#Q=6"{2YhWyn@DrtrL0=KTl@L=XQ%G|/f}hųaڮz湠Yݲ'hYBkSnatk/~i6j 2K%t7;D3ݮ$ΥpTj6RM`Nu7KGH읖t]P c{IgH}>; 7':vHIʷY뇧>"ڣeN#JS+H ]fMY H*-޷Ft#J~Ax2+:qu DW"r_&1*EJ1+ QVvu jXkOGZƶEv31(¨7l"Ck\Kńt"$Cd~]lw*teWx!Ya>^):ֹs|5jy1Uk\5w1be%YU={?LN ,3x8ř1ݫbͶry|kf#`H\Hʩ:wndƛm-֦4yPzoHc^܀_co2}g:MMEYm`G{uS\7w&c%-TAI23DmSY )^깇'^`tuwΒGmBih޻pz%t*S%bg^`mb} Cw<鹺 `&IZ6_(JYPEfWO^]uuF]gbl_fz]yU.WVI}*,DJlt%4bUZ!=ϐѕyjb3lg,s5ض'g7ʽ;3r}-a|^)@tJ3mm-Ұfj6EL'Qݱ1`~ُ81wNΐ @G o;Za6f|>(4Zif`%Ptz^h1twY ӽʃ e!iJbVIL*)ʥLOZ6;uwNύfA {(WI[$QZ V䟫Z1ysWbhŪ兰ְ(`/I.144b]>Q `Dz.*j `P_% KZehIsTLJH,Ht)h-`?IE0!:i*)ʊJ/$}h 7\"D!t$:EZFBB&iaBh|ΌZIjDIT5V3Q')93kMi;`KkNJZ=S[@*jeW̝F(oqGҧ3Տxq4r܏J:8aO(~ ޶%%N0^|v.g훉B&`GJ:n=C137$_TY*&jIU$-!i%I_KCxKψr#Z$j͒fRi:;ζr:g;QnR^mR;؇#Ѭ׉OV}-䬄"Q2 q,h{3rTp+BbpJ`b\zW1AQ$!x AKo"鄘17{"sTQ |5q'&M~Ȕ}&Hz ]%uHb;y%m-i oK %mJfUoH؆fIkHZ4V* Q+ 7g"ϊJG;U܅"zi%L)x`O&nNh$DwN(rQQPāuQ~1S|nbI3 iNI5sP{:azx0a=(>4;52ZaNʩ9$B1+{%a;1fv`_V. =. CN"ίyT̒% w$IжQY;χqCI /7,3lNGD-bHf:5`wa-Im@I5> \cYQExqOUFuo&>^t]Bͱ>+iiba"h*kJZV#ơ?#Scw% ңr?!t !YiBMt!q/q}8oC[At>;WkOJsrXϥ HBT8BP:EgɳՈX$M?1 }R}%5H"O&iNۧHZ+ى ݀l?b,YQ Ats]LD܋ ~Xҕ$kI* {SK`}r{"HZ!izܶXOn:\5Q?"B1|1ZҒw7V=2#htW IDATv:۷HZx0g:S׺]3%qt'Zݛ/IzH׮U8pxMI`ضiÀsiffPL]€23H\/&Q{Rn=}q!$ߥG#Z :}jj&#N4gZ6p򹴑`:%JVˈ:e}KķEە߿—^#Dߦ86xh> ߥΏXO: LM- {(^l~ߑH49^'oڕ$I[EҮ乀\wȶ;S DYxva Ic%-ꪞ1Xt+ֶ:3:gF(i椦D6nڨҬJܓ)20^BxI:ڒf_OiFڞAL#i`7=fחmN?tG#/3RiQwD\՝$jM̪9]$Xw81:DҸg&3d%4q&G>XV&J~l4G$/2}crm&vTn)`"_}隕$QvS:CD%"̶UlH\[NG2WZfF/9>gguE<o[~'v4c5gmל >:J]p|O _ΰ۳Zs8Uu2L/HZȬ ؔȠ6MIfOwJSiC!0ab{k)I5ICriD{Y$]'SiQ*튝dqn$r7v@I// ؖv%Zή,Ot\#r|㚁ѺDwKZqez&ԟ쪣M!:*Y?&{$yLTPk#d2C :Nt.{8~/mtH+ؑ0bČmz~γn$JԿ- |؊(;-2#SӀ+ZࡣTTn3gef m3[kIzMPf@oTeZHX}!hf2LHI,}Jd-MwRU^Bd8gx̿Iڗ8=j{z6|P &QNؾMҧm?-i-1V58uggPP&ZU6K*ܔpFhYw5@_ŝS~ng~3m_%1 TL슫*"5-ݛI:(Udw隶lzeوFLf,C.qOlSs䋉Ʉ˶Je\R}}>C+& ;_WH1Ri}bQo+[Zg' ,kגZ辯q Fҧ$]#i;I_JX+WKw$݄c^=AW뼞K2ɯǗ /e#}dc$-`!i-IJlsq}gz.<"iΒW.Wd7PO2c2tUmXYl|H#?l8b=Y7l+银ou\MG4 ]h)L/Hߵ <`f7ƝFOn$J;L?1y79Β-Y}C0j,?%L 7"&f2z%Yo{k=%L6l%0D:`䇄]w$\Y&|2p"qjdxQv|!?/cLIm3>1 a||3 _.}CJӍ>Ҙ_kYi]:{~@ҮDV·m_T;n+G~cIc/I{~7٣ŃMtLs掤EwkIW͵2MWo1{C19mv/a˴RiYUm+Le^&i 's<H-I}{$2ahqH]qox]b7mLă$MLަq&5PBĤ߮xĘu{B ؗ<%id'$Gg>!5wҬ"ĝɼhyo7A~^8Vsݞp#[Y1M.tJK.ri[|sœ4mw9L6mc%f~5oJm݊I`[ \[-+L;9mӪX2=Z~;I?&~vBKkekHgVT''k4*=׺WAib5| &؞ ,,{}K;t$ѵz;O4sC/;{a@eTksUI3/[rX;֭}ES;3LH_OWIza-k 8 hC-K9,@?S,|ha}L2i<ş b wHElRd ]GL!Fԅp#Dk[/2LC $?$6`S+% ؕү؞$ibIn<%!)~ p[%_b'bWO`1X$i)`z}iXv4szʛ_E-ۓ?e2[qk3,'[!7=ܑt<=I;ھ6-u hzj,ˌL .:TZ*9\~4OHB\ $o>?^fK2 o]%-+vr8!n#\#eOsXة5Pm W͌> ]81;HZ 8X'v:4y`HRtj1dch ]J*i,CL\[KȀ]XȬݸbowoe0@d8ݓ윚<*ٌ0bo>ωfįׁ;Ÿ9%٧N"D|} x8M^uǒքui{ӈq?%^,T!i~IWOPoH:3e1$)Iy%=#IIJ]%Hdȗk"iyIkE?tV"Nt{%%KU#iEoIZBG$m&'v oIJ&=پ$mT0\K ֊;=;Dk“*Mk=m/`{Xyw2M{I5?hU~TZرէ{˽.̴_]`E‡`EO.Jo1D\'lo>5EKmY~/ԚfMb@pݾq2zԿWe+KY_/ ?>uDX5x*e X# Y8-+SR۪]u5PqO~3eь#֟@`{lF]"Ģ,_1(Bi}͈.a>x7YQ1n}N/Mm+}Ċ*q=ې(iةrI칓8w~&7 =HZ8!2!ƿ#8DQ:K >PœG _SX$2 l#ۡf;1z%ӡ0+v~DY}B5% #MII>B2$=Wє3w $]҆~\ΞIÀTo{b)p+Z`!Mt|~դ^E6i%7[#/>Š+˶GW:ePg:!MȌ'+5p1ީj-lw$UoA~ H\D@( `Z, T$uI%/Y$(93 vMmuOLNz]u;L׽=;mYq>(_,H y:3^gf w&Z˛/!쬝EcGd@x&m:}=T`w=gWI=,|o׶73"-.DHD3!!mK|E\~IT\8kdݛe.%8\O|'V%ŽL+q'Ǭ4oZeN඿er?tk:IN>1mm Gp@/vmI9i;)b;"TQ@>LA V.$rOc{kBTV y' v&18ٌo?4 V. VG_A+d斴«bgbuQIKSt I 26F{(Bu U 0l?e{M}jw_a\}mI[б^_xDtʤQ;P_鍴,S x6w0M)7[KN3)Mb]45;G;|Yr%i IPKm֤3l[1&^Ur[}1\Ϸ]h$\mLTM/ۿ=;y"z*"Nv"S6ĉĸx1?dBme(j"^LEJqi2裻!WԊW˶e_)l6%*vEdirϴR>[`ևCg|kS(t6)ZDU s?ۏ"V&Loh )c4zQ{C>p*a=EFBڴ*ap]Omoيs6ɼwej^$w̝?@D ZKԲ̓1mmPÒwV%Lf4pgƶDhI׹c.a9IK7#֗t=!Sr"weu5rglJQ_$s_k5I&^oMB9=t.BHG +܆|]À "H/O"j΂hAkiuQ qtFsVc1[PT^~97cab%ىthO9VG>MX#6#og|g m2r'ΒjL+Bw%+qϱ/@S_R\r0`ֶ[ P[>6\n6a-CٔB*YnL H:0}2X]!+M IID{=XH_y%IZVW#wE߃a`dJ@R6a/; ˖Xp;ϊ䌷 =gXddUB'c̖#sӉD*Q9E|Dh9ϓ_-=^@6'㽛G41E} vsF4{::fЕ$儜Ld+_Wc1|ZU}ٶi-y޲~ĤQC]5dj@d_@]>T|y0a$`;J"9r3l+pVg?t0[$qpQI^w#UyO:5w$ +2Q4obhu{iw{S(b_>B'3=/NeYI[Кշ O$bTV{(ާ7`ׁ5m)jߝ_1HF2{6 ۳ nO-4p0JsKeEޡqyfY34Ix\%I_!J$&FN7MZ1A82y[`=IPUD鞒.ﮯR<"i")h(%C8UnZV̏U$MxDœ*g;^;vjE}$͙lgWRFUF۾ptDXi$MD҂DmOKf'~<tQ!%-AWIZ x^D yd| I㴚4-Oؾ$amx( BYJb`ꅒ$&KvטH2q^H0d>OES45XأKw'&c?֙}o$eVo8RpӝBaxs7 EdOӱ)ll:>,"b"ch:bFڄ8nCb Q}, IDAT^t*a:\P,EO,ϐ ;pL')ϡD%N_(넏],S"I"MR CRXҚDEuɇ QoojE֐4#TnCҒ&XJ}WҾSv'*dR|F L ryn# .thΤ̦{s4;`SI~e䠌nZV8¬z l?$li/I.B|+*ZNvA V"?ͧK6ΛU Dlcx~f+T[[I{So›iI;>FCV%F kl ImĀ>.ՉjM 5+z ߑUQqZ O!"fNdh]t ]=1Ύ!LE{$ EDz^U~3C+I=3c\w=OB+I|Wn=O6Ww0°%v57Q3-4i+=bDgmOQ RUo4ܩd B$-| \0%߭)RéUfZܱ)> eܶ 穲J# c/+фsB ~=/vyߩFٛ~MҬDI4;0퇛9aS7I,f痴7ۋLɇ0mf:ĝɢ MsN&H8O{WQQg$t}πMʰ + klb89΄Uit%+*:8'O>ikضT lB;IRemB|#]]鵎?b%|80C3kkQJTfʃw2c$OTLI ~7pŐyV:Q=>8l{{3$#3ו 1Wu,z)ђd%F::H)ܱ' '6iBW%/d=>֓M9$~#}l"DXi}ܥABĝFrDu mݪs1hˌIيВm="'1 UmzۘvL[DJV3T 0$KX=nzCƿl?kspmv!ȐMAk]v=esI##R/ΑU/jSȹ.^ATcNBߴlӾ&?lq[/iQQF#yڨv4=xn'oڞi0N,{~)*#$}F].E=+}p4S(v+ /V%_ɄF=eig`bEEEܞ7OT4OTęS8Dqv$NF@,jtu]lL^'M:3wkN"VSH 1mmC MSQۏp%}v1) =mIMھz4wwo٣>/7IWEƠ` It&0lخk@ݿ$ޫ_IG=UHܩdMTN1 l,~CDo LY(F,p m֢f1͵%!lfOl{d{p͊Ko#Ym}GI_4BM ~lNtx>ݱ6pM٬xQO09h%~Ix>,iM79ΰ#$mo$b+lsۯQ*D!7'fV lYbܾ>P_R/K'[Bͣ~"FdB]L4e[%! Nh7~f=GI\:m{vũ56LIDI%O$t'`Ckl_EFw9\NC`Rl$&TT[ʶ?,H2. pEoIZ0ݮDKi[Mַ^OOʌ%f*<6@bOĝ}*^IC+Xd> vŀfbBވk'GGPy0elߙ&ڟ+τXwTn=12;q5v5{I~>'m}dzʹ^!tfNiZH'QiuQ3 8 DldRI>uJz͹I|YN&iHՕȝD~D cR"Ηt!4ML-!~=Lh'3H"/+wl$"zm8I?/$H:*e>-iTa"V&DoJ@+gUSD65>\n,I{B|8c88?/+;IJK#=׭VWq%c#BpeOpِ(]T娨$aG߁ђ-_^жکIܮm%to[gNGvugAJOyX-'z|^J n/"wOj}+&R |NzwW[uRz4E`^hq!;{?y]&.'R+ls !gwuXFh5D5%|q ;9ʶK0sq&;)OS^Z7V/q~;EBfn2>"6#ę߳V}|{(Xl⨾5#?[G88TkZZyK7&"iAJsDz [OODJuW?!tH,MKd&ݓoK]~F6;ADŽ?ՒLXDkD5sǘ \mJX{ޒtPײl|)l:ۯ\N &!^l+3?.h"l I0!VaN?D3٫ǘU ~Y**&rlC.i"+Nv7@E ҂HR/Łi1Pi{6@ R$MKmR҈=R}ĘD=S^bB0Wn[O"kb{p #R`9}RYLWYqLx"fy ۇ3\8=So$}W653?9EqʲI߽XE^Ťd ~D,f4# 86~Ld\dXTbyio {Z;7I%} F$\Uz' #͵!a?\ս=M#ijBTkfgJ:Nh{ӎNxNeq"ƶHڈ bsS#$FV}K|OuA,\Y5LpmRN[mrI#ѹ]ѱ"Л**_^_J׺ v*ziA?yJ+G(XY4X@Ҍ$M7_ZY{7Kht=ȝ~=j4zwBkFqE1sLx#gsz~mmܶfӲ&oB fFKYV5{ŨlIDq1q7p5:z-f^THj2k:/Ҿ뜣+/\L!Mևqq:0,O7_gEBxےL瞗`N /eW ǝ|Ҽ+"`?#*IA+ދ3WhW`X&4޺DaL.$ĝ~nBDL~Kl_NW(l\܁f'>'l$i$ۻJI+vUT Dn'~.K8my".z**:j>X؛| xS"~ZGYtԲz aF $] R#L:+G٣Z _1"I% ЙHgzaHHˢaS`thaP'Ǎ|r! eF%,_rFW[C'&n*9NwJ%J3΢V""d}N#$}a}ز˦"wh>l&wʞ,! /I]X=& \( ]w{P~cZ\Ҽ%T,w$DIQgCIϿ:i$@(o/?%ݚ ZJ5PV!BMI=rVT XlnǒNL\GNq\`+*&Q}C"4n{,LV:czbp`n8b=^ !uJޡsKuMw\E \'^S ҵqfa߂)jsw$Hj[t5L8'#> ,˒!R:Mneė*bv1radGJ^v^+ONGϱ}j9$MW!u=QQQdjbPP'*Ji*J*iyIgΝgzÏNҒ>Fmo&L+qQVݮl2TU 6!*EJ,A5$&k km_@,ح<~~̅)e|`CIWQ'r $4[{ͅMj$ECXɓG IDAT"iFMIɱmU}(*FfKZ .&5^*3m^Wı[mM2qj}oiQLe~֓(Q,z!Y9/g:]Vzl (DGY)[ߣm)җy|g#7Inp=Wmz1mmkprk{X1cIs~W4H/>% 8ۈPl])jV{{C46T>_k6 u]1Qs6U3UEb{Os/ڮ[~eIXX )u4zX{TYfEEca ԅC^ 1µ+e\U^i)/N̓tE `7kR9 GvyKĝQ#6_1Y ;K]rD]a4;wI9?Aǔ޲6ٽUE4:YDJw+&ll\{&Ŭ nTз aR<Ǔ)i "ce^""׶>.PCs'~͞^$ ϐ!,"jb`Ew!\KlCMWf !{m/ν7HژZYgEIR+x0x$51oѴ$I7>Xv.!e-`b9Is+&Ԣ' 8!"3b^IO;QSJZa ;Yin]H|$&mI/۾تȝـwePS+4)pTnp`5I ~%4G|2M?lFADNG<Nˉ&QieBz x]C3QJ Sv 2پ9E {0;s;I*Vb% n.ӈ]EE?& 7uA Y Q)2tצ(VdL(Կs邠Ul^IB׳4(Y<-Nh NR-_6(SM;!@5}=nc}IHZ5.ȉ;D}(~H'VIjaD&0vwöD]ÐĊ"n7yi\qEE+8X]"J I;4loW{`f`lG+E}J? &*?TR>G+jɦұoEEc=`-t5I+8]WlH:0$ϜGӭftգH0XI܄8.ՉyaB;FQ2dXEE˱ᘶS5?loJU$V ((a?:Tg i"*%o?NT{x=g~MK^&W}2qkK ;~QO( De[ALT +&V]Iw3t)HZG0qt^_vLܱ}QDdADt0iܟHzx.8vE`az md6! ar)wwIZQ7\(O@\N~"~l a|b+Dn(Wd;Q #+cd s Se^!aHީD{AQLkXZ92P)g8vwCMch`ʘlV!9eEEaL[l|aM|Г Q"`K$b1զ3K:ʕDDWsۚOUOv$E_쑙 K:PҐ"$mA'ڼ O-%z+`{`o=9_7yXUQG uQH$ G1:<Ш#}mDi5tNEEEo|t3ذGZ|<~}ASl?e=:=vsӷ Dz\IG ٵfK.鋒L+*~VpWf% m ,I<Ib/oCa{go >)I\d>ϛŕ{ה v8!,`ۄ Iܱ=H^v$U8X.}GD$`)Y 菀å ݝRhs]wu+LI}؞`97'A!@IC$$tb@g,Ľ;t&P&_תH#"{cX EҮS~ǘeҁͲ[ %{Xə?~QSR$*+f{!{T3e7&ׁJYZr1*V5Zhňԏm}Tx|6!&9m>L$F՛63T&UJ%-jI7d7bbЪҊ]%`"Gu?vޛD t`t#5Lf%n u4He/n8ِ4 yvev;IƘмX{\%O |/00WTd ;%NTJii:y$-cNx>qiDO~d_'% ATSRx8]Ol^xQ4U6";bܻpIbr KbXaw%WT xZ%d|'ޢE,bbqD6_`N/3QV{^^OW$]|^') ;Hm_VJu*lqŸi">V'HZX8>TT`3Ia~"|k`NOI{g"iiIM Kx';~@lg,BH²kv@㔬F0zR_X F~&ڷ]h6#D?~+3b`}^tz^kd^b8/IkmLOشJyyn}fxPhoI+_mI'"@&,S 9 ִF;*$[яØM}Ac<%LbhYI>'L]+*!"[a%f*۟KZ8,>$rgV=.` I.E.Dq_EEDFDdLikFG3eh2QI=EW %AGŝ4OyER:p;!LՕ'Iڄnc>H!/{~?ibu,LxXNHXnAwiqnmryXބ7ޮ;}L~zmůwp<0wZZQniq pmR3`?I/"U8⯄q3|pڸqyy?v&azkVwLYS~XT,%s;F]BvgP+}Q-7}QSҗtoҾ)jGӿ)KnD!`_IWWJ* rKzz<1 1~)LOO}m%)rw),- ǘ4j$]l hj_W xogI(ԟJx%+i%"*z$}2ؤ|.ƴSz>eI?}VI*pIZ8$n.b"?  ~Z|'`kW 查 F^ ,mEi>pHE[)`)tw"Ԋnғ!Rug":η}I 5T46GڴJÏ~6m T⥉2$ %*$w֟; SA0"ZbU"`G"-}"ߖ}SѫRYq׉2Ecԓ:߼ViRDpGÿI\N=9_E"Ӆ.̟H:Z+o󜳀}#%mdeI 'ہtu;?ҳzDH:ri6u L;|1%޳UEe|-ka' $=$=A緟T^s01bGMF<5sA>B @>\|؋ZyIÉHsAf~B n3B@$L\3Q?i,8?~j 8׶rmv%t1G}sje.iGmgs'UO\`::41^.o{1{6<E1*&$ kf?oZ?1~O+ŝC9ҭS)bZ 8A iS&ϴ|f&f] ;``ۑ ^* )bSCYIbռPEE\C] i/)qGm`sGm#XMJ[-< ѢawXD9yK}ӝ)1mm5hRd ."&G٣z%*=v:hW= ,6_>\KIn#6B#雍דt l3࿄3?N6!.eJ6OC V"NlKKCppcO}cSJVVxix\\ ,I|%FV/ TZ)L B_fd{c ql𓌖O ~8Wmy$} X1>A<~E3mV"YN!>M,Kc$r)NQn" =<]\hH(\$m *3EJkݍqYIߵI z}ܭ&ާ Ȝ#>фMj:!=M|gOT4%mHGyf!כxMDY&KnVJc }Ys~\!EoLDEԵuAEv_"Ձ'3m_V8DR/w`s8ȼ QuS> ekņ4›dpm7ėP8J$Mҍ~9\]+[8&iTX^ۯlocJةEv%V~ @ !RV#V ';w&Bˇi62ջtLsN#qWL># ;=đ40R^xnUjV빚p~<)i9]3㟇ld/K4yμ^E76k~mU_ͬ .9GUS'6WH i~I& b(O$&[{k`Wr(ͼwmiۛ,LW<n ,FMPxg"iDVNY%1.;!F>w=W5ޏ9 eYR1n ~oB,=O,H3oJR_i}9(S!ܑ36$>Nq%)zaBD; 8SQQ." XeI%ۖGEcBI뷁lj( +%ض4aXVbimR aPZ훒 PIzvgJ: P6k-iIK:U߲JEfL[z,^7\/F[W$ݞTzJk"+Uldb@GeſBc {t-:(0JzٍlV2cڦ"&2Rl]H^3-݀S[pIXXȘ$x<[x7gRF4y"w/ 1^|J:[҃J:aQG{Xhrn[&.Ztl[&VNQJnz}==]6鿘x] N ̋'XHL:>U)'4-lkq΄0e˜-B0(&"a1"J3#Rю}{STVV&=F4[پ&] ۧx%=okxB9n~AL7cR͢Iǖ;&M*O ϵGWڲؾ9\_R]D~O9D8ߝc'iIg? ;!f!JTkikHk;kd=I+?PkdIw vl<S?} mIubU%e)_ԭ~.4IH:o%$]@ݝs?a`_vj bEG|VΔ T]/`mvm "'xhi&+]nv]f֫$HZ>1I|68#{YӇ>?YH+IHz#edqmvgAžg}[Ԓtg%#M &NNua}xO(g櫹|/!F]㜑u#{ya{c5_I}vj_r og$7~hr%I O eXDHH$qnmT4OTݪ3]uwNr'状X)%p")+ӟxI?CӸpj4˜k߫=S)TjN=<+bsԻf3빠s1IK+0%RM.|gu AҬxŮ=088S!m,2Sjl>_kUqa)N5JOCa kf_qQ.2%#<ǒ0׺ݙ@16dқt, IDAT?WW7>H8q_a߻ 2L1}bE"Қ>Nt>v?nV"Yڨu&ޡ3"Y]iY^/I}+OGbᑷc%G3B6#qߡ%WI!U|\yo<\$]#i%3KR HX&>$ɾfjz/7j,)(3y~Oa.xᘓ C B|k`oHRD,dwem+ۏB wJo2R~#.:-,!N2Ũ)lIWH.VȽM;淒'S#/ x'v>s f~P9.dvo>rz6z3'^ Nn+QBQd[:B*Nxji\$+0 vøUc\빀);~J:ϓ?pt~@MhfF Ɍ'帡$<')nivu(1ӇmI:OYRsiMKYSI@A_a>5IQyF^Zrׄ }$𝰒T>W 5#(DJ襴~~vަhdg݀3JIX*R`r2+E%$Xcmx4"IgY5D`.Lйqx}&;Ӹ(RZt9>V2F9+ wDkt-䆿? u|L13uژ]rVuP)xHc_ ﷙Yq]٧a^cs`Iˇ4m$vH&sVDw*&A2şdUNid5=Ik8zG$pm/G=<]>#75n*cY)1V#ةMhBʾHe2q쩪-bl>s\rHC%^E,vN )#^`Xk\,X@^ ۟_t ~_ 9Luxz,_,k߄{D7tN#Z[WQ܉w whz#wA>Ɵ ?6L63^Y[|^`3랈ot>;]ܒrh]9DKJ t084.N5M#5bfh+E߄}}2?l Z3wX[x׼ a;|2Uq$a!iy]Aic:?ԻpP+`KBwpy}{x$ f֯,o௸2He2G,TMcf_0jvXWPO(DD"1W奼ϗKMt+O? "^ spx)ìq#xlk~.X;?>ؽ٬NyQQ;@?28+V ³aa:BdO2\3ۥq_H'6e[ߧF*|P|6& AtF W4DE!|"y}Zp+H]Jqϙ_T̬rg_ ̏&[q6$}7\ 7jZ^jg#dL2<굋MIKez?¿#pR#agIXJmzxҬGy J!X!% K=rsR/_ۈWCǕ%?Zm[RQf=I~lF!?Ȱג2SXG|xF"Ìy KfvIi!aLRSzdSMITK6i8hV觠0,I>4k? f+meڎOv߈`vl2ՀS8d"06ϗL4!\3IjBvi%-GOkٹEi)xL. ƍg ֐z1%9kx̮oWkԜF5?Z= ONmTR60"VO#_qb"ns?nVw;7-'7Ύbf/j63{D"xBx.Z'ijjG<7Mr]e2}Sqa|]9O(Dnn4Ŭ\l Y=+M$<Ygԟ<^k0;i}LLf W҈Q;b}*n KoIj8j>  M#n괬/H5UA"fq:}G!^K-}QKY~HZ7_ɹ76)ő1K5Rx c 2^F20\ly=*ϕQRh?qM^33t :TG|+&fv'^IkGdbfgHZN^\3UUIϽ4ei@d1Y_&i64C$͇WWz[lAbNTG"-S\M2mǸ fY E}Gґ-…+D"hcfb|axf6IRO_WK^yafIZ=.?$fI \űdtExVfvA),v2pz6[;S+A.pߙYE"HZڼ;B5CViuA}0/wc{)pn:i-f= i͹mEz!V;҇J~nmw$ՆOk _nfvE4fxn"ÙnB}ŝUͬϊJ3w`rDg%<-}%iKvd_FExo%,M}+w0p 'ם2tD&cf/K7L oj\BGfv~X8X9b֐d |Rl>Yi W?ƙD!x`(i;\i:.plRz8:"@~Dm V^i"MGI#cS`pKmCÁhw$mW@Hp>!ၰ5Z^Ңsk6RLf|6u lDjaxX iW 3_w{N/Ğ-&lj CұҀ3J#6f, d>̯?#!~Ϭnv(#{[3XGM;I> {:Mtvt .4'i^`o^3vIHgi|5"O/W\&sCѧx%~Iٶ^UjnoK8OsW+\myh GrLg)~6O&jϻܝWO؏Z}S4!ez[~/T$"5dfSqk6Oi=R Nx"wV.iFn9my=yРwe~)ÞVFlWcl+K,Gܑ4&VoE~l*i:O\J8Y 8i /PV&cU[v࿳%pQi`$FN>+u 3{рWWfv}6pXX4vTNQ;9S^DZdDʸG f@A!xx|~sqj_͵iElwbSfVơ_cgS^IqUPomãQ$}jq'mG*DB.2Ix2 7CC$̬T$X1TN.is|k fvq忛ٰJt3Wu3z&$ if wuɶûԝ!G./vu|a&IEүfvۻ!I"F̉~ Tf֧UqO1SQJ̞ M? 3p>^L]3If[߯%؎;.߄$=5ݛ45pJbb׶xuff _1rGx&Nj]azw?OƛYٌISc32/@=if;maJ f66tG>w2[xΊa [35kf5Ι PgSPx%wkۀ?o'f3mpYdfąLfmLf. @f4}OCImgp1⸴H݌CqZ6QT$tO Ng6ِ&Kvmf)*5D(t*~Ol]GSI |\γ^P (xw/<BS. m.-8,.#971r7[Q^>II̖~sUIcE$'vSg'S.5J%ܛuu\|[oPnc`F"aGpqî%ǿ,WXwq}&i1axDNgm| a' Nq;גVs2z`G_{|{ G$DTWNdp(p$i)<`A3{MFD򄴪g'a'D,RP|R_q"g |}$vIp$]Gͬ4c!9fvb?%́";ے )g(RN Y\T\^}?Exkf# O3Uҏ1%fVS&$`\ ]I!mi|E`[UlVoxvxdsW(c+qJ5c}Ͼ8X6,J6<5I{$ƌHsHb$Hfv4>n쇇WYa''.G&SzxI ^f#o S$"A 63]MixA9.709^Pn{<1q[-!#Jgg)s%뫖Fq4Kb;cJs]_=eiS-% Ɯ~ܻ~iYN #|AsI󤜗ȟ IDATHd^cf#rgXGn|e{7+09]91M3;f>3+Q3of'TE\3+{% |oC?(^MI<i7k߶:Om>Z.'!Ky$vYףhSrH_N3!3)"U!jpOH,f%݌*)EtBzM|v'%ۓy<.)II^ɹJS3ӢY ﯤ) $V^9,nyOMٗ-U=MZ_Lԫ&̉}VSɊH>EjUR?%3{Hқ~"6.~JWş9TwSu$dfW]>4I2/8>_^mdjϝuCx^qz{ڶDke$Q3c)+ ilyu3r4!| U*LّvSe^HivI?خ]̤G%L -?CIٖwYffKZP?q5|p2>3 vjQ;WdG;ՙȠf 3{0΀.DJs7 ҈ !w.#QFJ'iGRQ/͘7y>E$*瑖&24+/4Cfxx/ mkD}rO&ioc*_[&lҫ>G#;#wBtQ1ONZHiqx5JCa꒦Ӱĕ9/KyֹK/+V@h1Lff|jmKDZx1_? zI?)>M!7):I[);↏#B?hd\iŝ@Q;v7y ~I%D\O/I{,WqӢ%JOgKS2Q RU*9רbbq߶JH#I'J[SnP!\k4q<MkKETbF+ŝ*gZJiSIgٙEgo4/HNo/'x~աbT\e<%]ˠ&ɬk.6mM%flBq,6bRxxN問ոk iYDQ%3ۨzƣL6z1ٶ=\i"p.(<^Lha6Ջv#ŝ4orO&"Ţ6'O"hd$- cNt=7-npqؖLĕý]N01ᕞȝJ-H\(Sd~K<)=Ҏ)=Tq !BýE$bn=ިj)](WZ -G(DtZ"ySkN5$ Ol&t/RVNn ۩hf,sbh&|e;\/s3;̎5lS||&.lW{l݃F&ʸ˃Oܗ&Q4>^BxIp\SI9InKcCߊSH l:E1a*,$\IB6Q\(^ΒY=.@05(bK,A+ `s,l>++}Lx_zmEq'r>~xj Eu;HC_vp~"%GHO{*IŝF+#wZ8l9.JYj}"id11[CԿ$q`!dmMai6򃗐4E<#UfPA\'kj-SU u嫛_irn͜k)1bW`RJZ˖<vؐdf~_Iډ\p9g"/y~޲}ZP]sN0M\3rǾVj;af{K>I<] 4ݰ.N$%+xQ#kTXt.x/j,O?BxzNI&\7\><5's|{vYi娇hB1Ҫf*.%bY>~z._%i/|<)l풎#6 з"ִ32ǂ!k%L v% xc=4bUjZVXP pr\ʹD s:0#eiPn9L*ƿȑt^W /Q29tFDïͳU[wp^2tIcJVJ"bfHZ); SX%FZ<|1U@"L>C4 a(oa6H瓈h1dHJUtx4QS|]3KPJ+ 3{*^p!c")E$-WMʕl_5sqyIBfvG ܡR2LN2$|RofU* IB¸ Jo7nZrSU!VI'ṟokN;N⫘ 6 cSBG{#;_eI [DZș힠sԐD?Iګ+scI_Qfvnxps۴i,:rG.Kx4=X] xqfVe1/E]@a/>NkE傸kH*3튗K iFX!)v[x3E؁qC⎤ fvkIțTx iܑZ8 ZĿ?ƙقs>G~=_Cƥ:*)y^&²JYHٍ ]RdRq'!:{@4nV{鶊NT~nf_IGbft`:eT}0i3\RfV6OYwA2"W$WӔmOjRM_};Bto߹ Nr@4u {f=w5s°782T*. `؈;>)y[K"wcZVdH-Eiff rJjp";`5@u|>W0Kb~lf#mdf;U=~fS[p͇%-af&}IiN6>gFB./#_c;pvwmbz@VD H ~\//cQf8E"H+iV.03%]^.RD6čky QB+]q6sO`a""Z-`l>okz5,8OϺ2wF"`U`I`9;5 /wbޖpCvø&hGLf \8,;ӣ`Δm_FiƵCUYD-w$}OXhM}A|qIkRi59*絰!.'|YϰUVI[צUҢhJgfT;٫18Fv e[M"mf7Hz t>m~AҶLOYO;9N6gN~"C3(47, iJW@$i\݋D"ѪIw_/9~5:ˀmjihs^f`3l5XW\H+e2k9a`(ԏffJBh|$R3F%ӿLc#Js5qaugf@'Vo œ]O)xELfS+l>FZ=^fבHw8X85yL9 HZK!GI7m*YIzxNZfvC+.k4—pŁI#z.jE_9?FٻlhWe2+VoTC?d8Ii%93OD+ h4ef=$- ˠ%,Y/;Н&T xL;ףSTz`KĝhDwVvIr+4-Hhe.&^l3'iHZ~02o+QtO\_͟L4(H'zuaxzVjf%pb#vRa'l{J c$LfJ< ҄:l72W[^iE vh:HQ'˔4'.Z\qG1J 57m2&inIمS%rx*k~^7*G"ucfJZM&fV(q.V ^ p%^yofFqI 6.+]*Gn/ᕻ&s KWXo7Vh4l;wRfБdy9$C,i.KIV #Ռd2Lf\&s'Ű+n 󓪶3W>v"Cc̬?aq^?f=x?-c]VC) fvTcQ\̎3JgfW\ߩbI%%M4Iafk?(au2=khڛow"sNO`]IHm*vP|&NA;Hdʴ,NK/;ᦎ6VNƫe='iK3 > xI3ӄo#zCIٻ`.Y_ŧ8ku)%mfd9uIqf6A <@ᾲԻYUNeXdвLV$U'/ x&I6iEZ?:qJ|)iE3{Ju{Bۏ91vKwHx>th1iA].>;?]-]$ JzO1w/-#<xOnb13E"HiSRi3{/6>LϿn5{^*Z:e2vFlf?i#M",SK>G"\D)mf<彯*Q IDAT4n+mRo+ w2f4_JS:Bd<>Yl:K._CqZ""VO`LJŻAy(yم:XD(wxHH$#i&Lf&@cmZk07<&Ͽ׆GZ}&E5I# D07$ P-fs~t so`FhfvMqDJp|)NjfvQ#J՝cV=;> ~\|/{ {f=w5sBI#U|tpuMQ'#JXB$f$ 8d/\|4hml /пyS}3IˍÝQ4l>le|1Oxdrp1LE' Bx:զsI3{ӞKs P8|Qh[g!g{]SKe2ߪ6m6} %1J0/U:V6`zIٻ](y~9NXx!tD"FŝP15ܴv6ROh1 4Lf`wVt6KOl>?`afoI1B4E0tzJ8QS 'T2{PR͸]Y|%iS3{Vm4ЧdfūlWL6 ?ԟ%]/-'gy_#h]kZ}H$i;#xx` ;P_͓Ȭby@.7,sji/|~ 7AI I;3} ^$NEg׀)(E;ob7|&|]JYLf$z^VDaf$/Z33{8X^ԪjQV׋~E௒r? ͎K.O/ە<u" 3{HxݜZR|z ͔#Ȁq\nd6V=,]ܑzNŌޑf= Xtr̜J&EGw3,i3@LfW# afJ ̪ݟ.Mt£&ןly:Exo /;֫:e2ρiw,i!m)y /=]e"^%hH8!xlUd";HdӌJxc F&%xzJk?ĵB(: .Af!|p?X.\r"H:yGw9ʗ󙔔}wFh`_D33l ̎)iu՛̞HВYg䪫??4zP Mޥ RT\T (e HQ"U&tA!zgdfޝz}f{f6rSXPe\F1}nI_z6U [w{G%of\WplXtwx/_vtC3;]kFYy4zEV$i4V*`גz35G^ ;տ:BJlHg쟒4}RlN*ٷ鹑$vB}\w;gnYfA}41: rɝ[:y߽'OxP:^] KZ&44ߨXҒ`jO? ٠L ̚?Zėk|j\BU3۝*UvWt dZ E`|1+~7}8j$U3B0kn% ?R{ p]k$|Fd7+z/kxx ـHM4pl췳ɾJ:MR0<16^jY٬ys! _F.Ek:^t 8>nwJZ`Q[E6򼷧Er'PDe_3QI5Iqx"N*5Eb'Ԝ$%= }%LY 5k}=O\>\|xnIwH-^ZfOIo%H«zQw |YVu`\>#fe рG !LfZ:uoͧgǛXώ/ZOgqQ)~k+W"~VPS?rNTH1Z|S)}*煮1O% lcfcjiR ]! ;aߔZV1k~+1w}h%bq3n虴/I<_ |ؾ鵷7m(6]>0n3L ![zuֻ !efӁ~lYTL%#,(Qx$W!+;eLʝ4|,#%ras.%n7sf܁fעc ua#1WPe-rO`x-6dfIeOIZXx =e.۬a%R3ߍim!&I 'ڭ\`lg轑^A2>zT$wʘVe}THċe~^a_n:845P+sG%]ͻC'㫩V_6vJ#/t 2)2 61٣(^%i9{*tF_Ŗ<y^|ymgBa"ST `VJ3'p&im-Hf%]qQƓ}m $O^Oḫ*sIwJ+g~[チ/YkH3M8)< 5BV -`-~0\$SvJFocfE6,_O|E3Bɝ2WrG7&1s1}"S|TI/ᡖ1IKH8̮-:$]/gUftxo,p\/ ~M/T eN2dr#K3]cZ['uK.[9yzM l]gGBu#;eLe`Ʌ$Mϻ.oLkk]No75ґZ! o)Z!thK|%__ISffI{8KoH6O <12\ӣ.=ÿ}y:ubm 5OZ~W\WUI_™y/ؑlf-G%P0Q4&eH_5LLx9i2КޣL%REJ$}'FZ2I5%mfS{٥م6.T \R`C}^fA~bhV L+!ͭ_{Kj?f`Efݩ<P2n9`De;ܡmfvR/#QB))o:Jk5G־gP/ζ_Rc um|b.(tz;uЮ%c|Y!7~Xj*5[+bN L2$:2V;[fvŋ'4C;aX˜NkfYΘ=8I-KҖԍM~ o<0;00+nlS.y#ETD$w+}ob~/Hwpbf+=,:Pׄ/-'[&qs/VBYEKtc{ǘهf}lf٧f}nf_Gvcz8 'mefB\sɝB]Nygܬϼ|pݖwIj*:P*%L:eJ)MI]Z-xIu>9uUByfX'ndO]x!/;!ɝ;Z4k}B ǒN'PC&pp2˂ qaw531T+*wB1?|{w^z(`2 !>/;Sr~brwFuES@+:P /)mKʝl(~DK x x}V]_!ԔW_t0 df:e!)OTIK"L2qEc쮮QҊST,X3;}6Sgv-" !tӆ„`x_h i~pc !ΊEn(8иBс>2}QR]r;Zkto5sYs$wBCV.6kulI` PGr'if68F"7?Sh8_ _+:'L19rkfW37ULj3ջiHfH-5]tL!( nC؈:%)NTzq{I3"Ԕ̎LGC?f !pp]ASR0Q`,b# !t΢3_pH5*>Wh! `k3{@B4'Ǣc }c8Y_}y3U@[s)>p3"*wBu'e`f v%E}$D~Oj < ̗.LjYŬ9˽ X P@,!;8N(:. mfH!tVT!iVt4(1sqJRt<0іWD lzBF_ZoFKBu& af;kF!w?H(p%(IOh8ӊ$V ZgI-QKROʝB]Nh4gP3fv5KqOGnc/:FL=4y R IDAT\6GBȍ<; :PrENhT?PkHBMFOKF#&eENnEr'4$370%4|!Boy (Xug-6y?򼜘B{ *:PN2%쥢 !5O~'x O#*wbYVnŲ~y@B0ɒ ef-EB_, pYldnfXFoEBՊʝа!!|g/\t}|0HB!8EjY Q?'ُF3XBs 2>IMEʾEzlxk9'I!H-K_/nl̎vꚤ9E%Y!:ɝJ3E|H`Pс:y$'ÀI!K-Q͆#NP )B)lHF5`w5w5 4WWlׅwH-S;͚'TaZno+/ҽu׀ϗZ{Uer[ }&~^>B ͟Z6/{͚߈I- r{S&6r_3ȍ<7,;! 5S%ëzts9nnd{ j;sՀMkZWq{__ށZn^|?AZof`^ƛ5_kU[n6Qr=ۚm۱H:8X^("Bܩh8"O%nζtlDœw9jZWq{#V_{q{Vf^n\m>p%l{,xbZ`lC5;صv=zva ތZz[#sݙ10|]dt?Q/; XIOnoD^r#FTq|Dr ?LuҍjJx{̗>_-҇7 ,X^-{T0`m`<~x%/ u<޾׼Dn5z{!PKQS MawJ{RjbFU+̚]f`m.Nk.5k2wWބ'Ӽ5YMfoJ-#m 3k. Acn5kjkZl/k ̚w y~aщ>h8^Bu/*w*MA3k#!f$i7R`3xzZ_ !tj}v *wnƚمBܩ^Ǜ;BvL!ԍ8yޞTT^- 7$IHBEBƿoH!t2 NaDrIEB*B.HZy}|3{DNADrIY#&C, Oxx?4VMxX)V$ 4'о!zX8̢wd;$ dUN!PbYVeËјf tmfbf+B5;$-YHpY؜JBξWl4u#;!˲*[ < ^p,)Δ0$=l/kf*rqBjuE-EBٕEBɍ<c!_M:??=IrG\f6; F; !KZO8^*43x~ !zɝ ub, 8X0ץWJ{GmlfO;[خ~ Lf{/= '[{,\Rrli~ `u|Ź <XO4eŧo='!G⽉ސ=ZW*=<i]\ҙf ˒(\퀗EZ%>\Ac̒`UZ Ifvu~_K߃'fKζYoi}xs'l\Wo[F~Z_aK8ye``!4HT iRcw!^XWIxiT7Sdf֒_%M-ݔO>œ;3TT-ԒO7-wݭ)U%fCIC{S̙ӷUHZO<(i's>=?UҚ8`-.{ j7x#9xmGIT o'~ T  \ i:<1  mrn^N^(ox$LXupZٽz&ii`Rjdt:.FWe80hBh 1-IslxW?;g]w|y ̬3Ahk|N“P>aQJG˔ڻ>K 5rA&cO|}I:gበ/'I/ܜߩ=NvYVyo34p|xlپ$͍Wkl`f[فf.^-p{ k׶Efff>{ca2v ,!I:NÒ~o-%m#G%U-4tLGɛj?u[+N3;3=8ZqpZOߴdOvxߟjYp#f7M+733;"Knٛh9x̎BS쳒h|fv}~fv^5:fsviFX6KlHΰt+={fZ.ifԄ/o]z;t ę!SVu5݂A8Bc0Dn ?o%_%͋W>IWMǗef7J>-i`>_msi 'xf{}j5V^j b3"-U](4ú4tfvu^Gم컂KW}W{>so셚E?d; !4ܩl~4jxс43/G^9y,fք{'7f?͇Od<򲫒޶+kH%Kc#I'2/$f`GpӑʑTeYft,nf`xl-(}Dѹi3а$.:P@`Qg|Ye`[6m815G^mx2hE<1O-ο dS?ן5R,|"ۃ~mXx_K܃+p͒&HNc^}I_t%d{JAM.\.gGާ1*iGIH uI3?H=]9%;C R|w;_WmDhMl6$j%*w*OD#͞QqXE-O23 tvn~,Rb4+9/Cf5K0ɒI΁/+U6򧟖ZI7[ɡ%Y[I:tgT,3!3"= UG ~^pi~_fM^LҐT"~WOj'5|bO'WKj='~$ia3kf3$sj #B,ފML jfvo$Q&Os𩉻Cjࠒ̶߷<ҤS1ډRs U$q|vIIA}[8sx2kln{Z ^6 0qr?:x,Hd !ɝF+:֙Cj]hfJg"Zt5|YRܱ.xsB(At:"0+mKtt}G@KeZT$͚t3gxb]mG({ՀymdL52rWʖ\n'h;@jff}df6@~DѱfH~6[9`f;ٷl31s~vf|o*}ϖ&s3I_'}Oh<oB< q}Ȳhh34 3,]<>e7me]]eYMiIg;oVA۬Va;hS*l;$N ƿUL• iYҒn i[IOgቂ&`}f|m@[3uii(KW̬NLЮ-3.4*CKB 1xGvP*$65T&)vf-͒ۗ&I:[m{ ̶Ǘd&`ƩuPd4+ecXڲ31?SnUfe`9j|grd1S1@'+{s?^=)j{hBhPܩ|eKxa^R}:~ */o% Zf6%}驴ߵ29*,z2pcA.@{\O4'x9u~b$42-sH҅vO*vI{2Ǥݒ7܊m-K.iIl{M'H!]H6oHH|>'_~\PI_|BMdrf1v̧dK~XawDCb >'TLkJe:J:)U^ oYe<ʗs]WtIJ # )<P8“;)tVu?K򒞓0%^'~痚{Wެ/K};m{N|iGKϪܑ􇴏=lbj2?xrU=V3;NN{}FWP'MW R؜fvtn:3V ~S~]9bH*ʝBCH෗ŨI_GRrO0+~\Jܘƭa?|ٴn{w'~G:xu^_fYvd<b?5mÛ31H''⯱ OH.hN&NIlfYJTK͒$-k>GJ)ea`WI<' oX֖^9"=CC$-Q`>o*;~p[^H>5&i>Nҽ׷Iwwtdqp[K첬VIĴ^J$ fDQ/{7kӤm\aY0Uo C7MN6;}h)quZ>Iէ% 3'Mqg9$Tg&m̋^?R4nN|ZK3]Xu>62MU) xYOh]kf;Vx &xN uDnfv]y=ۚmKtE3EѱtD|xyMK'xR${{o(;8]E\ IDATvJ. U⍃W=<}Y3f*ut#Lv޳m|!XR=w7M407K/{Fx]fv`nvxB\z^Pl ,ffc7ēU4Vė} c|"[xEU2A}6īr/7ifuҦнZ#I`-CDr'׀-֢ >?q,~$3Yކ~ %afOO䎓+||{fvQ!nHɛAʜr4$ WUkf䮛hY O- mfOlktx%lBZ:DϳfvA.&txk^{:ʒt'YUIOe|;B7Ų $71`bbV!=Isn):B QSm$}!ic !P[EB۲~;L9АrIEH$| 7+ΟN5ВV1xn~J|$jyl! ޳iຂc !=L9"S/:4 ~\X X p0SQҬj̘ZrsM3^ØC3zf!P"Bhh,IKL׋cf63wV=l=ڒ+S{b?%\S>`><<|&qI(욐$St,!t7}Ѣc !m)EB=!; vHj}bf{i=0U'M`Cr'ÛW9-\&鄚]?-:CҺ4XB!tH,N,˪`U>G9g5$??3sK88T%fdqaX 6/:BՓ4o pkѱBOʝ?/Rt *rC@I+KLҖIoܝ $$ *'KT'*=GxL3XB3ٍ̆EB[C~;!ɝFHrGʕǁ"Iv'9UܒΗoUҳZ$ mgKKJk'w'N% $ $5I-Ch,%%BD3BËNeHβV`U`A3OzK; l?{üO[|w3xe{>Yՙʝ|BgBHZQ#$|y%J#˒CIJ7]wCF旴SG$mU nJq';媨$m.iGIۦ*y+H:DO%mPi_!th&Bʒ;E!S\Vt 3J 87% LNti1>w0gWH2r- mfO&Ix+F3>tuWJ<]+]p5 KI ? -o}6h`:oL$ =,?sI{TxB}x3EB[FӨ !4ܩ@LnEҠ:(f1 \6 hfׁJm 'iGs;g.ϲ}~:)[;Ul*iI{I>^sZJu>u,8ABHefǘmf'`}<:̚}3{Nw,zXN1K`?Za t(F iYUϝ#K)nwv5/``R"?UPߐzÁdʕ;gxuN*%Ξhf3TыxYݹ'fM5+uۗ_ض@B!t(bIVŲ lu?]gDuc%󒙍oFあ3^5%݄n7:xͯaYgk.3ϊ6y/s+Ѣx>CW_` & *Iwu^P̮.y>&6 i`w3; 6g֗4N.-{@CBFԖ~\lfGeƃVwJ/>pe 6֒1Ro=<8^yc<!LCx`')B}Z3en|B’6ۚYyB]Kǃ M`X;ELZ8p/>sf6Wfz+])ZJ

Type Message Explanation/Suggested Action Unknown Kst Extension %1 loaded None. Unknown Error trying to load Kst extension %1. Code=%2, \"%3\" Make sure extension exists, meets the requirements for a &kst; extension, and is in the correct location. Unknown Unable to find required vector [%1] for data object %2. Ensure the indicated vector exists in the Data Manager. If so, try recreating the data object. Unknown Unable to find required scalar [%1] for data object %2. Ensure that the indicated scalar exists (try searching in View Scalars of the Data menu. Unknown Error loading data-source plugin [%1]: %2 A datasource reader (&kde; plugin) could not be loaded. Make sure the data-source reader meets requirements described in Creating Datasource Readers and is compiled correctly. If it is a built-in datasource reader, try recompiling and installing it again from the source package. Unknown Scanning for data-source plugins. &kst; is scanning for datasource readers. No action required. Unknown No data in file %1 Make sure file is supported by one of the datasource readers, and that the data is formatted correctly and is not corrupt. Unknown Unsupported element '%1' in file %2 Ensure that the file is not corrupt, and meets the specifications for the file format. Unknown Unable to find X vector for %2: [%1] ??? Unknown Unable to find Y vector for %2: [%1] ??? Unknown Undefined justification %1 in label \"%2\" This should not happen. Most likely it is the result of a bug. Unknown Internal error: No X scale type checked in %1. None. Unknown Internal error: No Y scale type checked in %1. None. Unknown Unable to load plugin %1 for \"%2\" Make sure that the plugin meets the requirements described in Creating Additional Plugins. In particular, make sure the shared object and *.xml file are in the same directory. If the plugin is a built-in plugin, try re-installing the plugin from the source package. Unknown Input vector [%1] for plugin %2 not found. Unable to continue. Ensure that the *.xml file for the plugin specifies all the inputs correctly and in the correct order. Check the source code for the shared object to ensure that it is using the correct arrays from the input array. Also ensure that the specified input vector still exists (check in the Data Manager). Unknown Output vector [%1] for plugin %2 not found. Unable to continue. Ensure that the *.xml file for the plugin specifies all the outputs correctly and in the correct order. Check the source code for the shared object to ensure that it is outputting the correct arrays in the output array. Unknown Data file for vector %1 was not opened. ??? Unknown Error parsing XML file '%1'; skipping. Check the XML file to make sure it has correct syntax and form for the intended use. If is an XML file for a plugin, check Creating Additional Plugins for more information. Unknown Detected disappearance of '%1'. None. Unknown Could not parse xml file '%1'. Check the XML file to make sure it has correct syntax and form for the intended use. If is an XML file for a plugin, check Creating Additional Plugins for more information. Unknown Could not find library '%1' while loading plugin. Make sure the library exists and is in the correct location. If this is a built-in plugin, try recompiling and installing the plugin again. Unknown Could not find symbol '%1' in plugin %2. A required C symbol could not be found in the plugin. Make sure the plugin meets the requirements described in Creating Additional Plugins. If this is a built-in plugin, try recompiling and re-installing the plugin. Unknown The %1 font was not found and was replaced by the %2 font; as a result, some labels may not display correctly." If this causes problems, install the missing font. kst-2.0.3/docbook/kst/Formula-kst-lowpass.png000644 001750 001750 00000001711 11544160206 021511 0ustar00synthsynth000000 000000 PNG  IHDRxXl8IDATh!̪P۷F"H$HI6Ha3b1L77/˞rto&Gy=?2|hg>E|_?;d~ ,y􇞶kZ̜IC~k>Nu6>5췂^[Np"4>&Srs0IW,\LZe=~-vq)owFH,mОq &N:3 F3_qn7 Nm1.Q'9@@zJg.:ʵ pج vD:J Kd>ei؈h[)5<}nƌLmQX7[>&e*f[t(}ZʇHd-94hP Uw$`O/y0!HB ?4ԟB_˨[Hb'$`?cFJa/f|(5JeH}7·꙰)V zYV{:WzhH_E RwlSyL] UvxŎUOA& @x nQx٨8n`.~hPds{ U:+ש؛qZyJy?_ (hx g/$N/ HR/0H}_6Iڄ_ t撀_( 5@/&*W$/: $q z WJV<؊_B/]}_C$̲~$Qև6\QWFyyI:ɹCvX <ɾ 1ǖ ύЙ Z#?^$?a#>b!=b =b=b=b=c=c=c?eCkHt Ky Kz K{ K{ K{ L{ L{ L{ L{!Lz"Lz'Ly(My)N{+U.[/\0^3a5e5k7n:qCvE|EC?94~QTQQSQQSQQTQRURRURRURRURRURRURSVSUWUXXXZXbZTm]Iv`8}hBsKXhw`TRNKC=;:99:@AAAAABIJJJJNQRRSVYZ[^acq雯Ώ2tRNSƥrMIDATxkg,s^†C`!\ f"'Gf'5d']|L!I1K%%Ji 6 v穧~w~>U^{eBj7^-,^[^xEH Psj,=pJɍ_dsnW_pܘLFnܸqk23\:Yzk>/ aS['KO ͏/^!ܺ{oON7.<4;w8ww^bww}ު|I~ ἷpzY @G7opDnL8WFxO)}V9I/Q o _|vv {$=Ep rm|}鋧?q^&8xFOSve2Y _D.oӻ**o8rw,^ƫ_.p˥K&ըv ;5K&sR󭿕sd~pVn[UQƙ}?>~a^GaUըxwٸ'\bw5jA%R᤹md)s7_Z}eyk+w.LV.8}, ['KOwpCɿ=?jm?Z?O"v+~v.俉߅ג^nO/Z0񥭓S|ݵk_rRFە+++Wnq(kdɄCR]{'KO!GH4.!5ppppp!epv^d`yvzgZypv݌1ږ3R\p:Cx/ƿGugfy9Ӎhw~??Ds )yɌ'>pɉEA0FU ?ыRRp%\"48p?yz<Ǝ/Hg~GZp%/n0q}D_न:,㮔fwYЋxaѳ͸c׿pA+:pp^zj6}CN4T)|8']sΉxoOsYgG2 h `yu+:,sG2 h)'^&Hs-CJ3xv $qg]yg>n.O q48[=slsӢ<w2ނ 8egyd~2fbLXpD$摶*% leUXr"/M_ N6qskO\̯No{0\9Ee,yx^U*N jdCeH1m`d@y՞iNqx'*$6;Xሲ:IN G a /m 8qL2kN]uQaYSGC)#8'~J&ec]8[A6|6  ,3zL1 ;G`K@hTN+paƟ6-G9mrxpn68mi=pg8iͺm8mrڶ o8Ӏ!ᜒƐ3 81ppppppX~,0gD)&dt(8Np$|ݶe7)7E3 $~MGmM2mތi[Ɛu:̤Ĕmo8dQGkMҲ!8n8bq\kɶVwǵ UU>Lvҵ-wO^ hUGbq8p8r VqXU#gr1r 888885߾.7RynVR].FJ+ wpSKJڷr7X zPmਗF)G9}{pŲ.tˣ-׼HA_?7[,tc*_Uj~ݔ>ZspO/\=sY'ˣߙLuHkW/{U9_b83ճDZ[k^^ 'Wܫr{WU鐃T-k "!!!!88dlo#۵ q{R0RKPJE+zp6w0f 8C)Pgdo~B)_̮l#@N|鴇-.$. Kc(pkť?I ˥NT QdKc p(R:Ӏ3I36K$'tgGyK=})8;3qTO>}9љmS#_tp~6m8[tpgGrHwO_jW՛?dP, 8~Wl1G8p3-8NTgpqWUNqfXGzug5耩ى8I46ճqfYh-U|%jY8~|%j8Ep~589_笶qzv5YUq89ƙa325555Njaq8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p325?8Eeghrpѯpћ*Tc\TcylqT9_8'8)cw±pj 8epU88 ,q]p*±pJ8p,r pr*p2rJpiu8x8  8eD8iVF\e%p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p%8ۛv 8C)Phf0JM8pɠ΄ :|Uqppp($y$85L|7N 1%0ӨApqFp\8i d4qpf_U8U-.ݥpᴙp;⿏o.qϵai{:V`O){N?t0|uQϹEr ܫJ?(4$!(E[WA8"C,S\ilppppppCCCCCS ΒgLx/wK539+X4œ挢<29?gUEe`iZ7@sG8KΫW7~훯^%նyɌq{V}(io|q1,!Yibf߮zbΕ7\~{?xrN=ɽת[ G27smgfo[gJޕ7V839=};驣U%qN ]pw;qs?,-GsNU3±Z0UvDL 4p?<^'#E5C5Y8MeqwIȽC!&"_U{zp97O8nrpUnRhy93InHeLvS UUq88c+c1oSUU~ Wnh\i۫RnބJG+.qGn&)DC? }*9>rpp*ȱ8|bw|p#p8r Fp8r <;epǜ̦888888!!!!CH&ݫ,p)!!!!Bj^D-31[˩ZhA&7 rzy][hA&7  l.Go~n;t&啵 lA[>LN q<Ԁ7!h_ZNN-@4sEǰU'-#sL?Ǖ2,ёs%^`$3c I2jhxښF)zp&/4YQ^ 8<,(h[29ʼQvU1tTc8Gťc8HJKR戒'&q+c؋:=I{n=99TY (/PTz $a+{A[FT&Řf'ZpkM@3WTGf%ٷt\I]e+qK8eѦ])-&gL򘅒}pZƐWҒ>Qhұ%SRF tR{n=䆀dԞlcs G0_.J&Ps,=-q&)h>:O䊗j d-3!y.iA?<|rәMBO85;=&=Gw,2Mg?瘫ʁ,lCCCCCppppp'?@HyX&v\QIENDB`kst-2.0.3/docbook/kst/intro-chapter.docbook000644 001750 001750 00000013123 11544160206 021232 0ustar00synthsynth000000 000000 Introduction What is &kst;? &kst; is a data plotting and viewing program. Some of the features include: Robust plotting of live "streaming" data. Powerful keyboard and mouse plot manipulation. Powerful plugins and extensions support. Large selection of built-in plotting and data manipulation functions, such as histograms, equations, and power spectra. Color mapping and contour mapping capabilities for three-dimensional data. Monitoring of events and notifications support. Built-in filtering and curve fitting capabilities. Convenient command-line interface. Powerful graphical user interface. Getting Started There are two main methods of quickly obtaining plots in &kst;. The &kst; command-line interface provides quick access to the main &kst; features, while the graphical data wizard enables intuitive fine tuning of plot and data settings. We first need a data file. Copy and paste this simple 40-line set of data into a text file, and save it as simpledata.dat: -20 100 -19 90.25 -18 81 -17 72.25 -16 64 -15 56.25 -14 49 -13 42.25 -12 36 -11 30.25 -10 25 -9 20.25 -8 16 -7 12.25 -6 9 -5 6.25 -4 4 -3 2.25 -2 1 -1 0.25 0 0 1 0.25 2 1 3 2.25 4 4 5 6.25 6 9 7 12.25 8 16 9 20.25 10 25 11 30.25 12 36 13 42.25 14 49 15 56.25 16 64 17 72.25 18 81 19 90.25 20 100 simpledata.dat is an example of an ASCII data file, one of the many file types &kst; is capable of reading. For further details on file types, see Supported File Formats. To produce a simple plot using the first column (or field) of this file an x vector, and the second column as a y vector, enter the following: kst -x 1 -y 2 simpledata.dat &kst; should start with the plot displayed: Simpledata plot Simpledata plot Numerous other command-line options are available—using the command-line only, plots of data can be printed directly to files, and simple data manipulation such as creation of power spectra can be performed as well. For a complete list of command-line options, see Command Line Usage and Examples. If &kst; is started without any command-line options, a QuickStart dialog is shown by default: The QuickStart dialog The QuickStart dialog The QuickStart dialog provides both a convenient facility for opening previously saved &kst; sessions and a shortcut to the data wizard. To open an existing &kst; session, either select a file from the Recent files list, or enter a path in the textbox underneath, and click Open File. Clicking the button to the right of the textbox displays a file browser dialog that can be used to graphically browse to a &kst; file. If this is your first time using &kst;, you most likely will not have any saved sessions. In this case, the data wizard can be used to quickly import data and produce plots. To start the data wizard, click the Data Wizard... button. The data wizard walks through specification of a data file, selection of fields, and selection of plot options. For detailed descriptions of the data wizard options and settings, refer to the Data Wizard section. If you do not want the QuickStart dialog to be displayed at startup, simply uncheck Show this dialog at startup at the bottom of the QuickStart dialog. The QuickStart dialog can also be toggled by selecting Configure Kst... from the Settings menu and clicking on Show QuickStart dialog on startup. Any plot displayed in &kst; can be manipulated. For example, dragging a rectangle anywhere within a plot will zoom in to that section of the plot. Holding Ctrl or Shift while dragging will zoom in on the x or y axis only, respectively, and tapping the arrow keys scrolls a plot. See Working with Plots and Window for more details on manipulating plots and plot layout, as well as the different mouse modes. kst-2.0.3/docbook/kst/Diagram-kst-windowplotrelation.png000644 001750 001750 00000007435 11544160206 023735 0ustar00synthsynth000000 000000 PNG  IHDRF譂IDATxOdw c saS9P]PVuZdKU%T rSinm\"1DD!! QZI*;̟̤Kf;I|]ݶy<:|ijrF.O`0"ug䦚4R>F0`####FFFF0`#F0"0"0"0`F0*!z$gIOeNя:#Wv~I9;0QYWҫ&ҷwF0*)a)r?̑FsX(h&EZZ#{HR5 #`ҡmC7$sdw M4N$Q wIWt| #Δ}Z {Fiv|c:hZ1t* #ΆMt+D#9EӦ}ms^wYA?F0.Pߘt4.d^K)iߤ=KktCykC64m:l^ . :`}ZۡosEҽ3!DoTc=4`}#IWvi3 5i?ٓ`####FFFF0`#F0"0"0"0`D`D`D`####FFFF0~pFiՖ1)k/|f#Q90`~P3W##F0`D`#F0`#F0"0`#FF0`#F0`##F0`D`#F0`#F0`#F0`#F0"0`#F0`#F0`##F0`#F0`#F0"0`bfQ/|0"0"0"0"0`D`D`D`#####FFFFF0"0"0"0"0Qކ*t-!#U]BF0QYIڲBF? \1ڳ^5v0Qٌe‰D8[ #h1JL=9hZ\`T;LZ2gӾI #UtQWҾo` 6J\`䊑DoT |*eiiISG0`D`D`D`D`#####FFFFF0"0"0"0bFFFF0"0"0"0"0F>kY^bfgR[^WV ,R #z\F,rdCiWwh[ Fo67ٰCo߆ӒwF_sb~ɽ,my܇!o6Vx~x(Ѩe?]GiHs>?z8T#ݳ)k?1{+`Lyք#OCdާDnGGoCVA'Mϛ#?m ۃHO/{3Vz2j/^mQ+n*Y/r^Oz .9#oR9Vzkf5~Fi`D/ #FF0b;a#^0b;a#^0jO0Fog5JF.9 F{^54m/_r?],1#hPCD"p4peHG=Pێ#h1JL=Aӊo>@Sq {%lV6E FSk Ϥiߤ}ܶ]k|ЯYj/Y05IIG}88Ps6 #yUZn>P';7|J䩟#H}N7*X[{ZL('NMGZZ"{R"Җݓt8y}5e?92}2z8uǷ;=rg|SF|6/=ݳk+\p.teQcGaI۾x@u-RԎx*VًͭNg;iuy7ST*a{,+RB<~YҽPWQ̜vLFgtuڙ+>P[kqp!ۙ햤Neiۅd#gɟ'홴f 'G 쩴aqۓj1*Ӛ%\._;Ѵ2!L*|63J/ݹg;i.Rv/jwj?^B;&Vi Sp)\#^wz͗:y>PF$'͗#dNVr _eF15G]>3zgk:y>PF{$[WzԔ/c'͗eIɜ)zt|+˨h5d՚#\.Nmjxr9<ŹQRy4)}{۴{^gȜI%a5zֲ+gv3獰-rZsKtuL-.=oevQ_۾NWJ>4l4-n4x$s'cu~M]mz4x_=#KזQ^kp |)籫>_gtd+3+_ TQq`;s~yvǞK?U hSFs_XK<5=ŮguCFr'އ}׷?z;_d Okf۟¨|Ha^{&7ҒdA:^'6'ʵί[oèOPu=KKSp#Qxť. Th˾m6m~4| ӉfV-r'0d^m* QbFetڣs{G$'ϮͿ͜0(F_B>_df֣v_l愹DF0:7\`t؂~ #Fˆ # #zavˆ0b;avFˆ^0uzͣ<0yKe&IENDB`kst-2.0.3/docbook/kst/kst.1000644 001750 001750 00000012711 11544160206 015776 0ustar00synthsynth000000 000000 .\"Generated by db2man.xsl. Don't modify this, modify the source. .de Sh \" Subsection .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Ip \" List item .br .ie \\n(.$>=3 .ne \\$3 .el .ne 3 .IP "\\$1" \\$2 .. .TH "KST COMMAND LINE" 1 "" "" "" .SH NAME kst \- A plotting and data viewing program .SH "SYNOPSIS" .PP The options are: .ad l .hy 0 .HP 4 \fBkst\fR [Qt\-options] [KDE\-options] [options] [\fIfile\fR...] .ad .hy .SH "OPTIONS" .TP \fB[file\&.\&.\&.]\fR A \&.kst file, or one or more data files\&. Supported formats are ASCII columns, BOOMERANG frame files, BLAST dirfile files, and other optionally supported types\&. A \&.kst files stores all options that can be set by other flags\&. The following flags can be used to override the options set in the \&.kst file: \fB\-F datafile\fR, \fB\-n NS\fR, \fB\-s NS\fR, \fB\-f F0\fR, \fB\-a\fR\&. The rest can not be overridden\&. If an override flag is given, it is applied to all vectors in the plot\&. ASCII data from stdin can be plotted by including "stdin" in the list \fB[file\&.\&.\&.]\fR\&. .TP \fB\-y Y\fR The source for the Y axis data\&. For ASCII files, this is the column\&. For binary files, this is the field name\&. To plot multiple curves, this may be specified multiple times\&. The same source file, sample ranges, and X axis data are assumed\&. .TP \fB\-e E\fR Error bars for Y axis data\&. For ASCII file, refer to the column holding the data\&. For binary files use the field name\&. If multiple \fB\-y Y\fR options are given, this may also be used multiple times\&. Individual Y entries are associated in order with multiple E entries\&. .TP \fB\-x X\fR The source for the X axis data\&. For ASCII files, this is the column\&. For readata files, this is the field name\&. If this option is not specified, the row number in the file is used\&. This option can only be given once\&. .TP \fB\-z Z\fR The source for the Z matrix data (which gets displayed as an image)\&. For ASCII files, this is the column containing the z data\&. For other optional formats (HEALPix, FITS image, etc), this is the name of the desired matrix field, as displayed in the matrix dialog\&. Some matrix\-compatible datasources also allow using an alias which is the number of the desired matrix field\&. To plot multiple matrices, this may be specified multiple times\&. .TP \fB\-p P\fR The source for power spectra\&. For ASCII files, this is the column\&. For binary files, this is the field name\&. To plot power spectra of multiple curves, this may be specified multiple times\&. The same source file, sample ranges and fft lengths are used for all Power Spectra requested from the command line\&. .TP \fB\-l P\fR The length of the FFT used in power specra estimation is 2^P\&. .TP \fB\-h H\fR The source for histograms\&. For ASCII files, this is the column\&. For binary files, this is the field name\&. Multiple histograms can be defined from the command line\&. .TP \fB\-m NC\fR Used when multiple curves have been defined\&. Rather than plotting all curves in the same plot, plot each in its own plot, .TP \fB\-f F0\fR The starting frame number (for readdata files) or row (for ASCII files) to read\&. .TP \fB\-n\fR The number of frames (for readdata files) or rows (for ASCII files) to read\&. .TP \fB\-s NS\fR The number of frames or rows to skip each read\&. This is useful when working with very large data files, to speed up response and conserve memory, in the case that the data are slowly varying\&. .TP \fB\-a\fR Used in with the \fB \-s NS\fR: rather than skipping each NS frames, average them\&. This provides a combination of very basic high pass filtering, and memory conservation\&. .TP \fB\-F Datafile\fR Override the file to read the data from for all vectors listed in the \&.kst file\&. Can only be used in conjunction with a kst file\&. .TP \fB\-\-print psfile\fR Rather than displaying the plot, export the image to a postscript file and exit\&. *BUG note: even though no windows are opened on screen, access to the X server is still required\&.* .TP \fB\-\-png pngfile\fR Rather than displaying the plot, export the image to a png file of dimensions 640x480 and exit\&. *BUG note: even though no windows are opened on screen, access to the X server is still required\&.* .SH "COMMAND LINE EXAMPLES" .PP Several examples of typical use follow\&. .IP .PP To plot column 1 a file (tmp\&.dat) of ASCII data: .IP \fB\fBkst \-y 1 tmp\&.dat\fR\fR .IP .PP To plot column 2, 3, and 4 vs\&. column 1 of an ASCII file, in 1 plot: .IP \fB\fBkst \-x 1 \-y 2 \-y 3 \-y 4 tmp\&.dat\fR\fR .IP .PP To plot column 2, 3, and 4 vs\&. column 1 of an ASCII file, in 3 plots, arranged in 1 column: .IP \fB\fBkst \-x 1 \-y 2 \-y 3 \-y 4 \-m 1 tmp\&.dat\fR\fR .IP .PP To plot 500 rows of column 2 of an ASCII file, starting at line 100: .IP \fB\fBkst \-y 2 \-f 100 \-n 500 tmp\&.dat\fR\fR .IP .PP To plot the first 100,000 rows of column 2 of an ASCII file, averaging every 100 rows: .IP \fB\fBkst \-y 2 \-f 0 \-n 100000 \-s 100 \-a tmp\&.dat\fR\fR .IP .PP (Using optional HEALPix Data Source) To plot the first 3 maps in a HEALPix FITS file in a 2x2 grid: .IP \fB\fBkst \-z 1 \-z 2 \-z 3 \-m 2 healpix_example_sm\&.fits\fR\fR .IP .PP (Using optional HEALPix Data Source) To plot a map with a specific field name in a HEALPix FITS file: .IP \fB\fBkst \-z "1 \- TEMPERATURE (Kelvin)" healpix_example_sm\&.fits\fR\fR .SH AUTHORS Rick Chern , Philip Rodrigues . kst-2.0.3/docbook/kst/Screenshot-kst-curvewindow.png000644 001750 001750 00000015537 11544160206 023120 0ustar00synthsynth000000 000000 PNG  IHDRiT]PLTEh O C5"+%   # +6 NX"L0S":X(;["Fl!GrGsFu@w$Jt-Qz.W"PK#Z/l:w?rBr>jJiFgLh\gpba^YWSSVRQSROPMB?:F>*Z=$v8;FW,p7с',JhܞϝƗ۹٭yϩoŠ`sjbzhwp|zv~ÝǝǛƘÄ~mdbcfaZMHHGLEEBAAAAAABIKKKJJJKSRRRSSVYZYZ^aabcckrsㄷ出ꊿݵ̿UDdtRNSJy6 IDATx{PW禤VECU##`YD3Z5JrTĘ-ZъAEL"'r.&7XEw+BS\V1lQŒMs0#4=ՙ;93gVBQgq'˥ezƐ}LfEy;$#Mj{.cJFҪ$ RW/yҪawQJd}2JŖJDjXC$wRb&[#v II/4/W֌{\礖]EiJ馃<$IEtΜ qaV {aaVmې| nkd; sҁjicNZFd HΪ*B򐤝i:iN=k]cods3ȝ)m#>̗Qg[IRTL H+VKs/SnZ$$eIbm*?c+͝ܭddgܛ=cKEywɩѷ)m%I eT+Q_>sf\JNcmR&ϥU YQ~JwRzƐ%rgnr %{8k[ѡSO}Y&׭%I5gTwH{ag.JyIi.ֺƶݪ:oTUY`rWKJF}|t:+SW;ݕiNzw˹"&:RYN#VLs}ge}}U rZٶ[aבedAdlظE#9[r+Ȫ4V$:RrUU*YY.%Fh|Nׅ1dlӼBdd(dv"d@d@d@d@fAT k>Y: .2 * dF ܳq-NLeP\lȄ 䵑'VCÙqkmsrRڱ !_(Mo@1p BW/mm#nײF(.KC-z8C0CI#CQ0(P 5' ` Q\/֨CIj&ﮖpEcoTqaXrJ5ϩs.6*SQqiz O5B&/4X؄C&}sJ>/Pj22*'FZIΓ)QܨQd?#E]ƃGٰ2Dԃ&FY:Nq$E<}s!FYpd <ߊ/E\]$-=$9dzsJG f(#Uo#ǍkYOj-c:2r-0wO`粓>:L=: wylو4ˀl& +|d@d%:5MS34|?SA@d@E5{ #S'ɼI PD%yy&¤("ȶԒ闖sr~ZL!Ck:#f(_,j{ŢdkX|T膸Z` xd b~1yqޏQ/'<Yݐp?wdzS:y{ }b&#kF6->>oBOC!;ZDs_ˆ5քDcaE#Poͭq/y'Ev-c6ӫ4 fSF&'j,&#xޑ 4$(2 2 2Ȁ Ȁ 2ȬVKiPf/TffY:J}w[B6@6KT|~7KEVn=]1Y΀u pŐG,% ~ OC7ש!MjN ۷;yd%FvId /4YA bH- YooNNoοS y0 #K$M3r?#PM䙫) ($ڔᤗ^J+ǫ9=ύ8md#ˉMVSDKEwZB֛7?\ɌK͟$1ѓHߢWv T˵w^co^ƺǗYzzr~_k?gy< 4nl9]dbaXf5A'gR| 1`y:@{z]֮l_"Wlm)^3DbH.׌[k;-z绷Ys%==Ek{Wri_j^o+K߿㥊.QTC&1ʈT0.5krzSk{QF_I^*Zخv{KvHi[xF'ҶovMpwK*}u^qb4bIb@+`8eo^k53OTAw;jzve*f(Lܖ΄DˈyybZ;1h8dvȸ@]4WV}z[}#E$t+ŅrynfFmY"W .ّEd,U=5\Ur1^La&##ƵV,dLIl2^ύ :NU-͝;uv>{ē-zݸ}٨nvc:y;wv *Wߨ99]&,ȝ+  mh>ICLӽcLj2RKeWXw搵k֦hۂr  n/2׶hv.J.Wg۫$Ē2]et?tt#SuEFHe3sKl1꾿p^,cFa6 mvӕd3>/>QlH_XJCн*74L'GIf@,ހsK }Ĩ'@ddIҐ:nٵYӐ/! LaȼWgF5ӘMDF? inW˳Y~ш1VjۏK~׾+o?$y)K{ IjȌtTSܭS\OzSddM! e/C|YH! e/82ė! e_meK{s_MeUlėEI|plK"ˢ+hQጇ2Ǘi5ėEI|~_e2ėEG| e/C|_f 2ė! eUe/C|<"q9@|Y9! @fA@AE jZ$h#eA@dA@d)eG ZZ%Z%Ⱦ3ݩZLAz٘EQ'Hae^̧WZMuFI)L<{*z,BR{`^ouFlEds6/Cb"Zm\Ͱ,JytŐPzlʑ}W6#`cJ5jVcQKՒreĶ+yV< yYH,UM%>#`cJ^FڐE}^yx |./<ʢ Rh3s9Y.W65,IVͳr˓e[7LvKբdQqSŻK.qLhR4KyDlEcgWrȌ)Ye}kլ.A&A3lOj QeJNZIŘE47UKRXGlFT-HՂT-H2dHՂT-Hj%*␪@fA@A@|ۊ_2ė_#C|_9e"ˬ/3'LD|ee&/,L4'LD|USS\&"̚2hFp2L ._f]|9e"ˬ/3'LD|_f2ė! eF2ė! /_Nq/)_@dA@dA@dP k i=jzh) +\o1aƭj:=2Y`Oa5L!rr؃dU&t0NX~A<];i J|y=w8jł%>W ?فq&# ՃؖDS{dZ8Yӗ鋦#b'al=(ZTkn8t/\c6-jԻ0\V1 eʬL|dCjAݢDO/20,dSM v8uѓuA>k~ ^8.B`+B6pG؜XL[:,n_ ,>A{>_o}zJ~V86ltqmQ1EΦbl'm(]7ZA㎲d>uAx+%J|@dhYH"Ė}꓏mdx)r1VWk ҄}i|\Qü|S>hr%Xt?z)weƴt-|Nl7^ȭ*  _F>7GȾ2RF;|}𩋽ros۟wq<{L6";xgJA;y=/m񫋂~޻~m7Gqi SC;Fdy}l1zh߁~s`~WWZ+J݇Gj}l4C}lDedpfJF$LdD3 "ɈN8!Ɉ+?4C^~LF$}7,p&#xzLF$v`M_f Ƿ} JoFd@f7JF#O8Q=b}Zq+ Fk\_}Xh/G?>kpD9$(d@d@d@d@d@dZ LIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-datamode.png000644 001750 001750 00000005104 11544160206 022307 0ustar00synthsynth000000 000000 PNG  IHDRPLTExxxiii^^^UUUDDD'''+bb+(k&IDATxGr:`r)XSTV8Oh&Dn\x# @r)ܜlC 4ps "yENP2A;oA 7 S#E(( t(#V IAMʏM^rq8q?(N= ڵ*XŬ)K8 #AQ,pi %t\wXg8 Am uP!輁ct=nuQ?ؘMCdu:;OT@Wh:,qA Z4S&N|ZAy-$v6O<+|Ỹ`Ez04Ih !tQ] *#P)SHڷI G7}@q;Z{6EN6 oy;Pn T} A -B4/n*ehi}tCȬ4Aہ6 A,8o(ASݧfJ-B 6:^V j*Àh AgбQ AQA-*E}uZY:!(AB AKZr 1':-J |JP7 Z- hPAu 67h²5 V@!%hRJӠBPWcd 0쎠Hc.Lhճ;J1@hŝ{ x!Z@Q _^==JЏ}-Rрq@CRuSм]psl>"1Z4A|:(|>h-Ь M?5Qt2#4;=,P!42^-3t2V_s@I ЄvиҍnPY$6}lz "r$,uʵ\C i/ų+4.@{^(&@cC!:ܸu:O&`.@vAa(A/{CyS݃-c#C^,yntתl'sA'kSA&AGc!@O Q<?@%T@KG@+Ag+5 N a# @1[5>Uߠmpp N{JɷuK=߰-e@ @dG{_8NzKwm&v[ P? c&Agwm"xAA-. :MALACNOeD J~mn6Ayv">NVIT~|!{_.śGK؉ވ܇[ _5x"r/-? DIENDB`kst-2.0.3/docbook/kst/Diagram-kst-array.png000644 001750 001750 00000014205 11544160206 021100 0ustar00synthsynth000000 000000 PNG  IHDR38PLTE˭Ǭ}}}}}}zzvvrrrrvssoooiiibbbYYYSSSIII@@@:::000,,,((($$$  ,x@IDATxkO{/6/@#D@DnG(%[h:픹()ӮJٮYg WM4l՟(j~~4fC:-HLoՓh$^_|q44_7[S솺׸z6U 4X(ʮ;ҫdR2D{4r\1)>V~^vRhOthY*:wVbj.vq2_oOΨ4`ŽʳKQXkR8_k,Of T w 7'Jz51FhJ'9r~eO-@ETnN+oȕkUVR7Sqyݠ4Dp@;D@M4&h)&4 MhBЄ&4 MhBMM4!`qBThBЄ&4 MhBЄ&4S@h"&4D@q5)%44i5ьEdơ-4#1I @32{%4#1G?C32 dUhF&&A324#Dנk45dЌLk d\ͤm: d,uhF&Zh:ރfd2V 4#A321hF&cA32#4#q~fd2fd2ZQֳ) d\dЌLdyhF&5MB32'hF&c~ft2RtءSЌL{tX¡^ctɘaivs*42D5: B4EMcMtnIe,Vk4xOژ,U;]9VOJң%x N3^17VPL3hv1zK1Sޒw+* N /6&gcrxmʔO+͹uoeɝl=Ir\LUs|M֌:43h7&l=5C5hf LS]s$WSlt.t&oƳzD׼+ת;+%nV˧7ɛ.E=xfM]] jˀPƕL&ޮrtF٫Ĵ>HBS yZmJIxK^l4ORgZ!5+w"e+gbg|O.jQ5g5͓`q&w{NurE%JdoL抅f茪\4cqfoɮRNswLU5vZ@ˌyR3V}Jި_Q3V^!Xsѵi9b)4ISs%?%g`>j52kk^ݜ޶|b꣖1i>]LXwO.ۄ&g(MIW5TZ*̶sdzqI5493/'2 ˄2ZTe^8]L mYOwMΌE74^UO4 kIv;O5c+jUNc4A< Nv:^˘4McjѣV['X+0L3+41S3`f0f341kb3aFfY6ƌU&fc}&f_Y$ }h]v;Mnӟ6a+O0(hbU~dlgP+6>K:V:_q=BuoUihK 43Ϛ 436b 43L)6[T3H4Zhi&hBIMzͮNOVP49 j۝f'ASM ` a `Tci?0hqHQM%bGX4;iUMivЪ@S1z@MVJL8 QSU- `M%ӝj*Tk*T9^k *T핸AoUMYUο &gM%̗MVJAjUD._UkvJӽUt& 4زZ/n 4ؤBܪ@S}MV SM%>:8MV!P\[hjGCiת@SP roU;Yi٪@Siժ@So*T] VJ,/VJ<©֪@SժlB5c~ &ypOZSF"W4ŠC:dIhF&cfd2VC3dNC3ltɸO?C32NS@3dyA3l_5hF&ch-cz\h-c\h-CͰe\uf2Rtl?;4CFE٠tHcЌLƁz _G h/2 _}kQx&3dӻЌLƚ43 a]fd2&7hF'^fd2m gH4>t.ДdK%~CS63SHT8Cϟwkt(C{M hΐh~P^" ]OZ Dx5ս 9ߢ 4t?~كeSgV !寧LlcS:Q)RIHHAqX:-HLR)W 1n_N:zPF3GȭM,KȿϘ返Ko~w{YG~n^ϯt\v;ͪFvWَ19VJڭ?iڠ?͝NiUr!0v6# <~p؂g,|-3Չs"w{:Y;  99J'&/f,#)P>K'&'f?-)P>]K'&f-_>J'&f-[>J'&f-Y>]J'&,Υ]kO%)M ;KQ>J C|:NgMgLo-/{/^[^Mi_:40L.Ӷt:h:`ay4]ʧ]״i:Oiit*6N?KP>K Qӡ|ZNkMkL-/}*~[^VMiU:406ӢtZhZ`kڔϋE`X^jMyt^мKiU>/vvX^zM^:40d MV:͚f`YBӪ|KIӄ4KhZOsll %4-˧th`峵t65f[|kNzQsxg.i+_?0n@3JMh"&D@M4t ӒZ-±4f ô4٫#4%%<>iC-KJ(K5> RR~Ҿ*h.)hΞ|^'S:<@*mߒyo,)!Y|HUs|>DP2<>!#잾 ӒJ̚'kRc\)jfPp)yI 2W}ܶD}]"7n۪T"; NU/Y+|cbLo你9M4Є&h", }dc4t_s[*pKCSaB>>1Ue'זi[Jd/[{sݑ,4SeQz9)jgB+78wjWf}L!L=Zj)X1ęvR7/uM)v0r~ZjX1'u}3R:kMSԗne q|KC(,hs룖69FCIN̻=4=,#gLڨe*c!j􆾙{{hzS{HS"=4=d'ɠڃX$fA3JMh"cQIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-zoom.png000644 001750 001750 00000011674 11544160206 021526 0ustar00synthsynth000000 000000 PNG  IHDRBP/PLTEޮ؞ϟαĿؿ۹ޯڪʭĬ֫r˟gp}{zyzpfijkqrpkklkjidca_S|Bs'cA0\E9TJEKHGCCC>>?8:=1!d  >ZK'1&oZ dMZ,9* 1&"řyl!ʻ%៟"~&ZIaBBZ%-eJ8Z-,X > +M]km"$LuV; V݁1ZkKaHD_B\?s`ZkqBVQ7tKb<-B:bF6@ňjWGA~C<2>.!?Ft AF[ _)8T[_iVǃ58cs҅NňzoQxsUrD,RaKP6ŗYN9BA$'a#f!q$7]9>mw,|#*U0%;i? Ϻ0GQ^[΅Lu+~ v*GsB鳠C ŀ>gυ!x͇XFJH-ЙP,ˆvs!%VCQ7CXFg+Ÿt.FsdP&KxHy9& yFFشa!vE;Pl`SBbBM S,4)!1]H 3sZ),px&j!X{@WHF'é̽8;'%p}oƀI( ˞8' G}uN a1^6NR'Ąx.,{`i\'EY#O|U,$wBVRBJ.)EJHJ(L9MAJHJ(L9)!1aJ,xm&.~-hN\O5hW)|e.\k3l!tp"\W0ַK# @d./H#$z|tv -IZ&"teZ燗!#?8GL8T唿jGE[grގm=Z(:lp(7 {33S) i5^#T3 ᴐRX1=&&VJJXcK̿͘iT0o9H8CS\TD z!"N/2 rHA =M)(?.QQ}F EBJ OPBJFV[ pthMK aMe/_@C3.2G QFx. ;DzLx%B;KEI҆R0BxI7]"'LJxLkOa18fPOol=E'%} a 1uiP?I/.v[+z383df(4>Dx6l4˻F[7 LFSSӁ& ~0ƇM6d{rF.4߄_ Ljl_jط l^\4/s.ݦ=`/pTO6%y | q3`9S5G)J L A.*      # + . 9 EA#;(*52//2/1212.24 =>?B>C 3O'`%s $,?S#S|!It It!Is"Hs&Hr$Gq!?^!=Y$=Z,<\7B]PQWYXYZZZ[X[WVf4b$ZY XYT =&k.w3o;s:w;z>wGzN{MTMKLJF9?AAAAA@ABIJJJJJJKQRRSSTXY[[[ZZZWaaccbdioprz|팿덡ֆ|ěĜƠɯʳغeNtRNSn#IDATx}LTgǻKEekk.aPnJKKYܪ(Jtc4QɦĈ mAwJ6vU6fgxyI9/sއ8x9sp`^v`/vU~-Tz]_`E^uD^0EFUs$5` qO9rTS=F0ks5F4zeڸ? OXk(AEB0BNozOg't>B(*;娰&&=Q)ceYP6 Kt@2MXtDY)+TN ehV5Ԯ|6)klC,PDȯsh,r:;HƩ\GYOw=**'V*ae_:a̯ZGF` Gݝl.q8Hn}EZ/?dQlNrG`T+"C#^q&)A_f[l8˟ u`Oوtd;XQprTX!_Ys-<A6A/R2>8 fHkf%A0Fϟ$sMMsLN aMJ0q 1ɰ aC`9E-h*5%&ov]+SvͶ>KbʊZnJ9RQ=`/&sQR"}E9O~')5)$;$ `DˊDcN=JrG`/^yO`]Xa[>&64Dksp_㍓[lcѩ`28);S+Kˋʏiڏ,~H]IskQS!LzeEɓ$b諬Y]35D]]EE #<תR'OeXk(Z,zEϳJ**NW>]^~xYEEpv%V4S8D3++SY&`_pѤ֞Sa`NU9ZAs nx> Q0  J@[wHeރv1Lg 'eLd\P> QVF~w$KxsKV:NYXW:5wx>`9]>. dH>!BXehkD)1;…JW\G-ܛ~ s_L+ﷺE+6T ٌaB̓A/MBq,߽`>n5 |oll {KM OXmib.yFWf^Ϣ&yRGdinM>Uo ^qz8k>6R0T ~{'ZKX b4x. K|ÉyJL˥eBVU/ K?޶L5M涺\gĴGdwyy_7O7{,j;|`AYVm088`3m(kvBD{S}H5MXϚv>4Gd齷/WWo ^q\^Kvj=qFG3k%-Q< !>Xͩ 6ZPǫf^M-]c8"MQ6l muݷNھ-U{Mcp#ifvYNڧ^0L7MY/m4CDnXw4J['nɕ["uX!-z.O;b&YNZx?`b.iZf뿷(/OZ&g8"MτՂIWGkf)[ gl=7t[WllfX%z_4d{6e{e>F{}Bq5n^KU_]Qp'OZ&g8"M3J~Me*^ie5#C"ݲ}Nb^s7|ۤabY{mg5faJņqDa+? av _[,qծc:N\56WcZD 3ņw'r 3 :L^NfY@uJK{<{K4?:l3#+UbDjض0PBt s9`4Gd-FezX||bXVψ;`}TVgz}/ȑ+rX3 թ9.Ox`9`BɪTzm"-NB8w#?9|Z0W3N.N{䔯"7$ZLjɑ˗ G1v;nQXinnir7!qG0!uoǷggւ_*-9Pq>蕴y"-yVN傫ȐF0'\!U>}^`r Ĵ!]dɇ'IHJJdK{eKF>z 8G Ӌ4֒]GG =6B[;B:[#Ç;#X?~5c K{ddxdd]l\yOH$z~] S 6zpM﨟򠷾x!m%$G%sA4uH#Kr?'}T:Ue6U,gg. 619qrϞɹ2`l%َGE\ /+!(fs`~ Dhy!,16[[|}h^y{ӺId0E0lϛB#^*ϻWHޒzjzO=-i!-\B򏇈`4xLw+.v^UWX!LtabO}0XZ7lhI0wetrRè_=BF0a#:rXst5Bfm0<Ӧ@xj]>^4b.X WB*XIR*DO~mG_Z`io2qGi/, b*X_iM_)?W_5lQEnݖU ,䪪WD]g:]I +ԧUp\*L7fUeiSshjjos &ɻZT#g`x]TzLS57>6>6ivk[ůVEl|Dk [Ll:1o_#Z\*moB_oowoSU^N5 &Geb%~RٹTM}"O~7t:5L6}7)E 挠I@ 2њ3GT.y-s~5Eɱ6jq"`T?z$R  k󌞩n%u5vw7V:1o"]Cg Xr8p85$Rh!L0Q0f?N)9Zq,ӥ -E.G$Nn{g&KERHI0ھyLB"OL4KO%X 6D2g\`m>:&2Yz<ʔa ]aT`Eӆ0>q+dYE084D*(oxr` r}"HQmfڋ*᫯ڿ_;:X5<2sv~6kB7 ЌzxbK IQD`K/Z27_h;#jj_{ XhlqRE0'a0by`؁[L`yLtHs`,^|M*qѡ^p1  - (eg3ySL{T?LMLMN6~pС}Wͷ:XӜEb?/آGƿ<i#lhJ1j`@K~J`dI2F*2Q[- DUi,+m sHbXrau"3LN&HKq0UCw8%x}*!%G`["a)L0tLUKc23Ԯ}W:[7GYn~X4}`W:<#Ê_\C (92j/zY,MUG0I&ɒE ,?bhM$jUulkjE01L~5QpISi8WL5`)RK#m庄@̪Hzqa,_Le~HL`ʹ˂y#_wJKfѤ\`m0U-yxƩi/*XZnvS~`mVҾojl:_妟o]1`b D~ZEcf,PO%  m">`exЋMY;VgյaW C"jQR`)9^4`;ϲI8|1N]s F2ߛK-T V/x464_iavvywZ0w}~&79L S^V~M1LzV,\$u͒Ed5LhCч,J>xHzk?.3T;rwM[gfnUlX̡B^O%qȩIIg5@_ETsj*RǢ|1էKνF@2jT.MLTWF7ɗHJmyfj>piiq>F-T0VC OS\v«˯ʴa6(RJK&D0?` V[p/R_iTZG[}MugæL֋G0*T+oI)d?fOh#X 'E/WH15L#6>J]R]절6~i"<~o>/ Ǝ~Y-NS㣣uDz9-_[T==VL ++//`G`t3ڋ%H_v `g.]N}f?a,m6IJP86,)B|%V!]xPmSZ2L8P"qfX? o7iiho֫-oV ƷUg[F07`-RY_`|h EX[íLMNַXgTWuF^dY}uE;)$UcFmLrb|mi+8&?cg.E0!}Ҏ˽HӑA0KhMжB?W+A#؀G~sE [U^G I homL2hX_{U#אcf,?D,^.}e%K,2F0V ul J%a|Uzs8ՓlxCSfLĪWۋLU"ypu .EOϖiD}ťK.c fL+53ᖯ;wAwwDLA05D10"<^Z0/)Nf+/{exuw;CW̐s^yz8?N¹<]¹ޖ>B]G ^$~m\'qA0YG.߰H 0ô+[400$ fB00s!A0 &SVLܘ d5pO_`8hup6"mlsd4A?Ys$ Yώ`9 ` @0`x\D"@  @0` @0 `A0 @Dn T  ` @03\ X4#؇I-O,* HzB2 Ek Ƒt*< k Uczh(M`hxK2 @0 `A0  N D0*@0 `  ` @0{ D0*@0 `  `,J 0` x#C,"7H` @0 ` h݆ v;l``Ks `3.ؚɻoSeDp)N-+1lSZ"{PE"Xڍ#l` @0 `@0)yoFbkƁ@8A0`A0  @0 x:y0`U$`@0< Wf_l0 `   @P%q`U$`'_i c v)D0*@0 `,a=zFc<*2veFLRr6A00-o$$Nl6  mu+ު\OH c1KyR?U%ᄏ)ʕ. qxb {(ثi=w7*U0D0ڭJ[BqM l&h=^$vD l, Q0|f`q-@0``kI\ Ji`6 $6Dz<"r XEB""X:{ˀ`&RM]M HP0zhx =];` @0`@Dn T  ` @0`Q`v`::`"`@0`  @0"l#I Gf l)G^zfVUtYV-+1nCT^$msG){Bfa C`h ` @0` @"  @0 ` @x\L=ߥEi   F`A0  @0 x뀈@" O0< `x[E/I+7 H0キ|+Nl6 [OH y>Hr˂RZVbL+ i=A hQ+#l``S @0 `A0 Xx!hFlM5(&f`` m0^$`@0  @0 x6nD0nEU$ýA?<ep8g#u+{S0B؂ @0%_e[l*zȶqؕ1h5vFZ]H0+l}MEd`*yM!gm%ň˞pgSKml݊l wΞ8ngv#,F>U ۮ8f64gmbdUdmU$-mO(&6rfw1FXv\Q4/m]%ӫam")3L @0`ֈf=˸$>Xy͘`[H|7ϙ`3&ؚ/8Fou`3'Xb"[AHH6iȇ`h0߶0P`  @0`) ;'.UWJ--,K` A0` =%lWr[i)n68^;e"&R{57[i)U6JCN?.`{U2ҒB)?`Q)pWjMӆJOM[~QXE$ĥmW,KZLH{E`Éy4t 40]6{9~,X[/J ", n.JfDŤM,:`=DHYAA`bT+ u_Ah` %}U`y7ܷ`m= qTUd"k:%ձ6W0K?[ޗV5yv) mhm䧞.u />"ԪF N\p)n%#WkK?`)4`x &jٌ1cYb=qټH~vM,S0_Hf` A0`OW0.~m_[ ``v |h‹vK*fIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-simpledata.png000644 001750 001750 00000023216 11544160206 022660 0ustar00synthsynth000000 000000 PNG  IHDR2 biPLTE _;4%&,{Px)~\ºgsixr}y~~ƨǫƮȵ˼̿мλЯٞ掬~tgO ܁xր7_~ˣӯմ坯{hTD|5 s ZK  )=GW_p\[]gXQLQYKQ[IPYHNX.,q&9p4.w {D E{Nǻ7ZUU]]jv۽]>U̫W/ KJ##^|NH<2yy!qIeO Kθ A6d=-^cъE#!gsfkdb8Q K'Fɱkbe}^E,Xj5M;YW4d~?03/\5=i7g׬Y]ӯ7qXu bWO淥~uQZ( oDOĞs~͚5o55?ɈkV=VR4_B4b8="H^, tX5㛵5J V^n~"ɾֽj3b.Pq!\%C\~#ʠѮhGL&Xya] ë-lKBĮ XM-+y^ݫ| ђB/Ī|ymuQ%Q5:$ԣ=j^T_4Grj:.\, l# H%iVIiЯ5?P7},^nJL3T.bJ9j@KG5SyT8q4{(sx4~e.#+/J ]ie3-]#cH VVq~Y*/dJ/+NKqE?ӥ, vJ[;bwZ#WҞ8cKx>5%q.?KK'@-!qH{C,!1 b b A,!%%bF_,i[\u-DӕnU> oK۶rmVֵ*ZYpmgY7b*ܽ~PKBfTlSW|틉=nC,rٗ&Y'mKQ}uٖ+ix]CD4kR8 PTX4::c=b=?ʬ߅rRcE#~bm{/\VqxxR$=>(."}Ķ˟&r9XMw@~c}ǦMki_QA?H !X#I,z<73уTx\5VX e=b#B} Sh*hL]\lᇈF"65XBKKȮ=NHbAbsq, dbDliߞL迵Fk]^Fe"/Zkop?;tf}uȑ#]o.#b-7VmWknj-9\Y\m V4M`B|csCΟJRmM-sPZ5=9yXCG*2G|K6Wes-W?VQwꋲ]lO'[֯jZ+א6v# K`BOF~YZzQk9.UW̫/:zZUkE׳tE~'O>.a[%~7SeiW?1y,XaF+>%g:*WȮ[u;w;\VoӬ5Zbkk|аY\5ׁb drقjqqQ}.eQ̩/4X)l-xZX_t&VkE~C˱NmZ?^>{ڽA֭[kdo/^LMvUYخĨGۥZ%}iZ&V|ARqU?U:jUZsV5gk]l5L^;>YXMD^~%~5VbNX=t5Z[[vت[+r?\ߩs{boLA3}"޿Sig=8W2>qsbb͛mSc??Y__8jrdVqu`W5ZWk뭱4mm͛m1uP&(fs~5Wމ{T༇Qvu[{)+&Ǩy ^zunn͉)Zi%KSS/Xzcؙ_|Vn Ufc{\dbʂ$+1d&V:[Qkvwfql2M[m7>ndiaEL-bR^ubmPhk_QgؚXېʵ#{jrr!ÇsjϮ'ž+ԇoS>sZffFVɃ[ϑ܍7dffn/+ /˯Fw #2|9_dWݭ6}bQzUuQZ# iڪoؕ+c7 9&7Y[ek56 r./]/m].d{].=b|!jՒU-ʘ;44#!LɛhđSɉɉgJ;1NLL~{{5dq3XqzzrS~cm{Cf [[5P޿/lOUYXMG%jJlϺUk1{kc{ iշ}Tln׌ʪhcqRWY^._G'+a6zFYŞ)s\CƳ񹹹EQG^t =3x3Lq?D~w#;3Ϝjڈ=e懮Zo ^_^Pb &G _lV3QiUH4#룦bկܭs-[ VjU>z]z]~rŶuM.V5 $ؠM>bV=IQXfjz߹Ycn5nzj|iʵ?zs_ϞTr=fJel4};3PVsDoo|k~%penHfM1Iؕ/Gs_wt|j>[b{:/2B۷-/,[d}~$jc]d} d^H]]*T3g?Yya[|SMQcoڜ֜j{F_{rʕmLc{ٿƾP5vSc :IMfXg͹kLXX{ScUv+TvؑW^5vyY8ŊeG 5VlBٲ/Y߹Yck׮\~}]jfǾ(N횕Fffd譱N?|83gP3ZbGS ^[-*{( :g#63ZDZ"+pb(ƱEryZ.v^au>H삕~bUUEFI{*u2jkYdؠWc;,߷ƾ~MB.ئ ,Nv?|/W^t>|]ϵT@v[cSj5@@w@͟]F+k< -k>{6XE]+K Q<*(˨d=/5jetAb_Pꊒ[l-f([bƱIP ]U^umg/Ư^՟'+G]EͰjv<W5잿  q_c3hSȺkǮ%1 fkշj= sg^W W~be̺Q'Xר@oշgQ j+h魃ƱӯnIzyI9sz${?^x#]:rSco[XkR>Y󫱷G{W'{w޽pE':t4c w|uNJk*۷Pof+{Zof֫WY!=b!8W )X- UG-VcW_fW:Y(]5Vzy۬OUҦ,~xKtɨWj'O]/.{'P\{ey#sOzj]*-mtn alF |6_(UTW}FT rG5[;%`T`[&`Fkժo&mwuL.׼jY%qlV+:[lQ-HUu:Yc3z}1k6:hou.㮱ZmoS ^y\G{ǘme֏,>WXboN߯|ybQn55uP~]a@׉|.Rg'3Ӫ 's/oY+F?︂~QVe1US0iNj%ݙudU} Z^)akmۇnǶqJWO~cj|뾇Nzk8vKJ d%yBK Y^G,A,dIx%qBK YކXPEEĒhչwL,dX"Fl(5mX3%FvBq+@,bʚ Kvx/# $}XXȒ0b b!Kۿ%, o" $}XXȒldB% Q,dXXۚd5dѨElF,bIz D Kߟm YnC~%q,`ϼϘ+` FϼA,!%% 4}bG#6`ECtb#")lX?bXĒcؘE,A,bI\~wK$KH#Zb GKKb A,@|>=y)L9~}9n"vsq"vsOη%SE~2>EElb!? Qw7ºRB 61ΩoXpҵ}B 6b8-V8]Elj^ XZ.b*V/Kٳ {(#6X>:.k=֓n"6ʣnؠĦO5]FBl68cOi+M}FP[d2bS:b=E"6hGD,A&:X6DlrD7b1O]8k]=3s9;^g pŞ=!qɗW/ OX,`IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-imagewindow.png000644 001750 001750 00000017056 11544160206 023054 0ustar00synthsynth000000 000000 PNG  IHDRAAAABIJJJKMQRRSUYZ[[^chr|낶爻obadXAsGkJiFg4_&R!M|!M{!Kz!Fn >a8U-B*0,-HFEUTRf`^zyżĽž:tRNS`IDATx_h׽5ZB(75咴8޸Ԩ)Gd]Ejز[[A`dpJмSD`.~rЧBP_`a93;;3Wo̜Ϟ3gg~lmQq_?z ultmjF~r\u{BTC#YClA ӫBЈ֒؂^}bz=2m+P18#[+(ދ M^oSMLKKN'#*%n0xwlS&h4uL?u"I9s=>C}q#8k99v_7"בh%jD ,}-LM?nݚ y0W1%kw@LbjR@/3K3M:R!>4^71fn4?`:%17iM:~C7f 8Xo5cquM?ZŠ;s! [Px&RT;tS>pez ]7وܡ'R4uZޭ(Ab z o8}DDȵ:#8pb 21 \F[Аb:QLG L0AL0AL0ALpajP{w0:_:C9ӷ 0+[{Qֺ Tvm"&L0Exh0`*JKM'!F A9&= &BYrb#wiI+}ZƸbʖI104f*&SjL#0ec"SZASDDڢ h@`X֦ 6JDYvDԦhX;ߛ&% Sr{{kJqS{z֎`iuX:&7SHߛ웧b]bb)-S jŋx݈Lhm- BX1 Ih& * * q*Sl@Z`N.g5zA#kTX$q?mܔR1u7S.N1 3}J (IYa"HLi; /Dw1A 4 $0{S_0C ]1EyBEݼcn]2JE]7{QrLe qv6ߝ6zLP]:;KfgC82;;՛@aL0L0LP^LJ&jBNO{9(`& & rSWQs%ۘ.^oF^`iP0Y?C~gawjV_࿔+&凁4L'`xݟ JVFm )Yf5zb.8Ivl==^_1*G_t]M0AL00LT::LQYƻr]j?j)aCuθX?qX˙ww#=yzŴ~i}[1Re+#cŖ~3M迌0}Y L1Ru &U1w^LqL̶ Lf{aƱ22SäG:&)6=GDeU~$_Vc*tDĞnT%o6Ϝdw(I|'>S`3Fuv3dIm#> IY[nϜdwM*Z22a*7!<zXs_a)ҺDLx'0L0LL0A ;A cr0AL0ALzXgnrLVSLL0XGdz}(]\YQu3[)u`%"uf:,TScҡ g&P7yȻd{#j_BT.-\sōgc! 4]T0嘇8ޓS=S@fsQuü7L9&`* LL0A9ikLӭ?AP9&O ֺw: gR/)kML7]))b^1#' A$1=)S'~[6!ъ/"9Z a :Lo_n1Emd.NL|ʊ0%Ů0-G"r "K򠔘jL[.4%秵 2Ӽ /|oI6=Ӧ114LC[Yyė7_Im.1e1D+nt#./)]ª\d"tEȢs'ͥ.݈Cz Ϙ,@R!&mQ4k|lg]yL:m71AR!&L<\4ݺ)2Õ[`LML.v)A\,VwE-`&`ڣz'dAl>L}$)Lḇr.=9aQ'ԧTm_4 0I2\WzY  cΟWivT&e6@ǥ 9ߵ)IbwHƴ6Lߛ%>,0TfIVMcv]^GpdS7>iWFâ~0=i`)m ލJ*|fA4rq6D>{ɜѢ+L=[֓]$[KXyVJ`" 1 L)˚S`DMh`Q6LZ 촫0>A>S1''4So6 LYeM)o>OH&'q'LD,ZS:"&^$&%Cfg]'mYW񰨧EzqL+[8y0i cb]zBzPJja\qe Xβ(d d0ZqL%b8JMA%&voݵQJwdd`*~*¡M4Ӟ|LLT[׌i l! &` &` ~av90Y[oo{%E OV` c '1Y4U$PgXl%0 #+,0uĽH$Kol^eɊ)]¦v,QزAS>cY`jOkԩ64zAƲ`zaŤPĝFcY`j;B/2zzjm"Fak=@i$^OƲdt@b&R;zd/4;x & & &`&` `t\t)0A &` &`y%0-qjY3ʁ |?YlƔ,^4,O~NYe( /^|XJ&^0RE Kn" q~T\EH'V'SgLﳍ &U&-BKcxBn` tL8Vܛ@0:)B<=YoemtLJGiXE*Fqs5Vb ΁G3p3ؓ^x*-/PZ' I|oٚ:&qO=\|e n)byĻ|V̾$3^|r "|QLH& & A aR3)=)M*43qTM%Ӆ'%^܅4q 'ILϴ2TL `Z)Ai;}9Sdݣmsm+7@00g)GL̂J"ur[B&\LRKEx L>FC4@3$;b cKynb1%I5sP5Lub[A6̣'ȴ YL#>~Uޒ H#P4>dZ揾ͤR5bb>II.D#gԾ글)e/úH9Vc2tIF]-Ĥ>$r2r *Ǥ L`L Ucbт˅0}*gAlMVi iXK*3db'sU)̧cRO 9)㵴V39͘:dX01Fe߀fQfN "1f0V0힜f^}j s'[P{:9$P~Z]ŤL@].&Ӓ !rzclkcJ4L]\SߛA^4v&9J"qS4:rDN%.-LLyهX1$mfl{jj^gZ} !dh<_c+vL( ek۬پ2rWS+sq'2pKýSLB7T'ۭKx^9t%3=߯h^ywk1x LCQ-ES` 1 `&`rӻ:ߠ\a߻!:/BL?SGAs[[~V ŷ[<-3LtSF|JL6~ZYpl6 v"[y%D7y4}g/7 ug7_Ů3_)ozbzlׇ||ʛn1}!5 >[8U{/ob%|TT]Fk!kRnILk~~[է뼲=^l󷡢Tl\E^|R U׾ťUM 1Z~G܁-`rڵ/("cعV{绪[]{wWڕ^]U#Wv6Y5Yjgő'/jF&Yvyո X|EiwBHe5U_A=_uP=qk5q躕aemUUp{}hu[\W,narhڽmB薅eyX;xma}x;=ܣ [ , d{q8Bq$[tz ZWhanhM CC8+>{ֻT<|[{',>#D?Ze|֘ڬUޢ(ts1tĖm֓+,7sXf&, aK rB0_, _Ba<>ݳ },WaϽ{Iy25:'K<&{ȟ{c\%>ysysy.WzWNJq[՗ e(/1[cO oga-+y]޽% ޗ>v2V#ߓoVɥҢ^d|H1Ŗˬ @b?o_d˥#w;W%J+6r>9R%?s,QjxgVxPL½mF㚹\/:ӷF[8Z exq`듖0+^:GD#Z&~\ "Ie k-xy#wM'"[}@K~>f_O.B| / GL#tsϭ3:˕>۞ 3޽S:'߄~BNé-hإ񭭅oOS>D_,k^xx \O[GW/N"v$nU,` JCi4w4h(=T_-EtJPRJ>JSu}zF{WTi~׶~88]DiG*(KiNApINT7H ȐMCi(m12cSܰ'*)f%ACe<pT m}AQ*4 AyU5?<'6^vb%oR YJA[+M^:w#T8@*~o=ud-c{U=˫(gys_&[[ӟ84;DvSg:Gti™_uڕqqG<st~^#`R}JћB+¾JQyUN?NJ{>j땂#;x tBcW:(M4W/irm{i4yU/08~ϒބBw/=LǘwXP:&/.oZ`#)kҶR=mӗcR'6^ ֟߯YÖKa(ݰ_cj`$Wt?٦=umv9+AvE7(>EV= (^մϵ#Ol)řc߁v`WMNxdٟ_iwRaxl(Oa)7zPҼǐysMM?Rv%RXBQ$ߨ(i(Jw<\7BJ㷇ޔ$THCiPJJ( 4PJTz49Sܤ 9SV`^p@i@i4P@i4P( Ʒb@MSJ;1V>Z pA>d;kت:ak*dUJCi( 4JCi.*8m9.( [鑶^ʟ.OmM%V*T nQ|UW/JPJL^aTR\nQkJTUiX QQe=t҆m|=yC N+JRqJPOb)G"m`,ne*kPKBWjPѕ5pyMS]LgehRe,<ºl[PSP+݂)(][uVYiALJoiX$i: ] (K'l%| (*S3(jw<&)-_^a{jt"IN vfҵGFi+- *QrXx$uP,Ht5ttw Fm\BQ)F BFxSF - !߮z +]#SzT (]j J5P^&PЕwtYN}LH~]T{V Ӯ|AI{ٳҥLm'YfvtLՙ՝+/l% 8o|xۏ-GH3'klvM"kgv2?S^7K/?w>O$%g_s[٥}444Ity&׹3ثZS@$$i:yΎLphUm[=FŔ^.ڂ[Iׯ9[P&ι.88ڣlKhee%쏬k{m<'{}q>Z5zhq"S %ޤ,MCDu[k5ғHJ^AJ61ްQ;һeZ|oU QKff ONh؁cړYu1u${o5l&Е{]򭓷&ctj9c)KfY䕓's.|Ys;N׍尶X\FvlF⊹ꮌcX/MmJ$Qn2i5D֔>| +=FGg= $)mcL*8-vە>.z̪4Oe%c&OXғ~]~dr#B!9#d6O3nO ONrkeKalRNط=Tڼk;̦mQ#_:HW= ^/JjZγf[NuI=VS6o.-TK1e,% g?d)~joVڪ0GlrV踶Qqsz0#+.m)FalͿaVb~uҺ{Ie3XgtZUz*#E&A~ ~/t+mJ,k8QP ڭH5J૖m2h7X^?u]_`ޭ*}Jqr_uް(s,Y] 2jd؆z 6 GVšqVb`ɫ(],x4R<;wm%f*Tr&%$o\ʫ4*GuQ}憦thw~INkKee~ǃ+Җ/PbvM|mw(oAiPsJQ-F` >/PPna!n,1c+:p1{u2PC=l{cT*1,mcb?;88cCM=dcYZ 7yPV{H60RQc$%'ڔú{8({+0O;=wdt(M뤕>l4ZKP}*M.[CQKX^';)4 ΕPzVW?E)MӖPҹkvsKl*.}J[f"tk?x+WgyݍtJoU/-㏓n1iX=[^K+-N[Vb}t]{LfyҖjm4H;Z:S|;FfoҰrWSe#-V_Jgv)v7gҰ + 4PJCi( 4PJ(͕vT( k@iLKiL KCJCi( 4PJ( PJCi( 4PJ!( 40( JCi4xàt* j(]}PE~7s2}4@AB@EJKKKLWSSSWVY[_bcis~!PtRNS=3IDATxoG'<6?$!@e/pUV(7+Y8&0tEի&_NjQyt[ |OS6M!%ˌH]S&`fIӗb`[\\d\QbS[&[ٽ? 2kx|zw)r1i>Li[0"Xda2i;f72¨"~zlFj6s713e{6j1y`!O=@b ~fjjm[~~ f25eqbY@L ؿNBٙ6 J2q`FAII0 5Dן5CAIG0 CAAPj{ HeyH0`B?6J}l@Z.s?=_٠ޅꮞ\'oviUG]{~8xAzA#kӅX J"2wmGZи?1\M~xSUD;}2cD 3ӟ>,gƲ.i:y6_zc c0V?^{*6poʘ:΢{PDsR^7+~LZus~ˤ/PY +VH3!.`7?-1Jg.5>4Kv(q9 lo /^0n< 9{'u)]\Tr|W$=w: ̯{ソ듶:$֭^{9T1KΩ=f kK8}xza+%GWi03VHdj :0늤>&3iu?`Yxu\/?D]zlA}U ?b"oj9iwEC;;n;gzaJӚ>W+l-r$̊[Nm#amɪyvU:,OTww;wHmS4bY_("ZnI|W$=t.s{O!Es;%?uE^QDߒe*OVb$"+   `( PPR0|DEɓ2hėrd.`Cm8nQzr=0Bj^Eji0v WGʩE>omt̋?-~ig_,D˿?@[okm;~j%ܱcBz%RZIsG:VVWVVVWW;ͺchmm4„ mj83W$6f,`yL'4ԾU߽ۀuvv]Fmhknl<`kՑȹ%6~JR:幈{SVHW0|xI[[=T-`=ymQ=&꣄Q?BKQKX8b},e!ԥHY)ㄆ w6`{,_i` Lڢի1js{+V`؎<9g/`-=Z)oSk6I3ՒTL~[[kvמ=%z=Tf*L(g" m]eث2xC90@b0d)SfTf"qBC{?rHǞG ^_{4XsTv629gul1@uʪG>]Z--JJ`O c/'Z>n~$Oأ;~i"MT1n_"YnBómr 2Le$ldh6h3P#/Ca>Ofk8m\ eLCM)_K^OfiW{`}1jc)tܾ=}~~kDȞϽp7.q)R7A[+]&%%N C&87)t-:|7[>ׅno-bhG„n6k# 3@ ̋jڇ01iYq(C2/'!C#ܽr&e")_Z  9rn?3߁H =+uL>z50^x$qV}-=k0C7:/m+pv%OE؞ۇaC7fM^̜X߀Pc#u&:CuUX'1GO31jr 𚡢[ 9.;u{[嫉+崃SXdMR¤H 9S7,.M.k`=Rs/QNE7]j38&[n_VW`#mذ=_n} X#k ;Vh| Ac&O5xI"l8 &fmc4Ў`B(B{?: q{>ؒlUQy ";;o^޻wy0ӡ _߼qmk kK iS`B-a]}u͐ykgz(a{{:v{ȡ}=5jA`45as isZh} oRu0ڙ3gC޾^F ` C^T|0ƞI-Pj;s^&ț){yKXH띓/ߺ1g5V]COϟ_^/{M$do6yv\ a2$5|tÆ=l~lOQGK J,߾9{g"Fȥô9Df Z m~F7;x'B2`ċ5,VH."}3jmVd7nqL_\θ|DRuU"nuZ#TQtjpZH{4 f{//~Kwoٌdii)W=Bz J: h`=`c[)e[c%T,ZZwdin9lWQXRμ> ֣F(K{5{"vL`Aֽ޻m䛀k99lXUVJmAO4<0sK/N~wkZm{$T{`%6?g?Y>gzd}/9zƘDkN0a(65mPG$y㈀ܻ)6x0ڒf\C\-rrje5Ztw>u駩}K<`n׺W_`/&hP\mx=8~&?`F.?s#G{q~cyҰ#.&rtt"(`0<Ͱ0g=nK4p}":8nW-v-RڒoFk(mxp\+y XnNM/_~7ޤL. r=.^kkO4J f&Wr>GWm?Wdltl]І l./<>8?; V~ `̇fL`a>#VZ2EqXs:14MzaanJzaH; Xy#Z]3O/ݲVZkiQ?Pb`~%*2S4{,li^Zϓ0H1Q{+ ߌ\i7&/h-Gwۯ*j̺ w_&";<,8LXg-T%ԽJ7Avm>GFN<3sZ6ELGɛa"0DPPg %$,] U, %iaYFPP^EP0O CI0V9-;y'+}6730$Bj(xțD).`N g#(8 P1Ĺ `fyyM&r›hq'\ J HN?9Ce)4/ Mb9x՟,{`2 Fbׄ>U'OΫ?.["`Mds@8& >N<:K,/q7]ͅN~׍EI\ Ғ "(( I0+~/M_dE$?Ly.B&K'9_nbr; )9`&, `ރ4`&=D|M@Ňy˼hEQYFAbUfXzLSUAWRbD /D˟+8?)W+:}$ɺ$!*u-M0y&V`Z5 Rڱj"Eb(R@si2LS1,BJ;9@. 5'*J =2(VGi)0J/`Zri9LK0c<L`)`Z  H`1k0 X"C*m@_siU3A P-:, x,jvV `Z(`ZvE`ZӲL`,pz@ DƃL+:`1,f ,E1El(`D POi "J[ UZc{ŀiL+`@bW% `i_1`< 3L0ҲLK )`0+ }ai0,iZV#Z%X蜀XEDrX2LCX#Z+#g_LJAjEb!`5K 0ӲLK0Y1XK@:Es>Ӫ`a+2FpQӀiLK0-`Q–ƀs, IGXV@7V`2XH@ `QӒ\FQHUKfD+L5p/S 2`Z4 H2}Dw(-<KN~D"`qY+)VgwGѲ,sHFR0X3`i?R3p5Hu#T0R4+`ћ)HЀ$30>`H1}S54X^A$uT#9,n" `,5#e9<>y5#Ih #X)`u)$``%[ Ld>LkE KyFrX"%OE 0RS G*0 #5A,$lM 4XFPq/(^X4JT`ћ)KFH,{HـCXlFHųL+h(. `DI07 z JwZ雀T) 000c) )I ap"~FZB,D3v4#U*#~C8hFMǽ>F2>*@Aό{%`n (YP`@d]"(3PhuM|e|hgTy-ҟ!yrb0QQPL6`vGTV}0`(( I 0R `(9\H #۫ J 7(`ṣ3Y,LJ 򐡹ѣXيN!`X 9\]6S `( ZL^?m'c-z 0$D .fN+ [ I>=a r\-NO˙s8) 0"8LF069 F!w]{w&pރ!` ;6X `( dzDPҩ USZRN$!-a(1$0 ]Gw]v9C{}V{sbP`"B!<e&B,3X47v!s1 5v Fq|0a˫TIz0CQ XM@&HH}\Md)8;DZ`0q$@'A{ΎRTג#֥`WJénQ5 pM\zPw`EJT PÙ!` TEK L$@3J=!'C$KZ=0@D #lkfu6S `6Sd\iFdN V `@0,]  0 CjCa#``}0UAX_#⅀U䃡>XTp B6PC|0$8dSQ&A=4SFE0(`e\M]L^  RT:0fC+SN>`SZ>`?A ;Llv.NNc:Pn$3JҾ'`@vN^D> .`@$Ifb,7< a*qa}0W<%9pEϪY3۸%'r`.ܷ=go--wA>EsS/M@11Q=,tc(sH?/JE*fN0UBu¸#.|ZoW$ v|ONtn@Xvā |Ϛ .|l޾|)i!-T^{onF8u > 0H#dC;xFp4Ȼ% o P#@: $u;!)|]`G|O2s4E׍CR`)J|`XuC +*x!`LDC`X>QN@G@&+#`X$'u9'_[cޝL LFowl@P0 CW>#S0*Ŀ+ fb!0U&AUT:/um  , .1C$JQwB!<&Bg,!cCX47v!s12v  Fp%B&&NQ*"|*㓀 \;*XHDm"X$'DL$t/8OQ XZq `hgP Zq[&ea?0e$Yb/\(?KE^AJXNA2|TϒF* ӄXl3,  FI5](`ak*#`XE>X/k@4T|D *mG'`jn,oD0a3Eq\V/7%`a=dA V s"`>X1|H@'$ͧ 0B4` W >G`em0`P!`-U;a3E &{+˾nM$Ty]+(k rX(@PP*qQ* 뀂Uɝ/`̪Z4<l0>Trx|b,]0D)6`Y-DU0pkTTۋ1^bi&b"`,`V`ҡy6Di@C0:`SQڪ?l|ܮ<F%w* R *T}V1 bk9RB֘ 0(06`ho sB,_5`$9@V-0ksg:- )J\9`S&`v dN"6P Yܨ8CEB5S]T'VJ#e' VQ*h*%6X _j. 0pQ` Ge}T pE`MxXt8`-~@ B=/)`PUoe/a»~|` [z5 0F&ze X]/>?Z=f Fj^ A[#Hp@= |60 XnhLzX(*O,mN~`?f^k&(cM!G;nHFQF9`|e X"ìet "zoeHmP8p"` YcxC Psj x[]̧X)RB`꒯M_Q&4u D),udw?5 AFe `k Dt۠ qѢ[Z]L,!F2hQ)`-| YEKQ=ptHڔE*D`8at o,oR qVyaQ\|iarJ$O^01`"B&FZ` :Ă (3\( >;s ^_kωE@#LUAuT z7  p|WVO?q\YD[E$W*[9>xS;%N4YB(s^Vj0RlD` X$p1Xz<`°@-M-\NW"B (*1n['㜑Nz,ĀRݚ0|&(R1`i7dѢφ& {WS Ldj`P,sa 3ʹ'?`iA"?" &ZW 0Y*u+ΰ;"7^WJ-7TXuPru uҹN3:G+ BM@ XsU|O##Ie&2ަ0`V'C C V'v0TCAP0,_煟2;x'n]qzg!!B[}>dNg3gVo?`$  ^qAaQ|l+ 0,YrpX`_} %ayu% %a|9"  `(Uw(Q*zNlwUs C0 CP0 C +6|zHw;Y8_>>nk;Xp!i{w1}]x=ʒ3m;FamkpV {צ FA:CuEqĉcں"`(?I>|=1 z=|PuÖm?Om6[k8*QŦ`X P8|5G ]zu}N}'O|<+?`j~`v_^7q 8ܩ;go*gvi:䃁{ B V4 f:h0}[2';<`:mZ]yLo³47_ɧvPxP\C?<|0o+Ρ]S5wrmuqM{?|=V0XSӺYsu.+m{̡G`u$teK~92!Xȹ;:E"`!` `XugT[CAIC0 ;, JJrsB>GAIM~U$JIENDB`kst-2.0.3/docbook/kst/commontasks-chapter.docbook000644 001750 001750 00000022106 11544160206 022436 0ustar00synthsynth000000 000000 Common Tasks This chapter contains instructions for performing basic tasks with &kst;. It runs through the method for performing each task in the simplest way. Links to the sections of the handbook with more in-depth information are also given. Plotting Simple Graphs How to plot a simple points-on-a-grid graph The first thing you'll want to do with &kst; is probably to plot a simple graph. Here's the procedure: Choose your data file. &kst; will read many types of data file, the simplest being a plain text (ASCII) file with the data in columns. For definiteness, we'll use the data file from , with the filename simpledata.dat. Open &kst;. You are presented with the QuickStart dialog: The QuickStart dialog The QuickStart dialog Click on Data Wizard, and, in the wizard that appears, select your data file using the Open File button: . The Next page is where you select which data to use. Column 2 in the data file contains the y-axis values, so tick the box next to 2 in the Field/Column list on the left-hand side. The INDEX field is a special field created by &kst;, but we won't be using it for this example. Under Plot Types, leave the default XY as it is, but change the X axis vector to 1. On the next page, we'll just change one thing: under Curve Style, select Points only to draw just the data points, and not lines joining them. Click on Finish and you're done! The new plot appears in the main &kst; window. Curve Fitting &kst; also provides functions for many different types of curve fitting: linear, quadratic, sinusoidal, and more. As an example, we'll do a simple polynomial fit to the curve we plotted previously, in . With the plot done, open the plugins dialog from DataNew Plugin . The Plot selection combo box contains all the &kst; fitting plugins, and more. Since the example data here are quadratic, we'll use the Fit polynomial plugin. Select the X Array and Y Array vectors for the fit – if you used the default names when producing the plot, select V0-1 for the X Array and V1-2 for the Y Array. As it happens, the Order of the polynomial is set to 2 by default, which is what we want. You can set the Order to any integer, one of the predefined scalar quantities, or some statistical value based on one of the available vectors (for example, V1-2-Mean). Hit OK to generate the values. That's all we need to do to generate the values, so now we need to look at the output of the fitting process. Select DataView Fit Results from the menus, and the fit values are shown in the dialog which appears: the coefficients for x^2, x^1 and x^0 (the constant), along with the chi-squared value and the covariances between the coefficients. The curve generated by the fitting is not automatically superimposed on the data points. To do this, use the New Curve dialog by selecting DataNew Curve... . For the X axis vector, select V0-1 (if you've been using the automatically generated names), and for the Y axis vector, choose P1-kstfit_polynomial_unweighted-Y Fitted. Click on OK once you've set any other options that you want. The curve is plotted in its own window: for this example, we don't want that, so delete the new plot by right-clicking on it and choosing Delete in the popup menu that appears. Now, to add the curve fit to the data plot, open the Plot dialog from PlotsEdit Plot... . On the Content tab that appears, the vector containing the fit data is shown under Available objects. Select this vector, and add it to the Displayed objects list by clicking on the left arrow button. Click on Apply Edits, and then Close, and you're finished. Plotting a Power Spectrum &kst; makes plotting power spectra extremely easy. There are two ways to do this: with the Data Wizard, or by creating a power spectrum from an existing vector. Power spectra with the Data Wizard This is almost the same as plotting a simple graph. Here are the full instructions: Open the Data Wizard and select your data file using the Open File button: . The Next page is where you select which data to plot the power spectrum of. Column 2 in the data file contains the y-axis values, so tick the box next to 2 in the Field/Column list on the left-hand side. Under Plot Types, select Power spectrum. There are also some options specifying how the power spectrum is calculated, which we'll leave as defaults in this example. On the Next page, the options specific to a power spectrum are found under Power Spectrum Axis Mode. The x and y axes can both be made logarithmic here. Click on Finish and you're done! The new plot appears in the main &kst; window. Power Spectra from an existing plot Using the simpledata.dat example from , we can do the following to produce its power spectrum: Open the Power Spectrum dialog from DataNew Power Spectrum.... From the Data vector combo box, choose the vector representing your data. In our simpledata.dat example, the required vector is called V1-2. Click on OK and the power spectrum is displayed in a new plot. Using &kst; from the Command Line The command line switches to perform the tasks above kst-2.0.3/docbook/kst/Diagram-kst-datatypes.png000644 001750 001750 00000022753 11544160206 021767 0ustar00synthsynth000000 000000 PNG  IHDR}PLTEᴴ̻ĹŸĵ~~}}zz~xx|uu{ss}sszrr{qq{nnuiimffheefddfaad__baacmgh{{Əyyvvttssqqnnkkhhggeeccaa__^^\\[[ZZYYYYXXXXXXXXXXUUPPOO_SUWVWSSTOORMMOIIJFFGEEFDDDAAA@@A??A??@<:&̞^' ĀQA<^F]d5Pt%7*|+K+FF:[s0]*:wyğI}҈e5c538+lğ~4u#5qrrPF-aD&M'f=g#"4G)q)lsbBO"Vt_S"'#OO\N OORJQ@&'"V%9tz'lH)qZݻyd|+:#%9ɁR __NzKw)J3Cק>j.x+*#%9Nw٥x݈ m5#_x'ٸݭ[ߋ>w̷%x+ҥPOg<\>Kmn]x}#JzZCy}*.s.t+cҥ@#WؿZbh.Ľ[ƤKb,{Ō!Xh O]]HlH$d޸*V^۰< ؐtIaG46-LiD0NAb#%w^b̳ȯkHl@dpI>M~xtP3qU`$1M h& Aٚ$tpbHe`}E-txbSW[z֧Kf.!b%3n5Dې.B .\nqRvK3]ؖtb`R!enb{%VN۔.FsmC']iĐ SvГ:AlWd1b%3n۔ Hl_d&1+rb%S!tNVۙ.Kzևt\bHaqZb{%NR'kML'^~,C_d)ĐJb%9?epĶKCUvo#?] 92b %K!96i9utS2`od1 5Đ4NS.YD dkE5tKڈԿeĔKU#jf95ĴKZ-P zEIBjR' I>_]\ ZV|bz% FpWFjG7!Na {oSa> lE0bϚ|bz% $I@K?&7%d)$AR8-Ԥ8ּ뱃m~NLQx#aDo8qC018ooPFr<*iJ4 Tko?v(qiL/`o{XbTKZ[_ .!ٛvWe%dc7l&%3 7h+` e.1]⪆bcqI~v5C v4T\Զ~ĔKZَ=LoپfӖ.i!=yE\m}#f&1m&#vwEL$.]2XEr 70tb!;iK/2fӘ.C 3)9M"2]`WjKb:%ۈA3t6bXlmS)M#c[5 3iMl$N|=׮ ԦK6Cμne[.M$(hii81钽ą[hb%{au2tfb`>\mI`b%ۉϵ!0tnblC)Ol'H;ĴK\oN/j 1Đ qK4UdmCgtɾ)M9XY%.n5_LtZc]ˋ<ĴzS'J)a5n,*wm*Db)fԩ@y%mo~'WaU98 KL5VXM4=T0,10[/u*P\MmH #zɣ MzYxXz:鈟Vo~:Qy> #d Dl}װJVx(l^KߞP<*soτNO< #\ yA5U<`S/vQLqƞޑ.=(K쓺[HL*|rUK (d$v&q2;8%d$X?Q?#1#16H}[JS0izQuzd/} }LjӇ~S?CK̎n7yedztx|Ghi8CP}x|P]U.&Ib]uul6}߾&.!K!)8 b:ƿš 㛲FĮǂ㫀%8tʐq`2O]bʄg\{Ut$#KH&aod )M =I< ^HOISUC118$|;!{U UHWlǞixp7`8jXoNÙo-/ 87cQ#j$FbMA%dC-&~}&7 bCmqQoeh,Bh'Z'~UߐY^BY{1;2N,x7NI\pY"oTc+#n*#.^^2Tc[φw*6zx9]o$+#. q#`7>ةޥ0ξHX(c5R[%A6Ŝڤi*#D%Ĵ7ծ<ЍDຕ 2*HLYj"{m`g G{faZ5GqA% xbfB,(#\uw}PJvEf;. ߁IK_[ g6Fz-R oGfbG7<Oy3׋9q[Ev7.J}iYpo~#IL*3ϵ_<{Yoؠ9;8 ߲Gbɛ?sZ]WDbcr3<.٘eP _aԲL!y@$6 V\W,:cg+I5oY^F9em^JO,zbM %e{@$֕+}>ey@$֓+ygeJҤ*H=h毯4~Y k,"\3?ڷ,ʯ", Lb [`Db4SL\$x 5- 6ԆkUqTH6n i/XOLB_ig]Tb&qǾM'vTv UJ6m#6a$ӆ8HL 惃iM t) c⵷A #n;h}%N5a JW^盟@3jF< "s=m~nĦ6a3x`ͦ6a+iH0q- zsǧ #Xߧ 't?Eo`i]mqKZmG [N|; m٬r8;}$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fb$Fbsąv! /<;XFb #1EdTxG{D|&|`xH4i˭aa`$Fo|D),\-)zI1FGQD숈R<+sb*<_c|۸#LھNi奃׳dXdl(?Q? <g4gqS8QMaF-KnVpw;pbw}Sb8qKĮ@{=:Rf+#W%Pϕ־/4oy9{/X)& , KC/1lj? jc1f!Nz0%${.J+#r+x+)FroR^'22/lxc㨋=# z22K:-~0qo=ƽ[*m7Zꉷm[T1W$>߼5W~kXC 1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1] / x5gbͿKw+l)F#1c 1c 1c 1c 1c 1c 1c 1c 1c 1c 1c 1c 1c 1c 1c 1c 1c 1E_Hٛ׊u3~/BbGO7,7kQ6>bg׺2"2= G,xg7v1G!'qț5ÈO,n8dG &D;qdlt#mV]f&#B f*7~@1qԺA,#۵nf>¬Gvm;fn{qYhOtGچz)]Ȯd?6 4H6&~]GhnBn.X[˜juSݚnJ&f,BK..F۫ڒ&7~yl.bjuS4MnJFY#p G]B41r =M|]=I&u ;*HePo%|O|{b:LcMծ-4OZFv #~eDT:=dp VJ%&û.E3w`)C!VTIMq2'bio'{_ 𡕍abtNBTn gå8?@?A>F;U!=Y&>Z+>[+;j#8! 6 2/ -'       (0> N[#q+ |  W~ "8Zozу{Цnɜ[ŊK{=v)dTZUSrU6[XYZZZ[Z[ZX`TRhEMq5Lv&Kv!Hs Hr Hs ItHm?n?q=qRG䣋 N0&)Pʵ sؿ$6 Ȩr]W^*`f# V!*kIFm~A`{!*AҹUU՗ʐO3W|ӫ\ڒERʞ*[;Fْ "$L~P^W1O>S<ܫ },mt-`$Z*oR"H%쁐q]z"!j~I?~ݟNʧ٩_>sNN=hrW-`//4QJ 1_II7r_sVE& *$edX)~[ xQ%LK&x&=P>%qyINM|NxϋN^}|^-//[Ο/PI}.Ih")C6xs jAv^%Jԝ~3,;7I]V*i `WiqjJ X|SS0N% AdI+'IZx*IdN9PVRqw\gTqz1Rf_Ų\|`Մ $ǏԤ̒)(! ߜ!*+PEOo";.x3/Jz>Xe=/VB64Dk 񠪛u2QbaJO/( ) tޣQoNUg^]ԫ*-T`WFu/!Nf)KHLHH(+MLHL,)I,- J+JJhR3hƊW$$҄2LܫJ#{Bv:OUX]༌M'2wXg)޽—u. qش+A3*QKޚjEk-޿ne=GAw="c0 iUEC6UJقmBsx(O7ż-氉޼s< (ne:ŇonlaO+V:|ms2uU &P/v;#]׋G>? 6(_ZƉi`fQr=柶 gAVP'jV^=|Ʀ 03Sc\c鮻;ڡ&;+GmuZ'}J"rC!c-⶟ʳ|ҽQ^ɹ,U1)gdk+fEK ; wQsq孶*B9y/N9vq\ R;G+Nwx~^d -<; gLΥX4hhQ1i7Lw=(|zZ5?SFab<K~n/Rr2=n:vQ]Ds(Ln^%bмKlgދr)+4[`P9&-7?-}~MɏV͹0=`&A #t7*[p/%b88` A `0 A [h6UAQAfAa+S?5%D+S~t'rĩ(^XmzkxGWw{zzETy3rKoQ 9dɡR%v j|)`4gEt+10,71bXVʟ"1'$`_WT7F'JKR W+Ҧ b(&9>ٓ쮤@RɚTv} -d_BvYK^Ztqt/gTi'3i%7n*f3[+c;:3G9q}W[ssƨoX5`55gou45TF3 ~3ŠB`𸤔+$P&e, bZB.kih^Kdgg{\vlɒ%Y0`?x6O8V͠pKZZZr&''6vZg0 ` #>{M՝Q9g21|r :$IR6UC>U,eg.Qg+eʗ.83ʗa`趔ƔuE>95ilHqq[>4lr7cr[XޡCW=ϟʷp~-z>3Izkn_^Kk];;999[`C%X0Lu+I.ds7,LkJr 0l˓Ml Ybp06RkIJʺzK/={au.N&-7EbQ~v025uP??1B)`Skξ^qv6`5xudNvc )a/Zf$LG父$b6;+Y!lY6Uy^_zkX_,KIIDЋlK1. OvHyd`S>$L[uS{뭷8n 4 葦}5t[4WPzi"ߑw4.u"c0C#H (^fDi|lDZ6Uvg{{>]Xkz4qr0JXA[A/~s1 0-=1Zcc#c##v'ɿFF-b1I-a@mLrZc0zգ|]s޽zQW_r;;--5uJ&L,m|aDQPaٓ>''wrտRkGS͵+}rmԭX5F]J FMb0RR=^$u#&~is똮N$Uwo\o\Es;s>H ݭf63M{Hq&FHS@R}^ZBoގ[ =1i{HGRɍEy,Y@9`.Xc6]*X M݇01iڕ3k"?;[pr*شAiƔjh/͂|uޮ<3&NfiZZnM}l]W_}uWW|{c--E?Hߣlb{ggO{}&_q~%RG6±I@#Fƛkꨅ2:VVSc'SDNb0Bݙl>];CMDN0(|A`>a| `+eQ|Ym1L^`P`XLi0m 6Yd0e8z{NI! '1bd4I,`O8IGV Ca ` 00h&t("6`HA A ` ` $ap0(:z94W/q H}0/^  >=f(KXxE p&)X_X\'l"@&^6)-3;H!E P`e 4e/p0"NX^_|P`ГE}0/^  >=f/q A\—@|bPl(H/^  =fƾ/q A\`A3`_  xa' & /q Ab{͌}0/^ x=Ƿ|x0tI?n|0E8^0]'c{n1/" }0 /.^ ]GŬ}05+غ c0uo\X BW~=lJEр6!p-[`;m r0a 9Cl/x0 A1^0L}xJH—~l Mng _l_p0gl?Kb0#"Ob/=}0(`k:+"6`D¾` AX왤 f'`1|"_,vb{83G ah/L^M= ` 00(N 'lI8B `; 26V5l`+mr !l`}TXM/rKĆ B6E*A0c1k\`h3H\8{EGDl\ =Yga#3lקp0^$ X 0̦} b600&x"`|^ Xv!%`/܂i,: zM$n"Bf1` ``Y [ :$ը9Eg_{WĀM`ᵎ+b/8z%xU#-٤#l !ܼtprlMl7OOɓjj1"2̫wr*y7tLp9Z\/#4^BbZ,y`0n͜޶* ^(")3LA `̂Xc_K~}.ƍ`Ql,MN52 &yE*`lSn`Q444,xΕe]AQ+q AO0_pdǭ Ni _p¿S 0`sËEq(SI8/C(^P{ۅnr>4ſ:'斋bwbju]:Z`p`tyT:2^ō-ͪU}!Q)Ka мNQy>cC%{R&(},ˍ~!n-J筢XxS%Gȧ̬:KC Ϋ&%++e3[Hɤ.zLP[%>gkBwllDc`RR,+;TH/~Oۅdz6yu0Vk Oxu UVⴉ%}zgqO ѢfAZ2(fY5#H:,N|:b<ڙɂ/hXHWo~jՋTve/O9SL0:JGB~06B54M6Nzx404OZ `SZ` 2*wh9oCFe^$` 0 >qۀ|Ay#g?QZRIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-curveoptions.png000644 001750 001750 00000013555 11544160206 023302 0ustar00synthsynth000000 000000 PNG  IHDR1e!PLTEþż&%&026%Eh!Kz$O|GT^QVT^`_~<(IDATxMkG_@` 6AdDB:8`< ^2qBnFZ-ð,}c㱥,PɒbL%gޫz{5Mt3O5PԘxA̅DV'J n/r|qr\xAt #sXd,-.tuQ\ԊD-.Q~+HJSw @,  [ Zo@Sͽio (pgSRYa|#wpR[ Ex$7 U1G fo@,e;B2 ]9@fMp#2@b|H Ė7 / < HmK]o@b"mM $"y9iqfQ- H ( (hh /drR_ 6&b5H7 $q%o@( p+"ހFOV!͏l) b!<ˊ@*0o@xPހ:("%ʔC4T @o (X8Ղ nvպ-@p )`PыAYjǏLf y+ Ԣ[B]Z{߇e  %$yD* @A9_QhA@ @@F[sO;, G#܃ÊD~-~+asy_$cH- D2iv5͊u"DnW D@8D`mfB&(Q+ -JdPe4L 0@%mNle[/ @$w~ͰYd:6D1-I(GlcD  vVz@z@FYH?D.:B~+@d^@h H, :;#' Blg[ 3ԩhIb<*2@{yT #䷒ ]UhuRWZdީ?̣ SY  @hH}7Hm7HM Ejj G Yןvt`z^r8H@Z68 ˣ`ZO; 3pGpxω.\_8\K'EGdOW=O \E=D. BH.]aq٪P K6Ts Q@2nCZxtOGft{x[ l7x<(!&@k3 qXrO/1LzRs]dz:<66#,w&iaW$hHk" OcWYb!D8m/({glxzތ DF@q-E߇^̥=n tX489|p"ܩ82v.<LJaekУ$,a}lO{ݑTDo Gjh{xA@ []oϠ1~ *^8즤oF+cJzl!k $3^8N>xLtTȡQY@ 1;mXO::er;}MwaԌQ2FՌ@;dմ%tXLBSea xD^nLoW- l2uăR"3zQ* f%Vӷ!n5&r3iRF9YQ{q꛱ʊҵD& 4h@x N$DU& nLZ2KVjK %bi)ڐY҆v@ 1TY҅|@ִ@6č!jZGnvw^kDuezYTkzYnŃ!1qUdZI!'(>u߇Sqd̷ـlpjN߇} m@F\GgN)w*x> @ @*1[.+n=\  D;u lvݵj;mHuT'NiGt6%1| ՛i7q@7v8d+3$rc'"I#?W6Dbfid?7b! oT [:Qj+HvSf ,@@ @ @^C _נr%[ȏC%D~*Wrm|KQ?} *S?KO)O~mPut-Putx  Kq @nם@Sfl^ $<..قR,8 ,yrxdj ;)ԡ:׼k)|#Qq@w߽r_8#KV|%G6܁_!$p'>>H=4.Ǎ?}ҝBf9*>.ǍkkC Q"ZoM;O,GE ?$` SlԌLzԌ ~0r O3#HXa o![2$'jcCE~?}ȧL76aƣbA3htn 4<t/Q$M)!@&Akr6![tmup FT~U19ytڥˢE#BѸ$=Y|娎"+Ѹ\>~I:eQ}wT 6)RBsx >`+.Hv0c<0Etq;w.sAVSA/>Cg&R 8d+IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-tutorial-gyro-multiple.png000644 001750 001750 00000046230 11544160206 025210 0ustar00synthsynth000000 000000 PNG  IHDRM+bPLTE9׮ԟ݃HFɄ亅}جwˠnȒT" ˤ #xCn~¯߫в¾ÿۢڞڀd֑ԏҋυʀ}{wsnlj~c~_{\wXuPoSnVlHeCcDcEeFfGh2_a+Z=ZG^CX9S&Z4J{MYtorkkkfff^c^\]\[\[ZZZWXWTTTQRQQjQMNMF[FEEE0Bi*q|L 0s%ST`8~ۼLL&H‘!Z.SgwOjӳfv4=3o~R!dh,K+Pz2ԭitwݰy?vk߂@˸s /nmnFi׬Ya-[mѝc#;=]c;TI{qN8/]m/.oy`:]Mbqyٺu^KߺH{~Bw@k ڏ):i+Ih,}+Et{8."ֿD 5Y~{YNc[נS'5#oItX TVG Fsk*bnM/Ez9Rq8~F/ҥE7k$X]'moDBL_:F.[4rD4:Dŭhk+EzFItE4}e+ᕟ~l9y׿ֹ>x5z1h¢hФ'z'è!v)ҳp'3Vw<2oM8dx / w٤qm_3i4mVBe}Uu^>mM>A=M~߱p>mX=Ϟ>9~_zyiqstwOgq8]|qX]-M~.>to`QՂSdq٤MR?y9ߡ:<~_L}gNˉd{-/+$Ir %G^ye!H'q8ƯZ)x[gś/p-3߹lbjhm}~\tHߺK\ٝOzsk89;:}vvӂW]׉q9^|~GS']mvXDϦH߶Ko[:ѹsysgΝ;?Kw=ictaM}Hv9{=[4śe,xʼnWaQ¨rJ!SUxCxū겜2Rnorz%ů` 2Ry(p]XVe꼜e9el>Ab1] P]t { @A @A @4޷'d)],}j4)&Va *isVUz5dXt;'3 8DĔ{gڝ_'p& bQQPg@:Hҫ?nB{Mlܻe([*d&IT>2g}]>IH&ۛEbmހt mYd..ޱDְ);Db|3\wZ5Cвğ9SZ)&hX~lyH6Ƽm>=?p`(2@u;C+D[ɉܣ2c۳n+H=8'A:kJf)ֵ9voZewڷ'NJA[92OG#;i3Z۵if"k}e$˵Gvoe6rh8ilq~, VH[1ǮBKYH/ζy|XOAz7`Y8!hyl/ZtbE)ϏgG6ۊYý;{.',=>e:V;VecaV[1Ǯ V+V:2>JbEވvĖ]BU;Nev؝?D-&weH6bM;=-&D{=p3>IfW1{[9cbßːbx)+H\|"1 ^MM݂lڄu1fU8KDbBubwlb'Riۗ&gݾ}27 ؾ1'4] u~@"NmЎӉX+F޽Cq+=L}$\v2_:CV'j gVeP]HY&ɵF<۵yth3Bj_|ȑ B7Q9@[c9O $_X)iJtz9.\φ_VrzY?{оn?sFx55*O1@ϙ-G:i2ap…Iit'DϮ~Ϧ19 Ii7(Xi} ',qfBz`tI"'A#R]G#?:"Vћ_vDyײ|'"ȱ͵r4Kxg"}bD6L5gێഥbkLVJ }j.-󺻻*lZ\rE/`G~HC?ۍVn,Ңl˴7qLu1pVx#ɨ SEv)XG~f3)&߼%9.8|̂as$iT@:V6Ҍ/r^HtַH @7[D?~ƒSzdH;z֬3:4dyE#k|}W?""GOͳpHSl$>4 cɑrsT8j}Ij;hdH[ *wJʴ͛29@8#iH+*C L >WXJKSg̚s˭ Cx r [tum#7ahB&[?l*EzI߮]j"M0ML r/y忨z :&@wtԯ FH"L~:Ӈ_CI{VU4E-t6"l+MR_Dɭ׮]LpNE&Dc1& >-I4q+l +G-3b<4H]QC$my򿛻DI=q8F(tTQ L-`&HT\ .J:HT iM+}x$8,E}i3Um?_Y@:Laή 5>)>h#>x[7w~gő0<#}"ӔZG0(Gza[LK8Z8f44ɑ(tGyHǞȑS=w$A/)D_#M$WL2@a/Mx 0HKNR[o;~it²Iѣ$H\k]ӓ2-̙$ -ӼH?tE<:#WG;GHLxxdLj 7ns4eῩ;-3m-8p#?zK[z<9bA&#jW6҃XeV)--vF$û.:jn}Ҙ˗>dNA|SDzZsSFܷ籞&cގ5)`o6 ޯ Ռ]|k筴tﲘ>zǶ#Nhy.ԯXh VZ^3-:}v)ѵBC_Rf %wC/ݹO/~->jR7S>I񰏔:!]/mL*`&6yCKԇ8=s5Ķ֭ywUϊ"$Fl MH .[vϣcw_ Dwʟq#M /222B%QE| ;5FZ.q(FF&-q@mR9H.iJsT""_]5BND;cD+_XGF˷E{=* 4>i-"Kټ xo+LxK{ISDO{$sG6j/b!dKw2ԏّ<}32H'vؼi֭]{{|`RXcFf'kuG0bxJ\?/ƹY4) Z dr$b>#%GMK~i|vtD ֚]UdlHcg<Ԟ*\;>~n+[`*t隣Kʕ+hRi'K;h@)!^gV}, y%RF-6)h irEtG ,0^ i ?V4Ky?=kr)CեdP&"bKDs8N$_LΡ|n6 k_̗AKҠi   LM HNJN]iP(iA4H  \ A @A @A4H@4H@4ii     @A#}{HcHKi     A @R$*`w* &CZ N3֕A H[^$a2ޏxS2D_#.JFl0׌ $Px5/K_\ޏ"s2Llan>v1kD (=ܾD;AH\ NxE*!F PRt1ySF϶ *E6ʒUy.ۘ"+.;˥HB.@b'f)HWXPӨd )*.jtVq=UX`2* R3T57b-я 9E|<UJRJkKW\⁡t&]i!ҕd,NIW!Eqg!E'+-ť0]C)OVzL+B:* +ӕݥ%]H8HCNX ;HC+.uVbӡ":]aEzj^j! 1Q ɚJR:^z2+dK- ߡқ!]P\FBeSŐNct)+=Op2]U:fYMj@V4 i Hw)v49JtS t(ӥikӘH+KWR cqKK&YGiܐHOK s<8uZ5QOVV/]}NQ7(S)]Np\jATMQ ҷƳ ?1QJU"=844t((HHW:&\S&CZGLJ_~g<_2i uH+ۖt'@xzR)PVQX?]К&%HCs'7i: g: ͌\ȗ.&Ko5KHcZ/RK=UQЩa-/5xj!EtAq}2G qHitC{.ExEi:jxtZ\)*d[ iuz mȹWr}jtzYYF:M'hj6N<= MCr+]/'kxj<m~Q+z+/jMFa@;5Fqb2ӀtCSRNi@i4gY(mXR+]/=wZ\~W@x tà:TE5'WZEC']Ч<"U\mB.K &3nvoEQS+^kZdZ\$_ܤѥ6J" )i7j-cu5Tj $tJQ@'Me!6&Eڷnȍui(`—9ʑB!@H@Sik|oYz#QqY(ϓ=' (&$D KsnQQ#Qtys!c 2ԗ @ztq+Ϡ9x:d(BDM\&ΉDWghƶ`jH=/K`<4i>5qH'cN2dνC++iynV 5ҳNDܦMfG|$jⲐV'kNr^Q_I3D Gz>^f4n5H (ˈGy9QTgȎGy45-ɶRCfS Ώ߲G .+yDQ!;Jd38 j$@H@4H7HC ~Ds|+D?qs^(%@ΐFXHً'zf6Hңy6\($@ސޘt~$"Wg2? mzz8i2iHc/\i=hG|1{V4#v>]~b}M%}&_i] i] i]W^ҺZ#͇;uKgTЧi,<7onls#- iOIObV{g65K3Ri̚@ݑ\^Q`Tgp~to>.(+z1 ] Y 0򐖧3I=4Vi]( i?tUHˈ^R0+CZ|P -\41&îi %*ƘD/lAv۩e=iᵚҘg`p|o4-t1qHè#-#0zHEu_;Bn=0Wu7lu>YzeHKU;}yyҺ3g؞o_OKBXE1L~":U!}Fd:w^Q炕iH:?7j!]mF>/GYHUݗu7+ooXV4;"KN_H/C˃?H(Ҍc?S ҘJ$|ӭU!Ҝ3y B:i 4{i iq"]n:ǣ0Ŧ%芐.duP{]>"]8SgH9XiZBGHF;wKtҾXM/H{?"<*H U>a ;4w*CZ/i^mhKq"];4 ?in^ck!*>Pұ_ֽCRuH rH랔ruUHs}(Ɖi]̥E+>r1_i {x[ Ҿנo?ȍ.0^"zmKFZA!DZ41C:54+ג 9YHs1ʑeC7ttCtי.ltNN{q?j\jŷEU \D+xIƋ;! ơDHFxKWs3!-ݣspshki]=w(:d*p!\2I>xoX a~N-v(Hs0U?|4/JQ ekA _22{[ XTպo.>q$q/EH;qH3bn)RT4ƀt al4q]"]`őÉ4i6 r֕"]̥bJ4Lc#MlRu֥\X,ⷞ+ӽ *PcG_/P ?s >aҹHc#BXx}әޒ3ƎCbH녑ƀ4 17+y1tI^i_݁!-N5jH^jO_2ֽH3Eu, aғ|~c44תh*MsӥUMori&}"/SDOxőƁ#YKi H X43.neXi #ːii̞"]O1/KEӻ)>H vL 4g06VR}1%ځ~쒑f;AH뀴iq퐮`Ңrǘ2ǖkٮjʞT4^ٚ"]Fx2Wc:/Ni=H#M( 0&invxivAc͌/-i@{;G"qDdL|:C&BʀF~"]%HW7v2JWVH7 i\EGzrCε<W !'C׽"gJȓ.U@tIV w ]^tzMj> R[lG\bXmtJ!@KAEU`Ҟ?CgQFF lTtmdnlC6לl=v 7\*-OkKBZ>N>PJ HuxxFۋ_21S!FgO:mHY 4EZU:Lz @F=e'#SM HutɎ抨vcM#>%r)ҐKJ@9W4  @zH[w`Wa|C ܒDA\V:OB3伉fRCA M_yށ^5>5qYH+Γ o"i#mMncAZDI\Fkrky@#~Ůwм$A'jٔYfnX:NthZw9n :i+vlfx8ȹ1b#inxi6Ab~h8JoWĠyPI#~Ůeb(jP@HO&0ޑE DtWAi+v X*fbڨ.EAl¹iUYi+vNmo -x ҕ\p4 ]HxҀ'D5ҵA*_vtXk\44H XiwH4իvtkWGiP="V ^wHXiP]ZBwH¾hhF5XiwH6 + W_Ѷ^dҠEA?Nie3cya A`iP(4 _K &ս^Ze+ _+NH \+ _+LH VZ+M/ft iiP LGx-:q<O*fBҠőfF/ATC' MyiP" (XiԱҞ05 >tn?TV05 i@u<SӀJ{}B;`jPMLSӸH4zҸp?խa3GuҠ8]44( V}Vj_ДB`2TGѳ9`AE}int+ .*nRonXiPtqnK!a-c%*4gǣ0襖x{i J@ǣi3ӝy {󰄩iFiJҗ.4z<ʺҠ8~\24(VSӀJ{w4;`jP -;;`jP}8H~xw4 iNąfMJwF+o@B]k𥽃;&Ʈ"aZku8Hk%J 6Vei 3C65GlW]!%^=.@n$ZHkHu s*P'C)\h==$UiCfW.oHdpBڎ. 6=,Ks4nј"d8}C߇a\4Rqa#i-dHciHҭUXDͶ1h~²ߙ͚kzs7ui 2w4@pdVrÁ49Қxeo-BJ}q@ZcVaHc2;̪@C9ڋ\$MjqѸgKZ  ;מҔši ;i]w¤ɒ/Hk'襱l&uXV)%0Hx86%9J#05v]5_Lxk%]ߎ=k].̽\5<H[j\]LӸ0x1+c%({&59Ia1! `KB) R#4g[lScWLxĮʭ󖺣fl[걎asrI`[;,3"qNief=T=B[M=.sˎf4)i^_rcA,iy 1ŃӮgwqk&ʶғ̅zi~'f<(M㞾vIhb1qH˻۲U"=>5ӞkM޼GϳZγm7;\-56_ғ~Jo 93_Izߏ"fnsߎ;ziKSӒlK"t z|w)R,v9HIaMľBQiy1jI#]tX,B_x8LjKmHKZgl i%x?5hJIMN:uHɐּHK& [iUXNO&sO}GDM\pCy2?>CgvV4D 4}Ln=>瞢, Q[ItD5i1Qx Q!{D5i1[2(#Q<ٟQ!3;2dP^C8 PHiFiaۏz.Obch0n H ~<{Dt1ՌF:Cz4;F;\($@ސޘt~$Lb< ]wH?|mƉL+ ]HF釳N"PFt"=?;.{[CD&ҳJ/$C)4΍>~EFݭYp=iMY7@u.i!^4i|AbP¥ƅ@ȡED:RA!mHi@HҠ>QX H*B2"HJd m~sUi#McHt WO"}.4ßt WnҠ F|8o[-zlܾjVM8Kd HBz]]cO7$c{cNVD}6bO-U o׃OӚEsm7'<U41Bd'(%b&mY3hMU4Ü)O/FfұX]M~ґQglXUҩ.f|OoA>"=0`Ez,rbr{ZOm'A#qhDz>1H\|"XNc&NkD@MH|u<',tx>pvSU"/ZkeӠ@T5 j 5ҽb4 &z*9.,PIϦE@wHcYu@aWj2*S0&(zUAWmy#ȥH} j? DSJzym M_pˁ3IENDB`kst-2.0.3/docbook/kst/Formula-kst-generallinearmodelexample.png000644 001750 001750 00000002665 11544160206 025237 0ustar00synthsynth000000 000000 PNG  IHDR|IDATx?H#KLJG|B"uilHB8HcE" < mA@X8 9M+41ٝ};epɎ3*L6kZVEm6Y@gτrԵb}#6:r-`<$5qi`ZZVkeKً`6ۆi%/ zӺ:[ \mjx%h;cRehYVcY̭Z$=jkŞGnW׸B׷Z7Ͱ%u+5gSpnȅ~?݀V<գZ~ CDwQҥ`\O pu88i4Nb׺ނ*"{Tڮ?Yk*;ǝ0-E]Ɗ}u ᧿GQ ֪FA0>@ZCZZ `Z&@dnd`r]gtcfP`2cz+@­C\Xچ.VuRa Z/::֥By\['"MNGIFĵN/tjQ C#Zפ{6ЪE* ky@pkQ C#Z *E* HhՏ *E* k^ jf9c> j~rɘk=mYk2'h64.qkejfjœkjX2xmMKI׷e-YYV-?=Ѥ|}ui%_ߢ6[jZ~kơҿ-M-29Op-4O0$/nio!'\Bcd0WoM)0Z^o֘ A y?oQ5&B[86W}Z' a02k86*GQz ;1]-Ϙ,ש@t #E͚ B3ZT86i dc^<6G+aVjitZ1]O^kVPKTBڅ Ah.2U¸PPP0BPr,va<xS%xa<=/:ke:S5fU[jBPȡA Z[Z>[Z>cS6,ϒgI3BkZJG>7+&kB"C-ʵo c IENDB`kst-2.0.3/docbook/kst/Diagram-kst-frames.png000644 001750 001750 00000006462 11544160206 021245 0ustar00synthsynth000000 000000 PNG  IHDRvw|>aPLTEÿĴ̱ԯܮ߱±|f~e}d}d}d}e}e|ovxptuqqqpppmmmllllllkkkkkk```[\\YZ[MZ_JZ`I[aI[aJZ`IQTCEF===888222***###-0 IDATxMOX.RRJtZf7 VgZ!aEQi#$6 "0mJss#:u0}m?'D ;e0lh~N_ J.^cl1@xeGmaf7ZuU\f##˺voپpm}KF [lo7\qoe}r޶ үxބ̧fΐ9vo%1bΐ^oDm2%~}!_QW]2HRBފI7 Ο@E{y_^ZHRrwu>-8y!MB{;t +?@n_Z]rx@ !0 C`C` !0C` E%M[7S &NY5ZG?GX{8uܺ.wprIC?g$u2a@&drIC?C` !uݺ;k~)r8Sy ڛ^ av-C` Qu\z ڜrˇ( ##|@q0C\˩+SǩDLJC!|DoC`N]Ʃp^9b?.iNy8u|ts<$ͩ6vҍy^yCӐcb}/G] q!"އr<=O@ϫFu4ؕ@~8$KʩϐxJ5~UWd4ؕ@. CR $)S2|Y;6C2a1-3h!΢Z-\ d4XTSwgSq"|>Do 8u C`/"Ykct!ҝ:H!"7cl!: !0Ɂv "۩cxg!:ni !0 /: qN]X    C`3-6N=@BS0 qYZaC ` !0C` !0C` ` !0P0C` !0 $ 0w=N][9M.@uusH:c u~'>?C`pq:q:qE!v-C` u8ua{ma';tȞOnSlFS"{.\|Tĵl_-2 h1xԋ>ݗnWp } 2N~gڧq _B&|`>r?ػŴI! )^Ư67z#lڿ HLNece(،vq40Y -3ȳh/o6ou ͐@rgQ.]~:g}b D|8uaԅ9k߀!|N!0ˁw"ݩct!}: "ۇ(dlC` !0Dr Bv"Ykck>>d[0DqC` !0D!Cp yCS>d!!!0 ~S0Ä3 $pzV0DXaC(C` !0C` !0C(C` ! !0C` !0DB ]So@NS{z(kl8uC1:$e!02\v~v~)z~Dq` !0gq=DS ]>DI  CS!02]N]ɝ?N]| 8>C'z Cpb5N]|8uafn7(M=p8f7] LH\oHzRǁ|XEKSiZ[W7KW\v=$>V>7iu.H gHJ5~UW8htT0$@YT6 _N͸F[0d 1}ew&yFA0@t3"YTKvtW%{>uqœ5N]o aNC` @;km 1DSW>DC} C2DS!0"9N]!Cd;uu וּ1D5C-"8!0!8S! aaC` Y|\ƩgaShpbd8N=@R+"`! !0C(?Z HIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-open-file-button.png000644 001750 001750 00000001421 11544160206 023716 0ustar00synthsynth000000 000000 PNG  IHDR&(ۙ pHYs  tIME/RFbKGDIDATHǵ1h"Q@LqE ]RD"HCB!E)"VAI!B0E@ YZ~ ᧰b )R"l6$J.>?|?'Q^^[ ҅.Kf 'ud :BlwMia9)> PK.嫆f6^_렾ytA'B'YLط07eY& @r՘1Cpju 䪨{ȭKd;& Rb֤3 ¨7t G]`GWԁ+AzC'Ŋqi ul l4֡9~{&nrlܭG[ai{#nD-t8ߴN8%'u.]߲{@lA( )6F:+1o$rܛpcą><%hO+=zNfGT WʸY˝q‰} +8qDudx(fg&=֐k.\INS4~SŒ :#|ׅ&=͇LL- 7dQ]700DXuٹ 2WA 3M%SF+YMwG':[*6^nWCf^_ ki^\=|1~"[T5*IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-vectorwindow.png000644 001750 001750 00000014012 11544160206 023261 0ustar00synthsynth000000 000000 PNG  IHDR]RQPLTE炵zsoccaa[\ZZYXRRRRRQKJJJJJJIEBAAAAAA?:999859<@DLQQTNLKIzD{A<}6}3|4|7y8s8o8n;o@sEqHkJjKiKiMhKhDf8b1^-].\-Y+T#G:2;B L{ L{ L{ L{!L{%L{'Lz%Lz!Ky!Is"Dj#@d!>b=a=a:^.H'; !( D'(:/0602846NCENNQuabnn}Š˝ÝżŽž8 tRNSŠrBIDATxOhG}AF;cg2x, 9  ف=q$Q,lh50|H N3w0aBAb#d1SU]ݯ~߯e_Uu߯zPYC}8Es*fu_|Cec)K(+le#Ǻ|CiDo\6䘲>(50|snh C)E>oV5[5krLYOAs~ݼ,6梋Bvrx^]0 6GVVɢ+~WᶷUΘy(~ӭo:s]H.*:d]yNxlk_ˏqevx{s^>ỉO"½ۢlO9PYOOmx-ِԮ[<ՉhcU}$D)'ƷQx*#X#Oy|-x'D|#ɴ Y"4O27PAؕA@J[R]u6(τ_cKxJ֑z{ iz2Ʒm 'xB xB 'F |"A2b|O}h흣 Պٟ+ gQ*x[gx\ xVEHyJNB-̱yi@󲞉)J;v#c>=]y84“YLS'رizȜ"-H*arNX%W 6}Wĥ/v-C3Z7gez|6ɢV'?{ԩ_ҥKw][GY=\gqg2y'/}uΝU+y6x +'IsJ̄(sqoD4;NW/7osT)O<tR499FNQ˫S8]qtpppZ,*x䉓r_EoV:֋k{{{;-my ^~湻+o|>]x/}Wv *>~*-Ͼu6`} PLO;x߯hM*)GTYrz߯oo$fTm{4 <ƕǕSb|<[[y6+,OL>!OOt<7c̃]N򬽴o ˪ct4KBul|K _lJE٩^ O2&yMe|;@TIt3>)%&8:?t$95 bfE7n~u BCs`D}~(3@D]xx6|v< 6 <;rZ?a*O<<O<~L<{ xΩw(ϒ;lXGOx8;ZRM'y;$&ukaׂWsM6/p3fxOcgD<+tW1%YK!ۗ*&'3v>}v3؄mЍ.߻LT38aޛ߇_mwJĆ roT~ڕjGXSxV`a'Ž>Dkaz>~46? Iy r֔`xrf$hY>M <դ mK{`F| Ġu撨%jg3 |UuB%H%'t)h]]mZC6#69K|i߇RZDjkLi̔ϰGi<g73̂>1JdoMmo['o+-m8s/eN<Mmo5lq;x: >C '9N8@ )zI3 ͳC֤qZcOk=6|'ޡ[0I x:S;'JOOO<<Ov"̳T:s$OgPI/3/ [Õ<;³kn/ކxj PP\}6w+<3γqggxJP&<ݤxvgbYusemggxVs<-׹'jheC@_ xB 'x'xB ' ʢ/ۿGnkyIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-multipleselectedplots.png000644 001750 001750 00000032075 11544160206 025166 0ustar00synthsynth000000 000000 PNG  IHDR/ rPLTEjcn9-J%:]!=aypca\[Y[VRRQMKKJKIFAAAAA@<:98:9" ~0}9xBvG}DIUelkWzH}Fw>o9m;f:W(TQ5BOWZds1`.^-Z+E&5#<$K|(K{"K{!L{!Kz!Kz)Bm%>b>`4N9p:q?fFUOKTIP@M2R)fCq@r27тKЅ\ךdl}l[B ڀrprME>A@?B 9E1J&OU UL@ 8 . &=)S2-:10212;48YQWYY\[Z[gZcvPjsPtlWjkjwsw||{ üƻԾ׼۽ּB tRNS0IDATx}l׽7HUeUmrQ-+-b8r!UZ! !H ԦͅXn8xUk^bkcG2T! /3/;;;{fϙwΙ}?؂@??RU@U[~Ė1jHclKyNuUb)Hd> &鏔n^Z=Yrꕋw KQNi6Ny=Ͼi\Rv!tp,aK-ؼ9SOWL JMsy+1)d*YZJ,ɘ*dd'Wbu2q!ֹ` r}\n|yeQgÇgoUye@SqOKtRFYv:+M֩ƨ:+v גpP?4mY捘Jk*S}ڽ[g)d)rKzmuooLLMOM霯1:btrŠ5P>_F7$ktruuu2?VP?ڵz%***̱ѩ 7?O;uä3*eα>IoߛSL'˝}җC7GGK+ڝj}fwkɜN'a<Nct:nehWp67Gy9Ci~*>{(Yvu Zߦ:4M1\닽}{pօu1`gkR@ZUAìg+%ar,ayrN^ˆ2 hrP*m{RgvxuifsgR'éN>;e"v=_6dGTkV;}`;5߀nggl*:Gc$ghvt|Y3<;33BQjHX:UKǬkv}J9K+qhKغf'䜔mN*!MeeLP6=r҅j,\~u\:>Nﯖ&Mf32gwiggfekOzrN)sc|j+RÕn/G/so}ɾ>w#~x}>IgeyYiW:wn>~NWxitDM'ϸ1w_r`uܔ;uTS*m{R>?sEfˉQΝƺV=D$:cv<-,w.q V1.O\938ț3sxt`4:1ե y}? ?yޜ;9u޴k9s'yСÇuVSzLt.lwNcRɝ},"[AIԺݩO>[; ו~ ;8Ū:~-?Km31y]'eQc.EJKRNYO>glUuk4Asz3K~J6Nݹ}oJ͝q (oֹbQ:ZD9e_p2QC칧IDzg]~Mp%-#_C_w(=;g;y3Y}[#å 0~e;g3;s楞4:/٥#5;?cdE h9q0eOS -_\QQ>:30{QʾYS;u=zGfGX:6T^VKc5;ielkvS/఩5,_.3J^!u׹ Ͷtq&L QsEgZ9GY#ORu^,urrϾfA(YZV^Śhg&*K:YN .^NF/\5(ݧ"wNy|x #zSXthҡr>[ُ}nj仗 lo?y:#L^I~N;KFɛsqy ̝i3UHnscܩ!Juru4^;i^_#7|h~~hUσV;ڟ4:EYZO|RN kN?.G9rO>=iY| ”)/ЊYNd2&$ȏAgKZfMb9DD,tLYn{y5NM3q( YAF)1eGZk/Iewp}ZOq% hueWUV&6#;;|gP3N ONq}ݶTgOÏ/A_b?g)ǎwxuu*+k*&x)Ao'uNݎG-iWrm>)w^*WfvF+RZ:rE8*M"7l{ܤpӫO)޹\QCyF=ݵDd~N{r]f18ΏZ W띳 uԺIirsYAig{tXV/_{ clYi 6q`?{t˧w_,i7t}6+Iwi 6R{t =Cl9{={ޔt u$ :2UO= ow[e%f&JvbYS5ݟFi-[T{/I:ߔo;hZDS̴ MN&tB6:ҡ:ENЉ#JMQB7m"wB6SGP3 lxi  iB:umd߷s{6Sz-6mʻސ6SgRgsϙ}_t٤MNTЉ#J>M>щ%j:qOއp6/N5ǝmB'tj#< ND:N:MLuzBNhB'"3۽ tzKw:>DMl8M> {,@_Az"vn/M}6!*d,Mx,MQB^`Љչ+'G MNDX:; NN N \ّ֙;;QCgqB'tB't"::3x:q:: Ŋ:q&SX8܉ǎ>;5;tB't"S!NNNpB'tBcJЉ@N %NgNgGDNYT8;; ЉNNDN<]Ɖ Y: ǻّ;;~0xN :;:: ::62@ou:E3:gG.tE-DM mAަ No\gS}_toȝ߉O7qBG::gNDD@'tNO@$6HN~rNN$out[p٩s'xfOƃQ~mm1ymX7YO ia[Y{Y͚|RN;6\.jB'tJghc6#Y͚|R:f=]Y͚|RTfϙկ:8 NNNAϳ{:q ȝ ΢)<:::'Й žgNtϳC'r'r't":}::<ӟ:9NVg(ĿY@6^μYX&:Ӄ3Ag2;-P̊μLKO,T2μLz't :ӯ8::ӟ83IlЙ*ByYOIWEO<tz- 㻡ӅD$8R?XED̓Կy ;;::ӈsN4")FC?v:ܙsWMA,wm:SP)/t'ym+ Et#w*{ۓ 6O{$?|h! mӥA΢g;O#wBgt~G &d]Щ'OTzVΏ;= YtW\N{EϠ:]L6:ٻsYt:lu<{>{0ufҩ g]DЙ=E?N:3owҮUȝ^l0tf;O;8Й#6A 묢 wB}:oAgx: s. ЙBmxj[YÜϗ Nݯ E8ϞEӫ-N'tfqD)o::M:="ArgPt:LN'tB't^g7"|3<3$w:QCOpB'jvqqJg CY~f<~f%٨w x ?NB6΢z:~7!GVT4>V/-= cwA[P$:ӝ;|wρݗNwK7]>?0&`%;=M;X![~3ĖgSMI{mlp{80ЙfT?.6ֿIߡoїv\z?)@*ٹgO=Lw6 ͐(mŖxK~6I`-Y<]X"ѹ6}now! RsUtw]\*&`%l]tow+d#Ve|9{X2iwl) -c:39N=Q1qvd-f)htt\gb?|=ip=C#JN!NteD',:3i=LhFÎ&Nݷ:l7ݶhtgu>l+ٞm3:[s|pTg{ηmwI'AJߖmʝzX|vo¬ym;tBg(Nto:]gN̢Cn1r't B'tBg$赻^DweqDIp ˝~B'tB't ϐ+ Йڄ<\OV:ggvuȝ뜼6l"]$I >^toY. YGN"PA'<[3d>i9is/t>8=[CbX|<{h8'=]޼eYx<}/zS{X8+iέ*{SFis"ΐЩU^ b 9S#JAiN,4^('tZgzӽWg9y犊*1t,wҙFTIr^fBx<:IBޯh r< ] QNQyBg.:t)B,SfNN? QNN,ΜzE賻$ SH!UL>5(N⯖g(4ZV'#;]b1P9Ssus)uÅou2Zt4p)Ho3qaUC[;ot~{SIr/7y2( %}6(qQgq) 7G=ȝA[< 6};' :CNB"qQpt|RM>wf3هipQ93ci0wj{EBN"hӯ0ϳo;;? z͞Iү2;Y4^7N/sgWW7rg&.ӳ^w]]]_pҩ g3=bãO eFgfAUȝi ڝN;U'q'q!qZ}ci% :]|GI0aHW(n^qݹTM!uRP|czߙt-<ѣ:y+c8-%'6?TN5l)Mŷh`4U6e+lZ)Ms^öҜW-#Uy/#aPWď:'H¦T[4\=u(yU2\Xӹ˼QM=%>7*Js_Gr^ uE|;߿̋{h)MESYW@i+aPWďwz-9ji\wYeaVc< LRa|^ 63::&t"wZ-M_nq]=[GSƑ /6E_:W{KnΟI_@vgZ+f?&tBg!t:BM:akw?BZ\|b}%oJ:[O&/AtTK@( M"Tom=#_\2't!w)L|ߋ%nsjt XWHҩ|?%Ŧd5(EK[rz3GdȠ3KGyt('=y tfg(Mݭ͡3ӝ{4$v6'۝{Oр(yxkہyyg66N^=^6N^=[SWO{Nݭ "^=iNfbGyN<[X4wIu"U9wz}k]2@@ӲWAOxaO;63I =(~kw NG<§+:ag:+OAW(.*δZ\c.x̜&ue5'-Ԭ2ȉN*mBg{EiXŵrW$/aw&yW)x%Z\ZN4[2dڄN':W)x%[\r!*KSW)CKRHlq3 gA3lu"ԡU В>?I=u3d#!sHʬ?2>uR3qB>?Awh3#H>2O'O4CKlqY%:sHƬ?2(sI:Zmh"vt$dI'QҧN 3Os?Qߒ/9|$c GRfI9|;_p-ϺWG2iyڜHsgሒWGR%PRNOft|:Y\)UK^ڝ|e rgYYN|etfiXu(3:7%cwΜ΢k?j?|"zEEǽ"ٱogONgJ:ӗ:L3]Y |0;"{BG:wxaly;>ӳ]z牷3Fw <{B}v1oЉ#JGEMhw"w>: Y7V}B'tOWG[L҂^:-'g>`Y ZNɬʓB:qksG*O ĭͪ<)tz6w4NѬʓBǽ"4ELu~G<:3׹j iIbҵu1y8(Z" S\ -G%I>&Wl&5':^Nu1hbH:S[I^F7CD&Uꁔ:3:MN/K6W_ $lw?PJ'YNCD,IL^tv5305Vg,e :}3TIc[$ɮ]ϮLg^o1t ^1% 犊+<;tC:։+ST:E!___xtfC 7ApD }1<-\U[EIENDB`kst-2.0.3/docbook/kst/Icon-kst-xymousezoom.png000644 001750 001750 00000000512 11544160206 021720 0ustar00synthsynth000000 000000 PNG  IHDRʥ pHYsnd tIMENWnIDAT8˝ Dc01*uB>M>J&L ;8I!^FF VJ =S) `dֈ)2]# ;&\A"$3cQ`j_i UM`cĐOs6Ǒ˜;&xyZ8mV~c8b@O.`س6e7\$}>.M&&J`$o,?Kfzem=8IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-configureshortcutswindow.png000644 001750 001750 00000021251 11544160206 025722 0ustar00synthsynth000000 000000 PNG  IHDR PLTEՂ~|`I !#(&5*B&-:0/2503A46@99@>?B@@B@@GABKDFIHJJMONRQQTQRTRRTRSVSXWXeVVQQU\`ZeOVgFPe8Ab(?a!>`=b=c?f$Kz&Lz!L{!L{!L{!M|+[/\2^5`6k8n=nKqZocmnqmrtjttry}þԿfĐ˾ǿžžдѫȟ΋tiXNJC~;{8~7:@<:6:>@AABEJJJKNUSSWYZ[_achory< tRNS ~MOIDATx[h\GǓd{ٰIlGXi6G,-K%l/MN43J"ͺd!PN&ގAH!+3``0X A{ԹTթK/ԩ_Uu._ T׊Z/˭Xӭ/:Jkn}ZdHcR"]5RDbr^ۿBBsׅ6*H髯LH_2aB>|*K=uU"җ_rޣbD8ZGBX:Bb{4FSzCqT\KSH3Ǐm :vr!2#!}mZGN$uDȉ>=;)i#:=)0kV)0t{֍,cѐv}OMHjK$7MMEHk'0 yU?gZ̔ﶶ)ͨF{ꄛ¿fqJ]^7bXQs"m4ˏ=|9 һ'fgAъ2լj=aǛA)Iʠr3} ޛooZrH377>gAp>"evdF!%.H} YVV,k~ͬ'c) ,H2;,ɐѸ儴 Q%Hߚ\xG?y,>mEȱ6{m:ic^۷bit͓άʹP'ؤzm{}Tԙb?}΂a{X菌Ύ&?2zoƹK/Z3Zjʈ'I殝40WFb|ն9H}ǹG)fZ;mAaAG9H3f Ȣ4CSrH{._^&t5?,DXYK!]# |sԄzmcT}adS, iVx.' Dg`Ism1W$ZxjDHr3ɻZY4 oc(CU"{eӊ~"ˠڮzn+Nq3Ў>I !;ë,m2UMjHW)"} ɺ1JVt1 5>նjju\e!4Љn%t̻CwnnnRq.|KU"w`h~ݺ̫dH:IW%^ E$}!\nB @iQP ! !!$BB!$*G}"7T&eyQ" TΒ )=V"B$*wE2AڹwnR!$!%zz{{{KRY =6 ]$b\"@H14ٳpkuu 2(do !Rތ[2dP ٜ{ZR *Q.x$\߃ THV>6@q,DlXRHEpO JJ I@…J i,%CIʱ+]!m,r"m؋"$B4n%ii!!$T"<*,x2ݙg B!$BH(TUz.*Lz.*,Jt͹O<عjP$kΑsNl ܫBDJUBs6?{|Bgl =RH9OHwP*̹ H^ dW%WUȰ1g"C]*}[AΟWc-FX+2_HvV iц9AZ㏮]#JV,KᖉԊցrjJ+wKoB2BU6UbİOH )%$V@T~>O@[uhU2ZQrٮ1sũD>HUۑRМ FB3VGVW_FU3Bg/U H\PVjBZ3[y nU"]s>PgS!!$T1H` B! x|i1cLTH H Hr$JIΡtӺOr $m$kptWB> !OBH7wl6@UA. )>IiIS:;&Ȑr쓔485fkrBҥSYx$9G ' ZWG'qG؇ P4xRGG ܁S"$9f!@K>ظ$`k5$' M3Yg@, I)$ɬdgde`,#$ >y(7oOL1u|[&I$#Jܹr$H#&鰁BgzΫ+/$%= %&&'&'Ǧ&'ZƐxKB CS7'';($3IiGw"Ҏ1*6+yOȣ;υҜ'̬{2IԔe6w%<ʯ8L3с8Q \fTs/TTHDҒ_ ʒyI!iIZ(%U%S;~5 K`I Ąt$.4$_L I@JUkIYlOBK] Is#Z^CKBKBKBHe$WJɒ6G(BHET,idhhp> >11<488t𕡛3ɭ!% EGGbcWzJsO;O@YhtjTr(WH>^Vl< H4qehhhx8:9u}lHp1nܝ<-<518@H{A,itꊁht46i|XpM{o3G?.poR.OX7>:844::>oI#b*olMP}!ӯ K⚻X,:|{I灔Ss煴8@Ar R4>}ejjj~ff̙ID*%e$K阞F:N t.iGw$U`s_FwԉAnuρ"CitC`~~dIΜln>yd8ynp\WgW8^Ԓǣ^BH^2ΓFFGG%M?,_2qyyXtz %~$OK9$OK9'as '~x!`I - !VEyӯ??L~:>`6BҒ~I>LKnM $--)4h@!dd(ۗuK}{݁]2o~7B*% t쒿)@>-=ɭCH%dÒD<$Hl~ɺ'/#ñtI ̀%@>4R??n'BrIO H wekI'O4 (?N Gwe /z&.Bn/ďIeudx?|qt0Nr%ŢѡΡh;m|'Wx?IIxOgKgk~V~ $QR-X襗xHe3ߒLD%c3U:dI$ѕd=yuր%^bH}=@y2=zB ջ[N<!$-~`/GHzZxc%}YPHigTSyfI DH#5$C SR>HE.ӒnN<$nfDh9w Tn%P Hft湲& %xbR $u $xHXr:2Z=Y)f щ%9>5m'BoпzOzO1O8Bz '5m6yWˍ!Ϭg8n8U%b䦓++$n+h}ҡu|\"K5XOSٚ8f43aڒvwjIܯ!Ol +`])zBMC3XnSdr_zϓ %hI3[8wfIçz;IGK"$--I3뺾0%_Y=3?Q+8VYtgϭ8ِ{jLv7'RY MvɊt[H`!bM;NoZ̄ͥZҁ'?t@K)@pCRquBnjdIlOr=wfCo^Jt$@ {c`!٬fIkl}}@qn]4mO3B$KrO:7zg@CүSъ^!UdP4K}ۼ3khQ$hŚ;~t] ${g;y?xl?ytW>HyȐWΒ;xAGK"$-I34e,BBY$^نԣϬ>R3OM"3ߝE{>#,W)O%,᧦pw;h5 >=뽽ORg/6Tต / D? |fS;u۩D?誴);(. J4_Z3K,.$ݗC8(fՐ/?gv!gr. :?XRi~CN,/Hw@H~a'X]gtEE췰O*Hcg 9Oì8s6@UZR.>u&"æBٟ2 RwYS3׮%qwfkw3>3+3g}f|gwܡϬ>}f]gv3d[MړTb==gW덝CB<gvP59v}ffYgŃ g.+M_Hg][]YYZ\H,l7i@i3kx\`E $$ޗNp} =r3jhs_l! >I~b򔳒4&A 誹k˒R׌_4*!)uSt巄|7ZploY#͝3[ʹ=ݡH(n}37w^Ė{ & JSCѳѝK%o'UDMUIjIo?[>ݑ$pW7$s[+-)-\+)В8ޮPF ]oHl0Y3{';f~+L2e ;xNKg"<`0|,NE$ഐGZ:;[ #$ =NIhK!{.(>ih2UL%F_gVH>30RqFw?J&YON9wY- 3 8Klo_F~}p;Ϭ ؒBHHK}X+Ô|ŃP=l@!q>]G::;FPh?͠@z(3˵xVΒ[;nAS vۻ癭0oUp}yLSNyOc}Y-GhvamuUOBGw?iicɦx|f1gVH6;ÝMyaH+E =:^Ԓ ͝GZVm-ު8u~oU*p;}f5Tή/=vPօ J KdM !BB!$BBH(} t=Pg>'&DV/\ A)$f]1p ,ܚvEc /BǠ vo}*N6~IZC M| =qAKb$;j -&G@:X " ٿ& $<~Dj@Y@RT+Rv}ps$KhOa @ kPS $oBB!$BH !!$BBH !RF * B*!$ LM9!)\{ Ν #$!3JۦLVBBH !!COm J\\ˁw[f"1@(ڛf280Hx͡*|1##_)kE.f2/8)'N)֋¾q(]lX/#wTlԙ!)nq}!9b{L}٨ srb%Kk6`\l 铸>W )J(/b{BkkfɪSwO@J!&u-dOB&|&D;$X i_CqJ^|tL7ɟ)H x!Yg E۪| 9vY H ɌoT!1 '%$E.րBZ+ )oq\6!BCq"q܎%<⾙Z=)H؞Ioq}#žN%&vz6 $S.YKgq}#žWy_fdz9$~f.Zvܚ,U%OW*8BBH !!$T ŸBHet !2@:w!i+Y ॅ^(BB!$BH(P !!$BH P ! !!$BBH !RAB?"Ai P !!$BBH(*ǾHWI T+/#R_YTiJ.flJŨ^H>ίHU{J Fe-R*@*y!TfūRAZ!PL&GE/9BJqvU $濲ܕ&(Zs!@(Y@"RRCzxL,f )m5C*̐6| amY|J@ZmN q_JpH iC( HzY5j/A6{+>%bܖ4rk IA)@RV+B)y6%6@ZQu$u!J$cŶ^HM V$&KR6b W )vwk%[>Q[v!Z0X*imQ!բAVpA4% ɢA[cA*@F!\򌐜<iC1-CZ]eA%R* WHkΣ`RCZ[,4^.<.;[ɅTj5AJe-*B*ٟ{g>k>rqU, B(턐 !!$BB!$BH(P !41Z/؊\/?4"3IENDB`kst-2.0.3/docbook/kst/dcop-chapter.docbook000644 001750 001750 00000001611 11544160206 021023 0ustar00synthsynth000000 000000 The &kst; &DCOP; Interface &kst; provides an interface that acts as a client using the the &kde; Desktop COmmunications Protocol (&DCOP;). The set of functions provided in the KstIface interface allows for easy control of &kst; by other applications or scripts. For more information on &DCOP;, refer to this webpage. kst-2.0.3/docbook/kst/plotsandwindows-chapter.docbook000644 001750 001750 00000156755 11544160206 023361 0ustar00synthsynth000000 000000 Working with Plots and Windows This chapter details the concepts behind plots and windows, and provides information on viewing and manipulating the layout of plots and windows in &kst;. The following diagram illustrates the relationships between windows, plots, and plottable data objects. &kst; Window, Plot, and Curve relationships As can be seen from the above diagram, each window in &kst; can contain zero or more plots, and each plot can contain zero or more plottable data objects. The Plot Dialog The plot dialog provides a central location for managing plots. To access it, select Edit Plot... from the Plots menu. At the top of the dialog box you should see two drop-down lists: Top of Plot Dialog Top of Plot Dialog To modify a plot, select the window that contains the plot from the left drop-down list, and select the plot itself from the right drop-down list. New windows can be created by clicking the button in the middle. At the bottom of the plot dialog are four buttons. Delete deletes the currently selected plot, Apply as New applies the current plot settings to a new plot, Apply Edits applies the plot settings to the currently selected plot, and Close closes the plot dialog without applying or saving any settings. The plot settings available on each tab of the plot dialog are described below. Content Below is a screenshot of the Content tab. Plot Dialog Content Tab Plot Dialog Content Tab As the name implies, the settings on this tab specify the content of the plot. The following are brief explanations of the settings. Unique plot name The unique plot name is the identifier for the plot. There cannot be duplicate plot names. Displayed objects and Available objects Displayed objects lists the plottable data objects that should be plotted in the plot. Available objects lists all the current plottable data objects in &kst; that are not in the Displayed objects list. To move an item from one list to the other, first highlight the desired item, and click the appropriate arrow button in between the two lists (the left arrow to move a item from Available objects to Displayed objects, and the right arrow to move a item from Displayed objects to Available objects). Alternatively, dragging and dropping the items works as well. Foreground and background colors Select the foreground and background colors to use for this plot using the standard &kde; color chooser. The upper left box indicates the foreground colour, while the lower right box indicates the background colour. To edit a colour, double-click on the desired box, and a standard colour chooser dialog will appear. Click to swap the foreground and background colours. If you wish to quickly switch to a white background and black foreground, click Note that the foreground color only affects the axes lines and axes labels, and is independent of any colors used to plot data objects. Re-grid and Columns Check the Re-grid option to rearrange all plots in the selected window in a grid pattern with the specified number of columns. Axes Below is a screenshot of the Axes tab. Plot Dialog Axes Tab Plot Dialog Axes Tab The settings for the plot axes are specified on this tab. The axis settings are split into two identical sections—an x axis section and a y axis section. Auto scale Select this option to let &kst; automatically choose a scale for this axis based on the highest and lowest values for this axis found in the plotted objects. Auto up This option behaves similarly to Auto Scale, but the upper axis limit will only increase, and the lower axis limit will only decrease. Spike Insensitive Auto scale Select this option to let &kst; automatically choose a scale for this axis that is based on the values found in the plotted objects. In general, spikes, or sudden short increases or decreases in the value, will be ignored when determining the scale. Mean-centered Select this option to center the axis around the mean of the values found in the plot (x values are used to calculate the mean for the x axis, and y values are used to calculate the mean for the y axis). Specify the length of the axis in the Range text box. Fixed Manually specify lower and upper limits for the axis. Enter the limits in the textboxes to the right of Range. Logarithmic Enable this checkbox if you wish to use a logarithmic scale for the axis. Major tick density, Minor ticks, and Auto minor Change the density value for the major ticks on this axis by using the Major tick density field. The number of major ticks on the axis will be approximately equal to the density value, with slight variations depending on the plot size and zoom level. Select the number of minor ticks to show in between major ticks using the Minor ticks field. If Auto minor is checked, the number of minor ticks is automatically determined based on zoom level. In addition to axis ticks, grid lines can be shown on plots as well. Grid lines are drawn as thin dotted lines using the specified colors. Show major Select X major to show vertical grid lines corresponding to the x axis major tick marks. Select Y major to show horizontal grid lines corresponding to the y axis major tick marks. The color of both types of major lines can be specified by clicking the button next to Color. Show minor Select X minor to show vertical grid lines corresponding to the x axis minor tick marks. Select Y minor to show horizontal grid lines corresponding to the y axis minor tick marks. The color of both types of minor lines can be specified by clicking the button next to Color. Labels Below is a screenshot of the Labels tab. Plot Dialog Labels Tab Plot Dialog Labels Tab Settings for the plot labels can be specified on this tab. Brief descriptions of the settings are provided below. Current scalar list A list of the current scalars defined in &kst;. This list is primarily used to quickly insert values in the label texts. Choosing an item from this list will insert the item at the current text cursor position. Top label The label located at the top of the plot. Select a font size and enter the text for the label using the controls in this row. Y axis The label located vertically next to the y axis of the plot. Select a font size and enter the text for the label using the controls in this row. X axis The label located vertically next to the x axis of the plot. Select a font size and enter the text for the label using the controls in this row. Numbers, X angle and Y angle The numbers used to label both the x axis and the y axis of the plot. The size and angles of the numbers can be specified. Positive angles rotate the text clockwise, while negative angles rotate the text counter-clockwise. Font family The font used for all labels of the plot. Select an available font using the drop-down list. Also Apply Font and Angle Settings To Select the plots to which the specified label settings (except Label Text) should be applied. If All other plots or All other plots in this window is selected, previous label settings for the affected plots will be lost. Auto Label Click this button to automatically generate label texts for all labels on the plot. The text for Top label will be a list of paths to the data files used in the plot. The text for Y axis will be a list of the dependent variable descriptions (e.g. Number in Bin for a histogram). The text for X axis will be the name of the vector used as the independent variable. Labels (preview) The preview image at the bottom of the Labels tab provides previews of all four labels at 100% zoom. Legend Below is a screenshot of the Legend tab. Plot Dialog Legend Tab Plot Dialog Legend Tab Legend settings for the plot can be specified on this tab; most of these settings concern the appearance of the legend. The legend itself is optional. Show legend This option enables or disables the legend for the plot. If you wish to use a legend, you must select this checkbox. Display in legend box Select this option to display a border around the legend. Selecting this option also allows the background of the legend to be set using the color chooser located on this tab. Alignment The horizontal (left and right) alignment of the items in the legend. The available settings in the drop-down list are Right, Center, and Left. Font family The font to use for the legend text. Select a font from the drop-down list. Font size The size of the legend text. Note that the size is not specified in points, but is relative to a default size of 0. Colors This widget can be used to specify the colour of the legend text. The upper left box indicates the foreground colour, while the lower right box indicates the background colour (applicable only if Display in legend box is checked). To edit a colour, double-click on the desired box, and a standard colour chooser dialog will appear. Click to swap the foreground and background colours. If you wish to quickly return to the default colours, click Also Apply Settings To Select the plots to which the specified legend settings should be applied. If All other plots or All other plots in this window is selected, previous legend settings for the affected plots will be lost. Legend (preview) The image at the bottom of this tab provides a preview of the legend text at 100% zoom. Among other things, the preview can be useful in determining appropriate font sizes. Markers Below is a screenshot of the Markers tab. Plot Dialog Markers Tab Plot Dialog Markers Tab Plot markers provide an easy means of flagging areas of interest on a plot. The Markers tab provides full access to plot marker settings and options. Navigation functions for plot markers are described in the Scroll Menu section. To quickly create plot markers on a plot, place the mouse cursor over the plot and press the Insert key. A vertical dashed line should appear indicating the position of the plot marker. New and Add Use the New text field to manually enter a plot marker value. Values can be entered in floating point or scientific notation. Values in scientific notation must be entered in the form mEx or mex, where m is the mantissa and x is the exponent. For example, one way to enter the value 15000 in scientific notation is by typing 1.5e4. Click the Add button to create a new plot marker with the specified value. You will be warned if duplicate plot markers already exist, or if the entered value is not valid. Note that plot marker additions or removals made from the Markers tab are not applied unless the plot dialog settings are applied. Defined plot markers, Remove, and Remove All The list of existing plot markers for this plot are listed under Defined plot markers. To remove plot markers, highlight the desired markers in the list and click the Remove button. Multiple markers can be selected for removal by clicking and dragging within the list, or by holding down the Shift or Ctrl key and clicking on items in the list. To remove all plot markers for this plot, click the Remove All button. Note that plot marker additions or removals made from the Markers tab are not applied unless the plot dialog settings are applied. Automatic Marker Generation In addition to individually defining plot markers, curves, equations, power spectra, and histograms can be used to automatically generate plot markers as well. To use one of these data objects for plot marker generation, check the Use data object as marker source checkbox and select an item from the drop down list. Then select the criteria to use for creating plot markers. Selecting Rising edge causes plot markers to be created when the y value of the selected data object changes from zero to non-zero. Selecting Falling edge causes plot markers to be created when the y value of the selected data object changes from non-zero to zero. Selecting Both causes plot markers to be created on both rising edges and falling edges of the data object. In all cases, the x value of the point in the data object with the non-zero y value is used to create the new plot marker. If the selected data object is subsequently updated, additional plot markers will be created if necessary. However, plot markers will never be removed as a consequence of data object changes, so manually created plot markers will never be affected. The Plot Context Menu When working with plots, right-clicking on any plot will bring up a context menu that provides commonly used functions. The following list provides a brief overview of the menu items, often referring to other sections of this document that describe the functions in more detail. Delete Deletes the plot. Edit... Brings up the Plot Dialog, with this plot selected. See the Plot Dialog section for information on the settings. Maximize Expands the plot so that it takes up the entire area of the window. Uncheck this option to return the plot to its previous size. Pause Pauses automatic update of live data. This menu item duplicates the functionality of Pause from the Range menu. See Working with Live Data for more information. Zoom (submenu) The Zoom submenu is described in the section entitled The Zoom Menu. Scroll (submenu) This menu is described in the section entitled The Scroll Menu. Edit (submenu) This submenu displays a list of objects available for editing. Clicking on an object name from the submenu displays the Edit dialog for the object. Details on this dialog are available in the Curves. Fit (submenu) This submenu displays a list of curves, histograms, power spectra, and equations that can be fit. Selecting a name from the submenu displays the Fit Function dialog. This dialog is similar to the plugins dialog, but displays only those plugins that perform fits. The input vectors are selected based on the data object. In addition, curve appearance properties can be changed, as the Fit function creates vectors, and curves based on the vectors. Filter (submenu) This submenu displays a list of data objects that can be filtered. Selecting a name from the submenu displays the Filter Function dialog. This dialog is similar to the plugins dialog, but displays only those plugins that perform filtering. The input vector to be filtered is selected based on the curve. In addition, curve appearance properties can be changed, as the Filter function creates vectors, and curves based on the vectors. Remove (submenu) This submenu displays a list of curves currently in the plot. Clicking on a curve name from the submenu removes the curve from the plot (the curve itself, however, is not removed as a data object). The Label Editor The label editor allows custom labels to be placed in arbitrary locations in &kst; plot windows, in addition to the fixed labels created as part of plots. To use the label editor, select Label Mode from the Plots menu. The mouse mode will change to label editor mode. To exit label editor mode, select another mouse mode (such as XY Mouse Zoom). The following sections describe the functions available when in label editor mode. Creating New Labels To create a new label using the label editor, click anywhere within the x and y axes of a plot where there is not already an existing label. The label editor dialog should appear: The following are explanations of the dialog box elements. Scalars A list of scalars currently defined in &kst;. Selecting an item from the dropdown list inserts the value of the item at the current cursor position in Label text. Label text The text displayed by the label. You may enter text manually in this dialog and in combination with scalars selected from the Scalars dropdown list if you wish. Font The font to use for the label text. Select a font from the dropdown list. Size The size of the label text. 0 is the default value. Rotation The number of degrees to rotate the label. Positive values rotate the label clockwise, while negative values rotate the label counter-clockwise. Alignment The horizontal alignment of the label. Select one of Left, Center, or Right. Color Select the color to use for the label text. Clicking the button displays the standard &kde; color chooser. Selecting Use plot color uses the foreground color specified for the plot. Once you are satisfied with the label settings, click Apply to apply the label settings without closing the label editor dialog. Click OK to apply the label settings and close the dialog. Alternatively, you can click Close to close the label editor dialog without applying any label settings. Editing and Deleting Existing Labels To edit an existing label, click on the label in the plot. The label editor dialog should be displayed. You can delete the label from the label editor dialog by clicking the Delete button. Moving Labels To move an existing label in label editor mode, simply drag the label to the desired location, anywhere within the plot. Data Mode Data mode allows precise viewing of the data points use in a plotted data object. To toggle data mode, select Data Mode from the Plots menu. Now, when the cursor is moved over a plot, a coloured dot will indicate the closest data point to the cursor, as shown in the screenshot below. The status bar will display the coordinates of the data point (in terms of the x and y vectors used to plot the data object) in status bar at the lower right corner of the &kst; window. The status bar will also display the x, y, and z coordinates of any visible image. If images overlap, only the coordinates of the topmost image will be displayed. Note that all zooming functions are still available while in data mode. Top of Plot Dialog Top of Plot Dialog If the status bar is not visible, make sure Show Statusbar is checked in the Status menu. Zooming and Scrolling Zooming and scrolling in plots is easy and intuitive with &kst;. The following sections explain the different zooming and scrolling modes. Mouse Zoom Modes To access the different zoom modes, choose one of XY Mouse Zoom, X Mouse Zoom, or Y Mouse Zoom from the Plots menu. The different modes are described below. XY Mouse Zoom In XY Mouse Zoom mode, you can zoom into a specific rectangular area of the plot by simply clicking and dragging to draw a rectangle where desired. The x and y axes of the plot will change to reflect the new scale. This mode is often useful for quickly looking at an interesting area of the plot without having to specify exact axis scales. X Mouse Zoom In X Mouse Zoom mode, the y axis is fixed. Zooming in is performed by clicking and dragging a rectangular area; however, the upper and lower limits of the rectangle will always be equal to the current upper and lower limits of the y axis. This mode is often useful for looking at a certain time range, if the x axis happens to represent a time vector. You can quickly switch to X Mouse Zoom mode by holding down Ctrl. The mouse cursor will change to indicate the new mode. Releasing Ctrl will return you to the previous mouse zoom mode. Y Mouse Zoom In Y Mouse Zoom mode, the x axis is fixed. Zooming in is performed by clicking and dragging a rectangular area; however, the left and right limits of the rectangle will always be equal to the current left and right limits of the x axis. This mode is often useful for zooming in on data that is concentrated around a horizontal line. You can quickly switch to Y Mouse Zoom mode by holding down Shift. The mouse cursor will change to indicate the new mode. Releasing Shift will return you to the previous mouse zoom mode. The Zoom Menu The Zoom menu can be accessed by right-clicking on a plot and selecting the Zoom submenu from the context menu. A list of zoom actions and their corresponding keyboard shortcuts will be displayed. These actions are described below. Zoom Action Keyboard Shortcut Description Zoom Maximum M Sets both the x axis and the y axis scales so that all data points are displayed. This is equivalent to the AutoScale setting of the Plot Dialog. Zoom Max Spike Insensitive S Sets both the x axis and the y axis scales so that most data points are displayed. Spikes, or sudden increases or decreases in x or y values, are excluded from the plot display. Zoom Previous R Returns to the most recent zoom setting used. Y-Zoom Mean-centered A Sets the Y axis so that the mean of the y values in the plot is centered vertically. The actual zoom level is not changed. X-Zoom Maximum CtrlM Sets the x axis scale such that the x values for all data points are between the minimum and maximum of the x axis. The y axis scale is unaltered. X-Zoom Out ShiftRight For a non-logarithmic x axis, increases the length of the x axis by a factor of approximately 0.5, without changing the midpoint of the x axis. The y axis scale is unaltered. X-Zoom In ShiftLeft For a non-logarithmic x axis, decreases the length of the x axis by a factor of approximately 0.5, without changing the midpoint of the x axis. The y axis scale is unaltered. Toggle Log X Axis G Enables or disables using a logarithmic scale for the x axis. Y-Zoom Maximum ShiftM Sets the y axis scale such that the y values for all data points are between the minimum and maximum of the y axis. The x axis scale is unaltered. Y-Zoom Out ShiftUp For a non-logarithmic y axis, increases the length of the y axis by a factor of approximately 0.5, without changing the midpoint of the y axis. The x axis scale is unaltered. Y-Zoom In ShiftDown For a non-logarithmic y axis, decreases the length of the y axis by a factor of approximately 0.5, without changing the midpoint of the y axis. The x axis scale is unaltered. Toggle Log Y Axis L Enables or disables using a logarithmic scale for the y axis. Many of the zoom actions are best used in conjunction with the various mouse zoom modes. Match Axis To quickly change the axes of a plot to match those of another plot, right-click on the plot and select a different plot name from the Match Axis... menu. Both the x and y axes scales of the current plot will change to match those of the selected plot. Note that this does not permanently tie the axes scales together; changing the zoom on either plot will unmatch the axes scales again. To tie the axes scales of two or more plots together, use the Tied Zoom feature. The Scroll Menu Functions for scrolling a plot are available by right-clicking a plot and selecting the Scroll submenu from the context menu. Most scrolling functions and their keyboard shortcuts should be self-explanatory. To quickly jump to a plot marker, select Next Plot Marker (to jump right) or Previous Plot Marker (to jump left). For more information on plot markers, see the Markers section. Assuming non-logarithmic axis scales are used, each function scrolls the plot in the indicated direction by 0.1 of the current length of the x axis (when scrolling left or right), or 0.25 of the current length of the y axis (when scrolling up or down). You can also scroll left or right in a plot by using the mouse wheel (if available). To quickly go forwards or backwards along the x axis, select Back 1 Screen or Advance 1 Screen from the Range menu. The keyboard shortcuts, CtrlLeft and CtrlRight respectively, can be used as well. Tied Zoom When looking at two or more related plots (for example, two curves on separate plots both dependent on the same time vector), it can sometimes be useful to zoom or scroll the plots simultaneously. This is possible using &kst;'s tied zoom feature. To activate tied zoom, click the small square at the top-right corner of the plots you wish to tie together. The squares will change colour to indicate the plots are tied, as shown below. Top of Plot Dialog Top of Plot Dialog Zooming and scrolling actions performed on one plot in a group of tied plots will be performed on on all the plots in the group. To remove a plot from the tied group, simply click on the small square at the top-right corner of the plot again. The square will become transparent to indicate that the plot is not tied. To quickly tie or untie all plots (including plots in other windows), select Tied Zoom from the Plots menu, or the corresponding icon on the &kst; toolbar. Working with Live Data &kst; features special zooming and scrolling functions designed to make it easy to work with live data, or data that is being updated while &kst; is running. These features are designed to be used in conjunction with the regular zooming and scrolling functions. Updating Plots Automatically To have a plot automatically update as data is being added to a data file, choose Read From End from the Range menu. The plot will automatically scroll to the right periodically, to display new data points. The update interval can be changed by selecting Configure Kst... from the Settings menu. Specify the update interval in the Plot Update Timer field. Pausing Plot Updates To pause automatic updating of plots, select Pause from the Range menu. You can still perform zooming and scrolling functions while the updating is paused. Selecting Read From End from the Range menu will resume automatic updating. Changing Data Sample Ranges To quickly change sample range settings associated with vectors, select Change Data Sample Ranges from the Range menu. Select one or more vectors, change the desired settings for the vectors, and click Apply to save the settings. These settings are a subset of those found in the Edit Vectors dialog. Manipulating Plot Layout Plots in a &kst; window are arranged in layers. Each plot is positioned on one layer, and each layer contains one plot. Thus, plots can overlap, with plots in higher layers taking precedence in visibility over those in lower ones. To change the layout of plots in &kst;, layout mode must be activated. Layout mode can be toggled by selecting Layout Mode from the Plots menu. Layout Mode Context Menu While layout mode is activated, right-clicking on any plot displays a modified context menu. The selections available in this menu are listed below. Delete Deletes the plot. Raise Raises the plot one layer up. Lower Lowers the plot one layer down. Raise to Top Raises the plot to the top-most layer, guaranteeing it will be visible. Lower to Bottom Lowers the plot to the bottom-most layer. Rename... Selecting this item displays a dialog box that allows the unique name of the plot to be changed. Move To Selecting a window name from this submenu moves the plot to the window with the corresponding name. Cleanup Layout Arranges the plots in the current window in a tile type pattern, with no overlap between plots. This action applies to all plots in the current window. Moving and Resizing Plots Moving and resizing plots in layout mode is analogous to moving and resizing regular windows. To move a plot, simply click anywhere on the desired plot and drag the plot. An outline of the plot will appear, indicating where the plot will be placed. You can drag plots anywhere within the current window. To resize a plot, move the mouse cursor to any edge or corner of the plot. The cursor will change to indicate that the plot can be resized. Click and drag the outline of the plot until the plot is the desired shape and size. Selecting Multiple Plots and Grouping Plots Two or more plots can be selected together in layout mode. To select the plots, hold down the Shift key and either sequentially click on each plot you wish to select, or drag to draw a dotted rectangle around a group of plots. The selected plots will be indicated by a gray border around each plot: Multiple Selected Plots Multiple Selected Plots Multiple selected plots can be moved simultaneously by dragging any single plot that is part of the selection (note that resizing any plot in the selection removes the selection). In addition, the layout mode context menu contains three additional items when multiple plots are selected. These items are described below. Make Same Resizes all the selected plots in the chosen dimension(s) to match the dimension(s) of the plot from which the context menu was invoked. For example, right-clicking on a plot in the group and selecting Width from the Make Same submenu will match the width of all the plots in the group to the width of the first plot. If Size is chosen, both the width and height of each plot in the selection will change. Align Aligns all plots in the selection to the plot directly underneath the context menu. Select from Left, Right, Top, or Bottom. Pack (submenu) The Pack submenu contains two functions. Pack Horizontally divides the entire width of the plot group evenly between the individual plot widths, while Pack Vertically divides the entire height of the plot group evenly between the individual plot heights. Packing plots usually results in a staggered or checkered pattern. To align the plots in a grid, use the Cleanup Layout function of the layout mode context menu. Group Objects Groups all the selected plots together. A group of plots is indicated by a blue outline around the entire group. The layout of the plots within a group cannot be altered, but a group of plots can be resized or moved as a whole in the same way the layout of a single plot can be changed. Grouped plots remain grouped even when layout mode is exited, so the Maximize or Delete functions of the plot context menu can be used on an entire group. To ungroup a group of plots, simply right-click on the group and select Ungroup. Working with Windows &kst; has a flexible window layout that makes use of Kmdi. Organizing plots on different windows allows for efficient viewing and manipulating of plots. MDI Modes There is a choice of four different MDI (Multi-Document Interface) modes available. To select a mode, choose one of the menu items from the MDI Mode... submenu of the Window menu. The selected MDI mode will take effect immediately. The sections below provide more information on each mode. Top Level Mode Top level mode is the mode traditionally used by other &kde; applications. In this mode, the parent window (the window containing all the main menus, toolbars, and status bars) is a separate window from the plot windows. The plot windows, while still functionally tied to the main window, appear as separate windows on the desktop. To quickly switch between plot windows in top level mode, you can click the buttons on the parent window, as shown below. Switching windows in top level mode Switching windows in top level mode Childframe Mode In childframe mode, all the plot windows appear inside the main &kst; window and can be individually resized. Each plot window contains buttons for minimizing, maximizing, closing, and docking themselves. The main &kst; window also contains functions for arranging the plot windows. The following lists the functionality of the buttons located in the top right corner of each plot window: Undocks the plot window. An undocked window is not contained within the main &kst; window, but is located directly on the desktop. You can also undock or dock a window by selecting its name from the Dock/Undock submenu of the Window menu. This is also the only way to dock an undocked window. Minimizes the plot window. Since the plot window is contained within the main &kst; window, clicking this button will minimize the window to a titlebar within the &kst; window. Maximizes the plot window. The plot window will take up the entirety of the main &kst; window. Closes the plot window. To quickly switch between plot windows in childframe mode, you can click the buttons on the parent window, as shown below. Switching windows in top level mode Switching windows in top level mode To easily organize the plot windows within the main &kst; window, you can choose one of the tiling functions from the Tile... submenu of the Window menu. These functions are described below. Cascade Windows Cascades the windows starting from the top left corner, maintaining the original window sizes. Cascade Windows Cascades the windows starting from the top left corner, but resizes each window so that the bottom right corner of each window reaches the bottom right of the main &kst; window. Expand Vertically Resizes each window to its maximum height. The widths of the windows are not changed. Expand Horizontally Resizes each window to its maximum width. The heights of the windows are not changed. Tile Non-overlapped Arranges the windows in a tile pattern, with no windows overlapping and each window being as close to a square as possible. Tile Overlapped Arranges the windows in three or four stacks, depending on the number of windows and the main &kst; window size. Tile Vertically Arranges the windows in a tile pattern, with each window having maximum height and no windows overlapping. Tab Page Mode Tab page mode arranges each plot window on a separate tab within the main &kst; window. In this mode, the plot windows are not independently resizeable or moveable—they conform to the size and shape of the main &kst; window. To switch between plot windows in tab page mode, you can click on the tabs corresponding to each window, as shown below. Switching windows in tab page mode Switching windows in tab page mode IDEAl Mode IDEAl mode seems to be identical to tab page mode. Creating and Deleting Windows New windows in &kst; can be created in a number of ways. To create a new, empty, window, select New Window from the File menu. You will be prompted for a unique name for the new window. You can also create a new window while creating a new plottable data object. See Placement for the specific details. To delete an existing window, simply select Close from the Window menu. To delete all current windows in &kst;, select Close All from the Window menu. By default, &kst; prompts for confirmation before closing any window. This behaviour can be changed by selecting Configure Kst... from the Settings menu and clicking on Prompt before closing windows. When a window is deleted, all plots within that window are deleted as well. However, data objects, such as curves, are not deleted. Moving Plots Between Windows To move a plot from one window to another, you can use the Move To function of the layout mode context menu. kst-2.0.3/docbook/kst/Screenshot-kst-matrixwindow.png000644 001750 001750 00000011307 11544160206 023267 0ustar00synthsynth000000 000000 PNG  IHDREﮫPLTE #"-&0%*1-.2//2+16$3?"6J9U;_=a!?b!Bf#Gp%Ky&Lz"L{!L{!L{ L{ M{M{S{T{R{"Q~)U.[-\0]2_3a5f6k8n:o@sErFpHlJiJiJiJiJiJiOk}`rhz~[~fwqfcbbbbaXQLHC:}5}3~7<>>9.&89::AAAAABBIJJJJJJKOTSSRSUYZ[[_acdkrt{삵焷犽ƿ3KtRNS޹sqIDATxkGZ1,:a/ȑ 䲾 |!8C -)`r19 Ɓ 눵`FAC0 ګIYQ#3U]SN 𒩩3SYLʙO/YӸpoi5ڪ G+o&tȋ֕#ŕCs..nPb*uG+%ܗ˾!G\ ^NX3lV՚ȫp9yuV.9|ÓM/(%f#:Y&L\>l6#])gU#3"w. G\9^Մr.(%f#:('I9$_}_ XYr,arD^tfoU0)ܚo$6rw~lȃ>8%=z܏46WV6bs%y)f["/D抌s*ێW?$尧Ϲrtn?tr@vt:S\I3\\ο%Aȁ9r @yv dl䐙JALKfE'҂ 9D)Y1# 5jA\ \!8US>@rn^-4w|F-9WYrn^܌tɡuý,;{_[38{k[9r @3,ԝ,@n~uHiʾ浓zqr^ #vroNM~d{$rrlX9M~ 9LV+VNR.V 4#9'&\CCz^9EscTs>XNsZn؋K+~&c@Icȑ3^ܿ"7Cn~w9{Q#K@aC!';3^,jrXrctn9rc@Bk!X_CX%`anaow@9D\]?Uo-+7LC B쇭_9BpZr9/XN[lfr Udq5oP9/ cGZ$4 Sn[%&_s P^r? 7Z_rCCo_H}3vr ǟ(5(B9r @߀3>7YSzE'9 rȁ09ڗuo77P#ZQhn[v.,4M]wiQNZź/K+&LC~!:p+ķhq}:t7mV1=-ZPZurԞtE &ҭYt;ˉ_Z+[nZ^rȁ9 @ Pl |cPeo/OiC@ΨXO儞v0츔Kyv|5 $r| gN#3 99IhE`t$P9"ḓ @ rXh Sw|Y>9i9J6\:ÖXN9#;uH+1ɖs{y h9&DWjL!oANr H s(yONrCђn}Y [$ʥAN/r:-)ȐQ$XiIAYfWC\n,u(q#f!jN<_r]eʱBNribIUNcҪ!d9m6jiYGuh46L*z 9B99r4;Pr }9鎒sANw9/^%gr=> "4`ghCЋD߀ r@9 rȁ0/>^ETxhŋyIENDB`kst-2.0.3/docbook/kst/data-chapter.docbook000644 001750 001750 00000135651 11544160206 021023 0ustar00synthsynth000000 000000 Working With Data Supported File Formats Currently, Kst supports ASCII text files, BOOMERANG frame files, and BLAST dirfile files as data sources, as well as PIOLib and FITS files with the appropriate libraries. This section describes basic data source concepts common to all file types, and specifically details the ASCII and BLAST dirfile file types. Data Source Concepts A data source in &kst; is simply a supported data file. The following concepts are important in understanding how &kst; works with different data sources. Some terminology is also introduced in this section. Samples A sample is considered to be the fundamental unit with respect to data files. Each sample consists of one data value in the file. Note, however, that one sample may not correspond to one value in a data vector in &kst;, due to the concept of frames. Fields A field usually corresponds to one vector in &kst;. For example, a column in an ASCII data file is considered to be one field. Each field can have an explicit or implicit name. Datasource readers provide functions for reading and obtaining fields and field names. Frames A frame corresponds to a set number of samples, and each field in a data file can have its own ratio of samples per frame. The size of a data file is measured by the number of frames it contains. For ASCII data files, the number of samples per frame is 1, but for some data files, there may be multiple samples per frame. In the below illustration, the first 3 frames of an imaginary data file are shown. In this particular data file, Field 1 has a ratio of 5 samples per frame, Field 2 has a ratio of 2 samples per frame, Field 3 has a ratio of 3 samples per frame, and Field 4 has a ratio of 1 sample per frame. Depending on the specific data vector settings in &kst;, data from files may be read as frames instead of samples, with either the first sample in a frame or the mean of all the samples in a frame representing the value of the frame. INDEX Field Some data files may not have a field that represents the x axis of a plot. However, &kst; implicitly creates an INDEX field for all data sources. The INDEX field simply contains integers from 0 to N-1, where N is the number of frames in the data file. ASCII Input Files The simplest input file format is the ASCII text file. These files are usually human-readable and can be easily created by hand or simple scripts if desired. The following is an example of an ASCII input file. 112.5 3776 428 187.5 5380 429 262.5 5245 345 337.5 2942 184 412.5 1861 119 487.5 2424 138 567.5 2520 162 637.5 1868 144 712.5 1736 211 787.5 1736 211 862.5 2172 292 937.5 1174 377 1000.5 499 623 Each column of this file represents a field, while each row represents one frame. Columns are separated by tabs or spaces, and rows are separated by carriage returns. Note that due to their structure, ASCII files cannot have multiple samples per frame. Also, since the columns do not have labels, field names are assigned by &kst; based on the order of the columns (the leftmost column has a field name of 1). Commented lines in ASCII files start with one of the characters in the set {#, !, /, ;, c}. All commented lines and empty lines are ignored by &kst;. Valid numbers include those with decimals, negative signs, or e, to indicate scientific notation. Invalid numbers (such as English words) are replaced with 0 by &kst;. BLAST Dirfiles BLAST dirfile data sources are actually directories of files. Each directory represents one data source, and each file in the directory, with the exception of a file called format, represents a single field. The file named format lists each field and its properties. Below is example of such a file: scount RAW f 1 fcount RAW f 20 sine RAW f 20 ssine RAW f 1 cos RAW f 20 In this example, scount, fcount, sine, ssine, and cos are field names. RAW indicates the file is written in raw format, and the last number in each row is the number of samples per frame. When selecting a BLAST dirfile for use in &kst;, the directory containing the field files should be selected. &kst; will when automatically look for a format file, if it exists, to determine the fields and their properties. The Data Wizard The Data Wizard provides a quick and easy way of creating vectors, curves, power spectra, and plots in &kst; from data files. To launch the wizard, select Data Wizard... from the Data menu. You will be prompted to select a data source. Browse to a valid data file (or enter in the path to a data file) and click Next. The following window will be displayed. Data Wizard Screen 2 Data Wizard Screen 2 Select the fields you wish to import into &kst;. You may filter the list of fields by entering a string to match (wildcards such as * are supported) into the text box above the list. The Data Range section is used to specify the range of data to read from the selected vectors in the input file. The following discussion assumes knowledge of frames. For a detailed description of this concept, see File Formats. Starting frame, Count from end, Number of frames, and Read to end Using these four settings, the lower and upper boundaries of the data range can be set. For example, to read from frame 10 to frame 900, enter 10 for Starting frame and 890 for Number of frames. To read from frame 500 to the end of the file, enter 500 for Starting frame and select the Read to end option. To read only the last 450 frames from the file, select the Count from end option and enter 450 for Number of frames. The combinations used in the previous two examples are often useful for reading data from a file that is being updated in real time. Subsequent additions to the file are read, causing associated vectors to be updated as well. Read 1 sample per N frames and Boxcar filter first In addition to the lower and upper range boundaries, the samples to read from the selected range can be set. If Read 1 sample per N frames (where N is the entered value) is not selected, all samples in the selected range will be read. Alternatively, frames in the data file can be skipped by selecting Read 1 sample per N frames The value of the 1 sample that is used to represent a frame depends on whether or not Boxcar filter first is selected. If Boxcar filter first is not selected, the value is the same as the value of the 1st sample in the frame. If Boxcar filter first is selected, the value is the mean (average) of all the samples in that particular frame. Power Spectrum and X axis settings can be specified within the Plot Types section. These settings are described below. XY, Power Spectrum, and XY and Power Spectrum Select whether to plot the power spectrum only, data (XY) only, or both. If the power spectrum is selected for plotting, additional settings in this section become available. X Axis Vector The vector to be used as the independent vector for the plots. You may select a field from your data file, or the INDEX vector. The INDEX vector is simply a vector containing elements from 0 to N-1, where N is the number of frames in the data file. The FFT Options subsection in the Plot Types section is available only if a power spectrum is to be plotted. The below definitions assume basic knowledge of power spectra—for further details, refer to Numerical Recipes in C: The Art of Scientific Computing, published by Cambridge University Press. Interleaved average and FFT Length The power spectrum is defined as the square root of the absolute value of the mean of the interleaved Fast Fourier Transforms of length 2^x, where x is the value entered in the FFT Length selection box. Selecting Interleaved average allows the length of the interleaved Fast Fourier Transforms to be specified. If Interleaved average is unchecked, &kst; will determine the length based on the length of the vector. Data units and Rate units The units specified in these textboxes are used for the purpose of auto-generating axes labels for the plots. Sample rate The sample rate is used to generate the X axis of power spectrum plots. Apodize If this option is selected, the data is apodized using a Hanning window, to reduce bin-to-bin leakage. Remove Mean Select this option to remove the mean from the selected data (i.e. translate the data so that the mean is zero). Once you are satisfied with all the settings, click Next to advance to the next window. Select any filters you wish to apply to the data, and click Next to advance to the final window. Data Wizard Screen 3 Data Wizard Screen 3 From here, you can change general plotting settings. Most of the settings are self-explanatory. A brief overview of each section is provided below. Curve Style Select whether to plot data points only, lines connecting the data points only, or both. By default, lines are continuous with weight 0, and data points are marked using crosses. Line and data point colours are chosen so that curves with identical colours are minimized. Note that the curve style settings apply to both Power Spectra and XY plots. Curve Placement Select the plots to place the new curves on. Cycle through distributes the curves on the plots by cycling through the plots. Note that the curve placement settings apply to both Power Spectra and XY plots. Label Generation Select the desired labels and legends to be placed on the plots. Plot Placement Select the desired window(s) to place the new plots on. New windows can be created for the plots by selecting In new window. Once you are satisfied with all the settings, click Finish and the plots will be generated. The Data Manager The Data Manager provides a central location for adding, deleting, and modifying all the data objects used in &kst;. It can be accessed by selecting Data Manager from the Data menu. Creating New Data Objects To create a new data object from the Data Manager, click on one of the buttons listed under New:. A new window will be displayed, allowing options and settings for the data object to be set. You can also create new curves by right-clicking on a vector and choosing Make Curve... Since you are creating a new data object, you may enter a unique name to identify the object. The default name can be used as well (if it is unique). The settings for all plottable data objects except images have two common sections—Appearance and Placement (images only have the Placement section). These sections are described below. For data-specific settings, see Data Types. Appearance The Appearance section allows you to change the appearance of the data object when it is plotted. Clicking this button displays a colour chooser dialog box, which can be used to change the colour of both the lines and points. Show points Selecting this checkbox shows the data points used to plot the data object. The drop-down list to the right allows the shape of the points to be changed. Show lines Selecting this checkbox shows the lines joining the data points for the data object. The thickness of the line as well as the line style can be changed. Placement The Placement section specifies the plotting location of new plottable data objects. Plot window Specify the window in which to plot the data object. You may create a new window by clicking the New... button. Place in existing plot, Place in new plot and Do not place in any plot You can choose whether or not to immediately plot the data object on a new or existing plot. If Place in new plot is selected, you can also choose to re-arrange the layout of the plots by selecting re-grid and entering the number of columns to use for the new layout grid. Once all the desired settings for the new data object have been set, click the OK button to create the new data object. Editing and Deleting Existing Data Objects To edit an existing data object, simply highlight it in the Data Manager window and click the Edit button. The settings window for the selected object will be displayed. This window is identical to the one displayed when creating new data objects (with the exception that the Placement section may be absent), so refer to Creating New Data Objects for more information on the settings and options. To delete a data object, highlight it in the Data Manager window and click the Delete button. Note that the entry in the # Used column for an object must be 0 before the object can be deleted. The # Used column indicates the number of times that a particular data object and its children (if any) are used by either other data objects or by plots. Listed below are some consequences of this restriction to keep in mind when attempting to delete data objects. All plottable objects (curves, equations, histograms, power spectra, and images) must be removed from plots before they can be deleted. An object can be removed from a plot by right-clicking on it in the Data Manager window and selecting the desired plot from the Remove From Plot submenu. All data objects that use a particular data vector must be deleted before the data vector can be deleted. All children of a parent data object must be unused before the parent data object can be deleted. After a sequence of deletions and removals of plottable data objects from plots, you may find that there are numerous unused data objects displayed in the Data Manager. To quickly remove these objects, you can click the Purge button. Data Types There are nine main types of data objects in &kst;. Data objects can contain other data objects, as represented by the tree structure view in the Data Manager. The following diagram illustrates the relationships between the different data types. &kst; Data Types As can be seen from the above diagram, the curve, equation, histogram, power spectrum and image data objects are the only data objects that are plottable. All data objects (other than vectors) have the capability of using vectors, while equations, power spectra, events, and plugins all contain slave vectors. Descriptions of each data type are provided below, along with overviews of the settings and options available when creating or editing each type of data object. Settings common to almost all data types have been omitted—see Creating New Data Objects for more information. Vectors Vectors are one of the most often-used data objects in &kst;. As their name implies, vectors are simply ordered lists of numbers. Most often they contain the x or y coordinates of a set of data points. As vectors can be potentially quite large, it is a good idea to be aware of the amount of memory &kst; has allocated for use. The current available memory is displayed in the lower right corner of the status bar of the main &kst; window. If the status bar is not available, ensure that Show Statusbar is checked in the Settings menu. The following is a screenshot of the window displayed when creating or editing vectors. Explanations of the settings are listed below. Edit Vectors Edit Vectors Data Vector Parameters The source file and field to read can be set using the following options. File name The path to the desired data file. Clicking the button to the right displays a file browser window that can be used to graphically browse to the file. Field or column The field or column to create a vector from. Data Range This section specifies the range of data to use from the selected field for the data vector. Starting frame, Count from end, Number of frames, and Read to end Using these four settings, the lower and upper boundaries of the data range can be set. For example, to read from frame 10 to frame 900, enter 10 for Starting frame and 890 for Number of frames. To read from frame 500 to the end of the file, enter 500 for Starting frame and select the Read to end option. To read only the last 450 frames from the file, select the Count from end option and enter 450 for Number of frames. The combinations used in the previous two examples are often useful for reading data from a file that is being updated in real time. Subsequent additions to the file are read, causing associated vectors to be updated as well. Read 1 sample per and Boxcar filter first In addition to the lower and upper range boundaries, the samples to read from the selected range can be set. If Read 1 sample per is not selected, all samples in the selected range will be read. If Read 1 sample per is selected, only 1 sample per N frames will be read, where N is the number entered in selection box to the right. The value of the 1 sample that is used to represent a frame depends on whether or not Boxcar filter first is selected. If Boxcar filter first is not selected, the value is the same as the value of the 1st sample in the frame. If Boxcar filter first is selected, the value is the mean (average) of all the samples in that particular frame. Curves Curves are primarily used to create plottable objects from vectors. Curves are created from two vectors - an X axis vector and a Y axis vector, that presumably provide a set of data points. Thus, a curve can be thought of as a set of data points and the lines that connect them (even though the points or lines may not be visible on plots). The following is a screenshot of the window displayed when creating or editing curves. Explanations of the settings are listed below. Edit Curves Edit Curves Curve Contents The contents of the curve can be set from this section. X axis vector The vector to use for the independent (horizontal) axis. Y axis vector The vector to use for the dependent (vertical) axis. +X error bar and +Y error bar The vectors containing error values corresponding to the X axis vector and Y axis vector, respectively. The vectors should contain the sizes of the error bars in the same order as the data points. Use +X/Y error bar for -X/Y If this item is checked, the error bars are drawn symmetrically about the data point. To draw asymmetric error bars in the x or y direction, uncheck the box, and choose a vector for the length of the error bar below the data point in the -X/Y error bar combo box. -X/Y error bar The vector to use for the error bar below the data point. See the previous entry for more detail on using asymmetric error bars. Equations An equation data object consists of a mathematical expression and an independent variable. The expression is built using a combination of scalars, vectors, and operators, and usually represents the values of the dependent variable. The independent variable can be an existing vector or it can be generated when the equation object is created or edited. Since an equation ultimately consists of a set of data points, an equation object is plottable. The following is a screenshot of the window displayed when creating or editing equations. Explanations of the settings are listed below. Edit Equation Edit Equation Equation The mathematical expression representing the dependent variable can be modified from this section. Operators A list of available operators. Choosing an operator from the list inserts the operator at the current insertion point in the Equation text box. Vectors A list of the current vector objects in &kst;. Choosing a vector from the list inserts the vector at the current insertion point in the Equation text box. Scalars A list of the available scalar values. This list is composed of both the scalar values in the current &kst; session as well as some built-in constants. Choosing a scalar from the list inserts the scalar at the current insertion point in the Equation text box. Equation The mathematical expression representing the independent variable. You may manually type in this text box or you may select items to insert using the above drop-down lists. Independent Variable This section is used to specify the source of the values for the independent variable. Use Select this option to use an existing vector as the independent variable. Select a vector from the drop-down list, or quickly create a new one by clicking the button to the right. Interpolate to highest resolution vector Selecting this option interpolates the selected vector to the greatest number of samples possible. Generate Select this to generate a set of values to use as the independent variable. Specify the lowest value to generate in the From field, and the highest value to generate in the to field. Set the value for Number of samples to be the number of equally spaced values to generate between the lowest value and the highest value (inclusive). Histograms A histogram data object simply represents a histogram of a particular vector. Histogram objects are plottable. The following is a screenshot of the window displayed when creating or editing histograms. Explanations of the settings are listed below. Edit Equation Edit Equation Histogram Properties The source vector, as well as basic histogram properties, can be modified from this section. You can either manually specify settings or use the Auto Bin button. Data vector The data vector to create the histogram from. Although a vector is needed to create a histogram, the vector is treated as an unordered set for the purposes of creating a histogram. From and to The From field contains the left bound for the leftmost bin in the histogram. The to field contains the right bound for the rightmost bin in the histogram. Num bins Enter the total number of bins to use in the Num bins field. Auto Bin Instead of specifying values for From, to, and Num bins, you can click Auto Bin to automatically generate values for all three fields based based on the lowest and highest values, as well as the number of elements found in the source vector. Y Axis Normalization This section is used to specify the type of normalization used for the y axis of the histogram. Number in bin Selecting this option causes the y axis to represent the number of elements in each bin. Fraction in bin Selecting this option causes the y axis to represent the fraction of elements in each bin out of the total number of elements. Percent in bin Selecting this option causes the y axis to represent the percentage of elements (out of the total number of elements) in each bin. Peak bin = 1.0 Selecting this option causes the y axis to represent the number of elements in each bin divided by the number of elements in the largest bin (the bin with the greatest number of elements). In other words, the y axis is normalized to 1.0. Power Spectra A power spectrum data object represents the power spectrum of a vector, defined as the square root of the absolute value of the mean of the interleaved Fast Fourier Transforms of length 2^x of the vector, where x is the value entered in the FFT Length selection box. The below definitions assume basic knowledge of power spectra—for further details, refer to Numerical Recipes in C: The Art of Scientific Computing, published by Cambridge University Press. Power Spectra Window Power Spectra Window Curve Contents The source vector, as well as basic power spectrum properties, can be modified from this section. Data vector The data vector to create a power spectrum from. Interleaved average and FFT Length Selecting Interleaved average allows the length of the interleaved Fast Fourier Transforms to be specified. The length is specified as a power of 2. If Interleaved average is unchecked, &kst; will determine the length based on the length of the vector. Data units and Rate units The units specified in these textboxes are used for the purpose of auto-generating axes labels for the plots. Sample rate The sample rate is used to generate the X axis of power spectrum plots. Apodize If this option is selected, the data is apodized using a Hanning window, to reduce bin-to-bin leakage. Remove Mean Select this option to remove the mean from the selected data (i.e. translate the data so that the mean is zero). Plugins A plugin data object represents a &kst; plugin. All plugins have a common format, and show up as type Plugin in the Data Manager. For more information about plugins, please see Plugins and Filters Event Monitors An event monitor data object represents an instance of an event monitor. For more information on monitoring of events, see Event Monitoring. Matrices A matrix represents a set of three-dimensional data points (x, y, z) arranged in a two-dimensional grid. The z values of the matrix are obtained from a vector, and the grid structure is manually specified using the Edit or New Matrix dialog. The descriptions below refer to the following diagram depicting &kst;'s matrix structure. A screenshot and explanation of the matrix dialog follow. Matrix Window Matrix Window Vector Selection Z Vector The data vector to obtain the z values from. Grid Parameters X Minimum and Y Minimum The origin of the matrix is specified by the coordinates (X Minimum, Y Minimum). The location of the origin is represented by a red circle in the above diagram. X Step Size and Y Step Size These two values specify the dimensions of each rectangular cell in the matrix grid. All cells in the matrix have identical dimensions. Dimensions and Use maximum x length Enter the number of steps for the x dimension of the matrix, followed by the number of steps for the y dimension of the matrix. If Use maximum x length is checked, the x dimension of the matrix will be determined based on the length of the vector and the entered y dimension. If this option is checked and the length of the vector subsequently changes, the x dimension of the matrix will be updated accordingly. Note that the minimum allowed y dimension is 1, while the minimum allowed x dimension is 0. Images Images are graphical representations of Matrices. Images can be plotted as color maps, contour maps, or both. Image Window Image Window Matrix Selection Matrix Select the matrix to use for this image. New matrices can be created by clicking on the button to the right. Image Type Color Map, Contour Map, and Color Map and Contour Map Select the type of image to be plotted. Changing this selection enables or disables sections of the image dialog as appropriate. Color Map Parameters A color map represents the z value of each cell in the matrix using a color. This section is only available if Color Map or Color Map and Contour Map is selected under Image Type. Color palette Select the color palette to use for the color map. By default, two palettes suitable for color maps are installed by &kst;—Kst Grayscale 256 (a 256 color grayscale palette) and Kst Spectrum 1021 (a 1021 color rainbow spectrum that ranges from blue to red). Additional palettes can be installed by simply copying GIMP compatible palette files to the colors subdirectory of the user configuration directory (for example, /usr/share/config/colors/). Note that saved images using a non-default palette may not be viewable by other users of &kst; if they do not have the required palette. In such cases, a default grayscale palette is used instead. Lower Z threshold, Upper Z threshold and Auto Threshold Enter the lower and upper thresholds to use for the mapping of colors. Palette colors are evenly distributed between Lower Z threshold and Upper Z threshold. Any cells in the selected matrix with z values less than Lower Z threshold are mapped to the first color in the palette. Any cells in the selected matrix with z values greater than Upper Z threshold are mapped to the last color in the palette. Clicking Auto Threshold will fill in the lower and upper threshold values using the least and greatest z values found in the selected matrix. Contour Map Parameters A contour map draws a set of lines, with each line representing a certain z value. This section is only available if Contour Map or Color Map and Contour Map is selected under Image Type. Number of contour levels Select the number of contour levels to use. The contour levels will be distributed evenly between the lowest and highest z values found in the matrix. Color Select the color to use for the contour lines. Clicking this button displays a standard &kde; color chooser dialog. Weight and Use variable line weight Select the weight, or thickness of the contour lines. If Use variable line weight is selected, contour lines representing higher elevations are drawn thicker than those representing lower elevations. Use discretion when selecting this option, as images with high contour line densities may become unreadable. The Data Menu The Data menu provides quick access to many features related to data objects in &kst;. Most of the menu functions duplicate functions found elsewhere, so only brief descriptions are provided below. Reload Reloads all data vectors from their source files. Data Wizard... Displays the Data Wizard. Data Manager Displays the Data Manager. New [data object] Displays the corresponding dialog for creating the data object. Refer to Data Types for descriptions of each dialog. View Scalars Displays a dialog from which the values of all the scalars in the current &kst; session can be viewed. The dialog is updated dynamically if the values change. View Vectors Displays a dialog from which the values in all the current vectors can be viewed. Select a vector to view using the drop-down list. The dialog is updated dynamically if the values change. View Fit Results Displays a dialog which shows all the resulting values from performed fits. Select a fit result to view using the drop-down list. The dialog is updated dynamically if the values change. Change Data File Displays a dialog for quickly changing data files that vectors are associated with. Select the vectors to change, and then browse to a different data file. Click Apply to save the changes. kst-2.0.3/docbook/kst/commandline-chapter.docbook000644 001750 001750 00000020650 11544160206 022370 0ustar00synthsynth000000 000000 Barth Netterfield
kst@omega.astro.utoronto.ca
Command Line Usage and Examples A typical use of kst is from the command line to make X-Y plots or Z images from data files. kst can read ascii data, readdata/dirfile compatible binary files, and optionally (with external libraries) FITS images, PIOLib files, netCDF files, and HEALPix FITS files. &kst; Command Line Synopsis kst A plotting and data viewing program The options are: kst Qt-options KDE-options options file Options A .kst file, or one or more data files. Supported formats are ASCII columns, BOOMERANG frame files, BLAST dirfile files, and other optionally supported types. A .kst files stores all options that can be set by other flags. The following flags can be used to override the options set in the .kst file: , , , , . The rest can not be overridden. If an override flag is given, it is applied to all vectors in the plot. ASCII data from stdin can be plotted by including "stdin" in the list . The source for the Y axis data. For ASCII files, this is the column. For binary files, this is the field name. To plot multiple curves, this may be specified multiple times. The same source file, sample ranges, and X axis data are assumed. Error bars for Y axis data. For ASCII file, refer to the column holding the data. For binary files use the field name. If multiple options are given, this may also be used multiple times. Individual Y entries are associated in order with multiple E entries. The source for the X axis data. For ASCII files, this is the column. For readata files, this is the field name. If this option is not specified, the row number in the file is used. This option can only be given once. The source for the Z matrix data (which gets displayed as an image). For ASCII files, this is the column containing the z data. For other optional formats (HEALPix, FITS image, etc), this is the name of the desired matrix field, as displayed in the matrix dialog. Some matrix-compatible datasources also allow using an alias which is the number of the desired matrix field. To plot multiple matrices, this may be specified multiple times. The source for power spectra. For ASCII files, this is the column. For binary files, this is the field name. To plot power spectra of multiple curves, this may be specified multiple times. The same source file, sample ranges and fft lengths are used for all Power Spectra requested from the command line. The length of the FFT used in power specra estimation is 2^P. The source for histograms. For ASCII files, this is the column. For binary files, this is the field name. Multiple histograms can be defined from the command line. Used when multiple curves have been defined. Rather than plotting all curves in the same plot, plot each in its own plot, The starting frame number (for readdata files) or row (for ASCII files) to read. The number of frames (for readdata files) or rows (for ASCII files) to read. The number of frames or rows to skip each read. This is useful when working with very large data files, to speed up response and conserve memory, in the case that the data are slowly varying. Used in with the : rather than skipping each NS frames, average them. This provides a combination of very basic high pass filtering, and memory conservation. Override the file to read the data from for all vectors listed in the .kst file. Can only be used in conjunction with a kst file. Rather than displaying the plot, export the image to a postscript file and exit. *BUG note: even though no windows are opened on screen, access to the X server is still required.* Rather than displaying the plot, export the image to a png file of dimensions 640x480 and exit. *BUG note: even though no windows are opened on screen, access to the X server is still required.* Command Line Examples Several examples of typical use follow. To plot column 1 a file (tmp.dat) of ASCII data: kst -y 1 tmp.dat To plot column 2, 3, and 4 vs. column 1 of an ASCII file, in 1 plot: kst -x 1 -y 2 -y 3 -y 4 tmp.dat To plot column 2, 3, and 4 vs. column 1 of an ASCII file, in 3 plots, arranged in 1 column: kst -x 1 -y 2 -y 3 -y 4 -m 1 tmp.dat To plot 500 rows of column 2 of an ASCII file, starting at line 100: kst -y 2 -f 100 -n 500 tmp.dat To plot the first 100,000 rows of column 2 of an ASCII file, averaging every 100 rows: kst -y 2 -f 0 -n 100000 -s 100 -a tmp.dat (Using optional HEALPix Data Source) To plot the first 3 maps in a HEALPix FITS file in a 2x2 grid: kst -z 1 -z 2 -z 3 -m 2 healpix_example_sm.fits (Using optional HEALPix Data Source) To plot a map with a specific field name in a HEALPix FITS file: kst -z "1 - TEMPERATURE (Kelvin)" healpix_example_sm.fits
kst-2.0.3/docbook/kst/Screenshot-kst-eventmonitor.png000644 001750 001750 00000014417 11544160206 023271 0ustar00synthsynth000000 000000 PNG  IHDR(PLTEE#'F炵{rocca^[ZZYTRRSUSQKJJJJIBAAAAA@:-99:<==84~5|;|BILNQYabbcjb:| u~^GxU_uMdKhJiIjEo;o7n7k0`/]-[%M|!L{!L{!L{!Kz Ky Ai =b;]3N-5>0/2-.1 %*8 tRNSߡ4:IDATxOiq2xs4GX>I_ _C3rL˘d"OyɅMoO9z(Kv0[8?M,wiwo{M yy=q+V<?Ioכ kܛH Xއ!FhKބ3EroIU(Ll\_߻޸OIr+ɗK&Er̳͓ '\9>x] q^v0͛)G7GF{㣻Ûtb emҵk\nuo>oۧ7>wsny'=]Oh?㣻F5$OKo3,yp26ɔ# Щnb\g]% r]'t/F9A9A9#ȑm>"ٌ棿z1%o=R/}r6(-%7uNK\mSGfB.+'HwC[oޒhFJɥ1r߅"' Α",9%$"0mA.)rU.RW1r:(ĄU.KFněKei%DYRGtheTIBPJs*'u)^碵MD]!cE-!WRN_Rk[ 9gȝ%erXRj쉵%4 ǖK+L.KBPj~*)OiӠWƿn\\4Tr5R&{rI\4TrER*Ƃj;qPZBC9r9ȼNO핳?ף#t:B+GGlWDGH;>2r`0h!f_PNKcbE9:B;>\)2PG ZCۈz ڊ'|"yZ:++-چny:BZJh(0TzVk'NGaLJ6e\J#ʔl[E#U{ijP)9r9r|Rk5-G/OKw] 9SNXu-a$'SW&$r'On8 Ÿ᰾y-!aG0JHqGO =ullՖJu\WdKPyw kD햔ZƵ5Qsiwi:\ [*XIc> rQkʉ&Wi@]n =vaPSc@vHCGONGϥCJV?+xsɱe‰@72`܎_nZB/OKRŸVRǓ[*ӇFGϥ0ij^^2=޷<_}y^2=-f^rc:cPEA rȑUwqýL&I}(.r! 9)upfZ$:m,Iׯu9Q+v6|k:r~m1̼ kl?gp.vn-, \sr-ǖcKa?C!G9CCp1 sS:Br!G#!ǻ)4:OCV3N6\[*}.sTVe'FtI4ȵAɞ9+ 9nsA$r]8,R~zlǖqlȵ33["rrTO Gu:u(=r!G#!G#Sہp;c<:p69҉ A A \(F>4''6HAriH e+}!I SD_2=XJcL's u}s9ֹE[>\wsbZ:sf-9-ɥ&ƢoC鎾I9܄^NVaTr:G#!G#!r9r r9'Ù _Ou0'kk9sdknz1$x3~aDi䞼{cܵcao X$ֹw<')T;ѳۦcq-(~#s$x13$rZRE~[/KoDZqsܐV/kqU&t' Q!S++2Cd )/'ݔKש\*w1ܭ'ҷ-. >VyzK֗eN=b 9mRrΐ-,rG/ɉcԪxRr"9,QJ.|Pr~L%X~.7dJSH8|Hr:/3BґcSq9c-O/ ZscK1sֿGϝYU}+Ԛ;᫮ 2zsi\ߦ= %XPE-asf}2>sfr9C GC GC9rc1B#4##+8wR<sGT874E쬐H"F1m19f%O;f[aװAN"sω+>8'o..rIxX(>1C5FH89aJbeֹ .~N]9k87dv##739A9##ȑn˩'5"e 2A9rTG%7s!7W1B,UzȵS.#lr%id5oVQ䎏̷ۣO.ر=J a\ry^ȵH. :*wf%/\2ƙ9JrMuEr1BR'sP 8[r|Wrݖp ׎ĩCj j9#]锛SΧ_!\DrVI.rOkv9`Eֹ2r<+CND97ȵYNHgkّs`':"G#!r9r9r!G#mۘy܆#g3˲ K3 rEr5kJε,J/Ky,EܱDN2rN^%{$~S+gBcqu.@" LSZ$nWpNEyA6tXk0rG"wrZV.•r٫|U˙}E^erPb"%[.r%h "g949!W(w*Ι@3-\G?ݒJ \%Uˏm;[-R~ɝKҮ˛qYQ#qVlɽf镙~Wpzuf,!|P.,ԡPA A rrr!A A rrr!A A rrt-#ё6FɑN9r9rDrܘy! 78+ؠCbL9Q.*8"r}>hq9ۘg1* \UQŶ1EK\(\MQcre ''Cnvrү&?Vِ+grV'YرbZ4+x9X4XGEܘQsJ> rq|%< \eQ6Rl*?Vp2Bp6~pՖ+3o层Ǐ \U*&V{Te*wz=+7ɘ+rCRmߴec#W/R'!G#!G#!r9rr3^tpW y'IENDB`kst-2.0.3/build-kst.bat000755 001750 001750 00000000060 11544160206 015255 0ustar00synthsynth000000 000000 mkdir build cd build qmake -r ../kst.pro nmake kst-2.0.3/svn2cl.xsl000644 001750 001750 00000015104 11544160206 014630 0ustar00synthsynth000000 000000 * , kst-2.0.3/pch.h000644 001750 001750 00000000222 11544160206 013607 0ustar00synthsynth000000 000000 #include #include #include #if defined __cplusplus #include #include #include #endif kst-2.0.3/run-tests000755 001750 001750 00000000152 11544160206 014560 0ustar00synthsynth000000 000000 #!/bin/sh cd `dirname $0` export SCRIPTDIR=$PWD export BUILDDIR=$PWD/build $BUILDDIR/bin/runtests "$@" kst-2.0.3/ChangeLog000644 001750 001750 00001143357 11544160206 014460 0ustar00synthsynth000000 000000 ------------------------------------------------------------------------ r1029763 | netterfield | 2009-09-30 13:27:12 -0400 (Wed, 30 Sep 2009) | 2 lines Updated release notes ------------------------------------------------------------------------ r1029756 | netterfield | 2009-09-30 13:06:13 -0400 (Wed, 30 Sep 2009) | 3 lines Get rid of old tests in the branch. ------------------------------------------------------------------------ r1029752 | netterfield | 2009-09-30 12:59:26 -0400 (Wed, 30 Sep 2009) | 3 lines Branch for beta3. This should be a very usable branch. ------------------------------------------------------------------------ r1029745 | netterfield | 2009-09-30 12:41:05 -0400 (Wed, 30 Sep 2009) | 4 lines Remove 1.x data sources from 2.0 tree. They are still in the 1.x tree, and can be ported from there. ------------------------------------------------------------------------ r1029651 | netterfield | 2009-09-30 08:53:06 -0400 (Wed, 30 Sep 2009) | 3 lines 'Improve' some defaults. ------------------------------------------------------------------------ r1029608 | netterfield | 2009-09-30 06:39:00 -0400 (Wed, 30 Sep 2009) | 3 lines Default system for plots and dialogs. ------------------------------------------------------------------------ r1027349 | netterfield | 2009-09-23 17:29:37 -0400 (Wed, 23 Sep 2009) | 5 lines Multiple edit for legends. Some improvements to legend dialog. Some improvements to plot dialog. ------------------------------------------------------------------------ r1025501 | netterfield | 2009-09-18 18:40:54 -0400 (Fri, 18 Sep 2009) | 3 lines Move some devel docs around. Save legend status in the kst file. ------------------------------------------------------------------------ r1024901 | netterfield | 2009-09-17 10:05:09 -0400 (Thu, 17 Sep 2009) | 6 lines Fix names in basicplugin. Get rid of inf() warning. Fix legend placement. Basic multi-edit functionality for legends. ------------------------------------------------------------------------ r1024048 | netterfield | 2009-09-15 17:09:58 -0400 (Tue, 15 Sep 2009) | 2 lines Fix broken short names. ------------------------------------------------------------------------ r1023551 | netterfield | 2009-09-14 18:21:09 -0400 (Mon, 14 Sep 2009) | 6 lines Part way into 'edit multiple' for view items. -View items are now named objects -Start some work to reduce cross section for editing a deleted plot. -Create a macro that can produce a list of items of a desired type. ------------------------------------------------------------------------ r1020002 | netterfield | 2009-09-04 20:35:00 -0400 (Fri, 04 Sep 2009) | 8 lines Delete old files stored here from the 1.x branch (if you want it, get it from the 1.x branch) Remove dead code. Fix the ascii read file bug. ------------------------------------------------------------------------ r1011565 | netterfield | 2009-08-15 00:12:29 -0400 (Sat, 15 Aug 2009) | 4 lines Update dialog defaults lists Fix rotated axis number label positioning ------------------------------------------------------------------------ r1008715 | netterfield | 2009-08-08 02:20:52 -0400 (Sat, 08 Aug 2009) | 3 lines Fix some file dialog behaviors... ------------------------------------------------------------------------ r1007685 | netterfield | 2009-08-06 00:19:12 -0400 (Thu, 06 Aug 2009) | 3 lines More fixups for line/arrow resize/move behaviour. ------------------------------------------------------------------------ r1007008 | netterfield | 2009-08-04 17:25:22 -0400 (Tue, 04 Aug 2009) | 3 lines Fix the drifting line bug... ------------------------------------------------------------------------ r1005451 | netterfield | 2009-08-01 00:59:29 -0400 (Sat, 01 Aug 2009) | 4 lines Better defaults for graphics export dialog. Fix parenting and resizing bugs (except lines). ------------------------------------------------------------------------ r1004417 | netterfield | 2009-07-30 02:40:55 -0400 (Thu, 30 Jul 2009) | 5 lines Fix drifting Y label bug. Add attribute for grid line width. Copy more plot styles when adding a plot to a view. ------------------------------------------------------------------------ r1002072 | fenton | 2009-07-24 17:14:46 -0400 (Fri, 24 Jul 2009) | 2 lines Add Build System overview for Kst. ------------------------------------------------------------------------ r1002051 | fenton | 2009-07-24 16:44:46 -0400 (Fri, 24 Jul 2009) | 2 lines Remove overlapping CONFIG setting. ------------------------------------------------------------------------ r1001896 | fenton | 2009-07-24 09:06:53 -0400 (Fri, 24 Jul 2009) | 2 lines Update Release procedure. ------------------------------------------------------------------------ r1001544 | netterfield | 2009-07-23 11:39:58 -0400 (Thu, 23 Jul 2009) | 3 lines Report some new bugs :-( ------------------------------------------------------------------------ r1001494 | fenton | 2009-07-23 08:59:47 -0400 (Thu, 23 Jul 2009) | 2 lines Fix plot drawing errors when plot's view rect strays from (0, 0) ------------------------------------------------------------------------ r1001361 | netterfield | 2009-07-22 20:29:56 -0400 (Wed, 22 Jul 2009) | 4 lines Update bug lists. Fixes for printing (seems pretty good now) ------------------------------------------------------------------------ r1001287 | fenton | 2009-07-22 16:25:57 -0400 (Wed, 22 Jul 2009) | 2 lines Update DEVNOTES. ------------------------------------------------------------------------ r1001282 | fenton | 2009-07-22 15:54:37 -0400 (Wed, 22 Jul 2009) | 2 lines Add view based plot font default settings. ------------------------------------------------------------------------ r1001227 | fenton | 2009-07-22 13:59:06 -0400 (Wed, 22 Jul 2009) | 2 lines Add examples to INSTALL. ------------------------------------------------------------------------ r1001072 | fenton | 2009-07-22 11:36:57 -0400 (Wed, 22 Jul 2009) | 2 lines Fix Windows command line exiting / help display. ------------------------------------------------------------------------ r1000785 | netterfield | 2009-07-21 20:58:43 -0400 (Tue, 21 Jul 2009) | 3 lines Update bug list: some new bugs... ------------------------------------------------------------------------ r1000784 | netterfield | 2009-07-21 20:44:32 -0400 (Tue, 21 Jul 2009) | 4 lines Some improvements to printing. But it still prints at 72dpi, which is inadequate. ------------------------------------------------------------------------ r1000623 | fenton | 2009-07-21 13:44:03 -0400 (Tue, 21 Jul 2009) | 2 lines Update install doc. ------------------------------------------------------------------------ r1000539 | fenton | 2009-07-21 10:33:33 -0400 (Tue, 21 Jul 2009) | 3 lines Add new install-kst script. Update installation documentation. ------------------------------------------------------------------------ r1000095 | netterfield | 2009-07-20 16:15:40 -0400 (Mon, 20 Jul 2009) | 3 lines Report bug as fixed ------------------------------------------------------------------------ r1000073 | netterfield | 2009-07-20 15:38:33 -0400 (Mon, 20 Jul 2009) | 3 lines Fix a bug with data mode and offset marker... ------------------------------------------------------------------------ r1000055 | fenton | 2009-07-20 14:55:08 -0400 (Mon, 20 Jul 2009) | 2 lines Switch printer mode to ScreenResolution. ------------------------------------------------------------------------ r999942 | fenton | 2009-07-20 12:25:12 -0400 (Mon, 20 Jul 2009) | 3 lines Update build system to support INSTALL_PREFIX INSTALL_LIBDIR and only set QMAKE_RPATH when in debug mode. ------------------------------------------------------------------------ r999909 | netterfield | 2009-07-20 11:26:38 -0400 (Mon, 20 Jul 2009) | 2 lines Printing Bug (showstopper) ------------------------------------------------------------------------ r999886 | fenton | 2009-07-20 10:37:46 -0400 (Mon, 20 Jul 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r999796 | fenton | 2009-07-20 09:52:34 -0400 (Mon, 20 Jul 2009) | 2 lines Fix crash when reloading settings dialog. ------------------------------------------------------------------------ r998454 | netterfield | 2009-07-17 13:19:26 -0400 (Fri, 17 Jul 2009) | 7 lines Report a new bug (a crash case...) Update bugs. Fix axis label round-off errors Fix tick count reduction (to avoid overlap). Fix tick scaling/position (to avoid overlap). ------------------------------------------------------------------------ r997289 | fenton | 2009-07-15 13:54:19 -0400 (Wed, 15 Jul 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r997283 | fenton | 2009-07-15 13:48:31 -0400 (Wed, 15 Jul 2009) | 3 lines Add reworked config saving for ascii plugin including global default flag / setting. Fix loading of .kst with ascii settings when file information is not in settings. ------------------------------------------------------------------------ r996831 | netterfield | 2009-07-14 19:36:10 -0400 (Tue, 14 Jul 2009) | 5 lines Update bugs Fix mean centered mode. Fix precision in plot dialog range tab. ------------------------------------------------------------------------ r996598 | fenton | 2009-07-14 10:50:13 -0400 (Tue, 14 Jul 2009) | 2 lines Move settings to native / default locations in the UserScope. ------------------------------------------------------------------------ r995951 | fenton | 2009-07-13 10:58:17 -0400 (Mon, 13 Jul 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r995949 | fenton | 2009-07-13 10:52:41 -0400 (Mon, 13 Jul 2009) | 2 lines Turn off debugging. ------------------------------------------------------------------------ r994600 | netterfield | 2009-07-10 16:39:14 -0400 (Fri, 10 Jul 2009) | 4 lines Fix plot dialog setting Y mean centered zoom mode. X mean centered zoom mode not fixed yet. ------------------------------------------------------------------------ r994570 | fenton | 2009-07-10 14:43:05 -0400 (Fri, 10 Jul 2009) | 2 lines Apply origin plot zoom before applying SharedAxisBox zoom for zooms that may change non-shared axis. ------------------------------------------------------------------------ r994394 | fenton | 2009-07-10 10:57:05 -0400 (Fri, 10 Jul 2009) | 2 lines Revert enforceMin change allow corner case label overlap to ensure minimum ticks are enforced. ------------------------------------------------------------------------ r993952 | netterfield | 2009-07-09 15:46:05 -0400 (Thu, 09 Jul 2009) | 4 lines New bugs Some minor fixes to plot axis numbers. There are more to go... ------------------------------------------------------------------------ r993884 | fenton | 2009-07-09 11:47:31 -0400 (Thu, 09 Jul 2009) | 2 lines Update window title. ------------------------------------------------------------------------ r993806 | fenton | 2009-07-09 10:40:28 -0400 (Thu, 09 Jul 2009) | 2 lines Fix sizing of PlotItemDialog by limiting the growth of the dialog. ------------------------------------------------------------------------ r993601 | netterfield | 2009-07-08 20:42:17 -0400 (Wed, 08 Jul 2009) | 3 lines Report new bug. ------------------------------------------------------------------------ r993490 | fenton | 2009-07-08 15:21:19 -0400 (Wed, 08 Jul 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r993479 | fenton | 2009-07-08 14:49:08 -0400 (Wed, 08 Jul 2009) | 2 lines Fix updates for Selector Widgets when changes happen in other dialogs. ------------------------------------------------------------------------ r992828 | fenton | 2009-07-07 15:19:13 -0400 (Tue, 07 Jul 2009) | 2 lines Remove maximum check and replace with minimum check on calculating tick spacing to prevent overlap when reducing the tick count programmatically. ------------------------------------------------------------------------ r992678 | fenton | 2009-07-07 11:20:32 -0400 (Tue, 07 Jul 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r992677 | fenton | 2009-07-07 11:17:13 -0400 (Tue, 07 Jul 2009) | 5 lines Remove TiedZoom support from SharedAxisBoxItem. Add KeyPlot to SharedAxisBoxItem for displaying TiedZoom in ShareX & ShareY mode. Fix RMB Menu for PlotItem. Fix Tied Zoom with plots outside of the SharedAxisBoxItem. ------------------------------------------------------------------------ r988395 | netterfield | 2009-06-27 21:59:03 -0400 (Sat, 27 Jun 2009) | 3 lines Update bugs ------------------------------------------------------------------------ r987889 | fenton | 2009-06-26 16:51:16 -0400 (Fri, 26 Jun 2009) | 3 lines Convert Dialogs to modeless. Fix AboutDialog linking. ------------------------------------------------------------------------ r987829 | fenton | 2009-06-26 14:13:22 -0400 (Fri, 26 Jun 2009) | 2 lines Fix signal. ------------------------------------------------------------------------ r987430 | netterfield | 2009-06-25 23:54:19 -0400 (Thu, 25 Jun 2009) | 3 lines Update bugs (related to shared axis boxes) ------------------------------------------------------------------------ r986540 | fenton | 2009-06-24 14:28:55 -0400 (Wed, 24 Jun 2009) | 2 lines Prevent too many ticks being drawn when limiting the ticks due to label size constraints. ------------------------------------------------------------------------ r985917 | fenton | 2009-06-23 14:51:11 -0400 (Tue, 23 Jun 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r985916 | fenton | 2009-06-23 14:49:01 -0400 (Tue, 23 Jun 2009) | 4 lines Add independent tied zoom for PlotItems inside of a SharedAxisBox. Connect hotkeys for SharedAxisBox options. Fix drawing of invalid PlotRects. ------------------------------------------------------------------------ r983670 | fenton | 2009-06-18 15:17:49 -0400 (Thu, 18 Jun 2009) | 2 lines Fix missing brace. ------------------------------------------------------------------------ r983666 | fenton | 2009-06-18 15:09:18 -0400 (Thu, 18 Jun 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r983665 | fenton | 2009-06-18 15:08:46 -0400 (Thu, 18 Jun 2009) | 2 lines Cleanup LabelBuilder based warnings. ------------------------------------------------------------------------ r983641 | fenton | 2009-06-18 13:14:11 -0400 (Thu, 18 Jun 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r983639 | fenton | 2009-06-18 13:13:21 -0400 (Thu, 18 Jun 2009) | 2 lines Reduce significant digit count for log axis. ------------------------------------------------------------------------ r983606 | fenton | 2009-06-18 10:37:57 -0400 (Thu, 18 Jun 2009) | 4 lines Fix inverse drawing of plots creating an invalid PlotRenderItem size. Prevent drawing attempts of invalid PlotRenderItems. Standardize all Plots after the final draw of the PlotItem and only if rect() is valid. ------------------------------------------------------------------------ r983223 | fenton | 2009-06-17 15:48:42 -0400 (Wed, 17 Jun 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r983220 | fenton | 2009-06-17 15:43:20 -0400 (Wed, 17 Jun 2009) | 3 lines Re-label Fill Dialog in Application Settings. Add proper updating of View/PlotItem when changes are made in General/Grid Tabs of application settings. ------------------------------------------------------------------------ r983070 | fenton | 2009-06-17 10:28:38 -0400 (Wed, 17 Jun 2009) | 2 lines Eliminate extra re-draw when unmarking as dirty. ------------------------------------------------------------------------ r983046 | fenton | 2009-06-17 10:18:01 -0400 (Wed, 17 Jun 2009) | 2 lines Bug list update. ------------------------------------------------------------------------ r983000 | fenton | 2009-06-17 09:40:23 -0400 (Wed, 17 Jun 2009) | 3 lines Fix load of document triggering a dirty document. Remove PlotRenderItem geometry changes from dirty document tracking. ------------------------------------------------------------------------ r982947 | netterfield | 2009-06-17 06:16:56 -0400 (Wed, 17 Jun 2009) | 4 lines Clean up/clarify bug list. Close some bugs ------------------------------------------------------------------------ r982791 | fenton | 2009-06-16 16:06:55 -0400 (Tue, 16 Jun 2009) | 2 lines Apply layout changes to ChangeDataSampleDialog. ------------------------------------------------------------------------ r982724 | fenton | 2009-06-16 13:58:19 -0400 (Tue, 16 Jun 2009) | 3 lines Fix layout bugs associated with multiple columns / rows in SharedAxisBoxes. Add immediate sharing update when switching ShareX/ShareY settings. ------------------------------------------------------------------------ r982683 | netterfield | 2009-06-16 11:50:21 -0400 (Tue, 16 Jun 2009) | 3 lines Update bug lists and wishlists: in particular, clarify shared axis. ------------------------------------------------------------------------ r982487 | netterfield | 2009-06-15 19:18:28 -0400 (Mon, 15 Jun 2009) | 3 lines Improve axis number roundoff a little. There is more to go! ------------------------------------------------------------------------ r982339 | fenton | 2009-06-15 10:49:09 -0400 (Mon, 15 Jun 2009) | 2 lines Fix disconnect between ShareX / ShareY controlled zoom and SharedAxisBoxItem tied zoom. ------------------------------------------------------------------------ r981137 | netterfield | 2009-06-12 16:47:46 -0400 (Fri, 12 Jun 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r981025 | fenton | 2009-06-12 14:50:12 -0400 (Fri, 12 Jun 2009) | 2 lines Fix crash when de-selecting draw based action. ------------------------------------------------------------------------ r980842 | fenton | 2009-06-12 12:04:40 -0400 (Fri, 12 Jun 2009) | 2 lines Fix typo. ------------------------------------------------------------------------ r980840 | netterfield | 2009-06-12 11:58:13 -0400 (Fri, 12 Jun 2009) | 3 lines 'I' key adjusts image color ranges. ------------------------------------------------------------------------ r980827 | fenton | 2009-06-12 11:21:31 -0400 (Fri, 12 Jun 2009) | 2 lines Improve interface for ChangeFileDialog. ------------------------------------------------------------------------ r979984 | fenton | 2009-06-10 16:50:33 -0400 (Wed, 10 Jun 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r979962 | fenton | 2009-06-10 16:19:55 -0400 (Wed, 10 Jun 2009) | 8 lines Rework Shared Axis Box / Tied Zoom. - Separate x / y Tied Zoom. - Remove internal Shared Axis Box Tied Zoom - Replace with special handling. - Make Share x / Share y configurable - Fix breaking of Shared Axis Box on zoom changes. Redo saving of ranges in PlotItemDialog. Add new zoom modes. ------------------------------------------------------------------------ r979912 | fenton | 2009-06-10 14:33:11 -0400 (Wed, 10 Jun 2009) | 2 lines Add new bugs. ------------------------------------------------------------------------ r979521 | netterfield | 2009-06-09 22:47:14 -0400 (Tue, 09 Jun 2009) | 3 lines Update description of shared axis boxes. ------------------------------------------------------------------------ r979399 | fenton | 2009-06-09 13:40:18 -0400 (Tue, 09 Jun 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r979104 | netterfield | 2009-06-08 18:28:46 -0400 (Mon, 08 Jun 2009) | 2 lines New tab option in curve placement widget. ------------------------------------------------------------------------ r977910 | netterfield | 2009-06-05 12:01:08 -0400 (Fri, 05 Jun 2009) | 6 lines - Start 'new tab' ui work in curve placement widget. - set version number for libraries, to allow kst2 to be installed with kst1 on certain systems. ------------------------------------------------------------------------ r977552 | fenton | 2009-06-04 12:06:53 -0400 (Thu, 04 Jun 2009) | 3 lines Convert to region based tick label spacing validation. Add font autoscaling for tick labels. ------------------------------------------------------------------------ r977363 | netterfield | 2009-06-03 18:57:42 -0400 (Wed, 03 Jun 2009) | 2 lines New Tab related options in the data wizard. ------------------------------------------------------------------------ r977202 | fenton | 2009-06-03 10:54:05 -0400 (Wed, 03 Jun 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r977188 | fenton | 2009-06-03 10:40:04 -0400 (Wed, 03 Jun 2009) | 2 lines Remove dialog delete code. ------------------------------------------------------------------------ r977178 | fenton | 2009-06-03 10:35:52 -0400 (Wed, 03 Jun 2009) | 2 lines Fix Dialog ListWidget growing indefinitely. ------------------------------------------------------------------------ r976770 | fenton | 2009-06-02 11:29:44 -0400 (Tue, 02 Jun 2009) | 2 lines Add automatic minor tick count. ------------------------------------------------------------------------ r976467 | fenton | 2009-06-01 14:47:41 -0400 (Mon, 01 Jun 2009) | 2 lines Update PlotItemDialog saveRange to correctly save if in Axis Log mode. ------------------------------------------------------------------------ r976456 | fenton | 2009-06-01 14:14:04 -0400 (Mon, 01 Jun 2009) | 2 lines Update buglist and unmark tab based bugs. ------------------------------------------------------------------------ r976406 | netterfield | 2009-06-01 11:51:05 -0400 (Mon, 01 Jun 2009) | 4 lines Update bug list start to implement new page in data wizard. ------------------------------------------------------------------------ r976392 | fenton | 2009-06-01 10:48:12 -0400 (Mon, 01 Jun 2009) | 2 lines Fix legend being parented incorrectly when creating plots from the DataWizard. ------------------------------------------------------------------------ r976253 | fenton | 2009-06-01 08:05:54 -0400 (Mon, 01 Jun 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r976251 | fenton | 2009-06-01 08:02:21 -0400 (Mon, 01 Jun 2009) | 2 lines Update Bug list. ------------------------------------------------------------------------ r975318 | fenton | 2009-05-29 16:39:45 -0400 (Fri, 29 May 2009) | 2 lines Fix update delay on log axis changes. ------------------------------------------------------------------------ r974858 | fenton | 2009-05-29 14:07:15 -0400 (Fri, 29 May 2009) | 2 lines Add zoom update on relation being removed from plot. ------------------------------------------------------------------------ r974522 | fenton | 2009-05-29 11:37:42 -0400 (Fri, 29 May 2009) | 2 lines Add multiple edit support for PlotItems. ------------------------------------------------------------------------ r974166 | fenton | 2009-05-28 12:10:42 -0400 (Thu, 28 May 2009) | 2 lines Warning cleanup. ------------------------------------------------------------------------ r974165 | fenton | 2009-05-28 12:09:27 -0400 (Thu, 28 May 2009) | 2 lines Warning cleanup. ------------------------------------------------------------------------ r973265 | fenton | 2009-05-26 14:07:33 -0400 (Tue, 26 May 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r973254 | fenton | 2009-05-26 13:31:21 -0400 (Tue, 26 May 2009) | 3 lines Fix inability to control plot rect / tick colours. Add tracking of pen change for redraw. ------------------------------------------------------------------------ r973206 | netterfield | 2009-05-26 10:36:27 -0400 (Tue, 26 May 2009) | 4 lines Add Nicolas's bugs Move some feature requests from Bugs to Wishlist ------------------------------------------------------------------------ r973200 | fenton | 2009-05-26 10:26:17 -0400 (Tue, 26 May 2009) | 2 lines Fix jump when editing DataSourceSelector text field. ------------------------------------------------------------------------ r973178 | netterfield | 2009-05-26 10:13:42 -0400 (Tue, 26 May 2009) | 3 lines Fix color selection bug in data wizard. ------------------------------------------------------------------------ r972953 | netterfield | 2009-05-26 00:46:21 -0400 (Tue, 26 May 2009) | 3 lines Implement default X vectors... ------------------------------------------------------------------------ r972772 | fenton | 2009-05-25 12:41:39 -0400 (Mon, 25 May 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r972758 | fenton | 2009-05-25 11:50:16 -0400 (Mon, 25 May 2009) | 2 lines Add ContentTab double click actions. Fix multiple selection. ------------------------------------------------------------------------ r972746 | netterfield | 2009-05-25 11:03:19 -0400 (Mon, 25 May 2009) | 3 lines Fix crash from improperly enabled/disabled edit buttons in vector selector. ------------------------------------------------------------------------ r972743 | netterfield | 2009-05-25 10:42:31 -0400 (Mon, 25 May 2009) | 5 lines Add default X vector field for new vectors. Fix some button activation bugs in the vector dialog. Report a new bug. ------------------------------------------------------------------------ r971520 | fenton | 2009-05-22 11:39:12 -0400 (Fri, 22 May 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r971517 | fenton | 2009-05-22 11:34:05 -0400 (Fri, 22 May 2009) | 2 lines Fix proximity to zero double bug for major ticks. ------------------------------------------------------------------------ r971512 | fenton | 2009-05-22 11:18:57 -0400 (Fri, 22 May 2009) | 2 lines Fix compile warning. ------------------------------------------------------------------------ r970803 | fenton | 2009-05-20 16:43:27 -0400 (Wed, 20 May 2009) | 2 lines Add Axis Label rotation support. ------------------------------------------------------------------------ r970234 | fenton | 2009-05-19 15:55:05 -0400 (Tue, 19 May 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r970204 | fenton | 2009-05-19 14:38:32 -0400 (Tue, 19 May 2009) | 2 lines Add new Base/Offset mode settings and logic. ------------------------------------------------------------------------ r968549 | netterfield | 2009-05-15 23:58:20 -0400 (Fri, 15 May 2009) | 4 lines Fix a couple more bugs. Report another bug. ------------------------------------------------------------------------ r968501 | netterfield | 2009-05-15 17:16:53 -0400 (Fri, 15 May 2009) | 4 lines Fix Don's line width big Fix Don's range tab apply bug ------------------------------------------------------------------------ r968485 | fenton | 2009-05-15 16:13:49 -0400 (Fri, 15 May 2009) | 2 lines Fix cursor drifting when resizing / rotating objects. ------------------------------------------------------------------------ r968065 | fenton | 2009-05-14 16:50:22 -0400 (Thu, 14 May 2009) | 2 lines Fix MatrixSelector not maximizing correctly. ------------------------------------------------------------------------ r968056 | fenton | 2009-05-14 16:35:12 -0400 (Thu, 14 May 2009) | 2 lines Standardize and fix alignment issues in the CSD, Equation, Image and PowerSpectrum dialogs. ------------------------------------------------------------------------ r967955 | netterfield | 2009-05-14 10:39:14 -0400 (Thu, 14 May 2009) | 4 lines Label and Name work... Fix one of Don's bugs (current name not given in dialogs) ------------------------------------------------------------------------ r967950 | fenton | 2009-05-14 10:06:11 -0400 (Thu, 14 May 2009) | 2 lines Add saving of View size and resizing of ViewItem if View size does not match on reload. ------------------------------------------------------------------------ r967553 | fenton | 2009-05-13 10:31:21 -0400 (Wed, 13 May 2009) | 2 lines Fix item drift on rotated objects. ------------------------------------------------------------------------ r967184 | fenton | 2009-05-12 15:58:50 -0400 (Tue, 12 May 2009) | 2 lines Extend ArrowItem shape to include ArrowHead/Tail. ------------------------------------------------------------------------ r967112 | fenton | 2009-05-12 11:52:23 -0400 (Tue, 12 May 2009) | 3 lines Merge in changes made in beta release branch. Clean up lib line changes to be windows/unix specific. ------------------------------------------------------------------------ r967096 | fenton | 2009-05-12 10:21:18 -0400 (Tue, 12 May 2009) | 2 lines Update bugs. ------------------------------------------------------------------------ r966686 | fenton | 2009-05-11 14:08:08 -0400 (Mon, 11 May 2009) | 2 lines Rename Notes. ------------------------------------------------------------------------ r966606 | fenton | 2009-05-11 11:51:02 -0400 (Mon, 11 May 2009) | 2 lines Add Notes and update release information. ------------------------------------------------------------------------ r964961 | fenton | 2009-05-07 14:30:30 -0400 (Thu, 07 May 2009) | 1 line Add windows icon. ------------------------------------------------------------------------ r963438 | fenton | 2009-05-04 14:38:37 -0400 (Mon, 04 May 2009) | 2 lines Fix qmake failure in windows. ------------------------------------------------------------------------ r963436 | fenton | 2009-05-04 14:34:45 -0400 (Mon, 04 May 2009) | 2 lines Config cleanup. ------------------------------------------------------------------------ r963433 | fenton | 2009-05-04 14:34:25 -0400 (Mon, 04 May 2009) | 2 lines Update Install note version. ------------------------------------------------------------------------ r963431 | fenton | 2009-05-04 14:32:18 -0400 (Mon, 04 May 2009) | 2 lines Fix windows build error and segfault. ------------------------------------------------------------------------ r963421 | fenton | 2009-05-04 14:24:11 -0400 (Mon, 04 May 2009) | 2 lines Fix windows build error. ------------------------------------------------------------------------ r963351 | fenton | 2009-05-04 11:29:27 -0400 (Mon, 04 May 2009) | 2 lines Prevent error on Windows build when processing empty .pro. ------------------------------------------------------------------------ r963299 | fenton | 2009-05-04 09:13:01 -0400 (Mon, 04 May 2009) | 2 lines Claim bug. ------------------------------------------------------------------------ r962627 | netterfield | 2009-05-02 14:57:38 -0400 (Sat, 02 May 2009) | 4 lines Fix arrow bug; update bug list. ------------------------------------------------------------------------ r962066 | netterfield | 2009-05-01 08:58:28 -0400 (Fri, 01 May 2009) | 5 lines More accelerators. Bug update. ------------------------------------------------------------------------ r961847 | fenton | 2009-04-30 15:57:07 -0400 (Thu, 30 Apr 2009) | 2 lines Add configurable dirfile maker. ------------------------------------------------------------------------ r961799 | fenton | 2009-04-30 13:57:10 -0400 (Thu, 30 Apr 2009) | 2 lines Remove old signal. ------------------------------------------------------------------------ r961798 | fenton | 2009-04-30 13:56:43 -0400 (Thu, 30 Apr 2009) | 2 lines Fix Scalar test. ------------------------------------------------------------------------ r961777 | fenton | 2009-04-30 13:32:39 -0400 (Thu, 30 Apr 2009) | 2 lines Warning cleanup. ------------------------------------------------------------------------ r961715 | fenton | 2009-04-30 10:56:56 -0400 (Thu, 30 Apr 2009) | 2 lines Add dirty flag for PlotAxis to pickup changes made directly in PlotAxis dialog requiring a redraw. ------------------------------------------------------------------------ r961253 | netterfield | 2009-04-29 15:07:37 -0400 (Wed, 29 Apr 2009) | 4 lines Update bug list dialog accelerators ------------------------------------------------------------------------ r960557 | fenton | 2009-04-28 12:25:17 -0400 (Tue, 28 Apr 2009) | 2 lines Add benchmarking for update process. ------------------------------------------------------------------------ r960510 | fenton | 2009-04-28 11:03:07 -0400 (Tue, 28 Apr 2009) | 2 lines Fix update process not correctly updating scalars / strings of Primitives / DataObjects. ------------------------------------------------------------------------ r958850 | fenton | 2009-04-24 16:40:59 -0400 (Fri, 24 Apr 2009) | 4 lines Eliminate large number of calls to update() on objects during update process. Cleanup of unneeded dirty flag and checks for dirty. Add save/restore for RealTimeAutoBin for Histograms. ------------------------------------------------------------------------ r958729 | fenton | 2009-04-24 10:27:59 -0400 (Fri, 24 Apr 2009) | 2 lines Fix saving of PlotRenderItems and add saving of child viewItems. ------------------------------------------------------------------------ r958274 | netterfield | 2009-04-23 12:44:51 -0400 (Thu, 23 Apr 2009) | 4 lines More accelerators fix a crash case. ------------------------------------------------------------------------ r958249 | netterfield | 2009-04-23 11:58:51 -0400 (Thu, 23 Apr 2009) | 5 lines New bug Some accelerator work header file changes for cfitsio to make it work w/ SUSE. ------------------------------------------------------------------------ r957557 | fenton | 2009-04-22 08:59:43 -0400 (Wed, 22 Apr 2009) | 2 lines Update Bug List. ------------------------------------------------------------------------ r957358 | netterfield | 2009-04-21 17:08:05 -0400 (Tue, 21 Apr 2009) | 2 lines More bugs and wishes ------------------------------------------------------------------------ r957356 | netterfield | 2009-04-21 17:07:11 -0400 (Tue, 21 Apr 2009) | 3 lines Fix up some dialogs; add whatsthis. ------------------------------------------------------------------------ r957269 | fenton | 2009-04-21 13:53:30 -0400 (Tue, 21 Apr 2009) | 2 lines Fix PlotItem failing to update on label change based standardization. ------------------------------------------------------------------------ r956839 | fenton | 2009-04-20 14:54:05 -0400 (Mon, 20 Apr 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r956812 | fenton | 2009-04-20 13:21:09 -0400 (Mon, 20 Apr 2009) | 2 lines Add saving of reference point and offset status. ------------------------------------------------------------------------ r955464 | fenton | 2009-04-17 13:59:37 -0400 (Fri, 17 Apr 2009) | 3 lines Add caching of rendered label details. Fix label alignment issues in Plots. ------------------------------------------------------------------------ r955448 | netterfield | 2009-04-17 12:55:32 -0400 (Fri, 17 Apr 2009) | 3 lines More bugs and wishes. ------------------------------------------------------------------------ r954946 | netterfield | 2009-04-16 11:13:59 -0400 (Thu, 16 Apr 2009) | 6 lines Update bug list: Add some bugs Report performance bug as fixed Add 'wishlist' for features to be implememnted. ------------------------------------------------------------------------ r954944 | fenton | 2009-04-16 11:07:57 -0400 (Thu, 16 Apr 2009) | 2 lines Cleanup compile warnings. ------------------------------------------------------------------------ r953795 | fenton | 2009-04-14 10:47:01 -0400 (Tue, 14 Apr 2009) | 2 lines Remove pixmap based caching of labels. Add caching of parsed label. ------------------------------------------------------------------------ r953663 | fenton | 2009-04-14 09:06:45 -0400 (Tue, 14 Apr 2009) | 2 lines Fix typo. ------------------------------------------------------------------------ r951617 | fenton | 2009-04-09 15:43:49 -0400 (Thu, 09 Apr 2009) | 2 lines Cache entire PlotItem into pixmap. ------------------------------------------------------------------------ r950203 | fenton | 2009-04-06 12:32:11 -0400 (Mon, 06 Apr 2009) | 2 lines Fix curve drawing offset in plot. ------------------------------------------------------------------------ r948786 | fenton | 2009-04-03 15:34:00 -0400 (Fri, 03 Apr 2009) | 2 lines Fix multiple Plot updates triggered on zoom actions. ------------------------------------------------------------------------ r948189 | fenton | 2009-04-02 10:28:40 -0400 (Thu, 02 Apr 2009) | 2 lines Fix missing update for ticks. ------------------------------------------------------------------------ r947970 | fenton | 2009-04-01 16:23:46 -0400 (Wed, 01 Apr 2009) | 3 lines Cleanup LabelTab Fix AutoLabels by making overrideText purely an override. ------------------------------------------------------------------------ r947891 | fenton | 2009-04-01 10:50:53 -0400 (Wed, 01 Apr 2009) | 3 lines Move margin sizing calculations out of access functions. Add calculatedFont to PlotLabel and code cleanup. ------------------------------------------------------------------------ r947564 | fenton | 2009-03-31 15:30:02 -0400 (Tue, 31 Mar 2009) | 2 lines Add PlotLabel and clean up all Label related settings code in PlotItem. ------------------------------------------------------------------------ r947011 | fenton | 2009-03-30 14:39:38 -0400 (Mon, 30 Mar 2009) | 2 lines Add cached PlotMarkers. ------------------------------------------------------------------------ r946927 | fenton | 2009-03-30 10:37:35 -0400 (Mon, 30 Mar 2009) | 2 lines Remove unused _xLabelRect and _yLabelRect. Update associated Debug code. ------------------------------------------------------------------------ r945618 | fenton | 2009-03-27 16:06:37 -0400 (Fri, 27 Mar 2009) | 3 lines Fix Zoom over-redrawing bugs. Add proper invalidation of labels when global changes occur. ------------------------------------------------------------------------ r945503 | fenton | 2009-03-27 10:57:59 -0400 (Fri, 27 Mar 2009) | 2 lines Add pair of bugs. ------------------------------------------------------------------------ r945045 | fenton | 2009-03-26 15:18:33 -0400 (Thu, 26 Mar 2009) | 3 lines Cleanup overlapping/unclear/unused functions in PlotItem. Add caching of PlotItem::plotRect and plotAxisRect. ------------------------------------------------------------------------ r944036 | netterfield | 2009-03-24 17:44:11 -0400 (Tue, 24 Mar 2009) | 4 lines Don't crash from the command line... ------------------------------------------------------------------------ r943977 | fenton | 2009-03-24 14:54:05 -0400 (Tue, 24 Mar 2009) | 2 lines Add caching of plot axis labels. ------------------------------------------------------------------------ r943279 | fenton | 2009-03-23 11:54:06 -0400 (Mon, 23 Mar 2009) | 2 lines Eliminate extra validation / recalculation of Tick locations. ------------------------------------------------------------------------ r941959 | fenton | 2009-03-20 15:33:12 -0400 (Fri, 20 Mar 2009) | 2 lines Add caching for PlotItem labels as QPixmap's. ------------------------------------------------------------------------ r941469 | fenton | 2009-03-19 13:38:12 -0400 (Thu, 19 Mar 2009) | 2 lines Add tick line caching to Plot Item. ------------------------------------------------------------------------ r941020 | fenton | 2009-03-18 14:06:54 -0400 (Wed, 18 Mar 2009) | 2 lines Fix AppendLayout / DataWizard incorrectly cleaning up LayoutBoxItem's and aligning improperly. ------------------------------------------------------------------------ r940593 | fenton | 2009-03-17 14:36:16 -0400 (Tue, 17 Mar 2009) | 2 lines Update tests / tools for DataSource::init() ------------------------------------------------------------------------ r940493 | fenton | 2009-03-17 11:02:16 -0400 (Tue, 17 Mar 2009) | 4 lines Fix context menu failure to load / slow opening of DataManager / Debug Dialog. - Add init functions to DataObject/DataSource for loading settings / scanning plugins. - Trigger init from MainWindow load. ------------------------------------------------------------------------ r939061 | fenton | 2009-03-13 14:30:31 -0400 (Fri, 13 Mar 2009) | 2 lines Update Axis UI to disable Base Offset mode when interpretting the axis. ------------------------------------------------------------------------ r939024 | fenton | 2009-03-13 11:42:18 -0400 (Fri, 13 Mar 2009) | 2 lines Remove reference to viewitemzorder.h ------------------------------------------------------------------------ r939015 | fenton | 2009-03-13 11:12:37 -0400 (Fri, 13 Mar 2009) | 3 lines Removal of ViewItemZOrder default values. All objects are now created equally and modified by user command. ------------------------------------------------------------------------ r938281 | fenton | 2009-03-11 11:14:21 -0400 (Wed, 11 Mar 2009) | 4 lines Add Debug and output path options to build-kst command line. Further cleanup of .pro files. Remove and update all dependencies on qt3support. ------------------------------------------------------------------------ r937332 | fenton | 2009-03-09 11:33:51 -0400 (Mon, 09 Mar 2009) | 2 lines Fix label parsing debug output. ------------------------------------------------------------------------ r936068 | fenton | 2009-03-06 16:36:16 -0500 (Fri, 06 Mar 2009) | 2 lines Bug list update. ------------------------------------------------------------------------ r936062 | fenton | 2009-03-06 16:21:50 -0500 (Fri, 06 Mar 2009) | 4 lines Fix parenting problems on object changes. - Add parenting check skip for items being updated as the result of parent changes. - Fix comparison causing children to reparent when grips extend outside of parent but not the object itself. ------------------------------------------------------------------------ r935982 | fenton | 2009-03-06 11:24:54 -0500 (Fri, 06 Mar 2009) | 2 lines Improve tolerance checking. ------------------------------------------------------------------------ r935964 | fenton | 2009-03-06 10:37:31 -0500 (Fri, 06 Mar 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r935586 | fenton | 2009-03-05 12:51:07 -0500 (Thu, 05 Mar 2009) | 2 lines Add redraw of Plot when plotRect has changed to fix garbling of plotaxis. ------------------------------------------------------------------------ r935307 | fenton | 2009-03-04 15:22:10 -0500 (Wed, 04 Mar 2009) | 9 lines Cleanup and Bug fixes in SharedAxisBoxItem's - Add locked axis for shares. No automatic breaking of shared axes. - Fix margins changing on zoom - Integrate with PlotItem paint optimizations - Update setPlotDirty to notify either SharedBox or View. - Fix alignment errors of SharedPlots when parent or view is resized. - Fix alignment errors on zoom changes. Cleanup deprecated SharedAxis settings from view and viewitem. ------------------------------------------------------------------------ r934224 | fenton | 2009-03-02 09:56:51 -0500 (Mon, 02 Mar 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r933030 | fenton | 2009-02-27 15:54:21 -0500 (Fri, 27 Feb 2009) | 3 lines Simplify DataObjectPlugin and DataSourcePlugin .pro's. Fix check for filters. ------------------------------------------------------------------------ r932985 | fenton | 2009-02-27 13:22:37 -0500 (Fri, 27 Feb 2009) | 2 lines Fix qgraphicsitem_cast related bugs. ------------------------------------------------------------------------ r932515 | fenton | 2009-02-26 15:28:25 -0500 (Thu, 26 Feb 2009) | 2 lines Enhance the build system. ------------------------------------------------------------------------ r931110 | fenton | 2009-02-24 14:52:40 -0500 (Tue, 24 Feb 2009) | 3 lines Add Threaded DataSource Validation. Update ChangeFileDialog to do dataSource validation for Ok Button. ------------------------------------------------------------------------ r931015 | fenton | 2009-02-24 10:59:57 -0500 (Tue, 24 Feb 2009) | 2 lines Fix DataSource Selector for String's. ------------------------------------------------------------------------ r931001 | fenton | 2009-02-24 10:32:50 -0500 (Tue, 24 Feb 2009) | 2 lines Improve debugging output from UpdateManager. ------------------------------------------------------------------------ r930525 | fenton | 2009-02-23 13:29:26 -0500 (Mon, 23 Feb 2009) | 2 lines Add Update Cycle explanation. ------------------------------------------------------------------------ r929179 | fenton | 2009-02-20 16:09:52 -0500 (Fri, 20 Feb 2009) | 2 lines Improve debug logging for PlotItem/PlotRenderItem in the update cycle. ------------------------------------------------------------------------ r929178 | fenton | 2009-02-20 16:08:57 -0500 (Fri, 20 Feb 2009) | 2 lines Improve datavector debug logging. ------------------------------------------------------------------------ r929175 | fenton | 2009-02-20 16:04:24 -0500 (Fri, 20 Feb 2009) | 3 lines Improve debug logging for update manager. Fix over processing of curve updates. ------------------------------------------------------------------------ r928712 | fenton | 2009-02-19 16:33:54 -0500 (Thu, 19 Feb 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r928688 | fenton | 2009-02-19 15:50:42 -0500 (Thu, 19 Feb 2009) | 3 lines Add debugging option for Child Geometry. Fix Resize command undo/redo command improperly resizing child objects. ------------------------------------------------------------------------ r928061 | fenton | 2009-02-18 15:41:45 -0500 (Wed, 18 Feb 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r927941 | fenton | 2009-02-18 11:19:10 -0500 (Wed, 18 Feb 2009) | 2 lines Fix continuous painting of plotitems. ------------------------------------------------------------------------ r927663 | netterfield | 2009-02-17 20:45:37 -0500 (Tue, 17 Feb 2009) | 4 lines Place annoying debug message into plotitem.cpp to remind us that paint is being continuously called... ------------------------------------------------------------------------ r927556 | fenton | 2009-02-17 15:54:25 -0500 (Tue, 17 Feb 2009) | 2 lines Bug list update. ------------------------------------------------------------------------ r927502 | fenton | 2009-02-17 12:54:55 -0500 (Tue, 17 Feb 2009) | 2 lines Fix Qt Mouse grabber warning. ------------------------------------------------------------------------ r925702 | fenton | 2009-02-13 17:27:05 -0500 (Fri, 13 Feb 2009) | 4 lines Add creation status to ViewItem. Fix continous repainting of plot items. Trigger margin updates each redraw during plot creation. ------------------------------------------------------------------------ r925610 | fenton | 2009-02-13 11:33:35 -0500 (Fri, 13 Feb 2009) | 2 lines Buglist update. ------------------------------------------------------------------------ r925608 | fenton | 2009-02-13 11:32:53 -0500 (Fri, 13 Feb 2009) | 2 lines Reworking of Tied Zoom to allow parent tied zoom's for SharedAxisBox's. ------------------------------------------------------------------------ r925533 | netterfield | 2009-02-13 08:46:20 -0500 (Fri, 13 Feb 2009) | 5 lines Fix some bugs with margins not getting set. Paint is being continuously called on plots, which is a serious bug. ------------------------------------------------------------------------ r924374 | fenton | 2009-02-10 11:16:00 -0500 (Tue, 10 Feb 2009) | 2 lines Update Bugs. ------------------------------------------------------------------------ r924372 | fenton | 2009-02-10 11:12:43 -0500 (Tue, 10 Feb 2009) | 5 lines Add PlotMarginStandardization for the Top/Right Margins. Add factor to match "close" sizes of Plots. Update Standardization to apply to all non-SharedAxis plots in the view. Code Cleanup. ------------------------------------------------------------------------ r923852 | netterfield | 2009-02-09 10:20:16 -0500 (Mon, 09 Feb 2009) | 6 lines Changes to the plot updating to avoid n^2 behavior in updating plot axis. There are still issues! ------------------------------------------------------------------------ r922275 | fenton | 2009-02-06 11:40:09 -0500 (Fri, 06 Feb 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r921831 | fenton | 2009-02-05 14:02:30 -0500 (Thu, 05 Feb 2009) | 3 lines Add the ability to Maximize Plots - Tracked by PlotItemManager. Add the support for disabling plot item update cycle. ------------------------------------------------------------------------ r920762 | fenton | 2009-02-03 13:53:31 -0500 (Tue, 03 Feb 2009) | 2 lines Fix highlight point not drawing without reference point. ------------------------------------------------------------------------ r920711 | fenton | 2009-02-03 12:07:55 -0500 (Tue, 03 Feb 2009) | 2 lines Fix cancel on exit option still exiting. ------------------------------------------------------------------------ r920701 | fenton | 2009-02-03 11:36:24 -0500 (Tue, 03 Feb 2009) | 2 lines Bug list update. ------------------------------------------------------------------------ r920698 | fenton | 2009-02-03 11:24:30 -0500 (Tue, 03 Feb 2009) | 2 lines Add DataMode. ------------------------------------------------------------------------ r918778 | fenton | 2009-01-30 13:43:56 -0500 (Fri, 30 Jan 2009) | 2 lines Add Layout Settings at application and viewItem levels that provide seed values for ViewGridLayout. ------------------------------------------------------------------------ r918704 | netterfield | 2009-01-30 10:00:29 -0500 (Fri, 30 Jan 2009) | 4 lines Fix centering of left and right labels Slightly increase size of plot selector circle. ------------------------------------------------------------------------ r918289 | fenton | 2009-01-29 14:01:41 -0500 (Thu, 29 Jan 2009) | 2 lines Fix context menu for SharedAxisBoxItem's. ------------------------------------------------------------------------ r918285 | fenton | 2009-01-29 13:54:05 -0500 (Thu, 29 Jan 2009) | 2 lines Eliminate movement of plots on break of shared axis box. ------------------------------------------------------------------------ r918253 | fenton | 2009-01-29 13:10:07 -0500 (Thu, 29 Jan 2009) | 2 lines Update directory name. ------------------------------------------------------------------------ r918206 | netterfield | 2009-01-29 11:35:40 -0500 (Thu, 29 Jan 2009) | 2 lines Delete a debug statement... ------------------------------------------------------------------------ r918204 | netterfield | 2009-01-29 11:31:29 -0500 (Thu, 29 Jan 2009) | 3 lines Fix some label and axis alignment issues. ------------------------------------------------------------------------ r917974 | fenton | 2009-01-28 16:29:23 -0500 (Wed, 28 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r917973 | fenton | 2009-01-28 16:28:46 -0500 (Wed, 28 Jan 2009) | 2 lines Adjust Dialog ListView to automatically adjust to the size of the text independent of font sizing. ------------------------------------------------------------------------ r917879 | fenton | 2009-01-28 12:54:49 -0500 (Wed, 28 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r917877 | fenton | 2009-01-28 12:51:04 -0500 (Wed, 28 Jan 2009) | 9 lines Updates to SharedAxisBoxItem and Layout's. - Add parent lock to viewItems to prevent reparenting (used for plots in SharedAxisBox's). - Redo sizing for SharedAxisBoxItem to maximize to topLeft/bottomRight of plots being added. - Eliminate black border from created SharedAxisBoxItem's. - Add highlighting to plots that will be added to the to the SharedAxisBoxItem during creation. - Update Layout - Remove spacing between objects & reduce margin to minimum needed to select parent. - Fix Context Menu missing Raise/Lower/Layout options. - Update ViewItem::maybeParent to prevent ancestor bug and prevent inappropriate reparenting of children to top. ------------------------------------------------------------------------ r916965 | fenton | 2009-01-26 10:19:28 -0500 (Mon, 26 Jan 2009) | 2 lines Remove checkable status from layout. ------------------------------------------------------------------------ r915792 | fenton | 2009-01-23 14:34:24 -0500 (Fri, 23 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r915790 | fenton | 2009-01-23 14:28:52 -0500 (Fri, 23 Jan 2009) | 2 lines Add reference point 'c' mode. ------------------------------------------------------------------------ r915331 | fenton | 2009-01-22 15:06:17 -0500 (Thu, 22 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r915330 | fenton | 2009-01-22 15:05:48 -0500 (Thu, 22 Jan 2009) | 3 lines Auto append .kst to saved files. Add document changes status updating to all appropriate objects/actions. ------------------------------------------------------------------------ r915058 | netterfield | 2009-01-22 08:15:37 -0500 (Thu, 22 Jan 2009) | 3 lines Add some new bugs. ------------------------------------------------------------------------ r914792 | fenton | 2009-01-21 14:30:16 -0500 (Wed, 21 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r914791 | fenton | 2009-01-21 14:25:11 -0500 (Wed, 21 Jan 2009) | 5 lines Add clipping of PlotAxis labels instead of omitting. Add Tick Debugging Mode Fix rounding bug for PlotAxis numbers. Enforce minimum of 2 Major Plot Ticks. ------------------------------------------------------------------------ r914430 | netterfield | 2009-01-20 21:50:03 -0500 (Tue, 20 Jan 2009) | 5 lines Fix superscript and subscript size/placement Fix selection box around multi line labels. Do some graphics call optimizations suggested by techbase. ------------------------------------------------------------------------ r914320 | fenton | 2009-01-20 15:53:50 -0500 (Tue, 20 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r914319 | fenton | 2009-01-20 15:51:52 -0500 (Tue, 20 Jan 2009) | 2 lines Fix Bug - Child of PlotRenderItem loses parent on resize when renderitem's size becomes negative. ------------------------------------------------------------------------ r914172 | fenton | 2009-01-20 10:06:32 -0500 (Tue, 20 Jan 2009) | 2 lines Clean up of Tied Zoom status markers. ------------------------------------------------------------------------ r913642 | fenton | 2009-01-19 11:44:23 -0500 (Mon, 19 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r913641 | fenton | 2009-01-19 11:43:12 -0500 (Mon, 19 Jan 2009) | 2 lines Fix negative size drawing bug. ------------------------------------------------------------------------ r913304 | netterfield | 2009-01-18 22:44:02 -0500 (Sun, 18 Jan 2009) | 5 lines Fix some bugs in labels and label parsing: bold, italics, underline work now parse errors like \badtag{text} no longer crash. ------------------------------------------------------------------------ r912130 | fenton | 2009-01-16 13:57:37 -0500 (Fri, 16 Jan 2009) | 2 lines Add Escape cancelling for LineItem. ------------------------------------------------------------------------ r912105 | netterfield | 2009-01-16 13:06:39 -0500 (Fri, 16 Jan 2009) | 3 lines Add \odot and \ell to the parser. ------------------------------------------------------------------------ r911763 | netterfield | 2009-01-15 22:33:32 -0500 (Thu, 15 Jan 2009) | 4 lines ... also autoscale legend sizes from the data wizard. ------------------------------------------------------------------------ r911671 | fenton | 2009-01-15 16:53:32 -0500 (Thu, 15 Jan 2009) | 4 lines Add resize of view when exporting graphics. Switch to a white rather than transparent background painting for print/export. Switch export to print mode for painter. ------------------------------------------------------------------------ r911615 | fenton | 2009-01-15 14:21:26 -0500 (Thu, 15 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r911608 | fenton | 2009-01-15 14:12:43 -0500 (Thu, 15 Jan 2009) | 4 lines Add drawing markers to indicate current drawing mode and allow cancelling of non-active drawing. Add Escape catching to cancel active drawing. Update viewItem cursor changes to only trigger when in layout mode. ------------------------------------------------------------------------ r911462 | netterfield | 2009-01-15 08:29:04 -0500 (Thu, 15 Jan 2009) | 6 lines -Select smaller fonts when creating many plots from the data wizard -allow layout mode mouse actions to work again. -stuck 'debug' in the .pro files - can't tell if this is necessary but we can take it out later. ------------------------------------------------------------------------ r911110 | fenton | 2009-01-14 16:22:33 -0500 (Wed, 14 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r911074 | fenton | 2009-01-14 14:49:19 -0500 (Wed, 14 Jan 2009) | 2 lines Redo child update algorithm to eliminate drifting. ------------------------------------------------------------------------ r911021 | netterfield | 2009-01-14 11:30:29 -0500 (Wed, 14 Jan 2009) | 8 lines In starting to auto set font sizes for plots from the wizard, I found some serious bugs in the data wizard, related to plot creation - mostly misuse of iterators. This fixes them and uses direct indexing of the list, as suggested by the qt4 docs. ------------------------------------------------------------------------ r910598 | fenton | 2009-01-13 14:12:32 -0500 (Tue, 13 Jan 2009) | 2 lines Update bug list. ------------------------------------------------------------------------ r910596 | fenton | 2009-01-13 14:09:55 -0500 (Tue, 13 Jan 2009) | 2 lines Add PlotItemDialog / CurveDialog launching based on mouse click/doubleclick on plot items. ------------------------------------------------------------------------ r910238 | fenton | 2009-01-12 16:13:21 -0500 (Mon, 12 Jan 2009) | 2 lines Add UpdateManager trigger for dialog based curve changes. ------------------------------------------------------------------------ r910237 | fenton | 2009-01-12 16:10:55 -0500 (Mon, 12 Jan 2009) | 2 lines Update sizing for dialog ListView Size. ------------------------------------------------------------------------ r910234 | fenton | 2009-01-12 16:09:47 -0500 (Mon, 12 Jan 2009) | 2 lines Add proper selection from ListView for active item. ------------------------------------------------------------------------ r910226 | fenton | 2009-01-12 15:54:53 -0500 (Mon, 12 Jan 2009) | 2 lines Fix drawing loop in PlotItem. ------------------------------------------------------------------------ r910171 | netterfield | 2009-01-12 14:59:54 -0500 (Mon, 12 Jan 2009) | 2 lines Update bugs ------------------------------------------------------------------------ r910169 | netterfield | 2009-01-12 14:57:08 -0500 (Mon, 12 Jan 2009) | 3 lines constant y value curves have more sensible limits in auto mode. ------------------------------------------------------------------------ r910050 | fenton | 2009-01-12 10:53:39 -0500 (Mon, 12 Jan 2009) | 2 lines Update Bug Lists. ------------------------------------------------------------------------ r909085 | netterfield | 2009-01-10 18:27:59 -0500 (Sat, 10 Jan 2009) | 3 lines Add a range tab to the plot item dialog. ------------------------------------------------------------------------ r908456 | fenton | 2009-01-09 13:38:49 -0500 (Fri, 09 Jan 2009) | 2 lines Fix Bug - Select General tab automatically on ApplicationSettingsDialog load. ------------------------------------------------------------------------ r908409 | fenton | 2009-01-09 12:20:21 -0500 (Fri, 09 Jan 2009) | 3 lines Drawing fixes associated with SharedAxisBoxItem's. Automatically unshare when box is broken. ------------------------------------------------------------------------ r907830 | fenton | 2009-01-08 14:50:05 -0500 (Thu, 08 Jan 2009) | 2 lines Add custom layout support and updated margin handling for SharedAxisBoxItem's. ------------------------------------------------------------------------ r906223 | fenton | 2009-01-05 14:34:11 -0500 (Mon, 05 Jan 2009) | 2 lines Fix saving to skip saving of items that are hidden (have been undone and not redone). ------------------------------------------------------------------------ r906144 | fenton | 2009-01-05 11:51:36 -0500 (Mon, 05 Jan 2009) | 3 lines Add projection size updating when applying a SharedAxisBoxItem. Fix SharedAxisBoxItem parenting / undo crashes. ------------------------------------------------------------------------ r904638 | fenton | 2009-01-02 12:26:04 -0500 (Fri, 02 Jan 2009) | 3 lines Add persisting of layout when projectRect changes for SharedAxisBoxItem's. Update contextMenu to remove layout based items for children of SharedAxisBoxItem's. ------------------------------------------------------------------------ r903958 | fenton | 2008-12-31 16:23:36 -0500 (Wed, 31 Dec 2008) | 3 lines Connect SharedAxisBoxItem updates to SharePlots and add support for custom updates. Add calculation for share mode (x/y) based upon current projections. ------------------------------------------------------------------------ r903467 | fenton | 2008-12-30 10:55:49 -0500 (Tue, 30 Dec 2008) | 2 lines Add specialized context menu for layout/data mode for SharedAxisBoxItem. ------------------------------------------------------------------------ r903121 | netterfield | 2008-12-29 18:10:30 -0500 (Mon, 29 Dec 2008) | 3 lines More dialog tweaks. ------------------------------------------------------------------------ r903023 | fenton | 2008-12-29 13:46:20 -0500 (Mon, 29 Dec 2008) | 3 lines Fix child item saving / restoring. Add saving of SharedAxisBoxItem's. ------------------------------------------------------------------------ r900877 | fenton | 2008-12-23 16:19:08 -0500 (Tue, 23 Dec 2008) | 2 lines Add initial version of SharedAxisBoxItem allowing for basic drawing and existing layout application. ------------------------------------------------------------------------ r898762 | netterfield | 2008-12-18 18:29:48 -0500 (Thu, 18 Dec 2008) | 3 lines More dialog work... ------------------------------------------------------------------------ r898636 | netterfield | 2008-12-18 10:10:04 -0500 (Thu, 18 Dec 2008) | 3 lines More bugs ------------------------------------------------------------------------ r898368 | netterfield | 2008-12-17 21:45:19 -0500 (Wed, 17 Dec 2008) | 2 lines More bugs. ------------------------------------------------------------------------ r898367 | netterfield | 2008-12-17 21:41:03 -0500 (Wed, 17 Dec 2008) | 10 lines Work on the label tab for the plotitem dialog. -change how defaults/overrides work. -put in tab indicators for overriden -fix bugs saving and loading. -change button types. -change layouts. -fix acceloraters and tab order. -probably more stuff. ------------------------------------------------------------------------ r897430 | netterfield | 2008-12-15 22:02:53 -0500 (Mon, 15 Dec 2008) | 5 lines -Add hot keys to tool bar icons -Change behavior of toolbars/tools/layout mode. -Fix some label/descriptive name bugs ------------------------------------------------------------------------ r897428 | netterfield | 2008-12-15 21:51:13 -0500 (Mon, 15 Dec 2008) | 5 lines Add a spec for automatic labels Update bugs update object name specs ------------------------------------------------------------------------ r896214 | fenton | 2008-12-12 16:24:33 -0500 (Fri, 12 Dec 2008) | 5 lines Major update to all label dialogs. Add ApplicationSettings default label properties. All labels now support UBI / color / font family. Cleanup of PlotDialog / LabelTab. ------------------------------------------------------------------------ r896180 | fenton | 2008-12-12 14:21:11 -0500 (Fri, 12 Dec 2008) | 2 lines Add labellineedit support widget. ------------------------------------------------------------------------ r895566 | netterfield | 2008-12-10 21:09:41 -0500 (Wed, 10 Dec 2008) | 2 lines claim a bug as my very own... ------------------------------------------------------------------------ r895538 | fenton | 2008-12-10 18:04:15 -0500 (Wed, 10 Dec 2008) | 4 lines Add ViewDialog. Turn ApplicationSettings into default settings, not pushed through system. Add context menus for Views. ------------------------------------------------------------------------ r895333 | fenton | 2008-12-10 08:48:42 -0500 (Wed, 10 Dec 2008) | 2 lines Switch axis label backgrounds to transparent. ------------------------------------------------------------------------ r895028 | fenton | 2008-12-09 15:51:01 -0500 (Tue, 09 Dec 2008) | 2 lines Update bug list. ------------------------------------------------------------------------ r894967 | netterfield | 2008-12-09 12:42:42 -0500 (Tue, 09 Dec 2008) | 6 lines Add a dimensions tab to view object dialogs, to allow location, size, and orientation of view objects to be set manually. Add defaults to changedatasamplesdialog. ------------------------------------------------------------------------ r894963 | netterfield | 2008-12-09 12:36:01 -0500 (Tue, 09 Dec 2008) | 3 lines Update bug list ------------------------------------------------------------------------ r894951 | fenton | 2008-12-09 12:25:56 -0500 (Tue, 09 Dec 2008) | 2 lines Add commands / functions to trigger view updates for sharing axis only. ------------------------------------------------------------------------ r894425 | fenton | 2008-12-08 11:00:23 -0500 (Mon, 08 Dec 2008) | 3 lines Add LabelCreator Connect new Label widgets. ------------------------------------------------------------------------ r893051 | fenton | 2008-12-05 16:06:39 -0500 (Fri, 05 Dec 2008) | 2 lines Add Label Builder widget. ------------------------------------------------------------------------ r892941 | fenton | 2008-12-05 09:41:41 -0500 (Fri, 05 Dec 2008) | 2 lines Fix layout of CurveTab. ------------------------------------------------------------------------ r892251 | fenton | 2008-12-03 16:32:54 -0500 (Wed, 03 Dec 2008) | 2 lines Add Bug Report Wizard. ------------------------------------------------------------------------ r892223 | fenton | 2008-12-03 15:08:19 -0500 (Wed, 03 Dec 2008) | 2 lines Update version. ------------------------------------------------------------------------ r892222 | fenton | 2008-12-03 15:07:43 -0500 (Wed, 03 Dec 2008) | 2 lines Update version display for debug. ------------------------------------------------------------------------ r891812 | netterfield | 2008-12-02 17:02:59 -0500 (Tue, 02 Dec 2008) | 7 lines Put a minimum size on the dialog list widget. This is not the best solution, because it is font/resolution dependent. I can't figure out how to make the dialog list widget be the size of the largest item, however. ------------------------------------------------------------------------ r891706 | fenton | 2008-12-02 12:41:35 -0500 (Tue, 02 Dec 2008) | 2 lines Add DataSource validation to DataSourceSelectorDialog. ------------------------------------------------------------------------ r891443 | netterfield | 2008-12-01 21:46:32 -0500 (Mon, 01 Dec 2008) | 3 lines More bugs. ------------------------------------------------------------------------ r891366 | netterfield | 2008-12-01 15:51:29 -0500 (Mon, 01 Dec 2008) | 3 lines Update bug list, including adding new bugs. ------------------------------------------------------------------------ r891364 | netterfield | 2008-12-01 15:50:46 -0500 (Mon, 01 Dec 2008) | 6 lines -Icons for contents tab -Fix up/down/add/remove button behavior in content tab -Add settings to change axis number font. -Change behavior of string dialog to use checkable group boxes. ------------------------------------------------------------------------ r891339 | fenton | 2008-12-01 14:35:52 -0500 (Mon, 01 Dec 2008) | 2 lines Add static validDataSource based on file check. ------------------------------------------------------------------------ r891276 | fenton | 2008-12-01 09:51:49 -0500 (Mon, 01 Dec 2008) | 2 lines Merge release changes to main branch. ------------------------------------------------------------------------ r890319 | fenton | 2008-11-28 17:06:24 -0500 (Fri, 28 Nov 2008) | 2 lines Activate new selectors. ------------------------------------------------------------------------ r890318 | fenton | 2008-11-28 17:05:18 -0500 (Fri, 28 Nov 2008) | 2 lines Create separate FileRequester / DataSourceSelector widgets. ------------------------------------------------------------------------ r890240 | fenton | 2008-11-28 11:35:34 -0500 (Fri, 28 Nov 2008) | 2 lines Update DataSourceSelectorDialog to allow selection of directories and to clear file selection on directory change. ------------------------------------------------------------------------ r889743 | fenton | 2008-11-27 09:10:09 -0500 (Thu, 27 Nov 2008) | 2 lines Warning cleanup. ------------------------------------------------------------------------ r889738 | fenton | 2008-11-27 08:56:07 -0500 (Thu, 27 Nov 2008) | 2 lines Warning Cleanup. ------------------------------------------------------------------------ r889493 | fenton | 2008-11-26 17:26:40 -0500 (Wed, 26 Nov 2008) | 2 lines Clean up warnings. ------------------------------------------------------------------------ r889447 | fenton | 2008-11-26 16:04:54 -0500 (Wed, 26 Nov 2008) | 2 lines Fix warnings. ------------------------------------------------------------------------ r889434 | fenton | 2008-11-26 15:24:43 -0500 (Wed, 26 Nov 2008) | 2 lines Clean up warnings. ------------------------------------------------------------------------ r889399 | fenton | 2008-11-26 13:14:38 -0500 (Wed, 26 Nov 2008) | 2 lines Cleanup Healpix Datasource warnings. ------------------------------------------------------------------------ r889388 | fenton | 2008-11-26 12:06:08 -0500 (Wed, 26 Nov 2008) | 2 lines Add Untested port of the Planck IDEF Datasource Plugin. ------------------------------------------------------------------------ r888546 | netterfield | 2008-11-24 14:55:00 -0500 (Mon, 24 Nov 2008) | 16 lines Stuck in an airport Saturday, so... Make plotitems into namedobjects so they get sensible names in the combo-boxes. Fix ascii config dialog, so it loads properly. Update command line parser help output. Partially fix default Y axis labels. Something happened to mess up *all* of the whitespace in plotitem.cpp. I have undone most of it, but there are still some caprecious changes lingering (sigh). ------------------------------------------------------------------------ r888544 | netterfield | 2008-11-24 14:50:11 -0500 (Mon, 24 Nov 2008) | 3 lines Add missing images. ------------------------------------------------------------------------ r888435 | fenton | 2008-11-24 08:35:31 -0500 (Mon, 24 Nov 2008) | 2 lines Remove unused property. ------------------------------------------------------------------------ r887396 | fenton | 2008-11-21 14:50:04 -0500 (Fri, 21 Nov 2008) | 2 lines Add Healpix Datasource (untested). ------------------------------------------------------------------------ r887029 | netterfield | 2008-11-20 16:47:32 -0500 (Thu, 20 Nov 2008) | 3 lines More upgrades to the data wizard. ------------------------------------------------------------------------ r886913 | fenton | 2008-11-20 09:13:34 -0500 (Thu, 20 Nov 2008) | 2 lines Update requirements. ------------------------------------------------------------------------ r886668 | fenton | 2008-11-19 15:02:30 -0500 (Wed, 19 Nov 2008) | 2 lines Fix ASCII plugin not loading / reading values correctly. ------------------------------------------------------------------------ r886377 | netterfield | 2008-11-18 23:26:19 -0500 (Tue, 18 Nov 2008) | 4 lines Improve behavior of data wizard field selector. It now has the right behavioir, but is ~n^2. This can (and must) be sped up. ------------------------------------------------------------------------ r886370 | netterfield | 2008-11-18 22:15:57 -0500 (Tue, 18 Nov 2008) | 4 lines -dialogDefaults for x axis field in data wizard. -fix watcher for dirfiles (but now requires getdata 0.4.2 or better) ------------------------------------------------------------------------ r886210 | fenton | 2008-11-18 15:00:56 -0500 (Tue, 18 Nov 2008) | 2 lines Update install directions to include Windows details. ------------------------------------------------------------------------ r886203 | fenton | 2008-11-18 14:49:09 -0500 (Tue, 18 Nov 2008) | 2 lines Alternate Fix for Windows build. ------------------------------------------------------------------------ r886151 | fenton | 2008-11-18 11:50:04 -0500 (Tue, 18 Nov 2008) | 2 lines Add remaining windows build fixes for plugins. ------------------------------------------------------------------------ r885885 | netterfield | 2008-11-17 21:02:10 -0500 (Mon, 17 Nov 2008) | 2 lines Update bugs ------------------------------------------------------------------------ r885882 | netterfield | 2008-11-17 20:50:34 -0500 (Mon, 17 Nov 2008) | 4 lines More improvements to the data wizard. Improvements to the vector dialog. ------------------------------------------------------------------------ r885820 | netterfield | 2008-11-17 18:20:31 -0500 (Mon, 17 Nov 2008) | 5 lines Fix bug with oxygen theme (unwanted scrollbars) Fix bug in wizard: impossible to use generated X vectors Rework wizard to look/work a little better ------------------------------------------------------------------------ r885729 | fenton | 2008-11-17 15:11:47 -0500 (Mon, 17 Nov 2008) | 2 lines Fix windows build error. ------------------------------------------------------------------------ r885703 | fenton | 2008-11-17 14:25:55 -0500 (Mon, 17 Nov 2008) | 3 lines Improve plugin dialog appearances. Add pluginname driven titles. ------------------------------------------------------------------------ r885641 | fenton | 2008-11-17 10:45:57 -0500 (Mon, 17 Nov 2008) | 5 lines Lock to Curve Y Vector for Filters. Remove DataManager Create Fit from Vectors. Add DataManager Create Filter from DataObject Vectors. Add Vector Locking in Fit/Filters from DataManager. ------------------------------------------------------------------------ r885580 | fenton | 2008-11-17 08:34:04 -0500 (Mon, 17 Nov 2008) | 2 lines Disable test building in Windows. ------------------------------------------------------------------------ r884406 | fenton | 2008-11-14 16:23:06 -0500 (Fri, 14 Nov 2008) | 2 lines Fix windows build error. ------------------------------------------------------------------------ r884393 | fenton | 2008-11-14 15:30:31 -0500 (Fri, 14 Nov 2008) | 2 lines Fix Windows build errors. ------------------------------------------------------------------------ r884387 | fenton | 2008-11-14 15:08:06 -0500 (Fri, 14 Nov 2008) | 2 lines Add Default value support for Scalars. ------------------------------------------------------------------------ r884292 | fenton | 2008-11-14 10:02:15 -0500 (Fri, 14 Nov 2008) | 2 lines Fix crash in plugins when no vectors is selected. ------------------------------------------------------------------------ r883911 | fenton | 2008-11-13 15:19:24 -0500 (Thu, 13 Nov 2008) | 2 lines Add simple scalar creation to ScalarSelector. ------------------------------------------------------------------------ r883802 | fenton | 2008-11-13 11:15:48 -0500 (Thu, 13 Nov 2008) | 2 lines Add lockable vectors for Fit/Filter context menu options. ------------------------------------------------------------------------ r883427 | fenton | 2008-11-12 16:42:17 -0500 (Wed, 12 Nov 2008) | 2 lines Add untested LFIIO datasource plugin. ------------------------------------------------------------------------ r883323 | netterfield | 2008-11-12 12:41:17 -0500 (Wed, 12 Nov 2008) | 4 lines Load images from the command line. Change default palette to greyscale. ------------------------------------------------------------------------ r883304 | netterfield | 2008-11-12 11:29:17 -0500 (Wed, 12 Nov 2008) | 6 lines Update command line documentation. Fix warning message in command line options Auto layout should lay out in an sqrt(N) by sqrt(N) grid, not in a collumn. ------------------------------------------------------------------------ r883284 | fenton | 2008-11-12 10:01:10 -0500 (Wed, 12 Nov 2008) | 2 lines Remove unnecessary includes for gsl. ------------------------------------------------------------------------ r883195 | fenton | 2008-11-12 08:01:06 -0500 (Wed, 12 Nov 2008) | 2 lines Cleanup FixedBugs. ------------------------------------------------------------------------ r883187 | fenton | 2008-11-12 07:55:56 -0500 (Wed, 12 Nov 2008) | 2 lines Fix datasource tests. ------------------------------------------------------------------------ r883185 | fenton | 2008-11-12 07:55:31 -0500 (Wed, 12 Nov 2008) | 2 lines Fix datasource tests. ------------------------------------------------------------------------ r883044 | netterfield | 2008-11-11 17:57:23 -0500 (Tue, 11 Nov 2008) | 5 lines for qimage and fitsimage source fix typeString get rid of magic strings ------------------------------------------------------------------------ r883021 | netterfield | 2008-11-11 16:58:53 -0500 (Tue, 11 Nov 2008) | 6 lines Update bug list Improve command line option logic typeString should return something useful. Fixed for ascii and dirfilesource. Fewer magic strings in ascii. ------------------------------------------------------------------------ r882993 | fenton | 2008-11-11 15:35:17 -0500 (Tue, 11 Nov 2008) | 2 lines Update INSTALL details. ------------------------------------------------------------------------ r882968 | fenton | 2008-11-11 14:52:42 -0500 (Tue, 11 Nov 2008) | 2 lines Cleanup warnings. ------------------------------------------------------------------------ r882962 | fenton | 2008-11-11 14:09:54 -0500 (Tue, 11 Nov 2008) | 2 lines Add option for GSL not being installed. ------------------------------------------------------------------------ r882935 | fenton | 2008-11-11 12:58:57 -0500 (Tue, 11 Nov 2008) | 2 lines Add test for FitsImage plugin. ------------------------------------------------------------------------ r882931 | fenton | 2008-11-11 12:39:06 -0500 (Tue, 11 Nov 2008) | 3 lines Fix strange behavior with FitsImage matrix value reads. Fix vector read failure. ------------------------------------------------------------------------ r882895 | fenton | 2008-11-11 10:30:25 -0500 (Tue, 11 Nov 2008) | 2 lines Fix crash when switching between plugins in the FilterFitDialog. ------------------------------------------------------------------------ r882630 | netterfield | 2008-11-10 21:06:22 -0500 (Mon, 10 Nov 2008) | 3 lines Bug is fixed ------------------------------------------------------------------------ r882629 | netterfield | 2008-11-10 21:04:39 -0500 (Mon, 10 Nov 2008) | 3 lines Read dirfiles from the command line. ------------------------------------------------------------------------ r882624 | netterfield | 2008-11-10 20:59:41 -0500 (Mon, 10 Nov 2008) | 3 lines update bugs ------------------------------------------------------------------------ r882470 | fenton | 2008-11-10 15:17:56 -0500 (Mon, 10 Nov 2008) | 2 lines Fix Datawizard not accepting directories. ------------------------------------------------------------------------ r882433 | netterfield | 2008-11-10 13:40:32 -0500 (Mon, 10 Nov 2008) | 4 lines More bugs, resolved bugs Update/Clarify Plot Geometry specs regarding shared axis plots. ------------------------------------------------------------------------ r882361 | fenton | 2008-11-10 11:13:14 -0500 (Mon, 10 Nov 2008) | 2 lines Fix PlotRenderItem delay on Dialog based changes. ------------------------------------------------------------------------ r882331 | fenton | 2008-11-10 08:13:39 -0500 (Mon, 10 Nov 2008) | 2 lines Add test image for fitsimage plugin. ------------------------------------------------------------------------ r881395 | netterfield | 2008-11-07 18:00:43 -0500 (Fri, 07 Nov 2008) | 3 lines This change to the .pro files make it work in ubuntu ------------------------------------------------------------------------ r881269 | fenton | 2008-11-07 12:03:10 -0500 (Fri, 07 Nov 2008) | 2 lines Add config option for building of dirfile. ------------------------------------------------------------------------ r881264 | fenton | 2008-11-07 11:44:38 -0500 (Fri, 07 Nov 2008) | 2 lines Add FitsImage plugin (Untested) ------------------------------------------------------------------------ r881254 | fenton | 2008-11-07 10:38:55 -0500 (Fri, 07 Nov 2008) | 2 lines Fix DirFile source not correctly parsing the incoming filename when validating. ------------------------------------------------------------------------ r881232 | netterfield | 2008-11-07 09:47:21 -0500 (Fri, 07 Nov 2008) | 9 lines Fix a couple bugs. -edit vector from vector selector on slave vector now edits provider -edit scalar from scalar selector on slave scalar now edits provider Move some documentation around ------------------------------------------------------------------------ r881113 | netterfield | 2008-11-07 09:23:42 -0500 (Fri, 07 Nov 2008) | 4 lines Update Bugs. There are a number of new regressions. ------------------------------------------------------------------------ r880831 | fenton | 2008-11-06 10:51:06 -0500 (Thu, 06 Nov 2008) | 2 lines Fix DirFile tests. ------------------------------------------------------------------------ r880830 | fenton | 2008-11-06 10:50:02 -0500 (Thu, 06 Nov 2008) | 2 lines Add fileType identifier. ------------------------------------------------------------------------ r880811 | fenton | 2008-11-06 09:58:27 -0500 (Thu, 06 Nov 2008) | 2 lines Update library includes for plugins. ------------------------------------------------------------------------ r880789 | netterfield | 2008-11-06 08:12:52 -0500 (Thu, 06 Nov 2008) | 3 lines Add readme to say where to get the getdata library. ------------------------------------------------------------------------ r880592 | netterfield | 2008-11-05 17:10:23 -0500 (Wed, 05 Nov 2008) | 12 lines port the dirfile datasource to use the external getdata library. add field scalars to kst and have dirfilesource provide them add field strings to kst and have dirfilesource provide them field strings need more work -they need to show up in the string view dialog -they need to get coppied in replace dependant type functions Still need to add a readme to tell you where to get said library. Need to decide how to deal with data sources that use external libraries ------------------------------------------------------------------------ r880511 | fenton | 2008-11-05 13:26:20 -0500 (Wed, 05 Nov 2008) | 2 lines Fix Equation Parsing tests. ------------------------------------------------------------------------ r880496 | fenton | 2008-11-05 12:29:43 -0500 (Wed, 05 Nov 2008) | 2 lines Add reset of NamedObject incrementors to ObjectStore clear. ------------------------------------------------------------------------ r880090 | fenton | 2008-11-04 13:24:54 -0500 (Tue, 04 Nov 2008) | 2 lines Convert double comparison to templates. ------------------------------------------------------------------------ r880067 | fenton | 2008-11-04 11:54:24 -0500 (Tue, 04 Nov 2008) | 2 lines Update DOUBLE_EQUAL ------------------------------------------------------------------------ r880060 | fenton | 2008-11-04 11:38:23 -0500 (Tue, 04 Nov 2008) | 2 lines Fix double comparisons in equation node parsing. ------------------------------------------------------------------------ r879681 | fenton | 2008-11-03 15:06:52 -0500 (Mon, 03 Nov 2008) | 2 lines Add testing of DataMatrix based on the qImageSource plugin. ------------------------------------------------------------------------ r879649 | fenton | 2008-11-03 13:38:56 -0500 (Mon, 03 Nov 2008) | 3 lines Add test for qimagesource. Fix test for DirFile. ------------------------------------------------------------------------ r879648 | fenton | 2008-11-03 13:19:21 -0500 (Mon, 03 Nov 2008) | 2 lines Add dirfile test data. ------------------------------------------------------------------------ r879616 | fenton | 2008-11-03 10:47:32 -0500 (Mon, 03 Nov 2008) | 2 lines Fix close on View Matrix / View Vector Dialogs. ------------------------------------------------------------------------ r878285 | fenton | 2008-10-31 15:27:33 -0400 (Fri, 31 Oct 2008) | 2 lines Update install doc. ------------------------------------------------------------------------ r878229 | fenton | 2008-10-31 12:16:23 -0400 (Fri, 31 Oct 2008) | 2 lines Disable DataSource test from DataMatrix now that there is no Ascii Matrix. ------------------------------------------------------------------------ r878197 | fenton | 2008-10-31 10:36:57 -0400 (Fri, 31 Oct 2008) | 2 lines Add initial 2.0 Entry. ------------------------------------------------------------------------ r878186 | fenton | 2008-10-31 09:55:24 -0400 (Fri, 31 Oct 2008) | 2 lines Add stub for release details. ------------------------------------------------------------------------ r877947 | fenton | 2008-10-30 14:55:18 -0400 (Thu, 30 Oct 2008) | 2 lines Add qimagesource datasource. ------------------------------------------------------------------------ r877556 | fenton | 2008-10-29 15:41:42 -0400 (Wed, 29 Oct 2008) | 2 lines Add SampleDataSource plugin. ------------------------------------------------------------------------ r877075 | fenton | 2008-10-28 12:49:38 -0400 (Tue, 28 Oct 2008) | 2 lines Move existing non-ported Datasources to old_datasources. ------------------------------------------------------------------------ r877043 | fenton | 2008-10-28 11:28:50 -0400 (Tue, 28 Oct 2008) | 2 lines Rework DialogPage to allow for non-Tab based widgets. ------------------------------------------------------------------------ r876618 | fenton | 2008-10-27 13:51:54 -0400 (Mon, 27 Oct 2008) | 2 lines Redo of Scalar Model to display all scalars in the proper hierarchy. ------------------------------------------------------------------------ r875535 | netterfield | 2008-10-24 15:06:39 -0400 (Fri, 24 Oct 2008) | 4 lines Fix initialization for a couple more data objects. This might fix the crash on load bugs. ------------------------------------------------------------------------ r875512 | fenton | 2008-10-24 13:23:25 -0400 (Fri, 24 Oct 2008) | 2 lines Fix DataSource naming. ------------------------------------------------------------------------ r875244 | fenton | 2008-10-23 15:44:26 -0400 (Thu, 23 Oct 2008) | 2 lines Fix bug with commandline loading layout problems. ------------------------------------------------------------------------ r875224 | fenton | 2008-10-23 14:22:40 -0400 (Thu, 23 Oct 2008) | 2 lines Move MatrixEditorDialog to ViewMatrixDialog. ------------------------------------------------------------------------ r875223 | fenton | 2008-10-23 14:21:33 -0400 (Thu, 23 Oct 2008) | 2 lines Update kst.pro to build the plugins directory. ------------------------------------------------------------------------ r875214 | fenton | 2008-10-23 13:46:23 -0400 (Thu, 23 Oct 2008) | 2 lines Update Vector View Dialog to have vector selector and rename to ViewVectorDialog to accurately represent the feature set. ------------------------------------------------------------------------ r875177 | netterfield | 2008-10-23 10:55:09 -0400 (Thu, 23 Oct 2008) | 5 lines Encourage histograms to not crash kst when read from file or from command line. They were being created with invalid slave vectors, so resize killed thing. Also, set the name in the constructor, not in change(...). ------------------------------------------------------------------------ r874954 | fenton | 2008-10-22 17:29:02 -0400 (Wed, 22 Oct 2008) | 2 lines Add SyncBin plugin. ------------------------------------------------------------------------ r874884 | fenton | 2008-10-22 13:43:43 -0400 (Wed, 22 Oct 2008) | 2 lines Adding Statistics dataobject plugin. ------------------------------------------------------------------------ r874847 | netterfield | 2008-10-22 10:25:29 -0400 (Wed, 22 Oct 2008) | 7 lines Improve the data manager. Remove bug reading files. Fix bug deleting tabs. Remove some dead code from the file writer. Fix bug saving skip attributes in data vectors. ------------------------------------------------------------------------ r874796 | fenton | 2008-10-22 09:26:04 -0400 (Wed, 22 Oct 2008) | 2 lines Add Shift DataObject Plugin. ------------------------------------------------------------------------ r874517 | fenton | 2008-10-21 15:15:18 -0400 (Tue, 21 Oct 2008) | 2 lines Add Phase DataObject plugin. ------------------------------------------------------------------------ r874448 | fenton | 2008-10-21 12:09:54 -0400 (Tue, 21 Oct 2008) | 2 lines Add Periodogram plugin. ------------------------------------------------------------------------ r874170 | fenton | 2008-10-20 17:37:12 -0400 (Mon, 20 Oct 2008) | 2 lines Add Noise Addition plugin. ------------------------------------------------------------------------ r874075 | fenton | 2008-10-20 14:28:42 -0400 (Mon, 20 Oct 2008) | 2 lines Add Linefit DataObject plugin. ------------------------------------------------------------------------ r873994 | fenton | 2008-10-20 10:25:54 -0400 (Mon, 20 Oct 2008) | 2 lines Add Interpolation Plugins - Akima, Akima Periodic, C-Spline, C-Spline Periodic, Polynomial and Linear. ------------------------------------------------------------------------ r872653 | fenton | 2008-10-17 14:47:05 -0400 (Fri, 17 Oct 2008) | 2 lines Add orphan / non-orphan handling for string names. ------------------------------------------------------------------------ r872356 | netterfield | 2008-10-16 21:39:18 -0400 (Thu, 16 Oct 2008) | 10 lines Add a new kind of scalar: vector field scalars... make a scalar from a single sample of a vector field from a data source. Useful for numerical displays in live kst windows, etc. Work on the data manager to allow strings and scalars to be displayed. Refactor the data manager a little - simplifying things a bit. ------------------------------------------------------------------------ r872288 | fenton | 2008-10-16 16:01:00 -0400 (Thu, 16 Oct 2008) | 2 lines Add Generic Filter plugin. ------------------------------------------------------------------------ r872232 | fenton | 2008-10-16 13:25:14 -0400 (Thu, 16 Oct 2008) | 2 lines Add functionality to String Selector. ------------------------------------------------------------------------ r872160 | fenton | 2008-10-16 09:29:03 -0400 (Thu, 16 Oct 2008) | 2 lines Add Effective Bandwidth Plugin. ------------------------------------------------------------------------ r871815 | fenton | 2008-10-15 14:14:46 -0400 (Wed, 15 Oct 2008) | 2 lines Add Differentiation plugin. ------------------------------------------------------------------------ r871770 | fenton | 2008-10-15 10:22:08 -0400 (Wed, 15 Oct 2008) | 2 lines Add Cumulative Sum plugin. ------------------------------------------------------------------------ r871746 | fenton | 2008-10-15 09:26:50 -0400 (Wed, 15 Oct 2008) | 2 lines Add sorting for plugins. ------------------------------------------------------------------------ r871385 | fenton | 2008-10-14 15:52:44 -0400 (Tue, 14 Oct 2008) | 2 lines Add Cross Spectrum plugin. ------------------------------------------------------------------------ r871334 | fenton | 2008-10-14 12:28:09 -0400 (Tue, 14 Oct 2008) | 2 lines Add Convolve, Deconvolve, Auto Correlation and Cross Correlation Plugins. ------------------------------------------------------------------------ r869682 | fenton | 2008-10-09 14:57:25 -0400 (Thu, 09 Oct 2008) | 2 lines Add Chop Data Object Plugin. ------------------------------------------------------------------------ r869660 | fenton | 2008-10-09 12:48:01 -0400 (Thu, 09 Oct 2008) | 2 lines Add Bin Data Object plugin. ------------------------------------------------------------------------ r869640 | fenton | 2008-10-09 11:27:43 -0400 (Thu, 09 Oct 2008) | 3 lines Add Error Display for BasicPluginDialog. Add DataManager entry for Plugins. ------------------------------------------------------------------------ r869351 | fenton | 2008-10-08 16:20:46 -0400 (Wed, 08 Oct 2008) | 2 lines Add Gaussian and Lorentzian Weighted Fits plugins. ------------------------------------------------------------------------ r869255 | fenton | 2008-10-08 12:13:01 -0400 (Wed, 08 Oct 2008) | 2 lines Add Non-Linear Weighted Exponential Fits plugin. ------------------------------------------------------------------------ r868922 | fenton | 2008-10-07 11:41:24 -0400 (Tue, 07 Oct 2008) | 2 lines Add Gaussian Unweighted and Lorentzian unweighted Fits plugins. ------------------------------------------------------------------------ r868651 | fenton | 2008-10-06 16:44:52 -0400 (Mon, 06 Oct 2008) | 2 lines Add Exponential unweighted plugin. ------------------------------------------------------------------------ r868530 | fenton | 2008-10-06 10:09:38 -0400 (Mon, 06 Oct 2008) | 3 lines Add Knee Frequency Fits Plugin. Add Error Message provision for Plugins and display in Filter Fit Dialog. ------------------------------------------------------------------------ r867476 | fenton | 2008-10-03 11:39:08 -0400 (Fri, 03 Oct 2008) | 2 lines Add Polynomial Weighted and Sinusoid Weighted Plugins. ------------------------------------------------------------------------ r867068 | fenton | 2008-10-02 13:59:56 -0400 (Thu, 02 Oct 2008) | 2 lines Add Sinusoid Unweighted and Polynomial unweighted Fits Plugins. ------------------------------------------------------------------------ r866992 | fenton | 2008-10-02 11:00:04 -0400 (Thu, 02 Oct 2008) | 4 lines Updates to BasicPlugin Interfaces 1) Add Validation check to prevent invalid object creation. 2) Add Scalar Creation based on Parameter Vectors. ------------------------------------------------------------------------ r866645 | fenton | 2008-10-01 10:51:14 -0400 (Wed, 01 Oct 2008) | 2 lines Add Gradient Unweighted and Gradient Weighted Fits Plugins. ------------------------------------------------------------------------ r866008 | netterfield | 2008-09-29 15:29:05 -0400 (Mon, 29 Sep 2008) | 2 lines Clarify bug report ------------------------------------------------------------------------ r866007 | netterfield | 2008-09-29 15:24:24 -0400 (Mon, 29 Sep 2008) | 7 lines Remove metadata from datasources. metadata is now to be handled as dataScalars and dataStrings, which have both been added to the datasource ui. The other data sources can now be ported. ------------------------------------------------------------------------ r865467 | netterfield | 2008-09-27 12:56:47 -0400 (Sat, 27 Sep 2008) | 6 lines -Add dataStrings -Add reading of strings to data sources -Add a stringDialog to edit and create strings -Fix some compiler warnings ------------------------------------------------------------------------ r865055 | fenton | 2008-09-26 10:39:05 -0400 (Fri, 26 Sep 2008) | 2 lines Add Linear Unweighted Fits plugin. ------------------------------------------------------------------------ r864855 | fenton | 2008-09-25 14:41:35 -0400 (Thu, 25 Sep 2008) | 2 lines Add Linear Weighted Fits plugin. ------------------------------------------------------------------------ r864803 | netterfield | 2008-09-25 10:31:43 -0400 (Thu, 25 Sep 2008) | 6 lines -DataScalars can now be saved -Clean up some un-ref variable warnings -start to add strings to data sources -add a debug warning about a bug ------------------------------------------------------------------------ r864429 | fenton | 2008-09-24 15:27:18 -0400 (Wed, 24 Sep 2008) | 2 lines Add ports for Butterworth High Pass Filter, Butterworth Band Stop Filter and Butterworth Band Pass Filter. ------------------------------------------------------------------------ r864326 | fenton | 2008-09-24 10:05:38 -0400 (Wed, 24 Sep 2008) | 2 lines Update the current Bug Status. ------------------------------------------------------------------------ r863732 | netterfield | 2008-09-22 20:06:03 -0400 (Mon, 22 Sep 2008) | 3 lines Clean up some of the devel-docs ------------------------------------------------------------------------ r863731 | netterfield | 2008-09-22 19:55:28 -0400 (Mon, 22 Sep 2008) | 8 lines -Invent data scalars -Add data scalars to the scalar dialog -upgrade data sources to know about data scalars -put basic data scalars into dirfiles and ascii data sources -fix a few little bugs here and there -capriciously fix a few compiler warnings ------------------------------------------------------------------------ r863676 | fenton | 2008-09-22 16:12:28 -0400 (Mon, 22 Sep 2008) | 2 lines Make Vector and Matrix viewers non-persisted items to provide accurate details. ------------------------------------------------------------------------ r863649 | fenton | 2008-09-22 14:53:29 -0400 (Mon, 22 Sep 2008) | 2 lines Add filter plugin for butterworth low pass. ------------------------------------------------------------------------ r862748 | fenton | 2008-09-19 14:39:41 -0400 (Fri, 19 Sep 2008) | 3 lines Add Content Menu support for Fit/Filter from DataManager and PlotItems. Add CurveAppearance Settings / curve creation to FitFilterDialog, including interface extensions to support. ------------------------------------------------------------------------ r862365 | fenton | 2008-09-18 13:32:33 -0400 (Thu, 18 Sep 2008) | 2 lines Add FilterFitDialog. ------------------------------------------------------------------------ r861991 | fenton | 2008-09-17 14:21:27 -0400 (Wed, 17 Sep 2008) | 2 lines Move Kst 1.X plugins to old_plugins. ------------------------------------------------------------------------ r861982 | fenton | 2008-09-17 14:04:23 -0400 (Wed, 17 Sep 2008) | 4 lines Add basic support for filter plugins. Port Despike filter to new format. Update Plugin Interface to include Type and Description. ------------------------------------------------------------------------ r861586 | fenton | 2008-09-16 10:37:12 -0400 (Tue, 16 Sep 2008) | 2 lines Add PlotStandarization to ensure uniform margin sizes. ------------------------------------------------------------------------ r860332 | fenton | 2008-09-12 13:56:31 -0400 (Fri, 12 Sep 2008) | 4 lines Add DataSourceSelector Dialog. Modifications to FileRequester. Remove Directory selector option from VectorTab. ------------------------------------------------------------------------ r859986 | fenton | 2008-09-11 13:53:07 -0400 (Thu, 11 Sep 2008) | 2 lines Fix DirFile not picking up when the directory is provided without a trailing / ------------------------------------------------------------------------ r859689 | netterfield | 2008-09-10 23:29:47 -0400 (Wed, 10 Sep 2008) | 6 lines -Fix many dialogs to look better w/ oxygen, and to work better on a wide screen. -Start of adding scalars to data sources ------------------------------------------------------------------------ r859548 | fenton | 2008-09-10 11:57:51 -0400 (Wed, 10 Sep 2008) | 2 lines Add Selective drawing of object details when printing. ------------------------------------------------------------------------ r859193 | fenton | 2008-09-09 14:49:43 -0400 (Tue, 09 Sep 2008) | 2 lines Implement DebugDialog functionality. ------------------------------------------------------------------------ r858825 | fenton | 2008-09-08 15:43:37 -0400 (Mon, 08 Sep 2008) | 2 lines Fix Segfaults when creating objects and not placing them in Plots. ------------------------------------------------------------------------ r858777 | fenton | 2008-09-08 13:28:25 -0400 (Mon, 08 Sep 2008) | 2 lines Remove ViewManager options. ------------------------------------------------------------------------ r858716 | fenton | 2008-09-08 10:36:31 -0400 (Mon, 08 Sep 2008) | 2 lines Fix Demo Model. ------------------------------------------------------------------------ r857568 | fenton | 2008-09-05 14:38:06 -0400 (Fri, 05 Sep 2008) | 2 lines Remove overlapping Assert. ------------------------------------------------------------------------ r857567 | fenton | 2008-09-05 14:37:36 -0400 (Fri, 05 Sep 2008) | 2 lines Cleanup unnecessary namespace definition. ------------------------------------------------------------------------ r857492 | fenton | 2008-09-05 10:42:36 -0400 (Fri, 05 Sep 2008) | 2 lines Fix QString Arg errors for Images and Matrices. ------------------------------------------------------------------------ r857134 | fenton | 2008-09-04 15:22:43 -0400 (Thu, 04 Sep 2008) | 2 lines Fix Scene addition errors in DataWizard. Add wait cursor while building the plots. ------------------------------------------------------------------------ r857083 | fenton | 2008-09-04 12:32:00 -0400 (Thu, 04 Sep 2008) | 2 lines Fix crash with Qt 4.4.X matching items differently than 4.3.X ------------------------------------------------------------------------ r857000 | fenton | 2008-09-04 07:56:52 -0400 (Thu, 04 Sep 2008) | 2 lines Remove old Debug. ------------------------------------------------------------------------ r856763 | fenton | 2008-09-03 14:21:53 -0400 (Wed, 03 Sep 2008) | 2 lines Fix Legend appearing after cancel of dialog. ------------------------------------------------------------------------ r856430 | fenton | 2008-09-02 16:49:50 -0400 (Tue, 02 Sep 2008) | 2 lines Add defines for label parsing debug output. ------------------------------------------------------------------------ r856387 | fenton | 2008-09-02 15:00:44 -0400 (Tue, 02 Sep 2008) | 4 lines Initial fixes for Qt 4.4.X segfaults. Fix crash on load. Fix crash on appending of empty strings in description fields. ------------------------------------------------------------------------ r854111 | fenton | 2008-08-28 16:55:52 -0400 (Thu, 28 Aug 2008) | 3 lines Modify update manager to support PlotItem specialized returns / PlotItem based instead of PlotRenderItem based. Add persisted zoom mode to PlotItem on update. ------------------------------------------------------------------------ r852339 | fenton | 2008-08-25 15:28:42 -0400 (Mon, 25 Aug 2008) | 2 lines Add debug define for plot label region. ------------------------------------------------------------------------ r850115 | fenton | 2008-08-20 16:13:07 -0400 (Wed, 20 Aug 2008) | 2 lines Fix ZoomYRange and ZoomXRange. ------------------------------------------------------------------------ r849992 | fenton | 2008-08-20 11:36:54 -0400 (Wed, 20 Aug 2008) | 2 lines Add caching to Images and benchmarking. ------------------------------------------------------------------------ r847104 | fenton | 2008-08-14 14:49:50 -0400 (Thu, 14 Aug 2008) | 2 lines Optimize Bar drawing for curves. ------------------------------------------------------------------------ r846649 | fenton | 2008-08-13 15:56:25 -0400 (Wed, 13 Aug 2008) | 2 lines Add caching of curve calculations for drawing. ------------------------------------------------------------------------ r846623 | fenton | 2008-08-13 15:29:31 -0400 (Wed, 13 Aug 2008) | 2 lines Modify update request to 2nd level debugging. ------------------------------------------------------------------------ r845465 | fenton | 2008-08-11 14:22:41 -0400 (Mon, 11 Aug 2008) | 2 lines Fix for saving of backgrounds for viewitems. ------------------------------------------------------------------------ r844062 | fenton | 2008-08-08 11:21:05 -0400 (Fri, 08 Aug 2008) | 2 lines Fix gradient resetting in GradientEditor and make it more robust. ------------------------------------------------------------------------ r843749 | fenton | 2008-08-07 14:45:38 -0400 (Thu, 07 Aug 2008) | 4 lines Add configurable background for views. Add special reset mode for gradient editor. Save background as application setting. ------------------------------------------------------------------------ r837860 | fenton | 2008-07-25 17:51:26 -0400 (Fri, 25 Jul 2008) | 3 lines Fix for printing errors. Convert all font sizing to pixel based. ------------------------------------------------------------------------ r837436 | fenton | 2008-07-24 13:42:50 -0400 (Thu, 24 Jul 2008) | 4 lines Add Shared Axis updating on item move. Remove triggering of invalid zoom's. Add Shared Axis updating on non-tied zooms. ------------------------------------------------------------------------ r837031 | fenton | 2008-07-23 11:32:30 -0400 (Wed, 23 Jul 2008) | 4 lines Eliminate overlapping items created by the Grid. Fix DataWizard Layouts. Add Debugging of Grid Creation. ------------------------------------------------------------------------ r836127 | fenton | 2008-07-21 15:11:50 -0400 (Mon, 21 Jul 2008) | 2 lines Update creation layout modes to support Automatic, Custom and Protected. ------------------------------------------------------------------------ r834343 | netterfield | 2008-07-18 13:28:12 -0400 (Fri, 18 Jul 2008) | 5 lines -Pause works now -Immediate update for some vector dialogs -Timer is minimum period, not maximum frequency - fix variable names and labels. ------------------------------------------------------------------------ r834323 | fenton | 2008-07-18 12:45:41 -0400 (Fri, 18 Jul 2008) | 2 lines Create interfaces for new Creation Modes for both CurvePlacement and DataWizard. ------------------------------------------------------------------------ r833979 | fenton | 2008-07-17 14:41:55 -0400 (Thu, 17 Jul 2008) | 2 lines Create Custom Grid building options. ------------------------------------------------------------------------ r833516 | netterfield | 2008-07-16 18:53:37 -0400 (Wed, 16 Jul 2008) | 7 lines primitives gain an immediateUpdate command, which propogates an update (including dependents) immediately. primitives get an updated() signal, replacing matrixUpdated, vectorUpdated, and scalarUpdated(). ------------------------------------------------------------------------ r833426 | fenton | 2008-07-16 15:57:04 -0400 (Wed, 16 Jul 2008) | 3 lines Fix updateChildGeometry to function with Circles. Update Layout drawing to support fixedSize and lockedAspectRatio items. ------------------------------------------------------------------------ r833284 | fenton | 2008-07-16 11:33:46 -0400 (Wed, 16 Jul 2008) | 3 lines Remove persisted Layouts. Fix label overdrawing. ------------------------------------------------------------------------ r832468 | fenton | 2008-07-14 14:45:22 -0400 (Mon, 14 Jul 2008) | 2 lines Update Bug tracking. ------------------------------------------------------------------------ r832464 | fenton | 2008-07-14 14:43:48 -0400 (Mon, 14 Jul 2008) | 4 lines Fix for Label rotate / resize bug. Add relative center position tracking. Add fixed size flag to prevent resize in updatechildgeometry triggering a position change. ------------------------------------------------------------------------ r832080 | netterfield | 2008-07-13 21:24:10 -0400 (Sun, 13 Jul 2008) | 3 lines clean up dead code (and make tests compile) ------------------------------------------------------------------------ r832048 | netterfield | 2008-07-13 19:08:34 -0400 (Sun, 13 Jul 2008) | 4 lines -Clean up some dead code -some toolbar work ------------------------------------------------------------------------ r831081 | fenton | 2008-07-11 15:49:54 -0400 (Fri, 11 Jul 2008) | 3 lines Update DataWizard to support Labels / Legend. Fix crash in Datawizard. ------------------------------------------------------------------------ r830984 | fenton | 2008-07-11 11:49:16 -0400 (Fri, 11 Jul 2008) | 2 lines Add drawing of legend and placement of legendItem within the plot. ------------------------------------------------------------------------ r830967 | netterfield | 2008-07-11 10:55:44 -0400 (Fri, 11 Jul 2008) | 4 lines Add pause, read to end, forward and back toolbar icons. Start to implement read to end, forward, and back. Needs immediate curve updates. ------------------------------------------------------------------------ r830013 | fenton | 2008-07-09 10:20:39 -0400 (Wed, 09 Jul 2008) | 2 lines Add tracking of displayed relations to LegendItem. ------------------------------------------------------------------------ r829689 | fenton | 2008-07-08 17:15:18 -0400 (Tue, 08 Jul 2008) | 2 lines Add Label Parsing to Plot Labels and drawing into Pixmap. ------------------------------------------------------------------------ r829277 | netterfield | 2008-07-07 19:50:09 -0400 (Mon, 07 Jul 2008) | 3 lines a placeholder icon for text labels. ------------------------------------------------------------------------ r829276 | netterfield | 2008-07-07 19:48:58 -0400 (Mon, 07 Jul 2008) | 7 lines -matrixSelector, scalarSelector and vectorSelector now can access the name of newly created objects, and set themselves to view them -move to icons only on toolbar (more compact!) ------------------------------------------------------------------------ r829239 | fenton | 2008-07-07 17:29:47 -0400 (Mon, 07 Jul 2008) | 2 lines Enable printing and exporting of graphics file. ------------------------------------------------------------------------ r829183 | fenton | 2008-07-07 15:32:31 -0400 (Mon, 07 Jul 2008) | 2 lines Add Editor for Legend Item. ------------------------------------------------------------------------ r828069 | fenton | 2008-07-04 10:37:17 -0400 (Fri, 04 Jul 2008) | 2 lines Add Legend class with placement but no drawing. ------------------------------------------------------------------------ r827871 | netterfield | 2008-07-03 20:51:53 -0400 (Thu, 03 Jul 2008) | 3 lines add bug ------------------------------------------------------------------------ r826873 | netterfield | 2008-07-01 14:08:52 -0400 (Tue, 01 Jul 2008) | 3 lines Clarify bug ------------------------------------------------------------------------ r826845 | netterfield | 2008-07-01 11:52:29 -0400 (Tue, 01 Jul 2008) | 3 lines delete now empty defaultnames.? and all references to it. ------------------------------------------------------------------------ r826599 | netterfield | 2008-07-01 00:00:08 -0400 (Tue, 01 Jul 2008) | 6 lines Numerous dialog and naming bug fixes, including: -scalar combo refilling from equation dialog -better combo to equation filling -fix generated scalar naming ------------------------------------------------------------------------ r826571 | netterfield | 2008-06-30 20:24:06 -0400 (Mon, 30 Jun 2008) | 3 lines Now we can change the names of generated vectors. ------------------------------------------------------------------------ r826570 | netterfield | 2008-06-30 20:13:46 -0400 (Mon, 30 Jun 2008) | 3 lines Changing entries one of the vector combos in the equation dialog changes the others as well. ------------------------------------------------------------------------ r826552 | netterfield | 2008-06-30 19:13:04 -0400 (Mon, 30 Jun 2008) | 8 lines If the content of any vector combo in the curve dialog is changed (eg, new vector, or edit, which could change the name) then repopulate all of the combos - so they read and contain all the correct stuff. This needs to be done to all of the other combos that refer to multiple vectors as well (ie, equation dialog) ------------------------------------------------------------------------ r826472 | netterfield | 2008-06-30 16:09:06 -0400 (Mon, 30 Jun 2008) | 6 lines -Add tool tip descriptions to most objects. -Convince vector selectors to show the newly created vector, if you create a new vector from the vector selector. Still needs to be done to scalar and matrix selectors. ------------------------------------------------------------------------ r826471 | netterfield | 2008-06-30 16:05:32 -0400 (Mon, 30 Jun 2008) | 4 lines -More documentation on grids and layouts -New bugs. ------------------------------------------------------------------------ r824385 | fenton | 2008-06-25 13:12:43 -0400 (Wed, 25 Jun 2008) | 2 lines Cleanup of warnings / constructors for base objects. ------------------------------------------------------------------------ r824252 | fenton | 2008-06-25 09:31:31 -0400 (Wed, 25 Jun 2008) | 2 lines Fix display of filltab when used on PlotItemDialog. ------------------------------------------------------------------------ r824027 | fenton | 2008-06-24 13:23:47 -0400 (Tue, 24 Jun 2008) | 4 lines Clean up of Primitive Constructors. Fix memory allocation error in Matrices. Fix DataSource Tests. ------------------------------------------------------------------------ r823651 | fenton | 2008-06-23 15:24:12 -0400 (Mon, 23 Jun 2008) | 2 lines Fix warnings. ------------------------------------------------------------------------ r823635 | fenton | 2008-06-23 14:38:45 -0400 (Mon, 23 Jun 2008) | 4 lines Cleanup of unused/undesireable constructors for DataObjects. Fixing of Tests. Fix crash in DataObjectConfigWidget. ------------------------------------------------------------------------ r822575 | fenton | 2008-06-20 13:13:44 -0400 (Fri, 20 Jun 2008) | 2 lines Cleanup of stale FIXME's for placement / undo. Behavior matches 1.X ------------------------------------------------------------------------ r822525 | fenton | 2008-06-20 10:17:50 -0400 (Fri, 20 Jun 2008) | 2 lines Remove Todo in save of document. Continue to save on every request. ------------------------------------------------------------------------ r822308 | fenton | 2008-06-19 15:50:42 -0400 (Thu, 19 Jun 2008) | 2 lines Cleanup Todo. ------------------------------------------------------------------------ r822306 | fenton | 2008-06-19 15:46:08 -0400 (Thu, 19 Jun 2008) | 2 lines Todo cleanup. ------------------------------------------------------------------------ r822302 | fenton | 2008-06-19 15:31:34 -0400 (Thu, 19 Jun 2008) | 2 lines Cleanup of Saving Todo's. ------------------------------------------------------------------------ r822242 | fenton | 2008-06-19 12:11:08 -0400 (Thu, 19 Jun 2008) | 3 lines Allow DirFile to function with Directories provider or format file in addition to .cur file. Add disabled interfaced for providing directories to DataVector. ------------------------------------------------------------------------ r822084 | netterfield | 2008-06-18 23:26:18 -0400 (Wed, 18 Jun 2008) | 3 lines Add tooltips to curves in the plot content tab ------------------------------------------------------------------------ r821863 | fenton | 2008-06-18 13:37:03 -0400 (Wed, 18 Jun 2008) | 2 lines Cleanup and enable GradientEditor. ------------------------------------------------------------------------ r821570 | fenton | 2008-06-17 16:49:14 -0400 (Tue, 17 Jun 2008) | 2 lines Bug status update. ------------------------------------------------------------------------ r821488 | netterfield | 2008-06-17 11:52:10 -0400 (Tue, 17 Jun 2008) | 6 lines Fix bugs in equation names (in particular, make scalar and vector references in equations dynamic). Take Mike's advice on names, and rely more heavily on the short name. ------------------------------------------------------------------------ r821487 | fenton | 2008-06-17 11:51:24 -0400 (Tue, 17 Jun 2008) | 3 lines Update KstFile Specification to be current including all name changes. Update BasicPlugin to save correctly using PNUM instead of HNUM. ------------------------------------------------------------------------ r821188 | fenton | 2008-06-16 15:32:37 -0400 (Mon, 16 Jun 2008) | 3 lines Remaining cleanup of unused constructors. Fix for crash when creating an EventMonitor DataObject. ------------------------------------------------------------------------ r821147 | fenton | 2008-06-16 11:38:43 -0400 (Mon, 16 Jun 2008) | 2 lines Fix SegFault in SamplePlugin ------------------------------------------------------------------------ r821136 | fenton | 2008-06-16 10:56:32 -0400 (Mon, 16 Jun 2008) | 4 lines Cleanup of unused constructors. Fix Sample Plugin constructor access. Remove unnecessary friend classes and comment from primitives, relations and dataobjects. ------------------------------------------------------------------------ r820286 | fenton | 2008-06-13 15:00:03 -0400 (Fri, 13 Jun 2008) | 2 lines Add Spike Insensitive logic for zooming. ------------------------------------------------------------------------ r820192 | fenton | 2008-06-13 10:40:06 -0400 (Fri, 13 Jun 2008) | 2 lines Cleanup of PlotDefines.h. ------------------------------------------------------------------------ r819992 | fenton | 2008-06-12 16:17:31 -0400 (Thu, 12 Jun 2008) | 2 lines Fixes for shortcut Key conflicts with plots and menus. ------------------------------------------------------------------------ r819888 | fenton | 2008-06-12 10:18:40 -0400 (Thu, 12 Jun 2008) | 2 lines Update for zooming. Remove zoom from main undo stack. Add middle mouse undo. ------------------------------------------------------------------------ r819531 | fenton | 2008-06-11 10:15:44 -0400 (Wed, 11 Jun 2008) | 3 lines Redo of Plot zoom stack. Add ability to not add to view undostack. Fix for Log Zoom. ------------------------------------------------------------------------ r818809 | fenton | 2008-06-09 14:05:34 -0400 (Mon, 09 Jun 2008) | 2 lines Clean up of debug code. ------------------------------------------------------------------------ r817945 | netterfield | 2008-06-07 02:49:58 -0400 (Sat, 07 Jun 2008) | 4 lines -add description tip to vector selector and scalar selector -add the tip to a number of data objects. ------------------------------------------------------------------------ r817714 | fenton | 2008-06-06 14:29:26 -0400 (Fri, 06 Jun 2008) | 2 lines Fix for updates not functioning on objects related to DataVectors. ------------------------------------------------------------------------ r817230 | fenton | 2008-06-05 11:06:39 -0400 (Thu, 05 Jun 2008) | 2 lines Fix DirFile to load and update correctly. ------------------------------------------------------------------------ r815990 | netterfield | 2008-06-02 19:53:29 -0400 (Mon, 02 Jun 2008) | 8 lines Move name stuff from object into new namedObject class, so that names can be added to view objects if we decide we want this. Start with adding tooltip comments. Vector selectors now have them, and vectors now produce them. ------------------------------------------------------------------------ r815796 | fenton | 2008-06-02 11:19:20 -0400 (Mon, 02 Jun 2008) | 3 lines Add Dialog Default support for DatObject Plugins. Fully document SamplePlugin to serve as guide for DataObjectPlugin creation. ------------------------------------------------------------------------ r814534 | fenton | 2008-05-30 11:51:00 -0400 (Fri, 30 May 2008) | 2 lines Update plugin to use new config. Add support for Load/Save of Plugin DataObjects. ------------------------------------------------------------------------ r814004 | netterfield | 2008-05-28 23:18:47 -0400 (Wed, 28 May 2008) | 6 lines The last vestiges of the old republic have been swept away... That is to say - good by old tags, hello new dynamic names. This certainly introduces new bugs. ------------------------------------------------------------------------ r813770 | fenton | 2008-05-28 14:15:05 -0400 (Wed, 28 May 2008) | 2 lines Extend SamplePlugin/Plugin Interface to support custom configuration widgets / editing of plugin objects. ------------------------------------------------------------------------ r812903 | fenton | 2008-05-26 11:36:34 -0400 (Mon, 26 May 2008) | 4 lines Add input only sample plugin (to be expanded) Divide plugin interfaces into basic / dataobject and move dataobject plugin interface to libkstmath Add basic setup for dataobject plugins to datamanager / dialog launcher. ------------------------------------------------------------------------ r811608 | netterfield | 2008-05-23 10:03:29 -0400 (Fri, 23 May 2008) | 5 lines Add dirfile maker. Some changes to tests related to new naming scheme. ------------------------------------------------------------------------ r811284 | fenton | 2008-05-22 14:17:35 -0400 (Thu, 22 May 2008) | 3 lines Point drawing optimizations. Prevent multiple points from being drawn repeatedly in point dense curves. Eliminate region calculations for point proximity calculations. ------------------------------------------------------------------------ r810759 | fenton | 2008-05-21 10:47:31 -0400 (Wed, 21 May 2008) | 2 lines Update PlotRenderItem's hover to grab focus automatically to allow Keyboard control for mouse over items. ------------------------------------------------------------------------ r810366 | fenton | 2008-05-20 10:52:33 -0400 (Tue, 20 May 2008) | 2 lines Update tests to compile / pass with tag updates. ------------------------------------------------------------------------ r808135 | fenton | 2008-05-15 15:26:51 -0400 (Thu, 15 May 2008) | 2 lines Add new XRange / YRange zoom to allow tied zoom to function as desired using CTRL/SHIFT mouse zoom. ------------------------------------------------------------------------ r807909 | netterfield | 2008-05-14 22:59:41 -0400 (Wed, 14 May 2008) | 5 lines More changes to new Names: many qwarnings now use new names delete unused functions ------------------------------------------------------------------------ r807905 | netterfield | 2008-05-14 22:05:51 -0400 (Wed, 14 May 2008) | 3 lines remove bug that has been resolved ------------------------------------------------------------------------ r807904 | netterfield | 2008-05-14 22:04:41 -0400 (Wed, 14 May 2008) | 6 lines More work on new names: short names save efficiently index values are reset on load start to remove useage of tag names, and replace with shortNames. ------------------------------------------------------------------------ r807798 | fenton | 2008-05-14 15:20:27 -0400 (Wed, 14 May 2008) | 2 lines Fix Curve Saving. Update Curve Drawing to follow line width directions regardless of pen width. ------------------------------------------------------------------------ r807723 | fenton | 2008-05-14 10:58:55 -0400 (Wed, 14 May 2008) | 2 lines Fix crash in DataManager. Update logic to properly support outputMatrices. ------------------------------------------------------------------------ r807372 | fenton | 2008-05-13 14:24:50 -0400 (Tue, 13 May 2008) | 2 lines Add Matrix/Scalar handling to update cycle. Optimizations and bug fixes. ------------------------------------------------------------------------ r805898 | fenton | 2008-05-09 11:34:34 -0400 (Fri, 09 May 2008) | 2 lines Update related cleanup. Removal of updateversion/lastupdatestatus. ------------------------------------------------------------------------ r805865 | netterfield | 2008-05-09 09:30:29 -0400 (Fri, 09 May 2008) | 3 lines Add forgotten file for short names. ------------------------------------------------------------------------ r805659 | netterfield | 2008-05-08 23:22:39 -0400 (Thu, 08 May 2008) | 3 lines The rest of the commit... new naming system ------------------------------------------------------------------------ r805657 | netterfield | 2008-05-08 23:18:53 -0400 (Thu, 08 May 2008) | 6 lines New Naming system: set, save, and load manual descriptive names save and load short names for data objects and primitives. ------------------------------------------------------------------------ r805409 | fenton | 2008-05-08 10:07:04 -0400 (Thu, 08 May 2008) | 2 lines Add File System watching for DataSource updates. ------------------------------------------------------------------------ r805156 | fenton | 2008-05-07 14:47:14 -0400 (Wed, 07 May 2008) | 2 lines Add setting to control update manager maximum update frequency. ------------------------------------------------------------------------ r805112 | netterfield | 2008-05-07 11:41:40 -0400 (Wed, 07 May 2008) | 2 lines Update bugs ------------------------------------------------------------------------ r805094 | fenton | 2008-05-07 11:04:48 -0400 (Wed, 07 May 2008) | 2 lines Add reference counting to update cycle and checks before relations/plots are permitted to update. ------------------------------------------------------------------------ r804343 | netterfield | 2008-05-05 14:35:02 -0400 (Mon, 05 May 2008) | 2 lines update bugs ------------------------------------------------------------------------ r803297 | fenton | 2008-05-02 10:18:06 -0400 (Fri, 02 May 2008) | 2 lines Initial version of UpdateManager. ------------------------------------------------------------------------ r803011 | fenton | 2008-05-01 11:06:00 -0400 (Thu, 01 May 2008) | 2 lines Add logic to decrease the number of Major Ticks / Switch to Base Offset mode dependent on the drawn length of lengths to prevent overlap of x Axis labels. ------------------------------------------------------------------------ r802528 | fenton | 2008-04-29 15:06:23 -0400 (Tue, 29 Apr 2008) | 2 lines Fix for disconnect errors. ------------------------------------------------------------------------ r802515 | fenton | 2008-04-29 13:30:39 -0400 (Tue, 29 Apr 2008) | 2 lines Move save/load of PlotAxis details into PlotAxis. Add saving of PlotMarkers. Fix drawing of incorrect subset for plot markers. ------------------------------------------------------------------------ r802158 | fenton | 2008-04-28 13:47:40 -0400 (Mon, 28 Apr 2008) | 3 lines Fix of DataVector creation. Object name was being changed resulting in tag name not matching registered name in ObjectStore. Disable name update in Edit of DataVector. ------------------------------------------------------------------------ r802112 | fenton | 2008-04-28 11:01:27 -0400 (Mon, 28 Apr 2008) | 3 lines Update conversion of MaptoProject to properly support conversion when Axis are reversed. Move drawing of SelectionRect outside of the painter translation to match the mouse / cursor location. ------------------------------------------------------------------------ r801171 | fenton | 2008-04-25 16:38:37 -0400 (Fri, 25 Apr 2008) | 2 lines Fix for Cursor updates in layout mode of PlotRenderItem's conflicting with ViewItems. ------------------------------------------------------------------------ r800746 | fenton | 2008-04-24 15:18:52 -0400 (Thu, 24 Apr 2008) | 2 lines Initial signal / slot based update for Data Based Vector paths. ------------------------------------------------------------------------ r800228 | fenton | 2008-04-23 13:54:03 -0400 (Wed, 23 Apr 2008) | 3 lines Initial version of PlotAxis, simplification of PlotItem. A number of related bug fixes. ------------------------------------------------------------------------ r799492 | fenton | 2008-04-21 13:27:37 -0400 (Mon, 21 Apr 2008) | 2 lines Update to a cached tick/label system to allow proper sizing for margins. ------------------------------------------------------------------------ r798239 | fenton | 2008-04-17 15:50:56 -0400 (Thu, 17 Apr 2008) | 2 lines Merger of Zooming / Projection Rect into plotItem to allow Plot based zoom. ------------------------------------------------------------------------ r797680 | fenton | 2008-04-16 14:19:42 -0400 (Wed, 16 Apr 2008) | 2 lines Removal of stale comment. ------------------------------------------------------------------------ r797679 | fenton | 2008-04-16 14:06:26 -0400 (Wed, 16 Apr 2008) | 2 lines Removing stale comment. ------------------------------------------------------------------------ r797361 | fenton | 2008-04-15 12:02:18 -0400 (Tue, 15 Apr 2008) | 3 lines Convert to single viewItem popup with ability to add entries. Divide margin calculations to individual values for top/bottom and left/right. ------------------------------------------------------------------------ r797003 | fenton | 2008-04-14 13:22:09 -0400 (Mon, 14 Apr 2008) | 2 lines Fix for CTRL/SHIFT selection rect marker not clearing on key release. ------------------------------------------------------------------------ r795915 | fenton | 2008-04-11 18:06:05 -0400 (Fri, 11 Apr 2008) | 3 lines Fix for label margin sizes. Add X11 DPI check for font sizes. ------------------------------------------------------------------------ r795314 | netterfield | 2008-04-09 15:46:10 -0400 (Wed, 09 Apr 2008) | 3 lines couple more bugs ------------------------------------------------------------------------ r795310 | netterfield | 2008-04-09 15:31:23 -0400 (Wed, 09 Apr 2008) | 2 lines couple new bugs ------------------------------------------------------------------------ r795208 | netterfield | 2008-04-09 09:46:54 -0400 (Wed, 09 Apr 2008) | 2 lines Delete closed bugs ------------------------------------------------------------------------ r793685 | netterfield | 2008-04-04 16:02:44 -0400 (Fri, 04 Apr 2008) | 7 lines Start of new naming scheme. The names are in place. They are not currently being saved or loaded, and are not used, except in the data manager where the name is displayed. ------------------------------------------------------------------------ r793684 | fenton | 2008-04-04 16:01:04 -0400 (Fri, 04 Apr 2008) | 3 lines Fix for significant digits on automatic base/offset mode. Fix for Load of plot item with adjusted projectionRect. ------------------------------------------------------------------------ r793312 | fenton | 2008-04-03 11:46:35 -0400 (Thu, 03 Apr 2008) | 2 lines Fix for Font size jumping. ------------------------------------------------------------------------ r792946 | fenton | 2008-04-02 12:23:13 -0400 (Wed, 02 Apr 2008) | 2 lines Add fix for zoom/shared axis updates. ------------------------------------------------------------------------ r792352 | netterfield | 2008-03-31 17:17:06 -0400 (Mon, 31 Mar 2008) | 2 lines Bugs update ------------------------------------------------------------------------ r792188 | fenton | 2008-03-31 11:53:43 -0400 (Mon, 31 Mar 2008) | 2 lines Fix for OpenGL Mode not properly activating. ------------------------------------------------------------------------ r791195 | fenton | 2008-03-28 13:36:35 -0400 (Fri, 28 Mar 2008) | 3 lines Fix Selection Rect drawing for Zoom. Fix delay in plot item rect updates when changing zoom state. ------------------------------------------------------------------------ r790054 | fenton | 2008-03-25 15:41:15 -0400 (Tue, 25 Mar 2008) | 3 lines Remove Line based items from the grid layout maintaining the aspect ratio of the item independently. Prevent grid layout items from calculating to a negative width/height. ------------------------------------------------------------------------ r787166 | tskisner | 2008-03-18 13:58:40 -0400 (Tue, 18 Mar 2008) | 1 line This source uses UINT_MAX, which is defined in limits.h, which is included in math_kst.h. Include that header here ------------------------------------------------------------------------ r786698 | fenton | 2008-03-17 15:13:33 -0400 (Mon, 17 Mar 2008) | 3 lines Convert Reference View Width/Height to be calculated in centimeters and then converted to points before use. Add trigger of apply signal when ok is clicked as part of Dialog. ------------------------------------------------------------------------ r786650 | fenton | 2008-03-17 10:53:58 -0400 (Mon, 17 Mar 2008) | 2 lines Add TriggerReset to SessionModel to allow DataManager to update correctly. ------------------------------------------------------------------------ r785699 | fenton | 2008-03-14 15:00:38 -0400 (Fri, 14 Mar 2008) | 6 lines Add Font scaling to the View based upon settings according to Fonts spec. Add saving of application level settings. Add LabelItem properties and scaling. Use Font scale as Arrow Head Scaling Value. Convert all font size values to scale values. ------------------------------------------------------------------------ r784546 | fenton | 2008-03-11 13:31:59 -0400 (Tue, 11 Mar 2008) | 3 lines Add setting for significant digits on Axis before switching to Base/Offset Mode. Fix margin sizing for large y axis tick labels. ------------------------------------------------------------------------ r784162 | fenton | 2008-03-10 15:35:47 -0400 (Mon, 10 Mar 2008) | 2 lines Rework updateChildGeometry for LineItem to match adjustments done by Standard/Unlocked items. ------------------------------------------------------------------------ r784054 | fenton | 2008-03-10 11:06:24 -0400 (Mon, 10 Mar 2008) | 2 lines Fixing Kst Bug Re: Plot Markers for Shift/Ctrl Mouse zoom. Add Keyboard handling and update hoverMouseMove to update the cursor / draw the selection line for zoom. ------------------------------------------------------------------------ r783301 | fenton | 2008-03-07 13:48:05 -0500 (Fri, 07 Mar 2008) | 4 lines Convert Static updateChildGeometry to virtual functions. Add updated line / arrow geometry updates. Fix for parent level rotated view items not having a proper relative size. ------------------------------------------------------------------------ r783010 | fenton | 2008-03-06 14:16:01 -0500 (Thu, 06 Mar 2008) | 3 lines Fix Log Axis Mouse Zoom. Move all point/rect projection calculations to PlotItem. ------------------------------------------------------------------------ r782933 | fenton | 2008-03-06 09:47:10 -0500 (Thu, 06 Mar 2008) | 3 lines Reworking of Dialog for PlotItem/PlotRenderItem. Move dialog to be based on PlotItem, and move all Log based settings into PlotItem. ------------------------------------------------------------------------ r782662 | fenton | 2008-03-05 12:10:03 -0500 (Wed, 05 Mar 2008) | 3 lines Redo of Line/Arrow updates. Add ArrowItemDialog and configuration of Arrow settings. ------------------------------------------------------------------------ r782272 | fenton | 2008-03-04 13:27:52 -0500 (Tue, 04 Mar 2008) | 3 lines Add Fix for Shared Axis. Update handling of PlotAxis margin calculations. ------------------------------------------------------------------------ r781875 | fenton | 2008-03-03 14:34:54 -0500 (Mon, 03 Mar 2008) | 3 lines Redo of updateChildGeometry to properly resize items with locked aspect ratio and rotated. Add setting for lock aspect ratio to ViewItem. ------------------------------------------------------------------------ r780806 | netterfield | 2008-02-29 21:53:24 -0500 (Fri, 29 Feb 2008) | 4 lines Delete and add some bugs Completely re-work the object name spec. ------------------------------------------------------------------------ r780601 | fenton | 2008-02-29 10:07:55 -0500 (Fri, 29 Feb 2008) | 3 lines Add Plot Markers for both x and y Axis. Add CurveSelector Widget. ------------------------------------------------------------------------ r779995 | fenton | 2008-02-27 14:07:01 -0500 (Wed, 27 Feb 2008) | 2 lines Add MarkersTab as PlotRenderItemDialog option. ------------------------------------------------------------------------ r779700 | fenton | 2008-02-26 15:28:23 -0500 (Tue, 26 Feb 2008) | 2 lines Fix updating of Apply button on Label tab. ------------------------------------------------------------------------ r779655 | fenton | 2008-02-26 13:55:58 -0500 (Tue, 26 Feb 2008) | 3 lines Fix plot alignment when plot is resized. Fix for plot not drawing when a plot is drawn but no plotrenderitem is present. ------------------------------------------------------------------------ r779319 | fenton | 2008-02-25 16:33:38 -0500 (Mon, 25 Feb 2008) | 3 lines Fix for Layout mode not removing gribs. Add improved grip updating for ViewItem. ------------------------------------------------------------------------ r779260 | fenton | 2008-02-25 13:46:44 -0500 (Mon, 25 Feb 2008) | 2 lines Update zoom to support log axis. Fix for log load not updating menu status. ------------------------------------------------------------------------ r779097 | fenton | 2008-02-25 09:00:45 -0500 (Mon, 25 Feb 2008) | 2 lines Fix minor tick labels not drawn when no major tick is drawn. ------------------------------------------------------------------------ r778208 | fenton | 2008-02-22 16:21:27 -0500 (Fri, 22 Feb 2008) | 3 lines Major reworking of plot mapping to support Log Axis and reverse internally. Clean up of Tick Calculation. ------------------------------------------------------------------------ r778145 | netterfield | 2008-02-22 11:50:22 -0500 (Fri, 22 Feb 2008) | 2 lines Some notes on updates. ------------------------------------------------------------------------ r778130 | netterfield | 2008-02-22 11:21:04 -0500 (Fri, 22 Feb 2008) | 2 lines Add bug. ------------------------------------------------------------------------ r778128 | netterfield | 2008-02-22 11:01:19 -0500 (Fri, 22 Feb 2008) | 2 lines Remove some compiler warnings. ------------------------------------------------------------------------ r778125 | netterfield | 2008-02-22 10:58:27 -0500 (Fri, 22 Feb 2008) | 2 lines Add and update some development documenation. ------------------------------------------------------------------------ r777820 | fenton | 2008-02-21 12:46:44 -0500 (Thu, 21 Feb 2008) | 3 lines Add Circle Item as options for Layout. Fix locked Aspect Ratio in ViewItem. ------------------------------------------------------------------------ r777750 | netterfield | 2008-02-21 08:47:21 -0500 (Thu, 21 Feb 2008) | 2 lines Added list of layout mode bugs. ------------------------------------------------------------------------ r777550 | fenton | 2008-02-20 16:51:13 -0500 (Wed, 20 Feb 2008) | 2 lines Add Arrow as ViewItem. ------------------------------------------------------------------------ r777480 | fenton | 2008-02-20 13:19:18 -0500 (Wed, 20 Feb 2008) | 2 lines Add proper cursor updating for view items in Layout Mode. ------------------------------------------------------------------------ r777106 | fenton | 2008-02-19 14:03:28 -0500 (Tue, 19 Feb 2008) | 2 lines Fix crash when no ticks are allowed. ------------------------------------------------------------------------ r777054 | netterfield | 2008-02-19 10:10:27 -0500 (Tue, 19 Feb 2008) | 3 lines More command line functionality. ------------------------------------------------------------------------ r777053 | netterfield | 2008-02-19 10:09:32 -0500 (Tue, 19 Feb 2008) | 2 lines Update some of the documentation: move things into the right docs. ------------------------------------------------------------------------ r777047 | fenton | 2008-02-19 09:50:36 -0500 (Tue, 19 Feb 2008) | 2 lines Redo of labelling and update to reverse axis drawing code to support LogAxis. ------------------------------------------------------------------------ r775347 | fenton | 2008-02-15 10:40:16 -0500 (Fri, 15 Feb 2008) | 2 lines Add Log Axis drawing. ------------------------------------------------------------------------ r774610 | fenton | 2008-02-13 11:46:00 -0500 (Wed, 13 Feb 2008) | 4 lines Add new parameters to save of PlotItem. Fix crash in restore of relations of plots. Update DataVector save to include tag. ------------------------------------------------------------------------ r774235 | fenton | 2008-02-12 15:30:55 -0500 (Tue, 12 Feb 2008) | 2 lines Add interface for log axis. ------------------------------------------------------------------------ r773811 | fenton | 2008-02-11 15:49:34 -0500 (Mon, 11 Feb 2008) | 2 lines Add reverse drawing of the relations. ------------------------------------------------------------------------ r773788 | fenton | 2008-02-11 14:22:10 -0500 (Mon, 11 Feb 2008) | 2 lines Add interpretation of values to Date/Time. ------------------------------------------------------------------------ r772603 | netterfield | 2008-02-09 01:32:03 -0500 (Sat, 09 Feb 2008) | 3 lines Vectors are no longer duplicated from command line. ------------------------------------------------------------------------ r772433 | fenton | 2008-02-08 13:49:35 -0500 (Fri, 08 Feb 2008) | 2 lines Add Axis drawing of Base/offset mode. ------------------------------------------------------------------------ r772124 | fenton | 2008-02-07 15:59:27 -0500 (Thu, 07 Feb 2008) | 3 lines Add Reverse drawing of Plot Axis Labels. Add interface for drawing base offset / interpretted Axis. ------------------------------------------------------------------------ r771735 | fenton | 2008-02-06 15:50:42 -0500 (Wed, 06 Feb 2008) | 3 lines Add label editor for plot, move Axis Plot controls to x-Axis / y-Axis Tab's. Add Axis scale options to tab. ------------------------------------------------------------------------ r771556 | netterfield | 2008-02-06 06:55:02 -0500 (Wed, 06 Feb 2008) | 4 lines Most of command line parsing is now done. However, it does not yet handle .kst files, nor matrixes. ------------------------------------------------------------------------ r771380 | fenton | 2008-02-05 15:13:38 -0500 (Tue, 05 Feb 2008) | 2 lines Limit max size for selectors. ------------------------------------------------------------------------ r771378 | fenton | 2008-02-05 15:13:02 -0500 (Tue, 05 Feb 2008) | 2 lines Add relation removal to Plot Render Item Dialog content Tab. ------------------------------------------------------------------------ r771337 | fenton | 2008-02-05 14:00:26 -0500 (Tue, 05 Feb 2008) | 2 lines Add Minor Grid / Minor Tick drawing as well as full customization of lines. ------------------------------------------------------------------------ r770971 | fenton | 2008-02-04 16:04:32 -0500 (Mon, 04 Feb 2008) | 3 lines Add new Plot Marker settings Tab to control properties of Major/Minor Tick/Grid Lines. Settings are not currently connected. ------------------------------------------------------------------------ r769701 | fenton | 2008-02-01 16:14:32 -0500 (Fri, 01 Feb 2008) | 2 lines Update to plot axis rendering from Adam with added margin to account for axis label and drawing of Major Ticks/Grid lines. ------------------------------------------------------------------------ r769698 | fenton | 2008-02-01 16:11:18 -0500 (Fri, 01 Feb 2008) | 2 lines Update DataMatrix Test. ------------------------------------------------------------------------ r769215 | netterfield | 2008-01-31 16:18:51 -0500 (Thu, 31 Jan 2008) | 3 lines More progress on command line parsing. .kst files not yet fixed. ------------------------------------------------------------------------ r769155 | fenton | 2008-01-31 12:47:40 -0500 (Thu, 31 Jan 2008) | 2 lines Increase resolution of number drawing so that the same number should not appear for multiple lines. ------------------------------------------------------------------------ r768898 | fenton | 2008-01-30 16:32:34 -0500 (Wed, 30 Jan 2008) | 2 lines Ensure that the top most axis label and the right most axis label are always fully drawn. ------------------------------------------------------------------------ r768867 | fenton | 2008-01-30 15:28:33 -0500 (Wed, 30 Jan 2008) | 2 lines Fix Zoom Y Out. ------------------------------------------------------------------------ r768824 | netterfield | 2008-01-30 13:26:31 -0500 (Wed, 30 Jan 2008) | 3 lines Add the actual code for the command line parser... ------------------------------------------------------------------------ r768565 | netterfield | 2008-01-30 06:37:53 -0500 (Wed, 30 Jan 2008) | 4 lines Starting command line parsing.... Reading .kst files is temporarily broken. ------------------------------------------------------------------------ r768365 | fenton | 2008-01-29 16:47:42 -0500 (Tue, 29 Jan 2008) | 2 lines Update bug list. ------------------------------------------------------------------------ r768363 | fenton | 2008-01-29 16:47:17 -0500 (Tue, 29 Jan 2008) | 2 lines Update fileRequester to do autocompletion of the path. ------------------------------------------------------------------------ r768344 | fenton | 2008-01-29 15:36:02 -0500 (Tue, 29 Jan 2008) | 4 lines Update MatrixDialog to allow setting of xMin, yMin, xStep and yStep to DataMatrix. Add ifdef to remove GeneratedMatrix options from creation. Update default values for scaling/translation to match object defaults. ------------------------------------------------------------------------ r768342 | fenton | 2008-01-29 15:33:36 -0500 (Tue, 29 Jan 2008) | 2 lines Update DataMatrix to support configuration of xMin, yMin xStep and yStep. ------------------------------------------------------------------------ r750113 | fenton | 2007-12-18 12:55:18 -0500 (Tue, 18 Dec 2007) | 2 lines Add functionality to ExportGraphicsDialog and connect UI components. ------------------------------------------------------------------------ r749807 | netterfield | 2007-12-17 17:41:51 -0500 (Mon, 17 Dec 2007) | 3 lines Add a command line syntax document. I will start implementation. ------------------------------------------------------------------------ r748568 | fenton | 2007-12-14 15:26:46 -0500 (Fri, 14 Dec 2007) | 2 lines Update linux define to include MemoryWidget functionality as well as memory checks in DataWizard and DataCollection. ------------------------------------------------------------------------ r748543 | fenton | 2007-12-14 14:13:50 -0500 (Fri, 14 Dec 2007) | 2 lines Redo StringModel to include strings outputted by DataObjects. ------------------------------------------------------------------------ r748487 | fenton | 2007-12-14 11:15:42 -0500 (Fri, 14 Dec 2007) | 3 lines Update ScalarModel to display Scalars of Vectors/Matrices including output Vectors/Matrices of DataObjects. Create generic ViewPrimitiveDialog with QTreeView for Scalars/Strings. ------------------------------------------------------------------------ r748093 | fenton | 2007-12-13 10:49:55 -0500 (Thu, 13 Dec 2007) | 3 lines Improve ColorMap drawing performance in Image by replacing setPixel with scanLine. Fix output matrix creation of CSD. ------------------------------------------------------------------------ r747702 | fenton | 2007-12-12 14:35:10 -0500 (Wed, 12 Dec 2007) | 3 lines Add Apply and EditMultiple Functionality to CSDDialog. Disable InterpolateOverHoles in FFTOptions for CSD's. ------------------------------------------------------------------------ r747502 | netterfield | 2007-12-12 01:17:13 -0500 (Wed, 12 Dec 2007) | 5 lines Some tagname work. Add color sequence to color appearance widget. ------------------------------------------------------------------------ r747395 | fenton | 2007-12-11 16:50:58 -0500 (Tue, 11 Dec 2007) | 2 lines Add Apply Button and Edit multiple Functionality to EventMonitorDialog. ------------------------------------------------------------------------ r747322 | fenton | 2007-12-11 13:13:10 -0500 (Tue, 11 Dec 2007) | 2 lines Add Apply Button and EditMultiple support to ImageDialog. ------------------------------------------------------------------------ r745662 | fenton | 2007-12-06 14:16:18 -0500 (Thu, 06 Dec 2007) | 2 lines Add Apply button and Edit Multiple support to PowerSpectrumDialog. ------------------------------------------------------------------------ r745600 | fenton | 2007-12-06 09:49:53 -0500 (Thu, 06 Dec 2007) | 3 lines Add Apply and EditMultiple Functionality to Histogram Dialog. Fix logic error in EquationDialog. ------------------------------------------------------------------------ r745284 | fenton | 2007-12-05 16:36:08 -0500 (Wed, 05 Dec 2007) | 2 lines Add Apply function and EditMultiple support to EquationDialog. ------------------------------------------------------------------------ r745221 | fenton | 2007-12-05 14:26:39 -0500 (Wed, 05 Dec 2007) | 2 lines Add Apply button to DataDialog for editing and enable on Curve, Matrix and Vector Dialogs. ------------------------------------------------------------------------ r745218 | netterfield | 2007-12-05 14:10:49 -0500 (Wed, 05 Dec 2007) | 3 lines Start to get the names to work in dialogs. ------------------------------------------------------------------------ r745171 | fenton | 2007-12-05 11:33:36 -0500 (Wed, 05 Dec 2007) | 2 lines Move editMultipleMode flag logic into EditMode of DataDialog. ------------------------------------------------------------------------ r745140 | fenton | 2007-12-05 10:02:38 -0500 (Wed, 05 Dec 2007) | 4 lines Add support to CurveDialog for EditMultiple. Add Same as Minus checkbox functionality to CurveDialog. Add IgnoreAutoScale functionality to CurveDialog. ------------------------------------------------------------------------ r744826 | fenton | 2007-12-04 12:07:02 -0500 (Tue, 04 Dec 2007) | 2 lines Add EditMultiple support for Matrices. ------------------------------------------------------------------------ r744769 | staikos | 2007-12-04 06:55:24 -0500 (Tue, 04 Dec 2007) | 2 lines better fix - didn't notice this was using qt3support ------------------------------------------------------------------------ r744768 | staikos | 2007-12-04 06:52:55 -0500 (Tue, 04 Dec 2007) | 3 lines remove some warnings. Unfortunate that QCheckBox::state() returns a deprecated enum. ------------------------------------------------------------------------ r744664 | netterfield | 2007-12-03 21:39:28 -0500 (Mon, 03 Dec 2007) | 6 lines Fix default limits on matrixes. The vector selector was not working (it wouldn't set to the requested vector). This fixes it... but see the comments. ------------------------------------------------------------------------ r744538 | fenton | 2007-12-03 16:32:16 -0500 (Mon, 03 Dec 2007) | 2 lines Add EditMultiple support for Vectors. ------------------------------------------------------------------------ r743387 | fenton | 2007-11-30 15:38:04 -0500 (Fri, 30 Nov 2007) | 2 lines Replace current buttons with QDialogButtonBox with OK/Apply/Cancel functionality for ChooseColorDialog, ChangeDataSampleDialog and DifferentiateCurvesDialog. ------------------------------------------------------------------------ r743309 | fenton | 2007-11-30 10:57:27 -0500 (Fri, 30 Nov 2007) | 2 lines Update ChangeFileDialog to use DialogButtonBox for Ok/Apply/Cancel, add logic to OK/Apply buttons and fix crash. ------------------------------------------------------------------------ r743292 | fenton | 2007-11-30 09:29:27 -0500 (Fri, 30 Nov 2007) | 2 lines Add proper cleanup of DataSource dependents. ------------------------------------------------------------------------ r743096 | fenton | 2007-11-29 15:56:56 -0500 (Thu, 29 Nov 2007) | 2 lines Add support for ChangeFileDialog to create duplicate objects. ------------------------------------------------------------------------ r742983 | netterfield | 2007-11-29 09:58:46 -0500 (Thu, 29 Nov 2007) | 8 lines More work on defaults. -Widgets handle their own defaults with setWidgetDefault and loadWidgetDefault -Defaults added to curves, psds, matrixes, equations. ------------------------------------------------------------------------ r742717 | fenton | 2007-11-28 14:01:17 -0500 (Wed, 28 Nov 2007) | 2 lines Add proper cleanup of objects when removed from the ObjectStore. ------------------------------------------------------------------------ r742337 | fenton | 2007-11-27 16:07:47 -0500 (Tue, 27 Nov 2007) | 3 lines FIXME cleanup. Update Tag creation for Scalars. ------------------------------------------------------------------------ r742312 | fenton | 2007-11-27 15:17:39 -0500 (Tue, 27 Nov 2007) | 2 lines Add OutputVector context menu for creation of DataObjects. ------------------------------------------------------------------------ r742287 | fenton | 2007-11-27 14:05:42 -0500 (Tue, 27 Nov 2007) | 4 lines Add Image editing to PlotRenderItemDialog. Add Image support to Content Tab. Add Image support to Add To Plot. ------------------------------------------------------------------------ r742019 | fenton | 2007-11-26 17:37:58 -0500 (Mon, 26 Nov 2007) | 2 lines Add Editing of Curves to PlotRenderItemDialog. ------------------------------------------------------------------------ r741868 | fenton | 2007-11-26 11:29:05 -0500 (Mon, 26 Nov 2007) | 3 lines Integration of PlotRenderItem Content options into the ViewItemDialog layout. Addition of Content Option functionality. ------------------------------------------------------------------------ r740597 | fenton | 2007-11-23 11:00:17 -0500 (Fri, 23 Nov 2007) | 2 lines Add implementation for ChangeFileDialog. ------------------------------------------------------------------------ r740570 | fenton | 2007-11-23 09:31:13 -0500 (Fri, 23 Nov 2007) | 2 lines Fix build errors. Kst namespace cleanup. ------------------------------------------------------------------------ r740524 | netterfield | 2007-11-23 07:58:21 -0500 (Fri, 23 Nov 2007) | 5 lines -Move dialogdefaults to libkstapp. -remove the last vestages of the old default system. -dialogDefaults -> _dialogDefaults. ------------------------------------------------------------------------ r740187 | fenton | 2007-11-22 14:14:09 -0500 (Thu, 22 Nov 2007) | 2 lines Add functionality to the DifferentiateCurvesDialog. ------------------------------------------------------------------------ r739769 | fenton | 2007-11-21 16:02:24 -0500 (Wed, 21 Nov 2007) | 2 lines Add Implementation for ChooseColorDialog. ------------------------------------------------------------------------ r739749 | fenton | 2007-11-21 14:50:55 -0500 (Wed, 21 Nov 2007) | 2 lines Cleanup Kst references inside of Kst namespace. ------------------------------------------------------------------------ r739729 | fenton | 2007-11-21 12:58:37 -0500 (Wed, 21 Nov 2007) | 2 lines Add full functionality to the ChangeSampleDialog. ------------------------------------------------------------------------ r739690 | staikos | 2007-11-21 10:35:48 -0500 (Wed, 21 Nov 2007) | 5 lines make it compile by moving the power spectrum setting code into objectdefaults. I think it should be there anyway, and not use dialogdefaults at all, right? This is a bit of a hack but if it's the right approach it can be adjusted and cleaned. headers also cleaned up in a few files. ------------------------------------------------------------------------ r739327 | fenton | 2007-11-20 16:18:18 -0500 (Tue, 20 Nov 2007) | 2 lines Update DataManager context menu to include Add to and Remove From Plot for relations. Also implement Delete for all objects including cleanup of plots. ------------------------------------------------------------------------ r739121 | fenton | 2007-11-20 10:25:27 -0500 (Tue, 20 Nov 2007) | 2 lines Clean up formatting and eliminate overlapping null check. ------------------------------------------------------------------------ r739100 | fenton | 2007-11-20 09:18:08 -0500 (Tue, 20 Nov 2007) | 3 lines Add context menu support for object creation from DataManager. Extend DialogLauncher framework to allow specification of default selection. ------------------------------------------------------------------------ r738975 | netterfield | 2007-11-19 22:00:07 -0500 (Mon, 19 Nov 2007) | 4 lines powerspectrum dialog gets defaults. Datawizard shares them. ------------------------------------------------------------------------ r738793 | fenton | 2007-11-19 13:13:26 -0500 (Mon, 19 Nov 2007) | 2 lines Update session model to display DataVectors, GeneratedVectors, DataMatrix, GeneratedMatrix and outputVectors and output Matrices for DataObjects. ------------------------------------------------------------------------ r737641 | fenton | 2007-11-16 15:29:25 -0500 (Fri, 16 Nov 2007) | 3 lines Add edit Support for CSD's. Standardize variable/function names for PSD's and CSD's. ------------------------------------------------------------------------ r737576 | fenton | 2007-11-16 11:44:13 -0500 (Fri, 16 Nov 2007) | 2 lines Add Test for Generated Matrix. Fix Generated Matrix creation to include update so that scalars are generated. ------------------------------------------------------------------------ r737559 | fenton | 2007-11-16 09:37:07 -0500 (Fri, 16 Nov 2007) | 3 lines Add Edit support for ImageDialog. Update ImageDialog to include proper calculations for Min/Max and Smart Thresholds. ------------------------------------------------------------------------ r737323 | netterfield | 2007-11-15 22:33:30 -0500 (Thu, 15 Nov 2007) | 3 lines Move stuff to dialogdefaults.cpp. ------------------------------------------------------------------------ r737281 | netterfield | 2007-11-15 17:35:51 -0500 (Thu, 15 Nov 2007) | 4 lines Fix build troubles pointed out by Mike. ------------------------------------------------------------------------ r737248 | netterfield | 2007-11-15 16:34:23 -0500 (Thu, 15 Nov 2007) | 3 lines Vector defaults now mostly work. We need to delete and remove references to vectorDefaults now. ------------------------------------------------------------------------ r737182 | fenton | 2007-11-15 14:00:33 -0500 (Thu, 15 Nov 2007) | 2 lines Add edit support for EventMonitorDialog. ------------------------------------------------------------------------ r737151 | fenton | 2007-11-15 11:59:06 -0500 (Thu, 15 Nov 2007) | 3 lines Add Edit support for PowerSpectrumDialog. Update FFTOptions Widget to support setting of values. ------------------------------------------------------------------------ r737131 | fenton | 2007-11-15 10:30:37 -0500 (Thu, 15 Nov 2007) | 2 lines Add Edit support for Histogram's. ------------------------------------------------------------------------ r736816 | fenton | 2007-11-14 17:15:40 -0500 (Wed, 14 Nov 2007) | 2 lines Add Edit Capabilities to EquationDialog and connection in DataManager. ------------------------------------------------------------------------ r736789 | fenton | 2007-11-14 15:57:31 -0500 (Wed, 14 Nov 2007) | 4 lines Add Curve Editing to Dialog. Update Curve pointType to be private with accessor function. Update DataManager to display CurveDialog on Edit. ------------------------------------------------------------------------ r736759 | fenton | 2007-11-14 14:15:42 -0500 (Wed, 14 Nov 2007) | 3 lines Update SessionManager to also load relations. Include cleanup of sessionmodel.h. ------------------------------------------------------------------------ r736708 | netterfield | 2007-11-14 10:59:01 -0500 (Wed, 14 Nov 2007) | 9 lines Add default settings for the vector file name. Before I go and install things everywhere, I have a couple questions: -I added a new VectorDialog::configureNewTab because I couldn't see a place where new tab stuff got filled. Should it have gone in configureTab (which takes a vectorptr) instead? -Should there be a 'storeVectorDefaults(dataVector)' routine somewhere? if so, where? ------------------------------------------------------------------------ r736370 | netterfield | 2007-11-13 20:59:01 -0500 (Tue, 13 Nov 2007) | 6 lines -Add first glimps of dialog defaults. -The vector dialog was not filling all of its fields when editing a vector. -vectordefaults is going to go away. Remove the include. ------------------------------------------------------------------------ r736280 | fenton | 2007-11-13 15:30:36 -0500 (Tue, 13 Nov 2007) | 3 lines Add force reload of DataManager to reload data on open. Add context menu support to DataManager. ------------------------------------------------------------------------ r736105 | fenton | 2007-11-13 09:28:24 -0500 (Tue, 13 Nov 2007) | 3 lines Add ScalarListSelector to ScalarSelector. Update EquationDialog equation builder. ------------------------------------------------------------------------ r735855 | fenton | 2007-11-12 14:43:20 -0500 (Mon, 12 Nov 2007) | 2 lines Add editing of Scalars. ------------------------------------------------------------------------ r735834 | fenton | 2007-11-12 13:22:25 -0500 (Mon, 12 Nov 2007) | 2 lines Add Edit functionality for Matrices. Includes both GUI and modification of DataObject. ------------------------------------------------------------------------ r735779 | fenton | 2007-11-12 11:08:29 -0500 (Mon, 12 Nov 2007) | 2 lines Add Editing of Vectors. ------------------------------------------------------------------------ r735724 | netterfield | 2007-11-12 09:17:55 -0500 (Mon, 12 Nov 2007) | 3 lines Add a buglist, and a specification for sticky dialog defaults. ------------------------------------------------------------------------ r735720 | fenton | 2007-11-12 09:15:04 -0500 (Mon, 12 Nov 2007) | 2 lines Add Ok Button validation to dialogs. ------------------------------------------------------------------------ r734743 | fenton | 2007-11-09 14:25:00 -0500 (Fri, 09 Nov 2007) | 4 lines Add test for DataMatrix and fix for matrix creation. Update MatrixSelector and MatrixEditorDialog to populate correctly. Update MatrixDialog to only include Matrices from the DataSource. ------------------------------------------------------------------------ r734648 | fenton | 2007-11-09 08:29:53 -0500 (Fri, 09 Nov 2007) | 2 lines Add EventMonitorFactory. ------------------------------------------------------------------------ r734432 | fenton | 2007-11-08 16:16:04 -0500 (Thu, 08 Nov 2007) | 2 lines Fix for crash in DataWizard when plotting. ------------------------------------------------------------------------ r734388 | fenton | 2007-11-08 14:15:05 -0500 (Thu, 08 Nov 2007) | 3 lines Add Save/Restore for DataSources. Modify loading of DataSources and addition of DataSources to ObjectStore. ------------------------------------------------------------------------ r734292 | fenton | 2007-11-08 08:51:56 -0500 (Thu, 08 Nov 2007) | 2 lines Redo Vector creation in the Factory. ------------------------------------------------------------------------ r734024 | fenton | 2007-11-07 16:01:57 -0500 (Wed, 07 Nov 2007) | 3 lines Update Save/Restore for PlotRenderItems to save/restore relations. Update GraphicFactories to have access to the ObjectStore. ------------------------------------------------------------------------ r733965 | fenton | 2007-11-07 14:01:59 -0500 (Wed, 07 Nov 2007) | 5 lines Add Save/Restore for Image. Fix creation of Image. Update Palette usage in Image. Fix crash in ImageDialog. ------------------------------------------------------------------------ r733929 | fenton | 2007-11-07 11:00:47 -0500 (Wed, 07 Nov 2007) | 2 lines Add Save/Restore for Curve. ------------------------------------------------------------------------ r733927 | fenton | 2007-11-07 10:56:40 -0500 (Wed, 07 Nov 2007) | 2 lines Fix Apodize in TestCSD and TestPSD. ------------------------------------------------------------------------ r733896 | fenton | 2007-11-07 09:16:17 -0500 (Wed, 07 Nov 2007) | 5 lines Add Save/Restore for EventMonitorEntry. Move EventMonitorEntry and EmailThread to libkstmath. Fix crash in EventMonitorDialog. Add Save for BasicPlugin. ------------------------------------------------------------------------ r733707 | netterfield | 2007-11-07 00:19:18 -0500 (Wed, 07 Nov 2007) | 3 lines Add up and down zoom changes. ------------------------------------------------------------------------ r733630 | netterfield | 2007-11-06 17:09:16 -0500 (Tue, 06 Nov 2007) | 7 lines Add Left and Right to the zoom options (I forgot these in the spec). This easy to work with! cbn ------------------------------------------------------------------------ r733607 | fenton | 2007-11-06 15:55:38 -0500 (Tue, 06 Nov 2007) | 2 lines Add save/restore of PowerSpectrum. Fix crash & creation of PSD. Update CSD tag names. ------------------------------------------------------------------------ r733591 | fenton | 2007-11-06 14:56:11 -0500 (Tue, 06 Nov 2007) | 2 lines Add Save/Restore for Histogram and fix crash in HistogramDialog. ------------------------------------------------------------------------ r733563 | fenton | 2007-11-06 13:19:39 -0500 (Tue, 06 Nov 2007) | 3 lines Add Save/Restore for CSD. Fix crash and creation in CSDDialog. ------------------------------------------------------------------------ r733532 | fenton | 2007-11-06 10:40:58 -0500 (Tue, 06 Nov 2007) | 2 lines Update to save/restore for Equations. ------------------------------------------------------------------------ r733522 | fenton | 2007-11-06 10:04:10 -0500 (Tue, 06 Nov 2007) | 2 lines Update .kst file specification to include GeneratedMatrix, EditableMatrix and DataMatrix. ------------------------------------------------------------------------ r733520 | fenton | 2007-11-06 10:00:30 -0500 (Tue, 06 Nov 2007) | 2 lines Addition of Save/Restore for DataMatrix, EditableMatrix and GeneratedMatrix. ------------------------------------------------------------------------ r733200 | fidler | 2007-11-05 15:44:47 -0500 (Mon, 05 Nov 2007) | 2 lines move locking into DataMatrix::change() ------------------------------------------------------------------------ r733199 | fidler | 2007-11-05 15:44:30 -0500 (Mon, 05 Nov 2007) | 2 lines initialize the _store pointer in MatrixTab ------------------------------------------------------------------------ r733198 | fidler | 2007-11-05 15:42:14 -0500 (Mon, 05 Nov 2007) | 2 lines oops.. fix locking ------------------------------------------------------------------------ r733169 | fenton | 2007-11-05 13:45:50 -0500 (Mon, 05 Nov 2007) | 2 lines Update .kst Specification to include string tag. ------------------------------------------------------------------------ r733168 | fenton | 2007-11-05 13:41:14 -0500 (Mon, 05 Nov 2007) | 2 lines Adding Save/Restore for Strings. ------------------------------------------------------------------------ r733156 | fenton | 2007-11-05 12:23:47 -0500 (Mon, 05 Nov 2007) | 2 lines Removal of unneeded friend marker. ------------------------------------------------------------------------ r733145 | fenton | 2007-11-05 12:09:58 -0500 (Mon, 05 Nov 2007) | 2 lines Updating .kst specification to include Scalar. ------------------------------------------------------------------------ r733144 | fenton | 2007-11-05 12:08:06 -0500 (Mon, 05 Nov 2007) | 2 lines Add Save/Restore for Scalars. ------------------------------------------------------------------------ r733137 | fenton | 2007-11-05 11:46:36 -0500 (Mon, 05 Nov 2007) | 2 lines Update .kst specification file to include Vector, EditableVector, DataVector and GeneratedVector. ------------------------------------------------------------------------ r733135 | fenton | 2007-11-05 11:43:27 -0500 (Mon, 05 Nov 2007) | 2 lines Add Save/Restore functionality for EditableVector, DataVector, GeneratedVector and Vector. ------------------------------------------------------------------------ r732089 | fenton | 2007-11-02 15:06:09 -0400 (Fri, 02 Nov 2007) | 3 lines Addition of DataWizard. Includes all function GUI aspects as well as object creations as much as they are currently working. ------------------------------------------------------------------------ r731376 | fenton | 2007-10-31 11:00:05 -0400 (Wed, 31 Oct 2007) | 3 lines Enabled Edit Vector from VectorSelector and add population of values to VectorDialog based on existing Vector. ------------------------------------------------------------------------ r731128 | fidler | 2007-10-30 15:43:06 -0400 (Tue, 30 Oct 2007) | 2 lines merged objectstore branch ------------------------------------------------------------------------ r731094 | treat | 2007-10-30 13:14:34 -0400 (Tue, 30 Oct 2007) | 2 lines * Silence warnings ------------------------------------------------------------------------ r731041 | fenton | 2007-10-30 10:31:10 -0400 (Tue, 30 Oct 2007) | 2 lines Removing extra function declaration. ------------------------------------------------------------------------ r731036 | fenton | 2007-10-30 10:15:30 -0400 (Tue, 30 Oct 2007) | 2 lines Addition of StringEditorDialog and StringModel/StringTableModel. ------------------------------------------------------------------------ r730873 | staikos | 2007-10-29 18:32:03 -0400 (Mon, 29 Oct 2007) | 2 lines we don't need these anymore :) ------------------------------------------------------------------------ r730815 | fenton | 2007-10-29 14:34:36 -0400 (Mon, 29 Oct 2007) | 2 lines Add initial combo values and other loaded values. ------------------------------------------------------------------------ r730778 | fenton | 2007-10-29 11:35:31 -0400 (Mon, 29 Oct 2007) | 2 lines Add dialog control enable/disable to PlotRenderItemDialog. ------------------------------------------------------------------------ r730774 | staikos | 2007-10-29 11:19:48 -0400 (Mon, 29 Oct 2007) | 2 lines win32 fix ------------------------------------------------------------------------ r729755 | fenton | 2007-10-26 16:59:07 -0400 (Fri, 26 Oct 2007) | 2 lines Add initial stub version of PlotRenderItemDialog. ------------------------------------------------------------------------ r729621 | fenton | 2007-10-26 09:23:43 -0400 (Fri, 26 Oct 2007) | 2 lines Add initial stub version of ChangeFileDialog. ------------------------------------------------------------------------ r729346 | fenton | 2007-10-25 14:49:39 -0400 (Thu, 25 Oct 2007) | 3 lines Initial port of ChangeDataSampleDialog and update to load of ChooseColorDialog. ------------------------------------------------------------------------ r729296 | fenton | 2007-10-25 10:47:49 -0400 (Thu, 25 Oct 2007) | 2 lines Initial Stub version of ChooseColorDialog. ------------------------------------------------------------------------ r728997 | fenton | 2007-10-24 16:48:42 -0400 (Wed, 24 Oct 2007) | 3 lines Initial stub version of the DifferentiateCurvesDialog and the Tools menu. ------------------------------------------------------------------------ r728880 | fenton | 2007-10-24 11:00:45 -0400 (Wed, 24 Oct 2007) | 3 lines Add implementation of matrix selector. Also made signal updates to MatrixSelector. ------------------------------------------------------------------------ r728594 | fenton | 2007-10-23 15:32:27 -0400 (Tue, 23 Oct 2007) | 2 lines Add stub version of BasicPluginDialog. ------------------------------------------------------------------------ r728578 | fenton | 2007-10-23 14:23:15 -0400 (Tue, 23 Oct 2007) | 2 lines Fix for save build error in EventMonitorEntry. ------------------------------------------------------------------------ r728577 | fenton | 2007-10-23 14:20:11 -0400 (Tue, 23 Oct 2007) | 3 lines Add EventMonitorEntry creation from EventMonitorDialog and save of EventMonitorEntry. ------------------------------------------------------------------------ r728526 | fenton | 2007-10-23 11:38:16 -0400 (Tue, 23 Oct 2007) | 3 lines Initial Port of EmailThread to Kst::EmailThread and KstEventMonitorEntry to Kst::EventMonitorEntry. ------------------------------------------------------------------------ r728246 | fenton | 2007-10-22 16:09:47 -0400 (Mon, 22 Oct 2007) | 2 lines Initial Stub version of EventMonitorDialog. ------------------------------------------------------------------------ r728216 | fenton | 2007-10-22 14:33:36 -0400 (Mon, 22 Oct 2007) | 2 lines Add ScalarEditor dialog and ScalarTableModel/ScalarModel. ------------------------------------------------------------------------ r728125 | fenton | 2007-10-22 09:49:09 -0400 (Mon, 22 Oct 2007) | 2 lines Add creation of Images and addition of Kst Grayscale palette. ------------------------------------------------------------------------ r727131 | fenton | 2007-10-19 17:08:58 -0400 (Fri, 19 Oct 2007) | 2 lines Add stub version of ImageDialog and implement Matrix Selector. ------------------------------------------------------------------------ r727091 | fenton | 2007-10-19 14:59:49 -0400 (Fri, 19 Oct 2007) | 2 lines Add creation of CSD object and image creation. ------------------------------------------------------------------------ r727082 | fenton | 2007-10-19 13:36:39 -0400 (Fri, 19 Oct 2007) | 4 lines Initial stub checkin of CSDDialog. Creation of ColorPalette Widget for use in CSDDialog. Creation of Palette class for ColorPalette. ------------------------------------------------------------------------ r726750 | fenton | 2007-10-18 15:53:17 -0400 (Thu, 18 Oct 2007) | 3 lines Add accessor functions to FFTOptions and PSD creation from PowerSpectrumDialog. ------------------------------------------------------------------------ r726723 | fenton | 2007-10-18 14:24:01 -0400 (Thu, 18 Oct 2007) | 3 lines Port of FFTOptions widget and addition of PowerSpectrumDialog in stub form. ------------------------------------------------------------------------ r726694 | fenton | 2007-10-18 12:08:05 -0400 (Thu, 18 Oct 2007) | 2 lines Name and interface updates for Histogram and CurveAppearance. ------------------------------------------------------------------------ r726680 | fenton | 2007-10-18 11:02:25 -0400 (Thu, 18 Oct 2007) | 3 lines Add create for Histogram as well as initial state settings for CurveAppearance. ------------------------------------------------------------------------ r726491 | fidler | 2007-10-17 17:08:18 -0400 (Wed, 17 Oct 2007) | 2 lines from and to were switched ------------------------------------------------------------------------ r726485 | fenton | 2007-10-17 17:05:55 -0400 (Wed, 17 Oct 2007) | 2 lines Adding stub version of Histogram Dialog. ------------------------------------------------------------------------ r726405 | fenton | 2007-10-17 14:59:39 -0400 (Wed, 17 Oct 2007) | 3 lines Update MatrixDialog to create DataMatrix's and setup GUI options to interact the same as previous version. ------------------------------------------------------------------------ r726331 | fenton | 2007-10-17 10:31:50 -0400 (Wed, 17 Oct 2007) | 3 lines Add creation of generated matrix to MatrixDialog. Also added save of generated matrix. ------------------------------------------------------------------------ r726002 | fenton | 2007-10-16 16:44:25 -0400 (Tue, 16 Oct 2007) | 2 lines Initial stub version of matrix dialog. ------------------------------------------------------------------------ r725974 | fenton | 2007-10-16 15:07:55 -0400 (Tue, 16 Oct 2007) | 3 lines Update .kst specification to include cartesianrender as part of plot item. ------------------------------------------------------------------------ r725973 | fenton | 2007-10-16 15:04:24 -0400 (Tue, 16 Oct 2007) | 3 lines Add save/partial restore (without relations) of CartesianRenderItem and the baseclass PlotRenderItem. ------------------------------------------------------------------------ r725905 | fenton | 2007-10-16 10:17:58 -0400 (Tue, 16 Oct 2007) | 2 lines Update .kst file specification to include layoutbox and layoutitem tags. ------------------------------------------------------------------------ r725903 | fenton | 2007-10-16 10:15:04 -0400 (Tue, 16 Oct 2007) | 3 lines Add parsing of layoutbox and save/parsing of items associated with the layoutbox. ------------------------------------------------------------------------ r725625 | fenton | 2007-10-15 16:54:11 -0400 (Mon, 15 Oct 2007) | 3 lines Disable attempt to write PlotRenderItems when saving the main view. Basic save of LayoutBox. ------------------------------------------------------------------------ r725615 | fenton | 2007-10-15 16:26:11 -0400 (Mon, 15 Oct 2007) | 2 lines Update .kst specification to include details of plot and plotaxis. ------------------------------------------------------------------------ r725614 | fenton | 2007-10-15 16:24:02 -0400 (Mon, 15 Oct 2007) | 2 lines Initial implementation of save/restore for PlotItem and PlotAxisItem. ------------------------------------------------------------------------ r725515 | fenton | 2007-10-15 11:56:20 -0400 (Mon, 15 Oct 2007) | 2 lines Add zValue attribute for all ViewItems. ------------------------------------------------------------------------ r725514 | fenton | 2007-10-15 11:55:06 -0400 (Mon, 15 Oct 2007) | 2 lines Update to ViewItem save to include zvalue as attribute. ------------------------------------------------------------------------ r725511 | treat | 2007-10-15 11:39:26 -0400 (Mon, 15 Oct 2007) | 10 lines * Add plot axis and labels for major ticks. This design will need to be rethought as I think the PlotAxisItem class will need to be merged with the PlotItem class. However, I want to get this under version control as this contains a lot of sep moving parts. * ZOrder fixes for all viewitems. * Event and shortcut fixes. * Other bugfixes and stuff. ------------------------------------------------------------------------ r725508 | fenton | 2007-10-15 11:28:18 -0400 (Mon, 15 Oct 2007) | 2 lines Update to .kst file specification to include svg definition. ------------------------------------------------------------------------ r725504 | fenton | 2007-10-15 11:25:28 -0400 (Mon, 15 Oct 2007) | 2 lines Implementation of Save/Restore for SvgItem. ------------------------------------------------------------------------ r725472 | fenton | 2007-10-15 09:33:21 -0400 (Mon, 15 Oct 2007) | 2 lines Update .kst specification file for PictureItem to have a data node. ------------------------------------------------------------------------ r725471 | fenton | 2007-10-15 09:32:00 -0400 (Mon, 15 Oct 2007) | 3 lines Update of PictureItem save/restore to use a separate node of rather than an attribute. ------------------------------------------------------------------------ r725126 | staikos | 2007-10-14 12:59:46 -0400 (Sun, 14 Oct 2007) | 2 lines just minor updates to the TODO. we should add more detail again though. ------------------------------------------------------------------------ r724620 | fenton | 2007-10-12 16:48:08 -0400 (Fri, 12 Oct 2007) | 2 lines Update to .kst file specification to include picture definition. ------------------------------------------------------------------------ r724619 | fenton | 2007-10-12 16:47:29 -0400 (Fri, 12 Oct 2007) | 2 lines Implementation of Save/Restore for PictureItem ------------------------------------------------------------------------ r724591 | fenton | 2007-10-12 15:03:16 -0400 (Fri, 12 Oct 2007) | 2 lines Update to .kst file specification to include line definition. ------------------------------------------------------------------------ r724589 | fenton | 2007-10-12 15:02:24 -0400 (Fri, 12 Oct 2007) | 4 lines Implemention of save/restore for LineItems. Fixed error in restoring of QPen and QBrush in ViewItem. ------------------------------------------------------------------------ r724569 | fenton | 2007-10-12 13:51:59 -0400 (Fri, 12 Oct 2007) | 3 lines Update to .kst file specification to include ellipse and label definitions. ------------------------------------------------------------------------ r724568 | fenton | 2007-10-12 13:50:45 -0400 (Fri, 12 Oct 2007) | 2 lines Implementation of save/restore for LabelItem. ------------------------------------------------------------------------ r724553 | fenton | 2007-10-12 12:30:04 -0400 (Fri, 12 Oct 2007) | 2 lines Implementation of EllipseItem save/restore. ------------------------------------------------------------------------ r724540 | fenton | 2007-10-12 11:49:37 -0400 (Fri, 12 Oct 2007) | 2 lines Update to .kst specification to include box definition. ------------------------------------------------------------------------ r724539 | fenton | 2007-10-12 11:48:56 -0400 (Fri, 12 Oct 2007) | 3 lines Implemention of ViewItem based document save/restore from XML architecture including completed BoxItem handling. ------------------------------------------------------------------------ r724251 | treat | 2007-10-11 16:37:14 -0400 (Thu, 11 Oct 2007) | 2 lines * Rename this to go along with new design. ------------------------------------------------------------------------ r724246 | treat | 2007-10-11 16:29:36 -0400 (Thu, 11 Oct 2007) | 6 lines * Move the RenderType enum to the PlotRenderItem class. * PlotItem's can now have only one of each RenderType. * The PlotRenderItem's are created from the PlotItem::renderItem() factory. * bugfix for PlotItem::projectionRect() ------------------------------------------------------------------------ r724215 | treat | 2007-10-11 14:47:37 -0400 (Thu, 11 Oct 2007) | 2 lines * Properly initialize the Auto zoom mode. ------------------------------------------------------------------------ r724185 | treat | 2007-10-11 13:34:45 -0400 (Thu, 11 Oct 2007) | 5 lines * Except for a spike insensitive algorithm TBD and a GUI to enter fixed scalar expressions for zoom... all the different modes are complete I think. Testing welcome. ------------------------------------------------------------------------ r724167 | netterfield | 2007-10-11 12:43:48 -0400 (Thu, 11 Oct 2007) | 3 lines Add definition of the plot axis... ------------------------------------------------------------------------ r724161 | treat | 2007-10-11 12:33:16 -0400 (Thu, 11 Oct 2007) | 2 lines * Need to recompute here in case of auto/autoborder modes ------------------------------------------------------------------------ r723834 | treat | 2007-10-10 17:11:27 -0400 (Wed, 10 Oct 2007) | 5 lines * Add more zoom modes: YLocalMaximum XIn, XOut, YIn, YOut * Refactor how we compute the projection rects ------------------------------------------------------------------------ r723810 | treat | 2007-10-10 15:12:21 -0400 (Wed, 10 Oct 2007) | 2 lines * Need to find a scheme for auto suggesting scalar names ------------------------------------------------------------------------ r723808 | treat | 2007-10-10 15:04:59 -0400 (Wed, 10 Oct 2007) | 4 lines * Some whitespace cleanups. * Superfluous datasource methods. * Cleanup a bit. ------------------------------------------------------------------------ r723801 | treat | 2007-10-10 14:51:03 -0400 (Wed, 10 Oct 2007) | 5 lines * Guard the ZoomState.plotrenderitem with QPointer * ZoomMode::Expression -> FixedExpression * Redo some of the zoom command stuff following conversation with barth. ------------------------------------------------------------------------ r723787 | fenton | 2007-10-10 14:15:34 -0400 (Wed, 10 Oct 2007) | 2 lines Implementation of ScalarSelector, ScalarTab and ScalarDialog. ------------------------------------------------------------------------ r723749 | treat | 2007-10-10 11:50:23 -0400 (Wed, 10 Oct 2007) | 3 lines * Let the plots truly overlap so we don't get an extra bold line for the shared axis. ------------------------------------------------------------------------ r723745 | treat | 2007-10-10 11:45:41 -0400 (Wed, 10 Oct 2007) | 2 lines * Delay this so that the curves can update first. ------------------------------------------------------------------------ r723741 | treat | 2007-10-10 11:28:37 -0400 (Wed, 10 Oct 2007) | 3 lines * Proper casts * Give the default layout a little margin/spacing for grips. ------------------------------------------------------------------------ r723542 | treat | 2007-10-09 18:53:41 -0400 (Tue, 09 Oct 2007) | 5 lines * Make CurveAppearence getters const. * Implement and hook up the CurvePlacement. * Add an interface class for plotitem for this purpose. etc, etc... ------------------------------------------------------------------------ r723476 | fenton | 2007-10-09 15:44:24 -0400 (Tue, 09 Oct 2007) | 2 lines Updating combobox sizes. ------------------------------------------------------------------------ r723465 | fenton | 2007-10-09 14:56:06 -0400 (Tue, 09 Oct 2007) | 3 lines Implementation of CurveAppearance widget and connecting it to the Curve and Equation dialogs. ------------------------------------------------------------------------ r723426 | treat | 2007-10-09 12:39:27 -0400 (Tue, 09 Oct 2007) | 5 lines * Whitespace changes. * Class methods should never be pascal case. * Don't pass QString by value. * Simplify qcheckbox get/set. ------------------------------------------------------------------------ r723405 | treat | 2007-10-09 11:09:18 -0400 (Tue, 09 Oct 2007) | 2 lines * Tied zoom ------------------------------------------------------------------------ r722170 | staikos | 2007-10-06 15:47:14 -0400 (Sat, 06 Oct 2007) | 2 lines MSVC can't handle the bitfield of an enum. also pack bits appropriately. ------------------------------------------------------------------------ r722164 | staikos | 2007-10-06 15:28:03 -0400 (Sat, 06 Oct 2007) | 2 lines This test is invalid on win32 - or at least we need a better approach ------------------------------------------------------------------------ r722154 | treat | 2007-10-06 14:43:47 -0400 (Sat, 06 Oct 2007) | 8 lines * Automatically set the spacing based on whether any plotitem axis is being shared. * Unfortunately need to update each plotrenderitem each time the label visibility is changed. The algorithm to share axis is not the greatest or most efficient. One possibility is to not redraw the actual curve when in layout mode. ------------------------------------------------------------------------ r721734 | staikos | 2007-10-05 19:53:13 -0400 (Fri, 05 Oct 2007) | 2 lines compile ------------------------------------------------------------------------ r721683 | treat | 2007-10-05 17:16:51 -0400 (Fri, 05 Oct 2007) | 6 lines * Begin implementation of shared axis for plots in layout. * Don't reparent the plotrenderitems *ever* * Bugfix for ViewItem. * Provide suppression of labels. etc,... ------------------------------------------------------------------------ r721682 | fenton | 2007-10-05 17:15:43 -0400 (Fri, 05 Oct 2007) | 3 lines Update of spacing on Equation Dialog, population of Combobox entries and creation of Equation support. ------------------------------------------------------------------------ r721638 | treat | 2007-10-05 14:56:20 -0400 (Fri, 05 Oct 2007) | 7 lines * Add new top-level tied zoom action to toolbars/menus. * Provide get/set for plotrenderitem tied zoom. * Draw a checkbox for indicating tied zoom as well as hover. * Redesign how we register shorcuts with the view. * New selectedViewItem convenience function for View. * Don't show selection boxes in ViewMode::Data. ------------------------------------------------------------------------ r721627 | staikos | 2007-10-05 14:18:46 -0400 (Fri, 05 Oct 2007) | 2 lines fix build ------------------------------------------------------------------------ r721619 | fenton | 2007-10-05 13:44:59 -0400 (Fri, 05 Oct 2007) | 2 lines Conversion of KstSettings to Kst::Settings and other cleanup. ------------------------------------------------------------------------ r721598 | fenton | 2007-10-05 12:33:55 -0400 (Fri, 05 Oct 2007) | 4 lines Conversion of KstObjectDefaults to Kst::ObjectDefaults, KstPainter to Kst::Painter, KstPSD to Kst::PSD, KstRelation to Kst::Relation and Kst::VCurve to Kst::Curve and associated changes. ------------------------------------------------------------------------ r721572 | treat | 2007-10-05 10:51:21 -0400 (Fri, 05 Oct 2007) | 5 lines * Implement shift/ctrl modified selection zoom. * Painting and clipping fixes. * Don't hardcode pen width. * Set the foreground and background colors of the curve context. ------------------------------------------------------------------------ r721563 | fenton | 2007-10-05 10:13:28 -0400 (Fri, 05 Oct 2007) | 3 lines Conversion of KstVCurve to Kst::VCurve, KstLineStyle to Kst::LineStyle and KstImage to Kst::Image and associated changes. ------------------------------------------------------------------------ r721557 | fenton | 2007-10-05 09:46:05 -0400 (Fri, 05 Oct 2007) | 2 lines Conversion of KstHistogram to Kst::Histogram and associated changes. ------------------------------------------------------------------------ r721550 | treat | 2007-10-05 09:29:32 -0400 (Fri, 05 Oct 2007) | 4 lines * Add get/set for logbase and don't hardcode. * Fix hackup for log mode. * Investigate kst2dplot for solutions. ------------------------------------------------------------------------ r721548 | fenton | 2007-10-05 09:15:54 -0400 (Fri, 05 Oct 2007) | 4 lines Conversion of kstcurvehint to Kst::CurveHint, KstCurvePointSymbol to Kst::CurvePointSymbol and KstEquation to Kst::Equation and associated changes. ------------------------------------------------------------------------ r721309 | treat | 2007-10-04 19:13:15 -0400 (Thu, 04 Oct 2007) | 14 lines * Refactor the registerShortcut design a bit and make them app wide. * Bugfix in the SelectionRect class. * Add ZoomModes: Auto, AutoBorder, Expression, Spike Insensitive, MeanCentered * Add Axis dependent modes * Implement: 1) Zoom Maximum 2) Zoom XMaximum 3) Zoom YMaximum 4) Log X 5) Log Y * Document all the possible zoom mode operations and provide infrastructure to implement the rest. ------------------------------------------------------------------------ r721239 | fenton | 2007-10-04 16:42:57 -0400 (Thu, 04 Oct 2007) | 2 lines Conversion of KstCSD to Kst::CSD. ------------------------------------------------------------------------ r721222 | fenton | 2007-10-04 16:27:30 -0400 (Thu, 04 Oct 2007) | 2 lines Conversion of KstColorSequence to Kst::ColorSequence. ------------------------------------------------------------------------ r721206 | fenton | 2007-10-04 15:53:42 -0400 (Thu, 04 Oct 2007) | 2 lines Conversion of KstBasicPlugin to Kst::BasicPlugin. ------------------------------------------------------------------------ r721196 | fenton | 2007-10-04 15:35:36 -0400 (Thu, 04 Oct 2007) | 3 lines Conversion of KstIndex, KstExtension, KstEvents and KstMath to new namespace conventions. ------------------------------------------------------------------------ r721173 | fenton | 2007-10-04 14:55:48 -0400 (Thu, 04 Oct 2007) | 2 lines Conversion of KstTimezones to Kst::Timezones. ------------------------------------------------------------------------ r721166 | fenton | 2007-10-04 14:38:39 -0400 (Thu, 04 Oct 2007) | 3 lines Conversion of KstString to Kst::String, KstPrimitive to Kst::Primitive and KstSharedPtr to Kst::SharedPtr and associated changes. ------------------------------------------------------------------------ r721142 | treat | 2007-10-04 13:45:57 -0400 (Thu, 04 Oct 2007) | 6 lines * Add a title to the item's context menu. * Change the names of the items to suit. * Add zoom actions for the plotrenderitem. * Implement triggering mechanism for items to have shortcuts. ------------------------------------------------------------------------ r721127 | fenton | 2007-10-04 12:50:27 -0400 (Thu, 04 Oct 2007) | 2 lines Conversion of KstVectorDefaults to Kst::VectorDefaults. ------------------------------------------------------------------------ r721124 | fenton | 2007-10-04 12:35:26 -0400 (Thu, 04 Oct 2007) | 3 lines Conversion of KstObjectList to Kst::ObjectList and KstObjectMap to Kst::ObjectMap and associated changes. ------------------------------------------------------------------------ r721108 | fenton | 2007-10-04 12:06:22 -0400 (Thu, 04 Oct 2007) | 4 lines Conversion of KstMatrix to Kst::Matrix, KstDataObjectCollection to Kst::DataObjectCollection, KstObjectCollection to Kst::ObjectCollection and KstMatrixDefaults to Kst::MatrixDefaults and all associated changes. ------------------------------------------------------------------------ r721086 | fenton | 2007-10-04 10:32:17 -0400 (Thu, 04 Oct 2007) | 2 lines Conversion of KstDebug to Kst::Debug and associated changes. ------------------------------------------------------------------------ r721076 | fenton | 2007-10-04 09:58:38 -0400 (Thu, 04 Oct 2007) | 3 lines Conversion of KstObject to Kst::Object and KstObjectTag to Kst::ObjectTag and all associated changes. ------------------------------------------------------------------------ r720975 | staikos | 2007-10-04 03:07:26 -0400 (Thu, 04 Oct 2007) | 2 lines I think black is more appropriate for the default color ------------------------------------------------------------------------ r720973 | staikos | 2007-10-04 03:04:34 -0400 (Thu, 04 Oct 2007) | 2 lines repair the layout - use a grid ------------------------------------------------------------------------ r720968 | staikos | 2007-10-04 03:01:19 -0400 (Thu, 04 Oct 2007) | 2 lines launch the equation dialog ------------------------------------------------------------------------ r720963 | staikos | 2007-10-04 02:49:41 -0400 (Thu, 04 Oct 2007) | 3 lines make a class to handle (from,to) selection rects with built-in normalization and tracking of the proper start and end points ------------------------------------------------------------------------ r720872 | treat | 2007-10-03 18:40:28 -0400 (Wed, 03 Oct 2007) | 9 lines * And we have mouse based generic zoom :) * Provide proper coordinate transformation from the projection to the plotitem's coordinates. * Update the mainwindow statusbar whenever we hover the projection to report the current mouse projection coordinates. * Draw a crossCursor when we are in data mode and hovering over a projection. ------------------------------------------------------------------------ r720833 | treat | 2007-10-03 16:28:20 -0400 (Wed, 03 Oct 2007) | 2 lines * Don't clip too much. ------------------------------------------------------------------------ r720832 | treat | 2007-10-03 16:27:18 -0400 (Wed, 03 Oct 2007) | 18 lines * PlotRenderItem's are now real ViewItem's which means they now can reparent along with everything else. * Modify the paint routines of PlotRenderItem to take this into account. * Don't allow PlotRenderItem's to end up in a layout. * Item's that have a layout no longer completely handle the children's events. This allows data mode to work for PlotRenderItem's even when the plot itself is in a layout. * Clip the selectionRect of the PlotRenderItem. * The View now default's to Data mode. * Rects are always normalized. We no longer can have items with negative width/height which leads to artifacts and bad things. ------------------------------------------------------------------------ r720817 | fenton | 2007-10-03 15:59:21 -0400 (Wed, 03 Oct 2007) | 2 lines Conversion of kstdataplugin to Kst::DataPlugin and associated changes. ------------------------------------------------------------------------ r720813 | fenton | 2007-10-03 15:39:51 -0400 (Wed, 03 Oct 2007) | 2 lines Conversion of KstDataSource to Kst::DataSource and associated changes. ------------------------------------------------------------------------ r720757 | fenton | 2007-10-03 12:42:09 -0400 (Wed, 03 Oct 2007) | 3 lines Conversion of KstDataCollection to Kst::DataCollection and associated changes. ------------------------------------------------------------------------ r720698 | fenton | 2007-10-03 10:04:43 -0400 (Wed, 03 Oct 2007) | 3 lines Conversion of KstVector to Kst::Vector and KstDataObject to Kst::DataObject and all associated changes. ------------------------------------------------------------------------ r720311 | treat | 2007-10-02 19:16:41 -0400 (Tue, 02 Oct 2007) | 2 lines * Don't allow an empty selection for x and y vectors. ------------------------------------------------------------------------ r720290 | treat | 2007-10-02 18:28:30 -0400 (Tue, 02 Oct 2007) | 4 lines * Debug and fixup the curve drawing. I *think* we are comparable to the performance in 1.4.x now. Doubtless more bugs, but still... ------------------------------------------------------------------------ r720256 | netterfield | 2007-10-02 16:05:20 -0400 (Tue, 02 Oct 2007) | 2 lines Add zoom modes ------------------------------------------------------------------------ r720222 | fenton | 2007-10-02 14:31:28 -0400 (Tue, 02 Oct 2007) | 2 lines Conversion of kstdateparser to DateParser. ------------------------------------------------------------------------ r720220 | fenton | 2007-10-02 14:20:18 -0400 (Tue, 02 Oct 2007) | 2 lines Conversion from KstScalar to Scalar and associated changes. ------------------------------------------------------------------------ r720216 | treat | 2007-10-02 14:06:33 -0400 (Tue, 02 Oct 2007) | 18 lines * Clean up the layout of some of these dialogs * Look at the curve rendering time... needs to be greatly improved. It looks like the problem is in KstVCurve though...* Clean up the layout of some of these dialogs * Look at the curve rendering time... needs to be greatly improved. It looks like the problem is in KstVCurve though...* Clean up the layout of some of these dialogs * Look at the curve rendering time... needs to be greatly improved. It looks like the problem is in KstVCurve though...* Clean up the layout of some of these dialogs * Look at the curve rendering time... needs to be greatly improved. It looks like the problem is in KstVCurve though...* Clean up the layout of some of these dialogs * Look at the curve rendering time... needs to be greatly improved. It looks like the problem is in KstVCurve though...* Clean up the layout of some of these dialogs * Look at the curve rendering time... needs to be greatly improved. It looks like the problem is in KstVCurve though...* Clean up the layout of some of these dialogs * Look at the curve rendering time... needs to be greatly improved. It looks like the problem is in KstVCurve though...* Clean up the layout of some of these dialogs * Look at the curve rendering time... needs to be greatly improved. It looks like the problem is in KstVCurve though... ------------------------------------------------------------------------ r720205 | treat | 2007-10-02 13:29:00 -0400 (Tue, 02 Oct 2007) | 3 lines * Fix typo in databutton * Fix typo in plotitem that was affecting topLabel ------------------------------------------------------------------------ r720190 | treat | 2007-10-02 13:00:24 -0400 (Tue, 02 Oct 2007) | 3 lines * Mixed up apparently. The usability design of this widget leaves much to be desired. ------------------------------------------------------------------------ r720176 | treat | 2007-10-02 12:12:59 -0400 (Tue, 02 Oct 2007) | 3 lines * Use the new Qt4 CSS stylesheet feature to reproduce the look we had in 1.4.x. ------------------------------------------------------------------------ r720157 | fenton | 2007-10-02 11:25:21 -0400 (Tue, 02 Oct 2007) | 2 lines Conversion of KstSVector to Kst::GeneratedVector and associated changes. ------------------------------------------------------------------------ r720153 | fenton | 2007-10-02 11:05:39 -0400 (Tue, 02 Oct 2007) | 2 lines Conversion of KstSMatrix to Kst::GeneratedMatrix. ------------------------------------------------------------------------ r720150 | fenton | 2007-10-02 10:55:18 -0400 (Tue, 02 Oct 2007) | 2 lines Conversion of kstrvector to Kst::DataVector and associated changes. ------------------------------------------------------------------------ r720143 | fenton | 2007-10-02 10:32:48 -0400 (Tue, 02 Oct 2007) | 2 lines Conversion of kstrmatrix to Kst::DataMatrix. ------------------------------------------------------------------------ r719783 | treat | 2007-10-01 17:48:19 -0400 (Mon, 01 Oct 2007) | 2 lines * Add the command to the undo stack. ------------------------------------------------------------------------ r719780 | treat | 2007-10-01 17:41:10 -0400 (Mon, 01 Oct 2007) | 4 lines * A little better default placement. * Use command pattern. * Begin fleshing out the curveplacement widget. ------------------------------------------------------------------------ r719757 | staikos | 2007-10-01 16:38:12 -0400 (Mon, 01 Oct 2007) | 2 lines make sure the lifetime doesn't expire on the internal pointer ------------------------------------------------------------------------ r719756 | treat | 2007-10-01 16:37:18 -0400 (Mon, 01 Oct 2007) | 2 lines * Build. ------------------------------------------------------------------------ r719746 | staikos | 2007-10-01 16:20:29 -0400 (Mon, 01 Oct 2007) | 2 lines minor cleanup ------------------------------------------------------------------------ r719743 | treat | 2007-10-01 16:12:53 -0400 (Mon, 01 Oct 2007) | 5 lines * We can now create curves entirely from the GUI as well as plot the curves. * I've tested with gyrodata.dat and it works. We have real plots now :) ------------------------------------------------------------------------ r719742 | fenton | 2007-10-01 16:12:38 -0400 (Mon, 01 Oct 2007) | 2 lines Rename of KstAVector to Kst::EditableVector ------------------------------------------------------------------------ r719713 | staikos | 2007-10-01 15:08:48 -0400 (Mon, 01 Oct 2007) | 2 lines don't support this on win32 right now ------------------------------------------------------------------------ r719712 | staikos | 2007-10-01 15:07:05 -0400 (Mon, 01 Oct 2007) | 2 lines Make these compile and restore unix line endings ------------------------------------------------------------------------ r719711 | staikos | 2007-10-01 15:01:36 -0400 (Mon, 01 Oct 2007) | 2 lines and now kst.exe builds ------------------------------------------------------------------------ r719710 | fenton | 2007-10-01 14:56:21 -0400 (Mon, 01 Oct 2007) | 2 lines Updating header information to properly include UBC. ------------------------------------------------------------------------ r719707 | staikos | 2007-10-01 14:48:06 -0400 (Mon, 01 Oct 2007) | 2 lines add missing libs required on Win32 ------------------------------------------------------------------------ r719703 | fenton | 2007-10-01 14:33:04 -0400 (Mon, 01 Oct 2007) | 2 lines Rename of KstAVector to Kst::EditableVector ------------------------------------------------------------------------ r719699 | fenton | 2007-10-01 14:19:20 -0400 (Mon, 01 Oct 2007) | 2 lines Updating header. ------------------------------------------------------------------------ r719698 | fenton | 2007-10-01 14:11:05 -0400 (Mon, 01 Oct 2007) | 2 lines Rename of kstamatrix to Kst::EditableMatrix and the associated changes. ------------------------------------------------------------------------ r719683 | treat | 2007-10-01 13:17:55 -0400 (Mon, 01 Oct 2007) | 3 lines * Flesh out the vectorselector. It basically works now. * Provide metatype information for a host of KstObject's. ------------------------------------------------------------------------ r719665 | fenton | 2007-10-01 12:04:20 -0400 (Mon, 01 Oct 2007) | 2 lines Removal of void parameter and code simplification. ------------------------------------------------------------------------ r719662 | fenton | 2007-10-01 11:55:46 -0400 (Mon, 01 Oct 2007) | 2 lines Adding popup auto completion to kst combobox. ------------------------------------------------------------------------ r719660 | treat | 2007-10-01 11:50:48 -0400 (Mon, 01 Oct 2007) | 9 lines * Reintroduce the dialoglauncher. * Note only the dialoglauncher is a singleton, not the various dialogs it calls. * Modify DataManager to use this new class. * Modify DataDialogs to use only one constructor to simplify the API. * Hookup the VectorSelector widget to use this. ------------------------------------------------------------------------ r718479 | staikos | 2007-09-28 16:02:20 -0400 (Fri, 28 Sep 2007) | 3 lines one more for now. All that remains is to make kst.exe link ------------------------------------------------------------------------ r718476 | staikos | 2007-09-28 15:53:07 -0400 (Fri, 28 Sep 2007) | 2 lines keep the default scope straight ------------------------------------------------------------------------ r718475 | staikos | 2007-09-28 15:49:36 -0400 (Fri, 28 Sep 2007) | 2 lines don't build dirfile on win32 until getdata is ported ------------------------------------------------------------------------ r718474 | staikos | 2007-09-28 15:47:40 -0400 (Fri, 28 Sep 2007) | 3 lines on win32, use static libs for now. build system needs work, but now we compile as far as dirfile, which is not really win32 compatible. ------------------------------------------------------------------------ r718473 | staikos | 2007-09-28 15:46:36 -0400 (Fri, 28 Sep 2007) | 2 lines add missing include ------------------------------------------------------------------------ r718472 | fenton | 2007-09-28 15:44:33 -0400 (Fri, 28 Sep 2007) | 2 lines Addition of stub version of equationdialog. ------------------------------------------------------------------------ r718468 | staikos | 2007-09-28 15:31:06 -0400 (Fri, 28 Sep 2007) | 2 lines libkstmath now builds and almost links ------------------------------------------------------------------------ r718461 | staikos | 2007-09-28 15:16:21 -0400 (Fri, 28 Sep 2007) | 2 lines libkst.dll builds now ------------------------------------------------------------------------ r718454 | staikos | 2007-09-28 15:05:57 -0400 (Fri, 28 Sep 2007) | 2 lines This file doesn't work on win32 ------------------------------------------------------------------------ r718429 | treat | 2007-09-28 13:04:22 -0400 (Fri, 28 Sep 2007) | 2 lines * This is an executable. ------------------------------------------------------------------------ r718428 | treat | 2007-09-28 13:03:24 -0400 (Fri, 28 Sep 2007) | 5 lines * Make sure rpath is correct for all resources. * Enable the vector selector. * Make libkstwidgets link correctly. * Fix resource issues and cleanup the rest of the .pro files. ------------------------------------------------------------------------ r718395 | treat | 2007-09-28 11:44:15 -0400 (Fri, 28 Sep 2007) | 5 lines * Add new curve dialog. * Cleanup the databutton(action) class. * Don't show the canonical dataobjects that don't exist yet. ------------------------------------------------------------------------ r718383 | staikos | 2007-09-28 11:28:17 -0400 (Fri, 28 Sep 2007) | 2 lines no app bundle on OS X ------------------------------------------------------------------------ r718377 | staikos | 2007-09-28 11:18:18 -0400 (Fri, 28 Sep 2007) | 2 lines add a windows build script that needs lots of work ------------------------------------------------------------------------ r718376 | staikos | 2007-09-28 11:17:56 -0400 (Fri, 28 Sep 2007) | 2 lines add missing include ------------------------------------------------------------------------ r718028 | treat | 2007-09-27 19:13:33 -0400 (Thu, 27 Sep 2007) | 2 lines * Don't show the extension by default. ------------------------------------------------------------------------ r718026 | treat | 2007-09-27 19:08:15 -0400 (Thu, 27 Sep 2007) | 5 lines * Disable vector selector for now as it was giving designer fits. * Rename kstwidgets and the curve*widgets. * Add new curvetab which will be integral to the new curvedialog. ------------------------------------------------------------------------ r717986 | fenton | 2007-09-27 17:00:17 -0400 (Thu, 27 Sep 2007) | 2 lines Adding plugin extensions for curveplacement and curveappearance. ------------------------------------------------------------------------ r717983 | treat | 2007-09-27 16:49:45 -0400 (Thu, 27 Sep 2007) | 2 lines * Style, namespace fixes ------------------------------------------------------------------------ r717982 | treat | 2007-09-27 16:44:40 -0400 (Thu, 27 Sep 2007) | 2 lines * These are not executables. ------------------------------------------------------------------------ r717981 | treat | 2007-09-27 16:43:13 -0400 (Thu, 27 Sep 2007) | 2 lines * Silence ------------------------------------------------------------------------ r717977 | fenton | 2007-09-27 16:34:41 -0400 (Thu, 27 Sep 2007) | 2 lines Port of curveappearance and curveplacement widgets. ------------------------------------------------------------------------ r717966 | treat | 2007-09-27 16:01:41 -0400 (Thu, 27 Sep 2007) | 5 lines * Add stubbed version of all the primitive selectors. * Fix file requester alignment, size and layout. * Bugfix in kstwidgets with inheritance problem. ------------------------------------------------------------------------ r717929 | treat | 2007-09-27 14:45:46 -0400 (Thu, 27 Sep 2007) | 2 lines * These don't need to be public ------------------------------------------------------------------------ r717919 | fenton | 2007-09-27 14:25:25 -0400 (Thu, 27 Sep 2007) | 2 lines Port of dirfile and inclusion in build. ------------------------------------------------------------------------ r717834 | treat | 2007-09-27 13:00:21 -0400 (Thu, 27 Sep 2007) | 4 lines * Move editmultiplewidget to libkstapp. From now on the only things that go in 'widgets' directory are designer plugins. ------------------------------------------------------------------------ r717832 | treat | 2007-09-27 12:57:22 -0400 (Thu, 27 Sep 2007) | 2 lines * Properly namespace and cleanup style. ------------------------------------------------------------------------ r717828 | treat | 2007-09-27 12:53:03 -0400 (Thu, 27 Sep 2007) | 2 lines * These should not be executable ------------------------------------------------------------------------ r717822 | treat | 2007-09-27 12:35:42 -0400 (Thu, 27 Sep 2007) | 3 lines * Don't issue warnings when we don't even have relevant tests for these datasources. ------------------------------------------------------------------------ r717802 | treat | 2007-09-27 12:15:59 -0400 (Thu, 27 Sep 2007) | 3 lines * Make ascii config look better and give a good name to the dialog. ------------------------------------------------------------------------ r717793 | treat | 2007-09-27 11:49:44 -0400 (Thu, 27 Sep 2007) | 3 lines * Set the settings object. This solves the crash that nicholas was experiencing. ------------------------------------------------------------------------ r717780 | fenton | 2007-09-27 11:00:15 -0400 (Thu, 27 Sep 2007) | 2 lines Adding final test. ------------------------------------------------------------------------ r717754 | fenton | 2007-09-27 09:47:31 -0400 (Thu, 27 Sep 2007) | 2 lines Port of existing tests to new format. ------------------------------------------------------------------------ r717421 | treat | 2007-09-26 17:28:31 -0400 (Wed, 26 Sep 2007) | 2 lines * Fixed. We can now read in ascii datavectors from disk. ------------------------------------------------------------------------ r717409 | treat | 2007-09-26 16:54:39 -0400 (Wed, 26 Sep 2007) | 10 lines We can now load vectors from disk through the ascii datasource. * Add new Kst::DataTab and Kst::DataSourceDialog classes * Provide mechanism to call between datatab and datadialog * Big changes to VectorDialog to create DataVectors There is still something wrong with the data vectors. Investigating... ------------------------------------------------------------------------ r717348 | treat | 2007-09-26 14:03:30 -0400 (Wed, 26 Sep 2007) | 3 lines * Get rid of annoying message and just use QVERIFY for testing eq INF. ------------------------------------------------------------------------ r717344 | treat | 2007-09-26 13:37:29 -0400 (Wed, 26 Sep 2007) | 4 lines * Rearrange some stuff in kstdatasource * Add new tests for config widget and filetype to testdatasource * Refactor vectordialog to cleanup taking into account above ------------------------------------------------------------------------ r717335 | treat | 2007-09-26 12:51:41 -0400 (Wed, 26 Sep 2007) | 2 lines * Add testpsd from Mike Fenton. ------------------------------------------------------------------------ r717316 | treat | 2007-09-26 11:58:48 -0400 (Wed, 26 Sep 2007) | 2 lines * Oopsies ------------------------------------------------------------------------ r717307 | fenton | 2007-09-26 11:39:20 -0400 (Wed, 26 Sep 2007) | 2 lines Fixing logic error. ------------------------------------------------------------------------ r717302 | fenton | 2007-09-26 11:33:47 -0400 (Wed, 26 Sep 2007) | 2 lines Reducing code complexity on hide/show of widget extension. ------------------------------------------------------------------------ r717299 | fenton | 2007-09-26 11:26:03 -0400 (Wed, 26 Sep 2007) | 4 lines Transition of editmultiplewidget into the new UI and extension of dialog.ui to include an extension widget for adding additional ui components to the right of the existing dialog. ------------------------------------------------------------------------ r717294 | treat | 2007-09-26 11:08:18 -0400 (Wed, 26 Sep 2007) | 4 lines * The datasource plugin loads and I can retrieve the config widget. Next up is to actually hook-up config widget and create a vector read in from disk. ------------------------------------------------------------------------ r717283 | treat | 2007-09-26 10:37:07 -0400 (Wed, 26 Sep 2007) | 2 lines * Style ------------------------------------------------------------------------ r717281 | treat | 2007-09-26 10:33:27 -0400 (Wed, 26 Sep 2007) | 2 lines * Add a howto and handy documentation ------------------------------------------------------------------------ r717111 | treat | 2007-09-25 23:56:05 -0400 (Tue, 25 Sep 2007) | 2 lines * Move these to be consistent. ------------------------------------------------------------------------ r717109 | treat | 2007-09-25 23:52:43 -0400 (Tue, 25 Sep 2007) | 2 lines * Port tests over ------------------------------------------------------------------------ r717071 | treat | 2007-09-25 20:56:04 -0400 (Tue, 25 Sep 2007) | 2 lines * And voila, test suite now works and datasource passes :) ------------------------------------------------------------------------ r717061 | treat | 2007-09-25 20:12:40 -0400 (Tue, 25 Sep 2007) | 4 lines * Beginning of new test suite. It compiles and links, but getting weird linking error when *running*. ------------------------------------------------------------------------ r717056 | treat | 2007-09-25 19:20:46 -0400 (Tue, 25 Sep 2007) | 2 lines * Start of new testlib ------------------------------------------------------------------------ r717036 | treat | 2007-09-25 17:36:38 -0400 (Tue, 25 Sep 2007) | 2 lines * Move out of the way ------------------------------------------------------------------------ r716950 | treat | 2007-09-25 13:49:09 -0400 (Tue, 25 Sep 2007) | 3 lines * Try and hook up reading from the datasource in vectordialog. ------------------------------------------------------------------------ r716940 | fenton | 2007-09-25 13:05:10 -0400 (Tue, 25 Sep 2007) | 3 lines Disabling all currently unused menu items until they have been implemented. ------------------------------------------------------------------------ r716937 | fenton | 2007-09-25 12:56:41 -0400 (Tue, 25 Sep 2007) | 2 lines Updated buttons for the datamanger with the text left aligned. ------------------------------------------------------------------------ r716935 | treat | 2007-09-25 12:53:53 -0400 (Tue, 25 Sep 2007) | 3 lines * Bugfix for Kst::fileRequester. This hacks around a bug in Qt. Grrr... ------------------------------------------------------------------------ r716917 | treat | 2007-09-25 11:43:19 -0400 (Tue, 25 Sep 2007) | 3 lines * Reimplement Kst::DataRange so we can begin reading vectors in from disk. ------------------------------------------------------------------------ r716545 | treat | 2007-09-24 17:33:41 -0400 (Mon, 24 Sep 2007) | 2 lines * We now can create new slave vectors via the gui. ------------------------------------------------------------------------ r716516 | treat | 2007-09-24 16:23:28 -0400 (Mon, 24 Sep 2007) | 5 lines * Flesh out Kst::DataDialog and provide more hooks in Kst::Dialog to customize in subclasses. * Kst::DataDialog is now an abstract class. Real data dialogs can subclass this and implement the interface. ------------------------------------------------------------------------ r716480 | treat | 2007-09-24 15:09:57 -0400 (Mon, 24 Sep 2007) | 3 lines * Revamp the dialog class to provide custom areas. * Get ready to move edit multiple skeleton over. ------------------------------------------------------------------------ r716385 | treat | 2007-09-24 12:18:49 -0400 (Mon, 24 Sep 2007) | 2 lines * Rename and cleanup this file a bit. ------------------------------------------------------------------------ r716379 | treat | 2007-09-24 12:05:09 -0400 (Mon, 24 Sep 2007) | 4 lines * Make vector dialog look better and use the new Kst::Dialog class. * Don't set margin in new FileRequester. ------------------------------------------------------------------------ r716360 | treat | 2007-09-24 11:29:59 -0400 (Mon, 24 Sep 2007) | 3 lines * Implement bits of datamanager and cleanup some other files. ------------------------------------------------------------------------ r715309 | treat | 2007-09-21 15:57:59 -0400 (Fri, 21 Sep 2007) | 8 lines * Add a bunch of new widgets so that we can port over the vector dialog for creating new vectors. * ComboxBox ... this is a placeholder for what will eventually be a completion enabled combo. * DataRange ... this is a port of the KstDataRange class * FileRequester ... we no longer have KUrlRequester so this is a replacement. ------------------------------------------------------------------------ r715285 | treat | 2007-09-21 14:19:28 -0400 (Fri, 21 Sep 2007) | 4 lines * Do not use dynamic_cast any longer for viewitems. * From now on, items that subclass viewitem must not reimplement the QGraphicsItem::type() method. ------------------------------------------------------------------------ r715264 | treat | 2007-09-21 12:31:31 -0400 (Fri, 21 Sep 2007) | 2 lines * These don't work yet, so disable. ------------------------------------------------------------------------ r715263 | treat | 2007-09-21 12:29:57 -0400 (Fri, 21 Sep 2007) | 5 lines * Enable caching for our gradient background. * Hook up the new application settings dialog. * Can now turn on/off opengl as well as set the parameters of the grid. ------------------------------------------------------------------------ r714953 | treat | 2007-09-20 22:44:31 -0400 (Thu, 20 Sep 2007) | 3 lines * Dialog/Page bug fixes. * Beginning of application settings. ------------------------------------------------------------------------ r714951 | treat | 2007-09-20 21:29:57 -0400 (Thu, 20 Sep 2007) | 2 lines * Forgot to check these in apparently. ------------------------------------------------------------------------ r714905 | treat | 2007-09-20 17:18:21 -0400 (Thu, 20 Sep 2007) | 2 lines * Switch between layout modes in different tabs. ------------------------------------------------------------------------ r714874 | treat | 2007-09-20 15:40:04 -0400 (Thu, 20 Sep 2007) | 3 lines * Refactor layout commands once again. Now they should maintain state and be completely reversible. ------------------------------------------------------------------------ r714804 | treat | 2007-09-20 12:57:27 -0400 (Thu, 20 Sep 2007) | 6 lines * Style fixes. * Make layout commands reset geometries when undo. * Break out the top-level layout box. * Custom context menu for top-level layout box. * Don't move, resize, rotate, etc for top-level layout box. ------------------------------------------------------------------------ r714552 | treat | 2007-09-19 17:39:50 -0400 (Wed, 19 Sep 2007) | 4 lines * Provide bit flags to set/unset the various grip modes. Labelitems can no longer resize for instance. ------------------------------------------------------------------------ r714515 | treat | 2007-09-19 15:04:05 -0400 (Wed, 19 Sep 2007) | 3 lines * Provide default pens and brushes that correspond to what we had in kst1.x. ------------------------------------------------------------------------ r714512 | treat | 2007-09-19 14:46:49 -0400 (Wed, 19 Sep 2007) | 3 lines * Draw grips on top of object and makes sure they work for the part of grip inside the items shape. ------------------------------------------------------------------------ r714486 | treat | 2007-09-19 13:41:19 -0400 (Wed, 19 Sep 2007) | 4 lines * Reduce the gripBoundingRect so that the centers of the grips are the same as the vertice they are operating on. ------------------------------------------------------------------------ r714475 | treat | 2007-09-19 12:49:48 -0400 (Wed, 19 Sep 2007) | 2 lines * Resize child rotated items by minimizing. ------------------------------------------------------------------------ r714233 | treat | 2007-09-18 19:44:05 -0400 (Tue, 18 Sep 2007) | 3 lines * Works much better for arbitrary number of nested items. Could probably be simplified a good bit. ------------------------------------------------------------------------ r714134 | treat | 2007-09-18 15:56:34 -0400 (Tue, 18 Sep 2007) | 2 lines * Resize child geometries when resizing a parent. ------------------------------------------------------------------------ r712612 | treat | 2007-09-14 18:11:57 -0400 (Fri, 14 Sep 2007) | 3 lines * Propagate the transform when reparenting. ...This took a good bit of debug work. ------------------------------------------------------------------------ r712511 | treat | 2007-09-14 12:05:23 -0400 (Fri, 14 Sep 2007) | 2 lines * Only layout direct child items, not grandchildren. ------------------------------------------------------------------------ r712508 | treat | 2007-09-14 11:56:10 -0400 (Fri, 14 Sep 2007) | 2 lines * Try to reparent at the end of the creation mode. ------------------------------------------------------------------------ r712231 | treat | 2007-09-13 20:45:46 -0400 (Thu, 13 Sep 2007) | 2 lines * Enforce the rules according to layout spec page 2. ------------------------------------------------------------------------ r712223 | treat | 2007-09-13 19:08:09 -0400 (Thu, 13 Sep 2007) | 2 lines * Rename to make the code clear. ------------------------------------------------------------------------ r712204 | treat | 2007-09-13 18:04:18 -0400 (Thu, 13 Sep 2007) | 11 lines * Move debug defines. * Fix crash on exit. * Bugfixes for reparenting when an item is in a layout already in correct parent. Simplify... * Better reparenting debug. * Fix crash when attempting to create a layout with no items. * Add functions to the layout class for controlling plotitem's margins as per spec. * Make the plotitem and plotrenderitem respect the layout's margins as per spec. ------------------------------------------------------------------------ r712130 | treat | 2007-09-13 13:57:15 -0400 (Thu, 13 Sep 2007) | 5 lines * Add gridlayouthelper classes adapted from qt designer. * Hook up the gridlayouthelper so that our items are now automatically placed in a grid characterized by their relative positions and geometries. ------------------------------------------------------------------------ r712066 | treat | 2007-09-13 09:37:00 -0400 (Thu, 13 Sep 2007) | 14 lines * SELECT_BOUND is disabled. Now default to selection rect and grip orientation as defined in the layout spec. * Turn off scale mousemode altogether. Now controlled through a define. * Redesign lineitem completely. Still not done, but it works much more like it is supposed to. * Rotation improvements and bugfixes. * Don't display selection rect when creating the item. * Provide a 'centerOfRotation' method that controls the origin about which the item rotates. * Simplify the debug rotation mode. * Style fixups. ------------------------------------------------------------------------ r711824 | treat | 2007-09-12 17:50:29 -0400 (Wed, 12 Sep 2007) | 5 lines * Use floating point in viewitem * Start implementing customizations for handling lineitem * Don't resize item handles when window resizes * Show selection rect when the item is under mouse ------------------------------------------------------------------------ r709605 | treat | 2007-09-07 18:20:51 -0400 (Fri, 07 Sep 2007) | 2 lines * A little nicer ------------------------------------------------------------------------ r709565 | treat | 2007-09-07 16:21:37 -0400 (Fri, 07 Sep 2007) | 4 lines * Add layout options to dialog. Can now specify the spacing and margin. * Reformat a few classes to fit style. ------------------------------------------------------------------------ r709544 | treat | 2007-09-07 15:23:21 -0400 (Fri, 07 Sep 2007) | 5 lines * Rename KstApplication to use namespace. * No need for singleton ViewItemDialog. * Add ability for ViewItem subclasses to customize the ViewItemDialog by adding pages. ------------------------------------------------------------------------ r709532 | treat | 2007-09-07 14:49:11 -0400 (Fri, 07 Sep 2007) | 4 lines * No more restore defaults by default. * Respect apply button for ViewItemDialog. * Little redesign to hopefully simplify and make clear. ------------------------------------------------------------------------ r709483 | treat | 2007-09-07 11:26:10 -0400 (Fri, 07 Sep 2007) | 2 lines * These are no longer needed. ------------------------------------------------------------------------ r709482 | treat | 2007-09-07 11:25:28 -0400 (Fri, 07 Sep 2007) | 8 lines * Add new base classes for all kst dialogs -Kst::Dialog -Kst::DialogPage -Kst::DialogTab * Move fillandstroke and break it out into individual tabs * Modify ViewItemDialog to use the new classes ------------------------------------------------------------------------ r709256 | treat | 2007-09-06 19:18:47 -0400 (Thu, 06 Sep 2007) | 3 lines * Add spacing and margin to gridlayout. * Add a default strut for margin/spacing. ------------------------------------------------------------------------ r709220 | treat | 2007-09-06 17:20:19 -0400 (Thu, 06 Sep 2007) | 2 lines * Get rid of unneeded demo now. ------------------------------------------------------------------------ r709218 | treat | 2007-09-06 17:00:22 -0400 (Thu, 06 Sep 2007) | 5 lines * Add an action for toggle between data/layout modes. * Re-arrange some of the menu items and toolbars. * Disable layout related actions when not in layout mode. * Hide the layout toolbar when not in layout mode, but show it otherwise. ------------------------------------------------------------------------ r709158 | treat | 2007-09-06 13:09:20 -0400 (Thu, 06 Sep 2007) | 7 lines * Create a data/layout mode for views. * When in layout mode, you can manipulate the viewobjects * When in data mode, you can do zoom, etc. * Adjust the render items so you can now select the parent plotitem when in layout mode as you'd expect. ------------------------------------------------------------------------ r709139 | treat | 2007-09-06 12:27:59 -0400 (Thu, 06 Sep 2007) | 2 lines * Start transition to ok,apply,cancel ------------------------------------------------------------------------ r709131 | treat | 2007-09-06 11:59:16 -0400 (Thu, 06 Sep 2007) | 6 lines * Add debug stream operator to view items for easier debug * Set items to handle child events if a layout is present * Set creation pos to QPointF(0,0) * Don't create useless commands * Implement reparenting rules according to the spec ------------------------------------------------------------------------ r708894 | treat | 2007-09-05 19:10:53 -0400 (Wed, 05 Sep 2007) | 13 lines * Add two new images for layout/breaklayout * Don't draw anything for dummy ViewItem's * Add two new actions for layout/breaklayout to toolbars and remove from view context menu * Keep the aspect ratio when TLV resizes * Default the TLV scene to 800x600 for now * Provide easy convenience to add layout box to top-level scene * Implement command pattern for layouts * Bugfixing for the grid layout placement * Little refactoring of method names * Get ready for reparenting ------------------------------------------------------------------------ r708418 | treat | 2007-09-04 17:45:00 -0400 (Tue, 04 Sep 2007) | 2 lines * No more edit on double click ------------------------------------------------------------------------ r708350 | treat | 2007-09-04 11:47:01 -0400 (Tue, 04 Sep 2007) | 2 lines * Get ready for testing layouts more extensively ------------------------------------------------------------------------ r707056 | netterfield | 2007-08-31 17:56:24 -0400 (Fri, 31 Aug 2007) | 3 lines Add comments about parenting and parenting feedback. ------------------------------------------------------------------------ r707016 | treat | 2007-08-31 15:38:41 -0400 (Fri, 31 Aug 2007) | 2 lines * Make it obvious ------------------------------------------------------------------------ r707015 | treat | 2007-08-31 15:37:05 -0400 (Fri, 31 Aug 2007) | 3 lines * Fix a crash nicholas found and disable gradient editor as it is not ready. ------------------------------------------------------------------------ r707003 | treat | 2007-08-31 15:05:01 -0400 (Fri, 31 Aug 2007) | 2 lines * Sep out resize and scale in command pattern ------------------------------------------------------------------------ r706998 | treat | 2007-08-31 14:53:56 -0400 (Fri, 31 Aug 2007) | 2 lines * Default lock aspect for pictures ------------------------------------------------------------------------ r706995 | treat | 2007-08-31 14:50:34 -0400 (Fri, 31 Aug 2007) | 2 lines * Work on preserving aspect ratio ------------------------------------------------------------------------ r706908 | treat | 2007-08-31 10:44:53 -0400 (Fri, 31 Aug 2007) | 2 lines * some experiments that aren't done ------------------------------------------------------------------------ r706894 | treat | 2007-08-31 10:20:25 -0400 (Fri, 31 Aug 2007) | 2 lines * Resize works, but are funny when rotation is applied. ------------------------------------------------------------------------ r706652 | treat | 2007-08-30 21:02:58 -0400 (Thu, 30 Aug 2007) | 2 lines * too far ------------------------------------------------------------------------ r706638 | treat | 2007-08-30 19:15:09 -0400 (Thu, 30 Aug 2007) | 2 lines * Only left button for creation of items ------------------------------------------------------------------------ r706634 | treat | 2007-08-30 18:48:35 -0400 (Thu, 30 Aug 2007) | 2 lines * resize experiment. works, but not with transforms. ------------------------------------------------------------------------ r706571 | treat | 2007-08-30 15:34:17 -0400 (Thu, 30 Aug 2007) | 2 lines * Show all the points since we can do that now :) ------------------------------------------------------------------------ r706559 | treat | 2007-08-30 15:14:01 -0400 (Thu, 30 Aug 2007) | 12 lines This is a hack around something we do extensively in Kst that we can no longer do (and *should* no longer do) in the future. Namely, attempt to de-reference a Qt container iterator that might be QContainer::end() No more 'KstFooPtr = *_inputVector.find("SOMEFOOTHING");' For now, I've hacked around this so I can draw a curve without specifying error bars. In the future, we'll probably want to redesign our container classes to make this easier. ------------------------------------------------------------------------ r706513 | netterfield | 2007-08-30 12:11:53 -0400 (Thu, 30 Aug 2007) | 4 lines Fix error spotted by Nicholas: reference plot -> reference page ------------------------------------------------------------------------ r706485 | treat | 2007-08-30 10:47:54 -0400 (Thu, 30 Aug 2007) | 2 lines * Don't trigger internal lex/yacc handling in qmake. ------------------------------------------------------------------------ r706463 | treat | 2007-08-30 09:44:46 -0400 (Thu, 30 Aug 2007) | 2 lines * Get ready for real resize VS real scale ------------------------------------------------------------------------ r706450 | treat | 2007-08-30 09:05:54 -0400 (Thu, 30 Aug 2007) | 3 lines * Rename and reorganize the menus/toolbars to fit the new spec better. ------------------------------------------------------------------------ r706444 | treat | 2007-08-30 08:38:44 -0400 (Thu, 30 Aug 2007) | 2 lines * Floating point snap and more options ------------------------------------------------------------------------ r706341 | netterfield | 2007-08-29 20:38:54 -0400 (Wed, 29 Aug 2007) | 5 lines Two new spec docs: Fonts.pdf: description of how fonts behave in kst2 Layout mode.pdf: description of the UI in layout mode ------------------------------------------------------------------------ r706220 | treat | 2007-08-29 13:59:15 -0400 (Wed, 29 Aug 2007) | 4 lines * Draw a grid and snap item creation and movement to this grid. All of this will be configurable in the future of course. ------------------------------------------------------------------------ r706158 | treat | 2007-08-29 11:12:11 -0400 (Wed, 29 Aug 2007) | 2 lines * New grid layout and other fixes ------------------------------------------------------------------------ r704487 | treat | 2007-08-24 23:02:27 -0400 (Fri, 24 Aug 2007) | 2 lines * Place items and ignore events for plots in layout ------------------------------------------------------------------------ r704391 | treat | 2007-08-24 15:40:33 -0400 (Fri, 24 Aug 2007) | 2 lines * Begin work on a layout class for plots ------------------------------------------------------------------------ r704333 | treat | 2007-08-24 13:04:06 -0400 (Fri, 24 Aug 2007) | 2 lines Labels are drawing and resizing nicely... ------------------------------------------------------------------------ r704306 | treat | 2007-08-24 11:29:51 -0400 (Fri, 24 Aug 2007) | 2 lines * More label work ------------------------------------------------------------------------ r704262 | treat | 2007-08-24 10:13:50 -0400 (Fri, 24 Aug 2007) | 2 lines Compile ------------------------------------------------------------------------ r700163 | staikos | 2007-08-14 19:43:07 -0400 (Tue, 14 Aug 2007) | 2 lines rebuild cleanly ------------------------------------------------------------------------ r700131 | treat | 2007-08-14 18:14:38 -0400 (Tue, 14 Aug 2007) | 3 lines * Labels, refactoring, drawing code, plots are much better now. ------------------------------------------------------------------------ r695837 | treat | 2007-08-02 23:57:15 -0400 (Thu, 02 Aug 2007) | 2 lines Refactor a bit now that I know better how this is going to work. ------------------------------------------------------------------------ r695832 | treat | 2007-08-02 23:04:46 -0400 (Thu, 02 Aug 2007) | 3 lines * No longer hard code the zoom box. Now it is calculated to display the first 100 points. ------------------------------------------------------------------------ r695814 | treat | 2007-08-02 21:14:31 -0400 (Thu, 02 Aug 2007) | 12 lines And... we're drawing plots :) I'm leaving in the debugging code until I have a chance to go through it and document/refactor the kstvcurve drawing code. The plots are still fully transformable via QGV. Rotating plots ;) I'm still hardcoding the zoom box to this particular vector, but at least we're drawing this one good... more later. ------------------------------------------------------------------------ r695695 | staikos | 2007-08-02 13:38:23 -0400 (Thu, 02 Aug 2007) | 2 lines OS X build fixes ------------------------------------------------------------------------ r695691 | treat | 2007-08-02 13:31:16 -0400 (Thu, 02 Aug 2007) | 2 lines Draw something vaguely resembling error bars ------------------------------------------------------------------------ r695184 | treat | 2007-08-01 11:03:20 -0400 (Wed, 01 Aug 2007) | 5 lines * And we're back to drawing the red dot, but at least this time we're drawing with the right QPainter brush. Also, the scale of the dot changes as the plot is scaled. So that's nice. ------------------------------------------------------------------------ r695164 | treat | 2007-08-01 10:21:10 -0400 (Wed, 01 Aug 2007) | 2 lines * Revert for now ------------------------------------------------------------------------ r695159 | treat | 2007-08-01 09:52:35 -0400 (Wed, 01 Aug 2007) | 2 lines * Another rename and get ready to change to QGV subclass ------------------------------------------------------------------------ r695155 | treat | 2007-08-01 09:45:12 -0400 (Wed, 01 Aug 2007) | 2 lines * The real rename. ------------------------------------------------------------------------ r695150 | treat | 2007-08-01 09:38:26 -0400 (Wed, 01 Aug 2007) | 2 lines * rename ------------------------------------------------------------------------ r694518 | treat | 2007-07-30 18:46:15 -0400 (Mon, 30 Jul 2007) | 8 lines Try to draw a plot. Not working... most likely because I can't fathom how to setup a KstCurveRenderContext correctly. Quoting kstplot2d: // FIXME: someone document what these things mean ------------------------------------------------------------------------ r694450 | treat | 2007-07-30 15:14:21 -0400 (Mon, 30 Jul 2007) | 3 lines * Redesign and refactor and add plumbing so we can start drawing plots. ------------------------------------------------------------------------ r694435 | treat | 2007-07-30 13:46:10 -0400 (Mon, 30 Jul 2007) | 2 lines Don't crash ------------------------------------------------------------------------ r693748 | netterfield | 2007-07-28 17:52:32 -0400 (Sat, 28 Jul 2007) | 4 lines Add Adams's installation instructions. Add comments on current layout/tool mode behavior. ------------------------------------------------------------------------ r691420 | aseigo | 2007-07-23 12:27:05 -0400 (Mon, 23 Jul 2007) | 2 lines build on amd64, where you can't cast pointers to simple ints ------------------------------------------------------------------------ r690037 | netterfield | 2007-07-19 17:41:37 -0400 (Thu, 19 Jul 2007) | 10 lines Re-organize devel docs and add some new docs: depricated: no longer valid, but of potential historical interest general_1.x: applies to 1.x, and may apply to 2.x Kst2Specs: design docs for Kst2 I have added 2 pdfs to Kst2Specs to describe datasource/string changes, and to describe kstplot geometry. ------------------------------------------------------------------------ r689812 | staikos | 2007-07-19 04:08:30 -0400 (Thu, 19 Jul 2007) | 2 lines remove some obsolete ones ------------------------------------------------------------------------ r689811 | staikos | 2007-07-19 04:06:28 -0400 (Thu, 19 Jul 2007) | 3 lines Add a view manager dialog with no model or real UI yet. Also add an about dialog (needs a handler for the URLs) ------------------------------------------------------------------------ r689801 | staikos | 2007-07-19 03:20:34 -0400 (Thu, 19 Jul 2007) | 2 lines add icons ------------------------------------------------------------------------ r689647 | treat | 2007-07-18 15:39:07 -0400 (Wed, 18 Jul 2007) | 2 lines * Sync loading with saving of equations. ------------------------------------------------------------------------ r689639 | treat | 2007-07-18 15:03:26 -0400 (Wed, 18 Jul 2007) | 2 lines * Load svector, avector, and rvector too. ------------------------------------------------------------------------ r689626 | treat | 2007-07-18 14:22:29 -0400 (Wed, 18 Jul 2007) | 2 lines * Actually create the vectors ------------------------------------------------------------------------ r689588 | treat | 2007-07-18 12:17:18 -0400 (Wed, 18 Jul 2007) | 2 lines * Add prelim loading of vectors. ------------------------------------------------------------------------ r689553 | treat | 2007-07-18 10:59:30 -0400 (Wed, 18 Jul 2007) | 3 lines * Equations now load ------------------------------------------------------------------------ r689391 | staikos | 2007-07-18 02:31:21 -0400 (Wed, 18 Jul 2007) | 2 lines load in the icons and images ------------------------------------------------------------------------ r689389 | staikos | 2007-07-18 02:24:54 -0400 (Wed, 18 Jul 2007) | 2 lines more moves ------------------------------------------------------------------------ r689386 | staikos | 2007-07-18 02:21:55 -0400 (Wed, 18 Jul 2007) | 2 lines moved ------------------------------------------------------------------------ r689380 | staikos | 2007-07-18 02:17:14 -0400 (Wed, 18 Jul 2007) | 2 lines how to make toolbars work ------------------------------------------------------------------------ r689376 | staikos | 2007-07-18 02:03:35 -0400 (Wed, 18 Jul 2007) | 2 lines add saving of equations ------------------------------------------------------------------------ r689375 | staikos | 2007-07-18 01:57:21 -0400 (Wed, 18 Jul 2007) | 2 lines don't save slaves ------------------------------------------------------------------------ r689265 | treat | 2007-07-17 21:17:53 -0400 (Tue, 17 Jul 2007) | 2 lines * A cheap and simple getopt for now. ------------------------------------------------------------------------ r689149 | treat | 2007-07-17 15:03:13 -0400 (Tue, 17 Jul 2007) | 2 lines * Note which dataobjects still need to be serialized ------------------------------------------------------------------------ r689143 | treat | 2007-07-17 14:29:55 -0400 (Tue, 17 Jul 2007) | 2 lines * Move tag to impl file. ------------------------------------------------------------------------ r688822 | treat | 2007-07-16 19:08:55 -0400 (Mon, 16 Jul 2007) | 3 lines * Give these their own files to lesson the confusion if/when we switch to real qt4 containers. ------------------------------------------------------------------------ r688815 | treat | 2007-07-16 18:25:16 -0400 (Mon, 16 Jul 2007) | 2 lines * Better errors and actually save our demo data. ------------------------------------------------------------------------ r688749 | treat | 2007-07-16 15:00:29 -0400 (Mon, 16 Jul 2007) | 2 lines * Open files from command line* Open files from command line* Open files from command line* Open files from command line* Open files from command line* Open files from command line* Open files from command line* Open files from command line ------------------------------------------------------------------------ r688735 | treat | 2007-07-16 14:20:42 -0400 (Mon, 16 Jul 2007) | 2 lines * A little saving/loading workup. ------------------------------------------------------------------------ r688697 | treat | 2007-07-16 12:48:29 -0400 (Mon, 16 Jul 2007) | 2 lines * Pass some args when needed ------------------------------------------------------------------------ r688659 | staikos | 2007-07-16 10:53:21 -0400 (Mon, 16 Jul 2007) | 3 lines Major refactoring that adds KstRelation and implements a big portion of the new Kst file format ------------------------------------------------------------------------ r683985 | treat | 2007-07-05 16:21:13 -0400 (Thu, 05 Jul 2007) | 3 lines * Just a minor change as we switch over to qmake... ------------------------------------------------------------------------ r683429 | treat | 2007-07-04 14:11:04 -0400 (Wed, 04 Jul 2007) | 2 lines * I believe all dependencies are gone ------------------------------------------------------------------------ r683352 | treat | 2007-07-04 12:25:06 -0400 (Wed, 04 Jul 2007) | 2 lines * No more kcodecs ------------------------------------------------------------------------ r683338 | treat | 2007-07-04 12:11:28 -0400 (Wed, 04 Jul 2007) | 3 lines * Not sure if this should open/close for every update, but don't leak. ------------------------------------------------------------------------ r683328 | treat | 2007-07-04 11:51:55 -0400 (Wed, 04 Jul 2007) | 2 lines * Move away from K3* ------------------------------------------------------------------------ r683302 | treat | 2007-07-04 11:05:44 -0400 (Wed, 04 Jul 2007) | 2 lines * Provide alternative to i18n for some configurations ------------------------------------------------------------------------ r683016 | treat | 2007-07-03 18:21:05 -0400 (Tue, 03 Jul 2007) | 2 lines * Get rid of bunch of static deleters ------------------------------------------------------------------------ r683007 | staikos | 2007-07-03 17:27:09 -0400 (Tue, 03 Jul 2007) | 2 lines merge psd fixes from 1.4 ------------------------------------------------------------------------ r682920 | treat | 2007-07-03 13:19:36 -0400 (Tue, 03 Jul 2007) | 2 lines * Not the right approach ------------------------------------------------------------------------ r682913 | treat | 2007-07-03 13:02:42 -0400 (Tue, 03 Jul 2007) | 2 lines * More internationalization ------------------------------------------------------------------------ r682906 | treat | 2007-07-03 12:53:01 -0400 (Tue, 03 Jul 2007) | 2 lines * international ------------------------------------------------------------------------ r682890 | treat | 2007-07-03 12:21:01 -0400 (Tue, 03 Jul 2007) | 2 lines * No more kconfig ------------------------------------------------------------------------ r682876 | treat | 2007-07-03 11:46:16 -0400 (Tue, 03 Jul 2007) | 2 lines * More removal of KConfig ------------------------------------------------------------------------ r681356 | treat | 2007-06-28 13:49:37 -0400 (Thu, 28 Jun 2007) | 2 lines * Convert to QSettings ------------------------------------------------------------------------ r681312 | treat | 2007-06-28 10:43:20 -0400 (Thu, 28 Jun 2007) | 2 lines * Cleanup ------------------------------------------------------------------------ r681061 | treat | 2007-06-27 17:03:48 -0400 (Wed, 27 Jun 2007) | 2 lines * All ascii tests are good now. ------------------------------------------------------------------------ r681046 | treat | 2007-06-27 16:22:02 -0400 (Wed, 27 Jun 2007) | 2 lines * Only one test fails for ascii now. The last one. ------------------------------------------------------------------------ r681022 | treat | 2007-06-27 14:43:18 -0400 (Wed, 27 Jun 2007) | 14 lines * Quite a big change. Start refactoring datasource plugin loading. Move ascii datasource to new style. Disable other datasources for now. Fix testrvector so that it "works" for ascii. Currently, ascii doesn't pass all the tests, but I doubt very much it has to do with the plugin changes. * I've hardcoded the plugin dir for now to use the full path on my system for easy testing. This will change of course. * DataObject plugins are down for now. ------------------------------------------------------------------------ r680250 | treat | 2007-06-25 14:28:55 -0400 (Mon, 25 Jun 2007) | 2 lines * Disable for a second while I rework a bit. ------------------------------------------------------------------------ r677389 | staikos | 2007-06-19 00:26:27 -0400 (Tue, 19 Jun 2007) | 2 lines update the TODO and fix a few quirks ------------------------------------------------------------------------ r677388 | staikos | 2007-06-19 00:10:32 -0400 (Tue, 19 Jun 2007) | 2 lines be less destructive ------------------------------------------------------------------------ r677240 | treat | 2007-06-18 14:44:13 -0400 (Mon, 18 Jun 2007) | 5 lines * Add prelim gradient editor. All items can now set a fill gradient for background. Fix up colorbutton. Fix up viewitemdialog. Other fixes. ------------------------------------------------------------------------ r677121 | treat | 2007-06-18 10:01:32 -0400 (Mon, 18 Jun 2007) | 3 lines * Clean up plotitem to use proper ::paint overload and remove extra spaces ------------------------------------------------------------------------ r677120 | treat | 2007-06-18 09:58:48 -0400 (Mon, 18 Jun 2007) | 3 lines * Clean up spaces and no reason to include non-existent moc files ------------------------------------------------------------------------ r677119 | treat | 2007-06-18 09:56:39 -0400 (Mon, 18 Jun 2007) | 3 lines * Don't include plot*.moc file in axis.cpp and clean up the extra spaces ------------------------------------------------------------------------ r677115 | treat | 2007-06-18 09:49:15 -0400 (Mon, 18 Jun 2007) | 3 lines * Please remove extra spaces and make sure to follow the coding style. ------------------------------------------------------------------------ r676960 | tskisner | 2007-06-18 01:29:44 -0400 (Mon, 18 Jun 2007) | 1 line Beggining of 2D rendering framework. Each PlotItem has a list of renderers and each renderer has a list of basecurves. Much still TODO before a working demo is available. ------------------------------------------------------------------------ r676062 | treat | 2007-06-15 17:05:06 -0400 (Fri, 15 Jun 2007) | 4 lines * Hook up the dialog. It works by operating on all selected viewitems at once and is nonmodal. ------------------------------------------------------------------------ r676043 | treat | 2007-06-15 15:31:44 -0400 (Fri, 15 Jun 2007) | 2 lines * First dialog for viewitems ------------------------------------------------------------------------ r676013 | treat | 2007-06-15 13:55:33 -0400 (Fri, 15 Jun 2007) | 2 lines * Begin with a simple widget ------------------------------------------------------------------------ r675983 | treat | 2007-06-15 12:44:16 -0400 (Fri, 15 Jun 2007) | 2 lines * Placeholder ------------------------------------------------------------------------ r675982 | treat | 2007-06-15 12:43:17 -0400 (Fri, 15 Jun 2007) | 2 lines * Move this out of the way ------------------------------------------------------------------------ r675955 | treat | 2007-06-15 11:17:00 -0400 (Fri, 15 Jun 2007) | 2 lines * Don't change mouseMode when showing the context menu ------------------------------------------------------------------------ r675751 | treat | 2007-06-14 19:49:18 -0400 (Thu, 14 Jun 2007) | 6 lines * Can not call setPen() inside paint event as QGraphicsItem calls update() within setPen(). Instead, provide an overload that items can use to draw instead of the base class rect(). ------------------------------------------------------------------------ r675692 | treat | 2007-06-14 14:33:18 -0400 (Thu, 14 Jun 2007) | 2 lines * No pen for labels, and make sure to use rect() ------------------------------------------------------------------------ r675669 | treat | 2007-06-14 13:10:04 -0400 (Thu, 14 Jun 2007) | 2 lines * Proper painting of grips when scaled < 1 ------------------------------------------------------------------------ r675646 | treat | 2007-06-14 11:45:30 -0400 (Thu, 14 Jun 2007) | 5 lines * Finally, all transformations are properly anchored no matter the current rotation or translation of the actual rect object. ------------------------------------------------------------------------ r675086 | treat | 2007-06-13 13:55:06 -0400 (Wed, 13 Jun 2007) | 2 lines * Better ------------------------------------------------------------------------ r674740 | treat | 2007-06-12 18:45:17 -0400 (Tue, 12 Jun 2007) | 2 lines * Better ------------------------------------------------------------------------ r674666 | treat | 2007-06-12 15:50:55 -0400 (Tue, 12 Jun 2007) | 7 lines * Huge change. The ViewItems now behave like items in inkscape for the most part. Still have some problems with resize transformations when a rotation has already been applied. The grips are also not always drawn correctly yet. ------------------------------------------------------------------------ r674189 | tskisner | 2007-06-11 19:01:24 -0400 (Mon, 11 Jun 2007) | 1 line whoops. set path to configure modules relative to top-level portto4 directory. ------------------------------------------------------------------------ r674008 | tskisner | 2007-06-11 11:27:46 -0400 (Mon, 11 Jun 2007) | 1 line Add some updates to the FITS utility library. This code is not enabled yet in the build because it is not fully ported to Qt4 yet. ------------------------------------------------------------------------ r673341 | tskisner | 2007-06-09 19:44:25 -0400 (Sat, 09 Jun 2007) | 1 line Begin the porting of configure checks to the cmake build system. Follow the standard practices for location and naming of files. This initial commit finds the CFITSIO library. More coming soon. ------------------------------------------------------------------------ r673335 | treat | 2007-06-09 18:55:17 -0400 (Sat, 09 Jun 2007) | 3 lines * This is correct. Draw the selection like inkscape does with the true real bounding rect. ------------------------------------------------------------------------ r673087 | treat | 2007-06-08 19:23:49 -0400 (Fri, 08 Jun 2007) | 3 lines * This seems to work better. ------------------------------------------------------------------------ r673082 | treat | 2007-06-08 19:02:18 -0400 (Fri, 08 Jun 2007) | 5 lines * Turn on debugging as I'm having a problem with the drawing the true boundingRect. Possibly a bug with mapToScene()?? ------------------------------------------------------------------------ r673076 | treat | 2007-06-08 18:28:30 -0400 (Fri, 08 Jun 2007) | 3 lines * Much better. We're going to draw our selection ourselves I think... ------------------------------------------------------------------------ r673059 | treat | 2007-06-08 17:14:16 -0400 (Fri, 08 Jun 2007) | 2 lines * Make rotate commands for undo/redo ------------------------------------------------------------------------ r673041 | treat | 2007-06-08 16:37:29 -0400 (Fri, 08 Jun 2007) | 3 lines * Introduce a mouse based rotation mode.. Need proper cursors for this still... ------------------------------------------------------------------------ r672992 | treat | 2007-06-08 13:42:51 -0400 (Fri, 08 Jun 2007) | 2 lines * Compress ResizeCommands and debuggify them ------------------------------------------------------------------------ r672956 | treat | 2007-06-08 10:55:59 -0400 (Fri, 08 Jun 2007) | 4 lines * Big refactor and fix for resizing undo/redo commands. ------------------------------------------------------------------------ r672713 | treat | 2007-06-07 18:21:02 -0400 (Thu, 07 Jun 2007) | 3 lines * This still isn't right, but resizing will also become an undo/redo command ------------------------------------------------------------------------ r672704 | treat | 2007-06-07 18:03:12 -0400 (Thu, 07 Jun 2007) | 2 lines * Makes more sense ------------------------------------------------------------------------ r672694 | treat | 2007-06-07 17:16:19 -0400 (Thu, 07 Jun 2007) | 3 lines * Fix the boundingRect for label items * Don't grab the mouse in creation mode ------------------------------------------------------------------------ r672672 | treat | 2007-06-07 16:31:34 -0400 (Thu, 07 Jun 2007) | 2 lines * Better debug and correct calls ------------------------------------------------------------------------ r672659 | treat | 2007-06-07 16:03:59 -0400 (Thu, 07 Jun 2007) | 3 lines * Actually scale VS resizing. Check out what this does to our labels :) ------------------------------------------------------------------------ r672653 | treat | 2007-06-07 15:20:57 -0400 (Thu, 07 Jun 2007) | 4 lines * Resizing of items via mouse grab now works. Need to figure out how were' going to do this for lines and labels though. ------------------------------------------------------------------------ r672636 | treat | 2007-06-07 14:41:15 -0400 (Thu, 07 Jun 2007) | 2 lines * Post some cursors for resizing ------------------------------------------------------------------------ r672625 | treat | 2007-06-07 13:56:27 -0400 (Thu, 07 Jun 2007) | 2 lines * Consolidate and refactor some of this ------------------------------------------------------------------------ r672618 | treat | 2007-06-07 13:25:36 -0400 (Thu, 07 Jun 2007) | 3 lines * Provide a context menu and three new item based actions/commands: remove, z-order up, z-order down ------------------------------------------------------------------------ r672591 | treat | 2007-06-07 11:48:15 -0400 (Thu, 07 Jun 2007) | 2 lines * Move most of this into base class ------------------------------------------------------------------------ r672570 | treat | 2007-06-07 11:00:43 -0400 (Thu, 07 Jun 2007) | 2 lines * Move ------------------------------------------------------------------------ r672568 | treat | 2007-06-07 10:52:42 -0400 (Thu, 07 Jun 2007) | 2 lines * Move to the base class ------------------------------------------------------------------------ r672564 | treat | 2007-06-07 10:42:12 -0400 (Thu, 07 Jun 2007) | 2 lines * All are rect items ------------------------------------------------------------------------ r672559 | treat | 2007-06-07 10:30:32 -0400 (Thu, 07 Jun 2007) | 2 lines * Convert items to common qgv base class ------------------------------------------------------------------------ r672300 | treat | 2007-06-06 13:31:25 -0400 (Wed, 06 Jun 2007) | 2 lines * Add an svg item ------------------------------------------------------------------------ r672288 | treat | 2007-06-06 12:52:46 -0400 (Wed, 06 Jun 2007) | 2 lines * QGLWidget is not degrading gracefully here... ------------------------------------------------------------------------ r672247 | treat | 2007-06-06 10:30:17 -0400 (Wed, 06 Jun 2007) | 3 lines * Movement commands for all items are done, compression is enabled and macro commands for selection moves completed. ------------------------------------------------------------------------ r671846 | treat | 2007-06-05 12:01:11 -0400 (Tue, 05 Jun 2007) | 3 lines * Fix up the label item so it can move, select, etc, etc ------------------------------------------------------------------------ r671775 | treat | 2007-06-05 10:17:27 -0400 (Tue, 05 Jun 2007) | 2 lines * Couple strays ------------------------------------------------------------------------ r671216 | staikos | 2007-06-04 03:08:16 -0400 (Mon, 04 Jun 2007) | 11 lines A huge pile of work. Not sure I'll be able to capture everything: 1) Remove C plugins entirely 2) Add factories for loading objects from xml 3) Implement a demo of the new XML spec (reading) 4) Support a few graphics nodes for reading 5) Implement skeleton of writing xml 6) Some general refactoring and cleanup 7) Add some missing actions / shortcuts 8) Start to spec out how plot might work ------------------------------------------------------------------------ r671215 | staikos | 2007-06-04 03:04:53 -0400 (Mon, 04 Jun 2007) | 2 lines The beginnings of some design specs or at least statements ------------------------------------------------------------------------ r670303 | staikos | 2007-05-31 20:35:50 -0400 (Thu, 31 May 2007) | 4 lines add an object factory that can be used to make objects independent of the document. However it only works for data objects. I don't want to go too far with this until the .kst file structure is finalized ------------------------------------------------------------------------ r670296 | staikos | 2007-05-31 20:16:24 -0400 (Thu, 31 May 2007) | 2 lines some state tracking for Document ------------------------------------------------------------------------ r670240 | staikos | 2007-05-31 16:24:22 -0400 (Thu, 31 May 2007) | 3 lines hook in xml stream reader, which does basically nothing. next step is to make a factory for generating document nodes from the xml nodes. ------------------------------------------------------------------------ r670233 | staikos | 2007-05-31 16:04:19 -0400 (Thu, 31 May 2007) | 2 lines port to trunk ------------------------------------------------------------------------ r670232 | staikos | 2007-05-31 16:02:33 -0400 (Thu, 31 May 2007) | 2 lines port to trunk ------------------------------------------------------------------------ r670230 | staikos | 2007-05-31 16:00:25 -0400 (Thu, 31 May 2007) | 3 lines updated to build with trunk. extdate is dead ------------------------------------------------------------------------ r670228 | staikos | 2007-05-31 15:48:44 -0400 (Thu, 31 May 2007) | 2 lines match changes in kdelibs trunk ------------------------------------------------------------------------ r670176 | staikos | 2007-05-31 11:40:01 -0400 (Thu, 31 May 2007) | 2 lines hook in more of the debug dialog ------------------------------------------------------------------------ r670174 | staikos | 2007-05-31 11:24:49 -0400 (Thu, 31 May 2007) | 2 lines cleanup ------------------------------------------------------------------------ r670014 | staikos | 2007-05-30 23:00:44 -0400 (Wed, 30 May 2007) | 2 lines stub out the debug dialog and connect the notifier to it. ------------------------------------------------------------------------ r670008 | staikos | 2007-05-30 22:12:57 -0400 (Wed, 30 May 2007) | 2 lines hook in the debug notifier (needs a signal connection and pixmaps) ------------------------------------------------------------------------ r670006 | staikos | 2007-05-30 22:00:39 -0400 (Wed, 30 May 2007) | 2 lines add a stub export graphics dialog ------------------------------------------------------------------------ r669890 | staikos | 2007-05-30 14:14:10 -0400 (Wed, 30 May 2007) | 2 lines start to clean this up so it can be activated ------------------------------------------------------------------------ r669887 | staikos | 2007-05-30 14:03:43 -0400 (Wed, 30 May 2007) | 2 lines start to implement printing support ------------------------------------------------------------------------ r669876 | staikos | 2007-05-30 13:22:07 -0400 (Wed, 30 May 2007) | 2 lines Add in the memory free widget and a progress bar ------------------------------------------------------------------------ r669867 | staikos | 2007-05-30 12:58:01 -0400 (Wed, 30 May 2007) | 4 lines - hack the label into the right place for now - give plots a solid background (white for now) ------------------------------------------------------------------------ r669862 | staikos | 2007-05-30 12:44:58 -0400 (Wed, 30 May 2007) | 5 lines make labelitem a rectitem so that it can use the label renderer. Hook in the label renderer in a very primitive manner - it works! - but it looks ugly. This is also a bit slow, but it shows that compositing works. ------------------------------------------------------------------------ r669741 | staikos | 2007-05-30 04:48:55 -0400 (Wed, 30 May 2007) | 2 lines display slave vectors, more info ------------------------------------------------------------------------ r669732 | treat | 2007-05-30 03:52:44 -0400 (Wed, 30 May 2007) | 2 lines * Probably a better way, but this works for now ------------------------------------------------------------------------ r669725 | staikos | 2007-05-30 02:54:45 -0400 (Wed, 30 May 2007) | 2 lines add a more generic vector editor/spreadsheet mode dialog ------------------------------------------------------------------------ r669724 | staikos | 2007-05-30 02:54:04 -0400 (Wed, 30 May 2007) | 5 lines more checks and cleanup, and add a copy constructor to indicate where Kst will crash due to shallow copy of pointers. This is really nasty and took hours to track down. It may also affect trunk, but I don't know of any place doing this particular thing in trunk. ------------------------------------------------------------------------ r669714 | staikos | 2007-05-30 02:13:04 -0400 (Wed, 30 May 2007) | 2 lines fix debug ------------------------------------------------------------------------ r669711 | staikos | 2007-05-30 01:59:48 -0400 (Wed, 30 May 2007) | 2 lines cleanup debug and reduce lookups a bit ------------------------------------------------------------------------ r669676 | staikos | 2007-05-29 21:26:07 -0400 (Tue, 29 May 2007) | 3 lines add a most excellent hack to make iteration work transparently on KstObjectCollection. :-) ------------------------------------------------------------------------ r669638 | staikos | 2007-05-29 17:39:11 -0400 (Tue, 29 May 2007) | 3 lines it's a bit buggy but it shows how the data manager can work - populates with objects ------------------------------------------------------------------------ r669631 | staikos | 2007-05-29 17:05:49 -0400 (Tue, 29 May 2007) | 2 lines add the hook for creating plots ------------------------------------------------------------------------ r669564 | staikos | 2007-05-29 13:58:32 -0400 (Tue, 29 May 2007) | 3 lines A basic plan on some things that need to be done and how they should be done, in very brief point form ------------------------------------------------------------------------ r669556 | staikos | 2007-05-29 13:26:33 -0400 (Tue, 29 May 2007) | 2 lines add an untested matrix model class ------------------------------------------------------------------------ r669554 | staikos | 2007-05-29 13:25:45 -0400 (Tue, 29 May 2007) | 2 lines repair the api ------------------------------------------------------------------------ r669552 | staikos | 2007-05-29 13:11:40 -0400 (Tue, 29 May 2007) | 2 lines add picture support ------------------------------------------------------------------------ r669542 | staikos | 2007-05-29 12:25:45 -0400 (Tue, 29 May 2007) | 3 lines stub out Document, SessionModel, DataManager, though DataManager is actually so trivial with this object structure that it's almost done. ------------------------------------------------------------------------ r669518 | staikos | 2007-05-29 11:31:30 -0400 (Tue, 29 May 2007) | 2 lines make editable vectors bold ------------------------------------------------------------------------ r669513 | staikos | 2007-05-29 11:19:10 -0400 (Tue, 29 May 2007) | 2 lines demonstrate editable spreadsheet mode ------------------------------------------------------------------------ r669495 | staikos | 2007-05-29 10:41:15 -0400 (Tue, 29 May 2007) | 2 lines from the confusing department, this did "init", not "reinit". Let's call it that ------------------------------------------------------------------------ r669234 | staikos | 2007-05-28 16:26:00 -0400 (Mon, 28 May 2007) | 2 lines hook in the context menu for tabs ------------------------------------------------------------------------ r669224 | staikos | 2007-05-28 16:06:04 -0400 (Mon, 28 May 2007) | 2 lines add multi-tab support, more actions that do nothing. ------------------------------------------------------------------------ r669220 | staikos | 2007-05-28 15:55:39 -0400 (Mon, 28 May 2007) | 3 lines separate the tab widget out of the main window and make the naming more consistent ------------------------------------------------------------------------ r669201 | staikos | 2007-05-28 15:05:46 -0400 (Mon, 28 May 2007) | 2 lines add a vector table model as a table of vector models ------------------------------------------------------------------------ r669188 | staikos | 2007-05-28 14:38:16 -0400 (Mon, 28 May 2007) | 2 lines add a demo of OpenGL along with a settings class for global app settings ------------------------------------------------------------------------ r669180 | staikos | 2007-05-28 14:08:59 -0400 (Mon, 28 May 2007) | 2 lines demonstrate how fast we can load and display a million points ------------------------------------------------------------------------ r669172 | staikos | 2007-05-28 13:55:45 -0400 (Mon, 28 May 2007) | 2 lines missing const ------------------------------------------------------------------------ r669168 | staikos | 2007-05-28 13:41:29 -0400 (Mon, 28 May 2007) | 2 lines rename file accordingly ------------------------------------------------------------------------ r669167 | staikos | 2007-05-28 13:40:00 -0400 (Mon, 28 May 2007) | 2 lines namespace ------------------------------------------------------------------------ r669164 | staikos | 2007-05-28 13:37:09 -0400 (Mon, 28 May 2007) | 2 lines add ellipse items ------------------------------------------------------------------------ r669161 | staikos | 2007-05-28 13:29:08 -0400 (Mon, 28 May 2007) | 2 lines add box items ------------------------------------------------------------------------ r669150 | staikos | 2007-05-28 12:42:30 -0400 (Mon, 28 May 2007) | 2 lines more refactoring ------------------------------------------------------------------------ r669146 | staikos | 2007-05-28 12:32:23 -0400 (Mon, 28 May 2007) | 2 lines more refactoring ------------------------------------------------------------------------ r669142 | staikos | 2007-05-28 12:19:19 -0400 (Mon, 28 May 2007) | 2 lines completely refactor, start namespacing. more to come. ------------------------------------------------------------------------ r668439 | treat | 2007-05-26 08:43:58 -0400 (Sat, 26 May 2007) | 2 lines * Update ------------------------------------------------------------------------ r668438 | treat | 2007-05-26 08:43:29 -0400 (Sat, 26 May 2007) | 2 lines * Set drag mode and TODO updates ------------------------------------------------------------------------ r668436 | treat | 2007-05-26 08:35:27 -0400 (Sat, 26 May 2007) | 5 lines * Undo/Redo for QGraphicsScene move interaction at least for the label. Right now it is too greedy as it produces an undocommand for each slight movement. ------------------------------------------------------------------------ r668339 | treat | 2007-05-25 22:48:27 -0400 (Fri, 25 May 2007) | 2 lines * Use proper cursors ------------------------------------------------------------------------ r668338 | treat | 2007-05-25 22:37:52 -0400 (Fri, 25 May 2007) | 2 lines * Create label properly by choosing a spot first ------------------------------------------------------------------------ r668329 | treat | 2007-05-25 20:11:59 -0400 (Fri, 25 May 2007) | 5 lines * Initialize the scene rect to the size of whatever the view is when it is first shown. Not sure if this is what we really want. ------------------------------------------------------------------------ r668321 | treat | 2007-05-25 19:30:56 -0400 (Fri, 25 May 2007) | 4 lines * Visual debug for geometry problems * Don't scale individual items... scale the scene instead when view is resized ------------------------------------------------------------------------ r668308 | treat | 2007-05-25 18:22:18 -0400 (Fri, 25 May 2007) | 6 lines * Allow for creation interrupt/abort. Still not happy with this as we have to allocate all creation commands on the heap and there is a somewhat confusing signal/slot tree going on... ------------------------------------------------------------------------ r668288 | treat | 2007-05-25 16:44:34 -0400 (Fri, 25 May 2007) | 2 lines * Fix up preserve aspect ratio a bit ------------------------------------------------------------------------ r668263 | treat | 2007-05-25 14:54:50 -0400 (Fri, 25 May 2007) | 2 lines * Employ a new strategy for drawing item creation ------------------------------------------------------------------------ r668248 | treat | 2007-05-25 12:53:36 -0400 (Fri, 25 May 2007) | 2 lines * Get ready to draw various creation modes ------------------------------------------------------------------------ r668244 | treat | 2007-05-25 12:17:58 -0400 (Fri, 25 May 2007) | 2 lines * Don't disconnect ALL signals ;) ------------------------------------------------------------------------ r668120 | staikos | 2007-05-25 02:22:58 -0400 (Fri, 25 May 2007) | 3 lines adding some interaction and aspect ratio support, though for some reason my slot never gets called ------------------------------------------------------------------------ r668103 | treat | 2007-05-25 00:58:37 -0400 (Fri, 25 May 2007) | 2 lines * Scratch pad ------------------------------------------------------------------------ r668102 | treat | 2007-05-25 00:52:59 -0400 (Fri, 25 May 2007) | 2 lines * SOVERSION = 2 ------------------------------------------------------------------------ r668100 | treat | 2007-05-25 00:33:23 -0400 (Fri, 25 May 2007) | 2 lines * Look nice for now ------------------------------------------------------------------------ r668099 | treat | 2007-05-25 00:30:47 -0400 (Fri, 25 May 2007) | 2 lines * Z-Value fixes and resize scene along with view ------------------------------------------------------------------------ r668094 | treat | 2007-05-24 23:32:16 -0400 (Thu, 24 May 2007) | 2 lines * Add some lines ------------------------------------------------------------------------ r668087 | treat | 2007-05-24 22:55:25 -0400 (Thu, 24 May 2007) | 3 lines * Setup for various item creation commands ------------------------------------------------------------------------ r668062 | treat | 2007-05-24 19:33:00 -0400 (Thu, 24 May 2007) | 2 lines * Undo and redo for the label command works. ------------------------------------------------------------------------ r668061 | treat | 2007-05-24 19:19:44 -0400 (Thu, 24 May 2007) | 2 lines * Create label command and object ------------------------------------------------------------------------ r668038 | treat | 2007-05-24 17:20:59 -0400 (Thu, 24 May 2007) | 2 lines * Break out ------------------------------------------------------------------------ r668031 | treat | 2007-05-24 16:51:01 -0400 (Thu, 24 May 2007) | 2 lines * Begin label command test design ------------------------------------------------------------------------ r668024 | treat | 2007-05-24 16:08:02 -0400 (Thu, 24 May 2007) | 2 lines * Move over ------------------------------------------------------------------------ r668023 | treat | 2007-05-24 16:05:44 -0400 (Thu, 24 May 2007) | 2 lines * Stub out items ------------------------------------------------------------------------ r667988 | treat | 2007-05-24 13:33:36 -0400 (Thu, 24 May 2007) | 2 lines * Default to current plotview ------------------------------------------------------------------------ r667984 | treat | 2007-05-24 13:24:58 -0400 (Thu, 24 May 2007) | 2 lines * Deletion order is important ------------------------------------------------------------------------ r667983 | treat | 2007-05-24 13:23:22 -0400 (Thu, 24 May 2007) | 2 lines * Work on command pattern ------------------------------------------------------------------------ r667794 | treat | 2007-05-23 19:40:52 -0400 (Wed, 23 May 2007) | 1 line ------------------------------------------------------------------------ r667792 | treat | 2007-05-23 19:35:21 -0400 (Wed, 23 May 2007) | 2 lines * Some stubbed files ------------------------------------------------------------------------ r667775 | treat | 2007-05-23 18:31:00 -0400 (Wed, 23 May 2007) | 2 lines * More placeholders ------------------------------------------------------------------------ r667753 | treat | 2007-05-23 16:56:07 -0400 (Wed, 23 May 2007) | 2 lines * Placeholder ------------------------------------------------------------------------ r667752 | treat | 2007-05-23 16:54:35 -0400 (Wed, 23 May 2007) | 2 lines * Placeholder ------------------------------------------------------------------------ r667751 | treat | 2007-05-23 16:52:27 -0400 (Wed, 23 May 2007) | 2 lines * Out of the way ------------------------------------------------------------------------ r667749 | treat | 2007-05-23 16:42:45 -0400 (Wed, 23 May 2007) | 2 lines * Move out of the way ------------------------------------------------------------------------ r642908 | treat | 2007-03-15 16:03:08 -0400 (Thu, 15 Mar 2007) | 3 lines * The waitcondition will take care of unlocking for us. ------------------------------------------------------------------------ r642854 | treat | 2007-03-15 12:11:38 -0400 (Thu, 15 Mar 2007) | 2 lines * Fix up connections ------------------------------------------------------------------------ r642848 | treat | 2007-03-15 11:44:34 -0400 (Thu, 15 Mar 2007) | 2 lines * No more crashing on close ------------------------------------------------------------------------ r642840 | treat | 2007-03-15 11:23:50 -0400 (Thu, 15 Mar 2007) | 2 lines * Install some icons ------------------------------------------------------------------------ r642732 | mlaurent | 2007-03-15 05:37:09 -0400 (Thu, 15 Mar 2007) | 2 lines Use cmake variable ------------------------------------------------------------------------ r642653 | treat | 2007-03-14 19:48:45 -0400 (Wed, 14 Mar 2007) | 2 lines * Bring back the actions ------------------------------------------------------------------------ r642635 | treat | 2007-03-14 18:36:18 -0400 (Wed, 14 Mar 2007) | 4 lines * Presenting Kst 1.99 extreme alpha: http://img358.imageshack.us/my.php?image=kst19extremealphano4.png ------------------------------------------------------------------------ r642607 | treat | 2007-03-14 16:35:00 -0400 (Wed, 14 Mar 2007) | 2 lines * This is a dialog ------------------------------------------------------------------------ r642606 | treat | 2007-03-14 16:29:33 -0400 (Wed, 14 Mar 2007) | 2 lines * Make sure to call setupUi ------------------------------------------------------------------------ r642594 | treat | 2007-03-14 15:37:23 -0400 (Wed, 14 Mar 2007) | 4 lines * Another missed export and a little cmake trickery and kst successfully compiles and links. We have an actual executable :) ------------------------------------------------------------------------ r642590 | treat | 2007-03-14 15:16:02 -0400 (Wed, 14 Mar 2007) | 2 lines * Main now compiles. ------------------------------------------------------------------------ r642585 | treat | 2007-03-14 14:55:16 -0400 (Wed, 14 Mar 2007) | 2 lines * libkstapp links! ------------------------------------------------------------------------ r642584 | treat | 2007-03-14 14:54:00 -0400 (Wed, 14 Mar 2007) | 2 lines * export ------------------------------------------------------------------------ r642582 | treat | 2007-03-14 14:43:10 -0400 (Wed, 14 Mar 2007) | 3 lines * Disable the plugindialog and old plugins, fix ui files, and make it compile. ------------------------------------------------------------------------ r642581 | treat | 2007-03-14 14:42:28 -0400 (Wed, 14 Mar 2007) | 2 lines * export ------------------------------------------------------------------------ r642580 | treat | 2007-03-14 14:41:43 -0400 (Wed, 14 Mar 2007) | 2 lines * Export ------------------------------------------------------------------------ r642316 | treat | 2007-03-13 18:58:05 -0400 (Tue, 13 Mar 2007) | 2 lines * Finally, libkstapp compiles. Next up, linking. ------------------------------------------------------------------------ r642224 | treat | 2007-03-13 13:49:00 -0400 (Tue, 13 Mar 2007) | 2 lines * Everything compiles now except kst.cpp... ------------------------------------------------------------------------ r642213 | treat | 2007-03-13 13:02:47 -0400 (Tue, 13 Mar 2007) | 2 lines * More porting ------------------------------------------------------------------------ r641967 | treat | 2007-03-12 19:34:46 -0400 (Mon, 12 Mar 2007) | 2 lines * Closer and closer ------------------------------------------------------------------------ r641949 | treat | 2007-03-12 18:29:19 -0400 (Mon, 12 Mar 2007) | 2 lines * Finally. All dialogs compile. Don't ask me if they work ;) ------------------------------------------------------------------------ r641881 | treat | 2007-03-12 15:58:51 -0400 (Mon, 12 Mar 2007) | 2 lines * More porting ------------------------------------------------------------------------ r641079 | treat | 2007-03-09 18:08:02 -0500 (Fri, 09 Mar 2007) | 2 lines * More port ------------------------------------------------------------------------ r641068 | treat | 2007-03-09 16:35:53 -0500 (Fri, 09 Mar 2007) | 2 lines * More porting ------------------------------------------------------------------------ r640437 | treat | 2007-03-07 20:18:30 -0500 (Wed, 07 Mar 2007) | 2 lines * Some more ------------------------------------------------------------------------ r640414 | treat | 2007-03-07 18:07:48 -0500 (Wed, 07 Mar 2007) | 2 lines * Lots of porting ------------------------------------------------------------------------ r640378 | treat | 2007-03-07 15:22:04 -0500 (Wed, 07 Mar 2007) | 2 lines * More porting ------------------------------------------------------------------------ r640357 | treat | 2007-03-07 13:56:53 -0500 (Wed, 07 Mar 2007) | 2 lines * Correct inheritance structure ------------------------------------------------------------------------ r640351 | treat | 2007-03-07 13:25:30 -0500 (Wed, 07 Mar 2007) | 2 lines * More porting ------------------------------------------------------------------------ r640345 | treat | 2007-03-07 12:53:03 -0500 (Wed, 07 Mar 2007) | 2 lines * Hate how designer handles this ------------------------------------------------------------------------ r639754 | treat | 2007-03-05 17:35:24 -0500 (Mon, 05 Mar 2007) | 7 lines * URL -> Url * Make some of the dialogs actually inherit QDialog * QWidget, QProgressBar, QStatusBar api changes * No more KProgress * QCoreApplication API changes * Begin DCOP -> DBus ------------------------------------------------------------------------ r639727 | treat | 2007-03-05 16:06:16 -0500 (Mon, 05 Mar 2007) | 2 lines * Revert and fix ------------------------------------------------------------------------ r639711 | treat | 2007-03-05 14:57:51 -0500 (Mon, 05 Mar 2007) | 4 lines * QListView -> Q3ListView * Port various props in ui files * fixes ------------------------------------------------------------------------ r639706 | treat | 2007-03-05 14:40:42 -0500 (Mon, 05 Mar 2007) | 5 lines * setRasterOp -> setCompositionMode * eliminate dead headers * KListView* K3ListView * add customwidget tags to *4.ui files that needed it ------------------------------------------------------------------------ r638650 | treat | 2007-03-02 14:50:04 -0500 (Fri, 02 Mar 2007) | 2 lines * Oopsies ------------------------------------------------------------------------ r638647 | treat | 2007-03-02 14:42:04 -0500 (Fri, 02 Mar 2007) | 2 lines * Less ctor params ------------------------------------------------------------------------ r638637 | treat | 2007-03-02 14:19:11 -0500 (Fri, 02 Mar 2007) | 2 lines * Bits ------------------------------------------------------------------------ r638621 | treat | 2007-03-02 13:39:43 -0500 (Fri, 02 Mar 2007) | 4 lines * Missing header * Bunch of QMenu related api changes * kst2dplot now compiles excepting the KMdi mess... woohoo! ------------------------------------------------------------------------ r638614 | treat | 2007-03-02 12:56:20 -0500 (Fri, 02 Mar 2007) | 2 lines * QWheelEvent no longer supplies keyboard modifier info either ------------------------------------------------------------------------ r638612 | treat | 2007-03-02 12:51:25 -0500 (Fri, 02 Mar 2007) | 2 lines * Some updates ------------------------------------------------------------------------ r638611 | treat | 2007-03-02 12:49:41 -0500 (Fri, 02 Mar 2007) | 4 lines * QMouseEvent doesn't deliver information on keyboard modifiers anymore. Not sure how to easily port so just comment out and note in PORTINGTODO. ------------------------------------------------------------------------ r638610 | treat | 2007-03-02 12:43:14 -0500 (Fri, 02 Mar 2007) | 3 lines * i18n changes * QPainter::drawWinFocusRect is no more... ------------------------------------------------------------------------ r638604 | treat | 2007-03-02 11:55:43 -0500 (Fri, 02 Mar 2007) | 5 lines * No more QPixmap::resize() * QStringList::findIndex - QStringList::indexOf * No more CoordinateMode * QClipboard->set*Mime*Data ------------------------------------------------------------------------ r638602 | treat | 2007-03-02 11:37:15 -0500 (Fri, 02 Mar 2007) | 6 lines * RasterOp -> CompositionMode CopyROP = CompositionMode_Source XorROP = CompositionMode_Xor NotROP = CompositionMode_Destination SetROP = CompositionMode_Source ------------------------------------------------------------------------ r638432 | treat | 2007-03-01 18:01:17 -0500 (Thu, 01 Mar 2007) | 2 lines * Various bits ------------------------------------------------------------------------ r638429 | treat | 2007-03-01 17:50:21 -0500 (Thu, 01 Mar 2007) | 2 lines * QRect and QString api changes ------------------------------------------------------------------------ r638422 | treat | 2007-03-01 17:31:57 -0500 (Thu, 01 Mar 2007) | 2 lines * KPopupMenu is no longer ------------------------------------------------------------------------ r638421 | treat | 2007-03-01 17:30:01 -0500 (Thu, 01 Mar 2007) | 2 lines * ascii -> toAscii, QList api bit, stuff ------------------------------------------------------------------------ r638415 | treat | 2007-03-01 17:06:20 -0500 (Thu, 01 Mar 2007) | 3 lines * KFontCombo -> QFontComboBox * KDualColorButton is no longer... ------------------------------------------------------------------------ r638414 | treat | 2007-03-01 16:51:49 -0500 (Thu, 01 Mar 2007) | 2 lines * KService changes ------------------------------------------------------------------------ r638398 | treat | 2007-03-01 15:20:58 -0500 (Thu, 01 Mar 2007) | 2 lines QMap::Iterator data -> value ------------------------------------------------------------------------ r638383 | treat | 2007-03-01 14:32:51 -0500 (Thu, 01 Mar 2007) | 4 lines * Remove needless include * ksdebug -> qdebug * KConfig ctor fixes ------------------------------------------------------------------------ r638382 | treat | 2007-03-01 14:24:33 -0500 (Thu, 01 Mar 2007) | 3 lines * Fix header, fix QByteArray bits, fix Q_EXPORT -> Q_CORE_EXPORT and use a typedef to temporarily get away from KMdi ------------------------------------------------------------------------ r638380 | treat | 2007-03-01 14:01:56 -0500 (Thu, 01 Mar 2007) | 3 lines * Q3GridLayout -> QGridLayout... ------------------------------------------------------------------------ r638371 | treat | 2007-03-01 13:42:42 -0500 (Thu, 01 Mar 2007) | 3 lines * QStringList::split -> QString::split * Q3TextStream -> QTextStream ------------------------------------------------------------------------ r638370 | treat | 2007-03-01 13:33:55 -0500 (Thu, 01 Mar 2007) | 2 lines * Missed these latin1 -> toLatin1 ------------------------------------------------------------------------ r638366 | treat | 2007-03-01 13:22:49 -0500 (Thu, 01 Mar 2007) | 2 lines * kMin/kMax -> qMin/qMax ------------------------------------------------------------------------ r638361 | treat | 2007-03-01 13:04:32 -0500 (Thu, 01 Mar 2007) | 3 lines * Move a bunch of decl/impl from ui files to actual files now that ui files no longer support them. ------------------------------------------------------------------------ r638190 | treat | 2007-02-28 21:26:45 -0500 (Wed, 28 Feb 2007) | 2 lines * Some easy stuff like latin1 - toLatin1 etc,... ------------------------------------------------------------------------ r638188 | treat | 2007-02-28 21:01:31 -0500 (Wed, 28 Feb 2007) | 2 lines * The ui files seem to be ok now ------------------------------------------------------------------------ r638181 | treat | 2007-02-28 19:56:41 -0500 (Wed, 28 Feb 2007) | 3 lines * Q3ButtonGroup is incompatible with QGridLayout and besides it can be safely replaced with QGroupBox in Qt4 ------------------------------------------------------------------------ r638177 | treat | 2007-02-28 19:45:47 -0500 (Wed, 28 Feb 2007) | 4 lines * Mostly porting of various problems in ui files KURLRequester -> KUrlRequester for instance. * Also cleanup includes in ui files. ------------------------------------------------------------------------ r638174 | treat | 2007-02-28 19:39:36 -0500 (Wed, 28 Feb 2007) | 2 lines * Argh, designer now wants all classes to match file names... ------------------------------------------------------------------------ r638171 | treat | 2007-02-28 19:32:37 -0500 (Wed, 28 Feb 2007) | 2 lines * Rename as other ui files are choking on it ------------------------------------------------------------------------ r638167 | treat | 2007-02-28 19:18:23 -0500 (Wed, 28 Feb 2007) | 3 lines * Clean up the ui files by eliminating unnecessary includes. ------------------------------------------------------------------------ r638146 | treat | 2007-02-28 18:34:13 -0500 (Wed, 28 Feb 2007) | 2 lines * New names ------------------------------------------------------------------------ r638144 | treat | 2007-02-28 18:22:53 -0500 (Wed, 28 Feb 2007) | 3 lines * Missed some converted ui files apparently. * Clean up the cmake list so I can see where things are. ------------------------------------------------------------------------ r638140 | treat | 2007-02-28 18:00:30 -0500 (Wed, 28 Feb 2007) | 7 lines * Tons of stuff going on here. I've run uic3 convert on remaining ui files and renamed them along with their implementation files to better keep track of them. I've run qt3to4 convert on all of the subsequent .cpp and .h files. Here we go... ------------------------------------------------------------------------ r638106 | treat | 2007-02-28 16:07:19 -0500 (Wed, 28 Feb 2007) | 29 lines * Begin port of libkstapp to Qt4. Starting with some ui file conversion and ui.h file conversion. uic3 -convert vectorsavedialog.ui > vectorsavedialog4.ui uic3: flag 'WordBreak' for widget 'QLabel' is not supported uic3 -convert kstsettingsdlg.ui > kstsettingsdlg4.ui uic3: slot `sourceChanged(QString)' for widget `KstSettingsDlg' of type `QDialog' is not supported; connection may fail. Line: 1332 Column: 16 uic3: slot `updateTimezone(double)' for widget `KstSettingsDlg' of type `QDialog' is not supported; connection may fail. Line: 1476 Column: 16 uic3 -convert viewlegendwidget.ui > viewlegendwidget4.ui uic3 -convert pluginmanager.ui > pluginmanager4.uiuic3: slot `selectionChanged(Q3ListViewItem*)' for widget `PluginManager' of type `QDialog' is not supported; connection may fail. Line: 173 Column: 16 uic3 -convert datasourcemetadatadialog.ui > datasourcemetadatadialog4.ui uic3: slot `updateMetadata(QString)' for widget `DataSourceMetaDataDialog' of type `QDialog' is not supported; connection may fail. Line: 114 Column: 16 uic3 -convert datawizard.ui > datawizard4.ui uic3: flag 'WordBreak' for widget 'QLabel' is not supported uic3: property `hidden' for widget `_testURL' of type `QPushButton' is not supported. Line: 167 Column: 48 uic3: property `margin' for widget `buttonGroup1' of type `Q3ButtonGroup' is not supported. Line: 980 Column: 60 uic3: enumerator 'NoFrame' for widget 'Q3ButtonGroup' is not supported uic3 -convert viewlabelwidget.ui > viewlabelwidget4.ui uic3 -convert extensiondlg.ui > extensiondlg4.ui uic3 -convert view2dplotwidget.ui > view2dplotwidget4.ui uic3 -convert debugdialog.ui > debugdialog4.ui uic3 -convert kstdatadialog.ui > kstdatadialog4.ui ------------------------------------------------------------------------ r638063 | treat | 2007-02-28 13:16:15 -0500 (Wed, 28 Feb 2007) | 4 lines * All widgets display in designer now although not all correctly. Missing pixmaps and some of the ui file conversions were less than perfect. ------------------------------------------------------------------------ r638039 | treat | 2007-02-28 11:59:15 -0500 (Wed, 28 Feb 2007) | 5 lines * Do the rest of the widget plugins for designer. Some crash designer as they still require bits from Kst libs which require bits from KDE libs and therefore should be KComponentData'ized. Or something. ------------------------------------------------------------------------ r638026 | pino | 2007-02-28 10:51:41 -0500 (Wed, 28 Feb 2007) | 2 lines QT -> Qt ------------------------------------------------------------------------ r637935 | mlaurent | 2007-02-28 03:00:02 -0500 (Wed, 28 Feb 2007) | 2 lines applnk dir is dead with kde4 ------------------------------------------------------------------------ r637889 | staikos | 2007-02-27 21:40:12 -0500 (Tue, 27 Feb 2007) | 2 lines make some of these tests pass ------------------------------------------------------------------------ r637888 | staikos | 2007-02-27 21:39:56 -0500 (Tue, 27 Feb 2007) | 2 lines i18n fix ------------------------------------------------------------------------ r637887 | staikos | 2007-02-27 21:39:33 -0500 (Tue, 27 Feb 2007) | 2 lines some KDE4 fixes, especially i18n related ------------------------------------------------------------------------ r637876 | treat | 2007-02-27 20:28:52 -0500 (Tue, 27 Feb 2007) | 2 lines * Make this a little easier. Rest of plugins to follow ------------------------------------------------------------------------ r637867 | treat | 2007-02-27 19:50:05 -0500 (Tue, 27 Feb 2007) | 3 lines * All of widgets now builds and links. Still some work converting from Q3Support though ------------------------------------------------------------------------ r637861 | treat | 2007-02-27 19:20:55 -0500 (Tue, 27 Feb 2007) | 3 lines * And the various selectors build now too. I renamed a class to make it more consistent. ------------------------------------------------------------------------ r637845 | treat | 2007-02-27 18:20:03 -0500 (Tue, 27 Feb 2007) | 4 lines * Large part of the port of widgets is done. I still have some more to go, but this eliminates a lot of old cruft and gets the designer files working with Qt4. ------------------------------------------------------------------------ r637799 | treat | 2007-02-27 16:03:49 -0500 (Tue, 27 Feb 2007) | 4 lines * Convert all .ui.h extension files into actual declarations and definitions. Clean up the source, add licenses and reformat. ------------------------------------------------------------------------ r637783 | treat | 2007-02-27 14:50:12 -0500 (Tue, 27 Feb 2007) | 3 lines * Begin port of widgets. The curve appearance widget is now a Qt4 widget with a designer2 plugin. ------------------------------------------------------------------------ r637782 | treat | 2007-02-27 14:47:16 -0500 (Tue, 27 Feb 2007) | 2 lines * No longer ------------------------------------------------------------------------ r637739 | treat | 2007-02-27 11:05:14 -0500 (Tue, 27 Feb 2007) | 2 lines * oops ------------------------------------------------------------------------ r637738 | treat | 2007-02-27 11:04:42 -0500 (Tue, 27 Feb 2007) | 2 lines * Convert all of the .cpp and .h files using qt3to4 ------------------------------------------------------------------------ r637736 | treat | 2007-02-27 11:01:00 -0500 (Tue, 27 Feb 2007) | 2 lines * Convert all ui.h files using qt3to4 ------------------------------------------------------------------------ r637621 | staikos | 2007-02-26 23:35:09 -0500 (Mon, 26 Feb 2007) | 2 lines more porting done ------------------------------------------------------------------------ r636983 | staikos | 2007-02-24 17:32:29 -0500 (Sat, 24 Feb 2007) | 9 lines This removes all Qt3compat from libkst, libkstmath, tests, most of the data sources. It fixes several bugs and gets a good portion of the testcases working again. It also starts switching over to KDE4 and Qt4 proper ways of doing things, and removes all deprecated calls. d2asc and d2d are also ported. ------------------------------------------------------------------------ r636397 | treat | 2007-02-22 18:58:58 -0500 (Thu, 22 Feb 2007) | 24 lines * Convert all the ui files to Qt Designer 4 counterparts: uic3 -convert comboboxselection.ui > comboboxselection4.ui uic3 -convert stringeditor.ui > stringeditor4.ui uic3 -convert scalareditor.ui > scalareditor4.ui uic3 -convert scalarselector.ui > scalarselector4.ui uic3 -convert matrixselector.ui > matrixselector4.ui uic3: signal `selectionChanged(QString)' for widget `MatrixSelector' of type `QWidget' is not supported; connection may fail. Line: 74 Column: 16 uic3 -convert vectorselector.ui > vectorselector4.ui uic3: signal `selectionChanged(QString)' for widget `VectorSelector' of type `QWidget' is not supported; connection may fail. Line: 92 Column: 16 uic3 -convert stringselector.ui > stringselector4.ui uic3 -convert editmultiplewidget.ui > editmultiplewidget4.ui uic3: slot `applyFilter(QString)' for widget `EditMultipleWidget' of type `QWidget' is not supported; connection may fail. Line: 139 Column: 16 uic3 -convert curveplacementwidget.ui > curveplacementwidget4.ui uic3 -convert curveappearancewidget.ui > curveappearancewidget4.ui uic3 -convert fftoptionswidget.ui > fftoptionswidget4.ui uic3 -convert datarangewidget.ui > datarangewidget4.ui uic3 -convert colorpalettewidget.ui > colorpalettewidget4.ui uic3: slot `updatePalette(QString)' for widget `ColorPaletteWidget' of type `QWidget' is not supported; connection may fail. Line: 76 Column: 16 uic3: slot `updatePalette(QString)' for widget `ColorPaletteWidget' of type `QWidget' is not supported; connection may fail. Line: 82 Column: 16 ------------------------------------------------------------------------ r636394 | treat | 2007-02-22 18:47:56 -0500 (Thu, 22 Feb 2007) | 2 lines * No longer in QPixmap api ------------------------------------------------------------------------ r636393 | treat | 2007-02-22 18:43:15 -0500 (Thu, 22 Feb 2007) | 2 lines * Get ready for widgets ------------------------------------------------------------------------ r636388 | staikos | 2007-02-22 18:04:04 -0500 (Thu, 22 Feb 2007) | 2 lines a bit of work done on indirect and comment out uncompilable sources for now ------------------------------------------------------------------------ r636385 | treat | 2007-02-22 17:59:32 -0500 (Thu, 22 Feb 2007) | 2 lines * Comment out for now ------------------------------------------------------------------------ r636381 | staikos | 2007-02-22 17:56:45 -0500 (Thu, 22 Feb 2007) | 2 lines qimagesource is ported and at least one bug is fixed. Will forward port ------------------------------------------------------------------------ r636379 | treat | 2007-02-22 17:55:16 -0500 (Thu, 22 Feb 2007) | 2 lines * Oops ------------------------------------------------------------------------ r636378 | staikos | 2007-02-22 17:50:59 -0500 (Thu, 22 Feb 2007) | 2 lines remove junk ------------------------------------------------------------------------ r636377 | staikos | 2007-02-22 17:50:44 -0500 (Thu, 22 Feb 2007) | 2 lines Frame is ported ------------------------------------------------------------------------ r636376 | staikos | 2007-02-22 17:49:37 -0500 (Thu, 22 Feb 2007) | 2 lines dirfile is ported ------------------------------------------------------------------------ r636374 | treat | 2007-02-22 17:45:28 -0500 (Thu, 22 Feb 2007) | 2 lines * SVN INFO for kstrevision.h ------------------------------------------------------------------------ r636372 | staikos | 2007-02-22 17:42:13 -0500 (Thu, 22 Feb 2007) | 2 lines go away ------------------------------------------------------------------------ r636371 | staikos | 2007-02-22 17:39:13 -0500 (Thu, 22 Feb 2007) | 2 lines most of ascii is ported but it still doesn't build ------------------------------------------------------------------------ r636367 | staikos | 2007-02-22 17:18:30 -0500 (Thu, 22 Feb 2007) | 2 lines correct data type ------------------------------------------------------------------------ r636295 | staikos | 2007-02-22 14:03:08 -0500 (Thu, 22 Feb 2007) | 2 lines More porting work ------------------------------------------------------------------------ r635810 | staikos | 2007-02-20 18:35:34 -0500 (Tue, 20 Feb 2007) | 2 lines definitely obsolete ------------------------------------------------------------------------ r635809 | staikos | 2007-02-20 18:33:26 -0500 (Tue, 20 Feb 2007) | 2 lines these don't apply anymore ------------------------------------------------------------------------ r635808 | staikos | 2007-02-20 18:32:04 -0500 (Tue, 20 Feb 2007) | 2 lines one thing's for sure: this isn't going to work in Kst2 ------------------------------------------------------------------------ r635806 | staikos | 2007-02-20 18:31:31 -0500 (Tue, 20 Feb 2007) | 2 lines a few more obsolete docs from this view ------------------------------------------------------------------------ r635805 | staikos | 2007-02-20 18:30:36 -0500 (Tue, 20 Feb 2007) | 2 lines remove some irrlevant things for the branch to clean up ------------------------------------------------------------------------ r635757 | treat | 2007-02-20 15:34:56 -0500 (Tue, 20 Feb 2007) | 2 lines * Compile libkstmath, but no linky yet ------------------------------------------------------------------------ r635754 | treat | 2007-02-20 15:33:20 -0500 (Tue, 20 Feb 2007) | 2 lines * Change QDir calls ------------------------------------------------------------------------ r635750 | treat | 2007-02-20 15:23:41 -0500 (Tue, 20 Feb 2007) | 2 lines * No more names in ctor for qobject ------------------------------------------------------------------------ r635731 | treat | 2007-02-20 14:11:11 -0500 (Tue, 20 Feb 2007) | 2 lines * search -> indexIn ------------------------------------------------------------------------ r635730 | treat | 2007-02-20 14:09:43 -0500 (Tue, 20 Feb 2007) | 2 lines * Using qDebug now ------------------------------------------------------------------------ r635728 | treat | 2007-02-20 14:02:15 -0500 (Tue, 20 Feb 2007) | 2 lines * Various QString api changes ------------------------------------------------------------------------ r635725 | treat | 2007-02-20 13:56:26 -0500 (Tue, 20 Feb 2007) | 2 lines * latin1 -> toLatin1 and erase -> remove ------------------------------------------------------------------------ r635724 | treat | 2007-02-20 13:55:25 -0500 (Tue, 20 Feb 2007) | 2 lines * i18n call changes ------------------------------------------------------------------------ r635722 | treat | 2007-02-20 13:53:53 -0500 (Tue, 20 Feb 2007) | 2 lines * RGB32 ------------------------------------------------------------------------ r635720 | treat | 2007-02-20 13:51:37 -0500 (Tue, 20 Feb 2007) | 2 lines * New QPainter semantics for drawing a polygon ------------------------------------------------------------------------ r635714 | treat | 2007-02-20 13:40:23 -0500 (Tue, 20 Feb 2007) | 2 lines * kMax to qMax ------------------------------------------------------------------------ r635713 | treat | 2007-02-20 13:39:27 -0500 (Tue, 20 Feb 2007) | 2 lines * QBrushStyle is global to Qt ------------------------------------------------------------------------ r635708 | treat | 2007-02-20 13:36:58 -0500 (Tue, 20 Feb 2007) | 2 lines * erase -> remove ------------------------------------------------------------------------ r635707 | treat | 2007-02-20 13:36:31 -0500 (Tue, 20 Feb 2007) | 3 lines * qSort algorithm is having problems with Q3ValueList Comment out and note in PORTINGTODO so it isn't lost. ------------------------------------------------------------------------ r635698 | treat | 2007-02-20 13:16:09 -0500 (Tue, 20 Feb 2007) | 3 lines * Typo, KService changes, Q3ValueList semantic problems in KstObjectCollection::findTag ------------------------------------------------------------------------ r634344 | treat | 2007-02-16 17:50:35 -0500 (Fri, 16 Feb 2007) | 2 lines * Should be index() as per george ------------------------------------------------------------------------ r634343 | treat | 2007-02-16 17:27:45 -0500 (Fri, 16 Feb 2007) | 3 lines * Need to find the generated ksttimers.h include... ------------------------------------------------------------------------ r634342 | treat | 2007-02-16 17:24:47 -0500 (Fri, 16 Feb 2007) | 2 lines * QString api has changed ------------------------------------------------------------------------ r634341 | treat | 2007-02-16 17:20:01 -0500 (Fri, 16 Feb 2007) | 2 lines * Missing header ------------------------------------------------------------------------ r634340 | treat | 2007-02-16 17:19:17 -0500 (Fri, 16 Feb 2007) | 2 lines * KConfig isn't so lenient now ------------------------------------------------------------------------ r634339 | treat | 2007-02-16 17:10:05 -0500 (Fri, 16 Feb 2007) | 2 lines * Compile ------------------------------------------------------------------------ r634338 | treat | 2007-02-16 17:07:47 -0500 (Fri, 16 Feb 2007) | 2 lines * Only use qdebug ------------------------------------------------------------------------ r634337 | treat | 2007-02-16 17:06:56 -0500 (Fri, 16 Feb 2007) | 2 lines * KService changes ------------------------------------------------------------------------ r634336 | treat | 2007-02-16 17:04:49 -0500 (Fri, 16 Feb 2007) | 2 lines * Using qDebug now... ------------------------------------------------------------------------ r634335 | treat | 2007-02-16 17:03:42 -0500 (Fri, 16 Feb 2007) | 2 lines * stripWhiteSpace -> trimmed ------------------------------------------------------------------------ r634313 | treat | 2007-02-16 16:02:05 -0500 (Fri, 16 Feb 2007) | 2 lines * QMap::Iterator data() -> value() ------------------------------------------------------------------------ r634309 | treat | 2007-02-16 15:52:38 -0500 (Fri, 16 Feb 2007) | 2 lines * Missing header ------------------------------------------------------------------------ r634308 | treat | 2007-02-16 15:51:30 -0500 (Fri, 16 Feb 2007) | 2 lines * Q3TextStream -> QTextStream ------------------------------------------------------------------------ r634306 | treat | 2007-02-16 15:44:58 -0500 (Fri, 16 Feb 2007) | 2 lines * Get include path right ------------------------------------------------------------------------ r634305 | treat | 2007-02-16 15:41:41 -0500 (Fri, 16 Feb 2007) | 3 lines * Running qt3to4 porting tool on files in libkstmath and adding the porting log ------------------------------------------------------------------------ r634302 | treat | 2007-02-16 15:34:39 -0500 (Fri, 16 Feb 2007) | 2 lines * Prepare to port libkstmath next ------------------------------------------------------------------------ r634284 | treat | 2007-02-16 14:51:33 -0500 (Fri, 16 Feb 2007) | 2 lines * Additional notes ------------------------------------------------------------------------ r634281 | treat | 2007-02-16 14:40:13 -0500 (Fri, 16 Feb 2007) | 6 lines * Clean-up formatting of cmake files * Get rid of ksdebug in favor of qDebug which is threadsafe * Link with kde3support for now And with that libkst can compile and link against KDE4 and Qt4 :) ------------------------------------------------------------------------ r634276 | treat | 2007-02-16 14:19:12 -0500 (Fri, 16 Feb 2007) | 2 lines * Use KToolInvocation and changes for i18n calls ------------------------------------------------------------------------ r634272 | treat | 2007-02-16 14:12:08 -0500 (Fri, 16 Feb 2007) | 2 lines * Define correct versioning in top-level cmake file ------------------------------------------------------------------------ r634245 | treat | 2007-02-16 12:42:32 -0500 (Fri, 16 Feb 2007) | 3 lines * Just comment out the references to the private d-pointer for now * This class will go away in favor of QWaitCondition in Qt4 anyway... ------------------------------------------------------------------------ r634244 | treat | 2007-02-16 12:40:47 -0500 (Fri, 16 Feb 2007) | 3 lines * Add a special header for revision information. The logger uses this. ------------------------------------------------------------------------ r634005 | treat | 2007-02-15 19:44:21 -0500 (Thu, 15 Feb 2007) | 2 lines * Update ------------------------------------------------------------------------ r634003 | treat | 2007-02-15 19:43:08 -0500 (Thu, 15 Feb 2007) | 3 lines * Small fixes. Not sure what to do about private qmutex header... ------------------------------------------------------------------------ r633997 | treat | 2007-02-15 19:05:59 -0500 (Thu, 15 Feb 2007) | 2 lines * Q3TextStream -> QTextStream ------------------------------------------------------------------------ r633995 | treat | 2007-02-15 18:47:12 -0500 (Thu, 15 Feb 2007) | 2 lines * Port ksttimezones to 4 ------------------------------------------------------------------------ r633987 | treat | 2007-02-15 18:28:43 -0500 (Thu, 15 Feb 2007) | 2 lines * Configure check and define ------------------------------------------------------------------------ r633983 | treat | 2007-02-15 18:13:06 -0500 (Thu, 15 Feb 2007) | 2 lines * Quick stuff for extdate/QDate fix ------------------------------------------------------------------------ r633982 | treat | 2007-02-15 18:09:02 -0500 (Thu, 15 Feb 2007) | 2 lines * Add a file to track todo items relating to the port ------------------------------------------------------------------------ r633979 | treat | 2007-02-15 18:02:29 -0500 (Thu, 15 Feb 2007) | 2 lines * QThread::currentThread -> QThread::currentThreadId ------------------------------------------------------------------------ r633974 | treat | 2007-02-15 17:45:00 -0500 (Thu, 15 Feb 2007) | 2 lines * QString::stripWhiteSpace -> QString::trimmed ------------------------------------------------------------------------ r633973 | treat | 2007-02-15 17:42:10 -0500 (Thu, 15 Feb 2007) | 3 lines * porting fixes for kstextension ------------------------------------------------------------------------ r633971 | treat | 2007-02-15 17:37:15 -0500 (Thu, 15 Feb 2007) | 2 lines * Use K3TempFile for now... ------------------------------------------------------------------------ r633969 | treat | 2007-02-15 17:26:33 -0500 (Thu, 15 Feb 2007) | 2 lines * Fix some qalgorithms ------------------------------------------------------------------------ r633968 | treat | 2007-02-15 17:17:35 -0500 (Thu, 15 Feb 2007) | 2 lines * KServiceType::offers() -> KServiceTypeTrader::self()->query() ------------------------------------------------------------------------ r633966 | treat | 2007-02-15 17:05:55 -0500 (Thu, 15 Feb 2007) | 2 lines * fix ------------------------------------------------------------------------ r633964 | treat | 2007-02-15 17:04:03 -0500 (Thu, 15 Feb 2007) | 2 lines * KURL -> KUrl ------------------------------------------------------------------------ r633958 | treat | 2007-02-15 16:49:56 -0500 (Thu, 15 Feb 2007) | 2 lines * Fix for QMaps ------------------------------------------------------------------------ r633943 | treat | 2007-02-15 15:20:43 -0500 (Thu, 15 Feb 2007) | 2 lines * Compile ------------------------------------------------------------------------ r633939 | treat | 2007-02-15 15:14:02 -0500 (Thu, 15 Feb 2007) | 5 lines * Missing header TODO: This plugin manager should be replaced with Qt plugin system? ------------------------------------------------------------------------ r633935 | treat | 2007-02-15 14:55:00 -0500 (Thu, 15 Feb 2007) | 2 lines * QString::findRev --> QString::lastIndexOf ------------------------------------------------------------------------ r633934 | treat | 2007-02-15 14:53:27 -0500 (Thu, 15 Feb 2007) | 2 lines * Use QDateTime for now ------------------------------------------------------------------------ r633930 | treat | 2007-02-15 14:47:50 -0500 (Thu, 15 Feb 2007) | 2 lines * Port ------------------------------------------------------------------------ r633926 | treat | 2007-02-15 14:40:38 -0500 (Thu, 15 Feb 2007) | 2 lines * QStringList::split() to QString::split() ------------------------------------------------------------------------ r633925 | treat | 2007-02-15 14:38:21 -0500 (Thu, 15 Feb 2007) | 2 lines * Need this define ------------------------------------------------------------------------ r633924 | treat | 2007-02-15 14:37:28 -0500 (Thu, 15 Feb 2007) | 3 lines * Initial run of qt3to4 porting script on libkst. The changes are logged in portinglog.txt. ------------------------------------------------------------------------ r633921 | treat | 2007-02-15 14:29:40 -0500 (Thu, 15 Feb 2007) | 3 lines * Add placeholder for config checks, create ksttimers.h properly, misc cmake build stuff ------------------------------------------------------------------------ r633802 | mlaurent | 2007-02-15 07:08:48 -0500 (Thu, 15 Feb 2007) | 2 lines ${KDE4_KIO_LIBS} already contains -lkdecore ------------------------------------------------------------------------ r633710 | treat | 2007-02-14 18:03:28 -0500 (Wed, 14 Feb 2007) | 2 lines * New plan. Porting of libkst goes first. Scratch extdate for now. ------------------------------------------------------------------------ r633705 | treat | 2007-02-14 16:58:13 -0500 (Wed, 14 Feb 2007) | 3 lines * Disable compilation of all besides libkstmath for now. * Require the KDE4 package for now. ------------------------------------------------------------------------ r633701 | treat | 2007-02-14 16:53:07 -0500 (Wed, 14 Feb 2007) | 2 lines * Disable misc, tests and plugins from build for now ------------------------------------------------------------------------ r633700 | treat | 2007-02-14 16:49:51 -0500 (Wed, 14 Feb 2007) | 4 lines * Add various CMakeLists.txt created by running the am2cmake script found in kdesdk/cmake in KDE svn. ------------------------------------------------------------------------ r633672 | treat | 2007-02-14 14:20:20 -0500 (Wed, 14 Feb 2007) | 2 lines * Open branch beginning work on porting kst to KDE/Qt4 kst-2.0.3/tests/dirfile_testcase/15count/ssine000644 001750 001750 00000000104 11544160206 021700 0ustar00synthsynth000000 000000 Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?kst-2.0.3/tests/dirfile_testcase/15count/format000644 001750 001750 00000000110 11544160206 022044 0ustar00synthsynth000000 000000 scount RAW f 1 fcount RAW f 20 sine RAW f 20 ssine RAW f 1 cos RAW f 20 kst-2.0.3/tests/dirfile_testcase/15count/fcount000644 001750 001750 00000002520 11544160206 022061 0ustar00synthsynth000000 000000 ?@@@@@@@AA A0A@APA`ApAAAAAAAAAAAAAAAAABBB BBBBB B$B(B,B0B4B8BC?C@CACBCCCDCECFCGCHCICJCKCLCMCNCOCPCQCRCSCTCUCVCWCXCYCZC[C\C]C^C_C`CaCbCcCdCeCfCgChCiCjCkClCmCnCoCpCqCrCsCtCuCvCwCxCyCzC{C|C}C~CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCkst-2.0.3/tests/dirfile_testcase/15count/scount000644 001750 001750 00000000104 11544160206 022072 0ustar00synthsynth000000 000000 ?@@@@@@@AA A0A@APA`ApAAkst-2.0.3/tests/dirfile_testcase/15count/sine000644 001750 001750 00000002520 11544160206 021521 0ustar00synthsynth000000 000000 Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=0 %Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQ0Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=%Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQ0 Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=|0&Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQSQ=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?kst-2.0.3/tests/dirfile_testcase/15count/cos000644 001750 001750 00000002520 11544160206 021347 0ustar00synthsynth000000 000000 ?~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=0$Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQSQ=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=|%Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQQ=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=&Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQ0Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=IQ[W?~z7zپk+ y8.#{>/:[@Ekst-2.0.3/tests/testcsd.cpp000644 001750 001750 00000020224 11544160206 016207 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testcsd.h" #include #include #include #include #include #include #include #include static Kst::ObjectStore _store; void TestCSD::cleanupTestCase() { _store.clear(); } QDomDocument TestCSD::makeDOMElement(const QString& tag, const QString& val) { // Should be some boundary checking in the constructor. QDomDocument csdDOM("csddocument"); QDomElement csdElement, child; QDomText text; csdElement = csdDOM.createElement("csdDOMTest"); child = csdDOM.createElement("tag"); text = csdDOM.createTextNode(tag); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("vector"); text = csdDOM.createTextNode(val); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("samplerate"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("average"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("fftlength"); text = csdDOM.createTextNode("5"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("apodize"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("apodizefunction"); text = csdDOM.createTextNode("WindowOriginal"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("gaussiansigma"); text = csdDOM.createTextNode("0.01"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("removemean"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("windowsize"); text = csdDOM.createTextNode("5000"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("vectorunits"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("rateunits"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("outputtype"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); csdDOM.appendChild(csdElement); return csdDOM; } void TestCSD::testCSD() { Kst::VectorPtr vp = Kst::kst_cast(_store.createObject()); Q_ASSERT(vp); vp->resize(10); vp->setDescriptiveName("tempVector"); for (int i = 0; i < 10; i++){ vp->value()[i] = i; } Kst::CSDPtr csd = Kst::kst_cast(_store.createObject()); csd->change(vp, 1.0, false, false, false, WindowUndefined, 0, 0, 0.0, PSDUndefined, QString::null, QString::null); QCOMPARE(csd->vector()->descriptiveName(), QLatin1String("tempVector")); QCOMPARE(csd->output(), PSDUndefined); QVERIFY(!csd->apodize()); QVERIFY(!csd->removeMean()); QVERIFY(!csd->average()); QCOMPARE(csd->frequency(), 1.0); QCOMPARE(csd->apodizeFxn(), WindowUndefined); QCOMPARE(csd->length(), 0); QCOMPARE(csd->windowSize(), 0); QCOMPARE(csd->gaussianSigma(), 0.0); QVERIFY(csd->vectorUnits().isEmpty()); QVERIFY(csd->rateUnits().isEmpty()); csd->setOutput(PSDAmplitudeSpectralDensity); csd->setApodize(true); csd->setRemoveMean(true); csd->setAverage(true); csd->setFrequency(0.1); csd->setApodizeFxn(WindowOriginal); csd->setLength(3); csd->setWindowSize(50); csd->setGaussianSigma(0.2); QCOMPARE(csd->vector()->descriptiveName(), QLatin1String("tempVector")); QCOMPARE(csd->output(), PSDAmplitudeSpectralDensity); QVERIFY(csd->apodize()); QVERIFY(csd->removeMean()); QVERIFY(csd->average()); QCOMPARE(csd->frequency(), 0.1); QCOMPARE(csd->windowSize(), 50); QCOMPARE(csd->apodizeFxn(), WindowOriginal); QCOMPARE(csd->gaussianSigma(), 0.2); // KTempFile tf(locateLocal("tmp", "kst-csd"), "txt"); // QFile *qf = tf.file(); // QTextStream ts(qf); // csd->save(ts, ""); // the constructor used here is no longer used in kst: use the factory instead // QDomNode n = makeDOMElement("csdDOMCsd", "csdDOMVector").firstChild(); // QDomElement e = n.toElement(); // Kst::CSDPtr csdDOM = new Kst::CSD(&_store, e); // // QCOMPARE(csdDOM->output(), PSDPowerSpectralDensity); // QVERIFY(csdDOM->apodize()); // QVERIFY(csdDOM->removeMean()); // QVERIFY(csdDOM->average()); // QCOMPARE(csdDOM->frequency(), 1.0); // QCOMPARE(csdDOM->apodizeFxn(), WindowOriginal); // QCOMPARE(csdDOM->gaussianSigma(), 0.01); // QCOMPARE(csdDOM->windowSize(), 5000); // Kst::VectorPtr vp2 = Kst::kst_cast(_store.createObject()); // Q_ASSERT(vp2); // vp2->resize(10); // for (int i = 0; i < 10; i++){ // vp2->value()[i] = i; // } // csdDOM->setVector(vp2); // QCOMPARE(csdDOM->vector()->descriptiveName(), QLatin1String("tempVector2")); // csdDOM->setWindowSize(9); // Kst::MatrixPtr outMatrix = csdDOM->outputMatrix(); // // QVERIFY(outMatrix->resize(3, 3, false)); // very odd thing to do? // QVERIFY(outMatrix->setValue(0, 0, 1.716299)); // QVERIFY(outMatrix->setValue(0, 1, -0.485527)); // QVERIFY(outMatrix->setValue(0, 2, -0.288690)); // QVERIFY(outMatrix->setValue(1, 0, 1.716299)); // QVERIFY(outMatrix->setValue(1, 1, NAN)); // QVERIFY(outMatrix->setValue(1, 2, -0.274957)); // QVERIFY(outMatrix->setValue(2, 0, 1.711721)); // QVERIFY(outMatrix->setValue(2, 1, -0.485527)); // QVERIFY(outMatrix->setValue(2, 2, -0.293267)); // // QCOMPARE(outMatrix->sampleCount(), 9); // QCOMPARE(outMatrix->value(0, 0), 1.716299); // QCOMPARE(outMatrix->value(0, 1), -0.485527); // QCOMPARE(outMatrix->value(0, 2), -0.288690); // QCOMPARE(outMatrix->value(1, 0), 1.716299); // QCOMPARE(outMatrix->value(1, 1), 0.0); // QCOMPARE(outMatrix->value(1, 2), -0.274957); // QCOMPARE(outMatrix->value(2, 0), 1.711721); // QCOMPARE(outMatrix->value(2, 1), -0.485527); // QCOMPARE(outMatrix->value(2, 2), -0.293267); // // csdDOM->writeLock(); // QCOMPARE(csdDOM->update(), Kst::Object::UPDATE); // csdDOM->unlock(); // // outMatrix = csdDOM->outputMatrix(); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->sampleCount(), 128); // // csdDOM->setWindowSize(11); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->sampleCount(), 128); // // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->value(0, 0), 1.716299); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->value(0, 1), -0.485527); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->value(0, 2), -0.288690); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->value(1, 0), 1.716299); // QCOMPARE(outMatrix->value(1, 1), 0.0); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->value(1, 2), -0.274957); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->value(2, 0), 1.711721); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->value(2, 1), -0.485527); // QEXPECT_FAIL("", "This has always failed", Continue); // QCOMPARE(outMatrix->value(2, 2), -0.293267); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestCSD) #endifkst-2.0.3/tests/testobjectstore.h000644 001750 001750 00000001757 11544160206 017440 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTOBJECTSTORE_H #define TESTOBJECTSTORE_H #include class TestObjectStore : public QObject { Q_OBJECT private Q_SLOTS: void cleanupTestCase(); void testObjectStore(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testvector.h000644 001750 001750 00000001732 11544160206 016410 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTVECTOR_H #define TESTVECTOR_H #include class TestVector : public QObject { Q_OBJECT private Q_SLOTS: void cleanupTestCase(); void testVector(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testpsd.h000644 001750 001750 00000002072 11544160206 015672 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTPSD_H #define TESTPSD_H #include #include class TestPSD : public QObject { Q_OBJECT private: QDomDocument makeDOMElement(const QString& tag, const QString& val); private Q_SLOTS: void cleanupTestCase(); void testPSD(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testobjectstore.cpp000644 001750 001750 00000004372 11544160206 017767 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testobjectstore.h" #include #include #include #include #include #include using namespace Kst; void TestObjectStore::cleanupTestCase() { } void TestObjectStore::testObjectStore() { ObjectStore store; QVERIFY(store.isEmpty()); ScalarPtr sc = kst_cast(store.createObject()); QVERIFY(sc); // scalar was created ScalarPtr sc2 = kst_cast(store.createObject()); QVERIFY(sc2); QCOMPARE(store.getObjects().count(), 2); QCOMPARE(store.getObjects().count(), 0); QVERIFY(sc == kst_cast(store.retrieveObject(sc->Name()))); // can retrieve the object from the store VectorPtr vec = kst_cast(store.createObject()); QVERIFY(vec); QVERIFY(store.getObjects().count() > 2); // to account for the vector's stats scalars QCOMPARE(store.getObjects().count(), 1); QCOMPARE(store.getObjects().count(), 0); QCOMPARE(store.getObjects().count(), 0); QCOMPARE(store.dataSourceList().count(), 0); store.clear(); QVERIFY(store.isEmpty()); QVERIFY(sc); // make sure objects didn't get deleted while references were held QVERIFY(sc2); QVERIFY(vec); QPointer p(sc); ScalarPtr tempSc = sc; sc = 0L; QVERIFY(p); tempSc = 0L; QVERIFY(!p); // make sure object gets deleted when last reference is gone } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestObjectStore) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/datagenerator.pl000755 001750 001750 00000000627 11544160206 017217 0ustar00synthsynth000000 000000 #!/usr/bin/perl # open(OUTPUT, ">$ARGV[0]") || die "Can't open $ARGV[0]: $!"; $i = 0; while (true) { print OUTPUT "$i "; $ii = $i/10; print OUTPUT sin($ii) + rand(0.4) - 0.2; print OUTPUT " "; print OUTPUT cos($ii) + rand(0.4) - 0.2; print OUTPUT " "; print OUTPUT sin($ii * $ii) * (cos($ii) + rand(0.4) - 0.2); print OUTPUT " "; print OUTPUT "\n"; $i++; select(undef, undef, undef, 0.1); } kst-2.0.3/tests/testgeneratedmatrix.h000644 001750 001750 00000001776 11544160206 020301 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTGENERATEDMATRIX_H #define TESTGENERATEDMATRIX_H #include class TestGeneratedMatrix : public QObject { Q_OBJECT private Q_SLOTS: void cleanupTestCase(); void testGeneratedMatrix(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testlabelparser.cpp000644 001750 001750 00000032277 11544160206 017745 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testlabelparser.h" #include #include #include static Kst::ObjectStore _store; void TestLabelParser::cleanupTestCase() { _store.clear(); } void TestLabelParser::dumpAttributes(Label::Chunk *l, QString indent) { printf("%sb:%d i:%d u:%d c:%s\n", indent.toLatin1().data(), l->attributes.bold, l->attributes.italic, l->attributes.underline, l->attributes.color.name().toLatin1().data()); } void TestLabelParser::dumpTree(Label::Chunk *l, QString indent) { while (l) { printf("%sNode: %p %s[%s]%s\n", indent.toLatin1().data(), l, l->vOffset == Label::Chunk::None ? "" : (l->vOffset == Label::Chunk::Up ? "U " : "D "), l->text.toLatin1().data(), l->group ? " [G]" : ""); printf("%sPrev: %p Next: %p Up: %p Down: %p\n", indent.toLatin1().data(), l->prev, l->next, l->up, l->down); dumpAttributes(l, indent); if (l->group) { dumpTree(l->group, indent + " "); } if (l->up) { dumpTree(l->up, indent + " "); } if (l->down) { dumpTree(l->down, indent + " "); } l = l->next; } } void TestLabelParser::dumpTree(Label::Parsed *l) { dumpTree(l->chunk); } void TestLabelParser::testLabelParser() { Label::Parsed *parsed = Label::parse(""); QVERIFY(parsed != 0L); QVERIFY(parsed->chunk->prev == 0L); QVERIFY(parsed->chunk->next == 0L); QVERIFY(parsed->chunk->text == QString::null); QCOMPARE(parsed->chunk->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("a"); QVERIFY(parsed != 0L); QVERIFY(parsed->chunk->prev == 0L); QVERIFY(parsed->chunk->next == 0L); QCOMPARE(parsed->chunk->text, QString("a")); QCOMPARE(parsed->chunk->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("\\]"); QVERIFY(parsed != 0L); QVERIFY(parsed->chunk->prev == 0L); QVERIFY(parsed->chunk->next == 0L); QCOMPARE(parsed->chunk->text, QString("]")); QCOMPARE(parsed->chunk->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("\\\\"); QVERIFY(parsed != 0L); QVERIFY(parsed->chunk->prev == 0L); QVERIFY(parsed->chunk->next == 0L); QCOMPARE(parsed->chunk->text, QString("\\")); QCOMPARE(parsed->chunk->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("\\tau"); QVERIFY(parsed != 0L); QVERIFY(parsed->chunk->prev == 0L); QVERIFY(parsed->chunk->next == 0L); QCOMPARE(parsed->chunk->text, QString(QChar(0x3A4 + 0x20))); QCOMPARE(parsed->chunk->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("\\t"); QVERIFY(parsed != 0L); QCOMPARE(parsed->chunk->text, QString("")); QCOMPARE(parsed->chunk->tab, true); QCOMPARE(parsed->chunk->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("\\n"); QVERIFY(parsed != 0L); QCOMPARE(parsed->chunk->text, QString("")); QCOMPARE(parsed->chunk->linebreak, true); QCOMPARE(parsed->chunk->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("\\tau\\Theta"); QVERIFY(parsed != 0L); QVERIFY(parsed->chunk->next == 0L); QVERIFY(parsed->chunk->text[0] == QChar(0x3A4 + 0x20)); QVERIFY(parsed->chunk->text[1] == QChar(0x398)); QCOMPARE(parsed->chunk->text.length(), 2); delete parsed; Label::Chunk *c = 0L; parsed = Label::parse("\\taufoo bar\\n\\Theta"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next != 0L); QCOMPARE(c->text, QString(QChar(0x3A4 + 0x20)) + "foo bar"); c = c->next; QVERIFY(c->prev != 0L); QVERIFY(c->next != 0L); QCOMPARE(c->text, QString("")); QCOMPARE(c->linebreak, true); c = c->next; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QCOMPARE(c->text, QString(QChar(0x398))); delete parsed; parsed = Label::parse("x^y^z"); QVERIFY(parsed == 0L); parsed = Label::parse("x_y_z"); QVERIFY(parsed == 0L); parsed = Label::parse("x^y_z"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->prev == 0L); QVERIFY(c->next == 0L); QVERIFY(c->up != 0L); QVERIFY(c->down != 0L); QCOMPARE(c->text, QString("x")); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->up; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("y")); QCOMPARE(c->vOffset, Label::Chunk::Up); c = c->prev->down; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("z")); QCOMPARE(c->vOffset, Label::Chunk::Down); delete parsed; parsed = Label::parse("x^{}"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->prev == 0L); QVERIFY(c->next == 0L); QVERIFY(c->up != 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("x")); QVERIFY(c->group == 0L); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->up; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QVERIFY(c->group != 0L); QCOMPARE(c->vOffset, Label::Chunk::Up); c = c->group; QCOMPARE(c->text, QString("")); QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QVERIFY(c->group == 0L); QCOMPARE(c->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("x^{y+1}_{z-1}"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->prev == 0L); QVERIFY(c->next == 0L); QVERIFY(c->up != 0L); QVERIFY(c->down != 0L); QCOMPARE(c->text, QString("x")); QVERIFY(c->group == 0L); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->up; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QVERIFY(c->group != 0L); QCOMPARE(c->vOffset, Label::Chunk::Up); c = c->group; QCOMPARE(c->text, QString("y+1")); QVERIFY(c->group == 0L); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->prev->prev->down; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QVERIFY(c->group != 0L); QCOMPARE(c->vOffset, Label::Chunk::Down); c = c->group; QCOMPARE(c->text, QString("z-1")); QVERIFY(c->group == 0L); QCOMPARE(c->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("x\\^y"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->prev == 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("x^y")); QCOMPARE(c->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("x^{y^{q+1} + 1}_{z-1}"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->prev == 0L); QVERIFY(c->next == 0L); QVERIFY(c->up != 0L); QVERIFY(c->down != 0L); QCOMPARE(c->text, QString("x")); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->up; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QVERIFY(c->group != 0L); QCOMPARE(c->vOffset, Label::Chunk::Up); c = c->group; QCOMPARE(c->text, QString("y")); QVERIFY(c->prev != 0L); QVERIFY(c->next != 0L); QVERIFY(c->up != 0L); QVERIFY(c->down == 0L); QVERIFY(c->group == 0L); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->up; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QVERIFY(c->group != 0L); QCOMPARE(c->vOffset, Label::Chunk::Up); c = c->group; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("q+1")); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->prev->prev->next; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString(" + 1")); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->prev->prev->prev->down; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QVERIFY(c->group); QCOMPARE(c->vOffset, Label::Chunk::Down); c = c->group; QVERIFY(c->prev != 0L); QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("z-1")); QCOMPARE(c->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("{2*2}"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next == 0L); QVERIFY(c->group != 0L); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->group; QCOMPARE(c->text, QString("2*2")); QCOMPARE(c->vOffset, Label::Chunk::None); delete parsed; parsed = Label::parse("x^100"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next != 0L); QVERIFY(c->up != 0L); QCOMPARE(c->text, QString("x")); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->next; QVERIFY(c->next == 0L); QCOMPARE(c->text, QString("00")); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->prev->up; QVERIFY(c->next == 0L); QCOMPARE(c->text, QString("1")); QCOMPARE(c->vOffset, Label::Chunk::Up); delete parsed; parsed = Label::parse("x^100*200"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next != 0L); QVERIFY(c->up != 0L); QCOMPARE(c->text, QString("x")); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->next; QVERIFY(c->next == 0L); QCOMPARE(c->text, QString("00*200")); QCOMPARE(c->vOffset, Label::Chunk::None); c = c->prev->up; QVERIFY(c->next == 0L); QCOMPARE(c->text, QString("1")); QCOMPARE(c->vOffset, Label::Chunk::Up); delete parsed; parsed = Label::parse("[ a ^label ]"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text,QString( "a ^label")); QVERIFY(c->scalar); delete parsed; parsed = Label::parse("[vector[2]]"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("vector")); QCOMPARE(c->expression, QString("2")); QVERIFY(c->vector); delete parsed; parsed = Label::parse("[a][b]"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next != 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("a")); QVERIFY(c->scalar); c = c->next; QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("b")); QVERIFY(c->scalar); delete parsed; parsed = Label::parse("[a]*[b]"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next != 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("a")); QVERIFY(c->scalar); c = c->next; QVERIFY(c->next != 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("*")); QVERIFY(!c->scalar); c = c->next; QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("b")); QVERIFY(c->scalar); delete parsed; parsed = Label::parse("[x]^[a]_[b][c]"); QVERIFY(parsed != 0L); c = parsed->chunk; QVERIFY(c->next != 0L); QVERIFY(c->up != 0L); QVERIFY(c->down != 0L); QCOMPARE(c->text, QString("x")); QVERIFY(c->scalar); c = c->up; QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("a")); QVERIFY(c->scalar); c = c->prev->down; QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("b")); QVERIFY(c->scalar); c = c->prev->next; QVERIFY(c->next == 0L); QVERIFY(c->up == 0L); QVERIFY(c->down == 0L); QCOMPARE(c->text, QString("c")); QVERIFY(c->scalar); delete parsed; parsed = Label::parse("Ends in a \\"); delete parsed; parsed = Label::parse("_"); delete parsed; parsed = Label::parse("A weird { case }"); delete parsed; parsed = Label::parse("x^y^foo{ case }"); delete parsed; parsed = Label::parse("x^5\\"); delete parsed; parsed = Label::parse("}"); delete parsed; parsed = Label::parse("Average period (ADU)"); delete parsed; parsed = Label::parse("PSD (ADU/{Hz^{1/2}})"); delete parsed; parsed = Label::parse("\\Sigma^{(x+5)^2}_{5+1} + \\Pi^{\\Sigma^{i-j}_{i+j}}_{x = 0} + 5"); QVERIFY(parsed != 0L); // more to test here delete parsed; parsed = Label::parse("A test \\textbf{bold \\textit{italicbold}} \\textit{italic}\n42^{\\textbf{42}^{42}} 42^\\textbf{42^{42}} 42^{42}\n\\underline{a whole\\tregion underlined}"); //dumpTree(parsed); // FIXME delete parsed; parsed = Label::parse("\\textbf{\\textit{italicbold}bold}"); // FIXME delete parsed; parsed = Label::parse("\\textcolor{red}{red}black"); // FIXME delete parsed; parsed = Label::parse("\\textbf{bold}unbold"); // FIXME delete parsed; // more to test... } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestLabelParser) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testmatrix.h000644 001750 001750 00000001732 11544160206 016412 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTMATRIX_H #define TESTMATRIX_H #include class TestMatrix : public QObject { Q_OBJECT private Q_SLOTS: void cleanupTestCase(); void testMatrix(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testscalar.h000644 001750 001750 00000002405 11544160206 016351 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTSCALAR_H #define TESTSCALAR_H #include #include class SListener : public QObject { Q_OBJECT public: SListener(); virtual ~SListener(); int _trigger; public Q_SLOTS: void trigger(qint64); }; class TestScalar : public QObject { Q_OBJECT private: QDomDocument makeDOMDocument(const QString& tag, const QString& val, bool orphan = false); private Q_SLOTS: void cleanupTestCase(); void testScalar(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testcsd.h000644 001750 001750 00000002073 11544160206 015656 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTCSD_H #define TESTCSD_H #include #include class TestCSD : public QObject { Q_OBJECT private: QDomDocument makeDOMElement(const QString& tag, const QString& val); private Q_SLOTS: void cleanupTestCase(); void testCSD(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testdatasource.cpp000644 001750 001750 00000053106 11544160206 017575 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testdatasource.h" #include #include #include #include #include #include "math_kst.h" #include "kst_inf.h" #include "datacollection.h" #include "objectstore.h" #include "datavector.h" #include "datamatrix.h" #include "datasourcepluginmanager.h" #include "colorsequence.h" #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) static Kst::ObjectStore _store; void TestDataSource::initTestCase() { Kst::DataSourcePluginManager::init(); _plugins = Kst::DataSourcePluginManager::pluginList(); Kst::ColorSequence::self(); } void TestDataSource::cleanupTestCase() { _store.clear(); } void TestDataSource::testAscii() { if (!_plugins.contains("ASCII File Reader")) QSKIP("...couldn't find plugin.", SkipAll); { QTemporaryFile tf; tf.open(); QTextStream ts(&tf); ts << ";" << endl; ts << " ;" << endl; ts << "#;" << endl; ts << "c comment comment" << endl; ts << "\t!\t!\t!\t!" << endl; ts << "2.0" << endl; ts << "1" << endl; ts << ".2" << endl; ts.flush(); Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, tf.fileName()); QVERIFY(dsp); QVERIFY(dsp->isValid()); QVERIFY(dsp->hasConfigWidget()); QCOMPARE(dsp->fileType(), QLatin1String("ASCII file")); QVERIFY(dsp->vector().isValid("INDEX")); QVERIFY(dsp->vector().isValid("1")); QVERIFY(!dsp->vector().isValid("0")); QVERIFY(!dsp->vector().isValid("2")); QCOMPARE(dsp->vector().dataInfo(QString::null).samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo("INDEX").samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo("1").samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo(QString::null).frameCount, 3); QCOMPARE(dsp->vector().dataInfo("1").frameCount, 3); QCOMPARE(dsp->vector().dataInfo("INDEX").frameCount, 3); QCOMPARE(dsp->fileName(), tf.fileName()); QCOMPARE(dsp->vector().list().count(), 2); QVERIFY(dsp->vector().isListComplete()); QVERIFY(!dsp->isEmpty()); Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "1", 0, -1, 0, false, false); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 3); QCOMPARE(rvp->value()[0], 2.0); QCOMPARE(rvp->value()[1], 1.0); QCOMPARE(rvp->value()[2], 0.2); rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "INDEX", 0, -1, 0, false, false); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 3); QCOMPARE(rvp->value()[0], 0.0); QCOMPARE(rvp->value()[1], 1.0); QCOMPARE(rvp->value()[2], 2.0); tf.close(); } { QTemporaryFile tf; tf.open(); QTextStream ts(&tf); ts << "2e-1 \t .1415" << endl; ts << "nan -.4e-2" << endl; ts << "inf\t1" << endl; ts << "0.000000000000000000000000000000000000000000000000 0" << endl; Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, tf.fileName()); QVERIFY(dsp); QVERIFY(dsp->isValid()); QVERIFY(dsp->hasConfigWidget()); QCOMPARE(dsp->fileType(), QLatin1String("ASCII file")); QVERIFY(dsp->vector().isValid("INDEX")); QVERIFY(dsp->vector().isValid("1")); QVERIFY(!dsp->vector().isValid("0")); QVERIFY(dsp->vector().isValid("2")); QVERIFY(!dsp->vector().isValid("3")); QCOMPARE(dsp->vector().dataInfo(QString::null).samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo("INDEX").samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo("1").samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo("2").samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo(QString::null).frameCount, 4); QCOMPARE(dsp->vector().dataInfo("1").frameCount, 4); QCOMPARE(dsp->vector().dataInfo("2").frameCount, 4); QCOMPARE(dsp->vector().dataInfo("INDEX").frameCount, 4); QCOMPARE(dsp->vector().list().count(), 3); QVERIFY(!dsp->isEmpty()); Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "1", 0, -1, 0, false, false); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 4); QCOMPARE(rvp->value()[0], 0.2); QVERIFY(rvp->value()[1] != rvp->value()[1]); QVERIFY(rvp->value()[2] == INF); QCOMPARE(rvp->value()[3], 0.0); rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "2", 0, -1, 0, false, false); rvp->writeLock(); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 4); QCOMPARE(rvp->value()[0], 0.1415); QCOMPARE(rvp->value()[1], -0.004); QCOMPARE(rvp->value()[2], 1.0); QCOMPARE(rvp->value()[3], 0.0); tf.close(); } { QTemporaryFile tf; tf.open(); QTextStream ts(&tf); ts << "2 4" << endl; Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, tf.fileName()); QVERIFY(dsp); QVERIFY(dsp->isValid()); QVERIFY(dsp->hasConfigWidget()); QCOMPARE(dsp->fileType(), QLatin1String("ASCII file")); QVERIFY(dsp->vector().isValid("INDEX")); QVERIFY(dsp->vector().isValid("1")); QVERIFY(!dsp->vector().isValid("0")); QVERIFY(dsp->vector().isValid("2")); QVERIFY(!dsp->vector().isValid("3")); QCOMPARE(dsp->vector().dataInfo(QString::null).samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo("INDEX").samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo("1").samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo("2").samplesPerFrame, 1); QCOMPARE(dsp->vector().dataInfo(QString::null).frameCount, 1); QCOMPARE(dsp->vector().dataInfo("1").frameCount, 1); QCOMPARE(dsp->vector().dataInfo("2").frameCount, 1); QCOMPARE(dsp->vector().dataInfo("INDEX").frameCount, 1); QCOMPARE(dsp->vector().list().count(), 3); QVERIFY(!dsp->isEmpty()); Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "1", 0, -1, 0, false, false); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 1); // Are we allowed to have vectors of 1? QCOMPARE(rvp->value()[0], 2.0); rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "2", 0, -1, 0, false, false); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 1); QCOMPARE(rvp->value()[0], 4.0); tf.close(); } { QTemporaryFile tf; tf.open(); QTextStream ts(&tf); ts << ";" << endl; Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, tf.fileName()); QVERIFY(dsp); QVERIFY(dsp->hasConfigWidget()); QCOMPARE(dsp->fileType(), QLatin1String("ASCII file")); tf.close(); } { QTemporaryFile tf; tf.open(); QTextStream ts(&tf); for (int i = 0; i < 39000; ++i) { ts << i << " " << i + 100 << " " << i + 1000 << endl; } Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, tf.fileName()); dsp->internalUpdate(); QVERIFY(dsp); QVERIFY(dsp->isValid()); QVERIFY(dsp->hasConfigWidget()); QCOMPARE(dsp->fileType(), QLatin1String("ASCII file")); QCOMPARE(dsp->vector().dataInfo(QString::null).frameCount, 39000); QCOMPARE(dsp->vector().dataInfo("1").frameCount, 39000); QCOMPARE(dsp->vector().dataInfo("2").frameCount, 39000); QCOMPARE(dsp->vector().dataInfo("3").frameCount, 39000); QCOMPARE(dsp->vector().dataInfo("INDEX").frameCount, 39000); QCOMPARE(dsp->vector().list().count(), 4); QVERIFY(!dsp->isEmpty()); Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "1", 0, -1, 0, false, false); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 39000); rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "2", 0, -1, 10, true, false); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 3900); QCOMPARE(rvp->value()[0], 100.0); QCOMPARE(rvp->value()[1], 110.0); QCOMPARE(rvp->value()[2], 120.0); QCOMPARE(rvp->value()[3898], 39080.0); rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "3", 0, -1, 10, true, true); rvp->internalUpdate(); rvp->unlock(); QVERIFY(rvp->isValid()); QCOMPARE(rvp->length(), 3900); QCOMPARE(rvp->value()[0], 1004.5); QCOMPARE(rvp->value()[1], 1014.5); QCOMPARE(rvp->value()[2], 1024.5); QCOMPARE(rvp->value()[3898], 39984.5); QFile::remove(dsp->fileName()); tf.close(); rvp->writeLock(); rvp->reload(); rvp->unlock(); #ifndef Q_WS_WIN32 // Win32 you can't erase a file that's open QVERIFY(!rvp->isValid()); #endif } } void TestDataSource::testDirfile() { if (!_plugins.contains("DirFile Reader")) QSKIP("...couldn't find plugin.", SkipAll); //These tests assume that the dirfile was generated with dirfile_maker { QString fifteen = QDir::currentPath() + QDir::separator() + QString("tests") + QDir::separator() + QString("dirfile_testcase") + QDir::separator() + QString("15count"); if (!QFile::exists(fifteen + QDir::separator() + "format")) { QSKIP("...unable to perform test. Datafile missing", SkipAll); } printf("Opening dirfile = %s for test.\n", fifteen.toLatin1().data()); Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, fifteen); dsp->internalUpdate(); QVERIFY(dsp); QVERIFY(dsp->isValid()); QVERIFY(!dsp->hasConfigWidget()); QCOMPARE(dsp->fileType(), QLatin1String("Directory of Binary Files")); QVERIFY(dsp->vector().isValid("INDEX")); QCOMPARE(dsp->vector().dataInfo("INDEX").frameCount, 17); QVERIFY(dsp->vector().isValid("cos")); QVERIFY(dsp->vector().isValid("fcount")); QVERIFY(dsp->vector().isValid("scount")); QVERIFY(dsp->vector().isValid("sine")); QVERIFY(dsp->vector().isValid("ssine")); QVERIFY(!dsp->vector().isValid("foo")); //TODO test samples per frame? QCOMPARE(dsp->fileName(), fifteen); QCOMPARE(dsp->vector().list().count(), 6); QVERIFY(dsp->vector().isListComplete()); QVERIFY(!dsp->isEmpty()); { //Skip FIVE frames... Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "INDEX", 0, -1, 5, true, false); rvp->internalUpdate(); rvp->unlock(); //We should have length equal to three... items {0, 5, 10} //NOTE: The last item, index #14, does not fit in the skip boundary... QCOMPARE(3, rvp->length()); QCOMPARE(0.0, rvp->value(0)); QCOMPARE(5.0, rvp->value(1)); QCOMPARE(10.0, rvp->value(2)); QCOMPARE(15, rvp->numFrames()); QCOMPARE(0, rvp->startFrame()); QCOMPARE(-1, rvp->reqNumFrames()); QCOMPARE(0, rvp->reqStartFrame()); QCOMPARE(true, rvp->readToEOF()); QCOMPARE(false, rvp->countFromEOF()); QCOMPARE(true, rvp->doSkip()); QCOMPARE(5, rvp->skip()); QCOMPARE(false, rvp->doAve()); } { //Skip FIVE frames start at 3... Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "INDEX", 3, -1, 5, true, false); rvp->internalUpdate(); rvp->unlock(); //We should have length equal to two... items {5, 10} QCOMPARE(2, rvp->length()); QCOMPARE(5.0, rvp->value(0)); QCOMPARE(10.0, rvp->value(1)); QCOMPARE(10, rvp->numFrames()); QCOMPARE(5, rvp->startFrame()); QCOMPARE(-1, rvp->reqNumFrames()); QCOMPARE(3, rvp->reqStartFrame()); QCOMPARE(true, rvp->readToEOF()); QCOMPARE(false, rvp->countFromEOF()); QCOMPARE(true, rvp->doSkip()); QCOMPARE(5, rvp->skip()); QCOMPARE(false, rvp->doAve()); } { //Skip FIVE frames 11 from end... Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "INDEX", 0, 11, 5, true, false); rvp->internalUpdate(); rvp->unlock(); //We should have length equal to two... items {0, 5} QCOMPARE(2, rvp->length()); QCOMPARE(0.0, rvp->value(0)); QCOMPARE(5.0, rvp->value(1)); QCOMPARE(10, rvp->numFrames()); QCOMPARE(0, rvp->startFrame()); QCOMPARE(11, rvp->reqNumFrames()); QCOMPARE(0, rvp->reqStartFrame()); QCOMPARE(false, rvp->readToEOF()); QCOMPARE(false, rvp->countFromEOF()); QCOMPARE(true, rvp->doSkip()); QCOMPARE(5, rvp->skip()); QCOMPARE(false, rvp->doAve()); } { //Skip FIVE frames and countFromEOF()... Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "INDEX", -1, 10, 5, true, false); rvp->internalUpdate(); rvp->unlock(); //We should have length equal to two... items {5, 10} QCOMPARE(2, rvp->length()); QCOMPARE(10.0, rvp->value(0)); QCOMPARE(15.0, rvp->value(1)); QCOMPARE(10, rvp->numFrames()); QCOMPARE(10, rvp->startFrame()); QCOMPARE(10, rvp->reqNumFrames()); QCOMPARE(-1, rvp->reqStartFrame()); QCOMPARE(false, rvp->readToEOF()); QCOMPARE(true, rvp->countFromEOF()); QCOMPARE(true, rvp->doSkip()); QCOMPARE(5, rvp->skip()); QCOMPARE(false, rvp->doAve()); } } } void TestDataSource::testCDF() { return; //FIXME remove when we actually have some tests for this datasource. if (!_plugins.contains("CDF File Reader")) QSKIP("...couldn't find plugin.", SkipAll); } void TestDataSource::testFrame() { return; //FIXME remove when we actually have some tests for this datasource. if (!_plugins.contains("Frame Reader")) QSKIP("...couldn't find plugin.", SkipAll); } void TestDataSource::testIndirect() { return; //FIXME remove when we actually have some tests for this datasource. if (!_plugins.contains("Indirect File Reader")) QSKIP("...couldn't find plugin.", SkipAll); } void TestDataSource::testLFI() { return; //FIXME remove when we actually have some tests for this datasource. if (!_plugins.contains("LFIIO Reader")) QSKIP("...couldn't find plugin.", SkipAll); } void TestDataSource::testPlanck() { return; //FIXME remove when we actually have some tests for this datasource. if (!_plugins.contains("PLANCK Plugin")) QSKIP("...couldn't find plugin.", SkipAll); } void TestDataSource::testStdin() { } void TestDataSource::testQImageSource() { bool ok = true; if (!_plugins.contains("QImage Source Reader")) QSKIP("...couldn't find plugin.", SkipAll); //These tests assume that the image kst.png exists in src/images QString imageFile = QString(TOSTRING(KST_SRC_DIR)) + QDir::separator() + QString("src") + QDir::separator() + QString("images") + QDir::separator() + QString("kst.png"); if (!QFile::exists(imageFile)) { QSKIP("...unable to perform test. Image file missing.", SkipAll); } printf("Opening image = %s for test.\n", imageFile.toLatin1().data()); Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, imageFile); dsp->internalUpdate(); QVERIFY(dsp); QVERIFY(dsp->isValid()); QVERIFY(!dsp->hasConfigWidget()); QCOMPARE(dsp->fileType(), QLatin1String("QImage image")); QVERIFY(dsp->vector().isValid("INDEX")); QCOMPARE(dsp->vector().dataInfo("INDEX").frameCount, 1024); QVERIFY(dsp->vector().isValid("RED")); QVERIFY(dsp->vector().isValid("BLUE")); QVERIFY(dsp->vector().isValid("GREEN")); QVERIFY(dsp->vector().isValid("GRAY")); QVERIFY(!dsp->vector().isValid("foo")); //TODO test samples per frame? QCOMPARE(dsp->fileName(), imageFile); QCOMPARE(dsp->vector().list().count(), 5); QVERIFY(dsp->vector().isListComplete()); QVERIFY(!dsp->isEmpty()); QVERIFY(dsp->matrix().isValid("RED")); QVERIFY(dsp->matrix().isValid("BLUE")); QVERIFY(dsp->matrix().isValid("GREEN")); QVERIFY(dsp->matrix().isValid("GRAY")); QVERIFY(!dsp->matrix().isValid("foo")); { Kst::DataMatrixPtr matrix = Kst::kst_cast(_store.createObject()); matrix->change(dsp, "GRAY", 0, 0, -1, -1, false, false, 0, 0, 0, 1, 1); matrix->writeLock(); matrix->internalUpdate(); matrix->unlock(); QCOMPARE(matrix->xNumSteps(), 32); QCOMPARE(matrix->yNumSteps(), 32); QCOMPARE(matrix->xStepSize(), 1.0); QCOMPARE(matrix->yStepSize(), 1.0); QCOMPARE(matrix->minX(), 0.0); QCOMPARE(matrix->minY(), 0.0); QCOMPARE(matrix->minValue(), 0.0); QCOMPARE(matrix->maxValue(), 255.0); QCOMPARE(matrix->minValuePositive(), 7.0); QCOMPARE(matrix->sampleCount(), 1024); QCOMPARE(matrix->value(0, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(matrix->value(25, 3, &ok), 81.0); QVERIFY(ok); } { Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "INDEX", 0, -1, 1, false, false); rvp->internalUpdate(); rvp->unlock(); QCOMPARE(1024, rvp->length()); QCOMPARE(0.0, rvp->value(0)); QCOMPARE(1.0, rvp->value(1)); QCOMPARE(2.0, rvp->value(2)); QCOMPARE(1023.0, rvp->value(1023)); QCOMPARE(1024, rvp->numFrames()); QCOMPARE(0, rvp->startFrame()); QCOMPARE(-1, rvp->reqNumFrames()); QCOMPARE(0, rvp->reqStartFrame()); QCOMPARE(true, rvp->readToEOF()); QCOMPARE(false, rvp->countFromEOF()); QCOMPARE(false, rvp->doSkip()); QCOMPARE(0, rvp->skip()); QCOMPARE(false, rvp->doAve()); } } void TestDataSource::testFITSImage() { bool ok = true; if (!_plugins.contains("FITS Image Source Reader")) QSKIP("...couldn't find plugin.", SkipAll); //These tests assume that the fits image test.fits exists in tests/fitsimage_testcase QString imageFile = QDir::currentPath() + QDir::separator() + QString("tests") + QDir::separator() + QString("fitsimage_testcase") + QDir::separator() + QString("test.fits"); if (!QFile::exists(imageFile)) { QSKIP("...unable to perform test. Image file missing.", SkipAll); } printf("Opening image = %s for test.\n", imageFile.toLatin1().data()); Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, imageFile); dsp->internalUpdate(); QVERIFY(dsp); QVERIFY(dsp->isValid()); QVERIFY(!dsp->hasConfigWidget()); QCOMPARE(dsp->fileType(), QLatin1String("FITS image")); QVERIFY(dsp->vector().isValid("INDEX")); QCOMPARE(dsp->vector().dataInfo("INDEX").frameCount, 58800); QVERIFY(dsp->vector().isValid("1")); QVERIFY(!dsp->vector().isValid("foo")); //TODO test samples per frame? QCOMPARE(dsp->fileName(), imageFile); QCOMPARE(dsp->vector().list().count(), 2); QVERIFY(dsp->vector().isListComplete()); QVERIFY(!dsp->isEmpty()); QVERIFY(dsp->matrix().isValid("1")); QVERIFY(!dsp->matrix().isValid("foo")); { Kst::DataMatrixPtr matrix = Kst::kst_cast(_store.createObject()); matrix->change(dsp, "1", 0, 0, -1, -1, false, false, 0, 0, 0, 1, 1); matrix->writeLock(); matrix->internalUpdate(); matrix->unlock(); QCOMPARE(matrix->xNumSteps(), 280); QCOMPARE(matrix->yNumSteps(), 210); QCOMPARE(matrix->xStepSize(), 1.0); QCOMPARE(matrix->yStepSize(), 1.0); QCOMPARE(matrix->minX(), 0.0); QCOMPARE(matrix->minY(), 0.0); QCOMPARE(matrix->minValue(), -86.297431945800781); QCOMPARE(matrix->maxValue(), 487.873565673828125); QCOMPARE(matrix->minValuePositive(), 0.000308976683300); QCOMPARE(matrix->sampleCount(), 58800); QCOMPARE(matrix->value(0, 0, &ok), 0.0); QVERIFY(!ok); QCOMPARE(matrix->value(12, 61, &ok), -17.691156387329102); QVERIFY(ok); } { Kst::DataVectorPtr rvp = Kst::kst_cast(_store.createObject()); rvp->writeLock(); rvp->change(dsp, "INDEX", 0, -1, 1, false, false); rvp->internalUpdate(); rvp->unlock(); QCOMPARE(58800, rvp->length()); QCOMPARE(0.0, rvp->value(0)); QCOMPARE(1.0, rvp->value(1)); QCOMPARE(2.0, rvp->value(2)); QCOMPARE(1023.0, rvp->value(1023)); QCOMPARE(58800, rvp->numFrames()); QCOMPARE(0, rvp->startFrame()); QCOMPARE(-1, rvp->reqNumFrames()); QCOMPARE(0, rvp->reqStartFrame()); QCOMPARE(true, rvp->readToEOF()); QCOMPARE(false, rvp->countFromEOF()); QCOMPARE(false, rvp->doSkip()); QCOMPARE(0, rvp->skip()); QCOMPARE(false, rvp->doAve()); } } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestDataSource) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testpsd.cpp000644 001750 001750 00000014371 11544160206 016232 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testpsd.h" #include #include #include #include #include #include "psd.h" #include "ksttest.h" #include "datacollection.h" #include "objectstore.h" static Kst::ObjectStore _store; void TestPSD::cleanupTestCase() { _store.clear(); } QDomDocument TestPSD::makeDOMElement(const QString& tag, const QString& val) { // Should be some boundary checking in the constructor. QDomDocument psdDOM("psddocument"); QDomElement psdElement, child; QDomText text; psdElement = psdDOM.createElement("psdDOMTest"); child = psdDOM.createElement("tag"); text = psdDOM.createTextNode(tag); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("vector"); text = psdDOM.createTextNode(val); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("samplerate"); text = psdDOM.createTextNode("128"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("average"); text = psdDOM.createTextNode("1"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("fftlength"); text = psdDOM.createTextNode("5"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("apodize"); text = psdDOM.createTextNode("1"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("apodizefunction"); text = psdDOM.createTextNode("WindowOriginal"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("gaussiansigma"); text = psdDOM.createTextNode("0.01"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("removemean"); text = psdDOM.createTextNode("1"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("vectorunits"); text = psdDOM.createTextNode("vUnits"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("rateunits"); text = psdDOM.createTextNode("rUnits"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("outputtype"); text = psdDOM.createTextNode("PSDAmplitudeSpectralDensity"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("interpolateholes"); text = psdDOM.createTextNode("1"); child.appendChild(text); psdElement.appendChild(child); psdDOM.appendChild(psdElement); return psdDOM; } void TestPSD::testPSD() { Kst::VectorPtr vp = Kst::kst_cast(_store.createObject()); Q_ASSERT(vp); vp->resize(10); vp->setDescriptiveName("tempVector"); for (int i = 0; i < 10; i++){ vp->value()[i] = i; } Kst::PSDPtr psd = Kst::kst_cast(_store.createObject()); psd->change(vp, 0.0, false, 10, false, false, QString("vUnits"), QString("rUnits"), WindowUndefined, 0.0, PSDUndefined); QCOMPARE(psd->vector()->descriptiveName(), QLatin1String("tempVector")); QCOMPARE(psd->output(), PSDUndefined); QVERIFY(!psd->apodize()); QVERIFY(!psd->removeMean()); QVERIFY(!psd->average()); QCOMPARE(psd->frequency(), 0.0); QCOMPARE(psd->apodizeFxn(), WindowUndefined); QCOMPARE(psd->gaussianSigma(), 0.0); Kst::VectorPtr vpVX = psd->vX(); Kst::VectorPtr vpVY = psd->vY(); QCOMPARE(vpVX->length(), 1); QVERIFY(vpVX->value()[0] != vpVX->value()[0]); QCOMPARE(vpVY->length(), 1); QVERIFY(vpVY->value()[0] != vpVY->value()[0]); for(int j = 0; j < vpVX->length(); j++){ QCOMPARE(vpVX->value()[j], &Kst::NOPOINT); } psd->setOutput(PSDAmplitudeSpectralDensity); psd->setApodize(true); psd->setRemoveMean(true); psd->setAverage(true); psd->setFrequency(0.1); psd->setApodizeFxn(WindowOriginal); psd->setGaussianSigma(0.2); QCOMPARE(psd->vector()->descriptiveName(), QLatin1String("tempVector")); QCOMPARE(psd->output(), PSDAmplitudeSpectralDensity); QVERIFY(psd->apodize()); QVERIFY(psd->removeMean()); QVERIFY(psd->average()); QCOMPARE(psd->frequency(), 0.1); QCOMPARE(psd->apodizeFxn(), WindowOriginal); QCOMPARE(psd->gaussianSigma(), 0.2); // doTest(psd->update(0) == Kst::Object::UPDATE); // doTest(psd->propertyString() == ps); // doTest(!psd->curveHints().curveName() == ""); // printf("Curve name [%s]", kstCHL[0].curveName()); // printf("X Vector name [%s]", kstCHL[0].xVectorName()); // printf("Y Vector name [%s]", kstCHL[0].yVectorName()); QTemporaryFile tf; tf.open(); QXmlStreamWriter xml; xml.setDevice(&tf); xml.setAutoFormatting(true); psd->save(xml); QFile::remove(tf.fileName()); QDomNode n = makeDOMElement("psdDOMPsd", "psdDOMVector").firstChild(); QDomElement e = n.toElement(); //FIXME: should use factory, not this constructor. This constructor is no longer // used anywhere in kst. // Kst::PSDPtr psdDOM = new Kst::PSD(&_store, e); // QCOMPARE(psdDOM->tag().tagString(), QLatin1String("psdDOMPsd")); // QCOMPARE(psdDOM->output(), PSDAmplitudeSpectralDensity); // QVERIFY(psdDOM->apodize()); // QVERIFY(psdDOM->removeMean()); // QVERIFY(psdDOM->average()); // QCOMPARE(psdDOM->frequency(), 128.0); // QCOMPARE(psdDOM->apodizeFxn(), WindowOriginal); // QCOMPARE(psdDOM->gaussianSigma(), 0.01); // Kst::VectorPtr vpVX = psdDOM->vX(); // for(int j = 0; j < vpVX->length(); j++){ // printf("[%d][%lf]", j, vpVX->value()[j]); // } // Kst::VectorPtr vpVY = psdDOM->vY(); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestPSD) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testmatrix.cpp000644 001750 001750 00000012522 11544160206 016744 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testmatrix.h" #include #include #include #include #include static Kst::ObjectStore _store; void TestMatrix::cleanupTestCase() { _store.clear(); } void TestMatrix::testMatrix() { bool ok = true; //basic default constructor values Kst::MatrixPtr m1 = Kst::kst_cast(_store.createObject()); QCOMPARE(m1->sampleCount(), 0); QCOMPARE(m1->minValue(), 0.0); QCOMPARE(m1->maxValue(), 0.0); QCOMPARE(m1->value(0, 0, &ok), 0.0); QVERIFY(!ok); QCOMPARE(m1->value(10, 10, &ok), 0.0); //should be outside the boundaries. QVERIFY(!ok); QCOMPARE(m1->sampleCount(), 0); QCOMPARE(m1->meanValue(), 0.0); //basic symetrical matrix Kst::MatrixPtr m2 = Kst::kst_cast(_store.createObject()); QVERIFY(m2->resize(3, 3, true)); QVERIFY(!m2->editable()); m2->setEditable(true); QVERIFY(m2->editable()); QCOMPARE(m2->xNumSteps(), 3); QCOMPARE(m2->yNumSteps(), 3); QCOMPARE(m2->minX(), 0.0); QCOMPARE(m2->minY(), 0.0); QCOMPARE(m2->xStepSize(), 1.0); QCOMPARE(m2->yStepSize(), 1.0); QCOMPARE(m2->sampleCount(), 9); QVERIFY(m2->setValueRaw(1, 1, 5)); ok = true; QCOMPARE(m2->value(1, 1, &ok), 5.0); QVERIFY(ok); m2->blank(); m2->change(3, 3, 0, 0, 0, 0); //should not be legal QCOMPARE(m2->xNumSteps(), 3); QCOMPARE(m2->yNumSteps(), 3); QCOMPARE(m2->minX(), 0.0); QCOMPARE(m2->minY(), 0.0); QCOMPARE(m2->xStepSize(), 0.0); QCOMPARE(m2->yStepSize(), 0.0); QCOMPARE(m2->sampleCount(), 9); QVERIFY(!m2->setValue(0, 0, 1.0)); ok = true; QCOMPARE(m2->value(0, 0, &ok), 0.0); QVERIFY(!ok); QVERIFY(!m2->setValue(1, 1, 5.0)); QVERIFY(m2->value(1, 1) != 5.0); QVERIFY(m2->setValueRaw(2, 2, 6.0)); //fails Kst::MatrixPtr um1 = Kst::kst_cast(_store.createObject()); um1->change(3, 3, 0, 0, 1, 1); um1->setEditable(true); um1->zero(); QVERIFY(!um1->setValue(0, 0, 1.0)); QVERIFY(!um1->setValue(1, 1, 1.0)); QVERIFY(!um1->setValue(2, 2, 1.0)); QVERIFY(um1->resize(3, 3, false)); um1->zero(); QVERIFY(um1->setValue(0, 0, 1.0)); QVERIFY(um1->setValue(1, 1, 1.0)); QVERIFY(um1->setValue(2, 2, 1.0)); QVERIFY(um1->resize(2, 2, true)); QCOMPARE(um1->sampleCount(), 4); QCOMPARE(um1->value(0, 0, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(0, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(0, 2, &ok), 0.0); QVERIFY(!ok); QCOMPARE(um1->value(1, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 1, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(1, 2, &ok), 0.0); QVERIFY(!ok); QVERIFY(um1->resize(4, 4, true)); QCOMPARE(um1->value(0, 0, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(0, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(0, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 1, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(1, 2, &ok), 0.0); QVERIFY(ok); QVERIFY(um1->resize(3, 3, true)); QVERIFY(um1->setValue(0, 0, 1.716299)); QVERIFY(um1->setValue(0, 1, -0.485527)); QVERIFY(um1->setValue(0, 2, -0.288690)); QVERIFY(um1->setValue(1, 0, 1.716299)); QVERIFY(um1->setValue(1, 1, NAN)); QVERIFY(um1->setValue(1, 2, -0.274957)); QVERIFY(um1->setValue(2, 0, 1.711721)); QVERIFY(um1->setValue(2, 1, -0.485527)); QVERIFY(um1->setValue(2, 2, -0.293267)); QCOMPARE(um1->value(0, 0), 1.716299); QCOMPARE(um1->value(0, 1), -0.485527); QCOMPARE(um1->value(0, 2), -0.288690); QCOMPARE(um1->value(1, 0), 1.716299); QCOMPARE(um1->value(1, 1), 0.0); QCOMPARE(um1->value(1, 2), -0.274957); QCOMPARE(um1->value(2, 0), 1.711721); QCOMPARE(um1->value(2, 1), -0.485527); QCOMPARE(um1->value(2, 2), -0.293267); QCOMPARE(um1->minValue(), 0.0); QCOMPARE(um1->maxValue(), 0.0); Kst::MatrixPtr sm = Kst::kst_cast(_store.createObject()); sm->change(2, 2, 0, 0, 1, 1); sm->setEditable(true); QVERIFY(sm->resize(2, 2, false)); QCOMPARE(sm->xNumSteps(), 2); QCOMPARE(sm->yNumSteps(), 2); QVERIFY(sm->setValueRaw(0, 0, 0.0)); QVERIFY(sm->setValueRaw(0, 1, 0.1)); QVERIFY(sm->setValueRaw(1, 0, 1.0)); QVERIFY(sm->setValueRaw(1, 1, 1.1)); sm->calcNoSpikeRange(0); QCOMPARE(sm->minValueNoSpike(), 0.0); QCOMPARE(sm->maxValueNoSpike(), 0.0); sm->calcNoSpikeRange(-100); QCOMPARE(sm->minValueNoSpike(), 0.0); QCOMPARE(sm->maxValueNoSpike(), 0.0); sm->calcNoSpikeRange(0.9); QVERIFY(sm->minValueNoSpike() >= 1E+300 ); QVERIFY(sm->maxValueNoSpike() <= -1E+300); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestMatrix) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testeditablematrix.h000644 001750 001750 00000002320 11544160206 020076 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTEDITABLEMATRIX_H #define TESTEDITABLEMATRIX_H #include #include class TestEditableMatrix : public QObject { Q_OBJECT private: QDomDocument makeDOMElement(const QString& tag, const int nx, const int ny, const double xmin, const double ymin, const double xstep, const double ystep, const int dataSize); private Q_SLOTS: void cleanupTestCase(); void testEditableMatrix(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testeditablematrix.cpp000644 001750 001750 00000022754 11544160206 020446 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testeditablematrix.h" #include #include #include #include #include static Kst::ObjectStore _store; void TestEditableMatrix::cleanupTestCase() { _store.clear(); } QDomDocument TestEditableMatrix::makeDOMElement(const QString& tag, const int nx, const int ny, const double xmin, const double ymin, const double xstep, const double ystep, const int dataSize) { // Should be some boundary checking in the constructor. QDomDocument amDOM("amdocument"); QDomElement amElement, child, dataset; QDomText text; amElement = amDOM.createElement("amDOMTest"); child = amDOM.createElement("tag"); text = amDOM.createTextNode(tag); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("nx"); text = amDOM.createTextNode(QString::number(nx)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("ny"); text = amDOM.createTextNode(QString::number(ny)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("xmin"); text = amDOM.createTextNode(QString::number(xmin)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("ymin"); text = amDOM.createTextNode(QString::number(ymin)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("xstep"); text = amDOM.createTextNode(QString::number(xstep)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("ystep"); text = amDOM.createTextNode(QString::number(ystep)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("data"); QByteArray qba; qba.reserve(dataSize*sizeof(double)); QDataStream qds(&qba, QIODevice::WriteOnly); for (int i = 0; i < dataSize; i++) { qds << 1.1; } text = amDOM.createTextNode(QString(qCompress(qba).toBase64())); child.appendChild(text); amElement.appendChild(child); amDOM.appendChild(amElement); return amDOM; } void TestEditableMatrix::testEditableMatrix() { bool ok = true; //FIXME: dom based constructor no longer used in kst. Use a factory instead // QDomNode n = makeDOMElement("amDOM", 0, 0, 0, 0, 1, 1, 9).firstChild(); // QDomElement e = n.toElement(); // // //basic default constructor values // Kst::EditableMatrixPtr am1 = Kst::kst_cast(_store.createObject(e)); // QVERIFY(am1->tag().tagString().startsWith("amDOM")); // QCOMPARE(am1->sampleCount(), 0); // QCOMPARE(am1->minValue(), 0.0); // QCOMPARE(am1->maxValue(), 0.0); // QCOMPARE(am1->value(0, 0, &ok), 0.0); // QVERIFY(!ok); // QCOMPARE(am1->value(10, 10, &ok), 0.0); //should be outside the boundaries. // QVERIFY(!ok); // QCOMPARE(am1->sampleCount(), 0); // QCOMPARE(am1->meanValue(), 0.0); //basic symmetrical matrix // n = makeDOMElement("Symmetrical", 3, 3, 0, 0, 1, 1, 9).firstChild(); // e = n.toElement(); // // //basic default constructor values // Kst::EditableMatrixPtr am2 = Kst::kst_cast(_store.createObject(e)); // // QCOMPARE(am2->tag().tagString(), QLatin1String("Symmetrical")); // QVERIFY(am2->resize(3, 3, true)); // // for(int i =0 ; i < 3; i++){ // for(int j = 0; j < 3; j++){ // QCOMPARE(am2->value(i, j, &ok), 1.1); // QVERIFY(ok); // } // } // // QVERIFY(am2->editable()); // QCOMPARE(am2->xNumSteps(), 3); // QCOMPARE(am2->yNumSteps(), 3); // QCOMPARE(am2->minX(), 0.0); // QCOMPARE(am2->minY(), 0.0); // QCOMPARE(am2->xStepSize(), 1.0); // QCOMPARE(am2->yStepSize(), 1.0); // QCOMPARE(am2->sampleCount(), 9); // // QVERIFY(am2->setValueRaw(1, 1, 5)); // ok = true; // QCOMPARE(am2->value(1, 1, &ok), 5.0); // QVERIFY(ok); // // am2->blank(); // // am2->change(3, 3, 0, 0, 0, 0); //should not be legal // QCOMPARE(am2->xNumSteps(), 3); // QCOMPARE(am2->yNumSteps(), 3); // QCOMPARE(am2->minX(), 0.0); // QCOMPARE(am2->minY(), 0.0); // QCOMPARE(am2->xStepSize(), 0.0); // QCOMPARE(am2->yStepSize(), 0.0); // QCOMPARE(am2->sampleCount(), 9); // // QVERIFY(!am2->setValue(0, 0, 1)); // ok = true; // QCOMPARE(am2->value(0, 0, &ok), 0.0); // QVERIFY(!ok); // // QVERIFY(!am2->setValue(1, 1, 5.0)); // QVERIFY(am2->value(1, 1) != 5.0); // QVERIFY(am2->setValueRaw(2, 2, 6.0)); //fails Kst::EditableMatrixPtr um1 = Kst::kst_cast(_store.createObject()); Q_ASSERT(um1); um1->resize(3, 3, true); um1->setEditable(true); QVERIFY(um1->setValue(0, 0, 1)); QVERIFY(um1->setValue(1, 1, 1)); QVERIFY(um1->setValue(2, 2, 1)); QCOMPARE(um1->value(0, 0, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(0, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(0, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 1, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(1, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 2, &ok), 1.0); QVERIFY(ok); QVERIFY(um1->resize(3, 3, false)); um1->zero(); QCOMPARE(um1->value(0, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(0, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(0, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 2, &ok), 0.0); QVERIFY(ok); QVERIFY(um1->setValue(0, 0, 1)); QVERIFY(um1->setValue(1, 1, 1)); QVERIFY(um1->setValue(2, 2, 1)); QVERIFY(um1->resize(2, 2, false)); QCOMPARE(um1->sampleCount(), 4); QCOMPARE(um1->value(0, 0, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(0, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(0, 2, &ok), 0.0); QVERIFY(!ok); QCOMPARE(um1->value(1, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 1, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(1, 2, &ok), 0.0); QVERIFY(!ok); QVERIFY(um1->resize(4, 4, true)); QCOMPARE(um1->value(0, 0, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(0, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(0, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(0, 3, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 1, &ok), 1.0); QVERIFY(ok); QCOMPARE(um1->value(1, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(1, 3, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(2, 3, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(3, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(3, 1, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(3, 2, &ok), 0.0); QVERIFY(ok); QCOMPARE(um1->value(3, 3, &ok), 0.0); QVERIFY(ok); QVERIFY(um1->resize(3, 3, false)); QVERIFY(um1->setValue(0, 0, 1.716299)); QVERIFY(um1->setValue(0, 1, -0.485527)); QVERIFY(um1->setValue(0, 2, -0.288690)); QVERIFY(um1->setValue(1, 0, 1.716299)); QVERIFY(um1->setValue(1, 1, NAN)); QVERIFY(um1->setValue(1, 2, -0.274957)); QVERIFY(um1->setValue(2, 0, 1.711721)); QVERIFY(um1->setValue(2, 1, -0.485527)); QVERIFY(um1->setValue(2, 2, -0.293267)); QCOMPARE(um1->value(0, 0), 1.716299); QCOMPARE(um1->value(0, 1), -0.485527); QCOMPARE(um1->value(0, 2), -0.288690); QCOMPARE(um1->value(1, 0), 1.716299); QCOMPARE(um1->value(1, 1), 0.0); QCOMPARE(um1->value(1, 2), -0.274957); QCOMPARE(um1->value(2, 0), 1.711721); QCOMPARE(um1->value(2, 1), -0.485527); QCOMPARE(um1->value(2, 2), -0.293267); QCOMPARE(um1->minValue(), 0.0); QCOMPARE(um1->maxValue(), 0.0); Kst::EditableMatrixPtr sm = Kst::kst_cast(_store.createObject()); Q_ASSERT(sm); sm->change(2, 2, 0.0, 0.0, 1.0, 1.0); sm->setEditable(true); QVERIFY(sm->resize(2, 2, false)); QCOMPARE(sm->xNumSteps(), 2); QCOMPARE(sm->yNumSteps(), 2); QVERIFY(sm->setValueRaw(0, 0, 0.0)); QVERIFY(sm->setValueRaw(0, 1, 0.1)); QVERIFY(sm->setValueRaw(1, 0, 1.0)); QVERIFY(sm->setValueRaw(1, 1, 1.1)); sm->calcNoSpikeRange(0); QCOMPARE(sm->minValueNoSpike(), 0.0); QCOMPARE(sm->maxValueNoSpike(), 0.0); sm->calcNoSpikeRange(-100); QCOMPARE(sm->minValueNoSpike(), 0.0); QCOMPARE(sm->maxValueNoSpike(), 0.0); sm->calcNoSpikeRange(0.9); QVERIFY(sm->minValueNoSpike() >= 1E+300 ); QVERIFY(sm->maxValueNoSpike() <= -1E+300); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestEditableMatrix) #endif kst-2.0.3/tests/testlabelparser.h000644 001750 001750 00000002252 11544160206 017400 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTLABELPARSER_H #define TESTLABELPARSER_H #include #include class TestLabelParser : public QObject { Q_OBJECT private: void dumpAttributes(Label::Chunk *l, QString indent); void dumpTree(Label::Chunk *l, QString indent = ""); void dumpTree(Label::Parsed *l); private Q_SLOTS: void cleanupTestCase(); void testLabelParser(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testeqparser.h000644 001750 001750 00000002321 11544160206 016723 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTEQPARSER_H #define TESTEQPARSER_H #include class TestEqParser : public QObject { Q_OBJECT private: bool validateText(const char *equation, const char *expect); bool validateParserFailures(const char *equation); bool validateEquation(const char *equation, double x, double result, const double tol = 0.00000000001); private Q_SLOTS: void cleanupTestCase(); void testEqParser(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testgeneratedvector.h000644 001750 001750 00000001774 11544160206 020275 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTGENERATEVECTOR_H #define TESTGENERATEVECTOR_H #include class TestGeneratedVector : public QObject { Q_OBJECT private Q_SLOTS: void cleanupTestCase(); void testGeneratedVector(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/dirfile_maker/dirfile_maker.pro000644 001750 001750 00000000544 11544160206 022151 0ustar00synthsynth000000 000000 TOPOUT_REL=../.. include($$PWD/$$TOPOUT_REL/kst.pri) TEMPLATE = app TARGET = $$kstlib(dirfile_maker_new) DESTDIR = $$OUTPUT_DIR/bin CONFIG -= precompile_header windows CONFIG += console QT -= core xml gui !isEmpty(INSTALL_PREFIX) { target.path = $$INSTALL_PREFIX/bin INSTALLS += target } INCLUDEPATH += LIBS += SOURCES += dirfile_maker_new.c kst-2.0.3/tests/dirfile_maker/dirfile_maker_new.c000644 001750 001750 00000005232 11544160206 022443 0ustar00synthsynth000000 000000 #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #define mkdir(x, y) mkdir(x) #endif struct DFEntryType { char field[17]; int spf; int fp; char filename[150]; }; int main(int argc, char *argv[]) { char dirfilename[120]; char tmpstr[150]; FILE *fpf; int i, count = 0; float x; int frameTypes = 10; int maxFrames = -1; int delay = 0; if (argc > 1) { frameTypes = atoi(argv[1]); printf("Requested Frame Types of %d\n", frameTypes); } else { printf("Frame Type count not specified, defaulting to 10 types\n"); } if (argc > 2) { maxFrames = atoi(argv[2]); printf("Requested maximum frames of %d\n", maxFrames); } else { printf("No Maximum frame count specified, running until aborted\n"); } if (argc > 3) { delay = atoi(argv[3]); printf("Delay between updates is %d ms\n", delay); } else if (maxFrames == -1) { delay = 50; printf("No Delay specified, and no max frames, defaulting to 200 ms\n"); } else { printf("No Delay specified running without delay\n"); } //struct DFEntryType dfList2[frameTypes]; struct DFEntryType dfList[frameTypes]; for (i=0; i #include #include #include #include #include #include struct DFEntryType { char field[17]; int spf; int fp; char type; }; #define NDF 15 #define SCOUNT 0 #define FCOUNT 1 #define SINE 2 #define SSINE 3 #define COS 4 #define TIME 5 #define EXTRA 6 struct DFEntryType df[NDF] = { {"scount", 1, -1, 'f'}, {"fcount", 20, -1, 'f'}, {"sine", 20, -1, 'f'}, {"ssine", 1, -1, 'f'}, {"cos", 20, -1, 'f'}, {"time", 20, -1, 'd'}, {"E0", 20, -1, 'f'}, {"E1", 20, -1, 'f'}, {"E2", 20, -1, 'f'}, {"E3", 20, -1, 'f'}, {"E4", 20, -1, 'f'}, {"E5_test", 20, -1, 'f'}, {"E6_test", 20, -1, 'f'}, {"E7[m]", 20, -1, 'f'}, {"E8^2", 20, -1, 'f'} }; int main() { char dirfilename[120]; char tmpstr[150]; FILE *fpf; int i, count = 0; int j; float x; double dx; struct timeval tv; sprintf(dirfilename, "%d.dm", time(NULL)); printf("Writing dirfile %s\n", dirfilename); printf("The fields are:\n"); for (i=0; i class TestHistogram : public QObject { Q_OBJECT private Q_SLOTS: void cleanupTestCase(); void testHistogram(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testvector.cpp000644 001750 001750 00000004234 11544160206 016743 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testvector.h" #include #include #include #include "ksttest.h" static Kst::ObjectStore _store; void TestVector::cleanupTestCase() { _store.clear(); } void TestVector::testVector() { Kst::VectorPtr v1 = Kst::kst_cast(_store.createObject()); QCOMPARE(v1->length(), 1); QCOMPARE(v1->value(0), &Kst::NOPOINT); Q_ASSERT(v1); v1->resize(15); QCOMPARE(v1->length(), 15); v1->zero(); for (int i = 0; i < 15; ++i) { QCOMPARE(v1->value()[i], 0.0); } QVERIFY(!v1->isScalarList()); v1->value()[0] = -42; v1->resize(3); QCOMPARE(v1->length(), 3); QCOMPARE(v1->value()[0], -42.0); Kst::VectorPtr v2 = Kst::kst_cast(_store.createObject()); Q_ASSERT(v2); QCOMPARE(v2->length(), 1); v2 = Kst::kst_cast(_store.createObject()); v2->resize(1); QCOMPARE(v2->length(), 1); v2 = Kst::kst_cast(_store.createObject()); v2->resize(2); QCOMPARE(v2->length(), 2); v2->resize(3); double *data = v2->value(); data[0] = 1; data[1] = 2; data[2] = 3; QCOMPARE(v2->interpolate(0, 5), 1.0); QCOMPARE(v2->interpolate(1, 5), 1.5); QCOMPARE(v2->interpolate(2, 5), 2.0); QCOMPARE(v2->interpolate(3, 5), 2.5); QCOMPARE(v2->interpolate(4, 5), 3.0); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestVector) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testdatamatrix.h000644 001750 001750 00000001752 11544160206 017246 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTDATAMATRIX_H #define TESTDATAMATRIX_H #include class TestDataMatrix : public QObject { Q_OBJECT private Q_SLOTS: void cleanupTestCase(); void testDataMatrix(); }; #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testhistogram.cpp000644 001750 001750 00000010314 11544160206 017432 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testhistogram.h" #include #include #include #include #include static Kst::ObjectStore _store; void TestHistogram::cleanupTestCase() { _store.clear(); } void TestHistogram::testHistogram() { Kst::GeneratedVectorPtr gvp = Kst::kst_cast(_store.createObject()); Q_ASSERT(gvp); QCOMPARE(gvp->length(), 1); gvp->changeRange(0, 10, 100); QCOMPARE(gvp->max(), 0.0); QCOMPARE(gvp->length(), 100); gvp->internalUpdate(); QCOMPARE(gvp->max(), 10.0); QCOMPARE(gvp->length(), 100); Kst::VectorPtr vp(gvp); QCOMPARE(vp->max(), 10.0); Kst::HistogramPtr h1 = Kst::kst_cast(_store.createObject()); h1->change(vp, 0, 10, 10, Kst::Histogram::Number); QVERIFY(!h1->realTimeAutoBin()); // should be false by default QCOMPARE(h1->numberOfBins(), 10); h1->writeLock(); h1->internalUpdate(); h1->unlock(); QCOMPARE(h1->vMin(), 0.0); QCOMPARE(h1->vMax(), 10.0); QCOMPARE(h1->vNumSamples(), 100); int count = 0; for (int i=0; i<10; i++) { count += int(h1->vY()->value(i)); } h1->setRealTimeAutoBin(true); QVERIFY(h1->realTimeAutoBin()); //dumpPoints(h1, 10); QCOMPARE(count, 100); // should account for the whole vector h1->setNumberOfBins(11); QVERIFY(!h1->realTimeAutoBin()); QCOMPARE(h1->numberOfBins(), 11); QCOMPARE(h1->vMin(), 0.0); QCOMPARE(h1->vMax(), 10.0); QCOMPARE(h1->vNumSamples(), 100); h1->writeLock(); h1->internalUpdate(); h1->unlock(); count = 0; for (int i=0; i<11; i++) { count += int(h1->vY()->value(i)); } //dumpPoints(h1, 11); QCOMPARE(count, 100); // should still account for the whole vector h1->setNumberOfBins(9); QCOMPARE(h1->numberOfBins(), 9); QCOMPARE(h1->vMin(), 0.0); QCOMPARE(h1->vMax(), 10.0); QCOMPARE(h1->vNumSamples(), 100); h1->writeLock(); h1->internalUpdate(); h1->unlock(); count = 0; for (int i=0; i<9; i++) { count += int(h1->vY()->value(i)); } //dumpPoints(h1, 9); QCOMPARE(count, 100); // should still account for the whole vector // min > max h1 = Kst::kst_cast(_store.createObject()); h1->change(vp, 10, 0, 10, Kst::Histogram::Number); QCOMPARE(h1->numberOfBins(), 10); QCOMPARE(h1->xMin(), 0.0); QCOMPARE(h1->xMax(), 10.0); QCOMPARE(h1->vMin(), 0.0); QCOMPARE(h1->vMax(), 10.0); QCOMPARE(h1->vNumSamples(), 100); // min == max h1 = Kst::kst_cast(_store.createObject()); h1->change(vp, 10, 10, 2, Kst::Histogram::Number); QCOMPARE(h1->numberOfBins(), 2); QCOMPARE(h1->xMin(), 9.0); QCOMPARE(h1->xMax(), 11.0); QCOMPARE(h1->vMin(), 0.0); QCOMPARE(h1->vMax(), 10.0); QCOMPARE(h1->vNumSamples(), 100); // max < min h1 = Kst::kst_cast(_store.createObject()); h1->change(vp, 11, 9, 1, Kst::Histogram::Number); QCOMPARE(h1->numberOfBins(), 2); QCOMPARE(h1->xMax(), 11.0); QCOMPARE(h1->xMin(), 9.0); QCOMPARE(h1->vMin(), 0.0); QCOMPARE(h1->vMax(), 10.0); QCOMPARE(h1->vNumSamples(), 100); // set to max == min h1->setXRange(10, 10); QCOMPARE(h1->xMin(), 9.0); QCOMPARE(h1->xMax(), 11.0); // set to max > min h1->setXRange(1,2); QCOMPARE(h1->xMax() - h1->xMin(), 1.0); h1->setXRange(8, 10); QCOMPARE(h1->xMin(), 8.0); QCOMPARE(h1->xMax(), 10.0); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestHistogram) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/HOWTO000644 001750 001750 00000001041 11544160206 014651 0ustar00synthsynth000000 000000 This testsuite is based on QTestLib from Trolltech. To add a test just create a new class called TestFoo and add this class to main.cpp. You can use TestVector as a pretty good example of how to do this. Here are some nice links to learn more about QTestLib: ############# QTESTLIB MANUAL ############# 1) http://doc.trolltech.com/4.3/qtestlib-manual.html ############# GREAT TUTORIAL ############# 2) http://techbase.kde.org/Development/Tutorials/Unittests ############# QTEST DOCS ############# 3) http://doc.trolltech.com/4.3/qtest.htmlkst-2.0.3/tests/testeqparser.cpp000644 001750 001750 00000064726 11544160206 017277 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testeqparser.h" #include #include #include #include #include #include #include KSTMATH_EXPORT extern /*"C"*/ int yyparse(Kst::ObjectStore *store); KSTMATH_EXPORT extern /*"C"*/ void *ParsedEquation; KSTMATH_EXPORT extern /*"C"*/ struct yy_buffer_state *yy_scan_string(const char*); bool optimizerFailed = false; Kst::VectorMap vectorsUsed; Kst::VectorPtr xVector; #include #include static Kst::ObjectStore _store; double _NOPOINT = NAN; void TestEqParser::cleanupTestCase() { xVector = 0L; vectorsUsed.clear(); _store.clear(); } bool TestEqParser::validateText(const char *equation, const char *expect) { bool failure = false; QString txt; yy_scan_string(equation); int rc = yyparse(&_store); if (rc == 0) { vectorsUsed.clear(); Equations::Node *eq = static_cast(ParsedEquation); if (!eq) return false; ParsedEquation = 0L; //eq->collectVectors(vectorsUsed); txt = eq->text(); failure = txt != expect; delete eq; } else { // Parse error delete (Equations::Node*)ParsedEquation; ParsedEquation = 0L; failure = true; } if (failure) { if (!Equations::errorStack.isEmpty()) { printf("Failures on [%s] -------------------------\n", equation); for (QStringList::ConstIterator i = Equations::errorStack.constBegin(); i != Equations::errorStack.constEnd(); ++i) { printf("%s\n", (*i).toLatin1().data()); } printf("------------------------------------------\n"); } else { printf("Got [%s], expected [%s]\n", txt.toLatin1().data(), expect); } } return !failure; } bool TestEqParser::validateEquation(const char *equation, double x, double result, const double tol) { yy_scan_string(equation); int rc = yyparse(&_store); if (rc == 0) { vectorsUsed.clear(); Equations::Node *eq = static_cast(ParsedEquation); if (!eq) return false; ParsedEquation = 0L; Equations::Context ctx; ctx.sampleCount = 2; ctx.noPoint = _NOPOINT; ctx.x = x; ctx.xVector = xVector; if (xVector) { ctx.sampleCount = xVector->length(); } Equations::FoldVisitor vis(&ctx, &eq); if (eq->isConst() && !dynamic_cast(eq)) { if (!optimizerFailed) { optimizerFailed = true; printf("Optimizer bug: found an unoptimized const equation. Optimizing for coverage purposes.\n"); } double v = eq->value(&ctx); delete eq; eq = new Equations::Number(v); } Kst::ScalarMap scm; Kst::StringMap stm; eq->collectObjects(vectorsUsed, scm, stm); eq->update(&ctx); double v = eq->value(&ctx); delete eq; if (fabs(v - result) < tol || (result != result && v != v) || (result == INF && v == INF) || (result == -INF && v == -INF)) { return true; } else { printf("Result: %.16f\n", v); return false; } } else { // Parse error printf("Failures on [%s] -------------------------\n", equation); for (QStringList::ConstIterator i = Equations::errorStack.constBegin(); i != Equations::errorStack.constEnd(); ++i) { printf("%s\n", (*i).toLatin1().data()); } printf("------------------------------------------\n"); delete (Equations::Node*)ParsedEquation; ParsedEquation = 0L; return false; } } bool TestEqParser::validateParserFailures(const char *equation) { bool success = true; yy_scan_string(equation); if (0 == yyparse(&_store)) { printf("Test of (%s) parsing passed, but should have failed.\n", equation); success = false; } else { if (Equations::errorStack.count() == 1 && (Equations::errorStack.first() == "parse error" || Equations::errorStack.first() == "syntax error")) { printf("ERROR: [%s] doesn't have error handling yet!\n", equation); success = false; #ifdef DUMP_FAIL_MSGS } else { printf("Failures on [%s] -------------------------\n", equation); for (QStringList::ConstIterator i = Equations::errorStack.constBegin(); i != Equations::errorStack.constEnd(); ++i) { printf("%s\n", (*i).toLatin1().data()); } printf("------------------------------------------\n"); #endif } } return success; } void TestEqParser::testEqParser() { // Base cases QVERIFY(validateEquation("0", 1.0, 0.0)); QVERIFY(validateEquation("1.0", 2.0, 1.0)); // Basics QVERIFY(validateEquation("x", -1.0, -1.0)); QVERIFY(validateEquation("-x", -1.0, 1.0)); QVERIFY(validateEquation("x^2", -1.0, 1.0)); QVERIFY(validateEquation(" x^2", -1.0, 1.0)); QVERIFY(validateEquation(" x^2 ", -1.0, 1.0)); QVERIFY(validateEquation("x^2 ", -1.0, 1.0)); QVERIFY(validateEquation("x^2 + x^2", -1.0, 2.0)); QVERIFY(validateEquation("y", 0.0, _NOPOINT)); QVERIFY(validateEquation("foo()", 0.0, _NOPOINT)); QVERIFY(validateEquation("foo(1.0, 2.0, 3.0)", 0.0, _NOPOINT)); // Order of evaluation and parser issues QVERIFY(validateEquation("-x^2", 2.0, -4.0)); QVERIFY(validateEquation("(-x)^2", 2.0, 4.0)); QVERIFY(validateEquation("-(x^2)", 2.0, -4.0)); QVERIFY(validateEquation("(-x^2)", 2.0, -4.0)); QVERIFY(validateEquation("x*x+5", 2.0, 9.0)); QVERIFY(validateEquation("5+x*x", 2.0, 9.0)); QVERIFY(validateEquation("5*4/2*5", 1.0, 50.0)); QVERIFY(validateEquation("asin(sin(x))", 3.14159265358979323, 0.0)); QVERIFY(validateEquation("x^(1/2)", 2.0, sqrt(2.0))); QVERIFY(validateEquation("x^(1/2)*2", 2.0, 2.0*sqrt(2.0))); QVERIFY(validateEquation("(1/2)*x^2+3*x-5", 1.0, -1.5)); QVERIFY(validateEquation("2^3^4", 0.0, 2417851639229258349412352.0)); QVERIFY(validateEquation("sin(x)^2", 0.5*3.14159265358979323, 1.0)); QVERIFY(validateEquation("(2)^(3)", 0.0, 8)); QVERIFY(validateEquation("(2*3)^(3*4)", 0.0, 2176782336.0)); QVERIFY(validateEquation("sin(x^2)", sqrt(3.14159265358979323), 0.0)); QVERIFY(validateEquation("5*4/2", 0.0, 10.0)); QVERIFY(validateEquation("5/4*2", 0.0, 2.5)); QVERIFY(validateEquation("10%2", 0.0, 0.0)); QVERIFY(validateEquation("10.5%2", 0.0, 0.5)); QVERIFY(validateEquation("0%2", 0.0, 0.0)); QVERIFY(validateEquation("2%0", 0.0, _NOPOINT)); QVERIFY(validateEquation("--x", 1.0, 1.0)); QVERIFY(validateEquation("--x", -1.0, -1.0)); QVERIFY(validateEquation("---x", -1.0, 1.0)); QVERIFY(validateEquation("---x", 1.0, -1.0)); // Constants QVERIFY(validateEquation("e", 0.0, 2.7128182846)); QVERIFY(validateEquation("pi", 0.0, 3.1415926536)); // Functions QVERIFY(validateEquation("sin()", 0.0, _NOPOINT)); QVERIFY(validateEquation("sin(0.0)", 0.0, 0.0)); QVERIFY(validateEquation("sin(3.14159265358979323)", 0.0, 0.0)); QVERIFY(validateEquation("sin(3.14159265358979323/2.00000000000000000000000000)", 0.0, 1.0)); QVERIFY(validateEquation("cos()", 0.0, _NOPOINT)); QVERIFY(validateEquation("cos(0.0)", 0.0, 1.0)); QVERIFY(validateEquation("cos(3.14159265358979323)", 0.0, -1.0)); QVERIFY(validateEquation("cos(3.14159265358979323/2.00000000000000000000000000)", 0.0, 0.0)); QVERIFY(validateEquation("sec(0.2332744)", 0.0, 1.0278393504553487)); QVERIFY(validateEquation("csc(0.2332744)", 0.0, 4.3259243283703714)); QVERIFY(validateEquation("cot(0.2332744)", 0.0, 4.2087553141976128)); QVERIFY(validateEquation("1/cos(0.2332744)", 0.0, 1.0278393504553487)); QVERIFY(validateEquation("1/sin(0.2332744)", 0.0, 4.3259243283703714)); QVERIFY(validateEquation("1/tan(0.2332744)", 0.0, 4.2087553141976128)); QVERIFY(validateEquation("sec(0.2332744) == 1/cos(0.2332744)", 0.2332744, 1.0)); QVERIFY(validateEquation("csc(0.2332744) == 1/sin(0.2332744)", 0.2332744, 1.0)); QVERIFY(validateEquation("cot(0.2332744) == 1/tan(0.2332744)", 0.2332744, 1.0)); QVERIFY(validateEquation("sec(x) == 1/cos(x)", 0.2332744, 1.0)); QVERIFY(validateEquation("csc(x) == 1/sin(x)", 0.2332744, 1.0)); QVERIFY(validateEquation("cot(x) == 1/tan(x)", 0.2332744, 1.0)); QVERIFY(validateEquation("abs(0.0)", 0.0, 0.0)); QVERIFY(validateEquation("abs(x)", 1.0, 1.0)); QVERIFY(validateEquation("abs(x)", -1.0, 1.0)); QVERIFY(validateEquation("abs(x)", _NOPOINT, _NOPOINT)); QVERIFY(validateEquation("abs(x)", INF, INF)); QVERIFY(validateEquation("abs(x)", -INF, INF)); QVERIFY(validateEquation("abs(-0.000000000001)", 0.0, 0.000000000001)); QVERIFY(validateEquation("cos(acos(x))", 0.3875823288, 0.3875823288, 0.0000000001)); QVERIFY(validateEquation("acos(cos(x))", 2.3875823288, 2.3875823288, 0.0000000001)); QVERIFY(validateEquation("asin(sin(x))", 0.7540103248, 0.7540103248, 0.0000000001)); QVERIFY(validateEquation("sin(asin(x))", 0.3875823288, 0.3875823288, 0.0000000001)); QVERIFY(validateEquation("tan(atan(x))", 2.3875823288, 2.3875823288, 0.0000000001)); QVERIFY(validateEquation("atan(tan(x))", 0.3875823288, 0.3875823288, 0.0000000001)); QVERIFY(validateEquation("sqrt(4) == 2.0", 0.0, 1.0)); QVERIFY(validateEquation("sqrt(0) == 0.0", 0.0, 1.0)); QVERIFY(validateEquation("sqrt(-1)", 0.0, _NOPOINT)); QVERIFY(validateEquation("sqrt(2)", 0.0, 1.4142135623730951)); #ifndef Q_WS_WIN32 QVERIFY(validateEquation("cbrt(0.0) == 0.0", 0.0, 1.0)); QVERIFY(validateEquation("cbrt(8.0) == 2.0", 0.0, 1.0)); QVERIFY(validateEquation("cbrt(-1)", 0.0, -1.0)); QVERIFY(validateEquation("cbrt(2)", 0.0, 1.2599210498948734)); #endif // TODO: cosh, exp, log, ln, sinh, tanh // Expressions / Comparison QVERIFY(validateEquation("0.0>0.0", 0.0, 0.0)); QVERIFY(validateEquation("0.0>=0.0", 0.0, 1.0)); QVERIFY(validateEquation("0.0<0.0", 0.0, 0.0)); QVERIFY(validateEquation("0.0<=0.0", 0.0, 1.0)); QVERIFY(validateEquation("0.0=0.0", 0.0, 1.0)); QVERIFY(validateEquation("0.0!=0.0", 0.0, 0.0)); QVERIFY(validateEquation("1.0!=0.0", 0.0, 1.0)); QVERIFY(validateEquation("sin(1.0)!=sin(0.0)", 0.0, 1.0)); QVERIFY(validateEquation("sin()!=sin()", 0.0, 1.0)); QVERIFY(validateEquation("0.0==0.0", 0.0, 1.0)); QVERIFY(validateEquation("1.0>0.0", 0.0, 1.0)); QVERIFY(validateEquation("1.0>=0.0", 0.0, 1.0)); QVERIFY(validateEquation("0.0>1.0", 0.0, 0.0)); QVERIFY(validateEquation("0.0>=1.0", 0.0, 0.0)); QVERIFY(validateEquation("1.0<0.0", 0.0, 0.0)); QVERIFY(validateEquation("1.0<=0.0", 0.0, 0.0)); QVERIFY(validateEquation("0.0<1.0", 0.0, 1.0)); QVERIFY(validateEquation("0.0<=1.0", 0.0, 1.0)); QVERIFY(validateEquation("(0.0/0.0)==(0.0/0.0)", 0.0, 0.0)); QVERIFY(validateEquation("(0.0/0.0)==(1.0/0.0)", 0.0, 0.0)); QVERIFY(validateEquation("(1.0/0.0)==(1.0/0.0)", 0.0, 1.0)); // INF == INF QVERIFY(validateEquation("(1.0/0.0)==-(1.0/0.0)", 0.0, 0.0)); QVERIFY(validateEquation("(0.0/0.0)==-(1.0/0.0)", 0.0, 0.0)); QVERIFY(validateEquation("(1.0/0.0)==(0.0/0.0)", 0.0, 0.0)); QVERIFY(validateEquation("1&&1", 0.0, 1.0)); QVERIFY(validateEquation("1&&0", 0.0, 0.0)); QVERIFY(validateEquation("0&&1", 0.0, 0.0)); QVERIFY(validateEquation("0&&2", 0.0, 0.0)); QVERIFY(validateEquation("3&&2", 0.0, 1.0)); QVERIFY(validateEquation("1||1", 0.0, 1.0)); QVERIFY(validateEquation("0||1", 0.0, 1.0)); QVERIFY(validateEquation("1||0", 0.0, 1.0)); QVERIFY(validateEquation("0||0", 0.0, 0.0)); QVERIFY(validateEquation("2||4", 0.0, 1.0)); QVERIFY(validateEquation("1||(2&&0)", 0.0, 1.0)); QVERIFY(validateEquation("(1||2)&&0", 0.0, 0.0)); QVERIFY(validateEquation("1||2&&0", 0.0, 1.0)); QVERIFY(validateEquation("2&&0||1", 0.0, 1.0)); QVERIFY(validateEquation("2&&1||0", 0.0, 1.0)); QVERIFY(validateEquation("0||1&&0", 0.0, 0.0)); QVERIFY(validateEquation("1.0 == (1.0 == 1.0)", 0.0, 1.0)); QVERIFY(validateEquation("1.0 != (1.0 == 0.0)", 0.0, 1.0)); QVERIFY(validateEquation("1.0 != (1.0 == 1.0)", 0.0, 0.0)); QVERIFY(validateEquation("0.0 == (1.0 == 0.0)", 0.0, 1.0)); QVERIFY(validateEquation("-1==1", 0.0, 0.0)); QVERIFY(validateEquation("-1==-1", 0.0, 1.0)); QVERIFY(validateEquation("1==-1", 0.0, 0.0)); QVERIFY(validateEquation("1!=-1", 0.0, 1.0)); QVERIFY(validateEquation("-1!=1", 0.0, 1.0)); QVERIFY(validateEquation("-1!=-1", 0.0, 0.0)); QVERIFY(validateEquation("!0.0", 0.0, 1.0)); QVERIFY(validateEquation("!1.0", 0.0, 0.0)); QVERIFY(validateEquation("!-1.0", 0.0, 0.0)); QVERIFY(validateEquation("!2.0", 0.0, 0.0)); QVERIFY(validateEquation("!x", INF, 0.0)); QVERIFY(validateEquation("!x", _NOPOINT, 1.0)); QVERIFY(validateEquation("!(1 > 2)", 0.0, 1.0)); QVERIFY(validateEquation("!1.0 > -1.0", 0.0, 1.0)); // (!1.0) > -1.0 QVERIFY(validateEquation("!!x", 1.0, 1.0)); QVERIFY(validateEquation("!!!x", 1.0, 0.0)); QVERIFY(validateEquation("!!!!x", 1.0, 1.0)); // Bit operations QVERIFY(validateEquation("32&4", 0.0, 0.0)); QVERIFY(validateEquation("32&4|2", 0.0, 2.0)); QVERIFY(validateEquation("32|4&2", 0.0, 0.0)); QVERIFY(validateEquation("32|4", 0.0, 36.0)); QVERIFY(validateEquation("0&257", 0.0, 0.0)); QVERIFY(validateEquation("257&0", 0.0, 0.0)); QVERIFY(validateEquation("257|0", 0.0, 257.0)); QVERIFY(validateEquation("0|257", 0.0, 257.0)); QVERIFY(validateEquation("-1|257", 0.0, -1)); QVERIFY(validateEquation("257|-1", 0.0, -1)); // Scalars Kst::ScalarPtr s = Kst::kst_cast(_store.createObject()); s->setValue(1.0); s->setOrphan(true); s->setDescriptiveName("test1"); s = Kst::kst_cast(_store.createObject()); s->setValue(0.0); s->setOrphan(true); s->setDescriptiveName("test2"); s = Kst::kst_cast(_store.createObject()); s->setValue(-1.0); s->setOrphan(true); s->setDescriptiveName("test3"); s = Kst::kst_cast(_store.createObject()); s->setValue(_NOPOINT); s->setOrphan(true); s->setDescriptiveName("test4"); s = Kst::kst_cast(_store.createObject()); s->setValue(INF); s->setOrphan(true); s->setDescriptiveName("test5"); s = Kst::kst_cast(_store.createObject()); s->setValue(-INF); s->setOrphan(true); s->setDescriptiveName("sdf"); QVERIFY(validateEquation("[test1]", 0.0, 1.0)); QVERIFY(validateEquation("[test4]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[test4] - [test4]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[test4] - [test5]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[test4]*[test5]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[test1 (X1)]", 0.0, 1.0)); QVERIFY(validateEquation("[test4 (X4)]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[test4 (X4)] - [test4 (X4)]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[test4 (X4)] - [test5 (X5)]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[test4 (X4)]*[test5 (X5)]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[X1]", 0.0, 1.0)); QVERIFY(validateEquation("[X4]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[X4] - [X4]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[X4] - [X5]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[X4]*[X5]", 0.0, _NOPOINT)); QVERIFY(validateEquation("[sdf]", 0.0, -INF)); QVERIFY(validateEquation("[=10+10]", 0.0, 20.0)); // Vectors Kst::GeneratedVectorPtr gv = Kst::kst_cast(_store.createObject()); Q_ASSERT(gv); gv->changeRange(0, 1.0, 10); gv->setDescriptiveName("gvector1"); gv = Kst::kst_cast(_store.createObject()); Q_ASSERT(gv); gv->changeRange(0, 1.0, 10); gv->setDescriptiveName("gvector2"); gv = Kst::kst_cast(_store.createObject()); Q_ASSERT(gv); gv->changeRange(1.0, 2.0, 10); gv->setDescriptiveName("gvector3"); gv = Kst::kst_cast(_store.createObject()); Q_ASSERT(gv); gv->changeRange(0, 1.0, 2); gv->setDescriptiveName("gvector4"); gv = Kst::kst_cast(_store.createObject()); Q_ASSERT(gv); gv->changeRange(-1.0, 1.0, 1000); gv->setDescriptiveName("gvector5"); gv = Kst::kst_cast(_store.createObject()); Q_ASSERT(gv); gv->changeRange(-1.0, 1.0, 1000); gv->setDescriptiveName("gvector6"); QVERIFY(validateEquation("[gvector3] - [gvector2]", 0.0, 1.0)); QVERIFY(validateEquation("[gvector3[9]]", 0.0, 2.0)); QVERIFY(validateEquation("[gvector3[5+4]]", 0.0, 2.0)); QVERIFY(validateEquation("[gvector3[]]", 0.0, 1.0)); QVERIFY(validateEquation("2*sin([gvector6])", 0.0, -1.6829419696157930)); QVERIFY(validateEquation("[gvector3 (V3)] - [gvector2 (V2)]", 0.0, 1.0)); QVERIFY(validateEquation("[gvector3 (V3)[9]]", 0.0, 2.0)); QVERIFY(validateEquation("[gvector3 (V3)[5+4]]", 0.0, 2.0)); QVERIFY(validateEquation("[gvector3 (V3)[]]", 0.0, 1.0)); QVERIFY(validateEquation("2*sin([gvector6 (V6)])", 0.0, -1.6829419696157930)); QVERIFY(validateEquation("[V3] - [V2]", 0.0, 1.0)); QVERIFY(validateEquation("[V3[9]]", 0.0, 2.0)); QVERIFY(validateEquation("[V3[5+4]]", 0.0, 2.0)); QVERIFY(validateEquation("[V3[]]", 0.0, 1.0)); QVERIFY(validateEquation("2*sin([V6])", 0.0, -1.6829419696157930)); // TODO: interpolation, more vector combinations // Plugins QEXPECT_FAIL("", "Plugins in equations are not implemented yet", Continue); QVERIFY(validateEquation("2*plugin(bin, [V4], 12)", 1.0, -1.9779779779779778)); QEXPECT_FAIL("", "Plugins in equations are not implemented yet", Continue); QVERIFY(validateEquation("4*plugin(bin, [V4], x)", 5.0, -3.9839839839839839)); QVERIFY(validateEquation("-3*plugin(bin, x, 12)", 2.0, _NOPOINT)); gv = Kst::kst_cast(_store.createObject()); Q_ASSERT(gv); gv->changeRange(0, 100, 2000); xVector = gv; QEXPECT_FAIL("", "Plugins in equations are not implemented yet", Continue); QVERIFY(validateEquation("-3*plugin(bin, x, 12)", 2.0, -0.8254127063531767)); QVERIFY(validateEquation("-3*plugin(bin, y, 12)", 2.0, _NOPOINT)); // TODO: more plugin tests // TODO: float notation // Combinations QVERIFY(validateEquation("1|0&&0", 0.0, 0.0)); QVERIFY(validateEquation("0&&0|1", 0.0, 0.0)); QVERIFY(validateEquation("0&&1|0", 0.0, 0.0)); QVERIFY(validateEquation("0||1&1", 0.0, 1.0)); QVERIFY(validateEquation("0||2&1", 0.0, 0.0)); QVERIFY(validateEquation("2&1||0", 0.0, 0.0)); QVERIFY(validateEquation("1-1||0", 0.0, 0.0)); QVERIFY(validateEquation("2-2||0", 0.0, 0.0)); QVERIFY(validateEquation("0||2-2", 0.0, 0.0)); QVERIFY(validateEquation("8|2*2", 0.0, 12.0)); QVERIFY(validateEquation("2*2|8", 0.0, 12.0)); QVERIFY(validateEquation("[gvector2] > 0.0", 0.0, 0.0)); QVERIFY(validateEquation("[gvector2] > -1.0", 0.0, 1.0)); QVERIFY(validateEquation("[gvector2 (V2)] > 0.0", 0.0, 0.0)); QVERIFY(validateEquation("[gvector2 (V2)] > -1.0", 0.0, 1.0)); QVERIFY(validateEquation("[V2] > 0.0", 0.0, 0.0)); QVERIFY(validateEquation("[V2] > -1.0", 0.0, 1.0)); QVERIFY(validateEquation("-([gvector2]*sin([gvector2]*[gvector3])+[gvector4]*cos([gvector4]*[gvector4]))", 0.0, 0.0)); QVERIFY(validateEquation("[gvector4] * -1", 0.0, 0.0)); QVERIFY(validateEquation("-([gvector2 (V2)]*sin([gvector2 (V2)]*[gvector3 (V3)])+[gvector4 (V4)]*cos([gvector4 (V4)]*[gvector4 (V4)]))", 0.0, 0.0)); QVERIFY(validateEquation("[gvector4 (V4)] * -1", 0.0, 0.0)); QVERIFY(validateEquation("-([V2]*sin([V2]*[V3])+[V4]*cos([V4]*[V4]))", 0.0, 0.0)); QVERIFY(validateEquation("[V4] * -1", 0.0, 0.0)); QVERIFY(validateText("3*x", "3*x")); QVERIFY(validateText("(3*x)", "(3*x)")); QVERIFY(validateText("3*(x)", "3*x")); QVERIFY(validateText("((3*x))", "(3*x)")); QVERIFY(validateText(" ((3 * x)) ", "(3*x)")); QVERIFY(validateText(" ((3 * x)) ", "(3*x)")); QVERIFY(validateText("(-3)", "(-3)")); QVERIFY(validateText("(x)", "x")); QVERIFY(validateText("(3*(-(x+5)))", "(3*(-(x+5)))")); QVERIFY(validateText("(sin((x)))", "sin(x)")); /* Wrap a testcase with this and run bison with -t in order to get a trace * of the parse stack */ #if 0 yydebug = 1; yydebug = 0; #endif // Errors: QVERIFY(validateParserFailures("")); QVERIFY(validateParserFailures(" ")); QVERIFY(validateParserFailures("\t")); QVERIFY(validateParserFailures(" \t \t")); QVERIFY(validateParserFailures("[]")); QVERIFY(validateParserFailures("[[]")); QVERIFY(validateParserFailures("[]]")); QVERIFY(validateParserFailures("]")); QVERIFY(validateParserFailures("[")); QVERIFY(validateParserFailures("][")); QVERIFY(validateParserFailures("[][")); QVERIFY(validateParserFailures("foo(, 3)")); QVERIFY(validateParserFailures("foo(3,)")); QVERIFY(validateParserFailures("foo(3,,5)")); QVERIFY(validateParserFailures("foo([])")); QVERIFY(validateParserFailures("foo(4, [])")); QVERIFY(validateParserFailures("/")); QVERIFY(validateParserFailures("/2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2/")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2//2")); QVERIFY(validateParserFailures("%")); QVERIFY(validateParserFailures("%2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2%")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2%%2")); QVERIFY(validateParserFailures("|")); QVERIFY(validateParserFailures("||")); QVERIFY(validateParserFailures("|2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2|")); QVERIFY(validateParserFailures("||2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2||")); QVERIFY(validateParserFailures("2|||2")); QVERIFY(validateParserFailures("&")); QVERIFY(validateParserFailures("&&")); QVERIFY(validateParserFailures("&2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2&")); QVERIFY(validateParserFailures("&&2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2&&")); QVERIFY(validateParserFailures("2&&&2")); QVERIFY(validateParserFailures("*")); QVERIFY(validateParserFailures("*2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2*")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2**2")); QVERIFY(validateParserFailures("^")); QVERIFY(validateParserFailures("^2")); QVERIFY(validateParserFailures("2^^2")); QVERIFY(validateParserFailures("2^")); QVERIFY(validateParserFailures("+")); QVERIFY(validateParserFailures("+2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2+")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2++2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("-")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2-")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("-2-")); QVERIFY(validateParserFailures("2!")); QVERIFY(validateParserFailures("!")); QVERIFY(validateParserFailures("()")); QVERIFY(validateParserFailures("2()")); QVERIFY(validateParserFailures("()2")); QVERIFY(validateParserFailures("_")); QVERIFY(validateParserFailures("#")); QVERIFY(validateParserFailures("$")); QVERIFY(validateParserFailures(")")); QVERIFY(validateParserFailures("(")); QVERIFY(validateParserFailures(")(")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2&|2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2&&||2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2&&+2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2+&&2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2*&&2")); QVERIFY(validateParserFailures("2&&*2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2<>2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2=<2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2=>2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2><2")); QVERIFY(validateParserFailures("<")); QVERIFY(validateParserFailures("<2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2<")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2<<2")); QVERIFY(validateParserFailures(">")); QVERIFY(validateParserFailures(">2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2>")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2>>2")); QVERIFY(validateParserFailures(">=")); QVERIFY(validateParserFailures(">=2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2>=")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2>=>=2")); QVERIFY(validateParserFailures("<=")); QVERIFY(validateParserFailures("<=2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2<=")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2<=<=2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2<==2")); QVERIFY(validateParserFailures(".")); QVERIFY(validateParserFailures(".2")); QVERIFY(validateParserFailures("2.")); QVERIFY(validateParserFailures(",")); QVERIFY(validateParserFailures(",2")); QEXPECT_FAIL("", "This has always failed", Continue); QVERIFY(validateParserFailures("2,")); // Doesn't give a specific error - how to catch this? QVERIFY(validateParserFailures("2*sin(x")); QVERIFY(validateParserFailures("2*sin(x)()")); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestEqParser) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testscalar.cpp000644 001750 001750 00000010445 11544160206 016707 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testscalar.h" #include #include #include #include #include #include #include #include "updatemanager.h" static Kst::ObjectStore _store; double NOPOINT = NAN; SListener::SListener() : QObject(), _trigger(0) {} SListener::~SListener() {} void SListener::trigger(qint64) { _trigger++; } QDomDocument TestScalar::makeDOMDocument(const QString& tag, const QString& val, bool orphan) { QDomDocument loadTest("scalardocument"); QDomElement scalardoc, child; QDomText text; scalardoc = loadTest.createElement("scalar"); child = loadTest.createElement("tag"); text = loadTest.createTextNode(tag); child.appendChild(text); scalardoc.appendChild(child); child = loadTest.createElement("value"); text = loadTest.createTextNode(val); child.appendChild(text); scalardoc.appendChild(child); if (orphan) { child = loadTest.createElement("orphan"); scalardoc.appendChild(child); } loadTest.appendChild(scalardoc); return loadTest; } void TestScalar::cleanupTestCase() { _store.clear(); } void TestScalar::testScalar() { Kst::ScalarPtr sp = Kst::kst_cast(_store.createObject()); QCOMPARE(sp->value(), 0.0); *sp = 3.1415; QVERIFY(sp->displayable()); QCOMPARE(sp->value(), 3.1415); sp->setValue(2.1415); QCOMPARE(sp->value(), 2.1415); sp->setValue(NOPOINT); QVERIFY(sp->value() != sp->value()); sp->setValue(INF ); QVERIFY(sp->value() == INF); QCOMPARE((*sp = 2.0).value(), 2.0); SListener *listener = new SListener; Kst::UpdateManager::self()->setStore(&_store); QObject::connect(Kst::UpdateManager::self(), SIGNAL(objectsUpdated(qint64)), listener, SLOT(trigger(qint64))); *sp = 3.1415; Kst::UpdateManager::self()->doUpdates(true); QCOMPARE(listener->_trigger, 1); sp->setValue(3.1415); QCOMPARE(listener->_trigger, 1); Kst::UpdateManager::self()->doUpdates(true); QCOMPARE(listener->_trigger, 2); *sp = 1.1415; Kst::UpdateManager::self()->doUpdates(true); QCOMPARE(listener->_trigger, 3); Kst::ScalarPtr sp2 = Kst::kst_cast(_store.createObject()); QVERIFY(sp->displayable()); QVERIFY(sp2->displayable()); // FIXME: This constructor is no longer used - test using the factory // QDomNode n; // QDomElement e; // n = makeDOMDocument("load1", "2.14159265").firstChild(); // e = n.toElement(); // // Kst::ScalarPtr sp3 = new Kst::Scalar(&_store, e); // QCOMPARE(sp3->orphan(), false); // QCOMPARE(sp3->value(), 2.14159265); // QCOMPARE(sp3->tag().tagString(), QLatin1String("load1")); // QVERIFY(sp3->displayable()); // // n = makeDOMDocument("55.4232", "55.4232", true).firstChild(); // e = n.toElement(); // Kst::ScalarPtr sp4 = new Kst::Scalar(&_store, e); // QVERIFY(sp4->orphan()); // QCOMPARE(sp4->value(), 55.4232); // QCOMPARE(sp4->tag().tagString(), QLatin1String("55.4232")); // QVERIFY(!sp4->displayable()); // // n = makeDOMDocument("load2", "NAN").firstChild(); // e = n.toElement(); // sp4 = new Kst::Scalar(&_store, e); // QVERIFY(sp4->value() != sp4->value()); // // n = makeDOMDocument("load3", "INF").firstChild(); // e = n.toElement(); // sp4 = new Kst::Scalar(&_store, e); // // QVERIFY(sp4->value() == INF); // // n = makeDOMDocument("load4", "-INF").firstChild(); // e = n.toElement(); // sp4 = new Kst::Scalar(&_store, e); // // QVERIFY(sp4->value() == -INF); delete listener; } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestScalar) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/tests.pro000644 001750 001750 00000002241 11544160206 015715 0ustar00synthsynth000000 000000 TOPOUT_REL=.. include($$PWD/$$TOPOUT_REL/kst.pri) QT += gui network svg xml opengl macx:CONFIG -= app_bundle CONFIG += qtestlib TEMPLATE = app !win32:OBJECTS_DIR = tmp !win32:MOC_DIR = tmp TARGET = runtests DESTDIR = $$OUTPUT_DIR/bin INCLUDEPATH += \ tmp \ $$TOPLEVELDIR/src/libkst \ $$TOPLEVELDIR/src/libkstmath \ $$TOPLEVELDIR/src/widgets \ $$TOPLEVELDIR/src/libkstapp \ $$OUTPUT_DIR/src/kst/tmp LIBS += \ -L$$OUTPUT_DIR/lib \ -l$$kstlib(kst2app) \ -l$$kstlib(kst2widgets) \ -l$$kstlib(kst2math) \ -l$$kstlib(kst2lib) SOURCES += \ main.cpp \ testeditablematrix.cpp \ testcsd.cpp \ testdatamatrix.cpp \ testdatasource.cpp \ testeqparser.cpp \ testgeneratedmatrix.cpp \ testhistogram.cpp \ testlabelparser.cpp \ testscalar.cpp \ testmatrix.cpp \ testpsd.cpp \ testobjectstore.cpp \ testvector.cpp HEADERS += \ testeditablematrix.h \ testcsd.h \ testdatamatrix.h \ testdatasource.h \ testhistogram.h \ testeqparser.h \ testgeneratedmatrix.h \ testlabelparser.h \ testscalar.h \ testmatrix.h \ testpsd.h \ testobjectstore.h \ testvector.h kst-2.0.3/tests/testgeneratedvector.cpp000644 001750 001750 00000003522 11544160206 020621 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testgeneratedvector.h" #include "generatedvector.h" #include "datasource.h" #include "datacollection.h" #include "objectstore.h" #include #include "ksttest.h" static Kst::ObjectStore _store; void TestGeneratedVector::cleanupTestCase() { _store.clear(); } void TestGeneratedVector::testGeneratedVector() { //basic default constructor values Kst::GeneratedVectorPtr m1 = Kst::kst_cast(_store.createObject()); QCOMPARE(m1->length(), 1); QCOMPARE(m1->min(), 0.0); QCOMPARE(m1->max(), 0.0); QCOMPARE(m1->value(0), &Kst::NOPOINT); QCOMPARE(m1->value(10), 0.0); //should be outside the boundaries. QCOMPARE(m1->mean(), &Kst::NOPOINT); m1->changeRange(0, 100, 100); QCOMPARE(m1->length(), 100); m1->writeLock(); m1->internalUpdate(); m1->unlock(); QCOMPARE(m1->length(), 100); QCOMPARE(m1->min(), 0.0); QCOMPARE(m1->max(), 100.0); QCOMPARE(m1->value(0), 0.0); QCOMPARE(m1->value(99), 100.0); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestGeneratedVector) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testdatamatrix.cpp000644 001750 001750 00000005713 11544160206 017602 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testdatamatrix.h" #include #include "datamatrix.h" #include "datasource.h" #include "math_kst.h" #include "datacollection.h" #include "objectstore.h" #include "datasourcepluginmanager.h" #include static Kst::ObjectStore _store; void TestDataMatrix::cleanupTestCase() { _store.clear(); } void TestDataMatrix::testDataMatrix() { bool ok = true; QStringList _plugins = Kst::DataSourcePluginManager::pluginList(); //basic default constructor values Kst::DataMatrixPtr m1 = Kst::kst_cast(_store.createObject()); QCOMPARE(m1->sampleCount(), 0); QCOMPARE(m1->minValue(), 0.0); QCOMPARE(m1->maxValue(), 0.0); QCOMPARE(m1->value(0, 0, &ok), 0.0); QVERIFY(!ok); QCOMPARE(m1->value(10, 10, &ok), 0.0); //should be outside the boundaries. QVERIFY(!ok); QCOMPARE(m1->meanValue(), 0.0); if (!_plugins.contains("QImage Source Reader")) QSKIP("...couldn't find plugin.", SkipAll); //These tests assume that the image kst.png exists in src/images QString imageFile = QDir::currentPath() + QDir::separator() + QString("src") + QDir::separator() + QString("images") + QDir::separator() + QString("kst.png"); if (!QFile::exists(imageFile)) { QSKIP("...unable to perform test. Image file missing.", SkipAll); } printf("Opening image = %s for test.\n", imageFile.toLatin1().data()); Kst::DataSourcePtr dsp = Kst::DataSourcePluginManager::loadSource(&_store, imageFile); dsp->internalUpdate(); QVERIFY(dsp); QVERIFY(dsp->isValid()); m1->change(dsp, "GRAY", 0, 0, -1, -1, false, false, 1, 0, 0, 1, 1); m1->writeLock(); m1->internalUpdate(); m1->unlock(); QCOMPARE(m1->xNumSteps(), 32); QCOMPARE(m1->yNumSteps(), 32); QCOMPARE(m1->xStepSize(), 1.0); QCOMPARE(m1->yStepSize(), 1.0); QCOMPARE(m1->minX(), 0.0); QCOMPARE(m1->minY(), 0.0); QCOMPARE(m1->minValue(), 0.0); QCOMPARE(m1->maxValue(), 255.0); QCOMPARE(m1->minValuePositive(), 7.0); QCOMPARE(m1->sampleCount(), 1024); QCOMPARE(m1->value(0, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(m1->value(25, 3, &ok), 81.0); QVERIFY(ok); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestDataMatrix) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/fitsimage_testcase/test.fits000644 001750 001750 00006102600 11544160206 021550 0ustar00synthsynth000000 000000 SIMPLE = T / file does conform to FITS standard BITPIX = -32 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 280 / length of data axis 1 NAXIS2 = 210 / length of data axis 2 EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H EXTNAME = 'flux ' / NAME OF CURRENT HDU DATE = '2008-09-26T22:15:36' / file creation date (YYYY-MM-DDThh:mm:ss UT) CRPIX1 = 160. / [px] TANGENT POINT X PIXEL CRPIX2 = 105. / [px] TANGENT POINT Y PIXEL CRVAL1 = 41.5791666666667 / [deg] RA AT TANGENT POINT CRVAL2 = -30.2747222222222 / [deg] DEC AT TANGENT POINT CTYPE1 = 'RA---TAN' / GNOMONIC PROJECTION CTYPE2 = 'DEC--TAN' / GNOMONIC PROJECTION RADECSYS= 'FK5 ' / REFERENCE CO-ORDINATE SYSTEM EQUINOX = 2000. / REFERENCE EQUINOX OF CO-ORDINATE SYSTEM LONGPOLE= 180. / PROJECTION NORTH POLE CDELT1 = -0.00277777777777778 / [deg/px] X AXIS INCREMENT CDELT2 = 0.00277777777777778 / [deg/px] Y AXIS INCREMENT CRUNIT1 = 'deg ' / UNIT OF X AXIS CRUNIT2 = 'deg ' / UNIT OF Y AXIS PC1_1 = 1. / X-X AXIS CO-ORDINATE TRANSFORMATION PC2_2 = 1. / Y-Y AXIS CO-ORDINATE TRANSFORMATION PC1_2 = -0. / X-Y AXIS CO-ORDINATE TRANSFORMATION PC2_1 = 0. / Y-X AXIS CO-ORDINATE TRANSFORMATION BSCALE = 1. / PIXEL VALUE GAIN BZERO = 0. / PIXEL VALUE OFFSET BUNIT = 'MJy/sr ' / UNIT OF PIXEL VALUE COMMENT ========================= COMMENT almagest: BLAST iterative mapmaker, v#644a14sd COMMENT almagest is copyright (C) 2005--2008 D. V. Wiebe COMMENT ITERATION 99 COMMENT SCALAR -8.02603748241242 COMMENT --==--==--==--==--==--==- COMMENT BLAST Data Use Statistics COMMENT Total Pointing Samples 314260 (52.29 minutes) COMMENT Flagged Pointing Samples 432 (0.137%) COMMENT Total Bolometer Samples 41796580 (4.83 bolometer-days) COMMENT Flagged Bolometer Samples 554770 (1.327%) COMMENT ------------------------- COMMENT NoDumpNoiseTODs COMMENT NoDumpTimeStreams COMMENT NoDumpSpecials COMMENT NoClear COMMENT DisableClipping COMMENT PadData COMMENT AutoReChunk 0 COMMENT BinCount 200 COMMENT BinningConstant 2 COMMENT NoCorrelatedNoise COMMENT CorrelationFrequency 0.001000000000000-0.010000000000000 COMMENT CalibSuffix _cp_21_mdt COMMENT DataHoard data.hoard_2006 COMMENT DirFile /mnt/blast06/ COMMENT NoDumpDeltaMaps COMMENT NoDumpNoise COMMENT DumpVarianceMaps COMMENT EquatorialCoords COMMENT FilterFloor 0.000010000000000 COMMENT FixedNoise 10 COMMENT FlagsVersion 10_CBN COMMENT GapFill yep COMMENT HardHighpass 0.000500000000000 COMMENT NoInputNoise COMMENT Iterations 100 COMMENT Lowpass COMMENT MaxFactor 2 COMMENT MapGeometry 280x210+160.000000000000000+105.000000000000000 COMMENT MemoryCheck COMMENT MemSize 2990492 COMMENT OutputName test502 COMMENT PixelSize 10 COMMENT PointingError [0-8] COMMENT PointingOffset 0 COMMENT PointingSolution %c_FK5_23_MV_20_CS COMMENT PolynomialOrder 4 COMMENT PostFactor 2730000 COMMENT PreFactor 3.66300366300366e-07 COMMENT SinglePrecision COMMENT FastRotate COMMENT SavePeriod 10 COMMENT SoftHighpass 0.033000000000000 COMMENT Suffix D_T04_F10_13_DVW COMMENT TangentPoint 2.771944444444444,-30.274722222222220 COMMENT UnifiedFITS COMMENT Unit MJy/sr COMMENT ClearZeroes COMMENT ZeroConstrain -900+^2-x161^2-y105 COMMENT -=-=-=-=-=-=-=-=-=-=-=-=- COMMENT Chunk: 500:0597655:109440 (0.100000000000000) COMMENT Chunk: 501:0597655:109440 (0.100000000000000) COMMENT Chunk: 502:0597655:109440 (0.100000000000000) COMMENT Chunk: 503:0597655:109440 (0.100000000000000) COMMENT Chunk: 504:0597655:109440 (0.100000000000000) COMMENT Chunk: 505:0597655:109440 (0.100000000000000) COMMENT Chunk: 506:0597655:109440 (0.100000000000000) COMMENT Chunk: 507:0597655:109440 (0.100000000000000) COMMENT Chunk: 508:0597655:109440 (0.100000000000000) COMMENT Chunk: 509:0597655:109440 (0.100000000000000) COMMENT Chunk: 511:0597655:109440 (0.100000000000000) COMMENT Chunk: 512:0597655:109440 (0.100000000000000) COMMENT Chunk: 513:0597655:109440 (0.100000000000000) COMMENT Chunk: 514:0597655:109440 (0.100000000000000) COMMENT Chunk: 515:0597655:109440 (0.100000000000000) COMMENT Chunk: 516:0597655:109440 (0.100000000000000) COMMENT Chunk: 517:0597655:109440 (0.100000000000000) COMMENT Chunk: 518:0597655:109440 (0.100000000000000) COMMENT Chunk: 519:0597655:109440 (0.100000000000000) COMMENT Chunk: 520:0597655:109440 (0.100000000000000) COMMENT Chunk: 521:0597655:109440 (0.100000000000000) COMMENT Chunk: 523:0597655:109440 (0.100000000000000) COMMENT Chunk: 601:0597655:109440 (0.100000000000000) COMMENT Chunk: 603:0597655:109440 (0.100000000000000) COMMENT Chunk: 604:0597655:109440 (0.100000000000000) COMMENT Chunk: 605:0597655:109440 (0.100000000000000) COMMENT Chunk: 606:0597655:109440 (0.100000000000000) COMMENT Chunk: 607:0597655:109440 (0.100000000000000) COMMENT Chunk: 608:0597655:109440 (0.100000000000000) COMMENT Chunk: 610:0597655:109440 (0.100000000000000) COMMENT Chunk: 611:0597655:109440 (0.100000000000000) COMMENT Chunk: 612:0597655:109440 (0.100000000000000) COMMENT Chunk: 613:0597655:109440 (0.100000000000000) COMMENT Chunk: 614:0597655:109440 (0.100000000000000) COMMENT Chunk: 615:0597655:109440 (0.100000000000000) COMMENT Chunk: 616:0597655:109440 (0.100000000000000) COMMENT Chunk: 617:0597655:109440 (0.100000000000000) COMMENT Chunk: 618:0597655:109440 (0.100000000000000) COMMENT Chunk: 619:0597655:109440 (0.100000000000000) COMMENT Chunk: 620:0597655:109440 (0.100000000000000) COMMENT Chunk: 621:0597655:109440 (0.100000000000000) COMMENT Chunk: 622:0597655:109440 (0.100000000000000) COMMENT Chunk: 623:0597655:109440 (0.100000000000000) COMMENT Chunk: 700:0597655:109440 (0.100000000000000) COMMENT Chunk: 701:0597655:109440 (0.100000000000000) COMMENT Chunk: 702:0597655:109440 (0.100000000000000) COMMENT Chunk: 703:0597655:109440 (0.100000000000000) COMMENT Chunk: 704:0597655:109440 (0.100000000000000) COMMENT Chunk: 705:0597655:109440 (0.100000000000000) COMMENT Chunk: 706:0597655:109440 (0.100000000000000) COMMENT Chunk: 707:0597655:109440 (0.100000000000000) COMMENT Chunk: 708:0597655:109440 (0.100000000000000) COMMENT Chunk: 709:0597655:109440 (0.100000000000000) COMMENT Chunk: 710:0597655:109440 (0.100000000000000) COMMENT Chunk: 711:0597655:109440 (0.100000000000000) COMMENT Chunk: 712:0597655:109440 (0.100000000000000) COMMENT Chunk: 713:0597655:109440 (0.100000000000000) COMMENT Chunk: 714:0597655:109440 (0.100000000000000) COMMENT Chunk: 715:0597655:109440 (0.100000000000000) COMMENT Chunk: 716:0597655:109440 (0.100000000000000) COMMENT Chunk: 717:0597655:109440 (0.100000000000000) COMMENT Chunk: 718:0597655:109440 (0.100000000000000) COMMENT Chunk: 719:0597655:109440 (0.100000000000000) COMMENT Chunk: 720:0597655:109440 (0.100000000000000) COMMENT Chunk: 721:0597655:109440 (0.100000000000000) COMMENT Chunk: 722:0597655:109440 (0.100000000000000) COMMENT Chunk: 723:0597655:109440 (0.100000000000000) COMMENT Chunk: 800:0597655:109440 (0.100000000000000) COMMENT Chunk: 801:0597655:109440 (0.100000000000000) COMMENT Chunk: 802:0597655:109440 (0.100000000000000) COMMENT Chunk: 803:0597655:109440 (0.100000000000000) COMMENT Chunk: 804:0597655:109440 (0.100000000000000) COMMENT Chunk: 805:0597655:109440 (0.100000000000000) COMMENT Chunk: 806:0597655:109440 (0.100000000000000) COMMENT Chunk: 807:0597655:109440 (0.100000000000000) COMMENT Chunk: 808:0597655:109440 (0.100000000000000) COMMENT Chunk: 809:0597655:109440 (0.100000000000000) COMMENT Chunk: 810:0597655:109440 (0.100000000000000) COMMENT Chunk: 811:0597655:109440 (0.100000000000000) COMMENT Chunk: 812:0597655:109440 (0.100000000000000) COMMENT Chunk: 813:0597655:109440 (0.100000000000000) COMMENT Chunk: 814:0597655:109440 (0.100000000000000) COMMENT Chunk: 815:0597655:109440 (0.100000000000000) COMMENT Chunk: 816:0597655:109440 (0.100000000000000) COMMENT Chunk: 817:0597655:109440 (0.100000000000000) COMMENT Chunk: 818:0597655:109440 (0.100000000000000) COMMENT Chunk: 819:0597655:109440 (0.100000000000000) COMMENT Chunk: 820:0597655:109440 (0.100000000000000) COMMENT Chunk: 822:0597655:109440 (0.100000000000000) COMMENT Chunk: 823:0597655:109440 (0.100000000000000) COMMENT Chunk: 900:0597655:109440 (0.100000000000000) COMMENT Chunk: 901:0597655:109440 (0.100000000000000) COMMENT Chunk: 903:0597655:109440 (0.100000000000000) COMMENT Chunk: 904:0597655:109440 (0.100000000000000) COMMENT Chunk: 905:0597655:109440 (0.100000000000000) COMMENT Chunk: 906:0597655:109440 (0.100000000000000) COMMENT Chunk: 908:0597655:109440 (0.100000000000000) COMMENT Chunk: 909:0597655:109440 (0.100000000000000) COMMENT Chunk: 910:0597655:109440 (0.100000000000000) COMMENT Chunk: 911:0597655:109440 (0.100000000000000) COMMENT Chunk: 912:0597655:109440 (0.100000000000000) COMMENT Chunk: 913:0597655:109440 (0.100000000000000) COMMENT Chunk: 914:0597655:109440 (0.100000000000000) COMMENT Chunk: 915:0597655:109440 (0.100000000000000) COMMENT Chunk: 916:0597655:109440 (0.100000000000000) COMMENT Chunk: 917:0597655:109440 (0.100000000000000) COMMENT Chunk: 918:0597655:109440 (0.100000000000000) COMMENT Chunk: 919:0597655:109440 (0.100000000000000) COMMENT Chunk: 920:0597655:109440 (0.100000000000000) COMMENT Chunk: 921:0597655:109440 (0.100000000000000) COMMENT Chunk: 922:0597655:109440 (0.100000000000000) COMMENT Chunk: 923:0597655:109440 (0.100000000000000) COMMENT Chunk: 1000:0597655:109440 (0.100000000000000) COMMENT Chunk: 1002:0597655:109440 (0.100000000000000) COMMENT Chunk: 1003:0597655:109440 (0.100000000000000) COMMENT Chunk: 1004:0597655:109440 (0.100000000000000) COMMENT Chunk: 1005:0597655:109440 (0.100000000000000) COMMENT Chunk: 1006:0597655:109440 (0.100000000000000) COMMENT Chunk: 1007:0597655:109440 (0.100000000000000) COMMENT Chunk: 1008:0597655:109440 (0.100000000000000) COMMENT Chunk: 1009:0597655:109440 (0.100000000000000) COMMENT Chunk: 1010:0597655:109440 (0.100000000000000) COMMENT Chunk: 1011:0597655:109440 (0.100000000000000) COMMENT Chunk: 1012:0597655:109440 (0.100000000000000) COMMENT Chunk: 1013:0597655:109440 (0.100000000000000) COMMENT Chunk: 1014:0597655:109440 (0.100000000000000) COMMENT Chunk: 1016:0597655:109440 (0.100000000000000) COMMENT Chunk: 1017:0597655:109440 (0.100000000000000) COMMENT Chunk: 1018:0597655:109440 (0.100000000000000) COMMENT Chunk: 1019:0597655:109440 (0.100000000000000) COMMENT Chunk: 1020:0597655:109440 (0.100000000000000) COMMENT Chunk: 1021:0597655:109440 (0.100000000000000) COMMENT Chunk: 1022:0597655:109440 (0.100000000000000) COMMENT Chunk: 500:0740348:204820 (0.100000000000000) COMMENT Chunk: 501:0740348:204820 (0.100000000000000) COMMENT Chunk: 502:0740348:204820 (0.100000000000000) COMMENT Chunk: 503:0740348:204820 (0.100000000000000) COMMENT Chunk: 504:0740348:204820 (0.100000000000000) COMMENT Chunk: 505:0740348:204820 (0.100000000000000) COMMENT Chunk: 506:0740348:204820 (0.100000000000000) COMMENT Chunk: 507:0740348:204820 (0.100000000000000) COMMENT Chunk: 508:0740348:204820 (0.100000000000000) COMMENT Chunk: 509:0740348:204820 (0.100000000000000) COMMENT Chunk: 511:0740348:204820 (0.100000000000000) COMMENT Chunk: 512:0740348:204820 (0.100000000000000) COMMENT Chunk: 513:0740348:204820 (0.100000000000000) COMMENT Chunk: 514:0740348:204820 (0.100000000000000) COMMENT Chunk: 515:0740348:204820 (0.100000000000000) COMMENT Chunk: 516:0740348:204820 (0.100000000000000) COMMENT Chunk: 517:0740348:204820 (0.100000000000000) COMMENT Chunk: 518:0740348:204820 (0.100000000000000) COMMENT Chunk: 519:0740348:204820 (0.100000000000000) COMMENT Chunk: 520:0740348:204820 (0.100000000000000) COMMENT Chunk: 521:0740348:204820 (0.100000000000000) COMMENT Chunk: 523:0740348:204820 (0.100000000000000) COMMENT Chunk: 601:0740348:204820 (0.100000000000000) COMMENT Chunk: 603:0740348:204820 (0.100000000000000) COMMENT Chunk: 604:0740348:204820 (0.100000000000000) COMMENT Chunk: 605:0740348:204820 (0.100000000000000) COMMENT Chunk: 606:0740348:204820 (0.100000000000000) COMMENT Chunk: 607:0740348:204820 (0.100000000000000) COMMENT Chunk: 608:0740348:204820 (0.100000000000000) COMMENT Chunk: 610:0740348:204820 (0.100000000000000) COMMENT Chunk: 611:0740348:204820 (0.100000000000000) COMMENT Chunk: 612:0740348:204820 (0.100000000000000) COMMENT Chunk: 613:0740348:204820 (0.100000000000000) COMMENT Chunk: 614:0740348:204820 (0.100000000000000) COMMENT Chunk: 615:0740348:204820 (0.100000000000000) COMMENT Chunk: 616:0740348:204820 (0.100000000000000) COMMENT Chunk: 617:0740348:204820 (0.100000000000000) COMMENT Chunk: 618:0740348:204820 (0.100000000000000) COMMENT Chunk: 619:0740348:204820 (0.100000000000000) COMMENT Chunk: 620:0740348:204820 (0.100000000000000) COMMENT Chunk: 621:0740348:204820 (0.100000000000000) COMMENT Chunk: 622:0740348:204820 (0.100000000000000) COMMENT Chunk: 623:0740348:204820 (0.100000000000000) COMMENT Chunk: 700:0740348:204820 (0.100000000000000) COMMENT Chunk: 701:0740348:204820 (0.100000000000000) COMMENT Chunk: 702:0740348:204820 (0.100000000000000) COMMENT Chunk: 703:0740348:204820 (0.100000000000000) COMMENT Chunk: 704:0740348:204820 (0.100000000000000) COMMENT Chunk: 705:0740348:204820 (0.100000000000000) COMMENT Chunk: 706:0740348:204820 (0.100000000000000) COMMENT Chunk: 707:0740348:204820 (0.100000000000000) COMMENT Chunk: 708:0740348:204820 (0.100000000000000) COMMENT Chunk: 709:0740348:204820 (0.100000000000000) COMMENT Chunk: 710:0740348:204820 (0.100000000000000) COMMENT Chunk: 711:0740348:204820 (0.100000000000000) COMMENT Chunk: 712:0740348:204820 (0.100000000000000) COMMENT Chunk: 713:0740348:204820 (0.100000000000000) COMMENT Chunk: 714:0740348:204820 (0.100000000000000) COMMENT Chunk: 715:0740348:204820 (0.100000000000000) COMMENT Chunk: 716:0740348:204820 (0.100000000000000) COMMENT Chunk: 717:0740348:204820 (0.100000000000000) COMMENT Chunk: 718:0740348:204820 (0.100000000000000) COMMENT Chunk: 719:0740348:204820 (0.100000000000000) COMMENT Chunk: 720:0740348:204820 (0.100000000000000) COMMENT Chunk: 721:0740348:204820 (0.100000000000000) COMMENT Chunk: 722:0740348:204820 (0.100000000000000) COMMENT Chunk: 723:0740348:204820 (0.100000000000000) COMMENT Chunk: 800:0740348:204820 (0.100000000000000) COMMENT Chunk: 801:0740348:204820 (0.100000000000000) COMMENT Chunk: 802:0740348:204820 (0.100000000000000) COMMENT Chunk: 803:0740348:204820 (0.100000000000000) COMMENT Chunk: 804:0740348:204820 (0.100000000000000) COMMENT Chunk: 805:0740348:204820 (0.100000000000000) COMMENT Chunk: 806:0740348:204820 (0.100000000000000) COMMENT Chunk: 807:0740348:204820 (0.100000000000000) COMMENT Chunk: 808:0740348:204820 (0.100000000000000) COMMENT Chunk: 809:0740348:204820 (0.100000000000000) COMMENT Chunk: 810:0740348:204820 (0.100000000000000) COMMENT Chunk: 811:0740348:204820 (0.100000000000000) COMMENT Chunk: 812:0740348:204820 (0.100000000000000) COMMENT Chunk: 813:0740348:204820 (0.100000000000000) COMMENT Chunk: 814:0740348:204820 (0.100000000000000) COMMENT Chunk: 815:0740348:204820 (0.100000000000000) COMMENT Chunk: 816:0740348:204820 (0.100000000000000) COMMENT Chunk: 817:0740348:204820 (0.100000000000000) COMMENT Chunk: 818:0740348:204820 (0.100000000000000) COMMENT Chunk: 819:0740348:204820 (0.100000000000000) COMMENT Chunk: 820:0740348:204820 (0.100000000000000) COMMENT Chunk: 822:0740348:204820 (0.100000000000000) COMMENT Chunk: 823:0740348:204820 (0.100000000000000) COMMENT Chunk: 900:0740348:204820 (0.100000000000000) COMMENT Chunk: 901:0740348:204820 (0.100000000000000) COMMENT Chunk: 903:0740348:204820 (0.100000000000000) COMMENT Chunk: 904:0740348:204820 (0.100000000000000) COMMENT Chunk: 905:0740348:204820 (0.100000000000000) COMMENT Chunk: 906:0740348:204820 (0.100000000000000) COMMENT Chunk: 908:0740348:204820 (0.100000000000000) COMMENT Chunk: 909:0740348:204820 (0.100000000000000) COMMENT Chunk: 910:0740348:204820 (0.100000000000000) COMMENT Chunk: 911:0740348:204820 (0.100000000000000) COMMENT Chunk: 912:0740348:204820 (0.100000000000000) COMMENT Chunk: 913:0740348:204820 (0.100000000000000) COMMENT Chunk: 914:0740348:204820 (0.100000000000000) COMMENT Chunk: 915:0740348:204820 (0.100000000000000) COMMENT Chunk: 916:0740348:204820 (0.100000000000000) COMMENT Chunk: 917:0740348:204820 (0.100000000000000) COMMENT Chunk: 918:0740348:204820 (0.100000000000000) COMMENT Chunk: 919:0740348:204820 (0.100000000000000) COMMENT Chunk: 920:0740348:204820 (0.100000000000000) COMMENT Chunk: 921:0740348:204820 (0.100000000000000) COMMENT Chunk: 922:0740348:204820 (0.100000000000000) COMMENT Chunk: 923:0740348:204820 (0.100000000000000) COMMENT Chunk: 1000:0740348:204820 (0.100000000000000) COMMENT Chunk: 1002:0740348:204820 (0.100000000000000) COMMENT Chunk: 1003:0740348:204820 (0.100000000000000) COMMENT Chunk: 1004:0740348:204820 (0.100000000000000) COMMENT Chunk: 1005:0740348:204820 (0.100000000000000) COMMENT Chunk: 1006:0740348:204820 (0.100000000000000) COMMENT Chunk: 1007:0740348:204820 (0.100000000000000) COMMENT Chunk: 1008:0740348:204820 (0.100000000000000) COMMENT Chunk: 1009:0740348:204820 (0.100000000000000) COMMENT Chunk: 1010:0740348:204820 (0.100000000000000) COMMENT Chunk: 1011:0740348:204820 (0.100000000000000) COMMENT Chunk: 1012:0740348:204820 (0.100000000000000) COMMENT Chunk: 1013:0740348:204820 (0.100000000000000) COMMENT Chunk: 1014:0740348:204820 (0.100000000000000) COMMENT Chunk: 1016:0740348:204820 (0.100000000000000) COMMENT Chunk: 1017:0740348:204820 (0.100000000000000) COMMENT Chunk: 1018:0740348:204820 (0.100000000000000) COMMENT Chunk: 1019:0740348:204820 (0.100000000000000) COMMENT Chunk: 1020:0740348:204820 (0.100000000000000) COMMENT Chunk: 1021:0740348:204820 (0.100000000000000) COMMENT Chunk: 1022:0740348:204820 (0.100000000000000) COMMENT ========================= END AfiV70U@JGBo{@1|@t?T@c@cU"c3ud S gCA߫@A@P=\@(]A 8?}ADA9@(ۡީP@@KAA@( x @DN@oF`qA,n%;/@TCn7dA8>AY>OgmAs [}qmOHAA~Tt?@?@Z[Z9nC@@!AQiE >A޿D!>cԗM=2 iA2AHBA,G`a0@FA"u>A<Ae[Λ@-@@>|F`@pmEA"@ h|_ @F%TVA%tyܭA 7Ax AV@ckA)@tO@0@d2>@_@NB@ A#@@B"aA~@I- 4Ų@~dN@ [oA3@|»3++i@5IE4?`,FA>- a?V(G\?=tg?A HWAN/@}@|i0dAJY/@ eU@,A@!P@ z@A5h;?X#bʜ?X@A?fAGAƠ0PwA/@ĉߺA-mA6}7/p@\t=@t@@:j/Gy i:Q@SWڭ<) )UAkBAs*Xjif@PAA~r@@rK!to >A B~AraB¸wbaPA,=JIq@򿿷d$$Sg@>ADO|P@7A|BaĢK*+ D#AA0*[gcALA=A >?@A(v@+ rK? >>CO@-S@eY J΋A1=l@x'B/qAFԿZ)" l%As~tOh=?=G[hl@o?(ys@7AA7P@@8oK?N4a@:1s@2bh;m?3Z>#>&U# q%/@kAg;@)V>FgTAW4ڿ|\?n@9eHqargx%APIAN{@A@#>@|Z@Bb@wĎ[Aa/¿kG@H@g@?>>a4@hT@@ UDBgz. @]AP!im>8A`=1U '?@W=@xYwAJ>v5K @Atr@MAoC.D]mA.ou?lA!=ÿ5d [@G?3]#=@E@m@IfA3H>Ⱥ?}Pg,dA aA9mc?l?@xI@ Ԅ?2 b?4>@ļ@^uA y@S,(|S R8Actb@_ q W@q@6=e2d>t!Η?1Gq.\@@9% ?dC@iھh$A# ZH@w@]@Ah?6T@&>STn?F^IC@Q;?֒ٽAA%FN]"4Afo.]BbH][g$AQHRdRª ZA4A|KBv-š.;AҙBy2|pB+0Aa=@ GLY*AQAAk E@ oyA .A5rjѾFD3A }?j)?4on>=j: P%@Fr>14#@]@A%;AbP29c7E@bA_ӡi`@wPl>th@ M@G@ `9@@Z2CIdKGA93?3ozOAi+GA7YA]GZ@@-/@g\9?Qj2?AF?>A?5@t2'AتU|h@ A5A5AA hDB?:@7;@E@'A22־mH\w )ljA@sAA3XBNA; AdA.KAA /A w@ AeXn횯A~϶B7[߿г4ՒA~A2sAy0[K@{)AC=<"e~*]AfCp??n ,?1AJ."BAW!@J:Av@@E:(@I?5#zr@Y±@ۡ`AMX/;AQ0H@\@rA=?S?1R@sj A6AB#"L"ƾ}A5оcrl~?4jUſw@?4em%R^AL8@!dN@/@P` 4P2 ^lAS,)#=W?'?D0?A%@DnؑG@DBA>ǹAArG48(Aul{I[!Ak@~AѕA F&jA AqA]9[A*@eAɥ?U@T iA<<ѣA)@y^\o@I?Co@@lr@?Gۿ]_1pGA;L?*WriX@;?5vw<@,H@t@&?羹Z?&56eWAEv=>+qB@֡ÿ ]?\eh7@F?)A<@@Đ@sL{^P @2dLZ^B*NҲA1PA[@lAw@Em;X'A@qQ@'@@lpۿw@Aʼ@&lb@x?xO$y@g?dBDb>A֌1@(d/A HAFAAA?vAl%6?7?a+jNA?̐&@ΰ)@yu@{A 1s'AD$p $Af-?j]@sJ:AbOAA'֍OA%dA|M>ԀzN 9A0&I4Ae:A@w5 Ud4A5j(b9\{A#ǿΜL#AVR@jw?=AXgsA?O\@WXu@w@;MC24n@?%AmB@ԯA&A@;C@ObA2A@K fA \@eA@g@$P}/H@rH@L{A?&@A7AWsAڢX?>\AB JAmA@}]"@VY:'d4A 17jAwAB/ ?rr$I@T'$?A@{v# ?@B,@:a@@Aːe }@ʑF@?2n%@(/@3ABK?s/@З!e@-G? 53@?^0?A,421?}m@\e _[X@w"@_@h?\Ν>a1@穉@*C?N;T0'Z>*nAA8k@IA*cD/@3h@ҷA!3&>@ @-v$|6g]@߭_@hA S@[@!?HA&uA,>(@K@n^4Ba@A?@oAο /@'d?RwAaNL5A9 J[@n@@>AX\F@A@ZA'TP5@!2AM[wT;@[AAaO"A@!@l@J&AAqA#LTլ6 A0]MvB. A=)_m@fa7\|@}ſ0@oӺ@oz,SA#lAn@@?k&@|q?CH Ή>5&L3GE?@/AK=I?@'Wh0I!+AgYS^@xA6T00zUP@ ? Y@wl? 4Ox"G?m@ ACb(AJ@P54@0@pPǾ3g࿉ @f3c\EktAkR@@^4q$t@Z*@IA/8@ >@>rZ "?BinXoA/ Oe?jA>?N0(Tu!{/?>I`n@1" ?ݗj@zW@`A@U<2p.@]>A @Q9@cŋ($Wb@grKO@佔!q@1?o<AJ1@:{6@K)?]F@q6]2f`AM?ŚA?cGD@2y˨?i@]@OX?D8P@n0X^s@Lp#˜GOR@}6RAʿT)̢l@A(7:5?K@.AA1AAjG?@r44n8A)t@Q6:AA#g+@:Ahp@?q{@1IAj @Q*,1`?@ Bs%]z@ye@?߼@?ۍ@ Y?v#@xsü/.??A@Z&B(@h%?@Kz>Ot "?@})SF^w}@a@E tk@< iG_[݇ߓk9οR|?q@_} =`@hxQ6C?@HU;@I@0b\ɜr!@@Aa7fAxUAv@<@tf(s&rA@~lym>Q?DpY?\wOe;A@NȈD(տ65P@DKR>0V.!>=?XF0]ˍ@?=@e@͸g'=@KJH>&^[@ w(x?pWS)?jXy@v@Dƾ]@0\tg HG3P3A1?"x@>E?3Swhh ?(>_MAA@O"ARe@6ߙ@B@5?@sd#0A C* @> ҶA:Y| ?Tٜ>@@_"@2յ?i@Cۆ$>pAI@?94XAThA8AB۠~@rARAC*Ar_X@|A! 2AtBl]ٮA<@AKBfG30i:|c/AMA;Mq@o@V_Ac#.?t@0>4mq@=Q[?"@o$#x@eA0[mqǿ-e@A@@@%?@ ѽ"@@6@ .AY?@[M?t ?!@nP.@.K\zJ@dZ?* ( @OuP@}1Wtt?׼A@Zن?@_˿Ȟm@-@ֶg?Sc@I@.Bn@m7KQKɾ-j4Wh@#r%+l48cEI7 @.QT@oK?mT>h9$/?p4 FAB@@8yE_?@3\1u4>}x@I2s@;@2A3A4@A:3@%B @@{@{@A| @A"laAVA$@!aqAs_xAB|< =BnB <@QA7A`@AT wA>AHɊ@ЍUMAVUAVۀ~tafA@̾@?mkAkAs | 5T?q&@ 㶡@PSv^g@Iw?@#\g?Gp&cF| @Z;4F' baqHB@-'u@c@'>p2??]e@j bRyG?D@,z#@>n,8?O@짿R\=B?]t~?i?2L?(@;@=(@yʹ;`@4:k>2)@[1@>?aR!e>ʐ?st@@@U52L0@U?4peh?Z@&@=?̯@`>ω@m H@R@[5?B@>~?W?R%)~Is;@D%@wn_@7=@ף A4Zh$,@RD>We?tk@ =;@ *A{1@9f(@g??@lB@`R~YMAi75l"@v~?'j@܄,@4S>@@? @.@Abn7$g?b@d࿻(*!`lACߗ_?j@T%W@"ٷfE̿d!ACAVE@Cm@&A8^@N/RAAʀ@٘Am/mA)<@Xl@ q@vzGUo@=S@uGGſA0 A@^^_AJB?CAX?RAuuAH/@ @d@ ݞ>@\Rг@*r @ٱ>c@(l`@unwB?tNY_5Ծ5/8ή@&x>@֨>@N@\*T ?!@_Fw@MVY[I@vB@@Pw?J@@#SA Y?et[=! ?E~,-l=zQ@?LSL@h?#g;5@)?~>A'@fV@ fHy>{?#@B>'$@UkD>+ 2C?@ed ?}@ Q 67PVV?^@9\yl@.=@|[?Z@`@f*> @ 2:3S?M|@%@ NK @?ǖAyz>^?)D?WR eږ?8d?:?C>@j!D9@^};u-@`>p@< @CH@GU@ V)?QCHv=1?vH^?M @z54*?5x@_L,A_w@L@1g@w@P0[Y~@A9z@>)@;/ѝ,y@ JェCoA(A - AfW@JZAO5p@v9@}=[@ @/.%y@|\;aAK׀k@JR0h@@!AeQ8A1b!AQaZ`i@AWz!GL[\&_X@Mpw+A,->e${@5*@l@88=e\<@G{@x@7¼Od.6b%fo$4 agY@q8@.@B;˓5z۾o?mS6'@@_S??*;3wr@ @,iܿb@wqgA ?o¾=  >ƫqC?=l?IG@D?| ?"c z[Z@q@dwڿ? >Jݏ?㴁& (? o>W/ݿ:@.RUw ?)|C> d!@xM> 1,Ѿ[4@@*"e@@?tQ +@Y+p?d@?5,Gſ>?S R%@nZ@{!?q0;?5q{@@yU @7^@X[Al?|>{?Q?[@=?q_@U-@<h@5ki`(?"v@8NoFz'*@!@N?u@9@L@T@&@T@3]4@M5_0SZ0x@"5{?d?$s1-2A6=w?d@|V=@=P CM^Q@q#EAk@7@4Ɛ@OQ|ôl8AU;?SO/Wh"WL@MA;q!8h@e@j%%?h=ΜA2?dT/@DCA,95+Qwi@ A@p@1@#RA%?+Aƿt>0>1ECANA,@3ڄA*|HQ83ADshft=ꃏAg6X@A@>@&!@G?h*əJ.(@0>%lo9z@l?da L6L@,1Q@R?R9?\S9?n}@+@ ?Uԭ@?ÓcB?`e@B.? >1X|=ܡ1ypp@9L= ۣZgFm>ݵ!HWg@׮e;7@AViU(lV=߿xh+Yָ%@x@ /?ǘ>̢pH?8@7I>mN9@18@C?Ꝡg>+{??BEF E?>]?AhOj@Y휾;@]t@)@ٻv@ C?7@8@8.@]5,@#O@J@KtܞS@]D1@In>U?A me,>"WO,=| V'>;@lk@X=Nc@5[P>_@qp@7\~@ ?BfHm<H@@=@@H>gF@?s.ut+Yz?|[@JD?Z?-hV.wX-=@}@fa#@tAp.?)Q@NYV??@ѥA,@Ag$@ Ap~l@A4h@eZ)/q?m@@mk?ǿ=<)xf@2i?W2HA0%a?WOa eAA9?QA0Kg?:OA8@@῁ 9\=A%[A/@R@?iAC@]}=@u? @AM@& [ɍ?;YygpTA>$?П?Ce솹@-=BxB3@@?Ė?j@Ny@K|?D>~s@`@g@ t4]Ӈ'?8ٿ'y@y>p?Yh?>U:R~@$',T&cr>Eav>fQ-@?f8@D;ٝ v-@PE>j\?H?lF@/Hi}M@A@#T>%* @ f9 r'@>?ѸcG~R?Z2J?񡄾F>@@)@1{q>4 @.ǹoپ-Qs5?_zKB@C,B4-FT@j^@!j?^T$>P?@@[1%T@F(=C>п@@~hM?(?C90 @\@]Sm>#k;@AEJ"A@Ιk< <@?0@Gdѽ)Jeg?Jf V@ir\m@p\&Aj[>?H?W?2uƿ @z%`#-M?~h>Tq@ G^;?E|A8h?@e ?ҴcS?c$\ ?A @w !A!Ќ @4@@L4A?@P^B0P!"Aa?DAmA=2AbRoAqA-StDA?_o~w^Al @5?g?3=W?ZMMA#>8.9!@?W?@7$?lh@ <>O␾)@*s7@Zm? MaڿBk>\4`/??Χ@]ě=㭾>?~8>?{M ?@,Z5@BCTI@ ?iD񿣕=@*:@jVQAn@ ,ƿ}&B@R@v_U@o??p@S?<??]!_?n`U?i/m>@WO1?ۖ1=eOpW[kԧ@(?g&@G@JlBDT0@.|`=@wK? a+j@ G?sʯ@@Kh?3@ ?x@'| @RM>x@@I͌ E@6g$__@b{Q@Ak@@8D@A[6ƿ\>@p?᜿$@d@ @8@ߐxH?y<)>at@3@̕@M"?~?VK1@Hg@@vl@`.C hcSnAŅ=@@mAOuARV0ũ@ tA]zz?P)@s>joA+(T?M]>' jQf%Avw%E@Y@D|@AbA!@RZW9t@ LR;@?26N,@1X '@Ri@Y@}qBξ8-Ai@I>9'1O@%}ApC@ 4CIAj}6"P>UZ:ob>TD?! @@J7"@ / ]:>2j@J@@" ERCBH@@R>6-gx`1/N?N&r=? u? : ?LKĿ92nJ@WV?@Xb۾G ?B_k¿@]CiW=4*?@aX%?o><6@,m7?>`?*Z?>4Yc?˓6@@]¾(#?P7?rbL>Ý?%?J@ow[>=[hd@"?1º@s>O->{@\}T@=lg@@@%gNb?Z;A4PO^@w? @E@(Y?ѓ@AFA@aA7@U?i?*Ak4@;rH o1\?CxuAzi@c@w@QAL#zA?,@V.bjоYf@A.%VA=@,@1U:6C@3' @R AQXA&*@T-4g.AeBAt >i?- ;E?: RAaz`E@GP:~B@@4ʵ@?<ܿr?8<l?9@IBE@@VI9/T4'=ڿȩ SAR|=k?_@fH >Ub%@"Cjn@G?;?LFW]y!?.@'@(@Ҋ?H5@b.@)@I^8\>x)x"_?B$@bĿ 6?@{ 4V?S?b'w>4}?[@,jX%@?@$?Cؽ[?#@!֝!_T > @O@==N?-?TR3>@(F@i@xf5 {?@K8@{t4 @XxPw-a% ?vb@>d??>/sI+x\R 3z ?u @S*(u@\}ο?@kH?@?Ӷ@ t>5 ? @?/p>- |[@@=寿r>_ʆ@fx@x>yX߿em@[G?It?yJ\ ??V_5@@x>*.?q\?"_N@D|)F[@K_@} F^@:lG[I@O?$Nf=n@!@2?+MrS(?ړ[(Y@~:^@ ?KA@ݰ >st@@n࿍|͜}[?@4B,@( ? R@?@i ^ ?nΜx-FX@@AӂbE@O[AF?+^X"P\eDN@F@-NQA R3o:@ jANC?BE&?6(@~?K70)?̊ۿd@$B%@42Y@ >C2@}|5=2= N_FxuAAL?UTƿy>%[@ >hz?;eu3?IK\@3ѿ<0@@F@HD9%?%@?zg?%ѱ>ȍ?ܭ@P?.2dtJ!Q@K CGn?)0Ŀ*n=1?D틿*I-1j"B i4R@#>оA@<5#@?/?C@-.n@,=8\?"^j>=R?f31?9~j;f2@)@c >?@܊>xVky0@Jf?0@i@1?a@kP??PAĕ7-'?.AX1>@7 ?v[l@i9{> ڋ 6 f?aSX5@?,OkO@D>/<ؿ&MH@ H k^$@d`'[=ӽ@?T@+>lr >Yn2"ھ@QFuDcǾ<@,@}s?F>ٿt8,? )?n @tO@\A@6S?==M #DI~?4@>ن?U R'?D_ <C+7?ZK׾υ诵9$*JUy@2ia=qi?"t.>ܵ>q?hS$udq$>kbJ?XWq?uy|j\'@Z@{@J>m@+?蕿r>i־?p! px?1h@Av>TyFf@?d?@t@+?F`?@l ٍ@>?;q?tgƿn>K?ZE$b]oO(@3'b @gk@z@HvR>@ ?@.@@'?c@M>?@U]>_=Ef?8@TU3FIi@ '@@T(@WRi@?AfW{??N!h> S@O6>@6*?'=s@3̯?91?p?8JQ':w@7@&eܮjyh&@{Ylsb@ӥ?.9d`>i& e448N@g:@@"? mGЇ@Ar?޳eQ3?7jyA S$@TAK"r1e5Nx/)C|?[+!@@{?٣g@L\LG "@4?5mp@HwM@ȸ?R[\m;Ӓ@>m>J+@"E?>l⼵hm٠hg@? ?m?E>x_+???޿u{,oĪ^D?bL5ۥ 3Ai׾lw@cO;@㧢$z2 u@ { ?侔Ow>?bi@uҿVH?&2=TK)H#zng?90@ad5?tP=ު)@(&NnIK@V=D5>3UT̅b@3|? I?p}?A@=?y>A˂??x?7s>&e??H~@T2?ƿEx;n@3 ?5B@ V @Pl| hs;t(>wU@&=Y1/@?_X?G=翧$Z\>X@=wH@6)@sX!zrw@@/K!}@$ľ?X`@a&M@K?g5n#$:o? @3U_?3=E<8]@C$?!?K?AK>+K>G4?"?=PAAFx⾝O@σ_!A=;E|6;@o:tT@':c@A @B@yQm-wTy? nA Dы˿ >r'?ƭN ȾDEbAxi@F*L@dc@?` U@jِ?Z}(@>=@ͺZj;FR#.;k >RU?hwRG@ilo@bq=@?$^@WV@c@[l=Ӿ3t{HD1@@9@=:VQx?)a=C@Vp8Lw?e??ǬP w>?iK[A?.@NB?:hC U彤-@k$?@!m7RJ )=h=ۋk@; ?n$i@)`?P>[A@,Iz"FW@L-8\=?ʎOh=Na4dh@qST@S??}@_$@O(AFZ?}>>F€%O`G5@;j@L>8:@޿x%ꢿw>k<>>֒o? ^@3TmVm@?x@P @*@@"D\6W]vI@,@3ZA?A{/_@]~=<"6^ڑ@&fwԿ|8=5|@e@JCA?h{ |@ C G@H#@_AP@XI|񿓱Hv Η+j>-Z$?V>9hF@z@Wj?Ű<1$Y(DKf?@3`>?$6@}@Z*]FL%\'z@O_a@ @ªr?>ҿ#ΕU>}2@?w!@! ?Ɉi?}[?2s@.@.R?kT>o@]?-@(?i"@Uah?lֿ…&_@>i[?D(@Uү=[f?*@Zx@7tb ;5b?Z1 ?i~@U@@q?ʎ2@q5?2@(5G?\ϯAԾ 3؆@N?=<@`]?\= zE4=%,>oWQ??ϕ?[d^@I r$@.Zf@l2@V=3?W*S@g+u4t@*w@%@HRO@% @qN6?A W:$=@UA>MV?w AFi@`+i{?{@J@@rpbc@pu%cgȿL?@3 >@xr?$=oJ@w#ݘf#,@> Tp{Re9^BG q͉@,?oM@zDFx@?uVO@@cL"m7?i ,\>?):hI E?|?yj?Xr?nbz=:U<D$?~?h?E="ǾR^>LͿeP ? @-lBNJc>z>@t*L]@Dxr?8v@a?a5 @ ?=/i'@w?ŠB'q0@F?M@$\l>5@1@Ehֿ@,8Udɏb&D#^Z sӟdl?T@S>Wn?_ @r"?wOi3?q(3@g1d@@D"uN?}?w"S>Y>3R:˿ɿ&o@h?,?{=ˁq?#`KN? ?u1.={{y>%?hxl=f/ hrɁ@r\u2c@^@@Dj@R>q?ڣ5;h??lg?9P8?!;@|f@B/o>$@'_>unѝ@Uy@tsiꭿR@R$C@>wA%R@xb@os9?@%2,V}'@^-@MMkABA?HuE_)H7@@ -@lnA&I!I @x ?\@c?@k@RE&>ܬY@?XᲥ7@ ?eO@J}?ЛٱW?Jm?L^#㿍?U6?&*@IO1t ?4Ǿ?[Nv/9?! B?`>t2?!Ի+'?G@Zc>Ly+@?&K+@k|@N.@'."AD?1/*?8?rT>_Q >RO?B27>AI?ிxW>(-XY@GA@:?MN@F!@PEWJB%zI%- Km-?ܩ ;7?+_>g>2<>0@VoO@/@\\@m??޿ D?>'?>ǰ?AӿӴnT1~(¿ƽ?G*~Ƹ?4@P1g]@r??P>z&"?Zf?"B?@*>i #Y?@&?zÑ@7@RjVO#?xBq+?f@t?=a@a5L"]>> kr?OĿſt@@2`?plѿ*?>l<@>w ?hk} @mֿ}^ ?7@ s~>N"C8A1=?@ &?E*?28b@QPKsm@d{BLy8I@i$".?vF?EA bTFȾݾD?ͣ>\w\sz?@S@AQ?6(@@AlC@B*AœG- ^ @/k% @~#-+AAzArPS?Żd@?l>!>$e?_/@ʷH?w>@W &edHt}^@Lڿˠ(` @Q>*3>GK["?}0'Z }T/Ѫ@@c@H/?<5?g'Fz?a~?j?@)ԣ|<>koT3K?s)D?㥑?>6skH>Ti@)?w p @__%э@$k?u@ ?-sZ)@šE 忦t>Wh?sWQG?@p}Jwo'>g@m_?q?N=.@Wi?zZ@6? >@e?o>>J[Vm$ق>rJ?_QLz^ot?) ,w@6 ̿d۾W@@@s){I@g@2r_@J@uq1R4Pp4?7f@49?@ ??i@#$g>?:lG)>e-J?>??$>?.tE [?v@`r6?vQ2?!OcV?@!@y>E}+#@N?>;f+>)?kr(V? ,?0/?@ @ ݮ`{@P<ֿ> _=2/@xY[@gw@1vm?@?ht>޸ʿ?bU?@ ݽ)@4p" @8:?@OA7 JM?5@@ AEڽz+̹@Q?>dA\X@ԫAqg/ I@w8@@9@$@1Gaii^_@eVi?f@_/okA(U@(l@Zk@o@?%@tTeM|15@@@A:_f6i?2?4@{75*?*]H@߿p(8w>O-z'?@@@d@@MY5?,>K!$>ج@H ZL@G=x?F?N$@s?T:l syR3? @CNc@6?k d?l4ov?2A>C,4???b >U?y@Smʿ+O? [?@39g@~:%^?>@?@E09>\x?ڗ>/J G%3?LV`jPS?҅ ? @0@ο>@Weau?1'9?xp4~bI?A?T䦯@Nv>nw?GYR "?*-_;S?@sC?(!3HgB@>+D@~;?w6?qG @@:^s:L7 $ג@S?ǘHM7F?|@?)z@2jbZ^?-qmy:?!?ӵ?~>ʣ@ԅ.@6/BN*io@/}?2@P@Wwݴqo&@B?@Q@=g@`_ֿm|O>2Gv@63I&Gi!@d…-|@X8Gl?>F@`)TʿjbAU?n:?%5$A8f'@Z@j@\c@@87$TA=s[D@!=@h@?P5>@ ,+M@^? ]:?H>@@@,YUl?:`߆@3|>驾Kʛ, z?ŋ?GƿP@6iԿ@>Wԓ ?$?WmGM -%@ W˕$?B+p?Qd@=@; #D?~cyX>|7@> I@@xs^>3lѾ+k@;L@V;J@&V?(u@W?s-5=Tȿ7@G2kʴ#? [v;? @3>B?6I:ϾՖ>?pN@忴ѿa W@{^@9D>U|`u?z@ai?͚O@6]&?(οj-?'$?ݡ>??[@=0?Y$i??y@ OCt@Brw@>d?=m-?9Q9V?/?6>CGn+M"@+?kb@dű?`ĿSQ?b??ɠ9+NT&V̿ KZ@ս@?t?[r@M@@3?@T?3a?be?S@Q|=h?yKb?.n@@Dӵ?LT?a@؛/@x<>? -fq? G0@U:c =I:@@@ ⸿„?V 7@rt@9)оv@D|u<6?'='@&As&@&2@i)9H@Z@oa2r@?OKAfFd@6J?ũ7rH6{?qA(S@D6A\!}݉*@F)A(@`K?X60@@7'?A"nZl@1?V@-Đx@'3en󭾾@"}@2A S;?0mSx?F[=6G ?7\?,)S?"?`E с-d?={3}?*n?i@!O@"^>] l- ?1 )@eƫþ ?w@ [>g)I=fZ?I? 4`2?*Du?$ >/@:5>ntBg`>|@:s >?C"f?}&r?Dd?^N@T@?#1?i@!j@G9>#?>^͸?@F?m? m #@\8sD?ȕ(ҿ?j@?ڿc$@@f?ge hG,@CмƿwGſ#2T@eljH?,`r9[[ȾCE?b忑3'g>*@#~?|@@==ʵ*0: ?׸af>@8?!?HWY4?\?=_ןH]?OhH#?Q2-V?aWDLem@b?L(A B =AȨ?TK-@y@~0@T!sBLAD{A[ ݃psZ@[u@<@@TV'\@(_S>᠜@&`k+j6_)N. @1??M-?,h"ێC?,?e?.?L;@j~L??O?vd>F@Pr??@?O@/kfoW i=>Z ,@@?#?K!A%&W?}@0cJRQ+ɿ&<@^_?οƿ)Pr?? >ת]yi m?ܾn?ܩ?>bBp?dtܿݜ,@[?#ѿ Tu??nٿ2 @KV^NG5=ؿ@C?2?@?c6Z+N^@/=r6+9@9d_@2@.U6&'? :BYۙ??օD?P?x;'UU[?",@?@?@]N6+^b?e[@Ѐ2īv@7'?Š@VK8@C#?<^>{d?^e@!ә?T0rn?A@?=7)?f?ic?+^T@m@]e @!ɝŨl@lD@ƙ@ gH̯?C9J~o?9t?@ZWG&?@9/؃@A0?@H{,0&F>к@>S`u@x@A@z(@".?'@:ZA,3r@7@m?YcA@@N+A!}{zO@Bb@tfVE Q($@! @ڊDBl>@im:>0Gb?n@-xW6?뿄>?b@.?*ENtSi90L@Bi>?_@>y7r@&@Xo?@eS#?pq?6=@vFL"?Fk?lg?ь@?ſ<~龳V>Dyf6>:Q?<#J@Js߿r5?="r.sڿ3MM?a@:9mS?N?>^e&ũ'k?ǿK?3S>F>f0@1D?%~1c~T (ē@ I(p9dMl￳$?e}k#>(\8Tc@ |?f?7ݼڟ?yT?zInR^>w@HZ ?9?W)><`>++Nj@F*@?P?t?R>N鿋T>>W@o?b?酿9C?K @)~? ?M@Y?mN@5@3m@!@;I?9^?B@$@4??!P?8Ny@`{@J@?Bo"cR-8?-@$S?@T+?Fa^@$5,@k@{@on{@7RVA`PE@5@(0@v@@>>V)AĞ@s@Z\GSΠ۸\iB@S_@yMt وl@#}|=3x-K@P\?>AoVPK?{ @~v@u?­ҾN^:@Ҩh@5)? :q?"X s̿OHY??s7@𾠲?>z1EU@mX?[eTi?6=]?6ׄ>@ؿXe@c?`:s?Ya_t=}=뿿h@"/M>K?ÿ >á0@<˻?I!,iD@{@M5@Bi@n>$sáF?S?%b?g:#?5^~ʿ@~t@?2/?UY=@~?2?Y<,?d@<8!jw>hw>`@(@n?Kf$,?/>!<> :>?{ݾ)@y?_Qx>,@B+@)&?ra:6Z?5V?N,?0<>?oyئw^ixT?_c$z=?[?2io$ʿz쾂>->2:ǨYG?J>Pǿa裿9O@4=Z>h?ɺ?վ@">=;m@? :¿ \߹>?Ș@k]?ٿ.&wfg/??;@_S_?o!?>vq>??<@WZi?{@?i@j?@/I @Bh@vo?@ֺ[j@ @”5@ ;h ?v'=j>-@@^I@2.@LARqA>/jA+8`MBf4vBqW@ `?FDAQ@`@@}ζw]!?m1@^?N@ $c@Y4+8Mރ53Լ;HS>(oÊ>j@ ?@C/)p>P_B'>GVE?I?b5=Tg>eq>?V??7?5h\5>g>@@@@ڿҏ&8>3?6?}0EE?wy?,k} @?I9;M {Ⱦ0?8?K>]ĿgMB8́? ?R-y?=@ 6x?%55?%?%@ i@$@lt}KH@{?g*?ʛt@i X&&Y?@?7M?EJ?I`1?p̿U>V3]>?ҿ}L?Ic@EejfLy?}`??}{cE@GzV/??=/U_@?V*@-y@]56?h𣿜?ܫea>fm[>^L?@u?IO?qzп?i-׿c )%;%@ Vqyt>%{W0=HM?L@8>('K`N}?ӿx>P??J@jW<=(@2@}@l+94@u@?D?  =;?ZUAH;mASN)@ܒADfI@?&|RAJ@O@/;;6?eDP$?¶\@)?@Y>C# pc?A?9?!?G>+2>e?ўS9 N &>UC:CGs@?u=;r>P?E@ϿU>Zsx"x>8@_ ?=sg8>5@Z/'"xO=0?l@+?h>*7$@CZ?Xav ?A@U/މBb]?՜?L>QK!@J:?,3yG!a@`gE2s6ڨ??n??>|@#?#?@H,..)!'?Σ1"}k?ė?5?@:D@GA5߿  d Bc??mۿc[?#w"0-ڡ'?@ []?i5|@+EӃ2@w;O>gG?LH@WtGN¿鲄Kk?pWN4~8'@[.Z> >Q?¥r@'῔dVVOOr? ?|:? J|ɿ6I*+4@+0Z=4W?^?#{?M@1R|O? $ܿ_?H[#&'!@A?Bl['|>ĺ{@ 4s@  ſ.@}?L@hzNF!^@7H@B u*A 1*LAh@ ׾̭@ӻ]@;PA Ar ApIܿs(a>[@l@TM|h>@@byr@3^ݽ،J]?".>R?̿6~>@I(>/s@}>Nuv?E?6@V,!>(`>D?uIɿ?amj{??|㿈 3>:?EVX߽B?],]t@_??p,@ /ڿ;@5Ϳ*h>XK?2C?2a?#KM?Q_s) J-Stn?:>B!5 @'3@fD@:IB։0G; N@,?@AoQf?l>L?vI@1U>wU::>~@ ? ?c^???徏 4>$9@'bJ> !ĿEdD;@-W7>ͱ?=EH>8. ?4R1 ?o>t?t@ 3@163.z>5%?q$? -?&Tn$vy??Ä? q@ @0(a ?".9[? `>Z?0? @nX?T*?JA?8a@ar@r5$^{?N-;K?@>a@?(o"@ U?J_/?@>@a!Ϥ?Hl?}@/9ῆ@+>vϚs?N @{@*IfNS9^@s@X@7I5?z=˿O]@naq@t?.|@z*@ pA]C@@jB-B&A`@F9?bA%~A@)6@Ug@e0D?*@,*BABZ#8q?C5S@d@k@@.-bg`ڍ@B@J~),@bI~1?b?[l?(V?9@ @lZ@[6&3t?T= fF?оͪB? :t]@&??G ('?nz@@ ? >q>v5g?=?Z2?#W@¿d*?3 C > ]??f>4gC71g4>ظq_3χJ?a?D志*?o?W*Y?X3@I?AE->4@o? @1">T?^ Wu?dt?oo@WH +MO@ (@ ??s񌄾% J8?}ʿ5??Ol@>(@%?F@k"*.?%??1g׿'\"?u@Vl|ѿؕ>%<s> *;@T)?̵>z+?TB?1ؾ!c:&>MJ?pg@?[U@^~?[?4?0?|.@92vn>B%?dV=?@@徣ٿ?m@@{U< ݿ՘ݮI7?r&d@1@8?[2=>49W?~>q2s?'?k( 8{Q)z/^?#>p>L?/^@)doLݚ@A>sm/@߅>1?SN?@B.k_?~i@H*Do'!˝?lt(?W)bDӭ>9@@m0F?`?KO<۟=T|ǿ|?Tɑi$?Ѷ%w4/@F_}x>E>(&@ /? 忶mҼOKX >?p@"FH?ű}?=bv:0?څun@W7?8=@%l@?b迤a@w@~ҿ\o@-@p`>a?,(GN@&>MԿ?ԵL-P?|+"#>XfHfX8@, ?? ?v ^?S?錿۫??ᝌ?$>3}?%'(O,@'GJ?O><_?J4=p3`? 7??6q@5q@/>>?!Fy޿kҿ S,A?Û>.R6C@(?0Y;`J~ò?Z?@Ip+>\:3>=}?[|?e6? dBl>s-پ[ ?z?\U%m@v@?tF=eoν׋?A9_h@@Y5@@P9@@ ??ֿkh>MAw;J(@K(q#?>?͢ne\W) @Ŀy0D?@_>? >ښ@H!MzW>=?QU,0A8Խsm7> Wz~?'2A"=4>LW;@j?s=Aj6A KAlA0&A5Lr\@]$A97c?g#=@z[XDϿchxWHÎ u@.׉>^)(ޕ@(?#w='@ZCȿM=^-@ $=hR@X̂2>@.?ړ=wXl@0c?Y?@q3B:`>#y?6DL?̿¿?;=?>V?ܨ??>?2&?@,~&@!(D? q? Bř?Z*?ku ?3H?=ټڿ\{>x@!z%7_wx>׾X='0?V2(?K+@N@#%7S??ۿuRl?@>@:!C|?w`U&=?ܒ? 0?Z@R= uA$Ff(>`}g?zt?T>FDgzq?='Y&??*?䊿"&Fh~@8{J@l2h?Ͽ@1@zt?¦G@C>%l+<FH5Oȉ$?c9<͠???@cwr>\?nn@)h?r?S>Ss@7?maj?4O>Z;>C3 2?>{m:L$>]?}Iw@`̰=P?.@I>9>?F}>>'x?B Ap?@8ܤ՘Ьd4@^?&[@\@ z 7@sE8.@6?>w@e?_iÆ޼)@U̹?⿽G@E ?U@t@54H睿X ?{@?_};l@,T=2"?lRky5= +QA @L[@C@5X%0?LQ@ͱ@"Ci:@d(.@m ͯ?l[@=Y?]@?c>_Y+@?j>6?ʿl@۲xX>x\#@9@ۺ xr l?@:?յ_@}r?g=9N:T`;nJѕvϥ?>ɿU?r9:?T?r"LUi??`2E@e,=^?=Pր{ƽE8Ƽ?+?!@9_Sb5>Y>?}2I?>#QW×D-a6L@#B@tҷ `K? f{ ?Ms>3?r࿍?+/-&TJ?%@*C@ ӿF%WD@w?+U1@~0z-p@H䊾L>^{ӔP?όs>8I/?&(?#%?Hxֿ{ @Nd?E=Z=?_h=^ڬ@y @8淾م@df><`-vZy?n\U˜?JG'@c[;X?ܼ]?(V@*nIa^Ͼ+@15ViI=g? qggĵ'S@\ @!m꿪T@Mp>@W? exB࿄?-DiWEv?<޻("?3{x>V1>[l2rؿnyPp=Lg@I&?.>u.;xZ@CA3 ?-=@>d#g׼@z@ Ծ?]@0>e)@ۆe@|A[eUMAe4i?"Jw8AK?H.YO`YA3ac@\2?G@Y6S \a@?^@@s\@:vg?dU*<@@x@qO?۾e;@f dp=gtT@te?[@@n$@@uVz @8^@@g t?XAV@rp@ P?:?|K D?S/+Կt@B?ݿCTq&?E!2@>vbN@i?@KI@(@4.@*l1?u뿘Q=F?Zu?t%ȿ0 $@K>l(?TdLu`?R?O{Gv/[)0&ٿtGO]?e>5@v^?>㪿9@3r%K?pM?_v>!Wݻ2k?k:j>9Rt ?L R?2?v>@1˵?zaf?@ g?Q>Ƥ?_A4?}T@30׶?ɩ>:=??Ή]?o >Ԉ@F`p?C3?#[$X=8>4@!y̧?O,ISD½?&:?XK?,B>ݿ@/>=ο":Ӿ/9H>' ?8]?$MIa?~Q?Nb]=@2G{KSZ$PK@ V@ Lؿ}C? ?wEmW=>b+_cE3AMȾ0iGk4Q?>)?]@@?-l@ OAT@Z:@ b@L[?@yyA^ټ5?X6?v@ F@2N@.6@.}UN@ko>{s@z|?|A2 j@:jA.A(B8%hTA2RڵA(*;?@يA#@GAk>A.@)Af,@zs?C>^͇S?~ ۿ@ԥѲ7>'*R?><_ÿU>ZyЀͿ`x-:A@? a@??Y@Plw@?:@?J)@U?"f?q4!@?}H?B?ӿc_V/?@V@@14׈~>l"P?6Z??TJ= >!Up9H>.>1D?ڃ?u>̿b`>;b?d>'?[?*Q>8( ϰ?k>f߿?j?9sJݿ2?_)?ֱ?qq?-F@ɧ?bڢ?:>Ko?p5nN@E? ο̌~??1S\?ſ=e?1Zh?K@?[7k?[[@C&c?a?)1?|W@6>>k~{A>$X>??|jL?n?7$&:>޺?:>\L>pS@"u?F@c@!NڽV?@{hǿ@)󿈛@?@#@O@}#EfN?'V@?`Q?(@Jt?$Q@rGi >vjR@?Կ@#QY!ra!?F`gп  @!cEQ?>`A 3@:@x@;?J?a݀@=@WU@ >b=Ⱦ@S:@L! ;?&_MO!@$@3,@)VAP1B0Y= @M@mA@ 8@/^>+2v ?X}jb7?Cک?? +?Y?#?e,Z?@G>Z@F@>ח7>@ gK?fL@btݿv?@(UwL@y=? x;?:/@ ={?G?0OCղ@/@?Ϩ\m "^j?\^u|?e?3? @L]>?iʿ6s>=@/ r8U?6t @пy >ɳb?kl@^=G?}??>vT?J?@ ?t>H?Ŕ:>O[DsF?Lp-DW@ ɛ=@?O"?eg?>朾= @Z>=6u??ZX? S?tHI{"?ɊrFW?@;\@g@ ?CI}?s`n>$]?@3??g>)?'Ж׫??iQ?>Y6׽@=>VB?k@9P ?qf>$1"뿙_?.+\$Uy h@c>]dTrL>޿>V>g@ 垿k{?G(?0>=1>'?1KX> |m?@tm@1?h濕?<Ѿʜ=?d@g?`k?oq?nBP|弼 6"?ݚ?(@]I@P@xlY@N8?0?V';' U@ZK?j?vBhy=A> x}@ӿ]i@& A)a2(?@PAVӿA_+[ɾty|?Szd#w]?I?)I?\'(?9g?_?o?=?ϫu=`?ݘ?P۫>Y ƒ>Upo@ (?by?cD@?*?Ҩ??0 /9?KM?R@(?-:濱r9Dؗ?Ү?=̾;@W>c@4?D@ 6g @ th mW?vQ>&?1HP@gœ?ѿL lQF=? B?S@DA=?+ оvgk _N1a_>?3ҿEhg5D f?֝@ ,iy>Ƅ??*b4&Jg?Օ@?˕w?W̿W@R[@1lE5B?u@A,?> *ߨLfp4@u}E/Qܾ]>֡=>ok~C@'@FS`@m̾E?h@½T֕@j@Z& >@$?у\AvIt?5=R@F>"1?q;'@%96ҺE-T@ ?ג@9??;W@nz?3L?տk0=l5>)@:S?{c>haĄ[_`&y?,:\?zޜ?O9<ͩ7#jT@'KԿ @,Ϳ~q@"A?*@]{Ao@VV@C+@-A%A2? uWKņT(h@nao@t|?A}|TmҿGo#@u*Ej@'@@:0@_=>DD??fá> TI(*dAQ4 @Y@.2g>6ȿ?p'M˄s?V?Xz?@)[>Q%@Maƿ??@.q}A>3?c R^ph?~3Q ?ٕ*?ȽP /4@#@^Nv>X[? :@*?dT?Ͷ?/ ?~9긦??y7ӿ&]>A <#?j9@ I?@Ŀ0C뿒v-@;ݟ>x2?f>@ 6 U@/@7"cEe=PsZ7??=?^u8x?=?l?{vS?~u>~d?iǿF2y@!@%@J(Q@[O@:۽@+?(&T`?w'?g??i?gb??a2@8-\)s?3?M@Vڽ)@?(bQ>죓{J}v俲Xe?C5e?oz?g,\?bϿ*>׽(@00@Htgiyq4!?'q\x@ YX8?NH? ɇ*0޾e?y̽f}@ex?N#d@7q"@C6W?/jR֟d?~%Fy\ Ch0L? @Đ͑} v=@AZS@/XpIZa@cMA<޴@wA^8'1>ͮ?-<?g5tBd@@@j@M=A f.r5B/Ѽ@H"@EU:\JAdسȼH1@c.fe?=7d%*G?ގ@%=@ @elM@2@ª>Ͷx/???뿚@B>-th@|?7@)@!4@8m={e @) @@D?A?}s9,˾?# @R ie$}1zߝ?O50@3?%f@,mDe#6/.k&=es'd>I?6"u?@ )d͈>?n@%a>Vj|T!?GJ|?pj? ;L@={?D,?t@1Y@1\(PJ?Q??3}@魿F>̚ƿe!`?ÛU? {?!S?sc?$?/# Dmڿ?&?=?Z73U@4 ?Ab.?4 ??Y@N?Ѿ\cȗ5r?h>տ>ң6W*=|:7U>@B?B?Һ@ "?k<T׼TI:ݠþi@@NU>@2ſؓv|)GkdIdN@G>?R;? P@#?͊ēL,'T?EV??Oj^'D@nEm Ah@Hֿ^Gqeg?S"@@~O ?xjT[1@ |뿈0d|*3@8?ѿl\sAMT@">x Iމy*@*~j{>fzc@l+ "1j@8j k?@1@NeGw@-????3@\{9BR8m ?2#8?u?BZ!Bb#6ҿ.@D? @* ?_ӝ&>$@r?]?XSg@||o@@$4+JZ?~?!?[B[?,Ȟ@Ut?gtp;?cT$\|=ڥ"@:Y?x?ATG)0o>#+@iֿYwLX@Aw?k4=d@7?ni7p?{9e?!H?pz3?J9_?";̯H>i.Q?Ƽ?v=L==>]?\񠿂lRy>;b.*0@\?ឬZK?־nsj0>ӎ?"?P*?l`>։E?G/?t>S>c> ?㊾*ܚ?6@>3^W@"7F=d@3gK>|?<ᒿAR?!7?t@n@ >xLoI?^@@,~"@}??}ysX6>uQ $_?А?ט>?q ?6S@?ri>2>xS1q=V?=1@ J? ?Hz?XeB>#?Y'@,@?i@ 齅 M?c6s>'PD@Mz1@@Ew?z;H@)u?>kS@>* L@T@) g"?V#@OE@@e]@lB@W@֝?:@@@{@zrdh>A@@A#=@2zH>j@ߗ f@Ms?9=>_'j?}b@І?6>Wq@y3x(],>5S+yX>?@ [?륷@]B?:=>ӿf@D&R?n>>6#B?i!ѿd?-s@qL?h{+? >m0.IJ>E$IaX6b>?%?:!xPȿ7LHG/>U@!2?q-XE@пU㿞d? ?@>I?Lؿ¿M}?#6>9 @,+g_S`C?e>6@ y?g>Û?h˿ >ӽ{6)J@>/߿- @yT?w@0A@e?&=>q(ƞ俇c}?EW#(887>h??O)?TE>t?}i?c?!@ ;?3]?>@Je5s@1b2=-B?}?ҿŽ|=+U> @J??Q>܌@2Rd??ٿ6cr@q?rYs>p@co>:/@6?A>`z>eB8i0? 0t>?bWS?4=B0@#?'6@%W >ep=:>@̕?)l?>H6?@O<ՕY6=X&&AA&@.B}%;㻀@0B?kډ`?z`T@2/@?@_A6A(AAN\@ia@B뾍 :n>??V?fҩ#^. ?>8xޫ P@oڅP(=l/$> ][?ϛ@Eŋ? h?V@\8?[T>6(Ŀ!?{`lkI[?F}]9k#H >`7>g)>(nkh?<5 =;?8?b@-?Z@.}>$@,>@F>?~d?T*~vgi>;N?uM[>`~?g@r>S9ƿ`žcV2@5_}ǿ#JE@>!?ڎ@@ɿ7?@B@$5`@F?D LO@k?V+Ⱦ?y?̾i>+Z=?ҒUCp鿁 @Z_zX 4Cv?s@O@+N@{P@B@*n@Hg@Ax?$61?JB=>M?ʿZ*=2>W>+sֆ+>.?\+2?B=Ϲ߾瞿 쾱`@hN"ɥ>?׿sK@-|KF$?3;d?E>QM1@>%>n?ܯ ?JĿ$> ?.ɤ-@6$Y?cr?g@1sXi?Ͽh5.禿 @KHϕ?r@@@? G?>N}?@!?<>\88h5?U@;hm?.@@ @VT5⽆Ë,%@v@_s{?`A\1?<@@?@3/߲@A['*9A 'Zz?LO@h|@0Q?z@f&y?}@U>?Z^!yb?@&%y?o>x?a?f?u>?ST+?7*`lܿ=nI?d@ PkFo?KRa?ml2?G[g0&f @:+xNk{@@y>?_< ˯:u'.?4 .TC'V?r c멿@P(?# ?T=?-Rg` ?,Uʄ[w5?_>_>nP?\d,5>K)??b@#:?G=mAQOٿ7 x>os ?VND>2 f??6?_?oM̿P?B?@r=n#(j?J>?Dm?7k6=cؾ꾼T??b?uU}j?<dü [?_ ?eF>O?;?|?t"?WI>J?[>l#?K?]@?b?3yO>o8p%Q?)?=̾J?Z=fy@'?>`ÿֿzrM?1|=3q2r?3>/@r޿#?>b?P} 1S@~859"%`Ծs@W `@W@H@H$KFT'?о\?k@YY'`@n?AR2c@ƓA|@}A-%A~W@aݿY7h;Aq?<]@Uܸ?lj\?>#1@:?@ǖ?k8p?"b@C?>u B@ ;@? |=Z)@ ;0ѿvD>idĿ??{?>tAs?ە@ Y_%=@I̿-G=2fqֺrM@ @,lt@Ͽ%>Ѿ?`>_:P2gbR'Li>JSj=..C?%`S??0)?>?-{}̿5@19( ?9W@J @ ?\и~-(?2tDH&Oҿ!?a@=I ?-?ɫL@9(A?S??na@b>>l?ݳqS F?)ð>Yĵ?̿ nſW@^?fumпIO{??/?WKV kDC ?QѰ]>-? bJ)r)v?v?r=й=tZN>g%E@ @?U@1̿F@c?7/6 @$?b?gv!@pO@ Y@7> Y%?>o2a,k"^@EA/i=`!65`> ZQIgc?@h@j( ?$iwX}`[?Ҿ^%K0P@?@eB??P @Qa2r@@Ŋ?phA">*@ l$3@QPPA6A'T ?\0@P@&ο鷿3*>L@@@h4?a Fֽ@L@y?y?P|#?|H  ?)#@x +JeHs; F@\̿z?G,>Bn-$I>?M?վ?5@.t@ാx←>~)ŸI$@ⰈS?!X V@)<x?Xp@JbL??Z+>WT?g2[WG7ޠM@R?75m4?.?N<]>?=bj?<_h@ Ƥ?Pv>:!-I[@ B@)qw@yپ4%=B?>ʇ=@ [|>do\>W[Jr`9?C?l>>@2?g?e͓h>>sF?fp=*kٿ??L]>ܼ??J?N>@ ?$+#;>Q@"?X@A)>P U.b>B>6e?!d?M 9?i8M?P?g>?¿tlVEB̿@U>T?e@9EO?d??e \O@/@&QB>)I=<4@#e@L}=ſ$e>C>+/\qH?}@EHG@HU?=BBR>k(`3 ᠿ JK@5v|??E@BT ͪ'$?Ԉ@Y] 0V@@dulCھb?L?̺FҒ?L??*?tP?`d?q@Y7@ 0@9yz~?A i@Abǿ@3PͿG@@? @X @>f ?Ɔ>E Qe#s@U\@:7qa9#/qb?f_k@_>#k6w>B{L$d@C^?V?žn?_ll=?)>NuG5>>>:n>О>^?>"@ @l&@"Z?,V@ N9q"^{7Y\s?rԽx>.F??WLC?mĩ>ȗ8 ?? ?s>N=~,?9~>jd_??@(r?u$?[ ?}@ר?q?aG@Y1 W>6gH@MM@(/?d_Jrc?-@@[?c$@8`???Kp@ p%q^Δi?dM@Q???>\>Pѿgb&C??Dhe?0!.>ٿ 4{/Āu@4?ԁ">m%@)Mud@n?~X?)f>Z?O>տ{?k>?]k4a? !$pe?Pz`?-'X㕿@S6]e4x>o?*o?,牿7@@bk@QS?}S?ǖ@3?Ŧ?s6^@~惾6Uq?@!p&)@ `@J??[$s@Am@#Tw6Au?,@Ɵ>Q@C> q@KL @CrA'@@F>A1[A:ATZ!Aļ-a@t:+?ז=H W]5G0.7B@?F\=Lɣ>PQ`tB>F?]UiUj?G^o\{G}e=_-"j@D7F?Ʀ?~˾i?݃@"B?sC=2@( j%z@3>G @>*z@ >̱? bNʹF_t9O@_?õZ1Ϳ?+t?ʖY>0۳?AG3!Sd?Bo> /?|>=u8/ia ?2 @ cQ?@p!K|?>JǾϥ@?ʛ?ᢿ8?pdl@p?'Ϩ?%>ٺ?bE{l?W?S<6@l? Re?@?Rr>6\^?(g̿= ?5f(3@ݿD?~?Jl +?祷?E^J?Nc V@@jy@wN@]F=@|m?6?*?M\?MAnyUԿE߿%?Ѽ3 `xu9?Zs5Hd̿n˾?aZPHc>½>;pÿ]q?ja_>O?UGmyC@,@@!%?}???Ɏ?'@ "~?ѿC@-?@M7?lk> iHF'?`I?8??N#P&=8~dd+@2?IĂ?P ?gFu@M?Xz`r>)sA}?Jy;EM?_P.? "@TK@f@st >է¿ <@Q@@H3@2>X:@h@Bޖ>g?f}@A)@@d??yvP@T?:QgU݌A Enjx?w@w'@#Ap?|-$?b uE,?́2W@]?e˿?@z"?0W"?ȿc <6Rvx?^ >s_H?r@8@V? ?H?\Q[F鴾>?Q>j@,2#q>ܾh1g@ ʱ ??]?Ԣ,>jܾ)-< "?[> f?g>{#?r?`?vW> ?ǁmg@Vaw>ᅪ]U?ZK? B<?<8<(?s>CB@!?ٿ>,S] -@%k@F>?0Y1v@JX ۨ?tK?>?fl?>݇I_? #x={ּt!? (?d%ި/&G>Yc>&>lC @U:b?~=V~@?@3@=@@iW@r˦u?@O?}@=?](.$S\¿O?v?>Z@k$_@ n?Nȣ>y,|_>sA, ⰿ?!~=8>Ee&?.? ?ڨ?̏h?#Тb=طs0?P2@bs@n5=4D*@+!r?H>sv?'}U@b?I:ī_c@7[ZjX&Ne?c?6ǿPjQ?o@H؞>A@[? >?NU|@ya? ?@\R?dsH? ?K;8??6?u@@?ea dqEa?B]r ҏ?ͯ, ?dB*X@U1@PA)e{ .AGD@}< fASU0pte{I=F?0 o4?>@U@i* @?$)@aڿ C9@u?إC@@j.@ >Q>xB?3@?^%՝?q:?wDζ:@%?-jSM~?`>b)k?ժ9? ??J ,?)}$x?5?O ^nXԌ+@c?of@/y>1 御~)69?qchv?1Š?J{ԍR<8?&b>8>)W@?>hRekp6+ؾ԰? Z~Ð?U? 1>@?ԯG%R@6yr#ؖp?@?h6?@`x?"WLux&@kڍ?J>_q??;>/2?qF@~@ɿߐk r^@9Z@k?;3@Z?-@h>;@{?P@nz?@H@@&<?%@_&=@u>uN$j?62@7 @z>sk?/xBϕo0> #?A@>@?]$3?hQA./7>>5@{8q*Va?G?&?ٮq?+=kq ?Y>=G=7@?_+)gO_ܜj@!,@@ f%y`HQo8D6@)Nd <8ٿ-Xhl@˿9 )뼴Y0ۿRr?m%7?-DY0B?|?nw zQ?{ xZkǿR@ X>h?;b@@]?tYa@@b@k-Aeo8deAa\~ /Az@.Bb>SZ@t>SA4M@PK;?E?Ch>N?%@?L@,R7!?@q(\1Y@;/Hb ?emem @T?=My@&rf>. !7^W?W? ?߇HoT<}2>9@ =5dPٿ/ >7?P˿V:?ݦ?po ?5d{>9?̈@'M? ^=9>|>a0FN%?m /s?9F޽Zo?꿁Z;X?R$0?!X?`߿N??"?"Xwe?b>~wz?we"A? @{q?:z??󻌿>'&>i> 2@ @??"r[^ʾ򂾞?Yf9? ???Sl?V??(?@@W@z @۱?s?J@FƑ@@(&?̨S@@q@XGh@ ?Wڻզ?Y\\32Y@-2?Y@37 ?r?lU?^M=>jANM?I?~j@@ Sd?a? M,%?ʿ7c=!T?IP? /)Qmuz?E@&)@J>q@> 꽾e,?>t?@ԭ@dh5@<>>ZY\n;B=?۸kB@YF@6**9)f!E? Ͼ)@w.J%Z,?߸¿l쾘@wo\@-@0l8@YnC]:?X}9C@>A"̜1@Aoi1@MBվ2˄@%V[jI@F@CAjW@{@\?_>@@Nv3'@F 龣=@%n @]yAe?u??k??Ĩ?$@rۿg*y? E?f9Bnwr?x${}@3p 2F@5@"]&' Yٿà7@2Ͽ?pv@2z$$P"?O@C?薿Jx?B.v?x>6h!4C?@`?@L̚V1>@X濵Y}9?_&N( ?V=#?m@ @RZBE>j?Q)l?8wٿFo/l>e@?p??@=b,?P@4W=B?>?Ia@k^;!?d?I(~@l&@(V>騔@T+@$;@h@Tt@ 5+@ɂ>IAp}?b@r@Cu@&c@,g?@@@c)f?x?~Z>Z@d@{>G??`˿u6>uܾԥkjh@$=z@0>]?TN3$C>UZ!|@=c>v[?oпheU{O"yl~]?B|@ |> AA>WB~@Y/1սh忺r@޽d)P/ '!0,$Ҁs@z @/of@٢bAI@#Ɛ@x@^Q??3wӷD6?z(}??{^+~?pD@Nl$Ü?P@=_l@Jj9@ҽ?-j VM?B~T[r?X?[vp^Jk>G9=%"@fe"?FtA@$2mJ?M=K~?QZ)@1?L?wqI?CK@2Qο./ׂP>p:@\Lȿ.&n/[@!V.?ӛ@ l#pS@"$@L3]>?pže3m˾l<@?ѿ|޿k?:?׌*=뾕z?e5g]2տ?-@Wk?.?Vc?D[>92Z>@(?!V?krMf?|?>=ܩ?Cg? ͽ_O?A]֕@n#@=@B jپ-^@/dR@g@@"x?0<@gf@f@"=ӎ@l@?R@4uq?o?Y0+?6:>N?1:?_?2Ky@@O?5>٨;d?ƿ>l<=?Z?|n3Vxgp?8o itA>Cf@f>0/@@3=>mBi?pZm\@~ @ ?U @.G:]Œ@?@ >>x@\A Ϳ?o?,@2@\G>ȚAzFd?\BP@|4R/:@@>?0GJ7#%?0$P{w@6> =b?l@,BY.ϐֻW@P ^?8@ o?gf@V|ֵ?%@K6Yw@>п9?+?>8o#[w?ϖ@uOa{\, ; &xc?/ y?:Û?!:??((y:gqG}i?߾7?¿ T̸b,@m½+ h>\@ 0H@1H= w>jNS>'?lT߲0?d,Kȿc>CK̿?@Kt_>=@2g>@K-?T@@Iz@}>@ǂi@=@u@@<_@* @@@~ S? W\?Y@_ݖ?;u@p@'"??&4X?FAƭ?+CHv𓿽1. dv?Y ]UOrW?>b[4 0>1z?&7?Kx?!g&ڥ?/?ĝ'wvxHl??=6 ?@{e ӢNr?!lV?p?Z@g@>/->ܹR 'F ?.?M@ӭ?W?j?>sh6S @0ײ>aİ,? >?[J?w=Z~h@?q@,e>p\iGC\K@@P=Y ?e?hE@^4?MO??>.?('>7=X2p @F6@ <?q?2,>"8@4(?D?yr?RĺLC לF@@ "Ĩ_9@@PBwQ;C$Jb??4;?5?Xn?s'S<A!?'?ze?*λ?7q׾mP?Yy>eut+v@1q`?;%?t@ [!;>@|Y"e>=?]?*4>t>Ǵ??c?w@ G?p,?h㿁Kh>ؐHǬT@@f@?i@ T@p@.d@@-@u@L@s@ m@w@@i@pA}@?,@O@s@y@G??&@K?-??r?.?||@(ի>P_?G@ ?,?f?`{ų>O3YR{@mL?S=kfhэQPVg࿔F]79^?A:;>!r@>NAi@ k@!Hk?@2h띥>}I?¿?UQLX=jZYN_ܿ@UDb4KC S@$͓?f%?=V>ӿ[ǿQ?">'8=Ū@s"@zpvھYv?pWɿ i .=T?V@~ ??L)@Ft {l>C@+@NRp"@(A3,?Q4@W@}@p@&A @1/57@S_F@+1@bl2@ʉ?uxLCS&@ ]濿D?Qk@C#@fo>`mE8?H?bAE4={}[-?E?X]$EW>@02@=B@i@ ʝM{?cNhuk=-$6(P#!@ ߿Z!^>ɼ3>vDLLsx@HA@T#@ ???򆿳sv?NxH2Qt???YF@s !>xxW?%@ >?a$.?%b>I{X?8ʿR-ҳ"I?;>a_Q@ -?/X@(?E>f=-(@A?< {>w?!» }>+H?Un@BeE?:&c@_&!>@<@8@@@`ױ@@ @@A_Ac@U0A&@@U@_>-Af?*@o@pl>?:@e@-@P@#?^@@ m@is%!?#<@@x?D>+| >#{.?IQL?bK=-0?7&z@15?:=d m@'d2;ԝ,>Ŗh?Q>ϵ?P_-?@?UB?3GֿC?.‡@c39,?*C?jG.<@~nZY?sJa'U?¿7 >@[G>d?6(?0??*?Q1@a:+1> @8@$f@ٰav?8z?$ J$pgN@7>"DtͽMy&@BɿT%AƒMֹO2NIAs>;<@b'LkPk lck@c5@ eiAAd-'?@ZF>(E@ F@P@K0? w@E@{5#1;o뿽@ȜAL?#~?/K|?5?tX0M@.|ҷ@sn(׿q?Z}[@ٯ?'%[1@t'?-;NP?8ۗ@ 4@)5y>Y Ԫ:@-Z龼w>qտ9F x=@@ @KU:@&@QP>g/?&OR׉7?#8D0N+@<"\T?#?5@3a0?y|;Ϣ-^Pa??۩sX@tG?偼Q>?!???h@G?N@E}j? ɆH?z?{?)z>@^@l@=@3@@Z@yh[@6dAC4@;AAȢ@tA@-@0@@:R@5@X@jQ@"@|I@@ @ۮ@GI>ρ}?ȢJ<?_?F>= Ϡ>El?Q@$]-? ?os?i?Az=;?n ?"?j.>C$2>4?:K,?Wj2@\?HAǾ{>/@W"TV#oɿ-Ϣ@3Q@%R??3L+m?}&HNj ?X@jl@]1>f\@QB>Oan]>blk=Ƀ@r@((h=@b 53r?:F>H|@U?~A xB5@ A@HA>@ -=|lb@k2YU(@e'@m|@d5K@5-1AJ4 /Yd@[AU@llAN?c@ w=%#a=@C@@>lmTY@k?:PeV%>)2?^3>uq@Pe @=X?}?$'l?h?0Wp$?;2>1O™??: ῃW~?;"?'b?t=@#'?@hDƾB T??ݫ?{0]?Rt?g?$(ҿq> ?ƿ?~?>^6cX?|:8?0-1BY^Aܿ<^͈?S??G?G?_R?k?>v(?D@@E:,@#o@Z)@&@E@?eS@W@f AA TA;"A)h@fA_AhA@xA@7AspA!@?@浞@A@z@S@@?2@v?g?@@%^??@YH -?y&,`=;ֿ03+E? ?T@k@$gS?Þ??V @ I?4>}.?t_?|X?Ǐ$>+F?Q=V:MK]S{>?I??(?/q?pOϒ@L"*>5~.>T>(a@Ij?'Pmh]=<ʽ?{E> ?@1h?R?agj(տk@@ '? @@v@ӵ w?/g=ݛ@3@C$-L9?G?:ټ_y@!1(uY@L N@9A]@A@L??8qA+ AA(N )M?(~6$rkAP5@$1STɇ@F)2?o9@&@8~=?X@gcO@5c¾>Kt@ 9@GrfT?B?}?^@E>f ?$=?$h@EX?k>РUJT@hZ@UA}? tHZ@>s0>g?OWX@oF@j^{.-v?GAb?4?=EP )V?z u@l?Rf<_?H?R'0?ˮ@ӿѝ 8ތI>%@C&@THF>~fZ>{AB@,p?h@@@ڇ+@@FJ@MAcA"@7A-0^AbA̍A9R,A#AJ^@ A1Am@bA(z@i@fAI@T@(@.@ BmW.!@ӀY|i E =dMo@7O>ܿke?B\?d?\T>tV?%O?ug4?#rv5XOg8p@3 K>?Z@-zr>ֆ9@5>!??o?mO .?xv@&?ңb)?t?"ٿAu3e@S@'?4@6ݿU@zC)@-?q?ӿlӹ?_?%@@@5@oHYu@YX@U@~iEN ?@bL(w@FqA,-BA*@fU@y %̿[@@Y;> k@)\/?@3G@{=@ڿ؋>쿇?Df?cmd)@{8@uj񿑰@!l??+HL<D1?2, @"07oD@ b*f?/?g)*} e??6,??"߾HLG?AW6A-bA3ܗArA*A-@Eq@zAm@$@OA?:@aR?LD=8?Ѿle=,,>$=m?@O,@${>Flil?]ǿƽ^@,4ƹ?d?)euS?֩뛻@d*뀿3/ w@qK? n9?{X?>jzm>RG??{<þm@/*?>[J@0H@HN?qE@lTmd@( >k=EOSjK@8I?^m?XU̿L꿵/@)"=@ݾj,?ɶV@y>R%Q@¥@O> G>?۽li@ZQ@ФL@=6 2@Y%p@wV?N@d @9>@c??I@l\4꿁w}?^)>{&Lc6?m@AO>b[}>?v?P5=ƿǺ]sκVѾ0 5 @F8%(s꾰^#@k@ ċh2? @ ?KD0 o#Z7ׅ=~>>нѿw΋?%b3,j>y.Jv>c!ǿ"I+jg6ރ>jBZ@:q?NGCp@/<&a?<8? b$@ 8Ѽ0SQwȶ?9?@?yg?>e^>2?)$@TSڽI0?7?N?X?j?8.@v+@_V@/@ϑ@|AIVA7AY@yhA%kIAAKAA.2A(AAAwiA``ArA7AuAsA~7AcAY)uA]CA5T@Z+@}@@@Af@ @@VWYT>q?3̕>a?kտm?k@,@V?Kp@ P;!(? Pu>'2=Ɖ?Z@҆?/?#*=?!P6<~? +@_1@4ގ@TTqdz+U@^Ǿ?q"@ ^?LC@f.>|Q'?nF@J>y:?aIK@w@?AǠ m_3"'%@YBZ;@'2@-@W?!?b`n8e>?؆@}?R@@zZo>@o@?{ [-A&BB mABAA0S6@@^@_0?@/?ޭ6uP@w>2@v?S!>)e?x@]o@fS?=k\e;$X$?,?O?_@7\TDp@C@_ZZX;/?@\ qn?ba@o?,q?u?sg-?AE?y`?W`>{y:,<"@{z?F$㿨j?q?3[Њ4]f<?pV\?K?٦UvF,?;Ľv˿R?8&k?? Irÿ>R3 nǾm־C ?J@ ywv?M?"?w>';f[?W?2@@S}ו@@at|?Qg@}@ub@mAZ@}A AoAtAvAAGgAPAjABAAaAiaA%A8AֽAyAeAAg!Ao SA\AA AA*ABAZ@@U@>ྲ?͞@c@K@ p >??s;a@ P@@@>u=H>?K@5X">ty>莿=>31\ @%wM~Xk^ ?sIڜ-?rH@)e@I_n>n?z؄> <=J>8:?D+k?"Š<_WiDU+W-8^u@7l?%sG@X<@s?>BE?}lr@,%ԥ?rĿ3 YW8ܔɿҕhP_6?QD@@%Yr@:4@l{>?0 >6ꈎAV7!<#dR@AW@s1>ZI@??>כտ⟿~n@@t:S<@'?Z5@wu/?@[?#a?뽿-@?eC@&b>K?c/=ĸ s @$?lz'y+ٳ?t}`X]>1?@o*@zM?+!)5?ɿ@$?.+..?C5@M3俕fS?0?̿Lr T6?#'x5{?ƛ^b@ Ͼ$?Eu-N|@0r?vN6t`?@1Ggd^?>E;<^?j^?KS,\Mj6)G;7@+b?f>[1R>y@@h?@}1@Q?2@X@T@@X@N|@N@1U@!R*A+A`XACAVkA$AjA}AAfaAAAAA AAAWArAA^AAr_ AS_AZ/ASAZW@B@6$@0@c@@(@2(?N?[?@ @{ >@e?O@A?k:@/<ODO>o?ғ%"?]}S?_C? ?ιA?<@w>6|Dz?$@ ?>v/?7?e@NU@bC?T?UB(>e&,IA?i9?y@G?;y?$j?Nxa"?jվOS>Ï?1@9?@6+t?Iv@>~@s[|i>@"7$vAY7.@\@{@h_ @$x,D@#/l@qA@@Ab`yLP`?+8=9A*jPFh5?")?t11@ܽq5ΣOu9矿>/㾋ʐim?hH T@;T@ViY?^I4<@'y|@e?0M? X?'?O?φ%ybF@?Ꞿׯ=?YL@)q?(p=W?V&$iʷk@?"?"?P@ ?׵?C$/SL?󾌤c)1@=j"@k@}=To>P⿧\D?{2?*?=^9(vb?r3>>ԯ(D|d?>i8>ٙ?ȿ(:@1+H Jä ?@@ ?q*Qv>w @]l8@7e@h66@!@{@٦A}@B@@(6@}>@]A/}'A@AAAٷAљA-A%AvaAzAy5)AA DAAA[Ab#AAJA7 AT QA uA22AT AVA(@[@2xCc:?z?ȴ(?Oj@ |Tvn?v?f?k@>Ia|?ť?տTL??L`?s@?qm45;2?20N 8 O"P <D\u>jX?+Ͽ/] p?mcտ?Y?&hVz?ݹU/?c@z?ؿ@ G54%?GJ@&Ը}HwARH @R?lP@ VS?5 p8uS{-8z@M>@FL/A;?? K&@~DuvY/ ?D@AM%ޱ^@@e@źw@Ո Ŋ@w;@- ?(oAXн @龪m@7>1>I?d¿Fݾ؞#3FF$>7]@@?&u?(>dy&?"Q?Md]a)3?3򿽯rǿ_?j`=,o? =ٿ?6c9м@PDz׽>/?S?}u@hܿz˵?J *@75?xL?0ܿӱ)ſq+^@8[?>p>=}X>Vh?Ȼ*} ;Z@?Ef?Ex?&'8xQto{(cY@N?cE?+,??渼?ӿƿǼ?p?G?H?ߧ??=+6?]@:~@!@<@k2@d?5@ @/@Ā}@)E@gr@psG@@؁A%.AgAAAAAAArALrAAtAMAPKAAAAu)A1AhI3AWpAwԟAmpaAKA}AFt@"A0f@~U@@q@dr@O-?7>_??nu?2@0*?x?MR@5>s@7?7?~VO??p0??3o=p=?q 4?U?>.XB"[\@KO@>G?ǿt  Wb=2.Z\?8?*y^?M>fbY濂[U>º6H(&}g@{cf?o\iUX#WS?zv>j]_@g? @Ah?2g{@J)A?Ѝ#??ÆY@>!Y@(@]~A A@G">AA{f A@A[? @ @A9K@JR׿PCs@5??}Z#,?k@/@C8d=iG'T?ruο?z7W=@l?P@' @??/9[<>2@G[!tG@'{:?+P׾Ab?T@z7b=2$@ ??>Y?6@-7ľQ?PGK?"v?#oFu k0e?]'E?݆n@@>@Ox??v>*?e?IrBzlr^|Uq+S>2 ?L@kϾfl>J?~Hn@`y@(e,@}9AY@,FA@Ĕ8@JA@oA jA1A0A9AmAAsB%B14B&B7B AUA]AtrA^AAqNAACA4rA_fA&A04A|0A7hABhA@$@jW@<@@V@vNp?@mxA@% ?& @@@<2t>@?T?@ f,(r?!@%%>ti@?̿ H(?L?J@@NL>L>>A>iOR&@?28?M:->X|u/?s??wdh*տ$E?F ?.;U*>&Ӌ?/ @zZx@U6@Dvֿ"@>@%c[vI? @ [I盆?=; Ʌ=&x@?G~@Z^Կqg.#@і@BduD5A6h3VA4~D6A<\MA<@$f:6@6Mr)@Iƴ@ER@;@7I,eH-Cпz?@oZ?v#I@j#(O@Bj!&@qa _@U@H?0\>H? {Up>/h?FF?D@,m@q) ]@T6 !?>L?ɿ Ͽ^,?I^I?ÿ%lA@;\?ȑ??@@3J>?"ᆔ?}unqU0?lh?qb[ފ>lE<@?N??nE;=s9_Ͽ>Co;!?ſL=qVU? >T@%H>-u=N?hc?\辙uf ?Y?#S>Q7%<Џjn@?@( @0@箕@ŸB@@HAXA$AFADoAsAZAeB*B%B@:B[BXNBIbB-B, B!B 0AޱA[sA/{ApOApA_o A5A"AзA92A $?A8LAO]AAA 0?D6?ڑ?3 L?@U⬿D#?rm?f@+#>ė|=IqZ>@/N?x`Y`>Od?i@0"b3? ) ?,Mܽ1Nt@Vun2xzBW{?V?aξ~s+ O%>n?ۖ)@L;=4?F>j@?t@Fl? ]"2 39@ZpW#@\@HW@5AMA@4c$Al5>sRA~%ȿ*JsJ@Ƈ@m@t{?*@3]>?@6@A$X]cq13nEGDH?.H@{?XΞ?꿏@a𰾫ǯply#D[@B=M#='Q?|@i{i"3s˿>>A )忐r׿C-Zxr>" >« ҿA@aDb[;m?tʾg3?>?I>FvD,T>̿7_8t?> @eꞾ#??4&?|G? X?#)?v @H@ s?b9QgVɸ?j&3>=[#@>(=@>ަ?> 7Ϳq?2̿&!m.=\lD>Q?1x'@@o@ϔ9@ @5@3@q@h@Ð@AQ#A$;AAbB}B-XBRBٞBgBBgBB4uB#BuAA1AGrAARA^N@@݆@@-@A2pAA~ACm@@]@&@zh@%9#?ýl?m |?o@D?a@@if?? r:5*?fQG?tH???r,?]d?,A&$A=+ >3b?%YD? n>J=h >='@DZ?jz?sG?-nM>':@S?5t?b?uNU@[??b?n?ȿlt>2#,̿}@%c@ `@`At@ Ce>\l4_@d@$?l۾̳?r%?5;# rt@h@/"3n+@JA4ܾg"?L?cDN?/>QO׿? sF?,%'=ŀ @216?Y>p2Trl@oi>?IX>C?>?F:TN%?eJ~y?x?,o}?ծ@@>0/p@pw@ey-@<@'?-|@AC@cCjA|>0AJATBBTBfBBBFBG3Bq08BXB3}~B:A ADAAX%AK+1A"Ay~@Ǫ@A@;@}@A@?@{@M#?[ɲ@?0?^$xžzv/?K?D1>gf? )?vZ?濞\H I0h^?mm?p~->z[>ڨw!D‡?͌p?ߧ=Y3/l>~<,_?>?\t>M?ګ: [?>@3[? y@?o@,ζ3?@I@Z&ڿ/L@g/@5?Žc?y'>=c׿G>XQu;@]h@]f?k@5nF4@/>@di@@ =@H*#/>{k%g@<1?5?W4?@ ȡ^@ +a@<'5?.BD=ȿ@4!@G@/@"7@yDO?3&%5AԿQ;?? ?`M@@_j>5?Ym}C:?HY?e@.?^< ˂?O1?U=M@7~x-u? A$Wl?ZǾj@>v?/:d=ҿ"?JS: ?.U4T=$JX@@I[=,[F>9# =?lҿo>{ʿ+ȼ0?=7Ej_?>ܹ>F䥿?؇h=oͺ>E??9?=lýcF@?@ept>@J@8>@uZ@Ow@Zn@@TA3A^mAMXBqB(BQBB9B^?BL&BBl>Bi8Bg@Bd%B A ArAoA/@[R@VA vA%A ҇A[Z@RA'@C@[>6@@>]?# q@>?I? ?(.?fZb)]˽5XMp⾵f@XxJ?E@m?? .Ӿ}] ?R+%=4?+T< ?T,?@$%Q4 JrS@ e)>E+6F@ehP%m>E?d?Rss?5 >@)So@L4h@@$?@ t?t@Ap@7@Qi&^@?N؛&@W@W?e@o |BA`@Aʆ@EMENA='&{ha@@쿙)TƷ(]@PK@?L?H= @?n6=俹?Ǜ?q@B?P@3Mj2о>@iO&T}LO?gJ?ʝ@kt= V?{vM @z|r??0f? |>k!I3;? @yTQ m3>O?>c@@^&?F>y>?3F>#?ӛm?> ¿ }V?V9`?<6 ?Jz޳?bA@fc߿-w?`g>%?~ܿv>ݿukֿj־ZPz?Q^<>yu%@A@`?2f?.@R׿Q$Ǜۿ]8@K@?u@N?O3?o|=)A@#?@xs@ew@7$@ݑ@dA'AA6B)=BhABcBޫrBDBB~ B$B(BBTBtBHAX6AA`I@[A"ڌ@_@X"A" @~A[@ފAS8kA(A@@aq@qס?@>}z?r{'m_?x:vI@?&:@EG?3brIc'Q4?"w@+i??=?dM?˜>';@=(_? qk?V@a@7U?l@W@Ks(V@lVu?V9\@_/=MWZ-h@W"?y@k_؄N>1f\<@eF@+O&=>r@/?ʿ*@I2@\# > @U@>ءOAcr@z]@e@$+A :3/RqAdA}A7> P=?gi+#1@B>OAhX?@@&=@L@dlg4+"@]!;rY~?}o?L( ?wH)5I B >5qGP?Yy@p~lѻ=Μ?DF@H5@!13?솾`)>?Ǹ@$M@J<Ġ~F2%G?ev??{?>?5}>{?%<*??zO0x?ڽf!H>l>H`?Nh$af@+m>uGU@U?ҿn@9kvr>YjOϿv  ?aE'][RSs?4F?~"w?.[տdƿ e??j]6 >+v=>`@a|@0?@Q@@0@ Ŧ?=@hД@a{@@4L@@@eA<AFANB.BfiBBB܇BsBғBcBBBBoBlB/$A4Aw0A3nA`A@g@i@g@婘A7?A>7{A#,A%O2@?@?|@%@'?@^t@Tw@ ?~<!-@ ٿJ$pj,@g??h?},@&q.K7@q@c?a-_㫾k>@#?k>o 8%?r0?j?L:=O|y<_Bj??oE@ fD>@5>73 ?z>$s@rj @|`nK5E>@:[?g?_w@Pz$wk":˾7I_j6@b?"3@@&Av\@-@Axx L@)Ynı@)0Ry?u@?׿&9:6@?q~]zyx?.?fuغҾ?d?? ! ahsN?D[ÿ{ Qˈ@gy?@D/տ\^u_2a=`B0@^DrZ?n&x_'i@8)5@M@Uu˛=u?268ο{6:?0odA>%@T?Ћ37?I &M@,;?v=οWl?:@ÿM?ܯ?մfx/+b<{?hf38?[>e6B@)޿fKH?ay >ǁ@* Q=FF6@?Ծ̀t?Y[1(@_@G@ Wz<@T]@hAfXA AחBcBI~BuB3B\BKCyCFC+BԻBLBBӄBe(BAGA6V@nA5wA BI@(@@2JAPAA"@^@n~@H@?@r@`cn?@K ľg^?ҙ4d~?^@?пTyz? ?e^wP-?0@3۵MǾ*?)V|?0G?U*@eŇɿ7|?Q?m1@w?It?? ᅪbH ?rF>@.>kB= BH*4jN&?>7?^@I]~EFοb8C@wMn!?@$W:j?׿pWU @tN?E?+AMοA=ʃ@@ A,@Dh 5\]A ֿ5lQ~?^A"A@1Nl ??J?b3t%i@?=XN?ލ@gC?M@L?'OBt@/+ȧ?=2Fo? ?ӌ @6׼s@*a@>?U"ɿ>x?L'wr]=@4b@@?l3@< 7mb>z+3?)YyC?F B>r@8N@^?5/=7-j?2 ?)ǽ],>.@!@([Cd ?'U">[(W|=?Ƽ>򠾯X>c@q@:Cǀ9?};?Rҿ:f>f^|^?h}?0>M?^a@=i?Wyk?:?連@Hp?~ `n+@@?%A'AT@AB =B9BsB BBETCCSkCCk/lC"zBB+BHBvպB)ZAhA*A2iA9A%AL@R@ۆ@@JT@ݖA@@y@U@y?a_@B?>3?Ž R?J>;f@F16?"ۿ@:?%.5TCv?L@ZEY\?n̿ I% پc _U@uvOR*4 < >˞?׾h=@h@uZPƙ@@ϴ?9)̽yzA?tA3V)]UA?C=H>o ?_)j?%>댿+~;)eD(~e@?X˸?w>K3@ @ 6ei@}-9?ay0#A2c"?AҾL[L#NT@-VA#b~?fȾ @i? {8@ @m??y׿2@R@ @)ĥ*%@@+@yB,??ńEE:F@<9?@X$8tx+w$?2?At@d3QH!)@Rޥ5?ӔJ4NlիĿ?@H?HWtv@2>Ʉ.? ?e@˲?zoVM@>f,OMں>6??sT}/ؾʸ?(E?9A$w?:?`;?逾N> ?E>Bg?ӒU>D?啿dT=3$ǿ|&Ԟ2@?!vF? ?E-5۶]?&f?NKv=@@ykj?6?gk@`@ d@@F@?._@H@@.ACADA|AVBfB7vBk,BD;C+C|C tCYCgC[BBBB4IAA_AMA=AsA"AA A-A2e@A%xIA<@v@ޤA }@R?(@l zv6@(@B@\U@˙*? ?6^?"@C@:E@ ]??ɿ?!7@ 0E1 7(>>^+?8d?@ ?O82q?9gl?80*>PfG@ \N @,w@5?`Qo>@ż?kk?^(?kO|Ogd迁3B&?_?@:_J@(@W@Y @%_w@~@D^>)dβf@ؚdh?')@ A–G>@K bA^=~@a6{gN:@*?X俍@!I@=@ ?anYH?Ը@ڤIڸU 0??@'p"" ?F4>j=?i6⾇u.@[_d@R|̖q>ȳ=?%@zG@+|q2?8+pؿ2BP?}i⦿ֹ&O孿ݿ |נ?wD,.8z-Z@@Fp?u@_@&2i?E_:@$.c@9???Fg=ńQ?&J?t@=f7>/>b=-͝?X{0?g佳/l!?=l?m f_P?->AE(D=3?z<@h@ˆfA":%Avd@h@>e@w@@䊤?@c@@įA0Tt>v>?2@T?@0D=bFc.&.!VV@)xpv>.?凿???@wL^@G>|JC@~?ڦ.G@Ŀ|Hc?7ɐ@l\3 m@Ɖo I޾d|Ka? Xh=s>{?UX; SA@X*@q)@@o.*AT@"a?(?@d"S@q?^%AA|`H@4upAv@L@0@>f^)=A%w}>[)@l@a?6Z?N5??7տ~p1ڭ@rٿ{<Rb@?L?Q7O ?a@G>?@ %@Cg@-l@ =@cz>@x&`Iv9@?OV?t?ˆҕc7>g?7]?ۍ52>A?@?29T=ꣿ̛?NU'>2=Ԩ* -t?Uj?-AD>o=[j@ @; ?BRxx_=#򿈫꾺뾆??Nh@?^@cb@B>?@@/@@z?@1?;N@@@PA$ڱAuAwAAgA BKBF%BC'CCَ}CmC}C:BWBBqE}BNB!FAUzAAQ'AlA>LuA:K@A@穕A@ҩA! AHYAA@ @&@n@{??DhA>w F?EZ^} ]Yo P@$?s>b@.8?J@j%;?6f@ Ы==c?\K?OLF?n+dd@ַ]*@?]?7 !@-O@>F-??*8i8>y@@]Cj:^?BԜ@b?-_`璸?+@#wւ@>~ir- +nMd!I@Ҋ?č@"ʐO?&??[?VACMi@G@*6>"U?z@ׅHv#@>@8ӾѾ?F51?[ A*71w?8+P<ȾMIQ@GbA[ >p@OB@<∿?.{v({ӾÿK@-@.$B>үꄰDi>'k?\H@E7?U]>$> y?RQ>؇@> r?>W @A>V?2>B ~>$6QEQX_1?Az!?;겥m٫ZDޱޚ?jjHl`?LPǼ?ƽt?a?>0?=w?]ؿ 9Nj?9A7?m@6LxF|86RЯ>1G@PR[\_?i\cW?-}Fi>5r?R =>I?̎>@ @/b@mL@@l?8G@@r@ζ%A@@JAZ|A+AA)A$A%B5:BmC bCsyCTCx4CxC']BB^BL$cB7B$UAWPAAkA|:Am-A %pA( @*yA44@_@wA^e@@iY@TdU>?@2$@e@q>k:b@XϞ4I>?}%ѿ=g@?k@O><?QP5=@6,@z?KͿyi?e@C? 5G!R?ӎ??ȧ?Y:?'(*@8JFkXJ@Bt5@CQ,YW?i>K_>7%<@1`b@A?t@j)@?m4=.'@KT@3y@@oII@kCI3B@7j-#(? ?^s@0X*@z@ C VT@;A{@*H}@5 GI>cv@{P͇@i9@ar@ݿ T@mfv~m=ӿz0?P$&@v89.Yb7?> 1->( 1hJ>>;s>u 7gۿ02@}f?@_䘦> ?A@!? a>ձ@6z>dl?ֺGW?c>?o?5P[zY> v?BT@ DS?ۇ??>L$p[?dVty@s?*@/Kox>{?g*YA@J@U@! @-@P9A/n@W8I@@[>EC@U@ A0ƠA9&A~4Ai1AيB |BYB*C!5CcC{'CI!Cn5BsBsdmBGB&RBwAA ASAA_A6A1u&@ۓE@%@w@F@@@@??b?{8hz(G2>E?˥羭@ :F=u\??ο콹?P>)Si>bfΖ?߲?Y&ver BIs???,l?5>_J @7;b6?Jg>2@h\,y@pjnWG@<;-?сѾ*<@9>?j;v0Rc+?DI@Oƿ??J%;پ2&?G>n@@@NA3:;@B?=?@w@ɿ]@nA+:k@?nA"MARŸ@6u4@^f@d6?<8 @)ŝ> K{>e?)TaHC?'GR#@q1q@(@(^?2?Rhg>PܽB%‰~?c>`>T /A.@ 9x}@k?8R>1<@ek>xɾٓep8 I꿐^O?<>ܟ0y{&QȾJe>U7@'?%@[ե~??pTg:z?[R?Ɏ?pj?h>:U݈="ٿD?v-@!eԿb?~B? sG?rLV|?Zs|Î?٥~&@3@!f@sE'?}D9YJ@@AYcA |@)@/?R@bG@M@@٦@?LAE2QAEAeAoB ZB>xB~BC|CNaB:BəBBBIХB%͛B AA4AA'AA:EAhu@Ȥ@[%x?1EfB?>:8?< r@af 7Wn?+@E?!j@Y<@zT+?0(u@E@mYE? 9;e޼^@’rJ@M(P @?>N@7} ϡ@G@h@\Xa@Jxo=1jk!d ?  .Y@-ys@q :,Vζſ57鿮hMF<_am?8ycQ<[ p?@@W[^?Nj@?˒@f@*T@Ao?߸@w'?ȡG?0@?k|>M*N?-'7M=VK?@{qX \k/{?+k?/7x@Vf/?$=@SCk/0,[]a9UЯ @_ P?rz>??ۿ?>9S m@.HNEP?z?A[@V?ɿSGLs@2^lS;|9+S_tF?f?zDA] =u0@( @?|e#n@>~@Ѩ@&@2AA: @1@A @C%B@}A @0@AAdd.Ae A~`AWAxBB;3IBw.BhBCBBBKB@BbB4B?^AA"fAyZAxAkAT[AݑA>wA@шA9U@A@@W@0? @-@| @0Fʊ@, J?h˿ >'F4L?.=pHI>^aiF@c>@Gn>z??ƶ]-V>%@2r?@9?Nh??U~>듾X:9>P׃A 4ՂW%eJ?1Zt>ha +@y@a1@>`;p?!>"? ?Aem?}ܿ>@^ K??C޿KU@?T r@η@n@@pܿQ%o񽒤@h@(T?hPAAG,1ſ^R> eZ?c+ +?а@)Huj UgI}@0\]4?xT߿e{#%2?qe?Cܿ=n+_rM!*?7?ouf?b=? ??KjeoSp[@ V@6@O@ ?)&qV>"ce q>U:s?uX|> #?@@DA,?n 84=>o1?'u:>̗}@:!+n?~~@?F #?gAr /\%o? |p>一?;?&m?U@R{@B7@_j5 @ Zngu> V=>#@?Yc`Xb? V@>B?_@W@$AhA i}A -gA:2A @4AoB@@$A PAE A@AFA_@?A*AAѝBWB#y6BJBbBBoZBz#BB~2YBmB*qAAA]A,AnAoA\AAJ)A#A&]AA!A!K)@@@?@K=!@o@?\?(?g?@!M=I?go?@T٭!?>+t?P=?h ?(ف ~U~?p;44?Kxvig@x>*vQ;aG@hXQV@?I9Z@. R9־DŽda6@(w???F C?9?@5%)@@b@Eٕ$? I1@7ľ@ lf:FZѝT@@"J@ۡ?`Ae`B-Ay@g@y @@.@ @[kO}2?D@-l\@(?Oܿ *?5@8/@L5x1&?WXG ?֘Ծ @9r?p/Xbɀ@@o0,@iՆ?6lI?]0ڿHD > 0Ez?BQ?H1? h? ǿ'h?щ]X ?_@̳=?EKՉ@@M$@u$L>ԑ++RFHF>zZ$ ?~P+hK?w?B?_?&!x?j?,6>=˟?@%;j@N%Ѿ|62>_F?. 繾ʿ` zb?9S@hql@^4??ʪrZM@sC?0@%n@,@"oA c@@ܦOAy@@Ά5@@uA5BR@AGWXA} APAAըBB7BD]BbvBX?BJ.BNEBiyBt@Bb B#!AHAA8AA6GAvAHxA?8ANhA%lA@ݔ@6@*O@t@]@@1Rk{Z??_@>< ?F?~dEk9?o3'?x쿤4KN??}?)f@@:`/@]an?lD@+>}#@ 2?@@D/?~S@PJ#ÿ9^_R":i_?v @  @MuW}?W?YQ??+&>/??b$ҿVK"@P@V]_2f@!E?1?l@/&@%Y޿XO]e?z@@+b@j$?dW8~@-<[>0@DA1Tm ¢A&"@+LA7]&ZA% @$CqJ@/.Q7AA Y!>?|@hw?@`],?k{b?&@AZl@q@4}f>"@!V?󈧿c@RD@ s?>OKt@Կ)β>?7aJ ƿ~?`> οօ@wO@-Q?c?s>s(@<@6# n>?3ӿ5F?%$ ?,K??\?Zn?c?1?BIοsL? ?> @%@(-?|u?u(),?TQ3}Z@-K=F@c(v@ @j@@[@@%A%z@@AGw@΃vA+@@:A?3AXh1AZAgA6B"B5DBGPBKB3B2BE{BrBW B0A+AbAy8AxA_A/AuA|rA7>?v3? |ſܶ/??ÿI$.^<ٿ?HOs?q;' 9?a?ǽw00]M@It@u6> ʏ꾿 ?e! ο5@|?@݊Y >zײ>5~@.n>˥ nF>L$U?`@Pۻ~_@ @ P#0R2>@9@TuͿ_@@0,@]3#oI@ƣ?M?@-.@]HKDw@ 8?I?31T?|z@ 1=`e?S?qH@VT?2K@N6B@`?gL@4 A*@A\E@]tYgF@lXOe_!@6T?" @[?@'@3]?R ^ ?C[-Ը~п{=[@bh??i>;Hᕿȗ?Ĵ wz}?-xiǿ[?*s?K>p?`@%E>0}7q?Wy ?2:?r-j#?Ռ6?Fs7@r¿DFLQT>S?ܿK>mx?IN ™C`>(@ Răa?ۋ?W>>vi@ o?S|[k?M?r<@- $$+TId>qw4?(@A)CA2AoAU A^A A+WAe@{@}?cU@@l@ľQ??,?@-R?@$C?z?fi9|Mia=h?!N'Ъ=5@T>yK+$ͽ徺@Z?7N 0@h?V?'@7 "n׌PygMhOY@ʯ@@e:/{@+;k?7#@Z==b=??ڶ@w??ҟp֚??r .*z%@@g俚12@ahI`h|eM@J@^lKa3@_@[@veݿ jt@:2?ӿ@s@+h->'-f@$=p?Vk@n}M@Mh?y;Kw_W$?4?]?!/@aӿy?Q<>@+@i?bɿ2?Y @ W@Y0@5Yn? @`?t/?/ȿQ?1x58V??m>p?z@&l'?D@0k?*?aRh@ f??r%@b@P@ C?3˾¯x?)In먁AMRڍ?轠ȋ^ÿe>(???Lg0@p>x'?&`I@ٮC@:f?s@L~@}NW@A>ADOADAs AASAAHhAVS+AC'QADnvA-AAرjB y&B!xB'5BzwB6B&B9BGyB4yoBARAx#A gAcOA^AYU'A?z:@`\ܑۇ6=?? < {\Bp?&?f?6(ltX?9<(JW ?=bg"@N c?̛A4@qsP ĿB >쒈1?8?V-eiJB>R?@ mc̾6֋@ |?@iE$3FL?( $zHS=H5@M,bڽC@q2??{? 0@`8[Y5@/(F@`l2E<+ )ԈAj&R'M@AQu"x@'N (^~S@|0?7q@a@ʴ/!?ZQ@;j @a}.&Ђ'p,??T@^?y?%i9@#\=\?꫿44)?ӂ@"?ڤ翘7#]ޓB-Ci=l5~>&?d?],8@Fg+ 2,{ `?ߗ>J?l/E?h=ؘpGL?l? ?@-B??D>}Q??ϋ?=XEjb:?6S/\1|9E?ՕM?E*?eL39K>[?+?.f؛S=v)? t@S/?z?ؾ[?>@r% ^?A+A]`AAnAG*dA:AAAfYABB(UB B!B B^B$|BigB)AꞂAvAAjcAoAA9oAq AYAA{jA[:AAXnA*AxA1H@-@ ,@@Ym? ? ?-#0@>J$&B>S{?𽱂2?;!+FuO?2@D8@4?U뽂aIo+@@$^\?-@(n???l{Y@"/?~?v{@?>闿f? P=?oӻE+sHfa>p?>h@, =v@6S7@S.\!yJ=_@@f5@ @*>7z?tT@9e@}?Z@ܱ?8:@KAaB@v=AavW@mAL$A,Aπ@@AՉې@rsN ŕC@Us>e?T@:*??BZ@ƷFÿ6U >̥ȿ5e)xK@1h@Z+f]Eƻ>|@ו?,❽ݿZ/f@鿔(:Mw@ Bz@;|?&@}> >nX?Gr?%}KC%޾l@Dx&>]?9I"ͿO)>-ݾNRj#?EuL@!(?P\B*?RR-W]> m>Z'>v>t<0IuU ?#k?+=Qd@}v"@2@ҫP@nA &ZAA4aA.ATA`AtAA AA|8ABXBB"pB#B 3BBd9BAҠA=A-AAF0A3$}A "@@qAH]A_r}A[AAb@P@A7A1A-A4%Aژ@Hª@GJ&iS?7Z7@qrw@퀾 T\`^?*q #iq 8$E 5һ3↓p?M>"v/??V:?䂦??#0?#@.пS.e>44`]@>`>z ?O ۛ@)zq0@Xz@c'^>t,Q/r@'j|iC@=ZA}?rA4@ U?@>@GG?4 >IAQ-6BҬA{A GQ?džF?Al\@I@(4/@@?x[$@Ҿ~`&@8K ;5?MJ?p쿒@2\7> @$mv^v@J?a9?N7nH]@{s5?\2>~?@,<_e,?ӡjw@(G@Bp;CDm/g~?eC?B@%@e9?+U?sܿC?_d֨6@eF6@1@lG"8=̿ ?U?%'Ķ>̤M> <>.H¿¬cn>zH>O,?S>}n?#ҭ?#?+tq iP>{?ɾS2?D޿ڿئ,Vu.>Jg?F@)\]>[#!@H:@7T@ d?>Qy@*@@)@NvK@_A@<A?A]A|.^A6(AkI@)A@7/~?p>ђH'(U?kf?m>ddV(5Fln??P?f濌:뾿 {O@<<@4|?@Ey@Ye\Ͻf?a1?4ƽ%y3K@0?>U?3c?]@ -,@+9r4@:?8?@@:(6+?癁@r~vT e]@*8k@a@]$kXS@j@NP&<2Drヤ@*AA@3APxAA7 X,jF@F|@+@y Ī@HC>L@@EK? @B팽s]@,f!>T@$?.=쿟q6Ȯ s>T٠,꨿8o?A)e>NYa?Qx2 )@]0οc.B9T??`@'}* 6X4[>> *?nǁ??,ӿYڿ/?翨>>B?l@#vpZA?ʸ?$9@ XK@￴Kf?'/@'?)>uӿ>@X???Jտ >r%?:,"}@`@=e?H?Ҩf@1@jzEŨ@g @ƚ@A @\AEUAAZA'AArA5AA ABBAAyvAAGxAeDQA6A8AAa@&AA@A0A&+A G@'A @AA j@%A~@A* @:@|^[@*OZ$@E@R;@9]?X>/-qaÀ@;+?nh7?ˤ+k?6@cɄ>@r>>TV?x?3W~??)?f??a>.G=7?Um?sZn$?%x@Eʉ|@3T@Tj?¿jEw?4Q?KF@ݻ5|#@ܕ o:@ʒ@j>zǏpF"?@ @Tʿ^G@x@8 >tv DAF>B6APAA%p@J=A `?J&O;jK@*1 %F??X@-qz$]@?~r@^?2V?EO?]@*.?&g?L%6??U?ħ@'?@1"{H_ ʿQ\ ?1@8g?\ X,?@_>D9?e?A:9pJw?.?Z?>Ly';1 K7?o?]?ǿk5ÿ!Y$+@?^?{S@޾ $>im?i?* NB}'??.?!?ѯAѾ9%mG?Ƌ: ?þ$og>K>=rm?/2\?[?X?r=i?o?Ԕ??NN?w?ӥ6M0sY?'(@$g>ӈ@@@@@9h0@ AADAm5AQ8OA6AAcAAu|AҜAA4AnjsAAA^A:Ab@A A@i@@ZA`&@?@@Ab@@:@A-AeC@%@c@ @ɝ@AO@1@)!IL@_VY@\MG?; yN2 }~>9}q.A9MM@&f?6"O3@^4@JX-Z 4k>a#?s@Q ?Y1?促s?@>x+@5:@2>U3?Et??&@=A0@fM[?{A @+ ?X,+@oёS-w?N#?L@n)q\9B?6$c?Ժp@+^E[j@Dy"]@sdqH}a߿;@;@a̿M=@-v<> LF0>y@_*?C@a6?Jlj?P7>Ȗ@iyD?@ۏC&2?D2@{?C?нk @3@iQؐ?Qi?G@YSo?H?ܿK?@<ʼ˜-?m?LݽCm7mM*_?1ؿп@6&ic?U-Q?nkC3\@?}F=.zA=%eAvN>JK@ %?8r_(F2p?!>e[<@RH X =c#se?ހV+=?j?9;?i>xF?"'@ @>@,p+ @6>p[@ݿYE>?}O?oB@YD@ٞ@X@e@A{AA-RA^AApASALAEA AvAA,A<~A=SmAA3AA UcA,@T@g.@ @eA@%@@b@$@-@J@]hAyA: ]@a-@@@1@?kWn@9@I@E@5E:~"ѿV?l>e%4e&>Y^}#ѽ@a=Ly>VO@Q`9i?a%[ VM>v|@Zj?)n`>g>'?--UQ4M"0i@J ^9&#G[j?$v~GrƲ@)?3?Sp@W=̌Q_>.n?bпHM @3 6?@C8AD!=,=?z@e?ؓ@IAѶ?l>8V= HA@P?QKhl ?u?(8@a/@L V`@5Fvn@ ~? @ [Oh=h?(l>)V?kпk@T+:0?@#?Pάwj_CW>*?왎?,?/8$bt@Tҷ5X?o>Bv迮+H1>a!;˜&&u@=e@^@>4?u?҅?xv?*o@0@p@=q>@kَؑ@%n?7@f@@@m{@@aA8@YA/cA{AEA5A6lAO@A,$A LAhxA5NA9 A#A Q^@A@@Z@V@@ @7@yJ@o2A)Ah@@wn AA(>@&@yI@@>? ?(>?8?D8> D$=yrTsƵ5 >ὧ@;}=.y? B=J _ef?2t@H@7z>(-z@%a?h?/w@;c@Z=@//Y>%G7j24@GOqW@s?>@b?@ٷ@hYѾ^p/>N? =fa K?R?`?@,@ARz@`?t@m@3?*QB+2@վ@-pg@SHA?_jAd>B7R@D:0k{XP@,E@ @N?.7@`_ !MS?)S?U0@4nR[?0 ,@@?Y@0+g@G2=C=M`:[W%>@7!HrC@s`?/߿&W-LB@)+@=)_j@nU@)o&TeOEA(O?u*e!^@.I?^Q@@}b>@)|HŒ`@9-V=q?@2S䟿Ǿ;RfF]k ?կ1>Sb>?WK:@JQ@(?vnq@ g4w ?/v֖>=H?<ֽ:UV?`݇?%>?|8@>IXt?t?r=J?? s>Pu >ü>ޝܿ)?~K?+?7a-j ?@Dg3F@4t?@ݪ@:x@~@&@@@@|@A]Ab@AC@ʽ@AA+ @@@@A)1@^@7!??r@p@7(@ǫ@@>@@`@AWA;@@b@p?\??g?E|?ʦ N.>Uɏ#>̢0bbzasee=~6e+z?.>mֿZZɿ#%g?~@b? 翍??W=&G?G?Lh,LF @[G?Os6R?%?r׾};:^|07̿k q3@ 1uAs@Ryg`?֣>t?v?2Md?Т@SS?iHA5@@ZuAg?f@r`IPA/rA8AP9v@6[A PA ?@\3ճ˿4AB*9@ @k@72G`23@/L>f?@ʏm@Қ =夾e?ܿȊ:A>?1S?h@*s?([q%\J@A%޿h@2C㿽%O?ɷ $|?<vb@&+??,!=Dm?(Vx黿JYg?u^DW@*@v@MOH=vSFl@4O= mۿtL[?qj>A@&>g@~"r>;¾jT+>&?~?[_>7p8Ux?՜?@?7@]Ͼ(o?Rx ?6@&lb@$B?X1? ~ 0#g >#{|@I%- (@@8n?T8~?4|IA?"??@C@¥b@g=V@G@D@@۝@)A@n@(e@@Q@ŭ@]@5@@a@;@;,@ <>U@@q@>@ m@ɇ@ʫ@TAz\@@v P@̇JA9@!L@@1Z@B >)?T#?[>Q=^?P=F{@O@|d?I't1 kIHf?{1@K%>?l3w? ?_ EG2@Gm?|@(_j@ў(\dp?yM?J>ٝ@Jvj+*@1^@4<I@}9\?F?@@ST>}1>S =; ?}? G[h?C@yoKjΝ@2??ﶈɋ@x\>?xC}hj?6@@n޳@)נJƚAT@+@bB-@Յ5AR|@(Ҿ%#@n@~9Du/h:;F@i`Y>yz>U{a@+!BJ?t{?M"j@ʡ@/?Ɋ:a#;?Л@(&,yR-?@No忐~@.o5??5?,y_?S?9x?4Կ;@+z?+?=8ks?E0@"PS/tg=?8@z ?럿n@e߿0#o@0@ż>v%6oD@C#?9?&v?k%? +? |ʱt?5 (?֕>6-=?|HN??\H~><,N?d@@kϙE?̽7>@ ?e? #[v =>/? )>?\z@ @O@"k??f@??,@k@@#@S`@_(@z@S<@M@02@XE}@b@XX@Fa@c@@A|@v,?x?Jʿ^젿G`?Ͼ?oɼ ɂ@ZLc>ꊟ?%J?70>Z>[e?۾"ѿD?S@ ޿r>fh>'@͖@?TĿP?(@$aY`B@ ]K2?P̿qP@B>i?x\8?u?&\j9{/ j?,}W?&ձ3 @h@̿?l?@$BA@匼@@/p$@qZ?ZH@ q@\րA@Z0®@U`1X* @0$iyE@C¿@ BA:.5>}@dVwd?ԟϩ>m!@_Ę?S>G??,fi?ԂEr+>Mr\?NZ4@Q@m>-@7(Y/!r@pڿρ_?pWaշt?3Vڒi*?9+?ψ[鿩f⽃\?> ?Km<?*p?<"??X=%@'?EX>%? E*>] @eN@ڌ?j?=>?`j>&\?8@#OQ?9? <]K{?@#3$[?6R':qrRU?z*? ˿??L\@+?,YO?agݿ?ʈN>_=i?k>/!@q|?-'c_?>?@k@J@k#@I@ |o@Π@`@"@O@@H%@@e@w@SB@u@wf@+@@"sA0?k4@@VUV;J@ph[@@5vj~?@@Op?.@u>+?@*@2 -[@qS?} ٽ~:L<T*???I]H0d|:2?H6?7%LQH?*6`?9V>?W1@ ?#"IX`@PE7?@?N𨿸[i>@̢}>cV)K)@[A@0/<6>_ѷ??^Þ|= ?S%%@5, xAx&oiAު7eAQ]~@jA0jdUV@n܁a1mAW@@( ᪿ?g@|q@ÿiр@-]:@!:b@CN;?^>{s w=ES!~{ lN;@Qi? v@>"t?c?1>9h@>j4h0Ok?@E` hs@}@5E>y @?Y*+?I?O3>Ϳ-_ ?f!Bj>8 >p?~xI`(?[xm0gj>Ǯ>뿓h@nt?Dm@9ɽ7"?Ͽ#r>+"+)Qii?[< 1Ѿ=.t@'VDv}&@@,: )>Z@ԓ@rԹkb1?|)@ >֎cmп[N@!N@W?Oi?jU>?@D@@›O?@Q?_M?Z@M@]^t=ZZ@@D@b@#@ Gʾq@~X@f@&@L? `>3@y?v@h`@?1?ɦ@|J@,>=7 *>-? LS=@flB@&?LH?|Qwp:g>f sI@zq=hc?Cd:@FWE>޾WCMh?ms:f+??&&w$?}@/>i&TRϛ?$g/>xk>Z? :@DLC@0|8(??~@zW~~A-r@IjC_@=+>L)@o@3@ @Ե@ -U>ɫ?m@ @{@wf@wLj2? /*@X@D~?UN:@z?+  A;> L3w@_@Fa?y=@[@&9Hǿ׾ҿ>du5@ *X;8?d>p?AY>z~@R@ E@J')?#@{{;?1y =Il?@`F&?+? ľ[d`@qAk`g1??,I 9?dL=M?[7{8_F>40Bpe?1Gv?ڄf0? zE>\?%"?m,0տQkB#>'?u@Tv Vt߻?@7?%5?Yu??mL>r^y@=h=뙖bYU>grSȿ@ iNӨ?_ؿ;˾n30Lj>NL#@;?R/Trr??ڰ_@g^<G7/˾@)>v??I5@?uO@w@ *?F?%u%@:j@[{@&@@|@0q=M񽞟?fz@6Z@|*A @R@I?h=?0;@e@d@o@VO@\_"@+>@߾i/@ ?Fe?%迆X@+9>Fk?b?c?F@0Ŀ"?ivp]ٿ(`%>7R>>@X9h=9L)@z?Z?X>k>$m?7?C?"xf@mZ@0SX>?1?&?J)8OJ% ٿaQVna@+`rD 6?z ѝ?5̑?.>WTgb)@c?IOd+@` @QG̿q@A,_}AfbܽAFܓ@{1rAL$@yZ@A <2qA؁ADа?^@D@q@sOry@.@;@_@@k?1 ~|@c?Ҡr@7?(@m? #? mp%??J?^=:ϼ@F'e@H^*?Y,)U(?7SNecڽ[>0@h ?>]$G?p? 9?r@5e%y N 9??19@ Bwe@?D{?QW?T?K6ҿ&dA?_+(? ??=aN+?;|ҡ/ Ģgc@ nF~-@4-^? ʿQ] B?׽>=B>MI Y>^1O0Y={1??|=WO4@({<@2Ց?ɿmx=<?>0bX?005?L.@?Qw@?%7?@K?u->Ğ=ή@ES?(8@H; &?j=Sa@G~@@ CJ?Lsc>r:? @ o?ެ?;?p @IуO@)>A1>^=>->i?ɿ?@"De?? @>t[BL?!?>E ̿y?2:z@@9 w1 ^gq`]??U?@3d?փ-E >w"lPϚ-h?X Aa ?85@LG?ݞ[a@O> ?X=VB-,?Ō^HJ?@%>QϿt@wo?<5٤Yf¿'@?|?)?ȍ ?8!{K9%)A ڂ@D'7A'@hKOΥAE-SB%]XEov_nU?a >a9%?@@i?/?Y>->>)@# @nmaT' @i9 I&Y@-;Y ӻz@m@@q?y?]H>>8?u~ XP@@Xz?2,@=@K\@4>(#Wn@(ͨ?g]ſ1r?43?(?ݒ>=͛?QjL>2`|B@T$p?_E@:'`? +F#`?!?ٮ@2 b>f"X俒y$A?9?'?>byjE4@#׿>DC5$XSA<8?@@gGz@tFw=HL?JžK@x̿x@,>@?< g@C;נ?T@@M%>2ځ>05N|n? [[? QzR*.C=@@(>12N?͜@6@Y@߿_..=w^@Ksy>k޿ȷ:@/P?@@?@`t@@j>)$@7@e?xA?]"t|@(?? Ͼio??J ?y? о#C3?,>nҿUO>߿,Lӵ@)ؽ. NӾ@ϿN ԇ?[$@)e,eaV>U>>ԲC5>Xd/p?ه*7?t86P?b?>ڞ?|\B?$:?&t ,I@>? @ ?ʿ%V>^@1)_?0! @@T='?'՟p@ET?OdNa3@Գ&R,@o@ez?p/AY|Ax"XAwhA@?- NR1A@kE@;+?j@Jq@E@N(@#}d鿍4?ȱ*??YK!@E!rȿ!g@"@˗*=%l?!,a@:%4G?̦JAd?f@:8)>n?k Y%4?=Y?:`,>i)(@!>SS ?!h?!?6?ΠO@.f+=psm?9?>p@<>-M`?/>"TY•??>?տ,Nƚq; ?Ƭ?1?ZVO^?( /?*>Eq%@,,L ,?.=199@?:>M>6:*T>響62f? >ޢ?zk\?["{QbӾK?F+y?kl@)L?=?Nī>@n|?TZ@ѿݙ>^@`X?r@b@*@U@;?@Rh\>~*B@gT@))@n |@>@C>@s.@n@9@}@-<x?>I;׿Z3?pt k??k޽T?ř@?k@=x=?m꾎@)?iCH?ǿૹA@~2 QBڿG?=@^5 ?N`@L@qܿqR>T!p?m!?r?@aŸ?>Ľ.@&s&e-@+mBAv³@At@@1ʬ&r@\@l@+EfT>aZcZ?@>4?ǵ@-4?h@,H)@R䜿3?@eS?1Zq@ =YQyt?@}5?TI4}@׏ =H`}>??ן@w]>A qv@_?ɪ@~&>F zW7>1<I>;O?la =?Dr>?jNS?-ƿr{n8z?$9@fOs߆?m@?Tg\ocmI@+?F ?>@?.Q?*:sƾBDN@)zq?GU?(?a\b@,,?᫐t> -r?`4raayMٿvg?zb@?ȵq>/\Xɤ?^#<m4OMq@(ʿ[?G?u@/?.Y ???t+m\ \m>_?M !@+?[??%'y1?eƾ@i-?@S=?F??a0?d?=GC?LŇĿoT`@Z@"?RauRL?~ ?ڄ@R??Po8A@:(W@ >(?J=R# e?4=_c@ d+@NAиR?aDY"\?@'k,_~>[0?X zu i@$/Sj?MM>=U=\@Q,?u@%ʲ?D@'Rvd!?x%?M<rW|$@N>8A;{@ >~@3?ü=G @uJq`@cdX@LG$}[ AAo=:1e>eV?c6VP?[@A0b~.ﲾ4??FHǙ@&@uRS)F >@S?H?T@1(b l@p3>N{?.k/]?6?u3-@ sZȲk@-@׮] &@m @@u bl"@y?o?a =H@'ɿEAi?;?U?Bm?H@n!?dP&i?G2>Ф翼|@ @?֢>y?4yT>Ὴk\2ξU0>*3?z@ @@%@J~?7i6|ӌ9x?U=:?]i?@ ?@ҰlϿMCzW?_Jdq?E6c9?s7n.?zQψ]?Pvo}s?0`W2@$%?^_T\?G?+@''?l>*a@>X>_v=V@!?;*@( ? ?w(?Q@~?@'zc@lJR??G@ {??=b=U?%vփS;(2?/@ۯ@Z@]2?hp@+a"P@E5n>=Z7@ o5@.]}>xGs>|? >?&t?ɿk??1z? >Fx>O\=j@*u?d@o?"?=~?"@b?Y#@O u>!@JjY>2оEG@tJap\e @LCG?Sbȿk$h?KL>za?uzd4?VmݢA @@t[RV@7Pq>zj?((,TM>? ?@I?-SI^}N>i'?),'3??.nu?6@ @(?nX@*&8?8a?Z?yֱG5@@$?/Z?J1ǿo<>n+?6 :޶t?"Ҍ@tֿgjy?I,Y@=駿)}=ޛBzNe?q>@8?? D>ߢ?]пEe*Q9Bu?f@j5?k'Sr? P?-h ?(|@& 5q?rKq}iD'?j?F$ jnV?g?窿jmIȝ^w?%I?2R>i;@?m(?"~? 裾sf Y?1b?R\nqXE?=eZ@o,'4?c?638>:z?ǽ?Az?:KCIYf>:E?pۿk?~ sTwO@@?.3:?ڃ0DCs?[¿3 ѿ@KQ9۾r@8-$@/=>A7Q4@?y?ӂ@O @>U,0@H(;?ˆ, A##ASa@±!˝$!@tH@{ @@p@6?X>Tf~'@4+z3_4-?E@3ɿ~@1Iy+D@q@zX@OE? SC"/M@%m;ǿ[>@fH@rU?fy%1<6žo??ʉ@cnT򠿉@Tg?@ff@V;@Bѿ X>x?Yٿ'IbA? 6?0hHD ?/@G<1W?>|`?@ecH>)}c??3ds?tl@}@$? s?z/ @A?0y>_?>H>iq?j/>?U j{@;?t4!?W9>$d@8>˜?p1/>Փ?5BmL3?c?.?Ŝ?!hFwtO@ ˎ?(@(?u"K̼Nʷr<=B@l@!@'@$@@>ݱ;v4))%C?>4?ڢ2?tA@&}?k>*"@p? ws?n$V?O?<?|_??oe7w$K''?Q @f_B?4rO g,տIo >>HId՞?yLm?,Ǟ߿}@ ÷@('vl?{>Me?i9E=/?:I? ȾοG>ᨿV8$$?bZ@jH>!^?2O?? -{|@[ fm'@`ŀ>F@0,N@*xi?HYA7@<4M@:wAsӃAg'AA*tKqE3U L?c}AB T u˙@@ˀ@Z? A*Y޾=z;ɿZa(?J@S>E@ne@mp?W!@AA׿EJ;@_ IϴC&~@NW@>gW@/?م??H- ?'Eb?%%?>VD@'8?5>a@Q>;#?WT8i4?F׿Y5q@?9tۿ>0?5lOB@0?l?f ">:m>5!Z8ֿvoD@72S@)RNݿ[;c?k=i,> -=H?oqI7-]F]r$?пVH?@ o>l?5?| Y@SX?#?=?TA[?˟@A?ؘ>"'j>O?-V?>?@}߾mP6@y@ >o?Mڿ ?R@?(̼*>0=? B*Vz&@~S?o/q +T s>pؿ~?ChQ/?O@k7r?e]1[7=H걿+񿥤>?B%EV?.?z??H$/?=اF^>@-b+%QioB@)<@99 8D?23j;?wL?t9q@PS>w>iM( RX @,@'? [h z鿡:J@^!@cH@V>;J= :Bj'*dj @M>@!?@@p ?  +@)A4V=TH2AQ}A7]?Bz4A%=AOA@j;p@0>A4w;*p?@@`@9@cT@߹? KѿP=C̥@>_2c>>߰@)@i, ?H? ?u꿗`&[k=:?7ŕ} <@^?`8;?@Q0!@їr;N te"?A@4iJp}=:m=@)>- ?3@NLg(?1O?@넾`?5i+?v@h@N=u'~@>e>tfCZK@7-@q? 15?9w\?PY?#bl#\>ھ}hp@M?; Ϳ* $@/w7s?hÿB .>2f?ꇿ{?7>w1>Kd>sd?$$@3$n???d?*@3,=?Ӥ?9>?Z?n ysL,l@$?c?=Q?p?u7?wܿ7˿k_Z7O?yrJB3 ?>Ʀ>Y?2?ų)Nsn(?Vʁ? ,v@)wPz? K={?*F?T:J/?#? @F. K?W?O?g\??@8B>@Q@/m@q?#/L1@#?Y -?6t_`0c?c$@ E(c@$F@>@o @d?)y?}iO?4JF#>ό@2@E@e+P~@,?]?E?~ Yj7@׍XL?02;)BhA%?>At2z"AA$4>s?HA;̌AO{@`@ż-$W;V?r%.W?{|5D?]Ifm9?<@ _H$%k eS>J7G@1?Jy? @E8@'@fᄐ8?)n{B9.b?%eK<~?̽=S@H?w?HG5&7?ǿ?3@">h@XI?M6?.N>?%?L?-v?C?˝v"=׫>!>?dn?Z+?I>@?@a_@$K<2AB¿Tç?K@O*=?? =2l `??T?e;4oRٴp>Ƶ@ ?8CZ6#?<>o 9?Ͼ`ƿǿʺ??ߌ?{J? e4K-@l@X x@'ػþu=f?X}i?j) ?0+qf?oP?{A j??ϳ?!0?L 6SnCc?:E?& |?`x醼ʹ>hW??z_>j"=N,@qy>uUV>2@0@ED? b?>C>c_8>slW?&p?k T?\SѿCFТ=ќ?bپBy?^N1E?Ͳm@̿!@S@ (??@{V"w9PS>6ã;;=ο'Tn#Ap@K}Q??'<;3Y%>@5[@. @f@?@[!@v@?Y<@.[i=X@B@?ӑ@e@"?e@7@eUDyQ@HXY"8A>E::A"-A,I@x@vJiB&R@d+@c7z&PV@@KNp@e 8pL@l%.>???#uH?s. @2@KĿ`@9x@7j@)X?}~8kZ ^ ?A2@ɋ5f99 @?2`?c?-@D?Rۮʿ9sݾϱI2/?I:2LT?p?OSs~I?Լ=">0E3??pCq@ʿ?0AO>X? tĿZJ??ߣ>L꿱~h?4k?9BSESdQpMF?1Ѣ@&%3?C⿹=r@yM%t=i>8;΢/?y&h`,=C=>/?_?n?v?sQu\>7>@o?,{8B@ n=&߾pwg1?K5>f_H3.G?6 ?p﾿?LY{`?]̿^Q?=7R@@׾Q! ?>L&?m?Ȁ>b+Z? 'H'm$YY[$%@WS{B`R+>Kv? 5tY4?O >)!@!@`i?X?`/F?j1@A?H ??Œ+> ̂@ Y@J@\㾭=f`f`N\c&i>W?ͿΗ?S@}bD?;oo@m7Y[S@ۿذ,@q O@,h>A8?^B [y8@0At[bؿ?ƞ@ş=@xA9^@@\\?@~U?Oj?²F4@;@KQb2l@E@6>!?'a@bĿ$?.g5UD@)?&?^I6@tb?4Rb@8?U@o?@"? ̿J@cn@t>~]k@`L?|e@~bӿ0 ??uH?r?L`^?XbY@'@1?F*? _1;X`ھSmD??8ؖ?"6h?/??Gb!?`N?@DM?l@]`¿r<@!t?%?Gֿ۠*>Rٲ>!?ziܿ|?=Q@4J?"%vMp ??S':Gt@?Db?@#鏿c>>?,?.C%$3?? ?fzU mp?Q˿j¿Aà@V?@?w?]/.?~(MN5͑?Rd\+@ɾX+?lI?.F?}?.^[?;?ߗ>heS(i2==ZA!oҖQKctlb_?l@t@+@ @BZ,ZNM%jB MA>@~p@AD@lC2?cAws:/>@|s@@J{?;@ WU@&?-.-t@Y'@ >S?L!@!8@ni?q{?Mл|?bBvz@bʿ*?,?_*?,u??՝-@3?;?c6O>RG?>-ޙz2]y@\8?FK?C3%@.?lJ0q=)v>dw=%@h/@@;`?~H?.@W4a@!>R?=i@n?eKvZ/@Y@ ?Q\>b?{?N.3=oԾ`Ӟ?KS>?$G?f=?H{>N?.@'=6!?ٝ?U?͏?FPh??9@*f侟?]?V@Dv@&{>T?'+@ N?^@57?6H2??3mZ@;4QG,?qu<>oa?iV`l`> ?ţ?޵? >}o?<ֿ$?ãQ?6z?>@>~=Ľ B?>>/$=C@N@A-A>k@w@3tf>|Ѿ#@]2S5(?/:?}?"R@?%?%?9x&WU?%@@i?٣Q>?> @i?n@$M@p$/_'f1@{-@z:?HXN><@h%bԣIt`?0D>@ſpO@TxdڿCz޿G ndeA fAU@A^ A=rw@2IAd?*,|@VA?,<@@,WWR@q3?oj*.8?n@>? @00F@!?{>J=9/]6,yce?^Z?F?Q@f p<?0>tS_?k7/pї<߿'H(>c@+z0@ؕ?^@s>*~:?}@ A=;@?9@gG!?!@Ú8L'rwɿk? I"?F`>?:?@㿢>~7q`s2?|@_@*]@ ,m[1?V@>m? Ϳѿ:?Vq;@V]?D??Ϳ@H93Z?q+Q?k}[If>v&=:. ]>,0>"O?*&?@樿OwD?{U??J׾վoU?Ū6Lu?=P>?ZA>u=?2W龘Awm˖?4?Fn(Z:>|P?[@6(@#vϘ׿?}3U$?@%r?ѿMul>%Y>#*?߿^l B?J1T??lJPXY#PĹO@Dt*0ӅRuWx@ܿ `aw@,@Yf8? ?ޏR 0<-}?{.>^@<8 @p?l? )Ŀ) ?x@ҭ?浔eFe@W@'=@¿rs@@iAt@ @`MY@ɫ|@Q1.0y¦$ABR|A/||'AaciQX?α@@n?A ;@ͩ@n.#?ӐjF?0 g0@PvK?؃߿G㜼~?.\@`@?sO1Q/@;?La e?y?={?|} AL 2?  M?We>@kt!̐=ʳ! rt%6?0@q>au ;ؠ2t ۿf}?/}?K2d@jx?ݖ?)@.:>7J`A7}=h>%$?A@0&?|T=9"Q Ⱦ sD>>@@1z?ƝC?dLJK?0=??Ǥڃ2?7I^5 ?.~h0?&=Ӳ?.U@[@?H? E?i1?(Ϳx?To@Zh?Nk4Ա?XT2?ѡѿ0Kj?ؓ>,K?$t?>4(JVB?/@b??Q77w,Bf?^b?1 ?./@9? ?|Qu+1z?&ٍ@7r)lK?>'>{լ@%?e @)ؾ9?=ii/}J?R?{4ڿ]=俒?>)?@?X?jǿְ@@9T&g@ z?2$@SO?hov Zv@)@Q??FCQ>H@-?S?m@ ? ɿh0@–@׿B\8@c @>a(H@V?@χQ@Y@%@-߾?! t־隩A ~@nP@ !?@-Acѭ9 $@a/8LNsU<);yվKMv?;z?rXm@ h>|Wݬ??^b@9@e"qq`7@(H5,? FU@*?˷>?S,T'?ak?lo0?:_??h ?Rf] @t8}?տHwy@ ˽%ھ0+6>*?jjW"Ri6ƻBq?%k#` NIw?n?ۆt?]osT=ֲo@n{.?kTP1}?.>gV>??nQ?k ?Ý t~>~0nN?rYS#q`-迿{7?>{]?Bk>S@ @A?x|? AN?ON?A辰v@̃?&?fMo?ƚ@f?=&Pjez@ x@ >?N, R=kT]@^Lsٿ?@[@5=?8s@oi>p? 2˅=rw@4j?]P@6ҽ@{ >ջ־>JMV辨BI@Q? D??̳?}8i=a?@~.?GW?i>@B~@+>?ݾ`T@a?:⌾$?5@;@D_[?9#Cg$?@ > YD@BY'@0 -@?_=~f@]?sȇmA@O@NL@]A>7@+@: Aa_As;@/o@(#>eCB*m@@z@r{ADjAP@_@@Qb@-M fE'@p.@@#[5@:>.t@i_?n@BAr-5>9@>=W?VC"@i؞@"NS׿??ecxA@@en?\l@&WiE> e?{w󝭾-3;>BJ?.*"?/nſʿ?%dP>ѻQѿ@? *`T?^H? G>7t۾<&?@Bl!髾SKhVML!s?>"~Z?@?TS?y?K7)S`ٿ3}B"6m@"?MN_?E]@/2]W@W^?R=M̷c?LeCF1!̀8P,|z>'?};?)?uE1C?G> O?ʠ=@W>7? /Ņr@-@P\(EJ?#>Fu?8k q3?H@?7۟˖DK@\Wf?"97?nXھG>q$E\s@@O??8¯@m@y?0e}h@.GA> ć?_&0Biґ@fIT@Y ?x?TУ@#A0Z5@bP@d7@=@ ox@?WﵗA8@mdֿ<9?տC?d%y@kJ/@+@֩u>3h>&b@`9=G?l[7Ev@oq@79?6<đub%s@Y@f@@VWY@p# _V O?o?x`XU/,?y-{?`>>F? =@$=ܤ>> <?W ??@">;s2>1$?ѽP.>z>@?#K?f>V?L?9햾濘,> @#?UͿ/>ouF@C@?1I&|>okh$x?4@[.v>|؉?I@=l @Nf?@??A?j@X?m=O4B?L?X@r-?p#>-@C1G?1g@?sQ@R"??:Lϩ?"? >5?C5@(@ =@$@fOԽ3; ? vͿ=.y^?q>P(>#>0>Y?h@ *.}<^<5{iEsW?If@ r??2>т>F @2?g{?ȝO?T?MbVFN?,m=??C@4?e ;忣 5?@= @. s@ᗝ@,B?:?Od{A;#@?@?to=ߦ~@eľ'j/Dݾwx??VtAr@ 6s?F?,OzJ>??5m)F_2O?N$@d<_@J?AH~@6C@!5goA^B@ A@@n7\>$@\oD2x5>"UR^=׎9?q@oо@@;\]?qqk]5e߫?C͗@5@XDY?V}?@?w>B߿=0Bc7A@>}"&s>@v9?c^>+C@R>F@Q?'fKZwtv@7vK?O2'6e>x@ k? ?7C@6&@J?[1>?ZZT=>M;=mQN>n9@o@`m;>4?2z?Vx@3;?@o=+l-@ܭ?;aݹ+Ɇo/Pt(@86@,g$j2Ku[?u`<}~?῜L? A_?!@/H!= F?B_@c9>;d??>q˿'S4Nl9Cҽ1@(?r?D3?`>󿢰Hn,>RL@Ap[@|zM@-h?B73>@->-1?k?>ǎ=͆Fvl?^@;hʗ3!> ,@56> ]F%W@ @z@|z 3.@n e4S^?Qtԓ@Xo￴E@)3@ y`(ih=?@/L0?|C@@:ru@ z-]J?>?{AG ?.;g@!u?`@F˾#GS>@;|*@8I9A?Ty|8@2"H" @A;9w#;A`@ctO/qo ?H<@LyAA8?=A|A[Ad>+h3NϋV@@Q@6@V@"@:(+6@ @@8>t ?SB}鷾4x@9 =yFlˏ> *@ 8=@IؿHDr*?-#f#Y&V@@@42?Y-G (?0 ?A᛿w?f6?vMpW4>)?迎dA?:?(8&?ι?H#@ 1@Ml?+5`>~r>7f@ &_,?i8&g,5?;V@C>la@!S?뒿6^j彞="z?]G\<Bms ?O?QK?? @R30?>eD}>ſԿ`I,? ?<4?@~`>CXec/n@/?v=2?k?8ƿT=W?.i]l>V.@{?B.>ɳ3?p>&۾Ŀ5!?Ĉ ?]D?U ?x>? s@1@?fW?Y ^Rd7?{+$uK[?> z`@E{??U?!;s'n>@F>1*eG|kk=|]@'T!?,r7?H̾ʐt?Dp@T:A>Zu \@ xC?H?8[@sn?߷u@9C]E¿V@PR2?^@-??#@<70z5ޒ@c)@]?>GN@p@v`ݢ$@7̀@N@t@o@^@_{@xmZAהB-8@p8?Ap"W?9cA\@C@A@9ծF )@C@&0N@ @I>@O_1;X]@@k(۠e?qD@@-@Sm?۾C@J[>UYb?@feMz܉>>-@~@D9@EYݿ3p?":>?@ _EqD꾽u@ ?:/C@>%?6>= ?@@n=ӓ@#>J?fXe?VӿK5+'bܾ"ƚi?xԾ?EAE?wA>Qy>덤@&[?cL?o9?G@r@d?pDnE'>*A3>?@3fK:(?E{!?^ul@`?y[y@! ?̾`?D}*?0}4_Cߐ?In4??{4Q6@|?7uRd`@*D?m>_@>FiѿaR[U>?(Ǿp@ :?&?OS<:q*3+ 0[H&@(z?|R@/O<@4'7?Z]1?s@ ;V?F;<>̲W`ڿ@=*={?lI?￴3@Zs@*BAhRk?b4=K ?8t?+?zr{@'qps@;?f-mP#=@@$@1@V~>AkO@M6vM@BAk@ l@'.@@R?F_/{?tAV5BK@"]?ͣl@avY?oS>?AӺ]i?wA@5A`@v@= @_%JE>J>MZ?蝽¿Q2A_@T<0 bJ-wPp@bk ?T>@0ZV!o@=U@5%u̚[8=7SuQ>b]U?V@ R@2?C @?O ?!?޿ؾp8>|KC?$kW>FGTfK?&{@.|=ރ@]?%M>|>l( =?RF砕?=1y@(>&-a?}̾RPuLq?#>y?]?w.>מ|>Ч?~@J-i#@?n v?P?]N"bW3 ?!'@-B'AZ@)ߛ߃ V>o3?@>@ T?-D@@Lk+@C?ƳfoD?һ?å4'%@?@t>@d[8?Eޅ?s6@Ƈ?^g >uc'\@YdB'HuK}c?V@ 6A>|>'6?|C;qs=貯?i@.?}[d@*??~+?S>YKҾ׾>Rd?H ¿/>!?Uh1쓈@J5?y| Z?~?6?[)?@Tl twy(BÂ@eO i?P@ 4K@2X^@@xi?=]@*?lH*?>Y U/;IR?u^g)?"LY(*ۿ@@7g?@+@F/l4@t(qi6@g ̝AE@2c@fA@d;Ɛ?A oA4Ag0=h+ Bui?IHA4z'@@Ϣ@c??y(Ht# @mP>0 c? JNQa@UD? ? <`S\D=@=@n)T=@{c?~F@ ?@v .@?uj?p1?@_L.Ϳ4A @??]޿kVF?r><{Vl?Z6% 7R!J?)oh@O4?h?@]}?k? +ɾc?^?10@EWx{EfO Ph@2ؿ𝽵HP?S??` @@bH"?ͼ]=@.zտl77>O@?]Y='>H?ƶl?W 8T!@gN>?p ]?SЊ'@I@@&X@x˸%NW ?A=@~?B?<>~?{1迍'?%?9?5w^?ʳ:8@1oy=ԣ?`[@@9s@!1 Cq@A=?'l?u?I?J=_?5KD徦0쿱΀?`B]?GP>ſ 8W- ѿ?ھ @R ;3?N9J?=c!ob?I=xH?1?%@ N>ª׿ ?#>(#t_ @m @|? a?@ '?! '6ZCe¾B@?l1?tjQ@oL@wy@=m Zt#Mo%>(V &?xct$@b<@*E@)hD>L@@K?[u/!?+AAA/E6=o{߾㴴s@d4?$&?y?d @Pm@<[V@yG?@`'@ f Mb!TE?,?K?~@տ@,T6h?mJ@2Vxب @A8??.407?@@ @KH|=>)6 zL$G eO3?B?WF>ֽae?r@$D6>|H1G?^w4@$?͞?ꞿ]zZozT?_r@{=?W*I@Ik4}07U>:ܿgڿ@v>kοӉ?ȩ>+?88]]tD?H?n?jDNS]#@:r@Rp?Tp@>+?T?KM`xPE&?ZO?>V?6|@;@N@|(^ "ݾwu??)@8.@ A r>ƥA@$:?W?-Zpy";@A#-?oiLq@gCY]?zZ-+_=l?ݽ?Rwc?-y$ @N@My{?9Koo???N?o@ ״@;[Nıq5aa?Z?9XnSĿF9U@ֿ>@L@Q?yqz@gѿ?6@{X-4П?x?H"סÿ'p:@`&?>*?r?@c}t>uX?3?#?sj?Յ=ǎ&ub@|@+Q?69@5 s@yQ?@g @R[?e?̴5ز@Hh@tjaϰν!@,@۩A q2>@+?$.?[V}WXWkҾjɿ?<~@ v*2o640a+jc8?Nm?Z>?)?N?@?l#Y@d6o>>0v'A@+O@Mh@MKYlg ?I>9@J~.>>8?1r@.a-4A%@_ >>@n3g^ X?G@_=0?T8pzyF?Ը@s>^>D%mJ_/2>tc`@K33> wʿ >`=h@'?‰ο!@@pI9@C@?.# >ſlTZݾ d!*?Q>`?nl@J?f ?O 7??>e?V?Ŀf`?-NS>x?D>=8?w?@y@qMTIdj:uB@-nͿ @VW@@A>>Wr<B[E@C>? @9@(Sf>4@3<6W?P:Kj?D9[Jc@>@B@J0@*w{h@D8??3-Z?8Emn;@@ 4)a3@Fq3q˿2̄@ ,? 4?܋?j@5ZEn@~PpUF @@j?>=I?@b,>D @@?y>w@0=m1TBs@=4>b(>[[?` 0@ п@aD%?J)?Å?<;=cw?#@U1 h1V)]u@?u?>VֲBF %?'{EF@D.>]?)@Ce]@r>g?)]?4hm9??>k<r2?U\Ⱥ@"1?ܔ?`&f> ~q꿗03ÿt@iތ?]Oj;>8*?|L/3}nge?KmQ?4M:@\,?.m@Xj@Vv?N梿C7?UWR"׶zB?/?Z]??Ŀ@xH>`Uj~'M?~?L?@,@J𿫼ھ꿏ݾ?{6PPֿ?g>tw@L??ԸS>@sG@=Jθ{U@@@_n?8@hڽx"@Q5?tx,@/@8$x!d+5Z@?Y@Ҟm6?lR@s%>$y?@@ڿK@wK~w4>Y:@ @A@tAR?/ g@d%Amb#s=@{#rA;>A)Bi@tj3@?PU@ ,@A-r@ n<@KBZ~@Վ@ڍ?@]yW?ܨ@Y@tŇI?²\?ud@@s*Qh?꿢Hg?gfJVj-\A ҝ? @!6@9+ȿp ȿᠵ@/ %])?KbY!@=y?96?>/K@?q q@a ?@Pɿu9/>-?&%??ւ6~?~%?6(d<@.u@:??Ҙ>s?m??~tvH?8ݿT>W@W?@x@?̟㟙91$׿č@??2j@qN^CLn7&'^Q@n@wE@Ir%>J@}?{ .=.(>\=<?"@Li NJ@T@+uJ9>T? ϧݿ!fmĿ<@G&@ :@ #c$z?n:>yk>@ @8L}!?@')s@]?˗?!lqI}U@hM?׎ڼ?C@S.t@%+W>}@@@@7apa=;R+<%O?J?#f@?F>q+z9@_F1@2^j?X?o?oB@Wp@\dAYyU@H@ N*t@+|A#8A A:M?+_AA eA7m8@1?Ҙ4>l7I@\@ EABو@'> 6@gɺAd@S5h@r,?\y@${!> @\{2~Uھ3L[@@.?5iR@z@EP?gA}@t8@@iF@i?cɿdu?i7c@]P@Z@P׾x G@e{? 7??D?n[?>!@@@|?hsҽ?bN>og>$8*!Fo? ]2i?u>%&N?|S2<)?>*5.=OΣQC@@? s=NzF@ z@ٴ= @?1@'W?f5?6n@Jt߾̕C?늫?l4v>Eh?'>US( ?@w(A?]?H:B6!; l#?Zۈ?^?˳?ɦ?Vj? t?7)&D\e&?X@Q{rStRű}=>5@V?=(?g _@wM*L?ʀ@y?&> U ?a ?M]@ ɾ 7@EʑZ'?d=f@d@?ɿ)?);l`>˗^@guz->;O<ݿoA =@APpY"S3z?}|?>b?&@??`^pe@4[cJav?L@[["@C)@N*<ؿ@ YbX@?4{"p@L6nqIBA@.?'@{RLN{ @nA.A@FIf>@JJ-ҿB@Dn?ň+Ф@Ԑ>踿|?&߇?ƿ7 Mh;Z?9=(G@y@g;A?7@ ^?V.>T?@c@@z? @<"@&E꾻Q{@s?rQ?[?*,'rKI@TK@>+ml?L@x?f>ҿD@Dȑ>=+˿d핿bucx@^sY?"2>l@DC?|"[Ŧ:?8|?@p@BN`J;\/7?؇qZҿB@@0*$[w@EQ_>_T? QN$@#?/@9)ھ" %>C龫K=V@,@ ]Em>J@X@8/Wj@Q)@ >>@f@-@uP$P?Jn?К!:>?s].f?k?[?>? pe@ >?B'?f7?>1Ӷ?W<ݤ?5 U@ ?V2?l?>?Q3@Qu#ۑ=?'M˨>Ϛ@YJg>Π@v@2??NA?*e?Q@5Z}|?ۨ*@QU?@>F΄Y?ۓ@YX@D.?ǃ ?ަ@W)@D?U&=Y?@2Կ~y? @?1?/8@v?@Yj@??>-@ U@xu?@8A0A=[1^fArA?z?h#AnςI-FH>A~@.@@PA"?=j& %?rS, i{ @v?u * @?,ρ?D @<>eN/`?e3@[@+>?X,F???1G@݃@y?c@jOJM?G\]td 1NyEz@D9M>R=H@ܾ}@ۆ?H<,H@ivCN@>>)><?7>Ù᡿`?gWgD?=;@?ꝰ?D?"Bxq?$?qj!%@?o@G@+?X6 b? R"h@>~GVFAj2>3:@!@?'z@o~?:aɿr]5MP>Gkb ?R@5_(MO?s*>@OUe>?1XT?k=Q?N>4)v? >-- ?&Vm@j?3g8RT@/%?$AXI>DQVA@I_??0@#>+?d@P ?6eB@DĿ@b?^@F2ž@>?zI$s?8@Eh2g??؊>SZS>@)DF@>"4>ZDr0k@x&C>V ?l9??=bBn@9>tbfE?sz3ч?7a>t! xrA'Xn@pd׿d? R@Mx@cŃ@2&@q@X:A @ $9@J@~D{@nA1uW꿅o]Ut{?[L@k@BU@CO, -@?Fm@`c>@>pn@jA.(QT-YC@?!]&53=#?79?N@\?H>?B@ZEeW?j->^@@0]?W@@A⃒?G@?GgoU"hw@g0@i*-H@?_Yo>?k.?ο`J*h@C?4Kǿ `>?OT=2 =>u?5!@U?2\>م3(W@@;V1,dME-?'R@=h#K@^S?[r?-?_u@vYܒm4z@F8;1?>=-ǥ@Z>@?Ɇ?e@DCD?F@ ڋN1fu@pF>=ˮ@Z@ @Q?ɯp?_2r=Čq`1f? ۙ?aw@1@Y>e?gxJ=>VJY#Wra@?2h?=%A,?k.K?M@U?O9@Hf.L꿾w-fnRq 9M^@b;@Y@?,翗@Ĵ\9I}jl?Ⱥ3(?yAN U@@AEj En DxLA0A| /=? AYOA/@ˇWJAkɤ5A((@冽79^@ey!@JU>2S?Q?@h"@@L=(>kF*?Q4>?ϡ?@ @2? @@ݿ%@,a~[>C. wkgD˯<~?Qk?@? r@gJ;?Q&^? 3U@,@?>~>?@/Ῐ*qۿ#/?+Q㽟ӽ?lU!,@ L43mjnw??"m?0DRT~@O~?|x>Dͮ@JZ=>=F=>l@H&@ܿӮ)`0'p@"3?Ʊ?% ̿lSN2y@$i6XB_=￘"?RR@x=kG?,A@_ ?OHٿ]#R@^sO ״-w.>@ ? ?~c?OQJZ>r?v@g+?nVD?m>3S?8ҳ?@Z.{?\@:e@,8m>G@2B$r>@K@/ @b{Q+w>,Uk,?@E@O9W@MhP4@S?畿Wgt>&h X @61%kG@r^T@f?1f=r?@}٨uK̳?N\>/O` A@Ue? G7@m>oC?Q}\?[Ĺ?BN?AB3 ,u@ф@8e?Q@ u?@Ih@~wqH@X?`r@G%?ƔJc@*9A;!A޾fA&C@=@|üGNA@~@fAPAp@D@ A5@u>@bA[ :^k@?aRTr>p?FA*N?8Z@Ć@@@L@eKXh>ܝ@P@-k9?@Lm1˷ݻ@E?hh](X,@퍿@E@`?gT@@$?} 1ÿ`Vk=@+;4@@oӦ?A'WGw?#5@`K*?;:h@$@<@y@ e.`Aif@g,?b>3?ҍ@r\@V$3s@4%=Խ2?r?mҜ>龵T*Hx??-`@7`?<3zs>lLBJ?Ќ>}@%T@RB;4>* Iׇ?}Q@diJ; 4C>|U@ ̿ >B&'C?+T@'u?Ø N&@ ?z?s?%G?Z@/@g@Er2>ohj9? O?I M#z>Q=@NlGܓ?7[E8]f>mbhK33bmI2(&> ?.@9$?>>F?ݿ}d ?ZF?R?)`s@CB[?e*?)yr+l@II@gc?=|C[@G@"?G>e@ V|@V{??@]궾<2,?3L`Ͽe@(@^sX?7?>űF@`D>zV@Z??Y'>/L.@Hy@(?G @To E">^cV4@ 2@9?+6|&@3$<і?X>/~ @`Q@c s D2{@buc?i3*?eBB#->GYB%OA=p@$TAmeR@7,q@fB$fA}?z+t@8@8zІ4S?v"@ybcށA"@:?y8V:y K =H섖&?@Cnͨ ?@O$1'A8y@{5@Z>@?@)[G? @>2)e@G@oq&#?Hӿ@@fY@,PB A?1@&@P@Ne@ Y^G!QT|@,hA9+R/h?Z ?&(?4@ZP"6@0@$s>K ?c{?@P='N?>WU=nc?t*q>'?ߏ><@*া"WYP>S ft>w? o@@A@ 1\@aj'@Ud??.ѿ&@ p47?y|X?v-࿡١??@ lʙ@_ CE@@@n#@O/m@;g9NY?nJ>B?ln=[4??.vC8?g? tk?95m?ya?g?H7X>Wg@?-?%)??:6@LX@a4>kkU+&^@*p? +l@=$>*~@2N?sa^W ?7;D>Oj$@Q2-?m@q@8 @4@ Ahq?s@7nj?&@@ï?O<@]Tl@j@-?=?J?I@ d@>:-?a_AABrA/@"j>o@-A2?@7@KAh?A A5翆lAZBA'd~?&%ZDŽ@=?o@/S? 5ء@)b{p@?@P@>V@@8?'rY\?+@B~?si?wOjFvO8N e?@ ?h?[?w=3?{=H@"@/>@44F24@!\?A@1[=FIN@@D2???r`@NkNו/j?W*x@; 򿘢Cr` >+ڿ..VF@?|^?M>O??Bx>Pd6(aځ%X@ B lQR=&@@bCU(@N?@G?n> ?"o?X>2>?E  A>D꿫W@5?Yn>H 5?KBB<@_{g@="?D@:Mg? *@!v?ˤ?4@s?,sByq0=?|SpࢿJ/WҸ鿺@<?VA?[?7?⍾???@/ @!E9=*@(Bq?4@Xf@ o?d@L?v?pkY>@@,?Y1)@I=E?+t@ @?!>R9;@1֥>E> Y` ǦA@v@ ?E@&>{9"? ?_V@3pR@Xv@|@6j?9? 0?ZB"A;"@O@_B@[@翭·V4kSBAk@ø@9jAA]_"$AUC)\ *@]@s@F@R@Z@rȏAQ@9@rxAn@t3@{?qz@Nˉ&n@' :@9@Ͼ?|?,L" =? %>@ @ Oz~Y{@Ģ竿 ?6 X&@  4b?K5?\@i}[N?5;z0?`>?肄?mo(@hy݈| >MNW'~獿u?@G@43؉>"?=>Uہ@LOA@Ku?M >hY E@}Wĕ?K?@=?dh?Fm@22;R@;* #x-$?Ȥ@H@򰘿㼃o>>~G@I0z? )EZғ8!ʿ͒??@96W>@P@ ]C$IJ-@Ὸ#$?- Q>+@ 7@GCY ُ?ߵ @\h@P5??;@b1@On@iAU|@J@u!??}{@G3}s@@n@A!ԱeL@EAwλ$bA A0'_A1
GJcރ@ =U8@0Wu@Diþu8? `@x(۪D Yy1?25@SO@^=?W$?Ix̿ض0@/o ??e)A@?.yp'/>¿??t3n#?d?cc?lu?@B :srl@:S?3@ &a?`?Z?!3 87^I_RC@@$@Z`le@?]ݞ '_@,p?TdMGU@G@D9?$?{Ca^Gg@rA п^@F<;?,e 'W3FVq d!ioN@6@q*@# @7W.@1Oľm@D%T<͢B6/bo Ͽ'd?R?=?6?&c@rX?XҸ>R>ψ@PN<ؿi;%@vQ=쿯o@(NO! >7>Q@KRf?XL修@@c>\?6?`*r@/!K.=b O@##?! @&l?@t~@3#?X@$ͽт;`@{p@%4@k2J@QmT@|@vӘ?i}@(=h߿o?M?.@-hD:L@~AA *@õ1G\l@Z>@ >?)=ۖA䠒A+|B5A'IAdꢡAy4AEg/D{A@ ?}kA|4(AABAz ٷ3A'6NZ8D@AA~?]Z>A@N@yn@HED@W@M@<+@#?D@Ylo?' av)wEc܃?PQ@`@@Y]y? ]ʇ@Ng$ϚW@,>Z?<>W@&@?2A~SβОP?Mo Ὼ[@B:1@Ʃ#"@Uο%ȿK?w1?+ȶ?rH]ƪ{?!@F/e@'0? >*v>|?Ō{X>d)5 Qݳ@ĥ@1i5nc @ N?öO}A"@zX ?$B@Qs@8U@FEm?8uEe6K@|y>;@$(r!??Ѿ@^{?S@3?I?y?"P.@g@V?@@†@>E?"?th?~z@_¿\<$p-R@b ?g$"?t@!@xԿ*@hD@K\/@c'@(DH-@D>KO@Yz@G@@y(c{s@,?h&*AVA3h?'4P!zAJ[yA YA@W<@M?1 @2@v u@c@/=vI mI8@G@#[ ?rU@A{ @=eF8A?Ha@{@= Z9?ש@a+R`@ @m@4@$;@S@P$@5@qk$6vL`ҾdĿވ@@~!U#u>@w#@?&'?͆@/'/@Ǝ>孿T@R?{XE@?S$>?F,)V?c@1?}R?Q?=>?aQ:??S@XrW>A0ɑ?7|[@!?_ @@:j!ԓ@c?@>>X?QT@ˬS]Խ+Is>==j@ ԯ@]XG}@F>-@@IEܣ?ԗ@4WR?D@7=$@,@]X#c4@D@Bb!)&@2 @U?\?@cTN;1]5?ˏ6Ձ>ߍ>S@ƒ @JՈ>@"h#]l2nB?w1B@ne@v? 0qJ?RM?;@$>cA@@>ֈ\?}h.mpw?3^h@vӊ?sۑ@ueLn'A?@_@<1@z@4=?P @N?g=L(0A[}r@`@@'gP@5@Fo7 !@S.XU@xy }s.I(A :wAhsS@e9+@#Q_Aۿ;"@?ע@ !A11>4@ܛ0@W@uZ@?Q[د?o9ɿ7@UNEn#@[@vL3@NGC\`A?@5+@#!??P@I@s?}@m[@[@)3=ҋ\Imž=rZ>1TGTE@DǿkO*@QS~ ?!y?1 Y ?(?y >rӿ@&@#t&X@ŧq@&;>ܭQ7>Dp@xM@G4@a?xEX@?2@W?+d??@tO?Ց?[zw/@0fF @3 @V>ݮ?B9@ExL@?\uP?a?.@9O%TBd@g0?.@ >k@6&cw|*U@`L@b@?@RsӾ=;@ l@Cdh@W)@&'>R @K'(2 6@r^K=?1?֕V?FH@Te?]@~_?ijn@k@F 5>@z?>B@@t@S/rQ@K># m:@_@P@чD=~?겛T}?bm@m@BgQ@w=hiȗz>a'y5? $@?2@[@@"E]@1@r,t >}@Od@wԸ@ ݳ@&@+{L@-*0BA A@~A0LBoo)RBA:XYF@ԻP'ʾ?=JC?DAY Wdl=ir@P?>H~@FQ…`X@V9@B(@@aw@6W@›3r /-HcTA> c$QBLK#@FGq@ixktٿs=>?AnbEc66 \\M@?r oE@悤^?1?G@R?|6킿ɨ?oiC>Td9>@{@i>@W'v??r@3@d@w?fVf ?>F3}q2n*.#@:TWﵤ?[C _?4oc@d[@NV@o>q4?jc@ ?2Zu\JHz?8@6@(]KfsK?8?@w (t9?ƿgNSάқe/?r?XSZ@Qn?Emv@o%>T?ƺ@zu@ @K.A~'ڑ/>@@ =$@g8D%Q?M?U) wkbYB5h6d?6@(@:LY?r?΍J@&GQk?N?@?3j@GTL8\o|Կ*࿾@@͆? ?\:+@u@ @@v>k?Wv?x@PE?ŒS@@?M@l=@;=nV?*@c6$H!_>?w@|9& pȴ#>Rg=D(@|5pGؠA3@!0A>?d?AP{S? F[6j@9bcA1{@q@| [uF@ @C}_.)@+@x ^ AA >xU@g@/@H@B$?L @w6>9Z7@b@@(4uU$-@7?#_?3=h@:@.A!"XE@w@V)?V?TOMfן@SF-?W@ >?D@8cKEwˢ@l?r@SV28XP?Aʂ@r@{9@?`>b??#wE?@"@uM@ap>W?@=c]2@@9~ =-*?$6⽵`?Z8@q@HC@lna@%@ %@zu?n'@`>$p??r'O集YIe@=o?L?.@j1ڿ>?G=g@W =o;@9jI@I@NHDZk?е5R?\20m@Z|e`ghV%Cq喿n@lو "ƿ@A`(^HQLA {3 @F`?h@Y3@8x?R?i@`)?O?Ec@2@7t|@Qķc@9@"Z?}WE>Mp?46k@Nد?nͿW @@w=?OP@@/h@@6aGr@_ @+@4*- ՟ < xͤA&C:n@@_(A$@fbA'S J-An.!g@s׽Ak=ACA-44^X??8AG@< ?taw=2"UEAb!N.͵Y]B_AaC??,AmAxaoA@@%?@YÿB.A|>1k)@2@пi @ <۴@A)?eW+,Vy8@*UZ@ߵ>9?g@? @@@4k@;߿1@/@U@0Ds v-`yhyl|7>@k?@qCGR@l?>@F f@6 >&@^[pL"=`x@ , ?cGCeD@D?@@7l` ?n+n>?@3DNJVSL@ä@xr=Ӝ?"_@?^?Vx?u@?@_?E@a)<)?a- ?Sɸ7?)k+@y;.?ɥp@*rh@aE񭿿AT@}?k@@@ et?Y|0G@Y@ⷿ@"2@@cL?{@'F> I+>@pxT@@7sMYv>A}n#@L>g!@kG5H"K2]@4?5@!@>@i޿R6>>vis@@[t@yBdT)t@p<ĞKK@lA>E@փ$A6G%¾ @9\!3YS@[/(?:V4@6O]A ?Cs@ @:@:@GdA7@3 3A2 @k>A4y؏ %@ i@?@f(Akh2A AK aE>,@.dk@A"q'俸 9Da@JA$@KFK9+ 둷ʭ90?@.&@m&Fd_?D@Vxڿj?/[?@"q=@%,Ak)AA@D6( -!bbsK@@n]@Œj @->ҭ4?\@>7QI>jV7@S;{*\@T@&RWXjo?8__"M@}45=׿J"*@sXB_?0b@-fB{@?@4 @_h@,*pMT{4>>ѿ?%@2?vu@>O@J߯@\@A?C sW^<e)? | / ?Uz-|ῃR@@@7@@Ŧ@mP_@l?a@FZ@' M@v̿;@aA@0MR@1N Q#@"'W mA .F`>A '@xl#NH=(X?cOA @0l@6C@WP#A^[5*?@ @@!/l:@0@ͤ?zſ1AYKӾkLDŪ5.AKBmHAq>P> ,Y_+rABA >{3Am~KA| @AHcA7tA;> eQ^i?E-Ab\A+A!R#l@0}@Raf@ρ.A&8)@yAJ ?ܞ@?nX?0TH@&)?UYF#m+bxQ@h@Rw?JD&4@#?4@pG@AOAO@V\@|A56EC5@JGA]z`?j@W@m@E@9@TʾB@?z@8.@&h>鸽@E30j?@ @q>"O&2?Y@?R}g$@hS=U$}@e@@ OaP ?? @%@H?Y`? ;qڿ A#uH@t8e=@?q5&]u@&?jo?7?_=80?=g@gc=@<6FaI@]h?az;O?ܦj?wG ؿ@[@=q'@wxMײP@\@?# @<@@H7@%>@6td<,S}@WٚB {M?:@'??l/ @׋@E?g\Q>Sk{dsTh?@@{@dO>L A@7@Z@(AmT=]@@A}@QA/@u'G@4^A%@KZbgAe~1gH4h#;N¬ICw`@A RA l?!~UA@f%C@[pXFVAmw ?DŢu @*8KU?i?g?h1%@c)@(@z:F H=[?`@kn+?x@~@sfֿ)쏿W@@6?{MlQ-Uwqs"ZC@fNN@F9_h@AXm??خ@%!j:ſݲ >@x>$c@??8?6@$@Ka)> ?@<3>@!0CH@?{l?Bf@k\]vG@i=?(>Xw&(<\@ =)@3?wC!<X@Կ 1@S&F@1+h͋? Sڿ@$q@/5fS^6@1@i@2+A .-@/zz[{??`J\@e@@6{@-7 A:Xb 7?PnA)f@$6?OA$*@"8 i@\ }+ĨpA+J: ~J2@D@J@>Ӊ?B(3Aqfw%C@P7"4?/4?t=A1@ѿ@ @"ݿc@n>[ ?ݿwcYz }?f[@y@3h?sv@S@>?ݱq@µ ? Sc @n= ?'A?"#^pO6.W@Q& 4V@@bC@?2ĀsxfQm@ݾ)?? '@)@!@h@@>5YLnW@=@;?@ DBcE.X(#8;@{@ RQ@)Y$ͺ@F6L@ - ΣJs@2Կ}L* ;@@a?72͊@arڿWH)>@Gڿ8@@?@G ޼A >RA?J-J¿'@= D E P W@y@!?F?}?,F?/@Y+@Ă@NcIlUыA3AW,A"ndTvA_NK@AE@WQ@ x[ :WA*(ƌ~KA(MBtKR06A Aڤ^#)@@ȪRA+fAA 3D;O%@@m@/x9O 1@rA~%~$@:@?%@CKA9/g\AWn'o@N|IV@xAԉ@~6ҲA-30A7K? ee@?a =;?@R̠P@[@ĮYMG>wW@v??@AL%߾K>d>)O/@?XS)ߑ@ÿAAU?Ն? ?' A%@;?@@m=e@A\?N*?]3@Q>I?߾=?迲@ژ? @AA??L@0t?ɋt>??K?[+@]2?cO?%V?;@o@^Jb@]yB_ߜ5@܋}@$|.F`@g@sAV7a@w?-)#?ǀ@,?Ž@(@r@@ .@@{.@?}6[@ZKrc?g@i_@<?9u@e @@=e@j@L?V옸@%澱fԿ[@@?]j@Gn?9c@;;@.oXJd?!L޿C&@ m9?O)@.?@>?l@@ےc@@AAm?ApA.g@USqfž@-#@ E:H?qFtArA;#AS.?\@}@A5bAdiAAd"At y/A{?dUA8.oLj2 lAphc@IKH)@#*Ay@CҿB"AL|1n[ ?Ev=}A`#K@MA??5?n@ӥn@eӿ@ئA /'H V"@ @Ϯ{?L Wt)A:@.ͤ@$A2 zAf*@Be Z:@Ճ@ @Q;uE@n>U|?7=A6{Pf?@ӹ_x@C?d.U?pݿ)]=z@lx@w.X?@{Zw? X +A:?ߏ#Q@N !"y@H6@Mk@"=Y`@X/b=@m@,?_$?(pUa7?/g@I?FTA"i„K@PG J<ϭ%sN@>}#y^@6!@sE-XB>$fxQ>TP)p?Լ?ޡr;>?>buO>w/@E@]L>@Y\";?7@+&o?~bXf :s(8o@?!@ )U?E@>c;{W w@Wvp;@ҩ@ g@@Gn +@ &fYa!@Wf|5@u F@{@2GR{R@A?&@v'үP_@;/4=BQ@^? >@=x,@WA9[ky-@@c@-Iɥ-@!@d?[p+@gy@=@`@nAa;b5uxcAkaӿ=A8*@\pmhcL@[AuBA0sAq\A(y@C7@]'AAtA;AB?-t4rA0qN?Cf?A| ռY)EA!s~V~.@> @5@ɽuA:þC%@w,??g; _A$}@HAa@U"_蟖?k?Xev(5?oimq:@Н=@u>=@(9r@|wc@$m@f@@o:b?2a?@`@ahlԿ3-@Vt@؍[Ʉa@4O@@@@lV?l@qmlK{rpXVy@A6`>7~8>A"@@?k4ͽw(&?-=%@e @f @n1 @إ@v?ls@@?VBO?`K@+@)@VA=~+KNƾ\Zj@k@>@PN6?@пtC@$6@M?v@E @&Ax@I"1A|PF3S'-@"pAGP@Q? D@&?dB,AH"?ymACA#A'}BA j$$oA O'n)"Q@m0A@hj>W9.QqAScD^i8״>ư?|@]@N>Rf X@b9A:?1@`2,r= ?ޠ?A@>FM犿ey@|@$ @Z[cA(@Aes?Qq@јi=slC(Ud@>SG@?rOc?cF= @$-^|+AT@RF8@#?A\WN"A@iIA"/|7/@MA**@ 㿉9.@+%@/@3>T$~@q+NVz7=S@@@ [?}A@tK@l>?5v?; V@W@@gh„@pLG@hz$!,[@oe@A @@-/.'j`=~,u@/޿.@/?ɏAux>Rh??|?ɪqq"s*z57Ad?Ah]@ ;@ $4n\@$z@BԮ@FP@ 1]Z@G4@A{ @- ׿|?@RV@e:A1@[>X9l?3@(/~Ak@@V?3>}@q6AaA@?@AA˜2aA'9;@ګA 17Ae9T6@8mPw@RAw)ѽAzAchlA!]@_M[A/YG?b-A:/@3鿓?[>}UWS_@6''6@x Aa> 3ݒ|8Np%@t?AQ@ڻp? `CV' {@@@S8.I8+s@P??AKS8@!n@ @h)򿵘;α=A?J/ mdž:s#YѓP@b@k@dc@,>@7~?-.e>4™(?w@7? 0FN?i@?F@=Mq?X}A(}?[DM,Af>,9Q<`@0i%L G:@@بS@|@ /K@W?n6ṿJ@]f?G1@Z?cn'?@U|?LA@7ԖAqu6b]>NAF- ?/ s@sCN`?Q>%o9@@q7@i@ҎZwV@o" |.U5A@g@` 4@NA@\6f@{@@0`7gVAw@P@^tpG@SCVA<pA9A Ag?QZ0C@>@BAJ=&9?@u@=>rʈA2B0#6-T?reJ[E&_A}TBT_AA AIwE=@ƔtXsRACAm =BA@A8cAO٘ @tA{J AL 7]Aw+@@>c9@7@6@X@z}j?A >,@?]@A.<@D@$ ;@p?pdx?Pt@1QA@W')@!@]AF@?*p^@j>uA-A@h2Lzc0f4G@Ͷ(M??>9)?g> @ @F@4Dfit@^YAY?ue@@hC9@O4sAI?k'Q?@B_y@ f?sIA0:ά'Ƞ@?Oi7U~8/@L@T@fAiU^W@F>w@@@55@:>C?ӿ=@~z@/@i!@Dz\v*?@ޝG?@~2?ah<^A @ 9AA@ܭwv1@Y@J\%J@t>a=@o"@A@F0@#.?O}t.@ fJ x@t ݆@)w@@JALA>3GAU?HA]*U;Y>'%GUB?A5':G+ApZ@rb%AGYAu>lCUAVAzOҹeay@YAA 6B8g?=jIGl!A9A~t@iA? bíAiilA8@D@r6b8, n}A}@LNq?AA™Az@t~5@@KA0aZ>ؿČ@z 4&wNSĈT@9v)6h7?`@Gm0zi/cAkLB?a?A @l@@ ?xm?N5AJ*@&/D| @AKY@c0oܺ]ܾE#@Alf`EqAt>@"3R@)AB@* ƹq%{A1.vc?BA6s:BAv5:+Ar?DAQR@JDj꾄!BV@(?wL?. >\A*XA@ )@n#85{@1?]`b@38@yL@\ ԝ@t%F?+տsG\@9@+C@~is A B@D@3<`@@@j@#ɹ@A^Ki@!@Ai Sz@fSY @No@@ @OT@AbTd>A1Aye@|?V@sum翣-'@k@C7AfZA^3AV? y|Adܿ@>̎Ao^"@w1+%fiA]<մpE?tB]B%2@P|#Kb@Z4{HAg?GpG_,ACA3PTK!APA*F@&@+eI1s'>^ξN@ :Ai AF4A:L@ʋ GL@O+Az?T@0@5=LfAS ?{?A<2nA6=[@8`PApY0""DFz@?8@c<2M@f@@A"93jA`ɿ^>jIѪ?tA6Ӷ@o9 ?+y%@? @L?M k#AA}c@QA>EA҂bbcA!-z[ @p@i$xA@[ %.Alm@TAғ{;@xK-AlDAff*RcZAP )@HG@>@W@!i@}4h0@)@6>@$թ? PCaZR;@pi>xD@>@xT?q@dcn?"2A3\>@B @@@+zA#_=@.y5ނ^@brsAX@ n pMA+6AAAWA|-*?@A?!K8RA@5?(@/@2@"$@!Fr@)1cA P@gK?AE,Й^@k(@@f=f?J~n'.?`:A>BA?ES*A"AFKA2`A @$'H<@t»A c_A@K B!4n`@CB$Y1BB 1?UWAI@dAt ?} @AA̹{A?Y{@@L<yf)A 4ABC!Ws-#A}nlKF[AWǁx?E;F{AbW@?@60@FBSyA @eRMf$w2GdǩB |A:BaE@5`:@؅A=c@3fi@CUWA; @ݸ%UڅA˳P#@ôÀaA>AC5?Ԑ?oAJlW7@sk'Կ?oe@i@E@aOLA;@tAZf'@l=A63A%A@PWOƪeA?U-@boA_Am @f5\@oE@_X@ o@{@Zr?Ѯ@{CCtX1@2+i@E?kUA4/@,xI>e= ?R@ vM+.AS@A;kAvZoAB>^AJ?@c =hB]#`trD"p@doADj?Ax@@?HAk@7AJBd@2<\A %A@ڹ5(?`D@eB5@I@yp?P@S @Ih?Sa4@¤AL4?@L~!$-RShvB[AAqAM+Ѣw@</&s@k2?BV^~@?c?@=R>T!Yx;'P4AK@v>@4@B?7lx@ZA1ꗿ@>_&A$-AemU'vA?A 6apn@a"B@T6>~A_Ps@u?@=@ >V@_^fA n8hAss@@BAۊ@aO21CvǬ||?DL@\:Y/A ?'?>>>@@u%> aA!AI R"A/B 6myAb҅NA A^.zB" AV?ɹB[\fzP@-lAA4PBbe@@LVK3|@|@:'@ew@G~eO?8=$%[A=VMFBB>X#]+0wNACKAHrCA*%@q(O;S:8xAx#A0;@HE J?@|rs@AP,MATAo@ l@k@@꼑,@jA"2$;@51twA"j;A(F'>@y|@V?@A>5@A+/6A8Up=?VZXȿlE @(&Ap¨?hUAtBd#>S@N@(|l-b@Բ~?yjV *@ᄩAMAAA sA [4V9@IB^7Bs/W;A6BA+`AA4QfG@KY@F?@Dcp@@0A=@[=AўA٢>șYe@=?ǩ%@$yN=?A*e@A >EhAp@.@G@?=>jAWf@|a@M1?Gc0JA *A3G?Z]"AuBVс?@+p F>*?-@'T@r,@@%~,A[țAGjB+$/AAH@D:E)@[J@PAX@wA2:K@Ļ@rsA:sz1A~A#2K¿DlA>ˮ>= ))A>u>BR@?A@κ@A>/S7R 0@|@,A ڻ|;?ApmABV4B0 B?%I?3G?\@,>z}By@UNKN_-AA{YOBAB"%AwAAG>䙿U9Aʊe#|<?;dmBg*ҿsA<@`@fBFA"e@y^+@l@{AkA#5\AEA@-;@eBAАAIBG7 Y1DT<@.2A]FD'@Kq*@X@B@TA>pB lA¾BM%A Xޚ@?v^@E4<@@mD{C@DL,$*A-A+u3@DvA'?O@W0A(d4  ?`3(A%$?{7KBAV#Aht?׿vAJ/5A,B>vAgDAӃ@ I?59@#.`AS?.A,q)u>E8AB@N+@AS@+YA_l@XC?@4@}@EA?3XAݲdB #A,B$ {18^ew@80.NU@`6AΩB/-!?>=5B KA @ABb=D2v3Kv@`ABdXTENSION= 'IMAGE ' / IMAGE extension BITPIX = 32 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 280 / length of data axis 1 NAXIS2 = 210 / length of data axis 2 PCOUNT = 0 / required keyword; must = 0 GCOUNT = 1 / required keyword; must = 1 EXTNAME = 'hits ' / NAME OF CURRENT HDU DATE = '2008-09-26T21:31:54' / file creation date (YYYY-MM-DDThh:mm:ss UT) CRPIX1 = 160. / [px] TANGENT POINT X PIXEL CRPIX2 = 105. / [px] TANGENT POINT Y PIXEL CRVAL1 = 41.5791666666667 / [deg] RA AT TANGENT POINT CRVAL2 = -30.2747222222222 / [deg] DEC AT TANGENT POINT CTYPE1 = 'RA---TAN' / GNOMONIC PROJECTION CTYPE2 = 'DEC--TAN' / GNOMONIC PROJECTION RADECSYS= 'FK5 ' / REFERENCE CO-ORDINATE SYSTEM EQUINOX = 2000. / REFERENCE EQUINOX OF CO-ORDINATE SYSTEM LONGPOLE= 180. / PROJECTION NORTH POLE CDELT1 = -0.00277777777777778 / [deg/px] X AXIS INCREMENT CDELT2 = 0.00277777777777778 / [deg/px] Y AXIS INCREMENT CRUNIT1 = 'deg ' / UNIT OF X AXIS CRUNIT2 = 'deg ' / UNIT OF Y AXIS PC1_1 = 1. / X-X AXIS CO-ORDINATE TRANSFORMATION PC2_2 = 1. / Y-Y AXIS CO-ORDINATE TRANSFORMATION PC1_2 = -0. / X-Y AXIS CO-ORDINATE TRANSFORMATION PC2_1 = 0. / Y-X AXIS CO-ORDINATE TRANSFORMATION BSCALE = 1. / PIXEL VALUE GAIN BZERO = 0. / PIXEL VALUE OFFSET BUNIT = 'samples ' / UNIT OF PIXEL VALUE BLANK = 0. / BLANK PIXEL VALUE END 3    :!-@//) +/Y:3"  =+%$'0"*6=oFE3 5  33/+#"$49LRoVB 4&9  $WB82-<6LWVqeY. !'+).,'&I* ALDF=:AMa^|oT6 +P5A04U4%?fVVUdUbkogbN$  #95- FAGEI9P0 !7hdfl^s^kzwwO0 @1%4 #.-=2-#;lS\OCi34jwyeU<! R?+%]6+)',) #$54LJ@6>n][^OOP2Xt># (3\wCA;iZRF4R& #:FOEMABrm{ZYZ[/  SqQ) (  *%+?{`NLnnp`NOJ( (5@WRtc^TS|{fJJH <`|V/ +)8 5.6:Tfh~lhlC# (Kaaq}bg}wdQJ# )RrkxC" $\[:,5.?0#,='0=QHNiqvqlT?  1]rxvmPH"!!BSsjR6 @.6P[|zVJF>:3'6;:%"L0$$5DKesp\S<$ 3LW}uiU3 )C]pV8  >AHi;ikgZcaOLA`=91EE:(.2]vxpSB7,"%1cvI.D)%+3dsc?& $%" '(+.0.-/)27:<;>>EOLM\[GIIQ^AB?Cj?GFJU[BBKFi=BAEAkBGFNW_=EAIT5875S6/-28O$&-,?$$%*,K (!,3 )/3 "  #7@lVsopp}iSZUZ=-L) &4P*qkZF@4*&*EUbvRG7- %7;89Bb nS<+# %**($&)).-*!"!%&+%$&&)6C2-.4BF7<3?R22*.H5!'*<G "5&;#$2,#"1B"73+ %3 %  2 $"D6*#/mjr|pe|kZ5<A4.8B{ ~eZXN@A;<<>ojM2:&"168NJTbz]D2'# $""$#% % .,-//8;6>EDTJHSO^`luxxvYcn{VY^NTZ=S]nFKTUZdEHPTSQA=CHa@B;72%-*+6+",.16'!&A##!!+  &*$Q.(>#*>B1)".!.Gt|xkOL=--;T{ U*  p~|~dXf]ocOUL=MTZkq}-MK2zol|x|vucig|g_`]ln{]KOjQG84<H`9G3Z3?3)7" nJIGSVI:6KM*-CSK80(3;:y\sk\Ye3AY~A+8*";D>V.;ipgJ2}el[W_lY[@H`;2'(,G(  :"-,D]xb{~{i[cvv`MCOWbH# 8 WWcl?  "<bs_B0FsmV&}zvwmi`[nRVSO^89<:F=,'&! &'-)2.* .7 8 H&.@]k5"1&^il`vwflkv'S?`D9|XZiYsD@;E/++.Mg.NJJTT=9Kc`ZV[stb[/:0 #300$)CdNmqm= x}^boS_HKTPUG>VaBS2:IJ<3"37!.! !< .,-c613gd\uzy tNJ/LHT) /2  Oxtvs^rzARrD jwujU`2'kD08$ ,@d[dx~v9xup|tbaswueaXckMNIFNHOUM^_oAJO?HT9:17N0)!#8('FGE,0oo^"(( X("IEukvZN6~Jg=Cqs_<D* gv^s'  o1E*3(&73JHLMiy^MWoP9$ h_amrS]mU_RBRKY56:8CI[<UEO)91J;D3%># o][P>z {alZTtFsuu kwdFpwKbUpfi~' %N GEvq{z "gM9* $7<$66SildLUO[U'~putxdtgmuHC;:;;898;W>;9*2I$) 2#1YKojOiyI0.AVR~y[>z$:3aWC4+}I!,L3UooWS7YO zr[M+2lM2>`SOV7=0$IHhTMUqQ!uu^}W~yr~kontpYbNRaGB>Jh3591I,***.A)+(* "L4#Tgnlq{)KbPPvRvxosTx&|sq]V}XeaAivph7/}gnz|Is7 "!*GUfbdN^u6CFI)( s}caXVUMgpN[@SK9(S8"3EK#,A+ "= '&/25C`|v BQ|* 74Lc0 CG#'TI{lk~oJ   $$=#2DZJWP=+zlWF/&'D,  qhmyonk^N^hXatOUP;9=?7J)='.!)9 "KHB)&]SdiZ\"@S*UU=& I6L+LHurF:.Q*)XtV4fQ<3FeVKXLf\<X->*0EK&<9'D02+e`q ,M" u}_WL7Jk>C#." / kzrjAb1>2\cJGv`gXLxy=nxiu,,{C%aBpVyEIXXjB.(U88=KyA&&*Iqdj0miC|RGcu~- *q4 NT{B7A6t`yt<:P_Dq[~K+/B8 0(-)@>AGUJte`  U}|{}gC(<lrf r  M'ud\[_&!!5w`Q-=  9zS| ( }~fk]zvwrMUK6Fzt~whE95%D(;E ~QJlEo>,F?'3HNGwoorv3 :Xe`W:6Q[}0"!5mhr3+  l-Q,P,BNS0^r%[# C -B^E.t]\Doy}Fi==d$!`98  )  k_[Znf?LfzNB-+/bK$6?-4)&B>SEp,a9pF5D;[9T,8;MRwHbKhxK0);G{_3jehTo|[dLh- *&JFoqzil`pRod<XR-2s{vowi]1wnM#xyh^grV@6:JM$ @ 9G<];oKd~Q%=|UA8gfnE,<DSip}mD1[KM8[7qysoyZRy jcdP!tn|  g=# 2&|<xY~o8.&  U_P2"rxVAN/Wo~k4E:NgcTTamL1x5EN4+ Bo\KOfd[Kc8C y<\JkZS4c;8I]_2<JR_El7mJlQ+Nnj/Vig_[byc|_#drY JhTC @!qe;vs<#;BSRurJ12.d ofVH=xW5AE5Fr~n8Uyrw^.%TKoba6wX[cC+Wv Ipdzmh_i1aArp1 5yD|cb2R"8)Fnt*DHCK*%C466xH  mxJwLY>?!_g skf>* zwfMi=/,65Q^|)I0,R:M4^65L-U:J\RLN~k5 M)qmt8<*!5__sU  n<K$^ A* )^hBY<$.rwrV & rQ`E|sn_[XvOQ:]oU+-5S> *Mh=<M;G?Ykay/G5LQ" Rk~Yxzi 4*kT7kg~j<!MD WO.~&hUe2S]Bf|3,*)~P7 (/"VUD.kt: ~ t`De$ bOf`TSi~z{sZJNDr,0*,>\%!6!<BygE~z %chmab)XGi=6)hS9X]aolT_y]w}-[yt':|)/6ta&%<  uP %.MjEuB*Rw}mW~:dUg6C7YsF="*+[H{htNTkdMf*&gvO/ed5"[_U=> j:?EN!')0$7YR]-}XSy)9yB~H3j4N1iG! '|^ 11/[Dn7MpmAG7cbNK!4K%8~5 !WKR (V{i"Mx*yT~Y  _tKj/ (W#2(;rq#T&efG6zTDl=;s[o+%;'\j tAx/qJ u?8fJ($2=D 'e%'oIiBljjP*w!V 4'`qv)E<3  p ' TPIX,Hfep{m/!, +?Jk-s "~$ %.qief'5LLd;,cp{TE%sK&iJ7]g=7LGDAJEXY$r:S/EX7 zl\k[-[),& ~tpA15HI>9tlo#MV3fY  (P8^T>).gNj4V2 uz. 7+` p#B$}n*VZe@0<UqWF}FY>vOixae =q'p!Rci@e0 i@p,HuGYrZ8dlq{ Bys\h5+?/  Xh`j+ )_\y6bv%`wO67y#mO 0||wE yp ^RoD5zm<nqzd ~tODGk\3Y~]BJb4Y=Wb jlgLE{|X]JS6Kv79;J4l|8c=Up.m.jW$|~[rIS\&w=)<|wz3ysMx[b;|V0]0AH, HNRC6a.'T\#/T}rC/:fB'#8MJLfi~D!)|qWi/'^=h52!< !&Q/'*H{ yi`omY'mv|]txC@oUNQ~iPyu aPnVhdS};jb #Mv jo}wMkoTt2an}a3L.*8t~u+rWk U1N:qh\llu$$2RSQUT44A te(--jw^kVlsI-GYiXEhQ2#>gB]#J8k6XQ^9 :kM1)9A4Q@<d}Ij_d[>c}ca>4<s5'I<0qR y\BXdt~oti`Brk0=Bx(vOdfA-.+#g/0&;1 CnwWM;8]YukEDATgr^];<qMj@a4fTfO[b4`mAF6Le"y+ (!0A'*wAB *x>Oie-mK'Dvxw&RL9Wv(h!i(I*<ORR(gf6nB{yroS`:8 &drWaw@o}C6]9+2=**Y_5OE_tV+%"+0Cu3: LTC7C\jO-50P|f_jL@rsGNo{g lfyMv}7[zWjV *  1(5 jv[zuJOX ymWDz^Y/M8 (|M/,?KKsB}C1 S Z:R(EnnlVEjKdEJO;+eIC{d#k)nD:jG1> f7sg{(.>*tc/ZVC+^D.,9ks0$PH}b*  }  %,oFMsu6 %$ G"54P&!V)]izt-~^2!?zv6hplCN$Z3NBMjns *cYL<*(7?JeN289,h"DGt4K?Tm}T3 &4; ZTzW5iP^]K[tc8.zX+ ,Eeb[iM# YG{7 \o *3:7]e;W+cUK; nY/<<G8  ,;L| ( ri7H.ESnJpS^tvgr`lHb>LMi=*tU% U2CYywns=!|K_?9DFbhHne25(&c06krg#7q'P=3"qD?4f&GhK/cX(VB ' 3k+`[O+W`r  T g Fpzo R<IYvdh"3+A Q/J0L_\P SLcra;c%`ew*DEcr:yPe."0' -%yhS}Jt"&2l%Lb^6*L+XA&O)@Va1#_ccei|urz{ 4o B,~8@vRYQ#(Q s4d V {T %Z{4:7+ <WCF~z0D)\ZS$ SrF!4Y+la' vR emd``9;@0;)2*v K 'JPVZIOJ%8"s/waRJ8(#RNP & : & 7lSf%B``-ep$ktSs@"O"+S)-LPzT9N3;x<>L 5wsgSY?*}BZyqJ? fNw{8"$_IRZ 4!M 9TVY/&roUWV1gD[ *%)]&; * D/R\1; B.} D ' t p $WJY9KC#kU P N f [ ~ I  g1 SzeS)]`o~V@\.S,+=E*GKu* W=*bS\NXA|zU jl+L+$Fd{;j 7!Ln 398c`K F D^ dHdA,n}iWo 6K;d>?yT+E{xx@5{  / ^ h =qcR?Stjp   : D C *P+  ( %M8b}  A y:wX^.]NY!HemI[\-895BS_fhZ`DK^jin-)1>MXCSTb(LjK N'3vju bJO\>4K9YUvU_bp3Vw  ! HT+:&<[l 5 C [ Q b zs\t1)8Q  ZfOd(IZ  3 ; Q SgrmS%:^H'!?/s Y{n^w6>6)62Opfq? "8o6J  YQJ BQ\NP-Fnmd2's(32WV+i_& iwQqa6"4:O}  c u ] E aAnAC` $ ; " R j d p y T sMcV  ^e )tkex + g<6(FA_tH)R/!_SC1-+<*h3Kw8zT/{:wy\tM-[v9}eq}=F`@^N voJ   ]lfi9_dkmo{<]55`+bsdYJeo^Dqy/9?C 57Q;d,F ` 9u'm9s^TIC(Ks%#<(^'+S  <GqggK:w6f8XXtTY}bh\ud 8 B n B 3  w x  (  / 2 Y + 5 u  O "   {   5 Q  O )@ZECbsgh^C}pmZ~_}Ba6".Q/pP9s1Eu-|:;& \J(~zba@%1,+Ly}"jd^ U*LjbSfj7IxFv}Pj(X`V|.St b \ G  N w , @  2 8 ? . p g U N z J   +   C   $ Q   \   ) 0   ! W M J 3 = d P = F 0 B W )  U*T ,2lxA=q_b8ig/$pyMXFi`RLSU`_yE:Ap?M/-h@+}DA# /4'@qrE^mVas `SEa]+< (   - h ^  % s Y s 1 #  _ Z k T y x x T } ( x ? ! F B % >   b 1    l  X H ?y@fyQj_Q*:Y? 5W`7A;1)=U|v OeA]*9BQ'!%*np{V,Id.#UI31H4Q@tefl CG(R0Qrp4v > 1 /  ( U F  e j H  <  3 ^ F O c h q C  8 F   " H c R L ^ M > ' K > 1  - " 1  7 # M m s ( ; ! "}z8_3)27H+.8+R{&?/E]t$0qyL<K=HI!F))XDqq4@~Y<: :fW!k+KF9tZs 9  y n ` U  c l r V " I 1 Wp[JLh*r~SPI|ixcwmR\[d hU8  ? 8z Ud YMO319!HwL h ^(KKZL#+]3gqRB# 6VZdUJt :Jq S=,eWFc&A7HFc(pq o  j ` 1 R ; (  A X ^ u k H @ K   0  o  *  A (  5 } t Y : x Z A 1 4   v$,W)UN!S_IU;tZ`vtzf]8 ;)oT0h-y3pB.;Kb={M0XqI'xz(Y;5pX ,b0c}=$j|& 8 B _ ( /  T z Y O S F - u g  x D 2  E + L   #    ^ o g  & + ! Y   6 Mg#ZfdO& nZA]`C{tF  w` &{zJHzWuF$$4dM}|#7EKXj1@_W[Np:.?Z\@{mlZ5Y(_/!F| F 3  , # Y m ` C A       c 4 N Z a      , { P < n   =v\1y388-pCIe#aWGx,|co3(kwk X_QhKKMT{/^;dAL*fu! [N!D @_TZL-Mu?~:>}25&wcaKFH .Hv O S _ j    q  = 9 @ >  A X  ( % v @ j )  Y A :*oE)'@}K,kikWDc(#2 z),:! (C!Ca+>\ZPM7C[gX 2 ^ 3:*+ERZv,(,SR=-85 4##kG3 & & 8 * : ` > u^ O * ( x c ( K I   { J , 5&@($?> 4 EfAa,PT`TkPX+ $@6Oh X_B>8_x3GIvOwUyeepQ8OJU9T)(jZ B}m7%E/%+B7k  Wi`es!6O07r & N   D ]  j u } "   ?  1  5 v X @ k Y ] K qkUZ ) @%EHR`,9)1>r#tVH}c4C"(y- iY Q!MLRW)W>MC:-F?.g\k"=Z8KU ?5^3[gl<<PdJ]l`'hZ B] E+0_ b l   4 3     _ z w [ 6 W e ] G 4 0 .    E .  j ^ | v s g ,  p F /  # , b o g   A + + O 5UC/-s:FqS?o9d.5^;;jA(uCL:GDQjMJ{eh@2 V}5r~4 3}EjHJzGZ^fD5v3aso Fns#i m \ 6   0   @  , Q t  W d ^ ( <  y ! z .  ? # ap * , J W    < Jz!D$%N1_yq .  o8}Aeyi]~n["w?De3"SRXH*9tni9OB9)OD ez+9G{Us5sZw;T l S)FS.]weEVGs=?E5O6,olt M Y 8 -   ;  9 _ P .  ]  n&]>;w,N)"wyp=f&m},^ ?dEqIdonRyRMpv|iS}q'Dc9 yZ{Z5x%C6)18~uuM  & F Y < # ; $ X m N Y )lCB5ZJnJ-8[YhE"B(k$[vy&>q!RZS/\0&wJ3W ?z!#1 |u _uWYKM@W$hgp^ig.80j&9Y5z4 #rn[ r _ = x P  ) D  m ? ! E A = o t 2 u a 5@qj`fyA&cE}TF*uN*94@E"X1?'@t4an*2xP@O"/<p1A=EFc`*JkP&(GSi5NTV  y5#Fid"PHTUosIb0lGEgUNtYo     $ < & c H ^ J i z k ~  /   6 q (  n | Y < ) Hai&n=nF@QRT  F@p}xc2>/@zGke[fOm#,'TT>5Sbc| cdUEp!Rm,e i2|Zsf> Wr9 z5 - |  q ! | S : 8  T N g k O z F  2  u  9 + ? H z ^ n Q  G U J ( ' e D 0 \ l r  ]t3V.=4ugi5#vQ-u~pY1(_. PVAByZpuIR.MGv~2E@*22l[h*IPH3[S[\P]u'7O#,tS  1   K n o ( )}[ ? ;  ;  F   a ! U T U P ] E 9 p   l  \  hv2_ *XZLY]Q{oup<O+O-#I;yA^d8)HjcK! .V[=RSMCweX{hY|{RS)P@/z\z@kJ9a  zC0#(3rf #  W 30!o|NFY^eXY5/QH<E < R    5 t +     I0UI%%Q }V*fF2+c?P"l0 e`U TO$4&mXhG ?:Cp\`Z2|K+Woa W8R2?'  1 : ( _ A  2 c 7 3 j * G  -  w Y  T.rTax F D 7 Fpo;Xz vt*5kRf]H*m^u 4Uk9<Tx5fNSL %\*!+j3Jal]JX20NAnH| w ,KHGAhqm8-Np   b J V   u U V m  ` a y B < X e j H  %    u o ) Y 5 C _ I . p   :f."RV _Bj}qZDP#rn^ |\(:%  QuF,25zb\EVx TS.l:nK"y0. (<rY+jT93d}  R 2 } 5  3 , A u y ; E S , * @ ? 6 d  2 I S ^ k T  3 Z S } s D > l S1)]vqctAt I&ik]4LVkjSU'+)*8p~# Inz A#g Wg|[0pVTUG/>nE -;$0gw B=^jk[Vy~ Z a Q S IbJHC ! = 7 *   M    , j  v ! p rOn\h3r6b=B#Z5:wAau=c>OFkK ,!U-+\B|\rdw~X?(C~egpb?!1[ jmv1.C& //(}1o)ko_ -<n%fvaZ2Vj_pgoMQoja9U:2^ N  vXvr & c ~ ^ B  $ <X/:?W>e{K#GkqMdv',20>.w!&s(feUDvo `L2Lp9IG-P5uRx YP/fv+f6 a T  n 5 V  0 * r C , y e i % 3  k4Efl^  j e M @ 3 k]U] K R85YyXdB3qzIM5$Nahk j,^yR3F!"iJ@?]ga,7iy#Cbmm:lvS8Te>Ro.]"n<#6 2%wq?OXT - T > (  g ^ J O j d o b ` k  M  S | < y ~ A C e ] L F : I z ` / : ,= @~x}kQ*.p5W|$]%:14`>&g|P4^|}kpowRTRI8VB9}gh-jY!<^ ;fip\ <]lE@sW4=;XU!Xr3Ii     = N , 4 7 , x R O p h   sy  ( 9 i  F {, 4B)\&SG0g| & (ld[qHWfm]szbhW< ^G0>!x?Q\ODFUJNa446 "0k$S#k`wTZy9{7=DAE4h6Z)89M 7Aca0[x5 wmI  D ` W 2 \   A 5    a ~ y 1\}os^Gs   X L  ( %  - T  (   &l0j@fJ=~R2-Y]]DZn24Jv ed~}mkua9/1'&%< EleD%Zu %zi|=w| )SGz*.HfH8C(8] - xAa}ePtw"% @Bh)W: K b Cck|  *   @ v/Nb+I|dGF+D>N"7 i)(d^-??DQ.]& HT$G5 ',K6tFwXv.|MM`rTC %[L +4]$WO3  ` 0 3 d I I e  X B y e x j U %r$#%HT_9*EtFH .2^y-nc6[hXy>*M_Cv5eFkC{5 ou268CI{P,b\P*6bj9MB6I1:Nv=]O!WH ^5 a0r~?Wi G 3   _  I D C 8 " 6 B h  w   7 ' t }j[j[wo!mSDb[3e#De(/7_j HDQ~AZKBgKc,B.4=)  z P4jjbbdp7V}&^HxS     Sf $ xmu   L 8 E I C ; r 1 Q S W %9 &UkiI^ O x  | c-b9+4l:nl|eX_v\~$#s}+#96tyn1'V&tId"zpbzO|xOz]Km0!,e6 ,c &QG9Oi;MN#WcZ  ) , * 8T&B;@  M / 3 F = j +  f &  i p k P 6  9 ! K  f t 1.V`8q/ %&*7DU~E'=wxN6.XuPU c?\O%<[HZB;0-0Fj3om\gH'"V5f;0'"R@MHwFu%o ${A:8#dd`DA%PG`3/}2=" H _ h @{  > w ? R  X T x  5 &v&O'RKs\_N7eavOe*&mT|O`F7> y&3x{wCKots  'lqt;t7FKI4tp 'XgL'k7u 3dca <:$0?%ns'j"<6J  5 ] Z . ~ o 9S0:S OL/!Xg vpqRl?y{BujeU2]D&W1? i2,Pet G[GD\ M#)&#OLYH"9eXE2,zw 5 . 9 : j W  R I n i Z Z >   S2Ef 1r H < d 5Y 79D>V cu=l}|ZoQE*5I!B2|+pzyZ*_ko`J|( 6mVK+%c+(L$KPznJB+WMC`U "/J]CE6 %Ft[ ?  {^<HI{GE^ 2  W = l 5 O Q +   4 c f @/wwts[Y} $ kJW5ERzf)zykfj-C5^$lx/-a{B/NV74<a( '(pLRi c\e;$]OOus3L?!~Oe&E(cJgzauX1uIx@L($ > DF8mykR|a  _ - |S2  (  / 1W7:7 !  ^B*\K~vB 6-p:=f1U<JC8eg C]j<uKg MC Omxc3%&C9JR;YF9) _~F>I UgYa*.B> b , U B Q a: ! m=*IV>`hfOw\} 2 i ;)&Jk  [ } U { @ I u ( " ($7AiDaiR ,Gdrz3$2t,&@cKN[cm t  > Mg'|<+RO8052~oy&4$c*Cc@z=:S;HF  . i X ' A 0 A36  4P\u7'>/  ) " l& s [pM% 7 f $ ' +bSTSy.,k:[Lg-e9O_|wd#W^+9Q6TnKh9=[VXHtVv# J%O^159E70^]})8vT({+6PVngx'R ^ | W   4 K g s  7 = > n x T E | G  m : ;  N " c 6 ` JB  3 6Qv@FDnhxGx1|Y}:MI?G4[JMK ,_$0 *LT,-+[:G7%ahooS\YM-.'7dtDkNif^ `_ I < 7 K  @ f r 9 + < < x f L > l  *zz -Y<7cUS 8 Y Z , (|2XLHkfvx}a<|Gc0@MUi 6M1tkd dye:s JHxt%FK%@d[5z_ F;Ke v#p k<bY44[?W (  e ; ( X Q  L G   E Q 5 1  K Zkw/&ej^Z ` U 7 n4.5 5 / )R ?  3[ElH!9tiKw[(KMOd8C*OR2-. V4=7WV5 FeE8, -;:qbAqe=u} gkG t8`{('a4?_f5K  ' = o A c T 1 { _ _R0WUy'/C=! # K G ? u T = ( %Z.fubQ xY\\_V\ l{]CrL|Z+&v'!RK}-5Z4<"w5iD9'm}riYnJPJ`JSCHT'\+(a[ n ; Y q bjv  Q Q   8 l x 3S ( p e ,uBY Wmk   {Ok, 1abA>nGG6 lwg@mE <o)g:RB49(tnIAV PXB.930 [fZ!wl_ wH\e[ hKEE?^2p= ,)= 1}p , k K C S ) 9  c $ * /  1 6 pwU " G LoIar&?WV.yY@(!vrc=z Q9@}n0orv/?h:KP#;.'lc_xJwv'&J:`0FtIy;2?]Ht<"W>YV@A\t7G{=PBJ#t^lUe%@ke`8NQ@#C/kTAo  -  etph4z" oX W=D{T'vr_OiE 9+6bn}G2* >o9c5%K0C""RI-ND>+1:,Vj,oa\" [I{<BD,j%  ~ENeI%s%;8; )NvN8%po h b (E$:"ep )}@"wM!Jq#1jULeY'%YaMEA[7~u ! &<P;'\~>1 Jehz_rlEox`bkR)4%edTXm *ml}8E _ws<-8&bZR*!qh n{\" 5s$RKH!Lt  ! Y 0 Y n  KlKoOswQ`tPM+c *ruWRKq~*l N `L/h FH7" ye-"`Zj+!XnfJwW$c=,. wiQBusixZ$~0@{jKAEQ .  NjQD`J ,iS E]F_9}"-E|dIKv#M.)y@_ L=uU;Q]sq)*"'S[MpY/+ "!KG $WX{sB%>OsZVZQ,,aD]tO% b gH]*x1?] SXGu  uK}r   Ci'@8 #]2Y]0\=?X{V*U]A666%IRI 49#.-;mHH ,I_mB`/',0'2$.W&>Q-<X"$F( \Gg6F] &!Z0+%m3X[ws&qxT_)=,ZOi$6Qe[/)1]b /-EK;S0 mt|y ] ` & ]=^IH:w?]:o`:@%qz$P&#Tq{oU G$!1W?^e]:%%"xZQ/`R:7|;kY i7K` i{E| 5 L R J    c) _n?/D,]G  !rxV|w|rJj<dWS@KLB~.^N;H2P 8  aqBmn-/%oe8OE +0-)[H?:W|x}2L3h0~#kxx-QqdS'Eu  6 e } G   S ~ k / U3>E v4Bnu-b:6rtidng{ : V+DR0Zq,ekb QvE= "ww7eJD +9=O1~h6UXawoW]Rh CJx2kEenA)]I8~ ' !  o   V $ j  $ " l 5 j V b h % ; ^ j & ( & H n W #  i k B 0  I | 5 G 4z|yM (!Ug{E3YtBJM8}km~H) pN'!g 9QmLOFgEZOX? {uHPQ //q/ 9! K"'8o`j^(zwdI - ; u 8 8  y - g _ N z y J 1 h ? , Q j M U 2  #  D O +   6 p p l DF;epNR  [ fH~|t,sB-Y#D8.W?v5mAR*`FKD[,zM1WDSQak:-*N H|tel,X&iUnx*[/XLzc608 oWsY~bC~~ 7 ? |}?{Z*B D)Ju]  D $z(r s!'Wz7xxMI 0 \ u   Ym|j3x)y)n1 Q|[kWh0/(3xC.t|? 7h53'Zy}Zl}/BA_5o:Y`kC abIp ,pF\_gHf G'Fr+/)Q31,=Zs95>Xq6)-Z~Ugp%tS\y=(aDGprsc`@g/ < pr/8," U`%vad 4DA!U) GoB2t &im}%)\n@:Q68N3n'.4lz]9GKw < ;   " F  M\w ; dakBUO pd"sR . ( u W q [ q  4 )uv\9 X.6'"JQN=t ` Hx{!S"@F  :L`:K6KKN+ggMgG=f '&/e~Y r*zxRA 'G    >  # !   um 3 K b ) "  (  4 2 j     9 > _  H  # W M k ovVk9tO0B\SNriQv r HCQMc2[dNe)cXo2(  Y\273Ayw0Vm^y(_/@u>@i\|d$3'4PQIHZ9ew axy{U|d/  L > -pc52 uShaOePO#q&@U[I<.6 !={njMr\B(l5YiGqS57^8 +JO\sy*bay  ^OOIhdS?hwOR]p' 6_`)q&N{t;&*d?T&SMECmU\kSd[_<7""oT,k6%9Q  5 l u _ Ce  |TfTfvo+4natjC3Q8O6(gdh:!?_Bj<sySA&6 GaBe[Ehw^T_L'u?#P <Bw-b.1aL,H5(8SS|:Z{|i>a$Zb:'"rdk~9Rfr}bo=Ii _9MNMIVJx  H1E'u|wpCVT'm"V \?"<k?i#!8"+%2%XFz9UL\idq tx9KQ'Ro% Snb4uq SZVM!8><HjPR} ) 9 K sR[atvo-.<%'#YL<MBe1TiT`>VAdh|MR%%8 gcuSbqhUqS% /Bu a<,REP[R~QTeUI  $Q/VncE%t]2Wh+Sow'+LNQ&cSV~Uaw^U  aoD9uS\gR/ zvlD{YLE8juh>p & J z 9  S :   ^ l r L a   Gzl}6PE!.N:]bhQ ?y"AdD8G.'NG#4){5.^+8+#m:-C=7+J6IIaTq#7s:wJ(iqyW+bV^tvW k>TCq4 ttBjCI$iMi Sk|^<'- Fv632t+24;0hW1zYZzwAzQXo3+"~nK3m}e k`{}C<U` DE_0( <;xBN|FNHVsK{| SlMz/:b/K^IuDL]\5-0-%{mcVcaM;-zwhpM ~kvaY ;8?f;fG gEP M4ro1JU {W>VrkL 07C?T?mu#BJUL{w</eUqilk NAA 6~9;4fL YP~+^):Z sA@MDN kli|5 AB?xtWK,An(w5l ItPx@//S"n=_E97S.5c~mF]%If@ SGZZ/@Q]3d*0{|x|B|uLih{<oLT?T 9 1yV~k,UW$FH ,ag3&bT4Xokv3Eh"ZM W;,JXxnR5:Gc(<ukTUHi + ! nrowYdT?LV3(QK`\{x<$~V:`$lCf<Hpd6M,> 6?^FT%EJ+%E$2+?N?P'$G G":GS6w  w?~h H5J&y (~ee<  ?@-5[lhCZb#UH<x9.|    @ !hm'SQ">nzMJm@cx`r uK3A>1P._4G)=)=%  _`F]{Q <GB;fVCS6wiEhV;~si&]Zy (USa,qUg>KWRh~wEN:pvs;*  prt\fZkF%P"<(hqjP.b! Z9>>U-D)|ub9*b0]Fo\8ABY$ Z}>`nGi`jw(04?-{ATXhnX;PJt>WxP@Dy!-+nm*H?$Op0[ze};igP1/'v'Lu ;+9&R$~^C?<I'(S ,;_KZiFO9q[Zh~hx! oe\Qitu0SB1+HjGO)iC$\liQ87.<*>.M/"m8bX>!}OeAqX?b1&&li[WE>F^zR05N9%3JC^rS%,>/WhidY Y>T_oqye{^ls` tq#wo8)cn roq;Zlt3uzxfQ _IT<Vw<7,3 %L33Y)<^ey~-LUXeF;}G3f(a.$h A3T T| 7.`?G]%;WSD; u882,%]DH*3 Kv"()P/O;bQH4F}j(bp5 %*1@uG5@e5!|w</ 3>Im|NLQX6P>TN!i&WfS^I+~w~Js% 'R(nFKBOg$ /V  lgoEP/y8& t}2IV=</LLR$bZ!,GjhK 7c"/4JW<I- |Ru_bkkp*94U5/CWdq BxY%$ 35mLni}1|OOat%OicXoK[WpX{;L=>'9^?\!jD |>FFH?wTQD esk`'wP9}v? s}GIAnj|v\]@C%nJVS&yu]XU'$$)yTr $17dEv  +CW[nN~x6 +elRCH;x|w l[yLZ"))HFi.yv] <w=]uoj]G5#X9wU+%)D s]>   4PSz[N/'  bPq!l.[z_mhAw}+ ~r0NjDwZB7GwYDY ~i d DCR&WW,(`5,&>WdwI !rv9)_crv"$**hu~,""] YlLgPI`J7Mj%/ 0 _fZo5 ,Q9QfG~v~R(DtV6  "0@Dk`L jS|:&I}i Rep'7D@Z~myFgvcu{?qS?xa6'vU 10[/q{>a{wIBV@D>6Roa;N7+rcqfmD~ ;<Dl/zT 7 Z7U|}5:JaF+CPL9@x{]~K h+aQRnd:8Olr51$8W'TaHW}&2JcI*e|`Mte[?.T[k98< &7ukDPi ^!!t\?]ple)S5pU)#*&~wlM1A5$SJT0x{ U8>F=,+M%$=c*=^98V|M_P`\;WG^TUmZ(LRd~`E8"ZpYNx8  2vGGM F(ZA8piJxRM!^&VfekP!$!ds]@"!q50[ zz>?="'F# $ <=ADty{NaQ|!rt/ZeEQ;PZaQ9_aK En<8J9,  Hw*&!;pHRJ\(#Fsns H1'l-9H$oY=prh{bdrbm[9Fk=  (z>ATb;T %k1qC0.W~=h^njhY` (m{ !"\[_mGe@jvb}6bZM~mYuaH}lUKaa&9@!6f]),9OrZqJB 2nc$z"?:3zH@ rh*?\VUA(7hTc-6GD{7;-)6/'K4d{_>Im4qrMYD;oRG( TK@:o%]~glx3:pqeEBY!&g$vvi*NG:%. RqF?#dfQm( v9.  ^y<XrkL||!D p ioh+<9K3G"SQ)'RnLhF9zj, b`VUB=RP6Xpx -@>RA#` 0$0( QCiI pjNSMy\" "z9lGS*TTF\';AJ 9`f@%5 uX5ojCFEGMi9*C1%\<aO;@waig[)a{zt]\HM_WYaa]CA, lG 1q08%Od\yB'dSU f{Y7><y!Pb89#g3X`^vlL" |}oOVI|~sa16O84y:=,!'2AXD6%;#K=AEebj_Zl(f)W7I)9L7lRA4eQY"QQ8f8)Da#=8-))!5^uL)6;2@; =`d{>T8C3 Pd,/49`~o--cq>g1P2 E6RCT="HBVE2f,ALXY1'b$' -FcONG=wlz^jR4V^RsXWhrgRWsiVp %zP][cJjZ}P%. 4'%;9=szGXkr\@<&&^miCWe|ta9d)EFh?$FR;Op'#S 7YCldFE[f4`&UBoz4||IG\t2VDZQ3e.A/WuNC2Yql9B31! :iJBVWQY`r.`Inz~: &=?c ]:+L/<oCfBGWhsj2V@y=K-'-,!Q#L)+U~'Q}~GMgsF7 QM $?f4iALljF- %_3+<WbKDdwkp# +0t  =?#QcV`o#Ux*4^&v &&4(~tJ 3/6|M]CAL5L6";fK}\@rV(K 6N.iLp*UE8#9 #]4G8Kle~yw69'5I/<d{"">z;F1K:]]B^5$-0rS:paflb7_@Gmgn //?D)ywB&=xWEB@O$0_QV^|srN6n>Pwy  epO)|d( P !t^eQ%)+;?  06'%=21D+Lk[_ZBxh~fx=@\ J" 96C {u|Fn~i\] a$(={ {dp |F fIrf>aySO-tcC[5RDV?)uNTE4>sAL9PD# =&0+(4Eg^OCdyz|N# ;Ow82 F "$>F[#%!R3`^B&Ehz2C z!&PJ^n7#w=RXA]M (1M !u |Pk80~t:DWna$.=? naN@Rn&8: j~jApp|(mmQC*{~{@V6zC.Dan#u$smp /DD# ?@<8 K8YShg$&`sH23Iy_@TGCFC?gzKAX<dv?5PBM5- $diM5;FvMAqt+D7jJGJYrBW# #O<0QCN[[rB='6&  A5v 0)>Wl{J [K),$0HWfm  9@ttR#tcP~UJ0'f}22%NxprEPLHdL+-D)C|ZB?<srfx IA 8WM=gX]|b*^rpb<5MQp( 3F@ "- HDP@(?8.59?@`ckMgAFQopkf83YPXR0dxYkIJ[X 4wyj\qC 4 N6#:5%+ 3+<'!?!;-#>0+J70368K8M`PQIFPwutw}.  E6ZbT`dkei4M;>/9[wM;D URfw   ##5cl[q5L .mn0ILdyxit^(7'1##& *16,#$')ZFALNlpbULm`PRVuxkgpnflrs]OYWwvwuy8e~)@T_)&%u $+VD<RE'Piaf~  q52?{w9`zeDSjkr}fd(sy{SwZ! ,9 ",)C%#'$%$&D7///!G?T=?ajb\eat,<k`_RbEU`Cphw,#(9%1 =KH>3 *8H(<3##Zt[rF [%xb'<{gH;hagyz #7!?A(yrVHaiI9;2F4#UO"" bB7,45VLA>Emighl|vuflhmpqxli{v%"K`}vfMF059OYQVHLWWlgqysp  -G= "7,,nW%V0iFedhgId`U&PswLIKVH8..,, ya}URJ8Va &7)V:*$MoYLFC\hTSS^k^\Z|~_XVtecvv)FI{zigK"C,5EP][saSGK[x}vz~GKCV  }l$'_a;]eeH #_VV=y_R,rzW&&% ! 1 ,.C8*" /?+,('UD65;5WTD;<IxcVTUgqdibginsrzts9?g[l`RVH<=&NVPjUO6Eerura]^COf?<VJ )"N? yleZ<WM\K:+*&?O5jp|`R<&\O*"  $ 403%#"!G<026<46BMNNNIHYSKif]^RLlUTJRVmb]]cXUUYZttuw|~LOfuomhCAG1  3>CAJ5$QiwVB7  'CWgo}tvZctENPv s]0,PK 8+an\ibd\pn<2"*5J: ) /<$!C!V6"*9AI<7SNUSLbds{jalh{2BqG7:$% S7&! ?F_dK!%!1HlrfADUraN  $`)LN~lTtjfe{sN6A=7c+%AB#5 N Z,;87226YPWPIJpZWPOfn^edbwnhqqy|~ DLZH>5  /H{Y= {ns=4% 3.(~rh[O`qgpeE<=9AA& 8-U<3(-XS?;AhuaRFajq[TU}ose~suy}}w}oq{ |v|}3G teMA74JZbE8? !wseyUgE@@5Fh9/3K@-8M& ( '(!!4*##B4+%&2<,&#"&T;/+;ED;==7`P?CCryrXYaqa\}~y}~shd[\jspjkki_a[MRiaz{~kVgki8(".dSK=-0FSbz{yrbjy|}rhy=JqVHRjV+$$&7D!&*B+0 ""*"#(-/,'I0,('%.000/M7942JK347BYH@LF?dK8651FMILDKWMNJ[XKEAF;H>HHGFA?CNLF@H?BGGLC>@F=@:GC@=8=9:@DKS`kwkgU\UieP0(&%:T\rzxphbq~tz_YSf|pu~xJC6:JMP1FV9,  '. (1":3)#,D6-)'M=3'$1@72-,B-34.?C04261()+(1*4B1.2,B864,*522,-)+&&)'-2,!"!#!$ $%&,&'!%'&"! "#"# !!%>Uc{gJ3'"(+;Pl|X=(  +C[X^Xakmy]fW_z_~poF?JHIYmhql7%+'(%-F?#? -,E-'A(# :=4/+;H;71)+"*$# )>nkW,  ,<N[{O.( -N@BUOccwv]NK>SkfQY`sf*04H^~`Zd[k  1L\tsS@"  $;Yqn|T+ ,<7ATSFcl`lJ184TKKJLE,#(26NQ8-:Ii# .@PqcR+# (<L_v|pq[&  <20CA6Jk~ws][U !?8&1=="B;#+7 !<XahN2  #=O[fj}yt{{* "0/=MJCOPkpN`>9A5&(=.ottD+ !.B\zx\lmy_R( -&,64YIG_pJ9> (<   (LrwrE% +CNcTO_cziR< !(*).6B`8+> +>XsH'!8S_]FQRjnzz\P6* ;< ';NyvdI-4J^HMN`^{@70  !?Wz|rd<"3Z9GPTWZwTbS *?VtzcuT:' 8G*CJCN]d9)'6Tqr]VD*"20%<\D?[=,  )>TZK=( 3<3(&#:UqH+   5  *<QqT0# $<N`.%  -M=+;XTENSION= 'IMAGE ' / IMAGE extension BITPIX = -32 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 280 / length of data axis 1 NAXIS2 = 210 / length of data axis 2 PCOUNT = 0 / required keyword; must = 0 GCOUNT = 1 / required keyword; must = 1 EXTNAME = 'var ' / NAME OF CURRENT HDU DATE = '2008-09-26T22:15:38' / file creation date (YYYY-MM-DDThh:mm:ss UT) CRPIX1 = 160. / [px] TANGENT POINT X PIXEL CRPIX2 = 105. / [px] TANGENT POINT Y PIXEL CRVAL1 = 41.5791666666667 / [deg] RA AT TANGENT POINT CRVAL2 = -30.2747222222222 / [deg] DEC AT TANGENT POINT CTYPE1 = 'RA---TAN' / GNOMONIC PROJECTION CTYPE2 = 'DEC--TAN' / GNOMONIC PROJECTION RADECSYS= 'FK5 ' / REFERENCE CO-ORDINATE SYSTEM EQUINOX = 2000. / REFERENCE EQUINOX OF CO-ORDINATE SYSTEM LONGPOLE= 180. / PROJECTION NORTH POLE CDELT1 = -0.00277777777777778 / [deg/px] X AXIS INCREMENT CDELT2 = 0.00277777777777778 / [deg/px] Y AXIS INCREMENT CRUNIT1 = 'deg ' / UNIT OF X AXIS CRUNIT2 = 'deg ' / UNIT OF Y AXIS PC1_1 = 1. / X-X AXIS CO-ORDINATE TRANSFORMATION PC2_2 = 1. / Y-Y AXIS CO-ORDINATE TRANSFORMATION PC1_2 = -0. / X-Y AXIS CO-ORDINATE TRANSFORMATION PC2_1 = 0. / Y-X AXIS CO-ORDINATE TRANSFORMATION BSCALE = 1. / PIXEL VALUE GAIN BZERO = 0. / PIXEL VALUE OFFSET BUNIT = '(MJy/sr)^2' / UNIT OF PIXEL VALUE END XX|W7xeWjW`HWd]WΐWqVyW<]MXwW2WUVlW{Wu]WD2W'XWzWW"W EVXWXXaWOXddW!CWvcWV~WWd]Wy$X( W`QW:,W}lWV2WfwWaWEW;"WWNWpYl IX?W[WkX%V[X WaV6WxpVPnWXX X~WW:WsWdWIǖW3^WL+W+W1WWW V6WkWDOmW.W')WԝWKyoWXCXٔXO3WMUVߌWWPzW^WWWUW"WGX}YYXvW:dVTYW-حWNWJzWCWWC8W4_wWĮWV2tVCV,WM WυX XY?6XSW}WEkWMXbWUWgWCW&NWMWWZI WW݊WtWWEWU;WXXۓX'YmXjXWZW,W2WM WW-5WtW \/VW7VVԃVW WιBX:WVHXRMWuX:W*ZX0WXW2W-fNW- W2WKC W2:W*)WW1X+EY<YHyXHWTW#"VAuWXdW]VVEVe:VӓVVVIVV}VVW3X.X6XEXX`YkuVX<@9Wʢ W\WϒW,lW!WWLWSaWãWVVq:VFWWnVWWX[&zXJrXTXFcW08WvHWsV-UVVVATV˞jVyCWVAV_VV?bV^\W;WcgWzXYU]XfW W"4WvEWW*W3]W!W>SWX,q*WiUXXn!W%XWWUW3;W>hVVcWW<wV1W ʮW @WCW]VXVW:YX[Y!X~HX-WqCV VRVVwVpV^WVaVi VVhV[WIV̜WX%X{XVbW;FWWKWW Wq@WXUCW^5WW^WW=WvXpWWWƒKWtWA&WЪWw*W WhWFW<VV uV,W: UW8&V5WPW9qHX#X XwY3YXNW@KVVVVVV VV>VZVDžVuVVVW=X%dVʯ^YNNW?jX1X HXVXW(W&aIVGV~W>$rWVVːVyW.WD6WWƴWWVY9"WWtW2X6X9FWQW2W;W.W 9VsW {VW V5WnWd5X0]XYU&Y_e$Y>MWvƛX+ WWVV VLV~VVYVrjVqVa[V VDVrV~WO{XVW/V$W^3W TWwmXsW WHWWV[VɗWVWfYVWVvVWyWCW W,{tW[WwXYSXkWںWq;WK)WW@pVVV6VnW@׮VãV:VnV)W,VRWX\WY2yX:XXW-UV?VgVKVƸV_VV|g0VNMVV Ve$VV;WeW}9XWXxX zW?|Xe6WYXcWءWwWWXW:zWqWWN}WwX_WpWWW}:WPnWc;VZVKVdVjVzVȨqV V V W WVÄWWWxXyQhWYKX~cWVWWk>VWEuVmVbkVpW %VVp9VB{VGVܜW W0*WF'W65W.XmN@X#oW#LW=VV1V9VF\VKZMVe@V5PV}V'VVvkV9\V.V;W2ԥWXsWcX+WQWHWaX!VVWi,Ws.VWwfPV0W@W=2X_WWMkWkW=W4W VڢYWlWEW@W"WWBaWVWUV 6V؂V7VVKVVWMVTxVBVV7W2WHηWXX[dX.4X P0WzWd|WV}XV`VQcV %VbVVVJVwW W.W W4WXjXCyXEWHWƬW"4VCV+~VVnxWVG+VctVGVrVVkVOVa׈V\VWWWW?XsVEVn gV^-Vy5V/?V%V8V VVV,VVپ0VW&NoW%AWQWl.WC=XsX=W諕W]WةWWXJXXwZW3X JX%LW:yWWW#Ws[WjWWU5W#Ws WVC&W" WTW'..WG3W)*W WD[WiW VkV#=VW ^2W]WW.SX0SWuWW)({XX_W{OWXOX#`W^XW;W2W_W޷XXW&Y R?XT=@WYt0Yb>X'nX W)KX:DWa7BWoWHiWWX(4xXfXmW NWWԶEVgQWgWuWFWWWWLWh/W?WPVVVLVVVVZW;VhVVVfV"VV VfVV BV9V@WV#W9/WemWNsWWLxW89vV PVVOkXVM[V@dV=D0UyVrV9rV69V[hVpVGGVVʊVVV=V]*VC`V(V*W:%VfWvVGVVVVd/RVj~VJ]VjBV-VVW:VIVfV@VPV<6WLW3PWN'W-tW]}zW !AW|WO5V$V0V(V]~AVs{VV[YVVcV.VF;VgrVz9$VV(V̲VWTWVvW)KVcVwW xWsfV}VSZV#VVV%5V_ VRV#VVVsVW-VڈVSVIV*VxVoVJVPVVvV{/)VOVAVJ!V^VVKV9VkVyVyV0eV VVm?VLV3V!?V0TVkVV`VjVLW> WCoWrV_WTjWW&aWWkWXWW MCW̥WaWGXWɹWtXgrXO%.YDXXˇV*WtmWjvGWqqUW 5Vʐ+V:W;"W1WIWU\WNtWPoW}cW*W˧WW^W|JWNWW W W VűVuVKVxV?BVHAuViV~VV[VV?^V[m;VrxcVmGVAVr80VVWVVJV(W W)nV/VVv$V=VV!VU2 V )VV5V!VL[Vp!VYAV6V#VgVV$VVСVVVwVVuVEVWXlV!EVœVVV#VV]VVf[VcVVҊVgV#OVuVuV^VV0VdV'[VkXVZvV_#`VGV^4V2tV#4V3V73UH+UVEV0eVJVE:VaVAV~VMVPVVVVVMmVV TV-V,VV|VWVVB5VVPVVcV VV{VVpVےVy1Vf$jV8VIVkVufrVViVonVCV[\V(VʦVf!V`VaVykVpVVVVV~]V#V}VWVGnVVVwVX V)VV>'VVV4VVUVvVyV~SV5Vk[VV\VVVYWoWVeVDVV`VxWUVVW dW W+_W?WQЗV5W1 7WW=+W[WZ\WHWWe3W0\WWMW/WX6EYlW8X [XNsXq/X$lEWXX̫(W=X imX+FXnXVvXt X{bWX\WoWEWWyȖWV?WmUWaWV-V#VtVVdV6VWW'fW#V%VWAW&hWmZW$W"_WE`WWVۍV[V6VHVW%VA%NVJdCVdV-VboV!IV5XV.V,VcڴVD cV~VVxVy;VuqVV#IVMTV*.VVVVhV;֞V!zVU5QUYU&VzV.>%V$_qV(MV%cwV8VArVp]Vd]VDVQSGVcVFVz4BVJVEئV[EVpQQVCV'iV@gU䶁UUUXV'7V؛V%VC\VNVEvVa[V`0VVVVV]VV|`VEVRqVU@/V,:V0|,V5SV&fV=VKUUؓeUUvValV2(V0yV^VP"VxV=V|.V~^V8>VPVLuVQ;V*Vb}VwQVScV|VuV1zVh1VZj.VwVZV\l,VVKVVH7 V>V? Vc/VQuVVZVY bV46V}V pV^V=VVkVrV} sV۵VEV{qVXVVEVV`VoVVAIVVhVyVV/EVjVz" VV&VVhVVȅVC6W+oWWXW4CVWB^rWV]qWVɖWW16WvW`W-D4W#xWGFUW WwPNWzX WqW2WOWbWWfbW5dWXWٴWYWH(X!X^WUX?GX;PWzsZCGW}WަWX)X[W~WsQVVR2VSoXVJ\Vv>VXZVa;CVbV;VVO[9V\V^V&VVd(V(VV_V^V&V#VVVV JVqVWƗVEVRVkWVVVcvW*V߻W*W^LWWWeWXuW9W@W@W x"WunWZ0WWW|VWAW;zW/WLW#>=WaWKWW`WWOW@WȮWUGWstWXbmX>X4XmX"hX3XWX2W!iW:X+XcXfXWXX^LYJXXiUWN%`XlW:'WCWįW)WxW7W;#WzWW-WOwWuwW;VBVޱVrVu{V V:VV>V`VvVݴ>VrVCVV;XVvgVMVMV>OGV$VXV3VXzJV?PVCkV(VlV3VmViVQVE^VE VbvVR"V%V8VVpV#( V7شV)IU-U:UVeUⓑUUW9U^UVжUUFVV'VϲVkV)rV+VVýV4lVnVUJUzU UǑUfUUdUU$UVUҥlUĽVV!6V&V4V ~VvKVQYV)EVV!xVɧVV!lVhUU2mUUUU_U}V VVDV`V(V+pV6v)V+z4VY)VkV(@VnV@VFʪV32V4kV)V4*fVUVI_V"VUVQU/UVV% VZWYVT Va]VVx%V2VVVtsV#V|ViVnnV]Vv0VƯVt?VVاVpVV_?VeVB&V'VjVGVVGVVVVgWUWV[VRVclW VWVVQVeWWVĒWW(W&(V,VVeV-WV\WjW׀W2SW!lW$ W7WWa,W(9WAI1W:4fWGdWJW3^VȤW8W`)W-W<W6 {WU/-WJB@W8 WOWW%W2qW%WX5XWF WX3WaXmWqWtWÚX?W/WjW08WW3WVxW9WA~W V5V]ժVVnv=V[VWVVs&VK0!VCWV:VۆVVDV V]V\QVfV VVWjV;Vo*VSV0U\VV-atV/kV*cVVVU-UaU"V.DjV$VTV&V}V;rVI(LV5V$VV V&%UUUUœUJ:UUU4UUUIU5Uƹ6UUVlV85VSV SUUV_VTUUqAUwaU*VCuV UCU-V^!UUոV V)VSV@VjoV^'`V?qVVVpV'SVnVV VVzV_MV6V9VVVoVV{$&V#&V9VVVVVVV,~VRV6VFVWV4sW|VV VV&WDVRV̩WV"=VqVWVp_V6VV˞0WeWJ"W(W "V>VLV,W(fV pV$W4WWW4WWߚW%WdExWqeWnWY9WZW?b W$cWXެW`,WUW-`5X2JX-X};XkiX{W"Wk9XTVVVoUV?VlF V8VgVfV|V V VVVԒ,VVVKVw=VVV/VW ~VVW V'WW _W7Vۤ7VGVW.3W׻WNW/7WW WbW#WyW)WqWQK|Wd[]VGWQdWTWWށRW-WaWxSWgWSWNzWW|WPX`W"WAX#X/WWWWXQW:H;VVuWEW1|V%VWVtVH VVW VVVjVV"VRjV= VKAV+BV/+V/V+VDŽV!VPV]VUgU6V5V>V\U U,}V >V4NVCVEVU/U7UڷUUUU-U3UDU0U9U$~UkfU"4U$UAaUǵUqU+]U»Uƥ#UaUNUnUUU9UUuUݭUUUUV 0V;U}-UV UUSUUӋDUu'UU૕UҿV UDUiHUV V+VyUrV>V"mV9V=sVPV+eV1[VM_qVTzV_2VIVi}VzɬVeLVT?VrVV&VVVVjXVԊVV\/$VzVXXVVbV%VV|iVӿWV"V؝VnVV@VuV&VWW=WxWVS*W1WWDW?CVW@W>?WH}WQX_% XYWW ]W9#X9zWxX+dW֎PW6WhWG"WXBXNX|WW$bXWq$VWX(X53X"X@'WO'W WqӢW|W%VuVVVVJVdV^[VxuVַVVPVd8V~VrZV/VsV3V`kV5V!0V;VDeGV!VOUvVhaVvUUUڡ|U\U:VOUfUTVUꐔUUU`V-VV~TV#)1V UꝌUUnU*U0U[8U-}U/UlUU|(U]UUUmUnUDU6UdSUU~}U_U*uUhU&U`U+UUUw`Uk8U^DUpGUe9UoUV|UrU`UcU~LUrV_7VAGVI}5VrޏVnVn!VVu VGV{VVEVtVTAVVVDVHVVVԹV@cVVW WQ/WO}WZWVؐV (W=CW3WW4@FW W1W*VW+ V AW3pWvWH W>WAWHWP8WFiW\BWKWW<WWX[Xa:WIW>YY XChXXGbW3W'cW W9:VV•aW_rW2WWWSWVFVVVwqVfVWVQWVPVVGmVVGV6VIVSVrdVh VcV'VJVvVN V>חVV" VkVV1URUܺIUUτ[ULVUϽU4U,U/dUlUUgUU]USU%UU VUUUǃ?UVU׍sUp U`U_{UnUGU ?U:UUU]UU]UnU$U UVxuV1zVT1V| VVeV\SVQVeVͦ\VW $VGV W5VV }V8WBW\6WXWEWAVVɑLVWoW AVVXW"WVz[W$UTVVVwVV kV V`V/VV#>VRV@^V '|VV V&AVV |U`V{VEVVKU?V!V V-VH V UV1UD_U U;UUUFUUU6CUUUFUjUN UbUUyiUPUhU|UU'URUɕUUYU"UhU8U5U%Uv77UUźUUUnUUsU;.U(UUI6UKfUJU UӖUBU~UUUUCU(UtUU7U͞UUUŗUКUJUZUZU;UݠUV U%9UUUWU*U7UUuUUU$KU_UUgUUU$U1>U)UUi*U#UtUUa9U!UUUaUUUUU?UbRUvUU2UBU^UyUrUq~UB2UUUURU+UUUTU3UgUU U)qU5UUAUUUUUɸUUUU߹UVS%UU4UDVJVVdV)U%VLVVbV U VV V.gVkUV~V7eVj"V /V"LV-V"VBV2dV9V;VMnVVVwVaVWVVZVVyVgVuVVxVGV-VV5V_V V VmVtW_WwW-*WVWcXWXW#WcW!WzW+W;]WB=?WwCWt@W5gW#gCWh;W5JVnVaVVVNVͣ]VebVDVV6&VNjVH8V+MV3bVV V+U땬V1U EVUڂ UȥUU&5UРU>UV|U zVIVU,VkV8V.V-VrVVVGsV-V V3]V&VQ4VK#VW΢V)"V\V@ V>&V^yVPhGV4VtgVV#V)VxVVVoV VZ*VVVyVϿ+V(VaVբV{ V+VbVЩV"W1jW1W pVW$sW7WbG`WH,W6WbWFW2SWWȨV`W3!yWxX̾X)WńNWXX=W&WA.WIWWTUGUU#U53UUUUlUt7UU^qUUpU|FUIUjULUNOUFUQUn*Uj?UUUUU,U?U:UUaUUf(UyUUU˩UjUzUtUq]UUUUU^uUUqzUU:UUU9UUR4UdUAUCU(sUܹU%U{UUUtCUUJUUUUB/V UU UV)VVƇV(λV9VS]V`VwmVVZV(3V-VVVVxbVOVoVUVVeDVWV6WVW9WrV|VMW4V~W$-VxW _WY\WuW4W>W2zWk VXjzWW_BW@W6WۢWLYX-WC[8W\zW}uWDW΄VEVVXVVt[VVx2VaVY{cV[VojVn+VJV74VMV{V^VV&[*V(HXVYWV=V[LVPV\+VCVsmVVU% Uͩ!U}UmU?mUNUU^UUUUcUUU,aU³:UU}UUzUG[UEUމUUeUĤUUkUUUbURUE~SUHU0U?ՇUMbnUX^UXUBUUA`USUW8+UqU=gU:+UCU^6UR#Ul\Un@UcUw?WUmUq>UJKUG U7%UD UM2U>UI1UVJU@"UJdUuUlUjUSU!UUU"U~U5UNUnUYUspUeUgCUb3UilUzPUCUKdUG̫UMU}U`|[Uq;UWϾUC'UUUU[UUlU!U[UU~]U&Um?UoGUUUgxUcUwUbU;UKA5U|=vUcZUU3Uw3UUh8U>Uo UܴUYUUx_U5UZUUhRUXrU`U,Uu^U6Uj7UuUUUUUVUvlOUJU=UU_Ub#UjUUU UkU:UbU]=UU UWV?U5UUUݓUUVVVV VVSV6-VYV>Vx?Vil5VV[4V\VBVoV'V_VMVV^VI?VƵVV8hV\Vv=*V"VW;fWBoV_GVFkVWQ5W|gWVW&\Xe(6WoWRWW2 WYiWVBVDVl!VDWVBV9 V>_VUU-z U8mU@`[U:USgUL=UR[ U:nUeѴUj9UBXKUR{#UKUU>AUPUPU@ Ui(U{UqUU#UUdUMUGU%UnU_jU~UnUqUUɻUq6U`GUoULUEUUlU=U>VFV?9V>VA}U2V tUAU嚊U EVU.NU&UrEVUUU(U{UfUUIU` U(U|\U̿U>(U U@UGU;U4U|UU'U?UtUZE Ug\USUi Ug?UZ+UQUCU_UVUofUXXU26UBUH0TUcuUQU\wU5UOU]UXmUaUCU!U (fU U"{U!=U U$VU6{U.U)TMU"UIU.3U3U,@U.U+pU9%RU-YU7RU?UUP U-]_UKW U7rU*U(i7U1WUU.YU?tU-WU$U;0UC UQ URbWUv\UntUd!Uv UrUv_UikVUvoUsMsU~gUm U\{U]UC%UFU;8U4EU>U4u*U4U] !UPUQ'/UhU`$Up9U3UhUQUqU1Uy|UoUUmU|U~UaU{[U^=UiEU[U?UBcU3^UV=UhXyUrՓU*UP]U|UQUv4UU~U*U~tU(UUUϩU(YU/RUjUJ*U!UXUɀUUjUmU4VU՗UM#U|UϋU݅U]U蓻URUʅUV^ U8DVV w"VV+V V&uHV/V eV06V1VhGVeOVQE,VVzV{V>VVAV:W QW lV˞W>W(ZW,"U;U/U?%UKeU'U+U(UvUuUE1U/"U?PU=ImU'{U jU$U!\UU U2UodUU(U6\U&U"9UH"UB#Ug[UZ YUb-UKU?εUJUE$UOUS<6UB;U]UaDUHUBIUFbU uU<|U&'>U6U1UFz UNUNUWUs}UlOU}Uu(Uw[UD/Up%U]UgUcbU]s[UHLXUH\UhUj@TUYULUIbwUI UIUjK&UnQUUnU U8U$U"UUdU=UQUU{U5}U UzULUÇU3$UU#U:UUΦUхU3UfzU5UBUjUvV yV6VUV$VxV$m>VJhVV~ V@VBuCV@VgYVa vVpVB@AVbhV;(VӄVV~VV~VV;V6V/WW#Wc!W)nW(\%VqVWqX!W).W"EW%_WbmW9XXp{jWwSOWW6DWWscWWzV_V WT(^W8V2V.VIVvaV+VYVVAV5x0U@ U;2!U8UDUL;U1/UODU=UMIuURUU>UMEU;{U;΋UC8U@UaqU{UIU UtUOiUU0U#IU%nU?YUNrUH-U*NDUM+U7tU6̴U3YU6["UV"U?FUHUMԝUAŷUAU; TU T{U U:U UU$wUU-[U/ *U@UZ'MULU9U?oUaUS9UEU@U8$U@ U4U1b(UVyV4V+VVU&iU9U$U JU%\(UU"CU4U:U=U>UG*U U<ѯUBNUHzFU> UFzU-U!U**U$2UYU$mmU/UU(2U9+U3UI"U_z&US*UYUyUi&?U`ŻUl.UYUSgUdUdUIUGUJUEnUCNU2UD}U?TvU:)UM-U:GUQBUK^UT`UcU^UT#Uq~jUj)UYH&UUdU UTvUWEUr^UiϯUnUwUYUOΨU/9UAlUU2U] 0U]KUKDZUV.P=V]V3_VA: VVV)W~V@VPV_V?tVeW5WXK>WWUWsOdWVWsXVV~VVVvjVVVVgVO}jV:/DV0Vb9 V0]Vj&V;QV eV <(V VvVVaVVmUUHUݼUUUUݒUUbUU}U:U UBUcUUi%UcUUUKUuU^u.UgUXUhqPU5UQQU0$U0U=dU0'tU@`;U5 U?UJU9EU3<_UGUFU7UR6UXOU9/LU@UA:U0} UAyUAU%TU1U&,U"U 8U ZU .xUeUU XUUU%YUpU*U(ZtU0FUU#U3UwUU~UhU vU5U9U"uUU>TU dU,U U U$: UU*tU8}U U-_U3UU(U(BU#QU,p{U9S$U=>U;U04U.U""U$8U%\U~UZUU MU UdU FnUU$UPZU/U96U6'U1U+UzZU%jU%U ?UhU'FU!0U'\U#U3UHUjU X*UU U+[U-GU5'UWpWIWHQWb7 X|:Xd8X.XnWW ZV5xV]MVIcUUdV)_V/YUW&VVVV*(VUV Uo5UpUUױ?UƻBUUUUURUUU3Us?[Un'UUv9U~OU`UY&CUskUlJUrU|TUSIUgUZhUSURc6U9 U>BU-rU15UU$2U+MUH]OU@UJdcUS^UCUW$UFU7 U/9dUK%U6UGUMUC?bU>jgUE UCU7^OU&K U!gUUIU9UUUU UUU#;OU~U4qU$bU#U YUU.:U,U&pU wU(UJU"{U<UUDUjT;xU`^T{TؗTpUULUUUUxUU.'U,jU3IU9& U%HU%U+4U2 U(;U?-jURU/OU;lU U!+UUKU5U }UloUoUN&U U)yU@UK 'U5UKU(UU{U*UAUUTeUkoU VUUU:U BUU-U)U(U-UCU={(UWUVUO^'UKBUYUPUXsfUfUdUqTwUW.sU[ UDUoHUNTU^CUq'UfUU'UUq7UgUUU,U{U{U_SUwYUտUUKU VuUi#UHV'pV*V -kV0V}|VUV11Vo[V@[V Vn:VVYV!VKVϰV9VdkV^n~UIU@\RU8 UGUmUT/ULhUbU@UJ1UP[ U^7UJ?yU_UH!Uq7UZdU}1iUwUwUUU,UUkUyFU@DU^DUlIUUU)UHU-UUUȋgUNV];UcbUUVjV0'V:qV@VV]V)AV VEV1wkV4#V VUhVQV@VVVEVu(VtWrWMX1CWXX%WaY6WWwAWtEW(BWDW!VVTUWU U U OUTJqUPU:U&U8;U3O U,fU5U-MUU U,p7U),U, jUU$U&YU.ZU /UU U)U7 dUC]DUBU<U,U8U*U7%UU)UVUM_UNTU ^TTVT0T3TNTU+T+TLUU$UU2U*U$H#UcU&b U;U )U>U:U&6@UOUU8U#oU*U){UU6T,UU iU U U%eU;U$>:UD۞UV5U4 U:*AU9 UN^UKUU9PU4U# U>BU"UL(7U(YUMb[UI[U#!UDTU9\U7yUPGU9jjU_(UnUo'UPVUitU[UwUl%Ur3UdXRUaUfUoaUkU~UtULUhUXU UeѪUg*UURUtUZU^UV$VVGU1aUUU*.,U?U7FUJDU cUU'AU*aU0U RU ˾UU!'UUT U $UK^UFU T=8T"_TYT8TՅ/TªT{UjT U TT햕UTwT U!T8T:UU:@U;]UX[UTTjTMGT Tm!TTT"Ta'T7TUM9UUEU6U#=U"UUSURGU3UUU(JU{*UU U]]UT@UCU]TjUDTDT9TTU'UeUBU mU֕UqURUUtU$gU 1U UU8QUUUXUcU%*U #U UemU>T+UUzUaUJU7U9U<U'+U&hUPU8 UYUS >UN7UdoU?Us9/UgU|U:UxBhUwLUUNUU_UfUUvUUUUUӦUVnUU;UQUUcU UԼUU8UPrVXV-mV?VCBV:q/V.VQgVV>VCVJtVgz0V+VNEV]&7VV~VVewVfVVىVWV{VƿW#WՂW~ "W;Wso+WŏWgzXsX:+WXƖX,ʹX W;W1VVMV!TVIVVV8V VFVS|SVuVUU@ Uܠ$U+U9UOUmVcUXUǸUΒ@UHUD U"TNUU7U;U ]U U X-UUcU #U%UK#T_T7T" U}U1TT4TTT8TT]U2U UёUpSU$;UUUU9UUR9Ug4UTUU RtU =USUJT27TTTijT5UUlU^U UUUsU U FU)UCUU UaUe_UUTlUUǑUy5T}T^TTs@T+TKTN T鶹UAU 4UKU (UASUU lUyoUTFTUU|NU4U UUgURU UUcUU.U^qU+|U( "UeQU-UAU; U.ZUA U8!U@ɋU@U=$UOU0U5^U3$U#NU:UA=U69U$>U0SU*kTURUEyU65UekUvUU]UR¹UgUUjUUUW VV:VcV]pVX*!VV_IVpRV[}VbuV3*VUUUBUIU6UU6UQBUδUUuU.Ud?UcUKhUh(Uz]U U+U,UvUtUXUf UwJUWNUYSUO^UBBUJG?U::U;U;[UO:LUJU594U$;UU'U7FUJBܹU#6ZUxUU#yUGU/U#U+UR~UwUjeU*?UYyU }UWrGWnXGWLWYWW-PVV)V2VyVjVxVRi VI["VM]VYVloVuZVgV^V&tV"V?UUUUjU£CUũZU9UvUxHUBeUU3UtGUnUaUU Uw$UUWUU6UoU`UZUl:UzUYU\z;UC^OUD~U7%UXyUS;UC[UGUB&U%6U-ZU U7EU)U%.%U*NUjoUUōUUpULSTiTTITET|T6TTߖT?@TT1[TxT TTFTT,TIRTTT{U UyU\TT 7TsTfT.TT/Tz&T)TTAT&TgTTTKT@!UZU~TpT TTThTTTTԵTTTUTTDTл,ṰgT־Tܑ\TﳄTRTeTTuU U mU1fU ޾UYU jUdU SU |U .eU=UoU U UMT-TJTBT/TEU {UU$jU U|U.U$oU&rUHuU$)pU,Ui U2U,U? U+U-iU2c;U)fUD:U6+UGUNDU;qiU#OUHwxUUUZUBYURUo;UzUԁU|l|UpgUPUmUo$UvhUc UfU{wUjUt!Uds\UvxU{U U&Uj IUWdU~QUUcUKUU{UYU,UU'UUM{UؼV UxV}9U܀V]=V YVOyV*/VKsVV ;V9 V;aVeV6VQ V+VV+V}VN,VYW4oWe~oXeXVTXPX ,"X"kV&WWLWEyWWd8#VVpVMV VVzV(V#+V[WV{UUUklUWV#VU^=UkVdV>VVbUUUU9U U9Ul U'8UUZtUUuUnU|UuUDfUMU^ UzOU`gGUSUeUrsUK(UOURTU>:U7`jU$U2UsUU(V VVjVQV/VbQJW:VVLJV՛V9WV~W7WCUWlCW)?XXXWēVWxWA/W/X;{WەXHUUU6UkSUfU[UWFhUVIUGUJU_AURyU``VU`!UCULrmU?U.{=U3UcU+TU3U+$U'AU*`U5EU'`U)YU(U4#PUHU;U8%UOU[ݔUHzU]FUZUtUYU5fU/UUk^U UYuUU,UU&UbU|UJYU/U UU^UaUU=V\UVTUbUcRV=V]VVVcV EVF#~VAGVd8V).VM.V˂W62bWiJW[1W;VWWtyW CW{WtW$>VcV`V-OV?VokVL2VVxVSהVFVGV>V$ƀUV UCUUWUUǝURUZUUU?U_~U UsDUxUvU[UmUUUtkUU/UdUiU_?sUZUjtU8WU4'U)U4U1W U#U,U)kU€U*NUU!U#UFU"UkUU &U#%U0JXU+gU KUc]U#U (\UUQUsUԍT\&U'U߮TU0TU!TUU#T*TSTT5T=TԇTTU#0TU 7MTPT[LTGTDž6TT3%TԈT/TuTTU?TkUT-UU jTaU U2T8~TMTT߰TYTT+gU TrT喡T掆TT;@TTmU zU UU UGUiU0UL8U\EUU|UU U UU U2eUs,U#UTeuT"TfTvTT{TUU9U{UUUUU UmUlU UTU xTĊTU U U?U T&T;UNT-yUUUOlU+DOU4U#DU0wbU<yU+aU7;U:-cU:U2 U3U2ۚU<7UBԛU?|UXU>zU^`UTUqvTUCUEUrRUv^UU|IUq U`UUӛU_U}U8U/UUbUMU,,UvU U8{UqU<(U'U-UUUVUoU FUV0GURUmUPU4U?U,O>U7U>BOU9 U.(UkU PU(ٵU$/ UQU/-0U!{UDU}UUoTU YkU&AyU/UtxUXUgUU yU DTMTTcTnRUyT'TޥT4TqUtUcU/T.CTmTFT TwT*TTTTJT#T1TT #TwTT,/TTTlTTTӓKTTxT.lT4lTjTwTݝKT%TEaT"TԮTT撛T`TTAT[Tz\T}T՟TԑATںTcPTޒ/TxT}gT TڦDTUq#TU T/TqT"HT^TTrTJ}TݳTTTTʙTTpfTuTFTFoTdU]TUTugTiUw|UUUU>UzUUU U*U>?UvUBUolUUUdnU2XU$U&MU!eSU!g[UρU'HiU-zUJUAqUGUI#U(UIUHUSU?UEUdPU\U~?CUU5UQ UF9KUVU~=VUzUtU.UU4_UVUUXUAUcUUU]UxUTU̝UdUP^VDUBUڵVHV'TV/0V&)V$PV.&V:BVZVF6cVOVr1VJ+;VDV{V@VVWW]WyLWRW>r^W#WŜVʧW'VٽV[VV=<U tUlUBU}kU;UcGUxLUn~Uq*UU{tmUl2qUSfWUgVUflUI\fU&!U.UU$,U2fU*6U!U"NU6lJU4U;U!:UhU9U[UmUTUUUUUUBUU C UȼUrTfT=T9TI^TT]T`T.tTMNTTcTPTTTQT\T7TPT䇜TǻTT$cT.Tj^TT֑9T'TÙTƒsTITБTFxTyTT TnTTT-TRTiXTgT -TbTڸTDjT@T|T0T?TɣTTTTDTTbTT9Tӄ T6}ThT`zTTTTTTTTT(U]{U\Tx/T T>ITesTTTdT=TdTTTTfT5U}MU%U U@UUdU-EU;oUϯUUܑUUVV?V09V V%1V*-VFCUV'AEV"V*&VivVM-Vs)V4V'VhVVTQTݦoT&MTTnTTKT6T牋T̄4TXT'"TӷT5T:T)T;T׆T 6TQTTpTT9T#TqTLTOZTǔT>T6T`UMUePT@TdTGkT/5THT8TbTyTkTVTTBT۷TtPT3 TTTKTTTsTTzfT׎Tu~TseT(Tw`TgVTaTҁoTrTmT#TB)T^T@Tǹ@TETDhT;TڰTT~TY"T+wT:gTᘒT|TTo)T%wT|:TړST2T$TْT&T`tTЕ?TTT>TTʁTJTTT TvZTI;U4?TsUYUEU ,PUFUVU 5U3-U U UaU#bXU/dU7X7U%pU*U0DU@ U6U;;U.-UB@UDdU8sUMgUVU^1/UkU_6U2Uv0UUzRUxUUtUDU")UUDU2UU2UUUOUGtUBUvVV -VөV'cV#Vap~VV!VkR~V V83VsVmsVV|¼V`qW'TW(W;W9GW-\2WWWVV VcڝV_aMV~V%V{wV;V/VQ+V%cV _V*RVFUVkU vUj(U|U UUīU%U'hUrU!UUUUc UQHxUi)UiUrC~UUeU@UXKUO0U?"UE% U7FU'U. zU&\UEb U1U(U&}OU/UU#3U UJU-eUUU#%U!yU?UU{U>UUTsU:*TWTTTbT~TUTT讙TpTUTƘTOT\T gTTh-TU LTgT戗TTݫTļTWT*T菖THTT足TBGT3TLTYTTqT9TբTiTBTT2T TTTއT(Tu>T㨵T̝WT¢3TTqTx$TŞTT T픸T'TUUUHUpUUTwSTU TGTdFUyT>UTYGTtTST(TT8T;T2T}Tڎ4T)TlT1"TITxU|U*TTVTTuHTܖbTTTQTC:TT*TnTTgT4TJHTkTT UTU1UPUUAUaNU{U UU 3wU T7U UtUnUU U)U&D~U8&U1[U,U*UDU3XXU8U!UVUYUcVV%QV!"V VAUV+V_`V4VVVkVW>XcYWWW<W,WWWEW3X WQhVVV$lV/V]6VKVWV%$U0V"zdV7uV4V<HV+fV(#\V+VMVU;U;URU1UY'U;jU1aU9)U1UR>UD#UEU#,U(jU?U*cU8HU#U7UUUZIU"hUXTŖT.TVTPqTT[TqTZTTTaTڑTTGTΦTT1TmkTؚ TTBT{TT TJTGT@TƨTTOLT,Tɪ}T uTXTT²ITܨTѮT[:TCT'T̚TҸT#TWT#TjT.TήaTbTpTTTB_TkTT@T1TRTdTX)Tp%TIJ1TCCTYT$TTTZTنT~TNT8TTduT6TsTT۔TXTT3Tۼ T˓FT?NTT TZ|TЗT߰TTT>TU%UU@UU UU UU,"U@UOqUlUvUmU |UAU+U0U^U+U 7U&"U!UU6U-qU&U355U"j8U52U=U=@UFU-@?U*>U9U=UB@UJUL UC*mUiUUzrUbqUa$US!UaֿUIUųURU0UU0UUCUGUyUU܋U젴UuUݰUnU@ UοlU̕?Ua6VSU#CV:VmV30VNV5VVteVXVvVdGGVx"VVW W,X"KTWeLXTFsWmWU XPFWcoWWVyNVaVldVtVAJV(1V<VWHTV}VUU5UiUڲUWlX4WW#ǾVwVW]{V,VQBVLVWV lVODV 1V7V>V VߔV JUU}QU6UeUcUUUmUtUJ+UeUeUΦUUUwOUzUvU^KU+UOHoUIUC0UPU'U8rU9>U&U>UU#KUU&UلUHUU cU#^UUMUTiTT2Te4ThU#T6T!TِTTȚUT^*TT볦T_TကT3bTTܐrTTITEiTfzT.TYT&TpT-TTՎ1T\`TQT LŢ&TeTTÀaTTӡT¬}T{TTTTӥTӄTϨxTǺAT˖T#TTTnTmTTT? U.ӝU>U U0xUU%_fU۵U U!UXUUU!UTUodUT6GU,NUXUkU 6UU UUdTZT_TTӭ(TUuTwT8 T6TT^T0TT(TtTT&T 0T̑/TT T̤T;TT.+TϰTTǭT֨TT;TTgTlTִTSrTT=+T^TTT`TXTڡT=T`T+TғTT#TFTҀTTfUTATX TTT_TjTSTT!T(TUUBETEFTT*T U -TTQmTTTT:TTBsT\TΤT vTT޴T!T͓T,T,(Tކ4T3T#TұT̵TGT˒vT TTTaTT!TDTF-TCT T8TڛTT#TT@TTKUMUU EU`ȖU`U"SUU.m7UU#o:U0~U#U.5U7U 5U/U6hU- UJZU7U,VljV\5V>MV_DVV'ZU/U,zUUUx|UUU`UUv0UIUU2UmUy͉UwU]UUhUY0UW UY/UmPUFU`XIUH3UN_8USUQU4U!8U&U'AU ˞U#rU&պU8U 5U#%U 6U %U %U UUUU(?UyU]UmTTTTbsTMT#Td!T-TxT TLTp^T]T΁TITʀ5TTTT wTTPTTTT TĪTT\TTTTTfTT^T"TñOT2T!TTET`TTtT.#Tc TůlT+tTP@TqITZ(TtTOTydTRTTbT+T\vT T#T߁TvTTvTϺTlT@Tͼ%T+'TXT 0T7T?T؁TyiT+TlT TܨTnTTqTZT5TThTT۽TT~nTُTt%T- TeZT[T߯eTTvkTUT֭TaT-U !TrUOU?U 1U mU U U LIU SUUVU? U6U'rU,=U&U#xUeWU U2pU)=USUF( U96U:1U4.U<U4RULsUVХUV>UQCUeDUjCFUQU UZUw]U/UْU?U@UFUOUUFUUrUUs0UUUo>nUZ@UVU^UYUSUIDUB\UU#{U2QU+pU ^U,"U5U'U%iU*U&PUuUUTU ]TUZTqT}TsTYTDU U ҳTȜTJT+TÍTytTꪺT۸dT6T"pT:TGTۥTѢ=T͸nTNT'T*T4T2ToTT4aTUT+TUASUhrUt+UMZU_ƝUYUCUj/UUU U UmUUUU$Ud(U,_UښUWUURUCU1U>U1V \V.U׊V.UV+ VV}TVpZVH&VXqVdV|dVdV[VV9WVb)Wf־VՊVQVpVFV) V@>LV5U*V "VV&59V'h%V>>+Vl V oUU{U U,UUC@U(UUUfUe'UUrUrtU{?UoU}NUZgUVUC;UIUSWU7'UCUCU;dU(SU(׽UE U@VU.^U(U+U#U;OU//U5yU.*U%q5U!6U2:MUU UTURUFxUU{/UyU~U_>T=kU8sU)vUUbyT`U TaTKOUT T7T3T#yTDTT`TTTT1TTޭ)T TӰTXTAT*TTxT75T\T)TiTTݦT(TmT7TT'T!TBTTTTTTxT T ToT6TTi$TTTTRT5"TTTTTyTh`TY3T]TQT#T T}>TTTyTeTbTTTTTlTTPTڒTcTڗU>TNKTYUT3UՊU #UU#5UUU DBUOU-U5\U4U#U48UIU<)UJU)JRU UMUkVUZ#iU`UQsUH9Uo;LUQ|UShUqUmU(UUFU݆U[UGUUU๴UsFUѨU=pUUoV@V VVVN>mVdGV0VZzVMXKVHVlV"VzVkV(W8Wr!WWv+ X8DW(Vk7V+V`(V=ՐVLV`$OVpVVpVOyV,UU9VVUnUUAUfU)U/UrUUUؿUQUǞUmUpU"}UUMUUVUU6UU+wU~UUO-U`yUT?TϴTCT2T˜ TT]T%T[TTF>TçTTT"TFTTT)TiTT&TTRTeTM}TT;TsU+U UjU (UmU UkU,inU"/UDU81U&w U5:zU-?UU&UqU.?UJ UZU[%GUNIU?&UF%UEUnUkoUpUVtUrjUg-UUUrU UpUzUU UUjU uUpUF$UƪUU!UsV÷UЇV6UuVA~TVGVLVd.Vz\VrW,VVЛEX$kX,WWWòWWW(W V5VVtQV`'VVVwV-=V=t"VFwVQwVVlV:VVK%V,V2U+U4UU-jUۻUYUŶU] UUbU$BU+UUUUU{ UNUquU#UUUU)=UkgUP!UIU+U;OCU}U7Z/UDU'UK`U7}U.UgdUzUUUU(UdU x;UKU^U3U"U{UAU IUT+T@eT+MT%fTTT TdTAT`TϞTT}TˈT@TոTvTZT?iT>T|wT)DTTwT7 T+TTT,TqTΕ0TZ TTxeTϨ8TRT+T/T>TTT TT;TQT+T8qTLTVTTMTbTJTBVTTȉT]uTTTT}TجyT3^TdTTTKT̜TT]TގTTͅuTTFTnLTa~T!TÛT;TTřTMTTTݮTӱ(TdT1T TQTTʮT̯T fTXcT9gTz%TT)TbTϥTϨT_TF%T9UԴUJT<T{U U+USfUVU"UU`UU)"U7U?U U U/nU7UU$ U+.U$G:U@UU1t.U; U7UGU3U>U8UEUUN*U2UiDUbUcURxUUkUU0BUcUǧUMUU:?U&,UUZU1UU UzUxVV %U:U΄GV%,V mV*$3V=VV2[VM1VTW,VFW~VMWQfWW6EWVV4ViyV?VAV~VXvVUIVZV-sVP.0V VžU{UVUllUvCUg=UjUUU.#U UUUNU&xUGUcUxUU[U.UIUUwUU}8U~UJUq@xUnUZ$UV1FUXUQUM?U-,U"iiUU'cUU rU TUKUU$,UULU=USUUKUkU TUUUU*7U TUHTTTT-TdT&TPT]_TrqTIRTУTTTԐTǓ)TT!TҤTsTT>TuTTnTPT[TviT!TěTOT@TÕTqT=T3jTṬTTwTNTAT!TT8oTD T͹TʼnST3TmTdTIT TTT3T5iTTWTTT,THTTxTTĪ;TT)T"TTTTT~%TTwLTίTfTmTETV&TTTtTMT{TUTy>TŧTT§T˟5T!TXqTiGT-TǷTΫGTq TTfIT9TT~TTTKTpXTT9NU >U-UUUU &UUU$}U `UGUgUU U'/U U/wU9+UGUKU,AU- UQ>UrtU`JUoUdUcUx/UfUWUנUU.>U9IUU.U6U U7U\UËU׫UUzVzUXU?UϗUbVI$VVbV')mVV_VVdV!V;VVWWW BW}@WzOXAs[XjX#TWKCVWLV V;U=UDU*MdUGEUKoU, U%U#vUfUgU kTJTiTTOU EUUT>TaT TXTٿTTךTNT-0TQZU.AT\rT4T U TTuTfT=T}TTԅnTշTU*TbTFT"T4TTOT8TLTمTy0T{T6TTYTdTnTQ!TT}TlTVTu^TgTK T¦%TÞT^T)TfTlTT TVTTTcSTUT;T8T:TmTvT}T\TTTϳDTɯT=:TTTЅT3TہT؈T?TѣUTTMXTTI`T^TTTT9T͚TȲTv@TjT=TqTTo^T_TTT-T:'TTا8T)=TìTܒTT>T{T܃T@,TݻmTT۠T]TAT>TݏNUCTmUȴUڈUdUU*U UU3w)U( U%4U2>AU &UHU*MU9URCU1JU:Uo U`tgUbUeUq=aU{UGU?U UrUJUݜUU-UUhU-aVUzUU9UrUV8)=Vj}V, VV+V+dV VYV[VVVpTV[pVXW]Ws:WX"VX/@XqWaWWCWCVWiVVbVVQ;V}V)TVVVUYUWUjU*UvU!UuJU-?UUUUL0UU U3!U` UULU^Uy7UTUq˷UhQUd|U[*UHU^bQUUgUt̫UOUGUAWUC1SUJUDWUTTTԎThqTPT lTYaTݳTdcTyhTڸTTzT׫ToTͭT48T\TnT½TЂTTgTT{T}TY[TTǙTaTOT'Tܰ`TT'TqTdTGT>TTTgT T-TqTTαzT.TT%QTAPTNpTfU,U TrST1TdU~+TUcT>TUxT_TPT֐T=UjT%PTET0TmTϯ5TZT֪TّxT^TvTTTlT[UTUT>T=TTNTovT&gTsT]LTTaAT^T@TT|UyTTT^TT#TSU UDTѦU moU aU U UT{aUTUUU.hU U(U"ULUcU`lU1+U2UCU-U9>UBUMU7$UI#U.GUHUN*UmwUIkURU:hUKǯU[yUUd_Us4U?UktUUUzFUU_U-UUU¯U_U_U`UUUmUTV gVU鈶U$V#VAVvV HVVjV6WWvPWqcVսVXW*VVՏV=AVq V#@V\VBV-V4cV(xV +VíUuV9aV9V nUhU!UdU[U.cU`UZqUUUhUYU=UtUwJ%Uc@_U~U=3Un$cUqUOUHUPUOUCUW3U8 U.2U)U*U+0U%U"UNUpU"PU*UUNU UUU !UU`ZUUU UoT$T^TaU7TIT?TмTT.TR[TBTTCMTTLTCT 0TTT6T#TjT T6TATnTCyTTw>T *Tc8T?TSTToT̀UT؅TたT4&TM TܧT년TM=TJTgT/TT䘇TؠTwTTˉ_Tǒ TTLLT-oTTڽTS}TETTT5TTqTbTӢzTTńTTT]T, TT U/~UQeTTTT`TР^TT,T}[TT㯢TUUU &YUU$U 6eU fTrT;TTڋULaT3U&TˣUUcTPpT7TƖU>UU/UvU*U @IU *U-UáUbU3U U˒U QUUnU`UXT}UYUVUzU!U" U*U U'LqU#U"VU? ULWU7UUVV6jV&hVb8VN=V"V[VwW/xVPWfwW^WJ(;WSWJ-W WBaVoV=KVEMV(V,V? U:?V@YV"yV}=UᇛUҙgUҁUUU cUUUKUU:UdU2UfUUsUI&UO#UϮUQVU]Uk2U_UVӇUT@U/T2UXUJURԆUZ?UM\HU@U:aU*#U0UpU!dUU~U U:UzUa'UbUU8U*sUkvU׃UnUUuTT; T(T1TTT#T{TT%?T؈T2uT8TTATTTkT%TrT)nTTP T_TƝTĂT|%T$T@TUTC]TCgTST_TuTT-ETT.PTT~TQTWTT7TTTMT TTvTT(VvwV1 VWV9uTVUygVT8W2W!VxW6WWXިX\xW#QWp(WĦW=wV V9eVTLVCtV<V8k+V 0UUU׵UU։*UBjULUUMUvU_UUd;UVUz>U@PUxUetUpLUU]AUH#UZUL U9{.U=4UKUSYUCUB>U=9U'!U6LU6MU&_qU>UDUGJU#>cU&U(%U9rUU>UyTT.TSTyHUU U{U+U U)T.T$YTTTTzT VV_W>VvXO?KX`cWWlV VGyVN$Vi|5V7^V ŊV,UPU9PUڏaU9U|U?U^U UUIUUvUUU'U UU2Uq6U/UcUj UXUo[UfUmUVNoU`U7qUJU7U/U5ZU9!U;UO`U.ɫU"uUU[U UBZU$DU##UrU%)BU.{U%U U UUU 5U }TvT$TTTUuTTtTTT{,TTCTtTEToTlTjTSTT̉zT5[TӈTI>T#TTVTvT^TT.T%)TTЎTTᴺT({T%qT=TnTT4TԵTӊ"TͳTiTUTT7TT TlTTTTTTTۛ0TT VTTAT̈́TTOT΄TtTև=TdT:T3TT$T TTmTR*T̀TT`TRT %TduTѦTOTT+TXTʷT*T*T TrU;T8TKxU]5U URTJTLBT1Tz`T{UT cU5U UqUWUEHUǏUCcU R]U6&U jPU"SU U$U2UJؠUCU9hU/$U7U0U$*U!U.U5Uf UpUpYUwUr)UsU-U-Uh"UUU@UU,UUbUiUUUeUUUV UHVnVG@V-7tVXV\VkV|VYV+$V][V6W44iVV٭V WxM\WgXcX-LV .X(>WjWVV,VD/V;pVsV%EV3 PV:VAAVT8TT䌂T TTTVT.T+T!zT5#T瀯TT׶T[VTT9\TTTrTƜTYT/NTggT@TET TTTFTT~GT7TTTeTT9TGTkTFQTTW`TTzU!U NUnU '}UzUUUUEU [UUU{UQICUXU`gUhwUE5U7U>U#UPFU TTwTN/T)HT]5T\TTTzTwT(fTڸTTT'TiTT^Th;TxT)@TTBT]T1TWT}wTÜTT橤TlU"T?T UVknVdVLWVTV9V#HV%9ViU}1U+VdqUdUgUUUoUUUU@UUͨUUUkUVAU_TU_.URU֒UWUUPX*UXlIUI1U<\aUP[bU8:U<8PUy UAiU3lU=UU!"kUhUU U>UqU_U 5U;U U-gUU U,U$Ua?U =UU @ULUT/U$UnU UҀUUMOT =UhTTiTxT,TϝT۝T Tں|T߄CTeTTT&TذTѮTTT'Tm&T"KT̏TђTTTTþTĎxTT?TTWTҫVTpTTsTuT՝T؄T:TET.T7T/TPTRTVTTT_TĜ/TT)bT&_TʕTǾLTMTQTքTbTW!ṰMT[TTӅETİT TԀTAT0RTŽTTTTG+T&TT?TTGT8TTTTǕTT,zT TT@TT~TAT`QT{THTחTTҫTdBT5TeTT<"TTT,DTTvWT\UNJU U[U1U2U0%U"JU-MU$UtUU)U7UB2UJ@UX UDUgKU-U_UeUKUx~UtUU?UUzpUpkUUUUUO_U=,UU/U6U=UV/V8V?VVV$FV lVV8V6~VBuVV( V(V:V2VdWWvWX!U7WXUUjUTYTkT$TUST-TTfT$TYTT1TTݫTbTlT]T?T|T޻T.TVThT`,TuTQ'T慊TiToNT[TmT|T]TTմTuT[Tʫ-TT1ToTҦTnTThTz%TT!T!jTTJHT)MTUTՄTմxTޏfTjTۤTTrTOTYT|HTNT;TTN Ta,TǥT!TߎTTT֛!T1TTڥTT֍TTtTTTHTTTT;^TT!T&TOTT'T%T1TLbTѫTރ0TMTUAwUfU%QU gUU$PUUU%U?U"nU8mTWPUU*JUU T,TTTnUvTFTUToBTٜ7TǝT8TTsT'Tڱ"TaT[TߔT1YTDRT@XTFT .T TɊzT؛RT#T_wTPT=TKT[TYTTqTT%9TʴITe(TauTIT T؀TTfT&iTTTHTÉT/Tm(T TTnjTbTTZTTT,TW TrT ]TUT T1TjT4T5TTDvTT9T:jTKT'T2TrFUieUTATTjTwUqT:TU3UUpU TU E(UU nU t(UUFUUbUwU)VUuU U&hU h[U$eU$CUDUBU&&,U(U?9U>eU&ayUJJUO@U5gUXe*UL&U[Uv'U[z1UDVUuU2U5GUvUUUU0UL\UUr@UvU`UfUFU|U}UgUUvV$VVV UVxNV6VMZVOVd/VV4'VV?W!UeWrW_IZW/$nWi0X~WpXZXIW7uVVpKjV3VLiV^cUMV1>TV=VqV6NV VRVGUNVqUSUU5@UnUlUQoU"UUd$U"ULU,Ug2UUn~,U?I\U3,U#m5U/UEUJ^U>nUKW%U0 U UjYUUUUFU=UeOU EUU UuUUTBT-T'Tց T~9T!T TT֎T\Tz?T[}T˂TT, T]TDTPTTTT1Tή_TTzhTe0TTtT\TT]XT΃TTݲTwTWTy^TnUU TƤUTT$`T6T`TTUVeJ"V.WWjW߰zX|X~XJ2XgVVMYVOV+ VsVIVV#VCU/vU3kUzU|MU˵UUФUULU*U~1U~UYU}tUUh OUjT U]RU¢UVUJUWU@\UaUrUU'U8uULDUBU< UChUF2dUHU4 UAOU=U:UU,_U*U$FUJeU,qU"U'UAU)U1UHUUhuUU n9Te]TؠTxTUTT[4TTT˄TVTƚT/TTaT%TTIT❱TƻTTqTjTƀTŸXT)THT1T֥T TRTȺQTpTT TDTTȏ}T%2TϨTmTbT΃}TJ.TvTTYTa[T+TT{TT߅TTTT헯TTXTަTTTTT_T}^TwTÕTNT,TKTTb:TvT lT >TIT"TT`TpTȮ7TϜTDTTTT T *T TTSTaTTԴBT+T6iU YUU\UTHUUFU `U̟U ٘UT<U UQU cU UhUJkU0U2mxU3 U)@UU"4U"5U=)`U<)U U$!U$dU.dUL"UH>U2^FU& UK U:\UZUb^U\\UWiUzUlUqUFUwtUUsUrUZU"oUUHUc1VJUԶV9iV#sVHVEY>VV qV HfVVbVyV=V2VtV>VVoVoVMiV6V櫻WVWceWCWuW@WWGX<8WqV VnVedV_(VOV? UoUV VQrV&oV*VeU9UBpU+U'UUL*UUfUlUQU+UuUMUUt˪UeOUX$U_ۤUO%Uk(-U=UXeUQ^UKƮUNjU0 U,`UUU&UhUPU+5DUU$w{UmwU-XU!UyUUVU!-UU%:U1U)4pU~U"AxUT>[TUbTKTn$Tm+T%T TTw?TìU/T뇔T㢲T9TσjT? T˾MT%U5(U)U8xUdRU=,U[vU@wUDU7zU9 UEUHnURxUq-UU`#UilUn}aU|U=U|(UURvUUp.U$NUU̧UcUګVšU;UV .V# V^U U˛5V-|VVQVFMVP"VV@WЧ#WWX4WuWQW-JPX)̕W˴W?jVWVrVVaV`Ul7V:VGVVVi`VV-U@VGVMVJURUUUUUUŜUDUaUVU>U\U^Ur]UW%UUU{DUv]UB{UMUOU`}UzUBsUJ\U6U3U+٫U-U$˔U.s8U&UDMU" U UOU+U|U U Ue U UrUUUU uU TUT>JTTTΧTTƉTVT,T˷TAiTT TЉT˓T1T"TxTġTGxTrTɢTTw Tz`T%TpDTC9T5T̟TT1TIBT<dUTaTٚTߩ`T3 TbT.,TTZTHTzTTTzTTTT>TtTTvT]nTk%TU}UXU UՖUnUU1 NUTUlUUxLUUU;JU݃UcZUIUVULaVcV5V3:Vh;V!-KVVdmKV6!Vvl WVŹWI]AW<X 8WkXV0W!VV?VVtVhV"VhV> Vi:U5UNTkTiTʥTxT޺TTͻUQU8nUWU<UTUCb~U@`U57UBQUFUdUL>UhkoUmUkoUk|UwUcUlU|U0U(UyHUKUUHUUU3U? U9Uc{UGUUUMUEUzUIV lVstVUU.Uy:UVFGVW|V8V!/VF)VvVCZVVeWfX4tWWV WϙV#iV4VVOV5VbFVBjV$VGVήVm UUlU UUUU0xU̜-U3UUY9U UU[UkQUxUeUUkU@UnUzaUj%UZ$UFZUFhUZ!UTJUAMULRU-UGTU7U,]1U<U"U+U/GU U-U*vU8mU.JU< U3lU1&U&=UOU*UU UhU]U]U*U UܸUU$rU(TU.#UU TQ6UT7}U TUTbUUU=TTTTTډTATT?^TחT0TT/TTK TTܵTTѻ6TGTeTL TTT 9T7rT҄TΦTXTyTTCTTRTT_TT)T[T뫥TTzTT T̷gT TTνTTZTKjUT8T|$Tҳ T T T$T㼍T>TRT BT́>T YT0T?{TT>Tξ6TJCT@HT'TT&T:TĊTTTETq!TT,IT$TTAUnU U)lU +qU ,T<-T\UUV!W0VVVnVE V^VWVfVV9/V"VVV-VtYVTUcTT\TT韛T܎sTmTiT~T/GT#T)TjUDT-^TT3TTWhT, TT"T3U?UdUT T@UTt T5Tڻ+TT U#UTTU!vUU !T]oU>T`T|*T6TbTUTĢT6TTֿ#T΢T#TTݸTHTTTTTT]LT 4TdTēTTbUIU6U^UEUQ:UgxNUS UUkUakVeV$tUU UU҂U]&UU U JUUaUTכITjT=T΀-TpTJTETآT-TIUTT܍TTT*TTƶ TՔT۔RT{TsTUNU%kUq7U>UUToxTkITTLT9TG~TT@ThdTTT5T T$ U̕TU sUUU UPU gTUFUkTT8TTlT҇1T]jT*T TLTIU T]U֜U P.TqT[kT Tˑ(T"9T;Ta0T]TT6TST'TWTTӡ[Th]T@TT<}TeTU3T}TWsTSUUFQU UoTwU JU 2UT5U4'UUU!UUUUlUU#YU49U5FU7 iU2z.UAԔU+UMU5DUAUTӂURUUGUS"UNU~U2UdUzUtUkUU UoU<&U VVF UXUlV @UZVRU2VV"5TV P(V%VWLW{qWt W! NVVZ2lVV‰VNVp(VVJQV*V(YEV% V+'VUU+V 7UQU˩/U1U UUUXUG(UіUGUU8U»UΔUUUUi UUU-UIUb>UTUo76ULqUXjUQ U7U>MU+UHU!ҝU&U~UU>UU@jUϢUdUU _3TUUZPUPU)U+UU$UUwU'XU @UUrT4TU-T-TlTüTTPTT̔TTrTTTUT:TTTdT쎑TbTTTϿTT TrTϭT TӠTPTsTTbTşhTETݠTTҕTؕ%TTTٚlTTҕTuTT T1T_!TTT7TTT%T’TTT)TwTmU ,U WU ~TE=T/T0TGT;TTT뿢TTϰTTjhTTw7TԸTTT-TFrTUsTGU!T8xTT㦙TݑT3TTgUVU QTUTTY#TTWTT)T@TUUfU&/U EUWUUtU{@U*UITڌUUU~U0 U U'WUKE7U3U$ULYU.U?̂UIHU?1UMUtUohU`'UUoU UtUxUCUn!U_лUo8UY=yU?U{UUfUURUf UU?qU UUMUYNV zUV>JV(Vo{VVZVO4VmWfПWWsTWW7WW$WV-aV%V^Vag%VCV&Vl7VbTDVh'VVVͲV VUrUUU԰UBUUbUsVU*UUUrU~\U U UǥUsUfKUh UAU_UHqU`U1lU#U;U52dU;sUCݕU6}ULUU.pU,KU-?U+hU*U,oUU)pU mU^UGUzUV8U*U WUUUQ5TTLU!TU U _vUU{UUvUT#TsT+qTƂTYTETTOTئT[uTT&TTTQTT\TTTTߊ-T&TBPTͼTT T6:Tl]TpUTT T"UTTTy[T4T1TwTpT-T"TT8T@mTT'T&DTe+TTؑ4T8TzTk~T^Ue^TTcTOOTbqTT՜T4TT KTAmU9U8U *U!UTTHTU UiU]U#"U U<_U.U3HU.XU5wU)U%U6F"UcU(U5%UMqUWUSUo~$UUoU^+UnZ Ut+DUfrU>U^UUi:UU^ U&UlUňUjUUUU$UaUGU_U>;U9UcUQU*UiUqVVVV 7VG.qV\VrưV=gVe!LVJW`T-WAXi\WUEFUatURUSqUGGUAXUKT UGU1U,wU,U6wULUOU4U$L&UךUUUoUD]U rTUyT)U NU(UCU*BLU8_~U9U9UGUC{UFUOUKUBQUEmoUU-UWUqVUJtCUUyPUgUTUqULzUSUwUX.UgUUUˬUԨ6UV!ROUVFUU_UV VUU9U_V.V'yV6cVqV*VV'{V.tVlcHV\!Vd'VVWpVW(XXuRXHW$V̞W$'VDVtwVVstV<tV/VVDV+"|VV&|UVBUeU/VUU2,UUŽUUU+U`U[U}UUs/U$KUMUjU{UgU|pUL4U^UZUJ>UMUD׽U?RU-nUNtUV UDvU$.UHU"TU2U$U)dQU MU U s5UaUeU 0HUIU"U U'UD)TvT`TTcTTUET;TvT߄T"T"TTFT̘T?TҍrTE7TTЂ_TǦTTqTTPTTivT_0TTTŎThT5TοT7TdTvqTTKTx;T T!+T T(T_TUUTNcT楿TɟTGT]wTT¡TȣTTTRT T1TTƢTTT꒽TTJATTߓ9TT T)T6TFTƨgTQT̷T_UTTT(TcTRkTT6T$T TmT_T`DT8T/TzTɤTߞTT,TQaT\TTTT6T^TrTJTcTATsTHTT*(TȃTFUBTW8TUTNU.U UU xU  UQUMU UBThUUU(UUDU?{U.U'UOdLU8U3U8dU9U"UV%dVI?VbtV zUJVUV 4VyUOUVV~0UPUU_UU+U԰UUU2UUULUU{UUUUo U;UbUqU}25UsHUqUEy>UXɭUE(UB U4RU:MUEUA|U*U-IUU04U8(yU,>U"U iU~UQUT0U 2U. U8$UU5TWTMTUTݧTkTںTkTЭTTYTTzT:TZqTET9TBYTTT=TTٵTTm[TdTNTKT[T'TșTDT TލT5TʐT}T9T|T|T2(T}T T%TT cT;UTmT݇T=jTPTPqTTZTET1Tֻ(T˯TnTp5T T=TT-GT씩U+bT٨Tݼ TTSTGT+T;T)TCrT6T TJTT]TjTTjT|hTUmUTFvTUCUe TbTTsT!,TSUST'T-TU T`4TT$T޸T93TT]>UT_UU4U UU 8U hU U!2FUoUzT®UUx>UU.U*rU'4U/*UwTo+TUw,U: UMURUCUI!UGUPUvRUmUuUeUY|U{[UjUoxcUm7UkUUGUSOU˳U%UUlUtUo:UUU@VVR>VUVGPU_UV*TV U[V=VV"V>ҍV2V̒VWxGJWW>W]]W$JVVVGV+ V9j`VC:VU UFUXUU U!ǿU)U[U4M8U6U?UNόU+UOU+UD2UgIUsdMUplUaIUXU?UU)QUU%UYUU0U]0UU AUUUVpUUUQYUHTTT܀:TTCTTVTT\TTTuUVTTڱTT(TYTTZT\TdU!U ToTmtT;U zU $UITUFUU\UUU(8U'xU&UU$\U%U U7JUt!U5U.NU2U>U5#USeU?U=UQ U?U*U8U0dU5%+ULU`5UC)Uu U{sqUW^UoFUYs U^epUx,UhGUXUKUUi^U_jUURDUTU΀gUU^UU(%UhULU̻\UVU]V6VVeVH VkVVqV$KTVdKVc-VLW CVV¥V4Xu-WՁWXͼWkoWNW VVsVXV=UVU)VU;U3UɤZUԟU|U{UIU:UuUOrUVUUbئUn|Uq0U|U~UUU`E~UDXUUU^UWgUFUAU5US^U0|MUIU#U#G'U5 U#UU PgU4UU,XU VU)UR9TDUlTeTT:ULU TT~TTT&TWeTϊTTŴT:yTdTӋTVGT˨T͐TꭦTT?TǟTiTTTfqT=TlTTTMT=T )TYT:TTǞTvTޱ.Tڑ^TvT5TڸTDT2ZTuTT T'TTڛ@T{TMT_TT8{TT8TFTTTTԃ8TTT T;T NTlTLoT5TTTrpTNTּT?TYT㫩T䞭TxgT T,LT7TpvTZTqBTԛ%T7U lTU};TT:T iT1TTѵTz/TUU)UvU!UU3UQUUٝUpUUU mU']U+%U)N4U(U>=UAUTeUEUdnUL>U_#mUh UDRU@QUCbUAuUVQUuUXUUU0UU+U^UU`#U2UfURVJUUUuUOU$VVׅVUEUU$V&V|~VCͱV3VDUEV3lVPqVVyWVc|VGGVKVWJ ;WeWcWXHWmnW5WW&R2W"qW V~VVӾV4VVveVV,`V=rV0VwVV!GbUKUsUUĺUUuUUUU"U`U.U}\:U[gUf*UdA4UR`UaU`_UUNjUF3U?U:$UGUb sU!.U.ίU4#@U1U UUUU!9U;U/U*=UiUiUUUmUfU~U4?TU KDU+T+T$T.TT{TذiTm(Tt[TA T­TTiT@T%T.TFTnTTTTTYgTT8T~TDsTTdzT5T-TJT0*T4TˁTʤRTYTTxTs TdT0BTtTTkTT6vTT%cT$uTذET|TնT]T½tTӭJTν,TؔT_T\T.sT`T;T.T`U-TTnT`TZTTTKTHrT^TP TTѸXTTTTƼTϺgTT TmT$~TַT:T,T֌T[T|TMT̏TTݾbTz2TLT|TTӌTTTT TıTɡ'TCzUY1UUTUuUTU%sUzUtUUsU UDUUAU#;U)1`UP6UH U2U&7U;U%U.UGKUF1UBNUdDuUcUQWUjk=UBU4UaBoU]-BUGьU@MU*U>BUA% UYUUxBUiUuU`UjvnUU3UUyUiUU½UUUNtU˪UeKV nU"dV G UƸVbU:V,3VWV(VV)VVs)VV˲"VIVTW]YjW[WWBWVVΰ^VVmNV'+VVמVVCO4VFSV3VjVrV; V=UcUUuXU!UUoAUUnUxUlU;UUbU8[ULUNUUlUtUUUg9UTUj>UpdUM5UYULUFyULUGU:@U)U5'U;d+U10-UU=yUU-aUU U uU1U"U[aU' U7}U=:\U0hU$UNrU.UHlU/@U:U1fUZTUbUU ^Ul*UeHUcUZUz^vUoU\UHUUU4UUZUUstUUUUwxU *UNV}tV6WVV(^V +V gKVV\8VC V4zV$V5"VsV52VOF;V5yWT"T3T*nTCT*T'KT0ZTdTMTTmTSTDTT%TT!T3T#TmTtTyTTȇTfTշ8TuTٔTT[T^uTTCT`-TƖTu*TTKTҐTԓ?TTMTq3TϦTƤTʰTI>TTTwTҍ TbTST}>TڲTҖTfTT TT҆STօ T=TTuTܬTшTTR,T:TiBTg^T(T˃yT̨T{T^T5{TҿT{TuT(TT$>TT,oTpTUOU[UU%UѿUUGT|7T*TUmUULUU8'U2sU27U?.U-.U& U"KU&tU5'U&(U#U'U7RUYQNU[P-USUP~UI,U=wU5O+UH9U_;USyUdGnU_EUl*U}UrUPU[U?7UQUQUUjuUV:U/UGU]UK UgUUUzUeUV4U WV ,V8V5GV;V@<Vg)rViV`%VgV`V-RVW WGWW0[WpVt0VUU=UUUc9UWkUeڂUrBU Ud(+UYU_UO6UuUOUdqXUTU?@U^[UK U*U=^eU%QU&rU#U(EU/U$BUUqkU(SUR1U#0@UbU"3U1jUȑU U pUUU-U UUsU%UqU jUmU iU+U9U3U9TNyT"`TITʛU;TfUzT9UTBU,UTUh7T=T dT|T|TTX%UTT_ToTTX]TITMiTTXTbTԨT)T$jTUJgTTWuTOnTmT$TUiT8BTTYTTRTT)TRTߠT'T㍸TrT5T̃T|ThT&&TTTTbTFT T}YT TTTU:TmTTdT{ATaT^KTTfTfT!TsKT,T8T)TTeTڊTHTޮTkTؓUU UhUϣU TUT=UTzUU U"U.nUMsULi U\+US UYUIUP U5XUP=U9,U@UMVB7VNz,V,yV hOVI=V$V_UΝU"U$UcU2UUUU%UUuU UUy UaUU)UmU`$rUc,Ud4UWU]U^UC|U3l_UK[U)U3U8T4U=ĵU8UU7>U%U*ʿU,ˑU@GU9gVU2UBoU'aU':U#UwU\UUzUTvTiU\UU aU U U oUɴUu-UU4U #T TOU+Uy}U UJU)UvTHUwTuT,$TT^WT坅T]TsU6UsT{MT5T TßTTT&TTDT TnGT?TTmT2ToTzTVT˕T'TbGT|TwYT,TۍTU T U[T$T#T*TT3To5T@sT՞U0TʕTKT4gTOTFT(T _TT kT읪T^TJTTTTATbT T[T˯ZTGTT߁TGTwTGmTxTPYTyXT}TTTBTTױTTJT,U U UqT\uT'UNbU`TMTU UCU UU6UU)tUU1MT TU^UcU$U3U&YUD US(UUHU:U< }U>PU9SjUNhU;.GU@jqUMHUf3UUUUU'UUeMU~UyUdUU'U^]U(UUDV=UUSVUU{bU$UvIV<-V%pV-XVPV(V6VHVVnVVg1VPW:.VWCX}XFYMYBDWW#X|fWY+WVSVt|V+V nU8UU@UϣUsU7UUSU_U{UOUUUmpUHUZDUcUVw1U3gUJU6U7bU-`U$U^yU)U+U$UU'UGUZU#yUU8VU* 2U,0U;bUCU:U1)U'U<U5U5LU*UU"aUXU)OU,6gUUrUMUYU(|U/MU!oU>U#(yUU^UUUTۘT+USTp5T@TTTTkT2TտTఙT4TTPTҙTpUTEUTeU T4TuTtoTTrXT]T]T0TÄUT,TYTTkT۵Tv$TKTTCTWTaTܚTTm]TYTRST?TѬTȝTTT>"TT TUTTITeTTlT3TTTTTTT-THPTTƿITqT͍TTnTUpUUUU4U,%U\wUUUTU*CoU +UU\U6`UFU,@UU?U͎UUU '@UU$UU/QUynU(UUlTTThTTU[TFTATuT=T#TTTǠT듄T#%TTݑxTToU TwTTA T\^TaT+2TGTTT#T7[TT~TݐTlTμTםT\Tӓ9T̯T TfaT?gT@T\TЭTO/T9TǛ@TTƭTςT΄4TT1T~rTUDTSTTTeTURT+tTiT|qTqT鍤THT蝪T8KTTT+-ThTT[TUP]U{UXTU /TUTēT8T'TOT T_pTUU>BUkUUT T!RTpYT^FTFT'TBUhULeU:UU`zUU"8lU-jUU WHU!U^U!$U4b7U3|U5'UEU,:U.>+UUU BU5URTU=UU T*TPU3LTfUUtTU 3TU8T! UNUTPzUHT#TW.T7TT/TnTТTT,@Tݛ-TβT?ThTT3TֳtTэTlTٶTT>TgT6UTT1tTŐT^(T؁TT[T7TͼTFT]TUDT.,TBTTڒ TCT2T T{WT#FTTTYjT-TtTs2T8TpTuTٗTGzT~TzT`UTST$TT%9TLTT.yT UjTdTT`*T'7TADTߡT T[WT1@T?Tٝ TT)7U9VTzTUWUyUrTlT~UU 7U fUUyUUUIfT~UTcTaTUUOUU'hjUrU&>U/mqU5"UA0U2U1U#{U{XUQUT8vUW.aUNeOULsUUXUg]UFUhUB UI4U]˅UyUUUUUUȩU |UUUUUUUdUξUUV`[VUVvTUVVlUޔU0TTM{TT1TTגTGT쥑TUTPTMTTۥTqTIT^TvTlT1TŹTTΏHT_Tڞ!TҦTTٸ#TTޒT".TÎTќ`TTlTATٖTTaTT݅ZTTyULPTTT耍T/U4TPTSTTTLeTtTTߏTTЖTTTITաThTnTT+T<TYT)TڿT)TuT?=ThSTtT jTTcT]ZTTT|T1TˤT虜UOUU TTnT/T T(TٷTT۴TU׵U U"UkbUvU kUU UUUU$UBUU9U0UFQgU:UU VUU˕U%U>UU "U4U1lU5U9;U>U2/UFU6U?UMU?US7BUhcUdU mUùFUUUBUU.U?UrU UxVpV{xV'U$VU V*V! U'U'UŜU"U3UAMU\V1lV5VlV5VhVn dVI#V#VncVh_W&X:WdtWWIWXWWaWQXYXSWa6WΤV#VǍVAVVl\hVTV V'VGVG=`V&o7V@UyUV"8.U(UӉ{UrUU#UaULVUvzU4UtU|UbUxURUqJ)UIUuKU>qU?oUJEUG,U\BUUιU#IU (UTcT&TTMT˹TqTAyT~TJT TT0T)TBTT)TT]T TTTT@nT$TոwT TTÂ"TTƗQTuTדT\TinTlT8TمT*TKTTpTaTT/TpT޴T2TެTTݖ]T TTT9TsAT6T0@TԘTyTHT iT]T+HTaHTtTTT'T'bT邲T(T'TT6TޮeT4T\TTqTT֌TǞ9TToXTa4T6T3T7T߄TɊTؘFT|TsTLTTTը'TTZTkCTBTTTˊxT&TT7^TֵTۛTǟTTTUTGmU CU UԜUU >UBU d^UwUZUnU$U$U U+U\UU%QUfU{U!UdV2%V$VV3-^V8VV6VV4VVwW2&W%SWm.W)WjW߉WXXeW WVVV=V̓VKVw\V9V:VQNV2ZqVVVV-V=cUV 3V UD`UU֛UUQ|UTU>GUsUȄU[U@UGUSUUG\UUURUs%UKU&U|'UkU8dU7 U94U64U8,U@wU,/U)U8KU';U(zU&U*,U#U UU*UUU!)UEVU8U"8UHU!TU gTuTT_TGQT 3TTETz TgTY%T>T|TBTiTd T˽TTT2TGT#FTTʁTʓTֶTTؓhTTΔTTypT$TATʰ7T[T0TTS8T,T T:TTR#TͷTVT eT2T;TIT͜{T|T#TFTHT T:TO9TTCT˚{TvTmDTJ!T/T^T6TTOT%xTCTTŨU UlUMT\UTT5T$TTޅT2/TTTLT+TT/TčwT6T̠TT{TbETʬT{uTdT TkT9TT֌TT`TMTTTjT|/T @T@TjTT\TT_NTfT(ToTTWFTT2TӨ}TзTԐTD^TM TFNTθTւTTPT́T-kTޙhT԰TJTTTT߼rTح4TTTxT+TT|ATָ'TTtTg!TSTTѣTTTWT iT;TiT٢T*[T1TeTTTBTҒU TqU FTTU gU UUUUUmT١TU YUU'U:U LUU,U"sU"^UU/`U(UDKU+lU4UiUUIUSUWUbUfU#U=Ul!URUUʼnUUMUpU%5U~lUdUUU0EUcUU]U7UvfUUӔuUUVVVqErVaUVV?V"kV-TV V~VށVVW)CDX%d+XX;1XpWeeLV9WLV,CW"VVQV.V[VVT0UUмVӂUGULVU:JU7lUGU nU$UfUBUEU#UU6UUAU~;Uw#UPUhjUWUYTUV?]UYcUvR8UUU[UOWUUUcUT+Ual4UZʬUGU9U UU,lUU 43U'U+#UUU9UԸUUEUcU HbU@U sU U$WfU .UUU!U bU CTۏTJMU3THTݰ|TxT/TTSTuTT{Tv-Tc!T&_TT4TWT,T"T`TLTԕ#TZTITކATժT7T&T׉TTz#TTȗTҊ"TErT>"T'TTDT&UwUwWTTUUU T~iUxU UUmyU_UU8U 8BUUpU #UUvUU U&)U*@ U6U1U.U.+U1{U6,TTBT>TT\U)UUV U_U6KUoUU#U'U%UU0UU;UFuU1U"UۡUIUUqUPUU.I*UCDUE$UM;UI]UNU7U5mU_]*U6UgZUQUMUz~UlUUU0)U)U8%UxUSUUdUUTUUUU"VUkUVa~VjV%]cVVVl#UVMVd VVV,V VEǣV; !VW3VJWB7W!EXEWtXvX\"X X*^X-WnW,:W?XDX4ȈWVVlVV@ϩVsV(V[V]Vi!V;/V*GVG(9ViGV(UCVAUlV UUfUoUtuUU UUK?U|UUU+UZUUoUUeUmoUliUS[U+U*cU!EU gU,TUA9T]U 2T'hU U7UT^TH"TmT.TxTuhTgITT4nTT T1TT` T(xT3TߪTWT4T,MTT2*TUgT?TGOV@VqVWVOyV6/V/VJ9V?lVE_V" VN0V.zV UFUXU:UEUלU.U߁UUջUȲUPUUMUPUU׳UdbU7U/U۠U)U{UCUyUgUY?UgIUJU>+[U,qUEUb@UUsU?ULU4fU#/PU-6UV=YUAUF>U0=U,U'U U/xU)zUU~UUxoUFUUUGTT Tݻ]TTԓT+TT"TTT^TBETKTџ{TaT TSTQTTߒUmU^qUsjUZ9UqEUSXU\~U_U;UU UMUU"bUUˋUPU#UHU`UKUMUUUQU|^UwULU}{UekdUnU`UM-vUUNUYUOUAU:kU)UU5wU=U*TU4sU)9jU/,U(U5fWU4LU313U1jUU7YU:U(U1U+NUU$ U>UGNU \UDUT]lT.U^T0TTTRT#TdTׄTgT~TOTTUUT T TbT![TӣTL6TTԏ(TϐT%OTT2@TTTETۊTӇ*TQTT5HTVmT>NTֻT bTmT憿TTT&TpTXX WWW:X]X yWVV'VVV VtVoV`JVR+V;:bV6 VB6V.݆VVV [VENV+V)UyUUS%UUzULUHUUiUUDURUUp3UUU{nU*U ULUHUmgUtTU}6UzhUqw$UU\(USU<UXUT|nUN U,U+%U.¥U>yU*_U5кUU5U(IU&U3U32U%.U /MU!WU*~UU5U&UU ֢U!WUm!UUU"U AU{TU MTNUT~TUTTwT[UT1UU U8U Uu%U0T#T%Tr+U .KU\TTTHTΈTqTT;TTuTR T)TUnT`T/T=TXT}TT`T/T7TҩT'TT;T~T TSTT2TT T^TTITTޥT߭TTT bTATTڍTӞTפpThTzTUT!TT@zTTTTŢbTAT֮Te1TTtTZ THTUm7T݉yTT_UgTUPIUvgUeUWNcU] UklUcUYU{̩UqUUUqUf2UIUeU UUhU'UXUŘUUѤUs0UUU=UUMPUCUUUf-U"UpUmUcCU`>UbRU[EU]U?[UA$UWUZ]@UdjUm UcfUErUKUU=U91U4^U:!U4fUU':HUYUUU 2U HU[U s)U%UfUZU =TuU wU-UU UUȔU WU SUyUKnU=gTӐUTMUTT\T5TT9UKTTUU UU,UT T8TgaTbuT T)U& UATTẇT咬T3UA\U4NU<&U>TUEDU>)wU+{URUnUn>GU\)IUq-gUhlUzyUUXUUUfVoUgUU/U}?UӯU<UlUіXU2U#UU碦Uۮ5UóU@VV=9VOVVGVJV0EV0VVVVRSV1dVW,ܵWG?VVXXXNw,W=WWWWW(XhW1)-W]-W# W2V;V0rxV;kV|.V#{VVI@V TVG'VzVVV<^UΜV[V ֥UOVSUUrQU\ UʉUU՛[U7U}^UUGUUQUuUxUoUq^UeUr1UCcUGFU;U_NJU]&USrbU;06U5MUV4UNZU\YU2UUFcUhUV7/UV5U1A0U#DU@^U-2KU1U2 U U U xU aU/UMT.,TUTUTzT-FT]TUTqU>eTLT( T0TTa0TTwTY:T*TYTQTT TdGT܈TTBT3TUT澒TT׬^TCTTTՔ%TTcT mTTTTTT?8TTHdT°T5TDžTTT܈TQTATwTvTZT TwTQTTOZT TT6T}TkTsPTwT{TTYTT펞TTU bTT:TuTET*T*5TU%TfTRT;T/TTvTzCTTQTTT鍱TTmTU TUTTIT䚠UUUTU -UWbU9U UeUOcU$NVUU$U1ZUU'ȸU&U+UU ",U1U>SUMUaV UF9U7-US3UmUqEU[~Us?U`U_UUUzUYU U^-UyUdUUVUښUW_VPgV'VVjVt4VVVY-!Vk>V[ VqV2zhV&V|VV*V8HVGVVV"5=VV}UQUUԤUr9UUeU*U@:UnUUiU.wU69U~UU=UUFuUUUfU`U`3UHΞUM{9U^UMrU?U1H%U8eUTcTU=UPRT_UT.UUQU1U!U `U%UU'UwU=U&U?U4*U3UPjU[Ue[DUaEUk`USUUomUuuUu< Uj߫U EUbU8Uf UUqUnUU0UUUӮUw[U-HU>UV mVqVP7V-eUUVKhVVo#VZuVV|BVuVv|VgV"W9WWuXDX+W0W8eWmq!W&W3V:*VVVkVVyRV1%tVSV)+VF-V8VOr]V# VNwVOV#UUITVUDU"UUUyUψUUUrU& UU0+U PUURUU}UmUgh1UvMUv0U.pU[jU>t6UAUPjFUNTU:҈U?UCpU0WU/͇U(U1ZU7NU04nU%UT&UHT*TU\UGQT,UT@T+TTWTIT TQT˸TT``TuU U1UV%TTA[T߬TFTTU*TT2^T,TO1TT(TݮT?T|_TTJT?]Tr3TT6TڱT TT"\T}OT7dTT^TbTI?TTd~TfTwTTqT;TֳpTT T78TT]TU}UU8TNUTBU TT`UIU OHU CUU5U]TTbURU1/U UρUGU UsU6U TiUU%U$qU'U1WU%sU_U1+UYUKU\U5WUJxUTUIpUDU].Ui(UeTUuEUxUU)U1PUUuUU{3UUUG&UOU˰UL?UuU̐UhUU@UWVhVVtV֛VV+VRVV{v)VVVXV#5WW*K}VVWhW.)WdXLW0|WnV:Vr1VVvVWVj0V VMoV ]V VEVVRVV,UQUU͟V!UN}U UUcUăU UVUXUXU,UDUPU&UF)UUUUPUUUU|U$UUUUeUV}U`.USUIfIU_̣UfRUH`U53UA UBgU@U5U&4UyU_U+UZ܅UU(U UU!U U+U")U'UCUdUšU іU U ZU|TQT*TU'(TTTT"*TYUcU ĎU8UYU TnT-UUTUUZMU 9UB7URU lU U4PU TxUUU meU URTT0BU (U UxU TmUTTTT|UUTɁTT\TTzT T?T UlUT> TGT*Ul!TU GUwUyU)TTTdT!T՟TdTXTTԗT5TTۚTTTU TT U?UU5T*UUUTEU2U RgUUͲU$@UUQUUߕUU UUmUU \lU(VUU lAUU0U&ޝU,U9N@U(HUAGiU.BU?=U=YUZ UmxQUfULcmU^UYUE+Uq#UvUxFUzU}UGUSU3UHU`UUUUށUZUV؇UЀ!V 2 UfV:V=VV#RV`VoV$V5VYW(շV;W tX7|WC-#XW.AX X,X;ZeW:WW6{hVzVWg!PWCV0VVq+V-LV\ŬV)dV+VV^V!(tV0v8U,hUⴴVU+^U˷5U±,Uo\UuMUU UUU)T UTݮUuT TT^UIUUUjU U (\T6cU T!&TCTKU2MT[UUUTTCaTcUT?TT{Uf|TWUӗUU "U>UUU y\U *U UBTUR2U!UU|TPT"TT䛛TTcTsT^TUNU yU U lU#UabU.U'RUqU4pU1U3U'U#LU/;U,#gUAU+U&U=b;U4qU%U3bU%>UUѯU4U;<+UDyU0̄U+ U<U"7U%:!U@WU(U;19U?=U\ڐUNUFUA-PUNOUt]GUKUfkUU)UcQUVpU`\U3USU6U U׈U UUUU%RUߵVUVUU|V/V SUVK:V ~UV5xV4VV)VPVaVVBVr~WS!VTWϪX:`W)VXW>QWVWXW!WVVmVuVW VVdV_V:V&ZV;9UV!V.V4V-VZULU_UˍUUU҉EUUUkiU0U~UU UمU9UuUwUUgMUT.?Uq6Uh9UrUiEUZUL-{UYRULUFޯULB,UJUK4UUUHAU@[UPoU;UfUe>U)hU!UUEU UUEbU UU UUrUU UU vUhTT2U U USUtTKU6U vUSTuTPTTTDTTT4TrT⊱TBTgAU U -zUUETT4T~TOrTTU UU=]U\T@U~T}cVeAV5UH U3LULUE8Uc?yUI:UK4UbU*U`8U?UT@UvU/UcUxUpdUjUUOU*UU2U'UUcUȲU zU=qVs\V#VSUsVz@VAV|עVLV!ōVVEV2VcVz2W:V VLjWTNEW~A WWVIX OWW>uX7XbXXe#WԬV1V;WANW'PV.}VuVnV}VAmVq%VbdZVKV4ϖV4eV'V&V3rVvVP @V:V9V UCJUV [U僴UҹU3Uh USUUU[UOUwUI4UEjUWU~a4U|,U8UQUhnQUUrU^UjUjtU@{UHZBU-7U;1UYUFUPU7UGU>1WUUpU85 U.XU?UH+;UMIU9nU*PU?UjUFeUHWU,TU/U9ُUqUU۾U>UU!qUlUB TgTNUsUUU'.TqU$U<{U \jT)UU TU\U U5UkTݵTYU#U&U$U+QTtTxUU AU aU UTOUUȕT([TnTQUU0UtUf'UAU"TTǙTTiU0U.Ui7TGUITmwU+.U *mU ,UHlUsUTTbJT"TITĸTmT݌THT/TXT]T%TᇶTZTQTꟚUTUU U_U CUU 3U'U_U 6 UkT[UuU_UTزUUx[UUl2TU`UU!jU,]U<$U)U):=U$0UA UeU8)U5F_UGUQBUX&UHBUCzUS`UA;U_1Uq%U{6 UyLUhUYq+UTħUQ>UUkUU WUUU}UIUL'VEr;VApVHV"V V;V vUVܔVjVJ}UUyUUߐV}VyU߹U(UUUU;NUU$UU"XUyUhUPUyUrUjUU\U_,?U{UiUaNUw&|UfkUU\UpUVU\nOUGXUMKU8 U!bU!1vU4UB%U,U9U#DU U, U8zRU7 U+WUmUUƐU]UNU UUUMUUUUU U"=UU0VIVVZ+VVrVS?VံW#|CWWWX+Y4WAV̖XURxRU>U+U"U 5U&2U,UWU$>UMUsU"CU$UgUǸU"UG"UyU"UQUZUU qU`UU.U;Uv8U U _-UeU TU:UU F#U>U)U=UrUySUUyrU U±U+U UtTUhU Uw'TT#UUDU;UTeKT'^TThUTUTgUT8UUHTfT؇TT\UoTTbBT~TU-TZ^UT@TT]TEfUWUU#3UUWUU |UUUeU%T/UTRUoTUvTCTT՚TTUdU>*UU`U)5UU#:U,ݮULU@s UQ@U@LJU0mU,U/U(4UJU/=U63UhֳUE1UVU? BUX;U9-U\VVdV.VWEVWW V`&XXW֣WQWBWWRW16X wWz?W:HW"W}JV˲VVZ?VmVVGRVIVVjVfVVuVU6URUAeHU U:U%U#U9U)\U&U%|U/U&U!aU;U+Ud UbU)UZuU +/U /=UwU~U UUU B.U [}UnU ZU,U&U'UσUҲU!?vU U dUgUU WcWNWX(X#aW&U]U78U1U0/U:%UDbU&0U7 U5U+gU$U U/UCU4#DU#NU1U<IUGs2UFpU@5UFU8UUfDUJʚU7U?]UI;USUR,Ul7U\(U7WLWYY 8XWF*W1W=OFW$UVVz@VV-V;VSVVWVoWV9 V.8/V}%V ʢV$aV'U)VHDV3V DV UU-3UփVKÚAUȶUdU~%UFUiU=nUQU\U^TUq^UUaUUU:U/U UUǼ?UU|UU|U-UagU@7U@UzURUUyU|US UlxUgUb%U܎U[CUl>U\Ux8UXUTUvUnUlUbړUd Uu5IUEuULUFCU4U$U9!U}zU!vUU(/U(̈́U0BU#TULUU ZEU/rUCU MNUU5U;vUU$֥U:0UoU HU,AUHU.p|UU'yU'3UpU RU#UUCUtU.rU!WU)sUEșUWUFbU0U,U,ůU5U5U7SU/PU2"U4aU)U#gU,g4U*BOU3aCU9tU2U1aU UQUQ2{UXUEoU7cU*xUK/U:UAgUBUiUE:UfRUTlUfU@UaiU_U{cUKU uU|UvjU+UU_U TUUeUUqU fU UUeUUܹUÙ^UUxUٲ7V SVUV~VRVtVkY}VvVe)AVA=V+VVV/V`m VA$W%DW%W3%WuNVkVxWАXǨX)X8LWWXMPWX{cYئXX XW.W*HWd^W!ÚW'9VVe2V\VPVVVVVOxVOVDaV2C~V9άV*\V"3V}V SV}VV+ŹV(SV5|V V VgV U7UU U*jU" U.U>؎U/@U)ƭU2xPU/U1:YU6U)U!YgURU#UV)/V mVV#xU׀U 6VV%*U=mVV7V+CV V4V%NVU,+UU؁U˃U4UwU.U!UUU WUU2UU3UݟURU9U~UU/U'UUkW\UA}Ul[UUPt(U^UZpUF,UK0UBqULYUJ}U6UAUpU"U0RU#'U'3AU4zwU..nU'U U"U)IUzUUU{UU:3eUL:U,7UU ;U UUU+U UAUU!DU[U _UsU!LU'UxUUUU [U,õUIU(DU-U DUdUUcTfUU yU 9UtUNUUUJU%UXU#@uUU7U(U\U(U \U &U ?UU UU UbUk*UU{U.UOUBU-wU3M]U6 U?[U30U5MU3!U?U&1U/U#VUSU53U,"UK,3U8cU-5UAXU,@UB9U@U)USjUXUL UCvfUPoURUcDUXUxUJU{cUUaU:\U|UlUh?UlUUtAU#UUU`'UwUUURUUUUoYUFU4U̴US$UesUҞUUJUUвUK UMVV UBU ?U]UUU"UyV V")VNTUVJVlRVAVR+V VyVV W VV.yVϖWGWW\Wu4WYdXlVWʆW)WN;WW3WP`|W~wVVVCVV_yVW d]VZ/VEAVdVVVVV;| V>V~'V(h$VkUVnUVyVV UsU4Uڮ5U}UӈUcUUUUAU9UUoVlwU=cU٧,U@UUUƏU_UU/UiKU"U:UU:UpUnU~EU#UMiU$UvDU{UЎUUU#\UU?pUm-|Ui@UdsUSUE[UQ~UeUD{UQO!UN<UIy@UKyNU\OUR\U\MUReUPU>pU<U0L\U-*U;lUAkUW UQUM2UHG:UF#U-cU@a3U;|U,;U.%#U'CU6U3֙U:SU@U7U5)gUG\U$U3g{U('U~U%\V.KV#܀VVτV V%bV #IVa$VU`UUꬅUtVV/VUUVUhtU85UU~sU,UU/UUq?UUjtUUU.8UYU;U^Uo}U!UUUXU~RUUn0tUBUUbUkYuUU}U~CuU\U~8UfwUj`U}bUolUEU|UpېUdUlUgݿUg]UvUtUvUfU1UthUfUb&Us U|"Uy&UqUp :U`{U`gU{ UrYUY UH%~UQDU\UjUh UayUd#Ut%9U1jUsq]UQUFbU98URzU=~UMXU@MU\RUL$UiU@y UJBU\UJaUWjU7U1U) U' U;UGUMfOU59UU9(U9c0UO*U@U;EU5U@'?U,"U5}U%U-U7UgEU=UI"UCtU5U@U$[lU+I)UR(UAuUaULUUUj/U~9UUdlJUK.UeUr\UUJUpUo!UUXYUJ,UAU)[U&U$UdUUɃURUzEV VmVCUiVV V V!V\V @V1FV MVRrXV)V3V΅VeoVLV8\VVVVWVØW]W:}WVMVWWG(YXMvWTVW~vVVV㰚VVV\Vp1V4VVPV_rVH\VXO"VXWV _'V`!rV JVD V@VLVV1V*^eV [V1UUU$UyU^UUUSVUZUcnUVVV^VSVV IV V=V dV $VU;UcU7DUwUk&UiU˟U6UrUIUU:U1UU7XŬUUgUDzU U\UU%UWU^UUT-UiowU\ϭUHyUd=3UNlUT׌U^PUj^UvZUWrUX>UTUHpUpzU_"UZpUc>U`7U[UQy{UCfUHHUZ?zUw8UX'UT;Ud4UUTUQ U+ U? U:lUHU7qUSUElUJ1UTUx;Um}WUXUUZBU=&UhpUYUHU[SUUUUUhjUe*U^}UPUNUj6cUlUhU_OUJUatUGvTU\U\?=UTfU]YUm^UekUllUOUIUMUFIUJ^U4ZU*BU:RUS+U`UJsU2U'$U3U0UY^UF.>URqU`tUPlUo UiUpUo@UeUkZUsˊU}!UcUSBUCtU@hiU\U)-UaF3UOU3hU]U[U^zTUKxUhUj}jUPUUfU}\U3!U/U)U*UVUmU@VU/UU{UUΘUUU%bUUrUs/U=UTUPV U(U]tU1V V'UݵV|VVV$V0V$V_#V pVXVV2VgVV1W.eWVV!ZWRW/YXa^WGmXU(UQUmUX.UUUoU6U"UUi UJUxUvTUi]U U+UjU_xUYUjZUkU| UeIUqHU\tUbU|oUkU[ UW,U_U`bUioUw9`U^3pUC(UCU4UIbUMUYUXUa%UUUVUOUaUa 4UrUu;U(UCaU`7UCrFUIU^UAUJhU^ UjBUqt"UhUPGU\jU[UBUFUHgULJUTUGjU@WiUcyUhTUfUV?UHUUNUAuUECUEBU6UQkU=UFZU\M6UAUX=UE(bUBMU>UJAU=U@UCeU@JU^tUVLUFZU`9UDyU\UVU<9UG=U1U+UKU8[U@=U<UMr U4UZL UA=U:tU%U?7 UQUDNjUSJZU_UfEUyU} aUUUrUUUU_UwU&]U.UPUUŴUUhU UqUdUUyUBU=U6UWrUUOyU]U]U0U'U7UU*UܱhUE~U.[U+VUhU UUQUשURwUdVUbV"VUVQV#V:V&0 V&/|VQ:VoV2 .Vm~VCV`mV]bV V]hVJVW+W W"WiWNX9ǙWVYWfW,.WWw]VTVcwVǤVVì"VVXDVWK[V.MVcVHV'V&V#CVJŇVsxVEYVVVxAV`V75V4EV/"!U!ZVVcUUBUуU⟡VkUֶUsUJUUNUv UUvUBUU݁UMU`pU"UϐUCU}UUoU1UwUn\RUU0U|UUnqUHUh U*U\(U`rUxUS_UnUQUMCUhP+U\s2U]HUUNUI1UUMUYUI#hUEɰUXU=GUMU#LUFU@eU>UE U@#U9RUZUB U]~U])UcUcUA;U7AqU>U=UI[U>%:UhV5V ٵV$UV7UچUUU2UUU U"UƞU9VMTUҟ U'UU+kUU$FUHDUVfVYUiVUFVUU[jUd?U'UGUUU(*UU^UCUU\UU"UzUUv?Uw"U~UvUCU~UvUieUtUPVU_n!UWvUSOUG^QUgmUMUKUY&UTjUK8URUYUW߈U]UmhPUj^UOUqUA2]U<ܨUVUZU+hyU- UURUfUoUbUU5UUUV Uk9VovV :V{3UrVV"V([V nVGmVPVV8VwVHqEV:VkVcVyV]yVL.5VZ4Vގ>VMVhbVCVRV)W6UW0W@RWޝWzWMlW6 WW)XXrX3WR{X.XWX:cWr(WHW$WV͗VW)^WWbuWWaVVVFVlVuyVc+VVVPVzV$V(zV9V1bVhVgVjGVvsVDBV%j(VG^VT\VKV6VUEUçULUB>U5U&UŷU QUAU U0U}U?VdzUQ U&OUـU#V sUGUU-oU賕U>UcUpUbUFUUWU='UUZU/UrwUU UUU0UU`UUU]UUU[UKU GU+UU%UfUU~nUlU-jU=cULmUcURUU Ux5UfU U<UiqUUUwUUUHUmGUUnCJU:U{UtTUUtU2UUH\UfU1jUiwUUCUlUZMUuTUHLUhvUU$UZMUxEUqWUS%GUZU4UAU? UNUoߋUeUUx(UUhUU\UUhUK UfUEU bUUUqPUfUUo4UtUvUTBUyUUUUc{wUbUFUUuwU_vUgU UUU/OUؘUUٞUUOU)U USU%U!UHU*U9UFU{U.*UЩwUU[U =U6U'U2UUUUUUUUU[TUU:Um U RU|U6UwULU)U3U8UyUֹUTJUmUcUxUrRUh˵UxjwUyU}gU(NUz8UqUU2XU5Ud>UUUΠU]UUzU]UNdUAUa5UUq\UUU+JU U;UUUs_Ug[UppUeOU8UU6U U}UtU2QUU{%>UxfUT8UdʏUbxgUUwUbUodU^&Uh0UtUk!U\UPUM :UJ UejJUu.U`FdUU"UUwUrUh_UJU[Uz ?UDU@`UW/U.U>UU}Q|Uo!U_UKUsUߨUUU*U+OUUUpqUUācUWwUïU U8UZU&GVjV lVVUUˍVU U}UsUVծU-UlHUUxuUUnzUSZUoeUʓUpUGU0U7%ULUUJUU~.UUzU)UHUUUUf5U[Uf U|UsUz}UUu!Ut)UA UDU=(U_U/ UU^UjUWU`PUoUe6(Ub SU{Uc>UUUUUcUpywUSMUj?UUtT~UeUUHUXUL4UUd+UUTUX;UaߥUnhRUctUm"U]U}QUvUbUhLU]xUU_*ULUKU]EUsTUqU:UDUUCUqUY[UUUbUU*U]UUUlUUAvUnUbUhUU UUxPUqU=Uآ0UŰU%U>ULUEU-UlU6UUUVV jV5V"U@VVV {VUUV*QVR!VR=fV@?VB0VMV3DV.VVV9W4VVPVmWVFCVTVs@-VtDVKVLV[UVxUUV{V)U.gUGU%U UVUrU#UVkeURU@VWVcUJV V!U'U堈UUsUPU4UhUkGU^BUW^UXUs HUV_vUP&U|5U0Uu UUUUOUbUsUUWUUUU$UUqUWU]U'UUeUyUՆUq U_|UBU]cUQU'NUhqUUѝUUTU UUǀU@DUVLUPVvVU UxUU U@UچV~UUwV3V OV$V?YVDyVo"V_ fV@vVmaVR-VGVG?V=VVGV UViVIZVsJVVDV%jVVxtW}VAWWp1WWXWX):W2'WsrX`WʥWaVY:5!XqdX|XnX W$W鞦XSWbXH]WܾW%W"XWXWܼWWGWWMW;WW W`W:VepV{WW.YVX6V._V#WiVVŚVºV$VuV RVըV&VVIsVV[VtߞV?\VىV]$V0BV0"VV8V402V?vUߥmUWUVU oU̶VBUUUyUҐV UNU,SVU}UUUUYU݋U99UYUʎUhUU߄UmUUUh-U^UBU4U[EUfUUUU {UnUcU)UU~#VU\NUnUW1UUUDUUnU>UUU\UUfU:>U[bU *UUSUUUU:UqUUjsDUU\UI&TUnRU/U#DU1VUsU#U[MUq|UfUq >UmMUuU UUoUHUU݌Up1Ux7UuUiUu4UUUUUUUQdUOU =UfU7Ue?JUU~bUNU[UUUVUIU@UMU&UϹUHUºUU7VU$EV|pUbU+U3.USUUU3U앗VV UUVVKf@ViHVhVSVR!V|V,VV,VHtVnV!V\V_RV=)V[ VVW VWV{W WDlW{]X$XWD^mX!4'W|Y4X)WW-W%X;NXYksWLdW"Y&WGcWIbVxQVV2V%V%BU0UVɮU5VF(U8wUNVXUV RUYwUljUqUVbUU'3UUdU,qUyUU UWUUUU`UFUUJUyU UUnUUcU8)UU>UUU|U6UUNUOUUkU[U3U޿U¢2UKUUUcUTU:UUUBU=U33U2UxU#UUWyUU UpUc:U?U|UQUwsU U5U0UthUUUU'UmUʁUUU|U[EUUCU9U^$UfUKUrU~UuU47UxpUUUxUWU,UdV*UւSUU8?U7UoUUUF U_hU&V;U:Uָ#UiQUӏU&UxU=UdUU{3U UU=UmVżV=.Vo\U޳VUZUAVGV V15V f}VV6DVVGUUV2V $VwV$V>V_;&Vc&CVY"VܧVVqVWV:hVhV|cVؘWKGW_WlGW, V՚JVWk?W[WoWaNWP\BX$RXX+/bX=VҢW WWW_WTT&VhWQVԩVىW#dXVVVV`2VdV VVTV0VVV&VWVBݐVt-VOVAVhV0٧V#nV>VLVEV UyU V /V*#\V(VuV VR3VY~V3V VŅUVBV<ƥUU#UԕUeUȣU#XUbxUoUUhAUUUŤUUU"UܜUOXUU`U֊Uj9VumU޿UsUnUnU'U;U1UUCUUUUEUڝUUU:UWU4UmUUUĖUkGU+UrUU!2U]ULrUهU>UU=U UaUU_UUUUMUUU+U. U*UjQU_UiFURUUA:UYU &UجU^UUlU'Ug%UlU7zUMU%UUUUVsdU6EUdtUUcvU.UUUUUBUU,UUxU@UTU)UάU9Ux`UU}UIUUUuUִU GUUډU#UcU-UiU`UU,oU U7U&U2UJrUU=bUU1FU-UU}U$U3#UZVrbV7+V2$V!V7#VVVV#V9ĐVAV(WV;&VEaVVVmU^VWV<VfiVMV)V@)VHXVVRVRVeVwVhVsW V`WiW?VWW}WW(W1UW 9WWSDWuX9XRƟWuWQXVK%YFRW?>VWm@Wy WWweWIVGcW W0WA&V7Vl1VpkVWV2VVVwnWVj|V)Vw_Vh_VgWV7VdVVx^gVVE*Vx{VdGVA8VrVdVtRVTV2=CV5StVAVa8V@2V",bVlVV;:[V0*VAU7VUVlUGNUvrU4UU8U.UuUzUUK^UKUkUUhUPUUUQeoUttUgKU]UU#UUU} UO'UMUUUU=UUmU "U/U3UHUuLUgUKUW2UNUBUUpU#UdUwUU:UBUU.UxU½~Uk:UǽUUUUxU]UUvUQUOUzAUjU+U^UQUfU Ua|UsU,UUUU^UUPU #UaUoUUyBUQUUU]U4UUU3UUsUΙUU{DUcU oUVyU;UU!U&U UUقU!U U͜V%UfsUVU4U֭{U)?UUqUUUwUأV VVK6lVV@1V;VCq@V"YV3yV3zV0VFV+Vvx&V6TVɋVsVZVGV-FVtV]V*:V>J.V*V -V\TVVV1V{VVrVZVWVV'wWWGWkKW1W5WFWHW(YQWWZ'WJ*XWcXWAW @WWHlWWMWV&WW.W]VαW:VVVWiV7V0VV0`VVUV95VYVjV'iV<ViVLVgVE VQV+VVc)VyVg5VnFV}"VzIVAcVFVRV9@VMQV'GV[n V`yVlVDV@kV6rV:VH>VDV:.VVaW^VDV[U\UkU-UUU܌UWJUjU1UU'U_URUUUnUVUӀUU^NU"UNU)UbU'UUUֶUUyeU)U UnU1UCUzX3U-U]UUUe^U UUUUhU2UUhUOUgUtU'.U !U$UU݌UU^qUkUUdUUۨUF]U/USU UUU6U~p UUzlUU UgUU@U]PUU`U(US>UZU+UUeU«Uf UғUUUtUUw UQUUWU[U԰U4UYUϱsU;U UU\U?UBUU?U?UpUfUVXV"*VV)2kV%V}UٮUV$vV"V=V!V VV%HV V tUVyU7&UV=V#(V#oV>iV}DV72Vr̮V/WV/ȨVVRVVzV|ٱVwِV_VyVHK\V'V1VrV/V OVe)VEIV8fVs&V߼V|V:GVI]W>WoWtWrNcW;;XzKW+WXWNX!XRRY9WXRqXmX4MXX:W$XXrW\WpWWWWWW9W͖^W<ɲW[XkWrQSWDWWkWLWIYW oW:W=ԸWRuW>V$V-V01V@UHV%V(VpUOV(V sUfVeV5V2 V KVT=V6zV"qVUVV~V%VV4rV2V)UXUUhJUxUGU5UU;*UٺU UU+U:|UXUnUhU*UƓUcUUU mU\UUŕUCUHU|ULdUU:UƗUSUUmmUAUUUUŅU6EU.UrUIU_U^UUAUUUwUUwUz;UUUtsDUuUUU!LU$U"UşOU1aUhUWU/UlUUeUۤUUUCUUGU@3UU[UD8UUvUU UPUϪ-ULvV (V\U0.U^/V0UUUUfV#YVIVCV9VБV-Vt'V U2UϸDUѲUFV yVfV7V"@VC Vu VdVVpq;VV5sVV\V'VVΞ)V~V_V@WW@WdVcVEWWGMWծWI WW¨fW&|WժXB WjgYYUWXQWį|WڶX,#XmX6Wu|{X7LWXX X=W*`8WDtWBRWW_?WGWtW mWhWDVkVq-VVeVYvV Vp3VA9VE(V@Q VVUVOyU1VHIV YUU UVyVUV0EVdVQVyVV%V'xVV ݶV Y5VI$VVV{VUU"rUuU0jUyU˭U QUU+UUV PV zVV-V%V6UUU`pUZU UU'[U!U|V LUVqUCUUzUUU8UӓV5VU UDUVU>UU1U4UK,UoUήU͑UɭUwUUUѕHU!UUhU}AUxU7UgUʡUV U3UݐiVm5V VU4U٣UӴUU V|V U҆GU6V MVU]UēUU(UUU9sUQU8V ֦Vu1V6V"=VVVyXUV_VV0"V+'V4V&?VeV&V2jV $0V|V kUtOV$VͥVEV_V쓛W܍VYVW*V8!V4iVWV͇VZUVVKzV%FVVxfVVV VV( V{aVVVSVbV@VyUmV_VwV!V tV,.V]VVLV}V){'V;V'VE@V*QVKVJ&V7GV!5V?MV.CVKV*36V^V[8UCQVltU;UbiUUUQ/VUU#V.V V+VVUUίUUrU8UȊU۵+UD@V V UU8VUhUUU\V0UU,UUUXU)VU.UtUU]UUU }U1UgUqUʤUXUUGGUU@U UUcUU‰@U*U UUeUVS@UVYVjUcVwU*UrVfV{V TV ^!UOUBVU~U'VUսUVVcVVNV+VJ>GV> +V/FVIVVV2 UV@VbVnGMV|(VTVTV9ԏVRkV5xV;_EVxIV8V@V,c(VO+VVgVOPVVVvVqVVEVRVV=VVSWE9VWWSuW#*W}+ WWTWGs%WPW WO5OWiWWeWmnWfX+ WWXYۓX[X>W@VWW(X >aW`W1V!WJZWWW0WMWWA:W;dW@}W2V*VDV̔W+iWVuWV0}W 3MW WWHWWWriWV4V.TW]4V3V]V=pW:lV.V3VtoV&WV[eVt@V˟mVWeVʒVVVVvVkV=VSVKVV\VvVOV`6V$_VVYVwVeV7%VVP4VQ*VRxVV !V#V0VrV+jV[5V'r6V-lV4OVDV|F*VMTVQ VDVKTV?bV:VaVIaVB?V?5V&dV9VV/EV VXVyU UvU aUƤV UrVSGVV|V,[V8VB,VDqV oVIUzUIzU߬2U3UqUUiURV) VcUU U%UUҸ(UXUޜUVmUVU7xUUVUv2UlU^U4UgGUVUW_}WJV yW e\W3W$HW7fWFVGV͟WWIW2RWy;W WV;WVWVcV VݡV4VVӍVEV+V,VcVaV}V;V?VVaV#VVSV؜CVYVRVVCVVīVVVjTV6V[VV"VruVrV>!VnMV)VPAVV'VeHV=V%z0V(VNV#VVM2V&V hV$sV<ɢV"V-OVGV.uVbbV8VCMOVCWVw3V-VqLJVkAaVSVǔVaMVK V?a V`@VPVFV7VVV:VAVVVVnV~V@V.#VVhWg?W0Xy0WTWX Y)X+XY$XXFWY\n>XX[EXW;!X ًXe]YWkX3W XpXWuWWW:8W ]Wt@Wr#W7WWn"Wu"W WP[W9WєW" WJ>WtzWSzW!v9WaoWzBW6g%W\Ww/V7W8UW1WWkWG WV%VVWVW'WVVVV>VW>VRVyVԑVVIVXVVًXVVY}V|gVV3 VrsVY`VKVvYVN;VWVdVVV%%V5pVFv6VUV9lVV+"DV?SVV0gVV.V_V<VV^VHVF՘V7VPV.V'V8VE{V9V!V&V>AV1VIV'>V%VmUUUoVV+V#VFqVYV*V*VoBV=pV.V&:VUUe UWU&UBxV&V&UcU V wUzUaUUs\UxU㢊U=V UU"0U-VUUU"IU탓UUU(wUVQV% VgU켍UU\CU+"UDOUUPUVJXVV&pV:IV8VK?VN\VM{gV`VJ_VV,_VayV\, VDVaVyXViZVn1VHmVH>,VI#V]V VGVd1VgĝV[VVWV̧V#W &VV'VCVV>WtV Wp8kX 4WpuWvW-W~W`WʧXf%XXXX"YXTnXX&IW8XX>Xʋ=XEuX$1Y6X=XaOXFXg.IXWFxW-W߈X<X%EW {WW W`W1WxWWyWWȬWF@WRE(WVW^W>aWOWsdWHWNW"W9^W;WKW:SWOyW!,W47W5/W- wW&JW(SWiWU uW L^W*WLbW=EjW/W=qW WV-0V`WFW{W4(hVVjV&V LW _WW!JV[VVƊV^V`kV۹uVOV暺W &VVܮWLV VVVvVHV{Vz~V4V-7VO)VOVבV~;V WV3VvQVVV!VSVHV8V'CV0>V8VuVVM VZV0[VG:VkVXV{Vf V9liVP~V7nV&V0V'@VCSVV]SVlCV(DVVV/V V]PV pVV2V.nV'6V})VFHVCEV_VzsVYVmLV(~VLV EV&2UߨV VV2}V0eVmZUJUxUUoUAUUx>VZV<2V-8V,V9OV%8V,VJbVF\VfV@V#5V,21VakV[VT/Ve$V[*-VVVVVKVV@qV-jV$VT,FVhܲVuVͨ VVy*V`VPW0M=W V9WWVyW,~VSxV`_VxWVW+VV:VV9WV+3V/VW7@W{WVV"jVێWVh*VKVqJVZ=DVVVlQcVV V VΊVNAV1V7'VQVhgVIVx \VfV*VN V V MVWVwV5?V(fV@aVw(V-VZ3VrdZVVQVP5Vn{VZVO.AV4vVL&V%Vb`Va!V'uV+_V6vVM/V)rUGVUVU)V'#XV$`VCrVVGVcVVHHV?kVhVJVfC3VhV4VRVb~VBImVk5VtIV')V@VXVESVl&V5%VAhVO5(V@VV\^VV)V)0VnVVvVVƛVKVɷVHV닶VW9%WWvV.9VoeVŁVVV]V W@WWWHWW8&|WW5-WWW1WXX9X_gW|8W93XM X9 WWWAXq(3WX!X~ X"X\Wd+V/X#xW5XTWPWRWIWWWWP3WI W|eWKWt @WI7WBWxWWyW\WBPW8 ViW=W QW'Y(W:tVWPVDVvVpV͞W IW] W {VKVhV6VVp3WNW 5%VIVVBVEV5VRV߯WHCV (V6pVJW8V8VpVPVЋVOVRV`VVTV`%VVVpVIVVnMVwVRV V~V2VRVVsV;VVW- VqV.)VDV8VzV3Vu$VVVԧVVVwWVEV0V}V4(VBuV3V@gV9yV2wVCVVLVMV"FVpViV7qVÈVVPVnVYVY/VrmVZV4VRVQCVwrV[VXpV)CuV.%V]!7V8^V5 VjKVV:V|?VYVWV+VJVVgcV+MVVVk VB]VRV3JV~_Vb`V^Vyw#VHV1CVFV]F'VpV;ƸVVrOVVV:VtCVDVV5VVi^#VXVƀKV|VWdVoVVV_aVVfV1oVD:VRVtV5V̗V8VZ~Vы!VWPVcVpCVrWVkVʢWWqW1!W1 WtWHVWHW/V.W VV#W]eWJAWcWyWW{WOYirX${Y YDUX;ZjBWXXgLX3XCWAWzWnWV)W*Wd#WNUWZW@ZWWV9V語WjWkٕWMWUW?W)W.#_W,ĹV҇V"W \VuW W]#VN W 0W vVV- VqCV aVmVVGWDVVfV'W/VKVuVYVV YVφyVVVW V(W!VNVҚVLVvSV;V VܩVsVWVgW_Vk"VT,WRVwVJ'VP#V}VrVVBV9VVFVϖVCrV侐VڊVVVVrVVVV9VVV{V +VzEVV4VNVV.V8 V0VwZV\}kVhVf@VJW'_W4W/؞WZW ;VW tkW0ɥW(VQ7V\VTW V:VVV#V5VWpVV9XWN6WW"JWJVPW_W76W.W+̱W V VɼVBVVkn$VkV\VOtV\mV\VVSVV?@VnWsWuW%WwWVsVV{VvV7jVVVVhV9V%7VxbVbwyVNW_VV^W"WW)(W $V~V#VWOWWLWWAX EW`p7Wf&X#xW6ܬWVW2WUWrWZ>WDW_W9!WaBW>2W5WtWeVWoTW;~W=rWWkW zWmWaW@!3W~WmHW}W 0WWZWKW!WnW 4WCW_lWWWW``WusW^&WCW[FWkWtwWZWfXW W-jWWt(W(WkVV^V|wVgV2VV;'VLV6VVVuW)WAV oWVW)W=VٌW V@V9VFVHVazV8VVG)VmgoVdVTiVVrjVV5tVVzW)+W-WWWƠX7XKX1`W}AW. W?(WVԵ VVlOV5?VqVV 3VNVVxaVubVBVVsV?WxVW 0HWn~VW!WgVVJVtWyWdmWbVOV#W!WۿVȱV'VVRWWuWW+W)W; WYW}WW%5WYWWW XXXhRWLWq;WQWnYzXYszXXvYyXwX3X LY:WWWmX1/WlX\MWiWvWȀWqXX>bXsy.Wm WjWr?WWWT-WgPJWQB3W%"WWW`BW WWWaW/WW)5W*XkW:FPW WWwW+oWnWLiWuWWsW|WHWWzWׁW W(aWYgWWWpWEWAW-XfmW{WOqWX3;WWϦMWǿYXW~nWW~WŒ6W8X"WWv|WS{W W۠WY-"W WX9WׅWCX !%XaQWaWWr WYW5WQWzW!WXWyWmo W/X+jX \X wW]WXAX WWFgWXxWX'p]XnXnX?,X tXOWϴW`W*V?VVVzV~VVZ>VVKW8 W@XqW"XJ XW4W^DWDW϶W VVV V6VdVVtZ?V,VVUSVqVK Vz WO~VT WWMcXXQ XD}X)MYmS%XQXHXF5WHZVLW\>W*lW0VrSWRVrVX gWWW>X/GXq2X$ӛW|X1ӸYW*^Y YEXW/X WWO%VuVVV8eVʤV>6VVWXWZWkGWPX XX訌XZWGW~W60fW)ִVtV)VtFVHVwVzV(V.VVgyVoXEXVX4XW+X? WWҟW=oWMWsWVW!WxWH=VVVVVVȁ W3W W'oW?-WH~WVW$Wh0W%<WVuPWyWdW0WJ?W1VV]W AW5/WIW/ VIXgXEXMWEFX܋WdX5XcWaXֳY7YDXSWlW5W7kWǷWoVVUVy|KVVJvWWWWzcXXtzY XMXlW|WWIKWVȄVVRVV&W/VEVonVCOVV` V$VV HVpWdFW&WX0>YjXc%XHDUWIYV_V~VBVmV%W#7W W WYWW}VFFW4bWPWV7WiWcXW̉WOLWGWW'WWWWA\SVWXXV!YuXe ?WH6WgWIV ]VVVV4xVW~Wl9WN!WXYXBY]OWQLWoIHWWg{]WV]&V,W kVRW+VWWΰWq/WWXwXN/W X.XW@kX/W6X5zYYQxXNWO0XVSVOW)V?V$V^V|-V>W,dWjWcX8#X)nX=zXmlXCW2>WW=^VV `VPW W VVVY}VLVV>VTVWOrWGXRW;YW~WW(WVWiWW&;W WMi$W2VtbV\3W=BW#WhWWPTXYIXXs*XDJY'WWXt|XXW W=V(VsVjV&V3 VJV8W܋WXgDXWSfW|UXW?(WW WUWVʦcViW>WbV~VͿ*VY V %V$VXW6VW!KvW_X6W*XqX#XVrXvXWiWWwtWKWdWG_W /W>1ZW5LXYX(X XBR2XWXWdW=WVVДVV՛V0WWNWXMY|#Z XW YVXLW5W=W!1WWmWV7W$wW#W5V7V lV<W 2WQW,OWuWj>X)nWUXtWۊW#XHX6X^X q8X4$XRJpX9jWM5KW&X 3X.XdXtYXaWWWW?SV)VVmVVWVWawW|WW䬖WWpW WNWiWtW5W.P-WTV?W lVVLWEW!QW}(XX+-?XWWɉV2VaeVvV1VŸfW%WxYXYfX;zW8WFW}WA*VCWD V"W[WsVW5-VVؕ"WWѲWڂX96'%3@K$-.$  (& &          %    !   ,)3'$,&&# (&"- !!'!$)0&(* *&#,' % )#  "#                       ) !" "$* $$''"  ' ,,)&                         #     #  &$  /"! "# "'  -(( !  "-              % * (+ $&".,"#!)' !) $&!#("* #*!**!     *       ! !  '7 ! !( '0+&.+$  -0 "  !   #*$0"&!!),0'#'1.'%#&%0& '"!!              "()2- 1#)!"&'$ %" .%14!$04=7)%7/:, '$(1-)$56,'"&%& %%/ (  %  %*)" ! ,           + #! &#& + * * !)- ($'!'3!*-&+&+$'/+,&+ ')#$$"$!(" '(              $ *%&! !# "#  ,!%$#!+(&#"&"$'$##%%%!#%!$'"  "     /'        !  &&%&'D!#)$#1$"   ( /,#!" $*%%-4*3 $) '/,$7&"'!&:6/047.+*/)0(%"&$ '#             % "!#)** (!%%  (0 (*/9$(!4#$1"!'*% !-)(()"!863% '$0"$+ 9' ).#+ *;2+%/E40!#& #3$  &83           "!&  +! 4($&  %!" $ !' -9&0",.#"(,"2,=6+#!&$6%1*44!)&!!$&7"+&#%(#)2#* %&$?            "#0   ( ,-)#!  2.* #"$!$" /"%+ !#   !  #$ A             "     !"   $5  %' *$.,#!9!  "        1         " "5": !E!& ,#&%& $('   & 7#''/+&1,"'$. !5/0"&%,0>A;( )*-!$.')!#+"   #           %    "!  & (P3+!,* ! %!,.9(.%*&!&21$'3"#!(  "&()"%7$-:@;*,)!#6N6=(#0/3-# *%#7 ("%8#% 24K9%           " '     32($     #" !2*$'-1=!,B'$C/%'$1%"%9*!+%*+"%-#4$%%%($%5%$(                              #   # %)! $+*0+&2%# * .(&#2(((#+                  (      #.$ (  #""!!"#*&##,   $-$    &#           $  !& - !-"$"!+%0  "&" #  "3()%.""!3#" +)1%!!%&)!%#%1!(,274)+  5                &!9% !*%#'!!"&0%-%#&$ %  !#%* .$'!5.$'#$/DC!5>8 !72*#!$ $                %$"*%(   +6+*8  " % + ) +"%" '',$! !   &% #      "        "     #'(+-89;   #%!.!*( ,-  #&8@7 ! !2)!+4/%0'! "! +!" $!   "    <             %-4:7. 1"# '3!'     *  %$",0#"&+)! $  #$.$.#!&           4   '"#%$" ,. #+'(* %#14.$",)##&&7101/*!"',&%#! ! 8,15(/&$'*!,,.<*'+#  $!#/+(                   "%!16 )$) + ($6 +12.'!,2%1 -# $)" &'0+11&( 3  !.$#&)'.$51"'#J!*                     ;-(.2 #-&3& "!%#2+"  &:(.+R(!%'"!$!("#.$.%!*,,   $ !2-$#& #                           '* !)+/3+ +$%%61+AD0-204",+! !'"#!4CG*"#/-,#/(#2!):%/.)"&#'!$6?GE*AB4(    !3@               !   %     " $ *($   #?=!! !+$ ''!7'&46)3* ! )             ! %44#(% 3#'$ $- 0,17 ++)>)(-*07! (:5*$$6*-!#"'$ "!'":4,!!%+)                    &!/#$#!0(&+"(-,'$-'5)"-',+ % )-$01'"(())2),7 %/$ 7#%&.;3$9&#03#:1/*5% %<%*# #" (               ! '"# +'% !,) -""!$+3;(*',$) $!+(2,/(#3+ ((%"*)2E203$ )-<'                 H % % +*% ' % :("#$ /,(83"*,&5(!"&&4=5$+&  ! /! !+*  #,#                '        #       %     "="'.! ".$&(!!"  '               4%   '# "!) &  "")&"##3,")"$+%#  ( &""#($!$$3)!'*$-('2<# ('%&)+*! &              +%'6?1 )04(%$/1'$)%+-.**,)-.+/ "$(B"3&8*.( #(13756/'$ "  !-#!6 )"$*$!34 $$               %#(!&( &&1(05$3/$,;0#+% "> '0$ *-#"C* "<A;-: R 2  T!$&  %1;:%!$%!' $#)%"                       !! ! ++#$/!% #%!  (*(&S (%+!!.(")1.)2   !%' %9E        4  "          %$ #(%%V|",,!.'"+/ $"" "          !%8   %      $      04' %,*% )(   ##                !       # $!)*"-!3,"*()'!.'$2+*2()&'+#,'7()*$ '*+L%$%$ )4!           ,       % $ #   "% 0#$")/+)-, $'2+# %"( $.(*-)- /*&&%,?.)(+" 5 W #- %C?+"'*%&                          ' )$/, $!#/&"$,52(FK  z 754(-+ +7+C2),!"*-(,)/($/$&               !          %" # !,'-*  P(#)((& ,+ 93$ /)+""(    ' ,(!               -! -&$$"%  &#*#"%'  ,!'&""!&')*))(( %#%#+    "   " 6    #)'"%.&"$%&/21)!' !#$#)%00#2/99061,82+*874.$)/,%& (  !"!*/ .#-/*($#*2$(-,'&! -                   04  +)(&! );.)%!&'55.44'..&4'&23!# +*#/&'+(. ! "'' + "&(&!&               7   $% ! %!  %-)*03)0)!3'!$! )&+ 7)+.-"+.5$"!($(1( &       !   %              "$ %  ")=! +1$0! +$"#)!(& "-8$#90,%"044%&8=I3 '& %)0%'"                %/$#5*-$##!*)2"#*2)%#' (#   1877DC4%11!$&(%#-# '"     &     "             .$"&3- %&#*!"&"#)#"'!(0.7.()'6/8"%*3;1.,$3%76(,/($&7?)&( >4)(  %  *))" #                     #  && 4 (" ' &! ""+'%+%""' (.( &"" $"&# " $             !    (  " .2 & #2("#'/%@. ,"'#(,@O3%&2*$!)+    '                      &+    # * &&'&!#12 #.-%#"5';&&%%1& "" #''            +%',#) '&,&(!', " "$! ( %  ##."$$$#).%'  )! $             #$%($5'!#('%)+ 2%#$""/2$%!-H)%*!%+ -$ #($!   %  +#                  (* "    '+-' %  )6.' * "!**,!#0## !!"' #+  #   $         !     !  ,1+/% 1##! 7.# C'# 3 -()("-.()#.%('")"&1"(#)$".3+&%   "    !#              !     '(:- ! -5111 /:.4$ & "/,  #C!  #$$     (           #&"/%# !'%  **)%,;92."3$#)#))"! #  # /'74!++$  #                !!#@22*',,-3"!#,+3-. (&+/*$%'!&%'>+"3/>846+$%"#4$%,!(*  %#& %                   #% 0,( ##';* #%4#1* !!'-&'+$27/4-13-$+0)6,)8* " = (    "  "                   .!&&$    ,%%3&*+ +7-!3C5, 2-0)&!,*,$+"79%!((%#(1!&6*,#* # "                   !   (' $#)  $  !#  % !7-"!&('!.7A"!*B2 /P3!( 1+,. 1!)#(.$/"&( %           3#)$"  !&6&&1%'&/'%/1.#&+& '((3$',$#)#&#$ "6 /!-'&   "))               ""#3*1&&+$'%0+)"!*271'//#,7%'02& & +(62*$5)!#&!" -  $(  % "/3             (         !%+ ! $" ./+(?;*(!/% ,,#$--3(& "%"-.2"')%#*.+!."("4 #,,.           ,         #         '$/-/'  *$,#*#%""%*#,'38>-$ &%%1%")#    # )#?- "        #&  !$%  !#-.5A/,*'!! '& % /."-+6$*,1 .0$'%>4 "  .&   !&          :&   %G   **"&.4"$" # !"$).%/#'*+%+1+#! (#-,$0=+*+(-""& !+("*$ !  $        $!      &1:*&'1.. 56!$29(',&''/!$%'&GMZL2M>$'*0,!$-4063 /((")!  "%24$#'.                        '    1 6%#$# -@(FWI46?%,'4!#9/"#2+' (/1.5:)$-:;',(*+#-5)/)&*-#!!2$ # , -                   !(#3    2644:/ $ #   '&+" '" " ,$          & &%   /          &%1*!++'& (,"!/, '1GB77<0= *+)&10(,#"&(/<"%#0 ) $                 %# &  /400-61($! '%#/2D+:8+0++!% "'" # ' &                       $32((  3'2'*'*$%)$--"!',7,.##  %"    !)                    ,/++! 41!#  !#-;EED;73#"  '--&',.:2%. %8>66*#$#                       2,*5  +(#*#  !&.'=93*' ."548JW21)*(%)(&! $       % +" #               % 1# &")%*'/,9#  (+>)!/3@@0;. ,#%+'<1<<(),3) :=@)'6     &               '   !1.%0*#%%1$(*5%3:8:))&&<5260B>#*,*   &  !                    % (   "   !'9B'+.-A "/)+1&   "-,-5                           !  %5<<5I.#  %%"'+4:000%!  /2/F$("   $                       # #      *;0".& !$+ /3)  &-+ #$(5+4#$(                    "&+2?(#!*"'%#,!, /%! $*A;/62, "$/(!%"!")2B*#&.$%- ,) &+" #)  !    /           ' -#' (   -#'%(, ! &%%>>843$  )"6.,2+  :)  "  "              #   &'!%*   #-% '     $&       #                    $%)  # #)" &% !   ! &  !#           8         )    +!     "2/%"-.3  *($#"   '             =   % .        " ((&'&A. $ "!(2)04+,%   $.2%%'1 ! !!              F$      ( '!+/)*6I;*"*,) % %-3(#+ # !5"")*8*.    '  !              &   - .0,)  '!/7   !#                      &(G*'    +1%   *'"                       !1.,#!  +""' (#        ,  !     "')!()   (#)   (.& +                      ,   ".,42!(   #',)     !++(%                     #   "-0!)   *$03'   &                    %-')&))',    &"!   "+ !                  3        )"    *                         !'(     ")&       #%***   "$                     !#   %#"%!  +"          0         !      $!   "                             "   #   +&              ,  "         "                     #&          "! "$  "               #"+-/&                  #$                  +     "                                              (  "             "            "              "$         +  %                             $                "       XTENSION= 'IMAGE ' / IMAGE extension BITPIX = 16 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 280 / length of data axis 1 NAXIS2 = 210 / length of data axis 2 PCOUNT = 0 / required keyword; must = 0 GCOUNT = 1 / required keyword; must = 1 EXTNAME = 'zero ' / NAME OF CURRENT HDU DATE = '2008-09-26T21:32:28' / file creation date (YYYY-MM-DDThh:mm:ss UT) CRPIX1 = 160. / [px] TANGENT POINT X PIXEL CRPIX2 = 105. / [px] TANGENT POINT Y PIXEL CRVAL1 = 41.5791666666667 / [deg] RA AT TANGENT POINT CRVAL2 = -30.2747222222222 / [deg] DEC AT TANGENT POINT CTYPE1 = 'RA---TAN' / GNOMONIC PROJECTION CTYPE2 = 'DEC--TAN' / GNOMONIC PROJECTION RADECSYS= 'FK5 ' / REFERENCE CO-ORDINATE SYSTEM EQUINOX = 2000. / REFERENCE EQUINOX OF CO-ORDINATE SYSTEM LONGPOLE= 180. / PROJECTION NORTH POLE CDELT1 = -0.00277777777777778 / [deg/px] X AXIS INCREMENT CDELT2 = 0.00277777777777778 / [deg/px] Y AXIS INCREMENT CRUNIT1 = 'deg ' / UNIT OF X AXIS CRUNIT2 = 'deg ' / UNIT OF Y AXIS PC1_1 = 1. / X-X AXIS CO-ORDINATE TRANSFORMATION PC2_2 = 1. / Y-Y AXIS CO-ORDINATE TRANSFORMATION PC1_2 = -0. / X-Y AXIS CO-ORDINATE TRANSFORMATION PC2_1 = 0. / Y-X AXIS CO-ORDINATE TRANSFORMATION BSCALE = 1. / PIXEL VALUE GAIN BZERO = 0. / PIXEL VALUE OFFSET BUNIT = ' ' / UNIT OF PIXEL VALUE END XTENSION= 'IMAGE ' / IMAGE extension BITPIX = -32 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 280 / length of data axis 1 NAXIS2 = 210 / length of data axis 2 PCOUNT = 0 / required keyword; must = 0 GCOUNT = 1 / required keyword; must = 1 EXTNAME = 'naive ' / NAME OF CURRENT HDU DATE = '2008-09-26T21:31:54' / file creation date (YYYY-MM-DDThh:mm:ss UT) CRPIX1 = 160. / [px] TANGENT POINT X PIXEL CRPIX2 = 105. / [px] TANGENT POINT Y PIXEL CRVAL1 = 41.5791666666667 / [deg] RA AT TANGENT POINT CRVAL2 = -30.2747222222222 / [deg] DEC AT TANGENT POINT CTYPE1 = 'RA---TAN' / GNOMONIC PROJECTION CTYPE2 = 'DEC--TAN' / GNOMONIC PROJECTION RADECSYS= 'FK5 ' / REFERENCE CO-ORDINATE SYSTEM EQUINOX = 2000. / REFERENCE EQUINOX OF CO-ORDINATE SYSTEM LONGPOLE= 180. / PROJECTION NORTH POLE CDELT1 = -0.00277777777777778 / [deg/px] X AXIS INCREMENT CDELT2 = 0.00277777777777778 / [deg/px] Y AXIS INCREMENT CRUNIT1 = 'deg ' / UNIT OF X AXIS CRUNIT2 = 'deg ' / UNIT OF Y AXIS PC1_1 = 1. / X-X AXIS CO-ORDINATE TRANSFORMATION PC2_2 = 1. / Y-Y AXIS CO-ORDINATE TRANSFORMATION PC1_2 = -0. / X-Y AXIS CO-ORDINATE TRANSFORMATION PC2_1 = 0. / Y-X AXIS CO-ORDINATE TRANSFORMATION BSCALE = 1. / PIXEL VALUE GAIN BZERO = 0. / PIXEL VALUE OFFSET BUNIT = ' ' / UNIT OF PIXEL VALUE COMMENT ========================= COMMENT almagest: BLAST iterative mapmaker, v#644a14sd COMMENT almagest is copyright (C) 2005--2008 D. V. Wiebe COMMENT ITERATION 99 COMMENT SCALAR -7.62486649668157 COMMENT --==--==--==--==--==--==- COMMENT BLAST Data Use Statistics COMMENT Total Pointing Samples 314260 (52.29 minutes) COMMENT Flagged Pointing Samples 432 (0.137%) COMMENT Total Bolometer Samples 41796580 (4.83 bolometer-days) COMMENT Flagged Bolometer Samples 554770 (1.327%) COMMENT ------------------------- COMMENT NoDumpNoiseTODs COMMENT NoDumpTimeStreams COMMENT NoDumpSpecials COMMENT NoClear COMMENT DisableClipping COMMENT PadData COMMENT AutoReChunk 0 COMMENT BinCount 200 COMMENT BinningConstant 2 COMMENT NoCorrelatedNoise COMMENT CorrelationFrequency 0.001000000000000-0.010000000000000 COMMENT CalibSuffix _cp_21_mdt COMMENT DataHoard data.hoard_2006 COMMENT DirFile /mnt/blast06/ COMMENT NoDumpDeltaMaps COMMENT NoDumpNoise COMMENT DumpVarianceMaps COMMENT EquatorialCoords COMMENT FilterFloor 0.000010000000000 COMMENT FixedNoise 10 COMMENT FlagsVersion 10_CBN COMMENT GapFill yep COMMENT HardHighpass 0.000500000000000 COMMENT NoInputNoise COMMENT Iterations 100 COMMENT Lowpass COMMENT MaxFactor 2 COMMENT MapGeometry 280x210+160.000000000000000+105.000000000000000 COMMENT MemoryCheck COMMENT MemSize 2990492 COMMENT OutputName test502 COMMENT PixelSize 10 COMMENT PointingError [0-8] COMMENT PointingOffset 0 COMMENT PointingSolution %c_FK5_23_MV_20_CS COMMENT PolynomialOrder 4 COMMENT PostFactor 2730000 COMMENT PreFactor 3.66300366300366e-07 COMMENT SinglePrecision COMMENT FastRotate COMMENT SavePeriod 10 COMMENT SoftHighpass 0.033000000000000 COMMENT Suffix D_T04_F10_13_DVW COMMENT TangentPoint 2.771944444444444,-30.274722222222220 COMMENT UnifiedFITS COMMENT Unit MJy/sr COMMENT ClearZeroes COMMENT ZeroConstrain -900+^2-x161^2-y105 COMMENT -=-=-=-=-=-=-=-=-=-=-=-=- COMMENT Chunk: 500:0597655:109440 (0.100000000000000) COMMENT Chunk: 501:0597655:109440 (0.100000000000000) COMMENT Chunk: 502:0597655:109440 (0.100000000000000) COMMENT Chunk: 503:0597655:109440 (0.100000000000000) COMMENT Chunk: 504:0597655:109440 (0.100000000000000) COMMENT Chunk: 505:0597655:109440 (0.100000000000000) COMMENT Chunk: 506:0597655:109440 (0.100000000000000) COMMENT Chunk: 507:0597655:109440 (0.100000000000000) COMMENT Chunk: 508:0597655:109440 (0.100000000000000) COMMENT Chunk: 509:0597655:109440 (0.100000000000000) COMMENT Chunk: 511:0597655:109440 (0.100000000000000) COMMENT Chunk: 512:0597655:109440 (0.100000000000000) COMMENT Chunk: 513:0597655:109440 (0.100000000000000) COMMENT Chunk: 514:0597655:109440 (0.100000000000000) COMMENT Chunk: 515:0597655:109440 (0.100000000000000) COMMENT Chunk: 516:0597655:109440 (0.100000000000000) COMMENT Chunk: 517:0597655:109440 (0.100000000000000) COMMENT Chunk: 518:0597655:109440 (0.100000000000000) COMMENT Chunk: 519:0597655:109440 (0.100000000000000) COMMENT Chunk: 520:0597655:109440 (0.100000000000000) COMMENT Chunk: 521:0597655:109440 (0.100000000000000) COMMENT Chunk: 523:0597655:109440 (0.100000000000000) COMMENT Chunk: 601:0597655:109440 (0.100000000000000) COMMENT Chunk: 603:0597655:109440 (0.100000000000000) COMMENT Chunk: 604:0597655:109440 (0.100000000000000) COMMENT Chunk: 605:0597655:109440 (0.100000000000000) COMMENT Chunk: 606:0597655:109440 (0.100000000000000) COMMENT Chunk: 607:0597655:109440 (0.100000000000000) COMMENT Chunk: 608:0597655:109440 (0.100000000000000) COMMENT Chunk: 610:0597655:109440 (0.100000000000000) COMMENT Chunk: 611:0597655:109440 (0.100000000000000) COMMENT Chunk: 612:0597655:109440 (0.100000000000000) COMMENT Chunk: 613:0597655:109440 (0.100000000000000) COMMENT Chunk: 614:0597655:109440 (0.100000000000000) COMMENT Chunk: 615:0597655:109440 (0.100000000000000) COMMENT Chunk: 616:0597655:109440 (0.100000000000000) COMMENT Chunk: 617:0597655:109440 (0.100000000000000) COMMENT Chunk: 618:0597655:109440 (0.100000000000000) COMMENT Chunk: 619:0597655:109440 (0.100000000000000) COMMENT Chunk: 620:0597655:109440 (0.100000000000000) COMMENT Chunk: 621:0597655:109440 (0.100000000000000) COMMENT Chunk: 622:0597655:109440 (0.100000000000000) COMMENT Chunk: 623:0597655:109440 (0.100000000000000) COMMENT Chunk: 700:0597655:109440 (0.100000000000000) COMMENT Chunk: 701:0597655:109440 (0.100000000000000) COMMENT Chunk: 702:0597655:109440 (0.100000000000000) COMMENT Chunk: 703:0597655:109440 (0.100000000000000) COMMENT Chunk: 704:0597655:109440 (0.100000000000000) COMMENT Chunk: 705:0597655:109440 (0.100000000000000) COMMENT Chunk: 706:0597655:109440 (0.100000000000000) COMMENT Chunk: 707:0597655:109440 (0.100000000000000) COMMENT Chunk: 708:0597655:109440 (0.100000000000000) COMMENT Chunk: 709:0597655:109440 (0.100000000000000) COMMENT Chunk: 710:0597655:109440 (0.100000000000000) COMMENT Chunk: 711:0597655:109440 (0.100000000000000) COMMENT Chunk: 712:0597655:109440 (0.100000000000000) COMMENT Chunk: 713:0597655:109440 (0.100000000000000) COMMENT Chunk: 714:0597655:109440 (0.100000000000000) COMMENT Chunk: 715:0597655:109440 (0.100000000000000) COMMENT Chunk: 716:0597655:109440 (0.100000000000000) COMMENT Chunk: 717:0597655:109440 (0.100000000000000) COMMENT Chunk: 718:0597655:109440 (0.100000000000000) COMMENT Chunk: 719:0597655:109440 (0.100000000000000) COMMENT Chunk: 720:0597655:109440 (0.100000000000000) COMMENT Chunk: 721:0597655:109440 (0.100000000000000) COMMENT Chunk: 722:0597655:109440 (0.100000000000000) COMMENT Chunk: 723:0597655:109440 (0.100000000000000) COMMENT Chunk: 800:0597655:109440 (0.100000000000000) COMMENT Chunk: 801:0597655:109440 (0.100000000000000) COMMENT Chunk: 802:0597655:109440 (0.100000000000000) COMMENT Chunk: 803:0597655:109440 (0.100000000000000) COMMENT Chunk: 804:0597655:109440 (0.100000000000000) COMMENT Chunk: 805:0597655:109440 (0.100000000000000) COMMENT Chunk: 806:0597655:109440 (0.100000000000000) COMMENT Chunk: 807:0597655:109440 (0.100000000000000) COMMENT Chunk: 808:0597655:109440 (0.100000000000000) COMMENT Chunk: 809:0597655:109440 (0.100000000000000) COMMENT Chunk: 810:0597655:109440 (0.100000000000000) COMMENT Chunk: 811:0597655:109440 (0.100000000000000) COMMENT Chunk: 812:0597655:109440 (0.100000000000000) COMMENT Chunk: 813:0597655:109440 (0.100000000000000) COMMENT Chunk: 814:0597655:109440 (0.100000000000000) COMMENT Chunk: 815:0597655:109440 (0.100000000000000) COMMENT Chunk: 816:0597655:109440 (0.100000000000000) COMMENT Chunk: 817:0597655:109440 (0.100000000000000) COMMENT Chunk: 818:0597655:109440 (0.100000000000000) COMMENT Chunk: 819:0597655:109440 (0.100000000000000) COMMENT Chunk: 820:0597655:109440 (0.100000000000000) COMMENT Chunk: 822:0597655:109440 (0.100000000000000) COMMENT Chunk: 823:0597655:109440 (0.100000000000000) COMMENT Chunk: 900:0597655:109440 (0.100000000000000) COMMENT Chunk: 901:0597655:109440 (0.100000000000000) COMMENT Chunk: 903:0597655:109440 (0.100000000000000) COMMENT Chunk: 904:0597655:109440 (0.100000000000000) COMMENT Chunk: 905:0597655:109440 (0.100000000000000) COMMENT Chunk: 906:0597655:109440 (0.100000000000000) COMMENT Chunk: 908:0597655:109440 (0.100000000000000) COMMENT Chunk: 909:0597655:109440 (0.100000000000000) COMMENT Chunk: 910:0597655:109440 (0.100000000000000) COMMENT Chunk: 911:0597655:109440 (0.100000000000000) COMMENT Chunk: 912:0597655:109440 (0.100000000000000) COMMENT Chunk: 913:0597655:109440 (0.100000000000000) COMMENT Chunk: 914:0597655:109440 (0.100000000000000) COMMENT Chunk: 915:0597655:109440 (0.100000000000000) COMMENT Chunk: 916:0597655:109440 (0.100000000000000) COMMENT Chunk: 917:0597655:109440 (0.100000000000000) COMMENT Chunk: 918:0597655:109440 (0.100000000000000) COMMENT Chunk: 919:0597655:109440 (0.100000000000000) COMMENT Chunk: 920:0597655:109440 (0.100000000000000) COMMENT Chunk: 921:0597655:109440 (0.100000000000000) COMMENT Chunk: 922:0597655:109440 (0.100000000000000) COMMENT Chunk: 923:0597655:109440 (0.100000000000000) COMMENT Chunk: 1000:0597655:109440 (0.100000000000000) COMMENT Chunk: 1002:0597655:109440 (0.100000000000000) COMMENT Chunk: 1003:0597655:109440 (0.100000000000000) COMMENT Chunk: 1004:0597655:109440 (0.100000000000000) COMMENT Chunk: 1005:0597655:109440 (0.100000000000000) COMMENT Chunk: 1006:0597655:109440 (0.100000000000000) COMMENT Chunk: 1007:0597655:109440 (0.100000000000000) COMMENT Chunk: 1008:0597655:109440 (0.100000000000000) COMMENT Chunk: 1009:0597655:109440 (0.100000000000000) COMMENT Chunk: 1010:0597655:109440 (0.100000000000000) COMMENT Chunk: 1011:0597655:109440 (0.100000000000000) COMMENT Chunk: 1012:0597655:109440 (0.100000000000000) COMMENT Chunk: 1013:0597655:109440 (0.100000000000000) COMMENT Chunk: 1014:0597655:109440 (0.100000000000000) COMMENT Chunk: 1016:0597655:109440 (0.100000000000000) COMMENT Chunk: 1017:0597655:109440 (0.100000000000000) COMMENT Chunk: 1018:0597655:109440 (0.100000000000000) COMMENT Chunk: 1019:0597655:109440 (0.100000000000000) COMMENT Chunk: 1020:0597655:109440 (0.100000000000000) COMMENT Chunk: 1021:0597655:109440 (0.100000000000000) COMMENT Chunk: 1022:0597655:109440 (0.100000000000000) COMMENT Chunk: 500:0740348:204820 (0.100000000000000) COMMENT Chunk: 501:0740348:204820 (0.100000000000000) COMMENT Chunk: 502:0740348:204820 (0.100000000000000) COMMENT Chunk: 503:0740348:204820 (0.100000000000000) COMMENT Chunk: 504:0740348:204820 (0.100000000000000) COMMENT Chunk: 505:0740348:204820 (0.100000000000000) COMMENT Chunk: 506:0740348:204820 (0.100000000000000) COMMENT Chunk: 507:0740348:204820 (0.100000000000000) COMMENT Chunk: 508:0740348:204820 (0.100000000000000) COMMENT Chunk: 509:0740348:204820 (0.100000000000000) COMMENT Chunk: 511:0740348:204820 (0.100000000000000) COMMENT Chunk: 512:0740348:204820 (0.100000000000000) COMMENT Chunk: 513:0740348:204820 (0.100000000000000) COMMENT Chunk: 514:0740348:204820 (0.100000000000000) COMMENT Chunk: 515:0740348:204820 (0.100000000000000) COMMENT Chunk: 516:0740348:204820 (0.100000000000000) COMMENT Chunk: 517:0740348:204820 (0.100000000000000) COMMENT Chunk: 518:0740348:204820 (0.100000000000000) COMMENT Chunk: 519:0740348:204820 (0.100000000000000) COMMENT Chunk: 520:0740348:204820 (0.100000000000000) COMMENT Chunk: 521:0740348:204820 (0.100000000000000) COMMENT Chunk: 523:0740348:204820 (0.100000000000000) COMMENT Chunk: 601:0740348:204820 (0.100000000000000) COMMENT Chunk: 603:0740348:204820 (0.100000000000000) COMMENT Chunk: 604:0740348:204820 (0.100000000000000) COMMENT Chunk: 605:0740348:204820 (0.100000000000000) COMMENT Chunk: 606:0740348:204820 (0.100000000000000) COMMENT Chunk: 607:0740348:204820 (0.100000000000000) COMMENT Chunk: 608:0740348:204820 (0.100000000000000) COMMENT Chunk: 610:0740348:204820 (0.100000000000000) COMMENT Chunk: 611:0740348:204820 (0.100000000000000) COMMENT Chunk: 612:0740348:204820 (0.100000000000000) COMMENT Chunk: 613:0740348:204820 (0.100000000000000) COMMENT Chunk: 614:0740348:204820 (0.100000000000000) COMMENT Chunk: 615:0740348:204820 (0.100000000000000) COMMENT Chunk: 616:0740348:204820 (0.100000000000000) COMMENT Chunk: 617:0740348:204820 (0.100000000000000) COMMENT Chunk: 618:0740348:204820 (0.100000000000000) COMMENT Chunk: 619:0740348:204820 (0.100000000000000) COMMENT Chunk: 620:0740348:204820 (0.100000000000000) COMMENT Chunk: 621:0740348:204820 (0.100000000000000) COMMENT Chunk: 622:0740348:204820 (0.100000000000000) COMMENT Chunk: 623:0740348:204820 (0.100000000000000) COMMENT Chunk: 700:0740348:204820 (0.100000000000000) COMMENT Chunk: 701:0740348:204820 (0.100000000000000) COMMENT Chunk: 702:0740348:204820 (0.100000000000000) COMMENT Chunk: 703:0740348:204820 (0.100000000000000) COMMENT Chunk: 704:0740348:204820 (0.100000000000000) COMMENT Chunk: 705:0740348:204820 (0.100000000000000) COMMENT Chunk: 706:0740348:204820 (0.100000000000000) COMMENT Chunk: 707:0740348:204820 (0.100000000000000) COMMENT Chunk: 708:0740348:204820 (0.100000000000000) COMMENT Chunk: 709:0740348:204820 (0.100000000000000) COMMENT Chunk: 710:0740348:204820 (0.100000000000000) COMMENT Chunk: 711:0740348:204820 (0.100000000000000) COMMENT Chunk: 712:0740348:204820 (0.100000000000000) COMMENT Chunk: 713:0740348:204820 (0.100000000000000) COMMENT Chunk: 714:0740348:204820 (0.100000000000000) COMMENT Chunk: 715:0740348:204820 (0.100000000000000) COMMENT Chunk: 716:0740348:204820 (0.100000000000000) COMMENT Chunk: 717:0740348:204820 (0.100000000000000) COMMENT Chunk: 718:0740348:204820 (0.100000000000000) COMMENT Chunk: 719:0740348:204820 (0.100000000000000) COMMENT Chunk: 720:0740348:204820 (0.100000000000000) COMMENT Chunk: 721:0740348:204820 (0.100000000000000) COMMENT Chunk: 722:0740348:204820 (0.100000000000000) COMMENT Chunk: 723:0740348:204820 (0.100000000000000) COMMENT Chunk: 800:0740348:204820 (0.100000000000000) COMMENT Chunk: 801:0740348:204820 (0.100000000000000) COMMENT Chunk: 802:0740348:204820 (0.100000000000000) COMMENT Chunk: 803:0740348:204820 (0.100000000000000) COMMENT Chunk: 804:0740348:204820 (0.100000000000000) COMMENT Chunk: 805:0740348:204820 (0.100000000000000) COMMENT Chunk: 806:0740348:204820 (0.100000000000000) COMMENT Chunk: 807:0740348:204820 (0.100000000000000) COMMENT Chunk: 808:0740348:204820 (0.100000000000000) COMMENT Chunk: 809:0740348:204820 (0.100000000000000) COMMENT Chunk: 810:0740348:204820 (0.100000000000000) COMMENT Chunk: 811:0740348:204820 (0.100000000000000) COMMENT Chunk: 812:0740348:204820 (0.100000000000000) COMMENT Chunk: 813:0740348:204820 (0.100000000000000) COMMENT Chunk: 814:0740348:204820 (0.100000000000000) COMMENT Chunk: 815:0740348:204820 (0.100000000000000) COMMENT Chunk: 816:0740348:204820 (0.100000000000000) COMMENT Chunk: 817:0740348:204820 (0.100000000000000) COMMENT Chunk: 818:0740348:204820 (0.100000000000000) COMMENT Chunk: 819:0740348:204820 (0.100000000000000) COMMENT Chunk: 820:0740348:204820 (0.100000000000000) COMMENT Chunk: 822:0740348:204820 (0.100000000000000) COMMENT Chunk: 823:0740348:204820 (0.100000000000000) COMMENT Chunk: 900:0740348:204820 (0.100000000000000) COMMENT Chunk: 901:0740348:204820 (0.100000000000000) COMMENT Chunk: 903:0740348:204820 (0.100000000000000) COMMENT Chunk: 904:0740348:204820 (0.100000000000000) COMMENT Chunk: 905:0740348:204820 (0.100000000000000) COMMENT Chunk: 906:0740348:204820 (0.100000000000000) COMMENT Chunk: 908:0740348:204820 (0.100000000000000) COMMENT Chunk: 909:0740348:204820 (0.100000000000000) COMMENT Chunk: 910:0740348:204820 (0.100000000000000) COMMENT Chunk: 911:0740348:204820 (0.100000000000000) COMMENT Chunk: 912:0740348:204820 (0.100000000000000) COMMENT Chunk: 913:0740348:204820 (0.100000000000000) COMMENT Chunk: 914:0740348:204820 (0.100000000000000) COMMENT Chunk: 915:0740348:204820 (0.100000000000000) COMMENT Chunk: 916:0740348:204820 (0.100000000000000) COMMENT Chunk: 917:0740348:204820 (0.100000000000000) COMMENT Chunk: 918:0740348:204820 (0.100000000000000) COMMENT Chunk: 919:0740348:204820 (0.100000000000000) COMMENT Chunk: 920:0740348:204820 (0.100000000000000) COMMENT Chunk: 921:0740348:204820 (0.100000000000000) COMMENT Chunk: 922:0740348:204820 (0.100000000000000) COMMENT Chunk: 923:0740348:204820 (0.100000000000000) COMMENT Chunk: 1000:0740348:204820 (0.100000000000000) COMMENT Chunk: 1002:0740348:204820 (0.100000000000000) COMMENT Chunk: 1003:0740348:204820 (0.100000000000000) COMMENT Chunk: 1004:0740348:204820 (0.100000000000000) COMMENT Chunk: 1005:0740348:204820 (0.100000000000000) COMMENT Chunk: 1006:0740348:204820 (0.100000000000000) COMMENT Chunk: 1007:0740348:204820 (0.100000000000000) COMMENT Chunk: 1008:0740348:204820 (0.100000000000000) COMMENT Chunk: 1009:0740348:204820 (0.100000000000000) COMMENT Chunk: 1010:0740348:204820 (0.100000000000000) COMMENT Chunk: 1011:0740348:204820 (0.100000000000000) COMMENT Chunk: 1012:0740348:204820 (0.100000000000000) COMMENT Chunk: 1013:0740348:204820 (0.100000000000000) COMMENT Chunk: 1014:0740348:204820 (0.100000000000000) COMMENT Chunk: 1016:0740348:204820 (0.100000000000000) COMMENT Chunk: 1017:0740348:204820 (0.100000000000000) COMMENT Chunk: 1018:0740348:204820 (0.100000000000000) COMMENT Chunk: 1019:0740348:204820 (0.100000000000000) COMMENT Chunk: 1020:0740348:204820 (0.100000000000000) COMMENT Chunk: 1021:0740348:204820 (0.100000000000000) COMMENT Chunk: 1022:0740348:204820 (0.100000000000000) COMMENT ========================= END /Z¹W_1¤…µc]2‹+./l՘ V§tGDlަV¦N¯¬A.[H¦;O2L (>N¦ 6D"y6—)±8p8m+JlY5d eV$Abo~l²si[3^|V‹&_RTP2+b·‘…T6a\m <Nll\6&`'HnY.™n‡d›:]W:²­Ar85:S,D*X B9bª/:*v^~3eHdTvEYq $!i?0ׯb(9ip.J¡©,V,–A!1c@Ծ3Az)SX€A\pԢ1 H5˜0t}b21Zi#@X TA¸ǹbܡ^hp|‚iŽ%?mΩ…Q‰5[v)D\¼9C3@L 3‹Am –ˆGMZ‡ABmq@~lRF΅4 :0Q->i7E(I/d$_!bj&s†FŒTxªH ҳB12~ )=ptd*AJK 6\M!ˆ%  tŒ=2VRʜ)@ybZjJzbe=jtƒdje?sտ睌_[Ff(=o5?uB8U17a‹đsve_~AKJW%z׳ׄ.a˻ƊS`,"if~ jjC•vi|­™BHW%L+|Uo+hʎ ^$],1#ˆ? \=w*I@8'B#ˆG @; @FOo9jܴpU)Qi 674#GʼEaFț9SI +eLJ/*[=3OhH^™P–Z4 B2hd_Ȟ@^RBv@.Z߂$(($,ZE@E\'K£wtrBDYq£›Xֆ A}Քƴ?AjrW \ ;pw&5YL(̞Rѹ)AfsmB@C@2BM ¤@ }cLu܂/3B[ɯlSQ:-'8"*F†R<‚n[)2 A;ԶvdrKSg)"O+hADЁ[Q@mB -B9\@8$5sd,甪.#@&)8"^6eAWլ¡`=6@@MAAOR~5?t9{+6?!GaXakU"[/ >OmF¾qhN<Σ%)[¨f3( IC Mo>#ݣQ»~ss#CHN jc+¦ /u#-¹>)0Ô@” u,)e'د 0=+Jue ybB]',cM@?eE2է?& =@ʹx"If)F\0m p+ % ZQOrDűDAe=A"CAA,)BBzAMOA5cq* 9U/-G}_;Fw\B6Z&ҋK‰Hž|&S B [([䘆h Bml&R؂Ae6@g1Tēi<懧jHGY‹K‚#A}Xb'#["33I8{VQ6 % d\2f \l4>M}>Vg$c]A3›gAiG-AdAU N? kB\B*9BOA(B-BFNB.BTBB,BB> 6B6BPBB\pB BYBrB'@t^]AVA?ASAlAXz9 {A\o@tuKUrfD,;͆T ǒ/Z3mrO/&(K@ty'Ewr570AYvN3)_YC ARAT A@4 *h!|@~^CiC  FQ'G[&,uɳy.S¨o8*$Z{Ae t_9fsE#p  ,?PŸQ1{–YB))A`k`R)H~0ʚA Aza*3 BkBe~{BMD,A[NA޿?B:H@#B3B?=B*^BBEpBRBfJ]BC"B B*[/AB!@LZ BbysBfr3BuA,A"AA@j @?A+K@_GQ,B%AFIBv0p)'AXYA9?MA]GB`AEfB&mBR"BcB=ATUB BgB3BuABn3B>TBrB%BԕBߡBC _BθAtf@3;@ܲL|mAm)vA|¥-HA|; B^@mAh}}ACc6!2WrLNsgLcۘQ@^rAk I@NFb(] T/.|jnWHPU#=F?"GտpAeP%0A{q.pfg8YӾ.V(5bag XZ7-пa@@ x@ˈ7FAnB2!w@ٕXAW +L1&pqkn&_!)X^1zP h­ tSS\‡UkMFWr<7MA>~Axn^A@54F-bH3}poVYqa#0 WطAo̟b6P]p")X@ B?MAB>A[@IJF9A?q[Y67gA_=yVA,@#!Nc@*1@A<`=#Ai@us?A_BB/8AY:]A@AzA|AֆAgAAyA~AiA cBPy?'M#ABoOq[yI+ڨp-vwg4bs)^<>?O?w?o-}\_l4G2M9A v?x!CO@2Mj-E!@96fwˤB>h#~AlR|&A+<)d@5?luQAfCzA*?/5sW@AQ9M@%Y@ JAPfAT7qA',8mT^70?@$$(&?\4ciozf~ 6D"]1X?_cP#=oq{ EiyjПglv/ +~خ[KRJ> o^0$q˄LDˡw :~{w\|Cw)|asJ?y+><}J].JZ_a93H~7~[;~~$.ao/nr"de`: D[V+7JVhc%(au{LcO"1Z KjUPQǞnȚ[K8*]jЈݗMU[rbJ@5bca*eCk`0 wB5{b pWHrBSyT&^!= *8T2W $_¶/Lk^?<盓#3 rz, RuсA/FR.dP*|K$Cj|b^+dgq z~L9AA‹Jg›! WTġ>VBGk_mR¿rY‰OTl$¶+@=ܯ֘F w)%D:Zy&ل w:OوZHKb/%f~2leKO`^*%.)gKLŇW#nqS#̕ k;@rfEQvyN?pA;Y_LED!n6d)iagV5@h 6%Sw}AU=z+ $2F -bmI~xBE 6'ZMBrqۋ uDsda\ '~2AJQMk/#h9v?52gtIupMhӾh K0I{KH rm >-:HKIO= l"]KmAL1sA5Ȋ@.~2WBe1Ɔ/#hڗ@[_uffhty!^$T{شxޠ<`pA A AHoAZr7@]?"cA7ğkRkA~AA?BHB0BzOByBxBW~B`B!B2ByB>B6BBB&l+/AhۀA@%9ʬM>A(^`R'lA̶}G@?cAY@%Mz GpB.ZM4"@ž_լ=Jo?RyPent[NFC|VK[@| ^k7X7 x=9bTС:y4@@0 U_ ؄aK|.tB |!KSXs\s{eY%Z_>]21ud%!Iz%Q@zW)Wݻ?j3N!?3L\:rv<@OB/EDpsXp״5[|ԮQl,(L@=?2?9VATx@ A/AYu&?h6K6b!*@Oe@!aA(.AUA4?@j]~QxJAz`A@D<[@Dhnh&%YҩSZ<їPA #VA URvx˾8x[+@U-.V?4>AZ~A4Hqi%@?AAczsA8}HA UAwAkM'sD@pQ((AjUAUN@TABvAwgAZA@ r1!T?|9":Bf;~;n½ චS4!-@3^WrY=e?SrGDs@qd@R@!$?NXc<.ST|%?ֽ܊>, 3@#7@fDMAAb@_@Cg,ě'0@kQOAcY]@'#@Qg㿼4@Z1sm@S'@=W@HTa^r$;=@9n#0R@(@9>&Rp@J@JApMj3@䭮AYA+UA&E>q⃿#A:}@_A%?A,?׭_@pAwۮ;Ag䜿A Agj#vA_@9`GAkMJP*AWE?FA1*)@7A 4ITЕ?W?AH1@BYUAs?2aA&.HH'AKR#&U@nAAB?C ^q#KB_V2.z{A1B`%@~A =AkE7@s;OAuA;uA=AaA-f9@[վ @x ?e@Bbz?J2gQZL@@@N]7[/@A1cd@<6~TAy@@l@~GT=ǜhZ}Py*v+y@$@f=?걿߹[w@\)@%b@, D ^HtIi -a}0_Pn,B0S@(dV@r@ġ= z@g?G?y@ @ xL@+5!,6K{80n ?zjP- R<.kA,]@@AWASX@3;?:hH?8@|@hX*'#>0cXY3JEQCD6/ mp /)|0;`ל =oREcW4KGCw#[.;ca@ KWO{ͿjBn~_ 2wihG~ڂ#J>ΚTD`zV?R0pDp\AXA&RFzu0ASA6oE@1D@Q6r@i@y A8>{bFA̾@c@(@ 9a@KAA @8hdAWe@nZAǾ@_?AaFHPA.Ay%JAI?UQxB VAMAAۥAD9A A{Afs @AKB@ _Av݆@kA@G~?~D*=T u@Xn{@U@@bbI@rF@L@m?@@=7@Y/ $@Ki@Y@AkIA2;:L>?.@vE[?96@>:áDͨ~Ju? `np_0 Rڟ'W|G~,A7M3a\A@@~&@l?@PA'AA?{d@@ b? {.3@@a]J &?:f̾cƿI@ @Fc!z@@PUBdC @ @%@k@eDA+8@^?_Aq@z,@NR@/(A-@kJ?5@̀A? @-J?1gѴ9@*f@̻C? ZAn@AC8?@>@*@P֦@k<,YηHb=g-8"d##XHjQ2@ l@3ۿQ>b?e@b@&t@wp0$~(8]DwD&@bh w$|+L]WQAFJ|LD@o҃__1GdjpC;pԁ{B:|D|\Jqw; zR2$mu[V=hǩoFAjtd;bSt? Q>@@,k( +Q(u>A+葿.Lj~@jB<;A?>AB%۽AB5ȡAxAAߤxBcBB|AnBB+V7AeBLBhB#%AZAB&BWB6B6B!?mARUB*q?AtpB!&*AKLAOAAYBA4A8=AAAֈ@k5_A@eAlVRA>@)A Ͽ#w@<0 k@f9"SA@@H@`O@ AAIT@\eAA,Y@0ÉA@aA I@WSA@ktX@pI?[p?dA5=%AFqEKKY@@Hi@ nRH?'dEA<:,@@%@'l@)@1@ @@T̮X:ZP˶VNGc65Ϻvb@Wœb@\:.@ms@ A{@d@K@_6ul!nNŃA;6p@!YPi?@b@k@*A,qA/xAi A]Ad&AAAUAxA&oA@4oA%A AiA`S7AA'AgAN Ap2AAAYAy=AAwA&tAAMAb9AKAeYAA@9"A2AR?@A!9@%>@ʆ?ŧ?[&3A@#@tE@YA\@@>A @E>?:R_@ ? @8Ad@U4oRA*?@؜A$ A0q?GATA3m@ ARbdAA7aEBK A( A3A:vBNvA A@@atAB>A_eAB\A+BA&AnB'cAϱhAQAvLB2OAEAiA!3Ny@؞-KAP/FMA P(@6AA@á?;zکd\V-.ArV< y辝|h`JA#fA'+ ?^ݾ^A6ӡA~m@޽ɷ0?Y/ج`&rؒ@!>D0@,@@A`,AEAxwAKAX*k@bxAP~@)AS2Y>8@?X*]&@:"?@@ S@@n@~@L?nAnA2AA`7A A)rA_hA_`@ @iY@IeM@@2?f2?Z?do2"@?'Y1@rS9Aܿ@lA`A*A e2Ay;AAAC@.@A@᤼͞P?M@u@߯@@i)V@:V@6+@F$@ЂAZTA@AMQA;%Ar[A2AWA8+nAwA\A2AAWAzAKgA{ڼ@Abd@4AbAQAUhAjAƃA>~A1AA܅AAЦAT7AEAA?Aѥ"A:AAA)0AAAA?AAAmAAOA AVB7qBA*B A!B.;ABыB~B zBBBB/A-BArAhVgA\A AfA{AASA/@ANACA lA mAULAciAxBAZ}A[=AAv@K@zzAFAWAWgmBB#XA@aL;>4AE+k@ 17SA7GA:n$CAA A???p=e@k: eJq@*{D?uZ>@@@ A"x?-KV`X >@\IF(AE\?k:+@e!A@?12A"@кFA1AQ}@R@$e?ȭW~[A+B?$%D s1?AD:AA4A+AJAA5@@@Ճ@è@1鿈 !?h@1 L{@f@dcd?9@? A^@ @@F??5jn06Ga* ٽ$u$o=n\f@XrY?_@tֿ?@Wn?@(jN?uLx0f*??R`hU מ>W@+*)|@%*?D >)L@KG?i@@f@3Q@a@ ?”|*3(@ #GŇ%asb""И@e@m@c9@n@쪇?@?Y@-1AX@mB@_=@>(?1f@OD=U`@I..?H#A<@P\e@xdcɿ錄^b )e@ ?@XZ?pW%@3@!nAaA8?N@#cAGfA@V@HˬAAf"AX@Ő@vm@nA^ľ*][@x?BVjA]VAA5rAk^?@#A޸A A/@?-A\A@RA?A AZYAzAn >sOq@h>8AA_%?M5&A@ hªA>XmA"GYAA'8@Լ@:ʖ$4SJ}W <"K@lf?-/xT@7NMA@5?$e9 e񜿬 ?Z"B@ j)*@ @@w>Ԩ@\@Tǹ@@@륫@$b?>=R@ 2%\@{ ك<ٵF*ENJIܷ\[&T ň+EAqUf@.oۿAwsA`"8*di⿍̚ l"OՇ o*ùV<Q}.M;{VpJhi Mv<@M(RF-e`Ygr.uj`C"F1z7dʾ7X=z oWqVfuMNg,;b:"eф*^Ooy[K8;u,CHLG b&1h'7|C( !>JHCsJJF~:}iEtd *;1;K.r8QVX(ҨC'_>u+۸"ttRq'Ԝv&Z?)] j#75 zݹ)G?!?t/!t3W@5 ""@\?=A?ۮF>"C}(UC2@E^RވnuA >ֿ}W? k@Ԯ\?@$e@SXJ@A~~r NSdy#M@$x6?'@9@Ay;ߏAz]?#?$- Ot<,,l!]ĕ5g];kc @K%'=]mݧ79?sƄeQ.[,ݫڽw }c[RO*w}6%Q9xL *>xr=e  A\eA zIA졿p>t@3?E#x9#U{&G %X,yc@.j?f@%@'@>I?zV8>19)50䴽qL/z ׵gZ<5 YaRn9%o!2ǕF"p%ZLn@*tX>HԿIzl#>ec'T>ƋRHL@I?hG> i,@vȏ'?PJgƨКOx] R}`~1Q0r;mYck1AxK pnBW|lٰC0(aYlq­@޿+"mMG@|/ID ᅩk@^AYAvO6 0Ae@SAz-ˣ@iu@\yAږBAw%8۫?ؙ d\ABS[lA AA@TA-BuB?A\AcaAAAwA|ASAUAm @Z@$GimA.uAsqA'+eA{|4N@{@C?mW@КA[@[@|| AA0ϼA?ZyAJ A?`OТ>ga2?ށe- Ⱦw;5+%[!^V=\gD?Hm?qLusADX S?~o[s V/A_Z|5(@3fO@ HTNGip޵1QNbψJaIkCCQqWED% ǁŽ-rB@@\@ ??!#@Q??0 c@?l-V@,g? @<5@5k'?<@ϗ@fMNF@C@+@tA!@6C@_@A \?ꗾUOI->s>dh?PADZ,'@d@t@&@@6%AjA`?¸@La@J?@X@H@E,6ذoUT Βgb.ZNG3?̿$dkTnrFy0j>aAsY=NKm<[lav\{Q7mUte>f%X}FQqO c>g橖2}Iq+An'ii2gW-uR@Eр0S*@-'1z!ڀ,`2b?'Hu4@I,9SN[ei=1@D7ؽy'A/@e)AJvANeAK@@=A i>aP1?"Ӡmm@E6`q<%?o'?ܐ@c@C@@9y?&BĖl@%?XT@@7?W^jg2*:cfLP *SP!/ǿ@P?FO@s?)@ZcK@y޵l3 ?c9о P?:>pn^5?@оj@F@>#@@[,@ A #(@ @|/A_ A_ASA @Z@f?AAA D'?>A0@3@$@AUB@޴AdthAA/Ay(.AzːA^Ad%Av2AoAfAUA]AAA4RAFDAgAyA !;AA AQ4Ak?]AAaAEANAڼAh[AŅRA xA幈AvA,AMA)A7)AsAzAR'A]AAX\VAlDAVA\tALA*)Ap|ALAdAA>GA;AA7#A\k@l`@nAӗAhAACiAA+W?aA6A0PAAU@d ?^A 8xA5%ALAD&@ĐAY&^QAf 0AL[@߽@A|>#ARnA/}E@7 x8AoN1{@@/td.@ Lp=j o$Iw*-q@ MEA{@@v?@@$zAb3@u2Ab1>7?p}?yr@.ՉAe?<; YͿYAc@$vl?hLJ{;?vr@++?saAZA@$?'?A@@+>4|/]]>@R?p: ]z>&K)@)?@c=G@_@5}~?1;Ar\Ab=?᛬'5ab~oֶ2ۋ5w,@׆Byؿ.{%+9cGc ~ձe%R-NB& BC0}"?!P??@Fbiv@7r}do$$=5@B(?{?lUs)>> 4@D @̾@~?Eu@ @@7 A@ P@?.?'2A >Ӯ>I\@@AA=AW?ATOAK(PA@ A@ WABUANA yAF@A>Aep>uA@yk>@c?@CAxA@{\AcoAB=AAJ@A`OA_A?A3AU:A&ANB@=AvA Ɉ;A#UBhAAZ:2A]B6Z~AJA~@@A6$@&jysA@.x@9ZvW^@2& r?3 2%@y2@0@-=~@u?& WQ?xWk N,c kFc8En*JT DJ0Kb ~T-XYgd*9ͷp.[ 1 KEQ%POC3۶ CIrVh2:%SRIvZCm2L^8TF3|TU@orC*96ko`ލh843#p+SC@(m"PX{3lKSZ b6:c>%@%[+'O87Ë:RMz{;n\lq32$.e\{#s+A [A[@\@TZ?hR Aɮ?"@^[̿@Jpel)UϦf@}?И@Kc]ٿ2@2!T@Kp|A ]@s@h_?@<@|Q >T02 @ oeD W293= 8,F?.t>@Oiyp@ ,8_/ƣ+9|z6 GGN quCPB^9zN6&d@$Q?MA2A@-=F?I;@H@Y^x >nL sPw?̞R@/%F@1ω@NM:@׍%>8@'*@ 2@F@R@Y徭 (5@ z鿛58l U)]c{-@='@.޿!: >aL0Jp'Ny1݊[w8:c^ &Bcg`k84@ a @)i&2 Z%GL`G˼K$!TLU;~L љuNݾ;T>BF2*ς#iL0s&IC@q? 4dq@9@@7@1.]v@@+WA~A8A˘@nAoA@eAA}A*K@KA'AcU@`( l@EVA)x@[@[;@*}KMtJL@hr@8h?6@G8A@@t@kG@AQQA1C@Z@A P@_X@7P8@@"@ ]>͋>3<;,v?S@HE?O|?yw@zA/@i@Hh@.?d@zDL/@G$ g@(P@b@?= A9ކ ?CO>lYB"ȾY@BT@R?O@7?&3cE9@6@Rj?пع? X_/﮾cU??QhW@? A@9A"AQ-AǷ@*@ΩAk@xO@?pm>8H?@/s@s@S@S@L\6@?N@K?M@%?Љ@"@ɘ<@/@6@@ `@AW@.o@@@$?B?X|y@Cr@'@E @\H@)@pA?cV?"@@?4a.@Q@:o?Z@?KA>!#+@oA)S@/c>N@!W@xAWA!@VAA@@!A`0Aq AAA߿@M@Lk>j@ ?r\@w]}(9aU,~"lEr#(Bw;ΰْr.8YC5pHiuG5?! @NyH%hkwOpH=2٧+A}AAAc56JA׽Af63)AA'@` zlbhA;@+߿xG3oۿE@,A%0A KA'BAv?L{Kh/k?r??/pnpcؿw,AA@l@ Ahn@+ =@K@v@"ad@@@^@-D?i@{Ӱ=0/?Z)=?@:ynnh?t$2A0p@e=@@F"@ (?<@L@4@;]@gp? ?XsthQрP=J?V9@o @J @@ZAZ}>Vf A@A45@A a@ @_@XW?@C?Z@,C@n@Ǭ@-@/vA1AEA!E@%AA$ AvzAgAB%AAAhVAM(A&AA+AqA5vAAAF|A@AAA AcN@+~ A,@V@KqIV@AF#9ͶZm?w ?oz!HA& @?۽%5@נ*?Э̇?o=ssL#w?AV@afn1(¿dO:?65?{Ô@ N&?E\ @lQ@e@ h? whz #>"m=p?r?hE@PO g?l>?R"@H@&A X@v@Lk:@]"@B >_ɵK@N%@,L] >q`ݻŎ9 uÿk@1Wrl?3?Mc>Q@@,.4j$?ʻ9?!6oefe?#~SYʠNL7D˼ OY{~)unw?ty9`M&>UFR>r@ i#d?@m}@+od ?'G @V?>@k?#AAD*A ʆ@mAC=&@@! @A6@A!i/?Q@SA?AuAg?xbC@WA%"Xh@hAe@lA^A$@$AqAA+A#bA..AuTA_@>A-AA:EA9AqkATAAAABAQT_AT@JeDAVA-BAxA}0Ap9AuqKB -NANAXlj$?BbtAAAB@AѾBDAAܰ@jf LA(G?!@b6 #h>)IbX@,>ރɕ9`O/j=1]տ*Nuydq2?O^I>^F 1  8H}?.Fr(`:WQ R|Lv@'XBfq4)+s@d{?P7m.[?S h&%1uUIIHb?Qq]Ŀ2t@h@}1CzY(?xRZq3 J 5\>׺ؖQz M{[r&a/1AiA=ѧ,vݥ@(AAJXw@iA4@_&Jn$ A\u9 ȯ`-'?Gpʫ _9:N?HO?2B.?Z@.{-5|b$p?G (18A#I^z_[tbr/*̨g$nѺVR, xv&E}cM6pNFIuGQ`8H =xU/|`I8I,\#?vv.n%BĿ&\>51xݸ2^g6rU o aJK`dx{Z@Hrf@q?Cٷ @\?u>X@%qL&.??>?] usH@u@/cl?<@[P{@@98ͽ>^>wxi=??{u?tL?u:BֿWuw?tnм$@@ @n@?}Rо:6@6@" >Ğ?A@@"A .@@?DO>)V@nk@9Ŏ?ܭI?*@oA}@a@{>?lA0A|7A=S@vC@"XA @@? )A5Y@1@ɓ?ۉ^?]AxN@i@g@%@@n?ȋ@fu@1?'?0:@|ϿCƝvg59տI" @SG@ >@?X>-@ G7_>@ L@BtD R?_Q':78d1}T8(C8-a`c?Ml`+ɠu ?(eO`j?]a;bt`]na"?.p?_>T=>@@aJ'r?@ʃ?ϧ1A )@j=A@Ƶ@@@ǵ@J>;C=>a@ K @&2%?Qj=@TJT?E??$@BP@B}@5@ @Azn@/A,@R@$@7@!A LA"@@@KT@+?a|@@@ǵ|@s@≷@,@O47?-@\@}@w@a@ ܞA{Ae@9e@:@s@@`@@cV{@P@RP@~?dA6@Ad>{A1C=AAAiAX#A"AiEA!ΥA0v.CAs,AB@sCA'N3>0A4cA7f!@A!|ݾA$ApA@>A.bAJ#AAA٥AAAAhWA>yAr)A>|fA@)8M@AbAYW?/ ٭@ZB=4B 2+B'@Բ@8-M6@@QAي@'%AcCAx{^fq)R@weO]h`,/FqAO@Ai@r8@!.:@9A[]@QQp\Z" o@U*>AǿRiৌ@?+?{+S?`@W@]O@9`YM@&3?fTA>0̷N>ڿBd>G`?֐ n?j?!A@ 8)@ #?:?.W&(@s]>f0,D՟OL!>I. %x\@0z@"!>g1*1?ȟ?P &,i<& K(;=vC$?i@AO;`&=@q@"?d>?m@-@@2rA 4c@X8@5@sA  @"?@-c@ B@ -@i@@@1'@"?K.@@Ϟ@Q@3@;@(A @c~@i@И@@2q@(@՟@T@PA'@/>@9@ H@PA;@_A@"~A AY:A9%AAAVEA=zAh7A A}?AqNAۦ@U@Ɂ߳f5cAhy?!V@@>4R>hVLw=T!zؿWZ֝7f E=Ct;+y@S6?4?&,@OvXFA B@I*+q?EͿ۽آ$?Iqͷ?*$e-L-5)j?㴳@ *X5?Zg_M?q}E@F@%[8@/zEֿ??t@.?g@ODzNuq~ p@K;0.@<=AgLg?@R{S@Ok>&by@GOq/ y@ U,Q>Ά? ?@ѿ{?@`R2>J@窾f@An:?@KCo @ 4M@+p|A 2bw=@3@h[ N@T7&@@%?dZ?]Q@M{Ug0P>T_1&P^?a A3V*A>q@9> ?E* A6>$8@ m4!A @!&]b<*4A@3?8.~A})տ\=?6AwA&@n9A-#A@CB8=Aq>Q @fr8AsBCB&AlA`dAAUDAeA|AP鿙iT<Y"$Av5uq  $^8U] PXu?JXyޢuo.lk? 2WM$J>uaX˷t3w?Ms)S ż*rs`- ]oG*R3'_%Jf 㥄 㶕 | X!̳)\g"mwN-4jŤn>AЖXZ49U Yῷ0l`ʲ[:z02{,P^k δZA&#(qTncR0]aZ??W #WqMK^d3e7?|ru@E'.u~4>wMDqDA> ³|w?Z^?e~U?"#@ [@@X@j@띂@ x?} *JF@t+ @5?|?aq?y!c+?zP{@@=fA @ ޾@-@p@۳?k@al@;A ?,>ٿֿ]M˴@vA#4@1=Ai׿\lA:N@gY@JEA@R@Nҵ!@@@Djr]bŸu?#RANqc@CV-IAIo=z*~[A[B JBBB(\B8RAp|OZXT_yAiA@ڿ()@{f@@ݥ iac @w_,4,e5@xH@@>@-<OsS>Dj@ 0>@*P@wAgV@nwOq@j^ys 1 r:!eE\M~? vFDʻhL'\&|)bR~]yP6D "_36=RTX اv7$Ug^xC7T+K Zh7X/\?@/ @N}._1"C]@+?l@lT8?] y>"D2@#iq"u?@ ?@4G@ާ@ ]@~@ˣ@ED@ AVAL AZAD)@]kAW[Ae@ƕA A!AUfXAXAAryT@ߨA$H%A`SGA %A9@UȾgAȰA!@މ0?0r?`]?6@AAaAI@A&?ArNAJA&q_A@AA _@A(|Aw@ЙAwbAou@_AK,w@QA? k@Ksx@[$[@ k?Xf>}p@S?<)]Kw%BF^Bɜ ?a>6։t& i@x@> @&Dhz0@w;?Ŀ@NL?v?0@#?^Zg@@Mk@@˗@AxPc@4A5TAyA7AAԷAAM{A#*cAemAtQAq=ɿ?(cl)ℂ@Ͼkq@8@*K4UAvB*7BBBA8:ur^5$ks@ˠvɀo o/GL~#DɈln0Y-e'a,BNNs vOD8Z[/ %kRԾSQk{[7s2%# &)_6%<DST$*a? ,GrmO8@+?@t??I@g@&'@r@ǿ'b@"Hj?m9>N@g!`@5@@2@k8[>@Rw???-$A?9#w@[@F@<?~@7ǿ?@@B@=?N@@i@fe@fA8r@p?O@@r@{@@+nA(=AQH@څA)H@G=@UAH^A H@+A#,w@YAA#Ax@ë @@Ư@?pXTA=*A&JsA"AgAABOA:AAVfA@OA @}A @@@~@B@;cA=BA cAD)tAIABt@~@z\AA:CA7o A]&AA6A$QAm+9AZAA{A(}A +AA@AQ~@=AGAlAV1Ak AA=ӢAHO@B$@A_myAQUA AmN?@2AA@8CA L@ڀAwRA=Y@RN@@zAAB?9TL@e@?Q(AA#C-9+d?B=@<ds?-?:L?29@\@&gY=p@Q|1@[?V?h@<*?/MB?V@y>@SW?:>I@1@@[BZ_*.|{K@J#Z}(=Y?3>Z\Pʖ錥 y@w2?AМ?oiy??~$z>_ d,?{@ʾDp@`j5g>]?Rl@Fܿ}s?e>L?pkp?"?j??萿<Ӫ??&?b( @Q@BO,BW@@D@G>"U J>t?@SR&',tH@u͘L3 n@ @KGShA:A)AsBAAK,>PB BZAC7GAY:@㿁?cf,+?ZQ5XG]BR@FAu@]/?8AAUO(?өR*?}?X`?*1pԜ751$vwl?D f3"#Cc X)l*_!>BI1@JqjC0;*$N=D)@ ڈ6 )""+ Pi6vNxVH`@2o1fX ?![hZYZy65 H.vGUmOlu)Vn׌=FfrF/K;TQڅbnsF?=< ?W]*~@'@q@s@?ge@|T@\1?t`H_@HK@@@.%7@b>|@t@b?(?꼡@M@nH@w@@r@Y@晩@p>@l&?s@ݍ 2@cc@S@z@^@H@@@@u>M_@ @A$*A2$6@١@oA$)AF>-A@)A52@9@g@aA,9@׺@itA?\AFA_2(@bA6DAMA'A^Ao@-AAAAJACr@EA,@@sA,"@M? S?Yv@&?XD?P&8I@B?d@d/w @p@I@L@@A9ADTAc6?|A LQA@}A (}R@%k(A%# A,RA%KA/A8+A^sASAA^A)B LmB$AAB)B,BBBAMvB/ t߿(A+A?%=@@>H@rnA'?"V'9= Y26#_hREd nA#Ql; )#WAA*A,&3)}p3σC[Cs?odBi9)*kB+q#TLFicYN$>+￙Я??jM@iۿ휿fWv yUyo:td+MMBd1ZB1>=//(l&x?^>N?ENz>#Y'@tRן<;U?wP@7?xVv>N"@Cu?.?@C8"?>cm@j@{$@ }@@G@?@O?a@@@B>a2@E@ V w@A@xA 8A + @i@ch@&@"T@h&A1JA A/A:zAAhA=AsA$@c0@@e+@#[@O@S@[@@9@HdA@vAKF@̮A_A@AQAےAuA.Ah(@)AAAyA4@@i@@A#[W?$@@=&p@@@ĝ@8A+A@j?T@_ˣA;A&A0XA7RA5A5.,ACAJw@A[=@AcA %@Y@,@@RF@m@@HAA&fA A((7A.8AY@ѻyA~AyA]!AE2AQ1A˕AAM@AY@@>A6҈@3(PA_@;?@AO~AB@BBBP[BI&A@AQAl@++?`!*'e20;J/pR$JH*DYU*+P?cJM ::BJik'#'Oe,)R N)z%03,ǺOWn /ԐB0˗Ej#Y#"4kB(]}Dk6@7WF?dp ?f@.)qw@NW2_7=K??0Qg@Խ?!W f=@>@[#@+i>i?s-?@P@@EAFA81A@ @@>$@@ρ@_?@F@p0@tQ@@A@`@.@"@T@Sa@cA"@@L7@?{A-nA@J@JS@,aA"OA[A&q@#.@@}AA@wA@ofA$fA A @?H@|A+U@ArA5XA[A-A`ޕA~As aA3Vk@XA@;A#AWAAJAmA0AAr|Ag~@iAqA?^AQk@6/AAAWP?@&@I@DNA&mAhA vAQAdA:/Ƶ;A>Ȉ>Z@MbAOtBWzB*+BJzB JA#7#|YN:94Ywۢ/ݷmh iɛ~J@fMDO7dptr 2hLvRF(89t ZuA _:TdQl.pшy..}ĿBGeEB5(LP + &VAXkf}`i^سh > |O!5| VE;xȰ@ n@$?&?:䂿ˮ?h@-P tJ¿H|?Na>vAK HB @U5)????@e'?l|?@tA"@E3@@1?S@?;@ઇ>P€ASn@@A@~O@@4@9 @@A)R@4;@O}@[@a@eI@倱>@>D?@Rc@@@Y@z@bA<|@h@HA$A?@Eq@.{?s AY @q@?'@AKuA/+y@LA ˿A@A0v@Q)@?MrAR@s45Al?,@n)?r'AY&@IA^C=A я@ BAANmAB1K`_ 1PM<@j|erIP@wj7}BB q?Yp?qF^qBC'?* 1}g%~5N86&(5\jLL'rR?D(a]=;I 7[T@[T:BYj1@? GK4QL\A3ӎDuW~*/1 'iiM:"=*gg6gD[rJP [?x5>(K> %@t"@HI0߿ayݿO@?nK@Y?z@)!@P@(@e@@T@=15?+@fJ@3H@@ݠ@@@|ڳ@t0?x @WM@$a@Z*@V=?@[0d?b/@KA^>謹Q@+@ *?@n@:?M@U𾓲$@e@(-@0eG@Pu?7@~@*@@?@tA%A6?ۯA0z@A]A"?_>ά@#H@tK?ȶ@_@P@%@ @lоl 9A*S:@x@bA @),?@A@c?Yo,o@ K@*%@1׿(HVݣA-we?A>{Ƨ@8?תL^o6?uF>\`$)MA!Z@}A37BA@MB+R,mQ"s@̲Aڹb"o@Ћ,t@?а@@VέJ1@uE@q?7u ڂ^ff @"2|LuHD?-FJySGq#FK91|Pq#k@yM,7k|'O++H5`E[{|gI6=zOnojw8S.J!64d9-< c d39/ #en42i=3C1l> 0ΒE׿hj@87kyT0e=O?1@U>ȕ?Vlc*?b4VL?}#s@ R>Njv@>5W@IR@Y=A0,G>B??༱ =no4\ {?p@?]Y/.W@V(YPP?"ƿ+?%q?V)?|p@aJn@@d@(4G@#@@bL @vW@J@#A @AAE'A8A@^&AA*)@Ҥ@A)o@{@{5@ @1r@iAAs@`@Qw5A&@8?A AA}A8AH@A= g@WArxA=0)A U@pg@W@ďAF4q@IƒA+]A)(A[A@h @A0?ʵA sAq A +@ӷ@\`@ZAG^AA@OAbAEA~jaA5@AAA7Au.AsAzAaAxA +AA A_(AΏ&AAwA2acAdB- Bfd8 l.D>v@^|@ǿ=L s/sv1QIn\MU@ *c=S⤹z<0SucNYSu0v.sAMK}csSH MA:ngk[7Y >[ Qyku]k @| Hװ*};?c`8Ah¬GIȿX4,E ;\yz9{@m#[)?0f'0?UZD!-s@nO'?{@=[IJS@@@@>@ @?˸?@Np@@W?TQ@@D&? ?tF@;@@@@IA@sAA>AIhAa@A%bASz ABA>A%Z@AMA8UA)xAX{@D@@1AߍA,bA2*Ah@?zABA0lAє@GXA @"A @)@m#APAJ@fAA A.8AE@ˀ'@;@@cPYA.@%A!AfA%Կ@X3@A5?@AjgAAAkcA&6AA?AATAwAyTAA4ArMA OADA%SAvC@kAdA .ApAQAbA AAAAn @ػB@}A2TXLj|kg6JD 1v"Xgeek(%/ljK܅_&&@Y/+:"*)bZ&ӷ>`Y+AhĊЋ&4$5 ֿ( s $^ƍTz6vt`DӾVHRmuq߻E+R[ ?At@]nI`U6@4H;@_@u7?*V+$i\.S?,s@zo}>[?5?=@e|@yc@[@@X@c?@S]A@x@< Ag@?@gO?d?co@-A]@@CdX@KN@N@H@0@@/nM@J@*@&@ {@$@@(_@E):A{@ @h@՟rAB@e\~@v&AW+@1@d@U@{A#Aggr@ɅA0(@mA2UAMBA.@TAVAAP=A4A8?)A3A&A`1AkAL\@eF@0b@@e7Av=i@@?r@@yG@ZAk#A@I@q@ A7A@?A> {A+Aʬ@ـ@A/@pA(_ArAi>@@{H9A{rAAa\@@AgoAE8Ao6A8hA"~AdA@kA YAxAqAz.A @A;dA @8@wDB&A@AV$B >@$¿–aAD&JԪ] 21J͗Y~ vRVt2IEI<~>+/& =% s*HC-}rYMcytT8}x.|rJw J+Q:߰Ws?x+rghan5_H-Rs%zU5B)C$տ4,(QX#95v;{Tk y9_\4֢n){ǡ*!y HL x[v;?(׮@ :?*t;06 CHw )>,Q(R? @:15Y@-ehDN?uKѱ@U@W@@@{0@<@؂@@ґ@?[r@*y]@>?|@Q@`>$9@ې@S@,?Ұ?A@*`@P@@j@oP@P5?@Att=@?y@E@_@n!C>:>D"@c?c@@.r@VK@W!@!@@@@)L?[*ANX@_?@ɣA@ZAaJ@H@Ā@ҏ@>@DPA0?[P@@{=@?7@$A@Uw\AF @@ &@)d@HAk@N"@@#@'A3@@?ݽJ@V@A"@@b,;?A]@Y@@z0ACA4SA.ABO@ zPAA<}@V@TNmB)?A,+u?R@!0A`AxAޕA;z'@t~?E@W$+aA9,k~E@n&qK $!PP6-xLm WL)a!M#JHDEfuD?*_%eHm)>&*rO] TL)>0'a+3 9{1CcdRBm`_9x~[oB!OAd#nE:sAWtv'N-V!|a CP)|B269 a% -%J@ݶ,2d_Bxax'Gn8z#/kmݽ>%pb'2ȼAgv9k@`٤=q @?dݽJ> @\@ɒ@쌀@-@tAk@ڦ]AA Af@1}A VAA AA A2O@ƈ@JX@^@Ң@FS@ݘ?h@?@rW@|O@3@:@@0@@PAA@ɍK?44@Y@tA \@:@6@D@A|TAAW@M@u" @AC!$A@ĕ@3 @J @")^=@$A@ X@e?3k1P=Dҿ?̈́i?b5Yp@>\MA!7ۿW2@=A0jsA8@R@x9@j@gNARvӄ@rAoArBU9AB1A/|AB"&&@t@f.@?kp>? * S3[o@\=?\7h_6{>ˏ4@d^@1@PSٿҁ ?s5?/:?/5@)<]>ar?{N%",K%FJBbER NWD5/mZu8_'N'b%r%BӭXA0uJ>M3 W(-UA95Qz* b>8m@_N1@5@2@y@ȯ@PT@L@@@@1@Mm0??0@4>U@??C;y@qY>k \@@.@$?@74@cڷ@䖬@@a4?F@" @f@OA"1?@9m@=5A,A2B3@%S@GA ASA#AAx@A=4AG@`TA]AwRA7A %AAFXlA?w"ARAv;rA8bA;@$PA^:ApuA_=AY AO-A3VAO)@A1AIAV?t@>P@A$A`@A4A>A K@A7%*AVARA`E@@tA%b2ADAA SAB%YxOA>AAEodvVY>S {@@a@ڿ(Cw@a> @sR<{K :~h k2L?r[zL>(Om5D+aA@FnŜ?a瑔?1;L Ar+L\v8btͿEH2O[\:)f6 @)$3Q@yYY݂?„ ȣs4f@MlY?8?вP?q>sྚXw0@@;&&?f ? ?#ȿak@@p@u@%@@@hr@@T#@'-@W}8>v @~#Q@rv?k@9{~@j@\n@"@)@;@g@AB,@t@ A JA8rA#AOAA]A!NA0A$QAܐ?TANL@mAEM@s@DhAFAoA!?@_@Y A@@*+@@)w@)bA%@VAY@NA>@y)@ȩAAz@NA@M>ApL@gm@a@NsNA|@A @#A4@Ac@@4@сAA:?@w.NA ArA̵~B&A'p4VXr{A-ɋF JNaV0$n9?;,K QZ"ݐ9 `I&ARu y.=ex>"İ?.ǹ2 o8=-IIT,;['!NDנIG4/H?h?@Ċ?>m@@cA8?@|@@@@@X@|@j@@@X @0 A/(@f@@|r@ A4CA$A @@tA 9AN#,ACAAA5fA*A@*AA@];AĄAF A0".A AA kA1D@UAA@RA$@@gA ^@k@~@jA@e@'? Q@@u`? @ӫb l@pAz@Ws@3ܓAt@0@m@iAb@bA@4<@¾g?Xu@OA=@ݨ@ @[@R @+@&@9@bK`?o?}@ӎ@RcAk6Y6`@A@@hzռ@@OAxA'1A?4@A AqABVA@7AZALwX@H@ A? ADAGA'@?˂@KƿlA32AYgAXaAD6D@^v@W9?A&`@ Alj@@fp?R @2A}BKAkAkA. !@ʬAA]Bs›X=††S]aT $uI/up lAK#G(D5grapgs=SWxl.Lɤ3);4-CH29 =}Bd/|vm8Vw&a^ pMD[&<‚&V"-GA8b-tVQkE<AY(ʲ//G)/;'Gl.9$>.U]hL~gG9>.^6돹SSxmYJ%U$Do D 9|5hsgj(Hm0R=z=3>Zn*+fNa \rpE+B-o#fʥ#~ ݼ?/.rBo{?@l?]@E@@X@[?@]>f> @'?h?&?vi>-@ʼ?y@Vf@.d|?@4@};@>@@@@U@8@@@)@A>Şe@"K@<@H@@P$@A m3@Wg@rAArA[9@ @@}A *A(A @AVA@(AFH@A!@@`He@w@ȳA@@Ex@gA A*A A-@fA@jt@ӕAN(6A&@ A + A@-A*A @\@SyQAA.?㘛ŴN@eOA@lPs>kq@AA3AWD@"Ԏ >dPAAo)AʿWS@H AFB DWA@1AAuULB3$Bp@kAmAM@@5կAfkg;J/C6NJVj_G!O8} !iըJ(ʰƟ258 )<-UHg+ean}ؾtMqTN+qy.XT1I|y;zP)zzTtC?@0j]Y@ :g?pV?=_@忡=?n@"??@?@Ik@ke@5x@+=@@q@@=@@AxAPAAOP!A?_bAL@ATArmA AIAcA0p@@G@j@3@@VADA$YAAR DA5KAcA nAJxAAAA \A`@A,6A!@F AAA60ADA@@qf@ߕA rABA;A6aAmAAM!AWl+@ն@A&_ANDkA:dA:G@ A9@:Ar@C@ 2@@zbA@2y?fX@Y@ȾR@ʍ(A/ǿrj@f@ΡA 2@}>iQAA!AF/AQg0@i$AA/@ôA %AB`A%AA_@Ak@"e֭f'\@B5>a? ?(O@:}?XlA@A?@SeA]APNA1οAQ?G@f ?eA]OAYIk@q0@-l3Sѽs)nBi*FgCvAb@@_?V@zYCNDR?0A??d60)@x S*'@@V=FΉ>wyľZMKJa]M!Ӛ/GO ,D&B ,v\)%",M)Ÿ)Kb Vm7؈` <h>>\HF\nO5q 6!_EG@䲪V Wk&{>_fa&zO#p? \(n/Y?<`?dѿܷE@:п @O/?s6?TX>>mA k @@n@q @@g~@?">@@ @¹?E@1J>ԗi@K@'q@jF@l@@?/@ YPAr4@@t@@Aa@#@z@8?[v@d@?@yU?$@(@E@k"@E@[@Q?@i@ @zA!DA%S@*A@'@E@nA A8R@T@;@}N@@aIA AM\@@%@@H@@VA wA A A.AAX@AhfKARA/E@՚ A,A9Ap@D@ AoN@?AU`}@J@bAA@A?r?o@:AD@dAk@a AC=A ,AN:A[AJ@DA4mABgwA @޾SAUA'#A @IA7%Aj)A)1AAl@EA',A@?ABA|ƯAqs@PAqa@A.@BC>aA/AAkb#AO¤ CS'|_;dVSB"zA6@܉ ha>( o@7tÎS* Q&L;zq|x4#LD)vY[4\GV522!1 Yd?EZg w0Wt?;&R`klt>c;3n>??ez$@կ.?~}y8 :?dRq/F?>6?U#9N?z?;9y?Wa@hgIdke'[[Ji>"?R?N?Uݾϣ@\S3LQkfKO!@"@7?+͖gU?;@w?@9D@1]@U`@0u??@*@@!W@Ue@?@h@A@@oΨ@N@i?n@@@|AAA(@SC@@ǿ@+4@lG@I@ם@u@W?U@8@{A2a@ L%Ax@&@@@@$@ GAo@]@@NA_A AǸAdAHFA"r@y@͐6@ a@N?@Y@15?p@j?@/@G%@y@@@hA,@YA @b@}d@kAaA#@ @ A)@ AX9@~A'ny@ F_@! @+@@Al@%u@@9A5@%AN@D?\0@@ݿ@D@Q?X@?M@ene>m?`}@t4dA]iA!OA>ABABGHBD)Bc)VƐCB? NpJ~U!Z;(4-Zՙ?*KcKhsX,7DYB(T8KčB4An[`{A='Ԁ"R!sbz?ekDbX@>C?)>.O@'~ѿ?@|G9D?`?>>:@& ^@L@t?n@ @2@@G@R1A @Rzs@ @4N@:@c@&@)@C=XAC@9@ڰ@ڿ@J@@c@A @ҿHb?E@U@v-@@@SsA"6A*?y?ڐ?@N*?~T#@?4\@mB@!p?@"?(@ӽAO@*}@7@=5?@$ @?҈@?M@0J@)Q@@xs;Cm?=X^F߭f]Km.RA?\/j!`ndG^IOoL`H WaJ6[?5djJ @/~C-l (n'zo`CVo"1Ә&A6&b$xx\9)v-?) WX1"5P9'aGK ],9G` 9b/T^wPN`SIWnRǿJ|`>?4?̻.@ Cxd@&Z@{@Ij>Ir?1??1b?B3a? @[]@t??^@8@?77!顾Ę@E?3??><"K7@]̞@A62;?@;k@@ 8@@!b@z&{I.?@@[ɿ^gXo@G^@@_@@r@wFSAy?\>t?AY83AnAS@tA;<@hA3,K@JA@ 9o@yoB,D~BiUA)Td@š6‚بChxfDûkM@hX XLT4'!OfOr03S\'oX]YQ % yZ=&G@<)w?!, W*e]P yrwNulkw2kFp|F,1 Sf0UE)o 0-)Kҳ4{Ҧ9TJ4K2ϻl1EH34u!¾_t%i#rJUVdp=@'J,9c?NUlH M\:UR o#3WAb=S,jv@ &+D؈輿 @ ;@zL@v@@D$@#gfb ?s> ؿ Ƕ@d@̓? @gDF95@4ձ4@f ?FFjW@_@ ǃ@ZT)@@ ?$@4@ Z@ZV@-@2A1@$h4U@u@$? @<N|@%&A?OA)AΘ@AAPkBNAYA()B Io+^A 꿯=wvCwC>oR?S;fu.@Ez[].H^_g*^?q-?Qe\ y9?(MD_BaK. I֛w,'Rj]Rn4s~KG ϴ//̀z܌3?a<$4#htrK& ")~`-bk"@Nqzc3Vd"Op~[.aV5%b t%Xul:ΒyPgÊIա{S5ؾUh>.vJ/@6>4@7f)?MG t@G_@UBE@=z+>@2c@A?3?'@U@F@@?-@O@/A=@1?h@Ӟ@c@@@E@êNc @3I@W@ALL@+i@?Q@ N@B@1@:j?ܦM@@(@f@I@ARS&@B?+@Q @b@lA!@@߁@5@b@-6@ҫA#-A&@AR@eZAtA2A.u E% ޿1Ǟn]y*JO5? D"xu5g70AqCĖ(gC|p52lh7bl.)CY9TG) >Fg*5{gsXʿ(|F?% vv)&\,=kjM Hu;~ -?J`.?A[?}>*?߾Y?-f?PtjAʿiuu@o2@U?7@k2?Ez^ff ʱ?>>g Ie>Ι#>?Ԋ?ٷ@=Ǯ@F@}L@!Ǽ@L~@+@s@1@Ͷ?﯊@9@N+A}@$@ʞ @&@@<\ypA@kB@@/@έ@v@kz@ @@=2@~@z@mM@.D!>U< |@Z{?`@1W@U@@1@P@~M@M U@ԣ@˓@^{A9@I@(A Se@@A @<@K@۾A->@E?xS>@ `@4@,`A@Ž+@9i@6@@X@EA+AB@@1A.@-AjuAl^NAlɘp@@"@fAW@ S@WNAJ=Aa'QxR@@PPA?k1AaWN7fŸh'£Vov|q@G#`WYpNquh;T@ FjcF(f/kGh"4uT]3q%+r/.!q״klb hz}D8m'F͊[@AxQU~:U8x$ h~ &Aզ `qB$P) [J`3gǡ8S~^!'j#ƛՄ.Ct=b$2{ n z<~'CʣMiھ=?&>G<_LHB)t~>v,@0;@m@#3? h@Q>B@ /@^0@5׏@Lv@ZJ@vg@.A@@%@ld@ˇAj_@ߓAwuA$F@ٙAA ,@@S>&@K?}@@O.@;X@Vp?@D@N?%-,HJ@Cwх3-ȿ%c ??%\!>j1l|ef0u?o]?5}g o%@ F@>(D %@F @zLmW]O@o7K(?ğB{ڃ@Arn?$E@Xqʵ?Mo@݋]@dWT@˙@@E&=- @y=@RAspk@@@Ve@A >A=AZ@0Sg?A[EՄyIeeQ?)_:\Aͯ@niEuh@= e%UBc%<"AA:RL*>H,'S8ƴM/ysEs{>/!K(X~bWg)*egЩs3n+B[aMM`w@oA8;`WqsDXUBB!d"&wThaY@^epdD38::8D3QCqjDbKVIP-|H"<9 vK >l;.o[ 9̈?5"EZڬ;,i |5Wa0mo[eQ֤c2Q,Կ#? ˌ@ *@Xj?̏@&3@M|A#7A@۸A^3A @#Au@7A@B@ٖ@u@ع@x@@D3@s@}7?@/@4@c@Gȥ?ŝ?Dc<@M%A> f0A:ؿՏAY]?_׋:?9|nIC{#wUA@%xdsV@WA8GYAȝ9@@*?B+t\AAצ@hABsBE@d9`# +,aCNA5!*C_>w{LNmW)FFaAL]83 v[oLG1 }BU7ZnE eU}0A 4 6T!wCH[@LQl]f0$X>н0c.C9$uikJw>yez@ fZ70 |6%V?ڈ() ǼL2&X *1.3%v Am ^z# (\bi}wŗn ߈w7!FE۠(0A;?Ї@ 28wU>>@j\A.}@z@A U@ơA-uAA6 AOACAVA`AAA)d@Q@.A D@5+@@5AA %Ak@@bA:sA }A,AA'^AN 2A AHA-@xAR0AGAgbmA8A+AMUAU|@?@2@R@IMA" @I@@Eg~@$f?7#?@R}@mA 6@t@b@(@ ?r@|;@y@b@VA1 T@.@=A{ @A%RA'_@G@$@yA3@2@nW@@zf @v\<@ AoӠyyAiA"?AAdZ;@?JP USV:aٽ83|XXcM/l{@0R ,FW>!(39O@ t?4uQiب 7)@7N~?'JvfM'@*>΅> @@d?@[@L:@2@@|@@@A AT_A)RAK\AcA;AoAOMAyWAlIAKTAK.jAADSAVA@LpAEA~@XA*sr@k@>@?1%@?@%(?ւx@ >@h@@@A6@rASAP׆AKAAKAJVA>ܐAP$AiA/AAUz<@A"A6@@5A$7A.^AT@@ܽA~iA4A A `@9AP;AwABPA%AjR5AJ1AHlAfx@ AFvA)@Ɨ?A#xA'V@@Y@7?6AVAc A4*Ax/@uA/@yAm;AvA?I:AuPA@uALA%YA$\ARUANLAU@ AMA5!3AgAoA_OA^UAA!/AAQ7Ax AAٿ!nAsAA@fAAoAjDA8B(XAD‚'Ռo#@ 8a7PkyW~N+RJgXDUvlv%dB#R3cr!hך,`H(b8Gy1?*LC8kK!DWu[J{ \L:r 7}wt?LHsh)P)_`@ J+>?jдRmÿ((Ϳ2&NzF@!3%"Y'@+@e@7@-??옽@;[@?꟥@?V!@Ljw??Ŋ?!Y?>+@Qܺ ?pl>$@vTm@O@A/@Y}!@$@N@}?@AvA@RA&AAD"A֩AQ.AvzARAnAJ>AM`AApA}AkAA1AMA'A`xA@FAOAWYA@h@@?y@uM@&n@ %@e&@H"?TA!A($@A S'@@ @n_@W@GAf@aǃAP@A@uk@B@/@>@ǪA@ ??v@oAq@A(=@2{@ԙA`@A@ABA}@1@ԭ@ʹAO:m@,@=_AW@c<@v>t@N@yM@۠i@m@@){ A)ABA =@A8[x@GA ~A7P AßATOAC&AKӅAA!`A0 |&}kAֱ΋)49 .-}v9&@>EF>);w A.žNXܿ h?@MO?„?c@^@۸)?y@iA@f@EfAAE4ACAA RAü/AB"AtAwA%A A\A#Av[6A|AA]ASAkAbAfsbAOlA@AA@Ճs@嶘@b@ @<] ?<&??{7*Gx>,>gHd}yZfuK;D\{tuCI: )_A*sMVX]$&m7/+]=ꙿr`! D>X<>EyGl@ī?>`~0?6@z@@m?x@h@>BA U@@;1@@AA!Dx@G[?AZm6@&?^@2E?W'?@(@=@@~AlfAAk@>@5H@6AStAFrjA_QB7B=ƲAa v>l@[پ'ӌ)Z{I@R60Β1$A`m{P!bDcAF_;xk- hOk'J#.;(Cot]&Q6UBU WjR=f̽PD]JPmKMBU#'cp˽.63*cO7 aj@5M *XQ:x`J~1W++^Sh 9aH}+}W3O:h36"נj +"}\]+_L)>j5Wh`u6GHFON;S^&0<]m{Kݗ~SPd{?UTkoY?)@qR?яJ@_>>.\A t@AgKAOAmGAaAXAA8AA A~yAk4A@AA-AqAAAGASAwALAwA>Ak8A@A'B6@r@p@|@YG?s@cR@?|@>??)>ݫ?@ >󿢘YO~G@LJgQZ g>捿cF }ƖdORkSm>S-H@ ?iЇeFaJ@ szE:%w濬e?N.?@@ 0Od%z !uZ&KW@ J87Jtſ^'w5`@mSQ_ A|Ax 4m?An@<&>K@-ANA}C|l? Ai6EOA zLC,@` Ai@D;UZx#yV:*J\Uh$+zxKMޘkHA-_ s6{Qb@0u.r {>H0dGW8Ŕ7.z^ T!5GP8Rz1*pZ[YD}]>S'tLj"Pp$< ^D4bmo& -*#],(DG $  3@֒&q&;'" 9OPEatd q\F3O9 0D<(I!{$E7~J$*y}Dxg4)e?"?—?ZC:+z@ @x@h@@?@A5,A"@YA,DA*qA9A:A AmAAABAAGAAAMAiAAXAA|AޮA]cAAA+AA[@B@҃@m@z~@@}T@٭/?-?p?`@,@@X@o; M>;= Q@fj[@I]ۿzR̐}@I@@0@$?*>e;JsU@ ?ˆ>@Z/ #lؗ;:Yz?sHBq"]n9-d 3na>Ohv?=_TϹ a=Nv(>{uj.@sY۾<@(W?2]t @Md??έ(?MP@\(?bb?P#,@;}>%~4??'?Ov@m6AAx@Fj/@Ym@fA AW.eb_>-yۯA˻@ҷ|,6O @L3ΊdYuHfq?$|w %C>m ~pUe36nnyg}]''/cARp~2%>};@CX axBDx=W/QJpXHb lK^0IAp!yY xkt@u+_+Ӯ}'s:%`7>7{w".K"i .)6 cIr Ca $>^:ѽRyh=oc& evp9 /vt<$;/ CK$#=d+}:2?˜!k>@5__@i@2K@Q?]L>U@C@@@v$A]ATOA:AArAV"AAAbAAxAcAAHAAA[YAAAOAAAGAMaA3A A=AJAZ@@@@Ƴ @J@RA:f@A$@@ʻ@!A z@@L=G@i~@ @v@C>^?r@a*;@P@A'@h$ ΞcW L?@Ks>&@rA+@@x(&:@*D@6~@{yD@s@.yAR?`v@bZ@@tJ@ͽ@f@P!?APA@t-@Y\@t.aÜ?JA A0,~@!n>K6@YA#B AXZBA]$AeB8AAzS5 ~!p>xʿ51\I;3舟Zл [X^@Say O oRd|_+y"#ODlO0l6s%'sOcjS?ep;ދ25-G|[2ض;t"W2bԐ3i$RExȗ$:d0 ^lN@W7UFgV˿ϓKOrN?;*Rv#LglnT4VG#:޹toX~hwҐp}s-nѣot>[Urٽ_=vxͯ)" ?[jV@|"@@s^@Q:D@l~@R{@jn@AAEyA]WkAaAˢAOmBBUBAaZAuAA7{A`YAWAAXRA_AqAPATA?+AUAz:AA=WA9@,@p@pq@@A&> ??{@.@@@Io@)@dm@JV@2?3{\@!@qZJuƣ@C̶?:dÃ?lP@u1=KtڿV2k`Zk?cAlbw?q`߿k_0ٿJ>7']2,y2>$ +v›I>S@{? _@t\Rsb@@4@JW@Ԟ@7C@ݙ?7@U{@oi? H@@BA ɦ@AM5!@%AF j r3@Խ@&:A@SA73A%AHGkA#@BFٿAH9s¿S[[lϵ/{<;O1(IQujAثR 0OOct_D3,)T2$chpWuRe2o(vK,1X؞SA{Aգmے,a`L*S*7>L&&osw3-scJuL?yoAybU~9$6 .4GsTtc*m`[tGO|hts(@ቶZQA;)-bC<*-njyyL?0d>kfk>×~?#@IA+@[A4ZAcAYB ËB%_B7XBVBL'B="B IB"'A BA xA{AADA7A&@!@ )@A>@9@9@"@8@F@D[ 'YGp ۴oyuT+W|7&^6&\j+wZ  6opEK& CG5 %v[^@>)ozfc(i#s*|"m_uI .@nNj @CO@Uf܋4@@sm@t+j@OV@|wz Rk@%YT@bUA%9AAӶSyA5{Dd:t- ƛ~@A; )AZBTݙBǞ†ylx"3J&]A4@lƾJB++IT?RAg_Fa7dLV:c^UB&@\ $ZFlPA_JK" ѪP4J;]]26L= &R }#9G~=Biof@Fl7S\[c QJj@R`x0P)°;A%Љ;yWU-mj^f)KF Q[ eU+rzp{Ir;Z*$ORfwdL\!P<S !"ń&؝aacS :  |дv/w)O+q?-@u @xA{AB>WB6ӇB}#`BBt%BVcB'4BzB $$APA~AGAWAn?A"Ю@;@_ D@@{h AAP@tTA/P@)@V@X?DlέWd ݿiMi ?-g?i;a:, e߈&1,@|6E-^>*TW3/&HQh2bpdgvY|x'T I;T9-),-[l?s#^_4IO#% sB-n=)?NF|g,pj0p@{͏ci /XoXBA|@R&- "kw AA>>@ Ͽx~B'AŎ?(AS"@x&Ws##moSDDPMqH0HY":\Km8}zq=xXh@B.^{-+-g%,j>i ](B.3mHj3+/T̓a ֻ d$MSi!G c%.,f[On5d0$kO`"BN(L.fv~RvsMt͘k-q'iSeoJgaU~xNVQmC R1: Hgvkdm MSzCeMIm: Aas'1&p1,@&*eA*UA@AAϑBBPPBBBB+BY BHB,oB7|AAA(AdAd+AI`A 1Af@ҭ@@o@@@)@J@Ia׿n=Cy0^7ʿQW*]Ф+7 JfR> irōx̚1a9Un?1זB靿E:r;'UH"GxQRK [A l+= Il'toI]66/~<uO .>"G=s3lA (}F ?ofm_?UL@.TjE@A[ BB Ao5CZMې dWm3V!|Smy91p7_I"WܡVGGu^uDãEfQ6%GN+LB׿։?z.FKPop8|{+%(&7< L`/f\#)!ej+л=W8@RbF;Ή#O P>  x9 4x"2 Od0|.5{ERP#R2d32ʴo--j0,X͊6F2nç3`+{O.)~ ?]> )8sAyed!6+W6OcKxcʿN;@0Q[6S课i"Jr1@A 0AAB!B{ BBѾBJmBBB]YBX7BX`zBU|B AzAFATA]HA4@%@A.\iA*>A A\@A 7@IJ@I?vp>@ZV@da@n6@ xi{>,@NT?ߝ@'?XoBZ7?X]@$hbe=?6@?j@[>ிНþ9,m]?V@f>ЇO1> eKjP=F@TzA͈h NPc(Bp-IDiI|Z H3 eg"qPu jlHO\MABKA6Z[RHWH(.yUtkKEtj"'~qH_hFtSiD$E ;v7ˈj]^$B_)>av~"h<6FT2_-z@:= x*I2bHX}#+8)_LA.szV3vן4v02,wE_7>W[g ш -R%ҩ$l=rI43/$Iƺ#JE'Z6l+,F9{3'7\ $Fm'ZĹ e- I1;w%.2tx~`c$5c=gz #%謅a'zVI\ZsT (>@ Z?I@ܕAIA͙B$BI=BxBΡ2BBZBBwaBlJBgBBp}6B)cAA;?}r@{4?E,@I@@m@C@ĕA5j@<@>|V-Ă;g?0M:9>?L[3A@Jfo?Fxk!e6kFMr:=!?_}c#8 7fy M,5UUҼ?~?~Xb XL3_6^ o-Hummlԅl`YdAm9l9-23A`!y׿N,eH@I qcf=(@?[=cW(.s#бA C?@`7AA;FBB2yB > NGpftrq>(%,>r)(ְ̣s?_.4Z%'~ &W$W?Z6YE-~o}dqM b Աջ>\SZF/ l!],Aw0t6wvpbjRT% e$SU/FTN h8;kd PLpv)XFHAIpkar|+CP:zW@NJ-[XV\k%swxo0ǐ_]^*2>C{sC]\rl%#X> 6Ry}8mGwX,w u |:r-gdw~eNo -CzVefsz }D_Kafcpnuvhe2hj*Oe~ zkHeǟ~=&}֍:NOJ5=Bu%D\*&em.nl}@/IpȻ&zo ?JuYy(?"@ܝAfA>B#BvWBBB C CbC7wCi#BEBBFB%B:zAiA%!o2S?I0r =C??NZ@ de*Ϳٵh87d Ye7+̧Z/'5vz/VVX-F*Z[ @&YZJEg~ L@T?׹D@<@( J~A;AZn@SAPu< @W@- Av%A,:mr*@ H1T%}LN#@?Kw,@em(]ٿa.)`[aRi%]:p]n&J?3jrpU/:_uc fnT- CbB 2L_!SYYkfB:#&3y/=˲ [ qI]}:ukzmeW0Q T WӀd.^%f{|]RusDS#~Mn)(PP3A|1u:1R!=R 7WHfLAVU@:"31a>zQͨ4`AmP8@n9A[hA1B6OBLBBCCPFCΛCg/COBTBBBRBoA6`@IurA=}YB?j²az[f9-RĉRm' OEˈ2tsbFbyϳ3Rv}`~"X6PR]<@1:wCzv3f ,Bnd$4xOF#˲ՍJ`;$:/ TW D[ivI-GP9(î7Dls>$z)/y\TJ3wQ]%YKQ__ 08:V?%RzѿH#X1.T[]R\4)@N1tT @>m"A-@i3AeBS9%BbQeY-AK+^Ac3M>϶1C@S g{K?nA:6G1k@Xfsq lmJ9x[2[ZmA=_XcVr*2(%_5dQ_E/7MKp9aI*Az_'gEV/K:C:]!6vXu. k#,P(Sؿ8+B *"kbN jF2`2KBe!CY1+V,;_;-j^Yw07lw*ȒqbfPק')/)&j#N J8RiN<`;'^P[X>5%] FTrunYR{j|M'{HgI#WW'kO~'6"z H$#ܿё@5@MA2Am(AdBOB0!B~C%CC CnCcCaBB{BX8hB A"A)@ah>R0OtoVTM@9mI6E7!w?̓=q!'T*u `ZH8Ij:^;heK'0 K ^wA3:%~fhO'/nC._nehY-)fy\&SWs >7x$T H; _rR9L+>Wdjۿ@dP@ P͙v@AۿMB@!̳AT¾ѮA*ijQ;_Zcc>P4[FxAe=f~^+ Mj|RFbX~Nn]5!&mp q3}2X}R ZM(NL8X+9]- ˥y[+޷Dٟ0 ?UN)5"$:W9\4M\$ W70LFr- х8)ϜGKq8 fcA2[4P>-%6ʌFo&@+GL jaF!>vPs;kX4B^μ;W^[p|#J c)S 'W:C` E^C'˙9p@XAVAtAA-rAߟBC#wC[C)CCHC<BՄB^B@UwBA@ M@?oh?Z=3BY(-z c? zR}?Vw s;<'=C$_  VO~4?sFۤ('%.)G5oBZt$=Jկ#H^a$Jp[6"]ɤ'TK?PEfB|DLYJcȾ ְ 'IH[I>@Q0:?@lAawA@f[yAL#ͫ%|?-*=pTRpA{A+rXz2O!BpAAAX}hmwyxywZoeUgY%Rn1Bjk&m;M/d0FKx&(}I ͦ͑Rm@M@bo?\A]sAAAlB BrC"JCCa{CrCC2+pBaB^vB6BAHAl@>b>EؓsRY}2.Y,4@-sY_'ixx:L5 "%Kr10@,:- V=_!O b'ɹ$9 A(A 6/niVK@\3MnN G>ݕX-kdK|h 1eEe+|>'B>W}xm?ҭ @`K t9q]@E蜿Rz(Aʆ)y-ÉhHc/@:@aA:s+gT 8 'Fu#<ŠFDۡ AfAK0 @[_ta@AcAA@z> @@bA @\@ >`'v?Ά? @=@@/@b?E >B:Az@su@~mÀ 䵿!@LK:?HpkL]@窿܋@ ]Fu(t+M -(!iv..4]MKic_ I$e.Dh!q*3 V J6Yn)9% A(y)-+V)mzKo]x{ӽ]6$Ou2:E3n"{W(7G!8[nL%LjvG ߍHrF.T-RYJPr7}@*>N@-@A>AFBorC1CjCCC]C^BB>IB A"AA[@B6_gX#µI40c6ω0)([d-Mք'YҎ2LN->Q@"V D4J.F)%j+Պߚ%3g¿ Kjk>=D%XSvQU-BH1B/xUC9"Y 32j;sѿ xs!-`! -@@†@;2߹*_B?4@u@ؿ5(@!A@q@>-X9>?=! kHK7ͬ .\6L0(#=Dp .%l4*3G)܌"\5QJ&(g?M2ct$9^Y6?x@6@\A/&A' AztBIDBsCC]^CCu*yCBBTB2BN B!BTA̔AAGA 1@@"Y@0>rLѵf# 3q0,#eW6Vvc*6j=9EGU?A7=d͜9xr_L9j{6b^[T^L3B+I Db>jkY6Ȥ0+g[9nEs}>{a*Dld*6Olnbx1DSY$Hm!0|Wr o+ν 8>Lc+$] 3>jSCSl2࿣ 9@t@9<@,-Uh<)p@dkxAV|@L-5/OB?@Ǟkmq D9@$w>rh#']jbJ;IIܫRĎ>9(ZhDkoGw-RB)V?Q#jR@P>X; iA>?-@Su-|^)"'I' $1Y5 /s Q6菿@@^?5m?M@š+D<FQ??I$b,L(N>;۾>ߺa'NZ:Ǖ)?P0g&oU+6r%yaJQѦʨ {QRPJ v/0Vg2 !DjW\|͗A` "bOO,wfj*ڊ6!%p&_F^U.B?@?u@)?L7 h=s"ei: @4(|H}^%g^^iBs᝝旭$t0E L,-x+TA[w!C6Da8ЩM2X)(xDL >_1ɣDsl^hb>îZ>< '3`ȿ??6@@~@q@wkA@j;'@rR_Q@P+u&Фk{&mc\?bAue.A_^(@miqуDpLwAv/)A @‰j{oq>"oAIA=?/b@@8?ϊ@Kl΁@8#@>IoAl>1k9.0@ .dK!He&̢B"T<aC [}tLbW+Fv:&}dYg'G&Ցb {)1M4Iy "2]N;Q)L&6 X:LbmcH0SlT^CXJ5`?o;eG"+V}6`nIGY{@DB+ 2tY0 Bgq4-0N03  E0 GT@Ã8RLcxv#$7hȿw!? W/@'X%c'Q`Ҙ @E@@M@@A AA%Aš`AB-@B>B`BC3BQ\BTWBRBGIBEAYApA6A1@K@{A A b? G, ? qz&n5o6+[/ qq]I? "l?y)=A6DC鿽5L%>u{C~V/}^T/ R?m W~hdvqlR7HSyoH4 vF *4-9UcOm(V\VT63ѼH׹ t17g%"mi?I#ijc`D(DlE)"jXy%vNn&3_o)ucW ʌ}Яp[5A LPљQ`q"Y-a6}ܝMۛB:o/Cؿ 4z~ Wl@QUrz%)=}ڬ?D8{=ӦR( '%\ J@@G#@??i>P>0@ q@/@/Am@|cb"@]>yAAu?3r’c@8]'@ *=hA\)@yׁ,ɍ>?S"de3R@. @Lsn9;ѿ3@BrOnb sm gmw ?@)?Zv<*?5T??@*>O@&y@K9xD#Jp8P Ot@YJt?NI? m>0'f(;OבHKm>U$(yV#1=TeQ PeJ-~SG AnMfWltb0zmbe%տ//)Q #>"޸?'0?SX?@YD@;6p@?'Q@1$@ ?"m?UQ@>gPs@8@&0@9AACAAFA BJB)B;TB;NB*)JB&B3#BdB@XB&AM_A`SA*A*A=AqA3fA@y@b;<%"??KH,ݜ1790D#Dr q)U NTicY^# QRYp "F2bUz >l3]q*''R@%yOt]J;N3vRch BoȒ9,jP N?fk#"E/%QVTq.@dMKp(FuY_1{4˝*`zŵ!7VUS@g@٭A@7nL@)@+@ .vcA@_'v @/A޶pt@1[M;E@xA>b?Ž4zd)@9ev4@Do/U?u@@a?UV@/:@(h@%?&F@<@Qq?c.h@AZ?Nm#/2 >11_@4G@%uQ?>A? W:?7?6ZH|Y=4ofQs7*3+)!WN]?mڐ{WQ "F"hSVc?ks'oʿD?D/&><ME`?Ng"?_:F\shoJ|?GVDImIzZ ^@:) ?/'`@@7@oAA$9@wArA$A@A4"ACA'A=FAaAUB OVB"sB0(B%yB!v$B-pSBIt.B[BJ;BsAuA(AA[AO7@4AIAAAC$AGI@0cAM@z@@@?n@@F?SI?5??0H iM_J&AV(CK?@ O XtpUlf^>y=NA?-%lJ↓s1իYG3Ω>*Ymow$þgò?YȋW")ITa @He@ @M#[MT?\|}m2?_<>UFd~C;;Z.@?zZP @NCB>HA,Am@d&?/A6\@@A?@F?O8?LA$zY@*տ_AAv?@Ϫ>.AO@b@٦AvA A@9A<@yA$ ?g%9Mo@OQ@T@D?@ZA @f@>e<;@Ts=n\@BS?>@M@Y@@?@3@!!@v@FW-iף3v`%$?,?ɿKhm?Li?忒oG俗^lS?U !Tu@((@AO?~߿6 ˿rV&^usUGII@B,)VQLt ޾bjf6Pr\ .W\@^ @@w @ǖA A'@䆵@7D@JA@c@cA'mAB_AcA&ARlBBmB&EBB#MB.9BIA A-AQn@gA@A!@A#`A,M@ @h?~7@@ֲ@@FF@by kk4LM $(Nd -+8\@9Ywd=E +}^Tx؟IZ_oDO$DJ#a|Ry{ZA^\rHf:eh؉xjh]闞2GYT6%}t]G7&v㐿"l=u m?S@/JЄ~9Tf5ǶZx`@A1eN<7Ic $B;t@&Y4,@[[@cAPoA(@aÃ@]@ŋA$A '@>ͪ{@>A@1?Ӭ@пC@:s@#@d@?MlDA}? <#ʻ<@۫@3@-4@2˾#= <7Ti|'cD!Xo5-#i'㴷p?!v>7^Y(hI<H>y>QP#:I!M3-7Jf,Urw /\aTe~5 _P>&= ++aUq"d"hȊVՓH=\ 1 =O }V?j 5m@o@@ա@ՒAA9A-=@AF}A.:A4AKAnnABBB\AcAM_A-AXADAuAtA2| @!@$@T@Z@WO@I3Aq@P@?ZF?'4?C?ї@<`¿8 օ؞lל[2y%3QyOb.p km aoӠY qnf9A~ 0ҳ2lk- 8 xuϵ޴R#Tì8<,rqR%irwk@9RfB1=%\VeBp d2C?bW>"w@K @iM@B3@_*/ޠ@E@EAF.A$k4A/L8*7Ů?M@Aw@%Q@يDP`@&ٽ@7@?s P@7ᠺ?uaCqLۿ?҇*t3֪;[nWeJXPp@u)֜`>2L?ycR?zS_#cP` akR$Gl9 tqu(Gz`Hm?c`BYM]#>w!PENP>Nvk{%fG +}P; 1hmB*E_:c4,%U,ܫ{MSZ%;J+D'1IaM #+7 {/&24 W7D9p͖gvk?sH?O@`@vuAAAARATTAEFAABBYB~JAAAA4AmAAJA@@ @]'?#?d3@z@*A b/@t @?H?'W@U+@`@l@s@'r&! V7 8N<==<ݞeVqԿ)lTv6&UT?5=ޖ&KX51.8&m@B C 6VRL&kٗ>ףBi?@VP@)OAb2@/?M[@ %?/?6O|52(yBJI AAaU h]=A 9r@w cu ?+X{v@?*aK?2\kPA=EAKC-rwWx!g{ǨE QW@y+>D!Qg?cWE3Բx?KH -`Ex (76@VYl?9r@0>ScPeVb)mV@F ?,ֿTY(@@)>3L{x@6qA!?G4+J<@ZW1XP9j{!L* L CAqſxh ˾B0?os (lm1ؿ !a>vl/޾S ?U ?D?=.쿚6 EA2@$߂?iſK迉?EAAA>޷Ak\KA{aAAgAkAnA5kBAo{AEAFAݛAAܒAAcWBA@AA @0ە@@"@f@ F@Q@@#u?Q@@K@8@Ο?voSh&2(e20<)Y5N@E]Dl{Ԓ>%E/Jw@2T\/~:hA i@@"4@近V@X a?ə܆@wWEA1pC@,[J =Q@>_>)7@- @?^=I=y?4@?J:@tva@# +`؛r1>T@N @o~?@Ƅ@ @WCTU>)j>䑹e!+u6@TK^ ^$Q*G>Qr=w`%9=(@4im?v-?Ր$@a @Y%5@ku@>@%\ 3t??X\ҿ3?_?wWלe<1 AxF?b?+b>ÿLX1?P?⎾O6}@/@=U@'ǿ-j@Sm@'T] ?h?h}? @h@fJ@ZBAiWUA~օAZAAeA`3AGAǐAۮAf A#AVAAsA2APVA"'yA;@7@^@@ x@@FdA @A@bAKA @A#X@KA5d@K@G@u@A)]A@@y?Ue?Y7@Z>4@0>ݷ@ yDʤ;@@2a>j?m?o@>]i?a@?/@, AڿN?{u?>\>|n?en?!X>$Em@@k0r@ ʕ?R'?@ƈ˿OƇB/-EEǼ#;@Zҏx|E)&BFv#ߝg'FAB= NA ABA飜A AAG@ݏ&JN(F4—z"jY?~ ^?'A@ޏb@4c<&@ʕ@bA@YA/A 3@ @gm@9@Ap A@N{ ?ZTbsپ@eA&?@]cD` t?6"侃%kk{?'HnW^&3^@-@YS=5? w1N O ][@Yk@&@'2翷b]l?7O@b=ﶾjY?B>&bGbXFzZas>mT?Ɋ\+??B?mG2x#@#QӾZf}+VӪ`a.@ D"6?& ʻX;3?P|U #MhafA~ƈ&c@F,Y@I&@8s>/@z@c@AA9A#ZA3A{A9uAthAYefAStAA߷n@U?@ڿk@a@ݭI?@ܞ@#@5@w@R@ ?H?Ã8:f?|>9˫@,2U2.uES$Ie俌[׷ߊ[߄IF(E@,x6(7ʙuiՕs fg:RJ-->M#mUՈP\3=~>L:%?QF@s/@!P?퀉F@-91@.8S @Y+%X ']@HU(oSrK N(+R-[Aze@rcs@`gA OAHA,AA&!A@\'A^H[;c@^Iq%0 @@BA AC/*@nAȿ@t}ƙA@@ݖf@$t1@y?\c?ƐPP@L4@fA@EL:?nI@/>ڿ5?PTz4@ B=fPc@K@6G?|eP@V7@?-z_zk>RX-@>}?\u>Il@$@R߿@ f< @ %j!!*0(?QV$4@&ߌ'MU c&_O֏5P|L?2WXC]B>>|2bp Oո@ k - ,v56(̭<; ux_s?'@Tsv}8)} Hʬ+,Ep>F(I<)0QSei*פv5s j!*S>†r?'G@@r>+z;;4xA+{v@V?H:[7A*lA.Aq@ MA3!BmB @9-\/QAc4AſOm8@~̍=mAl<@@*,@']@i*WhA QLN>@MSA@Rs@3M)@l{@tɾ6?#:pK@D?>~h3NJ@ .^ֽ?#??]M }}@*@"[(@3>':@,HzQ?M[=@f d@t?Ӿ=@I=g[B.D E?{#tP@cg@@0>)w?@)y׿>lJK0 9??Pw> f) 5۬^bh ݈ǿ%x@^@@MR^AX`AJ3A%VA?A A@@+s@aA,pA @@Ԉ@8@c@>U@@6F@z{>jC@v&@ @@@? v@D@@@)@f@ܳG?Լ-Y s־NH%L$yVg7E>?ߒL+[]oh=dtCche 4C@ GG򘾝P>0ZR @b@h`@^@.1@+-,+!$-E?Q?K?s@܌ɿq?ş:A*8@wArI@)\~ASk@FA-@v>@A~A(@@14Wh@AI@aALR'Ab@AQQBW'Ba@q(S5NO<$CbiՐ@v:WJ:(a/_M`@U5@{U+֛)@T @i @(¤G7UX>2⊤S@mZƭm@:?>1пe ?[M@x>sE?c@DZf@g@<.e`@ž? ?mNp @0vͤ||9?@ @@.?5@?|v?;@e.@˧s@X5ae=ſ=ʤ@#?^qJG?^g@| @1)??R>~?2Y /<-3@r w Ot4$ݿ۬3?st3ֹ?B; =gc &?ـL Y?;??@.@{8?%{}Zf@eb@+[N?ĩ;ى@Y?o@;eTZ\A @@@@oA9*aA @>A`@!N@QA,TA @sW@X@"A C@AW `RI@?=/@` @¸/@M0xߦ@=@r/@@̦AP$?S;@Ft[>fJ?sJz>"06A<AD>$3Zz[?$%u"')0 4bg3aF[-ĔyQ_' +p}/?oYxpYFFlꤼz'lc(1k{2%0=DJ56O?Wƿメ4D7.$+?T[An?߽A`H@.@IkAx}Bc0AnhAAyXz@!Oi AB-X@@<'3@?APʍAJRx@<@X@Kl@fb?3A@_|A3-A@~@Fm@I?Sm@@@@h?A?bc@I>ź@nʪK ?@G@s@M6ǿF^Ks/@%?A,' hS=O ?m@Cv6}?AB"lmY(=GJ䰿W*?bM?@ѿ 5%]JA?P@da^@.?&`?U ?}P(Ŕ@` > @f"@@@*ӝ@ H@%@@zc?A@?dyq[ؐ $F,4?9Y6@fhi? .4ֿ0!U+Iw~>?J?˿h?@I@P@V)@'@H@#?-@Mz@H(@@@~W@zG@~@5P,?ao@UA@[R;?R @V@_@\-@@}@NC@^VA?@B@E^?@\?ӂ?SFP@0:U? @@@ }?@N?ҫc@@v??G L@g1@W@&@ly@q@JT@@a*aA! @8A @aS@ţ@zɲ>|R#@f@J@b @Y@j;@OGAAJ@"kA*?T@O@ @C @$b`?^@ !a@0,@gf@#2[,@> =lgV@4c&AN0 b?M>;¾@5n.@:(f~A0AxB B;AAG&T@1[A(AVAj@@~V'P #@:&l@1H'8-@8@D@ @^]_2AW@7ASi@#A3E@@ZAA*A(6@0T@>۰A;A:@fL@zOA'>@W/@5 @?JJ?P~Ǻ@1￱@P@gQ^? @UY@ڗ@W'@.\?ͳ꽘YF? @ @k0@6@b ?E:@县-=?!r09HSv3?sW=&?X`@o>.?#%?yxU^:2#ۗ0?n?sDŽ?_=F@?ٯj?$?/o@#@c ,[?M@@(?͕=?hh?}T?TՒ? r?/{A@@_do@dR@0@g@oV@!+@H@@C@l @!H>:@ F@|H@SZ@6@ @E1={@oj?CJ@@V@@@ @ @@_@b _@V @-1@_@2#7? @ϒ?}@Q"<@&@@@%Rk)sCj\Ͽ\gQ1? d*2QٷʫU?s Uxj6?R%F@ F?Ȥ?>I@s@`?C`7?\k9WR>b @]=?@w-?_ FW@(!?tM&>Կ-2@n@9$>hο0YApN@)%QC@B~@-AN @ A@ߥn@&i?O@ 7@ A5Ak@%AQe@IAtg\Q~A`>ARZAݽAcAK~AAA@p@֊UAVA0bA%Aj:@GA-yCA>hPA-A A@@7@HAFQ@0@R@}5A5s?:w@frA2@sOuSn@oݓAV@"|9@d@R@X@=@Kh@r46@l~?=gA@*@p"_ >>9@Ģ@d@=Lk@&@k@@#"@t@?@@ ֹ6@>mA9?@GA @ @M@t@(>I@m8?!=K@!@p@>H@Z>C@-(gԧ@7O@TyIhc?׋S9zL=%Ny>m1?)ln?>,?uPTfD]{ӯ3NS?icjo6gʽذվh@0&?_x@?@dB@(@8@x@?@@ @@0b$&@/J??-@.@@wsAO@@){k@*?.@f??@1@@G?H@_f@Na@kd@g@m?j@"@#*vԿ8x;,z?jf?YFD?bW?萾X&??"?Wd_"?wn Y+ǯ2q8??Q@j?@=@/~?F@x3@Ŀ@Db@@%%XqF@s@JhUI?>󽯾B?~4@r:A $YQn @Ȟ@pz@w82@DS?M@Ax<@`?>eACHH@Ӻ? E?[F@ S5 @AZA`@]_8qAMAXHBN;@B$#/ժ&c䍎kq\@@WM?{7@\nJ@VFA%ɐAe1%-@KZȿ?ݶ@:IHI$D?/ K`?`&DZAY4?:Eڿ<%@@>6G@;<@z)ǿ누?(?b1bZ@@qYA3@I@R^%Gl@@@%(?}?l @z>#?]ܿ %@+o@m ? ?G @)}@"v@o@Wf@-?e@?@{@-g@@3@A*N?୺@)u@3@֧@NM@]~??h>uT?ځ@C?@$e:?@$e?> c@@R?($?+6fP@]wqҽIk@,@|THxI+&?f]A>>dc:`%M&%Jǿ4@"@@-tg@@@5 @`@x6@³@>?a@̦Y?2ږ@cux?G@@̩VS?P@U?`@@$@Y<@S@@ '@B?T@R@@lsI@<?l @1@@X@@!a&@0?;ɁN@X@@-_U+@k@8氿W,@\L -@`? I?g\7-?^@L> S@}l @=?8S@a-@X@"@ A<@n@@Ԋ@'A/@f@q$E@Mþ =ul@U(W>@ٲAHAD@θ~A @[@{AJ[@ Ao{A9I2@:A8AYuAcA aAjmA9t;A\^aAF>Ag ARA6@nwAUAFRAA,n|+I?Հ?A7p+[)F$# v'?ڳBk@>1@y7l6u*C@@SfſI3f 5h>xR$;5=|݃ E|0Ew|>y=x|@U@-i?>}@:@,rk?ņ@<>&>j?@#U@Hdy,$8@s7PLbwE?؄>Be?*Y6 X?S@?;?m.I.<Ѧ@$I@7$WnL@L@JQAF?զ??fy??B`<4?mr?[Vg5@(S7jGd;֍AgM;?̿i@f?PaGE6yd@g@ת@@NZ_ ÍZ88@M_7?dkg ??-@b@? |X? T@b@ǚ@lj@@@Σ@.@8O@TڿQ@UA#/@A@b E)C1@Uv@yv@N@?6>ܬ@SW k?@H1Tҿpz@ָ?Vj?gi?ُ(?,l;t3!G 24T}aMF,?+.s]8Kt?AaD㿼_¿O{?;ό($P$l(bsO?jԿ33?tk5*@6%~e-Z !"6e g<:$oǟR,()+`dZl?(A@#?@]@i\eA6B@̀?@ 'A*@QB mPAlAF<nA[@gAOB AA*B1 A&L@ ?:8AY@rAG8ط,@%D=jC;(?j࿨6=6?>ȯ=?,fĿK!=fH]?wUZ ,iyiu>e_yC΢o22L@r{Ml=@5m>6e*Ymduٿp NBVg˿^uҿ?ZtO7(#>Q63߿fNJ.MQ-N=)S’)Z(=?- &*}Z8O@ @Y!8?^wWwX/>Dz-27? @/?c3)lV@vk@E$ 7?r?u3@?чx??kq? ;ޙ@&*@@[?X>@ @z@w>\Z@ӿ)u@y@Nƣ?K? g@p a@dh@c@.faeѾ8lb@4[@W]A.@n@!@@C@tzp@@ae@9`ݿT@dB@?1w?o@#eAAkA,@@A@ Af`vA2A ATAUw@R@GxnA!A'?[tx@'@d@mec DZ?^A@LBx>z@zN@b=Tf-;(0VzA.FAZ ߍ#2 eA.BA?5A~BBPrAWA1@ h@GgGtF8A @p@,]þ AXt*A-Q@@y?wAg@$?O&e@A?%@-OA *@X?@1"UAUZA k@c"A;@ۈ@X@";?10@W6A"A JlVb'@ @x?6N??.An@0>@&@y@=@A?@LA@rg ?`at@Ҽ[~?H@@@t@[/?˟?u@ r*)>S-݄? C??>Ti3?.is7KtqpH@bZz @Aؓㇲ8FGR1?5t0nW6+ >*P?ODc/2@Kː2S~]>F?G9e$% Ϯ>?9o?u~ٿ0Jd?^@ c@n@J}&pf@(,}W'?UD>`Ӹ>T??@[?ƿ2?1@x?.>3?%c@)>:տٓ?@*{ۙRUK)1NM®cuPGd2@?Bl)NPl{ wA9Y(w^֖?cLL7q:?H220C=U>'Tt>@?M4?xbՓ?WÕw@xk@@.@5f@@"@KY@>)hAAKq@z@C@X@mBd@iwA@2@PA@AmmA@†?1.@?-BnOAB'RAEAA&=ATAA%,AvkAkoAe>AaN@I@?AkAxA,8@4AHAiA)A>ABlA]@OK+?qA"A4Au+?Q@Z@ACXA=!A5b*@씜A#E@~A4~@@0A4͠@@_.@ ?`+@A%?f@??Y[@I@ٸ@>F@tD@@W@ġ@@@և*@湼@/X@iAN@&@@x>@bF@o&@0@ǎW@A@hn?9@ԍ?koI"o@v#i@#>K߿OksA66<2K ק .XN w&SJY¼v<eP\οῦM<#F@#%@JdK>T@>@|@1B?c@ҥ6|?jT KI@Dx@?@O?@[ t@x@@Jc@g@:?R˽AXG-¾VY@6NOn>.7ث@<<'@5[x5ſtg@Pz?1}tx 7%év 3V>'>ZRS?g1=;⾜P1YA j}IT"3?_c%LF>?oyſ*7+?dzU]WW?.dm?pj3pBlm.u?0{#v@?#!@ ׭A\B6@$@@a@H?A@)@ @2̿ @)@l8%La(3AAA0M'2AAaAF%E@o@#1@+^G*- qPf}WeL#^@v9 fC_3`5 3T>},9JTbTw UT,DQ!Nj@_=>5^sWs>=rfN?U@4@"n>;? k*@)">@·A !?>U?Cc?-@]>Dž!@y?.?@x@1(@KUk@.@p@ @@<@,\@A@f@n>@@Α?K|@ ul?ΐGd@Kז?<cN ]@jN??ɨM@@H?i@?@u??.?M@])ֿ&eF6@?J@N??G&?wbWyFMYbpg[@89H?H`{?>2?)ڿB?}Uv@("@hyd@>.K?O_>^@7@F@"=@p ??@.@-@.[?g@'@x9@ȟ@+?? ?k>ArG@x>@@;?M3Kʅ@c @@Oؿ>v?Y}?k@<(@?CI?y*@4=i?>I@ÿy@&?B@?u@zD& S"@jd@L3?Sɾ?ÿe@IT"X XE@1_CO@xV]?;@= @S2?h"A @Ȗ=@[/@ݶAy9A@WП@AQ `A+AB AdA ?۰A^5@vA7A+@dAA^AT9AhA1@|RAbHA5sA:@ƂB)By }B8A4(Q@/nuM3A9rN)k@{V@X:A @K9>~&&p?0o50 2@ J_\@E{J,uDz:H ґ ~?&g?xm@4NJ@pH@9hWL[>wS= .R?i*@fLX$d@',>we[?d@% ?Fuz<^Z u,@b]t̑q.#JlT&Yy/C'ڿhYY8C?Wp1i޿u?`TuF%P$ ?@f=#빿3m|[7>i vUJ^Á?>t%?8wEf?:ɿT"@j?l2@r_?Lz>$϶@bh)?8/ ??y\@9O@-"2T@c<>&>?OdN`@?6 @6$@3@"?Jd@J҃>?e9?YN澽?8">󿢳=9oEӿJ?I@MP@J`@@HJ>S=84~?l쌿]]<뾼D$?ףOo!Bː~D |-"{EJG,Jgb?>L}fĘc"G?iZ@!Zÿ?dPl`@5>Wgm @CeI`O獿}%@p4 @0x Ww?L?z>^DAdy@ jj@5ʬ@@Jh@p@t3@= AKpA\;;@I?Ai$@F@٘@l@B@Fڙ@@~@YkA@uA>#EAO?'@O F@\g@p>.`@]?? AfϿ 6( lꐽ@ځU []1:;@l?B3ʱ/ſUϽ>Vt? py1@ZL!ɿoU!sc)UOEa9\?ȍE=}fGj:Ng=kxWgؽ{7kySiM}h]#ŕ8H&?"jL'}$Sp+"n^4 LrvajUۿǦMӜVv@{g>}=]7KAF-ҥon]nNƑ!CWMڱoe>~Ng?N1-q>y?@cڿV4!?j6?/@^?)@@[3?p@01?I@@P @u@;z|@MI>'l@k@h7@P#A ?y@2?? r?@/??d?B@)@3s@Ӱ@Eu?+AZ@ʚoAi@A @kBA*@)@?@;@=@B_AuAꍿh2+@5O?+@-\(?P@@J@c?i@D@b@bA.?Q'@@oAi׿5r~@{/> @@?릨AOPAyAZBGFzu…^_C.AE=?@)@9(2=E.?FA)A'C&A@Y;?@&O @vA8@ ;@?8}?ľJDc?bV@~j@d@1I@5S@??ɺoA m3X@.?GAfAZ@pJM%hYi@%@y@@A0c?L<6@isA K@ø0A A r@ @45@@@=> k6@uh@ np3l7p@Cs?'t'k@nYϓ?*]?*?ƣ4?Ok/@@C>;3?? v)@ǿm,?|H@~B -?R? qvz!)0]3fǿ1]yWѿ\D{1E_ "]4¢=Ȏ'==!\?Q@?@f;@ˡN&=;6_3؈;zjʢ.@:Р@^??N>huM?q?.[8t@Z[S(?yϤ#@@T;@{fc&2ѿGZ&0/Tkw.jC¬)xY?;Xz忦Pyy/ aL<WmE8'}b#׿]#@8>;C?h?ۼʙW\@E@bL;@^@K'@1v@4[?+@{@FA@@M@zP A @^C?Μ_~@XȥA^@`o? Aq@ÍA{B3@eM@oAn?}5@AB MA?0B+mBCB(B3ABpA=5q@ }¢zq+ ų@ԑAٟArgAF;AuvAAL.>@ A}?)\>@7IA*6Ad*@CAMyANT@K8(@q-A}@A@r;A >?3@@mAWlAAΔ@?"A @@w@?K+AA@ݷ@&1@@a@ @mK@M@P@ A@@,?̀A%I@@=@Q @d@5@7@c@Ȟ@v@@Z+@?i@@iM@os@K@o=h@;i\@躴@lU@@TH@H@.@ ri?s@,F@% ,}|60<@ ,ᘳ7m<JIcfnf1*?Y@b;>;?/R??Do@Pf@VF&?L>c>Ieɶ?V@[@?f9?C|@~1?*I ^\?ˑ@~?yο\5)c˿|s@?~k D dt@'@XZ>"c-?n@"@7q7=73?*4IJDt6b ,"?ZLz!qs\?95?ԡ@"?c7@(N?g\h?X_@ Lv妚7cOB?؄@[gjPtw=@.@]d>>>&#@4Ra?d,@>-9!>+[A-jA*@4AC@4}@@4L?pA`A#_@~AUAUtAbA!v@?Z?KW@"A_' EFss{t@AKAbDK 8A4BZA8A, NA}-dvA #&o_l@S`$4%.u$+-./vkpWFXcX';6jch @Z5[2~0đFtk@i2ڍWH@c>M^9ʿT7T @ ?^6@ד@@?Ī@b@cy7@C?\@@ON@\&s@Oc@(Z@@4@:*@46.@@[@B?(?Ϝ@P;@M"-o@@DG>$I@?@>ID>Od@_b@-?@ϝ?qu@`3)@"E@s?@"?4@?tC@3hN@Aَ='@6@@]\L@M+b?I;@.@B'.o?}@+Pݝ|@ ?!tI}g5@DYN'wz#?? j@#? ?y%s?@KM>@8@\?g(N@cn/?@ ?H}@SY@.o?c?[U@t]@C@VP@\˔@@w9@Z@@H@@ d@_x@[@ח@@X&@P^@/P@\@9@5H?Y~@C M@@%?S}@w@1>#E@G>1@>@_O@@Ax@mTA s@O@*vO@]{x@k @g X>h@|E=@@qF@`=E@?W8?/@Dm@J3A/@@*ATk@w@ AC@ZK@@T@@zA@SA*tAQ7HA; A`@@@jL8@A7mASARB7qAB)5StA\M; PY6@ds_b~{AAbAMF(A\P@"n?`@ks @Qt@+YA @e2@Sїg@"@uq TI>WtVЉA>(@uc@$Ϳve?UH? zYb)?Fپ?tu@P{@ P%'=( v>v6>ʨ1+ <\Ѕ`^=q?/@/i n?رꆿ>)]R?LZ:{?N'?I@y̠ ?@濨 }jnbzV6y7M?@$ؾ@S??ޝ`??K+m(f4VJR+@I?cȿ_+$N@.Q?㴋S(捿)׿@+$ ۱@@ t?UD@0@{O@hR@ j?GϿ@r@S@3 @xK@=@">r@@d@L.@%4@C@y@%#@l@0?K@u@}T@n?M@@hSJ?5@(H?V@#L@;1>[G?{%?R1@!@Ⱦr>@h=@{@2=_*@6@x@ aA@O@gY@41@~yL@@~@ @@sB[w@_s;>߻@(@ ??_~ {_#@@p9XYC@{bI@9ߖ?B@w#??:#^hrPAixR,%9?GLTtq @_ @2C_|@/@TC?,A$v&@]<@Z?2?%?%$ٚquACvA@@tfI?7/@С"~f^Q@An-CJA5$#mA1k@V'@SZAT5=@ @.@!iAB@[@ZA2~@2. @HEA mJ8AzC?@$~AS;@@ðAVAVA/u@vA wuA"AvbA:@@AWAUw?j.?t@o?R@XK=(*@$@s?.5lԢFvm?h$@6?}>XKῷF{ Ml~{:m5,F|+@RuQ::4Y~Pv;9WA?8^?6s@B}aƝ`7xewAvQE6M_cttu?5`k/ ?mIaZұ+)4T[~b&΀feewKT3'&Mt6%,3(~1 &jDL O(R[dFln{?ix-m8Ns+mB2 2{ CuXӾ>(wX@@JXq\@!T?h@TY@H&5>$@PD?6@dn鿁NW??@{D\;?>?F5Ad@_Ke@]>Z%z@:P@$@p1?1@R@zA'8?~AeL@: Ax@@@A@JA-=A|A#@G?2,i#@|O@d@3@?K?$p@wy@H~ wBM"~@C6J@@L4E@OVܾYf@rA_IXG&@ A]@RP@M4NWABm?A\1AYBq^͵Ae~ZAB$@ 俒uiA;\]FAb#LN Ap'v@Y!@oA='@xI@]d!@JDA)kh@>@)ac>{~2@A @z@ n@A 7=@f@¦?x@@A(J@{A i@D<@QA @E] @i?iMA#K@h>}> @@Z@;@&@6@6b@DA?@O@:M@Q@g̚@g@@@(4Ac@9SY@i:A @؞^@+(C@*@,TA-s@Q{@NQ?Y/Q@EE?`A-A.@Ŷ?;_i@??@\?@+@>>&"d@kk,@E>t@@6ܿHa?Ж @\? Ux= : A4V 0ޑg3iL ٨P=]%T3c>>z_@,s?o@w%[?=6@>?Ql?Ux$r?ClTp"[~[nZpP+?@㲿Q(?ˏ4J??#}U?V ZZs!{L]*1<$'=9&] 9sdeF?9/~@9?>3@q$)>?P^@#("@@=E?hj@ ?$L?S?@,rؠ@s???vA?{I@<@J?{@@׍@T6@A %Au1A@IA-@c AfA @q@b@F@ =@ȍ@3AAAgA%i@TA GA/@f?j*An @AY3-AuoACAOA*8@._쿿#dAUA)4A;CC$H(?e$BBBeA4oRAeB}A1R`A.A0+AK?ŸK"yAQ?A'T`j?@l@(@M?g>f?g@PAYA)RA2ZA @ܽԜA\H"A%^6AN _@8q@U@'?!@iA@3@'@@sL@YA@SL@96?(vA@b-?Q\՝A[@g@˝?v@Dl@厾w=@أ@N@{7@Zـ@A9N2@^3@@>^AA9(H@띦@v<@1p@u@%1@5@|%@`=XBA+:r@*@Ɗ@X.@|?@?@Fx+@:j,m?Vp?1%Ͽ2߿^?@nv8@S?/m@@u@_@R>c @0@q? H@@Pl~@A@mfkdf@ ks@U/?q@J@AL?n|@|C@iOAM@@v@:6@ŗ@RNz@@iHK=]S?@4qѿ`@At?ʍͧ@'Ჿ 2{c`? $?G@"Xm(L"?.? @u=@(5?ve,?y)T})=l6?'7@>o!>h#?d@@@9L5sc@?$1}@O@)@@\@8dF?ɿL?,@"t$@+#p@gb[@T_@4p2P@@B@ 4M@q3A+@Δ@\@@,A ^WAZ/nA AțA G|@@AW@K_@?kq@0t@3AKfA>@TAK A@@DKS&@YA$OA 1A<?I7A~@;A;AГAވ@>0>BR ? ی׎AAq'~q@|"xIÒl ?,L LjJ.@K?̃?@#%5@ a?@?v@&@u?֢? @?&@Z)@?+Aw@_ȟ?@@v\@3@VW@VI@B@@N'^@`Y@@k@B^@@!@y[@p[>+<@tG?S3VJg@Y8@|9@ @@Ť@=@VT@Ů@g @@̣@j@ƒA0A)A Z>8?A@H@T@!?ei@B@\@DT@"?C@X@@%.p@7Q_d?z@? @-+@{b@/t=ɔS@3@@a@%z@|P?yMd@ $>?59@z @1@m@S@}@RAW@d@@A"e@A@@5d@@V/V@D@8@0@ B@6@j@^q@y@@X@#S@@AEA@\@V@/@q@d@ۖ@쁪@1?<@xFL@Ǩ@ok?@@?Jk૓@φv,@4q@ @h2@2 n@?>؍@v@|A?俪F ?w@D)?.?ўA @5n*>BrA G@9@yZ@/?Qc?/@7_@-@'@5??eM|[ACu%@A.~h@o@d@*AwH@$ǿ3AAAsAb*A@ApAK,AAAYAA@+3AЫ@w@|AybBRBvN?O€&bA (YX%hAQ@~@3B6AAae@8nA?CXs@ovҿxA./2@{bJ?o+@,6@(>8m?x"@6A<@dTA U+[A-+KQ@?%?Ӵ@/caY@Ֆf@'+}Ŋ@49T]G׍J?eOR=\)UVHb&L@5w?*S@O+@/?9Ϳ{91\jL=翵7@p[??~?ߛzPw[?<?S渷-?>@ ?wW?ɾ0P>K nK?]>A@!,ϴ@ּ@}'?Zκ@@J>@7hWh@\@@*y@V?̈́?@.>5E?g.@@@H@oӿX@^@]>*?ߛ?o@@L@L?Wy?v@n@X@A @@P&>r?t?B;?O@~S҇@@l4@"$;r @@^T>J@G?a @g@1'?@`@vn?Q1@е?/* ?q@!t@w+@JA@A@ @ o@P@(l@ZU?@w@ACj}@@;@@C@@W@C?6@›c@2_?@{NŊ$@`@'>Gt@s@@/AeN,@wA0x a7ؿ]9@i; @~ >?y@9{ANAeҾ@>]ۿ(/% `j!i1@roJ;;B9d~Aʃ8>A%8w-@N!?5@@;nAA}@>@@}?>֤:@FPxa??9JG@!@&@ B÷#?U@@7?! ?6@6?/s@ ]?¡E>jf#)hDCR}@qGܟp@-~J?<*gu V?QXZfup(4nWƇspSh-1/> %懮u?@ho~g7k$uH?FW{G.&Mi渿׾{v:d7KP*#exQelŒzјBd(QU?J>9 -~?y<G۽wpGsNobB+k.$&uxs=zlɠKԊGB?QLF@[O Wln@6Yl@0.tkWY@=?X ? bf%@$y@@p@ @Im@?@4i=L@ >x?U@Z@@(@?,j@m@R|F8@ޜ @69@@8E@e@<2ANG@Z@kfAhA e@@YRAWA:@h@~@}]W@kQ@w@zA:S@h@>0@;߿`?/S@˺`?Y羨G@F@N#*@NS("@gc@UAA sA>A#mAdAw]?̋Ad7H{9AeB@lBOB*<o^b)rByAn=Z7?s0[BpwA׾A@[x>ȏ@@@gAo5CLnAeN@? ?CLAC@ҕ@_a?@@W@ {~z@t6?@٬L?A'A-@ĕ@@!{@:A@??T@BA$@Q @{A @ @d"AA Ae@p @b?A)^AF@1MAPA;NA3*@v@wAk@L@IbZ@@@ﵿ??\y@e@?C?'h@@_d\"HY@$$@@}@5fg?X@87!k>H20qYIB|>>~?ޑѿo$#?$ӿ8 @S\S=I7C@C\,GXp~RV?knrQ HF?;N@|@Q@@/"%?ٿ8|@ >V@ q?JIS %?=@\>*L?£?!U,;TQV0Ӝ?-I?@A@HO" @?5a=XAړ?p1V=ξ@rBmJLb@~(+> n>k$Skv?XeN4#{V}SPaɽ̯?q_D@Io?@Y6ɡvwI@I"@C@*@ec?;@AC?@̿@vAAl8@KA@v@D"GA nA3A<#~A@@AS@@AWA36*AaAcLGA \?^@@y0@` @@+f @@;rA:=:#@}W@

~'@X+A=$?@G?ݠ@@ @q֊@@{@s/A@@M@(@AQ@*@@+@uF@A@NRw@U@?o:@˟>?&bA@@SV?Oܖ5/@Y_c\k =>ɩ@9r@F >@{@us@n@R@e@WX@U@68?|^@h'@H@۾A@Rjt@?n=>-??U4@͵?4|@@!@@E'A@@&=?+@B0ԿU ?P@-s@+@!@V<NMR/?> P?իe@|K>f@Ȯ@8 y@=@h@$!?+=b?@@U;LStө׽OU4~-ZS2E0 ]@??6NoD@܂$@g?Xˇ<#>\?J@ J5`28@Mt@yd!@77hrƿ@z@q@u|A,=@سn@b@s@@D@Ȥio?@"@>^AvAY[ASA:4@,A`@Y@l@A-b?A״@}?) AA]24A/@ZA2mAz*~MW@A"OTG@sA gAF B5A&F"/@›+nYoB&#`@oGsc:Zkuc&+*Pɍ,]lna?9.mQt!I0,ng1lR8i) @ms ?'̓H@S51?Kx@~@װ>@6߿IA7Q@^@:K@@PML\(?5)?@͉?@P>=/@+@B@R,@fUF3<@}@]@+A@d@9N?^}?޹?\?f%to?2@Ǐ?@sT?6NJ+>qjM@ "?.@K:@:9:Njl3w@H@9<>$ٔ@/@y'@ll@hqR@?? K"?2c@@?@_@@@4@UA RAd8@@P@A) @QAF?Tſ(n@@@5j@;{Z?O@ӗ@{?yA%U@@j@snABA>qfAj0AGq@۬z@0A8A)(@tQ@~@*NA+(A @`4@@A|A@@ Y:@@r@=6@@~AR ?~? @ ?@r@UY@I@RT0.?P?ܵ@L@@w@1u-ҦZ&=Q@U[ʿ@ٿ̶ @`@-AB*@T@p@*AGÓ.'Tr@~@pdx@j]L?>WV?uPC$^bV'>8?Qm@kp}c7>1?cmŶ>3ytYn<?"[ZG?=0?`?2L]n?֖iX @]+aic7IrF)jUv7?P3@Yŵ:W +zO'>w?S@h侸 ?r2Y;9L@vt?H?o$@Bc@=?&M@&@,E@]G?z5×͊^=@<>ok/@+}?x?;$@m+?/q@4꾬@s%@$>@3BA`@@4@Nf@|@hGؾ'`?>Jhx@-oH?j^?eu?7@JI?]7A$+YVD@A^S?Ώ?0@i/nHU?@|[L{P@};O?`8@;4+#W>ۡ;@e>@ѾSbWHAu@c>@)=?u;t?+"@d( R`@?o}@7h?@@m &@H`@@qU<0@Ⱦ-3Ah@6־@9S@D?F*@/@1.@Aim>?jA@λ.wAlLB*A[!AEBJe&Y@@F>a:~VAGAd@A4hAmǽޙ+AjIAc:A}p@AVAM1_hAAwJA?d@@iADAS/A)?n@=2I?As@yoA]A=Al?YAA#?A2,0@~@j>@/4P 3z?Y?%e3@@hY`CI@@/aPA<)){'h-n?G?^ō/)_\> E}s8I!??/elr'h (CΏFߏJ\~=cI2=5. cvg:B7_. &?`o/ ~UdOPMi [r:/aFkXܺXqbk<P7VS"3}Zj>X!L*տ6Dn$qQ=nžcR-s<uP# !@N4?o@՛@]K@D?>C~y (x5="Xq7S(^e?#?+I@)>ο8@Gc;I@Mq@v@@a@\1@=!@m@+Q@@*/@@d@=#P@g @AX@Z?@`T>@{@DE[=6@@f@O@8@tS@>@@A?`? @忢'AzK@?D@!P@t%T@@%A3:@,F@C@@qQ%L@\@< aA I3@ U@i@@zA @*.A/@ZA7JAabA;A @'`zH?0A\ç?uAo? :;7f}7y@B5B;AAa?6NA]0 -YV@jo@, 2A3V?nA=rfA5I@lOTNA"Yh@pA`@$(@w!@An@@b< @@@(@ @Z^_A5A@lqA+[@" AXQ@A#K>Ay6@@AjA@܏f@]A @A @d@oO7R%½2*@!?A@[@ʌLA48@=p@`@ @i:@I܈E@YO0@?e@l@/S@A%I/?xKy@* v{@d?Շ[ ??;@j?f'HYm?̾@<&T@+ӿ%@u]gtQq5~z#>g֚@ Y䘿uo@T1@|>; r@)@?I<?r`>b&?@?ujaG@j ?HŘth*?g>&j0 a>11m >O??E@n/YG^j-"62?W'#!,@R(ral@SR@ۗ@5䰿*?@9>??᪾4=M?@vAb@:@'Qt{K߆@N@@aU@Y?Nk @zX=k@A_;@H@MA.;Aj AAg> !A;cPA1@J AU@(AA gAIA+U@ޅQA7 ~A)@aA7@?9AA# AD\@7A A1@ Av@TAU'A ܔ8AAͫ?Q]b!;+yAw `AцoAɿ%fBlXA4R@?$lzj@Z?1?V@duW@F~@#@b@(@GA*0@@KAiH/U@‰ix@li@Y5@ u?` `m @@ xAXz@|@@uo2@0@l@W@2[2@?K@ zAJ>@[ ?B@@A0x0@@a@S@T)@ut@_A .@p@R@8%@g@xVA'@Wq@8@SABA }pA yAʣAQ@3@@@BF? Qm@@ h@@@A@P@@ĺ@i@w@q?@@?fj?@*u@I@T]@>@@̖񊧿U@i@1@?E@HS@@mE? @@@ @U+@6<@x@n:@; A Q@5&>8@Ai@,J]Z@/@d,n=s@y@|%?^@"@W@s@]#@( @⯾ܟ@y@r@v?ѻ@~?HX>@u.?{:3? ?id@dP?4@@~$R>Cc@2P@$ۥ@{?'?e@LV?L @-? I@XL@@6?ْI?+8,>·!@PLIN@t@@QudɝfT>VtX@y'[0@-sI@?`@ZK>2@m@k>CzAyn@/̭$?@ؐAíֈ ,AN}AB5Ae0?[Q |u:+\h#EzԴQ_)*{9 ??es<_1 # fm< ޼C>EvqB.[nq4i, -1@*&!BYUv7c5e9B?}##@1:>@n?h @Յuۚ>5V+B){׹>JN,M?*9pƪnjaK9phiS}/;"f8&?[̫ͿH.ܿ{C^p@I}@.?1@jϿ g@z<4C:҂IT@>oT3@s1=ɿ?t%@ ;?m@N<@;ݲ@xK@==J@ٜ>};@€@b@N@@Q&h?/@q@_"?y@e@@>@*A4AGA_Jh@@AA AYۼAHAAK.@_@A+AR2A A K@}@@A%oA@F@CrA@o&@#?vA@>fX@,f@^A@A@nA0>A^@A ϭA@UA@ gA ,@s@ 5AlA @9?A$@^@)=I>O@V@@?@u>A @уA A E@F@nj? @W?~9@B7X7?w"Xp>Wワ?"@@X>?ɀ@t@?Na1@E8 @[il@A\AMc;@i@v@9A>H@M@AZ6#ALc@X@M/oAQ@:B劎ϋ@JYABm5B4e[BJ!A@f ~p !y@hAA_wAU@O&Г{AY=_]A /9?NaM@Ǐrq⌔@Ov?vgc!l~=h9i ,qn3Mw?~@K"Cp8 @$=/x'I߿ti6㪿6Q 閿k8@2#@O?A'rdL#vw ?%"#Z =_zb5i:NxRŊh>ď~E]tbۦ?CNti]d' ҿLb"@>I_ؿG?]>@kAſ"߿>? G@Uź?o@>v@10v,@Ŀ `>ě?E@$'-:mH?AI>Or@!?v@="@{AR@@&?M@@2>:M@M@;C@n @Ϲ@eA#: ?@[I>@J@k^@@3@@6@Vt@XAQ@ ANzAtAQ@]A@A-^aANA 8@⒃@-2A:@AEAAo/A*AAjA|AmbA2A#A&]A @aA-{A:@A0VAinZAjAAA@wj?ʟ%@LD@$Al:@^n@A@ܯ@d^@=T,2^@k A\U@z@ @^hA%@jOB@]\w7ϿL;@)?! ?`@B>?`@!3Aq3^@]f@&)⢭н8ZiAAOA-JIA^l@y{;?JA@LAz@)8XADlA1mAs;A?mQA&z@$A-x@ADOAA9A~,o@9b@QJ@A?;L@\?@A@.?@@17@,@QO}GA2@?ͤƿ'A*{Ғ?K@L @G@t]]@8()8rf@mZ@LX >I?&Qs%V@ ?ڎ8N8PzVdD47n?HC%\Rˆ>wND2Hg#:bs0Gǿ?Y{ڜ#;hۿaXXq 0G*ǸA]{D 1&/rQ@U`b;^LXa9u<YUL#`+Gg$E$g% >&+EJyY)7zdKs@L3?o,?@8ſR5EuRPP-yc@\@*E?WP@v?j6??+-տ@)fD@e A <`@3@أA!@D1A#V@:`?W?\!?U2g?x@@>o}m¿ C>ʿ @J@?ۍA S@AfN@M^@HAE'{nA s@#\>׃1?6AUDA9A!c@1W+@w@M@zpA+;@ @p+/@@ܢg@@H@KտV.>O@^>,@! m3S4@g@>'vgA DC>HAew2AA8APa3BQ"xY?\@% AjA8͵@2:L@2A%9@1[YAA:AEQckAAZ$AAAS+T@1A7kA7]@ @q.?A@eA'!@@FgF@5a@Z{@PocAG,|@X1A-ArӗA9,AO*@36V{>x@~R@r@FP@2A#A[U@@_@!6@=A(%@6DA @i@G?jNA ?'H@=@.l@D@Ք?@!@?@*@22> ZA8si@*@o?c,g?K@S@T@0@ڶƒ?}@nxB~?&Js)5 <@]^b@W?F>{(^?,s].ȿIG@J2@Ӈ@ͽ@K|FǰA@@{>zKA >W2Mm4.n|`\ʹ>x&@b@U?@^to@%݊?P?6R\\ f@A8 ܍l?P_@ *HKw4%a%kL!CR?',@[@A{AW@-S?[?@.[@R*@]I6T@@cM;@<(@Ix?2@@Y@xF@A6A, @֣R@I@WA"AOAPy@@66@?9@`?P~DA X@,@h@c|?\)#APP?liEA&kt3@ Asc@CAp֋@!Z3{@p@kMb²;̙wo@/r*BEB@#}KA;YWDF`F??A)aD@,l,1ABA u@@BE÷@NAhRGA1=@e?@3 j?n@XK?A?Ӆ@?y9>Fzg<ھOJA#A@{@$?g@bAd@4@9ö&ArAOAA ;?AWUA1Jf@S@_s@+@}?N@$@5?H@I@@6R}A 1@boA*@׾@@(@?JA1lAgAN@MAZ@A*@Ay`@֜@iA@)w@@M>@+TAGU@Ŵ@^C@v-A%K0A ]?@g@ Ab@6?^@Z?ѐ'@m?I?p@U@Ӑ@!.eI@#B?O@>z@,^@sR@g@1@@$ @d@s@!@S@h\@N@.?@TG@YO7b2?M@ ?U @#?T*L=cD@(A;c@u@@Ĺn@g?Ch@P?]T@_sR>?rO4@v@h?<0@?򠔾@X@%AgF@@A6@^dEHD=g8A@ cz@A/%!i@8h@?`@|@ڏ?@QAy?AUA sAf?AΈACαA; <w=A@R`{A/ %Ak?v">A>AHB CAA _AA bnPY˨@;.} FO@kp@Ջ@%@A@@J@oA]@?P@A.N@9`>'c8?d&@ X?e6>QN-0$2v1@?4#Q@7hV@j@?ÿFUg@YWL?`<|>,@@W)'@@|@A@fA AO@AMv@]AlAyA;biA1AL+{AbzA4A@FA/6A\AAF@4g@AEdV@}NA3A"H@ݨ@TA3O@#A!sA)@u@WA7vAAKASA,s@lA#@wAA@P@d8@@AR>>R6@xH@@)@i86A'o?@ɠ@"AAA?@@a@@@ӝAr>&>ո@L^@ܟK@N@"8 O ?j@@5@6@v/@pA?̍@@@5ؙ@.;@Z}@;4@>p@CD@s0@3ݢ?@yA1B\z#@UA.9*A pqB(BSeB{fA*BT˜GAAݝCS @~ANA[šr|4/!tµ^&G=QVXD@z2/H lU@(_c5Eꠙ\^0_n[k24I*~:IW0`(7& uU$xyh\CgM)D|@Z?jϊ" 1+*O}?h- *@F4|NJw4OuwS?-%s?1F*@??@Y뙟?ؿ#@ą[N?6ym~̪?( ?J.}o{?c@yx.~o@ @aA'H@z@W)@ @@H>xGֿKE+>BE& @Ƣ?6@)@ah?Bh?YS@@J2c@@Ym@!@l@@@|D@W? ݟ@DB@A@]| @in@|s@P@>#? ~@[@*dc@nj/@=?@촃@aAJA3)AX)AW@>2AA7U@A тAcH@@.pA|0Z@^}ALAEAC@QARn'AEA@AuAnA@gA64A*֩A6A@~AwA5A,ABl@ AC@?@@?AS"A@p\8[:@@-OA?;?.@@l@vȀAk@~K@ AA_i=NjA"?>>s@ƺ@?J*qA@SH?bA0:88A>A@-?͹?@g6@nF^)?8%i_D]-T o8°F=i@Sw/}q0EK;\T@/&@=7peCNv'*8^sɓ ]jLZZNZ -n}߳1^sHHq> ه:G*ㅀĿ0t \yQBgj?1gB:/N! \ϻMs24^YDoʁp?un;lQ9uLq vk > #?\{?`OfI^xoe:SVRWQ*@X`@}?Q?д+2F޴s$6R8)muڣɾH;n@9@DN'mOD\@@ 'a?6@ @ 9?w?ϲa @뿼'8m@~@2A?f]@6 @#_b??Up@-mCNAet@@{t@A#э@@A$A7A5=ڿk? @Nk@0Af?H'T?SY 9 鉿p?A5A?~A>5gZ?;IA/O<@>FWuG@颿[@2c@&t@0!|,  {HBG@B~Av:@AAARd@A`_A (A@Io? 64;AvN@G@[A-@GGs^6(>{U:φ䵪;BW??q^? ,>0,?!;;๿l@ڑ Aa?B@p@SN@#nFrU@?m@}x@L AO@>i:? Ak;o??Q ߿|j7?'Z>˓@p[;JB\hDG@w>)?@T 6?78[@@ʹJZ =p >@ȟ?2w<%/܊0@p>t@0"gmNJ'@WN@r/aɿʠ}L@t-!3aD>Γ@@7@؀@) @d-rV>cĖ0I@%:S@*b?Ye)@,B@X?ݒ9Z@mAI?p cv1@@A%AO@zA)A˘A8ADAMIAy@3A!A,bAIm%A/ ?<@6AA%A$>|A19dA-ANA+P?n? AT&AA@$@*A6<>&D @l@3Q3HFz+#AdAҲAr9BPBl>A^|A%AڀyA6AAB@4g'AUAA =Hd@&@?Ab1AǞAQ?#@%BALEA'FAlA UwAOc.@77@8A{^Gg@PP@cVA|A ؏@zc;i@UAW@d@+@?|(>(>?FT?I> 3տo%GAR@ý@|l @&@@,@ԻA<;@8@`@UEA #3@m0Ap$A4;\AAA@kA^8A@iAÇ@A@tA AJ%+^G@n?A?EP,⿕AHh@%@bÿ.j/@z?n@Jt߾.D@S@@Xw4??B?_jɜ?0AAF|@]|?8>9A'2`@A c@r[@kB A^RAc@8 A@<'@e@:A-MAA C??_Ӿ7PWyh >? NCU]@9@A >MA@@>~ v@Ìf~?+ؿ,}0@(P @+@A ?A#A@:@X@Km@҂GUAE?@@? \SK@e&@/@ \E@@g~@5A=@R.@@iIA<@`b@@Fx@e K@ ?r@ې>F˻AZ@ڕA1@=@(R@A(C@tA A @A;bAJP?£A:@A S@@;A7sA0d@bATjwAoAL9@:A2AB6AK.ARAwzdAm3Az@?As}T@Z@4[AOASpA+('@@n@YxAA< A+*@vQ)@R%A^n@Hj\@@P@AL{A @უA+ɶA '/A$A+NA"J@\A.@A [1@A6A1A@lA.BA)* A/@ר[@鳔A7fg@A.mQ@?&AN? S;%@ݥq@LKR"?|*?@n(DAi@Ug@I"@hA#@A(ds@@{A6.>Q=@v@?q RA7p@ A9P@%AA2k,@Q$h@|b#A~A9~S@六A CAB AAX-N8'Z@IAhDAT@(T@(A.AwA'@A@6tA@c?ۈCA`U@mU.}+[@ƷWPX\bR@뿅rz">~FP}Uz\InMS M#{NdeRKBhU~l/y?AߕqcAI _0=\? *A,J?`lX@ @pf'?pߠ@Y+iϰ~\5e@QF ٳķ9.]E3;i:<6ڀQ`.5 jFq?ecw[O@uQ@Ak.3@}HA@@@IAsT@/)@KAP@8A]A,yA!,A >A?K@@l@Q=A6n@ ^>N@gk@6@@/1@(uB@n@+i??cAR7@\A,PAYZA!KA A`mA8AJ[`A+"?Jڿ4F@iqd@M??)G$?N@<@κ@R@zA-d @uA0z@SA!yA\A"A3ATA1&AF A7mAn@X@!9A=+@$v@*'A/@x@"A@)S@*A@+@A)q@IrA&KA ATAjARg@A$8A bA1p?AAHA_=@w:'A٬@>!@+f?K@)@&s&A$ AiA)?Dg?E@ =@ @ȰT\`A?:}@N@̶4?̅A>6@7hZQDJQ/A m E"mm2(LNf5awAA?!AJABA&%Ah A|Ay/AA9AbAxfs@A]AI{A#AAr @AYAiA@G^A: >FA{;@|L֑9@z@˫@/_T@PeC#rv~W@9;7&<&ЁD@Q!|g X 8Wu& nH[E ۿQ/Z^:,MYB}anmEcO֏uG<&o7@b|/Lc@?h@!]@>@@p_@@GcD҈>lbWY@j=`<?f92?w4T=:@7?O@{i@lA/X]@=t@P?r5^@=^{S+@Sq5 @^@M)dپ )a*@Lu?>dv@A@?x?X|A'H?U?T@;eA6$#@7f>}@A@oA(A.v1=>̠J/@?('@pX@ AD=e&@=$T\?Z7A{?J"@٘@;@V?Tm@Т @֕65ɻ4m/Q@-528?ڄ@DHB/4xB fA>6=@_=B&xn]>gA/qAkV?@kl>QceAAAX ?^k@_ArAx;߿ٍA)2?TL/:gpP@&&@C4@w2@@V@@@ƆUſ 8u@/%[lYi3ۺ~-1mW?:pJ0#{)K 68?@O?p"kpE裎Y~\>v+@ 0?`@e_4@}L?<7s?꿪iNQ@&@4?܄-jb_Tl>@2adA&@d?;is|k,K||z~m1tAL @F@Cn/@?d@<.d̽:Sf6?;>so ?$?feŸ.ʿ*@`P֔K@*@ @u@ZA1@^>@U&i&v{!kF@w]D@7@uJAO@2JA/:AtEA/@s@o@Ϩ|l/A8fAA:2@,@@1@[A/:?fD?K@l@R?l>HsWA)=n[%A"%@A9@N2h?5?Pk?+?薉?y@@ @ @@U@)o@zgT@AHEn@3@*;@ߝ@=A0@珁@a@5@@d@t!A_6t@5#A(@`?gA^A A(iA AxA@ATlc@s@-|@kAAmAJ9@>T@@<@|%@BA,AJnAA\A3ËAgAJ@AA=YA(DAWAGCA?iA:YAz@KA@/@GA@@F@t?AA-p@ 4@oAJA%AJAS!?X@oA{d@8m@0ڻ8ȚSAG\@d@o>?<@3@@@@η@@(@;@2{eAM~@A@.iA)?xO@: ?(A65@=*F?Q?J.@22MZ@P&r"|=Y@@ޑ?>=Z@{A+A.@ gAA_A<AQ#?#~@l?slfA>|-@A9Ao0+A;ATX-/rA>"A'vA-A7BRA A mԀB,-9SWVLH?n(x#PCd.-{@.Ϳ,?bvt\@0Ax?V}=dK5^lt@\@T>@kA!0@oA_@2A t?ERLV7A@JA άA>u=@^=AS@x;Q &īA @9ݱPä @E1"@3Խg' ?]^47B>@ڰHAo?ɖ?;@ {@4?"ak@Zp/=@$)@?3?n{~D@I'@d@Op@=^A0@F?S A *@rU@F"@D{^H@A1r?\@9(T?7@?0A!e-A@_<{.Ap?>eAA1WAsc @ƍMAB`AApuAFAV -A;A}A6 A8s@A@WAu?*F@VwA'I@XA_A@DA /}AAt@ A A<|AkA,ABgA"iAA"A /ACR@V?+@?>A i@ A#|\?쐹A>@P^A@AP4@@ݾF?=AqA[ @3@د9? @e@~I[(@"a\ n*T iGA02f_@@G'&@L@s/D?3>wMF=a@D/i|Ǧd,h (Nb2 PB<|&W,_^f`J0^P)A m ^@YAv^@?.ABOAl[P@t -y\@&`A!/'&%r+ ?U]ƚvg]B5F(RO3ŪEcuٿۻ,:r@QЮ4F&@-9f? x/Cԑ~ b.q#5 ;72","AU?RF * B>= "?'z?2;='Y?ƽĬi@/ @/%9Oq>aV훪@i@؏@x%0ޚAК@@?a-I?pGA /@ @f@ (@>r@@ !=%qo@:A,#ASAg AbAA2\A:}@B0 A{@Q@@G>@9@xA&D?2>ࣿAL?@@A4@AACtA SLA-AQA&Aq@] @aA@Kѫ@-A/@: W?)wA@A$ys@9c@/SAAACA9AT>AFxAA A@TA?y@ƻA꿆x6e!qGRsKD؝@Vϗ5@bfV\Z)YOEl@Wy?4B ƪ;/ ~ K"F| 0USD}UiQ1ST xl)0QA=L <>F #B:BLS0?VA AA'+@ƃAIAB=Ao BJ@?2ӱ@uAh<?6AhAr@vj@@A!&|@A I@@@Ł . (? A`eո}gAv\@)S?eP_ELFv+C`ߙ$@T[@\*}oz8،m']R~23'6 R?6B; BhN@ܸ<0 l- C@1+7G#ƘseQq95,ͮ8 ? >Ɓ"@p?'pI?9Q42xt~ZP|x?boJ4Dsaj >jN{@] @[D@"b@%_a]h@ @@rL?6+@>?C@'>}A n+AOAhL>l@8@ ؅A%)@83U@]齿+,?; 47%?h,*=zIAA,@(@@_@'A&;A;7AC}+@w@ƒ@3+}wtCo>} @p@BG2`{>AJo,ACd?Aj@AAxi@2T?|@k[A:p#@A%Q@oQ~:&A @JA/&A)ACaUL BcwFAJBaY iy> ab^JʻI?9/@>AA ߽'A)A>AS?B@u˿?^>7-`?@ K!]P@@L Ŝ@dVXv?[@*H ,Z8?TC83igGSjT'@@#3?rJA1?n-6@I@\@!Ani=e)ҽ@A,mذ@f@?;!CS nI"'+U@ϧD @AIR@nA AAZAoJ4:@W7A+2i8a@- ǿ]@)^?(@ KAj%@@ȄA'*a@!pAZ˙A6:?A@{o@՛AA ǕA@@m5A=6@=@lK@MMl>HVA3@+X?q|@S}yA>@BAVA]W]@1A]9}Af^ߋ@[@@ķBhi[A A"@-QAH>@a5@-+cA.zBG@>f:?QJ ?YA5B(6Z@ wO@4JS0 ?{;:@$̚Ғ6KkAeawB]~;Aq/o?pA8( A4n(@ @8E{L/?AG60>@=@bVb@ @ٸ@?uO>ɔ]?^k5>k@p@(?A1%@e?A`8@AAsA?pT}@"W+?W?v:W㱆LҀǒB@AA3@*1*A+@`A@>}Yǿ@ @3@nx|A @öA!:XA}@K@#@R@-)A6>@3@RAG-AAAX@c~AX*A$@!A%rA"@Fv@˜@1&@;d?F'@e@`6?Á@f'Aq7@h]A@JAAC>@#tƿ@%@-1@\@A{@F?lzt@_Ab>g(ӓN@K@ @6Z@=\AZ@QA$@溿־Hؐ@@а +j7XaFJ^,@& bw?@Us@]5 @u@ؑAPv@mA9C*@'@A>AN\AF&>?AB l@}_@vD?:5AWXAdxAZ[A@ 7D?䖧A˜Bۼ5A]&B!A;'BcAA>zAB)43kA,xzĴA~@CA&WB5hAɐAB6,DA;ABAoAQe?4AtA`AC4AA=B PAksB|B ?4ACsAzAA̞\AlAf@GA ӑAuAA"LAA"Ak>AE4TO6m@̿J@RA[@4#Cۿ?F?t~!*$lK1AvoAC:;5GB{n1/;h/@Cdf@ !c4^+Guҹ@Oe%̿@v@I(@ARlU>1@Z@ǼA @2@^A \@~V?:=t7m@c&8ש@A ]@?>@@n[@[@T@BmAJ#A-@ȗA0A/ @FA@oHRAx0A!@;c{>@J,@>jAoKA?7@ȭ@^xIc!lA q`Uic'M^2^2^+-we",zQFj!*I+$ViB>vA B$Ai[@LAgASB B#UAB[B5@+?"ABG.ǩA:BEaA{B @o@A˝A|eA9@9BAiA@ӯA AI7AslA^!U0APuAMANf@>@^@"A AAY]^g0@PjAM@OlAl1AK AAsAt AdAAXAJAP8"J@DRAb@fA $Al+@*Cd@DnAM@[;@ߡ`N̙B?E'A>5au^!Em@CRm@<[7.wi@wX'򿒶UBA[I?J/@~-XGZ<@_V@(?]v0@E<@;>u)z@`XAB?V5@@k@@ӂAmA*A$IA7>qfA"QAP=9A"s@CAA@ O5@0@,7?@@!@tA=AQbA0A]iA0a@@_`AkAAbAT@EAP8(A @A9R@Ȏ @=@3A3͈@ޙ@AO@%%A$AA$(A bA.AWXjA[AbA+*A.A*AA1@UA.4AEp?O@F@Ɵ@b@ N7͒AE@)}]=@Y*@ MiG@'@ֲk@6#&@/cI2@,>~uQmAU|PA8"ACA1,Gm@ٜ+m*b< ŮÀP([:ABPmݖATBA@%BY%7AAgIAWA,/@͗CAA&< A@42AAgAA0?ah(@l%]@_ A@ˡAV[AzArGAJ9A@AG_W@ AXA " A-$AFd]A 7?@A@@eA@AAm>sѪ@p@@v?DA04}A:A?X]4A@9ŅԽ@{lA@_@c]@$?Վ AsAGW?]oyKO@AAͩ@A-Dm@@p;imĿ ˳,=,?ބ~A15U@@hJB4o@A? 2ʾi@4A A-@Y@G/SA@$Jϫ@jN?F?b&?r%fZ@tM*ttT@=lA$@8@1&Aa@}xA\A&A=~@7#@W?rAAA@uV@̽[@(L?O?J@P@L@cPAO@[@-A:AA@(Ad6Aq:@A@]LAarAUA,A*/A&@y@>NA ?AA#@'@7?-A:\@kAbA.9A AAr K?ޔT $@8A[6Q@lÿۑ@'Dž?l.@P?A zDL?GndU/;.Q`?ưS )pAh6Y_Dy`@5gN 2uA(@NA@e@5)G,#@锰TO7%@0?"?޹@5{Axw@V;@I@eKȚ>5$AgAMpA/cAA@8@I"@vA@a@u@&ּA4d@GNA7?{?'@(^հA߭>;d@q@BQB[AؒA6|aB|^@AX.A#(Aՠ@M@AA@]A@ߓAABA?&:2 JBv0) qe_9u¿ALUA،RjƒEYycs;zh%`IauX7_q4*nQmC@(`d $ C{%[eA?S@?p)f,?SCQn$Ao#AWLʎB&DAh@A @oA93*A>f@E%@ t@ A mp?ĵ@*.?@;@-@ty@{(S?źcASGt@T?@/[4@bAF̤@=$PvAMY \@DAF\;h:WP%AD@ġ^")A+AkF=@R#@ms73@S(7?;@)Sr?YT W?v.@U(b!nv?7@nVU?zo@+528@迩AQ^A}$f67{?e>@1;I<b>R@@=c@{?L@?1" źX3@!@ @#:e@RflA ohm:FYN?4W{@iAxij@X\@@2AA@ A:hAS,$'i_@H@iA[nA_mA?@(Z@49@YS{A@U@@+r? `Lد<1;jVAQȼAtA @E@րRA6AP@A 6A 1?Au`? *GvlA<@TAA[ZA"ř",V@[AmA4w@A t@ܿUA`AUABⒾA)?_A+F=@,dQI@g+l0yؿGƬ?Oii.ALA@ %?`_#@1RAA2@@F@s q% O5 1IN@"We@ƇV @|AB5%A#øA$@&@]u@a@A.@DA)w R*u@4A%>n{??@s/'@}ejQ-dCˉZw?Pt򿡽 jV Bu@@3y\NaHP@(@~UWcAu@pAuu@93k+J0@n,T40/k>&psB#)(@j@d@~>@A%@At0@$A>AAdAA}hA5@v@GD?D@-I (r6t>@.!Zy8k@,9re#R@D?@&Z@Aۢ@#XA.Ng@@p@R@ @R@F;AA$@I}@PAAa$@(4A 5?v|r@JAA AQ]ATAEcAγAeAgAAh@-%@')A3A]AYA j$*)e=m@eͣգA\QA KA{@D~"BsG@A@`ը @$_BAt)@3S+7@*K0X@EWB&^A\!E<#iA]"y~8GAroA|/bBBPA@6geA@BSAA\K$ BP|["]A=UtK["N@@¦At\?@^AuD4r@ 1A1؟@>&k8>qx&!@Um@SnAAxSA)~9A>@굽ۻAD@AM@F*)ZAA@A$A f@x<.!3@߉ \5m±@|F??AU?Vr3AAV@$1@+{@@ @AlAmpA/@BmAe+Akҿ*ρ@X?q@+Ų&?2y&V+@{7vW~^>U*kgF*0 @?S@-^>@K?AMA @A[VkA(&AAl@Mj@ܚA,@DA}@A:A[me"@lP?_@TW=?A0A@ )Af@ۛAAA A)~xA%5A/NAgA@M>v>0j@Fd@{@Z@]뀀@r9^\3>x@5nV@i?ߖA]@hARArڒ@U@tAAyQAAKA-$As 32`lAY¢ªA46eT'O@E@$[p@aZR/>EpnA| @Y8 s AT}@.Ls)C@w@sAAY] *2 8K 7@ȇE? ~tAc=lTe@`O@{鍾=?ج@tر?8@@:? l@ZAFA[4AnEᾨԚ)QA}MDK|tzE=?[5A%,@hV@rf?VeUwA Q@ImA9@@x*AM .@l%֜? @FA@mz?#@^h+">>d@o骪Ak+"AtQ9@A+Q@A:@YAAN4@eA~vx@AsR]@"AI|@7\@gZ@òdA(vhA~yA`Akn@OO@FUAݜ@cO8"(_5?ў{jC@yAk AǩA j@ /A|=kAe@A !AD6=bLNk@oY?wû}?<]W?A@ =.A #@0AҞ?@KbA+ʿAnA@vA.f|@ @av@ŴAIEAn]A:=AbA%=A'Ak AA5A/AjA0kAUAǟBCAAghBBA6@B@A^$AЫB<@y$A=AAAٙAvA?A4@PAF]@ @0@@0AAgpEA.dAJAAAAlAt@B@HYAZ @6A Aot{AVJoA1E$@GAN@A@t+A׽_A!AAAAAAB BAB AAȜ>B!NA@_4տ b[@xsA7AAA@"cBfA{\BkDMRABu@A?g^zAڝ'BA}g@P%8Vjp@'?ib5<$WA6ܝAmc+ W@5@ Y-v| t)I? `?A,s:Nر!5Ki@AAWCfd~&J@A32 A3ye@gl7iNB?@([UA)z:k'8IqVr9 y0.Xo]Id)1s AŒL @AFAn.N?|e0 A{^,A>FAؔ@A!A0 BU\BQA9;B%1 @ZAfB$B,AB& CBA᫙BZ BRUA&As6jBB&.+A7@?.'A &AqR@~ ?b/A-AϬAG)AJ AaZ 4!p^ 8"FVZ`QAT=A(qAVAmGQA?A"Ad$AxADAAB 2BLA=AFBBa@T3BB,BˆN@LwgAS{AIAVA1Aה@A@AQA$_ApAƚABAxBB A@dA0V7!@2A U@ʯAXJA֯A]@n+A0m?APAAPCBaAzA0AqWAMA؝ABBrB'B:@pBBv;AeAāA#;@v1A۳[عAAB(JhBGA<2AATAhMETA2A0FM@h ¸RAWAR@A~UAWAkٹA`u5Ae*nAAA:AA#AwA@EWBQlAQ?65AB bAA`)A)@mLAISBAOBR|A@@ B |A; UA/-XBBO&B%VB^@g@ -@~A%kA>cA"`A͌@8A^|AAc~AvB*:-A@j9A7f,#=RU@AEVA `!@,A40@@duAu;AtA\AMABAj63BlA+LAzOAPAC@kys;"A &@ѮG;N@?AB7A|oArAADgABB7:A BB B“BB!C*.BjBfbA$A3O@۪@A[A]'AF0JAfÓAAA;AB ZA;AÚA7Ad!AaBRxBzgwA#A;A0CA\cf@AAѾASA+BZZ-AB"ABB50AyA֧[vhnoBA%AeAfAFtB;B.bBB(BuAwBJB>BA AA$B=g2B9-A3BqAڌABAAB] B%B8B B;%BGƥBwB+ABsA]AVHB`8B7޸ߪ?(?fCVWBIB-,`BBbB8B}B hAUgAAb@]RAՀ1A&l”Je~?wA`TA^IA @@BpYAA@xAABSBX BEBBrAA2B A'BAAk4sAR4A;A3ASA!AB0&BBpBBeJBtC/{B,/BcBBAAMW(A`FvB[/A$1AWAUAFAY9BA/BB tB7IBVBAB;AVJAA(JBޞBpYB"TABBBBB*AoB-B5B# BvB`AxAv/@&K B\ApAA]6B5AfMB21BLBB!Љ@ƇA͜bA(>aABHB_OBTAB`BAB;VB_v<}BOB<[(AmA AAnA7!B6%BKNtAA}gƒXTENSION= 'IMAGE ' / IMAGE extension BITPIX = -32 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 280 / length of data axis 1 NAXIS2 = 210 / length of data axis 2 PCOUNT = 0 / required keyword; must = 0 GCOUNT = 1 / required keyword; must = 1 EXTNAME = 'naivar ' / NAME OF CURRENT HDU DATE = '2008-09-26T21:31:54' / file creation date (YYYY-MM-DDThh:mm:ss UT) CRPIX1 = 160. / [px] TANGENT POINT X PIXEL CRPIX2 = 105. / [px] TANGENT POINT Y PIXEL CRVAL1 = 41.5791666666667 / [deg] RA AT TANGENT POINT CRVAL2 = -30.2747222222222 / [deg] DEC AT TANGENT POINT CTYPE1 = 'RA---TAN' / GNOMONIC PROJECTION CTYPE2 = 'DEC--TAN' / GNOMONIC PROJECTION RADECSYS= 'FK5 ' / REFERENCE CO-ORDINATE SYSTEM EQUINOX = 2000. / REFERENCE EQUINOX OF CO-ORDINATE SYSTEM LONGPOLE= 180. / PROJECTION NORTH POLE CDELT1 = -0.00277777777777778 / [deg/px] X AXIS INCREMENT CDELT2 = 0.00277777777777778 / [deg/px] Y AXIS INCREMENT CRUNIT1 = 'deg ' / UNIT OF X AXIS CRUNIT2 = 'deg ' / UNIT OF Y AXIS PC1_1 = 1. / X-X AXIS CO-ORDINATE TRANSFORMATION PC2_2 = 1. / Y-Y AXIS CO-ORDINATE TRANSFORMATION PC1_2 = -0. / X-Y AXIS CO-ORDINATE TRANSFORMATION PC2_1 = 0. / Y-X AXIS CO-ORDINATE TRANSFORMATION BSCALE = 1. / PIXEL VALUE GAIN BZERO = 0. / PIXEL VALUE OFFSET BUNIT = '(MJy/sr)^2' / UNIT OF PIXEL VALUE END D%D;CW|CD!5CC'UDC}ED1DXDk%Do=D+KC;jC_1]C˷CQrCHC3C%DNCDmCD(9C}DSjDCCi'BzC^jCfrCD<_SCCdPDECCCzCC1jC8CBC C)CB.CCS4CIC{oCJC|D(mC!AC-DD D +DwbC5;2CCYwCCNCB1BpBC0CDaC΢qCGVD;&EE&EXDYaDC|CiCRC-KBC+nCcCeC!B;C:CbCSbBkCB$C?BjB3LBsBB~CCHCЌC CD$XDWDQS/CRC- C%BĸCApB?PBJBBB:BWvBBQBfC IBCCD DD%+DkPCB}B4BoBBQVBRBB8,2BBBjrB &BB‡CPCpCL`DbVD2CDf C^fD_uDXCCik^DttD# C`dCC1CDv/CC7BCrC3-CF}BCBBWBB2BOBsBjB7B?B&BfB+C)C|COD̤DDd CDaCB̟BvCBB&aBBDBKABiBzBnDB\BsBeCC/C0EyDECa CBBїBe9hBS߿BbBHKBa&BNFBFB4qBnB!B8/BC0CfBBB B֐BZu-BeBhBӪBCBBcgC6gPCDd&D!CrC_HC/BB;BBCM.BDXBNB35bB] B!LDB9cBN BލBĚBj7C2KCD=[D#XE CC*‰CR"C*BBDB|.BCE C]DnODҎ`BBBlI+B=X:BFSBdBr!B,B.#B`BB BB C#CC!9GCJgCDRWCÑCfCqCM$BfBBpBWBsBBxBXBvBU2Bn kBB`BŷSCCo CG?DDp9DeCMCC$"Cg.CBǔCtBzBRBV+BXcBB.B;jBZBB\BWB5jB,CYs4CDzDD`CC:DaCD>C7CC2BC؆CCOD)CtmCtZC>CICCJCp7CTC6 CCCP5C'HC֏CTgC.CфECCDӁCmDCC3CCr?Ca C~oCP CCCX4C3zCCMCwC2yCwMCCmDCXCaCE-C~CCdC- C~CgCCC,CFCeC1C3C<CFCCb/C Cr2C/C3CCboDHcC6C@#C:CCgkC@C^CC:dCTCqDDHCCCCeC2ChC CGDOC CĄCaC~'C@nDCCc CC2CvDQkD%GD9N-CPCf2C D7CʀClC'C`CxWC>B"PC C*FDȩCmD?D,Ce&'CKQCxUgB)B[BnwBB BB!B-lB|BkoBHBBBCxBОC1EC;BCG4IC^CCsMC45BBVwB^ BW.NB,0dB dBCBx-BFB#,B i'BUBjxBsBGBFBVBBղwCC3CoCcC20C)C#{DBDXBD%)D2CAhCbC0QCDCUbCM`?CBYqBBLHB..BcpB=rBWܡBAL&BbX`B~BC CM ^CCDDqXDTNPDD"DfLDDDuDDDiDmDDjT@DDe DFDI Ds5D[DL\wDDXDݲDYD*MD=NDzDD"D9DID6GQD;DKCDL)D6/D%CCgD D/kCҿD)C CDCԶhCLCɏC|: D C^D DCC┄DAmTD;)D [dC|EClD_%FD/2DDCJC;8DBAD,&DC8C~CrD T;DhCC8CɆD09D4C DC*CcDr*DD C?C-CYDCCjDCάHDD: bDrDCeCC&CuFDDgG]C~ DC`Cm|D.TDXZCWC?EgD:DDCCCj$CDPC/_C|CB&CNCTQC{XCHhCCqBBBBvBnJB]B1B`DBBT?BizBBw]B<iBJBoAC?C$CB:uC{0C C-YBBpp&BB:!B BAEB' BCBB BABBI+BYB|%|B{B4BBBBNC#;BBABɔBBfBQG:BB)2mB FB'B5mBN1B;BP~BB`3B&B ~B"B`+C/CB]|CGByBȓJB!B{BCB=B_xB_qB!|BA&B5BRB+DB# @BP~B[ՐBf@0BՓB)sB8B*ByvBnBZ BBjBBB}BBB~"BB{BBIbBBBqkB[BB*CBES,BCBQ~BLBBRBuvYB ˫BkOBXPB7B?vBMBeBt?BvHBeBguiBIBEB)=BF/BQxBFHBBHBBB=_ B@ŔBP7B_ 0BRB1[BQBLNBlOBP~1BBjzBTsBz#B֠Bc.BBBTBBJBUBqB"BBlMBBB!BtBBB1B?BB B?B:B{qBJRCB_BLBBC3s{CCSCCVB$BAC(wC'MBsLCV۟C'C]CCCi$CD1|DD"C kB(C@&hCC".tCBB >CCDrClCjC(HCkoCtBGBB嘁CFTC^C;CEC^[C>BACBB0~BtBMlB B`rByEBBuA BAH BB (KA8B.B /B*BB>yBNB79B[8BUBBxB|xB,TB0pA:A AʔA̶A}A4AAȏA͠A` AyABQ>B*B3BiBBpBB ̒B%?:B%B$B : B{AvB7ABAAAA A^>AΌAƱA؝BBBQB6 FB?BG_ B=bB]BCs_C{.CB_-B4}CyZCэCMC/BQ"B\NB)BB8\B5yBQeBoBnMBE BN}B\uB9-ByLB4 B%%BBY9BB-BBBPBiBr6B#GBB,$B UB eAA3 A7AכMAŌAnBAVA(AwA;ALA+A:A="A釨A|B BB3BpAAKmBMARA AAAtAB‘B$BX8BBB A!AxA6A!AbAA{A&B B(BB6BO}^BhB2BLxBo([BU'B`B`BfxBd5B8#BQBntfBBBB6BG^BKB-{BXIB5!BIBLyB@B^gBdBZBgUBfBGs*Bw%BfBmB](BBmBu+BB@B{BPBBC;]BדBĥ%BoBBCrCMCLC11ZB C*tCY!BwECBCd+CڧCBUC_C (IC6CuYC0!jC<C_jC+C+CdCCp)D 4DR`C"CC[2 CD BDYD DX0DlJDVC[COCpBa6C@CED9cD2C+CWRDKCsEݨDtCC]DCCp4CxGCXCYBy.C?XCDeC{TB3aBoCbrBBBgKBBҿBBBiLB^KBhB߀BBRBjBfNB9nBE 0B'PB+BEBBMBܺBuBBBBMЛBqUB~YB7)BB[Bk BăBMXC3RB2BBbBRCqB$BCBBnBvB۞BٮBЗB BB¿C ZB1C(CoBB!BBnYBBB3BX/C tB{qBC5B$C CCKk-CGBTCdRC#qCOCg&CmBbCċJC7D2Ch[CCUFC?CUOCB7C)C]C7BfB˜BBBcB7 "Bf>B*B.iBBFBQB)BB$=)BNB_iB.B%~ B<BBB5LB< B,5B:&BVB7BIB#G0AApAA'AAGBAŦSAAȠAڤAAaA߆A3TA[AA ASJABAܮKA3AAA6CAA)AqAzAA_A{Ai4A}4AAAA;AA5_A0A`AAA@A)AIAѰATAҋA#AjA}A;AsxA~Ah0OAA~iAy&A'AnAzA "A۸AΦAݝXAAֽJA[#ATOAArgAA4A>AYAwA{APCAAXAaIA1VAA!AAMAABQB Bh4AnA.A A0mACAr~AyA©AaA^AjAگYAAԎA AAAI#AޙA׾xAGB BB]AEB7(B!B BVB(lBwB B.kB$B)$B&)FB 7BTB>FB=BF-B/BS+qB,VAM)B&B;lBBB0fHB6;BeBjB\uB[~B7 B0TBX,gB1Bs#B]_B6B;BoB@BXBj=RB1BmB6BzB}Bg_BB3BcCBB&BQBVڅBB^Bq3BBCvCiBpBBCׄC3hB BxBPC:BkCrB3C`,BCiWxCrC[gCCBDBC'FC&C8B_ChC:#DEB6BB CBeC25kBgBaoBnBBAl1jAhA|AlA}ArUA~APFfAn0AXAxA Aw4AnA)ALAAA|A3AA_Ac`AtAAX%tAY^Ae.AR-"A`QAbCA`ApA/8A.AAţNAэAsA2AYAكeAxAAؙCAGA+4AH~AAAAAˠAAA]AkA?AA5AoAAݰBCaAqB:B/B&qB BWBOB|BV BA-Aڮ}BB6BBjZAAٓ7AaAYAԿALACBPB1UB0B'=B5BHuBwNBdB1BA^o A A}AANAgABA$ArAѬAAfAIAAQAAƦAACA&AAuA)AvA=A]At Aj߸AvXAAPA-Av:AA,A|AAcAl8AkAg]AqA]MAB A<6CA=NA8CA;'A?AAJ٣A`J-AaAX@AX~ACAdAfMAAA~A"AǨAvAvAAEAjAnALAHŬADADAWAU5AmA9AAVA=XA%AAiA'AAӢA8AAAAӥAs&AA#AH?AZAAAa9AABA.AAϠA鲝A}AeBLAAXAAkAlA~AVAA۹A2qAv2AAAAcA9AзKAEAǃA$xA¾A6B$AEhB1 7BB(9B@$BEU#B0+BK4BA}B{}B,B2BVPdBV~ByGBJByBMHBlBdBs4BoRB>BBNB~IB6BB@BB XBոBfB[B.B]BVBB5BbC5NCC_CasBz BCTflC"j CDCO C=CO3DnD. %CEPB%bBC3C_C^B)C)A'CG,CcCCm+eC C~dDQ9 C6DtCMfCC4DUC+CB4CHnC4CtC-QC.C 8nBrCMB~BBRMBvBn%BtsfB^iBq` BPBOBL&BrB7~BlBAB{B6BA_ALA3A(gAA'ABA{AdAAAA"AADaAQAApA A4 AAҲA`lAAAAXANgA An3|A AbkA_AL4A^!A{'lAE .AbAxXIAocAA2AAAWAApA A A|Af)AAAyA}]Ar,AkAA\*Aa#As AAAdAAѱA+AAsA[AA`]AAmAa@AS:A'9AZAahA9AFAAA噃AAA]AΔAABABh}AǣBoB1(B'UbBB8B/BKBRBBiffBsrBgBVB[!Bd?,BpEBeB\Bg/BBRB^6BHBBB׭B BEB?B(QB#gBBBBCRCPZBؗB5CBB CBߜCB{CQCaCGCC{~BCRnAA+AAݨA]AAK;A AEAABA߫ASA-AߕA iAAhA`A(AB]-AtBИB>B AB4BCJB ŝBMB BaB,B"aEB1B!!A-(BB.6B.tB6B2B$SB7BX5BkgBdB8BB{BvBRB(:BkBBBzJBԊBCB$NC@!BBB8ZB{6BYBxBBBxBk5rA?-AIAH#A^aARAj|A9A A#ANA/AWAvA3A6AAøAk^AzΎAWLANcA7WRA!A#rrA9 SA;~JAOA\9A}.Apm{AG:A_AqA!AV)AAAA4AuA4AGArGA> At,AwRdAhAiA,kAWAp\hAfѺAlABAQsA~A>A[OAmAAl&AAh}AWAAA/AjAm.AKAkwA}9AQA&AnAAȫA5+A$AwA#QAAaAҪAȭFA\AB.BSB A)AAGBAAJHBywBSB*)'B({B5BNB5BCB0YBeC1CKCʷB CCFa$BBC_C iBϺCsB8hB*JBsB@;B!B?BB%?BB(BoBNBCBBBN+BZbBB }BB AA6B'BVAA㖪A8A=A;A8A1AAXzAAA¡AA{HA A:AARA!AcAaA7dqASϞAZ6hAUjAdgAf5ASKAHA@{ALA;hmAEAJZAdAPAUAG~AlAvjAZ~AhARAG A4oA:BAfA./A0[A,A%%ABZA-AA2A:KA@UAC*A\AcTA[JAw-Aw&Al(5AvAzsAeɞA~Am:AQAwHAbOtA[8ASHA@)?AKAsABBNPB]qA/A/A-`A'dA.&A3FA*A8!A4nA&dA/A,I&A4A2A3AH7vA0mAX=ANCAK%A(ҋA$QA#ACA~AF7WA>A%ǒA4Z A(AMA SA$]A@@A(A=AkJA xmA ACA AUϷAwo2AAf+ARTA=A.^ADA7A+@A'A7U:AI÷A;1A? xAjFA/BALABAS1A&ACA A[A[A ĘA/%A)AkJAA#iAAAA=AO3A A ZAU:ARAтA(.A5+gA"ZTA%^A}A [hAUA!A+5A(݆A)AAAB[AIAc AWxAPМAJAW#uA?XAE@A>ֵA:A;JA'RTA5AAAA"B@+BNvCB:B ^BAۗjAdALkAA.AAAA8uAüAA wA.AAϢA4AzA»AYAA4'A#kA?AxA'SA AAkAF`Aa$A__&ARkA3A"A@4ACAS2A;UAFAEA4lAGHA2JAxA$A*]ApA)AFjYA.gnADZHA6zAOiqA`zA5 dAA A AO@*@bA aA\A @ZH@@*AAkA l{A7A A(A7Au%AA&A#A+A"qUAAw[A-@@C%ACA9A S7A AAYAEA"jA,pA3DA:AK_A8YAE[AP@A5(\ALF&A?;A5FArAAA pAA GA CzA)AAAA,AVABKAB7AQMA`AaAcA\AZEAUAT~AR]A6IRA3$A8A<8A;jA-?A>A%OABA!x.A0AA37AMzA_AmVgA|AAAA|AaTAZffAaJAYNAnWAdAugA{,AhhApApOcAo,GAAA5A!oAVyA|AAAA^AFA AWAqA[AmAAkAAR ACAA~AyAZ(AڨAA{A@B.BdAEB ۇBzB-.BMVB4+bBB'eB*P.B$cB%%B+ՋBA BN;HBU/BB9B;(BvQBۜBsk#BBLZCB.BgB(B`BnBBB\BʰBZB Bp_BBBAmVATAAPA'A_AqAiJA_ALhA@rA"fA0UAuA%kAdA) A) wAAA 7APAqR@AsAVAAA A)AGA AAEA8L@'@E@8@;@ @@>A@A@@@@ A+A{AAOAAYAA DAyAXfA!AAAAe@A"AAA AAkA`AA)A82A6A>~A1i^A:r?AEnA:EAEAEUCA8eA- A0VA#AAEA AuA}AA)A)vA0HA2A7UAGjARWAT4AVA_AWT&ATmAOASA=ѣAAAEA-IA:/A,EA)IA#\AQAAUA (A3A@bAEAVZ=Ao $AyUAs AlAvAmAVbA{_FA|AoAAa!AWDAtYApA;AnAAA\A2AAm_A^AAA~.AmwAFAiA AhmA24A/]AÂA?AݏmAe&BIA\B{#BnB 5B PB&!B'BT&B#xB92LBKt?B(BB]BBBgB BBCفBB;BCCC8EBҲ-BcBhqCA#Cw9C=CC&!D"DD#CϡCKCC]C>=&B]2BB6BBqBB:MB!GB#B.B"B!KB(B B MA8lACNA@AxA|SA{A> AAAWaA7AACAP&AAuAXAkA9AAUAAA$ABhAVB FBhBٜAؕB"B$JB6oBHB-nBDBR\BW|B&{BHB"B[BaZBGBfB;CBZC=B=cCS-CG.CY;B3BBC\yDoC-yC7C(YCgFCnCSClB4BBZC{B]B{WBBq B9BRlB@AB9BB TB~BvA可AAqMBSAA A`wAA(AâAA8AAAwwA=ArM+A\AZ AO-ZA:'AHA=4A@A0AC IAIAE8ABEACZA#.A0ACqA17WA9IA(%AA0T1AO`A5,AD vAsA.A!A} A TA A AA AArA 9A SAAA pAf:A[A i@`WA=AKA A_ APjA+Ao@@U@&@@h@њ%@RO@ڑ@tlA@)@+yAfHAA @A =AK7A&Ac AZAɷAI~Ao~A A p@YAa`@@U@؃s@=E@ @2@[@mz@@TAA nAEAAA WA@AA LA.D@iA@@ @@"@@-@@%@P@V@;@AWAA hAN AA"sAA AXA+AA9^Ar?A4IAPA\AGA g.AR@׻A*J@cn@QAASA8yA9iAJAL<|A?=)AEAQYDAO0AFr:AAlA:JAX[6AJAopA_SAdgiA^[AbAaAAx=Ax2A.AzA(6An;AūA@\AAAAlA=AA/IAAA[A ^AH?ACA޼jAA8jAApBBAB.|QB BE@7x@n@A@m<@EA!AfAi@@@@&@5@@̃@e@t@)0@^n@b@ɘ@孋@橁@A))@ 1AzA A *Ap;AWApA HAaAA #A o@#f@@\A@@@"L@.@@A AsqA"1A"A$:}A(#A<;A,$A)A!aA"ȤA,XA(`A%0A`A]A8&A WAZ A(A7A_ AA`AA`AA)0A;tA) A1hA&A"A9%A+A35ADA!|A2cA-aA0AhA9AAA#cA%qA06A(AA1AE,AY8AuAXTAcArA]Aj;A^=0AODAhAW_GAn-Am1AqfAlAYAYAAo"AAaB&AyA荾AnBB'YB`B3u@B7BWhBeDB .BBVBeNBB؁hBC2 C![4B\C>5CpCarBgP|C4B C|eCwB*BsBoBxB3B>BBLcBP"BdBhiVB;fALB.B(T5BA{AIAHA{AAA8AgXAAmAʣAiANAa AWy)Aj5A6ARAZTA^PA`A|Av AdADABA3G&A;%1A([AIA!A#A AA[AA(A!A)A?A rOA AAtA A I-AA!A&"A>AA8#AAA 8@@@@j9@@@2@ @{ @5@@@w@@@@&ADAAL@@8@l@@md@J@A@M@@ @V@8@@@τ@d@!@ٟ@j@@ e@]ArL@KA@1@|@i@|@Ҋ@+@֋(@@.@@q@JA@AA A_AGwA}AWA^FA$7AAԔAAgAA|A!WwAAhXAKA AA ŒA AAA@A.A*oAIAQA`A2Aѵ$AqVAAAbAĥBNA}AA@A)B 3JBB B 3B$=B"ZKBBBpB2lBBBf@B@B@ BR$BO,CC2>DX@CaC6CPB&B~4C"B BnBl1B^mB^8B=BB4ABG:B B1:B 0B!>BFB* AA A-AtAѨA悳A鰙A"AA:AqA| AAA=A}M#AAֹA__AHA Am#ATAZ8A\AnA A\A\4A>lAqA :A7AA A%AAA ]vAA fAOjA A$AA]@o@L@d@@DK@nB@~@ @w@Ŧ@޼@h@m@R@7@E@'@A@@@@n @4@m:@@6@V@L@@;@@@<@{@C@:@@(Ab0A@@TA @A%AAJAz#AYAbA b@A]@a@@@@@@n@ʏ@'@F@ AKAgL@AA AFtA j@9[A A@~@d@@K@qo@@o@a@ '@׎@4@@(bAvbA&`AҪAAYA A-0A%)A,|A"A(A3A-A4fA;EACA9NA<A@RA>AZ˼ANFAe@lAcAA~A{sAiAA/AAAA9AwAcAA MA.A6RA`A_AAʇLA A\FAۘ|B }ADAfBA.AAB_B 4B%pB AB&BJnBJB%B@B.hBU"BQ!jBBIBWBMBCBTBBITC%Cg9]CuC(ZCcIDLEj@DhDQB{B^B_ Bu Bx`cBeBpBB$BY8B> BK TB4LBA7BAf+A\SB 3!AA9AA͋AݯAATA+AA6AAAqAAEAIA-AtA(ARyAYAaSAN܈AVzA]ASAB(A7A=aAB A;EA=jA7 A7A89A&>A^A!vA:AsAp@=@@@UA$Ai4AMA1A4A&AAbA ALKA AUAA AQA ܔA[AdXAd@Y@ړ@S@N@'@v@ǯm@&@ @(@@Ր@@W@V@@<@"1@Fs@@ @+y@@=@ܷ1@7@8@ń@@8@;@Φ@@k@@ٍ@Ի@ނ@b@:@@@;d@uTA@%@6@e@k@x@FA*A%AJA (AeA'XAT@F@@|@>@:@1@&@N@E@T@q@:@gM@@S@,@@?yAa AM7A BA s%AAA$`eA AA KA+bA'A%5&A.%A)VA3iA#<9A4A$ABkA3ACABAJLAZBAx(A}0A[A9}AAiAnAAtA$AOA>ACAAUA/AIAB5AxBB BQ!B3KB/B>XB; BtpsBQ8BJBUB_BGBBBK$BB_BB.BB]bC&>}B^C 1C2CGxC}IDDj DHoD[D CrCО_CCB}BkB)TBBOBȉBB[q4B"B.B>jB(BBB AAeyA8AϬAْAGyAA;A[AA AT?AAe$AwWAVAQ A`@AQAC?AHD"A8-iA2%AD$A5wA,A1- A A#.A(U%AA@A&AbA%3ABAA VAUAAvA A A9 @<@@Q@@@@ZAuA&dAiJ@A0hA $@A zfA ADA#@YAXA LAA vR@W@@@>@|@&4@ @@+@@@b0AtAfrA0AW@A@ӢAAcL@A@q@.@@e@|@.@˅@Ҥ`@w@t@ˇ@J!@ek@@8@ @@]@@@@{@J@@@H@@؋@@| @?@J_@C@@ @ն@@,@_~@έ@w@U@х@m@k@"D@@@@ľ@5@@2@S@6@ S@]@˂w@t$@@<@p5@p]@X@[A@좂A@FAL7@|A{AhA|AZAA+RAAAA"KA AA#AXCA'Z4AdA5[A(~~A2A1TA;A]Ab`fAZA]F!AaAquiAjATAcA|i_AA+AA"AAa AA.AlA8AEAz7AokA BT ASAAaBTBBBB8AorBjBkB+BfBUB`BC8бBDtBDp/DZsDBC`DSEC|RBjC;nCCBBBӠBBtMOB`.B(]B#BBB`AAAe:A#A\APAA[AA(AձAtAqAB[AlnAbZANAMIAo0Ay]AbOAJ6A9dA'TdA-:AL,A2GoAA}AɋAu_A,AuA;AA{SA&7A )A 7A DvA>@NvA<A tAqA@AA@@s@s@@x@m@@{@Ȟ@F@K @@@(@ @a5@K@йS@#X@_@=@@(bA?@@z@m@.@V@-@z@d@0L@ɺ@B@@Ԇ@@@ z@R@T@{@@j@ }@Y@@@})@X@L@ӓ@y@Ӡ@Ƽ@ˆ@d@S@˺@Rw@i@BU@sAAAwA AwA@2@X(A AA\A A@V\Ay@L@@o@P8@,@}@ J@|i@@Ġ@\AA aA @A NNA"OAAA)@ڲ@]@A@흺A{AA6@_@@X@Fu@x@)AA$AA iA~A3OA&f Ae{A&)8A-A8AG5A2|A2A,'A'PRANBAH DA8EAPA@AD^A>A_Ay0AIoLA]:AyAAA{A]A^A`AA5OA#GAwEAfALAiAAAARAKAAAwAA^%BB$qBVB́B BTBn:B[BgGBjB@BB|BCgEzVDD$9C.C?CWCBlAC9ChpC2vC Bf sBu/BB5BUB$BBOB_B}eB`mApAAc1AA\A܊@5@@YM@@諂@x@ @;@@@@G@@@p@͙@@T@&@ԝ@.@I@ā@$%@v@#H@@@0@ @ @3@7@@@6@Дx@ʜ@8@ʙ@m@P@@違@*y@@ @x@᱔@ִ@A@:@@@@b@=I@@@@Ȯ^@#@b@@% @@Ȧz@ؘ@AeAArAA AA3A&NA1ADY-AP6lA>?=AMAGAL̊AO bAYAKAZDAIAm,AcA\jARTA]2#Az~AciAteAFTAwAs`AQAA AAABpAAqAApA/IAAʬ~AAʕVAPYAfAەLB  A?AzABBBkB BlB9B4mB&7BrhB!BX?BV-BMBBo5C ɊCD0CsdCNBGBՀCBCB}BVBy6B]aBCBBwAB9BAPAUZB|BBuB!IA\A&zAALA AA"ANA_FA\AdANAAAAs:AA[AtFAm#AH=AidA\ JAAT*%AIMAAMA20lA7SA#A(KUAkA AA@@L@jAŒA A|@'@A@g@VPA@9@D@@@~@/@@M4@@ɼ@H!@@@2:@X@@@ @@R@O@@,@@:@ʞ@H>@"Z@@k@@du@@͐g@H@@@e@@Z@ @@ e@,S@@@ቫ@WR@하@8@@@F@]M@9V@ @9@@@@!@߹@z@K @o@ĮM@;@ü@u@@a@A@Ѿ@@@rH@nA8@S@A'@&@VA@;@l@@@芹@@@ڗ@@@V@r @R@2@@AA AfrA;AA7A6hAB{AFA>ACArAhLA:xAAAwAAdAA~ARAAAAAAAAA^A(A=A9A\tB&B A|A:B'}B$}B7}BBC6B"BR]B!BB_BHB*BBzB^YBB> jBcdBoBCPmC]CCmECCCD_JlD>6D^CÙC@DC B7hBuBBBx9BBDŠAևA#AhB.rB^AFAʘAdAA#AaA|vAMAt4Ao.A]AEAAVAdAx}AcATnAKAUAVAOkXAO8A:GAIAO.A9@@ߔ6@ᯇ@ @@ػ@ѥX@@Ԅ<@2@@̢W@@ü@@@6@c@@*@q@{q@(v@ĉ@v@#n@~@̊:@Ԥ$@4@M@̊@@^r@MT@ٍ@-@1@A.@ґ@@Ȗ@Ó@) @@q@~@@@#.@>@1@ڑ@'@@i@_$@װ@ @ϴ@.@ɦ@ϧ$@Ԟ@?@گ@<@B @&@͆Z@@Ï/@xB@Ѭw@ғu@~@@@C@z@6@9@@D@L@@vA@B)tBpBF8AzB 6ABaAA`A ABAfAAA~hA"AAfFAJAIAm'A\ArKA\RA_E1AI}^A@ANA?tA*FXA.APA%A2?AWA)A""PA A IA LxA+A AA gA 8AeAa@@@N@<@.G@S@Ы[@f$@e@@@8A@@@@U@@@U@*.@(@@@\2@=@/ @L`@@@F7@@E@u@c>@@"@H@@N@}@@@Tv@p@ @>@@@@Ճ@a@4(@ܒn@@@׋@@m@@@!@@r@S@@@@R@F@@ٲs@ܪ@.,@ @zE@[.@−@A@/w@"@σ@f@ @֠@ƂA@t@_@a@ð@M@@Y@b@@-P@@z@R @@Ѡ@O9@d @@@Œl@F'@(g@=8@@@6@@˲@@ң@ @.@4@^@ۂ@@@@YA An@3AxAA-A;ApA$@1@A@E@A AKA|AIA AAAe-A&}A.`A=A.A"A1QAD_AhASAb3AIArAr>AQaApAt;A}AAOA:At!AA A;A-+A4A3hA'~GA3A@0A9ƷA-_,A_A^A+NA gA @@]^AFsA sA@~A~/AzAyc@`@A@A@Y@ӜA @@=@@ô@@Х@Xw@ @I@@|@5@@@r@~@%@@t@c-@m@v@2@6@c4@),@$@;C@@>@G@ɬ@L@o@9@R/@ @ @ @l]@{|@)-@@@:@Ԧ@Z@1@uo@Ɖ@@'@,d@ɖ1@@@:@:@ν@V#@ĭ3@)@4@@L@@R0@ @Ё@d@D@ԁ@@ @A%AAAOA@@v@ب@o@@W@Y@@@@@;@؆@g#@n@y@@n@5@C@nA}A @@b9@a@l@A@@@**@i@䙖@?o@@5@M@X@[@UAzA@ AI*@AnA,A7AA0AAAA4$A?A&A A A%A% yA%pA.bA{AA&.A+AMA?AD1AHɪALGA]SAQVAbAXAu\A, AA\AerZA`A@A0AA0AbAA;AA_AǛAAA*NB B'ڭA@A(AABf6mBAaAaAA]A^AXAԹA AA3AqDAZA!A'AAANAdJABA5siAOKmAJAZAAAYA# mA'K6A)A#\AKA$AYAA7AZACAyA$A P@-@n@@H@z@@x@P@ @@m@f@§@@;@j@ @zS@X@/@`@z"@@Y,@6@#@%x@@@%@-@L@@M`@9@Ŀ@@ @^@a-@?@Ag@@m@@ɱ@̅@jW@@2M@%@:~@m@!@l@˟@p@Ď@0j@H@@Go@L@@+@@V@@4@@@@x@3e@y@~D@ :@^@B@׸@kd@'@䅳@8@!@i#@U@2@,@+E@@n|@`~@@<@b=@˥!@w@˩@N@@<@ @A@AYAhA A !%A AAASqAWA AAMAAؙAA AA A.IAAA2)A9A(-A4|ADAAAZ&AHAQA=*A^oA_AByA3^/A@|.ANuANMANKAS!fAVNAWA^ĈAl@A,@YAƟ@A nA̍@x@L@@J@8q@{"@0@5@֗@҅@F@@@=@d@L@@@@@@n[@LW@@-@ҧ@_j@KH@Y@@@C\@\@@>@@h@@|@@@@@L@~}@@e@@@Sh@@L@ĝq@B@S!@כM@ʚ@޸@7@_N@(@Z@Ӫ_@į@@D@4y@@ٗ@@W@ڶ@@@}@l@gw@B@_@ɼS@L@^c@ф@6@"@4@J@6i@@NU@ɯ@I@@r@@R@k@ W@{@@d@@@@G@@@A6AA"AA>ASAېA A ŚA1A aAsA!A&BAϨA+?`ATA-#A)A6A2>AVڝAKAG/YACXAj|QAm}A[A\7AaJAhAYrHAqAy)A^(AArA6AAvA~)AAAAk{AyAyAc(A AǂA쀻AAtAYBA.BpGB3NB B BC+FB*=BC^COyEB4hBsBp!BTBSBVbEB B=B?4iB3B bAAA6AAA4zA*AioA~˒AxABeAboMAh AoAqAAéA[#A_AQhAI0A!WAo*A7A'%A7:sA/TA8l_AGAЉAMVA@AjAK@&ApA7AAA A OA@2A@@@G@z@@@ɐT@ʉ@вfA]@@S@@ܝt@ܗ@@@G@@«}@ 0@J@A@F$@k@/Y@@@@0s@+@@f@@_s@@‡@H@@V@ @j@l@@J@@(@d@q@wk@X@T=@K@@t@G@@@G@S@[@r@w@U@U?@C@¸]@c-@_@L@Dw@-@Z@@e@N:@@N@@0d@@S@^!@@|1@@[Y@]@[d@@S@k3@>Q@@@갾@@0@j3@j@+A@!@8@ARA@@\Ar*@kA 7A /A%7A$A/mA8'AK#AFARA@vARA|ZA[Aj|A^`AUCAZ2A3@AC+AA| AŖA cAAseAAfAAլAWA׷iAcAB_;BB B{OB![B;cBmBBGgB?RBB:B8BB+BNjBBtB?CA+C Cd0C D ejC=DOCIBnCOB0CC CDC>yBBFB1 BBY7BNB/NWB]fB:AB AAՏ1AaA_AA"hAHSAAðAJAwwARcADۦA3Ac3AAlyAdA<:AaߐAYX?APA:A%7AAAtA.=AtAAA'ƈA$ÃARAɦA%WA'A@㩿AA!/AP@W@"Af@@@ @@m@[@@@,@/'@J@@Ŋ@4@PE@U@ڿ@M@@Μ@@p@c@@B?@@F@m8@#@@@[@@ @j@q@@@3@@#@+@@e@n@-@2=@,@!]@p@@p@@@g@}@C.@9@@JP@u@x@@f/@b@S@@A@F@Ү@v@?@v@2@?@@+@#@a@\@@@<@V@M@m@f8@t@=@}@@E@>@@[@d-@H@Fv@Z@I@Q7@@@@@!}@W@F:@@\@@@҂@@;,@`@@@=@D@@԰@7@@@sr@ @@=@ՈACn@ޫ\@-@@[@M@'A[A ]A@JAUZAoAAnAA(lpA3A+WA")A2AHOAT]A^TAZdALAFYAN UAe:TAVGAuxAnArjA>ApnAqA"A}jArlAhAAApARA1AĚAAB xBqBҵBBյB'B6NBBBuB$*JB:B͒C!KC*CMC>CCjt$CuöBdfCV2C?>BuB6B,WBbMBHB=LBB3BB ByBSsA?eAŚA>AA1ANA,AAAstAkA=*A[۫ASARAVbA'FA yA"qA)A"vA!wAIA$A$A++!A%A=AAr@A$@h@(E@@@#@Ŏ@k@@@#@i@@S@5Ak@ː@%@9@@{@S@ش@?@@f@@@X@9@©3@@o@@c@@zl@o@@@@-@@@ @@+@X@@U2@@O_@C@ r@@dS@ @L@:@r@0@̼@G@@2@@p@+@t@@@!@s@7@1!@@@P@|@r@@G@Q@ܴ@@@*B@V@X@@@c@5'@إC@ؖ@"@l@ϴ@~@K)@+@U@i@J@@f@f@,@;@@t@@#9@b:@@c@w@⾷@'^@M@|@@h@T@@V@М@@*c@@Z@ @}@@ܣ@ٓz@ߡ@f@@rA@aAArAA^G@jA zAoAA@AA HAAhA"AAԓAAA&A,_A$A2:AEAO8nAFZuAFA8AFIAXA[AOrmATAXA?ASrAS SAAhM1ApAA iA$AEAAukAVAŗAdA\ApAZASBWRBaӫBg)B&BSB̜BγBYCPx C.C]5C6C}DCxCBWB&BΒVB£BSBH0B-bB#B1BxGB B3BB;B>BBB"3AAʻyA,AMA֗AA!AAAgA)jA{RAA]AA8A4UA9 5A#HAG+AC=AUA(qwA+A*pA"6AA }8@6A`A p*AAA-@@Sz@B@dA@q@̓@F@|@n@4@6@И@j@Q@"@@@@@@I@ju@:@@@@@Q@c@f)@s@@`A@@@@ @@<@@@~@@Yj@ .@@@F@@H@@C@kC@(P@@A&@-@WV@@ @7@X@i@@@L@/@v@@#@A@@&@@@{@@@N3@R@@: @F@p@E@U@̷8@Ŷ@2X@@@@N@a@f@m@ @L(@ߕ@x@@0@>@@u@P<@g+@#@RQ@@Y@Y@љ.@@@@y@*@@@C@H@ V@NO@1@J@1@@@VkAA A!AAAkAnxAA.ˠA1=/A"-A#_A#A24A-A*C|A%MA/'A3 A4iA3ϽA+_AA-A>ʟAYzAAAYUAh}A.A@a@D@kN@FK@Ԅ@n@@ά@O@3@@@@'X@@G@ @0@7@@s@@ @!@@k@@?@ @@o@dw@@U@@ѣ@@@Ǽ@ @ @Х@P>@0@f@@+@^@\@l@T@w@@@-@=@@~r@:@@@P@J@i_@@{@r@@@ܶ@@f@@@t@@%@e{@*@Q@@Lc@K}@@H@8@[@)t@a@e@a@l@@@@0@c@@3?@ݫ@@u@'=@@"3@+h@0'@<@@T@@@@@?A@gy@@@;@@@A A^A*A%6AA-'A(nA2ܺA3FA3iA"A@[A=A7A34DAKMAK>AJZQAq7AjЩARծAW#AHAYuASAq[AQAX\AfAAAAljAA(ACAAAMBHB%B VAAnTB.B_B'*ByB&BA.eBE=B@$BecBB&BgBCNC?r~ClCCjC C?I+CB3BBjgBL0BBKB$&B"AVBnB~ZAq+A&AAA A6ArAvA}AALAUAA;A-AA\pAF&A?LAPAAtAP`JAKNA=~CAO#A[Ac6AzȭAtWA`kA\GA AA԰A#2AA.AqAbAAAGA3BBjAUAA+kB")B/B^֟B+B BJ?B^BBfB4xC46BC5[CDbC2CCj7CCBXBդBIB-.BO\BB::AvA BcAsA AoTAAzA(AAmA@*AZkA1ACAAarzAXzVAVAlALAhAfAD7A4LrAI>A=uoA2fA%bA%A e=A!A'8yA*WA! 6A,A'*AA@gA0A@Y@*@QAA&.@@Q@֙@ٺ@Z@&@§7@k@@h@W@@5@ƥ@G@@$}@%@g@@,{@@@ @@^@de@]@q#@@{@@@ɺ@L@@wW@@ڃ@@k@3@>@@=@@-D@{@9.@@*@@@g@@t@@@R@g]@J@W@@8@%p@@u@;@@m@<<@@@l@@@U@Ɗ@@A@$@@@@@N@@CQ@@ @@w@C @)@e@ŭ@،@@2=@@h@@M@@9@s @D@@.@\@*-@G@@@ @)@T@{V@@7@m@@ 7@L3@{@W@b@ϱ@J@@@@-@ߘg@@톜@6TA@@g3@A H@AA AlA AAA!AjA);A$TA)A7\AHA3A3qA8-AOA]ZA]AdՃAxA]GA1AAJ"A%AAwAҎAA@AԷsALBcyBBrB(BAeB'B1e BAB0BkBBhyC?C7JC')C i^C0CRCCBByBB?9VB4oBFB6$B) B1I.BAƠA8)AļAXA A~hAMA'A-}AACEAxƞAzZArqAmleAEA2\A)A+lA[oAAAAA%A6!KA AwA´@AVF@Un@Hl@@'@2AԦ@%P@{w@ @&L@@OU@Z@a@B;@G@޾@@{@@@ @M!@®@~@|@@ma@@)@ @E@@@!@@@{F@c@d@p@E@4@Q@@@Ɍ@(@H@{@@Hm@.@@@]l@f@@@7@O@u@X@^n@S@dJ@L@@@@@{@@jG@'@5 @@@@G@D&@P@J@-@q@@@̒&@@F@=@\@@@:@Ì@@@'@W@@~e@@3@@B@xI@3@@p@.@@!@H@@W@@B@@@@W@@@@G@l@N@o@@@@@U@@q@@(@̎q@@Ϋ.@@@ @֠@O@.@@@@S@~@{:@m@!@voArA@ @A 9AA AAVA%A A-A-@AA7AYA;IAHAZ+ATmA;ABA\rAYGAs A/A~;AAAhA}A]A(AJfAoA#A1AAA+A/%A0B5ZBEOB6=B]B0Bl7CUm D'ILCCC>CsCDBِqCCc.CSBhBxBHB?BBBEA>AA:aAoA~ArA[Ah|AAtAZA`ARMAY+ArArAnzA?iAfA}'AR eA^AGb=AEAL`9A@:@s@8@@{@@@d@3*@(@ @@@r@@m@@zM@j@W@e@@@1@@:@@!@jO@@MX@>@q@@[|@f@@@ń@@@k^@>@@Q@=;@@D@@ʊ@@+@{j@5#@~@ @Si@$@@@@|@&@@@@@Ր@g@@&l@8@ @r@.@ @'@K@@e@@ԥ@Ǥ@@m@@!@߳@@S@ @Д@@@ز@@@֜@؄;@@@!_@}@9$@y@@%@@#@6A@2@PA -UA8AAA A 'ASA HAiA HA A>QA0A4cA6>ALA";ACARAA'jAMYAGAGhJA@AV :AaBAmAj(pAfAkASPAKA7AboA'sAFAA\A yA+NA-AAs AwAXA8AaB0XhBKBTkNB1BB3BZB-C@@@z@@u@@?@S@@5@ż@-@x@`@@@@@j@q@@p@5@,@B@@^@5u@'p@(@@tX@1@ZR@@j@>{@$L@D@+@K@@$@l@S@@C@A@E@.@@@@B@Ž@J@<@Q @?@f@ @Ù@Ɛ@E2@A@@G@@g@N@@@6@Y4@@@ɃU@`Y@@'@.@B@)@ݺ@!/@@@8@A{A%A cAЂA AAAA&A}ADACABNA&AIvlA>ߤAS{mA`An)A]AAi Ak@1@X@f@A@ @@O@@S@@@c%@@,@@G@2@@@¼@ɪ@O@@Z@O@@@k@m@k@@@`@@ @ŵ@H@@5@ƴ @5@@c@&N@@@:a@䖥@P@=@A@a@4@@@A|@<@N^@׬R@(5A AUAxAgAXAeA A 8AA(AA@AKK;A1 A<۝A2iaAMj`Aw A\A]lAUADӛAxϐAcARTAg&AyLAAA`AMAAAA#B AmAYBB>BʥBiB)WB=B%CǽCCgCC &CCPZBśC!CC(GBBY`BA0B9AA]iA|AA.AAA_A~oA|Aw-A^WAOA=5MA' ATA8A= A&;PA%A,AI AlA &5AxA oHA*A_A AAĐA Aje@!@@!~@˜@@/6@шt@_@%@*J@٣@Fj@ȏF@ C@n@%@e@]r@6@Ǩ@R@&@5@ģ@@/@ @D.@?@*@@@3@@`@d@t@ٲ@@@I@@M@=@ 6@9V@l)@?@@G@@i@?@@@@O@^@@c@J@@_@@@QC@?@A@2@@@"@"X@+@ҙ@{@<@W@@@@. @D@E@6:@@@@@6@@6'@i@zB@ @@@@e@Ĉ@@lf@kt@Cd@@@hp@h@@@@i@;@@#f@A @@0@@d@gb@w@M@@7@@@@y@ @@lX@@t@@@@@@@5V@@l@@@r@}@{ @t@@o@@@I@@V@zA@]A *@ΥAG@?AXAzAA AA3xA%NA7]ABA%zA'wA8A'A/'A>>>AHAH%A:iAFAS A\YA[ApHA^)A\AYAYA\@cAyPAj[*A/AvAAUAASBWB%MzBBoB*B Bx8B:C?C(CZ(BXKC=B|B~BEBAB BgBVBAAB"B B]B rBʒB)AKA^VAAAAmA&AwwAsAxdAqeAA6AEMQAAAZX}A)c"A8)A LAA--?A'JA+:AHAXA!4BA AtAcADA IpA JWA\@>@@7@@-L@Q@@'@z@x@w@@`@'@6@@@0t@@@@7;@D(@o@5@x@@@Q@@ @ @{@@@W@@@.T@-@@@H<@@G@Z@Ȼ@{_@m@{yA@W8@@@|@@@}@z@{@ @I@M@@#@s@`X@@Q@p@*@@tp@@@J@W@ @C @.@@hp@T_@E@@$@@@@+@@%@R@@Kj@@?S@ c@9@[Y@6R@=@/@b,@@%l@@@I@,)@T@X@m@@@@IJ@r@@l@z@s@o@@7@ȶ@P@K@W5@¥@ @@m@R{@@@瓈@Am@?A@b@塭@V@4A WAA AnzAAC@A {A "AAoq@A myAA A KAUAA!AA/A;;AAiA>-AE*(AC)Ag6AS;AMũAC\A^AfAvAvAbA AA ;AA5A̬AAҪA1AA/B7B8B!)_BiB,CBwBJBCF%C+NCxCBB=BX,Bhh8BS B-\B=B}B 'AAA7AmAVA}AAAA AAAgwA UAаAx%AfAc&APHACAQN8A'A6jA?@k@Y@K@š@Ұ@@k@~@@jE@@@A@@F2@o?@@h @f@@[@,'@9@EJ@`@@j@`@@@F@`@@@@@@9@@@@@bt@Q@@Y@@T@@x@=@@@O@u @E@@a @H@@?@@@@}@"@@'8@]@@@@@R@@:b@@@V@\@@d@H@G)@ޜ@m@@j@y@}8@z@΄@p@@9@IA@@W@@,m@@@@C@@]S@ƀ@Y@5@+@@y@})@ @F@@D#@@@(@@Qp@@@@q@˘n@]@z@p@@V@y@Rc@@@؅,@a@A@ @X@G@+UA:uAAeAAHA A AA)6\A<A1eA=A?mA36AI/A7oWA2AEAMcA}rA_;A`AuwTAp"At|A~PHAAAŪlA;AIJFA9AMBoYAyA:AA{ BB/B^B)BXB-yBA#BȣC/_B+8BrBďCCxCC˚CAAAAfcAMAAAAT-AC#A}eAvAIAJFANNACHA>AA AuA7 A.@AϒA0A&@}AZA@A|A @S}@@AA<%@G@@g@ϡ\@ @OY@>3@?@o@$@}a@" @@}@-T@@Ǎ@@m@N@W@`e@4@Y@v@s@n|@B@@s@@.]@@@@@Ք@@m4@@@8@B@@R@9@@`<@@v@ @v+@ &@]@Z@RZ@%@|@@f@UI@v@I@x{@@u#@;@Y@@:@_@%@@@@!}@=@=L@@{@@S@"@@2@@6@ @@@q@@@M@T/@ @@C@>d@@@@M@@@Z:@@3@u@(@@"I@@"@u@@@@8@@*@@Y*@\i@̯@@g@D@ǯ@E@І@@ˋh@Գ3@]>@͠@@g@L@A@*@Ap@A"AT@ tAA![A HBA+CA=NADVA6A4UA17pADSA=6AEOAP=AyAA|@8AAn7AiAnAoA2AUA+;AAAALAAAyA6AA"ABBKÍBkB,[BB$|BLZBYiBB8JBBTCBBt8BYOB=BZB?2A?B0[AZAvA:AԏAÈAɀcEAY_AVqAD+7AVAEA;]A9A)sA8AA#A9A AA /A@@N@@@ AZAAK@@L@A "AA@A;@# @{@Ռ@ш@W@Ƀ@ @@d@@A@®'@z@_@@\@~@o@ww@6@ZN@_@xS@w@@ȡ@Q@@@8@)@/@ @@@@-@e@@tJ@=+@@ @M@j@@@@i@@@@!@;@@@@@+/@@n@L@N"@@D@uk@o@@@\@©@@Y@@k@ @A@y2@`/@$<@U@6@M@m@lw@@@=S@@@HC@@ @Ǘ@-@ @4P@~@@}6@z@j34@l^@qM*@$@z@|,@B5@I@q@@m@_@@@+@*@=@JS@Z=@@o@@ @I@@n@k@u@X@O@P@O@y|@ @6@Ƥ@{@ܧz@kA@c@xAAFAqAe@A 0A%RA,J,A)AʙA O3A{*AAA8[ A,@A.#ACaAA\A\1AF AQA{NoA%A )AAe%#ArA>A(AcAo&AAKB0@c@SO@,@@>@U@a@ߨB@@@@\@k1@p@7@Ϧ1@uy@@k@k@@6@X@@8t@ t@t@,@@@>@M@r@*@]@1x@{T@@@@&@@]@@lV@Ra@G@z|@%@_@`@@@$@R-@@)@T@G@@d@@@3@s_@@T@@3@o@@%(@LP@@ȁ@@ @@C@@L@d@@}@u@@n@\@\[@C-@rB@@@E@@ @b@@@@eJ@bF@1@@@@@Z@@69@@wb@w,q@!@@}:@ @{@;@@Iz@x>@*@@H@F@@@@ˆ@DZ@@Zw@5j@p@6@@3@Ƥ@@ԩ@@@v@ζ_@"@/@fA@@@@5@Q@&@WZAA0A\A*CAoA&gAA&fA+EA>"A!\A0J1A!kA4@vA5mASQ-Ad@@$@@ϯ@E@xc`@M@@@N@@@@"@P@A@M@@ @@@@J@@@F4@@N@s@N@1@@@ @5@@@)@i@w @g@@@@vW@G@U@@@T@Π@A@@ 1@@9@W@@@@Z@@xN@@UN@э@/@qS@M@j@ȯ@@ʚ@@}@@>@-@ @@UO@@*@$iAQA.A A5\A.A wA A AܝAg A0A~A&(A -A 'A(A+HdA9XA-kANXA,/AUEA]AS?AXO8AJ'Az AAXA_NA߻A]QlAAeA[A.AʀAUAB vB#B%BhB^.CBĭC1EC*`C5CvCCBB^BfFBGBBB&3NB. !BoAbB A‚^AݛAfAAAkAfAPAVzAAslAFAZArYCA|AMeAd |AIAXAXAW2Am0ASAGAFGA9 A5_A;,AEuA.A-NA$AA.`AAA @!@)@"t@@`@+@~)@խ@HL@:@[@י@ȇ@@@e@@)@Ʊ`@mx@@@ѿ@@@@@+q@(@ت@:;@@@`@U@n@2@`:@ka@/@A\@@3@@@5l@O@@ڨ@2@L@@z@-@@@:@ @Od@e6@P@@B@h}@:@@"@ԭ@@ @[@5@@@~"@k@@@ @(@p@C)@@@@z@@{=@6@hO@j@@@,@8@'@S@T@^@ڽ@L@Y@Β@@@8@-@|1 @@@Q@~=@(f@.@@3@*@4@@Ȼ@J@X@'2@az@zC@@@s@լ@ @ډ@@ݸ@@&@ʀ]@2@yy@h@(@@K`@~s@@r@o@@?@AWAfMAA @GAeA0%AA5tA"r=AA4A/~A1CmAD A=AKA\bAvAkrAXrAp.AA*A48AGA2AvAԞBJBBdB_IBzQB:yB~AoBoA\BA?A͞AIAFAjAA^A#AFAw{AxA|A|GAT-A hAxA]@A(uAHA)A#=XA7QA'GBAAA0A AAYdAAGAArA+@!AVA(AA @@@@K@@i@"@}@H{@+@@'r@@@q@#@@@@@%@W@\@=@|@)@@@@X@@fM@@@{@A@5@@D@ @|!@S@5@s@^@@@M@@@z@Y@@(@@@@E@@@@E@@@"@ @Ze@}@@@@@@B*@@i}@@@4@k@~@@@@@@U@a@@I@n&@56@܊@-@]@Z@@@ڛ@i@Y@@@@j@R@@խ@9<@Ӂ@h@U@E@@@D@P&@]@$@,@@@ }@ @@f@U@-@u@@V4@ @J @uE@F@k@Ra@7@te@Lq@ؚ@@P:@ߩA+@@,I@@@@KA\ByB'B-C7C1fB_C_CCC{dC|D:C"C[CܦC+BoB4B~'B`9PBAkAAA w[A@!@@@l&@@@MR@y@n@@m@@S@j@7f@@@O@n@@է@n@ j@@@ @*@X@@@@@@}@9@y@4@A@!@,@`@ e@@ǪC@]t@ǚV@@ŗK@ɣ@ֿ*@n@|@ @;@@G@h@AA A15A I_A@A @FMAnA fA AA#ǶADA7?.A?AAMĊA;AMApAZPAƯA|AVA,A\}AAAAHA/cA%KAA"A)A6"B 9|A.B)dB#ýB3UBuiB-[JB@ OBI BP.BۉCPBpCBXDCѓC'BBʦBZ&B"5AᱭA2Av'AnA<A~AA~AApAAl$AAxAVxA{2AA^zAjA6NApUAe,A:AWXA\ `AKAOA5AnA5 A4\A:JA#AѣAAA @A@rAz9A@A@W@Z@L;A0@5@@.@@n@`@ں@@Zc@ǁ'@T@U@i@@hQ@@@cH@F@ @=@e@Z@%@A@H@:@g@d@@R"@R@@ @L@N@@@@~c@Y@ϡ@@%@$5@A@4@/@|@qW@Mi@@@$$@.@@@{@@f@#=@@ @@@@@'@@mB@5@@u@&o@@`@S=@f@5@R@|r@F@H@@-@A@;@c@@@ M@[@@@sG@U@-]@q@5f@{@3@|@R*@@BM@*R@X@,@i[@=@n$@f@ .@e@@@@Q@H@@e@U@@_@@I@@@@@@9}@ʂ@@@!@w@b@3@@m@ͺ@ʨ@A @oAALCAAAPA l@vA AA,A A 7A&A AۯA.A!aA#t=A6XA1$AIA>AH$AKVA@JA"A"V%A* QA/FA)[A0AA A VyA1A,Ae@@f@F`@@P@ㅼ@gI@Gy@ޕ@֎@)@-@ä~@Da@@G@r@@:@1b@g@M@M(@"@@a@@r@@/@M @@D@^@e@/@@=@3;@@%@N@~$@S@ @j-@ @r@99@ң@A@I@@d@@ e@@J@f<@o@@-@e@@,@@@07@\@1@@@q@@$@@@@3@Up@C@3@@@7@@ź@r@@C]@@6@X@_@v@@@@.@}@6@@@@u@xc@E@ @ 8@;@@@-@ʎ@Q@*@h@@H@@@l@w@@/D@b@c @@D@*o@΁@ @K@*@õ@;@/@H@6@@E@Ur@?@l@y@ɱ@@z@E@@X@@[@z@@9y@y@A,A AlAlAAAUA3A#8tAGgA%BA.UA-zA5:A&A>:)AYJAh[AbqAn6xAf^A`4AAAA>AAAA2A\CAAKwALBAAAB BBBVB$BoCBB_C_C(?JCXFCB{B:B;0BdBMA@;@n@L@Q@@:5@@@ϑ@ @h@.@[@@)@V@F@@@{a@جY@Ӓ@<1@x@Ks@@^H@@N@Va@x@@@Z`@JA:A(AA @?AAANdA^AA2A6ܧA(A9gALA6ΘA|AzQAܑ\Aj=BAcBOB3ȫB#x"BB[kCBVoB&C BqCDC嵾CACU1BBJ^B)B FBB QAB\A!?A{A"AAAA'AoAGAWAsAyMAKUAIdAC#A;AdALA:A.A8_6A!CAyA2A~AkAIAlA,AoNA A Ak@GAoAAMA iA`@Ӻ@@$@J@@Gt@՛@2@Z3@@A'@5l@ӹ?@ҧ@=b@K@&@@!@@ƒ@}@w@@! @wi@\@@R$@@ @|@@p@@-Y@ @G@@V@+}@@@9@B@8@@@@@@@/@V@@)@r@0@@C@@}[@@K@CZ@0@@H@6@z@h@J@@:t@+@U@@@@@^@q@S@@v@m@@ @ @@@@G@`_@Y@G@V=@@h9@ѯ@u@@7@@@B B8 B:cB;BB|C.C[pD~DwCW*C+BT ApB;BIAA`qBAPAnAAr-AAkAA6A#AFxAAeFAjRcAYmAOAYAAM ANA9ASvAAAA,A ArA NABA ΦA >A=AA xA`AA 8@@@+@HT@)V@@P@@U@ލ@w@K@@@@@B@E@#2@@2@u@@_@l4@h@)@U@@L@6N@{@@D@u@w@@@Dy@@W@w@@y@k@a@T@v;@Q@8@%@@@߱@@'@@@f@V@$&@@|L@Z@8@@6@z@n @@2@z@5@J@4@@!@@@@-N@1@/@O@C@"@@0@1\@JO@գ@/f@@@n@Fc@Ю@ =@6Z@1@@v@A@T@ @@@@} @0k@H@]@@ux@@dZ@X@/@B@<@}4@B@B@@8@@@?@ɼ@u@@@rV@5@@S@@CR@2h@.@@P@f@@@㸤@ɫ@@@}@Y-@! A =A־A.oA A AˍAAsAyA.A A$)A.AK(A9})A7A5FAA@AeA]AQ:\AXvA\GAHAvgA22AyA|eASAQA2A[A_AA3AB&B5B>XBDMBy+B=Bq:BB<>B]BzѧCFBғC CuC7DRBųBhBBn4rB6DKBBjQBACA}AB/B4B>PB B BBAB3vAAAIAAAAAwA ApA\AX"A8 AXA7AGA.dA2A>aA)FvAy$AA,A(@@Y @@s@X@p]@j@^@%@+@><@.@@@8@@ׂ@0@a@@6@,@@z@@h@@a@a@p@s@@)@@1A@Jl@_@z%@@x!@@@@@5L@+@2@ps@\@I@@@;@ԟ@@@@7@4@v @@N@@@?@2@@@t@}+@@+@u@@@@0@@J@w@%@0@E@ D@@@ry@_@ @ȹ@I@ @I@+@KB@ @׸m@љC@HA@O@ф@v @@Sb@@+@B@ٽAAq@U@@t@̚A DAyACjA\tA7MAJXA$xAAAtA#eA1tA1@*A:eA7LA<4AFA]oAY8A\IAx,AAHAWAA&A-AAA"AA AA<BDB(BB?BFBC C$C C?D DLB9BB7vBXryBPB@7@ @c@@x@@@c@=@@j@$@#@<@*&@U@@}@:@s@A@P@4@@fn@5@@6.@@K@+@@@6c@@*@@ϩ6@{@@@t@@F@ږ/@߳@5@N@/6@lA<AA8A1AAA6AZA :AvA!A3A#A(\AA\kA/97A4k.AFbA8SA6A6ZuAB#NBFBA֢AAӢTAAt@AA:A/AAJAqAz_Ao9A AdAAsAvҷAVzAG}A%A+SA&8`A A:AA4>A +A A >A|AwA6@XA AAIL@@u@@U@u@@O@&@O@ܢ@@@Z4@J@F@@r@佶@":@ޞ@u@y@C@ֲW@a@$@:@;@@ǘ@ @ @@͎@r@2v@ @v@v@@x@~@@x@7@@@A@@6M@>@@W@h@Ѣ@@}O@@ew@O@a@P@@sn@pz@t@O@G@#@ @\@\@@:@@@ƭ@2@@@xt@@V@_@@G@@u@a@3f@K@D@=@@@-+@@u@&@@t@@`@M@;d@[@ȥ@\g@}@ @@3@@@@5 @Q@@ [@@@,f@oi@@@@P@&9@-@1@@g~@;@@:@%@_@\@@ѶF@ҍ@@@JA @q@)@9Z@@a4@fWAA$AKA"_$AbA"AI"A9ZA6^A&#VA4RALYAB{AQA*AI2AHAYAxAyfAAdAA$wA.AAAwA߅A˲A{AAA̭9AB=BA~ARABQBLτBiB]6cC_CCo?CpCx$BC+CvbC'2CCB,{BB1BoABsBImAgA**A ADA_lAeA+A`{Ab }A_AOGA.9NA9AJCAcTAQ ADōAbAEnAYA4A'A A@AA AA XA cAARA A AwAV @@O@P@拦@'@Ĉ@ph@D@-@4@z@@T8@v@ @=@@;@|@d@C@ȟ@@RP@@/@Ŕ@9@@+@ߒ@z@I@3@l@@:@5@e@@@d@Po@@@]@q@@@p@_@@@K@Oc@@T@S@@@@ @Y@@@%@R@@@Nk@[@e@k @k+@u@l@T@I@@@o @N@@@@@d@@@?@@@M@@ @# @ @Z@@qK@n@!@݀@@@@@z@@;@=@@zZZ@@~@9Z@@A@v@m<@@t@@@ @[@@@r*@@@@@0g@@N@՘@ء@ӖZ@L@d@eH@#@:y@?@l/@A{@/AVHAiC@#AiAAA fAA+,fA4A.3AKAJΈA>AZTNA>AmALA,A\|AxAuA~AJAA A)AcAAACAlA1AǕALBC}B_B(qBeB@B, BA#Be5}B]qnBB0BChfBBtBsB*BoB1A_BtB>BA!!AAA2AɟAAoAbA3OA_AArA&jA`A[ANA=zAV\AMMAFOAXhAKA-YAbB,eAQA,AvDA0ANArQA1#A2A5AA3AAeAA-A A7A)AzAlAu-vAY!AR,A9[ARaA +EAB}ZA@R!A3,AAK)mA+CA!iADdA ?3@"@f@-@@\@U@.@.@@/@$@*$@͑R@@΃@=@Wm@t@J @Pl@@;@@@g@@%@7@ZC@=v@@@@@@@@@a@^@M:@n @@)@j@@p@K@@@[@)@&@c@p@I@m@Ԁ@n@@@l@~@a@\@y@Al@ L@+@8@@`@@@@R@2@@U[@Ȩ@EY@_@u@ε@@W'@@@@T)@Y@@2@b@@}@@@6@"@T@@ @@q@4w@B@"@`@M@@@8"@o@@@w@@@@E@@v@ @@H@ @Z_@@y@Ű @@ @@@@X@x@ήj@{@a@\@[@<+@M@p@Ц@݁@j @F@@V@}A @@A.AVAAAAAAA+bA-A"A=A#)A32A+FhA:]A8AYlAT/AalAnAxcAlAfRAkA>AAtAQLA$A-A`A<:A#oA5}AHBWB yA搴A-A76BB>mB̸BOP8C9.@@W@-@&a@1@;@@ש@@@&i@C@|@ @@}@@s@q@u@{*@z@"@@o@ @ G@8@[g@@E@R@'y@@f@FB@T@@@@a@s@I@\@r@;@ @&@*H@8@@@@b@r'@@ @/@Q@3@0@/%@@M@Y@@D@d@@fq@dž@@EE@Q@?@^@@喧@@@d@@@ʴg@Ϳ@ |@@@@vACA@x@+AtA tT@mAaA%A"BA&A]\A@A1djA-YA9AHAGAOAZAR3KAI"A5^AZAcPAl]A~fAxJAdA=mA@A.A"AYAuAޤAjAABB5BB`BBd6PC 2BeC%pjC!B& COKDCEf$CqYBBeBBpAtB}BytAJfA$BAȩAоAA&iAAo~AyA6"AykA"=A>(AY=pAioAc7AIAS]ARƍAF A=A"A3A%4A }AA &@sA8AAA@uA%@,PAmA @Ҫ@ZWA4OA3*A AG@E@f @ԞD@Ǩ@&@y@v@ƀ@@{@ˎw@@!@Ȅ@}@@;@4@@@n@<@ @3@@'@T(@dR@@[@k@@@@a=@%@U@@x&@h@=@z@@@`@݄@@9@r@cG@@.@\@U@@d@@@a@ @0@ H@@k@Un@@@Y&@&@@f@@u@@@q@'@@y@P@@G@@@o@@@4@@m@b@8@A_@8@@@@7@@[@@|@@@@@Ű@߯@@g@@)L@ @ݝ@e*@M@ý@_/@Ë@]@@,@@#@&)@3a@W@+b@@GB@Đ@@@'@ @_@Gi@@!M@|&@~@A9>@"A%wA uATÁA7AqAnĂA cAUA}A2GA(/OA0A+AFǡA_f$AcAWAUA[AqޖA͟AyA-A XAFAA[-A:AַAAΦA5AsABaB"A|B!NLBCAh)AF-AqATAAOqAAA6A bAAVwATZ:Aev1A5پA2MA7]A9`A gAQFA A/%AWAAԆA%!AEAWA 'AAA FC@\@@SA@A=A@@%P@KG@®@ܰAR@?+@@ =A@ @狦@P@|@1@v@A@C/@e@ @@@E@{@I@v@@3 @@b@@Eu@@@@'@ @I@@@{@ @F@@@Ԓ@@@@@ȼ@<'@_6@}@@k@@"@3@N@@Q@@Y@i@)I@@Zu@Q@h@@ @*@Sy@@( @d@a@@?@i@@@)@@ E@@ڈ@P@-@@?@@g]@_@[p@@f@`@l@,@_@@9@>@@e@@@ҡ@O@y@ѻ@@ȁ@2 @@g@l@`r@[@@ݥ@@@"@{@+@u@|w@.@ћ@@@@@@g`@@G@R@eAW@@" @{'@}AOAuoA&!@@=@A0A5iAA @!A A AA#KA$A$A>CA;H9Ao `AKAC"AdAL)AAoqArAt~AyrA4AAA@AMPAsA6AߓAdA=Ah`AwB;MB!uzB> BABEBqBWBŵBBnB,B-BC< CD0C9CCu<CA,C(CBqB"B  BDB9gAŒAtAABA6UB@ADAAjAAPA AV{sAU/Ak%A\-AIfA`9A0*A1@A*AA)A @AtAEOAU@AA?AA@T@@'@@,@j@Vm@,@$D@!@쫻@1@4@^@<{@̞@!\@d@ʽ@O@@@@Ɓ@@@@@@I@z@@@4W@Oy@@ž@|@@,@@#@o@`@w@@r@@@@6*@@@VR@A@@xK@@Q@.@RU@@K@c@qG@@9@(@-@@į@w@@@D@e@‹@@*@lq@! @@@&@W@Q@@:r@ǥJ@c@3@s@7-@1@k@ĺAHAP9A\*A@@@AK@@l1@M@ϟ@@h@3@'@P@@/@D@@z@@A[AA~AAnA^AdRwAqMA>MAXcA1AG A3A}A3NA,AvA0eAZAALA7A@0=@v@@7@{@f@2V@@k@@5,@?@l@@@ @`@@߽@@r@8 @u @"@v@w@~@J@@(9@@a@@d|@@VT@#!@c@@p@x@@@s@!@@%@z@<@@@@@i@(@"@*@@@@@b@@@l@A@K@@x2@Ш@{@9@:@҃@@@r@~u@r@@@?e@@P@D@"@L@a4@@&@H@p@?@5A:İA )A_AAxճ@s&@v@@&|@R9@K@ϴ@U@;@L@@@@ç@&@@ʾB@3@H@[@@I?@B @4@ӟ@S@b@Q7@V@@R@RJ@L[@@P@.@&n@@u@Q@@۰@SR@g@h@eL@\@b@ݦ@[@]@'@aAA[AA@sdA%(AMA[ APAp(AHAAA'6GA1vA,RA(C@A& 1A-gA7OAXA*WABmA3A@A]7AVQSAdA^XAn?AzA+AAAZAHAAAA箤AjBEB2BBBAB`BXB?B#BX C UBVSC4CMDBHBVBB;BfBRtBG3+B*>B6B0nB۹BDkARAAAD@AATAyZA^AAsArAZA_xAl=A^AHsA@MVAb6ARV5ANA;>A&VIAA2WA4A=uAAA9hAAvYAu AA8A M@"@y @Y@ɨ6@m@g@@܇@@Ж*@ו@&W@A@-@@нx@Y6@@@@!@@T@΅@@U@@ɂ@|@L@K@]@@U@@b@ @@°@l@j@+o@?@=@g@$@@`@:@@@:@@w@@q@z@z'@@~%@h@P@@I.@*@5@@@!@@R@yd@_@@f@@}k@{@y@u7@ @@@@@I@@̲\@8@呰A&cAAt.@]@@`@@U@l-@@@V7@Z@@f@~@Q@b@U@w@e@g@@p4@'@`@B@@@6@8W@@@m@@@{@A@(@F@;@s@~@8@C`@йQ@@ԁ@2j@@Axy@"@8@A@w@@#@ @@Ah5@$@A@:]A AAjA+A AA.}A-dA1XA)A&5vA.A*TA@GAGAOƵAIAiAGAEAboAX4AnZAAIAȖAkA=AcAВAfA{BSB*=B 47B1BRa7B1BA lBzDBpWBNBC K,CR$CcC Dvc{C]BjBxB{%B,`BTAAqB uA&NAL}AǔHARAB)A@#@@@>@@@[x@qu@@;@hX@@@Q@c)@u@@0@@e@5@c8@ @l@h:@p@@k@@@@%@@u@ R@’@ہ4@1/@}@t@Ȗ@@i@@@@@IAHAAMArA A AAiAGAOAfAyYAyA$?[A40A'ďA,|A4A.FAVwA;PAFJAZAh&AibApAoAFArAAtjAN mAR8AP#A(AOAAA_A;/AAA'A _ADAB BkA A$A|B0BhBh%BgmC*C >CMD#8B)ChlBHBSƱBt"|BAKB5bqB{Bz"AϸAݑA"AůdAAAAoA="A A$AzAgAmtA=A&A6A%A'0;AQGAXA6AD?A4%2A9TA4VA*bIA#AdA,2SAƤAAeA A y8A.*A #aA@92@έA@}@AjA Ai@A @[@@4[@V@ޣ@T@B@&@~@!\@ @͒@@@ @QI@@ @@@M@ņ@@@1@w^@Nc@@h@9@\@?@@rg@Ӓ@V@-@1@@o@wB@]@XC@W@j@!@@TT@/@ @m@<@L@݇@m@A@_r@r@@@*@)@ @@f@@%@@@@@@@@s@ @/@@@A>(-AW!Ag@=@f@>@@x@f@nq@@a@@@*@@K@-@H@@@'@@@@nκ@!B@@L@@@@U@A@@f@@@"@@.@9@c*@Ta@@6@M@T@@@`@@ @sr@BT@ڶ@迿A A #A^AAA A|A=AAAAs7A A%A9@FA9*A:fAGALAI MAiQEA[[AI!LASAc(dAA|VA3A3zkA A"A&׼A VA'A?@aAAa@?b@v@Ə@ZO@QA@z@_ @@@@Ș@/@B@@R@@ٸ@8@WZ@m@#[@C@"@@@@p@j@@@@op@Em@.@@@[@@*8@e@m@~R@`@pg@@:Q@@B&@i@@ v@@@@ж@i@Q@@M@R@@"@J@M@l@2@?@F@#@J;@&$@o@@!@@1@@5@ @K@x~@6@[@tW@@@@cO@s@K@S_A2AcA9U@@@f@@@"@O@v@5O@-@0@;@T@@[U@Q@@LS@s@yw@@zD@(@7@sƤ@{@y @m@nE@@@@b@@@<@F@K @+@h@@ @6@f@Q@B@@Ȉ@צ9@c@̔@E@'@5B@]@e@"@O@A QA gGAA[A @A P@@ۏA @ʹAdAAA8A nA AA/A(vACAOrAKAEG"AUAK' Ai'AYA{YA:AAARA A AA`AABB3BBDBDB^B8!GB oB|BCDC" B#B%BPBqwWB{Bg iBJA"`Aъ(AaaAA AAKBA~AA3A?4A#AAEAAhiAAA[AdAqctAbAo9A[IAArA{A-A4NA4A'sAcAA:AaoA A@FA=@A@e@Ac@@@@3@æ6@~L@ @sj@?@l@@s@@@@U@@@@@@s@s@@G@@@@@@gf@W@@@I@I@@@@9@@@@v@%a@@"@MT@@r@F@Z@`@,@@$@i@U@5T@@'@xG@ 5@~~@"@@p{@Vy@> @Q@ A@A@P@@GL@<@x@[@@@R@@@@3@rA ˴A-@V@S@T0@O@a@%@@Nr@@$@'>@@@@A@5@_@@i@!@!@2@Y@@@@@@@1@ڱ@@`@}@!@@ə@W@"@@e|@@@@@@n@@@S@^@D@̣@v@׻}@Y@m@)@:@=@)l@KA7A4"A2A+UGAsAtAlAH.AsAo=CAyqAwYAAA"AAAnAcAA"AMA8A{AA B(oBkBCh&CnCTPB0X4BOV~BzB]B>PB7B/ BAB)BAAAɀATApA7ALA`}AA!AdAr~AA`A 7AAApA'AlA]AO۪A9^AJA5>A=$A; {A#8}AnAAA+AA,Aէ@xy@o$@ @Ӥ@@ԓ@W@ԇ@ݝZ@^R@@޺e@J@>w@`@ǁ@@@l@!@@Յ@݆@™!@ȿ@@9@a@g@X@M@D@h@\@9@ @z@tD@@@@\@5@@@B@d@@@I@:l@@p@)@U_@e@@_F@@k\@b@@^@ @C@f@o@@Iu@W@@K@~@Mn@dI@^@O0@ĝ@Ó@}[`@|@@@@pB@@ @ @@m@ @x@j@w>@@@@a @m@@ @x~@Vy@{@@@m@u@@@4@@Ģ@7%@G8@R@@@A@}@$@/@@?I@f@F@@>@fw@@@@@@s@@@ob@J@5a@W@Уh@$@П@ٚ@J@P:@ўb@ͪA@@ڰQA@=AӚA O+A AHA#?^A ܋A,A5mA3@uA>A"/A+ACA!XA&8A6RA)^sA> A;AIAL$AJ8A$AGAA-CAAeAjeAAA~ABBQB<= AӎB IBgC"@uBCaCD CC4BBBKABBB3BBAB]B!ZBBAدJAAA͕eAAXgA .AAAAYAtApAءAaAk-A]/ATAsYAK A1.AI/A)]ABA@_A;tA2LA3A!HA>.AwA NAA@AWPAAQAȅA ~A7 A8@V/@-@9@@F@A@I@<@׻@ݦ@ՓV@*@@@ƶ@j@@@@@d@XX@p@@@Q@(@@)@@@Z@[@@@@@u@6@@)&@9@h@_+@#Y@@ @Sd@@@@@@0@@x@@/V@ڀ@@U@+@@@ɉ@@(@]@@@@@@Ј@ @n;@`@u&@@,a@@@ޘ@@K@2@@V@Z@!@o@ա@@2$@]@a@ @g@@@Ks@D@@@6T@~1@@k@l@m@LP@7@J@!Y@@@@n@w@9k@@@@g@ @iH@@Y_@t@(@ƻ@I%@s@I@@[x@@jo@ @̐@>@4 AO@@@&UAA A$JAPA+AA#A$DA$A+EADA=YA[AxANiADA~AlmAy]A;AiA}CEAzQ)A$AU\eA_FAArA5A]A20Ai8AAAArAA?A_lB`B B\_AwBBLBȵC_8DbjC:CBuB?AOB^BwB0AA AZZALyA6A AAɪAA$AMiAϤA~psAXZA]AK$ADnACA( A2DA%tA7A=x/A>A3UAA,GA"AAAxAt1A6BAAAmAA2@g9@ @!@@K@_@՜<@ړt@؀m@Ƌ@ي@ @@ρ@~@I@ۗ@@@@6@G@S@@@S?@@@Sk@ @@Q@Ɏ@R@p@@VX@@@z@@@R@ca@;@@e@T@}@@8@@@,@@@`@G@@)@[@T@@6@;@D@Y@`@O@I2@@e@@@˻@@k@@@\@v@@@d@ @H@Cc@$@)@@j@~@@BL@݄@@@Q@9@@,@@@~ @@i@U}@@%@C@, @t@Dd@f@Ͳ@@xB@y@L@@@@@q;@@@@@.@+@ @@P@.@MS@S@Fj@@ԑ@/@a6@̗@@5@S@@N=@C@A=A7UA qABAyeAA6A˰AQsA AA$A,AaEA?A4۝AzAe7A[AMW8AgAa]AA}cAjpAnASbA,AA@AAAABAA~AAA\'B$BFB6[ZB:xAhSB%B0FB}BrBMoB]CB۝KCpzD DeDBBo|C BbJBC]BNB&%A@AmAA3PAFAA bA_AA .A%A A/~AAAeAAϷApAJآATA2OAI]AJOA;jAAAA!NA,GA :A OA A~A։A_@@睑A:@+@@B}@ov@/@}@|@@#@$@Ņ*@ ;@@x@i@&@@@Q@W@;@:/@p@ډ@A@Y@@@ /@>2@@xK@@{@8@@~@@ @f@"T@^@ j@=@s@G@aD@@ @@@f@~@S@4@8@c @X@5@G@@S@$@M@˽@@H@=@*@ @@>A@w@X@@@@PK@A@@@@@Z@б@d@@@ @7@m@1@h@?@ >@Q@@@4@o@@.@]@\@@@s@P@`@:@h@M@@6J@ @_@v@@@.@W@.@*@@X@s@r@K@%%@7@[@@\U@ԩ@@@@:@@݆@=@R@kF@Ӣ@@ݦ@ěe@@ƹ@pr@߮@%@@@@؉@%AA }A $LA@@jA-AAAŒAAA)KA,"AJLANA>A<*LAQhAccA[:A\XpArsA AAAA.\AVAAIASAAAAͤA|;BeBOB3$BMCBEBCbCDZCBBFB->BBCAB7yAVBB Bk@BUXAՎAC{AGANAXAAԉAF|AQA5AhhAxcAkgAA]AcAVceAQtAQAV(A;A"ARAeALAfAIA]$Ax/ArAA5=AA>`AAA sAȌAAUxAAP_A Bi A|ABsB*B BBCݝD CC8hBBދWBܷB$>BYA^BA/BGxAAIAL|AQAQAgc9APA"8A,c-A)LdA-M2A5A-/AhAp=@A l@HA"P@`@\@uf@<@̄Y@6v@W@τ@Q@߃@y@B@'@@e@h?@@I@A@G@)@u@>l@@z@&@@@Li@{@@@@}@`@t@}@Y@@l@@ &@r@>@@Ӌ@j@@@@P@7@@@@o@"@'@|o@G@LE@K@B@}@(@@@x_@4Q@@@@ʘ@@l@@@@a@u@"@@@{ @@@@U@0}@ @n@0@dy@@ͷ@@@=@҈@m@@O@ @@-@@ X@@}@.*@Vl@"@ @@@)@M@\@@U&@z6@1@\L@Օ@I@@]@U@@@@ @@V@Ї@װ@6@B@פ@i@@@r@s@j@y@]@T@ˣ@AA ^ A7|A aM@Q@@APA?zA.(A#A+HOA7jA4AlDAVAV,A>AFAcAP9A]ALAspA`AAAPAnAhAAAhAA[AAiB/, BAո;BMB?|B;GIBFcBBDBWB+#DBcCZ4@CC !BHHBBB/BPBkA#AmAAuAAcAGmAAxAm0AApAAAxnsA5SACA=AB%TA5A1QA?0A"WA%WA"lAAgAdA{AA AiA bAVFA@A AA@]@C@D@V@z@C@@p@@@~E@R@@{@@Η@3@}0@ʉ@q@ξ@o/@T@U@g@@@9@B@@@0@; @B@@)@S@7t@: @@@@+@o@6@$X@E@@}@@>@\@v@=@C@T%@@q@3@)@{@;@z@.@c@@й@Z@S@~O@b@q;@*@E@pl@U@M@P@>@c@@9@A@^~@@ @@}g@@9@I@0@(@@6@״@);@,@CO@|@j@7@Op@@v@*@_@Z@@!(@0@0<@0@z@>@ָ@@[@\@(U@@mG@[@*@@@X@@%@吾@9@Q@@„@ڭ@ a@P@AS@@8@ZAOA@AA NA@.#@s3@@uA |A׽AjA$A#iAsNAZA7A:AeyAlAEmA4^AG=PAA&3A1A1!A.>XA#vA"&AgAdA=A UA IA :$@A\ AauA ,@c@@@iAZ@4@;X@~@ʬ@Ծ @C@G@@1@s@p@ϗ@,I@˔@@o@k@ (@N@Y@@C@:@P@@@h@@o@9@O@@V@@@@@@k@@Y~@@Ѿ@}/ @M@0@v@@S"@A@"w@-@xo@_@/@N@@@@@`@@@>@p@@@@X@@@[@@3.@@E0@U@@@@@v@b@@ @`o@o@@Jv@9@'@@@g@*@݅@5@@@@x@3A@Vf@X@@@X@SL@z|@t1u@@e@{@@s@@|@(@C@q@>>@o @4@U@@@@ZV@!@Q@@Z@v@Zu@i@@S@<@@@L@@;@\@L$@@D@[@x@!@(@@N@@@n@F@@u@(@@g@>i@TC@@~@υ@@@w@\@!@d@(.@@@O;@ @φ@q@=@@@H@a@;3@?@@ƿ@@~J@K@>@E@^@{@m@<=@C@\@0 @Ə@̥q@@mJ@]@ʌ@ΤE@@0@AA{+@*@NAlrFAhACA$A Af6A.AAYAAz"AbAѳAA61BAiB`B`BFBy=Bz5BrBC:E)CecCX(BOCvTBn/BMfB;B=AB;B9B7BEB'AZ%AnB'KBB{AA AAWA_AArAoAA{A_XAd,A|s7Ag2VA^!AMhAV@e@Z @F1A'@۬@ਕ@܊&@ @@@@0@r@ @1@@`@i@½@@{S@r@@@@ L@*@:@@o8@#E@ʘ@d@r)@.@ O@U@8 @@G%@@;N@Vz@@z9@x@M@@}@R@@ @@@|C@]^@/@@>2@TQ@:@@@t@7@e @@@A@y@@~I@ @q@-@@@@m@0V@/ @@fG@@V@4@@ @F@%@b@ @@4x@1@U@ϓ@@5@kM@y*@@:@Ϗ@y@@=@@+@@@q@z9@H!@@ӏ@@c@@~@@@@@3@y@-@@.@@*h@I@_a@Ž@i@E@Ζk@t@@o@2@Z@ł@œ@ٛ@6@DA@K%@x@@`A@Rh@]AQ_A,AA"AFA#AAA[A)WAAA A. FA@$ATA\^~A_AOcAXAiAA}AqTA{A AnBMAǎsAMA8A'B4rB'CBW BgAMB(^B&eByB%5B%OB%_DcDJxDD}CNlC#BT BBg$BB!BMnKBJAkBmA1B B&B*AA%RAǼA(A6A#A1AAd%A.gAxzAAm>A`=Ak6AvA\AklApi=A7VAHSAIL/AHFA=C[A'fA)AArA)/A#\ A/A~ATAe>@>A@F@@a@]@~(@~@@u@nv@ݍ@ g@F@@uH@{C@@܋@ߥ@-A @8@7@۰@K@<@g@D@Rt@@@@ɱ@X@@.@@@@P}@c@SA@@ )@Z@N@c@1@@)@@@@=@$@+@;@dP@[@ %@OM@@{@]5@@E}@~@O@>x@ӊ@4@K@k@@6<@?@D@Q@@J@@x;@@!@~@ @Щ@3@%@>C@=@&@@zo@@B>@@@ @@@o~@w@}@Q@t@@@@_@i@[.@s@@u@@@g@~@>@E@z0@b@@@r{@9@L@E@=@@@a@s@1@yZ@M@ A@@w@@B@捭@㯹@@^@ AFAAA hA{o@@8AAALAA1qA5GAGANA?A)crA9;A53A6A*A&AGAT:sAHkAubA\AjoaA(A\aAAAuAALAnOAcAAABB<#)Bc(B0BB5[BcBB@BClCC%:C(CV0"BjBB]/B;BBBAB|B,AӎA AcAK?AƧhAcAAASAGAA}A'AIAbAlu/AXA3:A5gA78A9A]AQ6LA^%AhA$tAAA#˩A10AmHA AAAAAAQA@/V@G@W@D@ @O@p@@@ې@@^@@@@ȱ@@B@PK@@ @3@@D@t@l@ @S@@B@@@_@=@D@J@@@~=@.@@N@y@@@@@@]@9@kM@c@@@\@b@ʹ@d@@a@D@$@@/@ @@1@N@j@@S @@0@ @hF@a@C@ U@ӕ@r@p@@@(@@@{z@(@W@@r@E@B@i;@LF@@6@(@@r@M@A@w@}@@k@g@@ @}@@{@@@@u@~@@"@@D@((@9L@B=@7@@ @+@b@)#@@@>@\@N@@j@Ҍ;@@^@B@R@޶@A@@ma@@DA4dAFA<%A!@t@FAq}Aq7A ~A TsAA HIA2A-PAPAYAChABA'&A8tAazAcAGAyA|jA A@SApAAAs!AlAAAnA5AMcAՖZAܸBbA=AOB-AB'B5B2=BTh-BB-C1CߖD DCPSDU hCCCI2\C C#Cf'CeBOBnwBFTB[B> B>B>B~BJBZBiA ApQAAANAlAAyNAAAAfRRAsfmAdrAPG-AwA;AD`A0]A;mA3WA4A4iAA>A ACAtA @@@@@o@.@@ @@j@ᦁ@ܭ@@-@꠿@V@^@.'@]@zL@@@@ v@@;@Wp@:@՘@@@@R@a@Ч@(@@n@]@@@L @ x@@w@~@@@k@M@$@`@@@K@@g@@@\@X@@@r@u@@5"@'R@D[@@l@s@q/@ @Ug@:@@K@@#)@<)@\c@! @I@@%@7@v@8@2J@@Z@9@/@@@7@l@sL@'|@ @Q@8 @՞@/@m@K@^@@@V]@C3@S@@R@G@'@@@@ k@{=@@B@c@S@@m@t@l@5@k@=@&@S@3@/@ڱ@a@8@@ 2@@@$@0s@"@Q@æ@ @N@lz@AA!1AA vAE}AJA(n@AAA @AMJAhAKHA$CA)AFAMA=EA'AA(AAACgAPAr-AMdA]|AA1A~A`AoAvUA%AVA@AAA:WAB>B0oXB#[B,KB/BWC[DŘDSC2C.CBBlBVqBDB+BgMBTKBxBB)BA9AAA&AXAߴAڤA_AAzAFAtAAACAPEAAWAiIA1ApA`CA^c=AOAZ?AMrAFuA6zA& A-QGA"MVA&\IA S'A A@NAAP@xA@\'Ag@@N@y<@S@_&@E@{@ޔ@k@@k@Yt@J@@5@ef@k@Ӌ@S@j @] @Kc@U@u@@6@l2@c@܌@#|@@@@Zj@@@@@+@Y@{@f@@@Z@>@AA#A4׸A9A7U)A @h@@0@~q@@cX@~@Bq@]@X@*@$J@@|@@}@b@@|B@@B@^@*^@@+o@t:@o@@@8"@@M@Ŧ@@ @ۇ@#@@@! @~@@@~@T@ҍ@H@A@+@2@E@ @@@@+@%@p@)@@V@a@0@O@@@K@'@@@@@$@K@@@@6@@.@w@ .@Q@@f@K@@Z@Ʃ@a@*5@Y@@tm@C@-@h@4@@X6@@ f@K@go@71@@@ⷶ@ֈ@ASKAYA aA AA<'AA6A An@@MuAQA,AKAhCAoAk AgAi-uAlAOHADuAUCAd&AiAWЃA^EAjPAutAAeAEAAAfuAA9-A$AB -B#B%kBMB YB>h(B^BHBcCC/D:CCg"C8DbrC2 B6Bo#uAfB3B%@$@8@%@P @w@}@@@G@Z9@@@@4@*@@@u@@ @N@ S@K@F@Y@*@M@IJ@i@K@%@&@@@ @@@M@.@V@@-@Q@S@@@ @@Ka@K@-@@7@P@<@@2`@@Ǻ@@h@@b@@N@@@@@%@i@_@Ǻ@K@@ϯ@@"@ϓ@B@L@Ѓ=@9@!@A@AgAA<@ A4AALA 8A%A#ARLAgA]FARA+oAWRdANxA4>A]}At AX?ADA]AAtAAA՟AVAAXAtAAAAp@+-@z'@@-6@l@@@@#(@=@^@$@@&-@:@H @T@f@ @ӵ@j@=@ٷ@C@+@@@w@]@@|@Q@ϗ@q@-@,@j~AAiA&aAcAnAA LAvlA|A AA[AA/jA7=A2aACA4iA2{tA+?A8A7A$AKbAAB A_AAAAAvAMA]ANA|AA-=AAApABD .DqDpC'VC4IByBBB2hBLi6B&HBAB ABAY3AOA^6A\Ak(A2Ao AK,A AAAzAԈB ?B$,"B"B0L_ABuB{BHB}BmCC a]D¾DZC 6ChRC ;BB5B|CFB2BS"AgB B+hBLeAA AD}A1`A_AKAAAѦAAAaAAhAXbAg' AW AJASA7A&@A8A$-A4*A'A$AC!A!qAyAVAAA($AAAA As@0@@@*@L@.@$@'~@1@ϰ@W@vY@@Ƽ@@@Ƚ@@ C@@@V@]S@W@@@@t@?@/@ @Չ@] @[s@Q@@@@n@@k@@z@+@7@E@.@3@X@@(@?@O@D@*@r@JH@@+@@@R@j@{@Z_@@@W@W@@@h@@r|@@4g@P/@V@@p@~@`@OD@b@8@ -@\@@{@@@,@g@@@ȩ@G@d@x@/@@Ŷ@@D@e@(@@@d@n@O@g*@Y@RV@I@Y@@@)M@)@M@@@K@f_@ ,@ @W@n@G@J?@4@@6@E@@v@h@@C@@0O@)@1@E@ @@-A AuAAAA A!A7A'AJn@pU@AAATWAA+~A4oAMIAQ8AgRAJA[A7A,AAqHA|AŰB&B^B*zByBBxBBlhBB*CD]SC Ct|B[BSjBhBBBB'B0bBB,BAcjAA+AA`AEA eAQ AmA"A>RA_AN*tAjAW+AEAP_mA;AN A(AE$A4mA;rAA,9A,>AA viAAAAvAtAAhA AAAiA6@+@"A(@}A8@@Ǿ@@@ @"@W@b@m@r@N@1G@&@@@r@@T@@@@@l@l@@t@@@@'@W@}@a{@F @٠@Zx@@f@!@@4@ @"t@o@f@@@@+@r@b&@J,@( @@;@->@@Ou@@@)@@8@@Č@r@$d@@@sd@@C@? @@a@F@@m@o@v@]Z@1@'@_:@ @n@_@F@ni@@p?@(@ @Q@@X@@Yu@S@u@@3d@@=R@B@@W@8@@@2@@@@Zb@#@y@ź@U@`@*@G@b@ @!@R@@h8@@=r@̫@H@@9@20@<@AmDARA^ A 5]A ܟA M@@1AJAzA)_A7AA)^A1A;ZAIAWiALQMA*"AFdA8xA/k^ATAo AdsAqJAeAAz A*AA~A'rAAnApAANAˣBBy*BHBV4AAߙBIB%oBYB Bt-BkBqCˑCC5=D(-DCсD['CCcC$AC5jD$D$CBТBbBB>BN1B]B PBBحArBBAAA0AtA$AqAAAuAAkbArA\)&Aif$AzAbkAW1AA=M8A>A3A@A/ AAxAAACAh@AW@Ao@Z@ @Xh@߃-@+AE@煩@#@֥@E@@@P@ڸ5@;)@@'@.@i@r@@a@@S<@*@=@c@BG@@ag@[@@@J@,@[@O[@M@ _@@} @J@2>@_@@QJ@@Qh@@'@@f@ @Y@q@ @l@@ņ@łK@̠@Z@@ԓ@ڜ^AI@C@ܩ%@n_@@րr@@p@^@@R@1AL@'A{E@KW@&AY0ALAhA AA _A A* A0aA?A4wA9tAA$QA-xA@=AQ2rA`SAc-lAwA&A;AAsQAI.AqIA=AyAӽAAtAAB ֌B|BmB5B4B4BsC ,BD ?E[CDC7CCjC ;CK[BB)BBIBBSaB!yAA!B#3BzBAeAAďAdAlxAANAAAv_AA]AAHA,AxA^AeRAfAWAA[A^OA?FAEgA;AO+A@X@R@@@@@t@v@@@-@ȋ@l3@6@۠@p@@x@_@@ֈ@?@Ә(@@-@p^@C@QAЙAАAAUAbA%,AA%ҶAiA!A] AA9A1YA>A5PAI!AY1MA\bAtAPA)5A@IAeA8ArAAA AAAaAviAA9iA BiB-ABBNrBϸCBCk5Ce<C_DlD'E!C{?BkBCBnjBV Bb֒B=BXAt8B#B1o4B)0BPTB nB AȠA A-AAQLAAAA%ArAAz"AtA$AAzAd*A J@@`(@bAp@|@A@P@@ݶ@0v@A@"@۾@7G@Y@뷇@3C@j)@M@@@@@@l@X`@@>@v@@@ @|@@Td@,}@2@i@:@7@z@ֱ@@@-@@@/?@ @g@@@@+@@(@@~@do@@,@@@~@Y@P=@x@@@Q9@9@@@K@ 6@@IB@@F@3@@l@@9@@@@@d@t-@@K@7@@@@S4@@@@g@H@@̸@ @@q%@\;@K@b@{G@,@R@@$@@'@5@@@Ɔ@&@ͷ@Py@Z@Hb@@d@m@k@ @@A@@@D@Y@@ÌY@/@ʐ@Ĺ@"@쯡@;@o>@\K@@@@(@AX(@Dm@AVALA!A ~A*AA-VKA(kA2JA/mA*:AIA+aA?w4A5֞A\6A9.Al_AsFAxAA+AaAASAq&A*AZAuB VB47AmB$B*{B}eBBvB:PxB.C'CCCDtC4D<CACCmDfa9DEACBoFBA)QB:YBP:B3Bh BB?>B AAA[AAHA֒Af5AiAPxAA9`A&A4A32AjAN9ABAAAgAApAW:AAX$AUASTaA7A=i AEYAB"^AQ+A/xAFA=AH A%WAANAlA1A'A@@d@@-@„@R@X@@?@ղ@H@@Ӝ@v@@Y@G@@ B@/@9@ר@@@h@m>@.@@/@Q@%g@@@s@@UW@`m@F8@#@@W@@m@6@@f@s@;@.@>@d@,@@a@f?@i@@@x@;@@-N@D@@|j@@+@@@a@u@@F@@q@C @@Ta@@_@CD@z@_@g@s@t@@"@u@y@@@Ń@H@r@p@i[@@`@)@k@!V@@ @@@J@T=@)@W@+P@7@X @@\@>@@@ @@@@o-@T@3@@_@\;@@`@@ċ@&@ P@@F@f@f@.@A@m@@g@@mA AA :A A"AAmA#AA7A A(A$A&{A7rAWQTAH AN%AXdAUAtBAnANAL+fAoAzAAAnj AAAXAAA՜AZrA$A(AA"A.B|B8tB&qBG'BjBBC"JC{PCCz6CCmCnCģCCOvB$B1dBo5BRB-`BL AMKB'B\MB mB A6AA?hAMAcAAAq2A/A,AAKAoA,AH 'A^AAMdA0PQAW SA\aA$qA& A1aAAA'0A&A{AΤAI\AA AtAnAFAՋAwA,A vA49@~f@ @]@@Ѡ@ۤp@ƭy@?@K@@ƈ@ @4S@@a @O@ʠw@Ɣ#@@f@ڸ@@9@Q@?@@m@1y@@@jy@U@\@b@@;@@@ S@ @W@{@HE@k@Xg@@3@@2@h@S$@@3@=@7@}@p@T@@I@F@Ԙ@@*@5@7@ U@@@" @F@@C>@@s@+@-@@V@@iQ@_@@@@ @$@@@eD@59@|@y@e@:Q@L@Z@@(&@8@E@@/@@@@<@@9 @L@@p@@AA A A .A|AA7AA&|A4A AB B-+BDChxCp1CɚB_C$`yBBRBT#BvZB .B$B^&BeAAB RAtB fAAAqAAALAfAeA~HAp@\@@_ @k@(+@@Ň@@@O@b@E@i@t@@ r@(@Bs@v@Q@@Z@*@:+@@@mD@@ @FB@@XF@@H@@@@@X@T@=!@i@+*@@qN@4@@@D?@A@0@/@v@@@@ة@e@@;@@>a@@h@Z#@@@N@#@@;S@[@:@qD@@T@(@<@ G@@,@@B@~@X@}@b@@)@r@R@@X@@@G@G@@5@@]@2!@fP@7@+@@rP@D@&@@(,@m@@u@@@@@@@@@>9@@2&@q<@g@8@k@-@@Eh@ @\@i@M@@˗q@و@ʫq@ϴ@L@@@靅@Աq@@CA@B@X@F@8%AApA+yAABAWuAFqA9A[~ApAѿA~`Ah_As$AAΖA[fAAAJNA9IAAW9A4AeB BJB!A/B B BbOBj[BXXB"B8mB1B_C<46E˺CAdeC&CeUCaC7B6tBl %BDB B$B7TAB%KyB^B/jtA BMABʬAAՑA>AP A3AkAAgADACAAPAaAD$Ai6A`A?A<]ACA4?aAA A cAx4AlA>A< A :AA ABRAA(A+A?MAbA`-*A\AcKA^HAxAWJA_AejAZ+%AxAFAw,AAqAA|-AAջA+AԒAvAA"BBXn B41B&xHA۞B?BrBBBpB5yC1CuCkDE&C]CNBuFBBsBmB[mB4Bz[B AwA޽A LAAW:ACAzA|ApA9AAA-A+AG^ASAyFA%AAoj;A]>ASrAt:AA? ACA?CA@AVA7#0AAAFA:jAF,A<{A8A0IAaAA%AA@A@st@@'@hqA@@Ü@@ֻ@9A @%@@ @c@%@9?@@@g@@@@@@@`@@N@N@@ @%@+@ @-@@2@@0@O@V@@g@r@@0p@@Yz@h@-@f@h?@s@ƫ@8 @ @@@D@@w@,@U@ %@=@@@ @@$4@c@@@/@]L@@@g@@@,@%Y@.@ d@@W@@@ @Y@"@B@+@@e@k@B@6@"@)@@ g@@@@T@/@@@@O@@v@ff@M@K@@@@2@@@*@̂@Ǽ[@5@<@@N@e@@M@~@t(@@[@Ǖ@߼|@}@6c@a@+@@T@@qA AʧA-A AtA@ ASA A Ab5AnA-A@A7@AUrA[AANA{"A/AAA(DAAQA`AMAAl6AAA A,AAA=A@OB B>5vBmBo/B[BSBsBG\C*CCCr=D5 CD-C CeCc/B}BzCB5tBɖ'B=BB( AIBmAӼAɫAAݎCA{5A>;A\AAGAAYA~@AyAx0At+AgSAv[A^-A8Ak,EAhAYZAcD/A:A?A/A.UA7A)+A=˪A5'A!AvAAQA AhA \A* Ar[A AAulAA/AA@KA@냒@ya@Җc@^.@!@@ @È@@vk@3@h@̤@?@D@i@ @m@Ź|@֔3@@-@"@Ϭ@@@^@q@@I@r@@o@@)@3@@w@@9@k@@W@̮@@#@@BB@eB@f@٧@1@4@:d@T@@@M@@f@μ@E@@2B@ё@Ȥ}@l@@ @@>@'S@L@+@@p@@@@@H#@'i@@&@e]@@T@@'@@~@)@J@qk@AI@a@,@H@@|f@8@<@O@d@b@,@V@ŵ@ڨ@#^@Տ@@ۣ@@5@ͷA@@"_@M@@0@y@@LA]@2@0@@q@۳@bAA =@@AkA7A2AnA;dAuB@]BB6BHBpmBw9C-BιC|CCMDJDCWD5D'C;CWbCQ\Cq BaܠB1jJBm{BqBB0SB,|B"BBAKBTBADžA;AAAAӵ@AJAoAAԥAA^A AUBAhA?6AMUrANA@AB_CAJHAEAAUAӏA'Q)A:!ALAVAxnAbXAcڍAM^A=6AaAhA^AeAAA,A36AJA$ArA5CA|AǬ AڼAAB @BAbABoBBUBc)B)BkrC 5FC“DEGCCi4D2CxFiCNCoC -CBdB'8BBIsBBўB SAMiB0ҜB,SBPNB `B+CB$ A A-ArLAQA AʢkA 5AlAAA9AAAA]yAWtAsAe1AY!A|AnQAjKABANϧA=CA3A1A$A%A6Q{A"wA>HA2|AIAeAA6A|A IAA N@+?A5&@ AA<@"AK@Q@@϶%@ʥP@B@r@?q@$@NJ@'@@G@@@@ @ @@ @xw@a@b8@@@>@@b@#@@J!@#&@v@ @?@ @@ @@z@ @O9@:@]b@;@@@:@@@@g@@@@U@(i@&@@(~@@A@@@Q@ڊ@$@_@lM@^@@&@^@1@@o@C@@@Y@@<@UH@@@@c@@w@;@@@@@@@@@@O@@hf@@x@@-K@"@@@@}@w@Y*@C'@@=$@ˠ@pK@@OP@!@Ƀ@s@5Ak@`@(@@-EAȷ@LhA A ,@AI@A rA3A#(,A HAA*A<A@\A.cAAjA1:EA>%nA;qA2A.ȵA&bAF5AJATA\x|AaAZTAtJ A]*.AAЈAA@@ꢳ@@ז@:@@@p@Ϯ@W@@'2@7@P@@Ā@ Z@7@@n@h@@j@'@ơ@q_@@^@@CP@@@1@:@!@0@R@ck@@ź@&@@@@ @{@ @;@V@@@ƹ@@@y@v@@k@@:@tL@@E@@@1@]@G@Ǒ@U@ @@ H@͍@/@U@~@@-<@hb@u@@z@L/@_g@&@@%@SH@Y@@@@Ƥ@@`@b@@?g@o@5@~G@R@@@@@!@@Ҷ@M@Ր@ @݁@V@Y8@Ԟ\@a@/@AA@AHAUiA %AQABA#؍A+A()uA|/A [`AaAƼA5AEޖA;XzAEAQAMARAWYhAR` A}d+A}A'AVA_AYjAXAA -AAA@WA A=@ =@@E@@T?@x@@@V@j@2@L@J@D@v@@ܜ@`@@@"@@9@@D@Չ5@@@ý@jL@̀p@-@ |@rB@6@@O@Ǎ!@ @ҝ@܊@E7@A@9@@Ƥ@U@P@o@ĵ@Ǒ@@v@<5@@S @V @+@@P,@@0@{@D@5@:@@[@@՝@@9@@@@^@;@@.}@[@-@F[@n(@Q@@@3@\@@c@@@|@@Fb@Z<@*k@@=@2@@C@@W@k@E@@M@S5@I Awf@@@@@@R@@@@EA#|AJAIAA A ƁAAA:AG:rAJOA`UAOHAVAXAwA$A>A%AS\A4A[A.OA"CA-g8AIA~A ,aA@@z@[@A @n@2@[c@㧻@.AS:@#@ -@n@l_@鹞@@@N@@@&@w@ɪ#@Ϭ@҄6@/9@@y@˺@b@@ ,@@?&@мR@ܣA@@6@˃F@F@z@W@ӳ@ZV@oQ@d@c!@@L@@_@Ʊ@E@@ @ @@@6@.@A@֝G@͸@:@q@@D@ @@'@e1@м@4F@@2[@ś@Z@N@ʰ@z@@@@<@`@Ֆ@"@W@֟@ͨ0@˷@q@Ü@4$@@p@@{@@@M@B@ @r@;{@R@O@@@@9@ze@F@@@ᡌ@x@+t@ݟ@T@w @@(@@u@@@-QAOg@AAAA A5AANA BA ٦A7A5AAA1A%A#,A9jA4^sA!0ADaAEA7A%QA=6MAIFbAaWAx%Ak3AAA9AAAfzAYDAA_AbGAcA%AAA&tA BqB@XB47AFB/k8B0FB2CАBCDvABbBCk:C$[CY`CFCCvC_C϶CDCCbD/C7dD'C)6CFBBuBG5BBB%BBB)4BAi7A5AAA0AAڧcA@@v@N@U@F{@@@@@[@=@h@yI@1@O@@4;@#@R@@Z@7d@L@@6@A.@p@iAAA l&@cFAkHA}AA$‰A9^A#gA/A)A$ZA)A8uA31A*cA.A; AEAAA<~mApARAbyA\A~As AdAJAh#AAA#APAhAf$A|AAPA~*ANiAJBB."B0AÛBe GB ^B9rNB7BuB`GBYFAB7BeCA`AC0A8GARA2AF*>AKvA%}A'A'=A#3A-#A"DgA%AƗA--A wA8$A&A5hAAB\A@k@A@Z@l@@[@*@y@@@ږ@@j@ޣB@:s@?@DH@@*@4>@@@:@ˎ@Ҡ6@ʊd@_@|w@@%@L@h@@7@ľ@@h@ȯ@#`@`@k@O@<@@@+@@t@1r@8@8@[@@6@U_@i@/5@j@@@@@@f5@9@@ď@o@\L@I@a@@:@(g@LF@:@:@@@<@3@M@P@$@.@E^@-@~@@@@f@U@d@'@k@@@@/@*@D^@@;@@@M@2@K@|@ @Q@Εh@̭@q@G@jAL@lA@*@@@@A:V@@AYA=A@ΗA SAA0 A24AA|A U>A"ƈA)hAXxA>,AJ{ADA>;A\AA)dnA6]A$A&A(nEA0J-A+;A j A A XA;A JA1A9@.A @@s@r@@X@@@y@@ܙ@o@@@0A@x@ۀ@rh@@?@r@ @@nY@Ǜ@ɸ9@¼@J.@{S@-@@UT@ʪ.@@@q@Ϳ;@7@&@w@ʹ@B@@3h@ҁ@@Ӑ@Ȩ@@@@m@qF@L@n@@-@7@W@ë@R@@@i@$@@i@@@@h@Vj@@L@ŀ@=@H3@@d@@S@@k@#|@Y)@4@N@@H@ũ@¨j@e@V@@@u@@@il@}@^@/@Q@mb@@ȗ@ۄ@ኜ@ֹ@I@ZA@&@A¬@%AyAA AZAA{AAAA  AA?S$A {A4KA>A1ASvAAiAsA[gDAyzIAnuAA)8AqlAQk0AA1ApAUAAAoAAWA\AyAAsA@A>A;BsoB0ChBUVB# B'cB=LBSKB~BCmAB[C*CC;D{CMCCXm1C"BCBKUCxCKB>B'B7BNpBbB3v1B(&BASB1_B B)fB2B_$sBBY?BBBBIBwBAAABADABGAѵAݥAF]A%AA~AA@AzA,AA|A3A~AxA~/AQ'eAmuAOeABA4A)AeA,sA 'A A!PA! A]A5sAlAlA?A qA A@A AAApA6A AgA AJ@@^@@џ@[@WAօ@@@JA(AL$AIABAA &@mA \AWAAAA3rAAx`A1A3@0A@Az@@@/@A @[@ì@p@@@@Lu@Q@&@w@y@ܧ@^9@ޣ@8@@o@O@:q@ѣM@s@4@zf@J@1@@Z@?@֤@*7@[@E@le@v@@e@ @bL@M@@y@n@.}@X@o@Y @@C@ .@m@@@Ң@֝@p@@@6?@˭(@¼&@ā@@t@>@N@@@ƻ@ʒ@{@װ@؆e@@t@@짫AAΧA &A AJAA8/AA ӢA/cA"UA,2A: A!A,AA|A5A"ACABMA_1A'AqASEAqAA'A|AAA,AAAAA)A+A̧AlA$BBGBA/fBBtGB(~B'BaB#uBЈCYCBbCC@DBDC3D*^D3]EIDCBUBBĻBł=BAGBB#kA{B$B BLBk"AͫAB3ADAЬAGAAHA|{AA:AA!AAɴA'AAYAy AqWAAeApAcWKAμAOAZAP?AA\1AjARpAU1ATY>At"`A^ AjڡA8A[A[+AR\AY%/Ac8A)KA1 5A/HA&ʚA%jA&.AA%AAYAAiA ApA A(AAA#A"9AAAPOAA0@ @q'@W @@@֚@+%@@}@M@v<@@ 7@C)@@ Y@a@@@"C@?@>#@K^@ֈ@r@rA @&@@0@2k@@B@ ~@x@ɾn@/ @9@:@:ARA ^3A@)@AAA@9@W@A^@@BN@@R@Ww@"@K@O@ @>Ai]@|:ApAeA 0A :AA AA@$`@O@~@v@|@"@^@V@@/@5@@|{@T|@@݇@`@p1@˝@O@A oAA=AB@@~A e{@l%AAAB@(RAx@O@)A$@|jA fA AAAAA&DA0>A%tA%A-RAGGA=A*A&A6ANArMAV$Az5A[KAFAEA^AgAeAwAAAYAnA0AAAAgAAAYBOATB 8BOBBiUB QBg@ABE}BCD"xDE2CCtoCCB/BB8B]BjUBRB)3B {BŬA5AM^A?AAL*NA/3A4NA8ZA@pA(GA3A./ A.A2iA{2A$A2A AbkAT@Ae@mAhD@H@@@ @/@١@ܞ@@b@ͮ@@Ό@SG@l@O_@"@ˀu@QJ@P@Dl@֬@;@@@#@(@i@@ @0@@ƶq@_@ɠ@э@Ԗ@@;@i@ϥ)@)9@@ڈ@@Bk@=@@@@ @š@_@r@N@ˣx@֡@ي@z@֓R@8@"@ǽ@Տ@ıd@@#@l @@[@٬@V@dW@-@ӟ@ @@xr@@@B@@qA3ANA5@dAX;@ܱu@@V@@d@kAeA @@@S@AAvAVAA5dA*A 6A'hA7A'yA&ÁA= wA.A.A/1A, 6A4A"A0lA%A[oACA/A'AA#߸A>5A5{AAUA5y%A:A}nAo AhAJSTA^ÑAkB,AurkAbAs sAsڟAOANA0AAˆcAA|AAA+AAANAǴ=ABtGAf@V@ˠZ@.=@йu@s@/y@v@=@@2@9@'@^@@-@\@k@_@~@Uo@@-AA Kq@r@@<@T@ <@G@^@O\A A A@@6@$@9A@CAAo4@AnA&eA'6A0 A$A/.A?C9A1A9A)AA;ABbALAX6AO&fAE;AtKAr$AUAAAAqA]A/A8A6-AAALTB onB^BB:bB&GAAABB+jB.٫BbBuB~FBBC aCBbCTC[C?WBӕCuDtCD:qCمCCuC.C4͚C@nC7BB5BNB BxB{B/BB:B$BXB2:BtB\,B:BqwBDBMB1BDAA A2Ad]AeA2A.AAAAA AAAAA?VA AAA_A=A&A(KA#AAnA[AgA[|XAPAGAEMA:AW~A=6ACojA=TAUAYARAGANyA3>A'5A;7A9)A9RA2A5YA,*A3:A(9A2,A$)A'A:`A#A84A$A A A(TaAVA""A*/A1iA!QA('A!AA3\A-EA0iA4WA!eA'A$AwPAA mAAW AAA=A" AH'A"A!A" LA.`}A#.A]xAaA}AA kAA UA@AIA ~AA;A;5AdA.AL@M@@3@5@RA4A?AZ@@X@@x@@K@#@@@@G@0@@`@U@B@ܸ8@NO@̄@V@@@9@<@^yAsAA @wAJ`@_AM@@o@A@)AApAEA &,AlW@ AvQ@7@AAA;A%A1AA(A:A8A$A)A3{A=4A?Ac&AVAV%LA<A8wA<~ AJ/AkAxAAATAHA27A,A5AAJAAµAČHA@bAJ ARAR=BUAƁB*B8B/B\BBbBBBgBB!C7BCnBGCEA/" A8AICQADZAY>A8ABH' BnfB;J_BKuB DB%iBIBB BF_BVB~B*ywBBǝBBFABAAA?sAA{ A AAANHAYAy_AjApAcA(AqeyAjh7A^jA.bALAdQA]ArJAhAt AGzA_hABqAL9OA7A$͕A=iA(AfA,A$mA&'A'YAAA>A#$A$n A+rAn}A'3A!AA(AArMAA ZA%CA)A FA hCA AILArAA8SAA ANjAA;A#BA!nA.*AFiAքA$A7A,EAzA {A AA/SA~VAA A/BA AR@@A6AvAA \AAyA&A"\AaAAxA @xAxARAYAA A/AAVwA ruAA$A6@bDA A[AKA)A~AYAA} vAATAAAWAbsA_xAAdAAAnADkA`AxB!AA_EA#}A(BfBHB3B$rA^B+BBBvBiPMB_Bk'BݞUC C&C^oCZC!BzBbzC5CYGCEBB+3B6BkB4BF3B1B B!B0RBAABBB1B9B$9B:B%B"wBAA:AfAW;AoAp~A}AmAAwA-AzAx$ Aw[AԒAoAgAATAsWAAA !A~AA6AXA|AhA_7AGA.wAB}xA5A-XA:(]A A=A)_A/A,A!0A!WAW=AcA~`AAAAkAAAAHA A A .A@EO@hA9AxA A OA ;dA;cA A !A,-A>pA_AeoA_AA AUAɖAצA_AWvA ^Aa@A @'AF3AW)@@@~ALNAA6A_qAA6A leA @@.@@3@@A_@f@bAAR AA:\@[.@N@@4@,@RAAAJ,ArA4AAYA E@A@j@궋@O@AA!jA 6A$A6@A AՅAA 4AA$A+A8j{A>])AAEA6sA`ŌAY A>A4yAGACAE,A]A`/AK A\e^AdATpnAP0A2DA8 ACvAaAK AAe]AtL AAA[AwAAeA|FIAA AAόA^AHA A &AA LAAA%AA4A WBGBzBZbBi&B4wQBXBBZCB)C36:CYBqBfmB溷BC1CLjCkC;C'C?CBC@C q7C$>C?ɘCsB5BeBNBPC mBBBBqBlBrlBw8BӢBBBSB1ABDA,gA΍AGA{AJAAsAuA9AEA_AfBAKBGAA2lAJAAqWA4A7"AsCAlA|Ac}AdAA7A&A A !AA_C-CZ`C CD6CAC惲CB0C.]C:B]B$BBdCB~C*BJBQdBqdB)z7B-BAWTBChBGUBpB=BB=AA7B@B 7ABBBB B']B BA[Au(BAbOApG'Ap"/AAA_;A|A^Ak A`AmMAmZAqOAo9A]qUAI8A?PAWANGA*A+A" HA3ZA2LWA-8A*VA!iBA,bOAJVAFAUA]AGڪA@NA)-:A$RAA&$A!rA-S=A MAA"zAHA$uA/A"#A#A dAfA2AAA:A pAUAPjA]A%ʙAA A&A@@@@AKJ@#Q@A!@@%@Wb@2@@֛@k@N4@|@A.AuAAAA@@@9ACA[AMAAy#A NAMAA@Y@AAHAYA!A4ŊA+p}A5 A;܀ATAUANANAdXAF9Ax`A|ECAUA{Ar/AAtuAAA]A@'A<A .AA1>AzA"A,|AvAAAĕAgBAcB Aq8B BK3B4eBnAױB09B[BlB;B5BABe C""BMTB\BBӨC>Ch>BGDFTCCdCZChDDDC:gCBT?BƛBC0APA.OA\A#mA) A ٰA"_A CAAoA%QAuA-ALAAAAg'AyA(A@QANABA:QA6yJACuA%AkAƮA$A2A5{A>A=3PA6A"A54AA*AJAZA*̓A9kAJ5ALA3~AGATA`4A=AzMAw(cAjAq OAlAوAjAuAIrAA0A+ApȈAjAA+AP}AĀA0AǙmAڥA2AإcBZB 3BBA[BfBBr$OBB?3B%Bwz`BC CIC 'BJ=C*9BC"CCBDDBܜBKCkCC8d_B%.BB,BBBà'Br8B͑B`BB3BGBQBP;oB\eBW^ BJBVBIBB&#KBB5jB AA(A8A/$A(A"܀AbDAr*A$A+t$A4dA'?KAE AB\AG:AJk\AFUAEcA7~A6yA0A$ AA$l5A@A.A'+AI%A:uA?jAKACHA8A/GA A1xA5AFATv]AAA/aAd!AUAB_PACA0զA YA7-A"lA/A)RAcAzA%8A!u9A\AAA=AA A wA!A*SmAA1A,GATATUAKAWsA>xA&`oA-A0nAK,A`SAS-AVtAWA7A,yA-hqA!A+ AKACpAs;A]>AWwALKAmVAz-AAxNlAsDArAA2AwAHAAAA=AA7Ad*AWAA}A4$AŐA AA%ABiZAGAöBQAL|BAfAB/aDB0BQ\BLBpBeBB₱BIBB)C(sCs> DDC]V/BB0^C#CUY C&|CӲBC#ZzBCXrBUBVB/TB)BBBDBKrB%:BcnB҈BtBjB hJA<A?AS$ADAC wAERA7-AL%AAAYAG A?6UAMASw5A1A+iA%RA+A/A,A6A5ABA`AN7AdcvAcA\[ AOqAR8A9A2\@A:AغA%A(A(A*ABLAAA7]AMA*9A+N:AA6A-A2jA8xA:A8TA6AK2A9]AXA"AAAȧAA}AmA1xA(A!sA4A)A uA]A AAgABA0A&/bA3*A<|AAv%gAl`AS'AR8%ARMA\AY#YA_|A=PAtD{A~A|CeAhVLAV_AVAfAaAfnAaAdAd7AAArAOAA.ALA.YAڤAsAABAA˲A7AбqAAlAZyA%AAAAA0B OBAyB"B2BA&~AwtAuA yA \AAAhA1AseALdAIA@IA*)jAG`A>AC?A-\AoA9}A=?A^NA9nA1BACA? AIAEAIA+A4A3HA=iAHxAIA/O,A: A)A5A#zA/$A$A+`-AwA6,A'A kAC8_A-c,A7A%cA#8A+A AKATxA4A'mA47A)MA`AWA#AX AAAAAsA!A"hAA3mtCANёAhiAXNAeADwAHqA.,A&smA4 A"A@A#{:AFsAU[AgMAemAAAJvAmAAA=AAAAA[AlAvAKA}dAA?ARAA AYiAA^A54A9AFABMBB-!BB6B.B"sBB{?B6BF0;B&fBB9B7BoB[-BOB<BBBZCC-CCICCB?CDCϺDyD>C xCCrDPCR^CCqC )CCuClaCCf8C #CըCB. BB BҰCPBBC1BBlBBBB~Bw%BBiB~ДBB_B`B9BQzA3eA[A=6A9-A@[AU A`AP<A?A5(A1A3A"A$FA:q1A02AH~AZf+AZAYAdlqA{2AJ+AwZAA)AaAACAA$ANAMAAAAaAaAA5AM9AkAEoAKAKB B B; B! B1?'B00BB )B.B0(BV^zBZ%Bx6BB ] BWpBB;BC$)BޝCCC!WC jCzBUqCC=-bCjC;CsClCNC϶CUB#BCeCGc:BAOBBXBM4BsyBx|BŧBBBB?B=Bm)BeMBP~BjKBmLB~{BQ@BBxPBWBf~BJ6B%kB> BGBIBK B%rB_CB.B7|BK]B*KASKB(eB&1AA5AcAAA 6AA+rABAAA[AzA-.AA(AA}%Az:AAAi>AxA, A#AAcAvAaAG~AF:A@MAD AVA=eA[AjAU5A`3CAnAa ABAdxA`%AtAqA^FGAaAy;AKApiAntAe AxATAjTAUAaqApAaBAiNA_AAAlA'AD,A/AAAjAMA{AdAajAQE"Av AAAAAsVAǏAh AeKA[AWPAHAPAgLAm@AxA6AAnA_AlAp-_AFEAq6AJA6*AMrABYAETASAPsA_[AOAW-ACA3A1/A-}AiEAWAw(At=AjPAAaA{AvABA|nWAAidAt5Ag!wAp8AA+A~AdAqA|AgkA[AY'AdMAhAlAKAkAAAA AnqA"YA5AAA@'AA{AOAvA=AEAρ AA AAB: ABWB֝B3B0BBBapB8BI*UB̿B8BcBOBWBͤC_C&C G4BBѥaCCCrC"BPDq`}CDCCUBBaCB[CC&BvBBBGBcBBN B(xBHBDrBlBP֋B-\B%BG:sBAEa6ACa A[qcASAkAXAqΌAz#Ah&Az()AA}A~nA~AAs AsMAjoAdAxAJ[AU/A_aAZAzAAAO"AMTALPAlmAo\An3Afe[AWA?BC C.CAXC>CCCVyCbDKEC۝BBBYC6C^yB,BTrBkABBB]1B0B3NB B ?BBk:BҫB7DBNLBrDBy?BAB2Bh,yBBoτB"BB BBpBmBXB?B-B+BAA?AkANAXEPAEGAAF]AVaAM88AFyiAXAQBAm3AMAMϔA:A7ARAJyA@+AUAJAi8AuAZ_Af/A%Aq%Ax3tAaAbVAU&AvNAPA`FAaZ&A:AlA#Ai AvA[QAgӅAXAUXAlpASczALCAcAMBA^[AJ8AMA?'A.!:A5AFMA=A]vAwp!A AAAm AnAIAAmAyAvAsg[AIAA\ADvA;AʼnAA|AzA| AiAAgA*AALAyAvZAcAA.AueAAAACB (6B+IB#btBByB2BnNAA AAEAoA.BAKA~BB3B,BSYBn~Bb9BsB9xBB~ZBMC0BEC/'CtOB<BiCvCw@D'C4C>LCeDC1C=|B_BBA;C@MC6eB\BR#BNB_B٫BɷBE$9BpBGBIBMgBEBXBV=BBBBVB8SBsBOBNBQK(B4XBI]BQ3BdBEbB9ZB0{B \B$gB(B"oBB%i:B3RiB BBpA+B B;BA#AեApAA5A A*AAܹAAuAlAoA*AAn^Al/AcAIAfIAfbAlrAbPAvPOAuxAqA}A,AiASbAq)'AeAaAhRAx4AXtkAX 6AF0_A>fA8ALA.ARAALAhQVAAXAD۝ALAD A3`A@'AQAEjA6A=/A93A-/A?A/Z*AE8AFbAAD_YAJ9AJXA(y A6X AEA* A;5|AAMAആAAgAIAA!AVA?AAbA+AAARAMA"AיAApADA)A9 Ap5Aw AA'A`_Az`AqrAzwA\:At[AWA^FArŢAjAv!AnAgAvHvAAlApWAsAtxA A\ATAUHAKYHAUYAHٶAVZAXŀAO*ALAKzAGA2A@XA+GHA%q A$A(^AG(ABG,AeLA{SAANAxAAqc2AfAx +A^y0A|AvA[AkjAkA}AiAlAzsjAoArbAXkAiAl_AbAiAAҁA .AtAAAjA"A`A6AbAϊBKAAA9AA/AA@AuHAfAq/A>A)B BAB<&B$B%ըB?gBE;BL{vB5B[7BCB'BieBe/BPB|QB0BBBCBPcBՑCZ1C)C#C"BTC{CCiDAݪDDC]YCNDC CACD D CA@CKCXCnCC`OBBC zC C#XBmB>BQ"CCrBÍBVBvC K B[B(By;nBB%1BSbBEBB܆BBwvHB'.B/BBԇ-B.B$tBj;CBkBA~BB>Bx0;BB®5BcBzBB]BBa4B?o(BTBqD'BQ7wBB!B(gB'iB-'AB.B&B"_B&ABiA (AdAAtA&AAAA2AVAԖA!A3AǬA*}A׳AAʑAٓA'AA:IAA,A-AAAOAp6AmA}A*AXsAAAAAgADz@AμB5A7A>A sAAA}AAA\AAoAcAEA3A{A7AAgA }AAAA+ACAAkAHAWBA>A*>AtTAu AnA|*vAAD0Aw^AAʏARAXFAu8Ahd-A\xAWLAX"A|TAAA05AAӛA AsA9AAuAAiA0AA޶A˜IAAAA /AA[3A AtAnAwA.AtA*AӜzAÅAA}ATAإAXHAẠmAQA״MA6AmB}A׀AAOAÞMAAAvhA쵝A~BSBCB&JBgRBBs#BaB}QBIyBB ]BÒAAyAAɞQAA Aײ9AоA@AdAỶAnnAA'AɠBkA=ABUAX0AAmC¼6C{YBCk*CKsjC0CUC)$BC)=C"CKUCHeCCBBBQBӧBBBQBBT#B#BtB/BtzBfBBy.B7BaϾBf7BWB`BvpBBBjBoB}dEB>SBvVBppfB:B=sB5BB_yBi%BSBsB+*BC:BB4B ‘BB-2BBiB&B)*BB AP^ApvA AbA2A^WAŇA2AܮCAA>BkAjYB3AB AA0B ABYAsAlAA7AA_AA1AmA-AADAAAǀ,AV"ArAƶBAmA?AAmA(OA!A<AsA-A/A$ACA[AAQA&?AAcAۇA tAAA(Aw}A AXA^A4AJAZAA}mAAZN3Ar,A1,A`AEA5A|AmAAy% A1AA5AAAAC A<AAAA`AkAtABA1lBBAAgGAZA AJAA&AnAAMAKB BcBK CB%B)B1A+B A^|B eB!BEB%BfmB6;=B6AA"B.B(/B-B%B p>BոBBHG BzPBB@BBB1IB&C BBhC?&BZBB>BBwkCCfDQCpCNDC]Cx/CpC)C_&GCrCCNQBl!LBXB%BBoB&BZWBl.BwBŸB[~BnļBBz;B=uBZdB+) B_ݎBi RB~[BaB3BCAAAA1ALA|'A[WAAA/A`>AA'AA'uAs+AȂAdA[[AA[AA? AAIAAA݃mAnAhAVNA`AmUA{%AרAjA|A4ArABAא5ASAB,A AԁAtAAگA A8BB*fB)B,LAϩB AsAAoAAKA}DD\ADLD9CvD{E CD]؅CM#Cz8-DXDVpD1D7#ECCDzDCI#DMeC[C9C}wCCtC9^CC85CVICPCi{BW;BӉCCGCCe8BC%KgC LVC>)CBB*"BrSB-cC_BmTC$Z`BrB;BaC0BBsC4BϓBَ>BGC_B%sBz|BABBYBnB# BBBB BXBBb}B?aBwBZ|@BjQ0BBs1BBB}r1BBYBGBtgB;oBy}B`+BIBDOB.B7׾B7>EB \B&?A{AۉAoA@A tAAjAdhB tB BBrBBGB DA%XACYCZDŖDŖDOE#CCUD_[CXJCQsC0C!CACU CUC CC34C=CSC}CC4Cf4xCm C@C#B{0CB}C`9C#KDCZXC0C9BcBBÍCB1CB!C BCfBZB #B8CCBBBBBTA)AɰdAZoA6AɁAA 4AA7AvAHAAALA`BB[B B ƂB(r2BZYAB@BBC+hCC4C~'C.C CCDC=BD#EE>#KCtCbz7C`D~5D$}DD^CD(CP*C,QCVC{vCs]C4C/CUCvCއCC@*C#BCACCnRC<3C+BѭCCFsBCfB$BSB.B!B FBgBB!B7BIBwBYBbBBBbB5Bu(B׫BB?9BYBdUBABBUBB!ByPBeBceBv_BnB-?BYBL7BfB- B02B% BA{BQhMBT!B nB=B(OBB/B^BPAAAEA[6AxASBpAAAtAA`AAAWBXoBBObBP OBBHBS BFZB)BB)?B $1B'nB)IB.B+B&|!BzB;Bg Bo2B@AiB1BBtBoB^YBs7BB2JB>B*B6B3B.BB>B9BrB BbB3BgB`BO4B){BEBmKB4)BNBCCYBAEB?.C KC= tCɠCaCTSBboCfD b*D\CCVG]C D<>D6:C;CCD#2BN~CTC/NCDBCBCw0CCCCB[BJB~BDZBB?BkBB.BBABNHB`pBBeBdB(TBqBvBvABB|@BJBHB BS2kB>94B"BBɺBm,hBdBYBiBq Bt2BlBfBQBwBagBK@B51qB_BU BUGBB~B/ֶB BHDB0՟BsiBqBB0B] "BTB^LBaB?BpB^BR*BBc9BcB\Bb=B]Q8BBITB@ضBZ(B AiBADA9B ƈBB8B X;BSB0>/B*bBe/BB%B:mqB.DBzBPjB*MBjRB 94BB2Y$B@B}B pBAB A!ABB.IB>BKtkBaB5BxBByBoBDB_aB-B]BKABnWBnB=^BJBA BGXB0B4`BeBo-fB}ԛBSLYBP3BaB(IBC+~rD8D:DCEX+DDEC'/CCgCsCTCJB=C_C`C-TC@BC 3CCjC!BMuB>|BBCB$DBBX%BdBf3B8"B~B;AMxB AN6BgeB5Bqo[BK_5BB/B2%dBbBi3B5@B1B\-BH,&BZdABU>B>"B4BEBcBI}B B*B ?%BTB5:BOPB|BB ByBB2RBC*BހBlC)C C6?CUC/Bv_C,C&C=XB0BRCCC& C`g6CWB6CCx7CzYC@CNB BfC=_CIDC(pCC!8C:CCC%DB4BCBCPC UB^B8BB[BC]Bυ]BNJBB8C2+B8BIBBBwZBqBlBB%BB BO`Bw*vBT BYBljBN B7_Bm'BQBκBvBLBwSBBABEoBqWB!mBH BJBBmjBCBB7BzBC =CB7Bڥ9BrBFC$ԹCbC:^C=BTB>BtBttBB>xB5uB+lBUhBHBbMB}m]BbBMB3 B&B̿DCB˹]C`BI5BڡBSBY8)BcB~BVBBhkBo:BB.bPBrBF#BxOBBBC%rC B"B;BZyBgBgB&mCkCCx7C#bCXZ^C2=D/ICvxC&Ce C"8VCCg=DlDmDcC"GDCVCD7 DyDQDׁDIeD9sDD3CC,CZC˞XCufCE@5C`C6CL1C4CqSCCcRChBBCOVC4HCHC+"CCf#sCLBZC;KrCBerC6IC(C)MCjRB_C߭CPCAuC|CB;C B C&ACC$CC8BC`CC""CtCC1C *C/OCgSC C-BBCHC0PBȦ6CB܂C.VC e6CvBCG2:CCl\CJ+C pC/BC?PCDC1PC-]BC$ZCCI2CRC)CC;=CC7C[3@CXsC[C'`]CC|CiC"C-շCUjCxCC3C`OCA3CL۫CCC BhBǛB1BUBGBsBGoB8_Bx^B}%B}{BQB'BƸ8BBC`BbCFBQB6}B{B[yB#BcYBh ByBq-Bg!BYBR#BgBcBBfB$PBI(^BXKsB`BB֣CCCrUC9ZCDOCCBU.BB|B\BƪBB‰BBvBhBT/AByVBwCU?C|D'BCD;NC \CE VCٗCdCnCCB)C#qgCC:jC[%{C0qC(%CCWbC9C`9C\^CnfC,CUBȣB=eBוBB\LB2BBrB*BjB+BuWB Bl~B<>COrCXC]DKYE DD%D*D{CCC Y[CwC%C3BBB¸3C;|BBwaB=OBm BJBB7CBEBFCV1CRHC B)>C nC XC?B&C- C<,D CraC!C85.C)C`BCBmCj5CfC+BvCBLBB|BCRC0CXJCC߄DzV C,^lCgC1CBB:B9wBsBYBmB&+B݆BOQ}BYB]kB"B#Bo!CDpCCu,DjC8CVaDECtPCRC,C TCyC=CCC e\BBCPBCC|9C]CRruD%CK'D*2CZ%CC}wCY CCICEb"DC#CzNC1BBu[BUBBXB{mByBB.CPC;DVD ]DmD9DsCCw$CnCgBBBBvBCBBxB|U$BBIBIB)CPCCBSF CCnE)CcC3PwCLQCC${BǞCCBzBCC,BlC CC'CND{D8DnJDYn4DWvcC\DD.-C&&C~C ΑBTB;ZBg@BfBHW~B?BC.eClD9EE5DC2RDT6C%CC!~BBhIBҰoC5`BBDBB~mBy;BXOdB(?BWCC)CDY]D'jDCC0CrmC(C\CSCymC4ÒBfB)C@RRC;C?]DDGDDDCDC!C#nC$^UBgBBj5Bt_;BBC4CaC#EeBgFNND]HEDCJC;BmHBBCRC8BC{B93BRB3B BiC rBeC0;D tCjB3^CC)tDCCCcCD}CbCtC+DI"CLICCE?/D D0C=CACBEBVZBB*|BBæC1tCDCsDNQCCdЋBBƪCH;C!,wBBBgBþBBB C'CpC0CD*SDEC6CޙCD~`D=3D+YDK|D4D&DE8CC*CBOKBepB~B|B|CCDwx|D 5Dq1DYD 3C*DYYCNC3gB!BABҩBB4BnC C޻DD^CbCLjC@yC# gC|bB]CCAByCBNBHC+gC }BеCrD E2nCDCTC]C=&BBBoBB%BpCԻCQCd(DEhDaCCfCYHC[?2C/O%ChCǔBA.BBC0DD*CDptD4DMCD\|CgC2~&B"BtBHBSC'ZCn.KC #include #include "math_kst.h" namespace QTest { template<> inline bool qCompare(double const& val, double const * const& nan, const char *actual, const char *expected, const char *file, int line) { return qCompare( QByteArray((char*) &val, sizeof(double)), QByteArray((char*) nan, sizeof(double)), actual, expected, file, line); } } #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/main.cpp000644 001750 001750 00000004064 11544160206 015466 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "testdatasource.h" #include "testvector.h" #include "testscalar.h" #include "testmatrix.h" #include "testdatamatrix.h" #include "testgeneratedmatrix.h" #include "testcsd.h" #include "testpsd.h" #include "testhistogram.h" #include "testeditablematrix.h" #include "testlabelparser.h" #include "testeqparser.h" #include "testobjectstore.h" int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); TestDataSource test1; QTest::qExec(&test1, argc, argv); TestVector test2; QTest::qExec(&test2, argc, argv); TestScalar test3; QTest::qExec(&test3, argc, argv); TestMatrix test4; QTest::qExec(&test4, argc, argv); TestPSD test5; QTest::qExec(&test5, argc, argv); TestHistogram test6; QTest::qExec(&test6, argc, argv); TestCSD test7; QTest::qExec(&test7, argc, argv); TestEditableMatrix test8; QTest::qExec(&test8, argc, argv); TestDataMatrix dataMatrixTest; QTest::qExec(&dataMatrixTest, argc, argv); TestGeneratedMatrix generatedMatrixTest; QTest::qExec(&generatedMatrixTest, argc, argv); TestLabelParser test9; QTest::qExec(&test9, argc, argv); TestEqParser test10; QTest::qExec(&test10, argc, argv); TestObjectStore test11; QTest::qExec(&test11, argc, argv); return 0; } // vim: ts=2 sw=2 et kst-2.0.3/tests/testgeneratedmatrix.cpp000644 001750 001750 00000003717 11544160206 020631 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "testgeneratedmatrix.h" #include #include #include #include #include #include #include static Kst::ObjectStore _store; void TestGeneratedMatrix::cleanupTestCase() { _store.clear(); } void TestGeneratedMatrix::testGeneratedMatrix() { bool ok = true; //basic default constructor values Kst::GeneratedMatrixPtr m1 = Kst::kst_cast(_store.createObject()); QCOMPARE(m1->sampleCount(), 1); QCOMPARE(m1->minValue(), 0.0); QCOMPARE(m1->maxValue(), 0.0); QCOMPARE(m1->value(0, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(m1->value(10, 10, &ok), 0.0); //should be outside the boundaries. QVERIFY(!ok); QCOMPARE(m1->meanValue(), 0.0); m1->change(10, 10, 0, 0, 1, 1, 0, 100, 0); m1->writeLock(); m1->internalUpdate(); m1->unlock(); QCOMPARE(m1->sampleCount(), 100); QCOMPARE(m1->minValue(), 0.0); QCOMPARE(m1->maxValue(), 100.0); QCOMPARE(m1->value(0, 0, &ok), 0.0); QVERIFY(ok); QCOMPARE(m1->value(0, 9, &ok), 100.0); QVERIFY(ok); } #ifdef KST_USE_QTEST_MAIN QTEST_MAIN(TestGeneratedMatrix) #endif // vim: ts=2 sw=2 et kst-2.0.3/tests/testdatasource.h000644 001750 001750 00000002416 11544160206 017240 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TESTDATASOURCE_H #define TESTDATASOURCE_H #include #include class TestDataSource : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void cleanupTestCase(); void testAscii(); void testDirfile(); void testCDF(); void testFrame(); void testIndirect(); void testLFI(); void testPlanck(); void testStdin(); void testQImageSource(); void testFITSImage(); private: QStringList _plugins; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/COPYING-DOCS000644 001750 001750 00000047663 11544160206 014471 0ustar00synthsynth000000 000000 GNU Free Documentation License Version 1.2, November 2002 Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 0. PREAMBLE The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. 1. APPLICABILITY AND DEFINITIONS This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque". Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. 2. VERBATIM COPYING You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. 3. COPYING IN QUANTITY If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. 4. MODIFICATIONS You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version. N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles. You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. 5. COMBINING DOCUMENTS You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements". 6. COLLECTIONS OF DOCUMENTS You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. 7. AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. 8. TRANSLATION Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. 9. TERMINATION You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 10. FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. ADDENDUM: How to use this License for your documents To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page: Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with...Texts." line with this: with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software. kst-2.0.3/misc/IDL 18 Pastels000644 001750 001750 00000004726 11544160206 015774 0ustar00synthsynth000000 000000 GIMP Palette 255 0 72 255 0 72 255 0 74 255 0 76 255 0 78 255 0 80 255 0 82 255 0 84 255 0 86 255 0 88 255 0 90 255 0 91 255 0 93 255 0 95 255 0 97 255 0 99 255 0 101 255 0 103 255 0 105 255 0 107 255 0 109 255 0 111 255 0 113 255 0 115 255 0 117 255 0 119 255 0 121 255 0 123 255 0 125 255 0 127 255 0 129 255 0 131 255 0 133 255 0 135 255 0 137 255 0 139 255 0 141 255 0 142 255 0 144 255 0 146 255 0 148 255 0 150 255 0 152 255 0 154 255 0 156 255 0 158 255 0 160 255 0 162 255 0 164 255 0 166 255 0 168 255 0 170 255 0 172 255 0 174 255 0 176 255 0 178 255 0 180 255 0 182 255 0 184 255 0 186 255 0 188 255 0 190 255 0 191 255 0 193 255 0 195 255 0 197 255 0 199 255 0 201 255 0 203 255 0 205 255 0 207 255 0 209 255 0 211 255 0 213 255 0 215 255 0 217 255 0 219 255 0 221 255 0 223 255 0 225 255 0 227 255 0 229 255 0 231 255 0 233 255 0 235 255 0 237 255 0 239 255 0 241 255 0 242 255 0 244 255 0 246 255 0 248 255 0 250 255 0 252 255 0 254 253 0 255 251 0 255 249 0 255 247 0 255 245 0 255 243 0 255 241 0 255 239 0 255 237 0 255 235 0 255 233 0 255 231 0 255 229 0 255 227 0 255 225 0 255 223 0 255 221 0 255 219 0 255 217 0 255 216 0 255 214 0 255 212 0 255 210 0 255 208 0 255 206 0 255 204 0 255 202 0 255 200 0 255 198 0 255 196 0 255 194 0 255 192 0 255 190 0 255 188 0 255 186 0 255 0 140 255 0 146 255 0 152 255 0 157 255 0 163 255 0 169 255 0 174 255 0 180 255 0 186 255 0 192 255 0 197 255 0 203 255 0 209 255 0 214 255 0 220 255 0 226 255 0 232 255 0 237 255 0 243 255 0 249 255 0 255 255 0 255 249 0 255 243 0 255 237 0 255 232 0 255 226 0 255 220 0 255 214 0 255 209 0 255 203 0 255 197 0 255 192 0 255 186 0 255 180 0 255 174 0 255 169 0 255 163 0 255 157 0 255 152 0 255 146 0 255 140 0 255 134 0 255 129 0 255 123 0 255 117 0 255 112 0 255 106 0 255 100 0 255 94 0 255 89 0 255 83 0 255 77 0 255 71 0 255 66 0 255 60 0 255 54 0 255 49 0 255 43 0 255 37 0 255 31 0 255 26 0 255 20 0 255 14 0 255 9 0 255 3 2 255 0 8 255 0 13 255 0 19 255 0 25 255 0 30 255 0 36 255 0 42 255 0 48 255 0 53 255 0 59 255 0 65 255 0 71 255 0 76 255 0 82 255 0 88 255 0 93 255 0 99 255 0 105 255 0 111 255 0 116 255 0 122 255 0 128 255 0 133 255 0 139 255 0 145 255 0 151 255 0 156 255 0 162 255 0 168 255 0 173 255 0 179 255 0 185 255 0 191 255 0 196 255 0 202 255 0 208 255 0 214 255 0 219 255 0 225 255 0 231 255 0 236 255 0 242 255 0 248 255 0 254 255 0 255 250 0 255 244 0 255 238 0 255 233 0 255 227 0 255 221 0 255 215 0 255 210 0 255 204 0 255 198 0 255 193 0 255 187 0 255 181 0 255 175 0 255 170 0 255 170 0 kst-2.0.3/misc/IDL 25 Mac-Style000644 001750 001750 00000004623 11544160206 016151 0ustar00synthsynth000000 000000 GIMP Palette 124 0 255 124 0 255 120 0 254 115 0 255 111 0 254 106 0 255 102 0 254 97 0 255 93 0 254 88 0 255 84 0 254 79 0 255 75 0 254 70 0 255 66 0 254 61 0 255 57 0 254 52 0 255 48 0 254 43 0 255 39 0 254 34 0 255 30 0 254 25 0 255 21 0 254 16 0 255 12 0 254 7 0 255 3 0 254 0 2 255 0 6 254 0 11 255 0 15 254 0 20 255 0 24 254 0 29 255 0 33 254 0 38 255 0 42 254 0 47 255 0 51 254 0 56 255 0 60 254 0 65 255 0 69 254 0 74 255 0 78 254 0 83 255 0 87 254 0 92 255 0 96 254 0 101 255 0 105 254 0 110 255 0 114 254 0 119 255 0 122 254 0 128 255 0 131 254 0 137 255 0 140 254 0 146 255 0 149 254 0 155 255 0 158 254 0 164 255 0 167 254 0 173 255 0 176 254 0 182 255 0 185 254 0 191 255 0 194 254 0 200 255 0 203 254 0 209 255 0 212 254 0 218 255 0 221 254 0 227 255 0 230 254 0 236 255 0 240 254 0 245 255 0 249 254 0 254 255 0 254 250 0 255 247 0 254 241 0 255 238 0 254 232 0 255 229 0 254 223 0 255 220 0 254 214 0 255 211 0 254 205 0 255 202 0 254 196 0 255 193 0 254 187 0 255 184 0 254 178 0 255 175 0 254 169 0 255 166 0 254 160 0 255 157 0 254 151 0 255 148 0 254 142 0 255 139 0 254 133 0 255 130 0 254 125 0 255 121 0 254 116 0 255 112 0 254 107 0 255 103 0 254 98 0 255 94 0 254 89 0 255 85 0 254 80 0 255 76 0 254 71 0 255 67 0 254 62 0 255 58 0 254 53 0 255 49 0 254 44 0 255 40 0 254 35 0 255 31 0 254 26 0 255 22 0 254 17 0 255 13 0 254 8 0 255 4 1 254 0 5 255 0 13 254 0 14 255 0 19 254 0 23 255 0 28 254 0 32 255 0 37 254 0 41 255 0 46 254 0 50 255 0 55 254 0 59 255 0 64 254 0 68 255 0 73 254 0 77 255 0 82 254 0 86 255 0 91 254 0 95 255 0 100 254 0 104 255 0 109 254 0 113 255 0 118 254 0 123 255 0 126 254 0 132 255 0 135 254 0 141 255 0 144 254 0 150 255 0 153 254 0 159 255 0 162 254 0 168 255 0 171 254 0 177 255 0 180 254 0 186 255 0 189 254 0 195 255 0 198 254 0 204 255 0 207 254 0 213 255 0 216 254 0 222 255 0 225 254 0 231 255 0 234 254 0 240 255 0 243 254 0 249 255 0 252 254 0 255 252 0 254 247 0 255 243 0 254 238 0 255 234 0 254 229 0 255 225 0 254 220 0 255 216 0 254 211 0 255 207 0 254 202 0 255 198 0 254 193 0 255 189 0 254 184 0 255 180 0 254 175 0 255 171 0 254 166 0 255 162 0 254 157 0 255 153 0 254 148 0 255 144 0 254 139 0 255 135 0 254 131 0 255 126 0 254 122 0 255 117 0 254 113 0 255 108 0 254 104 0 255 99 0 254 95 0 255 90 0 254 86 0 255 81 0 254 77 0 255 72 0 254 68 0 255 63 0 254 59 0 255 54 0 254 50 0 255 45 0 254 41 0 255 36 0 254 32 0 255 27 0 254 23 0 255 18 0 254 14 0 255 9 0 255 5 0 255 5 0 kst-2.0.3/misc/IDL 22 Hue-Sat-Value2000644 001750 001750 00000005614 11544160206 016753 0ustar00synthsynth000000 000000 GIMP Palette 255 253 253 255 253 253 255 252 252 255 251 251 255 250 250 255 249 249 255 248 248 255 247 248 255 246 247 255 245 247 255 244 246 255 243 246 255 242 245 255 241 245 255 240 244 255 239 244 255 238 244 255 237 244 255 236 243 255 235 243 255 234 243 255 233 243 255 232 243 255 231 243 255 230 243 255 229 243 255 228 244 255 227 244 255 226 244 255 225 244 255 224 245 255 223 245 255 222 246 255 221 246 255 220 247 255 219 247 255 218 248 255 217 249 255 216 250 255 215 250 255 214 251 255 213 252 255 212 253 255 211 254 254 210 255 253 209 255 252 208 255 251 207 255 249 206 255 248 205 255 247 204 255 246 203 255 244 202 255 243 201 255 241 200 255 240 199 255 238 198 255 237 197 255 235 196 255 233 195 255 231 194 255 230 193 255 228 192 255 226 191 255 224 190 255 222 189 255 220 188 255 218 187 255 216 186 255 213 185 255 211 184 255 209 183 255 207 182 255 204 181 255 202 180 255 199 179 255 197 178 255 194 177 255 192 176 255 189 175 255 187 174 255 184 173 255 181 172 255 178 171 255 175 170 255 172 169 255 170 169 255 168 169 255 167 170 255 166 171 255 165 172 255 164 173 255 163 174 255 162 176 255 161 177 255 160 178 255 159 180 255 158 181 255 157 183 255 156 184 255 155 186 255 154 188 255 153 189 255 152 191 255 151 193 255 150 195 255 149 197 255 148 199 255 147 201 255 146 203 255 145 205 255 144 207 255 143 209 255 142 211 255 141 214 255 140 216 255 139 218 255 138 221 255 137 223 255 136 226 255 135 228 255 134 231 255 133 233 255 132 236 255 131 239 255 130 241 255 129 244 255 128 247 255 127 250 255 126 253 255 125 255 253 124 255 250 123 255 247 122 255 244 121 255 241 120 255 237 119 255 234 118 255 231 117 255 227 116 255 224 115 255 220 114 255 217 113 255 213 112 255 210 111 255 206 110 255 203 109 255 199 108 255 195 107 255 191 106 255 187 105 255 183 104 255 179 103 255 175 102 255 171 101 255 167 100 255 163 99 255 159 98 255 155 97 255 150 96 255 146 95 255 142 94 255 137 93 255 133 92 255 128 91 255 124 90 255 119 89 255 114 88 255 110 87 255 105 86 255 100 85 255 95 85 255 90 84 255 86 84 255 83 88 255 82 91 255 81 94 255 80 97 255 79 100 255 78 103 255 77 107 255 76 110 255 75 114 255 74 117 255 73 121 255 72 124 255 71 128 255 70 131 255 69 135 255 68 139 255 67 143 255 66 146 255 65 150 255 64 154 255 63 158 255 62 162 255 61 166 255 60 170 255 59 174 255 58 179 255 57 183 255 56 187 255 55 191 255 54 196 255 53 200 255 52 205 255 51 209 255 50 214 255 49 218 255 48 223 255 47 228 255 46 233 255 45 237 255 44 242 255 43 247 255 42 252 255 41 255 252 40 255 247 39 255 242 38 255 237 37 255 232 36 255 226 35 255 221 34 255 216 33 255 211 32 255 205 31 255 200 30 255 194 29 255 189 28 255 183 27 255 178 26 255 172 25 255 166 24 255 160 23 255 155 22 255 149 21 255 143 20 255 137 19 255 131 18 255 125 17 255 119 16 255 113 15 255 107 14 255 100 13 255 94 12 255 88 11 255 81 13 255 75 9 255 69 8 255 62 7 255 56 6 255 49 5 255 42 4 255 36 3 255 29 2 255 29 2 kst-2.0.3/misc/linux-release.sh000755 001750 001750 00000001422 11544160206 016736 0ustar00synthsynth000000 000000 #!/bin/sh # Usage # linux-release optional: # e.g: # build only : linux-release.sh Kst-2.0.3-beta2 # build and upload: linux-release.sh Kst-2.0.3-beta2 "Kst\\ 2.0.3" username # upload only : linux-release.sh Kst-2.0.3-beta2 "Kst\\ 2.0.3" username skip # kst_install_prefix=$1 if [ -z ${4} ] then cmake ../kst/cmake -Dkst_release=1 -Dkst_merge_files=1 -Dkst_install_prefix=$kst_install_prefix make -j4 make install make package make package_source fi if [ ! -z ${3} ] then # spaces in $2 "Kst\\ 2.0.3" scp \ ${kst_install_prefix}-binary.sh \ ${kst_install_prefix}.tar.gz \ ${kst_install_prefix}.tar.bz2 \ ${3},kst@frs.sourceforge.net:"/home/frs/project/k/ks/kst/${2}" fi kst-2.0.3/misc/IDL 05 STD-Gamma-II000644 001750 001750 00000004677 11544160206 016333 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 0 5 0 0 10 0 0 15 0 0 20 0 0 26 0 0 31 0 0 36 0 0 41 0 0 46 0 0 52 0 0 57 0 0 62 0 0 67 0 0 72 0 0 78 0 0 83 0 0 88 0 0 93 0 0 98 0 0 104 0 0 109 0 0 114 0 0 119 0 0 124 0 0 130 0 0 135 0 0 140 0 0 145 0 0 150 0 0 156 0 0 161 0 0 166 0 0 171 0 0 176 0 0 182 0 0 187 0 0 192 0 0 197 0 0 202 0 0 208 0 0 213 0 0 218 0 0 223 0 0 228 0 0 234 0 0 239 0 0 244 4 0 249 9 0 255 14 0 250 19 0 245 23 0 239 28 0 234 33 0 228 38 0 223 42 0 218 47 0 212 52 0 207 57 0 201 61 0 196 66 0 190 71 0 185 76 0 180 81 0 174 81 0 169 81 0 163 81 0 158 81 0 152 81 0 147 81 0 142 81 0 136 80 0 131 80 0 125 80 0 120 80 0 114 80 0 109 80 0 104 80 0 98 79 0 93 84 0 87 89 0 82 94 0 76 99 0 71 104 0 66 109 0 60 114 0 55 119 0 49 124 0 44 129 0 38 134 0 33 139 0 28 144 0 22 149 0 17 154 0 11 159 0 6 164 0 0 169 0 0 174 0 0 180 0 0 185 0 0 190 0 0 196 0 0 201 0 0 206 0 0 212 0 0 217 0 0 222 0 0 228 0 0 233 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 5 0 255 10 0 255 16 0 255 21 0 255 27 0 255 32 0 255 37 0 255 43 0 255 48 0 255 54 0 255 59 0 255 64 0 255 70 0 255 75 0 255 81 0 255 85 4 255 90 9 255 95 14 255 100 19 255 105 24 255 109 28 255 114 33 255 119 38 255 124 43 255 129 48 255 134 53 255 138 57 255 143 62 255 148 67 255 153 72 255 158 77 255 163 82 255 163 77 255 163 71 255 163 65 255 163 59 255 163 53 255 163 47 255 163 41 255 163 36 255 163 30 255 163 24 255 163 18 255 163 12 255 163 6 255 163 0 255 163 0 255 163 0 255 163 0 248 163 0 240 163 0 232 163 0 225 163 0 217 163 0 209 163 0 202 163 0 194 163 0 186 163 0 179 163 0 171 163 0 163 163 0 168 163 0 173 163 0 178 169 3 183 175 6 188 181 9 193 187 12 198 193 16 203 199 19 209 205 22 214 212 25 219 218 29 224 224 32 229 230 35 234 236 38 239 242 41 244 248 45 249 255 48 255 255 51 255 255 54 255 255 58 255 255 61 255 255 64 255 255 67 255 255 71 255 255 74 255 255 77 255 255 80 255 255 83 255 255 87 255 255 90 255 255 93 255 255 96 255 255 100 255 255 103 255 255 106 255 255 109 255 255 112 255 255 116 255 255 119 255 255 122 255 255 125 255 255 129 255 255 132 255 255 135 255 255 138 255 255 142 255 255 145 255 255 148 255 255 151 255 255 154 255 255 158 255 255 161 255 255 164 255 255 167 255 255 171 255 255 174 255 255 177 255 255 180 255 255 183 255 255 187 255 255 190 255 255 193 255 255 196 255 255 200 255 255 203 255 255 206 255 255 209 255 255 213 255 255 216 255 255 219 255 255 222 255 255 225 255 255 229 255 255 232 255 255 235 255 255 238 255 255 242 255 255 245 255 255 248 255 255 251 255 255 255 kst-2.0.3/misc/IDL 19 Hue-Sat-Light1000644 001750 001750 00000005634 11544160206 016755 0ustar00synthsynth000000 000000 GIMP Palette 251 0 3 251 0 3 251 0 9 251 1 15 252 1 22 252 2 28 253 2 34 252 4 41 252 5 48 251 7 55 251 8 62 250 7 66 250 9 73 249 13 81 249 8 84 249 15 94 248 17 100 248 18 106 247 20 112 247 21 118 246 23 124 246 24 130 246 26 135 245 27 141 245 28 147 244 30 152 244 31 157 243 33 162 243 34 168 243 35 173 242 37 178 242 38 183 241 40 187 241 41 192 241 42 197 240 44 201 240 45 206 240 46 210 239 48 215 239 49 219 239 50 223 238 52 227 238 53 231 237 55 235 235 56 237 230 57 237 226 59 236 222 60 236 217 61 236 213 63 235 209 64 235 205 65 235 201 66 235 197 68 234 194 69 234 190 70 234 186 72 233 183 73 233 179 74 233 176 76 232 173 77 232 169 78 232 166 79 232 163 81 231 160 82 231 157 83 231 154 84 230 151 85 230 148 86 230 145 87 230 143 88 230 140 90 229 137 91 229 135 92 229 133 93 229 130 95 228 128 96 228 126 97 228 124 98 228 122 99 228 120 101 227 118 102 227 116 103 227 114 104 227 112 105 227 111 107 226 109 108 226 109 110 226 110 114 226 111 118 226 113 122 225 114 125 225 115 129 225 116 132 225 117 136 225 118 139 225 119 143 225 121 146 224 122 149 224 123 152 224 125 156 224 125 158 224 126 161 224 127 164 224 128 167 224 129 170 224 131 173 223 132 175 223 133 178 223 135 181 223 136 184 223 137 186 223 138 188 223 139 191 223 140 193 223 140 195 223 141 197 223 142 199 223 144 201 222 145 203 222 146 205 222 147 207 222 148 209 222 149 211 222 150 213 222 151 215 222 152 216 222 153 218 222 154 220 222 155 221 222 156 222 221 157 222 220 158 222 218 159 222 217 160 222 216 161 222 214 162 222 213 163 222 212 164 222 211 165 222 210 166 222 208 167 222 207 168 222 206 169 222 206 170 222 205 171 222 204 171 223 203 172 223 202 174 223 202 174 223 201 175 223 200 176 223 200 177 223 199 178 223 198 179 223 198 180 223 197 181 223 197 182 223 197 183 223 196 184 224 197 185 224 196 185 224 196 186 224 195 187 224 195 188 224 195 189 224 195 190 224 195 190 225 195 191 225 195 192 225 195 193 225 195 194 225 195 195 225 195 196 225 196 197 226 196 199 226 197 200 226 198 202 226 199 203 226 200 204 226 201 206 227 201 207 227 202 208 227 203 210 227 204 211 227 205 212 228 205 213 228 206 214 228 207 215 228 208 216 228 209 217 229 209 218 229 210 219 229 211 220 229 212 220 229 212 221 229 213 222 230 213 223 230 214 224 230 215 225 230 216 226 231 216 226 231 217 227 232 218 228 232 218 228 232 219 229 232 220 230 232 221 230 233 221 231 233 222 232 233 223 232 234 223 233 234 224 233 234 225 234 234 226 235 235 226 235 235 227 235 235 228 236 236 228 236 236 229 236 236 230 237 236 230 237 236 231 237 237 232 238 237 232 238 237 233 239 237 233 239 238 234 239 238 235 240 238 235 240 239 236 240 239 237 241 239 237 242 240 238 242 240 238 242 241 239 242 241 240 243 242 240 243 242 241 244 242 241 244 243 242 244 243 243 245 244 243 245 244 244 246 245 244 246 245 245 246 246 246 247 246 246 247 247 247 248 247 247 248 248 248 249 248 248 249 249 249 250 249 249 250 250 250 251 250 250 251 250 250 kst-2.0.3/misc/IDL 40 Rainbow-Black000644 001750 001750 00000004501 11544160206 016756 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 4 0 3 9 0 7 13 0 10 18 0 14 22 0 19 27 0 23 31 0 28 36 0 32 40 0 38 45 0 43 50 0 48 58 0 59 61 0 63 64 0 68 68 0 72 69 0 77 72 0 81 74 0 86 77 0 91 79 0 95 80 0 100 82 0 104 83 0 109 84 0 118 86 0 122 87 0 127 88 0 132 86 0 136 87 0 141 87 0 145 87 0 150 85 0 154 84 0 159 84 0 163 84 0 168 79 0 177 78 0 182 77 0 186 76 0 191 71 0 195 70 0 200 68 0 204 66 0 209 60 0 214 58 0 218 55 0 223 46 0 232 43 0 236 40 0 241 36 0 245 33 0 250 25 0 255 21 0 255 16 0 255 12 0 255 4 0 255 0 0 255 0 4 255 0 16 255 0 21 255 0 25 255 0 29 255 0 38 255 0 42 255 0 46 255 0 51 255 0 55 255 0 63 255 0 67 255 0 72 255 0 84 255 0 89 255 0 93 255 0 97 255 0 106 255 0 110 255 0 114 255 0 119 255 0 127 255 0 131 255 0 135 255 0 140 255 0 152 255 0 157 255 0 161 255 0 165 255 0 174 255 0 178 255 0 182 255 0 187 255 0 195 255 0 199 255 0 203 255 0 216 255 0 220 255 0 225 255 0 229 255 0 233 255 0 242 255 0 246 255 0 250 255 0 255 255 0 255 246 0 255 242 0 255 238 0 255 225 0 255 220 0 255 216 0 255 212 0 255 203 0 255 199 0 255 195 0 255 191 0 255 187 0 255 178 0 255 174 0 255 170 0 255 157 0 255 152 0 255 148 0 255 144 0 255 135 0 255 131 0 255 127 0 255 123 0 255 114 0 255 110 0 255 106 0 255 102 0 255 89 0 255 84 0 255 80 0 255 76 0 255 67 0 255 63 0 255 59 0 255 55 0 255 46 0 255 42 0 255 38 0 255 25 0 255 21 0 255 16 0 255 12 0 255 8 0 255 0 4 255 0 8 255 0 12 255 0 21 255 0 25 255 0 29 255 0 42 255 0 46 255 0 51 255 0 55 255 0 63 255 0 67 255 0 72 255 0 76 255 0 80 255 0 89 255 0 93 255 0 97 255 0 110 255 0 114 255 0 119 255 0 123 255 0 131 255 0 135 255 0 140 255 0 144 255 0 153 255 0 157 255 0 161 255 0 165 255 0 178 255 0 182 255 0 187 255 0 191 255 0 199 255 0 203 255 0 208 255 0 212 255 0 221 255 0 225 255 0 229 255 0 242 255 0 246 255 0 250 255 0 255 255 0 255 250 0 255 242 0 255 238 0 255 233 0 255 229 0 255 221 0 255 216 0 255 212 0 255 199 0 255 195 0 255 191 0 255 187 0 255 178 0 255 174 0 255 170 0 255 165 0 255 161 0 255 153 0 255 148 0 255 144 0 255 131 0 255 127 0 255 123 0 255 119 0 255 110 0 255 106 0 255 102 0 255 97 0 255 89 0 255 85 0 255 80 0 255 76 0 255 63 0 255 59 0 255 55 0 255 51 0 255 42 0 255 38 0 255 34 0 255 29 0 255 21 0 255 17 0 255 12 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 kst-2.0.3/misc/IDL 28 Hardcandy000644 001750 001750 00000005127 11544160206 016253 0ustar00synthsynth000000 000000 GIMP Palette 4 51 116 4 51 116 5 58 105 7 65 94 9 72 84 11 79 74 12 85 64 14 92 55 15 99 46 16 105 38 17 111 30 17 117 24 18 124 18 18 129 12 18 135 8 17 141 5 16 146 2 15 152 0 14 157 0 13 162 0 11 167 1 13 171 3 8 176 6 5 180 13 3 184 14 1 188 20 0 191 26 3 195 33 5 198 41 7 201 50 13 203 59 12 206 68 13 208 78 15 210 88 17 212 99 18 213 109 19 214 120 19 215 131 19 216 142 19 216 153 19 216 163 18 216 174 16 216 184 14 215 193 12 215 202 9 213 211 5 212 218 2 210 226 2 209 232 6 206 238 11 204 243 17 201 247 23 199 250 29 195 252 36 192 253 42 189 253 49 185 253 56 181 251 64 177 249 71 172 246 78 168 241 85 163 236 93 158 230 100 153 224 106 148 216 113 142 208 119 137 200 125 131 190 130 125 181 135 119 171 139 113 160 143 106 150 146 100 139 149 93 128 150 87 117 151 80 106 152 73 96 151 67 85 150 60 75 148 53 65 145 46 56 142 39 47 138 32 39 133 25 31 127 18 24 121 11 18 114 4 13 107 2 9 99 9 5 90 16 2 82 22 0 73 29 0 63 36 0 54 42 1 44 49 3 35 55 5 25 61 9 16 68 14 6 74 19 1 79 25 13 85 32 18 91 40 25 96 48 32 101 57 38 106 67 44 111 76 48 116 87 52 120 97 55 125 108 56 129 119 57 133 130 57 136 140 56 140 151 53 143 162 50 146 172 45 149 182 39 151 192 33 153 201 25 155 209 16 157 217 6 159 225 3 160 231 15 161 237 27 162 242 40 162 246 53 162 249 67 162 252 81 162 253 96 162 254 111 161 253 126 160 252 141 159 249 156 157 246 170 155 242 185 153 237 199 151 231 212 148 225 225 146 217 237 143 209 248 139 201 252 136 192 242 132 182 234 128 172 227 124 162 222 120 151 217 115 140 214 111 130 212 106 119 212 101 108 213 95 97 216 90 87 220 84 76 225 79 67 232 73 57 240 67 48 249 61 40 251 54 32 239 48 25 226 42 19 213 35 14 198 28 9 183 22 5 167 15 3 150 8 1 133 1 0 116 5 0 98 12 0 81 19 2 64 26 5 47 33 9 30 40 13 14 47 18 1 54 24 15 61 31 29 67 39 42 74 47 54 81 56 64 88 65 73 94 75 81 101 85 87 107 96 91 113 106 94 120 117 95 126 128 95 131 139 92 137 150 88 143 160 82 148 171 75 154 181 66 159 190 55 164 200 42 168 208 28 173 216 13 177 224 3 181 230 21 185 236 40 189 241 60 193 246 81 196 249 103 199 251 125 202 253 147 204 253 170 207 253 193 209 252 216 211 250 239 212 247 249 214 243 228 215 238 207 216 232 187 216 226 168 216 218 151 216 211 134 216 202 119 216 193 106 215 184 95 214 174 85 213 163 77 212 153 71 210 142 67 208 131 65 206 120 66 203 109 68 201 99 72 198 88 79 194 78 87 191 68 98 187 59 110 184 50 124 180 41 140 175 33 158 171 26 177 166 20 197 161 14 219 156 13 241 151 6 245 146 3 221 140 1 196 135 0 171 129 0 145 123 0 120 117 2 95 111 5 70 104 8 46 98 12 23 91 18 1 85 24 19 78 30 39 71 38 57 64 46 74 57 55 89 50 64 102 44 74 112 37 84 121 30 94 127 23 105 127 23 105 kst-2.0.3/misc/IDL 06 PRISM000644 001750 001750 00000004150 11544160206 015237 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 3 0 0 7 0 0 11 0 0 15 0 0 19 0 0 22 0 0 26 0 0 30 0 0 34 0 0 38 0 0 41 0 0 45 0 0 49 0 0 53 0 0 57 0 0 60 0 0 64 0 0 68 0 0 72 0 0 76 0 0 79 0 0 83 0 0 87 0 0 91 0 0 95 0 0 98 0 0 102 0 0 106 0 0 110 0 0 114 0 0 117 0 0 121 0 0 125 0 0 129 0 0 133 0 0 137 0 0 140 0 0 144 0 0 148 0 0 152 0 0 156 0 0 159 0 0 163 0 0 167 0 0 171 0 0 175 0 0 178 0 0 182 0 0 186 0 0 190 0 0 194 0 0 197 0 0 201 0 0 205 0 0 209 0 0 213 0 0 216 0 0 220 0 0 224 0 0 228 0 0 232 0 0 235 0 0 239 0 0 243 0 0 247 3 0 251 7 0 255 11 0 251 15 0 247 19 0 243 23 0 239 27 0 235 31 0 230 35 0 226 39 0 222 43 0 218 47 0 214 51 0 210 55 0 205 59 0 201 63 0 197 67 0 193 71 0 189 75 0 184 79 0 180 83 0 176 87 0 172 91 0 168 95 0 164 99 0 159 103 0 155 107 0 151 111 0 147 115 0 143 119 0 138 123 0 134 127 0 130 131 0 126 135 0 122 139 0 118 143 0 113 147 0 109 151 0 105 155 0 101 159 0 97 163 0 92 167 0 88 171 0 84 175 0 80 179 0 76 183 0 72 187 0 67 191 0 63 195 0 59 199 0 55 203 0 51 207 0 46 211 0 42 215 0 38 219 0 34 223 0 30 227 0 26 231 0 21 235 0 17 239 0 13 243 0 9 247 0 5 251 3 0 255 7 0 251 11 0 247 15 0 243 19 0 239 23 0 235 27 0 231 30 0 227 34 0 223 38 0 219 42 0 215 46 0 211 50 0 207 54 0 203 57 0 199 61 0 195 65 0 191 69 0 187 73 0 183 77 0 179 81 0 175 85 0 170 88 0 166 92 0 162 96 0 158 100 0 154 104 0 150 108 0 146 112 0 142 115 0 138 119 0 134 123 0 130 127 0 126 131 0 122 135 0 118 139 0 114 142 0 110 146 0 106 150 0 102 154 0 98 158 0 94 162 0 90 166 0 85 170 0 81 173 0 77 177 0 73 181 0 69 185 0 65 189 0 61 193 0 57 197 0 53 200 0 49 204 0 45 208 0 41 212 0 37 216 0 33 220 0 29 224 0 25 227 0 21 231 0 17 235 0 13 239 0 9 243 0 5 247 0 0 251 0 0 255 0 0 251 0 0 247 0 0 243 0 0 239 0 0 235 0 0 231 0 0 227 0 0 223 0 0 219 0 0 215 0 0 211 0 0 207 0 0 203 0 0 199 0 0 195 0 0 191 0 0 187 0 0 183 0 0 179 0 0 175 0 0 170 0 0 166 0 0 162 0 0 158 0 0 154 0 0 150 0 0 146 0 0 142 0 0 138 0 0 134 0 0 130 0 0 126 0 0 122 0 0 118 0 0 114 0 0 110 0 0 106 0 0 102 0 0 98 0 0 94 0 0 90 0 0 85 0 0 81 0 0 77 0 0 73 0 0 69 0 0 65 0 0 61 0 0 57 0 0 53 0 0 49 0 0 45 0 0 41 0 0 37 0 0 33 0 0 29 0 0 25 0 0 21 0 0 17 0 0 13 0 0 9 0 0 5 0 0 0 kst-2.0.3/misc/IDL 14 STEPS000644 001750 001750 00000004140 11544160206 015241 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 42 0 0 85 0 0 127 0 0 170 0 0 212 0 0 255 0 0 246 0 0 236 0 0 226 0 0 216 0 0 206 0 0 197 0 0 187 0 0 177 0 0 167 0 0 157 0 0 148 0 0 138 0 0 128 0 0 118 0 0 108 0 0 99 0 0 89 0 0 79 0 0 69 0 0 59 0 0 50 0 0 40 0 0 30 0 0 20 0 0 10 0 0 0 0 0 0 8 0 0 16 0 0 24 0 0 32 0 0 41 0 0 49 0 0 57 0 0 65 0 0 74 0 0 82 0 0 90 0 0 98 0 0 106 0 0 115 0 0 123 0 0 131 0 0 139 0 0 148 0 0 156 0 0 164 0 0 172 0 0 180 0 0 189 0 0 197 0 0 205 0 0 213 0 0 222 0 0 230 0 0 238 0 0 246 0 0 255 0 0 0 7 0 5 15 0 10 23 0 15 31 0 21 39 0 26 47 0 31 55 0 37 63 0 42 70 0 47 78 0 53 86 0 58 94 0 63 102 0 69 110 0 74 118 0 79 126 0 85 134 0 89 142 0 94 151 0 98 159 0 103 168 0 108 176 0 112 184 0 117 193 0 121 201 0 126 210 0 131 218 0 135 226 0 140 235 0 144 243 0 149 252 0 154 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 0 0 12 0 0 14 0 0 16 0 0 18 0 0 20 0 0 23 0 0 25 0 0 27 0 0 29 0 0 32 0 0 34 0 0 36 0 0 38 0 0 41 0 0 44 0 0 47 0 0 50 0 0 53 0 0 56 0 0 59 0 0 63 0 0 66 0 0 69 0 0 72 0 0 75 0 0 78 0 0 82 0 1 85 0 1 89 0 1 93 0 1 97 0 1 101 0 1 105 0 1 108 0 1 112 0 1 116 0 1 120 0 1 124 0 1 128 1 1 131 1 1 135 1 1 139 1 1 143 1 1 147 1 1 151 1 1 155 1 1 159 1 1 163 1 1 167 1 1 171 1 1 175 1 1 178 1 1 181 1 1 185 1 1 188 1 1 192 1 1 195 1 1 198 1 1 202 1 1 205 1 1 209 1 1 212 1 1 216 1 2 218 1 2 220 1 2 223 1 2 225 1 2 227 1 2 230 1 2 232 1 2 234 1 2 237 1 2 239 1 2 241 1 2 244 2 2 244 2 2 245 2 2 246 2 2 247 2 2 247 2 2 248 2 2 249 2 2 250 2 2 250 2 2 251 2 2 252 2 2 253 2 2 254 1 2 254 1 2 254 3 2 254 5 2 254 8 2 254 10 2 254 12 2 254 15 2 254 17 2 254 19 2 254 22 2 254 24 2 254 26 2 254 29 2 254 31 2 254 33 2 254 36 2 254 36 2 254 38 3 254 40 4 254 42 5 255 45 7 255 48 9 255 51 12 255 54 14 255 58 17 255 61 20 255 64 23 255 67 27 255 70 30 255 73 34 255 77 39 255 82 44 255 87 49 255 92 55 255 96 60 255 100 65 255 104 71 255 108 76 255 113 82 255 119 89 255 125 97 255 131 104 255 138 112 255 144 120 255 151 128 255 157 136 255 164 145 255 171 153 255 178 162 255 185 171 255 193 180 255 200 189 255 208 198 255 215 207 255 223 217 255 229 224 255 235 232 255 242 239 255 248 247 255 255 255 kst-2.0.3/misc/IDL 02 GRN-RED-BLU-WHT000644 001750 001750 00000004642 11544160206 016465 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 36 0 0 72 0 0 75 0 0 79 0 0 82 0 0 86 0 0 90 0 0 93 0 0 97 0 0 100 0 0 104 0 0 108 0 0 117 0 0 126 0 0 135 0 0 144 0 0 153 0 0 162 0 0 171 0 0 180 0 0 189 0 0 198 0 0 207 0 0 216 0 0 225 0 0 234 0 0 243 0 0 252 0 6 249 0 12 246 0 18 243 0 24 240 0 30 234 0 36 228 0 42 222 0 48 216 0 54 210 0 60 204 0 66 198 0 72 192 0 78 186 0 84 180 0 90 174 0 96 168 0 102 162 0 108 156 0 114 150 0 120 144 0 126 138 0 132 132 0 138 126 0 144 120 0 150 114 0 156 108 0 162 102 0 168 96 0 174 90 0 180 84 0 186 78 0 192 72 0 198 66 0 204 60 0 210 54 0 216 48 0 222 42 0 228 36 0 234 30 0 240 24 0 243 18 0 246 12 0 249 6 0 252 0 0 252 0 0 252 0 0 252 0 0 252 0 1 251 0 3 250 0 5 249 0 7 248 0 9 248 0 10 248 0 12 248 0 14 248 0 16 247 0 18 246 0 20 245 0 22 244 0 25 243 0 27 242 0 29 241 0 31 240 0 34 240 0 35 239 0 37 238 0 39 237 0 41 236 0 43 236 0 45 236 0 47 236 0 50 235 0 52 234 0 54 233 0 56 232 0 59 231 0 61 230 0 63 229 0 65 228 0 67 228 0 68 228 0 70 228 0 72 228 0 74 227 0 76 226 0 78 225 0 80 224 0 83 223 0 85 222 0 87 221 0 89 220 1 92 219 1 94 218 1 96 217 1 98 216 0 101 216 0 102 216 0 104 216 0 106 216 0 108 215 0 110 214 0 112 213 0 114 212 0 116 211 0 118 210 0 120 209 0 122 208 0 125 207 0 127 206 0 129 205 0 131 204 0 134 204 0 135 204 0 137 204 0 139 204 0 141 203 0 143 202 0 145 201 0 147 200 0 150 199 0 152 198 0 154 197 0 156 196 0 159 196 0 160 196 0 162 196 0 163 196 0 165 195 0 167 194 0 169 193 0 171 192 0 174 191 0 176 190 0 178 189 0 180 188 0 183 187 0 185 186 0 187 185 0 189 184 0 192 184 0 193 184 0 195 184 0 197 184 0 199 183 0 201 182 0 203 181 0 205 180 0 208 179 0 210 178 0 212 177 0 214 176 0 216 176 0 217 176 0 219 176 0 221 176 0 223 175 0 225 174 0 227 173 0 229 172 0 232 171 0 234 170 0 236 169 0 238 168 0 241 167 0 243 166 0 245 165 0 247 164 0 250 164 0 251 164 0 252 164 0 253 164 0 255 163 0 255 162 0 255 161 0 255 160 0 255 159 0 255 158 0 255 157 0 255 156 0 255 155 0 255 154 0 255 153 0 255 152 0 255 152 0 255 152 0 255 152 0 255 152 0 255 151 0 255 150 0 255 149 0 255 148 0 255 151 8 255 154 16 255 157 24 255 160 32 255 163 40 255 166 48 255 169 56 255 172 64 255 176 72 255 180 80 255 184 88 255 188 96 255 191 104 255 194 112 255 197 120 255 200 128 255 203 135 255 206 142 255 209 149 255 212 156 255 215 164 255 218 172 255 221 180 255 224 188 255 228 196 255 232 204 255 236 212 255 240 220 255 243 228 255 246 236 255 249 244 255 252 252 255 253 253 255 254 254 255 255 255 255 kst-2.0.3/misc/cfitsio-windows/CMakeLists.txt000644 001750 001750 00000004273 11544160206 021521 0ustar00synthsynth000000 000000 cmake_minimum_required(VERSION 2.6.4) project( cfit ) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) if(NOT CFIT_DIR) set(CFIT_DIR ${CMAKE_SOURCE_DIR}) endif() set(cfit_sources ${CFIT_DIR}/buffers.c ${CFIT_DIR}/cfileio.c ${CFIT_DIR}/checksum.c ${CFIT_DIR}/compress.c ${CFIT_DIR}/drvrfile.c ${CFIT_DIR}/drvrmem.c ${CFIT_DIR}/editcol.c ${CFIT_DIR}/edithdu.c ${CFIT_DIR}/eval_f.c ${CFIT_DIR}/eval_l.c ${CFIT_DIR}/eval_y.c ${CFIT_DIR}/f77_wrap1.c ${CFIT_DIR}/f77_wrap2.c ${CFIT_DIR}/f77_wrap3.c ${CFIT_DIR}/f77_wrap4.c ${CFIT_DIR}/fitscore.c ${CFIT_DIR}/getcol.c ${CFIT_DIR}/getcolb.c ${CFIT_DIR}/getcold.c ${CFIT_DIR}/getcole.c ${CFIT_DIR}/getcoli.c ${CFIT_DIR}/getcolj.c ${CFIT_DIR}/getcolk.c ${CFIT_DIR}/getcoll.c ${CFIT_DIR}/getcols.c ${CFIT_DIR}/getcolsb.c ${CFIT_DIR}/getcolui.c ${CFIT_DIR}/getcoluj.c ${CFIT_DIR}/getcoluk.c ${CFIT_DIR}/getkey.c ${CFIT_DIR}/group.c ${CFIT_DIR}/grparser.c ${CFIT_DIR}/histo.c ${CFIT_DIR}/iraffits.c ${CFIT_DIR}/modkey.c ${CFIT_DIR}/putcol.c ${CFIT_DIR}/putcolb.c ${CFIT_DIR}/putcold.c ${CFIT_DIR}/putcole.c ${CFIT_DIR}/putcoli.c ${CFIT_DIR}/putcolj.c ${CFIT_DIR}/putcolk.c ${CFIT_DIR}/putcoll.c ${CFIT_DIR}/putcols.c ${CFIT_DIR}/putcolsb.c ${CFIT_DIR}/putcolu.c ${CFIT_DIR}/putcolui.c ${CFIT_DIR}/putcoluj.c ${CFIT_DIR}/putcoluk.c ${CFIT_DIR}/putkey.c ${CFIT_DIR}/region.c ${CFIT_DIR}/scalnull.c ${CFIT_DIR}/swapproc.c ${CFIT_DIR}/wcssub.c ${CFIT_DIR}/wcsutil.c ${CFIT_DIR}/fits_hcompress.c ${CFIT_DIR}/fits_hdecompress.c ${CFIT_DIR}/imcompress.c ${CFIT_DIR}/pliocomp.c ${CFIT_DIR}/quantize.c ${CFIT_DIR}/ricecomp.c ) file(GLOB cfit_headers ${CFIT_DIR}/*.h) if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) set(CMAKE_DEBUG_POSTFIX d) endif() include_directories( ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) add_library(cfitsio STATIC ${cfit_sources} ${cfit_headers}) if (NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/INSTALLED) endif() install(FILES ${cfit_headers} DESTINATION include/cfitsio) install(TARGETS cfitsio DESTINATION lib) kst-2.0.3/misc/IDL 07 RED-PURPLE000644 001750 001750 00000005001 11544160206 015761 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 0 0 3 0 0 6 0 0 10 0 0 13 0 0 17 0 0 20 0 0 24 0 1 27 0 1 30 0 1 33 0 1 36 0 2 39 0 2 42 0 2 45 0 2 48 0 2 51 0 2 54 0 2 57 0 2 60 0 3 63 0 3 66 0 3 69 0 3 72 0 4 75 0 4 78 0 4 81 0 4 84 0 4 85 0 5 86 0 6 87 0 7 88 0 9 90 0 9 92 0 10 94 0 11 96 0 12 97 0 13 98 0 14 99 0 15 100 0 17 102 0 17 104 0 18 106 0 18 108 0 19 109 0 20 110 0 22 111 0 23 112 0 25 114 0 25 116 0 26 118 0 26 120 0 27 121 0 28 122 0 29 123 0 30 124 0 32 126 0 32 128 0 33 130 0 33 132 0 34 133 0 35 134 0 36 135 0 37 136 0 39 138 1 39 140 2 40 142 3 40 144 4 41 145 4 42 146 4 43 147 4 44 148 4 46 150 4 46 152 4 47 154 4 48 156 4 49 157 4 50 158 4 51 159 4 52 160 4 54 162 5 54 164 6 53 166 7 53 168 8 52 169 8 54 170 8 56 171 8 58 172 8 60 174 8 60 176 8 61 178 8 62 180 8 63 181 8 64 182 8 65 183 8 66 184 8 68 185 8 69 186 8 70 187 8 71 188 8 73 189 8 74 190 8 75 191 8 76 192 8 77 193 8 78 194 8 79 195 8 80 196 8 82 198 9 82 200 10 83 202 11 83 204 12 84 205 12 85 206 12 86 207 12 87 208 12 89 209 12 90 210 12 91 211 12 92 212 12 94 213 12 95 214 12 96 215 12 97 216 12 98 217 12 99 218 12 100 219 12 101 220 12 103 222 12 103 224 12 104 226 12 105 228 12 106 229 13 107 230 14 108 231 15 109 232 16 110 233 16 111 234 16 112 235 16 113 236 16 115 237 16 116 238 16 117 239 16 118 240 16 119 241 16 120 242 16 121 243 16 122 244 16 124 246 16 124 248 16 125 250 16 125 252 16 126 252 17 127 252 18 129 252 19 131 252 20 133 252 20 134 252 20 136 252 20 138 252 20 140 252 21 141 252 22 143 252 23 144 252 24 146 252 24 147 252 24 149 252 24 151 252 24 153 252 25 154 252 26 156 252 27 157 252 28 159 252 30 160 252 32 161 252 34 162 252 36 164 252 38 165 252 40 166 252 42 167 252 44 169 252 46 170 252 48 172 252 50 173 252 52 175 252 54 176 252 56 177 252 58 178 252 60 180 252 61 181 252 62 183 252 63 184 252 64 186 252 66 187 252 68 188 252 70 189 252 72 191 252 74 192 252 76 193 252 78 194 252 80 196 252 82 197 252 84 199 252 86 200 252 88 202 252 90 203 252 92 204 252 94 205 252 96 207 252 98 208 252 100 209 252 102 210 252 104 212 252 107 213 252 110 214 252 113 215 252 116 217 252 119 218 252 122 219 252 125 220 252 128 221 252 131 222 252 134 223 252 137 224 252 140 226 252 143 227 252 146 228 252 149 229 252 152 230 252 155 231 252 158 232 252 161 233 252 164 235 252 167 236 252 170 237 252 173 238 252 176 239 252 180 240 252 184 241 252 188 242 252 192 243 252 197 243 252 202 244 252 207 245 252 212 246 252 217 246 252 222 247 252 227 248 252 232 249 252 237 249 252 242 250 252 247 251 252 252 252 252 252 252 253 253 253 254 254 254 kst-2.0.3/misc/IDL 08 GRN-WHT-Linear000644 001750 001750 00000004415 11544160206 016651 0ustar00synthsynth000000 000000 GIMP Palette 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 0 0 12 0 0 13 0 0 14 0 0 15 0 0 16 0 0 17 0 0 18 0 0 19 0 0 20 0 0 21 0 0 22 0 0 23 0 0 24 0 0 25 0 0 26 0 0 27 0 0 28 0 0 29 0 0 30 0 0 31 0 0 32 0 0 33 0 0 34 0 0 35 0 0 36 0 0 37 0 0 38 0 0 39 0 0 40 0 0 41 0 0 42 0 0 43 0 0 44 0 0 45 0 0 46 0 0 47 0 0 48 0 0 49 0 0 50 0 0 51 0 0 52 0 0 53 0 0 54 0 0 55 0 0 56 0 0 57 0 0 58 0 0 59 0 0 60 0 0 61 0 0 62 0 0 63 0 0 64 0 0 65 0 0 66 0 0 67 0 0 68 0 0 69 0 0 70 0 0 71 0 0 72 0 0 73 0 0 74 0 0 75 0 0 76 0 0 77 0 0 78 0 0 79 0 0 80 0 0 81 0 0 82 0 0 83 0 0 84 0 0 85 0 0 86 0 0 87 0 0 88 0 0 89 0 0 90 0 0 91 0 0 92 0 0 93 0 0 94 0 0 95 0 0 96 0 0 97 0 1 98 0 3 99 0 4 100 0 6 101 0 8 102 0 9 103 0 11 104 0 12 105 0 14 106 0 16 107 0 17 108 0 19 109 0 20 110 0 22 111 0 24 112 0 25 113 0 27 114 0 29 115 0 30 116 0 32 117 0 33 118 0 35 119 0 37 120 0 38 121 0 40 122 0 41 123 0 43 124 0 45 125 0 46 126 0 48 127 0 50 128 0 51 129 0 53 130 0 54 131 0 56 132 0 58 133 0 59 134 0 61 135 0 62 136 0 64 137 0 66 138 0 67 139 0 69 140 0 71 141 0 72 142 0 74 143 0 75 144 0 77 145 0 79 146 0 80 147 0 82 148 0 83 149 0 85 150 0 87 151 0 88 152 0 90 153 0 91 154 0 93 155 0 95 156 0 96 157 0 98 158 0 100 159 0 101 160 0 103 161 0 104 162 0 106 163 0 108 164 0 109 165 0 111 166 0 112 167 0 114 168 0 116 169 0 117 170 0 119 171 0 121 172 0 122 173 0 124 174 0 125 175 0 127 176 0 129 177 0 130 178 0 132 179 0 133 180 0 135 181 0 137 182 3 138 183 6 140 184 10 142 185 13 143 186 17 145 187 20 146 188 24 148 189 27 150 190 31 151 191 34 153 192 37 154 193 41 156 194 44 158 195 48 159 196 51 161 197 55 163 198 58 164 199 62 166 200 65 167 201 68 169 202 72 171 203 75 172 204 79 174 205 82 175 206 86 177 207 89 179 208 93 180 209 96 182 210 99 183 211 103 185 212 106 187 213 110 188 214 113 190 215 117 192 216 120 193 217 124 195 218 127 196 219 130 198 220 134 200 221 137 201 222 141 203 223 144 204 224 148 206 225 151 208 226 155 209 227 158 211 228 161 213 229 165 214 230 168 216 231 172 217 232 175 219 233 179 221 234 182 222 235 186 224 236 189 225 237 192 227 238 196 229 239 199 230 240 203 232 241 206 234 242 210 235 243 213 237 244 217 238 245 220 240 246 223 242 247 227 243 248 230 245 249 234 246 250 237 248 251 241 250 252 244 251 253 248 253 254 251 255 255 255 kst-2.0.3/misc/IDL 38 Rainbow18000644 001750 001750 00000005175 11544160206 016134 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 150 0 150 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 150 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 200 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 100 100 255 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 0 140 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 150 170 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 200 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 150 200 0 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 200 255 120 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 200 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 160 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 255 125 0 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 200 50 100 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 175 50 75 255 255 255 255 255 255 kst-2.0.3/misc/IDL 30 Ocean000644 001750 001750 00000005314 11544160206 015372 0ustar00synthsynth000000 000000 GIMP Palette 54 67 141 54 67 141 59 67 153 63 67 165 68 67 177 73 67 189 77 67 202 82 66 214 82 66 214 87 66 227 91 65 239 96 64 251 100 64 246 105 63 234 110 62 222 114 61 210 119 60 198 123 59 186 127 57 175 131 56 164 135 55 153 139 54 142 143 53 132 143 53 132 147 52 122 150 51 113 154 49 104 157 48 95 160 47 87 163 47 79 165 46 72 168 45 66 170 44 59 172 44 54 174 44 49 176 43 44 177 43 40 177 43 40 179 43 37 180 43 34 180 44 32 181 44 31 181 45 30 182 46 29 181 47 30 181 48 31 180 50 32 180 51 34 179 53 37 177 55 40 176 57 44 174 60 49 174 60 49 172 62 54 170 65 59 168 68 66 165 71 72 163 74 79 160 78 87 157 81 95 154 85 104 150 88 113 147 92 122 143 96 132 139 100 142 135 104 153 131 108 164 131 108 164 127 112 175 123 116 186 119 120 198 114 124 210 110 128 222 105 132 234 100 136 246 96 140 251 91 144 239 86 148 226 82 151 214 77 154 202 73 158 189 68 161 177 68 161 177 63 164 165 59 166 153 54 169 141 50 171 129 46 173 118 42 175 107 38 176 96 34 178 85 30 179 75 26 180 65 23 180 56 19 180 47 16 180 38 13 180 30 13 180 30 13 179 22 8 179 15 5 178 9 3 176 2 1 175 2 0 173 7 2 171 12 3 169 16 5 166 19 6 164 22 6 161 24 7 158 25 7 155 26 8 152 27 8 152 27 7 148 26 7 145 25 6 141 24 6 138 22 5 134 19 3 131 16 2 127 12 0 124 7 1 120 2 3 117 2 5 113 9 8 110 15 13 107 22 13 104 30 13 104 30 16 101 38 19 99 47 23 97 56 26 95 65 30 93 75 34 91 85 38 90 96 42 89 107 46 88 118 50 88 129 54 88 141 59 88 153 63 88 165 68 89 177 68 89 177 73 91 189 77 92 202 82 94 214 87 96 227 91 99 239 96 102 251 100 105 246 105 109 234 110 113 222 114 117 210 119 122 198 123 127 186 127 132 175 131 137 164 131 137 164 135 142 153 139 148 142 143 154 132 147 160 122 150 166 113 154 173 104 157 179 95 160 186 87 163 192 79 165 199 72 168 205 66 170 212 59 172 218 54 172 218 54 174 225 49 176 231 44 177 237 40 179 243 37 180 248 34 180 254 32 181 251 31 181 246 30 182 241 29 181 237 30 181 233 31 180 229 32 180 226 34 179 223 37 179 223 37 177 220 40 176 218 44 174 216 49 172 215 54 170 214 59 168 213 66 165 213 72 163 214 79 160 214 87 157 216 95 154 217 104 150 219 113 147 222 122 143 224 132 143 224 132 139 228 142 135 231 153 131 235 164 127 239 175 123 244 186 119 248 198 114 253 210 110 251 222 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 0 0 0 255 255 255 255 255 255 kst-2.0.3/misc/IDL 20 Hue-Sat-Light2000644 001750 001750 00000005652 11544160206 016746 0ustar00synthsynth000000 000000 GIMP Palette 253 252 252 253 252 252 251 250 250 250 250 250 250 249 249 249 249 249 249 248 248 248 248 248 248 247 247 247 247 247 247 246 246 246 246 246 246 245 245 246 245 245 245 244 244 245 244 244 244 243 243 244 242 243 244 242 243 243 241 242 243 241 242 242 240 241 242 239 241 242 239 241 241 238 240 241 238 240 240 237 239 240 236 239 240 236 239 239 235 238 239 235 238 239 234 238 238 233 237 238 233 237 238 232 237 237 232 237 237 231 236 236 230 236 236 230 236 236 229 236 235 228 235 235 228 235 235 227 235 235 226 235 234 226 234 233 225 234 233 224 234 232 223 234 232 223 233 231 222 233 231 221 233 230 221 232 229 220 232 229 219 232 228 218 232 227 218 231 226 217 231 226 217 231 225 216 230 224 215 230 223 214 230 223 214 230 222 213 229 221 212 229 220 211 229 219 211 229 218 209 229 217 209 228 216 208 228 215 208 228 214 206 228 213 206 227 212 205 227 211 205 227 210 204 227 208 202 227 207 202 226 206 201 226 205 201 226 204 200 226 202 199 226 200 197 226 199 197 225 198 196 226 196 196 225 195 195 225 194 195 225 192 194 225 192 194 224 191 194 225 191 194 224 190 194 224 189 194 224 188 194 224 187 195 224 185 194 224 185 195 224 184 195 224 183 195 224 183 196 223 182 196 223 181 196 223 180 197 223 179 197 223 178 198 223 177 198 223 176 199 223 175 199 223 174 200 223 173 200 223 172 201 223 172 202 222 171 203 222 170 204 222 169 204 222 168 205 222 167 206 222 166 207 222 165 208 222 165 210 222 164 211 222 163 212 222 162 213 222 161 215 222 160 216 222 159 217 222 158 219 222 157 220 222 156 222 222 155 222 222 154 222 220 153 222 218 152 222 217 151 222 215 149 223 213 148 223 211 147 223 210 146 223 208 145 223 206 144 223 204 143 223 202 142 223 200 140 223 197 139 223 195 138 223 193 138 223 191 137 223 188 136 223 186 135 223 183 134 223 181 132 224 178 131 224 176 130 224 173 129 224 170 128 224 168 127 224 165 126 224 162 125 224 159 124 224 156 122 225 153 121 225 150 120 225 146 119 225 143 118 225 140 118 225 137 116 225 133 114 226 129 113 226 126 112 226 122 111 226 118 111 226 116 109 227 112 108 227 107 109 227 106 111 227 105 114 227 105 115 227 104 117 228 102 118 228 100 120 228 99 123 228 99 125 229 97 127 229 96 129 229 94 131 229 93 134 229 93 137 230 91 139 230 90 141 230 88 144 230 88 147 231 86 150 231 85 152 231 83 155 231 83 158 232 81 161 232 80 164 232 78 167 232 78 171 233 76 174 233 75 177 233 73 181 234 72 184 234 71 188 234 70 192 234 69 195 235 67 199 235 66 203 235 65 207 236 63 211 236 62 216 236 62 220 237 59 224 237 58 228 237 58 233 238 55 237 238 54 238 235 54 239 231 51 239 227 50 240 223 49 240 218 47 240 214 46 241 210 45 241 205 43 241 201 42 242 196 41 242 191 39 243 187 38 243 182 36 243 177 35 244 172 34 244 167 32 245 162 31 245 157 30 245 151 28 246 146 27 246 140 25 247 135 24 247 129 23 247 123 22 248 117 20 248 111 18 249 106 17 249 99 15 250 93 14 250 85 13 251 78 8 251 74 13 252 67 8 252 61 7 253 54 5 253 47 4 254 40 2 254 33 1 254 27 0 254 27 0 kst-2.0.3/misc/mingw-release-download-deps.bat000644 001750 001750 00000000323 11544160206 021606 0ustar00synthsynth000000 000000 cmake ..\kst\cmake -G"MinGW Makefiles" -Dkst_release=1 -Dkst_merge_files=1 -Dkst_3rdparty_download=1 -Dkst_install_prefix=%1 mingw32-make mingw32-make install mingw32-make package mingw32-make package_source kst-2.0.3/misc/Kst Colors000644 001750 001750 00000000103 11544160206 015523 0ustar00synthsynth000000 000000 GIMP Palette 255 0 0 200 200 0 0 255 0 0 230 230 0 0 255 230 0 230 kst-2.0.3/misc/gsl-windows/README.txt000644 001750 001750 00000001604 11544160206 017577 0ustar00synthsynth000000 000000 This folder contains files needed for building GSL on Windows. Build instructions: - Get GSL source code from http://www.gnu.org/software/gsl/ (latest tested release: 1.14, 2010/04) - Copy CMakeLists.txt and config.h to the GSL folder. - Patch GSL with gsl-msvc.patch or gsl-mingw.patch (for MinGW 4.4.0). - Extract GSL sources, eg. c:\gsl-sources - Make a build folder, eg. c:\gsl-build - Build GSL in this folder with CMake (http://www.cmake.org): * cd c:\gsl-build * MSVC : cmake ..\gst-sources -G"Visual Studio 9 2008" MinGW: cmake ..\gst-sources -G"MinGW Makefiles" * MSVC : build and install (build INSTALL project) with Visual Studio MinGW: mingw32-make & mingw32-make install - Set environment variable GSLDIR to 'installed' folder: set GSLDIR=c:\gsl-build\installed - qmake will detect GSL and enables GSL on Windows. TODO: Do real checks for config.h kst-2.0.3/misc/gsl-windows/CMakeLists.txt000644 001750 001750 00000047063 11544160206 020652 0ustar00synthsynth000000 000000 cmake_minimum_required(VERSION 2.6) project( gsl ) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(GSL_DIR ${CMAKE_SOURCE_DIR}) set(gsl_source_list ${GSL_DIR}/version.c ${GSL_DIR}/block/block.c ${GSL_DIR}/block/file.c ${GSL_DIR}/block/init.c ${GSL_DIR}/fft/dft.c ${GSL_DIR}/fft/factorize.c ${GSL_DIR}/fft/fft.c ${GSL_DIR}/fft/signals.c ${GSL_DIR}/min/bracketing.c ${GSL_DIR}/min/brent.c ${GSL_DIR}/min/convergence.c ${GSL_DIR}/min/fsolver.c ${GSL_DIR}/min/golden.c ${GSL_DIR}/min/quad_golden.c ${GSL_DIR}/blas/blas.c ${GSL_DIR}/cdf/beta.c ${GSL_DIR}/cdf/betainv.c ${GSL_DIR}/cdf/binomial.c ${GSL_DIR}/cdf/cauchy.c ${GSL_DIR}/cdf/cauchyinv.c ${GSL_DIR}/cdf/chisq.c ${GSL_DIR}/cdf/chisqinv.c ${GSL_DIR}/cdf/exponential.c ${GSL_DIR}/cdf/exponentialinv.c ${GSL_DIR}/cdf/exppow.c ${GSL_DIR}/cdf/fdist.c ${GSL_DIR}/cdf/fdistinv.c ${GSL_DIR}/cdf/flat.c ${GSL_DIR}/cdf/flatinv.c ${GSL_DIR}/cdf/gamma.c ${GSL_DIR}/cdf/gammainv.c ${GSL_DIR}/cdf/gauss.c ${GSL_DIR}/cdf/gaussinv.c ${GSL_DIR}/cdf/geometric.c ${GSL_DIR}/cdf/gumbel1.c ${GSL_DIR}/cdf/gumbel1inv.c ${GSL_DIR}/cdf/gumbel2.c ${GSL_DIR}/cdf/gumbel2inv.c ${GSL_DIR}/cdf/hypergeometric.c ${GSL_DIR}/cdf/laplace.c ${GSL_DIR}/cdf/laplaceinv.c ${GSL_DIR}/cdf/logistic.c ${GSL_DIR}/cdf/logisticinv.c ${GSL_DIR}/cdf/lognormal.c ${GSL_DIR}/cdf/lognormalinv.c ${GSL_DIR}/cdf/nbinomial.c ${GSL_DIR}/cdf/pareto.c ${GSL_DIR}/cdf/paretoinv.c ${GSL_DIR}/cdf/pascal.c ${GSL_DIR}/cdf/poisson.c ${GSL_DIR}/cdf/rayleigh.c ${GSL_DIR}/cdf/rayleighinv.c ${GSL_DIR}/cdf/tdist.c ${GSL_DIR}/cdf/tdistinv.c ${GSL_DIR}/cdf/weibull.c ${GSL_DIR}/cdf/weibullinv.c ${GSL_DIR}/cheb/deriv.c ${GSL_DIR}/cheb/eval.c ${GSL_DIR}/cheb/init.c ${GSL_DIR}/cheb/integ.c ${GSL_DIR}/combination/combination.c ${GSL_DIR}/combination/file.c ${GSL_DIR}/combination/init.c ${GSL_DIR}/complex/math.c ${GSL_DIR}/deriv/deriv.c ${GSL_DIR}/dht/dht.c ${GSL_DIR}/diff/diff.c ${GSL_DIR}/eigen/francis.c ${GSL_DIR}/eigen/gen.c ${GSL_DIR}/eigen/genherm.c ${GSL_DIR}/eigen/genhermv.c ${GSL_DIR}/eigen/gensymm.c ${GSL_DIR}/eigen/gensymmv.c ${GSL_DIR}/eigen/genv.c ${GSL_DIR}/eigen/herm.c ${GSL_DIR}/eigen/hermv.c ${GSL_DIR}/eigen/jacobi.c ${GSL_DIR}/eigen/nonsymm.c ${GSL_DIR}/eigen/nonsymmv.c ${GSL_DIR}/eigen/schur.c ${GSL_DIR}/eigen/sort.c ${GSL_DIR}/eigen/symm.c ${GSL_DIR}/eigen/symmv.c ${GSL_DIR}/err/error.c ${GSL_DIR}/err/message.c ${GSL_DIR}/err/stream.c ${GSL_DIR}/err/strerror.c ${GSL_DIR}/fit/linear.c ${GSL_DIR}/histogram/add.c ${GSL_DIR}/histogram/add2d.c ${GSL_DIR}/histogram/calloc_range.c ${GSL_DIR}/histogram/calloc_range2d.c ${GSL_DIR}/histogram/copy.c ${GSL_DIR}/histogram/copy2d.c ${GSL_DIR}/histogram/file.c ${GSL_DIR}/histogram/file2d.c ${GSL_DIR}/histogram/get.c ${GSL_DIR}/histogram/get2d.c ${GSL_DIR}/histogram/init.c ${GSL_DIR}/histogram/init2d.c ${GSL_DIR}/histogram/maxval.c ${GSL_DIR}/histogram/maxval2d.c ${GSL_DIR}/histogram/oper.c ${GSL_DIR}/histogram/oper2d.c ${GSL_DIR}/histogram/params.c ${GSL_DIR}/histogram/params2d.c ${GSL_DIR}/histogram/pdf.c ${GSL_DIR}/histogram/pdf2d.c ${GSL_DIR}/histogram/reset.c ${GSL_DIR}/histogram/reset2d.c ${GSL_DIR}/histogram/stat.c ${GSL_DIR}/histogram/stat2d.c ${GSL_DIR}/ieee-utils/endian.c ${GSL_DIR}/ieee-utils/env.c ${GSL_DIR}/ieee-utils/fp.c ${GSL_DIR}/ieee-utils/make_rep.c ${GSL_DIR}/ieee-utils/print.c ${GSL_DIR}/ieee-utils/read.c ${GSL_DIR}/ieee-utils/standardize.c ${GSL_DIR}/integration/qag.c ${GSL_DIR}/integration/qagp.c ${GSL_DIR}/integration/qags.c ${GSL_DIR}/integration/qawc.c ${GSL_DIR}/integration/qawf.c ${GSL_DIR}/integration/qawo.c ${GSL_DIR}/integration/qaws.c ${GSL_DIR}/integration/qcheb.c ${GSL_DIR}/integration/qk.c ${GSL_DIR}/integration/qk15.c ${GSL_DIR}/integration/qk21.c ${GSL_DIR}/integration/qk31.c ${GSL_DIR}/integration/qk41.c ${GSL_DIR}/integration/qk51.c ${GSL_DIR}/integration/qk61.c ${GSL_DIR}/integration/qmomo.c ${GSL_DIR}/integration/qmomof.c ${GSL_DIR}/integration/qng.c ${GSL_DIR}/integration/workspace.c ${GSL_DIR}/interpolation/accel.c ${GSL_DIR}/interpolation/akima.c ${GSL_DIR}/interpolation/cspline.c ${GSL_DIR}/interpolation/interp.c ${GSL_DIR}/interpolation/linear.c ${GSL_DIR}/interpolation/poly.c ${GSL_DIR}/interpolation/spline.c ${GSL_DIR}/linalg/balance.c ${GSL_DIR}/linalg/balancemat.c ${GSL_DIR}/linalg/bidiag.c ${GSL_DIR}/linalg/cholesky.c ${GSL_DIR}/linalg/choleskyc.c ${GSL_DIR}/linalg/exponential.c ${GSL_DIR}/linalg/hermtd.c ${GSL_DIR}/linalg/hessenberg.c ${GSL_DIR}/linalg/hesstri.c ${GSL_DIR}/linalg/hh.c ${GSL_DIR}/linalg/householder.c ${GSL_DIR}/linalg/householdercomplex.c ${GSL_DIR}/linalg/lq.c ${GSL_DIR}/linalg/lu.c ${GSL_DIR}/linalg/luc.c ${GSL_DIR}/linalg/multiply.c ${GSL_DIR}/linalg/ptlq.c ${GSL_DIR}/linalg/qr.c ${GSL_DIR}/linalg/qrpt.c ${GSL_DIR}/linalg/svd.c ${GSL_DIR}/linalg/symmtd.c ${GSL_DIR}/linalg/tridiag.c ${GSL_DIR}/matrix/copy.c ${GSL_DIR}/matrix/file.c ${GSL_DIR}/matrix/getset.c ${GSL_DIR}/matrix/init.c ${GSL_DIR}/matrix/matrix.c ${GSL_DIR}/matrix/minmax.c ${GSL_DIR}/matrix/oper.c ${GSL_DIR}/matrix/prop.c ${GSL_DIR}/matrix/rowcol.c ${GSL_DIR}/matrix/submatrix.c ${GSL_DIR}/matrix/swap.c ${GSL_DIR}/matrix/view.c ${GSL_DIR}/monte/miser.c ${GSL_DIR}/monte/plain.c ${GSL_DIR}/monte/vegas.c ${GSL_DIR}/multifit/convergence.c ${GSL_DIR}/multifit/covar.c ${GSL_DIR}/multifit/fdfsolver.c ${GSL_DIR}/multifit/fsolver.c ${GSL_DIR}/multifit/gradient.c ${GSL_DIR}/multifit/lmder.c ${GSL_DIR}/multifit/multilinear.c ${GSL_DIR}/multifit/work.c ${GSL_DIR}/multimin/conjugate_fr.c ${GSL_DIR}/multimin/conjugate_pr.c ${GSL_DIR}/multimin/convergence.c ${GSL_DIR}/multimin/diff.c ${GSL_DIR}/multimin/fdfminimizer.c ${GSL_DIR}/multimin/fminimizer.c ${GSL_DIR}/multimin/simplex.c ${GSL_DIR}/multimin/simplex2.c ${GSL_DIR}/multimin/steepest_descent.c ${GSL_DIR}/multimin/vector_bfgs.c ${GSL_DIR}/multimin/vector_bfgs2.c ${GSL_DIR}/multiroots/broyden.c ${GSL_DIR}/multiroots/convergence.c ${GSL_DIR}/multiroots/dnewton.c ${GSL_DIR}/multiroots/fdfsolver.c ${GSL_DIR}/multiroots/fdjac.c ${GSL_DIR}/multiroots/fsolver.c ${GSL_DIR}/multiroots/gnewton.c ${GSL_DIR}/multiroots/hybrid.c ${GSL_DIR}/multiroots/hybridj.c ${GSL_DIR}/multiroots/newton.c ${GSL_DIR}/ntuple/ntuple.c ${GSL_DIR}/ode-initval/bsimp.c ${GSL_DIR}/ode-initval/control.c ${GSL_DIR}/ode-initval/cscal.c ${GSL_DIR}/ode-initval/cstd.c ${GSL_DIR}/ode-initval/evolve.c ${GSL_DIR}/ode-initval/gear1.c ${GSL_DIR}/ode-initval/gear2.c ${GSL_DIR}/ode-initval/rk2.c ${GSL_DIR}/ode-initval/rk2imp.c ${GSL_DIR}/ode-initval/rk2simp.c ${GSL_DIR}/ode-initval/rk4.c ${GSL_DIR}/ode-initval/rk4imp.c ${GSL_DIR}/ode-initval/rk8pd.c ${GSL_DIR}/ode-initval/rkck.c ${GSL_DIR}/ode-initval/rkf45.c ${GSL_DIR}/ode-initval/step.c ${GSL_DIR}/permutation/canonical.c ${GSL_DIR}/permutation/file.c ${GSL_DIR}/permutation/init.c ${GSL_DIR}/permutation/permutation.c ${GSL_DIR}/permutation/permute.c ${GSL_DIR}/poly/dd.c ${GSL_DIR}/poly/deriv.c ${GSL_DIR}/poly/eval.c ${GSL_DIR}/poly/solve_cubic.c ${GSL_DIR}/poly/solve_quadratic.c ${GSL_DIR}/poly/zsolve.c ${GSL_DIR}/poly/zsolve_cubic.c ${GSL_DIR}/poly/zsolve_init.c ${GSL_DIR}/poly/zsolve_quadratic.c ${GSL_DIR}/qrng/halton.c ${GSL_DIR}/qrng/niederreiter-2.c ${GSL_DIR}/qrng/qrng.c ${GSL_DIR}/qrng/reversehalton.c ${GSL_DIR}/qrng/sobol.c ${GSL_DIR}/randist/bernoulli.c ${GSL_DIR}/randist/beta.c ${GSL_DIR}/randist/bigauss.c ${GSL_DIR}/randist/binomial.c ${GSL_DIR}/randist/binomial_tpe.c ${GSL_DIR}/randist/cauchy.c ${GSL_DIR}/randist/chisq.c ${GSL_DIR}/randist/dirichlet.c ${GSL_DIR}/randist/discrete.c ${GSL_DIR}/randist/erlang.c ${GSL_DIR}/randist/exponential.c ${GSL_DIR}/randist/exppow.c ${GSL_DIR}/randist/fdist.c ${GSL_DIR}/randist/flat.c ${GSL_DIR}/randist/gamma.c ${GSL_DIR}/randist/gauss.c ${GSL_DIR}/randist/gausstail.c ${GSL_DIR}/randist/gausszig.c ${GSL_DIR}/randist/geometric.c ${GSL_DIR}/randist/gumbel.c ${GSL_DIR}/randist/hyperg.c ${GSL_DIR}/randist/landau.c ${GSL_DIR}/randist/laplace.c ${GSL_DIR}/randist/levy.c ${GSL_DIR}/randist/logarithmic.c ${GSL_DIR}/randist/logistic.c ${GSL_DIR}/randist/lognormal.c ${GSL_DIR}/randist/multinomial.c ${GSL_DIR}/randist/nbinomial.c ${GSL_DIR}/randist/pareto.c ${GSL_DIR}/randist/pascal.c ${GSL_DIR}/randist/poisson.c ${GSL_DIR}/randist/rayleigh.c ${GSL_DIR}/randist/shuffle.c ${GSL_DIR}/randist/sphere.c ${GSL_DIR}/randist/tdist.c ${GSL_DIR}/randist/weibull.c ${GSL_DIR}/rng/borosh13.c ${GSL_DIR}/rng/cmrg.c ${GSL_DIR}/rng/coveyou.c ${GSL_DIR}/rng/default.c ${GSL_DIR}/rng/file.c ${GSL_DIR}/rng/fishman18.c ${GSL_DIR}/rng/fishman20.c ${GSL_DIR}/rng/fishman2x.c ${GSL_DIR}/rng/gfsr4.c ${GSL_DIR}/rng/knuthran.c ${GSL_DIR}/rng/knuthran2.c ${GSL_DIR}/rng/knuthran2002.c ${GSL_DIR}/rng/lecuyer21.c ${GSL_DIR}/rng/minstd.c ${GSL_DIR}/rng/mrg.c ${GSL_DIR}/rng/mt.c ${GSL_DIR}/rng/r250.c ${GSL_DIR}/rng/ran0.c ${GSL_DIR}/rng/ran1.c ${GSL_DIR}/rng/ran2.c ${GSL_DIR}/rng/ran3.c ${GSL_DIR}/rng/rand.c ${GSL_DIR}/rng/rand48.c ${GSL_DIR}/rng/random.c ${GSL_DIR}/rng/randu.c ${GSL_DIR}/rng/ranf.c ${GSL_DIR}/rng/ranlux.c ${GSL_DIR}/rng/ranlxd.c ${GSL_DIR}/rng/ranlxs.c ${GSL_DIR}/rng/ranmar.c ${GSL_DIR}/rng/rng.c ${GSL_DIR}/rng/slatec.c ${GSL_DIR}/rng/taus.c ${GSL_DIR}/rng/taus113.c ${GSL_DIR}/rng/transputer.c ${GSL_DIR}/rng/tt.c ${GSL_DIR}/rng/types.c ${GSL_DIR}/rng/uni.c ${GSL_DIR}/rng/uni32.c ${GSL_DIR}/rng/vax.c ${GSL_DIR}/rng/waterman14.c ${GSL_DIR}/rng/zuf.c ${GSL_DIR}/roots/bisection.c ${GSL_DIR}/roots/brent.c ${GSL_DIR}/roots/convergence.c ${GSL_DIR}/roots/falsepos.c ${GSL_DIR}/roots/fdfsolver.c ${GSL_DIR}/roots/fsolver.c ${GSL_DIR}/roots/newton.c ${GSL_DIR}/roots/secant.c ${GSL_DIR}/roots/steffenson.c ${GSL_DIR}/siman/siman.c ${GSL_DIR}/sort/sort.c ${GSL_DIR}/sort/sortind.c ${GSL_DIR}/sort/sortvec.c ${GSL_DIR}/sort/sortvecind.c ${GSL_DIR}/sort/subset.c ${GSL_DIR}/sort/subsetind.c ${GSL_DIR}/specfunc/airy.c ${GSL_DIR}/specfunc/airy_der.c ${GSL_DIR}/specfunc/airy_zero.c ${GSL_DIR}/specfunc/atanint.c ${GSL_DIR}/specfunc/bessel.c ${GSL_DIR}/specfunc/bessel_amp_phase.c ${GSL_DIR}/specfunc/bessel_i.c ${GSL_DIR}/specfunc/bessel_I0.c ${GSL_DIR}/specfunc/bessel_I1.c ${GSL_DIR}/specfunc/bessel_In.c ${GSL_DIR}/specfunc/bessel_Inu.c ${GSL_DIR}/specfunc/bessel_j.c ${GSL_DIR}/specfunc/bessel_J0.c ${GSL_DIR}/specfunc/bessel_J1.c ${GSL_DIR}/specfunc/bessel_Jn.c ${GSL_DIR}/specfunc/bessel_Jnu.c ${GSL_DIR}/specfunc/bessel_k.c ${GSL_DIR}/specfunc/bessel_K0.c ${GSL_DIR}/specfunc/bessel_K1.c ${GSL_DIR}/specfunc/bessel_Kn.c ${GSL_DIR}/specfunc/bessel_Knu.c ${GSL_DIR}/specfunc/bessel_olver.c ${GSL_DIR}/specfunc/bessel_sequence.c ${GSL_DIR}/specfunc/bessel_temme.c ${GSL_DIR}/specfunc/bessel_y.c ${GSL_DIR}/specfunc/bessel_Y0.c ${GSL_DIR}/specfunc/bessel_Y1.c ${GSL_DIR}/specfunc/bessel_Yn.c ${GSL_DIR}/specfunc/bessel_Ynu.c ${GSL_DIR}/specfunc/bessel_zero.c ${GSL_DIR}/specfunc/beta.c ${GSL_DIR}/specfunc/beta_inc.c ${GSL_DIR}/specfunc/clausen.c ${GSL_DIR}/specfunc/coulomb.c ${GSL_DIR}/specfunc/coulomb_bound.c ${GSL_DIR}/specfunc/coupling.c ${GSL_DIR}/specfunc/dawson.c ${GSL_DIR}/specfunc/debye.c ${GSL_DIR}/specfunc/dilog.c ${GSL_DIR}/specfunc/elementary.c ${GSL_DIR}/specfunc/ellint.c ${GSL_DIR}/specfunc/elljac.c ${GSL_DIR}/specfunc/erfc.c ${GSL_DIR}/specfunc/exp.c ${GSL_DIR}/specfunc/expint.c ${GSL_DIR}/specfunc/expint3.c ${GSL_DIR}/specfunc/fermi_dirac.c ${GSL_DIR}/specfunc/gamma.c ${GSL_DIR}/specfunc/gamma_inc.c ${GSL_DIR}/specfunc/gegenbauer.c ${GSL_DIR}/specfunc/hyperg.c ${GSL_DIR}/specfunc/hyperg_0F1.c ${GSL_DIR}/specfunc/hyperg_1F1.c ${GSL_DIR}/specfunc/hyperg_2F0.c ${GSL_DIR}/specfunc/hyperg_2F1.c ${GSL_DIR}/specfunc/hyperg_U.c ${GSL_DIR}/specfunc/laguerre.c ${GSL_DIR}/specfunc/lambert.c ${GSL_DIR}/specfunc/legendre_con.c ${GSL_DIR}/specfunc/legendre_H3d.c ${GSL_DIR}/specfunc/legendre_poly.c ${GSL_DIR}/specfunc/legendre_Qn.c ${GSL_DIR}/specfunc/log.c ${GSL_DIR}/specfunc/mathieu_angfunc.c ${GSL_DIR}/specfunc/mathieu_charv.c ${GSL_DIR}/specfunc/mathieu_coeff.c ${GSL_DIR}/specfunc/mathieu_radfunc.c ${GSL_DIR}/specfunc/mathieu_workspace.c ${GSL_DIR}/specfunc/poch.c ${GSL_DIR}/specfunc/pow_int.c ${GSL_DIR}/specfunc/psi.c ${GSL_DIR}/specfunc/result.c ${GSL_DIR}/specfunc/shint.c ${GSL_DIR}/specfunc/sinint.c ${GSL_DIR}/specfunc/synchrotron.c ${GSL_DIR}/specfunc/transport.c ${GSL_DIR}/specfunc/trig.c ${GSL_DIR}/specfunc/zeta.c ${GSL_DIR}/statistics/absdev.c ${GSL_DIR}/statistics/covariance.c ${GSL_DIR}/statistics/kurtosis.c ${GSL_DIR}/statistics/lag1.c ${GSL_DIR}/statistics/mean.c ${GSL_DIR}/statistics/median.c ${GSL_DIR}/statistics/minmax.c ${GSL_DIR}/statistics/p_variance.c ${GSL_DIR}/statistics/quantiles.c ${GSL_DIR}/statistics/skew.c ${GSL_DIR}/statistics/ttest.c ${GSL_DIR}/statistics/variance.c ${GSL_DIR}/statistics/wabsdev.c ${GSL_DIR}/statistics/wkurtosis.c ${GSL_DIR}/statistics/wmean.c ${GSL_DIR}/statistics/wskew.c ${GSL_DIR}/statistics/wvariance.c ${GSL_DIR}/sum/levin_u.c ${GSL_DIR}/sum/levin_utrunc.c ${GSL_DIR}/sum/work_u.c ${GSL_DIR}/sum/work_utrunc.c ${GSL_DIR}/sys/coerce.c ${GSL_DIR}/sys/expm1.c ${GSL_DIR}/sys/fcmp.c ${GSL_DIR}/sys/fdiv.c ${GSL_DIR}/sys/hypot.c ${GSL_DIR}/sys/infnan.c ${GSL_DIR}/sys/invhyp.c ${GSL_DIR}/sys/ldfrexp.c ${GSL_DIR}/sys/log1p.c ${GSL_DIR}/sys/minmax.c ${GSL_DIR}/sys/pow_int.c ${GSL_DIR}/sys/prec.c ${GSL_DIR}/test/results.c ${GSL_DIR}/vector/copy.c ${GSL_DIR}/vector/file.c ${GSL_DIR}/vector/init.c ${GSL_DIR}/vector/minmax.c ${GSL_DIR}/vector/oper.c ${GSL_DIR}/vector/prop.c ${GSL_DIR}/vector/reim.c ${GSL_DIR}/vector/subvector.c ${GSL_DIR}/vector/swap.c ${GSL_DIR}/vector/vector.c ${GSL_DIR}/vector/view.c ${GSL_DIR}/wavelet/bspline.c ${GSL_DIR}/wavelet/daubechies.c ${GSL_DIR}/wavelet/dwt.c ${GSL_DIR}/wavelet/haar.c ${GSL_DIR}/wavelet/wavelet.c ${GSL_DIR}/bspline/bspline.c ) set(cblas_source_list ${GSL_DIR}/cblas/caxpy.c ${GSL_DIR}/cblas/ccopy.c ${GSL_DIR}/cblas/cdotc_sub.c ${GSL_DIR}/cblas/cdotu_sub.c ${GSL_DIR}/cblas/cgbmv.c ${GSL_DIR}/cblas/cgemm.c ${GSL_DIR}/cblas/cgemv.c ${GSL_DIR}/cblas/cgerc.c ${GSL_DIR}/cblas/cgeru.c ${GSL_DIR}/cblas/chbmv.c ${GSL_DIR}/cblas/chemm.c ${GSL_DIR}/cblas/chemv.c ${GSL_DIR}/cblas/cher.c ${GSL_DIR}/cblas/cher2.c ${GSL_DIR}/cblas/cher2k.c ${GSL_DIR}/cblas/cherk.c ${GSL_DIR}/cblas/chpmv.c ${GSL_DIR}/cblas/chpr.c ${GSL_DIR}/cblas/chpr2.c ${GSL_DIR}/cblas/cscal.c ${GSL_DIR}/cblas/csscal.c ${GSL_DIR}/cblas/cswap.c ${GSL_DIR}/cblas/csymm.c ${GSL_DIR}/cblas/csyr2k.c ${GSL_DIR}/cblas/csyrk.c ${GSL_DIR}/cblas/ctbmv.c ${GSL_DIR}/cblas/ctbsv.c ${GSL_DIR}/cblas/ctpmv.c ${GSL_DIR}/cblas/ctpsv.c ${GSL_DIR}/cblas/ctrmm.c ${GSL_DIR}/cblas/ctrmv.c ${GSL_DIR}/cblas/ctrsm.c ${GSL_DIR}/cblas/ctrsv.c ${GSL_DIR}/cblas/dasum.c ${GSL_DIR}/cblas/daxpy.c ${GSL_DIR}/cblas/dcopy.c ${GSL_DIR}/cblas/ddot.c ${GSL_DIR}/cblas/dgbmv.c ${GSL_DIR}/cblas/dgemm.c ${GSL_DIR}/cblas/dgemv.c ${GSL_DIR}/cblas/dger.c ${GSL_DIR}/cblas/dnrm2.c ${GSL_DIR}/cblas/drot.c ${GSL_DIR}/cblas/drotg.c ${GSL_DIR}/cblas/drotm.c ${GSL_DIR}/cblas/drotmg.c ${GSL_DIR}/cblas/dsbmv.c ${GSL_DIR}/cblas/dscal.c ${GSL_DIR}/cblas/dsdot.c ${GSL_DIR}/cblas/dspmv.c ${GSL_DIR}/cblas/dspr.c ${GSL_DIR}/cblas/dspr2.c ${GSL_DIR}/cblas/dswap.c ${GSL_DIR}/cblas/dsymm.c ${GSL_DIR}/cblas/dsymv.c ${GSL_DIR}/cblas/dsyr.c ${GSL_DIR}/cblas/dsyr2.c ${GSL_DIR}/cblas/dsyr2k.c ${GSL_DIR}/cblas/dsyrk.c ${GSL_DIR}/cblas/dtbmv.c ${GSL_DIR}/cblas/dtbsv.c ${GSL_DIR}/cblas/dtpmv.c ${GSL_DIR}/cblas/dtpsv.c ${GSL_DIR}/cblas/dtrmm.c ${GSL_DIR}/cblas/dtrmv.c ${GSL_DIR}/cblas/dtrsm.c ${GSL_DIR}/cblas/dtrsv.c ${GSL_DIR}/cblas/dzasum.c ${GSL_DIR}/cblas/dznrm2.c ${GSL_DIR}/cblas/hypot.c ${GSL_DIR}/cblas/icamax.c ${GSL_DIR}/cblas/idamax.c ${GSL_DIR}/cblas/isamax.c ${GSL_DIR}/cblas/izamax.c ${GSL_DIR}/cblas/sasum.c ${GSL_DIR}/cblas/saxpy.c ${GSL_DIR}/cblas/scasum.c ${GSL_DIR}/cblas/scnrm2.c ${GSL_DIR}/cblas/scopy.c ${GSL_DIR}/cblas/sdot.c ${GSL_DIR}/cblas/sdsdot.c ${GSL_DIR}/cblas/sgbmv.c ${GSL_DIR}/cblas/sgemm.c ${GSL_DIR}/cblas/sgemv.c ${GSL_DIR}/cblas/sger.c ${GSL_DIR}/cblas/snrm2.c ${GSL_DIR}/cblas/srot.c ${GSL_DIR}/cblas/srotg.c ${GSL_DIR}/cblas/srotm.c ${GSL_DIR}/cblas/srotmg.c ${GSL_DIR}/cblas/ssbmv.c ${GSL_DIR}/cblas/sscal.c ${GSL_DIR}/cblas/sspmv.c ${GSL_DIR}/cblas/sspr.c ${GSL_DIR}/cblas/sspr2.c ${GSL_DIR}/cblas/sswap.c ${GSL_DIR}/cblas/ssymm.c ${GSL_DIR}/cblas/ssymv.c ${GSL_DIR}/cblas/ssyr.c ${GSL_DIR}/cblas/ssyr2.c ${GSL_DIR}/cblas/ssyr2k.c ${GSL_DIR}/cblas/ssyrk.c ${GSL_DIR}/cblas/stbmv.c ${GSL_DIR}/cblas/stbsv.c ${GSL_DIR}/cblas/stpmv.c ${GSL_DIR}/cblas/stpsv.c ${GSL_DIR}/cblas/strmm.c ${GSL_DIR}/cblas/strmv.c ${GSL_DIR}/cblas/strsm.c ${GSL_DIR}/cblas/strsv.c ${GSL_DIR}/cblas/xerbla.c ${GSL_DIR}/cblas/zaxpy.c ${GSL_DIR}/cblas/zcopy.c ${GSL_DIR}/cblas/zdotc_sub.c ${GSL_DIR}/cblas/zdotu_sub.c ${GSL_DIR}/cblas/zdscal.c ${GSL_DIR}/cblas/zgbmv.c ${GSL_DIR}/cblas/zgemm.c ${GSL_DIR}/cblas/zgemv.c ${GSL_DIR}/cblas/zgerc.c ${GSL_DIR}/cblas/zgeru.c ${GSL_DIR}/cblas/zhbmv.c ${GSL_DIR}/cblas/zhemm.c ${GSL_DIR}/cblas/zhemv.c ${GSL_DIR}/cblas/zher.c ${GSL_DIR}/cblas/zher2.c ${GSL_DIR}/cblas/zher2k.c ${GSL_DIR}/cblas/zherk.c ${GSL_DIR}/cblas/zhpmv.c ${GSL_DIR}/cblas/zhpr.c ${GSL_DIR}/cblas/zhpr2.c ${GSL_DIR}/cblas/zscal.c ${GSL_DIR}/cblas/zswap.c ${GSL_DIR}/cblas/zsymm.c ${GSL_DIR}/cblas/zsyr2k.c ${GSL_DIR}/cblas/zsyrk.c ${GSL_DIR}/cblas/ztbmv.c ${GSL_DIR}/cblas/ztbsv.c ${GSL_DIR}/cblas/ztpmv.c ${GSL_DIR}/cblas/ztpsv.c ${GSL_DIR}/cblas/ztrmm.c ${GSL_DIR}/cblas/ztrmv.c ${GSL_DIR}/cblas/ztrsm.c ${GSL_DIR}/cblas/ztrsv.c ) macro(GSL_FILES name folder) file(GLOB ${name}_folder_sources ${GSL_DIR}/${folder}/*.c) file(GLOB ${name}_folder_headers ${GSL_DIR}/${folder}/*.h) set(${name}_sources ${${name}_sources} ${${name}_folder_sources}) set(${name}_headers ${${name}_headers} ${${name}_folder_headers}) include_directories(${CMAKE_SOURCE_DIR}/${folder}) endmacro() set(gsl_folders . blas block bspline cblas cdf cheb combination complex const deriv dht diff eigen err fft fit gsl histogram ieee-utils integration interpolation linalg matrix min monte multifit multimin multiroots ntuple ode-initval permutation poly qrng randist rng roots siman sort specfunc statistics sum sys test utils vector wavelet) # collect headers foreach(current ${gsl_folders}) GSL_FILES(gsl ${current} ) endforeach() # copy headers to include/gsl foreach(current ${gsl_headers}) get_filename_component(filename ${current} NAME) configure_file(${current} ${CMAKE_CURRENT_BINARY_DIR}/include/gsl/${filename} COPYONLY) endforeach() if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) set(CMAKE_DEBUG_POSTFIX d) endif() include_directories( ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/include ) add_library(gsl STATIC ${gsl_source_list} ${cblas_source_list} ${gsl_headers}) if (NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/installed) endif() install(FILES ${gsl_headers} DESTINATION include/gsl) install(TARGETS gsl DESTINATION lib) kst-2.0.3/misc/gsl-windows/config.h000644 001750 001750 00000040601 11544160206 017517 0ustar00synthsynth000000 000000 // this file contains two config.h files, // one for msvc and one for mingw // later config.h should be generated #ifdef _MSC_VER /* config.h Generated from configure.ac by autoheader. KC:(21.06.04) Edited by hand for VC++6.0/WinXP */ /* Disable deprecated functions and enums while building */ #define GSL_DISABLE_DEPRECATED 1 /* Define if you have inline with C99 behavior */ #define HAVE_C99_INLINE 1 /* Define to 1 if you have the declaration of `acosh', and to 0 if you don't. */ #define HAVE_DECL_ACOSH 0 /* Define to 1 if you have the declaration of `asinh', and to 0 if you don't. */ #define HAVE_DECL_ASINH 0 /* Define to 1 if you have the declaration of `atanh', and to 0 if you don't. */ #define HAVE_DECL_ATANH 0 /* Define to 1 if you have the declaration of `expm1', and to 0 if you don't. */ #define HAVE_DECL_EXPM1 0 /* Define to 1 if you have the declaration of `feenableexcept', and to 0 if you don't. */ #define HAVE_DECL_FEENABLEEXCEPT 0 /* Define to 1 if you have the declaration of `fesettrapenable', and to 0 if you don't. */ #define HAVE_DECL_FESETTRAPENABLE 0 /* Define to 1 if you have the declaration of `finite', and to 0 if you don't. */ #define HAVE_DECL_FINITE 0 /* Define to 1 if you have the declaration of `frexp', and to 0 if you don't. */ #define HAVE_DECL_FREXP 1 /* Define to 1 if you have the declaration of `hypot', and to 0 if you don't. */ #define HAVE_DECL_HYPOT 1 /* Define to 1 if you have the declaration of `isfinite', and to 0 if you don't. */ #define HAVE_DECL_ISFINITE 0 /* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. */ #define HAVE_DECL_ISINF 0 /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. */ #define HAVE_DECL_ISNAN 0 /* Define to 1 if you have the declaration of `ldexp', and to 0 if you don't. */ #define HAVE_DECL_LDEXP 1 /* Define to 1 if you have the declaration of `log1p', and to 0 if you don't. */ #define HAVE_DECL_LOG1P 0 /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Defined if you have ansi EXIT_SUCCESS and EXIT_FAILURE in stdlib.h */ #define HAVE_EXIT_SUCCESS_AND_FAILURE 1 /* Defined on architectures with excess floating-point precision */ #undef HAVE_EXTENDED_PRECISION_REGISTERS /* Define if x86 processor has sse extensions. */ #define HAVE_FPU_X86_SSE /* Define to 1 if you have the header file. */ #undef HAVE_IEEEFP_H /* Define this if IEEE comparisons work correctly (e.g. NaN != NaN) */ #undef HAVE_IEEE_COMPARISONS /* Define this if IEEE denormalized numbers are available */ #undef HAVE_IEEE_DENORMALS /* Define if you have inline */ #define HAVE_INLINE 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 0 /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `memcpy' function. */ #define HAVE_MEMCPY 1 /* Define to 1 if you have the `memmove' function. */ #define HAVE_MEMMOVE 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define this if printf can handle %Lf for long double */ #define HAVE_PRINTF_LONGDOUBLE 1 /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strtol' function. */ #define HAVE_STRTOL 1 /* Define to 1 if you have the `strtoul' function. */ #define HAVE_STRTOUL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vprintf' function. */ #define HAVE_VPRINTF 1 /* Define if you need to hide the static definitions of inline functions */ #define HIDE_INLINE_STATIC 1 /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #define PACKAGE "Win-32 VC++ DG" /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Defined if this is an official release */ #define RELEASED 1 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 0 /* Version number of package */ #define VERSION 1 #ifndef __CHAR_UNSIGNED__ #define __CHAR_UNSIGNED__ #endif /* Define as `__inline' if that's what the C compiler calls it, or to nothing if it is not supported. */ #define inline __inline /* Define to `unsigned' if does not define. */ //#undef size_t /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ //#undef volatile /* Use 0 and 1 for EXIT_SUCCESS and EXIT_FAILURE if we don't have them */ #if !HAVE_EXIT_SUCCESS_AND_FAILURE #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #endif /* Define one of these if you have a known IEEE arithmetic interface */ #undef HAVE_GNUSPARC_IEEE_INTERFACE #undef HAVE_GNUM68K_IEEE_INTERFACE #undef HAVE_GNUPPC_IEEE_INTERFACE #undef HAVE_GNUX86_IEEE_INTERFACE #undef HAVE_SUNOS4_IEEE_INTERFACE #undef HAVE_SOLARIS_IEEE_INTERFACE #undef HAVE_HPUX11_IEEE_INTERFACE #undef HAVE_HPUX_IEEE_INTERFACE #undef HAVE_TRU64_IEEE_INTERFACE #undef HAVE_IRIX_IEEE_INTERFACE #undef HAVE_AIX_IEEE_INTERFACE #undef HAVE_FREEBSD_IEEE_INTERFACE #undef HAVE_OS2EMX_IEEE_INTERFACE #undef HAVE_NETBSD_IEEE_INTERFACE #undef HAVE_OPENBSD_IEEE_INTERFACE #undef HAVE_DARWIN_IEEE_INTERFACE /* Define a rounding function which moves extended precision values out of registers and rounds them to double-precision. This should be used *sparingly*, in places where it is necessary to keep double-precision rounding for critical expressions while running in extended precision. For example, the following code should ensure exact equality, even when extended precision registers are in use, double q = GSL_COERCE_DBL(3.0/7.0) ; if (q == GSL_COERCE_DBL(3.0/7.0)) { ... } ; It carries a penalty even when the program is running in double precision mode unless you compile a separate version of the library with HAVE_EXTENDED_PRECISION_REGISTERS turned off. */ #if HAVE_EXTENDED_PRECISION_REGISTERS #define GSL_COERCE_DBL(x) (gsl_coerce_double(x)) #else #define GSL_COERCE_DBL(x) (x) #endif /* Substitute gsl functions for missing system functions */ #if !HAVE_DECL_HYPOT #define hypot gsl_hypot //#define hypot _hypot #endif #if !HAVE_DECL_LOG1P #define log1p gsl_log1p #endif #if !HAVE_DECL_EXPM1 #define expm1 gsl_expm1 #endif #if !HAVE_DECL_ACOSH #define acosh gsl_acosh #endif #if !HAVE_DECL_ASINH #define asinh gsl_asinh #endif #if !HAVE_DECL_ATANH #define atanh gsl_atanh #endif #if !HAVE_DECL_LDEXP #define ldexp gsl_ldexp #endif #if !HAVE_DECL_FREXP #define frexp gsl_frexp #endif #if !HAVE_DECL_ISINF #define isinf gsl_isinf #endif #if !HAVE_DECL_FINITE #if HAVE_DECL_ISFINITE #define finite isfinite #else // #define finite gsl_finite #define finite _finite #endif #endif #if !HAVE_DECL_ISNAN // #define isnan gsl_isnan #define isnan _isnan #endif #ifdef __GNUC__ #define DISCARD_POINTER(p) do { ; } while(p ? 0 : 0); #else #define DISCARD_POINTER(p) /* ignoring discarded pointer */ #endif #if defined(GSL_RANGE_CHECK_OFF) || !defined(GSL_RANGE_CHECK) #define GSL_RANGE_CHECK 0 /* turn off range checking by default */ #endif #define RETURN_IF_NULL(x) if (!x) { return ; } #define _USE_MATH_DEFINES // Remove loss in conversion #pragma warning( disable : 4244) #else // _MSC_VER /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Disable deprecated functions and enums while building */ #define GSL_DISABLE_DEPRECATED 1 /* Define if you have inline with C99 behavior */ /* #undef HAVE_C99_INLINE */ /* Define to 1 if you have the declaration of `acosh', and to 0 if you don't. */ #define HAVE_DECL_ACOSH 1 /* Define to 1 if you have the declaration of `asinh', and to 0 if you don't. */ #define HAVE_DECL_ASINH 1 /* Define to 1 if you have the declaration of `atanh', and to 0 if you don't. */ #define HAVE_DECL_ATANH 1 /* Define to 1 if you have the declaration of `expm1', and to 0 if you don't. */ #define HAVE_DECL_EXPM1 1 /* Define to 1 if you have the declaration of `feenableexcept', and to 0 if you don't. */ #define HAVE_DECL_FEENABLEEXCEPT 1 /* Define to 1 if you have the declaration of `fesettrapenable', and to 0 if you don't. */ #define HAVE_DECL_FESETTRAPENABLE 0 /* Define to 1 if you have the declaration of `finite', and to 0 if you don't. */ #define HAVE_DECL_FINITE 1 /* Define to 1 if you have the declaration of `frexp', and to 0 if you don't. */ #define HAVE_DECL_FREXP 1 /* Define to 1 if you have the declaration of `hypot', and to 0 if you don't. */ #define HAVE_DECL_HYPOT 1 /* Define to 1 if you have the declaration of `isfinite', and to 0 if you don't. */ #define HAVE_DECL_ISFINITE 1 /* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. */ #define HAVE_DECL_ISINF 1 /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. */ #define HAVE_DECL_ISNAN 1 /* Define to 1 if you have the declaration of `ldexp', and to 0 if you don't. */ #define HAVE_DECL_LDEXP 1 /* Define to 1 if you have the declaration of `log1p', and to 0 if you don't. */ #define HAVE_DECL_LOG1P 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* #undef HAVE_DOPRNT */ /* Defined if you have ansi EXIT_SUCCESS and EXIT_FAILURE in stdlib.h */ #define HAVE_EXIT_SUCCESS_AND_FAILURE 1 /* Defined on architectures with excess floating-point precision */ #define HAVE_EXTENDED_PRECISION_REGISTERS 1 /* Define if x86 processor has sse extensions. */ #define HAVE_FPU_X86_SSE 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_IEEEFP_H */ /* Define this if IEEE comparisons work correctly (e.g. NaN != NaN) */ #define HAVE_IEEE_COMPARISONS 1 /* Define this if IEEE denormalized numbers are available */ #define HAVE_IEEE_DENORMALS 1 /* Define if you have inline */ #define HAVE_INLINE 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `m' library (-lm). */ #define HAVE_LIBM 1 /* Define to 1 if you have the `memcpy' function. */ #define HAVE_MEMCPY 1 /* Define to 1 if you have the `memmove' function. */ #define HAVE_MEMMOVE 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define this if printf can handle %Lf for long double */ #define HAVE_PRINTF_LONGDOUBLE 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strdup' function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strtol' function. */ #define HAVE_STRTOL 1 /* Define to 1 if you have the `strtoul' function. */ #define HAVE_STRTOUL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the `vprintf' function. */ #define HAVE_VPRINTF 1 /* Define if you need to hide the static definitions of inline functions */ /* #undef HIDE_INLINE_STATIC */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Name of package */ #define PACKAGE "gsl" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "gsl" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "gsl 1.14" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gsl" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.14" /* Defined if this is an official release */ #define RELEASED /**/ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "1.14" /* Define to 1 if type `char' is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ /* # undef __CHAR_UNSIGNED__ */ #endif /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus /* #undef inline */ #endif /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ /* #undef volatile */ /* Use 0 and 1 for EXIT_SUCCESS and EXIT_FAILURE if we don't have them */ #if !HAVE_EXIT_SUCCESS_AND_FAILURE #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #endif /* Define one of these if you have a known IEEE arithmetic interface */ /* #undef HAVE_GNUSPARC_IEEE_INTERFACE */ /* #undef HAVE_GNUM68K_IEEE_INTERFACE */ /* #undef HAVE_GNUPPC_IEEE_INTERFACE */ /* #define HAVE_GNUX86_IEEE_INTERFACE 1*/ /* #undef HAVE_SUNOS4_IEEE_INTERFACE */ /* #undef HAVE_SOLARIS_IEEE_INTERFACE */ /* #undef HAVE_HPUX11_IEEE_INTERFACE */ /* #undef HAVE_HPUX_IEEE_INTERFACE */ /* #undef HAVE_TRU64_IEEE_INTERFACE */ /* #undef HAVE_IRIX_IEEE_INTERFACE */ /* #undef HAVE_AIX_IEEE_INTERFACE */ /* #undef HAVE_FREEBSD_IEEE_INTERFACE */ /* #undef HAVE_OS2EMX_IEEE_INTERFACE */ /* #undef HAVE_NETBSD_IEEE_INTERFACE */ /* #undef HAVE_OPENBSD_IEEE_INTERFACE */ /* #undef HAVE_DARWIN_IEEE_INTERFACE */ /* #undef HAVE_DARWIN86_IEEE_INTERFACE */ /* Define a rounding function which moves extended precision values out of registers and rounds them to double-precision. This should be used *sparingly*, in places where it is necessary to keep double-precision rounding for critical expressions while running in extended precision. For example, the following code should ensure exact equality, even when extended precision registers are in use, double q = GSL_COERCE_DBL(3.0/7.0) ; if (q == GSL_COERCE_DBL(3.0/7.0)) { ... } ; It carries a penalty even when the program is running in double precision mode unless you compile a separate version of the library with HAVE_EXTENDED_PRECISION_REGISTERS turned off. */ #if HAVE_EXTENDED_PRECISION_REGISTERS #define GSL_COERCE_DBL(x) (gsl_coerce_double(x)) #else #define GSL_COERCE_DBL(x) (x) #endif /* Substitute gsl functions for missing system functions */ #if !HAVE_DECL_HYPOT #define hypot gsl_hypot #endif #if !HAVE_DECL_LOG1P #define log1p gsl_log1p #endif #if !HAVE_DECL_EXPM1 #define expm1 gsl_expm1 #endif #if !HAVE_DECL_ACOSH #define acosh gsl_acosh #endif #if !HAVE_DECL_ASINH #define asinh gsl_asinh #endif #if !HAVE_DECL_ATANH #define atanh gsl_atanh #endif #if !HAVE_DECL_LDEXP #define ldexp gsl_ldexp #endif #if !HAVE_DECL_FREXP #define frexp gsl_frexp #endif #if !HAVE_DECL_ISINF #define isinf gsl_isinf #endif #if !HAVE_DECL_FINITE #define finite gsl_finite #endif #if !HAVE_DECL_ISNAN #define isnan gsl_isnan #endif #ifdef __GNUC__ #define DISCARD_POINTER(p) do { ; } while(p ? 0 : 0); #else #define DISCARD_POINTER(p) /* ignoring discarded pointer */ #endif #if defined(GSL_RANGE_CHECK_OFF) || !defined(GSL_RANGE_CHECK) #define GSL_RANGE_CHECK 0 /* turn off range checking by default internally */ #endif #define RETURN_IF_NULL(x) if (!x) { return ; } #endif kst-2.0.3/misc/gsl-windows/gsl-msvc.patch000644 001750 001750 00000001437 11544160206 020661 0ustar00synthsynth000000 000000 diff --git a/bspline/bspline.h b/bspline/bspline.h index f80e03e..67d000a 100644 diff --git a/templates_on.h b/templates_on.h index cd32eff..dde02c3 100644 --- a/templates_on.h +++ b/templates_on.h @@ -20,6 +20,10 @@ #define BASE_EPSILON GSL_DBL_EPSILON #elif defined(BASE_GSL_COMPLEX) +#ifdef _MSC_VER + #define VCPP_MATH_COMPLEX complex // Workaround of problems caused by complex, defined as _complex in Math.h of MS-VC++ + #undef complex +#endif #define BASE gsl_complex #define SHORT complex #define SHORT_REAL @@ -32,6 +36,11 @@ #define ZERO {{0.0,0.0}} #define ONE {{1.0,0.0}} #define BASE_EPSILON GSL_DBL_EPSILON +#ifdef _MSC_VER + #undef complex + #define complex VCPP_MATH_COMPLEX +#endif + #elif defined(BASE_GSL_COMPLEX_FLOAT) #define BASE gsl_complex_float kst-2.0.3/misc/gsl-windows/gsl-mingw.patch000644 001750 001750 00000000673 11544160206 021033 0ustar00synthsynth000000 000000 diff --git a/gsl_inline.h b/gsl_inline.h index 2172201..75e4b16 100644 --- a/gsl_inline.h +++ b/gsl_inline.h @@ -51,8 +51,8 @@ # define INLINE_DECL inline /* use C99 inline */ # define INLINE_FUN inline # else -# define INLINE_DECL /* use GNU extern inline */ -# define INLINE_FUN extern inline +# define INLINE_DECL static inline +# define INLINE_FUN static inline # endif #else # define INLINE_DECL /* */ kst-2.0.3/misc/IDL 21 Hue-Sat-Value1000644 001750 001750 00000005602 11544160206 016746 0ustar00synthsynth000000 000000 GIMP Palette 255 0 3 255 0 3 255 1 13 255 2 17 255 3 23 255 4 30 255 5 37 255 6 44 255 7 50 255 8 57 255 9 63 255 13 70 255 11 76 255 12 82 255 13 89 255 14 95 255 15 101 255 16 107 255 17 114 255 18 120 255 19 126 255 20 132 255 21 138 255 22 144 255 23 149 255 24 155 255 25 161 255 26 167 255 27 172 255 28 178 255 29 184 255 30 189 255 31 195 255 32 200 255 33 205 255 34 211 255 35 216 255 36 221 255 37 227 255 38 232 255 39 237 255 40 242 255 41 247 255 42 252 252 43 255 247 44 255 242 45 255 237 46 255 233 47 255 228 48 255 223 49 255 219 50 255 214 51 255 210 52 255 205 53 255 201 54 255 196 55 255 192 56 255 188 57 255 184 58 255 179 59 255 175 60 255 171 61 255 167 62 255 163 63 255 159 64 255 155 64 255 151 65 255 147 66 255 144 67 255 140 68 255 136 69 255 133 70 255 129 71 255 125 72 255 122 73 255 118 74 255 115 75 255 112 76 255 108 77 255 105 78 255 102 79 255 99 80 255 95 81 255 92 82 255 89 83 255 86 84 255 85 87 255 86 92 255 87 97 255 88 102 255 89 107 255 90 111 255 91 116 255 92 121 255 93 125 255 94 130 255 95 134 255 96 139 255 97 143 255 98 147 255 99 152 255 100 156 255 101 160 255 102 164 255 103 168 255 104 172 255 105 176 255 106 180 255 107 184 255 108 188 255 109 192 255 110 196 255 111 199 255 112 203 255 113 207 255 114 210 255 115 214 255 116 217 255 117 221 255 118 224 255 119 228 255 120 231 255 121 234 255 122 238 255 123 241 255 124 244 255 125 247 255 126 250 255 127 253 255 128 255 253 129 255 250 130 255 247 131 255 244 132 255 242 133 255 239 134 255 236 135 255 234 136 255 231 137 255 229 138 255 226 139 255 224 140 255 221 141 255 219 142 255 217 143 255 214 144 255 212 145 255 210 146 255 208 147 255 206 148 255 204 149 255 202 150 255 200 151 255 198 152 255 196 153 255 194 154 255 192 155 255 191 156 255 189 157 255 187 158 255 186 159 255 184 160 255 183 161 255 181 162 255 180 163 255 179 164 255 177 165 255 176 166 255 175 167 255 174 168 255 173 169 255 172 170 255 171 172 255 171 175 255 172 177 255 173 180 255 174 183 255 175 186 255 176 188 255 177 191 255 178 194 255 179 196 255 180 199 255 181 201 255 182 203 255 183 206 255 184 208 255 185 210 255 186 213 255 187 215 255 188 217 255 189 219 255 190 221 255 191 223 255 191 225 255 192 227 255 193 229 255 194 230 255 195 232 255 196 234 255 197 236 255 198 237 255 199 239 255 200 240 255 201 242 255 202 243 255 203 245 255 204 246 255 205 247 255 206 248 255 207 250 255 208 251 255 209 252 255 210 253 255 211 254 255 212 255 254 213 255 253 214 255 252 215 255 251 216 255 251 217 255 250 218 255 249 219 255 249 220 255 248 221 255 247 222 255 247 223 255 246 224 255 246 225 255 246 226 255 245 227 255 245 228 255 245 229 255 245 230 255 244 231 255 244 232 255 244 233 255 244 234 255 244 235 255 244 236 255 245 237 255 245 238 255 245 239 255 245 240 255 246 241 255 246 242 255 246 243 255 247 244 255 247 245 255 248 246 255 249 247 255 249 248 255 250 249 255 251 250 255 251 251 255 251 251 kst-2.0.3/misc/IDL 13 RAINBOW000644 001750 001750 00000004535 11544160206 015453 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 4 0 3 9 0 7 13 0 10 18 0 14 22 0 19 27 0 23 31 0 28 36 0 32 40 0 38 45 0 43 50 0 48 54 0 53 58 0 59 61 0 63 64 0 68 68 0 72 69 0 77 72 0 81 74 0 86 77 0 91 79 0 95 80 0 100 82 0 104 83 0 109 85 0 113 84 0 118 86 0 122 87 0 127 88 0 132 86 0 136 87 0 141 87 0 145 87 0 150 85 0 154 84 0 159 84 0 163 84 0 168 83 0 173 79 0 177 78 0 182 77 0 186 76 0 191 71 0 195 70 0 200 68 0 204 66 0 209 60 0 214 58 0 218 55 0 223 53 0 227 46 0 232 43 0 236 40 0 241 36 0 245 33 0 250 25 0 255 21 0 255 16 0 255 12 0 255 4 0 255 0 0 255 0 4 255 0 8 255 0 16 255 0 21 255 0 25 255 0 29 255 0 38 255 0 42 255 0 46 255 0 51 255 0 55 255 0 63 255 0 67 255 0 72 255 0 76 255 0 84 255 0 89 255 0 93 255 0 97 255 0 106 255 0 110 255 0 114 255 0 119 255 0 127 255 0 131 255 0 135 255 0 140 255 0 144 255 0 152 255 0 157 255 0 161 255 0 165 255 0 174 255 0 178 255 0 182 255 0 187 255 0 195 255 0 199 255 0 203 255 0 208 255 0 216 255 0 220 255 0 225 255 0 229 255 0 233 255 0 242 255 0 246 255 0 250 255 0 255 255 0 255 246 0 255 242 0 255 238 0 255 233 0 255 225 0 255 220 0 255 216 0 255 212 0 255 203 0 255 199 0 255 195 0 255 191 0 255 187 0 255 178 0 255 174 0 255 170 0 255 165 0 255 157 0 255 152 0 255 148 0 255 144 0 255 135 0 255 131 0 255 127 0 255 123 0 255 114 0 255 110 0 255 106 0 255 102 0 255 97 0 255 89 0 255 84 0 255 80 0 255 76 0 255 67 0 255 63 0 255 59 0 255 55 0 255 46 0 255 42 0 255 38 0 255 34 0 255 25 0 255 21 0 255 16 0 255 12 0 255 8 0 255 0 4 255 0 8 255 0 12 255 0 21 255 0 25 255 0 29 255 0 33 255 0 42 255 0 46 255 0 51 255 0 55 255 0 63 255 0 67 255 0 72 255 0 76 255 0 80 255 0 89 255 0 93 255 0 97 255 0 101 255 0 110 255 0 114 255 0 119 255 0 123 255 0 131 255 0 135 255 0 140 255 0 144 255 0 153 255 0 157 255 0 161 255 0 165 255 0 169 255 0 178 255 0 182 255 0 187 255 0 191 255 0 199 255 0 203 255 0 208 255 0 212 255 0 221 255 0 225 255 0 229 255 0 233 255 0 242 255 0 246 255 0 250 255 0 255 255 0 255 250 0 255 242 0 255 238 0 255 233 0 255 229 0 255 221 0 255 216 0 255 212 0 255 208 0 255 199 0 255 195 0 255 191 0 255 187 0 255 178 0 255 174 0 255 170 0 255 165 0 255 161 0 255 153 0 255 148 0 255 144 0 255 140 0 255 131 0 255 127 0 255 123 0 255 119 0 255 110 0 255 106 0 255 102 0 255 97 0 255 89 0 255 85 0 255 80 0 255 76 0 255 72 0 255 63 0 255 59 0 255 55 0 255 51 0 255 42 0 255 38 0 255 34 0 255 29 0 255 21 0 255 17 0 255 12 0 255 8 0 255 0 0 kst-2.0.3/misc/Kst Grayscale 256000644 001750 001750 00000005302 11544160206 016477 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 15 15 15 16 16 16 17 17 17 18 18 18 19 19 19 20 20 20 21 21 21 22 22 22 23 23 23 24 24 24 25 25 25 26 26 26 27 27 27 28 28 28 29 29 29 30 30 30 31 31 31 32 32 32 33 33 33 34 34 34 35 35 35 36 36 36 37 37 37 38 38 38 39 39 39 40 40 40 41 41 41 42 42 42 43 43 43 44 44 44 45 45 45 46 46 46 47 47 47 48 48 48 49 49 49 50 50 50 51 51 51 52 52 52 53 53 53 54 54 54 55 55 55 56 56 56 57 57 57 58 58 58 59 59 59 60 60 60 61 61 61 62 62 62 63 63 63 64 64 64 65 65 65 66 66 66 67 67 67 68 68 68 69 69 69 70 70 70 71 71 71 72 72 72 73 73 73 74 74 74 75 75 75 76 76 76 77 77 77 78 78 78 79 79 79 80 80 80 81 81 81 82 82 82 83 83 83 84 84 84 85 85 85 86 86 86 87 87 87 88 88 88 89 89 89 90 90 90 91 91 91 92 92 92 93 93 93 94 94 94 95 95 95 96 96 96 97 97 97 98 98 98 99 99 99 100 100 100 101 101 101 102 102 102 103 103 103 104 104 104 105 105 105 106 106 106 107 107 107 108 108 108 109 109 109 110 110 110 111 111 111 112 112 112 113 113 113 114 114 114 115 115 115 116 116 116 117 117 117 118 118 118 119 119 119 120 120 120 121 121 121 122 122 122 123 123 123 124 124 124 125 125 125 126 126 126 127 127 127 128 128 128 129 129 129 130 130 130 131 131 131 132 132 132 133 133 133 134 134 134 135 135 135 136 136 136 137 137 137 138 138 138 139 139 139 140 140 140 141 141 141 142 142 142 143 143 143 144 144 144 145 145 145 146 146 146 147 147 147 148 148 148 149 149 149 150 150 150 151 151 151 152 152 152 153 153 153 154 154 154 155 155 155 156 156 156 157 157 157 158 158 158 159 159 159 160 160 160 161 161 161 162 162 162 163 163 163 164 164 164 165 165 165 166 166 166 167 167 167 168 168 168 169 169 169 170 170 170 171 171 171 172 172 172 173 173 173 174 174 174 175 175 175 176 176 176 177 177 177 178 178 178 179 179 179 180 180 180 181 181 181 182 182 182 183 183 183 184 184 184 185 185 185 186 186 186 187 187 187 188 188 188 189 189 189 190 190 190 191 191 191 192 192 192 193 193 193 194 194 194 195 195 195 196 196 196 197 197 197 198 198 198 199 199 199 200 200 200 201 201 201 202 202 202 203 203 203 204 204 204 205 205 205 206 206 206 207 207 207 208 208 208 209 209 209 210 210 210 211 211 211 212 212 212 213 213 213 214 214 214 215 215 215 216 216 216 217 217 217 218 218 218 219 219 219 220 220 220 221 221 221 222 222 222 223 223 223 224 224 224 225 225 225 226 226 226 227 227 227 228 228 228 229 229 229 230 230 230 231 231 231 232 232 232 233 233 233 234 234 234 235 235 235 236 236 236 237 237 237 238 238 238 239 239 239 240 240 240 241 241 241 242 242 242 243 243 243 244 244 244 245 245 245 246 246 246 247 247 247 248 248 248 249 249 249 250 250 250 251 251 251 252 252 252 253 253 253 254 254 254 255 255 255kst-2.0.3/misc/IDL 37 Waves000644 001750 001750 00000005146 11544160206 015444 0ustar00synthsynth000000 000000 GIMP Palette 124 121 131 124 121 131 121 141 134 118 155 137 115 160 140 112 155 143 109 141 146 106 121 149 103 97 152 100 72 155 97 52 158 94 38 161 91 34 164 88 38 167 85 52 170 82 72 173 79 96 176 76 121 179 73 141 182 70 155 185 68 160 187 65 155 190 62 141 193 60 121 195 57 97 198 54 72 201 52 52 203 49 38 206 47 34 208 45 38 210 42 52 213 40 72 215 38 96 217 36 121 219 33 141 222 31 155 224 29 160 226 27 155 228 25 141 230 24 121 231 22 97 233 20 72 235 19 52 236 17 38 238 15 34 240 14 38 241 13 52 242 11 72 244 13 96 245 9 121 246 8 141 247 7 155 248 6 160 249 5 155 250 4 141 251 4 121 251 3 97 252 2 72 253 2 52 253 1 38 254 1 34 254 1 38 254 1 52 254 1 72 254 1 96 255 1 121 254 1 141 254 1 155 254 1 160 254 1 155 254 2 141 253 2 121 253 3 97 252 4 72 251 4 52 251 5 38 250 6 34 249 7 38 248 8 52 247 9 72 246 13 96 245 11 121 244 13 141 242 14 155 241 15 160 240 17 155 238 19 141 236 20 121 235 22 97 233 24 72 231 25 52 230 27 38 228 29 34 226 31 38 224 33 52 222 36 72 219 38 96 217 40 121 215 42 141 213 45 155 210 47 160 208 49 155 206 52 141 203 54 121 201 57 97 198 60 72 195 62 52 193 65 38 190 68 34 187 70 38 185 73 52 182 76 72 179 79 96 176 82 121 173 85 141 170 88 155 167 91 160 164 94 155 161 97 141 158 100 121 155 103 96 152 106 72 149 109 52 146 112 38 143 115 34 140 118 38 137 121 52 134 124 72 131 128 97 127 131 121 124 134 141 121 137 155 118 140 160 115 143 155 112 146 141 109 149 121 106 152 96 103 155 72 100 158 52 97 161 38 94 164 34 91 167 38 88 170 52 85 173 72 82 176 97 79 179 121 76 182 141 73 185 155 70 187 160 68 190 155 65 193 141 62 195 121 60 198 96 57 201 72 54 203 52 52 206 38 49 208 34 47 210 38 45 213 52 42 215 72 40 217 97 38 219 121 36 222 141 33 224 155 31 226 160 29 228 155 27 230 141 25 231 121 24 233 96 22 235 72 20 236 52 19 238 38 17 240 34 15 241 38 14 242 52 13 244 72 11 245 97 13 246 121 9 247 141 8 248 155 7 249 160 6 250 155 5 251 141 4 251 121 4 252 96 3 253 72 2 253 52 2 254 38 1 254 34 1 254 38 1 254 52 1 254 72 1 255 97 1 254 121 1 254 141 1 254 155 1 254 160 1 254 155 1 253 141 2 253 121 2 252 96 3 251 72 4 251 52 4 250 38 5 249 34 6 248 38 7 247 52 8 246 72 9 245 97 13 244 121 11 242 141 13 241 155 14 240 160 15 238 155 17 236 141 19 235 121 20 233 96 22 231 72 24 230 52 25 228 38 27 226 34 29 224 38 31 222 52 33 219 72 36 217 97 38 215 121 40 213 141 42 210 155 45 208 160 47 206 155 49 203 141 52 201 121 54 198 96 57 195 72 60 193 52 62 190 38 65 187 34 68 185 38 70 182 52 73 179 72 76 176 97 79 173 121 82 170 141 85 167 155 88 164 160 91 161 155 94 158 141 97 155 121 100 152 96 103 149 72 106 146 52 109 143 38 112 140 34 115 137 38 118 134 52 121 134 52 121 kst-2.0.3/misc/IDL 11 BLUE-RED000644 001750 001750 00000004565 11544160206 015512 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 1 1 0 2 2 0 3 3 0 4 4 0 8 8 0 12 12 0 16 16 0 21 21 0 25 25 0 29 29 0 33 33 0 38 38 0 42 42 0 46 46 0 50 50 0 55 55 0 59 59 0 63 63 0 67 67 0 72 72 0 76 76 0 80 80 0 84 84 0 89 89 0 93 93 0 97 97 0 101 101 0 106 106 0 110 110 0 114 114 0 118 118 0 123 123 0 127 127 0 131 131 0 135 135 0 140 140 0 144 144 0 148 148 0 152 152 0 157 157 0 161 161 0 165 165 0 169 169 0 174 174 0 178 178 0 182 182 0 186 186 0 191 191 0 195 195 0 199 199 0 203 203 0 208 208 0 212 212 0 216 216 0 220 220 0 225 225 0 229 229 0 233 233 0 237 237 0 242 242 0 246 246 0 250 250 0 255 255 0 255 255 0 251 255 0 247 255 0 243 255 0 239 255 0 235 255 0 231 255 0 227 255 0 223 255 0 219 255 0 215 255 0 211 255 0 207 255 0 203 255 0 199 255 0 195 255 0 191 255 0 187 255 0 183 255 0 179 255 0 175 255 0 170 255 0 166 255 0 162 255 0 158 255 0 154 255 0 150 255 0 146 255 0 142 255 0 138 255 0 134 255 0 130 255 0 126 255 0 122 255 0 118 255 0 114 255 0 110 255 0 106 255 0 102 255 0 98 255 0 94 255 0 90 255 0 85 255 0 81 255 0 77 255 0 73 255 0 69 255 0 65 255 0 61 255 0 57 255 0 53 255 0 49 255 0 45 255 0 41 255 0 37 255 0 33 255 0 29 255 0 25 255 0 21 255 0 17 255 0 13 255 0 9 255 0 5 255 0 0 255 0 0 255 4 0 255 8 0 255 12 0 255 16 0 255 20 0 255 24 0 255 28 0 255 32 0 255 36 0 255 40 0 255 44 0 255 48 0 255 52 0 255 56 0 255 60 0 255 64 0 255 68 0 255 72 0 255 76 0 255 80 0 255 85 0 255 89 0 255 93 0 255 97 0 255 101 0 255 105 0 255 109 0 255 113 0 255 117 0 255 121 0 255 125 0 255 129 0 255 133 0 255 137 0 255 141 0 255 145 0 255 149 0 255 153 0 255 157 0 255 161 0 255 165 0 255 170 0 255 174 0 255 178 0 255 182 0 255 186 0 255 190 0 255 194 0 255 198 0 255 202 0 255 206 0 255 210 0 255 214 0 255 218 0 255 222 0 255 226 0 255 230 0 255 234 0 255 238 0 255 242 0 255 246 0 255 250 0 255 255 0 255 255 0 255 255 0 251 255 0 247 255 0 243 255 0 239 255 0 235 255 0 231 255 0 227 255 0 223 255 0 218 255 0 214 255 0 210 255 0 206 255 0 202 255 0 198 255 0 194 255 0 190 255 0 186 255 0 181 255 0 177 255 0 173 255 0 169 255 0 165 255 0 161 255 0 157 255 0 153 255 0 149 255 0 144 255 0 140 255 0 136 255 0 132 255 0 128 255 0 124 255 0 120 255 0 116 255 0 112 255 0 107 255 0 103 255 0 99 255 0 95 255 0 91 255 0 87 255 0 83 255 0 79 255 0 75 255 0 70 255 0 66 255 0 62 255 0 58 255 0 54 255 0 50 255 0 46 255 0 42 255 0 38 255 0 33 255 0 29 255 0 25 255 0 21 255 0 17 255 0 13 255 0 9 255 0 5 255 0 0 255 0 0 kst-2.0.3/misc/IDL 03 RED-Temperature000644 001750 001750 00000004374 11544160206 017257 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 1 0 0 2 0 0 4 0 0 5 0 0 7 0 0 8 0 0 10 0 0 11 0 0 13 0 0 14 0 0 15 0 0 17 0 0 18 0 0 20 0 0 21 0 0 23 0 0 24 0 0 26 0 0 27 0 0 28 0 0 30 0 0 31 0 0 33 0 0 34 0 0 36 0 0 37 0 0 39 0 0 40 0 0 42 0 0 43 0 0 44 0 0 46 0 0 47 0 0 49 0 0 50 0 0 52 0 0 53 0 0 55 0 0 56 0 0 57 0 0 59 0 0 60 0 0 62 0 0 63 0 0 65 0 0 66 0 0 68 0 0 69 0 0 70 0 0 72 0 0 73 0 0 75 0 0 76 0 0 78 0 0 79 0 0 81 0 0 82 0 0 84 0 0 85 0 0 86 0 0 88 0 0 89 0 0 91 0 0 92 0 0 94 0 0 95 0 0 97 0 0 98 0 0 99 0 0 101 0 0 102 0 0 104 0 0 105 0 0 107 0 0 108 0 0 110 0 0 111 0 0 113 0 0 114 0 0 115 0 0 117 0 0 118 0 0 120 0 0 121 0 0 123 0 0 124 0 0 126 0 0 127 0 0 128 0 0 130 0 0 131 0 0 133 0 0 134 0 0 136 0 0 137 0 0 139 0 0 140 0 0 141 0 0 143 0 0 144 0 0 146 0 0 147 0 0 149 0 0 150 0 0 152 0 0 153 0 0 155 0 0 156 0 0 157 0 0 159 0 0 160 0 0 162 0 0 163 0 0 165 0 0 166 0 0 168 0 0 169 0 0 170 0 0 172 0 0 173 0 0 175 1 0 176 3 0 178 5 0 179 7 0 181 9 0 182 11 0 184 13 0 185 15 0 186 17 0 188 18 0 189 20 0 191 22 0 192 24 0 194 26 0 195 28 0 197 30 0 198 32 0 199 34 0 201 35 0 202 37 0 204 39 0 205 41 0 207 43 0 208 45 0 210 47 0 211 49 0 212 51 0 214 52 0 215 54 0 217 56 0 218 58 0 220 60 0 221 62 0 223 64 0 224 66 0 226 68 0 227 69 0 228 71 0 230 73 0 231 75 0 233 77 0 234 79 0 236 81 0 237 83 0 239 85 0 240 86 0 241 88 0 243 90 0 244 92 0 246 94 0 247 96 0 249 98 0 250 100 0 252 102 0 253 103 0 255 105 0 255 107 0 255 109 0 255 111 0 255 113 0 255 115 0 255 117 0 255 119 0 255 120 0 255 122 0 255 124 0 255 126 0 255 128 0 255 130 0 255 132 0 255 134 3 255 136 7 255 137 11 255 139 15 255 141 19 255 143 23 255 145 27 255 147 31 255 149 35 255 151 39 255 153 43 255 154 47 255 156 51 255 158 54 255 160 58 255 162 62 255 164 66 255 166 70 255 168 74 255 170 78 255 171 82 255 173 86 255 175 90 255 177 94 255 179 98 255 181 102 255 183 105 255 185 109 255 187 113 255 188 117 255 190 121 255 192 125 255 194 129 255 196 133 255 198 137 255 200 141 255 202 145 255 204 149 255 205 153 255 207 156 255 209 160 255 211 164 255 213 168 255 215 172 255 217 176 255 219 180 255 221 184 255 222 188 255 224 192 255 226 196 255 228 200 255 230 204 255 232 207 255 234 211 255 236 215 255 238 219 255 239 223 255 241 227 255 243 231 255 245 235 255 247 239 255 249 243 255 251 247 255 253 251 255 255 255 kst-2.0.3/misc/netcdf-windows/README.txt000644 001750 001750 00000001752 11544160206 020261 0ustar00synthsynth000000 000000 This folder contains files needed for building netCDF on Windows. (netCDF 3 only, no HDF5 support) Build instructions: - Get netCDF source code from http://www.unidata.ucar.edu/software/netcdf/ (latest tested release: 4.1.1, 2010/05) - Extract netCDF sources, eg. c:\netcdf-sources - Copy this netcdf-windows folder into the netCDF sources, eg. c:\netcdf-sources\netcdf-windows - Make a build folder, eg. c:\netcdf-build - Build netCDF in this folder with CMake (http://www.cmake.org): * cd c:\netcdf-build * MSVC : cmake ..\netcdf-sources\netcdf-windows -G"Visual Studio 9 2008" MinGW: cmake ..\netcdf-sources\netcdf-windows -G"MinGW Makefiles" * MSVC : build and install (build INSTALL project) with Visual Studio MinGW: mingw32-make & mingw32-make install - Set environment variable NETCDFDIR to 'installed' folder: set NETCDFDIR=c:\netcdf-build\installed - qmake will detect netCDF and enables netCDF on Windows. TODO: Do real checks for config.h, no HDF5 support kst-2.0.3/misc/netcdf-windows/config-msvc.h000644 001750 001750 00000032542 11544160206 021150 0ustar00synthsynth000000 000000 /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* What sort of HTTP client is this? */ /* #undef CNAME */ /* Should the subprocess compression for Server3 be includes? */ /* #undef COMPRESSION_FOR_SERVER3 */ /* default chunk cache nelems. */ #define CHUNK_CACHE_NELEMS 1000 /* default chunk cache preemption policy. */ #define CHUNK_CACHE_PREEMPTION 0.75 /* default chunk cache size in bytes. */ #define CHUNK_CACHE_SIZE 32000000 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Client version number */ /* #undef CVER */ /* Define to 1 if using `alloca.c'. */ /* #undef C_ALLOCA */ /* What DAP version is supported? */ /* #undef DAP_PROTOCOL_VERSION */ /* dbyte */ /* #undef DBYTE */ /* dfloat32 */ /* #undef DFLOAT32 */ /* dfloat64 */ /* #undef DFLOAT64 */ /* dint16 */ /* #undef DINT16 */ /* int32 */ /* #undef DINT32 */ /* set this only when building a DLL under MinGW */ /* #undef DLL_NETCDF */ /* uint16 */ /* #undef DUINT16 */ /* uint32 */ /* #undef DUINT32 */ /* Client name and version combined */ /* #undef DVR */ /* Should all the classes run ConstraintEvaluator::eval()? */ /* #undef EVAL */ /* if true, run extra tests which may not work with HDF5 beta release */ /* #undef EXTRA_TESTS */ /* use HDF5 1.6 API */ #define H5_USE_16_API 1 /* Define to 1 if you have the `alarm' function. */ /* #undef HAVE_ALARM */ /* Define to 1 if you have `alloca', as a function or macro. */ /*#define HAVE_ALLOCA 1*/ /* Define to 1 if you have and it should be used (not on Ultrix). */ /*#define HAVE_ALLOCA_H 1*/ /* Define to 1 if you have the `atexit' function. */ /* #undef HAVE_ATEXIT */ /* Define to 1 if you have the `bzero' function. */ /* #undef HAVE_BZERO */ /* Define to 1 if you have the declaration of `isfinite', and to 0 if you don't. */ /*#define HAVE_DECL_ISFINITE 1*/ /* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. */ /*#define HAVE_DECL_ISINF 1*/ /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. */ /*#define HAVE_DECL_ISNAN 1*/ /* Define to 1 if you have the declaration of `signbit', and to 0 if you don't. */ #define HAVE_DECL_SIGNBIT 1 /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_DIRENT_H */ /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* #undef HAVE_DOPRNT */ /* Define to 1 if you have the `dup2' function. */ /* #undef HAVE_DUP2 */ /* Define to 1 if you have the header file. */ /* #undef HAVE_FCNTL_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_FLOAT_H */ /* Define to 1 if you have the `floor' function. */ /* #undef HAVE_FLOOR */ /* Define to 1 if you have the `getcwd' function. */ /* #undef HAVE_GETCWD */ /* Define to 1 if you have the `getpagesize' function. */ /* #undef HAVE_GETPAGESIZE */ /* Define to 1 if you have the header file. */ //#define HAVE_HDF5_H 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `hdf5' library (-lhdf5). */ //#define HAVE_LIBHDF5 1 /* Define to 1 if you have the `hdf5_hl' library (-lhdf5_hl). */ //#define HAVE_LIBHDF5_HL 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_LIMITS_H */ /* Define to 1 if you have the `localtime_r' function. */ /* #undef HAVE_LOCALTIME_R */ /* Define to 1 if the system has the type `long long int'. */ #define HAVE_LONG_LONG_INT 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_MALLOC_H */ /* Define to 1 if you have the `memchr' function. */ /* #undef HAVE_MEMCHR */ /* Define to 1 if you have the `memmove' function. */ /* #undef HAVE_MEMMOVE */ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `memset' function. */ /* #undef HAVE_MEMSET */ /* Define to 1 if you have the `mktime' function. */ /* #undef HAVE_MKTIME */ /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_NDIR_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_NETINET_IN_H */ /* Define to 1 if you have the `pow' function. */ /* #undef HAVE_POW */ /* Define to 1 if the system has the type `ptrdiff_t'. */ #define HAVE_PTRDIFF_T 1 /* Define to 1 if you have the `putenv' function. */ /* #undef HAVE_PUTENV */ /* Define to 1 if you have the `regcomp' function. */ /* #undef HAVE_REGCOMP */ /* Define to 1 if you have the `setenv' function. */ /* #undef HAVE_SETENV */ /* Define to 1 if the system has the type `ssize_t'. */ /*#define HAVE_SSIZE_T 1*/ /* Define to 1 if you have the header file. */ /* #undef HAVE_SSTREAM */ /* Define to 1 if stdbool.h conforms to C99. */ /*#define HAVE_STDBOOL_H 1*/ /* Define to 1 if you have the header file. */ /* #undef HAVE_STDDEF_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strchr' function. */ /* #undef HAVE_STRCHR */ /* Define to 1 if you have the `strerror' function. */ #define HAVE_STRERROR 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strlcat' function. */ /*#define HAVE_STRLCAT 1*/ /* Define to 1 if you have the `strrchr' function. */ /* #undef HAVE_STRRCHR */ /* Define to 1 if you have the `strstr' function. */ /* #undef HAVE_STRSTR */ /* Define to 1 if you have the `strtol' function. */ /* #undef HAVE_STRTOL */ /* Define to 1 if you have the `strtoul' function. */ /* #undef HAVE_STRTOUL */ /* Define to 1 if `st_blksize' is member of `struct stat'. */ /*#define HAVE_STRUCT_STAT_ST_BLKSIZE 1*/ /* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */ /*#define HAVE_ST_BLKSIZE 1*/ /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_SYS_DIR_H */ /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_SYS_NDIR_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_PARAM_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_TIME_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have that is POSIX.1 compatible. */ /* #undef HAVE_SYS_WAIT_H */ /* Define to 1 if you have the `timegm' function. */ /* #undef HAVE_TIMEGM */ /* Define to 1 if the system has the type `uchar'. */ /* #undef HAVE_UCHAR */ /* Define to 1 if you have the header file. */ /*#define HAVE_UNISTD_H 1*/ /* Added to fool ncgen. */ #define YY_NO_UNISTD_H 1 /* Define to 1 if the system has the type `unsigned long long int'. */ #define HAVE_UNSIGNED_LONG_LONG_INT 1 /* Define to 1 if you have the `vprintf' function. */ /* #undef HAVE_VPRINTF */ /* Define to 1 if the system has the type `_Bool'. */ /*#define HAVE__BOOL 1*/ /* if true, use HDF5 data conversions */ /* #undef HDF5_CONVERT */ /* do large file tests */ /* #undef LARGE_FILE_TESTS */ /* Set to the prefix directory */ /* #undef LIBDAP_ROOT */ /* if true, turn on netCDF-4 logging */ /* #undef LOGGING */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* type definition */ #define NCBYTE_T byte /* type definition */ #define NCSHORT_T integer*2 /* default */ #define NF_DOUBLEPRECISION_IS_C_DOUBLE 1 /* default */ #define NF_INT1_IS_C_SIGNED_CHAR 1 /* type thing */ #define NF_INT1_T byte /* default */ #define NF_INT2_IS_C_SHORT 1 /* type thing */ #define NF_INT2_T integer*2 /* default */ #define NF_INT_IS_C_INT 1 /* default */ #define NF_REAL_IS_C_FLOAT 1 /* no IEEE float on this platform */ /* #undef NO_IEEE_FLOAT */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* do not build the netCDF version 2 API */ /* #undef NO_NETCDF_2 */ /* no stdlib.h */ /* #undef NO_STDLIB_H */ /* no sys_types.h */ /* #undef NO_SYS_TYPES_H */ /* Name of package */ #define PACKAGE "netcdf" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "support@unidata.ucar.edu" /* Define to the full name of this package. */ #define PACKAGE_NAME "netCDF" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "netCDF 4.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "netcdf" /* Define to the version of this package. */ #define PACKAGE_VERSION "4.1.1" /* Define as the return type of signal handlers (`int' or `void'). */ /* #undef RETSIGTYPE */ /* The size of `char', as computed by sizeof. */ /* #undef SIZEOF_CHAR */ /* The size of `double', as computed by sizeof. */ #define SIZEOF_DOUBLE 8 /* The size of `float', as computed by sizeof. */ #define SIZEOF_FLOAT 4 /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `int16_t', as computed by sizeof. */ /* #undef SIZEOF_INT16_T */ /* The size of `int32_t', as computed by sizeof. */ /* #undef SIZEOF_INT32_T */ /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `off_t', as computed by sizeof. */ #define SIZEOF_OFF_T 8 /* The size of `short', as computed by sizeof. */ #define SIZEOF_SHORT 2 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `uint16_t', as computed by sizeof. */ /* #undef SIZEOF_UINT16_T */ /* The size of `uint32_t', as computed by sizeof. */ /* #undef SIZEOF_UINT32_T */ /* The size of `uint8_t', as computed by sizeof. */ /* #undef SIZEOF_UINT8_T */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Place to put very large netCDF test files. */ #define TEMP_LARGE "." /* Define to 1 if you can safely include both and . */ /* #undef TIME_WITH_SYS_TIME */ /* if true, build DAP Client */ /* #undef USE_DAP */ /* set this to use extreme numbers in tests */ #define USE_EXTREME_NUMBERS 1 /* if true, build netCDF-4 */ //#define USE_NETCDF4 1 /* if true, parallel netCDF-4 is in use */ /* #undef USE_PARALLEL */ /* if true, compile in parallel netCDF-4 based on MPI/IO */ /* #undef USE_PARALLEL_MPIO */ /* if true, compile in parallel netCDF-4 based on MPI/POSIX */ /* #undef USE_PARALLEL_POSIX */ /* if true, build libsrc code with renamed API functions */ #define USE_RENAMEV3 1 /* if true, compile in zlib compression in netCDF-4 variables */ #define USE_ZLIB 1 /* Version number of package */ #define VERSION "4.1.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ #if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 #elif ! defined __LITTLE_ENDIAN__ /* # undef WORDS_BIGENDIAN */ #endif /* xdr float32 */ /* #undef XDR_FLOAT32 */ /* xdr float64 */ /* #undef XDR_FLOAT64 */ /* xdr int16 */ /* #undef XDR_INT16 */ /* xdr int32 */ /* #undef XDR_INT32 */ /* xdr uint16 */ /* #undef XDR_UINT16 */ /* xdr uint32 */ /* #undef XDR_UINT32 */ /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ /* Needed by HPUX with c89 compiler. */ /* #undef _HPUX_SOURCE */ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to 1 if type `char' is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ /* # undef __CHAR_UNSIGNED__ */ #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Turned on by netCDF configure. */ /* #undef f2cFortran */ /* Turned on by netCDF configure. */ /* #undef gFortran */ /* Define to `long int' if does not define. */ /* #undef off_t */ /* Turned on by netCDF configure. */ /*#define pgiFortran 1*/ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ /* #undef volatile */ /* Shorthand for gcc's unused attribute feature */ #if defined(__GNUG__) || defined(__GNUC__) #define not_used __attribute__ ((unused)) #else #define not_used #endif /* __GNUG__ || __GNUC__ */ /* I added the following to this config.h file by hand, after being abducted by aliens last week in Kansas. (All Hail Zorlock, Mighty Destroyer of Worlds!) */ #include #include #define lseek _lseeki64 #define off_t __int64 #define _off_t __int64 #define _OFF_T_DEFINED #define snprintf sprintf_s kst-2.0.3/misc/netcdf-windows/CMakeLists.txt000644 001750 001750 00000003575 11544160206 021330 0ustar00synthsynth000000 000000 cmake_minimum_required(VERSION 2.8) project(netcdf) if(netcdf_sources) set(TOP_DIR ${netcdf_sources}) else() set(TOP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) endif() if(netcdf_install_prefix) set(CMAKE_INSTALL_PREFIX ${netcdf_install_prefix} CACHE PATH "User's choice for install prefix" FORCE) set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) endif() if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/INSTALLED CACHE PATH "Kst's default install prefix" FORCE) endif() message(STATUS) message(STATUS "Using netCDF soures from: ${TOP_DIR}") message(STATUS "Installing netCDF at : ${CMAKE_INSTALL_PREFIX}") message(STATUS) if(MSVC) add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DNOMINMAX) # add here warnings which should produce an error /weXXXX set(MSVC_W_ERROR "/we4101 /we4189") # add here warnings which should be disabled /wdXXXX set(MSVC_W_DISABLE "/wd4288 /wd4355 /wd4800 /wd4996 /wd4311 /wd4312 /wd4505 /wd4267 /wd4512 /wd4245 /wd4127 /wd4180 /wd4231") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Wp64 ${MSVC_W_ERROR} ${MSVC_W_DISABLE}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Wp64 ${MSVC_W_ERROR} ${MSVC_W_DISABLE}") set(CMAKE_DEBUG_POSTFIX d) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-msvc.h ${CMAKE_BINARY_DIR}/config.h COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/inttypes.h ${CMAKE_BINARY_DIR}/inttypes.h COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/stdint.h ${CMAKE_BINARY_DIR}/stdint.h COPYONLY) endif() if(MINGW) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-mingw.h ${CMAKE_BINARY_DIR}/config.h COPYONLY) endif() add_definitions(-D_FILE_OFFSET_BITS=64) include_directories(${CMAKE_BINARY_DIR}) if (NOT CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/installed) endif() add_subdirectory(libsrc) add_subdirectory(cxx) kst-2.0.3/misc/netcdf-windows/libsrc/CMakeLists.txt000644 001750 001750 00000001554 11544160206 022601 0ustar00synthsynth000000 000000 project( libsrc ) set(SOURCES ${TOP_DIR}/libsrc/attr.c ${TOP_DIR}/libsrc/ncx.c ${TOP_DIR}/libsrc/putget.c ${TOP_DIR}/libsrc/dim.c ${TOP_DIR}/libsrc/error.c ${TOP_DIR}/libsrc/libvers.c ${TOP_DIR}/libsrc/nc.c ${TOP_DIR}/libsrc/string.c ${TOP_DIR}/libsrc/v1hpg.c ${TOP_DIR}/libsrc/var.c ${TOP_DIR}/libsrc/utf8proc.c ${TOP_DIR}/libsrc/posixio.c ) set(HEADERS ${TOP_DIR}/libsrc/fbits.h ${TOP_DIR}/libsrc/nc.h ${TOP_DIR}/libsrc/ncio.h ${TOP_DIR}/libsrc/ncx.h ${TOP_DIR}/libsrc/netcdf.h ${TOP_DIR}/libsrc/onstack.h ${TOP_DIR}/libsrc/rnd.h ${TOP_DIR}/libsrc/netcdf3.h ${TOP_DIR}/libsrc/utf8proc.h ${TOP_DIR}/libsrc/utf8proc_data.h ${TOP_DIR}/libsrc/rename.h ) include_directories(${TOP_DIR}/libsrc) add_library(netcdf STATIC ${SOURCES} ${HEADERS}) install(FILES ${TOP_DIR}/libsrc/netcdf.h DESTINATION include) install(TARGETS netcdf DESTINATION lib) kst-2.0.3/misc/netcdf-windows/config-mingw.h000644 001750 001750 00000026434 11544160206 021324 0ustar00synthsynth000000 000000 /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* default file chunk cache nelems. */ #define CHUNK_CACHE_NELEMS 1009 /* default file chunk cache preemption policy. */ #define CHUNK_CACHE_PREEMPTION 0.75 /* default file chunk cache size in bytes. */ #define CHUNK_CACHE_SIZE 4194304 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define to 1 if using `alloca.c'. */ /* #undef C_ALLOCA */ /* num chunks in default per-var chunk cache. */ #define DEFAULT_CHUNKS_IN_CACHE 10 /* default chunk size in bytes */ #define DEFAULT_CHUNK_SIZE 4194304 /* set this only when building a DLL under MinGW */ /* #undef DLL_NETCDF */ /* if true, run extra tests which may not work yet */ /* #undef EXTRA_TESTS */ /* use HDF5 1.6 API */ /* #undef H5_USE_16_API */ /* Define to 1 if you have `alloca', as a function or macro. */ #define HAVE_ALLOCA 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ #define HAVE_ALLOCA_H 1 /* Define to 1 if you have the header file. */ #define HAVE_CTYPE_H 1 /* Define to 1 if you have the declaration of `isfinite', and to 0 if you don't. */ #define HAVE_DECL_ISFINITE 1 /* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. */ #define HAVE_DECL_ISINF 1 /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. */ #define HAVE_DECL_ISNAN 1 /* Define to 1 if you have the declaration of `signbit', and to 0 if you don't. */ #define HAVE_DECL_SIGNBIT 1 /* Define to 1 if you have the header file, and it defines `DIR'. */ #define HAVE_DIRENT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* #undef HAVE_DOPRNT */ /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `fsync' function. */ #define HAVE_FSYNC 1 /* Define to 1 if you have the header file. */ #define HAVE_GETOPT_H 1 /* Define to 1 if you have the `getrlimit' function. */ #define HAVE_GETRLIMIT 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_HDF5_H */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `hdf5' library (-lhdf5). */ /* #undef HAVE_LIBHDF5 */ /* Define to 1 if you have the `hdf5_hl' library (-lhdf5_hl). */ /* #undef HAVE_LIBHDF5_HL */ /* Define to 1 if you have the `mfhdf' library (-lmfhdf). */ /* #undef HAVE_LIBMFHDF */ /* Define to 1 if you have the header file. */ #define HAVE_LOCALE_H 1 /* Define to 1 if the system has the type `long long int'. */ /* #undef HAVE_LONG_LONG_INT */ /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_MFHDF_H */ /* Define to 1 if you have the `mktemp' function. */ #define HAVE_MKTEMP 1 /* Define to 1 if you have the `MPI_Comm_f2c' function. */ /* #undef HAVE_MPI_COMM_F2C */ /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_NDIR_H */ /* Define to 1 if the system has the type `ptrdiff_t'. */ #define HAVE_PTRDIFF_T 1 /* no rpc/types.h */ #define HAVE_RPC_TYPES_H /**/ /* no rpc/xdr.h */ #define HAVE_RPC_XDR_H /**/ /* Define to 1 if you have the `snprintf' function. */ #define HAVE_SNPRINTF 1 /* Define to 1 if the system has the type `ssize_t'. */ #define HAVE_SSIZE_T 1 /* Define to 1 if you have the header file. */ #define HAVE_STDARG_H 1 /* Define to 1 if stdbool.h conforms to C99. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `strcasecmp' function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the `strcat' function. */ #define HAVE_STRCAT 1 /* Define to 1 if you have the `strchr' function. */ #define HAVE_STRCHR 1 /* Define to 1 if you have the `strcpy' function. */ #define HAVE_STRCPY 1 /* Define to 1 if you have the `strdup' function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the `strerror' function. */ #define HAVE_STRERROR 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strlcat' function. */ /* #undef HAVE_STRLCAT */ /* Define to 1 if you have the `strrchr' function. */ #define HAVE_STRRCHR 1 /* Define to 1 if `st_blksize' is a member of `struct stat'. */ #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 /* Define to 1 if your `struct stat' has `st_blksize'. Deprecated, use `HAVE_STRUCT_STAT_ST_BLKSIZE' instead. */ //#define HAVE_ST_BLKSIZE 1 /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_SYS_DIR_H */ /* Define to 1 if you have the header file, and it defines `DIR'. */ /* #undef HAVE_SYS_NDIR_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have that is POSIX.1 compatible. */ #define HAVE_SYS_WAIT_H 1 /* Define to 1 if the system has the type `uchar'. */ /* #undef HAVE_UCHAR */ /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if the system has the type `unsigned long long int'. */ /* #undef HAVE_UNSIGNED_LONG_LONG_INT */ /* Define to 1 if you have the `vprintf' function. */ #define HAVE_VPRINTF 1 /* Define to 1 if the system has the type `_Bool'. */ #define HAVE__BOOL 1 /* do large file tests */ /* #undef LARGE_FILE_TESTS */ /* If true, turn on logging. */ /* #undef LOGGING */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* max size of the default per-var chunk cache. */ #define MAX_DEFAULT_CACHE_SIZE 67108864 /* type definition */ /* #undef NCBYTE_T */ /* min blocksize for posixio. */ #define NCIO_MINBLOCKSIZE 256 /* type definition */ /* #undef NCSHORT_T */ /* default */ /* #undef NF_DOUBLEPRECISION_IS_C_DOUBLE */ /* default */ /* #undef NF_INT1_IS_C_SIGNED_CHAR */ /* type thing */ /* #undef NF_INT1_T */ /* default */ /* #undef NF_INT2_IS_C_SHORT */ /* type thing */ /* #undef NF_INT2_T */ /* default */ /* #undef NF_INT_IS_C_INT */ /* default */ /* #undef NF_REAL_IS_C_FLOAT */ /* no IEEE float on this platform */ /* #undef NO_IEEE_FLOAT */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* do not build the netCDF version 2 API */ /* #undef NO_NETCDF_2 */ /* no stdlib.h */ /* #undef NO_STDLIB_H */ /* no sys_types.h */ /* #undef NO_SYS_TYPES_H */ /* Name of package */ #define PACKAGE "netcdf" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "support-netcdf@unidata.ucar.edu" /* Define to the full name of this package. */ #define PACKAGE_NAME "netCDF" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "netCDF 4.1.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "netcdf" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "4.1.1" /* The size of `double', as computed by sizeof. */ #define SIZEOF_DOUBLE 8 /* The size of `float', as computed by sizeof. */ #define SIZEOF_FLOAT 4 /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `off_t', as computed by sizeof. */ #define SIZEOF_OFF_T 8 /* The size of `short', as computed by sizeof. */ #define SIZEOF_SHORT 2 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Place to put very large netCDF test files. */ #define TEMP_LARGE "." /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* if true, build DAP Client */ /* #undef USE_DAP */ /* if true, include experimental API dispatch code */ /* #undef USE_DISPATCH */ /* set this to use extreme numbers in tests */ #define USE_EXTREME_NUMBERS 1 /* if true, include experimental fsync code */ #define USE_FSYNC 1 /* if true, use HDF4 too */ /* #undef USE_HDF4 */ /* If true, use use wget to fetch some sample HDF4 data, and then test against it. */ /* #undef USE_HDF4_FILE_TESTS */ /* if true, build netCDF-4 */ /* #undef USE_NETCDF4 */ /* if true, parallel netCDF-4 is in use */ /* #undef USE_PARALLEL */ /* if true, compile in parallel netCDF-4 based on MPI/IO */ /* #undef USE_PARALLEL_MPIO */ /* if true, compile in parallel netCDF-4 based on MPI/POSIX */ /* #undef USE_PARALLEL_POSIX */ /* if true, parallel netCDF is used */ /* #undef USE_PNETCDF */ /* if true, build libsrc code with renamed API functions */ /* #undef USE_RENAMEV3 */ /* if true, compile in szip compression in netCDF-4 variables */ /* #undef USE_SZIP */ /* if true, compile in zlib compression in netCDF-4 variables */ /* #undef USE_ZLIB */ /* Version number of package */ #define VERSION "4.1.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Number of bits in a file offset, on hosts where this is settable. */ #define _FILE_OFFSET_BITS 64 /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to 1 if type `char' is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ /* # undef __CHAR_UNSIGNED__ */ #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Turned on by netCDF configure. */ /* #undef f2cFortran */ /* Turned on by netCDF configure. */ /* #undef gFortran */ /* Define to `long int' if does not define. */ /* #undef off_t */ /* Turned on by netCDF configure. */ /* #undef pgiFortran */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ kst-2.0.3/misc/netcdf-windows/stdint.h000644 001750 001750 00000016201 11544160206 020234 0ustar00synthsynth000000 000000 // ISO C9x compliant stdint.h for Microsoft Visual Studio // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 // // Copyright (c) 2006-2008 Alexander Chemeris // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. The name of the author may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////////// #ifndef _MSC_VER // [ #error "Use this header only with Microsoft Visual C++ compilers!" #endif // _MSC_VER ] #ifndef _MSC_STDINT_H_ // [ #define _MSC_STDINT_H_ #if _MSC_VER > 1000 #pragma once #endif #include // For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' // or compiler give many errors like this: // error C2733: second C linkage of overloaded function 'wmemchr' not allowed #if (_MSC_VER < 1300) && defined(__cplusplus) extern "C++" { #endif # include #if (_MSC_VER < 1300) && defined(__cplusplus) } #endif // Define _W64 macros to mark types changing their size, like intptr_t. #ifndef _W64 # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 # define _W64 __w64 # else # define _W64 # endif #endif // 7.18.1 Integer types // 7.18.1.1 Exact-width integer types typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; // 7.18.1.2 Minimum-width integer types typedef int8_t int_least8_t; typedef int16_t int_least16_t; typedef int32_t int_least32_t; typedef int64_t int_least64_t; typedef uint8_t uint_least8_t; typedef uint16_t uint_least16_t; typedef uint32_t uint_least32_t; typedef uint64_t uint_least64_t; // 7.18.1.3 Fastest minimum-width integer types typedef int8_t int_fast8_t; typedef int16_t int_fast16_t; typedef int32_t int_fast32_t; typedef int64_t int_fast64_t; typedef uint8_t uint_fast8_t; typedef uint16_t uint_fast16_t; typedef uint32_t uint_fast32_t; typedef uint64_t uint_fast64_t; // 7.18.1.4 Integer types capable of holding object pointers #ifdef _WIN64 // [ typedef __int64 intptr_t; typedef unsigned __int64 uintptr_t; #else // _WIN64 ][ typedef _W64 int intptr_t; typedef _W64 unsigned int uintptr_t; #endif // _WIN64 ] // 7.18.1.5 Greatest-width integer types typedef int64_t intmax_t; typedef uint64_t uintmax_t; // 7.18.2 Limits of specified-width integer types #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 // 7.18.2.1 Limits of exact-width integer types #define INT8_MIN ((int8_t)_I8_MIN) #define INT8_MAX _I8_MAX #define INT16_MIN ((int16_t)_I16_MIN) #define INT16_MAX _I16_MAX #define INT32_MIN ((int32_t)_I32_MIN) #define INT32_MAX _I32_MAX #define INT64_MIN ((int64_t)_I64_MIN) #define INT64_MAX _I64_MAX #define UINT8_MAX _UI8_MAX #define UINT16_MAX _UI16_MAX #define UINT32_MAX _UI32_MAX #define UINT64_MAX _UI64_MAX // 7.18.2.2 Limits of minimum-width integer types #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST8_MAX INT8_MAX #define INT_LEAST16_MIN INT16_MIN #define INT_LEAST16_MAX INT16_MAX #define INT_LEAST32_MIN INT32_MIN #define INT_LEAST32_MAX INT32_MAX #define INT_LEAST64_MIN INT64_MIN #define INT_LEAST64_MAX INT64_MAX #define UINT_LEAST8_MAX UINT8_MAX #define UINT_LEAST16_MAX UINT16_MAX #define UINT_LEAST32_MAX UINT32_MAX #define UINT_LEAST64_MAX UINT64_MAX // 7.18.2.3 Limits of fastest minimum-width integer types #define INT_FAST8_MIN INT8_MIN #define INT_FAST8_MAX INT8_MAX #define INT_FAST16_MIN INT16_MIN #define INT_FAST16_MAX INT16_MAX #define INT_FAST32_MIN INT32_MIN #define INT_FAST32_MAX INT32_MAX #define INT_FAST64_MIN INT64_MIN #define INT_FAST64_MAX INT64_MAX #define UINT_FAST8_MAX UINT8_MAX #define UINT_FAST16_MAX UINT16_MAX #define UINT_FAST32_MAX UINT32_MAX #define UINT_FAST64_MAX UINT64_MAX // 7.18.2.4 Limits of integer types capable of holding object pointers #ifdef _WIN64 // [ # define INTPTR_MIN INT64_MIN # define INTPTR_MAX INT64_MAX # define UINTPTR_MAX UINT64_MAX #else // _WIN64 ][ # define INTPTR_MIN INT32_MIN # define INTPTR_MAX INT32_MAX # define UINTPTR_MAX UINT32_MAX #endif // _WIN64 ] // 7.18.2.5 Limits of greatest-width integer types #define INTMAX_MIN INT64_MIN #define INTMAX_MAX INT64_MAX #define UINTMAX_MAX UINT64_MAX // 7.18.3 Limits of other integer types #ifdef _WIN64 // [ # define PTRDIFF_MIN _I64_MIN # define PTRDIFF_MAX _I64_MAX #else // _WIN64 ][ # define PTRDIFF_MIN _I32_MIN # define PTRDIFF_MAX _I32_MAX #endif // _WIN64 ] #define SIG_ATOMIC_MIN INT_MIN #define SIG_ATOMIC_MAX INT_MAX #ifndef SIZE_MAX // [ # ifdef _WIN64 // [ # define SIZE_MAX _UI64_MAX # else // _WIN64 ][ # define SIZE_MAX _UI32_MAX # endif // _WIN64 ] #endif // SIZE_MAX ] // WCHAR_MIN and WCHAR_MAX are also defined in #ifndef WCHAR_MIN // [ # define WCHAR_MIN 0 #endif // WCHAR_MIN ] #ifndef WCHAR_MAX // [ # define WCHAR_MAX _UI16_MAX #endif // WCHAR_MAX ] #define WINT_MIN 0 #define WINT_MAX _UI16_MAX #endif // __STDC_LIMIT_MACROS ] // 7.18.4 Limits of other integer types #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 // 7.18.4.1 Macros for minimum-width integer constants #define INT8_C(val) val##i8 #define INT16_C(val) val##i16 #define INT32_C(val) val##i32 #define INT64_C(val) val##i64 #define UINT8_C(val) val##ui8 #define UINT16_C(val) val##ui16 #define UINT32_C(val) val##ui32 #define UINT64_C(val) val##ui64 // 7.18.4.2 Macros for greatest-width integer constants #define INTMAX_C INT64_C #define UINTMAX_C UINT64_C #endif // __STDC_CONSTANT_MACROS ] #endif // _MSC_STDINT_H_ ] kst-2.0.3/misc/netcdf-windows/inttypes.h000644 001750 001750 00000017504 11544160206 020615 0ustar00synthsynth000000 000000 // ISO C9x compliant inttypes.h for Microsoft Visual Studio // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 // // Copyright (c) 2006 Alexander Chemeris // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. The name of the author may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////////// #ifndef _MSC_VER // [ #error "Use this header only with Microsoft Visual C++ compilers!" #endif // _MSC_VER ] #ifndef _MSC_INTTYPES_H_ // [ #define _MSC_INTTYPES_H_ #if _MSC_VER > 1000 #pragma once #endif #include // 7.8 Format conversion of integer types typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; // 7.8.1 Macros for format specifiers #if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 // The fprintf macros for signed integers are: #define PRId8 "d" #define PRIi8 "i" #define PRIdLEAST8 "d" #define PRIiLEAST8 "i" #define PRIdFAST8 "d" #define PRIiFAST8 "i" #define PRId16 "hd" #define PRIi16 "hi" #define PRIdLEAST16 "hd" #define PRIiLEAST16 "hi" #define PRIdFAST16 "hd" #define PRIiFAST16 "hi" #define PRId32 "I32d" #define PRIi32 "I32i" #define PRIdLEAST32 "I32d" #define PRIiLEAST32 "I32i" #define PRIdFAST32 "I32d" #define PRIiFAST32 "I32i" #define PRId64 "I64d" #define PRIi64 "I64i" #define PRIdLEAST64 "I64d" #define PRIiLEAST64 "I64i" #define PRIdFAST64 "I64d" #define PRIiFAST64 "I64i" #define PRIdMAX "I64d" #define PRIiMAX "I64i" #define PRIdPTR "Id" #define PRIiPTR "Ii" // The fprintf macros for unsigned integers are: #define PRIo8 "o" #define PRIu8 "u" #define PRIx8 "x" #define PRIX8 "X" #define PRIoLEAST8 "o" #define PRIuLEAST8 "u" #define PRIxLEAST8 "x" #define PRIXLEAST8 "X" #define PRIoFAST8 "o" #define PRIuFAST8 "u" #define PRIxFAST8 "x" #define PRIXFAST8 "X" #define PRIo16 "ho" #define PRIu16 "hu" #define PRIx16 "hx" #define PRIX16 "hX" #define PRIoLEAST16 "ho" #define PRIuLEAST16 "hu" #define PRIxLEAST16 "hx" #define PRIXLEAST16 "hX" #define PRIoFAST16 "ho" #define PRIuFAST16 "hu" #define PRIxFAST16 "hx" #define PRIXFAST16 "hX" #define PRIo32 "I32o" #define PRIu32 "I32u" #define PRIx32 "I32x" #define PRIX32 "I32X" #define PRIoLEAST32 "I32o" #define PRIuLEAST32 "I32u" #define PRIxLEAST32 "I32x" #define PRIXLEAST32 "I32X" #define PRIoFAST32 "I32o" #define PRIuFAST32 "I32u" #define PRIxFAST32 "I32x" #define PRIXFAST32 "I32X" #define PRIo64 "I64o" #define PRIu64 "I64u" #define PRIx64 "I64x" #define PRIX64 "I64X" #define PRIoLEAST64 "I64o" #define PRIuLEAST64 "I64u" #define PRIxLEAST64 "I64x" #define PRIXLEAST64 "I64X" #define PRIoFAST64 "I64o" #define PRIuFAST64 "I64u" #define PRIxFAST64 "I64x" #define PRIXFAST64 "I64X" #define PRIoMAX "I64o" #define PRIuMAX "I64u" #define PRIxMAX "I64x" #define PRIXMAX "I64X" #define PRIoPTR "Io" #define PRIuPTR "Iu" #define PRIxPTR "Ix" #define PRIXPTR "IX" // The fscanf macros for signed integers are: #define SCNd8 "d" #define SCNi8 "i" #define SCNdLEAST8 "d" #define SCNiLEAST8 "i" #define SCNdFAST8 "d" #define SCNiFAST8 "i" #define SCNd16 "hd" #define SCNi16 "hi" #define SCNdLEAST16 "hd" #define SCNiLEAST16 "hi" #define SCNdFAST16 "hd" #define SCNiFAST16 "hi" #define SCNd32 "ld" #define SCNi32 "li" #define SCNdLEAST32 "ld" #define SCNiLEAST32 "li" #define SCNdFAST32 "ld" #define SCNiFAST32 "li" #define SCNd64 "I64d" #define SCNi64 "I64i" #define SCNdLEAST64 "I64d" #define SCNiLEAST64 "I64i" #define SCNdFAST64 "I64d" #define SCNiFAST64 "I64i" #define SCNdMAX "I64d" #define SCNiMAX "I64i" #ifdef _WIN64 // [ # define SCNdPTR "I64d" # define SCNiPTR "I64i" #else // _WIN64 ][ # define SCNdPTR "ld" # define SCNiPTR "li" #endif // _WIN64 ] // The fscanf macros for unsigned integers are: #define SCNo8 "o" #define SCNu8 "u" #define SCNx8 "x" #define SCNX8 "X" #define SCNoLEAST8 "o" #define SCNuLEAST8 "u" #define SCNxLEAST8 "x" #define SCNXLEAST8 "X" #define SCNoFAST8 "o" #define SCNuFAST8 "u" #define SCNxFAST8 "x" #define SCNXFAST8 "X" #define SCNo16 "ho" #define SCNu16 "hu" #define SCNx16 "hx" #define SCNX16 "hX" #define SCNoLEAST16 "ho" #define SCNuLEAST16 "hu" #define SCNxLEAST16 "hx" #define SCNXLEAST16 "hX" #define SCNoFAST16 "ho" #define SCNuFAST16 "hu" #define SCNxFAST16 "hx" #define SCNXFAST16 "hX" #define SCNo32 "lo" #define SCNu32 "lu" #define SCNx32 "lx" #define SCNX32 "lX" #define SCNoLEAST32 "lo" #define SCNuLEAST32 "lu" #define SCNxLEAST32 "lx" #define SCNXLEAST32 "lX" #define SCNoFAST32 "lo" #define SCNuFAST32 "lu" #define SCNxFAST32 "lx" #define SCNXFAST32 "lX" #define SCNo64 "I64o" #define SCNu64 "I64u" #define SCNx64 "I64x" #define SCNX64 "I64X" #define SCNoLEAST64 "I64o" #define SCNuLEAST64 "I64u" #define SCNxLEAST64 "I64x" #define SCNXLEAST64 "I64X" #define SCNoFAST64 "I64o" #define SCNuFAST64 "I64u" #define SCNxFAST64 "I64x" #define SCNXFAST64 "I64X" #define SCNoMAX "I64o" #define SCNuMAX "I64u" #define SCNxMAX "I64x" #define SCNXMAX "I64X" #ifdef _WIN64 // [ # define SCNoPTR "I64o" # define SCNuPTR "I64u" # define SCNxPTR "I64x" # define SCNXPTR "I64X" #else // _WIN64 ][ # define SCNoPTR "lo" # define SCNuPTR "lu" # define SCNxPTR "lx" # define SCNXPTR "lX" #endif // _WIN64 ] #endif // __STDC_FORMAT_MACROS ] // 7.8.2 Functions for greatest-width integer types // 7.8.2.1 The imaxabs function #define imaxabs _abs64 // 7.8.2.2 The imaxdiv function // This is modified version of div() function from Microsoft's div.c found // in %MSVC.NET%\crt\src\div.c #ifdef STATIC_IMAXDIV // [ static #else // STATIC_IMAXDIV ][ _inline #endif // STATIC_IMAXDIV ] imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) { imaxdiv_t result; result.quot = numer / denom; result.rem = numer % denom; if (numer < 0 && result.rem > 0) { // did division wrong; must fix up ++result.quot; result.rem -= denom; } return result; } // 7.8.2.3 The strtoimax and strtoumax functions #define strtoimax _strtoi64 #define strtoumax _strtoui64 // 7.8.2.4 The wcstoimax and wcstoumax functions #define wcstoimax _wcstoi64 #define wcstoumax _wcstoui64 #endif // _MSC_INTTYPES_H_ ] kst-2.0.3/misc/netcdf-windows/cxx/CMakeLists.txt000644 001750 001750 00000000663 11544160206 022125 0ustar00synthsynth000000 000000 project( cxx ) set(SOURCES ${TOP_DIR}/cxx/netcdf.cpp ${TOP_DIR}/cxx/ncvalues.cpp ) set(HEADERS ${TOP_DIR}/cxx/netcdfcpp.h ${TOP_DIR}/cxx/netcdf.hh ${TOP_DIR}/cxx/ncvalues.h ) include_directories( ${TOP_DIR}/cxx ${TOP_DIR}/libsrc ) add_library(netcdf_c++ STATIC ${SOURCES} ${HEADERS}) target_link_libraries(netcdf_c++ netcdf) install(FILES ${HEADERS} DESTINATION include) install(TARGETS netcdf_c++ DESTINATION lib) kst-2.0.3/misc/IDL 00 BW-Linear000644 001750 001750 00000005303 11544160206 016060 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 10 10 10 11 11 11 12 12 12 13 13 13 14 14 14 15 15 15 16 16 16 17 17 17 18 18 18 19 19 19 20 20 20 21 21 21 22 22 22 23 23 23 24 24 24 25 25 25 26 26 26 27 27 27 28 28 28 29 29 29 30 30 30 31 31 31 32 32 32 33 33 33 34 34 34 35 35 35 36 36 36 37 37 37 38 38 38 39 39 39 40 40 40 41 41 41 42 42 42 43 43 43 44 44 44 45 45 45 46 46 46 47 47 47 48 48 48 49 49 49 50 50 50 51 51 51 52 52 52 53 53 53 54 54 54 55 55 55 56 56 56 57 57 57 58 58 58 59 59 59 60 60 60 61 61 61 62 62 62 63 63 63 64 64 64 65 65 65 66 66 66 67 67 67 68 68 68 69 69 69 70 70 70 71 71 71 72 72 72 73 73 73 74 74 74 75 75 75 76 76 76 77 77 77 78 78 78 79 79 79 80 80 80 81 81 81 82 82 82 83 83 83 84 84 84 85 85 85 86 86 86 87 87 87 88 88 88 89 89 89 90 90 90 91 91 91 92 92 92 93 93 93 94 94 94 95 95 95 96 96 96 97 97 97 98 98 98 99 99 99 100 100 100 101 101 101 102 102 102 103 103 103 104 104 104 105 105 105 106 106 106 107 107 107 108 108 108 109 109 109 110 110 110 111 111 111 112 112 112 113 113 113 114 114 114 115 115 115 116 116 116 117 117 117 118 118 118 119 119 119 120 120 120 121 121 121 122 122 122 123 123 123 124 124 124 125 125 125 126 126 126 127 127 127 128 128 128 129 129 129 130 130 130 131 131 131 132 132 132 133 133 133 134 134 134 135 135 135 136 136 136 137 137 137 138 138 138 139 139 139 140 140 140 141 141 141 142 142 142 143 143 143 144 144 144 145 145 145 146 146 146 147 147 147 148 148 148 149 149 149 150 150 150 151 151 151 152 152 152 153 153 153 154 154 154 155 155 155 156 156 156 157 157 157 158 158 158 159 159 159 160 160 160 161 161 161 162 162 162 163 163 163 164 164 164 165 165 165 166 166 166 167 167 167 168 168 168 169 169 169 170 170 170 171 171 171 172 172 172 173 173 173 174 174 174 175 175 175 176 176 176 177 177 177 178 178 178 179 179 179 180 180 180 181 181 181 182 182 182 183 183 183 184 184 184 185 185 185 186 186 186 187 187 187 188 188 188 189 189 189 190 190 190 191 191 191 192 192 192 193 193 193 194 194 194 195 195 195 196 196 196 197 197 197 198 198 198 199 199 199 200 200 200 201 201 201 202 202 202 203 203 203 204 204 204 205 205 205 206 206 206 207 207 207 208 208 208 209 209 209 210 210 210 211 211 211 212 212 212 213 213 213 214 214 214 215 215 215 216 216 216 217 217 217 218 218 218 219 219 219 220 220 220 221 221 221 222 222 222 223 223 223 224 224 224 225 225 225 226 226 226 227 227 227 228 228 228 229 229 229 230 230 230 231 231 231 232 232 232 233 233 233 234 234 234 235 235 235 236 236 236 237 237 237 238 238 238 239 239 239 240 240 240 241 241 241 242 242 242 243 243 243 244 244 244 245 245 245 246 246 246 247 247 247 248 248 248 249 249 249 250 250 250 251 251 251 252 252 252 253 253 253 254 254 254 255 255 255 kst-2.0.3/misc/IDL 29 Nature000644 001750 001750 00000004764 11544160206 015623 0ustar00synthsynth000000 000000 GIMP Palette 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 105 246 234 110 251 222 114 253 210 123 244 186 127 239 175 131 235 164 135 231 153 143 224 132 147 222 122 150 219 113 157 216 95 160 214 87 163 214 79 165 213 72 170 214 59 172 215 54 174 216 49 176 218 44 179 223 37 180 226 34 180 229 32 181 237 30 182 241 29 181 246 30 181 251 31 180 248 34 179 243 37 177 237 40 174 225 49 172 218 54 170 212 59 168 205 66 163 192 79 160 186 87 157 179 95 154 173 104 147 160 122 143 154 132 139 148 142 131 137 164 127 132 175 123 127 186 119 122 198 110 113 222 105 109 234 100 105 246 96 102 251 87 96 227 82 94 214 77 92 202 68 89 177 63 88 165 59 88 153 54 88 141 46 88 118 42 89 107 38 90 96 30 93 75 26 95 65 23 97 56 19 99 47 13 104 30 13 107 22 8 110 15 5 113 9 1 120 2 0 124 7 2 127 12 5 134 19 6 138 22 6 141 24 7 145 25 8 152 27 7 155 26 7 158 25 6 164 22 5 166 19 3 169 16 2 171 12 1 175 2 3 176 2 5 178 9 8 179 15 13 180 30 16 180 38 19 180 47 26 180 65 30 179 75 34 178 85 38 176 96 46 173 118 50 171 129 54 169 141 59 166 153 68 161 177 73 158 189 77 154 202 86 148 226 91 144 239 96 140 251 100 136 246 110 128 222 114 124 210 119 120 198 127 112 175 131 108 164 135 104 153 139 100 142 147 92 122 150 88 113 154 85 104 157 81 95 163 74 79 165 71 72 168 68 66 172 62 54 174 60 49 176 57 44 177 55 40 180 51 34 180 50 32 181 48 31 182 46 29 181 45 30 181 44 31 180 44 32 179 43 37 177 43 40 176 43 44 174 44 49 170 44 59 168 45 66 165 46 72 160 47 87 157 48 95 154 49 104 150 51 113 143 53 132 139 54 142 135 55 153 127 57 175 123 59 186 119 60 198 114 61 210 105 63 234 100 64 246 96 64 251 91 65 239 82 66 214 77 67 202 73 67 189 63 67 165 59 67 153 54 67 141 50 67 129 42 66 107 38 66 96 34 65 85 30 64 75 23 62 56 19 61 47 16 60 38 13 58 22 8 56 15 5 55 9 3 53 2 0 50 7 2 48 12 3 46 16 6 43 22 6 41 24 7 39 25 7 37 26 7 34 26 7 32 25 6 30 24 6 28 22 3 25 16 2 23 12 0 22 7 3 19 2 5 17 9 8 16 15 13 15 22 16 12 38 19 11 47 23 13 56 30 8 75 34 7 85 38 6 96 42 6 107 50 4 129 54 4 141 59 3 153 63 2 165 73 1 189 77 1 202 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 82 0 214 0 0 0 255 255 255 255 255 255 kst-2.0.3/misc/IDL 32 Plasma000644 001750 001750 00000005363 11544160206 015570 0ustar00synthsynth000000 000000 GIMP Palette 2 19 7 2 19 7 3 20 11 4 22 15 5 25 19 6 29 22 7 33 26 8 38 30 9 44 34 13 51 39 11 58 43 13 65 47 14 73 51 15 81 55 16 89 59 17 98 63 18 106 67 19 115 71 21 124 75 22 132 78 23 140 82 24 148 86 25 155 90 26 162 93 27 169 97 28 175 100 30 180 103 31 184 107 32 188 110 33 191 113 34 193 116 35 194 119 36 195 122 37 194 125 38 193 128 39 191 130 39 188 133 40 184 136 41 180 139 42 175 141 43 169 144 44 162 147 45 155 150 46 148 153 46 140 156 47 132 159 48 124 162 49 115 165 50 107 169 51 98 172 52 89 176 53 81 180 54 73 184 55 65 188 56 58 192 57 51 196 58 44 201 59 38 205 60 33 210 61 29 215 62 25 220 63 22 225 65 20 230 66 19 235 67 19 241 68 19 246 70 20 251 71 22 253 72 25 248 74 29 243 75 33 237 77 38 232 78 44 227 79 51 222 81 58 217 82 65 212 84 73 207 85 81 202 86 89 198 88 98 194 89 107 190 90 115 186 92 124 182 93 132 179 94 140 176 95 148 172 97 155 170 98 162 167 99 169 165 100 175 162 101 180 160 102 184 158 103 188 157 103 191 155 104 193 154 105 194 152 106 195 151 107 194 150 107 193 148 108 191 147 108 188 146 109 184 144 110 180 143 110 175 141 111 169 140 111 162 138 112 155 136 113 148 134 113 140 132 114 132 129 114 124 126 115 115 123 116 106 120 117 98 116 117 89 113 118 81 108 119 73 104 120 65 99 121 58 94 122 51 89 123 44 83 124 38 78 125 33 72 127 29 65 128 25 59 129 22 53 131 20 46 132 19 39 134 19 32 135 19 25 137 20 18 138 22 11 140 25 5 142 29 253 143 33 246 145 38 239 147 44 233 149 51 227 150 58 221 152 65 215 154 73 210 155 81 205 157 89 200 158 98 195 160 107 191 161 115 188 163 124 184 164 132 181 166 140 178 167 148 176 168 155 174 169 162 172 170 169 171 171 175 170 172 180 169 173 184 169 174 188 168 174 191 168 175 193 168 175 194 168 176 195 169 176 194 169 177 193 169 177 191 169 178 188 170 178 184 170 178 180 170 178 175 169 179 169 169 179 162 168 179 155 167 180 148 166 180 140 164 180 132 162 181 124 160 181 115 157 182 106 154 182 98 150 183 89 146 184 81 141 184 73 136 185 65 131 186 58 125 187 51 119 188 44 112 190 38 106 191 33 98 192 29 91 194 25 83 195 22 75 197 20 67 198 19 58 200 19 50 202 19 41 204 20 33 206 22 24 208 25 16 210 29 8 212 33 255 214 38 247 216 44 239 218 51 232 220 58 225 222 65 219 224 73 213 225 81 207 227 89 202 229 98 197 231 107 193 232 115 189 234 124 186 236 132 183 237 140 181 238 148 179 239 155 178 241 162 177 242 169 177 242 175 177 243 180 178 244 184 179 245 188 180 245 191 181 246 193 183 246 194 184 246 195 186 246 194 188 246 193 190 247 191 192 247 188 193 247 184 195 247 180 196 247 175 197 247 169 198 247 162 198 247 155 198 247 148 198 247 140 197 247 132 195 247 124 193 247 115 191 248 106 188 248 98 184 248 89 180 249 81 175 250 73 169 251 65 163 251 58 156 252 51 149 254 44 142 255 38 133 254 33 125 252 29 116 251 25 107 249 22 97 247 20 87 247 20 87 kst-2.0.3/misc/IDL 27 Eos-B000644 001750 001750 00000004346 11544160206 015264 0ustar00synthsynth000000 000000 GIMP Palette 255 255 255 255 255 255 127 127 127 0 0 131 0 0 136 0 0 140 0 0 144 0 0 148 0 0 153 0 0 157 0 0 145 0 0 149 0 0 170 0 0 174 0 0 178 0 0 182 0 0 187 0 0 191 0 0 195 0 0 199 0 0 183 0 0 187 0 0 212 0 0 216 0 0 221 0 0 225 0 0 229 0 0 233 0 0 238 0 0 242 0 0 221 0 0 225 0 0 255 0 7 247 0 15 239 0 23 231 0 31 223 0 39 215 0 47 207 0 55 199 0 57 172 0 64 164 0 79 175 0 87 167 0 95 159 0 103 151 0 111 143 0 119 135 0 127 127 0 135 119 0 129 100 0 136 93 0 159 95 0 167 87 0 175 79 0 183 71 0 191 63 0 199 55 0 207 47 0 215 39 0 200 28 0 207 21 0 239 15 0 247 7 0 255 0 9 255 0 18 255 0 27 255 0 36 255 0 45 255 0 49 229 0 57 229 0 72 255 0 81 255 0 91 255 0 100 255 0 109 255 0 118 255 0 127 255 0 136 255 0 131 229 0 139 229 0 163 255 0 173 255 0 182 255 0 191 255 0 200 255 0 209 255 0 218 255 0 227 255 0 213 229 0 221 229 0 255 255 0 255 250 0 255 246 0 255 242 0 255 238 0 255 233 0 255 229 0 255 225 0 229 198 0 229 195 0 255 212 0 255 208 0 255 204 0 255 199 0 255 195 0 255 191 0 255 187 0 255 182 0 229 160 0 229 156 0 255 169 0 255 165 0 255 161 0 255 157 0 255 153 0 255 148 0 255 144 0 255 140 0 229 122 0 229 118 0 255 127 0 255 125 0 255 123 0 255 121 0 255 119 0 255 116 0 255 114 0 255 112 0 229 99 0 229 97 0 255 106 0 255 104 0 255 102 0 255 99 0 255 97 0 255 95 0 255 93 0 255 91 0 229 80 0 229 78 0 255 84 0 255 82 0 255 80 0 255 78 0 255 76 0 255 74 0 255 72 0 255 70 0 229 61 0 229 59 0 255 63 0 255 61 0 255 59 0 255 57 0 255 55 0 255 53 0 255 50 0 255 48 0 229 42 0 229 40 0 255 42 0 255 40 0 255 38 0 255 36 0 255 33 0 255 31 0 255 29 0 255 27 0 229 22 0 229 21 0 255 21 0 255 19 0 255 16 0 255 14 0 255 12 0 255 13 0 255 8 0 255 6 0 229 3 0 229 1 0 255 0 0 253 0 0 251 0 0 249 0 0 247 0 0 245 0 0 243 0 0 241 0 0 215 0 0 214 0 0 235 0 0 234 0 0 232 0 0 230 0 0 228 0 0 226 0 0 224 0 0 222 0 0 198 0 0 196 0 0 216 0 0 215 0 0 213 0 0 211 0 0 209 0 0 207 0 0 205 0 0 203 0 0 181 0 0 179 0 0 197 0 0 196 0 0 194 0 0 192 0 0 190 0 0 188 0 0 186 0 0 184 0 0 164 0 0 162 0 0 178 0 0 176 0 0 175 0 0 173 0 0 171 0 0 169 0 0 167 0 0 165 0 0 147 0 0 145 0 0 159 0 0 157 0 0 156 0 0 154 0 0 152 0 0 150 0 0 148 0 0 146 0 0 130 0 0 128 0 0 140 0 0 138 0 0 137 0 0 135 0 0 133 0 0 131 0 0 129 0 0 127 0 0 113 0 0 111 0 0 121 0 0 119 0 0 117 0 0 117 0 0 kst-2.0.3/misc/mingw-release-build-deps.bat000644 001750 001750 00000002431 11544160206 021100 0ustar00synthsynth000000 000000 ::TODO remove hardcoded paths :: TODO specify path for sources :: TODO copy cmake files to sources set KSTDEPS=q:\kst-3rdparty-win32-deps-1.0 rmdir /s/q %KSTDEPS% del CMakeCache.txt cmake ..\kst\misc\netcdf-windows -Dnetcdf_sources=Q:/netcdf/netcdf-4.1.1/netcdf-4.1.1 -G"MinGW Makefiles" -DCMAKE_VERBOSE_MAKEFILE=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%KSTDEPS% mingw32-make install/strip del CMakeCache.txt cmake Q:\getdata\getdata\cmake -G"MinGW Makefiles" -DCMAKE_VERBOSE_MAKEFILE=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%KSTDEPS% mingw32-make install/strip del CMakeCache.txt cmake ..\kst\misc\gsl-windows Q:\gsl\gsl-1.14\gsl-1.14 -G"MinGW Makefiles" -DCMAKE_VERBOSE_MAKEFILE=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%KSTDEPS% mingw32-make install/strip del CMakeCache.txt cmake ..\kst\misc\cfitsio-windows -DCFIT_DIR=Q:/cfits/cfit3250 -G"MinGW Makefiles" -DCMAKE_VERBOSE_MAKEFILE=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%KSTDEPS% mingw32-make install/strip set GETDATA_DIR=%KSTDEPS% set NETCDF_DIR=%KSTDEPS% set GSL_DIR=%KSTDEPS% set CFITSIO_DIR=%KSTDEPS% del CMakeCache.txt rmdir /s/q bin rmdir /s/q lib rmdir /s/q plugin cmake ..\kst\cmake -G"MinGW Makefiles" -Dkst_release=1 -Dkst_merge_files=1 mingw32-make mingw32-make install/strip kst-2.0.3/misc/mac-release.sh000755 001750 001750 00000000351 11544160206 016337 0ustar00synthsynth000000 000000 #!/bin/sh # $1 = path to kst/cmake # $2 = package name cmake $1 -Dkst_merge_files=1 -Dkst_3rdparty=1 -Dkst_dataobjects=1 -Dkst_install_prefix=$2 -Dkst_release=1 make -j4 #TODO Why is /build/bin/kst2 added to the dmg? make package kst-2.0.3/misc/IDL 23 Purple-Red-Stripe000644 001750 001750 00000004647 11544160206 017602 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 0 0 127 127 127 191 0 191 188 0 192 186 0 192 184 0 193 182 0 194 179 0 195 177 0 195 140 0 157 138 0 157 170 0 198 168 0 198 165 0 199 163 0 200 161 0 201 158 0 202 156 0 202 154 0 203 121 0 163 119 0 164 147 0 205 145 0 206 142 0 207 140 0 208 138 0 208 135 0 209 133 0 210 131 0 211 103 0 169 101 0 170 124 0 213 122 0 214 119 0 215 117 0 215 115 0 216 112 0 217 110 0 218 108 0 218 84 0 175 82 0 176 101 0 221 99 0 221 96 0 222 94 0 223 92 0 224 89 0 225 87 0 225 85 0 226 66 0 181 64 0 182 78 0 228 76 0 229 73 0 230 71 0 231 69 0 231 66 0 232 64 0 233 62 0 234 47 0 188 46 0 188 55 0 236 52 0 237 50 0 238 48 0 238 46 0 239 43 0 240 41 0 241 39 0 241 29 0 194 27 0 194 32 0 244 29 0 245 27 0 245 25 0 246 23 0 247 20 0 248 18 0 248 16 0 249 11 0 200 9 0 200 9 0 251 6 0 252 4 0 253 2 0 254 0 0 255 0 6 255 0 12 255 0 18 255 0 19 204 0 24 204 0 36 255 0 42 255 0 48 255 0 54 255 0 60 255 0 66 255 0 72 255 0 78 255 0 68 204 0 72 204 0 97 255 0 103 255 0 109 255 0 115 255 0 121 255 0 127 255 0 133 255 0 139 255 0 116 204 0 121 204 0 157 255 0 163 255 0 170 255 0 176 255 0 182 255 0 188 255 0 194 255 0 200 255 0 165 204 0 170 204 0 218 255 0 224 255 0 230 255 0 236 255 0 242 255 0 248 255 0 255 255 0 255 248 0 204 194 0 204 189 0 255 230 0 255 224 0 255 218 0 255 212 0 255 206 0 255 200 0 255 194 0 255 188 0 204 145 0 204 140 0 255 169 0 255 163 0 255 157 0 255 151 0 255 145 0 255 139 0 255 133 0 255 127 0 204 97 0 204 92 0 255 109 0 255 103 0 255 97 0 255 91 0 255 84 0 255 78 0 255 72 0 255 66 0 204 48 0 204 43 0 255 48 0 255 42 0 255 36 0 255 30 0 255 24 0 255 18 0 255 12 0 255 6 0 204 0 4 204 0 12 255 0 18 255 0 24 255 0 30 255 0 36 255 0 42 255 0 48 255 0 54 255 0 48 204 0 53 204 0 72 255 0 78 255 0 85 255 0 91 255 0 97 255 0 103 255 0 109 255 0 115 255 0 97 204 0 102 204 0 133 255 0 139 255 0 145 255 0 151 255 0 157 255 0 163 255 0 170 255 0 176 255 0 145 204 0 150 204 0 194 255 0 200 255 0 206 255 0 212 255 0 218 255 0 224 255 0 230 255 0 236 255 0 194 204 0 199 204 0 255 255 0 255 248 2 255 242 5 255 235 7 255 229 10 255 223 12 255 216 15 255 210 17 204 163 16 204 158 18 255 191 25 255 184 28 255 178 30 255 172 33 255 165 35 255 159 38 255 153 40 255 146 43 204 112 36 204 107 38 255 127 51 255 121 48 255 115 46 255 110 44 255 104 41 255 98 39 255 92 37 255 86 34 204 64 25 204 60 24 255 69 27 255 63 25 255 57 23 255 52 20 255 46 18 255 40 16 255 34 13 255 28 11 204 18 7 204 13 5 255 11 4 255 5 2 255 0 0 255 0 0 kst-2.0.3/misc/IDL 04 BLU-GRN-RED-YEL000644 001750 001750 00000004401 11544160206 016447 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 0 2 0 0 4 0 0 6 0 0 8 0 0 10 0 0 12 0 0 14 0 0 16 0 0 18 0 0 20 0 0 22 0 0 25 0 0 27 0 0 29 0 0 31 0 0 33 0 0 35 0 0 37 0 0 39 0 0 41 0 0 43 0 0 45 0 0 47 0 0 50 0 0 52 0 0 54 0 0 56 0 0 58 0 0 60 0 0 62 0 0 64 0 0 66 0 3 68 0 6 70 0 9 72 0 12 75 0 15 77 0 18 79 0 21 81 0 25 83 0 28 85 0 31 87 0 34 89 0 37 91 0 40 93 0 43 95 0 46 97 0 50 100 0 53 100 0 56 100 0 59 100 0 62 100 0 65 100 0 68 100 0 71 100 0 75 100 0 78 100 0 81 100 0 84 100 0 87 100 0 90 100 0 93 100 0 96 100 0 100 100 0 103 100 0 106 100 0 109 100 0 112 100 0 115 100 0 118 100 0 121 100 0 125 100 0 128 100 0 131 100 0 134 100 0 137 100 0 140 100 0 143 100 0 146 100 0 150 100 0 150 96 0 150 93 0 150 90 0 150 87 0 150 84 0 150 81 0 150 78 0 150 75 0 150 71 0 150 68 0 150 65 0 150 62 0 150 59 0 150 56 0 150 53 0 150 50 0 149 46 0 148 43 0 148 40 0 147 37 0 146 34 0 146 31 0 145 28 0 145 25 0 144 21 0 143 18 0 143 15 0 142 12 0 141 9 0 141 6 0 140 3 0 140 0 7 137 0 15 135 0 22 132 0 30 130 0 37 127 0 45 125 0 52 122 0 60 120 0 67 117 0 75 115 0 82 112 0 90 110 0 97 107 0 105 105 0 112 102 0 120 100 0 125 93 0 130 87 0 135 81 0 140 75 0 145 68 0 150 62 0 155 56 0 160 50 0 165 43 0 170 37 0 175 31 0 180 25 0 185 18 0 190 12 0 195 6 0 200 0 0 200 2 0 201 4 0 201 6 0 202 9 0 202 11 0 203 13 0 203 16 0 204 18 0 204 20 0 205 23 0 205 25 0 206 27 0 206 29 0 207 32 0 207 34 0 208 36 0 208 39 0 209 41 0 209 43 0 210 46 0 210 48 0 211 50 0 211 53 0 212 55 0 212 57 0 213 59 0 213 62 0 214 64 0 214 66 0 215 69 0 215 71 0 216 73 0 216 76 0 217 78 0 217 80 0 218 83 0 218 85 0 219 87 0 219 89 0 220 92 0 220 94 0 221 96 0 221 99 0 222 101 0 222 103 0 223 106 0 223 108 0 224 110 0 224 113 0 225 115 0 225 117 0 226 119 0 226 122 0 227 124 0 227 126 0 228 129 0 228 131 0 229 133 0 229 136 0 230 138 0 230 140 0 231 142 0 231 145 0 232 147 0 232 149 0 233 152 0 233 154 0 234 156 0 234 159 0 235 161 0 235 163 0 236 166 0 236 168 0 237 170 0 237 172 0 238 175 0 238 177 0 239 179 0 239 182 0 240 184 0 240 186 0 241 189 0 241 191 0 242 193 0 242 196 0 243 198 0 243 200 0 244 202 0 244 205 0 245 207 0 245 209 0 246 212 0 246 214 0 247 216 0 247 219 0 248 221 0 248 223 0 249 226 0 249 228 0 250 230 0 250 232 0 251 235 0 251 237 0 252 239 0 252 242 0 253 244 0 253 246 0 254 249 0 254 251 0 255 253 0 255 255 0 kst-2.0.3/misc/IDL 24 Beach000644 001750 001750 00000004322 11544160206 015350 0ustar00synthsynth000000 000000 GIMP Palette 0 251 0 0 251 0 0 249 0 0 247 0 0 245 0 0 243 0 0 241 0 0 238 0 0 236 0 0 234 0 0 232 0 0 230 0 0 228 0 0 226 0 0 224 0 0 221 0 0 219 0 0 217 0 0 215 0 0 213 0 0 211 0 0 209 0 0 206 0 0 204 0 0 202 0 0 200 0 0 198 0 0 196 0 0 194 0 0 192 0 0 189 0 0 187 0 0 185 0 0 183 0 0 181 0 0 179 0 0 177 0 0 174 0 0 172 0 0 170 0 0 168 0 0 166 0 0 164 0 0 162 0 0 160 0 0 157 0 0 155 0 0 153 0 0 151 0 0 149 0 0 147 0 0 145 0 0 142 0 0 140 0 0 138 0 0 136 0 0 134 0 0 132 0 0 130 0 0 128 0 0 128 4 0 129 8 0 131 12 0 133 17 0 134 21 0 136 25 0 138 29 0 139 34 0 141 38 0 143 42 0 145 46 0 146 51 0 148 55 0 150 59 0 151 64 0 153 68 0 155 72 0 157 76 0 158 81 0 160 85 0 162 89 0 163 93 0 165 98 0 167 102 0 168 106 0 170 110 0 172 115 0 174 119 0 175 123 0 177 128 0 179 132 0 180 136 0 182 136 0 182 136 4 177 136 8 171 136 12 165 136 17 160 136 21 154 136 25 149 136 29 143 136 34 138 136 38 132 136 42 126 136 46 121 136 51 115 136 55 110 136 59 104 136 64 99 136 68 93 136 72 88 136 76 82 136 81 76 136 85 71 136 89 65 136 93 60 136 98 54 136 102 49 136 106 43 136 110 37 136 115 32 136 119 26 136 123 21 136 128 15 136 132 13 136 136 4 76 140 0 76 76 0 76 76 0 72 76 4 68 81 8 64 85 12 60 89 17 56 93 21 52 98 25 48 102 29 44 106 34 40 110 38 36 115 42 32 119 46 28 123 51 23 128 55 19 132 59 15 136 64 11 140 68 7 145 72 3 149 76 0 153 81 0 157 81 0 157 85 0 161 89 0 164 93 0 167 98 0 170 102 0 173 106 0 177 110 0 180 115 0 183 119 0 186 123 0 189 128 0 193 132 0 196 136 0 199 140 0 202 145 0 205 149 0 209 153 0 212 157 0 215 162 0 218 162 0 218 166 0 219 170 0 220 174 0 222 179 0 223 183 0 224 187 0 225 192 0 226 196 0 227 200 0 229 204 0 230 209 0 231 213 0 232 217 0 233 221 0 234 226 0 236 230 0 237 234 0 238 238 0 239 243 0 240 0 4 0 0 8 0 0 12 0 0 17 0 0 21 0 0 25 0 0 29 0 0 34 0 0 38 0 0 42 0 0 46 0 0 51 0 0 55 0 0 59 0 0 64 0 0 68 0 0 72 0 0 76 0 0 81 0 0 81 0 0 84 0 0 88 0 0 91 0 0 95 0 0 98 0 0 102 0 0 105 0 0 109 0 0 113 0 0 116 0 0 120 0 0 123 0 0 127 0 0 130 0 0 134 0 0 137 0 0 141 0 0 145 0 0 148 0 0 152 0 0 155 0 0 159 0 0 159 0 0 162 0 0 166 0 0 170 0 0 173 0 0 177 0 0 181 0 0 184 0 0 188 0 0 192 0 0 195 0 0 199 0 0 203 0 0 206 0 0 210 0 0 214 0 0 217 0 0 221 0 0 225 0 0 228 0 0 232 0 0 236 0 0 239 0 0 0 0 0 0 0 0 0 kst-2.0.3/misc/IDL 15 STERN-Special000644 001750 001750 00000005356 11544160206 016627 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 18 1 1 36 2 3 54 3 5 72 4 7 90 5 9 108 6 11 127 7 13 145 8 15 163 9 17 181 10 19 199 11 21 217 12 23 235 13 25 254 14 27 249 15 29 244 16 31 239 17 33 234 18 35 229 19 37 223 20 39 218 21 41 213 22 43 208 23 45 203 24 47 197 25 49 192 26 51 187 27 53 182 28 55 177 29 57 172 30 59 166 31 61 161 32 63 156 33 65 151 34 67 146 35 69 140 36 71 135 37 73 130 38 75 125 39 77 120 40 79 115 41 81 109 42 83 104 43 85 99 44 87 94 45 89 89 46 91 83 47 93 78 48 95 73 49 97 68 50 99 63 51 101 58 52 103 52 53 105 47 54 107 42 55 109 37 56 111 32 57 113 26 58 115 21 59 117 16 60 119 11 61 121 6 62 123 0 63 125 64 64 127 65 65 129 66 66 131 67 67 133 68 68 135 69 69 137 70 70 139 71 71 141 72 72 143 73 73 145 74 74 147 75 75 149 76 76 151 77 77 153 78 78 155 79 79 157 80 80 159 81 81 161 82 82 163 83 83 165 84 84 167 85 85 169 86 86 171 87 87 173 88 88 175 89 89 177 90 90 179 91 91 181 92 92 183 93 93 185 94 94 187 95 95 189 96 96 191 97 97 193 98 98 195 99 99 197 100 100 199 101 101 201 102 102 203 103 103 205 104 104 207 105 105 209 106 106 211 107 107 213 108 108 215 109 109 217 110 110 219 111 111 221 112 112 223 113 113 225 114 114 227 115 115 229 116 116 231 117 117 233 118 118 235 119 119 237 120 120 239 121 121 241 122 122 243 123 123 245 124 124 247 125 125 249 126 126 251 127 127 253 128 128 255 129 129 251 130 130 247 131 131 243 132 132 238 133 133 234 134 134 230 135 135 226 136 136 221 137 137 217 138 138 213 139 139 209 140 140 204 141 141 200 142 142 196 143 143 192 144 144 187 145 145 183 146 146 179 147 147 175 148 148 170 149 149 166 150 150 162 151 151 158 152 152 153 153 153 149 154 154 145 155 155 141 156 156 136 157 157 132 158 158 128 159 159 124 160 160 119 161 161 115 162 162 111 163 163 107 164 164 102 165 165 98 166 166 94 167 167 90 168 168 85 169 169 81 170 170 77 171 171 73 172 172 68 173 173 64 174 174 60 175 175 56 176 176 51 177 177 47 178 178 43 179 179 39 180 180 34 181 181 30 182 182 26 183 183 22 184 184 17 185 185 13 186 186 9 187 187 5 188 188 0 189 189 3 190 190 7 191 191 11 192 192 15 193 193 19 194 194 22 195 195 26 196 196 30 197 197 34 198 198 38 199 199 41 200 200 45 201 201 49 202 202 53 203 203 57 204 204 60 205 205 64 206 206 68 207 207 72 208 208 76 209 209 79 210 210 83 211 211 87 212 212 91 213 213 95 214 214 98 215 215 102 216 216 106 217 217 110 218 218 114 219 219 117 220 220 121 221 221 125 222 222 129 223 223 133 224 224 137 225 225 140 226 226 144 227 227 148 228 228 152 229 229 156 230 230 159 231 231 163 232 232 167 233 233 171 234 234 175 235 235 178 236 236 182 237 237 186 238 238 190 239 239 194 240 240 197 241 241 201 242 242 205 243 243 209 244 244 213 245 245 216 246 246 220 247 247 224 248 248 228 249 249 232 250 250 235 251 251 239 252 252 243 253 253 247 254 254 251 255 255 255 kst-2.0.3/misc/IDL 34 Rainbow000644 001750 001750 00000004623 11544160206 015754 0ustar00synthsynth000000 000000 GIMP Palette 124 0 255 124 0 255 120 0 255 115 0 255 111 0 255 106 0 255 102 0 255 97 0 255 93 0 255 88 0 255 84 0 255 79 0 255 75 0 255 70 0 255 66 0 255 61 0 255 57 0 255 52 0 255 48 0 255 43 0 255 39 0 255 34 0 255 30 0 255 25 0 255 21 0 255 16 0 255 12 0 255 7 0 255 3 0 255 0 2 255 0 6 255 0 11 255 0 15 255 0 20 255 0 24 255 0 29 255 0 33 255 0 38 255 0 42 255 0 47 255 0 51 255 0 56 255 0 60 255 0 65 255 0 69 255 0 74 255 0 78 255 0 83 255 0 87 255 0 92 255 0 96 255 0 101 255 0 105 255 0 110 255 0 114 255 0 119 255 0 123 255 0 128 255 0 132 255 0 137 255 0 141 255 0 146 255 0 150 255 0 155 255 0 159 255 0 164 255 0 168 255 0 173 255 0 177 255 0 182 255 0 186 255 0 191 255 0 195 255 0 200 255 0 204 255 0 209 255 0 213 255 0 218 255 0 222 255 0 227 255 0 231 255 0 236 255 0 241 255 0 245 255 0 250 255 0 254 255 0 255 251 0 255 247 0 255 242 0 255 238 0 255 233 0 255 229 0 255 224 0 255 220 0 255 215 0 255 211 0 255 206 0 255 202 0 255 197 0 255 193 0 255 188 0 255 184 0 255 179 0 255 175 0 255 170 0 255 166 0 255 161 0 255 157 0 255 152 0 255 148 0 255 143 0 255 139 0 255 134 0 255 130 0 255 125 0 255 121 0 255 116 0 255 112 0 255 107 0 255 103 0 255 98 0 255 94 0 255 89 0 255 85 0 255 80 0 255 76 0 255 71 0 255 67 0 255 62 0 255 58 0 255 53 0 255 49 0 255 44 0 255 40 0 255 35 0 255 31 0 255 26 0 255 22 0 255 17 0 255 13 0 255 8 0 255 4 1 255 0 5 255 0 13 255 0 14 255 0 19 255 0 23 255 0 28 255 0 32 255 0 37 255 0 41 255 0 46 255 0 50 255 0 55 255 0 59 255 0 64 255 0 68 255 0 73 255 0 77 255 0 82 255 0 86 255 0 91 255 0 95 255 0 100 255 0 104 255 0 109 255 0 113 255 0 118 255 0 123 255 0 127 255 0 132 255 0 136 255 0 141 255 0 145 255 0 150 255 0 154 255 0 159 255 0 163 255 0 168 255 0 172 255 0 177 255 0 181 255 0 186 255 0 190 255 0 195 255 0 199 255 0 204 255 0 208 255 0 213 255 0 217 255 0 222 255 0 226 255 0 231 255 0 235 255 0 240 255 0 244 255 0 249 255 0 253 255 0 255 252 0 255 248 0 255 243 0 255 239 0 255 234 0 255 230 0 255 225 0 255 221 0 255 216 0 255 212 0 255 207 0 255 203 0 255 198 0 255 194 0 255 189 0 255 185 0 255 180 0 255 176 0 255 171 0 255 167 0 255 162 0 255 158 0 255 153 0 255 149 0 255 144 0 255 140 0 255 135 0 255 131 0 255 126 0 255 122 0 255 117 0 255 113 0 255 108 0 255 104 0 255 99 0 255 95 0 255 90 0 255 86 0 255 81 0 255 77 0 255 72 0 255 68 0 255 63 0 255 59 0 255 54 0 255 50 0 255 45 0 255 41 0 255 36 0 255 32 0 255 27 0 255 23 0 255 18 0 255 14 0 255 9 0 255 5 0 255 5 0 kst-2.0.3/misc/IDL 39 Rainbow-White000644 001750 001750 00000004507 11544160206 017040 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 4 0 3 9 0 7 13 0 10 18 0 14 22 0 19 27 0 23 31 0 28 36 0 32 40 0 38 45 0 43 50 0 48 58 0 59 61 0 63 64 0 68 68 0 72 69 0 77 72 0 81 74 0 86 77 0 91 79 0 95 80 0 100 82 0 104 83 0 109 84 0 118 86 0 122 87 0 127 88 0 132 86 0 136 87 0 141 87 0 145 87 0 150 85 0 154 84 0 159 84 0 163 84 0 168 79 0 177 78 0 182 77 0 186 76 0 191 71 0 195 70 0 200 68 0 204 66 0 209 60 0 214 58 0 218 55 0 223 46 0 232 43 0 236 40 0 241 36 0 245 33 0 250 25 0 255 21 0 255 16 0 255 12 0 255 4 0 255 0 0 255 0 4 255 0 16 255 0 21 255 0 25 255 0 29 255 0 38 255 0 42 255 0 46 255 0 51 255 0 55 255 0 63 255 0 67 255 0 72 255 0 84 255 0 89 255 0 93 255 0 97 255 0 106 255 0 110 255 0 114 255 0 119 255 0 127 255 0 131 255 0 135 255 0 140 255 0 152 255 0 157 255 0 161 255 0 165 255 0 174 255 0 178 255 0 182 255 0 187 255 0 195 255 0 199 255 0 203 255 0 216 255 0 220 255 0 225 255 0 229 255 0 233 255 0 242 255 0 246 255 0 250 255 0 255 255 0 255 246 0 255 242 0 255 238 0 255 225 0 255 220 0 255 216 0 255 212 0 255 203 0 255 199 0 255 195 0 255 191 0 255 187 0 255 178 0 255 174 0 255 170 0 255 157 0 255 152 0 255 148 0 255 144 0 255 135 0 255 131 0 255 127 0 255 123 0 255 114 0 255 110 0 255 106 0 255 102 0 255 89 0 255 84 0 255 80 0 255 76 0 255 67 0 255 63 0 255 59 0 255 55 0 255 46 0 255 42 0 255 38 0 255 25 0 255 21 0 255 16 0 255 12 0 255 8 0 255 0 4 255 0 8 255 0 12 255 0 21 255 0 25 255 0 29 255 0 42 255 0 46 255 0 51 255 0 55 255 0 63 255 0 67 255 0 72 255 0 76 255 0 80 255 0 89 255 0 93 255 0 97 255 0 110 255 0 114 255 0 119 255 0 123 255 0 131 255 0 135 255 0 140 255 0 144 255 0 153 255 0 157 255 0 161 255 0 165 255 0 178 255 0 182 255 0 187 255 0 191 255 0 199 255 0 203 255 0 208 255 0 212 255 0 221 255 0 225 255 0 229 255 0 242 255 0 246 255 0 250 255 0 255 255 0 255 250 0 255 242 0 255 238 0 255 233 0 255 229 0 255 221 0 255 216 0 255 212 0 255 199 0 255 195 0 255 191 0 255 187 0 255 178 0 255 174 0 255 170 0 255 165 0 255 161 0 255 153 0 255 148 0 255 144 0 255 131 0 255 127 0 255 123 0 255 119 0 255 110 0 255 106 0 255 102 0 255 97 0 255 89 0 255 85 0 255 80 0 255 76 0 255 63 0 255 59 0 255 55 0 255 51 0 255 42 0 255 38 0 255 34 0 255 29 0 255 21 0 255 17 0 255 12 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 255 255 kst-2.0.3/misc/IDL 36 Volcano000644 001750 001750 00000005033 11544160206 015752 0ustar00synthsynth000000 000000 GIMP Palette 64 35 116 64 35 116 60 40 105 57 44 94 54 49 84 51 54 74 48 58 64 45 63 55 42 67 46 40 72 38 37 76 30 35 80 24 32 84 18 30 89 12 28 93 8 26 96 5 24 100 2 22 104 0 20 108 0 19 111 0 17 115 1 16 118 3 14 121 6 13 124 13 12 127 14 11 130 20 13 133 26 9 135 33 9 137 41 8 140 50 7 142 59 7 144 68 7 145 78 7 147 88 7 148 99 7 150 109 7 151 120 7 152 131 7 152 142 8 153 153 8 153 163 9 153 174 13 153 184 11 153 193 12 153 202 13 153 211 14 152 218 15 151 226 17 150 232 18 149 238 20 148 243 22 146 247 23 145 250 25 143 252 27 141 253 30 139 253 32 137 253 34 134 251 37 132 249 39 129 246 42 126 241 44 123 236 47 120 230 50 117 224 53 113 216 56 110 208 59 106 200 63 103 190 66 99 181 70 95 171 73 91 160 77 87 150 80 83 139 84 79 128 88 74 117 92 70 106 96 66 96 100 61 85 104 57 75 109 52 65 113 47 56 117 43 47 122 38 39 126 33 31 131 29 24 136 24 18 140 19 13 145 15 9 150 13 5 155 5 2 160 1 0 165 3 0 170 7 0 175 12 1 180 16 3 186 20 5 191 25 9 196 29 14 201 33 19 207 37 25 212 41 32 218 45 40 223 49 48 229 53 57 234 56 67 240 60 76 246 63 87 251 66 97 253 69 108 247 72 119 241 75 130 236 78 140 230 80 151 224 83 162 218 85 172 213 87 182 207 89 192 201 91 201 195 92 209 189 94 217 183 95 225 178 96 231 172 97 237 166 98 242 160 99 246 154 99 249 148 99 252 143 99 253 137 99 254 131 99 253 125 99 252 120 98 249 114 97 246 108 97 242 103 95 237 97 94 231 92 93 225 86 91 217 80 89 209 75 88 201 70 86 192 64 83 182 59 81 172 53 78 162 48 76 151 43 73 140 38 70 130 33 67 119 28 64 108 23 61 97 18 57 87 13 54 76 8 50 67 3 46 57 1 42 48 5 38 40 13 34 32 15 30 25 19 26 19 23 22 14 28 17 9 32 13 5 36 9 3 40 4 1 44 0 0 48 4 0 52 9 0 56 13 2 60 18 5 63 23 9 67 27 13 70 32 18 73 37 24 77 41 31 80 46 39 83 51 47 86 55 56 89 60 65 92 64 75 94 69 85 97 73 96 100 77 106 102 82 117 104 86 128 107 90 139 109 94 150 111 98 160 113 102 171 114 105 181 116 109 190 118 112 200 119 116 208 121 119 216 122 122 224 123 125 230 124 128 236 125 131 241 126 133 246 127 136 249 128 138 251 128 140 253 129 142 253 129 144 253 129 146 252 129 147 250 129 149 247 129 150 243 129 151 238 129 152 232 129 152 226 128 153 218 127 153 211 127 153 202 126 153 193 125 153 184 124 153 174 123 152 163 122 152 153 120 151 142 119 150 131 117 149 120 116 147 109 114 146 99 112 144 88 110 142 78 108 140 68 106 138 59 103 136 50 101 133 41 99 131 33 96 128 26 93 125 20 91 122 14 88 119 13 85 116 6 82 112 3 79 109 1 75 105 0 72 101 0 69 98 0 65 94 2 62 90 5 58 86 8 54 81 12 50 77 18 47 73 24 43 68 30 39 64 38 34 60 46 30 55 55 26 50 64 22 46 74 17 41 84 13 37 94 8 32 105 8 32 105 kst-2.0.3/misc/IDL 01 Blue-White000644 001750 001750 00000004433 11544160206 016311 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 0 1 0 0 2 0 0 4 0 0 5 0 0 6 0 0 8 0 0 9 0 0 10 0 0 12 0 0 13 0 0 14 0 0 16 0 0 17 0 0 18 0 0 20 0 0 21 0 0 23 0 0 24 0 0 25 0 0 27 0 0 28 0 0 29 0 0 31 0 0 32 0 0 33 0 0 35 0 0 36 0 0 37 0 0 39 0 0 40 0 0 42 0 0 43 0 0 44 0 0 46 0 0 47 0 0 48 0 0 50 0 0 51 0 0 52 0 0 54 0 0 55 0 0 56 0 0 58 0 0 59 0 0 61 0 0 62 0 0 63 0 0 65 0 0 66 0 0 67 0 0 69 0 0 70 0 0 71 0 0 73 0 0 74 0 0 75 0 0 77 0 0 78 0 0 80 0 0 81 0 0 82 0 0 84 0 0 85 0 0 86 0 0 88 0 0 89 0 0 90 0 0 92 0 0 93 0 0 94 0 0 96 0 0 97 0 0 99 0 0 100 0 0 101 0 0 103 0 0 104 0 0 105 0 0 107 0 0 108 0 0 109 0 0 111 0 0 112 0 0 113 0 0 115 0 0 116 0 0 118 0 0 119 0 0 120 0 0 122 0 0 123 0 0 124 0 0 126 0 0 127 0 0 128 0 0 130 0 2 131 0 4 132 0 5 134 0 7 135 0 9 136 0 10 138 0 12 139 0 13 141 0 15 142 0 17 143 0 18 145 0 20 146 0 21 147 0 23 149 0 25 150 0 26 151 0 28 153 0 29 154 0 31 155 0 33 157 0 34 158 0 36 160 0 37 161 0 39 162 0 41 164 0 42 165 0 44 166 0 45 168 0 47 169 0 49 170 0 50 172 0 52 173 0 53 174 0 55 176 0 57 177 0 58 179 0 60 180 0 61 181 0 63 183 0 65 184 0 66 185 0 68 187 0 69 188 0 71 189 0 73 191 0 74 192 0 76 193 0 77 195 0 79 196 0 81 198 0 82 199 0 84 200 0 85 202 0 87 203 0 89 204 0 90 206 0 92 207 0 94 208 0 95 210 0 97 211 0 98 212 0 100 214 0 102 215 0 103 217 0 105 218 0 106 219 0 108 221 0 110 222 0 111 223 0 113 225 0 114 226 0 116 227 0 118 229 0 119 230 0 121 231 0 122 233 0 124 234 0 126 236 0 127 237 0 129 238 0 130 240 0 132 241 0 134 242 0 135 244 0 137 245 0 138 246 0 140 248 0 142 249 0 143 250 0 145 252 0 146 253 0 148 255 0 150 255 0 151 255 0 153 255 0 154 255 5 156 255 9 158 255 13 159 255 17 161 255 21 162 255 25 164 255 29 166 255 33 167 255 37 169 255 41 170 255 45 172 255 49 174 255 53 175 255 57 177 255 61 179 255 65 180 255 69 182 255 73 183 255 77 185 255 81 187 255 85 188 255 90 190 255 94 191 255 98 193 255 102 195 255 106 196 255 110 198 255 114 199 255 118 201 255 122 203 255 126 204 255 130 206 255 134 207 255 138 209 255 142 211 255 146 212 255 150 214 255 154 215 255 158 217 255 162 219 255 166 220 255 170 222 255 175 223 255 179 225 255 183 227 255 187 228 255 191 230 255 195 231 255 199 233 255 203 235 255 207 236 255 211 238 255 215 239 255 219 241 255 223 243 255 227 244 255 231 246 255 235 247 255 239 249 255 243 251 255 247 252 255 251 254 255 255 255 255 kst-2.0.3/misc/IDL 12 16-Level000644 001750 001750 00000004634 11544160206 015644 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 84 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 168 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 84 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 168 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 128 0 255 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 220 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 180 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 128 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 64 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 220 190 190 220 190 190 220 190 190 220 190 190 220 190 190 221 190 190 221 190 190 221 190 190 221 190 190 221 190 190 222 190 190 222 190 190 222 190 190 222 190 190 222 190 190 223 190 190 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 kst-2.0.3/misc/IDL 09 GRN-WHT-Exp000644 001750 001750 00000004674 11544160206 016203 0ustar00synthsynth000000 000000 GIMP Palette 1 0 0 1 0 0 1 1 0 2 2 0 2 2 1 2 3 1 3 4 1 3 4 1 4 5 2 4 6 2 4 6 2 5 7 2 5 8 3 5 8 3 6 9 3 6 10 3 7 10 4 7 11 4 7 12 4 8 12 5 8 13 5 9 14 5 9 14 5 9 15 6 10 16 6 10 16 6 10 17 6 11 18 7 11 18 7 12 19 7 12 20 7 12 20 8 13 21 8 13 22 8 13 22 8 14 23 9 14 24 9 15 24 9 15 25 10 15 26 10 16 26 10 16 27 10 17 28 11 17 28 11 17 29 11 18 30 11 18 30 12 18 31 12 19 32 12 19 32 12 20 33 13 20 34 13 20 34 13 21 35 13 21 36 14 21 36 14 22 37 14 22 38 15 23 38 15 23 39 15 23 40 15 24 40 16 24 41 16 25 42 16 25 42 16 25 43 17 26 44 17 26 44 17 26 45 17 27 46 18 27 46 18 28 47 18 28 48 18 28 48 19 29 49 19 29 50 19 29 50 20 30 51 20 30 52 20 31 52 20 31 53 21 31 54 21 32 54 21 32 55 21 33 56 22 33 56 22 33 57 22 34 58 22 34 58 23 34 59 23 35 60 23 35 60 23 36 61 24 36 62 24 36 62 24 37 63 25 37 64 25 37 64 25 38 65 25 38 66 26 39 66 26 39 67 26 39 68 26 40 68 27 40 69 27 41 70 27 41 70 27 41 71 28 42 72 28 42 72 28 42 73 28 43 74 29 43 74 29 44 75 29 44 76 30 44 76 30 45 77 30 45 78 30 45 78 31 46 79 31 46 80 31 47 80 31 47 81 32 47 82 32 48 82 32 48 83 32 49 84 33 49 84 33 49 85 33 50 86 33 50 87 34 50 88 34 51 90 34 51 91 35 52 92 35 52 94 35 52 95 35 54 96 36 54 98 36 55 99 36 56 100 36 56 102 37 57 103 37 58 104 37 58 106 37 59 107 38 60 108 38 60 110 38 61 111 38 62 112 39 62 114 39 63 115 39 64 116 40 64 118 40 66 119 40 68 120 40 70 122 41 71 123 41 73 124 41 75 126 41 77 127 42 79 128 42 81 130 42 83 131 42 85 132 43 86 134 43 88 135 43 90 136 43 92 138 44 94 139 44 96 140 44 98 142 45 99 143 45 101 145 45 103 146 45 105 147 46 107 149 46 109 150 46 111 151 46 113 153 47 114 154 47 116 155 47 118 157 47 120 158 48 122 159 47 124 161 49 126 162 52 127 163 55 129 165 58 131 166 61 133 167 64 135 169 67 137 170 70 139 171 73 141 173 76 142 174 79 144 175 82 146 177 85 148 178 88 150 179 90 152 181 93 154 182 96 156 183 99 157 185 102 159 186 105 161 187 108 163 189 111 165 190 114 167 191 117 169 193 120 170 194 123 172 195 126 174 197 129 176 198 131 178 200 134 180 201 137 182 202 140 184 204 143 185 205 146 187 206 149 189 208 152 191 209 155 193 210 158 195 212 161 197 213 164 198 214 167 200 216 170 202 217 172 204 218 175 206 220 178 208 221 181 210 222 184 212 224 187 213 225 190 215 226 193 217 228 196 219 229 199 221 230 202 223 232 205 225 233 208 226 234 211 228 236 213 230 237 216 232 238 219 234 240 222 236 241 225 238 242 228 240 244 231 241 245 234 243 246 237 245 248 240 247 249 243 249 250 246 251 252 249 253 253 252 255 255 255 kst-2.0.3/misc/IDL 17 BLU-Pastel-RED000644 001750 001750 00000004505 11544160206 016633 0ustar00synthsynth000000 000000 GIMP Palette 33 0 96 33 0 96 32 0 97 31 0 99 31 0 100 30 0 101 29 0 102 28 0 104 27 0 105 26 0 106 25 0 107 24 0 108 23 0 110 22 0 111 21 0 112 20 0 113 19 0 115 17 0 116 16 0 117 15 0 118 14 0 119 12 0 121 11 0 122 13 0 123 8 0 124 7 0 125 5 0 127 4 0 128 2 0 129 1 0 130 0 0 132 0 1 133 0 3 134 0 5 135 0 6 136 0 8 138 0 13 139 0 12 140 0 13 141 0 15 143 0 17 144 0 19 145 0 21 146 0 23 147 0 25 149 0 27 150 0 29 151 0 31 152 0 33 154 0 35 155 0 37 156 0 39 157 0 42 158 0 44 160 0 46 161 0 49 162 0 51 163 0 53 164 0 56 166 0 58 167 0 60 168 0 63 169 0 65 171 0 68 172 0 71 173 0 73 174 0 76 175 0 78 177 0 81 178 0 84 179 0 87 180 0 89 182 0 92 183 0 95 184 0 98 185 0 101 186 0 104 188 0 107 189 0 110 190 0 113 191 0 116 193 0 119 194 0 122 195 0 125 196 0 128 197 0 131 199 0 134 200 0 138 201 0 141 202 0 144 203 0 148 205 0 151 206 0 154 207 0 158 208 0 161 210 0 165 211 0 168 212 0 172 213 0 175 214 0 179 216 0 182 217 0 186 218 0 190 219 0 193 221 0 197 222 0 201 223 0 205 224 0 209 225 0 212 227 0 216 228 0 220 229 0 224 230 0 228 232 0 232 233 0 234 232 0 235 230 0 236 229 0 238 227 0 239 225 0 240 223 0 241 222 0 243 220 0 244 218 0 245 216 0 246 214 0 247 212 0 249 210 0 249 208 0 246 149 0 244 142 0 241 135 0 237 127 2 232 118 4 227 111 5 223 103 7 218 95 8 214 88 13 209 81 11 205 74 13 201 67 14 196 60 15 192 53 17 188 47 18 184 40 19 180 34 20 175 28 21 171 22 29 167 22 36 163 23 42 160 24 48 156 25 53 152 26 58 148 27 61 144 28 65 141 28 68 137 29 70 133 30 72 130 30 73 126 31 74 123 31 74 119 32 74 116 32 75 116 29 75 115 28 76 113 26 76 112 25 76 110 23 77 109 22 76 104 20 77 104 18 78 103 17 79 102 16 80 101 15 81 100 14 83 99 13 84 98 12 85 97 11 86 96 13 88 95 9 89 94 8 91 93 7 92 92 6 91 88 5 94 88 5 96 88 4 98 87 3 100 86 3 102 85 2 104 85 1 106 84 0 108 83 0 109 82 0 111 80 0 112 79 0 113 78 0 115 76 0 116 75 0 117 74 0 119 73 0 120 71 0 121 70 0 123 69 0 124 68 0 125 67 0 127 66 0 128 64 0 129 63 0 131 61 0 132 58 0 133 56 0 135 54 0 136 52 0 137 49 0 138 47 0 140 45 0 141 43 0 142 41 0 144 40 0 145 38 0 146 36 0 148 34 0 149 33 0 150 31 0 152 29 0 153 28 0 154 26 0 156 25 0 157 23 0 158 22 0 160 21 0 161 19 0 162 18 0 164 17 0 165 16 0 166 14 0 168 13 0 169 12 0 170 11 0 172 13 0 173 9 0 174 8 0 175 7 0 177 7 0 178 6 0 179 5 0 181 4 0 182 4 0 183 3 0 185 2 0 186 2 0 187 1 0 189 1 0 190 0 0 191 0 0 193 0 0 193 0 0 kst-2.0.3/misc/IDL 35 Blue-Waves000644 001750 001750 00000005030 11544160206 016317 0ustar00synthsynth000000 000000 GIMP Palette 82 0 214 82 0 214 77 1 202 73 1 189 68 2 177 63 2 165 59 3 153 54 4 141 50 4 129 46 5 118 42 6 107 38 6 96 34 7 85 30 8 75 26 9 65 23 13 56 19 11 47 16 12 38 13 13 30 13 15 22 8 16 15 5 17 9 3 19 2 1 20 2 0 22 7 2 23 12 3 25 16 5 27 19 6 28 22 6 30 24 7 32 25 7 34 26 8 35 27 7 37 26 7 39 25 6 41 24 6 43 22 5 45 19 3 46 16 2 48 12 0 50 7 1 51 2 3 53 2 5 55 9 8 56 15 13 58 22 13 59 30 16 60 38 19 61 47 23 62 56 26 63 65 30 64 75 34 65 85 38 66 96 42 66 107 46 67 118 50 67 129 54 67 141 59 67 153 63 67 165 68 67 177 73 67 189 77 67 202 82 66 214 87 66 227 91 65 239 96 64 251 100 64 246 105 63 234 110 62 222 114 61 210 119 60 198 123 59 186 127 57 175 131 56 164 135 55 153 139 54 142 143 53 132 147 52 122 150 51 113 154 49 104 157 48 95 160 47 87 163 47 79 165 46 72 168 45 66 170 44 59 172 44 54 174 44 49 176 43 44 177 43 40 179 43 37 180 43 34 180 44 32 181 44 31 181 45 30 182 46 29 181 47 30 181 48 31 180 50 32 180 51 34 179 53 37 177 55 40 176 57 44 174 60 49 172 62 54 170 65 59 168 68 66 165 71 72 163 74 79 160 78 87 157 81 95 154 85 104 150 88 113 147 92 122 143 96 132 139 100 142 135 104 153 131 108 164 127 112 175 123 116 186 119 120 198 114 124 210 110 128 222 105 132 234 100 136 246 96 140 251 91 144 239 86 148 226 82 151 214 77 154 202 73 158 189 68 161 177 63 164 165 59 166 153 54 169 141 50 171 129 46 173 118 42 175 107 38 176 96 34 178 85 30 179 75 26 180 65 23 180 56 19 180 47 16 180 38 13 180 30 13 179 22 8 179 15 5 178 9 3 176 2 1 175 2 0 173 7 2 171 12 3 169 16 5 166 19 6 164 22 6 161 24 7 158 25 7 155 26 8 152 27 7 148 26 7 145 25 6 141 24 6 138 22 5 134 19 3 131 16 2 127 12 0 124 7 1 120 2 3 117 2 5 113 9 8 110 15 13 107 22 13 104 30 16 101 38 19 99 47 23 97 56 26 95 65 30 93 75 34 91 85 38 90 96 42 89 107 46 88 118 50 88 129 54 88 141 59 88 153 63 88 165 68 89 177 73 91 189 77 92 202 82 94 214 87 96 227 91 99 239 96 102 251 100 105 246 105 109 234 110 113 222 114 117 210 119 122 198 123 127 186 127 132 175 131 137 164 135 142 153 139 148 142 143 154 132 147 160 122 150 166 113 154 173 104 157 179 95 160 186 87 163 192 79 165 199 72 168 205 66 170 212 59 172 218 54 174 225 49 176 231 44 177 237 40 179 243 37 180 248 34 180 254 32 181 251 31 181 246 30 182 241 29 181 237 30 181 233 31 180 229 32 180 226 34 179 223 37 177 220 40 176 218 44 174 216 49 172 215 54 170 214 59 168 213 66 165 213 72 163 214 79 160 214 87 157 216 95 154 217 104 150 219 113 147 222 122 143 224 132 139 228 142 135 231 153 131 235 164 127 239 175 123 244 186 119 248 198 114 253 210 110 251 222 105 246 234 100 240 246 96 234 251 96 234 251 kst-2.0.3/misc/IDL 33 Blue-Red000644 001750 001750 00000004637 11544160206 015756 0ustar00synthsynth000000 000000 GIMP Palette 0 0 131 0 0 131 0 0 135 0 0 139 0 0 143 0 0 147 0 0 151 0 0 155 0 0 159 0 0 163 0 0 167 0 0 171 0 0 175 0 0 179 0 0 183 0 0 187 0 0 191 0 0 195 0 0 199 0 0 203 0 0 207 0 0 211 0 0 215 0 0 219 0 0 223 0 0 227 0 0 231 0 0 235 0 0 239 0 0 243 0 0 247 0 0 251 0 0 255 0 0 255 0 3 255 0 7 255 0 11 255 0 15 255 0 19 255 0 23 255 0 27 255 0 31 255 0 35 255 0 39 255 0 43 255 0 47 255 0 51 255 0 55 255 0 59 255 0 63 255 0 67 255 0 71 255 0 75 255 0 79 255 0 83 255 0 87 255 0 91 255 0 95 255 0 99 255 0 103 255 0 107 255 0 111 255 0 115 255 0 119 255 0 123 255 0 127 255 0 131 255 0 135 255 0 139 255 0 143 255 0 147 255 0 151 255 0 155 255 0 159 255 0 163 255 0 167 255 0 171 255 0 175 255 0 179 255 0 183 255 0 187 255 0 191 255 0 195 255 0 199 255 0 203 255 0 207 255 0 211 255 0 215 255 0 219 255 0 223 255 0 227 255 0 231 255 0 235 255 0 239 255 0 243 255 0 247 255 0 251 255 0 255 255 0 255 255 3 255 251 7 255 247 11 255 243 15 255 239 19 255 235 23 255 231 27 255 227 31 255 223 35 255 219 39 255 215 43 255 211 47 255 207 51 255 203 55 255 199 59 255 195 63 255 191 67 255 187 71 255 183 75 255 179 79 255 175 83 255 171 87 255 167 91 255 163 95 255 159 99 255 155 103 255 151 107 255 147 111 255 143 115 255 139 119 255 135 123 255 131 127 255 127 131 255 123 135 255 119 139 255 115 143 255 111 147 255 107 151 255 103 155 255 99 159 255 95 163 255 91 167 255 87 171 255 83 175 255 79 179 255 75 183 255 71 187 255 67 191 255 63 195 255 59 199 255 55 203 255 51 207 255 47 211 255 43 215 255 39 219 255 35 223 255 31 227 255 27 231 255 23 235 255 19 239 255 15 243 255 11 247 255 7 251 255 3 255 255 0 255 251 0 255 247 0 255 243 0 255 239 0 255 235 0 255 231 0 255 227 0 255 223 0 255 219 0 255 215 0 255 211 0 255 207 0 255 203 0 255 199 0 255 195 0 255 191 0 255 187 0 255 183 0 255 179 0 255 175 0 255 171 0 255 167 0 255 163 0 255 159 0 255 155 0 255 151 0 255 147 0 255 143 0 255 139 0 255 135 0 255 131 0 255 127 0 255 123 0 255 119 0 255 115 0 255 111 0 255 107 0 255 103 0 255 99 0 255 95 0 255 91 0 255 87 0 255 83 0 255 79 0 255 75 0 255 71 0 255 67 0 255 63 0 255 59 0 255 55 0 255 51 0 255 47 0 255 43 0 255 39 0 255 35 0 255 31 0 255 27 0 255 23 0 255 19 0 255 15 0 255 11 0 255 7 0 255 3 0 255 0 0 250 0 0 246 0 0 241 0 0 237 0 0 233 0 0 228 0 0 224 0 0 219 0 0 215 0 0 211 0 0 206 0 0 202 0 0 197 0 0 193 0 0 189 0 0 184 0 0 180 0 0 175 0 0 171 0 0 167 0 0 162 0 0 158 0 0 153 0 0 149 0 0 145 0 0 140 0 0 136 0 0 131 0 0 131 0 0 kst-2.0.3/misc/IDL 31 Peppermint000644 001750 001750 00000005016 11544160206 016470 0ustar00synthsynth000000 000000 GIMP Palette 0 0 80 0 0 80 0 0 160 0 0 240 80 0 0 80 0 80 80 0 160 80 0 240 160 0 0 160 0 80 160 0 160 160 0 240 240 0 0 240 0 80 240 0 160 240 0 240 0 16 0 0 16 80 0 16 160 0 16 240 80 16 0 80 16 80 80 16 160 80 16 240 160 16 0 160 16 80 160 16 160 160 16 240 240 16 0 240 16 80 240 16 160 240 16 240 0 32 0 0 32 80 0 32 160 0 32 240 80 32 0 80 32 80 80 32 160 80 32 240 160 32 0 160 32 80 160 32 160 160 32 240 240 32 0 240 32 80 240 32 160 240 32 240 0 48 0 0 48 80 0 48 160 0 48 240 80 48 0 80 48 80 80 48 160 80 48 240 160 48 0 160 48 80 160 48 160 160 48 240 240 48 0 240 48 80 240 48 160 240 48 240 0 64 0 0 64 80 0 64 160 0 64 240 80 64 0 80 64 80 80 64 160 80 64 240 160 64 0 160 64 80 160 64 160 160 64 240 240 64 0 240 64 80 240 64 160 240 64 240 0 80 0 0 80 80 0 80 160 0 80 240 80 80 0 80 80 80 80 80 160 80 80 240 160 80 0 160 80 80 160 80 160 160 80 240 240 80 0 240 80 80 240 80 160 240 80 240 0 96 0 0 96 80 0 96 160 0 96 240 80 96 0 80 96 80 80 96 160 80 96 240 160 96 0 160 96 80 160 96 160 160 96 240 240 96 0 240 96 80 240 96 160 240 96 240 0 112 0 0 112 80 0 112 160 0 112 240 80 112 0 80 112 80 80 112 160 80 112 240 160 112 0 160 112 80 160 112 160 160 112 240 240 112 0 240 112 80 240 112 160 240 112 240 0 128 0 0 128 80 0 128 160 0 128 240 80 128 0 80 128 80 80 128 160 80 128 240 160 128 0 160 128 80 160 128 160 160 128 240 240 128 0 240 128 80 240 128 160 240 128 240 0 144 0 0 144 80 0 144 160 0 144 240 80 144 0 80 144 80 80 144 160 80 144 240 160 144 0 160 144 80 160 144 160 160 144 240 240 144 0 240 144 80 240 144 160 240 144 240 0 160 0 0 160 80 0 160 160 0 160 240 80 160 0 80 160 80 80 160 160 80 160 240 160 160 0 160 160 80 160 160 160 160 160 240 240 160 0 240 160 80 240 160 160 240 160 240 0 176 0 0 176 80 0 176 160 0 176 240 80 176 0 80 176 80 80 176 160 80 176 240 160 176 0 160 176 80 160 176 160 160 176 240 240 176 0 240 176 80 240 176 160 240 176 240 0 192 0 0 192 80 0 192 160 0 192 240 80 192 0 80 192 80 81 193 160 80 192 240 160 192 0 160 192 80 160 192 160 160 192 240 240 192 0 240 192 80 240 192 160 240 192 240 0 208 0 0 208 80 0 208 160 0 208 240 80 208 0 80 208 80 80 208 160 80 208 240 160 208 0 160 208 80 160 208 160 160 208 240 240 208 0 240 208 80 240 208 160 240 208 240 0 224 0 0 224 80 0 224 160 0 224 240 80 224 0 80 224 80 80 224 160 80 224 240 160 224 0 160 224 80 160 224 160 160 224 240 240 224 0 240 224 80 240 224 160 240 224 240 0 240 0 0 240 80 0 240 160 0 240 240 80 240 0 80 240 80 80 240 160 80 240 240 160 240 0 160 240 80 160 240 160 160 240 240 240 240 0 240 240 80 240 240 160 240 240 160 kst-2.0.3/misc/Kst Spectrum 1021000644 001750 001750 00000023070 11544160206 016440 0ustar00synthsynth000000 000000 GIMP Palette 0 0 255 0 1 255 0 2 255 0 3 255 0 4 255 0 5 255 0 6 255 0 7 255 0 8 255 0 9 255 0 10 255 0 11 255 0 12 255 0 13 255 0 14 255 0 15 255 0 16 255 0 17 255 0 18 255 0 19 255 0 20 255 0 21 255 0 22 255 0 23 255 0 24 255 0 25 255 0 26 255 0 27 255 0 28 255 0 29 255 0 30 255 0 31 255 0 32 255 0 33 255 0 34 255 0 35 255 0 36 255 0 37 255 0 38 255 0 39 255 0 40 255 0 41 255 0 42 255 0 43 255 0 44 255 0 45 255 0 46 255 0 47 255 0 48 255 0 49 255 0 50 255 0 51 255 0 52 255 0 53 255 0 54 255 0 55 255 0 56 255 0 57 255 0 58 255 0 59 255 0 60 255 0 61 255 0 62 255 0 63 255 0 64 255 0 65 255 0 66 255 0 67 255 0 68 255 0 69 255 0 70 255 0 71 255 0 72 255 0 73 255 0 74 255 0 75 255 0 76 255 0 77 255 0 78 255 0 79 255 0 80 255 0 81 255 0 82 255 0 83 255 0 84 255 0 85 255 0 86 255 0 87 255 0 88 255 0 89 255 0 90 255 0 91 255 0 92 255 0 93 255 0 94 255 0 95 255 0 96 255 0 97 255 0 98 255 0 99 255 0 100 255 0 101 255 0 102 255 0 103 255 0 104 255 0 105 255 0 106 255 0 107 255 0 108 255 0 109 255 0 110 255 0 111 255 0 112 255 0 113 255 0 114 255 0 115 255 0 116 255 0 117 255 0 118 255 0 119 255 0 120 255 0 121 255 0 122 255 0 123 255 0 124 255 0 125 255 0 126 255 0 127 255 0 128 255 0 129 255 0 130 255 0 131 255 0 132 255 0 133 255 0 134 255 0 135 255 0 136 255 0 137 255 0 138 255 0 139 255 0 140 255 0 141 255 0 142 255 0 143 255 0 144 255 0 145 255 0 146 255 0 147 255 0 148 255 0 149 255 0 150 255 0 151 255 0 152 255 0 153 255 0 154 255 0 155 255 0 156 255 0 157 255 0 158 255 0 159 255 0 160 255 0 161 255 0 162 255 0 163 255 0 164 255 0 165 255 0 166 255 0 167 255 0 168 255 0 169 255 0 170 255 0 171 255 0 172 255 0 173 255 0 174 255 0 175 255 0 176 255 0 177 255 0 178 255 0 179 255 0 180 255 0 181 255 0 182 255 0 183 255 0 184 255 0 185 255 0 186 255 0 187 255 0 188 255 0 189 255 0 190 255 0 191 255 0 192 255 0 193 255 0 194 255 0 195 255 0 196 255 0 197 255 0 198 255 0 199 255 0 200 255 0 201 255 0 202 255 0 203 255 0 204 255 0 205 255 0 206 255 0 207 255 0 208 255 0 209 255 0 210 255 0 211 255 0 212 255 0 213 255 0 214 255 0 215 255 0 216 255 0 217 255 0 218 255 0 219 255 0 220 255 0 221 255 0 222 255 0 223 255 0 224 255 0 225 255 0 226 255 0 227 255 0 228 255 0 229 255 0 230 255 0 231 255 0 232 255 0 233 255 0 234 255 0 235 255 0 236 255 0 237 255 0 238 255 0 239 255 0 240 255 0 241 255 0 242 255 0 243 255 0 244 255 0 245 255 0 246 255 0 247 255 0 248 255 0 249 255 0 250 255 0 251 255 0 252 255 0 253 255 0 254 255 0 255 255 0 255 254 0 255 253 0 255 252 0 255 251 0 255 250 0 255 249 0 255 248 0 255 247 0 255 246 0 255 245 0 255 244 0 255 243 0 255 242 0 255 241 0 255 240 0 255 239 0 255 238 0 255 237 0 255 236 0 255 235 0 255 234 0 255 233 0 255 232 0 255 231 0 255 230 0 255 229 0 255 228 0 255 227 0 255 226 0 255 225 0 255 224 0 255 223 0 255 222 0 255 221 0 255 220 0 255 219 0 255 218 0 255 217 0 255 216 0 255 215 0 255 214 0 255 213 0 255 212 0 255 211 0 255 210 0 255 209 0 255 208 0 255 207 0 255 206 0 255 205 0 255 204 0 255 203 0 255 202 0 255 201 0 255 200 0 255 199 0 255 198 0 255 197 0 255 196 0 255 195 0 255 194 0 255 193 0 255 192 0 255 191 0 255 190 0 255 189 0 255 188 0 255 187 0 255 186 0 255 185 0 255 184 0 255 183 0 255 182 0 255 181 0 255 180 0 255 179 0 255 178 0 255 177 0 255 176 0 255 175 0 255 174 0 255 173 0 255 172 0 255 171 0 255 170 0 255 169 0 255 168 0 255 167 0 255 166 0 255 165 0 255 164 0 255 163 0 255 162 0 255 161 0 255 160 0 255 159 0 255 158 0 255 157 0 255 156 0 255 155 0 255 154 0 255 153 0 255 152 0 255 151 0 255 150 0 255 149 0 255 148 0 255 147 0 255 146 0 255 145 0 255 144 0 255 143 0 255 142 0 255 141 0 255 140 0 255 139 0 255 138 0 255 137 0 255 136 0 255 135 0 255 134 0 255 133 0 255 132 0 255 131 0 255 130 0 255 129 0 255 128 0 255 127 0 255 126 0 255 125 0 255 124 0 255 123 0 255 122 0 255 121 0 255 120 0 255 119 0 255 118 0 255 117 0 255 116 0 255 115 0 255 114 0 255 113 0 255 112 0 255 111 0 255 110 0 255 109 0 255 108 0 255 107 0 255 106 0 255 105 0 255 104 0 255 103 0 255 102 0 255 101 0 255 100 0 255 99 0 255 98 0 255 97 0 255 96 0 255 95 0 255 94 0 255 93 0 255 92 0 255 91 0 255 90 0 255 89 0 255 88 0 255 87 0 255 86 0 255 85 0 255 84 0 255 83 0 255 82 0 255 81 0 255 80 0 255 79 0 255 78 0 255 77 0 255 76 0 255 75 0 255 74 0 255 73 0 255 72 0 255 71 0 255 70 0 255 69 0 255 68 0 255 67 0 255 66 0 255 65 0 255 64 0 255 63 0 255 62 0 255 61 0 255 60 0 255 59 0 255 58 0 255 57 0 255 56 0 255 55 0 255 54 0 255 53 0 255 52 0 255 51 0 255 50 0 255 49 0 255 48 0 255 47 0 255 46 0 255 45 0 255 44 0 255 43 0 255 42 0 255 41 0 255 40 0 255 39 0 255 38 0 255 37 0 255 36 0 255 35 0 255 34 0 255 33 0 255 32 0 255 31 0 255 30 0 255 29 0 255 28 0 255 27 0 255 26 0 255 25 0 255 24 0 255 23 0 255 22 0 255 21 0 255 20 0 255 19 0 255 18 0 255 17 0 255 16 0 255 15 0 255 14 0 255 13 0 255 12 0 255 11 0 255 10 0 255 9 0 255 8 0 255 7 0 255 6 0 255 5 0 255 4 0 255 3 0 255 2 0 255 1 0 255 0 1 255 0 2 255 0 3 255 0 4 255 0 5 255 0 6 255 0 7 255 0 8 255 0 9 255 0 10 255 0 11 255 0 12 255 0 13 255 0 14 255 0 15 255 0 16 255 0 17 255 0 18 255 0 19 255 0 20 255 0 21 255 0 22 255 0 23 255 0 24 255 0 25 255 0 26 255 0 27 255 0 28 255 0 29 255 0 30 255 0 31 255 0 32 255 0 33 255 0 34 255 0 35 255 0 36 255 0 37 255 0 38 255 0 39 255 0 40 255 0 41 255 0 42 255 0 43 255 0 44 255 0 45 255 0 46 255 0 47 255 0 48 255 0 49 255 0 50 255 0 51 255 0 52 255 0 53 255 0 54 255 0 55 255 0 56 255 0 57 255 0 58 255 0 59 255 0 60 255 0 61 255 0 62 255 0 63 255 0 64 255 0 65 255 0 66 255 0 67 255 0 68 255 0 69 255 0 70 255 0 71 255 0 72 255 0 73 255 0 74 255 0 75 255 0 76 255 0 77 255 0 78 255 0 79 255 0 80 255 0 81 255 0 82 255 0 83 255 0 84 255 0 85 255 0 86 255 0 87 255 0 88 255 0 89 255 0 90 255 0 91 255 0 92 255 0 93 255 0 94 255 0 95 255 0 96 255 0 97 255 0 98 255 0 99 255 0 100 255 0 101 255 0 102 255 0 103 255 0 104 255 0 105 255 0 106 255 0 107 255 0 108 255 0 109 255 0 110 255 0 111 255 0 112 255 0 113 255 0 114 255 0 115 255 0 116 255 0 117 255 0 118 255 0 119 255 0 120 255 0 121 255 0 122 255 0 123 255 0 124 255 0 125 255 0 126 255 0 127 255 0 128 255 0 129 255 0 130 255 0 131 255 0 132 255 0 133 255 0 134 255 0 135 255 0 136 255 0 137 255 0 138 255 0 139 255 0 140 255 0 141 255 0 142 255 0 143 255 0 144 255 0 145 255 0 146 255 0 147 255 0 148 255 0 149 255 0 150 255 0 151 255 0 152 255 0 153 255 0 154 255 0 155 255 0 156 255 0 157 255 0 158 255 0 159 255 0 160 255 0 161 255 0 162 255 0 163 255 0 164 255 0 165 255 0 166 255 0 167 255 0 168 255 0 169 255 0 170 255 0 171 255 0 172 255 0 173 255 0 174 255 0 175 255 0 176 255 0 177 255 0 178 255 0 179 255 0 180 255 0 181 255 0 182 255 0 183 255 0 184 255 0 185 255 0 186 255 0 187 255 0 188 255 0 189 255 0 190 255 0 191 255 0 192 255 0 193 255 0 194 255 0 195 255 0 196 255 0 197 255 0 198 255 0 199 255 0 200 255 0 201 255 0 202 255 0 203 255 0 204 255 0 205 255 0 206 255 0 207 255 0 208 255 0 209 255 0 210 255 0 211 255 0 212 255 0 213 255 0 214 255 0 215 255 0 216 255 0 217 255 0 218 255 0 219 255 0 220 255 0 221 255 0 222 255 0 223 255 0 224 255 0 225 255 0 226 255 0 227 255 0 228 255 0 229 255 0 230 255 0 231 255 0 232 255 0 233 255 0 234 255 0 235 255 0 236 255 0 237 255 0 238 255 0 239 255 0 240 255 0 241 255 0 242 255 0 243 255 0 244 255 0 245 255 0 246 255 0 247 255 0 248 255 0 249 255 0 250 255 0 251 255 0 252 255 0 253 255 0 254 255 0 255 255 0 255 254 0 255 253 0 255 252 0 255 251 0 255 250 0 255 249 0 255 248 0 255 247 0 255 246 0 255 245 0 255 244 0 255 243 0 255 242 0 255 241 0 255 240 0 255 239 0 255 238 0 255 237 0 255 236 0 255 235 0 255 234 0 255 233 0 255 232 0 255 231 0 255 230 0 255 229 0 255 228 0 255 227 0 255 226 0 255 225 0 255 224 0 255 223 0 255 222 0 255 221 0 255 220 0 255 219 0 255 218 0 255 217 0 255 216 0 255 215 0 255 214 0 255 213 0 255 212 0 255 211 0 255 210 0 255 209 0 255 208 0 255 207 0 255 206 0 255 205 0 255 204 0 255 203 0 255 202 0 255 201 0 255 200 0 255 199 0 255 198 0 255 197 0 255 196 0 255 195 0 255 194 0 255 193 0 255 192 0 255 191 0 255 190 0 255 189 0 255 188 0 255 187 0 255 186 0 255 185 0 255 184 0 255 183 0 255 182 0 255 181 0 255 180 0 255 179 0 255 178 0 255 177 0 255 176 0 255 175 0 255 174 0 255 173 0 255 172 0 255 171 0 255 170 0 255 169 0 255 168 0 255 167 0 255 166 0 255 165 0 255 164 0 255 163 0 255 162 0 255 161 0 255 160 0 255 159 0 255 158 0 255 157 0 255 156 0 255 155 0 255 154 0 255 153 0 255 152 0 255 151 0 255 150 0 255 149 0 255 148 0 255 147 0 255 146 0 255 145 0 255 144 0 255 143 0 255 142 0 255 141 0 255 140 0 255 139 0 255 138 0 255 137 0 255 136 0 255 135 0 255 134 0 255 133 0 255 132 0 255 131 0 255 130 0 255 129 0 255 128 0 255 127 0 255 126 0 255 125 0 255 124 0 255 123 0 255 122 0 255 121 0 255 120 0 255 119 0 255 118 0 255 117 0 255 116 0 255 115 0 255 114 0 255 113 0 255 112 0 255 111 0 255 110 0 255 109 0 255 108 0 255 107 0 255 106 0 255 105 0 255 104 0 255 103 0 255 102 0 255 101 0 255 100 0 255 99 0 255 98 0 255 97 0 255 96 0 255 95 0 255 94 0 255 93 0 255 92 0 255 91 0 255 90 0 255 89 0 255 88 0 255 87 0 255 86 0 255 85 0 255 84 0 255 83 0 255 82 0 255 81 0 255 80 0 255 79 0 255 78 0 255 77 0 255 76 0 255 75 0 255 74 0 255 73 0 255 72 0 255 71 0 255 70 0 255 69 0 255 68 0 255 67 0 255 66 0 255 65 0 255 64 0 255 63 0 255 62 0 255 61 0 255 60 0 255 59 0 255 58 0 255 57 0 255 56 0 255 55 0 255 54 0 255 53 0 255 52 0 255 51 0 255 50 0 255 49 0 255 48 0 255 47 0 255 46 0 255 45 0 255 44 0 255 43 0 255 42 0 255 41 0 255 40 0 255 39 0 255 38 0 255 37 0 255 36 0 255 35 0 255 34 0 255 33 0 255 32 0 255 31 0 255 30 0 255 29 0 255 28 0 255 27 0 255 26 0 255 25 0 255 24 0 255 23 0 255 22 0 255 21 0 255 20 0 255 19 0 255 18 0 255 17 0 255 16 0 255 15 0 255 14 0 255 13 0 255 12 0 255 11 0 255 10 0 255 9 0 255 8 0 255 7 0 255 6 0 255 5 0 255 4 0 255 3 0 255 2 0 255 1 0 255 0 0kst-2.0.3/misc/IDL 16 Haze000644 001750 001750 00000005320 11544160206 015235 0ustar00synthsynth000000 000000 GIMP Palette 167 112 255 167 112 255 255 213 254 254 212 251 249 210 250 247 209 249 245 208 248 243 206 247 242 205 246 240 203 245 238 202 244 236 200 243 234 199 242 232 198 241 230 196 240 228 195 239 226 193 238 224 192 237 222 191 236 220 189 235 218 188 234 216 186 233 214 185 232 212 183 231 210 182 230 208 181 229 206 179 228 204 178 227 202 176 226 200 175 225 198 174 224 196 172 223 194 171 222 192 169 221 190 168 220 188 166 219 186 165 218 184 164 217 182 162 216 180 161 215 178 159 214 176 158 213 174 157 212 172 155 211 170 154 210 168 152 209 166 151 208 164 150 207 162 148 206 160 147 205 158 145 204 156 144 203 154 142 202 152 141 201 150 140 200 148 138 199 146 137 198 144 135 197 142 134 196 141 133 195 139 131 194 137 130 193 135 128 192 133 127 191 131 125 190 129 124 189 127 123 188 125 121 187 123 120 186 121 118 185 119 117 184 117 116 183 115 114 182 113 113 181 111 111 180 109 110 179 107 109 178 105 107 177 103 106 176 101 104 175 99 103 174 97 101 173 95 100 172 93 99 171 91 97 170 89 96 169 87 94 168 85 93 167 83 92 166 81 90 165 79 89 164 77 87 163 75 86 162 73 84 161 71 83 160 69 82 159 67 80 158 65 79 157 63 77 156 61 76 155 59 75 154 57 73 153 55 72 152 53 70 151 51 69 150 49 68 149 47 66 148 45 65 147 43 63 146 41 62 145 40 60 144 38 59 143 36 58 142 34 56 141 32 55 140 30 53 139 28 52 138 26 51 137 24 49 136 22 48 135 20 46 134 18 45 133 16 43 132 14 42 131 12 41 130 13 39 129 8 38 128 6 36 127 4 35 126 4 34 125 6 32 124 7 31 123 9 32 122 11 33 121 13 34 120 15 36 119 17 37 118 19 38 117 21 40 116 23 41 115 25 42 114 27 44 113 29 45 112 31 46 111 33 48 110 35 49 109 37 50 108 39 52 107 41 53 106 43 54 105 45 56 104 47 57 103 49 58 102 51 60 101 53 61 100 55 62 99 57 64 98 59 65 97 61 66 96 63 68 95 65 69 94 67 70 93 69 72 92 71 73 91 73 75 90 75 76 89 77 77 88 79 79 87 81 80 86 83 81 85 85 83 84 87 84 83 89 85 82 91 87 81 93 88 80 95 89 79 97 91 78 99 92 77 101 93 76 103 95 75 105 96 74 107 97 73 108 99 72 110 100 71 112 101 70 114 103 69 116 104 68 118 105 67 120 107 66 122 108 65 124 109 64 126 111 63 128 112 62 130 113 61 132 115 60 134 116 59 136 117 58 138 119 57 140 120 56 142 121 55 144 123 54 146 124 53 148 125 52 150 127 51 152 128 50 154 129 49 156 131 48 158 132 47 160 133 46 162 135 45 164 136 44 166 137 43 168 139 42 170 140 41 172 141 40 174 143 39 176 144 38 178 145 37 180 147 36 182 148 35 184 149 34 186 151 33 188 152 32 190 153 31 192 155 30 194 156 29 196 157 28 198 159 27 200 160 26 202 161 25 204 163 24 206 164 23 208 165 22 210 167 21 211 168 20 213 169 19 215 171 18 217 172 17 219 173 16 221 175 15 223 176 14 225 177 13 227 179 12 229 180 11 231 181 13 233 183 9 235 184 8 237 185 7 239 187 6 241 188 5 243 189 4 245 191 3 247 192 2 249 193 1 251 195 0 251 195 0 kst-2.0.3/misc/IDL 26 Eos-A000644 001750 001750 00000004412 11544160206 015254 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 0 0 127 127 127 123 0 193 119 0 195 114 0 197 110 0 199 106 0 201 102 0 204 97 0 206 84 0 187 80 0 189 76 0 191 80 0 214 76 0 216 72 0 218 67 0 221 63 0 223 59 0 225 55 0 227 45 0 206 42 0 208 38 0 210 38 0 235 33 0 238 29 0 240 25 0 242 21 0 244 16 0 246 12 0 248 7 0 225 3 0 227 0 0 229 0 17 255 0 34 255 0 51 255 0 68 255 0 85 255 0 102 255 0 119 255 0 122 229 0 137 229 0 153 229 0 187 255 0 204 255 0 221 255 0 238 255 0 255 255 0 255 238 0 255 221 0 229 183 0 229 168 0 229 152 0 255 153 0 255 135 0 255 118 0 255 101 0 255 84 0 255 67 0 255 50 0 229 30 0 229 15 0 229 0 8 255 0 17 255 0 25 255 0 34 255 0 42 255 0 51 255 0 59 255 0 61 229 0 68 229 0 76 229 0 93 255 0 102 255 0 110 255 0 119 255 0 127 255 0 136 255 0 144 255 0 137 229 0 145 229 0 153 229 0 178 255 0 187 255 0 195 255 0 204 255 0 212 255 0 221 255 0 229 255 0 214 229 0 221 229 0 229 229 0 255 250 0 255 246 0 255 242 0 255 238 0 255 233 0 255 229 0 255 225 0 229 198 0 229 195 0 229 191 0 255 208 0 255 204 0 255 199 0 255 195 0 255 191 0 255 187 0 255 182 0 229 160 0 229 156 0 229 152 0 255 165 0 255 161 0 255 157 0 255 153 0 255 148 0 255 144 0 255 140 0 229 122 0 229 118 0 229 114 0 255 125 0 255 123 0 255 121 0 255 119 0 255 116 0 255 114 0 255 112 0 229 99 0 229 97 0 229 95 0 255 104 0 255 102 0 255 99 0 255 97 0 255 95 0 255 93 0 255 91 0 229 80 0 229 78 0 229 76 0 255 82 0 255 80 0 255 78 0 255 76 0 255 74 0 255 72 0 255 70 0 229 61 0 229 59 0 229 57 0 255 61 0 255 59 0 255 57 0 255 55 0 255 53 0 255 50 0 255 48 0 229 42 0 229 40 0 229 38 0 255 40 0 255 38 0 255 36 0 255 33 0 255 31 0 255 29 0 255 27 0 229 22 0 229 21 0 229 19 0 255 19 0 255 16 0 255 14 0 255 12 0 255 13 0 255 8 0 255 6 0 229 3 0 229 1 0 229 0 0 253 0 0 251 0 0 249 0 0 248 0 0 246 0 0 244 0 0 242 0 0 217 0 0 215 0 0 213 0 0 236 0 0 234 0 0 232 0 0 230 0 0 229 0 0 227 0 0 225 0 0 201 0 0 200 0 0 198 0 0 218 0 0 217 0 0 215 0 0 213 0 0 211 0 0 210 0 0 208 0 0 186 0 0 184 0 0 182 0 0 201 0 0 199 0 0 198 0 0 196 0 0 194 0 0 192 0 0 191 0 0 170 0 0 169 0 0 167 0 0 184 0 0 182 0 0 180 0 0 179 0 0 177 0 0 175 0 0 174 0 0 155 0 0 153 0 0 151 0 0 167 0 0 165 0 0 163 0 0 161 0 0 160 0 0 158 0 0 156 0 0 139 0 0 138 0 0 136 0 0 149 0 0 148 0 0 146 0 0 144 0 0 143 0 0 141 0 0 139 0 0 124 0 0 122 0 0 120 0 0 132 0 0 130 0 0 130 0 0 kst-2.0.3/misc/macdeploykst000755 001750 001750 00000004234 11544160206 016253 0ustar00synthsynth000000 000000 #!/bin/sh # 1. Plugins # Change link information from # # $otool -L build/plugin/libkst2data_ascii.dylib # build/plugin/libkst2data_ascii.dylib: # libkst2data_ascii.dylib (compatibility version 0.0.0, current version 0.0.0) # kst2lib.framework/Versions/1/kst2lib (compatibility version 1.0.0, current version 1.0.0) # QtXml.framework/Versions/4/QtXml (compatibility version 4.7.0, current version 4.7.1) # QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.1) # QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.1) # # to # # $otool -L build/plugin/libkst2data_ascii.dylib # build/plugin/libkst2data_ascii.dylib: # libkst2data_ascii.dylib (compatibility version 0.0.0, current version 0.0.0) # @executable_path/../Frameworks/kst2lib.framework/Versions/1/kst2lib (compatibility version 1.0.0, current version 1.0.0) # @executable_path/../Frameworks/QtXml.framework/Versions/4/QtXml (compatibility version 4.7.0, current version 4.7.1) # @executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.1) # @executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.1) # #ref: http://doc.qt.nokia.com/4.7/deployment-mac.html # mkdir build/bin/kst2.app/Contents/PlugIns change_lib_path() { install_name_tool -change $2.framework/Versions/$3/$2 @executable_path/../Frameworks/$2.framework/Versions/$3/$2 $1 } deploy_plugin() { change_lib_path $1 kst2lib 1 change_lib_path $1 QtCore 4 change_lib_path $1 QtXml 4 change_lib_path $1 QtGui 4 cp $1 build/bin/kst2.app/Contents/PlugIns } deploy_plugin build/plugin/libkst2data_ascii.dylib deploy_plugin build/plugin/libkst2data_dirfilesource.dylib # 2. Libraries install_kst_libs() { # this is not nice, but then we could use macdeployqt also for kst libs sudo rm -rf /Library/Frameworks/kst2$1.framework/Versions/Current sudo cp -R build/lib/kst2$1.framework /Library/Frameworks } install_kst_libs app install_kst_libs lib install_kst_libs math install_kst_libs widgets # this copies and fixes the frameworks macdeployqt build/bin/kst2.app $1 kst-2.0.3/misc/IDL 10 GRN-PINK000644 001750 001750 00000004760 11544160206 015534 0ustar00synthsynth000000 000000 GIMP Palette 0 0 0 0 0 0 0 0 0 0 0 0 0 14 0 0 28 0 0 43 0 0 57 0 0 72 0 0 81 0 0 90 0 0 99 0 0 108 0 0 117 0 0 126 0 0 135 0 0 144 0 0 153 0 0 162 0 0 171 0 0 180 0 0 179 1 0 178 3 0 177 4 0 176 6 0 175 8 0 174 10 0 173 12 0 172 14 0 171 15 0 170 17 0 169 19 0 168 21 0 167 23 0 166 25 0 165 27 0 164 29 0 163 31 0 162 33 0 161 35 0 160 37 0 159 38 0 158 40 0 157 42 0 156 44 0 154 46 0 152 48 0 150 50 0 148 53 0 147 54 0 146 56 0 145 58 0 144 60 0 143 62 0 142 64 0 141 66 0 140 68 0 139 69 0 138 71 0 137 73 0 136 75 0 135 77 0 134 79 0 133 81 0 132 83 0 131 84 0 130 86 0 129 88 0 128 90 0 126 92 0 124 94 0 122 96 0 120 99 0 119 100 0 118 102 0 117 104 0 116 106 0 115 108 0 114 110 0 113 112 0 112 114 0 111 116 0 110 118 0 109 120 0 108 122 0 107 123 0 106 125 0 105 127 0 104 129 0 103 131 0 102 133 0 101 135 0 100 137 0 99 138 0 98 140 0 97 142 0 96 144 0 94 146 0 92 148 0 90 150 0 88 153 0 87 154 0 86 156 0 85 158 0 84 160 0 83 162 0 82 164 0 81 166 0 80 168 0 79 170 0 78 172 0 77 174 0 76 176 0 75 177 0 74 179 0 73 181 0 72 183 0 71 185 0 70 187 0 69 189 0 68 191 0 66 193 0 64 195 0 62 197 0 60 199 5 59 199 10 58 198 15 57 197 20 56 196 25 54 196 30 52 196 35 50 196 40 48 195 45 47 195 50 46 194 55 45 193 60 44 192 65 42 192 70 40 191 75 38 191 80 36 190 84 34 190 88 32 190 92 30 190 96 28 190 101 26 190 106 24 190 111 22 190 116 20 189 121 19 189 126 18 188 131 17 187 136 16 186 141 14 186 146 12 185 151 10 185 156 8 184 159 6 184 162 4 185 165 2 186 168 0 187 171 0 187 174 0 187 177 0 187 180 0 187 183 0 187 186 0 187 189 0 187 192 0 188 195 0 188 198 0 188 201 0 188 204 0 189 207 0 189 210 0 189 213 0 189 216 0 189 219 0 189 222 0 189 225 0 189 228 0 190 231 0 190 234 0 190 237 0 190 240 0 191 243 0 191 246 0 191 249 0 191 252 0 191 252 4 192 252 8 193 252 12 194 252 16 195 252 20 196 252 24 197 252 28 198 252 32 199 252 36 200 252 40 201 252 44 202 252 48 203 252 52 203 252 56 204 252 60 205 252 64 206 252 68 207 252 72 208 252 76 209 252 80 210 252 84 211 252 88 212 252 92 213 252 96 214 252 100 214 252 104 215 252 108 216 252 112 217 252 116 218 252 120 219 252 124 220 252 128 221 252 132 222 252 136 223 252 140 224 252 144 225 252 147 226 252 150 227 252 153 228 252 156 229 252 160 230 252 164 231 252 168 232 252 172 233 252 176 234 252 180 235 252 184 236 252 188 237 252 192 237 252 196 238 252 200 239 252 204 240 252 208 241 252 212 242 252 216 243 252 220 244 252 224 245 252 228 246 252 232 247 252 236 248 252 240 249 252 244 250 252 248 251 252 252 252 253 253 253 254 254 254 255 255 255 kst-2.0.3/COPYING000644 001750 001750 00000043141 11544160206 013726 0ustar00synthsynth000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. kst-2.0.3/kst.lsm.in000644 001750 001750 00000000612 11544160206 014612 0ustar00synthsynth000000 000000 Begin3 Title: Kst Version: @KST_VERSION@ Entered-date: Description: A data viewing program. Keywords: Author: C. Barth Netterfield Maintained-by: C. Barth Netterfield Primary-site: Home-page: http://kst.kde.org/ Original-site: Platforms: Linux and other Unices Copying-policy: GNU Public License End kst-2.0.3/AUTHORS000644 001750 001750 00000000776 11544160206 013752 0ustar00synthsynth000000 000000 KST Developers C. Barth Netterfield George Staikos Andrew Walker Rick Chern Eli Filder Mike Fenton Matthew D Truch Nicolas Brisset Ted Kisner The University of British Columbia The University of Toronto Sumus Technology Limited Peter Kümmel Zongyi Zang # File must be saved as UTF8!kst-2.0.3/datasourceplugin.pri000644 001750 001750 00000002301 11544160206 016751 0ustar00synthsynth000000 000000 include(config.pri) QT += xml TEMPLATE = lib CONFIG += plugin warn_on CONFIG -= precompile_header !win32 { OBJECTS_DIR = tmp MOC_DIR = tmp } DESTDIR = $$OUTPUT_DIR/plugin !isEmpty(INSTALL_PREFIX) { target.path = $$INSTALL_PREFIX/$$INSTALL_LIBDIR/kst INSTALLS += target } INCLUDEPATH += \ tmp \ $$TOPLEVELDIR/src/libkst \ $$TOPLEVELDIR/src/libkstmath \ macx { LIBS += -F$$OUTPUT_DIR/lib qtAddLibrary(kst2lib) } else { LIBS += \ -L$$OUTPUT_DIR/lib \ -l$$kstlib(kst2lib) } LibExists(cfitsio) { win32 { } else { CONFIG += link_pkgconfig PKGCONFIG += cfitsio INCLUDEPATH += $$pkginclude(cfitsio) } } LibExists(getdata) { win32{ INCLUDEPATH += $$(GETDATADIR)/include LIBS += -L$$(GETDATADIR)/lib } else { macx { INCLUDEPATH += $$(GETDATADIR)/include LIBS += -L$$(GETDATADIR)/lib } else { CONFIG += link_pkgconfig PKGCONFIG += getdata INCLUDEPATH += $$pkginclude(getdata) } } } LibExists(netcdf) { win32 { INCLUDEPATH += $$(NETCDFDIR)/include LIBS += -L$$(NETCDFDIR)/lib } else { CONFIG += link_pkgconfig PKGCONFIG += netcdf INCLUDEPATH += $$pkginclude(netcdf) } } kst-2.0.3/INSTALL000644 001750 001750 00000014557 11544160206 013735 0ustar00synthsynth000000 000000 ========================= Building Kst with CMake ========================= Install CMake from www.cmake.org or your distribution (version >= 2.8). 3rd party libraries ------------------- Install Qt 4 and make sure qmake is found. Add the folder with qmake to the environment variable PATH. If you've compiled Qt by yourself or qmake is not found after installing Qt fix PATH, Linux/Unix: export PATH=/bin:$PATH Windows : set PATH=\bin;%PATH% Libraries for plugins: Currently only Getdata, Gsl, and Netcdf are supported. On pkg systems the libraries should be found automatically, on non-pkg systems like Windows you must point to the libraries by environment variables NETCDF_DIR, GETDATA_DIR, and GSL_DIR. Generating build system files ----------------------------- CMake is a build system file generator. On all systems it could generate files for several build systems, for instance Makefiles for make, project files for Visual Studio, Xcode, Eclipse. Running cmake without any argument lists all supported build systems on your system. Passing one of them as -G"" argument when running cmake selects this. Building out-of-source ---------------------- The standard way of using CMake is to build in a folder which doesn't resides in the source tree. This has the advantage, that a complete fresh build could be done by simply deleting all files in the build folder and to re-run cmake again. Another benefit of out-of-source builds is that several builds (debug, release, command-line builds, IDE project files) could all use the same source tree. Therefore when using cmake create a folder outside of the source tree and select this folder when using CMake's GUI, cmake-gui, or go into this folder when you call cmake from the shell. Using cmake ------------- When calling cmake you must pass the path to the source tree (absolute are relative) and optionally the generator (each system has its own default). Additional arguments could be passed with the -D prefix. Here some examples, assuming the build folder is in the same folder as the source tree: * Makefiles on Linux cmake ../kst/cmake * Project files for QtCreator: Open the kst/cmake/CMakeLists.txt file and select the build folder or create the files in the command line using the -G"CodeBlocks *" option, eg cmake ../kst/cmake -G"CodeBlocks - Unix Makefiles" * Project files for Xcode cmake ../kst/cmake -GXcode * Project files for Visual Studio 10 cmake ..\kst\cmake -G"Visual Studio 10" * NMake files for Visual Studio cmake ..\kst\cmake -G"NMake Makefiles" * Makefiles for MinGW cmake ..\kst\cmake -G"MinGW Makefiles" Daily work: * Re-running cmake is simple cmake . * Adding new files The cmake build system scans the directories, so no need to update any file, just re-run cmake. Also the mocing rules are generated. * Unused source code file Because cmake scans the directories for *.cpp and *.h files it will also add files to the build system which are not mentioned to build. To exclude them change their ending and re-run cmake. * Projects 'make help' lists the available targets. Options ------- Options could be passed by the -D prefix when running cmake. Available options will be listed on each cmake run. Here the options with their default value: -- kst_release = OFF : Build release version: optimize for speed, don't embedded debug symbols -- kst_merge_files = OFF : Merge files to speedup build about factor 5 -- kst_merge_rebuild = OFF : Rebuild generated files from merged files build -- kst_verbose = OFF : Make verbose CMake run and Makefiles -- kst_install_prefix = ON : Install path for Kst, using a default if not set -- kst_install_libdir = ON : Install directory name for libraries -- kst_3rdparty = ON : Build plugins depending on 3rd party libraries -- kst_dataobjects = ON : Build dataobject plugins -- kst_test = OFF : Build unit tests -- kst_pch = ON : Use precompiled headers -- kst_svnversion = ON : Use svnversion's output for Kst's version information -- kst_rpath = ON : Use rpath -- kst_3rdparty_download = OFF : Download precompiled 3rd party libraries -- kst_console = OFF : Open console on Windows -- kst_edit_cont = OFF : Enable "Edit and Continue" for Visual Studio To enable a option pass the value ON or 1, eg cmake ../kst/cmake -Dkst_merge_files=1 Using the merged files build ----------------------------- When the option 'kst_merge_files' is used then for each library a files is generated(merged_const.cpp) which includes all source files of this library, this speeds up compilation about factor 5. When you heavily work on one file you could comment out the relevant define in the 'merged_const.cpp' file, so only the file 'merged_touched.cpp' file will be re-compiled again an again. The CMake macro 'kst_dont_merge' is only active when the option 'kst_merge_files' is used. 'kst_dont_merge' prevents the adding of the listed files to the generated file, all listed files will be compiled separately. Sometimes this is needed because of too much compiler errors, and it is simpler not to merge the file. - Adding new files When you add new files the merging files have to be rebuild: cmake -Dkst_merge_rebuild=1 . Or start over by completely cleaning the build folder. - Starting over with same configuration Delete all files but CMakeCache.txt and call cmake . Packaging ---------- - Source .tar.gz, .tar.bz2, .zip: make package_source - Binary .tar.gz and install .sh: make package - Binary .deb: create : cpack -G DEB --config CPackConfig.cmake list : dpkg-deb -c Kst-*.deb install: dpkg -i Kst-*.deb - Binary .rpm: create : cpack -G RPM --config CPackConfig.cmake list : rpm -qlp Kst-*.rpm install: rpm -U Kst-*.rpm - Binary .dmg make packages Status ------- Kst builds, starts, and loads all plugins. Tested on Linux, Windows, and MacOSX. Nice to have: - add pre-compiled headers for Mac, Xcode Releasing ---------- To build a release for Windows install the "Qt SDK for Windows" (it comes with MinGW) and call in a build folder ..\kst\misc\mingw-release-download-deps kst-2.0.3/config.h000644 001750 001750 00000000452 11544160206 014307 0ustar00synthsynth000000 000000 #ifndef KST_CONFIG_H #define KST_CONFIG_H // obligatory flags //#define QT_NO_STL //#define QT_NO_KEYWORDS #define KSTVERSION "2.0.3" #define KST_INSTALL_LIBDIR "lib" #define KST_INSTALL_PLUGINS "lib/kst2/plugins" #ifndef KST_HAVE_SVN_REVISION_H #define SVN_REVISION "unknown" #endif #endif kst-2.0.3/RELEASE.NOTES000644 001750 001750 00000000001 11544160206 014551 0ustar00synthsynth000000 000000 kst-2.0.3/COPYING.LGPL000644 001750 001750 00000061347 11544160207 014474 0ustar00synthsynth000000 000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! kst-2.0.3/sample_data/GROUNDTEST+fixed-width+delimiter+windowsEOL+comma-decimal-separator.txt.gz000644 001750 001750 00000134350 11544160207 032721 0ustar00synthsynth000000 000000 h@Mfixed-width+delimiter.txt}Y,;$^@!Chz׃ ԃnf~>ǔM?K?r|rOo8~?ǿÿÿOzt9*OJI/%}s.g3z./_WGQgVt^?Ow?rK'JmZcjEooi;xne| ~6i|FQM<߮eEz-e|]~o_=Z??.v_lwk(>nea'V?9cWeE*s3.(\~$Ew}}M~?1k]wVtݞ/9UjOίN닏缮'ъjc?4/[ iy~MWڊZu۔']s}^7>酰?dnujE>qW`$~RodE`vJ1+r?\;"{Q7+OXߊmϻ o{?YS7=G%r)=^ݧ9(f}GE*Ao^TR6]%/ѹU>*ǗZX4~=,󩜿+\>836'].λ;">}-mE\Y޸z~oNIoNi9}K1^iyXd(2K~-7V[2w.Zګ!(Jw EOΞҞzǶ_=|ǮҊK}SWٳcW~59_{5m I)aWzB^OcWr)Wyz?Eߪgon_(B|mZ4tɮōE?1TwW4 o]F~:ֽXW_E'':=imE?\(A)(BTGQfѶBQi](Bħ|\}k3MqIQ.tFk=9hOaUQ' ziP'{y{4z-v`DR{_;}_YΏi<CSw'_2w bOƯmҹ wY/HW1B͗Ɵ\Үk}3g5.Oe޶Xzk|U|k23뼻志 ƅ)WhjZúvsFȣzײ\dvuIOc9-ݶHɶ~ 6\Wt59ѹCx(V,v!' &8^y@͸8q~[קxV|"OZ|XfuNcߚ09;9AӋ"jN-ax[%gKn5@f@RM~KjM>Ulu;"Ow٩^يD']gmF;x kSzٴ)j5 PtW mC\'~/q3?LfuIJO{=ؽXm5z?_?D Cq5{,O|l5Z}j-kV?>=N B{dT*6JlP& TRۮ!4W|?s_kݛBf{'ݳYsS[/,׫2ojԭǧ=6zM ,SN>5tC옷}=1g# TL<~M*@QD@М?̳ :O/:1y)>lQ+lr uv=(sEo^c%4';oͼiUfy &Y^n38ZȂ?G:5YOصbYvɮ{dvvy@6܏󁝯ŸT':OK) #8 X^IUyxm~ѵ_S2 K `,r^8Ǟ0'{:IOtTO("q^굵e-?9[" $[Z mm%_"O㌢߳'\tOB$2R<2R`^Eܟ>Q E;S*ՉHVq) 1nxs䮑#|x|ck8ds ld,?(b䓔y 0LSN ^kXI\cDKX0zTF$'qR ʾP bjٔVEv7,_a"S͂?.A"O%_ir-M̭E蟀i*j'&i)şL._iPDSv"au;> D8Akή*"V9{!qOCU8^UzX_,(i2QDI;5Eh%OѺsPoIڻкuxcZ F]p"?NW۪,?J8/jz\? 7G%h=O쟜:؏\=E'W4# #Jaderg@"bVM MךokV°T'^.[FN|O }" u( ֙3:ˇ$xs]3OARJ}w) "}ח%'ss.aTW>2:6:.QƓ¦&7q t(zJ/OT'k-'01na~s] U1!%襈+B{cLy8O6>:)3O@uT"韠MqؔFQʱkYέUv }wPKSy8!%8[!Sk~rQObx bn` 󽛜&+xS1sԚ7nэTDwxmÉuP,}+UOAH~FA7mzK("?B*K=>=*LO?ݘ6$%'z jEZQı>Vs;{CcæFR3M-?E&?(b (:Vgm5Sݝ%PV*~+蟄D;:pjUD~3 kU(8tYONj%~m)6UTӓTX/eS Ur Ir^X#L{nAϫvfU'a VIElL(c}HDK: zUş*6<8@Z0EsQD:)Hl.shPdA@J(BX(+G c9Q1NFrefO OQ۰aO =4W fQ/B{P$QZuV}maɠL VD D؟jڻwUߊ:\˱-&~,an!GtU6o"5ϲ={kDŽڟpaEB˺YW@P*|&#fOHSIAxF)5\{1kc=U?eGdw&FUL <.>?6a,[:jg'OB';OsPlQKs,k y{`fv0?`Iy<U `}4Up9_"?}Ed Yh#:^Y:hyYO"٠SfY@[}g6BS;Ÿt2*\7.LΎ9p'Xy!HJcHK/^#iG^*{ld㒙("/tc!-,{dب>? "6M"O✓ě$?(3?uWX#'cʁe(ә_ 9sSJۛ?A5818/s/Ϧm$dڲs+A W8FVzU?A8aStu꿇،r7%p {n!j-9^2٩JCE+ʰlZ] 30謂?I>;"ڞl͊TϦ*SAC/"$ f*VkX#aKQDrB3,[{6\^8){ 1?B1KH7{ v9{sq'97Rˉ,DiZ>bWOGvyV)XvQJ7<ѭ`V?Rɒm댇OҥW&57"$L/QI\:&SkKO"T雅=j S 0?6ĆGl[]9jX"l%U]TlNU:B~J /!I2쬗|.qF0P!(BDh)nX^E@qUj?}98r<&Os27^[MbE4^cϊF8U݄=buF_!29?~{yfT(^CXSE$8E.'3b3ꇯZe6ZhOğ*OCjjpWm46 䣘Il *`JI)A) z;ԩڥng9lԼt[M&uGlZUh7A b1q2! ("Dhd}=ğ*c%5ci?(p7W Xo [*emYS>-i&uT~#U"Rt5e@2x뱈y7abGTAo{s:4Fj:11 $"(-FMO\ r|lǷ ć`_{߃uH&;թV]t>TBvkwR(8wf}8M mcPO6g~4h?^B w1G6ci?AF7Na0L|x5WlB@k)XBn-6Mrw PɏȜ_SM':%)5?@◷D:л$ ?U'E{{ocLc<[ {AUPtE~c;5Gk﯇)Q\Ut2ೣ2 PDn\l 0Ql[XB}-t=MOiNxVr"Gf.Ȓ2I:pt*O@ Ssޜ$n˲OI'ߴMnNͿ(#PZ&S-/l_93U@},Y(BDOiȍ +0kbpbn}UYϨo:!?W#VN'a6* QI0v`vݎn?e#EZVOis~iAچGz&dQًBo-$M'3WJqυhSp}Eإ9[7]nA"OIgFD\\3,f5qI.՜ |&vr/mHG|>^MvJ8Gh˭ʩIpQcs ѤuPDI6n'M'Z~- l"i?b#,ĺsiT5fI",_OeǷ8fW@F2?"1g"#)C1B#^'5m?f!6"%  M&墸mGٓ}EdC8-:|FH2hBj%%H[چ(rQE*"NRSü?.4eާ4.FO Wؖ"OHх&5˯sTW6?Q81a]%25hRbT 6|$X "$JZ1-ى?!k2:1 j|Y_0Iq\)so#mL9@~05#@lΡ#F19M#lҴ5?IWcs@S$ j[%,X$9wH4Y8`K_|[,1gtj:_"lyx*Q%755|mu*L=. q> TmXQJemJ}? 磨k?!dLm3MGy$fO(){4t+Ė)&?7wr=EaChW%3>^rG(虺v$B*M!& ;k?bt2rCTFjx*z˫?I8%u`<^InoE:fJ/]'4qńVI]' Rc KqBHWS8Kgm ]'ʇѭgQu$¶OM'?$&')D=P&IIӚ˜8! \ϙ9gp (? 8f׳ \ORl=8@(2q'LT_TvO!m3?6z $$:}8 neWKZx*ķ $Et"O8ƏY>ENu"+bt 0kXiƏ?&''1#/6I a7iw)vS&wQ}/K'6]Ae)xVt(z7 /[A'u񪑁m5Q cԚyX#(]7nj\'Ld ϿO"<ϢmSnVH 2zAg)d"#p-y GHgx5^BdZM/,," mE蟒{uE1>Cf}I={?҈O !(l$JKo'E?O$cVDmewş43D/d);khiz6 M| ~-ѩϹ=F?=B:Z.ORKL~z%ܑ n>]`xBm1l}Tœ$= ɖ7 'c7?Hp2"',P+YwnkSPl2,2x?  E$p{x˧꟔y^I?њrx/9 g,g!OR&OXw]!O,U9P"DƢ81/Z(x:tȤY";?RWݜY>OgN&;Yf_r ADOr 3E*$("6 )7u~q<^1?2sMCO=!Xy TΛ.pw/6(Zm* T3.9 1-ǗD'+z KސO"-i^9;]ݏ"MxA H)3f|R&ÌI ߲ F?"SFoX/gLOx.3'XWFϫoԧ?eY,[K!)PDz>Oy+8.6.ev 4r/v(-0қ}Y۠'x- ,9Y QD},oj$ͅ?ڻS'Rp>j|jK}OvjtH ON`Qsi쮹UO 6v 'T_ 4N!9c@1\<%gXm't[ZѿݹR>UJ[Xh({)?&΄K..F ;+9t,L_3U|nd=u꟒XSvNx0ڰMе x)İlgG7B/ (8"k@H'5z2bT o@z34>$, 7'O4m{4*ccWjY 5"[h_b (Ud'v!W0hșO2?u)xoQՐ, 9 "OS=)S@ڊ4%@8`k'p#)L/ş>lB%قjRk'zw'^[pE쟨L(:h~aOG"es|sƳb.şSLjTt"I5wѕ|Ixٔ^)ƚ_Cs o-$OD"( B/[iW.O@æG(0IGQJ .)TYapZ0N"&dqQ(bDsnhPޯ <ֳ*|dz5^G'E$Xtk%SUy\=xF?d3nƞׇ8,u18`QE7r֤!⦃Tؐ$QbQF\YevZvOd9ȣ= O_.^O8pֱcOhQV'.|?풣>O~|Oğ(V4E-EwH nO3Z^=6͹>sɼ<9LiO 86~kbp 5x/+*'a8Y{ c@=9b[pBmaTՊ|cs,9e2.*PALJmW>?qղp8K NrE 8nO_NxrXߖ,;?{5- MA˓Rd.2H}᱅]Odު('L 'os#O *KAr3'iEak"ߟdo팭'fD|XEHmK2 N3MAT.ц[?o%~89iGdC^MsѿʉA9 YGƳ =>TN'*eFnMT÷bn9??mKt)ڻDG'F5Xrǣ'urjcăodoaX<'5q{O@GΜ}iXTljjEQ;qEG| ""-CQD"([UF-/fZ='9KFbsP0MNpICE/׸gYOvKPѓ<*QO1sd`<5b=[j)|ĥ {9Flc'䉯$?I~n)?(('q9|ȈoKعPD&>4F]̚2?Pbtn2Oř c]rDYy`Lh=̶; (b #{bm?1lx9(B))8d :@veY[N] '2#uj$'[yթ|Ջ: {=?w,j$HexD~Py\ÿDĻ$~SN@~{}؞+,m_^&[R٣Ir$͠Mq('=?li |`P`4(2:ɫYfkbOm&F;(b؟kiZtѵ}ƤCYh$/=E)TKN`rh[ͫR)|`5B@" G睭9,{ŀ"6t$HVqnk/5pi{ݯ,鎰cK8Ld;HFG A30G$>Te(ybPx %TO\rOpDZl'ykpO }Ķ'c?v^$\"JH|:݂E?½{xꦬOZ~Ai_~:5qrz@9iƦ=Ѡ?Ogx=1'?vy)(Cji]9 "jn ('蟾BJ7vh6'ş)'[QW*X(c8Q\r,]0l)>W1W&];æ6Aa"-\\R`'`$` o](3lCEW ,~uK ;73Ĵ`pOAFv8E蟊K~ebS y!NO;K ?%ZSV=kX^N?ɓaY 쒓OK0wԢzBL9 ,!w9 D `2:%ƭm'KF"Ӟ=EX3](9i&$cr)8[] #PDRU@\^Œ{y%o> jW3Fĸ̰y`xrQn T<+B|S}M5?eUl09h 1E|NGa'2t^a򉣸C"Vf QI}[#t&jYCRzN$aނ9;"SlL8+#i߻-$4'"C&P$:RT694RALXߣͰ%2a"ld. ꊗB8s,QBC{2K]&Ӆ4lmjG"U$ю3H":3}(bpdK1qwQӢQwrBxQE؟nIb.(bTcfAm2dE 9!a+BqwZ"O#Sϋw*1y`)!bDG?H:A"O ;iuLE4$C/ZAo>W=|:sr~gPț߅llf@u%2?Qivg'K>2[."=ݙ0Lodi~6"T 2X)'ǟ0>{1|\( hu®Z]RRe񉣨2_CKHGQ@bp#dJA6puJEa)o嗗bNҋo0!i\,$4;^GO(-\u‘1z}"]9+w:Tj(B3Oۅ oI, nbT"O:]kԣhOLf5+Ne'Dόg/x3lva)1EğNS 1{h(=Y0CGx* D0+ q\.R_PD1V3` ҙ% X?`΍_P68c"5u,a|%I)IS(DEMi'FOhWS8T"ED)+!ġcL%6?Ugi,gg[:IV|xkz VκNV\Ύ?Vh\īeq5M/638JOAF2ZXĢ7]Җ6A7vk6g9%8be-S ϊ?#>5jiϝ 1Y'dαPJ.'uЧi R>/XQQŚYH(*ܻӹ() `= s 1oј&1t-a _=!(o(xFraǤ77I"R*PD!UEFOf"0r(BD28;[#Z㔀%dQk2Z&}\\F$Ot'O*|V}-?5I11C3ӗnYs~XQi(bD = 嶯a^T3XGq9KSHlP$B9IǵpL}z쬮C֩([} dܧ;ct?FFcOEKC߽¼jxP-"ﱽF `;|#AH(KI_Bs{'k_E7r[E8I̍(?H 9E5Ql_Yeg=y&C?L !Fl阜x%X2-Y|BL w5)?S|sIXI8aQIDOb?ESE'N7Zr/٩E͚@'QF rKӷ˫Lݴŷz{KHEADS_2|rϲ)($4Fό"O0]R0]88d '[i2/.ğKRdtnޤLE*bfZڻ? 83cEYr-+Tt1Xی~ˣS \xo0")ueAJz8J")[3(\֓onU,Q 򟒆e $tE`[ϦK(Btv3*VԀ5O{ 3ˎ'>  ,MY_O\KyֱeS3G?Cti FE^x]2,?68P1+YѬs过¹7p"|і9\RQ{O4)vN%?emf/mxI+d)Ĵ"Oٲ?XOc˃("t2GVzM#z11UtIğjJʩ*?^ ~ͦ&^ik_(BD1M:Ws*-?>wVw1,sz#O$_>o`R=ED!Hw?d"4MY0C%vԺ%!WDc섮ӣ3߫fmD=& PVw,t+ /JXOX)&"O(9e;Yrp-|Q$|$0sk$?I1C=azt? j<{sy i34SyŹQХ㓊wwX"OG $,0oA?brE2S^?[Qf O"+rpÍ-J$ 9X#eΦKܴX$`lPQأD{g#XPDƈ h!4\?I'}GT RU{w{dz'OE㏣[ñItYTKZmj tZ#ֲXÿF(I^ݨk߿M(4#( =ۦ 淠 mE &coNJ ";ņ2' 0 9Iu E;x݂ks8Y܀Ÿ1urcEGw/&Kՙ(š5gveK%=>+C$50EkQ܀fp%ΘNR6R :G!X)C(/߬7 hYd]YD~c'\+glP\&-Wߓ[0hTІ\F0dI:Ģߗ~$1/3'P]24]יj>%AZū0#ln1 gVu"il'ݹBÿAIUɒE9E쟂 jhÉ?I^J=pݮ<(,͘P񐞶Q1{6{E/djGd'_UW MTiqaS#5z$iDbG'a$PKdÁEuTq6I FM',3Y|CAî 9 MOn! ^'aɘa퓂eGS4>#ؙm ,noRׯ`$)LX.G$NL c0mb4W-+p6"cֆc/@M mMhVz f|ةCk™x,;GKŋPD>}qo&&P&LvPc6`781A4{m)$'L1q!}~SqD)#,dLx" 13yOXrm?YGn%n(*ܟâ:Tc$OLBS0/Bvi?B,)_Om%:Ր>_1%7s&SO\=IZWOS,_MOl/Mhj?a!{A'zLm|=QӚ$ Ay?A:̲Ŧo.ruҒObi AOTRqYH'6,e OEYa "4d`F("Kmi?- ,1Q͢.Ӳ_$T]'x"[<. &PMݺOw!+Rz]B9,%6цH?}^5UO]2U8%k~G'X(w.JVN!^[ccHS%J,Hɚ)(FΔ^<.eպ8hi,?Q%b?vgmN"լFEX%gjQ>kH^Zu?ݧ(]'F(=0PIJO!sX(7oüO {鼉.EbrG+nV]*H酻Q/}*W. ,]﮶>ض[&`o_- f|[fH=j󨳧)~зD.'N\Z+5|ݙM4*YI22=BOM6:$EO;1r_tO-pƏ]'B2y&寸 AJwžyLjsK9q][=?e|./^F%|gN{:f()R?k\NOX?NaY$@'xp!u}SC"?EKxJO!*b #:ly;:G3.ԕ%vI!qkâ;0ZS+kp$bYd8a_w@ 60D'iϯW $6E v!&vN="PCgLǵğn~'(b~.oZv7G,h=8qR\9WqZT, EtT0F#dXR;Ch8"ǟlOzPʣ'F_-Jyj]W :j|- ğ;07ءSu,3 oO=q:E?~e^أОZk$z=]OzrĀ P>8-Ďῗ.}i}|}:tZ⍯)'`k/?nWp #5NNşB2-0kSSfZڡ?\ , 9S'QL n"O̙*a[w!)W$ꉅ'/Yz3n\<%Ih9^|?4:(\n.BI#K9 E ~awQ\"O07 x3t5DL?hq $~,#[@PVDF:?:ʷMG{? db~Fb)S%hRbF:V/mq~(p'|sԠͥ4J_Ƹҗ`Y?}C ۬t+H32\Oc7x=$FpQ"O<[HHA|(Oe%'$aĩHq':^'KO 'oFMM٠ 絼'A5%)x x4n~C P9ssI9~e 9&OL*=B{%M5"ꟲO[Ru"@[w.!Mm.+Z9-W8TPaMWp8=$xro+ex $_'n >Ts|) hry^9L:%8*h :є\ԮKhg BS'@xrO`bΞO>c ɿܻBH9O!aUlyT"s:dޓNKNr~<=DCƖIpzx'Z{|`u ;(!_П>E4i5}[Sb+)јv #$1ο2 8?^7o}/ʼtŋ$[Rep~q:xDe)S.)~ׯ ON)(Bԙ&]DldQ4d=d O_/_7@|NyGQ[ۋ9 O b4WcSKB|.}s亝?Z0>Th(5~Y N2"3c2OzğD0Zͩ~fs:82{)SԘNWQO%'HH4Ĩ p/)51# ~D^DSxH9)y-6">P}QRN~歾.'wEQI6MF:?YXaDI mOEϵ]-/'"(&Y0?I0;75:MM'} s/WK'l쯎PJSliF%"V9C]-KCzo\A[k"%4IKP#h zc)f_pm9 %]?sx)YQUY^?$YP-dɅ4+.usd~9SEx˅tmjAr}9 Z}zJGȯB^ɀm>d\g. w4Md(EtOH PDʇt1o0Tlt 9^Y |&ꟲL*Dw^<> QlaRYmWQ ^/K'` R7"nş+}:cފ?] ߗ1ͭkĬ 9soΐ0:u|wOspMArYAi,t( 6Zp/+/ s '; ɑ:tk2+Tn7!`)9" )Nn?$cҍ`[O"h6"O=Oebj!X3['?Q(GQ)0o$3z5[qg4?$nu]c-WS|XWʇLFCO`E v%TFwIs/\QDI(엌*_rR'V፻yrAÂoCm8WKx u)/ۭAtVC[?MY/[prD;Ք'oR U/s/$o&XQ =7{3e8y/uK"֠,O6oNH{ߢ tuT-s.r2@Μt;UݒB<`>"JҦT2%ek̖_lKEߣF?roKg)x2mS<o?tt06dԋ$Ip9:܂? !5pĘ?eSSނ?$Oc9JjwNGajW$gXhT44 m&ͷ g@}vKS`x"ǒ+2Df!/tU秏u=$\3uE("OcbOmnBQKeݎ?IX2?ܕ s \"Np=="[X*s8V{, &?;0ɵwLjq No5K?OOhB|O.= rV)ۻW6]&$ mGld` ?{  O$;H'-oߣ/p=1֓-,W|.CtNw4: _"Q^W#JdSEr\{N(#ړ !$f$/ue{q|j ҆8^͹5ct߸Ob>|LAC+\3S׸⵩~!af'KicwHaI$c6܊?QSn'XXF[N{zEr4聾m4h*D17-; SZ过QܟdΑw~Y=_"*loEvw cʌoUIOt~j e|3!mNZhdaښԛ`p(CK 'b`cyq.b,H#O˚W"*qAj$Rpu("/Xs@C>=#ǜGx6("{!l0uP#dh}e児'>UD$Ȉ/fS8Y>C7pwNz$ wcv"{/ڊn ZOj;E`Lsf^«AIvp|DKCSgaA#z^85^7ր}t`8[ķ!8h [Qs.`8! xԘ[O]Ꮎ^Bu>ث1$>'

COUG|Gsy>J@l߻5Ӽ{Dd?b<R9~?cs~ WY/܍㺧I|7!e2=RǑ@}Y EE^,VۆPñG,؄"?$꟨8FSb=,bDQP_wR3t5QW[ͦ~O5J'#ok:Ϲ,w~TIH5Ǧ&'OGCP'XG0[GJYXDi p@S4v= ƚN,⿧7> c+ps?i^t#xbP.ܻ'O 9D-ĸ5/ڣ{zȥq+mzs2Mn͓?B%INُ(I"Qa@"l: xߨɒ;g'?]B/I'׆s}OZӥ-tĊ憲lBn_=R9jEDE4B("t8|H>Nm͔NsJR=S.j8/I'S1 ^\UVRW=~Ӿ8o]{J)7"S.ܿ "9;y֪wwQQ!#T$IEQDlچoRjkI?wi|+XhPz5ZP=pwW{@5x~p=O|I?04+|*[.>{?p'U%}h~D(+PW48 0?al'K!^A"B4,iM|$RO,!bu*EXsĝ+i(zfXFu/8p"Ghas$h *IA)-[ UF #^4TZCL\5ZzI$3#E_.[X'H`eEKBfz1Ar.v S^(b2={zŭ7֢*x${#9`:mg"T7w'N 5vW7庑TLJݥs*Hȸttͪ?|V ䷪X A#+Ihg&YJ;ĵҵ*v)ƊgY-`gOxTAʢܜ'Ɂ*p>FDd>j0ZH;hOrTԐ+*FcVhΝ[KLU2.ꟾ2 YAܨdOYO Ŷ"9M3 gFSh6 J쵝²Fg 7SywiS>I.epA{Dk'[E,g9$ɝ:3>CtR 9꿧 U*_/=>=gEF#o?*Q$S7\=-\aS=LtSgV=3kήdc~ HK-AK.BtɴW?Y'5 6A=ϨDE("/)I߃ Zd E!U+QDrؿ6ã׈/iErRU;^?iENH$a1`E],G˝E>JG&cA-;~!$wg?ߣW76Q2 l?==#}"']z`Ed꿧11C{J/ ;'ByBWf˜̾F}Q},{q~dߣ1ڛ.Hyn-D'% .?.n Rviw*3eo_p.7)uiNs%L]0M@("Pt"a,j2_ bY^g^M ƞEñ ;O(.Vۘ("(˰r4ǴG};EvF)E\7rf=NmXԍRk߲'EË|3@a(i "\eKNIv!N|TB$,"Ih0X"l'OaT*b$#}nE۹Q)z}oa$Af/5h*k (A() Oqm-,9'JYDXY%BPz=Ǘ9ң[=&V2C6 |QAU1Z"t:Wj`)mARGOMX@ѣsC6~X@'͑ 듈?)SP{?anNbQIIJQ)E}7.{ scVD_[[2q)x^$'sr?I[OA]Z^f!zKWǮA4Q煀 VCQG\$ 6.)rJ(.a?]3FuEGdM)'=栠JBA=BOX `3E'UnӜؚc'FE"g'GOꟊID,y(R{zQK|Gɫ.墊a  9vZְq+|/qd"O@sog!YEY"#oNJտ"ru^k?.I=xH =~l$CzZn_OFYI'~k'quXqc}έ^JpEwI1Q\ӦC"{F1&qGR)(Be!OvX@*b 'M 6ne"c+u%S H: EwI(a1mW۳+㯯0X \.gb۹V+L$UW RR"-ԜYViǜ"OVǫW 'z -ZN ,aĪ{cf)OU߃&gN1?SwKA״,_՘R|׃ wANhR4*cLu۠=Yel?JX^+Eb\j(]U*{7˷ U4wj$WYO8)Zmd*͎Xb|"Jr%/VQi5P>͆D?6r蟂8<^_Sh6f&E&c*# ^ I(o9ʳ*OV#b $!"NZ fS f/jxEmsTJ0V4w?#8pyB/_9p@<(Lo:Yۜப,lM]kߴ"v7' }B){yyv ə}1YN O bB2p*7:"N%gU?Y<9J>*{1I=K$& _d]xb =UOhyʯ)C(ʾkPT|^㕶3.(öՈ>zGT?1R#4 bOd *^Ĩ? j\EMiCΓHB8+@UaIP晧-‚Pb0OWz$F{Hw˧x,4ꤔ>9.aCJo%ePRޗ#VH:e<^$D=G.AU9.U=ڦ?ga(XB*j_#$ua,r.da"%:d]CkiF{iY76za:yۦG4Yt+}9_~PDS$lgPE/@͐\ϋd۹)X&x8We"OJJч/]@U>kxY5 SOV PD=F]O*fZlzk؟ zyI?i5xݜOh/5mG%j8O~*{FroEvuޣ^W~pd"OA'>iT.ʤpZ/x6%D84XodUoӸ']_G7Ͼe%vCl;juQt1gߨ%ٲH_-*'?y6+[SR Q:r"Op3Rq nIیE3_Gީ 8dvU835?)Or0zr XdDvIUSYr7H\S}) XG8fʋ'=AIa(la^*"(Dpp?iDx#_3K O-`675tekg]=תSH]OJS*?7G*OԲΕl9lP@(fy(>.E ќUeS=ճE8lBwɻEG[sA?vuj PR}Y.8~s'qm" hMOuZ? ߴBMO.Wvl^Kۂf{bMOMYwAHgؠ ԡ&'YF͕EN{ OQGMGSJfEF~qsx:X:HmeS=xBh.uF,yqDMj_jwΎ9O%MjbEzbiz0)TZD~lIa75($?Wb˔~=Kə~AO ("O0݃/úgA -xHG:TS)8ޱqZ./A@vcwdlW$( MMORdjuS95d%2ޓt95ǟaz_NJ -&6NH_c]rPglW|°)0:O?6dIV(:26߃a,mѦ{=j;& q:ڠwO˷D0TQ$ռ^D0@OB`+kHn/"D<:5ژC]&wHJÒF-d\=,B`cTs7 Ѧ{(,ayOxsq MYnY|ҵ@f#^2ɒ{!tm}>?ѧSNC5 kD$]vI9"":{%A i6FP_Il]4̀xts(jw"{uMB\L#'EӉ!{j'!Ps+mh6MOÓoG 2<ErYFx FƊ./"<O)_A{^wFܽ/N-m•(nkVW[8ILAI-jVA'JKP!4" 1BM\ ܱ ğqVM':|\KMɶ6 70[eoEX!ژ֠Vta蟢*=2b7@+y6\򟂽s{ޱf?a#^*#7[W~N'<&]nAbF.Y$MP/BFɹ=DBi?') w? ܞ&ґݙ$}7 '^{!縉]&BbBllY;'R)aը3ɎbɫLE]eG.vWhc~\#O}SKm>@dGE e>aT`.S )>q R8)l[,83:"c_o("Dv[fc?Az7 ?3KT}a[c.ԑD/C"ض,wOSGYOWP9/Z%"߼:'[YQ^=Z z7WſҮ79(2Cd"/;]@/DG=;5ew:oJ Q$}+WdZ>w bJSЁ>6u[ӯu>Q?"qpjzVWYڋ"OQw EEqClk'tbtO2ZgTQ(j .kl-<ĝ=b5 o-z"2q"ZE"^0`jJHaw#gVn5A҉?4p+/O &]4S)]C=q{Ow 过| {`e 5DkG7y`7Ъ)8g*ov?Dz@'{ETWYP7ou6gͺ?ҡD~DקѾ0zB 7NQ?;tjD8k nҊ65~-d 6]OA+}_E`qsw2&NWSt?|, qT=8̅N>pA7r2?O*ojZjotߋHHfކKX)gBFwÙI ,RQ$i\2 tݍO8q-迧ZHٟrS}cCa] 7{Tn}RDꅺ!ZlGukXn'4{dѽsSD0WF]O5nݨC]OAibIӚ>*'Amwj?,Q 2$wC֪"g>م[,"thFPD'B1t ^ H sJ+ڦ9JHǰ +{?9"Q݃1!vrHWIq/a?0i?)D/oa>C %INXQ0;l5R85f3E-IO~a&` :HӶ!FPWDC,S:$ HKuE pGQn\*9QG7.H`X=iGP[sO 0;0ϯ^ows7Ur#߃iZT&úh?]j y)p,uX@?ɒ'gj?$h*pSѭ]' {nipT=UDZ@'X 过>.c:?*PjoS'!p( &NİPEp!|[OşR:?idGSH~O`?kTZ'/,Erq?\OLei yjSTy"aUI!إ"\!վ_B*&,jf5vr.m~){¦mH7JO'"s9q2dsSOC|yNꟊ0~ϩQ4 hOş4c-ۡ{ ۼ7S8[[rT=Mϊ}ֵ(Nxpڹ$YtobQ:%;Ij~mjCnN**Gn,X{N R01>li?z,A\E>lDN p ߴ0E"y*+(K|Þ?}!"i?ޞ<:T 2.I*H^lXXO/ceEߋCvt"O1hBWs~p˸~>Q$DHPΠAtdn',mMOOscI>=x]v  HR:qF:E9t֛E]{B~X /ˢv)"BD1Yz蟿)N?ܶQxe yPDIEeǹ\'|'?Nm+ SA.Y\?4Dwn+b-0$?wkH࿧Ƒ~ 0v?5>!/j.şԲΰ BX{l/şԎ8cS%{3 ‘]J=}{᪠S8Y.{%M%{Y:%{-i(7G@c nQD 9]Vמx!zk{(Eښي,k+[VbsrIFu ۅ:RD[WӔv S-0@t A'Al{e;^?W89uŞ@4IpY^Nk jKW*r8 l8OH.ZmDB O1fQ )]G{ uQ&P/!~B%fa./?S0*ݎ]p S$ƌK'jUn!P{=#\(\ dLz.5eK WB%{¢OV$~ mZX%SAsXh\RȥEVE /]g" 1snERK)7uG8늢ud?эb>{˭E!sѮУ=FIqt3^hC*HTbK /? >s#r &5>T/巉E/INWϱ(6SNFu&޶|h{VU3(϶> _O>JYDSuTlQDك8`̸ Pc؊?I?6O.% ۅ'|Bb 4YE/@MG;{!NG\7&JnR"E(w$ğCN!U))?ѣ&.bd. +q`b \i}o4edP{ߡ\*1Abmmd5-Rct!f_IIe:/SVDAiY/߻98Kx[H8k?P^l  ҢE<KOcn :9`ﰈ7z3"#Ζ}|95(*5-79c  #uxK?`%(aF_-o5>F{@=}ݥ^ 謹"8khhT弅SIu:ơYz.R΁dgKD?ш'⿧YѴ/2/#n`+KF$ cf/W"Y'յH*S}Ptco}܅%HIvH^"ILPwTף^蟺QDɁ#PJkgX,QZ-Da{mX͸Xu;73\PD ~"O_'KTM ?A 29iZtŻ ; o%FWZ?<kst-2.0.3/sample_data/TWIN1+fixed-width+whitespace+unixEOL+dot-decimal-separator.txt.gz000644 001750 001750 00000125625 11544160207 031233 0ustar00synthsynth000000 000000 n6MHC_case1.txtKm˳݇S쎛8ߏ-;A#w ¼6/Dy }}ϜWo1u 6T2#5b__//ӯ_߿}?˯?{??ӿ/~__m?뇯 ? /?R+C9U _q|EraZ~ۋnC%B )&0z[., V1DЈoC ea+ÎO yrC I0]wCΡCX`v}l Moa? + ^0_!/ 7~`h]*TK?ЖMWZ?µwC{.UC'MW - w)MnjCeӵU*]pc1e5UAlڻGĦo0 eI045l1F >^%`mZ%cM_>0]cp]2C z`H},}=K7Cۚ&(!=5ah&i0ʯޝb t[SZӱ>>?Po'!n!شcP\/v!q~91K-C!=qYw)`&Ǹ5/14CyVз'21{|k{6,gO9׺aXWCeq1Oi_C}sC1$X@W󿶇*1M6cƭ;bb@>]z21HR9f{b(r/ebh?jc E0db |Ʀx!212A05mش3pyO1Hlk51 Xcր>.cO .sCf콢ᡟTeL!b'Ӈ=t.EK;KjR >j]bh,EޥZ9dC01dbH?okyj}{vu$5!.0*f"Z|[M>*'gb6.1HZ#ХJ20x5ԗB f|d׿/H~Ŧ} CH{m ~1>s6@ݪ{{8w)ܥhbX6üYCyl?00^|[551$ޥdc|/i VmƋ2!b$Y3Ώa%Eg30Ŀ.y[sO} o0eӽ 8q7,;ƀ5JV|zAޥ. _0/V1H=>{uw~y F̻"=; ~ Ab q+x |#)*%39g`Kb8Y&C_wԯx}YŎ51lpy.1ӑo<:i>`@g006*D_~9. C qkNboo+kd|Gf'qX# uK:1Q]ğ`@ |2qkqtagĐ!CbZr_~K+4C |w?$ {sҮboڱ#7Dž({찇azosB 1@wYؚs6w)y`qs>=jv Ʀw<1g$zlN 766C?c&ش>s`HQd>l:gq?Ê5c:M^pCYokkd7PokƘ/Ert#>6 \}\mڮw$+(UsXAyd7\b(+(eüBIc`b O ?x[J_Ё!Vp=]: [IK ^1eG^'qkk/ew!_00gC51!f[ARyhvAV$vv7g\$n%'Qf^[x'a>}S v5'18ݿƻ%Yg`x MнCeuܮb&~&l jdNX؏SFN>N͕ 7P3 .b>=ɎA9#? g$:tr R&~ kxaFphs&?]>R_~Z3 ΂o\*_o<~iCqp`䑍/\;?bSt-NPgdstߥsh?9+E56ԼaF'"vMe>G`>2!mF@#S foWrvsPCDO{ܚBo\ȷUydxs{YCf/ 9rbGs(bj|$vκ9Xay_tPM M1xEq}k(ہ@>_xd?9`vUӵ?#1LM59$ʻTO?à~V4:,CQ,XokjU48^Z.%M'O?46SOD˫+e)CzSK$/7g}j".fߥv$R|U49Np?ڌwN91'17TM R5! ~:tܥ^?|s ?#Nb΢stZK97Ơ~:Yg~{5ews[u/aYz()6<.ip ]JtGWip y4k;76Ǖ{ bbP? NbV=ㄽ U@  شip]:C<=fmp?ǐM I<"$*ǟꗼ$6Sڳz덟Ώ0N.<@P)Zeegqk6k3Ġ~:%Px \00OR⥬~:%E7tQiDWydzYvM S`ٲ`oBfC}9 ]/!Nm?0D&]zAtlkDC̈́;=ʧ(C0ЦO4vߞij`NkN& Í{cꧣ=8bs. sY790lAt=Vɛ A1gCjO;Uqe~}i<>L qmFpJ{52P}R?M o{"9OCc'_qpG8bih 99Y3J_Tb4OCc;'o&<8t/, [?.- Uc0 l͋Mָ\s1{pmyCC|tĠ~ ϸ0t͛F9lV]#› 3 =:hbPD747kzdbRo >ށ.l`W<;ðjQ}-`̋vYP&^"`bP.CcqHޱԞi9PNy8¼5c&׳\gV~(z-E/c?# ꧱6wrGoWRhˊ15w FOWzy^OcWm]F-/n4##Vl FOרQoys& y%n4ʣXê/yЅKJ6|\E.m~͡l~\ydK.!Ġ~:5%IoÝٳU[S`fzӮP~#ӻta^tM{ۇP#Pҳ~]*0)9N>6]={aXW? R vs*jbxlsCM _}bXư8wb=S5ތ5xdfbP? =M۹ڐ@퉡C |ί Cp=Ġ~ܟ7ӽvwaqN4?Iw?~=YK{kk EobP? Oka&{1\ԩ~im 1g%?dDqɪʹ{`yfu"?{8fR>æS`!<͘Rk3ؚ`yf.6ut?0xOlZ1TԻo{b(GC\AC*yk i!qАI|vm1ە/Gǁsxi%<2[CXǁshSL{ nf8ga'dܝP=jO1f` sQv}J,~k#{ ѐbwŇ<#<wYjd!04Ű!Dhy~`jKİ=5c!0Tp`x{ 0HkܦOaҦS)~:<9A4aIum~λ pCUCp<0 ƭ7]Ǖn3?K6|xq :΁C|/&^><ȅ~0OG/͵Kag 𞚛]r5gH'; +s:[ǻb ce#{Kǡd~:SlV pOWq豻JܭOzdsC\=vW?)=qO?{A4v~<ŷI靀"G{U(꧱kLw ~b1Kǻ߹ w~A4.ao`hk aXu~:ƣo )7ugO?<G!=CYu~znPr}᡾MKy/1$OzY?~zv]w~x)7 6OG/VK6M Wo׍-ء]}F>C ~ 7{bxdO/=7KzkwAjƻ <à~zE]w^pvٲ; OWç?HEoxdiۜ"1^}QPsz=6ê/eӫ/ w=`nn0;1;x́6soKk zqJ Cga՗:1?f!-pck0TzTݧ {(#{ț1}܎a՗X? Xt`(U&zS Ow!+<_aC|'sX֣"kkCzw!wDUl3ҎaXƞS~!ԾjnX#Gi_RPxAOĀF%tj3AԗʤTm=EM wzd3~ɻ2{$uUeA4Yޥ=z~rV}ɫFaL HQg9fmM'1/M.%"~)s!Ǫd|Cheǰ|̵F>vƠw@1g6<`hU~lgٲ]Wzǰ|ƃ\M=M!Yy\~z!*7ͬ] l^!]*0ڽvQSݪ ;.I!:5(EΧCiJc{(úK#s=hRDm}ið|Ԑ "v=x 姳KYƠ~.-~70VvMK!N^ v1F;5fR6v /v<dN vC51ZЫL|`#`>Acu`W:KKcoGv.GૉAc Խ Ʀiө52t5t|i)L kǯ":ػ5XAD۬9[L0xڴ_6/ųL ?]8J]s쮙4[9]kj?9H ?]9{}[M,-?j١|yRl ?]bX,dl1ߎνz(Wyb0lafg`p ۖmokXc^I04bz # \RoCd̷PZA/6I,p ȧ[}K3^sYJ« ƎWydtLœ`Z,x[ zkksދfY>Io :^ꑁrˁ=kˁY/FG,Rl}q12g|`X/ƕ?npWa5za8P*w~ 5oCѢpS i`0w3x뢦]j/ZEAsyw#S y,P-bظE#s{|_JBz4fƸw'=MGdbf  T~90Xe/ȥM57~kOpyȈ6 ["^ M1L?;0~^c;9 FzK ]S>. u0WĄj_`<0gwI1T}'P.-~kp`(S>,B'{WΉS Xc^_ͯ/Oay*m]!;t:}0`R@9);2৻bX?;v qY{Ƭ{k~]zQ:ԋ^.黴KEq eʀ'St`bH\ Ȁq}k]#@*z_>sE<$*v:/5m}+=[ЦLkt2/bB꫘0w@f-Ѩ7gZvS?䕗hV#GV˒W b`XѦfz|9eYϜ*&a&KaD7t`XQ9Be/g`1Xȭ}C2>MjoڄOlPP%ʌj`Rmʛ|,OifZӦ^+8eUp5T$Jq'p`XhZ9_PV>$KMWJ쪟NxDxA A]qk/AVOɜ=,W!ҦW{Ͳ>[;0)pbdM{ȆMWa1Cv9} 9wwIse:0~pn e1|%/ dx8  \806! F>=j8d*"ǹ3t]:57|[8b_e-.+L6 KҁapaZp /'ƝqO'w{gDI!a6,,7VOEp#F?0(ǡ료|u1 n.UFHXۻlw]ʨspZQySֈfVM>|^Il<2̱屟CGu,Vv`Ш80ɜ<^vG& %9 5 =S<CAj#nqַ"90zd\|[IICY 2ȻyTo mffĭMƢWxdK Ѧi|  ( 9&O2<AϮWYK498T /hۦίw  q mMsXz g$C̡FVYa 9t9˦=*:/FU'aq738#kz1X5ÁC21TrN`XigE#恎siGg%D_u/th'Ag`X6 C^daAw@I髚<ȶ^,8;0ݓt70rrK&Xã;sb0bش+! '1J}Eݡp?uZ^0:EX¼ȀMk iC$V1*5|bӝ,ǭ/a22ƶ=a͋WjOBC.>ՍG&Bypnu}2m*HaU̹,v1i3Mk3.ZA~a40w唁aџ0/V^lY˺P8ʐɤb 3Q$}ڳ__-bkY1 w"uHy-[ܟ8uu(%v`PٺqkaoO fU&/ -Gj\&̖~:X6N9D<]ZE@= c܁!NJ2!UMY:{,{^<]0CsX;]W's2E^li }ޫ3XJ2U/x֧v_*^U4_uOmcX=Ws <@-4Z0֔~q5ٹ g h2FI/9K=J!. cNqO%Q *tI|$fIs`@}iR&0\$9fY{-#]>ԍQF'|3tR]@$1Kl]<E d4 Ҷ247 ̘mӶ=, ='iMdPFFGw)ȷe_3x`X?0`h֓(UM~b1,:hƖž ]CS-&Rb+ @b|P.\A1P"ѲI}ǻ*kTx4D%xz.IC.ͷa$] 6m-qؕT^eA=|B0%h"^˘Whp"òi`ߑU( aT<C)-LC(?{=AG:Z1-[6 IšPĘokqw``XJe݈k̏$u5cx/C=,ҲR{u칽69Iԛ.\b10,sxKeDzKT]j6,XI%p|l Ү A+ǕQ{c.e`İ%V\tT.EtG6AG&g,w} 8f~ R++{mK>w)~z;$b /pe`X}ꖠ؁!O;QY|>};ܥH{!fN A;^ސQ.#]ӻM] u`: Vt`+oɄ-ө$ZkkPb@a5qLK Ӟ'YƎvL* av) lVVnW+*9d׭5˼Kƙ'b|ΡwbSHКNl vMqShG&=E}zY$a! hM la(hf2 YO]a悰0@m--л/Ze;Y4! Sщ^jE0,ֻvYޥL{a~P{r=V1K+NSĶȔ7K|ķu>sC?hqFwL옞lru 3^bon[[f,;;Zw`P`ݺKrAޥjdy%XlL`X]ҁ݂)"ikepHOs:0x`@iI0/ ~5S, ˻4c+Ɍ'e8Ҫ :B DWxdrDIrQl o701 i{[m1= -^Aĉ 6$&`YKIO1.\3~EE?0OYjr2G\bP$z3#^$O oӍ԰VrܥCii҇^%hӬb([  _䍯Ȳ=m%;Ê"~1xkn`XZ-NӍ9P沜iBVԓ|,~PE.w|Ebof1?KO 쫙{-{?D>Ri'bX}=z(Ú´'yaˁJ2ڑcp8Q;ʋ9@ SL)+V|xd[A!H0o q1XVyOaŭa~\4%>G_KܺIw:0D+d%pdE9hlZ721`C;1|Z9[# }5$]Za`QóH(4.ڶr7ӭo ~U 1FsקCs0l?pf`.e|z㚟2)_^tG$n]ʆ'P $Ԩ f~, :i[+S3vs}LW3ydS|5!bR#::+RMĦ%n Nv 55! g]*&i.2d֎}}P4l{Q [JnL̨<?AoqY,=>P;1F~M k zqWxd\}w5L9@Q!'[{qW3yd.qPeG!6:o OKy]ց ;.15f'vn?j~ p}У jY` Pg8P'։!Co`-nT̾`џBxPCߥuѦ K\zMY CsHI0+:76ƗFˑ_ŞIlvbQ0u(wohElz_#~[KA1sX~:02=/"24ߺa|305{:c:Z9 eC bhrDc'V  s cj1/֋߾Gv{z4B{iաwRu8M=/u`hzfcp'fJwզPأ^.ٱ7{YBkdyo O%) C(ҀZˊh"H \8 l VG60YwOqݥI˶m^"N]Yh10Cj3^rQTB1WbP;x]-+xdE/HM`N"aGI*@tbu#Ԭj\8'ŖN6+Ȣ͹ȷ56]qbp CLԛisMRXOmNy6D.aU}K{,f^SkM3.I>G  ɾKObo.0ñʭ(8}bp%w/pPwɾK{z ̙$bk+%4SPBwlAC9%ָشDaKmӶ$b^eqZ~V9:˓^AT'9{#tzssh{nc'>"FMOTf(tnY3M5*}TsgkPP`B 3I!rh=IsLpcӂA!ìnbe˹5v넉aɄvzZJ'GS7.ȧ.3mœerY |\lֻ~:SD}9Cqe)Q{(5] QS- o+duM9,?R-?K9O ρ;R[v:w/[|=6U3 Q!Rd IepCSo8-=u^[MVH]rJĊZEo统ńZxv?ß֪ۡ2j$V"#Kf*_5ڌ}#J \FqKeGCd5<<)o<2iX%n0u con] AN?w0y3~q\50g7y,%/K.u?i>]4sQW,k)&reO}x!P9s{([Ogb$ {y]qqbղdӊ!=gN b$wXU얠<&#˳-tCmھK^Z~OQvNS/]:9x$ǎLЦuI=c:L"]jgoc c5oc{ qnY׸4)BXˮ9[Vas}bDՔX9/EO`dDKi'ubޥ]\E1aD=akš&hy\ ӆ=$7"  ֞a1Aw_&˲ ɧ. s.sځa&)]ȅ&$xҊ<5sv?jl:glz3&* K. 'kgBw]Jz6@223O.\!.l n[ p.s'`X| f.yy[] z[;J~{=qZZaVZHQ9,[_<Da'9#L Āԁ -Dqj3 [`Mgx9̞;R Pס%X#ՙ-yΈs$lӊUz}a.KP';0VH~q`وub C@*wm ǟ SGww Mޥ}&f׵+0o}HaK$ >..|M#|?'C)\>0gMfKYOor=*0'P5׺ *v_T:Yl,2=;RǝUw{H~\٢<1D`hİEp€sPww)6,fԺsK]*%֌]ؑ:6jc>z/%z/ۉV@q=y 4&@czOm_ +<14.me\ l.wpb[}|uG ٨vիsAMN `3.en*zFv \<1k{fͻbeQ7ebXڧ.f&ػSj@:1aQ^I\I50\ BK^arΡ'9 V! չmPWǬ3~.fCkOrN/''00'ʬmok?}7#q q1ܽaZa핱wHS2&%^*~::ͧs`݇ N :1P9k!Fb@M{ɧK0W:Z C*KūdViמT|]m:s '0dO uݥQ3nα{N_̋UC0GRs@u1C>U&#kCY]ú?bL/Vz#OO &Ħ+V.mz()$Rp/C0bkW8LN+q!Exj[SU.`?]td*Mq; 1d=0Ac<ґY_*F C]rV}/2b.U9-ז f-vXXw)K2M}`Đl~gD6?J|bw?峝!KtNmf^=ut᧓΀+CJmPYsV 7x{dbHҟFvb=,݁adnE󚼸MQv ?K.ʎʉR6v-O)'zڟR#2K<0Ȼ%o 3]rnRu4E=N :~_oO{KЊ\&Bv  e){ ~ܖ?7/qi80I/m>.>+Ad!yjNr6Eief LW Z/1Qz2!Jd`u˚r>09qt%OW g 51 џnm&,.uyEĪ6 x[[&Vee6KUR3ߥjٴCW{hx[[ 3sa/? G!6-*[.5|eAXH*Cb . !?tG }0fh:z呉VY]S:Ԇǻ4EKER1C}5^l.R^wA=MF5"Fn@;U]Z=X#~W@C%n5f"9[j1<1T8h+90]T&{hkVY ?ﴼ4Z?'ÜR,0gV/G&#'A> F9 6M5KZ/Fݕ7cpg_ R]mB2[涚qijj YSl μ|'O hHwF5]g8L?ie I0≡Eox)J.ji\; uz@Y F?] ?a04#2xguYo]eI'. p>0-v0'IV`ӻ=X12bcuqN[0ueM ؕϗahmy\ pypr[6]#{ ]z'4j3OyMs6O8}n~{5,Y댿1 CMOjXZ>fL;Cux ڟ% Eoc(@s[aM?ͽebj`ZQKο16L?N{a)f3Ӊ!=z[c{fmܦ~fRTĆ{kѴp݀<1%sV[@Ñ';N| 4ȃlzL/%%BT7]BB6\ubX51۝n6\KxvO _K|9Jzm w)7`;0^**́M5;xs1JQ ŪU6$EmF"~wUbeyahqF`ޮQ# J !h_ߜNq=Axd<\ae''%r=4w3Uv͚@#qo=EKQꋎ|_ p|9;Խ^3^].;1x?8xd[u ,Kfnޮ)]`ػPPe(,nʒ{i=:TCP{(>.st`/(_`j}O 9l@2vL?=!)k/K[@PhjK޴T IyOo4rY|=1uoX{`<<.|oMƾKEw]*aˁ|{|\TwEPSw8 }~$0R]b)6~bX6]38X=puϠc:0X<6w).qctF],Q/"!iQ S f>>"J< W.}^A$`47 !M{CRz֌҆O~=1<2ށzwI?2VL\#_T"A6'IJnm>..=<. o7fz+l0`P^e ][ȻTm 2c?zd#Mna`m $0$5aӘK9KM!z CZCɹQxT,ތ!.5=ȷ έTX!?_N pwo; 7t>Ką9z^$dv ӁCsHPmԍ "M>1<2qpDQXoQ2:mCqC娽1h܊Xcec.kPL s]UNhY۲I5vʣd[Q@Z&Ž/ wuwi7M=s~]jSt&k wR\wh]~=9Cx)7 ?:'3rq2T#{1Tbs(K:tˋ3r`sRΡ=d֗0daȿ.![V}n*u~`6g6-!V$e󁯭.=CK2m|t 2Xa[[顿4DϪh5l<;!93Ǎ*ҫC_*q5ok#HfO/֌_ǬJG>.?hQm?wCet)Ԝvڀ2am"-_r滄9ƻTZ0,.\:~Yax$B't`/KYʣժa˶RۭR6Aݜڏ쁺H~9袳k[~:D%\iѦCOK?.r V}bH9k9i0u-a<0z,A&LŊ[i?uta2 & 7fe%R*%%6 ؇R{g<$z,y.eK};laЕva&9P~h0, ek.cqF+bok7t݈p5̖!s ڧ!oC1Gr4~]`CY0TR#Vd۴y}'ɧE+~ǰv\84<YkHKR7$ɧbfYwÌӴ޺a`-Oox}$.NĀ8.FXoi%[s-I>]hnw5=!ݫpp L0>Ѧv°)ޑtUBx#+2IM^UR:0ʖ5Z{-uqBSO|IN P׎#a 犬`k9xѲiѽ4Zì.0tA֯riQN 6Č"wy5  Y "{w?00-I'ίXhiRMT>oFu2V+ Ec XDw/ŵ]X(:՗Rڌ,A' 'P־,h s]WWUF ;'o+UI4Bdoَa6tݚ^sbH&jKzJÚZƱ-|¤ƉXb!.Ui?@r-jco{k{'GcUUMmZ>0NCrLNO"UD40̽n)ҦF6co; '"'"1иCR?kCP, +cr}6w;/)C0TЌ=ksڊ{`qʕ 96+`6]C Z+? 店vmL,>d=fTay ";N8(_܉)`=8bhm[]J}X:^/*swsb'U ͯu`hT 8GHi>0lzx0#/=E@=(L{C0̧h08 }U.a݉a&R/ʙJS#w)9m#8Z>/؁!6k?5]{YŨޱzvb(\1wty`]iӾ?i5"B0_C+󗼸ycֺmy+*[Ds`slbΡ]j|=Rq;0Rلxnݷ$j3^zꗲ.tу08|tNȤFu^ִ71/u3~3pxs`Ɂ}SE\%Űj%X4H°8X1. ש"b iܥ#}xVhlrn1-mWŐKGB{.tEFn2^0dޥAlZcDmL g)~`Z=/Vv Ks5c _km!ή,w5.Ny3i#s#i}bԶ@{XLsX1_s[#1T+֨f/ |=}c.d`H]2m'R7<1?d5r䢍`»O9#{ {M1TK`, C] s*d5!) ȁ8zoq0E qۉ-0^ġIKCmˎ7ڣ~u6÷*N , *a%LL-`Mu>PaN졼r]aA0{8][LqRkƂ>..y}]ʉ׽RO3N 'z,GX|`ydֻȧbmz`6D s!]l1IH:D'S7԰~l*tOP?1dmwiŭi\[Ibÿk}RA$~1>1~ڰi}1Yn5!9b( @wjA4K;7tp[V1(q+H}Vˤ!9d {$SYFL$FW:Z(v?ț ٨U6yUZ>BÖ?Ru>(Sț ݨ>C^V0pns]052oڴZKqKؑ1/wwY#1|g/=yܞ5ܪy 0_{Q{1Qy1駅Zu|[~@ :K(eY{' &R1m:GbU i)P;{CM*L.9?legؼ1ߥvw4w)mF]NB>N!ޥy\E."~:fȧjH9rUݜ9h`(ji%%b0Z&vU a  CA}`s8%d9#66bxd5 z[=x|CY:F?n'k'<=T[=ZaS֞& (ok+u0l g405̒=z6S&(7TZʎFlc 6Yul <b >a 9rE`rCjqAE;b I!= y\R96 ~39jȧ#05hNq?yY8i1.vy0*KYȤ[1qûFRa S+/.3 *R \'>aR`x 5`+x[#twÑ_jx i$ɧS4r[ K\12ȧd0vOOok1Khp7Lqfg4bMPw.860!O Úirɉ{m7{cJK+zPikFp&ͺwOj2ka@Dkj@|ffZ f8w)`@Mu6%'Ml:~ڎ/~;걏w qk+VIyCs{7k@P<1,=qkF0$tt3u7qkVK|{J~]J.~#8(?@/!?)bmL. rh;Úyۨa麗csq|\. :]"'vQ>̼nm1_]GSLK>ZPJ1m:>01 Dh\ػOEM?|`0cV?0x'>{(ZRL܇l)>N#H{hz ''UGfo0$f^X0|,G91w{Kp/ފ$pЦ'd?i5?l =n\:֜bqSmB?].i >8s 3mL}~؃ȔUYH沌Š/C]¼h&Ò=q,ZɿsxfӐ K8/qZn32ɷCßc`u?PewE9eڟX]2Z~C|绤{-R 5^°r fmsNb3u_V_GRiͭ9Rl zl}EV ?-+xޜC$Kl?n3Uu\|\lY]%!ɻT|Gv Y{c{5+]*ˋ49kmbo̖u)oCPښhj5KŌ%֨v}[+8eul=0$?@$ȶ֛|׫_=0s|COgΡoF*#[I=?t} èHګa%nO QsBOiP6<0hH2=j<2]ԀAm:m<Ё73TKqm Ԧ3VtLG|>䢫kᷚbP{з5 :bJTӲ>zkԦsjcC_Axi]":ԁaJб_4xҦ\(}WΡ̻G64\8z{hf}b ]7;Ey`] Z^ xdjq^졙,tʸ0hf8*g8zg+Ϙ5/Rkb ibMб)ޢR~{ك7cEq,2[Q1.*]x{_ԉ= ^ EfF=r8 y}ΧBb.ZA}ܚwύLSUzN졛ވ5sڌ`P{L +4 ;;R{Asѥ}Zɻ7ra` mFPn}0DE|x1Fڅ=$@Qo+1=48co5010L6҆A'4Y`w 48ӣ'hsv@1f/(AokԘ/5h|c w]j@nf5f0gP.H_ rgړx)iܽ6lC(ks(Qkr ydbк8ĭIcw_QJαVWۦC[E 夗UnȞI]Z/&Tuֹ?/ތbCA%qYc>wiu==cEa?6|:k?H :{ ׻$4:\IyKCuĐD3g:8u=ۦ#f})pXR=i}A* m4|yi79ly֗Uw$=1g}qEmmEy3t{U%$EI}]Q"y~n5OY6ylYbWԦמ*%ٲAv^Nzf|ECQ?𶂏; ,z]#46C(:ĭ8j K$/'sYG0EsQ~΁!I} )YVm Y0Gu>O{u{'sX5xi"6yȶsP 򸺽Kq+ĦZeX{bh{bj3zI8'QM{-x&!\#nnT¦Cs`M`n^MIr(nvrn7# uNLYZsH/<2Ħ%[3G Ҧ3l^K&]ĭfh_ʘohc#}bDNbWPs#΁~s 'WC$W;^R{ZjgVAj`Ġu>vlnoO۱4ֶKMj3Z-qnqdtCqʯG}1bKӨs5&CCx5@a904i_oK?.T}Fy((E3>0`/27 DR| Y:06}`kxٝQjWi|!`:bh6/y('hY%[C,^@o_F9')dPdyO f/Kr y[{ZEW:CG-U<_Cr<}\:lw>.?U^ `Xi5œ/ CyT3ux|1db6Iaj27Po0Gqk|}Zs-Tȩo;c>HNJ=㜘Ǒw)hܺ8ø=AjNz?z-w=˺KUгK>xb` d*Q Aj3͜h9.ͦ0$b@O180+=ŏsgȞ8sg(/BK1sANu#G[?p,"}ch ގ!ChjH u`(f6j|IpnƐ'A~mĪ]LT&UO 33 K?fltfscw63~T81H?iC'c{<8٘u,k3=ʁeӅF~`Ey[0VX'w[V|cF;x|f(̻\u#{V`Wklu ?Nm8W0'kUyd6،5*cZQbb@:MfێA`(MϡeȈkƞ]jV|da/8JVU.k_I?NfuT&b(R#Km-V_UR82@^e ~/'Ǖ<2חշQ(oWfW:0 ۠{f]9ok*Cqwbh{~%F9 Q_A&W6b^􍚛i[@zI.*xŦ!#4,w՞^@0 G ]b,w6 ?yi:Ѡшˊsuj~Os A}\ۊ~\p *T3棾FU=2d~úgփFshyɨ6"RA.%K o+zY!?@4'38dLB썜7Hp3srsGcHֽnF60gw'dſ]JG~:1^KkCVڴEseKwѸug~=!1١?̾ei^#[Ǩ(AfN=X/hәy\ѷu폓y:5ҫr C.eη4h)vFHU65f(sYHEscL?]5X3LP눗ԗtv]#.߼ywIY;ZRZ6C \Pk ]Y?<#3u$l;G7JȁC,m2.O4orʷmZqxw0+Q]#Zmx~oGhz %͗ɤc[GhӍq3CA4hCڐdr)c7zd7@ |[`Đ c prZ݋M{y[wwi6=L 9XiiYb#co!pcХFPcdIAC6ah=`=fQoumJvy @>|sajydѼKO1%9³ۣؗwɈ[tt=r\ =.-7??U04C"{cv{-)̮ gwIsр\3f`ъq)n̹/doð͖- 31So&@kO8I׉<[sڷ<Rz|nqkwI>'#$'mXL $F.1eLfLf)w?Ӷ=&лa( Wm{bo߭h}֮60k|:)6?}>N0.pv|q/e̷շ?K>k@M}$9O+w)6G 'F}1y"9vC?mbPm [;)?$)*2y[ohc 7qKc0f, ݨ/%<%C KYsYڂ Rm!7plnH mhMﻤ|7æ9pkWw?=s|ND.Y{-7 / :VYI\2 6`{z/ش"VDS!.YoKSc0ʉȧ9a8VYnNٽUs3X_ #P'<=cuH$R4ŕԠM9`كbt;+ 2Ky96̸tv m'E, ^ܚ0.O ŲsHİgJGaa$$|r`4 l)g=9EXy}NÖ_Hlf؟.MƠʼޥjpC9r[h JVȞW'RO Đ̚u3I<1wqI\|MU1dȶs0.ow)eGI졤6{`ቡY;mED+;,lY͢+Da˧m=tZeԦMEVHA%m 2e,]D(hd%6⎡]Vn10ūAĘF3m:'w7/^vMq"M73.o0 ^74xibp:`ٴv"^#:c< ^?eA?Wa`+#.F؍zޥ$Q|; :&O|lxd]ʦ= ZCc͡CSObCLVq!_rP'>()|JovM^CS聡rh !B bİjƌU_ޥ>ʂ?d ]0֗ t a΋ ]}\6%a`ӨҊ/N X^y39toI0OXL pz^ud:˦ljY1m?Up²1ӻb^ -M3[ܷC KTZwok|l Ol]R E04`Mc 5;P\XhĐsh 1k䀽eŷ}`=F8;s rՑV?n`h8iŐ'fݥBgwӏS KX6ؠk>8FZ[Gq6]31,.o֎U3Fk e6'* tmL"[R{co鋮``i$Vd91B5;!qg{ 580ttso1Pma}BEuvD:'6MLqi/y%L:]o7"0dbhyaKC`.6l~AV$*n)Q3UdumL99MK.4k]bÁQO@m:ì*ky`X=YܮжdȢvcp70/Z#FW.ե \ۺ*-=CZrד~b!/=kvQG#0t/Ty[1d%̋ YQ&X'?zY=$KlZP'=1.Et٨dY_*/Pzɧ*{2tq5`]n ŐGr`F5z81jMKPpлP;0]{%LFoֻFޥZ.ݟppM ݷ|Dy`9Dw/9dɁ |wj|cӦ/E`CEc6x _ρ!Y?asDQ z, :K4֐"^Ǭب}`U4պ.EU~b(&`WuC4mm.j!SP =T.IO; O0d<$iY@a[Œ8W9aս31fc08w)I7c&Z6C'3F2SC]֞RVݛN#{AAIU3fJ*R6QJ[=vbH.Sk$d^ށ-jZuo;`=9 C>uK衔|$|BVЯc '+^&j +-aRtbiE`5(_Sjۡ4EPh^oM,Y [L =qr+Z]X#*Ӧk4JMgB]+P"n1#e.uo"~ժh-=4i%3 .EiV _׬e1֬ka0lZyv;9ꋖya.EA3Ug6}QlF]œaEg]Z&J:[kic!U]}"ZJ[0_s^t#Ƶ"1z滴"T^V}`$9AV]=VWD,=umEyѭFY>x]u}сU|a sQ֍7ڗ#5T=9E:TޥR̷~Vyz1z(Etd-}aqC]*q`_l,l}QOV>;antzQÁ`Hݸ$D v` q>mCzG*eh#,ܸ?Dv @ f^{_컌^V7cZŭ1[w)0^"0ѱAաNshůEaI #0IE{a'qy4֭pW1C98{b/EkIe˳ (=M N?0\xow~:Ҧ9;{uP(,Y=1 镹r=1L{YԕG?q ww!&?0c+sĦb+}pC@ GvŴ?SY(g[~[FǻBs WsVE|usNc+с!S+ ;|bhrs]raڴ1v@7#b`.U@6 UVzk52d!<83Et}` Ⲏc=0`|;H~fŇ5?`m K5ŁUۚ _";ow_ӽ4xC ؓ}b˽^꿼6ltNqj3Dj d3hW>r{`&CN j3vètV7=2gap nkѳ&7TsQ'6.6sPaz}G֎[;!GvgĦvʣs=Cxi#G9#)_o<2V4N C_RZMsi9/yoމ.By@}yo@I!Ч0x"h`}C|90ncMp`ؽVܥ%tגj"?dqسsbX;,ZkZ3's~[%[,PҊ]a9eڣ;! 6=h8;@ )C:kN h.m52qYtBMnaw_&6e1VCzds@6]0ސw X fܡC\C=$}% ՝ eÃ{ q*6I|C=vɒ6؃3!Cjİj'i6޲Gff]oEM %6}:%X3X&mi>ߥ=ThcF qL Y, bO tbfqx[S1xbXs-WƭClfo^~bxV#q 570THC[ΩCYu,Ua`yd!v˦ 9uh #m]>>"~b_1=ܥM Ts"8q^E^'ѕ|LAO P]tE5ꋪl1O o琑Oj|塁9P?K;ڃzhlbQp`p]Z{8DZ]a%Cis71<<0S.Eb@]#9aK2ګ, UC&LlXz-4Unt3)v մ5fbX9[({'Z-81Xe͂pPC'5y+nU ?`X>b]H IܺKݬkkĴD2AƉK7{}qZ_B,8LE3^OaJY_D F'L6c ɧa\xiY=m 슷AlZ!uV 9eC 68o Ա>?z3]Ѩ#aR8X޵ODʐK5GV$j\l Uͬt+|Ԇ %w@^䆂4o⧫`M{oi%} hN 0<6*ȌK%G%n-ǡ1pbX~ەYa^cڳa/yGҕ<'YaSm:+0N +N4K@hsn:]!3z86Vrj/Pîmgޥ '" O+0pqm낡<Н.jc( |!b ׎Ա/_t!Q9Ц}VFYRF/F\.֒R ,ȱك}z2?xba/dؑơ7(KU8onv:RX]˪KШd~:.Uy[C8CkK. #9iE FR9`AҊUV- +7ߖk=08lm6DЀD o1.iT'ol\]WdN& H̗i%ZL ] %_a1:c ÑmM@vm ƀ5YCM@lydc8XP# (d5Wu=-(6(Smʹiwo+ ;WOzDİxd.pŕ)fb1Ѻe2/Z8_y *Q}G F&C;fϯ.n)bazGӥ9kk졙>CO 3ë-ہaluoi*R_*]%vw ea@}),_mJsH59y{{e\ӁaZY%;JS1D{(l|Y]ފ!Pw2a!/>vԽX6e_Vw ҁ!4Uڴ#=g?bʏ AC714[;a`j kZ%⥗UiUzYմ- z!mŬeDU>Za*?b%b'1mŬe\!S>$wIj4'91xC^Pa7ϡ,/jMVfb\9o܉!.B0t?  e)>Xm |\^ӼKSiCwIt6sшw)db+^!5D]v)}68w~Zl:5WtpNgKcOw}b(Vd%=g֗"b>Fc4Z, Bz|ZkFzO ӃP !/urֽa9ۦ] \%aLD-m6-wBv:`ƝûKߦx M li_&r"4Ύ[Fy͘iC~yb"gLi~C [!mkf_ti%N:oC]`qHA~<f78Ij3{TK8T c%/MǻQskE^!MU,6K.$gCzc|K74Q+bn] %GMoM$oMe5dYJD$^RwTOΡ|vc"o&aT&=r ޑ<^Yy |[C&-ױ(?qؚ^C(dj *eQIh +8 eIswzAc>{@m&YKIa)1H79_l:0^~RL$DplOdžCn9loMsv\KS]K-c`ȧi^daHAm$L KOu%.̚A1PI|ǁU̼g;l3M fb`.l=t?6BTrǎ?Al ׃T3GQ>ίiW9/vYEO G(,6npz}r fV70xhyUz$].5@А}液CO+$&`toF1 .UАA|[s-?git9DRT 5iTCkY7%nM>n`{}[+VfbkZVw`{! fK73KN0,NbD]w`X5|n`H~w:.}uZPL{ ob`5f)K Cx;~]IO ͺKbӶ6sLTHX:1kpe\ 6$;K. Jǁa":1DO _[k|ӬU:95&:4u@76]ƻ5HaV}K918q`\V47F =2:_y{r|[5Nx[15+^}˦J7ez;q o+K -CE>} yȬx* ٗ𶲾VDZGa $u>i#R֋!me} V35 wXk$MC$m{^0x[1buz[i+5A?M@Bb`P?b.:& /<.R\%kiX`:"4 [>dyWq몷8rY졅Go+%; KY`1w :h30ltY%gǘϯGj6vf\3S~A5BK_]l?ݜqk!]V\-?.PŰޛU1_aPs` 2K+zzE?{` _t[T/ C$n_"tb|я/ޣ6B]:X.9h]#ҖOtYC&B k߮60(v[hg<261,V9߆<,9绱n]Z(NKYݘcGѾ~L[n9R퓯Vc_;|l{B|u~J,ǥsݏz'βhڬ{)o[V7Zub+)oa>mTcYú\y>;esy7ek]gI.v~^s0i]f.=v3#&]u]y5i9Ic/#IbN:הMs\x6z{.]ʺ1fu\Yt~Feܥؠ^IyJ3x͡o n6MoWllåEuSF6N%~K}FGZoQ:o˭MVi-y/*6.{m=^f?~r3qj!ފ4oglhLMy[l ܪZf[mJQbLon9}ƫuI$?3Wy:ɖ{s̟变Z߅֬9wiuEu\Fx+1~}&Ѡ*nngz0}nEmM7Q~^wVيnXre vld؃mL8휖sB]i(lƕhtئVXk]4%LJIma#^eO֜g*%X-xcM|:&\6yVk0qb͆%1m~{^*Nzisgdj :}FaL*^ϵ}BzfuLs^kæ6vQP&-{$q[qvq,s3q=DILlۃz晵mDΆVcEI~&KPq=Tn-"vmOk#8$&Ce&<y̡i䝗ЗY{$Ò[ǜ{hZiiqImM1ITi:֤=KØ.mc{,yD%ӚIe6y7D>xR|ґi} ukx62"j>Ls2x.[E0NiFüh^瘸-,.ޠbDbC1:h-bsg9k[ 8xctT[i ycg"1L"/%mNqp(T4l1os7&X )z޴u1b~b\hLC&Þ&yxMӜ~7$qZG&_g}EkދQmhRr2E)ʶfŲ']0Epр͵ Xxh"͞LnKiG>䊭InbԖ=0E&bD>Q2M,$ޱAq>[BJLq +MbɐE-E55&_1a9\"{Ke\j%MQ>`K\p#y17(lDGĽhhk^48!wU<Y_b2 Aך;bvܟP uzM}#kǭ? Mdޠ<:Tb>x9́ĸJE LrMs\"Fr~N+l5I|h9b6Z -EcfcjL.2x2xjC~[t; 06JER=i::Yt2Z̪oq,nȶK<8۵}5Ҳs&6 ;{>ӭxx?mt"jks7jRbcJYkbFxbXg Q/G,Sb[cJ%~Y3"$jƥۜ(lbK:!UlQB1c+FYA~־DH6%r..',86;I$ćv;yZٱn\s ZZn#^mKj~?bI͘eR[q(i>ԶiǍյõ;ףđ#O絔4kIZR`=Z\bK>#K[ٺmOGJ̲DRmG=JlؕćLϞ{t][ؔR[Q|nH`ձD56{./:|HLZWg6&mM5Fi/Q G$F6w}L4#8|QwHmْCUdY=K=Q*[1|hw9AZϙq!D:B&UGp{ei5e)=+){mTRvǤQWW5G~"Y:lSpV0ͩ'FںS-ZMB?"YԤ:i_OynG}I:u{VRIHJEsJ3AG3}DS&/uQ洺 ]ꡮK$Ym }Ƒ1Vt[f:LYKzuͰXWcfgIyKV}fM)F eyEV}3zH3#KX#Ѹk3(|o^]m<ͨ&mH`+5)sYP9e&=[A V+󡫳ՠcv_{ӬẴF]\2;/_Du%)*wԕKa}[Ky%eQcvӽؕKk%vORIOk`WK3JX祢u%_}Nt}gMt;E۶}Α]#ѥPN' 4"{ِ>${QwQ Ep> *hCWGQf I-i`T~+IY6GL~D=r3lL4s+zFS2+36ؾTuYZt,4@L|Q S~ILWϥMO9k*kх6t~ERYѮ\ui]XzBr)$Iy~M'uIKv,u+iďq.Cw\.܉ Ā%y/Tۜ e/k3J]?vRm8tEμ{:IN{Dź+ˑ1 p`ڶ:oi'2t[>r7v5"7 ^.y82t)ىu"ZVQfn]o.{Gz^ֵ<~̓~gM˥Ӏi^xgI'nH˅bsӅ7ڝ.ˍ@\:ρڭeK N%^xw{K6gA#p".y8=Rmny0xрxS /7)&mn]]mwNu^nʅٳ锜Պr}K4]f\9/\׸w{[lNK).u:ͳ htΑNίb~9%nsM+{MTqӜlvE۬|CSAwr^u4%6qg"u\n2Ke>w#m,t1(ř4zq7)&6޷Yvo^[ʂ! nTxmvȻ6G$'~߆:osKħ{Ж^=$W[ aUgYpopa* y[͘˵6cmxn|Ӡ}p[cW9GFp׺vji;1jVnS'@GҎ%5is{uw8qϤvFp 5*JT 8)k}`xkAp i>LåJ5(1QZLxϣqS{#;w][Ȱ&϶Q]k9׆Ng{R:R {gf@CN=X"8׾Gs>vNAsa(vd3j{ [.) dܖ~<)ג\s/q>rj@o-Px+b  ٞ JB%|Dh,ÿ@"̅36QPApG; CX$D$}Hd-_Y G'Ag:)T6+D@L ] /۱yWJLq9Y,E#tֵL MBPJ -v[`1M8q %s1biWmdB<\$b!uPKG GFY 9bnRu::MOWlǐb4$4$KbK30KPr]ᔈYB%bt+ :8DW`H\ҫ,(QKLZAB"y)׊(mEECm #"ks:KSQ(F;ZQ+C, j% dvƃNtK%db%yF0>@(Emk#jSq{M82oK^HH,=wmJ%ٺQ:?LqG\WK"fm-c mnStmCg6j~/[U)WlؐK6<%Yxُt,*D[N\Q,I}];w7*qnYq/v\?9:$z[JV)BWarΗ(JA[ƍ%c^2] .*qZw'o()v*{\k[($^/[Ro9?0Rӽ ;-R[fx]Zma#dS<婞G `E^ɡ2 M0ΞrS0鲯gtÆ.u`Cp]nL)Z X~Nw&o|frFYAGPCR< )*b8\l-C"۟ H{wWPKmMaC=Kp:[g?)t$u\."C*!*:ͥCqEҝ?!<2tx9A4b+= r-ͷ- jqЭlUl 

9.$!Cp8І/R QJ@J=Ea @MGD%0I%}߄C|K=! /smPʨKeΐfRuTS6hd@#.S48tb )jKs ]c0kH/bz.Kߋ`Z(:ʌoQJ'VK%0{Cp4!/%|ۆHi rRK gƊmã}AW`G SߕT*B{yRL/C|!5?! )2;P'AP)C+n^op R":JLy~+ߧߌC֔]JmR*_q"[!_++L>cZ`Z%L/`kuܦK ,)pO!~5@H`y]qW]nHo)xXΥB*gxg/Rϗ0| 'F#\j)oK?RҼGJ}+0NK "%xbTf#8?݀XbɷQBAh䗔i>r]@uG2e.`nۓmAؑtסXyMO/j>L>Yd~j'G#h%G~[JsܴP[ZAt''R99oxjOFeJ T6B8VuqjӠro v;n@mɟa?vCUݞYCm}&iPۆoN?.>'Nd|R|]e:>6ng灼u(|A+6[ΎgAG@mR8K>{XeRo :<;&P}9cוCzAm{ob&Pmqjuix*fqĶL3e]nn+gZu#gLšءmoHכIc#vuvIy= n󼄰lt&cڂ;B':27MNK:Wmd:ۯRkݵ>׹;"w: BlXm ?E,\KIlkDSk`ٵDh[Mbzcc<"kfaS+{42A,1M c w–B U/`:y9 wv1,K;*2ؐ,qH_K)wV$F) K$+ g,jcޠy|MqHJʝј74,јKA)C]aѦN$SsT#UTh*kcܗJE V09A4G~,PyH "$.W*Y6&E4,5 7+đZ P[ny#Irgga]N1'1QLC T]iW QiPĉq6zZ%&1ψDMzɃx <+Y7Iy[qW#$&mܶƍIȝL SH, RHCFS$1n]#ͱZk9[9)|Qv.ZvX~u 'F-~?( םvFmDMRَmj-p^.t8x֦1y[o\L{t45jZ(ԏYc,elYaFc+nBK=6b4$!rZ[Dr\z$%Z"o1cuXJ2RkGJͼ6Ti=>L۵='azT*EZ 8BDBLRksܸDR4ī甑VFIAZ%h}~F+;-vIJ |+ qM \<9S/^̓T鱃Ie./㙑ZUYdB7u|tW*'f/IW|fR'T_(Ծ"3f+A袓#"Sϩ"2+0#4߮KAHSV`$njA '>$ȗRv)]*6 DT3/5ti^ CTDsRuȣ<ьBb*qZɮJ<\+jg9`=e&yf⭯cT@v)Qk[Jf%"*Օ -H/;X+$V>cWP" 4UeFgҜda]JJ%tN&Ӫ<\|h`9TKB2t5帣HLԼg)ۡTJrhOYZ_P  V.Tfju=+SO|uqGtDs{|kDز/B勀<+U*HC>P/–|KZkG]燎sj}`JtFAY"H.A "ג!DRJ]hų j#5 WC Tb)wL[%*cuj#_.\i%eb!⪌W|4t3ËR"9 4FEĥ}>u{F#=xh9dP* ]i]mpV $"*P +I 9Ӗ؏+9uiI%LG7VP\C)1^ + iAIeX>siD /7%زZKvմo۷X}&tj-Zl{m%]8^{y9%"O%au6RʲDK'Wy״ek\?ׄ.]#B]գɏ]-џZ[( =EVY5Z>'1G= og mv<{NlJ) 6Km9 )8Ӷ,[dJ|lDsM}{E\wj7mڌCj{I^_v+HY/3~ٖ j-Z lE^YXg.DZELPkK٣YGܨ*w֩c*Z1qLHV<_w"j-ZK`O8M֢݊Ju aݱP9St;دBķ6ݿզ Pkh B6mZVG3t9#n'8O36q\$\tPoykuǵ E=RRh%aVtj^OtKTێ7Җ2{fSem-L!V$ O)VDV"[Xet- 6Hx;ԖO]RG#=Fc p\%>=.'OpT/jK@>9Qs!DD1i#hTp*a@mUI 8e_а75oH\iUVa"M%k1Ҳv.*U XL,Tߴ8RQ,[ߊKJ#wY0nMa |IEC$.}he-e\L-ҖOýQO 2bD: ؂{ks=!\QӨPY/YVRN|\ufs_T;HK+B[u9Tyj7=&2![Lqm >Eyg#Ƕ-M嗒uo[˛ΔMFsX& 1?^AZ[cws[؁KP[Ն7U9ZvCܼ$zcmժN'Y99:,V%&.[fyΝ(ڿ~MlxQ%YwMa*v-3:Ԗ{ܹxeJLYP[;625m0 %ؠ֢wǭ׽bV͡#@mvt<(mbx|j@MܤQk\I(=LsWrڪu{)[ V-Z4WR{tts1fyxTjKRi_|D|Kj<#_̉(,;=LĖY}}Pi_w;COj+~=|l{)K tx &*¬P<`[1ޏT[nbaH;.CpBm#`pm`6Et= q>.\JPJ0mZX=0J93g~ߗ5 j_4y z ?GڜAbBĜ-~4gۛ5;t7V֞sߩVP!u:{Am 0KXlY7Dꁶ l͝bB<{8 5>vn"KGt #LJEVer) k) B 't.%@|A*8Uz(ipDX"ץd.I=_ϟ\ ,0]hA*z%/q G` <& R"c}DE.0[Imk^稔|K0}K,E\.bT0"i!gCmaPiCIw~"nggڂm>-otr+sXzY__9ԖN쿾r˖|uaE)Or+}5?"[b%vEoߩ[)m;;F1#ljٗ`, :qO7Td*~swCulٱ5e]?VfwyUv+O%AH׍7xK]'LCO'm\^wHںcsb6nqN6wJLF|7x:Z\=F;؟0SROzbJׯʎr/%r 1mʺ-=3KX$; p͑mK\Y XeĎz/Ax# !>6c1L#[6K]WSDu!d{20{laUko13.c/}%hL@R83_ya$VZY[70]0@G04hV괳iF4sD/%hg&Ht~2-5oAXi$ ҚIфwG%Y biƃbLd4X*y8/m`{#V؈Ԃ㕑Kv^_Hr;g7qOM" *BAۛ}PP0YjGhw6%Fqq_;H[@Poh(曭M` {ŹRRC(l t%?ho?!h8콘0mTEckqm54dԦI/oeaj=2+r:-; @[x/sx*FR0EmPɛjO?Yʹ^mooX[fA2&w6NGC2bpM23t'I8OΪ̥{=lqDJÁj->͉tokYn֥v +2O2&y/ߖco̥}3%c$7Oh 0WqL!䪶etR۲? ̥aƷo3idb3%;Ĕ|+ i~"o4ļqyLlG=^./y8ϐQsҌO _Uz2#<.,뽏;LTK役{Esoz-8[IZk'^ QBg=C)ƯkgDZԅlŦ9Q|[\-c:Wu#Ήk5ڣsTr=)q!<~:pxz$yJOXƫ=D pz[~jwMI-1У8mܑ9s- 44-[͉mYcʣzϨnJ+@Mb=?HK DMJH6f$mҲH3[ 4.13[YDj1q Yyd8ӌCs( ĝ&91Q ϔf:Ϋg R]:*4HTHKLR7DƘqd}6IL֧^4g{Ѓqd0/IݮPw,3<}A0PWR+iLth>/h.&th  @i&p|`MW&,xĮ,}?]?|Rx+)?ZZʑ!)R%R<(ĽtB,5eW@.pk@8M k䄤ď|K%WbOkK-v;w\0"QD7}\]TBjf}ڒ=K:VHv)rIWV'g ϧhu%i.XPm[ϯ*V'qVGD\'ey h"i%)ؕXa.Cs\Dy[ la"Kc^tY-D% uH1G+dLYx)C 貘o:<3oA Y(EE,sg^˜5t[x:ߗܻ&쭔y2yJ@=]7+rEk5i>NKY=KyKgR[r c6 y JإJeӭJ>T0[Mq3oby .Lg¼=ka9e1sO#Еv@.=mIo_N?N}uO^\=_ z4:N]y`ߜ^Uj~7\wڎ~skt1ynV6y _[xNĵUL{}\7Ґ>'nteR뜤6KdӶڝy5~=iY{^lM7[k/r"Ɵrq9B%|kٖ9ފmdӆWaiMYB[u5[;5TU[ſ?Z3>*vϕDH|98-)|wA[l$RRӈt]έE,~~˙s m(\R=nzKݽ#iTly{n?n}"zc).[J<3RKݺShC^3{שE\j.zKUfsh݋6vDbPz}^ AV \%'譊=c$fjzKg:%9nDCovƩYT,b h6ڝQ{i6` n75bRX@o3arfuod [[(> Kѫ:=Kݖ#H9b!mbS98V)fv\lC=o|3(]DBl=ʹ]?"-LzNrj?KT[RlO 249kO[cR.m9jMb -†KT[ާE2c([ öq<;>x}]K0!T[jor9mpb' s=Pbg { XD9{14v"p(Uaf $)}H)NT[F1Pm5Q%qi1R~]Lf鮎Y@&_$dY4pɟ[qϠa"DUV(@oUВxhcYDhHa6x6=/bjo1W(~J 8YU.-cQNwumψE8Ho}A#ʥp\7" _񟹴* "DER9qZy~R/wM"4!7ݕD"ʩrpH4d>c-ϊČ9|*+{!̎|=~33-}az6m/ cb ^p/<*qJ 8x9e2PP,R̈́U)jTY޿wf-TՆQ_X`o09s'FG R2"BX}# #Ֆ` с,@}sn^Zq>4`+Z2B/NVrlM:R Lo6o%܉h.:֠. rabLA^Bb| ;%` =}6=V;QL-g, d-Ԡ/b4\+x1zS[ 92E{ y֙_wx}]DPmrlq^뼔PmErbIIP-)]#~HS26vhLl7To!Wkzܟm_iI%wy\]@c1qmv*h}>ӱz}~z6Ϝm;l9җ[Vyٮnuަ) 7=}آ'jmżRgKFbԍ|m\c"&Ew?S3f(R#YoYmzOɱ˱w/^يHTAs\gbʃ0\=:b'涘ߖ-d[]c-hxw ͌ :CB]aI!#֔0S?g}uΈ&`ԩS.t&F7y!рm)d5"XJ܌w$E-P9D|M69ȧDv:]Rvf>S~ߤS `Ϣ.}s⅑(2~|Lg]ȗ(Eu;H9_lʨ)Gh@F$HԋREv}jCD4')` עXĆR =힯K&+u*dbCM:]Xxo.)43E[ $p􉧋u%mRJi0^@M3L0,dbXa]=kT*%> MKg4^X˙=/V220$_Jtݞi/) N59IQ#*p}]{ 8^9!gsXu`ӻ.1kL=%Tc4՘Ï_h%;GHg"/c'c 3Cu#"c+ `(H1_8Tp~!VGR)"Rq| 'tggDuK}A ,N){ $i[8E~|]II$"=L`X:!83 řzs !e坏R Ǘȵg]#?ع ` cmۉ)׆GIb#Y ߋ7 _ c,龔pBRg?us ŋ;mkå4K\[b~o.D¼5tKiuJJo eynx0z 3Z\ȸm7N]v];׈㶔~>镛y=eWO+7~wLf3L7͵ܑMMZ此ĸg߷V~[h_5-'q|FωI@'z[ě[l׹NME.ۺ863钯SM&3FF^ZN7r* 3Qo]J>6E6̑I^RJ뺟Һ\|#ekcf}b+^v[emCR:gި|lG77?}KͿn]DL\>o<K[m LZ9RP{sIڢ&.m2]wyoGGmµ?k:|m>vsނxxoa liװZ4S͢_m*w 8b{)ڡ9VOm>>Gĵ-;o#qi]<}7-D-:<6?oVgjb6vw9%ڧGܢװ[{p%u"H1G7pO\!D{g17ZH$2qWn(^l\ĉC,:UQhM|suhүG'0N3[{!"Pms`.݋4G3^(>ξmgSJ\L1XǾEؐ#V DtD[m]^ t$\ZXHn׉x:41,Y mjlbމ67}hPSm}뾧4 nu,}7g ks lDzu rV$Eĝ,Kڂ%YKPh[qH~\RE36# ؿohB9$JϑT{AiH"T3:@*~#񟐸)Eb*iHum )a5 k]CAVjD!:[thNAm Y.4%OB?5\*J%253妽7-2q 6'N]4dOFd9_Uk0=*^pJ]r3P[?9oG7@Q ) DEk+$qZqn8yӻDԽ̡[_j_t ڸn!b8adR"3j;x 7K{0X,b+Qw<^(VD1|Q$HdkdLE&.q\0I(r"ʎtN:wb>RCLbT 34i.wE,pWJʝcc@$K{ޒ7A +JT$G|yY‘xڲq E\cUL #w< xKEQ%}Y*gh1fcZ"GE/k_Xs(F`tgb*#|D TZ3"k[{2K 1a-Ks0 iD9͏LI,A|J-__RDZBq/>d/X4DMth}3moO<=ڲ^]b7_ρzS_&m[:%540 %¥kٗЊK^ͯ6W]=X{꜂醧ƹ-%z\T`O\ '~{-o'Oֶ#x8C[p3G|LA߷9j3zsI/OBKclxiεq51sp&.m񆚧)qiccdzҦ8dp:Zk3pW]M+.//~{ywr$NQ#ǧ4i:Uĵ@[w9:b+si k_uL1Z1PMc죈k[G _P@{KKdY;> k{1}6hk*v7^;m-b6z<%OMbQ>;̡Uc ZvRH@ydJ&?Lj;$!Kll;y,"=Q1zv5I׺dvly8md7S׵9G⣅ܖإs<8>ymb6jҺ|4X`i,є}6Da9[󪎁.]Qc2 'ґ>Cw26;`<F%ڳCksTl=[brlenǔ]j6W(!VLgstD+4_ZF$&? .k;YMXԜP3ki%lG =屢@$`< EG3ĕq`뫠R9.S#,)#p {Q+j}ĕ%eTKEB]tay^@2_H'TWi>g@@kI1e_?KоǁNt&v,R@.ga%`Z+ b&*2`E$]Ѳ}ҎUо7\]ʎ|T K+}y,S8/ AJo}p%+^ʉu%e(ճT`$T𿏀_ױ&Lz(=DeGt KG;hLtN;kVŒ/_REHs VaxG)bKzB$80JQ e2T ]Iҥ^F8\I>bx_0)"EVPև2 8>S}}>+OX^h?#1e #M,nf F9夕@˶iJ`OGڥuLؐZ'rk=?ahlhzRhIk:˺ָސgIepӱxtij~g'\c]"}nz:lMeCw=d Krii-},Kw"wmb3 BK5[kˆ>gϳCD=o[=zSɘZLKۖh^;okvL1|ܞ19oA )S%mfqgPvs&ެ;<.6XȲ)B!YVĖgKFy6ѫZV.niBѱ9e;ר=:c3#M.бgcm,#F%6ho8WX\JV)d&HJcm=~*gmx{d#}JhIR%Ő? m vlS(L1oo O]x=$rb_Jx ۑ/eH_r3anد$̌4b#A2dDx8%!+ #b`n݀̈87RYmN:?b>SDs;$:pH¨(Z\S{m%*ZC׹ .Hyd"&80RITeBh-!~C6'=EZPN] EbH(Q{nL$T :YLVӸ#*vĆ"e5q@b|rJ__hotWE,S,aL, kʩp%*"*uęk.9PNFwEmZ3,Ę7-GZqAĘ8ŨhPFb:I0#RE}38O |# XJ,F!u_|('c i15ELE{)9 JF5F[C!NS%f1wX ΂"-d8 B 5xGDJ_03syAi=#%!Pw&O=oSO&1&>BtnY6I%:xȇj iX5?8\q)ĹA0؋bUDLӜ&J}05uj _Ϛg.ygE'I(NqM59scrm$Z|л!.aT2?b법(v[;* ,u9s\.h.WwdLr/Hy}Lt^_\,oeOAtw%v=0KRF-]m%kiվzW)PO,K\ ¥%O@{# 6ZD^lst to\#)36tgEl߸$SgK VMڹr%bE5MT[#\ڼpirv4/\|~qk d-r dm -`|nb\ڌpiSvMK~Fj55zJ1uOXί¥%Z qizmooă(rSzIAݧyQcLwUj71ssuo=}ui8ZC.{ 6v\jΥ޷-گi/OB],\Z.-׭5)ʶTi1bK7?۵9ݗ\|Z#r#fCl gn˒=XS[)Kjk%z`F|GgΑd$O`Z.@_1.!|*L|B(> FۺLwmK̷:6OZ&k\o`jnN6HDQ0mDZpR۳тm`Aqn-j9RӂM7qE]bPTs}c5Þmf}z [| U9آn[޸׺)hV.1`~">_@[Im{zp!;Ԗ'гM(]o#o25A pϞO2tK(֑#o 聧D-`?y pW @c^Ŋ2H1aؕq;: VАB=(0*-lٕq{9!PvBf:zGt=uTgKY֊W K8t>%" HBv!Lw$&? `ZGv lg:tj=w =e)`zET"(SeF`Lg]:N딡g ِ"` /]H-cRHyr$eRſ! Zϣ`!0Z?=U., ^"jå`i:< }]ẾWP9!ut),sh#V\4;uSuր 0Se8vZB< #! r~HImrp ||]W.4.@1kLi] HA TY Z^}-K eFԮBM2b fXJik%/YP*)`U^Od7ÃE <8Wq_Jӓ)S+0݁˅ !H+Ngį>K `|JWf+TbuϺ Ӆ|b,n>K}O\<2w)gy$at$ݢr)[>"o=e+z >,PRݱ8S]s:5?QE0]_"q}08r(zyIY OE.x2&6)Xl-cA[tR5 b/62nSN/3FSZRFH(>Egjp! q^@\}t&]9~>ѳ[YMe +Ojw*_O9*#R53Е58+aE;=]7[>{mCnW6hHy_[lط8c.l䐖zQ:ʬSe;*NKYn8M69)NkNsiy;.Zv{^J-a$&\XPEV2xЪGSȟ a5KnRk>on4,c~=q^ɋ8pic\'b5Fpi?K[c.\Zv.- 6[ih*-ƣP0OcG"mQ7A3biL"v.mҖT˜hڦ;כƥ "꾱 sJ (!;|Kߛ5&GKm OfrQ.mr㷟f g$Wi"vuK9tbbҺ1 6LI};P~iE3K S=)'Ԧ-6ҦV/ެҚyZE9#.K $V}keUon";Fn]".==~h^3C^lq)FYdF.eKXm'>F\UrDKm4/rn8b)P"貴D[=DܶnH|ڹ{]+ۥ粤si=h(O|ɑ}zĈEs==P"*ђl|!l+5Vkyڳg{(<\Au+[d yDBgZKF.HHsg8iҶ LQ/DqBY@WqqiB6T* iPp#R!vK s]`2=95\݉Ëfgz]b"B cbb#ؕԉ[ºNޮpb 6攵d*]^#xBu0m^vy^*].Pka!.׳cbGI6iRaTV2@&kn!#dt0^ٲR]cZ \v2|SF-̿(aL$VƮwT*: ETqZY*3u l_j>ӡKH|Zt$t/IѥL[uV6ix%):UMnu6 , BDƷd;z"uoBu#yV #RRJ JMDr$jeiKgۆ0mȅZ =rzMB @URR@h&Mp|)kO9k5% KӖ[$Rv"/Y9_xO\JƥFBmO0?r_DZ8RV.K=!N+P>T2`IJqW*] =6F9"9{"~M)| ?{{패A[g k=aE{-mrRlF5ާc :_G;Ʌ,3wa\mYL)rPҶ2j?g%7[M"Y H*c1qoн-ȃl!$^rAv ą k-1TȲ#`C-¬q %ħIpqv /E,xy0aF]I>A>w=Y1g86m=&iIbvO"G8 eu/=<&F~N\Ժ 5:MgUۚk) qsh9jzRk{Q,6׊HnʈߒU4!g!ȵdbgbF9gm:+Ι}"J_ -Z;A|b kCyv䟷ACS\-1X3%Mk7ڐl7nρk 3g뫫6GNT%g(^1ٹLT-cqzRDl&ewDsȽ83.vLk72ql?"$~5dZýC P[Hvqrb'EPd,[DQ8}8jKciZ?>x܏ɪGv1bşVc0Y(yKs-%IuUrXRg.'6FSLn.dĶ @%ޗN "SOqz^uWt촔>Wktwqy6 3z-l 8SC@Џ}b~v)~PO#'&ƻsxǜk9oL\Ƴ\ *;WވOqVi[\Pfoiq>>HC"^<`Td_ݟs/06~DpSqݧvk̥&֎DL1xVqr7q'tfb#8bJj'O w0In*Km sri'[Dw_q/ƴF8 |Φǯ"vw4Zo:AducF2t/dԱ>[?D0:=F%i?#[t.6Gi5wdMYl2_"W; 6k.Dcxjtׅނ[c8m[s<ϩgFsg)Ĺ/hZq,aX՚? v-="vǁkY͙dY{9{u, Q-&ڦE d¿u?dDcmеJ&T|g켽76v϶bP|1ʯ꺋UyL7ls+/ί-(X[);6:;fs>wԛі3 n VmFKHHhI&n 3s '~0N:#Ή#N!P+\Nrr#%Π.+y]@B(WHViC_9.Pw f6&iD j&{Hv]"뙘/J%JԳЭ LDbdu$Ris]THz"mlHt{tK3+H9yEʲԤA tEJʐͫ% )XO`@ؓ¼4ziAI%p>(e/ґVK] $"]ZB>(0/J`rLv)M4oB㶻|l'q"v8|P\]t!e"J9_tuE4\"#2qg.[_@+P! m UXϢL Wxyvw`G$}e~&RKNZU\M( ItX& KWBE)C*5^N\HBE:C}0\rŽRY}yHlĹx@̐H~ڃV:u){ Π@R" ؄$/<|R'5 [?{$",<_ra N>-[B_aŔ`'4@iXGz C\;,0p>(T5 }$x,|_k,^/dY>dWTڮY,^">Y,rY v%nZ`YVSv# 4\:潕Lcii=ر&]ֺrkzSkYR&ӱ峂kmOGٗg\}t/|:Yw-&oˢĝ_Yk~V*ؤeJ7D[xGeۺ'0&o޾{nyky)7.5Ǽi n,K2p+#P< 7t֒Ȳ@xoYv$/?'˹xT=emSϯ[ɲPf!˦@c{KeeUEdY"vFvO,+ѡ=^ tX}=T~ఝo[pZlȳuhY?<TLyuKzG&56j{6hYs0Au{,0"~=&p#-\вV㏷C#L|#e{.hY;Zw! oв ieZV-kkaHnNb[&ROl6A>]вԖZ{eA@"2(vz{%"!/hYrCu4[9h#yyCY~oeMD_<"5l/tPܵU"-\ Br?犯{ĭg-p>S Qbg@ZأIPX)>=\ɲ%Ll木yg G!T"oć9["P[=fPLSP 뙀_#qۜ.=)AѲ@yҶ Ds#A[1- Kݧ=\<֏"z3ق|^b2o+{a8ùAD'X5!EvHPdhY8 ;έu:$q\`Z ґT(VXc/hUѲ\rgV*X"k1!96Y CeBboWKaJAj, *y{~+2M(V$r]B%"aY^rvH*i}6@(kL8vx\o3  ƈtXGƢk!c$;_D!WlE~Nr,oX"vw*@nZĨrkmnl>&/NRY'Hf<,FGXP(zfQ5 (HQ 2iLa{sDMYž&nmYm@蒄jA]N_K8p]U&6tdlڞG_e` iK)z(Q>nذм9De@M0"`G5 = @MʬKecɣJ !zkX ؗz޵_ `kGH`\zX}ĥW>xo;VF;Bx3jHaDŽn[ `[$Tz+uźe=B\:PE#=` [KgaD:VV)@^2G13rؼ4w`Iar# P̜2Z IO`ZOY5EE 00ZRju]"|r ėԾ 5"}iAB>bkTs6H g3ULLх1Ǒ՘7hd@49|kJoǩ]W1c@,}ĸf*"3]JȽ1"O(?Ҿ>|Sy!݌]pbq~kWPk~~ѳTg,`? X*?i}@Gc] RĎ| #!i$q kDzMfPXX6*|TS}2?Xa']hAA`HY&ITbu]Z!?K [ 8(Dl5T]/GԊ%(Am Z~2k'ꗰU)uL%8%`\`.u y/DH/XEdCR:q2W*HAR"B/#*!Q XS4:\a u[|/RϐWSBV<S3[tigWbW\, V(+b鹧EJxBBʄv(&!~E72U=}Ηl2 >)C+T ak RDf|MN9OD>#oE/g)+%]R*\Jt17z@tRš~D%HpKKLtB%e&]"fE|ba>TtsXf?G!搵oBvC:t/iyVn$ܚSN\oUoXC-&4#-N{_hnDgZ#~.9UK}rw̳M %yYtuY{BZWM[ūh?^ͲGO4u~\je(]E:[9G 8q9+HV76ޝ"*jE/Ou)t/Vw5<;k;-}9ֆ;?7Gͮp!ޒ%Ty>4u]iX;Ԗ-OhO68'ҠgK/E9x{+"Ā)fU#WHl%Ah#.%p{.zS3S<%y[@oúh-GI&Rz|iSY:#Ll+M|X1C)T-ǬMsc<O‡y J@BalQ)/S/bwnJB/fj}pg遆mr[cCH Uj;+; _vܷfCqX#PȐ+1ha5v"NqvV%2Zb̾Dmc!qyf{ЉM[<kWl7O^<,SPG)"%Vގx Ն3:pz60MG%J]xS<}q[ >[FAO$䳩3B$t3pQZ+l܏LR%pqs¼%źOg}K,3l$bj1 V/6oשw)t!Qs!0(\JJ\HE G&"*rL 8*N1]2Gkĉ*% y`Uȱ(v,-!=q…6V!oJ#Q8H Wݒ1Y.ƱZkxc@wNJNLLgB.\bhܑ9;~J-bk1DHf/D˸F| k'dE1rmDLSkt vDDouq:Ns8MẈqz~cS LQF¢x(ĕR_")+U+HQDt1Lpg3&JԚh吠"r,@ibNit mFp4-Kg"EX46!yTNc0_0$.  +.Š3̀!q%q"JE;K`JaCq/;A!V JT4L;K$YKCr2ӄs1$Hܷcss}_4ւ39 Dg~Ik&KZC ^3ֈ;b"@~1E5$w%p%m*P* ^YM&ifCfS|[p} Ή22=i{{ OdyrJ}3el]$8ϡ|MF&2&91_? ϊlknD~gKukc7^K,b q0ADAۓ/Tak0&6k;ԖI.hD;j 9-S=e4' yJzKKDRBnrmֽؗ;GikzaGj6/kX}-K=^)ex=6~L1qv~_egx-AbS##Q[:Wb$6}kwmi {t5SwFʚ;M m˲Xb½(\߽eHLßd\ۆ6ƣ?ij{:W,yns: B?Ԡun> q\smM'S[wn>Ϙ'^k^Ӳp?="_m7TsAGģ>?==N^3RWxݗiMOwBijV%F`v )vNZe92s`kޅ6RzsԖ=Ñ#^k 2;ptƎ%z²MawytXk!ɧդ˾ƫc6%"s@n^?#o#(i( К`}KG]Il͋6Zݰ+B @J#+aEu;1K ;/'S`,fi 4zvJ kڹ1$nZ5nk !0@9?FkP|6یԞr>Ӷdɐ.qZB*mؼWm^oȚ;9-w;v=QS),/X5<4 V@hG.=:݇l-YR#t/ D@p%1 : @2A1] o,%%9_ sЅ#mHEב@0U NGf◰$%L`\AץƔ2;g˅|}u#h9$}}/ bBmcT }[#L^Ɛr h6(9;l_4?"h<0T{m$L{g{gHdj}kjh莾΁?ֲUt49L_oOPʙ0-3@Wm\}Xu޻V8f4qۖ1=3(u]7Ӳ>xKk:ur5~MaݣX@!$qzĽ2I\:}[Ӎ-g۽9l'a_sVNMҞ{՚]&N{G6}F$aq'[#suoo;Jso?4F!G]jZz}!CMڙȼ]cyt_Ԫ*ؚ(6q_ِKls[lPA,_۱`ijm:MK.ܖg<Ț*7gw} !,fg0mYRcivYg 중T*PۄQhAFXE}/P[1Y^k=6<1nERp qjþKjM!ִ5"UlK@mAT ($@$Qql`F5J0~KFӏ(q[PMsŒ X@RBXEk|RlMY^kQ[Tn))ҋ&Z%,Zy<1')LIq:)bGap:q`g1CmqlAKژ͙PKNO _D2YQj_H8Ac}!R'zb8)B%X.K/|q)|fMyџQ;}_^pTD&s^{XL,P֋Oǖ;s?ϱtXvd!oЗ1пNk_1P~7h8!m qz$7чBē`xM  XZZǶ%~ ޏxަO[#;k.*i1,g%kQj-h|m?ta~PkQZM.L:}ܚqDf=3U<ϲҕRka&O’X%Ʊ\gqs j@SK¶{`Z?9 L=Z]H3>cJjs)5Ρ2QkjkqX-#LT"mbn͡1_i;%p.Nshߖ-x)wv= F;Pw:}bKkcǍ,u.:=ڼ#Yx\<ЄXZO{HͷL[XJ*ԶXM&`r$wޠZ뚼Xegc*-Ltq 6Z 9 kʃ|jWS]۩(6!.FR_'V=;So^T?"O VB-F 6E6J~\6נZVK]8*z{[/?w-g[ZSjCG\D]KpYLҩڈuC9_ksV2ͷ#=Z BMQO&jZZI:[q aD:`jKZ=m^u]v 䁈\3\Vbuz$OM1أ<ܻSH+٪`9m2K&53EqT|j-;ȕO'$nIi{e /dY >p\ %>,kdy%ffļK KҾл}*bDu)@DŔAR}ff^HadލC!NN&V K>ᇂTUP7ўT0K|#a p-.1[W}/\ZKR4nS왤^<т*֧yKЧYWP*]P ŕP>aܐևuq"u(L*\KХ&+3{ o%)ETr-2Mv]gdB0R`+xǣG~H dRPJ+xpV \}4EJ RLX@&Hu-H!RIj ~RY{)@(PND%nRaRY)$tعBr)ŷF) E^sKGkUyJcHLJ!DTO`WRz3($2)٤G8^QMm.(IxepbR bU+y3FiMGQl!]>gl}) ٦狺P*,3Q\K ,?زxk"ϲN鋈K3HË3LTSgR BE%)񎥍`_ز@+B-eb4}7a嶅زRf-)Q5YS&-~+[C+ zoiv-}+wm@thZKǼweJ[$y+뷖PWB[\oyZ0y)knϮJN/{]ɫ\N"nq;Nܞo4Tڥl)&n])Ϳδy7/4yrY5n9'[OE~ 9<%Z ,MC_jyHs\F;Kv_U~APfֺԩ@]lvc׻{f ?m$W洍s%D>c h?): ~n:{ݖ]V[2SQRV9J; УGZ=T,K%:jMTk *q*YmX"PWHA?(=Q}kEES1AVj-4H[pV ־?KL`b*x@uj-7IK[[Y,SI"M?#71uI, TNjT*9YL!hk/ehReGr,P6!8ulI譢=FQGE*Es,x/M403wvYt"b9`'*{Iyڝ~&P_>LfDwxL̝%~țX :VoԯTk83P(ofr;[v5N#*&kEb /UD7]M&VM=SEj-iZG/dIRZȥ&@/K]r />FH!re%c^aoE=5iUZ+Po1/8R$oA6\c~-\A3AGߠaK޸%YqqsN$37Z4z[X4f&CF RaV jS[tJ cf87(~s!1iƓ`Ǩ& 5Ehoǔ1@DmtrDM$\,sӪGd$V;Ļ]bk 0q߉`hC9y؃S5N\0$N 14hjA ~[5p/2R5@Ej=uޢثJOT d6v>#=X%Pu;t~>[JٿtM쯗6[y08pܿ@Va~zީY?[ u+R})w <L3'-ZiGijzџI4{ Vq.s8v99Ԛ:<-#8ϬS*n {w֢P[Hd[ &bR s{#EEtzy;0&.t0~ڦr?)Ь4E\ZiA3"ݖ l#@aZ'Lk:meGf$k4ߑrܣ_ R^l8HQ* 67ϓ%%q{[bHۆ@mE; . cxW_9.FsCm!G rcy_HsYM:lM}GS{()fI[C ]>P}G}_y6ߤ[KDG* k;κ%LoGYݏ8yCmP{@4R" yYk1ڊvb"nڦd=tx^nm 5^vzG9]w ":duw1:/9Dp)tdOu%(@)؝B  8 l Aay*_=)@-8(N"o?I[>qEQ.B $Jm LCLc lT@H+G`H.I ntI p7DmD(tE]*@24tsZ݋EπX] u)8Lu񑁬۔9/AN$f0(zFBgGEc;a\ @7FonΗ`' X7SKR!eS}"{)_ǂt W2!ȀX ^ಣu-\|ɮ=KWew=;i KXB#6&0>i @E|,=6ZB>K B.Pی`2ISZ^!%+"`)@ܼ(|$EԮƛR漂B*c OTyʂDKMC "K L){4#oTq[a 0ňu*!oAJO 0vKk$>tvdzk:&䭤LoqL] #cauMpY6gl)%x0|  )WJա8ztܧ \trWA/Y[<“E ^}"!o-F,Am=eo`-&X^"vs쮟ECw5-ֆ 6۳͜sI'=+P ˡCR%lU9u?g>'+PG8meTtj-V0\ӌulCma?X38kԡi.kr\GvV(Xl-,Osf9Ķ?m*U6'Ź_E$@m㞱4I!mo F2 #NEه(6fNv,QEC;ǒ{T4s0&e;?EʙF-B$ni'G-Y8=*#Hc43(ܫZ͙ń)}u{q!B@/qPv!Ę8"][Kd|8qA} f G:DWzb^_*UhXkm?[ zOLzilM81&NXgM.4&jP~ jŏOgdL_mzԟ@sXT DX|.'hp&|Ճ `d?cq HKLxGC*H:/3G-?ze[ڤr|R4gSYW=rIڜ"=w0oi-DrK ښ0o(zblYPkf/0g=Dr+wك:AZ 3Y`u'/^" 12bl˼wK~<˃PLgzOwJ+`.^e]L(`}fmYv-%b-kbS<7); ԖNs I\eբqKK1@ɽ=zy?v3-K{|P[crif:ui# \4}; g0vSڞLƒgm>?/ft|u n?_̶2$>?Vy5Fcr@mRks)D@mɋ[ϳ{=1@\PFCAޮgg3C}}nMGwa(@RfP(He</[_źaTZ(Ԗ Im_2|Q-VgW#%D!u-J@d-~E`F柁X#L% Eҭ3ZV ~6C-[59@䞜{[&/Zdm[lߞBzb{ U Rۃ%Lz6{l=tηmNu.V)uy;nښ2tgJ6<J!o{-)yC-7ۓ|z p(dY)p! 4 #!qE`-T!U#\c#.ׅ;[P@1 o3!.u v!eONZO.!o qu-bI:f r=SЕ/"*SɮYߋpg,1I}F ǀEˑǮڟ|-FYw?ܾghpP}&ћBYQ>VP`oG(eR&0IE4:u= 5 ,d(Tg.~d`l‘SZ"ZQ_/zNuA);g.)t3}JY5;Lx3_]JP"]?"*lH)Y #/R^}-;#y/ x/ô ^$yQC&S3 w}(' $->-HgP*Ϡ2 KE''%)AXSE?3TqȒ2"F:)<)g ,R I/VRTtM ^"Е.U^t +yL/zd u %,PY!?~3VeytU:!oIEL(V)"`LOo%]tsE*J2˔AM ca^xz0/n\WK+("6ϒ w^ߗv]Wgn%X}:nMja|Vk]s~kOqݱ=G{>~JRۇn ]F`wΫ/3-u?Ys"~ o%N+Aޖ9CZb]Mʃ< ,[xن9ajA g5{nÑi{؏i-|y )5y i;<JkA嶭p#GނƔk]%3Iq_i1Aֿ;`ZB3O+;6{#oSm}ݬܚgtޝA5Ǿr#oq=(V?˃zYsOQ`uIbzLN,iҡ i?,鐑Y'{M\Q8h(vA^@bWΎ?wj'߯4b턈{mnWixw[qzx;کi#=J?7n}ڝE3ۖZsCΘ$~S_v.^_bH[" P֍iXӴveH}Ww$YkWhm]hnLME}iR9Ul[0(傼-ɁT#g湯G=U_l[ XNK2mmػio}6w=xY{W,~~WFNZb򗹖ǔ+1@ш_@SrlN.^jo8+|KMa4{h|=Y)t9'/-"KsAS 6J(aEj%KI(g(UDELVA~o\zNWܮTLezmM'ywS\,_ʊ3Xd>;H& KL[K>=ݞ8cbX-YмZ2=bku$N q,zB~ c 3^!֙ܖ82=D)q+S=v^VZz{ӑ)ߋia"bs3%oB0$ } b$P%o0"ka0dbR{L%!a3ql]C%X/omP EEa&J۩.vmqkJ}Ia$vC-u(5b'  9j{ zauC{s'YP򦹄b*vm+ͤo)$FV7Lb/dayRb^QbT/xW 1Bڻ! hHW1%މ o[g2\':Kmj_DGXCW2A㜣3ixda}6:tNai[NlCc?ņ`nS疥+-L[/B6Yg;H4m4dM%(ڨX዆F=eeXk5F|ϩ]/ՕDy8- =#ng L[5EĖǔ6DS$]n Co>tI*t`gb[uRcd9/lOlȤ~ j#g;A#35s ՆHa#g;hW$eRCJ3HZ 4d]?3xK3oi/qT;Jo?<c4bu(]_AIe/)jD[qiA3Ӗ(/LǔiK,&o-@+7uEGRʣ c;e~.U; JRRȴg/A@V2%ËF`ͥ2]L_d;4D}$ [VDC~%w?Eϑi+_ _B= H"}v<,*}y@”ЏP W$(r¯ -(Y8Iu!-JJgjgK9QʌWoAkR9[YDJ 5gSY*g] SrNt3>y᭖KKgҼPkGHZ垵*Z(պluZ+i|RN+t工r.zRjm٪rvP(tlrZ']ک[~{cܕH]ltĵKL_Vˏ]}>=BMmtgHkы/~/^ qr#}Q=rKE)B0 Ͼ|?2Kts9_2h=7o!:ZuAj{+vfk*qj-=\:e䐯ni5HY_j޷WBZN!u+Zr KˑڐtN>DڴӼ=XFd/ӚvBܓ#bS٢?r,ZDM]Ţgo_l)Pcs7#Yݏba^4Rr֥jG۷)5QkiX_jm:hy^ǟz|ޛќo|\DwB 6 gWlL$?<3fo5&NZQj-Fڭ,;8c\l=3xPf,Gaǒzw֞mSpj-X+(2/Z[(]6w^#kl+)۱ MlzjKD|v뙾ۣ&-R{m vBt[kV=%6GKWYnͽc?W535jKd#DԶfZ]b2V{[ʖE,P[ ì=HS˴u7Z--)5xK+4(%GM[ \|go_n{0J)ŗeYbJt}wp|pk{F`OLҖvؚ0o)[Զ1sOa.ާTF<~v"@mmU3S5+wm8{Ԙ"q'H\'$ $0/_HD7$9 2"&$jgjQD6a  'gQ%s[I[Ԧ,y#V/-Vwb.Zj3's@/qHf;6 t8so|X_w`2P~цKH-ka8e%HvL/=3wKK4|żyS30ULYL K $Ǿ0o ,BZ]`Q!XH)w:6q"ؗѰH}O qZFH{N/aT-bP_LDE>#ANu 'I2&.bf qu^* 1%m@2%*N5%F&b2_Ŏ&$j#c$L')%z+Ns_`+nA#/}_Eʡ#3i9D/ Tn"FE? YFLV`U:' LK CJhXl4oi=:ĹU<$̗/b0Ң6B/E16 _OJ\XۛJ@]" U6"Wbւ-FZ”6D-$Թj;Ԗ:zuߗDPk׳Fj;nzht{"bքyK@m~ux/ysa&*D,ʼ%]Q3K(K1&6MPfӨgl`)4߸_Pϫm宍yc=.h6y ښh+[۫󭔘3ER[!Zwmq^1rʼͶq}4!rܶۚ}H׽2tqu$ijmM)c[&Ĉ%cj3rL2oj[mH&=ee/w7I|.]JYH.)/ց+JqY0D3vH׭1:- ߭\-&2o qĒR>1%:5iAeF r]"ID@!>`^.0psĠs0oa%D>f^|/> !I< (mJ_HO)˟?)r D>j3o̘3mHRd> R`ŸP)3S}}*3$уH%L&ºzG}.4?FySl#"#9e`K2UKy.T)Hi&K.+Ga$ W#C!pM,@ o ]C&}|ILەH}$O}LXD}KL*XxEΒHEl7b#V@y|I&HRjߗ|Ab9PW_/%RĞ-d}B~|/r_سؾrkLu,g,/iK' ȀR}/H1HqD}J[agn#5>SmE77K}j -HoyNE0 AʌtaWRd/x=8ȭ] dg" /q+PӜzH}>LY!5R|K6Z > yέ+crk0t>/H`%C$^[F/ߗ zߥΞ՗Ye&gKȜ2bL7DRS"n:jI+etoz~QqA]e۴Ksk٦71p+[:{Ihyryui8&Hy>0 {ٚqa2{X3sh[' smoSOo@#v[{n^Cs3ΰ.-[G,rJ;ݡDx7|lูA, yѼ;in!%H1-(<q]w@mѩm~3o,I_#!f/8XӏD\е9ˍFƟ-16!ŵ[4SNfdjeߣϘqwi]yD\`6Ji5Yܢ-XЂLi>(m'S]ږȋqB%jHDhjMb cȑ&^\I"n&f2WVKTg8i:D!}^p,imq ˔ɞ YJ~SlS;Rt7:He߭Kڬ&>e^R-1u+x᭒V3)£WvK)Վ[2 .!b""[[e$7y4$b_qg#_9h{c#lJtEmNEdmHa}Q 6wۘ+HGY֒x]m,Lۣq-䯬)MٵEZ䭕SYQL[j5Faa5Rܬc-6O4q^!,ŏj+mSd'peZlݏ-f{,m_‰b8I3c5yyXH6;$›`"Nb0u$?!=i #bc{7aSm b{&WLxﹲ|N>>PNR8)U&+@!dLv [/lWz_Qc&y Y`@u! ,6}5տ. o}cF*-s_Ϟ8TL Lf1O y s =XkNǁZȐ iD\n$ɰ _i6 n'xDAkx+RI[vU11m}q@L[֦!ޑ;/,Pik Qd^%T }櫾0/jI%GH14oBh?[5vGNӖ/ ѯKZj1&>s_`- D(BRX+hsѰS#*S_H|Aj{Cd(ǽ 'Nbq^ȑUV>[qM38%cjDo|Nߊ߰/$Au2㔴Z\dnL󇽽 QL+$!hKy~-&y9{h4>s3ZC)hou5 hx #gB)}+ 1j@*X ׉mLsuOH^Vu2*TDFd?%Gm2dK}Bk'*˹ޟ !R{hTr5*ޗ(zi ǡ0법p$". i]/rQ;ւVrssy>]Sxٗ܀{v869G&9{Wc-[]զݥP8=w´%ԽAw3zZ)to )nsJ}oG3JTuij;|c].ߌu삢 H G1~zۦزA]<5nW#SδĝiKb-2߻i[?\hn1~^b7̌ui- =\1Q* 1JȀPABtWXMLem·~B&GQapa{zZ#cuF p.iN z!B4tCwܵo[ϖҝw|5X n Z["4Jv>j XZ aze>pO=Hi_|os v{eP;=hȆ'ci{~t)g cCMzbC]ika-Rk;Xu:MQAPYEB msȹ^RlIEpXg{~ pg4!X>Cl (Ch; T6rg(?!=|_ДD3^Z;P+ V(ss7}t9ewR !7} :8 jC`$uHo[;L+IB2qT߶·5I^D8%I ;~{7|ۇPb8o5hu! J#xVR`h,ך/+ KΠ^w>[ Qu%#{e  {v"v=;vxX@6JV)gT'$.~1qR,H;ux; i xEH1,J5h[ Z3x"i{0 n9E1@҉paE B]s|K!X`%,-bZ Hcנ`cQέuD)XZ”.pד9M;]g)[kcUY6o(,bA}ktAnr[!7PH.΍=_Pj{۶a~ g}ai zY9om\s !V㭵3 -Ze_0w DbFֿ?`qtAI\P4 B >0uO!lzx@ o%ӠehqWMƟy 6hq[} H(+۳:ЙdkT-޳7&XZ m˵@l"uؘ涣 薫xmyav܏;}qg)q-"E,&~ e[kf-:9ֹXˁA}Zs pt#Wj*02?J\u<Ķ%5 ,KuݿDJ3Zjshb[raeTW[ʯͲfÞ!10:գS)Ԣ}io)=Pڦ{ǏȱlX}!0\g_F JxkI  ͱ،QР|![PԽ`R&Ԟp̈:,&̼!N`HEr ߈h1XSL)aip 9V (&L) TLTKR) WT1)e$.<Վ^C)Fr:AR7^BX)!UL)PLELJ͉i RiPL ILS4b,SJcosm,b廣&S:hA@pgadm*VxV}9O{hV$jyȒ/fdC2A0L*Č̜ssB;@ڎ%sw l-ǹm]mgj5tr#6֒Ge^gt>Zz7؁Yī-r]P[c mf-W.mږ'.j+3b~ uBr>eij$'8cKڶonH<I%bH<JeSƚ+ψ[ƮTݽ^eDvMZmĔKZbw@6x.u9DilGCRBRHO6 <Wk.} {OaZj-D^{O|`gYA\VRvݟ5Y.|tS^sv@zұ:ڤzye'mOy3|lز籣N=ZKTLci{=6!#i'QpX9Ӂe+pX|\A(p7(n|@An wLrE\Ha&b&$8 p$0X!:8bc]$fh}LL2 (EPT*tH&J1k#6RJdC22Iu)1ա="H,k/s]E8EcRjYDz쓲ҐM,ey<9LSu"K DT¸TS/3H!ef'qm̎/Ss1~LK^ :=xHDcDSrCaf)Q\8ѕ`p%e:(CKTp Uˉ6) 'NBrZe*3ƺ-z&-0^'@$鼍'e$XW<_-qȳ/rh%8T4Ob $1^ĊtQh}bṳ+R`ٲK%#3 (= /xCR^ʉ Fm8DsZRt) UbRK!_םHZaS@DE RUь^S\ RaU.Xb=_,GK´%i:%hM:GWsmYZ7O;Ӗ8i\纞wjvn?%hoy{/Ѷ֜J X[-bgڒ0m[:L[TKÆOg-*Ӗ,8Vmbڪ#0m!+9caڢm_<>Me1Vms@a^CDlZ[oXRZ^ xgRMٻ /i[rsbڢZ@j75xN崤)Z)U´uƤ|B@Ol}g+ʴ[smƫ}-qlO|Yv5&L[V`&cܢbSNjvvjoBAmҿ#ɵmyY|!KXF,dz۪0(-;"ޛ$[-QұJ o)FCDl-6/M= qڒK$dA1?ʼgMxvTr`I }Ĺ&Ѷ3*Bpq15 jzX?nmlOFIqo05Ztأm;JMim'pگ8i" Kxd3p ؃ Hc Am֧Z{-!4Bj} JE#KIf#wRބ@ b WVE =:k;OK>n4} ~5o[Ǻv\yvRlW*U]L3V %y#~UZ 3SD[g6Xݯ.1$NZ%0WN%Sa¿(X鼟bxy/{2иvgEX {C0cZ;f9L8~JKx2QXŒ3%/M o)qFךhO*kT?&N4O<Y Y1ԂaCޝZa"h-E*%TZ}h  aH_5d ?Ri /-FmOl ~%Nbaހ_aœ\u$D {$s. 2L|J+]%' 8Pig{vLD\{)j{4@:́bYQaVD,P?1YcRRhB_`haÙ 1qbTk&~򄾬+.Dɰj~v#oĞ7m[fa$3:䍦xeŸ/ci&r1?_6i?'g($!Fdl1a~ 띔|K: OonLL6 wCH+qB nH߲] 1Mbnw ʴ{X=jԳp^L[,Z^t4ib:+8TB\:#4[ld-z[2mrߌ-M5ٚ6Ո) T0m}?jzdн%?jvG[saڒ;Da{^/w 2m]|)omB58;h?kSR؅"> j~F8Vs!M<ޔk2\C HZP|ۂ%ͧ6?-G[5_ n]2+mC7Eܤubkt!&Μz^KD#]xPc؄@m!l*yB=oٚh ҵ&{@9V@ڶȁ2%>wҊEmkP-u\Nx j [P=oVamqFPZB0t}v˖5!owCH\Ӧm ֪y HNl6 j-?(3q|qw햶.`cp6y}p ,])R ] u/^`b/o  n0)c䭇wZ QC!]A9fcP9z;F9S#I;:ФkGlg.SE c]/ u=eN +V]7ºKH6R~R1Lץ\$LHlABJCV\"zp>ڻ`D*u+O ^HG<&:]ʗ0 +(LYFUPzpv.0D!w2ZY5屔ಔ2RlҚkKXbZoZV$u.rDXҏt;.- `X xXΑRUk,ܔ 5e BRŽv=e7:vw .&&)!LuTK+gօ{9wmbz' ^@žc{]H씲vIw(KȥxV@nܕӎt JM Ȩg;-@/N&$qo,3$ _3ݮ\uN/r]?)GsSݚᄂ=]OB=KJ0]D,XJP[*ԶJi>u .[cH3 o 1-ǡ$u3Uu.c O`O3iu/vK 8d@]WP.QoAϒ.B|-H*bRu5@؂uE/xi%0-v -RiN0-RBSR"B.UKZֱږ_?+j]5}(ԸԕזM44 };b] w@~aᷥ]?<`|öf5_i >i,.zYc6vw1 RcN.pHLǫѝLQa][ oXיtY1y }ck ˵4 IUWi{o=8/xAF#ƔL<k+_UvW[ɥKC?w꯲ٜz`֛+~PՇcnY5|1-c֫߬irW9w0m8!ϦgMخ{!Tu+L[ZL L&>umۖ.wޖ6Fޖ AgGG`\H= !rK+wJrRm:ֵ?Ռ)괥(4A??ywN%/cʺxS|-MykLkK'J{ yOGsnqiE|]ތ"=xSO`Z% }6&=ŁϪ*$hټ>ޝlي?ua .^-.Ͼx-n⫵RILK⫗fJ|v.e]lɫ+Co{&s,׳Y%?l ceY[#ZHRwDۆ֘^ .kt8|nX_qI) `mC|jV6 {[xvCd͙?I6dVlTzr>T"ع@qm" !fPo ڑju߸\ b -6_}@@q),_@ P E(h %>Umۉ%rc^P\mm۽3Weѓ;]p)@g[HrMRjO%EqJt`F1Q94L8@vsTp^t)WlV\-c܄}̵5l B:͆G[B$1LM(ϳ=!r"VhK `Ni&8%Zm(qQyHE([DLpX7I N < ƤuA3 JlIўΡ;DxW u8'Kp;0tA"KS*&/u!K;Jرa4:H*kŀv ).Fl}[L :*ֱtbk|n&[VB&wȭ4_aSba[Ғ[[R;I4mR>mÀy˃}\G|[]rܹ|'21xZ5>@nf9SYqmcnRRỵ5[U>i=k?~ndڼn-u]7sWzؚ>5c-̅bR(NϪTդl#Ĥהj }]sjamt(aM-KٳHKEYDRNq*4 8ݝA4"x6w&HBP4u7gA'R"9KwD>ζRR"91,^oIFJj L6FJLHĺE.}(%Ư/1o6THyٕ[X #{82D0J>e~kq@;Af&rkIC]j,)S2Ρ QJ4]"Udrtj9v]a HW/𽽧HʑmRC4}ہK3Q@%_X"MJhm˜޿֝g\FR g:R);wV* -.vQV}Ȟ%#]B<&mץļu,tbWP"Za8eF}V`Y|!]_gǜ^_.bKe.AٳiIZwc)R}M_$**KB^az@JQBMṱ)4z΀RX*yygĞ*Rv9S E' D')O0z!t~ER)D=Ŕ U5EN c#t&ˁRMȥdidjc]8RxE\Sb3qQHy%)rRd U /KLXrƜO:'֔0}JEc2MР>sy- H+t\*1mQ=e8/W=Ηu]Zo[nmAy }0Z,])P\o`6q88|BUJ#8jUQx'c¼&|Ҕ;׺W*o!}^Lηs=oKtyg;w^B_[&r\ZYWqqaUPjݱOHҮݯҭ.޹h!kk}l4snmå{k;f1\<׮Tg$jߪp"{aߏm5DeY/eN/S/VWyǽf;Vqۈ~2R;>uKϩm$]$]!mGn7,l[mj{{n(܏cy>[Kx)t]{cuʴ]γezbk߹֛~pdHp^?qjmSDqpTX[q #D#1zUwu_-3 n {}Kb)X0FU#pD6".!qZkKRqZ%?O5+צRg&KM}C 8&D_m{k-~GoPz&si-U<[ȡ{%?NQ5G;mg+LaNڶy Hm⮽ڤ󮽖5r O[kqBO+]j *$ڶd9׶Wqm-~vڶ? cG̈Dy}=_D\ڱNTʴݷeiŞ7Gyh5,φ" 6{n@}1 q>"o1^TcbE{ Aɪ Umk'-̂_qgHü-GNed"nyk4bؚ:heI[ m}|bQ|gOqV pڸq%UkmF쭥J=H ${6 fZn5w9aKH/;/%p;ИmUv".qmSìֈB&`-BEqsAbȾǦ#ƒ1t_- %"Ӗi# #HF hHE:ZɴN@鬮M#Λ31v 0!82K 6K*m7J] {b1$q,DLx&ԯ8R-ĉƋJ00Ѧyvݗx\',-!J o52$zP k%s#Mq,Vp,M2,v^H`x+q66A"Sخ~6j+*D V.Ju`.QKqUJ5B2ӖPŒ65X^*`HLLX'zYLS,&7ظA;цe<"IړN$1G~y&v nwB7jR,? '2OT_򞐾팳 : 7aEI[$.\o:3,F&ywq[pg~o>ʋ*MWy$z)<7+bzgSnO: OTV)W´OQqY~=4ek}[59*r** uqد}BL0%nW_/;is_Р.(r D]Kwj 9ibgy%Z=oķjw2 ykr6k&)dgv{{!o;Z}kw2׶-owt_ү5~M_&8Wu*^suˑ]2 ,+}zC{yqg%sHiVm)*ת7=k *80q}DţXVEB}\]z/zZc۸~nޯ5+׽of:iߗ5;AmmyOBZ5pd] `TLmym߳q@E޶- n q`km>J@I%#l q HYP DWH >*S[yKM \G[Pmj$8) Fu󵞏2J8߶}c%l1J G5\Rrk p:@t(16Sm ]vڠ7$m]uxmC y[S-x J^[hAږ=[`ڪK0]BRp)Pp[7j 5_i뮟;\Y4,kju,IcY3>ZotoIs~(hcs_vCH v{^vUq- )s~?ޡ(,wxOftamXy(>6[J|?v]0;덟^pgY翺`#얛1A6gCuyzC~_8L{ci1s $Ee0[ȗ9/g`rnq NU7g\ڂ۠}B#UĴҎg}\w[ Mf]\iȟ;z&g*o&7̀X[~^t5ڿ?&4">nn6Qm>TpDU<0q'@/dM޾(,0ۗ,U0qz)at`(&9zbV"Q'k~ELSk╸ɉX1t X*Fl`LKɱ@%Ǽ]Ldx-9Y{R4 ZL*=&6u PHv1M8: BlMذV͉ȲmK]JJi#'I TH xVn[[Ls XhV|+Yg |#D]B8uBE[smlЉ+S$NwEueY#%'#&'wFLaYR+Dozɘ&<^61&"QdM8aBt1a'mI+B 㙱 "Rio01ƭP`?'b,MxfA҉dE$(ccZכ=D$#׎ank_̛/mmFP;\-C%gMhSC1oa "x,O41`)ԓ8ȭD cݱ62Ř]ykd..'c)ڄKC} $;j\ZpOiT1{I3Eh3 'bd."dՃSDWm: ¼h,cFw(B+]f+ `ݷy#k.-V*ZbkV 䶅=%\۩|Ono۝.Kn#Bo EmRo[K˽ j/VohDZxOϗ?B.[d0lMxTJnsm'8lLs/oVmMTmyڼqԚ:4&N`khaǍAF&VfKH=TJHkZ^o>G^/p)hTa}泹U^r!^TϺbkoz!\a6R@9$a \-h;wwC,>7~{X=)yehZK-3yy^yϹE~R Ypkȋg{;ػ4n=y;~+D x]u(Mcgq? K.nBSҒ˰#A;ޫIſm~QmZ[YI\ܴI[䶛#u]Yɣئ}kMQě[EmO4yzsHx+ėըVmdzLj 8_SVm[#=4ΘrqCt,n㡽-Mgଫ !6F5tHm5r kU5un\/f۳܎9AKm@Z5B_dл_Ѳ$-suUTףHjBPĺK)cҝ*@QHITuDJCUrih΂>xO]9{gN]GDNK $. 3G\S]"bJ$LRJʠ;.IǺnB.%]"~4/"鐊)T`M,{HN'Ȟ1_a~]03r8nn9̬yrM{cf"eΥ6|E H {HD#J\%"Q16PꥪKx@tú-%:kHh|I)_8$Olbb냮|/LDMb/"v%9q~u5)/,@/u,P1=-p-%v6̥}/R' _4)q@VR1:&<7|Bm0XreuJR&HR+pIc& LT$Puϟ<[X{k_SUf&t%)pM|щ&%R+P^kJ RmDW0הtk.ؤ)`Uz69Nt.K#W`T^e~,JڥT@=EnSm g}=R҅P D\ا(X^IJMz0ӑ.2o-X9c-90tI7rz̮ |TXbB]!|i$g`u;I93ZJ5:v2 y:э{+J29 7&(%c1R X!{i4NRv]"krj[^^{6y]X;*"n,sᥞݓHG87s<㋊yKD\gޖn(Ik~q7ZyJsʚ5g~+}W{'6~ߝ4Gzqo˦s[-5of]t¼l/0Bq`;Hq|R (Vrwś%S/O[{gkﭮ_;D-[b=SmmKptXM`{:9ږBYeZ Bu, ZXF5s N/yE-qמN;,'{7]fk.=W^xâɶbbKbskGw9{^>WC|k-?N&"v щ-1D̨ѝc8 j\ٟ9G'?Cd o( (L9-݋/8v}JMM^޶"9Pމ y k^3PNX~maT [q (Φ1ڂ" iKae;EzdĈ@ [YWޝi[F?b]N}N_^BޢVk W ꁰcٟ' y{L}*&ySaq7ؙ1.3Zju1?V'Iힺ1T dh 0)TeK-KC߈XSۥYL[X1<~wq 1oąRJ1~E$֢9Pĕ=HTRCĥy 2WRba}P@(D3NTq PIL|U O$&q3NXY)!P:R DGk9B*,q{$!PAM yӈB,@5*9B'%Cb2dD$> \!Q b荞7}h ` Z4dCH!q.b3:f ּu0\ p0Nc[4߽ 26I{Wz#T '?!9p}=q):.Z Xt8.kTZ#ѡ\ZdkEftn&nL};JW.y9ǩ.ju+[^ۼ;OnktEwxSha?{z?sIF.nҵ~WƵ1m*F,粷"ft'N7o)qQD,OAK^`02ϳCty:;-Ofюy/(x?.޶2G~va˚疞eMa,Ws3mNn>ZKNlX\؆oEzη'[VtM؀؎Fu.|{oG?&\ꊨ못kĥ W/Պn{xy]m$;?1x5Ӄ#on[dfmDdRPm `z؆ o!"M;"<($RB"ٮ^x0'[-~"ot}ꦌ!h+VđE ƫ'T+rl;.6>CmfB`vtvV⎞R P%N X,w ,#刔`3%rUWhUZK9p  |H`vU`MbDRANեRpw #e +amHkRzyM"JaߍXMR&[{!@/x!u,* gϧ`]BhүuOR}CXS"(a\j򯱵TWQ C_$)TJW `= }J!e-0̾3(y:ttB5>L=i-a/)_+xby+zt-NI-P u  ){jRcJV'qM /| J8~;ǎ\NfX'0nAǎETWR܍eK y 0]l#+ B|žN02v߂iQ׿,u|"|2SbkAWS3jKv$Er֖l\w5 a-Q`{Am)$abцԖ8EI\uum`ǻvǞ m ~ j\x<=S44:8`_0/bwrn#ӗ5a ?R& TY3Ѣȵk:']W=Kr"vV7y)vNPn`b޴0A*.#x "qxbX%D*1sbhhHU[Rm6QLÐ=AʖF=QE"Fq7@@]:$"34XlP"j"1pHoxh*%h-1Dm/9!3]QbL$T(FD%H\Jz i7n2I1oV8r ZZ^D gđ )eꄨ ESslDa2Zr"Hdzk$!A,\Jn^6 Ej"6Ũ'F7)c ܄:yblb%Ju%cbĤgq48o3)ff(~7QLCFy= -E2:i.!Jߗ6]H|/ӦGۛsJ&B?_Hkd㇑Xt" \۾w~ ڒ1 ԖFypcNZ5,W/|RӇ6aPuɹ}Vor-X2o1[An-_)JcK;w팷5oyڻ8e8lxh{Y{ݡ7~ {MڼK{߶i=<@5ݢi}beoW=캮uyH1*/mܦ|vj%[gA{=miмhfWh|ZZ x%\\e{Ħ{{XרhFb"}o(zN^1~}V4HG2@|sy 0mM^ۧTmdBੇZz0%.)-mBP+9ujW %1@-RV$ T"PQ{"u`*K'h!T,J6(&/y }+R"f DBʒ/)k')V45ڒP*hRG3١}J0ΪK 1zu5vm/ݰ7Tp49J6__`_i"ϥ0"a2c> (c\ 0{ koY]Cʴ2R@KPI`uqc VWu7i )!l[K)m[ oi>Py.-3 o >>Kg\KXǩ}uipYzKkmD\.ڤ R-U\8Ԗf:}2 dip=W^_"mY8"ɭ%tu>%+y a3[ZxoxI{aGB= ܖ}v-`YGڬ4ߥpBs*{x*uyK^uqZq]p䭍aP#-W7򶵺Wym{ʣ[uIB;;oT]R>lKƺBgc֏sj[r+ul? OR l]GMZ{ѻ |D [yF%x<=:cۂm&Yxd#{jus=xѵsJ8-'GB7`kJ3&0ƌPC`ne!qKh~Ľ(L~!P8jQ:+"oX{AWtVBRLXy;O]b}U,"q Y`L;i︺gH1c Lzi Øh~W&@P'd&,6<&"adkXH1\Hu.1V7/& c&H1qy6#<w85qЊ8%18.-/,YF H!āik&NQܮ| Xdߒ#\K9YT4OpX~ 륍AaӝawK^#SdkFC&SQ,@TZʛ{2sa/hLt7GbN8& 1b^TZgNĄOÙgbs_CBeo^syKYD޺|kT-w{M_,[)1ﰴ崤3ؽ[C\LQlMMWk_k俦H-T̬Z% Bo[sn}6 hERٞ2mtEh?~]g yx!o y$(Gv(~9n?Vyio{N[-5}r탘awV(ht^#ouvq-xoh/Z,)@DZ yKxeDzyGcmD}~_%fb -mUx|IZ;cHP}5^ߟ$R Ap r폯 m=*,6ckM|u>&ݏn:@^a"QCLGsͶԕ:jr/ ǁ0xuQm" ]*k~`y^ ޳oPˆ Xn6i qfA`Ǿ?}m}H\[ln.yA^Np:; 1DI \y;_X/eҽ|lZKq5 6"\C-<mOԑ+@\s%i}6P<]R>Bw͎qi 5$k:!%P(BPAlaBh%PA$VMгA"F 2bk Q|aU*@ouGY. lІ 5RD)6=_ !FK"Zn-6` Kj=H IpYȓb1z0.^bR J_ <0ebC;Mha.̰mRjR|r#c=K)f]e%&/rI+3A_})_7.VZTu#ll-*$RΒ_)e@J=pYѵA bl-MJX@ JpcjKO(lE8IʎR@\>M@5x ?B(_n8e~!"@^`=ZP[qxi )1^!\.EAJHcJ[3B^;nA血_ sGs;ZJ9>C) ՆE]!N,`/IW?L`\ TapYjaI6=Ke&{^97kNSNK3qYߖ>j3yΒŻ*zQ|=;LW8.{G}ր4=V)}{CGP:af3{ޏ7)xѬۚHus֫$5c|?rͶjJ|ܽxMqms@\:fR\}5gگrh1{^ׇI1OӲ N?vGֵ-zBW>3EXJBKEC omM!IPC(꾏v+!LZ-IB} ',JW-%/oW^lvvRljx*b5vwmֳS煗{=a ^nKY=t"4X-fɐ8x=/k$񙭑 f&FK%#nSTr ]&!9>Ǽ܎*6'KÔFǐxK\4M'Ƅk&l!]ye&H[Nحc옶2d! IZzH{LWfKJ%KZo0S{D5'C,%r{ti<'4!={ÉРgH !^q+n-R~ 粤JruG8xb֘x@\Mg[璸oy0˧n*M5ֻ=9Kf!/7yo[d]w jq wr+*vhšqzθ *aZli Z 7p)e;ݦp^A֜ylE=\ ׹E2;qpZj.Mo\o }Ȯ.ͫm/33JF[kLv?'ex)Ϡ GݪHæ,WA_"7}mWX%['~\ڽ]KT"/\Dw^x`8S5 ꎷk⚸GVH΍"7i𐽕ڮZDھ?&yVӽ?+.ʍۮrW[]qRh veM.]oqzIZm2^RuKCwt.nق-Eۺuدa]wYl O`4 %]mU{ȅv ͌w3yO:6DΜZABۖ?~@%xV 5,8ץp2s/`ʻ DZnۀ   k#:({n#-hOsA3{/kKm3 R&bچ[ՐdT9v?geG~tM:CIwov޶Ay_{@PAluWڀ Xw[p!.u-y[5`5eabݭo -.B<,>p ;5* j o!mRp+B ؃ F g.`]FG|$BX= *Pc0 >Q/apJB# EDQ0$Vu9B\ӎqhEX#bQ7bP*ZBB-dg%PW(_zd/3F 3ia݈p2E`Iǎ4uNNAP*bN0"TpׄRZ Q4 N8sgr`u88J'xLb%&\.ƒA ߋEh$įckG8/L!RY=k3]Q $2x%k*]\WnBLeG0]֍Bˀg=a/R<20_O˥t .L;-@|vUu6P])t2H2+\(3J ;C}}p(,`gggZt)ezKWڂ>VC,X*RX*9""[+A@R@bѩ)"'Vk]!NkTƸB=#@,[uy ӎk&GARRq_B@QwV*Ԛ2=u HTNj"| /c@BS8U:C|bkߗuP+=bW(3$"`TnrEV2RAT2u5.H{y [BZp\kr?N\[:2u ߥBʛ?wX!ooDmĝϭ;.zYRnA/[+Zf$?ҪO#V .v}0,j(\'>P lD  .< }0<+->'i[:wO>sU\5N;Զx65NDz,[V[+}%aslumxʛ ImIapJllNgJAry&zgW=CΏ}I#ٳё=9wd?X%Δu݃;֭t_tlk8UDM㺦׿E&.~ ӄKtſ߈OzB6$[3֛YqJT 2y֊wCRěMGb(M>u .M# w?R"^Rer_3Pɡ&ZA {M\[q|` 0rQɝZ+׶.pAY rZR-M[Kl8R 4Bd9I!r_-\c_)LSC.=x@\ ΟKczlֆ :h97F˱ E\PU[IVnukK02_ŐX dĝK*| 2|N4ˇ!ؿ;Wg0^"_@q sKy+uaT-J2u aO(_loF6[ZXE12K 4:EfI,>^1%Fd&ApA#Z j&c lp}Pr'q'`1\K(o)z+w#thkL㦇Аōr⴫!3ΉIOe1\q:g[p/x}4;ϽvjfddL3$o::@dZ> *}T4bRoKz֊fK?oEIބF1ҕQڴ]w3BkLO 8cjyG×*TrD'*#L52_aюJKU횼 5ڗvwħ%?5Kh8ܮjG%V={?hx\^.W|L%~M8m;.1YǓ_NK:޽d3!N .~|诮Aq߯X~ȏk;gۺ]%&.͙mɴ,n"mo,ėZGqZHv9 ΐ V+sindn?d)ki)ȕ==|sqi΍b/8k |:p9hJ@\s`qZ򭧳ǖqQlCz}̽ //CU,@\O\ga3 ]fw{ּhEO_[,\؃33w >"ū -m`mlX akH {o{D@eo]y@\qm MAqc nIC[ʿm@ mYn[jFP[ԁʳCQ[ .s ]q6Cmx]2 ڏ^g@H:ą0B@ 0*k~QY/.܍r-m[RhY;@x r{'㟀|i҂O#q]z:RO@qx _4wjQ]m/RRUqg,VBh" R Č!6'NJ\)}WV[7R#J =]"ZDڦ \t8VEDKIh1N[4)<1H0]`c/bk=eԖ|~RkxMp67S&`9j`Ɣ= ԭ[^2S!vUD̗vDώShl% i֐/"귘^hTfE)AmVPLKkc]ebk zZ2>L^AEXqQjc)K`Z(3qyu캴wFog.Z+@fNѳx.htk )OVG\g"p䭷_Of:ԕr]O][9ω`ZzV/bQ*Uj'I{k AMξTRv)<(!3d֔T++7.:jNK`.bkZ1( }AH` BH`Z"x(Eh}TB+^֯QpMu Z,xXu}b L _1Xţ}IW`u[bʀ镔a5"ע/ÒR ◤oRW.ԆKx쥂6B|QK^-ciŃוn+.P^>\# .v۹KyCkH-=y;D^v^ϫ}UmU{!WiYߝ^b4%w f5U֔xc؉5[b_U"u_KBkmo]|.]c@\r .ˍӹu?uh߸ZeYn\+`Zx\I[ Q nZޗm[gsO/3/-}Ճ8q}q1vk 4YD’wJyNք缊mL\J͗a! 6ms08H1׺ {o_Q9ĕ!⪶AI9b~v45*DJ=|xQw<cfuH[ e2<{/o)f¬ ³8iD('z {~Bl; 0CiK(nǶةq6XJ>WGPZxJME}wqmy#(D{lDonʬ~hT*!mm{ym"_ poh['i!yxP q508 `gb K1Dpcg#~R^P_em$IӒhXSP(34ɯi`XJр bCj(v8̹-6 뉣Fb*NTl-Jt /0(KlK4E~ ż Ly |yܿIdD~U1|Ci sBWarH I0blL\ȯ)q␶Dg%"k# Z4J\ȯgjh ȯ* i(FmZMR4}`eiA=1eOeD̘QAmqDɐ-1c*scRyhPD1mfY(N` gŻ>=x[8Xg (_ylچIr)JY}7|!3 <3Q'][hP/j͝nɗsֵ_q>KU{ ϢXp3 ǡ4{ti ٸ9nL;7X 9Gv񑮻Kގč-G{ڻq$ulݾEl71ƙyyNPb8?=lpR_[M C e OHxV3@>i/k[r vϭn|g'a F'B_;CIKw@Vm_8qٌ{ve,Z,FףkE&p-VB+TPf Ŋ%w罆 'c>BoEڞ X Jy'7Ot|T -az[ٵ!`.Uڳ'ୄ%F B <۹˱ ?+FfQĺ[pǯPh}emgkz*ps IPY@؆q=)PZ I<+Z#!{"e@2bPFZ} č Ìƾ0AS.X' R% R" Ѳ5A"si ){mT,-!ZK8Mú.k'XpkI_#m =JdSKIʀy| mrC6zIc$5o4 ʎ)NRv)YR7=%1ώ6: a J!``ZI77|Ept}Ů\Z RhS*2v|e]*XlϪEH>#%R& K+X:VAH F(mxXώ2 ]@ y, +U"вq2o!_zTUH!rћ󈺎[t)1ew1 L·RzjD"iO^:n@sE)X<$`R#d@/]хb9{(:=5?`hNZfͥڐ:=nu`n/:G>8PڮԛqDv1"4 Ͻ 9>.LuZI?7\tAy؎نK4..^]kOZI8ž)W;NʗDhIO2.1GRU=zHЯ1ֿ"#lR(e}YV,Imx,NJ#xX) Yb=e|.w{´oFz|rgw-_Gۻ]z޽X}VXn=z,\gHMYa^ҕ|d:Ó.m Sf t]_֣ͦ m=|!K{Nzoli + ˵z}?xX]vy,K|= Nc^Rǖω\c_=r_PN{pӫ^CJ׻}qRGbQR*(_Y'; DZ0{ټoflkgkGNhӃ̜[Zdp|V@xvx[1">mmYO`5I4׷,]qMũm*Z^^U4ߟ?hE|_qi.Q@otkhh'%>0喘(-Lӭ(VjB-skߐl,w*[:E^)lBkHx\ŶLW#K+6k~u?mNM+UJ#}1a֔m:yt6Je $C`xa__xƖS=R!FǶ-!q.ѰTxʮ}Ӡ6~mK%^=Q*\l??Mor*>}|aULcU|}g,20cbgy[mBݮ}h cS012{ĵQ@m+Ljt?W#L[BfQ5JAl|h@PC %poQƸ]3C<爜pUF&:s%D6?7\m9iNY\s9Q% r@.lx ФXac̍'~.w$|F@$a;S*g ̐*v;񊐳1*I~-B=Q0Zv 5|i [X7!X/)яEXQ[HQaځx.Rbޕŕ^&4\֒;PVE-MՒi'X.#g)_&-%'t"%GhScHʳ%`HbN`}TXԦC/t筓E#> ͡ALǒI⓼黁Y0qp+ҏw2/ڄO_9D8#:gK$yLibv-Z;dVZUHe1piI%o>6> QZb3ˇHESnbz1Bžqm`I,=!R0rkވV/ \HU DLYΛ$c_AQLEc,<=oTr&>iG{=lj Yij%W<kqIESd/dapYV1q) D%/? E8Q "/) B^c(!/0ϖ T - Ob1֯(ڴVX. ƾ cVSh<P*BLYD7EJy3`a4P'bqd~}1X IFF8['c5UygYrv g<ɇJ{"jo%T{ts /Q9xyRޢ-/UyXMdʵ!tͼti6Xm6=m5y=y+3nJWDm-sy ,B3z5xo͝|n_ootI,,]zY^=Ӓܚ#sjm[^,]*a?ޡF<7zީr]K,ݰ=/ҝ_,]J|Gnyo$;f!} YHYQ.zĎB c8=l='O@=O!]@sj@*| h8idD8r[r%g!Gx^rRPJ11vj^u`N8"k؅ߒ H,N"H ikI\SMyKc=W1YHPfh#bKAJ+}u]չSJEmR29jL 4 XJNt‡ ć%]&ER.#ۉK3X Y䴒T. Iʤ )] 6K%,>`},L{b鋆ׯu""{TVAŔ+3VP‡\KEHa{jr\Pf. -w,]M^U#El[=ETq/J̲Ԃې|h'"R&.쏄w|I%I͐3^ku)ԳEevvԾ 0{h)^E Nl0eiXW #ٕCw5*uҺGi^<>Eo_׿W(%!a4? nuI*"s=_^*pÙ B6e o29sk  n}d t5?5y܁Xr z7 X̔DrZO qV/Iev)Xݸ*UGBׅJa&|T|NSQu7"+g~iW2^_yq(e<ن9+)XRu8ne*L\Zy/_SǵAw1=_})e^m~{Su%_D~Û E20I }uiGP>,z"" ۹P*]2{=l"Xͣv<>4tɮ˞[G[_<]5'y3VVX2@[sYU6Mx`vm^}+7fÕ=3_Ż̬V0{ыF$5`Rs⥺nm˂NoIJ,δ-^΂{xWv8&=Jѻoc]յukc60tnR{)A|*w[S\*ƺR6x]"ޒv䖣_kIOd2..W T@5MUi;gi[rT-ƳH|DSrlv?]uqӴH'śUy{ Rz<Knj]e(ntx4+G@K⮣KxJGZ]:VW mˁ}D@Sb˹=Fa\c(˱>m3M9$r&. aUl{= 5EѶ{ӁjK ̯@ 0 ʻ̗gg PlzZ7 Gظ[eq}"3Sw ! <=`~F'CWZB|sعYm%z};xȷw;$Hz+{ߖh^[;ŶzbH|y%"V6DyQHDYZHlԹukrod*K~_X=32A Kwrm ${.oc=NRC)y3y̖>k&ҶiqS!Xqo  ==⁗J9.݀b],kޑZ> p ^@\R! TN"L(@vs CD̗xNǫNQ[8%h"ma1k٭(q@j>0?, |'PZsrS(jA0W\/1MjUKu۱!{i9ᓑ,d 6B3k#N @fNpض0Q0Obfƕ&~SXY$Wk~26I`dM_VhDD^4ƺ6׼h_k#x+_g)PF3m"&ƋXa/2I:X!j_Ӵ ! \25bPBżAA[P-JZL2FW1Xg"m yL8FSk%Ƕ tZZNn| M0<\37 k3D9V?ΡRZ仩e-7 EW80ZhbwG& m6RqlIglfl1ϩYL3`/;&s6LT-HnljG(-BTi;̜8bhRgBLN7 >1xH4i{Ǚy-v?ڗ;¬;ʝ}NTr*/V ԏoSY+wUhλe82M.ۯiД_ B\P⹃ohz5FM~WwkNRBҵ\hwxZKGr7$Pe><=ލOQoF*>k *lyǘx[}ъY.6_SR(3kOKuf[{&|-Pګ洃Gn30xxZڣOCi4\h]!uu%ڸ7u Lgkֶm\k}cۑb 8c-mSh8?wI\e}"5Cj0m#VhKF$[3mś?F=Gj~>m 'N@"7٤6\_?LpPRIN.u-p;6)Ӗz.m+\ZbV^0m1mC~iᘔ1̺D7ea^fo|; j{Gԙmd\KK+]H^O']aB\0m!vTh֎F(t_ 0m!vy2ZL5bոźJny 1m=egBi{mZkcK{ZBQҮg:ڸ5=gδ }wkl\mȳ)KףJ{-ϫciKȴ~7~fCL"1hAqP;MYBN| O1{NV"Hƨ!Ar—:#uhL0\P5*uK|FaicG)._$)StBH-w--׿xQNȗK#eLK[ʌ1[Z׺`ނA6}6/{fWdU#d:Yإ<] yw]c: )=, ),kmDf")҉ hꡢKՐ- f AJx R{+kR=R7(ea;;UJm4$ 3;t4*wإu4\9|piR[X@%vˡ|wLLLRʴ_6eS;LRhk %~ҁIά 6b0|^.-3쭈;L 9 b_Z`y_(Z L[zWؽ;ZyةGE ʗIr/V=R(GP+L[һiSx ҮܪPkZEۦػYmSk夂}g-Sk!ePkF- .^ѮyUsF.)ŷZk7@mܺXEr6XZ7SWymժ}өK:TD$[UP\W}joikw-:0Sk=|-~9Amy[jMS\ VBJ=gRk:ޑZΊz *}?S]񝧈XV1EQ=&gfx yѬ.qv6uj'lbc35+MVGVqK~Qk |qۉzۺw(mW[4R0w|xԣ݋Dzd䰔EqBmZ / o860TgNESkZ)Yn uTWW|ݭg! Nr.=Ǽ^&VXZ[|0VW+'q&gqM% ٷ`m8jAޟѷi*Rk4yﲮg S=~XAv=-Mlkm?SMpǷ|F%TyKkS}-B$KݫO&Z۹mąD4sSa.+ %RkCK&^8|GڀEq)y?%Pz7ftpK!jB"L(ۆɳ BhxmeOLDI+_tB4ΓDA,YFGj j-uۏnQKǴPkm1>di b ̈́FHt%,ur6QrmX3<[2?̬m%Qkkۉ%5cǜz}Zز鱔V1 Hqu_T[>v?;c]yvѡDS>7g\Zi;fڎcl=Ax+ѐE 6 H|DSR/|$9B)IDS%) k[>,̿鷺t(/u{1aDO>H:f.1)e$~59^"{c)}/QTcnBE,OJW"u:-W2@qQ&[:@%(!j2MZ%6PSRэ TSJt @kj-Şqv__P)P\fy2h}B¥]Ń|ZֳKnqӄX^/ڶ`T}ri㨢4_i뿥zY}yKHxo]zR;=|5{XdR=]/zy+tQv"Ꝏttuywӻ+ U7o{ U^CF_sOB8vY;ߺ6k$9m>Mں|m9#z_hgכj7]4'\ڡ?jiQ4HkYlJͬoN/6+wxI9VG,h\mx:G_Ez H׽lYC5Y/MWrk.>L&j-9rZS-Tſ\b(\|{um!UV~L} #z; Z| r+.oT^Z6vj-w}9<+TWkuZV9oWtŠjJpo2>ZwZpBHY*RklAYVa]*)"1*uV|R EbPʘ1waR)_~ *aKlz X S(JXKL5t:>CQJe&-o㌣hq)T].@MLRuǘVeSU#al5eZ>Ӽ9)UbUP)TAv%չȧ&%hg |e AR% R1u, X 稕n}_SR´ʸ!M3)T+0ՈE\*H}^ =siťShc)9Pw^}% *RB=W)"mE ŚHò. ϣ8bKcK@0oeqiΚtHW0NlHWxQD^&}}֨5 3`ǺSRyJ`9D)>$TFyStYwCʢ;Ɋ L+䙔RKZ8Jx,@>ǏLju_ֺŊn<)]㺊\x ]-s H/.A\_` HǺ(!߂vAJeu_ x_u +\ւgIBua`~c7bRf1A. IoL&(ݪ˨dh@RM(},GW#뭰/5_]6$_hN%-#ma |ނ뵅[Z]R>'';>}~Xp3n/,m:xCu lj_udIq{^Py^<Ky"ci ?-~8:|cZsp{qg1ai=oR̥Z+mٓڼ]<VƘ} aB9B0Cb T*#.=8ȱ DJXtGT0ȱ@TgO], z-EF< VW!jĉ TFRѰ8TUO|LP% y{9xw(cs )LMb"B=Fbg%@N*TQĄHE(bJMI'Q9دHpYI, U֒J)S:"08IR3LT4q@0PƭdL.y̭a mZW:^?⊭M3_M1Z.Zрb7Q_A#Ȟx y9^BGD("RHtkī)ry3ڄ@CS-4 r&,OƍPfiEy'lSݎV[\JN&"徥y" JNhJw$\J.8ޟ&I"1&X Rms1,kDD{;uj$v~s2Eq1h2 yC4'yRpA♥bѸwO-իV\7$x@dLhk1%(F[cD,F2dT`6?,]$F>DvR)Xrnv$΂l7j{|i-'@9oZ)wS$ 8`Q Xr,qtnZp.Il3u؟^BAhk31_UK=ioW ֲZ̵m8q׮?k؟mDmڝך\ ԖܖI\[>9_kY rTm*i ,UQy =y47E+ٞZA'Kc~?nw'tK^X=bn^er*aG9>JFV|~f&R׺|<5Z>pr7V|=b&Te`Ƭ6b/QgS~H{ ĭs_-O`2E|luy$[«۴qmԹx۟cRR_쏃78μ|˝FTʫ2oc{9 "#yK׶ĉd+7RUtn!2oqݩͷFͬ[-Py \ہ*{ ѭ)RuLTd z0[. )#')łϩQ/U8{K*HĮHTt ALA7&\S' /y3)п)忖2yxRD^IΑ. LT )ӌCR,s1br(eZfXN/VRF_3oe4"vȞK,V"*U"ui[[SQdtQ-- 4]l`_{)t u[GB.fTJju+pz%H; UD ;p}9߾D\J^rOO`w?o[śo:v-l|^%k-|oz9*V~W9=Τd+ýrZ:h՞^X_D\H9]q6arڷcmO?\O??V6fgzuqO2AޚRVw 'KEvkzR@)+q@-D\rT"'^".UKwm"-[)A:7Gqlw_vW:ׯ\".j_]]uwf3muEޮ6-&bWtal`{GK-1GJܱ_D\ hCϬER@m~2]PZkm$mK?q?r6Q".y);Q(ʹ Ll#kKR`C0r-qoBң&8NXFfyV %`.>Qk&_IX=q=o˜iɉ38YF 0qhkRk4C/c|7'8],o߻cg'E{T Ř֋b2Ejo& •uhJK@l*q]JN]6Bku:?y@Emʚ nQKi ~Qi3<)Dܙ XrEIA@HEcQ,%ƪv A~elɱhbzDG 1i.!*?D ț#-RgbI YW/)bBOخB} j%9sgb" GQC:A2u 1h! {B)BI<72/#ٮA,0O/}R甸'Չ6cvRrZ"? Ub#xLȰ;Y k#׿[?JKOþ=8d8o$q2dԖī6{´v-Z_!Fܯd%m8kr(l)ʝ$FGXo>?j3ZԞyۦ}}2malKf4enwxMy {Rrji-ȴũ`{`#v'~)qqɿE'Fh?mL.(0Ck݉rK6HmjIGc>v]Xq1{ٻE"4[>x/b㶄Nav[4kR.~T[ 6pBR'J;a;7OvǼt>51ՇN!~^罤3箔H:3$;2_L⬾6mꝮܛb꺶l+jw ꞵ:KcoF8֥ܶ\co@jxWi*\kC'o۹V\\{mۛ؆lj&; 5&=TҠJ "_?}\em:{EY{EN]msi/>ISܕ4#Le{r=7fɑZkt/k+L[ne:ZÒh3a˛Y TwnW>Z}K˝l|KQzjUJSNh6g&{콌ĆcΗ,lCkʸ6R)ga%Sf6L4zC*뎙;F6qү)pE]Q\zGy6#.Uѽpj-_Nk?2cz=-T3['1|cniH{KR)˝4^ȳ*#yRN둚yv=)Քݜ쾝cY\7Ccr}%ݎʻì[sio_%BT^]^׋StF[.rv1i2mAu9̰EҖY>6E/4ǹ5$/R_f |Xy ;xVtmYw]y;x0}>Te~j)/6}x&/m,y ٗ:[rj[A“W[ui[>~Z޲/Q+Lr1%i8jvtO$ez$.+,].tc.^7jC2NZ}bcyMȼ[QPk.v`"gAFգ[d>j %xt H>ڊ{ʝn)Oh+VwmbiYjۆ5[ƵϴGa=?"Jt rg]m)9K-Kyqؾȭ[pg׶_-/mctn]N,n.>=A%naabξ9DKw>BsgP\mcgʟNe@}`i),ƵϪay땶ühpxvf]S[Էظ&bV?k++ B!m~Qڗ@(6b-ĘH)65Rk=x9~W+]Cq;@ I&D"r LAOUmV"CM4B(Bm~Ďt\(E? d$.8OxD x;ڐFΉʨP]'b+7"qE{̼q"`iHPMS _tf JoU%Q' p8S228W_w" įZZ  Xaq<+MS*X*]1a Iv0Gb@91@[4ՂM_; ` 9umk+T׹4([eYU&Ǣ,LPjmǐC*\x.U?vو|%S:VM{-$=aQh\k ܤJE &*IDUrPo ܄61N\'h3j-hXbKS,b&+Rk"L"&;'mD"~ g8Gj-KT;bH%8Y0kS0o;ɛCNJj!)eqbS4K=)ĉSH K%'$.~p 8^B({ܿJF"a|KD{-DE-101{"'=xīX!wG1!R'P[#8㗇Z֎>&Zn!E[Z;~aGWȱ8px6!ֵ)4P8 ,b]9j1u-AI^M3@mtPOe+:C|(R8Z3=vd ZpJ[i.9;šTg{(^DPKL|lcJmbaߑX^鍛BY>jK;Ԗm6z\m}.zs]_9M|-byn8'V{wI[^&_bo>m>|1MTЙX"0ۑJfzŢVQ\כ8`ڡzCـ/C6VAwӠP[rJUbk>OJqoRkx~{a纜inw!qc-ףF(㼗x7SoAV0tWrq=k+ڮܸHI76UE}Im+-d*N׺yj*XhP[MW|v{]:rb8K~um H~ڔLe{pC^ ZPu>"ȰlѕDb}pLAPdUl2V63׆KsI׵Q l^P[ lV:[e-HO_ 鞟=mPckjKRڂTQq|c)G;wH - j ӼbxYn6?`@(j ܖѵ;-!$ .eֆ[y~RP[S6ϡWiɵ^]z`e"CjQkb Pxp aL b^.]S BǠ8\tX# Bj-B FOB 9 ՁCmD0]*D!vHp1zukLE8%}/v} :NKa^`l갞#qc/iilg<0.B < @q?$l`zEvRIzZx\fR pLX":х6L/¼|x)KG/<{_b;Xc`-FaY VWj<ÒNzxXTA)`zEk:),)Z84E)|7u#]nEgv1<LuagR%C%$s 0! VTi?B#Rg<xڥ=bTvhYM4|x,ZXzGC|6*pJ%e)\VL<Ӓϑ$*u㌃`:x;*ߋsԕrX`mz#+ `Zх/R]JsBDlxQB|r[AAS+~ e( BHTx!=Vf4C> )cP_Ka$<pY"|4IM7KU"#yc]}t!lJ.7꽛RR.3JeJe>ٕc(I "i}57SqN98{}1,}Ptm⹸ckХ{ٵK%؎JZ*ul-lU RoZ/j{^;)<5qX\6+TIѶ90߆t_6)ZXɤ+{=ܺk_yJn5QkeA. yq[ϐꑢ^%,ǧ}[ӣU;_ mOB)⩫B?>)+Զ)73OʫUtx .wbzCm=*5#ESɦGnpOYgoA?OΧmo&t$u;hc(5rDĴWZ*86W<m;`/ߦC,Xӷʹvdִc5sK ε (cź`CϾ`GfmZL%9,#BC!0G֫?3oy>WOv~ze*ˏ'9B~iGpj$G>AosZԖ!^;b@ [,]k㱬r M[lU3*<եM:gRtMwj!&綴_)+[P*0=ݖGa^êmdk낯 o9nE+D!&A _K<A5rblīٺXԼMq  @#Hh<\o1lqьx;m\{ÞoQBmlͶ=S,IH6ob@WV![ߍ9x @a[^_֦Iz#Uch,>ۓ*~aװZ4ĀT(&5(\Zn2+/\o,ؚ)h.Ƽ}~)%iޮBRJ*qMċeExL!m)NX,6rw;qA7m2&)PjJb)8qDz(B\hB%Nj`s8̂8 bJQ&jM8D4_*eEn"KjGаRҀ$ ΀-S r"& 3Ř\[Eڞ>KD],i#Ix%!uU 4_sMyEXK-b*VU[nd Y tYTrZy;"%&6LwET0èAE.->\i1J\:0aLb U)PE*R%JcrJzIT ֵ}zr[ɜROJ>N@e6,2`Lp.Am`-iOY(bLIMBrg(Q^'b}9OԂG1bkAX{8oA UĐ']Ut0p_kxKØr )؁&{g Sm11_zH\k_';3&`r`Qy&0i{O H+%U#|V\3 Ic1&xK>ACc&L<p$1=L4<3 &I&h$GOe2CƄy#G=&>V`yFEzXL q2m=YߢÜKXwapܞq8[/lNw]S@֜!T-'>jzK)4zM|{`y˺0Ē +wYrv꯸Ut޽jM--SӀ)oCý%zT7XW|Z?Tq כkYr+ݻ؟{ >&uiO-ڮL5j:Ϝ~+x9i6ljd;+ީPR{3S|8K[Lh7-Z$\Z_kCfq%hD>*C&鎾sKl:څw-=!k{6gƵ5TgHҊx9j1hW@ٽ;bஔM3{;0yi[EԹ5u\Zr?w[4峪v FGLҒ-xLlyr}oBע}~|w?aoKYrmMҠH{zp'V3vF^piEgaB,`dMM`.iN@wOAZLX~?/8p>֭]l,~m| a_dZU.!.ڤ(C=\ym.^][ɷYY丮m&eO.-bQs>- )lD s2{IKHRKtX'!D[f'g  L[^W`X Z0m4!D(v^G2­@:eUӖ&aKж^ &iUH\*eZ]ac WSІyIj`Bz8 iUi^K'VE_\Xbge;ǡV| tXZix ]ga|YzvڐZ cp#ȓJ6x#yv#`ɀ~iFP bpCV/ `#J&<0IdXYe0!#A)xq/in%T Q(e0ӾoRg\[ɄBsĒ>#o3tOB rt& - +?A| k$0tY puabLE.ᐟ -}"๢v0l׫6xQFt_g}|2H[[*D~-'ipY!d I^q޿[9Δ! a_0$Xx iRR4.R־21SIj%_YK*h1v ln{W0 b_DW#o3Z`9 z@yڗV.TvŸ2u.sy%0mE'qM 8oSM/Ϻ© m6Tn= 8dš3=Kz$ ԐfR8!kV 6;{y5-:5$cQ"~*HhߏH*@ϺT߭{iH50 ٗ1ӗVzQ4Xۓ~[g. LKJ }Kp73џcXzejߎu>{$*-0-G8}>j.Ywq*ipy_ga#c_:ImsfZ|!bγ-YRiɏ"v>5Q󲘎iI izu,齻ihT^)+U2`ڌqqIMtVz[kia-%uz㋿3ȧH`Z.a:S򃪞N.-k`Ze2* v-ҝqŹU|MرG,ƃVr4{!֫#gic:b %_??Lf)0}㍢; L ,=i в<A%n#V~spHxӒo%͝  LKѮBVxtIұ>K냮 LKMK~)>{8i%Y4܋ LK޵gqh9g0}z4Gө/0mqJuXs0mn&FB\ٱa[i?XǶ,SNsy|U%h\AI;|!q[&?3n^*jܷh[8]Mm`4G) K4Z$h 0oebzfH<V]O2篊^s e0s1խKKsSPJDo&6)6>MGڨnK[͒1du ; /d-7sȶv%Ro;Q5[D`}ibDM'CVqٓ4&&P)}VӲGXmuȋNj1֢iS@܁_l(r<V&55ƍ \7n9TbJi8@GB,#EoЖϒr#=skam1n-}t0G_ŭƭlƭޠCyH׸ZǀMsck.^_sᜦ+4~r&sWonn)Fٍ)?/=?Pc}P硭[.GX[VyO9Цr"9 Òas[>-⽞Gv4OI7W+Jn>mLf>sk$Fڜ\lw{A:Ynu4昗ŭ<.=R!ȳΘ{ I`X=|-sT8q>DtE-8J,|_ Q~Ix]msM8ʛfbguK;f'gLO6s\LzCb(ԛC!Ok¿iSiqk 4cLlYikku>3Rƹkj蒽)Zc<-K塖kHZ!TjТWI{a=nVizK:z@j]}LztF< Qknd@,z. q@#^$⑺Or) fj/o7U1&Kgs˶&RaOsW 3y(uǵEg"Tnmk&IJ 8k$ǂ]=سą˺&jI̼ؑg(yvJw=~^\c.1bKA73/3{Ö75LUi)&=DZ/IHv"1 @ 3[F J 9z65HbP2ވj Lc~p0ITGn&ٳVĭ6[lD3bj6]"[>iM7hNjؔ#+H8Ş|k^oP^M2a[k `:%#UAy/m_;KhtYXS%]qloګ%XNz}-Vڭ|F[\Yl]͐?Yu&Al2ӿq %W)΅g)QDĞ5]_߲vz zE]K]F%#ޤ;' Ȼ6k>! K}tYIj9GS8A=HLQ";:'UM*֜|R%>t_ZEOď5g&tp.):N')Pn0υfmn}^:嵞ͤ{YWRۭ@\TneT8T/`KtJJ,VIЅF}"Ep6si)za8^iy.8OWRg(%MZ 5b*Lu鎂D%TkdWV/V`y&n{dg6KLTkUIoїԞےAJtLTg f TL҅{g]}Hȏ} ROXql_pJ{8Fom#5lm(t¼ٙnITZwb"6;6qn8ǖ Ew ,i6)7{G xO4]l~1~N&fy FvVU WOa%fv0,؁ƾ/C7nt\n7Wew\z8ٷ'@ui{n-?Yj{/oicZ~,ӺKi⽥;`*~tEx:;Qc@>蕱(ôN&mzs?S/DFq60,{ntc0>-~lk`;۰9xϹ ̳—u\Z̊B3lx4`;lύzEEÏHXƭ+rZ-;zp' eqlMZ帽lÝTw$ 9>A^|(^+?Wsع<=0/9[KҸ/)Z@bJ:%1lin7h6Pې<ԴįŭEm(_k csD 7Kb =S@q&'_mx#u"ski("RWb^Qed&3JoŌ$ SPGe)ͺ^WѣS~gʗjVc{sL}紇"cmvڮv,!()Ǡqm8ۑ ?qpqhSC%R8j[ğVvn!?l{0&|vq{ΐ7s 7w 6yɣVi6.Ǿ3t}*ñ:.5lư$ݏs' tK;-$amպL0s%c''n;6V>gDuhEEPcǑ.6[bm%Uhj?aI%:3xy5Q iLX`#Up8-K:]'E*0(Ӱ<<ОJ$غ%2~&\T}<2)*A,&iMW%ڛ.!qA{FPUo17k5>U$+H(0V}B>'AijZ NJRaO 䚒ݤV2A3M7'^2T+tX2KA+e.Z> #Xq$+d|U(UD€B^fX[*ts* P*iBEZXx" %)tjDG0*\Ygҵh$$)v_RZ# lJ-"SQ7cmqH6 ϋϰWv_ 0Vۏ"qr ] 1]}ou#HhZ3>3O}TdQ؊CQ-uۇutW{%}omy,sgy=K [BoC4<[uǏf~L[w%\u{ ;1JIS̳MSXD z iF%ǘ%k}f-Vcoq8ִzk\0Lc9 0}y^W8BE :-r4W&-]orۓUW)ȸ' \7-iw#L]iK [Ӊi6ѹw?u\:^J(3-%J?Zoj^%#Ӳt z %pF̟SzIew![ύyKcqΐTi>zwEօ}vsZ0_S3\튆w1MYb&r[S׬--5M<ܘTwg濊 sԣ!1do縶(`w.nh:eKPwOlv?PvyYx$*6mW1oAOvp?foB p=P#3KJ%Ch228-6w[n5-8Uc hcҐ8b[l ~ 9wa Q\?{o(zṳ= Sh{-<+%Dm/NÕO"\PjO⭥jX2^ozc=funb߈S³T/wVvPP_ iP 땓 yKڱ _wTs~Mxo8|S^n ) b"IaMP<0+@' JBHƀ40 Іd*uԋm@>/5F"b΄o$C61mI0:Z bԆvs2%ȱd-pW+  M['-sqM`́:iD pF%s32ֈH-_cj`YZLаF~e s&*e MԲ7h!UF%  j[ix-`YXp8ozL'x#!v}V³UrCF V@%caّ,.du5^j-֍X;FXbJ .Q g(0oZ/Dۥ SP#Je-8Z.6 ļ} 1@2$p2dANY϶H;Z[ {(6ip S∽h9܀*<}l"y+1>0^\6*Սi{M8^< 2>c3o30܉$yWY#;H\5!qqCpZnĕ61兰φ/_)m 3uC ^ŃةtD Ǎ-sjT$[>G7DTϣ{7qzPt|AL71kӀ5s*@#b[^D@˸b0̦a.3ui Ԡdq{xEv0&s{iNS^+0r㹷TLOu}GV[<8!O6gyyKya^@T4g;Ǥ}2P)LSoelCs4a>̎I9-sm?yW (|[lfKN:1ynrn{hJ'2o]w)Xy8FUi#{;uOːo-w4KH.4t`wvZ ArأySn6h/ţxۉ'Ql˙EǼ <獧Mt#҉䏟fNSBDmD_Js\Rr0' Y"xĴ^ >$ӞhSp ‪E"]=0ZAڱyoSo4E7$ge_ξϿx?%gZgM--X)%5i%g-{ !7-(+ d4Jgq]Ğ 2LRNm@Z5vaq[EObՠ:%VH7YHv]8&M +y`>lЃf:YaqTC, ǴUrP\BbH<,Xs_`  [Lcv"-8p5dv(Ռq(YSx `܌XRU1qjm^l8;džtJV=G; 6v9l۱ c^|U(,aS%Sc ;Q ~4khc71 l@ڼ%S&FEl%/nEd;87#( $( BK!Є-` $Bɠ/VB `$X`c@D#_" zm:LtfdjU0.JI`9TstK~Ӆ6L=icpgkP2aq.]]}+}x'L{‡P_Ka.؊DG;kB&煾y`~A{ʋJ AfVPJ Y6L %JV`}NA=} j^$ɩ?g:*<'8 `ZtqE|*Btόx\.U悤7/'zIO8 L6IrEn {JѠ zP[I$) y.]U2[>]OTK%C_!Vp*5+==@pG=-,?eKwu-y+ ԺZVGxxĴ?L1L-nN1X2*~ /۞:V#_Rcom81Yl (I},bў')Bt:LjFus;W]1~Vx`x[+) 6 9KIlt>Uܩ _҅s*&%9Y0A}\WSruQV=@KB;{Et-CEZYRJ|j_j q 竗@ l|rr d8JmL6mթUdX1E÷RB?'_Apd8u(%]ֿxNh_/KVYD _/HNum缌x_ի!TsiCq.X=o%[_/BV/5|cK&-˰ޯIX( lF`$yQo]Y'[wnR۞Yyc+)/lͰ/`C%ۮaRjU.^ntF^Kz֕mT+=,֤JMJkWɸn=YJ%=J]|^x:]dbp=)!+,ŒMK~n5=Jwn8 ҭRui~? 7)#7mM P2K6t/'/Sb'kq5Oc볤tP,Uoyw2ܪz5PJD#llF?{Y@|L^|g;>V[WM6eVХS.YydVm. #]+4FT}vBڳJ.W-Z/tٻt)P zn3*vGzo4Ԫ u&i.XHDdSUZ??꒔I}_z^}:$xd6Q/[㙐Juq}NM+)g g Y> 5kz+)<IiEzqowՙK7 Xt,zab._Mtu8)ީ*vx/)xu\XqǾ?be/U6IX\X2˶uӴMStcŠz-Iϧi羇R|٬0@ j$oqak.dkҭ ,+ um&D8}ڒL4sAL=&юo.Qb3=%e-bleq% JCA[RX~%O.194w..'^c-sFP"KuI8״kԞ-ӺoO1<椦Tg[bpZE)񃉏cNّ7l[zMC*گ  rv!.%nk.kK¯t䰎Z.8ǀ}rNcԈ?V7˷DOsZ !o>[9 !HKcܚ9fe:*/Nnť}ao< (:q8) S^2Mb%'ɪ "u?Zu B9{ox~,]mmyjch9v5j%Ah;$ܖ{9''Ҡ!qkbt>V,k9 2-ؖ7}^vzƏ!Mc@8-g{}s/΢⣸M56񊾴 ,Q;xTאD(\gqifqxc6ȡ usl9cϋC I Q{quE\RvÔE#/7*JxJxz-GWmogrt[{ʇĻnC BZKڰCe"vY~%T&U/I#`Cy/%eҴCSbJI0LJKsQ5J(kdcMyv+ ^QGD Y={MnG}ZɒK,ccKyZ8DOj YkVi*3Sk4!N"6[ukڗ{X뚉)-L֎s8B ߨm#fbHWifKiQZpZSieekRV$w1lT&Fs޴a b(-bw*m.XS&Moy-|-7zj@b3&Ӧie!S/pȶ۹rb*\Kv1ieVxިn-WݐĘnZM3cRfCSkxXKnzBvAekVT8\ɭp0_%6 iVu"x701i8gbhi01m@Qfk|LC{ɶS;M2+67b֮ug`P?,,y=^[|ui@I,`bݘx8lMb:+LLmLW"iثV{٣MPi۫U+ P(;w`Ӧ!^&AtVnouXڸpAnLS ^/;MbiV*sv`hk W`t[dbD62*Lغ\8ȨnMuCmb56޴ۮZ%1lCx[7Mb!;ܐQݘ^^P2v S/b|PI&1i[ 1x.W:eo~D^8hX7]؃,1"z6 )Ԧto0K\[ϭIdJ T8f&Uni7 WcZ8N$V^7~{ns5}ӡĴ2=fkk-X8~Rt|n4&}\*<;xhi3-[ۧsLnJO#Zf1lMںůfkҖ.T\©n&iu!O{m׶-)Ęľxo|$FcR2C/ZN(1Yl6CuX(hL :ك;%e ͫSAG,V׳`t3m~KK,pjkM8PEl_-GkeFiZvQLw{V8.\V8\ >k*pkA*>CѰL@R^X7kyn#-\(fcڴX.G$r/MŸ[~?dsebxٷup?mMki_5s*"uz Ӷʞ-iM8ȵИ4$jZ`p>ĴHLasKjim N\f&}k>ϖb{ntG×ZH$˞킼K` .W:P܉|h۱=ls bo9is -֏JCP[}ۑJ(nOj:3٩Gb<|-~>Kj9@fXBp~7-!Ǐ@ zn±q^tb|{s j!。1.=MF˞?S1Z_4jՍbҶ~)\olNm7pYx&1ZK4ɐM {k(6cR6Uݐᕈ4rvsT۽׭&Nqk(fVݸ*pi\#YAMå߸i/u\$;5~!u ?}᷻\6QԆMSi/ye- &́z_|\T7N"3Ӌ ?itŸpZzh ƕ*9ؗtIxW4N9)] Uq>ٹ z>iNG՞|.gXj\?_/WbmsӞwkcLT ߆sjK4F n6ys ][|kq oOF0B)=o)xAG6ƵطeMu^HIY7.yo-a4#ϩ70gkgARXzwJ24-MXt4q>~E@lV&+|aa#yx)_2no(!9^YqQK Pܺ#҃ سO˹ި3hnVo*LHkX`%Ц{ܚs,ŌY`m>T 2naʆS5V1[#}/`0ae2 9~z^,e[><̡`&?k4bdL }G,)E֒ sumJ$YCJ !1 ^8Բ89qit.)\*٘*ƓLqcQ8~ {_aaM&槸i i[@1?cYe kO5t_U pm!Z0l[rU[n[9E4ˣj+HXyc9;^(8+\ej`mk{"J:[BAD|L %Jގ3qx)AtÞcEǎ%(-~yS HoN_:P ]m>I`hW$IOsy ܖsv~Ԁ) c _̑9L1H$k yk9K2i>W٤_/Ty smu62 o֥)"-)f1Uc z٣]UTܵx[fz~HD֦<,(,(ĞlҜMwqP.lHP7gf=YN 2Ts?7t!;Ҩdʇru y+P^/t$޺9\ؓ ,9Gb.er)X R o~^X6&6<lH*Ja}\u2,]X7@VZFuh&}[Ea5#KHR;<(ɣȞWmXIUIaXbIwgYaXg2N Y҅z )d,6?=I|uՋl0:щQ%JS>f%c FTBv';lui=#m[ndIruU$V䜩u/q}Oi7KmTq fh]D%7L "maMJQx.Y}n:J"ގae.k;\[lf7/L? ~"I˻Iu5joڎ<.Ii˥`Ja]+o 5Z_dj3?*J'IT|E lf๝%sγ'm~S<i" mzQqkM栬4I}PɰAl?nղdz"Ix^U+lRw_A˭ڬtp#ҵUv:J3vgkWOzEls,v v۠=%ھ0(I80d5NmR%×VI_lα4W>6T/Y0p,dt?νn1u\ ~F%If}zzl{^^_9^5_q^{ŕwi9i,yݒ_o{q!L+U2dՍׁ1s!4Wug>w0'" YU"q;pe~t.Kӓ&zkvse=.NWαlK;+bۧmhyOA| rFXDPk5w((^[\5.}J$ ܹm<Ƕtp4]8[_Fc/\t U22_Vp6F̤2w8 Ee8>Wv~ 6&I6|l'FE]ynS>ڲ,Kih lE/ڦEvƦĬ7}8Ʃբ+Sblѥz]~|6(ͺL[5v9wٶSCqQExM"m +h&.@?4Ͳqn4${B][qcML6K{k#zA'5$ahsfD|R)3hS¸X-Z-|bLFxC t$C-v-|3g]8Jbcա9mgC,\ќit,lcq <&yb]<&lm?vxTurn*$m73s.Ɩs7HsֲL9Hx4M 8irkkG_8FPMLiVO<4DjVgƛYB\vW~yB6)t§V]Mڌ1Vw7 C3vK4cksƌ)M\GDxAm?3AEr8]$_beπcZxjLL;~ 8gNi<r1QlJ- >߆x7h7I!fmiUmhl/|H,j˷x!eǐiH dlWyӾk' 9skmpENxX>ǻ`? paoJhM;/=dpm?M [.[31F m3&kZw>k- 7[IrY، T} A[(̛ ىpjck-m*mJEL7mb7Pn#NA"8-8b2ȨMuC[!mD8$}Qi驋O>ym`tAYh@m;XH g&[X][p2i˞koڔd ~gz]) 㻋wݾ5+m&y-i['MHtuC'{0JmE-K;K$6knue-i&ZmYini*^SQۺ vmf4-ѿCsz0e.VUu=i8s)nV_4fu^ĵiѤM.%%pZq69뺏$es[蒤Wag]jo m]81'tmJ MF69 oeH*dd89'8ucT띦]!-(Am, _o;P4y1˺B ?8D4V1&j,vVna[gli͹Zqxw /s25Eg{TxLx!=TM 0R ["oLU$%nMiA.]i!N&ݚ;#ͣ:Cc.[=ŽvNzo~czSa=Vc>D)\SK̲wp9-tڕz#oluM:)Ń;VҜTi.ˉ:Rӽ֪8qy9MKe(a+>lYJFVmZ,TZz"Iaݥ|Mz.Qg*٬F3N}k5V,֤9mh.@A*f9iIiͱQx H*㺡M(ytkϺK>uZ$%VQzINEZ/چt)w&IܦzyrJSvA8;\ >[ڏPZKOdv:'U}T[tڴt(VR}W~S{t 'Sw[E'7 B4C|&3)d/I^U)3T͹dI+iװ7Xc.%*D6^F+x# sɔVOfIjQݪ>VՒ \[oMd|1Og+rRZW{Di~Ks OR<f){.MQA=GnT/IZnPJOBE{#NutGپX^竏k]7tV/_nWr} +޼өUtBi^p~/zٕo"huڏUPe_ӅwX+_+}w&:\o*9y~VOJiTk؎&U`9V]:+=/Jz=Eqq|aZ7U*YZWتKMUyEz{G}ܓyEsۛ; 2իu[]z6wminuwV(w 땷 I|WVWf$WƇRsju|Ohc^$=ѷ@6))!{m9,Y9/W:(v+k3*4 RjHf(Y{(\[ۨVGK*-T2Jcd+LRХz_JXqߗ,YtѮ4`m/K\ףlOd, نZE%bI 6[O>m1_#}A A{W*b9u|qg')xOzm\GM]Rǒ?zfJkݳā%Fa+nl# RQ؍TiׯbLj<{1Jm\IaB yTӰIhM;u[#,rN: i$߼[ 7ojtyIXέ鏍dj٦AC6HxK?mJ֊6.܏iJsҵEڗtRZf] %mL Sߤ8Tj3~)foĵekic U*vW],+Z'gXu5pfVt-|cjMe5(Xus6b}8~v Vt{2?%*د,XUd%d@k!UMWH)ycDqYyZ2MׂBcIV)1GK#rCYZ}Pxsn N]uL)yXʊ6bQO5ӎDƅ̍i-l8wbGx}K\>auv8ذR><ҒƋ%M71d4 bE3Qe`2$F Qro5(PB6(uk K-1msv ڵSn'l{E$eL~5$KXeNbjĘp^%_[iv1)Mocn;_ݵI 9}@U7jKL1\.u*ҀMĴ%sPzmIluKmkU?CocWE崏6im`U7I훚#fvcۜx^3mCkZucۿ!t0QtG"j]ݴhJ i4C4\4U8j#Vxf2mTv71<%Ta.]T1jzkhZC S.cZku:QӼp֦$4K-Ɯm㭦x6gynPjd- f[zH<4i!obmLԩifV6`b^C"1V6{|0*8'wC!WpL1/;nbӦ,4bfk(FK!+0/>tS*_֒dc4:suӶx]k .?ZyknOئto^<=j8,>GqzcK`stOoN[z4JzsĖhC:ThĚA9$  uX}> ds<'0ZB:ǖUW9-┳Nݒ<ϹW˶mWG荘Åi!6Ź'Ѧ=TV66ದF޶yXi U`ZH\}nFФőelj~'Rn@98 1&S:˴]uT0  !UpՐzC(xjN0*}IHA,ga%ǹ~K-U Saj3']q\=B0sMpk{7 IU%S 0) v)%lS5*/Ie9Yp WUpF)$PZe;X霫m@mR#[KJIMH6C3p}"&ٲz󽨍̺RݫԞRJP psJl .S.H`ɞa56g)[cjL qLRTД[zu_vfae%M dκ6(}L I=UR:HQl&{*R*J+K_M)]AX7'6۠I5Vuz&UV2!["aH iiղIL~\ȘRjV3]aҥt )ZjUH~lRH+!)l9K!U%0~BbIkBP45%Q2d)(i4<0n7,F=XuۓLuסݏmcT*-_"ؤ<оx]9-|uH2sT/u|C[c4MEB4О2nۙלkd*;LgJsXR>8,-za/?t'S ҴE'q>g$Hrl˱~A/ClRyhXɗ%qľ>U/chڔf ࿱ %k74jhv^2ismi?1мs܆ulΜի14զR R\{!^eN(0:mN=EYt:SxgavHjdZTB-˴ue3)x%Z< ?ZTxyN0`+xw6Bu[lkU5Q"64˛44OBL\,.ǧ~\l2UDXEquKXNb/-LY(ѹb7LLYhmò Qex,$^ei,YR0_ pHG_L:mY8:]YK)967`R)Rx֧\K#D0mY8 C;-2[ii3FԲȏҥ&=dK:9b$+p.5~~KB #3WXz|n !@ʯ@aږ=ae۱fmPiSp JD ̟R8&HNK.8^7\-yniSZ!m'!b'#)-s~;\8 (bO6bru &pnԆĜVB:Eښ T]LV8eF• 'fu7 8y1ks|9NN1}NZn'0I%!mr M4o/4h/x2i5o864U7cjz\ŔV&Tcֆԋ,T>9QGL0exĶP*ԗ)gہ{ GfLة҃FLLlonȓ 66S$[31M"dMʏIiEӍِ\̮R8> (M S,%Uez〾b&&eBsHl^ m {Ii&K"?KiCMNJ8x܆0klKcWWL]́6%nhV{ dHP-rRMsok#߿HF埨a]sO$}/c8Ӵ[̡D#Srvwp:SVn?-O\?q2[JHCZ6'jskyƭͦwGˊ[K1mOWui ٵx17k鹁i%kL) LWӾ cl⍗Lcj6 S[#[+=ݛx*ȇ,rl`Z20;%>R^͵NM3mqkiumm6|)4ͥ`搘yI~U ii|?P|l!.s9b;g$t93紮~n-ڊ[wgxqT¿Qa7 (|FZJk'hAC]=?KϱGk[RMcIh3և/^c=LےC 'Ki!x5<ʆZ'3~qia09Ik\Z:7昖S %{H `''’CbU `Z~mk}L70m M m,N)iقt1.~VOX LkaUW`lWqo뭭AyZ4k`%=1Cy`v]*⿱;񻭷g*$ؚvn sg4mS;5{lmu _ېWP 0M7Lȫ%&b8}V$-]8nwCx6L=ٶciX!leµН+ X4q앬e i lI 9%0A솱r!R`  %#ᲀ)" 3fg pn&%0pA4lO:"cD$'%ci@dbV c\+)bM z8FuA6LW 1X#J6UJ~Xִ2QUO>LR[I\._`O^K 1+vLaɀ%4]ҮARo `/'3-:{#\Ywgڻk_*Y}_g?2T^% JV] >JhaB^@_XSI¸R Téf]*EVA^UϺ Su`*Vݥ}S@>Z* h4f{v*63P%):Ws璿ZkKRҭHi \ #h-4} Bf!BI ,Y|T$ o*Nn:.ݯK.e([=0E JhRhY(UD0SiR*Ź |Ffp=k2)DfWҥQ h7[RKX+^ҭWlZo\RCgdI!}X?6uT_=KI2q>0qӛakn瑒RILMYp3l-ZХJ9 KFOI>'[Ga#ժi6} Q_h[2|mCK\J]t-=#ހe@f`WZ\m>%xI{yw|ZK{2T+-x\t_cHd(ܠ ]avxEW]lm,g;(w:̡DC6e_{Fi_M N uqN5xLgZ47Zо//'`>r6ODu|w֟7GsphFSaBGj|-*T:[P8' ڙ\1ꎜ57PVD.⣔4Ma 7jm rgeX>J5j-zgju{?Rr`k̦]G ܴa6.GSk-Gh!=Ns+6j-9 S)u,mZL3oe RP0\v3XHZHa րܝZV`sC"u —vx/j~^[7^ OXB,F3Ra n1#>߅Ued T[ep?1FVNuĉyx)V XY{A !ϙ-UP[*+]luŋyLbQkEj`,ȱE3K,-)M};)2"!(rSez&~[Գک >em(6͉Cjbh(\+*\q};peUn-2 W+[3l%7dS_{;mX(Q +'ijE6yh/`:>BHD0#K"Q\J,C U GF"]J`%6ߺ{cMuK`YӦ E3F̆yu43U#FԜWkxSTbpPLSdonM`Y*F|eBMB4@hL~5j#b p7iq淚ۢIq6h9( zGاiC/u6*jH=6Iz0$b~iDT(v >$*(iQD1u1< ِb|; (%ڨp&6!)f%Sbʹavgq]Ϲiܻv=y-b@2I,F[{VBf7$ƤX8!3߆\JV H/$QclH_rȒrI@Ái?w*-4$6XjhezO69>7j2$ϝ5#aHp2 Uw 2!`o$Q,@Ɔ#'D0H BlnD9@F~2~ [ᒚh4T$尃S¨PmXSVv}V&a-4 (Vhw{)%@ <[9%d&nP_CZo1ݾxCPM9/R6~u`jc¥M`AӨ1O siV^B\E)_z[NFZÇ Ǚ}>uX.[NHe vV(Q .m "iݧtݪ1].GpN5-L?2Ék)Tm҅M}7-D6L5fcAm)ޠye*PcN F-o OKkQhS͍#qe?̉%"mNYq) 4lP[1o j{#6K]]:4n̡_y,zv#iL)iۛy6o!CNg jKſ,d9,-ZҴ)oc]kfob]%;bzbݠ9]Ac6c vsmr4n ĽY-KFsvp9uG4:y_x-Xc{W񺌟&q,KAe.7ʑ1z 6B8֭z?7]߇yR.R6ۂ)X mJs">u9Ƌ۵uŖ)~@`2. hLcou?cӔ4l7w_ CRT~Q8͗+=G2?|6Opq G'ɺ&i}ۘEsǵPB_-pmchb.]ڦ؆(^i(+IiXX'V+枢Υ[y\2L2!VDAt(J,GQmK[*kIj#/]ڥn}W d{".K#h%ID>3`<@򄙂3nJjިV'1$gsf7}˺> I&RhoFO,8HԤ6xmyGv^"ϴs+ 46;<"(&_q¹ |`@tŽްVZEM{Iq1ަʏLĝ$Wۄ=ZU2b9Ke(uaO1]5HJN KI`SzW=9&dnkT_~V%T\&+9],')vf&-͕TLq { y=Ulom@3:sR2-NlD@1b]|Q"g,Gjtቐ0DDeD UΗg]8* wŦZ;'X SI^ؕZeR5{`q-VIQ پ0QOjK,۠~6)lZUt~jW& Jc4oZ 6iU( $O1TRRLNHtzKg:F.%e~gok%0vr6)235 TIdsf"ɥSؤ/G]q>+_nUDFiHZׇv5LTZ/V*8OB69֓tFxVV;T|VUq-qسq.z^ʨx,Rϊ'{.1oynD\Ƹ哐wX>vzPI/73:6齬J1cfR kr D<ӹ]aq^.|Yy܏]<,sN/ڕK 7+B\NüYTx ޞ\^_Bl{u^./WaS\j\ȕ|zIl}qsr]*Yn 4Nw;OF\ٖa_ Ym\RrIw- XVCuۼ{G~Pok1}39W61I'=R&N~vI%xt: g'βOힵ^fS sfOy}Ou=/KNʴ؅;'.KǑO=6agF,^{\`Ѯ*ίrhe\pʤQXtg~ i-!H}8-qLu*rթ9] nsZνX\צf]:visk__X\oX[  }ۗ5^MH ӎN;Tx ?}I֢eIhMQ:lgVgM/d Wl"c(Jx6b+toŊ/1^.#тUr):eZ;WGcbuǁ~lsf4Llg˅YpZ^[\X`#%ExĬc@㴈? /@c_8~ PF+ǍKq1^+t.T=4:zoEu߻-.pc$ƣ]<.V\ |(؂n1x`Ol&V0e_NI'A%DC|I`qRT)5;g2nB(Eg 9c&QHp<En,MN%0iYK1.Z[}..kW .Rg䱵3 GF4 SpBsYbTf`X$`Qnv@\?6Q97K}' !Su׵ KH8F1`ohfa@\? i-N0zchLxg:6 #W FF1Rp5ү@_͌ύ^#Y8bc&-QFM/;WG*5UˆvR7i"1x_ZN1"G # d|0>o,xύsEZN ׋幭pc` OidP e3{~*~H[,^Pg"FSY i4D+[Ѯe)n8}3 08+BJq@mG"XD;Aھidg'`By0KƉu7 (@_n " iQdZJ |#f_#Npw q6:n@}AҗwuXtL/v M-߳<VqDz/V,QgktbC=AJi!7F[IbjE61pc#VwFF1|mqє69 (w5Gځf Arl_ V1 .v=Z>[&mOr^޴"WEzgXg1|ve[I3bMۜf}蕶U |\f鳺8˧yڨþ-n{Υ6. ĕ&KG_\\K{jo~ِo^"݇KDû^G )gǝu[g罽u0kʀrĢ%;.}W2~ȁe ;=SwyRkO~^Arkc*o]劵'8-EI'r17s'+aj ƀu>ex)(u,_б/Cjĕt\ֱ'S_ @J<,Sz ĝiTtUZ(! j+2ϟeI8sWHB*lKR$RCגcLiUmUp3yyɵ΢?u mIFya39kul\ye1/8Ƕ%<0Y}czIs{ڞp6tqH?wvގ+) :;xb#(?y_[C| n_Oj+NJ86r6fګƉݕ֗ϴ%WrIo']+gȾb.rR +X_8a:rP(.1ű̯1e+D~Uę`8S6Z^ϳsBxH`e- sʑ%bnv! r^1=1n=-s[}nEL1Ó;۰a.>N[ ! V wspknb*`hZ(sE2:Hp>YϽoߩ1iiaoAZ6WLSXWeѲ7 w׶,vخ sxrh.'c-? Fiцb-d=Ųy Bok5[菂N /N5-F=zhYb[[9EHx> Y(֢j1^1XXRlLXAƴu;`!Ø1B(Ĩio@\wqBý!FHơk HJ7>s%_d-DV/ӄu)s)%.ϝI\8SJuh[ˑ# fb1k_c,Biؙ|H JMC;WWo3/VwRȬE*iK&ՁJWE(-Н / Q^Ѓow}5xଌMqv%rC!Nnz0[sVH[*vEZ[ny':DGl&V$!|W~Kuqƚ9 .~VmFV1Xo8#-C\I@Hq[7.&S1iۻ˫?hYk0%m"bfȕ] F5v) `P('GA0lZŨRmMKnMbcvF iҖ$IUXUiE+|H:kQiMW"XYPL3ح/hW^z ։[ }HkF֗2BdWdOV e.=%D]QS@\:6>] +'F̧ӰnŁy8/\mq #\S0Sn6XgTmgč~ir9 9R}ՀD=.zz̼qJ3r\<Xg.^`о!粢7~.) Z3ym{~5M NlTSqm@\U"Nݕ1-wn]|+w;ǵͳgޭ#JnTvƻl[+@8e(<$O-Ykϭ–k@@\xHRs8m][ iuH el ;ƙ3=dX.kiCx6Ͻ:Qdie퀼', L\eҥJ`V]:%|s'K60-x5 \*@, %#t˺~bW%>֤Uѳ ^ L%SZ@ϾH^(%KRII&Iy_zC(ou)A ->$_P&!<0LE0LXb|^T3j-l8F4 ׇ\2AW7^hS~-}D  RѲ:nG^e,9MXz??3ao Z[ѭgr`1ٺs1 y6mtYU!`Gi( ?1E}1dI,"nqIm⥼`%lۦcf\bU|MMn[t]H%C,$ ױc/Ex9v1ۅ⮱{p7;Ŋ|4Y[l}zD1 e^)2Dz}oA'8zaEf E:ԓз] B8y'Ή5bK\O$ FX/Ƈ#8'Bό$X6XZm"n.Fw_C!BM4dk)'nF$cz)Tu*aSqscڲv-Š4+[^4KP [&$km|0XhU1% =-nU$`T_vf0zl`p'Kii $k|!c¥ C 7Az{I$(6;{[dw植|65-t6*'׺m?+^KwҚFXf[lCt6h#I }̴#1&5mMM6a8f r{0dJuKbiWS}ӵM\ED&D~q6b)|tӆmȘC˘lRRm&iUBDĵT52sq@fo)Hx͘Wv[#83qVm@snE[9SƁC%5:fGilCFSDm;^J`,TBY Iր({.~c6;|=ۚAi[ o4x2NP` \$Q/W04kĤw2@_ǕĎ7+q][;?OXD1njyA֡yy1賡g0_q4}\+[C"i}*gCvsPiZsF͌ө֗Z>ǰ$ST>SH4lȴ]ƳM_lɠǴ|l-c!^i<ʻ;ⵦy'r!o,qgv7p9聱갴q&k)N4׭-%lIg]3 +ʛL^A5"੹qhHҦL,S4O,Mvz{֘yʱ+sjx[#.Aꑭ2my[3x8}q|6#zj\hѯջP֖diǺy[c_B*ӱq5M3mo. 7Fn3\V$"F`ڗ h&^A.GmFӴZglMv!Vo+׹@xq1mGp]Av@??7Bfwqǣ-K8vYTdiy;]ڒ kv,y{  i,şRRn1m𷤄XϑjjCK[ܢw$]8yvoSuCiU+z֑"wC&+n/wIh]Y +m2@d*#fzc:f y 0s\1j6ە#os0A!o!`.Wb& = yßغVdͱ^]+ oll+}% nAQҍ:ގtnkG875F?fn@yB&|fT-tFЂl`: ([*ڐ?R ,wWXt FS@36ڭO Ľbr u`Pg)@M*SxQ* MUE6i{\KV2JjXr}gRjWcoW)*^ZI5+K6CI>m&4KgLF6x +>b ãt+Q cP!ʐf Aӫ50SLJ缚 V3BJ\'IWO] 2(5.)Z0}Aq(5ۀ'BHsF:9hÌph8-)m{7 k 3BdڭoKcT[c$]2#VҍLJJJ%Mdz^4(ג%ݔ'%ZLk3 ͐$V$CW$N%Z ٤v/ 4 L mH Z3U;Mfح ZLgoWvE@kz"ҿ஡'F3%W!4(3 p׆U#6>wtRv w-h1 hMhCdyTĭ%#rOa~Blj*Yg2 LE<#YtSTKn\M,pȦKHcfhYA#pȰ[P`43 MQun@.ݩya/Va_=cz/Hca ,kdڭ \+L֎h,[h1:IJ`ZsLln&K!/rṴ}x!0 }^WFe 5+d~F)r x\uizis"hY{~t3J_\[)#Iu5 [qiO֖3 WVچrxA2b];߻KncKpJ}7Ml8+yZ|amRRƼ 眾W䭠PAma}~I\V~AmiwvS=i j R0Ekڷ)qK2e7k>Q.C)|?WI|^ޡ-=EsFZzGlu-P`md*uJcMWh)B"#Jgm*EP\71PiIQ J\s+ANk0Pז @%©iMHcҚjE^r%%` ‘ׇPe7 L!yit( J Gh1IF% 41x03[#mfG< *ԵU8!֐Jmcmubb,́p~D>Gc"L)(,HJweJKPہ%(tH1.11+32Y`7z+ᮝi Ŵ4H5izNBG^BN~MbcX cH4F/8_lHZN /M8oڀ }!K6kPt1@0)hFED&, ./bns \#&#&!v\8uVC\gl ׎({Eg|;QSN)#ؗnAmWt$.oӊLMWdi㈙LZbi> ׉K.jct}wVĚ%s{(kߞ{/\݀(Q0 pvG;Ap,[f n^_0Ǭior`31.&K5r,%΋0D[.kV+b͵.+; jl!3 Mڢ۰jQk3))"4ibUryDHy\ Habr}Ҙ h_F]VaDgݴu RLO`b"'T2p-d XDqE.HL<\`"9BۙD$Z/Kx^Q hHC ]e"6LDiK30 =6.ImGDT#OmC#>u,I'i%N+ KAF$~(01C2)H%K M Ͷ}`{|MU|ɯY-ZNg+i>tՓD1X2#`q:}PW'( eӖIԧ>#$21Q7P;"JJtIl,*uF%3_RR[>3#'ŗI\-g +&#H̄6{r'\ HIo*ؔ[L+{^!Ԥ@DBh>後s_s-Hp2/I'q6 $$> hj1LV~ԅziŒzb@&&8b\&&KFsv3_m^,%3J:߶ Ӡk{dU7*11.,{b]8'=jg]|>/U 纯0S^Iҵ Sk"*Ee>K6^LNKR▒-MNP*d&RL艰dkZS.qZ-KU p"l͏%眈x6k|dHtQqi ֭n\y>7=)2־.9u[ ]l+{1mav68=҂򒂵aaWieZ]5qTVc3pt䲦{~ݏN7N_{).rv=y{<ZK9z7s~,;5Vƴ_ullRTy@8C#5jQ!RoVmz(oLa.籭W}vCwkXc{_K[UOy`uMHDݏ?I-m*9px<'/ L7%UHk7/=ҍiKƴMLE>hiKtVsX`ɒ~ߦ/STR36߹vQ֥wm9j~nb9YlrsMw"ԸjnϏ߾;5no{nw{mHq\k3\NQ y G>48/+<|JǷunK? 1JlWwOF?{ֺ;vס)ƴ.Q }X Bkc+31J86*&*\06ܮ3B(Gyh δhrفT5'Kfq7..ǵs_ήWI ./Dڋ/+HJK>2؈_TGGpS[MqXXÐ[gK0k!ֵh086C"8-CZ& */ll|=0ֵ6bcTw*%ioCL~l>O䆝vKءӊ7,FxDzc}{H '~PfƇ#tOМ7`re[z#1\:B"_Dm3Z!RZ+'5pZӈq|NlW6*YJ oĂ"6; }"Ng!+#P T ߊߌĆ_E) P b5oٮheO"1.=HC&&NZL@`Sх)fx!؏ĠxN|`Iz i.HS2@r+#F:.G&Ui%Rptǘe5Z6֫5EhsmZ%E]VQFZewlt6)б9cґbt," $N7)f0PGdZ`ep>!DM+SRrTʯ1uS|$"QS5)0`U/eMZɴ@lcUٹdw( ]ä@;kU8DQ`.1oH |Q#S&i.`ə6hd9D}g0JwRIȴ4 سID1^. gʫ$&iN_L͜^fWcLY֍Z2vݒv؋=aS qk?i4G+Y싔DąkG>0ٕJ&IaS%j`g2rzN;x g$,?ݪPZL-Xp^dm:,sk%}|", V_YoY?tgΧVd7>sz+H-E=E=/P ϹWT m&6r\ӋR{"=6D^פГ&UEmjR }ďy*RDy}Ś*&% w .1`"֒kZ[EmIȻsI|Q`QRne%̮N/ >?>P]Yb] nVL%M"ؤ0FWyܪ#XurL~]>s,[Sj>/Yd_QOi&ziż+,IK%kU%-JM_IHDX/.IaERϹ }lqQJcܓ_Ji'|`[t,]8AyodkaV)(-WO7m>>!:_[[Y̋K5^XZYsnUu:Ha״U~\'I=*֮q{Yl=K'N[D5զ/92}>omk_!81=Åd:H9sü<%ý,rVwLa7"ݧlcS~g;#U6/k{T뵼 ]Ϙ+v:KW?%!)2v.zv7/kKte*^xHt݆3׸KFhԜkcw7"nqs٣_c΢SvN/8[G HAǮxg؈}5O3z{͔ރ}%Ι?՛+sx<YĄ_U<; &αZ)nHg]0&Gv6y.V} !)0ܐ˶.f9.SkѼbϱ-t8*ڳ!oZr|Nzƒ۸&w%EDsg?L[Z$Dڋqsp9WDmĐE327}W)Z551Iү;b[$x lcK;Vqv Nuq95ݗK1禨rDo-b(&؛0zMDܲ|vH #A$!XLW98j~b~x32LqS'q9x#+:}a ~kz #yY /L2L#&c OHzl 23i_F##,D~D! ґ4 )8QLU6BLE)p@W .mMS hc3NgHgTXMU%&_Qs*Jk MX,JMbJL6&hWyo[i$miB䭭k_3mSJ+ lȰo%~mM _}V1|]ņ Y,i&~i\b$QZDH2l+K8E)z-=M#UgE؉ih#M;0 ]PHL\l@ F mM¡iLi8LLPmLͼWp,1N_m|StΗX UpMq$`"MLkٗiK3b0O|72,QΈjҖBkS{JEs8ߘTպxIи2ش@ ò6MYWK^YBW/1HZ"OMCh]QDdR(eBmsT`rolgj%sek_Ri;-b&CiZGLM!^[GL=8}ci[[ OyC`|e<P0߼ ;F 8/r}i;=ͼJn tI*.Š(z#qI}-qh%-SVQxq*Ot-trDzx$Ows̘xGE")EkQp-J l~vvLS)4>k Fsޗf[`OӴ]GkXqӹ[V&!x<}m97zuv;U:Kx*uΩxYr9.FZ-].bGb@*ʸ `D*za  L5et,mW"3ϣ(q@U2V\ zie KK,^ >gQ%֨IKOD"~3oyLIr`X v+g-M2f_Kў0L},/$łI>3b> &}~" ~-58F}fV ,YQ`imE91qzK,)Q+\%NeE% Tr+VQbϒBox U⯠e)* L!];lg#B]ikLUzXoL\EY@"qi)ĈnZGڙ8yuD[RxRb )D},=Y YPNR#Og_x[&.J%/G"ΫY;XDF|Yڒ wD!ش]ڳBsi6pmsq?B.,^󘸘lJ40pUö/m?X{J2!**Ax5.13 ZNhҎz D'"i^,{GC0#ѮLJ%5Omu,FokE2вqOyb5>,9uހStbMW7p6# z"RəK{Q~a?9_Tcf"2JE5(Fo"_ӔVkN&R+ٮu`Wh#mIarmo,Kt@[Ng$k߆m}ONl9.YslK 0H_xcͼ g38-Jc\v?7%H;9k:D;7CzF!sKk0V<hB9c%ےE̍s슇ܧ&b]ڳٿ}ޖv}@X&ᘆ-}:Xp#o}o916o:Fk=?ͦ7]#Ȑn~wuINY2P;Su˼M}y/ ARz s㧝lE?X5 S;wԴpusՀٻ+-Wj&qJAE\% X¯X1A\'n紜8$]&XZ,`qyy8zAq4򶐁qpS9uS6mfpi/i]K1j\ac֋]Lo >Z-b_ ~Dj9rtyբvrX9Oaؗr܆ay Q֭mk1c^ϱ908nZC|ױ, B&^WZ,p.ֵ1}C Y7 {W1- KGkY<-5%Mt[rWQN>5vX׎f\|Gc _}NbXoq!"#ޘ=#Ý iKlDEb  TBNm"2naBb]~dw8)ʚolW" MVJ51yXZ[#0uvuƩ‰rB51۽> Ș;K&~5ڴ+Z޼s5$FpayI(ƥdL!G2, ɋ rP>'Wմ{F#*4$= X .\P7o\PZpxOb1x6 Ki4"#M4%hM,_5ǒ6"oi2:36Ds3 ܋X-nK$`Cd(jyՎ7IqlH`&8G4n )-_؍# mCF!)D~ۋO# F ,g; 3&icdS˭pP~+ƌv&kRo5V8`!m/G8k0mEhR5bcTBZ! Y[04riٹ=7!oxqHp@ ^sR6c@saPX8Yg0[/ixCZ}pFZc¹vsJÙRlu#8NxK iokogn~F1ܩGG^}ʡ߈)+2e|F;cq7ofMS iڭJ~LFtiĢɩzmXZZro9>ݲ kZ|.qG{޶+ZSpF5Yr]o\cVN5`nvIs-. )dqj(&`faq;ڹy> d9dn/}}kĪ{qjM_wLG൷%̿e9B8,-43Mp1z 3桝DU>xer~F`4v:9囃;07}.zzrKOq >bH̝eWq>z7?s콇x-n(q7C<3m[[sQ{A;Ze0̅Co EVq}N1gjg*z] *?c[X*JhRS,vun-xX[|{u˰gr@U9;hNRcܚYOC禧p~k)RDV;׀P[zJav)a8QncK P{@ܡ焹7&g$O]Kt ?+ x.y\\ed*_QS8] H. cҊL y5Ї+\c&R1m6\K(OU !DMWR2ܷulA+I )KuKA&M"Dgk Mpj3!DM Z2". JF]=_KDc5~#0/x& 2I&`.0LpRyO!D7h5PBLG CSd ]%4c afjst Rp =4\2 v3I7qyza_V=RDZ#0ш&x,%/Jk^jxhIۛ{ho@%yta11ft8KKmw$VYpҮ=#;$/ucCg[Ւ,gY 9JҘӑl_CBxw櫴JJiwwt 'Dp1<1Bz5=+6c_4+V@5lx;kzg%[ja@r}Jr_KLZt}&*tX}?B;ߑli Vr]>W` پPEt߭ifYb;wgDU7&ަ63"-yvAoLL͵`?`¿FI^۝wݸy6֫ve0i) ;osl=bMojyenq2Zxu1q{E$ߜemnE ׻v9:~2qJd} iZ:K+S.k69a~Y0% X&k h9Wq+ xiLG3[XR=cY9zǍrY4D-e4K[$ؙ) =E$(vfݶ.4ÖBn~R˷㼎$7`詍Ԉa~)C/>[u0#֏sr1C=7jZ1슰MCY1`;Xe}#Y!)qg 1l{Kxq' UTԵMLb"˪4 X[bp% Ӏ;U!Y ~x)B\=m Kgz3O纙LCk-x_ GjKYn/W&Ao E\d>uGD]ϢXNԭT[DIL<7, %g=ElXJĮ D1NlXum'" 8Hة'ưQ׋81:MC)ѐ DJ5ϒ9؈|z0)6m-km<ƾt*Yĸp K-Gmx/@Pi~cڄoE,gAّP7>7nFX%F*[ѐU72X[2|.Nd[,/Mú4jd{6,@1IQNsi[ݸ <p;QX:W7f z^& ҈4,^c ` #CX [@bKͬ{>zUb?SWd/#vxf F.k29|=n RBC?T7Okבb6 4KH|Cn@@0Ԛ'Mu[)k4[ZB&a Em!N\@5MrK ,F|n :jYq*|^ iN,tS%dLq Tñ7;-Ǻ b]k=[u1:-Ku97N-}_WZtq?RRgږͫ=<]ym8/iS al4&ߺ|/.&9xUr෮LþM}.7m.~FrC4-W_7ٮx yx.o.5SOrg6NEm.{gQy)sCŊ:_nܝv?Ǻ XXh`G%;]ꗮtCb+K{ȅkŚ!̠ܬ#*~AS]y 0)Ʃ 5MfW`9^پ`ss^*Gĝ#Z6}}}J. ߫չ^I»גixS`DlK_5s>:xZMV76(tO#;~Ӻ!5A:B#1" .iC`mr8=׮'dyH[i-̈́}8Ku懹oY8l׀~&:pg)=zyam %t -]+A%}E(y MK69du/0t[6B=uX BɿO@M%ÙJH([?ZP&X6>NJ./ -m^~]2H'MD׹ͨ[PJ{3؁Z͈gwV`&)QmV^@Y xY m|ef| ۥ[q] y pp" R.V~.P钒 kK}Fh~ICRj3|0]%#0~!`pJ Vo@Ԫg+'8@w+Iዘs1AQK\}覓1`.pnC{o 6Om_<OBf_Ij)`~~V`1 tY[vltc?me7 MYWRAlij/1 nUAĹ43$3zG5YrM<+̍ݣ'>-&18:x8eKj|Y(xXeH)m ѴS{X07- R{,&=Qzޮme経Y׾ۇ`d fK˼@L[S(E6 KJą".i Znc~Llm5´?h w]>.b#Ɗs)F[js"[Qbfu{$lH bfZ12N,;{*nN=sxSpù٢93W>)8۷Y?@Ƌvksz3d/*4A!RR{ut4(*OS pGC"LJu,%PyEAPƩT;~"ΊUcʅq4I|F"M.3xE-tpZ7rKYFq3 ws0dTXu@!F3=E[Lc09xe~.Fk!1.t/ښk#Q,# qT8R QMY#zNL<'fA_}/od6 R˝aN: S(b:|_7qLD~F836̊e>h3 [ /7q/-kn42ʽpķhf5 J[Ӄ9~¹ixIȬd@rRߴ;ӀLouKӺ&b{<]VoiGT mEZbܠX|ӂ-pZiIc&4C!ݍ<aNT?ޑpMŸ"IDn[r_8X8LpTߦi m7mP\Z=F p$S ;qkD@D}/3(ȍ/doSN 7>?߰P8~ XNFJ˰gmz$`Ke췘IӾ$>! [Ljc|_@J)MH!"._ix{Ex+P w"D: qʤu:`PRf'ϐiK@>n L[)%K'5M>:N^:y=[+)-61oYd. [rvcC.۲,ґiY"w N$T5$NukUfV{#MQĴU=5{%Rj=:tmaڒι휽g]}rͧ.^c}]yUi?ti.nYmU؎dHcF^IL$^s`8^tyFK@lіꤝܯ2s'-葤LۣѭboL[b}\-ёTMhRbjk6}ն')L۵2Q"½ȜKiZ'C@=49PDZ}YះOPkڰ{mIvy>e_fk58ʀxQ1Qunaf[#?Dܼ!z$_|"lN,6i[eֶc=zah9#]t5c_ԣ5@W"=%J֏qZHtܓ]gMYߢbŒeF4TbƁ5#1QΥM۱h.^-׬ӾIp ƜY::5ZՉ4ևKGZ\2C/I<>:o3o{X2QUj|$X;342@usLH6Iu01]:<"UW4 $>4̾23@}eUT'ڼ^׍w:XwF6%v" !f½铱d$=%1 CB)8IY[RDE$$0愉Ľ.X4J%{XrgD*eu'qKE/(n@ PyS/yydpdqzonA!+G =$RK;OW/}E{i\ۅJz&Ix"j$*nEcX$A$VJd*| {Ϻ>ՔzK'4U-EVr Z2.%L=?aUP/q 7~_6kYJ_.H Z )D%-XשgZn9ۧmR6=Iy ^Υj^ 6:mضk+P?)!>/}8 5q^N-qlٛtKJdlbΞڏN=plWɋn?szɭU:qѺs$ [ֺ0vd'r cGB=%WcFjF%}+sG,_3<ʄKmi^Y?"8+7nm[q.c]ہ` gխHtS%u?C{V cJzMΥ%س9eqiPGGvyᗵm dK]XvY.nK9nq.mY- y1si)?ϱ zKKb$-@7;\Zu.6SkT,qb^u-랎2-qVlΥXpϧ" /g*䜹ߣ~i5~.F%Ad:c}ڶ0I^pip;o%R9\g fIX|c؞N1bavͭBSڗ8̴ٱb4d;xbrN{RoY Ӭblc%;C 9eW΃znVࡒ!}K!AJl9۩_ #/:50ﱯAjD%r=Y2NbD| y {4G8H}7`Ιj;<䞊40f 3ItW^" 1XΓ%JUA/Pe1@+7>7k#QWF \ Dw)~c*s V.~a=X4 Xghǘ"JĄz:,k*aL_@ dYŷ>WO9Sl+J7 ,9ihZ8Y˿4 ApVDªXؗǦ6D} k/Hf^'7ߎTNZ23@Y\Ԧ#ipHGs#Mb7h! IIDo)X{B2dw"76uߴouc61S2Z/H(v}!F%bZP@CoB|!q/L}1s3b/G# #;}.e@MD؇M(Q Yx;6M@NHZF "&zh KT5-h|N/t=`F{X^ֺX^ֺ4Xkvk;l:hȐV %3NA6@m10/ "Z\4_~ߞ}lOi-MpٓC;'禽0R6녳6<itnTznk7k~溽i4_֥Vq?jIhbka ?x9̱*HmmO [bf0.Wi6'Xp^-3kMz4M|AI][%`N}Й?ӍjKNX@mwJ8s&%B,J%.-QmŁ.#\ڳ-!%(ӛVChFNBojI[i&mեx!o(MX7NR>:zi[j'T[u?Smd:-v&9߹*ѵZ\ (Tu97- Ֆ>+z 83gS<5n(\$mSmAT[uI&K(\-P]|%ukDPmQ|)t%508EJKEَsc|Zl;M OjйݩdGs[m}ů"u-/XR.ͩץ|΁#-^lA*T2ou*دcgyBHu]b&^Z@=QdgG'}Kإe$9vmls׽uM\zSIj1b׵5NLXKvhVʵ.ci=&=iR뺶cԛ.M?؟ws'#xyܞQjʄ{=F{l­mi\l>mVu=фG69(#|VZnD{U,|Jnu l _سfR$ո4Z3{9ELm>3;yP/2"]xPȭ%3?6|B,:0 g,INȏEHK%&bޯ$)@y% (K\z #r fIyB| {eߥg^:gxE͘3B/*TLbF2-ZBnW2zt?)YzV~I.F(٤O#bu΀k f DVɭKIWȥЪ]g"(J~f 4譸XHun-̈́y sɴpAs:Sb[ cL%-QǝK3T0Cz\3Vt;YϬ]+$:նRMO#.]]O#]gIV7soSme9%iGx)[t-dtSx햳!p!45Q8󖤘g&-Pm3ؤ|}It]aҗtQ`G'y )<Ǜ0ocaԽ3ocN꒎"N%kRGKuTzvS)JmH LrCN~cކ) !^f7<2{¼i]˺b7jZRHv -n-yS6$YRW{gWaepμ꺗aiFij_uc[ahb_6ZKG[Ɏ -iwv'Szg?'BoŶ;vj3yb?3AV cfpvtqt/c]tr]\LəG{@o z+.^N6x^sΩ q e.4:V ^ɣ,,NAX^3[1ǚq;70zw]lBޛu94Cs ^йjDB2b%m]t1)ʾYfX#G$‹sGt11qU}uŽipA=&к9qR=5-mޱ;pיL\ &.yڬn32VCyݢy`-[uJP/D^Y ^2ZB|7d ʡZDbPsᩄc&n,nFsL`Pu.kǝFwe.\av.-uA{(/֗M养L\K` \H3Swxuq5?| MCd.x T3A4[ Q+v.bIݮ7h!so]gm~MI*1|#xݴ٥>e/_ ǿ sq nP7#$d*g-ǹu`Y G`o_wIo\\K$u*}ī 53e-Smފ)گKr֜ESzamwZR %:;Xijm~\Ϟi_R:LWmBkrm`x oFm#|}Sq-16͵+JoK1يzFn-OAw~</I㊜M;N6iEv4+\\ΰոVun&niЅ@o!4" tXhOR 5 ކ'' ~lP@oCϯ%'jϫAdu=x o@M-{KNKT!{߾p[*nMY>>#~GVel[ Ormu{_cR˶\8G*ղfsrЦުbg<^uk!s=VRkuzp; NX|%K{^))`#<.#H\; z{ Vm z$$.{Y>S^K^CprB.5. 3K~֜S}ArJȫ~Łd9k6i+ĥ`ڣiQ;pԓ:ɣG@kA:'+$0 1 R@<[ 'ax?" i3 pnW6hn=[# #tÎsHJ%+-&`S9)3UEA`=D`Ut]}-630S\]>/qɽ^A@o{d#lf;ߥWduJg3 0F~GKXK}vw }^;zXdD rxt#BKk"6gSVIXp{R(`m^GJržJp+z sFk.z醋R9Z׋^2ޝE @d Rm@`n\KH\+l|;=I%/IPTAyk %(sD&~Ƽ  E]A`2LP}N4%8xVAb$R"Y -8}hgGI [FS] ޚYJY`p ۅw$u`Oa/CpϔKsn 1?tͨmC$.*`Sy^IyKo80`Ъg`#b$CAYeR2躔pϺ}%$]g@KR(8WBݪCoIe~14t :D`JG] ^ֿW8<)&GwĞA%oWٺQ.݊$.̲X;)=ryXsxS$Hܴoւ  7$.01Co=-ӑ4> LWn W$r5[HqK RE7[`u\yIx36I,|lLy<7$.%rHkr{rh}ʞ*iۉq\<,K=58׶M\x̣ qÞnHٕv#qUH^EFϽȒ.M5"5׽qQ|{ Gb8%""{$ZS_b) >{ W딑q8zk008HmcURcc~ nՙo,J9|yp#~ Ã)։Ym!w"ϥ9 w#^|wu)}B.yW0ms.cf< WH'gs'u^RxJBڮx鎝".as):YGh۾6DDa fRzq: e?Zs9y A]l;[%Vb:Ki,I$Cfg&Bnd")M2,ĕe]YO }R_`-C"bn B",ߥwzoDm Xz鹑bo#>lBE"n{"*7s,\DU83is?v  8gZ0׭p~O͸n,kDs5mPdt/y37mY6Cpq gƈ́R!) ZY'0pA#O7Rn$S,Fmb>kKڹ>^4Gb"Mi83Vm)D[>R)@˶^B!{l%s0oN4C/)bK57|]k ov#xзwۆ3)SS.),\BuXρ9Z;kþyKip. 7O mjxqm!z´%/2m%uú:FJj/)9L[;Ӗ୒;znぬ^^~9~Т ~\m L[3ؖy2m=d]hHDdKGH&L8o1a8CV*Z3|I,"N⯈bv$Weڎ?iycڮ7O8Ӗ1i ´ gl'ie &~b3 T"[b{]iF~aږE[o+ Lp&.-HQԥpjtk+akwv͵f^j&kx,t U^d:α?>{i;+J)MeɈ7 1m׽̲Lh\Z[zOxgrfqd獏m@Vi#dYv,qi]%~Ak2Ѭ=Se1.u0I҂7̅l6LvWWLSI{J1K ,{w׽0ys(u>煟շj _z<~Ő/׼׮ծdX~1]9kĻmm߆Aʥ]FK{˚Y XInGF86wmcv %m8eYe6 ~ϗ+Z/|.H !8:ֹZ->I˖!H[$ &Lp\a=u0 48휋[K1Cb1j;IdԵmyXe}$xp̵68jP?NǸ\CGYI(m#Y&Ā 6>R#[< - Y?AA2$ŎiHD Fd.aslmK%.6c8CZ:Q(Jq,S;iRܥPIsOElrqUG jږ}ǃ"<^ GY`˙4 >qBѫK!LrҶ 8AJ/ (^->"?!J8gƜH*=에\9.PTq'"aUP8|AIŘWUdcL :SDX1bkSJbϾ%*Ys x9 2ý '^uiB-Ri L\xf:ՖpR7h 4@dY @0B獑V"OPm]o9e=юW^o5ߋόTܨo7DV">c_𭯅1IɃ@JXQN}Yܵq‰sӁ X7m"QWd}AILAbY|V}Gɷs곭~Y)(&/kS%dz6ߞ1ߊqɅib-/?%/}lF垒hӞib-x\x\[α[h][ yYm x9|mPT0g;1M,<pAN`r: d@_~L@DܕPwfQ}$GKB qJ3cR S4tw!B˷cTN Yo- hGLku*;P poYky0RIJ[Kkuh8ǡͼrbO{톭%NiS2WYOk?ѻU!cޭgY1i}{d&oGֺW|Lj{l͙?S_[+mОsq%ǮwGݠ`kQ^ѭ3|.Elxyv[[w[6k][?3h`-^a8_g؝EWp"dkunl-L}`|pakCavq;^TL dܻWޮm  z]wFAd Ȁ큶kre.ϞHHSxUl-i=Z%A3p%K0B~_TrܰЪ<9J1DCֳ,0/s !n<ül.L2 C amMKlht=>X0>q@(E(WYe bz"vD0z!P ӄ\?kW"`ڵ]jvwzw;pU{ =3$fxL0FXLaA+d"H P*B,1rR#ŠZψ2Aq#E$R%xB}ps(&@1 / R"E-XhI0ݎ#)}g .t JcDX$%.D+/ ` W~[`Mi>B/JR.{"|6_>ho1}v\opYV!,#[$. vE8U:^p.{|K`K)l pAs>ψ}Е3v/tBp `.cRB>I z (JUJ/q#lU%(5|nw)g{ɨ*Gv4)#u^Li 3$OXG&u+IW@ K)KϺ: J~NDg]y" $d&5MJHgTzq.'r2A*X2%3|ԡW(oui%Y`/*ޤ/% ִ/&U{74πX݈V$~*~mw)*gF@XSH|-,GQ0SdB=$b\%_o$4'K AuTbݘѳ}:\}z_뭩ǹ ߼n1KޗҡzK\a+?Qe[kd:v+K{S}ޭeKxϻ'|7␷'.T`z|?_vzѬqGx_Ew{<β|9y[ƺo@7tNmv#(}n?ꗐ`<6?s7zH69UF߻]wYRUVIf am86Ιx_')>+Pzy @\[q>$9Nƒya5,Al\u{96ASs $Q"EF-x:kIc!%I=;+n럛`X4(s_JuHኼܑస}k9Gs[J 9VB\[PL۸TuƐc3ui@WcZm\="}E6-{]UU4 vޮgmtʴ`bR$dc­TZ;veJ%Ňc_c<`g϶G{wʕrXEl~mkqm5M ygI -xKP.vm9M2lp#c y'bLBSнpǍf&/x] 8b M D8XJ W( J!Uk  "뚗pa]:D)ӵ_W1#n"P]LU]D*&7ߎnZG"][^.`knkX8+,_gBTb Kd8K3./u ŞĴp!OWi+ͫ"2k700"DmV7 'Nu6mMs!fwAsq'BܮsNsg¹n8`qlTDgE 96 ECBB -c0v@R8x'D=>iaor%mjn٨DP :1(p0ڨD;&G񝵣> 18$oܪ. џVC,~1iV^33vedɅ6*M鏉<\H-:Z`!n@ R<7׾T50("swq Xoʾ΀$a}Nl0-4\)H(4pvU1ⱞ Qh-~;:Mos-_#曄 |t3oe#ViڐSӏ{CрJQd\s8_˞0mq;0miu-}IƝ)iKeO^FuL|Љ!WRž>ߠ)樌L+1 w"'{`r1o1rUl{yr8SoL?W0/\dӀn{9 r6ow'g)VW+V4^n^=s_ יg}uo *v^ImE&m[\ƬXm.j}ٶILiTڲ(ױoc^6[g̉\H=,Z8I|T0H5$U;L{hMдƹ/mZG ~Ս (V t::qvsſʛX]{G8MՖn)qmqc8avZɺj?Fq #Hv;UAS0.i pf{-On*]0X{)0<j !_! C3&Dhn68(: !?Jk:vP`u3r(3X5Df.6dB$ lDfJ5%'x@o-^ ԌO%Sb퀯sg)`]o%]7(%ݗ6Pt!RgW&)U,&!Q(\N MlŒuCxf0@@fBM"n~Fu~ yDhR[Еut%$I\9zzKSH\积%(A@Q 9O@'Uu0K. O"GY 璥U%w(O$m=!*|6(|?3n^q>R:INPm6G?=P)n$/ 1~* f J oqVtn5u)Iu_j'FB>mUxObE|:#=J\ 3>K/Jo.}:ZL=V]f*JZ/"%-4Uc)=/:zR``KXZ LKBioo>K Lu_6 VQ@0mRb.9uy. k,bzտv ,}@0c7\ >r ڥaZL]J_ABэPg߷ \Jrz)Yy=EPH:MϓG9=@J_{5tw򞭺i-ҽxuBMIB9bcIۼVt-u:|cb^ *?c :J)nWJN)ׄlu)p[Cmy; y ^% B(oXv!(]Z3F_&Bކw 8JAm{P{+0m&An2v ] .58×}tK-dc5rtqΈCREV oIpŦl{N'L[w#Fq$WKq9$htF۲y{N:Jf[/-kL酋gtr&= C{m==MV*.j,α:k)UGuVR#f;raXo0_y߮qіp񫃈+|vڰk#u65Bks9FoAѾjx,)@w~wvdn1k6A8 ۾g!lm'0Np;~/!uGsl9˞F2mתqgށRfcZ,DԄ_5iJռt˱]1ʼnǞǨza%f9rl]iR^̖BTqPXα,Hl$~V6 N?e@aiWiTA%ܬl_ĵ-}b' q0T8p$FLv9?gĶG(V͋]95!Nը"#qS]l:PRW\:T"l5+lm]֋umߊ%crm%.KxjH_L|Z%XmQۉ癯uKMr<}.ײsl3wϴ01ek*k!>&–4ĕ$tm94ǻ=PBmBVc],^`OFĥ…Kӕ B%`n>efo>wA!};i5eB͏\HBTO-z2Hx᧭k3?wi6\$xĕ5: {vvHڶ\#yv?ojژY "n}ߘ_CkvY1%0׎\ xl27E!P;[F\?Bĕ>WGD$ [A۶NPm) KMt=n"nK9>Fnaڞ|%{{FdXguq)jz} r"BOnFq:hBĵ2{tR>q!Gs[|yZq!lv~D#D\MvѣNĥT3Fi1 -l;=QTGB|D4P"D xt2sxt"}TISIL]kg3ـ#GT=b9X %LDMgv]wiI(tՉo) x,8ե6!6R|u` K#%w%^`uKY2X{k3A VX׾"3Oȏv>`t'pId#UDB"#uQ Y"M!MK~\tISȴPdڗ'r۠.&Bd#"GuGN璟4˞@}*M@] =z4^.Uofu7k$LNA*SHToTm~Y2YDu#?@iF#VȴέVEqgB,H"%h+9]c R1J%}-'Z|F#Bfmۥ>l9N}Ğ]x^5PJ ~3Kv#x,^/1~D!O3ހ祾A*@^*Ɨ %LsAp IWD||4b%ܥ>lj"=}m |`9}QD&o_C3KM׋R*>~M#>~ez#x/4Fˍ_y]t;/W%v߳}a uT۲7oS(YxDz*u˕Cxq vxa`y F}F`.t:E%dvXƍKRp]nu6Jڧ%c=Cki,#\^.K>ޞ,ߍvJS9tg.9zL`t3te{ 550&ꓨ8}Bhov+a/8]|G^.U WAa \NW[pBoȍUNn-kmzQ,X_z[Mb5̈dkM^J(c=-?!Wd 麖61%.ݘbZHbZz'śQ>a\Zm8#EbԼ_vl{yPK_SsGr y h^[SC<[MH~]c3Wn:NSkq(GY".(k6.^w XԮ3^WuY4CMl6LB3GK{0)1=xo˵;pU!R} h\J>w^c͸} jur7g/.=msgPmt]2 n9u\EꮻjU 0mLo(?֙!E9 5[۾!u7BV'VJK0i] `YRp !-2fh6|I{Ѳc>j`]c'ն\5u˱G^C;.׃wvl; \;^]̶#[u풚2;}iGA] L׃ Vx]Zw4c Еd?s Y}!@pK9 x\. $tV[hec*큧(լacҸQ252{0ݮ{!F X XE7!7T/\J#AB R @qC\3.Wv-^OA*p0]nSZ%DPۯp|#` ӋҎ'_^,sކķzzɰP6 +%y?Hܥ}{՞f*m%@O(RyBj~wiD1;],Rg* &ȫAxQ vEgz^B" 0 x`.9> [8UZF)̣g3B>p/_ZE8dG8:>f,9"^|F1zae 2Kd# =IZzɲk4J'H3%: 7J6{)Ng~ZͨfvSshZ?R=a H/*:HrїS[_w6^ZT~Y-g'imVs)|w]?KOX)9zIX Co]w ol(ּ] E zuKv muo?%NKIRO _{ 㻮g\SPPm,yǮ΢[oɮv+z:8v0ȑt?~9"M284vDq j{.Tӝءw-[ř%}I!ͳhvLl̽D7[D׺⡪.@P-a_mmeݞGL1^v2*]s[J#:k wTkɸh0EѾrj*PH>䩓=j &H\[ۧ >-O1_4FxluyGz;8,L{P~%jJ /KQ SLnH_H jjV (`&]>q+Զ 1Fnj#-J#E#kjK(KPcB~ڊ@걡4D!tFZP[vY WZퟆŵ혲J̘y@+b ԖxWuq%C.ݢbS=wK?R %`3Dlooay$>o9(<= Rs)Rr[9FBK>XFJ: NCxo6hVFpH#;Ne[c,܃WmM697sY[x-!ly In,M΄2Xf< q iG S.pZbLUt0 wsHTm#2I(Ւ8G$!3S#& Tu2"śMxRX8<B#Aq%Rb }Ub 1_X8-T8ioŵ)]¡_Ja7.m kv<+u*P$ دBE4쳶71)InUN"A0@>.J-&oոȱ]߷B@]=V&E/ +Bs˃x'V (nqe.o5#o)ŀ@F @Y, pV|m9QQLH)n{[\lYRin> -bjHM#mN+O۱tm8y%Zi"&l%-$psȞ}PNŦ%HX8T#Nul--xH#F]m`LG {% [9ҥSiE^C:hL4F}?[ n8SeքNOP8i=0IuӚ*hrܨhHS&ba?21)bgSDsx4AbqM8} }7f}\SbkULoM#Z^8NSi/݂y\rELH~|IF[DluX(~&' znB#_ih/bI@M1Hv-~$^@ ݖm|/j ح4nRIOkq]%E(e4$T?:FlYlI.o'l# Yr.(clx3l5+6v"/KsCWJM>-}[puw Ț,+F,"5eݗ9~g)g:Ror/Kt qto9%KJMit&$ >vd>-IwpR|KmoT$''6³Ml+3 [sDV|V88Dk:w l?{^) ϭ#1)}؄YR(Ô\Hzό.vxj=K?8}v5|&l@?1dk>8vy,GIJe#kJƕAJ̥%>,p d$z gBgj>IUpސ K}/ g7f},TXU & Sbb25J~$\G)T]HRx}"r o3[%*(c@4dnL.Q]^-ƩkzoHrL r>뺔Ɨ(rϷra>ىGVbB|rf >Vr}v$ƗlY (n3{}&>1Oic](WI0$}iUfD$⭔LWᴒnoM&mT)}UdRi~V&/dn|^%/5J?(h^f#^zKȇ%ۤVbA*+y-u&LJI Aoӊ4UbB9GD xF6pZD g)f.H^ȊGb-fy»:z ˼AUջut;-^ v5]:xm`Ge-L#UAg5G}#kO[1T H~c[ y}n9C 1p84YjӴP [[a5#o\ 8XS)%xkp^~TBDX2.L[6Wp![ۚ²'۳y۶0)G;#TDHݎ=]e*󾍀%:6kPJn=bֵL͵!o[R-#Dl,z3 q-vϟilSl WYRsm`;pKMlנk[&3d,m֗n6,Z;*WvZt+K+h -Xafu!T<EVחK\CV _ ak X>$>}#%7&=!)Wυ튑/bT e~ ] @ub0q7aP[^zHD3`Q!Ďrm,…I1*Dk?g:a*6*zToN"E0D Ux+bc(&\-a`pFef/ csD9,F(M"ĐB$/HI!R:NԔeycF$&cHqrjhZwqx]L;ׇuwR[b >^w #;'L"^Bh) =G ZjB"Pٿi)Ă9zn9#wDhH&,5 f(n@ I4 "6M"jcԵnFHҋ61o9n5~/;jSV#$8RCI/{{#Ǻq{f6>4SGͱk)N8'ynobnTIw`%8()nEjtǹ)Vkm8iڛ8_no-[,qK( I/)g^8u j1pc =ѦIb)\J|t|0Ti9ƴpxs b\!1C 12M)^Q/ڷbz&90d8CI,9u*7hļ9 DDRue-ݿU C昷){ynz,Gz hH}Lb}I%EstmQ1Y*Qn5\[ 5? rp-,;G(N=%`QTZ@LΥnD1F ?(X o5b-pm,ƽtЯ?7|q@BZ 栅ԽKmJsr>Ju SdI{oTt͝Y[*LIsIl2V0,'P#sQ e[2ύK{Ϳ%zb؞f̑˹#Ӧ;0y.vCN˕kvnZkg+Oܚ/Xڒ 8~.9A AV.zkb f-VXN{<]Ҋ .yO|K14i,Nu. $W@v!zsV=4}k=ۛA0SJr)E|ںN$sZfjy'DrrLݔF{ڲ7502k\\ O crp!utS~Ub>cH* ll"Yqi`;z ޭzݟ5UxMŎ5W~ږTU’u~ ۯD!$;lM6%Zb[gBxNۅ8_gkVW\>ܸvCTkk0Ev*]nmkn]= E%3OcA*?.ha""KQSD==rt鹥e^v$,y=P#ꔶBۅtTZ-Xh$ݶvzym ]B]jSQBc4RsΚBvv3-zuѥ]Gcwc <];x¨v| {k)0F{-y#^RQ(=ZشN4g2BlH<[L".Q`G<0 !_YbFL>`!Mu\2De.+_y&o)Br Nes>LD~F6sBcސQ)k5Yv}%c_]}Oh"%p"P3!ɵW$E-($ D6}&V^>Rɾƺmƕ?L\bz@[E)QQ z> ;Zd4#Qե$W* KB]9o<Ӎ/^2H/B }$"yKRa[F$QQ\THtV̭zb %ndGY%{odub0 Bu]U] <0ɕtY$s,ʥ@''[pf[BO4Bf.3tVH d7'ް'#EWQxJL]m82 m&¨u}{˴|Hh˕+^p1JD6-3'd9X21S@ItRip@]k:) K>?rOaO!( V F{hu QɝER`S-.EN3J}] 'FTUE*B $Wҍ=ГD,gT2zꐉcRX;>/IX|K"m=Io]P U[%KH̅Jtb/NLVL&oyB']zGR/EzaU!oŒ[ %Mv&.ܨUyڝNE/Vٺlx m7p.7*ue$Կ<״}]);1J[s=c֪m;efplRʖk{Y;L/e_Y٭߻4ϥ=- j:D}.rcO~Rc* ǾQuCN^W&ߏ]%|V[e>k]M(21 _%guuZ :gHnW+xt^3=tGn^e \yU Ol?9C;e3uB7m{t+fMtqui:Kl&[ݯq?$+9E\l[|%+$ͥcPiK)u]]HiP}i^{@8}t~uWwFt~|8vO7ve/?r<=.(v_h[=SX1o; g amZ#pro!qdL *@ϋZ 9_%NoG!=_轮Nמ,o@ !*ǣlcY%RE&ط4FNN9exݶ Q(Ck&2KtJNؖ!BmF~rs*%Q9zNَ55FCrm?Kl5o=ڥj٧ڊ ! ->xcˁjR1v͵/;>2-ܶ=Di1du!^2$eؠ@)CLnJv̝hh>ײ#cgAb l4>[dvkbhv_%fui9P 2N}@m9o5f 𣵈 @cmٻfH5d7]09Y"͸ Fl!)k^ƆsȐ';v]+$’3#WN(q|8q),U<։o0^',po9kص2M# A0^.h3NnnȰ2)Җ8]/W[މv-6E#1ͽ kȯ$V14t 1 #puDhy l-Htڮ /}]ˮbة!!a0~S>#2;/WTrskivmD8F12@cF|!  e G*kH7m{7;XrB^~ g}AFj׉cl9-a"SݴI*^6ҕa b6ER:}";/L_}F*WB*p-P"~d5 UDSBt'!aF1"/]J6ĴluGFskA;)H[ODL_\l旖#UDEL8`eߴ"#'VB VN\ce_8CQ0}DVT"_(d$22h'^.Qcj< 'bJ%c`LO?3fxSbN/p~=]_n8sk(\gp|> hry]*NER6Cly7w|I0xl7[^dLY)Uuy_SE;*x-T[=Gx(76fm`!Ӑd۶4grԒ1]pTd.׵0s+(qh tGkKkEmk|HkK\8]y"ĽYr4'\z>o8]0β/rUuVm}[/㭈cgo* P ֊_vmYRq5zx?.}xA{%..1]>J ƣozVht@?Yʧ߇[}{K1jwZہ4CH ϶1Cv!@uٚwxDZw.;)N7@_O^[fK^=k,!F^jlIc،%G`_K Aq=`c+ױސ#+{-PDy 尭8!FǺh ^>;G"K:oy++IMIVztک`G*ܥP؍+VJ~N)R+ z$Fwqg8Ãd#Œ3 <4ю s&B]&8\{[A)m[(KFC.x]zv9N>aE2N`vni!8.`Еe Yphw,' @CEB!zP"3q`+08>v>tJq\3t`#H>QEu!x^쯺iot)>s)"DO<3W&=H%[E(}qJ&]+{p$4SL @d@Ssg<4֫ p%d az,,Wog+҈ZF%D;JamTt x-g]aati.O}ݮd#0*}FG0#VTX]IZ5I0C'LhZ9{?g\ vEH\.aOd[qX`|yѴ} L9Xl* dK&'UL@c_.[-i=֭᳏ }k3@`'MR8ɠT=vi~7>M! Rna"/sza_X[;/msZSXmWmq=lڧD* wnM %ׯã2j!!I\ڝnܭ#FW [1-'/яS^%ɒs}A~-|H7›}IG9/J^%q[='z%w_~8ɴi9/cTәK kc~BKSt~P6ysOuzmVѴkN Z%&8^FF񋶊<_R:jLP2B("3ToFSZv/bƒh8 ":>^,a}CsPK}6&/^8SL{Dx@ h-4zሆr 6 GL 9DXаLs#Tc"GԶ w,-K Hz+Ӑx˿.ie ZѰj1Y Y$t!ma >CkNZ3~چW347MdkHe+A],[6Ť#ڌHNȭXb/DMfu9HZ8DfՁ@YBg< XvBEl/T@Jh3X`PF-fnAw*4gdiMsH?%FD.h9Yz [ H#!7󈽈ZD56ӃPLߴeAUHBo}~ S&j2o4GbPb$DFU, `8C*y"Qy,:T(>KIVZLhs 3U/(ּm,4$ *Ǜ-4$4 {M Y"=AvC'(fD*ᶝJ)JD`q z݈H1Ww vg[{5hȀgeS_>QMS:ZN@]|n:B9o\`usauqbL[)9_雤s_-*[|,=VIxֲ$CM!u|yٗʫa#Xz-4/VTGlw۞S9ݻ%~M[iy<Ϫ!+si6bעoN 'B I|y[Ӈo:|QqeޟW~<-\[![%WEOZ;`BEe8`oy}"R"VT"8QQ]G$u*6yɽduKID4S^* ,ZEO>q|r2,EW>";ms}+}Dm l9´q޷^@RHNVKR Vo5 ht(xFT2¥K'zFT0F1].,]R[a \zR/_.S 5 pZ9i.*pXҩ{Ñ`Wb[2 yE@$}NAoh@ONK[%ķxk ~<# `D0bP{ɀU d@ؽYFI8Z-61Ƌ,yw EKр4aMwgXVNnt+'4$%4IZm&!uyɰ\*Ed8Fi. +#n0F] Wak}%W\v,uq:<{[q,%xxRdl '”^Mda0*n`nӱdLދ6)"19Zʏ%(( KqG;8qaw)ǥd9fA]/ Z+hyz = 0m|Ē?J M[W ސdP4, >H)&Q֏'܎siu|?("sۓ|k~ٹ`8?ԿZ')5I8d]hz}_av^ Z_lzr]ukF]R<"~Yo֥N*qdV_˵.ÎH֔{”bORܒMlG/I\^}l =J2eH-\8?>}]!) Kޫٶqxo!IJ 7tCdGZ׶$un F~sP7'rI2j={Y)!I'p]G?@%w JuU6dks !x6 Vw|q+DZỉ Vl-bwQ}[X\9Zl]5Msfc2:5 U\X]uo|5ٶ_0ByLV?7_r#(nDz9emy,DO[aئXP )]Qp))R+L"0v=xW Űu Um[FGoIz=fA$?X i?+:C^?a0kی9o!$[(ر۽iח ftXMG%(㈉MwX* Ժ"҈0$vN9ZNV*q]ˈ­;xBWգ>҆Dh "oT){2Eˀ{νcsxnPe{oSKȝ+w`DQ߬ J@Msm䐓yJ wmxyHݐ~Ͻn*S|+<Rvͯ@u)BX `=7WЭe!nan4#"&cQ(| |/¥nԗd-p|)/|)N9-H%M3l(vm!Ϻ)R [H6ꭦ۠ۃ!! *>MÌV(wt>|wdaMQꦻ |,$s;h +:XӻHyqbzH`tQL@^Owq)/4N$U,(a0dMXIkJw)hYY(R>«?.i>I{JsѧǺ͇˵-ٞ_ϗ4djô5ۮ),.Y!ÖlK-r\ܑIYu/1Scm=1i 6Sk@m%:Dnoh=c!:ݜgKaG-9MR;Y~"[iy]Z<>8yتbO./ߺؚ:~mR'7d6zV^i:5/ssФw=vt@wQ\ۯ%N">ܾ2.(8%xM+XJ^uxrӎL*AȳYK06 LK.O%iC0Oͧ}c}oG=k ~O=3[нi*4kKǸ䪛vNNGh>y'TTw[Eӵ͎љ_m]kKhVm9'-CH:f%8 ҭTwS`BMv#L\Mb*$ȳf["cشEy[ҵvjeGul fĽK ¥hW({\)]ZRΖ& ʥ5~6t} ݢD]VW;֣͟E^6Fo׵n!BY^rُ-uziץѮz,rm V]י@pm[Р4N/}1~.=ؓڣaiu=ΖN=F,6#o݌ci}mO- nWvVG.$ڙHGMMEr~G#3B"#Bp&RD;AHaBW(Eg]"qWDChH !K7 -Z Q\ tvrY>aDq)>Kd羪;ElCB\-j3w+KA7&Rg/>@"/Yݷ# 47b.PI+J7PIO$c%lR+; | jX'h$64Аu:_ZkЮ 8"ÝLHRq}/>%ȚJT^2ZKMd V3چ VGODDcZ,/g fNC2r6 >dn]8OX2JK4gVr, YL4үXU_ DV̕vvǡ32m L[0ПvMb!:rQKR^NUCjm' "sJv)31OI-hxz>߬ɤlYbS"B+BI zRz>i)KڏvistB/Y\IӤV=3R\] P᥂dRaƝX2v.D 4Uzo{T=CQ {髏XN",^W'W,Gh-Rx#GRy)Sx{Rx&oMm-W MS> Du۠}D fy R!goVzJx]9Au⭿w8dT龍TDY\J<*Y{GAt0u$.0mAw+&B[zB{AP'*W4f9]'ƛ~ݮ$$ؤ>^zgǵٔ6 is: ҳBOK$޺_n7#8&;?ϝ!ퟞXR{=O|DS wgi.TOkw?QXufT;  JCg"D ܼz#'?<*SVC:RܽdQۙO79KōNw_SdvIKz#$ٚ H[\VJn`8uwOi P- {7 0F+ֆEtY.@ ;E4RozN-gjEx|>J'B! $ [o"Q95t u:GCi}F+G#EHU-IVf LbsAZvagkKc'm.>K^ϏW6EHMk#Khz TK# ׶ob#CFT-iKʬHG[qZ coQeۇ…5 PZaK u޾ٖ3> uֵtʢ-{9o UmfTrFqsAքq3350_/.> MamCYG?[BЏ0$~Tp! <Ͱ- ‰*M*N7MT姞 k*Cľbed#V 'jT7MAʢI(_17 .%P/ p3Y(!"+4i&& .W Kia' ׅ ȯ7Bb$.bo"Ô#tR3(/7P [s&-]4|F? И\;FSM];ҹkn.)fh-o V&9RF1FDC$߄=溝vHr1AԛwmκT?#64IJwmׅ#DG!BWĆB1_mM gW[ H%/K8izQA*uӒ'9)'-tME1j1=7.\*T[ָn1.#X##imE|[ kiE #6*fR<=4]r1&y !TDd-H3u1XLp٣PT^8jǖkpBm|CF7h$a)16msotRqȬ?66VީSu~KQiWdkh-L`InZ8͒-]G&^7PKz21Y>U-UW`Z7;v^Ãq 6*/S¹6\#bi9{V-'?ϟ Y>P0ǴnצI4^B4;0z} NUg`ʽ&75|o<*Nwro˵ҋ9hX,<>L"q 5U# K< TMBGN_#ZjVnW1bN7:$p(rMg.@iΊl|(k NlP\<.GKt0}zKMNb钵,fX8%[F"YӶM[jDri,%<%=9KI"uy4`8Ly'Y98C!S ^o^ӛvp8=6~-ck-f]m[vjg®vǑǃǯӅ0!BU7{xsrGjZ\[NCo>p5f#b V_>. 1ƈFچpꞿ/XX Cxl1rv$,'z#٣.<@b愳=:lJv39DdtgؕP]d&uس4t9RJ{OBʠIKDI7%)+|Jb RJvF,p^t/l%&(p"q%RX )ەzo;MduD]&PJLu8t!&.|EGK#Q VK+ˉbWkD.홤ɗkEv 瀒LHHf'YbBUVњCRHPf.v]Zs!ԥC)yWoۢfq"cXaNe$!BzoD]wgDDiu(+0*%R':X˜3ER8. rHᦒGg۳zP@>}gJF_͈A\?f؟H*.I @ĕȭEb@"[ IJۭN@u%Ν c[)Mu{ǾRRZ6 ӥP mӽAO.QJcDWC7odrkS=w7ۗGoUk9Ʒ[m|DzcK{j]R_ԿB4v2V&=nfw{To>gl9h7Vi3W T pWGၐ7oYH B,-eZ&pg"H4$ȴ+X6a DBm ʬ_s`bǮ;!FLu,-!P$VmG}NMs8i3N,P_bՆ`ψs_q+^7nTYNNDg& ?Lx_Ĉ_~aD3)P0712`XZGR{_i IۛCqD*.Fsqz -UiKȐߚmq (a\I3;1 SHH[ Ob(43ә5W s"$z_ $v/I- BjhS 2HH9?2]E,1 3o&֯ TDfx&Qnn9<SRL;#/a2Es^8Q-yBgF0ⶁ{+qĀR|J6Q,\i Pd.Mu+/84^aH^;MO4/;$y)1L;;~%rsG1s, YdX14B72H\(Ap0gҦWѰhk_ŐQ܎s#A&ABQr?~I ^,h/2PŐqmRpFLѯgEm{1!Νy¼H\2dlH+v.-d[O\L4簞wzK{Cf]5H\,ܿsbRS|ޗ UqY>pZKXS=y\Y?./\>T~YC0a޺[vb;PfdARmqh?';+q#|ubPݒۘOq]!⢏wOSmq ,Mf<-]\Һ8掷EgH2&qolװa 7rM>{C Sc*w{ąc"qH\8VHf^@9L$o?xΉֵTQ);zWo@͐U~cL[(Nv^[ ֎i6oH\ζlkwdK4yn)ۑha_oٔKR T|: `ۼ^Ԥa`u,ڤa3 xYB 0w)e.G =.{m_Knuy OH\-pQK=;<ۃy8ՎdsK! lZ0OE$nf–' [b#f۟jp=ݎc(v}[CV p;P(F kDzE\n.6d]^ۨPb:Amj%r,c}uy[_90BKAJL9nCf&ǀƹs` )֟׺Mװ*Nw J1X[#{]c1 ֥n`fY)Y07J PDB\ N#5ArdO@/Y Bg 0s)  Ъ炂>dNAjuiD /K@UB p~mWck K(Y&`}WQn9.,m,Ѯh| ەfta?BP`| +nf:@%%AoU>Ft]ZZW'7A~}~BvW mF![hLI麎#WR 0"_X\tK-Y`qBt' ,PT/uzVF![ŨVWg+z'JKW|Wt 0Vд2=$B?8T2dͮ H*[p_U*u`K;Jv!b|6nbϸdPK! ERG9Prӄd38nW~Anr9W R4ڳH`:{T($](u]LVcވx֞%C}sQh_/tI6 \+ҍTB݇pU(ȯ4_:g_]jY0/$]>#rMwnޓx6 #yGSѧzr pAkCӮARA-2}E"؆^Fg_E&@]uG uˁ'bXo_K<גW$#ۣN>^I$nw^#K}!]+i-ɹvlv}E|Sdnk+scȟhW1qm-T2dz,;C4C:Ks%b2~6q#F]ۀmD?9,g[öF*v".]i,w%&^!"Yy[<@&[F~,W"nX~}AĿ&Ky Oq|Jp -D\ZvzJG;e(v\^w".DGֈ:&hmⲅ`uZޒg@e# Y & X°l*3Cu%1궆Wp&d5ZTzeD*Hj^l79M-yoJpᆩ&{cmgX34PnDܜK3]>bmz 'mI]l5FvP?HHz8G^kB%X^.F{H[t9i@Bp pmj9rfE y%z +U 71L[eb$F`.8CnGfX/4My-CB"~iZ ߴFu#( 2.{!=?uPi_ [Xܛ}8$ϝhҖaI1Zx J ӄ~k_]"m]LXJ*\ŏK,؈nRH!~3D[Xىa hz'DĴ%1*u$YܵW֮ۛL .b0;M +2]L12b0f&J doWφn~7M&d]X7BMsmD$F2j #S$5"q9 yO!y/#Vb4&j9M%4p 6-0f/rC65 [h~~ s,!" e'"nc"}ЬMlcϖ<$e HkyiȥkO~+^$Qb &:s`h5&m#A,0HVUZ2՜{)cBX{a7E 2* |1_yb2S2Bh+7m z G2, RQ2W2ޢMDĬ&N[|0D" ǦO*-b)_sݠ3G~%>#oL_-Ni <]C~K7F1  s}R} 緋hup0򝈋|Bąi]y I[Z"̱m)f;q%( Z㜈9DG浺O4M_U^g.5?%[<=B!W$ C} kCkF%nfVÇ}w43ssUxV18rU@uK-7YJgۥ''F"nc&m[*\Plا7Iv9>v o 1IhD\j;N%;Jy{o8ɞ|u".^GXlam]gw"ۺ2`Kx3b[ְxx;3S%#lvѳ,2nLlIc͏ v"Rlj(e*&"|=g-:AKu׏H*b'Rݟi`obe ׃z`4[+uYƄb-9|Ӗ}|kuBNv&EGT_e-;cj:b=WFC7yO9 +`蒷k#P\jȦW/ 12Fsslcnݲ ]t{li8M<0*(7SWw1Vcyҵ/t'CR?jqtW;Tu/`XꎑKtoLW3Cr{w ke86bz]I¼[NKyBĕX<8>UH I)V} K~ -zjInc=Bߎy *sϭ=S@=E.F.A*$@(YkNu)p啈mN.%]g`P^UAC]V֍yRZD2E \bgb*𐉶꺽d (Y.qJMo!y:Wv+i3P@yI}r  A42t?,e=DP  Y!SD)FD.ei'VAVLMb 'u#T[b.IjK\S/1/Jl $O.KN N:{όP PRa WKKܙ{5i+EDHFm#iAW]ȮDF DN)HCҥRS167 $$Dآ-'H`9"2 5 %=(@%]gAmoG*r' HdK/IjF<!HH$U"$u!LZ/h#O*ROzoHGG,IE}H c$%W.u?IKuM Xuu}XDv+*٥" }#zto~vr|/ G& 3}v)೴M~2w]:̿ Ug8(uqp xלTRg^:~vn@+RI ߣ>ܸk}XhɈt[il?]c=(aK+|-yߎտ:/7<HlkOμĺ{RVkN>vv a>lt)؆;%YZ}8{Vxt}, Đ+YxlSsN?_;r_;].cbˊHל'cyu^zF/y?NoU{u ~Pym_=dv"nXo]_ڂ߻mKJpLb6AGF65,ex°\܈?^# oX ڱ](Ľnvۺ+[K"ob_>[)|>{FvIF[se2pe[3m%RbJD\OBĥXe!b) o% 6|TK"o%K%f '!܎ 0jU8o<鹅qJrqbHISyVz~ Zk '67-Q[NӀĺ`?[0 w:3X}'Z{A.a9.ڊ@%i#-(V[',' UKźE 1_H PD)7K8%m! {ܢGN%{݂QHgp?v,_F*\Ycp#Vg ]|&-nڨk  αeoIQP(~ĕE'.D)K%%T83N>ڄ_~h*3&ny#oH!x=4nu9>P6 nk ɰxi!a l>$1O_o;_gHIUįwsd !H1=QJJ/*1)Yշd$~|UݩXx%7ޚo4mKa=wqi>.3X?-^bUò꯸1eqk#vW0ni9:y%y<s'Te`gpt Z+ޭD;Y[i/4=Numn7{;#t̳ &v.J<ʓb1(r,sy*іBf$8][ҘW֮jmָ1|ϩFz'}/EZO}5ztÐ"I2魢fHhim m@XoIy:viYD<0dS~[J] U9Pr9"R8_B,OKadi? Xɜ(B'sA}:}BdayAB} Yr_Y7" W9ޣOlH(g#.wTV&C/q ,Jeѥn.7Zra8MW$Ս *ڌq^eGrxvb3qI6aRl k!Š$_*ˠom.ڤ~㋧ms͆y]wMqw/ȉt\t_N+zz#X6=/ٴ7Ymͮw\r·nϩYr7k/ͮp~$Kk)`l+u!{7qbkpкUF@<%,"wF"M۶>z'K42s(Hh[1qK$Y R?#;0t"0!9 8VPȇ1"*Tttd\roи$,yGLY\ZVvsBbyl1܋UNw1Ƀ}mAmA s1LŠ--_b{ :Ѧ^=TmZ+&Z8 ;l{=9\[KጼFlo\РgaKѲDž;v wFp_״Q!^@~JҀv&\Si&h5R_ G!`o րi=u{Z^ΒFpDgw*ҥp"R 5Vso&!• \isO^e_Ēف MM \J܎sWV3M]iapN"Sq>+{h\wo׍ژE ^6dA w3 Z$͒8nbhs:>^ p\\,{Γ!?g蛸_w7n)"͐h-H!mn@uӀxfƬWk b-p{GcBX7iEkav;k`l& YlE{Huc^ 3Yxƥ% Ƅbt#["_#UhXiᒺ="%!xYSE ڷV} \9KhwM"&;)8UmHC"S)eխgmɦѷ.^,Ы^M y4"S(L{4$3Z}Muá:9""EdjdkM[9ғ΅KOLaH\'6x,\45'%'-c̖É?=B?eJn`q*J^1!H\r(y=OC_[<<1!Rő皎u}(Q|ɓ A[6F:hgH=|^"Uj1~,c EN?ܖ1VY6^<ďkYr\0]=Ж65&OaaFyK`a)٥P׳"Epg8ChT\)+k|}DՍ3r:H!Y5 XYqxZpt8έ%'?Һ L.D]xb} gtf)h^sG-(`1 [Sɚ ىNk;G,١<~!eՑc.9xHkWtwmm953a:ֶβn͢Orzi $@b,B*"_TlXaHzcD3rHץ@xFg)񮉨I I5QzҥC+!P׾aHN]Zc$ 1i}V _v>H* ɮKR@:53q b#RnW@> )c|cN 5b9'T.%B;QU R?}KGZcx0DTZ0ɜiZI@\V"%nEHm&j"΄$%#9T(U"TIDR>5[d-/,;Dh`",7Jd*{:%ډ?IAzz ~[D&;Xnp_@]N8`W(!,G`Љ bDHNC:FKtGʽI|7tJ~vE~+v%X-YS e|7BN%j{$}qK_d8r&<3Ah_s>mUR=.5=S%I樂6w(n)9',,V qHWHuK]؏H׭h V:1(*UХݪK qdXdx^zIGP)v~VARkB.e,|1z ,un ZdϺBRv)/iU%"A\~z%B-۞ jVGGq? >ʖ,N3HB:WZ/9QzzFڎELiƵߧ: nݷ/ '"5_#x'%bҌܞԳ+Uv+:7~k۷K){9lCPrZ}Wl)NQ]-KNBEv@bW]saf9K ]:7XOK\܊q9xWi[XڹgT Ǿ"n:t;]!9܈ѻqz$sahnƽ,vepQD4Maoqxq~8bJHuD\^v_nnwm&R$q)d6Ag,BčA!uz3(Vu, mKw{9jmfS~َ6х2:ߐicȀxPOf5W\;/`v1UAE=m yvY](z03]Ǻ^sc0 )+I}+k{4e`52|Rx~^O\CRxc ҦMCnZ<9&skYmb[nҦmw"{$bgJKvmhx|nr1ud޳lK;{iĘ&h;BM"_5;Va/=(EBz)0V `gwn# :ȴ*"yP ЉAHXC쬋E@$0EB#:5![ZD" #Vrj᝿4?8)d oumXu2*`2N!6]qH@[Fs_o5iSCf1 PB 4&&;K 曵[|-\S\#9|6'k˃ 4Ĵ>'qiQA2peA#F"m)-!M [ͳn_Mc&bbGMۇķطqH"[nY_nA.]EZ'Ȉ3Lg.b2߄1{y2QJIEE%hHvN|a •%h_bb?"yxCK%E!v,&*-Ab;z` Z~FZ*nEQL^8nbhh ~`1.{zbzs s CZK,F2A^ myng(:&(`7&St1-[&b,Pz0E7 3! SF 6q@q#Щs# ސyU4^zS]l :o羵5buy+7 .ƭ[.TYRјihkbR8i1уVRVsyMe,Ulꖕ1e{7?X5zYr[ܐ v>ya@Sà>7kN"7E0@ քqJ,]jF*4p5*|"~)['gDmӖºeW&IHϭYe|xtKSDWiAё^s%c_Z^VTΛ8D|z_veC*lԽk ؘj 0s>IS[pHܵ.ңl/\0Dz;qJ ̅ z~v.!*bme]3-Mo:ׁ̳.ٹBnb`nn-a #=\6rX/x]%@${ u쑚`.6%ȥw nt \ץq?UWR=m "j^8WB\Ɠ4M4I*@!hP\ M=p\!s/WHó.M[LG$Cy V^@J!`#.sl=QFP C1H޹|rߒO1wCo!q{VzRąn`pJXUz8KCx0sEڡċ aKhrKE$$>C@- ( 00T\'p ;Ut]@ 8 E `IA[>*H:p[$"` J9S0d>F1A (O 3Xr&(@Jd|a.P??ۤVr\2l*>C3X*4@+R$zX;Pk+k, PvGv&AdG^'ZQ+»;֖%pG帴yPx&|2_ڏ%Х" {TK'~VAxH:Og(*M -R@x@Q { /X=rC*J'eX2@Qt$a@^\T2I]pzhGK 6mF`_"@>^#Z7HWF_.`@T P[( W7p5%(*$^Ҥ/|yý c)`^JRg)KeR:8Ro&!sQ%\#`GǭRbܛ 80,Yl g~Rk+`$O'ջ(XC9E-LFHRX>^2rH]w)ᒽ=m&u.RGҽ<~kuo毴yLs2FުxBѧ4'Kv!/`| xY@ӲQ24Y7vd&$`rL_:o悗L%|0 R R> uɄx~E|VE oDv룮⒟P˴;cA%@Œ }%_M1-(^{ q[h6l~^Nnq®ƢI9hO>IfstLhۚ|9.VU3岺Z/ۥ=,YtiJ[x;Jw+9'J_7oH}G}O,v%`1kzg^O,1/{,KEn.^ofk>./E {ua{{*{N|ooy ~#ĭƓ{+mV$c3s_+G._xj-SiIy gUζ,Ko%:s NBY>"&^O8Xeٹ 'wun{1{Gc NkN}vPж17ۺb1b-2o;;[~o۷9nImeIasv ,fp{Kae Vc?Yh8r\{q4>k%ږ?NTloy09KTl-c؍mv6CF#-z <.e& czcfELnF"(k=wv( 7/Ea5Wblߖa^wK<#O+&BqscEISKYv+ %uѥT<{cڶLcS6(3#&_K,cbr[))1RB8i-S/ѥ|P-CW k#b oH^(b J3yk#V=uCH .)(.L!qHf'ӐH3LͣA@`iI<Jf f1Sop_f,r2cXEL2UlaYQ˒KXn& BLJW^*[:FePaAdgՆ^{k>7+pPi+?0s:GſAӦE '\6kwAf(i+ѺkLڂ X)ƥνpY׈.jxueO@߲:xݸpMSm)R/h/ڴN8g?eJnѴU,,n#qrTm N -onͥQ FkTn.9gZ4dXF1e؎"&S]Jb5j *l&rNGLMxآbB;2\IiѿFR9!F%π5ShIioQC[.n|e*.W#.CI}݄ƛ\q}`NayhKc ޘ)Q3qu$!jeu1ݘxS/gB[S$[ELx1&15 bC8`xBOc G[#m1&;le&b>-Gs"&#NŗJœkyh9x%Ͻ1yso"NXj"gPgaa*!{;*x#\C WoZ {ziUZf7&8:zb1Im/cxx-Rxᣄ{L"esɍ M1Ousl觞q7-ֲqy6s^T0HӾxɐS-9cq`rA0b S^18o-])>+ .,C F?)P԰8]@b>&=g9}Kv[0+Cr4]*0^fmMin3DC Y&k\} hbB(x̳UmKsxm7uv mگI`>CX!mb9WőtK'Cۅ._e@Ph 閴\c@4!T9c ȑu/N@Nx(2 N1@?Rf>G{UBf-iFKǶ^ z si$WB xk v~Bq"HSk!lʥFD]vֻppUt! }J@}47\'`.X@D}Vrױ`WR2W /a\uSvJX)@lj?H,P4_tiImDH(m;^K "&v]bwRQ+,HMY3|Xqt Xv% P֘,Gt +!>| L Fȗ^Xv]KQc0DŽ"" {(_d'bɾՌ\`] 8t)ۆV:K"t-aoi KI$#XR@/ RG>"d &)'A)Y8]BVa(Ww/9+zHOѠ. Sd9%T/K KRQn9~Ҹ>nWa}XF{(Rq\"X  L#oMZvEY/q.h*H^z+wx)| .]4tgtܜ|%X+^@r+Ia{:A $4.$,I Mm(xCv tGAVGpZ%dJta$T/aBJ AP@ര[I ZZrl B!Kؓ#(YA/a| so<#.xQ% @ PNhSz.3K,傾/|"_D RU RG^R:8`E9*d+ےՑT$ao K@]_"lL}ʞ77s<}9P׿-BoHPxtGi|dxgu=)[:~}adڙ`z/JO_u[}z^֦h|֥V3G~@'zr %[ u$ߏ?xzQU`Q)/OR1x!Q˺mQN2&m?Cj[')?a8AmfIMq?V\5=zymnkiRT/QSJMگe l{'ɗ*o)kJaz,y]5]eZ{c ѐ[ůLr(([V'Ou̶|!]L|!iYօk)S؏g~ QKjnK.?)o-^ov_gݲ2|k.~=#zL=g](WPLTYrGהf=K}\mq]=zӎicM}ym#nC"۳.!GBy:+H$" ךj9cک#2{.ckEbBzz#+޴eiø؊y`v*\luiݫGd&c?Xcغuim8r|9iqmi-u ؕ)0%ʬ;DI ѶE: X o`VlfhF]:LyO{( |BA)3!6M|r"YdҚm16_vr ٵػJWW[o%<n ڙJWu6+i~IhOe,?e>FQy+ӐkRÉ0R֧6 {5%ϏP T X1p R/[k|n`Tü)޸S]dQL=N GAJcR#q#I[`NģU)T '/lֈW#ɮ!0iJ_YP * I[ DLBn!cFn@)#юz~2FD3/xEv1a-Gmon5D0$n32h)\ZZO$k5 mf}/_bo=vd8b|ۣ^qĈi'DԊ W,S-`ޛN\PxzCݘH~%"vBF&1ΤSn\SQLGhZ B()=VKEs#GZk$&m%A)g Z.1(mXKou_xbn1Sqy-:Lh礭<nZ šP@[޿弌=Fc疖+fS|Ѧ!k񖛃>1;xXxG[ǦMĔZ,P-"sBI5r? P3xsPoxE%>&s ia1,IDķeeMUnQ̝!E%Nmm M0},p#nk42f 1h.Jڔ 'C$J +ӫRXXޘЖ Bn㥇R[K,ʄ}NY$vZ؎xM5|&—|Ai˞||U6+HW<)44"+ M\J rVGkD$w%VK77HNSUø=ȇ~ u$  ;R>K ˁze}P߾O+&~R?DdDAj D&)8~6)pDO} y!' '^iN-E`Z'R m&MԒ#K`YAy6g]&UtezHRlu}|^Qʥt=}BwvrɠKqodHB馒QJ R/$t:P/rr$Wt FU@$#in]OYdρ|P- tҍRXU0KU * V+DBRz"g 91 !c RMfӺߚҪ"RXۉ,R:O7"嗬]6?[LRgrbހt{o:;_.dcs|*T8/Q7k> R`AN(Zݸ(68};IF`Q*R2|!:VcDr],u;זrW:͠|]oUVyE,/e=qUom7\cgzY5О0V2}yy_+<5ؿڋ2ER2=՗fREt͸҈us9Sl/1GJnK\.]]ȉ{>2p{KN%v2xqoxH!pxƬi9ni&;/K3t:~uo:/R`jV1C-u8y#t <]*Owtyp8jurxk{`L)e=޷p;yydl}{h66mwg.c= ֩DܼeX8zbUbY2%x}ӭKyݺjt"t Z+<XCqm^1R=Ŋ5{,),gik]qb,6uQ-\<] %߱K` ts ֢A=qE%nХ^Qܟ-a7u8cV~Io Ɵ}x1ɣv$,73w5i^:[R uR)z  *Q,4^{u,!FX/%"0Z-bRz)run,_跣1\Pf;]z랆5n=cӣ/lgy%QNFH;6 #^YmI=1V$6].DCB n7'F@NwC 1lJ-\Ir4$1N,ɰ^*R2*Qq{Wm[O-z +eG64%^':Weȃ9" )Vb/s8#_ob«v=7>i1v_>ް:ʄhgIDK] |#/Ldwiy<# w4 #nW؏`†eON@~19puH1Xs_b 6*j~#u1D"&xV#b%v/jj*F}(DD ╉GDg8k]PaWvpߨD,MsALg&ߚɪbY~W1Q9( c~2LD~f2RU'ӺFf$@  gkAV7jz> w5~iFjF;#zm2$SF;VȢMvNbyn*\k#: !m^7z4$?9qR'(o:ֈ؏5Rw:)d&(>{;ViLWo,&[cz)ٝ&-OBصPDy{<ÊYY/.'ҥ&F;*;&Iۧ6L6dܨxKNABiXL+/ɘTBsz^L5i?w_pʞlH!i1#4|,d-/ƄM@{b4nt {*ɱ5 7 7df@2╡ig~v˔>?1g$Rm&)_ZBUE"n5G{|UGҏ7IO^J{q)YqDtr2cَxY+zkr$J}=T§w˸pq'ՈneoBuqhw".y$~)!▚G_*%9%lxw%)_3|t"I Tk>-/~#I4K^Son)h%D\g3-""H!ek1+b*bse'fNo/4v' Զkf?k 6eGtVgZm{*u"nkc܄Sm Qyk|ރ%{ ?VQlKiv('"N z:c?'[*a't/i u4z5y)۹=p j1ުg1&k{^XokS"(]Zm_#cb|w3K=ˉ`ϧ6Kk]qMzf8cikV\uJBxm N3-fRĐ S"\SMjDdS "j+T[elD ­%얷4e0_v٢q<810H^]vC quAdn9*3-Ϭdqɴ_J;9q,)`X h7CJ͈=n3}G@_yauh3,@` +Lt#E$O(cxS_,e5M<a{գ8(!߭Q8H DzSPm]ZȮ|.Yن\D1c f|B5+y$N5侚TJE|G% RDGx"˼HCGPZGg 9^2J$Csda)@>ԋ|HzDZT"PoKӰ6)k4}FQ |~[DX~ g`%p{;Ǣn/0X zQNy 9cTV'[_h]N2Xkt]+z"'}Eb~D,V W7iR(9 6)Gx%[.2丗)FPxO%#E##aWBo7F If9MCGArQ7I(DZZK&RR1Nt p ;CNRw¤LfbfR[y%xBV)=g# 3ȥ$1r&U хǥ~FB]u;ɓZ$Ox"XUI}@=QWh,}7>/*I/RrD7G(5iqv42o ޤuۀ w2˦[],:՚˸[t4)ۦ'ۦ{ۗ;*HD' {]HSZ6'I$-gi[ydNoqOCКSK7, \%ztuGdXH籏0srn2{fRm|pNz S;-L4Gu˓X%찗 }K2Fm/kv'OאK2gݷq{nF?_}8WL4cKh]wx>Q>'⭔z~W5$8 6}2ݳ+q9ftNp%C/kbkOs(;ⲟetQ!?ͧpBNzk)#FN%qIa63g~s@N:I{彸%p?u1{Ns۶Wܟ6nU ~)>۶sgy.n~yvz@,ѶV8LuwnIcxh{BF.1\9*9l?\\m@$^E:7M|fxNlku=>ov(nAYi-Z@K ku&,ݴ^.xGMcuȍ?"z0P,$^zHxmkuXBi儙v7de鶕'1VB,ۗ4{pcO3ߏΕ#NKHfհ1O=j1,&VUX1 WT-р XB HD-4җ<@SpHKV~Z{=XTXۿ ,k)#OX ۢwTף|k#ޟ(1t\H M2dnC˻4&,={9P ,\ -;ы 6?I_>].&q_ ~t/lJbyO4P#vC֯@o^d&O9Vq>x=αϥ[. }dε.yƿ׭AnilM@]j(Kꍦh}Mc)Aq6Pﶆ<(/wrɈ5zY.30=ڹy# ڞr5S{.uq[ZNSh/o{S~ny|;^C<͟ _ll./0z>8ď! Z) 1T)!ipnqT{QҾD;ґg^km4e;U8;דI>κgm?U="Hˏ5w(}$BzkSu@MK ,٢@bpjc;Ubڒncw۲.9ϡȍgI>r&NM{"ҥO+K j﻽uf;+B)I菑vDݏi\EtgKmIJ)qH~n9Qk :]-]đg|~uW!"9!_^`[2U{M}h42LGcn;܍qB^[n~ g[|Ā ۰E%K<F=vf]j{ :\Χ dLi?~kPR츙P}^-p^[ %(@aH|~!%8G.籄H1i6|zMxy8sk[m(ϲzKg>I}y*q|]#q1z)FG<#W!WΫx_G87qf :^"nh7JJF;Tx$w4GZ~5 53F;ϺD(QʘYoR9:Q 0׌ cg]/4 N̥$RX0.Lŗ^~^`ZkutɮHJ\j 2"LVPo.\e `ȚC+\#KFz$LCǵ=B%sr-)rrVoK&^gzN%!|;?IHlZAb)k]`9_t񜃄࿖eB53k  Q׉ zH_)I0"۠4V`,^". Q5\XJF)LWC}_(9<$1qIJ,)nѷ!;K:Qz{H(%.+E8UnnFRML-s|;*Ki bh#Xro:*4S7d(*JHn! C-IKJam b. 1SIJS=҅]*bbDch3֫g)=3YJtaR+,r^h32Q Q ,F^2ӽui$6-?"E)K'b@ Bfj5tp)UMJ\piw^֭N[;Q"ɦrYHc~0g zх;ν+MFUoR(͐T2\-#li8 @W8ݮPI̝K wVm"Xedb2EgNH;[2iɏg8I$]6p6##(ݞm۞%r9%xo=j٧떎sz'V⥒Kw˚[Ωs%fӒj8gn{ngnR*9'3ГܷW Cmt*vNDyEgO#0'lTąeq8Q,뚋 lV]4Ѹjႍ 7m$?6|Ԉ}TxjP[Z<>'Dm5^8H,sߓ|qMnBb J@E(h.!xIb}x^_+*Y{A򂬕iM /`Bv%K6%G‘ Lyզ(Fm@r/B= dW1}-c pao/\/Xz"mFmilix"/γę~!mуLv~Ql~̤X[ݽtԺ;T~Al7/a]i|Mb/X72jk>k &vA) De1aω9!Żs^tp5v!j1a:*,B0~sVEXI*ˬMDHdpb xqx-X8 _I̴lًl5Du N%KdȈ\7Qcʾp8Fd-%.t?Q'pl )4 P}'߰/_|įhznm&$_6EP1&3vER.abgX`gK2ŒFab ˰"2|o,^:IvQ˥t{oTKWlsYra&)]#)kX(,-{3L&!_ĕmH$^1Ucگcly,]c9xSfiro_:^x)ǶY~.rso 9Nw?h-"1zyqg4_XgYvFjZ:f<^vjiRN۵cD[m+si1'V9aЪ>#&55Jec\2s|!N-~09piphi Q?r|cLr9& 7 1'1a>]NN2͉nA!ڟp/&"Po'HFRׅzIC!]X1.ijۺqsjf˒m(7UmҶKks7 ]RX:]bI/)Js(ήK3uDH>l2dbA?#'zqBFRKtR}"LV.Hi />vH9@D\RFveh/#J,< DVEg-1? &׵/i"zXj;K_f6Z-Nkkovr]Eӛfo{Qn.kLyT5XxV. GN`-ˀ_.A%%Dq=M5bmڧ-i 6{#$vϦm 9Ij<`2[ tm)cW$0ZK \w"&/Şݶyf%@\faK={W.iK`+uhB-!]^.B1$cꟃDH.b 0ρZHC&"wN(ԟևB')LB} v &AhGNotU*G}nok 11J#L,ڎ07Q᫿/#W8!h^s1APkK79iHvbS|a{\8ps*ԁ#t jS`¤%2oO:UMhU ѭ0%BJ\M#&Z7 wA\8-/tU!ں61:H AjNx!-i11ɗBgCQ6PY l׵)i'r1ikpF>6aҒ@}eԧ@t/tU: ]TUy顺xz"FF!sS_ĈDm! !EYZx@ (O+2` HMd1?saJڄ0E<7ReĄ!iR &oq2El,2iLc>nAˀ">{3+x Jb"x1N>N~ ''N #pB;2/TR8D$ILĄ+Oe>I,ro!<$D o~QN\ h~bl׍No3vq m5:aKp顖xeTۺј6WKQȜ5`ٶMlMdKf (b2-EŸ : x{x+b*K|HK}ĞKi`͸\2n2iNӕl~qnOI",^1өW"k.h~xbGfAҗ3+,u+bg}^,vWb?*wϗ5jl•[yig9m9Z|uMHn/_KY\< $_)nAMMU-//!|CQѶcI_OjWPJsJO5&y^^=Qoب䫨޲\|@D {v%-(D[0虣b'8XHB%?.!I|kcifzyQ TH=|To]c܍X1s?Cv . ])Fɛ9KøǢM7):5TGGkk;SI[<\2A_ա.Gsq}[h>Lq|ܽz["NǶA x7t[?^͜z TǶAU:8C<^.#ITQXQI{piOcT4tَIw[ĸR c38˾OX;m?Bڞ|,3]35N5cNk%+f+y[[nm^jKI ]%N?c@ KD/8 OJ,KD`NrK{J4@`RK̑tR$JR=:y͉@'"QE)8|"  %#K.L,fFW81]uH>Ejj+$"ST/շ’]ݿ Hu)EvMҪ"qk$zQJǒ㋺} v%RZہ^VdQ(9tfx.ho%.Q @noRMlF J%"z>:p#z3VHH V_ d_9R /G&KO : ߁(7RXIDlĜ"qQW.FXJg)8aV~zae))B ]l4@V] w~~nՋUEާqE&mMJc6]٥/d*b19"ڥ aօH^xV##0r3o!>os˩Rz"B]txxCsDKGz8X;Z$6KhX_xٱe?ǒ)f "hX/Ѵݮ,%ەHL)}a^Gsk˥ؤr.iF?oɧ7 FL_(dz.ʿ\w)S}IM L%zx@K;22s~4}k# t;ɗ3RR:=oy:E'ԿKRѲ^^c<ϓalg 3)hY-4C\_y.>jz9GOcěŤRBfSԛ}350>H=,qVo$8,ƵcwPV/|=_~!0wIļ W$3{Fu疎_L%u7{m8 󅷭}.֔:zvp)8)<͞nv%9cKe[/\ptkށKG"5&4.e5}[/U|#Q{2=:}6$rq8FB;مLv ą4?*цeYγ˨_'q!\36\Z|c{`6qO+"Fd{%v c>XkDs#nMv{0]e)ϽiG{':m'.V[Ӹ BÈ;?77-)ϏWqJuߜ +!ans]ң4@~w[Zx"[QX=ƣb w;"[{e k_뾅=vϑW3%^kܮ 1Ѷ庆@Hڱ~$ɀnk9Gơ0t?{GaټIuۗ5Q)qfO,=Ĝ#xm#ǸAWP^ b`FS벌N/DiW xpB;xڻA k 8,+1"aDb: 3/ݖ|9ZP^ Po_Yhr`h:cCuih8%HDHT1xZ!%I 4pcC&pVz0"`/b[W1113T*b3ɯ.܄2"&`_h,!ː mI &CV#^QFazbBfjڨ: qYp:{k/\Xϯx4eQH۾2H@eOȯ)1kSqHE+ȲW/nMWNm"'`ۤ7(8@7&Dh^g& i!Vix #ZPa$p$o#n1YvR8b'Zpɐr1gbz/"]; T7_؎@gTZ_/20kʄE}_i@lGF?"24ﵥikZ81QFL"C718ǨR#J S|nE}4@0K_L|kM{o\4X78$v1bqFG~buY5o#bo1DVNDEl=.l h2 r[hfK7ɲ4y[cZ5\@ĺ1[݀K(c(ƦQ5+qAݜԍEF-4 A=k 苭a&j"C鐐)Y@Zp^>+=]&kysIvf-pkl w 1K8E[Z`4*ڴ j9OA/9L;ez6wAE2,d(\>YR cfɚny[IYx2Ē %їʽ(Um['֚ ̏8j5)Ѻyא~lut NVo1zcn}L٬bkp"qǼϏ J粯3}`Fϒ-^pmCuO:l>8+quR7}=yR \jLCo8PȖm (Г.%pNIv&//)tBqRumkU2v 逆AvI!PK yijpK z v_-͠1k캛 -} V'`i(5GМD]ح]ŀ:px xw] P!a j/\{u " ?I*Ǝ 'س>!_ !RX7|RP1Ϳ>m_YץNKD~/X=H"XkWT XcJgQi,?i+$&%۠z&ʾ.[,Yf Þ66. Bf箋ȥt])'Q[q{ƹRg/j3A V.A /$;Jc.kRXdZ\X)SɮKksɠi=8.ҢɎyI*~ ] I_ dAN#Vj¹rў)!w/gJgoK Bɜ9Ճ=[iAP^хT&+||֥D'D$zzyM~gJWsJخ4(/ROsm~Rxj޺क़P $ 6u![d%%Rvα .G5bK`.{حʾ2P6  hLQ̔hpG| ;] ~Avm,X ~m86u]R/ܿǢKz*R #HUKЪzW(kc녯$Ĉ=}!tʓ*ֺLO#* K$/$L (x o18q nە2fJG:n1h۲sz. Fack8wﺗqe UPrnu ,X'cw&;{9o.`ueM%?ӲT5]W%]Xvm]F$/I~l,vnkK='L=4t\7{keo)M?|5#Gumri~2˺=^D3&:;̓qWκ[֔=x,\8=ip& ԕW=;|(:ؤx^fJ"`Pr΋ ܼutsի0^@?7o(qogvq  WÇzo۹LԖ{*0^(&KxUs+ĶmчD`{~Um X64.ۛs' M:#g>b %1xܖϞ2xung^'{mW ?H 6R%b@`0mo*uv~RxIKPݖkk!k˯Kq{dL{弐ajAr; !Ĉ̡描ol>/xIcl ƫbڡO%bƠi z;o05].i1/^f8ۺ,l]8$]Pi#pD=^Pb(0gk<8mUmOa?k i"sրBR-zioWsp2an6NFMúDkJh @n"bW x,OaҴes>x]2`8Rs7Mؿ{V'["!0cr!`sCF_[Wj o QL]PnC 9{/ia 7=/lH+8]K ~E]Poؠ;9XmK*7nilzs+Gocَ6׳,E-[´mūrl]G{)GM{FLKKD|fZ8imzcvI,pxk"*= ~{RxE3cvt?ͳEp)DEV[Ҍ ݜ<`vr˳^-2{{orMڶ̞F%-65p~ݛcy=&:omAvfm,۝~Wz:u"=[A*-N !Ϭs6ޟ؎_mak 'Xۻ?rN6f=珚ˈ _Ϣ<8!uil2${ǎ"NC0HVX&ң CrR-_. _B}2 6g/`pTﱥ}jJJ7mSXܑK!Х_n)ml+aq{ .@ݳ.e~ ];B{fOR4 ao!DT>`[<l R[Ͷ^nY-@[%d RL1 z;fՓK4ucV9Yrܡesu}:ǒmq<@G@':u;4YG @*D. E`L}IHBn>"!I 7 }[RD`ϴ^!dVQgX6'`L[@[+;J.%0&-ɨ'X/^2K~V unIlWv)!;rD$|3dWQ=8ѥIc> e#]fa$#Hudޱ EF!9`y~"L>K 1JNH A01:rn03Qtsw+$@e|wFl3 %J녒6A 7uRd]Vou( )ou{nI/ҸT_z= @5rБp3ƺ.u\'JJm!ޓ]JguݸPohɗM K/kL(!dqT#[hg*OAB}[2AS k2FdZD`Kcԥz@lJ%~ +R2 U_Ky;Ot+X׍w`o+0 Rg&?K"u(g]G׺N/A,9 Y, }.mW``N%#b{VBzN_y֍RDR%Ds_Q6ӥ{^)T2e٪f[lVۄ~=y5GZYnMGA}4{ؓ| o^֐fu -비o^rJ}rz" drqyy)qi1fODsֺ'qsgUI#s[ϱ.Z!-FW[*P7Jzn)wܮ&g$sYB:P<{bJkQ(؆-iv%2<u#VD PQHʺ@] P5N{@] Pg,RCuÕ F4&W\*̓Xxԕ8߀jDͳЙuh?/QuX^3ѽ?qwv-guQ@QtxP7F7nӈvPWӀ#x}B bZ>a"M{1v44ڹyR>|Ѯ[_zԍtPPK6_Y4 !2tc9|PlyMchW[qj'm +PWn!.k-K۵]g\.?RS\Zk kC;L tVL dVII-!ZF,d#~Yui6 J8x&OEoۃyX0ގGHܜ)oJ،pbm`ݭEcHdQ.jH-  qfMca9BS()2T*H&1q 8? `Ht&FœRDT(r@>@*jĿ[b"U/V#{b.P# }^"-Gc>j8a _Y#r0EY4cC_&GL_c"Eu3oW@H녺_b^א,R/{pxECb4brO+2qu_īO {m!?u^p"ޣ6"q̜gR[ϴޯXvΑ+LPY!mDoa"$1bid_k%[W`18iHd7CR bdK[`$2Ef Řb.-fA/D 0"&kACF49iˀ ۙDxڄ&pѸL5h# Ttf+cΙX8N"f6Pb lgG3(~qSbӸגbqp-=0erA<C Hh5i疿 M:>1oW`/MN%1֍<73 isE8K/ @:\y6YˋIxYڔLŞ  tiiÜ uyBoH_u^o Ύb|8n<~Vpq_R;?Xx(fԦODm.Y[RvC/tuK˅Jݕi22_ ħYB(@~WK^@],N#DMqc6\;9<7b3| ]P/smht9?8-'i6׺2N]rjs#hwmqH-+0Cn!pm x-[[>ic33ܲѻj`v_m6 \Ѝӝѱi^#'ԈyIv/}rPEs9,.cIb.#*"ql4Pbm𣣵xBz6 1W42" ܼR'Bs_> 1 V\BŲMKn%7\aMZ8q ܟ!ey=R'R܌s)n %Jblqj[ÄBְE.HQD1(c)96mj t<8>_̰~cۏ|SRo=[]-,-PD=V\J<]?;94=dG=UgZgqqvVb+Ps'7< k\r X+q1bRc"ch9c miglqHM\k۟h|&Y*# G=!x,64[c_,vclvle甾m' tzfGh@%?2v,ZDK㰉DWrqAwg#GL $d/N5'`y vWhT\[>z>L\ #֥6iĉ}/R{c^)RSR"Vyo.YJ m1IŠL54s_~~:q~; xiUP=42|IF3iH5~KWIS$nV`$ Rr`!LbhnxKK[W1I(]mCX%20Jr-iG>4J]/u}\+6,{Y< N>ZF6<׬g^28iz(%HaR aGB&1"n1pd.R li;ңSk~$Ju孭3Q dbg="ӌLg]8͜¥&:LD@7n AL@ Vnd+@z#rAqP7umٟuy,R"xB}%+·4/{/RUH21Fsv}͵}R$HB~{]*x/DK ;q}.]u+d{{}/r`t\[`>l{g-1}"ىN57QJ;Iݞ͏O8;Ĥs +=ʺKf2sߵ όgԅ]CĕϼK,>*&.t{"bR/Q-):OgDto뺇ߚMV֋ta ]Rx'%s)ܼxTu7JWnWi +_|Ž㺥}/Iߝn;mD'(p_-tNj(ZIыu˲D}N-zSeV.՚]95$wiktiW)<ѶLWu;2 ib5 y6931<\x9_5/g3V~wQt)?\qTH(,"֖#mki c3Ҷz sdN(8] Wn0NWL=ұXZ 8o۸܂G;0ءmDcskJ=/GLl1J8q`}DAf[Cnq XZZQKbSF+WѥML{$3bN^h @DBXr.&&hDbϖ(&JW1#K&i ֏a_vL>U Q(V8]Yl"~&"͵b_<&Fp!Ȓ/bTb4 V -oPZ”xen,3kIL[7t4|GspYSFk9>yfKX~=#aϴ]R UkOPZ H[FhIBp 06:LK3nk(-BGFi:јyɄD|73(Џx;GCM$CJp@][4J bυi %ou6RɻFӟ ur-Y)qbK::jIk ~Mc'=c*q@6Z 5:PJOU5Sn)! c[(AVrxJ4&Wg$ʈbD` +݂ nu?>˚g$צoseO2aBݒG!$P.^tZvmV9[)!mwKWJ8]z 3rm@Re51Sw]1ZџI|-$?09{S1(-k1tN3r2;m9aήn,o/"3TV`Ȗ*Gn^4r$ڞȯ˱l28p䨅8].Gĵ6A,0TzL[X5i->f/@e!eNvna/Щb- BL.$vW&yLF6dӾrwgt.1Lk[gG9aڲw΁~x˩-HbyyJ&nLU9L{jun^v[@zV/ɯء6!5o3k~ m7Kj{UC5 "y;$vc H[)H;7,s1yۃ]BgB4MzҤؓNM vzڻr\[_S^UsQV9@ٴ*-1?U[G6N{uuZIK>%{|0Dr%DXj XjEbDžu1Af̳y3=[9_^=H#2if Z?{ -Հ؇|," Q*mF->EMD$I \gn"Lg#d`?.L~&™p "n^ ߞ6yaM(VH܄nvIի^qؖIJےhxc9DIs^ꅒi5Cig%qOI"#9/H^>2~F^1S8%qub(>a_z~n3ٔfu:)PQq|gv5JdS_ng+2brffv)~_)1S֥gLJ7VyIFp zdS??gEFuzULVJ/6izo^k7N)JFhv㝌z)ο5`Qp%+&̅m9)5ۥkm]n >Sr-V޻ۤd=r\T|/5Mo÷k+<`^q߀i j]I]е]B>6+OKaqGШ[qڮx#3} =N;4sLG9C#2S3d=rKFklPd&Rox#1WJ׶؆؝@#O?P{2jn0^w_E;X\gɫח%5~GwJZb[ kTi_$kng*}4_9hǔ䍼\w"]v!DaMm+.7i[ԑu]IL[#bS:LŇ!^q!/07B!=Y19fv ˱&1( ;41'.1AhY@As \9t)âmH֠rfm#Nbopþ1 K@\oQg_~aj(fm^B3H[ܨIbznݿ򟱲n& 3㥺_hW}幡pJv.X5/G(\ .b<+z݈W+ܻS S2Lh!d U_ G,=k#_@E1=UMn{ح;_\6Kxbļ{FԭUUl/ߨ(XЛbT|'"d9- gmsƕ g(_/ظ"94x֖-T/QLs?¡帽>w¿4w"x"qӽsxٷqGK^nmI'ζeqbL?ݟV qHhlGoHRچg{Ӗ͖kA t/\x۾3G=^Ń4tSֶ#xtgg=L8x7:miIa]bҼy+)N۵8PR=2Ub|)>;dbn6WaLՈg"?FK{p1;O*wۤmo/bIW v]KT~06FL>"4 {H=bj]إ§jKz `mD%+d z<:8sR"طv9zEش^2r1tl-IF]b'T$= =E:Yz3>D0CU4 iv {FRcIǹ{]lb=YHa.m} z"ZcrhUH^/В:U(K뤬ϝ̘ھU#nd,m]+hh_y̆e/]#߽i /}Eg]@xR=']30<ɍX˨-9Brֈ| <{,YαT2壈Lؓ$5G Hh0IFR;RLGХכ}օV״g><ZKG8@ LMC(}uڮsO,|}!;Ϻg>IhWDC~YNg) W\o)is%3gn@f g}+,QWJT^ܛaF/FWQhbW+R'$k{¥vl].c-yDDd$xR\%ɦ`j%taXڥتgv(zoQ${~""35 ܏!DU/毖gJߏ#m%2.G8da+_HU`WWpCO$Ro1[)y6cJ~yNԖyDIO8WgGX_Iuq|&oÝ[Y:toMzXGȭN<Vy^M6cXs ZE <]尵apYm)yWy[:~|yBi3KN^E[r֚zEi!\j^4퀴ݞ-.)eKS7 [[9Y>#9m8%t@ma;Q,#w'G?<[-ߎ{V;{_dOFO'oxIAae {݉溔=${ʶ֭aNv%[G'7;7=Ji-s=-g0lM5kvOqTv Ķi9Xڿ?M'[9l=q{>Vڮة^W/n6'8oCĀh NWĿӣۂ0qu qq{;Z}4O1-h%޴ڂ'SMI\mhﶅtڝI4W@I9=Mi/d N*?X҂!&8])\tz ðer,%w/RNYIv^S$vڮyԝG."]c ׻cgrmtxۅ2P۪x`:]Lv#:(m엟iyX?v4g.{s ]uqK +^xslh6Ϲ}M5MI,5miߴe9r;O0=ґ@` 6~6yo8C$='i _b}R@yGX;GYR^J#[B|^qstjw]%몎k hWa 7q eZv:T\ m4AS bEiV;w|P{[j0&5!a=CTJ [2_>_s8,Ox9C=gZ~ 'ڛkZF9ҹ5O4N : ?jW}*k.@ln"&`fR1Qq ;xB1q-{r kHnrڈv:tn-fFkZF[5i9dh}1cbHvv4O")\{,n|0PdkBv&jiHD#=# O-VĭE`xȴ1A*{n,7*;h`zFw2n_$Ua@Dvֳ?P|r #Ȇ11ܢv.ڄOms ;O 'ںlf"Z1aLTiĄQ2N*OLD4b MʔBO P_:{kA[ 4M-oV#6IfɛyL|aqFQϴ>=kDI;⧾Ppu)>fp g(WOFSDZ*hˉ a{F}"\8]! >$腇`h@f/_@/BJ 4iİpb"Eq/ɷK,^FbsxkL~C}6ՍvNӀ}Dy _xz1&27mBڢ$z$q~%nxʿH0u:} WDŽS`/گwش`?L-JboH*cz⾉Ϋ J(Q28ad^B+E?ƠrYw"K+kƋb0F鎶X.H{23P59#%_,lm KMZrf9Ӥ3ekSN<l aqXf/\?w`u8[Q/5\`.jw`!us܋gΞa gh7m|i/pKIr4x-%ik]WYjB=_)<4-z[ LN( INC^$'c"9i9/h*c:Kn>|n2i82Xr\oJiF5t/sY&!nN2V;IWmlt/yyngs2̒=1b"~[Hi/rRQEVoތ]ی'j*^_o-/>[رfn-9۱&Xj+؛ּ4q:m z(M`ҿmҺz˭0lv0 `[/j h]=P1Я{v{N'T/zb'IyNK`׵J"%ǿnmQmǥmAF 5$ڣ9/6?қ1W=0æd+v& .(PwD3}8b nirbu!X [Rd.!`ǁP 0 a+[ގC{<]v["ۃ1ˍt-`lt([+:~FAƻ+Knmץ>Kf y`j> XtG0 0 pTn#>$'x !:RpR^P е}"-Y`W"SF`=NgfAo :xQWiJ:@fuao*W u#y<j]~W/ﺴi<)l/0% `%$T0ҪG! 譢zG V WГ0$]]|LA  U_Bq=bd. ']"J&]:< 3Hm~:1sJ6V %R ߏ̀] G%#0td΢q/ VRJ^o3H*Hok`O&MA])*JF)hKO$G*PItER}$7ME=Tt% (Y|}Im~b]ě/n9̈́E)R0Co?u) ]mwAIMZM#Td<J30֋OUх ' ho\JgƤ](]/%X &2FT1]CPKP!_L^n]=uaU,cW6Uʾ1K^o>uu]Ҳ~2=vz܎> .uT/ s"Ĺc~i_=]~ץź*xWI:G&iUMP͏=%ݛ#X:QNoج=r='eЪ\'I4~ʻRuf%=x, ?E.)Oh<&N-cx_[^qKN ulK7ow^_9Js2{ :Ӝ iD'%H%]n[4jٮdvmw9wz Y۾] `txdiZRUQ=6bN11i0KnAw5HRaRԬ .3U xT|sOaDwHFWM)D,5.5DYvc9h^7h>*UsN-׵ۿ˸`KԬBb/!c׺Z~KaЋ'Ydkɗ ._WLZ)WLNB=;Ww #,Ŏ% z99A`^<"~o+CDaJ r֦,Xr$*FL9HY2ARi)dV|qSzc9~UF&&XW4%sXZhng} fTͷf4$~=8X|=7m}ƫk g\^f$ggt)i[Iӛi8zoNbԘlr/ةήa'r,q9PbBߞ\-y-鿳6zyk٢98{3^b, }9vWJvTowUv#VQ >%V>Roޖ5}2x7If;גzI[PTk`< %7乆ign<TPxN[Ɣzs/ncםZC %0{(QhA K+ʚ3pC ʰrg5 [RL_j{k Cϻn/Gi/uKS.z=K}ov5 Dv8^u!9%i5Km8%׼nWR6|@{׭K !Hܗ}Dm`[۾3`%ptl2zx{a^BDE9EP ZCZK!PP~ P[gN̅ڞz{X0Ͷ-m\!i ¡=lVoKy[U Hk|=\ _t ( II:#؅ xqRX/B8 `ˈ"<3zCPrq):!$<)IE >b$KUJzQ@}>c3fƓ_(CuCRbHkA3ԺK -^/u] c}c}Ƅ"JF :uUkE"AvHR w@.qȡl >J6|ZRƒ{oj[>l7^ 9[E7,[sx6si>?/Qk)T> `L9?_,z8Yץ~(0A Sb7z3\grӟЈ" #isג]JmA}>mUב0.8.=tn9R?x=߬ K=X̭d5 _)o ӷ%K7`Ro'; J/Ay,чHz):="Ue3ގ@WT__+_rADTRCD0$uݮ' K4d2 N7[qdSNt}okI;n/^vhG/Nӹ  o"wA®~uU\kc\}v]{$)9bupo"tFܭՋNi{REz{+RHud.LHd%|7r*B^Kɀ%]:nm}RZ闸\JӾ-F'E߿RO^5ۿ,Dyn)#zzY#[ge׿~{}gD'o uOܹ H8G[s/yh%q^^'4o~#agsKck?A48S?],_rmub>[WOA/k#.$C"uog!@SܨzOAm oiN.Of€ o|Ey 꽍- qHL}Y);2\\OK? h'-ٟcYn0v@4SE6Dۂ͂v4p;2ԣG:bX0ijp N[s<2t(iߎ˷En6'?_яXK_N!kWz&HO-pKvvrcڐѾ"l%U ~^0̶^6=eN̶#G$gK1-{eB%BnA-v'6"gsC/umhP-@ZeLD!v.Ἆ}%b_+m ZՒ>CBC,'iJ0M}D*~?[vO)m5J>e@_v VSdsH$EsA8!=N4RvW&E9V8 yx1RH$iocӀh'3Č9b:R)񪋑 ' |) A&'piO#dMC<=Hsm$RQ,LNv3HKbł׍5F]D]9Y uN/6*P$&1}@ύ9|6h<<{/Cr Ef6Y*;vA6IJMc_Q]-)W^e^˱ܮ/\7nlZ/\hcu~6msC"$zuHJ:a)ȴipVu1Z*pdm"MӦM-;^^8p?M #jc8(9U>J4b*\[o p1v/'0d=4M=91 Xmt1n9@m…2b^mz[m zGfez=3T8rIu/⣩˾_HPz 󚒶$MEo9.gX?*T /};|57|s| 5b9Gɛb~!Z[|ߚz0fR*eo-~Z~2D\nV=c.m.$\l>Gek~=;K0y _r`wӥQܖmDq9hnxc"(i@/0Z%Kڶhξ7cۛ&_m#?;sc6cl{tiS4784c ]p@ 0[aRF<-Ӷ -K \)LGY}d)-l`ET(fVm01a_hG:vpLtotxqԜ-of"/ οhb-?lzk>mMrnl#CmKc`';|$}Nvfo3,]/y${j;`ueu=T]m@rXu-GmDfs @I5Owi֏m@|eo{8 ܃)"#?D&}^1VP/FoP>D$ } ,I9ѵ[}vIZZ]+rG)ASv?Kz8^ 0+m`ՅQ ]}I@.F^DAz_>)1ΌP/D@( [v@4dPXхpـ&?HO$hCO 09b4D @)(}хzaO:`%.uR/|9: =v]81RL(fEc& c͘%)ޝ'}5NفDpP k5=kۄ^Ԫfx",Uݎ@4e RB3е*JRғ}t$ L Pkl(2 M/"x8+ j-=RxP i\ A; IA@⛞P̸GnN[ J%/bڟ3.eULޠM翇ZJF6Ç PkB"~\rETk ­8U')m͢*R@L8ָ(c5 nKa_V^z)mH}(@tVyےcou7]51zwxޭJv/I#KRH_S@z^IA:}[|3aG 3szԲw]wqwAݞץurMi cK^lFO.u/}wԴ N^KWoV\}|soMGx{r鶔mvVᮞ ݬe*9wYnQቚmo֍~:߽;wr!p/HiuiA6Zmsi*KU hyMb!y u.gni>j\Am]Gteyفws^_δqJvm}0ldC$ Anqn7J6Ku Y+2:ƋsCJp<@.S:{oZwY r\'2,kAjm.>t@ϲ^(ގ5"{u`k`dtx?[}Vut ȗ"<"h6!$KY m@R-k~7/Q`l FPvp=c #wPWpxɡc 0);#x&*y~$ = OEE]>YMg0q{Ͷ3/\ls|0\; 5i8&M+mS db$rno׳9M kbCkeI"4K{PXL(j:(<(^{ȳ w/iK\+QL4*GKp i!!/s)@%uJ B10$D2!mi#lH4.') $q@UDu)"(wK/hȿhNn»BUbp6QR3-Ȝ}73K7J/,Zڈ4#i~f.HKO|7- |] *|Ь`#{^Em/ɭ$F.W`JBjnƦ9 <*=jN=T{PWUp">?ejT&'qe%Wѐͨb8=/ ߏP"vAPzu6#H\Hd3~MvD<ҸPoDX _Eu } J11!4b/Cl6IJr:Œ;0kIhKŐY -G[ËKu*d떊 Đ IEL$v lqY." kt(B5Ԣ)o>9톬/rA֦$__R|.bz'zaƿHQ~y<>\^<(溑LY-uŮ .&IZM6fN|q=!)Mt[`\w Do^,9kM(46'2&0i@W.CZ("ȸI$)drW"~5@p: i[K)aALXB ^Ǻ}6L[!MRB8 e.Lk3g|lbwۗ\m;]Ie\Ŗs;TYx"+5^d+3|' |;.KnBMRIsG-|ԋb'GRyR6Wc),itaR/9 Wu(\V>{}߂_z *5-݁G^|=myB2摴3dݟꖴC[|Hۦ1M\qz=[2Òzi=8̀NCQ"G<±ay|Bum \ %C׺mv9qs |n!PO<+ehb $kha'a sO%4x- .J]:43 ~䇛6}ǏݎeݴlYܞAYTv!pY-c z|\zqzu& 1-DZ`n{BQӅ!(9 1!(?809R-~1!}ހ^luGl:n^~B=@lk±+i I}v w 4r5o*iX@%vĀq^$$< pG_ǒ{x;N+t=yzcYf/  ӹW3WعAhAc>uJ`vH9Τr|,Co I0ys@5Aw]PV 뙯\'nuYWt^ӈqDۛDZYpB]ZRG᷽8@zxpi)v%^)(^td L^?"w\Xς E6 p~P@\DA/ V WF8`c(!'NORk룔*U $%2D!_ںT^2`/8]@e"IF$AKM҈-{d3`} 8A)z0-)ԫ%z  %RWV3j[g%@[v]16D7ޫ<riGIaEoW̍[5H#(Rح^th R^AB9bOH\Fܪ`O G] X0FJ\,Yp3qPk\U7)u]Fm&`&)d u$#0VzpP] ȵ[lwKHkTLHH[E] IJm)ޒu +RX(K6\7 ds-vgAO[r$P|x鬂(^6dAB_ 0Vp2$/˰>/uIp' ^n';_%/˞LVes]w97A20X>xR)6rw? pߏkY(^_gg8Ov-V_5|IE?(rJ~n=}Y{3,޴Г5)EuikZ.]/X]+ish]둂ZӷgK\SBӖWͥ[C쾥/T=R[eui1t..u~ڦ50 "xrqֈWRZʘ^;NN; '*W|} {>xqwxߍH|[8,Pܾzh8A/|kY`ۏq*>:Θ:haƇ=eu1{y X{:F7mCn=󬈗zW=eH1vUHfv li؈%!"*qpooY R]p_іJa,K[5KZ&fX(\| ڗMKToyan36_R^'M\QXc*ٹjx!=mc4#>K[3aEVo>…Ż{K.-3hi} a.,^"jA'$A 9LQ *=@T,2SQv4P$|Τ _ﶂ2 >iͤNWD.{Ym-f9ǵ4hIZ{4 v ;!xTFaEv J1j{2bi_aV['0H J_#R ˤ9&LlPT"%We/BeE8$Z%:y^8i>+A/]ZT 1!opp3Mxp}xZmoMQFjtdڠMQ:ULё8";b],Z1ɲZO ,#hubXDjYZHbG([kc/yiaqYL\$;QA97mˈ w'vs8Li@ZDL-3ob1 e@I|-Do-戹ob@a2/oA 1KPK"5N@bһ8Fn?bGLāp{/mεET0o^pRa][h\RxM,yݎeN 8.X9Zdm8 I w̳f7p#8bJܵ@޸E6ҩ\g}{-!QpP*ޘxM7R֤4 .-GkuA[yyg>=-JgJ6mZ8A$ndiX GA4~n9jҐ b,DLL-ezX[P7H 훵XVu[qapv1noS9)\2&dhsӥ.o[NDeO&0 fw߉Buߴ]urNn@IR#& #b0OՐZWE4T2EsL&>WKڼp!Xԩpa2gm iϫOA1?;I̒>Z7h(^y A(XI.JGQz!\g^b2oGfC/k|*Q +z=-p.^&i]K~NӺ&^J5}ֲNN6%LUznk)\Hr4\H^ U8GnA0kk5ԭޭfo:n>E+06񛤈zMrZ2Yif~7ΖqܢZs[.o yq?-wޖ::,͂4~nYn۱FSwH< oRhZp"q_ɳ[XRG_>+Y^H0ކxAܶ5" O*/Pۑf$RUPhS_е_ߞ Jv%Has?\C,*KR =Ja҉N_\)Hxuأ ϱ RɔbW$*Hsul$XKUX2`$z3֑N*HKH%;FL"Lh"P2 ߟWy]WW. I H%?YZat) &FI@]gp(` ǗJrhu$u*\7D7Bp"RZU]kY=u,!xKpZ6V ފ.d ]K-{k.Ha}{B%.9{X/ݚ#V1ci>T/!ܧ6KO0FN}.]&T>rGDiE(}D"cβum(|x?>_ p1@\`Bu0>se:ED6F4nqhbeഎ;d-#9ދK3 [{mCPfJ&@jM` º&9vۭP|&G[^ӼJ@zl ܖ&u/C^Z/O)b}}տ,;NԴk1cVN[c{ƽ@c|NkoVciɔJir6:oϹ,[;\S-akI/TIUIW@𼒴:̔F$YvX'vaT2ût;u5T߽VVf[[Xs\ pKl=~4ݸ^u, ]j6I3,>/g)$viNu?7SZ o#{Ւ.+ryF_T֍ώ_r^5tfeܰ\XDH eO%to[ss3yTUq%SAV#m]u ȗemo3B;ښ; ;$1|=4ৃ|c +qZO@ksZ[raR1:xެ!Z1I\P[ΐ1&v[EX| ݎ}!aqڥy|=bBFcRY.WW x`qfxbd$B>2v2QܺmGx/ bzP,R,w3ȗ^cNcdAR/11GmEIzݶ`_#F_;i^#FkB#zc܊#9ۉ"&P:ȵ^BnENۣA@NvU#ݨa|#7D7q'hN\T! L½i1O֯T79+m;cs~)0 +XxO0#%uŋ8\߉"&F_ bgiX 1͝J j9޸x`Fs mY\, \zN _s`6pn)׈'hD@o݀P_$f<-=1$iR/| ŋa6“ۜhY i29U"Fb$Bڞ!.Qw1pˀY(|uMP _5A/DW| d2O׍0^MN/*e름2{(;2b//=SR>1J&mmhˈ _#3@㒺 ba Cx8x^бĨ;0x`-/c#u%MR7poM٘'Ӏ|ி5WAˤ_ĺ)v9 ;%$fHDRD$$0awk+0CnV+g[nJ4K޴;;q"u <91ٚLдELh-8$`…y_/xbj9Z Oi7<1d$s!n_4Cemb (K^LZb 5d6$K|y?-uBŔXs#P1<'R3\z ɦ22ؔ @F 9($5)cKC.+{=mMŒ!˗\*85M& _,AقgoTmqe*~q $K 0|SJr*Sdɩ)ё#u!lЇU>"E>&j:Y;T{osx9S1` X@P|C&M~AJZE7|'km, ߰?jl'&=ͳx˚Z1{K0r=iA[5~c.=/%F=TAva ; Z7=vf(_N8# ~76?im9.hcjm 0-kbe a<\pJ@ VdE'Rt] #qa$A:Č0V(%[ A"fХ ##Ј P/ 7hlu.k!@]>b`_J&>ㅿ}n,xaX)$%]no;T.X]{)-_qQo,{-L\oDz ~F@k/1!` LhqG.!<]zA$P+Ա/!/G3 %!dx]\)"(8Nn~ TQ&J_ ou]O.%$#‡=!AD^wT/+>Hd /,R0"$,m&$;2B8{??Mn+&?ҏ_3HRԅwIR*oP2Eץ`  3>_Lg)>Lw`х@R)PJ%nL{J ub} P96< Kgpʌv){U"y~EVGitf Үɭ]LE6m!F1Z(y%ƙх.W`)Yo vB1#n>>J~F^(0ƈ*G?)0CUfFYĴoj~ @'(KG3(XTK;z^w3VߏLVy^}j3/2 >EzQKg$&27WK&7AV$&ˆ`L{Α[Vm FUKk[m20tk=|wtq^p%eLd -8˲kaŭӳΩ!'O1x/n_ iw{)N.0p[W4%0X{SS[)'%ǹ-.Pgfk9Y#crYBF`YǸ29)|rcfͩCԛmd Т+2z٠dV>}n/)O# ljHvmR`Ryi qNoI2>vmi?Bm]F)"KeD}xL9qiWBE^/7Ec2{n5̈G1/L@Xu=uv_@L x0Ln^gY gًءrVER:PMuCNvpcNm:"MW‰ QeCTFj)94^a/\*v^m =7+"pZ 3D"E ٧h 4H?u1MQ fT8"HO,0\+ JWM}Hg@Z ;u,!Fu6r]Q-F[,-7l綢15X/훅;hط9z}C1-\ʕݿk#4қ8D;'1fp n,/(Ny de9pJ%[sZyPu0}kāiuu'rqEINuj/i_}LӦIlsͷB^bڽ!qsY>qi\ǂRmr܂>b[2ýe!5O} xrz)Q-L2BJԇ b&os],ip_$YƷ #yb%Sr])gP^zܥ=%[_1&s7q2KǹYyi i*Û.-7Qr=ʲG)yѧZл5Z7V,=kۉ`f پU bqu^v `zE^m JiOzg̒$ul_xcO.-bQ*7,q@IPQ! E37Ų;,ӷ85O.^boc=}SOx+ű-\6,1SHrI\}cSk9u,sh)aطn1`r+VQk{|ZZ?mt$ ]:كG(r`S^K^XIq<*]y[vyCFD)Vd=% Hyq`3Qw+U7D h[|{/BtsΗJQQ7Gܡ/|-Nrg3Õ!8cW? HR8\nOyXo(PVFXq6dZna~(ie{kee- vZ8myVF0:#8mHZN[\+cpIbqɮb/_Ď91uD3=lI ,gOҋZßmi'n$_ȣ 6Wg* [Eg>11 tKB!4F0kDGf.1(M7sa Zio*Ktߖ~Fi #XzӅ<:$z!kRfuawe˿H |agMRR xֻ.9RFNd9.Y;3g3*Z%O٬.3 gKגMt/ge8h8<:}m'1)X@1iJ+ѥi&]$g3fTRG1N|g칲zqQEZIu)s0/adXۍ 4@MNϺ(IUgp>KCI}IgbCf??ٛ2pH$}9K7-[q6)I hM%'O[ľ}h@y&{V$}8mޥm\;7ͪ ;fa.ίt[,D]d|6۽c w7H}~%+\ -aGNzsLZOJ|i!#gdV:W]ч/5R:?V/ .T=%vsiZ.X$ίIKToeҗ8]npZyovcvl_IWMeYQƲۑ^n846)%>O6' e=zcoz;޵<=ՙ2㚲YzE{shZp r+C^p7xvnb]ʦ !c96;1hKN!_}N7HaުGVC~hB]׾BL~e-> \kbGKϜ/tf[s,g}!A^%]5ִz\}iu|j^y*'=asJ_u& ſn9NVT}yܗD~aq~sx؍KX똢nss4pfOr6}K촟Ve^K4HwՒ*y Β=x q^sR˜L w/h7Nj->؍XZ8G/㲷]z8I?ֽNð5[]Sө|jkG0)*U suSRH,hCsX73oBنylZ~ƙ0WMSC Xc+Zp( Q%\c&6/|) 2؅Ofs݄iA׃m[Z|W2NOѡvcdj쁟Z-p?K&oSЬEAǁH"r-[h`:EHZ?`Ի2DG6QȌJUI`~!~2 AFcRP~ y%"DWDPH#dAD04\LuXk#yO W$SwSjcaUf/X X Ƅ8\,&u R%&Nf5R7p'u K CE '&׵X%y($1Rw_*52Em rb-\&뒋{i^VxQҴ%BbK4.ۉb}OEQci ĸp@D,ǣ5/d4LnڢbYӯ/V;+l9/ R]%:53g[) ,i)t^=HSƆ$0iC11Hq{،`L̻iҴ.aa Ig'QD[pb΢!ip}+Mֵi7M 祇;ks )@ g.yӞ nDYan^&K,~hLosMQvA3CӞ^6C[8:s'މH姞p;|NEw$Ӏ)i^/7kyۗ $9in/4~ƺ!縶rd4C_ǘSJSrPx\jND ݋eg@C8@]!y:qW #0NےK0skGA-U Ƽ@@N”k]S6GCVp /%Ȥ(a¢.qPHIk,9څ](P@1ݠuٮ3|jxa>0U2A%-wvTt 8JV` CH*E?tCJ !d-h| BVc5_7^X d+p4 %|% }!%D0/xU\GGqKan`qmcLz))"fHαg@zRm5$2邴֋X0krzT/$*.$)6dTs@T2 6_Z,#j3j^Km T2a mqޒI@K7٤Ia%7I&6 P=V`/š ᦫQ\pgg<#Z=vi[,)& LM0@y0.\vy3 ZCqK*-GR}%4qTzMbj~/""ҥYf@]n`2a~U&0`~Mzㅙ")x~- ֗{`}{Ӟ$ޗzA+Sh.nNa@"/r1u/l!eZ2Ϯ c*A8ߊR& KzeO}Uu 6Y_w_vuskzԾ&'k_J^z _7j1/|+WXzam/o_!ِ}itG oz /͗7u%T<jIӎS<㐔^.]%S+pq\/ _~^~lzT5.)_e 5O2/.Ú(9y[[ l _rܪ;jN;xBp;f@e<5 <^1J8bQf _@n eumXr:)0.OL7/[WXN"hX˗m8Eɋ A;R9.ԲYUR$8Pl"O|3i8{ݢWx1tfX$_rG;]uA赻%ƣcئ)oqa[~T#p][K+|/!Ջ|[9paŁoG1HCITsPm Mm8iҷsjn#?x{^4qez\n;ѳ{ /c͋mmoTˢKȐυnc e ~A?O^ߟz^4ty@y},%w 􋝪OwHcjT,99H[Lv 4IS,EV0ڧZ7չfr/mw7Lm=j,7ڕ֍|X;'~2sL(.֝K$~hk_c}=~*1-=7/i7'* bq8[Egc?m!T6_I3ÔL1&;/:CU<.aU:=iݽ מ (r;1Z6SPq =/?.`xGoμuZGKԌ ӌ[#oߟfk藌iYAf @ @Yqr¥mǧY$)i{ qKMEX;(CG$o(9O ֹA*찠 y,d:EbIٙy_D_nL&LE: 8Gf:ZҸo6$]}lM-Y:em퓴n:31q<^R藤4il덋jK[2|!P KA`z%D%3Y_&z@t3%.̿~KE&$abIJɯ TC=IhX t  R I+B ~-W_A`p9 LR4nz,Z *1fWyNkOVP(JAj,p3q _CIjN[*(1$(BTnR*:O %%xAV$>I ~)(1g q䴒|_}>CF’NBϱyY RK%FЧv_ sr ExDza{ɤ[K׏VU4T # w2W×Z7]aS~ҜȊia(ak:B'JF_4$48ٽNnX2QSߋR8m:rlJ1tv]J뾀ugi}+ Id+~.`& @KX\BEAsaEz.[)qm.cb.KUDmJ~}lڜ_> Km6-vX,ڌgIT`R@&h.BdQJ cdyP,J!"%n}C"BϯӄnaS̮k%胮aAyEA`kN'z Bҥ3ʾH7F,۠zn"TcBPYY}E%nc2: 'eN߼T!DZnVw:}[<Մ}0_XÂnu\'[rVYsL/+pWiQPHaaAo;|;^1U]%M~ 6 z\>$b {2uYktUxY3*q,}zJL) Nw1{ꫫcfun|!mk,}cT`뱴8Bkɴw+&y]v| c>VQ繍-@łCL`؁ A QGڎ0GR(**@چl%}0TlЂ,r.Q<#wXrlc"J,/b~Jzpި8;89\ipZLERB9ޟ1C70KY.0A; lk5P/i :` "& 0aEh+}DF Xbs:6wTyJn1FQa~U8!\ ` k bϖ1X3Vu#jN/BQlv"5"( LQDqZn[ "jb@3$B4#iqGuj&mw~75z vAT'ʫRaaekbAy]bZ<Ī duӍMňO L7*p{SˍK;Į]7h_*mZ[pn9t wHsc[ӐMpdk Gڵh-cr p% xT8i#Y'w7ښ%"}Q~&190;bsi!K;.w[Ot 3q~cZ2hbBv`"{Ib9T7KpM51pQpdkPڐt803E2iWݔT7# ȫ~itEf1ȨSA(3"T8n M 07& ̈ M\ "&VoZ-`k5moi 1Lߛߴ_b" Xb4&i'r(4Q 3ugM?Z0l%Fpi b]M9&K!6,x/7$_.$ LAq@ (9j߰i6p+\"HDi!b"#Ǘnj yebcl3[yx0v0 bfFS`Ӎ~9PØ ܴyS|N\/44#}ǹ}pq%b1}@q<$zSc؏iƎ[sqH8]ѳ9t\z^A[%MӐֻm$.Bsl%9KYϾ!q8q\{w ؖOf[ ǷPvlш!=,Tq|BQ%VPDڍ㛧Ku@2k9 97Ho( !߆=gq|Mwmq|)>%nXMj0v!@҈!r#?:{_So_ԖC"yygO,#$_;1XziZOggrwmː"MW {M>w7o5C9ZC#t!j zo,6o>JEggq|CbۻXmn_q(◥ugtyzjG~e0rO,>myǒܺ|k1qC:saJ ܜ仜=(PhZ︞ 1o 勿e"Н;E9mmLҝi;b= 6H&_9/=-$A,'Mm)+:.[[e _ijLV P%qۥU0!.c) :S 2AD&oZo _ OHlAp)hvs}6uJvmhG„ ƫC lCo lJ`=fXavn`)XRU 5#ȗ1r>lhS.4ե~J^!z[H=(% X/Ť0PI>FpB~꾔 ^\I*];Ś.YRRz{*!dd9aFW h~df"p1 s&.>iaEB#"؀+‡khW&iz]0j0(b0fe}aDI꺵dw/KYEi"pta4C1Q{,A { o6 })ȗ09e ~@b JtP\XNkRdr5]C! Xsyk8e P̦ 0^B>>I WvGߏޤ:JRwWkw/m?_K=)/nEν o0$TҚ`e#ͣKwY C{牵\ㅻݱtq?ڷM)|8-zyڷ}gWxxq2wlr8ouy3nFt6vmiMmzھ -mH؆<[CB:Ђ^~u[ۼLJG>Ev om9 kѹWY;[j[0Rqt|{5W"*:`ٳ} k)f˟>EDžt)?Ryg}Ń.J)\ȚZxI*ovӾx K^1ŪJD+?Bp Gŭ vz^弳Lc /76ΕGY`\B@+B$vġ6Ӥ*}^  }P`HPv0N7m|T/t%OcwOV .}>[2s0:sr _c4~7oL(k98h$ m[€~$t`y 8|n9P*1Gh,n0< wJ  ꕤt8J XaD LbN! K;.%}:,!xvň^.ʄr &D5P6> X:h^b.Ql p φl(qBl;7 $\*#8Rȴ|H"mOJ\*1-mĄDfT$Pr#֚Fu %H)R8P T#Fx6ӆ@M&u)Id"Vb}GH bhaV[*1BML8/yGJL\hO\PMYri`-ޙ<,mKDзyC D*O{&m1Nd_^7 gz%9kchƛUbx܌-icEL)AF6n$[M$=$qcU8ݨȵi@!ե95Źܘk ijqL۵kN'KzdkzEM2V#6W.SB\>ЯAӡ@E@2F9<K!]1g]HNCǮ$-Q}\r1 qu^K<67A3ǺLShW֭a %|.].3qL0w."x.\>8o Kv\| ]CD;g(w:xeVcIգe{m7 BiKZc[{[=z.7oz#աzC 1Gu8Kca{NAv{zv3OeZ9֘A<,X6Zڅe aꍢe6-i߻M[,MݖH% lm(:oY' "o9?iśOw9a'P{L6W8׊͹|ߡi9ݣvlrcZ*7ns*| G@ach0tmS KxD,*mZo^⒡8'k PHGZ P< %y˟eMk;8m Naj~*H΄=&=uouc~=Oy}0K|;FB8.;5" ! CCPqPJ0S;a 2WC@,]&̤4h(2T@j0KC D8 |DF/36UU:>JeW}⛳612i^U7hu&j.PɆk{u'3;4X/@d`b#HR}+՛B{%?ڳJߛ/XkOCeoDǰz2Vo6p醗&0#@3izi|sc T~j/|ٍ,E"BJ&8} }')tM #"4Lxiҵ_D"14؆lf쓝1K>덊֪); !xi[: ʨ&b`/H^~,Y`THArNo# `6g9oPd892$5on3aI)V $*c  . mk#ZRI:g~V uQ a,IeEUH0⽛JF)%2 F#Bz I?cɈLJ+?!иn!LIV] ",~6)M-@rI dfٕY*R.HWD-]$`ж_wNL|"}~\o:Z6ZRO"Je]g*Y͜tX^%wXR_ z7Nf"J!*&9L_=Ko!a#`| rh.${,>KR+._t#b"X/AsmF0-`Y8mW,/y@V.Q1&uk軤}y̯Qv:%>a͖܆nb9kڝn^ i~J0 iĶPxwv ^g{{%k\T麂~zUP0wJ41zY)Fs(x&Srlr3K)GLv>{Rlo-tڕY''ޛLHiZ[ڮ8)鎟9vur8rFG60*9m;Kͮ9L~T0nUuw I K%ߌR %myvSo9>COa\dZuoi>R&osw܆56YA)1ŶA9P}\n1{̯ѯruDܮ|sK˗%1|̡/u|Q[ qmeŠ%N2b|N'B4 s9 h@hZ RKڊF#!ߘx!D 9Eg7GlGy jI`*0F %<]k\YV* DSr9W$6n Ǻ! k x ‘*+E\Yԯ#oJ)H&ŴE MvdiM[4 MbFfF09L/˽hkMhgW h ̵aCXq8ϴIRˉTZRaqp7vrv4dsǒvEiC60,_JK'.QipcYCsX?L@k1sEĥ!2,UG84?0ĠW#t'"+rebl93m$Fڛ8DΊ4LKQPo5(fmZ;y#fԒ؏h-hH*1c) I`Ig ǵА |)v)7fu Y u Tq7xӋ j=96̐#V&T2+ )1-h Sĸܫi"IPiOpȬ^PøaA9 Kh{a/Sm&'o,92E~N14x#/v?i ~Nj&rc:2ɟ.T*[ՏMڔ:ap#J\H)){_ɐ_o۔xꁵMl9%@&F9'KO/ZOT W,caFև^L_A8v%r'K/EӾ lj߿iLpsG5퀚+勧eCO6qgr׼[e<2}~ڶMHq jMv6!c嶻x;2|αnG[`_aǟ9'E'5~凍i90˫~)d 3[WOIFq߃<ڠI{wkbnhzb9oo \x/!7s;5!OЯǥ8VAۼޯP C@oaM`Tbۜ/fW-k-e.lZ}LbRB$ݶmioEMS6BoXţIJת2{K ZeA~H6.36Im];(7ۗ,:l<0׊؀ L7ϩBqk{ri~&bsSSuU| z/mj6Y.`=}juEC`4CrwXp};.O:nmiq~A s\XcvKJ*\ ssXH[_ÒbX1U&`<]it"<>狒d\[XlBÞ).uX+[b Ʈa(UX;a8 .Q b\6WD\  b8;D8Q 3j Vj&kº FQ]u ~DDX(:E@O=3R}fbF pۊF}FiSS`J)zRI0_I+r"z ~h/0.Ϩ}H4 qBIπ ~Sk%Ik J+UXdê%Kon4 bXRl fUǗɀ ƹ_u19Ie&+u^V!¸K7U.[0.~/o6/ aጒ| -6Px1L*b%K%+im_ǡ=K0 #KZIk&].`/.J6]K_[L^Z@\wo4/F-HvEg]U]lP< ֮9*0*1Yiv;&8^2,kal}I XSj+ktGV)vJߎy۷~:1O|_ԣ-%,Ƹ T=iS}8$SK´Wy,F,sN%(?c7(QöT)Q^VrKcfCSܪC.)i;vU[< ci'?s6*kٙ<%z-1yV$4D&bgx֟giH(?UףS[ve x٭KY` I͇0MS7yX "L~CL/qXcHv93<ssT "< OĆ0qښb1LaIT9 fb-cUXC5kUL<קY6#r-wTFx`$☟qb^VtC olF"gEDQD ŋS>]LXX#ƚU"0n0@Hĺ_H`,qo a(hϼۯ3 <ΝF%9$\  T l{j1=O",0e-=_C_TƒvU>g j{:PQ}vvsߊ_~7w*N:D"׺1{ |?3=puCe顳i26FS]| Yb_4i6#F^cjŪ۾*R/.h9W+%A {WDF 񖊖6s'mwi^ƽ-Ƿ%zm,~h1)]acM "L`K\)lGcyb%Y Uu)9U&d-y=c7o%Xm=J t^60V?>sA_F Q0:Aˑ]{Ÿ ГD¦VԕPuhU mxI_(ِɺ8p_֒QI^ҭnX7 O =I_>ziS_K3Yo#T2 P9q$k%% 0Azej}B,_DUpxiUEhiOw33V/r9sR/zH0w1A R+IaUy~61z>?Wo0L6e +|Cl0`cBO~ E&1&ǃ@h-M.Ym^q5A,qˀL7 @ptQjmV/ +!s 6)K6s^f MߞE]*KPY 7/B8>˷}:4H:͝o˺u{$ +ifM+4gU]}Ix@_i|czgQm Xjbɂ(/Uy;HguuWV_5~*XDZbǕpH!9! 04w pN]"Yږu$@*uK-ݚ|-,ȵ{zX/H`J->nRNn`H-n`F߼v` p-9eZRɗՅeOCZ<;]y[W8 "yjUab8>MtV8;B2{]%P8}1'q]6(?j. ol`aGsu=$;[C7}9J\ 7^_`t]SX85x ߭l[W]H[.Z'lC-p~9-wF6 0ET&)TLOvmm#vTwjџQ,T` [ t9eo~(KP,, g+W_ ߞ)Q!Cǟ5H2mFL."mbVd7dI@KqAhEaftc4@HvDY|F؞ɐ܊^l9WMLa"RQLYB $xFm+kKLu/u3F ih"(XxA%4J\ w"V~7Bnug k$BhlE$7q/ {INP2ePo`T@tTڀZa1 782'c LL`- .͘L6 :9$H>$TZ`sy/nD+өG G&0_hV8tfzP/bO?c:cڭ9ɍ@DL?1V8s|+h$lfV˜|24K( q34A߁8«f1e/!ɍȌ& 3k819̞ gd'n04Sƴoˆ7~ц!amX{O7 #̢{DD ezO'.Yp1C13!A5Ā"+;c!p*5U$1MM#j$r|S8R1ɬ/XgXJtgYWdf Q^popdDig2齅n@^f~ {t#:‘ƌQx@1ȩi0FFkyyf@Y;snSks?f31mȔZ@֩uHp〢X/Bb}]å>aݸx\P@ֱ|Q{3iKĥtG8h]pZ@^,v!MuWi!}/4,sV3|iÚ&|uo]o4Mݼٞr(l^͛!gyK4nTӻm{tW}-yt0QX߂)s8qN^CP|L̯;zۮ9=eHj@ F `Mv,mj,tڳh1#&=t+W%dMd7X>IU^3s:׭0*!Uti-GqQ҆TrRvne7KYh/M-'R1,iMI6vMJLGCϴg*l橴!JRr J 4s\q׈gsiĉ4_5Ldd BL:#P>p|IZW(tŤ~3aK=mv*q"~_Krɦ/PnQشo%/t]L%hf24sOͮ1:f:ճTk0hvЅ@)1S]JF 8G(+n1qOjLH6_DXgq^M;dN/+]lt;ti.#f(&J,jS>Z+<1qMtpdx`3iDVJg)2DsN ׅ2ɵ@(DWFpV7py"oU4֪KLM yzk|YH/ZKVEDcDt.IY_>B** >"Ja?594gm2 qUhV2I?m_ٴN~/X K|YxI0* %j%M.qOIVdZP OZae0f**@cլJke`gi!f |YVR/v%Ϋ]0זT}b)]ZE/̞tn^/FEc5}{%2gE̽V ,R%%]$ Dd}"׾qmaE-0bd4`YhnuTś_k_K{alfҍul|}ѭZ EǤÙٮ RV߿=eQnod^ii篤wg^5~jZS4xHwǵ=q>׶tP&^:1ǚM\H9Q%=YN8کJ*OteKN-r:tޗ!yQU0;l^8(cH tԻ ^Rog1x-^v^MVinf1/!xuy_ړHR˲^a紵}ePT㡅Ѷmr[֏F(p[\߁;]AAٽ«D4b39}nK uP*mE1P"?{VFEƴ4=0dtNg/6%sɡp"BzmkHU~n؍5T|Kd ۏunDL,.瞀.3["5XTƒ9B07OBZ(ilxmDX9<,}}8"$%h@A!CoP g2H3 vX*nкʴ{!0 wg7؍N$5  #O)mJw/H+bu3F)BP3dv&  # : B՘ )`D$RPIL"l̉:bǧѐ#FO,Uk_L,0$i㊌]"IJTƛ7&^} ZbFZN08-'FۄCkX.(>%/$@[N }m'twjƈ Vx|^sBhbfV>0s kAzR>S'% bDi#A ‘ ?I}@uBS%k4@nIY]ΉYi5JgW370i&A4&rJB#{(%@ JA3VHR8ͯ!X8n{^#1q~#iD<}L/$mJ( 6 W^6=Q2U`kP5 GᐺZ)Ŵp md^Ccin>_fk 1pte-#4͒ l; (<'n}ޛDKUo0Eqⲇs;Y kPpS GM b4EZ% KIiM\ _6ؚF+S D.Lmn刣CN&VmTiOb{n]BfЃ)kS䋻b˧}㻑| uBOgĖaNmdiNqydXlI<1&^PgۇV)9Px]/Uvq@^"g Ø{b elNǚ`悒Nn/y9ŝL1J}[KF7; x)y%.W̬,}K.*|mZZZaq̳$l?j6"Loc:sip6g: {8KSwAT|N}9 ߒCٚCu<䣎 UGs.,'RƊ}ޑOs'8屿  _* c0Lp:8;&8A PDrV(9oKg]:!L0|  @ ن N?;gaǵ>s t,iևni\6ݒ]ՠJ _!!hv<ŘFㅳr :Â9$SU7z*+Xa>GS_s8ES Կ'5v8kˡb/G,ݣjɱ>5m O yvƪ5+Bj O vUB&8YafvN]i]lX*sZx9SA+g` Ap(OzG%idl@@C šc<Zp) IRO0^1T%KC cg%T*` }JJGfO^I $t %_FId5۸,T&6`μAT7Um6P %U_Cm%eW:EH4Y7 6,%/,)^JaJ*4#zI f -tMn{Y>ɘ.aa|.vIWPKR`_oLKhWB>Td=ɰKb}N`R`.RaQWSߓmdfhc:1BɚG֪G-*:7'd~ `}@MI7Յ~6s`9$}Yrn>`2xR>In \&('tm|50`%g~C~66$ |\oRgmke`@޿HkO"XShceuTX伇.JA~/<DG[İ`U>J~jJp=1}Eg)@m/ 6Vk ACX䗒3pw B*JF)٤d9$縷 L+I鵖t Z8#T#hϲ+1b ^ Li *&9c? m60аڋ:@A\/"}&/^"%İyggg1 +0 "\1p3/KRHVd_y w!YUyEJfOV VYjL?b1ӞomtD@4s<ץ"{-t˰S~͔9 J)f^5 \9,ǒ&75 4/髖\ߖ`)l"}1*QCz)~4+AX1c-ƽ_j^8~=1֤F~4δs7y< 1\\-Y⒳/"pjפt 3u|ͣX4; EP#c!SFXa*<!3A'-hąeO)>>k*`D\L &)(Jr}"4˧6Ncvn! M= lTxlS׃1[liSفvaL1Nl7o`Am88B@@RŒ9 g^Eꜘnsm }C84&n^wRYj|Q% kJ$,$-[%f,,pnpŊ.8򽉫6RXvՍLGfq ڛF3ԍ y@oZ|K_ Y0%oTa#5İ*,9FϠn|gM)Lfq-@G2i1p-,V݀gy[U7RMLX[L"^4dDD!.A,m[õ A, }6g `ZIbī\E+ScAI _V*-5 XjN\HE`g;U'lY 7gr+L 2#nh+-F@*g/!C~!9s P* /p WFs 1Xäly>O`FU8߰&ȨidELo+.~)oo1o$O⽈sRmnY'.q BgVMLAF X,\[ a|*^xq2LFu#ʏ4vBIdG :FٌCj7<!{/#%BӤHX8.= (jfaB1Nb^&kwS@{˩pa(}s4`KVoO{s| J0n P1ӒAlJ`~&ɄbEE?mUG3SS ^/#㺆 ɶ_4}.C2)ݳF2pc]cvm5K 4rc\ܖr Ae2C{{9=~fk[6ɡ$V(☖5g_ 9tڣRz dZܵD1[+-uxprshաJ{/q1d$5ݿWdKLS?yqϔ:ξsŗ׎ccx>I=a ۀ\(On8ır+SfY޵Q)'qñga_}>~R=bAɿzyF}Oj5U~??06|0 <;ZM0\pg=rA=ŭľ"X’y-Ӵ8u_E< 7y`+(` sA{\Lp=kڑ bkidBBS~[,rl u|kVH}=Ka, 0@Q̆kdx'p!5cqjk.ɍ݆\JcWRLhMJϰnPmsA  4K%j`f16Mo'plTG7H-NڂVj7ς a!*A1 KG ^X9:f%`w0)p *Q2J =-SzOյ taŖSm&C7tbќ!WHMiR!؆+x{o00,5\wg @[Ó8R |>5~҆WPc`k뷕hdC- \Pa D t } X-N=P(} __pE9\¾jjL8ABԑ(Q Kx=!jq9X Ш`3ĥ %0q UɂJM &0>s١_Dc a:՛NzR@LȤ&zmDZ{WɈ=i{ FMCmF)so`bmWYY>i| 'G[g w]U=@ty#I$cj Z)[ wҾ`i؏^2[$p,Ǥ`Ww酶3at*œCk=)ߐڀ67}㲺gt9P J3Ԫq9crfBXg8ɐOT#Pa3TK/!~_bm%C7/L ;ӥU\$|T( 7fuKEdO"WR"ЕPد%% 81ǟB@ي@W@CNcO>-[*XgJpcI + [_lPWRu0PVNAkR@TR*^%19ݤ%鳮 ޾^U^]I R i ap|z~5E)Lip^#]htlleAT2( ]VpTr~oǒ-K^![^B_muO}.-6KN_$]!yw :Z󰦵ZI0L7t.u>9Iu6)+k7)*MEIG/!z+U^v ْrº.9%]u髴ӱpn9=YL's cdR ҹnצ7p\p1Ȱt0[ߞMIv<dw8α\0azp{j>p!`9~3E]p::zO AfAe$*N{IQw BPw(..] ߊh-wr#596͉;͕e}۸4MmdX o凊3 V(c҈ՖdLii@C E C,{fSLjkog#ȥd|Hײ-LWv*DO6Y `];T".1LnFS}{R7X4`/#1Hn&46unMQu61ƅf)(261q\LD[#v=!Ql vq=!\Mjg2mQ.z2Au?ô] YiV7i#=ZNRѓ a/e`743AgM Ka7`r3rg1_.8F2jghjWdd SDnFrB+5aMf&u5H&iГțV&Zp׮PiB5\89pi[k&h,95Q|s0z)nsokXsqW&%/[<n+~ݔ;̅c9InbX~9Gst?MLs GeY/j?OA^,M_(m|6 Z_^8Ϲ*yے / т\ި^byBKgKRd:hMίy]RE؝~E&RF7#(.ܕQ,g^}Zfi˼sE~''2x.o9&x_{\i=9_/<[[ډL<㵶d wܵ%CkQ&U(B[CBihiiۮ]&[]k8SF;mq[aW'NPVH1ui\IJ嘝B'ʸ A,-甂g+ !݁=o1@ݒ%m0H SَPzkUf'vfi iXPl`M>bLH[ZB@7Ι,^ik5pӲvUD !Ncg'*{So-<.n9t qt+̀\unn\T Q9cSo V'AsX/d50ja\RRcHuV3 1f-,-˸{%_ 卥!AʻB߄' ᪻.9d95(Zb@,'Ρ(e+TPKpi v|*fJnEø C8D@u.ͳ[X( 0: A.$ H 7 w='pn$Й((qb >. D!JF1m unB"tkOARj,,2H!\1!JdݤjG<+!Zƅ f7)8K^5]X@ A G*P&]Zr o87i AqېcCfA12m:sI@#}d-Vzx{B9S&BL(X\)񀍠зpF*2M9n+Ɋ^M 2 L! {!wa50./Izss/V-",U/b^{XN, s&T/m0̀#8]6},Ya_1تש'MW%xYɒ(~ZEoPaDf]z$]|L6IhzDaM47igB9_# *.p zFsSɭ(V.A:\_QJT\kH%hkR}`J6t~v݌S'8 pjCHW 4~M #m~0ykK>iʎ9G6I [޾l!0YҊF4 m|}բJ X5#ͭ\n14fU:lOPUj_!ٲ۱=Yi.2= plOuuUbN~A[ӹ5Zδň;t7kzpZE%YS^ڛqP b8aCv@;ςꡱ/CN[JO?husאOZ'ݛZgo0v9]m6NӔUq̧H%uwMKzYvzΒ<[)Jڻ,'zmZ˩}5>% 1<SZUt6gq):QyzV tZ/ƟD86ư ʟD8ݑ8vn,kJ?fs!>sxw='4.w60t?sig'ǡzuX~5^[~W?~7gs'&y#Sa7mZBõ,K\͏˧79Xa)%0U ¡"]ؾXZB8 "LCQi,a D˵H3}v)zNϲq֊?Bڅk|՞mp՘L,0E2-\Y~Qy]z!.AxX3z˳ L\rcZB2e\+Efڹ$ke;vqln[?l͌q^4q}V EU9c%8 Xqk%oIc犒Hxs+/Q]Mlz("h[ #ƳP AbXR6Gh*3ϸçxÜP q̱_jbQۨBrAuqLУ?FL{4;%mlN-1Bq92&Fo5 21$ 6h @7s৹6,_CBh1F8D)5*IM3%1)MLLJ6 ii#T&{Uc b!YXXk9iK8\abZ4I|Vqމbjtz]Xap3Eb+t/Pm( FB1L}fb&%Fh0v1 ̬‰o,ijڛ6M? ՁVipwrm5q2ٹv":R!v#3?q!pc$} QӼp:[ӌ,m.1b%FCVtuI~ ]݀(Z;~wm~Xx 3v=olجE?2i͛Ժ3VF[b뮨mnkq7c!uHb:q-[3C݂r3dj-9ݨSYE /k9N"CP}"12U&kŚVhx|I44C*<ʹs[~)ܴέnX_]ڀV_4 nՍS|0 }3g>zմ14zw6ey+\Xw,\L4x,º#QH˕85Q@7q}kyNKlޛ5$CVᴽ; zNNH\O\M.ׁVdf$4P Cږ1Fv.>=x2:in\<O}dΊW⪝s dkP@w12aP)mzf>6JFrJhu, poKGB"ro-H7m,^ 'm Dl@ MS^N-@N p RN:pi^Q⍕o\r1W3E&SaKs&8X84b [ah!'N1mIW-v+oN]8g%>ENju6)a^c BzLG:<.ҁ %Dr&# gJX[G`~s[@1M=\[+X .^DCϋ~L؏ p ^pgO0(~Yq2._.)L=Q;N }bT28&>zèֵy0s}5q5hc(`c|~v2 aqEܗ#@%=׀KOq<4n,G㑤 tva Y&cxk:7k %Wuζ7`@ϸLC[ت*qZ q:SP] +׏rֆR `>~ \ ܃[1Kֵm2AOb8TƐGB,2 [sj+"iXB(ꍊ[[ ؘac ܅mCh<@K ,ˤ`c).z ]LPdA(I"<lLPd[>/:L lobQ %#Dc/(uK`#Hj$%]k&Uk ~/͔\;Md%22>_ @dgL,nõߖ̺b lR0W㽡|aze%JVe\lfs)'#ҕL6j@0u/ݤOZօSs4%i^NA4&% p:2\Qj٤~sɀ{SL~=Fd2ߞꞥTتK@Yu3șp0p#ʗtEw=Q @zBD%ݭ@m.@e ޸}(2%ժzE_ rf^/R V_FA%\xW]YS/` sQȷ%) CZ4Fޓ.K2`˼o E*0]C5b%]Az40tnw]+{zFb 8mFM:(nA&e6VOmJH",J΀RjzUvEh@3N[lXԀ$͉p|7˩vTnn3LmUr&`6@5ju#U0Sg4W$~8F*f&,_dFoD^{0/%g6R" /M + o2WaAC56Nfȷ+pMAښж]/b4@ڗ8=v]y"|$61!/ڒnA}<`tJo(_\[<x,؆%/ӹ\'cIOP]bmO_?VV&]ZZwJ'O˜-<asz3|{ K^pKqmլu~ֺߚ?=>&8Va̘˯-8Õǎ)u8۽Rie2tmi'UAz|< l-7Y+>ĭED l OVn ' a}I|V\ 7W 1*,CW }$w镽̇[.!qGv04朞?7)J9fgye?,kͱg% \QǡF q(bXD͡Rna_rX*nm$Smӫ8n 8 ngH0(ίbr -(XQ5>dŴ LDFag&eDF(sѐxU]Nj866{ښeESx%l;e)^ȫ"j4%,woZؠc^A/-g^Kѡq>\? SKkL-_Sa[hnAm]jpZ{Bcpg4D^s53fk^IrX)-%`w#x`aVΣf9wF1!T "׀:dȆEK2ݘVmbJ G@qzH8$#_Ȏ@q!3l I/b yAe)6wpP(@OE0o(Bm6ɻXG#NObdhMcS$RmimT19evlRkLnijω-mb $LQ˞e/q%XX-@O+KpU41jp~I}s MJ#sq$vBo <16-~/&LEvq@LJitu LL+P8ic,1gMLXN: ڜDӼ0_4ͷÿʀNLHO6ۚ@2,Ѭ m{BVR"NN2'사m\w"J җ+DMH"[%: mvĈvzG? ?,}jԪmD{Y+6Yo v!J%(Y|CVh][XQ~/X@ޘn|1m|HT.<ߴ)U hR>IlM#F^p42dWdkF$?EmSoNu16f57w r_p@'u4ꖷ³:8\1@1HM} *)_sѬ};{[r+@ma67i㐠9TŤmL{ Y7s R/Z )τb}2!XY[[o*SX#.i/\t70mTBڈkm ,sXs[[&bf`*zOݠ^qk5- 0L{>*s)=AZcKzVs}޶i_et%X߿i c~:uuoSX})m>3Znjļ%H\jv7q!0 ,a4Wr4:^"K:/xϤ·X3S`%6%abۼt]A=P:u[3hy?["lݻ-)zwJ0\"r_]i?==Yeڧco=47pG۩*|<֣fڱ,'_RuZ4$CKݼcݓ˷Nnfy[q%F}Ui9s *.1mq<(^ t\NZ./@2 'bOu|GjAM[-ՊvON[q(vJ0z5/X# 66-jzcyY'֤׺10>q;z{f^|ߧ83u:~\Y Z/ 0OpSWІ)Y¡LՠqЪ"$]V!+C:jRu踷a!픶[ӭ" &1mI>ސt؆e l:jJBùbao19>?\/-@O'9wšxb 0H5QrKX9 ݆ x=kH%~k_܆+HBaaC@eXx"H}&t*mm:C`9x薶'z9)e5/r]SPQջ񏝙RX0U7usA7N^ )x?n[ +jw L4tMaNAC e0N J?7X}/e`ԐO0*˜i_`c#V ?P@ܣ;OpSµ(T=.OA8Gqj Qy4iqLY*zY V]%,.3Y;B1RZŒHQ`95D4aצ[kV"@wf]SZe|PP/MGvEa I`L2VӤ75:[b& Z{) LUJv}?u3`8"Y K:S県MS 0}%cR}r2v d%&b5z)Y(P>QKǒ_:V] *xΓ 0%]C >3DK.0FQ$YWoj>,Az~/!! 3 # %ZEAXM@6~{dIDcL@ 8HUktCFi|U2OIJiBcBo<ИL|bo+)6 HN.HF(Psn½dHei^BўA_D8g'MR/ u+ &w~/T ɩ7d{%}A{#}1"|`U^0f~κ JNa|fx5ۀ vR/Z-:eRJ k_IdRoH.٤Th[83IfEҥoO[N:GIK;yю_TRPW}[ݕLYaKI/z_& SV]Z sm\I}=bSP=]pέ7t-IlN{+3DkWSanނ$auړs"ߗ$E.f4's S+q\ީ)ES|N,2%y86C-ql </zXriy(t 2Nw_E`W0>.T>6!yb0]˄kP֡&Z_Xړ2WCL)!nT}8|FR%Ǿ_w97/ylފPb#4.*88!")ut 0:qJ #YǙ\ĿpF, \__gǕ<[@?~&qq~F[ N銷0;lwlQ!*DP_<ς!9 jS< 4$qwNK[Ȟ!'K[QH/bao+\%S .>0K<Ge''[(C{+n-((&ǂ0'#4mqD~` sqo 7mY6A`.TRcc3M{qøl Ω]S]x[⏭ .S8}d ~90{[ֽ hiM =₵p@)9 q+| +[2G*V/-Α^ï*ŵZ%j怤ޱ\[qPE<-+8]R|QrC0Q$2#,LAb'><ބB;PD,#Q_+Ƈ h%Ft Y,ђbʂ\\H&,CF҉ 񨈅EcT "ۼ< \&CF9k4M&Av0,{Ƶ1m}m{׉ĀGxf4+hؖ:*^1oҶUѵpS&KeHvnW1Y*MbZ]Xc+[L M3biĨn7kgG+nk&6R/x\6ڛnLy ^(qlޑkN8-@<܁U>|BvsoL782ds#%ṣ Q~S`~XhVgHwH_X{ epW8 I{iTWJ)x[6"r9&T' rLx+hOp~yws~Xk.k!qoڨ~*kM=Keίa8AlwwOOݹ\s<.80c8ơ/[~vX*N:* ҩ g4f{ǶǩY}[v߃_ آPi@pڂ,@- 2/]U0+ tV16>(9+țaEeIAނX%qKk^)sIw ;i|/Ʊyz mbX ?vyےT`5H0Ii9:!]jq ڥb#JA!m<2Z,P EX/ 'Pd`2x^ 0IaJ0`KEbI*D%`!,gn"BXpS`Ч'&/xZE pG 6P(\tVLQɈ%)`qsEXefW$:aZdj|Srl6[Ii"CHԓl¡ pb,]AdQZWzBg) i?BdILNsDmLL+J&ThG&zc9hXvXe U2>Isp$E"81`qGqR А@ 3VY&@=Z,I IeaI"W,. #k:OV]NϺ0fC S=Z<] R-pˈ=]j+D5CϺXۓfjvڠvkU$}5^Z(_}KSH9TII&t}MJJzr{ 1$@pb$Y%`M7h 勭+9yk."ukMY,{Lh[@k.|ZR7(ćSL)jv.(JV=cqUPY{եt}˞IW$P(,sP2U-xEs~ |4 k>9 贉U#\OZm5PZM`&[~G6^Jך_֭@*YW97>m}WkOa]Iծ jH O۾7 Q^],JM[}Kn_kzFϴ3zcu}kSQsv,hzjvd{籡u8*]cm:WN1ߵk'F_YIɧ?gkX1-7:ڭ}=$u6u]3{H|b#րn1%HۺgvUD G[,8n{qj[ 2׋۴x꟭qlc#:bu8NCK43ϘNҿ XpJv+8%f弴Ƥ¦ZKvh):$6M噮ծOKn뮅O8KW#@0a;vHjf>NJ`]Т%Tx8C[~8pYOlTںR˟ o)'Eu0 "T:)ϴcU!)_^rq[ZQs$D!V3?޴.\fg,S-h>\<`< j-05(X?8RX"2'vuh8ƒ|pC sA|Mĺ58Dm11]cHH;٧e^ˉi!+z2Y2iQ+֘paǵWʂV9P)"l T /)D޽@ 5^0FYnK+ j9 ?sB4C֖_8/_DcLHg;snTV BzPU{IDAM%Fh5ZK5i/mR8ܦ64b%{ڙ` & Ŧi~±Vw-ؗm (>ބ8< 귻"S9Fa%%F(?1LV&wM GqVݸKM/kn5Zϑ+1YEXnp6m5mbcHΨm̜.6q{G<2в M4$I,ޛ!Sԩ8ЗY Ǽn2dh# s,˸ͽqk&1/Z[И`=w9ts|YĴSmmk1f!ϟ-&6>鰺Q[GS2w ^SI1&% 9Y6*{1Pv%1.m.xd Lkx̗7~{ o<&'*0>/K]|XXlXzOA7g 1Lp$M8g]Ep"4ؤmI.q%o(롺e\28aglZi8뚉84~9L ;,S0),҅T<-m[Z1TtOa)( ҁn!;.8l`(9ΎCKW`B|?% A Jt 0$8\ |>?&69@USM?S K6*9=ao}6 p0~ӑ׀8#hL nZo=)sv.!v+85zz0H!Ф+vح7NiS4Gvi9˸LO F'P7"3d^ulgNvy]S@l,9Ta@)B065D|,i lX4A  0 y@|!|`\U܅C2*ҠAȥQ!IXr>!XH00 H3}N43,0ppݑ 3k]50*kBCBUZ|PM>%}%b"4^ytoUJ[`ݺ7%k|6 9s+6y)V Y$g%I&/" Kة~~.6F6Q ]!u|}'zRNJtm}&c%$3 V3JHRZ q$*J@e q781ؕ>Hy˾-0B!02U֓ڗ.f6_%2H^O?KOA(jOd"YRJz <F)Dq-Γ_ZI~ \-ѳ BDSL&].UN+Ẁ䤒"Jm6t MRHtxi@ d%43ZEEkI+21X /@Gs,0@s-*/,V6a/LB]ж$o1d/RYlRh&O 6iž[hs|K3.I1=m#B04 =]ˮ-^CMdIׅt3.uK&1u+pϺX`ELRU0Fo^O//RxKØ7XSd`2t)qR4оzc\?U-egbBK akyoǙ*1i'ZL5'Oo4ڸg2vsؕ0d^M[`VxՒ?cI\%\g͟81 & "/iT[ۊ^ga aQ|:elV6^fkn9%8qaI;3L6ވ0c9ۺ/z78Nʎ8(iD+Bv0CB8Pض69rIy4bad&ew6L3ЃG2%6<~уiZ "lƟ{o'r /OG$IP॑v~e*8.$_xdt\@v5nm2lm Xek]3mXQlfJߐt>"]\I st7PԶ¥Kז݁?#骈p3E›dLNʵkѐx[ 7$Y cQ´C綿B =gv:[ӈnhZ8XYؐN$qv{]д˫'6c;|k\8u*ZĖI!PֳsphX31}Ԗ'elӵwCv7os#>2(u ըiRm5Q`҇V _cyHb&ѐ1Lu-eU;U}9(>'ՍLizqt $h #VzP_@71P=%x#CK8Q_D &}#}žwk{6>ciQ -aa׏/?^־"+SYS=QiuuKleӞb{ruEOENMziєX i4>E9隊`.>Ɂ=y)9qSjM3JnNC$&J5ǵuZA%8ŕf9%8V)M"a;S9P,{ K=Zny̭xKa̶mN@wk.tf7(ybOg`x[δ"kNɝ1%iZ hfٺ [#Mgd9ޞ)v\P-~^V ^%8Ҷ6d?QnxLϣ{wl03d-&^cl.VwZ楍%xù|qq SD8W J E7 :# 835%+lcDŽݬ&  .78&Z5o J43"a.JA[!4 o@O@:^ KiR*td:WCHa| ىm,JI@P+)!, Rz"[] I3pL_ӅA%IR $(HInc6]AŒ %)]nHTvEz;{xg7d`u`|TȀ4ˁzѭk8H(a_Y!~"aui>3[.5{3Ꚕzz'>c+BkisouU/^=CU,%]tF^#(P EmT %#q a Tŝ}ezn*1U&VrR9)K}+)AHI F_RZc쪸 w$.JȈ%4y0 cdnm4/q.%]Hah_TdX(|jaH6#+W%KeިP]NQ_}\oINatq&L0"h3 ì }UGp=KZ[wτR|ص:K} 4 Yk\sozl>xM*?Z5qM}MRwvKǛmMJ^NRrbvX1ҝ@7n9bnӹFaObr9hNӲ mpJzn淊>!Wʻ%F,Epuugjz\敱KmtS,_qm,Qkݦmax7.~g971Dh:t`BBcig)92Lq 9`7cmo~lnk)bq'9o887v1>QyoԒn!19.a蹭s" 2 ̓/2%cZdaE}ؚB,6R%*a)m^S&F /,l٧?8ֵ/m|gQ;nS? rOOYqq#L +34 ?2 7΍{ 9KBƙX^>9P)c7ù'h i->3)Pu^}7RQ%'.6F"d>ԧnrzaŢHS>Um⸃\vN`y.5ЮVK^[ci9S ?Av " e%6YӤ]$\B! O-GzT HFdi"!%lblk٬bgP:A Msqtivx)Ս MY@m:4 ^jv.5ogkAh+rtUfgK5x)2jP(Dʳ¿7pЧd-m®SXK!_נ7(EnfFe%kP6KPi>Ąu12ekhrVfL&ևYLlr"E{'8髃X8mM(kitO9hJxCgm5˷hZiU[#f\o$gSA]{.*+e8w㖰o)mDOƬD丳޵L/s>up#&=nx|V,9|ݝuZ` /L i&,q x>%Se-Fo7l0js"mS쩸]oivH<Ɗ_jb[rhI!~ޱgAoO^mu0 _e?z| Z‹=iՅZTVyZ"}6 Æ^Nj%+.{LvZv&pN9;-vZ/5){ j̤md-#}X )zeN^լ1 NŁ,J^]n5HKLAdms_чS]HcĊ*]ˌ%1*q3>`,Q2FH8дC[.X:qSײG/׊__-_mr?Kj8S\aFKz'8-W-QXQw>]R<޴#c;D%t^5~cĎN<-:t-1Y]^z:n]kJp%B9]xx/̈́Xǽ#p@7N8{+eFyhd$Kwˮd'g׶+U4 I UDcC%;DdLшu c]5֘VC.ppf}{ϼ?ck ~l YHV:51F+fp]`Jj֧V!eX&fҴݸ7*n>{f%tJ%.0 g0 |a6UGEZmF8ĒtrȮduD5o2yҥ5u3W̅Lҗuص dLq`aG]Ϧ0oR+U %V3􅊛wBl|dJJCZ?>hY(Yg."7dI=)%So£ a99sVo||ZVoյzd8/ e{KgQFtUFPV6MTVG|a=XP*DF&rfAmYv~>1 n,)"I*YRMt"N7r9Hjfѥ6u7K4ml3"*وعm/#]$Хy|a1.,ڻiDWo(3r =! GЈ(Mz`z)KЇIO_.爛r (Z&H`bJ.&]}6f4RRbJnFlLs} Ğ\lbeF乗|Z21{FUz^}[_IN>'o$ajO}u|=~{]w+\ Q+:BWxzi+ 8S^I^ ࡵKZ(в\Mjb^sGnuY +e Mٔ q(}ҕω_vU43Al.fO60y$xzSmͼ(g[y,mWܻICMVZP7?g;r=m[wd~wkfZ>yn?c;;$"š|D -a ɽ|ciޚYaRckq\z ley#sؓ,awc?Kvŗ,ęs7s7F={\[xwi*~6燷'QUa]ayױ]rUpŰOـ0\1Ngj˸$sN p{Jd!Q6O ov  ӆI8e0KlsSfھ\ dzWoq9ړ,d}>bGXy 4 $ m9Rbư-%hECF ![C1 R.(gR l/ޖ,<+GB v˸*qAWdă9s!ba׌ʤst{aƟ l]{cYAQK^Jm8 B Co\!5/V+x-lJ.[yL1T[R g ZQq 7P3kR"# Վ I3Pp/\VDa7/rT(D ɚg(o5_A9}M竐l{[GWҴ8sP.^K X*%t~"M!&Y%׾RO &p%KȀ֍uz%%Z2X,šuN!^2aҊ$]X LR㪗>!IހuF`73X'H!XrzV6s`56c?uΧ>@KJ@mC_ҏE~ f+L3$ €|LK @^=~NT2GRJ*9C_E7+H4L.>."NȈcp x8x1ωC6I!р#%,[& E*u~<0ST2Q~*Pq(ͽlbMg|-a2cj U־sKZb T.xGJ.o:Ҷy躵[,y!IԬ9 /ngY[,:GdJHsEש*~ik}4z O Vg>r)$vKǏ42 w>_'0 <Q#ghrYEvmt<GKaX~aiBqsK1|KQ .킻#F D`Z+ ]F|a("/܊D޷q5,8&e3A_ĐBc:u0WJAi ,N4Ǒoi붠uϭpC)- tJy h= ԐPC9ܱg4vg+5b'yݺX>@ظ:"&1ϘvH\UuMt=jk[+24lzж«8RBK!-Hƴ4/}s8bF+ ˸O{Y)BߐaXñiF vz r#t @\?9 JU4寂~(>aEL,E"&}Jpӯ$IN'&_l-NRlh wq<8m3EӦaCM69 M }XeԲbTʫfM#}CJpK\v}mF6*ZhcRa#S!9Fښ8&6Al ZhBL) 85E,9[#aAw ;Ķ}M[ڢ- p f:l ~mswA*:q>nۜ mNb5t3s2Ƀ(pnaHfA|E61 9=?Znp '1$ aME~36mbaÛՠˀ6tOjA5E[nCZ5bfǐeMh-Ѧe9=O=& 흊"`CkA>Q&*L`bkTfd387:qŖ_ex3 xosJܾ*<_~1"_[K"~~=tBXᇳ ?17%Kkkx!_9Sb-upm{W[@:y`gnzq.lBo1ͭXykM +mgܝq8މx崑$pryujc)/-K<)q{O>EgZC6sZx4aK8-%Ϝ /U"L_86skq ϵ<.Zs)$N? GRt9ܜ!u5j9b&|lxZ KXUN[9$X;x(=ux|᥸ݵ]\8m*v |p+sqn]N 6 -g *NqjTx`V\K܉ssn'Ca.=zǪ4gˑ-0C{zabam `DC 0p CmPB!4ɜ\ 0\رǭ3|8M *nڕI4о4룵 !c}RͥkA 'o+X,1?/h C>9`q5ğ֟p Gt$#I;nҭLh%ZE,U` 9  a3 DpE:;`EAd+`lhP"`%UQ^=}*1/UP{ET5IZ.Ӥ/53ŒB<|e(1IXoar_Ţ7 jD!]Bܑԁ*I4[V }+Խf Idߺ yQW6Sc&: mR2 4CmXhj9|xgKJS":0:=K z:Ύ6ii >aҩ@KlJw@Axi8>KIk-iI*"$͘+ ik9%Q*p pS@隒!la+:ջB7}}aai-٤ {lk g}b" wRT)ޤ^[ lj3u[$P9C(!IJɌ}ߤ+E&z 18S͈=44 %mS/}.x `TQ6 ]Ls&J%qPͰHs&t"Z+e4 _d&B027Oz >ߐM-$M]@Z3!yfYFOSFzQk]ޑ.xiik.6Ҟk@o},To W[ n* Vc>|ZE@eI\PͤKqHp l}Ag~,hX2 h‡W?"ld [[_jl| [~)5cɒ@4 4,%U2~M!L4 yn⦙j<@Za`Cqϣ˫ēJ6%[-MS2 QUUwX汵IC״͚wt0`åWR^r}yk)&i.Hj0l|αi9e`B8}'y[8ynV`ei#ƶ0kI_d.$-\]I=yxNĽdeqKxRKNҸ-R$8'Z'HI>yhZ ވR*3Csz> 0ș(tz '楂)9Z0αETti-_=m?9fX`MX݀01SrF%x-"XCaK[4Eu;4m]zu76q3u:ۭ904˂wU )~۶(ql=@yoV;+^ĂG~N 8.S3 B޴kdK5/c؂0 %mob,#׎)d?΃)imM,NE ΰr {9+F $tc vs6dWCBE(c@#qP7g1]?$ԗ &bƸUAXQ&¡B0 Ab{`RD p) t>GgKy.vp va A Gƙبd^%CwOĈJ|DC)9KMCXڈcjX^ZNa[h9|L"lb2&7MDB(!΄#@qQ(Jp c`BJ! њaje3$ ~D/bDVg"6B9pG/g/ vvrX7`@[DV8,H4z}D~2$BmET'M7[3x8m&NO#Z.axYz1LGW.`ݭni1MMVd~^Ql@|)v"F9T8i#6I5ځq [ (3a'%71N 4OֈL 7mToĘ:AbY6%bPC :AL|c\,-{_t p_^DWlFw羪傔ci"8xݐ{mNu3L^gT6%?j=8JZӐfbXz])"נtvn!mnpٳim! iWńpz9p@NBujMt&n9cS "e"ОdL01N\MsQbdf*8ͨNFx5#l My!lkx2 ALY<9pU]ҵ!9٭p-=1Xh45Jfӏ-?/Um:z݄V*Jd[Dx"V[ўaKՍbpۈ4 b,-`{ʹiH(}n0nKQ[uS^%{ -ǥgX[NڷH5%r~#V̡I>ڲ,O'e mtGGa ѣG/0gQv flՈxtҴTb өtfo$V]F&1L氎C t]StQ%+rk1Àf-aї1gƶu-5"B`׽-v~ '\[t%4df/劝}Ѳ-gF(1ɷf^~>@);tL[ZD [B?]O}ƹnKGV A ܍ B:Pq*A]ao-01 \6t im{ЌDӨ ӊ P9)\c<21YϿ?t`47M!'$5ffPp\>yk^nL ݖo箋q[X¢˟m$N /B< P\%S@!r2 !<$3dpUDBhVh L2t[t ,aIRAs92A u. Ig!7 x.%3D (QD/BEK``8 qPWStyo9~8RHыb: ?բnp|ƒt^&y |s9X?>4bas®@ sba``ԎUͻv{cU8͖_XΧo+D\$rXjFƚz$tj Ϝz孥XxR1{NM彊n~tj.L#*x.B+ƿUiZQ| 4<6hs_^3i*!C pD5!H-$V,!BôPցѨpm<gX 7H v#Kϡu# 9GXGB"zMID "&#DOJbY Qė"Mb$?ִ12_!y+\Tu vs1A/E.+ l/eg(S cpJNiB㭅NLV51qYI[Ms9Ӆu4mf4mڨHv,\dU 27I&ֵi-#r ! {(lnHuH_¥@ ϭrܛOV=~ӣk$E 'K}l * t| #"y"A8~څLU¥%hMHmδIL$]V1,i>{  7ߴOlu4@4 70(WܴiuY.ul/osfL˾GrDzna88`&e?ېӞsi N-V߁K.;i+U,uKT=K{FQ1NkN{g郈'Nu6sw^R]1fML{ 0LT\:wKޝk?a|>̡-h 0, H Cܓ? L[a}RIT<.Ku^4|$TAr1{4o~ºɗʜRX4f!['T^ţRKTDK!nϰ63x~K> V? ͳv_b+c:`0V\;u+s_<̝IT\[P#6pEg[;q= %+?ZaSOSuz#a˃ #XDʎc9yΓEC X.PhMjI(` ^B biea z!f[#6ᘵU] ~yghnJGk !,0 ˼\ xkf \qtֱ[q.X[*ݦl?)abTNng3 㲍RX8ݴO~%9 WP]RyCX(,G~y^fRqpmt<5- 拙0Њclq0 s?$4 |S;SMЬH 481lpbhpmWc4ťB8j`:-M9-mH‰ %81PK(e?[!D^x{,YĄ"[m7 N;ݘycs 0n 'T,l] cD{I &XSf, Ch[&WE!1qG?JU/ؘ~F!qi֭L,ҭ%#ʷ1՛K*aP0$6%P74$#({Б뒔t{ƒ V?Nxx}?U)j&Рss:jXkB#@QͰ[%T#OxiN3E/ =ZBIkV7Ҝt{`)|+O;,$Rp4?0[iqtLmD@J&AduS !$0" ff#[.N s>֫IfxBɺk <Ѯ-%A m&z㭻dk=/MX댈6*A -)$d pV녒t{ ؁ʏcC& K^H*Uɴz6#R3A g"ŀ[)bd٤2Ŕu| R%PJcHVC"2+fIͭzJTcxi^ QZ6ND5[HzLg~|4^k^_\ܥZW57 J%+8#DD /ުL2]J[&}B5ʏ gaS& j׸py6]+98.oj3M˜!iI K 0LdW.#K*3GXak-%U շ'KFФ9}}"$X_WWh ]Twj^K1 Zc46J[g<`_-὎ųr8Y)dNqvcxI=n^ƴWnfҊPR|zއ%}zMO?w:FȲaHuˎWcS9p<_h7/oAKa.^Na1c}^[k)nb1cc-qEuB8a˟C9$/!gnjajE,fp\6}(X]Wu_~@H=hE6qaF7'kBn{H)K:MC99}%Iݜ-,r0jLL)Xڅ>&°3!4K0H!.6p& "@tHa_T]|){p+Jb#dȟ0rz[|GOtI<Dz&C-|zL\ ifPژa $—u\X|X;aX8c?xw$>wU s+_DL+wcoG X?8|ficj0}uP![/J|*rieXZ]FaSW* R)y?KYt8BM1"cB𘾟 :5x\P4.)CqX&1pkf` 4#u-T&H,vW!TQgȐQT)0dcR %W l2aHA6/ӈӋ @p/bcZ [1Ns:8-Ob K=nGh3qNݶܢN^SZ57uK6Kz$2m1I\27d#BEB)1a?ƺ #Dt[Fi?3) 9$~! ? lڨ˻kXu z.n+jnbbaJ$­om=n0\5Mg3ζr[`b3!~&O=ɹ#H_ks cv3‘*%1(y&T 4r(/quKN{%Oj[$Fx Q ufpꐃolvJqS_k#РrȜ{eZww) \G9SRMCX\hc2S"isF"iWJV_n82i6mKLxrCRn}b t{wK]?li+P;[ k)n8/GLf/wsCb b83{ .1C^̐U7]pʹs̻jө *rv`&-O'nk&ڸ2(F[EӁ w"֪X5aShtm[NbK~sJ^`ugMEQ\8nx~kE[c;ۑ[RјMq>U 1Z-:خ5zftem[}ׇ}6Xܩ 71-=N7nэ #0Gt1!o⎝i/э ho~ujӃ8֊帳mkڞ9<ݿotco1}TR!QRWZ?0_z mٻwҼ;S߽S]<9z [la.˧;J|9$!ݘ>m;V1jnLxK涛'zm]r%q噡X g e֮763ܼIwi5CoߨF\;umh 7[Kcj{c^Sl[AGƴX]Z;7`R5#f#a:|N'zcKjPΩ+#jԀmj" -b$vR4sd4X=Z" B/\?8x0E"Pf7Wė)x8˰n٧* lKWiqFrNeدKm$pUKf2Ta0>.}ڈ-rL%mضNI.đkG*ARhe5B5g&UieZ)DkUW9g[òt8F:)A9*NHb1.ne9ο~@JR6%NVE#kFLX Z$FzړDsVU&ͯzWV=^Ej>&WbPL$Y*YW%{;\{ҤfTeH\Tdd"HDiTF}օlf/kR`[[T.*f :+b=Sb=5ҺȜNsΤo$#ldd`:H_cy!7z1q򣸱apq~'41#1 SXOAeY+b[6_}цWb_1q!louZg:8;#(ݸ+jWPJ~%Sr=k),6>mcZqgMaFK}L*2<,v ȉU|~<BP؆mSZlmU භ[˧GcC8ӯ^4ClcCt=O=3j7)yK6Ih!otㄼ-uÅW+7{3_B .#*9#wyi=э8Ð#d,/|܆53%PexL|d]xfEs>w>W^n?эllěO *;(;]c*=(ݘ &ˮr7r.8F76wJ6vzl 癁O~g'X`ڋFg> b 731>2b`آV!ynsK7|SҨEG?wb: M|i,բZ>M'D'Lamq,']ouDfs縿.eў6̡8+%"~G6Lqm!Poi2L6[s"%!eu~zW)61cN0\VjkEF0;EІJ}#@֮f{4U:RԴq9uWmY˛X^z vi~%&~ nb9-MbaHVhLMWl8 9YÌwb$iA~7 N|6-/iU>]~Pf<9iOR;BXڙRp_a_"P7#L;nTGOu6r:aE/b>1ILuF^uKĴ .2p4E+\H괺 eck9>ꎆl1w䣤ue$|> ;SG3}#6d|3 ċbkhkjk jbZeGc1O^7Ѭu7qŲ7$/ns4ބpֆ⊄=Դi] bM˞V7%FnWPL0{ӊlީF'8If $ lh[)2b835b_q}AS[eЪ҇@ئ?Qm ۚ(xXJ68jKL o t臡.l**! Z0eF Aڴ"[?SNMor|05mx71ژí.N: N`-MupιqeҢu r⃦Q;~uxܧ]<$p*س2x91}UxEbK)}lѲjtPA'n|}˭1>8+=p-4ҝ)y>zGrb*6?Lo>Z{snq1XZlte\1N$*|ߕYUlN9C_sWM.<9P{X1<Lk _ϊw,sŪ2 9ġ:bj@m?^"{OL9oK/7, Jb>)rO =DF8+hv ʼn]΀wdA=Co9< _l.i7ޟ@x=LITH 8ÍώKR A ^SjdΗBL*|1~K:t)Y"A[M&i@6-"G&#`\&8*J/1 7lAHRpJlH~eد`΄~lE6HwoBx1ߋ,#E0%(KiUyWAY`fG)S\TyN_kHҌ]%,Ii/#~/^(Щ!5tj P/9L!8E )]3K&R:!Lm(ԓë+QSٕNPVUTlRRB W6t7*NȲ:; Jak+;g5sM 7, %]i:0-N_QuqE"lޭYV,6CPڕddBO}4i7T/"BLy~z*U!so ox')G,*)5-S*pU)(Fb3 C |m${[lPedG&J Y4bIrG\]{!5*1&PHMH%ғz4lc+B\ IKId> 5]eTk)KMZF+KoȆi)&}M_D .DBқy!8o*ŵ]#׺ǒ/UE**Q %]t}t NJW0X|߻.̅ u ~ٳIdI ?^_~HԤ=Zxjk/JU`H_k_=\X#v/9c _ ;:㙾6Q`מt52v P*XUYx+Xv&'WcНc~.=E>&%Ͷ1q N^/n@U*1|[psMaW Jτ5=cte롡|O>6Fhr(v;#XatLi_)c"8^ ٽ;Fwteyt=ҾJgΛۏKg5 .a8xNj/~. cZx|Qxu*nlg:J\-|ǚS|lb 7y~71})ZGⰡw;TFH#'cw /wX2'A-w2ϱ4%el. 4,5C;ښi/m#O46 c%;ژ[KHm9$~u+n:x.ma/9)>Ibrul'0q Goxxa ;4+z"a. UoX87~0ILh%uܗmY="}9nTaq!Z z鵀X}jIqqTS\8/ ;Y<0Y_2^%M+BK: (Qa0P;7E]M`+PZa GH rV8\, ߄s ЈoHHkȉ^#i~AmHuyfJgGLd5\G%T菅# bj/5dUcHnL~P-7m!\b`U{X7QY_4 ,/$xU;# AۛmBHTVW19}21plM%0iX vtJ'"_pjU.e56纉5ombcQ|kLTV䓙NEdaW (“Hzou G?򘜈/u/e!A< i@dT9b7 )bYk _IqBXTVZ_X8j#[,r8 '4km,[:EpNaPz7M$^,N^eH7]0ٛuKܟזi8ќ-WI[C ~:sbXp:6[8@hQ\$\הGkةte ?s> 7%ׂΩ^8\rpXkmnZFL-^S r\f37q- -^8Nmߦ֡zM?9bAYI :|4Sݦyo5s["[缥Ly^=ٹJqwq/opN\ߴǾXmloT e&Qs;cӾȆ6>cmxpHս]I_gN%wR)0xϽyoq9.V>\RTR$#OckF>&qp/bvcoe*%vg+Ms.=702j/RX~{i>D|&09exُ,&uuqLW:cG9s?iJίr̻ݍ|xn;pboc0]q9F>vޕۋJb#gmhgoe;}H]go>֐Lzmvq,㸗}' ^HU{؎sk@ mK0bVIy\%[yX莄ޮQ%BηcӍyy"C8ir}?zø@k^DY ȉSx"CqӖ{w"S4X!w"&.2q::dQH'EV{",.2Dӹ#_v8cn+0v|<ʼnZddSi kcF5ꭺYsKר@4j2ŧ59Ӫl.mmt9ZVJs<(7R&oM"5Y*&gr.QI5Y8UZZ" />L&GD1bfD&4bJɌkbq*hlcG ҋlc&yJ&#qdE3fs.rB!x$J>rdUrcə5mVB~F3uVq)pd/ġmA7]K)^ڭD?%ཛT tFy@Le8VX8V2ULQVN_dkI!gPm|#[6I%Hkɢ5S*1wN$uZsר@%)'E&֯r6fJ1J4ؕOp~ZeRPX/13 >~D3(]HV/NdD8gZU^G#oE>_J&1s:#(kK#ͥ~^Ռ]M{(mZ(/$/Ҹa#گ_uM d"CF9ĝŮ`Nsu 3]: n1&5n@\I/2d*[$1jU/E[uL(Mm\' gNPT/Ƌz ĞתBD|cKAنI+n=ewyl7{VZK&69I3N_ȼG)I+>J~__=Dn3dZ0?9Re9UӔ@ iY=J3jOHY U8om?[na|/@r3 |1csUd"d7iK{h@ޮޒRW+m͋K'%dE#}YL[h*F/3%fcd_aoo:_kFrܫ j85A)ob8m"X~9'f˴/a[~$zwņt(m2us9,SͭcH^d܀N Q*o8=Jy)^Cry@Brm,!V;o):t4ΓW4󼧈>検Ӳs-9e8@2XNC(oy?[1uqqscZ𲉷O". ukJ"Tn1Cpd}G\֒㏸_T5drO%ȱ Бy<#~M/&6ımx[f RW )Ka/.>A%fAi^gjWK656bUP-cU)F$>8bOlZ'NڑûL㞱`V31s @L?쌭 ׅ8&ps/'Zhar40KRLa7ㅻcƣO)N0eO됂ai̘#WDy s-^> :tc2b\)muJ 7t2g)Bde4dñ P[^: 8}s{W_nb ^Ү NڭڸYKMhn{0mډ(Fmڬ4Ln,V$uu7`%>q w,S6U s1b:nq} P!æQ +2[ ĉb-MFm1'FͦH ~'qZL+2ٹi *%p_h/bv 'd4o:+zΝ=imyYw"5 }&61- WK.HKu|rґ*6WTӾ^ 7c%%)8n%_cI3qXvֈ 9Okò],: ~wo %\Kn/ܞps $/7'j~/K_הA{שrpsɓ8 SJor1~^@;Zilshj2 ۲L[[֞Lbpc,\ʞ}H>&7طl->1.1p 4ϒ i6>1{p_[ނ=H;q%^Ok7+QfggShJGՎw߷F>Z)-K5>14h 0]Pwrx㲷[{]rmsXnam=w"AkKLD%6=fobxHҝl)z&v7טe;RLmڱxw:ma~^k+`^ڶ'(,MC:ZVuv%>bkh1GmVYcO A*%[GK_"sy.U S,>ey1 MX6ʰFX螱И{O 1yq%!.CKSPb.e=;da_>ü@.qeH[EUTbX([#A)S' ̰y{ D"_m 9Ja8DzL-qm=F781ę:u;?x鸞'sVjļbY#㊾|6]Ň(/y HFUuJGhD~BVENn Qߌ'ܳDe{fjSH:2R";p~ <[HNAd"ϵ).͵޿QZ%Nt-q9RUkvX.:$})Y/L20.(¨V=G<J}bI/Jx@)/YQe5Y& Wbgq]~Kֿ$səR`vUi|Ve%}߰zAZvդ@ڜ{JԽHIg0og]n\.X=U,n~w]f/mR`V )Z4T2bɒ֒^*M}:{2iI>t>8Ʃ;?"]yz@jy 3. ꅒMjmvݱNc*^Qw`*sx,\<=&C~eD0y1#[ԓW>mC ڢ#<\`r%o"?߅EοhYWg7u 7o{|,iΕ=yS,C͋[AqbnPWqn<.Y-^{b%sE){\>o'jc[-}v23Yc9஥Tp#ouſѭV.[іX6\jzb"K|Ŭ#}lX8x,px)ɣѐ4w<cj xOgg~鸭Ν|L%6^%X0](vaN>vn>Wƣ99F9v-㊮̉ 5mÅ鐏?X~ )\-b]:ZwnQ+o1/R6^!$>ylŚ֖<޷P ;)*,(% {1YԊ)|ʐ_źtR$S^m݊+_C u,+Y0w4q{br%tqںU9o۔BkiR8%=7L6jbE!'+1C5&M9fg::HK&N6M`Tf4n:.nBZſinŰIbӜZl\ekx"k+XҶd/`4L 5Z;jڄ?zn*=i#`tn1P._@V8kSiӉ7-7r_-sQxuI _#דdHMYNjVu,EޤRK{5{˓«#3|'. _C;Sx/g 4Z2O5^o/PG_t4BKj!*o!@q]S,V#9@2~mM|Qt^W'(-=/}Ⓢ ,nb|у fR+:6u No=(x(?-*-=&F:(1킯w8Ubz@ߍs_&@.~F.Z*nRN4stZBź Vku g-eM"|VW&cْ%,ZHd&3ΌM%Ueq`=녋Ix3IHeN4ZSȓ5C~!>$D ȶf F?,#_yvvrwZ'D•yzj{ RlTjUJL$ދ_^{]PhIV%}JdmVC⡖o˼u%3Vٴ e:滠;, ۜ9jLwRR\|!TiaW–4 ~B eΥ8t1 ]x1jo'0A3ukSۀüjgи7|LdM3!ch 7mas#˞\)KsRm]'ns52!s;R s_jI޼[Q<ڬkY[i78FoLhQѢy/{MY\=~6b֭0htǭ}04H? $ gkPJs XsUwḱ@7M^12P؆T,аJ73XNZ`luJ2VgҌt oUThd…l*wMhIRJrg(N0B֑oG'*K@PB+1EJZ+FLe]-ѬYXV@P.@L _M[K- }ݱ?zB mҥ 31Ko agW7QZH3 t MR_mf0CQabShU tMaIJ7€I7=fVyOV)_ E]탐BL_aѹ/`҉p,9&$ #hy-KT1Cӈ8U58nnc-–_jfR+n *Yny.IM%k ^J֜ 5nO6r] 5|k`s(Yp\aaE IxL umD X@@g]A3|฀(6kz+*@R\+lS,+@ц 9Jd Ҿf!'DFPV1QZw+}S%!}Qly/CNP^NWvc?;캆?~43Ie9$|񾣂6JnjgX@¤GRՁm Tm`V2 9hP|wGd/ 5`HQ>+XvF;s%.9^zgʿ^%+R"HU?H+Y 0{2:7'k<`+JJzU4lgi7!Ēe]u AW{ W32)Vo\D^WI#Acͩ&LXy+,g\έ㻜ۺ !:;[j<]0x7$3NGwzY-U߻k:O6 k;mL< d6훤d6U5ɐ00vKFa,0h'yhOzwTC2]Uݡ6J*eҗs^}lW␜W͕t/䞬X}ӗ8dhOQMtÚf5 kqM_*ytqW<(n|VWH8%zܮ?=>-ˢJsO c] a vlӐJwاs|a$13 ɜKbSɜ! |Οep#6aAGgRYk; &5oC܍W⾾RQg|\8YZ#Uj\2d){f8m6Hf\%|څdv?+ىrPiKB+H\9,1$3/ 9B2ȏB;Lΐ$s[3ؼo ǻ sjX;ōy*מBB'4ǂzAmCXdɖs[Ω$rE ɌQFB2g ɜ{TO߉S~3)m;bS8l1*KD)N*c#H?Fi6?D>`-%V韕 iъ3?tdrEAluH,D1Ǭ({}ש=:[o*\AaYt& &M5JJ9%C<{8Kc.[bw 3T)wڶ˅X%|`PQ!1tlHST[[oj 93O&[ -phH^ n}i21` ^F H[$<"&֡Ff#m 74A8  fMol#[$5mуiux% "VQ6Fu&FHj֡QLx}kK/6c/1]hn[oi{`MTԶIL 0/|9ƄsBӮb[(c? 6֩5~۩>CM@~n=g ^@pZS׼i0Yj_ĸpiM d"I7md[ݵi(6="&̽)e=ȉ pbޟw fkpvaϠz+Lg K {hAGh'˹E/g&`yo N+s$kaV7-M% ~Kzb$z8"$ N}%fz"ѫp4d!qៈQv!S)uNt{w1%~A[ w̽ϐ|C Odi`H6iY%M@VhLa`.=ԁl7 ]v{'a|`{&SýWg WmZLM i B92LuD{icicA OADbo /h|4&@f{ڿP׆s A}}͈QJ@bXLLY.^6P=Lg1)wϫu!_%a/1mzH2m̨"mLcabicݰr01>V@?neI i%wM;g1"@[A`b1YU76ns&K6b-1k`lk1dm#AsB\[``Ie bٲHfx=ĞG>!g9/\;@Iӝ̔ϲ"-zƭvr`}L syoQM2{,ܙ^|Aъ+ſ¡hs&GfжO:7.w}nv`}n'Y%aZ2jd~8S2EW8JÀ@,i8yscIurF],6ixp(ٱzF cP)@z*0PWox. ٞRjbEa9!3" Z&%$  eG_`d[U)H`d S 3ԥYhMB\Rްo{#^^RHw+![AKÜm0HVLmRfaaZ# Ź(}^sEZ6J6ft.RZ7(tg8PSU(%?Ki#8*UU*t3$uU.%D@!TPtA)  DtI.L'()(#\j8_OBSC* W'FE8%+@Y%z C 8)`HbMzB={"O"#=맒iՍ@Rk T`o1Dt8 3ԥt@t5'`HJpFVQ_J~DV',gw>% /d'2L0Ui}ED6 q IRɄCL%t)(FG֓yzQvL$ *JRÁ,^w{&8LpǒbKV_U?΅7*]ivS"3qԭM!z)dR_BžbsQ FpN%WA;535p36?B«ݥ[BG@)(u%>)u'ÐHz_lRj5)XI F Vgh|@1YF~Crtn( 3U/Fq͵^Ҍ9 _{JDUjp?zAԭRjsS*8Cɰ/"wI Z/|k32 LV'rJ].ҾjaN{or=SSѮCWW_u\:\[> s[r*=ؤ}߇-i2 v5瑾 (s=Wc9Cc&J)7;e Q/(zjszH-M:OʚT^4JxK\lU1Қ}}Ѧ)}3|ipj=ѝeOTfI-x Ӣ&piS/ԴkNO ]v3yY`ݢؾzd q-1MmՎ5j{~lb56\3S"96[Q;v-akpQ@p38s LX5[OE&[Fᚩq.lwWquh PZ%Gǐpzp5SsymD%KB2ױŪX˗ztN khUyi;6FТʋޚCՎ,p )Hjk{şM )cטZć:;Ytk}E%ripݔG1Ղ]A2_ 16V BuGqLMeTy>lr&)]aAC60=,[c ˎ vlLcc7XqkH8F|ATrr >$]" m ENB Q e#dkhX4 ?7 [0:A1-HX4aMFD I\$dIzbI@7T4TY~{i~[ >du-Ҏ6q,M؂70i&7%&Ս?[&=bT0dQ\2 Hltps S{Iv86'Y몈j[iӚhQz-F X85ZHHU:q :,~ƚm#&m bMQ,ߊ}[@WDXiIe6?]Y_«6qWm{9 GP$mM.\wڠMSkNPTĹŃнĴύJ4Hi#5/@C\[ٹxxej/\6$1Av$<*اiݧʍKslsI~T;;ݾS„`p7KݾL? Sbh r@39^.ĩ=cz!OWEwk%.r:ҍhW[elًWkUBG9 |KÞz$mR]<-ە 8ws0-VK<۲%V9$1ksUӦs4Fj_=}=Hf-c9XЂ=Kq{o(>q&!_Rӈw‚/H)-{ZFH޼[0Y5m cUtP_r(GSRKfn=׺Nt}e2 LK|v;9K}jS,cS,!RmPv\aևxRgHK+˒cA/]"sdҫM"he}mc[Ku<8.p/ӺI_v+ʿ9xIˠc]4(e˳inuL(^~hXFsVۢR4` (hKw"3E!9rqܷhHqL,3ux]c=[\빖\RiRzvCJҸ-^%ɍsRdl6t54PKy}yeB1D3"LOֶzD$h+Qˬ!FX#ލ3zWW9sL@+&%Z(0bJ Er_ 9YI@Uɹ&6tbR u0oR %n t٤z,U/_LWĢ:T/KkB2]࿨]f3ɩʙzl>y}z1]Q-ZRe>c_'V"HDTzH^[Ep*L"3t}HzcR3kO;woXMp5)V!aװ6w%KZ 4PO2siDZsH5\[AW%LX״HLm}&_[RW?3i goY1a%46Vr&:EU~֒iRUZu= H|-SuR,hD LmbnCgjs2Qj%?g$2z5I$n WM/5P\5]`Zsg~ʧ/g+Y$$VѮa/00V)^ˉI.ǷIbdk%{N%#t3Q=0ߤpwf]APi>Vٍ LNUz%%N4[>Bo&NQddS&/R/27gL>5IJlhUv M7}O />3Q ,oc"M!0L;JUT9ݙpqCɔ=tAL|?<@|ekcm+캵UɭV*9}[lf"_f"}myzcH>v2PU_gxn׿)avEk} }ԥV=YT2(}%>5PD־ҊaŎsW*t+:|J\ۛ~/<[5sHwc%JeNy.dR; xq%2xeϞGFgضo8 _N.IF31 ۯ^&|^ηɫ$-Lh:o4rMk]7ƽvܬ&٤umylo<69a"-G[K ass3OE"߰N[U:ʝ|.=7"#ύȜ _?7"srK)}(h0cz@-7"3'O#6w۟izo<܈?mDfaΪ}ʞ:Df^K8M[ \c&2K]l󺇄)Vt9y\rU|܉)ZNoO4MȬ ְpYnD-\8.r6NW1 ɋd-[:ћz@~t#޻ NMN\& 󜟵n% w˨ $jGjZKo7/âsQȱ& ,oc1 UU5Xt%>Umh[,6/M"iu^LC|mH޴+<.=Nsx^{;Zn$Rn3 ٛF5&p1qjwi1kHlE1!H7쓨_҃dbDEfh2fIl*`WDQ{v)23ױHl%m&ȦtAk-$2!:L212^i` bdIgV٪bj SA l&5=Jl)oM{a*IL腡bx,=ش<<$*$Si@y~)Fmbo,^~i#fcpEܳâ%SZ^wnN&_[ E7:0h _L W&5ߨ$%a~+N;)}W ֝IwLEf4â 5M-gS̆|chXjծ/< U釩iV7!mA 4^4d}R--ٚ%8mJi:-+>g~ JrK쒞c{R|}C.PSm~/m[jm*8~y9y񸹿os?b&EӺ K*( r0I( #qh+C.C?[` }@-B(0g-XY Yl[, ÞԮ- Fa/d=yD -i/N4 i>?:+eZR AʯAP+Wh+1Va9}8„H-CsY>7IkhAj!Vfe|c~Q!y^-GjqW2934l9lWqRV*LT=900?U OulU 8B>_0B 6@1`%%0` (`%&{L%Ǩ*%I $ȸ2@>VGP0AiJv3tb^BTaZ2ؿ n jߪ+,̇1hH )^@Up(_Tw ԭ@ )A.dKV ay]aݰ>cBŚ0J+LKɠK6q`φkv մXɐJ e ׄpwhm6{)7A-n ,U's8xLbPhVV=QQp?6K >h6N%ف}uGR@")Qjs_(oί$ut9ܝ(U2d\.%%=I{u ?Nrz3;6ǤB*9l 0pM G`,z!^{ioAٞK彽@.q+Xt/14 Mvjգ.9#-I`ߢQz)* NtrfU6';"ta5{)`jz&P?j޽#:AI 0jU/U{1WBf֠`?xyqۄIj@\f(: kHGT;տ@ ]OAΧ/~&M&ZJTg `d|l8XD'3l[Em|dWͬ֫/Z-M_.ؾr[:{QuO,~ Xb\e٦~_t/S4 眾,W8/{J\2uFu>WiږV/ t*{> ϰcNRu˅|0}Kiͫǹl^*o}Nj7BtLJ"0<]LDW)lC'/y zU*69Í Ynd96R6lMޝkԔӺ|,'ĿMOKcMGg-oX6PZ^p12-"0yɃ.yok}1t=R4i5: eUbF} `R:Ϸ"ޏqJn6lv"^bq)#VK,>K4|l A8$?ebj#tpAjP{-UwL6m= gې 6[syJ\iuK:-)"Nu9eS똒/IZN| 3 nci15R/192Du[#f,<0:k0mGwBs[˧"(!n\ewͶKۻuϱe@paFH!#kkCݩufagF|m0Z"8xt Ha|Ѳ ش-8S52:L _!S04 pp=!yd_Ok(KȚQ Br'9jn7 *is6 LTVG:/Cq(W$P,8R8̨ga׸}^"һ|jQZƫkK/͐ed56 FI xwi[7LL+3IL 0 T7Zr.0Yx8mip_ȉe$0BBzHb#eҀJxmZMڨB+*RYtȵ`4ZZp '`,yUY$NEįDa1nLDFP.Mҩ&uG &wjm^895&_.WP7%*fiU\BY,Xfk* (y+ms$_)aO̅ @G*xr_4ҁ O=d~⢃\d8 àч҃tq]pژkfv+CaQ7nw뒋'MnA|ݺ`"0b8iiSˁèEN fF$@k׺i~+quT3ӕ]3 NN%ĈeTe/xaaW/,v1qUٌ]d]f!U-1mOP9قx"_ 'j#t^s(fRG":p4&<'sMbJ{JbA[!`d2O$F81%s$ RY{b^t C1mF1Z4怟4=Ah+0na o-wAdZ^/bΩrX*k4^LSPbDY‰|L'9٨NŃ3Y=F] '/[pNvG,זA[IY<[ .{:qᐠ62u=?nkRӅ3>75Ns޷B7.CY뻿%M!5jOЂS=lun5\4efa}8!%ߦw!l %=O3ǹ˺Ŵm> כu;FFm9 8SF)ѻUC6_*ihfNbC&Gu.f#/>ϗu\OwnWdiѫG"]/ۘL\\{>&7Y6czuqPWrYöYb<ı*^&gęk+p%koF z15 zaJcł߮MBy- /kzA]/i-Te_C5qzkPX)-]6Qq/"ß %l<.tNU* Ub>`QX|S5O!|)8':XQv|l˱I JXq35L+vqh#L:=$S umQ5UWa15`<5QnkSnL ]&-TwZZQ50񎢨aqL*P2ر.ck #z u 0 ,S`+X 3\a&99@Q̀\D4  z{h3&NGP U2$S)H FqեQ0|3pMK֙B)"#*8 P2$K6ҥSa^C0?Bi_;v`B|V!-= $_;#G2zktjb*ҥ٭$8J&rd u- F]([. a(Ӌ Zͧ *E 0f.Y rRĄ ,t4$! ˰d 㫒 . ]So.^j|IWjI-ձK8Tb5Ft JWDZ~]%v6P% UJ(UB?ZfЪ~/YoȤ[w=u V^6XS\v *IJ{ ^^V+/9qXZdY W|~okm$%{^[y|2][MjY]^_~/~lVQgzےŪ'av)K?/IX}AxI`]h&P`^E6[??Zg|AkJfXǿu& -6mݠѯ8r gSҥzKV ۤϖVgo1Ru{z4{t'bq5uB mN][zW`ZϫUmbdu//inKnÑdh|ᔫi&)m|K:t_0^Jހ$ ztUҭ% U?C⍗V,֓jsN6R,9Iwv1KcT󗬮^~炬.K/?l``uNFY_Khm'*4bIWVfu`vNmh/{)TJ~^6VrN Rx B{&Œi. %ؕmB?ky^rT/z֒%³7$CT/թ^ 6 X#ZU/4>UpT)}iEuW]{# }^UpEz}[2yQx$)3sp6y=ERXd 3f tנ}:Xp&ĕ_{^FR ] s~F#Jm#HtJEI&2xWYJbɴKJft N}řR%z=ҹnkV7[+dz6p{"˱# RO N+_DE %c Umc%囗; lR($h<`!r2C]22i!q߻ƼǔRioWJ6?D9=;sHd7y%h3ko%dJfOKg.i8DEGJu-C0S{!`| 5F-̱35{ޠm1'cgx}ʩZ#q$cI7Bxe_ `8vŠ gۆ7N!8Ƨ+c?{zʟ"(Fl9%#S_th-$v*\BĿ[f )3z.ڟ1ӧmѶK;$.i6i[ ߷snsu#I;ֱBGvOq,7}oc;ZmcMC02eDžcX-<5m\!t[>kqykҞbQL Valgk&>o %(ѻ8f`FJ異.bدuj9iw#ān,cֽJY)սՍ܍47󗷘nuӿO,ѠOl9Qڧ#ueo? ^c]X6^(XF !ex=+Cxbx߯gugCҙa8+/ƮČF.PFg|8eUkiݖ,K3:8LAJbTzmoh(.]po&5́k~ ;SK{zry.-^(ۖ+e!\À2󹬽i-~Y4C|g~S|* b%1mZi/acG/Y SiZ>WiI@-AbţG,ҖVc`-;s.{L%C%}'K'7~N ]GvU4khN"5mY⸚}Ck>[eC.m%V^Lt6b} Msq%?'.Ԧ]\[IU8fmV4MTh-uKL!&V9,mλeފU4ǬnL-1%.!m2Qn3^tnyW;m◺)ݼf z%^djƤ G;'Cibem4IWMb-P$iWAW>4޷U24uTrށrÙ>p;Ĺ}\o! O=4$5i/Rx'ijbڠI|%0Zil-TikM9hLzLLs].huiZŃ-&rYUL7* MQMcKUZN#?L8ةttmXLL{k9-.+\jSq'1*b[b8k$}ocJ?Zno-yۈK!Jk2oiӡz0HuP޴M_LHbSmQ՘[mV{#*rY*}طbG!rh.S8bx V8#[Ḟ4:q-<6bajjˣXbhİܵ_ ^oh1Cc"ߚ7mjKz |%9dmd9CFV0'1[4!~ [z d[JeWK;/0G;ޅ-$'Ϥ~a Q<> H\yt#М{R~ñikF,kc[{$iE0cY>.Ԯ-Υ*ssKb>iúW&X 1s޷>bI, Rsޯ@Hݠ?eזgh{gi[W<Ր4- д OI揎CZV^l֩9}l[AmWLN5_c 8+j9yo!wnbۇ+0+1?ZP$cwu6{Ɵ0L̀8~&v亞s5>ı&)1N~YR??cosX{ohpH'2xUאi-- };;^@ݸL)@C %/abcJRq1,-@GWϩH(90_9Aqw¹@Z9/in*@{FWҰ哨$j+c2}xMDsn"+Eҥyfy2ܾQ#Ʒ7V$InMH׸筍Iޝ)ͲK%n֫12i>Zvf8H4_ ny՟ڒ{VyqKk~Qɪ7oP٤0Kv?6lt ٤FǍJ] RDI&U/٤t^*9ZoXtn֫VU)>IU +LتoBikl%[zݒT`%%lR%Szsz.$.ͤcpd$m{RR[7Ȯ`!LrIm~͖RqKRLw1$}.ZA~A0)$C6?+7kIFto"c{i^X^0޼kXp%۰d0F$E_f׭,q_Ⱥ].JU~W|"&3Xt&eFZ6 3l,VvEVlh_#Zqk_Vb`Wf%^oL 66(}R:#21$%W]xAJ.G~/,%ݗτKB?Nw^&ݿAG0Ks~pBy^ɍ{TyQwS9hC6h94{Փ4HVm196{[ueTɒd ҥsŕJk7]Sjo~${_<_J6HꛗZ{F)XJmK^R+8teu_M)k{9z5Nd/,v(>2*QwI:?Kav['u2xR,ZEkR 'FeT26h|i3)6D|VoGŞN su+?`.<ϲP2G~oM> (YZ_۳HYbmTOlϠK/1n%)6OPV/5*ڭoW_ޞȮ Y])^r^Yꥒ?1z=B_=">_=xy~"ۀS2}{#;Mҽ/xopz_3!HJ@%?fgbk,yv[e0PW)~_RowÝr3?혾Xtlc?GW,vA$M(xnJ#*II˵]8&_fP _IV#hqel/H cBɒk弔 ѧ_(sp~e߮ϺT﷿Ffˎ ]pQɉ ѱv8X/tP2Y;_4F緤 tJ +rnUX2]鶬siy˰SUKi>slr^W\/R};yٿGWmq{\7qr4ubkk6& lBu>^ .ciu+8s)ub$={t(>μ )fYD_IܒֺPy2%D+@Hc>RE)mwB9-9FIٍ̓^ ߸.3C8N"tSwVoYg5OiI,䰃y̅k:֖pơRZZ!M[/?cHBj&Z!\-J1]D++d%ڝ|a\M\({Ke#S~0nW/Ӕ;9rp/\-=Ί"^C6iuݕp"#.zbA䓃5䴹3,4٢2R"dݻ:`&1)c흧MZc㽗&r-L8Gm /i}LSe?>ar-c+]Zf繌v{ex3p8z tq9FcG;!WkLkS#4׎=S,|mfg)GehDu.zr!ƆۈϗEp1VK<m?q,nⶽ}*5wq[IJq8 [3؞d-ߖI,Cʺ~ƁplXF(.Ե/):ƎۅL@B]zL\ g n9-:BOAj6!a@ } xDXSPa!%O8.0b)Yn)AЩ8l8W~SH[.c$˹qnQ0 ߇ .T{Sp*?bݚ=ԵGz riSzOKYƔ3fP`J89s6-}yj \U֐M)VwKї}혽 IFUC\1uKӦ|1=c!cw٦hFoem/|V`E} ׶\vv-/ &!8ݿS8} SZab41vbskn4+2m{ZݰY;ٺj[gm@Qۺz WҟeȔGŰ`[{)k$]M5fLULig%:pi\M ̋-\CuXþn.{&KU@&maqĶլ49٦rM9FMEo[! kC$)mcK˞oTi〚6n&cz)ntCm~fE榩=֘d7m(\KjXۜb$ףkZs굗s* zjXxրjk[:[#1ں.uϡpMk˫X륨^,Ƥ$;0cM376kfe8-bٚeLִqw6ng*a ifnVv?om6(nGL"7V7n6&2Nnu6]][+͘bT׭2}|$V8S_eMPZW2Uxe5&iK]h&i9mT3EJw+m\2-[w lk'F Vxx??<㈡xaŖ\5&n4U1L)˷i'+澺wwEoZpx~smԩִc=>krimbM*~iMƄucnklLÙ Mэe>@[?NIFp(bc2qI_b؏v]CmLvM3;6<Syu!ڇ^À7jk|u!t*h[d.!Mӷ92/,a-Gk1mr*01t/11jpDCu7B-&=eeWzu*[31чWk!CLޱtGI7md/S-p@OhVoSߩĚ%zXpmCa } /&{Y -P4ܿp=bQxm͘[oڴ|Cm7b}NhKr86u>Rm=Ӗ&1n4b-4X8ew,d<_~7FM`T ɗ-9煋'00kilָИ$ƭf96O\6g-)/sê~$b˲R.րIӺDi-GmsaZKŦֺY\ Ӧ#q u9|=K yŶh~=_OA/z2SR_~|siA_&x?kLQbyŧ"cHkTw*o䛥>onf//{ [xljڂ'.*aYX7CFSTӬp\aYBw8CI n'ƒ)<8 X[/ojpVӨO2 w㪈i8ԩX1VqXkT[P瘂pu=bNbcxR| ~QߦVg&ЗMRdp4)_NP'~9idY1EԦ=[i/'ͯԗk~&w9uz9FkI:Q6קE5o|.wuj]M7Gk&O xOw,vѻ cA{wrwoG̃_{B¥] k#nMڣH{y׳g6ݲDd mYsumm{(TzO3C{. y,sr\/ٱUl}x9ı*K+#6_Ӝ 4v[/nΰŖKb{+V0'Ċ 7ί}D/=/.4ITYA϶F%t\C}XFbCáx);x(so֡uo] C-\5 'W,fC؊1\}Oau-7Zi*5ep]~aL6y!oAeƹl,G}\?);:GI_ [cL&[s]?2D{}~og.?.)p*}'CWcSu)m;[Z %e(ckW[IїFjնEV>k Zc0fյ+}֭YT^ %tqJko{! i8 |8.kʯPu ҍlfA0]jt!6XUפʠXr:z6>|1T2^Y-t_/$dnq+\0)_,Y}:r~^F 'd9(sL JR\{r@7,IVdJA+]Yٕl~Z,,6g|yVn,K9:\ޙIIlfwmfԓnLRړ&Irl?+*Z*.2iJW~)jIbCF.7p6.I%kKϋ[L bevk_YT0|ɥ9J5u{]H |J'7ՙN} 5ݜYV'UXmL-׍ stLo.sjPZX26nѾ`DR҅[Z[zN%t)zaׯ1biխw:=ǭvXV_.kKr|nE_VtW B&?Yʝ=F)eԍJ&ͧ/EVPu&b 4 J[>TtO}[Y'7MzbRT)(Uʹl%]뤛ޮ0zGJ_]0^dHQ(E67BEoPf /~zm%DiaS^0ˬr*XETmVSmR?K9"z6^k1N/5 AʭRʳ)LANbIa?2i_VuJtS곛2HJz7)wե=%^r__Ez,Ϻh3)}m!bR:p/z.זC^2YRemQ}d9dK6 Zʶsa;_ۮa4F9wIk~kfA\EI lCK(3AХQ+Ǚ\U2݀^J}QAFt,On3R?KXII^ZU_IuV`ԅqHqvc??d}r7tڤܓ&}\U+:o]a ޗ5>FyZ^J&i~1<ãK4y+L̗;4c|!l9~ou>w8Vt济о^F y/CJ&~Vv쮿mg`ZTtk gow q^VG[˙yEѧ]lyy{k]/O}lWPV3g _*@ƈJVoB}e`LO+\sJ}}΢d9O#Xw buf9p#ޠV7Jziq?v+HUb7ܧAd\wK>߬U,}>i_{hKֆ('}COAϭNg{4ɗYռ{c%Þܿ= ֜oXj"Zi<`եzhuS_W#۠j$sK~ggl32j3IzZEg+EtW5g(@ҭy d[JZJ}6Œ.ס]}ou7dh_\@W+)d9ت_Jk_YRmoP2,jM^QJ`9+.Ъ1TKK^!dxP Rd%F]I,7]Gr)tk4u^p9)Y[cmp.밟ݓH*N̲\5gcyVy<%}YtsX֞y|טqػ7i8Gx} |&hXfs,qsHUw:=k؜ѨInK^HYH}˭%rl SQ~aoߎ}nH5|nx!~ֹ;@رSyZ^4h7=F۲ czqz_[~`SsR`۾v;)3+݆I$Nvenk1Q^Bۏ=rr'kv#z-벯_4 ~A,cvbږOsLDA yHѲ@ 6Ñu.AJga?ִO\-2K;Lmg"n]apm}.H'U$2Ӄ[KrzۖWBxkYkN98-`<ߩo$K-+dJXsՑ{#Vq6DҮ [\?Q\!!M\JZ׭͜$e>ϥcS\FXiNZ  |nkYI\b?KOFPÎ+MⰦғ˅CSy.\f;rؼ~]bX 5-umvzA\kAfE-䌜*6mʐr1cU<uBrKP!c@^3}kC87kF!9b̈ڴ#n|֭۠ՙC^kڎVSlN&wFL{qɛ?Kǒ{!,vH8qmfMlLM/1apvQjC+ ߆F-^]?Ő N\Ѧ9imJ-1Z9ZY%u4${hvg1Ga֘3-!QR)ZoM%m-mۜ7h n$# { oצvm,hCk9%nAKԉo`M#S4Kmk9>iUꀓhmȶ`ٞo0LiTSoq /<9cڠ)_iiTkGw| q14O`g= S L,e㲶4Q6 jSص.{e;xjL| ӑfnf1{mڶUkb1 v6FfwC墿UyZ h\uY$y띙nM녏 8k YoҶi@?cD~Sڟ?{6q 6 ¨Uw~Zqg:J*$Gs1V ;0^M(糺e3v㼈ƴ -p"]׺=~>!XlK 9UGdr(9fўr[ &^o;Du<}.9n TiԾ6KHoӴ͢GI6qm4p:i퇁TT7>1Җ9rZz{NMyp ^:f ׭DàXTYyӦ0+ioYw< ٦?,{&6[YbcBKՐ6MbT4&''0J<-:5塘n8 p),(~\mv" pmMxT8.=Aϻa%JG tv?ky]lm~>qaT1eƤʔ ~6*4=1i"ңSi)ѭ2a[KZ?SO/ YX7YbmH;515onTtf2ٚy[sxKѦp$nLlMto7Iv*#@fb3E`ז[xi lʹ%I-v6r2dr&qN'+}Hl}nuy[N_[iz:ً A^\LIfpӫ96N`1nm5x@:cXې)J\},FoLb帇r{FWd_%cqu7m;ɐQLq=èab݀^A4.IþxTo \פ]LrMlߴk޴Y1ŷ^ߨp6ku Y ;CB]6 fsky5E<1pruƦ[h\lx/3Tv3ׁks1n9ha>n}h]Mq'cZwnhhډ4ӵ4mS6VJolg>b]sƤPY!]t)^0)兤1iZ~G{ u^0;)Q5SPZ~DS[4zVr\,/:zWXɐt! ?TzERb J~7lQh}aOz,J.>Id+IeyF˱zs_\ {/N>Ke9WѺAT֫/V6]oݨ{I)J,zs",V`ѯk+鵶sdjs W9A)w*+9vIvͧ.PjIs% }?s<ڞSANs-l[gy~_!A%:TUH ֳ#:k8LyRIYta*YtUIk$MXR4PW 'sӵS=:KZ2t]Tɴzגu!tiNIJ;ݞ`.Tw:7&SV;l+/U>m[c n, 3jJ_cimV`.ɺM >ICU4UJkV>'Yݶjo*fJ}gZj_ܞs$Upα HpJKkVPuu3,[iJ6X*-$nm>󅯧 LToa֞UB%]i?/g/|Rɸ͍BIƥbR7J;C;!ΔGzc={v){=uzޚcRЪUpްVQ:_nwkIIW/ǼiI+9#os~579 oL|cܚ֒iWtFTv .)BBjkӅW}lhT2V2ٕJ&48JNUqdh=u`^EV2}IW"Z2XɰT]Llt6$֭ͧkNd^ ;KT/3X;syƇ!ĥ,U,gIKfT2"~[Tz%sy.dxpi>AYpOY*y/h?ӱw:*=7c8ҋ}%Xԗe)*=,=%DY,Zw͏}('r-ɌveT{sgg  0 k:_ɻC}=0Sx{IWfHnuhy(>GVbfk):"\J fi!]OI ?RuWctJ {yHn 5; w[š5 ܄@+Y=)Y,\ې@~~C-\jNHՋړ韛;uKy;g"KZG)E^Ym7O  N=h؍|UֵI S;bҼX ˼XVϽ)L^%̪G,.)(zj9emsgyr#sDJVF$V; 1 Zڠ)Ԝ=VN)tOAV[ Ra6ulqIy+>Z x u4L:WiM 9M:iz;ƿyyo }NHSy`WhLђt}Q we$"[3-= n^mC crmfA`>24Ps =Iy-<_9 jVז,3H 6K(;)5jf-:wS*t˻}Ps3-S)ٱi]r]`4 iX>:A}bKe@1!nPTQ~y5 p@i2*RA[bm ض[a4 bf(0k5)n4pV8lP-f+2k4Idb8yrO n"M.iuv-yĐ6h[t)6Щnk*\M[mX{-lk[6%ԶC=:xٙV4b2ZSQlaNY"Y b>߈ѐqUӈdeM#n ~TQ=x 3mZrfӰϊ|/QML?l1uڎynQUv'"FEY}pV8fye&y]aJbϴZ0ѲiS7igm:iӸ"]ibJbέ ܭLH` &:?Y% $y|Hhi1GlJvlo⚒ %RFan\QP '%3iqpzsĺZ Ĝ/RTLaɔ$2R16NYKX%3R fMO3QjMhp+NqaAbcAӓgq9q^3bZ 5ZmWDU`4KqYIoDc~N1`Ϥ=%; eHeQcZ8z$1S^gc5P12,g'^iMmӜh;%=jY4'sO>ȵuI־h9+~yg[ќCzR-œ5݉< ٺw1 c:I Gǽdm|ǹuymܲ{mqLX\z1wC1%&RsJ0vqj©Xyȿ{o/.\L>,x7)W, Xtv!xx6o$n BmbGb2<Ί<o-D5Iv.OAE\{=VnihD-7s $s9"h%b3ٚm7.9KO.}K{{DUdθ2ܪ[:}ڒbQHz͖GQ|N?z_u͵^"_k#-Qw]ELg1g22/IqrO.J$/=/"q2"|/Qט$@(~LFƕ8vVy>792U &, ,ȌR%^7>?3f-toRэ녽J*%%Xķ HW΀Sd9$աZ;IJm~)%4CU/PqB(t/Odd ޯZZ9(&)ꌺ k]"QWX`uX2QYo!H@wQZU/oE ~8%tٸ@9D)pW4K =IӿE,`5DcĔRG,1L`WdThWG/<_p&d)Y{ďk3]~3KmҬyOyR/߀P $#WHέ#H\ҥ~r.1edgǹ 0=Ig>52&Uĉ~XccdA>j zL)gҷ0LkKw$4\zac{eI_j}t`@!ZݾHinmY)' q!0LcV_*sʛ<]uI:SzT9id#A2ħY<ՕHPZ~9aahk64ylUeܦ6 dd#AT$h(Om$h(8mO"+_~F|-/0H$K<8֖b)V#A/my8ڕôc /ao3NEE|jrmH"mKN/{ڟp ")30cbi89ZϨ]kD̴0yU㫹o̟ex?g*!:1]VN5.}e3K@qnpmgﲈ?hRWX04&^ck_X繵T3ϱ Z˯#q渌/*Y[P4O§OCes\z ,g'5p"SX?SxM u3GI[h\5 bv(zi-}㖒X8$;AXS, mAqkV սiX{攗BQzPS"ƌB^5Hu8NS_;x4j:UxMg|w!xR4js`Oۻ&Yo+Njw xVsb5#U eKCI<ﴌMZ+P 7%ƍv5{DN|aX:U!Մ H6- ꖂKeO',>b&ڛut^lPr?Y @gK@/!mh;^ʎGjc(FnGRY<<./\1d"{csCMs➜M+}{8;}r`#*bBT ;K1SNDkg֡,j)b#XRԂ ~WEL#pC)a1c..ޟb&AGH Gz@ js_}6:X׵e ^:o1&;iӦF%rZ^iÐ) . DmuM9ִ[`93˽pE- -Uf( ,=-=Hu-t?Hfb$y>Z4 { kצJ٭p\[\d32i-\"`Kd{t1U~LZ0d "K4CaTQ ms4o·X z*@ӗZ!k<:֛="lvn9BBx5[1&h&ZbR{ay:%fko"lh!44܄t+]]W{WkVǐ0.=:aϟ7Ԧ [=)#0. 6IECn 9VWRG=C*8k^sRoW ʔY-ˆ +[͞`}^:dT\@t<]DϪmnv% ȭwp/;E Ÿ'L;d a[b\Wm8  B8&)K?[T %Pr%ρ`l@~"6 /.|dTS1Nu~ L@_#w kp @O%ؤLc8Y#l8H RyL.= Xj3Y'<=cy}.8*؟7랺kP2j^2yG1*"mT 3NA {Vy&l'%K) 6u +@߆Ftg`83TNd-S3T/s^Vt_p0SUem%K~.%j_r:\ž mRyQ#HmQRM&|5aAJL/4) Vԓ~'{ntE|5oܰʴMXԤDNp r-Y/Hf94* k MP,tIJ6IR3$ҔkRo^2޿%!}"FPEOH{_yɴ>4ގP)0ҥAѴ2tl6(h%`sӕ7 Mog»k):J@ rKar>3{WJK&{oII&ў[?)Z)AE2p@T'1i.-du"-Ԟ}#xS`> 1>6Y->AE0 4߶qs `ހ&9ALźݟ#)"wZo(z Ue=vͣU[#Nܒ  ڥ0-A1d[oz]O['(DAQ`un˱V]8IiHp:O@-(hJ]~8FA$ځuW3mPCbs.f:NP_l@.[(sФG.a|)&:kym/.׹gB *.=t I gGA XPА^~/ZyYG|=MRBAuQVQЭd풩toB %7uG sBN lv/":y3clzdj# Z <ϒG`;!_ť|zO[B ]|XG R[ybk=;cR$0ƳJ(MZ bD5A(+y|N }m!*-e/v78ɴQ8c q2-8f"xB$^#c(,"f>gQ"Iցdt&Nڈ`% U&hɘP_QN)IRx> bV84 0b, THƀ}x;q-\ ,b4&(cj E[@x.=x؛u(ص$ f]ۜ3͉R=Gߋ_ďŖZX^C9,L/F"5d]|z8`{tmmjnbl5n f$2!@P6]<4 -s&p8b"R0y`O9Yr>Gd ZNz!Ӄn;aC\޴;U؄D_$k) )/@]xc,1ֈqb&0!0UM` I@`!ְŪ&5t }@Q-|'+R]5Ԑ^C2%h?0smNqdLh#PTk _|DAր"V[-4q s5k;@A9ӮM}T,b ge>G47 wb*w. &<1f"dO=hڂmo 4eC ,=4$^87"MDiYޯ!_zl^SnIkg`: bLyڷ-1daV'$nDpaVN ;Qo KitInKi{1Fh7O,]^ ʧZzf-{/uߠD%Euw/Z4k78dp*[#63;R]W>Jt@Fu>4ڨj 51 Sgh- 5e#?* Di sH)^Ǹ?f8N^{dr u84z}+uyx/\< į'V()={w'縵kaki6S WtQ+9?#2݀:w8o=@[f!u8b.f9HK˟1"jB*q_+{C]mF4p0w>JVrnV_kfo-ҩ[p߼[ gBȈ[ŎvggPt8d!zKfǡnP7qzV"v 5gtCRH l9h:0fT{(u u@і9G9`%;[֕R+LSYUp r%&pDXS@{Pw?QE:vZʾ þCzuY<Ѻ=X-峣:^*PCPbc`CC *͎<=dC]9-wKv C>!.G`0UPT=l&9 E|`! T1_ 갣shPbqH2e{;zk' u@ KGIl!Մrд`IZ!Nj҆mR"P;7Q4-F9blWi)T0 &P. '?KvPâY6f|~P`((Tb2+f cƲ. Mғf@w">4 % * &1 =G S 6͂nR4+[mf+p*0>Yࠩ^窋 9dL%hz>fߎ>Yq#4+aU_C %%zKN7iǑ݊"ucVvfГ,(iH?gob[S76UIˤr"5 %Ks;P~rix8m['NuiEt*s_qS}|SyچJ뙟UK&v P0VȀDxrż$A<2]OH#_1Šc8'+RJxG0HKjJv)ݻI@&c-sq!: 0SO6I'[*H5)uIs(:m;;_T}!:KNi9R/&]TLcr.KZ6H lw%|mqnQ7/m»P( FFڛwb{-u_竇7 o3~2Z4B q,\㸮1(:ݶ v8K<\b@ vPyF  + ]|l[ 0Pr9DxpӞ0mUpz`0M[8붗Ž)XC@{p4[{>9(\b݈B}yXiSy`G@HTe׭$=}RLvVԇ6kdIl+raX3lЁk&$u/Blu[+ B!VI=Nb""3(9M 4 `DJ);CKExNK W7$"[C䱠I&IsDl""4B'OXN$hM<f 5b! a˿1"2Nn8 EDv1 okݍDE:/;ڴ}#UTx.ݲ'-G&$*v Y.(X#1f{PZJV8+-G긌.vss6c[LxN,b#.{F6* `]eo?_d-MEm`> l_\ o> hDx8R}#G*GOs$H,M#/0(]: br¥n_tv۹6Dp}0`l(rC AV &[ ah+.a  F,#Q<ƴ֗J|ł%ŮM$`D[)GX5*`,& 5i3$moV啈w { J7Wj+\?AM+M5&$ 檼)"SZ^8CR}7]QS1}9W@zT-ӽZ sqŲ7 1dąO[>(g9XB+ڔz>^6m2&1 }& -)pnbMA>K6_a:b- ]F/us p𻨍uMouN$ (š 8iu/b)4),mOw䟰\S ,}NoZ pid̴):fSzS#bZldo(,@kmM8wy 6Vuc{$%[G,"ͅB1f':?Nɦ`?H}.:!gXEe;8hZUwvV̴Gf!:}PaL d&g^A OCI"V۵ #?s*m=94"lB l;=A~l! QP.]m %(؞M?YBVW[T Kb<*|(a =:8<(PYVu6)L tުz jkT/X-ǜ8ӶܝCyf 1Mh>V"BQuU"^)ES#I'PSLym`?Q i̲g,i,vY IWrg:JV/zbO3*H^/R]"Q=W<$XKɠmQM=ޓ$u˱U|汔orVivn I:nwoM$ %}%ȶ45-o0:о;IvVoM$ ol#5Е`:~j7ң㬀y)pƦʟ.x^̊vo$s7YK*z@wn\1Q%9'ϹϏCtmKк',h/\ oNŠ&W}; }~+]$QtfwSҴ D-h(r'YCG+v6w5f@䆝)E(Y1*Vtx&͢{iPy.n:ȡwtNK4E|\|Mwvzj(!eEJN#Š% "[{ :f,$t'1t]˧#¥pV vEqt9g)95} ͚5!b!T5O%UHL<8g[ru,0FemƊi )}"SQXs ɃjgESo n `DhWM vsph'cQIJY~9&N([Vй-Fa@%lLQPDyݲpƖb5ڿ(il*~,@9Iy2`#2ƦmR携<56 3h  $/(Q,Y5N%"Fk mmM%xص %2 Z$[{p\bȊbCe=hصS͝$q{wAЫv`&#{ [(puP7Apeto$]ELdqB=p$քH.+MCa.&&åpp1 N {vB<<؃ ޴6"Z6}0b %Yg-!/zn9Z`*f oȰnmZ6"8 DuzF IWdBbUȤaTE/d&iEL%[,`o(i+T01ba`-j#vE!i[H-%F.s' g RpA̝8Z d$/p41'$7]zhQS$oTxTߚw10Z &~97mJK 8gI#mH&VFR%_i" a8xHr\2dy{c+Nah()܂gP-ҌR)1Y|oN};SL΅{xK,)pm>X׫2ў]3|B͸ ,1Ti'+Ǥ^<twu/eG{+ҭ9~mE ڃm;-fwC.D}n|~nLD{VОCVZg MgeEs /T\;Y}] ɟ)قSWL|۲GB{>ЙA{&Y=zA'ˈp!%VyW_i2:i>`-u7d}{|؃GR*oSߧ"9Zj*/ԍ✷=,gBh#j zf8Vgidm|09;홼@noОiېd+C,UWoT"^{} .|čk\HvܹyIrp>s &\ꪮ#cG"-v+DX2-kTc#uN"KD#$Ze# =ً宯 _Ug%؍#R#vi^,kkҥv?&ĥq 6;)YN$L*d2 (@B겐Ѐۤ~>!؄6UQzt$FD&N~ pYru9eo"eO. %ORD‚)r,7K )WġK^*/FMK"ܢ]+(^ gkf/>F~֋$aA:շF TrzOw IqE:*C󐞋'"rKONG__DKq[} b*0EJ=I%OWo:+*Fdt5yWD1V^LS K^Kc}=(E{eoxRSLCfџA8}.D{&h:ҲU+Idv-O ~F5]Lu?',b#Gc=}Nrɤ.!Nasڕ}0MzIno\gc2ݤu>r4y?]]Y7K|ayT@-lރoVbSJYcL6YܮߪܱW*Оm9<[JpJtlsUf e<ԏ 9'E_Ki"u4ؕP#8#GsH4j_qwCiS+1*Ķԇ0p(;G\)|I菘Clԧ2P1Gw)-BѦv=<(4W%[(.鰈qq\R>*4V)V33W݋W):F">Si  18ąE8U Gpw{&D287ɫ-K}ri5,0vfbJ:[NKYS"eZ?aB-aH^wu{t/E}HcXt>ͰB]9e:F\0@/"Qŋ5,=.5I4QDg_z$\ul>j4I{tL }Lh tN4ᳯ|΃MvBNV3& ʙq3Y %bcp@9+!7Mbל>39N()a5S5ȞT!ҔzC`mmbBF[FD5d!V{uzk7^܉CX<=S%F5SGM:ۓ,Vn0aG(h_`#ٝHb).֙\+{[ '*#bBIQ M{hCN‰r%{D-v`08$N[Piu@Fk;'ZN鹥bH׆%)ӈSF j(™Ŏ+,\Eu Ωib|gk>$ &3nTobXwr$=Z p0A %`1jnj*&3>LӟĘȁsJ"`T{ 18@DiDD"M"L3陦OcClp~AIpHO xL֢`ƛh*v1r``I`/'dҖ?51O5eX1Ҟ`̤\յi d_tfm8v`M #Fq {}-`8CM1Y bEX4AkQ[[okXk71􋆄Ū#"K&1Q J~AsZa#mZ鄶L&ł< /yuFp(R.$3pі›6w_"u!0bE>h/%$Lo Dv ?;,ָ%@/, zs  Wd6Hjƥ)HޚF74 @…Ocq7osX'iEsH뾍_'|k16ImKo--ܿCqԐdJK+ƄΉ4b>B-=F9tVN4-_iҖJD ( p۔U2zxߪc8!)ٸf2~t3qZ"U|kO9۵ O}ZԽ86ɂ۷+-uoi?lG"^Bb{qۋʰx"8K߹e-R}ݮ3uqgM98U;ٲ3lI:nݒ7>-Ķ}$+%@OW,=42mmƅ_GTPWYozT)ֵulh_}8m qΉ.%=ksp>} .^b9bGijT"{;;73j)FV'i6 E"YRŃ<(*c,?skCI5}los-Q&C pN4[ξhaaI!`A g͂kx*'۵.Nگ+hz_C&5xDM.v&fҠImg!?{Yo f* t'%hP;LtY(F⑼n}-HBZ_vLt*X\}h_^cPi`K i0+A{gXN=4r)SD`X F(h9&P/)R qdn" Ẅ}'"5BKx=G"|P2'҈b`c9 q9~%/BLP9uV%I Q]S0 az HmэкG[]JΥDn@f#1B6=5bZ%%8}Sl2Z7, I +zIW/Kž ;Wox.l|O#<TK]ZH ROX/7=٤8f J;X? npT#.I-屴6^@i`zY!@^Ka/n<2LZ%nW(%8jnsL4Δow d&)#Jp͸N~-mҏJ@а/Qڞ h˶;M㚏;pihO^Le40BLP5Z|ޒlWrIHLYe9_MҴVw_8QRfo[E[dWQgSC}0ĻF3̘+Yt=q9 jͪ?5u>|`j9*L1$)ײ v?5A[^BqAO,j͎`gݪS1e{̞Vv{5/mﻷ+u_5hzeAſ Vbq \(=?~ǩwusk_'v׷kvbkݻ9˺uވR>D[6 zNvQ9{=kt4z(nNKTڟPYC.>=kytxM 꾃i&S.eP|Ǹ.>JlQ\[@mAiKwXZmzOO҂$Ӓk,^m>^m"=-#ʗɫPMȑ'h߼+w#&#nGXBK U%[Z0]O:0׬ K㱏"'ѳ"yRED&z $vkkR"i\|Erw${N<˷>ܬ-u˸pDG̀- dqu;z9R f!'Zʩ/llƟ`-f6GX<~11聑&')޶^)RLvv=K=(ٹ&Jŀ=i/jHCtqCAdƪBFBP=@75ďTΞl zʴO_hM-v]"B.CVojkEMku vpB!Z"@Lv"U,`svJ^{F5\~(`ƅf{ >{? ւ^S%a˧s\e 6MDM΅bཁ~axu#VZ#HD&P*{FĭNHy?8AL3ik8Wz# _2Q ԐD?Ո;x(HRV&{-~Zb1KM_T]s0YG5`YŸM&7-Yê(9bՀnD<<7*ц4N°E2a[]PEl8QD$ +XMKE[ T AH4 809MAf@.x{ݔ y2bAl EԩbȤ-b){2$$6޴ JL IʎjFmF#8;`I 썗r_zmtW Zg,L- ^w.f4$vlbGXGl{Iٴ ^P"Z@W@n%"Vr]˕Q}RJϝq@k0pm6zaZk|J|}E.c:zԹ։e^ǥä@Ao9B)9{Ȕe8)e~Zh`H䧸ZֽN11^azQζ瀰aڟ7R>8 ~kAX֑`_!%am#x fEX5m+Cf*9_gڥ_zaB*ܶkN;,Qb հ/vC+(>|40٬wo9~lOK# >,Hem SAR!T˱}rCX ;" v,nm9k=4H3@XC AW`ue'{IODiPu5;]Q<.yقXm#@X<O-בRf ]a[n nƾ%mKܮq(Un~.x贙58>® 8Dyԡ7U @2)t$=t"H Va^E.WhVintӈh9:ųF4O fJ2UJłkZh@C_%11 ؤ&dئK>2hz^/A RA+lp?:R2HE׀2I>PnJ8h:y;h3E:4B})BۭK 4#(>r^S]nu|IsZ%? ͎>Ia FD /ol`y '"Ha}XK%[i^8S4 ڤuEi`J_BJj:AdWhƒՉFzs=%t䴀s.%m즴&d* `ht@* |zR*"J."sQNL!9H oGP pt/0&<yOꍽ!VK`|,uT<S0>M`m8H Op{5(/ng\"}~eDnS#<Y6 sS r_Ъ%8W ,ߝh4N߻Qw/DMjuF.zm6먻'pk_qR2xʟsozK w:zoe7 _êm gT[3ēT_YʉW=cFI?^4s'􎰆$峄7Tdse"a +C ຿Ř>Wam\t{xFA`"fI^,l$=k xuE%ջq,cyg%4 H/ky5[t{ tO lcWOq뼷JwONW">XOR/9z3Ch{l“ wge wKw~" >Eݺ'DN8BhY'Hv't?uH-#r\(~wm\ss][ӻu' dgKQ~rOD4pM]%xŖoy6S ZTl#qGH'PRr\uwx\\[q >h(Ep崍\\ٙv;>UĶh~{okZb~L ;^\^.479&2+`SuZ2#6piGP51,lA?%Bh]hDAb W{g~{%xr-ٹ`d)^`B%hcujMvhl猌Taî:.[m;B"  EL}nWIaG=ЖٱsVdkE,M]Lk^{7h78.-asQrHڽ/>$r&_Ļ-qsY.FCYB\"&kqm:`2C^uH`F1/$vm``8 P}N&T84_n RL 'x>u6LHo-Z CI/u)n`h`pfz5:yHйE;I>3X 'C±nK@&Ǡ_5@Gߦy^rgЙ<` \%X5`%XpIBhnֺ)Ny^2ODcX w:IBͷ_Gp=1Q-3kKFmpsy06>{f o1߀tb 罡/D wDvZ:wۜ@,Wj8йn|$%_Ę ?\4n:[<p@sX '7銬b2EĂcӈ)X//`o&XX@T?PQx$v1!I=(}duDlꠖ jx 9#)?4\it>/'q85U]l3rF.|5(?y7xٲuI{6_ùŶ.a^Ì~CdDh{H@~@ďRc8]KCC Ӄ,2ڃr4AӤX"DYlK cM0N%,(xmlm^grj_Dz{W'=>zV7%֤?텤{9>9ZdKiAں,|%+/۳4`!rg"~\ˀo PndmDcHݱZ D>0ƣrדbȟ&{I%JH(C{wG(uj9l?'Im|BBу ,Vm˻nY7 jgעu7/CGR|}Nøv!="ߟ (i3Ъ '0!LZPt]HDB-| htu)%Jb;ºQ6ԁԞȥDNe,IzF"nKN0-z{ ZߓU1zٌu]mz$kג[oJ%;UtcU^u HcKlfdmXJ |i3]J,9vDb^r:Jƙis(V苴,s۳sX"!/ v_\ހCm6Du)ن`>[Ӓ=OR=eZrj존R $?;2=@#ij&_v/44Fh4i|Y‰qnu >掘g<@pUS0i.ĜhW8!KqB^Mz_AoN`~@^t!K~c~ bFzqRT{GηǧR<@y f_+Lna18 q %9~A:%ld8W˖avb;K)Nznߎ촾o_YfW띗kh]6~v~r2a9Sz׫WgxZ::$^p 8owx׵s~l1cv.rw ;yϹ渋kƵ񘯳_Yb1>JsG0ό] Em~Az_ R;[W; tҳM~󒮵(ju\?#aErZ^GUj+I v繆UI ^r[>R.5,G| o3H*S\3VU'_؝FI).9:*u={CwLٟq$96^ǾuwE˙r&m[vn/} $v^b XYν3<+o0v_񹃲Iެ^ >m;x^/6Cil'ke9[-tow(8ǭCeoC*9-u%n>{ -AK])\%uT7)0]duD{+0]H9w*89ۖI$⽄ ^cE;ۄg9vu"+d~|E㮖)w*}QnJ}n/UB|t\_Ջ,`9GͼN"(*9lu$I1gQp5ە.f":(h6܁*qֲsqF~l^ 52DK- EͰ:sPYA{)'U&!y{K}= B6@sn{B*g@Wǀ"A zxF%?]#$ȍzSҨ!H=˿[#T]!AI]3򵐠d!ASh%Wox[;$h Z"-@q];JگG^(m;}X K4' {t}+ :r*q, V#Ԃmx|bmEJl$clQ9Êt%&t?K=v9[NKT![89%<^~DFp+/Iuw{ϼ8p[M1hVb^;8wBjZN$bQm2 ENsn#]&ILm=8=Ib٤HlP uW]m Sb)5 %I%2ҍQ \N uI_a7/7{Җ.hRr}U)*mFSZD}K}WS]#+j J]iOmLz녾vJh%G N)SiS9v+!P+' 7A{ʜ/=9DVVlZI*{ Y޾{V" %,lj[QH&)ؕ(/'j4/7" "ݎ4\VG.6!.TUEs]67چEQץS.]J ō +gù45A/)N˽^%H~B6w7qZ. }[EK[܉ R᭓nkځAb,G`_J}HH6LH@d&i  7̎Rڏm9~D6',1) b&ݘl'Pҗ s)dob>0^H'zM9R.`IX6 l\NG&b_ӓX> v'\D9ri`",'|S}F&F팀[N9\yu"s^ JsTJ7Hpd 3^bC\/PY};]=oT: xBw©]YEtCvE 'g3j+ZbO[tg'(mI-vJ(YI3s9R}"9Gkzi ՜aKowA򭍞2~+xsiqzkxǒAv~TYr5\3vdK+9ٮ򻟃NdueQc _v {|w[]}gw/!/MKׁ#4 6gNnkbt5pg A<%ffzu)-=C@#\~EyL,eݽW#<^Y!] Vi .^Cgn%*VV麗TKa^pts>w+ky?Q2luힲҧ>{O&E/Vk۵ =貭s1{:4߼׹Ճy( |Vr2Ye'dڻnkgyW/,He5zzӞEl;>#5Q;i9p?[ 9. ȼٕ+\>%(鳲蚸0^b{%\{-;C b gH[ڏwq.߰Iӱ<$mװ>˅edkbC[7I\7H} DILY{n}uZ!lH'#GHGVV5?uz0#vX[+\mɅYx^)IPj^RoDe^3KEAu\5oIuEnի6sn$f`}6FX×%>gZz4dBfBa HfDg6!v1ZMCcjnM.# ː&$;1lH8Ppt1hp KltD'"E5$ DLl)ވWeK-)oI)z^ϛ+-a@F d95!Ǜnv8F;=dGO#R/|4dGQWE ~^m$+2,傃D&:ް<čbh@}w[͚55kR8"c`0bGQ[͠zpУ ~X8GbF=ĖVA1k28&F˜l.)zY }~b7@Ϳ>̟ $N`b؛&UCQR^׼[L?l9 rp ?FʖN00&fR˱p;БvީwWDMDC&v uZˑ&'R GJ&j[`&1$bd:p> P,é9xHC)"uιDm"tɃHB'K%"yF3sY,ֵܢi1MaMZ0ɣ~N ة8$DJ&q@qqv1"ILDVѦhK_"2~i&^ۃBLn41.MYⅷCѠn,D6*(=G#eў7=7qM?7_[Kk_k@,\Z ý׵q@I6Zb,\,k{6'F2s#a{x;AFhLhT8[g"MS>ܐ_Z."Y`I[ ih֠mkKve۵ d8Dj_p-{ ⭄)ww#*p3{ ^pQGv8K<~ ׹ V%=RY9yܠ x<@ Dv!\ ѝQHfDm~TڿX~\ōr $Qum2=@"~6N7 j jrO?N;t hk?ף[+ jr. =ZݕЎ]ܸY"GCĖWdW&5Qx݃vnEn u>F+x١YGҴ,},ב-/qU,( tK( Ѱ=Qv@|N(.xߟ$mv_pm͞Ip <\"%2.e>+^E؄v_u X WJR?/n)gCVmE}Ucf{!i#kyc`AEr y=:W-@G{"}ӑTu񯉮K*^*bAT7Hzm۵I,v10 h0KX wD5-BU[EL MH#םV7@E`mgo{DDm6i--IlS^wb4j|}LĴhPToqhB=!Z:q,T)4xc^{ /7rEs…mX4_VdVBS K/@sfA\`j1sQ˙)&DiHL9$[&(">k`".F`oJ xHr6 )%jxaD!{ԦMR(jLv4N/;Gڭpb9R]%RR+z)9 FX#8H&qi ~ xTU,f\ 䇶?ؼ[:l`bL-bB 淊w˦k9N3Pˠg!D{{?xzrزi e0.Ch F%\[ ct/Τ\V;?-GLӳvs" 5 -\/6Yv5~ak˽Si$k㭻4Mh`s_2+u ͂mŃH#moLls(KS|%cݼ|yMc[{%tzQSKu=d ég~^{1EfS25c/&<6=2]z+>{~Vc;Ϩv:h۶rLPdF񲧘giHSr[iogH|L+rt/GwJb`^F j.iRwK 2>#8ecc=Tv띓" T{{9ſ 0)v%/Wb`u"%]a#ߓLb"sR׵LQwZ5K&}޿0X2JM3w.]Bg2"LaI L3'ʒM"Yyڥ]dy,R.(5R_D`&p F(؀>b@-$&qEH(mwLqB#>؀!ڌ 3+4Z`Qv"J)}WfE .7l6[(ڶfG)51l9x۹ܤm2²gWf@pWDQ)8, !O`fK˘kFAVv}ѽ6qmCf c~d•%^ oū5pQd {DT{={썱IH9Ԁ]ȁC dږC8Ć${!f) tB%KzҡKGa%tV " Yd;b* v.ЖO -'.SF #/@bb޴sю  0 )@bFb!##zGmyNCmJYiFk_'3 kU_Sߴ^ i'rqkM, r)FSDm_L3XX<rq V;1M!L:B Gl$"\8(Fm2dS4yś F~MNMp{Wd48KflA[[}.\0L'DbD92ōˍK˵EpZM=GMc9삪M,6|0ԦnP2$B$YLh>?H4 IpNAM26 -;)us R1鹵6AH, %Ә1KWAռk{Px(15^CoaAij9H !烘=iSƟ(_ 7*|J G:-p) 'K`1paEN~/z͗{sSJϊaȯ}~u0O}fȴhL㉋/3$b)D2iq/i7%+[^B9xL">+~K09 `G D/ K[K:KRNʙ JiipL{ O"]W&5'}qwEz|дfkqkRg8nl7msyf|\3|7ay//Nۙ©ౠYMڒ٫xݯܢM"[C0ucZsϭ}4?ĨiVx4XR --V۲ȺElZ_BKgNe^G%Pb [V"4lzϸV=+ 2$ذIr`3*dl{ uC$[.BuW9_Y$zJYcCE9wBmwm-NGXƛIU wnxvVR 9l@>zA؁IqImual]uuJ::#r<*!Bsh 4*'mX[L@r},U %Wo-^^oڒ!wl:O+r=}66z\F}uߎc1fRГv:Rlqz!6+@數k,בIN9끘)sҔHL:ʉuuj$YA\W ɞD&2+ҙ.1S;ϙA.uT ]cי"n.~t9RE{$Vu^WiXzQ5`.iP,KF*ڤD Hza]bu?B3dy,iS@$:JTk19)@ҵnJ]'KJyExH S*DDi[ s vɒ.t^ 'COnKTit@SׁRX(Ơ+ax"GDS2'".3ԋ\pxRڅS sAN(ƤKd<'.RAdWғ`sZAFٴ^KZE,i%9؆ Sy$|sIׅR2$q Lv$Þzc>spuF]nvb\] ~|ѓ9㼰ae[`N]QD~\Y +W1ʁFmMHPR%=qjF}EvB]w)֜9su]2Ydk"O;o3>/q0}P';o%aǡF cU:k+qhUҎJ] ~ޓB{s6J U#s=I#MX*=Ƞg"ԓm__O%;Z &B8 EGA-V]QQhd/%jXzFmfӪ"Rj_ƷOA+~rpݘ/Gg$kzq2w C oRK} 9{W@hMw]LTn+_jIXfMW=z%Tnxol\i=R>s*z sJ6v]Fk_l0z)ܝԽY@Asp(Dѣz&Y>t˶\k_5bؔZ9!XĚXͮQH9؁ :{-~]16%]X[qbX$2)Xj^-=Xkg>Ǜ&1U՚c]{kO}d-bx(MFk\x{?"I,g$>t6ͱ{K$K9DO66cN]Q}:zBm8Udc{~L|W!4Ю>W 2p_Oe]3] {3XnMM# W/=S$!N(ew6x&SD`LQgDnB;kع EvEl'_qp1{+yzƖ*bTElܞ ƺir$L{ሯֽΘdk]>W&oSrU都Mbiy+Bg7@Nz.uHF1d`/T7Nn):էߢM 6-kpnа#Xt/\8CELMzb5c6MB+ܓ8 OM*̓!xXN"ѦS,ҭeDһ=_;;:KfUnqږdb_G^9տfvoG<Ж?[=#(m=߻nQqQ{S 5-]yaq'>y)>Nymn=ƎN66nkF~N$i^ɛ_ᣄ{֊*iSHtV%E^#j!Pb9j-Nvb`1Ьqi ɥͮJYGF)0_K αuc༢w#ѻ"vqĀZtˍguZYKuۑ'rr34G.#p^28ms>>TRrĎ,m6=HsY֒QOz"Ӯ!ŀz_EHKcDJVhɮԥX$I[ %H#rAVo+q ;W$_U|ENYI`W*(ܟKa T{ 8K͡dGԱrN'RGyQ%\p*x{r G$ 3''r=<1= ;GL\W&ؓ_ RH9T_N6UJ%њ*ۍxQ@mx2|+ѤēP[yv5O@69bIkY ZE6Ii9攤I@OD\(Z`S8; fs{, |@s +kJ+RnOӊ0U L[0_G%=\Ou"˙s4%= G$,LA]/C/RuMJ a/(odx v}P':tKa=Evc?Ӟxs",!Մuz|mbyADq=-d};7)KA%O/@1}"B++{4L9t <ߋ=/!$D]›ӎ㭂Ļ^x\rJ1"Kr)AB{|M1AZ o/R RM}=w/$jٗ-m@}}w*}[{Yӕq.lm9$Uoyg wP־}}ҽ-vMWޖ<,V=b<%ִӞH+Y=4L S$!!I*I=Hhʩ?7x{@&ǖ^-@Cr ׹o:%}g JWI rovߝy{q ^a͇8k+c bz?φ&/Xv{wֶBx l/8@:xH>~ߞJkT4z<\)֛nΩweoWq %/txDlig?GA>k/vދߝ˗tGa~"vd{7FSYMlnAXSpfyRw+\<;1kѱb-ApYBs~.E?wX"Pki=z^b<[}]{/WyEX[)#%bsFX7K} #iꁰG8Z&Q{Y7Lۙ )ô_kB9:-DkDoK l zkؖA[8 :JR4'3[ !@MlgPv/*{[) #K= (vH)h{갘õo5/ œ]gt&k{h#}y IjQ l٫MB&mڈlmRZ".`*zelLk*_b(q)xo}GUK0|+Dz'+Hh"آ٧b`Ls!gR, <1z G h+PC U'#3KD乘)Vq#2 -m4V (|,p"{cir*܁Y pK70ȃ Ř3If!Z%"Y76[{"?&p,1] 4$,a.sa!ŴXžuM w1.X@QȂ4 dKpimT !>DTݨZ"FEmmNqR8ڹg ^8lTev/"}KŨ9J0Zx"s ص8_LX(Vk\%rz9ι{/opHҴ/~PEb*`Jvi6?ڡ$F;1dˉ &PǦs*<LӀ/sE[m o=/͚.LOu*}Y^Xv>x:@s{gȴThqy1kkVfb >wAw~-MFN}Foǟ`+J@Ѻc6A;a X~֚ GC~-Ms񶧵;# mY 5s m?3Wd['C(0?磧)J12Owٶh}"v,^+轟"ޖ%}X`3.3Aɟ@'xrMAaXu[+te,=7] jV̰tݼWzQNףV q%,B >s+i$ ^WbLuc,?wK3j[tyԗz-iۓe- ڋji9 ʩ̅ mVueu?"onݶ~ 71O!m۹׮ۈ+v4^w8:Xׁ_h-6]& cD=jV@0/8>&c\ y+ѳ1nAT#c{tta^::֒𯝎:tlGKmroN/ZCm_=MɹΞ8d '̅ F_Pa.![!{`?pY)Lm9>GU]u7?t(tp.3o5D8;th:v:6Y= _JzUMf;\^i6U`T0lR\(AWޱhE>f$;R~.g_?`C2ZVcsgm"U\uP֕5&d;0[{⯷ί0cS ô "[q:zcrXds'c[<` EBXR/ل籲Lg[&u/hǹ.Q?a̮z5Z;8Mk\3&쪝Ξ!///  9S 2 #B4E3A|=~{'mk<Nr +[[-&c)܁>#~p'-/#;R,N\-ſ#=Hw򭝎]_b)s ;[۽[;BJ;z ]0RĈvͤ vhxx7Lmn,?rق#xǍ66V#N1x8noГzWzo`~,i O֌!z憼|XB贽p޷"ף[=bZ.PuIǽTP(0n,:NX;-gΐ{JXIcuڂi-HNUeq)>j=i.Pzۀ%g/{]CP~郳z*PX(c7[ȍ棤(ڪw Vo͵ǶcWlp୍ S(.CVMB! 8[=gnkxlaP@As: +Aa7 6giVzWۋ#Zֻ$: (lt6, MzkhuIX-* Jc',@ Ύ"pnA7*,QJЭ18^78& 4`} S%M,z0@, [δf*m}r7g{琮qeВAv)"@q!6).@Cq]H`vf =ۉZݤf&% ޠ}Bu#FB(K,Jbd).4LN3TJ{ s+ҥV=H5*`,Gmu#D]}`$zIJՌzCt#,u +H^Z*e{PT0~ G@#%Ӷ%=J M0i{C&NtֻuиzE5mu;.]?C]}mQ,rRT6e]0wW'Fg]W llÍضmW aTJfg'bw%6ҊnNWﶭm{ҔS[ؿ=|lw@1Oep]AР5-1XMa|nq&F5[e{k!\x+»?G{r8?s ~??gWy 0cߎMD!떇{(S?b5$+1^$G꣓Dl30&9g=JV>s{,aB^sQ>Q"eJ"b|$(<"g')LFN܇|yԞfغvy_[4bgk" z)Ox6geU]˒~Vv9q}(l]GY'=^l?ԅpmb@J̦t{@B)lZIp-|lgXnj G d Q`(q)1~RsnaIfJȇij೑Б`sTq/ s dR $J\I,X 0!%Pw +k%&*· *XabLW "yDJpnB#MSxȿ4SL _֊⹶Lc1ׂq'qpq\:Be֍bqļiTL?p^81b6ޥR7x)Y7e$]P-9w"sb [ rk!9&Q0-\ԐXm~Hrg=9ݮ._k#|K_w4d9.} w"1&s &2/FsD;<Cx@aMp?TLN-͂ 1  Br/ȟK6s:,t4ω΃ `qӖb'~aP2ZZ%d Tp9Ť $wF0) &M blk#{RI!?`렍\1Z j;3ހKᔆXy_rH[s&O 1C; N"bヽ4apf[S%`H^_'0hkh0Ҙ8t/Q9xhofDA8evc"&j9;Hvj[Y&0Q=E%-;?Qf -;3sXĿ)za}GoL*nbiI"d{eGfZ5=rsi;sqޯ;%-9%5p{>Q2og{-V!!{)iYq)=t/[x6W@ohӿ%|)1)pM.GDÔ{pM0:0F >1D58Zq|#Oܝĵ6 3|]smTn*IKADDz{[,5?<u/O`څL*N&_ib뢭0`lx{VUר](P^-};% /\٦I  \SӔpί 챌c".,ӺYׇɋ4Q??GV&?ۢ֡8߅;!m;P'A[ $[ZRmqf Hw^7EgZgHvXqlMjnSc MES?-3NywZp JŒmqPy{oz1T~ݽn*)zS7& \nM;Sp |d\j{fe"s cz_`}0[xOhT){ΰuNv'ŴS^s;u79,}-4y?֥Q2u?uCTͰR>^˰UfR%µ&yF~ Ѥwկ5"&̙G %* OBpS $$u|F9ѥqlfJ,,RZr:3ug"0 JdjU)m **Y۩ 5fU$R?<Ѽd璮HaKe/Gs޷rAd(u:<}zQJfl?$ A"/LQ $]A2[sP[ kY2& $ ye'9$vnRoY/sv6V)Z;WQ +c/[}{-[Nn_I׿Jodt>'?^)5~goW~#ΡJy\f:aoKs?x,]鵿55ts|CUKV;#Er7ݽ#wě%'>_NU/+d6+b׺n6ۑIe=Ooۍ>ܷ1\%j0h0udC^S'{h[rq_t褥$/^}.Wo-n"^vLdfSDmb_ {DF5oڵRaޏy+hxmi(Uߢ=ԍ()%GX\NfX Զ!t YҺu@c?xKQX!ՙ!D›#mApk=m%૏Qه|%<ХԷTcgRs1lͻi 8X _Ks"/ZP|XGAAht1c6ضi_$}OD_(B{cːyH@5r `_8/KoX00b6  eXa;e A9g[sWs](VsCCWٚ|QsZJuK7߭Cpn@햠jwͱ8S1X`EL h9+Fv.8K[YQD@nb4nb–MXh-mXD 'iT8 ƺ&qUŃpjy _&1MД7-".AMv;_[wibj@QxۨpبR!3l`Рqm9u?|@@h{bJLh@iJ`9^ E;"> p}y gr?"E9d`OTq#d@LȼNzcy!nڴab _`~"[L<_t^#<.H*VS눸-m jPx ~O%uS )hC&9jw6N`a)9ڸ.MQpE=Hs_8UKր?` u#fW4&.QR7іQLXBc"$lkק;.Ûr?Y@L9Hv|Mģ80z †__0bh)"ќ=fC׾cK;9ҖE>r-L =ŭ345^k>mA |]\j˝7؃NFzoւ]ic=x΋[>uPe).Nu. +JK2\ҵQt#)kĐP,iHM*8iA}wRLثmݪ8'mY|Ekfn5Bjk:SְZ(E̲B*jB~ ľG,68EIo >Yun\OaQZ5-)}OXQLCuZz$0(-Qb'Ij G'.VŠT3^i`]pBvy֋LB%omi#v& sߤ `MRbT<$&uџ ۍ(=DsеU'qbhuDVSڸef F%6#D],Lz ݝ,&Y׺߹j_eHr\}g 3Tt&K ]N2},؆]lCJyD> R/XSdX{Rxԓ}Po:hFth/RՍ FP ]ͮ'`,%g:Ѯ=: TR.U߶4e5 <_&bqKۚCk\JOLkʥ}-6(mNk;Q]*VN#;yxS靊#HRjYrHdvX$z"RX\{Zf3D z.D !]"u5|Ct/o06)e,Ru"^+SOxDrEZ{CVoi.]4+ 溊;xNwtdzs",wxsBx5gRt6)vɻ Z\:)y Y6uK DnjjtR⢿};,C6H$N7O(`uDrzN6IRz^, Jv|+|yd}+S㰶Hቄ1tR=As8ωC+S8Hlns㙟u7vF1~GTޞ7%2XHKo"إ@1;D}=g׋1͐-,h `WbdXD; X sp&4)ۢ4oG*Х6$؆nMc;x΂Vg_ (wX{`؏;7i~o{:xY+l 7ի8'[.Ut]r} bH}&\W|`8Ӟ۰t3D(w :([u%TO^J+n3c}߽R |3mo8Wr&zs;BV5xՒLi?,|1s}cXv pfS[Z"ގtڑ2Lw-δwF5񱼖`{M,)ȷv< BpkmS&S~{oE/>-:,n]h&=⫰&]\, j()_6/~@][ K.[ňC-{W^ uqp?Η>$8$| 8ϥdSX:E PʶXI[+]Q0'DGmΣC1ਭl}(ӻ7&\rfIh^n6w! VuY"ٖk/^Mڭ[{Kn9X ) eAPs>>+ew{!tĹa>Y%эHs^֚bMtZsOdԠO4&>4Qz[C[.-Nȴ`z ,\ݠ|#Eu3mTLl| dljZx('}x}-ՍJ#Qňkm:q<ˑ d2D 'cޯ ,pYpͮ7dTxONמq70{@scz&SM _3a95|9+y0VsLd*I\sj Z37>1BOs&F^C-L'moMULFEvNJɖp 96ak.\`Yh_Zjc4xIX-΂^R>n{v[[X(eF S "߁򑙴5}ܴ,i]O>=_(spwPŒY~dΎ4eJG빮|>&/WuQq :o{C #y+Xt#^j\[X,h JMQ N[ (b`AWqʻQwdA y+m×Gf;[mLݍJ 9+]}zj4Cx}vZ-xZ Su{v6(ċi ^*[5NRQfP9:|Wxc‚wk<뾂\>;;Y`AǷTZ{~4\Ug+# 973Qvڶn }D_܉}^Ou~}ըe3yBE YX4lCퟞh; V#a[BZҽZ.HPb( WD: :#]lǛz%V%8o_΂bEjrDjV{%bsc<ihs.vj~,uS ,?H%Z\!(*Τ?Ϗ.ɕ|nO#leaA.Rq~*RK[n-ZGh;}Mz4ZԞnmk X" Ӟ\vFq15* PrngI]% _&RH[ҕF]6[u:r:ryBƺ{DО!RNm=Әp+g\H[@qiq,N{f(yП?Db],YQB4]~,9if1$3E NP{@t2E BBA$F"H`2M}*]dGE~&9goᖈH1D%/] q mF,2_% TϦ6R2[< |E GK!ӷbGphzӃQ,'VHgz6Ie.VJua61AHNnvdzDo|m/È躔tXIKs^ fY,Gp g~Սo]twRg7ҍj2i_zi/|W(iOAJk,K}I]\ ΍kKD_9;Sx@@%)គ[וw\J3I\yHu5 */d=x+>/S)){>|ZzMRrFAlr-_oObsRYͭUB,*,wfH$ܤ {@1}*TlemqweNƂn(ۤ[K~ yM0X$%k)`Œ}- uj ˉ-4o5|#si7ۇ=JSfYNlFYV};6uCUZ_uOdVo'k ϢBRtKܲݕ ߼OvYyn"{w=>lޅҳuK zgcs_v3=CcyU0!x:斎ɭ5Dx۞/MxF2q}*)- v9-}ȗRo&K2IMyggQfȽn{L2wsvRt⥙׏N Z> qTb~S_UHVoC"#qϫjR'E/~G|,yI\/To˒.[/ojGA~?f]>^eRe'S6u3ON:a=t 5GOG xU>Džqb7XY .k) $  ):αiG~ zaxم܍k(h[>;P$}nˇL޴n5=-Wgrcmw(ߚp?"-hbLM,lq) ztA:m4Զ2k^D-%Qplb[5R3!):r ʔK4QWFC^J@uu@*n4!Ev!},(˲NRQG? ҷ+Q^Lq'v8+M}b ?dD]qՋ]oChb'EǜhI):*ڀMD-HK&[D\G_\ iR 'bJE٠t1{K]~CL(Ԙ!%iu;Gܡ*nňmavG ^s1`QbZt|.=\-9fC,TdpP`|BmT)Z.fkڵ=$G`Hd)N$h6kCH'Ps^b9{9NAzڋX 'hDnv6NAI θ 1gE7M>CE >CQLu^ڸݞQИAZ.p`$Vx7}HMӀ5?:7DBo^hG6M^@5lGI>;xݸHn-nLmvC./I^[vhM)7v'l{"*rv"^"ldy @aBR *bĵ:q<96L@ea61k,|$PLwmH.m ֵ+dB"Z "L'W0} i{_ؿs1coŔ,xDA3ҼQ!Ͽ16Ad:@,3ۢx+O Ű: HDUfھQ)w7_p8kG9X6v`*7Pc{Z xKdiU McqkMװ[PRܗ1,v+jipmңVHXb6Kv-8/Z3qm/ԴeHd#PMs9v2b#XDgmD@КF" rGƹ@tjI$12gڮ~=cs(&zym;nm\iQlϱn}TWc2v Ԛ+qLkV,S^1"wΑ(%=Bɳ{߂fϗmgpٶO$Pw:):qԶ{J,aoυ#}=A&#}g\Okh^HeK݊ёٺ 6?/-ve.Q[M-8&gppsBR%EGAn5%EXgZٜ֢#@]/׉A2)L$Fq5JAcMt[GҞJlFXYH Q.((hu~D@KI`qa^/oPspyS0ѩtN?NW,,|ruB&YFි[KXX ,i$1zTm{ߺ5Ew.m{F+7vN"m4^WB 69ؤJ,n ܺ.^>-EwJF@)˝nysΟ'.:}|C3TX>0gE)21>W1oKMB@NG8oϱsKTǹKܡ;rsb `e_/;j)e-_E,/}s=tه[JM8 Vr˭⧥rUWwi6]рllPg#E'PŃ.y c͚c=ҤUm3L"EhjN3Rt0FFAKev&yf] =T6ѽX̊ q\k;fCHNZ{0:)y#F<{G[ʊ@8ƣlu oeT:,?k[:gVR/A`X3ı\zDž=o њMܱ7z N,{I i0^Ә[ 饬}ktA)xsݒt=f]ZZ|RYݚqYPGAǢp̷U[lx`3]䂂΀ ׆.>$Ԟׯ=BSGTt!Nkֳ.#K+Xaמm:>+hK5[' LA17j c}yzÜc=胟L{;8y&xM!?§X%3PsLs1c|Lg-9= ;1LF%vvʟA8(h,f~,ʨ%5n!GHQS+"10Hd0Bh#'Bn CtmE jR 0j5Z,pm ϸ֯6Q/C;Y+9dl9XFDsw tۋ<3y`pk߈LM[3󳉚 p-aFСµcb$2ZZ %E1 HsEmB"aSbdd6VhPKa*-lK,F^N5DŸg" i(g#_ĴGFm3Ÿ{# 7[#m5kT-MJ6FdT4[Jv.ml5fT5PCqLQOqe<齰1Ex:|J%O6+ `xގsw\)XψVX؏Yn=D}RKY$):L[{lHC3550v/mҷw1}=}'H)DvǝZ&Rk 2cQz9/C9ʝzb݀_Cʇb =n|:r?8/78XJ5^ 1O1u?#H{a*q-15RQ,4q[ٖ+etx";$=,{i}}r͟B<Eg)헪Ow==k+8~3J &W/Gٓ)ñ< Ǽt|lHnsAoC9=->N,޹Vͼ,CĹsOKCby_8${/;!{W )˼͢heȎ]tK{(54Ev̵nuc{#luy*%֯ƊAws}a79Ʀ8ngkO@uc5;[âQF*-G5in4tL֢Xt>Ql}r!q3N{([9uo$iU!>6b>Ò(Mjh b0siLXP^IF_ۆ[4wM|Դ6GOGH-"{sP"u)HhrsgY@#=NSftzLpmZ|oqVPH݌M鉩~ᙴ̤B=Wl4^hfD1^v}sRQ)6#Q= DAbB1Rh``"Gչ+),r2r;H&J4o9PRk$)B!tk<7;(nJ~Zdtj=/n3՞y)3G\Wc[z#hF/RQM;eFj 0/fBث1lQ+J97s R.Py5$}$Һ2z ]MlꨭH(&\/Ry5d37("([w#f/rloRΞ#?7'9Oڙh#LmYcYT2Ю\ΰst=Xk/'_WIaO;gݗ>=W6񫉻+)_9gXətk`3iDn/V!MTR,Y̔󶂱@qٳIkc녜J&]Ȕͫsaz"74K\t";G_a~!E=T֟ʛWI9y%uܵ36 s_J[qck2 t}>C*g:H+&ᒫ=*͹#>$Zm/y+x:9zITOn>cM5KRcAѳ2 Z>ժ8 hgofF^u=% (bAt\m띬% MW͓__GW4HʹG iX56}gJ6$SYsn>.$-4Ap-4/,~sn8U|Tl{'Ftw/l߂Vbn¿HhUgf#i0h6"siΥL="q7.f)9J0\'9_2<-K?qI\_nXZ$.=QfoҎɱniy8ЬSr*Zpyz0^8=ȌhHvS c;VP @$/R }6 0I 1wKs 񾭟cئ{:`֔#JŢ3YbRn.B=gA/Fiԥ[w?y>];v.V1=ۂb=OCϰ6PXUMb GX]/dy]ki5`TЗar/>6x -hB.  Č&⋳cbcRxOɑ>b jXU"IKLI+X轢hvz 6XoX44^+\ßAXj)wrS8 F9ZN<{{~ \;Qo/alc (A/$poUw\V8\ %ظcǘRy4 4;p>dܐx1d2Y*1Ή\ֳMLU ^ {5[hS͑MZi }aA=jo Z~Ta@\31@ӘJsv5𢍃ޛ &дc.3 ©}"N-ZIƱ%bi vA27™P;%&;Gl1b.ij/\s&a#60ڥCU5%%~U/jjKjDXiYjFVV_Voo59%]1Mѱg,<ݯܽ<#s4?g8ma9=$OП-=%0*p FߋcUw>;i0߾pCE,=lko awICmbPWмZ2xvz{#@8^osB2l,W&u9eG̋58sPCmǯbǽ114bMlZm'MUmvĜZٹaɽ8d c?k:l髢5Qǝ_O,D"6:I:fBRg d>IywBL>(.U61AҍgAkñ}vvHu#Ϲ@e܇f /Sb;+:6i9Zt,c?RyG({$s%˹$Nz@&Hu3BN: Oz:ǑvIM`a/SlC]Gcqou vX/k(1xB1e0lb f_J ΄gD! b (/(LD+[_ʺ(modoc \%\WHI L_'Y@Έmz4֊E,nX7zMZakе:oLmeҘϦK~ng3#fܑGD lB0pœot1ޜP,o#Ts'3ING]@:*\RcZY҄\ $>[PAφi~. %~zd%>ҸK.I^熃Ztjg=Sr &md2FڴlutaGa6IaRޜV:¼a%gWPU.H}=f})U$5>I"8 Ig]#Л mٮO]G4ARzH!p’[8춒~/G]:Jodp2g6f3ۑ -7i]`݌Fh3  |FgY%,3 ޤ TɺmIl672aIj8h> @~9;qjd$I|)IH6Lz#!YiE2%YC0/@}1A[NbXBt.'YI t hVBtgl6!Jae>ۋ)C_ pf*=У]WPPBB<[)a3A0JUZq9Ii^ E-s{ FUᛈ פS%uXC45"vPurA%,xr}V E 5!lcb6h,$/K&GY;3Y hԕ=> 2VܥcҶœ܃ny7l>}xRhun;/p̀nL7W3z~Ύ ԟ4ffޟmKMt$ wUb}M^jrz‰`?!i)y>JפK)GMx<:K3 8 eK'r,5̢@)ۥ %}N&揫K4 Xc+rFչr?>yhqH_xOԯ)&o4bn`HmI0I^a5VJabrmt{{Gq=wنW+yXUPN&om+,&0t,櫶qsWeza`µGvʼw05Z ۴ɣ0ǔח;G^(92tڪ7`pB+qM'a)ZPȱCuCS 2સ\kXow0QbyxnZUm/ώ&n%h)p>׫> ,&>^,δaK`Ne1,+"Z֨%ޢ_ C=x YQQka`jAvioq'WC0F)b)6P4&Fek%b;ݠM,b[4w1̩V8j02%Nyr1SbAn~S_vM[H&#g`^sZ w{loKlozp3Hڲ3-q~ ynAi^Qb= }hVXan/4­݇n['jndpCoTícΟr$G";ϰc4z& ϖN51i mⵜT/ $M5IS-6ռpI]ʱoN^Ol/Ϋ`iK2yHǚgzt/v dox7iVRZBŲ1v5b8oCM io1%xǸc۝Q =S>C&7s085G1zv_ُmDb{56Hw!1FYrc$.cbJp:yeX)UMe+c[NWS\@O@(6Tpv*;:xJZ| jVoSP(^7K5%4_eN:-vV(b*xIݦJ8şGiJw>m%vqóCq4eNWa onh=DI qo[Hh[@F+Ĭy{Lm2}8mrRzSzX.:Dz'Xo=@%fО;1a y:%>@Ew:nFV ϩ0Ut]as,-9˜hn!G_$=9 $]'5G}!I~Fp!IgZ1a@ކ g~>7rx#˺aT9I}97jc𡷍Ϛ&̌uLse.ш8ti+اC Zh8zf]ygY(,Q-j3vk̓4fhcE43MVitcg?WMQȊs>n櫻ݮxgm[x]xϢ5)10FnS~$֝@ 4]d76^qA9I3_ɝD53 $g⯸D16J ֎zI3KF}kknt[{~j"=>,HglrFFS/䩘[21&4)2kI^]>YW- RVV2YY h,VRf[&(Hݞi $2gx__Q7$>W3Vf~Z#\a,N3=X4ˮndtxUt_V+WWֿ,oM<4O=s&dT^}#X7 ,5:xļ9^oM%iА{D-IeImL5Wvr{fMD'i3V=YטMFV&ĩ%f3fbs#Jst鍬yvMljM'ma\gڑTje~n1fnd~WОqm2KmrCYQf~$E/czQa~wOb9Ǻup9aKrZZKnkek蹊Y0~j]vbSlE,nK1rzț*53}XԇlMOi^9=ֺ/]qxH:Ǟ.̷ 铋X{^bJ]{;DHz\֡G 5E8(M}$_[~*suǭ;DyTɶRvƏVٷP(1P{5am^5sQՙQn&MMC?yy8!JusׇxS̸wWɗIS-ݤiٛ/g]mݮ6 `:$TFPA!G/Bڊw-½i{}EϮ}-X4FߍgxsH,cfkqZoy35q.)b EƒFtL[nq` 7}Iӽ MC?jZ1| [9=)tX9o[+ʏeXΛBeĆjzRBtcIЂӡ .߿Uj۽(71 !5^6سc!mR.42_RiOXQ[ND#C]ltNe<)6빐 EI\ X$FtmטÃ_0BMLi٢0<{7q .Qr(~z׽?\ߩ߾[Q5o GmNx=縖O\so5+V8%F*$~FikЋ06Aj0qQͽKp6S.A{ G8䐂Es yLԨl&x1s;X7+ѿSY X %"Mx/bL]mT6mbp"xδ ȒFZ,h{fŴ33ll+ 6h+ib_ gd$ggӋ6 lF[s6صI,m$ L'hz6 V#1p`*_6cF1D4hQ)+Q$ Us G47 Tˋ!jښEil[!lhCYjg9Bp]bNw8m ާ۴$W7r"QBriѡl:gc :t;<_zrMvb%C_3Xi lؖb^l^ =jTRrSSھ~ q%֡SݼG\ڞ=mu\%]ut(Tosof(.4poAh^8Рr;NisAhp];Wʋ(c :[W%cȒ7uvn1 Bi{Ϊu-5jbIϡhqG]bi7FmVii]{py[oYϻg ڬec-P۲zn[~6C{ǘ˲to0vӽiVo=.1i"L.e%vOnHW_̥'H:m'=ED9/鱞xVz`m,r8&=uU14㼝~U:Lc\E ,1k\ImN}>ƛվҠe.}$iw"X(C!ݶaРS zAyߨϚT(vJEY\=c*BWZh#|U.4[Gm)nѓ1mb+x( Q7r4H83i-XVrO ǔqc9ۢrVrL3Zإ>H#M(eeXHi4릞hhU}ĊgƏHKl!l.=IfcESHxī#&I\ԏA=YT+ѠHX 8m\G޳t^؜bsyptL_C l]d6?r4LdeJ \F,ې$5] OUKڙJF)_F/:A$a,nouX0QRA`s" <[- _>F(AJ?ԃ\Ěd96J%#x@[5q;7IFa`Q**74h)G\^Uݗ 4oͧq\+E.؆ f%k|o\Sa3( *ˤG^,ɻ]L_uiX> 3!YE9ݧ/ N=(]l*HKn2dӅb%?qVy\|ޗaFzs#ӅZѮKI#glIȀJ%srX;{.j-ݾNkľs};[pft_pHwOHc뿾hǁ0Yt^joǭ4c\sF|xr{ڛ@ֺ 8-yHc:>*㱦TKݑY4-q+WIšsk(j};E'3Ѡd,[;_m~륭r4%6?Cѵp=/q≮ӀZNV3/c+ 9j+73V4- Hz7C`? G:t󽳽ZM_8H9@e>gL& qM.'a[5z 7uUBb*b'/9fGn ͨ o:zkiQBClƻ3OgDZN+4XLCPG&K<-!HC,ǽ)*C=tM5)viFߵ%> ˛-^3/c0&ƎLwZbmhcEgj_qbO{(8MbERdQ>dGS4UސE{.e&K$ҞH}*|}:)Gxc5f4^W]>Y|}:gE+RMq"/q%1As&VV"m+:TV뷋l+6z]~3O-$F%)N9s. LhvJ|`Ttʖ3ٞe5n뵍{~tŢ"L@GeD k dL %SbᡌN5anSR8 5 9[/^žj_ȄsF+I2} 4 ;pΗK\bBڄFm5ۋB!=a8G1G|na8X,0ٚӽ,PdT[dk/϶#9q_pυ9Dw10yf"k?//&4"gh$&V4kp1-6e 1r^X9ϙ"oz1`;z{Ƥy!m뜉YjZ6NDf Ndfob8OGuen.8}Z TO'b٥6Ur8nS+y>#50mI yZu,Cc3̃83˻ݍ(顜lk'\]W>NSOEi ? Pp:,5'`c֋#u8&9ͩȊiZoa;a{q^[E|VƘEiϿ X)ŊFq^tlcEYbB-u[[>E2Ŗf0q[7#Kʲ3f1_!Et.Dzv8:EBMkߩ؎ G#)eNu%cdC?Y#YCǽe=Q1G~Hq-&Z$Toǒxs+0 WYUbV}N ""KS%b ~z{iE#نxϊH5cEA|aEYљ~LVLhB`xjWgE+ne_=MDVt" ӱ(bEmD|61%]c|I㴱&>_cE9gN޴r7jzs 5^v-wByh WW8[foh~^}H17OK8#ӈx96oOvt[ lc!Gn_tb7n xDh#^҈fg= (zFfxК/Dsh|\bTC3 X|HWNkLgb3/L Y[Ϩ`WϽ҃MJCdd_H-o%HĨ6]S*YKx_lLd6#!oDD6#R}DG&()~N{^gypw3!̓4_ Lz$>F] YhXRIX4OYj/ :FDX}ඒ.WE;#鋴qԈLu%~*rڹ=dsۮUfdVaƍ{y]>-Q*n@$*mxDf5)0#Ϻ]=&񹏵oDmEgLzPW{JZ1JFHaJ1X˾+rDxBN|״ G)F0m|IV~f C4q#wKcdcd#M_J%EWҼg@03뮀`VU 3eVkSG(1%+Xҕ,~wҮuX5m&;Kv_F`D&)T2HȊ1Be!nv6|ѕF(Q-Qng1HaX Y wnL/\K++Pl}%%g1uL,~Q3@%vIJZ01}L_};Zƺ!b(qj&W]=]Q{!j/}uz#}9u66U.ۙ8DYU;SSĵ0sas*K4x^Xi"&kKXir_O6}WN[~ ث9a8Ӊ™&cL@n;+<ւ.iI.9n7찆ҧvgqZ[I&NxZXoi.`72c;43='Q5UcFIV/˴Ou[8{kKqkiogb8rRb:´!'89j1pXYaP 9C17 )b}ntL{T5K*GŢzZXqO1 bOcq][GlUg jb]-Ѫ˸=b]Ô-|d=vK?Ɯmp"z:iܖ_ߐ2 L<iTrt6p;'Lte r1GŒf;!9S\5)E읥Ҟ)ٻl-L Il;.+j˜ݯ٦ҥP5)[ iڰo-UxlR( Wj=3)ok@ ٞM,V8`bH=_z6,PLPLɒP`*2Ap kIBAP15aȴEniB"O6 p̱_e5͕< 0[ThoW_uq™΋3U*(S4דa.B\s(yjT2w :D_|z>L_ܕRK_KFδktغg::t)%E D/akC'l}Qg:dGWYǞ!8\:rOnVˏ}PLT}~ m\o۲%7|9 ^tZd2{^J_j\CMeY=b5Nm}I_ضt3O9uň?6/u)^mkaUr?up=զqk,Ѩ61(Ft͹vΈu =H۱} tĎDi}3qKkbI%Qk,stbǣ,{?iPBNgKTn:U R_i+)OEN[K2LUȝ0dSXHKfF*s.EbRq2ax o6:#$,E'(I r5sP/Z=QǠsxf'&]t`m8/..HuAH}hF[ }3eB#v X+( jG~9r;_g_ՉwA\fNKnvZ Y Te8@FfWL%k]#'^R`͘5]I!k db-1Y!C璁mϭ6I{H }Zu%vsM:'(ʈG2j>ZFǣItmX2ɮT28Tg*fT2a/J}D׺ )|{BʤP2Y ߗlB0Sܷ7]II[x[5r&PnuNN8 e<<Is5{͉#.2,vWorEzkWb m8\N7R4M٭ř9 74dNn3mwIz.ǔοMW$i}-?H07,g؏}K+zjJtzᆪ7m2tzn?>Λ;n*K}~G~!Oy8[~ɴL~2 c!Cq{? y:a7n!]3˥`^p>r՗34l4t\ nAu<*ZVOr /(}>cGƛ ތX{әm-|e6ܷ!-C"˱`!y {172ɱ?ĕ;P&RQj9rLC[eq%.ƵjjE\]yŊegEx! [ffm W{*^k$??sqGS'vqs^e GV4 `M.MlWޘ̓&˺vaUv]} AgEv}oZE'N)`v.<!)-XbcmT?6XT)0Y>,jz^s2SP+|%S`{e(G'lNoFbOq=G M[t*JT}1E0|>yQ3cw^c@{˙͐~-Yщ^D&+<<4"cttst9yPռM3mbw@/& 8׼8?}rvbH{F#pv@7C6l f9MɆb#AjNK;l^grt |7E+-/|7bZϦhߋrd6zolʹaUC+'hT<쉿OSm{"l-Uxjsm@wCـ~nAt[pqF Gm`?W%ب//lv@>2 %([)AÙx0̴VGP؞ tP"]dkDΥdkF̀gkpΥ%g{bU[361RQuU{6ljKjv-[Ota?Xs <ޗAlH{ֳ iFm#4z1"C]IM[!Wq3D: Ȓi2?cNS;m?'fGLѵK sI܀W^ S*!k7V@}\CUXN{ӇATq)S"f&>9|c9I{'I丧Xk8hk/ZdǸ̦kq.id9+f-e"i;ЙNTn>k,'uyt-iehA=׹?lث1^(QT*G61F&YAcқG%dسͱ,=b'B1ľϹGJ3B&y<`E7EXgHъ}d#{Gm+,8Z2LjVG6 ̍&* 7hFA$*EC%яHDP~4!LGr4uveZ"67iEV~,qVw2>7Qo,)=dkEυ5) y+ۨ1?ݮI*&6twt[Ih0y󀙀RU:ٳQ`_>ڳi؃&ͭbmu)ޭN#T3Ӝc/J˽TWR(%taR2{.VPg#3HoRbsA[3P:ҵ95xYa <d_{oe,Mr}3D7J65䞐e,F`n"E1nԨM@{n[:mF"^1i+.:>IONLW} LmHZ=smլ&@Y-s:\Yi!gنI.z֕M'7FFi@R<-wA7gI!9e97\f`|.0&M IȮϻkjktblxU F /eBz9d?vsI cKRc窏[38$}~% tIK,u-L&):7O<vujUb<#ż r|&6̚j;W<0#ܟfƏ&_rPy꟢.Sk% ?[*#uY8+q X7C:6@$G0YA]/2LXCN]^7KO\1Nú%w}?z"fJ>X2^O.^y쇁"fb8)J<Fu9i)j%venx]f(e"2`ۆ[5.Tidž!f9b-Z3ӱ60.!o9 $:x?,X̓G3&.zZ.Ǽ=`ܲWtH!ei1gF9w<>/QڇISibE;iZ)AL`\DRV Q"XA L!ѐ$u(UsBolY@t@04"=(0MۨGrm"2E,ٌJ2T5.?Cը ^ '&5C[V5B97hMLW#uD`&Fe"7lȹKnL1h-~!|pd??R8Gv ă'mo͘lG~ ~bWu ivZC-m4d*)ʢ_ .F`obML _"# Fk71"!QL5"/ѳ)/r%&<4p_ln/FHa~6oaB?ÉHl@fn2 3K cic]~9Qx3fii]% a-^8qUJ-1J`$e瞢o'h!@_ob:x3QYi;{+\5ML@k׎n-jpr1<_ ̸xʈJpV[bcћtyJXeo*ѡÐ9L~Ș w]{:楿_?;It6YV4neK9U,)7=Ӄђ-2{`kuĕu)˴HcjC`#Z?Y*bx6MgQ'i3:M{q]=`,ǘ01t K?bG;a=!T3km2Ѻ&wF9ÒPIqye9ΔLwN7LZE熺kxMe n`Ǝ"iba:dwyM3ӳǡ̡,u'B]6FP$%JlerײQ529;ueb!ܻ5,m=ϕ'*a.겉-~Mf!kXͣKʿ'X(vm.lv2ƹGʓ˦;w7{'xV{SN/nU˰Y4>Dv>į{r׾?1:\6 pv=ä]VQYwI7s U^$T >ߠJEG4xFIQ.|Qd1>)=7p'~\uT iu9YXIKlhzb0ioXe^APlJݘtER.!2 7K g=aG?> c*)[(!Z"cO,#-82:!F $r?UgVn&ÊU^mbK)[R/ɠ;? !03R ~/櫓[R>`¥889bpنl0DtrhdB8w$I9Fx'%)aK+7@C>>o " T CoRћB~2rC V2p_(`.m[ԶvF,Ų,4IcM7Rm R+0fr4+D1X2H @@5$P| R' U)P/ ]Fq{.ڤt{OdC# /s QBӥuL%J a+k_a3alL eO&mAfV(/À olҦ 3?UH%{΍m'|g̻I1DsK+] {"{qEZV%bOڮ(VH(g)Эm4:n#=@t.O|:-6*%ҕgòtdMRa(5P4'@]IW5;:)tާ5M7f6 4 ve`fyh5X,ahm7'4,  0Q%)&D:͉t.lT+8"֤)v  J}F6:41,ٳQpEN%3vW%yJݗLk u nm7?N[+. {$+yPH@ˆ%k']{'D$qeW$%.U^&PZAFX+*')IJk_,i}Ap3p _.pV+I 3L`D& YHftagB8.)PgvY엺N`&]=7&PJhZ% QL{]6[Ҝ8T+v=*[!Еv_$t4q.skGUB*B2b-qAy:&o/Q\p3fHDż Iw,5t)3IWHfJ׼{Jt E ^=?|}-ߐKcY&\ǶɫI)ivui~&^RZ&$][`tLJU\:u_!" o%;H9vo Lj&$Ls8{Cy!ݲ ?y5i[z!Z,~F2/m?>m qwc{`saw448W7}z0}Np je[ɜZcwUNuCmbU]MǺjޭ$W`Oq퇩&Lk7__mLYF\n/z7Ϫylcچdu<2Z\.kB]%b[ЎT =vmݰwʰFyW g;6HU<+=~Cϝu pIM뭶nrPgDO"c\zVxlX?q#|XHfaXGL}9^ƴ-چˆ]Y٦ky8% ac :P㣆rxA1C2XHf"i {ؐ6^d&ކxRM\[5Ga1'.t94 JK$~r]dl8mgV+KbUÑ̡:9څ؜rAA\lnנca vΌ(ռzowu3Dԇ8ծOp3@N& fCpZ#8zN ߅;Gb"ND9ؤϴI*6M lR#ذTh61L=?N:=8L6l=?WMb6`<5/m(j#6gr7Q w[#,?<טGz8 "оԜޛ́ߋ/UkF.v(iCmTs,OI4qO^S.1 U;شiF66%4ݟ볁nNUkf+1aPV`dY2v^$ox:ʜs&Hlnȸ`jڭƶ=EL#AӋ6k lr˦Q6$a@#ř}+>f(11ߛysz6iFFmٹD;9X*LN("ibLc!jsC#[yhIn.Lɾd!abd}7c6&~;b`l;rјHvn0 [ WHLAclX5yA[Y :bIX.5-EZ % =Nbz61:ްʸ4IQ=oĶl ,ՒRN3oVx,&*Q,sfU@.6e= E2=-u8ySϮ3wlGF1 t _Т_HL_xo\g ̱4 & .gD͊"0~^?x !? `r0"VWd=@քEFr1q%Հ8\~b\%L.v {ly*K۳ĥp͸Pѳ9$}QPmE0i&Z EY$ $szbSp2$3\9s5_'Nq287E:c<A$uH\T/[=XRI KD-]Pm8'S^b.[@>|,po&.Ǿ};mbBɳ k~9qkco9@p1*|-K_H,9ޠgz՜IO*m{yKY{o(a?Ƹԓ7jrt1n59yJ<Ǚcqr2r ԛ{o雤e|ﰄHf#6A_K it.c;syyFS'cQz>*s8tzυvϭ@n'.eOmnq wj21ͼV'iί\nrzVCusn7JUA%`^\NsKˣnnerv6q#sVcMQv>|]?U^\n‘lo/}!]j\&2y)݄l^R\H}]SM 08q3y_;@A! i5A\t-B ҭyT9 I;r.jme[Vt95`<4^PNÜ]i>#M@z8.@ԬGLBj Z cai]Vr}lCwF3wpXcC6 >=tš\+ηߏ瘹@*q|$q*Kӭ468 Ӂs $X"1 jVJY/!gV@Xh,ZX-U;[jWOsR-)!ECTH*LKҌ}U{. 6ig')Z=WhXr_%išAJ |5`h]q~Aj'kH$ZYv*b _} }u;;]78Tu퍠%'9AlvULJ[[ 406IVn 0Bu }-)DtSʮdB})5{6L8q_m pIp/:ڜ`'P4@_nyrP+YK&5Js]&42IJmeHf:?][iEqH!Z%?J 3 N~y_!]ن鹀sF$d4V|MWҜ4Q;+ gaveV@_ deJ}D_ӷ\+y(h*Y{$ySRVE3ܺ%ΰ.2ݺ,xONRZ᜕n/qﰰoCѬξÚ2mI#o0?nXSm[8G qIİPaItJn30TXh&:,4X&/ acHundjJ'󘕏;{Ol'y$ VKXeL]NôL貥[oOڹt.7Vg~ [b?yCh\q=r$aUyX j*8u'A7EyMNC9+m+9rZn1ҎU$0s t}Z ].Xe6V9T6StvI$ƛO}}n\x-K[iXdOa 'Xeg6>8v-ux>zQXezo*{y|yN&3|lXe2&*)u }| ʝL{^]w Vb2?kջohυ\Pz$XC흍="i1nr}O^Y!\c?aJv|)!16I{7qy˶iʴ295.y.i'xPuJX' $: lb C!E4R8_ )6Fe{q{>)P̳Me=)~E/PDAF1NQJٺøɱQ/\~>b#uqMѨ1.RS\YamtQ8n=+˾(<bf]+R4b7e@2Se&4Cui(8( ll&1del@`hC:#=aO$(|/gZ qV7"`X .{Pd2Yj.܈r! &Q4mt '-mlXQNL%v1] hAbfXm.H/ 58w XD40aWU8ںMЏ#nP!‰'Q{-Y0'n#ēF;F1D3S41 `^x* ܬM|3V5-PfqIlX8QlϦ~߹Q~k@|%%xtH5SW1AZ`fF7DfLIAxLdҾ5hLkVR{mUI&5R mgwS} 2l; _,%Nn%QQdVⰖr5TnHsT!*7X\b/q,s= 7:8ʮ;4pɿEy /9\ɉYcoLfܿ ?{Cio3ې(ۖE^N3LWA9j9L4Mld/rKt 8RG wW02pz&}{tZL~S`ǓuN2S?u񲕓GUqL{OX):7uڪyZ&*^c&=ܻR NLpwnr[j|fY0N <ࠛŢFԋ%'|`m͚e5M=&7|ccNM&ikx]ϧZd pU "}3'sA"8*IrYE%y2)^WFԿ֒6᷏``FBAx[a9 JpTS5 R3їR#YؖF]E*I.n t  %Sܒg)oFr`g]h+ګK36$G%-%J-)\VԒ 7’/Bk`[7Gn0~ǾA۷ Y{NG_.\oVS Kf= ' _CI}ӤsEntF0dkHV+: Erqtm߻aLl;z^odg}@X;S{b\Mb.]^eX5s&WeC8Dխ^[b6 ٜ΅U}OۆTDmͲ{;n]1ƱHcV82\ x2cXdU3 3d&mXG[t̷o9S܇52U.6pS\DZNA%4\QwL`83;vŦ s,{[SrS-)6&EG:qLкH[^c^PlсS5Y?9n>sl];=hZ]XW }Xzິ2dC*Ǵ  FiHa~+/5|J'.t#<󑃈ZDy_XX#uW:c+URض1c[z蚂l0[ge;jP۠Ѝ3 XvL.}b x*S\v gmbص - ^΃AF#HPu?">ihR/\S&kQ D5:jhψEmaOhψY HC͢ ٴbA?UIJq2aOmmNVBh(&6KEn1 v_ g/EQ,&AU5y $ Gv^?qnA& AgSZ{ Zak-y#Q*%E,Dߋ涼bA\JI LLƄbՒ1w\F%i ̱51bnIcK8 (kS bA@5-ܦm[" k.hbT8BrfБ迮nȆjO; fD:AگLv"$/if{|T& )ʀcjuv#&;{#Z^٘Oz6N{ߋiN;Yp#.ӳLO ^Ġ d";oۥu}iI{/6B<̅*K*(fۘx 1zm.jhXĜޖ/0ɦM?&"REsmBQ" {S oXpdZ<Ԟ?kDk/b|1- A׆#m)-4]qfk%os|{CV A|6poDL6Z &فڜH V{~115E.c4jaZ^] ;y m,Zs_ .F˜7Lj[6B%b/bx1Vm|ڏA:me c`-;t AفTR yl8U6{w2Sy Dw幺ϥK9J ]s@9S$m4ŋ#GIVrk@fp"1?m_`,Jt׽{7N5*}N'lL^oP>UM>%m.Gʘ.$qI=&='}ȹ2 8% {UOV]D"U,(p+8>8u=:˭iG\HzԸڮf9{ ]RpDluplG. $iu%ǑQZmLE9 1,I1Crt\T%r;"6r"30eI`):p˱Bdh8O{`:Cv2<#I݋Y2Ő+j\FD tu,$΀@mTe3)x(nCbELIߤbk>SJdGF(~&؞TgIuCLbLAkRTԿ%6эGqp쯀 F&y,Г IJ7kK?}l:[[TF{xfWo\]V\Z9JbW\"}.2Y cfG01|MR _8ǂ]Yɰj<10|,%=H^ˈRZ>JL'ҷmG7$ FdA~qV/w_ҥT2J˛F71Mlku63gDT=@-iuؙdWHYs]t/s RCPr(wW_8[Mfv\ޤfϭsuF{682LDc9Gϥ=?D'.YɁojҿA;ÊxDwv7'+bvcat;(BɒUA.>؉m~g* 7r!fod`VDG8ؤݹA[hR_[hE&Ex͏dd󸉚 kby~ܺDvf.V4\,ͮ.'9̢`WֿEJF|.$,wV2X+ȗ̗'22=+Y0#N,SFFjoiG| C\AukoR[+Ttz}K8/Ŧ}I9J_h!B6n28"3 $]}u"#[vLKdz#}lw<2{%V\qڝsM/<)Y=yh7wvqDodAK4g&hoͷF,ùhO7nlR>'Ⱥ!]e6_c1OޫqI%7y#YϷ.};-sk򹿃Uz7WV"bjqݧؤS>*,175i]N M?("\" 8x&066Bǣjjć``U+G=gLKzq+6d'~_k!1 Ks|gE=l&z}5'ExT;LW-mOybRk!YK1m}rtbVM!!1%zf>b}\Pzjr(٢/12E"?^$:ޱwYTMU.g["V9]ĻP0Ov vq{6lLmM✇RxԸԜ=.$UB{(2gpVx#ʚl3E*BRӋyC0NaϾhSͅT (b,džpvp*YpJ@h#>|́,V5Rl7p9jmV;mZo%*Бe3v1.1L2dw c2m"VǘřtoTwbZ %BVnkr Vv=K4 ܴq{aZ$9!6Dmsvc6#9Җi{ҳ&՟Ŧ bM`& 48i+\tE16 "He%kAK}#nLo&n5Kj!TAKjcdLlk>E ﳭ1򕨬hFU(/7,ːތ媽P@N֍(alo_l O;0 : 7h[b`9=;ヵ 'Cr[ pJNzp>m];9 E,C5 cs_#*ܲkTY塂e;Ҩ~_憓sOH6&5-g FbXeO2/2y$1QiɝzH9 'o|Ȍl P-N3ű:%Km68>rlFN% 5LV\cɢ.#Vy1gcb"¢+%9̒(2G {X]u/ NZeI_s4ݳ?Ą~m(?ӖJRoko间ÎyI)3<6cڰ "YX_P2Fڿ_~=RsWg4^6r `ƤYUU6m*w]S?i?ni^ʱޜ~C ' PJO5"Hh蟺_,a )uN܊xaa&&zp,ű1N1̟ojڱSY#%ouTTeZ~'s?ŁDi2h<_*t?8ZT~Z8UYb*W-gNO8T0鮏Ƌokֵ[O,md/G߃MzSLWsfܚaݒn~ *{/y ,rb-Ia߿-^˾ćmntK7v kn޲>argu2CnDf L9nK+ ~:5CER8MeoL879Dz͌t"ڥnm}$]˺ϕTg1^0FKOӍ;zH Q 8Jnt'97ҙ3Zl7HsV&گȌ0BHCb>sHa tTd\+63$.Мp R+d[DF͘Յ:u3"H%&/n[b/q z&T@FN4>_sԟ K~$#Lؿf9 d9duԒM{Hփy3]:-z,ٞ%%J8L/Jx&țgQ#%fЃFy)^z#R&"$JJ50K ,xܢZVמ]۾NhI6iiDIs"3XќIHР,E 8j+-# % PտM64(댱\ JcddhI;[>Ld;s߃Te:/ЉϤpZ|ֵ7G2 X"#guQ*F (~1,J bn b"2LɦDFȚAڙޗf`bL?gj)b>R.+>>?WodIGjZ@~f۬=ɹOhu/ҳdZ}ݞlFܛ!KT%J6-l=lFzg:9q~R7@l,od.tyےlݚ" ZR5VYן.(MJ4XIitNtg)!ˋ,6ˑ80Bڹ4\\3|y3ƿԥ 0ʷFFRePg@w)PԒ&~ev~f?p_(NuBj_Z/27wI!֊"\gmsNV'2V}}Uc阺"2W\\FiN[ eeGsF1)è79^ q\Yx,Ú<O]c.GF?&]}|x}'XN>u^˒

^o1 ?y5]*u*ܕmG~P6M}n0n6]Q)Q{K>uP< zV2O&Ftc_,*iLka%tޛE,JgW)NUJďTeǸ7ΐ?c݈cθ̳c89u[LwLr?u-x]TaGc?Tqz̈́ӭ2 'wǏGI}{_9;n/vl$SJ xPzm%zY)r9)xcB03@ہbAq%P&t9,.e >K{1.繥5􋦢Rb_{N0P(ۥ($A/1'sJ+@Iz'|`PmU[ئ}Zmsx3jTr|ܐ=K2ubg2[0^ x|In wr qƘKr>vq,0pr={^{*|ߧ[{aܻy w20cbw޲ YKg*CQɼ#O,L117pP!XaPncqzDd%etFBqLfK0d.e8Us1 l:vdd3& H,K@6oRD6( 5閘1MY )\9iJzvr(8q6c$F ߋT5Q,U7@YjiΣ1DRMLߨ,1NPkj=ӬhF1,5M UbAx7ml%dX8Bաj/eAjb"i[Pk-ig{E ƻ=0E]E̦oT֖vUbmXcBv6PQlHW::uEK ,!]фÅU Xֆ(4~&#1S$CYu#Ht#+_xm1nƋ% G.b͐%F/mc"mK[D@0ZcbRh3Pճa-n(cqӦK,׆a*nQ{KU3׌^*{Kjւb2I_Jbv zx#]@̅dj^a#"Ѿic NVҕx 7S$mmtF%1~> Ks1ٳ l.1}AS7* "[ fg&3zs\gY _f/bڐ0g#kѥ?7BE@|z6}|v.^^ŭK×=ȃ6Pł 66Eb;"U*qWZ\50 @[Ic25kl$߅;E蟨ax:Ӭ8N'e/4<\>g6q.o |Ԁۥ@kԑ%,]{Ῠ;,yyô{<,s7Cߒܟmзmy׀|nj^A߲Dmw.(#i<#}є'ּ["mc2ybewbM"OQLgRMs4Lba_:+<Вz_*7~?oDZw߆l67&^{nvĬ~{ǘڳ[!ȨrR9{^b~<d];6&.^aKb!nӊc<2渫 ;5dan\U&sTo.1mKmr_{y[ U֨9arU8&Ay mbt\?F()o <.mS|(CcIZ~V4( Z־UD7bi}QֽR+6}܇"Jʲ~Cmzn5acx*`HcX.=<4%eJocZ" (ј2*iJl^Ҷ1 h '3\/-L ;+YHaKItǹk%kjdXɦMoRd2e羏Z,}c>wqoLf<%쌫"[s ø{g@1) E[nBzeo.l*"ǷLBz`a/s*$:c?_h8(tU-=m]}\,zڕ!6e8LKϔkύ}zt@8Enub"?L@ Q2uى͙&2d~9qFo Rq,h=S*|f2GlFDI/,hߢ)b[`(yȿHV#6JiA$'YVIBkPSkGe# S/guKk$ = X,Y`ؚxƿR3XVX21"~BW#T'3|#bSkPK~K?nRbt&5ӊRx__Vuh9/F?VFN6L.ͩ@m3$}uIx&]9*i{Wf$*c/k '빤Kh',)܃(J-HYlg]GTIG&t3Mb#S%Ev+٘0!YH &0e15ЭQ yI(glR۳8ҥ&),lR#ㄟxjLctTTzo`F'Z{n+VXkۜ7YCqA.qi4]Xa%Ӣ8$Z=9߫يH/DkDnR^0"r)vnHB5W Ld.1M{Fܨ x?KgF1_/ZD_zHE%?SK\ߜW{_]`R~+_սD5)}H(~MՖzZؠkTm.اM$pzjq2.zԾ-DfP#)܉,3)R,&s#؞KRsr\R{_8D{^t^>3LxRThtGѾ/]ҳer,t]AZ)^˹Yc:}MgS7\ݦg {i歟E2;1O;(Ño{άa ]1oyDWx1 u6_}S7u<4L?Nv2W2SF,Kjۢ~V9K;L{m֬-zu0NZFJqA./8,im5O':ߍJ4ⷰ}v}0O.\MĄ~m1&Go+QicE]6+i)gV"wƚH.a. 0hXy-ۍEXR0o=|Gc"{P+|GR]ScLp;v=-`1FgJfK8̗ )=m]sd;8mZo|l-q5>1 >oՅ/j{8Mt \;uF]]R3.DCxV6xK<{~%qL{[e-"ևP?#«NUhCz4od-!αۂRء$nqa,V:lzZ &+0KAD(n^̰ijc_:c˺bq!֩kT.a@ZgdklXeM[1 & /Jj%(R݄BdoT7de\cfB呭9h 'QA0c̰7$`,][f 6bQ Uc1i_ xE1,/0j`|JTV<HkKOgKL @ֈ@V3@0K#]R_L@f@g >\@x#]/d7."3| JKum#;[F|m⃛6a>b^ÆĚԡfe 6٦MbzoĴ@kP#~)9/79t0m7_Oɐ/E \5لt6w=o1%شM,U;eSV?7e-1SmHͮh!_|yߴ)foEP͍ۙRsB64 b6yP[ T8N=t&c24ގtȵF'h/* 30m ,z#^PIX@hʸD($/w4EM,6-T%!3mqHX)djc5ŸnPsk5=N5fD#m_l2] AL32 " >w5\t9lXX8Q-5` ~h>s5X*>Y,z$6%^5k5d{.!mPTUe@ԪF&łb@6a{Mnm"Rx#|>yuFHFS41A^5~pF:_"í/߉@pZ햊b"SZ#$>#ʚin'-So/ ٲ&`T3dE[@|f~9K,$O+6F]ul:T@SSažyGמ1(3l=|tN9[?=vo؅LI^9u9k{ȓY+#950 }euy-Klcc=UtGcZc/ǐo#-q쑧ٴ jϟ'3|/n}ljr'Ve?wv ۘ[Kۄt&oG*;"Py{#ڥ`/s9|"8f?5ջu()WBj e3Oac|6}z6A1=Fh)~y5a:- H!K/} ܵEaJ6(3<]oߨ0JH6Jۨ *mPf B9ac;4'7~u 334-]?zHaOk &QZ}س֬})$LeFlѩVtta;?r1=`46؈]nc8sc-!*_O%Pm5GÏ4X4$%]RX2}Aᬁs4#|E@v}k6BiGӄ }Z ]}+Snk.`_iaũ6 cs-K w'i)o%L4Ǒ%t{%wnmAsHzںp)Gj(M/%Vɞd:ת ɼjT$1by6J@!Y7'cPtov2tp=ӫ}]Z2bQ>7kYoݣW˦kPf(١Kj]{I>T͗[zbLRAS?k-~_wU>SRa;{-H}xTPLqacs"`t3A#]a.- Y^l?YN S1eqmXslx) !keޝeY5|c|r׍j_TxV!EtŜ^p3dw[p ,3+8{7U(c\,p쓯hzg:n^+k,UR>BuGzs9]͙Yת5PlP$/GPXR F[8mH,d3Bd`<viۏqL{=dEݫoCZx="8]d і+&io#E60Q$j&Ξ2qt٧YɼU,խ Et9u%0F]HuYf4x-8܋UZ1{g G6X;cL>DFH@IfviM,L+c2bqo})L-ޝ"=^V#X l. B u"dGe/>8G&&q1Uċ5 f,,Q8l OF|@u~( lbKIlb!]l ]סhgk]0F6*fM|gL5"MգG7JQM| 6 ]F0R,_kXڄMV"6dL(6QÇYr5݆iiRf1hjL'+^5G=X`MA¡YK0ZgB]l$[n#y[ tɛ3^́%_#\4_K|mesᮝblcEUd0.61eDbb+M([aR xLE4'K^"MLu1jQ Fe"mLlnL53@ M.$<3Q"v9sfLTp[K^d\g:SNE,w(p],3~𴏭deni7u-tI_ ۋE-@$ưUruͲ) z?Y&g32e9Ŵ}HK-2X5|zg_<5rtzzXTaʔ]!LX[^]V򜚻NCTmNTDt{2!ԻqOV!1)R{=6lK-9$WPEy1Mce:Vb=_ZNHe;: U8ܗY*5o!%Aq݆=c&2QLU/{tL;OMaU< NOht9Ca\I^SF<.)fYLw2ji8w_tv[VnjFUm[x )NNޱ=^3] .c}`0!Aq,88z4%r,=Tô6]s7x3N]<;VRb./9oQZֽl578JWCh ^Xih%6HKVYHf 9^9(VgAqڇ)PiW?j[md!>d}Jޏ>O):IOˉq2Mνat9C nn!1m'#c1ms?̪͐U{D-t6B#`stΛCr !ȱ -ds?." 8JcjN;X: GY1Z2.1M=0^EdTZɂ<#f۪,@J`Yʁ/8gf)eD pt2sC!Y74t &E@3FZp>5T! nD(]*cvs%)1x$Enz銀LkfX;7d¤=9 MS|Y[Ap4X#B 7HV2H[[-C"F7"y C,%, JcKD͓#@FIi1,+XO΢6gf J(Zx:HBiF>?QJTϥv~^4ku~Jΰ7[*9%s̀V_=€i|mLj)/ R Rz. RmwGC&&j"Z{.eϒn؎RFIƑIuFV2Cn쾖"@H-bql%-!p C_zVPUP4oϰX=R Rakg-$\I>Bj+)A=^0{.AketK -iN0`҅t7ޒ$D1*(љah%@hVgG$ޗt=6~)mۤ7X4aυ/4sΡUdWJ`ϸn94LwPEl&FA83n&§qswЇL#ncZPVw1{tnS¶L=a@/a+`?"4~8 .QRڪ;}Y phq;.bkʚ~%2`󾎷cL̙؀0k[ȩ0RXwמ{^}o1pNg1n'K'ռJzoE8{)؀ģ`Y1y> cD>b~?S%HsOSiS;I9 X5K.P5RB0[M4@1#ΎA0b"0;>A |Sd\-Qx&-mdx&6c2eÃJI7m)5Kba8U[dD f_[L;^M561i[=aBJLA b}aIep@7`Qpo.1mQSU9K@ւ50lv Di-' / MM{Ԑ 2il-1oXskWꀯh06E2G /l~s ;ѐ/7TxNuӮ )s EbC[bBLUsqې q3FgԴI mlڵ-Iʧt6f˱0 \ /^HVC1 Leۮ B)Z 3MCMӡGf:qc(a4+4AX1t.1"ұx"Nk%֨Vs:j>6*2)UMbz15Ƌ\cfrLsۘpPӴZZT8ۋ!6p~ 99A4B |@#QC8%ɗf@*oڋ^ I&&^оA_CJ#¢t @m6EfCe;.,9ZT8bQt ͅ#W P%2mKE_R-ń\6CV"@u.~V‰6p")/,UMKcGؖ1@E0悠YI.l%"16gTp/HcO@v;Ĺ "[*p\jcMDf;дGjh-eQl&X͈Tq:ؼVe.k3ʹg3nc_td_M6kӿΏb}{F/(w; eDZq\?Jc%xK}{q?Ԛi5/e?_DŽDc>q;xal&%CG.)FP0vLbktݾw6Mu{= _ڼŭk]2owa . ج))^§yXz󆚪ݧ 9/ؼQW.DZ{W:NU`s9=\ 5>%̡!RJ3ZkĀ͙_{-/Q|TF{[[:=&ors>[i2_89xڪxW&촛wj)'rF{_'Mwn/e1*X/xkYqd,$%Z,pڨ\tc k!AsXS¤y>TJW^*`B7(㈽Ri%\舿ֲ#cwI*$Z.$jf ^㷘R8I,thޓNLǾVza3h+貀ԵN}u6`s IZSg9V.CA]lR q0_D6s_Rǟؼ.b^sh&aIU9pafx6C8[{RXshҩis9><89,4УJǐp)-v9Anyx29%9K^m;-'Waӈ¢v  #MA' Gb `s ]lBndl@@Pn$$B%`tAQH4D1WIZ5#DJZShJ!o[Ƃ3+J}Tj9 UɠkR@4m/J{W8 nDϭW\}PJR;Vq<{J&J5L 6jE`~9΂1l%ms .0i,=S$%P4Ѯu |w7ƱPmBTXt7&ϗumRR3G+k'鳮a)")a3z &Pgx7bR*8V*m=0s%ՃϘp 4|_+[IWu>w_H |cNtA%%)rZ㰤~(wqNMWMWHf-{Km)M 3HDߖB2xyL_=dާ>ڦEUr> t{xYsj-B(($=lUVpFƞ-K17-)ŦA<}eN)\gԻ8Vl5zd[XwrrҜZ7˙-)*sy<\\nS$^)TOƴNqb~!s96es3P[!kj|C<286[ݱ'q Cc΃ JYƣ܋H( '6â'),sAd^nz`g,k}:iƜM 0@gGQ5+_X)֚6|Pb[Đu6} HHhK.4GJD8-sV5r`u#KuHxț2n"PHג)6CA.1bm7O8J4yJL`%K[Fجac/l1lN}y14dSq^`.HT8`cоڗjZbqg&ŀsx8d\F6i -ߛX8X8kyϗ=Sebdg9C5g#2 ~k#[c 1m biF$;N&%{! mL^sknb:11bu;M=fbS &`c͘t4FμWmڴ)2r fLb|1ߒt5`g!Yl*kr-AX,_t@smbPAk!( 6c!#LL[D׳`\<Nw.&CɃh6wR=71p͘t0LӎILoTtC d ]lq%ABp#c[b… /F$\xKwo|Pa4.j(K":c;ƒ%\Sk B&6a(jžŴ_o.a6l|! %D,agùM]cf!h[Bվj=&29}Nq*:|tِF $3kt)5Հ>B.ֿYK`5u drH<0޻5qQ亘WHfL1;.Dd !1%1&4RIchX[>-Td5]ySb~S j;d/Ὴ?g]6=;m>EVoV}LFϮ)#%4bs/sodftK}>14K!:,{ܾޝ,j8|ǭj0gOo&o-/>'8!;B|_-jq蠦*;'bss8Ǒx|읍??Hy+Հi ɌPZ^ܰA1}tNMs94+/rXJ>_ƹem(KLw/J6UW͟Fl,nB]ǩs1gemܢ'a Q'%ͣX[!7x]s1 s`+'s sߘxI3mcM,Z{X9ZtU3r4%12lP#~+sy$JhCfhn#2yu8S9+@Ը s׵:&sKntxCDzstL-x>?ѣc$eSneϷ|(Zuħn%G^/8V7Ĭ (1+CQ=0/C,'qttFcbF(krI4`H>@VcHk.g"tڤHW\}+ml!ʾmK-iy)D8/R̖jE낞KopQk`3!Iec%a~VkI[; J㗤ZVϺTFT23nj .k&uҊe X2٬țz_8YDU1C;kdO妫S*ٕt8Wwzm#Űri낤D7Sd60@~"UrmsMވjE%ź.H(8 |L&?J%d`#oJ6i&2m⒉FDEzHMJ,QGm֬=Xj="A7蹐-YX&VFqRMĸPIv"db=(MZY.H,Vw״2]xs|M qr<@wwfy;uW70t7[&"_[$]}-:8@&v9RAp?%8L6't{iB(6]9ߛ9HbQ=ҥ:cDU&ֳKds >b˰/uWkh٧enz+6x’WM0~ yNW ]lw^ʖɪg/^};>=b7-z$YN.t=}gMo=wϬo<^hѾf#2C>-9=h^iM;&]q5>{9DVg#;wPs"sr96HO3?G4gթ:'xɕ 6o%5'P:Jk1ۡ|,}V>*@eQ< m(bOO'9Uy]PGV?E?̓.ffU.w?RH0t XS+%W_1sTArts2\]}朒W;އC!{TVNQ;7t}ӌ?1N&b8j8N=̵僌-݄U_AքW\}jepbMVdX.cZ; ߻ {?;|G[~F1?%I$^{11 17?KUpc&7b,wku,g0> Fs^GrD >֖C|{b&b:^`3׺_1+&pᚇ29\lK h!F.EKsmxƔ\"mWuכר{ [̘`Zegy_2dzIb^`C$\\N[ӫi1W~O9`NP|)pFsNv9M!ËXKf3(C̹kx4ض.U q~^ba)=%3i6FLkrm*:f%2! NSogdeL˲ (~1%8]PNtz= B& GM+RBBmŀt1ZhTg"qb,*<kdI>+\0>́f$~.ASXІsr 1"@_lf-dczf$ELڄc.A;7Kl KD ɃkNT7[PAD4SącL5'Z *<܈Jh2ZjL[8$Fv(IѷQF%[LdhߞOn'[[z6xak0n-/˼~Wmh--Ub܈Qnp"7ETi%mGbo¡&V 'Kg(6+{5p~,FC~1E)yUsclZ$j6,t_ls,x .})&z~ᖢKPLXS LMoԣݘ|-ipܨD&[ Ǻj7&#<V󯵍khb"pz6,1ZCk!7dg;jn M^ o6mtشsqt(# U\볛8}sSPTjstkvNwlIg"tB"^C77ڀTuء0y"[Ċu&2zPnM,|o{'FmȏcH [ID肘T(8{ ]s>BMLJbZkTVU8N=uu" 5wk1m/Lb2RT8͍51a6}- "لDSݒ}Jy*mbK.~E*NT1QC+Pyv8GGX ,}KL%kTkmqܯD6/}~3XD9[,ތК{>9iKaQ[W0̐ fbOV(]SW_ü}W}랚Ŀҝb&<綠! !V=Bʸ}ɂEǑoZoe!TV?䚮AYْNF_bIHn(SIcm!\euJP_Ŏp}VNw֕ܬ@).F>3TRcHcm|b\>0b!o 5bΠh[>+ KS/]AZNCC6H5G7my 5%F׷J>ԷUB jfsknϵ\CZ5Hxvb1Aq߆ 8sgg*H CsLD=HMm51xIun%+dPi.[oa%YZ)`J GPd@`hĩl&58vs ,g̒$u(߫ dak0{EJ "IWXdP|& d65KR@h%h ePÂF KeW|~BgKyM0%FڜeqIM^ҵ'dlR,zAgIἁROZy5zU2Iא)Ϻ` :(^[R˾-ُOǫz_ҌVi]Lk Ϻ .}gD>um|ak|VVQJ@;fdV2Uסd&\wXGk'k咟D`Wvk3)G5ipY }OR:#LI"Hj蒜@ߦ X4b/I"6( c4 2äg:{KJLS|n"J`|M(H-&/{ɰX ߞDkm=Hn1:_QRtR$aiU/%iTuS8Q}8SO@Z"LNu X-m]6=fY,ꕜv:z`Q[E T.! )%zdHmd e$[5<'0%G„ b JTMK￞C؛&E]HQ jƶk $T Z}N`)IR PA{T2WK<(q%%Pɉ}v+91nd9҅DP~9Ͷ8teG]:}bPoPjIJ4RZErk`"t ~L^@  `WR9Tp77yVjt:B%8!B$v !}# /olNy-i/|24}8hڭԗvslh8+Gi9tjxǞUj8|{ cĚ@Oچ1L6Q7F h-i%7w/}jHqw2|+!;Ic91 4mISz8J i\oJK* |z\f5R?|oOdj4:Ҩ~%8L ^Sr5 s[rśѬ›?JvހφἰCuSK7W/˸\) {A7MEH\.7O d`移6lڴOM׾+ˬQ^'M}rlVp#]߹jDFىGRfc)Ks0m9XgnM+>׫hyо7K53q L{IPWOq_ϵu5q Rㄴ%֝b8i |>yے|.ȩF>x(k3Gclc,c9l ;.$֎B? 1-Ƕ dmWRhϱif4m؂Z܀D6s ݔ=+&ޜ3lZwlI[`Xfx7s 6Som&xlڟ|?./Xx۾b˧ z7-Ĵ%/mȃ&=>G_,4EO|(-\b LbAP0̗E%%Dy[R\ 4Fg : FzQp,$] lC+\E&٥'e :Цj6Ae@];V^ Lf1iH^8M`ڄ6I[c-P?ܵ*f0kAmYweJbMTFS0 a07s 1_ɐm&s d_<ͱ_ϭSymUKИmBmG-Q{\K,`5Ѣ vޱaYt sSQ*78tKe۬Z^ 7KIVQXL}7q~n`lLM;xӽ}M%;Ÿ{ۈQlLUwZM#1\;nZYrp ͹ @Ndsh0E~8;%x5v-_oM6lM^2ߨ/~|-/b71 ֞Ob*cYTNMiaаX7-\R E{XEmoe+~3AY[`5[j(tnQoLپ02|>>f:OWy-Vd聶OGVm_Hכ[F߹qNHFi-eR걔863x:-}d^SJryyc2tѶJGK=έӐԨjenL%.kix(oE<l/OԮ['pc޺2GojgnayqxWߟ.hz3O1_֒B<{{7c*hu8}xέ}MzĀBHsIRc3bq9(En\1?+x7#V3s%E2F{ˎ7yX<ۊ6ن-/ĵd1!nd0Znڡ%`24!>^^ tqLYش6LQLy-]1"5K\vNL5G^dXzW|Lh1*ǔK6]1\1lPlڮ0uKr~Xq4Cn4*sܷO<0Pq|#KxU"'ˑ~k[U[=&3UXD;R&Ci[N1xLָMކ|i  8SnWld&p%i&KJĹlIK℡˼X$2YwGYqV[ca8qױS;/-vmc_EalD"Xd;H-ĭ0)At# qLw7ƙeAqk{ɎE#J&g% HvZō+ށȪcIVӫ׹`%T%y/yEV43z^(ԓ-4mOJwT2ILz) m_F=u6]`b[3mR.]8}yOᘇ= (Z Z K1zD41>_GԒQzm͢Fs^ ^U8,H᥎zѧuRCY=!Sr^O_z)Eλk[ѺL|"}gs3EZVk9"8D63 Ы,^eSةߒ;؎uDeVQ~5S ʴA'Uri,n2&_%z@|5K L^qIJ/Rk Z=iBɦے:,)VuԞJFZU{N@65qXRj&0aV&/zX6w,"D]MA )XsD&.@|R:AI*]IM C#NNYR`w9]*ci^EjVbł.4Jyά޼uKF](HZ8x^,mRhEe%Dme>KDWp6[Tk VN*xlRGҪDI #BO(@%#ufp3v+#›|^ eXp|A}רODfjX_,sɥck氬ve_j'^i[:Mh&/)2EF djsydYHn1딣TM lTeȤ<$˹lè:K--銪lM.2\<21HbYuЎQ%#51ptG}NP|U-g5K#%Cd[rՍk2abeuBU&|0Cc06_S!9UQɫdX/n!~\^R9ɀ^PqIzyIşŤfL_5ݒԨs8joSU[r,X܇ KʇE丗mh~^8~36GBGJwĴ6ɞlh?3ep]}eTDý%lqt\ƹYͤ;۶7#a-a-nm1ܨjR..&U9ğBU,urlĂ.Li-\޼M ܏ 6Sk>!]QV,Oa3+>}݂o%UFUN"KSSbQi{q5k|k=M".is>(U Ƕ^v"t(&ǩ!nZϮ0s\xL/xcO?GL5xcطaEC1]ѱĽwrlcXiަunk4Ǵ$\ZShN~o.=^x[y7R.=eP!T퀚x/Y  +hp+xx5[^{ 7I?\fċ5 QW11 $Av@YFgm䦍4QWi7mpeHtK˞Cid%SThk*"|@7 lf27~(#}UM2dY>.U3 ,=F"n2*9 GmiM%̦L| Rީz00,GΨmAh2FP'R$QH y ')kܚ"&49nAIT Ho(si"B MlT[Nhrkyd١Q4%4oa"ImjdbQlf 5@nk鶆C8OkZ٥2&&aUufF%tu3I)/`T2&ڪH-w񷶆K.}Vp , MtuFd3.\$mUQhkV8q{cC27܉p/yY<( cVᭅMWK. dybޑ& ֦s1<3.ڵX $dp\TO>0&;|W0i:%¯%UnT_tu Te/WM.x.gz_ϩn.B|1cjsﰇ8I ٙ۲l]=ɵ[\1*lq\/o\$fGAG__y=ydv-~%z'ҩaߗygwr+1-'ű6}:g"ז}>r2eTQmz'xK-e|drP;mۖAm;7ꞖHRS < oX-SKkq^ckq-?>Ud1vMV>$C39o]4ӒoaZ[˓>bH&ܣl b 3rONEn;d=9Eezϰ=5jOd*q=kôG?mQFBȐxU7e]R٤Z*qL|Ec9%)ǼH?g,\ehghb'{.HyOM3_Ҹ$FSƩp(T/qFy-a u_Rt޵: T`xcSzQIĈ0 F1Q 7@1:PŦ-Y%bRp7*I`*V~WnKlt)lvꀯ(]"9L$C`##ΤW"Q]ZD4~tkFN&se>2?%%y@B&Uo@D_JBn'PȂ TtzqJ3ȫhWTmlDkf24T/$Nls$,u#pX0p@)pJ[ T2-Y 54F 5YjW噞j;Ba.=N$F8k֮5Z6+*Yl:Ceu(U_U)j &3]rNRʤ~$Hd H~nɐti|abiUɴKM -dWam3%A)",4`ԥ=Sz"|J R&}A$s>J3lm@o|/tޯ@&G5`. hWk1B@&I#54+Xf5F[c$)txt@mM%{R%K% /Kz8NlYX@/V{&Ҭr/حp%g:. + <Qy[K{(Yu1)ꉤiJKg3z"j3|ި6mdW/ ֮53+>kT놾[&*>.9g:F3͌ w(g˺{^7\}^:zxl 8hP{T_ҡd w_\-'KάZuUy$Sg7?5PNsƵyey^lt򱱜o\H:yWo%u!e'ld.SFn:U* fٜfJ52=w_&M.C:}XFвޓw RA]a#QxVY4JޱW-VU"i<خ9"6eN]e iOn(|pƂycS =1<53űC,c_<Ǿтr9l:,Η"Zиѹ{g 6q([zg N]&Y[5"Q {-Ov CZ1ʮ-Ӣ3⌫srN3GcuűkǙB=mF]xe:9&A2&Z`~E]&f9b )bFqyvUJQ}9>:v=-"3'~N4y+h B#Mae *R -&G鼶n*Kxo$)9w⌤mX8+dE2UOVCv%j 8'm2sIXYt&mOd6F%D8g.)>Ђ4K' zw*qyHN ZLW`Z!7YMl2dJ\qOƪ-L_BT8E%cva3Wס~![Lu60H&~&>uCoPfdDwS$4V$ŃXXkX0K[ GicEVr*3uy**S_o1s*{g66 8i.&07DnAk!ڴp5!(3L9f-15 r׸vNXe5aC5Z V CXnk:3! Wچ>581M"`V!3|}@A6LQ _V.'\8bpz& #868kKL\BRpص-帗`Ӥ |Đ" 2=^ T7}`5":v5o啈;Ј{CBfJ IofiЬ˖@ w\z0|FtRƒ9e$ ń$ ,Z勘duc"PjkZ8E%ߨ:bo 'k3710|EK5mڐj36nN%RYj%"M< n"Z9pmtqT6ts&1=wŬjnX~|9;\Q$B1%A[޴ArP4 @|VݔsĶCnuKWF>&: b5LhcsЛ"6 j7IƊڈU&1Z*%ɘ\́ LQڈV@|vq}}=hfLl6k48}x cʵ}mquo4N!>͛K׆ۯ-7w}N,M6VXcZ;.X7k ޠfQ\Pa_څ:׻"_5&.`U]coPf*ܠ$67'P˸^yj/yXήH!M,BcJmbp3t}loΒfQ^qX"Ú·4-w(srI( waBek=m[^y֞r^KO:7x؞9x8[2QQg^t6(󴧘5m/10Ov8V /fIk(m2_نd%qXP[:8޲׮n|nB'lsu?xkǶ+=': %ȴіV8Amq8 کgsu}l#{3@GܥRzNJTfpJDt^s xS(~-ۑ|%>7*sj,s\ƪw}kDVsJ"lclnѫ  2segݽgq|By/^iϱ{ѿtl{䴓t0m@ޕtb͊{AY5PLdg09L2C Xh%K\@Bq r5j 0nA$hBCFI$ f&+;22|]oE0hJ̛c,[h'bL+5u6M.pOTF$qepqrԒeuF$ҏ͚֭GFgf+{ޯrڐT,L}uН06>s$c|+^ 4zwƳY刣.fC6.)һ;m⒍o?^u#XDF)&e8Y DG;(וtE8{K%XuDjup tdy=8'M#\cVz.elGo&Ŋ+ڨ,n\^) 5k7oޏ {= ĒIJ4w" }K6)Ƌڳe烷&׺@٤DU鳮Y0 HG&k4aVNeQDg}A9:zMbJ蹘tit%]# C2Q=}-۲moKk)*g/' _utBȨ̰NFeۘmi}QnTD|˯ތ sNaeW?=Li;=7Ƙfː8k],=\`CT/A}2z?|,:Fe e2G 9n󢛇Р0̨^aq@d2<#I7ة]Tr2柗S<śqZֻQm<^4Og"87pn]mb[[X"Nl~~Q/rb܏qJO9p9yWx֝ ~FeFc^xco ukiӻW?r]-^*2[;qҞo-Trmk^Z?g>gRvL-wnu;1W\2^N")n\rkܒ<\rn]m툱[美HnTf2eZg 9Y?vPI$6Cg 4PXL eZk1S1ƽa-OՂTf q.֭ű*6.Yr3'b\Һ+'Ju= Ž[0ġJ\by/^ YyBZ$18%h 74pruPB-/#ToẅQTF]k)J!AYpRmCc<Ųv*&f._^_ 3I 8// V018v[Q`p8 nr4W P/6nϴ <(h?EeV,~+VbYPŠi\8GZYț5-!a kY3522na _>![ mb}NX6v|85cMҨN9 Wݰ؞8kUL$.f(9b1SC89hsqqjHAP׆{w*mHeddbJŴb3EQvFF,n6cX5rW ڌb-#&(f7u&Bi`U^CKQz Zl" m}*1OZ8MkmDI SMc< |3P&WX8&f;9m"~eLŘi6 5 Din tmnC^}yd1fA?juf YĴ4I0Ǟ7ֵeuE˽5 Wda  Ǐ7m6SKm/cNdFLlmCݯbLin 5"ΧcxܧG-T F׼rLv+E!#.Tf's3KX!Kfl##HFe&2SsXS7 ucHwySFe&P״X>'iyCڟ%`xiv=n.Gg#6s4sâ48vOԆEޭojWJoB^۠N;~^3aWi?{x<63V%qsmNۼGx(/s«ڐZԺX26ʜ/E耝{{ֵ0s>v3_r_IT?,ح!C+6*%ta}sǶt&p&5<}mw`nq.w` {{ Z@@(F>b!4/Ȁ'VN(%hZ1r e@VL`v^rIJ@ ' MR"/# (SWRI3pfBn F\&n`zǧwjE!,%<#V Tլ`f5)`yފ6 q[f(a+YX^L@ߎ=/u!t7%SXInJ.%0@_subOf82꾌 @ l}AEӮ!e9#@Ú)&)&&X0If¹w ?8c)t0:X Z"0!5^5` VJ4p/VvVaC:9cKi<,ˡzT>M>KdPw7xnz}mr"tMpd@c=#>F_AvEK9HvTl*B3tj@1eN_CG.^$ɮ^Hjb~ )ei~)0 ,jlWgAk3J3֤ k rҩ:Bc ,''i-UrI*NG֮uڬz7$)a'kG)% NAd<#ٛbm?RɒV2>lL (7Tm|ﺀ6lzN4`,ǐ؝XJ7݄R뒴aTi;ŤUJc{IorZf5ivKvVWRC_AoP PuLdh=P?p+Ie&Oq Pч \dϤKvjd6;7G*$ԛԷzot#6+]v!k=F-I@9h|&Б`*9y@tɞd jUݤPɫE nTM4K0h+y_Lp1mK_cN7I+veXJg׭iseo1.Sc(8 w?t:EךBn9so$xi3s aHKPj&(A7Ƌ{ Nbb2"XkDqeQ "'YR T74ip$@5skg$j6ߪĆd Y51L"d;pnEstc&Ʈp6m<=~)qF& i fkeeuK,4)? U:bsxr"AUzn"404 ( bDW:X,Ć+m5znkQ Ͱh8q9,%i@h[m7j9c`m=v']A}ozH`,9V8hu <{69L"XL7 ĚydAcHpV77NЄVd5b~0:4xH 11DҀV%7 i4 LT k 5$2c48U}L<CUѶ9iV/8 HlvsKۖ{ĥf?:XJlg&?3pjNUٹ6EhWצCEN5lb2d1'i{˳=mIluCLCbok-(vL l>h_ur1y߮XVKCblIz=exδS>cnِI^д#y8k fnŵi{L.Рջi ޶RNcI{JmZFw/wT5 {ILJ>+E$ Tu'I稯#NGK\2t DHt-֐t88sBY{$_.>t5Ē~'yL/k{shĊ՞Hq8[aV}E8X~Q!vږD|I:K)r)ZiH.z12V1y |.q\\g\\L:q (@/<䃪Ǝ2vF~y9A/r${O"ݧ#x} #ڤ b| 2 }xT?ȋ| hI0˘TGd8I3yu_$hMZ%(KI+Ca9{ɬg^,BMkuDK^Q+VBV8P#GMm=/%%{Yd/YJ<\/[GMN2ogb7Hi0$,{V# U_3-#uAjg`b>+)pjM>AK,,tbkOWUk;,j/InNn>$ra$9r!1am'kkP4pAo-H(̤H~Q]6NRVZ!JzdFL kJs/<;8qu.RܰJ&]ݢ֤DdR8m%m@PJ`9 [I((8PZʤO%*墪ÝJF)>IIJ*]0ы^@wzm|r6<ǚo=i<ԺƋ<"{̍+,=csNJxЍx܂Gy ym q[H$#AYp^k۟/clMʑxŮMlⱠz&mL%Q6:8w#'f=goy9Dqps l@ !DqX-{=S׵D4bG qj[@gb>!yς݈ QDcUKUi`@YXI.KJk(iz0'pcUf|(CWsplTU *A_Po 12 n.[+b cq+A_p$Ձ7T-M`",=Ձ:"[hJZmyav"V*nsF=`&hF1>ƛ L&-f&&N&j 7rd#|kcgm')'@/i#l% 4:htU7&p*f>+ 76b uGߚ'.*-p1k˽M{VhMm̧纱k^8m(>f]Xqv]!R%w/Hgg1{mi Z91 ((L&8}7z6II0p)c6%xO T)qY:E8sӢb|n:6Jfu5%QiKjiNovnڵ饆yؐq"m7:ְpP4&;Pl4 Ӏ/=t4Ԑo(LE&%9=_".X5 RXn[Sܜ.M\5s24y6ϔk[7z%T  (jk:Ѽ&R=R0Zk9{YǥͶa)ży vζNw7w.qRWxַEi x.F؏!1!.\fobyZ A-7'P |F?ދp}aiT_ !fLKIYfD;}bT-рyZzSkFJY--V4LZDd0 %ac2Yugk8S_I3 /V_'iiEr V@"z}J`~-G6)ܞm1`p[DfJ֛1[}!c|_B^dH=* kLIa_ɧuWTrNbdW$ \1p5),)r83D^"4of@qɏRK R`րp;F)zی`gd43AUp1 +1%t_ W4}պ d/| wUֵZyU ]ȥ+W% z- $}.c41)&40|0xo"utI ++{Q CO$zjuV}NgJh^J(ܴs~CLR;da1#HM9qd}M[EVm~UU/|33J7'ZcwPܪ*UɐaԏKa6z/̵e/ KwAoڪ=MoMƄ5F)Bd㷧Nnɮ,I.+K4alߋ*pH7kCdWy҅/@ ўE]y|j.i횊/ѓ"N_ws08KGzK.]S|ijarp-&GBqru H9VťX%;/r̼^'1ZX3RRo- 0z5֑crjmMCbyKduL &Fv̇ics{cdȞS}W1s荑MnG-٢>G$k C2ŵa=[ gR9ł`x*{E,gm| )x=d$khAXIq[ʖ "X ,Q@ʵ.aɆt`G$ΆC =)6@6F6aMLA߮Bmw \bvHr&;7>i9Ǿf15 @ nic )0Vm">yˉ% >(!S\nq;~/Q[DxTnTRarm xQm3;vk |[^7`;bX \,2k5V c 61Z}}Y%Y-Wݿ}sudL*,nӑFjEm@U7.!X怅sCKӨp{0*Ŵ:6$p{ڑfȂ`qT8 p; n` SM|n#pZ1Y3:/u۩Gjlp2&sKSo:޸"[ݴ"[ݔn-P8"cŃDu8a3pꬭ 5 |B6u)cdl(D-4ڃioҩP` [nIǐ uw*oy4 0%ɘLv"avuN{L71CP1[3bS>4n:k(+0e^xǍHM+0ސ sK pR Zk tkZs+%cn ^c}kqb (fe2 m`>pU˞,k|,eC8ξTuƩ5psΖjvLoLg} (X o?Dm :("R@ԉEaPG(;qHDJqgCQ'U46JU4SL)?nNٵ87_YI{[HrhO.~8Q6˴.cckbλ2˕hHkF8XihGJŚ^C&V^Ѥ[Ot׹8jK\;/%~2^u4t0UJ_lU1QY.%q{)lSkϢ { 61EX=b}(ODɈI_5062k惡؞$%BS鈰JacU?"5ͻeI7]Fܦ[AI@ɒ{$F{ܳgIخ%TX'?JiOQ|XE %Co w@^#~_KV3+9Xn#د43lc/z^byiE.2k?{RWsح6@Dݼ28TmR#'r]`u "fs/Y\yETk{zRŭU$U)c[GJ|{˙RIe&0qQH$rh 9^*؏ W vv#'B)]*F3ҕoťum0 z{Bz`oz #nݙbh~{i\P8#۰m \m:#4[GQ g~zӋRjs{6)r*h =[ɾۋ(Kv&Uf|2)z+NknHhL+]=QUUζ2@ɖEzZEK%dh h/ze>gS8_nj3Spj|yTنIa$G{uksִ]o0ߨVB֦ql.}=/[ٷ|e`tŐnuR[4lY}ce_7yLUvi=[ѷ"wvя6r$NB:-jeƩlgUqISp˴(W" e[58kh$-q2?4)QkSlOz1!ßUݵ8.PI"qۻ(6/]Oer: o㸥hƩOhb\O\=YGܒO)ѬuFj*y!:^scPjn%^18ySa9cо7/GyH&}*y1%qLuACd9Vءۯ&fY2X6j$ܣi~Q ?: Vw(ZmЈ֐ܪ;.}ntosTӐѼ֎8Om~'++Y6nchjb"|V^Ϟ)(k{+hd.΀L1)*d [ۀSN9:9Ӈ̂K|ZI~$Bi#\+@cPppo~;@/t2CRlĊ(u[wH;,`8ڰl L|bm#L0ԴČ"9 @mn\a|0#Ni/r\h;b5dtb݇7Kc\JN;z톩g7L51G{J<mͩv~QˁfAD0LuӛԻO{"Zr@Y7aD'}& ;$iT'ՉC\b"Q2X(Ϡ(J~&~fŒ"{vHm*-da#b{Ѭ71kfk@0i7#ft1-.cML-vm%C?>h}>yHx@ΩSo`$&s3mxېd̙g=,P۷X8jżu±cݴZ 5: [,<ǺI&Y`6N`ALe 9/fuObTvsBIFL*CF\(QGg:!CF =jNz5#eRtZy2]kf(ohP?7o}\#!hq1S`qiMp4f`ojX D$m'* K88#"j#7d-{&f*i#c1Q) {}yD|?2YF{n+0NpP&&2AQpB,!w*n ͙+_Qh-$p-Il/mb:,~iސ>1d512n4xn?9(.{8K9Ԙ0Վr8iMMC27t Fm =F3f6pEh49hHȂ?C:uͦ Iyn-b<MO\V7z:mIMM)w.uj,W ;f36_!tsYVecoҞ\Oq}6]<,4M.?t[KЩ|Ƹ@} :f@a.}b.)QnŐHҨ=Mm 1M,g|kJ~=yyf[}<kJ6;>rXbM`q]U7aڃ؏qN)ѸCWC ϶܇sF&ys5WlO{">6ԭH e$iǁlm=T$Msl8}o'cɽ%I˱v$m^HE%}D;OE4bs>z?9I0ŽхGk˫7Cz9;x=VgJ1}2Y!tWVx_]x+98Iܕm[SUyӀ~ gg,R~h9.uSFFqq}Oj-Cs-wF6Q"IcHҩ'1K'=΍$ c#IYy#%Fz-$ǯYۄ&U, 0QiAxf}KeH: F+^.)̪<[itYr8H[V8ݭZu3uf^{[l9!gZcSHf-b l(`Q {{9+i,O9Vz"H=ӱ;no-5XTEXOJÕ %E0:r9Sab5lG9^mѢ+iZoS]q>O, D!pZmXq㪞UZ2 s/J'FαӾlQ{#ϑ1(W66˺>ѼWѯk\5Fx4ԋDAx; r=i\W 0FOl+nڢ@/X֒'1\QO2ٸD!H =SUa6D:RtlO9F#n|iKEّ"g'OIW~=ӭUҥ llS[9@hs)Q%ͳ۩0 Fj ULs/RLIιڙkc]J.隴\yH47؆m0 ‰BM{ оF0s%%δI&]WJ7S|m")L=vEu@#,pJsɢ_gb7>/H솞D7d̀;ӯa5SLR; j+u*g,Y^md ]`n 0;SnBkYgoyKv<-33gv F4B.ie0 5 DJDg,T۔o2Ir6wޫX@~EN$iZ*#tUWJo{PJ4g]-S%gAYWNg#Y!s ߞ.'zħW4 V~Xu;F[%[W~W%s|Fr^,0pL,aƠQ8qyiנd70Ii@7 5rtFzQHDd9϶lWX2-($}2'ƚ*Sh|6MrХ| f(IMgݰ/PTYtڬl{z_(+•3V~e @i Fޖv9p냾~_鞢[5dWZZ a?*qQ]tKK?o֕B }<ǰ'^˱iO_mo"IPla+A#]Q yJew]Pdzpyјg礽[uUwy¤-!eSs<-Bb8A !>#![^a0</r_uǭf:ں-KaYU.)LX/f9{& U>9ayg{txTxߖ}墐c_xp%c:%D>ySA׽K*r RMᦱ[*ĖtPiEJ,~œ8᳦X[x"F;zDt-wH5@bt9>BM[:qnM][{dqӄ=2&B0<&8ط4' FAƊvcI/TCg%F? hFhPkS7SK&iBBiW1C;SobL35knSS g(A_Cl}@Zܐְprir\$6%g(qg1O>`#x ^,i߿v9ع5z/b@k ~cXԔ hơ$[5 5A- N"0QS|"~ǐy Rb܉tvWaXkML޴tk?`44s>xnb9Ŵ͐Wv/࿈`Cyr2 ΍Yb0 igÕɴ7@6DȦ3inznTVx~50!놴?z~uct("]Ƌ(,TNdK,;5;XX8isI Wd?Cb%on wدM387킄&\# +\B|][YYou疳6b [@t 4Ԁ"61ĺipoR#FI(ʼ*QV7Ui16q MDdWm|#{$)Ԅ'HS^/P8BQI"W&v-f0DoLcyȉ[b^j- }5~hD5k!0Rj 8vm0l_l9cx?3 SVD5ppB&ާ qgS-hk4!goP f/qMfc"8q6bC5?[stKܕa}oo R}W63I{ۮxeDs,B ľ`ӡȿáh:+b}Xx:/wj}ا[ns w\B}[k.;!y;n:xA1 Ք>8gN ՅY־9x?qi6ON⪛zy搣2okrˑ%OonIFÇmӲ-( (ڰsz޷9x\z>9!:~\yB5=Xat9I\R!McևX;$Kz߆y=2N%ѬSjjAM:!٩@ k.@c<WW RTƝ\gSKeps%`A0][ץ؍Lq+sl9Z?~YAtsNܜۓps'혃{;+e`ZK8o=׆o-1ۧ}H劰i C&։ i̐el+b -#(4}OlʙƱOX +[ D2Qt{bB=bhd}EVcqx٧e\؎4Rct)SևAE ;t4tS[IřN𿏉+ \#UV)s# 1~>l' 1,9vo8*hfW$9q"I2Q<#"IvrħѠ!wc8ziyy 5IĊxPЍNE+X+5޳îx))HGѱ=t۷3n]"kY~#:#s0X>+0?}"ϵd1rzϝ#=Zt1ۘ5llEAUw7)<sq cO-hL2Dw#2rDC^&X;ۏ.O"V#m'SjhQ1%K)ԏZrC,^*#znfCLTȣl΄cMJu03XWf9̽p uRo<dLg?iՓb_U)оM luoOt(T!XEu^7l9ȴJ՞RK&EU:wɭ^VyǾzeuFzV~]Ij{ {mJlAW-RbO2ڻ`R+eT 0LwZ߷H6݋Q|" 6*Q]dWXwDYrtMV;JuN-҉Gt4 Us|gJeH^$v2蝏t[,غV`W6{Kk{=8F4R'2ېJ^b)m6]*Y7u$5,ZAJdu +3Keuz"g)fK71ALQ@8llB]t5FDxN;"I׫:/6fbK03Ql sbTIZRHEFu"joᙫMRyf2[b#s +Ym|k:_MB?lNҥ]Ȩ$Q,3Ib~x#C@83Ie=tJ"\p4]"ߏ4bR}5VhttN4c^g@.Ͷ ߼i`"롏 =[l}C[UIiRIҚY2.{2ӹ[:V}߾{jO&-8B\%ޖފ_O4әnضTe0Lc?_=a Lswy^/5ƨGWa2K׽YD8 ss3U2c7r>Ԯ?MXƞr?<ѿ2ILg)qBРͳk%yTh0s){+:V6axUWXuydaZzYθI_3 i??Vx&_^IcZC5̅5 '@y<:??5)3#i>rZxyY,I%P>ʛl=\qY^hx3\ G/ζ m :gZ1#riUsHgE{LBXBqGiEVП;v$[e\G̡UܚlMۺrSPkƙh#n3rL'q+kiXga.&gT П;be\o\$AҌcf1@nMl]*bsci>vq/yYzמB _Ƅl#!N=[aj_fװ禽5Qy1_jʤ_:3>9_> 'C6m2Eiỳʵnr+ZXLMC;!96ktaZymNgb:[bcjJnc{ Sƃ+60+L6rc׶SS b.Fbߌ3} :PkXp>$W?qtG7C券DZCկǼ+T=ΐ%b88'eneZ9Ě\Am[6ݙq!#GyXnZ7y:۴^xj9 ܇H<i~#wFw2ϥ/+e^`&J9ӹ\g^bKrPna&I^&𽠀V[ԆnL4 uiM,5ѹܱG%Ax3Ok gmBׇ]?ᗽaZz i0SP)}C!)~v .9dd*p.k4a4NFQޯ5Rp>wܨ( u!#kPx[; q9 lJ,s@Q18OiITSsgۓ5gYE;vۚLҵx61i1Hq8.SgήRra s9J sviGF?h\=`ұ U1K:=tEtR`_B]H }MUzCKB`è6XAt^\(3niv 1.{ Թ-575ni| IhukB\Q<v 8,Sͨ+<1+L9wo+B\ۼvAk;֒(]؂>cmq'܆k8x;F!t~9Jn W; My[˱zCp|4i>0(d!(P1an Xă Pb(% ;x?4~ wnE]ͰbB] jogJk?#x[͊2%KNa_MG+ &IIJx]V8ҽ}5 l`HyXk% {fP†ժ*O L!&)~/)3"󙟓 tVG<;_RҎ!8?Cu stIAVGd;ơ閊{m>CMRy~& JIoRNgRl34Vi$12.p0煙Br0F"U{&$0>H_o"4 p.)Y,a5Fv) 5 @h> }6AbMɲROd jXc qmKa(5f] 3^rҏ]~-QJ E\D6L5H 4N dU"Ɛސ$Yw{o[erÅs%n] ֔Nv?ν٥SZ*|_:Fcқ>36kII+Ěު bMg b]ʯwgu_8tLol b 8N)=s ޒy !o[b\E-; AIӹ= 𘠗.xp5}ޜLg5eWɆ5 t6j}Ɗd}:, L b 0q ݊?Sb^M_=0TUw7u,,]B9,ǘC KfdQolPi,6^4AơKJs ύbdP[©̙ozHW7Xȉ^o-fe֝RQ{ B|3E4o[ 6K*S7sx!lR$ LE/1QR #" K {LZYhW%.}[A=m:xG[>ذ '<婑_y~*)}7ҬvS{wx'"K/\'=Nf-hSۏ%&JZ%h/CBvu/\NU GkKŁODsērpAEd M33* ـNj\% cN\2lY4K<<'Bj&/J 7B6x/Cqs/"1kݟu^|)z}l (8 ށSN˞0pl=qC:ab`˔0$]Α+&z@PDb 2^/"s;nQ0t᳭S6lSbwC"!;^eW,86QMiޤ1c)Wp0]i|=ȥ;cÉa ՛Fl*c&i,vOĎ)t.@V%~;Ժ)Lvh[eu Fu&*iRo-و@)ƔD_scDmV;z",>$ J4q"-rJxkc`(׽ qDF"'N @@iOskW*YVƹ"2&ntg3B%v`4cc7E|#d 4ĥczeS=KSH1:~KDqٍ-7y耴"!ѐ(Dz DCYv TB#VYHϺ@dƪWU%WR`%_z!*I-UYfE/YI/D:2V JR} 3YF07p!j,աd,TD$(ITQ HB}Ld}YtԪ?# XztYs"Y'UjJ,m_QzᤊƷuOt~&-H*~fW%m@%i8" d"77")ͰV/ nOfUfG}i=Ԩp5,AV.=nPɐ= "{YuKJRdJĔUO>CpqK ޺E'rf;6A[2 D} ;3XV,VI戾 ,n֫%oI~.3$Yd}A%n:(XWp"]Kg]x"J-i^^U l_^ߨk|ڴo^d {}#~\`z)styn -53}9E[Xw<=neA7z-r^fщ~̗gsG)ws0z^Q^C|}?F_uz4?xlK̳tg<$<_ˆW|bZ_yg|&.{%;# ůs/D7y_%K'ƔVp'7"Nm.5wTsom*=d0c:.r/oL1>k;c]n=aC6wXlRlmr=Qn*<8;Y4 i/g26cM\E'7Ͽl}83~+ 6:ɛ89M+q4fk"~mh[6.>c]&AO:7`8d8A0NZnpy[@Fj*[00V|8sHv.6nX/Ϟ!x߮\ɫN4TP])2UrC7ǥh4qFHQl[qܟ?kfr#XW9Ǖox =XƏT7'3pk{k[nbkqu)Lm# c/mlm}@1&pjhf1ԏ4"x^ |:.f h 4-x>][jL{'Y*E92#"8W?[x3S_phk3FZ4I`' 18noh;m # iHJu4Z[T8b V G96V7 x^B&^Nܿ&Ѧ M,1}HER#A}@#g#:so'F4(P u$~1&$%c^ t3>^҆B?}#%!og")ۦ1MQ#o;a1~/jߒ Ř^F&m{Ӳ~ +vsxn#L81˸q2&k3E{ F|u{-!qdƕ{X9M# YܡB7:q~K ζC;m86iP8wl8b|R9^/i&gĀ}-ܰ]6IEB4fl`]@@#{x5ênyy0#?cH77\i-fSL3Vs mM aYL3>-Ѹ$g܉А(Lb l+M$՗8ƾ'w,տՀ1א!R(J &s01k׺Z8h0?a@i=muMM#16 ƦِLk_|@\L`o݂_rQlu?nZ[n00ȌݲMfLocO2bx27mΪ"@7l{ډS[S҉5 t|'Խtm8סecivV"$+f)v!Q )gpYw+mUF mhJ#WidϽQO]Enq'7xُ7/ TO{h  c A1ŭ^H˘#lE #*C'ښD0؆ÁCQ@0e {ז$K֒IOz=XD…^*Fb(B26Oڏn0+X<5ʎDLg6=/q6zNV.!rEcJL$]dNM"ThdmMusNg^'5I 'A(IJ@|^eWƒys‹2;Pݑk|q>>ET1H]6SH~$Y#?nAceLF:銟NR`;"y!oI֙dgo׌Jwv3U2X,IޒS:O|G62ay´B^ _2,j([G_˨Lgbl"Zq"'ۀQ_[X*:1>龜 i|ڄ'@w'dZLDG33Pɹh(K4]M.l/16?ƉgJK td>ʍM=8 3wIAYNW[*JneRJB:̺Nd]R$%:$+0{M챻4'T~DpӥL$5ʹ`j3}²ۤ`})$qQ u1'ڸp go+N2j36=:X?ĽdS/)mzźY WsD~$>K8iOd\pڸ1c;:}x[.+GqLy0 =Kov pa?߶!6N W1kCc0s80&Ù?KWs:׋[ R,-ʐoc|5?g&&B4t_ŅLzm;$b85N:q\~p)(j)Ƿa^tѭm\z͈)b8!P!jىcv˘fabK`FbӮ27Nl-^ǯ s,TtsO>oTW7%͋1˽ԩ2_1,ݞ ' 8siP1&K?yw"uK,gQ+vVcsތR@k8ʕX%}KyO%z]z/{9Ձd6{hA1ޕSl_ f-4wlZI3 P)ƄͶwղƶyS2#$MN+,-vMӴ6.~WJnVܴٵ^~t+ 2͉ΐ>,m԰ޠB#ֻJcMj-ai.T3onX;:BXͭpT@d8$yqe"o#3EFiBoǂլ qm]M7#@I d<{le(Q OklHmؾaS+@<:&[\ Ԁ!>tEc[Dmb  SojGA-lFP{lOB T6Y,=1WUvkTk± @P?B8{uAPC /R8X[-]kVM 3Ta5/ݔ +IQ蘠&,a)le1*P%k\W% }[kV' k*Y^ `IlTLn }SdlGL} 8 v`&>cTqek)?6?hx޺"Bte[.nF(Kx f WŽ P%ԭ!v%)7 }D G_R vJ0=IM8{$Tj O@}"O_틈0D [w+?"gQ o p9KpV}r*z T[Hal3387]IWK&{g, ;3Q;L|BY_zlG19#~+giRhQɔ* ϋ`gAL'ž8^jmXGz&q5 M#Hst^jyv?i7c`ɹ^.}}3g_X mz;j ٫WD>Srp}ƗN2>|I@R/] b_3rw=4?}KJ-V}bp!ty0vtf Ij&~d|6y!Us TYIJ{Ńlt ϳ}06tlo}[Y9w1 R~ê2G%wg k촜ѾQnAmC3ޡ9%Kڞ'k֡Z*%^붌iHa2.Bҳk(漼"[=nm*ջM-$xqoҾG٤}"Im},n2'5Nsk-C1xE~i7Zk~nuzXX.?([a9XZ*}N>E69L8ڞTɀ蛇dV}m-kA4mnUܚC09%a;d>?e~άg>|1jo}X\čWAwm#smDOxm>?  NJAyecukAbݓ#|]cwjl2k O~6/|2&7vsΦ^;bD-fh㌢zƙsHeuc66u$R0Ko@}7v5eq 1h\ob)6Xm4PC ]*FlI |B2¦28.SG,.c-",,-X%k(1EwmpxYZE^f0=6dGb7D.K-}\`Bbs޶4Z\[`#Þcp\3\w;$s[+ pЍZ>:.g*8׫.wYl1\bI\0;z|-a7;^Po t i,%+݉X^-,ӱ+Vڈ…Em;9;@cbڵPb!iHo>aiMoZSz$(%7`*^{%gXI 1M/)oD <8K5N8"e@P;!nxMcs 7k9M{6.4ސգ+sJ/%K C]_1Z@|d`t%4^ sH5QQl*1.&Ws4йZ< Gm>7mHq{nX\/`~N@o+ !!O"3EG`y&;|߆=}|r|= ,}9/H]lm:;[E|&S4z5`lmOSMoM͡x0C\P8zu16?cN%6IóejWE :ưRin!}-6v,n^A΋O6b<;-P&qmeA y l?Ɣ=-{>d@ۖMi?i4WVN5x6Y˴WkG>d1SqqHi So3 lXF$*h6ѩ9iºx݇690x_[_A\$6:6hNǛ>~4}%ƒ_.ӱӱ7v>I\Xί>%fKӱuVT3+ GdL묃- {mEbѱQ3_U3֌M㹏=k˴6ƆS>'O5ޗ:ұG1CHp7(dX΋7[tlr[q"ou:b捽V9mԐ1Q44s087hR֥NF TV$p:S"EREokV8p\oh5Tbos1L+ i:Q[/u`IS(Q? 1LG$Qb :kcc9POǹxʰXDyh 1G^qơ:I܅K14D'Ht崁Viv4 D{gIz%mt=`MQM%;ȃzʃ>Hxkھv%3di{0]r]n{aӨ$fͮq41D,]JLňGB1%1&n$,8D/8Eyeuz\3yT0L]Yl\huݤ`.N^/x]ZK+{?vyX,r[ZucnI+C#j޼R @6K'oJOT^˵zҤ0Q*ZIK7s:zzIWRҥomްQ(*hڑQn34UIͮZ7j7zIVZ`͡>(LN#&ѯCRl[-Ǥ-k4$ =8*G@aEM. *u!)E ]Qym3BmѾ=KuUWd`^lm6̸@g;_=>f\xΩ@)|Yj̚PG}θ$' "@93hlA6t: r֐X&+)r`e^d)f>i5~N,{ՌqtAsRN!31K8J: :@ᅬY"֭>=/q1dk n eM0]~>.r &rHSBXe>(X}ηA93/R;%c& lZOIiY@tI)ǗF 522WNj. {6)=HA֮$l6C%xꫜUڏ,H5\D9؀CM9B Tnr& -QJhI nvm=cnozkD:6rW2ICM&9/jK3WBJHP2!"e-za5{9e> ]g=q)zR%?s!N+s)+s 8|q9KdICn%uαݪJm\Tj{(xjP ^0Z4z kѢ)ѢiY3e weއEjaڼҵ/j^lWd,؆{G;>^kӢ9rT\0Z4D\ Ѯf7ZtG8זtjYk,ْiDNcSdhz >cN옃WNP?!M?ȍôW"4y*}QnT{s2WC(sqliiMZ^愢6ј-\hCZz^Qɧ ınu? ܽn~zf4-GZ4<Ѣ &MhW?x3pL#}1k?74{hiѢſ*.oÇjӞ>Xax=O?7o|281 ebE)-:G@ܢrV٠@ W-+gkb`=YJ8haD*| ݵȚm5ӞI6A4qT$*);Z4O>ohs- BdlWսĪ؂,nhq8h:kѢs\e~/E`msY 0kx;Ɓq/o Q,x(<o|TX[aͅx/ۿuv$ѢrQ!}GMhԏS6|yeL:sj3\abFFbh`F2H,CF 6K8hG1Fqej47t%>b& '$ä F0JESohpLq&%GfqqЀ.,IdT>/d}#p֍b,d_8Xq=FT-T$ٚ@Jsmo"Eq0:ti-~AjUD,-=/ٚi`%9M6m,Wonc"\2 {DF414=L}8w`OA{BsV8_T83x%biM%Y*nĚ%{`̙hb&ԝh .D!l *1N@H:8tI6ՍT6sF\p tW`U"> gmb€L,=M"Fh+r&iAbBYL`(6lk\8"kw{7X5>^,NةιO!_`p:3-ULR޴g[6 _b[ 0fk04bongsX[-{m86L G:81{H ,ވF,FBd[g 6̄bY7B/hnK:@DvGnHqVݬ]ID]d4:ÕIklG/iN CU _@1P5׃Jb6:xEV8MqD:smg`;k)Q &ßș(jn1c.SZ<Эf;171zT7a=9MAgM4p4|=DdŊȚ.~Z{W 3Gej&[<4 &MhO_3aDpc:/mi'2464o\S9}0i9yϷwtAI_[JsKSWA1sNgcM%lvV~lf- krL7%dMorwEx.u="\,ti^`||&iyIR̭XڂIgWʛ=MJxf͉-4MAIz,%,c,Sr䐷6CC &~=S qN`y1Ãm[ry_sx֖LޭeE{H>&^mel·57+acgy;߈n%3p ^Slb`JlF9]?Ex*wJnkƚy\YEӚ:fP @qTR(;X 1Ls RL^r &=_@nADQx8㳞瑧3Aak (τPU(̴  _r%Oq&fjяĩi[ bڭI)&ICMO GZBkU}$j:,mٛwi>0m%hl6tIA)t%Ztn-C@3`aQޮT}lTnxl˱۪{M8 @ƌs }TrhطƂn~EMq)Hg*jk^aqNä 1nXUqœ_;nb=_q#1㰧ϺU*u iLY z^X&s0atW\Q0ecoaVco|Xa6\! Dƅph-ĵMق?ҽ %M qMu%@Y\vXϸB=U,il! i0X%'\*$}o)o`9ĺ&4h(0%Ta_ëp*wMTK~bQJHG4b}lDaqtj3uvֹ` fֹΨ[i_$UJ jZQBڳ7О(m:.@R&f[7j~uU$H%So498]lѷ1Ռ@Vo{ZI&kOBR_QU:8׍G]IVQӭk<sAꝦqiCϺ>]'yie0M9}V1nEcԅzӻ.`SB霣U9WtFD=KAp׹a8L"͘y`Ypd,_J %%{(&1|=a6tal6S CC*t%h*Dvtf0]DϺwM~iS%}?aqCɄF 9Y BstB] .VIj CNg›"Zg3!!lFXn7qG7џtBxJ&\4!›1`{jKmOd\IV8 X 6&ϩREV/uM𫏀կ9F83@7ՋTqzLYB侌`>O +]y ]e g,wqAװ'Uz"` ް`X%E=IW'R^f 0pB]L8:&U kHlުZ2;3)}mzMW ׾'(ٕ%_(v7O hI]þ۞u:)vyhJ{rZiMnW%I+LΓ-5Vj8}'@&=i^/^H?)vK4m0] >0x nKʝ-˛?c#f<=o 8 w#_c0cqzLS'rb(ZސZ7=VSDq<{i^EAM/Gv3^_nʮX9,KͯJi} ?ϧ^OZb! 5NI<έ jZKJRN~0y!gn<_\[O`! T"^z6yrR6o{r#Б0[#ZѲMh篌ںZ3׸^8tBqCrfx81%.?ąN QT Ƥ5jq!ZB OV<:t8Էڵ9.xŀpQi+ cŜG~~>uĒTf_hYamĚ9ZJ*a#8z<^صm-ԎO(^C5CMk*.5k<[[x96+Y29O.64N?j<ٹӠI,4c\u-7Ky,ga]?x(cܛ ]}-P-CKEvt,bu.̄6όŒ Cދz޹oMNZp-;\ObTVs#N=!ioOئmSk73i+ENQ3UP+6o:.G-tU-{}e-m4 b=x)k8[gF&mAxlco0a mnq+ *O=i9p)P'a|v] fi pDstavҥ6T?siI (ŀAؠd{VJΈzizuMJ}GO3304C' P*9v{եӗlk@t 6v-y4CAm&\!KR)&,,os}TTjH,eֲIJL6 RM]NGIm*ߤ`g$p| a9x[=.j%_*% Z RҥNҭܤ[gtTT/1I =ltzMZG_oN*`$E]81[jpڴ6Wve}rp183fñ7jp|gG, 5 pA 0z#g$|_(7vͨCGXVVR*8t6 0abg2 p Cm&4X`Ѥ+3ydٳaqpCy|e+̼w =6mGZp˞RtIZpk!>u~vͩI՗if*wṉ5};~As)U1c|*ªR˱4EyЁ_߸Tf?m(hͅ p=ޛI:,l)y"G$sOcwO{Iz8ļĦҞxX9C@!-̓W|ڏZ Z/M>sK8Mz<m[6*me~~p0fIy!g`&cm8y17f6ϙ/c;ƴ 0&U8:׎vr)}̗h<9c=ޯT$.{E)sh ”@\b6GKo7<řT8EZй12Ar E#m8]}]B$̮Hz5z!DmPy&Ѷ&Yښ%Λ|#ۘp'=70>p2uk Eԭ H]f-*.TEAipVӈi]"N\aX2ds !VdCZN)L4Lvx% ,>8r̆ 1,Af3lɐYڵ NMڸܿkY|[|L/PYM`*wI#_422!~p]7a8nTbp6 R7M;`dg((ݘH\Ռtku6pl3V3嘦/DX{cbL_B=t)WuÃqIlLeǡMZCB#[nP,^YdL*d6C66avM8_7dqhp\n-=ύ(ʴYb7q|1E4L]~Dry <_vAֆ]Ri-@U^|/φ~HtI3K[,.x6 T\<>i,1j7sKQmW*==E*|9!uiH b˶ K}Tr1Hۜ P,3ñolҙnT4_x.Qʞʷ9-u7s^znHg19k n3~g;,'jeNCD&#+t:ݐ5=!~}ZeSW6WlWC:ˇ,/=sC:Z ac p73u9/ոo{f9/!i!%7}HXfߐ46_]ǔq=>aD=b^7֐ 'XW N`]l0lWG?"jos|-ZZ<> oܭNn)w.ou:bXab'?z~&ѡ^UDXc-+}>{QL`Jf8X,nq〵cR%e~+Dƿ_H;{#7.7XMzd@5pҧՓfa$k ~KLJ vEVDk>`ed3KIJg]K@VL7#W (}ZfT/*JkuH8$fSaӞBDIJ6] KH"*&OB 淺 -8T/3Y;9!Js,0SsXB4S-Ug+d1r'#*誢Ro6 sx(и`9Uz6)CC Pgג[3lJ((yD=T-],Vwg^Iuӛɺ~kiU1)͐z]U_RRf",1]J+@5)Q]D;FۀJޥR*%-YO/R>Ȼ47ȮT23r%Ub?LOn|чn0~lB6B*XlnETuՅ7OI*0n[^匂U*]֙PDt%aYݷoV)>&R;' JRGd.0ko^FR'SqUm#M_Z_JJ߬%绳Ҟ,Œe|0-HVƹ@%k`1{ζ/[վfƼIcI[u(TK֮ G)B-Y4h:ϻg* c4h8Aja6n'!%+2pͯn@%^$ݻa 0-5,5܀+ya.!8Uw(e4|(O8p-x^vO^aS&i_\-_&fkZoZo&ϔoPDL߼T4hmwPP ɶK~_z7K? :jeKJf C;C+Y̓vHDZu/51ut`gZ_Ry Sy"Kh*nh[t>{%-B7E<Z}h!xVi=*TG8=UғB|Y,NrpQǪx !jl9ˑX4bi!~qW%֎;qfx9Z-~Stz:88kq!c`{~;I~sPj|2^$2XՖJ9%v{\>acs#uR ER(ǔB QN[>2q<,v;QTMk$F3Z5 /,iiK <$҃6Lo4 .mc?zbFrs`RV"dISBiDTdb_&LL4IJ_2[euoL5E-υ$0_iH醨iZ]H6EnIĄ}Xu لȒ!qJ.c6Aov6[pLfc{W8N`Q8ynkKF#a8ǞMA-9I/Ф`oM^#m?=ՠ1 Yqi_`qHp~#q=f$9 T5`db`?j3溞Z}n`:YL2x?2.$~6X Mf/};]z7v:`o Ϳ+m4EӱFt`KLBɓ)B:dw[ӃqE|~F.Ӫb*q٘p\rnTh8 D=ḱ j_},i7XK\5|WiO6ަ={?X{,u]u P]ct7q-E8~k`bX6_Y55mȆsba؆[tۜbOM/Ф N$\.(s9m 5]08ϘoMx iJ6!o#֙B{uo ^cF]{7g[szKaiϹ}{wP644/ۘ2xlݓ 79OןSyA:KZ hW$7/v̞Wr<$UjWݍS,i=;Ku?cN\ɟKڴ?\gcjjio,ygmۻIz,z)v1tyzu.ck74.vUKAYfkƒ&s04_tsSŅBڹX۰~%A% ʌ,1scI'0ż g7% XOg?b?4&E@4Kg'ek,iTϱ~>(j(Ub6Z_h1m˼O2`sJO]["}>2t"IX49+*l\ژ@(KeW&Xn~hFJc_m)Fcϖs=ciJ)YC-E*Vc>kd yIVr4'!N5qkc\-с (yskWEAl#B%iK gYYd8;Ѥ^4x``Li9LQ"M}5N ҭ:.Gꬱw QkGU7NmKmulq"2 : Q3blJ̡xKV_C:~3#0).jJf`hF[/x+k[nEq8\rZt%}g|'Ez\Phio,f{vL2)\XZu &g)ytz㺙Zu&ݯT`=lKfӅq%^>P#%i#Bsl_) IЃпϺv=h/ro*j Yck<αĈmK g]\Xgד.n `4HJmE|U(+;[_jT2HiAY1=s^2[P <'|?Qc,6i"i_î~"*G]:XΆGv63kOϺġ&ިIs:XȰ&5/Z+"Q^wDEJ5P2dg]>’Vk;XλE.UPI&Vgu~fI?gCz{I4pX+VjX_Ȱ&)A BR9Z.\gn8wB#ta>[΋V EQf {⛛g"wqGaQ.)!G&rbb􋞳ok A#C.㪃&uvD]7ڻ0>]IϺ_&Nɒ/^r:2O%zd,xAcI@{ri.>i(FxШKKǶ)@}!zy,ttSTKylYj[M{7or+[gz?#t 37󾴿H5)Ҟ=%HtK-7oȻ#RYZ{lttnGJt~gwf!s'>4fb#>g\ D 4M^%*wLbqWbX,35~ ވibW],s֟+!iB9ŭl q0WVuqlW^+0i\"K|-6=:*#jNH6a>N(uLEk\yQ=(_Ut<#]Y)GdNlɨv޷xF.m 1.nDF9-!$߃dd>1[~{̾ (-M,8a.Ni0}h3ZG8ÿ&|c::!IlM~AYIҹ&&;F4#IFjiF+-t3FR&tNDu1 'Ɠ%NhaoFb"}҆~ G׹t$NXF2&l5M:3XLZw= %;&۹/pb2'fq-)=BFKF# fV5vॴ ^4ʊS0|oØm=FڈetukVct~ %&C/UF5*f>2JXlLԘa/bbܷ6Y OZG KFb5M6ko?LSyn51Dfk6>8qahkvPW.<(VӣNmXsP+́]۞Kiz֞'C컷}Ma)a mXeJaoXgwN#]ni-ooKaPf.G/;e;طOS:a]VSiܑc3Evfef;(sށk/~˜eVVq*.q'V)޶lgStp$Zğ[Ǖ<,cef N]npsBO,9j!7q'M%@aڻWŇ<1YvYV\Z=S5ض!X)z{6k]s!c8/lOw? ǃpwPsEpb dgj"xXPbvRf;h8U1\+bGKM x8G0?7f3j 1Y6FN|n-+hj4[r_O. wx)w(Ҟ,SC1D:*E"js̕k8bQ]JAl;=n )-P1>8&)y4mrn{4ذ3&y@X)>w6lԫU4EOs0}|r |L^FsATw!qlLЃ+jۃBE 9L'$氲u8[k +;6O0ٽ ,yה@j dX6Ƙw1i. J(+2Lm_wgOdBϵ=m <,uHm%8L}Fñup !kjt vR]uB%ݷqXN8dog[+Ϟz; Ǒ;=DvzZ՘ׄ/yXaIZÐ TNm@,58@Kt{W]t?v `t/@ ']A`b"ݖ܀* @^FA5 5H %@[c iku}7x .`lp! ss|Q[ҤB`cGVJ`"ggd [@$eZe ?6F4W»,8H l']ùW)_+465g݊ፚs8Ēm60X Fw]ixt5f~ Լ D^Ld_"%q= e6"`Yw)9EU ?VJU򾝥5`, V.Ue ½c$Fs6h7rKaWxF?6 WD6ohoVKyׇ3IV$"(5`>PVVv_j{$}=JiK0COº d9 d:+ uV uCtxF;ž$W K(YI ltvhI(%pkD*@#Ĝ%הf Hv2yQl׸*Mw7۰Y,'ax1)^%,$Y3Zw#$}W+g.ILHdτEOk alicΓ`/%q߈8&,&5>rkȅ3 0ϨaeV2)]taf @d L#]8YȞU2u,ߝHgڒ$52 >,:GswAtsniޭ١bֵ/ <[3~e/9}<!"Ѹysj}䡡|]}<.?` 2X49y41-Y=a z{Atގr`ѠS墛F-M< G5% Ta6,*y-q~xRgxygWXΚcN0+AW<9'Zyy]J\ MMN1@]#Xv,tV5<'Dzme9cƟ$]H?9o3x $OŪ;lǼuaU)Φ{\,eGcw &;wF\sэy(H\;Oqa zbhl;hsPS(YAcU8P}ݮ]:9uN3J8Xd2%HؖY,Zs=y?Bfe[aaн(3.Nmӫrnja فš,}  +kC[\RCk MYA1Sa+q=ІkJNymalԡƾFB(l;en'.};rBn[b=.QkS+S-QQb\R~$\-ؓBdcDy5uqm}MӸ^#cȾ>-EZX4^n>D4JLPPs@dNƑ@\^(ܸ@4x%5؂!9;;hlb_AsMwN Ad^yՄZD0gF Ud>6jmpa ~i'9ɜu-Եunv~ig9<-Ub+m uað/|[*{Acoo5GJ{s͹j%c/z_w5o _̩/HsM{RqwfƟihLf -fa^šbde1~jhl6&Q)j̮\L_05u-k5SyMk+|\23Sܡs:!^cZl4 n-G[j=_u悲 ~ 8{[nkb@|ü85[hf_絤8 Ec.fk޻ԸQ,u^"|nڛUv`yg_G^XĶqli/ZǪMjL&6w.kքB}MnDyy9$"Z yss9ތZW+)0O0NI>r_}ܻ-p[, f,&X2_t~հŚ}_VƘjʳӐcHLy>%Ιx|\fl1n?.)i8֢+?G! t.c+tXZ(("<Hq`Cd58#Ygkf-#V17G]X5_o>͒ƂUuد C?O Ϙ6SӇ@1/߽֘fҦ1-6\D^c~}TW1w6n9P2M7;o]έ٤J^zF,q3BQR_b߿{N-"hU:ZEUVdZYY1F `Hهor* %fu+@{Ƥ}^ dCtz/YV[K TimuG)9¤wϼ+_;?Y{XݮTgEL-bjԔm)rUL8+_\J>w9&_=Jm%szU4LzĖy~")_4q3~F҆oҺjxsZƥ[#,3@-6LZz0[&ݢ~|mW i9`?cm7l&GIk@YIT] j֖fr޻*<ǎao-Vv ylCv}dvZYVZcԬ7\.ՎJvvZX[r|VHQ>B% iMVҕf9Ym?=,GrjEM^(nvP^kWsQč^[Կ),Gu։@R6_U{n*j"5~m+#Y2UԃjbSKlv&mEs]~=k=("+]H%W]9/ˑT{`*6R.tm-Zi^3نzP+UռvPJ+lFUF15m6RR;;[Οv^tI3? oU+8Z5$dFd/}Tj96ʪT;(녺CVf_I]V0fjvۓ+~of&XsA"Jط-tIj%˞r4ռm5K>Ҽ5ULW;7*tqH[K& #[%~FcEZǾfWUR@c{0@NEo!zڃdWvl+N.HpR gݽdtkey3;ͱ@t3Lf7)rm[v?IXeп^vڹIEY6ǚGWǦCVnnUuգޞtr*}֭g:GoM K̳ZiomK82]xQuzTg5JXn^z$aԤ&5S%:K*/ )uM!kkVw_.QǶҪ!w٤vI5o@Tw暑ttu"ЭժvYJº3Z# 1]Q[y^RUdW.^E[K26Sn%sf,V yXkߗp7)>~>f$ m8b0}r[j>֢Tk9 sJkT2)6j%$f9ҩq%Xӭd\`b3õ+yt8jmPe M />[g웮mFovԿb+Z 5]'k*=|,iR^ZW)#黴T>c x)HH%Zw8] +HVgթdŪ N/%dV2xG{?[q];V)8cuֿ]7Fu)manReS[U)TVWK xfM2c;k[BR%oR8w 8xȫ}Ӆ{$7hLZ޷[K'k[Sd]ZSk3Cjox ']Q[W٧e=)qE6 V=Ř;m۫,)PggϮSOO$o%}̈́Juk7ۿq-o랥-+M7/; >Fp=9hπ; JX<#Qɤr|S KZitÞ|Js;*getƱѭ^xҼ3dRQ`.$}no! G›S_q ->'X&Sg,>EuAVG;;6:׊lgZgvX:kخ9YV+ mFw}xV:$/R ]|NO9j{Iο,J'zثP4/$+a)#kj电x೤~t!ܤS;.ĕ%g -IJNK_[~֒9Iia p_nLQQ4/\wU{I9ooB3?h}=e,<#Q/.S&BOgueݾK;>t['n>GGAJLT ktΜt^mlpYٛW+)?ǤG}x7]cqqKΌ3ġn5hOk$Ci-}f5TR坦k/)M4T!u9&9jX`Q/}Xb5ϐ:R􋞥tVPTq?AR:p{[D}y>ƂtiUVy e!!zD 3/ɫR|H%$J';mח=Y 7_;VIij$; S5]8-mdOE/c _GcG"yw$] ~w#vN"oq{}NJ&?f.G ±ҽ ޺h]̯ ZZoi0XW+9%PxoV3ԙ$ JAwGz>.OQ9EJk `Eo n v_t|L Ji] {u9kѬ7c}@w_M3|>(/W/HvN߾Ю;oTi'C;v: ~^J]з}~?W癁ڙֲ]|]t(,=ɗ ^u}~̓xgz_%3? f39qw7=NqenULJAŻsswNoU_h,܎yƳOҺ% -ӍzPo|vcG%4a'C/D$Uu4h }[&ZRf>v2kYShoѵaMv)ҥWOoh5K_Dgvh ץqT,U)2Z<4T2FFCx>#6 ~{~' GcxD6b+쳔94?~ye%#=Pin\}0}h-_ZS%#_*gxx /͢Z7y{>ӽH% hF±}~K2XG{z=>{eطRUpt]G5EDxyv_yOҺ#l`{~~s{X07*g#2 -`E;y5UXRfV%Ali7MReTU6:-*yZ,x4[I8۸'嵌/ğC! > ^ɝCl˚;K^MK(0۵iۺlͭcNYU8'Xm=|R枥Ė{z%kM ~K&>GV3blk2[Jli_C0ǚ}5$J?£Σm5Q+>r9|eļ4zC+Ve\EҐkLk̓ZLׅWf̾26ܳ>1틣A۾}gnc)~-[JbnbJ_6z{,NӦQb;iʼn٫jʓ gq/qeQڲ15 Aco-\frNoߝݾ~Q%ADbN~~X2ƐјX¿֮͂c [7VA6i[{҈+صk>![M+ A8YL-Q/bZ1&_ &R4J\u wAfu *<zn5ϧv]jrGA䅷wmDj 1޳sRQ(=t^iDž#e6ydmlRz^eT=Z5abXhNl4OS;#1vhTl<3>]mEij47_-*1q9@Px}}\C͇/K4qA^{y8ΊCö@ )eWA| ܵ,}a^I;>7iMS+;nKfIGScLb7?kV5j?%_ ,w_U Z~l)X^ 5B`zX\f.Jw;קoRGp6xC(pp'y/7zzL3ci96.ôNGW:خkVKhq}YuooV G{Mg褳u-~>0-S>6A#q`@(K!m%4L)09跺EI!ayiⳛ1'9{/fׅmN6i~,Τ0?o˹8Q,ɩt“="Kɯ}p^etR6cbpT2AH16R`,ZQ&Ϥ` Y7;/L *a K~LSK)Q*].%W@R&iհ{$h \1- aA p2Хe,a,HڭBw3C"<0{Ska,PEX-{ڵ˖QʕӏW9]]=o/^DWO >k=vyci_ޝJwC>ꃆ vCzwZ!1~'/:gžigwWG@J}f4JhqjrC&׏qzb1ߋobu]w z֋PzK jUsB1.䱎?nJ?6EldklE5oU{qaD:F]#~1!/Cv G&~+ 8 cPL~eCqF^t/W>pp_a|!4$ gAYbL(]Ai_@hPz1$'쵑o$%x<~/YrR:]+7MJc` .%2 07np0KމIѣUW+b}?y?\?Ƽx' /Qgygz7Zƀڳ= zI|'^(Y^UU߹4ySQj<"[Vy&*|r`v)XJI)f`w!׹t.`p']6u5n_RV:&4)$+B5QX+h #Jc<% 'O0Xq򚳱wdlg.d`]H oK]ӯPn`]H9ai]N u}eg!`e> 1extPِ}-wdu`%5?@֭E=X:\FKRl~? Kcc&W7 9 Q X$O= wD/A]$?PKrA هb!yҐ}tdVt{\@Փ]ڊ/#uJ;橧xeҶhgr47@ HXWnoU ߧc^ň^MXau|l(is]骈7a!ַcK8$#2M1gnh/bz7kz03q,Py Sn}K":N@ϫ/߃sLmH~!ҏna/^c.ilń*D1n#:9^RώY a,PG&&n*Qf/$Ctסn6A}$hА׎ ].m/WM zs@ƪrDؙ<z ~B#7BtS@o S8kpr9Ÿyo/i<#)>'Wy[هXL^a@Osd3Kk&铗?9G/˜"ikMш~4 :g }qҎk<Җ`6_4 Ֆ xvD6Fzen%v<7_zW9ź (mLxOS!3,PJB]RmzGϮ<%P(߆}[(?B ì<#v^"3xVf׳5Nvy޻grMmOO4gu=wCKzn:ǖ2Cπ!k9OO/_7`9QJ)RLEX'pOc"0ak%=+ y,cۧ5 ڃ!{ĊeI:L㺤ǜ9 =$)#`}Lz$%Р1+P)4)di9eGw)4抯=ݭmRzU+j.:Eû9&[݃ľgjt! t!݊7Ot"GsO2)B=$藵נU,o7ջ)ʴ)4G1f}Zk꭬UϹ[K~?ymB*I]P]Anp==jh8~.˺c~3!??OJh` י= D眆;_ qtuB}?nK?cߞKKVwj'5r߰ ~,vON`Xiϯ} <=~v\^ Vs1yt.0 BȔw]IJqW-zLscm98֧?2Xg^אA3&<Яx/zi s4gw>$oԬ?۽jv9oV{9jҭ&ދ1l-n!tlA7K[Fk'۝=&ؔeR*FY&%ӎ1?Vsο?,6~[5?z;뵀P>OZ+zO]2?*buݖV|M=Sηnks4~.'-qJ-_rA~>&q*+օBo/}xACq̉u3E ]~=Z4<C;Q;:+8AZjM*QT. mv?[^,ZBg''oJ6Rmwq߭c}KE5+}n$2Be+j.֢.1~'q=/G+s3]_~gnu=T|m$( V` uX`(oT6XSռ~.T­K^شjk}[yV5i\E{YZ☛{lYqhĶ &VմSռ*"Wse Ė O`"sQMF]?g,kfҷM{^1:fbd-olXКSqvAF6&.߭xm]i-1mD.vb\b1\?L T8{>8[t:b[LxGm\k(}/\L^8k{.K,fm%Zj|k+VMXhZlkAbK˿]pYj`FS̨`vLdn$Nwq/wFoj"OX؎ n[b/UjKoсw=i-m(n_KwBEb[jR}%U3<-o3 G6wFb߫F E2%۳G U12dxVCyC&mdahڐZ"13.!Hv+l9] 'y΀p%tbĉ{m Yg"^7c&CmJŮMXs^G14e8Be&"]dQgm{&۽mm|f`cLC, kS0Tn ϋ*7w#=#k(X:Q1%|vn(ϛo!˶|bm5s0Cj@$:Jt-XVd ;&J1\Y O^:{L6E egr6{ A<6.jl7O"jr-w=XL{=ڣt'q9BeTh}A(Zv"(H(1Pdeb;q"b"yc -Y=a, \-^`Q6%dCukL{9cN?7xPR8ɰtsPI51ⷭZ1łѷ DXqc9k YA⽄9[X@,(\XQp]uho-v"OnfсOO?LE6֯0с2"nnmܿmFc$d-F/%2we=qs$øw.:q:Е$0gzsK)#)#I&Beh[68T JzLG˟6:&ґ~MziiIk@Du,9q R8i$ ZMQR*0"KGHd<J'. ɯ ; ^ʺ|9p bhk!vݠňcqK?ĸw%TB1Ϲ]Pj%ޘnLKTuCaij0Wg ߽]kKۋBuUlj59K$%8Ԙ*_i+?-yߝbWٞ>sXitiڦĤu>D4*}R봩 5aXyڥUF1U7&* :m|ITYl.X:F4z0}vi t~~@"iЛ~^tOÑ] H ,h#2.[gI`c4/.^nz|>N9afƖ>פ@(Uf\gEεHu1TحUo `RhʺٕٗM#iz8-%DyU 8G4ݳgӘgMa]8Ƃs.n}7ԻI͡I jQukkXGҺő")$M:|qkCޤpj3ib{[ ۉ t,O8b%K7ዴg`+Y}vԵY<Ւ#y[}^=h%.tjNG3יtv`봘ӤߤIngcT빤F7T*ƂKtBEvvg7UgGfI=.n c馴89VrrDHUrm=ULсQEt^.uSt3ffתp8j _qj8&~I]IaeJʛ4!X<&ǀVre&ѻ q?)0V+vsr.%FHvg,t}Һ_${ a6yImn]Z{Ù*Ut܎߅U,IG&ͷLnm['߂X]n>Y.nYNz]Z[Hc "I5A/FHrZZtGJ%k6/]ձ`RՒq%]A=P2 ,Kv~/Y;z+m2uƠ]ڛ̏ Lݸ.bL2 ;cP30nu0BbdX>2 !P]sb7g]֑އ{5RЬ]o|ˮufl%/9uœ,6ΊsKm9dz}M,>;뼷oz拒#Eo44p:Mnz'ݨ8vgit_xjOUwaJ'-\<):GwI)V+ĕțż;m-GzLǴsw9ˬ#7WдG iolRYAլav\[dmɖߧfw"wA98F&3Pt .#-2^|+d,<֬a捖`v-\`5@鎅012?a:K6Qpq<~},@1^IU tw#r8L JnsY;WEJs5zc`gki<\ģ*--9j>BzSw5AP3'~CX?T9duD&Ґ'x\ڲcor??n {6@b=6WvVyeزfg[N[b=?ͷSr\9tGW-pu0oy>(O0-2[o ~B?-sOZ2ó${ڮ8U|%ilTxmbc0cQm.:2.7*%?6_Jnm1LyFLRyp̣G_X[VKY{Sъ1a+Ńl16OQH^QZs df)6® Ӎ_SM rI.XyKLL x(;:0%e,- LRkd 0Dz~c`ݎyS:;6b98V8A '޺DzybUMshVzL[,m(6뷉c 2OǪbbۚ)焉njl0U- ŴXطiʵ oSVmi>`bѤc&ì)A4ǐ[ds p0_ bn͉䌙2ɷ,vILb4N=&.lQygqqQ߽+mK^A$OQ>hyӤSjǵs{&2\yCFX&cr5(|3j5m` t` \ت^KF&ػ 8vjD;o4`;vg_ῳ4X#,~i9. ȖPui]1\[irv6tR 1ҟh^paMG׾Y7v-ݽ7c2Ж Җ5iyS:n4 ?7;[%Ml4&cW?xf1i:6ԟXv&mCP:Ʀ1iX/4a Y;J4Bcc[x%BpEɵecKWԉѤAj!ȍX)JDX]wF856hDfyXXWcb5mW@lW{6 =^I]~/k_4ֽ3iPT^ty_j&$Ul-.,9tfHܹš>uJ&cUF_JZڡ$1-i#ѱXX_GS[gg'ddK;(QC iJ0v2q'5vcomR}򸤀0<5~#UsdѤ`4i -DIz$IY+]bZ#5խңX[|4PRh Kw)IXs:"7EA*= <_$OhK5ߘW@ը/$KFT Ј(Wp#&8PYyk$xw0DÒIQW Q1D*T FFv+ĸ$ VRJEwۜ7)WU2n%.(X]au]`0J;je75yjE٣ 3hJFe,bxETI3R1jeF9ΧKRk+ M_`:ET+$CELI#بΏҪ^F'S)=]e?䳔4rlR*9}H 0#=3mWY4aq&vlw)q)CxG =ȣ 85`8X;,%?޴XNk 2X`/ !-xњi]@] @?W㑈jz-yv͔rօOű@#HϽ|3sY~/Z,ImPwA4(9IZy~djgAZFgou)ZѪARwwP)N^ X{QIa,؛&ܫqx9(ְ0{C4Bmؗ-u,w H:>״9`>},>nݛla}j<$Zk8/ty;:fmst.__s:DC"ߏ[gHϹNcj8qooE^׽Ed>~"xOw/ą2uɘN*wF$|lq~pcz/5?.C,?aֹ39upf_%2`5-1`\G׳9M7ZH!KK8dt)?:g_-N4U<Cn6C,~6SĊxU ?K\Ï8Gu^$DfQO!D]B  Pmhvs4mn)h8ыG/.1ufϱIi c]b~2COZ#%Yӷ4*62>c/T[ iG@-Ba XtK)q=6 IT fjs.Wb}dA)u hcVl׵hC\od:zU~wY)RVdX|gi%|x't=F ylSo9eOIq7:GOŷݘw&>Cޛnjo:ϴũ&l0Cb[pn-۵ũ&8h)ڷS7N5>u+H 0uk y/+ykopXqZ:qN&VR  F/xNߓj`݇ ,eH_jULf0 s6YGVs:v#Y\#A_M{ۖ瓇Z\LB3oӔkbcSU9#F5ж#x[dfN5 <~CI5G ko"& "8JLYo#3q5*hԦN=ͩupvژzl^L"/J*IĊeHb-4"vIl`sL3 PdTk3}MJhV^4&\T\,hv}|:GIvQ D$6 mr2\9P-nbݐ1=~kL5 6!lyV"=n܄Ū!Y?LF(jƱ}&McPf-&1Spc|n:!Rp#ⲷ9p'o,M܈~<;%-1xN 1zNLtišPr΃[Ml4M\DȴPŕ*R)Zbi F5.^ݾ9:5ۈZ i>s:s8#29]kt0a]Ǵ 1B6E21;D #ݓ8zسGoͶشAF΋E Z˘(rLs!'w^XN"MgC𿑦 kX{q6f>E"Mg/Bv+o|xv 7924Ì9A[5Qs\s!1b qLC3ݻ;cL/<ւvCf& Yn)1M;y&I! MzcQ<Ku^<]̅Zq+<-"IWHBO\ qICK"MSOl=NQR۠9mRƴ}'׆=95w۾I㶵-}K򪻭K #, xD}qn+4?]V)N51Z:*t-1k`,SWPKgXZ{&fBTgt>LV?-SsCZ"/.d%űzjc$bjؚIÌD@~ohKW$ylUtt:+v kE%U.j@B]jpl^y@K7鹭{K|ҘēU8盱K~\0ɱ+~3"ĥz$7|'DD4w( LESR_$t|U U$3Z4h,.Vn/UtA*1Dvi_3ŸE5R []gw]XD6vbXc@uJ~%)Պx4~%r:Y;RIJD{V8 )x^D.dQj%]JD'v61HէNLyc]wgҥIV/2R z3n"?~9Œ>ҥ1HcY1-Ak1~9ʀj܊Rjk&JڊػF$3>.ӄY %8ykUX2*Ώr`;g3_V CR Tj,%g0?ϿQP`xcC/qɺ1NXѭo.V,|aIګ*}]uFpwu] Igx;8Zi9]}Y/q:7V`jCɱt0R圏+4=ŘOJ{ZVk5N!)9)V-7|wbggH 6g絴Y :a{:VteU {1u|Bkfp }0}F7nzUm֭T/8e/n4tk\fJ;m)(~=][7X躓ɬpK; iV4&)U4ߘ>swɳU1ɹU3mt]9(ā9nضIxkWm@Hi=Ͻ#P\3yhM;LW,LyҎpm97b'9܆|~=(xs\Oodi1"{??>|LϏ65qTC$8LOrӚ$qne_1.ɝBFbE(%;}=:xʳ" F0{7~Ҙ[{t8vGܡYQ,ֱEE|+Jwmrdlcy3] f31>g+KF6ܢH|4U#|) W?,hq0~81Y[l#QϣZܻ*vzf kKLi |q{C\Ǽ&gZلZ,5e{ܮMKs̊.>G_F\#"!Dl@$ƶyj9N,HIh1#Rx1OE, OXRi)#FEv*m_!"`S 1)oLcT5m|6+f:%7m%&@6P/H d"ksM`fqRDZ-s1<JvbknbXjquĩ?i7ĵmJ(#;i(u5/Vs`.obiV"qR$D#[@t!1[%|Kvδs2}s(~c϶(X|$y ک6ĆF6iKh[b)mD{ CA)|^$>in/\\b kbUh ZIӹ^p阯4ONӾ^hN3̤ab&igjqǴ18{ Z p2H5y<3Þ+͑#Rm]mj+ ;~^dj%'_Zo FO]:&g)r9o_~Zll7g,a10x޷Dc6nci&3 qغ pId fk, br7 n&1a_HTSHRMa8J~s܇w3zkNB Rw{Ho)| vmA7Oq׌[x=v¶o/k] kAQ\]Y&#nml= 096S Ntyu TsT'GIsLR+|ڸEԿ!yCɩ.ݺڱRlgۡaن1T R ?aHK "xvTb<>(\e\ˮO_c빢`CA)Xi_^hhVpT'HHǞV֕^L\aMɵʨےuzP+ Zr?kw\֓)9%*.6eGgB9MǹA=U\i,T6pO*Udr q^[XBKՎ˱ VI{.=48Ly`OZ@t3^H(2x`H+ JB{^hZU0 n*5Y/0kB pNr+h$9$g&a y^^п%t_Uf+-"M x%K.“DLHX pc^D\id9B: uU+u%b)!̵KR}YWHkI`w5Lq%<ꚴ"&B̺]XnQui6#k')Aڅ&+7i%+",au:jͳ7dL4? 7}tjŸo ~^ foӥyR*X60уPu$` ^YI1LWr%ϡ]m棶f9 BnXuK׾ cjrjJht57DҺ0 S]/z_""ah.WM'rо &`tJ.Ia=B]+N1|dXuEPG[Hxs#JzJT"@V+_„GPs^ڙZ:kR``Xol(0>Jk5@=ؤIW/B+v2 ; JuDJyJx * `&$G4od A=9qEohO>"@I!m ;\/>@:ԭ/zW+ASz\L[SZz<3`z a)=%I^`dﰔG)o( 7gݮغQ|uΡ&]t|݈:SRi=.[hix.K?]y@,5<"پ\ycض)0GAx&ߞVp*9i;Zg ?cXHw_޶ ;~Yڈa2y/QzGW:1݀dg9oig~ZYa{CUwƯmeΨ*]MQs[htt*j?PE:yڶ7%k>Mio'_5rFLHPn>'z4+9Oq9զ8? mCMpqҝ'0,.f#)s:mv9'lxHciCǸ OC҇Um_^ZGC^ςr|aQ;mg&}+{PErԡa73'Vq<Րa{80]6%:4ؿMB߶d2 -"x H 8{h  <x_G5V[rحem aX>9mϔ?Og!9+B|Ʃjk95$9ހ7fgJr'_z8|MrkP>? Ֆ!PEtJ9}rog[$EWN%(hoF!';}Otpr€QD^!hM0F:+]s6yr]2"$vO&/9aUDmb@e :@(040c"eP8Rp#Lai8|dE*;'pIKEL(XTu&1H1DU6JQm͚ƷNX#X5 ifl-uߝSMDF0ÿ'+'dcz`sm[5ODg0D]5mx lZ!|_ĆM0MH661|ٴdb[j^w6왨mfQ"IKaվ16ZC 0m@QΦw\8^Rl7S8,~ۈ6V`sjsHk@1QX Z^7E!&]d@wYLøjPĜ#Į-;q؎'*ikڸ ij@]yYĴag(z@7ƾF‰7اo{Ֆii67}f{AS8rQ6& GxbӮFDgX8> ] ZGL[-z%+BG!" $Fz8h裶(Fr9bڑ1cj>dl o]6 ^ђ&^pdUQǾ%LTrQen@70_7 ,࢑/XT[6C \fP%/sL{@X&S4/l",(a! [}+El >}-q bbA0S/Lɯژ8̢&SDl2j6 EUqI5Mmu\Rs5&lL8_^peieeMK=W6]Ē5=~gA{=7d3;i21mIr56ceϑ%~scFt^!o0CȹGJgeb=s7 |cr^mYQ<*ދt{0rKoޜg;f ^Ѿӑߦv:9Un&^rPK90o[4oh_SK/OMRyc2]x0oyLTӱm1Ϙy.dΩB\~M1oه4oOL|l1mM0am )'bI,9jmk_ \VhmD/)6O>d&1ɋTr!?dRv%eܭ-&3#׈x/ {|Gnڄ6&3ڧq9#U٘-AкbXtiied2K;j&q1mW1Nmjik[uqn1C4 Ƿ"}:sHSDXTVN<+0٤Wƴ,r\~)qp&3Ic'W31U+_+5'TLf x~LRrJϷ)m8R*2K_cm'7{/;I*&|O$#-˱MR{>v]`[P;Yju:^.s)+%t qfN.0Kߒ32nRLzNŊmTU2\gс#S/ \%Z6˜@eU9[TɊ'&2Ө\g~+xS##eAb}˲{7# R'(fF"+#_:[P3O$5]\FK*&pPJ~&Œ _޷Z]wD,м͞ VG2IIls @ jeD1XuitKh3j TZW'EKf`"ٞtZ!*.Lj#%h {zD ["(ҥUjk(U21E@yɶ@T璉 -RQ%],)؆}MjfP+V05 2̇! 135@ vnE)٫12{,:S kdI`l[avl'BFJ| =H%#C9 RYfF5-GO1QEo~*(Cr&ַIg3w RʕUun=$TRq+ld_1~MXDP*7~.dR@~0]Q kVxX3;FIdqDלakG~_ڊD?~X|_D%)J&$V2Bu7 gr̀d:{qC.etBAV2Gj߅YƟϳ͓#dP&62I_e/41H3Ѽa1"7~wd])nDn1.vҭ%Xjſ[)smIb׋L6u.0]EYep4R4bA8`(%~5ۑ_MRe6IiR.œ;~Xb u{~ Ҟ%]/ d!0kaXR# hўs]tlαz_u LWBa[':~ʗ?/缷8%i=+/6c7rny+ў799]`t"1u䰴{g/ǝ~q.cῒ|L¥8(nqmoMd{Hw>U\=qM٬r,g+x7^b po8i#9 $*]߇aJ%zi_˧Z2`jM78Lie=h7+FF{3ފW{63lgGQprhüm|3ٙE|߸8>yWpf+7ah5 l޴t1su1ޘk=rz׸F rnšw-,2yz$DL3ӟT~-^u+p㹝}K=m;?([Afw"}SgEfXtD؊d?Y" 1س:r;N8Wߏ 汶(yRȉPRѤ) QexlW psa4$cR&e>V\)NCJg*;ִ3o Jm(^zNT $:cBy֏q.8c8X\N${ϔVAifzcv9zc{V33QZ`עp#%EO,vsyG阆@^XF(y8jaibl} gf|\+n}Qx D^n.ߜZ-Vyo 7_s(:9-ޢ |N\Yۺ39Y|j BZV^P/ے{^zl䭼D<1šv}1ݽ<2i:&t:ϳ&kF{Nܿx+@+pK{c82EJ-*Kc+}mrҽZ"€^ܒNh@J8|yWvP%ǙiS GzmMƄ23.ӖlC9IzNxmbg ze$V8n[""gC[CLG#O]2LS&k4h }Nl+Rxc;oJk\nyE7[.tFN9 ::5tyRbcD3|e'EscĽ >Sz>F3sېQz!!PۉC:x|\B?xeH4Ni岒تi馐nvciVR.fLH$hFO q26bCkedW]+%1?dV[bkr1UR`'nhdJX#KQvRDȢ$vӕ'@O}f2"+0V@~{E>JԿqwՅ$*Ii]-.qh4[@>[BI^T%Kߥqd;D\Vȗ!)IK HW!Ff푈dW؃md7eHtng3βv7Tl߲sIҊcRXqT2@dgV,X;7)&HUg:M~]U4R$Ri IA'QߥK;3}ZHE_$>*~0q<2z_4ݾj%ۊ{9ftz] v2҅kRȺGV28B rRJV8uo^lϴ1i CoiU.m]/qywa "lr]9>ƣE.U@ZsWJhs ­ݒ*.6Y>_cߛ͖YIzنe(N~b!bH0XM Uin>oxȯrLӾuo!2 u.ݪ~wӍHf׋vQ%),s|8>k~63WuLNǴ$ ec=L]ۓ t_΋v)ɬsNy>oLVi"z^=kBs)p[߽+R*.c8(ӭwqӜKpֺ#'m_yJE44٩Y~|S)鍠sڹIss~E4~Ro@Buzeuc':̭A>blND6Sv sL爱lO!$f:?ֽnβ(x`}.p0/oo!OnWm9=fi4"xnq/xuN%kLroVyLѩڟfpG[p (Qr 3XLǦ5EV#-4) h.34f:&ɣ-<ą&VhmbajrE09\w ?OR[vl4.&s04] 3cY!$KnF8#6-1}v }1>$B 3M8!v)q0Jqc,mc>XVLOu) y*{ k?l[YCvz7ihsB`e[fy6A8Ǫ<&~rPr?˺|77%&C|^;\BY÷ogc`he0}j)- 5b*Rj_?kYF-&~[&20Oї&lߔĴ812ƅm2mX=f4Zbߴr1-s*LBJ1Oq2mLCY;v=" 6Efkn=L 8V/p4p#RM[I[(-[ VaG\+6,0>[ MFhDaMHXČ[Q,H/wLڵp4ŷsoXX?sl=FmX^}; \a8SݠU%4 4G,yʄ.lMߔ)o]9i#:oo H54."pjJʦ`” r ,Jp=FǵW'6H{d&ФmZѠh%uB.Y*tRLF e<PzY&9j~%,Cc)q័G, }#W2GbZ}Gm;j?Zh=֒+QzD1ɐ_ G2ᖹC\GsulERASb܈V#m(m=aѡGcNiSƚ K^=<*ӝWx8;.a3LFc_bA)] ~7dxÅJ53X 48{C\[% wC\ckZǢQS<4/8=珶$ݝm]#eoǂ;zS 9L=5P469,ai9u|L8XV啎yw#SaXc:aKƤ·\ڷw];􌞺!<-U>E>,k~=q_Ba払 %!1ua[S'׺`dZoU0`p87Rɽpw+?wu#4/iz1vC\Dvg!ۅ;\s9a|%g5ӹӲJ 7S֤ qB@ĺLD[ JFQPIT<6k$%I E4/uvF鳮TLjT ڐ&?+Z u6\t: mgɞQ,[) О87u楇ͺ(K ڳ=#ͼ} ffLZI!j>gB>?>C A둒HԄVNv,|cCk ؕ *BcK(%]^Jr FVVg@_~\!%8^DJJ(5BUɀ^Rɦ : J)Mg˱ R&ې F*t jfUJve dUdWU 5.pή v{Yݳ~?#y#ޞڊԿVR:35<#L3#p;?1}sJ K#]:t黀F7Zx~^K6ݙ 'kC\C q 2ĵՕϒ68*Y4pMRIl2b%7kWil՟ Xׁ%!a.?a25F_%'Gy9 -a{_ݒE0߽Pj:o7ϟԨx { SZZmƮPXyJI_t+2Ei[=yY۔ &/bmj2]kkס 'B5FK-vk5:B\'%jJ8}̟ b }42>!ܜ uq 퍣(xJ9pqxP:(Dv#ug.:A9Ke:Ŀ]~;D +8c/My:\m~1Z϶Hu]Ƴ3W1Yʥsr6q[o}8l;Te%={XbD7x0] k5cXc|\~ ! 0u+^qYK1ӦpBDdcXy1QB4D.GZmcXgW;ZcX(W+IE,ҷk㰴M6u 1Q޵&S|r=٭ytpx/n2PU=nmbE!:ldo.V5QqK&V|!9)X屍$>cѯ"c6a,b:)h#BOJG )a GBHlb??^?r0@X6Σİfl^pO/,)i|L5D!$aobX"obep0k= 671bCm9ΘuoCҷ%cg|S9rmb76m[cm 'pU; 3ל~N ac "nnmD=E֨p}WƘh88ϦcrDo[}G⹉a@5ԥ:h%@vmdęe57%i怾m4f oBEh[ᤍߦlF16*0B\[/UVĆNnUd)6W TFve4[GFΤXT3R[F6"p;i Ǫ=}&" kZR(Z5dWC~DFں0TqϰfۖU }c9':oo(X#[3gV[^I2O_1 ټn[~w>Zok3xz!@Ph 1q=oMĵm.1D/73I59\oҊm; i&Xst}-掞#fz8/"b!JlX۰s RMP9^>TPÖa&4Ǵi9ϣ7S49ZpySb/so \^vh}YcȲTPSՌBMkCl ..c"Ş\ _h&].rςY;\??܊{DQY4u~E\fծG\[Xn}si}}u:p tf3Q"+^e=Z uo.M,xtەL!(sdGy/ӝeަRk3[w3iؒ1!t}H%M;Vl dLV;͖iciAI )f RJĶ[!_#zy0U   @mz 2r 0H5uώsO bќӶ gI!i NfpH5IaiKkTX5ְ4n[ȶ ڞz Ga Icn47%ξkF_c1Sue֐ BIG^s+jo8 sےUwUg'QǽVPܺ&9B!,7:5­o[W7Zb\@jp!Vx,3 A3@]*# `AA n 7#L,=0G) A.,s"Bd԰C~׽ގ:p]PXγu Pt|K`fu?7g0/:HJ\V$싔`y}dP v 3 E$""C2(}F;Vn#5ĢJ&c"lJ. pB;RQ2#X!% fhB0.I uր1"Ukl1 -Rgܨ(jeu3<#ԊVrE\#̐t WuMcR# 5ĻPxjۅ: { z.S -ZЎCfR#8Bqv;#͠%ޘ!l]tI ׵&a$U&Ý ahh ,lAjYj%nt9奭%)sPZ!fo]Xy&QG3%>߹e鳮p,`KtuOg`jIBV{u{qJ|sa0a_LFօ:.HRJ:Sz˩wlAu-r]BRkH`Ϩx΋ C;(+V:J%8zUiɬ,%$".J#0#Yx+9&mo%ıtR$f(վG/F,8st2]h/sY6oթa.Gڻdm XUJ+|uf`miWAjo^u\}NGߵRXq}ӝyma{ZTN˱/c:T v)U aMR!-2,yy=[Bg];;&%z)ZaNvt9 zlg$_ې^*Z0uֶ5%. pKF}X9U?Ə_]3 Ut_˹Ǿs ^<> sJ.mZ@t-lGcJ [\=eh꽳 0U=~ ڹ]u~52!#}9,zX_ pB4^pV^y/\$cjHI>ծX$ %&6")௯]}TY;.x4o㱏[B=i K'g_R~L0qkpEv^.~:nxs+~ Kѱ RB9l@;8j65?3~X|o3S$W9/NEbbm'z!äml 3x6-uYjK<ó9nl1d#[]?AW( ҘLQVIO=NgO&gl'} <;5fN6xv tmؼo.y3 Y)9NBsVqi[.=SnῨ}`&")(>bC{+"# N,T d[d-<˦89N)ϝ(E&.(M IG"Ds>N %Nk8.H5>R V'rܿMbamJnQF6mX\v& k Iڎ TQ r3sS%FdZ 6ofy˪IXmkzR_Fɷc,T5m: g:;1ߍ};{ ؗq;x/CsvV#SqR`jor5c^&MφƄ0@[Qpa:!uNueO2Fjq )ſ)xֶ…޶ۼQ,v~l8(;yk1zƜu 08)MHNB KP[#;4HM1u V@l=6]Xߏt{؏qjFYB>]j䐑 =Ą{F 㰜TdyZdJrߓZ ,sW@i -磽eq)]DDS49DƑ5)SȇUWx'#qD$:dšTYbf2J_8~їs9.S/b)=8dvbM V%Y4Jh0_q "c$%ZQf%ьX޶{+}vXHd @'9"Tg)D^qD%:0sO3|+;PĿ.9SPWR+YkJ&tZ]3V@̃:x x FfyPg]>ӎ~ Y8d}#YJ~$uEd?џϻ*%Br#vPbeϵr]3 Oyhtr#dۀ/L^+a9u)gP e-c(vUѳWB[av)^xj _}j8:#Pg*tq`G鲝SKU,tyHU}>Jkj~hQc_[0,&w=Ҽ}Oynw~6?40kzO?[Ya`syhxeV8*0m]t-|VY23n4rN3R9^۳)J?[揔vŗ)G*~PQv+irhg ~Jc*:/y|KiLc )xll2/[8nM,+`DᲕ*g1Rl<_c[-$i|1~X LL 1@1!R_6J ~{]#1\,yNh\)X/)> o@GB%Gp~ok׃5Nj$,j;.d# TNaA 0hDp=q_[m}{ΩeVl 0,3P{ڴyťӼ6mL;.{GiMlI=t,mV,xVLA ò-7/N=05W`rLОj̉x<P~\=]3Zo{7G>?K#vw:.RoNCy~M 7x^cvokþ1yh3RV%Z gwBvyHlB9{BL1ş\&v'uCp@y.Dof#dQv–ko?DϮXnTxN$.mmX+U*|Evm5W:ZnZc%`_˔"dOݸa;1b7Kư Oy_u򙇸ֹ98!;#BmF3SXe_/ 2$2rh^u[niLok;+9L1Tζ5:sLd*S~c3 LƁ ,Q jcU=Y{-6ź尦8Zy9s?h3Pgid_J7PMBojP@$uJuGDvQfR`(DFR:_Mt0,8 .=j=(k')/J!Cr:T+SNIU J3ʭzg$XqLw:߈pG-S8KLYv۠yɠ+"Xs{>龰{9DQ}Ysj|@ϔ\jEt^/T`sH/l% \2҈댬Zڊ,ǤduВ%#hbX+3VW~& 5 Ȥ{#iΖYa5%d5lMtȄ~*KjE3Isn@Bɔ&ͧ6Ե|r~-L`urco`W9g{f׻~L[ SK66h(w>ckSmo`i1zlvv_%Ow-}^MV~۰3_ ]Rkouf{߰9ۊs]'_=W2w̢[rH1fJb;4Jb>nk+. -=F $TdnrmuoO>n \,xaH-/yJBCڿhn(>Pc -X6øhysĝ;m"8̗ ~o9ؚٗ| #ٗG~؃9 H;Ѳ=!vgҡfrV q>őfLK;ɘ v.H,&AжVC1ic|۠@sA 4⯉ra3BqLi}IͪiҤNZfE2 lkv,pզo='i4(%ߝOsY 2mwAnlm~zΟޭjp[,jX+UD>}K_/-DIQ`-Nk6p/<_$ݺ${KK 1OsFӴVCR3C6mBo# /272Ͷ\-U}})mj50=Q9! k D;#3FǮ~g94/:!ƴ֖ƨ[ 9Ӝ55RٷAV8Ux 7_ Bg XlmCֶ{m5c7Eo`) x7OR4E7mDra؀Ɛл$3hog췵e!-w3y$NH X#Tb#mԡH;oCշ)/&j{3@2fxib΅3,_}n9 3w ËөFX`[jh^óQ OPa$"TLPf1Vs%Ao\o"s<;Y*}ZAlU#4ӱ_/k mk^lV"6EXooK2k8?̍y ={gXK0=4t[n/-xy\\J Kwt^4 MsqZ3&wc:twӑɝ)eF!&w{wDտlT:P>wkp8\Q(:/9@Vpg` M&֛S<PR0R 5\ފ&)`g%pl%]w4`^ߗ.! NHaa V|n/`FMȤS/H* )>ϛnO~B7wJ5DH^x}eou%-3 kk qRH4@k(rNZrEiBo+T#Pm,wNti]xIQoui֠ZHZ=[WIJ,tKF <݊G#Y%S}؛.su'ɵ!]RvJ%\VZ@ǒXs~CEN=Xu %]\5jMW+N &% UjwA>JDkZ٥K;թ̮~_okje>Ji=29&SZ,lN,G %;|j%k@]m@xENc%0pJE)Q6SJp GĽta ,?"/{h+DC/{G 5S/i58UGI|ߕBd 0LBI=#ڕtbVt. Iҕ4%?KLh/qⴻ&:Hɞm kW25P B{&=- #ǒ1ymwDlM8ݰ1lP9 !*tf\2bɏiBM>H Vmx#s{_ZR֠6r,sbMBΏ6R6W#.no.I-<@pbh}}8i')Y;Gr~F.T2;|; 0\# vktddWӱ\HN[*Az[^isnjPnގaep/o]0^q^D_-^5~ݺ GsqT|tvyS8;q=ӲUcss<ttnB:\޷%/ ʝs {H׼wRR-]wchݵqh@it4U{e9s;dA;%/Sl'rC^GkϴJjYxxF^RmK{(|;^ca}@rɅ<6Mvn\L*.oh1T<h m"ҾA6GyS Nծ0*|,ɭՖTSh0-ܸ4["s mN.Nc{v&xv,[Ћ(8wƳ \Fp7.m%Q4E%rnz%orkxàE0jdtu؈eGh zEs޶  ghQ>e8/xO /Ijv8FeL?D;Tr\GlL!>F-B{z[#BM>6☚۔VG974ΧoǤ7}Xrs`KbZn\1c'X !uk@jBkImB.ߍF,} S6AX,BOژp+oɐĪ-97d&ÔDO똑i%227oXWwjܴu:uyT271M.Gp)}Lg]jB\| ~=G}N>E{<$9 ǚ^#I.GS气r^<ğlG{τVy8ton^y,Nb4.JxcٙښDmuyKTFp(Ka~(:>F[;9qLCcMa_=;gaSxA_GtϾWqF6b.pױwk4Wș%gmC\;&͔v<g/%tyF.۲w y(craW _r OZ[[3m^OAL&.n"sy ʟa@c|hM{<Ӭbu GJ(V)CaGC4ԱEWsFP RR0-1MkO˒* 'ax41(|,Wdk!ֳ 4viX)Khda ] q~J/iF%6!u gSZ+F4wm+ ٽp!1kJ4ET ´$4a:747Ie3>Y΀4$ o4R"]>$J%3lZK?aG>~dޘv~cM8"JJa-~ mdi-{,RPK4-ck _6tjUXg+jJ&s- {[ΘFF #++. }@K MM3q=2]g"wUJ{ʤ`ugtZ# 59TQF]Hch /o3#~9#.@ ϛZv6k'smIK~>52P0tN") X&32NOl }Dh ͢`du_1%2:H&t󷵲_{$Y({ngJ}BVF 2HΌh׽G#e jFz,%`xN-牺LVovR3Ӻ@k B&mbK&47!ХK7}{Q]#ȚJ~V vk%Mpf-1{M a+ gFiER%跐6]@s HK2) Vn~N` %(n{X fzX&83M$KRsP ɏo}@Ӫ&YWҼ9t "0(%{&cYJ8q|^ctAeylc^ڟu q W>[߼.y&/闺 Ǵ)z-%4$8`>-~ C<6MIZ:GÌ~sZU : g k*iRzd ;Ѯҝlb)1\%粬m_4.vH2s4RyhO\oȻ9s)$G Iy=/KvI:J{'Uqܶt a:^v\$cN^ftٷ_͘;ECa~_ [P\^ǥHkbr[~n:\46 rp6xI~l ^aG[ )igǔ1 k~}>u=4Hڵ8CUmȖ !Wa{oǹ%w+gah@&z\)vg 71/ #oⰘ1V՝53$p][O],!pU7DX*2n /k7NDmE%=g`Ћ?2[ToT 1x:dL&.5/h1ooVhk3ѵɋsow¥a.Gszm#xvhK@|QRBH@~d05.(PKaEߖ8!GתűiN / ޮ{S"=SUp&w Za]􈱚Z3m蓪gl[M[4bx 0y.&~dxBXe#=^)W6]"zCkk]:)B Mf4-F&C݊U hSot1*㏄\z"ѵ)l')PiaZ1z0[4b `ISyPCP@0Kebj۷ (g,(V5bT6s(&>8/ fmڷk(g:VM&y${[j#8kPG+VLLiDXKc.11i)Jj6ٚ}KB L= `!M_ofg\p[^Z  &Mx\JUy:s^ Kɖ@ W"ܫp-s?Մ6mBwݴ3l ۠}aINy\P2xqh~ݾgzf8BMb t$ab~!vߠĕKYD|!XQ !x ` ΋Lr%Njob>m.d6C_/.jr3VߊVsBa)#7c8\5GFbݬ ? /7}G1cfY g##npmH[F"Q[j` 97*SYLYZ˭es&56,^a$~g9d[*t?qq¶IL_&l-Vo#Flη)Zs͙MW(Xow`̴̽|?.{A9~7ݨm#۸υ=F{>vT0mtmrahsךspX_B:{5~9?`[/TP?]LcW66iiO^O֋۰~=ŎsFN?76u0Ǿ ,NðL{'_fZ lR@p 8 XX+j:zɂR sL%6[qoZ)ݒWRn_J5.6`P++04R *JQ};FFS#BhW _%_du0R K3?|Em f闵2.KyAKf_@BpG 1niiKJHwB,|V)" %4]@pR,(ԙ:XJ \+. ~5'Y3#wA/ d`dҊ }{ux LhuUj]{f&EKhI2k6v~foF3Bji,<} L{~n"V< [O.$4@]}Bkn-lRI o|.mZ+JΪu)9+H6 +rhM1]a2_5{&Hws?'k5?Sk XkskJf3,K: p {uvv𒣧@&$]l%fua܊_ykűtѰ'ڛkmCoTm#ta6zhV5p}aZM&?e&%w˒\nw+`|Ƕ h*GɖRHǶd.-vktVPS.>'۾Fq s| (s/Y_ w_wc=.{_uZx:sne^Ko*v%ouX~A[ޯӽk{MB[m k]ã >|*i3^goxБ4'ۯc쩸s;wA1ۤad['%Q2}tŻzfv\,}-glG5pkٚߵ^EsشeIi)s|./"*YLb}.kٗ-u?{ \;BhGl:u ]p('s w_k{~^rrN"/{"\EL$6ok[NycF;I7p&/|;1ܥ8qykӐph$ֺ#]Ff)JQ4w3L]k's4b=:Ȯ$H{-xhwmJڐ g5S{ԩ31c'k#&x(B8</r" 7-d` P^Z}쑵Nu F  Vw4`ulڣp5%2Cama;ǽc ӌcb1co{#D/4e%Jj=5RԎ9sC~k9Ni@ՋKǞes xZG1Б$BmܨZG,m1LLZ=aPj<98b>=Iܫů=s}Tpj?5"no ?>(an0M׎KSM̑SɫC y]?mMF/TLSz[֝L|j ɽIi`>[۶0.\0s-kf !5Wo.[H@onA/4v/Hk }k[@_r ^G }ډ&p^,FӽjKǝ{ @):\ڬpWzeT'1|f9Fls>fF7] 3+!Xh7-p>텠Gq1 OK"ΣI#`&=+wT>l1nنn $%PdkǠѵ5̪tsK/ֵ֔6Y'lx`ngSuhu 3 1@ND4K@5s(AE U| D51Ml– L\d#{*%2 nf >t])P/ @z9pD(m}%҈l8JC6` ?OΤ U %a4 $%k񕞜KI:]M-`j&<@M{\sh;@pz z-K>ϾzVў^@Ca%DNtH @pOXyv::y;o0CQWZKog%;My<O7\*#:ImaIOKwB =Jc,-'4tOou ʏk:2ʩ02?HIyw]ILEo|ҪX$N)SObZC1_ *Z_tꝷ-YU0/i$MP[Y(<=YP&D/I"a~9P҅60ĴdJ@;пsLA(y5)pא&׋)UoSA1LP^PJ)F䯥p¹@L`@y!4= ֓ǗRݪ'y/PD ܂FߥSJ&haJnAA+ A[@ b̒WL]5ݹ`*%1KxT3z͘(˹@>0A’)=Ԯh/J 9p0= $E)/)0yIl%.4*%zR/SHfL"Rͣp/JTـOvA[*ߎaeΰk7k8y!t[kzTZr8}5,G@Zp j VX {;iD / X&SB8*)&?d= 0<|{ d^aǹ\J_,gi;{u5,:r7%LEM6}SRdӨg%s0ȱozSvziêݕP,KʶHQonL4N5 mUp~1WR^Gvn[)V#O]keUo?{?"Śx[Ϗr (Ko0y0'c\/k],A\ޠIg[Kŭ嗍l;![~ٙv5l#US%`>SyyEz iǹ˜lkK#>c-hG؊:F.A.ޮs,U+i,MHvc%`ч| :,:b!`?sX]}$ f'~mPl#uyq Vқڶ1{DH5NfW^ٹG2b:m}l];)(֙f[׎q4*ƓX )K,+E}`c[/z ]M%߾iLaҶsRG֌#QDc& %T;ad[S_T M$X&؟( Sm`.&Qaw3>7q0[&J1ѦI$ڄՐ4MN೤y1.\sXt/qu-Y{e7 Lv5^_(\^8f m݉b/qRpLxY(mK)(}NbL) (4'bk(IY$7$,Ljܣi.F>֍YC(c 6Q9(<B >`HY -L-kVg ?9Qmc (\IRL/(f6?p^-sF=1VN|FX3 h1k.xZLLLcM[@ٟpc^[.">1/b6?,@6 Ut?0sl nD$F\[ n@S ȓ%'0j~nit?`.9/iD ϭ`2ǾSNf9z0qKxynf1SDGcBhi44OԿP`2_31R_M/vڜ?!э -<Ā4WSqmNdd\OYs?NҞ[*#qp"2]B,a;L-P o5$VC&4_~A:MUn8Efu˫A\r,P gWBX} Bnb;m'yiRv͌=O{ &%nkvN(tfo栾Nܗ:{.^I*tN[N u,Rwy(z4y0}[+tW;'>Ky;o 3sx)z{SxI]n?6l%B,-w>B%ު6|l_Gu7mPDŽ ~ykKٯ/.iB:3/rNc63}9'$F_^~@48,qdkȕ"\(M;վ܎<;ۑ\V  59^ /ם@wU8O[_?F^g]1:'POU*Y:+0asu 5kjkmwuK+mގ0ZoU:CZ`۟.B&j,>e>Ӑkwdw75 ]\%5.ubCEi7m=BgJ[ WN7$(GZRMCh%;:XpR ubR%5l-ţd¤Oa#RP{qNzcl "l[- *ۆ{b0ia./`[ݯ',j(_ǶGO:+xDԤrvu饮{(ZrEMM)@e 58JGzIZ3Mu 9xP!vOqBn5v,'6Ƒv9P)h qvG\"lz[NBCG9D!7> ՇT A}G҃ ,582؄HE99筙p~P6JAwu$I+8^U$z758 r'YbF2b;tR2 L3ץM\PBff!I` RwWS8uY㈝ \]X'Q bbS~U]\IPX;HbamXDz g`i>PlꐎLk)/HzivX<\mې$-żChzlHVF|^\skn:ϝt ͋iv{&󔻌ts w:эR~&MιJGvRЅwLaot\/ЯpHe #Ѭm%]ϝKVh}[O2*33<p˦2#p!~ [9 I29iKPMGx۾[1,{8{{+mNóa-i~Oaޒ\-|qtZ>=0_K˂N\; S}3M{pKL{ I_йYn^@ui,NFw8>HҔ}JIчjsy(R=/;뼶Ys{v56UO*II6jS`El;Ν:Iz?{"˶W<%U \yv%߭J[Ohv%Gk2{q*.KYW~*>l &-$m;r\J=eeM!67 4y?Z.$i!IE?$dzvG(@k8#9\\نv:MrI" Ny_B͡]HdLG尅wG~ nvUy=IQN:RAZQ84\w.m9\"$i VsLP#Ƈ1HfZT)õ…$b[^[.$iu9%t $i[{ܣf-.k>I ž?䛕$3-}D?I8qH7}ئLsT֐91!IڃK_x z[zx| MG=6;IErCm'|-MJm۠#=6ɵ۷)WB=Ó4+1DElFC<(hE<%oMTmG"Ys%;cb aIQю5! 3q/ybY75c '[j{+,h@>YЭn1 a)ۀVs<~?7\71( F b9~b2Ef[{\4 =I{&1jӒ߇1(&_h#ۤdu4C]6hti_vAX#_¡FucA#W(<IQѨ 2utnq1L2FDM| IILj.3Sr?UF:挫 $4gd 25&odATtv>/K̄ pC@R=6~!*3`4PH-G3n|nd2=p \^663(_az%Հ9 ?=sQi@̡&[W"21A2<Mhp,E„-F8ڛAF𹘮S˹^&|HFk n~nĹcCi>ޮڑ&R!_q$6/4K>Цumz[*|n\zD zGmo9R? &=9Gk!Ac",9 Kl>rB' n9}/֎P9&kx9k48N|0B }o3Xܵ|xi;U4p<Ǿ_xRHx.w`1dz04&Z4qAΡ}̻ųVSK_ӜM)ʑkRFgdzX}D +w< ɲw/e]ʚM~v.(|AyO7+GMlK96EAEKzLd[]Ǘɻ,h ӇoȘyrݞO-6ĩ "дl[k )ϖR3E^u~U׵PR^`R}DO5!mWnuT4ݻM&}]swς4hr ?PtTtx4(2}ka [:*:D?= *1Z>-.|][P bGu1Z4hriYyv;!h@T]EDE%C%ŶZuTDV *dHPtx^[W2dp.TtWP0F"%o+'# 6v*:lT4X:tt e>Q|@E,)MNDWF#{;"-?Ѐi;rKKE]^`v Q*mEт&V{A_eKv]b} @;0o]AE㟴/^U fu A}-|ا'EBA[wXU  (lfHX@o@AW1XpM*')Ơz{ ^ƒTHJVqk]5'^!hۼk[LK`POέ,睃h_ls46'e|'z( +I*:j#8z`8o\sV`y?v잗 ;/ƴkxsאq8o=; p43;v ;"qm JzCh ƞ/zxRv s|K&аϔ9tS59䈨V#_UlKioHnx"D;0 ]ut R%#%;‚+8`X/‥^x^ON[zB8>L-%LgDT0Jy$%&H Sy{F5Z}[}AA11dIyPMd+%_Ý}Kk o #(hlIӵJ/b˖|%uw"aH|,1h:*wAz(ɭemo yI޷Q)׺#'=4,(XBMI>8@EMKʞn'5izX7?O#858T7Hᕖ2GMPM>Ja6onkIڒc&#Tr=ֲn}~[Y:qq c$h(=cW[׈mۆ%[m ef{´r~|? {m[ǥ~70 O{x?ƂFmKg- v-MkV흛zӚytN쮺&O+G&Lfq2IQvoo6Dr.uO/Eq @Q/:isnIk*k~/vc)[`omxsT4;kDG(}{6U# :{GlEڞk4y xrSXW(*V6>!jR*jz0}>rي;a>q:  !BU&pCG8ic \QI7q ^7Zû3>PsCTmgשbbq&l+%݈؃>xRQeYA}sKl2S @V*Z>KN[ċF}E },~B'Wk/0>AvK!'66יB|c)]'Gt5GU)C dGB>o'(װi Deh7Mg"kjRI T88SB04M@-}^rڈ(RO63Ukb-\dAZa+F!פ-Msڀ榡JMS4=jLsd`CӘLHtةQDE%Iv"y> {&?oxy݂'lsr_JgT#d* xjp'MRvIb? 5@2bMiӀ5^H7ZX5v~\F46?Q&س]q\;՘gcovFO.1[:g"A5UpkK‘,,QL?m\fF z*B2R؂o\/ɣ^BdkR7.zLsn!4< ١"Cћ ԛs){ LmFEJk5\M񍠍-GmltiCs#Uak3ңA \8 <5 8rHh-eL/m2ݗ&%RoI"cbm-gڌѩ)S9[*EQ I[dd-7mD^ܴӺW؁R8XZMol S1f>gF|<[#cG>YVQ &Qeoy$+䨵o.f̓_ΐ$ [W;c}rcD≕#I4R$慗,1Gh'Qe^7zMw.%>$6GohBJf#*/E!SrĴغ}D2$k4C[7gbVT=LN |ϡe,4kYwyO3ݏ(1-›v0gִ: Tkk[Z}R# GQ=W#F~uV,#kxKdI}߉=4|gU-{ot1zY ma?"EcL!RͤvQ[#0sAї-Rl5>{FF?!.u!6rKӠ=Xf]i'[Y5u]!! /_xŠv́NPʊʑ>%#)V|<8/ƒMQ}Nd'to \m!;\G3H4iga6C ?Y9)͢g7Q /=5l3'[#%{FK',٥NVL*?!cZ0QH32A%JƷիQlJvg=#Q`BL4h rJtUثp.! Y%îi=#IK6I9F$3+mfM.dK_^%)0#9[&73H(]MmB%~9 t%p?z+ٙz5>JBEvxʩd؃t-Buї7/=";n*HhJyD]!(r3Y9npZ v4h:Kx.s7 ǷYsp|aݠ^,\Lv.qa^΍qk#)\yK_jw}X% Ivyr|EgJJܟ!;z9v>o+QGZ{Wkun\72duk{Vry϶ٲѯC3}RYFo\rL$i)+{|{$i荲e yo{^Pox¸_ 2*/Iҋ=S)GPIqtZ_=_]7-ͻWwp_\;_R+$b!I0|sYK]X8Fv٪k^DdS 4G_wGxOe wyQl/˹Cuf}9NԼ~Maenv^ 7x0I:WLۜ-Xv~o`cߎN$irg[h7 ܰ_{6nyG)Ig l`P4H #EILڄi0 IKPh ֳ. !;F޺(x8D?yxrT<º솱!4YVo;Zx=,2>חpGe؏&3 p‘$'ƗFA'nH$0gɈ)IƛH%Ɣت9*K X? f幏l*DKZ5c.iI.&Tk.DK/ږckh6 [j:!FU=jJk7b%уD2=Qфsk;AX51!-S~$χ8bbJdȊ#t^B:6M7,j1فi{SM҉녻(֦]<7\ʋo]:"kM`m{ M@iXαפin/~MG \FjyȀ1pIDTF1v[w_+b@|h_D1R^8pK G3=}ELHD7E=CADP*ngdK 2E<3Þi ZAQ#F9XNֈ#Hv4_+ni%;/dAz|NUtx$I5`SKJ I&m;ĭiB Ib ܯH2$e9aQt4L\.\>OV v4?@RNvt\i$Iֿ@4^uȯ۲YR̜^gmnp|_ko.FƒY|a!It?5ܘ\~#IW? oeLɫW/=n>QgzrU[ $s6Yϑ~\UuK]r7w;]0PTmD{\tJ^0-el5e@XBE ^ IwHB;HCc^=Y.+ҺaWZSe,Y@c@P]7[ܤ] m4P,?i wC ig3%ۭk`x F RS46t;]Cm+M}Gt+9yD nAvn]+Z:HzYePϞ)q:1PV6!am2k͟&[`!_w! [a AMB9 #1q0 f#<WGB/\Pt7 ]M0^EtױQ);E ѹA鷺%5#1,-\X>?X^[Ϣ iA)8D0u!Xtɞ % uDcI`sT".LÑdX\v_<6b M=#g u h L9˕p1SJ$MRAw\)k; =DXĦt M'H HnsDJ&9dN'?$OA2M#>?1SiuOȎ/Gկ ϋ8oGOsRJj.F[QMpdANa$ ޚ)K]H/ iH׭K?Fᄄ7BMk[ϐ\2Kp.M I:ET,?/~ґVaOB$gXm}9IeoT:XӎR羌 < j##r82j6Sq b|"qh $w*E`7]36db BJޖkzy i 'd]~]"`t ݊J-{F'P8]vyO",#g! 4f i:?c]}I Iys_U J/`uuy:]=ض}>#SPViaIJf*9e体e]_җ*g84ݼt{}.K >u)qޖmֹwydϕcy,o*8GE7K?Jg?% ]ý{s\_+BBxCZ֖^›d}yX9zK I;:Mrxvܞ/'htBT㞭[\o[zq:*|󬎲)w_ *@9-7B<;Mn©\7]l;8ӶPwlW_?T4(/KJ! :*?cމs֧w*>kQPkB5o袼Y#9vMR^ܚVװ2]3eDFKR.AQ#GzSA%Vlc]@6b>{,y_+yD`{׽7&WOUv9SKx9oŧmK?,cGӮsɩg%0#;Izx? [$(rrԻ.w Y'65qr/n}.Sfg9ͱ~-Ǹ}):.6.\Qqv؏kc. @jRSa 1F44=*8Θ6jG6=ع}zL( #IzROUR_(w9s/$Mq ; -gqHx}fHep]'.Xq]qyC\+nטDboty2ԉ6א"iP^e@_4 @Mb-8Z3u6JH2aeSRnKYCMC1.Ck*L0Ӑ,TMqE,Z yup^mE} r!*wAܨp$}Ӛ+N,F5$A\ˍ[t;gb'I4xȼW }&Yʵ-}L?Iw8-rC~5?պp+> fuio iu,f'>U]A&}wq"KHKӕW}6*Vs(ւbr}X/\vLm"v#Lu4q¸"Wg}?È*mdvEjFL5[`;m8RMc.N/{X{}Nv$]HUlweylU ꯸ݾ4ǒ PѮmxcmw$8;O ;g]J0XS/BT[SM3*y̽oU[m/T_n#$ÖSJ^x{ݭrT[ɻ^щ F} J!ճC)#3o0OunCp7qJu6 Ahp Ya,[(?m T38vwhtC NΤk٤mi^--NX>Kʥ_ [DZٷ+ {vJ3Bm?Cw#,s$ѽzkoQ?oɮZ}-~'r3I l(yY5*UVJ|mga]RbZl|zMQiKːNd r>J3sD k=&-ŁROF&%zH0ȷpQӐpA|)91 7Ei+Yfۆt74Lt"Z$y.9 DDK[Wps"^J z#Uƈh=B4ʗB?#[F#XQedDGɲq>p3tJaD$QEӜJVHRDNj{"Z{YD "#W`$)Fui) V~#ALw[KFrdk3I pWvH|ȱ F=t V.QEdlJ'X;>9}+YF8y|53Ys-I%M8_|)IJunY\XXѥzs;P+k'){x@Q%VKCRxޗз'&3? UԹS/I`b E"17+X_taZELCLh,T'MRv}=Q&'JƜ +%' <.f^2[^8d3OmҘcw%7#k OZ-יtڑLvZ DaxF^vx0FDAlR2fxR Oz+6j,$d'ƕ_)sZm<]u=J#QIٽu'!]J=MH0 ߖRӷ^"ιΤKa*`pFo@Dg YΔo݊sr\Wƨa_'>:L<ZhOi^zcͼ^A+)4FÞ"Q'c+V~#pvpaeyr 6پ,[c9ܬRfN׾sI6ގ,9-rXɍ H?y1#ekۦRw=gh9H Y6 )7od#|弶^lOf_ϐ=prqvjҲތ5ݴ魴{IK^cFv/)>_{v[]€r>ʷb䫶X ZofvPZ-w&]-zIm:~+HMjz 9fw-4Wqyn}K'sn*lVo*X랎gbwG ?27yf>TAN[םϲޱLxܽ.W*?/Xe{b(|_UME#JShP\),zGTjG^J[v^}C̥+h'k[qq6Bw&}; ?#<\Q!Ո~BN7ٝZQ±ە&6+Og&+bTGM6By(.mϻz\K C=@(f;]M5~eمI6mV_N(mcmkd{A-l ;jRrݧcj`>K )de&p5XnWckYA3%UA!5龝3]uW s%Nu-  ,1L27!w2|n c 5(h-.z&a (6JЉP#w8GH RK.(`w7)-b† &b%`bYlQC_H8VpK,+S!7鞙qz4C (ux{[1CshM\8nk٪,XTKv_#כ0b&j0_qG x3bE8dW2s!FT8ns/@x,\oڴxX*$$x17hx(E &wohLR7u*VLq5gksv wK 0?qXrcyrq3dkm731˹-%-DZ˾>\ROWuI\x,vcEe;R]=0Di賂閫D\胈75 -pܽ[ҾxM$!)փkݎUS,}B@u`9'm]{ɃM-[C-f,2z`bk WչCm"sͯd?-U&scz=/mѻ;%șev5_[T߹sFr*q&Ys;Q uqlk ^&2mMMfEo_k\lkjܝ ^G:~-dn%(\HMfnq HKၠ\l·;k灐=H//|XK*qNo}hw?eo7N #m&=q{Fr]˙BT]Q]hhE׵Uc!'CzkoOq1Nb !*OHGeH=ݮeϺge]HV1&֜mu4fV2CW6ͭ+dn`ju'ҀDRLp:rQPm[{$42ߞAJӢorۮR#-ĹV~*)^)"cIMx g@O"AJ@sˀXlWgmΣV1x !I;H&>C~Lƨ#K7F RoՑO퉎zI3Iх+%{$WҦ[^G9z]Lu^{;l)Xl{^zO;1_r*}нz(MBDZMu]m,%K_4z\,6 ^>"m e˹ǗCfH ;38|zyf5'uG۪Ju> m$VBhMT~,{]JW>~{J[:8Y7Lub7&qvѤm\"]JmRn;؁'f\ Dpa%: Y~F)J]uSĈn9Bnv*Qra?#arCJFK!3FN[31eaąhݓx`W 9UH*NBBМI%澔 d'eR'y䭢3Dەfg#[MWD3DCg)HB'I w/%Qy[犤Ҙ+[n(nHD$B'ppQN2K;hy.h!O.#_t R e9n!C7Gl@MsZVG9a dYF)7ɾD${~Ys`?SrqLk씾 ĄT+yL)qVlZoߒyNmk5A LR"F/[* !оB&2KHiCˉwX.tjۏ`fi|/ew8] 3 ];R-b(w`GJꝷ$hCODR:ϥ.@11Z KVAneN}}Km&kQMF^3iXWۖԿ[cdwXϦ3EQڍ`ݬ]K;/vt _rd;~Doocr{a/jOwmph rneيźeM:rJ՜Ǟ=]׽#%W&M{eеŋXSx٤N~eGV.%btm8+J[^E ];z m{mW6vڝc}YGk3Sn >rk]6>!g] {ņ m%|[e >mnOrn=fO |mH7o5fg{dd :]{?KX`uJ׶m#;.DZ#[ڃK{sٯA?յs=ցQW,}ÕvKWo"7+;-N*&.'Y͌NW j^;<{)$#-M:yV~_?ob Ñ8Փ3m=NYv:BObq-X[ٲyKy[g;M iu^Gv~^k[$ ?l^F}TD|>{Sp''^vK&m]z;Wv* 1K/Xln"ٮ=%CQ)գM1ֵcͰc4;&Mۀ'_)tY۶m,J"ZHG;/ؑİZ#;*fBX $)RitB-g[9Fu+0u1Nc%s7. f)N"ԏq7wHS;[$}T:|zmu^c&^"jnbccӜ3R7<AX?sH-೹i/ւHcӡ(`@G.N")s4V^׈+}M[c(nւ|3Z|l޲p @zfs<.%,N"ǎfxNϸހs y%D =`jL"<.)uDu8Bj_^cfHEPb)ܵHb&4mDl-(ڴZ/ύw )€ x)yK4 [p/i1߀8Ǧ(翙ީ/hLw҃i/b\RKp/!L""AF9^"mcOGMR&Q3ٟgNǑpMM[|\/?ډM+=V>5w*"/=w>׏bX=Q/$ypdתƙVŞE=+|,k'!yӕTP[#<\R7g2Wvn"[ *Ĭc*ެӷpgsM_r/bqwp|ߎ& _S׽?Rs÷]{)ҿg-W1ۑӵFv.SNb~`ϺtH3[v[Z_=ĉlMUhߎO'а=]HA|8zm8MlwR|-kiV>޴_rmwNÒ킝K?I Zҿr}Gѵk/-UۀrJv&Ѝ&HZؤv*j v{=:]9eMw2L&-e޴~kSpLq];iZv}I8byJ4A=ݭZ6}Q4nܖ wI<04A@~;@ ?RNͱu&!Աuip7AG P{WaM Kι1}"LuP`c0D.u`cAWUdWD.He;c6%młRB T@ Tp@ Ӓ:N6N'ltrȮОQ[@ M8SхXg <G2TJ6]S`hg=P{KQrxX][=6K6iStCʤbsP915K_Cݻ^YQv i"[tbM{ pW~{&!]p =Eta)l # X0|RSH*=I ZkHΥtBݿWJz%0s跴wICr) KI ovL K6(hi}+:>7]U7Vu,3TJ_f;. хw2ێV2%IJ`HZm;eL3Huqh}K9onusԼ$azgcgBNKƹh)АI{u`8YDgۋ.Nڷ!3#GR'r﷞ ]Y5<8A:0Sn{p&О.an[ q9ΣGj%]դ֔tΫAp7ybwճŁphy)-!\_ n =cΣ{'$jWTԟ}yQlpw@֤HH!#z'i"Z_"e:c~Y_Mkw}7+s\Sv1 >odꖣ^z~Ǿ @7Av~جqSu-$.vPċP c8EV߽PW^jN{³K 5{L"BT/}Ds$[pB?tnjCY1Y]\3Y;ă m6>Nݶ*n}imU*QtįNEgלsBw(YIZ{ R HQ CDMpoqlRpGl'm|Nd>,RcM>NB/_B*Yi]wd;.@_ wwج\~MO {?p낳sL‹-{{`K©F/<bp"} ] ժo U$*s`c"*ػ %R(vT+В @c%LWƴYh3g:6?["ːrh-$V`9Dr?{iP~ wc1Knl9Ғ=G+ZHpb@cp ܍-UX8 p`$ MŃ)Nt;,h.R8Z/{Y-U-\nXQ{BS\X4.bI!:Ul5DCajB7IL_dPC^;i'Sg@Ci 4tc$f;niX|L[ rr;ԱhnTwp ]݈|V$1Dژ5xnJۡy82[Nʄc!E@̐Gi!$8xeޝ f덉n5jȀgmjP,rL"lk b`ȳ',UR{ɛݲ ]qZo^ LBg6rI,vZw-k{@)$+=vn5n!On/bE41 v" ):\m p\7+quíE{@1H/Դ"Kq\g(aeQޘ98ƍY2qIPn b o`Lid!1 {[C"ˀyx@[*̵p3 4c!n)9XA[ L~LhL: ^14?ϕ@x1o4 h{8'|2$mcT1o`-t3Q?oI;G5AuDZi \%xaȋ6{gmO -b+iY\H}5[u}cݎ+dn?L-:+̭g݂sA&ofA'{ۣ'h" $bOFubUt`v27҅M 55);#7ʯR YTe4q:(ٻid!HAn.\ ?;Xhٕ XEݺ6TǺ},A^{+Q Qw0/FAM;_^gmݙ 6h=pqPãS^vZ%dnĴXm_3Eܑ`dn̜ܫMZhi& %Zkno*d`S/60V;q0W:Qᾠ kIu6 J)a3G2M5D2fXQYїdvŊNAN[HiF)D⺰ m:r^XfԜrR:`>%`Bޒ:}+y.Gt}EϞDk'ی9Uy.w>SHJ+?e#.;)V2B9( s=Ȅ|teG:HŮ \J,ygI.>Pv,pg')YYlyD+9huk_fܞ{Qԕ0[*`$I#Dpk\`gI#hs>:Jc6uIt^ġ)L%1g ~B1G3K9@JDaI"FYDAkr1X1> mzJ_Ӧ)MR/s_¿cF52 G=YNKytmX—G6L4To;_m|ґ޾R-%N_붕c85ky'_=4)9SK:W3ϭMr%/78z3Ϟ-|_7i:9|%dnxT~' 8Ifuej wI's%_r9je2w2w$1yQ[aKCmtry+cWd ߃MYa%m<齱qzWBov om׺rlip\ J:vXk1|ltLgw[]%/z]C|{x*"fFP?l&*G)lkp85 -6w}LVc_…?~ c>sokzvՉYO]P֝Qd@͞,:aȟU@ `@| aCb #0Z.dn_{ skYQb#pjJ# 9AtK=M/\pl[ztvIR-x rMk7v /yXӒE\d"I榦) {?`o ;L|p[-J~e[>G1Ǿ1[b#vF.&]#F l#~vM^rډU~{.]I-: &# %$agsDh1=BpCAu/f[Oߓ{ʃI2[3JL54;j.D5A,7$.s\Q)TQo*֡Ah;bUD dQdQ,-ߊӤBK֖ p b? P󷦡64`Pj/|k"51lL/(fN0"i]L"{b^C1_Pg-ďA[ )ٵאo@8m= 0#8d,dóQ-JnnQƪFXfLV*DCaLK 8y-q'"m)I4]4EL1BPˈZAΎc< * ))3E%;G0haYŤ l{/e)\4 >Ze4Aƺb%f-ڈ;#.D`4]doJ鈐#׍4t!`Yt0GM wAiY|P.F_r1 )ޞ^OLwKp [|."9ѐI/ oύX͐I-cK62y항Bb}h@[G̛k~̵nl4$K*@YLu6t^7V%2oJXNFX:@Ő [* ErfKߊq'c": $^ŀ[*q@xϵO|7C~[ɽ!$.G^-Wo7IڂN=M*U {}!}\c=+5Mޖ; Ϳ~N1Y&mnYŝހg+Ɔx6mT9_Gͨr̈~/ DtJJoMbgATN$l 41;1CһW4+[{ђ[ Cq MQzF w׸!4W?g"7[)Gpwme2\F\q}^`׾1=WWغ8bwH~.} 6Au{;lJ>䃭_U-_#3 dnBv܉Fbweq\Bn*,X}n>"&CNe7Kܫ:MꞏA?bO93ţOU|axiᮼ.0s {/G l[n&GLD@4Sm`~'ǵī]TGyn3 @˽%!3xP%(6v)]wO>TStǏ{b3t$q+;Kc1N.t>3 Gb*xkղg!;0ױuZ.=-J+;~w5pyŝUf|?=b6*>^W QyOΥB{,…[Hj7^Ү! g9@?tI* ^ 0fF%吔tV!RЌLzb,X MN @ƞ$>3_:7[)_ ; c@V:%2t1Oٿ%@dzdYi@p[ d8=FFr,%E_"lþ}DSK?TȓP2nߤs,qqVM,)-H]FZ mZs8 R)$19H /ZsB/6`UOM6l)]N~ƹ]X$L6ϙSn0G ĕ%01{`5XK޹TfXUQ*$N#(YKnR:_Qoa۹ v9%/_Ɯ+m']+g+: Ɨh`u8  ;]7HŮ@y}F_Ƿ9N`d\ 1^vERЅ~ftݘuE 8av;CzFbͧ#Fuޮ\ھ[Ӷ/ CMa)oGqᥬumo^eٿ;;OseJ 's͑-u7X#skn ա_Ks?s{+9/y_⚧OzӶlMZl7J,G-Az^K Z'l{`u&]ʾVr!2'lNXw_eKloNc183T~w.W'lGY%eaO\;kWeg`?<ͬ*p_R-pޛOR8w[pw?^LxY;W NL&(nfGʉSY>k/Y?  ՛W&ܺ]0G68Hg91 goL1ka @zIbI ˠi` Z]\Ss*[g (m WV5H/u9 xmnȩ,=JZ^ݎ#O²9$I>0kib6]8Z꨷;΢!lUX  lU<Ӱ[l]cD-pMv|m#.YA4KxUnh1ܮ1K`lԇ6c4*lK+%P&L>:^| |&PPlPreQ8V6V pF!Y(~2!<t&,E#v$*C ,7 hÊh1y,QdZB>Dvú|TqO;aELp`װ6*VC "^۟EH -Lj i~!#mքSW|F0Nz69qP?Z{9|1QO kX[uu\VE2d؉nA_-^ GF=ghA[{@E,0v*HLGS3$V91[ Ju<'Gr'\X)̰&2\1Ӱcrر  [Nmd`:"ͽpj+m +LPr,998s ?{:Kx@_ M݂uڂS/xm&SrZbȐDM,vCŐco9)y R6-ZYH':@CSy ^ RTer:A/ t=gp< 6usz H vNb-NSZ.bLӟTXhZI2 "?dS|X!vrCC.vzˋ%`[!|e4/tk|gR\l<ǧ\↋)=}kj6sCoi;qnԝ}="W0CiԉMn J^p;񍉳RF&:ؑ7E9vj'nB[? \[4awx59ۑ ^N?^v7eY;R>[+W_K,Rv_{s\:vvԝ\0(⽤gk؟3dK-zȷ)z8C)+%#&t/(ڶ},0t^'*ypTϳ[pUͰ>Ѣ:޺.w0:s{4Ňr|\urm؆ Mbz5bTIMwَr[ [ٍHC<bfp0w%#'owHĀ)}ݢBa}q.؃=A\8tNjo^!\TMk{{ux'3lu,1'ւcN$򇤋QqQ4$jcX/۝tMpDay^Rm|GvU`WJDY6hk4ݚtu`۝ߘrg-M _I`mW°QOud}@R0Rs[ynv$yϿږޤ&>"+b[k٘PlBhuL-ݶ'- n(T~j `/LD@"ݜ9C:A@@U>Ke W #[9Fe!wlyUdKu?{J}H˺ΞU qG͂cCy]}Uc>(ti3I~:ricyJ3gBoRhUºc-V,m#Ro;&6PZIS>1TW@{+KrZHzQ7e|FD}:S]u6?rb!dp2LkY ܧuX23u~=p) w^ZUd(̼K28P38nWW}O<=x"}{xsR(wY;e z!O't&Vdz^0\Y"d|= MO2ON2K)wP/@Z'9$`)&OPNjH9y?Ϝb;Ϸ937agSN󧒅 򌿔Ӯ{o^n׵c'\{ Z܇2!\Y0K. )6o`e;ҟ]Zr:4"kLvxohds4:{hj&ʁS| x ;ݫeF#X=RHѯNvo ltL^w6Xj}-fsy~3 Ҳp:7#|U%H.F_nb{Js.yy &]NzNcAl>֥B53µg![Woi=zsڶsSX;=Xn-c^s"v5uY8"쉄_/1°v5[pk :⽔5; ^=_;w\WΞ q!G\yňoG\u*M|%Q#F ƛLzCl{pΰ.4t^eS In_\~R4Kcrs[ioXM\!KcZjlI!7 M nÎ>Gsq^e4?cWO .ubgX#:ΰqr:>k S"ӵm!1~voViIJFpQU^sm/>R$:0"-X5uxu_}gMnm_`}mǘDlϗZ°6e{wcKJ1`2Ths3pgX#"3>E+.vT$yaMM,\/bd:9%B$蹶4Lg(zN^fhnk6ck{EV]n(bD*#my0i9qGU DnzIJZMcm6"Rǧbgw#(H&K_OAߠ6#imYB|ݷpB/MT@?%G:nbcHi.~M1&@IDRG{@h @oĸp6]7{rfBc6Q'.C.-;ݴ6QRĎSUMm-L/HsXo4\ .TաIb;mAt@6#Եİ.QXnTNcF_DJ5ofn 釸Q)9iݳn5@:-G_.؄9ݿζhPsrz0~nsKaG?[Z^h/vNuF;q15D-/s WHL`M|п4q|Ix ڙIiәI"'+w/ۉo#ȞPuщ'G@2#GZꞋ_s Gz4-=7';-@F$`VCj҃0祿x!`s*_r)}|jsc$sxY<||-/"~/nԎFc&;Lb1^_İkA6yuSwT}'r2v5+|/haIŷIM|tso~=ΰ&K5ٚ8",Wok&X H%N.w*7u󆺎wxئ|F>Di^NCΰ^lFcm$V`{fPlWw/ȭ%]SmSR?S+'^ Toǫ1N6W}%r O]6ׁ湏 ^out!uH5RGֽ{ߩ"vH?دRzBd[,Wok2,j7mTCYM~V>[{Mך7`Dl u.*^b.ꕾpvs5힂v;nݻ:|5]k y,($@F,]Zx7CH'F#AΰP`8Pv!b?awȐtmD,q#ޗ j xY $b:b{qy،j\)Po(y,SCLoRJ5R rTe]5Νնk^ۥћtw BzfU 1z.H%gZvbum#U`;֨? K &u]!0Z2zMa |k*zT+Yήgѡ#o{X-o]eXXe5"_o'__i;a4HP*]3^>_:8MBh86~5,q׾}ԽGe{4DJT6DJ7z;29i,#Ri]ŦR}:t# A*s*u*UF亾RW Yp4a)FVxš# SCKL i30QRav '/ 2 @n%#ѻRAGҸ2`Dvat:F'zt6.RA+ '(0 3T2#5)P8.,i2M&\ ~&3[*g°w2n°3~Yv:RJ 봎xV׹c2x<Ӱ-$ k/(cwi7 ]5|!zoO^3- kA^O8`.տCvJq=y9s:!RϪe.azds!3t_[a}p`X{,r{}0`XKޚƿNM [1gpI<kSU o/4}VNs[7i`7ڹ.9]oRR .?@lc$ kX&GfsĹ?yܞeTn:.rpm#1jk%v.™qyVhUHG7B]tD+i(xi|!@"ޮq"+ĥ=&"phH91_70Bz\J :Hϐ/?+D:խf%j)%Z-e$\13tFv\(e5kpY8a6Z*?T⢓̓@hӴZv~)6裌\v.Ǫ;?oI(xYA:: |R֓`UfbF6eK5,X#d intzk OĄD 0|f1E#SIJǎ"y-%QhF|̘Yv-!/@d6cBҳ",|l'=HRcbWs?{ %M؛ԍtmpM MC>6>74k=!h.>ۮx7_́ C~A~sOv{궚6u iCM"~rmq4?ikSZ-}.~᪈yĵ9}"&\pOD:¥+܉[d9%zaL_ak;k*Nu-2]Ί &rHS'Pj{_8^7 T(:'=V7%3K@#,!iC $IIbް_hĐLB2?7>R8YZ(Z 5WT .t>7p3O5~eb̬R8-=_r,dpEEFةX8Zꅣ)6-"nւSеb\:1ANb4,#936~'Jg=x96lP$t₺Bb!4SNso4dѦf}sa!"tRi/!na;o# Y|iH:{:{doL Pi+5ށwAt`rI44O*Q%\jYA;W9<BMoRΘ0p}eīU3ct́xiI܉*qmy z+۲3&wIy)z;Ow{W{ejhnb?C=\KB┏_Z"ֲϻZq|Go~PMc\a^[J;]6Vb Sn}Zt $߹dɫ+s3%r_[QW?5 >iLF5ʨ֞ *N¨ wuUZ[[¨Fq]_.5 ~oѣXܕQOF58z[Ə~v(1[ϓzS} 55anFTY9]}굿-<}ş:`D:\{_@ 5a]ޥLFp6MqK % k_@KZ{mkm(rx(KpjMTBlDowٺJ2^a,K`nՖ+ N?] C`I0urۆCz%$ GsN>}B?`alTөH_BTwrJ &~@ @Ӻ9j>؃T%%<2kxढ़ե Т| 5}A()ڨ\ªmg;Фv\T^oگW.=\mK"L} 0ӮAȀ@T!ل| v<A8$̑dTt!Bq$%PG6afԝh K ZA=tq!%.AI[A;Vt#r$Rҍe⼱dK52bAJ/_6X/<V΄v1PXJF:BO.>ztuz(\{X78o--R*:?BywErI!u2J@gBcSd_fu)HH?(0w) G( ksD?aR,c$/ ./`LAYiUXJm|mR_ ,.udjEJ**Zt Z%X`u޽ tɮWtcAUmB`t׀6IFhX,Db,-exMvӺ!H_A0[j6OJDXmLhIy9%i~}vP)#wgZ$HK4%)E ,b*tA6۞x~~y`Vzsi5h| LBjzc5E'xKnV[E8#A]KJRO8R8▤YlrQ7ٕY N2)Y W_q; nhE#n!uby[ %\{>ؤbQHo1?o\yO4Й\X @'2d_Pv:gϼ eO  LbJA8NFp㏿XP%|/kj6Wd9`zKi/T^K÷=33H8+Nn QMg$gzTR%a:AeWW{'rݴe K.ï֏{HW2W9{jk]Vڕ,ͮ3&󎭒DqZl\>'<&u Κ4͒׳߭ι0 h5_+ګN:~vRI` IkTOȭdV"\Rfqu>Cr\UxTgq7=$arrs]3gxz?W~AT%n#Ƀ @8&-VwUOz>ʾដeYcO6_tm75kr_2O[Lyict&^?ge8l͍7m;gVq9%bv¯:,W\o=g:Q<>p]}9$Q"zڕpۦmvBLW{8Z"LrVCmk{;_y.j;ϭnka ]%O_o? {vg7E? 7K%F}G_G)ZBB:=ސ=Bھ#$JKe"F9,"N9IӼnbvN]{Zth#Xn^xyQRzX#TDLlcը6װpnBޯrnol@XC+j;>L M"b)qj, 4kӡHj`-EGU_ɞ].g9ދgkE=G*w-9Qxi˩sS,r__[2=1:Nkҽ9xV#I$'Xq{dyZ06>R*;O"|m VovGدMӧJkz+(Hv}[U7FR };vRv` YeZ]fMN]!ܤv Y{"2at= OV9;YHvzʼ`m3=l TeեW|ipmsy+|hv>עYio1v{nDZ;>=GcssqkQl\bwM\%=Ek7G'w.%fGRw ql  D^)Zm+}r>G%o&Qc+(M@{"DŸ"bR[7qZN$A] RW8"qP鮍(=%âT$*t5 .g`Fu JYFsA`W$E;o)5 tUqƿ3БF t ϥ/Di~2MuL BbȆd槻4ݙxSvn݊m כHQmO*2"hҤp$]zV] #{{ϲ}Ss) i83/k. w{o̹vR[2!x_`HHtBpˁ2I,l.*)BN=|u.46b^J|Z%G! s;RlG {JaOb8HT* md#";S_!aٹs0틹NG uX=/I*e)sF6IDildI>+eTN3I}|ɞ6Is/DT2 녽꥾zaL7Ra9%t>AWb~n;dv҅woO3eK)su/&ucHFIv\~6vz J w ىhPJJ4eSv{}׭NpFBځڏ%Ӟ8o9=U5س0TNx92!(BH])9ޏebb+&`DžX'\JeOv>=: "|xeb냳n]"fQQl)knkk)n*9ᖭO"Qx3 ?,M{PHc%_D'G"I`ȭD;ONl 7GbPlLЕ7Ͷu0Ck5EA"4 ol/ƻƋܿhLTr|nZT 07*9v<؋؟e@I ^7۹,(F:Uu6ͱ)&":=R_ap "/-;giB-ۚJh-ƺuE/J.R;N+dzc jM G>;pby, 0Q,rƭ# kHӜ΍iC;xxxcӴy.}"&cL('.l!mj4K Hm":[㷿38|N&85ᰮs?SeHnTnZ4us#R4nZHv"6M瘋ImFFj@ڲ$eܼ,bEjc:F|ݵRTr9ƤyP x7?iq%(i9sS/W@h8 x-GC~+œq|@28<|`/֍h< 1и=P!D/GSd;ñi1ϙ/r)4 }`eG?6_2ssYX7A8'4v2&J#$xiވ/uu 3\0v`GvsOQoP"fx3aqV0F\qA ״p6.hnJƺ#gz4`-~vsAAo à _Lܿi#W>"W2`R ^X8}ZvjZ6/s-3S1y|?{j0@eYG{ɒL)~]>_zg hSSNd=Ku\I9mlbJҧbc3st ,s^JVk0U9l%͎=Z=J#4Jf -́~^gKv;MDo2ܤ4'a @KʟS7IRVO9@goi,@ԖLV'K= ڼՠtԶ^X[s߫xFӶK¼qiԯO.=J}qM, EІz5\1k׊s>LGd>ڡdZ/bU-Bhmǀ2l e GlW#yA!S&4k{j Y-L, d\AVϊvO_s^Z%xm.N6w6lmSM,B y !19.gӋ`X? HD@#+ ST),޹4f )fK_ABݢ@D1jtAxm/c=(FʀB{v,p Jd̥4F/VbS)Jftq݀~?%`g:I+_z^&QG=mKbԓU0$ŒņsABξ 0aF7 V(PJFH' ViDz *`||Hpԝ[AṂd! }n$%.&a!>A霃V0X=o $t]\ &O'(¶#VQvZGzV]HAKnKnv5;\ P ,nm^ j9.$ h?L*8f(J."g z4B~y". #I*A@ߦ@qI:PLp2¨=`E`8N}=U L4A"K¨ &Kڥ`$dMmXUD@X-E].x^J΄ƒ0jz;Rڌc8?HdBd^s)"a L.AAw EjKC'#pxm vPy m0",۹ ڶTL[W=`dC:z4~=zVZoa YW[BEo9>xm{@i8)M ߏ|; ceR% 8+b$sP6<RI"M ^/&^,xr߰PlC٨(Ե:"i(󶗞&!6 gfk9pmϱF.-{[(b)VCى& L{C1^XDҷN wł%CA ,#QbQk4}ֈp g@6y<'"#пqUd*tLTD;W>ڄm w]?_4â)}b$x4kSJfPP oDZm^Hs4@[G HndL@qӴnslmG fꀅ# h1 \/mFm Gt?n>@J7zƤ 4{pT#\ۮ-\[Xq #> 'jeiC˱[輆IEp7{ܧb˙S PX$=% iOT$fm:i!%~6ºu@pnY63_ڋ61u 84x pGgǢ lp7s\1sv\zj ZBARH<#$Kn5AbMN+!scҥr&X3јy4"R8]H|s?弆 Vm/~z1sýߺ q{mb qMb)7rEmgcb鸁#d?׏ZnriZrm=V?Rkx PӲ lcoD3X;q 4S1!t{W~.l?;Ni}g34W1 ze{⺌،緋ӦhVRr Eէv~[]pfrgrϱ + _e>3ո|n.W>`*ޮ38z, y!1ՌojľĀ氤 :7N1żg0D&.g45\y({-}ElXiY;[S*w^FSlޭ:vWj;DաG.G~5h@حC; f#yH#exIEZX>d[*mo!3Ÿ1e%;k~ƭ=Fmv4b00V#.y!&Es6j^fhd5N?kH=zO^v^u{/&Rm(tZrvog𕵏MqALaHg8;-(|wR l^9v+\+lw1?˲/CBX1qC?Ƒ`MZ &5֥? Hn1JȎ+lyx49@ ʊ|`"UVHE1◫A5d<<"QuVQE %BI\g:)EW : KDR'WIoxDNXIJ%'rNV*yUL9K^%uW'M\79 RyD*WP/a.H$AѝI" 4X/>$˶ QYX>/|,B *#KF"Hbk%#,]]Y ]jjgo%K&]\%w+$ HlYD$)eH*UI0\$$N6Z,0X 9Iҕu's:CO~-%&^̷C#R/K)F"3fټUBٜfX/T R\74P2HuʳH~{ƪ] k;J?ed)>#IQ,ӈKb}_꒴HJOdpaw*}l3 A6)@&4Q~+!Je)Ј)AyIEkUsƹ R{һ9˖)SHaFV|ޚf:ET +KN~ M; u.P4𤅱9DDɅ RK$~+wiۏ%.,YP2f1YtOAJn[UwFإS ɾs]$|ǞDrs+9p4wvyDi<[bT/mއ&s [2}K7E^2KDri`.lyKOt]3cngI[LڌR Q {I*OMlf_[0,ۿV3\ȗxp\&AY+Cv ϻ(!(52Q{ibo[G蝐 ٗJՉ@׫첧Ъp(rFφΔrB2 7\f;gH8mV|f{-7KgË&̣:z'SQ9 ۑomC}ÊoO}M[~~݇i]]*>Tֶͫ߯~#,-~ '/H0F\ߏ\jGr|A϶_7b{w*-@Zɒڤ_&i{iIgG0WXs\̮][cKm[E?V*]n0iP=$m* wuUu!ZWbkٟܻ!nϙUr\o-}\’YM3 B ⣾zmގ.#k_EDVf|BW_M=—}Qbkf-"6ч.)@|Y?gA@Kj.z^^"'b#կ*kԉocz· m}VF\=Ctv_ kSFD;8U }t8e$[4K_^loK=ۛ&OϏDe;cj$*kOͽ0ҫݗFTW"7'BZlS衬+xב?Y&>jk%/R*];*M9wbn7% jh~{G`$E]4]bkٴ?>jH-{7ͱ[6g?E[[D[^3pXtdut$>Xl1ctm*i9KOɐlM&rA٨{ m"`܈!bG iA"v·SG!%|F,HN$* 9~Q#0 ,W$џobpU9_KMZ.TR5i *)a ;8$,vm !Ѿi{e4P6{:wA^ӟ@>,W\p9&&6-̑E;@(Du,#n`#*Nڈ3?놌bK`bH-rۃ>7yɃM;K\́-Gw \f>/)Gr!i4P,QDąMk3İEީ?:,0,V;禺,x݇EaG_͂-Ń(F.x0SV#Yj[H\ֆ; G*іmFVC92/=^7"޴'62MZ8-.Q[h 91W݂FC~C܂)2Tȝ?p< 8f N1yA&γd[{6M(BA8z&[e#?#aִ~6R*Yk)M|M<A_,vpGmcP-lχ6 aMW&j4py{)K] "w\ϖ;{Vh)cR8SI8tfRmʫu#ڵ'˧6?m5[;ִ֭q颉b":(6|ɘ-R%)}a=G6 Z.)GyzCu@/r6_nDЩbLo } Ɩ;{>K>Cr?9f;F su!>{߯%^#;NA)-S?2Vbܨ$?4$4(K:#|?_U5||ٖAz?+Y7h>pبݍ~g DAIX9xHvk>z[{mN_>"Ys9S"y~L90 [GLQM빍&Vq6Ԩ!Sk/ė jV&YcAδtw?@z&t]n~*=1ە67`.0å!ЧErK>s(v ن}~'[*hSuQKQ I]yy% nvUxlnuh}Q&FT|!Bϟ{>Pߜ~e8f 9Bw+nbwW.-m5?"{9<@w|`~Ӳv۽E\ ﮭ$킑}1E_ubکwcsT+wѩdCmtS.M Ð( ^`rӻ5`Tx9I%0uk%4ݽ~"Tƒb(UEF]ӱ|-ȋY ݽBy&=1BT*7l.׽6#߹.Z}oe{d0} >nǕozx^ :`YA v镯lC,I*etd2 v]CS+Ya>b^uT3v5=]8\sp]!87R"ܷXn X};w9".<@@)vx<]\ 4" ADP)TZUiڈ&E6GMʳ{.ְv߬5&c1B5uTZp\ozpy֭f^tQڞP.z#E6na?7wuFK:ORKɮDJ뽥В">H)] wf9TEBmnRڑjw.=|#\hD(`~YA#H-𮄓GcTO}D (%`< .n#y ҉O#hvNxFr6X` ;oOqԈnL0r;PІ6cMlAY 35%KTr7ܻ_,nEfEp&2`Vi'=R$ /su-FOPpǙ̅|}vmx"% fL8j)0 7z~ }TBF]alпN)N_z 8Fzɞ]VMcʏ~4S`R-A:U %;m[`&5iCl\h%ͥ nkz*cJSIЖBNuU߭ v]mޯW^r^1 閽 \t~Oqtw>: )Y5n8d ~ o@95fiϛ+<'Hw8wV2&po% o>'Q7[iw ;x9~*僅vvsrliޭ͓ڷ}l=2w7lǍxy\nnHVeXVru2w{MR[EotG3TG.ǖ|/ ל{| j)6x7A&o: G;?#AFikORG[r -SSS1݈~? VrwT"%zG x^,Ùr7ѳu9nܯ".q}УvyZ;}nưb w?bI}mP^7HTa Zg{o ȴ)EM V9eę1(HGċu0r+De8L+ m%hDKv^>ԟU%1[#b?dעk 6brMޭ!|գU.L!¯"@Md[=mܚCm+Ng&4@]#A+Wn7Ea!)5P%x3cEڶMtUg4L.%@ v6 w6eI">n/AM!5ls /t> ؼ̰D&3I:K¨umao; 47a-hn s+bpmDT MD5Mο&mdP HF"6kOy5-Xp4`lZ?io>K+b2E3k Bǧ1/Mv715M Ń\d:|kHr83T TBJ0XD•ޠ/v>bH1Ǧ1.& -TBDs {rgWy~4k,hX5Nj'K)<$ar 4/q?,>0H$H08,~+Мx .s #\ Mb~)|נn`?.= JbDsA7?o w1E #D419\ S ! i=Nv)#7rw_cȐ-ku&15tzZY똆Aoo/(+1E0/(v4d4&g3EL&5Obgb‚ '""q413` $~\Q윅F&F spM0ucZeV/:ڷ/_f inLw |mymY8 ְpgZ\ ~a4)(br_ݼx0LH:$yo(vkE: {'47`o_`S -n7B=mCU[:.~!ˈ!5 wr7܍vn{9A )R1~I_4ݩ,w(@[iY")c9Gg J IAn ,%hnrrR`#[Ğ<&&]9pA+<:=|uhRy>TIۻqVsY-ђ[9J>EknzD+S6kY',AZ^`wF7Ew t{OlM^'i]*mBvUl2 taZv]rSa:l#8Wq͋߮fa`4wT@-ø-;j`]p^%⋝5u>k" wRqH?۝h6[<4Zc(Z!]v6C[5ov4wpO$Hg sPKdH 4jquґєrZ% M/vIk[_'C))ўPבqOq)aQ7F>FnxmDRs`!8@W׆/oZsW(uτ@'7INRx;MaIb_>{rSfG=xi q/s,uOD3,VRO$YteO?wWSu7UVbZAm/I )E:OB@*mJiˎCHi" +G.I Om&n꫖^MxmwnYֳ/Rw^V%}JKyxkz|IUԎOҝ}\=_~%!8ԛy-zTW|VT"w b3+s -U7Zl2Vp$\%$n.?"49]ǔ~y5d wQAkTDj^CQ=]>6Vs(N3zhnޭ*GH/=_^VV)tɣLXm=`5K7pIseWONkm̯/SRϜ/ cQɥ| 747Hӹ =ǀ]e1>k ivy2v4_Oc]LǕ궰_姝6qBlK8erK]FDPl)@SZpK9@TF1ҵ-{uc^KA c}W1,!F*)т2)9-񹕋A(\Ѧ)/c#\>B. t R,ibRctѵk}lTb du# $lBK8k;H|Ml7p?7fKGXaB܊PbAvO]VĢLSV7MLݲ#whciq5ٚNbjs& 6Xk4$IN# x>D-G8Y>Ǵhxp Q/6w]o6;X7_<<_(A^bS߈p@g&ϭMk\6a.nuJuɁ:!Put5HufT{<9X8QTs]Lx1ǖ(/7mHk$\aN;#S_kӢ;GW,0ori7p4jí/=#ͅiG9cQLLrdfb`k'zCe$֩X8Zumu떦l4 Hl,f4/\d/k1_&_bB*&:qmyfRhȁ';S8o?RŬuMh9OTqkG[ѵ-'go X~tܴ xQvC #:;+kIHAa۶>=}׿]5?uY5ҵ.^0LAf;P毁E],Y7v eݎ3"6IiYnq6~3ϵ?+'?u6]!bFw="DVVD*0)+wʡ{d$_m^kN7i5zwɑWr'vMqt%+P`~w#,[B45}yk15CYwCcgcUO26i9!;UrJ7 t,*n|ԯ<-:=Dx4/ۼNuZ~ђTtmӽ'XF%hhThѵCT Xpn2%ܤek(x,+0.\1ߑč]~, %/iMS[[#αLmȊo= egJxqF'[""LDH5#b%D#JZOKItPʌI[)m.caBD4)L DRQ^@o5ȯ3Xz@#OKRlRczٳފe":&NK6 mt^l3~Q#/\DWo K^$c#ٞ@2n76#͏dK@|G[6iO"ɘhD_ 0r&οr#*L RZcN94͚GKti!6Ҧi?"ƈW#ՋB{@QSJnQuzqC]dJ%ɍQ-@CRԅ̐~QxBGILW%{Qy(L<7%MJg$ӪB1i݀3I֍g]$sD'`u΁IQ7fD Dm!FzkvMlyAɾ=~B{~7Z;2v?<q09نR k3H}w]z1AaM+xR\:0y%mmﯩ\z]}7\ʐp6[\6wg#s}kNP#p4-s3& aj,2I-kW@6&|a5C2wb|ZsywPvt 1sa(o)GEjgEs?9S][;-zetS pI#[?FV(g?w֖+Lۓy;ږy)8]cd0]nKn%OeOD&\~qnoOx^a|QpDx96i:m&.Ys;k֣FKAެe2rϕG)~c>ehY]z>k9^nif~[J˶]GU轢FOSgωg4Fu2l?>C&0G>U\98Bs^wנhDe =WҲ>Zܢv-(Viij$.أ2J5gX*qΗqVE`Hų߅-gdȿѢp,P&0wቆ\ݕ/{*{ܒ) wƤ>_Io!]ueYtN=딇kr$bnAxh!|kZO"=B[a1m9tQb>R^#aQ5w9 Q|Bo~6a5s(kú(Z˴!|EK2n {b l&rViþgh +ƠG$&8bqRo Kg[4'Z 5,xD2H8 D(v-Aɾ7Ts!  QM$gg^8Є%5i *HcᢵIlM#|.mMu3&Ĥnem! L$gf1d$6 b-ZSw~7}7x@AϏo5L'pB5s@r~ށo"mohb- fðe rB56eĨՉ -U16Iɵzƺ%II`(Qq(V7ibF5G fL~np`O&1 Lv"9#>1B5?^"-9L3 .lL/mIaMqEv98B5gd*xSV~Ĕ%}K4~)*][ڰ|rx2v:0vثK|H[,o'~k@Л_:4,|O1Q6t:ԭ9<^#[u,՚Nsl94JavpM6rh-GRfo…K}:zmZ51\i띶۝Al`oBd_񱄐s,gwne'ZE<-#.s5{o }Q3Vrw\[:ΐU|n}sO=B:휇in(B1'wOsjq#w xMޫWgKOo;oi7j8yG.ǒD: /Gqcr|sy+"]WX6ԍnX)"p[gZ a-DO|`g\~4cޗOf:§(y0ʹ C#-p:x|CD.r7],S!yݽy#:%izpӑCw|>t[-xui0GNoOvQFμ:X3`fcv* blӰrϩWrνM '=Zl 77t7`@G3T p#D$Y%54bDؐZ(k sw0p 4 0S^W%z5ubRgZ9h@ͱM `0RBw ŷ׻r#]3(dX*6)U)F2Vr (n(B$z*E)(.$I#e.uX Ea!ϐ{[E7>,(UR Ȯo!K6)ASk w+9"|`d݀77ߦ }ܸL);d~E$1US;^{ (V/LKZ7YAVec^S*m/Q҆/˺o_ϴU%Oq"r5 :YK,{Y7r-mR^缇Pru4~`Y N}FzœK7!iJ>U2S&o՟󼸛.×t~onE%4HxCw(tX#gמ9Ry[sHS ?r OUoJC }489_f.?x'~\Ęއz9.,]dS,+̴LB|ǩ\J"swH x_,?7gpu<{6vGӞ-nr6'F[\G9umٜ#7YD{@E@7} !L~2nug_Ɠ맮gqޖzd 7^&A`l>$_v)6bs+Ս{Q6,.ccKF>PG:y\}2is-3 Y+'N1r_@ G;=^׊[xl5gu oЕiKZG;ٛwm 8-ᕪ=}n=g[Sc[GGù?\x׹wW+ybEn͗| ,_ky+hޏ<%WOw_^זsy;N^ܗu7t빴=gyct-9['t\|UT׺+MDsӌ7,Y0zӲt ז)! Mۺl&ќ~sὲuBȋW7t9ˣce{3򻧖/4IMuCCы;Ce޶$s˴j&^+fzMk-?tCtJihmM!g'rqQ?5&$.KGY^՘Gp)>$(-dMs Qg]er񙍿\h#yK}1]IelnѪ8*6OS-vܧkj<}[+c5#JW߼ >Bqkn]^l [EU?MZwIkcW@\jD][d yӍ-67{sCTpk9aͣs/⣟S4"?zn(;h֢Y -¶L˥>lǝy߀˪HpE͑2-Tݝs#D]ްoִ1eq7NqVsǓY4r99Cd|K@.-]Y#wEYqDR3cEiOCie{uf~Ҙ޷G~n2+|J}o5$z,2 nvjJ9z ^c /z:77rJKU*>{ޏƷhyu׸dhH⴦mW8՛v.Cz?zCέи,B"(?[q2jt3Y?'k/G9kቭjlݿ}uE!]?'1? TRS*sf z^܆d+͜+GB4Q&b诣@">I>$]6OCJSh3M8zq0u;XZ1Pܵ/n`}Id7zC Ńu>֭yޮ4*s0"قcR=.bt:Ɲ,9Zz~S1Rde+s_xӮI-ía:r*cHW\]ZFKŹwaw.r-/!dכbzR*ܝ8b+8zޒk! 띧\oc4PJuR𰉍 e??}n\o~\,n 1L}fc"tO= b sGR.ĸ\z & FrlJ&&)OR<KW €CiL4~[D&䙉 $b14&83ʼnbk3zVh H}<_zB;>'An9}#boٹ <.1ōbb޵'&qk]L0';|TD\ DbaEiGh8NhK"ݒ`q.hM Ĉ<3xvLKD!&S\,6h3dky+\Ƅ8n&1 i5I}&n\6%qq8s~^#J4aAp$1_D311흊8dB# Mq4]SMCnam<)Fj71o+1&F4/poyǑ;) E`j ԶY0mpLZF14gnLCu1OkFt11LL'.&\}/i0bw1A˜GD4=SqH @@zPlGI`@|͙+俦Mg PWتΦA~n"fTe隊b{{1~[B@:3'q"[i$}y?;E^kpZ5 N{ةh/-G '>fJ1H17 TsMx)bNN)_Nۜm"SԻTȾ8vr[Ձ ÿM`]P;8&ޛF2v;ouOU8"=[ڻ;0q7PQI>^\ /YLk9N"Jl+m\M_[\L G8O=&%d-n`-/K[Pc`I d|0ckc@~X7*C'+mtRi,XЇ!)KwHnu+q5xr38‡ tݫ؇VNZtJH\ѻ8枞k-]dǜVӺwVP˰ߴp|5wHiϣ׹Ϲ22鼼㑪%cjhݡ)ag^?OrYGW۶KxG,=|zsxSbQ+ܼ#fu+bE$.-=dHS h~GCf8~לJӱm}.o17;uF'|w7MKؽͨ-F7J<֐eYMѱe_Z8N^3%73_[o\fBËrOX^3/ֹi-qd1"fjcVڃ=r, n}-R94ws/֫=830quHkU, Ǧ A=v[ lq1(yB"933_X@G?LϞnt.?DYO.X̿<k۹ݾk1Me=mc ybg[,SiT[deJ^hobw=\Q_>[ۼGDIܶ~fe\z^ ^,2-}< H#xFo23?II5Do:ŷJ>lFv*c56d c282Q\Q"mQxdޅXҏBӭnSO)imƘbI)YQҩ,8ݨt&f# xPRrM4fx1ɹΣJk?Vv4c⍙&.1 l cߥ̏$sb,#hՑLqX6]1#@Q֩t[&m+tI |fd5ZvliV˴,t6)Zto?Icmދg0_fh+6)*ZH~/o+ɓd+bJId+!IM+pkdomVMf药0F+l;Qh9HLldu* iItcf .Y|{"]{ 61bTp:<3d9{WLxC%_t`H9z4rХU~lÈ0'oDq`gb>R8`u*63=8QhVoEEZȱ&l~ gGϤzحZH[ [Y,q"ʽf307u6I+ف8L~fh?g3*8WW_DʟI/|6!O%zFlvS&FʉN֎/hF{:C_15FR?e@1ė @2ft:}= xkF;c7M&61kV4Y / /KF#nj-(: k<2< _2UfSk;$̩hv%{~X >[sl{GR2=Hq}\cs eǐ.d1oOX"8.X,J NہdyFoPܪ6CE&)Qa?ԟ-Z #_ݘPr˰LvcԾӗt]c©n Hp,9%!64s6|^S:E==O繏o"qE߀yxvoyf y.Ky_RZ~oɃyr|Ω\N~2zžf l:uQ/~^/ڪ|o9m].doo48Q+}ūhw. (s+o4s/t͓#,dw364x1/n~ҫ>_nl+u %_F_+|{_sm(J^gS? *9s/b npXeKGRi/e.귘ᤝ9]K)x3ŨZ>u #i>OGsm;6f8uipd/,3ʙy!~e DE.cg>OAsY4{i׼#(6Eu[8urf,k<*fRF߆d_#fAto"Pb5 t.V!np=<ӍnP&K5;{޵=`{f89Nީ\F{$[ܲ,1{1vXpB=æ]m}@Le'Cl-_pLQ>ši g!kI߷h8SQ όxCrNy'F =rP/@rz(vˆ's`33f8o97obE0>^c._2 t"R\yRcv\j&q>90E>v_6%}#ڜHH\K.1Itp:][pI3 4ܣNV{*gʈ*L\>4~^%f8:{G/&{n3TwP#,=J r.'uKNS?Vxua!ũi )W_t&gZz1r!uJcʀמn񶞽vaޚU\~._2ܻΚ3mB~8)>{wteZށEM+7^!?x$ Oxvc?ǵTV뀗oqZye`H78Iѽue 3-~HLq([K$cL`ɣ[)-)km |[2xCA:}ܒu۵#Ts]c9j6,1C)mzяb{p~.(q*jkڏrS-]X6I[:ϐʨ*F 6pTJ3I {S$XX~b >krD5h Li=Iop\85.r`ɏm~E| oA>Hy9^"qjE6`}E #Q 1L:^8@G]bj#(ꡨ4b0ýꅌLƫxJgg3St܎LqU?MlBGhF7qo&] (dϴr"aPNDD3~u٫Lj|KR\pr@}dmmidB~#g#OPy$ggC>Z,#.J5DY&JЧg39K M_^G# Hx}f>ea%|%RE>e5|yMvy"bY/6 mWb>2k gYC_dudĻ%M%=ٮ:KV5gsf0EFxƍ 5K2d/gѝ],dͲؖEdm ѝ~@ɜmk^S=b0 9x + w7] 6ˈXqa}&Je3n_U~&!P+oZ"[lo&<]h9%is=y jގ%6Ҭ"'jx:g}?z&| [lLϝb/ږ#鬈berC2"sO972kiJŪq.<%/OG+ݼ7J?P^'޽2E2wGt]#|44 ?oo_iݏoO@޸!(:g%JQ'HK=2UҥZ?^:e*vז q}9-"'NqlxKk wgX7oW炃79chUHG @di[hD%=+2?S܂:ɡGw+h gc2*SVR+<].,bc,Uvދw.VNȹgl⋨p ^"µEF{>A ˂Gv^ }]eX <6bb(^M@}mەފE\k,(ʶecmzcD|}ԥu5?璧~coa  $`Tₗ'x.YL,l8On-_ 0nQ#xl2`vy/gL-Pu)\ 'H@0_- XD%50M] \bƑPuaKh_͙ 'V3Rʼn61 WLr{4dTAI/n,~7 ˑIt-/lY2m;J_kL"d-sƠ{V8QQ Mb,y B'+j7m2E FAK3Ma돹ޖ\[ M,MI$ij!pҶsg7Pv`݄Ǻz) G1f$ya]7N\V7Q*!Y ׍3"z<.G`[.*EsvD b $2F5ٚI%! k(1q`}˵Q`O`̲6pYL6G&e[nLc0dz{rpb8!Hs{90H$mLT#TRQ!9/Ħ!gh}T"Q%P7R 5\}Xs^Lnڑ3鳄v=33~sz70xH/@iHEk:P(O#&p4dco+2k8.د G#aJ#@h-/dosl9_xɸKrE iL^'~-}í( 67.0nǛ́ obgB3i601%q Cfql(x)bkg>R=7Ic8ߚFŸ lfsА\Eb)۾`>V hbF.x~Ä u_}rZ+e';zE3xK?rAp^+YjZ-LOF. ]t8r9] xZw̱M'3X{;fI˕Qĩ3qH=|/}V>w.8s11}+ ,^[jG^(cEr kN| 4ގ _tZ R̄Zn^3#RU\ j%NG{= vq5<+eu1%]*][Nv.88ZW\,o.X:/{vͽM {\qe2mYrsvGu.[~x[}tqu?@fB1v61wm(uRe tF ma/mbx*ӨTw[(9[ EL"q àYbAdL5hc}> gO)T11̱8<8゗2(E&<>2KM Ҿk3"_to݁UqC4dUe: 1 9%)~90a6u}ջYxVY\)ҹQ^ZoI7.8H c'3_S laTҵGksGHҤ֭r)9אTwoѢ]Ο>̣\uRy_3tsB^Loq$]˥g*~q^^59s>zUb;F/5|5 MZV\i~E#npW5<<i@bm9]1}鯺/hfc~ "]HQ_G~q qUqŊ\8593}^b"z(2ƞFZ}þQiY@#P2Ҭ9M<;IJ߸{ 9{ a=)갸ߍ2_Ĝ>3[mmGT{unsJj.c av m,F[oXF(zTHm!~/2A j5FnT& m*]N[OhV_IJ볤;I ;NS,Eӵ<ڏWJ ,dImIMr7:LYq lg:Icp7kc#"pru NR;@$w9ؤpz)h&%fݞ"fn\YULW E:{w+/kӞB${dǛyQb]?ֿ6悤t'tvo*YRv(|G]sl_k (،ztUQF s"CŴs$Itqhb?XpzY RqIYf / μ/dWOߏoOg{_1x!{#F;%?6soxg!cEf?32:lmB%V"R\pb)$%>xΏbx661($?Ϗ/woi~j'7[>[{W  75Hj|F}FIў]?~yf dTsV}MqM5WjI{J.dk}Kӵ}3vK:/db{+[5<{y ((5RzQT9 B9L=sK <%d̾J6 qRkbUL1hUu,5 ru_[g1~_–S3@=}^CVm4᝿Z2ΟǨ wTr"iѭsmBU0e vդ₇ N2uhp2*܂"ޣ{ű qw)(lqFGXdAx1ԥȔ ^<,= ,:WEi!sDEG8Rbɽ_[}fg,Uss]Oe~[pq*C6u#zB]NGxQlTr}vy;-zXa{|UI ;@o<)@[xobaE)qqƠ;M@4Nr&A!\8Ö%\S ;wOb/u_ ׀i&~-GL4Y0bZE4qL_ÖkdBAH)H730CYQMqĂXpm KLkePD[|K& kp){ATS _M'P͖0ѭpJ@ۜco(&6-u {۲~! QM=֙ tSuⲺڴpmꦍLq1 GzH 7N{2Eߪ[Xݖ0ݢC @-#iSoڭnLoaqOCm3&apiMg7M3.Fm#2iznÉ \bCkshXp6MtDsy[F޹ЩpJb3Y\_ݚmS/~2`} Ŕ$2bJϛ6nTBqmK~3{4bobhsuc5 lINl}i+)aI >Y gd1a1Aߒ<ѐvNHr V2?@ MI/)hnb&$9B$0S#p I2CR͕™7^:Cv$0݂~ط0(fS6o43on@G*4dHf| &3FYS28-IAL6f'BƉ9p'zI%/I`Tlܩщ6bx(2,8켆y,AXwY' qq~eI>Ū\oڿ"t1GhɝXӺu< \5XX>w4mX+r.C#͢͡ IE!IMKkNx6Grq7p^y؆,8Ǒ3pNRLZ~Ti/ے"_O%7xf>EKf.G>x=9jI%Ae[B:QS/α9Z˖RiW7^,mÂǕ}^3H8t8$|ˁ?n55c]]کX2is LaIs?#V~gY ~R{so>Jט%7R ΣTbH*dgʏW;Dէirjx} _[Y}^NkTwHk@t8 ,7qiQr>:Wby·(TB'HJǓ(ݸD /StSi $j3(ցH@YyY m.5B$ͩQr9[Pڧ3G7_@'d=1H*74byYck-Gbc9"˂}~;O- b 7w6i͹yר1z׸@2jʨaި 'ѹP<_X(QpթeNTih>*2צ -z7x1UcŁREbt?i:\,kt%˿錼q-/to⯧`}HZ!!ц|&-a!v>֑`4r79p-(a1幷XI#C7~/;l+zCsG=I`c$=7P)͞g$bg(JVJRQpCtiRF_d<}U4X]ui0)Jq8{ ",DFHpEIa5F,:79b"#Cn2]_ cGR mʫbdx+M*"1ڥT̏@zhZہ̏n`k%bqug')й_D##QL_L"F؆7b;CDmeX>HCwz}z"S*( 7 ([_D`~s %[>XSN[DDqH&#EY nc)g{nl:Aٛu㞂UdTpxGeȲ~g(? $dd,˱UL#vȘ.h`RѹebZۉ*̺0KVM#*Zo.Ri_ ]lC4SV]CmbboЕCͅǼ{ngYk8K}E3tmT/šlz!KEQ>WD5{+0{&)IzVRG`u`굞$3\s@343\ڗWI;iߠ/Kui /N[&kb '}6xynEHy4-i`['t QgĻlҽ?C]#g_>Mz4!|ZҔGϹ쉦?眏|A_7K^FEz.t,۴nPe^VrZg?^Ϟ\pְk7x1LU'[q /67,}'sj{ ]n"_gJnEZ Jx@jD> E%'87f_UŗBD߭tL&QҴ-ݏM"ŏ9BM%]e}nCi ÖU\݇ ~nN)\- N{y+l?ZO\^?H{Is;=H+d^>sT8!ťm䤽֖ j_1.B@rCܐ6'|zo{ ^fV8"ekXšbG[.V؄!5(wsx 0q>^I=WyG>zb/ԯL=Ta^xe eA-Ʈ7왗!Q\A[YWPhsXKıb͈W-2zr,v "Ħ~(}WBi߶r؅&ޫ9E\ -W>@נS1~e/ׅ!|Ԙmw~Ce91Gەbn\TWYjxk S*Sge*qǩNiU/՟SY{>XPa o-7x?uš%=x#MP2 (alI1⍇ÃnH3ōJC2r8Lb^ł%KLh"2ٚF;ENoqIl@GNMӐ)-yE 9"Zfqz#3I[6(u#PG(8N$8 BCn aǶo[Tx}Ӑ*@unO!Ҹ0t 6V7mr$Zz 9Zy'ז61 p Ms!][}Nl]Pdu.Ѵ@/mJbxkJkґۉˇG)' H`qs Ҙ˰9;]IO{_ fOr$mbA ҫ7r[.2Z 5xw !eW`>Wn:KWa 5IIs kIZaR܂{AJX{?l!ǀ))+rM!`!epb" nx+ /iC .ecBYH9$,~/6[LG1B6J<7e7SB;{sa-Jd(@/p_ h2D07Aa>4\]_b"FI+ ŽRgB%G77:1Bl2 7 /6_^ti_ {#g]2¾ s^:ɘl!i.sV2 t7y0Ȟ $s桯h_x>O|{f!#$~&=Xi_ܮ/s PrC㞒Ӝhُi 7v[.ggecϖtcsYXBr_^5_i5\aRm_[[M].6V}:\V%M\{sۭ%58ۗ9o_2/_chϹ :)EZgB]IG =t(r>*s ;]5h8k_b-Rsf9h?7wSeEgU&_}\(~F۹R R}dos+1δ[81yV^[^-Pȝ lK[Pr!V7mR^MېTxYm<{9wm.X2IVQ&Y\C[ӊ-ؐm]r ?M"]QJݠMM,x߂MxߐdHq lyc )Y%_cM\Jל3tŹrLi+f]]M*EM)X+ [.ե2_4$_4.T蝢UyϫWbm^H2s93,G`wf}1eؾ`b wq,zF̬,,}VMZEW%T,̵lڇ*?mi_1Xe yh!6 )NLiZS^O[HPf[Y~$˙al&Tč3# REB"`9]/Md|$*9][V݀q^D;&qoDb(a"O8/_D"]OMcp#{@T}yv5 oBbv4@~ñ @@rrӈR8h`ԩ ާƵQ -I߬ v.1P_,{ 9owXz|UCm;(>iNޠ@kAf8縏u kz/AR 9 pӂm[ w VC@8/hH4_FN=hk:`"HjTs _ [ᑥ|,1/-c#$bi'9~ lH.86-\jU7ψgFf8uF~[)moG`1p/&~.-f1i)>[*񢍖jv~sb1Kpi~[wi+ IXoDcj ickcV7{"rj:.jјpT>p6B-R)hN[Y9l\]z} q@R4d)AkX7Jufu¥ k*i@i61\(!/޿&X2M`4o,eiʄ}bXS5漊gLc!#z7ndw1cV8t\h,B"ŒyfKm҉H{4J 8s5 4[݄607%֐ Đz-fLp Fm} y/^6byڑb-XZB4HeEqpC2XC…6qY_)_X[}J3ӺOݓ!9ytGd+fɴNk6)mWdmsFGοƜFGtr8|Mvy2#R\U}Ltvn^F>}f"M:ٹeF~sgGݜ!qǕy:b)^ fzߘyĖr=0~&685މnq58j5K`JzD.6q*{M<&6GUG&7uɗ*iO5C7V%>NkM@>nwE`X,Ma=[ߌཤoE8S|6q9M8Bn3 qR\N}SSޢ^ [C-e=V^Gm,ڦC[OenqqJifÚbqXnQMGnU>nɈS8F8wR1ō8Ik]HjC_v́|[c,Sǫb8.Rm8ӵ³/#xǷxDzSͽb%s ${iSY{;j6tR!ڭ`ةHߧ1586.igJ.ǁ)= R[=SsO;I&}fIX'{tvb{kE2636)z 6kDvv5j#2<;Sy(} /z~ѻ iJ[!LѦz 虔 Y">n_H@,~Z,Og7J oL$?/nxg3_3z{I|gsWF;*m{C 7eV}h?u$L[#.1l{(L>/{^^hǍLo)ڴ0;2Mܰ[%>tay }ulu$]&}?r%M6)@m%?nZ{i&]g)Qã♐ZYNWRW_M/ פpko_gnR}Kk4w>c w瘿Y)ި ´9 ܖQ4i}L %Ou[UZ-!ǣ;ͷh^I`͛%U ^UL^ŋt*1xu<Mi{WWe B˴͗Sr=XA3FkZ{۴ΒVp̭c9\b{/[YPoed9Z߬~n9;ҝؖSySqXܛJ|i (wYT\琻Q%؆Doe9%&ExV*R/4Υ j&N#s#`J,Kem9w yIE;_|S+|x8nі޴ͭPE;䨷9M`/nepyǾUJgEAue_'y ZGK1MHH|I𺘍boCĐ.g9`[=E3@M EĴEl([8i-5P18r8[\\~:}diqL̰Fx */=_JI~$s sq/u9^L@iw)ވ1pq EcL*5 [`r{a@2[ LOyaDŽC-w 3F AdWzs~oWݘ䁠C#\iT8-Ccӂb^aU୿.kmf3Ӌ6dA9|Ek![^{-o}=-7iipt^B1PM~iy/ioJ Wm [Br5A^<Ԡ iͩGv:/'~"oge,kqFf^yo9uU\q0%<ĥ5m/:]8%"z.ؕ ]ĘOzC-k߷#ѭeM⑪6KO+|94k&pVz3S ڶR;WL #̩t׺}^GQU\4c+: 3 `ʫm§%s4@gOi`rc+9jxϼSH+z%%&.vapqY u6%v]э:%yG?Qj /\WduIk)⥆"n~٢F^9jOu"0Anuc=^Ek u9h݃dW#Sz7C%^|㲌) ԕޘg>Gcny| 1EZV}Lek In]K"I4/ؤϙ)VF3?ӔqkҭnP*^9#[}P>ҵC`ٗ?Le/Wp㕇+u@a6^y9̒O9qȸT"|{f[+DhWNCEBvK`Sr9ik\ ϥa5ZqdNodhmnIgYlp/92N"9QD|vdC6 Uߍ[d?(@EtK$fROFz/umhmg>qMJ~&#"#7 7)ALRu; uZ7HޠVa[> Q[n;#IHӉ{QAWi&8DF@olRٕteW&mdu . ݲ:>̟Lj,F?oXH(јJ6]!gs~²~/)W$/R\ KuZ7d $CW#╋uZL^]F_93Gݼ Wm ݤ9r^ NAHJ3/meufWs>v:#KJ.ixPJ֝euzkX[VyO[wwm"yIuNR}5k(~(ÝnN˜;۱=iK/뤲sCV$nkuo6^&1|+Y罴N-/myL:zdŽiVO$g(B|HӅ"i9eny WCw=rZճc-GvXܬ 00̼tf.mk#[Ҳg?sWrMYg3"C"*b~wn.frd?J3C.ֲ1,\< 4͘!k9vYb f/X(򨮕7Q]?tf"pf^s4u9F(,,w[OeByη-Cq#OY>GL¹GXhkٓSj1re6kد%StfL5)XeL3'E`8:5jTcCvGqQX;keoeeoo(.+dO)iq]?[zI ir l!y>g"EY(O< AA~]I\%y>m(b̑SAHtK14C:^ܠoY0Wx,:W@qѫ#$8(sMYYM5 ;N{wm^"1nbD-/$Dό3qܨW>N )ܔnl91,=&aU^3h9w2EiiSRkXLQl%a&6΁Hۈ}Mf-5+GO\YEͽwro ʩ[MAf!nb!%JxI >)Qx%#{ig1g-!_#ED /Mt" 6m!;S/1Nfpe`#fm5D>ʏk OLs6q4Fi'C v|n>H9 NEmY7zk9, 4%/<<$Z ikEMCCFb8ґ[Ӛ6=x+YȆ+&7h1'"FcTX,dZr+ۻ}4͘!_ӌQ՗y&&K&s P_Q4_ p~ bD4HHyة< +bd#G}nw4Rcfjw;n&~)1z6"ijy^zx4kA;9zy@G,9CT%p'BƏ'xH u!QΗ1d"#۞ှݟwX +=}pk4pⱆlk:=P%$V˱p#hxbڴAMLg&VhkF%crs< 7"&oM{Tsaxf! %o5 %2 %9< Nq7o>db&Fp>ڸQِ垑4 u9ܝsе+hzmr'8ÑxrZ9]xTɟit9&i>nwnS,g> ˶=-+w_;qkgtFb8xMSo(+ʏ}sZoETe۶(ʍ ^#˛Ey%_}U6 -M.aBMz ^S(s-oSZOo -]GF֓xDupxda#ȏ *FQEkD/P|0[AsxT\p9ǍLmW|nc68p(>w񑂵7>M@-ºܤcm.["o ,e^{~BkR.K7.x:'GR /=mO#n3ȄE@>RDF sg#P% cH'~ cHR"IUg$Hܨ0)I~VobKJuJd#Om`#o\R ;F2xe˫gR+(͗ Dg)mZ?,7)!d-jH@ r]VJ *o3( iDF.)1R^/4e9ຑR)bY_Ij%_c֪# rQ,s,FϐGe 3PYdϺyXҾui?VA.'$] 0Fv$*3#]`9f`p}Ψ7fb`%n:OJd~㜋NO2Ef>>ѧWS{q%6[_E lHnON7B"Ʒg2)IWTayFgI)ϦF2xj_T`xR m˭@R36P,'JV9[Jc dJc >9pr{I+EUr:X.6 އYs0t_nњckV/#Nǹ3cUN9,(.Aھ<Sz}EK/Royvf(6i_xae3y꿶Q\Y-Hq}+}gWɒn ]4sϔVoFm<{YyY:Q<@bW-ŏY $]>coDYE=@`U{9:/O3c_Dq`/yY+|@Uo 't%F_%|l~Pkluc^]s䞂r6}=v<8$_t<سx[ֲ ͏Qkigd49I5F 6&xQ8nK{yH4C` xD: , -t\n\-'mC m*ѐ%&4i~;X/bNMDCFzk1bFV17&b;HI˜`-o(u,iu(7shbB&8>l޴toh`>qG9n{<+`M5$Biݞ{c;?Lٺyigqxn\p8JW¸;P7x0CM$~(p7NY*~Mz,O\r}+-e&1sP711n@fu[}[׿% v:J$MDbVtp12ppxdƱ,: ]^c;36 -B|#<!3ܜH>- ~l1rf;Scie fi۷wʅ0<8ߘh3v)M9I4(14@,߁x)~Vi.e#u1rӒ:6~/es̘ToT7~)/,2.XĹz}nx9y{MKZgb;Z-Ѵuێ8|֥z?KO8.B%#śa )5#M`@Nߠ5wX_ؠ iPĝIe"V?r ҹJ[S֩s2߳go saܠ!7\i;Cvq.|-#C}ާ7 }%*ov4균]]1wKM7G~鑋iG[1.x/3 L UVuo-m@?5\t_ϲ^_Sd5 +~ } Mu$Zˋ-;o|v=ba F^L,t/J*i<2-)-Kד W@9؆np Xf pa3s>hHjhp>BL iC"ЅB&$Asާ0ayOm{25O3BRtbɪC0\g2')qa] tTwz6pziÍC&UeבŪd+Iaƨܶ~Jj~Xɤ]{m:k4Ij%ABA\W=4"#ՙn\sleUc)"<}EW kIm ްV$}#j@R+va0i×ǒ J ^BR Jp~EvСV2 X1^Ҿ`%éu!ߗ &%% 'yRg]CCr+^7JhR `"C. `J%t/tLKcdR3n aFcl >?#i7, XY(K0?Agw $@IJ'W6 _kۀdk`xVWL&`h)gKz)рv~iZerIBw g~U[OJ 7Q⏀_#Aj_ w d+E&}Bh.Aix5 ;"ץ!(8u;066"QSo/]XUzOFp?ΐbWMJd(6}_ 5I U i BlJzU."IaA6fZd+Xs8zQ~/z΄f+Q_YOJ7/b4 *z+R*yΩ\R%/Bw`[%&}ގ~uGVo$f)Awދ˅}YomȾwSn%ߦK )a7B0ܝ=y|S-G5HjA:/S8C \`eݼJ{4_-c-' |ծ}C2Ec&^izZlH.{'ߞ- }uL;Z`}dn>c~gײ;'2r+y^?m ְ77VT+~s3\[>/6KJrm{gunގy+Mwd;l(f*[J`& .~沛u*]6ϧQ>sJx*.yp~c?O˜Y~!}J?qp*s K*WF"r}xJMx1mT/#7_vWyRDu;I=gS[9!~c\~`ҺNޢ.¾Qŵe4ioz~G/".W@`cU,ED-N&qYikMVc*҅tXEQT9nCV=Vbbo*ˈ;WU>E#c#^@;w}K )6tUadaN+k|uٯT|/yG4!Vz vԏjbnAq$ň;Hi L K\֎}t])#t8p[mz/o NebMP mTBZ"Dd0CW 1sB0Tp6@oϼAG#,7m ,(Pa6Mp[Ez.jT+s`Mn"aӐK lsq d=sĠE,ҹL 4&JLZ"WLӟaʑky+ɞ(֪Hb$">~Ȓ6֍=i#^Obicݖ3nM{" K-i`+;>ƷMYLh^aH%CF̴c;2̈́!y)nǺiEh^\rA;nJbik{9RE{<.u[i#j[(:"]w*܉(6s-4/"4$\pSBMFu6bc`/t~~FbF[́_7-_Po@cf,pnM8dݿ 6 r"7`]Ƚ,F#kv@q̪y/PimK1ͼDnASڀS$Dt!cr 6Q̉DL +&7q%#Q&HKe,ki/MC6b<}CwNҶQӑ gSi@5nAFhX8v+Mrֆ5;ѐa~P_I[uëLX7pናX _mL&g(o#z.~ʑc>bMK{6K7ޮ@# (L< --19w4JVF$ƕI Zu}B!_eȄ޶ɘ- fkxٵ퇽hmbCA|DM[c !6LLK.4m0 h9`5$rYVl<->Tp(7=-yȁ:Gȃ!1_,͙CjIҡt[H5Ӗib>pʕ J4D/r=T 'WRx9&qޅWgs9c-Eޚib%nm["~ 8.{Zw/d=Z .fF/dETkZ<}.RG`K{Zϼtww)\џ]\&xs`J 6Ȓbmug<}?>c'Dtn,%8tk"nb?gds-PoG^s^ޯǚWOr<,]y4?9da3\nC~V10PQP.kz:@A>ZW{ZtAd|!QE^H^z }6"tqy.khߢ4v%ŧ1/㖼 1x5fJ!KZ e- $-4 qȹ{ 9Ȑ ji 99Z!Ǐ9B6uf`#},KyAbh:ڇR@\d9_>Hr[rՓ{9'%PDpgަiᐂi}hK H^%{628!sݖ C-FRʡaaְy#n,T ,#T\qpv=7] HnP@ i9c߰@iJK2 eeјs9pB#V>ǵFB/* C0]ɵ0~Ƙ֥,I#8 *zY&A.]4g$akGAA7"1A=5lIoRCc (]UxXO"KPA>I% G+ߋxX‘`4~4XIlg {ď%.`-' Vd@աm@R=4"q (6F~S4C1U`W"̀R6 o8uc osLbf `*q_v} h%ߗdA?\RB&d/LRAzCPdXaI@6`9a e ;l6i'/b<&۠_N#뤡a"lp&3ZJ~ƴ҉EW`",k`z+hO`zUhHT/e8AJC6Ixg0ǠĀ4Y]bӥ5Gm`5%YuZs$ {'X=~ZoIưp;9;7IJJ,Tr3Do4wv ~G& >IigMQ~n37,ExYdWKizE—8C4@:-)@k -τÕ4 (}FCv ˍ?C] +~nu.Ӱ2wn;ZlSHvI+B?Mr }3pSPQmv]sLcR ݧf]v|Fʣ) mIeuV'ˁl7<aװQ̜߭ ۀ7r =,:̲R)WELkl15ޥn}ywQ`0c_˔'hgKL_xi9IAӹӷ/ːp|.FUHz fgiߎ/}K NϞR<8Sԏ<O[N󅘋[]m-Fɮ+'2ߏp^%E>UuN.M˅ | ̥4I_OYG6#r6WIZTdYu7"-V,7# ʯW.o4y|L^7t>epOI+' 9ʯ]H}^w Js[,j<:<ݼI~FPaޕiIݙAg&Tr ^z+p::yloHz'+K 79R^; .J̋-#KZ#g+v>xﴉZZ? hƉs=tAi忛kcenT?jֶt!clGtaq^9`kEyϣźcѻb bXR=MOx̺ѕS_1כt"Bm]Єqr{2cc*1ܣNs[L[M\<~3 ڒ:xM.31W9O(qE(t T_s!/e՟h\{kNge߈ʴ V<04q*dbU]UPye"hAseB2@K{mNkq72WrYS)mדq}2~F{i3%QM9M#jZD* \?b@m@ ΐ$5 IgZ"w ґƀmLcTxY -j7@InLѱPs&̼ ԁ`Dy@uߐa>v藦m3`Dq&mư ̉P.nu4yn9p`1pdL7doZ1b^7ᩩi'vGl kM_/t䍃6ii;H!lnZS_*?idk)9L/pp e!ʉu M[ %FːPGK:KPlw]E3&mP.f@qnjit1׍ZN>Z ښm50DykMϰ@>jb8d~p$7.&Xuǯk,f3"dM,pa\y\d!#iBkZ$0A 6dYyYc-͘ vSĀ#wK70+%cb7tzqOv8C?u#m JGg%`S׆-oKT8kK1`d&mT/bc?OALA3ԧ?pQ/0ss:qӨp0I÷ Y#2K}wo &f6 !'K$CΉ79;}Ñ)3SUw޴#]wd;PX8Ё;SKE\r#5Uڔqۗ{JgiQ, G4,C:]1_ZZ6rI\_% (.W F+AJ' ͧGHiG/EV~Owcsq~ a(Ӑ#U{/Fn\ro~1|Y*Njߨ G^yCiZ,4$$7; ʃ{0c.=}[T&Ri 7m.!1\: +J ʱ>DQT^C:m9ZF 5 Pw11FΐO"+ 4`z'G$ji)[ȻfMR'H{>7ZR]Ļ)ݽS?VKHbo%]K_\T@zn9z-^ |ZGI-L,n4Ie+%S$=jŒ:}lҵ7^gnraFHrݞ# S)ee"6eLESr*ҶG-[EѮ6==%E/-BWѽo,s*yc0,Hnpy$7X43PezݷY73}$2w [я%@4S\h7QS$u5f nI`@J#Eɫi8SzҨ_zKi1nWkҸX0C]Wopѻ/fwG )kȜm@3*<%%>KJtV2htfl¤c%k[D$6?I٤i{JXhܐFO3b]VߤfڭDw.ډ,V}kƛ+0Dl~ڍF/ivP/ׁu<}SFA u ;V1K_'7`"7 /6U2 %cfF v%)*v E3ID+3tNpǩ[u)WO#W5͈{sؗm9E=Ŏ1&<&CA3 i8N9_%ވ!{󸂪 LjR68Vq w>z": '⸴fEЧ}_zԓ6meqG%/e-_=}kZGj>5/` ^T֎|7Eoe3cF8N}F|J?e[H;q<=U"M⽦07Il? nVsd78r-ܺ"p--HXmlq܂8nuXmS z y*Vx\0b4<".w*r'Pqdw ` LhGoFb.嬸t+>߿Y[.84\Xi1\ւu{ZiDkCxa ڷO3 Nbofc݄)HJ3 աQO۵-!8`  kυ~mɅ,,|n9M Rw"@hK?lP8 9a񇽈U8 ج41 l-of *hX7^91fMTܘTxC)]@_Vw G9)muشieO/1#- nk?-1uӸ[pݑhm/Ɋw ).

1'6 Lq,F^ 'qڿ߮ aM7 4j1K19XoG,6kG FksO"/(uB;HDFn<ƾ>!%p'BmHh`LDg3X8װ<;|ι[-)Ђ8N5SDAw%*_^~CR+1]E@yڏ>XyM?x{2IZviLT#C6 ߢVͩuT<zkR=}.yUK(H~. ~񌿵NiPҡ*g ;Qc0MqveK6EZ⡶mʠ.WX>ou꫽r>ٻ̓@EkpLKmg$ݖ#HZ4{oMzv䡴{'a-x$S\Lo"aˁ$#o<қ\Ԟǥ(Zȁf4r;_SI<7V9DrXq5LNI)X]QX%mq1y* t2rYr: X]y s~b,3p *y.8sA{/U0%Qn5yY@Wg`k5BC?1<HB XeeA6le桮D(27")537lDS"mJ1]fR`52 %t# `Σ:FE6v$!AYD_6#;2.ƍ,]1cF/Y ^j3x"A;/cD{V/). pK)7H 'Iis^ETpl޸I۪"N2YrXXo-Qi.sd>2=e#îBg1Y)(}_)/AO]&1ziEB)Gg6l7jyэ|5fD@B *Y#H|u@#7]Qk@t_]$7)d~7)3tnΑS>QIuV1]Y]+&m RŽClX⫣3IduId;26I8{}<8C `TzI粈KjcSUғ,5Ex_須`W-!.rqQ=^w9ub /WUAE5{dq#\3EWz-wx3&eaǃ1 oe*ݸ`HH ja,Fm46eיF%uj3m%.}ũl*{/Yb76,j,1t́P3[~o"![q5-.{wTz-2bon.&x|D<*'-5Ӷmlb к<4croZsgmF"` {n4ushj=ٚm6XFVzoMdk*\bK&mRhLDž˘H@o(kTZ CXmzĘ@ܞHMQfahCNo{!wVEMͅ.ʟ0X#;ٚC XSj};R! cA^bV@y OO"6|#k^:[?\poŘH9`Lt>w66i[v|#k3fAxKl 0߀lpۈi6Q\bD4Ԙww08옭< X8C)ׁBRI ;AE9Mdm)/Dw"NlͷLf/ o[,0Wd?q~`^D!D<S(ùYuŞ(͊ M Wwq[įnD)ҶڂaJG, h4 ꀖ8I^r ĸr|-Yo-l F;]im1_)!@Y0 ~<Ў_4jGN#~#Zߋ_@bV _ H)˽}\WT7% 5mz0kƑҎ{(-uD([[.Y*}3mq9ݺݾ0hXf~n-ԟhh|SRMY9-_rr !6K0 1 gqCc>}F˦a 'W?J[I^e >6d8*81Ddx7ɔ4֖2w2!eDB$oo1BނK\os [TLcozStiBǍz Hڄ 79zq K֥̃nՊ _sϣ;{e\2Mqq>.D͙. 7x+2c#13嫸幪+YV)J.[M0Es,Zކ),Ǩ3q,khPZy?zo9=,y L,dx ܐA|C\C$u!A `?[ s WPzg_p%c4ߧ)n^m'@hqmZAiQב?iAxk΀2Fn9]>lKp(-0{M ԇ4I62 I$췤e: ٰ߀H?%M7 *5Ŗ9rԭCE8qkiJk T.j>$ MRQ63lҹtƟ@_u[.4oF43tMZ7} +n%Bd * ـ1 6N2S?N@ׄ^r5]5J@e'i '̪`Մ;5AX Q= c.Hi| u|A JXh0# hj^`zEpa/%AxfL}x0GrGK%J6|/$2) s~#j6VK9̔L5x ِ.~/3 @p=y-twEhWn'7sVmq@wp /jm.T/z1E3P=/.Qp-陒uKu]RU-Zwu?'՟3ݬ?Qɗn9.o߷)Φ[~E_{X+uF6PZe3%+~+t%[^\R7}2Y}[T͞dS}I{έZ?9fﵹOƫ~1􃊩V+VrCݙt?>P&5˹p6UmX*P@Ú47~Wq#_͇X+Jѧ~oHYy[E5M砤Mw)6&m;|_}jJܗ]4 n(~1#>& T#amp6kxb(L`ߤϰ2iT_;r@*Tɲg/2ۀ ioR~;ҵ=Eߤ:,)k\fV,ѬM @qg5UEX2Hq[O}GxFdxU[4g}+9 o+@`3ݐޓ=ߥtnW;^ )֋ѿ z/nm#n#7=EVrwk !f.}o%igJBŶ#ؤJu.]7&5iن[FbmἁVI×[AMWZ7rhͱKRom+yc%uw)܎mj,+alM*o@ѷ_dBOCwm[Ih܇_d?5$ ]d×G׍_]^ŒXvڌ%+Hxg~oڻ}h75$ Aݷ1]V- 2!6lWt/hkOAiتnuȨ7& f"iVuUoa}Ix~t!AV[f9nu{ꕵϔ(5]+H|^wZ ^V~o`DZջIhzc*ś]CB\Qw=_,S=P~E}|4 gr|hG#`0]5rȟn0˅ͮ,EFPV{vϲޏb0uRO;C5iqH)lf_/y_KZ7j]UTE81!*4B%ӎcP/He,2lF+FȮh%]@nsRiF[q0h_Ix(О y+7A,3ن+\PqJmUߤkhǡU%qO9lkh5.xhЙv +qbi XzEל5Ƨb0i/~m%[fu$ ߤ!JhwWR욇d+y>`F_4~n}NOu[}V%o|S>:kYSU6ʭgJ\ӕtOn?8?GG84mevUզ('N}5F}'wr3ˏQ;}kֵӶJtҶn9^]|l]BlHڞAUH?\"禽ZVX5FR-Ϛl>ϭ#8HfARF&1>ǣԨ] eΏn~f/080fsg6v%u>.|vWDu&_֙a|+OTl ռ\M2Θ7-9,ǧ7WVCL$ \Z^\]߷]{[-O9ʫi%~zV*/{g&nF1,K,;P) 鰋޿-)9cAj>1 ,{'Vy[׿Zjs9MN!.nYbt|pZ L#J'jupƇ5i7bk ;x&%h}菧J[n{sf 'gW/LbI(GKKNe)Zi'bԲr%PCYLn1{iiX/=meRZOb-OqHɼZ>oϊ7s kk~^*nZK{ۜL^]Jgh~KG-V4[1)wXw"K11Nb9Fe$zUJvE66ޱill-Җشcxm L1(-_Ĕ4nO:P S[ݐR"P54S[X[x,3ʗ酓XM 9bc/F`'.zM#Spx6mVc}ym\<^&D4qĴxrڸYHl7j6gk:fI\ִ 1[.oJ@R,UǼc¦żlL*b*nqdhٓ6c__M\ۂ {`]meI/M;u 6&n 䋵i?%o_OAY olTxzٿq38C1֍_[p;l5Щ4 rk)OOۚ)zyP:3Q5RӭSNd)cr_xo=|faIʕG/e8 nCWdKX/w9_ך Y}uGDP]4?[X+b<qޯDQr%J{/d9iN%{yHspsn'K9/XjO!峏zsCyzKnյz͜-a}`LT,SτI Jqe s7=a}:c_Hx굲̆(68`u9Z׋זMvcޖ".SM{H T OL+oJGiH>^[j WG߉Q`A,Vx:4Gѭ،H-q}6x'V"Rܔ`49o.?X^ʟt-弝<~eTYH;2".c2ң8yo(3$7dHEc#S|"6% -#=Rޞ>Da遘;s+2:-F#XFQ3Yjb]zyi46g$cL \`S֥[ukըy{-=^\i^Ub_mx߲[~+G9:{䞖-) r݇Ϸ\m*_>q:Fɦls6[/(4yZYl} TN3iۯ Ø7\;g _. d@Bݽln{GTTɵ5,\ae\[9(>A<ɖ*Jr={VrYRQ}5:w>r5۱|=[{~\~r 6ِr^Is|V3<꭯mP|aJ:OXW堷.?.=Gh9߼گ9WI-~"|nn-KֻWn' 3tveʹsY<-OB6<#2*[2e ϭ'KR'& ^#.卷L3=|==dʨ>\s[MQR,#klXG}%]Xy>d6]ukI/A],]7&yd]4)*p᧋%slml (wbMWyU/WҥFtfnk꺏+C`L׍>@\X%kv^yRԊdqd)Zilv[??˭}!J'ѺRݲa餮36lm}ARB|ƒcحM2Kө@NV2vW~h$#)d$3scFWli7@p~tR5i<7] s^f3,9 [np /];]Sdk%:~&ݹ>_dۡgV~" )sx.pkUxI UU/Y%8Fxy#1K2N}+\T2~X{-3vHb#{qd9CYꍼI-dx:՜ eq?iΥL)I;i^ܛ^LX#GeNr/3D*$h'%rM|\}?j5i7k[b?,Kv]ǶEo]|7I+@w)\q^"Ԁ*VX>M@s@.y aB~;у+6ǘٺ6s0X,1~zB|NSA]#RRK$T ak%̱Ŏ1>}Qt?)V0Ǻ:ɊOke_JZe̹jݱr }-x%yogPےd[Q)KXn-:(ς핣Q~:X㖈78^EE}qspmi5IM;kIlB_ӡ&&8}\ jlP'd+%Y2 6CS4uS4ڃ<ҁX3m'ش bԦ>7I%س6qS%noXgn,yάi©׬p8b̐Ȧ"\rnZޱ71NA7Dv^#iӑ >M[#J 6%0R<[ᔺ>,pNe it v*e9M;%Iuo)0 K*IXmMwAQ ƻP)n Aj3M;{ڜn ߾;?bIJTU@nŔ]w"P,_İ Z!ĴŒ1'mx1D(: 9uHb{xfɩLn-Ϲ+qU­ /\u"[ا?i?gxq1=C6}7թ֤|!^7hc8$aqՇѻcMC,Ę ة9S9$…-9}7=xґw"E^ļ`/Jbr2 MaJҀ\%hQ<2~@>A <]ő6ur`iM" S)Bov{!3Rg$euc1(!LG w1':?g-%4I|C[[Lq~%gSLbox9`x=5DX7пNL|!&;Ս=nWK,'6 nM hwꆟK17"zK>C uJtY`񇡥pJjbKD+ǍJgG[J.B PˍVNiu|\1Ӹ^a,ܛKtVn&qVNYm?CbyX^"ʤzǜ~]PH<sa3qX΋LG`#-({q@zB:g1m/2켊ȴ尴gni@qȑ.G-_s8Η}!\>Vdq痃6LCa#O`7y>pyQk:}ktXoTV_nV4Z0NZnB.mS 4T;֎KNgKCSQCֈ{|6{im]ns#}sۍF+?ec7_w >v|މ[Y>ͭ#Nay=^Л9}Sҁxԯ\I݈k>/3wsx H/dӳi~; Qܲ'UgfXb]j0ZD2AbQL@Nqш\h\G!QK+?ƭWCU"̙rI$6j%TlJZl` Vl  CfT,d zH߿8FJRWڱu|M*^5Ѭ-@v'&"E,6"uftNVE6Iu 8lvGD%r?yIRӭ fZlUR`?霥UV$}\9mWLlG>7ҝ_J.n4a nmI8ٮ ߫,ĺ6"5+MYٳH rY!c}-J&2YUir$Csߥ&T+"A$Oy*@I5ىvdm,JeӋM~y Nc\2Il<pDNtG~h}6J:PZ1SH`uT2Hm>KeWTZew/Yx? G!4bbD.>X/0S!4C{i/0fÄ,VA $9XXcPؤIKMY zn@4Sщ>G?Ef")Xn{V!)ƈع]ǀw$Ƚ`d9$FKk֪L@8Dц'ҹHMmX]hoG6񌫔&N"z3yDX]zY~+K?q^x$#^ԓ%]"/bW%om^TZa3x.ͧ/}u^*,FoƽzrNOzCVe:V~rp%A3Ҽq,[#s:߯k鸵/Ti.BfJmNoSF}\0e#=y(_e=T<W( i㼵'F3u}kbR#Õ-76&t]?[BH_D{WaX?HB֢y|]emv\<ٍ񉿿F /^0;/37bl_IB,'5m/.ajd9ҏa="{?x1l'd8N'm{Q+Q/s߽wߴnib@:ƹj#QLbf^"[3/zgz[ b(ːi[9(4LoI$1%b~!6㌑iJ@b?ibn9.m`?ig0TN)X[u[LQ*:ϔhjVbD&P+xnہ6W(c(b%{C65~Ki7n⑿D5 !G=!Kd&Fg&kY8z!عZU muSb;4E3nȵX?%Β7Ȼĵap4gg2ovq0+pQ <:S1θQI$f{mfjLf M"Ӧ/[ˑ\Ŭ bvn v>zײ3R;[G4P/ G@i#\.Z秲_q,⿟ntzӶ?74hQyKh5L4-|W]A%X=%6y~ŗYXtyjTyLPaYIä'<*JL^!q>\AvQ땮z$XTy7z]z@b4K'] {#C1\6NԦ4i9\㻕r›ՠFҡ܋Z҇]tM7֭1IWi4'|l2 zc6@tcm >wo9(=75EH]6ienû ~52{;I:ElvXl$LlŏRGwԀ!-ZSolK M5nT-Ng;CkqN|**`[YAZ_5Q5;nKi*=ͅrm!yWi_U۳Z{v!25T4f#Qp?٤]-M]srG'|Pʀ4;w fߩ^dbws9pM+;!ErK,ց|ٮINS >JX5ZҭYx1!p*%62- w gCeV2 v].Xsd&!N;xXR,'vmsLgBN$`dԽ/%`0LwIB ċG(5k<6I+0߮y,z)@PP+ ZE}w:qބ]eݹP_KXn K\d`7]V]:HJg) rV@n>PӾ}fzm?d֪AUx.T/!3-6]6U2X]=>qA^mc/BL [G0aM Xnw_®mN ߐF%) 74 X )n6IjwRZ*--W(<!Y&Bq/5C27VuGJJog9+,$ Vbm5OyK=I)[׎xuȺ;6.^asfrH|pC.l8A{u K 4Ke D|F60o_[ N)1}A濑X^s[ׄX_%υkVtsHeճ ' s[|lwl+8Z^p(_>raxhh0li?cfEr )67Պ^BHwYVZuYOɯ]I]{c^}mW$!vRAIfpz:O1ijgs"i)h_,GSSI3ZsntǪ1OǂtyaXȚwMn^t%yx=e};Kl96`pcr]_=8jlUkU{sn.K WT|^ ?;x)XӱiiN@pcl8*^k Sgɡ8KvVfqG\ uCe=nurDvV,z:ZB\ϛ@5 S1q rBs0m훏úS;L3k+8NnAy(n} jd8 Qa{.eL{%&`⅋.Oah_);{}$Xĵ7qt }%) -yH/J ؛p #[dܒ>3q*bUαEY2Sa&; Rmk69^)J {ҺŊ%AZ7K-0` VBY?3^ȍS0'q=Vq\Z"#K‰ Hat2nXZKu"#7hq%1'bil?&v|Ărc ~w/CB 71 8 ]V6m1ɂzĄJM[䦍o6][-G=`ԹnÒK@ %T5NpPHuWMV*1p_Iz|/|ctbi6euo,!tiTeQǦM;ik ]pkLiVCx<v\? N˽i/!uNb따B1ʉHds[4bKtw1눋yb|xډ-E9V8шn"ۿM領/d{r$+ ( lͬE_Xs0Pݚ%m\bb#z;?#M {ߧ9bjmͱ-x^3|oO`򅛍bCIә Df[#"CU7,|`lJږ=h/8b͐f]L0S`v3?r7ń}a:ߞA-UN}^`ѧ/MR4s0I,.qݨ.ߙ/b\zhЪ{ '@B~!3ncw יtޙl?C<%uSn8˿ms<3md9^bdј ]X [hoY@bD׋Qk$!ݹSo\~1&z90s ĦG ޸(W}zi1-́s{abJ : IX2uΥuѩg @9VN4j[᢬S#shm|)&66.OYQ gA*N>k k-Q+Ul-' s%siI?#%~\o)8zwk6IH kDbuwڣ<)/#R]ňNbKuԢMӅMd7zFŨ{vH}+;3mw1tmkOV(yQ։t>Wޓͭ/?si]K!BsLI*|*+F{uЇq5.ámPt,1:uk^"]_XF~u=s]{}'OO96[햯iM;ڑh%4]o)mݍ|n@\Ӽn-Cuo縎)HX;7b}gp7zn.w" ^\<|Arap(ck[wP >K~Gա4I3K$@ ^0 r Bvn$dC$a-2e+kX5vE7AQ?˱ d(=6SF¨G6_8 ^ʻ%vunn摃.L:a=+ 2- 7; E^`xo@ yW %!7E,A/F#Td:E&[%U&x~2 ^:l_GR'ݸ\o]R@b.ͳKڼ{Ҫ;ԞUjO. Ͱ@6#")a\׾PufUG\ #A'z%E| >YF~J@Hc n1w)8v DjF6CɈQ,8`9b#I *{A8K&']'YJ7a J @v:4b Zv WD *OEϧ/ P.m\B:-i5XJpŠCpFh1":  hC%ޡ_Ra%nv t)ahM^C8{u@3ʑV$r& KFZL=K[qj|!.%#+tL(V*0ϐHE]B"lUP[jvu JcLFa2BނR.a=3ڑƭiGJ%'oۛM}nHS΄9HP*zu. `hp")IۜY=I̥ٞYހ°>Ve)@^ZSz^{BHV~+^B _0Hץ(G9 ͏Oi<;,PӅ{ K39ǘ^rɞn" hwBe;:Zkt)IaAjb[[;Mm.}3`IQ7[>3XI6@{N"zK,4x%w,*:C˔WHrn"%6)1Yβ޼^ʌ3ܕo9v\u;AǏiפwggKg =iaUp+79^<v5SBr!ԡ]EDҤ%`ϳS6{xb/DgDr2&O/(&™ֵ.vf%.۹PuLEL眛N:[޽ĉ+7+Phv\>$eh瑐yVAwݷFnqkcM:܎`e۶t+t>tF>rs,·"\JvcMǚF_aSZ5BُQ>_7>~b[H>EJaY}Ytks'%q.tRa:|9֝/Dؚxaj~t_XÄ6Sus]΁Kuܦ3uhp^vkFpᢙ,gssޖ~2GD'ҰqG!PT|/9;vzT}2]k([hipYa3ڧF[L҇^گK" <-K+j{W7f mZ`Bb]o2j5Vc z(8Ĵ|j#k9+Q|K[ӈLpw:۱aV7obfvLbisv ߊ" pqm9aq5/H0&Iڲst? u%&Y,P;PId%4#-݇i؇i4ǸnkZvK5mB Ήrb{P:?O"l& Sn7d;3PBK:N A}Ӧ|"Po5QW;Bi¥Mpbuc,A pN\)L2זiQ j@1drZ|IX~fQ۲SF%m"-s>:XL"c^JH gJ݂/dfYc mr`- 8cLHGxۀ$67/jVS{R͟)Lm(^uroS5z4\s1#yjs$U)>5h-7ABOñaDqW8eC{|71JQ4ysˍ()x'ūj 9?h)N2e:A~m.rM!?7dx~~!@ ǔ7Ǵyk8אR 2}qEEMӬi5'\\ӽ1s0CzjL?Ɛ%V@)* :yI1&K?:+2אy^.qn(* J?xmCE|9,U7Ef`mf,(x /^qq,KvdS8%GXGQvPGE~d(\VQ$~9(s a ']o =bM)6qk,֥=HT:⡝5Ե8_ L2Bl\cic U.sIk;|ް iXZgY]PWm~9l^R̠VZ/ugJ +0uZ,`J%۰z20y%J&iE!WmzU05BD&UO=NSjG)|}{a1'(+\@]H@/.wg JX/E/P?LBe@$3!% ]*}*') 8u! JՕmՋ4rVю mRY5)%t./gS_G>AH Fl?Lڎz$gҵ4#JӴC$^/Tpp?`AjC,g:8 )?B1ENgBKIW '$B`* @]=û ק\U8Cs:4 `ҵ_ ՀPdr֏W $Xy;V&I6wNRa 2ڕzlu*9ڴw=`I0 ~!f:ͫ,о4[!t7Yt Cw߈%uOlV3s;êu׽8m|B KYI[O0ɟ9^8'_닶m^.o6b8\QV)eL63%mgp/D)}׉t_r)->guPKcxDjUL}mN玓[5c8ҋr"_gp n'Ih0XHΣ1_-{@3SxHPn8/s#5as58wu% i]eG5L&rƞ;?Y-9{2{v+'NVM>h^&g#w+ kqHtVB0sI/Q}_M?mAwwmlH687xP|}[z}nglpu{ O(mѷZGbI4`tńđchQ٠I\\>f[,k8oQrQHq)a.{Jlx8.#s;qWz^(kUl"+\[n[q&ōݍbsoD s+-QcX{Q7vw^:? ׭I3/ G7 7za:fsSBp[%Kb{PO /_pclC fƨH*qVxҎG4ǩ/5p>Lׁ#}Ld9s"PE]s| eG0`2D0@6OXqBd6PKJͱ2G-{%"Hgvǹ{&P=0n 4F%>ML7*({{˩pT0Inbic[KZSij9Si/bT-m@.qӞ[n*1M 44&¢؈!ku->Eaߵ%f7x/[И݄ufziNl[BGZ+YLDETCògMC65F^wADE?%B־KTRhkk$sx۱؃X_@JR64|'Hc*Ny'?{5$hfE"1^0Ӛ9΢vf64$_bX{$݂ya~c(\ Is?&T8SoF6kFƜ%[Lu Gt 35kxٖK+婑%.y9qhüc8=S,.(iT9 }{AypϜ8/{DGK)ٗtf3[%g_s <жqLpBgևLn^:\7v> Lmg}F&7/k\8?Z=|ksنcz˚3-";萸Y% q^:?1FXX1t~ q8ӒپN%g&~k\*'alY{oǁanj{J+9TSzQ{\U4TmpvJ9kC|W3֥=P+68,}[PFߖuv,FpվJڔ6U3Z>u=뵓f*cȇ<Ӥ+) p-"책.C+ei}\8}O<F12r7DqKQ*YTr)6JxKZyCG(a>"IqOьeeN-7ZcL>{ \?A[C[;sPt״8g~Hf(̎zYiH\DZDչ(&Ѳw#ib=7qh5&x&iܑǶ;]AB[XT1,DSEol!I@ F33 FK>c8t9N3`SIbtWGH^KlZ )xpY]@[}6 0Ȱ0FIɰ4&3'G?"3/Jm|kLaQŀS*t֔-,8Icl_=o I@z>K tJ.ϭ"3͖ѿMC^]dHaX[[E Y%AƗOzîAv~)@yCZ"Q agb)HeL2zULC4Q|@j3w"yUG:m}Lt9:dZs*̮3gxdE-kn" v_H-2*%J&B=J^s:RzW;1 EUJ{Z4j^FY13 %kRC W妩dҜ%9e6I @&.|kӝ#AY]X٧] %ƗHʗFc@6j!*ʮoD6~6{Φ8^P*g}XIfzA75~mZlìs3炭u5-GF^򋍭 pDZ}FFͺ"aڏhݙF|@Z1rz|ThlfKopAi~sH8fnU#,9KͮPZK6'z{Lg)ixI9# 2deϯ%솳NDK /.VG8A,~, v 3ް>W)sl~,]$hÚCKUk3z̠9ʠ3!Iu3pˑ '(C6}eqY9GE_廤r`!~I E?9B.QW@Ry,:&3~m\`Fۺߎ+\.wݕR{tsz|vt\^[[)3xE+u-[ԃƊ~["VtLuW&%l%K׼ࠟ̓1~~ME~ؒ{eA/,r}c¨ֹ,r)I: K tve>$=toD#z$Cl7i b)ʱv 'uGdu=:{owg6?ά1wVDo(%u7BWxydioR"!9.|(f1q8_+B5Qы] V[ {'޷X0>|">6n9T^v֩ZMWo31D}mQUk)DxqNuġ8Dq+}O qm<~U;skLLȠSo\:MZ\4@Έb(n:!Ty,z69|S̏}صU ihM\afZ2- Qu\ŠeMEA.o}ȿ#VS\F+aN/CǚҲ}/[M\uS_[mі(~ֽc~{ZiYqϻآΣ\WZXrY+XhKq>N!XnR!1S,Ch@i^ƽ8-! )[1:v1vG6o "sFɴ#!Ya3$5 F̰x/4qÀe[H6|4@]ڀ}+ܘ@dXuC7tuxCᮽբzĪ u41_7C֫TmצV&ä?5KcRG ~6Nڌ's$ssM,s@:޴yݰrPoofhE?h:0F'1NX# E]@kŻ ƛv"[.ni'6략NlAm#`NA6uZ8MtĉEcz|i$g tN9EN{ i(1)-!!/keЯLQްimNDPhyNbn c:98>lj4E5,%ugIN:`-&kAV"1cSIM 8bւ y}%*_T^it4mbp|{ni#GՐH^u#u:6k,ָ 6o4d5isӰwC8[CNM{P\޿"Rdm~9Knb  '9D{ͦZ&p;- s(8mJ`;#_r,4R7&9#pBR5Kh='=a#~d6L:, MQ~Wz~߉,7zyi>!h9]dLF, F#{,NVuiMuk1.m=,hB>eȹ68w'JhB]WlKlk1iz9nyJ1aSBuT<^˽ 9t9ɣ8&rWUo8bx/bl-CiO箔"_zp)+Odu)\iYo55yu.o%c^'VݎGf&nX!OɥP>#ս'tn>iM4JǾY"4K9ou+]eYW_u<ȯ_9n^_l'&gwm~+ מu3q֜}^S!6r+  a-Yr](۶w<~9` ג"+ݏijkh4H es*=-!k<ǤRoZ4 G.2 x,!S֎[h_ZvoaP&m:%oFyoW&A>c`anT)lw-ũ06> !^o`n-F}lB0#!j,zBsq@^+gچR0w 02(zF>z N!Q 8uN%+<͔P q'd@?sE:ABI*4F݊:E(Wp|CsҍrHw,:ܧ'ܬϒ_ThvڳISu)9NX}aTޘ*9U@ՕǑq[uX <㤷LmT^bVBEXh%#Cs.TK3dĤMQ0ClRvj>[ɵS̞"dlJ鳮`&c$>IJRtaPk2n3`*DV/9Z`?riFS59` qn@ѯkon֪t #]xZ3tґhRB4#GrrK@ c~d# b6Ri,c*E< pmd`z3j 55 %t P%UJVXvlJn6? P4! 9dC%K,G}+ z/]NQ/Iu! azIKsJd-4 yKawV)$|zЁ֓0)Z &zLM(QNa&*JQ,n^cj"J/Dm~[чydBoP/)s0cʍ41ɄI;!4pΡt; *K]+K-Fiɢr(-Y8Zb ڏjɘlI/T`9f҅JJJm}t"UtΑNA^J#)$-GvU-Ǭj31J H v$}N HIb)JJkP` tZ/$`](nj#SU<Ä:~Nl%?][%㡒sNT!״SBJ D0Ǩ&]Do^ąxpሢVGP5q2)$I c}^nG! SP@Մ΀{Nz-zJ G`Ĝ p2ѮHZu=)N^{(op&\20Hzنί=s+-tDIcJiq/Õ>09)!WߎÏ~atrİ$SR]}/b5aͼx~˶Z9ya796cuXW|{!ͫ#,l^MZoEuȸ" [R86~n3΄QʱL=oׇjuAT0ӣjSK.^%NHqއ={Kwڏ[ 1w['}v297K&&i^UVrmƮ:Σ[ iްQ汴1[C?FeV9,km<|ޜ@ mbVXl5[79 r[e Q|BWWlsd簍`\/k,qOb~r'sأ^n}层 yX{޳E\|SgOLD 8mIT$co=&DX"J}o6@v-D#AlUwں%HX|) .X8 n- ekH Et9 {[O}THu9Id9jo=UxƹTE-qSЇرucIxy g;/h[9Y!{3 woVu9?Kf$ɠf؄_xnp ^ʦ@ϩmkD1ִI"Q9-F6hkmXcB=0gmdJ]B"LD ; bVz k~@XR/VHņV[`LV lm\aD/b;Ug.`I:q&N޵!4ʤc 򔑀+ui=7mZ -.M]j54LK.9F"r ر5En@[v{*1Sin,j9&̈*EXٶz$Fn8)\b.JfaL6C_пxkp%#~_*"$IÒ9g4@d`~$ZĸYយb鏵 p 4i ߍM{Òfb*946//}-yt c.% ]"gsK9 ;p:u?  s,8jy|\eFcg&m'.2d~.\w"# G j?z"16 YbS gz:ѵxx.|D[G9YN]xmڨɏ7TT{/i׵شih%tҴTw4oB84T@,b40RB5Ӆ3|l dw/m2gw.$6/j>uH@4w~6pÍ삀i^iR;\3ٹDZOo&^1]M<{QB-7/0ro+\˞1l vp=ϦinVE==o)}TےH]<< φ 1!֞n ώLG5~6 xB+PhW&w_5WGfɽ񳗽ڍ.a^_X4Jp,J.(),VU:-:l(lTzgm@&X\ʟnʟ 9 w~5}gc 5v[ 疛SotvcȐ"aHA>lqkXmV,Bb8Hz;eغR񳁽=.qZjfNĶ6gc >n!_bYz{bMѨ+c[h^>Ōi'⨦Ūܗ+>ǜ-eȥk[PZHm\0 m"dC̙b5ey;}KsRQ;E;Ui\Zg!/D3cأhvK*B6I I4!n<}r8" \ c`CV x<恸SbSP ұ1LU"Y=67GOG\Qsl[P78x̉㺜T7!d9GE7qF{%;:3rMkQSZ\/ҍ]E-=v {g8u瑱@dt" u=ŀ/eLcډVفH$7)k*G9"$^)0_Xb"((z8uzdf2)+*pfb3MZH#%gbZEve (?Kl2s)VRX\}LW4HJL;zDے[bIrR`=u*& 2pJ&0Ls$dSc`g3]*Bvnbdb![K6Ih|EqS?'MlIuް6/ıNq=i=)@1(2D6)7\v"2IH{_MLܣ6tgl[lO t@Dr@4/u$T?=ڰd55[,MH>+lD3@6W)}e H[ekQ׾&3{_P/~+67LL璁 lwg'C^2S}- ~$)Pc _=ڏҥY\UL +gp@E0MJ?>#RcQH{۾ՏHUD3zSM?ھ*4clijK];*N[j^(\%O^^RoӵjHǰ6z>g_(Ktэ`U=mt혷ekaT7p:otm LnZ)v0z1JYN8qkӱLKgu4EXU׾23C~e.0QZړvv"X-G챸ъk]<[GB|[^x|opY1ך?租[-z Wr|klR-|=jXq2/cҖc/GΩwin~DΑp76gъK(uN Sٷ,tmەKL],Jtm ;ľBotm8KSW.1ݺmڢk cѰh4kS}c٪%KLD3ѵ39[qoui 7vP838عlЮ.^ZHkS`ex kk*&s86F%?ѵ(D^"{>,QԳUftmDQ{`D5d"-DߐJ FյMȸt4Q\ɠyaGm%<% mdX@" €5StvE2PlڂJw@l1 M3;a91lHѢ 6.}dLDBmS2&M4{؇U1-=mPbGi\HYbu m+A_ņ4kbښٹ`o:岭*66i M,<>!wT8U8rEU89M0vup<>q"4k[ 4~QiT;UߍwA;~qrT;AæL%iFmg#pr& bFԣ6r659ap&$;x|IUYnb7&5TcD'F&~悫>FdoYlC"6[ۚ~Սp&os~߼{ڶ><,E e@dp^{րv2|,&=m~z 󴶀!";5VݘHѶI$18[p1K"b#:Fuۂƿ53l_ 4KĀjG4?Ǧ}M5m䂛/n`c ns55"zشoi8KlH(ymѩViqrLt2TwoȿEe@_ GژYK-gqfKM~!۽!Heg:MLvn?2SHic ot|h:Z?(+RW+\y&,kIdkfq_rk~sd`[|%:/ő#,@/>oK9sb.(6Kbw9ֵK qtMd3ajеi~3e4Cg-$v'VTcŗ>L>sw{ER!;9w? <]'owyg+ڱdN)'20bFZH [wv= zՈ*0b'[ފc%Wii1vS4<ġԃcouQCƥWr j_]< [>JV-ڳ˺/EI4qdbˮ2Fϔ=׾@_dR Ի4׋K6'.đ7;Q ʤ8ƒy@7fjm&)Z^^$_R+yx$uAod`v[V2b!AOIWqNU̾G޷J&)ͰUyMULVcvAUubZO9ScLRhp~&1!F FT#j3eqf/NRkLvKb_d^T]W#θn17k+5d[ޠT ^d&C/z^vk3r ]QfK6luʚ@V(ʣ{XhR.ʉZpr mpz>#Q)N:j!',C]4Sh{̉qv>%d[0@|o+aR=߬!GŤr)+iX_ȞAJc qS?ӄfUG?s<ܹ$/B?7mjZږK{+mܟt̸˲F`֦SRmib\gZ+ƙ&cp̓)AO $ٚENZ`%gJ߈!-[̵IИa{뺍g1Shm!d<>!fa&t0b!/cV8Q,{2 RPOblյbcLFڣ(61IJM62p C רMX5.W ;DX8MEĕJbh -9Y*t?I搩l-9]m\R] #fk_M{T nĎ#HQE[k*.XsF0{ ELOmV&b9 DlBrfF&iz {E~M,D A|>(~Z Kd2;RHUG1^34:3ֵs2Y* 1ߋ[aHT%r0Z<#H/Hd 2ho"H[mD`©c/{qB>kE,Km[Vr[}\;y ܴiS^/y}A1 t4̔+1NO |`ۏDikS?CUl:ݿj1 bM8ҾK8{zEUqXakyX Kd[s:;ĺfBϩ z?¼cL~"癜0321[cθ.nAb`3r$B32tmZNyil/ִuZw]+a\-2[e+cSZ^ sG` 76q}:;R&a;w--1!5 8sMa桽rڽDgc3{Ӥ \z e;CaZ Ĉ}bV"1uo𣬔}zNA E\N~s\[Ojg\=W; M9Q b8:!{*Mi@@ɗ 49X!ŽmZr9봷 !eLq 4~4{?u8/6! 3guiCR-)"G~npX0%jh$Ait&賂R<f,6t~0c(8d(p :9{^'(J mk Q* [AGP,\ۂޗ@= :y}ZbYP7XYGBpJt0LjBE4 XjqK%#?m \wskL$-?˲qg2$-pj;+PXb\Pd,LgzϸlmɒےyhGZy[lq={8CQ'qvk0>{ܶn BFVݸR*󺧀4@c; Ȟ+B)Wz\$ +2S'vA͚I8ow]!  mP$Iǩ[o 6(:X 'erڠn9F5mmЯPu9-vֻ>[ۨ_Fv[007b$ s"k!젡Pۈ"!)+(I4lJ fõV :vYfRzkBҌf _d@ap/o= ϶/,w5MRbDNHhb_jr ve ,H(yI'6YK} bN⯁ | k,G2>@ c qH!\ hfvU)wmנ_%gtJ-%8rd\ KO$i*#7`Oy#\Wp(H ,@]R*YH,5)©UVlCmT.*6T%YgQӽl%kuJ6#Q@pY g`>I`d脥Nn,9,QZGо)f:Cjn1^2qC/@`n")4hvC񬂻F^$E4ҮPʤ|{R|vIޕy埳}) yK*9(+Ӝz -%=I: <8]<ҙ/>}s6lg m݊ۇ(1XOl8v@%^ z[Ƕ ]cH;8`Q,#/ҕco{#V[h4bK,u \EP PYzP;v+~{oL1@2BᶘI㈓Ikq|?gw._qYF,(D n{ -ׂbE3'sPpC6r N Er9e3r5OTSqz"]mmM+8Ǔނ)֣sCd El!z&RT%LٚHPɡ*j;0ư3F "8\1"233fޣml-4\ob;^fa-71u*h9!Xbk>Z疙6軘8PˈqӈlM[`} nZ4bP>fsZ[bn@Mw{*o֢^#ƫ}KL1F"2|iok 29kI[X3[ )(mCwS P7*NY@y9;bb'!`MqigmN;k9& !-D41p%!>~7N;dۀMRJ,m$h}Hvvw1e"1;ӻɐ`dJ^Qly`$MCm* g#ۙ|kh봦 X?oqs^ nyZ6 m [ JMha9fPL?r#u\Ƅg%(V7bK/PiՍ[i B6v>@xm|V)inb4t 4[lr0<-T깢3sB(97 S-u8ҐX1Ӧ][- R͠ȏ3 &^ ƞ\g;n> -dkDg~sw4IR$66lةPӀ޴3Vw.V8,o`p`wr$үXx84K %妽\OI~-_!NQKư> [syjdic&,h%-u^*i@9M hޜi]Pahy[m~EywLDwnI(:?omn&^J\A}C\ n\ZcqI?Yޭc,=ڒLh)Dc[;1혆 $x]-ŀW;rdO wrRLgf1\;o~i;U2lqR@ƥ0lW5φ&^cߋ0L7bޭG H[~G^JlޭgY3'%H:%\. <6҆I:z1v[EZX ZP.5 ր_Ku%1 WC bv:h75Uh%"PYI*t!z `4Z2(jW1ޔT1c]=3u8őa&ϸ|f([$WiX$P\1R 0 #qCA-$4Ʃ{[[. )Ө]jo5L5^ S®J9'wrN ;TWl1V0JVx Sؒ0ׇ: 0> oYƭw(w"Cȯ|g|45N<'CMCHg@hjv `1t"'=ipGe9 AKQPFcKP*NMɅq!=MJxg3n@8V/뫨͖%)J5&SYVWmJ԰Ͳj*y =`Ґr%1rcFa4l39{(J X %Li@tA Uʒ4ճn#?_ 9SW ]MđIB\?3Pb*<"tr ^J"/Rk dA`[6͌"5v t_Xr<ڌҌ=,@z_##{u(*v%/b&ab'_Ow{5Vg$\Qf9Oac?V*V/HAVo|I@i3͈n T[}Oɉ,5krV-Ҿ"J侖,5Ic4}%կE^7"_K.:'Ii9Q|J~~Y jB[d(ْ'2;4޾3?)UxG)> h{roN.ɛxYl{"+ToQ'DZU1NE99֖qkiH.QDGI3d 5O{L[@i/+ rju%on&WIQn|ՇJ~Pvu8@ԭ] ^p˰-zYy_ܻiisuΑnWO (@Ԧw*}:.4u<@6M?c^/w]FاsiFXeojҝb[ﱸWƊ)qiq5NN8 9Nq;Jn ?7T DCN!63\W7n?~:[\M nM%dZ:GCn׶V2eBnvKCY˺6 \m.uvYMŁ`nVl6tCJoKs Sw[::W#V]L{]$I8k\8^n0._uA5[qN ~A羷lA%Qgg yN{aϩZ0@iKs Dm[W "eH +rarcl[_=rh D-?:jۀƑ{nl~S14[Q-X{q$DΖ@uM@~9"k"M+-8R=L6 }]LQ" ::^!KƘyTBX>ǍNz{bTcLF7*wQZj &鳶Ⓣ GbhkTu \K"M"tMu#G 4!BibbPDTWk,&mAuJIjUx^xLKо3UvsT E߭7"ԔﮭQ;]؛NGIl9rLւ<8XpGx: }F1u׭m wS˩nnc&D=F6_Ą56k!0jnTt/%&mJ`]\[LPd\4Ls+nІ9]iLaZ4  G7A Lb-Ūgm/Zr$BN51Y$Ap#~!BL=2c4K$;7Ҿ~q'"N9dD޸htob.^bh&ۦ:;jzl'. .u C5IՁ+m: x0y\"j 7&GRIKtPKhp0&I3E|>d)S2E%c""G5p;3I Ŵ:=0hߍmε}=Ν[  aݒ?#~́EJevnb-Ҷ2M"Ҷƴ%4e6Eݨ[p~ ! `b ɻ)8U\pxc-MBӀ͎Ll1ks:36=֢8;t휶4Eӆiz.m\rc֮O;vADŽGy. cmba)eZb\XkO:wLrW K@M9s:k 7ʵȔ:Fti~rhӞQ<7 L3Dr4#( R۲DŽ1n֗ij&&w?[GҴ9 ibUI/öy 6W>/|S~W5U4`gKC\ 8.b!ކ5%WZۋv&7N[l*|^#D7_^ض = Ȱpۍj:R^A0*>`m&.8glA |t\nlO=?oD-hcazo8V;/\ۋ1snqe3ADk. $ agLb`'&za+fw 8ژ +z_A޾ʟ^v>s˜(Z&ʻ:n*;]j<Cb٠g~^WAZkMSB8Wz98 b9/0ar-ÔkhC$ᘆ~%cL ELn/) P1.U\w i)21ӖБ΁E 2D6@mIAnpCRAaC=H+(iuI[JaR?_c!i$";) 7{`t`9Ȗ!"[)ݙ;՞-\Q^@'x mJwx*Uf*0 !S m!s`#3 ƂU hPl9}Z=™*`L#klk+d`kSrZEkAIk 3ǒiEXvJzSVx#AJ >lm%"0K)GgU)-TЄ Pa\Z7,9+βlbC/X1a L@ib +pڬzySnZegz)!_te9&g`S2uiO4T/L h#!SH/- IFxt& Xz@!E^<ɐ% U/G.d8}!JFF>WF@LB=g T2 1"3fya> ^KBɈm'AdՋ]*D|AOU K7ڗK^ս 9&@)EkA*pXLv5φ%rZUl YugRxG6ՙ.̅V0t'TRYS0LXABd;a'MqĈ3ŒARB%%$꒔pQ/zkoE(*c )'?" .zieW&IC kꂔNn$V]d8FVoեD=߁U2du3nےߤPv,mJ@c= ?A|7(чҚFql$Hk_QjOЙn9 Z8`uV2#l#TUF__I+Vx.R[E{%Z@i7(͉_Elϲv%|֒%M .97kIBљa!e@dOHQ:p [ueܛ3,VxmG|t4~ ߷ci_\wDsMgׁކtSB)gJ؁>8.bqT/zk~l&t^;ͅsixGǷklW7Jd_&JV[Wg)QI>dj=mݗxo7q\.Ѳan#t~ԃA%O1x^㹭sm(~LCoC1yW1pӚ Ś$XyW3pybh@-\- x[d9b幉m0v(GqbF$n o/9W: `OSm(JǂxҐihͬis1S@4υm(P_ߝ4˔=M/SSq8|;$ #q ~ⶱP#e·m`cZj×D!㜚5v(6˰[+v]z|$3M~4b&S\69獉:bbC&>L"\"C2bߚËzHS7A~W1co1d@c" GS6l&虃1;P(-C-Fhh~S`zG<b9~A#EQߋ mgdUAjw`/lKfJ|61 <*%&b"4F)z"1!߮kD465l F(1V7%6A$~kZϑm76 _8/;>@恅#]'D0mw[n8e&^bCyɴ+iu@Fz ahktDkFSTro}sPkۦ ߌ6m2d9)r˿sl9n;ZwөĎ {6&u*BgnbDFL @Rs]ՆKJuUFfV3h#Y{rJ_iD9PnD֜n@[F 2:Mc9ԭi/aMn0+ƽ|lG4x6&SF;G5|lgwY"2ߙ6 ,a;;s}4u˧=ʳdp>͒? OqʔWIqo-4 Gޝ] CvMeNUحޢ?.u['hcW]cCI pn ihj9,1@S"/نxгǙknJLhUjQǼ_IS}l8O% ^^Q8֩R@at%g yVZXcO? EOV qW]c`NVHks\b^dɝ;W(PӷIzޮHUjQ;>PC{۷Ka͇by<$DmF6Vە&ì"X?;0pQ TXR'鹭{k$ϴ% s{$JBeKCURg(o4KqGSbV y$Ct \#L|]fQؼFG7.Qp{uM*&fMjlJ5b0{+Xy@E7H6:QkO{7Vr:QJFۨ%. hxdę7@g5]`]) %/JI6{IHH~R.hHJQh5zIjkl>3`f_1%z&$ @ޠ1"ޝJ,!'kCU/Һ;vG2 M(tRt@B2Paڍdfw"YRT[?Y6cM{iIZRVou՞B%eHry=O5ٰ"Qt%E9Lo(UoLC=Q]L jIũ&4꽘fHVM }%)ZE+9\73Hڈlm./ﯙP3XD5)T~f\%)1GpKlm$ `9ĸI&5 oOFڜ^ko؎][߫O4xc?ucwr&58fiduB`KYmr;N69}3YNtZdp^pgFͺsNg~_{ePoo>kT܊7rW1|Y1@ G֒.~a>۴& AU%{KȱMbDzA5]9_0U *SK -eLܑgm~~˼gp#oc|=L֢^cE9R|㫯I$P.'=ӱ'_q.XrPr،Іs^"~inѠDT06Ŋ[*X ɐZ35WgZhe!b֦i$m/j&2ZM𗺁hj^Z*HY |A * HP33-UVxnQV=L.q.6,3lˇ#H{ WIfߍ$Giӭ{Щ4_>CdoMg҇=ZK[P\ќ>VT4bҐ`k0UӦjP=b8x+S]~td֪.1{U8NVs}@k*Lcj:Kfmz!jwәɴsB6;Qv(]sDK5b8X%{`z ~6X-GsP䳄 0hc] O&^Sq'^L+h.7pHb%[詗2zBKukѐa)8fkTmoM˽vJLXoߴpۍ 1Xss);iOv=#[?]p+dN=ΛC1ai\͟i.!؉ %eƥܙ㱭)[NqR9.D^ T!aÔZ81vt(~[9Π7.퓧i[Gvn=* [hbcg9LRx~Ow-ֻ[Z3<7f8yDŽɨ{[/7d{owf8 M.cig[+ĽyUуFL/nQ^X{f~J}/HLW7:Otf208cJs#`f<3ݤ7ZϨ>}n\IՁZ LƳє f/Rd~Ƃ؎tύP*6@3  VR.@yNI;(O8c#pmF‚w+B|P{跉 l%9t#Qѧ5`4$}W!huDhضdqGWqM~;mK~c0yKjW_!_sl`6iޕЪᘆ]$ݎykF߼:uە{84FE<a[ }ڛ)f$uK(8u8׾p;1^Z&[{uqF.o}H{j%VH/\.]TUr-P =v91mP3< c/f.G(zI٢\K~/ggL l?LcsnU`/7qsstxg=c{z Tɶv sɅ?e^ (5)B8ؤ?;<^tvP\8r=K gOuMb30kϡŸ:ܖa&e\+`݃3ܴ-ʍpkő{#=/HY#%.ֶ%CMo q؜n GNjTxÐ8 :M *p&K|uֶ(V $79<ǁX)ѻ ϥؿak;eo#cպ~˜<#xk;b" Hmyxgs^0J%Ҫq+ImDEy]s0jum78&[s,7 GNS0gU8ylMĕl6QnTbݮIf߭^©Sj:5g:R8i}#[H,!;29tM[M^> \[ LLm Lv0f;/)\ƗD=|/!\ktND u#1bR/,vq':%ɩbdݿM#fM#1i ٸۨ u%1Qy_oM{!(.Xf@LOXn$ޙ0E/fb81SQfQ(ِ6fQˑIr HL^}b{MLamεue"7*i8?>M]O6-6gaȝ`o"zMMB޵ ۋ#)mM㩇P6Ǡ[:P) fJ;̑V.md8^^ÝM^߿ݐ褉OAd|To$s)JE;6CuCA܅4Cm%p}Ly턧db]`zegQ㤳tɺ7!}>{o%64_xqJ|T=9'8C~\a{ Lq0r3oe~H>d@#_.r&qy]{ HX skzgP\> %rnLmw6ar#-P3oTGtv0Ҟـ"_Q;V龱r~%#SUci8G%c/ ş[|xͩPogUx,=m@:hq4} Xa 0݄X?}]P yVy2y9YR jVEyqty<$cMkH y9e6hXS>v-k?i>3l-fM{Ԓk7SzgR U_+ pk'yW2mrOkN 'ip@o@q%xGZk P^pǡ+B z=@AI*]}=>=&$A| J p% 3vԀĀk"`G;PքRha׌. $$gx?pkUJ3g]%sd},f/2l0ȟ44eMc<4%ߔ*#%D+*#ke9S$x3rPJ| o6Ť ?qԄ'&}a|nu{N' =hi7jH^糊u_倔Zs? AgHEx3 uLD6L >cW)9CvL@q(dvsI P2N#d%5-tiKJ)wqTkJ֞~Q۰3?!x!d9_KG$pnLpa[_*N (\2Π%) 7pmCv&A闺>ctF•*Z7`y )p| CmY,_$K6d8w {mhg_2lRJJg|zuDmp&z Z5{AUvzҰu6`/ )uRw=ϭh)8 oAB $&f(a_̏t s{9un|+7a uqԈ*'LRfG;_gP=g'22YvI?K#۵JrZ֙n9$}I\shMw*$ЋM"{ 02.+8T\x4;c@G]H|e5`ݗOo{AwZ{o50}ﲝ#2OE[fϐ2Z0r(ْQ``96uWjnJ]g~Z#ˉ ) F6K*/EXz[:Ncgw3$} \>6 uv69t%m>uW#74Ֆ ^Fyj6z)mpU|fQw[i4S٘pM>FD"Zlu5|d vdE%&4h3tR`;]v O5:36 ُgk#Qty$ޚ8^8SQ@S.y-R pYi(NtpW1j9P$E״i 6׍k ęɏTNnjMO1#Jdߍ5w(T4dDƍ0ꌏ'OaY,mx 1k# 3U1-QӦmނ b=Ū a/pj:!!؀umڠID`h!AˈBuc-^8"IHFRw7J'\ 7?I}!#H3E0%CsVHoć%nCV 7$2pu_4bHxwihM@yFSThƺ1;eH*Ӡ#Bkȇߦyidaro\zL컱44Ecex,&9Ԛ/>܉BX阓e8i`\:Ly7!}f. 1K2_ymw":Kn`0r o!!Oq8YQLK纜. @?g(m5y3h9z j*Bm2_?ox!ɯg[/H-¦}7}7wݶM80dk2%uHti>ߞxaMg*ڼcQ~@־嚭o5ɴcK[r8ώ2V99Ǚ;#=Jxtys̸_>zX٣8 {{ ~aI,V9y3w+yF Le`ns;[Lۜ~%sj[exM fsݎiN/E&ggG6Wij9Zw6B ~qbuѮ?磓SFUW Tݦ[jˋO0xkg q򘗡hڈN1w(!ܾ9( vѬMbM{q n95*KcZo9DJ!7UjDuSØn"=+ q=tEx!@\!׈5}vUcէXLVD#3a:a*Gfx KKoL qU-7n\LH#]^غf(龬pV˞H#)[){hiUYo32e_fxd}'V9'i|sH2Vt#nl߶ 0Ha?s݉s7G:g"_{~ۢʁ7/ cCNaaX9o~ݎqy^ԫ9sKSBDqȁl4qYLõGA KbO-Gk13 ~ n]z2m5xnG1(~i9#Q PovRyۉmkìpD4$HӹnkNZDpd~.Hb0ZiA<ՍT8q  67 /4nSݦIq~[^Zܩ>i@mdbԦN}wA~_>,Ć1:d#;/xxcmԷ}  I"N_ss6[p@ fnt¦Q̗oaHG;DV77a[0sD@ nT_D m-'װc|?_ |n[bgazaF& km6_ִۘTb__9IóEv "­јx} 6E$K4_~|{sݝwAl9RiĨSy$\X6s"݂;0&ayY`xsmV \l0soq)c6bS[-7_w8\ zn\g + _]4?=֎aAKajޑ͡fC? ۲=כ8bnC/#?T29c0iшnGw̰t/\!IJc8[_ sAl8rBcylQ֛%cXvYAf)xQU2M XrK~F*-/"-Ad{ M |qKI{I FI;M X h+ӭ̥5ېT}B u߮Tw+Ա,8u1)$5c+,0$fF{9H{K3֍wf؞Ieuec LPG)|/%mP,ZkN] s>c."S܎;\&}%/)}z]7Im՛qkk|@ @)_R٭']2)&" i^%<\ߤfId^v:q(YqZHˀt]L  6JL^} P?B >)F4lWT2|A<%%88kcs-]<Jp߷ Гjwv2vϞ΢qL][l$UgyBۄSzpd}f p'ӘC:0O 4I3ޒ~gr1Z_}]ZyGAY B0l\ X'/V~ߘڵz.gW,kfc2'yjY6RDg 6T>E)j\"YJE1NCni:;}m:}xdKAu\8 >Glw)_n4`9[<911nKaAhLZC؊4ZJ?gC97 2t6*$!Ym⯵yɃT1i{'k$j6m1qQk-mT3awNr#KҦSZP@;XI̔xd G3p=ǛҸ6iFxcLnЩ?榹0B©i<dZ#?h~)6*áӍ AH3[_uJL ]rqmg˟Yp DD#%pKYmlyFhq&Ή1ڴQ}Hj' Sݜr ouӇh[Lv",Fw{mJ\ Y|Te$zU;s'.Mc¹iT8%td,&<6=!ḱGqֶ4m8txIJ\Kqw>\k%H#pE6k޴I,3[p©i Jd L<^ϧ݀hȸ,bY|?S-h@tO3ޘ"9+cJi<=Qp%(tCԯpW&nˆxl_[coLjyHuk1MFlu\d-c&zvkfΐk'"IYO cs\S$I0m ӵۅ6Bt8zv&Z4D-q ָLݒ9g%EƺmO5"ltm KٮxetmH6q(+Ew t1ZJnHt̳];EehNj4]$vFpb۶yd Ǹrh$o4Ɯ=E VvT|0єsn#>];Mᐮ8+Jh:ˢs#UJqbeU 99%ԘQkotm*ȐH4+PEBɱ%o-'2wF-6KPUxÜWSTԾW@Q<1Q0ϪbL.r<~82T%DZ+mr,nH!g?h2n)Ic^UzZðR1+?Pb`[\~.qh[tϰOZفbTD0t<.JEVN[w(&@4σD%Z-2)TkP'HƅU-%H0,$cMJWJ뚣]"  [%HC^o^l̓6"]z \gӾhDz:⻱aEw $UV2 ē&k_h}cQco ;+5 m*hӏj`:Hy w}!SslOI7L !e)cM |t/gE63I&4%@5]LT3aK\+biD@FpmkgqprRIJx E]bR+) >+H|G"eB.cR> m.Lj+iZ2fbR.3P K\:" 4T~jIE(n5)YJF5Lc=,$,bNus3^ªB3E2">#ZU1'Ët?yv^7괙9$+H uxU-YV3ڏhUy&rq+'޲+Ցn:$sV!y_ WIƴ@t6{&΄{ʋ}D6G' ~6v}563jWTyʳ'2(|PHjOȤG9L:kzooz %Oǖ;t`<]2 ]9W NKmBӾ 4FgEi®ې)UϺȔݯ&m!#޽i\})yv49^r>`z':/J=#Ng:m 5GkH焹@m/"4ۀ4k_ zvE􋘯f tց刾 9^ػm"v Zs$jFlk];(ͶA./qV_ӑ]I쪞 ݮAI!^䌮 hO e8=3}_<%ziڦ3!2Ӵw9%kl7z:83C-=7| @bO-w_t6n< 3d8ӹNRetO/J6i=EeA{Kmiit? t={/9]@.mR)=)mT]jE>c2,>T`tZb$y1%i,y>&ҽ ih! Z]' PaXC&w\ن}WQkWSɮCt۝"ʼ:LqĐya8q,r |qm:t;5cUl)5r)7i n}a)e01=繍V@c!z|N=F_x@qii-hS'Y1+y.agvvY P,(⚣iDd'"+XPPySC56PD71Asⵉ)ތSn7#Ґ9(4%xKbb&M 5)mv^ńq9o_h#‰Kf\:[[uZx>nL{3ܩjn!uSpZ9ZwrBQbqiolLLp"룭i1qAԿ8/)J,nySY\L ڋ1y$&m(Y|~-~6Eځp7u*`Þ',mh Z.[,jSǛ;oi9{ I-K{iyq7Ⰾ_qm{b _+Đ1ݟkc .pڸns=eN),e9~^2,,#s0w61-CzX7g+ڻdɎض׊Aw&%bJ#@H+`"%>/L6}-qNT}k*'DCb^SX#Bɸ1uqg9ܸF{{=-]<rB$y<}هl޶#Qr§5jiLb8le_ٿݾxi=1y qYXm=Q o3urӲ,1g3O ;'ieꧠiGSsһiKuCI}Jr>V_y'1U7\;mqr cM\ѓ:6ر/ܴ妝X{aCbo$]]sfWw?wO![^Sb,\)ʢye8!EVpLg}dXoASVObgN)Z,LJR3lq{L\r,k?Z-?aAw#gءq? e?=b8b4N:wʼnPovIˉ×Am_>>ĕ.ѩ*o=2}W)7[nbbNZ6(;hEtm|K>ufp ~K6yFmq4TqۇA*$}xc78 Hƭ-acM"ϳ1UcM5g_']aWTV;EJdS;qOꃲ^7if|jmdv**8F &7 tRʶ̉%i\;#K1*D4=&WOaC_o%"HxbC,1ߡj_J2{cg4S}jFOklΐ z=)瓤 }76S "OXx YvC<]W|"Q9RaT{ž#Jc]BIYU.>R1 x[Dri*%=JE;ّȸ7Hפd5Ngtū>n+֭+ tGR/IEސؾUĺ%.IVK^?Fm4 ZE&%ngA巰UE[ h4׼nxV$ xav I#zӛӀdEh35] 1 O*J[&mA6M%L+ze9/R NtA>oZB!Fmg~V2_qrK`*JRI6]VQ&,m3- `5rLJb\5K647Md7=C&lF6I%[ (H`WhučmzjEj<[Z,X LC;`k3G[֓tr{b&6:)]S?]ѺA`þaicD3HdƩ9HJg~e)@8eGRF ,c d72gQ3sq=E}+˧儆woCsC-;˾[*dצpeXo9gSg"gLktMuor[cHoM04N_oَV' U :ߜ7?hh8plRIK9wky<w7cdBʌNyU#+ܶGna5SHJwާ(&ʖ֜֓ݙ2 SQކ@`7v.b1ݹ8?ݤMwKNFW%1gn*9~p@7R1K)ʹr+5r+^.˼[-?0 RzOϮsex-{ɚ8L~]4c'i5dיlu!7Wm(۱bϥzw6 7zr-kЉb?@}qɰ.! 979x1t; cO k?dk{*Qi]i\$^yVq5釵0=>3#s8tq4}%mq=Cu%ZnRClx} YMDoP)N?jҮ M>C<\muI+8n8Vf[cL4U13=@ҶB}zQp g-2+j(崌w,-︋0N/Ss̴eγDp/^Ct&Qq^rrmm7k?/G@!1g?y hn@-9o(#tE4Gv }AC9c+ /j`D@ <3"ߌLlV3:QnDmcE1'6[ᱛ}%6VjapBv:Uu7vsm?TQKxg:7߉z~cfqՆoLz,{R23H ~ 7wOE,U-5 av.%V^bb{˅;$;Xz61U7|M֍bD? (.~1ηF> ц""lHpS +8LGv,oDw~+\r!wC~/oI4#fhl&ޟi)i8 Dw)^HG8eAJu䐿ai=rRn!bZi&;q/ /v{ ԝǭ;-/hxA+\ 'P;p[[:XI+X_AOÞ%Nhfb;}79oNܸ'9'1g/ۜ \ֲKKCʋR}S#c\>d>i;Úyf.սWZK|di9wU tA_ Ⱥܻ-˺0|=jpr;!քZ^ݻIPrƐs3)Q{myѐL4s$;<~C35sO"F% !^C=~~r/Ñ rNH)1NGl!桏qDgX gۼ[ +N_8`&%TV]tVDy67=b~u^}F%y|FC;gHߚbyڇ}^IX_Ef׾K[ss*^uB1J{)iDP(/K4] rD.fVu˜YeTO-j$ <|_3Z /&Wr\!<,>HP8Zg[(sW=l}8[]`+]bn1;@i1 ^Gw,~|xAe@! poV2- BOI kB'̒;aMHI /ұ>)u=z%%llJqJ#j6Z@iL`IBחVcu[(m%''.ٕI3e}|eA} a(lCP;IUtC.A81 hW{&pu q+"نI kb {/`(%<>-IJiZ/) H*xNu ("]!MJx|R k]Jo,iX~>V.[ a;_g}1B !5$c Sل16]A!] I {V*j4˴nZɹd,X隰v~nRJzJ dZϧ ψ{Bx Mn14&B@i!a݀6#2Z<4p&L8bL#YzPGPs_ɧ4Fp{?J h )w Xfz%4(HoLj$(B)e9l0jCrU0dABgPaO!,0i)A~ ªbTj KVڭ9WM^igRosqz f p=)-JFl5F0WF,qU&U`Ez}Ui}[]*aiAiAk,V4qI /T֓[pfzmT/UZߴkNk~LK}Bs [cl?;H<8OCga'Kꉞnbi}|-2$۸z "#lyku8D{[1m,Q8Re9C> }jk3 &~Ȁc~i9`_xDȏ { '25k NUW3 ~aK#8 ^ꀅ܉tDbװpcک7:tfKu Psp(rd73oP]2d澑k 苌e:[fbjyu6d>/ ML?{Py;X'_۫vBn\~7KrU7njP/ddK!XlEi#V/8 2fr\M{2bz43@yі!c"d,i4 >A9| Qfb/0.)Iˀm8R1%_2_ńf8XG%/}EԈFVmA8 }@_aD/#|gCvY!L4]2b/I^0P ck 2z˥%0qeh=oi }Sҋe Q'fwm1i(tҜa$ > wq}κgLa%Ν!8JL\NshN{x4zKP9eiOQ#L 2q4*1SRci#9ϐvqzŜ8~m$f{+6}䕰W?/wa.̹9-19Cn/enp7m&'ޭV<rSy $m/U)tէh-,~Y8۶]@j0rY5 Fmv8;MG ~Rf̢r;p`ӚUy%tBN =. 58`H (N1B 819sc@q*9jO >\N/N{͏[1] W o( HX{$^R I bVM[[.=e7 eO`A4X ~9Aùsпù"5tCFg; aXJRx>, # k6 /#t(a UA 8$`R@bY 1)m;{s-6%g 6gB6l2/V$ڦr>JKO!d9ItU4cUBJJV U?SToMVIϒ Gͣ ]I~RYD˱V6>uUo r ( G3zP VTzaaƾ")}9 Wt{1Q\ Im%h! 5Vo+_DRX&iO1]ʤ v+ I  `T_侥8#/j*X RJb@{!x%/8̺ܓÔM7`nJҁ@ݤpFiN&E~N@'GgާTπ|J`p}b );'(kNRJAR\t UNM@RCJ@I*1ds2b2Kc_`|%]io~~?PB> PI)GNGRJ@wڻ[t_^↑*Oq fGz3oL fIw P<\}Ϻ_z:ݥ+P|*GoudC (uO4Z mhKWM0zxz Pn\@4~i.9|ӌ*:x+b2L78;+t{HCIp#gX'ߗ!La:}>B-.^ʺĢ"Unm<Ķp _2tV53vlKyU;QU9ZZ-&ߓ]/ǚT}|[\Cx'B Xu0.e~sJbRbوx_44$uz,^zf枉墟>G?ǐ|5LuPe~Idm4di/y-p۵ilg5-`9ĨM\n$6*X(^11}'Y,F2j#XҲT~!XoB47-4bꄵcyTG*3d<{gl+VHa#qQ4о)w A:& n1ji@(Fk!9YCj!i[Ō3), 38Q M|g39*k!R Y¹׀nMCp'P_ڗYi42o 'Bm@A분_dȄRvV8o_xε鏹ȈH @M,ȧ~~Agfh_|?h !Mh|~L}46sALpʚGpʪb,τi+ɽfLy5:aBsPf+Bms2K巺/og [4>iU|5sY)q!y$_L3'>EmB ?/U`%3Ǖh/Z*GR{feHįW 6N3 rP# [`HhD\9Սyk-h-i6&F:uö4mÊpuhEL'nډ\\PV`u3 YR}g-m\4MLmHrdKp{Ԗ)iߍ ^Ⱦ'My_CD֖>xCᾮIL"j6.InA1q?px8g^\2h?$Va  mcN~R[c|Lȷ樄ٻO8|+ȴ}JގyKz#coRYy=2-= } KƤ58|—duB_ʰ-բ 2|A]X3wuPmըiIC(.d834Urク:!C,=?2/}c3ü\(c^nԊIUxr{S,úc>btkv8!EO~?8("ު8+Iۈ=Px]n]M&fQ\i]zq/<}7dVj"qH~M@_S??>QiEW8P k8J.2k~W2FoGj n}DiǢxpU# ( o Ic'룇G3gIR1Ie7_l]vV\&&lCq%Աl=tq]SpQ9h99`&ÀnK{oUlc*x t06lUY[͋0*0Zzw"6/Vx:u4Z4܎¶[ 1) i))6Wwؘ IwHYy֪# !jޯ/<$j-_tSzi )/r7{CnY3KP:c2O7T9k8tL 8(y{F).Kr ȼ!vS>[Xy&:+y5`)=tP-xS,N+kLp~{ 'Z z2zeC%U=` >|j|)=\Jnq^*]|!~r ieIFǠ<@*+,%P "` _EuB 5$)[Ēq$PcK~D$25 Ipư6dkֆ%ޜNkh)^J0\ZP/(UB}L3J1] %0%J@~W`>FܬPA( xP[6@j ?@,fMMTϒh$I5 MI MgX*aX 0\*pN/H*]4x5 FФ1F(U .=ujR J>7QFz HSISPbbI x!B|"p&}+ê%9im'@>Cia͡QNgkp}zh t6(X_;#Y17dH%?t/n9#HOi<&a|DHbbe96C7G^NlUlW(nt_܍Y싔~/HW33֓K%A»!xJ;,L ^ݢAKՓp㤆MԸKnc/o(KF)! ݒ\[Iis#X7htlϱM i^fD{΢RÍu*JoԥJJs,ʷs/^$^\w/ `hW6S_!&g]#3yw~f$9 ~¯#nJz-YzY.8ID!>is{:I+̳P+9jymauKJVmE;5 =eiZj`y,]yj;$29x;RݿtU"UFYKrsm}!#\%eÊDPCq[T m>EVJotKP*qiJ)20j?BIUBv)j RW+bӖxw?V^|G5 ꖰƈGTVG eN6}٪>G¸љPɫ"X\|huIPsLt*8pzJ58IkP肽gX2 B1sYHT=>Zm8, .^ǰz cnYbULpj ̍U.yHC*P 6Әoeb@;\(sʜzP$@Q R IpKGm&!i5tu%ڳ*cسV<l&KmMHg'Bbԑog۴}}a$k`.L Wl3&j8-\'fz Kd=A\%x-?D&B{7L$dW;F36퍛-4_ 'h7V9 ƎiĈLxEmkiB%6ٚĆEϡS]Mk58hkh)M7y#]č)dۀƥZ^~ ́(djL |x7E㊜W|<-=o t`H^[M־a73y__ 6 a{ES݂4Cڄx6=b8Ř[ ';" y?+ Mƾ$FcÀEMsmjC1ro2& NmMúJb&C1M`%4r^St'k%">k!,n;U9KbN)X@H_X}6Cmly@9S o[09|-& F0Ȗ/b}P AĤ\#krsιA-IB}BcYRHlo%]4)t HǓd 9F)0ƋXS9X;sݞ G>nsPM2&hA@s,0׈%X킔&@;Y`t &%&Y{ y@D,Иp0ů ˲u>nwYwGΒ"NC'IbC {05B(E$/`2$ ѥ{ڠ^ryEiq9# (~IMlYy=i7(س[sJxm.xzÓȉ]]_L4Li>6.wyǾO#'嘦59K|,xbecqcMWcQ\@mzyӫEW*\ [˧a_ Z~\csCnyV\ޮpcW/Įi6$>LcW L{u8왋`e?[ǂ]Xfw[k6mw 4k¥]C,RRuOw 2rd—0&mƉl8qiv^1{ 'nYc*py8| 'NM#/p$)N!7g4yxڧ>ɂY{2&Vfg3 @ 5 #GJa G *s]zzWdpv̸~I}@2hеH96^8`4K"e6ך>EhM㼕>[eUᆜ1E*Kpc464O>ݕH!ROm| Ւx jC+5 l|CiMSthy;*_Nw|t8t[ZkJh| !X?3SMzGWqnT=|lkrnMz!̨Npś#bUcno>Gb6۽A1ߒ۝+|׍;NC"sWâ!rYsJRH"vhC|C}KY?$}.cC&OFW1s>k~ xxgŊM0񳉂,Z@,Ӊ6i&HԆD4IѨ;g# ;NDlW&FH@3 vJd_ՋJ?N?[4_*9eMLU5|CQzr+DFi^E8Q6ڥKmmҶ/dfKR=>1^_V g +I4)1ec~nRo(&M*",X\fuDl"M4k4 TcҶ®s_l9+KH%WvuG?ei۾(U&/znUӕV`G}~٤B'on yMiwץ^>y$(|}L7G,m lIeu߮iޤ@78֐߳F\I"m~"W(n;Yֺ 'Jڈҵ+1^֛O_6F/ [)1eBLw#G6)^*mRT:XIϲIC^INƗ2TXM nd{.O+ڜޯ.VϬR/d:#Q_!OXF#ta%)ꍻBW GR5 &헔kl!&Ym&:#-IjHDC[ۛTy`_i? #,Iwk/R,ЗA\g)%{wρt)uOӶ3Icٓn+S%K lԅ6t%z+Q6D'(YN; , 6Ku9_I*];536) V\gr,H>_!-tK/Ҝc-VsKNߋp\ #xbg$r"yaNW9<D"}ag@2' ه辏;sz$5d."npWw]𞃷r:Q4IxNm?AI ٖH :f_.'([&f9T:mjBwYfW]rgomp#87s ֎_xar2I!lrǵI)h*4t9ҍH7n ҟ4˞-͔&U.q8eS6ZN?-=uڍ aT̒N2{|N^Vptee[^4!21ne۸-yřeI򃊫qe98.7_btױ6߭h{KV˜zYCۤVQA:vY7Sjtֈ}xyewӺ!'J˘ޯFyR7UTǽ~XCt*hf6s XT 3M?uRi'*A\.1nCWUm?;:TM.ZNnﱉc0}{Θ3 հOfk׺Hkg Z9q]ޏ)M*\#!Y_ Fcyڌi9*o:. o98Uqbx".X^' Ʃ[`ײuA癿EEȣkzϡ2yA(UQDZѻեo/HZűNd %YW7ޘ {AS`8i1!Ċ["q||6Ax`ד|L>lѢ;+~MLB8.x&S}P&cAy99IbɺN.a:=NAQ:f50I +6vq2G{+wppV>C^߾*"A>.Ѵ)b)֑q{!kcLQKXrz,~`m[5{075{x[3,DB4 "1"ɐAb~S1-^ [(. q}˘İ0}葘#`K4+-OO{#Stm8ٚ 7\9F5f {8̄w&0h;@H&kXMCm~M31i#I8̤HRFN7wy >n[אu_rdd bfrfA\ۉ( 3 }Eظ4,w\^02M>ʛmFXOiVT -V,E#1_/4D-"n]{`M_uY h$̣-\4S4]z9n2EC6m\`s*T$i`\?Mc㆞d>i=&ԱD {㽰i=ݍ6-a61n1$@IGǡmoFD"%= .W4 Npdg"SE`Jbi'H7bs>$-m-[6?eka5C&DRq>G njN)?32/gޫXo ۼ:8Z0e-M=-OC~:qvieBߑCLH:zW#u ՋX?)N7qs6x3Cؚ &QPu}Chy Oඎ܉?ĭ>|CXq,ʷmj.&kY>$c2̘0B>a^}$QO<3n*n%\x)ƅ7 o31MfPD#W,UbtCsNJ湌G]ܼ=P:I~,'KN\'[iǙ$K]ݶʥ&TWaoQx*ќ*<?Uu˶5͢~!ϵ~}sҘm)9lc׎f1sI)XNk%z\;c#50es\U-&HҍA"Kzmc9 H5"ܴHmH̴Ƌ0:Dg?G }Xr ׁlu`=>Ic'|fhtݼٓ~bzrfD8 k:[#H&{~ LQܗ)\>k{vMmLfq\)cO1+'%µkmR|&׻bsa>CԎq_@?fhؽ2:[1.KsH~' EiI8m-&^#uK/- JLZ灨Ut3Eʥ@%VA_/!)M,ۀ12'$Ҍ332Ӆ}*\_%}zu[ɰ.,1,#QF-I&d9 ]#XK)ÂX 龭UUؤ}D^D 5Pcj_ 9'󐸲"9 \Yúa|Bv)5z3pEMhmN$JQ*]ĦÒ:6RnOtY%pU.ېՑX %.ڥV@)>hr ь3'JR^\Q*ǒϜil(z$T$EC"E(&KfH~9ȴ|E&sVJo١HLbZf;S~ȄIJF>sP:[eygw:(T#9l@t*x>A!iYJN8}k}d4FDC%N2XV̍dNtP̡'lR |Z 6LVBɲX_Ŷ-dȱ`utR/|},N+(\?4϶>ȱJ&m9B^Lc_\ڿo"j3YY;)ʎ(2ϻ!]I9u_#ӛYW/mۻ7eKʴ~.N sqINg*>mWG:߁rWmy,q+v\?pjH|}L ,w- {jaik*iFqwb[L.Kx XjOCRmlu8oZ{m8SXӥ;9A\dkѹe~scoW':C!ΟtAzK0E_WX_o2_w ;+<-&pMy-In=^,:{i5sJѴX43d-:t3Tq/V4#z,䗑6b[Xg qQ*Eq,UьW`p6%ziGl݀ ~9'eNtv 6PBEp"5a[/u4DDwU f` 0Ft7+~=qG:(bۉUTè|k(+4L@Xb'-5 ,#v7(-3„j춗Hi/1:;qq07N9sӥi/b7;Z01{I W`^bz v`ӈ!OMCY[1ŵn*릝8KZ\l>JmJRi^OYӀT pa ڐpzH)̀1(9 E<$'X*⋶3nMܛ6$8Ǥm+U8m#m1Ӏ{3y02?1 Rpq0p)<s.$m:0ߵ[DoK[7hVڄ5w& 23n:#BTCuA6'mh}4b^~F7j5\[,Rm] '1pRč4R=N\X7LT#|)N22N\i4c k?qe":]\FH 6p8+Ne0R<aECvm N"rڨpxqY!Z^&09"1)>ϒ!1x#L.ebط(?:1MM#ٚĘB?>Ƽu}lgu9dp՞ZӤ|%>bq\Ĵ>:i0ܴP#_};!]|u?Nٚzk0- >f|)3>cdYqzGұW~ix氕-1Nv}I.GqǼcFY|eξ,i~Or7C\}5B\b|YQ|m8Hgƈt/mm>yebO,&tq_#krנS Niq._1G^\xw78=B#:c^.uL?rP<5ٓ|Dg CNlpW<^/ޭy(wuvfX{7;'rS_ݪg㯗%7_~caJڒޢ!Rsmtutt ͟/="EoǴ 9DztጧJɣ_t~ރCc4tNTKQ+y삥)uf@J"ΉdF:0obb4/8D$HjdX<YVL!QKSIzaV5oDy$NJF>w<#7&B|n>`WN~b$̞u63$Fy1t%ͳ[%#[%jO6lڟVot.3*&6.a\ԓ}/9./l!,]ġ:MJTZ# +0,|"e<F|2d6KsPjLq}L "In%ۤ@ ']Z *Ӆ3BޕXȐ;Ť q!%{RI続=J+=)tps_J;2zI RN}D}{J(89M4I g8ڌ/uJRgݒ>G_&B\ nM">SK_ߍ )) mھ{9/dhb?#C>d~~ x1]Olkɽe`ߜ LÅtgJk]AKJ#FnHJ#(:쳔^]HjD璡U}YhVXR`gXȦ[^+boh5kM_.DE-FčF!9J5N}&7\e5;nkK|lWΜ)F_,3R2d Vt$%{ 1iƗ^?|ltsH. >U8SK; T2mM~Voz0N>K(5N_"~< X2e)Z, }xîa=Z%6?Q7he6P`>L$RcY[`FX2qP? E3?+Qn \l;ӗ-]s1atmٳ}<Oم.!?!u{@.o?_zFc Z)g4#9Bca;G#a>=Ӌܯk;揔^\{8 jN?ܵji9]^ 7ӕNۻSh$9J*:'4<wS15OE;Wr.y&M_7{rF:Ea;Wbx/m>dD7zS y9de܆FX'W2)iw3i97=4?[9c\TӋPGɝy=}-Ѧ-z8cgt]9[P:w#߫y'6v9x'9= uߖGx. Bu R\3YWw*>T.QT-Ѓ-u^ʽmdIBX'F]ۏ\FɻuZX3"8C[xv9*{{C6YR}Cc=n'% P, cT`j"=>qFմ]OB+y/=[bVΌ8ǘBT+Cc>M7׈ĜP: <\%fѐy8Kwr9krZ7z^Āqo;D)3GUFS^٘ƘKeYO6FplSI- ꎥnXi78,& ⸳}Zz4}?.y$$ Ax &nl ]-C1!ԭnq/.'i \KpIpiEbj $jD}! -~LQ4"?XhiҖXjcNń>':ؑKO9af-\Hm)5#Xync`x ?8b!5@)UMg mڨ1M2(`ĆwID2i?6*aBM#&=iFmDj3("81Ɣbۉ}LƆoƤP,DI8;[5FgSh3(¥-KE~L-%{mnbq4+ܲH[b1iyis|7A \zpD ̶u7CnV8عO;}dTo/ڭnq 6PSCYB\zGd> OiSR r`,ZߐT{bkIQ‎Nښ4k G BsJByߛ1ߖ{i`̵aҶJ &NM% ()h~ Jr:,A΋aކ C1gC{+Fk{qHX&5>%=T)П4e \}k-ms20ҩ};B(˹1o#&a:7Tܑә HoXfZw>_.^`^y!S3x. kS kGzq_3MAe/%,;yIYd-cu2ZkFz~ 7IG<%c%rraQJ]\>1MAG}<|ڞO N/0SA;V=k2%J+|mLִm"K[HOa?F:w[ž6 Gs7][UzkfRqtbXXӖ>AlRq]ѲNR6X|ۭo% s ԧ}nB}>B9a}ǒKH\_7_4aguKGRO6S1Ӊ̀2U_)c YktH>X(Rw1WgakUӵ %k?iɩu:-Mzyxu=N_duY?]~:1.oA>Oh-@(7R9ݮ-{o4t|zs8PZ1=Idk7H: v߻3ا}Fu&RO;qF+ z) ziAR,WCqX!x$r s tF`Ԡ l'tW zh[_dkң,{kq ΀׸`V a zV't]n!1g3TH9o` _,_s(yֽ?61 +e:e F ;z|FO6w2(Ax a3QSgйఄ3at&p3@ Ќh嶺 ޭg7c29M^ǥDB% &p Y7w55/zd GALpv+=Ô<[R+YR+J62Yfpp܂w?b *Dz$%0nsʍV`/YtV2Iv`Q/R}~(s/((Ovt#찄']jla6|g~*H,H:2@^_ǹ@+?I5Uos:`)"J @Vv?KۉRv )5'ܻo HY{ HS(% f( JNA*p) )W\#?%H;]% ?%*I(`|ɼaUͮ^A#ߤLRD@ %]B$ 8rbIu_Hr@G> >ɮ(\Yfk0?uń'.II&4 FOR8AqH'1a9H&*ނYk+R  oIWK~&0 ` kNiHОom7q(ɋT $V=[*FG~{θm~aWj`duhORنKs2 XX'9%GyIXqOX9LF|7@d97U\Qf/(Bʟ-q8eN"hm'K\UC 22' z~B9& {&h <C `E3m ! [$`{B59QY,K>o !@*:ۗGDOS*s>[jiWZ<^YlеprB8)qGO/M*H:ؤ}'M'ǾKܞ/DI[r'P~_oPV4%$꥾~T\2'FA&z9|ջqy+#RO~o埵"3ol.a*k]n$ah-HzN7iGe;_ߗ%0> _E`Q:Gȭ7Lcd> N>c4Ct( hfwqIgLǓ}#MBrb/2oR eKIraON'r!\>)}7w{_tﴭc}\,6t`col]!t52h%?ѣFlp9?i:R8 dmnLi1[qx_={̪_$:s;mCթS[fq>Wa۽.7şꊺl$$s--ܪ8D݁83hMܲD&|bDMaf 1vkb#CD27m"6u=#$ ma*XfI=Er<{pް{oae03e/|Dʮ+k Ӯ)[VRݭiIm)qZӶX2LXHZSCլKb;EmIJw;K*|9[j ծ_YXii/s弾Y}$ Vv&QZl~-w> 2܏ġĤt4E6+ybb1$"rC 49M,L:1{鉨S Xbu u&XwN (Ep5N ]M@`۴8=FF:&mD8]729 S~![#.0ʄ͆h7cB!gcBj>n%65MlM&tuV>Kvf,nŴzHͷYB{ x#ڶG#ٚXb-,Fv-/Xm+[i`1F FN51qsa{ws ෙ6P`疔B0_)gʹpMܻŰLx61!%ꦤ(AY5 2r8E]>MO{Y6k/@adAW:79PԽn(܁p/yAŃ@fLS&NټLl[̘^ |-ZݚFi >my^ n)HbsD6,r+ܨBI[Wd ĮɐŇ&ZyHl#L Y Tm @""qumiE(BuS# 'l6bu i@#EQG8 %ה&nFQGqo&֧ysOsңxQ܋5S0XaaTxYvFgRѵ[+qHO" |la!+0Le%̷p-vgۗ%8B]\m?JqӚ8FOjeO#-^$KI>ǤzjǾ 酬tsMl'jhFMe>zY긏P1] :SEKm?kCbmEhL}%e%KZy_I̴+RN\}Dɜ*~Ӹ1-Z?Csy~E}j]C- os.l3CXS>_ދ[@8mgH[e&z8i^&u WH,[b^\34TɃ$]Q紕le97&N9(vwJ^nn5Ix(q!5Jߧx#_pc zv&5ιƷQطR9x'3HM?cO)Z9Osw+s[_ 8ݎ׃ Fqi[LQ dw===U6鑒91t8nm-~"C9'ylRM|n*=Q#Fz&[yRҨr]8r "p:`J)l!:ccl%=2qpUN2ιHi8w`$s qr+fnI:LXgs,mhq>PFʁq9V=Ѳ~"3q?;00.65`M #kBE`c "q*U, bHF{6!6٤ &5n0pVE#VIWd٤bgnKϲ&3rUfk̡U_b_H*vCgD}'/Ȅ UA% XϴyT39ݲ  x/>ۚ2 3Dtq*8@tn}蒮VfW5"1lݤpz_L"VY/Pg Ȥ-x0Hm`Y2^X ^}1M*:2~sn/'۰VqРybZs~Q mJ,kRFEjV}N㸨l "ɶsg{RԤޫc˭g^ʶNeZNݭS.~PP%ѹ[׹neYwttțZ[\qn^ko|H[NѤVD}_<hPOpޏ˭I^.$~}iĥq=$#|圯˔dtEAO"!?6Yjt5 l"O4'I b*lHO✛>@T?czo9꾤7rJNS.ik{v 3AlXb['(xbakV#`X.a qxs Q|TTmœ|%SX1 )%!%lͪ&.™͐ -=zi5.4}x'pBݴ }ۖqv%&/t"sI= vaP' !Գ!T6˞4YЇ[Լ̷zQDc)LL&1MCZ `ˀq/s9^^ʋY∵&>3u;!Q"̉<ŢtHB-ʨpè@ U/ /;^PmNb JPHxC.g͐ECb KlxHF>FT bq'BmٹV7L/-4q4B|vlbķ ߎ݂b!ԑwĘ^7߭pqnx^d*mH@Hznݢ$ǭFژ&vk& [C>]pobAkFCF12PJ4`U79pƸXFC65aQl a_U Gcξ:nĘO3R:3 XĆ? 'ny_ة-mrNЖm  MA+\tJS`߿)AMp"gP{ގi;B]tjXaa̷cLېNC( o JOlx-3+g #=_+#}ΕҽDLp78^eoC[25gW^obfcƻg3-cz_k-B:ngB].G Uysz+1^%yo wWƠ,s^[zl$ז ,c{˭jӲߏJ|[ e[{Aq楟%-z>3U60MkUB!ac:ktWD:u!Vsu$4$e\{r?9usVws&v:ַ{P'X;ѿ 7VsًΓ\g[4dWi6zNM*^j>^,zևEExK{sԏڦUf*΍ sIT< oTϘi Z>3Î>#?ϝ#'!5}z?Uôq-"*4KjqZeBi[L/ #;]eN 縥0cn)'!2SңcKQ@žb, HkE ùt:`Ŗ)ǜ%xIFhP'#!88,¯qonq$St܆i/]VUF1a.DѥGُ^IcJv({h;UFIO15؎( y\Dmz"U\Yh u/`,SMs [E;C=}Qkm%c}ut-n8*C=#D +tk1Aj POMHvua u0!}*~Oyv!D^LF걧$vt P|XgX 5z&7Xd?7V~Udž2FX"󪉰nc2I`db{2=G NLǴ@!20"a/e>󪑓L)CIJdwb{7ndnew6ɡ%g7QL ^lL.2z%6LR1Łh0\_.JȋfI.IB] ׈~~Λ+phpsHv'"5썑_0VQ҅<Ktv٤PҥsFpѥt3ŒRy )w /*YR߼H}}AXDEtI*Z)dΨ{,Tꥌk=m)n}A% l5$TEp~p%mH[ɠDyaVN21@4kfeؤ>T% 7Nu )3ʘt2fכn2G)%`V2q$M z(I(z~ǁ$hRq$E:tv c@@=|=X nLXG~3q:)I@&)|E^5@|JdbWT/pmtOR"p)st { qr=S+0a:*D31U2#]v+c<"+%V4F4)#e y$-J&d$*p;>9xozf'H6dHҪB/fW@yK ?GҾ@s3~ g:?#<`>Uǀr< /Q&!]ۦg7I1@TϻS͚g)虂OYtR{9蜣%v jI!SVob[ DX ^HEȷ|ȧL懓)٤-R) dsS!mRܲUSX~ 'N:C>AMk^"ne_D1FO|6[@cݖA}=ڇc~mo As9< jhOO)-''1 +X+ϱC,P<4R#E2Y\zL}US3{wV{ӷ~~Jc! [sQ 2KұoSbx!(hС|~&{ޠK]jY -9K~z"Asb += Aüq 3Yv!QL5BoX/]h \Mƍ;p7v-za UV*È3MD!|EIM*CkHj=N'/'EA'&IۚݖU F}@9)4UFiև7m $ [bc4/e?pHl)6rb ݀]i&D4%*^8<޸՘6{ojP}j NyL 0CB6}wI{L>'m3fk7[#Tk g$%ݨ-4n5/xxb{I3iGKfL~4p1%Ӟ7jbȷAúٵ$F:"֍Ln>gENpyniCΦL:Ci@pBC< V+=E3 BgESrЏ5]T>t9Vw{#u+<`89by!?/d1ʦmt/˺&Vsu] l;y5yYn]|ihθI濖W7.eSMlw5N31~ 41 Gwd h6ϊ\QqzHfCwH}Jd#Ǒ^U8 =G[m7wx{/&j8|z);\g鐟*y6^,s%ṗ7qO=Yk= -_+1 M^˾W7 Wqrry>⏥V~538f /k U[?6 %Z!Xu=l@Ҫ>Y:ssJȇizvIE2s½ļUey>nuىJz]]K8-4O)z藛6mKY;I+bn'%W#f_!t!Ӥ0}Jc{Z>OwpSWmMiZ5cWnŪ?jsTg E?F:%7.Vy ÐDžU2+TQc4~o Vj؀פ˰}FiB#$jq.w +xZs.Qi|C:}I\ǯ-zyXa9-:rO18DQx % w[xi>PMTp1ÁPaJR1a|X#Hv㫟L[z7zeM7VVK~rs62ClGZXƗ6&1Z$&/ҙ9ƥ4#o(>l4?HL5/HB&+f4ctņ_(Rck^Q;gnGD3撁'O,zJ}K&)ٕYH9_3Q0&-IAWk6_Z**^#! d`/ILvekfکd͔(ʙ%RZ,/]Y yg ]yH3u8.Iuj6iR@|fBϜ)RXF)0'W$%y+&=tF&?ٕtҮK+]`Q^ϰkݗv_$0# :&]+h7փݬN,#l?KCAIi/ޠ6~Kek7oRNI?Sg۪Q ޸II(nΥb^BED')Z,سB>D/ȱTey(\Jƒ5KU:MpFA&@o)g~+&٥mאnM%Dը;Vne02G֪] _Mme 2/.Toʄ{M-wRx%N /RvFoj4 wDqX2y+C^:JEC^Ɔsu.CW2i?}3ЎM6MӤ@6:7pOYZEgʫbtL`hLZ6(lV`]aFO+'nEm>p#۠1ч*t6:_^&*qC͞B7z^{s~""S̰ T=rAF_LM_dF_o_mOi6)An@N{;;x^^Uva9+ eveBPa׭'=Fz F0ҩ[mm9}!_|so@HY_|]t]̓=K*Fz:3N>38#=ߎ/^C똲6O6V"Dy9ݰNwar/5]jig?̀jUzH7>EQǾo[,gZơ7FzܱOxǸ.\ >ǖ|[_]Sз-S(18۴)9+迶Kf9/*i,w\}sqrMx*^\p2O\~ eܛ>TcLq,%iL!֭/TXؙ T'1w tF Ś؃́>e<7u:EIs TWןOG4M7:oJ؇eHvn$3uaǴo[l8n}>wĈ :N1%gVl>E{ܐ@92'3lDl8~?^"W:#jcgpRy,g6 t&&57k^z1L"ߠ2@ YDq/!IŠnb?sˆ8~u9qC. S Q{ZUbS\_KK1ƪ_g&|M\NᆯqmE 6Vo=~u8%g6}|2n @R9Cķ[ް=9ąEK?cD h?Tn\O6&,Stv^$2ƟZz X3Cc+[H||d(&Lkkxn:{ZbEms QuM,nvnKa.K8s-sb0MðpFm4$nk6K⻫pDϛ)B53X7ϒfiW|S)G_ s̽p}chF͂/XL2iM1ynbb꣘еH%2_oipH4&(6m",1B\.,H}Ս(rVb 7 k9ޭQi.hΝb#R+_iz==;1ݠR,|gx`gc $CP 1UD_ @OB}~-~a~A9ƴQ@ڐ a,eaKBV6u@U8]zpӘDmOq#մ Lx󚋁kSӠn$f,lP7W+\ьKݔ7;kÑ -7W#^^3MݸQ߀y,8ixIY`baVi!YKAb܉nςnikjIbHÅK61֦MRQW$~ѶEڸY6dbk!1fIl@M3m9] lHSnK:S[7mfҶ9f4})gn,lе́ |j}V0&~0q_EBeꦝh|l;k7oĨ s/9jW*q1MA}q}] Fw:lXؚ򳔵cayaK"i]@ m;ꡒ -ӖrKlt3 zjBc?$wasSKǾݓR[xL1艩?TN¾g&sԒ'V bM,RyB|p1lʑ%ai-w.leIyd38'2Kks/||K*.mQ7sq22bsgDgct*Rݼjȴĥ-q^Vb1qYʻBIOd*RTRPNO,p]RqXz+x O1DI߭7JzCH,\oH GVE[f&J#?+rgNIXmeClcCn55$& BP}ݱ<.s? /q$Zn5 q1S-(&Qx+TGuЍKpjb"L ,܂,(TKIo?SB$j'%Ǎܭ'˼A ?&?u8zOd ~z`Z[P[Tz,4/jn kє}\TMs}x2 <|eGɻ40jhsͻ5h[leoS` N sҧ7NkZb6WBkjotLk\dž \yԐhhS1g>(tt'(!ljҸ1}@ 3)2bi*a ikfJJ_ = M}a H.\9dB4c "%Lz6,mP]Wv%=0Vo+9'_RVoZ*w +Y=iK+H7ݎ%g_'_n@RS'.LQGgXK?cM %sjR=b!mB1E ې}B.  L%{s(hsbؼݔf*'Nri^^w?J po9!FAB>Bi##EKb)붒 J{t#ҖAcgd1kHIRYmD\*aҡUiCGVQ$Emnz^l[)J\hg&_v^  R+JH^( aKk "d2zS%{6;ZGQ>C\r^B ta_ gCٛlR`. Kg$裴I(XXe!]e` jH5)|] T0f4lD%CWR5/VB*+\6h.n^E!,]Z{X,󗋗7pÎCi~o^V 5VR[)%k7>b$+v4 IJ&y9DUn}KUɒwlsYxm_%99J:/0J$R});Q9)8Ai7c'R7kC4vc${W /SX#%l^4B{*&'Lzۼ"ֳTWߞtN7͐ӺޜQiޭ*Ow)}9>7|5.W= D%Ǒ~M`Aԫpr6nuN6jd[ϔ{c_;V bD~y-%agq<4c ؽ}|}8D= i\\V_Y#7{itgxf/yN)la.c~|%6STײHZ~*}֤,]Qocm bH.>isׯڂ,^UwxFgW(Q-N+CXjxzh9v"T3 oͱ6 ;eIDE)l˰}mP&!ƺR^4^[y oU_re[ٶ oGmok^^ܦGͽbBcMι5r^0$XvcZ~1>M2X>1N£=s?Kmlw,el}c()6N,SI?ӄ,"סg )E$8'HMߐ %J6C,ōKQԨhDhI鮪 X C0 xf"n>҄&Ģi鄠nLjZڿ& ^ vq'$)i9PҼpTK hD:A$6l`B4ab Ǻb?&im(vt[,<32ЛݐI4DPµVcT[~J1hȭ| h*bj7 Rn-G&!BP],-MAؿݘ zwb"(cpIL'\`i$F,ms֩Z'QMugy,m/{7$tS":E!vVڧ0;6Ȥj0anDHG7nTPg0 -Io<ĜFvV㭆ѸF+ӅEXߴ nPeהruqyL~mg5 *7mԩrcᨍ0Pb^,AiqfF7Vż"#xFV(}X…E;hIkCs/#e7#qXF,qiL6;_/jH w eta8ش21֒kL{Df1D1F9olD‘KAܵMގK+Pt֦')DEy Sq~SL`1oDW))"`ĚcļF4(!5mޚ&m,\uc2 x45ELpgNSimyB )Anp>YBbǤ3~fkըnF|,R#OLV8|'B3` Xi8mشqzMlwaKz̑81\5Od\Ɠbf~-;-ؖ 맠ĕ? Xe8H\$27r(eKvuuѱG-#̲L7bOѾ'/xPK[MLحȍj⩬S{H <2Iz-F}vr*[sk-?3Z w?Mqo3x:㝥V׺mOizM:ݨj@6yލ|~NB>V#Niɥ0fpj~,CWRގy|}뻴rbpgժ;mw\#}5'q*7*6Rs0y/KSυ,}]_p c ۝\ݚZYq*CO&>A^k3vh]}89yzy /*TҮo:yqFc@yz]J͉qɫMHalw4-'ʯK;xL *|wb-;Llmis7{~m=E r\bܚgVmչ?IR΄:$UENIPi<&~;U"xg k)S'>"i>P, I1Wz;g65[w?c'2!ϖM^Zߪw˻&]onW\#50~E]7>myrt gmnQԝTtqDyAܸ8Hk̳VwٷYt &DdtF<>KI.3)=bDEXc\0&+{^R)osfJ*+pK.q.Ė9'WRJ:1ғhFRhDr.<̳"<38j٥)#/95N)٣6nRX琧{CkѦGi|_v!72g^ԕTX rS$:IGN`kzYcBBQUr(d5L2T=tE5lOi|vIs+9&ۤt%4$9Bx'#qso  Gz{& (۶,]X4kkU )N2ͮT@4:v'ҥ|0N>IU~Deo%PL3[d ;׵7t!?q{Vv =tft UŸw:eAT/DX1eݓf3TRS^8nD~oQDrh}v߇8+>Ioz߰sȁTj$l5u'⁤1"%bD.H^ȞE$8r龼A. [dGcP st5f8}\̣giNRU̅oRIRo vER5ݜN}/^hF\\17ؕA:͐"/*3I5 QG6 p<9ӛpIj&g$g[84镉 E]R#GrR&f$ǤsbvMn=׽,$]I5̐ߑx:f Z= yҝT/ҽmO_kPz)HDrԵ6L|#2(c|l'z)WYs8SOSIinvR]þCy)qjbە2pٲwL1z;P-k8*[9*9H}[-;;"CN09Q%U6z6LeZ߫b0Sޮ]g۽qʍvnU9iwӓ혷1iσ.~wn>ca|sFϘ!B8n(Jܞo^o<>w5̥sWݦ)۳.٤LXl)+ ŽS@XМ*9ىK 8voP*6SKHŦ=UݲF'؁c36b[Y䛿UrO@M3~S}_k86|;_p:fSG;Sj%vޘ<,Gq?7 靝au_, N%/q^cFvO5^?&|;)=)%!/hna&6uK|q ͟^⯷|Zlk8GZ۰əB-_]%.5t@%1SXx-iHQ:Ra-̈ V"sStķrNB;Za9B&+mH-4ztA xg&je&z'_([nX[|bW6Qywm8Za?2T)\׾Yl|v tHv`N]YBtX)JlhD4"j~##uXrcÄ'd>! f LB?b8 NdD}Bp, OڨGb1vݐOe6XoЄw6|vLmbjh|8` ˞@8k]D7 shCK-.6mcHԗ9؉ylIL|P.D/◔7Դߍ)UۈrK4@YiT8%8|)S$<7G^C1N>܇d'g)s ͝IkyX҃)”xE~A'z -46nJyCUmOY`'}{]p\Ck˸lecyb,OaNxf_ uܬerR@\iHWbY2Gàz N~=G@ X Nw;Kum}:|kr ៘mƌ_OD!w/>EyT}.z_0Sq._*"/2/ n~\9cPB9E%ڶ[ٽF qI셇^[j2ߞ~Q֏n_T0-?I\>vXf{_,7*.zJJc-}o9P/u=qN \NOSY[gLHKFXVɵy35i _c 5m%wL,_ģ٠AZN!?mu929uAsjͮbu qJJCb`^Pw֎$UW 㨪8*ϯJfZP 9Zؒ&{/a$4 +4̿6ޛg+z?ˍӴ} t(<[< _cw4n .qqGIP&N”<2$ә¥e)':ەCesq?dg8cYf LX}H8 I!TA5+x256 hzc !^tIc{i }nj`:YU1A=Hg,\1rKu[>D+BFp<-'AmN+x[XO0gI' jt$'6xV3sZ2t@*5PE u6!h ac#xMCD#ӠA']8<;

G_RB~nyvt!a<#?8%$ | j"X:^@9<n%H:i82')aߩ,`{/HgVj3p4Od &KqH(͘{:m>E4>1U a8t'!N&*dOHq=1tBo L Y:8Kn#@op#0έdK}PzDd<ןQ54]!>:o"}A )ݎACg䴥 !IuUfKTP?Szh kHǠx;Got҅Jl&݆G.+՛8N6cz C KN^J"lIʓgߤpp@ۀh N.ta`ϒMU (Q .ݤkhI$ KE0^3n痹/ H$ +J`Cf}ݠ˫hI5 vXhU:hv< >_8?Ck3J-^|랲~$4&d+P"%=ԤE?0t")$u@Ŵ72FW2]H_jr g%QZv }t 5]J6K0)Da5@F ; 4 u ;&56Oھ 30$-Cs뉽!Ré y;{>/pbD =)_55 GA 1m `+1yg"àҿ0Wȋ`I+{'nt8޽ *1wޫDHc4k|{l)#8au/齚K[,gidƂ߼WSy-s: eCP5揗TX:k~_1k_rÑ70Wŏ o J]9ٳI e.)Xl9}խ~'Ҥ%c%L{9otbG˯EmbO+xZ6an{ku=4`!1: n$z!~-$KZ fMl=cՇrb=}3^)#j(q-<錧ǔBAs6\@}@{:Ƞt]#`7^ 5*i Y(<=O˕5Ucy|X&~.&HU/>խvs{ l)_PvR;) 7fDˑ`tmqT0EoO ^Ǟǂ'&vqE'j_b%/H$6LІom #@MI]&F6b(VJ%Txoф6ߍ)GgCTv.ޅۡH 4U 7[M"F&m,obmLe[PNƖ\id@,bk{DW#Sb4dm5*'/m8.b)w4M̈́gB۾6hBW#]iÂX^ 6_ж bF8#ld"؍ )aźI-όf&) 6b^8B16/h(شQ 9T/j3}pg IF#4C;m-1/d~X>6"?e v"2 F"(ZvN72E^u aVia4aφ|!f(h ?uJ(DB@RbWF (!ia@onp`(9{{B4K؈DJ$*MoI5Y4R@lzgN }Ii]c1i E*G T`i 11a*u*_`mZ4C[-ܗ{ g+9i~|hi9ŏKݸ:fX F;8$6m5ޑi*>'S4m⿛8-`}[%)mnOj9F2-j9.2o냸E5s3&m2C_ ECBL8KPۜg1Rn\א-WᶶJ@,=we?o*^lro $-ظ g(-8bOIt,A?q[m9 K^?N W2>&޴2)y,lE:ʖfABI%_v?~%S#Ɍ/*ܟnѰOWyLq->1HZl1 7C\d~1{~Iwkm5]$a6U*Ws^5%:Uv|S{WۈS v)%HM*>;)uKXw);r˪p{1pDt=S/%b,o#,%D̦gsĘ$4dI 82  \ % _,")@F^곔ΤKDr#GYXn gOz;SKdcətoh^Df7&MoH&ݜv +sɴS8k H}:.~7fhK,qڌLyEALy g[ezqZEsbp4q28GD=i,l'sۉg_Ds)g3]GTI6naDٶQƈme{,)4I r<dWbQMDTh3+ʘ3u, ~K;:MRO={1L{g'HpFzWNɦ;`;QJ3QZ2//+ۤ펔|K~K')Ify`Kj|h+]<"GJ"]QE~ѮygG)rtO%) ߾`A"?3IXؖ_8ږ!M %g0mi%~3_&rt3)/G[KywKsAkN>fH~)*D/*j'(8.G_)# ry|<_a #SNĿlY&\xM`+RB%LɯL/{7f"B)ػúp. 3171cɴ9hߟZh_5<o6| ( c<䱠𐑫='Gf0ֻ|0 ?J4dKoD)Ƕ2Hʰ_j1C_g c眓+h-:[{ae<Үq}/"XOBuOyߩ(ׅ`|O 뱦('}>S$V6߼}Oo&m>TSEMuw6?q?=q{:gራU'{tt6g[:ӵ9HyEt橛+ =C}9ky-f%gC@驳1 9NSYz1Pzo1rqYvFԜ?=B:1Twuz^nL)ϭ?fGTŏ=T׋-zgﵮ 7o?VWa֏a9M+{xݲ_ ~ A1Wx9蜊<^#NUNJ qI}Ԥ:g8:/E# ]NuE(0˘>[.K UEƱ8.3nPqv.c_GνXuǚu|W;hǬN ےb&7#h{-:NbQ^@!IV!uy|0iíM;fKpԧGx0=&Q\ x3z>f[ 䀖?oTFtM[Sn6#[ݖ 1=gobS2jj#:֐qٱ1ʠ4 ϗy-= T'Ĕg p/ڭh5Jd[v clb3EJ' m /fNbJe`kX /E3.cj9b^B[ i[ЭFLp7Е 3[{K2#fn&YXKaiXBn(ˁ1 4$iĦHvgKʲ`S%l-\8N|Xw;-9pNm`>F80d췥GڸnKȐq7*+vAM{6@ wZ4o2<ԗk˥"_4S22[8hx^ZN$1`t&~k4Kp@…\0˳!ڔSR([*otՍ:K\ꆤ4"z BCv8g`1]90ʸgM-.Xʎt!L&6S$(?ݙvx3m,Z$wi0dŐsb^pqieMɛq>X0(IɄ3sSX$x 7N[[4i cYTpƽ KlC[ mN_4];8Ȣ /}lMj,9Iduzw0:Mq\Cn籬g8}z:a-gsbsDZ$(]s@@\H*^#QCT~ (X},ZA  .H}gcNmq_*9K٩3޿//QJϧ,Sxmڼ s鿶p+M0~vPlm:qicݵnM3P:1>ceN{c{׺yR[b,1FkJvu.?Ѿ$ݠgX)" P0}$~ ʫ!߉^Mˣ8F{~{}8{5w-om=i׮n~Vvoދa{TC|hM؞ OIX6Fgg՘#/6?^cUU>ǽ7-i/?F"0`>fe؆0ab)A sz9 "8ܱsTU) O+T+tX n:F:.x-㴂>jYr:ݫ{O5rl}"}ߎt-e]kI_Ⱥx#Z>ħXD+wkA`J^jhMMnzDI%7->XyNMZ9n#Ϫ65ՏL8^oaL[J%i̓u.c*zyN/&cÉ;Ggu^&ݎ)Y1MPEFz]ISZ: u^5jx o+)b^6~̮e߱1/i uK\SLiWFo,s `)S7iHh _k@]"h 5kLheDJF[ɢK7Z54Sn" Fפqrd&WgUO~WQۤj$?[A}Qڼm{( '47V/3U^m%^k4˿Hmn/ p~nm&vIi5e&WMGqv4t6&bo=oQ %~JحQZUv^UX֣W;6~ֵ`%klc4OB~ (wfm9Ѭ'/ȊU>j|lCUŠў&LlB&u-]kst-2.0.3/sample_data/TWIN2+fixed-width+whitespace+unixEOL+dot-decimal-separator.txt.gz000644 001750 001750 00000103046 11544160207 031225 0ustar00synthsynth000000 000000 6MHC_case2.txtŽrn9*dNH,9 8PLRw83 2WaswjFU,_?_~/?Oo_?_o_?ǿ/'w?/~o'? K/?> __~#20Cۆ/(?SGOv ~8Q 1d2[p8p* NW"\o6d \'* gtr.#2:/ \ r'gpɵw;7Wo ֺ5: G/Z5+17*z^p.s? .U;ek?% 'gpt](B@CT={"\OˀpZ% 4Op@_-b"~|pBpV3w=z . /I_[otÕp)S-Z77ùUry؆Ʀ#Їx~+u0nt3<9;Z2X%ˋc8cp0Ԗ8\ N*ҭ1ܡS} pAx GMXt'QuUgoNrQ]wFp@iYoh =qrN*)e S qut;7p{{ΣNs%qO4ă2uv 8eOn,Qb-C_4K\YW8ONEɟ`8sjKZ4jgK[=n<xne카bU3\ǘɔ59V z \Zk4A) YN cb򖩮p=Rc$ɯ[3?\ yi4Є; ƺU*YҀon npn]pwT?dp M&fEI+Lu9z?C$=79JUֵrf=TGp rT<_k$p >1x8*|h2=JrnJ{.g/C q5 R\598$gMz}sOtf2uk a׼DIQ-8EK9YpQ|'{AC:]әK!\+!0Lu=,@8 ?Ve|~s\D9 -ů}^p*+254j6c8JRPsnrZ >áUR<ǟb.vK#pYPےsAC9ð O5P[2/u‡pFp%rq_zIe*~zOpKc'7^?Lu?U_ SR_D-gr g UX!Dܩ=ʹ ͩRj?% ~R_,d=:81\c8sc}E&\8? pXhU_k%LpἪQ'gS=K?TO-SMrXPzg T\&L/[*y8u˨*jJ+[A}'psY1v-[:Vq(Ԕ _kI_!\BJ)L8;ӭpn \L)t OáU"SAp#ZȦ.o #V )ZdR_j c%plH (zj2z'K@aWh2قknϱ^: k G+fz;26pp,OCN4C9Y䡧u.tiV˅b8'| p-ɍ%i5~'pk?q8c8VyaUΉ ggf?P+>1$f w!:,0V[S&\zsE+~vaiɹrh2j38 Gr9ÐpBpϦ4SǙ5+(J:aȀE'ڎ"8w¡(muTǣOO(T=~\CQMiɯ5~2Hk}ESҙ%#8xZj8[0Xp N ypNo4߆S;p5OkAc7Xc,O~n2 o\pFpƦA -ᨧZ= CNp``]8ԗ, ;#+Ac֨Zpг8Cdk0-r*~s@C"|2 4֌[BXڞo TP W8%' U{ieNupxp_\peF{owؿKXv=ph^!OCxf(Eݨ/MyA7u &|k؃Tf>g=(S}"[H}y4a!%S7/<Ŵ`V,< 5M` G9D| K7z!9 NT]@K:V(i[԰Zq`Z 8|EpZdy$kG>\Lp@ uT% qv\p*pX+:~<^=n!*3sxW'E_.0f5Gr+8Vb&}0ڥI 4aǜb4UVÞ>M3YkzxP:8# <9r3/|Z6 L3(SL&}Ɣ7p>&1gcs&wfJp+.#ܞqe2nԭѵQdGj.0M;|TI îmT26QPf&\9*k[ 3m WiJC6ŁiYq.(!~Q䄮rqCz GM1Kp/8؃-ᱮ6|yPNdSV^ЃT()1ыn>d{ǀbT*9\5 ;}\p:ǵIb•x`M8+J:r|wM3`XkH6ao'{ Nd{T>zYu)~i y_/>ܲ.pAx>Z%E7{CU .M\p0ȹ \dj[ pОJpB'@Q" ^rNǀ2&\!2BTgA7}v$\ ܖ a`#7recﳆ|Y5SJJt*_ jM$iQqy Uoqʾ*f QwNAhm˂G7WfsV)!./MOnQB'smNbZojazOs`z\p 2+β+b Ӈ=$,J7 hk+_ch { 2ZP!Yp`]prRk]7|kBp^wo"~yk}]k.ך.,DmTPr7ܮ!jčzx}2R[sږKs ё BN=Dp<#gmO0 ҴcL +8\5n¥ 8?OO.z7C@bx.?CȌ9zruD-$MAe2z!DŽDge~q ֈd xȓ`A*S,/FYB5<9_!}TL<7%R T9L5ծ7:H&Jp@Kk`ףQc%7{c^sqܪ|k[Nn."!zL 5)o-S\|+TWR};xu(Z?l"]ת5zFzv xq돕"^yek^k .p-q'Tɴm^ .꩞jAQ&WvȄ9?HZ׃pQ-&4Z&I/p4os>YQZP! )1EVS&Jp(uPP,{\3M%A!6'rv)0[Q=ѴZ޶e&ᵢS]}{D v5W޽R_MzS=º[?1և?Z BN |rSm}zB rSOu9ez DIAFA K>Z1csDch~x>nln4i>eUߝ˿ɹhT|xksK}Yȑ-S]1l3/)ۛ^_xs}5aɖ8ac3[+ 7rFLuK.,nپIS*sA&7-c iRWlj$GpҬ+2SX:6DK9 =uaA)$~pnL8xWtip3Ȗo@4ak]fp޻QG)>LkSӿ EnǯuYFwV]ZZՁUz+oe\DIon{T'h7zuNsLU\䢎rnDB4<˅|=Zᛓ*5dTو᪱4j Uf)Ʌ{+o\"8A8<9,Xm@VL0?ݰQN\^oML5\+;>@bUPx 9v7dBozp]ןG 0Ch-opQn-A]ksk#wwd-uセ\_3P N\tq(&S"35w{Yx>"} ugJZe!}eINMw"$a_i MH'،2խ# ?<2iit%٥GKe*ao31r<^3 jA= k͐pƎ ,QZ6O%=՘aLCЌCi#d!\ͫ (POFbrq&Cm/ŅRuI\ofpF` 1O4t(yie|'\[$Л&e`ve ci*|=*5M=XE7gUcm%_}^p3K7V~OޤKm^"+c.pb$2}+ɞH;I,u :='\ L4on}hٖ.&/zLke~$T7\4E E6˅p| KC`zWGÎ;wiF'8آ@]ل6yք~dG{qO|KsW Oi 9* 9nEQΕAwZ?#ZyML5=~ Nes oQe-SM>:}sP%Bʅt[fWuk TG8 5|9^^Xu Lu R=V!  D/'qykl9Ҍ3}}<Mi>q:|^p^~Tgzi V az & "&勚M恜9:1Ɓi!]˅tΚ}K2RL5|s(1Mp:vϯe _vhMp Nn9%u`ǜZ'; de,tS]ꈠ\rd 2AKMg]k6luڄ |maƏVP4쩾&Ir uUnH]wtߺʿۼWKÞj $xdB[yyWжѤ(K2TO|f­W~V$hwQyg|4NUͷ(trP> G1B˞k3| p'W*g­p.GZ4SnU[ n9't' jW BO8.b7&%kQp]pީܤ܄I#AtTk2Yz094\;@-MÞֹ4:68PsWk4b?DML5~C\^p$J`OJ%%ژVwK@N|rZ4OתnRrPa=ؾF>\_k8~í5AM~p% AuG" s8SvҠCQ&]ߪtr nUMWEZ5LكP:9+|ruÑ)sR”fcT6#s45Lym\S7z^kkT® n[H.8/됑J|htʄ+a]V|rtʝp (i2C4%j%md @nYß.MYӅZ[! OZ*5s#tVR_QO>:=98Wq7|Vs{+梞")17gI83%zYI0g@׭Y>.GM/fּ:sEKxhܚ7 9nAt|pgr:ͅ{5[ %<(]T}_ \pylQZ\3߳XZ篕\Êab{qmMy0S=C?''9~Y4h+hOu5F 0]qÕjAw|MmiS]m p=oS<5nUV*ML5\^k|s֙ ^r_pQO5K? :r/!ܛ\ܾi8C] s>L.8o@s1OF{JGV K3\N{hojkr+&\P+n2e|[{R2Շ'G5t!3Zk*z9\˃5!*5 J/#YֵrZC8 vgO9YZ9S[98B?l0){_yQ7{Y)N%jAׇPvl k%Z3OTpOZs5''I*%qlko|ѵ;Kv-^{Imqp@孇{+>PveInb0&].v=FXaP^p:}vQCMLo}T'[+VGd_%ùeKTGcymo}T?\$žryY圾_g}NY+]A Wڕ,a_0|S||υ'W*Ak[r;W7` G=Տt88ΖAZ LIsit_''% 9-aʴ^o[(GpW*Vu9g/$ℓj\֪ SP#c>Ԇ@D,ԭ]$ an.JD ΣLr)Vȹ{kuY"꩞I~piGg3ZCZKzfdP*ZLumQuO:*0v ǙjqRz;uk=8yZU=Ls6? nd9fD+'G5!\%8P\v! %Wj5﫿B&q‰ h0YRTWu<` t>]s8]Mo=S]KV7{>~^0p!zmؕYܷRo=TK3 RN* \hN4N y1]ŵLr2"e4 ?qůlz f{aOo $`y%>΍MuQuZtJ?43rro4.\91Kq ?~{\y"fȦYtA-\Q 'PAl[[s_9 nL@8"W6889÷V((1= \Mi0JԕbCfzh;Ȥ;L_\it4}):MȤp!_ָC>d$9'p~Xд_9/zN:`ΨwͶL5qC>t ACL fGXػ)j!rPfxc{i]mZU`ONS& ePCL8V:.sz2WX.7*0=8\J q ;| Uu u}7V0k 9* ⳸d[+i]/xw t#'!)'}x$Fۚv=o/ȖpN}Pq[F5\#NQ[s5M7r gX[S]46hPo A]_4Le2~Npb0~y OV* .쩮4I/Cͩk}RЭ-y˶L5 ;c`$L"цoGdXxyyd@>%ڀ7{D ? ږy j^ ;N5 ;XN or-U^'Zㆹ \_ )P9ڬaqO5 p{Bv8پ9%nHL)Z v]3GY -sڔgܜ4FGb"N vxùX$rIL,}6g3ц3i84kUÒܔVAx@ 'lpWj XIKz^U`eyB 9AeVkZ]CT`i#цNHCtV_A)A_] 's#JAW[yzѣ9lʰ!mlJ- d{T2Zآݩc \ZpńCEqI<4YvO]W|ζL5<&Z8|h\5{ynS *,T7q(ɤpv8/(mwI.$zcK/J27(CTyc"p>߃p[3uad&]pe{0S[õ4@ڨ ',ݸ][s>իuE=^BC $xB6G*l\ԛmjkﭒL{pp9v_^rU2}^ .CܖC¾yG TOkm.>ymy+ݓ5ߔfߋ8XIuXV`'[{ )hǏp^LJrѪ72ՠ5*J :T>렯K^maOu3* m[k[tN\=4n5DpYͶL5' *yILeb[lzrr`R~L>_|Zd .V7o'#9\?p{!w0,v~t Qe?Jkr^kEiM8614g&kU{[]yy 6!,eiG;a z ¼kܖn-f[V(S;D[A,f[^+i^Trq'#:%\Zfqz[5|ztu0ey(opAV ÔomӿS-S^?G1usI/#M[BW< 5kf>LݺFx"s<~,< \uQ+ާn]si7:p(y7!7]B8N.GOp\d"׍]k]o#S G = dC8I9qq;BZᛓ¹V0N̕X55 Z{[Ô &\!jhl Gߺ}sJp,a((mu}]p-#q$?%!®3oZ3L5Q,xGmpEC8/(m3f^N2S=BtZWj3ON.tDb\]Nu_ҵZ|rapUФ2ƄY}5ϷaWWA**{ AE_:9mQ\APF)A/pJˮ!nbLrQQL؃T~e[R<w8RQO3\_˼)Lzqz{b7W9xdp+;:'7ǾzAht>(Lkq[l^d-S aZ5 iXW&Ƚ)m /$> rIBU҅)ʹ̀T9CBݾp/KRX[H[aOo. aVpm 89+&/gȹLߜ@KnL3ۺ=?LnlFyLQ&,۵y**z_cK\D N9sfy[Gn W ,6Ǖim5m{qӃ@A­m.ܒsjKPWK"g9\ 65dQ_L&{gm-"ة><9ɬK/8款u|{9,aV_ ur½Tr S.w{韷q:J0S]49;gS\Cɺ*.h@N[B5ƦepuUH־.ZkvG_Oh\ :p-(S0u_VpJnF^pv _{P½Fp׃(f!]konvE8wp  d?89kM•U]w\pz&\v=愮O["fːj[ly"S>Y%XuD.[ '~qU \Vp&Xq[kFS|+!  5n7bI)}sU6 e]7eu#~zPShn p-3R7]pS=Mq'C]҃hq6u=}m/bhx "9$X%[8lrЬ13ɹ D~󎹁:ֽA7&S?s½~̊fw]5N̡}s[ܗ/m%2Gpq[e }CX!_9Uvk [JFجAp$Z>[ s{ʚ)2熳(VB0u!2C˺ (S /E:^Hz[M}#$aMz)2URNU#{%k\;l„pcn yp][; G4V=[[6J΢oW O89kTV8br>(I(Rb~hjk W=Q_Oe_`Ppra$;շ-Csް5#cXG }shv[3U2N˭URDZ3" peWV}-o[eWorzpȞ+56 Χ I<_9ך\BCpkh ,08t+9j+G8Nur%J7z~Զ_VC|}s>x5+q9.NךK νf 2~`"vCݒ Ӡ_DJG'+P}5=ӨWpPÿ6a쫆h'''| J6-]u6s~Vy(3"I{ sҭoǏBIޢP3& fib@k^Qg[u4k3ůU&@M;Iuߨtrrb6ʿі;\_-gTӃNa"m w/Q, Q4DNB8a}w_IsQ28l3rZE8]rNC:ΎU"- ½PuZx;rTrfJUg+^VJj֭R\}KKCYû)m8\3Q!0!j[d&%( VI3Պ[D.jppbxk ZCm!\s8͓kEN"9' KӥqKxq0;"QU7 X%D4-SʹPCPCA_eLFp<$m ed ܯu7g?VDVniO BAEN~T\!r>:|髠\g!N|+7n7kVyT"R=s^Ƞk0:'>n Sg|5~~.nn9^AI2كm! 2.#*OA68 Lכ9tkkA[QCpK}Akurk #,(m.%vRѦ'LЇwmy ܊l9ґdȦR J6cwL:Pp$%;:8R~ B5c3ݷLU0w*yr[y_(e-L)篵a|Nmn?2}$\˻ny_sVЭqуh%v+ |+<(a''gNuIU|K<50SY8"d@4g3g;\&.a :˂OJr\q XCpn w(%j#O'%ᒟ?p=|'~G岅Π S={p gU Sڶ0#\]+l[gG\pq;_9.1peY%$l^U7\m9V_rfp.J̗KM970VbAi_+s m+RA}QiwB)kvΜk?b[ WWoeMp]+5_Z5L*1ϩ1?ǶD+INZvh\e~Ė0JI>hG'k1\Cu$(%=7q2 \ "ܪ+.8]o8;%-kT.-d4tkLu!)۷-'+9MQpშ+>pgp+V)Cw(aOH/p=\O} +:[q9\ j?sdl\g8C%4Ժo)G'L'mq{GUI΍A'z /82p\™Mλ78a8A 9puQCؑD!5Uݞ4Jpg$ Wnń5G'0/vWך~VIw_8Sowp2½;3/8[v ~ֳ n&Cq!,kj jbg"Kg%s'ҭWT B8k6ə ;Ԏ?0NnbR&g01\GU .(JzXˤgBO>06 &p+?U™!trCi'z=ɭ$ ~>%aW8oÛKhgK̤}!^t76k׊{pvLpJjW+ztrp5~ VJpDrK2ՇHCg6rE-lҳ*3ޗQ}Sm?uka*@[H˖'>/V Qkgsz¹k j6tpxkkU͡}K2gM.t!9W4ZxQAj /!9W &Ąj9.[ɹr[5q7B8%bP-K-S]~d¾LTXI#9PztY9SM+a]Q'sR(tgnիɴ~RM8*KeS]c¯U.,z&JpzţuUR>L>j9ȠB?2+a{ږeU"R%oazC9kaږe/㟢DB)n9k%fp3Xd b[Ou95/huAzT0;^4+OiJhެQ*GpLu%Q['\.hl6BN!u+ a, U[%3 +\f!6}+$Jj5rjk .XVMʅ*9k5V|4g3o%M/,J 5]H/_k M& ˿+B9ɴB7YЃAl2A#$B1ʙKC3ʿ% s_j~jsa8c*fU=ėmw8$ lR7V<}^IԎBR717CQ2<\L0lXXCS^%Mr$cQ}_.k5AC!Q&|%^Jf ON(I]5;d0(֪ WgT_EGu%,&ӿ7Qb V`|N(SIAĩɰ` \:(IpH_VKLӿ5?!|BnAѵx#ş0&l>Խ>TK$ v!k6+gc!lVIH y/b#Z;,QckK7dha+pZAEN'eptE>D1VԊ5M14B).b&TSU!!oPCă-fRN nN,ݰTS)\,^V1a]o_}tk]+RW*8(zLpaTvtr)pURk7`Φe-v '7|q T[ .6*6-~̷.6J-},6JZG߬uU~05URb [>{͚_s| 7B5>s,a1\*>Oh [S˯pypvXv9(z6¦k ԰a JpP8a=˷>DO덦f}r}N8oxa  \ʷNp>gpj1\61J˞ naOɑ6rՕ;@|U1xAЇxlj'1~®6,q9 ;] adSg•~ټ\}Y~=.LSqZiK `O> G:82NLo LkAE $-L6TӃ91(1Vs}`pM34q) p]Q!F!F?3hbʷY m.U?ha Gk4'Jg'> &DS)0SůƞqV_8On aL5]+jf1 Bʅf L5֧c8Z98}/G3eTg:ʹ;<ĊJ9Ep\.}_4 [ ™jÓS%ضLL Rؠ}p:&3zܠZ&[ݮ7\^k>^+jc8*A/Kn2Iz%qn0y# +pBX!V'<ڜp -an!M*r5W.͆p-aPўjÛ|*[u6/8R_Z hჰ~ pGU4lʖ>+#2u֭{+4|™jC h~TcG2 gY2b!\%wr!zGpr];+Jy1' kHj0i<mޡ ;*20#OyVI ^rpeTCS]JB0Ib\3pZ9&Sy:Fp}sd 7Jֵ2O hO8m*)ȷv VXC7W\CD=?pZ_.i 7w { l?DAGcV<9A!TΖ6h%I[3tr: 7b8TFͥ[3pc/* .Ӡټw(V@Ck-J7V+7gfpJ'1<~Q3Xž A`Gʲ_kryr՗>gg';:`hM Le \h0ɢ=0&M~zCPb pZ4 FJGc8JDdz5HL$̿Z%X5L ^L#! -_,a;57hjPL|~W8Pֵ_'9L5ZK;!}$Jl.e\>쩆ZٞVX'Rmy_Bitj!AP7 %a׺b%f7zd( 5aish,ɹ S!KXiLb{G}̓ʙK3?J*14}) lM>&Z8}…p2VkUhVD}z)?4|]0&k5?7j4T0Z^qE{Ϩ!L=aB` ®JBB`H7JCxS / 0Eӕʅb GL5R܂ rYΓ[^3ՔQr C6f(9-Z ׏(j07j =,tv5ZC$,]|t!07Lޯkm,:)55S+:ՠOۖw82ӽ,r(L&떩FFp5r%j!U^ԇD îEUy8"yӿ)HslK+6yO䍐'o76:kK+6~n\jp7 uk®S޽\Örõſ]+'5XoBiZ 5g/8ilsQO5[K_sWڥ~^y%VzILٵƉ9CUm)Z5ك.@$Jk|ӿ)S%KZy]eQЭbHEʙ޾Ϸ'O=^6*d 5%\ֶs=Wi޲r9kŨ8D*Ϳԩ&pO5[wQ'Wc%ʵ9C`=gvQbCl!3x_v˿9 MPv 6߮o 0A'ףת V olKChĜ7COpy=9]AQOfυrn݃Hz^kr3îP>+'/o<p-ʷA/tv!\gC0{VUЊsKw.8<}7L5_ks8/sp񌦃Z EY%;8jV~NӪ=YGV¸~\oU9Fsv(3T>>I^3YAY%Ck aT`le GՇ ax&e)NpbK3k]SPu>|_k38Z} >dILV Wz_+QL.d{O&L/IGdu+*ZGNW >l>uV%ll(жZfv/a&Q9(2L 3P. Z Xg%ӄB-yoӿoGĒZ$J<>v[{zW( >X'%:klߦ#c0B8(ܜݿJz8o5de>B:c%M_kSMrNރL` HpƖ0lP7LEIqQRcD9D={=<9o NZ!ǯCzS}*8itB`hej.ń 6،HCZܗ*L$ Q}!9D^WÞS:H`z#!9bhV(sZ;:8tqMpõ#_?^T\"fM^8L.c}`M i R0S}e*o;V25*Q3տml-H iFC#z-Sz4?f> 1ÎdeVCCƦ`qfO9' DZ j.8 ly? d}8|,-cb{S}M/`r To{p .pV-#WjXIl0{PD%ݚ% e_TJTAp? >'8Lope/hzْ$) +6:*(]7#۞O8oy3Adn})­QUuõ?16 NL y÷ƯFH%t#0 fpP*}mM႞ꧬ!^wCi@8SVdzNNAf0?eMkfwc@ O֏Q&TGTB`q n8z㶼sfo^kkmxruVzGUh;J~_L`WɄ* `ܠUCoOB8vh}5zTXϱ{ϒ$s8 ݠhL&_.k !h|j3g Ny7Tl7LW ч?2Ɂ@tcʅ*l _ko>fCb[:Ηh+>=jC`TѤw!Է.+Zub(z'I*z{7n9ȩ0xv e,O'3־\!uT]C{TLjPp%[Bc.dOjtpFtj|rXRYXKa[zLV[aaonsZ _뜘3~O(mtPVl|ӿϬJ Kc ayXD6@4=guޱB}pEPuD]|pvdHtr&Y n}s赮AeN>+  T*-w58x9Lܚk"(zsz68%ڪ0C)qJ6"u[ dp4:9;*z \J.k `kՄ{=/2u[{Q'\D?VA!ZiNd/GS14S\!G^^(\ k{TJMCvrͭXt:yr ٵftn'Gҭfozu{dr cpkf|Z\r6c"0}s㗞a.Bt\f 26鍲˿EE|Ȁ=e;ոCNPqzys7N~V3tpPVL̹ A[%rvA4l>Z\A!,l~? wͷ [;j7ܡQJkp-P:ҼO(>F\US|Zbb%%~Jߜ.8K =9/ Fo4d\[7iW׭ZL z 甾9N=1<T7Nܦ!0#^!|ر=e!Xb /"CEδZc8~0E}%9Oxˎ3჈ntu;Qd?3$rV-ZmӿRC0e U3U`t鑙>k-VsYVڶ=?x%R_¢7!0)~ O>^P Jߜ'${q` V<povf#846_+vtይ<=ZdSQgp3>=էƦH4e jn7BjB+ u-&(p$ NŻlTE/W氿W}n!]Q&VQ()lה\hL}GYPq4Do.7ߩbصCqp8+9ҤJejfp0-(aP{udp:C94)W|=?WA/ 1ž' AckpU| ]9cNFC@?0PV|Λ?hOYU0z$xSqS>spppu3ixLäAT9k+rU3\w!\jDz Wf0`B17N{Fp$=ՋK+G&PW# tpЄS8A j%'#\f8 _¶\IƏ ^3~pllBYzkhO My}9Bl='pbը핶qN.UI/:ON{<~Hs± d2fLn9'}g!`2-z;"V8\W!Ug\;E#T>s;abuBd@zlӿ_Ɩpbc\.8Tvlr_hap|biƭ$Վ V{_&\pe*ky%3LCJ:hz8)S!.!{_e9uckT8hsnDp}}7I|n < fZ㶢/749 Vhs3 ܼpt.#\]hd#zQr4~v ”kR J.:[`N n֨kIׄˡ28T)u ,8> kZ2p٨uc!/do]˄"fC0[%0w\AQtpя:I(Y6:#d5 DE`c!>z[%j;$P .Wb*_.vdPB~˜M.T[;)pl}sR ɭ..4ȇ(=SJ`[7XoΰW K7O9jg KB:Okma8j[.9c #.8W]tCʹ S- ʥtQ ލ^{(E֢ '?AZ~XC@RP>Hd3(pkܗ@/i=~(Ap_+t/]pp_p\y%٬謾*(CSsJ'g71'{._+t/:rƊ!L`$T0٨_+t/ %oA\h jFpdsP>zJkR ~p a8~91 7՗jճC ѨMwyZyrkg }Up5h߰fӋo}s`PC|?g҄t Kx\^o^XAjsih21gsӠ"ǖ{qõMh4EItq S\8  Ǣ$7}M!{%=ѤJ d>vE-C:U?;LJx `Q%s [sV"!\QaC:*yyFNny%7\NN0Eu`9%x&BsÅBQZP}vK?\kCq UP}6%C @:~k0)5[NJa堤hX^5{ʿSÕѵJ4-p?xL_kRJFh24z+Hfq+)꩞UN9*ׁ NZY¯Kzr4|Wop 㓣 kQلY:൮b.|s YBurbiY>1*ɹApJp ׺s9T?Dp U®ˊL S-h#ǁiLp @V/s*~ 3\&9ͩim9o|1aB[_p[,aL5ܑtZlL9eXL=qn U /s5KpA54jѵSM1jN8̐/;^+ ;.3 NP))L28%js#DvZ;8yTB{" \n!J F;ÑP zjɋ^rS=u>LD dpg 4= Ñ&S[.~Asdp{vtr SEjsHεp l%׭W2\HUVLxN֬.$,#{28 ;A7GB4\3? S-( aٴȧnUCh9\HC*(~s 5,QO)|qJsS[s fL5?;8,d 7:A8"n83c Fj֘eDkw)8 I2ܺLUn898Opd2AdxǽK%Z5ҭ Y%2`,ŅAe<^LUBN2y]IΘ^*͋KS}.J*6Q:a;Xs_nA UוLu|rpe rn㏝j% m.\[$Lyy8!e6wQ8pz 04Don3on2u=9# a(p ?3.ozph6݁s_n8*lb%~flF>`rNFwYgCrꁳ.8HGY^vtr*OkLp`U,Q+>EBp9PiGp9kؽtlrT@s@9'Bp~+Χ g0rm")A'Ɍ$ {OL4o3KW0901#!\%:Pfܞϊo.*t+.8dU?j+g38\'8s.en~k]Fӿ5qko85Ww}T5|?`] xG o9!8~7oXIL#9{ż<> 38|r@TG0\%8µsyk+rꖩ.]B&8Le5 .( VflNnuTT? &g\F>p BCJ7*g"PCJp ' 7fċ؇V.j N!p<'8yWl+×W?T:R{sU| Ġ(ddNz!TY?!68¹\KPh;½_pdGpd2e9k|X}TC0Y%p2.JpʙX<~+(BEmOYs(d2 \ï>K`hQnmApdS"8o!{p*gPA ΅}é‰_'ԩ&8y gpPyغ/ўM#{E0w|p 7.v|y]Ik>unӿY5}TȞsap 3@ ǖpQ&;op:iZ+=A7e-=a1,X—nكVmL@p^.T3}!?#rA(LQޤAHT'pdUs}#j!cs7aGJ(uSpDBڪ-WTج({#8GԆC VUT5s+ t 5T]4z&chtRKq?\AfrN֎DGT0SkZ 5LuTOp(.zD C`͆rN ٲ[Ʃ5@ƺ>J{C9 `?8S}XrNUj%=5hc-n'3)Jp||~Mo#A*ipd9JiªA(QkRO3vTɇ46)9@}5>r9+G'c8­IqVl>n\}'_/8-[7Nu&KPεDp$lKӮ(SLuPprAH)jn7T*pf^p+i۞N \"PQJp}I[f<9|8S<lp(j&8/m.-nm㾯8se\AUa{Lu;IVE9W:8SsO.rQʹSͰVȷ6T M̷Bv>IjўcQQa<dxZTO@`8;9̷ @W/hSMU9̷ Lȹ3rgO\:Cc3Z&i} oJkog>ʹ'C꫒%\]C^5\[P>P(J a߷JNU."ig!]ʹnGP}?8S}h ?LY_E/prJ'8s]b%4dW= ZcB+1,(m m1ʹBx<9IP  r=áɤ|.1OG y_&p]a*9u2\HavD2 $1@}I%=iw9ʷpM&aдHS}VpxáNp>VPL݇á(!806 D3AM&p ֆk; ƙá4z0W(z)k]Ó#8#8%FXW"k}rqTl&3֕\O9S}֔WP`= Tm.3ձVP`= X!H>ɄilRhPOZ3ՇfPEIƦbص-F_kst-2.0.3/kst.spec.in000644 001750 001750 00000006124 11544160207 014756 0ustar00synthsynth000000 000000 # Installs in dir @prefix@ %define prefix @prefix@ Summary: A data viewing program for KDE. Name: kst Version: @KST_VERSION@ Release: 1 Source0: kst-%{version}.tar.gz Group: X11/Applications/Scientific License: GNU GENERAL PUBLIC LICENSE URL: http://kst.kde.org/ Vendor: Barth Netterfield BuildRoot: /var/tmp/kst-%{version}.root Requires(post,postun): /sbin/ldconfig %description A data viewing application for KDE. %prep %setup -q ./configure --prefix=%prefix --libdir=%prefix/%_lib --disable-dependency-tracking %build make %install [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT make DESTDIR=$RPM_BUILD_ROOT SUID_ROOT="" install %find_lang %{name} %find_lang kstplugineditor cat kstplugineditor.lang >> %{name}.lang %files -f %{name}.lang %defattr(-,root,root) #binaries %prefix/bin/kst %prefix/bin/kstcmd %prefix/bin/d2asc #libraries %prefix/%_lib/lib*.so* %prefix/%_lib/lib*.la #headers %prefix/include/kstdatasource.h %prefix/include/kstobject.h %prefix/include/kstdateparser.h %prefix/include/kst_export.h %prefix/include/kstsharedptr.h %prefix/include/rwlock.h %prefix/include/kstextcalendarsystemgregorian.h %prefix/include/kstextdatetimeedit.h %prefix/include/kstextcalendarsystem.h %prefix/include/kstextdatetime.h %prefix/include/kstextdatepicker.h %prefix/include/kstextdatewidget.h %prefix/include/kstextdatetbl.h %prefix/include/kstwaitcondition.h #update %prefix/share/apps/kconf_update/kstautosave11.upd %prefix/share/apps/kconf_update/kstrcmisc11.upd #fonts %prefix/share/apps/kst/fonts/*.gz #data plugins %prefix/%_lib/kde3/kstdata_*.la %prefix/%_lib/kde3/kstdata_*.so %prefix/share/services/kst/kstdata_*.desktop #plugins %prefix/%_lib/kde3/kstplugins/*.la %prefix/%_lib/kde3/kstplugins/*.so %prefix/%_lib/kde3/kstplugins/*.xml %prefix/share/servicetypes/kst/kstdatasourceplugin.desktop %prefix/share/servicetypes/kst/kstplugin.desktop %prefix/share/servicetypes/kst/kstfilter.desktop #designerplugin %prefix/%_lib/kde3/plugins/designer/kstwidgets.la %prefix/%_lib/kde3/plugins/designer/kstwidgets.so #extensions %prefix/%_lib/kde3/kstextension_*.la %prefix/%_lib/kde3/kstextension_*.so %prefix/share/services/kst/kstextension_*.desktop %prefix/share/apps/kst/kstextension_*.rc %prefix/share/servicetypes/kst/kstextension.desktop # UI file %prefix/share/apps/kst/kstui.rc #desktop file %prefix/share/applnk/Applications/Sciences/kst.desktop %prefix/share/mimelnk/application/x-kst.desktop #icons %prefix/share/icons/hicolor/22x22/actions/*.png %prefix/share/icons/locolor/16x16/apps/kst.png %prefix/share/icons/locolor/32x32/apps/kst.png %prefix/share/icons/hicolor/16x16/mimetypes/kst.png %prefix/share/icons/hicolor/32x32/mimetypes/kst.png %prefix/share/icons/locolor/16x16/mimetypes/kst.png %prefix/share/icons/locolor/32x32/mimetypes/kst.png #other icons %prefix/share/apps/kst/pics/*.png #docs %prefix/man/man1/kst.1.gz %prefix/share/doc/HTML/*/kst/* %prefix/share/apps/kst/tutorial/* #other "%prefix/share/config/colors" %doc ChangeLog INSTALL AUTHORS README COPYING kst/COPYING.LGPL kst/RELEASE.NOTES kst/NEWS %post /sbin/ldconfig %postun /sbin/ldconfig kst-2.0.3/install-kst000755 001750 001750 00000002016 11544160207 015063 0ustar00synthsynth000000 000000 #!/bin/sh cd `dirname $0` export SCRIPTDIR=$PWD export BUILDDIR=$PWD/build echo "Building Kst from $SCRIPTDIR into $BUILDDIR" if [ "$1" = "debug" ] then echo "Building in Debug mode" export KST_DEBUG_MODE=1 else echo "Building in Release mode" export KST_DEBUG_MODE=0 fi if [ "$2" ] then echo "Installation location of $2 has been requested" export INSTALL_PREFIX=$2 fi if [ "$3" ] then echo "Installation library directory of $3 has been requested" export INSTALL_LIBDIR=$3 fi if [ "$4" ] then echo "Output directory of $4 has been requested" export OUTPUT_DIR=$4 fi if [ "$INSTALL_LIBDIR" ] then echo "Build will be automatically installed to the the configured location ($INSTALL_PREFIX)" else echo "Build will be automatically install to the default location (/usr)" fi mkdir -p $BUILDDIR cd $BUILDDIR qmake -r $SCRIPTDIR/kst.pro if [ -d /opt/icecream/bin ] then echo "Using Icecream" PATH=/opt/icecream/bin:$PATH make -j4 PATH=/opt/icecream/bin:$PATH make install else make -j3 make install fi kst-2.0.3/src/libkstmath/eparse-eh.cpp000644 001750 001750 00000004646 11544160207 020211 0ustar00synthsynth000000 000000 /*************************************************************************** eparse-eh.cpp ------------------- begin : Nov. 24, 2004 copyright : (C) 2004 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "kst_i18n.h" #include "kstmath_export.h" #include "objectstore.h" namespace Equations { KSTMATH_EXPORT QStringList errorStack; } /*extern "C"*/ const char *EParseErrorEmpty = I18N_NOOP("Equations is empty."); /*extern "C"*/ const char *EParseErrorEmptyArg = I18N_NOOP("Function argument is empty."); /*extern "C"*/ const char *EParseErrorTwoOperands = I18N_NOOP("Two operands are required."); /*extern "C"*/ const char *EParseErrorEmptyParentheses = I18N_NOOP("Empty parentheses are forbidden except in function calls."); /*extern "C"*/ const char *EParseErrorMissingClosingParenthesis = I18N_NOOP("Closing parenthesis is missing."); /*extern "C"*/ const char *EParseErrorNoImplicitMultiply = I18N_NOOP("Term must be followed by an operator. Implicit multiplication is not supported."); /*extern "C"*/ const char *EParseErrorRequiresOperand = I18N_NOOP("This operator requires an operand."); /*extern "C"*/ const char *EParseErrorToken = I18N_NOOP("Unknown character '%1'."); /*extern "C"*/ void yyClearErrors() { Equations::errorStack.clear(); } /*extern "C"*/ int yyErrorCount() { return Equations::errorStack.count(); } /*extern "C"*/ void yyerror(Kst::ObjectStore *store, const char *s) { Q_UNUSED(store) Equations::errorStack << i18n(s); } /*extern "C"*/ void yyerrortoken(char c) { Equations::errorStack << i18n(EParseErrorToken).arg(c); } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/curvepointsymbol.cpp000644 001750 001750 00000010210 11544160207 021744 0ustar00synthsynth000000 000000 /*************************************************************************** curvepointsymbol.cpp ------------------- begin : Sunday June 17, 2001 copyright : (C) 2001 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * Permission is granted to link with any opensource library * * * ***************************************************************************/ #include "curvepointsymbol.h" #include namespace Kst { namespace CurvePointSymbol { void draw(int Type, QPainter *p, double x, double y, int lineSize, int size) { Q_UNUSED(size) double s; if (Type < 0 || Type > KSTPOINT_MAXTYPE) { Type = 0; } if (lineSize == 0 || lineSize == 1) { s = 3; } else { s = ( 3 * lineSize ) / 2; } switch (Type) { case 0: p->drawLine(QLineF(x-s, y-s, x+s, y+s)); p->drawLine(QLineF(x-s, y+s, x+s, y-s)); break; case 1: p->setBrush(Qt::NoBrush); p->drawRect(QRectF(x-s, y-s, 2*s, 2*s)); break; case 2: p->setBrush(Qt::NoBrush); p->drawEllipse(x-s, y-s, 2*s, 2*s); break; case 3: p->setBrush(Qt::SolidPattern); p->setBrush(p->pen().color()); p->drawEllipse(x-s, y-s, 2*s, 2*s); break; case 4: { QPolygonF pts; pts << QPointF(x-s, y-s) << QPointF(x, y+s) << QPointF(x+s, y-s); p->setBrush(Qt::NoBrush); p->drawPolygon(pts); } break; case 5: { QPolygon pts(3); pts.putPoints( 0, 3, int(x-s), int(y+s), int(x), int(y-s), int(x+s), int(y+s) ); p->setBrush(Qt::NoBrush); p->drawPolygon(pts); } break; case 6: p->setBrush(Qt::SolidPattern); p->setBrush(p->pen().color()); p->drawRect(QRectF(x-s, y-s, 2*s+1, 2*s+1)); break; case 7: p->drawLine(QLineF(x-s, y, x+s, y)); p->drawLine(QLineF(x, y-s, x, y+s)); break; case 8: p->drawLine(QLineF(x-s, y-s, x+s, y+s)); p->drawLine(QLineF(x-s, y+s, x+s, y-s)); p->drawLine(QLineF(x-s, y, x+s, y)); p->drawLine(QLineF(x, y-s, x, y+s)); break; case 9: { QPolygon pts(3); pts.putPoints( 0, 3, int(x-s), int(y-s), int(x), int(y+s), int(x+s), int(y-s) ); p->setBrush(Qt::SolidPattern); p->setBrush(p->pen().color()); p->drawPolygon(pts); } break; case 10: { QPolygon pts(3); pts.putPoints( 0, 3, int(x-s), int(y+s), int(x), int(y-s), int(x+s), int(y+s) ); p->setBrush(Qt::SolidPattern); p->setBrush(p->pen().color()); p->drawPolygon(pts); } break; case 11: { QPolygon pts(4); pts.putPoints( 0, 4, int(x+s), int(y), int(x), int(y+s), int(x-s), int(y), int(x), int(y-s) ); p->setBrush(Qt::NoBrush); p->drawPolygon(pts); } break; case 12: { QPolygon pts(4); pts.putPoints( 0, 4, int(x+s), int(y), int(x), int(y+s), int(x-s), int(y), int(x), int(y-s) ); p->setBrush(Qt::SolidPattern); p->setBrush(p->pen().color()); p->drawPolygon(pts); } break; } p->setBrush(Qt::NoBrush); } int dim(const QRect &window) { return qMax(1, ((window.width() + window.height()) / 400)); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/psdfactory.cpp000644 001750 001750 00000007404 11544160207 020511 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "psdfactory.h" #include "debug.h" #include "psd.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { PSDFactory::PSDFactory() : ObjectFactory() { registerFactory(PSD::staticTypeTag, this); } PSDFactory::~PSDFactory() { } DataObjectPtr PSDFactory::generateObject(ObjectStore *store, QXmlStreamReader& xml) { Q_ASSERT(store); double frequency=1.0, gaussianSigma=1.0; int length=8, apodizeFunction=0, outputType=0; QString vectorName, vectorUnits, rateUnits, descriptiveName; bool average=false, removeMean=false, apodize=false, interpolateHoles=false; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == PSD::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); vectorName = attrs.value("vector").toString(); vectorUnits = attrs.value("vectorunits").toString(); rateUnits = attrs.value("rateunits").toString(); frequency = attrs.value("samplerate").toString().toDouble(); gaussianSigma = attrs.value("gaussiansigma").toString().toDouble(); length = attrs.value("fftlength").toString().toInt(); apodizeFunction = attrs.value("apodizefunction").toString().toInt(); outputType = attrs.value("outputtype").toString().toInt(); average = attrs.value("average").toString() == "true" ? true : false; interpolateHoles = attrs.value("interpolateholes").toString() == "true" ? true : false; removeMean = attrs.value("removemean").toString() == "true" ? true : false; apodize = attrs.value("apodize").toString() == "true" ? true : false; if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == PSD::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating PSD from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } VectorPtr vector = 0; if (store && !vectorName.isEmpty()) { vector = kst_cast(store->retrieveObject(vectorName)); } if (!vector) { Debug::self()->log(QObject::tr("Error creating PSD from Kst file. Could not find Vector."), Debug::Warning); return 0; } PSDPtr powerspectrum = store->createObject(); Q_ASSERT(powerspectrum); powerspectrum->writeLock(); powerspectrum->change(vector, frequency, average, length, apodize, removeMean, vectorUnits, rateUnits, (ApodizeFunction)apodizeFunction, gaussianSigma, (PSDType)outputType, interpolateHoles); powerspectrum->setDescriptiveName(descriptiveName); powerspectrum->registerChange(); powerspectrum->unlock(); return powerspectrum; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/dialoglauncher.h000644 001750 001750 00000006110 11544160207 020752 0ustar00synthsynth000000 000000 /*************************************************************************** dialoglauncher.h ------------------- begin : Nov. 24, 2004 copyright : (C) 2004 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIALOGLAUNCHER_H #define DIALOGLAUNCHER_H #include #include "object.h" #include "vector.h" #include "matrix.h" #include "plotiteminterface.h" #include "kstmath_export.h" namespace Kst { class KSTMATH_EXPORT DialogLauncher : public QObject { Q_OBJECT protected: static DialogLauncher *_self; static void cleanup(); DialogLauncher(); virtual ~DialogLauncher(); public: static void replaceSelf(DialogLauncher *newInstance); static DialogLauncher *self(); public Q_SLOTS: //primitives virtual void showVectorDialog(QString &vectorname, ObjectPtr objectPtr = 0, bool modal = false) = 0; virtual void showMatrixDialog(QString &matrixName, ObjectPtr objectPtr = 0, bool modal = false) = 0; virtual void showScalarDialog(QString &scalarname, ObjectPtr objectPtr = 0, bool modal = false) = 0; virtual void showStringDialog(QString &scalarname, ObjectPtr objectPtr = 0, bool modal = false) = 0; //standard objects virtual void showCurveDialog(ObjectPtr objectPtr = 0, VectorPtr vector = 0) = 0; virtual void showMultiCurveDialog(QList curves) = 0; virtual void showImageDialog(ObjectPtr objectPtr = 0, MatrixPtr matrix = 0) = 0; virtual void showMultiImageDialog(QList images) = 0; //standard data objects virtual void showEquationDialog(ObjectPtr objectPtr = 0) = 0; virtual void showHistogramDialog(ObjectPtr objectPtr = 0, VectorPtr vector = 0) = 0; virtual void showPowerSpectrumDialog(ObjectPtr objectPtr = 0, VectorPtr vector = 0) = 0; virtual void showCSDDialog(ObjectPtr objectPtr = 0, VectorPtr vector = 0) = 0; virtual void showEventMonitorDialog(ObjectPtr objectPtr = 0) = 0; //plugins virtual void showBasicPluginDialog(QString pluginName, ObjectPtr objectPtr = 0, VectorPtr vectorX = 0, VectorPtr vectorY = 0, PlotItemInterface *plotItem = 0) = 0; //show appropriate dialog virtual void showObjectDialog(ObjectPtr objectPtr = 0) = 0; virtual void showMultiObjectDialog(QList names) = 0; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/builtinrelations.cpp000644 001750 001750 00000002070 11544160207 021714 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "builtinrelations.h" #include "curvefactory.h" #include "imagefactory.h" namespace Kst { namespace Builtins { void initRelations() { new CurveFactory; new ImageFactory; } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/eparse-eh.h000644 001750 001750 00000003507 11544160207 017651 0ustar00synthsynth000000 000000 /*************************************************************************** eparse-eh.h ---------------- begin : Nov. 24, 2004 copyright : (C) 2004 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* This file must be C-clean */ #ifndef EPARSEEH_H #define EPARSEEH_H #ifdef __cplusplus #include "kstmath_export.h" #include namespace Equations { KSTMATH_EXPORT extern QStringList errorStack; } namespace Kst { class ObjectStore; } #endif #ifdef __cplusplus //extern "C" { #endif void yyerror(Kst::ObjectStore *store, const char *s); void yyerrortoken(char c); void yyClearErrors(); int yyErrorCount(); extern const char *EParseErrorEmpty; extern const char *EParseErrorEmptyArg; extern const char *EParseErrorTwoOperands; extern const char *EParseErrorEmptyParentheses; extern const char *EParseErrorMissingClosingParenthesis; extern const char *EParseErrorNoImplicitMultiply; extern const char *EParseErrorRequiresOperand; #ifdef __cplusplus //} #endif #endif /* vim: ts=2 sw=2 et */ kst-2.0.3/src/libkstmath/eparse.h000644 001750 001750 00000006235 11544160207 017260 0ustar00synthsynth000000 000000 /* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton interface for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { T_NUMBER = 258, T_IDENTIFIER = 259, T_DATA = 260, T_OPENPAR = 261, T_CLOSEPAR = 262, T_COMMA = 263, T_INVALID = 264, T_LOR = 265, T_LAND = 266, T_OR = 267, T_AND = 268, T_NE = 269, T_EQ = 270, T_GE = 271, T_GT = 272, T_LE = 273, T_LT = 274, T_SUBTRACT = 275, T_ADD = 276, T_MOD = 277, T_DIVIDE = 278, T_MULTIPLY = 279, T_NOT = 280, U_SUBTRACT = 281, T_EXP = 282 }; #endif /* Tokens. */ #define T_NUMBER 258 #define T_IDENTIFIER 259 #define T_DATA 260 #define T_OPENPAR 261 #define T_CLOSEPAR 262 #define T_COMMA 263 #define T_INVALID 264 #define T_LOR 265 #define T_LAND 266 #define T_OR 267 #define T_AND 268 #define T_NE 269 #define T_EQ 270 #define T_GE 271 #define T_GT 272 #define T_LE 273 #define T_LT 274 #define T_SUBTRACT 275 #define T_ADD 276 #define T_MOD 277 #define T_DIVIDE 278 #define T_MULTIPLY 279 #define T_NOT 280 #define U_SUBTRACT 281 #define T_EXP 282 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 20 "../../../src/libkstmath/eparse.y" { char *data; double number; void *n; /* tree node */ char character; } /* Line 1529 of yacc.c. */ #line 110 "eparse.tab.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yylval; kst-2.0.3/src/libkstmath/csd.cpp000644 001750 001750 00000023547 11544160207 017112 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 by University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A class for handling cumulative spectral decays for kst */ #include #include #include #include #include "kst_i18n.h" #include "dialoglauncher.h" #include "csd.h" #include "datacollection.h" #include "debug.h" #include "psdcalculator.h" #include "objectstore.h" extern "C" void rdft(int n, int isgn, double *a); namespace Kst { const QString CSD::staticTypeString = I18N_NOOP("Cumulative Spectral Decay"); const QString CSD::staticTypeTag = I18N_NOOP("csd"); static const QLatin1String CSD_INVECTOR = QLatin1String("I"); static const QLatin1String& OUTMATRIX = QLatin1String("M"); #define KSTCSDMAXLEN 27 CSD::CSD(ObjectStore *store) : DataObject(store) { _typeString = staticTypeString; _type = "Cumulative Spectral Decay"; _initializeShortName(); Q_ASSERT(store); MatrixPtr outMatrix = store->createObject(); outMatrix->setProvider(this); outMatrix->setSlaveName("SG"); outMatrix->change(2, 2); _outMatrix = _outputMatrices.insert(OUTMATRIX, outMatrix).value(); } void CSD::_initializeShortName() { _shortName = 'G'+QString::number(_csdnum); if (_csdnum>max_csdnum) max_csdnum = _csdnum; _csdnum++; } void CSD::change(VectorPtr in_V, double in_freq, bool in_average, bool in_removeMean, bool in_apodize, ApodizeFunction in_apodizeFxn, int in_windowSize, int in_length, double in_gaussianSigma, PSDType in_outputType, const QString& in_vectorUnits, const QString& in_rateUnits) { _inputVectors[CSD_INVECTOR] = in_V; QString vecName = in_V ? in_V->Name() : QString(); _frequency = in_freq; _average = in_average; _apodize = in_apodize; _windowSize = in_windowSize; _apodizeFxn = in_apodizeFxn; _gaussianSigma = in_gaussianSigma; _removeMean = in_removeMean; _averageLength = in_length; _vectorUnits = in_vectorUnits; _rateUnits = in_rateUnits; _outputType = in_outputType; if (_frequency <= 0.0) { _frequency = 1.0; } updateMatrixLabels(); } CSD::~CSD() { _outMatrix = 0L; } void CSD::internalUpdate() { VectorPtr inVector = _inputVectors[CSD_INVECTOR]; writeLockInputsAndOutputs(); double *tempOutput, *input; int tempOutputLen = PSDCalculator::calculateOutputVectorLength(_windowSize, _average, _averageLength); _length = tempOutputLen; tempOutput = new double[tempOutputLen]; input = inVector->value(); int xSize = 0; for (int i=0; i < inVector->length(); i+= _windowSize) { //ensure there is enough data left. if (i + _windowSize >= inVector->length()) { break; //If there isn't enough left for a complete window. } _psdCalculator.calculatePowerSpectrum(input + i, _windowSize, tempOutput, tempOutputLen, _removeMean, false, _average, _averageLength, _apodize, _apodizeFxn, _gaussianSigma, _outputType, _frequency); // resize output matrix _outMatrix->resize(xSize+1, tempOutputLen); if (_outMatrix->sampleCount() == (xSize+1)*tempOutputLen) { // all is well. // copy elements to output matrix for (int j=0; j < tempOutputLen; j++) { _outMatrix->setValueRaw(xSize, j, tempOutput[j]); } } else { Debug::self()->log(i18n("Could not allocate sufficient memory for CSD."), Debug::Error); break; } xSize++; } delete[] tempOutput; double frequencyStep = .5*_frequency/(double)(tempOutputLen-1); _outMatrix->change(xSize, tempOutputLen, 0, 0, _windowSize/_frequency, frequencyStep); unlockInputsAndOutputs(); return; } void CSD::save(QXmlStreamWriter &s) { s.writeStartElement(staticTypeTag); s.writeAttribute("vector", _inputVectors[CSD_INVECTOR]->Name()); s.writeAttribute("samplerate", QString::number(_frequency)); s.writeAttribute("gaussiansigma", QString::number(_gaussianSigma)); s.writeAttribute("average", QVariant(_average).toString()); s.writeAttribute("fftlength", QString::number(int(ceil(log(double(_length*2)) / log(2.0))))); s.writeAttribute("removemean", QVariant(_removeMean).toString()); s.writeAttribute("apodize", QVariant(_apodize).toString()); s.writeAttribute("apodizefunction", QString::number(_apodizeFxn)); s.writeAttribute("windowsize", QString::number(_windowSize)); s.writeAttribute("vectorunits", _vectorUnits); s.writeAttribute("rateunits", _rateUnits); s.writeAttribute("outputtype", QString::number(_outputType)); saveNameInfo(s,VNUM|XNUM|MNUM|CSDNUM); s.writeEndElement(); } void CSD::setVector(VectorPtr new_v) { VectorPtr v = _inputVectors[CSD_INVECTOR]; if (v) { if (v == new_v) { return; } v->unlock(); } _inputVectors.remove(CSD_INVECTOR); new_v->writeLock(); _inputVectors[CSD_INVECTOR] = new_v; } VectorPtr CSD::vector() const { return _inputVectors[CSD_INVECTOR]; } bool CSD::slaveVectorsUsed() const { return true; } QString CSD::propertyString() const { return i18n("CSD: %1").arg(_inputVectors[CSD_INVECTOR]->Name()); } void CSD::showNewDialog() { DialogLauncher::self()->showCSDDialog(); } void CSD::showEditDialog() { DialogLauncher::self()->showCSDDialog(this); } bool CSD::apodize() const { return _apodize; } PSDType CSD::output() const { return _outputType; } void CSD::setOutput(PSDType in_outputType) { _outputType = in_outputType; updateMatrixLabels(); } void CSD::setApodize(bool in_apodize) { _apodize = in_apodize; } bool CSD::removeMean() const { return _removeMean; } void CSD::setRemoveMean(bool in_removeMean) { _removeMean = in_removeMean; } bool CSD::average() const { return _average; } void CSD::setAverage(bool in_average) { _average = in_average; } double CSD::frequency() const { return _frequency; } void CSD::setFrequency(double in_frequency) { if (in_frequency > 0.0) { _frequency = in_frequency; } else { _frequency = 1.0; } } ApodizeFunction CSD::apodizeFxn() const { return _apodizeFxn; } void CSD::setApodizeFxn(ApodizeFunction in_fxn) { _apodizeFxn = in_fxn; } int CSD::length() const { return _averageLength; } void CSD::setLength(int in_length) { _averageLength = in_length; } int CSD::windowSize() const { return _windowSize; } void CSD::setWindowSize(int in_size) { _windowSize = in_size; } double CSD::gaussianSigma() const { return _gaussianSigma; } void CSD::setGaussianSigma(double in_sigma) { _gaussianSigma = in_sigma; } MatrixPtr CSD::outputMatrix() const { return _outMatrix; } const QString& CSD::vectorUnits() const { return _vectorUnits; } void CSD::setVectorUnits(const QString& units) { _vectorUnits = units; } const QString& CSD::rateUnits() const { return _rateUnits; } void CSD::setRateUnits(const QString& units) { _rateUnits = units; } DataObjectPtr CSD::makeDuplicate() const{ CSDPtr csd = store()->createObject(); csd->change(_inputVectors[CSD_INVECTOR], _frequency, _average, _removeMean, _apodize, _apodizeFxn, _windowSize, _averageLength, _gaussianSigma, _outputType, _vectorUnits, _rateUnits); if (descriptiveNameIsManual()) { csd->setDescriptiveName(descriptiveName()); } csd->writeLock(); csd->registerChange(); csd->unlock(); return DataObjectPtr(csd); } void CSD::updateMatrixLabels(void) { LabelInfo label_info; switch (_outputType) { default: case 0: // amplitude spectral density (default) [V/Hz^1/2] label_info.quantity = i18n("Amplitude Spectral Density"); label_info.units = QString("%1/%2^{1/2}").arg(_vectorUnits).arg(_rateUnits); break; case 1: // power spectral density [V^2/Hz] label_info.quantity = i18n("Power Spectral Density"); label_info.units = QString("%1^2/%2").arg(_vectorUnits).arg(_rateUnits); break; case 2: // amplitude spectrum [V] label_info.quantity = i18n("Amplitude Spectrum"); label_info.units = QString("%1").arg(_vectorUnits); break; case 3: // power spectrum [V^2] label_info.quantity = i18n("Power Spectrum"); label_info.units = QString("%1^2").arg(_vectorUnits); break; } label_info.name = _inputVectors[CSD_INVECTOR]->descriptiveName(); _outMatrix->setTitleInfo(label_info); label_info.name.clear(); label_info.units = _rateUnits; label_info.quantity = i18n("Frequency"); _outMatrix->setYLabelInfo(label_info); label_info.quantity = i18n("Time"); label_info.units = QString('s'); _outMatrix->setXLabelInfo(label_info); } QString CSD::_automaticDescriptiveName() const { return vector()->descriptiveName(); } QString CSD::descriptionTip() const { QString tip; tip = i18n("Spectrogram: %1\n FFT Length: 2^%2").arg(Name()).arg(length()); if (average() || apodize() || removeMean()) { tip += "\n "; if (average()) tip += i18n("Average; "); if (apodize()) tip += i18n("Apodize; "); if (removeMean()) tip += i18n("Remove Mean;"); } tip += i18n("\nInput: %1").arg(_inputVectors[CSD_INVECTOR]->descriptionTip()); return tip; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/psdcalculator.h000644 001750 001750 00000004771 11544160207 020644 0ustar00synthsynth000000 000000 /*************************************************************************** psdcalculator.cpp: Power Spectra Calculator for KST ------------------- begin : 2006 copyright : (C) 2006 by Kst email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A utility class for calculating power spectra */ #ifndef PSDCALCULATOR_H #define PSDCALCULATOR_H // the following should reflect the PSD type order in fftoptionswidget.ui enum PSDType { PSDUndefined = -1, PSDAmplitudeSpectralDensity = 0, PSDPowerSpectralDensity = 1, PSDAmplitudeSpectrum = 2, PSDPowerSpectrum = 3 }; // the following should reflect the window type order in fftoptionswidget.ui enum ApodizeFunction { WindowUndefined = -1, WindowOriginal = 0, WindowBartlett = 1, WindowBlackman = 2, WindowConnes = 3, WindowCosine = 4, WindowGaussian = 5, WindowHamming = 6, WindowHann = 7, WindowWelch = 8, WindowUniform = 9 }; class PSDCalculator { public: PSDCalculator(); ~PSDCalculator(); int calculatePowerSpectrum(double *input, int inputLen, double *output, int outputLen, bool removeMean, bool interpolateHoles, bool average, int averageLen, bool apodize, ApodizeFunction apodizeFxn, double gaussianSigma, PSDType outputType, double inputSamplingFreq); static int calculateOutputVectorLength(int inputLen, bool average, int averageLen); private: void updateWindowFxn(ApodizeFunction apodizeFxn, double gaussianSigma); void adjustInternalLengths(); double cabs2(double r, double i); double *_a; double *_w; int _awLen; //length of a and w. // keep track of prevs to avoid redundant regenerations ApodizeFunction _prevApodizeFxn; double _prevGaussianSigma; int _prevOutputLen; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/csdfactory.cpp000644 001750 001750 00000007364 11544160207 020501 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "csdfactory.h" #include "debug.h" #include "csd.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { CSDFactory::CSDFactory() : ObjectFactory() { registerFactory(CSD::staticTypeTag, this); } CSDFactory::~CSDFactory() { } DataObjectPtr CSDFactory::generateObject(ObjectStore *store, QXmlStreamReader& xml) { Q_ASSERT(store); double frequency=1.0, gaussianSigma=1.0; int length=8, windowSize=8, apodizeFunction=0, outputType=0; QString vectorName, vectorUnits, rateUnits, descriptiveName; bool average=false, removeMean=false, apodize=false; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == CSD::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); vectorName = attrs.value("vector").toString(); vectorUnits = attrs.value("vectorunits").toString(); rateUnits = attrs.value("rateunits").toString(); frequency = attrs.value("samplerate").toString().toDouble(); gaussianSigma = attrs.value("gaussiansigma").toString().toDouble(); length = attrs.value("fftlength").toString().toInt(); windowSize = attrs.value("windowsize").toString().toInt(); apodizeFunction = attrs.value("apodizefunction").toString().toInt(); outputType = attrs.value("outputtype").toString().toInt(); average = attrs.value("average").toString() == "true" ? true : false; removeMean = attrs.value("removemean").toString() == "true" ? true : false; apodize = attrs.value("apodize").toString() == "true" ? true : false; if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == CSD::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating CSD from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } VectorPtr vector = 0; if (store && !vectorName.isEmpty()) { vector = kst_cast(store->retrieveObject(vectorName)); } if (!vector) { Debug::self()->log(QObject::tr("Error creating CSD from Kst file. Could not find Vector."), Debug::Warning); return 0; } CSDPtr csd = store->createObject(); csd->change(vector, frequency, average, removeMean, apodize, (ApodizeFunction)apodizeFunction, windowSize, length, gaussianSigma, (PSDType)outputType, vectorUnits, rateUnits); csd->setDescriptiveName(descriptiveName); csd->writeLock(); csd->registerChange(); csd->unlock(); return csd; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/histogramfactory.h000644 001750 001750 00000002224 11544160207 021360 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef HISTOGRAMFACTORY_H #define HISTOGRAMFACTORY_H #include "objectfactory.h" namespace Kst { class HistogramFactory : public ObjectFactory { public: HistogramFactory(); ~HistogramFactory(); DataObjectPtr generateObject(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/relation.cpp000644 001750 001750 00000043131 11544160207 020145 0ustar00synthsynth000000 000000 /*************************************************************************** relation.cpp: base class for a curve ------------------- begin : June 2003 copyright : (C) 2003 University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * Permission is granted to link with any opensource library * * * ***************************************************************************/ #include "relation.h" #include "datacollection.h" #include "debug.h" #include "kst_i18n.h" #include "objectstore.h" #include namespace Kst { const QString Relation::staticTypeString = I18N_NOOP("Relation"); Relation::Relation(ObjectStore *store) : Object() { Q_UNUSED(store); commonConstructor(); } void Relation::commonConstructor() { _ns_maxx = _ns_minx = _ns_maxy = _ns_miny = MaxX = MinX = MinPosX = MeanX = MaxY = MinY = MinPosY = 0.0; NS = 0; _redrawRequired = true; _ignoreAutoScale = false; _contextDetails.Lx = 0.0; _contextDetails.Hx = 0.0; _contextDetails.Ly = 0.0; _contextDetails.Hy = 0.0; _contextDetails.m_X = 0.0; _contextDetails.m_Y = 0.0; _contextDetails.b_X = 0.0; _contextDetails.b_Y = 0.0; _contextDetails.XMin = 0.0; _contextDetails.XMax = 0.0; _contextDetails.xLog = false; _contextDetails.yLog = false; _contextDetails.xLogBase = 0.0; _contextDetails.yLogBase = 0.0; _contextDetails.penWidth = 0; } Relation::~Relation() { } void Relation::save(QXmlStreamWriter &s) { Q_UNUSED(s) } void Relation::deleteDependents() { Data::self()->removeCurveFromPlots(this); } void Relation::paint(const CurveRenderContext& context) { if (redrawRequired(context) || _redrawRequired) { updatePaintObjects(context); _redrawRequired = false; } paintObjects(context); } bool Relation::redrawRequired(const CurveRenderContext& context) { if ((_contextDetails.Lx == context.Lx) && (_contextDetails.Hx == context.Hx) && (_contextDetails.Ly == context.Ly) && (_contextDetails.Hy == context.Hy) && (_contextDetails.m_X == context.m_X) && (_contextDetails.m_Y == context.m_Y) && (_contextDetails.b_X == context.b_X) && (_contextDetails.b_Y == context.b_Y) && (_contextDetails.XMin == context.XMin) && (_contextDetails.XMax == context.XMax) && (_contextDetails.xLog == context.xLog) && (_contextDetails.yLog == context.yLog) && (_contextDetails.xLogBase == context.xLogBase) && (_contextDetails.yLogBase == context.yLogBase) && (_contextDetails.penWidth == context.penWidth) ) { return false; } else { _contextDetails.Lx = context.Lx; _contextDetails.Hx = context.Hx; _contextDetails.Ly = context.Ly; _contextDetails.Hy = context.Hy; _contextDetails.m_X = context.m_X; _contextDetails.m_Y = context.m_Y; _contextDetails.b_X = context.b_X; _contextDetails.b_Y = context.b_Y; _contextDetails.XMin = context.XMin; _contextDetails.XMax = context.XMax; _contextDetails.xLog = context.xLog; _contextDetails.yLog = context.yLog; _contextDetails.xLogBase = context.xLogBase; _contextDetails.yLogBase = context.yLogBase; _contextDetails.penWidth = context.penWidth; return true; } } void Relation::setIgnoreAutoScale(bool ignoreAutoScale) { _ignoreAutoScale = ignoreAutoScale; } qint64 Relation::minInputSerial() const{ qint64 minSerial = LLONG_MAX; foreach (VectorPtr P, _inputVectors) { minSerial = qMin(minSerial, P->serial()); } foreach (ScalarPtr P, _inputScalars) { minSerial = qMin(minSerial, P->serial()); } foreach (MatrixPtr P, _inputMatrices) { minSerial = qMin(minSerial, P->serial()); } foreach (StringPtr P, _inputStrings) { minSerial = qMin(minSerial, P->serial()); } return minSerial; } qint64 Relation::minInputSerialOfLastChange() const { qint64 minSerial = LLONG_MAX; foreach (VectorPtr P, _inputVectors) { minSerial = qMin(minSerial, P->serialOfLastChange()); } foreach (ScalarPtr P, _inputScalars) { minSerial = qMin(minSerial, P->serialOfLastChange()); } foreach (MatrixPtr P, _inputMatrices) { minSerial = qMin(minSerial, P->serialOfLastChange()); } foreach (StringPtr P, _inputStrings) { minSerial = qMin(minSerial, P->serialOfLastChange()); } return minSerial; } void Relation::writeLockInputsAndOutputs() const { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << endl; #endif QList inputs; QList outputs; QList sl = _inputStrings.values(); for (QList::Iterator i = sl.begin(); i != sl.end(); ++i) { inputs += (*i).data(); } sl = _outputStrings.values(); for (QList::Iterator i = sl.begin(); i != sl.end(); ++i) { outputs += (*i).data(); } QList sc = _inputScalars.values(); for (QList::Iterator i = sc.begin(); i != sc.end(); ++i) { inputs += (*i).data(); } sc = _outputScalars.values(); for (QList::Iterator i = sc.begin(); i != sc.end(); ++i) { outputs += (*i).data(); } QList vl = _inputVectors.values(); for (QList::Iterator i = vl.begin(); i != vl.end(); ++i) { inputs += (*i).data(); } vl = _outputVectors.values(); for (QList::Iterator i = vl.begin(); i != vl.end(); ++i) { outputs += (*i).data(); } QList ml = _inputMatrices.values(); for (QList::Iterator i = ml.begin(); i != ml.end(); ++i) { inputs += (*i).data(); } ml = _outputMatrices.values(); for (QList::Iterator i = ml.begin(); i != ml.end(); ++i) { outputs += (*i).data(); } qSort(inputs); qSort(outputs); QList::ConstIterator inputIt = inputs.begin(); QList::ConstIterator outputIt = outputs.begin(); while (inputIt != inputs.end() || outputIt != outputs.end()) { if (inputIt != inputs.end() && (outputIt == outputs.end() || (void*)(*inputIt) < (void*)(*outputIt))) { // do input if (!(*inputIt)) { qWarning() << "Input for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") KstDataObject::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": write locking input \"" << (*inputIt)->Name() << "\" (" << (void*)((KstRWLock*)*inputIt) << ")" << endl; #endif (*inputIt)->writeLock(); ++inputIt; } else { // do output if (!(*outputIt)) { qWarning() << "Output for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") KstDataObject::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": write locking output \"" << (*outputIt)->Name() << "\" (" << (void*)((KstRWLock*)*outputIt) << ")" << endl; #endif if ((*outputIt)->provider() != this) { } (*outputIt)->writeLock(); ++outputIt; } } } void Relation::unlockInputsAndOutputs() const { #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << endl; #endif for (MatrixMap::ConstIterator i = _outputMatrices.begin(); i != _outputMatrices.end(); ++i) { if (!(*i)) { qWarning() << "Output matrix for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output matrix \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (MatrixMap::ConstIterator i = _inputMatrices.begin(); i != _inputMatrices.end(); ++i) { if (!(*i)) { qWarning() << "Input matrix for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input matrix \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (VectorMap::ConstIterator i = _outputVectors.begin(); i != _outputVectors.end(); ++i) { if (!(*i)) { qWarning() << "Output vector for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output vector \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (VectorMap::ConstIterator i = _inputVectors.begin(); i != _inputVectors.end(); ++i) { if (!(*i)) { qWarning() << "Input vector for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input vector \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (ScalarMap::ConstIterator i = _outputScalars.begin(); i != _outputScalars.end(); ++i) { if (!(*i)) { qWarning() << "Output scalar for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output scalar \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (ScalarMap::ConstIterator i = _inputScalars.begin(); i != _inputScalars.end(); ++i) { if (!(*i)) { qWarning() << "Input scalar for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input scalar \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (StringMap::ConstIterator i = _outputStrings.begin(); i != _outputStrings.end(); ++i) { if (!(*i)) { qWarning() << "Output string for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output string \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (StringMap::ConstIterator i = _inputStrings.begin(); i != _inputStrings.end(); ++i) { if (!(*i)) { qWarning() << "Input string for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << this->Name() << ") Relation::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input string \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } } bool Relation::uses(ObjectPtr p) const { VectorPtr v = kst_cast(p); if (v) { for (VectorMap::ConstIterator j = _inputVectors.begin(); j != _inputVectors.end(); ++j) { if (j.value() == v) { return true; } } QHashIterator scalarDictIter(v->scalars()); for (ScalarMap::ConstIterator j = _inputScalars.begin(); j != _inputScalars.end(); ++j) { while (scalarDictIter.hasNext()) { scalarDictIter.next(); if (scalarDictIter.value() == j.value()) { return true; } } } QHashIterator stringDictIter(v->strings()); for (StringMap::ConstIterator j = _inputStrings.begin(); j != _inputStrings.end(); ++j) { while (stringDictIter.hasNext()) { stringDictIter.next(); if (stringDictIter.value() == j.value()) { return true; } } } } else if (MatrixPtr matrix = kst_cast(p)) { for (MatrixMap::ConstIterator j = _inputMatrices.begin(); j != _inputMatrices.end(); ++j) { if (j.value() == matrix) { return true; } } QHashIterator scalarDictIter(matrix->scalars()); for (ScalarMap::ConstIterator j = _inputScalars.begin(); j != _inputScalars.end(); ++j) { while (scalarDictIter.hasNext()) { scalarDictIter.next(); if (scalarDictIter.value() == j.value()) { return true; } } } } else if (DataObjectPtr obj = kst_cast(p) ) { // check all connections from this object to p for (VectorMap::Iterator j = obj->outputVectors().begin(); j != obj->outputVectors().end(); ++j) { for (VectorMap::ConstIterator k = _inputVectors.begin(); k != _inputVectors.end(); ++k) { if (j.value() == k.value()) { return true; } } // also check dependencies on vector stats QHashIterator scalarDictIter(j.value()->scalars()); for (ScalarMap::ConstIterator k = _inputScalars.begin(); k != _inputScalars.end(); ++k) { while (scalarDictIter.hasNext()) { scalarDictIter.next(); if (scalarDictIter.value() == k.value()) { return true; } } } // also check dependencies on vector strings QHashIterator stringDictIter(j.value()->strings()); for (StringMap::ConstIterator k = _inputStrings.begin(); k != _inputStrings.end(); ++k) { while (stringDictIter.hasNext()) { stringDictIter.next(); if (stringDictIter.value() == k.value()) { return true; } } } } for (MatrixMap::Iterator j = obj->outputMatrices().begin(); j != obj->outputMatrices().end(); ++j) { for (MatrixMap::ConstIterator k = _inputMatrices.begin(); k != _inputMatrices.end(); ++k) { if (j.value() == k.value()) { return true; } } // also check dependencies on vector stats QHashIterator scalarDictIter(j.value()->scalars()); for (ScalarMap::ConstIterator k = _inputScalars.begin(); k != _inputScalars.end(); ++k) { while (scalarDictIter.hasNext()) { scalarDictIter.next(); if (scalarDictIter.value() == k.value()) { return true; } } } } for (ScalarMap::Iterator j = obj->outputScalars().begin(); j != obj->outputScalars().end(); ++j) { for (ScalarMap::ConstIterator k = _inputScalars.begin(); k != _inputScalars.end(); ++k) { if (j.value() == k.value()) { return true; } } } for (StringMap::Iterator j = obj->outputStrings().begin(); j != obj->outputStrings().end(); ++j) { for (StringMap::ConstIterator k = _inputStrings.begin(); k != _inputStrings.end(); ++k) { if (j.value() == k.value()) { return true; } } } } return false; } PrimitiveList Relation::inputPrimitives() const { PrimitiveList primitive_list; int n = _inputMatrices.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_inputMatrices.values().at(i))); } n = _inputStrings.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_inputStrings.values().at(i))); } n = _inputScalars.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_inputScalars.values().at(i))); } n = _inputVectors.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_inputVectors.values().at(i))); } return primitive_list; } void Relation::replaceInput(PrimitivePtr p, PrimitivePtr new_p) { if (VectorPtr v = kst_cast(p) ) { if (VectorPtr new_v = kst_cast(new_p)) { for (VectorMap::Iterator j = _inputVectors.begin(); j != _inputVectors.end(); ++j) { if (j.value() == v) { _inputVectors[j.key()] = new_v; } } } } else if (MatrixPtr m = kst_cast(p) ) { if (MatrixPtr new_m = kst_cast(new_p)) { for (MatrixMap::Iterator j = _inputMatrices.begin(); j != _inputMatrices.end(); ++j) { if (j.value() == m) { _inputMatrices[j.key()] = new_m; } } } } else if (StringPtr s = kst_cast(p) ) { if (StringPtr new_s = kst_cast(new_p)) { for (StringMap::Iterator j = _inputStrings.begin(); j != _inputStrings.end(); ++j) { if (j.value() == s) { _inputStrings[j.key()] = new_s; } } } } else if (ScalarPtr s = kst_cast(p) ) { if (ScalarPtr new_s = kst_cast(new_p)) { for (ScalarMap::Iterator j = _inputScalars.begin(); j != _inputScalars.end(); ++j) { if (j.value() == s) { _inputScalars[j.key()] = new_s; } } } } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/plotdefines.h000644 001750 001750 00000005470 11544160207 020315 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2004 by University of British Columbia * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLOTDEFINES_H #define PLOTDEFINES_H #define MARKER_LABEL_PRECISION 15 #include "kst_i18n.h" enum AxisInterpretationType { AXIS_INTERP_YEAR, AXIS_INTERP_CTIME, AXIS_INTERP_JD, AXIS_INTERP_MJD, AXIS_INTERP_RJD, AXIS_INTERP_AIT }; enum AxisDisplayType { AXIS_DISPLAY_YEAR, AXIS_DISPLAY_YYMMDDHHMMSS_SS, AXIS_DISPLAY_DDMMYYHHMMSS_SS, AXIS_DISPLAY_QTTEXTDATEHHMMSS_SS, AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS, AXIS_DISPLAY_JD, AXIS_DISPLAY_MJD, AXIS_DISPLAY_RJD }; struct AxisInterpretation { const char *label; AxisInterpretationType type; }; struct AxisDisplay { const char *label; AxisDisplayType type; }; const AxisInterpretation AxisInterpretations[] = { { I18N_NOOP("Julian Year"), AXIS_INTERP_YEAR }, { I18N_NOOP("Standard C time"), AXIS_INTERP_CTIME }, { I18N_NOOP2("Julian Date", "JD"), AXIS_INTERP_JD }, { I18N_NOOP2("Modified Julian Date", "MJD"), AXIS_INTERP_MJD }, { I18N_NOOP2("Reduced Julian Date", "RJD"), AXIS_INTERP_RJD }, { I18N_NOOP2("Temps Atomique International", "TAI"), AXIS_INTERP_AIT } }; const AxisDisplay AxisDisplays[] = { { I18N_NOOP("Julian Year"), AXIS_DISPLAY_YEAR }, { I18N_NOOP("YYYY/MM/DD HH:MM:SS.SS"), AXIS_DISPLAY_YYMMDDHHMMSS_SS }, { I18N_NOOP("DD/MM/YYYY HH:MM:SS.SS"), AXIS_DISPLAY_DDMMYYHHMMSS_SS }, { I18N_NOOP(" HH:MM:SS.SS"), AXIS_DISPLAY_QTTEXTDATEHHMMSS_SS }, { I18N_NOOP(" HH:MM:SS.SS"), AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS }, { I18N_NOOP2("Julian Date", "JD"), AXIS_DISPLAY_JD }, { I18N_NOOP2("Modified Julian Date", "MJD"), AXIS_DISPLAY_MJD }, { I18N_NOOP2("Reduced Julian Date", "RJD"), AXIS_DISPLAY_RJD } }; const unsigned int numAxisInterpretations = sizeof( AxisInterpretations ) / sizeof( AxisInterpretation ); const unsigned int numAxisDisplays = sizeof( AxisDisplays ) / sizeof( AxisDisplay ); #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/basicpluginfactory.cpp000644 001750 001750 00000013065 11544160207 022223 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "basicpluginfactory.h" #include "debug.h" #include "basicplugin.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { BasicPluginFactory::BasicPluginFactory() : ObjectFactory() { registerFactory(BasicPlugin::staticTypeTag, this); } BasicPluginFactory::~BasicPluginFactory() { } DataObjectPtr BasicPluginFactory::generateObject(ObjectStore *store, QXmlStreamReader& xml) { Q_ASSERT(store); DataObjectConfigWidget* configWidget; QString pluginName; BasicPluginPtr dataObject; bool validTag; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == BasicPlugin::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); pluginName = attrs.value("type").toString(); Object::processShortNameIndexAttributes(attrs); configWidget = DataObject::pluginWidget(pluginName); if (configWidget) { if (!configWidget->configurePropertiesFromXml(store, attrs) ) { Debug::self()->log(QObject::tr("Error unable to create data object from plugin"), Debug::Warning); return 0; } else { if (xml.isEndElement() && n == BasicPlugin::staticTypeTag) { break; } } } else { Debug::self()->log(QObject::tr("Error unable to find plugin for data object"), Debug::Warning); return 0; } dataObject = kst_cast(DataObject::createPlugin(pluginName, store, configWidget, false)); QString expectedEnd; while (!(xml.isEndElement() && (xml.name().toString() == BasicPlugin::staticTypeTag))) { if (xml.isStartElement() && xml.name().toString() == "inputvector") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString type = attrs.value("type").toString(); QString tagName = attrs.value("tag").toString(); VectorPtr vector = kst_cast(store->retrieveObject(tagName)); if (vector) { dataObject->setInputVector(type, vector); } } else if (xml.isStartElement() && xml.name().toString() == "inputscalar") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString type = attrs.value("type").toString(); QString tagName = attrs.value("tag").toString(); ScalarPtr scalar = kst_cast(store->retrieveObject(tagName)); if (scalar) { dataObject->setInputScalar(type, scalar); } } else if (xml.isStartElement() && xml.name().toString() == "inputstring") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString type = attrs.value("type").toString(); QString tagName = attrs.value("tag").toString(); StringPtr string = kst_cast(store->retrieveObject(tagName)); if (string) { dataObject->setInputString(type, string); } } else if (xml.isStartElement() && xml.name().toString() == "outputvector") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString type = attrs.value("type").toString(); QString tagName = attrs.value("tag").toString(); dataObject->setOutputVector(type, tagName); } else if (xml.isStartElement() && xml.name().toString() == "outputscalar") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString type = attrs.value("type").toString(); QString tagName = attrs.value("tag").toString(); dataObject->setOutputScalar(type, tagName); } else if (xml.isStartElement() && xml.name().toString() == "outputstring") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString type = attrs.value("type").toString(); QString tagName = attrs.value("tag").toString(); dataObject->setOutputString(type, tagName); } else if (xml.isEndElement()) { if (xml.name().toString() != expectedEnd) { validTag = false; break; } } xml.readNext(); } } else { return 0; } } if (xml.isEndElement()) { if (n == BasicPlugin::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating Plugin Object from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } dataObject->writeLock(); dataObject->registerChange(); dataObject->unlock(); return dataObject; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/histogram.h000644 001750 001750 00000010146 11544160207 017772 0ustar00synthsynth000000 000000 /*************************************************************************** histogram.h: Histogram for KST ------------------- begin : Wed July 11 2002 copyright : (C) 2002 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A class for handling power spectra for kst *@author C. Barth Netterfield */ #ifndef HISTOGRAM_H #define HISTOGRAM_H #include "dataobject.h" #include "kstmath_export.h" namespace Kst { class ObjectStore; class KSTMATH_EXPORT Histogram : public DataObject { Q_OBJECT public: enum NormalizationType { Number, Percent, Fraction, MaximumOne}; public: static const QString staticTypeString; const QString& typeString() const { return staticTypeString; } static const QString staticTypeTag; virtual void internalUpdate(); virtual void save(QXmlStreamWriter &xml); virtual QString propertyString() const; int numberOfBins() const; void setNumberOfBins(int in_n_bins); void setXRange(double xmin_in, double xmax_in); void setVector(VectorPtr); VectorPtr vector() const; bool isNormalizationNumber() const { return _NormalizationMode == Number; } void setIsNormalizationNumber() { _NormalizationMode = Number; } bool isNormalizationPercent() const { return _NormalizationMode == Percent; } void setIsNormalizationPercent() { _NormalizationMode = Percent; } bool isNormalizationFraction() const { return _NormalizationMode == Fraction; } void setIsNormalizationFraction() { _NormalizationMode = Fraction; } bool isNormalizationMaximumOne() const { return _NormalizationMode == MaximumOne; } void setIsNormNormalizationMaximumOne() { _NormalizationMode = MaximumOne; } void setNormalizationType(NormalizationType normType) { _NormalizationMode = normType; } NormalizationType normalizationType() const { return _NormalizationMode; } static void AutoBin(const VectorPtr, int *n, double *max, double *min); virtual void showNewDialog(); virtual void showEditDialog(); virtual bool slaveVectorsUsed() const; void setRealTimeAutoBin(bool autobin); bool realTimeAutoBin() const; VectorPtr vX() const { return _bVector; } VectorPtr vY() const { return _hVector; } double xMin() const { return _MinX; } double xMax() const { return _MaxX; } double width() const { return _W; } double vMax() const; double vMin() const; int vNumSamples() const; virtual DataObjectPtr makeDuplicate() const; virtual QString descriptionTip() const; void change(VectorPtr in_V, double xmin_in, double xmax_in, int in_n_bins, NormalizationType new_norm_in, bool realTimeAutoBin = false); protected: Histogram(ObjectStore *store); virtual ~Histogram(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); private: NormalizationType _NormalizationMode; VectorPtr _bVector, _hVector; double _MaxX; double _MinX; int _NS; int _NumberOfBins; unsigned long *_Bins; double _Normalization; double _W; bool _realTimeAutoBin; void internalSetNumberOfBins(int in_n_bins); void internalSetXRange(double xmin_in, double xmax_in); }; typedef SharedPtr HistogramPtr; typedef ObjectList HistogramList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/eventmonitorfactory.h000644 001750 001750 00000002243 11544160207 022115 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EVENTMONITORFACTORY_H #define EVENTMONITORFACTORY_H #include "objectfactory.h" namespace Kst { class EventMonitorFactory : public ObjectFactory { public: EventMonitorFactory(); ~EventMonitorFactory(); DataObjectPtr generateObject(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/kstmath_export.h000644 001750 001750 00000002221 11544160207 021044 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_MATH_EXPORT_H #define KST_MATH_EXPORT_H #include #if (defined(Q_OS_WIN32) || defined(Q_OS_WIN64)) # if defined(BUILD_KSTMATH) # define KSTMATH_EXPORT Q_DECL_EXPORT # else # define KSTMATH_EXPORT Q_DECL_IMPORT # endif #else # define KSTMATH_EXPORT #endif #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/dataobject.cpp000644 001750 001750 00000061563 11544160207 020441 0ustar00synthsynth000000 000000 /*************************************************************************** dataobject.cpp: base class for data objects ------------------- begin : May 20, 2003 copyright : (C) 2003 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dataobject.h" #include "datacollection.h" #include "dataobjectplugin.h" #include "debug.h" #include "kst_i18n.h" #include "objectstore.h" #include "relation.h" #include "sharedptr.h" #include "primitive.h" #include #include #include #include #include #include #include #include #include #include //#define LOCKTRACE namespace Kst { QSettings DataObject::settingsObject("kst", "data"); QMap DataObject::url_map; void DataObject::init() { initPlugins(); } DataObject::DataObject(ObjectStore *store) : Object() { Q_UNUSED(store); _curveHints = new CurveHintList; } DataObject::~DataObject() { delete _curveHints; } static DataObjectPluginList _pluginList; void DataObject::cleanupForExit() { _pluginList.clear(); //FIXME? } void DataObject::attach() { } void DataObject::replaceInput(PrimitivePtr p, PrimitivePtr new_p) { if (VectorPtr v = kst_cast(p) ) { if (VectorPtr new_v = kst_cast(new_p)) { for (VectorMap::Iterator j = _inputVectors.begin(); j != _inputVectors.end(); ++j) { if (j.value() == v) { _inputVectors[j.key()] = new_v; } } } } else if (MatrixPtr m = kst_cast(p) ) { if (MatrixPtr new_m = kst_cast(new_p)) { for (MatrixMap::Iterator j = _inputMatrices.begin(); j != _inputMatrices.end(); ++j) { if (j.value() == m) { _inputMatrices[j.key()] = new_m; } } } } else if (StringPtr s = kst_cast(p) ) { if (StringPtr new_s = kst_cast(new_p)) { for (StringMap::Iterator j = _inputStrings.begin(); j != _inputStrings.end(); ++j) { if (j.value() == s) { _inputStrings[j.key()] = new_s; } } } } else if (ScalarPtr s = kst_cast(p) ) { if (ScalarPtr new_s = kst_cast(new_p)) { for (ScalarMap::Iterator j = _inputScalars.begin(); j != _inputScalars.end(); ++j) { if (j.value() == s) { _inputScalars[j.key()] = new_s; } } } } } PrimitiveList DataObject::inputPrimitives() const { PrimitiveList primitive_list; int n = _inputMatrices.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_inputMatrices.values().at(i))); } n = _inputStrings.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_inputStrings.values().at(i))); } n = _inputScalars.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_inputScalars.values().at(i))); } n = _inputVectors.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_inputVectors.values().at(i))); } return primitive_list; } PrimitiveList DataObject::outputPrimitives(bool include_decendants) const { PrimitiveList primitive_list; int n = _outputMatrices.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_outputMatrices.values().at(i))); if (include_decendants) { primitive_list.append(_outputMatrices.values().at(i)->outputPrimitives()); } } n = _outputStrings.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_outputStrings.values().at(i))); if (include_decendants) { primitive_list.append(_outputStrings.values().at(i)->outputPrimitives()); } } n = _outputScalars.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_outputScalars.values().at(i))); if (include_decendants) { primitive_list.append(_outputScalars.values().at(i)->outputPrimitives()); } } n = _outputVectors.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_outputVectors.values().at(i))); if (include_decendants) { primitive_list.append(_outputVectors.values().at(i)->outputPrimitives()); } } return primitive_list; } // Scans for plugins and stores the information for them void DataObject::scanPlugins() { Debug::self()->log(i18n("Scanning for data-object plugins.")); _pluginList.clear(); //FIXME? DataObjectPluginList tmpList; Debug::self()->log(i18n("Scanning for data-object plugins.")); foreach (QObject *plugin, QPluginLoader::staticInstances()) { //try a cast if (DataObjectPluginInterface *basicPlugin = dynamic_cast(plugin)) { tmpList.append(basicPlugin); } } QStringList pluginPaths = pluginSearchPaths(); foreach (QString pluginPath, pluginPaths) { QDir d(pluginPath); foreach (QString fileName, d.entryList(QDir::Files)) { QPluginLoader loader(d.absoluteFilePath(fileName)); QObject *plugin = loader.instance(); if (plugin) { if (DataObjectPluginInterface *dataObjectPlugin = dynamic_cast(plugin)) { tmpList.append(dataObjectPlugin); Debug::self()->log(QString("Plugin loaded: %1").arg(fileName)); } } } } // This cleans up plugins that have been uninstalled and adds in new ones. // Since it is a shared pointer it can't dangle anywhere. _pluginList.clear(); _pluginList = tmpList; } void DataObject::initPlugins() { if (_pluginList.isEmpty()) { scanPlugins(); } } QStringList DataObject::pluginList() { // Ensure state. When using kstapp MainWindow calls init. init(); QStringList plugins; for (DataObjectPluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { plugins += (*it)->pluginName(); } return plugins; } QStringList DataObject::dataObjectPluginList() { // Ensure state. When using kstapp MainWindow calls init. init(); QStringList plugins; for (DataObjectPluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { if ((*it)->pluginType() == DataObjectPluginInterface::Generic) { plugins += (*it)->pluginName(); } } plugins.sort(); return plugins; } QStringList DataObject::filterPluginList() { // Ensure state. When using kstapp MainWindow calls init. init(); QStringList plugins; for (DataObjectPluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { if ((*it)->pluginType() == DataObjectPluginInterface::Filter) { plugins += (*it)->pluginName(); } } plugins.sort(); return plugins; } QStringList DataObject::fitsPluginList() { // Ensure state. When using kstapp MainWindow calls init. init(); QStringList plugins; for (DataObjectPluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { if ((*it)->pluginType() == DataObjectPluginInterface::Fit) { plugins += (*it)->pluginName(); } } plugins.sort(); return plugins; } DataObjectConfigWidget* DataObject::pluginWidget(const QString& name) { // Ensure state. When using kstapp MainWindow calls init. init(); for (DataObjectPluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { if ((*it)->pluginName() == name) { if ((*it)->hasConfigWidget()) { return (*it)->configWidget(&settingsObject); } break; } } return 0L; } QString DataObject::pluginDescription(const QString& name) { // Ensure state. When using kstapp MainWindow calls init. init(); for (DataObjectPluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { if ((*it)->pluginName() == name) { return (*it)->pluginDescription(); } } return QString(); } int DataObject::pluginType(const QString& name) { // Ensure state. When using kstapp MainWindow calls init. init(); for (DataObjectPluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { if ((*it)->pluginName() == name) { return (*it)->pluginType(); } } return -1; } DataObjectPtr DataObject::createPlugin(const QString& name, ObjectStore *store, DataObjectConfigWidget *configWidget, bool setupInputsOutputs) { // Ensure state. When using kstapp MainWindow calls init. init(); for (DataObjectPluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { if ((*it)->pluginName() == name) { if (DataObjectPtr object = (*it)->create(store, configWidget, setupInputsOutputs)) { return object; } } } #if 0 KService::List sl = KServiceTypeTrader::self()->query("Kst Data Object"); for (KService::List::ConstIterator it = sl.begin(); it != sl.end(); ++it) { if ((*it)->name() != name) { continue; } else if (DataObjectPtr object = createPlugin(*it)) { return object; } } #endif return 0L; } double *DataObject::vectorRealloced(VectorPtr v, double *memptr, int newSize) const { if (!v) { return 0L; } // One would think this needs special locking, but it results in deadlock // in complicated object hierarchies such as filtered vectors. Therefore if // you call vectorRealloced() and v is not locked by you already, you'd // better lock it! return v->realloced(memptr, newSize); } void DataObject::load(const QXmlStreamReader &e) { qDebug() << QString("FIXME! Loading of %1 is not implemented yet.").arg(typeString()) << endl; Q_UNUSED(e) } void DataObject::save(QXmlStreamWriter& ts) { qDebug() << QString("FIXME! Saving of %1 is not implemented yet.").arg(typeString()) << endl; Q_UNUSED(ts) } int DataObject::getUsage() const { int rc = 0; for (VectorMap::ConstIterator i = _outputVectors.begin(); i != _outputVectors.end(); ++i) { if (i.value().data()) { rc += i.value()->getUsage() - 1; } } for (ScalarMap::ConstIterator i = _outputScalars.begin(); i != _outputScalars.end(); ++i) { if (i.value().data()) { rc += i.value()->getUsage() - 1; } } for (StringMap::ConstIterator i = _outputStrings.begin(); i != _outputStrings.end(); ++i) { if (i.value().data()) { rc += i.value()->getUsage() - 1; } } for (MatrixMap::ConstIterator i = _outputMatrices.begin(); i != _outputMatrices.end(); ++i) { if (i.value().data()) { rc += i.value()->getUsage() - 1; } } return Object::getUsage() + rc; } void DataObject::showDialog(bool isNew) { if (isNew) { QTimer::singleShot(0, this, SLOT(showNewDialog())); } else { QTimer::singleShot(0, this, SLOT(showEditDialog())); } } void DataObject::readLock() const { #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::readLock() by tid=" << (int)QThread::currentThread() << ": read locking myself" << endl; #endif Object::readLock(); } void DataObject::writeLock() const { #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::writeLock() by tid=" << (int)QThread::currentThread() << ": write locking myself" << endl; #endif Object::writeLock(); } void DataObject::unlock() const { #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlock() by tid=" << (int)QThread::currentThread() << ": unlocking myself" << endl; #endif Object::unlock(); } void DataObject::writeLockInputsAndOutputs() const { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << endl; #endif QList inputs; QList outputs; QList sl = _inputStrings.values(); for (QList::Iterator i = sl.begin(); i != sl.end(); ++i) { inputs += (*i).data(); } sl = _outputStrings.values(); for (QList::Iterator i = sl.begin(); i != sl.end(); ++i) { outputs += (*i).data(); } QList sc = _inputScalars.values(); for (QList::Iterator i = sc.begin(); i != sc.end(); ++i) { inputs += (*i).data(); } sc = _outputScalars.values(); for (QList::Iterator i = sc.begin(); i != sc.end(); ++i) { outputs += (*i).data(); } QList vl = _inputVectors.values(); for (QList::Iterator i = vl.begin(); i != vl.end(); ++i) { inputs += (*i).data(); } vl = _outputVectors.values(); for (QList::Iterator i = vl.begin(); i != vl.end(); ++i) { outputs += (*i).data(); } QList ml = _inputMatrices.values(); for (QList::Iterator i = ml.begin(); i != ml.end(); ++i) { inputs += (*i).data(); } ml = _outputMatrices.values(); for (QList::Iterator i = ml.begin(); i != ml.end(); ++i) { outputs += (*i).data(); } qSort(inputs); qSort(outputs); QList::ConstIterator inputIt = inputs.begin(); QList::ConstIterator outputIt = outputs.begin(); while (inputIt != inputs.end() || outputIt != outputs.end()) { if (inputIt != inputs.end() && (outputIt == outputs.end() || (void*)(*inputIt) < (void*)(*outputIt))) { // do input if (!(*inputIt)) { qWarning() << "Input for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": write locking input \"" << (*inputIt)->Name() << "\" (" << (void*)((KstRWLock*)*inputIt) << ")" << endl; #endif (*inputIt)->writeLock(); ++inputIt; } else { // do output if (!(*outputIt)) { qWarning() << "Output for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::writeLockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": write locking output \"" << (*outputIt)->Name() << "\" (" << (void*)((KstRWLock*)*outputIt) << ")" << endl; #endif if ((*outputIt)->provider() != this) { Debug::self()->log(i18n("(%1) DataObject::writeLockInputsAndOutputs() by tid=%2: write locking output %3 (not provider) -- this is probably an error. Please email kst@kde.org with details.").arg(this->type()).arg(reinterpret_cast(QThread::currentThread())).arg((*outputIt)->Name()), Debug::Error); } (*outputIt)->writeLock(); ++outputIt; } } } void DataObject::unlockInputsAndOutputs() const { #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << endl; #endif for (MatrixMap::ConstIterator i = _outputMatrices.begin(); i != _outputMatrices.end(); ++i) { if (!(*i)) { qWarning() << "Output matrix for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output matrix \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (MatrixMap::ConstIterator i = _inputMatrices.begin(); i != _inputMatrices.end(); ++i) { if (!(*i)) { qWarning() << "Input matrix for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input matrix \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (VectorMap::ConstIterator i = _outputVectors.begin(); i != _outputVectors.end(); ++i) { if (!(*i)) { qWarning() << "Output vector for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output vector \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (VectorMap::ConstIterator i = _inputVectors.begin(); i != _inputVectors.end(); ++i) { if (!(*i)) { qWarning() << "Input vector for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input vector \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (ScalarMap::ConstIterator i = _outputScalars.begin(); i != _outputScalars.end(); ++i) { if (!(*i)) { qWarning() << "Output scalar for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output scalar \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (ScalarMap::ConstIterator i = _inputScalars.begin(); i != _inputScalars.end(); ++i) { if (!(*i)) { qWarning() << "Input scalar for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input scalar \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (StringMap::ConstIterator i = _outputStrings.begin(); i != _outputStrings.end(); ++i) { if (!(*i)) { qWarning() << "Output string for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking output string \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } for (StringMap::ConstIterator i = _inputStrings.begin(); i != _inputStrings.end(); ++i) { if (!(*i)) { qWarning() << "Input string for data object " << this->Name() << " is invalid." << endl; } #ifdef LOCKTRACE qDebug() << (void*)this << " (" << this->type() << ": " << this->Name() << ") DataObject::unlockInputsAndOutputs() by tid=" << (int)QThread::currentThread() << ": unlocking input string \"" << (*i)->Name() << "\" (" << (void*)((KstRWLock*)*i) << ")" << endl; #endif (*i)->unlock(); } } bool DataObject::isValid() const { return true; } const CurveHintList* DataObject::curveHints() const { return _curveHints; } void DataObject::deleteDependents() { DataObjectList dataObjects = _store->getObjects(); foreach (DataObjectPtr object, dataObjects) { bool usesObject = object->uses(this); if (!usesObject) { for (VectorMap::Iterator j = _outputVectors.begin(); !usesObject && j != _outputVectors.end(); ++j) { usesObject = object->uses(j.value().data()); } for (ScalarMap::Iterator j = _outputScalars.begin(); !usesObject && j != _outputScalars.end(); ++j) { usesObject = object->uses(j.value().data()); } for (StringMap::Iterator j = _outputStrings.begin(); !usesObject && j != _outputStrings.end(); ++j) { usesObject = object->uses(j.value().data()); } for (MatrixMap::Iterator j = _outputMatrices.begin(); !usesObject && j != _outputMatrices.end(); ++j) { usesObject = object->uses(j.value().data()); } } if (usesObject) { _store->removeObject(object); } } RelationList relations = _store->getObjects(); foreach (RelationPtr relation, relations) { bool usesRelation = relation->uses(this); if (!usesRelation) { for (VectorMap::Iterator j = _outputVectors.begin(); !usesRelation && j != _outputVectors.end(); ++j) { usesRelation = relation->uses(j.value().data()); } for (ScalarMap::Iterator j = _outputScalars.begin(); !usesRelation && j != _outputScalars.end(); ++j) { usesRelation = relation->uses(j.value().data()); } for (StringMap::Iterator j = _outputStrings.begin(); !usesRelation && j != _outputStrings.end(); ++j) { usesRelation = relation->uses(j.value().data()); } for (MatrixMap::Iterator j = _outputMatrices.begin(); !usesRelation && j != _outputMatrices.end(); ++j) { usesRelation = relation->uses(j.value().data()); } } if (usesRelation) { _store->removeObject(relation); } } foreach (VectorPtr vector, _outputVectors) { _store->removeObject(vector); } foreach (MatrixPtr matrix, _outputMatrices) { _store->removeObject(matrix); } foreach (ScalarPtr scalar, _outputScalars) { _store->removeObject(scalar); } foreach (StringPtr string, _outputStrings) { _store->removeObject(string); } } bool DataObject::uses(ObjectPtr p) const { PrimitiveList this_input_primitives; PrimitiveList p_output_primitives; this_input_primitives = inputPrimitives(); PrimitivePtr p_prim = kst_cast(p); DataObjectPtr p_dobj = kst_cast(p); if (p_prim) { p_output_primitives = p_prim->outputPrimitives(); p_output_primitives << p_prim; // include the object itself. } else if (p_dobj) { p_output_primitives = p_dobj->outputPrimitives(); } else { p_output_primitives.clear(); } // now check if any of this's input primitives are one of p's output primitives... int n_in = this_input_primitives.count(); for (int i_in = 0; i_inserial()); } foreach (ScalarPtr P, _inputScalars) { minSerial = qMin(minSerial, P->serial()); } foreach (MatrixPtr P, _inputMatrices) { minSerial = qMin(minSerial, P->serial()); } foreach (StringPtr P, _inputStrings) { minSerial = qMin(minSerial, P->serial()); } return minSerial; } qint64 DataObject::minInputSerialOfLastChange() const { qint64 minSerial = LLONG_MAX; foreach (VectorPtr P, _inputVectors) { minSerial = qMin(minSerial, P->serialOfLastChange()); } foreach (ScalarPtr P, _inputScalars) { minSerial = qMin(minSerial, P->serialOfLastChange()); } foreach (MatrixPtr P, _inputMatrices) { minSerial = qMin(minSerial, P->serialOfLastChange()); } foreach (StringPtr P, _inputStrings) { minSerial = qMin(minSerial, P->serialOfLastChange()); } return minSerial; } ///////////////////////////////////////////////////////////////////////////// DataObjectConfigWidget::DataObjectConfigWidget(QSettings *cfg) : QWidget(0L), _cfg(cfg) { } DataObjectConfigWidget::~DataObjectConfigWidget() { } void DataObjectConfigWidget::save() { } void DataObjectConfigWidget::load() { } void DataObjectConfigWidget::setObjectStore(ObjectStore* store) { Q_UNUSED(store); } void DataObjectConfigWidget::setupFromObject(Object* dataObject) { Q_UNUSED(dataObject); } void DataObjectConfigWidget::setVectorX(VectorPtr vector) { Q_UNUSED(vector); } void DataObjectConfigWidget::setVectorY(VectorPtr vector) { Q_UNUSED(vector); } void DataObjectConfigWidget::setupSlots(QWidget* dialog) { Q_UNUSED(dialog); } void DataObjectConfigWidget::setVectorsLocked(bool locked) { Q_UNUSED(locked); } bool DataObjectConfigWidget::configurePropertiesFromXml(ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); return true; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/emailthread.h000644 001750 001750 00000004336 11544160207 020260 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EMAILTHREAD_H #define EMAILTHREAD_H #include "settings.h" namespace Kst { class EMailThread : public QObject { Q_OBJECT public: EMailThread( const QString& strTo, const QString& strSubject, const QString& strBody ); EMailThread( const QString& strTo, const QString& strSubject, const QString& strBody, const QString& strFrom, const QString& strSMTPServer, const int iPort = 25, const EMailEncryption encryption = EMailEncryptionNone, const QString& strUsername = QString::null, const QString& strPassword = QString::null, const EMailAuthentication authentication = EMailAuthenticationPLAIN, const bool useAuthentication = false ); virtual ~EMailThread(); void send(); QString _strFrom; QString _strTo; QString _strBody; QString _strSubject; QString _strSMTPServer; QString _strMessage; QString _strUsername; QString _strPassword; bool _useAuthentication; int _iPort; EMailEncryption _encryption; EMailAuthentication _authentication; bool _sendOk; uint _bodyLength; uint _bodyOffset; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/builtinrelations.h000644 001750 001750 00000002031 11544160207 021356 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUILTINRELATIONS_H #define BUILTINRELATIONS_H #include "kstmath_export.h" namespace Kst { namespace Builtins { KSTMATH_EXPORT void initRelations(); } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/settings.cpp000644 001750 001750 00000026124 11544160207 020173 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2003 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "timezones.h" #include #include // application specific includes #include "settings.h" namespace Kst { Settings::Settings() { plotUpdateTimer = 200; plotFontSize = 12; plotFontMinSize = 5; backgroundColor = QColor(255, 255, 255); // white foregroundColor = QColor(0,0,0); // black promptWindowClose = true; showQuickStart = true; tiedZoomGlobal = false; curveColorSequencePalette = "Kst Colors"; xMajor = false; yMajor = false; xMinor = false; yMinor = false; majorColor = QColor(128,128,128); minorColor = QColor(128,128,128); majorGridColorDefault = true; minorGridColorDefault = true; xAxisInterpret = false; xAxisInterpretation = AXIS_INTERP_CTIME; xAxisDisplay = AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS; yAxisInterpret = false; yAxisInterpretation = AXIS_INTERP_CTIME; yAxisDisplay = AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS; defaultLineWeight = 0; timezone = "UTC"; offsetSeconds = 0; setPrintingDefaults(); } Settings::Settings(const Settings& x) { *this = x; } Settings& Settings::operator=(const Settings& x) { plotUpdateTimer = x.plotUpdateTimer; plotFontSize = x.plotFontSize; plotFontMinSize = x.plotFontMinSize; backgroundColor = x.backgroundColor; foregroundColor = x.foregroundColor; promptWindowClose = x.promptWindowClose; showQuickStart = x.showQuickStart; tiedZoomGlobal = x.tiedZoomGlobal; curveColorSequencePalette = x.curveColorSequencePalette; timezone = x.timezone; offsetSeconds = x.offsetSeconds; xMajor = x.xMajor; yMajor = x.yMajor; xMinor = x.xMinor; yMinor = x.yMinor; majorColor = x.majorColor; minorColor = x.minorColor; majorGridColorDefault = x.majorGridColorDefault; minorGridColorDefault = x.minorGridColorDefault; xAxisInterpret = x.xAxisInterpret; xAxisInterpretation = x.xAxisInterpretation; xAxisDisplay = x.xAxisDisplay; yAxisInterpret = x.yAxisInterpret; yAxisInterpretation = x.yAxisInterpretation; yAxisDisplay = x.yAxisDisplay; defaultLineWeight = x.defaultLineWeight; printing.pageSize = x.printing.pageSize; printing.orientation = x.printing.orientation; printing.plotDateTimeFooter = x.printing.plotDateTimeFooter; printing.maintainAspect = x.printing.maintainAspect; printing.curveWidthAdjust = x.printing.curveWidthAdjust; printing.monochrome = x.printing.monochrome; printing.monochromeSettings.enhanceReadability = x.printing.monochromeSettings.enhanceReadability; printing.monochromeSettings.pointStyleOrder = x.printing.monochromeSettings.pointStyleOrder; printing.monochromeSettings.lineStyleOrder = x.printing.monochromeSettings.lineStyleOrder; printing.monochromeSettings.lineWidthOrder = x.printing.monochromeSettings.lineWidthOrder; printing.monochromeSettings.maxLineWidth = x.printing.monochromeSettings.maxLineWidth; printing.monochromeSettings.pointDensity = x.printing.monochromeSettings.pointDensity; return *this; } Settings *Settings::_self = 0L; void Settings::cleanup() { delete _self; _self = 0; } Settings *Settings::globalSettings() { if (!_self) { _self = new Settings; qAddPostRoutine(Settings::cleanup); _self->reload(); } return _self; } void Settings::setGlobalSettings(const Settings *settings) { globalSettings(); // force instantiation *_self = *settings; } void Settings::save() { QSettings cfg(QString("kstrc")); cfg.beginGroup("Kst"); cfg.setValue("Plot Update Timer", qlonglong(plotUpdateTimer)); cfg.setValue("Plot Font Size", qlonglong(plotFontSize)); cfg.setValue("Plot Font Min Size", qlonglong(plotFontMinSize)); cfg.setValue("Background Color", backgroundColor); cfg.setValue("Foreground Color", foregroundColor); cfg.setValue("Prompt on Window Close", promptWindowClose); cfg.setValue("Show QuickStart", showQuickStart); cfg.setValue("Tied-zoom Global", tiedZoomGlobal); cfg.setValue("Curve Color Sequence", curveColorSequencePalette); cfg.setValue("Timezone", timezone); cfg.setValue("OffsetSeconds", offsetSeconds); cfg.endGroup(); cfg.beginGroup("Grid Lines"); cfg.setValue("X Major", xMajor); cfg.setValue("Y Major", yMajor); cfg.setValue("X Minor", xMinor); cfg.setValue("Y Minor", yMinor); cfg.setValue("Major Color", majorColor); cfg.setValue("Minor Color", minorColor); cfg.setValue("Default Major Color", majorGridColorDefault); cfg.setValue("Default Minor Color", minorGridColorDefault); cfg.endGroup(); cfg.beginGroup("X Axis"); cfg.setValue("Interpret", xAxisInterpret); cfg.setValue("Interpretation", int(xAxisInterpretation)); cfg.setValue("Display", int(xAxisDisplay)); cfg.endGroup(); cfg.beginGroup("Y Axis"); cfg.setValue("Interpret", yAxisInterpret); cfg.setValue("Interpretation", int(yAxisInterpretation)); cfg.setValue("Display", int(yAxisDisplay)); cfg.endGroup(); cfg.beginGroup("Curve"); cfg.setValue("DefaultLineWeight", defaultLineWeight); cfg.endGroup(); cfg.beginGroup("Printing"); cfg.setValue("kde-pagesize", printing.pageSize); cfg.setValue("kde-orientation", printing.orientation); cfg.setValue("kst-plot-datetime-footer", printing.plotDateTimeFooter); cfg.setValue("kst-plot-maintain-aspect-ratio", printing.maintainAspect); cfg.setValue("kst-plot-curve-width-adjust", printing.curveWidthAdjust); cfg.setValue("kst-plot-monochrome", printing.monochrome); cfg.setValue("kst-plot-monochromesettings-enhancereadability", printing.monochromeSettings.enhanceReadability); cfg.setValue("kst-plot-monochromesettings-pointstyleorder", printing.monochromeSettings.pointStyleOrder); cfg.setValue("kst-plot-monochromesettings-linestyleorder", printing.monochromeSettings.lineStyleOrder); cfg.setValue("kst-plot-monochromesettings-linewidthorder", printing.monochromeSettings.lineWidthOrder); cfg.setValue("kst-plot-monochromesettings-maxlinewidth", printing.monochromeSettings.maxLineWidth); cfg.setValue("kst-plot-monochromesettings-pointdensity", printing.monochromeSettings.pointDensity); cfg.endGroup(); cfg.sync(); } void Settings::reload() { QSettings cfg("kstrc"); cfg.beginGroup("Kst"); plotUpdateTimer = cfg.value("Plot Update Timer", 200).toInt(); plotFontSize = cfg.value("Plot Font Size", 12).toInt(); plotFontMinSize = cfg.value("Plot Font Min Size", 5).toInt(); backgroundColor = cfg.value("Background Color", backgroundColor).value(); foregroundColor = cfg.value("Foreground Color", foregroundColor).value(); promptWindowClose = cfg.value("Prompt on Window Close", true).toBool(); showQuickStart = cfg.value("Show QuickStart", true).toBool(); tiedZoomGlobal = cfg.value("Tied-zoom Global", true).toBool(); curveColorSequencePalette = cfg.value("Curve Color Sequence", "Kst Colors").toString(); timezone = cfg.value("Timezone", "UTC").toString(); offsetSeconds = cfg.value("OffsetSeconds", 0).toBool(); cfg.endGroup(); cfg.beginGroup("Grid Lines"); xMajor = cfg.value("X Major", false).toBool(); yMajor = cfg.value("Y Major", false).toBool(); xMinor = cfg.value("X Minor", false).toBool(); yMinor = cfg.value("Y Minor", false).toBool(); majorColor = cfg.value("Major Color", majorColor).value(); minorColor = cfg.value("Minor Color", minorColor).value(); majorGridColorDefault = cfg.value("Default Major Color", true).toBool(); minorGridColorDefault = cfg.value("Default Minor Color", true).toBool(); cfg.endGroup(); cfg.beginGroup("X Axis"); xAxisInterpret = cfg.value("Interpret", false).toBool(); xAxisInterpretation = (AxisInterpretationType)cfg.value("Interpretation", (int)AXIS_INTERP_CTIME).toInt(); xAxisDisplay = (AxisDisplayType)cfg.value("Display", static_cast(AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS)).toInt(); cfg.endGroup(); cfg.beginGroup("Y Axis"); yAxisInterpret = cfg.value("Interpret", false).toBool(); yAxisInterpretation = (AxisInterpretationType)cfg.value("Interpretation", (int)AXIS_INTERP_CTIME).toInt(); yAxisDisplay = (AxisDisplayType)cfg.value("Display", static_cast(AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS)).toInt(); cfg.endGroup(); cfg.beginGroup("Curve"); defaultLineWeight = cfg.value("DefaultLineWeight", 0).toInt(); cfg.endGroup(); cfg.beginGroup("Printing"); printing.pageSize = cfg.value("kde-pagesize", QString::number((int)QPrinter::Letter)).toString(); printing.orientation = cfg.value("kde-orientation", "Landscape").toString(); printing.plotDateTimeFooter = cfg.value("kst-plot-datetime-footer", "0").toString(); printing.maintainAspect = cfg.value("kst-plot-maintain-aspect-ratio", "0").toString(); printing.curveWidthAdjust = cfg.value("kst-plot-curve-width-adjust", "0").toString(); printing.monochrome = cfg.value("kst-plot-monochrome", "0").toString(); printing.monochromeSettings.enhanceReadability = cfg.value("kst-plot-monochromesettings-enhancereadability", "0").toString(); printing.monochromeSettings.pointStyleOrder = cfg.value("kst-plot-monochromesettings-pointstyleorder", "0").toString(); printing.monochromeSettings.lineStyleOrder = cfg.value("kst-plot-monochromesettings-linestyleorder", "1").toString(); printing.monochromeSettings.lineWidthOrder = cfg.value("kst-plot-monochromesettings-linewidthorder", "2").toString(); printing.monochromeSettings.maxLineWidth = cfg.value("kst-plot-monochromesettings-maxlinewidth", "3").toString(); printing.monochromeSettings.pointDensity = cfg.value("kst-plot-monochromesettings-pointdensity", "2").toString(); cfg.endGroup(); } void Settings::checkUpdates() { // ### Do KDE3->4 update (?) } void Settings::setPrintingDefaults() { printing.pageSize = QString::number((int)QPrinter::Letter); printing.orientation = "Landscape"; printing.plotDateTimeFooter = '0'; printing.maintainAspect + '0'; printing.curveWidthAdjust + '0'; printing.monochrome + '0'; printing.monochromeSettings.enhanceReadability + '0'; printing.monochromeSettings.pointStyleOrder + '0'; printing.monochromeSettings.lineStyleOrder = '1'; printing.monochromeSettings.lineWidthOrder = '2'; printing.monochromeSettings.maxLineWidth = '3'; printing.monochromeSettings.pointDensity = '2'; } int Settings::utcOffset() { return offsetSeconds; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/labelparser.h000644 001750 001750 00000005277 11544160207 020302 0ustar00synthsynth000000 000000 /*************************************************************************** labelparser.h ---------------- begin : Dec 14 2004 Copyright (C) 2004, The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELPARSER_H #define LABELPARSER_H #include "string_kst.h" #include "kstmath_export.h" #include typedef quint16 KstLJustifyType; typedef quint8 KstLHJustifyType; typedef quint8 KstLVJustifyType; #define KST_JUSTIFY_H(x) (x & 0x000000ffL) #define KST_JUSTIFY_H_NONE 0 #define KST_JUSTIFY_H_LEFT 1 #define KST_JUSTIFY_H_RIGHT 2 #define KST_JUSTIFY_H_CENTER 3 #define KST_JUSTIFY_V(x) ((x >> 8) & 0x000000ffL) #define KST_JUSTIFY_V_NONE 0 #define KST_JUSTIFY_V_TOP 1 #define KST_JUSTIFY_V_BOTTOM 2 #define KST_JUSTIFY_V_CENTER 3 #define SET_KST_JUSTIFY(h,v) ( ( h & 0x000000ffL ) | ( ( v & 0x000000ffL ) << 8 ) ) namespace Label { struct KSTMATH_EXPORT ChunkAttributes { ChunkAttributes() : bold(false), italic(false), underline(false), overline(false) {} inline bool empty() const { return !bold && !italic && !underline && !overline && !color.isValid(); } bool bold; bool italic; bool underline; bool overline; QColor color; }; struct KSTMATH_EXPORT Chunk { enum VOffset { None = 0, Up = 1, Down = 2 }; Chunk(Chunk *parent, VOffset = None, bool isGroup = false, bool inherit = false); ~Chunk(); bool locked() const; Chunk *next, *prev, *up, *down, *group; bool scalar : 1; bool linebreak : 1; bool tab : 1; bool vector : 1; VOffset vOffset #ifndef Q_WS_WIN32 : 2 #endif ; ChunkAttributes attributes; QString text; QString expression; }; struct KSTMATH_EXPORT Parsed { Parsed(); ~Parsed(); Chunk *chunk; }; extern KSTMATH_EXPORT Parsed *parse(const QString&, bool interpret = true, bool interpretNewLine = true); } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/enodes.h000644 001750 001750 00000016076 11544160207 017262 0ustar00synthsynth000000 000000 /*************************************************************************** enodes.h ---------- begin : Feb 12 2004 copyright : (C) 2004 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ENODES_H #define ENODES_H #include "string_kst.h" #include "vector.h" #include "kstmath_export.h" #include "objectstore.h" #define EQ_FALSE 0.0 #define EQ_TRUE 1.0 namespace Equations { /* Global lock for the parser */ KSTMATH_EXPORT QMutex& mutex(); /* Evaluate the expression @p txt and returns the value as a double. * Returns the value, or 0.0 and sets ok = false on error. */ KSTMATH_EXPORT double interpret(Kst::ObjectStore *store, const char *txt, bool *ok = 0L, int len = -1); class KSTMATH_EXPORT Context { public: Context() : i(0), x(0.0), xVector(0L), noPoint(0.0), sampleCount(0) {} ~Context() {} long i; double x; Kst::VectorPtr xVector; double noPoint; long sampleCount; }; class NodeVisitor; class KSTMATH_EXPORT Node { public: Node(); virtual ~Node(); virtual bool isConst() = 0; // can't be const virtual bool collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t); virtual bool takeVectors(const Kst::VectorMap& c); virtual double value(Context*) = 0; virtual void visit(NodeVisitor*); virtual Kst::Object::UpdateType update(Context *ctx); virtual QString text() const = 0; void parenthesize() { _parentheses = true; } protected: bool _parentheses; }; class KSTMATH_EXPORT BinaryNode : public Node { public: BinaryNode(Node *left, Node *right); virtual ~BinaryNode(); virtual bool collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t); virtual bool takeVectors(const Kst::VectorMap& c); virtual void visit(NodeVisitor*); virtual Kst::Object::UpdateType update(Context *ctx); Node *& left(); Node *& right(); virtual QString text() const = 0; protected: Node *_left, *_right; }; class KSTMATH_EXPORT ArgumentList : public Node { friend class Function; public: ArgumentList(); virtual ~ArgumentList(); void appendArgument(Node *arg); // Makes no sense for this type double value(Context*) { return 0.0; } bool isConst(); bool collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t); bool takeVectors(const Kst::VectorMap& c); double at(int, Context*); Node *node(int idx); Kst::Object::UpdateType update(Context *ctx); QString text() const; protected: QList _args; }; class KSTMATH_EXPORT Function : public Node { public: Function(char *name, ArgumentList *args); ~Function(); bool isConst(); double value(Context*); bool collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t); bool takeVectors(const Kst::VectorMap& c); Kst::Object::UpdateType update(Context *ctx); QString text() const; protected: char *_name; ArgumentList *_args; void *_f; private: int _inputScalarCnt, _inputVectorCnt, _inputStringCnt; int _inPid, _outputScalarCnt, _outputVectorCnt, _outputStringCnt; int *_inArrayLens, *_outArrayLens; double *_inScalars, *_outScalars; double **_inVectors, **_outVectors; int _outputIndex; // -1 = scalar 0, -424242 = none/error, +0...n = vector void *_localData; int _argCount; }; class KSTMATH_EXPORT Number : public Node { public: Number(double n); ~Number(); bool isConst(); double value(Context*); QString text() const; protected: double _n; }; class KSTMATH_EXPORT Identifier : public Node { public: Identifier(char *name); ~Identifier(); bool isConst(); double value(Context*); const char *name() const; QString text() const; protected: char *_name; double *_const; }; class KSTMATH_EXPORT DataNode : public Node { friend class Function; public: DataNode(Kst::ObjectStore *store, char *name); ~DataNode(); bool isConst(); double value(Context*); bool collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t); bool takeVectors(const Kst::VectorMap& c); Kst::Object::UpdateType update(Context *ctx); QString text() const; protected: Kst::ObjectStore *_store; QString _tagName; Kst::VectorPtr _vector; Kst::ScalarPtr _scalar; bool _isEquation; Node *_equation; QString _vectorIndex; }; class KSTMATH_EXPORT NodeVisitor { public: NodeVisitor(); virtual ~NodeVisitor(); virtual void visitNode(Node*) = 0; virtual void visitBinaryNode(BinaryNode*) = 0; }; class KSTMATH_EXPORT FoldVisitor : public NodeVisitor { public: FoldVisitor(Context*, Node**); ~FoldVisitor(); void visitNode(Node*); void visitBinaryNode(BinaryNode*); protected: Context *_ctx; }; class KSTMATH_EXPORT Negation : public Node { public: Negation(Node *node); ~Negation(); bool isConst(); double value(Context*); QString text() const; protected: Node *_n; }; class KSTMATH_EXPORT LogicalNot : public Node { public: LogicalNot(Node *node); ~LogicalNot(); bool isConst(); double value(Context*); QString text() const; protected: Node *_n; }; #define CreateNode(x) \ class KSTMATH_EXPORT x : public BinaryNode { \ public: \ x(Node *left, Node *right); \ ~x(); \ bool isConst(); \ double value(Context*); \ QString text() const; \ }; CreateNode(Addition) CreateNode(Subtraction) CreateNode(Multiplication) CreateNode(Division) CreateNode(Modulo) CreateNode(Power) CreateNode(BitwiseAnd) CreateNode(BitwiseOr) CreateNode(LogicalAnd) CreateNode(LogicalOr) CreateNode(LessThan) CreateNode(LessThanEqual) CreateNode(GreaterThan) CreateNode(GreaterThanEqual) CreateNode(EqualTo) CreateNode(NotEqualTo) #undef CreateNode } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/basicpluginfactory.h000644 001750 001750 00000002236 11544160207 021666 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BASICPLUGINFACTORY_H #define BASICPLUGINFACTORY_H #include "objectfactory.h" namespace Kst { class BasicPluginFactory : public ObjectFactory { public: BasicPluginFactory(); ~BasicPluginFactory(); DataObjectPtr generateObject(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/imagefactory.h000644 001750 001750 00000002204 11544160207 020443 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef IMAGEFACTORY_H #define IMAGEFACTORY_H #include "relationfactory.h" namespace Kst { class ImageFactory : public RelationFactory { public: ImageFactory(); ~ImageFactory(); RelationPtr generateRelation(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/psd.h000644 001750 001750 00000007636 11544160207 016575 0ustar00synthsynth000000 000000 /*************************************************************************** psd.h: Power Spectra for KST ------------------- begin : Fri Feb 10 2002 copyright : (C) 2002 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A class for handling power spectra for kst *@author C. Barth Netterfield */ #ifndef PSD_H #define PSD_H #include "dataobject.h" #include "psdcalculator.h" #include "kstmath_export.h" namespace Kst { class ObjectStore; class KSTMATH_EXPORT PSD : public DataObject { Q_OBJECT public: static const QString staticTypeString; static const QString staticTypeTag; const QString& typeString() const { return staticTypeString; } virtual void save(QXmlStreamWriter &s); virtual QString propertyString() const; bool apodize() const; void setApodize(bool in_apodize); ApodizeFunction apodizeFxn() const; void setApodizeFxn(ApodizeFunction in_apodizeFxn); double gaussianSigma() const; void setGaussianSigma(double in_gaussianSigma); bool removeMean() const; void setRemoveMean(bool in_removeMean); bool average() const; void setAverage(bool in_average); double frequency() const; void setFrequency(double in_frequency); int length() const; void setLength(int in_length); void setVector(VectorPtr); VectorPtr vector() const; const QString& vectorUnits() const; void setVectorUnits(const QString& units); const QString& rateUnits() const; void setRateUnits(const QString& units); PSDType output() const; void setOutput(PSDType in_output); bool interpolateHoles() const; void setInterpolateHoles(bool interpolate); virtual bool slaveVectorsUsed() const; virtual void showNewDialog(); virtual void showEditDialog(); VectorPtr vX() const { return _fVector; } VectorPtr vY() const { return _sVector; } const CurveHintList *curveHints() const; virtual DataObjectPtr makeDuplicate() const; virtual QString descriptionTip() const; void change(VectorPtr in_V, double freq, bool average, int average_len, bool apodize, bool removeMean, const QString& VUnits, const QString& RUnits, ApodizeFunction in_apodizeFxn = WindowOriginal, double in_gaussianSigma = 3.0, PSDType in_output = PSDAmplitudeSpectralDensity, bool interpolateHoles = false); virtual void internalUpdate(); protected: PSD(ObjectStore *store); virtual ~PSD(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); private: void updateVectorLabels(); void _adjustLengths(); ApodizeFunction _apodizeFxn; double _gaussianSigma; bool _Apodize; bool _RemoveMean; bool _Average; bool _interpolateHoles; PSDType _Output; PSDType _prevOutput; int _last_n_subsets; int _last_n_new; double _Frequency; int _PSDLength; int _averageLength; PSDCalculator _psdCalculator; QString _vectorUnits; QString _rateUnits; VectorPtr _sVector, _fVector; }; typedef SharedPtr PSDPtr; typedef ObjectList PSDList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/kstmath_pch000644 001750 001750 00000002710 11544160207 020052 0ustar00synthsynth000000 000000 #include "kstcore_pch.h" #ifdef KST_PCH_RECURSIVE // libkst headers #include "builtindatasources.h" #include "builtinprimitives.h" #include "coredocument.h" #include "datacollection.h" #include "datamatrix.h" #include "dataplugin.h" #include "dataprimitive.h" #include "datascalar.h" #include "datasource.h" #include "datasourcefactory.h" #include "datasourcepluginfactory.h" #include "datasourcepluginmanager.h" #include "datastring.h" #include "datavector.h" #include "dateparser.h" #include "debug.h" #include "editablematrix.h" #include "editablevector.h" #include "events.h" #include "extension.h" #include "generatedmatrix.h" #include "generatedvector.h" //#include "index_kst.h" #include "kst_export.h" #include "kst_i18n.h" #include "kst_inf.h" #include "ksttimers.h" #include "logevents.h" #include "math_kst.h" #include "matrix.h" #include "matrixfactory.h" #include "measuretime.h" #include "namedobject.h" #include "nextcolor.h" #include "object.h" #include "objectlist.h" #include "objectmap.h" #include "objectstore.h" #include "plotiteminterface.h" #include "primitive.h" #include "primitivefactory.h" #include "procps.h" #include "psversion.h" #include "rwlock.h" #include "scalar.h" #include "scalarfactory.h" #include "sharedptr.h" //#include "stdinsource.h" #include "string_kst.h" #include "stringfactory.h" #include "sysinfo.h" #include "timezones.h" #include "updatemanager.h" #include "vector.h" #include "vectorfactory.h" #include "vscalar.h" #endif kst-2.0.3/src/libkstmath/curve.h000644 001750 001750 00000016734 11544160207 017132 0ustar00synthsynth000000 000000 /*************************************************************************** vcurve.h: defines a curve for kst ------------------- begin : Fri Oct 22 2000 copyright : (C) 2000 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CURVE_H #define CURVE_H #include "relation.h" #include "painter.h" #include "curvepointsymbol.h" #include "kstmath_export.h" #include "labelinfo.h" #include /**A class for handling curves for kst *@author C. Barth Netterfield */ namespace Kst { class KSTMATH_EXPORT Curve: public Relation { Q_OBJECT public: static const QString staticTypeString; const QString& typeString() const { return staticTypeString; } static const QString staticTypeTag; virtual void internalUpdate(); virtual QString propertyString() const; virtual int getIndexNearXY(double x, double dx, double y) const; virtual bool hasXError() const; virtual bool hasYError() const; virtual bool hasXMinusError() const; virtual bool hasYMinusError() const; // Note: these are -expensive-. Don't use them on inner loops! virtual void point(int i, double &x1, double &y1) const; virtual void getEXPoint(int i, double &x1, double &y1, double &ex1); virtual void getEYPoint(int i, double &x1, double &y1, double &ey1); virtual void getEXMinusPoint(int i, double &x1, double &y1, double &ex1); virtual void getEYMinusPoint(int i, double &x1, double &y1, double &ey1); virtual void getEXPoints(int i, double &x, double &y, double &ex, double &exminus); virtual void getEYPoints(int i, double &x, double &y, double &ey, double &eyminus); void setXVector(VectorPtr new_vx); void setYVector(VectorPtr new_vy); void setXError(VectorPtr new_ex); void setYError(VectorPtr new_ey); void setXMinusError(VectorPtr new_ex); void setYMinusError(VectorPtr new_ey); /** Save curve information */ void save(QXmlStreamWriter &s); virtual bool xIsRising() const; virtual double maxX() const; virtual double minX() const; virtual double meanX() const { return MeanX; } virtual double meanY() const { return MeanY; } virtual void yRange(double xFrom, double xTo, double* yMin, double* yMax); virtual int samplesPerFrame() const; virtual void showNewDialog(); virtual void showEditDialog(); VectorPtr xVector() const; VectorPtr yVector() const; VectorPtr xErrorVector() const; VectorPtr yErrorVector() const; VectorPtr xMinusErrorVector() const; VectorPtr yMinusErrorVector() const; virtual bool hasPoints() const { return HasPoints; } virtual bool hasLines() const { return HasLines; } virtual bool hasBars() const { return HasBars; } virtual bool hasHead() const { return HasHead; } virtual void setHasPoints(bool in_HasPoints); virtual void setHasLines(bool in_HasLines); virtual void setHasBars(bool in_HasBars); virtual void setHasHead(bool in_HasHead); virtual void setLineWidth(int in_LineWidth); virtual void setLineStyle(int in_LineStyle); virtual void setBarStyle( int in_BarStyle); virtual void setPointDensity(int in_PointDensity); virtual void setPointType(int in_PointType); virtual void setHeadType(int in_HeadType); virtual int lineWidth() const { return LineWidth; } virtual int lineStyle() const { return LineStyle; } virtual int barStyle() const { return BarStyle; } virtual int pointDensity() const { return PointDensity; } virtual int pointType() const { return PointType; } virtual int headType() const { return HeadType; } virtual QColor color() const { return Color; } virtual void setColor(const QColor& new_c); virtual QColor headColor() const { return HeadColor; } virtual void setHeadColor(const QColor& new_c); #if 0 void pushColor(const QColor& c) { _colorStack.push(color()); setColor(c); } void popColor() { setColor(_colorStack.pop()); } void pushLineWidth(int w) { _widthStack.push(lineWidth()); setLineWidth(w); } void popLineWidth() { setLineWidth(_widthStack.pop()); } void pushLineStyle(int s) { _lineStyleStack.push(lineStyle()); setLineStyle(s); } void popLineStyle() { setLineStyle(_lineStyleStack.pop()); } void pushPointStyle(int s) { _pointStyleStack.push(PointType); PointType = s; } void popPointStyle() { PointType = _pointStyleStack.pop(); } void pushHasPoints(bool h) { _hasPointsStack.push(hasPoints()); setHasPoints(h); } void popHasPoints() { setHasPoints(_hasPointsStack.pop()); } void pushHasLines(bool h) { _hasLinesStack.push(hasLines()); setHasLines(h); } void popHasLines() { setHasLines(_hasLinesStack.pop()); } void pushPointDensity(int d) { _pointDensityStack.push(pointDensity()); setPointDensity(d); } void popPointDensity() { setPointDensity(_pointDensityStack.pop()); } #endif //virtual RelationPtr makeDuplicate(QMap &duplicatedRelations); virtual RelationPtr makeDuplicate() const; // render this curve virtual void paintObjects(const CurveRenderContext& context); // Update the curve details. void updatePaintObjects(const CurveRenderContext& context); // render the legend symbol for this curve virtual void paintLegendSymbol(QPainter *p, const QRectF& bound); // see KstRelation::distanceToPoint virtual double distanceToPoint(double xpos, double dx, double ypos) const; // see KstRelation::providerDataObject virtual DataObjectPtr providerDataObject() const; virtual QString descriptionTip() const; // labels for plots virtual LabelInfo xLabelInfo() const; virtual LabelInfo yLabelInfo() const; virtual LabelInfo titleInfo() const; protected: Curve(ObjectStore *store); virtual ~Curve(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); private: double MeanY; int BarStyle; int LineWidth; int LineStyle; int PointDensity; int PointType; int HeadType; bool HasPoints; bool HasLines; bool HasBars; bool HasHead; QColor Color; QColor HeadColor; #if 0 QStack _widthStack; QStack _colorStack; QStack _pointStyleStack; QStack _lineStyleStack; QStack _hasPointsStack; QStack _hasLinesStack; QStack _pointDensityStack; #endif QVector _polygons; QVector _lines; QVector _points; QVector _filledRects; QVector _rects; QPointF _head; bool _head_valid; int _width; }; typedef SharedPtr CurvePtr; typedef ObjectList CurveList; } Q_DECLARE_METATYPE(Kst::Curve*) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/basicplugin.h000644 001750 001750 00000010731 11544160207 020275 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2006 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BASICPLUGIN_H #define BASICPLUGIN_H #include "dataobject.h" #include "kstmath_export.h" namespace Kst { class ObjectStore; class KSTMATH_EXPORT BasicPlugin : public DataObject { Q_OBJECT public: static const QString staticTypeString; const QString& typeString() const { return staticTypeString; } static const QString staticTypeTag; //The implementation of the algorithm the plugin provides. //Operates on the inputVectors, inputScalars, and inputStrings //to produce the outputVectors, outputScalars, and outputStrings. virtual bool algorithm() = 0; //String lists of the names of the expected inputs. virtual QStringList inputVectorList() const = 0; virtual QStringList inputScalarList() const = 0; virtual QStringList inputStringList() const = 0; //String lists of the names of the expected outputs. virtual QStringList outputVectorList() const = 0; virtual QStringList outputScalarList() const = 0; virtual QStringList outputStringList() const = 0; //Pure virtual methods inherited from DataObject //This _must_ equal the 'Name' entry in the .desktop file of //the plugin QString propertyString() const { return name(); } //no longer virtual //Provide an impl... virtual DataObjectPtr makeDuplicate() const; virtual QString descriptionTip() const; // Validator of plugin data. Expensive, only use to verify successful creation. bool isValid() { return (inputsExist() && algorithm()); } QString errorMessage() { return _errorString; } public slots: //Pure virtual slots from DataObject //Each plugin can provide an implementation or use the default virtual void showNewDialog(); virtual void showEditDialog(); public: virtual void change(DataObjectConfigWidget *configWidget) = 0; //Returns the respective input object for name VectorPtr inputVector(const QString& name) const; ScalarPtr inputScalar(const QString& name) const; StringPtr inputString(const QString& name) const; //Returns the respective output object for name VectorPtr outputVector(const QString& name) const; ScalarPtr outputScalar(const QString& name) const; StringPtr outputString(const QString& name) const; void setInputVector(const QString &type, VectorPtr ptr); void setInputScalar(const QString &type, ScalarPtr ptr); void setInputString(const QString &type, StringPtr ptr); void setOutputVector(const QString &type, const QString &name); void setOutputScalar(const QString &type, const QString &name); void setOutputString(const QString &type, const QString &name); void setPluginName(const QString &pluginName); QString pluginName() { return _pluginName; } //Regular virtual methods from DataObject virtual void save(QXmlStreamWriter &s); virtual void saveProperties(QXmlStreamWriter &s); void createScalars(); QString label(int precision) const; virtual void internalUpdate(); virtual bool hasParameterVector() const { return _outputVectors.contains("Parameters Vector");} virtual QString parameterVectorToString() const { return label(9);} protected: BasicPlugin(ObjectStore *store); virtual ~BasicPlugin(); //Pure virtual methods inherited from DataObject //We do this one ourselves for benefit of all plugins... virtual QString parameterName(int index) const; QString _errorString; virtual void _initializeShortName(); private: bool inputsExist() const; void updateOutput() const; QString _pluginName; }; typedef SharedPtr BasicPluginPtr; typedef ObjectList BasicPluginList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/builtinobjects.cpp000644 001750 001750 00000002434 11544160207 021351 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "builtinobjects.h" #include "equationfactory.h" #include "csdfactory.h" #include "histogramfactory.h" #include "psdfactory.h" #include "eventmonitorfactory.h" #include "basicpluginfactory.h" namespace Kst { namespace Builtins { void initObjects() { new EquationFactory; new CSDFactory; new HistogramFactory; new PSDFactory; new EventMonitorFactory; new BasicPluginFactory; } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/eventmonitorfactory.cpp000644 001750 001750 00000006126 11544160207 022454 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "eventmonitorfactory.h" #include "debug.h" #include "eventmonitorentry.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { EventMonitorFactory::EventMonitorFactory() : ObjectFactory() { registerFactory(EventMonitorEntry::staticTypeTag, this); } EventMonitorFactory::~EventMonitorFactory() { } DataObjectPtr EventMonitorFactory::generateObject(ObjectStore *store, QXmlStreamReader& xml) { Q_ASSERT(store); QString equation, description, emailRecipients, script; bool logDebug=false, logEmail=false, logELOG=false; int logLevel=1; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == EventMonitorEntry::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); equation = attrs.value("equation").toString(); description = attrs.value("description").toString(); emailRecipients = attrs.value("emailrecipients").toString(); script = attrs.value("script").toString(); logLevel = attrs.value("loglevel").toString().toInt(); logDebug = attrs.value("logdebug").toString() == "true" ? true : false; logEmail = attrs.value("logemail").toString() == "true" ? true : false; logELOG = attrs.value("logelog").toString() == "true" ? true : false; } else { return 0; } } else if (xml.isEndElement()) { if (n == EventMonitorEntry::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating EventMonitorEntry from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } EventMonitorEntryPtr eventMonitor = store->createObject(); Q_ASSERT(eventMonitor); eventMonitor->setScriptCode(script); eventMonitor->setEvent(equation); eventMonitor->setDescription(description); eventMonitor->setLevel((Debug::LogLevel)logLevel); eventMonitor->setLogDebug(logDebug); eventMonitor->setLogEMail(logEmail); eventMonitor->setLogELOG(logELOG); eventMonitor->setEMailRecipients(emailRecipients); eventMonitor->reparse(); eventMonitor->writeLock(); eventMonitor->registerChange(); eventMonitor->unlock(); return eventMonitor; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/doublecompare.h000644 001750 001750 00000002747 11544160207 020626 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #define SMALL_NON_ZERO 0.00000000001 template inline bool doubleEqual(const T& a, const T& b) { return a == b || fabs(a - b) < SMALL_NON_ZERO; } template inline bool doubleLessThan(const T& a, const T& b) { return b - a > SMALL_NON_ZERO; } template inline bool doubleLessThanEqual(const T& a, const T& b) { return doubleEqual(a, b) || doubleLessThan(a, b); } template inline bool doubleGreaterThan(const T& a, const T& b) { return a - b > SMALL_NON_ZERO; } template inline bool doubleGreaterThanEqual(const T& a, const T& b) { return doubleEqual(a, b) || doubleGreaterThan(a, b); } kst-2.0.3/src/libkstmath/curvepointsymbol.h000644 001750 001750 00000002753 11544160207 021426 0ustar00synthsynth000000 000000 /*************************************************************************** curvepointsymbol.h ------------------- begin : June 3 2001 copyright : (C) 2001 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CURVEPOINTSYMBOL_H #define CURVEPOINTSYMBOL_H #include "kstmath_export.h" #include #define KSTPOINT_MAXTYPE 13 namespace Kst { namespace CurvePointSymbol { /** draw the point on a painter the scale of the point is based on size */ KSTMATH_EXPORT void draw(int type, QPainter *p, double x, double y, int lineSize = 0, int size = -1); /** Get the dimension of a point */ KSTMATH_EXPORT int dim(const QRect &window); } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/curve.cpp000644 001750 001750 00000121722 11544160207 017457 0ustar00synthsynth000000 000000 /*************************************************************************** vcurve.cpp: holds info for a curve ------------------- begin : Fri Nov 3 2000 copyright : (C) 2000 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // includes for KDE #include "kst_i18n.h" #include #include #include // application specific includes #include "dialoglauncher.h" #include "colorsequence.h" #include "datacollection.h" #include "debug.h" #include "linestyle.h" #include "math_kst.h" #include "datavector.h" #include "curve.h" #include "ksttimers.h" #include "objectstore.h" #include #include // #define DEBUG_VECTOR_CURVE // #define BENCHMARK #ifndef KDE_IS_LIKELY #if __GNUC__ - 0 >= 3 # define KDE_ISLIKELY( x ) __builtin_expect(!!(x),1) # define KDE_ISUNLIKELY( x ) __builtin_expect(!!(x),0) #else # define KDE_ISLIKELY( x ) ( x ) # define KDE_ISUNLIKELY( x ) ( x ) #endif #endif // for painting #define MAX_NUM_POLYLINES 1000 namespace Kst { const QString Curve::staticTypeString = I18N_NOOP("Curve"); const QString Curve::staticTypeTag = I18N_NOOP("curve"); static const QLatin1String& XVECTOR = QLatin1String("X"); static const QLatin1String& YVECTOR = QLatin1String("Y"); static const QLatin1String& EXVECTOR = QLatin1String("EX"); static const QLatin1String& EYVECTOR = QLatin1String("EY"); static const QLatin1String& EXMINUSVECTOR = QLatin1String("EXMinus"); static const QLatin1String& EYMINUSVECTOR = QLatin1String("EYMinus"); Curve::Curve(ObjectStore *store) : Relation(store) { setHasPoints(false); setHasHead(false); setHasBars(false); setHasLines(true); setLineWidth(1); setLineStyle(0); setBarStyle(0); setPointDensity(0); MaxX = MinX = MeanX = MaxY = MinY = MeanY = MinPosX = MinPosY = 0; NS = 0; _typeString = i18n("Curve"); _type = "Curve"; _initializeShortName(); Color = QColor(); HeadColor = QColor(); } void Curve::_initializeShortName() { _shortName = 'C'+QString::number(_cnum); if (_cnum>max_cnum) max_cnum = _cnum; _cnum++; } Curve::~Curve() { } void Curve::internalUpdate() { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); VectorPtr cxV = *_inputVectors.find(XVECTOR); VectorPtr cyV = *_inputVectors.find(YVECTOR); if (!cxV || !cyV) { return; } writeLockInputsAndOutputs(); MaxX = cxV->max(); MinX = cxV->min(); MeanX = cxV->mean(); MinPosX = cxV->minPos(); _ns_maxx = cxV->ns_max(); _ns_minx = cxV->ns_min(); if (MinPosX > MaxX) { MinPosX = 0; } MaxY = cyV->max(); MinY = cyV->min(); MeanY = cyV->mean(); MinPosY = cyV->minPos(); _ns_maxy = cyV->ns_max(); _ns_miny = cyV->ns_min(); if (MinPosY > MaxY) { MinPosY = 0; } NS = qMax(cxV->length(), cyV->length()); unlockInputsAndOutputs(); _redrawRequired = true; return; } void Curve::point(int i, double &x, double &y) const { VectorPtr xv = xVector(); if (xv) { x = xv->interpolate(i, NS); } VectorPtr yv = yVector(); if (yv) { y = yv->interpolate(i, NS); } } void Curve::getEXPoint(int i, double &x, double &y, double &ex) { VectorPtr xv = xVector(); if (xv) { x = xv->interpolate(i, NS); } VectorPtr yv = yVector(); if (yv) { y = yv->interpolate(i, NS); } VectorPtr exv = xErrorVector(); if (exv) { ex = exv->interpolate(i, NS); } } void Curve::getEXMinusPoint(int i, double &x, double &y, double &ex) { VectorPtr xv = xVector(); if (xv) { x = xv->interpolate(i, NS); } VectorPtr yv = yVector(); if (yv) { y = yv->interpolate(i, NS); } VectorPtr exmv = xMinusErrorVector(); if (exmv) { ex = exmv->interpolate(i, NS); } } void Curve::getEXPoints(int i, double &x, double &y, double &exminus, double &explus) { VectorPtr xv = xVector(); if (xv) { x = xv->interpolate(i, NS); } VectorPtr yv = yVector(); if (yv) { y = yv->interpolate(i, NS); } VectorPtr exv = xErrorVector(); if (exv) { explus = exv->interpolate(i, NS); } VectorPtr exmv = xMinusErrorVector(); if (exmv) { exminus = exmv->interpolate(i, NS); } } void Curve::getEYPoint(int i, double &x, double &y, double &ey) { VectorPtr xv = xVector(); if (xv) { x = xv->interpolate(i, NS); } VectorPtr yv = yVector(); if (yv) { y = yv->interpolate(i, NS); } VectorPtr eyv = yErrorVector(); if (eyv) { ey = eyv->interpolate(i, NS); } } void Curve::getEYMinusPoint(int i, double &x, double &y, double &ey) { VectorPtr xv = xVector(); if (xv) { x = xv->interpolate(i, NS); } VectorPtr yv = yVector(); if (yv) { y = yv->interpolate(i, NS); } VectorPtr eyv = yMinusErrorVector(); if (eyv) { ey = eyv->interpolate(i, NS); } } void Curve::getEYPoints(int i, double &x, double &y, double &eyminus, double &eyplus) { VectorPtr xv = xVector(); if (xv) { x = xv->interpolate(i, NS); } VectorPtr yv = yVector(); if (yv) { y = yv->interpolate(i, NS); } VectorPtr eyv = yErrorVector(); if (eyv) { eyplus = eyv->interpolate(i, NS); } VectorPtr eymv = yMinusErrorVector(); if (eymv) { eyminus = eymv->interpolate(i, NS); } } bool Curve::hasXError() const { return _inputVectors.contains(EXVECTOR); } bool Curve::hasYError() const { return _inputVectors.contains(EYVECTOR); } bool Curve::hasXMinusError() const { return _inputVectors.contains(EXMINUSVECTOR); } bool Curve::hasYMinusError() const { return _inputVectors.contains(EYMINUSVECTOR); } void Curve::save(QXmlStreamWriter &s) { s.writeStartElement(staticTypeTag); s.writeAttribute("xvector", _inputVectors[XVECTOR]->Name()); s.writeAttribute("yvector", _inputVectors[YVECTOR]->Name()); if (_inputVectors.contains(EXVECTOR)) { s.writeAttribute("errorxvector", _inputVectors[EXVECTOR]->Name()); } if (_inputVectors.contains(EYVECTOR)) { s.writeAttribute("erroryvector", _inputVectors[EYVECTOR]->Name()); } if (_inputVectors.contains(EXMINUSVECTOR)) { s.writeAttribute("errorxminusvector", _inputVectors[EXMINUSVECTOR]->Name()); } if (_inputVectors.contains(EYMINUSVECTOR)) { s.writeAttribute("erroryminusvector", _inputVectors[EYMINUSVECTOR]->Name()); } s.writeAttribute("color", Color.name()); s.writeAttribute("headcolor", HeadColor.name()); s.writeAttribute("haslines", QVariant(HasLines).toString()); s.writeAttribute("linewidth", QString::number(LineWidth)); s.writeAttribute("linestyle", QString::number(LineStyle)); s.writeAttribute("haspoints", QVariant(HasPoints).toString()); s.writeAttribute("pointtype", QString::number(PointType)); s.writeAttribute("pointdensity", QString::number(PointDensity)); s.writeAttribute("hasbars", QVariant(HasBars).toString()); s.writeAttribute("barstyle", QString::number(BarStyle)); s.writeAttribute("ignoreautoscale", QVariant(_ignoreAutoScale).toString()); s.writeAttribute("hashead", QVariant(HasHead).toString()); s.writeAttribute("headtype", QString::number(HeadType)); saveNameInfo(s, CNUM); s.writeEndElement(); } void Curve::setXVector(VectorPtr new_vx) { if (new_vx) { _inputVectors[XVECTOR] = new_vx; } else { _inputVectors.remove(XVECTOR); } } void Curve::setYVector(VectorPtr new_vy) { if (new_vy) { _inputVectors[YVECTOR] = new_vy; } else { _inputVectors.remove(YVECTOR); } } void Curve::setXError(VectorPtr new_ex) { if (new_ex) { _inputVectors[EXVECTOR] = new_ex; } else { _inputVectors.remove(EXVECTOR); } } void Curve::setYError(VectorPtr new_ey) { if (new_ey) { _inputVectors[EYVECTOR] = new_ey; } else { _inputVectors.remove(EYVECTOR); } } void Curve::setXMinusError(VectorPtr new_ex) { if (new_ex) { _inputVectors[EXMINUSVECTOR] = new_ex; } else { _inputVectors.remove(EXMINUSVECTOR); } } void Curve::setYMinusError(VectorPtr new_ey) { if (new_ey) { _inputVectors[EYMINUSVECTOR] = new_ey; } else { _inputVectors.remove(EYMINUSVECTOR); } } // labels for plots LabelInfo Curve::xLabelInfo() const { return xVector()->labelInfo(); } LabelInfo Curve::yLabelInfo() const { return yVector()->labelInfo(); } LabelInfo Curve::titleInfo() const { return yVector()->titleInfo(); } QString Curve::propertyString() const { return i18n("%1 vs %2").arg(yVector()->Name()).arg(xVector()->Name()); } void Curve::showNewDialog() { DialogLauncher::self()->showCurveDialog(); } void Curve::showEditDialog() { DialogLauncher::self()->showCurveDialog(this); } int Curve::samplesPerFrame() const { const DataVector *rvp = dynamic_cast(_inputVectors[YVECTOR].data()); return rvp ? rvp->samplesPerFrame() : 1; } VectorPtr Curve::xVector() const { return *_inputVectors.find(XVECTOR); } VectorPtr Curve::yVector() const { return *_inputVectors.find(YVECTOR); } VectorPtr Curve::xErrorVector() const { return *_inputVectors.find(EXVECTOR); } VectorPtr Curve::yErrorVector() const { return *_inputVectors.find(EYVECTOR); } VectorPtr Curve::xMinusErrorVector() const { return *_inputVectors.find(EXMINUSVECTOR); } VectorPtr Curve::yMinusErrorVector() const { return *_inputVectors.find(EYMINUSVECTOR); } bool Curve::xIsRising() const { return _inputVectors[XVECTOR]->isRising(); } inline int indexNearX(double x, VectorPtr& xv, int NS) { // monotonically rising: we can do a binary search // should be reasonably fast if (xv->isRising()) { int i_top = NS - 1; int i_bot = 0; // don't pre-check for x outside of the curve since this is not // the common case. It will be correct - just slightly slower... while (i_bot + 1 < i_top) { int i0 = (i_top + i_bot)/2; double rX = xv->interpolate(i0, NS); if (x < rX) { i_top = i0; } else { i_bot = i0; } } double xt = xv->interpolate(i_top, NS); double xb = xv->interpolate(i_bot, NS); if (xt - x < x - xb) { return i_top; } else { return i_bot; } } else { // Oh Oh... not monotonically rising - we have to search the entire curve! // May be unbearably slow for large vectors double rX = xv->interpolate(0, NS); double dx0 = fabs(x - rX); int i0 = 0; for (int i = 1; i < NS; ++i) { rX = xv->interpolate(i, NS); double dx = fabs(x - rX); if (dx < dx0) { dx0 = dx; i0 = i; } } return i0; } } /** getIndexNearXY: return index of point within (or closest too) x +- dx which is closest to y **/ int Curve::getIndexNearXY(double x, double dx_per_pix, double y) const { VectorPtr xv = *_inputVectors.find(XVECTOR); VectorPtr yv = *_inputVectors.find(YVECTOR); if (!xv || !yv) { return 0; // anything better we can do? } double xi, yi, dx, dxi, dy, dyi; bool first = true; int i,i0, iN, index; int sc = sampleCount(); if (xv->isRising()) { iN = i0 = indexNearX(x, xv, NS); xi = xv->interpolate(i0, NS); while (i0 > 0 && x-dx_per_pix < xi) { xi = xv->interpolate(--i0, NS); } xi = xv->interpolate(iN, NS); while (iN < sc-1 && x+dx_per_pix > xi) { xi = xv->interpolate(++iN, NS); } } else { i0 = 0; iN = sampleCount()-1; } index = i0; xi = xv->interpolate(index, NS); yi = yv->interpolate(index, NS); dx = fabs(x - xi); dy = fabs(y - yi); for (i = i0 + 1; i <= iN; i++) { xi = xv->interpolate(i, NS); dxi = fabs(x - xi); if (dxi < dx_per_pix) { dx = dxi; yi = yv->interpolate(i, NS); dyi = fabs(y - yi); if (first || dyi < dy) { first = false; index = i; dy = dyi; } } else if (dxi < dx) { dx = dxi; index = i; } } return index; } void Curve::setHasPoints(bool in_HasPoints) { HasPoints = in_HasPoints; } void Curve::setHasHead(bool in_HasHead) { HasHead = in_HasHead; } void Curve::setHasLines(bool in_HasLines) { HasLines = in_HasLines; } void Curve::setHasBars(bool in_HasBars) { HasBars = in_HasBars; } void Curve::setLineWidth(int in_LineWidth) { #ifdef Q_WS_WIN32 if (in_LineWidth == 0) { in_LineWidth = 1; } #endif LineWidth = in_LineWidth; } void Curve::setLineStyle(int in_LineStyle) { LineStyle = in_LineStyle; } void Curve::setBarStyle(int in_BarStyle) { BarStyle = in_BarStyle; } void Curve::setPointDensity(int in_PointDensity) { PointDensity = in_PointDensity; } void Curve::setPointType(int in_PointType) { PointType = in_PointType; } void Curve::setHeadType(int in_HeadType) { HeadType = in_HeadType; } void Curve::setColor(const QColor& new_c) { Color = new_c; } void Curve::setHeadColor(const QColor& new_c) { HeadColor = new_c; } double Curve::maxX() const { if (hasBars() && sampleCount() > 0) { return MaxX + (MaxX - MinX)/(2*(sampleCount()-1)); } return MaxX; } double Curve::minX() const { if (hasBars() && sampleCount() > 0) { return MinX - (MaxX - MinX)/(2*(sampleCount()-1)); } return MinX; } RelationPtr Curve::makeDuplicate() const { CurvePtr curve = store()->createObject(); if (descriptiveNameIsManual()) { curve->setDescriptiveName(descriptiveName()); } curve->setXVector(xVector()); curve->setYVector(yVector()); if (hasXError()) { curve->setXError(xErrorVector()); } if (hasYError()) { curve->setYError(yErrorVector()); } if (hasXMinusError()) { curve->setXMinusError(xMinusErrorVector()); } if (hasYMinusError()) { curve->setYMinusError(yMinusErrorVector()); } curve->setColor(Color); curve->setHeadColor(HeadColor); curve->setHasPoints(HasPoints); curve->setHasLines(HasLines); curve->setHasBars(HasBars); curve->setHasHead(HasHead); curve->setLineWidth(LineWidth); curve->setLineStyle(LineStyle); curve->setPointType(PointDensity); curve->setPointDensity(PointDensity); curve->setBarStyle(BarStyle); curve->writeLock(); curve->registerChange(); curve->unlock(); return RelationPtr(curve); } void Curve::paintObjects(const CurveRenderContext& context) { QPainter *p = context.painter; p->save(); //p->setRenderHint(QPainter::Antialiasing); Qt::PenStyle style = Kst::LineStyle[lineStyle()]; if (hasBars()) { if (barStyle() == 1) { // filled p->setPen(QPen(context.foregroundColor, _width, style)); } else { p->setPen(QPen(color(), _width, style)); } foreach(const QRectF& rect, _filledRects) { p->fillRect(rect, color()); } } p->setPen(QPen(color(), _width, style)); foreach(const QPolygonF& poly, _polygons) { p->drawPolyline(poly); } foreach(const QLineF& line, _lines) { p->drawLine(line); } foreach(const QRectF& rect, _rects) { p->drawRect(rect); } foreach(const QPointF& point, _points) { CurvePointSymbol::draw(PointType, p, point.x(), point.y(), _width); } if (hasHead() && _head_valid) { p->setPen(QPen(headColor(), _width, style)); CurvePointSymbol::draw(HeadType, p, _head.x(), _head.y(), _width); } p->restore(); } void Curve::updatePaintObjects(const CurveRenderContext& context) { _polygons.clear(); _lines.clear(); _points.clear(); _filledRects.clear(); _rects.clear(); VectorPtr xv = *_inputVectors.find(XVECTOR); VectorPtr yv = *_inputVectors.find(YVECTOR); if (!xv || !yv) { return; } double Lx = context.Lx, Hx = context.Hx, Ly = context.Ly, Hy = context.Hy; double m_X = context.m_X, m_Y = context.m_Y; double b_X = context.b_X, b_Y = context.b_Y; double XMin = context.XMin, XMax = context.XMax; bool xLog = context.xLog, yLog = context.yLog; double xLogBase = context.xLogBase; double yLogBase = context.yLogBase; double maxY = 0.0, minY = 0.0; double rX = 0.0, rY, rEX, rEY; double X1 = 0.0, Y1 = 0.0; double X2 = 0.0, Y2 = 0.0; double last_x1, last_y1; bool overlap = false; int i_pt; #ifdef BENCHMARK QTime bench_time, benchtmp; int b_1 = 0, b_2 = 0, b_3 = 0, b_4 = 0; bench_time.start(); benchtmp.start(); int numberOfLinesDrawn = 0; int numberOfPointsDrawn = 0; int numberOfBarsDrawn = 0; #endif if (lineWidth() == 0) { _width = context.penWidth; } else if (context.penWidth > 0) { _width = lineWidth() * context.penWidth; } else { _width = lineWidth(); } int pointDim = CurvePointSymbol::dim(context.window); if (sampleCount() > 0) { int i0, iN; if (xv->isRising()) { i0 = indexNearX(XMin, xv, NS); if (i0 > 0) { --i0; } iN = indexNearX(XMax, xv, NS); if (iN < sampleCount() - 1) { ++iN; } } else { i0 = 0; iN = sampleCount() - 1; } #ifdef BENCHMARK clock_t linesStart = clock(); #endif if (hasLines()) { QPolygonF points; points.reserve(MAX_NUM_POLYLINES); double lastPlottedX = 0; double lastPlottedY = 0; int index = 0; int i0Start = i0; // optimize - isnan seems expensive, at least in gcc debug mode // cachegrind backs this up. #undef isnan #define isnan(x) (x != x) rX = xv->interpolate(i0, NS); rY = yv->interpolate(i0, NS); // if invalid point then look backward for the last valid point. while (i0 > 0 && (isnan(rX) || isnan(rY))) { --i0; rX = xv->interpolate(i0, NS); rY = yv->interpolate(i0, NS); } // if invalid point then look forward for the next valid point... if (isnan(rX) || isnan(rY)) { i0 = i0Start; while (i0 < iN && (isnan(rX) || isnan(rY))) { ++i0; rX = xv->interpolate(i0, NS); rY = yv->interpolate(i0, NS); } } if (xLog) { rX = logXLo(rX, xLogBase); } if (yLog) { rY = logYLo(rY, yLogBase); } last_x1 = m_X*rX + b_X; last_y1 = m_Y*rY + b_Y; i_pt = i0; while (i_pt < iN) { X2 = last_x1; Y2 = last_y1; ++i_pt; rX = xv->interpolate(i_pt, NS); rY = yv->interpolate(i_pt, NS); bool foundNan = false; // if necessary continue looking for the first valid point... while (i_pt < iN && (isnan(rX) || isnan(rY))) { #undef isnan foundNan = true; ++i_pt; rX = xv->interpolate(i_pt, NS); rY = yv->interpolate(i_pt, NS); } if (KDE_ISUNLIKELY(foundNan)) { if (points.size()>0) { _polygons.append(points); #ifdef BENCHMARK ++numberOfLinesDrawn; #endif } points.resize(0); if (overlap) { if (X2 >= Lx && X2 <= Hx) { if (maxY > Hy && minY <= Hy) maxY = Hy; if (minY < Ly && maxY >= Ly) minY = Ly; if (minY >= Ly && minY <= Hy && maxY >= Ly && maxY <= Hy) { #ifdef BENCHMARK ++numberOfLinesDrawn; #endif _lines.append(QLineF(X2, minY, X2, maxY)); } } overlap = false; } } if (xLog) { rX = logXLo(rX, xLogBase); } if (yLog) { rY = logYLo(rY, yLogBase); } X1 = m_X*rX + b_X; Y1 = m_Y*rY + b_Y; last_x1 = X1; last_y1 = Y1; if (KDE_ISLIKELY(!foundNan)) { if (KDE_ISLIKELY(samePixel(X1, X2))) { if (KDE_ISLIKELY(overlap)) { if (KDE_ISUNLIKELY(Y1 > maxY)) { maxY = Y1; } if (KDE_ISUNLIKELY(Y1 < minY)) { minY = Y1; } } else { if (Y1 < Y2) { minY = Y1; maxY = Y2; } else { maxY = Y1; minY = Y2; } overlap = true; } } else { if (KDE_ISLIKELY(overlap)) { if (KDE_ISLIKELY(X2 >= Lx && X2 <= Hx)) { if (KDE_ISUNLIKELY(maxY <= Hy && minY >= Ly)) { if (points.size()>MAX_NUM_POLYLINES-2) { _polygons.append(points); points.resize(0); #ifdef BENCHMARK ++numberOfLinesDrawn; #endif } if (KDE_ISUNLIKELY(minY == maxY)) { points.append(QPointF(X2, maxY)); } else if (KDE_ISUNLIKELY(Y2 == minY)) { points.append(QPointF(X2, maxY)); points.append(QPointF(X2, minY)); } else if (KDE_ISUNLIKELY(Y2 == maxY)) { points.append(QPointF(X2, minY)); points.append(QPointF(X2, maxY)); } else { points.append(QPointF(X2, minY)); points.append(QPointF(X2, maxY)); if (KDE_ISLIKELY(Y2 >= Ly && Y2 <= Hy)) { points.append(QPointF(X2, Y2)); } } lastPlottedX = X2; lastPlottedY = Y2; } else { if (KDE_ISUNLIKELY(maxY > Hy && minY <= Hy)) { maxY = Hy; } if (KDE_ISUNLIKELY(minY < Ly && maxY >= Ly)) { minY = Ly; } if (KDE_ISUNLIKELY(minY >= Ly && minY <= Hy && maxY >= Ly && maxY <= Hy)) { if (points.size()>0) { _polygons.append(points); points.resize(0); #ifdef BENCHMARK ++numberOfLinesDrawn; #endif } #ifdef BENCHMARK ++numberOfLinesDrawn; #endif _lines.append(QLineF(X2, minY, X2, maxY)); } } } overlap = false; } if (KDE_ISLIKELY(!((X1 < Lx && X2 < Lx) || (X1 > Hx && X2 > Hx)))) { // trim the line to be within the plot... if (KDE_ISUNLIKELY(isinf(X1))) { Y1 = Y2; if (X1 > 0.0) { X1 = Hx; } else { X1 = Lx; } } if (KDE_ISUNLIKELY(isinf(X2))) { Y2 = Y1; if (X2 > 0.0) { X2 = Hx; } else { X2 = Lx; } } if (KDE_ISUNLIKELY(isinf(Y1))) { X1 = X2; if (Y1 > 0.0) { Y1 = Hy; } else { Y1 = Ly; } } if (KDE_ISUNLIKELY(isinf(Y2))) { X2 = X1; if (Y2 > 0.0) { Y2 = Hy; } else { Y2 = Ly; } } if (KDE_ISUNLIKELY(X1 < Lx && X2 > Lx)) { Y1 = (Y2 - Y1) / (X2 - X1) * (Lx - X1) + Y1; X1 = Lx; } else if (KDE_ISUNLIKELY(X2 < Lx && X1 > Lx)) { Y2 = (Y1 - Y2) / (X1 - X2) * (Lx - X2) + Y2; X2 = Lx; } if (KDE_ISUNLIKELY(X1 < Hx && X2 > Hx)) { Y2 = (Y2 - Y1) / (X2 - X1) * (Hx - X1) + Y1; X2 = Hx; } else if (KDE_ISUNLIKELY(X2 < Hx && X1 > Hx)) { Y1 = (Y1 - Y2) / (X1 - X2) * (Hx - X2) + Y2; X1 = Hx; } if (KDE_ISUNLIKELY(Y1 < Ly && Y2 > Ly)) { X1 = (X2 - X1) / (Y2 - Y1) * (Ly - Y1) + X1; Y1 = Ly; } else if (KDE_ISUNLIKELY(Y2 < Ly && Y1 > Ly)) { X2 = (X1 - X2) / (Y1 - Y2) * (Ly - Y2) + X2; Y2 = Ly; } if (KDE_ISUNLIKELY(Y1 < Hy && Y2 > Hy)) { X2 = (X2 - X1) / (Y2 - Y1) * (Hy - Y1) + X1; Y2 = Hy; } else if (KDE_ISUNLIKELY(Y2 < Hy && Y1 > Hy)) { X1 = (X1 - X2) / (Y1 - Y2) * (Hy - Y2) + X2; Y1 = Hy; } #ifdef DEBUG_VECTOR_CURVE bool xInBounds = (X1 >= Lx && X1 <= Hx && X2 >= Lx && X2 <= Hx); bool yInBounds = (Y1 >= Ly && Y1 <= Hy && Y2 >= Ly && Y2 <= Hy); if (!xInBounds) qDebug() << "x not in bounds" << "X1:" << X1 << "X2:" << X2 << "Lx:" << Lx << "Hx:" << Hx << endl; if (!yInBounds) qDebug() << "y not in bounds" << "Y1:" << Y1 << "Y2:" << Y2 << "Ly:" << Ly << "Hy:" << Hy << endl; #endif if (X1 >= Lx && X1 <= Hx && X2 >= Lx && X2 <= Hx && Y1 >= Ly && Y1 <= Hy && Y2 >= Ly && Y2 <= Hy) { if (KDE_ISUNLIKELY(points.size()==0)) { points.append(QPointF(X2, Y2)); points.append(QPointF(X1, Y1)); } else if (samePixel(lastPlottedX, X2) && samePixel(lastPlottedY,Y2) && index < MAX_NUM_POLYLINES) { points.append(QPointF(X1, Y1)); } else { if (KDE_ISLIKELY(points.size()>1)) { _polygons.append(points); points.resize(0); #ifdef BENCHMARK ++numberOfLinesDrawn; #endif } points.append(QPointF(X2, Y2)); points.append(QPointF(X1, Y1)); } lastPlottedX = X1; lastPlottedY = Y1; } } } // end if (X1 == X2) } // end if (!foundNan) } // end while // we might a have polyline left undrawn... if (points.size()>1) { _polygons.append(points); points.resize(0); #ifdef BENCHMARK ++numberOfLinesDrawn; #endif } // we might have some overlapping points still unplotted... if (overlap) { if (X2 >= Lx && X2 <= Hx) { if (maxY > Hy && minY <= Hy) { maxY = Hy; } if (minY < Ly && maxY >= Ly) { minY = Ly; } if (minY >= Ly && minY <= Hy && maxY >= Ly && maxY <= Hy) { #ifdef BENCHMARK ++numberOfLinesDrawn; #endif _lines.append(QLineF(X2, minY, X2, maxY)); } } overlap = false; } } // end if hasLines() #ifdef BENCHMARK clock_t linesEnd = clock(); std::cout << "\n Lines clocks: " << (linesEnd - linesStart) << "\n"; b_1 = benchtmp.elapsed(); #endif VectorPtr exv = _inputVectors.contains(EXVECTOR) ? *_inputVectors.find(EXVECTOR) : 0; VectorPtr eyv = _inputVectors.contains(EYVECTOR) ? *_inputVectors.find(EYVECTOR) : 0; VectorPtr exmv = _inputVectors.contains(EXMINUSVECTOR) ? *_inputVectors.find(EXMINUSVECTOR) : 0; VectorPtr eymv = _inputVectors.contains(EYMINUSVECTOR) ? *_inputVectors.find(EYMINUSVECTOR) : 0; // draw the bargraph bars, if any... if (hasBars()) { bool visible = true; double rX2 = 0.0; double drX = 0.0; QRectF lastRect; if (!exv) { // determine the bar position width. NOTE: This is done // only if xv->isRising() as in this case the calculation // is simple... drX = (maxX() - minX())/double(sampleCount()); if (xv->isRising()) { double oldX = 0.0; for (i_pt = i0; i_pt <= iN; i_pt++) { rX = xv->interpolate(i_pt, NS); if (i_pt > i0) { if (rX - oldX < drX) { drX = rX - oldX; } } oldX = rX; } } } for (i_pt = i0; i_pt <= iN; i_pt++) { visible = true; if (exv) { drX = exv->interpolate(i_pt, NS); } rX = xv->interpolate(i_pt, NS); rY = yv->interpolate(i_pt, NS); rX -= drX/2.0; rX2 = rX + drX; if (xLog) { rX = logXLo(rX, xLogBase); rX2 = logXLo(rX2, xLogBase); } if (yLog) { rY = logYLo(rY, yLogBase); Y2 = Hy; } else { Y2 = b_Y; } X1 = m_X * rX + b_X; X2 = m_X * rX2 + b_X; Y1 = m_Y * rY + b_Y; if ((X1 > Hx) || (X2 < Lx) || (Y1 == Ly && Y2 == Ly) || (Y1 == Hy && Y2 == Hy)) { visible = false; } if (visible) { QRectF rect(X1, Y1, X2 - X1, Y2 - Y1); if (!lastRect.contains(rect)) { if (barStyle() == 1) { // filled _filledRects.append(rect); } else { _rects.append(rect); } lastRect = rect; #ifdef BENCHMARK ++numberOfBarsDrawn; #endif } } } } #ifdef BENCHMARK b_2 = benchtmp.elapsed(); #endif // draw the points, if any... if (hasPoints()) { const double w = Hx - Lx; const double h = Hy - Ly; int size = 0; if (hasLines() && pointDensity() != 0) { size = int(qMax(w, h)) / int(pow(3.0, POINTDENSITY_MAXTYPE - pointDensity())); } QRectF rect(Lx, Ly, w, h); QPointF pt, lastPt; for (i_pt = i0; i_pt <= iN; ++i_pt) { rX = xv->interpolate(i_pt, NS); rY = yv->interpolate(i_pt, NS); if (xLog) { rX = logXLo(rX, xLogBase); } if (yLog) { rY = logYLo(rY, yLogBase); } pt.setX(m_X * rX + b_X); pt.setY(m_Y * rY + b_Y); if (rect.contains(pt) && pt != lastPt && (lastPt.isNull() || !((abs(pt.x() - lastPt.x()) < size) || (abs(pt.y() - lastPt.y()) < size)))) { #ifdef BENCHMARK ++numberOfPointsDrawn; #endif lastPt = pt; _points.append(pt); } } } _head_valid = false; if (hasHead()) { const double w = Hx - Lx; const double h = Hy - Ly; QRectF rect(Lx, Ly, w, h); rX = xv->interpolate(NS-1, NS); rY = yv->interpolate(NS-1, NS); if (xLog) { rX = logXLo(rX, xLogBase); } if (yLog) { rY = logYLo(rY, yLogBase); } _head.setX(m_X * rX + b_X); _head.setY(m_Y * rY + b_Y); if (rect.contains(_head)) { _head_valid = true; } } #ifdef BENCHMARK b_3 = benchtmp.elapsed(); #endif // draw the x-errors, if any... if ((exv || exmv) && !hasBars()) { double rX1; double rX2; bool do_low_flag = true; bool do_high_flag = true; bool errorSame = false; if (exv && exmv) { if (exv->shortName() == exmv->shortName()) { errorSame = true; } } for (i_pt = i0; i_pt <= iN; i_pt++) { do_low_flag = true; do_high_flag = true; rX = xv->interpolate(i_pt, NS); rY = yv->interpolate(i_pt, NS); if (errorSame) { rEX = fabs(exv->interpolate(i_pt, NS)); if (xLog) { rX1 = logXLo(rX - rEX, xLogBase); rX2 = logXLo(rX + rEX, xLogBase); } else { rX1 = rX - rEX; rX2 = rX + rEX; } } else if (exv && exmv) { double rEXHi = fabs(exv->interpolate(i_pt, NS)); double rEXLo = fabs(exmv->interpolate(i_pt, NS)); if (xLog) { rX1 = logXLo(rX - rEXLo, xLogBase); rX2 = logXLo(rX + rEXHi, xLogBase); } else { rX1 = rX - rEXLo; rX2 = rX + rEXHi; } } else if (exv) { rEX = exv->interpolate(i_pt, NS); if (xLog) { rX1 = logXLo(rX, xLogBase); rX2 = logXLo(rX + fabs(rEX), xLogBase); } else { rX1 = rX; rX2 = rX + fabs(rEX); } do_low_flag = false; } else { rEX = fabs(exmv->interpolate(i_pt, NS)); if (xLog) { rX1 = logXLo(rX - rEX, xLogBase); rX2 = logXLo(rX, xLogBase); } else { rX1 = rX - rEX; rX2 = rX; } do_high_flag = false; } if (yLog) { rY = logYLo(rY, yLogBase); } X1 = m_X * rX1 + b_X; X2 = m_X * rX2 + b_X; Y1 = m_Y * rY + b_Y; if (X1 < Lx && X2 > Lx) { X1 = Lx; do_low_flag = false; } if (X1 < Hx && X2 > Hx) { X2 = Hx; do_high_flag = false; } if (X1 >= Lx && X2 <= Hx && Y1 >= Ly && Y1 <= Hy) { _lines.append(QLineF(X1, Y1, X2, Y1)); if (do_low_flag) { _lines.append(QLineF(X1, Y1 + pointDim, X1, Y1 - pointDim)); } if (do_high_flag) { _lines.append(QLineF(X2, Y1 + pointDim, X2, Y1 - pointDim)); } } } } // draw the y-errors, if any... if (eyv || eymv) { double rY1; double rY2; bool do_low_flag = true; bool do_high_flag = true; bool errorSame = false; if (eyv && eymv) { if (eyv->shortName() == eymv->shortName()) { errorSame = true; } } for (i_pt = i0; i_pt <= iN; i_pt++) { do_low_flag = true; do_high_flag = true; rX = xv->interpolate(i_pt, NS); rY = yv->interpolate(i_pt, NS); if (errorSame) { rEY = eyv->interpolate(i_pt, NS); if (yLog) { rY1 = logYLo(rY-fabs(rEY), yLogBase); rY2 = logYLo(rY+fabs(rEY), yLogBase); } else { rY1 = rY-fabs(rEY); rY2 = rY+fabs(rEY); } } else if (eyv && eymv) { double rEYHi = fabs(eyv->interpolate(i_pt, NS)); double rEYLo = fabs(eymv->interpolate(i_pt, NS)); if (yLog) { rY1 = logYLo(rY - rEYLo, yLogBase); rY2 = logYLo(rY + rEYHi, yLogBase); } else { rY1 = rY - rEYLo; rY2 = rY + rEYHi; } } else if (eyv) { rEY = fabs(eyv->interpolate(i_pt, NS)); if (yLog) { rY1 = logYLo(rY, yLogBase); rY2 = logYLo(rY + rEY, yLogBase); } else { rY1 = rY; rY2 = rY + rEY; } do_low_flag = false; } else { rEY = fabs(eymv->interpolate(i_pt, NS)); if (yLog) { rY1 = logYLo(rY - rEY, yLogBase); rY2 = logYLo(rY, yLogBase); } else { rY1 = rY - rEY; rY2 = rY; } do_high_flag = false; } if (xLog) { rX = logXLo(rX, xLogBase); } X1 = m_X * rX + b_X; Y1 = m_Y * rY1 + b_Y; Y2 = m_Y * rY2 + b_Y; if (Y1 < Ly && Y2 > Ly) { Y1 = Ly; do_low_flag = false; } if (Y1 < Hy && Y2 > Hy) { Y2 = Hy; do_high_flag = false; } if (X1 >= Lx && X1 <= Hx && Y1 >= Ly && Y2 <= Hy) { _lines.append(QLineF(X1, Y1, X1, Y2)); if (do_low_flag) { _lines.append(QLineF(X1 + pointDim, Y1, X1 - pointDim, Y1)); } if (do_high_flag) { _lines.append(QLineF(X1 + pointDim, Y2, X1 - pointDim, Y2)); } } } } // end if (hasYError()) } // end if (sampleCount() > 0) #ifdef BENCHMARK b_4 = benchtmp.elapsed(); #endif #ifdef BENCHMARK int i = bench_time.elapsed(); //qDebug() << endl << "Plotting curve " << (void *)this << ": " << i << "ms"; //qDebug() << " Without locks: " << b_4 << "ms"; //qDebug() << " Number of lines drawn:" << numberOfLinesDrawn; //qDebug() << " Number of points drawn:" << numberOfPointsDrawn; //qDebug() << " Number of bars drawn:" << numberOfBarsDrawn; std::cout << "\nPlotting curve " << (void *)this << ": " << i << "ms"; std::cout << "\n Without locks: " << b_4 << "ms"; std::cout << "\n Number of lines drawn:" << numberOfLinesDrawn; std::cout << "\n Number of points drawn:" << numberOfPointsDrawn; std::cout << "\n Number of bars drawn:" << numberOfBarsDrawn; if (b_1 > 0) std::cout << "\n Lines: " << b_1 << "ms\n"; if (b_2 - b_1 > 0) std::cout << "\n Bars: " << (b_2 - b_1) << "ms\n"; if (b_3 - b_2 > 0) std::cout << "\n Points: " << (b_3 - b_2) << "ms\n"; if (b_4 - b_3 > 0) std::cout << "\n Errors: " << (b_4 - b_3) << "ms\n"; #endif } void Curve::yRange(double xFrom, double xTo, double* yMin, double* yMax) { if (!yMin || !yMax) { return; } VectorPtr xv = *_inputVectors.find(XVECTOR); VectorPtr yv = *_inputVectors.find(YVECTOR); if (!xv || !yv) { *yMin = *yMax = 0; return; } // get range of the curve to search for min/max int i0, iN; if (xv->isRising()) { i0 = indexNearX(xFrom, xv, NS); iN = indexNearX(xTo, xv, NS); } else { i0 = 0; iN = sampleCount() - 1; } // search for min/max bool first = true; double newYMax = 0, newYMin = 0; for (int i_pt = i0; i_pt <= iN; i_pt++) { double rX = xv->interpolate(i_pt, NS); double rY = yv->interpolate(i_pt, NS); // make sure this point is visible if (rX >= xFrom && rX <= xTo) { // update min/max if (first || rY > newYMax) { newYMax = rY; } if (first || rY < newYMin) { newYMin = rY; } first = false; } } *yMin = newYMin; *yMax = newYMax; } DataObjectPtr Curve::providerDataObject() const { DataObjectPtr provider = 0L; // FIXME: fix this.. I don't know what's going on here #if 0 vectorList.lock().readLock(); VectorPtr vp = *vectorList.findTag(yVTag().tag()); // FIXME: should use full tag vectorList.lock().unlock(); if (vp) { vp->readLock(); provider = kst_cast(vp->provider()); vp->unlock(); } #endif return provider; } double Curve::distanceToPoint(double xpos, double dx, double ypos) const { // find the y distance between the curve and a point. return 1.0E300 if this distance is undefined. i don't want to use -1 because it will make the code which uses this function messy. VectorPtr xv = *_inputVectors.find(XVECTOR); if (!xv) { return 1.0E300; // anything better we can do? } double distance = 1.0E300; int i_near_x = getIndexNearXY(xpos, dx, ypos); double near_x, near_y; point(i_near_x, near_x, near_y); if (fabs(near_x - xpos) < dx) { distance = fabs(ypos - near_y); // initial estimate. } if (hasLines() && xv->isRising()) { // if hasLines then we should find the distance between the curve and the point, not the data and // the point. if isRising because it is (probably) to slow to use this technique if the data is // unordered. borrowed from indexNearX. use binary search to find the indices immediately above // and below our xpos. int i_top = NS - 1; int i_bot = 0; while (i_bot + 1 < i_top) { int i0 = (i_top + i_bot)/2; double rX = xv->interpolate(i0, NS); if (xpos < rX) { i_top = i0; } else { i_bot = i0; } } // end borrowed double x_bot, y_bot, x_top, y_top; point(i_bot, x_bot, y_bot); point(i_top, x_top, y_top); if (x_bot <= xpos && x_top >= xpos) { near_y = (y_top - y_bot) / (x_top - x_bot) * (xpos - x_bot) + y_bot; // calculate y value for line segment between x_bot and x_top. if (fabs(ypos - near_y) < distance) { distance = fabs(ypos - near_y); } } } return distance; } void Curve::paintLegendSymbol(QPainter *p, const QRectF& bound) { int width; if (lineWidth() == 0) { width = 1; } else { width = lineWidth(); } p->save(); if (hasLines()) { // draw a line from left to right centered vertically p->setPen(QPen(color(), width, Kst::LineStyle[lineStyle()])); p->drawLine(QLineF(bound.left(), bound.top() + bound.height()*.5, bound.right(), bound.top() + bound.height()*.5)); } if (hasPoints()) { // draw a point in the middle p->setPen(QPen(color(), width)); CurvePointSymbol::draw(PointType, p, bound.left() + bound.width()*.5, bound.top() + bound.height()*.5, width, 600); } p->restore(); } QString Curve::_automaticDescriptiveName() const { return i18n("%1 vs %2").arg(yVector()->descriptiveName()).arg(xVector()->descriptiveName()); } QString Curve::descriptionTip() const { QString tip; tip = i18n("Curve: %1\nX: %2\nY: %3").arg(Name()).arg(xVector()->descriptionTip()).arg(yVector()->descriptionTip()); if (hasXError()) { tip += i18n("\nX+ Error: %1").arg(xErrorVector()->Name()); } if (hasXMinusError()) { tip += i18n("\nX- Error: %1").arg(xMinusErrorVector()->Name()); } if (hasYError()) { tip += i18n("\nY+ Error: %1").arg(yErrorVector()->Name()); } if (hasYMinusError()) { tip += i18n("\nY- Error: %1").arg(yMinusErrorVector()->Name()); } if (hasLines()) { tip += i18n("\nLines: Width %1 and Style %2").arg(lineWidth()).arg(lineStyle()); } if (hasPoints()) { tip += i18n("\nPoints: Style %1").arg(pointType()); } if (hasBars()) { tip += i18n("\nBars"); } return tip; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/painter.cpp000644 001750 001750 00000004366 11544160207 020001 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2005 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "painter.h" namespace Kst { Painter::Painter(PaintType t) : QPainter(), _type(t), _drawInlineUI(false), _makingMask(false) { } Painter::~Painter() { } void Painter::setType(PaintType t) { _type = t; } Painter::PaintType Painter::type() const { return _type; } bool Painter::drawInlineUI() const { return _drawInlineUI; } void Painter::setDrawInlineUI(bool draw) { _drawInlineUI = draw; } bool Painter::makingMask() const { return _makingMask; } void Painter::setMakingMask(bool making) { _makingMask = making; } int Painter::lineWidthAdjustmentFactor() const { int factor = 1; if (type() == P_PRINT || type() == P_EXPORT) { const QRect& w(window()); // // we want a line width of 1 to give a width of approximately 1 pt (where 1 pt = 1/72 // inch) when printing on letter sized paper. Assuming a margin of 0.25 inch in one // direction (on both sides) and 0.5 inch in the other direction (again on both sides) // and a printer resolution of 600 dpi: // // w.width() + w.height() = ( 8 + 11 - ( 2 * 0.5 ) - ( 2 * 0.25 ) ) * 600 = 10500 // // we want a scale factor of 600/72 = 8.333 in the line width, so our magic number simply // becomes: // // w.width() + w.height() / scale factor = 10200 / 8.333 ~ 1300 // factor = (w.width() + w.height()) / 1300; } return factor > 0 ? factor : 1; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/dialoglauncher.cpp000644 001750 001750 00000007110 11544160207 021306 0ustar00synthsynth000000 000000 /*************************************************************************** dialoglauncher.cpp ------------------- begin : Nov. 24, 2004 copyright : (C) 2004 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dialoglauncher.h" #include namespace Kst { DialogLauncher *DialogLauncher::_self = 0L; void DialogLauncher::cleanup() { delete _self; _self = 0; } DialogLauncher *DialogLauncher::self() { Q_ASSERT(_self); return _self; } void DialogLauncher::replaceSelf(DialogLauncher *newInstance) { cleanup(); _self = newInstance; } DialogLauncher::DialogLauncher() { qAddPostRoutine(DialogLauncher::cleanup); } DialogLauncher::~DialogLauncher() { } void DialogLauncher::showVectorDialog(QString &vectorname, ObjectPtr objectPtr, bool modal) { Q_UNUSED(objectPtr); Q_UNUSED(vectorname); Q_UNUSED(modal); } void DialogLauncher::showMatrixDialog(QString &matrixName, ObjectPtr objectPtr, bool modal) { Q_UNUSED(objectPtr); Q_UNUSED(matrixName); Q_UNUSED(modal); } void DialogLauncher::showScalarDialog(QString &scalarname, ObjectPtr objectPtr, bool modal) { Q_UNUSED(objectPtr); Q_UNUSED(scalarname); Q_UNUSED(modal); } void DialogLauncher::showStringDialog(QString &scalarname, ObjectPtr objectPtr, bool modal) { Q_UNUSED(objectPtr); Q_UNUSED(scalarname); Q_UNUSED(modal); } void DialogLauncher::showCurveDialog(ObjectPtr objectPtr, VectorPtr vector) { Q_UNUSED(objectPtr); Q_UNUSED(vector); } void DialogLauncher::showMultiCurveDialog(QList curves) { Q_UNUSED(curves); } void DialogLauncher::showImageDialog(ObjectPtr objectPtr, MatrixPtr matrix) { Q_UNUSED(objectPtr); Q_UNUSED(matrix); } void DialogLauncher::showMultiImageDialog(QList images) { Q_UNUSED(images); } void DialogLauncher::showEquationDialog(ObjectPtr objectPtr) { Q_UNUSED(objectPtr); } void DialogLauncher::showEventMonitorDialog(ObjectPtr objectPtr) { Q_UNUSED(objectPtr); } void DialogLauncher::showHistogramDialog(ObjectPtr objectPtr, VectorPtr vector) { Q_UNUSED(objectPtr); Q_UNUSED(vector); } void DialogLauncher::showPowerSpectrumDialog(ObjectPtr objectPtr, VectorPtr vector) { Q_UNUSED(objectPtr); Q_UNUSED(vector); } void DialogLauncher::showCSDDialog(ObjectPtr objectPtr, VectorPtr vector) { Q_UNUSED(objectPtr); Q_UNUSED(vector); } void DialogLauncher::showBasicPluginDialog(QString pluginName, ObjectPtr objectPtr, VectorPtr vectorX, VectorPtr vectorY, PlotItemInterface *plotItem) { Q_UNUSED(pluginName); Q_UNUSED(objectPtr); Q_UNUSED(vectorX); Q_UNUSED(vectorY); Q_UNUSED(plotItem); } void DialogLauncher::showObjectDialog(ObjectPtr objectPtr) { Q_UNUSED(objectPtr); } void DialogLauncher::showMultiObjectDialog(QList objects) { Q_UNUSED(objects); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/linestyle.h000644 001750 001750 00000002445 11544160207 020010 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2004 by University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #ifndef LINESTYLE_H #define LINESTYLE_H #include "kstmath_export.h" namespace Kst { KSTMATH_EXPORT extern const unsigned int LINESTYLE_MAXTYPE; KSTMATH_EXPORT extern Qt::PenStyle LineStyle[]; #define POINTDENSITY_MAXTYPE 4 #define LINEWIDTH_MAX 5 } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/curvehint.h000644 001750 001750 00000003312 11544160207 020001 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CURVEHINT_H #define CURVEHINT_H #include #include #include "vector.h" namespace Kst { class Relation; class CurveHint : public Shared { friend class DataObject; public: explicit CurveHint(const QString& name = QString(), const QString& x = QString(), const QString& y = QString()); virtual ~CurveHint(); virtual const QString& curveName() const { return _curveName; } virtual const QString& xVectorName() const; virtual const QString& yVectorName() const; #if 0 virtual VectorPtr xVector() const; virtual VectorPtr yVector() const; virtual SharedPtr makeCurve(const QString& tag, const QColor& color) const; #endif protected: QString _curveName, _xVectorName, _yVectorName; }; typedef SharedPtr CurveHintPtr; typedef QList CurveHintList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/eventmonitorentry.cpp000644 001750 001750 00000026006 11544160207 022145 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2004 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include // include files for Qt #include #include #include // application specific includes #include "enodes.h" #include "emailthread.h" #include "dialoglauncher.h" #include "datacollection.h" #include "eventmonitorentry.h" #include #include "debug.h" #include #ifndef Q_WS_WIN32 #include #endif extern int yyparse(Kst::ObjectStore *store); extern void *ParsedEquation; extern struct yy_buffer_state *yy_scan_string(const char*); namespace Kst { const QString EventMonitorEntry::staticTypeString = I18N_NOOP("Event Monitor"); const QString EventMonitorEntry::staticTypeTag = I18N_NOOP("eventmonitor"); namespace { const int EventMonitorEventType = int(QEvent::User) + 2931; class EventMonitorEvent : public QEvent { public: EventMonitorEvent(const QString& msg) : QEvent(QEvent::Type(EventMonitorEventType)), logMessage(msg) {} QString logMessage; }; } //extern "C" int yyparse(); //extern "C" void *ParsedEquation; //extern "C" struct yy_buffer_state *yy_scan_string(const char*); const QString EventMonitorEntry::OUTXVECTOR = "X"; const QString EventMonitorEntry::OUTYVECTOR = "Y"; EventMonitorEntry::EventMonitorEntry(ObjectStore *store) : DataObject(store) { _level = Debug::Warning; _logDebug = true; _logEMail = false; _logELOG = false; const int NS = 1; _numDone = 0; _isValid = false; _pExpression = 0L; _typeString = staticTypeString; _type = "Event"; _initializeShortName(); VectorPtr xv = store->createObject(); xv->resize(NS); xv->setProvider(this); _xVector = _outputVectors.insert(OUTXVECTOR, xv); VectorPtr yv = store->createObject(); yv->resize(NS); yv->setProvider(this); _yVector = _outputVectors.insert(OUTYVECTOR, yv); } void EventMonitorEntry::_initializeShortName() { } bool EventMonitorEntry::reparse() { _isValid = false; if (!_event.isEmpty()) { Equations::mutex().lock(); yy_scan_string(_event.toLatin1()); int rc = yyparse(store()); if (rc == 0) { _pExpression = static_cast(ParsedEquation); Equations::Context ctx; Equations::FoldVisitor vis(&ctx, &_pExpression); StringMap stm; _pExpression->collectObjects(_vectorsUsed, _inputScalars, stm); for (ScalarMap::ConstIterator i = _inputScalars.begin(); i != _inputScalars.end(); ++i) { if ((*i)->myLockStatus() == KstRWLock::UNLOCKED) { (*i)->readLock(); } } Equations::mutex().unlock(); _isValid = true; } else { delete (Equations::Node*)ParsedEquation; Equations::mutex().unlock(); } ParsedEquation = 0L; } return _isValid; } void EventMonitorEntry::save(QXmlStreamWriter &xml) { xml.writeStartElement(staticTypeTag); xml.writeAttribute("equation", _event); xml.writeAttribute("description", _description); xml.writeAttribute("logdebug", QVariant(_logDebug).toString()); xml.writeAttribute("loglevel", QVariant(_level).toString()); xml.writeAttribute("logemail", QVariant(_logEMail).toString()); xml.writeAttribute("logelog", QVariant(_logELOG).toString()); xml.writeAttribute("emailrecipients", _eMailRecipients); xml.writeAttribute("script", _script); xml.writeEndElement(); } EventMonitorEntry::~EventMonitorEntry() { logImmediately(false); delete _pExpression; _pExpression = 0L; } void EventMonitorEntry::internalUpdate() { writeLockInputsAndOutputs(); if (!_pExpression) { reparse(); } VectorPtr xv = *_xVector; VectorPtr yv = *_yVector; int ns = 1; for (VectorMap::ConstIterator i = _vectorsUsed.begin(); i != _vectorsUsed.end(); ++i) { ns = qMax(ns, i.value()->length()); } double *rawValuesX = 0L; double *rawValuesY = 0L; if (xv && yv) { if (xv->resize(ns)) { rawValuesX = xv->value(); } if (yv->resize(ns)) { rawValuesY = yv->value(); } } Equations::Context ctx; ctx.sampleCount = ns; ctx.x = 0.0; if (needToEvaluate()) { if (_pExpression) { for (ctx.i = _numDone; ctx.i < ns; ++ctx.i) { const double value = _pExpression->value(&ctx); if (value != 0.0) { // The expression evaluates to true log(ctx.i); if (rawValuesX && rawValuesY) { rawValuesX[ctx.i] = ctx.i; rawValuesY[ctx.i] = 1.0; } } else { if (rawValuesX && rawValuesY) { rawValuesX[ctx.i] = ctx.i; rawValuesY[ctx.i] = 0.0; } } } _numDone = ns; logImmediately(); } } else { _numDone = ns; } unlockInputsAndOutputs(); return; } void EventMonitorEntry::setEvent(const QString& strEvent) { if (_event != strEvent) { _event = strEvent; _vectorsUsed.clear(); _inputScalars.clear(); _numDone = 0; _isValid = false; delete _pExpression; _pExpression = 0L; } } bool EventMonitorEntry::needToEvaluate() { return _logDebug || _logEMail || _logELOG || !_script.isEmpty(); } void EventMonitorEntry::logImmediately(bool sendEvent) { const int arraySize = _indexArray.size(); if (arraySize > 0) { QString logMessage; QString rangeString; bool makeRange = false; int idx = 0; int idxOld = 0; for (int i = 0; i < arraySize; ++i) { idx = _indexArray.at(i); if (i == 0) { rangeString.setNum(idx); } else if (!makeRange && idx == idxOld + 1) { makeRange = true; } else if (makeRange && idx != idxOld + 1) { rangeString = rangeString + QString(" - %1, %2").arg(idxOld).arg(idx); makeRange = false; } else if (idx != idxOld + 1) { rangeString = rangeString + QString(", %1").arg(idx); } idxOld = idx; } if (makeRange) { rangeString = rangeString + QString(", %1").arg(idx); } if (_description.isEmpty()) { logMessage = "Event Monitor: " + _event + ": " + rangeString; } else { logMessage = "Event Monitor: " + _description + ": " + rangeString; } _indexArray.clear(); if (sendEvent) { // update thread QApplication::postEvent(this, new EventMonitorEvent(logMessage)); } else { // GUI thread doLog(logMessage); } } } bool EventMonitorEntry::event(QEvent *e) { if (e->type() == EventMonitorEventType) { readLock(); doLog(static_cast(e)->logMessage); unlock(); return true; } return false; } void EventMonitorEntry::doLog(const QString& logMessage) const { if (_logDebug) { Debug::self()->log(logMessage, _level); } if (_logEMail && !_eMailRecipients.isEmpty()) { EMailThread* thread = new EMailThread(_eMailRecipients, "Kst Event Monitoring Notification", logMessage); thread->send(); } //FIXME ELOG need to be implemented. // if (_logELOG) { // KstApp::inst()->EventELOGSubmitEntry(logMessage); // } //FIXME PORT! // if (!_script.isEmpty()) { // DCOPRef ref(QString("kst-%1").arg(getpid()).toLatin1(), "KstScript"); // ref.send("evaluate", _script); // } } void EventMonitorEntry::log(int idx) { _indexArray.append(idx); if (_indexArray.size() > 1000) { logImmediately(); } } QString EventMonitorEntry::propertyString() const { return _event; } void EventMonitorEntry::showNewDialog() { DialogLauncher::self()->showEventMonitorDialog(); } void EventMonitorEntry::showEditDialog() { DialogLauncher::self()->showEventMonitorDialog(); } const QString& EventMonitorEntry::scriptCode() const { return _script; } void EventMonitorEntry::setScriptCode(const QString& script) { if (_script != script) { _script = script; } } void EventMonitorEntry::setDescription(const QString& str) { if (_description != str) { _description = str; } } void EventMonitorEntry::setLevel(Debug::LogLevel level) { if (_level != level) { _level = level; } } void EventMonitorEntry::setExpression(Equations::Node* pExpression) { if (_pExpression != pExpression) { _pExpression = pExpression; } } void EventMonitorEntry::setLogDebug(bool logDebug) { if (_logDebug != logDebug) { _logDebug = logDebug; } } void EventMonitorEntry::setLogEMail(bool logEMail) { if (logEMail != _logEMail) { _logEMail = logEMail; } } void EventMonitorEntry::setLogELOG(bool logELOG) { if (logELOG != _logELOG) { _logELOG = logELOG; } } void EventMonitorEntry::setEMailRecipients(const QString& str) { if (str != _eMailRecipients) { _eMailRecipients = str; } } DataObjectPtr EventMonitorEntry::makeDuplicate() const { EventMonitorEntryPtr eventMonitor = store()->createObject(); eventMonitor->setScriptCode(_script); eventMonitor->setEvent(_event); eventMonitor->setDescription(_description); eventMonitor->setLevel(_level); eventMonitor->setLogDebug(_logDebug); eventMonitor->setLogEMail(_logEMail); eventMonitor->setLogELOG(_logELOG); eventMonitor->setEMailRecipients(_eMailRecipients); if (descriptiveNameIsManual()) { eventMonitor->setDescriptiveName(descriptiveName()); } eventMonitor->reparse(); eventMonitor->writeLock(); eventMonitor->registerChange(); eventMonitor->unlock(); return DataObjectPtr(eventMonitor); } bool EventMonitorEntry::uses(ObjectPtr p) const { // check VectorsUsed in addition to _input*'s if (VectorPtr vect = kst_cast(p)) { for (VectorMap::ConstIterator j = _vectorsUsed.begin(); j != _vectorsUsed.end(); ++j) { if (j.value() == vect) { return true; } } } else if (DataObjectPtr obj = kst_cast(p) ) { // check all connections from this expression to p for (VectorMap::ConstIterator j = obj->outputVectors().begin(); j != obj->outputVectors().end(); ++j) { for (VectorMap::ConstIterator k = _vectorsUsed.begin(); k != _vectorsUsed.end(); ++k) { if (j.value() == k.value()) { return true; } } } } return DataObject::uses(p); } QString EventMonitorEntry::_automaticDescriptiveName() const { return i18n("event"); } QString EventMonitorEntry::descriptionTip() const { return i18n("Event: %1").arg(Name()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/curvefactory.h000644 001750 001750 00000002204 11544160207 020505 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CURVEFACTORY_H #define CURVEFACTORY_H #include "relationfactory.h" namespace Kst { class CurveFactory : public RelationFactory { public: CurveFactory(); ~CurveFactory(); RelationPtr generateRelation(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/labelparser.cpp000644 001750 001750 00000052355 11544160207 020634 0ustar00synthsynth000000 000000 /*************************************************************************** labelparser.cpp ---------------- begin : Dec 14 2004 Copyright (C) 2004, The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labelparser.h" #include #include #include #include using namespace Label; // Debug output for Parsing - 0 Off 1 On #define DEBUG_PARSING 0 #if DEBUG_PARSING #define dumpattr(node, text) do { printf("%s: bold:%d italic:%d underline:%d\n", text, (node)->attributes.bold, (node)->attributes.italic, (node)->attributes.underline); } while(0) #else #define dumpattr(node, text) #endif Chunk::Chunk(Chunk *parent, VOffset dir, bool isGroup, bool inherit) : next(0L), prev(0L), up(0L), down(0L), group(0L), scalar(false), linebreak(false), tab(false), vector(false), vOffset(dir) { assert(parent || vOffset == None); if (parent) { // attach and inherit switch (vOffset) { case None: if (isGroup) { parent->group = this; } else { while (parent->next) { parent = parent->next; } parent->next = this; } break; case Up: assert(!parent->up); parent->up = this; break; case Down: assert(!parent->down); parent->down = this; break; } if (inherit) { // inherit these properties from the parent attributes = parent->attributes; } prev = parent; } } Chunk::~Chunk() { // These are set to 0 by the child if they're non-zero delete next; delete up; delete down; delete group; group = 0L; if (prev) { switch (vOffset) { case None: prev->next = 0L; // Note: kind of does the wrong thing if we're a group... no issue though break; case Up: prev->up = 0L; break; case Down: prev->down = 0L; break; } prev = 0L; } } bool Chunk::locked() const { return scalar || group || linebreak || tab || vector; } Parsed::Parsed() : chunk(0L) { } Parsed::~Parsed() { delete chunk; chunk = 0L; } inline void setNormalChar(QChar c, Chunk **tail) { if (*tail && !(*tail)->locked()) { (*tail)->text += c; } else { Chunk *f = new Chunk(*tail, Chunk::None, false, true); f->text += c; *tail = f; } } inline QColor parseColor(const QString& txt, int *skip) { const int end = txt.indexOf('}'); if (skip) { *skip = end; } if (end == -1) { return QColor(); } const QString endPart = txt.left(end); QColor color(endPart); // This one is slow. If we support our own formats // outside of QColor, make sure that this is called // -after- we try our own formats. Every cycle // counts in here. #if 0 // This is rr,gg,bb support. I'm not sure about supporting H,S,V or even // about compatibility with LaTeX so for now we don't support it. If it's // ever re-enabled, make sure that testcases are added. if (!color.isValid()) { // the color is in the format "r,g,b" QStringList components = QStringList::split(',', endPart, true); if (components.count() == 3) { int colors[3] = { 0, 0, 0 }; int base = 10; // assume the colors are given as decimal numbers unless we have a hex value in the string if (endPart.find(QRegExp("[A-F]", false)) != -1) { base = 16; } bool ok = true; colors[0] = components[0].toInt(&ok, base); if (ok) { colors[1] = components[1].toInt(&ok, base); } if (ok) { colors[2] = components[2].toInt(&ok, base); } if (ok) { color.setRgb(colors[0], colors[1], colors[2]); } // Should error out? } } #endif return color; } static Chunk *parseInternal(Chunk *ctail, const QString& txt, uint& start, uint cnt, bool interpretNewLine); #define EXPAND_GREEK(L_U, L_L, REST, SKIP, UCODE) \ case L_L: \ x=0x20; \ case L_U: \ if (txt.mid(from + 1).startsWith(REST)) { \ *skip = SKIP; \ setNormalChar(QChar(UCODE+x), tail); \ return true; \ } \ break; inline bool parseOutChar(const QString& txt, uint from, int *skip, Chunk **tail, bool interpretNewLine) { QChar c = txt[from]; bool upper = false; *skip = 1; short x = 0; #if DEBUG_PARSING qDebug() << "----- parsing " << txt; #endif switch (c.unicode()) { EXPAND_GREEK('B', 'b', "eta", 4, 0x392) EXPAND_GREEK('D', 'd', "elta", 5, 0x394) EXPAND_GREEK('Z', 'z', "eta", 4, 0x396) EXPAND_GREEK('K', 'k', "appa", 5, 0x39a) EXPAND_GREEK('M', 'm', "u", 2, 0x39c) EXPAND_GREEK('X', 'x', "i", 2, 0x39e) EXPAND_GREEK('R', 'r', "ho", 3, 0x3a1) case 'a': x = 0x20; case 'A': if (txt.mid(from + 1).startsWith("lpha")) { *skip = 5; setNormalChar(QChar(0x391+x), tail); return true; } else if (txt.mid(from + 1).startsWith("pprox")) { *skip = 6; setNormalChar(QChar(0x2248), tail); return true; } break; case 'c': x = 0x20; case 'C': if (txt.mid(from + 1).startsWith("hi")) { *skip = 3; setNormalChar(QChar(0x3a7+x), tail); return true; } else if (txt.mid(from + 1).startsWith("dot")) { *skip = 4; setNormalChar(QChar(0x2219), tail); return true; } break; case 'e': x = 0x20; case 'E': if (txt.mid(from + 1).startsWith("psilon")) { *skip = 7; setNormalChar(QChar(0x395+x), tail); return true; } else if (txt.mid(from + 1).startsWith("ta")) { *skip = 3; setNormalChar(QChar(0x397+x), tail); return true; } else if (txt.mid(from + 1).startsWith("ll")) { *skip = 3; setNormalChar(QChar(0x2113), tail); return true; } break; case 'g': x = 0x20; case 'G': if (txt.mid(from + 1).startsWith("amma")) { *skip = 5; setNormalChar(QChar(0x393+x), tail); return true; } else if (txt.mid(from + 1).startsWith("eq")) { *skip = 3; setNormalChar(QChar(0x2265), tail); return true; } else if (txt.mid(from + 1).startsWith('e')) { *skip = 2; setNormalChar(QChar(0x2265), tail); return true; } break; case 'i': x = 0x20; case 'I': if (txt.mid(from + 1).startsWith("ota")) { *skip = 4; setNormalChar(QChar(0x399+x), tail); return true; } else if (!upper && txt.mid(from + 1).startsWith("nf")) { *skip = 3; setNormalChar(QChar(0x221E), tail); return true; } else if (!upper && txt.mid(from + 1).startsWith("nt")) { *skip = 3; setNormalChar(QChar(0x222B), tail); return true; } break; case 'l': x = 0x20; case 'L': if (txt.mid(from + 1).startsWith("ambda")) { *skip = 6; setNormalChar(QChar(0x39b+x), tail); return true; } else if (txt.mid(from + 1).startsWith("eq")) { *skip = 3; setNormalChar(QChar(0x2264), tail); return true; } else if (txt.mid(from + 1).startsWith('e')) { *skip = 2; setNormalChar(QChar(0x2264), tail); return true; } break; case 'n': x = 0x20; case 'N': if (txt.mid(from + 1).startsWith('u')) { *skip = 2; setNormalChar(QChar(0x39D+x), tail); return true; } else if (txt.mid(from + 1).startsWith('e')) { *skip = 2; setNormalChar(QChar(0x2260), tail); return true; } else if (interpretNewLine) { *skip = 1; if (!*tail || !(*tail)->text.isEmpty() || (*tail)->locked()) { *tail = new Chunk(*tail, Chunk::None, false, true); } (*tail)->linebreak = true; *tail = new Chunk(*tail, Chunk::None, false, true); return true; } else { *skip = 1; setNormalChar(QChar(0x20), tail); return true; } break; case 'o': x = 0x20; case 'O': if (txt.mid(from + 1).startsWith("verline{")) { if ((*tail)->group) { *tail = new Chunk(*tail, Chunk::None, false, true); } Chunk *working = new Chunk(*tail, Chunk::None, true, true); dumpattr(working, "start group for overline"); uint parseStart = from + 9; working->attributes.overline = true; parseInternal(working, txt, parseStart, txt.length(), interpretNewLine); *skip = parseStart - from + 1; dumpattr(working, "end group for overline"); return true; } else if (txt.mid(from + 1).startsWith("micron")) { *skip = 7; setNormalChar(QChar(0x39F+x), tail); return true; } else if (txt.mid(from + 1).startsWith("mega")) { *skip = 5; setNormalChar(QChar(0x3A9+x), tail); return true; } else if (txt.mid(from + 1).startsWith("dot")) { *skip = 4; setNormalChar(QChar(0x2299), tail); return true; } break; case 'p': x = 0x20; case 'P': if (txt.mid(from + 1).startsWith('i')) { *skip = 2; setNormalChar(QChar(0x3a0+x), tail); return true; } else if (txt.mid(from + 1).startsWith("hi")) { *skip = 3; setNormalChar(QChar(0x3A6+x), tail); return true; } else if (txt.mid(from + 1).startsWith("si")) { *skip = 3; setNormalChar(QChar(0x3A8+x), tail); return true; } else if (txt.mid(from + 1).startsWith("artial")) { *skip = 7; setNormalChar(QChar(0x2202), tail); return true; } else if (txt.mid(from + 1).startsWith("rod")) { *skip = 4; setNormalChar(QChar(0x220F), tail); return true; } else if (txt.mid(from + 1).startsWith('m')) { *skip = 2; setNormalChar(QChar(0xb1), tail); return true; } break; case 't': x = 0x20; case 'T': if (txt.mid(from + 1).startsWith("extcolor{")) { // \textcolor{color}{text} if ((*tail)->group) { *tail = new Chunk(*tail, Chunk::None, false, true); } Chunk *working = new Chunk(*tail, Chunk::None, true, true); dumpattr(working, "start group for textcolor"); uint parseStart = from + 10; int firstSkip = 0; working->attributes.color = parseColor(txt.mid(parseStart), &firstSkip); if (!working->attributes.color.isValid() || txt[parseStart + firstSkip + 1] != '{') { return false; } parseStart += firstSkip + 2; parseInternal(working, txt, parseStart, txt.length(), interpretNewLine); *skip = parseStart - from + 1; dumpattr(working, "end group for textcolor"); return true; } else if (txt.mid(from + 1).startsWith("extbf{")) { if ((*tail)->group) { *tail = new Chunk(*tail, Chunk::None, false, true); } Chunk *working = new Chunk(*tail, Chunk::None, true, true); dumpattr(working, "start group for textbf"); uint parseStart = from + 7; working->attributes.bold = true; parseInternal(working, txt, parseStart, txt.length(), interpretNewLine); *skip = parseStart - from + 1; dumpattr(working, "end group for textbf"); return true; } else if (txt.mid(from + 1).startsWith("extit{")) { if ((*tail)->group) { *tail = new Chunk(*tail, Chunk::None, false, true); } Chunk *working = new Chunk(*tail, Chunk::None, true, true); dumpattr(working, "start group for textit"); uint parseStart = from + 7; working->attributes.italic = true; parseInternal(working, txt, parseStart, txt.length(), interpretNewLine); *skip = parseStart - from + 1; dumpattr(working, "end group for textit"); return true; } else if (txt.mid(from + 1).startsWith("heta")) { *skip = 5; setNormalChar(QChar(0x398+x), tail); return true; } else if (txt.mid(from + 1).startsWith("au")) { *skip = 3; setNormalChar(QChar(0x3A4+x), tail); return true; } else { *skip = 1; if (!*tail || !(*tail)->text.isEmpty() || (*tail)->locked()) { *tail = new Chunk(*tail, Chunk::None, false, true); } (*tail)->tab = true; *tail = new Chunk(*tail, Chunk::None, false, true); return true; } break; case 's': x = 0x20; case 'S': if (txt.mid(from + 1).startsWith("igma")) { *skip = 5; setNormalChar(QChar(0x3A3+x), tail); return true; } else if (!upper && txt.mid(from + 1).startsWith("um")) { *skip = 3; setNormalChar(QChar(0x2211), tail); return true; } else if (!upper && txt.mid(from + 1).startsWith("qrt")) { *skip = 4; setNormalChar(QChar(0x221A), tail); return true; } break; case 'u': x = 0x20; case 'U': if (txt.mid(from + 1).startsWith("nderline{")) { if ((*tail)->group) { *tail = new Chunk(*tail, Chunk::None, false, true); } Chunk *working = new Chunk(*tail, Chunk::None, true, true); dumpattr(working, "start group for underline"); uint parseStart = from + 10; working->attributes.underline = true; parseInternal(working, txt, parseStart, txt.length(), interpretNewLine); *skip = parseStart - from + 1; dumpattr(working, "end group for underline"); return true; } else if (txt.mid(from + 1).startsWith("psilon")) { *skip = 7; setNormalChar(QChar(0x3A5+x), tail); return true; } break; default: break; } return false; } static Chunk *parseInternal(Chunk *ctail, const QString& txt, uint& start, uint cnt, bool interpretNewLine) { Chunk *chead = ctail; if (ctail->group) { ctail = new Chunk(ctail, Chunk::None, false, true); } for (uint& i = start; i < cnt; ++i) { QChar c = txt[i]; Chunk::VOffset dir = Chunk::Down; switch (c.unicode()) { case '\n': if (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) { while (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) { ctail = ctail->prev; } ctail = new Chunk(ctail, Chunk::None, false, true); } if (!ctail->text.isEmpty() || ctail->locked()) { if (ctail->vOffset != Chunk::None) { ctail = new Chunk(ctail->prev, Chunk::None, false, true); } else { ctail = new Chunk(ctail, Chunk::None, false, true); } } ctail->linebreak = true; ctail = new Chunk(ctail, Chunk::None, false, true); break; case '\t': if (!ctail->text.isEmpty() || ctail->locked()) { if (ctail->vOffset != Chunk::None) { ctail = new Chunk(ctail->prev, Chunk::None, false, true); } else { ctail = new Chunk(ctail, Chunk::None, false, true); } } ctail->tab = true; ctail = new Chunk(ctail, Chunk::None, false, true); break; case 0x5c: // \ /**/ if (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) { while (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) { ctail = ctail->prev; } ctail = new Chunk(ctail, Chunk::None, false, true); } if (ctail->vOffset != Chunk::None && !ctail->text.isEmpty()) { ctail = new Chunk(ctail->prev, Chunk::None, false, true); } ++i; if (i == cnt) { setNormalChar('\\', &ctail); } else { int skip = 0; if (!parseOutChar(txt, i, &skip, &ctail, interpretNewLine)) { setNormalChar(txt[i], &ctail); } else { i += skip - 1; } } break; case 0x5e: // ^ dir = Chunk::Up; case 0x5f: // _ (dir is set to Down at begining of loop) if (ctail->text.isEmpty() && !ctail->group) { setNormalChar(c, &ctail); } else { if (ctail->vOffset != Chunk::None) { if (ctail->vOffset != dir) { ctail = new Chunk(ctail->prev, dir, false, true); } else if (ctail->group) { ctail = new Chunk(ctail, dir, false, true); } else { ctail = new Chunk(ctail, dir, false, true); } } else { ctail = new Chunk(ctail, dir, false, true); } } break; case 0x7b: // { if (ctail->text.isEmpty() && !ctail->group) { bool rc = false; new Chunk(ctail, Chunk::None, true, true); dumpattr(ctail->group, "start group with non-group and empty text"); rc = 0L != parseInternal(ctail->group, txt, ++i, cnt, interpretNewLine); assert(rc); dumpattr(ctail->group, "after start group with non-group and empty text"); if (!rc) { return 0L; } } else { bool rc = false; if (ctail->vOffset == Chunk::None) { rc = 0L != parseInternal(new Chunk(ctail, Chunk::None, true, true), txt, ++i, cnt, interpretNewLine); } else { rc = 0L != parseInternal(new Chunk(ctail->prev, Chunk::None, true, true), txt, ++i, cnt, interpretNewLine); } if (!rc) { return 0L; } } break; case 0x7d: // } if (chead->prev && chead->prev->group == chead) { return chead; } else { setNormalChar(c, &ctail); } break; case '[': { bool vector = false; int vectorIndexStart = -1; int vectorIndexEnd = -1; int bracketStack = 1; int pos = -1; bool equation = txt[i + 1] == '='; for (uint searchPt = i + 1; bracketStack != 0 && searchPt < cnt; ++searchPt) { if (txt[searchPt] == ']') { if (--bracketStack == 0) { pos = searchPt; break; } else if (bracketStack == 1 && vector && vectorIndexEnd == -1) { vectorIndexEnd = searchPt - 1; } } else if (txt[searchPt] == '[') { ++bracketStack; if (!vector && !equation) { vector = true; vectorIndexStart = searchPt + 1; } } } if (pos < 0 || pos == int(i) + 1 /* empty [] */) { return 0L; } if (ctail->locked() || !ctail->text.isEmpty()) { if (ctail->vOffset != Chunk::None) { ctail = new Chunk(ctail->prev, Chunk::None, false, true); } else { ctail = new Chunk(ctail, Chunk::None, false, true); } } if (vector) { ctail->text = txt.mid(i + 1, vectorIndexStart - i - 2).trimmed(); ctail->expression = txt.mid(vectorIndexStart, vectorIndexEnd - vectorIndexStart + 1); ctail->vector = true; } else { ctail->text = txt.mid(i + 1, pos - i - 1).trimmed(); ctail->scalar = true; } i = uint(pos); } break; default: #if 0 if (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) { ctail = new Chunk(ctail->prev, Chunk::None, false, true); } #endif if (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) { while (ctail->vOffset != Chunk::None && (!ctail->text.isEmpty() || ctail->locked())) { ctail = ctail->prev; } ctail = new Chunk(ctail, Chunk::None, false, true); } setNormalChar(c, &ctail); break; } } return chead; } Parsed *Label::parse(const QString& txt, bool interpret, bool interpretNewLine) { Parsed *parsed = new Parsed; Chunk *ctail = parsed->chunk = new Chunk(0L); if (!interpret) { ctail->text = txt; return parsed; } uint start = 0; uint cnt = txt.length(); Chunk *rc = parseInternal(ctail, txt, start, cnt, interpretNewLine); if (!rc) { // Parse error - how to recover? delete parsed; parsed = 0L; } return parsed; } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/histogramfactory.cpp000644 001750 001750 00000006434 11544160207 021722 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "histogramfactory.h" #include "debug.h" #include "histogram.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { HistogramFactory::HistogramFactory() : ObjectFactory() { registerFactory(Histogram::staticTypeTag, this); } HistogramFactory::~HistogramFactory() { } DataObjectPtr HistogramFactory::generateObject(ObjectStore *store, QXmlStreamReader& xml) { Q_ASSERT(store); double min=-1, max=1; int numberOfBins=16, normalizationMode=0; QString VectorName, descriptiveName; bool realTimeAutoBin = true; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == Histogram::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); VectorName = attrs.value("vector").toString(); min = attrs.value("min").toString().toDouble(); max = attrs.value("max").toString().toDouble(); numberOfBins = attrs.value("numberofbins").toString().toInt(); normalizationMode = attrs.value("normalizationmode").toString().toInt(); realTimeAutoBin = attrs.value("realtimeautobin").toString() == "true" ? true : false; if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == Histogram::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating Histogram from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } VectorPtr vector = 0; if (store && !VectorName.isEmpty()) { vector = kst_cast(store->retrieveObject(VectorName)); } if (!vector) { Debug::self()->log(QObject::tr("Error creating Histogram from Kst file. Could not find Vector."), Debug::Warning); return 0; } HistogramPtr histogram = store->createObject(); histogram->setVector(vector); histogram->setXRange(min, max); histogram->setNumberOfBins(numberOfBins); histogram->setNormalizationType((Histogram::NormalizationType)normalizationMode); histogram->setRealTimeAutoBin(realTimeAutoBin); histogram->setDescriptiveName(descriptiveName); histogram->writeLock(); histogram->registerChange(); histogram->unlock(); return histogram; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/builtinpalettes.h000644 001750 001750 00000075360 11544160207 021216 0ustar00synthsynth000000 000000 /*************************************************************************** builtinpalettes.h: data for builting palettes ------------------- begin : September, 2010 copyright : (C) 2010 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUILTINPALETTES_H #define BUILTINPALETTES_H namespace Kst { static const int KstGrayscaleCount = 255; static const QString KstGrayscaleName = "Kst Grayscale"; static const char *const KstColors[] = { "red", "blue", "green", "black", "magenta", "steelblue", "#501010", "#105010" }; static const int KstColorsCount = sizeof(KstColors) / sizeof(char*); static const QString KstColorsName = "Kst Colors"; static const int RedTempCount = 256; static const QString RedTempName = "Red Temperature"; static unsigned char RedTemp[257][3] = { {0, 0, 0}, {0, 0, 0}, {1, 0, 0}, {2, 0, 0}, {4, 0, 0}, {5, 0, 0}, {7, 0, 0}, {8, 0, 0}, {10, 0, 0}, {11, 0, 0}, {13, 0, 0}, {14, 0, 0}, {15, 0, 0}, {17, 0, 0}, {18, 0, 0}, {20, 0, 0}, {21, 0, 0}, {23, 0, 0}, {24, 0, 0}, {26, 0, 0}, {27, 0, 0}, {28, 0, 0}, {30, 0, 0}, {31, 0, 0}, {33, 0, 0}, {34, 0, 0}, {36, 0, 0}, {37, 0, 0}, {39, 0, 0}, {40, 0, 0}, {42, 0, 0}, {43, 0, 0}, {44, 0, 0}, {46, 0, 0}, {47, 0, 0}, {49, 0, 0}, {50, 0, 0}, {52, 0, 0}, {53, 0, 0}, {55, 0, 0}, {56, 0, 0}, {57, 0, 0}, {59, 0, 0}, {60, 0, 0}, {62, 0, 0}, {63, 0, 0}, {65, 0, 0}, {66, 0, 0}, {68, 0, 0}, {69, 0, 0}, {70, 0, 0}, {72, 0, 0}, {73, 0, 0}, {75, 0, 0}, {76, 0, 0}, {78, 0, 0}, {79, 0, 0}, {81, 0, 0}, {82, 0, 0}, {84, 0, 0}, {85, 0, 0}, {86, 0, 0}, {88, 0, 0}, {89, 0, 0}, {91, 0, 0}, {92, 0, 0}, {94, 0, 0}, {95, 0, 0}, {97, 0, 0}, {98, 0, 0}, {99, 0, 0}, {101, 0, 0}, {102, 0, 0}, {104, 0, 0}, {105, 0, 0}, {107, 0, 0}, {108, 0, 0}, {110, 0, 0}, {111, 0, 0}, {113, 0, 0}, {114, 0, 0}, {115, 0, 0}, {117, 0, 0}, {118, 0, 0}, {120, 0, 0}, {121, 0, 0}, {123, 0, 0}, {124, 0, 0}, {126, 0, 0}, {127, 0, 0}, {128, 0, 0}, {130, 0, 0}, {131, 0, 0}, {133, 0, 0}, {134, 0, 0}, {136, 0, 0}, {137, 0, 0}, {139, 0, 0}, {140, 0, 0}, {141, 0, 0}, {143, 0, 0}, {144, 0, 0}, {146, 0, 0}, {147, 0, 0}, {149, 0, 0}, {150, 0, 0}, {152, 0, 0}, {153, 0, 0}, {155, 0, 0}, {156, 0, 0}, {157, 0, 0}, {159, 0, 0}, {160, 0, 0}, {162, 0, 0}, {163, 0, 0}, {165, 0, 0}, {166, 0, 0}, {168, 0, 0}, {169, 0, 0}, {170, 0, 0}, {172, 0, 0}, {173, 0, 0}, {175, 1, 0}, {176, 3, 0}, {178, 5, 0}, {179, 7, 0}, {181, 9, 0}, {182, 11, 0}, {184, 13, 0}, {185, 15, 0}, {186, 17, 0}, {188, 18, 0}, {189, 20, 0}, {191, 22, 0}, {192, 24, 0}, {194, 26, 0}, {195, 28, 0}, {197, 30, 0}, {198, 32, 0}, {199, 34, 0}, {201, 35, 0}, {202, 37, 0}, {204, 39, 0}, {205, 41, 0}, {207, 43, 0}, {208, 45, 0}, {210, 47, 0}, {211, 49, 0}, {212, 51, 0}, {214, 52, 0}, {215, 54, 0}, {217, 56, 0}, {218, 58, 0}, {220, 60, 0}, {221, 62, 0}, {223, 64, 0}, {224, 66, 0}, {226, 68, 0}, {227, 69, 0}, {228, 71, 0}, {230, 73, 0}, {231, 75, 0}, {233, 77, 0}, {234, 79, 0}, {236, 81, 0}, {237, 83, 0}, {239, 85, 0}, {240, 86, 0}, {241, 88, 0}, {243, 90, 0}, {244, 92, 0}, {246, 94, 0}, {247, 96, 0}, {249, 98, 0}, {250, 100, 0}, {252, 102, 0}, {253, 103, 0}, {255, 105, 0}, {255, 107, 0}, {255, 109, 0}, {255, 111, 0}, {255, 113, 0}, {255, 115, 0}, {255, 117, 0}, {255, 119, 0}, {255, 120, 0}, {255, 122, 0}, {255, 124, 0}, {255, 126, 0}, {255, 128, 0}, {255, 130, 0}, {255, 132, 0}, {255, 134, 3}, {255, 136, 7}, {255, 137, 11}, {255, 139, 15}, {255, 141, 19}, {255, 143, 23}, {255, 145, 27}, {255, 147, 31}, {255, 149, 35}, {255, 151, 39}, {255, 153, 43}, {255, 154, 47}, {255, 156, 51}, {255, 158, 54}, {255, 160, 58}, {255, 162, 62}, {255, 164, 66}, {255, 166, 70}, {255, 168, 74}, {255, 170, 78}, {255, 171, 82}, {255, 173, 86}, {255, 175, 90}, {255, 177, 94}, {255, 179, 98}, {255, 181, 102}, {255, 183, 105}, {255, 185, 109}, {255, 187, 113}, {255, 188, 117}, {255, 190, 121}, {255, 192, 125}, {255, 194, 129}, {255, 196, 133}, {255, 198, 137}, {255, 200, 141}, {255, 202, 145}, {255, 204, 149}, {255, 205, 153}, {255, 207, 156}, {255, 209, 160}, {255, 211, 164}, {255, 213, 168}, {255, 215, 172}, {255, 217, 176}, {255, 219, 180}, {255, 221, 184}, {255, 222, 188}, {255, 224, 192}, {255, 226, 196}, {255, 228, 200}, {255, 230, 204}, {255, 232, 207}, {255, 234, 211}, {255, 236, 215}, {255, 238, 219}, {255, 239, 223}, {255, 241, 227}, {255, 243, 231}, {255, 245, 235}, {255, 247, 239}, {255, 249, 243}, {255, 251, 247}, {255, 253, 251}, {255, 255, 255} }; static const int SpectrumCount = 1021; static const QString SpectrumName = "Spectrum"; static unsigned char Spectrum[1022][3] = { {0, 0, 0}, {0, 0, 255}, {0, 1, 255}, {0, 2, 255}, {0, 3, 255}, {0, 4, 255}, {0, 5, 255}, {0, 6, 255}, {0, 7, 255}, {0, 8, 255}, {0, 9, 255}, {0, 10, 255}, {0, 11, 255}, {0, 12, 255}, {0, 13, 255}, {0, 14, 255}, {0, 15, 255}, {0, 16, 255}, {0, 17, 255}, {0, 18, 255}, {0, 19, 255}, {0, 20, 255}, {0, 21, 255}, {0, 22, 255}, {0, 23, 255}, {0, 24, 255}, {0, 25, 255}, {0, 26, 255}, {0, 27, 255}, {0, 28, 255}, {0, 29, 255}, {0, 30, 255}, {0, 31, 255}, {0, 32, 255}, {0, 33, 255}, {0, 34, 255}, {0, 35, 255}, {0, 36, 255}, {0, 37, 255}, {0, 38, 255}, {0, 39, 255}, {0, 40, 255}, {0, 41, 255}, {0, 42, 255}, {0, 43, 255}, {0, 44, 255}, {0, 45, 255}, {0, 46, 255}, {0, 47, 255}, {0, 48, 255}, {0, 49, 255}, {0, 50, 255}, {0, 51, 255}, {0, 52, 255}, {0, 53, 255}, {0, 54, 255}, {0, 55, 255}, {0, 56, 255}, {0, 57, 255}, {0, 58, 255}, {0, 59, 255}, {0, 60, 255}, {0, 61, 255}, {0, 62, 255}, {0, 63, 255}, {0, 64, 255}, {0, 65, 255}, {0, 66, 255}, {0, 67, 255}, {0, 68, 255}, {0, 69, 255}, {0, 70, 255}, {0, 71, 255}, {0, 72, 255}, {0, 73, 255}, {0, 74, 255}, {0, 75, 255}, {0, 76, 255}, {0, 77, 255}, {0, 78, 255}, {0, 79, 255}, {0, 80, 255}, {0, 81, 255}, {0, 82, 255}, {0, 83, 255}, {0, 84, 255}, {0, 85, 255}, {0, 86, 255}, {0, 87, 255}, {0, 88, 255}, {0, 89, 255}, {0, 90, 255}, {0, 91, 255}, {0, 92, 255}, {0, 93, 255}, {0, 94, 255}, {0, 95, 255}, {0, 96, 255}, {0, 97, 255}, {0, 98, 255}, {0, 99, 255}, {0, 100, 255}, {0, 101, 255}, {0, 102, 255}, {0, 103, 255}, {0, 104, 255}, {0, 105, 255}, {0, 106, 255}, {0, 107, 255}, {0, 108, 255}, {0, 109, 255}, {0, 110, 255}, {0, 111, 255}, {0, 112, 255}, {0, 113, 255}, {0, 114, 255}, {0, 115, 255}, {0, 116, 255}, {0, 117, 255}, {0, 118, 255}, {0, 119, 255}, {0, 120, 255}, {0, 121, 255}, {0, 122, 255}, {0, 123, 255}, {0, 124, 255}, {0, 125, 255}, {0, 126, 255}, {0, 127, 255}, {0, 128, 255}, {0, 129, 255}, {0, 130, 255}, {0, 131, 255}, {0, 132, 255}, {0, 133, 255}, {0, 134, 255}, {0, 135, 255}, {0, 136, 255}, {0, 137, 255}, {0, 138, 255}, {0, 139, 255}, {0, 140, 255}, {0, 141, 255}, {0, 142, 255}, {0, 143, 255}, {0, 144, 255}, {0, 145, 255}, {0, 146, 255}, {0, 147, 255}, {0, 148, 255}, {0, 149, 255}, {0, 150, 255}, {0, 151, 255}, {0, 152, 255}, {0, 153, 255}, {0, 154, 255}, {0, 155, 255}, {0, 156, 255}, {0, 157, 255}, {0, 158, 255}, {0, 159, 255}, {0, 160, 255}, {0, 161, 255}, {0, 162, 255}, {0, 163, 255}, {0, 164, 255}, {0, 165, 255}, {0, 166, 255}, {0, 167, 255}, {0, 168, 255}, {0, 169, 255}, {0, 170, 255}, {0, 171, 255}, {0, 172, 255}, {0, 173, 255}, {0, 174, 255}, {0, 175, 255}, {0, 176, 255}, {0, 177, 255}, {0, 178, 255}, {0, 179, 255}, {0, 180, 255}, {0, 181, 255}, {0, 182, 255}, {0, 183, 255}, {0, 184, 255}, {0, 185, 255}, {0, 186, 255}, {0, 187, 255}, {0, 188, 255}, {0, 189, 255}, {0, 190, 255}, {0, 191, 255}, {0, 192, 255}, {0, 193, 255}, {0, 194, 255}, {0, 195, 255}, {0, 196, 255}, {0, 197, 255}, {0, 198, 255}, {0, 199, 255}, {0, 200, 255}, {0, 201, 255}, {0, 202, 255}, {0, 203, 255}, {0, 204, 255}, {0, 205, 255}, {0, 206, 255}, {0, 207, 255}, {0, 208, 255}, {0, 209, 255}, {0, 210, 255}, {0, 211, 255}, {0, 212, 255}, {0, 213, 255}, {0, 214, 255}, {0, 215, 255}, {0, 216, 255}, {0, 217, 255}, {0, 218, 255}, {0, 219, 255}, {0, 220, 255}, {0, 221, 255}, {0, 222, 255}, {0, 223, 255}, {0, 224, 255}, {0, 225, 255}, {0, 226, 255}, {0, 227, 255}, {0, 228, 255}, {0, 229, 255}, {0, 230, 255}, {0, 231, 255}, {0, 232, 255}, {0, 233, 255}, {0, 234, 255}, {0, 235, 255}, {0, 236, 255}, {0, 237, 255}, {0, 238, 255}, {0, 239, 255}, {0, 240, 255}, {0, 241, 255}, {0, 242, 255}, {0, 243, 255}, {0, 244, 255}, {0, 245, 255}, {0, 246, 255}, {0, 247, 255}, {0, 248, 255}, {0, 249, 255}, {0, 250, 255}, {0, 251, 255}, {0, 252, 255}, {0, 253, 255}, {0, 254, 255}, {0, 255, 255}, {0, 255, 254}, {0, 255, 253}, {0, 255, 252}, {0, 255, 251}, {0, 255, 250}, {0, 255, 249}, {0, 255, 248}, {0, 255, 247}, {0, 255, 246}, {0, 255, 245}, {0, 255, 244}, {0, 255, 243}, {0, 255, 242}, {0, 255, 241}, {0, 255, 240}, {0, 255, 239}, {0, 255, 238}, {0, 255, 237}, {0, 255, 236}, {0, 255, 235}, {0, 255, 234}, {0, 255, 233}, {0, 255, 232}, {0, 255, 231}, {0, 255, 230}, {0, 255, 229}, {0, 255, 228}, {0, 255, 227}, {0, 255, 226}, {0, 255, 225}, {0, 255, 224}, {0, 255, 223}, {0, 255, 222}, {0, 255, 221}, {0, 255, 220}, {0, 255, 219}, {0, 255, 218}, {0, 255, 217}, {0, 255, 216}, {0, 255, 215}, {0, 255, 214}, {0, 255, 213}, {0, 255, 212}, {0, 255, 211}, {0, 255, 210}, {0, 255, 209}, {0, 255, 208}, {0, 255, 207}, {0, 255, 206}, {0, 255, 205}, {0, 255, 204}, {0, 255, 203}, {0, 255, 202}, {0, 255, 201}, {0, 255, 200}, {0, 255, 199}, {0, 255, 198}, {0, 255, 197}, {0, 255, 196}, {0, 255, 195}, {0, 255, 194}, {0, 255, 193}, {0, 255, 192}, {0, 255, 191}, {0, 255, 190}, {0, 255, 189}, {0, 255, 188}, {0, 255, 187}, {0, 255, 186}, {0, 255, 185}, {0, 255, 184}, {0, 255, 183}, {0, 255, 182}, {0, 255, 181}, {0, 255, 180}, {0, 255, 179}, {0, 255, 178}, {0, 255, 177}, {0, 255, 176}, {0, 255, 175}, {0, 255, 174}, {0, 255, 173}, {0, 255, 172}, {0, 255, 171}, {0, 255, 170}, {0, 255, 169}, {0, 255, 168}, {0, 255, 167}, {0, 255, 166}, {0, 255, 165}, {0, 255, 164}, {0, 255, 163}, {0, 255, 162}, {0, 255, 161}, {0, 255, 160}, {0, 255, 159}, {0, 255, 158}, {0, 255, 157}, {0, 255, 156}, {0, 255, 155}, {0, 255, 154}, {0, 255, 153}, {0, 255, 152}, {0, 255, 151}, {0, 255, 150}, {0, 255, 149}, {0, 255, 148}, {0, 255, 147}, {0, 255, 146}, {0, 255, 145}, {0, 255, 144}, {0, 255, 143}, {0, 255, 142}, {0, 255, 141}, {0, 255, 140}, {0, 255, 139}, {0, 255, 138}, {0, 255, 137}, {0, 255, 136}, {0, 255, 135}, {0, 255, 134}, {0, 255, 133}, {0, 255, 132}, {0, 255, 131}, {0, 255, 130}, {0, 255, 129}, {0, 255, 128}, {0, 255, 127}, {0, 255, 126}, {0, 255, 125}, {0, 255, 124}, {0, 255, 123}, {0, 255, 122}, {0, 255, 121}, {0, 255, 120}, {0, 255, 119}, {0, 255, 118}, {0, 255, 117}, {0, 255, 116}, {0, 255, 115}, {0, 255, 114}, {0, 255, 113}, {0, 255, 112}, {0, 255, 111}, {0, 255, 110}, {0, 255, 109}, {0, 255, 108}, {0, 255, 107}, {0, 255, 106}, {0, 255, 105}, {0, 255, 104}, {0, 255, 103}, {0, 255, 102}, {0, 255, 101}, {0, 255, 100}, {0, 255, 99}, {0, 255, 98}, {0, 255, 97}, {0, 255, 96}, {0, 255, 95}, {0, 255, 94}, {0, 255, 93}, {0, 255, 92}, {0, 255, 91}, {0, 255, 90}, {0, 255, 89}, {0, 255, 88}, {0, 255, 87}, {0, 255, 86}, {0, 255, 85}, {0, 255, 84}, {0, 255, 83}, {0, 255, 82}, {0, 255, 81}, {0, 255, 80}, {0, 255, 79}, {0, 255, 78}, {0, 255, 77}, {0, 255, 76}, {0, 255, 75}, {0, 255, 74}, {0, 255, 73}, {0, 255, 72}, {0, 255, 71}, {0, 255, 70}, {0, 255, 69}, {0, 255, 68}, {0, 255, 67}, {0, 255, 66}, {0, 255, 65}, {0, 255, 64}, {0, 255, 63}, {0, 255, 62}, {0, 255, 61}, {0, 255, 60}, {0, 255, 59}, {0, 255, 58}, {0, 255, 57}, {0, 255, 56}, {0, 255, 55}, {0, 255, 54}, {0, 255, 53}, {0, 255, 52}, {0, 255, 51}, {0, 255, 50}, {0, 255, 49}, {0, 255, 48}, {0, 255, 47}, {0, 255, 46}, {0, 255, 45}, {0, 255, 44}, {0, 255, 43}, {0, 255, 42}, {0, 255, 41}, {0, 255, 40}, {0, 255, 39}, {0, 255, 38}, {0, 255, 37}, {0, 255, 36}, {0, 255, 35}, {0, 255, 34}, {0, 255, 33}, {0, 255, 32}, {0, 255, 31}, {0, 255, 30}, {0, 255, 29}, {0, 255, 28}, {0, 255, 27}, {0, 255, 26}, {0, 255, 25}, {0, 255, 24}, {0, 255, 23}, {0, 255, 22}, {0, 255, 21}, {0, 255, 20}, {0, 255, 19}, {0, 255, 18}, {0, 255, 17}, {0, 255, 16}, {0, 255, 15}, {0, 255, 14}, {0, 255, 13}, {0, 255, 12}, {0, 255, 11}, {0, 255, 10}, {0, 255, 9}, {0, 255, 8}, {0, 255, 7}, {0, 255, 6}, {0, 255, 5}, {0, 255, 4}, {0, 255, 3}, {0, 255, 2}, {0, 255, 1}, {0, 255, 0}, {1, 255, 0}, {2, 255, 0}, {3, 255, 0}, {4, 255, 0}, {5, 255, 0}, {6, 255, 0}, {7, 255, 0}, {8, 255, 0}, {9, 255, 0}, {10, 255, 0}, {11, 255, 0}, {12, 255, 0}, {13, 255, 0}, {14, 255, 0}, {15, 255, 0}, {16, 255, 0}, {17, 255, 0}, {18, 255, 0}, {19, 255, 0}, {20, 255, 0}, {21, 255, 0}, {22, 255, 0}, {23, 255, 0}, {24, 255, 0}, {25, 255, 0}, {26, 255, 0}, {27, 255, 0}, {28, 255, 0}, {29, 255, 0}, {30, 255, 0}, {31, 255, 0}, {32, 255, 0}, {33, 255, 0}, {34, 255, 0}, {35, 255, 0}, {36, 255, 0}, {37, 255, 0}, {38, 255, 0}, {39, 255, 0}, {40, 255, 0}, {41, 255, 0}, {42, 255, 0}, {43, 255, 0}, {44, 255, 0}, {45, 255, 0}, {46, 255, 0}, {47, 255, 0}, {48, 255, 0}, {49, 255, 0}, {50, 255, 0}, {51, 255, 0}, {52, 255, 0}, {53, 255, 0}, {54, 255, 0}, {55, 255, 0}, {56, 255, 0}, {57, 255, 0}, {58, 255, 0}, {59, 255, 0}, {60, 255, 0}, {61, 255, 0}, {62, 255, 0}, {63, 255, 0}, {64, 255, 0}, {65, 255, 0}, {66, 255, 0}, {67, 255, 0}, {68, 255, 0}, {69, 255, 0}, {70, 255, 0}, {71, 255, 0}, {72, 255, 0}, {73, 255, 0}, {74, 255, 0}, {75, 255, 0}, {76, 255, 0}, {77, 255, 0}, {78, 255, 0}, {79, 255, 0}, {80, 255, 0}, {81, 255, 0}, {82, 255, 0}, {83, 255, 0}, {84, 255, 0}, {85, 255, 0}, {86, 255, 0}, {87, 255, 0}, {88, 255, 0}, {89, 255, 0}, {90, 255, 0}, {91, 255, 0}, {92, 255, 0}, {93, 255, 0}, {94, 255, 0}, {95, 255, 0}, {96, 255, 0}, {97, 255, 0}, {98, 255, 0}, {99, 255, 0}, {100, 255, 0}, {101, 255, 0}, {102, 255, 0}, {103, 255, 0}, {104, 255, 0}, {105, 255, 0}, {106, 255, 0}, {107, 255, 0}, {108, 255, 0}, {109, 255, 0}, {110, 255, 0}, {111, 255, 0}, {112, 255, 0}, {113, 255, 0}, {114, 255, 0}, {115, 255, 0}, {116, 255, 0}, {117, 255, 0}, {118, 255, 0}, {119, 255, 0}, {120, 255, 0}, {121, 255, 0}, {122, 255, 0}, {123, 255, 0}, {124, 255, 0}, {125, 255, 0}, {126, 255, 0}, {127, 255, 0}, {128, 255, 0}, {129, 255, 0}, {130, 255, 0}, {131, 255, 0}, {132, 255, 0}, {133, 255, 0}, {134, 255, 0}, {135, 255, 0}, {136, 255, 0}, {137, 255, 0}, {138, 255, 0}, {139, 255, 0}, {140, 255, 0}, {141, 255, 0}, {142, 255, 0}, {143, 255, 0}, {144, 255, 0}, {145, 255, 0}, {146, 255, 0}, {147, 255, 0}, {148, 255, 0}, {149, 255, 0}, {150, 255, 0}, {151, 255, 0}, {152, 255, 0}, {153, 255, 0}, {154, 255, 0}, {155, 255, 0}, {156, 255, 0}, {157, 255, 0}, {158, 255, 0}, {159, 255, 0}, {160, 255, 0}, {161, 255, 0}, {162, 255, 0}, {163, 255, 0}, {164, 255, 0}, {165, 255, 0}, {166, 255, 0}, {167, 255, 0}, {168, 255, 0}, {169, 255, 0}, {170, 255, 0}, {171, 255, 0}, {172, 255, 0}, {173, 255, 0}, {174, 255, 0}, {175, 255, 0}, {176, 255, 0}, {177, 255, 0}, {178, 255, 0}, {179, 255, 0}, {180, 255, 0}, {181, 255, 0}, {182, 255, 0}, {183, 255, 0}, {184, 255, 0}, {185, 255, 0}, {186, 255, 0}, {187, 255, 0}, {188, 255, 0}, {189, 255, 0}, {190, 255, 0}, {191, 255, 0}, {192, 255, 0}, {193, 255, 0}, {194, 255, 0}, {195, 255, 0}, {196, 255, 0}, {197, 255, 0}, {198, 255, 0}, {199, 255, 0}, {200, 255, 0}, {201, 255, 0}, {202, 255, 0}, {203, 255, 0}, {204, 255, 0}, {205, 255, 0}, {206, 255, 0}, {207, 255, 0}, {208, 255, 0}, {209, 255, 0}, {210, 255, 0}, {211, 255, 0}, {212, 255, 0}, {213, 255, 0}, {214, 255, 0}, {215, 255, 0}, {216, 255, 0}, {217, 255, 0}, {218, 255, 0}, {219, 255, 0}, {220, 255, 0}, {221, 255, 0}, {222, 255, 0}, {223, 255, 0}, {224, 255, 0}, {225, 255, 0}, {226, 255, 0}, {227, 255, 0}, {228, 255, 0}, {229, 255, 0}, {230, 255, 0}, {231, 255, 0}, {232, 255, 0}, {233, 255, 0}, {234, 255, 0}, {235, 255, 0}, {236, 255, 0}, {237, 255, 0}, {238, 255, 0}, {239, 255, 0}, {240, 255, 0}, {241, 255, 0}, {242, 255, 0}, {243, 255, 0}, {244, 255, 0}, {245, 255, 0}, {246, 255, 0}, {247, 255, 0}, {248, 255, 0}, {249, 255, 0}, {250, 255, 0}, {251, 255, 0}, {252, 255, 0}, {253, 255, 0}, {254, 255, 0}, {255, 255, 0}, {255, 254, 0}, {255, 253, 0}, {255, 252, 0}, {255, 251, 0}, {255, 250, 0}, {255, 249, 0}, {255, 248, 0}, {255, 247, 0}, {255, 246, 0}, {255, 245, 0}, {255, 244, 0}, {255, 243, 0}, {255, 242, 0}, {255, 241, 0}, {255, 240, 0}, {255, 239, 0}, {255, 238, 0}, {255, 237, 0}, {255, 236, 0}, {255, 235, 0}, {255, 234, 0}, {255, 233, 0}, {255, 232, 0}, {255, 231, 0}, {255, 230, 0}, {255, 229, 0}, {255, 228, 0}, {255, 227, 0}, {255, 226, 0}, {255, 225, 0}, {255, 224, 0}, {255, 223, 0}, {255, 222, 0}, {255, 221, 0}, {255, 220, 0}, {255, 219, 0}, {255, 218, 0}, {255, 217, 0}, {255, 216, 0}, {255, 215, 0}, {255, 214, 0}, {255, 213, 0}, {255, 212, 0}, {255, 211, 0}, {255, 210, 0}, {255, 209, 0}, {255, 208, 0}, {255, 207, 0}, {255, 206, 0}, {255, 205, 0}, {255, 204, 0}, {255, 203, 0}, {255, 202, 0}, {255, 201, 0}, {255, 200, 0}, {255, 199, 0}, {255, 198, 0}, {255, 197, 0}, {255, 196, 0}, {255, 195, 0}, {255, 194, 0}, {255, 193, 0}, {255, 192, 0}, {255, 191, 0}, {255, 190, 0}, {255, 189, 0}, {255, 188, 0}, {255, 187, 0}, {255, 186, 0}, {255, 185, 0}, {255, 184, 0}, {255, 183, 0}, {255, 182, 0}, {255, 181, 0}, {255, 180, 0}, {255, 179, 0}, {255, 178, 0}, {255, 177, 0}, {255, 176, 0}, {255, 175, 0}, {255, 174, 0}, {255, 173, 0}, {255, 172, 0}, {255, 171, 0}, {255, 170, 0}, {255, 169, 0}, {255, 168, 0}, {255, 167, 0}, {255, 166, 0}, {255, 165, 0}, {255, 164, 0}, {255, 163, 0}, {255, 162, 0}, {255, 161, 0}, {255, 160, 0}, {255, 159, 0}, {255, 158, 0}, {255, 157, 0}, {255, 156, 0}, {255, 155, 0}, {255, 154, 0}, {255, 153, 0}, {255, 152, 0}, {255, 151, 0}, {255, 150, 0}, {255, 149, 0}, {255, 148, 0}, {255, 147, 0}, {255, 146, 0}, {255, 145, 0}, {255, 144, 0}, {255, 143, 0}, {255, 142, 0}, {255, 141, 0}, {255, 140, 0}, {255, 139, 0}, {255, 138, 0}, {255, 137, 0}, {255, 136, 0}, {255, 135, 0}, {255, 134, 0}, {255, 133, 0}, {255, 132, 0}, {255, 131, 0}, {255, 130, 0}, {255, 129, 0}, {255, 128, 0}, {255, 127, 0}, {255, 126, 0}, {255, 125, 0}, {255, 124, 0}, {255, 123, 0}, {255, 122, 0}, {255, 121, 0}, {255, 120, 0}, {255, 119, 0}, {255, 118, 0}, {255, 117, 0}, {255, 116, 0}, {255, 115, 0}, {255, 114, 0}, {255, 113, 0}, {255, 112, 0}, {255, 111, 0}, {255, 110, 0}, {255, 109, 0}, {255, 108, 0}, {255, 107, 0}, {255, 106, 0}, {255, 105, 0}, {255, 104, 0}, {255, 103, 0}, {255, 102, 0}, {255, 101, 0}, {255, 100, 0}, {255, 99, 0}, {255, 98, 0}, {255, 97, 0}, {255, 96, 0}, {255, 95, 0}, {255, 94, 0}, {255, 93, 0}, {255, 92, 0}, {255, 91, 0}, {255, 90, 0}, {255, 89, 0}, {255, 88, 0}, {255, 87, 0}, {255, 86, 0}, {255, 85, 0}, {255, 84, 0}, {255, 83, 0}, {255, 82, 0}, {255, 81, 0}, {255, 80, 0}, {255, 79, 0}, {255, 78, 0}, {255, 77, 0}, {255, 76, 0}, {255, 75, 0}, {255, 74, 0}, {255, 73, 0}, {255, 72, 0}, {255, 71, 0}, {255, 70, 0}, {255, 69, 0}, {255, 68, 0}, {255, 67, 0}, {255, 66, 0}, {255, 65, 0}, {255, 64, 0}, {255, 63, 0}, {255, 62, 0}, {255, 61, 0}, {255, 60, 0}, {255, 59, 0}, {255, 58, 0}, {255, 57, 0}, {255, 56, 0}, {255, 55, 0}, {255, 54, 0}, {255, 53, 0}, {255, 52, 0}, {255, 51, 0}, {255, 50, 0}, {255, 49, 0}, {255, 48, 0}, {255, 47, 0}, {255, 46, 0}, {255, 45, 0}, {255, 44, 0}, {255, 43, 0}, {255, 42, 0}, {255, 41, 0}, {255, 40, 0}, {255, 39, 0}, {255, 38, 0}, {255, 37, 0}, {255, 36, 0}, {255, 35, 0}, {255, 34, 0}, {255, 33, 0}, {255, 32, 0}, {255, 31, 0}, {255, 30, 0}, {255, 29, 0}, {255, 28, 0}, {255, 27, 0}, {255, 26, 0}, {255, 25, 0}, {255, 24, 0}, {255, 23, 0}, {255, 22, 0}, {255, 21, 0}, {255, 20, 0}, {255, 19, 0}, {255, 18, 0}, {255, 17, 0}, {255, 16, 0}, {255, 15, 0}, {255, 14, 0}, {255, 13, 0}, {255, 12, 0}, {255, 11, 0}, {255, 10, 0}, {255, 9, 0}, {255, 8, 0}, {255, 7, 0}, {255, 6, 0}, {255, 5, 0}, {255, 4, 0}, {255, 3, 0}, {255, 2, 0}, {255, 1, 0}, {255, 0, 0} }; static const int EosACount = 256; static const QString EosAName = "EOS-A"; static unsigned char EosA[257][3] = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {127, 127, 127}, {123, 0, 193}, {119, 0, 195}, {114, 0, 197}, {110, 0, 199}, {106, 0, 201}, {102, 0, 204}, {97, 0, 206}, {84, 0, 187}, {80, 0, 189}, {76, 0, 191}, {80, 0, 214}, {76, 0, 216}, {72, 0, 218}, {67, 0, 221}, {63, 0, 223}, {59, 0, 225}, {55, 0, 227}, {45, 0, 206}, {42, 0, 208}, {38, 0, 210}, {38, 0, 235}, {33, 0, 238}, {29, 0, 240}, {25, 0, 242}, {21, 0, 244}, {16, 0, 246}, {12, 0, 248}, {7, 0, 225}, {3, 0, 227}, {0, 0, 229}, {0, 17, 255}, {0, 34, 255}, {0, 51, 255}, {0, 68, 255}, {0, 85, 255}, {0, 102, 255}, {0, 119, 255}, {0, 122, 229}, {0, 137, 229}, {0, 153, 229}, {0, 187, 255}, {0, 204, 255}, {0, 221, 255}, {0, 238, 255}, {0, 255, 255}, {0, 255, 238}, {0, 255, 221}, {0, 229, 183}, {0, 229, 168}, {0, 229, 152}, {0, 255, 153}, {0, 255, 135}, {0, 255, 118}, {0, 255, 101}, {0, 255, 84}, {0, 255, 67}, {0, 255, 50}, {0, 229, 30}, {0, 229, 15}, {0, 229, 0}, {8, 255, 0}, {17, 255, 0}, {25, 255, 0}, {34, 255, 0}, {42, 255, 0}, {51, 255, 0}, {59, 255, 0}, {61, 229, 0}, {68, 229, 0}, {76, 229, 0}, {93, 255, 0}, {102, 255, 0}, {110, 255, 0}, {119, 255, 0}, {127, 255, 0}, {136, 255, 0}, {144, 255, 0}, {137, 229, 0}, {145, 229, 0}, {153, 229, 0}, {178, 255, 0}, {187, 255, 0}, {195, 255, 0}, {204, 255, 0}, {212, 255, 0}, {221, 255, 0}, {229, 255, 0}, {214, 229, 0}, {221, 229, 0}, {229, 229, 0}, {255, 250, 0}, {255, 246, 0}, {255, 242, 0}, {255, 238, 0}, {255, 233, 0}, {255, 229, 0}, {255, 225, 0}, {229, 198, 0}, {229, 195, 0}, {229, 191, 0}, {255, 208, 0}, {255, 204, 0}, {255, 199, 0}, {255, 195, 0}, {255, 191, 0}, {255, 187, 0}, {255, 182, 0}, {229, 160, 0}, {229, 156, 0}, {229, 152, 0}, {255, 165, 0}, {255, 161, 0}, {255, 157, 0}, {255, 153, 0}, {255, 148, 0}, {255, 144, 0}, {255, 140, 0}, {229, 122, 0}, {229, 118, 0}, {229, 114, 0}, {255, 125, 0}, {255, 123, 0}, {255, 121, 0}, {255, 119, 0}, {255, 116, 0}, {255, 114, 0}, {255, 112, 0}, {229, 99, 0}, {229, 97, 0}, {229, 95, 0}, {255, 104, 0}, {255, 102, 0}, {255, 99, 0}, {255, 97, 0}, {255, 95, 0}, {255, 93, 0}, {255, 91, 0}, {229, 80, 0}, {229, 78, 0}, {229, 76, 0}, {255, 82, 0}, {255, 80, 0}, {255, 78, 0}, {255, 76, 0}, {255, 74, 0}, {255, 72, 0}, {255, 70, 0}, {229, 61, 0}, {229, 59, 0}, {229, 57, 0}, {255, 61, 0}, {255, 59, 0}, {255, 57, 0}, {255, 55, 0}, {255, 53, 0}, {255, 50, 0}, {255, 48, 0}, {229, 42, 0}, {229, 40, 0}, {229, 38, 0}, {255, 40, 0}, {255, 38, 0}, {255, 36, 0}, {255, 33, 0}, {255, 31, 0}, {255, 29, 0}, {255, 27, 0}, {229, 22, 0}, {229, 21, 0}, {229, 19, 0}, {255, 19, 0}, {255, 16, 0}, {255, 14, 0}, {255, 12, 0}, {255, 13, 0}, {255, 8, 0}, {255, 6, 0}, {229, 3, 0}, {229, 1, 0}, {229, 0, 0}, {253, 0, 0}, {251, 0, 0}, {249, 0, 0}, {248, 0, 0}, {246, 0, 0}, {244, 0, 0}, {242, 0, 0}, {217, 0, 0}, {215, 0, 0}, {213, 0, 0}, {236, 0, 0}, {234, 0, 0}, {232, 0, 0}, {230, 0, 0}, {229, 0, 0}, {227, 0, 0}, {225, 0, 0}, {201, 0, 0}, {200, 0, 0}, {198, 0, 0}, {218, 0, 0}, {217, 0, 0}, {215, 0, 0}, {213, 0, 0}, {211, 0, 0}, {210, 0, 0}, {208, 0, 0}, {186, 0, 0}, {184, 0, 0}, {182, 0, 0}, {201, 0, 0}, {199, 0, 0}, {198, 0, 0}, {196, 0, 0}, {194, 0, 0}, {192, 0, 0}, {191, 0, 0}, {170, 0, 0}, {169, 0, 0}, {167, 0, 0}, {184, 0, 0}, {182, 0, 0}, {180, 0, 0}, {179, 0, 0}, {177, 0, 0}, {175, 0, 0}, {174, 0, 0}, {155, 0, 0}, {153, 0, 0}, {151, 0, 0}, {167, 0, 0}, {165, 0, 0}, {163, 0, 0}, {161, 0, 0}, {160, 0, 0}, {158, 0, 0}, {156, 0, 0}, {139, 0, 0}, {138, 0, 0}, {136, 0, 0}, {149, 0, 0}, {148, 0, 0}, {146, 0, 0}, {144, 0, 0}, {143, 0, 0}, {141, 0, 0}, {139, 0, 0}, {124, 0, 0}, {122, 0, 0}, {120, 0, 0}, {132, 0, 0}, {130, 0, 0}, {130, 0, 0} }; static const int EosBCount = 256; static const QString EosBName = "EOS-B"; static unsigned char EosB[257][3] = { {0, 0, 0}, {255, 255, 255}, {255, 255, 255}, {127, 127, 127}, {0, 0, 131}, {0, 0, 136}, {0, 0, 140}, {0, 0, 144}, {0, 0, 148}, {0, 0, 153}, {0, 0, 157}, {0, 0, 145}, {0, 0, 149}, {0, 0, 170}, {0, 0, 174}, {0, 0, 178}, {0, 0, 182}, {0, 0, 187}, {0, 0, 191}, {0, 0, 195}, {0, 0, 199}, {0, 0, 183}, {0, 0, 187}, {0, 0, 212}, {0, 0, 216}, {0, 0, 221}, {0, 0, 225}, {0, 0, 229}, {0, 0, 233}, {0, 0, 238}, {0, 0, 242}, {0, 0, 221}, {0, 0, 225}, {0, 0, 255}, {0, 7, 247}, {0, 15, 239}, {0, 23, 231}, {0, 31, 223}, {0, 39, 215}, {0, 47, 207}, {0, 55, 199}, {0, 57, 172}, {0, 64, 164}, {0, 79, 175}, {0, 87, 167}, {0, 95, 159}, {0, 103, 151}, {0, 111, 143}, {0, 119, 135}, {0, 127, 127}, {0, 135, 119}, {0, 129, 100}, {0, 136, 93}, {0, 159, 95}, {0, 167, 87}, {0, 175, 79}, {0, 183, 71}, {0, 191, 63}, {0, 199, 55}, {0, 207, 47}, {0, 215, 39}, {0, 200, 28}, {0, 207, 21}, {0, 239, 15}, {0, 247, 7}, {0, 255, 0}, {9, 255, 0}, {18, 255, 0}, {27, 255, 0}, {36, 255, 0}, {45, 255, 0}, {49, 229, 0}, {57, 229, 0}, {72, 255, 0}, {81, 255, 0}, {91, 255, 0}, {100, 255, 0}, {109, 255, 0}, {118, 255, 0}, {127, 255, 0}, {136, 255, 0}, {131, 229, 0}, {139, 229, 0}, {163, 255, 0}, {173, 255, 0}, {182, 255, 0}, {191, 255, 0}, {200, 255, 0}, {209, 255, 0}, {218, 255, 0}, {227, 255, 0}, {213, 229, 0}, {221, 229, 0}, {255, 255, 0}, {255, 250, 0}, {255, 246, 0}, {255, 242, 0}, {255, 238, 0}, {255, 233, 0}, {255, 229, 0}, {255, 225, 0}, {229, 198, 0}, {229, 195, 0}, {255, 212, 0}, {255, 208, 0}, {255, 204, 0}, {255, 199, 0}, {255, 195, 0}, {255, 191, 0}, {255, 187, 0}, {255, 182, 0}, {229, 160, 0}, {229, 156, 0}, {255, 169, 0}, {255, 165, 0}, {255, 161, 0}, {255, 157, 0}, {255, 153, 0}, {255, 148, 0}, {255, 144, 0}, {255, 140, 0}, {229, 122, 0}, {229, 118, 0}, {255, 127, 0}, {255, 125, 0}, {255, 123, 0}, {255, 121, 0}, {255, 119, 0}, {255, 116, 0}, {255, 114, 0}, {255, 112, 0}, {229, 99, 0}, {229, 97, 0}, {255, 106, 0}, {255, 104, 0}, {255, 102, 0}, {255, 99, 0}, {255, 97, 0}, {255, 95, 0}, {255, 93, 0}, {255, 91, 0}, {229, 80, 0}, {229, 78, 0}, {255, 84, 0}, {255, 82, 0}, {255, 80, 0}, {255, 78, 0}, {255, 76, 0}, {255, 74, 0}, {255, 72, 0}, {255, 70, 0}, {229, 61, 0}, {229, 59, 0}, {255, 63, 0}, {255, 61, 0}, {255, 59, 0}, {255, 57, 0}, {255, 55, 0}, {255, 53, 0}, {255, 50, 0}, {255, 48, 0}, {229, 42, 0}, {229, 40, 0}, {255, 42, 0}, {255, 40, 0}, {255, 38, 0}, {255, 36, 0}, {255, 33, 0}, {255, 31, 0}, {255, 29, 0}, {255, 27, 0}, {229, 22, 0}, {229, 21, 0}, {255, 21, 0}, {255, 19, 0}, {255, 16, 0}, {255, 14, 0}, {255, 12, 0}, {255, 13, 0}, {255, 8, 0}, {255, 6, 0}, {229, 3, 0}, {229, 1, 0}, {255, 0, 0}, {253, 0, 0}, {251, 0, 0}, {249, 0, 0}, {247, 0, 0}, {245, 0, 0}, {243, 0, 0}, {241, 0, 0}, {215, 0, 0}, {214, 0, 0}, {235, 0, 0}, {234, 0, 0}, {232, 0, 0}, {230, 0, 0}, {228, 0, 0}, {226, 0, 0}, {224, 0, 0}, {222, 0, 0}, {198, 0, 0}, {196, 0, 0}, {216, 0, 0}, {215, 0, 0}, {213, 0, 0}, {211, 0, 0}, {209, 0, 0}, {207, 0, 0}, {205, 0, 0}, {203, 0, 0}, {181, 0, 0}, {179, 0, 0}, {197, 0, 0}, {196, 0, 0}, {194, 0, 0}, {192, 0, 0}, {190, 0, 0}, {188, 0, 0}, {186, 0, 0}, {184, 0, 0}, {164, 0, 0}, {162, 0, 0}, {178, 0, 0}, {176, 0, 0}, {175, 0, 0}, {173, 0, 0}, {171, 0, 0}, {169, 0, 0}, {167, 0, 0}, {165, 0, 0}, {147, 0, 0}, {145, 0, 0}, {159, 0, 0}, {157, 0, 0}, {156, 0, 0}, {154, 0, 0}, {152, 0, 0}, {150, 0, 0}, {148, 0, 0}, {146, 0, 0}, {130, 0, 0}, {128, 0, 0}, {140, 0, 0}, {138, 0, 0}, {137, 0, 0}, {135, 0, 0}, {133, 0, 0}, {131, 0, 0}, {129, 0, 0}, {127, 0, 0}, {113, 0, 0}, {111, 0, 0}, {121, 0, 0}, {119, 0, 0}, {117, 0, 0}, {117, 0, 0}, }; } #endif kst-2.0.3/src/libkstmath/equationfactory.cpp000644 001750 001750 00000006152 11544160207 021547 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "equationfactory.h" #include "debug.h" #include "equation.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { EquationFactory::EquationFactory() : ObjectFactory() { registerFactory(Equation::staticTypeTag, this); } EquationFactory::~EquationFactory() { } DataObjectPtr EquationFactory::generateObject(ObjectStore *store, QXmlStreamReader& xml) { QString tag, expression, xVector, output, descriptiveName; bool interpolate = false; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == "equation") { QXmlStreamAttributes attrs = xml.attributes(); tag = attrs.value("tag").toString(); expression = attrs.value("expression").toString(); interpolate = attrs.value("interpolate").toString().toLower() == "true"; xVector = attrs.value("xvector").toString(); output = attrs.value("output").toString(); if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); //FIXME Don't know if this is a bug in QXmlStreamReader or what, but readElementNext takes us //past the node to the node... //eq = xml.readElementText(); } else { return 0; } } else if (xml.isEndElement()) { if (n == "equation") { break; } else { Debug::self()->log(QObject::tr("Error creating equation from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } VectorPtr vector = 0; if (store && !xVector.isEmpty()) { vector = kst_cast(store->retrieveObject(xVector)); } if (!vector) { Debug::self()->log(QObject::tr("Error creating equation from Kst file. Could not find xVector."), Debug::Warning); return 0; } EquationPtr equation = store->createObject(); Q_ASSERT(equation); equation->setEquation(expression); equation->setExistingXVector(vector, interpolate); equation->setDescriptiveName(descriptiveName); equation->writeLock(); equation->registerChange(); equation->unlock(); return equation; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/equation.h000644 001750 001750 00000006474 11544160207 017633 0ustar00synthsynth000000 000000 /*************************************************************************** equation.h: Equation for KST ------------------- begin : Fri Feb 10 2002 copyright : (C) 2002 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A class for handling equations for kst *@author C. Barth Netterfield */ #ifndef EQUATION_H #define EQUATION_H #include "dataobject.h" #include "objectfactory.h" #include "kstmath_export.h" #define MAX_DIV_REG 100 class QXmlStreamWriter; namespace Equations { class Node; } namespace Kst { class ObjectStore; class KSTMATH_EXPORT Equation : public DataObject { Q_OBJECT public: static const QString staticTypeString; const QString& typeString() const { return staticTypeString; } static const QString staticTypeTag; void attach(); void save(QXmlStreamWriter &s); QString propertyString() const; /** equations used to edit the vector */ void setEquation(const QString &Equation); void setExistingXVector(VectorPtr xvector, bool do_interp); const QString& equation() const { return _equation; } const QString reparsedEquation() const; void updateVectorLabels(); VectorPtr vXIn() const { return _xInVector; } VectorPtr vX() const { return _xOutVector; } VectorPtr vY() const { return _yOutVector; } bool doInterp() const { return _doInterp; } bool isValid() const; void showNewDialog(); void showEditDialog(); const CurveHintList *curveHints() const; DataObjectPtr makeDuplicate() const; bool uses(ObjectPtr p) const; virtual QString descriptionTip() const; virtual void internalUpdate(); virtual PrimitiveList inputPrimitives() const; virtual void replaceInput(PrimitivePtr p, PrimitivePtr new_p); protected: Equation(ObjectStore *store); ~Equation(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; private: QString _equation; VectorMap VectorsUsed; ScalarMap ScalarsUsed; bool FillY(bool force = false); bool _isValid : 1; bool _doInterp : 1; int _numNew, _numShifted, _interp, _ns; static const QString XINVECTOR; static const QString XOUTVECTOR; static const QString YOUTVECTOR; VectorPtr _xInVector, _xOutVector, _yOutVector; Equations::Node *_pe; }; typedef SharedPtr EquationPtr; typedef ObjectList EquationList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/equationfactory.h000644 001750 001750 00000002217 11544160207 021212 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EQUATIONFACTORY_H #define EQUATIONFACTORY_H #include "objectfactory.h" namespace Kst { class EquationFactory : public ObjectFactory { public: EquationFactory(); ~EquationFactory(); DataObjectPtr generateObject(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/curvefactory.cpp000644 001750 001750 00000013264 11544160207 021050 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "curvefactory.h" #include "debug.h" #include "curve.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { CurveFactory::CurveFactory() : RelationFactory() { registerFactory(Curve::staticTypeTag, this); } CurveFactory::~CurveFactory() { } RelationPtr CurveFactory::generateRelation(ObjectStore *store, QXmlStreamReader& xml) { Q_ASSERT(store); int lineStyle=0, lineWidth=0, pointType=0, pointDensity=0, barStyle=0, headType=0; QString xVectorName, yVectorName, legend, errorXVectorName, errorYVectorName, errorXMinusVectorName; QString errorYMinusVectorName, color, headColor; QString descriptiveName; bool hasLines=true, hasPoints=false, hasBars=false, ignoreAutoScale=false, hasHead=false; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == Curve::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); xVectorName = attrs.value("xvector").toString(); yVectorName = attrs.value("yvector").toString(); legend = attrs.value("legend").toString(); color = attrs.value("color").toString(); headColor = attrs.value("headcolor").toString(); errorXVectorName = attrs.value("errorxvector").toString(); errorYVectorName = attrs.value("erroryvector").toString(); errorXMinusVectorName = attrs.value("errorxminusvector").toString(); errorYMinusVectorName = attrs.value("erroryminusvector").toString(); hasLines = attrs.value("haslines").toString() == "true" ? true : false; lineWidth = attrs.value("linewidth").toString().toInt(); lineStyle = attrs.value("linestyle").toString().toInt(); hasPoints = attrs.value("haspoints").toString() == "true" ? true : false; pointType = attrs.value("pointtype").toString().toInt(); pointDensity = attrs.value("pointdensity").toString().toInt(); hasHead = attrs.value("hashead").toString() == "true" ? true : false; headType = attrs.value("headtype").toString().toInt(); hasBars = attrs.value("hasbars").toString() == "true" ? true : false; barStyle = attrs.value("barstyle").toString().toInt(); ignoreAutoScale = attrs.value("ignoreautoscale").toString() == "true" ? true : false; if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == Curve::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating Curve from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } VectorPtr xVector = 0; if (store && !xVectorName.isEmpty()) { xVector = kst_cast(store->retrieveObject(xVectorName)); } if (!xVector) { Debug::self()->log(QObject::tr("Error creating Curve from Kst file. Could not find xVector."), Debug::Warning); return 0; } VectorPtr yVector = 0; if (store && !yVectorName.isEmpty()) { yVector = kst_cast(store->retrieveObject(yVectorName)); } if (!yVector) { Debug::self()->log(QObject::tr("Error creating Curve from Kst file. Could not find yVector."), Debug::Warning); return 0; } VectorPtr errorXVector = 0; if (store && !errorXVectorName.isEmpty()) { errorXVector = kst_cast(store->retrieveObject(errorXVectorName)); } VectorPtr errorYVector = 0; if (store && !errorYVectorName.isEmpty()) { errorYVector = kst_cast(store->retrieveObject(errorYVectorName)); } VectorPtr errorXMinusVector = 0; if (store && !errorXMinusVectorName.isEmpty()) { errorXMinusVector = kst_cast(store->retrieveObject(errorXMinusVectorName)); } VectorPtr errorYMinusVector = 0; if (store && !errorYMinusVectorName.isEmpty()) { errorYMinusVector = kst_cast(store->retrieveObject(errorYMinusVectorName)); } CurvePtr curve = store->createObject(); curve->setXVector(xVector); curve->setYVector(yVector); curve->setXError(errorXVector); curve->setYError(errorYVector); curve->setXMinusError(errorXMinusVector); curve->setYMinusError(errorYMinusVector); curve->setColor(QColor(color)); curve->setHeadColor(QColor(headColor)); curve->setHasPoints(hasPoints); curve->setHasLines(hasLines); curve->setHasBars(hasBars); curve->setHasHead(hasHead); curve->setLineWidth(lineWidth); curve->setLineStyle(lineStyle); curve->setPointType(pointType); curve->setHeadType(headType); curve->setPointDensity(pointDensity); curve->setBarStyle(barStyle); curve->setDescriptiveName(descriptiveName); curve->writeLock(); curve->registerChange(); curve->unlock(); return curve; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/relation.h000644 001750 001750 00000016712 11544160207 017617 0ustar00synthsynth000000 000000 /*************************************************************************** relation.h: base curve type for kst ------------------- begin : Fri Oct 22 2000 copyright : (C) 2000 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RELATION_H #define RELATION_H #include #include "dataobject.h" #include "painter.h" #include "kstmath_export.h" #include "labelparser.h" #include "labelinfo.h" /**A class for handling curves for kst *@author C. Barth Netterfield */ class QXmlStreamWriter; namespace Kst { // context for rendering a curve in a plot class CurveRenderContext { public: // FIXME: use reasonable defaults CurveRenderContext() : painter(0L), Lx(0.0), Hx(0.0), Ly(0.0), Hy(0.0), m_X(0.0), m_Y(0.0), b_X(0.0), b_Y(0.0), x_max(0.0), y_max(0.0), x_min(0.0), y_min(0.0), XMin(0.0), YMin(0.0), XMax(0.0), YMax(0.0), xLog(false), yLog(false), xLogBase(0.0), yLogBase(0.0), penWidth(0) {} QPainter* painter; QRect window; double Lx, Hx, Ly, Hy; double m_X, m_Y, b_X, b_Y; double x_max, y_max, x_min, y_min; double XMin, YMin, XMax, YMax; // range and domain of plot bool xLog, yLog; double xLogBase, yLogBase; QColor foregroundColor; // plot foreground color QColor backgroundColor; // plot background color int penWidth; }; struct CurveContextDetails { double Lx, Hx, Ly, Hy; double m_X, m_Y; double b_X, b_Y; double XMin, XMax; bool xLog, yLog; double xLogBase, yLogBase; int penWidth; }; class ObjectStore; class Relation; class KSTMATH_EXPORT Relation : public Object { Q_OBJECT public: static const QString staticTypeString; const QString& typeString() const { return staticTypeString; } Relation(ObjectStore *store); virtual ~Relation(); virtual void showNewDialog() { } virtual void showEditDialog() { } virtual void save(QXmlStreamWriter &s); virtual QString propertyString() const = 0; virtual int sampleCount() const { return NS; } virtual void setIgnoreAutoScale(bool ignoreAutoScale); virtual bool ignoreAutoScale() const { return _ignoreAutoScale; } virtual int samplesPerFrame() const { return 1; } virtual void deleteDependents(); virtual double maxX() const { return MaxX; } virtual double minX() const { return MinX; } virtual double maxY() const { return MaxY; } virtual double minY() const { return MinY; } virtual double minPosY() const { return MinPosY; } virtual double ns_maxX() const { return _ns_maxx; } virtual double ns_minX() const { return _ns_minx; } virtual double ns_maxY() const { return _ns_maxy; } virtual double ns_minY() const { return _ns_miny; } virtual double minPosX() const { return MinPosX; } virtual double midX() const { return (MaxX+MinX)*0.5; } virtual double midY() const { return (MaxY+MinY)*0.5; } virtual void yRange(double xFrom, double xTo, double* yMin, double* yMax) = 0; virtual bool uses(ObjectPtr p) const; // this returns the data object providing the data for this basecurve. // E.g. for VCurves, it returns the data object providing the y vector // E.g. for Images, it returns the data object providing the matrix // Null is returned if no provider exists virtual DataObjectPtr providerDataObject() const = 0; // return closest distance to the given point // images always return a rating >= 5 virtual double distanceToPoint(double xpos, double dx, double ypos) const = 0; // render this curve void paint(const CurveRenderContext& context); virtual void paintObjects(const CurveRenderContext& context) = 0; virtual void updatePaintObjects(const CurveRenderContext& context) = 0; // render the legend symbol for this curve virtual void paintLegendSymbol(QPainter *p, const QRectF& bound) = 0; //virtual SharedPtr makeDuplicate(QMap< SharedPtr, SharedPtr > &duplicatedRelations) = 0; virtual SharedPtr makeDuplicate() const = 0; virtual void replaceInput(PrimitivePtr p, PrimitivePtr new_p); // Compare the cached the context to the provided one. bool redrawRequired(const CurveRenderContext& context); // If you use these, you must lock() and unlock() the object as long as you // hold the reference const VectorMap& inputVectors() const { return _inputVectors; } const VectorMap& outputVectors() const { return _outputVectors; } VectorMap& inputVectors() { return _inputVectors; } VectorMap& outputVectors() { return _outputVectors; } const ScalarMap& inputScalars() const { return _inputScalars; } const ScalarMap& outputScalars() const { return _outputScalars; } ScalarMap& inputScalars() { return _inputScalars; } ScalarMap& outputScalars() { return _outputScalars; } const StringMap& inputStrings() const { return _inputStrings; } const StringMap& outputStrings() const { return _outputStrings; } StringMap& inputStrings() { return _inputStrings; } StringMap& outputStrings() { return _outputStrings; } const MatrixMap& inputMatrices() const { return _inputMatrices; } const MatrixMap& outputMatrices() const { return _outputMatrices; } MatrixMap& inputMatrices() { return _inputMatrices; } MatrixMap& outputMatrices() { return _outputMatrices; } PrimitiveList inputPrimitives() const; virtual bool invertXHint() const {return false;} virtual bool invertYHint() const {return false;} virtual LabelInfo xLabelInfo() const = 0; virtual LabelInfo yLabelInfo() const = 0; virtual LabelInfo titleInfo() const = 0; protected: virtual void writeLockInputsAndOutputs() const; virtual void unlockInputsAndOutputs() const; virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; CurveHintList *_curveHints; QString _typeString, _type; VectorMap _inputVectors; VectorMap _outputVectors; ScalarMap _inputScalars; ScalarMap _outputScalars; StringMap _inputStrings; StringMap _outputStrings; MatrixMap _inputMatrices; MatrixMap _outputMatrices; double _ns_maxx; double _ns_minx; double _ns_maxy; double _ns_miny; double MaxX; double MinX; double MinPosX; double MeanX; double MaxY; double MinY; double MinPosY; int NS; bool _ignoreAutoScale; CurveContextDetails _contextDetails; bool _redrawRequired; private: void commonConstructor(); }; typedef SharedPtr RelationPtr; typedef ObjectList RelationList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/palette.cpp000644 001750 001750 00000006217 11544160207 017772 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // application specific includes #include "palette.h" #include "settings.h" #include #include #include #include "builtinpalettes.h" namespace Kst { QStringList Palette::getPaletteList() { QStringList paletteList; paletteList.append(KstGrayscaleName); paletteList.append(RedTempName); paletteList.append(SpectrumName); paletteList.append(EosAName); paletteList.append(EosBName); paletteList.append(KstColorsName); //TODO: support loading palettes from disk. return paletteList; } Palette::Palette(): _colors(0), _count(0) { changePaletteName(DefaultPalette); } Palette::Palette(const QString &paletteName): _colors(0), _count(0) { changePaletteName(paletteName); } Palette::~Palette() { delete[] _colors; delete[] _rgb; _colors = 0; _count = 0; } void Palette::changePaletteName(const QString &paletteName) { if (_count==0) { _colors = new QColor[2048]; _rgb = new QRgb[2048]; } if (paletteName.isEmpty()) { _paletteName = KstColorsName; } else { _paletteName = paletteName; } if (_paletteName == KstColorsName) { for (int i = 0; i < KstColorsCount; i++) { _colors[i] = QColor(KstColors[i]); _rgb[i] = _colors[i].rgb(); } _count = KstColorsCount; } else if (_paletteName == RedTempName) { for (int i = 0; i < RedTempCount; i++) { _colors[i] = QColor(RedTemp[i][0], RedTemp[i][1], RedTemp[i][2]); _rgb[i] = _colors[i].rgb(); } _count = RedTempCount; } else if (_paletteName == SpectrumName) { for (int i = 0; i < SpectrumCount; i++) { _colors[i] = QColor(Spectrum[i][0], Spectrum[i][1], Spectrum[i][2]); _rgb[i] = _colors[i].rgb(); } _count = SpectrumCount; } else if (_paletteName == EosAName) { for (int i = 0; i < EosACount; i++) { _colors[i] = QColor(EosA[i][0], EosA[i][1], EosA[i][2]); _rgb[i] = _colors[i].rgb(); } _count = EosACount; } else if (_paletteName == EosBName) { for (int i = 0; i < EosBCount; i++) { _colors[i] = QColor(EosB[i][0], EosB[i][1], EosB[i][2]); _rgb[i] = _colors[i].rgb(); } _count = EosBCount; } else { for (int i = 0; i < KstGrayscaleCount; i++) { _colors[i] = QColor(i, i, i); _rgb[i] = _colors[i].rgb(); } _count = KstGrayscaleCount; } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/curvehint.cpp000644 001750 001750 00000003461 11544160207 020341 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "curvehint.h" #include "datacollection.h" #include "relation.h" #include "curve.h" #include namespace Kst { CurveHint::CurveHint(const QString& name, const QString& x, const QString& y) : Shared(), _curveName(name), _xVectorName(x), _yVectorName(y) { } CurveHint::~CurveHint() { } const QString& CurveHint::xVectorName() const { return _xVectorName; } const QString& CurveHint::yVectorName() const { return _yVectorName; } #if 0 VectorPtr CurveHint::xVector() const { return *vectorList.findTag(_xVectorName); } VectorPtr CurveHint::yVector() const { return *vectorList.findTag(_yVectorName); } RelationPtr CurveHint::makeCurve(const QString& tag, const QColor& color) const { VectorPtr x = xVector(); VectorPtr y = yVector(); if (!x || !y) { qDebug() << "Couldn't find either " << _xVectorName << " or " << _yVectorName << endl; return 0L; } return new Curve(tag, x, y, 0L, 0L, 0L, 0L, color); } #endif } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/eparse.cpp000644 001750 001750 00000172252 11544160207 017616 0ustar00synthsynth000000 000000 /* A Bison parser, made by GNU Bison 2.3. */ /* Skeleton implementation for Bison's Yacc-like parsers in C Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Using locations. */ #define YYLSP_NEEDED 0 /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { T_NUMBER = 258, T_IDENTIFIER = 259, T_DATA = 260, T_OPENPAR = 261, T_CLOSEPAR = 262, T_COMMA = 263, T_INVALID = 264, T_LOR = 265, T_LAND = 266, T_OR = 267, T_AND = 268, T_NE = 269, T_EQ = 270, T_GE = 271, T_GT = 272, T_LE = 273, T_LT = 274, T_SUBTRACT = 275, T_ADD = 276, T_MOD = 277, T_DIVIDE = 278, T_MULTIPLY = 279, T_NOT = 280, U_SUBTRACT = 281, T_EXP = 282 }; #endif /* Tokens. */ #define T_NUMBER 258 #define T_IDENTIFIER 259 #define T_DATA 260 #define T_OPENPAR 261 #define T_CLOSEPAR 262 #define T_COMMA 263 #define T_INVALID 264 #define T_LOR 265 #define T_LAND 266 #define T_OR 267 #define T_AND 268 #define T_NE 269 #define T_EQ 270 #define T_GE 271 #define T_GT 272 #define T_LE 273 #define T_LT 274 #define T_SUBTRACT 275 #define T_ADD 276 #define T_MOD 277 #define T_DIVIDE 278 #define T_MULTIPLY 279 #define T_NOT 280 #define U_SUBTRACT 281 #define T_EXP 282 /* Copy the first part of user declarations. */ #line 2 "../../../src/libkstmath/eparse.y" #include #include #include #include #include "enodefactory.h" #include "eparse-eh.h" extern int yylex(Kst::ObjectStore *store); KSTMATH_EXPORT void *ParsedEquation = 0L; /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 20 "../../../src/libkstmath/eparse.y" { char *data; double number; void *n; /* tree node */ char character; } /* Line 193 of yacc.c. */ #line 172 "eparse.tab.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 185 "eparse.tab.c" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int i) #else static int YYID (i) int i; #endif { return i; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined _STDLIB_H \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef _STDLIB_H # define _STDLIB_H 1 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 360 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 28 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 17 /* YYNRULES -- Number of rules. */ #define YYNRULES 68 /* YYNRULES -- Number of states. */ #define YYNSTATES 106 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 282 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 4, 7, 9, 10, 12, 16, 19, 21, 25, 28, 30, 34, 38, 42, 46, 50, 54, 57, 60, 63, 66, 69, 72, 74, 78, 82, 86, 90, 92, 95, 98, 102, 106, 110, 113, 116, 119, 121, 124, 127, 130, 132, 136, 140, 143, 146, 148, 152, 155, 157, 159, 164, 168, 174, 179, 183, 185, 188, 190, 193, 195, 199, 201, 205, 206, 210 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 29, 0, -1, -1, 30, 31, -1, 32, -1, -1, 33, -1, 33, 10, 34, -1, 10, 1, -1, 34, -1, 34, 11, 35, -1, 11, 1, -1, 35, -1, 35, 19, 36, -1, 35, 18, 36, -1, 35, 17, 36, -1, 35, 16, 36, -1, 35, 15, 36, -1, 35, 14, 36, -1, 19, 1, -1, 17, 1, -1, 18, 1, -1, 16, 1, -1, 15, 1, -1, 14, 1, -1, 36, -1, 36, 21, 37, -1, 36, 20, 37, -1, 36, 12, 37, -1, 36, 13, 37, -1, 37, -1, 12, 1, -1, 13, 1, -1, 37, 24, 38, -1, 37, 23, 38, -1, 37, 22, 38, -1, 24, 1, -1, 23, 1, -1, 22, 1, -1, 38, -1, 20, 38, -1, 25, 38, -1, 25, 1, -1, 39, -1, 39, 27, 39, -1, 39, 27, 1, -1, 39, 27, -1, 27, 1, -1, 40, -1, 6, 33, 7, -1, 6, 1, -1, 4, -1, 5, -1, 4, 6, 7, 1, -1, 4, 6, 7, -1, 4, 6, 41, 7, 1, -1, 4, 6, 41, 7, -1, 4, 6, 1, -1, 3, -1, 3, 1, -1, 9, -1, 6, 7, -1, 42, -1, 42, 8, 44, -1, 44, -1, 42, 8, 1, -1, -1, 43, 8, 44, -1, 32, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 46, 46, 46, 57, 60, 63, 67, 69, 71, 75, 77, 79, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 111, 113, 115, 117, 119, 121, 123, 127, 129, 131, 133, 135, 137, 139, 143, 145, 147, 149, 153, 155, 157, 159, 161, 165, 167, 169, 171, 173, 175, 180, 182, 184, 186, 188, 190, 192, 196, 200, 202, 204, 206, 206, 210 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "T_NUMBER", "T_IDENTIFIER", "T_DATA", "T_OPENPAR", "T_CLOSEPAR", "T_COMMA", "T_INVALID", "T_LOR", "T_LAND", "T_OR", "T_AND", "T_NE", "T_EQ", "T_GE", "T_GT", "T_LE", "T_LT", "T_SUBTRACT", "T_ADD", "T_MOD", "T_DIVIDE", "T_MULTIPLY", "T_NOT", "U_SUBTRACT", "T_EXP", "$accept", "WRAPPER", "@1", "PRESTART", "START", "BOOLEAN_OR", "BOOLEAN_AND", "COMPARISON", "EQUATION", "TERM", "NEG", "EXP", "ATOMIC", "ARGUMENTS", "ARGLIST", "@2", "ARGUMENT", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 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 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 28, 30, 29, 31, 31, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 42, 42, 42, 43, 42, 44 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 2, 1, 0, 1, 3, 2, 1, 3, 2, 1, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 3, 3, 3, 3, 1, 2, 2, 3, 3, 3, 2, 2, 2, 1, 2, 2, 2, 1, 3, 3, 2, 2, 1, 3, 2, 1, 1, 4, 3, 5, 4, 3, 1, 2, 1, 2, 1, 3, 1, 3, 0, 3, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 2, 0, 5, 1, 0, 51, 52, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 6, 9, 12, 25, 30, 39, 43, 48, 59, 0, 50, 61, 0, 8, 11, 31, 32, 24, 23, 22, 20, 21, 19, 40, 38, 37, 36, 42, 41, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 68, 0, 62, 0, 64, 49, 7, 10, 18, 17, 16, 15, 14, 13, 28, 29, 27, 26, 35, 34, 33, 45, 44, 53, 0, 0, 0, 55, 65, 63, 67 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 1, 2, 25, 75, 27, 28, 29, 30, 31, 32, 33, 34, 76, 77, 78, 79 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -58 static const yytype_int16 yypact[] = { -58, 1, 221, -58, 46, 28, -58, 146, -58, 48, 54, 76, 79, 98, 99, 100, 101, 104, 120, 333, 141, 153, 166, 196, 177, -58, -58, 169, 181, 23, 15, 52, -58, 176, -58, -58, 121, -58, -58, 38, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, 246, 271, 296, 296, 296, 296, 296, 296, 308, 308, 308, 308, 333, 333, 333, 2, -58, 71, -58, 197, 204, 205, -58, -58, 181, 23, 15, 15, 15, 15, 15, 15, 52, 52, 52, 52, -58, -58, -58, -58, 176, -58, 96, 171, 221, -58, -58, -58, -58 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -58, -58, -58, -58, 212, 208, 160, 161, 147, -35, -19, 148, -58, -58, -58, -58, -57 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -67 static const yytype_int8 yytable[] = { 50, 3, -46, 96, 55, 4, 5, 6, 7, -46, -46, 8, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, 65, 66, 24, 89, 90, 91, 92, 36, 67, 68, 59, 60, 61, 62, 63, 64, 104, 105, 80, -58, 35, 57, 40, 93, 94, 95, -58, -58, 41, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, -54, 98, -58, 69, 70, 71, 42, -54, -54, 43, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, -56, 102, -54, 44, 45, 46, 47, -56, -56, 48, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, 49, 73, -56, 4, 5, 6, 7, 74, -66, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 51, 20, 21, 22, 23, 37, 24, 4, 5, 6, 7, 38, 52, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 53, 20, 21, 22, 23, 103, 24, 4, 5, 6, 7, 56, 57, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 58, 20, 21, 22, 23, 54, 24, 4, 5, 6, 7, 72, 99, 8, 83, 84, 85, 86, 87, 88, 100, 101, 26, 39, 19, 81, 0, 82, 97, 23, 0, 24, 4, 5, 6, 7, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 20, 21, 22, 23, 0, 24, 4, 5, 6, 7, 0, 0, 8, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 20, 21, 22, 23, 0, 24, 4, 5, 6, 7, 0, 0, 8, 0, 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 20, 21, 22, 23, 0, 24, 4, 5, 6, 7, 0, 0, 8, 0, 0, 11, 12, 0, 4, 5, 6, 7, 0, 19, 8, 20, 21, 22, 23, 0, 24, 0, 0, 0, 0, 19, 0, 20, 21, 22, 23, 0, 24, 4, 5, 6, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 23, 0, 24 }; static const yytype_int8 yycheck[] = { 19, 0, 0, 1, 23, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 12, 13, 27, 65, 66, 67, 68, 6, 20, 21, 14, 15, 16, 17, 18, 19, 100, 101, 7, 0, 1, 10, 1, 69, 70, 71, 7, 8, 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 1, 27, 22, 23, 24, 1, 7, 8, 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 1, 27, 1, 1, 1, 1, 7, 8, 1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 1, 1, 27, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 22, 23, 24, 25, 1, 27, 3, 4, 5, 6, 7, 1, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1, 22, 23, 24, 25, 1, 27, 3, 4, 5, 6, 1, 10, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 11, 22, 23, 24, 25, 1, 27, 3, 4, 5, 6, 27, 7, 9, 59, 60, 61, 62, 63, 64, 8, 8, 2, 7, 20, 57, -1, 58, 72, 25, -1, 27, 3, 4, 5, 6, -1, -1, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -1, 22, 23, 24, 25, -1, 27, 3, 4, 5, 6, -1, -1, 9, -1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -1, 22, 23, 24, 25, -1, 27, 3, 4, 5, 6, -1, -1, 9, -1, -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, -1, 22, 23, 24, 25, -1, 27, 3, 4, 5, 6, -1, -1, 9, -1, -1, 12, 13, -1, 3, 4, 5, 6, -1, 20, 9, 22, 23, 24, 25, -1, 27, -1, -1, -1, -1, 20, -1, 22, 23, 24, 25, -1, 27, 3, 4, 5, 6, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, -1, 25, -1, 27 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 29, 30, 0, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 27, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 1, 6, 1, 7, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 38, 1, 1, 1, 1, 38, 1, 10, 11, 14, 15, 16, 17, 18, 19, 12, 13, 20, 21, 22, 23, 24, 27, 1, 7, 32, 41, 42, 43, 44, 7, 34, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 1, 39, 1, 7, 8, 8, 1, 1, 44, 44 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (store, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT # if YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (YYLEX_PARAM) #else # define YYLEX yylex (store) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, store); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Kst::ObjectStore *store) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, store) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Kst::ObjectStore *store; #endif { if (!yyvaluep) return; YYUSE (store); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Kst::ObjectStore *store) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, store) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; Kst::ObjectStore *store; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, store); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Kst::ObjectStore *store) #else static void yy_reduce_print (yyvsp, yyrule, store) YYSTYPE *yyvsp; int yyrule; Kst::ObjectStore *store; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , store); fprintf (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, store); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into YYRESULT an error message about the unexpected token YYCHAR while in state YYSTATE. Return the number of bytes copied, including the terminating null byte. If YYRESULT is null, do not copy anything; just return the number of bytes that would be copied. As a special case, return 0 if an ordinary "syntax error" message will do. Return YYSIZE_MAXIMUM if overflow occurs during size calculation. */ static YYSIZE_T yysyntax_error (char *yyresult, int yystate, int yychar) { int yyn = yypact[yystate]; if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) return 0; else { int yytype = YYTRANSLATE (yychar); YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; int yysize_overflow = 0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; int yyx; # if 0 /* This is so xgettext sees the translatable formats that are constructed on the fly. */ YY_("syntax error, unexpected %s"); YY_("syntax error, unexpected %s, expecting %s"); YY_("syntax error, unexpected %s, expecting %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s"); YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); # endif char *yyfmt; char const *yyf; static char const yyunexpected[] = "syntax error, unexpected %s"; static char const yyexpecting[] = ", expecting %s"; static char const yyor[] = " or %s"; char yyformat[sizeof yyunexpected + sizeof yyexpecting - 1 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) * (sizeof yyor - 1))]; char const *yyprefix = yyexpecting; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yycount = 1; yyarg[0] = yytname[yytype]; yyfmt = yystpcpy (yyformat, yyunexpected); for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; yyformat[sizeof yyunexpected - 1] = '\0'; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; yyfmt = yystpcpy (yyfmt, yyprefix); yyprefix = yyor; } yyf = YY_(yyformat); yysize1 = yysize + yystrlen (yyf); yysize_overflow |= (yysize1 < yysize); yysize = yysize1; if (yysize_overflow) return YYSIZE_MAXIMUM; if (yyresult) { /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ char *yyp = yyresult; int yyi = 0; while ((*yyp = *yyf) != '\0') { if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyf += 2; } else { yyp++; yyf++; } } } return yysize; } } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Kst::ObjectStore *store) #else static void yydestruct (yymsg, yytype, yyvaluep, store) const char *yymsg; int yytype; YYSTYPE *yyvaluep; Kst::ObjectStore *store; #endif { YYUSE (yyvaluep); YYUSE (store); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); /* switch (yytype) { default: break; } */ } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus KSTMATH_EXPORT int yyparse (Kst::ObjectStore *store); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /* The look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (Kst::ObjectStore *store) #else int yyparse (store) Kst::ObjectStore *store; #endif #endif { int yystate; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 46 "../../../src/libkstmath/eparse.y" { (yyval.n) = 0L; yyClearErrors(); ParsedEquation = 0L; } break; case 3: #line 47 "../../../src/libkstmath/eparse.y" { (yyval.n) = ParsedEquation = (yyvsp[(2) - (2)].n); if (yyErrorCount() > 0) { DeleteNode((yyval.n)); (yyval.n) = 0L; ParsedEquation = 0L; YYERROR; } } break; case 4: #line 58 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 5: #line 60 "../../../src/libkstmath/eparse.y" { (yyval.n) = 0L; yyerror(store, EParseErrorEmpty); } break; case 6: #line 64 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 7: #line 68 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewLogicalOr((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 8: #line 70 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 9: #line 72 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 10: #line 76 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewLogicalAnd((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 11: #line 78 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 12: #line 80 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 13: #line 84 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewLessThan((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 14: #line 86 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewLessThanEqual((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 15: #line 88 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewGreaterThan((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 16: #line 90 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewGreaterThanEqual((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 17: #line 92 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewEqualTo((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 18: #line 94 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewNotEqualTo((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 19: #line 96 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 20: #line 98 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 21: #line 100 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 22: #line 102 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 23: #line 104 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 24: #line 106 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 25: #line 108 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 26: #line 112 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewAddition((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 27: #line 114 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewSubtraction((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 28: #line 116 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewBitwiseOr((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 29: #line 118 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewBitwiseAnd((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 30: #line 120 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 31: #line 122 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 32: #line 124 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 33: #line 128 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewMultiplication((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 34: #line 130 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewDivision((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 35: #line 132 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewModulo((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 36: #line 134 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 37: #line 136 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 38: #line 138 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorTwoOperands); (yyval.n) = 0L; } break; case 39: #line 140 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 40: #line 144 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewNegation((yyvsp[(2) - (2)].n)); } break; case 41: #line 146 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewNot((yyvsp[(2) - (2)].n)); } break; case 42: #line 148 "../../../src/libkstmath/eparse.y" { (yyval.n) = 0L; yyerror(store, EParseErrorRequiresOperand); } break; case 43: #line 150 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 44: #line 154 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewPower((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } break; case 45: #line 156 "../../../src/libkstmath/eparse.y" { DeleteNode((yyvsp[(1) - (3)].n)); (yyval.n) = 0L; yyerror(store, EParseErrorTwoOperands); } break; case 46: #line 158 "../../../src/libkstmath/eparse.y" { DeleteNode((yyvsp[(1) - (2)].n)); (yyval.n) = 0L; yyerror(store, EParseErrorTwoOperands); } break; case 47: #line 160 "../../../src/libkstmath/eparse.y" { (yyval.n) = 0L; yyerror(store, EParseErrorTwoOperands); } break; case 48: #line 162 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 49: #line 166 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(2) - (3)].n); ParenthesizeNode((yyval.n)); } break; case 50: #line 168 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorMissingClosingParenthesis); (yyval.n) = 0L; } break; case 51: #line 170 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewIdentifier((yyvsp[(1) - (1)].data)); } break; case 52: #line 172 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewData(store, (yyvsp[(1) - (1)].data)); } break; case 53: #line 174 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorNoImplicitMultiply); free((yyvsp[(1) - (4)].data)); (yyval.n) = 0L; } break; case 54: #line 176 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewFunction((yyvsp[(1) - (3)].data), NewArgumentList()); } break; case 55: #line 181 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorNoImplicitMultiply); DeleteNode((yyvsp[(3) - (5)].n)); free((yyvsp[(1) - (5)].data)); (yyval.n) = 0L; } break; case 56: #line 183 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewFunction((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].n)); } break; case 57: #line 185 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorMissingClosingParenthesis); free((yyvsp[(1) - (3)].data)); (yyval.n) = 0L; } break; case 58: #line 187 "../../../src/libkstmath/eparse.y" { (yyval.n) = NewNumber((yyvsp[(1) - (1)].number)); } break; case 59: #line 189 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorNoImplicitMultiply); (yyval.n) = 0L; } break; case 60: #line 191 "../../../src/libkstmath/eparse.y" { yyerrortoken((yyvsp[(1) - (1)].character)); (yyval.n) = 0L; } break; case 61: #line 193 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorEmptyParentheses); (yyval.n) = 0L; } break; case 62: #line 197 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; case 63: #line 201 "../../../src/libkstmath/eparse.y" { if ((yyvsp[(1) - (3)].n) && (yyvsp[(3) - (3)].n)) { AppendArgument((yyvsp[(1) - (3)].n), (yyvsp[(3) - (3)].n)); } else { DeleteNode((yyvsp[(1) - (3)].n)); DeleteNode((yyvsp[(3) - (3)].n)); (yyvsp[(1) - (3)].n) = 0L; } (yyval.n) = (yyvsp[(1) - (3)].n); } break; case 64: #line 203 "../../../src/libkstmath/eparse.y" { if ((yyvsp[(1) - (1)].n)) { (yyval.n) = NewArgumentList(); AppendArgument((yyval.n), (yyvsp[(1) - (1)].n)); } else { (yyval.n) = 0L; } } break; case 65: #line 205 "../../../src/libkstmath/eparse.y" { (yyval.n) = 0L; DeleteNode((yyvsp[(1) - (3)].n)); yyerror(store, EParseErrorEmptyArg); } break; case 66: #line 206 "../../../src/libkstmath/eparse.y" {} break; case 67: #line 207 "../../../src/libkstmath/eparse.y" { yyerror(store, EParseErrorEmptyArg); DeleteNode((yyvsp[(3) - (3)].n)); (yyval.n) = 0L; } break; case 68: #line 211 "../../../src/libkstmath/eparse.y" { (yyval.n) = (yyvsp[(1) - (1)].n); } break; /* Line 1267 of yacc.c. */ #line 1871 "eparse.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (store, YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (store, yymsg); } else { yyerror (store, YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse look-ahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, store); yychar = YYEMPTY; } } /* Else will try to reuse look-ahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, store); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (store, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && yychar != YYEMPTY) yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, store); /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, store); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } #line 214 "../../../src/libkstmath/eparse.y" kst-2.0.3/src/libkstmath/image.h000644 001750 001750 00000012706 11544160207 017063 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 by University of British Columbia * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef IMAGE_H #define IMAGE_H #include "matrix.h" #include "relation.h" #include "kstmath_export.h" #include "palette.h" #include "labelinfo.h" #include namespace Kst { class ObjectStore; class CoutourLineDetails { public: CoutourLineDetails() { } CoutourLineDetails(QLine line, int width) { _line = line; _lineWidth = width; } QLine _line; int _lineWidth; }; /**A class for handling images for Kst *@author University of British Columbia */ class KSTMATH_EXPORT Image : public Relation { Q_OBJECT public: static const QString staticTypeString; const QString& typeString() const { return staticTypeString; } static const QString staticTypeTag; virtual void showNewDialog(); virtual void showEditDialog(); virtual void save(QXmlStreamWriter &s); virtual void internalUpdate(); virtual QString propertyString() const; virtual bool getNearestZ(double x, double y, double& z); virtual QColor getMappedColor(double z); virtual void setPalette(const Palette &pal); virtual void setUpperThreshold(double z); virtual void setLowerThreshold(double z); virtual void setAutoThreshold(bool yes); virtual void setThresholdToSpikeInsensitive(double per = 0.005); virtual double upperThreshold() const { return _zUpper; } virtual double lowerThreshold() const { return _zLower; } virtual bool autoThreshold() const { return _autoThreshold; } virtual MatrixPtr matrix() const; virtual QString paletteName() const; virtual const Palette &palette() const { return _pal; } virtual void matrixDimensions(double &x, double &y, double &width, double &height); virtual void changeToColorOnly(MatrixPtr in_matrix, double lowerZ, double upperZ, bool autoThreshold, const QString &paletteName); virtual void changeToContourOnly(MatrixPtr in_matrix, int numContours, const QColor& contourColor, int contourWeight); virtual void changeToColorAndContour(MatrixPtr in_matrix, double lowerZ, double upperZ, bool autoThreshold, const QString &paletteName, int numContours, const QColor& contourColor, int contourWeight); //contour lines virtual int numContourLines() const { return _numContourLines; } virtual QList contourLines() const { return _contourLines; } virtual bool addContourLine(double line); virtual bool removeContourLine(double line); virtual void clearContourLines(); virtual const QColor& contourColor() const { return _contourColor; } virtual int contourWeight() const { return _contourWeight; } // a contour weight of -1 means variable weight //other properties virtual bool hasContourMap() const { return _hasContourMap; } virtual bool hasColorMap() const { return _hasColorMap; } // labels for plots virtual LabelInfo xLabelInfo() const; virtual LabelInfo yLabelInfo() const; virtual LabelInfo titleInfo() const; virtual RelationPtr makeDuplicate() const; // see KstRelation::providerDataObject virtual DataObjectPtr providerDataObject() const; // see KstRelation::distanceToPoint virtual double distanceToPoint(double xpos, double dx, double ypos) const; // see KstRelation::paint void paintObjects(const CurveRenderContext& context); // Update the curve details. void updatePaintObjects(const CurveRenderContext& context); // see KstRelation::yRange virtual void yRange(double xFrom, double xTo, double* yMin, double* yMax); // see KstRelation::paintLegendSymbol virtual void paintLegendSymbol(QPainter *p, const QRectF& bound); virtual QString descriptionTip() const; virtual bool invertXHint() const; virtual bool invertYHint() const; protected: Image(ObjectStore *store); virtual ~Image(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); private: //use these to set defaults when either is not used. void setColorDefaults(); void setContourDefaults(); Palette _pal; //upper and lower thresholds double _zUpper; double _zLower; bool _autoThreshold; bool _hasColorMap; bool _hasContourMap; int _numContourLines; QList _contourLines; QColor _contourColor; int _contourWeight; //_contourWeight = -1 means variable weight QVector _lines; QImage _image; QPoint _imageLocation; }; typedef SharedPtr ImagePtr; typedef ObjectList ImageList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/psd.cpp000644 001750 001750 00000027260 11544160207 017123 0ustar00synthsynth000000 000000 /*************************************************************************** psd.cpp: Power Spectra for KST ------------------- begin : Fri Feb 10 2002 copyright : (C) 2002 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A class for handling power spectra for kst *@author C. Barth Netterfield */ #include #include #include #include "kst_i18n.h" #include #include "dialoglauncher.h" #include "datacollection.h" #include "debug.h" #include "psd.h" #include "psdcalculator.h" #include "objectstore.h" extern "C" void rdft(int n, int isgn, double *a); namespace Kst { const QString PSD::staticTypeString = I18N_NOOP("Power Spectrum"); const QString PSD::staticTypeTag = I18N_NOOP("powerspectrum"); const QLatin1String& INVECTOR = QLatin1String("I"); const QLatin1String& SVECTOR = QLatin1String("S"); const QLatin1String& FVECTOR = QLatin1String("F"); #define KSTPSDMAXLEN 27 PSD::PSD(ObjectStore *store) : DataObject(store) { _typeString = staticTypeString; _type = "PowerSpectrum"; _initializeShortName(); Q_ASSERT(store); VectorPtr ov = store->createObject(); ov->setProvider(this); ov->setSlaveName("f"); ov->resize(2); _fVector = _outputVectors.insert(FVECTOR, ov).value(); ov = store->createObject(); ov->setProvider(this); ov->setSlaveName("psd"); ov->resize(2); _sVector = _outputVectors.insert(SVECTOR, ov).value(); } void PSD::_initializeShortName() { _shortName = 'S'+QString::number(_psdnum); if (_psdnum>max_psdnum) max_psdnum = _psdnum; _psdnum++; } void PSD::change(VectorPtr in_V, double in_freq, bool in_average, int in_averageLen, bool in_apodize, bool in_removeMean, const QString& in_VUnits, const QString& in_RUnits, ApodizeFunction in_apodizeFxn, double in_gaussianSigma, PSDType in_output, bool interpolateHoles) { if (in_V) { _inputVectors[INVECTOR] = in_V; } _Frequency = in_freq; _Average = in_average; _Apodize = in_apodize; _apodizeFxn = in_apodizeFxn; _gaussianSigma = in_gaussianSigma; _prevOutput = PSDUndefined; _RemoveMean = in_removeMean; _vectorUnits = in_VUnits; _rateUnits = in_RUnits; _Output = in_output; _interpolateHoles = interpolateHoles; _averageLength = in_averageLen; _last_n_subsets = 0; _last_n_new = 0; _PSDLength = 1; _fVector->resize(_PSDLength); _sVector->resize(_PSDLength); updateVectorLabels(); } PSD::~PSD() { _sVector = 0L; _fVector = 0L; } const CurveHintList *PSD::curveHints() const { _curveHints->clear(); _curveHints->append(new CurveHint(i18n("PSD Curve"), _fVector->shortName(), _sVector->shortName())); return _curveHints; } void PSD::internalUpdate() { writeLockInputsAndOutputs(); VectorPtr iv = _inputVectors[INVECTOR]; const int v_len = iv->length(); _last_n_new += iv->numNew(); assert(_last_n_new >= 0); int n_subsets = v_len/_PSDLength; // determine if the PSD needs to be updated. // if not using averaging, then we need at least _PSDLength/16 new data points. // if averaging, then we want enough new data for a complete subset. if ( ((_last_n_new < _PSDLength/16) || (_Average && (n_subsets - _last_n_subsets < 1))) && iv->length() != iv->numNew()) { unlockInputsAndOutputs(); return; } _adjustLengths(); double *psd = _sVector->value(); double *f = _fVector->value(); int i_samp; for (i_samp = 0; i_samp < _PSDLength; ++i_samp) { f[i_samp] = i_samp * 0.5 * _Frequency / (_PSDLength - 1); } _psdCalculator.calculatePowerSpectrum(iv->value(), v_len, psd, _PSDLength, _RemoveMean, _interpolateHoles, _Average, _averageLength, _Apodize, _apodizeFxn, _gaussianSigma, _Output, _Frequency); _last_n_subsets = n_subsets; _last_n_new = 0; updateVectorLabels(); // should be updated by the update manager //_sVector->update(); //_fVector->update(); unlockInputsAndOutputs(); return; } void PSD::_adjustLengths() { int nPSDLen = PSDCalculator::calculateOutputVectorLength(_inputVectors[INVECTOR]->length(), _Average, _averageLength); if (_PSDLength != nPSDLen) { _sVector->resize(nPSDLen); _fVector->resize(nPSDLen); if ( (_sVector->length() == nPSDLen) && (_fVector->length() == nPSDLen) ) { _PSDLength = nPSDLen; } else { Debug::self()->log(i18n("Attempted to create a PSD that used all memory."), Debug::Error); } _last_n_subsets = 0; } } void PSD::save(QXmlStreamWriter &s) { s.writeStartElement(staticTypeTag); s.writeAttribute("vector", _inputVectors[INVECTOR]->Name()); s.writeAttribute("samplerate", QString::number(_Frequency)); s.writeAttribute("gaussiansigma", QString::number(_gaussianSigma)); s.writeAttribute("average", QVariant(_Average).toString()); s.writeAttribute("fftlength", QString::number(int(ceil(log(double(_PSDLength*2)) / log(2.0))))); s.writeAttribute("removemean", QVariant(_RemoveMean).toString()); s.writeAttribute("apodize", QVariant(_Apodize).toString()); s.writeAttribute("apodizefunction", QString::number(_apodizeFxn)); s.writeAttribute("interpolateholes", QVariant(_interpolateHoles).toString()); s.writeAttribute("vectorunits", _vectorUnits); s.writeAttribute("rateunits", _rateUnits); s.writeAttribute("outputtype", QString::number(_Output)); saveNameInfo(s, VNUM|PSDNUM|XNUM); s.writeEndElement(); } bool PSD::apodize() const { return _Apodize; } void PSD::setApodize(bool in_apodize) { _Apodize = in_apodize; } bool PSD::removeMean() const { return _RemoveMean; } void PSD::setRemoveMean(bool in_removeMean) { _RemoveMean = in_removeMean; } bool PSD::average() const { return _Average; } void PSD::setAverage(bool in_average) { _Average = in_average; } double PSD::frequency() const { return _Frequency; } void PSD::setFrequency(double in_frequency) { if (in_frequency > 0.0) { _Frequency = in_frequency; } else { _Frequency = 1.0; } } int PSD::length() const { return _averageLength; } void PSD::setLength(int in_length) { if (in_length != _averageLength) { _averageLength = in_length; } } PSDType PSD::output() const { return _Output; } void PSD::setOutput(PSDType in_output) { if (in_output != _Output) { _Output = in_output; } } VectorPtr PSD::vector() const { return _inputVectors[INVECTOR]; } void PSD::setVector(VectorPtr new_v) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); VectorPtr v = _inputVectors[INVECTOR]; if (v) { if (v == new_v) { return; } v->unlock(); } _inputVectors.remove(INVECTOR); new_v->writeLock(); _inputVectors[INVECTOR] = new_v; } bool PSD::slaveVectorsUsed() const { return true; } QString PSD::propertyString() const { return i18n("PSD: %1", _inputVectors[INVECTOR]->Name()); } void PSD::showNewDialog() { DialogLauncher::self()->showPowerSpectrumDialog(); } void PSD::showEditDialog() { DialogLauncher::self()->showPowerSpectrumDialog(this); } const QString& PSD::vectorUnits() const { return _vectorUnits; } void PSD::setVectorUnits(const QString& units) { _vectorUnits = units; } const QString& PSD::rateUnits() const { return _rateUnits; } void PSD::setRateUnits(const QString& units) { _rateUnits = units; } ApodizeFunction PSD::apodizeFxn() const { return _apodizeFxn; } void PSD::setApodizeFxn(ApodizeFunction in_apodizeFxn) { if (_apodizeFxn != in_apodizeFxn) { _apodizeFxn = in_apodizeFxn; } } double PSD::gaussianSigma() const { return _gaussianSigma; } void PSD::setGaussianSigma(double in_gaussianSigma) { if (_gaussianSigma != in_gaussianSigma) { _gaussianSigma = in_gaussianSigma; } } DataObjectPtr PSD::makeDuplicate() const { PSDPtr powerspectrum = store()->createObject(); Q_ASSERT(powerspectrum); powerspectrum->writeLock(); powerspectrum->setVector(_inputVectors[INVECTOR]); powerspectrum->setFrequency(_Frequency); powerspectrum->setAverage(_Average); powerspectrum->setLength(_averageLength); powerspectrum->setApodize(_Apodize); powerspectrum->setRemoveMean(_RemoveMean); powerspectrum->setVectorUnits(_vectorUnits); powerspectrum->setRateUnits(_rateUnits); powerspectrum->setApodizeFxn(_apodizeFxn); powerspectrum->setGaussianSigma(_gaussianSigma); powerspectrum->setOutput(_Output); powerspectrum->setInterpolateHoles(_interpolateHoles); if (descriptiveNameIsManual()) { powerspectrum->setDescriptiveName(descriptiveName()); } powerspectrum->registerChange(); powerspectrum->unlock(); return DataObjectPtr(powerspectrum); } bool PSD::interpolateHoles() const { return _interpolateHoles; } void PSD::setInterpolateHoles(bool interpolate) { if (interpolate != _interpolateHoles) { _interpolateHoles = interpolate; } } void PSD::updateVectorLabels() { LabelInfo label_info; switch (_Output) { default: case 0: // amplitude spectral density (default) [V/Hz^1/2] label_info.quantity = i18n("Spectral Density"); if (_vectorUnits.isEmpty() || _rateUnits.isEmpty()) { label_info.units = QString(); } else { label_info.units = QString("%1/%2^{1/2}").arg(_vectorUnits).arg(_rateUnits); } break; case 1: // power spectral density [V^2/Hz] label_info.quantity = i18n("PSD"); if (_vectorUnits.isEmpty() || _rateUnits.isEmpty()) { label_info.units = QString(); } else { label_info.units = QString("%1^2/%2").arg(_vectorUnits).arg(_rateUnits); } break; case 2: // amplitude spectrum [V] label_info.quantity = i18n("Amplitude Spectrum"); if (_vectorUnits.isEmpty() || _rateUnits.isEmpty()) { label_info.units = QString(); } else { label_info.units = QString("%1").arg(_vectorUnits); } break; case 3: // power spectrum [V^2] label_info.quantity = i18n("Power Spectrum"); if (_vectorUnits.isEmpty() || _rateUnits.isEmpty()) { label_info.units = QString(); } else { label_info.units = QString("%1^2").arg(_vectorUnits); } break; } label_info.name = QString(); _sVector->setLabelInfo(label_info); label_info.quantity = i18n("Frequency"); label_info.units = _rateUnits; _fVector->setLabelInfo(label_info); label_info.quantity.clear(); label_info.units.clear(); label_info.name = _inputVectors[INVECTOR]->labelInfo().name; _sVector->setTitleInfo(label_info); } QString PSD::_automaticDescriptiveName() const { return vector()->descriptiveName(); } QString PSD::descriptionTip() const { QString tip; tip = i18n("Spectrum: %1\n FFT Length: 2^%2").arg(Name()).arg(length()); if (average() || apodize() || removeMean()) { tip += "\n "; if (average()) tip += i18n("Average; "); if (apodize()) tip += i18n("Apodize; "); if (removeMean()) tip += i18n("Remove Mean;"); } tip += i18n("\nInput: %1").arg(_inputVectors[INVECTOR]->descriptionTip()); return tip; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/eventmonitorentry.h000644 001750 001750 00000007146 11544160207 021616 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2004 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EVENTMONITORENTRY_H #define EVENTMONITORENTRY_H #include #include "dataobject.h" #include "debug.h" namespace Equations { class Node; class Context; } namespace Kst { class KSTMATH_EXPORT EventMonitorEntry : public DataObject { Q_OBJECT public: static const QString staticTypeString; const QString& typeString() const { return staticTypeString; } static const QString staticTypeTag; void save(QXmlStreamWriter &s); QString propertyString() const; void showNewDialog(); void showEditDialog(); bool needToEvaluate(); bool isValid() const { return _isValid; } void log(int idx); const QString& event() const { return _event; } const QString& description() const { return _description; } Debug::LogLevel level() const { return _level; } Equations::Node* expression() const { return _pExpression; } bool logDebug() const { return _logDebug; } bool logEMail() const { return _logEMail; } bool logELOG() const { return _logELOG; } const QString& eMailRecipients() const { return _eMailRecipients; } const QString& scriptCode() const; void setScriptCode(const QString& script); void setEvent(const QString& str); void setDescription(const QString& str); void setLevel(Debug::LogLevel level); void setExpression(Equations::Node* pExpression); void setLogDebug(bool logDebug); void setLogEMail(bool logEMail); void setLogELOG(bool logELOG); void setEMailRecipients(const QString& str); bool reparse(); DataObjectPtr makeDuplicate() const; bool uses(ObjectPtr p) const; virtual QString descriptionTip() const; virtual void internalUpdate(); protected: EventMonitorEntry(ObjectStore *store); ~EventMonitorEntry(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); bool event(QEvent *e); private slots: void doLog(const QString& logMessage) const; private: void logImmediately(bool sendEvent = true); static const QString OUTXVECTOR; static const QString OUTYVECTOR; VectorMap _vectorsUsed; QVector _indexArray; QString _event; QString _description; QString _eMailRecipients; Debug::LogLevel _level; Equations::Node* _pExpression; VectorMap::Iterator _xVector; VectorMap::Iterator _yVector; bool _logDebug; bool _logEMail; bool _logELOG; bool _isValid; int _numDone; QString _script; }; typedef SharedPtr EventMonitorEntryPtr; typedef ObjectList EventMonitorEntryList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/emailthread.cpp000644 001750 001750 00000005774 11544160207 020622 0ustar00synthsynth000000 000000 /*************************************************************************** emailthread.cpp ---------------- begin : Jul 7 2004 copyright : (C) 2004 The University of british Columbia email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // include files for Qt #include // application specific includes #include "emailthread.h" #include "debug.h" namespace Kst { EMailThread::EMailThread( const QString& strTo, const QString& strSubject, const QString& strBody ) : QObject() { _strTo = strTo; _strSubject = strSubject; _strBody = strBody.toLatin1(); _strFrom = Settings::globalSettings()->emailSender; _strSMTPServer = Settings::globalSettings()->emailSMTPServer; _useAuthentication = Settings::globalSettings()->emailRequiresAuthentication; _strUsername = Settings::globalSettings()->emailUsername; _strPassword = Settings::globalSettings()->emailPassword; _iPort = Settings::globalSettings()->emailSMTPPort; _encryption = Settings::globalSettings()->emailEncryption; _authentication = Settings::globalSettings()->emailAuthentication; } EMailThread::EMailThread( const QString& strTo, const QString& strSubject, const QString& strBody, const QString& strFrom, const QString& strSMTPServer, const int iPort, const EMailEncryption encryption, const QString& strUsername, const QString& strPassword, const EMailAuthentication authentication, const bool useAuthentication ) : QObject() { _strTo = strTo; _strSubject = strSubject; _strBody = strBody.toLatin1(); _strFrom = strFrom; _strSMTPServer = strSMTPServer; _useAuthentication = useAuthentication; _strUsername = strUsername; _strPassword = strPassword; _iPort = iPort; _encryption = encryption; _authentication = authentication; } EMailThread::~EMailThread() { } void EMailThread::send() { //TODO Implement Send. } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/image.cpp000644 001750 001750 00000055674 11544160207 017431 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 by University of British Columbia * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dialoglauncher.h" #include "datacollection.h" #include "debug.h" #include "image.h" #include "math_kst.h" #include "objectstore.h" #include "kst_i18n.h" #include #include #include #include //#define BENCHMARK namespace Kst { const QString Image::staticTypeString = I18N_NOOP("Image"); const QString Image::staticTypeTag = I18N_NOOP("image"); static const QLatin1String& THEMATRIX = QLatin1String("THEMATRIX"); Image::Image(ObjectStore *store) : Relation(store) { _typeString = staticTypeString; _type = "Image"; _initializeShortName(); _hasContourMap = false; _hasColorMap = false; setColorDefaults(); setContourDefaults(); } Image::~Image() { } void Image::_initializeShortName() { _shortName = 'I'+QString::number(_inum); if (_inum>max_inum) max_inum = _inum; _inum++; } void Image::save(QXmlStreamWriter &s) { s.writeStartElement(staticTypeTag); if (_inputMatrices.contains(THEMATRIX)) { s.writeAttribute("matrix", _inputMatrices[THEMATRIX]->Name()); } if (_pal.colorCount()>0) { s.writeAttribute("palettename", _pal.paletteName()); } s.writeAttribute("hascolormap", QVariant(_hasColorMap).toString()); s.writeAttribute("lowerthreshold", QString::number(_zLower)); s.writeAttribute("upperthreshold", QString::number(_zUpper)); s.writeAttribute("hascontourmap", QVariant(_hasContourMap).toString()); s.writeAttribute("numcontourlines", QString::number(_numContourLines)); s.writeAttribute("contourweight", QString::number(_contourWeight)); s.writeAttribute("contourcolor", _contourColor.name()); s.writeAttribute("autothreshold", QVariant(_autoThreshold).toString()); saveNameInfo(s, INUM); s.writeEndElement(); } void Image::internalUpdate() { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); writeLockInputsAndOutputs(); if (_inputMatrices.contains(THEMATRIX)) { MatrixPtr mp = _inputMatrices[THEMATRIX]; // stats NS = mp->sampleCount(); MinX = mp->minX(); int xNumSteps = mp->xNumSteps(); double xStepSize = mp->xStepSize(); MaxX = xNumSteps*xStepSize + MinX; MinY = mp->minY(); int yNumSteps = mp->yNumSteps(); double yStepSize = mp->yStepSize(); MaxY = yNumSteps*yStepSize + MinY; _ns_maxx = MaxX; _ns_minx = MinX; _ns_maxy = MaxY; _ns_miny = MinY; MinPosY = MinY > 0 ? MinY : 0; MinPosX = MinX > 0 ? MinX : 0; //recalculate the thresholds if necessary if (_autoThreshold) { _zLower = mp->minValue(); _zUpper = mp->maxValue(); } //update the contour lines if (hasContourMap()) { double min = mp->minValue(), max = mp->maxValue(); double contourStep = (max - min) / (double)(_numContourLines + 1); if (contourStep > 0) { _contourLines.clear(); for (int i = 0; i < _numContourLines; i++) { _contourLines.append(min + (i+1) * contourStep); } } } _redrawRequired = true; } unlockInputsAndOutputs(); return; } QString Image::propertyString() const { if (_inputMatrices.contains(THEMATRIX)) { return i18n("Image of %1" ).arg(_inputMatrices[THEMATRIX]->Name()); } else { return QString(); } } //FIXME: Inline and optimize! QColor Image::getMappedColor(double z) { int index; if (_zUpper - _zLower != 0) { index = (int)(((z - _zLower) * (_pal.colorCount() - 1)) / (_zUpper - _zLower)); } else { index = 0; } return _pal.color(index); } void Image::setPalette(const Palette &pal) { _pal.changePaletteName(pal.paletteName()); } void Image::showNewDialog() { DialogLauncher::self()->showImageDialog(); } void Image::showEditDialog() { DialogLauncher::self()->showImageDialog(this); } void Image::setUpperThreshold(double z) { _zUpper = z; } void Image::setLowerThreshold(double z) { _zLower = z; } void Image::setThresholdToSpikeInsensitive(double per) { if (per==0) { setAutoThreshold(true); } else { matrix()->writeLock(); matrix()->calcNoSpikeRange(per); matrix()->unlock(); setLowerThreshold(matrix()->minValueNoSpike()); setUpperThreshold(matrix()->maxValueNoSpike()); setAutoThreshold(false); } } void Image::changeToColorOnly(MatrixPtr in_matrix, double lowerZ, double upperZ, bool autoThreshold, const QString &paletteName) { _inputMatrices[THEMATRIX] = in_matrix; _zLower = lowerZ; _zUpper = upperZ; _autoThreshold = autoThreshold; if (_pal.paletteName() != paletteName) { _pal.changePaletteName(paletteName); } _hasColorMap = true; _hasContourMap = false; } void Image::changeToContourOnly(MatrixPtr in_matrix, int numContours, const QColor& contourColor, int contourWeight) { _inputMatrices[THEMATRIX] = in_matrix; _numContourLines = numContours; _contourWeight = contourWeight; _contourColor = contourColor; _hasColorMap = false; _hasContourMap = true; } void Image::changeToColorAndContour(MatrixPtr in_matrix, double lowerZ, double upperZ, bool autoThreshold, const QString &paletteName, int numContours, const QColor& contourColor, int contourWeight) { _inputMatrices[THEMATRIX] = in_matrix; _zLower = lowerZ; _zUpper = upperZ; _autoThreshold = autoThreshold; if (_pal.paletteName() != paletteName) { _pal.changePaletteName(paletteName); } _numContourLines = numContours; _contourWeight = contourWeight; _contourColor = contourColor; _hasColorMap = true; _hasContourMap = true; } void Image::matrixDimensions(double &x, double &y, double &width, double &height) { if (_inputMatrices.contains(THEMATRIX)) { MatrixPtr mp = _inputMatrices[THEMATRIX]; if (_inputMatrices.contains(THEMATRIX)) { x = mp->minX(); y = mp->minY(); width = mp->xNumSteps() * mp->xStepSize(); height = mp->yNumSteps() * mp->yStepSize(); } else { x = y = width = height = 0; } } else { x = y = width = height = 0; } } //this should check for duplicates bool Image::addContourLine(double line) { _contourLines.append(line); return true; } bool Image::removeContourLine(double line) { return _contourLines.removeAll(line); } void Image::clearContourLines() { _contourLines.clear(); } bool Image::getNearestZ(double x, double y, double& z) { bool ok; z = _inputMatrices[THEMATRIX]->value(x,y,&ok); return ok; } QString Image::paletteName() const { return _pal.paletteName(); } void Image::setColorDefaults() { _zLower = 0; _zUpper = 100; } void Image::setContourDefaults() { _contourColor = QColor("red"); _numContourLines = 1; _contourWeight = 0; } void Image::setAutoThreshold(bool yes) { _autoThreshold = yes; } RelationPtr Image::makeDuplicate() const { ImagePtr image = store()->createObject(); if (!_hasContourMap) { image->changeToColorOnly(_inputMatrices[THEMATRIX], _zLower, _zUpper, _autoThreshold, _pal.paletteName()); } else if (!_hasColorMap) { image->changeToContourOnly(_inputMatrices[THEMATRIX], _numContourLines, _contourColor, _contourWeight); } else { image->changeToColorAndContour(_inputMatrices[THEMATRIX], _zLower, _zUpper, _autoThreshold, _pal.paletteName(), _numContourLines, _contourColor, _contourWeight); } if (descriptiveNameIsManual()) { image->setDescriptiveName(descriptiveName()); } image->writeLock(); image->registerChange(); image->unlock(); return RelationPtr(image); } MatrixPtr Image::matrix() const { if (_inputMatrices.contains(THEMATRIX)) { return _inputMatrices[THEMATRIX]; } else { return NULL; } } bool Image::invertXHint() const { if (_inputMatrices.contains(THEMATRIX)) { return _inputMatrices[THEMATRIX]->invertXHint(); } else { return false; } } bool Image::invertYHint() const { if (_inputMatrices.contains(THEMATRIX)) { return _inputMatrices[THEMATRIX]->invertYHint(); } else { return false; } } LabelInfo Image::xLabelInfo() const { if (_inputMatrices.contains(THEMATRIX)) { return (_inputMatrices[THEMATRIX]->xLabelInfo()); } else { return LabelInfo(); } } LabelInfo Image::yLabelInfo() const { if (_inputMatrices.contains(THEMATRIX)) { return (_inputMatrices[THEMATRIX]->yLabelInfo()); } else { return LabelInfo(); } } LabelInfo Image::titleInfo() const { if (_inputMatrices.contains(THEMATRIX)) { return (_inputMatrices[THEMATRIX]->titleInfo()); } else { return LabelInfo(); } } DataObjectPtr Image::providerDataObject() const { DataObjectPtr provider = 0L; // FIXME: fix this.. I don't know what's going on here #if 0 matrixList.lock().readLock(); MatrixPtr mp = *matrixList.findTag(matrixTag()); matrixList.lock().unlock(); DataObjectPtr provider = 0L; if (mp) { mp->readLock(); provider = kst_cast(mp->provider()); mp->unlock(); } #endif return provider; } double Image::distanceToPoint(double xpos, double dx, double ypos) const { Q_UNUSED(dx) // dx is not relevant for double clicks on images - clicks must be inside the image if (xpos <= MaxX && xpos >= MinX && ypos <= MaxY && ypos >= MinY) { return 0; } return 1.0E300; } void Image::paintObjects(const CurveRenderContext& context) { QPainter* p = context.painter; if (hasColorMap()) { p->drawImage(_imageLocation, _image); } if (hasContourMap()) { QColor lineColor = contourColor(); foreach(const CoutourLineDetails& lineDetails, _lines) { p->setPen(QPen(lineColor, lineDetails._lineWidth, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin)); p->drawLine(lineDetails._line); } } } void Image::updatePaintObjects(const CurveRenderContext& context) { double Lx = context.Lx, Hx = context.Hx, Ly = context.Ly, Hy = context.Hy; double m_X = context.m_X, m_Y = context.m_Y, b_X = context.b_X, b_Y = context.b_Y; double x_max = context.x_max, y_max = context.y_max, x_min = context.x_min, y_min = context.y_min; bool xLog = context.xLog, yLog = context.yLog; double xLogBase = context.xLogBase; double yLogBase = context.yLogBase; double x, y, width, height; double img_Lx_pix = 0, img_Ly_pix = 0, img_Hx_pix = 0, img_Hy_pix = 0; #ifdef BENCHMARK QTime bench_time, benchtmp; int b_1 = 0, b_2 = 0; bench_time.start(); benchtmp.start(); int numberOfLinesDrawn = 0; #endif ImagePtr image = this; _image = QImage(); _lines.clear(); if (_inputMatrices.contains(THEMATRIX)) { // don't paint if we have no matrix image->matrixDimensions(x, y, width, height); // figure out where the image will be on the plot if (xLog) { x_min = pow(xLogBase, x_min); x_max = pow(xLogBase, x_max); } if (yLog) { y_min = pow(yLogBase, y_min); y_max = pow(yLogBase, y_max); } // only draw if img is visible if (!(x > x_max || y > y_max || x + width < x_min || y + height < y_min)) { if (x < x_min) { img_Lx_pix = Lx; } else { if (xLog) { img_Lx_pix = logXLo(x, xLogBase) * m_X + b_X; } else { img_Lx_pix = x * m_X + b_X; } } if (y < y_min) { img_Hy_pix = Hy; } else { if (yLog) { img_Hy_pix = logYLo(y, yLogBase) * m_Y + b_Y; } else { img_Hy_pix = y * m_Y + b_Y; } } if (x + width > x_max) { img_Hx_pix = Hx; } else { if (xLog) { img_Hx_pix = logXLo(x + width, xLogBase) * m_X + b_X; } else { img_Hx_pix = (x + width) * m_X + b_X; } } if (y + height > y_max) { img_Ly_pix = Ly; } else { if (yLog) { img_Ly_pix = logYLo(y + height, yLogBase) * m_Y + b_Y; } else { img_Ly_pix = (y + height) * m_Y + b_Y; } } // color map QColor thisPixel; MatrixPtr m = _inputMatrices.value(THEMATRIX); if (image->hasColorMap()) { int hXlXDiff = d2i(img_Hx_pix - img_Lx_pix); int hYlYDiff = d2i(img_Hy_pix - img_Ly_pix - 1); _image = QImage(hXlXDiff, hYlYDiff, QImage::Format_RGB32); //_image.fill(0); int ih = _image.height(); int iw = _image.width(); double m_minX = m->minX(); double m_minY = m->minY(); double m_numY = m->yNumSteps(); double m_stepYr = 1.0/m->yStepSize(); double m_stepXr = 1.0/m->xStepSize(); int x_index; int y_index; int palCountMinus1 = _pal.colorCount() - 1; double palCountMin1_OverDZ = double(palCountMinus1) / (_zUpper - _zLower); for (int y = 0; y < ih; ++y) { bool okY = true; QRgb *scanLine = (QRgb *)_image.scanLine(y); double new_y; if (yLog) { new_y = pow(yLogBase, (y + 1 + img_Ly_pix - b_Y) / m_Y); } else { new_y = (y + 1 + img_Ly_pix - b_Y) / m_Y; } y_index = (int)((new_y - m_minY)*m_stepYr); if (y_index<0 || y_index>=m_numY) { okY = false; } double A = img_Lx_pix - b_X; double B = 1.0/m_X; for (int x = 0; x < iw; ++x) { bool okX = true; double new_x; if (xLog) { new_x = pow(xLogBase, (x + img_Lx_pix - b_X) / m_X); } else { new_x = (x + A)*B; } x_index = (int)((new_x - m_minX)*m_stepXr); double z = m->Z(x_index * m_numY + y_index); okX = finite(z); if (okX && okY) { scanLine[x] = _pal.rgb((int)(((z - _zLower) * palCountMin1_OverDZ))); } else { scanLine[x] = 0; } } } _imageLocation = QPoint(d2i(img_Lx_pix), d2i(img_Ly_pix + 1)); } #ifdef BENCHMARK b_1 = benchtmp.elapsed(); #endif //******************************************************************* // CONTOURS //******************************************************************* #ifndef CONTOUR_STEP #define CONTOUR_STEP 5 #endif //draw the contourmap if (image->hasContourMap()) { QColor tempColor = image->contourColor(); bool variableWeight = image->contourWeight() < 0; int lineWeight=1; if (!variableWeight) { // + 1 because 0 and 1 are the same width lineWeight = image->contourWeight() + 1; } // do the drawing for each contour line QList lines = image->contourLines(); QPoint lastPoint; // used to remember the previous point bool hasPrevBottom = false; MatrixPtr mp = _inputMatrices[THEMATRIX]; for (int k = 0; k < lines.count(); ++k) { double lineK = lines[k]; if (variableWeight) { // + 1 because 0 and 1 are the same width lineWeight = k + 1; } int flImgHx = d2i(floor(img_Hx_pix)); int flImgHy = d2i(floor(img_Hy_pix)); int ceImgLy = d2i(ceil(img_Ly_pix)); for (int i = d2i(ceil(img_Lx_pix)); i + CONTOUR_STEP < flImgHx; i += CONTOUR_STEP) { for (int j = d2i(ceil(img_Ly_pix)); j + CONTOUR_STEP < flImgHy; j += CONTOUR_STEP) { // look at this group of 4 pixels and get the z values double zTL, zTR, zBL, zBR; double new_x_small = (i - b_X) / m_X, new_y_small = (j + 1 - b_Y) / m_Y; double new_x_large = (i + CONTOUR_STEP - b_X) / m_X, new_y_large = (j+1+CONTOUR_STEP - b_Y) / m_Y; if (xLog) { new_x_small = pow(xLogBase, new_x_small); new_x_large = pow(xLogBase, new_x_large); } if (yLog) { new_y_small = pow(yLogBase, new_y_small); new_y_large = pow(yLogBase, new_y_large); } zTL = mp->value(new_x_small, new_y_small, 0L); zTR = mp->value(new_x_large, new_y_small, 0L); zBL = mp->value(new_x_small, new_y_large, 0L); zBR = mp->value(new_x_large, new_y_large, 0L); // determine the lines to draw int numPoints = 0; bool passTop = false, passBottom = false, passLeft = false, passRight = false; QPoint topPoint, bottomPoint, leftPoint, rightPoint; // passes through the top if (hasPrevBottom) { topPoint = lastPoint; ++numPoints; passTop = true; } else if (j == ceImgLy && ((lineK < zTR && lineK > zTL) || (lineK < zTL && lineK > zTR))) { ++numPoints; passTop = true; topPoint.setX(int(((lineK - zTL)*CONTOUR_STEP + (zTR - zTL)*i) / (zTR - zTL))); topPoint.setY(j); } hasPrevBottom = false; // passes through the bottom if ((lineK < zBR && lineK > zBL) || (lineK < zBL && lineK > zBR)) { ++numPoints; passBottom = true; bottomPoint.setX(int(((lineK - zBL)*CONTOUR_STEP + (zBR - zBL)*i) / (zBR - zBL))); bottomPoint.setY(j + CONTOUR_STEP); if (j + 2*CONTOUR_STEP < flImgHy) { lastPoint = bottomPoint; hasPrevBottom = true; } } // passes through the left if ((lineK < zBL && lineK > zTL) || (lineK < zTL && lineK > zBL)) { ++numPoints; passLeft = true; leftPoint.setY(int(((lineK - zTL)*CONTOUR_STEP + (zBL - zTL)*j) / (zBL - zTL))); leftPoint.setX(i); } // passes through the right if ((lineK < zBR && lineK > zTR) || (lineK < zTR && lineK > zBR)) { ++numPoints; passRight = true; rightPoint.setY(int(((lineK - zTR)*CONTOUR_STEP + (zBR - zTR)*j) / (zBR - zTR))); rightPoint.setX(i + CONTOUR_STEP); } if (numPoints == 4) { // draw a cross _lines.append(CoutourLineDetails(QLine(topPoint, bottomPoint), lineWeight)); _lines.append(CoutourLineDetails(QLine(rightPoint, leftPoint), lineWeight)); #ifdef BENCHMARK numberOfLinesDrawn += 2; #endif } else if (numPoints == 3) { // draw a V opening to non-intersecting side if (!passTop) { _lines.append(CoutourLineDetails(QLine(leftPoint, bottomPoint), lineWeight)); _lines.append(CoutourLineDetails(QLine(bottomPoint, rightPoint), lineWeight)); } else if (!passLeft) { _lines.append(CoutourLineDetails(QLine(topPoint, rightPoint), lineWeight)); _lines.append(CoutourLineDetails(QLine(rightPoint, bottomPoint), lineWeight)); } else if (!passBottom) { _lines.append(CoutourLineDetails(QLine(leftPoint, topPoint), lineWeight)); _lines.append(CoutourLineDetails(QLine(topPoint, rightPoint), lineWeight)); } else { _lines.append(CoutourLineDetails(QLine(topPoint, leftPoint), lineWeight)); _lines.append(CoutourLineDetails(QLine(leftPoint, bottomPoint), lineWeight)); } #ifdef BENCHMARK numberOfLinesDrawn += 2; #endif } else if (numPoints == 2) { // two points - connect them QPoint point1, point2; bool true1 = false; if (passTop) { point1 = topPoint; true1 = true; } if (passBottom) { if (true1) { point2 = bottomPoint; } else { point1 = bottomPoint; true1 = true; } } if (passLeft) { if (true1) { point2 = leftPoint; } else { point1 = leftPoint; } } if (passRight) { point2 = rightPoint; } _lines.append(CoutourLineDetails(QLine(point1, point2), lineWeight)); #ifdef BENCHMARK ++numberOfLinesDrawn; #endif } } } } } } } #ifdef BENCHMARK b_2 = benchtmp.elapsed(); int i = bench_time.elapsed(); qDebug() << endl << "Plotting image " << (void *)this << ": " << i << "ms"; qDebug() << " Without locks: " << b_2 << "ms"; qDebug() << " Number of lines drawn: " << numberOfLinesDrawn; if (b_1 > 0) qDebug() << " Color Map: " << b_1 << "ms"; if (b_2 - b_1 > 0) qDebug() << " Coutour Lines: " << (b_2 - b_1) << "ms" << endl; #endif } void Image::yRange(double xFrom, double xTo, double* yMin, double* yMax) { if (!yMin || !yMax) { return; } // if x range overlaps with image x range, just return image y range if ((xFrom <= MinX && xTo >= MinX) || (xTo >= MaxX && xFrom <= MaxX) || (xFrom > MinX && xFrom < MaxX) || (xTo > MinX && xTo < MaxX)) { *yMin = MinY; *yMax = MaxY; return; } *yMin = 0; *yMax = 0; return; } void Image::paintLegendSymbol(QPainter *p, const QRectF& bound) { if (hasColorMap() && (_pal.colorCount()>0)) { int l = bound.left(), r = bound.right(), t = bound.top(), b = bound.bottom(); // draw the color palette for (int i = l; i <= r; i++) { int index = (int)floor(static_cast(((i - l) * (_pal.colorCount() - 1))) / (r - l)); QColor sliceColor = _pal.color(index).rgb(); p->setPen(QPen(sliceColor, 1)); p->drawLine(i, t, i, b); } } if (hasContourMap()) { // draw a box with contour color p->setPen(QPen(_contourColor, 1)); p->drawRect(bound.left(), bound.top(), bound.width(), bound.height()); } } QString Image::_automaticDescriptiveName() const { return matrix()->descriptiveName(); } QString Image::descriptionTip() const { QString tip; tip = i18n("Image: %1\n" ).arg(Name()); if (_hasContourMap) { tip += " Contour Map"; } if (_hasColorMap) { tip += " Color Map"; } tip += matrix()->descriptionTip(); return tip; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/objectfactory.h000644 001750 001750 00000002776 11544160207 020645 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OBJECTFACTORY_H #define OBJECTFACTORY_H #include #include #include "dataobject.h" #include "kstmath_export.h" namespace Kst { class ObjectStore; class ObjectFactory { public: ObjectFactory(); virtual ~ObjectFactory(); // This takes ownership static void registerFactory(const QString& node, ObjectFactory *factory); static void registerFactory(const QStringList& nodes, ObjectFactory *factory); KSTMATH_EXPORT static DataObjectPtr parse(ObjectStore *store, QXmlStreamReader& stream); virtual DataObjectPtr generateObject(ObjectStore *store, QXmlStreamReader& stream) = 0; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/enodes.cpp000644 001750 001750 00000065361 11544160207 017616 0ustar00synthsynth000000 000000 /*************************************************************************** enodes.cpp ---------- begin : Feb 12 2004 copyright : (C) 2004 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #ifndef Q_WS_WIN32 #include #else #define strcasecmp _stricmp #endif #include "kst_i18n.h" #include #include #include "enodes.h" #include "datacollection.h" #include "debug.h" #include "math_kst.h" #include "objectstore.h" #include "doublecompare.h" KSTMATH_EXPORT int yyparse(Kst::ObjectStore *store); KSTMATH_EXPORT extern void *ParsedEquation; KSTMATH_EXPORT/*"C"*/ struct yy_buffer_state *yy_scan_string(const char*); KSTMATH_EXPORT struct yy_buffer_state *yy_scan_bytes(const char*, int); typedef struct yy_buffer_state *YY_BUFFER_STATE; KSTMATH_EXPORT void yy_delete_buffer(YY_BUFFER_STATE); using namespace Equations; using namespace Kst; static QMutex _mutex; QMutex& Equations::mutex() { return _mutex; } double Equations::interpret(ObjectStore *store, const char *txt, bool *ok, int len) { if (!txt || !*txt) { if (ok) { *ok = false; } return 0.0; } mutex().lock(); YY_BUFFER_STATE b; if (len > 0) { b = yy_scan_bytes(txt, len); } else { b = yy_scan_string(txt); } int rc = yyparse(store); yy_delete_buffer(b); if (rc == 0) { Equations::Node *eq = static_cast(ParsedEquation); ParsedEquation = 0L; mutex().unlock(); Equations::Context ctx; ctx.sampleCount = 2; ctx.noPoint = Kst::NOPOINT; ctx.x = 0.0; ctx.xVector = 0L; Equations::FoldVisitor vis(&ctx, &eq); double v = eq->value(&ctx); delete eq; if (ok) { *ok = true; } return v; } else { ParsedEquation = 0L; mutex().unlock(); if (ok) { *ok = false; } return 0.0; } } Node::Node() { _parentheses = false; } Node::~Node() { } bool Node::collectObjects(Kst::VectorMap&, Kst::ScalarMap&, Kst::StringMap&) { return true; } bool Node::takeVectors(const Kst::VectorMap&) { return true; } void Node::visit(NodeVisitor* v) { v->visitNode(this); } Kst::Object::UpdateType Node::update(Context *ctx) { Q_UNUSED(ctx) return Kst::Object::NoChange; } ///////////////////////////////////////////////////////////////// BinaryNode::BinaryNode(Node *left, Node *right) : Node(), _left(left), _right(right) { } BinaryNode::~BinaryNode() { delete _left; _left = 0L; delete _right; _right = 0L; } bool BinaryNode::collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t) { bool ok = true; ok = _left->collectObjects(v, s, t) ? ok : false; ok = _right->collectObjects(v, s, t) ? ok : false; return ok; } bool BinaryNode::takeVectors(const Kst::VectorMap& c) { bool rc = _left->takeVectors(c); rc = _right->takeVectors(c) && rc; return rc; } void BinaryNode::visit(NodeVisitor* v) { v->visitBinaryNode(this); } Node *& BinaryNode::left() { return _left; } Node *& BinaryNode::right() { return _right; } Kst::Object::UpdateType BinaryNode::update(Context *ctx) { Kst::Object::UpdateType l = _left->update(ctx); Kst::Object::UpdateType r = _right->update(ctx); return (l == Kst::Object::Updated || r == Kst::Object::Updated) ? Kst::Object::Updated : Kst::Object::NoChange; } ///////////////////////////////////////////////////////////////// Addition::Addition(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New Addition: %p + %p\n", (void*)this, (void*)left, (void*)right); } Addition::~Addition() { } double Addition::value(Context *ctx) { return _left->value(ctx) + _right->value(ctx); } bool Addition::isConst() { return _left->isConst() && _right->isConst(); } QString Addition::text() const { if (_parentheses) { return QString('(') + _left->text() + '+' + _right->text() + ')'; } else { return _left->text() + '+' + _right->text(); } } ///////////////////////////////////////////////////////////////// Subtraction::Subtraction(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New Subtraction: %p - %p\n", (void*)this, (void*)left, (void*)right); } Subtraction::~Subtraction() { } double Subtraction::value(Context *ctx) { return _left->value(ctx) - _right->value(ctx); } bool Subtraction::isConst() { return _left->isConst() && _right->isConst(); } QString Subtraction::text() const { if (_parentheses) { return QString('(') + _left->text() + '-' + _right->text() + ')'; } else { return _left->text() + '-' + _right->text(); } } ///////////////////////////////////////////////////////////////// Multiplication::Multiplication(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New Multiplication: %p - %p\n", (void*)this, (void*)left, (void*)right); } Multiplication::~Multiplication() { } double Multiplication::value(Context *ctx) { return _left->value(ctx) * _right->value(ctx); } bool Multiplication::isConst() { return _left->isConst() && _right->isConst(); } QString Multiplication::text() const { if (_parentheses) { return QString('(') + _left->text() + '*' + _right->text() + ')'; } else { return _left->text() + '*' + _right->text(); } } ///////////////////////////////////////////////////////////////// Division::Division(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New Division: %p - %p\n", (void*)this, (void*)left, (void*)right); } Division::~Division() { } double Division::value(Context *ctx) { return _left->value(ctx) / _right->value(ctx); } bool Division::isConst() { return _left->isConst() && _right->isConst(); } QString Division::text() const { if (_parentheses) { return QString('(') + _left->text() + '/' + _right->text() + ')'; } else { return _left->text() + '/' + _right->text(); } } ///////////////////////////////////////////////////////////////// Modulo::Modulo(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New Modulo: %p - %p\n", (void*)this, (void*)left, (void*)right); } Modulo::~Modulo() { } double Modulo::value(Context *ctx) { return fmod(_left->value(ctx), _right->value(ctx)); } bool Modulo::isConst() { return _left->isConst() && _right->isConst(); } QString Modulo::text() const { if (_parentheses) { return QString('(') + _left->text() + '%' + _right->text() + ')'; } else { return _left->text() + '%' + _right->text(); } } ///////////////////////////////////////////////////////////////// Power::Power(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New Power: %p - %p\n", (void*)this, (void*)left, (void*)right); } Power::~Power() { } double Power::value(Context *ctx) { return pow(_left->value(ctx), _right->value(ctx)); } bool Power::isConst() { return _left->isConst() && _right->isConst(); } QString Power::text() const { if (_parentheses) { return QString('(') + _left->text() + '^' + _right->text() + ')'; } else { return _left->text() + '^' + _right->text(); } } ///////////////////////////////////////////////////////////////// static double cot(double x) { return 1.0/tan(x); } static double csc(double x) { return 1.0/sin(x); } static double sec(double x) { return 1.0/cos(x); } static struct { const char *name; double (*func)(double); } FTable[] = { {"abs", &fabs}, {"acos", &acos}, {"asin", &asin}, {"atan", &atan}, #ifndef Q_WS_WIN32 {"cbrt", &cbrt}, #endif {"cos", &cos}, {"cosh", &cosh}, {"cot", &cot}, {"csc", &csc}, {"exp", &exp}, {"log", &log10}, {"ln", &log}, {"sec", &sec}, {"sin", &sin}, {"sinh", &sinh}, {"sqrt", &sqrt}, {"tan", &tan}, {"tanh", &tanh}, {0, 0} }; Function::Function(char *name, ArgumentList *args) : Node(), _name(name), _args(args), _f(0L) { _argCount = 1; // Presently no functions take != 1 argument _inPid = 0L; _inScalars = 0L; _inVectors = 0L; _outScalars = 0L; _outVectors = 0L; _inArrayLens = 0L; _outArrayLens = 0L; _outputIndex = -424242; _localData = 0L; _outputVectorCnt = 0; _inputVectorCnt = 0; //printf("%p: New Function: %s - %p\n", (void*)this, name, (void*)args); for (int i = 0; FTable[i].name; ++i) { if (strcasecmp(FTable[i].name, name) == 0) { _f = (void*)FTable[i].func; break; } } } Function::~Function() { free(_name); _name = 0L; delete _args; _args = 0L; _f = 0L; delete[] _inScalars; delete[] _inVectors; delete[] _outScalars; for (int i = 0; i < _outputVectorCnt; ++i) { free(_outVectors[i]); } delete[] _outVectors; delete[] _inArrayLens; delete[] _outArrayLens; } Kst::Object::UpdateType Function::update(Context *ctx) { _args->update(ctx); return Kst::Object::NoChange; } double Function::value(Context *ctx) { if (!_f) { return ctx->noPoint; } if (_argCount == 1) { double x = _args->at(0, ctx); return ((double (*)(double))_f)(x); } else if (_argCount > 1) { double *x = new double[_argCount]; for (int i = 0; i < _argCount; ++i) { x[i] = _args->at(i, ctx); } delete[] x; return ((double (*)(double*))_f)(x); } else { return ((double (*)())_f)(); } } bool Function::isConst() { return _args->isConst(); } bool Function::collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t) { return _args->collectObjects(v, s, t); } bool Function::takeVectors(const Kst::VectorMap& c) { return _args->takeVectors(c); } QString Function::text() const { return QString::fromLatin1(_name) + '(' + _args->text() + ')'; } ///////////////////////////////////////////////////////////////// ArgumentList::ArgumentList() : Node() { //printf("%p: New Argument List\n", (void*)this); } ArgumentList::~ArgumentList() { qDeleteAll(_args); } void ArgumentList::appendArgument(Node *arg) { _args.append(arg); } double ArgumentList::at(int arg, Context *ctx) { Node *n = _args.value(arg); // catches out-of-bounds if (n) { return n->value(ctx); } return ctx->noPoint; } bool ArgumentList::isConst() { foreach (Node *i, _args) { if (!i->isConst()) { return false; } } return true; } bool ArgumentList::collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t) { bool ok = true; foreach (Node *i, _args) { ok = i->collectObjects(v, s, t) ? ok : false; } return ok; } bool ArgumentList::takeVectors(const Kst::VectorMap& c) { bool rc = true; foreach (Node *i, _args) { rc = i->takeVectors(c) && rc; } return rc; } Node *ArgumentList::node(int idx) { return _args.at(idx); } Kst::Object::UpdateType ArgumentList::update(Context *ctx) { bool updated = false; foreach (Node *i, _args) { updated = updated || Kst::Object::Updated == i->update(ctx); } return updated ? Kst::Object::Updated : Kst::Object::NoChange; } QString ArgumentList::text() const { QString rc; bool first = true; QListIterator it(_args); while (it.hasNext()) { if (!first) { rc += ", "; } else { first = false; } rc += it.next()->text(); } return rc; } ///////////////////////////////////////////////////////////////// static struct { const char *name; double value; } ITable[] = { {"e", 2.7128182846}, {"pi", 3.1415926536}, {0, 0.0} }; Identifier::Identifier(char *name) : Node(), _name(name), _const(0L) { //printf("%p: New Identifier: %s\n", (void*)this, name); for (int i = 0; ITable[i].name; ++i) { if (strcasecmp(ITable[i].name, name) == 0) { _const = &ITable[i].value; break; } } } Identifier::~Identifier() { free(_name); _name = 0L; } const char *Identifier::name() const { return _name; } double Identifier::value(Context *ctx) { if (_const) { return *_const; } else if (_name[0] == 'x' && _name[1] == 0) { return ctx->x; } else { return ctx->noPoint; } } bool Identifier::isConst() { return _const != 0L || !(_name[0] == 'x' && _name[1] == 0); } QString Identifier::text() const { return _name; } ///////////////////////////////////////////////////////////////// DataNode::DataNode(ObjectStore *store, char *name) : Node(), _store(store), _isEquation(false), _equation(0L) { //printf("%p: New Data Object: [%s]\n", (void*)this, name); // ObjectStore *store = 0L; // FIXME: initialize this Q_ASSERT(store); if (name[0] == '=') { _tagName = QString(&name[1]).trimmed(); _isEquation = true; } else if (strchr(name, '[')) { _tagName = QString(name).trimmed(); QRegExp re("(.*)\\[(.*)\\]"); int hit = re.indexIn(_tagName); if (hit > -1 && re.numCaptures() == 2) { _vector = kst_cast(store->retrieveObject(re.cap(1))); if (_vector) { _vectorIndex = re.cap(2); } } } else { _tagName = QString(name).trimmed(); ObjectPtr o = store->retrieveObject(_tagName); if (kst_cast(o)) { _vector = kst_cast(o); } else if (kst_cast(o)) { _scalar = kst_cast(o); } } free(name); name = 0L; } DataNode::~DataNode() { delete _equation; _equation = 0L; } double DataNode::value(Context *ctx) { if (_isEquation) { if (!_equation) { mutex().lock(); YY_BUFFER_STATE b = yy_scan_bytes(_tagName.toLatin1(), _tagName.length()); int rc = yyparse(_store); yy_delete_buffer(b); if (rc == 0 && ParsedEquation) { _equation = static_cast(ParsedEquation); ParsedEquation = 0L; mutex().unlock(); Equations::Context ctx; ctx.sampleCount = 2; ctx.noPoint = Kst::NOPOINT; ctx.x = 0.0; ctx.xVector = 0L; Equations::FoldVisitor vis(&ctx, &_equation); } else { ParsedEquation = 0L; mutex().unlock(); _isEquation = false; return ctx->noPoint; } } return _equation->value(ctx); } else if (_vector) { if (!_equation && !_vectorIndex.isEmpty()) { mutex().lock(); YY_BUFFER_STATE b = yy_scan_bytes(_vectorIndex.toLatin1(), _vectorIndex.length()); int rc = yyparse(_store); yy_delete_buffer(b); if (rc == 0 && ParsedEquation) { _equation = static_cast(ParsedEquation); ParsedEquation = 0L; mutex().unlock(); Equations::Context ctx; ctx.sampleCount = 2; ctx.noPoint = Kst::NOPOINT; ctx.x = 0.0; ctx.xVector = 0L; Equations::FoldVisitor vis(&ctx, &_equation); } else { ParsedEquation = 0L; mutex().unlock(); _vectorIndex.clear(); _vector = 0L; return ctx->noPoint; } } if (_equation) { // Note: should we use a fresh context here? return _vector->value(int(_equation->value(ctx))); } return _vector->interpolate(ctx->i, ctx->sampleCount); } else if (_scalar) { return _scalar->value(); } else { return ctx->noPoint; } } bool DataNode::isConst() { return (_isEquation && _equation) ? _equation->isConst() : false; } bool DataNode::collectObjects(Kst::VectorMap& v, Kst::ScalarMap& s, Kst::StringMap& t) { if (_isEquation) { if (_equation) { _equation->collectObjects(v, s, t); } } else if (_vector && !v.contains(_tagName)) { v.insert(_tagName, _vector); } else if (_scalar && !s.contains(_tagName)) { s.insert(_tagName, _scalar); } else if (!_scalar && !_vector) { Kst::Debug::self()->log(i18n("Equations has unknown object [%1].").arg(_tagName), Kst::Debug::Error); return false; } return true; } bool DataNode::takeVectors(const Kst::VectorMap& c) { if (_isEquation) { if (_equation) { return _equation->takeVectors(c); } return false; } if (!_scalar) { if (c.contains(_tagName)) { _vector = c[_tagName]; } else { return false; } } return true; } Kst::Object::UpdateType DataNode::update(Context *ctx) { Q_UNUSED(ctx) if (_isEquation) { if (_equation) { //return _equation->update(ctx); } } else if (_vector) { KstWriteLocker l(_vector); //return _vector->update(); } else if (_scalar) { KstWriteLocker l(_scalar); //return _scalar->registerChange(); } //return Kst::Object::NoChange; return Kst::Object::Updated; } // Hack alert: [ and ] in names confuse the parser, so strip them out. QString DataNode::text() const { if (_isEquation) { return QString("[=") + _tagName + ']'; } else if (_vector) { QString Name = _vector->Name(); Name.remove("\\[").remove("\\]"); return QString('[') + Name.remove('[').remove(']') + QString(']'); } else if (_scalar) { QString Name = _scalar->Name(); Name.remove("\\[").remove("\\]"); return QString('[') + Name.remove('[').remove(']') + QString(']'); } else { return QString(); } } ///////////////////////////////////////////////////////////////// Number::Number(double n) : Node(), _n(n) { //printf("%p: New Number: %lf\n", (void*)this, n); } Number::~Number() { } double Number::value(Context*) { return _n; } bool Number::isConst() { return true; } QString Number::text() const { if (_parentheses) { return QString('(') + QString::number(_n, 'g', 15) + ')'; } else { return QString::number(_n, 'g', 15); } } ///////////////////////////////////////////////////////////////// Negation::Negation(Node *node) : Node(), _n(node) { //printf("%p: New Negation: %p\n", (void*)this, (void*)n); } Negation::~Negation() { delete _n; _n = 0L; } double Negation::value(Context *ctx) { double v = _n->value(ctx); return (v == v) ? -v : v; } bool Negation::isConst() { return _n->isConst(); } QString Negation::text() const { if (_parentheses) { return QString("(-") + _n->text() + ')'; } else { return QString('-') + _n->text(); } } ///////////////////////////////////////////////////////////////// LogicalNot::LogicalNot(Node *node) : Node(), _n(node) { //printf("%p: New LogicalNot: %p\n", (void*)this, (void*)n); } LogicalNot::~LogicalNot() { delete _n; _n = 0L; } double LogicalNot::value(Context *ctx) { double v = _n->value(ctx); return (v == v) ? (v == 0.0) : 1.0; } bool LogicalNot::isConst() { return _n->isConst(); } QString LogicalNot::text() const { if (_parentheses) { return QString("(!") + _n->text() + ')'; } else { return QString('!') + _n->text(); } } ///////////////////////////////////////////////////////////////// BitwiseAnd::BitwiseAnd(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New And: %p & %p\n", (void*)this, (void*)left, (void*)right); } BitwiseAnd::~BitwiseAnd() { } double BitwiseAnd::value(Context *ctx) { return long(_left->value(ctx)) & long(_right->value(ctx)); } bool BitwiseAnd::isConst() { return _left->isConst() && _right->isConst(); } QString BitwiseAnd::text() const { if (_parentheses) { return QString('(') + _left->text() + QString('&') + _right->text() + ')'; } else { return _left->text() + QString('&') + _right->text(); } } ///////////////////////////////////////////////////////////////// BitwiseOr::BitwiseOr(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New Or: %p | %p\n", (void*)this, (void*)left, (void*)right); } BitwiseOr::~BitwiseOr() { } double BitwiseOr::value(Context *ctx) { return long(_left->value(ctx)) | long(_right->value(ctx)); } bool BitwiseOr::isConst() { return _left->isConst() && _right->isConst(); } QString BitwiseOr::text() const { if (_parentheses) { return QString('(') + _left->text() + QString('|') + _right->text() + ')'; } else { return _left->text() + QString('|') + _right->text(); } } ///////////////////////////////////////////////////////////////// LogicalAnd::LogicalAnd(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New And: %p && %p\n", (void*)this, (void*)left, (void*)right); } LogicalAnd::~LogicalAnd() { } double LogicalAnd::value(Context *ctx) { return (_left->value(ctx) && _right->value(ctx)) ? EQ_TRUE : EQ_FALSE; } bool LogicalAnd::isConst() { return _left->isConst() && _right->isConst(); } QString LogicalAnd::text() const { if (_parentheses) { return QString('(') + _left->text() + QString("&&") + _right->text() + ')'; } else { return _left->text() + QString("&&") + _right->text(); } } ///////////////////////////////////////////////////////////////// LogicalOr::LogicalOr(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New Or: %p || %p\n", (void*)this, (void*)left, (void*)right); } LogicalOr::~LogicalOr() { } double LogicalOr::value(Context *ctx) { return (_left->value(ctx) || _right->value(ctx)) ? EQ_TRUE : EQ_FALSE; } bool LogicalOr::isConst() { return _left->isConst() && _right->isConst(); } QString LogicalOr::text() const { if (_parentheses) { return QString('(') + _left->text() + QString("||") + _right->text() + ')'; } else { return _left->text() + QString("||") + _right->text(); } } ///////////////////////////////////////////////////////////////// LessThan::LessThan(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New LessThan: %p < %p\n", (void*)this, (void*)left, (void*)right); } LessThan::~LessThan() { } double LessThan::value(Context *ctx) { return doubleLessThan(_left->value(ctx), _right->value(ctx)) ? EQ_TRUE : EQ_FALSE; } bool LessThan::isConst() { return _left->isConst() && _right->isConst(); } QString LessThan::text() const { if (_parentheses) { return QString('(') + _left->text() + QString('<') + _right->text() + ')'; } else { return _left->text() + QString('<') + _right->text(); } } ///////////////////////////////////////////////////////////////// LessThanEqual::LessThanEqual(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New LessThanEqual: %p <= %p\n", (void*)this, (void*)left, (void*)right); } LessThanEqual::~LessThanEqual() { } double LessThanEqual::value(Context *ctx) { return doubleLessThanEqual(_left->value(ctx), _right->value(ctx)) ? EQ_TRUE : EQ_FALSE; } bool LessThanEqual::isConst() { return _left->isConst() && _right->isConst(); } QString LessThanEqual::text() const { if (_parentheses) { return QString('(') + _left->text() + QString("<=") + _right->text() + ')'; } else { return _left->text() + QString("<=") + _right->text(); } } ///////////////////////////////////////////////////////////////// GreaterThan::GreaterThan(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New GreaterThan: %p > %p\n", (void*)this, (void*)left, (void*)right); } GreaterThan::~GreaterThan() { } double GreaterThan::value(Context *ctx) { return doubleGreaterThan(_left->value(ctx), _right->value(ctx)) ? EQ_TRUE : EQ_FALSE; } bool GreaterThan::isConst() { return _left->isConst() && _right->isConst(); } QString GreaterThan::text() const { if (_parentheses) { return QString('(') + _left->text() + QString('>') + _right->text() + ')'; } else { return _left->text() + QString('>') + _right->text(); } } ///////////////////////////////////////////////////////////////// GreaterThanEqual::GreaterThanEqual(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New GreaterThanEqual: %p >= %p\n", (void*)this, (void*)left, (void*)right); } GreaterThanEqual::~GreaterThanEqual() { } double GreaterThanEqual::value(Context *ctx) { return doubleGreaterThanEqual(_left->value(ctx), _right->value(ctx)) ? EQ_TRUE : EQ_FALSE; } bool GreaterThanEqual::isConst() { return _left->isConst() && _right->isConst(); } QString GreaterThanEqual::text() const { if (_parentheses) { return QString('(') + _left->text() + QString(">=") + _right->text() + ')'; } else { return _left->text() + QString(">=") + _right->text(); } } ///////////////////////////////////////////////////////////////// EqualTo::EqualTo(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New EqualTo: %p == %p\n", (void*)this, (void*)left, (void*)right); } EqualTo::~EqualTo() { } double EqualTo::value(Context *ctx) { return doubleEqual(_left->value(ctx), _right->value(ctx)) ? EQ_TRUE : EQ_FALSE; } bool EqualTo::isConst() { return _left->isConst() && _right->isConst(); } QString EqualTo::text() const { if (_parentheses) { return QString('(') + _left->text() + QString("==") + _right->text() + ')'; } else { return _left->text() + QString("==") + _right->text(); } } ///////////////////////////////////////////////////////////////// NotEqualTo::NotEqualTo(Node *left, Node *right) : BinaryNode(left, right) { //printf("%p: New NotEqualTo: %p != %p\n", (void*)this, (void*)left, (void*)right); } NotEqualTo::~NotEqualTo() { } double NotEqualTo::value(Context *ctx) { return (!doubleEqual(_left->value(ctx), _right->value(ctx))) ? EQ_TRUE : EQ_FALSE; } bool NotEqualTo::isConst() { return _left->isConst() && _right->isConst(); } QString NotEqualTo::text() const { if (_parentheses) { return QString('(') + _left->text() + QString("!=") + _right->text() + ')'; } else { return _left->text() + QString("!=") + _right->text(); } } ///////////////////////////////////////////////////////////////// NodeVisitor::NodeVisitor() { } NodeVisitor::~NodeVisitor() { } ///////////////////////////////////////////////////////////////// FoldVisitor::FoldVisitor(Context* ctxIn, Node** rootNode) : NodeVisitor(), _ctx(ctxIn) { if ((*rootNode)->isConst() && dynamic_cast(*rootNode) == 0L) { double v = (*rootNode)->value(ctxIn); delete *rootNode; *rootNode = new Number(v); } else { (*rootNode)->visit(this); } _ctx = 0L; // avoids context being marked as 'still reachable' } FoldVisitor::~FoldVisitor() { } void FoldVisitor::visitNode(Node*) { // useful? } void FoldVisitor::visitBinaryNode(BinaryNode *n) { if (n->left()->isConst() && dynamic_cast(n->left()) == 0L) { double v = n->left()->value(_ctx); delete n->left(); n->left() = new Number(v); } else { n->left()->visit(this); } if (n->right()->isConst() && dynamic_cast(n->right()) == 0L) { double v = n->right()->value(_ctx); delete n->right(); n->right() = new Number(v); } else { n->right()->visit(this); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/escan.l000644 001750 001750 00000004272 11544160207 017075 0ustar00synthsynth000000 000000 %option noyywrap %x DATA %{ #include #include #include #include "eparse.h" #include "eparse-eh.h" int bracketCount = 0; char dataSpec[1024]; char *dataSpecPtr; //void yyerror(Kst::ObjectStore *store, const char *s); #define YY_DECL int yylex(Kst::ObjectStore *store) %} Number (0|[1-9][0-9]*)([\.][0-9]+)?([eE][\+\-][0-9]+)? Id [A-Za-z]+ %% {Number} { yylval.number = atof(yytext); /*printf("Found a number %.15f\n", yylval.number);*/ return T_NUMBER; } {Id} { yylval.data = strdup(yytext); /*printf("Found an ID [%s]\n", yylval.data);*/ return T_IDENTIFIER; } . { switch (*yytext) { case '[': ++bracketCount; *dataSpecPtr = *yytext; ++dataSpecPtr; break; case ']': if (--bracketCount == 0) { *dataSpecPtr = 0; yylval.data = strdup(dataSpec); if (dataSpecPtr == dataSpec) { yyerror(store, "Empty data reference."); yy_flush_buffer(YY_CURRENT_BUFFER); BEGIN(INITIAL); return T_INVALID; } BEGIN(INITIAL); return T_DATA; } *dataSpecPtr = *yytext; ++dataSpecPtr; break; default: *dataSpecPtr = *yytext; ++dataSpecPtr; break; } } <> { yyerror(store, "Invalid data reference."); yy_flush_buffer(YY_CURRENT_BUFFER); BEGIN(INITIAL); return T_INVALID; } "[" { bracketCount = 1; dataSpecPtr = dataSpec; *dataSpecPtr = 0; BEGIN(DATA); } "]" { yyerror(store, "Unmatched ']'."); yy_flush_buffer(YY_CURRENT_BUFFER); return T_INVALID; } "!" return T_NOT; "&" return T_AND; "|" return T_OR; "&&" return T_LAND; "||" return T_LOR; "<" return T_LT; "<=" return T_LE; ">" return T_GT; ">=" return T_GE; "=" return T_EQ; "==" return T_EQ; "!=" return T_NE; "+" return T_ADD; "-" return T_SUBTRACT; "*" return T_MULTIPLY; "/" return T_DIVIDE; "%" return T_MOD; "^" return T_EXP; "(" return T_OPENPAR; ")" return T_CLOSEPAR; "," return T_COMMA; [ \t] {} . { /*printf("Found char '%c'\n", yytext[0]);*/ yylval.character = yytext[0]; return T_INVALID; } <> { /*printf("yyterminate\n");*/ yyterminate(); } %% kst-2.0.3/src/libkstmath/imagefactory.cpp000644 001750 001750 00000007762 11544160207 021014 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "imagefactory.h" #include "debug.h" #include "image.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { ImageFactory::ImageFactory() : RelationFactory() { registerFactory(Image::staticTypeTag, this); } ImageFactory::~ImageFactory() { } RelationPtr ImageFactory::generateRelation(ObjectStore *store, QXmlStreamReader& xml) { Q_ASSERT(store); double lowerThreshold=0, upperThreshold=1; int numberOfContourLines=4, contourWeight=0; QString matrixName, paletteName, legend, contourColor, descriptiveName; bool hasColorMap=true, hasContourMap=false, autoThreshold=true; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == Image::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); matrixName = attrs.value("matrix").toString(); legend = attrs.value("legend").toString(); paletteName = attrs.value("palettename").toString(); hasColorMap = attrs.value("hascolormap").toString() == "true" ? true : false; lowerThreshold = attrs.value("lowerthreshold").toString().toDouble(); upperThreshold = attrs.value("upperthreshold").toString().toDouble(); hasContourMap = attrs.value("hascontourmap").toString() == "true" ? true : false; numberOfContourLines = attrs.value("numcontourlines").toString().toInt(); contourWeight = attrs.value("contourweight").toString().toInt(); contourColor = attrs.value("contourcolor").toString(); autoThreshold = attrs.value("autothreshold").toString() == "true" ? true : false; if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == Image::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating Image from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } MatrixPtr matrix = 0; if (store && !matrixName.isEmpty()) { matrix = kst_cast(store->retrieveObject(matrixName)); } if (!matrix) { Debug::self()->log(QObject::tr("Error creating Image from Kst file. Could not find matrix."), Debug::Warning); return 0; } ImagePtr image = store->createObject(); if (hasColorMap && hasContourMap) { image->changeToColorAndContour(matrix, lowerThreshold, upperThreshold, autoThreshold, paletteName, numberOfContourLines, QColor(contourColor), contourWeight); } else if (hasContourMap) { image->changeToContourOnly(matrix, numberOfContourLines, QColor(contourColor), contourWeight); } else { image->changeToColorOnly(matrix, lowerThreshold, upperThreshold, autoThreshold, paletteName); } image->setDescriptiveName(descriptiveName); image->writeLock(); image->registerChange(); image->unlock(); return image; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/libkstmath.pro000644 001750 001750 00000004504 11544160207 020511 0ustar00synthsynth000000 000000 TOPOUT_REL=../.. include($$PWD/$$TOPOUT_REL/kst.pri) TEMPLATE = lib CONFIG += dll DEFINES += BUILD_KSTMATH TARGET = $$kstlib(kst2math) DESTDIR = $$OUTPUT_DIR/lib !isEmpty(INSTALL_PREFIX) { target.path = $$INSTALL_PREFIX/$$INSTALL_LIBDIR INSTALLS += target } INCLUDEPATH += \ tmp \ $$TOPLEVELDIR/src/libkst \ $$OUTPUT_DIR/src/libkstmath/tmp macx { CONFIG += lib_bundle LIBS += -F$$OUTPUT_DIR/lib qtAddLibrary(kst2lib) } else { LIBS += \ -L$$OUTPUT_DIR/lib \ -l$$kstlib(kst2lib) } #Don't trigger qmake's lex/yacc handling by default. #Rather we want to use the files that are pre-generated and checked in. QMAKE_EXT_LEX = .lex QMAKE_EXT_YACC = .yacc SOURCES += \ basicplugin.cpp \ basicpluginfactory.cpp \ builtinobjects.cpp \ builtinrelations.cpp \ colorsequence.cpp \ csd.cpp \ csdfactory.cpp \ curve.cpp \ curvefactory.cpp \ curvehint.cpp \ curvepointsymbol.cpp \ dataobject.cpp \ dialoglauncher.cpp \ emailthread.cpp \ eparse.cpp \ eparse-eh.cpp \ enodes.cpp \ enodefactory.cpp \ escan.cpp \ equation.cpp \ equationfactory.cpp \ eventmonitorentry.cpp \ eventmonitorfactory.cpp \ fftsg_h.c \ histogram.cpp \ histogramfactory.cpp \ image.cpp \ imagefactory.cpp \ labelparser.cpp \ linestyle.cpp \ objectfactory.cpp \ painter.cpp \ palette.cpp \ psd.cpp \ psdcalculator.cpp \ psdfactory.cpp \ relation.cpp \ relationfactory.cpp \ settings.cpp HEADERS += \ basicplugin.h \ basicpluginfactory.h \ builtinobjects.h \ builtinrelations.h \ builtinpalettes.h \ colorsequence.h \ csd.h \ csdfactory.h \ curve.h \ curvefactory.h \ curvehint.h \ curvepointsymbol.h \ dialoglauncher.h \ enodefactory.h \ enodes.h \ eparse-eh.h \ eparse.h \ dataobject.h \ dataobjectplugin.h \ emailthread.h \ equation.h \ equationfactory.h \ eventmonitorentry.h \ eventmonitorfactory.h \ histogram.h \ histogramfactory.h \ image.h \ imagefactory.h \ labelparser.h \ linestyle.h \ objectfactory.h \ painter.h \ palette.h \ plotdefines.h \ psd.h \ psdcalculator.h \ relation.h \ relationfactory.h \ settings.h #LEXSOURCES += escan.l #YACCSOURCES += eparse.y kst-2.0.3/src/libkstmath/histogram.cpp000644 001750 001750 00000023676 11544160207 020341 0ustar00synthsynth000000 000000 /*************************************************************************** histogram.cpp: Histogram for KST ------------------- begin : July 2002 copyright : (C) 2002 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include "kst_i18n.h" #include "dialoglauncher.h" #include "datacollection.h" #include "histogram.h" #include "objectstore.h" namespace Kst { const QString Histogram::staticTypeString = I18N_NOOP("Histogram"); const QString Histogram::staticTypeTag = I18N_NOOP("histogram"); static const QLatin1String& RAWVECTOR = QLatin1String("I"); static const QLatin1String& BINS = QLatin1String("B"); static const QLatin1String& HIST = QLatin1String("H"); Histogram::Histogram(ObjectStore *store) : DataObject(store) { setRealTimeAutoBin(false); _typeString = staticTypeString; _type = "Histogram"; _initializeShortName(); // _Bins, _bVector and _hVector need to be valid, // so initialize them as size 2 (where 2 is a small valid number) _Bins = new unsigned long[2]; _NumberOfBins = 0; VectorPtr v = store->createObject(); v->setProvider(this); v->setSlaveName("bin"); v->resize(2); _bVector = _outputVectors.insert(BINS, v).value(); v = store->createObject(); v->setProvider(this); v->setSlaveName("num"); v->resize(2); _hVector = _outputVectors.insert(HIST, v).value(); } void Histogram::_initializeShortName() { _shortName = 'H'+QString::number(_hnum); if (_hnum>max_hnum) max_hnum = _hnum; _hnum++; } void Histogram::change(VectorPtr in_V, double xmin_in, double xmax_in, int in_n_bins, NormalizationType in_norm_mode, bool realTimeAutoBin) { _NormalizationMode = in_norm_mode; _realTimeAutoBin = realTimeAutoBin; _NumberOfBins = 0; _inputVectors[RAWVECTOR] = in_V; if (xmax_in>xmin_in) { _MaxX = xmax_in; _MinX = xmin_in; } else { _MinX = xmax_in; _MaxX = xmin_in; } if (_MaxX == _MinX) { _MaxX += 1.0; _MinX -= 1.0; } _NumberOfBins = in_n_bins; if (_NumberOfBins < 2) { _NumberOfBins = 2; } delete[] _Bins; _Bins = new unsigned long[_NumberOfBins]; _NS = 3 * _NumberOfBins + 1; _bVector->resize(_NumberOfBins); _hVector->resize(_NumberOfBins); } Histogram::~Histogram() { _bVector = 0L; _hVector = 0L; delete[] _Bins; _Bins = 0L; } void Histogram::internalUpdate() { writeLockInputsAndOutputs(); int i_bin, i_pt, ns; double y = 0.0; double MaxY = 0.0; // do auto-binning if necessary if (_realTimeAutoBin) { int temp_NumberOfBins; double temp_xMin, temp_xMax; Histogram::AutoBin(_inputVectors[RAWVECTOR], &temp_NumberOfBins, &temp_xMax, &temp_xMin); internalSetNumberOfBins(temp_NumberOfBins); internalSetXRange(temp_xMin, temp_xMax); } _NS = 3 * _NumberOfBins + 1; _W = (_MaxX - _MinX)/double(_NumberOfBins); memset(_Bins, 0, _NumberOfBins*sizeof(*_Bins)); ns = _inputVectors[RAWVECTOR]->length(); for (i_pt = 0; i_pt < ns ; i_pt++) { y = _inputVectors[RAWVECTOR]->interpolate(i_pt, ns); i_bin = (int)floor((y-_MinX)/_W); if (i_bin >= 0 && i_bin < _NumberOfBins) { _Bins[i_bin]++; } else { // the top boundry of the top bin is included in the top bin. // for all other bins, the top boundry is included in the next bin if (y == _MaxX) { _Bins[_NumberOfBins-1]++; } } } for (i_bin=0; i_bin<_NumberOfBins; i_bin++) { y = _Bins[i_bin]; if (y > MaxY) { MaxY = y; } } LabelInfo label_info; switch (_NormalizationMode) { case Number: _Normalization = 1.0; label_info.quantity = i18n("Number"); break; case Percent: if (ns > 0) { _Normalization = 100.0/(double)ns; } else { _Normalization = 1.0; } label_info.quantity = i18n("Percent"); break; case Fraction: if (ns > 0) { _Normalization = 1.0/(double)ns; } else { _Normalization = 1.0; } label_info.quantity = i18n("Fraction"); break; case MaximumOne: if (MaxY > 0) { _Normalization = 1.0/MaxY; } else { _Normalization = 1.0; } label_info.quantity = i18n("Normalized Frequency"); break; default: _Normalization = 1.0; label_info.quantity = i18n("Number"); break; } label_info.name = QString(); label_info.units = QString(); _hVector->setLabelInfo(label_info); _bVector->setLabelInfo(_inputVectors[RAWVECTOR]->labelInfo()); label_info.quantity.clear(); label_info.units.clear(); label_info.name = i18n( "Histogram of %1").arg(_bVector->labelInfo().name); _hVector->setTitleInfo(label_info); double *bins = _bVector->value(); double *hist = _hVector->value(); for ( i_bin = 0; i_bin<_NumberOfBins; i_bin++ ) { bins[i_bin] = ( double( i_bin ) + 0.5 )*_W + _MinX; hist[i_bin] = _Bins[i_bin]*_Normalization; } unlockInputsAndOutputs(); } int Histogram::numberOfBins() const { return _NumberOfBins; } void Histogram::setXRange(double xmin_in, double xmax_in) { internalSetXRange(xmin_in, xmax_in); } void Histogram::internalSetXRange(double xmin_in, double xmax_in) { if (xmax_in > xmin_in) { _MaxX = xmax_in; _MinX = xmin_in; } else if (xmax_in < xmin_in) { _MinX = xmax_in; _MaxX = xmin_in; } else { _MinX = xmax_in - 1.0; _MaxX = xmax_in + 1.0; } _W = (_MaxX - _MinX)/double(_NumberOfBins); } void Histogram::internalSetNumberOfBins(int in_n_bins) { if (in_n_bins < 2) { in_n_bins = 2; } if (_NumberOfBins != in_n_bins) { _NumberOfBins = in_n_bins; delete[] _Bins; _Bins = new unsigned long[_NumberOfBins]; memset(_Bins, 0, _NumberOfBins*sizeof(*_Bins)); _bVector->resize(_NumberOfBins); _hVector->resize(_NumberOfBins); } _W = (_MaxX - _MinX)/double(_NumberOfBins); _NS = 3 * _NumberOfBins + 1; } void Histogram::setNumberOfBins(int in_n_bins) { _realTimeAutoBin = false; internalSetNumberOfBins(in_n_bins); } void Histogram::setVector(VectorPtr new_v) { if (new_v) { _inputVectors[RAWVECTOR] = new_v; } } VectorPtr Histogram::vector() const { return _inputVectors[RAWVECTOR]; } void Histogram::save(QXmlStreamWriter &xml) { xml.writeStartElement(staticTypeTag); xml.writeAttribute("vector", _inputVectors[RAWVECTOR]->Name()); xml.writeAttribute("numberofbins", QString::number(_NumberOfBins)); xml.writeAttribute("realtimeautobin", QVariant(_realTimeAutoBin).toString()); xml.writeAttribute("min", QString::number(_MinX)); xml.writeAttribute("max", QString::number(_MaxX)); xml.writeAttribute("normalizationmode", QString::number(_NormalizationMode)); saveNameInfo(xml, VNUM|HNUM|XNUM); xml.writeEndElement(); } QString Histogram::propertyString() const { return i18n("Histogram: %1").arg(_inputVectors[RAWVECTOR]->Name()); } void Histogram::showNewDialog() { DialogLauncher::self()->showHistogramDialog(); } void Histogram::showEditDialog() { DialogLauncher::self()->showHistogramDialog(this); } void Histogram::AutoBin(VectorPtr V, int *n, double *max, double *min) { double m; *max = V->max(); *min = V->min(); *n = V->length(); if (*max < *min) { m = *max; *max = *min; *min = m; } if (*max == *min) { *max += 1.0; *min -= 1.0; } // we can do a better job auto-ranging using the tick rules from plot... // this has not been done yet, you will notice... *n /= 50; if (*n < 6) { *n = 6; } if (*n > 60) { *n = 60; } m = (*max - *min)/(100.0*double(*n)); *max += m; *min -= m; } bool Histogram::slaveVectorsUsed() const { return true; } void Histogram::setRealTimeAutoBin(bool autoBin) { _realTimeAutoBin = autoBin; } bool Histogram::realTimeAutoBin() const { return _realTimeAutoBin; } double Histogram::vMax() const { return _inputVectors[RAWVECTOR]->max(); } double Histogram::vMin() const { return _inputVectors[RAWVECTOR]->min(); } int Histogram::vNumSamples() const { return _inputVectors[RAWVECTOR]->length(); } DataObjectPtr Histogram::makeDuplicate() const { HistogramPtr histogram = store()->createObject(); histogram->setVector(_inputVectors[RAWVECTOR]); histogram->setXRange(_MinX, _MaxX); histogram->setNumberOfBins(_NumberOfBins); histogram->setNormalizationType(_NormalizationMode); histogram->setRealTimeAutoBin(_realTimeAutoBin); if (descriptiveNameIsManual()) { histogram->setDescriptiveName(descriptiveName()); } histogram->writeLock(); histogram->registerChange(); histogram->unlock(); return DataObjectPtr(histogram); } QString Histogram::_automaticDescriptiveName() const { return (_inputVectors[RAWVECTOR]->descriptiveName()); } QString Histogram::descriptionTip() const { QString tip; tip = i18n("Histogram: %1").arg(Name()); if (realTimeAutoBin()) { tip+= i18n("\n Auto-bin"); } else { tip += i18n("\n %1 bins from %2 to %3").arg(numberOfBins()).arg(xMin()).arg(xMax()); } tip += i18n("\nInput: %1").arg(_inputVectors[RAWVECTOR]->descriptionTip()); return tip; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/psdfactory.h000644 001750 001750 00000002166 11544160207 020156 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PSDFACTORY_H #define PSDFACTORY_H #include "objectfactory.h" namespace Kst { class PSDFactory : public ObjectFactory { public: PSDFactory(); ~PSDFactory(); DataObjectPtr generateObject(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/painter.h000644 001750 001750 00000003743 11544160207 017444 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2005 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PAINTER_H #define PAINTER_H #include #include "kstmath_export.h" namespace Kst { class KSTMATH_EXPORT Painter : public QPainter { public: // KstPaintType - hints to paint to allow optimizations // P_PAINT: Neither 'data' nor 'plot' needs to change // P_PLOT: data didn't change // P_UPDATE: at least one curve was updated /* FIXME: Define P_PLOT better, and do we even need P_ZOOM, P_PLOT and P_PAINT? They should all do the same thing. */ enum PaintType { P_PAINT = 0, P_PLOT, P_ZOOM, P_UPDATE, P_PRINT, P_EXPORT }; Painter(PaintType t = P_PAINT); virtual ~Painter(); // Defalut: P_PAINT void setType(PaintType t); PaintType type() const; // True if UI elements such as focus rect should be drawn. default: false bool drawInlineUI() const; void setDrawInlineUI(bool draw); inline QRegion& uiMask() { return _uiMask; } bool makingMask() const; void setMakingMask(bool making); int lineWidthAdjustmentFactor() const; private: PaintType _type; bool _drawInlineUI; bool _makingMask; QRegion _uiMask; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/colorsequence.h000644 001750 001750 00000003435 11544160207 020647 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2003 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef _COLORSEQUENCE_H #define _COLORSEQUENCE_H #include "kstmath_export.h" #include "nextcolor.h" #include "curve.h" class KPalette; namespace Kst { class KSTMATH_EXPORT ColorSequence : public NextColor { public: enum ColorMode { MonoChrome, GrayScale, Color }; void createPalette(); QColor next(); QColor current(); QColor next(const QColor& badColor); QColor next(const CurveList& Curves, const QColor& badColor); bool colorsTooClose(const QColor& color, const QColor& badColor); ColorMode colorMode(); void setColorMode(ColorMode mode); int count(); void reset(); QColor entry(int ptr); static ColorSequence& self(); private: ColorSequence(); ~ColorSequence(); static ColorSequence* _self; static void cleanup(); QHash _pal; int _count; int _ptr; // pointer to the next color ColorMode _mode; QString _palette; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/fftsg_h.c000644 001750 001750 00000257545 11544160207 017430 0ustar00synthsynth000000 000000 /* Copyright(C) 1996-2001 Takuya OOURA email: ooura@mmm.t.u-tokyo.ac.jp download: http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html You may use, copy, modify this code for any purpose and without fee. */ /* Fast Fourier/Cosine/Sine Transform dimension :one data length :power of 2 decimation :frequency radix :split-radix data :inplace table :not use functions cdft: Complex Discrete Fourier Transform rdft: Real Discrete Fourier Transform ddct: Discrete Cosine Transform ddst: Discrete Sine Transform dfct: Cosine Transform of RDFT (Real Symmetric DFT) dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) function prototypes void cdft(int, int, double *); void rdft(int, int, double *); void ddct(int, int, double *); void ddst(int, int, double *); void dfct(int, double *); void dfst(int, double *); macro definitions USE_CDFT_PTHREADS : default=not defined CDFT_THREADS_BEGIN_N : must be >= 512, default=8192 CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536 USE_CDFT_WINTHREADS : default=not defined CDFT_THREADS_BEGIN_N : must be >= 512, default=32768 CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288 -------- Complex DFT (Discrete Fourier Transform) -------- [definition] X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k cdft(2*n, 1, a); cdft(2*n, -1, a); [parameters] 2*n :data length (int) n >= 1, n = power of 2 a[0...2*n-1] :input/output data (double *) input data a[2*j] = Re(x[j]), a[2*j+1] = Im(x[j]), 0<=j RDFT R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0 IRDFT (excluding scale) a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k rdft(n, 1, a); rdft(n, -1, a); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[2*k] = R[k], 0<=k input data a[2*j] = R[j], 0<=j IDCT (excluding scale) C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k DCT C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k ddct(n, 1, a); ddct(n, -1, a); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[k] = C[k], 0<=k IDST (excluding scale) S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k DST S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0 ddst(n, 1, a); ddst(n, -1, a); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) input data a[j] = A[j], 0 output data a[k] = S[k], 0= 2, n = power of 2 a[0...n] :input/output data (double *) output data a[k] = C[k], 0<=k<=n [remark] Inverse of a[0] *= 0.5; a[n] *= 0.5; dfct(n, a); is a[0] *= 0.5; a[n] *= 0.5; dfct(n, a); for (j = 0; j <= n; j++) { a[j] *= 2.0 / n; } . -------- Sine Transform of RDFT (Real Anti-symmetric DFT) -------- [definition] S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[k] = S[k], 0= 0) { cftfsub(n, a); } else { cftbsub(n, a); } } void rdft(int n, int isgn, double *a) { double xi; if (isgn >= 0) { if (n > 4) { cftfsub(n, a); rftfsub(n, a); } else if (n == 4) { cftfsub(n, a); } xi = a[0] - a[1]; a[0] += a[1]; a[1] = xi; } else { a[1] = 0.5 * (a[0] - a[1]); a[0] -= a[1]; if (n > 4) { rftbsub(n, a); cftbsub(n, a); } else if (n == 4) { cftbsub(n, a); } } } static void ddct(int n, int isgn, double *a) { int j; double xr; if (isgn < 0) { xr = a[n - 1]; for (j = n - 2; j >= 2; j -= 2) { a[j + 1] = a[j] - a[j - 1]; a[j] += a[j - 1]; } a[1] = a[0] - xr; a[0] += xr; if (n > 4) { rftbsub(n, a); cftbsub(n, a); } else if (n == 4) { cftbsub(n, a); } } if (n > 4) { dctsub(n, a); } else { dctsub4(n, a); } if (isgn >= 0) { if (n > 4) { cftfsub(n, a); rftfsub(n, a); } else if (n == 4) { cftfsub(n, a); } xr = a[0] - a[1]; a[0] += a[1]; for (j = 2; j < n; j += 2) { a[j - 1] = a[j] - a[j + 1]; a[j] += a[j + 1]; } a[n - 1] = xr; } } static void ddst(int n, int isgn, double *a) { int j; double xr; if (isgn < 0) { xr = a[n - 1]; for (j = n - 2; j >= 2; j -= 2) { a[j + 1] = -a[j] - a[j - 1]; a[j] -= a[j - 1]; } a[1] = a[0] + xr; a[0] -= xr; if (n > 4) { rftbsub(n, a); cftbsub(n, a); } else if (n == 4) { cftbsub(n, a); } } if (n > 4) { dstsub(n, a); } else { dstsub4(n, a); } if (isgn >= 0) { if (n > 4) { cftfsub(n, a); rftfsub(n, a); } else if (n == 4) { cftfsub(n, a); } xr = a[0] - a[1]; a[0] += a[1]; for (j = 2; j < n; j += 2) { a[j - 1] = -a[j] - a[j + 1]; a[j] -= a[j + 1]; } a[n - 1] = -xr; } } void dfct(int n, double *a) { int j, k, m, mh; double xr, xi, yr, yi, an; m = n >> 1; for (j = 0; j < m; j++) { k = n - j; xr = a[j] + a[k]; a[j] -= a[k]; a[k] = xr; } an = a[n]; while (m >= 2) { ddct(m, 1, a); if (m > 2) { bitrv1(m, a); } mh = m >> 1; xi = a[m]; a[m] = a[0]; a[0] = an - xi; an += xi; for (j = 1; j < mh; j++) { k = m - j; xr = a[m + k]; xi = a[m + j]; yr = a[j]; yi = a[k]; a[m + j] = yr; a[m + k] = yi; a[j] = xr - xi; a[k] = xr + xi; } xr = a[mh]; a[mh] = a[m + mh]; a[m + mh] = xr; m = mh; } xi = a[1]; a[1] = a[0]; a[0] = an + xi; a[n] = an - xi; if (n > 2) { bitrv1(n, a); } } void dfst(int n, double *a) { int j, k, m, mh; double xr, xi, yr, yi; m = n >> 1; for (j = 1; j < m; j++) { k = n - j; xr = a[j] - a[k]; a[j] += a[k]; a[k] = xr; } a[0] = a[m]; while (m >= 2) { ddst(m, 1, a); if (m > 2) { bitrv1(m, a); } mh = m >> 1; for (j = 1; j < mh; j++) { k = m - j; xr = a[m + k]; xi = a[m + j]; yr = a[j]; yi = a[k]; a[m + j] = yr; a[m + k] = yi; a[j] = xr + xi; a[k] = xr - xi; } a[m] = a[0]; a[0] = a[m + mh]; a[m + mh] = a[mh]; m = mh; } a[1] = a[0]; a[0] = 0; if (n > 2) { bitrv1(n, a); } } /* -------- child routines -------- */ #include #ifndef M_PI_2 #define M_PI_2 1.570796326794896619231321691639751442098584699687 #endif #ifndef WR5000 /* cos(M_PI_2*0.5000) */ #define WR5000 0.707106781186547524400844362104849039284835937688 #endif #ifndef WR2500 /* cos(M_PI_2*0.2500) */ #define WR2500 0.923879532511286756128183189396788286822416625863 #endif #ifndef WI2500 /* sin(M_PI_2*0.2500) */ #define WI2500 0.382683432365089771728459984030398866761344562485 #endif #ifndef WR1250 /* cos(M_PI_2*0.1250) */ #define WR1250 0.980785280403230449126182236134239036973933730893 #endif #ifndef WI1250 /* sin(M_PI_2*0.1250) */ #define WI1250 0.195090322016128267848284868477022240927691617751 #endif #ifndef WR3750 /* cos(M_PI_2*0.3750) */ #define WR3750 0.831469612302545237078788377617905756738560811987 #endif #ifndef WI3750 /* sin(M_PI_2*0.3750) */ #define WI3750 0.555570233019602224742830813948532874374937190754 #endif #ifdef USE_CDFT_PTHREADS #define USE_CDFT_THREADS #ifndef CDFT_THREADS_BEGIN_N #define CDFT_THREADS_BEGIN_N 8192 #endif #ifndef CDFT_4THREADS_BEGIN_N #define CDFT_4THREADS_BEGIN_N 65536 #endif #include #include #include #define cdft_thread_t pthread_t #define cdft_thread_create(thp,func,argp) { \ if (pthread_create(thp, NULL, func, (void *) argp) != 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #define cdft_thread_wait(th) { \ if (pthread_join(th, NULL) != 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #endif /* USE_CDFT_PTHREADS */ #ifdef USE_CDFT_WINTHREADS #define USE_CDFT_THREADS #ifndef CDFT_THREADS_BEGIN_N #define CDFT_THREADS_BEGIN_N 32768 #endif #ifndef CDFT_4THREADS_BEGIN_N #define CDFT_4THREADS_BEGIN_N 524288 #endif #include #include #include #define cdft_thread_t HANDLE #define cdft_thread_create(thp,func,argp) { \ DWORD thid; \ *(thp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, (LPVOID) argp, 0, &thid); \ if (*(thp) == 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #define cdft_thread_wait(th) { \ WaitForSingleObject(th, INFINITE); \ CloseHandle(th); \ } #endif /* USE_CDFT_WINTHREADS */ #ifndef CDFT_LOOP_DIV /* control of the CDFT's speed & tolerance */ #define CDFT_LOOP_DIV 32 #endif #ifndef RDFT_LOOP_DIV /* control of the RDFT's speed & tolerance */ #define RDFT_LOOP_DIV 64 #endif #ifndef DCST_LOOP_DIV /* control of the DCT,DST's speed & tolerance */ #define DCST_LOOP_DIV 64 #endif static void cftfsub(int n, double *a) { if (n > 8) { if (n > 32) { cftmdl1(n, a); #ifdef USE_CDFT_THREADS if (n > CDFT_THREADS_BEGIN_N) { cftrec4_th(n, a); } else #endif /* USE_CDFT_THREADS */ if (n > 512) { cftrec4(n, a); } else if (n > 128) { cftleaf(n, 1, a); } else { cftfx41(n, a); } bitrv2(n, a); } else if (n == 32) { cftf161(a); bitrv216(a); } else { cftf081(a); bitrv208(a); } } else if (n == 8) { cftf040(a); } else if (n == 4) { cftx020(a); } } static void cftbsub(int n, double *a) { if (n > 8) { if (n > 32) { cftb1st(n, a); #ifdef USE_CDFT_THREADS if (n > CDFT_THREADS_BEGIN_N) { cftrec4_th(n, a); } else #endif /* USE_CDFT_THREADS */ if (n > 512) { cftrec4(n, a); } else if (n > 128) { cftleaf(n, 1, a); } else { cftfx41(n, a); } bitrv2conj(n, a); } else if (n == 32) { cftf161(a); bitrv216neg(a); } else { cftf081(a); bitrv208neg(a); } } else if (n == 8) { cftb040(a); } else if (n == 4) { cftx020(a); } } void bitrv2(int n, double *a) { int _j0, k0, _j1, k1, l, m, i, j, k, nh; double xr, xi, yr, yi; m = 4; for (l = n >> 2; l > 8; l >>= 2) { m <<= 1; } nh = n >> 1; if (l == 8) { _j0 = 0; for (k0 = 0; k0 < m; k0 += 4) { k = k0; for (j = _j0; j < _j0 + k0; j += 4) { xr = a[j]; xi = a[j + 1]; yr = a[k]; yi = a[k + 1]; a[j] = yr; a[j + 1] = yi; a[k] = xr; a[k + 1] = xi; _j1 = j + m; k1 = k + 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh; k1 += 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 += m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += 2; k1 += nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh; k1 -= 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 += m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 2; k1 += nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= 2; k1 -= nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh + 2; k1 += nh + 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh - m; k1 += 2 * m - 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); } } else { _j0 = 0; for (k0 = 0; k0 < m; k0 += 4) { k = k0; for (j = _j0; j < _j0 + k0; j += 4) { xr = a[j]; xi = a[j + 1]; yr = a[k]; yi = a[k + 1]; a[j] = yr; a[j + 1] = yi; a[k] = xr; a[k + 1] = xi; _j1 = j + m; k1 = k + m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh; k1 += 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += 2; k1 += nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh; k1 -= 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 2; k1 += nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); } } } void bitrv2conj(int n, double *a) { int _j0, k0, _j1, k1, l, m, i, j, k, nh; double xr, xi, yr, yi; m = 4; for (l = n >> 2; l > 8; l >>= 2) { m <<= 1; } nh = n >> 1; if (l == 8) { _j0 = 0; for (k0 = 0; k0 < m; k0 += 4) { k = k0; for (j = _j0; j < _j0 + k0; j += 4) { xr = a[j]; xi = -a[j + 1]; yr = a[k]; yi = -a[k + 1]; a[j] = yr; a[j + 1] = yi; a[k] = xr; a[k + 1] = xi; _j1 = j + m; k1 = k + 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh; k1 += 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 += m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += 2; k1 += nh; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh; k1 -= 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 += m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 2; k1 += nh; a[_j1 - 1] = -a[_j1 - 1]; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= 2; k1 -= nh; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh + 2; k1 += nh + 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh - m; k1 += 2 * m - 2; a[_j1 - 1] = -a[_j1 - 1]; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); } } else { _j0 = 0; for (k0 = 0; k0 < m; k0 += 4) { k = k0; for (j = _j0; j < _j0 + k0; j += 4) { xr = a[j]; xi = -a[j + 1]; yr = a[k]; yi = -a[k + 1]; a[j] = yr; a[j + 1] = yi; a[k] = xr; a[k + 1] = xi; _j1 = j + m; k1 = k + m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh; k1 += 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += 2; k1 += nh; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh; k1 -= 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 2; k1 += nh; a[_j1 - 1] = -a[_j1 - 1]; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; _j1 += m; k1 += m; a[_j1 - 1] = -a[_j1 - 1]; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); } } } void bitrv216(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x7r = a[14]; x7i = a[15]; x8r = a[16]; x8i = a[17]; x10r = a[20]; x10i = a[21]; x11r = a[22]; x11i = a[23]; x12r = a[24]; x12i = a[25]; x13r = a[26]; x13i = a[27]; x14r = a[28]; x14i = a[29]; a[2] = x8r; a[3] = x8i; a[4] = x4r; a[5] = x4i; a[6] = x12r; a[7] = x12i; a[8] = x2r; a[9] = x2i; a[10] = x10r; a[11] = x10i; a[14] = x14r; a[15] = x14i; a[16] = x1r; a[17] = x1i; a[20] = x5r; a[21] = x5i; a[22] = x13r; a[23] = x13i; a[24] = x3r; a[25] = x3i; a[26] = x11r; a[27] = x11i; a[28] = x7r; a[29] = x7i; } void bitrv216neg(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x6r = a[12]; x6i = a[13]; x7r = a[14]; x7i = a[15]; x8r = a[16]; x8i = a[17]; x9r = a[18]; x9i = a[19]; x10r = a[20]; x10i = a[21]; x11r = a[22]; x11i = a[23]; x12r = a[24]; x12i = a[25]; x13r = a[26]; x13i = a[27]; x14r = a[28]; x14i = a[29]; x15r = a[30]; x15i = a[31]; a[2] = x15r; a[3] = x15i; a[4] = x7r; a[5] = x7i; a[6] = x11r; a[7] = x11i; a[8] = x3r; a[9] = x3i; a[10] = x13r; a[11] = x13i; a[12] = x5r; a[13] = x5i; a[14] = x9r; a[15] = x9i; a[16] = x1r; a[17] = x1i; a[18] = x14r; a[19] = x14i; a[20] = x6r; a[21] = x6i; a[22] = x10r; a[23] = x10i; a[24] = x2r; a[25] = x2i; a[26] = x12r; a[27] = x12i; a[28] = x4r; a[29] = x4i; a[30] = x8r; a[31] = x8i; } void bitrv208(double *a) { double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i; x1r = a[2]; x1i = a[3]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x6r = a[12]; x6i = a[13]; a[2] = x4r; a[3] = x4i; a[6] = x6r; a[7] = x6i; a[8] = x1r; a[9] = x1i; a[12] = x3r; a[13] = x3i; } void bitrv208neg(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x6r = a[12]; x6i = a[13]; x7r = a[14]; x7i = a[15]; a[2] = x7r; a[3] = x7i; a[4] = x3r; a[5] = x3i; a[6] = x5r; a[7] = x5i; a[8] = x1r; a[9] = x1i; a[10] = x6r; a[11] = x6i; a[12] = x2r; a[13] = x2i; a[14] = x4r; a[15] = x4i; } void bitrv1(int n, double *a) { int _j0, k0, _j1, k1, l, m, i, j, k, nh; double x; nh = n >> 1; x = a[1]; a[1] = a[nh]; a[nh] = x; m = 2; for (l = n >> 2; l > 2; l >>= 2) { m <<= 1; } if (l == 2) { _j1 = m + 1; k1 = m + nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j0 = 0; for (k0 = 2; k0 < m; k0 += 2) { for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); k = k0; for (j = _j0; j < _j0 + k0; j += 2) { x = a[j]; a[j] = a[k]; a[k] = x; _j1 = j + m; k1 = k + m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 += nh; k1++; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 -= m; k1 -= m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1++; k1 += nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 += m; k1 += m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 -= nh; k1--; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 -= m; k1 -= m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 1; k1 += nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 += m; k1 += m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; } } else { _j0 = 0; for (k0 = 2; k0 < m; k0 += 2) { for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); k = k0; for (j = _j0; j < _j0 + k0; j += 2) { x = a[j]; a[j] = a[k]; a[k] = x; _j1 = j + nh; k1 = k + 1; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1++; k1 += nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 -= nh; k1--; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 1; k1 += nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; } } } void cftb1st(int n, double *a) { int i, i0, j, _j0, _j1, j2, j3, m, mh; double ew, w1r, w1i, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i, ss1, ss3; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; mh = n >> 3; m = 2 * mh; _j1 = m; j2 = _j1 + m; j3 = j2 + m; x0r = a[0] + a[j2]; x0i = -a[1] - a[j2 + 1]; x1r = a[0] - a[j2]; x1i = -a[1] + a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[0] = x0r + x2r; a[1] = x0i - x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i + x2i; a[j2] = x1r + x3i; a[j2 + 1] = x1i + x3r; a[j3] = x1r - x3i; a[j3 + 1] = x1i - x3r; wd1r = 1; wd1i = 0; wd3r = 1; wd3i = 0; ew = M_PI_2 / m; w1r = cos(2 * ew); w1i = sin(2 * ew); wk1r = w1r; wk1i = w1i; ss1 = 2 * w1i; wk3i = 2 * ss1 * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; ss3 = 2 * wk3i; i = 0; for (;;) { i0 = i + 4 * CDFT_LOOP_DIV; if (i0 > mh - 4) { i0 = mh - 4; } for (j = i + 2; j < i0; j += 4) { wd1r -= ss1 * wk1i; wd1i += ss1 * wk1r; wd3r -= ss3 * wk3i; wd3i += ss3 * wk3r; _j1 = j + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[j] + a[j2]; x0i = -a[j + 1] - a[j2 + 1]; x1r = a[j] - a[j2]; x1i = -a[j + 1] + a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i - x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wk1r * x0r - wk1i * x0i; a[j2 + 1] = wk1r * x0i + wk1i * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r + wk3i * x0i; a[j3 + 1] = wk3r * x0i - wk3i * x0r; x0r = a[j + 2] + a[j2 + 2]; x0i = -a[j + 3] - a[j2 + 3]; x1r = a[j + 2] - a[j2 + 2]; x1i = -a[j + 3] + a[j2 + 3]; x2r = a[_j1 + 2] + a[j3 + 2]; x2i = a[_j1 + 3] + a[j3 + 3]; x3r = a[_j1 + 2] - a[j3 + 2]; x3i = a[_j1 + 3] - a[j3 + 3]; a[j + 2] = x0r + x2r; a[j + 3] = x0i - x2i; a[_j1 + 2] = x0r - x2r; a[_j1 + 3] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 + 2] = wd1r * x0r - wd1i * x0i; a[j2 + 3] = wd1r * x0i + wd1i * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 + 2] = wd3r * x0r + wd3i * x0i; a[j3 + 3] = wd3r * x0i - wd3i * x0r; _j0 = m - j; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0] + a[j2]; x0i = -a[_j0 + 1] - a[j2 + 1]; x1r = a[_j0] - a[j2]; x1i = -a[_j0 + 1] + a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[_j0] = x0r + x2r; a[_j0 + 1] = x0i - x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wk1i * x0r - wk1r * x0i; a[j2 + 1] = wk1i * x0i + wk1r * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = wk3i * x0r + wk3r * x0i; a[j3 + 1] = wk3i * x0i - wk3r * x0r; x0r = a[_j0 - 2] + a[j2 - 2]; x0i = -a[_j0 - 1] - a[j2 - 1]; x1r = a[_j0 - 2] - a[j2 - 2]; x1i = -a[_j0 - 1] + a[j2 - 1]; x2r = a[_j1 - 2] + a[j3 - 2]; x2i = a[_j1 - 1] + a[j3 - 1]; x3r = a[_j1 - 2] - a[j3 - 2]; x3i = a[_j1 - 1] - a[j3 - 1]; a[_j0 - 2] = x0r + x2r; a[_j0 - 1] = x0i - x2i; a[_j1 - 2] = x0r - x2r; a[_j1 - 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 - 2] = wd1i * x0r - wd1r * x0i; a[j2 - 1] = wd1i * x0i + wd1r * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 - 2] = wd3i * x0r + wd3r * x0i; a[j3 - 1] = wd3i * x0i - wd3r * x0r; wk1r -= ss1 * wd1i; wk1i += ss1 * wd1r; wk3r -= ss3 * wd3i; wk3i += ss3 * wd3r; } if (i0 == mh - 4) { break; } wd1r = cos(ew * i0); wd1i = sin(ew * i0); wd3i = 4 * wd1i * wd1r; wd3r = wd1r - wd3i * wd1i; wd3i = wd1i - wd3i * wd1r; wk1r = w1r * wd1r - w1i * wd1i; wk1i = w1r * wd1i + w1i * wd1r; wk3i = 4 * wk1i * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; i = i0; } wd1r = WR5000; _j0 = mh; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0 - 2] + a[j2 - 2]; x0i = -a[_j0 - 1] - a[j2 - 1]; x1r = a[_j0 - 2] - a[j2 - 2]; x1i = -a[_j0 - 1] + a[j2 - 1]; x2r = a[_j1 - 2] + a[j3 - 2]; x2i = a[_j1 - 1] + a[j3 - 1]; x3r = a[_j1 - 2] - a[j3 - 2]; x3i = a[_j1 - 1] - a[j3 - 1]; a[_j0 - 2] = x0r + x2r; a[_j0 - 1] = x0i - x2i; a[_j1 - 2] = x0r - x2r; a[_j1 - 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 - 2] = wk1r * x0r - wk1i * x0i; a[j2 - 1] = wk1r * x0i + wk1i * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 - 2] = wk3r * x0r + wk3i * x0i; a[j3 - 1] = wk3r * x0i - wk3i * x0r; x0r = a[_j0] + a[j2]; x0i = -a[_j0 + 1] - a[j2 + 1]; x1r = a[_j0] - a[j2]; x1i = -a[_j0 + 1] + a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[_j0] = x0r + x2r; a[_j0 + 1] = x0i - x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wd1r * (x0r - x0i); a[j2 + 1] = wd1r * (x0i + x0r); x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = -wd1r * (x0r + x0i); a[j3 + 1] = -wd1r * (x0i - x0r); x0r = a[_j0 + 2] + a[j2 + 2]; x0i = -a[_j0 + 3] - a[j2 + 3]; x1r = a[_j0 + 2] - a[j2 + 2]; x1i = -a[_j0 + 3] + a[j2 + 3]; x2r = a[_j1 + 2] + a[j3 + 2]; x2i = a[_j1 + 3] + a[j3 + 3]; x3r = a[_j1 + 2] - a[j3 + 2]; x3i = a[_j1 + 3] - a[j3 + 3]; a[_j0 + 2] = x0r + x2r; a[_j0 + 3] = x0i - x2i; a[_j1 + 2] = x0r - x2r; a[_j1 + 3] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 + 2] = wk1i * x0r - wk1r * x0i; a[j2 + 3] = wk1i * x0i + wk1r * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 + 2] = wk3i * x0r + wk3r * x0i; a[j3 + 3] = wk3i * x0i - wk3r * x0r; } #ifdef USE_CDFT_THREADS struct cdft_arg_st { int n0; int n; double *a; }; typedef struct cdft_arg_st cdft_arg_t; void cftrec4_th(int n, double *a) { void *cftrec1_th(void *p); void *cftrec2_th(void *p); int i, idiv4, m, nthread; cdft_thread_t th[4]; cdft_arg_t ag[4]; nthread = 2; idiv4 = 0; m = n >> 1; if (n > CDFT_4THREADS_BEGIN_N) { nthread = 4; idiv4 = 1; m >>= 1; } for (i = 0; i < nthread; i++) { ag[i].n0 = n; ag[i].n = m; ag[i].a = &a[i * m]; if (i != idiv4) { cdft_thread_create(&th[i], cftrec1_th, &ag[i]); } else { cdft_thread_create(&th[i], cftrec2_th, &ag[i]); } } for (i = 0; i < nthread; i++) { cdft_thread_wait(th[i]); } } void *cftrec1_th(void *p) { int cfttree(int n, int j, int k, double *a); void cftleaf(int n, int isplt, double *a); void cftmdl1(int n, double *a); int isplt, j, k, m, n, n0; double *a; n0 = ((cdft_arg_t *) p)->n0; n = ((cdft_arg_t *) p)->n; a = ((cdft_arg_t *) p)->a; m = n0; while (m > 512) { m >>= 2; cftmdl1(m, &a[n - m]); } cftleaf(m, 1, &a[n - m]); k = 0; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a); cftleaf(m, isplt, &a[j - m]); } return (void *) 0; } void *cftrec2_th(void *p) { int cfttree(int n, int j, int k, double *a); void cftleaf(int n, int isplt, double *a); void cftmdl2(int n, double *a); int isplt, j, k, m, n, n0; double *a; n0 = ((cdft_arg_t *) p)->n0; n = ((cdft_arg_t *) p)->n; a = ((cdft_arg_t *) p)->a; k = 1; m = n0; while (m > 512) { m >>= 2; k <<= 2; cftmdl2(m, &a[n - m]); } cftleaf(m, 0, &a[n - m]); k >>= 1; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a); cftleaf(m, isplt, &a[j - m]); } return (void *) 0; } #endif /* USE_CDFT_THREADS */ void cftrec4(int n, double *a) { int isplt, j, k, m; m = n; while (m > 512) { m >>= 2; cftmdl1(m, &a[n - m]); } cftleaf(m, 1, &a[n - m]); k = 0; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a); cftleaf(m, isplt, &a[j - m]); } } int cfttree(int n, int j, int k, double *a) { int i, isplt, m; if ((k & 3) != 0) { isplt = k & 1; if (isplt != 0) { cftmdl1(n, &a[j - n]); } else { cftmdl2(n, &a[j - n]); } } else { m = n; for (i = k; (i & 3) == 0; i >>= 2) { m <<= 2; } isplt = i & 1; if (isplt != 0) { while (m > 128) { cftmdl1(m, &a[j - m]); m >>= 2; } } else { while (m > 128) { cftmdl2(m, &a[j - m]); m >>= 2; } } } return isplt; } void cftleaf(int n, int isplt, double *a) { if (n == 512) { cftmdl1(128, a); cftf161(a); cftf162(&a[32]); cftf161(&a[64]); cftf161(&a[96]); cftmdl2(128, &a[128]); cftf161(&a[128]); cftf162(&a[160]); cftf161(&a[192]); cftf162(&a[224]); cftmdl1(128, &a[256]); cftf161(&a[256]); cftf162(&a[288]); cftf161(&a[320]); cftf161(&a[352]); if (isplt != 0) { cftmdl1(128, &a[384]); cftf161(&a[480]); } else { cftmdl2(128, &a[384]); cftf162(&a[480]); } cftf161(&a[384]); cftf162(&a[416]); cftf161(&a[448]); } else { cftmdl1(64, a); cftf081(a); cftf082(&a[16]); cftf081(&a[32]); cftf081(&a[48]); cftmdl2(64, &a[64]); cftf081(&a[64]); cftf082(&a[80]); cftf081(&a[96]); cftf082(&a[112]); cftmdl1(64, &a[128]); cftf081(&a[128]); cftf082(&a[144]); cftf081(&a[160]); cftf081(&a[176]); if (isplt != 0) { cftmdl1(64, &a[192]); cftf081(&a[240]); } else { cftmdl2(64, &a[192]); cftf082(&a[240]); } cftf081(&a[192]); cftf082(&a[208]); cftf081(&a[224]); } } void cftmdl1(int n, double *a) { int i, i0, j, _j0, _j1, j2, j3, m, mh; double ew, w1r, w1i, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i, ss1, ss3; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; mh = n >> 3; m = 2 * mh; _j1 = m; j2 = _j1 + m; j3 = j2 + m; x0r = a[0] + a[j2]; x0i = a[1] + a[j2 + 1]; x1r = a[0] - a[j2]; x1i = a[1] - a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i - x2i; a[j2] = x1r - x3i; a[j2 + 1] = x1i + x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i - x3r; wd1r = 1; wd1i = 0; wd3r = 1; wd3i = 0; ew = M_PI_2 / m; w1r = cos(2 * ew); w1i = sin(2 * ew); wk1r = w1r; wk1i = w1i; ss1 = 2 * w1i; wk3i = 2 * ss1 * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; ss3 = 2 * wk3i; i = 0; for (;;) { i0 = i + 4 * CDFT_LOOP_DIV; if (i0 > mh - 4) { i0 = mh - 4; } for (j = i + 2; j < i0; j += 4) { wd1r -= ss1 * wk1i; wd1i += ss1 * wk1r; wd3r -= ss3 * wk3i; wd3i += ss3 * wk3r; _j1 = j + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[j] + a[j2]; x0i = a[j + 1] + a[j2 + 1]; x1r = a[j] - a[j2]; x1i = a[j + 1] - a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wk1r * x0r - wk1i * x0i; a[j2 + 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r + wk3i * x0i; a[j3 + 1] = wk3r * x0i - wk3i * x0r; x0r = a[j + 2] + a[j2 + 2]; x0i = a[j + 3] + a[j2 + 3]; x1r = a[j + 2] - a[j2 + 2]; x1i = a[j + 3] - a[j2 + 3]; x2r = a[_j1 + 2] + a[j3 + 2]; x2i = a[_j1 + 3] + a[j3 + 3]; x3r = a[_j1 + 2] - a[j3 + 2]; x3i = a[_j1 + 3] - a[j3 + 3]; a[j + 2] = x0r + x2r; a[j + 3] = x0i + x2i; a[_j1 + 2] = x0r - x2r; a[_j1 + 3] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 + 2] = wd1r * x0r - wd1i * x0i; a[j2 + 3] = wd1r * x0i + wd1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 + 2] = wd3r * x0r + wd3i * x0i; a[j3 + 3] = wd3r * x0i - wd3i * x0r; _j0 = m - j; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0] + a[j2]; x0i = a[_j0 + 1] + a[j2 + 1]; x1r = a[_j0] - a[j2]; x1i = a[_j0 + 1] - a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[_j0] = x0r + x2r; a[_j0 + 1] = x0i + x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wk1i * x0r - wk1r * x0i; a[j2 + 1] = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3i * x0r + wk3r * x0i; a[j3 + 1] = wk3i * x0i - wk3r * x0r; x0r = a[_j0 - 2] + a[j2 - 2]; x0i = a[_j0 - 1] + a[j2 - 1]; x1r = a[_j0 - 2] - a[j2 - 2]; x1i = a[_j0 - 1] - a[j2 - 1]; x2r = a[_j1 - 2] + a[j3 - 2]; x2i = a[_j1 - 1] + a[j3 - 1]; x3r = a[_j1 - 2] - a[j3 - 2]; x3i = a[_j1 - 1] - a[j3 - 1]; a[_j0 - 2] = x0r + x2r; a[_j0 - 1] = x0i + x2i; a[_j1 - 2] = x0r - x2r; a[_j1 - 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 - 2] = wd1i * x0r - wd1r * x0i; a[j2 - 1] = wd1i * x0i + wd1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 - 2] = wd3i * x0r + wd3r * x0i; a[j3 - 1] = wd3i * x0i - wd3r * x0r; wk1r -= ss1 * wd1i; wk1i += ss1 * wd1r; wk3r -= ss3 * wd3i; wk3i += ss3 * wd3r; } if (i0 == mh - 4) { break; } wd1r = cos(ew * i0); wd1i = sin(ew * i0); wd3i = 4 * wd1i * wd1r; wd3r = wd1r - wd3i * wd1i; wd3i = wd1i - wd3i * wd1r; wk1r = w1r * wd1r - w1i * wd1i; wk1i = w1r * wd1i + w1i * wd1r; wk3i = 4 * wk1i * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; i = i0; } wd1r = WR5000; _j0 = mh; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0 - 2] + a[j2 - 2]; x0i = a[_j0 - 1] + a[j2 - 1]; x1r = a[_j0 - 2] - a[j2 - 2]; x1i = a[_j0 - 1] - a[j2 - 1]; x2r = a[_j1 - 2] + a[j3 - 2]; x2i = a[_j1 - 1] + a[j3 - 1]; x3r = a[_j1 - 2] - a[j3 - 2]; x3i = a[_j1 - 1] - a[j3 - 1]; a[_j0 - 2] = x0r + x2r; a[_j0 - 1] = x0i + x2i; a[_j1 - 2] = x0r - x2r; a[_j1 - 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 - 2] = wk1r * x0r - wk1i * x0i; a[j2 - 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 - 2] = wk3r * x0r + wk3i * x0i; a[j3 - 1] = wk3r * x0i - wk3i * x0r; x0r = a[_j0] + a[j2]; x0i = a[_j0 + 1] + a[j2 + 1]; x1r = a[_j0] - a[j2]; x1i = a[_j0 + 1] - a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[_j0] = x0r + x2r; a[_j0 + 1] = x0i + x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wd1r * (x0r - x0i); a[j2 + 1] = wd1r * (x0i + x0r); x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = -wd1r * (x0r + x0i); a[j3 + 1] = -wd1r * (x0i - x0r); x0r = a[_j0 + 2] + a[j2 + 2]; x0i = a[_j0 + 3] + a[j2 + 3]; x1r = a[_j0 + 2] - a[j2 + 2]; x1i = a[_j0 + 3] - a[j2 + 3]; x2r = a[_j1 + 2] + a[j3 + 2]; x2i = a[_j1 + 3] + a[j3 + 3]; x3r = a[_j1 + 2] - a[j3 + 2]; x3i = a[_j1 + 3] - a[j3 + 3]; a[_j0 + 2] = x0r + x2r; a[_j0 + 3] = x0i + x2i; a[_j1 + 2] = x0r - x2r; a[_j1 + 3] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 + 2] = wk1i * x0r - wk1r * x0i; a[j2 + 3] = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 + 2] = wk3i * x0r + wk3r * x0i; a[j3 + 3] = wk3i * x0i - wk3r * x0r; } void cftmdl2(int n, double *a) { int i, i0, j, _j0, _j1, j2, j3, m, mh; double ew, w1r, w1i, wn4r, wk1r, wk1i, wk3r, wk3i, wl1r, wl1i, wl3r, wl3i, wd1r, wd1i, wd3r, wd3i, we1r, we1i, we3r, we3i, ss1, ss3; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i; mh = n >> 3; m = 2 * mh; wn4r = WR5000; _j1 = m; j2 = _j1 + m; j3 = j2 + m; x0r = a[0] - a[j2 + 1]; x0i = a[1] + a[j2]; x1r = a[0] + a[j2 + 1]; x1i = a[1] - a[j2]; x2r = a[_j1] - a[j3 + 1]; x2i = a[_j1 + 1] + a[j3]; x3r = a[_j1] + a[j3 + 1]; x3i = a[_j1 + 1] - a[j3]; y0r = wn4r * (x2r - x2i); y0i = wn4r * (x2i + x2r); a[0] = x0r + y0r; a[1] = x0i + y0i; a[_j1] = x0r - y0r; a[_j1 + 1] = x0i - y0i; y0r = wn4r * (x3r - x3i); y0i = wn4r * (x3i + x3r); a[j2] = x1r - y0i; a[j2 + 1] = x1i + y0r; a[j3] = x1r + y0i; a[j3 + 1] = x1i - y0r; wl1r = 1; wl1i = 0; wl3r = 1; wl3i = 0; we1r = wn4r; we1i = wn4r; we3r = -wn4r; we3i = -wn4r; ew = M_PI_2 / (2 * m); w1r = cos(2 * ew); w1i = sin(2 * ew); wk1r = w1r; wk1i = w1i; wd1r = wn4r * (w1r - w1i); wd1i = wn4r * (w1i + w1r); ss1 = 2 * w1i; wk3i = 2 * ss1 * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; ss3 = 2 * wk3i; wd3r = -wn4r * (wk3r - wk3i); wd3i = -wn4r * (wk3i + wk3r); i = 0; for (;;) { i0 = i + 4 * CDFT_LOOP_DIV; if (i0 > mh - 4) { i0 = mh - 4; } for (j = i + 2; j < i0; j += 4) { wl1r -= ss1 * wk1i; wl1i += ss1 * wk1r; wl3r -= ss3 * wk3i; wl3i += ss3 * wk3r; we1r -= ss1 * wd1i; we1i += ss1 * wd1r; we3r -= ss3 * wd3i; we3i += ss3 * wd3r; _j1 = j + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[j] - a[j2 + 1]; x0i = a[j + 1] + a[j2]; x1r = a[j] + a[j2 + 1]; x1i = a[j + 1] - a[j2]; x2r = a[_j1] - a[j3 + 1]; x2i = a[_j1 + 1] + a[j3]; x3r = a[_j1] + a[j3 + 1]; x3i = a[_j1 + 1] - a[j3]; y0r = wk1r * x0r - wk1i * x0i; y0i = wk1r * x0i + wk1i * x0r; y2r = wd1r * x2r - wd1i * x2i; y2i = wd1r * x2i + wd1i * x2r; a[j] = y0r + y2r; a[j + 1] = y0i + y2i; a[_j1] = y0r - y2r; a[_j1 + 1] = y0i - y2i; y0r = wk3r * x1r + wk3i * x1i; y0i = wk3r * x1i - wk3i * x1r; y2r = wd3r * x3r + wd3i * x3i; y2i = wd3r * x3i - wd3i * x3r; a[j2] = y0r + y2r; a[j2 + 1] = y0i + y2i; a[j3] = y0r - y2r; a[j3 + 1] = y0i - y2i; x0r = a[j + 2] - a[j2 + 3]; x0i = a[j + 3] + a[j2 + 2]; x1r = a[j + 2] + a[j2 + 3]; x1i = a[j + 3] - a[j2 + 2]; x2r = a[_j1 + 2] - a[j3 + 3]; x2i = a[_j1 + 3] + a[j3 + 2]; x3r = a[_j1 + 2] + a[j3 + 3]; x3i = a[_j1 + 3] - a[j3 + 2]; y0r = wl1r * x0r - wl1i * x0i; y0i = wl1r * x0i + wl1i * x0r; y2r = we1r * x2r - we1i * x2i; y2i = we1r * x2i + we1i * x2r; a[j + 2] = y0r + y2r; a[j + 3] = y0i + y2i; a[_j1 + 2] = y0r - y2r; a[_j1 + 3] = y0i - y2i; y0r = wl3r * x1r + wl3i * x1i; y0i = wl3r * x1i - wl3i * x1r; y2r = we3r * x3r + we3i * x3i; y2i = we3r * x3i - we3i * x3r; a[j2 + 2] = y0r + y2r; a[j2 + 3] = y0i + y2i; a[j3 + 2] = y0r - y2r; a[j3 + 3] = y0i - y2i; _j0 = m - j; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0] - a[j2 + 1]; x0i = a[_j0 + 1] + a[j2]; x1r = a[_j0] + a[j2 + 1]; x1i = a[_j0 + 1] - a[j2]; x2r = a[_j1] - a[j3 + 1]; x2i = a[_j1 + 1] + a[j3]; x3r = a[_j1] + a[j3 + 1]; x3i = a[_j1 + 1] - a[j3]; y0r = wd1i * x0r - wd1r * x0i; y0i = wd1i * x0i + wd1r * x0r; y2r = wk1i * x2r - wk1r * x2i; y2i = wk1i * x2i + wk1r * x2r; a[_j0] = y0r + y2r; a[_j0 + 1] = y0i + y2i; a[_j1] = y0r - y2r; a[_j1 + 1] = y0i - y2i; y0r = wd3i * x1r + wd3r * x1i; y0i = wd3i * x1i - wd3r * x1r; y2r = wk3i * x3r + wk3r * x3i; y2i = wk3i * x3i - wk3r * x3r; a[j2] = y0r + y2r; a[j2 + 1] = y0i + y2i; a[j3] = y0r - y2r; a[j3 + 1] = y0i - y2i; x0r = a[_j0 - 2] - a[j2 - 1]; x0i = a[_j0 - 1] + a[j2 - 2]; x1r = a[_j0 - 2] + a[j2 - 1]; x1i = a[_j0 - 1] - a[j2 - 2]; x2r = a[_j1 - 2] - a[j3 - 1]; x2i = a[_j1 - 1] + a[j3 - 2]; x3r = a[_j1 - 2] + a[j3 - 1]; x3i = a[_j1 - 1] - a[j3 - 2]; y0r = we1i * x0r - we1r * x0i; y0i = we1i * x0i + we1r * x0r; y2r = wl1i * x2r - wl1r * x2i; y2i = wl1i * x2i + wl1r * x2r; a[_j0 - 2] = y0r + y2r; a[_j0 - 1] = y0i + y2i; a[_j1 - 2] = y0r - y2r; a[_j1 - 1] = y0i - y2i; y0r = we3i * x1r + we3r * x1i; y0i = we3i * x1i - we3r * x1r; y2r = wl3i * x3r + wl3r * x3i; y2i = wl3i * x3i - wl3r * x3r; a[j2 - 2] = y0r + y2r; a[j2 - 1] = y0i + y2i; a[j3 - 2] = y0r - y2r; a[j3 - 1] = y0i - y2i; wk1r -= ss1 * wl1i; wk1i += ss1 * wl1r; wk3r -= ss3 * wl3i; wk3i += ss3 * wl3r; wd1r -= ss1 * we1i; wd1i += ss1 * we1r; wd3r -= ss3 * we3i; wd3i += ss3 * we3r; } if (i0 == mh - 4) { break; } wl1r = cos(ew * i0); wl1i = sin(ew * i0); wl3i = 4 * wl1i * wl1r; wl3r = wl1r - wl3i * wl1i; wl3i = wl1i - wl3i * wl1r; we1r = wn4r * (wl1r - wl1i); we1i = wn4r * (wl1i + wl1r); we3r = -wn4r * (wl3r - wl3i); we3i = -wn4r * (wl3i + wl3r); wk1r = w1r * wl1r - w1i * wl1i; wk1i = w1r * wl1i + w1i * wl1r; wk3i = 4 * wk1i * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; wd1r = wn4r * (wk1r - wk1i); wd1i = wn4r * (wk1i + wk1r); wd3r = -wn4r * (wk3r - wk3i); wd3i = -wn4r * (wk3i + wk3r); i = i0; } wl1r = WR2500; wl1i = WI2500; _j0 = mh; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0 - 2] - a[j2 - 1]; x0i = a[_j0 - 1] + a[j2 - 2]; x1r = a[_j0 - 2] + a[j2 - 1]; x1i = a[_j0 - 1] - a[j2 - 2]; x2r = a[_j1 - 2] - a[j3 - 1]; x2i = a[_j1 - 1] + a[j3 - 2]; x3r = a[_j1 - 2] + a[j3 - 1]; x3i = a[_j1 - 1] - a[j3 - 2]; y0r = wk1r * x0r - wk1i * x0i; y0i = wk1r * x0i + wk1i * x0r; y2r = wd1r * x2r - wd1i * x2i; y2i = wd1r * x2i + wd1i * x2r; a[_j0 - 2] = y0r + y2r; a[_j0 - 1] = y0i + y2i; a[_j1 - 2] = y0r - y2r; a[_j1 - 1] = y0i - y2i; y0r = wk3r * x1r + wk3i * x1i; y0i = wk3r * x1i - wk3i * x1r; y2r = wd3r * x3r + wd3i * x3i; y2i = wd3r * x3i - wd3i * x3r; a[j2 - 2] = y0r + y2r; a[j2 - 1] = y0i + y2i; a[j3 - 2] = y0r - y2r; a[j3 - 1] = y0i - y2i; x0r = a[_j0] - a[j2 + 1]; x0i = a[_j0 + 1] + a[j2]; x1r = a[_j0] + a[j2 + 1]; x1i = a[_j0 + 1] - a[j2]; x2r = a[_j1] - a[j3 + 1]; x2i = a[_j1 + 1] + a[j3]; x3r = a[_j1] + a[j3 + 1]; x3i = a[_j1 + 1] - a[j3]; y0r = wl1r * x0r - wl1i * x0i; y0i = wl1r * x0i + wl1i * x0r; y2r = wl1i * x2r - wl1r * x2i; y2i = wl1i * x2i + wl1r * x2r; a[_j0] = y0r + y2r; a[_j0 + 1] = y0i + y2i; a[_j1] = y0r - y2r; a[_j1 + 1] = y0i - y2i; y0r = wl1i * x1r - wl1r * x1i; y0i = wl1i * x1i + wl1r * x1r; y2r = wl1r * x3r - wl1i * x3i; y2i = wl1r * x3i + wl1i * x3r; a[j2] = y0r - y2r; a[j2 + 1] = y0i - y2i; a[j3] = y0r + y2r; a[j3 + 1] = y0i + y2i; x0r = a[_j0 + 2] - a[j2 + 3]; x0i = a[_j0 + 3] + a[j2 + 2]; x1r = a[_j0 + 2] + a[j2 + 3]; x1i = a[_j0 + 3] - a[j2 + 2]; x2r = a[_j1 + 2] - a[j3 + 3]; x2i = a[_j1 + 3] + a[j3 + 2]; x3r = a[_j1 + 2] + a[j3 + 3]; x3i = a[_j1 + 3] - a[j3 + 2]; y0r = wd1i * x0r - wd1r * x0i; y0i = wd1i * x0i + wd1r * x0r; y2r = wk1i * x2r - wk1r * x2i; y2i = wk1i * x2i + wk1r * x2r; a[_j0 + 2] = y0r + y2r; a[_j0 + 3] = y0i + y2i; a[_j1 + 2] = y0r - y2r; a[_j1 + 3] = y0i - y2i; y0r = wd3i * x1r + wd3r * x1i; y0i = wd3i * x1i - wd3r * x1r; y2r = wk3i * x3r + wk3r * x3i; y2i = wk3i * x3i - wk3r * x3r; a[j2 + 2] = y0r + y2r; a[j2 + 3] = y0i + y2i; a[j3 + 2] = y0r - y2r; a[j3 + 3] = y0i - y2i; } void cftfx41(int n, double *a) { if (n == 128) { cftf161(a); cftf162(&a[32]); cftf161(&a[64]); cftf161(&a[96]); } else { cftf081(a); cftf082(&a[16]); cftf081(&a[32]); cftf081(&a[48]); } } void cftf161(double *a) { double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; wn4r = WR5000; wk1r = WR2500; wk1i = WI2500; x0r = a[0] + a[16]; x0i = a[1] + a[17]; x1r = a[0] - a[16]; x1i = a[1] - a[17]; x2r = a[8] + a[24]; x2i = a[9] + a[25]; x3r = a[8] - a[24]; x3i = a[9] - a[25]; y0r = x0r + x2r; y0i = x0i + x2i; y4r = x0r - x2r; y4i = x0i - x2i; y8r = x1r - x3i; y8i = x1i + x3r; y12r = x1r + x3i; y12i = x1i - x3r; x0r = a[2] + a[18]; x0i = a[3] + a[19]; x1r = a[2] - a[18]; x1i = a[3] - a[19]; x2r = a[10] + a[26]; x2i = a[11] + a[27]; x3r = a[10] - a[26]; x3i = a[11] - a[27]; y1r = x0r + x2r; y1i = x0i + x2i; y5r = x0r - x2r; y5i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y9r = wk1r * x0r - wk1i * x0i; y9i = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; y13r = wk1i * x0r - wk1r * x0i; y13i = wk1i * x0i + wk1r * x0r; x0r = a[4] + a[20]; x0i = a[5] + a[21]; x1r = a[4] - a[20]; x1i = a[5] - a[21]; x2r = a[12] + a[28]; x2i = a[13] + a[29]; x3r = a[12] - a[28]; x3i = a[13] - a[29]; y2r = x0r + x2r; y2i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y10r = wn4r * (x0r - x0i); y10i = wn4r * (x0i + x0r); x0r = x1r + x3i; x0i = x1i - x3r; y14r = wn4r * (x0r + x0i); y14i = wn4r * (x0i - x0r); x0r = a[6] + a[22]; x0i = a[7] + a[23]; x1r = a[6] - a[22]; x1i = a[7] - a[23]; x2r = a[14] + a[30]; x2i = a[15] + a[31]; x3r = a[14] - a[30]; x3i = a[15] - a[31]; y3r = x0r + x2r; y3i = x0i + x2i; y7r = x0r - x2r; y7i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y11r = wk1i * x0r - wk1r * x0i; y11i = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; y15r = wk1r * x0r - wk1i * x0i; y15i = wk1r * x0i + wk1i * x0r; x0r = y12r - y14r; x0i = y12i - y14i; x1r = y12r + y14r; x1i = y12i + y14i; x2r = y13r - y15r; x2i = y13i - y15i; x3r = y13r + y15r; x3i = y13i + y15i; a[24] = x0r + x2r; a[25] = x0i + x2i; a[26] = x0r - x2r; a[27] = x0i - x2i; a[28] = x1r - x3i; a[29] = x1i + x3r; a[30] = x1r + x3i; a[31] = x1i - x3r; x0r = y8r + y10r; x0i = y8i + y10i; x1r = y8r - y10r; x1i = y8i - y10i; x2r = y9r + y11r; x2i = y9i + y11i; x3r = y9r - y11r; x3i = y9i - y11i; a[16] = x0r + x2r; a[17] = x0i + x2i; a[18] = x0r - x2r; a[19] = x0i - x2i; a[20] = x1r - x3i; a[21] = x1i + x3r; a[22] = x1r + x3i; a[23] = x1i - x3r; x0r = y5r - y7i; x0i = y5i + y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); x0r = y5r + y7i; x0i = y5i - y7r; x3r = wn4r * (x0r - x0i); x3i = wn4r * (x0i + x0r); x0r = y4r - y6i; x0i = y4i + y6r; x1r = y4r + y6i; x1i = y4i - y6r; a[8] = x0r + x2r; a[9] = x0i + x2i; a[10] = x0r - x2r; a[11] = x0i - x2i; a[12] = x1r - x3i; a[13] = x1i + x3r; a[14] = x1r + x3i; a[15] = x1i - x3r; x0r = y0r + y2r; x0i = y0i + y2i; x1r = y0r - y2r; x1i = y0i - y2i; x2r = y1r + y3r; x2i = y1i + y3i; x3r = y1r - y3r; x3i = y1i - y3i; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x0r - x2r; a[3] = x0i - x2i; a[4] = x1r - x3i; a[5] = x1i + x3r; a[6] = x1r + x3i; a[7] = x1i - x3r; } void cftf162(double *a) { double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; wn4r = WR5000; wk1r = WR1250; wk1i = WI1250; wk2r = WR2500; wk2i = WI2500; wk3r = WR3750; wk3i = WI3750; x1r = a[0] - a[17]; x1i = a[1] + a[16]; x0r = a[8] - a[25]; x0i = a[9] + a[24]; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); y0r = x1r + x2r; y0i = x1i + x2i; y4r = x1r - x2r; y4i = x1i - x2i; x1r = a[0] + a[17]; x1i = a[1] - a[16]; x0r = a[8] + a[25]; x0i = a[9] - a[24]; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); y8r = x1r - x2i; y8i = x1i + x2r; y12r = x1r + x2i; y12i = x1i - x2r; x0r = a[2] - a[19]; x0i = a[3] + a[18]; x1r = wk1r * x0r - wk1i * x0i; x1i = wk1r * x0i + wk1i * x0r; x0r = a[10] - a[27]; x0i = a[11] + a[26]; x2r = wk3i * x0r - wk3r * x0i; x2i = wk3i * x0i + wk3r * x0r; y1r = x1r + x2r; y1i = x1i + x2i; y5r = x1r - x2r; y5i = x1i - x2i; x0r = a[2] + a[19]; x0i = a[3] - a[18]; x1r = wk3r * x0r - wk3i * x0i; x1i = wk3r * x0i + wk3i * x0r; x0r = a[10] + a[27]; x0i = a[11] - a[26]; x2r = wk1r * x0r + wk1i * x0i; x2i = wk1r * x0i - wk1i * x0r; y9r = x1r - x2r; y9i = x1i - x2i; y13r = x1r + x2r; y13i = x1i + x2i; x0r = a[4] - a[21]; x0i = a[5] + a[20]; x1r = wk2r * x0r - wk2i * x0i; x1i = wk2r * x0i + wk2i * x0r; x0r = a[12] - a[29]; x0i = a[13] + a[28]; x2r = wk2i * x0r - wk2r * x0i; x2i = wk2i * x0i + wk2r * x0r; y2r = x1r + x2r; y2i = x1i + x2i; y6r = x1r - x2r; y6i = x1i - x2i; x0r = a[4] + a[21]; x0i = a[5] - a[20]; x1r = wk2i * x0r - wk2r * x0i; x1i = wk2i * x0i + wk2r * x0r; x0r = a[12] + a[29]; x0i = a[13] - a[28]; x2r = wk2r * x0r - wk2i * x0i; x2i = wk2r * x0i + wk2i * x0r; y10r = x1r - x2r; y10i = x1i - x2i; y14r = x1r + x2r; y14i = x1i + x2i; x0r = a[6] - a[23]; x0i = a[7] + a[22]; x1r = wk3r * x0r - wk3i * x0i; x1i = wk3r * x0i + wk3i * x0r; x0r = a[14] - a[31]; x0i = a[15] + a[30]; x2r = wk1i * x0r - wk1r * x0i; x2i = wk1i * x0i + wk1r * x0r; y3r = x1r + x2r; y3i = x1i + x2i; y7r = x1r - x2r; y7i = x1i - x2i; x0r = a[6] + a[23]; x0i = a[7] - a[22]; x1r = wk1i * x0r + wk1r * x0i; x1i = wk1i * x0i - wk1r * x0r; x0r = a[14] + a[31]; x0i = a[15] - a[30]; x2r = wk3i * x0r - wk3r * x0i; x2i = wk3i * x0i + wk3r * x0r; y11r = x1r + x2r; y11i = x1i + x2i; y15r = x1r - x2r; y15i = x1i - x2i; x1r = y0r + y2r; x1i = y0i + y2i; x2r = y1r + y3r; x2i = y1i + y3i; a[0] = x1r + x2r; a[1] = x1i + x2i; a[2] = x1r - x2r; a[3] = x1i - x2i; x1r = y0r - y2r; x1i = y0i - y2i; x2r = y1r - y3r; x2i = y1i - y3i; a[4] = x1r - x2i; a[5] = x1i + x2r; a[6] = x1r + x2i; a[7] = x1i - x2r; x1r = y4r - y6i; x1i = y4i + y6r; x0r = y5r - y7i; x0i = y5i + y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[8] = x1r + x2r; a[9] = x1i + x2i; a[10] = x1r - x2r; a[11] = x1i - x2i; x1r = y4r + y6i; x1i = y4i - y6r; x0r = y5r + y7i; x0i = y5i - y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[12] = x1r - x2i; a[13] = x1i + x2r; a[14] = x1r + x2i; a[15] = x1i - x2r; x1r = y8r + y10r; x1i = y8i + y10i; x2r = y9r - y11r; x2i = y9i - y11i; a[16] = x1r + x2r; a[17] = x1i + x2i; a[18] = x1r - x2r; a[19] = x1i - x2i; x1r = y8r - y10r; x1i = y8i - y10i; x2r = y9r + y11r; x2i = y9i + y11i; a[20] = x1r - x2i; a[21] = x1i + x2r; a[22] = x1r + x2i; a[23] = x1i - x2r; x1r = y12r - y14i; x1i = y12i + y14r; x0r = y13r + y15i; x0i = y13i - y15r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[24] = x1r + x2r; a[25] = x1i + x2i; a[26] = x1r - x2r; a[27] = x1i - x2i; x1r = y12r + y14i; x1i = y12i - y14r; x0r = y13r - y15i; x0i = y13i + y15r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[28] = x1r - x2i; a[29] = x1i + x2r; a[30] = x1r + x2i; a[31] = x1i - x2r; } void cftf081(double *a) { double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; wn4r = WR5000; x0r = a[0] + a[8]; x0i = a[1] + a[9]; x1r = a[0] - a[8]; x1i = a[1] - a[9]; x2r = a[4] + a[12]; x2i = a[5] + a[13]; x3r = a[4] - a[12]; x3i = a[5] - a[13]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[2] + a[10]; x0i = a[3] + a[11]; x1r = a[2] - a[10]; x1i = a[3] - a[11]; x2r = a[6] + a[14]; x2i = a[7] + a[15]; x3r = a[6] - a[14]; x3i = a[7] - a[15]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x1i - x3r; y5r = wn4r * (x0r - x0i); y5i = wn4r * (x0r + x0i); y7r = wn4r * (x2r - x2i); y7i = wn4r * (x2r + x2i); a[8] = y1r + y5r; a[9] = y1i + y5i; a[10] = y1r - y5r; a[11] = y1i - y5i; a[12] = y3r - y7i; a[13] = y3i + y7r; a[14] = y3r + y7i; a[15] = y3i - y7r; a[0] = y0r + y4r; a[1] = y0i + y4i; a[2] = y0r - y4r; a[3] = y0i - y4i; a[4] = y2r - y6i; a[5] = y2i + y6r; a[6] = y2r + y6i; a[7] = y2i - y6r; } void cftf082(double *a) { double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; wn4r = WR5000; wk1r = WR2500; wk1i = WI2500; y0r = a[0] - a[9]; y0i = a[1] + a[8]; y1r = a[0] + a[9]; y1i = a[1] - a[8]; x0r = a[4] - a[13]; x0i = a[5] + a[12]; y2r = wn4r * (x0r - x0i); y2i = wn4r * (x0i + x0r); x0r = a[4] + a[13]; x0i = a[5] - a[12]; y3r = wn4r * (x0r - x0i); y3i = wn4r * (x0i + x0r); x0r = a[2] - a[11]; x0i = a[3] + a[10]; y4r = wk1r * x0r - wk1i * x0i; y4i = wk1r * x0i + wk1i * x0r; x0r = a[2] + a[11]; x0i = a[3] - a[10]; y5r = wk1i * x0r - wk1r * x0i; y5i = wk1i * x0i + wk1r * x0r; x0r = a[6] - a[15]; x0i = a[7] + a[14]; y6r = wk1i * x0r - wk1r * x0i; y6i = wk1i * x0i + wk1r * x0r; x0r = a[6] + a[15]; x0i = a[7] - a[14]; y7r = wk1r * x0r - wk1i * x0i; y7i = wk1r * x0i + wk1i * x0r; x0r = y0r + y2r; x0i = y0i + y2i; x1r = y4r + y6r; x1i = y4i + y6i; a[0] = x0r + x1r; a[1] = x0i + x1i; a[2] = x0r - x1r; a[3] = x0i - x1i; x0r = y0r - y2r; x0i = y0i - y2i; x1r = y4r - y6r; x1i = y4i - y6i; a[4] = x0r - x1i; a[5] = x0i + x1r; a[6] = x0r + x1i; a[7] = x0i - x1r; x0r = y1r - y3i; x0i = y1i + y3r; x1r = y5r - y7r; x1i = y5i - y7i; a[8] = x0r + x1r; a[9] = x0i + x1i; a[10] = x0r - x1r; a[11] = x0i - x1i; x0r = y1r + y3i; x0i = y1i - y3r; x1r = y5r + y7r; x1i = y5i + y7i; a[12] = x0r - x1i; a[13] = x0i + x1r; a[14] = x0r + x1i; a[15] = x0i - x1r; } void cftf040(double *a) { double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; x0r = a[0] + a[4]; x0i = a[1] + a[5]; x1r = a[0] - a[4]; x1i = a[1] - a[5]; x2r = a[2] + a[6]; x2i = a[3] + a[7]; x3r = a[2] - a[6]; x3i = a[3] - a[7]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x1r - x3i; a[3] = x1i + x3r; a[4] = x0r - x2r; a[5] = x0i - x2i; a[6] = x1r + x3i; a[7] = x1i - x3r; } void cftb040(double *a) { double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; x0r = a[0] + a[4]; x0i = a[1] + a[5]; x1r = a[0] - a[4]; x1i = a[1] - a[5]; x2r = a[2] + a[6]; x2i = a[3] + a[7]; x3r = a[2] - a[6]; x3i = a[3] - a[7]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x1r + x3i; a[3] = x1i - x3r; a[4] = x0r - x2r; a[5] = x0i - x2i; a[6] = x1r - x3i; a[7] = x1i + x3r; } void cftx020(double *a) { double x0r, x0i; x0r = a[0] - a[2]; x0i = a[1] - a[3]; a[0] += a[2]; a[1] += a[3]; a[2] = x0r; a[3] = x0i; } void rftfsub(int n, double *a) { int i, i0, j, k; double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; ec = 2 * M_PI_2 / n; wkr = 0; wki = 0; wdi = cos(ec); wdr = sin(ec); wdi *= wdr; wdr *= wdr; w1r = 1 - 2 * wdr; w1i = 2 * wdi; ss = 2 * w1i; i = n >> 1; for (;;) { i0 = i - 4 * RDFT_LOOP_DIV; if (i0 < 4) { i0 = 4; } for (j = i - 4; j >= i0; j -= 4) { k = n - j; xr = a[j + 2] - a[k - 2]; xi = a[j + 3] + a[k - 1]; yr = wdr * xr - wdi * xi; yi = wdr * xi + wdi * xr; a[j + 2] -= yr; a[j + 3] -= yi; a[k - 2] += yr; a[k - 1] -= yi; wkr += ss * wdi; wki += ss * (0.5 - wdr); xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr - wki * xi; yi = wkr * xi + wki * xr; a[j] -= yr; a[j + 1] -= yi; a[k] += yr; a[k + 1] -= yi; wdr += ss * wki; wdi += ss * (0.5 - wkr); } if (i0 == 4) { break; } wkr = 0.5 * sin(ec * i0); wki = 0.5 * cos(ec * i0); wdr = 0.5 - (wkr * w1r - wki * w1i); wdi = wkr * w1i + wki * w1r; wkr = 0.5 - wkr; i = i0; } xr = a[2] - a[n - 2]; xi = a[3] + a[n - 1]; yr = wdr * xr - wdi * xi; yi = wdr * xi + wdi * xr; a[2] -= yr; a[3] -= yi; a[n - 2] += yr; a[n - 1] -= yi; } void rftbsub(int n, double *a) { int i, i0, j, k; double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; ec = 2 * M_PI_2 / n; wkr = 0; wki = 0; wdi = cos(ec); wdr = sin(ec); wdi *= wdr; wdr *= wdr; w1r = 1 - 2 * wdr; w1i = 2 * wdi; ss = 2 * w1i; i = n >> 1; for (;;) { i0 = i - 4 * RDFT_LOOP_DIV; if (i0 < 4) { i0 = 4; } for (j = i - 4; j >= i0; j -= 4) { k = n - j; xr = a[j + 2] - a[k - 2]; xi = a[j + 3] + a[k - 1]; yr = wdr * xr + wdi * xi; yi = wdr * xi - wdi * xr; a[j + 2] -= yr; a[j + 3] -= yi; a[k - 2] += yr; a[k - 1] -= yi; wkr += ss * wdi; wki += ss * (0.5 - wdr); xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr + wki * xi; yi = wkr * xi - wki * xr; a[j] -= yr; a[j + 1] -= yi; a[k] += yr; a[k + 1] -= yi; wdr += ss * wki; wdi += ss * (0.5 - wkr); } if (i0 == 4) { break; } wkr = 0.5 * sin(ec * i0); wki = 0.5 * cos(ec * i0); wdr = 0.5 - (wkr * w1r - wki * w1i); wdi = wkr * w1i + wki * w1r; wkr = 0.5 - wkr; i = i0; } xr = a[2] - a[n - 2]; xi = a[3] + a[n - 1]; yr = wdr * xr + wdi * xi; yi = wdr * xi - wdi * xr; a[2] -= yr; a[3] -= yi; a[n - 2] += yr; a[n - 1] -= yi; } void dctsub(int n, double *a) { int i, i0, j, k, m; double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; ec = M_PI_2 / n; wkr = 0.5; wki = 0.5; w1r = cos(ec); w1i = sin(ec); wdr = 0.5 * (w1r - w1i); wdi = 0.5 * (w1r + w1i); ss = 2 * w1i; m = n >> 1; i = 0; for (;;) { i0 = i + 2 * DCST_LOOP_DIV; if (i0 > m - 2) { i0 = m - 2; } for (j = i + 2; j <= i0; j += 2) { k = n - j; xr = wdi * a[j - 1] - wdr * a[k + 1]; xi = wdr * a[j - 1] + wdi * a[k + 1]; wkr -= ss * wdi; wki += ss * wdr; yr = wki * a[j] - wkr * a[k]; yi = wkr * a[j] + wki * a[k]; wdr -= ss * wki; wdi += ss * wkr; a[k + 1] = xr; a[k] = yr; a[j - 1] = xi; a[j] = yi; } if (i0 == m - 2) { break; } wdr = cos(ec * i0); wdi = sin(ec * i0); wkr = 0.5 * (wdr - wdi); wki = 0.5 * (wdr + wdi); wdr = wkr * w1r - wki * w1i; wdi = wkr * w1i + wki * w1r; i = i0; } xr = wdi * a[m - 1] - wdr * a[m + 1]; a[m - 1] = wdr * a[m - 1] + wdi * a[m + 1]; a[m + 1] = xr; a[m] *= WR5000; } void dstsub(int n, double *a) { int i, i0, j, k, m; double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; ec = M_PI_2 / n; wkr = 0.5; wki = 0.5; w1r = cos(ec); w1i = sin(ec); wdr = 0.5 * (w1r - w1i); wdi = 0.5 * (w1r + w1i); ss = 2 * w1i; m = n >> 1; i = 0; for (;;) { i0 = i + 2 * DCST_LOOP_DIV; if (i0 > m - 2) { i0 = m - 2; } for (j = i + 2; j <= i0; j += 2) { k = n - j; xr = wdi * a[k + 1] - wdr * a[j - 1]; xi = wdr * a[k + 1] + wdi * a[j - 1]; wkr -= ss * wdi; wki += ss * wdr; yr = wki * a[k] - wkr * a[j]; yi = wkr * a[k] + wki * a[j]; wdr -= ss * wki; wdi += ss * wkr; a[j - 1] = xr; a[j] = yr; a[k + 1] = xi; a[k] = yi; } if (i0 == m - 2) { break; } wdr = cos(ec * i0); wdi = sin(ec * i0); wkr = 0.5 * (wdr - wdi); wki = 0.5 * (wdr + wdi); wdr = wkr * w1r - wki * w1i; wdi = wkr * w1i + wki * w1r; i = i0; } xr = wdi * a[m + 1] - wdr * a[m - 1]; a[m + 1] = wdr * a[m + 1] + wdi * a[m - 1]; a[m - 1] = xr; a[m] *= WR5000; } void dctsub4(int n, double *a) { int m; double wki, wdr, wdi, xr; wki = WR5000; m = n >> 1; if (m == 2) { wdr = wki * WI2500; wdi = wki * WR2500; xr = wdi * a[1] - wdr * a[3]; a[1] = wdr * a[1] + wdi * a[3]; a[3] = xr; } a[m] *= wki; } void dstsub4(int n, double *a) { int m; double wki, wdr, wdi, xr; wki = WR5000; m = n >> 1; if (m == 2) { wdr = wki * WI2500; wdi = wki * WR2500; xr = wdi * a[3] - wdr * a[1]; a[3] = wdr * a[3] + wdi * a[1]; a[1] = xr; } a[m] *= wki; } kst-2.0.3/src/libkstmath/colorsequence.cpp000644 001750 001750 00000014640 11544160207 021202 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2003 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // application specific includes #include "colorsequence.h" #include "settings.h" #include #include #include namespace Kst { // Default palette that is used if "Kst Colors" is not found. static const char *const colors[] = { "red", "blue", "green", "black", "magenta", "steelblue", "#501010", "#105010" }; static const int colorcnt = sizeof(colors) / sizeof(char*); ColorSequence *ColorSequence::_self = &ColorSequence::self(); ColorSequence& ColorSequence::self() { if (!_self) { _self = new ColorSequence; qAddPostRoutine(ColorSequence::cleanup); } return *_self; } void ColorSequence::cleanup() { delete _self; _self = 0; } ColorSequence::ColorSequence() : _ptr(0), _mode(Color) { createPalette(); } ColorSequence::~ColorSequence() { } void ColorSequence::createPalette( ) { if (_palette != Settings::globalSettings()->curveColorSequencePalette) { _pal.clear(); _palette = Settings::globalSettings()->curveColorSequencePalette; for (int i = 0; i < colorcnt; i++) { _pal.insert(i, QColor(colors[i])); } _count = _pal.count(); _ptr = 0; } } QColor ColorSequence::next(const CurveList& curves, const QColor& badColor) { QColor color; int dark_factor; int ptrMin; int start; createPalette(); QVector usage(_count*2); for (int i = 0; i < _count*2; i++) { usage[i] = 0; } // check we are not already using this color, but if // we are then count the number of usages of each color // in the palette. start = _ptr; if (start >= _count * 2) { start = 0; } while (_ptr != start) { if (_ptr >= _count * 2) { _ptr = 0; } dark_factor = 100 + ( 50 * ( _ptr / _count ) ); color = _pal.value( _ptr % _count).dark(dark_factor); // if we are too close to the bad color then increase the usage count // to try and not use it. if (badColor.isValid() && colorsTooClose(color, badColor) ) { usage[_ptr] += 100; } for (int i = 0; i < (int)curves.count(); i++) { if (color == curves[i]->color()) { usage[_ptr]++; } } if (usage[_ptr] == 0) { break; } _ptr++; } // if we are already using this color then use the least used color for all the curves. if (usage[_ptr] != 0) { ptrMin = _ptr; while (_ptr != start) { if (_ptr >= _count * 2) { _ptr = 0; } if (usage[_ptr] < usage[ptrMin]) { ptrMin = _ptr; } _ptr++; } _ptr = ptrMin; } dark_factor = 100 + ( 50 * ( _ptr / _count ) ); color = _pal.value( _ptr++ % _count).dark(dark_factor); return color; } QColor ColorSequence::next() { createPalette(); if (_ptr >= _count * 2) { _ptr = 0; } int dark_factor = 100 + ( 50 * ( _ptr / _count ) ); return _pal.value( _ptr++ % _count).dark(dark_factor); } QColor ColorSequence::current() { createPalette(); if (_ptr >= _count * 2) { _ptr = 0; } int dark_factor = 100 + ( 50 * ( _ptr / _count ) ); return _pal.value( _ptr % _count).dark(dark_factor); } QColor ColorSequence::next(const QColor& badColor) { QColor color; int dark_factor; createPalette(); int start = _ptr; // find the next color in the sequence that it not too close to the bad color. if (badColor.isValid()) { do { if (_ptr >= _count * 2) { _ptr = 0; } dark_factor = 100 + ( 50 * ( _ptr / _count ) ); color = _pal.value( _ptr++ % _count).dark(dark_factor); } while (colorsTooClose(color, badColor) && start != _ptr); } // if we couldn't find one then just use the next color in the sequence. if (start == _ptr) { if (_ptr >= _count * 2) { _ptr = 0; } dark_factor = 100 + ( 50 * ( _ptr / _count ) ); color = _pal.value( _ptr++ % _count).dark(dark_factor); } return color; } bool ColorSequence::colorsTooClose(const QColor& color, const QColor& badColor) { double r1, h1, f1, x1, y1, z1; double r2, h2, f2, x2, y2, z2; double dc; int sugH, sugS, sugV; int badH, badS, badV; // make sure that the new color is not close to badColor. // to do this imagine HSV as defining a cone. // The distance from the point of the cone is R = V / 255 // Angle of rotational symetry is Theta = H * 2PI/360 // The 2nd angle is phi = S*(PI/4)/255 // a color is acceptable if |C1-C2|>dcMin color.getHsv(&sugH,&sugS,&sugV); badColor.getHsv(&badH, &badS, &badV); r1 = badV/255.0; h1 = badH*M_PI/180.0; f1 = badS*M_PI/4.0/255.0; x1 = r1*sin( h1 )*sin( f1 ); y1 = r1*cos( h1 )*sin( f1 ); z1 = r1*cos( f1 ); r2 = sugV/255.0; h2 = sugH*M_PI/180.0; f2 = sugS*M_PI/4.0/255.0; x2 = r2*sin( h2 )*sin( f2 ); y2 = r2*cos( h2 )*sin( f2 ); z2 = r2*cos( f2 ); dc = sqrt( ( x1-x2 )*( x1-x2 ) + ( y1-y2 )*( y1-y2 ) + ( z1-z2 )*( z1-z2 ) ); return dc < 0.3; } ColorSequence::ColorMode ColorSequence::colorMode() { return _mode; } void ColorSequence::setColorMode(ColorSequence::ColorMode mode) { _mode = mode; } int ColorSequence::count() { createPalette(); return _count * 2; } void ColorSequence::reset() { _ptr = 0; } QColor ColorSequence::entry(int ptr) { createPalette(); if (ptr >= _count * 2) { ptr = 0; } int dark_factor = 100 + ( 50 * ( ptr / _count ) ); return _pal.value( ptr % _count).dark(dark_factor); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/equation.cpp000644 001750 001750 00000035176 11544160207 020167 0ustar00synthsynth000000 000000 /*************************************************************************** equation.cpp: Equations for KST ------------------- begin : Fri Feb 10 2002 copyright : (C) 2002 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A class for handling equations for kst *@author C. Barth Netterfield */ #include #include #include #include #include #include "dialoglauncher.h" #include "enodes.h" #include "eparse-eh.h" #include "datacollection.h" #include "debug.h" #include "equation.h" #include "kst_i18n.h" #include "generatedvector.h" #include "objectstore.h" /*extern "C"*/ int yyparse(Kst::ObjectStore *store); extern void *ParsedEquation; /*extern "C"*/ struct yy_buffer_state *yy_scan_string(const char*); int yylex_destroy (void ); namespace Kst { const QString Equation::staticTypeString = I18N_NOOP("Equation"); const QString Equation::staticTypeTag = I18N_NOOP("equation"); const QString Equation::XINVECTOR = "X"; const QString Equation::XOUTVECTOR = "XO"; // Output (slave) vector const QString Equation::YOUTVECTOR = "O"; // Output (slave) vector Equation::Equation(ObjectStore *store) : DataObject(store), _doInterp(false), _xInVector(0) { _ns = 2; _pe = 0L; _typeString = i18n("Equation"); _type = "Equation"; _initializeShortName(); Q_ASSERT(store); _xOutVector = store->createObject(); Q_ASSERT(_xOutVector); _xOutVector->setProvider(this); _xOutVector->setSlaveName("x"); _xOutVector->resize(2); _outputVectors.insert(XOUTVECTOR, _xOutVector); _yOutVector = store->createObject(); Q_ASSERT(_yOutVector); _yOutVector->setProvider(this); _yOutVector->setSlaveName("y"); _yOutVector->resize(2); _outputVectors.insert(YOUTVECTOR, _yOutVector); _isValid = false; _numNew = _numShifted = 0; } Equation::~Equation() { delete _pe; _pe = 0L; } void Equation::_initializeShortName() { _shortName = 'E'+QString::number(_enum); if (_enum>max_enum) max_enum = _enum; _enum++; } void Equation::attach() { } const CurveHintList *Equation::curveHints() const { _curveHints->clear(); _curveHints->append(new CurveHint(i18n("Equation Curve"), _xOutVector->shortName(), _yOutVector->shortName())); return _curveHints; } bool Equation::isValid() const { return _isValid; } void Equation::internalUpdate() { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (!_pe) { return; } writeLockInputsAndOutputs(); Equations::Context ctx; ctx.sampleCount = _ns; ctx.xVector = _xInVector; _pe->update(&ctx); _isValid = FillY(true); // should this be updated by the update manager? //_yOutVector->internalUpdate(); //_xOutVector->internalUpdate(); unlockInputsAndOutputs(); updateVectorLabels(); return; } const QString Equation::reparsedEquation() const { QString etext; if (!_equation.isEmpty()) { if (!Equations::mutex().tryLock()) { qDebug() << "Don't reparse equation while it is being reparsed..."; return (_equation); } yylex_destroy(); yy_scan_string(_equation.toLatin1()); ParsedEquation = 0L; int rc = yyparse(store()); Equations::Node *en = static_cast(ParsedEquation); if (rc == 0 && en) { if (!en->takeVectors(VectorsUsed)) { Debug::self()->log(i18n("Equation [%1] failed to find its vectors when reparsing.").arg(_equation), Debug::Warning); } etext = en->text(); } delete en; ParsedEquation = 0L; Equations::mutex().unlock(); } return (etext); } void Equation::save(QXmlStreamWriter &s) { s.writeStartElement(staticTypeTag); // Reparse the equation, then write it back out in text so that we can update // any vectors or scalars that had name changes, but we don't get affected by // the optimizer if (!_equation.isEmpty()) { QMutexLocker ml(&Equations::mutex()); yylex_destroy(); yy_scan_string(_equation.toLatin1()); ParsedEquation = 0L; int rc = yyparse(store()); Equations::Node *en = static_cast(ParsedEquation); if (rc == 0 && en) { if (!en->takeVectors(VectorsUsed)) { Debug::self()->log(i18n("Equation [%1] failed to find its vectors when saving. Resulting Kst file may have issues.").arg(_equation), Debug::Warning); } QString etext = en->text(); s.writeAttribute("expression", etext); } delete en; ParsedEquation = 0L; } if (_xInVector) { s.writeAttribute("xvector", _xInVector->Name()); } if (_doInterp) { s.writeAttribute("interpolate", "true"); } saveNameInfo(s, VNUM|ENUM|XNUM); s.writeEndElement(); } void Equation::setEquation(const QString& in_fn) { // assert(*_xVector); - ugly, we have to allow this here due to // document loading with vector lazy-loading _equation = in_fn; VectorsUsed.clear(); ScalarsUsed.clear(); _ns = 2; // reset the updating delete _pe; _pe = 0L; if (!_equation.isEmpty()) { Equations::mutex().lock(); yylex_destroy(); yy_scan_string(_equation.toLatin1()); int rc = yyparse(store()); _pe = static_cast(ParsedEquation); if (rc == 0 && _pe) { ParsedEquation = 0L; Equations::mutex().unlock(); Equations::Context ctx; ctx.sampleCount = _ns; ctx.xVector = _xInVector; Equations::FoldVisitor vis(&ctx, &_pe); StringMap sm; if (_pe->collectObjects(VectorsUsed, ScalarsUsed, sm)) { _pe->update(&ctx); } else { //we have bad objects... Debug::self()->log(i18n("Equation [%1] references non-existent objects.").arg(_equation), Debug::Error); delete (Equations::Node*)ParsedEquation; ParsedEquation = 0L; //Equations::mutex().unlock(); } } else { // Parse error Debug::self()->log(i18n("Equation [%1] failed to parse. Errors follow.").arg(_equation), Debug::Warning); for (QStringList::ConstIterator i = Equations::errorStack.begin(); i != Equations::errorStack.end(); ++i) { Debug::self()->log(i18n("Parse Error: %1").arg(*i), Debug::Warning); } delete (Equations::Node*)ParsedEquation; ParsedEquation = 0L; _pe = 0L; Equations::mutex().unlock(); } } _isValid = _pe != 0L; if (_isValid) { _equation = reparsedEquation(); // update the string } } void Equation::updateVectorLabels() { if (!_xInVector) { return; } _xOutVector->setLabelInfo(_xInVector->labelInfo()); QString yl; QString xl; QRegExp sn("(\\(V(\\d{1,2})\\))|\\[|\\]"); // short name yl = reparsedEquation(); yl.remove(sn); LabelInfo label_info; label_info.units = QString(); label_info.quantity = QString(); label_info.name = yl; _yOutVector->setTitleInfo(label_info); } void Equation::setExistingXVector(VectorPtr in_xv, bool do_interp) { if (!in_xv) { return; } VectorPtr v = _inputVectors[XINVECTOR]; if (v == in_xv) { return; } _inputVectors.remove(XINVECTOR); _xInVector = in_xv; _inputVectors.insert(XINVECTOR, in_xv); _ns = 2; // reset the updating _doInterp = do_interp; } //FIXME: equations should not use ScalarsUsed and VectorsUsed: //instead, they should use _inputScalars and _inputVectors only. //This code, and used() is only here because they don't. qint64 Equation::minInputSerial() const { qint64 minSerial = DataObject::minInputSerial(); foreach (VectorPtr P, VectorsUsed) { minSerial = qMin(minSerial, P->serial()); } foreach (ScalarPtr P, ScalarsUsed) { minSerial = qMin(minSerial, P->serial()); } return minSerial; } qint64 Equation::minInputSerialOfLastChange() const { qint64 minSerial = DataObject::minInputSerialOfLastChange(); foreach (VectorPtr P, VectorsUsed) { minSerial = qMin(minSerial, P->serialOfLastChange()); } foreach (ScalarPtr P, ScalarsUsed) { minSerial = qMin(minSerial, P->serialOfLastChange()); } return minSerial; } PrimitiveList Equation::inputPrimitives() const { PrimitiveList primitive_list = DataObject::inputPrimitives(); int n = VectorsUsed.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(VectorsUsed.values().at(i))); } n = ScalarsUsed.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(ScalarsUsed.values().at(i))); } return primitive_list; } void Equation::replaceInput(PrimitivePtr p, PrimitivePtr new_p) { DataObject::replaceInput(p, new_p); QString newExp = _equation; QString oldName = p->Name(); QString newName = new_p->Name(); newExp = newExp.replace('[' + oldName + ']', '[' + newName + ']'); setEquation(newExp); } /************************************************************************/ /* */ /* Fill Y: Evaluates the equation */ /* */ /************************************************************************/ bool Equation::FillY(bool force) { if (!_xInVector) { return false; } int v_shift=0, v_new; int i0=0; int ns; writeLockInputsAndOutputs(); // determine value of Interp if (_doInterp) { ns = _xInVector->length(); for (VectorMap::ConstIterator i = VectorsUsed.begin(); i != VectorsUsed.end(); ++i) { if (i.value()->length() > ns) { ns = i.value()->length(); } } } else { ns = _xInVector->length(); } if (_ns != _xInVector->length() || ns != _xInVector->length() || _xInVector->numShift() != _xInVector->numNew()) { _ns = ns; VectorPtr xv = _xOutVector; VectorPtr yv = _yOutVector; if (!xv->resize(_ns)) { // FIXME: handle error? unlockInputsAndOutputs(); return false; } if (!yv->resize(_ns)) { // FIXME: handle error? unlockInputsAndOutputs(); return false; } yv->zero(); i0 = 0; // other vectors may have diffent lengths, so start over v_shift = _ns; } else { // calculate shift and new samples // only do shift optimization if all used vectors are same size and shift v_shift = _xInVector->numShift(); v_new = _xInVector->numNew(); for (VectorMap::ConstIterator i = VectorsUsed.begin(); i != VectorsUsed.end(); ++i) { if (v_shift != i.value()->numShift()) { v_shift = _ns; } if (v_new != i.value()->numNew()) { v_shift = _ns; } if (_ns != i.value()->length()) { v_shift = _ns; } } if (v_shift > _ns/2 || force) { i0 = 0; v_shift = _ns; } else { VectorPtr xv = _xOutVector; VectorPtr yv = _yOutVector; for (int i = v_shift; i < _ns; i++) { yv->value()[i - v_shift] = yv->value()[i]; xv->value()[i - v_shift] = xv->value()[i]; } i0 = _ns - v_shift; } } _numShifted = _yOutVector->numShift() + v_shift; if (_numShifted > _ns) { _numShifted = _ns; } _numNew = _ns - i0 + _yOutVector->numNew(); if (_numNew > _ns) { _numNew = _ns; } _xOutVector->setNewAndShift(_numNew, _numShifted); _yOutVector->setNewAndShift(_numNew, _numShifted); double *rawxv = _xOutVector->value(); double *rawyv = _yOutVector->value(); VectorPtr iv = _xInVector; Equations::Context ctx; ctx.sampleCount = _ns; ctx.xVector = iv; if (!_pe) { if (_equation.isEmpty()) { unlockInputsAndOutputs(); return true; } QMutexLocker ml(&Equations::mutex()); yylex_destroy(); yy_scan_string(_equation.toLatin1()); int rc = yyparse(store()); _pe = static_cast(ParsedEquation); if (_pe && rc == 0) { Equations::FoldVisitor vis(&ctx, &_pe); StringMap sm; _pe->collectObjects(VectorsUsed, ScalarsUsed, sm); ParsedEquation = 0L; } else { delete (Equations::Node*)ParsedEquation; ParsedEquation = 0L; _pe = 0L; unlockInputsAndOutputs(); return false; } } for (ctx.i = i0; ctx.i < _ns; ++ctx.i) { rawxv[ctx.i] = iv->value(ctx.i); ctx.x = iv->interpolate(ctx.i, _ns); rawyv[ctx.i] = _pe->value(&ctx); } if (!_xOutVector->resize(iv->length())) { // FIXME: handle error? unlockInputsAndOutputs(); return false; } unlockInputsAndOutputs(); return true; } QString Equation::propertyString() const { return equation(); } void Equation::showNewDialog() { DialogLauncher::self()->showEquationDialog(); } void Equation::showEditDialog() { DialogLauncher::self()->showEquationDialog(this); } DataObjectPtr Equation::makeDuplicate() const { EquationPtr equation = store()->createObject(); Q_ASSERT(equation); equation->setEquation(_equation); equation->setExistingXVector(_inputVectors[XINVECTOR], _doInterp); if (descriptiveNameIsManual()) { equation->setDescriptiveName(descriptiveName()); } equation->writeLock(); equation->registerChange(); equation->unlock(); return DataObjectPtr(equation); } bool Equation::uses(ObjectPtr p) const { // check VectorsUsed in addition to _input*'s if (VectorPtr vect = kst_cast(p)) { for (VectorMap::ConstIterator j = VectorsUsed.begin(); j != VectorsUsed.end(); ++j) { if (j.value() == vect) { return true; } } } else if (DataObjectPtr obj = kst_cast(p) ) { // check all connections from this expression to p for (VectorMap::Iterator j = obj->outputVectors().begin(); j != obj->outputVectors().end(); ++j) { for (VectorMap::ConstIterator k = VectorsUsed.begin(); k != VectorsUsed.end(); ++k) { if (j.value() == k.value()) { return true; } } } } return DataObject::uses(p); } QString Equation::_automaticDescriptiveName() const { return _yOutVector->titleInfo().name; } QString Equation::descriptionTip() const { if(!_xInVector) { return QString(); } return i18n("Equation: %1\n %2\nX: %3").arg(Name()).arg(equation()).arg(_xInVector->descriptionTip()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/enodefactory.cpp000644 001750 001750 00000005176 11544160207 021021 0ustar00synthsynth000000 000000 /*************************************************************************** enodefactory.cpp ---------- begin : Feb 12 2004 copyright : (C) 2004 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "enodefactory.h" #include "enodes.h" using namespace Equations; //extern "C" { #define CreateFactory(x) \ void *New##x(void *left, void *right) { \ Node *l = static_cast(left); \ Node *r = static_cast(right); \ return new x(l, r); \ } CreateFactory(Addition) CreateFactory(Subtraction) CreateFactory(Multiplication) CreateFactory(Division) CreateFactory(Modulo) CreateFactory(Power) CreateFactory(BitwiseAnd) CreateFactory(BitwiseOr) CreateFactory(LogicalAnd) CreateFactory(LogicalOr) CreateFactory(LessThan) CreateFactory(LessThanEqual) CreateFactory(GreaterThan) CreateFactory(GreaterThanEqual) CreateFactory(EqualTo) CreateFactory(NotEqualTo) #undef CreateFactory void *NewData(Kst::ObjectStore *store, char *name) { return new DataNode(store, name); } void *NewIdentifier(char *name) { return new Identifier(name); } void *NewFunction(char *name, void *args) { return new Function(name, static_cast(args)); } void *NewNumber(double n) { return new Number(n); } void *NewArgumentList() { return new ArgumentList(); } void AppendArgument(void *list, void *arg) { if (list && arg) { static_cast(list)->appendArgument(static_cast(arg)); } } void *NewNot(void *n) { return new LogicalNot(static_cast(n)); } void *NewNegation(void *n) { return new Negation(static_cast(n)); } void DeleteNode(void *n) { delete static_cast(n); } void ParenthesizeNode(void *n) { static_cast(n)->parenthesize(); } //} // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/csd.h000644 001750 001750 00000007124 11544160207 016550 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 by University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A class for handling cumulative spectral decay for kst */ #ifndef CSD_H #define CSD_H #include "dataobject.h" #include "psdcalculator.h" #include "kstmath_export.h" namespace Kst { class KSTMATH_EXPORT CSD : public DataObject { Q_OBJECT public: static const QString staticTypeString; const QString& typeString() const { return staticTypeString; } static const QString staticTypeTag; virtual void save(QXmlStreamWriter &s); virtual QString propertyString() const; void setVector(VectorPtr); VectorPtr vector() const; virtual bool slaveVectorsUsed() const; virtual void showNewDialog(); virtual void showEditDialog(); bool apodize() const; void setApodize(bool in_apodize); bool removeMean() const; void setRemoveMean(bool in_removeMean); bool average() const; void setAverage(bool in_average); double frequency() const; void setFrequency(double in_frequency); ApodizeFunction apodizeFxn() const; void setApodizeFxn(ApodizeFunction in_fxn); double gaussianSigma() const; void setGaussianSigma(double in_sigma); int windowSize() const; void setWindowSize(int in_size); int length() const; void setLength(int in_length); const QString& vectorUnits() const; void setVectorUnits(const QString& units); const QString& rateUnits() const; void setRateUnits(const QString& units); PSDType output() const; void setOutput(PSDType in_outputType); MatrixPtr outputMatrix() const; virtual DataObjectPtr makeDuplicate() const; void change(VectorPtr in_V, double in_freq, bool in_average, bool in_removeMean, bool in_apodize, ApodizeFunction in_apodizeFxn, int in_windowSize, int in_length, double in_gaussianSigma, PSDType in_outputType, const QString& in_vectorUnits, const QString& in_rateUnits); virtual QString descriptionTip() const; virtual void internalUpdate(); protected: CSD(ObjectStore *store); virtual ~CSD(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); private: void updateMatrixLabels(); double _frequency; bool _average; bool _removeMean; bool _apodize; ApodizeFunction _apodizeFxn; PSDType _outputType; double _gaussianSigma; int _windowSize; int _averageLength; int _length; QString _vectorUnits; QString _rateUnits; PSDCalculator _psdCalculator; // output matrix MatrixPtr _outMatrix; }; typedef SharedPtr CSDPtr; typedef ObjectList CSDList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/linestyle.cpp000644 001750 001750 00000002323 11544160207 020336 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2004 by University of British Columbia * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "linestyle.h" namespace Kst { const unsigned int LINESTYLE_MAXTYPE = 5; Qt::PenStyle LineStyle[LINESTYLE_MAXTYPE] = { Qt::SolidLine, Qt::DashLine, Qt::DotLine, Qt::DashDotLine, Qt::DashDotDotLine }; } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/psdcalculator.cpp000644 001750 001750 00000023517 11544160207 021176 0ustar00synthsynth000000 000000 /*************************************************************************** psdcalculator.cpp: Power Spectra Calculator for KST ------------------- begin : 2006 copyright : (C) 2006 by Kst email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** A utility class for calculating power spectra */ #include #include "kst_i18n.h" #include "debug.h" #include "psdcalculator.h" #include "vector.h" #include #include extern "C" void rdft(int n, int isgn, double *a); #define PSDMINLEN 2 #define PSDMAXLEN 27 inline double PSDCalculator::cabs2(double r, double i) { return r*r + i*i; } PSDCalculator::PSDCalculator() { _a = 0L; _w = 0L; _awLen = 0; _prevApodizeFxn = WindowUndefined; _prevGaussianSigma = 1.0; _prevOutputLen = 0; } PSDCalculator::~PSDCalculator() { delete[] _w; _w = 0L; delete[] _a; _a = 0L; } void PSDCalculator::updateWindowFxn(ApodizeFunction apodizeFxn, double gaussianSigma) { const double a = double(_awLen) / 2.0; double x; double sW = 0.0; switch (apodizeFxn) { case WindowOriginal: for (int i = 0; i < _awLen; ++i) { _w[i] = 1.0 - cos(2.0 * M_PI * double(i) / double(_awLen)); sW += _w[i] * _w[i]; } break; case WindowBartlett: for (int i = 0; i < _awLen; ++i) { x = i - a; _w[i] = 1.0 - fabs(x) / a; sW += _w[i] * _w[i]; } break; case WindowBlackman: for (int i = 0; i < _awLen; ++i) { x = i - a; _w[i] = 0.42 + 0.5 * cos(M_PI * x / a) + 0.08 * cos(2 * M_PI * x/a); sW += _w[i] * _w[i]; } break; case WindowConnes: for (int i = 0; i < _awLen; ++i) { x = i - a; _w[i] = pow(static_cast(1.0 - (x * x) / (a * a)), 2); sW += _w[i] * _w[i]; } break; case WindowCosine: for (int i = 0; i < _awLen; ++i) { x = i - a; _w[i] = cos(M_PI * x / (2.0 * a)); sW += _w[i] * _w[i]; } break; case WindowGaussian: for (int i = 0; i < _awLen; ++i) { x = i - a; _w[i] = exp(-1.0 * x * x/(2.0 * gaussianSigma * gaussianSigma)); } break; case WindowHamming: for (int i = 0; i < _awLen; ++i) { x = i - a; _w[i] = 0.53836 + 0.46164 * cos(M_PI * x / a); sW += _w[i] * _w[i]; } break; case WindowHann: for (int i = 0; i < _awLen; ++i) { x = i - a; _w[i] = pow(static_cast(cos(M_PI * x/(2.0 * a))), 2); sW += _w[i] * _w[i]; } break; case WindowWelch: for (int i = 0; i < _awLen; ++i) { x = i - a; _w[i] = 1.0 - x * x / (a * a); sW += _w[i] * _w[i]; } break; case WindowUniform: default: for (int i = 0; i < _awLen; ++i) { _w[i] = 1.0; } sW = _awLen; break; } double norm = sqrt((double)_awLen/sW); // normalization constant s.t. sum over (w^2) is _awLen for (int i = 0; i < _awLen; ++i) { _w[i] *= norm; } _prevApodizeFxn = apodizeFxn; _prevGaussianSigma = gaussianSigma; } int PSDCalculator::calculatePowerSpectrum( double *input, int inputLen, double *output, int outputLen, bool removeMean, bool interpolateHoles, bool average, int averageLen, bool apodize, ApodizeFunction apodizeFxn, double gaussianSigma, PSDType outputType, double inputSamplingFreq) { if (outputLen != calculateOutputVectorLength(inputLen, average, averageLen)) { Kst::Debug::self()->log(i18n("in PSDCalculator::calculatePowerSpectrum: received output array with wrong length."), Kst::Debug::Error); return -1; } if (outputLen != _prevOutputLen) { delete[] _a; delete[] _w; _awLen = outputLen*2; _prevOutputLen = outputLen; _a = new double[_awLen]; _w = new double[_awLen]; updateWindowFxn(apodizeFxn, gaussianSigma); } if ( (_prevApodizeFxn != apodizeFxn) || (_prevGaussianSigma != gaussianSigma) ) { updateWindowFxn(apodizeFxn, gaussianSigma); } int currentCopyLen, nsamples = 0; int i_samp, i_subset, ioffset; memset(output, 0, sizeof(double)*outputLen); // initialize output. bool done = false; for (i_subset = 0; !done; i_subset++) { ioffset = i_subset*outputLen; //overlapping average => i_subset*outputLen // only zero pad if we really have to. It is better to adjust the last chunk's // overlap. if (ioffset + _awLen*5/4 < inputLen) { currentCopyLen = _awLen; //will copy a complete window. } else if (_awLen PSDMAXLEN) { psdloglen = PSDMAXLEN; } return int(pow(2.0, psdloglen - 1)); } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/builtinobjects.h000644 001750 001750 00000002023 11544160207 021010 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUILTINOBJECTS_H #define BUILTINOBJECTS_H #include "kstmath_export.h" namespace Kst { namespace Builtins { KSTMATH_EXPORT void initObjects(); } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/settings.h000644 001750 001750 00000006703 11544160207 017641 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2003 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SETTINGS_H #define SETTINGS_H #include #include "plotdefines.h" #include "kstmath_export.h" namespace Kst { enum EMailEncryption { EMailEncryptionNone, EMailEncryptionSSL, EMailEncryptionTLS, EMailEncryptionMAXIMUM }; enum EMailAuthentication { EMailAuthenticationPLAIN, EMailAuthenticationLOGIN, EMailAuthenticationCRAMMD5, EMailAuthenticationDIGESTMD5, EMailAuthenticationMAXIMUM }; class Settings { public: KSTMATH_EXPORT Settings(); KSTMATH_EXPORT Settings(const Settings&); KSTMATH_EXPORT Settings& operator=(const Settings&); // do not delete this object KSTMATH_EXPORT static Settings *globalSettings(); KSTMATH_EXPORT static void setGlobalSettings(const Settings *settings); KSTMATH_EXPORT static void checkUpdates(); KSTMATH_EXPORT void save(); void reload(); KSTMATH_EXPORT void setPrintingDefaults(); // set printing settings to default long plotUpdateTimer; long plotFontSize; long plotFontMinSize; QColor backgroundColor; QColor foregroundColor; QString curveColorSequencePalette; bool promptWindowClose : 1; bool showQuickStart : 1; bool tiedZoomGlobal : 1; bool xMajor : 1; bool yMajor : 1; bool xMinor : 1; bool yMinor : 1; bool majorGridColorDefault : 1; bool minorGridColorDefault : 1; bool xAxisInterpret : 1; bool yAxisInterpret : 1; bool emailRequiresAuthentication : 1; QColor majorColor; QColor minorColor; AxisInterpretationType xAxisInterpretation; AxisDisplayType xAxisDisplay; AxisInterpretationType yAxisInterpretation; AxisDisplayType yAxisDisplay; int defaultLineWeight; QString emailSender; QString emailSMTPServer; QString emailUsername; QString emailPassword; int emailSMTPPort; EMailEncryption emailEncryption; EMailAuthentication emailAuthentication; KSTMATH_EXPORT int utcOffset(); QString timezone; int offsetSeconds; struct PrintingMonochrome { QString enhanceReadability; // order of "-1" means property is not included in cycling QString pointStyleOrder; QString lineStyleOrder; QString lineWidthOrder; QString maxLineWidth; QString pointDensity; }; struct Printing { QString pageSize; QString orientation; QString plotDateTimeFooter; QString maintainAspect; QString curveWidthAdjust; QString monochrome; PrintingMonochrome monochromeSettings; }; Printing printing; private: static Settings *_self; static void cleanup(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/csdfactory.h000644 001750 001750 00000002166 11544160207 020141 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CSDFACTORY_H #define CSDFACTORY_H #include "objectfactory.h" namespace Kst { class CSDFactory : public ObjectFactory { public: CSDFactory(); ~CSDFactory(); DataObjectPtr generateObject(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/relationfactory.cpp000644 001750 001750 00000003714 11544160207 021540 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "relationfactory.h" #include #include namespace Kst { static QMap *relation_factories = 0; void cleanupRelations() { foreach (RelationFactory *f, *relation_factories) { delete f; } delete relation_factories; relation_factories = 0; } RelationFactory::RelationFactory() { } RelationFactory::~RelationFactory() { } void RelationFactory::registerFactory(const QString& node, RelationFactory *factory) { if (!relation_factories) { relation_factories = new QMap; qAddPostRoutine(cleanupRelations); } relation_factories->insert(node, factory); } void RelationFactory::registerFactory(const QStringList& nodes, RelationFactory *factory) { foreach (const QString n, nodes) { registerFactory(n, factory); } } RelationPtr RelationFactory::parse(ObjectStore *store, QXmlStreamReader& stream) { if (!relation_factories) { return 0; } RelationFactory *f = relation_factories->value(stream.name().toString()); if (!f) { return 0; } return f->generateRelation(store, stream); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/basicplugin.cpp000644 001750 001750 00000025771 11544160207 020642 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #ifndef Q_WS_WIN32 #include #endif #include "kst_i18n.h" #include "debug.h" #include "basicplugin.h" #include "dialoglauncher.h" #include "datacollection.h" #include "objectstore.h" #include "dataobjectplugin.h" namespace Kst { const QString BasicPlugin::staticTypeString = I18N_NOOP("Plugin"); const QString BasicPlugin::staticTypeTag = I18N_NOOP("plugin"); BasicPlugin::BasicPlugin(ObjectStore *store) : DataObject(store) { _typeString = i18n("Plugin"); _type = "Plugin"; _initializeShortName(); } BasicPlugin::~BasicPlugin() { } void BasicPlugin::_initializeShortName() { _shortName = 'P'+QString::number(_pnum); if (_pnum>max_pnum) max_pnum = _pnum; _pnum++; } void BasicPlugin::setPluginName(const QString &pluginName) { _pluginName = pluginName; } DataObjectPtr BasicPlugin::makeDuplicate() const { #if 0 BasicPluginPtr plugin = kst_cast(DataObject::createPlugin(propertyString())); // use same inputs for (VectorMap::ConstIterator iter = _inputVectors.begin(); iter != _inputVectors.end(); ++iter) { plugin->inputVectors().insert(iter.key(), iter.value()); } for (ScalarMap::ConstIterator iter = _inputScalars.begin(); iter != _inputScalars.end(); ++iter) { plugin->inputScalars().insert(iter.key(), iter.value()); } for (StringMap::ConstIterator iter = _inputStrings.begin(); iter != _inputStrings.end(); ++iter) { plugin->inputStrings().insert(iter.key(), iter.value()); } // create new outputs for (VectorMap::ConstIterator iter = outputVectors().begin(); iter != outputVectors().end(); ++iter) { KstWriteLocker blockVectorUpdates(&vectorList.lock()); VectorPtr v = new Vector(ObjectTag(iter.value()->tag().tag() + "'", iter.value()->tag().context()), 0, plugin.data()); // FIXME: unique tag generation plugin->outputVectors().insert(iter.key(), v); } for (ScalarMap::ConstIterator iter = outputScalars().begin(); iter != outputScalars().end(); ++iter) { ScalarPtr s = new Scalar(ObjectTag(iter.value()->tag().tag() + "'", iter.value()->tag().context()), plugin.data()); // FIXME: unique tag generation plugin->outputScalars().insert(iter.key(), s); } for (StringMap::ConstIterator iter = outputStrings().begin(); iter != outputStrings().end(); ++iter) { StringPtr s = new String(ObjectTag(iter.value()->tag().tag() + "'", iter.value()->tag().context()), plugin.data()); // FIXME: unique tag generation plugin->outputStrings().insert(iter.key(), s); } // set the same plugin plugin->setTagName(ObjectTag(tag().tag() + "'", tag().context())); // FIXME: unique tag generation method map.insert(this, DataObjectPtr(plugin)); return DataObjectPtr(plugin); #endif // FIXME: implement this return 0L; } void BasicPlugin::showNewDialog() { DialogLauncher::self()->showBasicPluginDialog(_pluginName); } void BasicPlugin::showEditDialog() { DialogLauncher::self()->showBasicPluginDialog(_pluginName, this); } VectorPtr BasicPlugin::inputVector(const QString& vector) const { VectorMap::ConstIterator i = _inputVectors.find(vector); if (i != _inputVectors.end()) return *i; else return 0; } ScalarPtr BasicPlugin::inputScalar(const QString& scalar) const { ScalarMap::ConstIterator i = _inputScalars.find(scalar); if (i != _inputScalars.end()) return *i; else return 0; } StringPtr BasicPlugin::inputString(const QString& string) const { StringMap::ConstIterator i = _inputStrings.find(string); if (i != _inputStrings.end()) return *i; else return 0; } VectorPtr BasicPlugin::outputVector(const QString& vector) const { VectorMap::ConstIterator i = _outputVectors.find(vector); if (i != _outputVectors.end()) return *i; else return 0; } ScalarPtr BasicPlugin::outputScalar(const QString& scalar) const { ScalarMap::ConstIterator i = _outputScalars.find(scalar); if (i != _outputScalars.end()) return *i; else return 0; } StringPtr BasicPlugin::outputString(const QString& string) const { StringMap::ConstIterator i = _outputStrings.find(string); if (i != _outputStrings.end()) return *i; else return 0; } void BasicPlugin::setInputVector(const QString &type, VectorPtr ptr) { if (ptr) { _inputVectors[type] = ptr; } else { _inputVectors.remove(type); } } void BasicPlugin::setInputScalar(const QString &type, ScalarPtr ptr) { if (ptr) { _inputScalars[type] = ptr; } else { _inputScalars.remove(type); } } void BasicPlugin::setInputString(const QString &type, StringPtr ptr) { if (ptr) { _inputStrings[type] = ptr; } else { _inputStrings.remove(type); } } void BasicPlugin::setOutputVector(const QString &type, const QString &name) { QString txt = !name.isEmpty() ? name : type; Q_ASSERT(store()); VectorPtr v = store()->createObject(); v->setProvider(this); v->setSlaveName(txt); _outputVectors.insert(type, v); } void BasicPlugin::setOutputScalar(const QString &type, const QString &name) { QString txt = !name.isEmpty() ? name : type; Q_ASSERT(store()); ScalarPtr s = store()->createObject(); s->setProvider(this); s->setSlaveName(txt); _outputScalars.insert(type, s); } void BasicPlugin::setOutputString(const QString &type, const QString &name) { QString txt = !name.isEmpty() ? name : type; Q_ASSERT(store()); StringPtr s = store()->createObject(); s->setProvider(this); s->setSlaveName(txt); s->setOrphan(false); _outputStrings.insert(type, s); } void BasicPlugin::internalUpdate() { //Make sure we have all the necessary inputs if (!inputsExist()) return; writeLockInputsAndOutputs(); //Call the plugins algorithm to operate on the inputs //and produce the outputs if ( !algorithm() ) { Debug::self()->log(i18n("There is an error in the %1 algorithm.").arg(propertyString()), Debug::Error); unlockInputsAndOutputs(); return; } //Perform update on the outputs updateOutput(); createScalars(); unlockInputsAndOutputs(); return; } // If a plugin provides a Parameters Vector, then scalars will be created, as well as a label. void BasicPlugin::createScalars() { // Assumes that this is called with a write lock in place on this object Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (hasParameterVector()) { VectorPtr vectorParam = _outputVectors["Parameters Vector"]; if (vectorParam) { QString paramName; int i = 0; int length = vectorParam->length(); Q_ASSERT(store()); for (paramName = parameterName(i); !paramName.isEmpty() && i < length; paramName = parameterName(++i)) { double scalarValue = vectorParam->value(i); if (!_outputScalars.contains(paramName)) { ScalarPtr s = store()->createObject(); s->setProvider(this); s->setSlaveName(paramName); s->setValue(scalarValue); s->writeLock(); _outputScalars.insert(paramName, s); } else { _outputScalars[paramName]->setValue(scalarValue); } } } } } QString BasicPlugin::parameterName(int /*index*/) const { return QString(); } QString BasicPlugin::label(int precision) const { Q_UNUSED(precision) QString label; QString paramName; label = Name(); if (hasParameterVector()) { VectorPtr vectorParam = _outputVectors["Parameters Vector"]; int length = vectorParam->length(); int i=0; for (paramName = parameterName(i); !paramName.isEmpty() && i < length; paramName = parameterName(++i)) { if (_outputScalars.contains(paramName)) { label += QString("\n%1: [%2]").arg(paramName).arg(_outputScalars[paramName]->Name()); } } } return label; } template static void writeVectors(T& vectors, const QString& element, QXmlStreamWriter& stream, QString (V::* name)() const) { for (QStringList::iterator it = vectors.ordered.begin(); it != vectors.ordered.end(); ++it) { typename T::iterator i = vectors.find(*it); stream.writeStartElement(element); stream.writeAttribute("type", i.key()); stream.writeAttribute("tag", (i.value()->*name)()); stream.writeEndElement(); } } void BasicPlugin::save(QXmlStreamWriter &stream) { stream.writeStartElement(staticTypeTag); stream.writeAttribute("type", _pluginName); saveNameInfo(stream, VNUM|PNUM|XNUM); writeVectors(_inputVectors, "inputvector", stream, &NamedObject::Name); writeVectors(_inputScalars, "inputscalar", stream, &NamedObject::Name); writeVectors(_inputStrings, "inputstring", stream, &NamedObject::Name); writeVectors(_outputVectors, "outputvector", stream, &Primitive::slaveName); writeVectors(_outputScalars, "outputscalar", stream, &Primitive::slaveName); writeVectors(_outputStrings, "outputstring", stream, &Primitive::slaveName); stream.writeEndElement(); } void BasicPlugin::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); } //TODO Could use some templates perhaps... bool BasicPlugin::inputsExist() const { //First, check the inputVectors... QStringList iv = inputVectorList(); QStringList::ConstIterator ivI = iv.begin(); for (; ivI != iv.end(); ++ivI) { if (!inputVector(*ivI)) return false; } //Now, check the inputScalars... QStringList is = inputScalarList(); QStringList::ConstIterator isI = is.begin(); for (; isI != is.end(); ++isI) { if (!inputScalar(*isI)) return false; } //Finally, check the inputStrings... QStringList istr = inputStringList(); QStringList::ConstIterator istrI = istr.begin(); for (; istrI != istr.end(); ++istrI) { if (!inputString(*istrI)) return false; } return true; } void BasicPlugin::updateOutput() const { //output vectors... //FIXME: _outputVectors should be used, not this string list! QStringList ov = outputVectorList(); QStringList::ConstIterator ovI = ov.begin(); for (; ovI != ov.end(); ++ovI) { if (VectorPtr o = outputVector(*ovI)) { Q_ASSERT(o->myLockStatus() == KstRWLock::WRITELOCKED); vectorRealloced(o, o->value(), o->length()); // why here? o->setNewAndShift(o->length(), o->numShift()); // why here? } } } QString BasicPlugin::descriptionTip() const { return i18n("Plugin: %1").arg(Name()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/relationfactory.h000644 001750 001750 00000003010 11544160207 021172 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RELATIONFACTORY_H #define RELATIONFACTORY_H #include #include #include "relation.h" #include "kstmath_export.h" namespace Kst { class ObjectStore; class RelationFactory { public: RelationFactory(); virtual ~RelationFactory(); // This takes ownership static void registerFactory(const QString& node, RelationFactory *factory); static void registerFactory(const QStringList& nodes, RelationFactory *factory); KSTMATH_EXPORT static RelationPtr parse(ObjectStore *store, QXmlStreamReader& stream); virtual RelationPtr generateRelation(ObjectStore *store, QXmlStreamReader& stream) = 0; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/escan.cpp000644 001750 001750 00000140545 11544160207 017430 0ustar00synthsynth000000 000000 #include "kstmath_export.h" #ifdef Q_CC_MSVC #define strdup _strdup #endif #line 4 "escan.cpp" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) //#define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); KSTMATH_EXPORT YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define yywrap() 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 29 #define YY_END_OF_BUFFER 30 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[44] = { 0, 0, 0, 0, 0, 30, 28, 27, 29, 6, 22, 7, 24, 25, 20, 18, 26, 19, 21, 1, 1, 11, 15, 13, 2, 4, 5, 23, 8, 3, 17, 9, 0, 0, 1, 12, 16, 14, 2, 10, 1, 0, 1, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 1, 1, 1, 5, 6, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 1, 17, 18, 19, 1, 1, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 22, 1, 23, 24, 1, 1, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1, 25, 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, 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 } ; static yyconst flex_int32_t yy_meta[26] = { 0, 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 } ; static yyconst flex_int16_t yy_base[45] = { 0, 0, 0, 53, 52, 54, 57, 57, 57, 35, 57, 46, 57, 57, 57, 57, 57, 57, 57, 13, 22, 33, 32, 28, 7, 57, 57, 57, 11, 57, 57, 57, 14, 21, 0, 57, 57, 57, 19, 57, 26, 29, 33, 57, 31 } ; static yyconst flex_int16_t yy_def[45] = { 0, 43, 1, 44, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 20, 43, 43, 43, 43, 43, 43, 43, 43, 0, 43 } ; static yyconst flex_int16_t yy_nxt[83] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 6, 18, 19, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 32, 38, 38, 40, 40, 41, 29, 41, 33, 32, 39, 34, 34, 38, 38, 40, 40, 33, 42, 42, 37, 33, 42, 42, 36, 35, 31, 30, 43, 8, 8, 5, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43 } ; static yyconst flex_int16_t yy_chk[83] = { 0, 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, 19, 24, 24, 32, 32, 33, 44, 33, 19, 20, 28, 20, 20, 38, 38, 40, 40, 20, 41, 41, 23, 40, 42, 42, 22, 21, 11, 9, 5, 4, 3, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "escan.l" #line 4 "escan.l" #include #include #include #include "eparse.h" #include "eparse-eh.h" int bracketCount = 0; char dataSpec[1024]; char *dataSpecPtr; //void yyerror(Kst::ObjectStore *store, const char *s); #define YY_DECL int yylex(Kst::ObjectStore *store) #line 506 "escan.cpp" #define INITIAL 0 #define DATA 1 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #ifndef Q_WS_WIN32 #include #endif #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * in_str ); FILE *yyget_out (void ); void yyset_out (FILE * out_str ); int yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif // static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 21 "escan.l" #line 697 "escan.cpp" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 44 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 57 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 23 "escan.l" { yylval.number = atof(yytext); /*printf("Found a number %.15f\n", yylval.number);*/ return T_NUMBER; } YY_BREAK case 2: YY_RULE_SETUP #line 30 "escan.l" { yylval.data = strdup(yytext); /*printf("Found an ID [%s]\n", yylval.data);*/ return T_IDENTIFIER; } YY_BREAK case 3: YY_RULE_SETUP #line 36 "escan.l" { switch (*yytext) { case '[': ++bracketCount; *dataSpecPtr = *yytext; ++dataSpecPtr; break; case ']': if (--bracketCount == 0) { *dataSpecPtr = 0; yylval.data = strdup(dataSpec); if (dataSpecPtr == dataSpec) { yyerror(store, "Empty data reference."); yy_flush_buffer(YY_CURRENT_BUFFER); BEGIN(INITIAL); return T_INVALID; } BEGIN(INITIAL); return T_DATA; } *dataSpecPtr = *yytext; ++dataSpecPtr; break; default: *dataSpecPtr = *yytext; ++dataSpecPtr; break; } } YY_BREAK case YY_STATE_EOF(DATA): #line 66 "escan.l" { yyerror(store, "Invalid data reference."); yy_flush_buffer(YY_CURRENT_BUFFER); BEGIN(INITIAL); return T_INVALID; } YY_BREAK case 4: YY_RULE_SETUP #line 73 "escan.l" { bracketCount = 1; dataSpecPtr = dataSpec; *dataSpecPtr = 0; BEGIN(DATA); } YY_BREAK case 5: YY_RULE_SETUP #line 80 "escan.l" { yyerror(store, "Unmatched ']'."); yy_flush_buffer(YY_CURRENT_BUFFER); return T_INVALID; } YY_BREAK case 6: YY_RULE_SETUP #line 86 "escan.l" return T_NOT; YY_BREAK case 7: YY_RULE_SETUP #line 88 "escan.l" return T_AND; YY_BREAK case 8: YY_RULE_SETUP #line 90 "escan.l" return T_OR; YY_BREAK case 9: YY_RULE_SETUP #line 92 "escan.l" return T_LAND; YY_BREAK case 10: YY_RULE_SETUP #line 94 "escan.l" return T_LOR; YY_BREAK case 11: YY_RULE_SETUP #line 96 "escan.l" return T_LT; YY_BREAK case 12: YY_RULE_SETUP #line 98 "escan.l" return T_LE; YY_BREAK case 13: YY_RULE_SETUP #line 100 "escan.l" return T_GT; YY_BREAK case 14: YY_RULE_SETUP #line 102 "escan.l" return T_GE; YY_BREAK case 15: YY_RULE_SETUP #line 104 "escan.l" return T_EQ; YY_BREAK case 16: YY_RULE_SETUP #line 106 "escan.l" return T_EQ; YY_BREAK case 17: YY_RULE_SETUP #line 108 "escan.l" return T_NE; YY_BREAK case 18: YY_RULE_SETUP #line 110 "escan.l" return T_ADD; YY_BREAK case 19: YY_RULE_SETUP #line 112 "escan.l" return T_SUBTRACT; YY_BREAK case 20: YY_RULE_SETUP #line 114 "escan.l" return T_MULTIPLY; YY_BREAK case 21: YY_RULE_SETUP #line 116 "escan.l" return T_DIVIDE; YY_BREAK case 22: YY_RULE_SETUP #line 118 "escan.l" return T_MOD; YY_BREAK case 23: YY_RULE_SETUP #line 120 "escan.l" return T_EXP; YY_BREAK case 24: YY_RULE_SETUP #line 122 "escan.l" return T_OPENPAR; YY_BREAK case 25: YY_RULE_SETUP #line 124 "escan.l" return T_CLOSEPAR; YY_BREAK case 26: YY_RULE_SETUP #line 126 "escan.l" return T_COMMA; YY_BREAK case 27: YY_RULE_SETUP #line 128 "escan.l" {} YY_BREAK case 28: YY_RULE_SETUP #line 130 "escan.l" { /*printf("Found char '%c'\n", yytext[0]);*/ yylval.character = yytext[0]; return T_INVALID; } YY_BREAK case YY_STATE_EOF(INITIAL): #line 137 "escan.l" { /*printf("yyterminate\n");*/ yyterminate(); } YY_BREAK case 29: YY_RULE_SETUP #line 142 "escan.l" ECHO; YY_BREAK #line 990 "escan.cpp" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 44 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 44 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 43); return yy_is_jam ? 0 : yy_current_state; } #if 0 static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } #ifndef __cplusplus #ifndef Q_WS_WIN32 extern int isatty (int ); #endif #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } #ifdef Q_WS_WIN32 b->yy_is_interactive = false; #else b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param line_number * */ void yyset_lineno (int line_number ) { yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 142 "escan.l" kst-2.0.3/src/libkstmath/palette.h000644 001750 001750 00000004723 11544160207 017437 0ustar00synthsynth000000 000000 /******************************************************************************* * * * copyright : (C) 2010 C. Barth Netterfield * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * *******************************************************************************/ #ifndef _PALETTE_H #define _PALETTE_H #include #include #include "kstmath_export.h" namespace Kst { typedef QHash PaletteData; const unsigned int maxColorTableSize = 2048; const QString DefaultPalette("Kst Grayscale"); class KSTMATH_EXPORT Palette { public: /** * @returns string list of avalible palettes */ static QStringList getPaletteList(); Palette(); Palette(const QString &paletteName); virtual ~Palette(); void changePaletteName(const QString &paletteName); QString paletteName() const {return _paletteName;} int colorCount() const {return _count;} /** * Returns the color corresponding to colorId. * It truncates to max or min _color if colorId is out * of bounds, so bounds checking is not necessary in the * calling function. * @returns the QColor */ QColor color(const int colorId) const{ if (colorId<0) { return _colors[0]; } else if (colorId>=_count) { return _colors[_count-1]; } else { return _colors[colorId]; } } /** * Returns the rgb value for the color corresponding to colorId. * It truncates to max or min _rgb if colorId is out * of bounds, so bounds checking is not necessary in the * calling function. * @returns the QColor.rgb(). */ QRgb rgb(const int colorId) const{ if (colorId<0) { return _rgb[0]; } else if (colorId>=_count) { return _rgb[_count-1]; } else { return _rgb[colorId]; } } private: QColor *_colors; QRgb *_rgb; QString _paletteName; int _count; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/dataobject.h000644 001750 001750 00000016364 11544160207 020105 0ustar00synthsynth000000 000000 /*************************************************************************** dataobject.h: base class for data objects ------------------- begin : May 20, 2003 copyright : (C) 2003 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAOBJECT_H #define DATAOBJECT_H #include "curvehint.h" #include "string_kst.h" #include "object.h" #include "objectlist.h" #include "vector.h" #include "matrix.h" #include "kstmath_export.h" #include #include class QXmlStreamReader; class QXmlStreamWriter; namespace Kst { class DataObject; class Relation; class DataObjectConfigWidget; typedef SharedPtr DataObjectPtr; typedef ObjectList DataObjectList; typedef QMap DataObjectDataObjectMap; class KSTMATH_EXPORT DataObject : public Object { Q_OBJECT public: //enum Kind { GenericPlugin, PrimitivePlugin, FitPlugin, FilterPlugin }; virtual void attach(); // These static methods are not for plugins to use static void init(); static void cleanupForExit(); static void initPlugins(); /** Returns a list of object plugins found on the system. */ static QStringList pluginList(); static QStringList dataObjectPluginList(); static QStringList filterPluginList(); static QStringList fitsPluginList(); // static QWidget* pluginWidget(const QString& name, ObjectPtr objectPtr = 0, VectorPtr vector = 0); static DataObjectPtr createPlugin(const QString& name, ObjectStore *store, VectorPtr vector); static DataObjectConfigWidget* pluginWidget(const QString& name); static DataObjectPtr createPlugin(const QString& name, ObjectStore *store, DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true); static QString pluginDescription(const QString &name); static int pluginType(const QString &name); virtual const QString& typeString() const { return _typeString; } virtual QString propertyString() const = 0; virtual const QString& type() const { return _type; } virtual int sampleCount() const { return 0; } // If you use these, you must lock() and unlock() the object as long as you // hold the reference const VectorMap& inputVectors() const { return _inputVectors; } const VectorMap& outputVectors() const { return _outputVectors; } VectorMap& inputVectors() { return _inputVectors; } VectorMap& outputVectors() { return _outputVectors; } const ScalarMap& inputScalars() const { return _inputScalars; } const ScalarMap& outputScalars() const { return _outputScalars; } ScalarMap& inputScalars() { return _inputScalars; } ScalarMap& outputScalars() { return _outputScalars; } const StringMap& inputStrings() const { return _inputStrings; } const StringMap& outputStrings() const { return _outputStrings; } StringMap& inputStrings() { return _inputStrings; } StringMap& outputStrings() { return _outputStrings; } const MatrixMap& inputMatrices() const { return _inputMatrices; } const MatrixMap& outputMatrices() const { return _outputMatrices; } MatrixMap& inputMatrices() { return _inputMatrices; } MatrixMap& outputMatrices() { return _outputMatrices; } virtual PrimitiveList inputPrimitives() const; PrimitiveList outputPrimitives(bool include_descendants = true) const; virtual void load(const QXmlStreamReader& s); virtual void save(QXmlStreamWriter& s); virtual int getUsage() const; virtual void readLock() const; virtual void writeLock() const; virtual void unlock() const; virtual bool isValid() const; virtual const CurveHintList* curveHints() const; virtual void deleteDependents(); virtual DataObjectPtr makeDuplicate() const = 0; virtual void replaceInput(PrimitivePtr p, PrimitivePtr new_p); virtual bool uses(ObjectPtr p) const; //These are generally only valid for plugins... const QString& name() const { return _name; } const QString& author() const { return _author; } const QString& description() const { return _description; } const QString& version() const { return _version; } const QString& library() const { return _library; } void showDialog(bool isNew = true); protected slots: virtual void showNewDialog() = 0; virtual void showEditDialog() = 0; protected: DataObject(ObjectStore *store); virtual ~DataObject(); double *vectorRealloced(VectorPtr v, double *memptr, int newSize) const; //The plugin infrastructure will read the desktop file and set these //Other objects that inherit can set the ones that apply if desired... void setName(const QString& str) { _name = str; } void setAuthor(const QString& str) { _author = str; } void setDescription(const QString& str) { _description = str; } void setVersion(const QString& str) { _version = str; } void setLibrary(const QString& str) { _library = str; } virtual void writeLockInputsAndOutputs() const; virtual void unlockInputsAndOutputs() const; VectorMap _inputVectors; VectorMap _outputVectors; ScalarMap _inputScalars; ScalarMap _outputScalars; StringMap _inputStrings; StringMap _outputStrings; MatrixMap _inputMatrices; MatrixMap _outputMatrices; QString _typeString, _type; CurveHintList *_curveHints; virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; private: QString _name; QString _author; QString _description; QString _version; QString _library; private: static QSettings settingsObject; static QMap url_map; static void scanPlugins(); }; class KSTMATH_EXPORT DataObjectConfigWidget : public QWidget { Q_OBJECT public: DataObjectConfigWidget(QSettings*); // will be reparented later virtual ~DataObjectConfigWidget(); virtual void setupFromObject(Object* dataObject); virtual void setupSlots(QWidget* dialog); virtual void setVectorX(VectorPtr vector); virtual void setVectorY(VectorPtr vector); virtual void setVectorsLocked(bool locked = true); virtual bool configurePropertiesFromXml(ObjectStore *store, QXmlStreamAttributes& attrs); void setInstance(DataObjectPtr inst); DataObjectPtr instance() const; virtual void setObjectStore(ObjectStore* store); public slots: virtual void load(); virtual void save(); protected: QSettings *_cfg; private: friend class DataObject; }; } Q_DECLARE_METATYPE(Kst::DataObject*) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/eparse.y000644 001750 001750 00000013546 11544160207 017304 0ustar00synthsynth000000 000000 %{ #include #include #include #include #include "enodefactory.h" #include "eparse-eh.h" extern int yylex(Kst::ObjectStore *store); void *ParsedEquation = 0L; %} %parse-param { Kst::ObjectStore *store } %lex-param { Kst::ObjectStore *store } %union { char *data; double number; void *n; /* tree node */ char character; } %token T_NUMBER T_IDENTIFIER T_DATA T_OPENPAR T_CLOSEPAR T_COMMA T_INVALID %left T_LOR %left T_LAND %left T_OR %left T_AND %left T_EQ T_NE %left T_LT T_LE T_GT T_GE %left T_ADD T_SUBTRACT %left T_MULTIPLY T_DIVIDE T_MOD %left T_NOT %nonassoc U_SUBTRACT %right T_EXP %start WRAPPER %% WRAPPER : { $$ = 0L; yyClearErrors(); ParsedEquation = 0L; } PRESTART { $$ = ParsedEquation = $2; if (yyErrorCount() > 0) { DeleteNode($$); $$ = 0L; ParsedEquation = 0L; YYERROR; } } ; PRESTART : START { $$ = $1; } | /**/ { $$ = 0L; yyerror(store, EParseErrorEmpty); } ; START : BOOLEAN_OR { $$ = $1; } ; BOOLEAN_OR : BOOLEAN_OR T_LOR BOOLEAN_AND { $$ = NewLogicalOr($1, $3); } | T_LOR error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | BOOLEAN_AND { $$ = $1; } ; BOOLEAN_AND : BOOLEAN_AND T_LAND COMPARISON { $$ = NewLogicalAnd($1, $3); } | T_LAND error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | COMPARISON { $$ = $1; } ; COMPARISON : COMPARISON T_LT EQUATION { $$ = NewLessThan($1, $3); } | COMPARISON T_LE EQUATION { $$ = NewLessThanEqual($1, $3); } | COMPARISON T_GT EQUATION { $$ = NewGreaterThan($1, $3); } | COMPARISON T_GE EQUATION { $$ = NewGreaterThanEqual($1, $3); } | COMPARISON T_EQ EQUATION { $$ = NewEqualTo($1, $3); } | COMPARISON T_NE EQUATION { $$ = NewNotEqualTo($1, $3); } | T_LT error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | T_GT error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | T_LE error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | T_GE error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | T_EQ error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | T_NE error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | EQUATION { $$ = $1; } ; EQUATION : EQUATION T_ADD TERM { $$ = NewAddition($1, $3); } | EQUATION T_SUBTRACT TERM { $$ = NewSubtraction($1, $3); } | EQUATION T_OR TERM { $$ = NewBitwiseOr($1, $3); } | EQUATION T_AND TERM { $$ = NewBitwiseAnd($1, $3); } | TERM { $$ = $1; } | T_OR error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | T_AND error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } ; TERM : TERM T_MULTIPLY NEG { $$ = NewMultiplication($1, $3); } | TERM T_DIVIDE NEG { $$ = NewDivision($1, $3); } | TERM T_MOD NEG { $$ = NewModulo($1, $3); } | T_MULTIPLY error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | T_DIVIDE error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | T_MOD error { yyerror(store, EParseErrorTwoOperands); $$ = 0L; } | NEG { $$ = $1; } ; NEG : T_SUBTRACT NEG %prec U_SUBTRACT { $$ = NewNegation($2); } | T_NOT NEG { $$ = NewNot($2); } | T_NOT error { $$ = 0L; yyerror(store, EParseErrorRequiresOperand); } | EXP { $$ = $1; } ; EXP : EXP T_EXP EXP { $$ = NewPower($1, $3); } | EXP T_EXP error { DeleteNode($1); $$ = 0L; yyerror(store, EParseErrorTwoOperands); } | EXP T_EXP /**/ { DeleteNode($1); $$ = 0L; yyerror(store, EParseErrorTwoOperands); } | T_EXP error { $$ = 0L; yyerror(store, EParseErrorTwoOperands); } | ATOMIC { $$ = $1; } ; ATOMIC : T_OPENPAR BOOLEAN_OR T_CLOSEPAR { $$ = $2; ParenthesizeNode($$); } | T_OPENPAR error { yyerror(store, EParseErrorMissingClosingParenthesis); $$ = 0L; } | T_IDENTIFIER { $$ = NewIdentifier($1); } | T_DATA { $$ = NewData(store, $1); } | T_IDENTIFIER T_OPENPAR T_CLOSEPAR error { yyerror(store, EParseErrorNoImplicitMultiply); free($1); $$ = 0L; } | T_IDENTIFIER T_OPENPAR T_CLOSEPAR { $$ = NewFunction($1, NewArgumentList()); } /* | T_IDENTIFIER T_OPENPAR ARGUMENTS error { yyerror(store, EParseErrorMissingClosingParenthesis); DeleteNode($3); free($1); $$ = 0L; } */ | T_IDENTIFIER T_OPENPAR ARGUMENTS T_CLOSEPAR error { yyerror(store, EParseErrorNoImplicitMultiply); DeleteNode($3); free($1); $$ = 0L; } | T_IDENTIFIER T_OPENPAR ARGUMENTS T_CLOSEPAR { $$ = NewFunction($1, $3); } | T_IDENTIFIER T_OPENPAR error { yyerror(store, EParseErrorMissingClosingParenthesis); free($1); $$ = 0L; } | T_NUMBER { $$ = NewNumber($1); } | T_NUMBER error { yyerror(store, EParseErrorNoImplicitMultiply); $$ = 0L; } | T_INVALID { yyerrortoken($1); $$ = 0L; } | T_OPENPAR T_CLOSEPAR { yyerror(store, EParseErrorEmptyParentheses); $$ = 0L; } ; ARGUMENTS : ARGLIST { $$ = $1; } ; ARGLIST : ARGLIST T_COMMA ARGUMENT { if ($1 && $3) { AppendArgument($1, $3); } else { DeleteNode($1); DeleteNode($3); $1 = 0L; } $$ = $1; } | ARGUMENT { if ($1) { $$ = NewArgumentList(); AppendArgument($$, $1); } else { $$ = 0L; } } | ARGLIST T_COMMA error { $$ = 0L; DeleteNode($1); yyerror(store, EParseErrorEmptyArg); } | {} /**/ T_COMMA ARGUMENT { yyerror(store, EParseErrorEmptyArg); DeleteNode($3); $$ = 0L; } ; ARGUMENT : START { $$ = $1; } ; %% kst-2.0.3/src/libkstmath/enodefactory.h000644 001750 001750 00000004334 11544160207 020461 0ustar00synthsynth000000 000000 /*************************************************************************** enodefactory.h ---------- begin : Feb 12 2004 copyright : (C) 2004 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ENODEFACTORY_H #define ENODEFACTORY_H #define CreateNodeBinary(x) void *New##x(void *left, void *right); #ifdef __cplusplus namespace Kst { class ObjectStore; } //extern "C" { #endif CreateNodeBinary(Addition) CreateNodeBinary(Subtraction) CreateNodeBinary(Multiplication) CreateNodeBinary(Division) CreateNodeBinary(Modulo) CreateNodeBinary(Power) CreateNodeBinary(BitwiseAnd) CreateNodeBinary(BitwiseOr) CreateNodeBinary(LogicalAnd) CreateNodeBinary(LogicalOr) CreateNodeBinary(LessThan) CreateNodeBinary(LessThanEqual) CreateNodeBinary(GreaterThan) CreateNodeBinary(GreaterThanEqual) CreateNodeBinary(EqualTo) CreateNodeBinary(NotEqualTo) void *NewData(Kst::ObjectStore *store, char *name); void *NewIdentifier(char *name); void *NewFunction(char *name, void *args); void *NewArgumentList(); void *NewNumber(double n); void *NewNot(void *n); void *NewNegation(void *n); void AppendArgument(void *list, void *arg); void DeleteNode(void *n); /* WARNING: this does evil things. will cause a crash if we ever do MI in the tree */ void ParenthesizeNode(void *n); #ifdef __cplusplus //} #endif #undef CreateNode #endif /* vim: ts=2 sw=2 et */ kst-2.0.3/src/libkstmath/objectfactory.cpp000644 001750 001750 00000003533 11544160207 021170 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "objectfactory.h" #include #include namespace Kst { static QMap *factories = 0; void cleanupObjects() { foreach (ObjectFactory *f, *factories) { delete f; } delete factories; factories = 0; } ObjectFactory::ObjectFactory() { } ObjectFactory::~ObjectFactory() { } void ObjectFactory::registerFactory(const QString& node, ObjectFactory *factory) { if (!factories) { factories = new QMap; qAddPostRoutine(cleanupObjects); } factories->insert(node, factory); } void ObjectFactory::registerFactory(const QStringList& nodes, ObjectFactory *factory) { foreach (const QString n, nodes) { registerFactory(n, factory); } } DataObjectPtr ObjectFactory::parse(ObjectStore *store, QXmlStreamReader& stream) { if (!factories) { return 0; } ObjectFactory *f = factories->value(stream.name().toString()); if (!f) { return 0; } return f->generateObject(store, stream); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstmath/dataobjectplugin.h000644 001750 001750 00000004222 11544160207 021312 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAOBJECTPLUGIN_H #define DATAOBJECTPLUGIN_H #include #include #include "sharedptr.h" #include "dataobject.h" #include "dataplugin.h" namespace Kst { class ObjectStore; class DataObjectPluginInterface : public PluginInterface { public: enum PluginTypeID { Generic, Fit, Filter }; virtual ~DataObjectPluginInterface() {} virtual DataObject *create(ObjectStore *store, DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const = 0; virtual DataObjectConfigWidget *configWidget(QSettings *settingsObject) const = 0; virtual PluginTypeID pluginType() const = 0; }; class BasicPluginInterface : public DataObjectPluginInterface { public: virtual ~BasicPluginInterface() {} virtual QStringList inputVectorList() const = 0; virtual QStringList inputScalarList() const = 0; virtual QStringList inputStringList() const = 0; virtual QStringList outputVectorList() const = 0; virtual QStringList outputScalarList() const = 0; virtual QStringList outputStringList() const = 0; }; typedef ObjectList DataObjectPluginList; } Q_DECLARE_INTERFACE(Kst::DataObjectPluginInterface, "com.kst.DataObjectPluginInterface/2.0") Q_DECLARE_INTERFACE(Kst::BasicPluginInterface, "com.kst.BasicPluginInterface/2.0") #endif kst-2.0.3/src/images/kst_gfx_polyline.png000644 001750 001750 00000001425 11544160207 021015 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDAT8ke_9g-9j9FI)~QuӅ؅1 ƛA*DX ,el9sypilngoxn6#7T7o|# @~,yd;Ya"<šƛ?X*#a̮^|=St*w.ͶAl;o-c&T})|B.4T&=+o;܍y _@G[z;[F؁mFq˗6i^;wjۤ%mw3xVS`75CclU,Ͻuw1ol[^KYKX8P3*Mgr> ؜z@˺7Ncl3s~O<p?i,,ĺ' Ow+ݖv a4 s}bXlDzxy=4N "b-K_~Ş~{KW,׏w`oޅ<?+ O#,ᠮ;56Ty:r Sy%P[I&$|$ yc=KvEs:^ԉI>.`gVF?.*by{ c+X5n|ۏއ?|>kbHI a-c'}׽̤ 1^tRIENDB`kst-2.0.3/src/images/kst_error_1.png000644 001750 001750 00000000362 11544160207 017666 0ustar00synthsynth000000 000000 PNG  IHDRaIDATœ@ D_ф~ _/ `B]&sئ3NMA$ ϲwJ¬Pˬ׿Yr/UD%RY@#yr*0|d|2Me 4Ho N;Zbp[@>5CƸf1FZqWV޸L:?kL5/IENDB`kst-2.0.3/src/images/kst_gfx_sharedaxisbox.png000644 001750 001750 00000001231 11544160207 022021 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sRGBbKGD pHYs  tIME R'+IDAT8OKTQ3OZCBALhE*+NM@:}ܵkAQl()Hn`{n99{i1c\B]>s8Y .4k/1nz\.ui<ʎd ,~3& SˌP<~t}blT A%xv&RUr@X"_66Fܫ*UĒ%~A X6`%N3Kop\ |*6Fk>=(p-Նњ/R*~Ŧ\ Hu FNV` #HRq\8lْB$y("++k\, q׳qo[n%UU}5e ccctr<%tnnի'pdddO!oG.o2:ucC}[Bz{{y8 %Lc1Us~oX "*'SF~})E###ˡ!zemcL{7M2}|W#։b*JO~,HO^=)EzY@$>yR/w}@F(x1i˷/ݽ]sb ycZdee!r|)jt[Xrl_1ϱddqFvԄ# x8='!k2Yc]Å5%h\lH[[>obAi6]ޏH)_2BoRgHEQXrĂl.gniܿݻw҂㡢h4ӧOv`6Ν;9.=>W\p9sdJKK)//jƿfNMM ncZCUUb8QĀk^zםпc=[q>֒Yl>pų{LEG!D:(zKaTM[o&3 L/\14k)I +<% . ?o#,GU_(Zyܣ`/C'M:ziy`Hxw8u )*"*>}/]+il{^Qr/\X {K %FBV ;qUuX+sTCR3Nٞo}C`D~;Ǿ `7^]'l,,LbmMo\ H)0ce~"η%a;77s90CV95P8`\'`.Y-<#ƍ;_= +<|.׀wզiQE#۵_wuO ?m2Hk-4[-{ALjcG8yHO=jHlsOSu/`Sih US^~ݣIENDB`kst-2.0.3/src/images/kst_quickcurves.png000644 001750 001750 00000001137 11544160207 020662 0ustar00synthsynth000000 000000 PNG  IHDRĴl;&IDATx=n0?9€\N  i K@ )r O..@1)dR?Vn@$7o Gx5ƨp^y}}%1eY7tRsgvUejf;cU"1f~z464pIDH8tzPAUEsNGy[{'//`,2.23]f."**bZemkbl̡h{]T(3u&Ӂn}|n\Ԣ(͢Ԓ {UEEW].euݤcSY>HM!2B"WU5)>?9ގZ;O6~ chRٺ.zgz;JR87Mzi1G酴-MmP9SIGiq2R }>CT%[fZruU=]1NQw8~j۶5!SU!7­Oi^.s<˝sjnN@IENDB`kst-2.0.3/src/images/kst.ico000644 001750 001750 00000010276 11544160207 016230 0ustar00synthsynth000000 000000   ( @ @AA466  {||HKK ""K999QVV),-t<==hjkghhimlKRQZbc:AB@JJITUITUITTHSTHSTHRSGRS,34VVVMTRkyFOLpxwt\ijITUYYYGSPT][w@JJ6@?BNMITTIIIRUUTa^?HFS\\?CCHSTNNNptsfyt=GDaooetu7@@.```?JILYYHST,===U`ҧEP,9SZxz*1/BMMooorrrtG\Tc1Aɂѳnr}$,V)-$)*x000j666s@VQc9MP`窲{ffpnoP\] ]]]~~~ZZZFKK:@A"""@^^^dkkxMQQNNNccciiiYYYnnnbbbqww]``TTTrrrcccgggZZZX[[abcAAAwwwZZZQQQsssw{{cdd wwwWV^^^wwwGGGHHH~eee444x;:PMlllbbbpsseeecccWWWlmmddd'''Nbbb`]tq>: YWfffdddSSS-*62ON&$YYYAAhZYccc&ooovvv*&;8&#-*ac_]ooo"bbb222{cccooohhtbbb###@NNNxxx```JJDClaaaAAAwwwbbbzzaaa 444wcccggguuuYYYNNN___gggRRRaaaeeennn``````AAAwwwwwweeeVVV~~~zzzXXXWWW|||}}}}}}}}}~~~~~~???999hhh&,,,]YYYSSS'III?kst-2.0.3/src/images/kst_gfx_line.png000644 001750 001750 00000001053 11544160207 020106 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDAT81kSasnD[ v !S&EdhIFߑ)"ZRpQuih{-R4mzs}9@( J$s+ЫEW53yD˘Iae`@ ʼn^H/*SM8fnDe!:#J -HV\]~KQծn/qƻ=Zhu7sv -@%gz)=hw,pzqϣA8-;GVa:KJ)`yax`y h7qz9|TqvT/8ɯ0̗Z[ &g~mۓGY֨{xkxmiyђUޑ}&;˯ 7s|@Pspǝ>}tj ZL 0GIENDB`kst-2.0.3/src/images/document-save-as.png000644 001750 001750 00000002321 11544160207 020604 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<NIDATxڵmlE{* J[l b@LK/Z*؊Zb%! /@BP 1AH  UFP- \KKzwۻٻu6Yf63>8t]`ieUO ȱm}s=N%~C((J 7[عm H`NCC]ݔc~\ ]ะ0b3veeb{#yi:!( Wҭ D.1԰g{W+oM_&<Ӏ?\D$*k]Op,LWC dYú Rlm0XZC$GoX茅g; TmcaS-o9+9_U$` `9=13i?:#&uJ.=qgzV,QXE (3y[lfױs3ޢy&xf*65A!I\Ī-R>EF~&ol%A&+ޱ,sBV^⦪du]2nL0$28"R̚ZH<4iΟ"+/;n~LKNK/OSiڗjG͵YHE D~*Sn1M|guR\m s]_ҥ%0<z.T@'bɛk{6FU'i8bI0׮w*E1u믱8%5Fv.^%8~?X uW1+GQդ V :ƼT7.M(FU|lSxK ϴ Fr4)%C\w.t¡/<<ҙB_PРgC[,w}S4:oC##C!®1c.8YO4S0OQFIoi*Mc'>l늌Ky_B$ XBE FUgܼKr?YßK=]:3:|Q"k@hYHS87bώs2$ @UQUl--y4OA~"_"ݶȰ-sa뢪"=[ &p"s?lZ4IENDB`kst-2.0.3/src/images/kstplot.png000644 001750 001750 00000021561 11544160207 017140 0ustar00synthsynth000000 000000 PNG  IHDRK IDATxٶ8 P՝_ _@?3I2c@ J'H`(@`(@`(@`(@w}_dТƋ!]$ =[{,P<Hyugk9+^🫟8|ϧ\v)0i~8YϿ^Nm3$#%?+,k*I<a@OaB"Oazw P ~j~"+f<Ʈ5e/SЮ!t% MYϩ0mۻ"Axu[ȑR6T;0oʧk3LcA)+| ]?b/lJyt Ȧ {e`Tk𓪭J _#ٔ!N *%@ \ }?t2l* z9tT.A3hg ֥j,X [hcba=XɗR&nO5q'~/!0# :/p=l*2|xdŶ"]rY{t H1n.þONdwW~2mO*Iu8j98LʅztH0w3𔹌͹To>N+lsa7}%5~&~wӯlt+%.|p|]NEhvH#]IJbvy t] CY`KUU<@аFk!u)Y~@g"qJGb,a<ܭ[^uko#Y\V].lmkYUVGjӯû\l"3+a~5h 0R);bGtg/Ed5&ZbdCVzwNdnv@xr8G%JKTM4oP29k/JZZCwQ Οƍ;I SQ{{8No~ǓgfՖho>ϓߒGTAC‰O:¶B kt73]QANXN"CMЀJ(C)EC[`xpV1 t:| j ?`h^ݹ$b:Bh[J^Fa 2)_1,zR+iYZ0 AX2q#4Gh*GG؆CW`أ  MݐtcFi-Kڤ7І 6)#a]nYV;>k kŊ< |d=14Тpc50o55ِ j1ÊٜK'7R60\y}'LA#ldq 5tF=DyϷPOq)U8zT;e4ZCS}&nEW`*.m8>t` c%ggQrƜp<8}C.e±MppE7r$NL%ZA??; Ԙ_| I2ݭK,;#x09M}O_I^}Lg D<߆C^"I;7Ǟe8 k$,abZ.G>9tv,F¢,`]?CdBo7ؑww[Lp~`7W)zz19:=VyFXÏuؔD^N_3"):Ov֪$蝹Mɛdk.pץ58T ^sG@!ձİsa.tY^0ͳVVf!G S~~{wj*ӫwy󸿎\0r'o G)җ6֣襻_AtT׭]wg^.3%‰f ەk[W8ٔqjO.nԯ-нt+1VNT쐟a(N ^ }K)f=]{ o06}bߝ_>WՖ8eJ ՓI끦FwR mZlw_Y+g~7EѻPE%`x+*D 4\fHFnczx%؞[AUqkl.0m,mNAb<{?vX2ڒG*)>Vi7aզjLG(CW^.G?rYM?ۿS+dq߱nojr5:z"͊H9/ :]É{%U)5~]UfM[r0-ҏZAqI~t{fJOdz*Ld w^O7b4poD Z}T|SkK k4޽0JaIIu%!,w>~\g-(Y+hxow[wYrxwj5EgJ {=^so^5I020Nΰ9nXFW.;Hd;gCdr?M:|^V{!tևkWNZrdXEB:S^۟aXYσ|l c))0^ ԾÏl0eK/3[\@\f1:_WM6%P{ ~u]ٳ!uEH2,+Ğ de WGq5(Ph5G*h#aA\3ޘs0~5C%/qְ}!Gzp q#aPx{} _kǻxU@Gk^wW2Q%uktqFz8Hyt 6P:R}G`:"a-.7Th} P`N.j, V`r!o%Ħ3?V&[Zƈ8iJiK,C\J>eU穎MVkS~V2~s y7M[1x,}ðwcJIO4oq%R/SصSXgjj]x2Y!%P@xNaq🫟/9l}3n;PRv~@n}S?Q[!]$ qw UVx]6&[w} uíDK) [g _!-r٫\|GJog3w~cpRܚVi:Yxv-_9/,93[m"KM$*w~}+LfTgqؗ SיIʸ%B Ei<YC}7_6ۮ+e"+?ѕ-w'){UZH|d7E!@0@"m4/*]v=f>yY{sa7nej y6a#)ij…zgpYx;,SoY__.9-3+&nTЭ!0pxDS6K=-ofU^Ve,WF~UҝSPƁиn#̹`(@`(@`(@`(@`(d &t+BH-6R=%q$ǭM[a|ɔO#=?,Ͽ2!i,RHWTT{&JVޜ;_g*h]GYof_^#ժW,kM6:0 @0 @0P~W #,B\J?R_*%@0 @0`6$ nHWu7$]B/ 04TA(V; C+>s rXPƂ,}-g*J]ؒ^!÷wn9彯wpeG| @0P>^GjK# u?]:!?ɳWtCTij#w<k#+;`5=<(H7Y-*!ˬԫ Plg6O0M腸!U蟿y0  P  ZSglfFw+^KiE K7$ ,KytRꟵ"!.%P P /X;,'d LGB|=/e CQBLzd w!UPP)CQ$FXPf i}`gg*aLucX +w?{shz\PTPzsΗe]ؒPNo^v]7+hz!9kig*0 Vn$$@ƂJXPǂ q#n!B\wtH  ȦB8ݐ>(z"PP:b(JTCQ穂`(@+hVo(k04&{/k0(R0x P-g\i3輪Sw P+X c,wKO^6HG\ZWR5 jG/>ў tKthB/tC E 3)ۋ5kEԜGYJ ii^a4%TP\o  [iP x d ̆B8!}3Mu .} ( ZQB"RƂwS dSqUOG%AO$&f<"@0 @a"|W;pܞ6%-tRE1ҭ^|j06>sd(PجYKXP"kZJo%=w cV!*ԩp`+@ _Y%8|W){Yrז~?אR|6{ٵmDF/:gB(r\XuC'%^vGܵ]oB_rNx\ il5w@XNZCYpArzu ِ"1[X 3EN\(\`K]+tÚd2Q \ɉsaj..>O4JmV~M"'tCpzNf_^#k]x>WA}?z*V>. FZ 5rOgY| о_û\[Ib#)auةڎl&՞ {Z&=/7wYl)7UytN۾GZ]򞾵ȯN)1YW3.\A {W唳S,*ʿ.Vץ$ Dl(`a70HXvX?YvwoٗFt,-Hi"DSh;JlmkH韼tL^Mi#ZM)lB+;uHCCQ.p7qbVnt6[<0)ǓIʵ ]ռ )CU?VܪӊֳZ?8'Thw*/SLmӇe/ʮwK^t:^M;@ZOлl>2; x@0 @0 @0 @0$ue! IENDB`kst-2.0.3/src/images/kst_newplot.png000644 001750 001750 00000001627 11544160207 020012 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<)IDAT8]lUw;Y--WBŤ m| F0$@L4"Q<$AyfƯ16ɚB۸lv~^#p{so{o ۦBu(h0#L|`_­ضmA&׍\t:M2 `w9P| QDo)] d.]ץ˲, 4[#::oqtɉ>Ntr2&_J|hxaЀHӆ;BN)v4nV8;[ek>T)R/=#G8DSPX,RLݷ=chhl6[lJcyt/@,COW x}_mJ󘟟'> ?6Λ[Ha@VkACmvKhB!t]I]|y}" ݸ9!×M*[6u J.U~;-٫ē1[lyR-p'/g~꧂_ B}ܡurAN}9Bac R8|);45~a9t]'9\7Elfzz6 J[} i5 M#v R >::8G 4M2rه޽뺸9oMaN5ˁ`jl[V50BLR*T`ݫbVfݣ]@xx9H?uibLIENDB`kst-2.0.3/src/images/kst_blank.png000644 001750 001750 00000000317 11544160207 017404 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDAT8͔ CrwQ@ IxtL|" Ip D^M{g &8Dsflb5Fe5tێ <$S:Zmb*ήтDҚԌm?;~ݬ]X7"q-H鮕T+N%fu#IENDB`kst-2.0.3/src/images/images.qrc000644 001750 001750 00000007436 11544160207 016713 0ustar00synthsynth000000 000000 kstplot.png plainplot.png kst.png kst_blank.png kst_changefile.png kst_changenpts.png kst_choosecolor.png kst_csdnew.png kst_curvenew.png kst_datamanager.png kst_datamode.png kst_datawizard.png kst_differentiatecurves.png kst_editplots.png kst_equationedit.png kst_equationnew.png kst_error_1.png kst_error_2.png kst_eventnew.png kst_gfx_label.png kst_gfx_arrow.png kst_gfx_ellipse.png kst_gfx_line.png kst_gfx_picture.png kst_gfx_polygon.png kst_gfx_polyline.png kst_gfx_rectangle.png kst_gfx_rounded_rectangle.png kst_gfx_layout.png kst_gfx_sharedaxisbox.png kst_gfx_breaklayout.png kst_graphics.png kst_histogramnew.png kst_imagenew.png kst_layoutmode.png kst_matrixedit.png kst_matrixnew.png kst_newplot.png kst_pluginnew.png kst_psdnew.png kst_quickcurves.png kst_quickpsd.png kst_scalaredit.png kst_scalarnew.png kst_stringedit.png kst_stringnew.png kst_vectoredit.png kst_vectornew.png kst_viewmanager.png kst_zoomtie.png kst_zoomx.png kst_zoomxy.png kst_zoomy.png no.png yes.png kst_rightarrow.png kst_leftarrow.png kst_uparrow.png kst_downarrow.png kst_bold.png kst_italic.png kst_reload.png application-exit.png document-open.png document-print.png document-save.png edit-redo.png edit-undo.png draw-bezier-curves.png document-save-as.png kbugbuster.png tab-close.png tab-new.png tools-wizard.png transform-move.png configure.png office-chart-area-stacked.png code-class.png resource-group.png draw-eraser.png image-x-generic.png dialog-information.png text-x-log.png document-export.png tied-zoom.png change-data-file.png data-manager.png kst_gfx_circle.png x-zoom.png y-zoom.png xy-zoom.png document-close.png page-previous.png page-next.png pause.png count-from-end.png read-to-end.png new-log-event.png save-vectors.png kst-2.0.3/src/images/image-x-generic.png000644 001750 001750 00000001655 11544160207 020403 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<*IDAT8Օ[hUgfvrͥiB쪩IZXi4XK"|P[(j|}Q/SK lK%K$BRM4lwwvvχ0˃yq?CֶPxKZT*-k`\D2WPJM8{yL8x?pxg@r"|( DzcPb 6HzmuF̡k;'.\H:,uY,% zvH%o.cze7IH)seQrqc/XI%SQ~9W"bG beP{uxܱR#\7k6q)<-w#55g21c4QF$әvM~mmwvL 1:D!FJR$ϓJ&C9&f㕗 WC_tF;++̔ѶF" 5tGALΔ7L 3}zoW?ro FYhD eoOύBRAF+kzjjI1?c], k5( (JM5( dO?Te]Vk@7) 9ɆNM>]cspKkՂ" K F d&3ӫ'6qZ#t켣譪R<3 {[O\(`(܅\՗{3ufBAZk PŢG9u6}$-vڶm"^5mOY JIENDB`kst-2.0.3/src/images/kst_graphics.png000644 001750 001750 00000001671 11544160207 020121 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDAT8Oh\U羙$i:&h4S-.ll"Y"*]rѸpaJb B+H("b?&$u&3of̽H34 o6wDU]gd,B?b/~Vb5#_5kSaYWDeG./?]Fd\Й.}+`0T߿M\WЛ_U8Nj[t8DPM]ɱ*8&J:oI37-/ك\_ 7&gBk$_uj|.uALR ??yzqVXkd=Da~in&x!Vj y,Fzic0`8ٙk;}TrGba an-ܘ\=y"F$R qff:[OW•cZcd`^IENDB`kst-2.0.3/src/images/kst_equationnew.png000644 001750 001750 00000001772 11544160207 020662 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8͕Oh\UͼdˌRMiZ,M;T]d#VEQluхE&*Ū͢ El-fB[-Fk$yyf$m҅\8=,F6#v$q󹼞?ºNo1l#fd޺~ Sv-E6#b2{)F4Ǝ&S~MJAG"f\^Kf$ tmқ͵o>!QPH̝O\ P=v',U-Ti DN.ٽ$+o"l/7$bnK2]% ^ҮokóּG'p^ݸN&uB,LB42c 7PUGÖ5.Zmrdkc{d/=ń*CAy4*ec:,]ѣxqvVugBva$ꍜPhxß~ˏVigsyzt]]3!6 ^U8Z@J~ӫYCbY/IJ(<3Њr\RT=׾\^j_Y߯pxzAxd2Q-ջ>jпmL lhqQm.(~n}"\4rWR)y6k]-8fUUb) ҮKU.`8D {EZ" $8R]M o?j9ʚIENDB`kst-2.0.3/src/images/kst_gfx_circle.png000644 001750 001750 00000002042 11544160207 020417 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDAT8OoU̼xlc;ICD뢔R.ԨQOT|JAb 6(!Rq,&!jEHo}G(̌t--hDy&A*/kLK՝k e?x|ꅄRbKD\$b0v/feegӲJ7?ixzhh&v~;w[6^ܮvƉ2{OV1xuL콙#?>rLt4]`=;L}~xܩYXw?Y޿Oƴ3citCp_ tPf_/]N-;MY 7jd&rqT[/BDI覞ѼQ>ipz+H Jy9Ci "(D9I bc?C I$&j8n8ұ83#<= @ ڽ@m{qMUXe 0;` &^5ΤжDpd%,yYJmmŅ1<  X ^Z_i?Ÿ.IFߓNd|VTUu՞n7-P ">9#g%+S8+L3uప#?ܼe={lƴu?|NLG! B4%jk[5mPb1oRs^0cHs/rBJ8^d/4oܨowJVm|0z|$.S3Q%D 0UY ,ijo>Pl=EIENDB`kst-2.0.3/src/images/pause.png000644 001750 001750 00000002002 11544160207 016542 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsItEXtSoftwarewww.inkscape.org<IDAT8Mh\U{ɋhbSBZ3"@7""u0̶Q7..ˀM@Wş5f2dC&q ݭ@A`w㥀#Fs ;~o?TxD!Xy|+/RbCk Ji~ȝ{ĭI~%{w,՗/W_\\1ܐI!hI)IƊ U<S\魼xRBy 9dJcڮeē~ś/ƟNNN`Xթ!}.ǵg|><5Ƴ~~cpƁ/|p3V/>M<<"Ͽ0tO*cD;J) r bm/ -N`XYsvhmȲ4#Ku$y |;XkJ=g!Y^8cR'ޙ3a ՚,P5"MqC&Ƶwerytvl-fV4)q㈏ji74%ˡch41Zn$Hz%qBF}u6C0Bd mH`?tp}ƘGG b 4gHe5$N`#< VC}WEbn{6cޟ~y=v[ WE)o1:U%h[k^Nv7X7p!,z`WZL5Zٗ\kG"[%L/{:$9?* ›pl `kk/YpIENDB`kst-2.0.3/src/images/plainplot.png000644 001750 001750 00000000656 11544160207 017444 0ustar00synthsynth000000 000000 PNG  IHDRĴl;uIDATxUm Nir s>tS*͇0fc$$Xۣa "Db"1iXLD*E4 NX5} +GɁ г[\-}fŋuIeR:~5"oA)BC4uaΝ l*A[vT "(% k:/#PQ\zV`|Imh"ճeak({bÖ}7X ԬόR:CBK9Cq) kJ$ WVh#Qb!r وlahWCW;6IW Tp[Y0p"c<7n) d}:|8 #9G+qռR'x[e͎=EX'LFib2_/EJZI fM#sqp476fNc&BJA*'CG- Ȃ$qY [Z[JvWámK';"aUGp&DU*l| aUO r[ :EM7n'AA!ʵۋ~>p#2FZARyUxRX=9An~"@IئtuͼV*s[٤tdl0?.ԁOmGG yIENDB`kst-2.0.3/src/images/kst_matrixnew.png000644 001750 001750 00000002033 11544160207 020330 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8[h\UuII&AP5FVmCR EHhVioT@E[J-uzB &1s2ˇxfx?쇳9^-Sx~23z)QUDD B{3eO\ >UTUQUi-L=4ϡHX"-+VT V&UȖe"Fq`CGM:ƋԞ`|Ϊc}x;7Oc@?BaCݢRoS%="qOyU@U)  :7sGē(P*p&mNQp0d}:cu9VGĵqEƺrǎC qoo=kJєăm&]IXqy]Z^]-h`Tl~)vK̃V-}y˪*Er^bSMU;55do;Q*qgtxw_ܷt=xXA>iϝlۆs].S_lHM+%`bx0ш%>}1D BmA()W[2ivSRMJv˿{R"DJeXURHr¶I+ 6NͿQ!lrbˊzxZ}nUSs_WiG(: ϨBMXMj9:p ru._6?)'rϯPX#x#-K;(k]]]% Z! ϡW# 뎊 n\08||rL +@(EpĊ ?|>;9k/* Ny&s[-6-;ܲsF>5MPGIlb-B'p8ihs[T*8u x`Zlmm DB ##~\&auuiNu(&ILNN( C[XGY2-#[g_a\01+++-ax#tw?a5ՏѤX..ED*Qjxv^@uB%hC Xa}Jiڭ  :mEWW9w5^g2)Ӭ(]ɑS7IU0 VAAA^7*0%* >ԥaIENDB`kst-2.0.3/src/images/kst_datawizard.png000644 001750 001750 00000002334 11544160207 020450 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<nIDAT8klUoo1ce 6q .3qY0"q!&a^!t^FaaH 3Vjv]o{A]qF“<9y]K|pױfr1{l W-\\/ gnaPD"ξg>Iڱ X tѠdi!!|dr(F3;wa&al篙Z˛FdYFW⊝7OillN0$jFY< >)4lKC)NK*/0 p8qݴӓ*[VY3̴raѸ́H)3M*”C8o/|с |B!~?faIE%5zr ;sԹgDS<6s?>&R._L__t:- m1~ 8d$♽74otf fkzZ|mP$/jQ|F1S8EQQfv{f^dZ:HBNa$Qc&ܸefP(DAAT*Ӊ!tڨ\6:>qw555k8s@GGu$@"HڑR|zmϞ=I` P^jggH$nݺ(e|;, ,Yt@%ܱ (8 RIENDB`kst-2.0.3/src/images/svg_icons/new_equation.svg000644 001750 001750 00000033213 11544160207 022140 0ustar00synthsynth000000 000000 image/svg+xml f(x) kst-2.0.3/src/images/svg_icons/zoomx.svg000644 001750 001750 00000037647 11544160207 020635 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/new-log-event.svgz000644 001750 001750 00000071766 11544160207 022342 0ustar00synthsynth000000 000000 i㸕(ݿBWda_n߰ݎǛwuT8+3C]տ@HQʥ%EBpxpOohI,7X7fu}{)v,~zݯWw>=<ܽ{_~)EO?byo߭S/Wr}_/߾>lopoyI޾9|>ͳY^o?ooҒk\[3!O~0M#&Vm@}~us"<נSrd7}sJ×(x7}=۷e#,5T̻0%.!P?~zO(9 ԏ?'W|-t=_gI49Sh>l oS IYN}K,B붐KVJq)&YR8\S!/ŀJ,E.3 09ԶM $'V3KSɴ% πui`çÏËG4#QQG,A1  `p|טό-V6 h"<8/.%BvWx_w77[6{HTA`tP(IQR 9$#KCPq Q{ MɂSmĠsLU߀ 4_J<=y %Cї̠R'_v-btp9}OK'nrRbp c)O =ۏIB*wi:Pvs)bt|_Iuͽ Isv(lw@r~Be@uRa1JM= _A8yʆx3|Xo@  K`wGfZgM0^8m;TgځX Z DZ 7dv 2;Gn*o6UJn#5ي40"{2[:3m"ff˙68(3m$iԉɎ*QK;5Yk=GDSx)TB -x܊%XI$Rd!ǀ IOI`@#mJH R[V3j{SƓ9B:!Q!LsIX*rLqL)җ`I_1"`4@8E)4=ŅSRE*]r!PJ5UG~J.B1f*0Kn61 ?3x#)I"&x~oVEHsEs՚c "ui.njKhա]b0$x_4-+lTp%8'K)$DҖRe\rފއ-0&Bq\?hCչG'|SVE*tqI'* t[aAs,u^0#<\Ow3eϱҗse|Y$h+MJP-_ʬ@'DL"RcXlVAR[PZm׻]xj2jLv\EZe*-jF3.jiv`OOT,Tr6WFc 2 ;9qO7IzƁղ/vBeSW[쿂0HN})( EswV cCeI2,HOU{ oܷobҎT7FԘh't:^eG0i5 /V( MJi,&u)~N+dU0j5ypF3f6^:KU0& WgڮWyhhXz  z R!VAo`%G EQ¡L,_K%gL~Ce'AYg?T=7&6!|44 pgG!7g(9C1цh*A fK\&ܯy zH<j6=xG¶mFl旤uG/jdɘΔ"sߗ_)DI&*`/R&ޟ=pTvM E-GFM e!+ApJT"_\ =# kj5s! nIN_@7€q7 XAJg<{?Sq?a?X9ϟJ$;ihKII$j7B/0C=~yND^r 79OХL@ cI ºLR!8fGlF3\EPcvd|KS,B !fgċ[@sVE0=+tTgc/qW6Wp2_h2~{Yp  V4vKJ$SLtʾ\Jp `. )HTXDyr0@`4Eje ޽+ ' !!I7!#M'LX\[Cn"Y M'Q:KQ&iOlg8.؛|DgO7C0WCFCP=y9Ū}K3fJd"]Lt?6/\]oȐ[ŔN7kNQs06?7'TY4/_}@OрD!rr+ WW")[-qЄs0^ *fRLT*N&X24uxi)c^? iM);t}JѱiMVO$_Q&hv<9+_ƹh՜ Mc0ɎV͙TRғr636z!z2`6КTW.5W.˥O?s/bbژ:p= 31ۜ\n!rQz f"8EW 7U 7/D^m\ra.bmOK/ 5H=2iG@glqI3N$glHaF-j v笧 |{LP1`kK "K7@nzKdrtX Y+vU| <-C-ǻ'Wc0K>cM4IXMyPQ aKv{1[(N5$ *dXrʇJl6OK4/ DnĔ |w 6 (XB[d KlX(NYx J'PŸ EkB] RbEleZiNg$]}WI[IdⅲHuaІ$^[&A1wdd-qn:|D^1NQh%XHC|mA_ I:!uUvhI8d#ܘ%:*Ey8UDZ *;hx +- ݢxۖYΊ)~~ZLBEbHװ_1#KjQoGv޶*90yamsӶ4@&I! !0Dd1Ui 3P]*;gfP̘vXcU8%)(TVu|FH?(IEO Ov,ճ ˔|x|7h^6m0Æx%KHh4-91]dž}[Y3ke%INY %2:~_$X%@0ڦ%L ('~lhhDE䋕ɹ\Ngh*e:uSXٍOVv q; 3Q PImc qmRi4b9aS#DP0R$^|pRO5LUİh-,@?QDʙ0û1I1,&#36kt[qE9m0&,qiVx{~m46fL5"[gxzն%q%s<)11?$kx5"I7Ņ l] =[$ jM>lD1n֌8pQf3iBδ#if-aJa!N :ǿNJtdR|>l1 ՆсVͩ)aXE cN jż/a'tH8ܩQ*-t-:M˧mՙM`" r )5pS<4F EFZب-&xłf\Jw)Yb>]R݄m-Vtx,3d)-zbX؏򐦲k;RDVaHnO~Fžr_M )=[R{#/1cuZ0%xrɷUrtE0ٿІ*@!{-7+߂m+L9;WAuw`?*xܢǿ Zr{S.9op qz|7**bY.u|`Ϊu&0KBض%O2-f9fU-:u8(2P;ZJ+Tp›MWV[/ QEC$#%~G-39 A7PǜVҞ^k sVg{k;? {r6*N,-%ݱ1;3&-@?naBkmBl`InLp'JfgƬdШd+wHu4Ш$6ۜ`̉rOnM ,0 mN0d'7&&0qg(&qls1'31#碍"B䒴qBSi Xm[ >GEDVT7 S!qيt4.)-\cx"RSS:osig|#lGv;);?xd &=x^j ;vqQOinwf;3/*568.&4&HUDv|ޝQɎj[Ev2(ٶ br,QeOi[Նu-eɅf7Z%AT2GL\ f mvk蜍xpct2ӌtD4ۜHk v[AsӐ,e1IމfSt)&6Pzkf .WINZBs1䇓;ʠBKe #Ԯ4(i%b7 j,0Zb7—iz]gW 2ܹ%y\UbQ/+DRmI_AVb={m&]*  G5 v-Фa*Q]r*ix VʸqJk`Ty朙21GA/`.|lJ^ocN0WcFE q.SvcOrmgs殂cܳrof$/OX\_[oΌ¼Ý}w!χ;ldîyVzZf7{Īwח-"M 񸓤1>bnʐDypRUsGb|{Y$N:H5N#P0Y"|04gA\LF`I#Ĭgz0YME`ikiĶ ?ؠMϯ0}(xJ@ -,$_ӟP'Ewz3B>Nt:iTp;a(PDPh@*Hܭvd*HK)I!;՛ ^̖.8[\@P9hvCR6Rr3T{t^ǿ?ɟFrVCFZ^`2ߍ"ޓ`Sz=jOmțƗTĎoB^r;@Sʫ̶w&;*d؃?wʀ2 ˕žP`s$%萙hrڛc5' ۡߜ$ޛH %oRuhkmɗCKOl'WolBhuByI\ZgƲڷJ80Q@=k33ShGÝf=a(ӄա}3(%$V &B͒!J \7_|O̹Y2& Q?E]/:@J&{/GƧ ="H4Vu];=n(p/eNVuCs2PaoJ(`jKJE&uǏ7)Km|) ;G sϪ4K #SmhM讉 8l?=LAgnl nno3U—<|e$ )>xiX@p P,.H;( "& (HР\J(lQ-Ha':)BJq6!Pf^ĀEIl{RZTsxJ8+".LkR M1%;SZ,QN^3S7< ER- P3RBz 0JqR +4B5KPdKbA -dbָaS~l2͇&/;[6!ӵ٬jy%G8݄L6>WNhhjvy]`b]$Lȍ)*oMk%q գgbvNlLK{Oal`71/Ÿ#>L+YgXM|ӎ71S泅fgf(1IllJƴcCwH4-0K^J+P{CsӦ/9庄m͵DZs.:v>^l0ca\t|6nvYP J{Dɉ61URjl7J˖ .sͣӫ=;y>hq׀\sRIǝ<pVcBkE| hb:3XydheV>+9hkIk0b6lSX uc%Oz(Ivk{JK|li19Pد8cWa䗏ڃPq13j4%, qɰ!r[%/Q_@sRҐХ1\K1m2]8dR 󌔳 +a-!m զ ڢ?,s;vN]' %sPaMI$D(A=W: (" %J6ʶ(% v3ufmuSl31RkC4ʱA16^6O؝kIG$`qpckjS.@2$]EiYU̓UN'ُoͩߝ/f]bK;PۢEZEv% *l S;T:?#XGvw,^@̩FN| 6t  u$̥"32@?(ST[0UB1dc=͋<*8;e UpRC*x G bQ ]VYi"v9; , sQ 3ڎL(xx@>uF\D. q9  ckFDka3 cSp0!Q^-:͘-K[CCWN@X]G4hˆ c%kJrMA(3_2#w]8*p9Gl#*s8*ŦV!4c.@ղ\\2]aD<&R)f]*[cQ IH/Ғi%쮿U79ucs\/5*d *YyDIQO \`-p35AS]ަU&,3tY2W{[a "H4,x.0E4 O1v2,=1E4%]buqP[Ne^Gr̎jV.ȉ6 y^,E3Ciah21B+QhKHhTkm%''G@=Tɚi޳90'Ԍ:<6'yUI^n@>lT`y5<ag@,37"/2@r,l_TC1O~ P@+ZT6/E3^T P[7{ό{ PSyt5@eS!e2zz[gaNx/e(uKȇȯs>4D mZЋ(h!iRq_>6ٻ^]i'c=,vTv z荦 ^sdG@+ZJnkRDIN9Г.wꞭ茣u)c85yς=nnn7ۇow[x=GjaMyY-+w-̸ht}W]dr)"=x3%#VZdV sK%zj(tIQKx䒢gZŵ{$15)~G1 >CFE[Y2F¢hI" !!YUQ-z|[|Շssv_^=|o3c8FՎdZ'y՛zdRP4MK׻͛DIlUmNu#ENEz=$ǻ SN`PY}@Q&_4Q=bt3K'yG-j4UKXQ (л c gEʈ5 E΁*̀@>gZ֏7R)Ñ^̾RεD.4þ0Jȅ*c+.[x{tyh # V )$T"ZRxgqEjFZ,Ѭi0fEj lȵ` ~aJ  LHQR .Y`z/_cI< Qy,ås%m,sS,G %%+z ܊,4 lq0bIt9YNQ|\uTXE>XMXxY hN!Ya{Nd]JB9Y^'e+7|ͳ&'l=|B"f*o Džpc8{^z>! rK6Y>dix66zhb}>0V9#Oжt:Gout|\YU%R>KfA(|`-(d8X@5#F+T qXdDDaľznq d ڬ7uPp)P4dk#9z,O5\q4WkwSPΜhIðRYq9G̵fFQqX=`˨ 2YQL(! iH7{[2:14 V9ۉ."ݓ@g,AigFMpJzک*4IAeznz(82* B9#m\HAUEpq`E[jhSK# -혶 %J"9Rd¹@աhUY:1OpLYAԻ@?÷47ӌS h^ uᨤ &X%ռԱԱ*fg`Q/I f$]Y9M/8\\߰[]e! \ sR"hMh4V,3[) R@5pYHĀ#"p(B2h,sB,7.bA*H,8臆5@{+4:N)G~H妞Pb ;weo~]|Ǣcʻ/Kg3x_NJ|.]i#Vc%,0mQ8H&Ҙ@wJ Z  I–q*^njG )>C{V x!c ,uM "pG- p-(@Ji9*nk.Jh9$QcHS~o9U&>{IM Ry0k5 BoڋpQk:TIB_O5x忠Jae/m?фt>[m-Ṍa˜BǼfT9:W^8&N6!+S400:Tc=U?HX)IgCn`$={Og =" b%(V#R`b4Kfu)KQuhsᕡDHdpZ'iHXUJ0Bk*=3]KJ[ \4Z1H- B@HN-,FqRLBʎ5I BJ raŒK! ";d)Ē5` x4wmE,֫}Ȑ P+ AYQp!c 6DR*8V\V8iEW,%_*8aPƶ&iV3!"Tr.0ӆj[&#M[<:8/OE9#R1W*L7JEē={D tNUAkyZ(Шp5 We¦XґIZb^g${@.s*IӁ1V)cK VL %ZҴМd퇧T`Dz'֬J˰s *0ibNs8Vh\o7?_mVݭ>n Xxo|o斋qWR`2$׿\mލCa6vH`Hiپ-(ꀴ!x[v3K$w_;շ-_Cj~T./[ba_n`ESDfB:pG|=:۷=\k-n,fuW`b[s?^~X]<^׫Wn76UtoP><\|<Ҕ}~?;\x=𲚋‹7"jhַȭarHiw?ܻ.X|u=a .nZWM.HJoo%8jzXOs ~{?x \n4`@[m|?nZ=v{G۷w_#< Wx CvsV6x[o{b_>liAPg8X5ysl@ui⚚yFzJ׋szD*csuzwu(qͯUsQ:EŊ#tjr0TRSiN\+gm :6vSLbwq_MY[lgD}ݑ ZA;0RYB?`RbTJ~DeFh$( =8oګח>*(SX |;mS^ɤEջJ(ΡR+GauXU(=#0\16%'oR2"Zdݪv9qƀV%';Q59-u4~_13/\r LHk٫샃$w9#;0H֫"xg&~ 4dBRaX/ 2Y]~S^/6fBMld0O,fcXbhM~fM`fp_k +EXJ/K`@\SKz1/M%8J`أ&cDGN&|̰hbBk&^@20IF`,+u`s}@u4~S|*c GIn`&S1'\T[K5qPcjKm~ 4L61a5]=&؋CT^NKl={?pM ױsռ{ӌ~ӎ4XcpQn{y T YBsKqy|$ppw1Dƨ}ꖓvh2d~GZDs9xg\l$MqCĸX HptYТ}`\!ii 1]1; gSozMM&\- U [1+ܞP P%H.;FF{Lu} L;2, dQ@L~XT^f\)t]YʒK9]>/‹ Hb+/& {`r0ljCt-e؇ Hb[[6X&@ wZiAf/@ykjIy`Z֫=~$%諱^k;;i});^2.0rBGPtl O+h7;wS)P( D pԌ҆c/fPKh-彪/;ôÞ)|Óq\=&Y2K#iߔ55{eD}#n+zVMk;;i}'#e J@% #T>'Jϥ\>0MH2߷M[AkQyas*jP6ʧP XSRi`@WTG-cM[,Z)}| ]NI'vfaA?x={*lAde-ux{iXQ!`-Np7JPlN ~4Xa-dǤE5 Cl į Q1@A>_%VxqbCvc>b/l)TuTBm (l>~Rd;PT&NU(=kbއ۫gHgrz=HhhPA_ 1LDW si'P@=DB!T-0c\T~A]LFt$"^TɤZLƪ$G'%@xZVMP!~_FCN_Cӎ~L׍IB+O ,-lKP?\t"ct|L?*eox'KTHR*c\Owtai Il~(1%čJ|@fdh Lq s%FP)5ehQnҀu Kɔ" /N,dQb"5b T;vڒA0- \vu-AbP8xg", lɈdكIjvgp%zۿC^cCr\f{gx*cdݟ0au>vCAj^Yx[8nK۷__ǁ~]a4o ;[gDYnk+z+=e?4FQ(~(?A.8[c&ζuss?jFQ`zdUGz{حc,azM^cY+T(.Pvߒa"B#Y2jˤHeeV a#pz#!jM-4 $nKa9!u-VV~Ӄ1(ԇaX%1QK^C煱 0WP"A&B XtBt+V0 &^Q띯@A7a΂φ HIX)Z+Fs=֡$ZJ- ocnP L3IKj{@?2^? *A8KKb(Rpn93 lIAXL! p8X|R*4d-$P vkGc~1-vY늤ۛXz"8Kb#,ipƪ&RXck& N &s+]"F$@V_FbDv00#< %p /KШ#% +K&8j)AWD#t̀SCGPDs'5XPR0v}Y l̶{/[fZemj {Mkߡ31Վ,%vo?=lS bld].{ Ϩ؉Y b4 d&Sj˕YtCUw 3a h;\*8576Oс,}u3(N8miDW^~;b TR- >c]fӗبR=1q{ >)Y:M 3U'5vwiU ;hLط ±&C`psyx6(H# 4|t~50j4KJ&ww\ FL<ҟWO$Si93˙*xxx % O8DmxiԊȱk < p k#YtbK^YCDCڱ<<@D(a%1wtIzJV[Y4k38_܃]OZ=,-&)χyxz}W2$ii҂S^nYQ!]_lbK^сh(hQK cV_4/XpOtsIJ/КzGVOp/X=юjy/tprF;2+@:laWMn'A?x)H%D&>&B7jtDDKŹ;8/n)]S00)ZQ|&҃ͽ`TjbȈ<7m,nJ{EJ9l,o%C p'Nt?oaP# \3+Xo",yq1Mpdu'6liMlb&NWfW1K4|cj Ι wťw}Kx\V [Pww{4ƻt|]z"pvj+ڕڇO|9-3GWٷռg)չcչ3sw0xQem5 `P+8wřF.ǼhGVnc5nOZ=*3X8p#Zpdۿ0-jh-2n.g0xu(x$LgW/KTu;{ZUO*7CWM<ҟٞLΧ|'K'E5$W=Π o@GF{/kH3QF6٘6a0&E@tPc_@23{՘wVR[K༢R+ֆ9;<8Xw h\$U,"ڎMϨ_O*UQ"' 5H-TST/12W7hMJn6Uun /p/*x-+x/d٩ q ͤc[ċ*朡5B QV`knQ8 ,3CV]Tcgo* U\ATAcbGZi. ,nO`9,8e$3t geWwè'èič-E]l[Mxa} X'r1ZX~?!#gʆuݿ5X)VeGŔӷ]Qa ݰmG-0s jǒ/:otB+Ľ ̭@ȊpŸFhxe:EK)#%U&$f8Ё /ҡh&JU$PD$9_ a(]P[k#P#32Bhi%#֣6GyI9(O%["KU]_cP c XW5beaB >s4E3ѡ qC0h>e|:’e>ͣ Ź@Hjt*%вHG\a_QX;8a&${!ȳ$`,1, .!<})dث2)[4s5"S,YVW]UVO<дAL# oTGyi vN(^R*\kr57YYb1E6zWtp`kK< H. Ve IG}!B:wx`3ρp})*_s3]QUKYEyڰ Lpԣfϊ X!c 98UR Ϊ mB-ll%4Dyxx^}v|^3M4o֗B@f' Td@h}.bhUI=Yqb^"sg W$ʵlB SSg2%;lV5qӸم7! 紏W,Rb=+:JѩyVKٿU\,V6Ǒz`Y%~X^eJa! uJ}}6.Wyds/x|d3{ ]32SI8 )z!gqrJ3#~~L1c.6u(g%@iccJnx"?fc9mvzAHUf@ؔ;L VuoZ RψJ{lG1LtP3! 'J%d "yF7QS"ҦǮD0I}PX4mhKGGz2?zdD &NWqgm>HAIgml bbFYN[+=mxݵmkģJ?yx_ 8Scxxhj5xZJxpذģE/ !zAt&De⁏"#i&̹35,]%^Biҥqi/bjFNNS7hJZFy~ߡ Z;dBw /;˭8fqyϓrrX?4wYߨlǡ{]usޅXَ}6,$2Z)qg΅9lkL޿Qy~9騝BCk'ϝRj><,;/tBK%~xkc[YNlJyb҄ѥh^>(\'g|kwsvvG`tc <Ymt9M9wԽPѽP7{J7\ʝߦ%hv3|y>Sip}+'׊ipԄ]b 4im+O[ʹ$"EUcEVKS׃X?7a*V5M4o{汆?6_vDNݫGW5s{N9Iۅw[N~Bv /m;gQs/׶=elNDƗ3Y>~:rFj ;s4שݹ#ѝyi6S^ʊij} ڍw[xBkvg~g7jI93Έotgvީ63{rFtf?x}أфūz y|x]vBr3NW`ÙZgf[bBrPf묯ϡz]ۯc`ݻk3\Y3NW1xYOWߵ#gUǜVgizW%,>ƻЍMA}A^^u.[)TJ<$y4Pϒ0Ot.Jœ'g}Wx~A2sH,JF&H"sIgy<2]n:~#4f/f/8pĻ(NOڧʲ(= (bKEg>Cr>'=Rx)y!]^F$'!HO:SgRx#'FFAC Fqp\'ݚW)$t$SNjx[!0#dHϪlē3 A8әUOL?!6'Ȝ>r!gMaiqP님{0)Ȝ>4t!1s:M}9ygN)9B!Ő~RC EO\$1s/Z؅}ʜ9}~REO5ӭyps/5E,vO$=tZh% I⿎'X\[Uu)Uc7Z$9ixL 3*5Y.L8LpkRP-=9j0rHPSmhf|. IF !.;))|j65`@ߠP!DOfXlݏu\Rux)fڵ-[}{+rG˻픐^ VDs!ѢN$ %PIE 0`OzfkI H8:- EO%FS$b@i#+?CZ>n<:jpaUlvvVh@knАer!Abo/PjÈ\(ʈ3.hAU?rvʰw&ndXL>ӫ6P\c@ڹU##nDyhh2TTOzWRB$EZi|i>#P* ! Ԁִ WZTMfd)L5[;!Sk'uک T́~8恵9޻$RkjH" }DH֕}[M3T%пL'Ґv<\R7'CZT;1ZC~2v IE::E3Gc{Ex~Q_qUPRF8Mpm!BDX{a\"55$nAS Oǹx+MH?G\֞;ݑzi~u-bOj%qb{nh]#VVAlׅMr=d[WiN̚Psp~ O[4%sf:/%G;9 cf*y\.*\hH3a eXwܸ\_@^.^v;ͼܾmRI ,ʥ G9C 4c L<mEm1Yw9A50)2龱(Ўְ\;[A1N˜MkHk/LN2&.i_h89} n& ~޴n(#HWm `BK>e``-춓9  ND'ƦOhh^p64.J㙕Xd^R 6cj!m.n1wuuH"c^)u~Cԧ~} ֣0L3Ϧ&-!)퉂6Fk}1skZi欏WQ.:wS@ە iv/gJlbDe㿊+%, ` :|nj\^2}R1,#88F{x.?Xnk9{P5EP pD͸цic|4) <|8o )z&|& *hĄ@2'ʦa|xp P3&voLK`pa /+I 2WܩNFL$lHonNb=tiPc&%NIF^jf_i >iChn2moF\& Z؉ȒPp"ɫ^̦N4/G%$ޝt:||<(EWBG(m|[{%zmb#p sDP.^ۊ꠫k @D5Q%ҠD0 vu0h&?'v{𼞿BS/eZߛ[reŜ院 BhtJb]](WͮuOj]/v˧.[WnQ(5'Tv.vzyP?CB9_>i[svpן_0B pUUcZznK\Z.vƦp%@wE$3ErY\\X|B1(}'~ 9F0+]nJUlKj]lϠwOev(ez}Xlh.WϕYyge} Ny4ŏCwPM#EMEAt|H>"_ T5[QZ}N⛯ޟԿ~:cw?F{kst-2.0.3/src/images/svg_icons/changefile.svg000644 001750 001750 00000060726 11544160207 021540 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/plainplot.svg000644 001750 001750 00000030340 11544160207 021442 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/newplot.svg000644 001750 001750 00000032154 11544160207 021135 0ustar00synthsynth000000 000000 image/svg+xml Data Manager cbn X Y kst-2.0.3/src/images/svg_icons/kst_gfx_ellipse.svgz000644 001750 001750 00000003220 11544160207 023011 0ustar00synthsynth000000 000000 Lkst_gfx_ellipse.svgWQ8~_ї.i']V}:+/8 *&_c&$dۻN*͌gyfXrfփȗ6AضdIжFȊ\.Y8JF&>m6[RZ7MS]wߣ[DEvo-ǹY˲o^ϓxiw 40]ɭ̛%x2."f^:Wʠn(\L]J@81oT)ـ>A*nFKOCK7 ]hJ}:%MrbHru)bYߧIYڔ꧍Lכ<҆~>!i`=>_m/a^ɴWx]Nexw<7xDID ~.{5['3v/Pə.IRW"NJq^Dhwx,;XB)*B-"UCd_5| 7[ V_x 7m)tBM0 (E Lu7#l8YU7j:>EpgJPQ/Qz( =a$VCS6`ם/y@oղoZC7idBݪ@mZbWשv C3.CN>0{ω>v @vOށnd #@ϱ A]!_NY!yH~] tJdՋD]j'qU#z#bԹ(:Y(*g> QFYr.kfigצ<\J2qԛb4EfgTi8ݼ !x"+nG1b+F ߯@G߽79շ*/vss4aߊNOjFn F[lgן$ަJԤYQ99髝Ѵp0*qӠg Ľ̖[U+0pw8T"U[k image/svg+xml (x) kst-2.0.3/src/images/svg_icons/pause.svgz000644 001750 001750 00000016270 11544160207 020755 0ustar00synthsynth000000 000000 ]Ysȵ~%Kz_%uj$o.e)[il@4 YC׌H@g?}/w׋ї(^WwQջqz.b,Wyhfhbq$F"x៿nVf*m9B<Iv\Wo_^F#xh~wi9:<\Qh&b+̏'WXO^,VIr| N~~W6_דݻutOVp}xFכu<9_W@9oW=Mo(GrTcZolS~J8 q8\iq&mR `$~%7ɡPs?"o+V:V{#ۚ !g +{'t':f _r y:?1d3-ƄԼyOL38縳Ǭnvy36T0HJߗXGn)V#\Vl6NԬtv,4{o@~.zIᤗlCE5Qԗ^}}MO/-ڴjC6ͱ*}zZ|K,*_$8E~T 4 t2Fwp.p5_;yi]F0"SeWBmkgG DžGG+N=*Ruz]pj'yt$a9:]Fjp~^ZNτS$pf\FtEƤ1#e a o-j:.n6~Xv إWG~t6]>,R<|N_\bYkx^6.ދ,27YjЀ2DW5Ob~{^$VFpo04cGa$ Ԍo6brmaʆw'pu};!Dђ[)2.o[VGϿX ǚNΖ~Wje߃$[ ,/%9}1?GK!k#o/g+rFA.1[j7:,TpRUea , d >GFTZA2-TѰIJݩ72% 4ذjX!*Ȝae}Xo7kh[%XX4@pͰDdC("@bAJmGB)4 E L$81QQvvI3.Ji#HQ 8TA`$!;d%ŖAWN]Z<$K1%5kՙ6ՙ/8aJ"6"/q'//N%Sc :+Kc(ZjICVG%[m r}qi`0r]ptRŔy°e3ã$4"V 5δRв"jw*H"z9=P\0 0@9b` C]=,_4e 8ӚHd_=4+.İ-^0=ȉ.률Z/`6Jd&0ob@r h5 b .hA`A e=;x<\>40Djg9{N73i]Pa)ѡAʞ5t+׫ZOJT 9&i=dkd%nU>ԏ6=ЌǏXHg[5촤7umN!i2UvjZ/à'E- T)u Li09%Rmz65a`t}ֳ Hm(ۍZܔ1xkp +[pkhUL5 lpRc8V=e2 cy3 t_k? xj}ѳ/}e *g}g߁4wԃӑKXQp q,O43Fxك`-{nϿ@uIO,퉺=i^bL4g!O0FvhXj.$עVvoQI3*pٺo 'igRFҺ5Vj"ؔ ֐qx$; bcZd.z_i Ec ]mGjN ϽT؊Y˥o#^ڸ6/v2Zz)h-}F/:k̎zڦxw8-=ZOg_RȾW6MP!AeҺ/H2ZQ[5"|a:i^T9Vz]6oxd~ ۍwzx;BSzwJbG|h\:1.[xxbЛi;/8^vlbS5ScN )Te-sh7s1*_u&Զgio6©(gWPWiY-"`Q )Npq$'V5]rQ\܂T'l% էdN}ẶYɷyFl5*,/Fr/԰1;XQ\ߘ]rdUMv`i"`.C'|isFK,u3fl6n~=Mw^7bu.G*EHR+W׿C̗WUI{{Iv(,CCvSOYrb*Qt}xt۴tofwaˎe唐 VYvV1W}(]qu &=޿[ )O5U!ٕĮ{s?]èƔʒ$JF߳6dx ];kΔ6 /Wнݿgrdm[yld߻mc9%8Jj܍k: ?loN|'_{6O}Üƀv2K>~&6?BYu1V( ZD;݉:d' 3 }IXɬf.䣈xRVi +b3Ꟁ0dp'7Pah`4Լ' eL!Vz˱ԨTۤyU̕6^78_妣,_N&uIVYJ9qbRb9arj1R+֫ EMNĤw18RO[޼7=^S&Jp3YM > -9 w+Vv5F+K$eܩ&.-7K½C/o-لϓp)dV[|H>4wKV&җ|"4< pKgp_ ϰGT& *w~ΨKW+0m¼* ukㇺ۫i"anHFMd"1|8Qe+#*BYq$B;ͣ8rR+åI j5UwRm g2+A*ugKNv|ɡvl!/Ö#M?rط ~aT_Ȟ%p<DG&3 99!OB f .b L CbIxlVV<#mXmhd^sB!H9ĈYN=_iBO7@ ыl^q f쫲wxaۙ "^/A`F)B"e#Dv9X8mg8MJ0lvSYBSIGK}/9`G0nUb *Qc#K $ &-փD -B)rfIV\Bd$u£ጀq!?dc%B])R2PpȎvIfXsQʾ|ɋNm,ZujN!i)U ¤[r1X{LS^=KΗ/De\M|O0g5qNϵ>9nh?6,Oڼ >ȭʖdmK˓JgW'ԺbiNϔ9-'3gv76n%TӦ/...Nqw]+崥 N6E9 uK)|{$륾MqSm$D9 \w%X #gU N"Bg_D0Qǻ%!qҎsʪR_-NDg;}y'U#K+$q =it^2hӵB e28 6V0pvN^YřEi WƘW}$eO Ð#3!G/{2UKLj$;_Q^5jWݫfmޕj+gܫ3 ~sYz~Qv\ ^@ٽ bGŶ@v`Z)Dku5uKtKs'ٙ:-Zܤ6Ten\ǧǦޗ;V풚Ssn}bZ†zWn5QTz_'|Ez֟/?`WsS҆<S&;"II0IΆxˤ_&zot'g$@2 ~6ݾNU'VeApd,D$) <1H1ɩ  t -)?lys["[Hl)Z,D$|%%7-ܔD1.Y6yawDW(pbI3BEF}5dAZ-%pUX:Ŋi$Jq](&IYlcۍ$lP&"(FLe"<NUH2t5I~ƷEQa9 SLEx4_Zoҍ image/svg+xml a e u b n x c k v kst-2.0.3/src/images/svg_icons/edit_string.svg000644 001750 001750 00000037301 11544160207 021757 0ustar00synthsynth000000 000000 image/svg+xml abc kst-2.0.3/src/images/svg_icons/kst_mime.svg000644 001750 001750 00000154713 11544160207 021263 0ustar00synthsynth000000 000000 image/svg+xml KST kst-2.0.3/src/images/svg_icons/zoomxy.svg000644 001750 001750 00000043720 11544160207 021013 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/save-vectors.svgz000644 001750 001750 00000030310 11544160207 022250 0ustar00synthsynth000000 000000 }oI2ƉTjۋ[b}j"ekZ~_̬'XTsmFeVTfD/##_~}^o6.B\7Wb[>ſgon}}ᗧz՗/_wb}b6ᇗO0O׫WO{θZ߯?vOWr!.7uf቟|xyr4_4g1+Sӷ(qߣJqEiuiޓ( éͷrcYғzwJjj)oftU-{/w"U`]M[Wb&ftsVV.Hq~Zo? \W )j&?*en?ܠ:b>-忶9m>?~^ݭKDC,-Z2>n:fs|zY~y]=mo>.ߓp[Ez|x#i\څq۽Y~q[euuJ}/onf r都.( rK Wu= Ăt渷n>ᑫ/fW~*U뗕!%/w͗y1hžچc;:<.T?iC&KUjܯ^V [zŞw#Kyٮ ui}u?N@y[ٻSPl>V8js+|' eqv]tv0a嘓Yݑͧ|~6 bǻ_הGVx,#osn#HaHhR/mS|q/ۻ?7nwTWOM]h&=i*!ػ||t~M{\>fܤ{م\-BDTy~UϷ x>6Os裏vGLLqS ;jO2wb^Mn.ŋFvޮVM=>:iH J7dOdR-O}D'L["%`vaS[aeKZ{mUR0B us9Bz-" q9茋4]=i1r+yn/fJA4u,by"ߢb: Q* kNʶn:=t hKQF}ooJW!F^+,)O?g6 ~6E~"ߑN?aR?sΤp !<a,_\z;s6YCzyÐ\x[J~@B.&>fDr឴v*%zx_B^4 W}ԋ||_M~YuGj?h@_[:Խ3ꪣ?z OInG+{<>hZ{O@u \Yr Ք>HhT"O_zlϥ)H7K#R(!tDߨ I**y^/@ops{*1O|+T6Ӆ#8ĝ0]Sw=M50r2-rµ˫9ļ+H05= k 5]tzдnqMe-(;",MnD'j> .>ۅ !;0˕Lok \k;^21IHou-j-;`T>B_=ĞB^ʷ~A^apqEn!-^-tcZk"U, dk*n u;\SO&F̳aw moݞA1k2n@*7گpMf sk2ka,}k2emTɟ1$eWH7G]FePHv 0 e΁C T =ny:ꎑOCiq7\>˧šx848!© ꍔOCap7P>C;?CNxR8C` q:Bá^T8 zP?8tRGNCixȊC8t l2g{:_|H/>RsŇyC!uNCV¡aj7VgŇC|!u:o|H+>RƇwqj7VgŇC|!u:o|H+>RƇwS8:K|H/>RŇyC\!_;䠍Aؐќz!ySԉ0(v 6VŮ.6,%<՟L{k\$݄N:Rz`Iw7Ptӽxk2n7*k2n*d]H=5u/>$ F83uOZ ZD\Yh`"ɬ{jn]zXwʼnB`;c_ل0bǠNGyCfh_0`1{nn9{"ddݾjܮۀk2^)1ʞ&~,]T 8̂lT:fϡwm%~Od]5֍zOƯnX[G=w7}/>Q=ɬ{a͛]qMfUB;ezj "ytXQGF;60(| (9 ƛ1,o*{jN8\wF9VzL6nT:0rwN'hsXE\wUU T07vt_q w< EnqMfUmPjT7pMf 1Xdž#ӇnaᔊJj2wM\2ٜihq&͎u\Ofaa'p4Rq}š;h_pzq,5F="SANvHs4Y\Q,6x퇷ުn,o,Q݄1us=G 0Q(߼Ը&G`,.^8u w,j d𣮼55D3ghn aR:o(ݖQAiqNuA(NwAF G̏9ykomz9Uz9*bt/\aL83iL/\&k=Xۈk2*=o3@l@>^TlfA綸5}mQ:77}_crk*{s[PF-uBN {ˈWtuDW Oqez*=%,!1<252@1?wAt{ay-v5uC`4sL<ƄngBkΡτ1 ]:)G:>}W8wQD\Y\ F:tnh5^q0ZQ ʋIRp=Kbr!U6r ab~$k/0x:e N4S'@ju-An~MZp( !,@:Ʈ]gN>[$=5Ɍm%GQ(O`gh`36 8g9텁Nۈwڈp#k5^hMtJR8E~sNׄwڄ[gaZMXE(aԆ`B L?KRҘu1Ӭfb(  V\ ڷRbX ]t-e:U/[t:/` n0TzԀډӫ}A i[Oγ݈i:-UŞN{/:T }=žQWJgWDӏ` zzAO'@8N^#]ⷕ )O%'g_zXXW\޸CsslUklhCp 0ZElF7ñQi4Y\эJ;Gd:{чG0sS T}w /[tRqeK''q nj@i5䚀<0aLqVw"qMu^tsXxۅ3TS 'TS_G7Cd{Υ@7U`םnM jnmX\_ZpBō,XjPs;{'Hc:.YRv..:liZZ {²Ѳu٫uu',Q^vީT)?Əxּlg{jk@1ǸMM honm>FF1E>hqb J6sBks GXӄ?<ꄕ3;6PSrA!:ݿ>=u L~|mc|WPЫ/+#.` ygj޽{L,t#Bv$4g20G d|{r|M9,6Gzq[Lr>" >p"ԋ-_o_xYZ!?& +?z}sZ>^!W=S^|\>$Fp5;|(QG uiTof/ LHLKN02,3O~B/aZ&:JP"2EelRVdτJmM,SӞ ]ʪSw__Ţԗ蒽`;P0 8R*hX~I$@LRɊEXMT~雊Badt*fs|Z萞0D1EEWҷ'δK,UoX X\cYHl`Z-biUYR%' ?mcټLXfNv/SܵnɚY&+:Qd1UN úgvV~BtՓfJ-*T+˵/:RZ[<0VPBq,F3-Q !T4L4EfBX#Juoi.)֝v' lRFa߻g?V[ϡF k3-ɑJCzAP/$Ey(S[T]Y ]{ ѯHh2Wo N ^< S:Ca9 8x3UVg~lQ={B~;VQnWazag5'wFe-~ܨlFRlC6 )R'*qR$g_K[ 풌阊e/'|r}*W*!fhv }5o /{~!t$g"<W LYԑKa|ǗJ\p7N#Pϵ |ԡWgS^)k֩UyYR]TiD{jMSi{Q &y*v<߇O>vq/ CgByYrQ}TP%4Ry}Mp\Kl&ˀ ePӐfvY#:kDUIaWA%Vu;1͆aN0]$wƃ.K[ VjLū5< ? =c~1 zH„O745@kΡEWh#g 5 t d-quu7 jIё]B;l+)4~:T ;jeJDϯ'AVSeTDxf56^jMlЩ2.m[ 3M%בhg "yP7kM"@plI5〚oFFRP*6@P .o:H3Si M^kyMC$<,8Pi`-pA2 e@dԾ&i`}Ξo`?,3阌!#lK<c-wU7,8Egn{XvcQQnX&te) 5kِGU3X)C/3NBd,d &5aJ:ֶ+ǩ&,c/K0YEӄɆte]< qM=6Áu*#MSUl4@NimcUe2XnS-FM=˥uoV>! B(bXeTVg4H%p$ ĘEKM  qoiY,XtP,vcJk;na!V"x4Q!`&[89  D&S3NR/o~l74E}nЧ`C@`t2}ue<.tU;irZ"\ PXG`aa22 GV٩<([wE[ceIR㥡 1ä5&J*QKn \Q#cykD?|#I"\KCM8 UG}aIYh1z1^TA\"*"i2 iȵ U*ulI8lN X74&Ҥ9D+xMVd6ꡌO6e!aE YeDEH]oA9=vTQU39zK<1 L^Ӕ"VLjUTUvHߡcI2c\s$I4TVe*r.QDgA)grȄS6=qg 9Y Ҁh '>RxsdpƠiյjL*1z*FM6R7Qޫ@T순Ŵj;Y Zs*PJ%TzR!RqXS\=8[FU2[S(t ܿ\<=jМKq! Q2%dB跱ut,.`T1&)PHP$Ma)OB^ȳ ;T߶E!)*L;{B݊'o`U?4ʶ8"vOFo-ld`84Zі`$OH֦D꭫̾M2zU9*on_9AڦZޖ7C4&Ka,ʦ:zZ芶ɟECNOy gi19S0?i,Z\&9=i: TO3.SVm4f-?S" 1ՀMA] )dcd38@Ǭgr*42P2^ f *{1yZбP3ۋMs^T8_qL̔SR( nK8`lP΅-d,`,v,6,,&&0|q bHٸI3`ڥh1VId2[F3{DgQfZa&巹R5ߧӪeы\1 ٣Ζ:^ǐz @ 4QV+ tzyCn:&J^XՂUI\>W wrſ8I-}רH,'J͓qJ&g9tn:U%MUI0U"qOf;4KݴZ]zr^khJώe ;%jEtPR/6Ք\"R+) bO #Xwi@.i MyMQO:Xi/Nr^M|)xHz0RJA~{?̱dGd]Z\?+5#d_7aZϘ"S ̊&">):.ˊF|96*|fE ESghd%X6fE# ^htj75ìhTu\A_-ܕyQ"^DQU 6=^+C]Lʐ,KJU@CXgUAYɋ(d|kR5DBU8&-Y*Gc H \ Kor;uB}P(3ޒ(We0 U2J$"<449?DNtXTT,2yPyTY.REP*"R`ghcl{LENɹ%S c">W7{J)TVnON’T6JAc:Zm J4yu(fd[Q58[·k p5ՑTT/SenťP"^=@?폛g?)G 'hڼSoqZT)MuX>TSkpHk{M]E{o1`7#Ryo6|~b#M|h  &UuuS't^X%l^]ּM/f#Gj̨؅ Qxf6 3]rQ\.¬_ZFvH7pa%yt) $\ vمjM8פma74D (d!;8 v{=\ۭne5?צ[->,T/|Jo-߯iE9QͱqY2"KRFC׼^4\Ss9 ZH hR"B4{X֭U'KLHCƼ3®Vtj%Zx;rXZQOaaZ&. $j@ qp@ yߐ8Ԟt%|HHPMl>х!C tQ SR=~ϱ;j'cZcwx HƙV=-88ֶ|zXuEJF&,EB]b*AQ˘Iw!!Iq^8YDac4)!N ߨK>C` 0cylG[  Mz*mqԖLy>-ט@m& Qo4.HX6ǜPÊ[# $֋{XRF$k:9XNUctA4yBFmDbĜ#=ʯFiLstLRb x0 Ĉp61"`zC 1tR{7~wGKga_A?{FW!-OPkst-2.0.3/src/images/svg_icons/image-x-generic.svgz000644 001750 001750 00000040205 11544160207 022574 0ustar00synthsynth000000 000000 }isXz/$t=J2NTSEȒJy$ dVwƞ ~OnWO7w?ѵzSW7wxzz^]-nV?wg>qx^]U.t/lO_nO_rWʻ?N~ޜͧI:|̅1s1|4^g(.z0k{um.X?>.W׸rU߭/8WU6kwnaX._n5$_Zݼy7x?T'x#U[SNmnѡݮ||X_?߯V7Omp>=庺>=?>ϯonWe݋?.n{|X>]ǘ,Asvqypap|m}2bp{Wꇻ~zS'|ngg|7}X-*oT[H ??sջ*8 9zɿ7ĿajoL6`Ug;|zR^)v f"fL)TJx[c.BTTs_6#Z%fWT5.8##nA+98j1i [,]{#p6n :!pv 䙲M!Ω3}frut&nb]ONi\U0 nV:XMPCZ__95^znxW2x < j 1J F;82==? Tr55qqCd={׿i{H6KmVj^ufq v_V?ȃeS1wW<@PljȠ8|JU^F3c $kk\`fv=MmkI=U N!X G9Am\;Lz#&2P|]ŻÍlb#:Bz-|[|bVrs%t0%8 q׫8>Ĵ7]/ YC:Ղܾq{]^݆SH˻Ɯ~b,;WwhőQE}Ybwm싡8F\_-n{9ԗYNp6t(QP yBZcҺr( FeG_E7.Z-i/t̹1K1pB+_]g3dmLMxL k'16˻FF$Ց78c_DR'gk#-ʟTQ2([K j6fFɯ)}=N~]_(*p8bdf>& iT}ߤ`[7!d~cT#ItfTGqGqB$}لCg;s̄s>|Aq. 'eaY:騕d']Vjf=%_%0"#P#&lrni,QN:DmuS =H3W[ABc5Hgـ3Uuv)V;瘝j\'V1.c(WIk5!ɷ q)g5f͏]S.v =e8R}'`2!Dc2'lw4Eh`"PM 5{PZqo7xW(xK ^{nx/i!ڋh]Z@4r 0Lnu-]-smaB+j똀`@\ ᥔq@h8θ>G`B $lla|ZS Gzv2ptpn2$iK|p`15kSt,jY][\z}3L,<̾a9_kmฆa` ~ .d8H68TV.lq`T ~mBa;] "68\؞UKS?3GI@E/(rϚsÚӮO`fiW:@QjH[AM 4VT y0Db̮ѩگg)+е,9L9g *UJoA@N:rsHwaOd &tx1spuNwg9S9dHL"]z Ky( se\rݱ`"ed2 "m}%::V eI0:4VBrq8p:B_>B> :ɛٜ{V0ԘT4[Scuxnɺ^ .y(\'3pa]1xpL]zl2^ѣGs 6 q0R6B$ m!`ړE_+T}I*w5|ؑxS=L5 JLDepHj]p[j'5e@2fk9k`յg2Oh 6qU(k;Δ)fY.WG('㔚ql9GMnlL4ˁr3ns8l ZxeHez4vt JUQoaAMSffs]`J~ p]?;g{VcQzT򫅽~+;iT6}k7HF9HM)h{Gɹuq@(wg+sd]Râ߸)AWzm2g]gGsT)-"=]c']]͂ĀLIu`Q8N饼_nK0ډD#8ШKMcSjᠭq*{'ol `{ak-*|nN-o/͇_WW =Hw[oX,W|R.V: 7>Ǜ7w| .?w>TtOkF"IoxVb>uܵ7ko~y-pw0n'\(n?7m$FMYA; Ňrt{F򏗯R`3m}|kǸZ6u kX˦F,ٜ~z],?WVBǫwt:.W*C⼫;*o>.~~?}9i#û{pË.H紹ϲf~5zb 'n+Ȝo~^W;LJWFق͚ѝ-A*-Fޖeҏ|kPY6(<Ӎղ2P/0`i鐫9,g*:XQl}T3kj /2L)Hm,n+8+aqE2{n+,t ҭlGMBCs'[g&Bu3|80GleN=& ?icaP. |:;nN=O@7SI5ik=lZ5}Bp83ӛ\4*ݾњ# `9:s bg*©\V.p edr t#j4ր$aOD[+vȇXڭ<+mA!V)PY qW:F[W9^ɱ{ڐBe/B,@vy #xb4D*V pVZ+wqQ|Po Iygǘ]h9qiYç/$l,sykwx*+Od`sF͂Xf{uΥaSen"x T&kk0mV t\8`)?ޮޭ~^ˮ^jا@CVD%:141hxănSbh:0oEc] "PP2Y gIa} c*f%8NQH!9U. s+hY(^q ylE0ø9KR9_(M ( w^KtF_A*`++Vtk+lu,'TFd1gEb @bȌ(QS$8 xςCkhusZIg7„FFa_HX70pa6}G$s:Mkϛ]"n8g`(<,E3KR04!Ҽ2!Y 7%CawtccP$1<xĢ.z A#L/@@\9% R`Dt4-g9QJ(S.‚hOKOѬa!nXO!LC%XӐD+ DbL9PfI 4_eZ< hdyFߠQGnLX|% \e>M# <9\~cŒĸwI{QsIݥpUԏMmԘ᰾T=p.K6K3n65#li  VF!bb1*NRQ A5@AkLp)Gq_pkTVzf"nx])I-G̕,Y+&t+9+uȪ_2P^ @2M4H4c)ú6+ |m4gFݖZNV"o`-2+D/Vuy-kI4p8R[.WMaub^ĉ"&̺j3۔V)Ll0XΒ5%+uf rFvF(Ա GbUgXEL;XEdvM?t;p^'8rCQ,"r.PڬdsHh IE^CW?^ dmC-97JRWCɳv5ɉ^>\ç*Y>Kãb<hR)"Lֳ)&Y,89d!Iph(3Xm: 60:RT @"`ˤPa>,FT)%;l+Ra0Cvb0 s(vWAtAʾD&"|y=۰> uN)~ 8b`窵E,:)b ʆX2h5$s"i3=b&CT!E ?IRahQJX>q7! Cp5K!F:N;D'&0qxg˄rcht;h_F < q$_IxS3,f (L V`gGGcڏF?ƃ8p_M|bO}4cM\vFc:FHFFCAZNeGS$RUDW3ǚP\Ic_TOgrM3ę Ԇ V=gDR.f WZW(2hdNH!b8`[ۊl%,@eaR:OL[s +Xx]|C]]Bim7l蟳@GiHۦ ,h9s}doYy-[Q3_,v?22T$?Hh&.*eܟtq0AI )Mc?;' r$I H`i'd פ&E#aRT=뛃_O\bݭ%7F!)--)Xc =H 3Yudv+GpwYA8$T3yFWCm) wE𯏢(-p"fȦ1de*gxQX8"6CS+uq*)sYVmFZIỶ XQ2R"Apjjl?K}aL\j]M(t}OV_#[f.FMR-f+S4%αR M)8P "L80:O^|utƑv0:E3+(;Ci f"JKdORтٻeXb2D9l!FfX)p8Ep /άb\d@ƷfLeqX #˼N܌DG4.UW1aVlu#(IqNK?Ǘ N@52wyR`BxEĒrR~FNg dVh̐kȞzQRT`3/'_+ W8%[ߔaJCd#K  L,$4 g6.̗dō T̊]x#;Ur{$8ӉUfxN,}^b & a<:'֢1˦r20yh]&3;teR=㒳ni(ҽ;gtr]#; L%imY{ : .Kt,-wTS~P܊R2 }Vge/W&|Xƾхi>+^ x{C0XrMEeO\ Írl3Ƥ"I<4o8**.l]-9k2>օScKfrJYB8 s~"=3xS)lu"AP'Q0f 8$ytCBJƽ>Ž 3)E=W/\J*s,:ϙ g@!&Kw]c82Px&B5LaYi,/Yd^249eidPbSh%1:2Q "X+$ TkPXGy3$iA6Rm5@8bˌp)/'2Qr,4seOKuIтKhlVx+r%8,) Yd~JAp8/;@3KT X*si<>8;,Ƴď`c)uBtBPg_ hC$>e>,JM#y9/ 6ɱh*3\lSjtQRWi9}EKq - kAz`C5nM8ˇ tk6JrpO|& ̾d1& YJ2 mpҙ58MPm|+8ɪypa>&Y04li˰c<#c=өDz9B eXG ~Tb4DhrX_~\|J1"-Z !-N[se?XJtF=-:j*)L =%jY6' R[ܒ(a[>cQXA`q4)?JkZvK}1pċ-stX%d*)}H/*"ɉX&1r&Q'P0ZO(Ai212to[a#Do$5 2)0mޡdĮv3s=Fĭc2@%\@W$W%NFfM6%--,=7II_ڲGhz&xTiȷD=CLxUb6<+I׺1=Ä 0p lbsh4L08nk 'b&l4ȁcځ[:L l膈W`/9џFUqE`cd#݌ddOvEĈ-%6l2!UVlt!ӣloM‹ ͎$0+$8bcyG wTdC6|(4- C,ܼ dk0;$v7s5)+BV BZ'YerDL +O8yL"9`(|Q8' †9 $er.3tWDOy;E_ٙLi68-vTU![ e ceFX:+d$k,YvWw{* YeRr e4GFd̠yZŧvyI1\(u)Hה=+nɍp儨,t:ߌw* S8Fi)d4?`qipDRJxXFDVeǩw+[lV.SFفD+tj.4J6s Idsh-22EA"Ӹ`AʒPp(##EiP9Qjhs&3^tf3 ,}-o ilV }~al$60)ݹ0 S#,y^+(Cժ*S0MmP5S,1 PeZv6T Un%}3- Q|dbivӛ밲~ENrXUpCa"ى>sx6clNj8a/N֤ z(F۱G=bI\䏶^4uVY@Yjڠcs@/RmLAȎc{ioQAtq/ӞU,vҏ[p 0 wR#JpZ2 -#K{ba)I6G6G[TB'f?9< !O-wyҁ%z&*W9iL4d &IKr/)&;zbdd͵%59*m~9]F3 ɳ|KR8Fmh74,gx<*; Xvmbز7Wːiɞƚ+e8 ORKܐKi/2(c~ZE*4Z,> 8ƭSqN4gm\OM:V6*'hcRb:;e\` g 9Ww2BBMvHfr#,Sa4NsT(Jl 8*v3F0IQ m8Hv(a}e|֥_Z*dfj!irC[qTr.;D"3,&,bMѬǬ:CElelbdDQS+BT $Z̗j)у½%r8m䨉 ێ(˚$C N3rdQFiQZo>2JZ6PBܑ WL6L9H&'P&3eFe &Ƃm:a,aXZ`0MSfrR ‰;M˼T(-ְbDMRW8HJ~؛a$!K'DJ:N+3XHq%#>X)6QU=ۡHQJL^Â*;S'{jqT*3Dm™6=tҳA?6Jd|W6Wt4[kdλ d8>XBNS! 6r勲ce;b p*s^<}L:Y_1o.2oSѵD 5L&}qs9cOt y}jOsܽp>*_no;>>-iAuб4Jw%uU<1b>S$w`"ryTm[R.un6>>1J}ig?h5kst-2.0.3/src/images/svg_icons/new_string.svg000644 001750 001750 00000033207 11544160207 021624 0ustar00synthsynth000000 000000 image/svg+xml abc kst-2.0.3/src/images/svg_icons/zoomy.svg000644 001750 001750 00000041541 11544160207 020622 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/edit_matrix.svg000644 001750 001750 00000047271 11544160207 021764 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/edit_matrix2.svg000644 001750 001750 00000041577 11544160207 022051 0ustar00synthsynth000000 000000 image/svg+xml a b c e k f u v x kst-2.0.3/src/images/svg_icons/plotdialog.svg000644 001750 001750 00000044455 11544160207 021612 0ustar00synthsynth000000 000000 image/svg+xml Data Manager cbn X Y kst-2.0.3/src/images/svg_icons/new_curve2.svg000644 001750 001750 00000034330 11544160207 021522 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/xy-zoom.svgz000644 001750 001750 00000033030 11544160207 021253 0ustar00synthsynth000000 000000 RLxy-zoom.svg]sIByRUf֗מ}؍{ -[1P[_fDP4HĎWj Y]j64J_^TӇ?~a/Fpy?o?j&_o/xP]yxxwuWuOW^ _~y&<|'궺+zx=|,UwwyύhX21+ WC1?/F߆GsY6ݷ[b6gg<]PٸOVZ\>9j4 d܏h\ͯןz3Y|fjPyfgP;xLGZ!, XHh/t,7zKobx}s[-G^}UW7h~餺sW7wOΧz׷nh}c__-۲@;b/oIu=AK/>L=h_rrdWOӇTcOLGa.P<ϸ\ppp9NV,y:\)Yݑ2%+SysA)J}6bHtNɝFf iig;>g<75麩3RVM*{9Dbp#;\*\dVG8>*x;ST8PϦK\g%yވ v:0ߒ90o)J.)Ƶ(mhpGc 1^5Xk)P`jExpU2L*#4x_a8s`\K;,f6zGZC!Bp A+LKXtңMrGʐ /IMomrK|Ϯ%t֥a6IU@x"YJZc,R!I؏jK7:`-g[n)m[ ͻf.-)E5a:zG75zsC١66xOutzߢqzH6 bt]O`ıq!SJ՘B G^D)cٱ%r&!^cO [gk eYHAxSl*t,DC( mX%aV3a~,G9 l2QsM%W KWZkbcrvYXp<;VbOb4|.欝;LAn7V&YfJ JO-kp׉%la[&a oTlءrDMI0 ZO?L{gc2j’7&:^f`fT g_S<hZ>6 CCfR2®(62~.˜L;8gy7;#agўFƌ7-9R! r heFl] ]$AkmˀqIdx=.wlX e^P'u_T~ghїQh3YoeɾAїceiax6QĮ8Z%"N]X0bCx6fY Kl( 5ZެqmxcC(Y|.޽ Ӫ@f:4be7|$9O *(:HƬPl`84?[+kظe{~kˣS(CHM}2O綏;Cb,IrmCj9*%ۈl:Y*om}/w['^h<'S=lXC3wx '0gW`P1F4潒yfۙ8Fi~G@zqEۉ:n뼇;t_z[1AWcIEVhl4XO͇|:Nb/Hjvon -3>A"|դYMPqj9\1& `^kK 8t F h$$'))b@Eyw{Yoă式LMmgqy'|' .ok7*M gڧ0|?yr;W9+CB3dM;Xn$#5#q\>u1*K9Hje 䍗BkA{XEW΂qݐ#s:]fJoXRlHGmIiV*2 t{ SVh?^+rϱVRHyNSg{V)N)^PNk)%7=,c: 9TԳэQ w8.gk]ɾ.,+[$[5Su֣lA=k}9PTEw@k΁(:k(TpK:LW/}ZPl=`쒢N(."|)Ynm-z!ގ/( 8y)]4kYr),F,4.+,f(t!ړH>n=|Ld;6ԇm~uju6Ca2Nֆ@.B9e8{_=#s M ti=i\ֵqhP:7g! :jqjsjeV0mwU+ʸ r&W9%I&vʢIȵq&2pK(AEϸnФ.7|\FsutzÍ鋚P=iѹ&gmOCkЀ[xH'F : t#,SceVUO w|hc1t?BV҉\ibgn_v{'%@X(z(kX0QAF&miWƴ[_UXO5 $=<}5Vji ^KA2/c,/6t]ci qh o~&. tR퐦-18頩ŗfF}?ؼ/s0v13┙ta#6Ѣy즲b,H^m~R#?xJx"ځ)@SjYyԇtm{J#[QǛHF#*+Q ZJ2OvR0via u'3JffA,kQ!X V|||ϫ|Kbݣ۵7u:5=?υ u~`r d[C_s0LokV16i9ʦ|J ("rf]V!xk NjS`>fŁge q-[)9iuDLccg`-d6n00iU_PL}cD_@ I6K"jɴ/FwHk_gY+u8Jcٯc-Oeٻƕ+>bDŹ $HL0YV5׶<ۯ+j(Z$%Z%"Ob ]5 uj r^ #!&u, laXg7e2LD܆BJS(LBr 9 GL\I[(xYM~nfhߴó/;o5+J8'+A70IuշT`܁stώiW*(ֻR/Y+Q[)6N~/)!9ufSkv7TJ鋛 ~3/TC?U1fS̽dvIF"hIg MؤJ@Xl+7Q:EUFZV[-,3%)869SVkYZJe(_~w `"6uf7 eѬVƸT$ D8mB h^hBM% cn$܂l vrcy"V]9Onteq㥲mDxw@JwN|Ii|y*K0]g}zsWߑϝ~{!i-p2J65&-o;A{jw{\wn[rm;yL{ܧw7plqK/r<,l\~^O.AQ<x`|I2Nu>Ooa@v$/5W}| H I#k|.To8>摒E\nFsh5b]hS[i~m5nJgKof%Sjӽ 6zSGÊzJ V(zQllѬ)& q؞1C\QQ 媂l Kf&,o ~Ki8ys<|&f>Naֽ>ʕ׾I>7g̖j̋qWyVk.3ɑ.(,_ͥnLgE9'`b lR-Obq\{zC!,}l[*p2|/ 2\{a8vU=#-q)v.ZtnȼtKFtN{hD犍?H:DUXt#ACe4\'1j f˴3-a"fLG~05f ϷRkR}^C j>5)FپrϹ!F7z_$9ṆBab{Isv|<ء@\k(lRK$1 <[*D ^^L;!<-' Sw9u޹ZqHmWa̦sU]HOөhc6cj^)˺hZCV28ĠC#~cS;NRVЮǥ짺P9oѫrvryF*$4+IH:xP-ybtIl]a)^{V0/ +!cTP`/({!4ɮb+ mt۾ؚ)I4W(M :|}UCdu<~ub=fwڻ-4d(ɾeItH-a497~it6$fW@Ҿf-JД]LSzg:)HvqF⧰0ł[bؔ7Xiڑ M@%ї&&ɦV$ L2vT"g oZŬ_^Pٹr͐ը!w1ͣ~(u-_MP⽏dmv̦=#Sڙg`H~Mt$!7Xe-oC ՉJɸ?%wH94Ȍ1?9[g+Wd+"lv4@T\>wPьDOZW/6bl>rMb%>eW>;_[LplHwGYs'hH_o:t>38QڝoTK/@*|_J:+e;Ĥc:-v&։|O u̧rJ但>DO,b|*d'n%NKP%Nl+ɦ=76OvQw0λmE yiz}P4{9 -ɪcA6GKp5@;##CS ⼿`oq]yqdСtX[m}?26dLSj[\QOū+N^St0AT|ȒOFƼ6 6&Ǽf-[5(P;c׎-5"8Q4j}{i.1w_g70Ѱ}]SuW< Ak\[v8M+ǵ u9^+3u+╚6z:~)ܷSЋڂ z^WiF!D*oTvY}[jH!C?j'(R$T(mU4&AkmhBU^zX򈴥O]3Ks 6/iW''sF3Xy +r=2oܮ7$+صvK~qVp4 y<5T<,Bڶ/հtrـu2_ZMqmMm H.@Z.k;=M(zT׆4kUݵ: ct yrgB8}/fڟ3wR-[E9$0uWN3=31 {^#%<6p{̵u3Vr_{-sdANcې';Pu/51wl^3,Q.)%s{>@wbd{hxޱs}!ޡ#K;~דZM?N'm(W=n& 0sWd:֩%$Xhw?at=<_gi*p%֑[sFaq#{6's@2}]ҟ>=~}&Gk/xS#xq~u5}Oiz˾Aj9`X,``vgyƕ\=u7<~\ y=ϕ0b1nFM5XWl|$wv~>Bv5d3%W||9-]2M&h1r"ok?_l֝e0= ւ ǗdşwċǏ7c}bk0`siNX<\^\<zc`eS4!+=Y).PXρbxiqtPc1)vUdσF,| /epܐ2D)U̘U)܋qZ1F5&<*6K5h6 hL t+}Z6 1~-^a2!-dthVU˩,3Κ !f1zDa[_KD e'Ŧh?%L_O|"*ne-7OŹ5XQwCԊ Hr T 'ym50M:X<ǜ6<ؐ$v+x:(X:`0f(R$2qX3v}4Wta`/b ,EvTeT4ȉvYE ̶%>:o},fժIn.#9aKt.5G`.'*sKc(JV"3ON 4pA@qu X,u:ܤ^gXO4TJIn`IDR0ٌmyeh1H0 5K `4ʂ@ ˯2X}4\i,Wy5.Yv+\e ^`2eգ(Kϑ. M-)0Hgljbd~bcG àfp$hAGE1C&SP"D`\Љ{ |`0 *prautT(+Pϳˣ9l1[t;+h#DP SQ r4) ]@_Bn ^DWĘ tΛZ̒P8}ȱ0ag`0,o@j~n=BXn#]C^+ aChXKm. * ftDn!Rߥp$zɨAD)_'*M[nv)+#6il4k1{ۮ+ |T2hL Bi i t\ =XX4Pѓ%K||UMtHQHig J.[_#R}1z+I0>:>2O;Gi> /GSPWfk/ӊQ˘JhކqnaBP><7A?\0:@25.sM-a&vzD!YəEԉB?4@e{ޑKTH*4Ph@eƳX &pWm .FN<4'dRǀ$nGuLhw5alX@ vIC{s@ z|Y2BwbRެl.Thw, l͂zpס2«#YeRG/L~9jV RCXFz& Pﰊ ؅}4 D`1eF3F8ow+JOb#F^RaRt+0C&1K0dKfze FtࡧBzl0l|AC` ; ` x.i:݂==y+NvRYSMrJ<K,MLѴ>BM*FYj @&nUXzwXtɵ E5("pn>_q0-%IeM3q+'mD+$a67]:w5t`SxgZ^_ڧkjE:$ݞi&z&2]b:.P 1ksPҌ[ uts!5b>fP$v2jolv# |S``^H~k֌F{Ere DY]lA0{]? n0/Q^"}W0w1`:*7 7"KOqHq锱"c6#5 !IDI((?``3C^:(Ú(L;|`Ԭ,!Wk:X! dl%H䪥wDX5 b5>PeĴJhÆZWf7DȮ#C 3\>b(D[5EL' E - VƂ4F[ J 5VD3lMyzQZ^6R҂FlOyy'lJlB$횋\KUDAA+5rA@EKFŚn/>hC׎fW~y:Jd+Q?Cbgs$iֳpaCŖnr=KxMῲ2vtBP]L>w: 256 "`l#j#:EFzpcskԤxx؂U&ELsUU3IPP|K6IAA@&v/ K(Kgǀ$ǎkst-2.0.3/src/images/svg_icons/x-zoom.svgz000644 001750 001750 00000032457 11544160207 021076 0ustar00synthsynth000000 000000 }YsH{ ^KW x511=w&>ve$Rty\2I$HvI`{s^ 棇aտ(MF?~}'?__]}]\,wW? ~w? z4z|5OOWWc~d<><;~ ]߬Fm>4HR|hފwݪWn=ݨן/? l/ DU5tWfJ٠ӈ5v=߼T|NKLɧl^MWntקl|u{?zu..O׏q{L??940y zrA ;| ԙfoq`q7Fzw=ͧ˱~^(ϿKS`kLon& Qw`jp~6ޘ-3Nj $-/$;^9(FKs!pgq2&]>iϤ,͡z5? 0x=pDv̗DOD̤Jf.?08B?ޤM!k}(s"7TNgk{1&Dq<wwGJGVH5~#&mf+mv>/.F;+nkW$Ͼ }jtqiI}~6ؤ)n*]W3'5t\s'LJ5ހץZՀ-Up Q a*[gﲱrgJiY r1]WKvKa硛4hT2*ei)BH)EX\)ql#g#7޼\\#M\֕'0H*0^O87t I":9)tOY > AuǐAa{#y9:e'gLچ9r蚴%%}pܶ1΂Z5 TN^TtS0d[*Wy=,*j o_(KUՆfYDP-r7aI?ce ei4歒y f0Nmӊ\ڬ1:o[.]Kʆ>oyweg[|ܦ'^HONyr X7|ψjt;Z '2;mƔ We3\GiPLU UL1␆J/$Jt2 FLT@kB)*n7M?>LlMcmg7&o'&&oC('.Qhŝ9s8 rGH+!O#%_C2ʺ<,e|\l'H]Kuz4i(|wEl5\{iag o2 XM[c/ X*\aƳ՚rWptoaX):Id^D([0[xDjf+M-bu;E e.6L1-:x("HzZ{'0ꈎ;<4ߠu xe i pA vR=Ao `Rp9=;jeh hyU`s]k5O)C7(Ph|V%h ##aj,}k&$L m1>'diSO<#^nVyhvG:pDs;Q:6op YnSoUE{ܟ؂lONvx=$J[͎gd{Vku&8{D1};1':5j. a o_c:ц(;243m:ʵߟ[ذWِ;y\1'ebg;lz~oF=Q*/9;eˡ'nFe!ӴW:iy奥6TC="Y΂l!B4 56gY2hkq"tPX:m|xSjFXF1pOݔ3euz5pѕ(肯MN6Yn |f|;1J]fG#B'.08ړk/RIދmf іp*NaK6J +IgMA-i{kxH;#юv A,NfsFRhFJeF (#EY@ 6ۂ~*ֳř1-kM mzu,=ڣ>U~k f\uPB׽χhuXlkV(U6*M/=j\IC @UXaQݚ$l`>d ބ Ba,fJ E 1`?v8hںV>yh)z5+Fo&!$p{ 3qW=>W/}-NJGZ-c%R%ީU)wN4C DV)e>MVm[k)%79X4c(r˩g}k(qf;sO׺}[pV9ɖԱz("^4ʾ("|1PU y1PE h yy1PZ9^6"3]u۳x8DEcBTx{s1"b&Znm/*)z?FDCG#q.ʵL}Q43 }!S-Rv!ڳh6}ܶ{ZL ;(E.c_@-Z9 p6lԐƗ&zpifcocWh&fb4n׵ ~;;6>_ jE;kSsdC΁hk4L1n㤶Iz1Z8kvϕ7WD'6Hg-:HIYml}m5ʦokiB&@׼K^6)l,VfXfgj9(F6N0 n8se\_coc\?+2-dT|@yTZn{#dp&y'oĺ-MTid`p7~QަsZ$\ Z/аS˺O#̢|f+]: \^#ͳ/6:CRAO@YA36 v_`*tuNq:UZŷ (R_ 3x̑b&1w6єwSYS4#ZPH]~P#6^JG9]ij}F?ch=M4Rw8<U wAPtH3@Q0mzȚ]gMK^}K5 {d#hvL^[yV#V.K8./~/3`RB2r=CG}7^Zҧ:wP쬭mĝ]|:p lU){ ^l2hڤd#TYؤ3KVȅ&^S~=6))2[uTNQV}ƂCԮZڶ5q2J:oUM F9&x 3pE,B3Q*N GIaX/4L!f# c n<̅ű䂭7I=qjsNzuxp[,G7,[C+ۍ 8JV4ѽb|8)f5wo}*5v4چv˥do'/opo.F.weq'`r'?o\>F܇UU.`m_q2{zo!STM|oާCj0x=HI2w/ HsDK#c>Uc64}Ŀ'o^m_7u(9 Pf4#Vuֵܿݽ0ÏsğҷrGOzQ<4z$}gzwW8eӨ]fUynx QŮ}=H+:EM9 QIU[bu!$F}^7Lwk3-)WÅ}.1՞FNQ68-v-v׶_]r-5"m*bg9Ռ*"i?rlU <ȕ;P͏{ZRp (k5 ǁg0]@qbk.ӁѴ8ԱU*1/(kK`(WKbaU!PhwرmU`5GhJNjҩSArXUN`2{ZwfKu.aIL 0 Wƙ=cX޹J U.%'wK7Q7Q,u^#:TgЙ әpAѶ+3^y훤3Xat iH/ΜuC_ :\8f>4IGx|ֳ>F2X2hϊ&sNElR_cVOQ\{tRoE4 B,ll`˷x!eDp8rQ1mѪgsLa:ΕKWyΣhD犍_ cэ<SkF^kub3/Ku`%tWQŌ(b_3zA: 3x[%)3+J-|tߧ E(N[9[♌9⾙xsD}7EsK vf>Ul)r]h $` ³Buʹߑ%]:{K;-I*taw{r!?NFK6e/"{SU Ji]E.^v!3C :ď<6$ov?-g gΛ2zUN&/ÈƑcItI9 Q5Ty'vH#l8/7,k b%d B/HFwF6A~h^Xٹz͐렄E5>#.ZGV|1m2պO$mv̦=#Sک &UDsw ,،39E0}:_*_<_(-2.9ލƿ*IraTLGaT3',hK+<YyD9AFUg qo{كKg8*b_J:hWwI7U!.;tYf y&!։bO ȩ B>DO^b-t[s/5޲E -]) &V1 o.}`AKX>~|7#`nFw+Ȭn?<~oXt>^Oӻ h<4%jܲ~"~^IV;`u/?ՀͯGnoL3CF\fn)ٿgMqǿJ.V _uysQIW?7.1a &;Ṫ]7i >d>G냻"\7yv}5?٪`@.qפm/8WOOw !/VMfD뫫r:{[tpvXxtdČ~Xt*UxdtKm NVZbc/L< }GuG~Zz݄Jm Dի&'3lAh-ӓ<Φ6?>U =x6nqQO9 Nf%sϞ}߿&~w;s-miC&}zA ֹ"w7/[߾M?</i׻QCP2bLj|w&6o['}k2"HK,yQk#:gƀg4TC{ 6q4_ߙ5=ǒI_WAnkX:T˺`^5HN:@9c1KUND5$%j)J|j( ?ᆐ!*W %y+M@cXxɅ.ee/zw+[ňJfkO%ׯkly5}1{oq=l9>W}gik:CqkQj:eQlQWn!ZψRCs!ٿ_19Z%-9ZNV/}~zqd6i?4qH O;/#%w50rSʁN!ҸDq@0 0uPa?Lih ږI"kʷT  "KF7#FJ !!*XqZ1#5&*v6@hL8V,bX2 d,C0Zx#&L|/S" ޟ{oa@V?X%;TفtY3OyC!0]f˶gퟄ&k{Ub{8p̦5 megvQD%!DaXfXӼ&[lc<d{P!;ao$F@\r* 2#j 8q\3tA94Wtah%⠨v+ Aji OhQ"'[x J`8QRO.4]|8=W'm?tq(IPq= Uq+}8U$L$ )D3T]k8n{O4DJIj1ŞG#^H|' #0ʳ? ֻ@E{-(?hy>$H bgAlTI3W@ ۯrHXft*vx0x $ (}#i]zF&$P*zc@Nhg8vl+t%h7+tƦF, @ vw20 ԃh8-DPCOplq#"xpt"-#8H4%5 \Xn_rGG\La٢ڑ@M9$ e+XY)`8|C K'A$"b PIxcXCa/ hFN; .2s$`cg `i:f_~/l9BXn!]A^-!+ aChX m.1G( ft Ddn!R%sepGȃQ:R>*`bWF$yF!S}OO  ?1{۶) A>*a" N-"A4 `$L"P-n#X@ _=ϼsIqXf.)JtZ݂V!UͲdujLzۯ%GGf}FO%% 1yZ4(A9!{}աoޅ*ѱɒfѤWUND 9L.OC-]RNGB҇Vi 䦡bG"3JH7e^9xHW4а I~`x1E (E `09 Ih4q1A/ ENZLM9<--Cٕ@g_o]G~}^Q1q)#i;e93:}vGW'CuS0K M cVb[ 6aQj !$i>)TcP Y/$Q1*$I֭(=mVMtx< ?OY g 3qm29H d&W6 DA' r**Ai9UA4A.hhyZh;3քuqF#@p%rlȪ lOؤ>*Py8b,62Es/ڤrdcZAZ;i$='m,QYd U NDR%24)yth^>@%]9iIwR 魖r84Z"X! jhI=LLe ";n=X& Hle(`~=evl7FÅEu v{\e(_D6_[Dcqj1 %/ R"%!Sia:ꯊB!ֺ$`5}:"C)1`|[{EHǀ&0t(ydmc@"&GE2H(PF(h‚t,1@g PEAJO VֹDRO2*u5JäK!T$W,rC5 Tk3 3uWDFDVOVX$Qf(IgACb5IðD̤ 8 WrBѪ>ws,Dv`݀} P *Ckrif,@7# x?V 4@ASJ*2j7[`r|q*Vչ; zBLN htA&3 ^K Ni): %@Ѐ4@r,+*$,K t2tmZd%$ym0x8%(zAptRөE4E- +q)B@`ZqrE-ddg0eEb=ٳA_Џ4g/O_dXx'>X2F41'c(!BH Jskq-4n*ZMvn((G P.CxHPb+CA:ĦK8BYX 0Rr݄kht/hzĀjJ9Y q &gNKɠp_֯3t K L瀵3>1arXp8T%gmn&1<ǩB:Ҳ<.a$V]KdHM.J1XΥC(7T_Y߳ [al0CSkFlz+quoiF6q!)XBɇԯV74Tj]dAt|}9cۓM>mOʃӃ ưkA0*H̽(Ppm<|zrH#դyۋ`7`-f!VP<-$衡a<{g3힑Cy%3r=LiZi2- m5DˀG7[ Y"kS/iY5 $Mـը{c*ҊDr-T&meh9T2B&O; 촣 U"&&z [Mp,4dMw n4QjPOH;|  9UT[ݵ\8?3?rkst-2.0.3/src/images/svg_icons/arrow.svg000644 001750 001750 00000016513 11544160207 020600 0ustar00synthsynth000000 000000 arrow-right-blue buttons webpage hash computer arrow shape Benji Park Benji Park Benji Park image/svg+xml en kst-2.0.3/src/images/svg_icons/page-previous.svgz000644 001750 001750 00000017042 11544160207 022424 0ustar00synthsynth000000 000000 ][sȕ~ %%Z}hl$KZo.mf(RR4>FDl eO454Ot|9NV #d/l?~ٓj=ZLF"~sX'?Nj8|uzj8n~Y Hz3P:'Ť(zW?0 ɧt"#|/oOߏ>_)ɸ>et2>mX96ox}%< \~4N&Ӳ/_6bιSO9Ez\GQVUۭRz 6-ku0-~Lzt8AVdOΘ,/ˋ% ts^xu7ǫ|zl|3_f'hmz)}_.oN1_Η_ޜ|f7b?׏~[_͛a\g9KU|n/ 8+_7U$ \YQy# c>ϖ+~}w?E'YA6Gj֏s辀ଊ@ya4mN?-olVtOg->0p.qmm޾U34plߓb2zvNfC6ؐ#sV K{?9pPECkifc1[Yy?V^F4UBA:XL'v/"6Uyzf:r;~_K/ ӛҋuklPz]C`S.Qd7Zt&IgBR(Yn})w`e[~ #YR$0S vD-Z WfCčbtA14=Ō`>P6vtgz㌇pԹ.Tع"TiL+ hңE5Va7oә/ytQ"iDܡit4M[%wDjNM4՜ø`ͬFx: Vu x̭c\VX1j>Pݴ"a ؖ&mĉ5 pX4췢2cf6K-RKLpUM%ҜfESf 7M~d€ք(lbڙFԡlJ,Sd󂎐 c8NNtݸ]'Xd+c(]d;8) ű>VJ/K/>ޓ(_M>5lGYbhL5zjRX 0e5s駱W?{BJ&> 9Ǔ֧zTJxrOOZw41܂,8zhVZaWNRbH8 +}aS/lR IQU>G Gߙ8_Ђ8Z'Zn ^P,[OWÝ"f'lM{áڎCj;랐{%i}`2s=q*ŭm翫L yjeٻK^ lt2k^kX\t3GrYXjde%//M2i1G/Re0MpHXps/-ViK$ \[r `$AAFFRκ?́F1r' JԧBC9u(z; 1Y{Vn,Wͅ|3pE`?¸&[˥ Pe~6y H>n/7햛e2v:eI@/݄'3Pq:c셁7Ucߖ[s ظnl{>C_řvTl$:Gc4ݫwlėX}Z~A0ߜLGBt-/} S=D77|$xRhj1>Η7yJ#/:Y-zX=<-L_z-hԼudœK|iܜ͟r [8C8~ b7J}[6^&Xq)4Cs>+z>sNw|(^|k0%$tܫ)^^xdzo_gZ&#,{܍p|y~n}lT]y &;HlֽF'p~=~S8zM{/~/brB%bH_>.ǣ}2qE#,Wg|I$$דI7kjm˲3@:7.(EQ"O'hd`:/.-tf|";"SFY.H Q8j1x /Ǜ+J>[-0/*6:9->_laOՓ8U~ZIe6@8Kd/M`_}yĒяd^EJ7|% ٕ3dHijM|oY?70@ohh4TA҃DR2PzuFzmЌJcMt^ĸ㷖ҿzW/i/eQ<'KCeQرBHGbtX'T^"Z.L¨CEMWy@ڏ@ڛ@z@ J!#g@ OjJWbV\nަ+]0]ʹr\ p_zC)āA"-6X,߸0V4g͡9~{7f!"m(9?ޣ!=m<7=!P; bu=g\C*?61k+.BU.B)>&{1gU=ȉPK-ZnPP ,; ^4DALʙ{}ɉ7, D^-yw <yNSC) v&/w%]%'we=(FTj jD(xwnkM(pAq 1y:ulzUS_ ;+}ߑU+g6a> VXDŽmKՌ ](wuX /hG6)9xɨk_>,$4Vbچy]^2>& uW5E"(LK8cǕ9'RI3.Ey&K:Gl5~_Gj@7wǚBoM B-)tEpD_YAY!#`x9#%澞|825 /jq@ A$1a#g!AOpGGBA&<~:f aH !\br# fknj 2Λ 1ގ 4hB &ה0ɠ=?{ox|EM`/|6%{qܜAqva/эUt0nK:: Caz (,XQ"@*U NWlPD9I[$m{?ZJ_d.vi>&*i\ PW2PpF$p Sʾ|\0M.o,:ujNy%XaZWogpLzOYwqN6ϒuK &`%WM&W^wW q^na.P]@ ]WF~MXi[_J_lU{zwq.X+Z-Ҹf_b{.mJlwp&,ຘ6׵r; r.//dYUޗ>orX0.r^+d^P690վ!v([BӈSB5Hzh鼴RڼWW;+!V_n4; ʪC" 0z`QCt#olN6hH$Z:ѫ$M?-aPwI1l7![tsXAmT=vT[CiGoB&~)dPq69b;Am3 |{` Q^_oTk|! ;#ۼ$7ae7;(d pYWWfMV6#JZ㞧D0o=-;ŸuþRnÍ,Lj[ߩflߍxk叽 r;:>15]Q'e+?A1Ĺ}gMVb֟ ?`[ XJWцI Hf^LrL($z$WˤgCe[.}Lz? Iq`H ~6|t)koi e2]ZBy,INOe(,1BKH8I"eG$L"; ȎG%R-[D*ɩPMK77&A T0ʡ`ӝ <K&*u5(stTʳXkAToɼY z~(;uʄ%pyJ)& BVF+Z 8U~/{?B_~yE/?s}˫+vՕ6 M}.y/4]/@/?V;o_{MA7 Z:mKfVdZHm+ד]_\^drַണаX{ﮂCV5&蓤&C8UZ`^ǟ]vdQmQEhTףF2X'{[!@k5pn $R*(~ uyC5*HjTiTFըA , WWfca5?ۢX_A7~fHH9Eאڴ>#㸜6^a HpGq1 1bGJFeSkAĄCi*D[ _:`_ӝҎVFeC/VOhݸངO5.mo4K+֟`*A?g?֫hpkW?ʎ1u5>[,Oq2/[!۰an%Z.*ր/Sbk. d|Fff~Fr 7,Ir\9&L;^{DjRc{pZXWp;5Ն0|0扸g1 u?jR*4<]M, &(YNkv!$ˬR@{C5\כ_`pT|bt15,![Nfrkӽ>?H`ITVpҫ'_C4Hzy a _)kl$io/+.,-]tqmvb6=K>M>Yh@`kW ɬYoLś;CoQNbmMYhO2Hs:6 1p$1F`J͸e'Ὲ(\~a[X4x|] ]Vj)`►2C6mʀ6]?Xiכt)9ZI;rӿ"pʑj߽sc} {7#0=8ֆ5f2]Y8d X7uzI?&_Z,Sw 0~n5;P()EBRu1VL%2LS\Ǭଥ` JՂ8,rU{9fh; # S UH) X!@YqKZPz~ UFƘ!f!:+)HzYK\c̔DI-Cp{CZ2Bq%0J-4+t3Qik+Y  u lF'͙yTWQ@Od  D}KhŴPenB /Zn+ZZ $6T!aVefYK9{.)V!σE1,)9ʤ`"HI8Hy~$@ b WkWlHZCD(Q՟ XNm品 lb7uol='6j tRU+,E̘P5uinuO~%'LiRAQFW%@<%YP%820IKIKNG%Vs3B&;798Iƻ40>8x[bGaXZ몹Q4FD:ƙSZ~A({BN$qDZñ#:.f1hKHa c]&,D-+4DH "[EXq)]4Lz3Ɓ N U"fMpAF"lי<(cxZZ`w RLrH BU ¡3bfo_7i&攧D,xTCVW-%z,lKg1V)ӟ*e*BVxfxPYS=W{xMM-/gI?@|ݏ/~k =Q.EXXnG6vJZJ_*ۉ7)'aa51lgH[_ߞS#@7O̠DD`n'B >o$z>@=?0^p15vM#Ը݋+"TY] 1&TZѦ!"EI_Eʆ~&`Y|xU[aŐU'ʃ8bUkଥ`ym!5sfQ2jۼZpxAsB\Ġ߻|7:@נ ~l+sV?Qg '&}-ȭ&2<f*{|RW3NУ"zY.&u6ͽAɑ}`SvJWC0`a .@b7py[z >Ayn?O.}N%-8_W0O2j%#`hww<_Mhe6je<|d_:PFF,67T AӸ}+V4Ѣ=gjNzUm|9]}iۓ?c1Z2nvu;&",A -Tß{7U:MҲ R;#cۡvg_1I_Wk['[)[aƽl$mEnVMzl_ܾcDحݧHk2-lMY`o2^]ȤVtu4\O6PgW[TZI_ܺ޲G{A=P,;0~A-sn^ۢ|{7o-UA8lZgQ[e^-y!'՛dOM\p|q޾7Tb>IPW;+:ok0%$dkD.CI=xf29*[x_nz{fx֝PfO-c9p-lipz&tr=/mN[|H޺ڋy^L/:,<,h nw?jonC[twflXdZ"Z"m4kq? d&d eX RJTE<O=QcxMKUQoX"Cw{JݘC EI鮞,aEBGُWiH]usR)Dv`Ѓ.)Dfcv;25 /j1rO A8Qa#g!ea`+ 1 Z6P BTbqÅgΊZdw6xdAkB!Hu2h{1:r{<` >($nt; @}3M ž6pP`ll}kAsrA%xkOW쯂mFUw SʦmgrwN'sH%M-MmopZvH=rJ12fOTj!2̄C"P;ɇ, Eg8M*0|G溧}+8 &  [Xt&!i%6U.^ޱis1X$xLӋwY/y_R+6\yaޝ7y>60Ltdu;Lw;u7UmusyCW99%VK5t'gʜ6 SrFuSwn]dS,M#n88mbyӎ&ٸE`e'K49C,뉋w]l2/(_1NBTվ#v] ț]D譋&xwLzHn`P74]lwCw,f,4Ƃ&wIR R-1 9z:rx'dȱǞ%풣/^f8 y{]U;2/ LvKg<(3~Kߛz~vӞ LB\r1;kxj2Hph"'>uKtGOO3Y~_)F&-ȥD3^FJ:ywrqbuco.ygMOLUGU0}֬&JyDӪYWpI+_=OD+ F̹h]ȂwV^LRL($z$g$φˤ7'\&`~&lPIdl=˝̥w ApI 1'cʘiXqB(H"yIDv|9,_K$[`-T";&B%cn*X"sSa)DPqQM σƶvo~ITuWJ ,V1 |,4XDm$O,:Q6y@#/ϭӑ(ϲc *;^&S)%žⓓfEiܩy=*{TRY%" ٲhMd%Șro5ނE~-yZo_gͺ\O[gl*?S;K3ڨ}&v#^K㭫z ";5m#@H"R: CoOvzrzv*ulbHM[_?uul]^UphʣjX}dBWx aK7kԎ 5P47rjԨYkVnO> @{5Ȟ`H% 8B4* ըc7Pk<=fR6 "i|8MFcy}Z9gIWjQ~6Aى q:+GWC;S`=Qh;Kgd]'# pm/`HB~] ;'0擁 ׃A}ͫ`X,֧G7xy{~9Z_m+Ws\O<54'm*mfcv wW.?&Ӽ/_c1ǔF"Z?.6|)R1>sۖZΎKf&GqG&Ѐjc<~ǟ֛j|<O{iarD9+Xwv'ޏ׸Tʩdl7IYcI1Oq'4]r\MU~ R:B}p% Կ+\>5lcc)tx߯V|Ov{pG[Q_,GѼ:"{"[V7x{%J{&ZϦ=ngǓx֋]t3_^#>V_WW1}7L^J$т>;X нݓ{|bMhmm߇9mc9%3Ulw='cvf/8~~fug_Ӈ{1O}ƀvU%ٯO~5p@}ATyce}#`NӝN&NӝNVn48N(&IQ* AL}Wk@J fX$ۋ= FH_2)*Ʈ~ܧcxJ{CWSJWf+xb )ΥgQ{ԤV&v0rpZ 7P~hio4|O [\2ckO$c̕6A7x完_^:6ˢ$i#K}eQѾY8EB&]6-H9=XjSŒ0l(0ҮbSR~RR}R)UPm-)1HP͝R,aXnӖZ6#FR) JR=)Dju:w#6ɶu;" r.hR} 9R[W!nDCDP"R'Gcv1od y"~g;MƛlMYUg]\|JM:CJm~J- XvpdٽȉV.oX<[0fOiiILgwᗜP܅+Vt5FKK$Eܩ&5'.H/7KýA o-ل&pe[|pvؿ%ώm{ٗ|"4< pKƋQb M0|ɨK_/$4cڄyY^2>& uW6E0N0(!YF7mNИ䨲 #*BY~$B;ͣxrR+å I j՛UkS);¶P3Aە p: SͰC]Pr޼ 3[; 0rؗzaP= " xD)Lj2r(B z"<,|04!.*gd..e mJ׻VĂ1$-Ԯ~Y-+G5\ $v%kKƗT" sM&W^wg@_j}~N\&ڀf8i A}/F~MURS_RֲUzzw~II+jɼBj_b{N.J?lwpl&Dl⦫*Fܿrڲ J6Ey gUK)}{yj }+Jj7{WLŴ7N+*yW`z"*-Iɍvs*NqV+8؍${z`AYuX8d=;l=0jBiM%"0 !Nj*^-S[ţ_ĖUVfQZ$`A7Bc,(^'Il&HE?p&dȱ˞-N/6ܦ? y:7>{QAkݫfm^+՚o>A fm^ޥ7anW@)P gZAkeg&"^_k}˩[[0z]wW՞{K723MA.}'~7RJ}wgWgڗ?VwTjyTt ծk!;}/?i+eQ97mXH,6 Rdc@ 8]b X\m-l"pO]t4fWTI)#7R= {dԖ!m}Ivd $8z,2D1_B\s q'Ϸyz-l޶Yll.QIxI;I_~WI7A;gDj8Q&2WǨ -aݵ,meFa1$R;e"UQߒ2 ak0*Dz0-ڴ۝Mr ؟t;d0eb@{Apw5f@-7k <5ɤ7~Zeb%MlRmgȁ}]d9rW52hAUG)YtR l'v2Bm$csOld?o| D|sR*#aR:0aH_Rt=H`;Sƣ82CEUIluqYo%[x1f˜~xx,h)^%qwlaE?'Dף񧛕%d4GLwHA@¬}+ߌE]UT+Clt盷#7Px&kst-2.0.3/src/images/svg_icons/layoutmode.svg000644 001750 001750 00000047176 11544160207 021641 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/edit_vector.svg000644 001750 001750 00000036057 11544160207 021762 0ustar00synthsynth000000 000000 image/svg+xml X * kst-2.0.3/src/images/svg_icons/new_vector.svg000644 001750 001750 00000032504 11544160207 021617 0ustar00synthsynth000000 000000 image/svg+xml X * kst-2.0.3/src/images/svg_icons/datamode.svg000644 001750 001750 00000030340 11544160207 021216 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/data_manager.svg000644 001750 001750 00000040377 11544160207 022056 0ustar00synthsynth000000 000000 image/svg+xml Data Manager cbn 42.618.433.522.8 kst-2.0.3/src/images/svg_icons/tied-zoom.svg000644 001750 001750 00000267611 11544160207 021364 0ustar00synthsynth000000 000000 image/svg+xml Oxygen team kst-2.0.3/src/images/svg_icons/end.svg000644 001750 001750 00000027307 11544160207 020217 0ustar00synthsynth000000 000000 image/svg+xml (X,Y) kst-2.0.3/src/images/svg_icons/changefile2.svg000644 001750 001750 00000052457 11544160207 021624 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/new_curve.svg000644 001750 001750 00000034457 11544160207 021452 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/lr_arrow.svg000644 001750 001750 00000033310 11544160207 021267 0ustar00synthsynth000000 000000 arrow-right-blue buttons webpage hash computer arrow shape Benji Park Benji Park Benji Park image/svg+xml en kst-2.0.3/src/images/svg_icons/kst.svg000644 001750 001750 00000351703 11544160207 020252 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/y-zoom.svgz000644 001750 001750 00000032107 11544160207 021067 0ustar00synthsynth000000 000000 }isFw nK;>mOL;&ggb;cEQUZKb_ϓI AJ&7nY7xzs7f<=ތwMӇsj4NdJ+ (??GxܭJq#ۍz2]ݰP>O?Ɠ[9)'?O/ QojYB1ocKGx|xw3lP!~r|Oo>O/ DU5tWfJ٠ӈ5v3z2>KOOټT#O&Wwl|u0zu..O7OeyߘӇ?'j]t k.l@|ng&o~Ɨ?Ln9<cy&_f;L5Hi9?|XvEc4?|gz{<Vڵs7holdv Wx\ug iy9 i H?D|0Zꘛ6.mkOΧɘv?4Ռk'@`v ##>W#$/yH/3t{V0i,iY>OD̤Jf.?0鍜o&ֵ`6H SŞ|oyqfsFZ@Rh{J:=0W7A6Qm3[iyyw1Jwф]qver{Пތ?>? o&r|9ڭ~ǻ9ϓߨ?'[>=>C;~h>9-eA(| T1eJ5e!$thd+Vu#=Оf/28>p9MZFc:\[Tһetk(aMimdeC6+u\ \] ͞F; X=)q1\$jD2vo*PAIkFSg^}vK-UqX lw`TTfSDx1]s]Pl!VjT#oA鍉eƵ W*]?Ke` 4ZehaH` m73F]R/[ozgNks踖f;)LJ3ހץZՀ-Up Q a*[gﲱrgJiy r1]WKvKaa4hT2*eiz!tlGRJx)# $A7Hʖ 9]ER6>HJ37ڛƚprXtqYW[SaTJa^S87t Y":9)U㇧7Rnp18HR&x*`i7BzD\-;%llXh_Pt ;]:cٰ1eFk=}];G ?ԔeIɒ2!J@^r(qU'%V>N 2sC!LC)w&.<v]2'kend74gGZǸh^ : QpA0 ^X0fiaq TID+m`gʼ!2` {8Nq0;vrFiN@ >=(/’^0⎌@S_v3X04VH5R_ʄn0QhW[W)ucA:Cc0f? Ku kh ָmv]!Y| ś3,~U!̌N3PAMaAJiU(_izcHƬ(a`t l .k0u_ {~уaj+B5 ә9,?1ʫ.}POi,^j_FSxW@XzKjzip7abm_U#)B,h0XCy/lO]F`$]n:),@T{d3Mw}`5نFP Ool2Z`JG'TڨF:!At\rFAڋNw%[<ζTz8;5WӺf7'":茱|;lfpe] /_[f4.je=Ժ>ֵͨ=uژꕥW/>HwˠQ?fnkF6\,AACv,=dw =ΎM "0D'-\`F=eRVZ5hpAn=N*U$}7[F!m"7ji&P8ornlE@(PQmrHt]"fTJnPBxrjA l=M턥% v/:ؖ(Nji0ɚ;8_ f9sK,q:\YI6Hw|bP]y~o}Dyd6Z4ZJ{R(u>2r1D,\Pi_$ cȎ0dwEHAGDžE۰GN]D^䫶Nq>YЊKN``l:Y*om}0_]p{KWviڰ, ȃMX5~XCctZr=ydރv64@n>;6λ7Krһ| bG"hA^t]??i+=cpq>Cg#֍ Z3qw~CLfOИRlfH72 ] TP%#4 Lz!O.AU K0Z%C N'VRZJVyw{h 7afnwV.o 8m1ty;7QtyB9u)R@5.y1h# ȫ|tR2 {-{R@IXk :ĉ Ioк]ve ˗i p{˅*iQm;@{N;F4=xsl \G_m|>.Ahads`fLIu#b|OȀK ӦxG0ѱ D|2'uV\)CTZ5l,#[J{]Ϙa2[kjg5pѕ'59Q_k>4lm&%+ `4's*EtYYۏ0 T "޺2gkONK%' {/5[]q [:PZh#;DZ$њ,[\[}vF3 3kYPfsFRhfPf\JK c3+  d ބ Ba,>h3 r1a?v8hچV_R>ex){ 7B8R的 IW׼=>6V/}ui+Yr/NG{D3uyPޫL=*:<)xT-5z8)%794chr۩g}'DFѸ!vd u'ҭsmg۩cQl({( sL(΁2rk΁2-rEsˁ´:0<䈰a9Us:`l=1NQ!oR<&W\DmqѢx?OPD::y+wQdjlYY(+ u?7f* ўFm*԰:^2&E (6@!NֆSO"*ZWvmvl3:2SZOq; Y~#Nw?9qulR]+qP61RE Zl|cH{eczP;/3.RZQ0:v%ʃ lb ^mȮu*gmDz(Έ:$nx>yz?V#*$yTL{$#ӇGckkIIFP#5sL7R{Lg*SlOlZNxVz;[ջͶm9KRO<-dR v #5ʓP+<^Jmv;z5z콠ڨ>G&aЃY!glܛ.]3ݺ:'ٱ3Vek1* v&Xߺ >ipv :Jd*5~IKcD_2~%׽ ~B+M:sv0q ;$1izG `^nV]~ hWQNR]]URF-aY unT/;A_:gʹjtʅt8y L}۟Q.oGHu6onVSO] >5q2_ *mUMWN8GچRb|tzDz5azZdU6wS:S1b:{w RN~{,0;O՘g9gZ3g]qw?+_~ayar3Q*i31qKʠwIш_'h)E5Ѯ,y49&&v3KLKخyñQĨ050̘o h [C +}]-^9o oug2jΑuek"*7Mbyz[J\lf|ZFa{2ol*%xy2<%]^:GK;-Mvw*ao`Աm}Qy^bLx+u]M{{kͶ,1p?Ԏv~K{?,JS]ؠ9oU' 뢂R$R@7Z1,&}H^<*E~Εraa9v47 .cK/3\s9$7S7u]c}Źl/E̮.`p*W?t#S!uvH6s޲Zk ٙ`Ʀݍv1As4PáRpb[bo8loO@& ZVlvIga>[+&όM8&W5aӉ0wIkxˁ3vyY:\UBCxtNT Tsk< "J?ZzgSŸ$wH9ĖžJe E>\t}ڥfT.'i,(ZBl l~4HT\pPьDo1_se?S.FHL7cT(nf @sKcW٧DƉZܮmYCe52Tžzv}R)Ku+a ,։bOqx' J=woH<0M@Oj kˠf[#Yn ֮-PT`x0.NBN"2i4<Н{!Niq٢ֽm#{;x&=|8_9Kn~(zRu3\.U3ZEHYZPV+K݂'#H>Lˈ(# }Pm+xu3/G,Edd,vm:ic[@ԬePZ%QL8T p.~W߉ݽբlFB#;ܦ!&'rTݫ춶C; =++8ah+'fl99̐L66QqЖf˩dҋa/Pw 0ӹzu# Vz623cU|(a|EOfGk)1V0Z̔C4p5HP?^LnӧUarw+]V}$. Vzf2[~O+NUG/օ5x{f-W72>d.'!+;LaCȸFf3fq?Ūi+./~n^|&>#l_ܼDvVt0Lv|SCqU^njKz&ta2݌5.H-8}Jlu  ]O? V ݌ߒ?={/=V_4s;*aI-s, `4LF"P-n#a!8@=i^{X⹤ wP, j:Y}nAAk{D*fYM:sG5 XjW#0J#tT Wט42=Zlt0=Yʇzs*Tء$ {1&e[QɊI%Y1gv_=O" 0BId *;7ɻJ>ocu@t )@Sk ȁ瘅 D2%# :YSVAa Jad =L9;`рg ` ;FXJ` x/Ki:݂=ּJlȉN*6d=a@GU Xe'6/ldO7_I_Hv0#%IeM^;1t<2QoDv3L+V Q.pWC<%wU*6>]Wt)$L33I'*Y,&M@7ǪQI;( K)- tdCjޒɍX{v0 I>aI`nZi:A4RBZ_4#gh>O@>aW7RӃlr=]f zzWܣ^fʶz.o+gvCi4\XQg0궗UaEtg1M;JrMe, 5x)|! 3ԉ~US%{-\=XdB,9<#@ N1<6ͅ C)"$Sl҅1*G ϖNBBA4` l!>Lp*Qb| gXյ%6GZJQAEQ&] bbyEV+< U\Qͼg &2z T8*PJ=D^3ę=]zU ' =r&:H%%$8[儞WI|صV1CM+t' .tPX<ނ#/@ulO+ Po]4ƩX5qT 2 1R0πujF-31訔Cfb lh8.B`'/y/)zYéA1 Pc A-]-Y&fXq̴JW (3U(j v옧P$'>A,"r{*>=UX<S-H/XO|*]:Yb 'cJ J5~`"jEg # f0>1*V@mBCy" PTH`iJGhXeC%GMXZP >Ad+g)k LK*.k__2 K B}3:>1a Yp:Tdn&aHǩx|` i0N_G2TF֮ AX_eb}ōqP,!EmԛCGԯ4\FFlf+quoiN6y!,%XBɧԯV]o7˳+3Έ.akvKQ@03IПXdKCC ưkG@.SiU{3A'p/5j pҼRټ,Tz J(B9z!~6F g?9 )#u*lh|THn"Kaq[u!2ΙS}!빾4^d! S{c>[8|*v׽uuol^eY4Lc:@ɅЊZdZ1,S HT}f+Uvv']ĺDxR}UgDN $;2P}xma,0 r6¶z_kfA??i%Ck`kst-2.0.3/src/images/svg_icons/zoomzy.svg000644 001750 001750 00000043720 11544160207 021015 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/data_wizard.svg000644 001750 001750 00000043465 11544160207 021745 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/kst.svg.hold000644 001750 001750 00000351703 11544160207 021177 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/edit_equation.svg000644 001750 001750 00000037302 11544160207 022277 0ustar00synthsynth000000 000000 image/svg+xml f(x) kst-2.0.3/src/images/svg_icons/datamode_old.svg000644 001750 001750 00000027645 11544160207 022072 0ustar00synthsynth000000 000000 image/svg+xml (X,Y) kst-2.0.3/src/images/svg_icons/tiedzoom.svg000644 001750 001750 00000027606 11544160207 021305 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/changerange.svg000644 001750 001750 00000037501 11544160207 021710 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/svg_icons/data-manager.svgz000644 001750 001750 00000302015 11544160207 022154 0ustar00synthsynth000000 000000 Ldata-manager.svgײX%WpT'@ޝZ8 583"#2r]eu [=19fR A d}2U_+X֨Ov賿?ܜEk{7KuAG_o|=o-M?:0Mͺ_+?'?W,n_{sg5;k#iF!/ٯz0 uloG{_kD.|( Ʊ="6B2R "g-܋mǟBO#HYJ~: /A8FZo݊%új&ryyuқܾ%eANŠܣ_ڜaRbZqrhm }؈y՗8.~=cmo)YP<[325.5 ‘'Sų\:AuzE‰(j3. .Ӡtltr @@mX3\fbush'$?PP&ȋIDCA!}NF:V_ #2[89BgKOi$,&@G{z5Ni\[P~$?DSR&Ycū>-N%y$r A}' * 5#GBi3C4V𔚓6hԷ\]DM8X.!H^{|MF [N˄7d*C=er>t uP>$aXbdǣZ>kk)w)۾ce~Y4}<& {^U14$ ~Rbkwri#f4. S~a#ќS ^"2QLl8+ g1F#:r̀yԵgߝTdDa, )͖4486M8:GaQj1o/}~"xG;G-gs@\ B"swU1 xV^ Egp‹vdKk-i{~bxi.eG%[/a7t G-pn72` qX]D潾f<^9)QBU۸O6$yX*$ȒKa!8- ) :Jޓ84 s3>EGOsv_s >|x"nt$YdžwzueRYgT v3N+ 7)Ʋ Lz K{\bG gB:BN]%묛-K_@\ߜK!i\D"ar'YA6d.tzw!qߵoar-T~cQx3^M"&% 9߁5jP3ڕ.ܦϴ}Qԙ5;Jnߠ饼7L^,@F1eG&udz+@ϡ$sCD -/V;Cow(,ѵ(vwINv7ߩ?Vɳh=G^r7C;kP\/ޥ5˟Km1B;Z%}-1rޔ-6s9o{/qK r%53hߑlﴷt~_ˇof G~m1W|s;o4[5xv4*G) @y^OlRGc"&|vرHc*(i:*YjuJE0Sg~Nד 7Uw*{>rgW%MY@DHM1AU`WMJK_hQ^9 /&}9# 0By>O[u\0]^Dfx̺E P9 *ThT뺻UBDC2O`0;@&+ѴW4lhfzգp8̘x+!U֚{%iZ޶LO&WwM7S۠c,1Qkh1KAChUFqշ#+̀_ו7d;fNLMW@7@1^e4zioz#e6We.[7o+{n-K-bg.~> [8/6'e~$ iTiގWR`%z0P3u=j^*-A[iG-Fme9~Ŗn~:IXFtqeap~%^RP\~3 ao &쌦"oA 3pM`ga=%+TdvWg@Lžl ɶ>H/+xƀ* K$s1 >VbbN6A0={1!{VעB2ě}:{3)=(ƅV<׵#2.a}mcތKŇw~u!*vRû:O/u^|c~'eHHxmsLZ }i<Ӊx4C&mbo|zkQ6ao-{ xJ/O:1Nޔ%av-Z(TnxܐxKXQZItw60Eeo6^$LqXO{r.PQh}Pc%1u^KwWo3˖2,[PxAlG7րqd? աT^ mImѓ%xz^`3R?->a>kP<И"(j¡mt4Gx}&i{Xʕph;?K[0"4? `HhՃ@*ݸr'"GF/KG\+/^S`7(aUCvkn { gGOwa) >"N2Y2z vYYvw{o.}P'#!%߲(bט^3m?+YF_bE "*@kMM/NxӼƫ%} `$9 oĕGd̠(D2 Rn~\ZRE!e}=dj+Džcf-{Bdv>rDi ![,NmJN|b/}'++07Vk<[ɪx8fŋKCfz7 oW>(Ae#\Ȑ:s'`]/$ )G R܌KMU2*r(/:v%hKO^ M{t:H=?V;%L}>Yo#=R7.qGd*Y06Al)w!,z{ȳdG'yT4D~d7f$ӭGsft_VE/J 5dMU7I+1Mq}՘ϐ Ymcn({BqaEx1)qGƗR-dQ&VYgUt>eZAR#ܐY|_^ܞ=Em `h2\'sHgߙoH))1|A /  ,`wΖ=DuMܧoT=EOkxȌ `(Du+{Gݧ3z=9K 5y ֒<1K~8x>/8wϜm*8q{X ̙T)1VZ'v^ٲ(Eby9fG"Hj~P$sP[18wk##~Ǟ!j!SsiJ["1.CV:e?q%V__ç }}8y04?lZ:BdON7S 1N|:oF҂R+=e=;'<^/ I}|!Y*)[+.?O1s܇*:-B/ڻWMdp=orE7 E~?h[k1q0r,vzi :_~(J*UES۳=ǘ624 4èV:=U".PnnsW C#ef./Ne_ƚ)޾b&\*ի?¾A@KM K^J?bgAcX}]"*~0EHGKrH]vFc̾ÊsB^aV.Zn252tX]npHo@|hBק1qChrgFbHK1 ;C\v٘s/2Tلo͝_-\?<Ĩ|;/ϩ"1MwI&{-.x2.7)dؕ@c1ۜɘlB B]paȴSKM }#!Ke|CC0 x ʅ!Tk1$\eDHQ7O}g"5NTu|$⏓|w~ce8!ܔ]ل,<_#i>psgjRndFQ~م u?Toҝ}v0N)e59őݥ37;BaPa<}"֑8qw ճGqR.=X>FfMz˰z]xɗQۘ%uzُ[JAnR qP*һF rKB;|7xpQ%!Aϴ Ġ4_>%C /8G@O, @Wz5žre蘀_ځGm3M"Km`oun`VGu?W[ӡ&|[ʩo#:Mfx αyaw]ג\+[S˞XY˺7e/pѪ|˂4KaƔLS .&pq[{״B}/tq<\_%E=7գcnU̷7yڞ!|(6|n-m[i4x ɘ^(K;nM-MUߞ9+YGj@OD>5-z~;juZ"峩.6#Tׇ>:gVr4^uՙ. 6>HL_e,=ъi |>mGe-`r뛟k M29$!N܄l0^A &w,}fϳLlM ~Lpi5FE\D=af<&jUAIVث-au.7ϯ7cCr1~ؤ*>!uS| t1\uԔf=vhTv#/{yBϑgREuIÐUŹ8}b c8V[ O_GP_J4"(왟@B/w|N8B|ۖ+6 &ΙE1(>Du }jbP2$3e_Se2^QCDů"9)H׼wg ꟋԞ[_N0'GQ9s b9qgnd݄~IlJqDYx4 /;8_!wu!W l8j"vQ nU.iqKc6?A rF[,e`߷n-D9b55s 3*4D"i(ݛiRt[kKh?m*qI4ׁsW*ћѺ=֧ W7%.)j%{3y>FX^ݵP1YikH9aǩXRYFI*Z<(^Ϝ$&h\jW'NUX#4!^I6a%[R/φ2c)KV6ߒGofX[d'ަ9]2O` P{,/TbQqʇr/#9Nig@ a?Ӷ}ВqySBڮp?7pxő鲠WFmT:}WX#RSؾeIkbb'6.qyWS{b\![*wrP"\"B.ib-G8[%Wc=+eP|.>qŇ.{ *qc&ZmUK @{vmO1$\$H]#ֺY49}IfE"h2Fmpk;XkE⼋|*7+yX3FW&N򵬭CY\,h'"2xU _99 AaE4/C]z,jY#sr/SͲ"Ooٿ#[ըlۍzS/ oœ+Cd}h|RFOS_ĨВ}v8l`ޅSԇp7ɀŗ+OXW<adLv w" 4(H1%#2ռ)k4r(‘:[Qln1fd1YeV#zdz C;=6AWg*-Pr&2c˯\?a,hnWK]dq y{?D0y!K1(]Xd} y~CK^$pt2>$`Oe,\yҖ 3}|;Ȏ8 h(0q:E(sE#'붫%¬!m k w @ɩFH-I^o3m\Rc5"*_JWbP# &Kbr's- <ߘb&j"'\-Vbn Ky+2{M3x_AUnAf46!F呹v /9-;*xH0vT{ WZ-ؾ&yoUX' xlj:Х,Nց%$sپq$cNfGaMˍ mYsis <<=}~Mc[on|L&"Ź_˶gs%2W[d}ʕqRſb\ ֒@b}%ecmRL1;u1fAuSL+5 3Xt0`\.^wF1dZ|W54)G[\$8ASAy#M6~F I9ך(`D[,%i"¢EIBY8wgݭgi*WrwS!NZF>7Y(狨Dyxp$PM gHO~;5,3?D9mي_J"Y2 OJ{]%[5~n<!T1Y.\~0 | %CҹUbd@s0˽/GQ>qDgߠUx̎5Gjq#^B/U4V=@q`dr9x *~J#a 2Cdakc\} _JL,7+PEG# `Q9>,dtr~9ˏJυ-v]ouLaҡBݎd&9ިq+կȽscP]g:An㹈7}> G$T:?O H~ Z;5:T`..Zb" lE>z$3":o1m8R+WV=i,c&bP^֣"uvnCL<$d*؃m_}; K Pm.O'ы?x#>x8i7OR+K`XT6믽Mؿ%Q"+xWi"d G*Thi\܀hzpo4`s`CˮHR@R[щUj_?$mNS}s` q*03}UxCN'̝&F%a^x E }Q?~P-S9y K[p֯UAֿލ-A_RJ?aW\pNpFVqsZzXo^љհ7X xi7L?mQߥZ}7b٦o H }eڥ"f|bUOܸ#LYDѯ#ϫOr9ц0oKU, #=&>/jN GYx]Odr>ۥ-D?1jy15\z`g563Lnmp:s}׉K|Y(kwi1}x5ZI^ ӎy,E eUd7#EKV=~%qUc <^8+e 1<ΰMVٟGG2?.}t=-΍WarF$ ho9҆Z3WĖ^nYLJ#S}c8JpBR!?T AtxlN;~[ڴ8@H95Ԟo8f-CQM9?ɓܯJTE4^PTt( vPK 38> i!Ig-+f-dWQ~#"L1ơ$K@(cYCvKu*612Xxp7Ʒ7Q}}z!Ut'| :> w0KM&G H0g/@ 5pD0e^6AycPǦ(wF4êٰ=H}A7Dj?ۺNMd=C"y k`+9ĸ~^m 2AX(WS_ن[jJo~,jxx[qmD}EJg"ՔbEg(\2vPNÏޭ;NyU+s⒜{^!iIa1e< x[H<aAl~/'Y.{Zf⪺]C `aԴ=ИZ /m9T;\οb;ÝOloOAG"haMXJ8 29pۄKzx74L?512/͈ϛ *1ŷi d ٨: TJ29DŽlLr ~&[Di#"#-L{N+ Ha??^S%N|~|iN@rӌ7g2r}y![mP;6 MY4sd`~v!%ᆕ N}mLy(Fu`(wF} HT4p+Ӳu&K{KCMB2D'G6S ֪0@&ډ?5\h"vyTX LnlL ШCsB.~T?% =3lJ%)6yt: H%> }ovˑt7mʆ7?9 !8֡:I$"]pF&CUI1l &kE(*Wby^wM)9o2uXXi>T[3dž"9N BeF* ~<e&#G26? hU'''$b1(oS3\$, LwH-[u|<7J'PdKt,m(,HFߎؘ-\;^J0ߋQ;N?4Kr~c.RWְQgJT%]J'.-1{D&%G!βeW5;*&VO\`?'fEՐ%y~h7g ʝn\ֆ'´Mc ֠\9u*+L{]{"ܪhrI*w^˪X|GFI/~9CA؆yt$:D)Г*(Wha,A Oؿ u5pdV~AaF-Ŗۓ`-.vK|ϤYlʉcp$Hw:/ >D=c6h3=!g%aryoS Z=rlT5DŽVN&7o<ŀ"ZP z2WӭCaG6&s8]i+kv|3.j"xNz^kF`,)Ҁ[Ԣ7-c#R#wƐ` 1T:]CFO=C&+Qjm" x@][Fgu].;e9Cv1YtW͜v Ꮫ @W$ <^,aT,B]i.L3UDoԫaeld~ȿa\Sc^Ľ1εkMop\7%#`fhAn-,tLm-yi9 k. 1;{s|meFK%8SHS84kB bwfE ΂y4}:h/)}!On_hAj|3)X 6sұ7=BiXjuQrgaՊKh z*HdxɚZG2S ytx%;]h 1jYJYҩ,KeS-B&q9t'pŸJvq²:ǥSϛ]3&bonP,<= y%?Qm6D(1.KI[ \H!8<D~WEA0iFgЄQkMLiI֨`,(%L qmZ".ywGu/iHZ&?}d{y+S_":dϫ܉Wݙtψv˰Lg+?SV{i:h@-Q«HzUdGgG(3 Zh$1MSwh%tNhr)Bw= V,lʑ29PpϙDC}بbMMn,6gEUњA8llKh.pOPIWfo$t2]\5bۤ |1r:?7S I)B{ xfxviӤ@[!|ò sM$%m=哭$+XCl?f@})OpYDHԒo;P`Fmur߅v~u5\85PDt3K7ǽԷHyK(zB*'ɢz^ZՆ'<.ђ>{ȈrvTRؘ9#3:OJ(e>:Ϻ ,j۱ip}4l/DsS ״g9R۪kS{|fGRW'N<>sT+TW{bU+ ~oXF t{mja/u&ʷsQLr.r{AO!. i^DK%?rj\ҜDmNss޴'pH93_VK7u~V҉SF|{>}ϟ L׾( UkUS3ȁ-ʌwE7G6$|Q V#P ܭPk#4>꛻p[I0ۿZx BVA'Wv~<%lg~Γ-YB*KCG̋%oI!uY8Y#1&CS1i"bwҳ,p+ ?MK%G?\oFr\kzϐnׂND\ v)P-lumX*|n^~ZJ/|l#ո6yݢjh`W A›;EKSު,n?cltq:9%ʎV(Iܪ.`>PE|f. jAHK <šPŠ jv[2>}p(&9yXSSr) Mݝ~1i}<2q| My*Ӝ ;stVIԘ%KoL;)>h~(P+U2WoE &9V\˅͝? Jco-6E -e!ċB)[nTn *F rƺ-nzw 9iK|]'o/FVܥ$KtKMIEy`Q`΄nפpX }h'svPokonPU]xM:<}KHM bv|'<;5VG@SF ymz;KЫ3[k:;'n85~}MX OHc j;vVԢ{>Qei\v.v6C*Fa?S f6\ڙJu{ŦX[q!wwxE+:8o92v}H)rvl<&Z@+PzaHLQY^B 6lJ Y_,!%2dbPHe>ptV)P3Re󮛊ȌޙUL% y-!m蠣:My` ŵ/loݎonL Mِn$'y7G22s&D]KuR-'}݃qZX"<+>0/4yV:&igIe]coOk[gv(sƌ~|9N_/TVE9ǤRD6:1vl['MU\@iw>9@G sG٨ r]$=VZǑR|X..ob5wU )!͖ܺ?1 `d:^h⑗.z!LҜqŝ~) Z=>tK^&ec]{P1+3hb~($=rx ͱ :r&kfeSN F_GxZ$Q "I_JrVO.jQ|Cݢ&`7.(xb,z;(Of.vJ;yT("xjh8V I|:ah?*T;9'ۨN?Nň tq풹¯(}eÆ!:s(;K ht${iz%wD(~ڷJiUywGNjc ,LVFƨ.AL"&;%]Dž#މ7K?s :U!i#q^\y xK/RP6" %e(ɻt0$e|%eįQ7_+\dv[fzdI&{7Tr:iT+jf%}g~{"LZCiQ]qiMMr˵b8*݅QԜ$@rj9T2*j_أr_Bt>4n3_T 3`ǝ/nhR(6 x̀}ʩZӆWE>ӷVwfzb5<@.vwg2iϖKf;iAy#Oxi9=mͪ Z ̹@1&ϔĎb'Z-Lʢ^o\*` p( hhy4B(G_Pd?s>띢tqX^? Z+iw.(ǺsZ QYy\9K({d4Un$Y OMnW+o+͍2Z$^=B$IGYɍLB)O\mRI-~o Z?QcNNn&SKSc4|KkA╏ҲDˑR+M%va57sCM@Kis6KΓ`vDNo UAv%xV77wǑT˩ͱlAR$f%@,SnLvUh*wnD}%"QժdgAo|ӖS:*0 Ee$aC2+/Z&e,)lhD~<K\^"@ȓЂ-kĭ%K<񣫆iJ뢔ʡ Ѡl.v% ٳ/mE MM.w"'eg;AR2GJsoxS+1p-g57%yܘx`s ۤ7Pti[ i@{ 3 I(_Y&b$"`4ā=N8W0s6Mi~KiZ˅Xoa$nW~.Otx(ÆKA IΚ_nʷz,'6H!,%^u;u I|WGk<̝ͣ3΄[0&l Yǻ,u֛XlS|RkTMǚ#d&y u^x&yrǭF@pbӇkƛ_yeM|6ĉS twUӐnGłOF*!FpEUޝ\62oN[(CsжC`.mã\rU:mT-5%pA#3\{d=?[M|uTroAOS y*XL6 .R`iAy18$NL>v/k #8H6ah{r>YF' @.w}E qba;|<.:ɔZ>xe rg_ <0. KJ.Z̝z(O'ZZW ^Ռg!,\ QuWĎ Vl?ZEjoyˍޱxH&ޒ,> { } ][|xʊ|\d2]p 6 a@FYYxZ^͔Šmx3]nqo7O Z7}.N{](CDbfxs> u$n@k_4T&zY7%#VͰϝ*[ҝF94t72_ C8ס;M4$R}fK>q$>!;\;d rl gi5aa*"ǹK%A&V!@S WD;"PM=ڊ2m%: ÝۋVс|O?ς>4(@ndI |i: \'I0({T_O8{lM CwR{C KRV D68B|nߟ҅+zI;9ox3Dq3ˠ AXڛ_Jx 2)Nۡߣp:r3&~{JAjZ Gh/o4m L<_I c^d Y+X.7EZ ^{soTꞿ(_䪱%ٯ.5$)emdNk:Ľ< ZZj^THZs)bF|TXz n5lqx@Ӻ;YX!az'*Sg;iV8 c,|5A{C19iI#h0T^y2::<5("r n(WN 1&oe** ̉7'~  iQI27C*@y[*1Lg^q5j ?ϛf˶ޔmy1M7%,i'kxR2wD-ku2 D= /S > ˤ2ͳ{gFoKcAm_̷ q3Iv" 9:o{1? ;Su[}z͙PW?CՁpU=ԅϵia>x1ꖷPlQ 3&KT*\&VJ?ﳺM[q('36H-oЪ \ߤd?.|>gTSߺIks$T1;##'`lI" |dU|XT|j)L=ОBR%ku3]A<`8,Cr ]7ܴ'QSf;R)ZExdJW>X)~ :5]^qT%5Po So23#`ۏ\;&?NȒbi|Cl>8l*PD'-\V̾܍qt۷kՃ=0ÒlLת*%Tf)КS JiVJ^{|U^ 5JPlxF_[XEUoapz"|*ڍoYcns\ `!zw#H&ȸ6o^{"_20Z߂sAʎ3LWf *򵋊t*a | ːrݡ54&-)ۢ..=Z/o)t>kwi 3}:ڂЦKDMa%WSF}[mt2;\ņ^_E" Лy'1) `ԨsY#-a~n %M3GCRۡ t'[GvPZ:L\O:>ՕُjFURF`>$N@%*u 6_D7آ~pu {09Uh+/Ϸ;[,!sD50 ʵCRo'1BVh’+ O}3I=sV I- n%=DػgpsZ؝PP=% l8*;MүI f~k:h3G>|Ey@{Q${.?7}8?گ{i.x eá)p=rLgS"{xλXBUf/ebST>@J!n@jpֲ?ԃ~o_j >a +(}{74 K#ቕ9i"1Ĕ9/jmFlԲ P-f -KA&1]MAU":jEr'|2_ΐ6}qcr;VvPXǗ7 r.ϑȆfo`>[E%$RYVo(Gs1_PƆ^\(>MO^BvWgH9s&TJ+,8϶7Rc O& Hc2m'-/cOr[a[s JIy T8. s|@79'o!RlK[qΞf-ly̸`m|=\ތmҔ<5+ys;$|Bdwu0<MjcrIc=hKt!SN1xe(^ k!`dB)*%L UD>翪t'Bd}WDm}(ip ~qSж6Sؠ͉͚BgwXvW wM'97߲U'ޤ񐪑G2*Eبdma`" +e\v˶\$K,׋ogW1K Yd?U]n QΆkl= `!Awh khg]a}c@SJoZ̊R>S\+Jd[5bZHxw~|>r-pJISHxݺ?e{-^ؘ' vr-:+.T6tӀw87&Y)Թ; H!{Qmϳk@*@]dLC$i H>%iG8=v_uy U$ֈ<;E.?r:OXԤIW͂706NRqel'Nڷ'"jxI;ģt=9A| TWjz;Y=/+#w-TQgg}V Zq=0sNKKfL._:nĶ!-V(QB'SޙV&S&)oե]fж F*Fc wdsyzrB(h!kf{r\Qpr:uJO|pDw,+[hpRjO K;¾$K8 ӹ)ۀLTuJ9#0X{Iub`sgvZ Oݜw5dCMҐmB3l1ɜ2pS#9o8`NnVIV;si2fx/t}>om:Y#% nNoFE{k TV LK=I3lnOAy5 cOn!Ti{%)RuʗzkJ)M]P֛ʮWG)XNn`-!i- GzS7y_LjCwEI'˯OXG[C[62Bhz?/ȑ$g-zdҵMȅt6S%2V"(@5-=yS^$-ц{帐sr4akSfFx%:7a|!ի 0~c_r\HysTOd{sկE0%c&yz_ٰ{hVl:ٱu/mљ쵬|NyQDt{r|m=ʹ8GVml`&_9=oG{Փ*%\y" KO(kV{ .-< N_UNJ^[%LGsxmޭI``Gt|K e 'CZ u}AOU^ڥ4J;(RH,/2X4]7 gkRh=KxDdB]#75P`jA3/|w$! ˵߳|cӉqޫ/?fLt!M$ޣިJh +y"~K.gږ?,bMq2:/ϔ5ہX,X νm\ʸ~,JTICPCxtaQDsTv(GFf,+3QE%{PS`"Q 3e @w a_XkŽ+,ncRЍ^\Oqjxw<˪io<[F:QDák/t oL =R~[QH³Hu vX0S)h;Cnj,g`0^ WtO1DkCZfv un6G M/I ^rlH)0ɷ`ae~Hi6Y7o<~ܻ_L<Ȣԏ%$f:0F Chd RGXJK/3WBƋD|Ty,!z'_Y}C՝* {% ׌2H/YTWI?Ctif.pBڸ<<:ADT_#Opj'^)_?)N3 w_.on`}ľt/W0~ΌE(o ס޸1nO!N+*#L'ruwf(?$DZ߭Ζ;|\/wTd!u ;)Kt um vyTG84L67wzA]fд_C ޱO$no0@]%T)|2Ѷ?qҽ. KD&m@B};2[ !d?_ $~'X@LTN=Z/G},I.ɇmi;D7)KagO(&+!gpĢxL^>2Du#4~_CCkv ߎă4ǰr 8+Lh),[wx裘hu*hARU:_G~y^So=A9'^?EC1^4Kf_:O 1WQ}tt{+!$⫝̸VN} Le[X{5eњ45#EQ`yƚHCT#R5T $jf&S$fW׶uq-2Fqcn믯); m2z+p8?ƤVg'ϠXW"g1אOhay87NN_3H0D8VyC%XcJGG,ͮޣd`t F&#L}j')qoSr-A] qkh;' UVɿ? #g9L3 69KcoߥOڣAJ ѭ !ecI8Z'U]w vjA*4z=Q#tI94g~OXid[ R|#+Z쁄]!mmLO}Z?1\|_= bD΁Y_I/&6úT4^Ano#=zbЎ1/۫FK`Q -_:w5/nj//J:AX * l| 2f 0(3BTcS,`t4}ɳ c+Pw,J|@!D1i?Td6Ɯ5~gϊWF/]ELxIwIȐ&}baoqʸZ %FyWc)kJ}J+uS#5QL'*(i^W]DtCľG_ԏZD඾o俑Tw+0N{Z.]O>y{UTճnFm9Lic #"`(YW Ю<Dtu91 #Q hį@JXm T(F]zSz_{*op}5b9@B;y.i/qU0aL3/"'TC._2tPظ`7\e|L+E[WqDZpg[a\ sIvq_\WcǠݺA- DE_HgAْ@fK4\6/%hN/I{[\ĵA-wvp☿.Kkx;L12敾nޑX=~_2|Y@&>hӎZ'mEn*.TAKJG*~V7uŠgl/S[&f8䳳S!Q&KtU,s$:,=uxS%[M)6n t ,^Мק\Zz,w-'I]Zm}]+5rC *Ba&ok]RĞq| q%!B(:wkXQfx3ìG~ ѦKoKI]7K?V^u$z5I=NW~rTLZW=G|ބ ;R1]7vIEx;;u zYM;DTGF\sx'6){.)F^Fg NBztL`3I|{_""AWh=+1A3tn8}2/JVy2o@e9K?ї l֍f9 uPkc dsvMSGNȥ?T'4c $ƨR+;N%C֤'ݬߠϿ#qXE'!\'63DnE ?^ґlϛp%{H/N>¨T,w2{Vg "۸_pPI8~Rτ80;hLq8y G3X{f  ثcߘ/SWTmd05}eŎ8#G4[/=] U} Zp`_Ŕ|5}ஏf={J!n//Y'c털`nZ.X~^B>hf9 ^/9kLK+t/ZmR:'AdR|Z{s漛7$E _]c}vzcCZP&3Oꑋ b0YGߖְ4|j6$^I⮭,Yd]IyKam+~GtpR**e v4a#L&Ǡ*mxD*$6't?<*W,t+&ҼGZ~G6a[@mH)yg+ζ&i@M8bt}*l^ş꺅 rN - H, ЭDӿ6opg43|jׂ!̝ʛo);-EKrM67%@^~iaS8"1.΍՚%EX Zr?܆hv>h&نljd0v=e:3]W5hs)ލg>&Z[q̠Q[s`6s~heu׋}N4nvͷ;gu,h:96mT'kxSגItߏ5k؏aE!_9`Kk֗=jH0K$93/Q8̲[S\l.2hah!*_N3ҫ*"O»d ],׉aJ\ VUzIkg>3+.'5Ľ_ ɦ+$ 1эD3{uEH?|_ͬ-? HL{JZS²]){Iо9PBcԞM*0O¢[+7N]4w*ſ|Y)!R:a t{1܇$dK[H^MȜ}BdvA0h[VoAvzAO2ı][וklND I4|C,ƓZg/䗝0爜MT4ªQ,\V"%5BtI;ΰYȣeZ|P&־H-ѮD*)" z: *RLA5%9(sp__#3$ ,B E2~*bd iۡͮ+sRoM@𑒐VƥSʼn"cDM/4HQơW uH?G7_0􉣷zK *>S +Y6 DT 6Ʒ!11چ@@;c[w!4T  Dhy X|l b2Y/VL VxX!C0Wb#I3`FLbaCۂC2-G 3_8m{8"IQٻ$Y96 3Te)\*2oxPT/?YT IrN9ĉV%S(M ]/CQI׹]{~Z|7zz1?8Լ5\oė/ly9mߛO|uϫ^4K5!ؙI7YA\,̓w$}( Z2lHotJLI}RƟ(Cp/\]mTOʺ(کNlI + %V򓙻!B:BpDOnKTH0CT#yynj0}uq\^r=9vtg>7hDK iӻ%gws=԰C语1PHZh6sV=yRBG/6\Ђ3~^d@s)FpotnouTi+ A@ 062\|R@ (}$zy!d 4۸+ܹXB>r;Kׁ"Q3)ߑڣ7CtYNDcfU ?n1c6A*jv|w]5# b̾0]>H=DW )hHz w3FgF\Mб!s%"2' g=zJ Z'V0j"@I\x#i):a9 g@WhhRnS+!U]b[h^߭:O$8*eg m_{J!CZJ3w'ϒ2'.{5$$% cF>Ku]ocH F7Vne95BP~MctJ"|K.א]6ڇ8q}sjdz={8c`yȼG2NhM2`ɾFi9}4s;`D;m_q1U[ڠk]6CGgp-*k ,sd瀇kn8w r87x\Gfuo4'CK@ B{U^W--gs)y_Y" itjz`X4񞘩U،a3ui'['霓{,[vcӟ|lflx;_N'qN:zIL#`d_H}V8B4_rq[>+ im. )0CZ^?o*Ekokb-#,) 3.xaod%*}o{mleM@E"oZN1 bȒIiIfx8x__l98 ƥ?/sz߾σ?_WNQPqtdC^?6h؊ؤvYS/v6?\JX MrCblN$?H!Av]KNƮHX\ݫV,SL̴{d .>edX3)im!qIU\pO./,$[rm0ct_rRcw_P$RmSǷ-9WUWuĹMYG2EXG!BI,<=$ j%ȇ,_ x ﵻ7o}N-Aܲf}Ƙκl2ӲiI7F3 -JN$c;9t2DomJ貊&u=3.= kx|e!_ _L LSxrǣ>!;=o#vupa }<0ZrjƱe{Ó}J.&Ixy~COv.rT_Jzu=oϞɴUC[44阨ؕ3_ pczmmPÜc1G#']rFͰ%\hq]DDOJz~ͻAx-uο|}'E~uauqDTAi^˽-ümr&Ik )q{^dPt$92[3P=\L6lԷ"i 0ygTXV[XaF@ܫqϼس ]Tnׂ ԝ"Vޘ` ogRi]+N&YbjXDXg%Z\tGm]\Dh![Sfel`E8.jVI>{kS T?U@jmY!(֎r,%i_!kSܕşMh|oo!0 v ZJ03IxK*װf)푪Ų6ڿNZKzj s[ Ag qIUM{.a~+:Ꙧ;#;:4Ế.! o4 )>⵸Moʊ)/߲~nޓJS Aywzb+6!~%Y8&M.#OB,' 3ܪJTO1X 7?#@bgBԐ#dw6! K)%@MVWi#ea{ކ!(Y}لHcv+xE|_>ݾG@Dd>G?;Ʀ Օ)<F=HsH+K?2çK;=zCOFkp֐\/7?t! tq<,,: cIHyrt G)Lß}"Wz`iflOS9ueʉ?,*MHm?)[~x?YK!|)%2MZ;iBWokWcǍnNNA(hz܈\G4-x}S]&Jy.jNK2R+}mJ5OniW#>%Km9Q1ef`'.COCyԲF iニ 8~ߡF.DCz K1Z{Zjm{ӰzDYz@[;79I( .ސvfTE!^/d@[-u.4$"5g`1}-kqT JaK$-ͳ ݣl*;"@*k#`?~N=p%M#Yoz 8huG]]'QWaUEEYym9LKU\=;^bIg`*կ[c[:z.W^dSXpz]/eŬ~ix=BيwmG8cnU]`ݽ B=N\l_K2dG8 _]ݳ @._Uty&!\ $4E ۀSY7qN &ԋeB[>" إ\E̫ @??|2Ru6^>qItԈe3Fϭ=?q bo#pF:z=hIPɹzxT!+H*GܸGZ& {p'|c/fKFpNJxu)G2vЩB܂\mnPEs[k ?oh)` WJDT28F{dB&eNY7ݏɘ?c;ci I 1ܪ L}D%wk܀B9Ŀۿs81dֿ.Ol|\Z4Օ}U')H֦ <7~uWE }MIyzB?#&6RjČ)#3/2}Z7NTT(h)66 g:}dlo{zxot_B;Тߍ؍~4$CrCԩT a /oXt|Vvن`G]ĸT~lI44A`;vRRSwC)NUI>@2M3&sO4vTj0m%P`m./SPjbYSG--g'dk&ꑵ;(!c8SR^b2e#CtW28&= ]tD{crbU}0OAL/u"G!E! hS9[n8hE)?g]w,MDtXN38~[9AFPR(bYԜsß;Iѫyisʬ.8q/-똂g@x>~^D'mkg`C,,115GGIF'}b6v'i>ͯkky"),h{|.]pވh^Z}Ӊޮ]2A~&bE1B9#wQ',W8̝)"E 2ZᐬfR0ژ8mBliÿO5{SIL=/r~UIp4 1xE+ qRy_!11ȱWf/#[Bq1nl:3$~!Meg-+d\$1 }E3U\15n=8SbuaN>'޻yA!<ӥ:Ox,rg3mC>-oƜ)Tӵeqsp511,D4hO|`BV?R,J< _f}QOB,Ak2Q:a 2k!U>" odhN2Dt .mIoc1w^8[ҙJۥkЍSVGA":bHß BwqwRJk-/_g d?L\}h L~7W]qLkc&9uzW1ה#M6`WJ4iS_9A׆Ԕ&OA3& ;"1U/S+t=\a{⤧&88ժae`%0VmU1Լnʍ@&8+sju؎'ncS!Kc. 9'zռl9-ɴ?/X=EQ.ʕOSXCV&F,1Y]/Yʸx7% s}@۰MnEx<~/јއWoWL_mqB_ԵwXhC rZ.~JϦjч~X?65yzV_ڋlp~ Dtneҙn5G:ɾb#ą^.#(A8}[|v!zNw+"D{g 3 Tґ<ُ=R T6됻*ʊ1\əu^7S>VE!sAyefD `M΄L Fw1p鿯t-䃠"N2c)9+aDsּ ?  !_@ZE DƘ! Y˘\1iEOyTU z[o ZG=NJwbs]57>POJY}F54 \T2DOɷ1pc&hKjqo:Nw[{,=de)Ex<= 1+i;}CZyh %PEX EǠsDswC%^sCs_e\tzf@LE| qRD=l'‘/"% mbl0J.!s򼽿}N=ҷ6Xθr_qH㼑VXwa;E_SۼQ/49 s4) \䪐pSnVAm޺biQ=u|_`n-i @ic*~XqH=߅ MElD\ѼPTԽ8](B_Vn')]|w3%h#09k}xga;#ME~A\Wu#]ax$emo m.H VC]Q$ VM%[=H~B?]%.ِvxW⸛>~A6,(dA_^c(kI `1k'7o8e릑~v J%jr,5y5dp?F+YNѯHj#񳀐BuOd6{y2vXLq05iX7&jab)\%ƷnGo?OSse>!ggśrAy0W\ ZVZz^ IDBlW cJLu:DX%$;\K9qػ|QOp"c$dM"_o@2!7΋o[d7ov"Kxf=J5,+ \nZs.u}BhûwM(:԰R-W,G#q( I2gm1}Mr̿ej)nP#x2m违Z 'lu@b@Q^jn5-p"[Dq 6r&u~cIb b5=@oB=jq\"ߗtIՏTDJqc+i knSP j$-w|`Rln߂D@q?` /h{՟D)h1$sR̹H#q/ xrE.h:"?C|b';Yd@E0_0%eE R"}QExJSiU*XO Gd2 ZWzȖXY},(MNkÜAD}c? 26A46w3ՙH3R\lMX,ДF|c>Q$ҰRRJOŽsw2WɴwRs 3,QmoTST_.7Pny ^ucUS{>Ll@>.} E,.P*wfa=DxXfX۾><~1v^7G+۟0`]2D\<mlf`OW7>TH!FLDJ^:JS\gsƿVʄVLǂƎ#xG}07zߧInc;>Sr4*b鹨 ۿ)0n\a88˼FZ7NR 7HhU~kjR˻F*u/}ϲ=^K@(H,FbL7a~Y2Ne#ET-EwuPA)tjzlz=d 7+6!Zx׈¾C*`ݩa=G\ޟx,ܟ'%hEg]4Yq?\+{&mΌޏ⦰&mLڀi dl^y}I8C|4 \E5OqzB3=X8^E 탴_n8i4B>i{L{șGbyo৴ԩl2i sL߮{<7r.T^x:O]{[ lJ'MWC/(w.d tLa,SBCWR9y*2ܭZ_ J9++{9)8$m?].ն2g-4'B3 ӿzueqϏ"M׼ݠ|N|;beY~cʗ_IAnx'`NB»ME&\CaCa1߄ a.oc}8f[Wu 󬗚hcWGzg;L d.U0~ݝ.hUJ,rQkuZr41G0ehĨ<$d>T:xYIWӭ)\5  cOLOAUt}mDdb10|.i'x1& *IuAlSjzO$9s~Uڰ%^\JG\W䧾N[㾰G꺣S6(r\7us/r91腧0vӔap Fz0>)'9B 5иc('N*> 8۶iG`}o |Vh42/Rĥ"4K>kRۍN>TX.z wR21Lm!9FĄN#er!g!QigaXbuЗR昃eTC7`>ެ-ץA7q>+I +N yF{S,PK|Zu ߯c)fkYѫv+0KmҬG++wQIo@r_Yj<ڒ~25=:BEb=TJ',ΠRؼX:-dH6/ uklr%g~W wwX;>8'Ԑ7W8Ƀ踬]U)K+Rߔ`y̿y!sHong)@;s!gCs2o=b LtȰE ?pGsqfL$|.8VALPxTW()>  h+bR,mf>쯡`)N9)3TkԙNfǕX lC)O]t+tUmKu(GFn vM $b(QV4lBYyrp6a?]2RѳrqLwkÈ2CvNl$o͂1,EQD/ݾA@;5 gs0ÄkԔGV1LmxAU(rmM@Rϊ"p%y+y-&` h7/"(8%% {@~bT?܁;BW*!E4KVC.1Ri7_Y#-Yp2H{PY 8 ! ta,쐕7e)6jMt}yQ_,I$O6kB8ŴFB(BAߣ9}%m],ŚBB+^'W Pj 1m6YvaΉvtIp( ;ǒKgzHp%R Bv̻d/*,d *B+7"23_U/3P-o7ovɼS~m*YD.V+>>x;MEj7h`vl,cFY9$]-730y6zs;ָlPoG!p@ԁbO2/;D ҆/hI =y97T sI%'Sl ߩ)>RNK|ѧ XЛahR#7$d|5;^bw)-x?I5:XqoC.ƀ4A^ü~"F1PP|<{*s{*Zܚo,V,< _$62Of>ખtV;)md.ݞE?⢿{8PzIiA.0 4$ʐJxl]Ln>ĵuR4)̌;ZYW{-6^y;n[ nI癅2T:LlLu.c"vq`V.Х\KgV $Ƥ_;''QPT\uIL4E8*&O]XIR[{Qܭtk-O1_"|yf"pL^u65B*`#2 <8ggAE}bUAi[燘T̡KN,m'tdiw b= XB(w\YԍX)Iѯǜk^%\w?? 5|^qA@;Uݠ4PXPX=$ wB6yGv 췮iH7, SOpо7]eR*V.)黎|/!/ m o ܌k2g,$5k۸0IsN}!A}eD:w|K$ z_-8M? 纎0^U_fr%]ImdFRMBy[$ 0=wA/ Fl%=T\ߪ +N[ /} oRR[OfjMw' 9ܠH̓0+Is9<[a&G%Q0:㙎/Z<6X=uXG}x:$|f ΔE"a?s^΁&vֱtLɎںEsf RUL=""]#*fM:M:/* $-wlk2K5:R%^*3σ#}Gd1# ^?#A߂G^ɛ Nhv=!0Y^փqˬns7"}?hXXzIyϓH{^uP~.`M/(gqD m(4Ydޱc)Oq!K\\6aZ5Ԣ&R&m`-&ȃ~ %jғyKKFڭquW(;!DS2FW)5;XPe?HgY mty@xTkR-qr5"MRmYm{끟#wdi G޴9GJH"{7}ɕ<::&_WlPh{/Lb*'T-D5X 'W֩A A3-)6OI BϬ i׸NUF-Nhx<Gq$\=/zJZ\O!YĘS@L1LvaA٦H{M\??ȭөc>D}>r .A+mj*Nsم*=n{V^}|N"`+L -M,HuLyWƴqB CYg#_8?w;N9YE|(.͵zz"2 :F!PV1lL9WU?u¹W~jI3P[V'LCB^pHT΄^{p)pvz=bFg#+%^ g9TR:zsaDJ_ow.q ?TG2d7NM ?F]מ|$&և3ۈZ<xČ$fNmbuz:ϴ"Y]5@E}I!)N(bz`WTuQ5Gi#٘2?I`wQwo8 V&G\:q 2eKÍ ݾ\Ƨ+8?jp9J6 &㊎Rd%.Gn8q#k'rsH f#e1꒧ .L(EG"_uϭY l|;jrmAF7_7T!0! /n N7"U5j5˭〷jܒ6$.uߜ"ΫK#"ۨ&~R^&Μz8"ϼu-jd=u$p-h#}{}2[kƃ{Vz$Jv|\Ó .XLd 0|6 1bg'28GM kj0 8i+d9\_:iQ1LY@_S3 =t{W# O>?'(} WD*LoX;v~ry#bB}K`2])CL.zhGWpppW\F2CY䗞RqRiNuQdHDXXGIg?bI` ?qsAI7ڧJ{֭0(x;ѰG%~K,v0`+ }*V '"m> }R]ҹM n urrL~+q{\?o_mϫ괸KK֋*r|>^y2u,fagn*+ \ҫ˗1DkԷ,Woi)E"YK Z4sxn d'oYW#L}EWi %@E΂nPTfs%ó\st0)7(p65Qԧ0ю9؇\@2RjW:|Rz$d Lr|U(cGBsŞtN}55PVDi&-(յ۟g]Ȟ?i`t,VW - S0Bi@A;@m̐ƉXFڿ:3}BDwDI>z勨i^ &-4~r\2!hJw* qL?;=hN]-zkB&QOp;<3_ R"Cep [ԻkXBCn{QPfȎ+P [Z8 LkU7/󳥧nsX3 8B?7ի$+)qT [Gמcˍ ]zU]:2L;DV1 'L%NU3 (/Ϋ6@FJn/M†(rVdмxnG8& 08թeGK㛿V{~]u$Ow):a[kT9%鑢՗Eڧ&J nI ~GIl~@Xm9gPY}. Lq=*;jQH,}S.hEo8DtD-ŏ1$^U% RγI gm%һ w+ ;]ֲueUBnno_M,p3,(NRWQ O[;v=߽^[.܁?kd}: 8K~()m &K8zx< <קmETPmnX- s2|E,_2PSzrQo'4IIT(?K?( ^AYnšo"7.m!(履$KĘa^ mvU[ix5ӒL"/ANXi~r^×H2|>_7pi tZ~&\&oN;㖭 ysսRi>"kG63'Gz i r7Eu =$b9G*\#Y8ᮛ[vMl:]SHkOwUH(-Bᠴ6VVѣ0jZ97f/ qhU ;UgE>h T>w" e&Gn8u/9?{Dͪe nS0Pq5ӐL@vؕ>imüz+҅yi1 S]{'RKkӿ,Y{tʅuv۫fRH-#FkA.&Π.ZL-7C$"|E=pj8 jߘ 2~C&9"jmz/2/Dץ?P7x+ĦIC""wMū }UeN"`:vR*g"@RLw廀lǔGe[u[Pގm3DO kΘ ;Q!Kx _u'0Ʈ:qlL<PV3_g׫)z5qepΫ/(ybi%?a^h&hC-1 S?cYcO+`fۅkk('X)F{T8*0JZ6f}qyfJSW2V(}_Gi @}Hvש'M^U԰Gr0߿=xr"J~(.G8՟X׍X}k߽ D܇ @w s.i 2bжo:+AσJaEń;FZi+cBY\P|,`_1pT$u2-f'ZJ'H]vc!L> . 璽a+mݯY 6$Y.kGI2,)m(isy*U؛4FwX5&m7,䀣_iX_Q d W9 ><-OIRAs3)Mlio'w$TSa|&s/}hGԤ86xNhH'hd$c6,o S,mWIw.׎IF5C#c!bjdwk 6|nw;43{8,3AikU~8(Cnl t=7S!̪x7 ԍYZ?~]$++AB.]jmT6C:Fq@_E9,>B)>XSr&񱟜 uPϘŎɚ6a]kU/?Շ(O8:/LZўYZDxv"o֌m;3lY%6Ծۅ@N Ha-CWOM-`3=?fcy,bBPi1~T.of1~?W,9X;חlše^z5Ő y7bp ^nYN?&un?曶x[%MsqNœF[LQ% nuNT~7_OX#ir0ͭ f:SaC ۼ扳 ߗբUs}u+d kF,Y Yѓu7#e)wo hJe=0JZU]LpzY3&sach4& 8V"$ՆGaϦZSKAƔn7z;RvVqiȍ;ND=wXL~J߃&II75'o}ϿYt4"֞/"6?h)UF/tٶdEq5;̲ u˿ayS"W g36N,⠰߿$S1mS}56#vu[WeQ$# ~v { 4}4 ] pc7$OPN*^ﰗO2h{d naȩ1)Ci?|))YySl0o]k4PDFDP)u̼[TrWzHSo-wӄ `nRmyL] avg(]񉦮DjSk9l_z'"R T2|*h?$`޷ɩf všoTn;Rx z(^E[|ߪ(6$x¨<YPf;m28Vl 8ǩؖg\^k2{!.1wYH⏝ m{ȦHg_Seqj#rI36~M{N_~)~.N'lY;} x`-i|>d2KFSE){O%e2\1|{n2妚@n9RhqT ]j*;8kTɎw{҈dGkr;8 ks=1aydK'yӉtq~\Ԏ#AEx$WM*)8(%BbuuzhGA:j֜oSV7jT;1e(:]`w)7Jjj.Rb͹yx0'~|4Й6 (—Gg:Q-tLY%8M~Q^yp p?cHܷl$n[0isCya#^a<[>V|OueU~u aތeP#Ase!ԮO'0xWI[LL-UvRHW&K{z.=g o N .$' !z?뗗IR füMxƕaX flHQ KH^/Q:a>GE `]Le#B]{].e:(%ݓ߃ſ !ͼeuC֡khbTRn !8NuՐz}dBYo-"a&ff/8Cjt{xeS`-iv$ҩFaʎN.28T_= 7:qY r\ ᬐ뗢PΞJw[giPUeeY~Ӄ*,5p&L ms )v'*#=mJ#Yoq%v;V]%Ԓc?N[;~&#ezL F wyKi2C`jk %6OP{ r\oZN3B/DrbVB}%ts}/> PJ|kY@V~?HTL==#YAɈń՝S,acùaB =!)}T dN잴g˘/H00m-A?}Ipm0beAFD[2LcV&B+2%!F@9 Y6w #bzOmՀ3AmW!vXiFZ߬ ?oDۻY9QZ6:FTmaqj,N*o-+ĵfC=1)8cRf{ ˕VGG\bVJn6p}.&``4^V.pǹX$<  1-[=s.O' Q3`l8qL>~9X{sx)c)!$χA+S+OwTw":>W[@ۆC3 Ig̃,#7A?߅!%k:;W*g f_nf~}CԦdi(jc7EYN7( }]߯띄q|1>X{s(̒ ܧ$[k8Hlm،mS){] TE'ٌ[cRԑ; Ɵ;w`ah mU+qo-6aEk/ik 2 uE1 Ðsl~W xXJ P\+H}A&q1fCiyQ igPI~Bh|?]-gEb~-tK`A.úU'~&jYOQ̐r "r(q uشt9Q³7A Nf>)#B\:{XbftAVf9FTPv4n榲z|S׷㓏c-BIqa v9ehfV[J zcGm9VTܟzkt$ҜS$b>S1)[z)ll_krM8^TTI-ԾȌ[Zv2څ EX2dWZTb(u*Ck3=n8/UR.3*)!BDq}Fi|Hqi/D#Dto}"% &(rqqަCIdOxEڅFqcSt=ͫ1XTX)ov{1e8 3{Xsqij{SiVKBsSU $,wHE5 - k#‘S =H!jz(_2+c9q@RA W<[/L[’kMj'R1jMm*|N=Z3knj9&O>&!ҹktyw0^p?ZRT8;ҽT x6Q?huX;4liJ {I g_Xp`PQ<]DƥMww[OT՟0ɫ ESNb%|&.B^lu$kH`[mKFf4Ec#Ҷu5p^K#<@2Ēph3Xuy* s߯lJKrum ~v毁Q3]L A/ePcwhz_3"8g.JY#} ȹ೷)y /ii8~uf=hz0Z3?;QGeMh}Ղ@ôE`߅SeA՛:@)_1N!J=&/g:$-Yʖ'I;c=8Ah%?)sȋEW/$ks5Chl ,Һ`lioVbl}F%{V7|3t@ţgrXxB 3)xxUv2,@6لgXHʝ|ĝ15#ڧA绿($.W;Kt,Hg4Zw$ NҤ{3P=LU5Vܪ-K?剦TbY Z+0kO4p|q*|QU^"BU]/O UIBD>ޥ7M .|`m.{zH!Øw $@AN\G[D/f#"}I,Wr~"فazKzƚM~Pԁ *P0WV#~Hh$9  kAɼj{P*PHtv(af{_Q++%VrYV 0Y(K}[Aqd.p-빿h~ϩtBnwuNhL'h6c ׭:a84rEc#~1߿@'u:="[B2EF|4wF<0# 0-)֧nNjһfЙC~K7Mٓ\amUKjͥ&Wu*m|^|CSR&M&rMl*ߕΣxSF ^,YomS#Z܈<( iwG8a9[ɀQ2Mw*]A4*tʼn=Q`f`$QEpǪ=ߠ-sXHՠN6 17e98 {9<TE@3Ye7X7;/9Ez]K5;cR='=:dG<00G"Q@3 @;۸P 헦*q݅+<˖3:DhqMDH"~LoyqԈ- ifS_o7DPm0^b /{6:м(ˉG8Ȫ弄!PW5wZ!/),ֳ;wTVrv(RлptA(;TqTCCxd;)x@tQH0زJLA_E|eÇCJ߂ŪlmVm[>bώAj.JUܯLS`(牄Jp+kʳIÙR77{ɄTx0=8ZdO1#/?4* m ܻeC%u-@NޙbkO8r^S>V|XyFmg*y!Q}=أLlj16E}UdgQј ^d:-y+5?! Ak{L v|9{^oύLmsWo|Xrf=x)t1ep3|UwR`#t,cްE)@gؠJZAD>;>2+TQ Jb&r$nGDKc v4"6\ж}12=VmT?' cW͋d.z_r_ʲ} DF e⏓y.CD+7= 7BHF=_21xN/#؉p]#Su[dŌ#R}\8W3X4$kKQfxJ?Lή ^>RFV9䆸G?.zl:ΓԗnI?Z4H[K)ӡ2 cȘі.>.|Ob̧X8UIy{~РxWFJL1bi,u?$u i;~C^'[&~(\0,-f"+ӧSG#ut+ܳ䧫5,7=PrkA)4B2Oo4pZ}Z=.=r&YFťi௱zxGe|;bؔc$X?6;en~~!(739c%l'5nٱ CExp^ZM}df &T+E;X08cB3(g|F 3zP&u!y a׏,FJ^BI(qԡ_z =Dh[+UP?e2=1??XFg 9~sG] )|eR7wB { ,H1+@a3ԇ {#[$1{K8~ )׃m]ADj_W~T?A`GT Zo4X#Q `(}<C5$Qo/=Էa["«=RSi#!|L0(\=XZTy5n"p&55-=Z>™g RYNԹsWv{Oko,SR\dxO~:j}!dHrzۗgٯz!y{`Gn{1|6j]ڰ;1QdJBqb۱mf8#DzYRQQTAEpD(bS`amRQMW /]kMO'{Okc3-d'ݦC~=M1DI1!Zqo_̻7lbyXkШ a/4vT X?,ZwSF0D4kt ramAtG$MRƨ2D5[lYTCZ[u!_@+}4Un'5S ǭndk@t׷v2W4#dp MmF8HMI{.o3@4iX;J6jnpHQBk37qa1˛Γ K"m[~b]y D!Pl3DH&ȷad(RL8|j-G-ѣLq ZO* ΀YgM:`3د?S<>8٘no2Ew>$mNkyTj^Q5rmA߱ڏ;dLD+txZ q]1oEI s}}wNxϬ,uV-;cOn1g}KgsFwhpAްZoa?A|P;y 4b뇱ю#IIOD^>[xzZI{ U [LIL&y›$PcɽϦ/LmadU]= zKO$,Hi !Bu><-nYOSr .äHo;!OraB+"D)͛hé~@氵4}ݨe1`J ?tn%|ӏT9.䟸i1<Ƒ, ;xz1jl'm-;$ /~]k=iV^6#xh&I<KT}(,k7S_5bހP|Yv1df{䃒neI9\M3sy ^Vi :!uo\_d#׽!7AoMG_@}.>aV$>x~T?F.cg]J  HP-#$CrSڗSa)+c@?a^ wZe;Z:_FY0 m4`%Yo'fY8$绀 a0wM"Fm.!(̼ xz M8 lu'FI/%dэ;.9wIDku^mQ'^HL.}#-J+bO|禡+Cߞy~qu^RF0M8k0cgh80@l^eGc>r`0 x1*Y;ՃCbB.ƈ񪦎E p f`oK4RggљV2Krw}NNKԗϚk>$V)nx<خcq6ǒs^6%K$Gp(*c:|vGP"!4!&u_ J|l:0|Чxi DU}kE&p^x0`m,?ίy@ DX[^3[i_+MےzS\ɔv;\T! Anӑ'%"گ, 7[my\;*zw6!H5oXS8_ Ç>5y-tD|ql.p<QBIB4cuC~v־1?l~VTͰ6( `8c16 1]#4:/x뜈y0p;oLb)ޚi1k4oFJw9V[J)_5]/b*F9|Ko챔yĆb-0{0mv2DU4q2| g5ٕwXJ%s@|+sUM]L!|gN{ro:*υҷEmQ33i|X{=)[[x hq/a>8;Z:|ɓI/#y0_a[#Z8 ֨G5g=ߦƾO_ߐJԑ/ GΆJ‘!Vgk~,B掲P4n,+ $!"?G8C\rU-aQ.?*;g, iCy% &ZMV#GT2m0ELn7xk5 |0g!ߩ³7IZ&JyUq\J.CBԕtn4"bgcU=F,՞ Dᐦ{Ӯ[Bi?vQ1Fu#P^%E  |Ky}p8Z2L_& im~cZ5w`X־/,,KBn vf)xstۏi{©gGEyvԾ;I5nlGj-Xit] Yb:‚DB=Н36U,M.]B[~$ t>"58@b-7Gi,SiU@|kmq^Rz_5{3SI$(M&Zp?M =?~@%?8T|R[TǁU~.E!;ڱ1 @"U_}-䩿ih${X* d}G2~n׷z2ף.c*IҫΟ0* ŵJ4_3o;Zqg"&ye9cWKM Y4*J}y#).SklU^,J\U95i%)+75GFQ;nL\&aShz&SV?aGGg"|Lm3V{>c>~ >>_ڵ7'xԐZgQQ#!R])Ͱ:H!G" 82#6)rAl3oIJo 5ΰ~޼V>ES5hԳha/<%.5l`ߋ0{Iڿ ʒy պs&$㩱y(zF:#8גs8ZȜІ%0e1qo|:v̓/~ 1>Ĝ:-6@ >}>.)114=H/ *dX~dKP}{~vZ,Cu]!~K(L'St㛌2PG^DaŗKB JÏ0Q')î aC/^6+^36AaXι J]5Ϩ?&%,KcV۶C x7 {YҠqZ ߀n y!*$*qC1IAc/ 'olQϿ p/>81l4 t߮@%ך ^eKx:TEќY_"=#ԏb^qkQ2MeF/2N $|GZ.DaKJM! OO%7˻[{ T#(ힷ\2&S:adrO'k\kxl,Y I!b~‡@>(pJ6NX} \RMߣrw .n;e34_m弳S鐷5KLٿYaS]T a=~x(~i=Ǧ?ߣatp﹀%ncU OM V%a+Q[=a|%m.D=zEo9o8XbN}V/ K ~OE25hȹ o6g?mx{2Hou@cFNj?T'-V]g5A0Nզ@ Ҷo$N>TGj[9 NJ?0gN8^[l~BMF*ʵ9Zz~ub>;oC3$9a[nCg,` SPz!E|-;T1_]- wwB!m/S`)Fڟ K$qI;}#H O _~9z҅z?{07%";zg@ފӵlaw>pKZE`G[ꨒeE,XgMP<5psߒryo! BQS`2/*Iʎ̕ko=2G1+oq`!E+DO߿ppχoqϔgO+tQz)Pxag+_:t3wt,)WIl ʒN5bCǙltv2 c8z@~ V6j8wVC'#IV蕎ZH~j){HR[oBGGG^FLAϩb\ach2e-oB;sk3L>k>ic (鵽t?z_U:DEy_+M裁_GE"aGX6Ew} JS"K˭\ԇb?R[̯]t'"QebU1#z y^/1{9Ԁx.OZﻸ{qgFſ!m(AcNŲcz44_"Sҏ-Bۅ:dU9^Tk$}5{k0+z-: ΕZλ~5#:y61]掁[LupblXִR- 4fX_پVw6 ~7TxrrirnJŧw(ov.hfM_M7+X\z9\^ ƴcF07JzJ.?vkٚ >/CRHN" KfeX+0WHb%-< [m ?%Rm:L6KXUQsmWZfP; KM7w( B?lϿ㧴v~SpYC{){n5Hδ<6 3Ї)/c!C(^576LĞR-l i)}5wƎ*2A40 yΘIҶh,k*ݡUEPMk"[3-L`]/r=>/>2FLS4oM쓂fsԽ,@M>", ME쏬9.yҌ4a݆ڝ$i'&~2\e>#CI<ż_J~*He_<0N#o֣֌#) v0}+c ѱjUN]rD)nUw3t%:);$ 6`s.6t]ziPa$4r/i74~-n]XJ5yM}DoBq|a'4 % s~B;*V\[8^V V$ qEh‘0=:[ dzOZN GZiVps?I1P~Ѽ1li{VKo-h~?Hl>tlK+}4tX١ځy\~׶!/t]g?]οq^4o3%Um~m+'@MK5~fߟT[V[HuI+>7 )!jY!fWw`Ak!D@' Sb9?\;-R\f!Y̱fsØWkc1W;4> MM3m1{ Xu)NuM ͋fy "X;:2ZɪK'5~Sd fK - ~,xƽJ_ǀhm3Iа/Ajk^l쒦Rt+$ 'gaL5`HA䷿*!눘Qy;$lj&||߷W৐qw۸nF8r+}|!ڍ$E&WxJgkNw7I)|7@В4az#1޶[0di,3 dslez|78D|Q0Z/P0{eRUF*zt f0JH]F#E1Ɲ9& .p+j|!xA%(,/<,9ǜ^,X/[Bt~qE< SQ􌓜1@Ifm+D+Kiwn&A(慟ig"PcL4,x$l>oulu65<*rr3, IUkht޿ 4ߠ.Y6exkR+U"!oB>f%*(̵V86_c^~3jsůȹu(Riq\7Gz$_l=FJK[rAUJcUN*|g]=ZDsLX2K7/xZ;6FR296K*Mߡ޾ڻg#(WTs9üE؛(]1L,X88ZLbQ3B IB[#/?csw|[k&&՟#1 [{j}ѠjXtp>pk~(s$QT`/O,]qT@)Wu|)(VlgXm?\AE5A-9AƆ dاtF@&q,ZhA'ĺĂ#dFydC/Ά2"93M\}؟di;*Uf2Ih_TF\ 6'cqCnD^}ĞtސbXcWtqdEHED\6/b\ujn ³@.J^,ʟopIzło_w6phLw?/A)x)e{菫1%m'N> ; ~%91S\Ge,Eyd|ZLPRϽs\Crn b4Y{ss iu$HT*Nu;)w@Nw<:' K 7 [F}ݳt ER6|!jXVǒGq7.A ^Oц kC%*QI8;aJ^ GT%pvM/܍-#6^)F׾z|9290ՠԒe\Vi'F/\Wt [7w&!j;ybN~Qm`5(M8mYBj:v$ 's8gԟx<;VMcVu_`\g3vfԈ4k?1-̑Nmkxe>>E'||I%_l/f"?jR&D1>/050TieS%RW -y# ^ġU;amv.T('k)(p1 2fDz'w]!kL"3A{F>虙[8(l{#1*xy5fTtzD?O (XYE-6">MQKXz*vs_ ޺~~7IVnxϠڂ}~;C{Ƿc=Kֱ/8٠&]v GߜoW+vW#Mb{&(,VG8 vd=[1!Gkq bTÚ y+$U[`~CiwۛyiQ˃ ܼ*oѼ$Up?`n4}7J98F"bmXɩ,vk"M1s<Kq:> N{֪W?.Vo0Ù}nNzyL;+ԫx@͵#ml1ϲ'Te_Ux[먽J_ð_Jq9(c@k|]1M,Ƶ&2ܾxsAN?o^ۉ~Qb-< w%]I*vϲ':wJGZ}YFEvs.S:iJBy/7ң>b OT#I1{$ˇ4xa*ƶXARM cwտ~>*+u4jBrم.|P#IU nus5?+倥I.d䑅heoި͔>lMǠ=R3WH*JL4<T93f1R7M')ob/VƋ[|yRꔼnוeeUnݦbY60mvAhKzA`PtfEذLxC<ΊJ3 OOm;[dxJۛޝ|DB1KovKI*nToׅOVaZgJ#|_xG }] ˑ-"dBp6+V ¢̙̑U<β(5U4#Z&V`zźGYK1^gUS+2>*O]_].gгq7Xu-`p;͔\`҆,2yRwm_\e>]Y7څκrbmf|\ MGF\_xbɲEZ}}Wlxk6FL>-oh2&X+lZ-W3R}țv}{zK6]؇@ŻfZ\*=P[޹Q^=95Uf]i,\436 ɨ-_Ve橵j^F+Iv4Wgb _*:l\wU6P$wx<;DrZNRtWU]u{Ju4siΪ_T^:aX^N#I88JV+nx0ae6\6^.Ǜ}h6`H~*W6< xi -9/Faq[x&V kjpboj2OOM7swwgZ2mFB6j>mMӍ}HKNa9\N&iVwIgd`Wuc|7xl]w=[IP&QuNŋ"Vr: #& (N5SZZnוn~oto03HQrfWl_eT{:OeZ~z]'x. IE{6v ^{&FY',™Yul{( {zlײd2>xViʞ/`:X4dme4# i^lFXꦐtlk"E5\mZYn+gz4w7l&gqzN:I6Z*P+W D/G7{@K ^V7I^MuR&^yؔȴSORqÒ29c{WDLr7NE~)/nWI]tTzr0ީYr[Y6Qd|{%"".MuYA3k6G%ش/T,~6/^=痪U^d"b,3i/ֱH X)vI^7{ME:^nqvwM"ӠbϋqIYLkAJ&Jb./ʽXUtWޤKX-YLxBF$ ji|]{͝oF&LJ=m.;.f~%ާ& e.T7E{Պl!bY4^ɢMooƼ[@ZOnb(.#1;~l寋}ڌuL ~ -rWryJ^k ,4_￈וN_Ai]f=SNcOx\ϛjS'˧aoVG~ WzU~kO~nV/mpz??>_Ys;Ziu8k igO$H$!.ϩ! zmAm[)>inx-mm֝ƨ7F{r4gc; l>l7h?ZvF|K*F֬9/TВC*5GS.{l'Ͻ~ g IJXjMH!ބcŰ.rI 5 IM=RO/B( 2 k"Dȏ"$9n="$ *򈐐&!hŤG^?MRxk#1tb$c?8/M ԁcee`iXS~P*E ^)i\Z:OF9o0la (ָq&k  a|_s/fqDSFCptHh.kS/Z`1璐O Cl=܌ [$٬SF^oаKh\4:yg4ĸUDg!iΓR.q M }ͯ=}搝FŲO 2- Y ~wuV~1"spdiH9%I)ZGpSN9$!^󩋥2$1Hn"ؖ$d)Bh 8(Bhd(vh {6yefKě|)vzuJAi[L|@׿.ou7k>5Fm86>wvA~K6 #eQg۠:Ҏ6vF,܎=B,S4D%QbaBqm̻R dH-̼47 If10YN]#fƺX^AaE $m2$/t!w#z.ተ|:oRH]Rk0>\R++؈Zuu+/~)BVL\AN$JH֨ #C\+PcWt'L&wN3|B.90%wr)Ύr3tBku  : XC->uf2 ?2'Qk !k 㧘+v-4nrP=kGbq-Lnx)9{B#h@Yv ٷ!t1މHD-$DG$|JgGSpuy;=o\E*#wt=|Dj}5%У1t]c%CJ2AGhZ&!LrFKgI2Mble<[9J00z-6-h6H,Zδ H kyh̡=2T;٧_@0GP/Cͤhqc³Fz"` \c)h`%,Kܧv,! '=K(AU;ӵeF@D0\!~.^]aӨh[>OwX8v1w:}^;;Fu֮Nյ^;@ߵ7R<%zV!ƒ8 #݀7!P&(?Y:8>1̉5! !VhP˂рO] 2"Π}*$lJ4W K<$ &G 'H   "L2P1cQ[@Gc?&`f2FrX 0Sx ]'/,87؟@yМ]y6PAj}X-DzAs3 -i`x#Ҁ#1V\Ge+5  *00bfs(F i ~Up 5X p_K`2lЂjNEiAOR C3hs2F% 2F 4Hܿ0mT?#fϽCLP@A?R!AEvnt0)T 9킰3B֊XB +@o%_Lo<4] ڗ!Ķ o@/P.1,/>XNs-2u5Zk,T_f#XXшg̙9+CL £)mP3g.m!$v)bk ß mU)~߃n';oi9(Hoį,|!K1(QB7;`` 4?s_;Ȃ9ϟ+c8֠0m0DQ @+a3#/ft{c1sk \jpT`+B-?qάY`PGZ~ V^OT%d+Q[G-AWGEb] \=e]g\Wμ+>x|:@/h@G}͛5'Λ%#b'I x}'DfaB[&Co2$bCai f%#ASƸ-遃6{c@pW98&! /O`y{q11hX?Gkie wX?*zu#kE'h:(U2b(d =Zz4ZZm7tJO"FH^rpDxҫ΍XMn8T~'i(+gi@JOo2߼'MX*df% dzDFJD:w|"1T;)v)lQvr=5'\{H@Bj-/O->q(舜+ן?l Jh"偰ī`Dq=" ݉UpAqTn:A e7:e" "v"bd~#xa*ف۠M| F?}~ K#5ɦ.j ./Lߏa0jx<4cJ>/[.b{'TGwSmAoըjd_u nCf蚨O} HCc4iw4臺͸eޡ ǑM cDyh8?O~LI?/IFNY v&~M?y<)"! pۜ/sü侉?ȁ/ݓ[<>>]}!e畄x^I(uy^I(~Tz&RoD%}g MOp.^ Ac`'3KtނlHFf%dLYx_~˂Z1?zfO"d'-Pl3c`E" >VA)8O7 0çs*Ey)y-P_aA}0EU,R& ̌s;*sf7p`y;A}W n9ٌwmZ)OfcY|Tc+@Ä8{N(\0)q>6/A\ەdļTJ] >`W|x>|lW?t%1|E`X*Jǐ?QNB8wGb`<#$Qkd{A{ɬ<]<ܟR^y H4 ZdA 2SΉ|C=E^NyXIpOrL iŔww;$ ,n;uWlG8~u5@U싗+J`pHJ@-EfgB656̑Fή<'N7dgou2~CsxCxGEfr 3BF⬟oSlzr^*ıN1TI}a;E@5<ǕI.7:K*&49jym:ɍ7ֈgfxnك57?OK?zo`"߷ݸ|ӻ?~ӧ?FOۍ[/;Z1|ˤ:6泐4q?h۟>;<}K:s/E;s=Ffʬcs(~ƱT[o{x;Z'>I* P}o;Snne G=Tsj!Oi[_Dc4OѹѲ"4"d-jw%Xk1~G?#'(q5xYWRY|<8d/ ;2C)˚뻟cdNhac`ϻކ|EBMme!Pfۋ@]@w^6^I5xT^N'{au>Fd h,$} O%]i%$a},33=bAWzƸ)>}RnOJvR}*h<4Lbƅ4}1]sQęI>ux'h &zepgdRV>qk!5Vyi%[xn/=^?|ZS֢Zuûݟo y3G_ _}VUH>T\%|lO0h\_^I0@NșAL]NE` B",KB,4 u^b_bn!Hne€u,1%Fζ;+iRgvSaV uE!$BZe۩S􋅾͉ غvz8lΉzv$I/v9-~ 6ȩl4ȼ?[ܸw?>BZd Op NdނAdkآ bw'Q64p9h'Bf8$!UDN;s%٘.13[^#Pe !I2Vĉa ?( }-PxFvUT*&iqK 6뛟|QAMD " [t 9e"s$h>+n&7 0;kf.GJtbt&iX\"KXPC\ ܞ@A@jyhvKO9p&lk}bRh(U+zS׾9Bt3؇ӻc*ƳΆI*'YHf,FAT9Fyp+>'S,-O1-;Q,ڀcgmYL@r}fbuT’FqAf'm(q]CAыd2٩d.L:6ժPfs~D*lH=ia, }ERk_JZTxĜ{8zu K]*e;@;.J[_7=$Q;<0{ A?# T[2Q$=* [C ]aP+.xA.SP6W8F{pm㏑JsN.Z!{揨sӽ1>'K>tp9[oR窆邏=3>A@N:-h$$*q[vt1̜ՅA%Ε(bqq׉qK|`B}H0ȊΗv:h֤$"Z MQ+1U n@ρb?uC* j77;W6Ro~b6p{G XfJ^˒OۚsD6Rr "JӅ.2̙];L:!qBtKvS2C( OJaܘ(\(aszBDpN5'^B Gy^`n׳𐄍~AG9)8ajI>`ld}%N v[(nZ_W%:U>Kw i2έƙܧ,4M1CnplNMzVe}A'VÇz{\ߧz;h7 6.>`M}8lm<mޒGk&r+kݑP`}E$(iv]JQzS~b@%~}gl8*.*`MdL`F@ 4ͽl^ԚCӀk`Ty% d<Uó4zIzP1JP6nǝoӱZyP 3O [zCZg`F4]i$ě y?iGI-%N20I;^Qk >,^|5CdwC2-1k|V_9&|hN4#"S'KPII!(bxj$fo$?lMe{\^\C[GYﱢ&L>hwMc1 .&SSjx yT2A9)hڀq5$`-=A`19Zp1._BҎ80G&"c *vn+m-0l.@- \gY! m847n(j&䯅eMj8lŹ̚4orWA.m >LB 7*h9aQd9>i%(5md6"S Xd&n÷" [Jxg&"IՃ$ q>+W<d0r# µB1E0jWYaq+NWW_UСj\O)kHLQvi' $*!#\HXjqD(Nb$YTР~Kc, $ ) ~NV1$ь%٬>A9yS6;J!r3n ALZ|Tg8DnBVLx![+2+Y}ijhnڣ4dW!3q4Ŷo3>JM1DٲGDa9 b  eMhQ偄 ТTDpy?%Vmt$R*PF={ 05NbI"1>ӨųP[R G?(rub&\#9sHj2`lƃVEPLfYa?^ J%j% Qmd,#٭{fEiWHf; /I6N>&uB %] @ !B26CY&sGۡm]<%Lr[jN=li74xuup|\"+R1v-)qcK mv$p?IZI 5 YBdgv2bQn61 _[<:ovOc~m#Iّha9[akq㍝[./tMc Ο֙(^hcx"䚿Jܰehǖ W"I$3&upJcH;Hk}ߘSֽ0ywӟ"eЋ\k1!!#!t=L,Fr^0~'if[_W<#1<_qW!IǛR! H{T}31(ʑ$Vb.%g2#1@sUFlDO{F ` +@3j-BJH چUƄa^|S,{eQ j?n+\]RBpь*7!z7q .Ppe{ؑ 7;'u n>2 XZS# לsUv+9Tz89փ L:29puz٤Bs6}w-NUQSZ^CS=!2h!x9L3ٴ8h F5eH(&EErte~1/ye<ը9X81=&o1 <BQ<,aLɥ笇}:"6\4,(TuPuH,cEVf;^g16VuS^%UW>Sdu+%7&{!K4Z7<L(o(Zslnɍz`p)bJHJH9ϭZNcZ_f%0R1療Z_M٬Z!übB ElM6Rݘm}>'FjT͆QiePx{(,BX  fK%uH(*ƌ&@F慱Y bo~jÓtW A4.Wz~6]/%%廽)~cxճvakq.WjD8C [!lnѮV%,[-O0/ʯ _WX.iDA&D9W%*,aAA LnHP fa\avu]Ic[SbVR99LUͱJXROAtM#g#k!4'_-.Zhif󐞗;pUߦǀb{tA&n /ݔeIS˩ZQL'IRe@1ќD[s E/bo\b[f/+ ˦I]iJaKU!j1]C?n7#Kԃ3_-SDOT{!Ra%;c`bmʊ{_?X(_ 3NӶ=zwu,݉,ڕ*Iw߸N5xyELo߻2|+zvn$7.9t4Mw?/.-<0]|sN< r[ǂlG Yw8KVr4f]UKVaG%M VvTWܒ"nu+hJNާŝ|ukDTYUTш>ELi'2Fc#,~rzne!a>_M9*H-Gs͗_^T[{툽 &eam|L݃uًwj4{Ѥ}b/^k~^PK9"h#!Yy'8i6of{dOih%9bH'H+ N`-ޗwJ~'uҦ)`h BF╲rڒ W2gx =vn;m@" qm/^$;a^%Ay)w#gՕ>1] O}dj1#!L1IrwN[ʒF4{v¶b\""D=\hr§[ƴYiuPi>Y ?1曃Z9H, [Ph2 oJ&2kqq%ѥ>pٹWP#fIGq__k-wby'~%XIBλz8CQ {*;Ni"g 0Y' @$ߖ$9al6G%lJ5˧XC T}нpJPynW2Q> +GuS!u4cknKbׄyUI(9ދ.fN93-=L9Yt o/OΖY`-Ft nWp,%:+'[:ܨl[ =($ ĿVo:s5y^`H$!#VTd4=]~KWӗ~I"d)ӆ#GA5ψrOUeGt$[X=۳q{oji7(xϦs(H7u#wG텥ʨ_|3w7R7˃_HԼ|yٕ6 ,73=OML)ؼeaﮚﮚǮצwDCd[u.zF=v+'v<*"Ko4Ii= LId{;Tr0uHסOTIгaT;Z++Oա4dƺit*xN{k=\ӑgӈ_EuINkst-2.0.3/src/images/svg_icons/change-data-file.svgz000644 001750 001750 00000020623 11544160207 022706 0ustar00synthsynth000000 000000 TLchange-data-file.svg]YsF~v .Ŏ%YDpgp3HPm_Y(A5սx,#t7=eNE?`v{+G{˕7{pgaqzVa_**a" zw4[Yύ '\zgt1S8/nz=ly4[?Vpt=>w ?yU3'j:Ĩx=8_Lpq;Կg%oo-|o<^j-n^'ݏ#nZ!"CBY>VޓS|Шz pm}g싵2ہ#_@Z.ȟ;WË?/rǫqOf_#oޛxywr0-/)'_gqߏxOH~^e?,|:Qjz44|:ZKBrs=jvQ?cL|LjCiFsg|xWåU BOJYO脋6>!ڥ~hV ~oxzƁ7h]dnM5 V 76kwdjsuT0c1@s1"ًoјpb%SAx)<N&KDRZ}PEB.TxJѼ<7 -R1*zFlңZiQlmҒǬPY/NqMpyVbLiǗhz`|ogxb)%4A+o B`|@=ijS[h..ӍxXlEU[IZ'g|ҍ{ g5A:pPA& '?Wɻ2P~ D` {r- @flҦ?ϼ/!D9<8:ضVhE8DE SoP%YԮ)꓾7}q}y>Q_[P[@KUfHĢp:TpٸQMkh\3hJ3I[t\A K4>iIG- 5-mZ r-`(#עEZR푶m\7H0Ѵ lɽ9UYT)M:X0†1췛 F{,e:̐Mx 9qa*۽h~;ßp| 7 ӇLˆơ@.b76f"m= #` +y:7ӤM4V7Q1Dk:YJb޸J(rX o ;ש.a;|~z>nx_EpMLj b1x\IIBaNm]zӏȕiv`j  k&THԠqP6Td,e]%N/h&dm޸>4_Nڋc+ɻV JGgkM6N(GmFqHh*Spj5˻ϑȢfʞe-QraL1#JkGF{p:f栀i3pbGEIoP{4a(W6o`B@i:VÛ.+NS%^Y5,=U}齚ՉNx&Ld"~&n"^{aO fM縡H$HĿTP$jBjt!(B!F`OkhW*?i8hY.bǹ8,q%R2&Т-u%T)#̬`kƵ .ւ^Ȕ1"HJ4( ܂iRڎ'U;1A NēU4$\᭝ 2JD8B]z N,8!pf S۲ e #xRtMP&_v,sL gg-AxR⥪/Kn cmGgKXǑ-$Ekk;e^<#t!TN& h$UɦQX[)/{eTgyw#}@: Ly l@: L@ ZˋK8dJ6d[hnnE^n/LP2'77KLGI4|mг XrDZT;66UL A!_5@]cGu5&ͮɚ ͆wVzm[k (I:Ӓp/ZLԚ-nLZfc"&e*.iU04eYi,4AfG 3j& 30faZvTpB~lK@ 'un,/#-Ŀl6M,IYCIжZΚuB1I"D(Nf 1V6 m$X;(' m{&{[byu %q)Pdań hnsr"P( LĖv∭a*F\UDemmퟁ3"ADgHI W# Ǭ;Afp9i#uN)p,N i!@"ܻ: F}8u&e2B뻰X5= u"e\}fDs5as*%D`:ʥL2r]%Qk1ZkN5-JziyHlLntcsXRrQI8ئN~T%\"#h͕I ̯+G KggxH;+x^= o AXg(q覐H$wI2ʐ4eDu A5s@Btxdר׃D6[!1-!!5j QM!!6HHh IZ:@H Zc&ZBBk AjDKHXZjIy#6?GgT|hc.m/Ɩ4>G}|__K|ypVI0à͏\=?p<,/,Iw=IJJ5@=4p1}UsMǵq V"j fsNUΜ*sdzr #:8`NN;*x}XgE.^BhSw\lzHWW%aS$ oylr"#^u퐖s#I7eo䍺~O[J,6D'LjjNHg &XaV+s4#4)€k6ɱí4vuTC+v*p!z5OnM5GJ&JSI_ &B0f*7`6/"zlשV⬝"A)uHxρ1(„8f"M$y8%ѯg]XN6*+/4Toښ\YY5ݿ]m5 id+2nӉ׫.A5m,5NliZWثX4SZD겚v'j7{13,A5Cx1#ܜ (U7q:/Q.26*CGEʯLT^X'̾1_ٺX'˾qoٱ1֡_a5ws2YYܤ}dB9Jzv9UovlG't]KvNO <(w"ܝu?fqwBK;Fݤlf#.38F`@#.|Lj!qTcxPKu:Qt#u#՝ej{09^idƄ[WA3.n$ypOY8̻X1G'sy=ݻ!z[ك{N|)Kk'cN}d0:uM P[NY'-f{㥻W~)*"-6fJxV^'7S g=P_?I`fNi+tRw֩iAF<`f6{>F.yWV=dޘ7MP3W󞂻olLeqW|_WV6ݾ==G8ġ%LEK%[m=R0Q zݼR~ʚ*-6%-q5&Կ AU~?\iDMwƣITppOwS0sc1ȴbꆋ[xwVtiD=TK;LEݻdO㜀}|JbN&C8QBlD{*0fJI3Js16Jp*P"NI'SE?\"lRʭFR'WP`䲈#N=GEJv uYϯ\@G)m##^ڴE0T;hF2`e2ƨ҃NzIYx!9fB73iU C,d?VSO}3gpWZAݏjslnS󩧾yA1@h2zNBNf4mDZ:pt9TC] !lڊ9;U` NJOk!D (+c386qk/wN1u#m6 MT/}vVHv)CHZ:W.)6$9 J>ؠd7M2;u9+R1C~|>(iɡ[q<3"%; ׸S>HɎ8~υ)9%$gq*yH(eV-I8`yñ_{׶6D}JEh S/yf6lee{$%R")Km#'eCxt>l uOdJEN Vw܈RƢVm]şQ}PPJ9YCsWͲ'_wB9}n~7V%~l p+-{|B{|.%\GqAjr2~t  zwa:裡6zR G4A~1AkZը$u,VRPl9IsJIJ6O塹M \8g4uH6W6yyCoxS%!S-OiNoݧF1iIf߰*1\ܤE4fjh̼Dc142 ^@tCx5X8sk,`rAvIoR x4}fںIE1\/|LOٝ51pc=T{P5^#JWYi,7{9$`soi#spIQfƑxl| Jdb 6a$}XrBoƃD++/ H.LddReI =Vs2Oc1ph##БGgy:.vaѠ!r!#G/9o+nvG`Υס:i e =si1Gs34RӔ"!1E/`" ,*#/Υ|@~_6\Ii򒔗tkAaFu.+Di.W|\ eszu;?r @(mUYI-7JOGiY!lNgܛ7*kcyY!lNc|{Fayir$WW|\"Y]_D[ (+?ee9]J .2Yp܆(}3ʓn u*Svd ,1 V٬]d?9"0%ۉwÚ(Ww !}^5fو3W:YZ*Dbou9<:j}!رTز7z MP VV[\.&}nqh7#bdQ,{t^0gqhc UHrJtc9b8 g [[Q$C&&h4(88d1f8$h  $[JH тyp8J1kDpIWN+pR쥐Z|B-n2&F5ΰGvKAi\)PVg<:l@/!l &/3oo)-?=ۻ'kst-2.0.3/src/images/svg_icons/page-next.svgz000644 001750 001750 00000016235 11544160207 021531 0ustar00synthsynth000000 000000 ]sƵ\ʗz.C3tڹNC͆"5$eK{AĂ\ eJbٳ7>'t1{=%b<|{/W{[p'o拣{ޏ7_1n9#8%7||i>Z&s,ix|Cr<)Z|sS~Z V~PFt+õMZϦ߂/㯖d[ ܙy>墸8dNWmRyn~2kxnduWX OLo~g|ןS2i9ܽΞ pqPsCkhf:Aw݁GyUB/#j*F`,&c*==R3`,zinSc5Ir( Us t ؤBUqUa n?xc L?=X,`(|+ɉ?S+ HG߉y*TֵнG6=`/] plnH#݋'"iФ>e Md EU>n,l۵>΅\ݹ [m:.8/ϭqYѾcL47~PUU܋2Z_ˉ *$Z=C^VdۘE}J}lrc3MOƯA$(,+mv8'_y#!*[~yl,v pLwt8?-g_$u8tL(v f4cޓ ~vZT?E\[o"VD#Ie'(юr/L6? K [%KOw6\o<.ߣК(Kn,Sdx]6 N?3Z_-j\$=y8q'Ϋgo@s"sp>TgSA8aB7hbe(c: S, sz ^' qéFzGeFoΉQA"NXNs4544\2R~EE|o!' maa!80PV}PܒF(yÍE68<(p "B?[$PKQՐ644|bJ^#r:m3)+ 1MIV_k8ihXn1s$?(("UR2t Y,C3f--YG2&V dA7GBZ0e0`9%hb *%ܧq 4dR}12q {|R*00U[~ĵ$FHn3,1ږacL.(4148a݊|Z#l13ND(]n`%uv4 τ:gmu%܁Un7XgI`6jFD]YM[Bo3R馃bFi;|ɡRmAcᢩr-(:]q^ع"TiL+ h£E5Va;uoWм[S(`4upr G4:Qv[& wDjNM4՜ø`ͬ@+X$HZՂ%$SqYBb Ĩ@vv$)`[L'Pkf0Ac ߊOʈޛ%d[23஁˚JfISf 7Mvd€ք(lbڙFԢl RiD!%8NNtݨ]+Xd+c(]d;8)ű:V /M/!ޓ(_M>lG4V 5)Rвt9XO=R\!f %`VrшɧǺzT O9'-;nfHG Gߙ o@bͯr hA u-#-7{X /s( ܃śM^3Qb&ɃdmGS1uOH=ʒ>B86?Tk2p͵֎%c:[5{j5S.V$KVjz@Tde%//M2i0EA_I"I%Ԓ%\Kbjj.ZTIST[r[90 #Rκ?́F12' JT垄^χ^}Pvb+䳀y|dGDR-{~$ @Y7Qnigmغὃa#aej05?FN0kWӍ*LUt4S=11v-8x,ќqtp[yg۬NbzsP˄<':\J&G`b>Uimԁ(ײyH (&戛9.gwWZ HJ_Xs&(o}vc>1vrAwTGsN7>໲ *CrNg߮V;|uyajNbYD[vq&~Rޙv ¦/)S~R*lP{CLEWbx:"/Ϗpq\*Xʞ iVTuZۓ*҄SM(*a}i8J9D!,'rTV(o.[ouiuJߎ6;Ҧ:s6,mh<ӼFR~ J &˂TkX+ X'fcչ1K>[5Y41Mn.?-_Q2_VҥSz;ѯ> Ǹ?߾q2wq^ /ϊ KxB< n^,ɲxE@BrP~:~-}apUە2`0.Օs24o[.uC~{fA Bh2DŽrK6 Y'75~aj6f{2j>|-Jz mG8Z.nL z\.ӽT6 >?P>~Y wօG3%盦rs6{"HYv.D 9D1kGZgY#/r՛d=Ücq՟WG&Ot{3ܿ>y\_cJZeII#dlG7xONݛ_oNt_A`VfmSIoΌG7Sz:z8z?{1oyƀfw$OOn9r9D!k8zq>$xxI,$7\o,EgрIC)7QDk6rضˤI UQe-{O;ٶdߤR&eڮ)0Y}`uƜ" x2a|r1Ub}Z&326Wz9JBgƹ>҆{*\m2[bY%bRgA1F̵\ =Yu;9DY8tݽQ @ Q@@#ɗ3VE6/"uv遆^X}QӋtQ p 'nI =+lہJz9}I6mա 7>sj`?Nf@ ]ZW*Ct'2yz)⦅ODO0T񽡆zDE2} -톆wFC+9qnu`6SmE4D!8LD,iեv‚3H&~paY,˓PY1tĂ$#%-XbSJeF^VfdF+J_hX4434P4QJTbCFĉ&m.9w9jR+b1n59Qr&EWr K#ayFs[WZY5*YbZ1PΏ,&l]B,g^(*$FQbxA<77H%Ca@ XiUixɨ\8^M|3E",澴e)|åqE2Iz8%{ͣrҚ#I ZәcMRvDl:v_]B<8=ONvba;/@Y"ȁu}=pdj,A\Xb Q%Hˊ|-#N(<9ldPQt)gZN5{Jג }uYci|݄EnQS͞ կ:Oj<{IX,z̺sY&"[Kvu~vX+Z-¸z_b{.Klwpn&,:6ꬎ ׵r[ r..dYoܗ>s Xưꉫ|#M_& ́0mT9 FF#`_L Uǻ%顥 NJiʪR_-SA/[}E'@,*$HqG wxM RY G}.njЙ^.obyqlp*,JoXaUhBD%۷IR Rn 9y:r2q8pQiNB~pg5U ~սjE] aBFo_uFyIKo/nwP gALh֮(i{M‚VS̶pzR\zORnōMjSU=^4Fjmuz~zu}coC.;wWSu^Ի CoYYZCsk}E4;DE۲h`R6ܖHJD5 RdcH d&@Sc vK$RZ KШ%QYK7R`7J2zFrv.qU ,n6hY-:u2 9pi"!3_AjӢXG !mӮ6ogcܡPN~!RjPfqZc?FKOH`TzJ:gd70AX揹Cc>@[)ހ8oВ2}8o`1(jӴ d#UI㏫ !Ho71U`hS#8"oj{gBZ1ЎiOB 'R?a2 OrT=*0;٣uF6Xڙ0Dz)G&<<ŌN3N 3lxe? W_CYHCyxwokst-2.0.3/src/images/svg_icons/edit_scalar.svg000644 001750 001750 00000037055 11544160207 021724 0ustar00synthsynth000000 000000 image/svg+xml (x) kst-2.0.3/src/images/svg_icons/kst_tiny.svg000644 001750 001750 00000211437 11544160207 021314 0ustar00synthsynth000000 000000 image/svg+xml kst-2.0.3/src/images/kst_datamanager.png000644 001750 001750 00000003131 11544160207 020556 0ustar00synthsynth000000 000000 PNG  IHDRusBIT|dtEXtSoftwarewww.inkscape.org<IDAT8uklSƟs!v'1#4!$Nե->4RE(-M[DՍ-Ь6h7!Bh6T.Cb/I|휋wreh{={C)Lf2``jQں>JmZ+HJi𬁤ٗry>]l^d-7O TY`L:O.{ r?q沢/?hZ6ö܃ :Sgwa{.w~$:AduSӟ*z{{~Z]<,{5Yc[X?Åbzx`\ĹaP^>~⯫W9t~>x+2|h݃6V#!ټ^Xٷ5w]]yaDGAkxv-bO}jj:RRTc5)#MsvZ"x`"w JsySƫvp@744֨氘ac/Y΃2uΉsvŐly&@"A!?ӒIyEh:yL#KJ-rwJu۶9 ȊWƌUsyLrdGgf;曋Df,Yr?0y`+:Wb\~b'C*8LȲz  (6vi+8;kh"a``ذ}qϞ .Nn׮wws->?zS̽*ULIiK[YdR]*%JH2J)yyy1BHJ!$㭭捛6u\BJ) 6_M4e馲7r1ɐ4spᜣ;1r#a_0⤏yQy<뮼| ,f<}iPρֆf\gTfetFg Nw (:FОGJ Zk2( 2BT٘!ϻ?Zb&ϻlO N ?EJI$R yd$}ySE.0қ~>s8֒*1k66izOHozXxׁukڢp;d1c-Jkhe78@q)NMvБGHf= =<߁/Ac$IH*RXkAd@ȋdchK^!ؗ>>{)@)!GD:Qq#@nu L/1Aju7z'} 4M( QRj?76P$|v( uS SJR%fQ,eY^Y\RR%alg}Dj:msyN(@0ay#f)'Y c[O=`K`$,bgujnRfs1:1N;C|;ȭ{Vx7~w!榮5ǦBG_l3ܮ 77uO78OxB[Ij;-Sq *K3_E,nn9[щqwlЃ?^qiFu qXęޫ>x#0;<nne1E IENDB`kst-2.0.3/src/images/lo32-app-kst.png000644 001750 001750 00000001110 11544160207 017560 0ustar00synthsynth000000 000000 PNG  IHDR szzIDATxq0jHR.805@FSreBtA\A0ytIe[;Rcnd.g̝3Q"RJ DD* 5_F#A,lzhcwȒ>A,nU,n _ ūH//AJ/Ow0t"Cgk#~Ę9k'[0^ϓ-O\mz`G> DF\P吳$b`C}'`WY|CyV̵G*sɊuckkE W;zΡXפj =FWw\jSTͫhSmx0Xap /{X`a{IENDB`kst-2.0.3/src/images/kst_gfx_picture.png000644 001750 001750 00000000705 11544160207 020635 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDATxŔjTAFOiZw..|wøpΝ".QḼsqdEuS|>|>은][_pJ̛a69e٫P wfpj!%pK%ͬC,΃XȾa =a+Pld#ǗiD3ɻ|a<ɣ}`x1 4D Oǻv Ysg$n쨵0)Ӈvg`im;D) ZRT5ˬ)"B<=$?vrvR-VNjؽlR2U+"w˖Ӂ UW~s0[`Yhc o3. $mj'u#PlMdIENDB`kst-2.0.3/src/images/document-open.png000644 001750 001750 00000001434 11544160207 020212 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵjAS6DР(AV\$H|"t% DшD$LgRt:3ATMM}]d!y)LVEB. ...-͆"9JL{F9.TN ~0N:1}4|ϓo@UU̬p@8pn\9 A]ںrgo>|rZ ̻(2TZ~X?TQ| cJs g:-%F)}>:qg2] ߑ}:`[:'Tkl2tC)hXk Pڕ|gr|sY&O Z"P_, uJinsO˩=5<FZ7ȶzcu#FL7 5\lАR4(n 6W560v$t# 0 oŠ^pJ=(dDF`E2g" wWT| 5ï?;S0 V$`!'nMBtf͆QG(\eY^lw1Z ou"fتghꭼ<}D0#WM;JW/pj]{8tg{8xK/qTyIENDB`kst-2.0.3/src/images/kst_csdnew.png000644 001750 001750 00000000676 11544160207 017610 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDAT8AN0?A2GͶ]p EX&'aĶ@{p:~+sg?Ic7JfC1/&c`\ IѶJ{&^3TESanR<%Թ^.!zg*Xװ,(?&'I"TVҍ;IVNdι8/TVac[SIZ)lhA?+ސ>cXN!(W; S\ ~h;h$K5m#~o~PٴGt(4 |H)e$a0e{{/)(I͈][OB2xdYf%@$6qz>|"L ! u3+`8XXX4^55!Vhb"ډ TTTT_i ?!I!uXNV(>s'Ii鵿^@x<(//G`8@ I_z+rt:u:NL&j6Rp4%n,lnnxrxx$qT*Gl8;;{"-ƮbvCѠ`;;;1o$q;:y^n zŕ#pjj^mmmi+ xOT=C7Q<P{V>LNNpLzd'%O9,˔$CCC(:.z8#l?&Qo<0xv922B,)) "˞>.̅e4R:[yq(S(4&4 ,*H^ITTTtR]]7;;{)88o"t*P/V翃߻u; jE"b6~?v;cC(@skniنe,۩AuA8eH6bu%OBPE{(9PRvvguBH;a`|7͈cHlA&Ě93D}:$DQVץIeu`ickoWnf&4)W-E{22}} '=޹`m;B'boO^/O&|mt+p7{T>ϻxJW,b_n1hHڏzjvthζ'hS^Dd.Hjtg.^,/Z>rZ}?dȞgӉ2MRr>:m._Sz;.mQxy&4ݹzcYh }2g1LIENDB`kst-2.0.3/src/images/text-x-log.png000644 001750 001750 00000001512 11544160207 017442 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵUn@=;vc(} BH; 6ln,݄?`۬hDUďuZ+D7gνsmH)qalТ+Ax$ Pa$"X1"MSh4FF=^9ömhLvLxE!fWżT/,CFh˰J%B(ժV\L̋GG,VH, v8i`2IH13R;풍=?4I@ɂ37Z[f2 !X&w–[B D`s(aa5Jd"@H R{gg(O9ajdap\zBRi$!LSm-La*RL'? }k5fO? T'뚎 jcUrp8qMF \Њ^3˭C (1'ꀨmôq'+S) 3dp.<4}}k%l6?mnn%m_Rml8VW( ~ 8{{{n˝s\ >.GkG5~!)LI O 9< =ϋk0_?M1zo`L6)IENDB`kst-2.0.3/src/images/read-to-end.png000644 001750 001750 00000002153 11544160207 017533 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsItEXtSoftwarewww.inkscape.org<IDAT8OlTUۙy}B+FCԸ1jE"1!]$h41F!,pAI.$H[B7ofޟu1P:%79߻;cch]wLWnIRE)smfֻ?:O oȭͺtwdLY(p/ט_;c;WޜȒq'zF_yY!ZJPJ q \K`;d|PK,&+ΥdFAMb!,,˂% &rp2Xv0žxn۶^1cZŊ$h݈֘XB#eVX{>}jhxAJi<ߓf5J%*! #^ 8qLs9ii>]'6lLH)40Z|g!!њ$A֧7+8n>r^Î%JSըVkDaܰ@kr6_Ͳm$b~zRjENkXy,IZW+<ïDQ @{JpuFUTH+֒K"֞ z;ٔsٸngz<ʭ_#ht8WFI /iX$ץْkg}WjŹ6ismBqcqLDQDF2Z\0R-5U\ܼs=22u[7 =$RkS--G+8 a cs7(H-}P@QS^ ܳ1 J 0Y;9a3?{zD]2GIcρI¸6c']͒U4xwC ZzZ6LI۴|6T&1ES_jGα}Cf@f^ y@=]}4=!@²w1]"0e Mtv׬IENDB`kst-2.0.3/src/images/tab-close.png000644 001750 001750 00000001471 11544160207 017307 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYsϐtIME .,IDATxՒoHqǿwmnfڦ2?|z'EoH/‚ |"3zQ&D Bo "E"3I5et6tn6D^;<;t4OQT֖qy>q<,p8"  EPB0z 0ժ!I2[X*" f3AAVv)Kr׿OC&XIIh4H R9 sssTYBϹR)*-//2I)&5k,[@<K[L)bZT3*,&##:4HSyYnF$b- Ur{Q~ڜKBABIӰ5yW@(H=քL,tA}ptȽ$0fA_ұ&b: R 9$9lr0GP1n ج |7] SHQb_lY@tM6˷Ӧ`]9rqsUl};qwXnRr󾣏F`g?6!Mw/#6SZjn0"Ԁ!5 U%REJm#Z* ؍Ib&ٙwֻv+!q{9+澵gϞ'`%iu.,,?s\)? !T-Z!P*ZcW(Xkgs_wKNJ %h|CmX(8((۰ ܷS3nLkclml7k1hmoe^kНmIB^M[[;ݛX/F+r5.]R"[*"N'ts"ŋ+d2I! r:Z#@k 5h211A.uľJ.f@˗/T c `% Cd2AJp\hkm{b!FFFϢAߡ볓 _嘥@tփ )c}>t"3:JO~3/PsmWUO"D`RJ>?/b[o"Y9i*{°&[cڞ>N"d EZw]v;ÏZK \OO~ooƛct BiTx$=;ˍ_W׾}/~@5_Ā2v.k|bUe۶P(SHLOOs8AR*q=l#f8\cDm,m@XljDzՂZvN6ۃfsDu'sss9s eFuRU0F$\мqC}O#Jhw;|tGOlߧWFovD @_])Lצ ҵ> !L@kEÇ }BF9˃c.ϞzJGC&Wjj5Q :*T|ުE*U=00hySejk."vA@3gID_:+Vo0FsOmVy≯qw1#yh fRJt;T|̽秧S, /|*fY"+++'OmVB晙EHWk5wf.p{waKK3L]0vS("0ctÿi-)MP/:HT-K3l> \}0$ k(!ZaR!J(m\"Ν;ܼysflllNȑ1ׂNr(,--͌3! w%1 n߾=311x}bȭ[f=x R]XXXRn_BJm(@OM"-VWqZ :٬㥐Dy@|C $1!ɜq#oөjP.C Ǒo8siGq|nq8=)@ = bi6TMz1*dOpѐ\ADG (A}%Fҭ{#2x})2T RIS zƟ@>yAv ##L6TyDm=|>ɭ>iɚ|+;suK-qmMGJUy_j{H:ihOAœz˭piNMp&+-s8+^.A)/voD $IƍhM~Z{^`zof]b`>rg'Zs(Ʈ9'6o^514+y2_/IENDB`kst-2.0.3/src/images/lo16-app-kst.png000644 001750 001750 00000000455 11544160207 017575 0ustar00synthsynth000000 000000 PNG  IHDRaIDATx D#0L4>L&=Q['EWY f+}{3ZJ1ƶ-5%`+VUz1p_+3BS[1 /ض ̌R7ۅhJ) E9;jq5#U}h)E%fQsL'h%ZtlGb4_@GKa#LoIENDB`kst-2.0.3/src/images/kst_gfx_breaklayout.png000644 001750 001750 00000002570 11544160207 021506 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYs  tIME '̞IDAT8˵[LW^u HQ*j -iiJ&jCR|ύCZӤч^a ]\@daYؙ9}(A?=@Y~wa)0}l. sݝG&|#?zMK0G D\EUX; XJy0%DV`= 0(|x](_P_xCOmb9!?v D~0UK<7 Gԙmw6AcLSVo]vcJ)B@1tqCB)XulSaE}'NiGnW&-+i$V5ͮ$Y&0v<; _\rc,v|xBYEinTF8%欮K Lbb0aTVk-/1:B̤'[Xٵ-<~;cx,,I#YXye%fi48BLNZUQopRY8K#]=6e PFʩ3g:::YB=;Г4eI.mRkepAB2$djR'O 8] pMMM6[6TD\2 QpJ~I:|x_ss󋮮4`)--444BD"!<'eY^u󪪮AQu=LSIENDB`kst-2.0.3/src/images/draw-bezier-curves.png000644 001750 001750 00000001513 11544160207 021153 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sRGBbKGD pHYsϐtIME 'IDAT8˵[Ham6UTTՍBPDQ,jUvpn rEL(@$"ň ÄIm],[Ny}? , %.}\%X: x.wUeMfۈ e* WHܕ} ~տJh֠ȼ~ύfj0t˥ptcP!ds6󖰢 pKJ(-=7wN|O~N7y%D"֮A4k`oyKodu^/̞:E4Ua rڐ^)aÇ)${F |>.ҵk@˵%it::@``[]]QwwllL-qzzk\6᪩UYs;w" HJ)u]J)d2i{~v ##FG 2\Mi>ܿ.UQAP-%,LMax x}}}MMMwBɭKOji4m&<{i/ݛg3MS&?o#-ZIENDB`kst-2.0.3/src/images/kst_zoomxy.png000644 001750 001750 00000002117 11544160207 017662 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8Lu_wǯ9ut`y$c*GpXm~s-I-]˶bn ],lAd80$؝~?4M< ^L)ei,0ñ%i}NSDDR dzz:vR_ْMWd>D~5Zk,ˊ, ҇p1 >b>8O$`vh(FG8 ?̅緰=!HY@a. ˕0B?De󽓴O0uuӧٸ_,-)ɿ\ͤIGGG"1f W<nCi)/|l(ZEh& ›/PY控>|~m3rI۵e'Oʻ0^,ˢ~G.OAxٲB$ۓm6[Ҿ~wQ^M_D1b{bd eoYifIENDB`kst-2.0.3/src/images/document-export.png000644 001750 001750 00000001471 11544160207 020573 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڥOSQ{}DkStЁ2 &A(F!90( N4M00Ib& 1c AhQ㵶^Ͼ;xsߞ{_%!m]\\&A3܆,K$)Q 57HzO C`b0pzd2@ #M%OH/0 Qh "Ȥldx(O0z{ o---%@b6`uWWB( fgg^oxqqtIyU0dJp{||}4M4 z Vx tOXV1<$33_> H ^CAU9&ZX|ݿ: 8<;1q A jp|Ag$'] z%_e׬Mr\[ '.(pIENDB`kst-2.0.3/src/images/kst_bold.png000644 001750 001750 00000001745 11544160207 017243 0ustar00synthsynth000000 000000 PNG  IHDRB sBIT|dtEXtSoftwarewww.inkscape.org<wIDAT8Mh\U73oJv&HFIp"YMхB pEq…6j4VP AfiPhDRIܹ.hý{~p{^7m]J5!#Si붜o~?>KG:ub)[n~Gi<_@RA4'?Ggq!B^ ӑyG e2/@4jM=*hkq)ǁʎwYfZR|xy9đjкQAFZkR}>H'\В{{{wYYYIT*|yJQM*!x[QxErJcP" W QY-aT.1\.GVZjJEdP"m{1qbuR}X$loo0sssAЬ (-ⶢODZW,666XZZboo^R7T9N:錺 FFFfqY_^fffj68bryT*!w[1DOhd*qM\a3I{mE:Z:Ja"lnnR({X__CXdE11::JFۇruQ&[SSH{wt|0SKZ(l=^5Zkjh; -Ġs6~oϦ yr8}gho^{s+B5ӭX]IENDB`kst-2.0.3/src/images/save-vectors.png000644 001750 001750 00000002641 11544160207 020057 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<IDAT8_l[W?kڎ}ob'i.hЦkGW@Q4a2i44u˴&4 Eb *:U+c[,iرsCjI>a[/ ݛ3_&VR8!Z1hZniۄah?e.ȑ#W~v(||{h`L1Qa0 ),..>sH!BE֛${xcLnq1==H!H&RJo>2AEDQ֚V=?vH;,bqH&Bp}F͠ޱ_|qxRRTzeƐvV7(vS(}5:w߃Zk㠵g?YT?13  8(Q'QciTRJ\]/' ILg)@Oyc}֙DOQ{1ApbJ)o盏|=+\%rZkV>W ^1q:Fc3GVq3 ٷs̜gnR*spNOԨ}S,Fwit:MVq=μ}]c|0qOX,=sE3f*r6wb9h Y}յ?^ݳ\^޽[xm&8ZF3PJ122BX8pumryǗ U^ߺJ8BXFJA \ץzs_jPɓ} `h밹+m_E_ΒJ4`h81N 6𪷊jk,:4v%[5/osYl^?fЎ?K6nnᯫwlZk>if|#IENDB`kst-2.0.3/src/images/kst_gfx_ellipse.png000644 001750 001750 00000001561 11544160207 020620 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8MlLQΛNyT)!iJ  R V MHBj!BmFM)N|㽙h(prs!_O37+"˄M&wkhEQV-/3VKk++7y%zG ZdӅoe=9оk**MK ݱs` Kd9l @v٦`jڶ5Vػ6erފD@ѽJ2d:t\F%;ZczK˲pt'TT1~9˃hC4Ou+_D,|ԛΎ7<0owPɬTơU*ݩ,ܕ]YZ\GXEGL]PRydO RPpAqɻpX"@DCVAM @H@8V u ioYSKu]Bzm,k?emόNo1Dq:;tGby5;[}9̎tdp /0&\<דfyyc;* s [fyo?׌ݝXԴ\ `\$HT\DAt?5D~9g" џqh"V5Lb1sw io,&/IENDB`kst-2.0.3/src/images/kst_editplots.png000644 001750 001750 00000002046 11544160207 020325 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8Mh\Uwޛ7yԉfd҄4DFDSM)u!nR,~!.*QEFhA]Q.VM$ Mf1d2oޛw\$6sDj܂4FɩT WG"$^w[95+ `>tb B4m 455e PJHJʋvy?ANZk9|0n ?ԧx?atL@(~b]AOiֶw03 ^C9~H{`vT_fp:&,fNN$WeWJ5(:~?@`7w<ރ1Cydmr N`FiKTFUz &# mض]ׁ7؞PpͿ>Pd8,mq6"RlFf (ڃHB,cDno[(l iaR8`6zHHv9M0|%"(Zz+4a`t$~Æ6ЎS^B;NZŶm"lv\4Mh!(Z<0;E; RoǵZ '3DT= 6>m P.j xtP\s 1PUZq ~؅e(- kk9@ٶ&@lZ\duIx_@ hwϵ˱TzЍqɏ>new(> :;9 wJdZ;]egO4^P̥8гoI<H%(_GPVC҂>u-ު]"\y OUd…i$^Ac A$8##eͰ˲ژIENDB`kst-2.0.3/src/images/kst_forward.png000644 001750 001750 00000002356 11544160207 017766 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYs ?@"tIME 2G9{IDATxڅKEUvwXdv bA$x0z'c 㥋>c;Fڦ}=o<]ɸSxB򹜏񘒹R]~sfyx'Љx8܄0I\ҋwroI)9 z![Oaݡ"z"0.SuX.azX& '{w N ONT; v !lm XMhDkwǞD\;~D#8`@B TiKqվz]UV dPHA`|2 7aHP@jt4ّHD) lVAF97P/bhM ef ~T?;FU*WtTX$EETP_eM\b֕Rp;Q JFIxG.\.P2U8~] o+>S&"}`H~XȤحmSqip؃dp<Iԕ ZyAUg# yH6O~[;4"WZ_^?R}<[SX\7=GVu{秃DtV6ŧ2F< @?2~p<~SJhjR(ZW ?.2 -7OI7o1= `ȐFa T7گϑE~n FZae-v|ww{OEEL*r:00è0!2vY JI[lUc cf8x&~=3TmnkQPPADŽM ՘[=[$ޙt_6ѮQHd*  CNncl}tX1:첞h<8} ۳KyoQc9LY|+`bV[Y U_wl>L [8 ўHlۋ fD"*8D2K bnk8V밶Io< ޑ _FRE&90 q M6 LLu'Ŭt:*I3b8 glQ/_ߺx:r_IENDB`kst-2.0.3/src/images/change-data-file.png000644 001750 001750 00000002125 11544160207 020504 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsq́tEXtSoftwarewww.inkscape.org<IDAT8oU8,R)c# }H!*\mQTEE$6QVgxlaU# Ů<}upn(HHg~}93#`$B%ߏk;${z} m33__s}D ԅQ8Ecڇ1 _^֞?8wU=<㡍:([ bp J+Qc ]GFXs uB+5Jk4t:dVnx`08c1D%1=A{{;n.kgX\.'\NRԿL&#\N&&&d||nmm}"KGчk"BcYEm۞=_#}%r*IENDB`kst-2.0.3/src/images/kst_pause.png000644 001750 001750 00000002247 11544160207 017436 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYs ?@"tIME %&KX94IDATxڝoE?3q P)TE !U(T T -= !q\zSDU"uPTi8kڻ;mIA<ћ}fOҙftc`c^{Z1#1]`F||uu_33 >Rerrd0&)saY]Yȿ_4n#tfs8#Ϧxh { KB ֌[ PTY{7 pk[_dr:/>x5scFfC lPQܮ!//Xyr"u\. p8wOoN(%FNM]M't"1}lZ?ŃAר}\811ZlVKdI!%tCOŀŀ€\4[00GյYX GW3#ܸmNO+9KJ4Z.lWw`!D^˜0p$dגumTx~&Y?b Y juXoKmtzWdo¶AX,hid/B[)wQo!@&RB7M ̶@muc 0^nhɍfn]Ͽ70Q%nbm0qU֒Tګ3tZYgULҎqѭifYW]qP{h囌囏 ^Z+/_V`jjʺjM}f><<-zf]UѰu"CJ|0oeLNZD:!H(ӓuL:|AOx\^= 47.%Ut÷yh4V dm%ql\oz8v(˿rl&'J#m#'iG/ecK`LLmmB`<{n 255% I:$(dSV ǁu&/? ,뻾 ph"Sh)Lԑ7w:|u?$B`IENDB`kst-2.0.3/src/images/kst_downarrow.png000644 001750 001750 00000002515 11544160207 020341 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYs ?@"tIME 6]IDATx}k\U?wLӚU :H7"?] .Dt nܨP((jkJlm5WI2ɼ7ͼwuh={GpS{vR3Y fV>W <v'*B0V_&I;?xG=e׬+ 4ֵ(͙Fsui4$ʶ_}$%pěx=;dW-VJ8;^rߜX'ͣ/l>ƫL޷$< BpvK;lTlx!"a˿y>< 0/]+ Z N ;1w9;w4B q2(anX&IzbzOM!%bCwX(w(`^\#zN֞9|.]m l_CsinDhc6LX?\GX,r:俤71~G'-e0K4,oEY]W=C3tz(%:eϸņF 㢟^p]0W@eUr`X-B{J̲@fjsYvTY6 SG$Rx[ӗk^~X :MkfBchv\S|yj%H90ZbWA)|| ^ Vץ f2~0ʱx,o}9 Qs5h\qKYn ,RT򆼊dzl( 6Uu܍-TD^TL/ h-ͷ3ۛ{keF6S 9/ ^qaO~9k@V%T+b., ykt^oӗctK^zj &XQ 85ݡYU/N:6mcŜ~:IyK~~fq}#"y?/xʹZlIENDB`kst-2.0.3/src/images/kst_uparrow.png000644 001750 001750 00000002450 11544160207 020014 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYs ,tIME ' IDATxڅKlE3ױ Q9@U$AU"!@܊7qA+aW"(U)}$vxڵww۴47ܠ*0c'0nT~]ot M@w;0+t<]2x/gocnѼIshJ8SொfZ5?t(zAOn'm{$ KM Ҍ[_9xt^8ҵw7/í)p AH)(9329f4olŌ6B𲹭m*s\.U#^hAR8Jҋ ۟-^xl'ܳ>:Yc 7+r_LFžQ7sTdEXݑOo+)^ #vnQ;!owG|R{6d5Y?;ΉVi!xzSV @72GmW& ?Ay %㻴dvww_$\ֻg0 a=gd3T\8xBF< C3gH$cT[6{z.JR<+khM\.l̼zmkm;4eJ ]2/en!zi&o(Kȯy1rg$x3%L\|Rj-$+^ Qk"? !<;w;$ }A=Q߄5 [^;E ku4_0CT+? vl' @rH_XX#h'ƿDV2*N* Fg~8X&r "+kWwI"0I>]R7,is/mHl4rTaӄcJ0f4hRPXd Hlw>}:&b luڃ4T*Im0㎿Da}J1 CQZ'5򣪊RE0"L-0JY'8"?K~<=tKt6{᣹\NTJ/a EyU( ڴ-K§-BPzt9۲31f3~rX9)pVƴ/|Y7h 1v#q@9׽? >y 㡤kJ4BBIENDB`kst-2.0.3/src/images/x-zoom.png000644 001750 001750 00000002205 11544160207 016663 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<IDAT8mL[U{K_愊Xܖ2TATl-}0&nal&.QgFc :T *eAK[eDINrΓs"*ٵKS>mk({Ӭ^)6ߝ? Uyf3˲r&$'Qm[TcPD8hUMo@ϴ׆q>-8>+xOU_LV.MZqVYl~/۲ShΜz/Ȉ"քdzL@$" Ke[[١OYȱe<,nӪ~ c3@(!,U=d'(]B0sؕ<( 9I FAx}0{&RB>Y{Y 2l.˧BKww߃FIq6;_JL1n{sܺޱc675sC˗[G$?޾8@WW*uXxxcη1 -u">Js(X_|79[GW=6Fqr ~qÑ<E63/sZPp5o;9ܴJQ_Nx3D7 6 ͯS?J3g  WA 5aMRiC z*sCC̏smn wztA8魔@ݻdhS"8p9JUaG('Ov6*{\)l}=ӧiq{U0 @t^UͷnU j# = CDd+Hċ{,N2j<IENDB`kst-2.0.3/src/images/kst.png000644 001750 001750 00000004376 11544160207 016246 0ustar00synthsynth000000 000000 PNG  IHDR szzIDAT(WiPT=MKl]n+4j#3`$h+Q 4:M*D8 %DDW7pp4HC# t }!0,Tw߭{{G̅ j4Ηw8م\mcggu!==e3 nnn眜@[[cP(4ްarɨAzz:\.ӧOop8EEEEEEuW]FMDDTQQAqqqAŔM{!"PGG G 1eYGccc$$$eY?.]@ @LL !ɰqFBBBQFEEEaҥN .Ovvv0&&f)S8 DYYkk,,,`om q~>yx`޼yؼy3 L;u`ӦM[dkkGwww5kL411AMM mT H$?~@2KJr `hhN7`3gNBRR.Hdʂ1o-_Lj༻v h] ~pp"֭[pC.}W0 Y5{f4$t*Kn| ߅ `˅P$~5DFF!"JJJ'sI2ƒH$HJZX%Ybc7PJJ EEE]韴6)::sr/\7`@II R1Vc#x#lC?!"[P0=?`t xcΝ;GK,!HDt ڵk'EGG_PT_mCzv6,["TWWԩSx1\\\p:;;qaܽ{޽{qfAׂeYC[':t( ^zEeeeyf|bYjZv-ҙ3gHӽ.V\A ǔFEE)rkC9FPPPpoށرcx<bccaccFAA222`aaXBpܷ&M##H$ =3raO`L:uX,VuvvUR(55i߾}TYYI 3 o^(||׭a@XXOD sN G/,K:4Z%uԮh&t"8Nn\^Lhر BDvJp, y2p @NNFwϥTv2TVVO ÇURT*-r~"Ȳ r3R?S雑  xzNtP*pJΞ|-o ->haRV<,Ǜ7li'BhB`DXpu/ѡؚ8._rQXxͶĉPQٳ~ 'i6&763=V9X\c0ו ϫjn%&MEMMY=ô )AAA33S:A@נV23rÏ0"W7p,NIBMwߥM.FAtat1M2x{.Q+e#.\Vy5jk%O+`ȑ=,pX| "E3P*s9V\O&[¥WQXT. @`i4aVrDGaV?ţjB_rvMf6~0? ,K $!lqZ[$,RuL&cmJ)VUrggdZ}UʨR{8b"Z!-J{P):ۛ Zk)96n F9C6Q*L5Բ_/s83C}Ku.@:"^p hūoןE:B-nll,^bcWP\Es0{kI\.1<<k7y^HtĞall \z#廀Ӄcee}?BL.>a&! !J:>t0) fY& !4-mGGGB@!m¬:;;ÌB__߿l===]WOk,loo(֘H$̥%.,,RYq6YB)5155# \Ir'_mL8'{I-l *e,rOHuGFFaeYJ)eiᕷQk|*8q"z92R ֞d1۵^ߛ|>wcؔu%`؆G}'_Cqw{H퍐 L˚+6PČlqtϙOА0`J?s<\3Ҷ}CVɪ&8N';;4_yy>aanف8nh=\SϾڊ|޾yM/BzɁTW`sS㘘Lͻ[u#}ZB>/VD:*&|3춚AσKOۻs5vu5X4Sjj;+Utٳ9GV}WQ:B{*yF,ijlrAMyZK `Mmjie](n:^JY!R*<QK b@UiUٞ?ÃC.+3ڏvUnl+=K^Xl v[^ Ft"~G̏r$`4DJPXX]d < VlGFc.c`Tsc!$"VۍuHm+]Hq;f)T bo:u} R5е I;8Rk G6 斀y ~A[RCAMp=kHh; l t=#drԕcH .$;\IENDB`kst-2.0.3/src/images/kst_stringedit.png000644 001750 001750 00000001642 11544160207 020473 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8ŕ[LWYEE%xV* jPRjҴ4ML4c/k|`Fm5}0MF@1rQle N֠k'9ə3g̙3g*oBWWy|Z 뤪qWkQKZyx>q#.+YAO\Ōi3']7]`dM~SO[kn?Н(#IӲ]ɹvΡHByTl1xЗk7̈́Qa'G/ ?_P):= }} ߼  "_ɀZuߝo>ͣ;/hP߇!"R^aa=3ջ6cjz@ uB-@o{O:`p:tg 6/Rl]w}4v܄3!U~* +"rҬmBr>:kOA*AH{t6 HITmF U] |G-0S~"K&@$lNkݿ"i|l[a*4ƅ?\Fԑ%bq B%E$ (  [N~w0˱nk^_rb Dǁ d78Ab?Д ˀOUOyk{JoL{CmOYi}7ްdoE_\O~0ڠCUc#_TU͔s*`{__o{mif\IENDB`kst-2.0.3/src/images/kst_scalaredit.png000644 001750 001750 00000002067 11544160207 020434 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8[LUP.t-& hcc jDm1TFL4ikXVcvPR @BD Kw^Ƈ.k$̜L挨*YVdo [f k*N^O p vwx"R ~ r=-"4W~p8u@j%GE6In xj SCj"< H Pd~ h5Wc86m1`σ^.D. N(?%) `ɚC΅zb5gbC0 ͖G@qr̈́H^.{)u˭g|%AIENDB`kst-2.0.3/src/images/kst_readFromEnd.png000644 001750 001750 00000002361 11544160207 020504 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYs ,tIME &~IDATxڅoU?v-XmkUbRb‹QHb41|h G# bYR+bHG!ݝΏ{m9gN=g tf3zc2`cq'@'#("tƨ亮_p(O=Sy/&iGJRW<ױ1duҙ!S$ƟIc \ 5@ss!B/s5Bq=W>{ќde6ý<7ht,"al?o36{íot+f|l"}\..xs$r ޙpH806 Þ#:qpDde{尰SJRBi:f|;Nf! CP3+i6h-Y:=`lO*_Mk)-Z;[) Y^~6R4}AŎ|2쉊.0B*ђZ/ӬGs ~&Yhb؟5f]&x>cX/ߗk4vf{Ԛa ADQd'D[F[NhBP慬 ,쮯< !@&r݈Fa3XriA meu8VkBlL-m0>:h/ҴTi4#᫏X'NG81z釂 0϶@~FUn-HG7*,v,Cbn2"e+Bڦs`ܗݣyxj dZڤ59doH@z̮9Z)xZZJfҕxfzjoI[lhùΜM‘$lMK^Mjcf z(˿K.\.ce3|LՋ8cѓD 0F\k{Z7Sצ֡uG #̞8htn. HTp!EDQ@N0q uk`ﵖV&໮73JIVIENDB`kst-2.0.3/src/images/kst_quickpsd.png000644 001750 001750 00000001141 11544160207 020134 0ustar00synthsynth000000 000000 PNG  IHDRĴl;(IDATx1j#1?{-Rr G,sz!p9e {SopB o YgL , =inBPÆp~'1EQi5VU T(gV"sbBk6x V6x~~Zxousd0#CdmO}E=o,K{o5}ߛڞ4Xר~dbE~>rTUiӀ/-6IENDB`kst-2.0.3/src/images/kst_reload.png000644 001750 001750 00000002403 11544160207 017561 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵ[lTU>s3ә5\,۪D NgRʴޔP-I4 JJ TZ 4rDCo<4&Ac:{ƄI[A_xZzҨzv>kSdAOTaOa$3ﶻ=a(@g֕|ZhPO _/D*t}҅_ov~lو+a3մ|yЅe&g)D\+~>#a v|q>#bXnطV;f傾t@Ůi^EY=zpC {5]H:Wumcm1֟Y.Gv{6) SA~_>v-HjL j^ɞcBHoN1UBD)"ј K.E#?9j0bA}#9˸/MZV/'1#$o}maXr| 縟⤰EF/)+eP]1(ڧ-G_) `1^wsu8R\ؽEۊ橬To͐jR0! p~D޵<}^³{h.[qTvx1o<侖 PT];C,s*j$a JA iMfOS`5@\0\<'J*Wdg.:_ۧJ5s: }|{ᖚK ,҃)*I0}#nJ+qJWv^zu( r5Buh'B'!c[Vb*K+n܇m۬AI'𚢔Ns.#-"h\ 2dbqRHnM9H>}M:]5YM R"nB?ө(8S98wYGc[m(D31Āp!s码#r?paH=+.\sDq2F,8!y4̗P첫6߅,Oj22',x~JcYrtVR RVenP.8' &xxf[coU0ͨc3 TKuM!..{ʽlIENDB`kst-2.0.3/src/images/page-next.png000644 001750 001750 00000002171 11544160207 017324 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsItEXtSoftwarewww.inkscape.org<IDAT8Mh\U7y$$MZ'U*BKS$-4Ņ"[H.Z(dإ B*TDFI*pc4f޻_.26:ls;ױK˟) /OZ[AV}VJ>o/<ytqXy`gvPJs+R:7k֝'/^<7["ώ*/B`E)R )5R*AmΟnjܙ_~{%Ч/yܕ<99N_.tuB88BI Fsr wywv=(ZcHBk1k0`;^+# `ȹPeahcP &IR*hm;BiR tXmAx9|w>D܎Ru˻Qp0L8~k"PLn_dIENDB`kst-2.0.3/src/images/resource-group.png000644 001750 001750 00000002270 11544160207 020415 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sRGB pHYsnnޱtIME  UCbKGD8IDATxKlTUޙ Ng- RPmhD u, ΅ 1l|kLC"bB, mycν2ݹw|w7φi HO:&_GDNScONnMk/ް'ϡ-`81Fqrd#CUkG&L&lQ{+D2 }fm'q_>g7o¶-r*%V*',z\o|T(AlIWg~\Z=8(N$T*<|G )ԑyR)cU;+YvifPj9]Ωjbx0m3ih4]$Iv@NP5iz1Ad(> 3ǎWTMVN骪J1A{{XҒLօ:&.an~#PP8&clOȢ0 M 3aw~VٝeZI%U_Wj<-~m; ԁg|sF ?"h9J靽o&Tʕ|U{ݽUʃy~2KPSu*@ԉ @2K=R6p2ֈ0傞>MuRŽmAsu v@\qq݋9 ੭[용c+ Md8:z ~u忌]u v,.ֺᕚs0IC&nJ(dAg&2noxdݪ+VR_tmBy`1H$IQql&IrR(GA>Il)q[ RS|4AxBз+zmG4ٌH OMM=p҆V N3l=t|!tѯfL!DR.WGeOՑ{\8߷o4 3_MBo8ՙ8V:nVN[9[%rp' z񥅾gq;e=Vٺ IFIENDB`kst-2.0.3/src/images/document-close.png000644 001750 001750 00000001772 11544160207 020363 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<wIDATxڵohe?[tT6i7{U|h E nӕU¾o9G;0[ZM!GմjMM$4m=Ls$m _y ]׹|!ā+di_,4Nph(d ihhp{t$I`Ѕ%MpE8NMcdè\6X~oxx!f 6ߏg_~# b?҈r2\i1ű1 O}0OtʣPs8]b/5(76 ECaN) ǪR<_ oì~8ؠ\m}^F.4t7XZ9Ӷr!mx.1O@ӳozJB´.- }}$Ϝawk~}u2K`4wJ062AϧЪa rGS")p{(Iq2^+6ˇ1dݼ>99zfW(ؚPsLn:-t:12rh0$tr6lXVdYcVn\`E2L cBH$5B2nVdYsssD1F?޺Ѯ`QhRaI4%Y&_jolb]Y]Mp`0jOH$f /"C:Yͷߍ*o E>b FVeXqp8_SxC?ym孲KVOJzIENDB`kst-2.0.3/src/images/draw-eraser.png000644 001750 001750 00000002224 11544160207 017647 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxڵmH[Wǟs574Q̷ۘFSM+j[ v@q{R2JF[?ح-kqӍk sMsΕ"ũ-py1(B)o5]C ^Y  \eź.=xPl< WCzz!>x=Km' VxT? @qf(u]]]Nw -{O罠J@!nKsss5_xmJw߷CꊄY0b ᫪Jjxkې|;'dNZRblydM^ eLбR`iqsiRufQ,0}![֒PUssscl#@M G7#%\,bQ7:e~t+ kOцiH {vPgRS rc=D24"_kҠHGRR|Y/#}ဤsGvuhOCCHdbV=PHxtɾf2s E&ݻ33vT y' _ݸ]:jkT"I"'MpEPtqlʲ\[#D+g?&@\RRRv R /޹<*׽* I?-Uѥ֊ni~~mkStI`2:4nc?̮ R A_hٹ4q `Ϸ}}}&}p0 aׄ8VR+Ӯ}WAAqpǩ*ЅXEv׷yQ~~g_MNN3'v'=$7%ݒ=A,WE'8DhD8!ǿx0s,>Ya]<oaaS9[cejS\ oYF=J@&ҥpZaE2`VQx` @u<E%n["RxG)5]4@n:HDž?xZ1d@IENDB`kst-2.0.3/src/images/kst_gfx_rounded_rectangle.png000644 001750 001750 00000001357 11544160207 022652 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDAT8?o\Eyq8V ^!lcu$ "5T%.D@7A4Bbk8f=PDki7sϝIbn9.ViP !H*}Z|uJTBL|\xL}vqR(G#( (Qam~' ')\볓ޮ_-!ǜ*BlAeSeG7ewꝥnޮ_-2OZq=K bmr͹+KŅM$N_2݊cg Y^kGGbyتd<`lDBY4;f{3vzߔeI/R=٪"p {_0 ?%YF X^QdO&ApHIENDB`kst-2.0.3/src/images/tools-wizard.png000644 001750 001750 00000002271 11544160207 020073 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<6IDATxڍT}LeݵWBkSZ(_AA(%d0AYM h$Li?&-2c&벰.j 26h -z5>ɓ_y#B'5. 1/ $3Orv++jش!-B \m. 떖C̓=uZgWWp62 M?<=M CZbJ|@P? I j>2[$w cbKb1=%d2-3g{<#IAeF#t&]6;fk8Euu'ݥ_yNwd_r%z<`fb̌JܘLr{x-p˜Dj{}5'XE<8] +Sk#p8 #]/G᫚MAplo]ǥKV&J PuuPtct?Bkf8 OL0F-nKohh`` N4Aٕ)D.t"_ `WW:ݴ=|$G+Ӻ76^KO):%*)"G%$,c>.n6Ra=TR%,'`/C(HHl覗\;'#:龾Bx 6r{p9E-M!1 :v^ 8aɠILUℜk7fG/}~/)% q:bobqlB2==ǝp8 jw۞ֽxBQ0.މ \._i[|R$BYgRiƙOMM-y[Vwk n>D:6ދ|Tr%+n2eE8VE"w[aјx!\~7Ol]#P8q2Liǟy\`ޭ&@,IENDB`kst-2.0.3/src/images/kst_error_2.png000644 001750 001750 00000000343 11544160207 017666 0ustar00synthsynth000000 000000 PNG  IHDRaIDATœ10(rߤS QXH"Fl%I[|{HcBk$GHǽ-"=Abj TgN#4LXb Ԅ/[,@uhhsrgK)烃rVv:kT:OHͪIENDB`kst-2.0.3/src/images/kst_vectoredit.png000644 001750 001750 00000002025 11544160207 020463 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<IDAT8mHel:ܤZ97އ"h8!C- ؂> XhQ0$m6j,c)M37tq׫gx=px_~DUKXhWjv,Sݩb[5t!v7b&_hy]t|!kkf1ᒏqh}z\"/ӡfz۞105o.@CD"D+ +n3 "~ 㽌z^]%jZY l';Y1u_(( '@(n2B\YWi2|`f?yҞ!}Ru6߲m~X@9t{;eUalLߗ|%ذ>J N?|a͡(l?Y]y,;{—TBɌ&f>&3KŌ.b;EjQp[AdAv˝=)8参a  $~񔵫N[1#UF^#^p^ ﷪^]Lc"TX^KDxij$7:#,] IENDB`kst-2.0.3/src/images/kst_gfx_arrow.png000644 001750 001750 00000001106 11544160207 020310 0ustar00synthsynth000000 000000 PNG  IHDRĴl; IDAT8?kSasnD["t)tP*8(AIFO"`!V RH>@.U 5Mrq6mrg?ޟ;qHX+dy?M-#d%vQA`bܛ}o$1;ҐQl@ߎ{n}!2D'CyYݪZnaغ]'3/RQj4L D1q٤9-#Agޞguv=o9繢*qDZaD:\R ̨` `KL$_.|ѕ/|Ȍ`<"{R5| ꇈkIjZu3V?`IJs]n/ܙHX&&IUqbE[ݸ#՛̳ChSd}xbjvk<ǙUs:- اSsyc<pa(xM<ϥwi , K*p$5‡0Ys43NN%AOT *dšZ(HU5᝛i \,Od$x 6c2)=A^"9"[,Cݾ̯5 0]GJsLvX6ۋF2D4,]8@+즇desa#| UЙivv)0 314šhL[I"S)T I6x;yߓJq5( t]W% ӦjYt8;hL ִ"޽~݌y"B'6בld;;4@ɪYB P2 \Ue_bd T1ӴoǏ0@Uҩ<,kuWU3|q; 3ת釾hz`W7M@y"o8=]2@-$|N9z 8`L< xρbe>#Ed('}EDr} P%( |Y # (U.c@\U/HE?X> DHIENDB`kst-2.0.3/src/images/kst_graphfile.png000644 001750 001750 00000001450 11544160207 020255 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDATxkG?iV&Z#T\xo7 {L y1*{уZ=dgJxZEBMhclL}}o]{0>00}_>;R dSJ", x>@65T+0 J&sJL *mkAF9,`ki8.r^U< B"`c˲G\Qi=!,2d2Z[7'N/fmRNLVPC5oqwǘ<ߥ8"{Wƥi_ ;ҍ<]sMf =YqZ(5##?lN]{zx=g|ڶ G9Vg y'u|>#6Lx3&E wځ:8u ^5Ͱq8NxO'aZj0J%[u`˹nB#B̈́MFсux.kUY>cccŋlb?2?taeffxı H`T*e9Ø}C5 Zvn6p&BoN8套6Ia]57A>AT%4iY.֞ߗOw,-@5wVhmh+TS?|>5ɤpAg"ěmDIENDB`kst-2.0.3/src/images/y-zoom.png000644 001750 001750 00000002155 11544160207 016670 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsaa0UtEXtSoftwarewww.inkscape.org<IDAT8mL[eZ`8AfJAc2hqh4dCY2# n,̹e Ȉ 1NgB- lo_}@ 8^Or+Ngtlm!t]+7!}0!x3)] [FM1UҊZ_oE(|VS.xa#;] 7*0aCj>0-$ he0q`yZlW^x>c,3#iPe<-{ A"a?,fjfI.y7*$Gd/w8 R*iLo\fFb qMD*^ux@ÇGf]2z{׹'ꏱ'ޯi(68$X؁wqn ot63[s'?l6A~(j[æ542ꪇks4yR"xx˾2/z$Ĵ  arM&/עBS㣣Ve<.Y(~FB3tC/Skipu&(M^Ny Ȟ@"[^#26na~m @18[Ȁa(oXK$gj0l'BZkɔZ>Q]^i]?g̴5 Z&346Td(4Qxav.\CwVi^ّB-̼ P0v)@Jv -ܶݖbNX V< oVW3lkibNsH9xT'I'J?w Hd fڜ7k#\< E~ki/؄Q!єe:6*0An-);NCNH I}s *h=/[2lA1YXʶx e<%=rZ,KyR]2G5D45g@Y;}ٞ~u?/8߯e2qJa@ 60~7mRȪz֬**WĵwT8;3G\ 1G 8ejBt`^yv k5)hz|8Iigb" 8}tD1i H ER JbM5`mҬMif>3>nKR|3C8?$ުqϛ[ a}ۮL9n3r_ue2m4l(sJaD#/)vlStq[48o*\l `wmz]7}dOt毽J;jMH\. %TgY( T0HX*Q0Hg䅴P^tʎox :ͳKq0D0wg6MEY@$X6ۦ|fѠYk`.!#cCݤ~o{;>T[@BVe`눶mSRٌP*31:yP0JL%"k!:%`V$vuƆ^˲(e-n/kj<][j*pw>7X(5$u@ p^G:<\ni]@8JS)n1U+9&p76TJNE]6"3qX)K;̶R% tTj:j*58B<`VlXgl2<Pu'&0=>wLɾ?pŕ4Ep \5 qQ jQG.] !9OWoS]!L'ѩ 0)24bSÓ{eumh TpLWMof) CQpi((S?x %]䮯$. EaM뭔xxyayZ>923Q/CzUsokr@-1zFSvM> )U "(`h?N[7TIENDB`kst-2.0.3/src/images/kst_scalarnew.png000644 001750 001750 00000001653 11544160207 020300 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<=IDAT8MhTgs'NƉ s(Y4H+0$mMhF1Mڪ% EIohQE%Ԋ1q&ɝtdpWTJ&$䤓aek?XF@UAU&@0eryk LmJY,30 .,Un8lDlKu#:TԪ>֡%"RFamd/7u1&'qyieDJԝQ'ohQKS7t46f!vHB0@飊K0nˁasNCxwoqgl)ׅשT+ʏ(U :fb107ng͂ϝfD%@*$Jߠ.7g`x/y#{*/XT7˅Eo`jn֜`YL ')b?\a7x.L?avPV6?#@ccSogĔe't!\G:eY)^ \/,PUT9b2L M &ɼ|?_胃@ o&&qv̢9&4Ϲr{6½ rD65G+ ,vGhT/Aw04?IENDB`kst-2.0.3/src/images/kst_viewmanager.png000644 001750 001750 00000002473 11544160207 020627 0ustar00synthsynth000000 000000 PNG  IHDRĴl;tEXtSoftwarewww.inkscape.org<IDATx}[LTWs.ÀEPDZ/dImrk(ƨOmIk6Bkjo`( X//3sf}PqP־|{?koiԨQm:@}}}dzzc+0ϝ;7vOB1"PX;n}\RZOO\Ғu\qrB!Cx5~?C7i5115**X ݲSAK\ݶ~žb䆆y6w2zvu޽Kij*aa>>aA4c YfuTWWU,_VUag2OJJj{1s'@;No?, }((PI)'w h 4VZ׬н^ZYTiPUUqPw+'7' 2DB;䯲!VUۙ͌).FQUu( /l3<6V #QD.|a]rZ{5;ܴ_E MO7x2)-OYZtډM45r%d|:$zY`(˒ " i+K<.ظޤĄ􎳵hƆ hnnFQN'7nt˖-0~<}` o718]6ҥK!í:7o uրdEnii BHaa!oOKeMFSc˜ũs9pKR^^b I&o޼yH+(+tvR YgBt5✼_viQƗ| I +5 ,2†} ΁!wc=g`ŠSdQYuݻP[Sc~Br`#G|h9O3)2ٟqߘCBIxk}Ͼq[tD_U~y?'-QgM:6 YӋ{|E[vv6W1O~rqL)3pΎ$-lۻ***4kt:Qvg+'v~ڽ5ٝ)p{$x#866֝Ncc%99Oexܹ֫:W^qA,I->Vbfwggy9O3lZW?yci@ik yReYMliM>S.FoxQBPw *LݼI)\!m[DDW_z(FfkGcOhTzE oE"rKz׮eeǰS?KiʭŢ\ڳG{nrchH" }_ hM`6߇wŗhVm!TpFo 2"a;p j@CQ}ekbUBT'@qDĎ}s8{,Pc < a,ˢRDfX,;ݧ bضMX$Hy^@i]۶Jۮӓ^C'* 9]6 :P=弽o\rRϣrM"Q)"wSIŷ_$ 6YX(oD<{uMR uˢi~.ֆZвe|J~!of[{s{c8y$J)ǩ3FkmĶm̚J%) ȵkdŒd$(w@TBD}jU_C$addx~ Ŗ*T|B1m!Y6S ~$3J&:nn˶eٟd.g(~eɒF@`C,C1 {9ǹds4{S4.9,&=ˎ`0pzo?8ŀq|ht|#' ];J _|HΏGPYU9 V;Dc#RddHNɳ>?MYy'48|%/mIΒ`IiI+05= Ḿ+s̝aPKnMB2sIiY_uM)s9FdyE/]s=J<]L2 mokoqm6KI 'DWw@H۶oK5D9ú".^`OoG5DEs\&$XTaC݆g8?q OMHnm0ýJi<6P J9a Q@$Q$f(8.%;PI$ў"2I$p ޤI8lބY1.54Kh@=Uj=bGQ+Hr00/ۿL&/_Ŋ(MھpC[=f s [6mn卬x€1:H.MNcfOEk0Ph)RF7s~5dyr~bzMVc` b`" ' ߿*]Dowvjvkz+mSw:-B%\5g \0]2v{\? æļlpUˌ%rʊo>;:g9$dA,9w{|2u,mćůc JiRl\' ggy@Xy~ W89kx+Q.))xiG ~1ƢAkCF lȱuw>3 R b$0rZ|ߧVis o?c{oc,qH"jnxn1Z ?~V8 È Vl5}JCZcxM|&)3Η#!3 %M-`M 7mH!Z]mhlIISY\Xb -ԟ&($Ci> \)8Wkôf܆T9[*3j:1XSpIT ?ŃԡǹVW%L`RTب|~AϹZY LUJ.|$N>Q- G+b>u74Axݔ bVJclGh!]_",C8n{%jV 4RыX}KTf(Rqkhc7_Mv#äN pRC׿ !=]}5C@?ЇpZ)@Ѧ }efVIENDB`kst-2.0.3/src/images/kst_changefile.png000644 001750 001750 00000002301 11544160207 020375 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|dtEXtSoftwarewww.inkscape.org<SIDAT8Mle3el)*RB§B h=`Ġ$xG8qDh<4!j1QM biBnvfwy=4?yϫR4$DQ[LjRJMӄ|@?hP('eR$"w <N|kZbsOM yg4?[uQKk#LO2IqG ,Z_,vo^ťiM^x*r'$ϫt aI4D$cWXg3,fF]Ns&ٱOQ9 ; H[ ?~[W28RC eޏ!---39ݿ3t^)sKk[ JTLTiaT|udAxsHp8HN9rdg-[` p=p]pT>OP`4Wq,Ԡ䛟ưm{!8,\\B%؎G!7IeL0M("Tl)K04CrRJ;Ɖ'"D`zP= k32fA -MtP*+ !V*!$qz1Fz֐Ifܤo0˘aE[ecYU>qP={:!XVU2e /< u~6Jڕ_x`QJl[#38wqԄ%OޡmtwH?3*Ojn?xeC^/u]0 !38Eb:6/WyB|}oLqڞ!( (8m.lLZRJ[hig2YJ3NR`st>6>uqݼ09R(DBsA8p<\C097Y+$ƱEKM,qsѕ)d2'qXc:`fI`ݚոڗCqjQ8ma8{ʂ5'wt BPi>9ɍ S;~v\4ĹaV:r#dd̰\fw0:[dp}@VQl4?O!0T8) C<}iZًr^z{{%~!"8ȢvaCpN@XX z S pnh_o4us1c~"IIQQs[,fjoLv}/3 [ kʃHyoRO58@~;Bb4T[woN 1V^ G#VE]$`BL覔 tu9ї*-a[ cBGwJ,P za 6vv`N^燻{Z;' kS_-[H]xb[G|2\ X1čiztthRŦ[B(כ4Mc/]Bܗlf \w"ΞiR$~h暾 3oŰ- &c8\"#cqI-o) zgn8d݆Dr/aQ]DڋcR""оQpy [vdCP!n siEkumy{w/`9_g-iSK`xi,Ex N{vyh~hh mjJPpLf8[ZZBk 8qH$\L6%]{ϱqLugvvZu;Zk/1UB5?؏F8N'؞CO7npw`0#Z@N~ =|gfH200"뢵&cAD $IRz{؁뺭׍1QDc" "Jl/JyjuJ)̼"lė#8fZ#]<_A޹R( %*Ovx6" "ED0X*0v >]c~Χ\dROg13_W+qc.çAQԴq(޼Il ]M1CIENDB`kst-2.0.3/src/images/xy-zoom.png000644 001750 001750 00000002360 11544160207 017056 0ustar00synthsynth000000 000000 PNG  IHDRB sBIT|d pHYsssچtEXtSoftwarewww.inkscape.org<mIDAT8iLTW738.XdlmF%v--Z~L4MMZMjclKR4؅q) 0Ȣaf{~ IΧ{;ˈqxhٜĮK]*R:ƈ`U/LȘlq=vp_OTwH5k-MEs~}@/@]*IA]*{{ٲ=~{#"D=nYhy2-0LBD5+&tp})` V;rlH0v  b"505=AWB`"usxϜ5Wҭn ā_/+4-&glTgvm]gf>+` r- 2gƝۺ6/oRlOvq$Id >AĴ:fnRn>1Nq[ks*HBoH| &c>b=2=N@D{\)ɦlNHu| }7\`݌L# &=?l aas ~{_^왋 ZIu/^_W q$!HJhp"-@V&$CUljOycZ꿚cjԢ 4s11ab ^PNN~(-靃pfҸ&87G0$d'A0 >k'hg‰TWvڤVv,hi`aA;n%x3#'OCr^S}AV!IVޒRIƙ88^yn-\=6j )p2&oì1`ۇ ό΄4Jq{-[3g\zpJNjݨ>7C^y( \`^j?3uֵ!<0E_;QW*YEҔ?{Q+MEj*dfgSRPpҾP0 '%F^5;,XUurrxrZ޲bRf_HNo R~j-K \níN x(0T ]|/!HW& -Xh+?fksIENDB`kst-2.0.3/src/images/application-exit.png000644 001750 001750 00000002156 11544160207 020711 0ustar00synthsynth000000 000000 PNG  IHDRĴl; pHYsϐtIME  ҡabKGDIDATxڵ_hUƿgfw6ِ MIMI`#DHE҆C4(J+bOyRԧXi(H$&6knSEnٝٹ3lZ"ss࿨ B W sv{קzT6˃w{ ܿ{|<%A-/M]]pDV?=! N=oU.ߔceiT_F&sg1t]@ϝ=9^X;hLm{$wc!N$0}IN\K /"n*WHP`EJK>]4nm*;KtקtW{*cUBe™3i kc[o/ e$zzyR(RC^ ։VASbQº:1 ٮnܔ\>BuVV079u9ľz0w}7wbaJ-%?ʭ<ϡlw$k#f!j$O=Ͽ 2@'2qzҳ֑=O\XQx}dbZ_ĥp.J)!bUć)<UwX)t 딤-'{V D IK^ 1H e} Bzu7P|8@#F߄Ik3l`368Sŷ $Mt#0'FАY$uᣨ} |?'fEgBR?B<Qk8}5h4 4~iIFxeNu{d:`lS4(=H$557߂Jb ~L#eWKpK6 (:@8e:>53owk/…$Y~0#8+cPbA gs(@/ bF "V [SXr}{ۣ/&"0 J I#,=@Iә2 j<Xf<) fy56؅'>Z?(!3*?lIENDB`kst-2.0.3/src/images/no.png000644 001750 001750 00000000354 11544160207 016051 0ustar00synthsynth000000 000000 PNG  IHDRRgAMA aPLTE@GtRNS@6:bKGDH pHYs  tIME 1P ]FIDATxc`@ PbP* 8 CT2 *@P0aj1Xn<F*2sIENDB`kst-2.0.3/src/images/kst_histogramnew.png000644 001750 001750 00000000654 11544160207 021030 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sIDAT8NPe6 Y`@}L!Z@j(HqބAQ@C'ՙ$(/ Q/475Ҷl$IENDB`kst-2.0.3/src/images/tied-zoom.png000644 001750 001750 00000003211 11544160207 017337 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sBIT|d pHYsccΖstEXtSoftwarewww.inkscape.org<IDAT8{PUsﹻ3\^ ,RB%#jmL hMҚ$bg,JI%/H+"YcW!G0993sg!0Œg2 d/HT(UlO[7\.B9) k%xut\wтE?[2 !Ϛ?>}sD[l| #Ӯ֫y*(` ~.\߮x¯?]r]HOOWt:x0#<_"lXYZP(yV0 !IqAa BCttcDZ B !g_ngV8`2yri6耄 0*PeLdY@lR4oaN&QXhžO?$''K9G-.Kс#20 0 `EƏr[>R( Igά޴eXyncL&É@"14]1\|81*v5k" pឃ_~7;#c%'#EQP~ %D) !C`ݾN3vCCeFqluMrEeeB^## &u">ADWEBƂ0g1Zi4$TSSgXm;̉ڻgn1l/mXd*{qUd)D1 eqӭ֤!,477GRQz ^|Uqwڵꃪcwwo=|z:].Wb|jy^7G{Ja^g7o^:1a ^؛0"Tlrw߭jw*1BL|ggu:Վm6(nhm OM$Zp为1x3ȲZChE)))w*+)>}q`<La*nK9S}K!e{DR{unV|yYm-p ݮO8FF!_ѣ(̩'v߷T*Us\Fkt݂bXOHIK}e&CL&E)znazoҥ*)Za'1c(rl{{ςiCKyyJNظh%wekhԩ*̌ Y6N5;vfSqqXmP'{Av@GNSH2NZ:hκ!OŨT ϗܑ3pwjj[ fQd6FY :_2IENDB`kst-2.0.3/src/images/lo16-mime-kst.png000644 001750 001750 00000000455 11544160207 017744 0ustar00synthsynth000000 000000 PNG  IHDRaIDATx D#0L4>L&=Q['EWY f+}{3ZJ1ƶ-5%`+VUz1p_+3BS[1 /ض ̌R7ۅhJ) E9;jq5#U}h)E%fQsL'h%ZtlGb4_@GKa#LoIENDB`kst-2.0.3/src/images/kst_rightarrow.png000644 001750 001750 00000002437 11544160207 020512 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYs ,tIME 'VnIDATxڍk\E?4IhMZ[FRPQUA "*U" W b5X4mif{􇶶/3g>s93l^MlkSvnVt<~E<0"Ltd?GO/j$[CW_|fGxw*"A+A&wݞ;ٶa]Dv|\H](2^PA<=:Vd ¶6$Rpo1?-ӡr\_un@ў!Tw擃%)hJ:ܻ1ɑ5rkFKsn&웉7̄*6rψ,DZHgV:woH%%CZOGG55$Z˲s"$]ޝ|vloRkŭ5Q,j!9AeH'$J),Rsqt}JhDeNõLVj*˾o깲3 >6yw[1榓|tζ-Q$[ ٔQa fsp{rەK* |O=R$i݈\DU8{KԈ9=H!-=mU,@Y =WuA9)t"2!͞el?hvő= K}(@'|eɺwa%*~ieԝ 5;|rv_~1x_\+PI4r ll|.!lo8p}X\ 1 $i[ƶk<59R]xΆs߃7#cmQd6FILҍԭr^nvnUߏK 򗱴g,2\Zxl[XeK2`,B^Hڄծ8Yw-?$*']r!i?I&i/$mh&U!7o?٧>~9jU~Uz(;;*P$0 bk#v|MF' #$\Arym֙‰\BϔL.3ݏf)֬]PoGxsƁV-Wg&sNj`Rěj*ʩF]fεNjtt#]\ Db=Nl2_8qZT*/ȑ#G4>_GkUCۚr2^t44zA+3*qj%Hr^ns@T*{/{hRhIENDB`kst-2.0.3/src/images/kst_advance.png000644 001750 001750 00000000710 11544160207 017713 0ustar00synthsynth000000 000000 PNG  IHDRĴl;IDATxAj0EK/]A>O‹.rK/#Hed H ꢱj;NÀ_3$]q "1㽟]l6HXD>zG VUiZ/YGY/ /E H™E&Jۢ@^_SSG1Ȩ'")hI͑֓3mWJykQJʓGP!@6p:9kTߊmpKv+˒@u̓gu zMz)[ ZkGǀLa:ҹg#iia1fKɫAXzMߍM-.=J)A)j"@ǵs/qUU=&b]IENDB`kst-2.0.3/src/images/kst_gfx_label.png000644 001750 001750 00000000545 11544160207 020243 0ustar00synthsynth000000 000000 PNG  IHDRĴl;bKGD pHYs  #utIME  | VIDATxS1E@}D% Q(A*6ؓ8mt$\B̯X|''fv͛veY!9Csm/ uw<ϣm\O!q4,S<4a\Ucʊu.Ym@˲u-MO-#lFE0M:cP9'KZba$ } Wqq Bg|V='E]1Xb; N9}?ń&Xd֮J3=?yr?<eZ&1339q4P(xp:z-@ǒH$Bff[B/o}ێQw+/ $o,ŖHkQ4M7QBH.{)kKvLq0l(A_533`XJړh:`iQQQ aamk׭5Mdoox (iT*!#SZX-mll\߰d; Ç kî,Zy/C" hhN#F {%|b=Z6uv=-UUs\joE $+͖&"Gq.Q0nc9нBqn'"2W7_vUMMMa2HpQjxZl{{ E ,6>v;'[?_p'ھ?K p8O{+*6QN~#g4:0 i@"Dyyx^00KKȈʕ#E_jj4%⌫GF.\X i:rp$paIog>I /?IENDB`kst-2.0.3/src/images/code-class.png000644 001750 001750 00000001570 11544160207 017453 0ustar00synthsynth000000 000000 PNG  IHDRĴl;sRGBbKGD pHYsϐtIME5IDATxڝOheovI6Ic A*-x(JD&`AQWAh E*U@n667N؍a홗oB;ח?hRLӁr呉7f^{zD|p[iK1h6 Uk ENxI%ϷWZiubapCg[|t^ox ŠRN{~~Ů?XnU4U$)@}d/LR^f7, a' 9>'N'Ϡ5I%DYa0 W f"Pʠ"CA+MΒװV 1+؍# 8ܿ[#>|BJeYh!94$m {g?N~?Mf㠹vAM"e@XnhzkEs?vR04>M[lHr( @_:Wo| /@d{s>jHD2H'=t+Y;]r`wَĥO4ps;WϴʗALfWωO~Lm6>w˺m_/bt@ק/py[#-0:e܆M)joQq&B0Ylzĩ=B$ YAhSz{RvNt4oLl)70:rc tIENDB`kst-2.0.3/src/images/yes.png000644 001750 001750 00000000413 11544160207 016231 0ustar00synthsynth000000 000000 PNG  IHDRgAMA aPLTE@@R,tRNS@6:bKGDH oFFsL pHYs  d_tIME 2+DkJIDATxc`V( (L @3gE!*H!YQP9`1ig P 2c6a,IENDB`kst-2.0.3/src/libkstapp/filterfittab.ui000644 001750 001750 00000007017 11544160207 020474 0ustar00synthsynth000000 000000 FilterFitTab 0 0 609 310 0 0 Plugin Selection 0 0 0 Plugin name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Description: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Inputs and Outputs I&gnore in automatic axes range calculations Kst::CurvePlacement QWidget

curveplacement.h
Kst::CurveAppearance QWidget
curveappearance.h
_pluginCombo kst-2.0.3/src/libkstapp/databuttonaction.h000644 001750 001750 00000002464 11544160207 021173 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATABUTTONACTION_H #define DATABUTTONACTION_H #include namespace Kst { class Document; class DataButtonAction : public QWidgetAction { Q_OBJECT public: explicit DataButtonAction(const QString &text, QWidget *parent = 0); Q_SIGNALS: void triggered(QString &name); public Q_SLOTS: void triggerWithName(); protected: QWidget* createWidget(QWidget* parent = 0); private: QString m_text; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewcommand.h000644 001750 001750 00000002465 11544160207 020142 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEWCOMMAND_H #define VIEWCOMMAND_H #include #include #include "kst_export.h" namespace Kst { class View; class ViewCommand : public QUndoCommand { public: explicit ViewCommand(const QString &text, bool addToStack = true, QUndoCommand *parent = 0); ViewCommand(View *view, const QString &text, bool addToStack = true, QUndoCommand *parent = 0); virtual ~ViewCommand(); protected: QPointer _view; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/arrowitemdialog.cpp000644 001750 001750 00000004317 11544160207 021353 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "arrowitemdialog.h" #include "arrowitem.h" #include "arrowpropertiestab.h" #include "dialogpage.h" #include "application.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" namespace Kst { ArrowItemDialog::ArrowItemDialog(ArrowItem *item, QWidget *parent) : ViewItemDialog(item, parent), _arrowItem(item) { _propertiesTab = new ArrowPropertiesTab(this); DialogPage *propertiesPage = new DialogPage(this); propertiesPage->setPageTitle(tr("Properties")); propertiesPage->addDialogTab(_propertiesTab); addDialogPage(propertiesPage); selectDialogPage(propertiesPage); connect(_propertiesTab, SIGNAL(apply()), this, SLOT(propertiesChanged())); setupProperties(); } ArrowItemDialog::~ArrowItemDialog() { } void ArrowItemDialog::setupProperties() { _propertiesTab->setStartArrowHead(_arrowItem->startArrowHead()); _propertiesTab->setEndArrowHead(_arrowItem->endArrowHead()); _propertiesTab->setStartArrowScale(_arrowItem->startArrowScale()); _propertiesTab->setEndArrowScale(_arrowItem->endArrowScale()); } void ArrowItemDialog::propertiesChanged() { _arrowItem->setStartArrowHead(_propertiesTab->startArrowHead()); _arrowItem->setEndArrowHead(_propertiesTab->endArrowHead()); _arrowItem->setStartArrowScale(_propertiesTab->startArrowScale()); _arrowItem->setEndArrowScale(_propertiesTab->endArrowScale()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewprimitivedialog.ui000644 001750 001750 00000003403 11544160207 022073 0ustar00synthsynth000000 000000 ViewPrimitiveDialog 0 0 597 536 Primitive View Update Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() ViewPrimitiveDialog accept() 248 254 157 274 buttonBox rejected() ViewPrimitiveDialog reject() 316 260 286 274 kst-2.0.3/src/libkstapp/datagui.h000644 001750 001750 00000002337 11544160207 017245 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAGUI_H #define DATAGUI_H #include "datacollection.h" #include "kst_export.h" namespace Kst { class DataGui : public Data { public: DataGui(); virtual ~DataGui(); virtual void removeCurveFromPlots(Relation *c); virtual QList plotList() const; virtual int rows() const; virtual int columns() const; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/legendtab.cpp000644 001750 001750 00000020702 11544160207 020103 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "legendtab.h" #include "objectstore.h" #include namespace Kst { LegendTab::LegendTab(QWidget *parent) : DialogTab(parent) { setupUi(this); _single = true; _up->setIcon(QPixmap(":kst_uparrow.png")); _down->setIcon(QPixmap(":kst_downarrow.png")); _add->setIcon(QPixmap(":kst_rightarrow.png")); _remove->setIcon(QPixmap(":kst_leftarrow.png")); _up->setToolTip(i18n("Raise in list order: Alt+Up")); _down->setToolTip(i18n("Lower in list order: Alt+Down")); _add->setToolTip(i18n("Select: Alt+s")); _remove->setToolTip(i18n("Remove: Alt+r")); connect(_add, SIGNAL(clicked()), this, SLOT(addButtonClicked())); connect(_remove, SIGNAL(clicked()), this, SLOT(removeButtonClicked())); connect(_up, SIGNAL(clicked()), this, SLOT(upButtonClicked())); connect(_down, SIGNAL(clicked()), this, SLOT(downButtonClicked())); connect(_add, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_remove, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_up, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_down, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_availableRelationList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_displayedRelationList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_availableRelationList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(addButtonClicked())); connect(_displayedRelationList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(removeButtonClicked())); connect(_autoContents, SIGNAL(stateChanged(int)), this, SLOT(updateActive())); connect(_autoContents, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_displayVertically, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_title, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_fontSize, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_bold, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_underline, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_italic, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_family, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); _displayedRelationList->setSortingEnabled(false); _availableRelationList->setSortingEnabled(false); } LegendTab::~LegendTab() { } void LegendTab::updateActive() { _contentGroupBox->setEnabled((!_autoContents->isChecked()) && _single); } void LegendTab::updateButtons() { QList displayedItems = _displayedRelationList->selectedItems(); QListWidgetItem *displayedItem = 0; if (displayedItems.count() > 0) displayedItem = displayedItems.first(); _remove->setEnabled(displayedItems.count() > 0); _up->setEnabled(_displayedRelationList->row(displayedItem) > 0); _down->setEnabled(_displayedRelationList->row(displayedItem) >= 0 && _displayedRelationList->row(displayedItem) < (int)_displayedRelationList->count() - 1); _add->setEnabled(_availableRelationList->selectedItems().count() > 0); } void LegendTab::removeButtonClicked() { for (int i = 0; i < _displayedRelationList->count(); i++) { if (_displayedRelationList->item(i) && _displayedRelationList->item(i)->isSelected()) { _availableRelationList->addItem(_displayedRelationList->takeItem(i)); _availableRelationList->clearSelection(); _availableRelationList->item(_availableRelationList->count() - 1)->setSelected(true); } } updateButtons(); } void LegendTab::addButtonClicked() { for (int i = 0; i < _availableRelationList->count(); i++) { if (_availableRelationList->item(i) && _availableRelationList->item(i)->isSelected()) { _displayedRelationList->addItem(_availableRelationList->takeItem(i)); _displayedRelationList->clearSelection(); _displayedRelationList->item(_displayedRelationList->count() - 1)->setSelected(true); } } updateButtons(); } void LegendTab::upButtonClicked() { //_displayedRelationList->setFocus(); for (int i=1; i<_displayedRelationList->count(); i++) { if (_displayedRelationList->item(i) && _displayedRelationList->item(i)->isSelected()) { QListWidgetItem *item = _displayedRelationList->takeItem(i); _displayedRelationList->insertItem(i-1, item); item->setSelected(true); } } updateButtons(); } void LegendTab::downButtonClicked() { for (int i=_displayedRelationList->count()-2; i>=0; --i) { if (_displayedRelationList->item(i) && _displayedRelationList->item(i)->isSelected()) { QListWidgetItem *item = _displayedRelationList->takeItem(i); _displayedRelationList->insertItem(i+1, item); item->setSelected(true); } } updateButtons(); } void LegendTab::setDisplayedRelations(const QStringList& displayedRelations, const QStringList& displayedRelationTips) { _displayedRelationList->clear(); _displayedRelationList->addItems(displayedRelations); for (int i=0; i<_displayedRelationList->count(); i++) { _displayedRelationList->item(i)->setToolTip(displayedRelationTips.at(i)); } } void LegendTab::setAvailableRelations(const QStringList& availableRelations, const QStringList& availableRelationTips) { _availableRelationList->clear(); _availableRelationList->addItems(availableRelations); for (int i=0; i<_availableRelationList->count(); i++) { _availableRelationList->item(i)->setToolTip(availableRelationTips.at(i)); } } QStringList LegendTab::displayedRelations() { QStringList relations; for (int i = 0; i < _displayedRelationList->count(); i++) { relations.append(_displayedRelationList->item(i)->text()); } return relations; } QFont LegendTab::font(QFont ref_font) const { QString family = (_family->currentIndex() == -1) ? ref_font.family() : _family->currentFont().family(); QFont font(family); font.setItalic(_italic->isChecked()); font.setBold(_bold->isChecked()); font.setUnderline(_underline->isChecked()); return font; } //FIXME: handle tristate bool/italics, etc. bool LegendTab::fontDirty() const { return true; } void LegendTab::setFont(const QFont &font) { _family->setCurrentFont(font); _bold->setChecked(font.bold()); _underline->setChecked(font.underline()); _italic->setChecked(font.italic()); } qreal LegendTab::fontScale() const { return _fontSize->value(); } void LegendTab::setFontScale(const qreal scale) { _fontSize->setValue(scale); } bool LegendTab::fontScaleDirty() const { return _fontSize->text().isEmpty(); } bool LegendTab::autoContents() const { return _autoContents->isChecked(); } void LegendTab::setAutoContents(const bool autoContents) { _autoContents->setChecked(autoContents); } bool LegendTab::autoContentsDirty() const { return _autoContents->checkState() != Qt::PartiallyChecked; } bool LegendTab::verticalDisplay() const { return _displayVertically->isChecked(); } void LegendTab::setVerticalDisplay(const bool vertical) { _displayVertically->setChecked(vertical); } bool LegendTab::verticalDisplayDirty() const { return _displayVertically->checkState() != Qt::PartiallyChecked; } QString LegendTab::title() const { return _title->text(); } void LegendTab::setTitle(const QString& title) { _title->setText(title); } bool LegendTab::titleDirty() const { return _title->text().isEmpty(); } void LegendTab::clearTabValues() { _autoContents->setCheckState(Qt::PartiallyChecked); _fontSize->clear(); _family->setCurrentIndex(-1); _displayVertically->setCheckState(Qt::PartiallyChecked); } void LegendTab::setSingle(bool single) { _single = single; updateActive(); if (single) { _autoContents->setTristate(false); _displayVertically->setTristate(false); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datamanager.cpp000644 001750 001750 00000037661 11544160207 020436 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datamanager.h" #include "databuttonaction.h" #include "databutton.h" #include "dialoglauncher.h" #include "document.h" #include "sessionmodel.h" #include "datacollection.h" #include "plotitem.h" #include "objectstore.h" #include "dataobject.h" #include "curve.h" #include "equation.h" #include "vector.h" #include "matrix.h" #include "histogram.h" #include "psd.h" #include "eventmonitorentry.h" #include "image.h" #include "csd.h" #include "basicplugin.h" #include #include #include #include namespace Kst { DataManager::DataManager(QWidget *parent, Document *doc) : QDialog(parent), _doc(doc), _currentObject(0) { setupUi(this); MainWindow::setWidgetFlags(this); _session->header()->setResizeMode(QHeaderView::ResizeToContents); _session->setModel(doc->session()); _session->setContextMenuPolicy(Qt::CustomContextMenu); _session->setUniformRowHeights(true); connect(_session, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showContextMenu(const QPoint &))); connect(_session, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(showEditDialog(QModelIndex))); // Simple keyboard shortcut for fast object deletion _deleteShortcut = new QShortcut(Qt::Key_Delete, this); connect(_deleteShortcut, SIGNAL(activated()), this, SLOT(deleteObject())); _contextMenu = new QMenu(this); connect(_purge, SIGNAL(clicked()), this, SLOT(purge())); } DataManager::~DataManager() { // the data manager is only destroyed at exit, so there is no real // need to clean up anything... (though valgrind thinks we really // ought to delete all of our actions before we exit) } void DataManager::showEvent(QShowEvent*) { _session->header()->setResizeMode(QHeaderView::ResizeToContents); _session->header()->setStretchLastSection(false); QApplication::processEvents(); _session->header()->setResizeMode(QHeaderView::Interactive); } void DataManager::showContextMenu(const QPoint &position) { QList actions; if (_session->indexAt(position).isValid()) { SessionModel *model = static_cast(_session->model()); if (!model->parent(_session->indexAt(position)).isValid()) { _currentObject = model->objectList()->at(_session->indexAt(position).row()); if (_currentObject) { QAction *action = new QAction(_currentObject->Name(), this); action->setEnabled(false); actions.append(action); action = new QAction(tr("Edit"), this); connect(action, SIGNAL(triggered()), this, SLOT(showEditDialog())); actions.append(action); if (VectorPtr v = kst_cast(_currentObject)) { action = new QAction(tr("Make Curve"), this); connect(action, SIGNAL(triggered()), this, SLOT(showCurveDialog())); actions.append(action); action = new QAction(tr("Make Power Spectrum"), this); connect(action, SIGNAL(triggered()), this, SLOT(showPowerSpectrumDialog())); actions.append(action); action = new QAction(tr("Make Spectrogram"), this); connect(action, SIGNAL(triggered()), this, SLOT(showCSDDialog())); actions.append(action); action = new QAction(tr("Make Histogram"), this); connect(action, SIGNAL(triggered()), this, SLOT(showHistogramDialog())); actions.append(action); if (!DataObject::filterPluginList().empty()) { action = new QAction(tr("Apply Filter"), this); connect(action, SIGNAL(triggered()), this, SLOT(showFilterDialog())); actions.append(action); } } else if (MatrixPtr m = kst_cast(_currentObject)) { action = new QAction(tr("Make Image"), this); connect(action, SIGNAL(triggered()), this, SLOT(showImageDialog())); actions.append(action); } else if (RelationPtr r = kst_cast(_currentObject)) { QMenu *addMenu = new QMenu(this); QMenu *removeMenu = new QMenu(this); foreach (PlotItemInterface *plot, Data::self()->plotList()) { action = new QAction(plot->plotName(), this); action->setData(qVariantFromValue(plot)); addMenu->addAction(action); PlotItem* plotItem = static_cast(plot); if (plotItem) { foreach (PlotRenderItem* renderItem, plotItem->renderItems()) { if (renderItem->relationList().contains(r)) { action = new QAction(plot->plotName(), this); action->setData(qVariantFromValue(plot)); removeMenu->addAction(action); break; } } } } connect(addMenu, SIGNAL(triggered(QAction*)), this, SLOT(addToPlot(QAction*))); action = new QAction(tr("Add to Plot"), this); action->setMenu(addMenu); actions.append(action); connect(removeMenu, SIGNAL(triggered(QAction*)), this, SLOT(removeFromPlot(QAction*))); action = new QAction(tr("Remove From Plot"), this); connect(action, SIGNAL(triggered()), this, SLOT(showImageDialog())); action->setMenu(removeMenu); actions.append(action); if (!DataObject::fitsPluginList().empty()) { action = new QAction(tr("Apply Fit"), this); connect(action, SIGNAL(triggered()), this, SLOT(showFitDialog())); actions.append(action); } if (!DataObject::filterPluginList().empty()) { action = new QAction(tr("Apply Filter"), this); connect(action, SIGNAL(triggered()), this, SLOT(showFilterDialog())); actions.append(action); } } // Also add delete action in the menu action = new QAction(tr("Delete"), this); connect(action, SIGNAL(triggered()), this, SLOT(deleteObject())); actions.append(action); } } else { DataObjectPtr dataObject = kst_cast(model->objectList()->at(_session->indexAt(position).parent().row())); if (dataObject) { if (dataObject->outputVectors().count() > _session->indexAt(position).row()) { _currentObject = dataObject->outputVectors().values()[_session->indexAt(position).row()]; } else { _currentObject = dataObject->outputMatrices().values()[_session->indexAt(position).row() - dataObject->outputVectors().count()]; } if (_currentObject) { QAction *action = new QAction(_currentObject->Name(), this); action->setEnabled(false); actions.append(action); if (VectorPtr v = kst_cast(_currentObject)) { action = new QAction(tr("Make Curve"), this); connect(action, SIGNAL(triggered()), this, SLOT(showCurveDialog())); actions.append(action); action = new QAction(tr("Make Power Spectrum"), this); connect(action, SIGNAL(triggered()), this, SLOT(showPowerSpectrumDialog())); actions.append(action); action = new QAction(tr("Make Spectrogram"), this); connect(action, SIGNAL(triggered()), this, SLOT(showCSDDialog())); actions.append(action); action = new QAction(tr("Make Histogram"), this); connect(action, SIGNAL(triggered()), this, SLOT(showHistogramDialog())); actions.append(action); if (!DataObject::filterPluginList().empty()) { action = new QAction(tr("Apply Filter"), this); connect(action, SIGNAL(triggered()), this, SLOT(showFilterDialog())); actions.append(action); } } else if (MatrixPtr m = kst_cast(_currentObject)) { action = new QAction(tr("Make Image"), this); connect(action, SIGNAL(triggered()), this, SLOT(showImageDialog())); actions.append(action); } } } } } if (actions.count() > 0) QMenu::exec(actions, _session->mapToGlobal(position)); } void DataManager::showEditDialog(QModelIndex qml) { if (!qml.parent().isValid()) { // don't edit slave objects SessionModel *model = static_cast(_session->model()); _currentObject = model->objectList()->at(qml.row()); showEditDialog(); } } void DataManager::showEditDialog() { DialogLauncher::self()->showObjectDialog(_currentObject); } bool DataManager::event(QEvent * event) { if ((event->type() == QEvent::WindowActivate) || (event->type() == QEvent::Show)) { _doc->session()->triggerReset(); } return QDialog::event(event); } void DataManager::showVectorDialog() { QString tmp; DialogLauncher::self()->showVectorDialog(tmp); } void DataManager::showMatrixDialog() { QString tmp; DialogLauncher::self()->showMatrixDialog(tmp); } void DataManager::showScalarDialog() { QString scalarName; DialogLauncher::self()->showScalarDialog(scalarName); } void DataManager::showStringDialog() { QString stringName; DialogLauncher::self()->showStringDialog(stringName); } void DataManager::showEventMonitorDialog() { DialogLauncher::self()->showEventMonitorDialog(); } void DataManager::showEquationDialog() { DialogLauncher::self()->showEquationDialog(); } void DataManager::showCurveDialog() { if (VectorPtr vector = kst_cast(_currentObject)) { DialogLauncher::self()->showCurveDialog(0, vector); } else { DialogLauncher::self()->showCurveDialog(); } } void DataManager::showCSDDialog() { if (VectorPtr vector = kst_cast(_currentObject)) { DialogLauncher::self()->showCSDDialog(0, vector); } else { DialogLauncher::self()->showCSDDialog(); } } void DataManager::showPowerSpectrumDialog() { if (VectorPtr vector = kst_cast(_currentObject)) { DialogLauncher::self()->showPowerSpectrumDialog(0, vector); } else { DialogLauncher::self()->showPowerSpectrumDialog(); } } void DataManager::showHistogramDialog() { if (VectorPtr vector = kst_cast(_currentObject)) { DialogLauncher::self()->showHistogramDialog(0, vector); } else { DialogLauncher::self()->showHistogramDialog(); } } void DataManager::showImageDialog() { if (MatrixPtr matrix = kst_cast(_currentObject)) { DialogLauncher::self()->showImageDialog(0, matrix); } else { DialogLauncher::self()->showImageDialog(); } } void DataManager::showPluginDialog(QString &pluginName) { if (VectorPtr vector = kst_cast(_currentObject)) { DialogLauncher::self()->showBasicPluginDialog(pluginName, 0, vector); } else if (CurvePtr curve = kst_cast(_currentObject)) { DialogLauncher::self()->showBasicPluginDialog(pluginName, 0, curve->xVector(), curve->yVector()); } else { DialogLauncher::self()->showBasicPluginDialog(pluginName); } } void DataManager::showFilterDialog() { showPluginDialog(DataObject::filterPluginList().first()); } void DataManager::showFitDialog() { showPluginDialog(DataObject::fitsPluginList().first()); } void DataManager::deleteObject() { SessionModel *model = static_cast(_session->model()); int row = _session->selectionModel()->selectedIndexes()[0].row(); // Single selection mode => only one selected index _currentObject = model->objectList()->at(row); if (RelationPtr relation = kst_cast(_currentObject)) { Data::self()->removeCurveFromPlots(relation); _doc->objectStore()->removeObject(relation); } else if (DataObjectPtr dataObject = kst_cast(_currentObject)) { _doc->objectStore()->removeObject(dataObject); } else if (PrimitivePtr primitive = kst_cast(_currentObject)) { _doc->objectStore()->removeObject(primitive); } _currentObject = 0; _doc->session()->triggerReset(); // Now select the next item _session->selectionModel()->select(model->index(row,0), QItemSelectionModel::Select); // Cleanup and return _doc->objectStore()->cleanUpDataSourceList(); } void DataManager::addToPlot(QAction* action) { PlotItem* plotItem = static_cast(qVariantValue(action->data())); RelationPtr relation = kst_cast(_currentObject); if (plotItem && relation) { PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(relation)); plotItem->update(); } } void DataManager::removeFromPlot(QAction* action) { bool plotUpdated = false; PlotItem* plotItem = static_cast(qVariantValue(action->data())); RelationPtr relation = kst_cast(_currentObject); if (plotItem && relation) { foreach (PlotRenderItem* renderItem, plotItem->renderItems()) { if (renderItem->relationList().contains(relation)) { renderItem->removeRelation(relation); plotUpdated = true; } } if (plotUpdated) { plotItem->update(); } } } void DataManager::setUsedFlags() { _doc->objectStore()->clearUsedFlags(); // for each relation used in an unhidden plot mark 'used' - O(N) QList plotlist = ViewItem::getItems(); foreach (PlotItem *plot, plotlist) { if (plot->isVisible()) { foreach (PlotRenderItem *renderer, plot->renderItems()) { foreach (RelationPtr relation, renderer->relationList()) { relation->setUsed(true); } } } } // TODO: for each primitive used in an unhidden label mark 'used' - O(N) // for each primitive used by a relation mark 'used' - O(N) ObjectList relationList = _doc->objectStore()->getObjects(); foreach (RelationPtr object, relationList) { object->readLock(); //set used all input and output primitives foreach (VectorPtr v, object->inputVectors()) { v->setUsed(true); if (v->provider()) { v->provider()->setUsed(true); } } foreach (VectorPtr v, object->outputVectors()) { v->setUsed(true); } foreach (ScalarPtr s, object->inputScalars()) { s->setUsed(true); if (s->provider()) { s->provider()->setUsed(true); } } foreach (ScalarPtr s, object->outputScalars()) { s->setUsed(true); } foreach (StringPtr s, object->inputStrings()) { s->setUsed(true); if (s->provider()) { s->provider()->setUsed(true); } } foreach (StringPtr s, object->outputStrings()) { s->setUsed(true); } foreach (MatrixPtr m, object->inputMatrices()) { m->setUsed(true); if (m->provider()) { m->provider()->setUsed(true); } } foreach (MatrixPtr m, object->outputMatrices()) { m->setUsed(true); } object->unlock(); } ObjectList dataObjectList = _doc->objectStore()->getObjects(); foreach (DataObjectPtr object, dataObjectList) { object->readLock(); //set used all input and output primitives foreach (PrimitivePtr p, object->inputPrimitives()) { p->setUsed(true); } foreach (PrimitivePtr p, object->outputPrimitives()) { p->setUsed(true); } object->unlock(); } } void DataManager::purge() { do { setUsedFlags(); } while (_doc->objectStore()->deleteUnsetUsedFlags()); _doc->session()->triggerReset(); _session->reset(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/markerstab.h000644 001750 001750 00000004560 11544160207 017762 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MARKERSTAB_H #define MARKERSTAB_H #include "dialogtab.h" #include "plotitem.h" #include "ui_markerstab.h" #include "kst_export.h" namespace Kst { class MarkersTab : public DialogTab, Ui::MarkersTab { Q_OBJECT public: MarkersTab(QWidget *parent = 0); virtual ~MarkersTab(); void setObjectStore(ObjectStore *store); QList markers() const; void setMarkers(const QList &markers); Qt::PenStyle lineStyle() const; void setLineStyle(Qt::PenStyle style); QColor lineColor() const; void setLineColor(const QColor &color); double lineWidth() const; void setLineWidth(const double width); bool isCurveSource() const; void setCurveSource(const bool enabled); bool isVectorSource() const; void setVectorSource(const bool enabled); VectorPtr vector() const; void setVector(VectorPtr vector); void setVector(const QString &vector); CurvePtr curve() const; void setCurve(CurvePtr curve); PlotMarkers::CurveMarkerMode curveMarkerMode() const; void setCurveMarkerMode(const PlotMarkers::CurveMarkerMode mode); PlotMarkers plotMarkers() const; void setPlotMarkers(const PlotMarkers &plotMarkers); bool markersDirty() const { return _dirty; } void enableSingleEditOptions(bool enabled); void clearTabValues(); public Q_SLOTS: void add(); void remove(); void clear(); void update(); void setDirty() { _dirty = true; } private: PlotMarkers _plotMarkers; bool _dirty; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/layoutboxitem.h000644 001750 001750 00000003420 11544160207 020526 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LAYOUTBOXITEM_H #define LAYOUTBOXITEM_H #include "viewitem.h" #include "graphicsfactory.h" namespace Kst { class LayoutBoxItem : public ViewItem { Q_OBJECT public: LayoutBoxItem(View *parent); virtual ~LayoutBoxItem(); void appendItem(ViewItem *item); bool appendItemFromXml(QXmlStreamReader &xml); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); public Q_SLOTS: void setEnabled(bool enabled); protected: virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); }; class LayoutBoxItemFactory : public GraphicsFactory { public: LayoutBoxItemFactory(); ~LayoutBoxItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/stringmodel.cpp000644 001750 001750 00000003225 11544160207 020506 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "stringmodel.h" #include #include #include #include #include #include #include #include #include namespace Kst { void StringModel::addDataSourcesMetas(DataSourcePtr dataSource, PrimitiveTreeItem* parent) { QStringList strings = dataSource->string().list(); if (strings.isEmpty()) { return; } PrimitiveTreeItem* item = addPrimitiveTreeItem(QList() << dataSource->descriptiveName(), parent); strings.sort(); foreach(const QString& str, strings) { QString value; DataString::ReadInfo readInfo(&value); dataSource->string().read(str, readInfo); new PrimitiveTreeItem(QList() << str << value, item); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/curvetab.ui000644 001750 001750 00000017426 11544160207 017635 0ustar00synthsynth000000 000000 CurveTab 0 0 538 265 Curve Contents 0 0 0 0 0 &X-axis vector: false 0 0 0 0 &Y-axis vector: false 0 0 0 0 +X e&rror bar: false 0 0 &+Y error bar: false 0 0 -X error bar: false 0 0 &-Y error bar: false &Use +X error bar for -X U&se +Y error bar for -Y Qt::Vertical QSizePolicy::Fixed 71 31 I&gnore in automatic axes range calculations Qt::Vertical 20 87 Kst::VectorSelector QWidget
vectorselector.h
Kst::CurvePlacement QWidget
curveplacement.h
Kst::CurveAppearance QWidget
curveappearance.h
_xVector _yVector _xError _yError _xMinusError _yMinusError _xMinusSameAsPlus _yMinusSameAsPlus _ignoreAutoScale _curveAppearance _curvePlacement
kst-2.0.3/src/libkstapp/choosecolordialog.ui000644 001750 001750 00000004610 11544160207 021510 0ustar00synthsynth000000 000000 ChooseColorDialog 0 0 425 162 Assign Curve Color From File Assign Colors 0 QFrame::NoFrame QFrame::Plain 0 Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok Base Curve Color on: 0 &X vector true &Y vector _xVector _yVector kst-2.0.3/src/libkstapp/choosecolordialog.h000644 001750 001750 00000003316 11544160207 021324 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CHOOSECOLORDIALOG_H #define CHOOSECOLORDIALOG_H #include #include #include "colorbutton.h" #include "dataprimitive.h" #include "ui_choosecolordialog.h" #include "kst_export.h" namespace Kst { class ObjectStore; class ChooseColorDialog : public QDialog, Ui::ChooseColorDialog { Q_OBJECT public: ChooseColorDialog(QWidget *parent); virtual ~ChooseColorDialog(); void show(); private slots: void OKClicked(); void apply(); private: QColor getColorForFile(const QString &fileName); QGridLayout* _grid; void updateColorGroup(); void cleanColorGroup(); QList _lineEdits; QList _colorButtons; ObjectStore *_store; // Use a QMap to store the list of used datasources and their color QMap _dataSourceColors; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/filterfitdialog.h000644 001750 001750 00000004774 11544160207 021006 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTERFITDIALOG_H #define FILTERFITDIALOG_H #include "datadialog.h" #include "datatab.h" #include "dataobjectplugin.h" #include "plotitem.h" #include "kst_export.h" #include "ui_filterfittab.h" namespace Kst { class FilterFitTab : public DataTab, Ui::FilterFitTab { Q_OBJECT public: explicit FilterFitTab(QString& pluginName, QWidget *parent = 0); virtual ~FilterFitTab(); void setObjectStore(ObjectStore *store); void setVectorX(VectorPtr vector); void setVectorY(VectorPtr vector); CurveAppearance* curveAppearance() const; CurvePlacement* curvePlacement() const; DataObjectConfigWidget* configWidget() { return _configWidget; } void loadSettings(); void saveSettings(); void setPlotMode(PlotItem* plot); void lockVectors(); QString pluginName(); public Q_SLOTS: void pluginChanged(const QString&); private: DataObjectConfigWidget* _configWidget; QGridLayout* _layout; DataObjectPluginInterface::PluginTypeID _type; ObjectStore *_store; VectorPtr _vectorX, _vectorY; bool _lockVectors; }; class FilterFitDialog : public DataDialog { Q_OBJECT public: FilterFitDialog(QString& pluginName, ObjectPtr dataObject, QWidget *parent = 0); virtual ~FilterFitDialog(); void setVectorX(VectorPtr vector); void setVectorY(VectorPtr vector); void setPlotMode(PlotItem* plot); protected: virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private: void configureTab(); FilterFitTab *_filterFitTab; VectorPtr _vectorX; VectorPtr _vectorY; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/axis.h000644 001750 001750 00000002576 11544160207 016600 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef AXIS_H #define AXIS_H #include namespace Kst { // A representation of a plot axis. This has nothing to do with the way the // axis is drawn - only the properties of it. class Axis { public: Axis(); ~Axis(); bool reversed; bool isLog; qreal logBase; }; // A representation of a style used to render an axis. class AxisStyle { public: AxisStyle(); ~AxisStyle(); bool showMinorTicks; bool showMajorTicks; qreal minorTickWidth; qreal majorTickWidth; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/changedatasampledialog.ui000644 001750 001750 00000011750 11544160207 022455 0ustar00synthsynth000000 000000 ChangeDataSampleDialog 0 0 590 419 Change Data Samples Vector Selection 1 0 The source file for the vectors selected in this list will be changed. QAbstractItemView::ExtendedSelection Qt::Vertical 20 40 Select all vectors in the list. Add A&ll Select all vectors in the list. &Add Unselect all vectors in the list. &Remove Unselect all vectors in the list. R&emove All Qt::Vertical QSizePolicy::Expanding 80 51 1 0 The source file for the vectors selected in this list will be changed. QAbstractItemView::ExtendedSelection Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok Kst::DataRange QWidget
datarange.h
_dataRange
kst-2.0.3/src/libkstapp/datasourcedialog.cpp000644 001750 001750 00000004471 11544160207 021475 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasourcedialog.h" #include #include #include namespace Kst { DataSourceDialog::DataSourceDialog(DataDialog::EditMode mode, DataSourcePtr dataSource, QWidget *parent) : QDialog(parent), _dataSource(dataSource) { setWindowTitle(QString("Configure %1").arg(_dataSource->fileType())); QVBoxLayout *layout = new QVBoxLayout(this); _dataSource->readLock(); QWidget *widget = _dataSource->configWidget(); connect(this, SIGNAL(ok()), widget, SLOT(save())); if (mode == DataDialog::Edit) { connect(this, SIGNAL(ok()), this, SLOT(disableReuse())); } _dataSource->unlock(); widget->setParent(this); layout->addWidget(widget); _buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); layout->addWidget(_buttonBox); connect(_buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *))); setLayout(layout); setMaximumSize(QSize(1024, 768)); resize(minimumSizeHint()); } DataSourceDialog::~DataSourceDialog() { } void DataSourceDialog::disableReuse() { _dataSource->disableReuse(); } void DataSourceDialog::buttonClicked(QAbstractButton *button) { QDialogButtonBox::StandardButton std = _buttonBox->standardButton(button); switch(std) { case QDialogButtonBox::Ok: emit ok(); accept(); break; case QDialogButtonBox::Cancel: emit cancel(); reject(); break; default: break; } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/applicationsettings.cpp000644 001750 001750 00000021744 11544160207 022251 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "applicationsettings.h" #include "updatemanager.h" #include "defaultlabelpropertiestab.h" #include #include #include #include #ifdef Q_WS_X11 #include #endif namespace Kst { static ApplicationSettings *settings_self = 0; void ApplicationSettings::cleanup() { delete settings_self; settings_self = 0; } ApplicationSettings *ApplicationSettings::self() { if (!settings_self) { settings_self = new ApplicationSettings; qAddPostRoutine(cleanup); } return settings_self; } ApplicationSettings::ApplicationSettings() { _settings = new QSettings("kst", "application"); //FIXME Not sure if this is the best test for hardware acceleration // but right now opening with QGV with QGLWidget as viewport takes // several seconds delay when opening application on my system. _useOpenGL = _settings->value("general/opengl", false).toBool(); //QVariant(QGLPixelBuffer::hasOpenGLPbuffers())).toBool(); _maxUpdate = _settings->value("general/minimumupdateperiod", QVariant(200)).toInt(); _showGrid = _settings->value("grid/showgrid", QVariant(false)).toBool(); _snapToGrid = _settings->value("grid/snaptogrid", QVariant(false)).toBool(); _gridHorSpacing = _settings->value("grid/horizontalspacing", 20.0).toDouble(); _gridVerSpacing = _settings->value("grid/verticalspacing", 20.0).toDouble(); Qt::BrushStyle style = (Qt::BrushStyle)_settings->value("fill/style", "0").toInt(); if (style < Qt::LinearGradientPattern) { _backgroundBrush.setColor(QColor(_settings->value("fill/color", "white").toString())); _backgroundBrush.setStyle(style); } QString stopList = _settings->value("fill/gradient", QString()).toString(); if (!stopList.isEmpty()) { QStringList stopInfo = stopList.split(',', QString::SkipEmptyParts); QLinearGradient gradient(0.0, 0.0, 0.0, 1.0); for (int i = 0; i < stopInfo.size(); i+=2) { gradient.setColorAt(stopInfo.at(i).toDouble(), QColor(stopInfo.at(i+1))); } _gradientStops = gradient.stops(); _backgroundBrush = QBrush(gradient); } QString fontString = _settings->value("fonts/defaultfont", QFont()).toString(); _defaultFont.fromString(fontString); _defaultFontScale = _settings->value("fonts/defaultfontscale", QVariant(13)).toDouble(); _defaultFontColor = QColor(_settings->value("fonts/defaultfontcolor", "black").toString()); _refViewWidth = _settings->value("fonts/referenceviewwidth", QVariant(A4Width)).toDouble(); _refViewHeight = _settings->value("fonts/referenceviewheight", QVariant(A4Height)).toDouble(); _minFontSize = _settings->value("fonts/minimumfontsize", QVariant(4.0)).toDouble(); _shareAxis = _settings->value("childviewoptions/shareaxis", QVariant(true)).toBool(); _layoutMargins.setHeight(_settings->value("layout/marginheight", QVariant(3.0)).toDouble()); _layoutMargins.setWidth(_settings->value("layout/marginwidth", QVariant(3.0)).toDouble()); _layoutSpacing.setHeight(_settings->value("layout/spacingheight", QVariant(0.0)).toDouble()); _layoutSpacing.setWidth(_settings->value("layout/spacingwidth", QVariant(0.0)).toDouble()); } ApplicationSettings::~ApplicationSettings() { delete _settings; } bool ApplicationSettings::useOpenGL() const { return _useOpenGL; } void ApplicationSettings::setUseOpenGL(bool useOpenGL) { _useOpenGL = useOpenGL; _settings->setValue("general/opengl", useOpenGL); emit modified(); } int ApplicationSettings::referenceViewWidth() const { double dpiScale = 72.0; #ifdef Q_WS_X11 dpiScale = QX11Info::appDpiX(); #endif return int(_refViewWidth * dpiScale * 0.3937008); } double ApplicationSettings::referenceViewWidthCM() const { return _refViewWidth; } void ApplicationSettings::setReferenceViewWidthCM(const double width) { _refViewWidth = width; _settings->setValue("general/referenceviewwidth", width); emit modified(); } int ApplicationSettings::referenceViewHeight() const { double dpiScale = 72.0; #ifdef Q_WS_X11 dpiScale = QX11Info::appDpiY(); #endif return int(_refViewHeight * dpiScale * 0.3937008); } double ApplicationSettings::referenceViewHeightCM() const { return _refViewHeight; } void ApplicationSettings::setReferenceViewHeightCM(const double height) { _refViewHeight = height; _settings->setValue("general/referenceviewheight", height); emit modified(); } double ApplicationSettings::minimumFontSize() const { return _minFontSize; } void ApplicationSettings::setMinimumFontSize(double points) { _minFontSize = points; _settings->setValue("general/minimumfontsize", points); emit modified(); } QFont ApplicationSettings::defaultFont() const { return _defaultFont; } void ApplicationSettings::setDefaultFont(const QFont &font) { _defaultFont = font; _settings->setValue("defaultlabelproperties/defaultfont", QVariant(font).toString()); emit modified(); } qreal ApplicationSettings::defaultFontScale() const { return _defaultFontScale; } void ApplicationSettings::setDefaultFontScale(const qreal scale) { _defaultFontScale = scale; _settings->setValue("defaultlabelproperties/defaultfontscale", _defaultFontScale); emit modified(); } QColor ApplicationSettings::defaultFontColor() const { return _defaultFontColor; } void ApplicationSettings::setDefaultFontColor(const QColor &color) { _defaultFontColor = color; _settings->setValue("defaultlabelproperties/defaultfontcolor", _defaultFontColor.name()); emit modified(); } int ApplicationSettings::minimumUpdatePeriod() const { return _maxUpdate; } void ApplicationSettings::setMinimumUpdatePeriod(const int period) { _maxUpdate = period; _settings->setValue("general/minimumupdateperiod", period); UpdateManager::self()->setMinimumUpdatePeriod(period); } bool ApplicationSettings::showGrid() const { return _showGrid; } void ApplicationSettings::setShowGrid(bool showGrid) { _showGrid = showGrid; _settings->setValue("grid/showgrid", showGrid); emit modified(); } bool ApplicationSettings::snapToGrid() const { return _snapToGrid; } void ApplicationSettings::setSnapToGrid(bool snapToGrid) { _snapToGrid = snapToGrid; _settings->setValue("grid/snaptogrid", snapToGrid); emit modified(); } qreal ApplicationSettings::gridHorizontalSpacing() const { return _gridHorSpacing; } void ApplicationSettings::setGridHorizontalSpacing(qreal spacing) { _gridHorSpacing = spacing; _settings->setValue("grid/horizontalspacing", spacing); emit modified(); } qreal ApplicationSettings::gridVerticalSpacing() const { return _gridVerSpacing; } void ApplicationSettings::setGridVerticalSpacing(qreal spacing) { _gridVerSpacing = spacing; _settings->setValue("grid/verticalspacing", spacing); emit modified(); } QBrush ApplicationSettings::backgroundBrush() const { return _backgroundBrush; } void ApplicationSettings::setBackgroundBrush(const QBrush brush) { _backgroundBrush = brush; _gradientStops.clear(); _settings->setValue("fill/color", brush.color().name()); _settings->setValue("fill/style", QVariant(brush.style()).toString()); QString stopList; if (brush.gradient()) { foreach(QGradientStop stop, brush.gradient()->stops()) { qreal point = (qreal)stop.first; QColor color = (QColor)stop.second; _gradientStops.append(qMakePair(point, color)); stopList += QString::number(point); stopList += ','; stopList += color.name(); stopList += ','; } } _settings->setValue("fill/gradient", stopList); emit modified(); } QGradientStops ApplicationSettings::gradientStops() const { return _gradientStops; } QSizeF ApplicationSettings::layoutMargins() const { return _layoutMargins; } void ApplicationSettings::setLayoutMargins(QSizeF margins) { _layoutMargins = margins; _settings->setValue("layout/marginheight", margins.height()); _settings->setValue("layout/marginwidth", margins.width()); emit modified(); } QSizeF ApplicationSettings::layoutSpacing() const { return _layoutSpacing; } void ApplicationSettings::setLayoutSpacing(QSizeF spacing) { _layoutSpacing = spacing; _settings->setValue("layout/spacingheight", spacing.height()); _settings->setValue("layout/spacingwidth", spacing.width()); emit modified(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewmatrixdialog.cpp000644 001750 001750 00000003323 11544160207 021535 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "viewmatrixdialog.h" #include "document.h" #include "matrixmodel.h" #include namespace Kst { ViewMatrixDialog::ViewMatrixDialog(QWidget *parent, Document *doc) : QDialog(parent), _doc(doc) { _model = 0; setupUi(this); connect(matrixSelector, SIGNAL(selectionChanged()), this, SLOT(matrixSelected())); matrixSelector->setObjectStore(doc->objectStore()); setAttribute(Qt::WA_DeleteOnClose); } ViewMatrixDialog::~ViewMatrixDialog() { delete _model; _model = 0; } void ViewMatrixDialog::show() { matrixSelector->updateMatrices(); matrixSelected(); QDialog::show(); } void ViewMatrixDialog::matrixSelected() { if (_model) { delete _model; } MatrixPtr m = matrixSelector->selectedMatrix(); if (m) { _model = new MatrixModel(matrixSelector->selectedMatrix()); _matrices->setModel(_model); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/changedatasampledialog.h000644 001750 001750 00000003325 11544160207 022266 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CHANGEDATASAMPLEDIALOG_H #define CHANGEDATASAMPLEDIALOG_H #include #include "ui_changedatasampledialog.h" #include "kst_export.h" namespace Kst { class ObjectStore; class ChangeDataSampleDialog : public QDialog, Ui::ChangeDataSampleDialog { Q_OBJECT public: ChangeDataSampleDialog(QWidget *parent); virtual ~ChangeDataSampleDialog(); void show(); private slots: void addButtonClicked(); void removeButtonClicked(); void addAll(); void removeAll(); void availableDoubleClicked(QListWidgetItem * item); void selectedDoubleClicked(QListWidgetItem * item); void modified(); void updateButtons(); void initializeEntries(); void updateDefaults(QListWidgetItem* item); void OKClicked(); void apply(); private: void updateCurveListDialog(); ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/layouttab.ui000644 001750 001750 00000007255 11544160207 020025 0ustar00synthsynth000000 000000 LayoutTab 0 0 419 327 Form &Horizontal margin: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _horMargin 0 0 &Vertical margin: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _verMargin 0 0 Hori&zontal spacing: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _horSpacing 0 0 Ver&tical spacing: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _verSpacing 0 0 Qt::Vertical 401 121 kst-2.0.3/src/libkstapp/databuttonaction.cpp000644 001750 001750 00000002600 11544160207 021516 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "databuttonaction.h" #include "databutton.h" namespace Kst { DataButtonAction::DataButtonAction(const QString &text, QWidget *parent) : QWidgetAction(parent), m_text(text) { } QWidget * DataButtonAction::createWidget ( QWidget * parent ) { DataButton *button = new DataButton(m_text, parent); connect(button, SIGNAL(clicked()), this, SLOT(trigger())); connect(button, SIGNAL(clicked()), this, SLOT(triggerWithName())); return button; } void DataButtonAction::triggerWithName() { emit triggered(m_text); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/eventmonitortab.ui000644 001750 001750 00000035245 11544160207 021241 0ustar00synthsynth000000 000000 EventMonitorTab 0 0 458 447 9 0 0 0 E-Mail Notification 0 N&otify: false 0 0 Expression 0 Vectors: false Operators: false _equationOperator + - * / ^ PI e = < <= > >= & | ! STEP() ABS() SQRT() CBRT() SIN() COS() TAN() ASIN() ACOS() ATAN() SEC() CSC() COT() SINH() COSH() TANH() EXP() LN() LOG() Scalars: false Expression: false _equation Description: false _description KstScript 0 Execute: false ELOG 0 No&tify: false &Configure... Qt::Vertical QSizePolicy::Expanding 241 31 0 0 Kst Debug Log 0 Qt::Vertical QSizePolicy::Expanding 120 21 false &Warning false &Error false &Notice true &Log as: Kst::VectorSelector QWidget
vectorselector.h
Kst::ScalarSelector QWidget
scalarselector.h
_equationOperator _vectorSelector _scalarSelector _equation _description _debugLog _debugLogNotice _debugLogWarning _debugLogError _emailNotify _emailRecipients _ELOGNotify _ELOGConfigure _emailNotify toggled(bool) _emailRecipients setEnabled(bool) 40 258 106 256 _ELOGNotify toggled(bool) _ELOGConfigure setEnabled(bool) 40 306 133 310 _executeScript toggled(bool) _script setEnabled(bool) 39 393 139 391 _debugLog toggled(bool) _debugLogNotice setEnabled(bool) 56 195 100 193 _debugLog toggled(bool) _debugLogWarning setEnabled(bool) 63 204 208 199 _debugLog toggled(bool) _debugLogError setEnabled(bool) 54 194 251 191
kst-2.0.3/src/libkstapp/viewvectordialog.h000644 001750 001750 00000002534 11544160207 021203 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEWVECTORDIALOG_H #define VIEWVECTORDIALOG_H #include #include "ui_viewvectordialog.h" #include "kst_export.h" namespace Kst { class Document; class VectorModel; class ViewVectorDialog : public QDialog, Ui::ViewVectorDialog { Q_OBJECT public: ViewVectorDialog(QWidget *parent, Document *doc); virtual ~ViewVectorDialog(); virtual void show(); private Q_SLOTS: void vectorSelected(); private: Document *_doc; VectorModel *_model; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datamanager.h000644 001750 001750 00000004363 11544160207 020074 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAMANAGER_H #define DATAMANAGER_H #include #include #include "object.h" #include "ui_datamanager.h" #include "kst_export.h" class QToolBar; namespace Kst { class Document; class DataManager : public QDialog, Ui::DataManager { Q_OBJECT public: DataManager(QWidget *parent, Document *doc); virtual ~DataManager(); public Q_SLOTS: void showContextMenu(const QPoint &); void showEditDialog(QModelIndex qml); void showEditDialog(); void deleteObject(); void showVectorDialog(); void showMatrixDialog(); void showScalarDialog(); void showStringDialog(); void showCurveDialog(); void showCSDDialog(); void showHistogramDialog(); void showPowerSpectrumDialog(); void showImageDialog(); void showEventMonitorDialog(); void showEquationDialog(); void showPluginDialog(QString &pluginName); void showFitDialog(); void showFilterDialog(); void addToPlot(QAction* action); void removeFromPlot(QAction* action); virtual bool event(QEvent * event); void setUsedFlags(); void purge(); private: Document *_doc; QToolBar *_primitives; QToolBar *_dataObjects; QToolBar *_plugins; QToolBar *_fits; QToolBar *_filters; ObjectPtr _currentObject; QShortcut *_deleteShortcut; QMenu *_contextMenu; void showEvent(QShowEvent* event); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/commandlineparser.h000644 001750 001750 00000005051 11544160207 021326 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KSTCOMMANDLINEPARSER_H #define KSTCOMMANDLINEPARSER_H #include "document.h" #include "datavector.h" #include "plotitem.h" #include "mainwindow.h" #include #include namespace Kst { /** @author Barth Netterfield */ class CommandLineParser { public: CommandLineParser(Document *doc, MainWindow* mw); ~CommandLineParser(); bool processCommandLine(bool *ok); QString kstFileName(); QString pngFile() const {return _pngFile;} QString printFile() const {return _printFile;} //bool landscape() const {return _landscape;} private: MainWindow* _mainWindow; bool _doAve; bool _doSkip; bool _doConsecutivePlots; bool _useBargraph; bool _useLines; bool _usePoints; bool _overrideStyle; double _sampleRate; int _numFrames; int _startFrame; int _skip; QString _plotName; QString _errorField; QString _fileName; QString _xField; QString _pngFile; QString _printFile; bool _landscape; QPrinter::PaperSize _paperSize; QStringList _fileNames; QStringList _arguments; PlotItem *_plotItem; // lists of command line named plot items (and their names). QList _plotItems; DataVectorList _vectors; Document *_document; bool _setIntArg(int *arg, QString Message, bool accept_end=false); bool _setDoubleArg(double *arg, QString Message); bool _setStringArg(QString &arg, QString Message); DataVectorPtr createOrFindDataVector(QString field, DataSourcePtr ds); void createOrFindPlot(const QString name); void createCurveInPlot(VectorPtr xv, VectorPtr yv, VectorPtr ev=0); void createImageInPlot(MatrixPtr m); void addCurve(CurvePtr curve); ObjectList autoCurves(DataSourcePtr ds); }; } #endif kst-2.0.3/src/libkstapp/builtingraphics.cpp000644 001750 001750 00000003031 11544160207 021341 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "builtingraphics.h" #include "boxitem.h" #include "lineitem.h" #include "ellipseitem.h" #include "labelitem.h" #include "layoutboxitem.h" #include "pictureitem.h" #include "plotitem.h" #include "svgitem.h" #include "arrowitem.h" #include "circleitem.h" #include "sharedaxisboxitem.h" namespace Kst { namespace Builtins { void initGraphics() { new ArrowItemFactory; new BoxItemFactory; new CircleItemFactory; new EllipseItemFactory; new LabelItemFactory; new LayoutBoxItemFactory; new LineItemFactory; new PictureItemFactory; new PlotItemFactory; new SvgItemFactory; new SharedAxisBoxItemFactory; } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewvectordialog.cpp000644 001750 001750 00000003757 11544160207 021546 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "viewvectordialog.h" #include "document.h" #include "vectormodel.h" #include #include #include namespace Kst { ViewVectorDialog::ViewVectorDialog(QWidget *parent, Document *doc) : QDialog(parent), _doc(doc) { _model = 0; Q_ASSERT(_doc && _doc->objectStore()); setupUi(this); // TODO ResizeToContents is too expensive //_vectors->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); _vectors->horizontalHeader()->setResizeMode(QHeaderView::Stretch); _vectors->verticalHeader()->hide(); connect(_vectorSelector, SIGNAL(selectionChanged(const QString&)), this, SLOT(vectorSelected())); _vectorSelector->setObjectStore(doc->objectStore()); setAttribute(Qt::WA_DeleteOnClose); } ViewVectorDialog::~ViewVectorDialog() { delete _model; _model = 0; } void ViewVectorDialog::show() { vectorSelected(); QDialog::show(); } void ViewVectorDialog::vectorSelected() { if (_model) { delete _model; } VectorPtr vector = _vectorSelector->selectedVector(); if (vector) { _model = new VectorModel(vector); _vectors->setModel(_model); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/bugreportwizard.ui000644 001750 001750 00000007402 11544160207 021245 0ustar00synthsynth000000 000000 BugReportWizard 0 0 532 197 Bug Report Wizard Kst version: OS: Qt::Horizontal 238 17 To submit a bug click on the button below. This will open a web browser window on http://bugs.kde.org where you will find a form to fill in. The information displayed above will be transferred to that server. Launch Bug Report Wizard Qt::Horizontal 40 20 Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close buttonBox accepted() BugReportWizard accept() 248 254 157 274 buttonBox rejected() BugReportWizard reject() 316 260 286 274 kst-2.0.3/src/libkstapp/viewmatrixdialog.h000644 001750 001750 00000002534 11544160207 021205 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEWMATRIXDIALOG_H #define VIEWMATRIXDIALOG_H #include #include "ui_viewmatrixdialog.h" #include "kst_export.h" namespace Kst { class Document; class MatrixModel; class ViewMatrixDialog : public QDialog, Ui::ViewMatrixDialog { Q_OBJECT public: ViewMatrixDialog(QWidget *parent, Document *doc); virtual ~ViewMatrixDialog(); virtual void show(); private Q_SLOTS: void matrixSelected(); private: Document *_doc; MatrixModel *_model; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/svgitem.h000644 001750 001750 00000003457 11544160207 017311 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SVGITEM_H #define SVGITEM_H #include "viewitem.h" #include "graphicsfactory.h" class QSvgRenderer; namespace Kst { class SvgItem : public ViewItem { Q_OBJECT public: explicit SvgItem(View *parent, const QString &file = QString()); ~SvgItem(); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); void setSvgData(const QByteArray &svgData); private: QSvgRenderer *_svg; QByteArray _svgData; }; class CreateSvgCommand : public CreateCommand { public: CreateSvgCommand() : CreateCommand(QObject::tr("Create Svg")) {} CreateSvgCommand(View *view) : CreateCommand(view, QObject::tr("Create Svg")) {} ~CreateSvgCommand() {} void createItem(); }; class SvgItemFactory : public GraphicsFactory { public: SvgItemFactory(); ~SvgItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/powerspectrumdialog.cpp000644 001750 001750 00000032165 11544160207 022263 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "powerspectrumdialog.h" #include "application.h" #include "curve.h" #include "datacollection.h" #include "dialogdefaults.h" #include "dialogpage.h" #include "document.h" #include "mainwindow.h" #include "objectstore.h" #include "plotitem.h" #include "plotrenderitem.h" #include "psd.h" #include "tabwidget.h" #include "view.h" #include "editmultiplewidget.h" #include namespace Kst { PowerSpectrumTab::PowerSpectrumTab(QWidget *parent) : DataTab(parent) { setupUi(this); setTabTitle(tr("Power Spectrum")); connect(_vector, SIGNAL(selectionChanged(QString)), this, SLOT(selectionChanged())); connect(_FFTOptions, SIGNAL(modified()), this, SIGNAL(modified())); connect(_vector, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); _vectorLabel->setBuddy(_vector->_vector); } PowerSpectrumTab::~PowerSpectrumTab() { } VectorPtr PowerSpectrumTab::vector() const { return _vector->selectedVector(); } bool PowerSpectrumTab::vectorDirty() const { return _vector->selectedVectorDirty(); } void PowerSpectrumTab::setVector(const VectorPtr vector) { _vector->setSelectedVector(vector); } void PowerSpectrumTab::selectionChanged() { emit vectorChanged(); } CurveAppearance* PowerSpectrumTab::curveAppearance() const { return _curveAppearance; } CurvePlacement* PowerSpectrumTab::curvePlacement() const { return _curvePlacement; } FFTOptions* PowerSpectrumTab::FFTOptionsWidget() const { return _FFTOptions; } void PowerSpectrumTab::setObjectStore(ObjectStore *store) { _vector->setObjectStore(store); } void PowerSpectrumTab::hideCurveOptions() { _curvePlacement->setVisible(false); _curveAppearance->setVisible(false); } void PowerSpectrumTab::clearTabValues() { _vector->clearSelection(); _FFTOptions->clearValues(); } PowerSpectrumDialog::PowerSpectrumDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Power Spectrum")); else setWindowTitle(tr("New Power Spectrum")); _powerSpectrumTab = new PowerSpectrumTab(this); addDataTab(_powerSpectrumTab); if (editMode() == Edit) { configureTab(dataObject); } else { configureTab(0); } connect(_powerSpectrumTab, SIGNAL(vectorChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_powerSpectrumTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } PowerSpectrumDialog::~PowerSpectrumDialog() { } // QString PowerSpectrumDialog::tagString() const { // return DataDialog::tagString(); // } void PowerSpectrumDialog::editMultipleMode() { _powerSpectrumTab->clearTabValues(); } void PowerSpectrumDialog::editSingleMode() { configureTab(dataObject()); } void PowerSpectrumDialog::setVector(VectorPtr vector) { _powerSpectrumTab->setVector(vector); } void PowerSpectrumDialog::configureTab(ObjectPtr object) { if (!object) { _powerSpectrumTab->FFTOptionsWidget()->loadWidgetDefaults(); _powerSpectrumTab->curveAppearance()->loadWidgetDefaults(); } else if (PSDPtr psd = kst_cast(object)) { _powerSpectrumTab->setVector(psd->vector()); _powerSpectrumTab->FFTOptionsWidget()->setSampleRate(psd->frequency()); _powerSpectrumTab->FFTOptionsWidget()->setInterleavedAverage(psd->average()); _powerSpectrumTab->FFTOptionsWidget()->setFFTLength(psd->length()); _powerSpectrumTab->FFTOptionsWidget()->setApodize(psd->apodize()); _powerSpectrumTab->FFTOptionsWidget()->setRemoveMean(psd->removeMean()); _powerSpectrumTab->FFTOptionsWidget()->setVectorUnits(psd->vectorUnits()); _powerSpectrumTab->FFTOptionsWidget()->setRateUnits(psd->rateUnits()); _powerSpectrumTab->FFTOptionsWidget()->setApodizeFunction(psd->apodizeFxn()); _powerSpectrumTab->FFTOptionsWidget()->setSigma(psd->gaussianSigma()); _powerSpectrumTab->FFTOptionsWidget()->setOutput(psd->output()); _powerSpectrumTab->FFTOptionsWidget()->setInterpolateOverHoles(psd->interpolateHoles()); _powerSpectrumTab->hideCurveOptions(); if (_editMultipleWidget) { PSDList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(PSDPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } void PowerSpectrumDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_powerSpectrumTab->vector() || (editMode() == EditMultiple)); } ObjectPtr PowerSpectrumDialog::createNewDataObject() { Q_ASSERT(_document && _document->objectStore()); PSDPtr powerspectrum = _document->objectStore()->createObject(); Q_ASSERT(powerspectrum); powerspectrum->writeLock(); powerspectrum->change(_powerSpectrumTab->vector(), _powerSpectrumTab->FFTOptionsWidget()->sampleRate(), _powerSpectrumTab->FFTOptionsWidget()->interleavedAverage(), _powerSpectrumTab->FFTOptionsWidget()->FFTLength(), _powerSpectrumTab->FFTOptionsWidget()->apodize(), _powerSpectrumTab->FFTOptionsWidget()->removeMean(), _powerSpectrumTab->FFTOptionsWidget()->vectorUnits(), _powerSpectrumTab->FFTOptionsWidget()->rateUnits(), _powerSpectrumTab->FFTOptionsWidget()->apodizeFunction(), _powerSpectrumTab->FFTOptionsWidget()->sigma(), _powerSpectrumTab->FFTOptionsWidget()->output(), _powerSpectrumTab->FFTOptionsWidget()->interpolateOverHoles()); if (DataDialog::tagStringAuto()) { powerspectrum->setDescriptiveName(QString()); } else { powerspectrum->setDescriptiveName(DataDialog::tagString()); } powerspectrum->registerChange(); powerspectrum->unlock(); _powerSpectrumTab->FFTOptionsWidget()->setWidgetDefaults(); CurvePtr curve = _document->objectStore()->createObject(); Q_ASSERT(curve); curve->setXVector(powerspectrum->vX()); curve->setYVector(powerspectrum->vY()); curve->setColor(_powerSpectrumTab->curveAppearance()->color()); curve->setHeadColor(_powerSpectrumTab->curveAppearance()->headColor()); curve->setHasPoints(_powerSpectrumTab->curveAppearance()->showPoints()); curve->setHasLines(_powerSpectrumTab->curveAppearance()->showLines()); curve->setHasBars(_powerSpectrumTab->curveAppearance()->showBars()); curve->setHasHead(_powerSpectrumTab->curveAppearance()->showHead()); curve->setLineWidth(_powerSpectrumTab->curveAppearance()->lineWidth()); curve->setLineStyle(_powerSpectrumTab->curveAppearance()->lineStyle()); curve->setPointType(_powerSpectrumTab->curveAppearance()->pointType()); curve->setHeadType(_powerSpectrumTab->curveAppearance()->headType()); curve->setPointDensity(_powerSpectrumTab->curveAppearance()->pointDensity()); curve->setBarStyle(_powerSpectrumTab->curveAppearance()->barStyle()); curve->writeLock(); curve->registerChange(); curve->unlock(); _powerSpectrumTab->curveAppearance()->setWidgetDefaults(); PlotItem *plotItem = 0; switch (_powerSpectrumTab->curvePlacement()->place()) { case CurvePlacement::NoPlot: break; case CurvePlacement::ExistingPlot: { plotItem = static_cast(_powerSpectrumTab->curvePlacement()->existingPlot()); break; } case CurvePlacement::NewPlotNewTab: _document->createView(); // fall through to case NewPlot. case CurvePlacement::NewPlot: { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); if (_powerSpectrumTab->curvePlacement()->scaleFonts()) { plotItem->view()->resetPlotFontSizes(); } break; } default: break; } if (_powerSpectrumTab->curvePlacement()->place() != CurvePlacement::NoPlot) { PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(curve)); plotItem->update(); plotItem->view()->appendToLayout(_powerSpectrumTab->curvePlacement()->layout(), plotItem, _powerSpectrumTab->curvePlacement()->gridColumns()); } return ObjectPtr(powerspectrum.data()); } ObjectPtr PowerSpectrumDialog::editExistingDataObject() const { if (PSDPtr powerspectrum = kst_cast(dataObject())) { if (editMode() == EditMultiple) { const FFTOptions *options = _powerSpectrumTab->FFTOptionsWidget(); QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { PSDPtr powerspectrum = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (powerspectrum) { VectorPtr vector = _powerSpectrumTab->vectorDirty() ? _powerSpectrumTab->vector() : powerspectrum->vector(); const double frequency = options->sampleRateDirty() ? options->sampleRate() : powerspectrum->frequency(); const double sigma = options->sigmaDirty() ? options->sigma() : powerspectrum->gaussianSigma(); const bool apodize = options->apodizeDirty() ? options->apodize() : powerspectrum->apodize(); const bool removeMean = options->removeMeanDirty() ? options->removeMean() : powerspectrum->removeMean(); const bool interpolateOverHoles = options->interpolateOverHolesDirty() ? options->interpolateOverHoles() : powerspectrum->interpolateHoles(); const bool interleavedAverage = options->interleavedAverageDirty() ? options->interleavedAverage() : powerspectrum->average(); const int FFTLength = options->FFTLengthDirty() ? options->FFTLength() : powerspectrum->length(); const ApodizeFunction apodizeFunction = options->apodizeFunctionDirty() ? options->apodizeFunction() : powerspectrum->apodizeFxn(); const PSDType output = options->outputDirty() ? options->output() : powerspectrum->output(); const QString vectorUnits = options->vectorUnitsDirty() ? options->vectorUnits() : powerspectrum->vectorUnits(); const QString rateUnits = options->rateUnitsDirty() ? options->rateUnits() : powerspectrum->rateUnits(); powerspectrum->writeLock(); powerspectrum->setVector(vector); powerspectrum->setFrequency(frequency); powerspectrum->setAverage(interleavedAverage); powerspectrum->setLength(FFTLength); powerspectrum->setApodize(apodize); powerspectrum->setRemoveMean(removeMean); powerspectrum->setVectorUnits(vectorUnits); powerspectrum->setRateUnits(rateUnits); powerspectrum->setApodizeFxn(apodizeFunction); powerspectrum->setGaussianSigma(sigma); powerspectrum->setOutput(output); powerspectrum->setInterpolateHoles(interpolateOverHoles); powerspectrum->registerChange(); powerspectrum->unlock(); } } } else { powerspectrum->writeLock(); powerspectrum->setVector(_powerSpectrumTab->vector()); powerspectrum->setFrequency(_powerSpectrumTab->FFTOptionsWidget()->sampleRate()); powerspectrum->setAverage(_powerSpectrumTab->FFTOptionsWidget()->interleavedAverage()); powerspectrum->setLength(_powerSpectrumTab->FFTOptionsWidget()->FFTLength()); powerspectrum->setApodize(_powerSpectrumTab->FFTOptionsWidget()->apodize()); powerspectrum->setRemoveMean(_powerSpectrumTab->FFTOptionsWidget()->removeMean()); powerspectrum->setVectorUnits(_powerSpectrumTab->FFTOptionsWidget()->vectorUnits()); powerspectrum->setRateUnits(_powerSpectrumTab->FFTOptionsWidget()->rateUnits()); powerspectrum->setApodizeFxn(_powerSpectrumTab->FFTOptionsWidget()->apodizeFunction()); powerspectrum->setGaussianSigma(_powerSpectrumTab->FFTOptionsWidget()->sigma()); powerspectrum->setOutput(_powerSpectrumTab->FFTOptionsWidget()->output()); powerspectrum->setInterpolateHoles(_powerSpectrumTab->FFTOptionsWidget()->interpolateOverHoles()); if (DataDialog::tagStringAuto()) { powerspectrum->setDescriptiveName(QString()); } else { powerspectrum->setDescriptiveName(DataDialog::tagString()); } powerspectrum->registerChange(); powerspectrum->unlock(); _powerSpectrumTab->FFTOptionsWidget()->setWidgetDefaults(); } } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/equationdialog.h000644 001750 001750 00000005021 11544160207 020625 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EQUATIONDIALOG_H #define EQUATIONDIALOG_H #include "datadialog.h" #include "datatab.h" #include "kst_export.h" #include "ui_equationtab.h" namespace Kst { class EquationTab : public DataTab, Ui::EquationTab { Q_OBJECT public: EquationTab(QWidget *parent = 0); virtual ~EquationTab(); void setObjectStore(ObjectStore *store); VectorPtr xVector() const; bool xVectorDirty() const; void setXVector(VectorPtr vector); QString equation() const; bool equationDirty() const; void setEquation(const QString &equation); bool doInterpolation() const; bool doInterpolationDirty() const; void setDoInterpolation(bool doInterpolation); CurveAppearance *curveAppearance() const; CurvePlacement *curvePlacement() const; void hideCurveOptions(); void clearTabValues(); void setToLastX() {_xVectors->setToLastX();} public Q_SLOTS: void updateVectorCombos(); Q_SIGNALS: void optionsChanged(); private Q_SLOTS: void selectionChanged(); void equationUpdate(const QString& string); void equationOperatorUpdate(const QString& string); private: void populateFunctionList(); }; class EquationDialog : public DataDialog { Q_OBJECT public: explicit EquationDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~EquationDialog(); protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: void configureTab(ObjectPtr object); EquationTab *_equationTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/stringdialog.cpp000644 001750 001750 00000021300 11544160207 020637 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasourcedialog.h" #include "stringdialog.h" #include "enodes.h" #include "document.h" #include "objectstore.h" #include "datastring.h" #include "dialogdefaults.h" #include "datasourcepluginmanager.h" #include #include namespace Kst { StringTab::StringTab(ObjectStore *store, QWidget *parent) : DataTab(parent), _mode(DataString), _store(store), _requestID(0) { setupUi(this); setTabTitle(tr("String")); _fileNameLabel->setBuddy(_fileName->_fileEdit); connect(_generatedStringGroup, SIGNAL(clicked(bool)), this, SLOT(generateClicked())); connect(_dataStringGroup, SIGNAL(clicked(bool)), this, SLOT(readFromSourceClicked())); connect(_stringValue, SIGNAL(textChanged(const QString&)), this, SLOT(textChanged())); connect(_fileName, SIGNAL(changed(const QString &)), this, SLOT(fileNameChanged(const QString &))); connect(_configure, SIGNAL(clicked()), this, SLOT(showConfigWidget())); } StringTab::~StringTab() { } void StringTab::generateClicked() { if (_generatedStringGroup->isChecked()) setStringMode(GeneratedString); else setStringMode(DataString); emit sourceChanged(); } void StringTab::readFromSourceClicked() { if (_dataStringGroup->isChecked()) setStringMode(DataString); else setStringMode(GeneratedString); emit sourceChanged(); } QString StringTab::value() const { return _stringValue->text(); } void StringTab::setValue(const QString &value) { _stringValue->setText(value); } void StringTab::textChanged() { emit valueChanged(); } void StringTab::hideGeneratedOptions() { _generatedStringGroup->setVisible(false); _dataStringGroup->setCheckable(false); _dataStringGroup->setTitle(""); _dataStringGroup->setFlat(true); int top_margin; _dataStringGroup->layout()->getContentsMargins(NULL,&top_margin,NULL,NULL); _dataStringGroup->layout()->setContentsMargins(0,top_margin,0,0); } void StringTab::hideDataOptions() { _dataStringGroup->setVisible(false); _generatedStringGroup->setCheckable(false); _generatedStringGroup->setTitle(""); _generatedStringGroup->setFlat(true); int top_margin; _generatedStringGroup->layout()->getContentsMargins(NULL,&top_margin,NULL,NULL); _generatedStringGroup->layout()->setContentsMargins(0,top_margin,0,0); } DataSourcePtr StringTab::dataSource() const { return _dataSource; } void StringTab::setDataSource(DataSourcePtr dataSource) { _dataSource = dataSource; } void StringTab::setStringMode(StringMode mode) { _mode = mode; _dataStringGroup->setChecked(mode == DataString); _generatedStringGroup->setChecked(mode == GeneratedString); } QString StringTab::file() const { return _fileName->file(); } void StringTab::setFile(const QString &file) { _fileName->setFile(file); } QString StringTab::field() const { return _field->currentText(); } void StringTab::setField(const QString &field) { _field->setCurrentIndex(_field->findText(field)); } void StringTab::setFieldList(const QStringList &fieldList) { _field->clear(); _field->addItems(fieldList); } void StringTab::updateDataSource() { fileNameChanged(_fileName->file()); } void StringTab::sourceValid(QString filename, int requestID) { if (_requestID != requestID) { return; } _dataSource = DataSourcePluginManager::findOrLoadSource(_store, filename); _field->setEnabled(true); _dataSource->readLock(); _field->addItems(_dataSource->string().list()); _field->setEditable(!_dataSource->string().isListComplete()); _configure->setEnabled(_dataSource->hasConfigWidget()); _dataSource->unlock(); emit sourceChanged(); // emit valueChanged(); } void StringTab::fileNameChanged(const QString &file) { _field->clear(); _field->setEnabled(false); _configure->setEnabled(false); emit sourceChanged(); _requestID += 1; ValidateDataSourceThread *validateDSThread = new ValidateDataSourceThread(file, _requestID); connect(validateDSThread, SIGNAL(dataSourceValid(QString, int)), this, SLOT(sourceValid(QString, int))); QThreadPool::globalInstance()->start(validateDSThread); } void StringTab::showConfigWidget() { QPointer dialog = new DataSourceDialog(dataDialog()->editMode(), _dataSource, this); if ( dialog->exec() == QDialog::Accepted ) { fileNameChanged(_dataSource->fileName()); } delete dialog; } StringDialog::StringDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit String")); else setWindowTitle(tr("New String")); _stringTab = new StringTab(_document->objectStore(), this); addDataTab(_stringTab); if (editMode() == Edit) { configureTab(dataObject); } else { configureTab(0); } connect(_stringTab, SIGNAL(valueChanged()), this, SLOT(updateButtons())); connect(_stringTab, SIGNAL(sourceChanged()), this, SLOT(updateButtons())); updateButtons(); } StringDialog::~StringDialog() { } // QString StringDialog::tagString() const { // return DataDialog::tagString(); // } void StringDialog::configureTab(ObjectPtr object) { if (DataStringPtr dataString = kst_cast(object)) { _stringTab->setFile(dataString->dataSource()->fileName()); _stringTab->setDataSource(dataString->dataSource()); _stringTab->setField(dataString->field()); _stringTab->hideGeneratedOptions(); } else if (StringPtr string = kst_cast(object)) { // edit value string _stringTab->hideDataOptions(); _stringTab->setValue(string->value()); } else { // new string _stringTab->setFile(_dialogDefaults->value("String/datasource",_stringTab->file()).toString()); } } void StringDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!_stringTab->value().isEmpty() || !_stringTab->field().isEmpty()); } ObjectPtr StringDialog::createNewDataObject() { switch(_stringTab->stringMode()) { case StringTab::DataString: return createNewDataString(); case StringTab::GeneratedString: return createNewGeneratedString(); default: return 0; } } ObjectPtr StringDialog::createNewGeneratedString(){ Q_ASSERT(_document && _document->objectStore()); QString value = _stringTab->value(); // qDebug() << "Creating new string ===>" // << "\n\ttag:" << DataDialog::tagString() // << "\n\tvalue:" << value // << endl; StringPtr string = _document->objectStore()->createObject(); string->setValue(value); string->setOrphan(true); string->setEditable(true); if (DataDialog::tagStringAuto()) { string->setDescriptiveName(QString()); } else { string->setDescriptiveName(DataDialog::tagString()); } string->writeLock(); string->registerChange(); string->unlock(); _dataObjectName = string->Name(); return static_cast(string); } ObjectPtr StringDialog::createNewDataString() { const DataSourcePtr dataSource = _stringTab->dataSource(); if (!dataSource) return 0; const QString field = _stringTab->field(); Q_ASSERT(_document && _document->objectStore()); DataStringPtr string = _document->objectStore()->createObject(); string->writeLock(); string->change(dataSource, field); if (DataDialog::tagStringAuto()) { string->setDescriptiveName(QString()); } else { string->setDescriptiveName(DataDialog::tagString()); } string->registerChange(); string->unlock(); _dataObjectName = string->Name(); return string; } ObjectPtr StringDialog::editExistingDataObject() const { if (StringPtr string = kst_cast(dataObject())) { QString value = _stringTab->value(); if (DataDialog::tagStringAuto()) { string->setDescriptiveName(QString()); } else { string->setDescriptiveName(DataDialog::tagString()); } string->writeLock(); string->setValue(value); string->registerChange(); string->unlock(); } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/csdtab.ui000644 001750 001750 00000006522 11544160207 017255 0ustar00synthsynth000000 000000 CSDTab 0 0 549 590 Spectrogram Contents 0 0 Data vector: false Window size: false _windowSize 1 999999999 500 0 0 Image Options 0 Kst::CurvePlacement QWidget
curveplacement.h
Kst::VectorSelector QWidget
vectorselector.h
Kst::FFTOptions QWidget
fftoptions.h
Kst::ColorPalette
colorpalette.h
kst-2.0.3/src/libkstapp/labelpropertiestab.cpp000644 001750 001750 00000007731 11544160207 022050 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labelpropertiestab.h" #include "application.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" namespace Kst { LabelPropertiesTab::LabelPropertiesTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("Label Properties")); _labelText->setObjectStore(kstApp->mainWindow()->document()->objectStore()); _labelText->setWhatsThis(i18n("The syntax for labels is a derivative of a subset of LaTeX. " "Supported syntax is: \\[greeklettername] and \\[Greeklettername], " "\\approx, \\cdot, \\ge, \\geq, \\inf ," "\\int, \\le, \\leq, \\ne, \\n, " "\\partial, \\prod, \\pm, " "\\textcolor{color name}{colored text}, \\textbf{bold text}, " "\\textit{italicized text}, \\t, \\sum, \\sqrt, " "\\underline{underlined text}, x^y, x_y. " "Scalars, equations, and vector elements can be embedded. " "Scalar: [V1/Mean]. Vector Element: [V1[4]]. " "Equation: [=[V1/Mean]^2]. A [ character can be inserted as \\[.")); _bold->setFixedWidth(32); _bold->setFixedHeight(32); _bold->setIcon(QPixmap(":kst_bold.png")); _italic->setFixedWidth(32); _italic->setFixedHeight(32); _italic->setIcon(QPixmap(":kst_italic.png")); _labelColor->setFixedWidth(32); _labelColor->setFixedHeight(32); connect(_labelText, SIGNAL(labelChanged()), this, SIGNAL(modified())); connect(_labelFontScale, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_labelColor, SIGNAL(changed(const QColor &)), this, SIGNAL(modified())); connect(_bold, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_italic, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_family, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); } LabelPropertiesTab::~LabelPropertiesTab() { } QString LabelPropertiesTab::labelText() const { return _labelText->labelText(); } void LabelPropertiesTab::setLabelText(const QString &text) { _labelText->setLabelText(text); } qreal LabelPropertiesTab::labelScale() const { return _labelFontScale->value(); } void LabelPropertiesTab::setLabelScale(const qreal scale) { _labelFontScale->setValue(scale); } QColor LabelPropertiesTab::labelColor() const { return _labelColor->color(); } void LabelPropertiesTab::setLabelColor(const QColor &color) { _labelColor->setColor(color); } QFont LabelPropertiesTab::labelFont() const { QFont font(_family->currentFont()); font.setItalic(_italic->isChecked()); font.setBold(_bold->isChecked()); return font; } void LabelPropertiesTab::setLabelFont(const QFont &font) { _family->setCurrentFont(font); _bold->setChecked(font.bold()); _italic->setChecked(font.italic()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/gridtab.ui000644 001750 001750 00000003535 11544160207 017432 0ustar00synthsynth000000 000000 GridTab 0 0 243 131 Form Show &grid &Snap to grid Grid &horizontal spacing: _gridHorSpacing Grid &vertical spacing: _gridVerSpacing Qt::Vertical 20 40 kst-2.0.3/src/libkstapp/labeltab.cpp000644 001750 001750 00000025771 11544160207 017737 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labeltab.h" #include "application.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" #include "applicationsettings.h" namespace Kst { LabelTab::LabelTab(PlotItem* plotItem, QWidget *parent) : DialogTab(parent), _plotItem(plotItem), _activeLineEdit(0), _fontDirty(false) { setupUi(this); _globalLabelBold->setIcon(QPixmap(":kst_bold.png")); _globalLabelBold->setFixedWidth(32); _globalLabelItalic->setIcon(QPixmap(":kst_italic.png")); _globalLabelItalic->setFixedWidth(32); _globalLabelColor->setFixedWidth(32); _globalLabelColor->setFixedHeight(32); setTabTitle(tr("Labels")); setGlobalFont(_plotItem->globalFont()); _globalLabelColor->setColor(_plotItem->globalFontColor()); _globalLabelFontSize->setValue(_plotItem->globalFontScale()); _scalars->setObjectStore(kstApp->mainWindow()->document()->objectStore()); _strings->setObjectStore(kstApp->mainWindow()->document()->objectStore()); connect(_topLabelText, SIGNAL(textChanged(const QString &)), this, SIGNAL(modified())); connect(_leftLabelText, SIGNAL(textChanged(const QString &)), this, SIGNAL(modified())); connect(_bottomLabelText, SIGNAL(textChanged(const QString &)), this, SIGNAL(modified())); connect(_rightLabelText, SIGNAL(textChanged(const QString &)), this, SIGNAL(modified())); connect(_topLabelText, SIGNAL(textChanged(const QString &)), this, SLOT(_enableLabelLabels())); connect(_bottomLabelText, SIGNAL(textChanged(const QString &)), this, SLOT(_enableLabelLabels())); connect(_leftLabelText, SIGNAL(textChanged(const QString &)), this, SLOT(_enableLabelLabels())); connect(_rightLabelText, SIGNAL(textChanged(const QString &)), this, SLOT(_enableLabelLabels())); connect(_topLabelText, SIGNAL(inFocus()), this, SLOT(labelSelected())); connect(_leftLabelText, SIGNAL(inFocus()), this, SLOT(labelSelected())); connect(_bottomLabelText, SIGNAL(inFocus()), this, SLOT(labelSelected())); connect(_rightLabelText, SIGNAL(inFocus()), this, SLOT(labelSelected())); connect(_strings, SIGNAL(selectionChanged(QString)), this, SLOT(labelUpdate(const QString&))); connect(_scalars, SIGNAL(selectionChanged(QString)), this, SLOT(labelUpdate(const QString&))); connect(_autoScaleNumberAxis, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_showLegend, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_editLegendContents, SIGNAL(pressed()), _plotItem->legend(), SLOT(edit())); connect(_globalLabelFontSize, SIGNAL(valueChanged(double)), this, SIGNAL(globalFontUpdate())); connect(_globalLabelBold, SIGNAL(toggled(bool)), this, SIGNAL(globalFontUpdate())); connect(_globalLabelItalic, SIGNAL(toggled(bool)), this, SIGNAL(globalFontUpdate())); connect(_globalLabelFontFamily, SIGNAL(currentFontChanged(const QFont &)), this, SIGNAL(globalFontUpdate())); connect(_globalLabelColor, SIGNAL(changed(const QColor &)), this, SIGNAL(globalFontUpdate())); connect(_globalLabelBold, SIGNAL(toggled(bool)), this, SLOT(buttonUpdate())); connect(_globalLabelItalic, SIGNAL(toggled(bool)), this, SLOT(buttonUpdate())); connect(_topLabelAuto, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_leftLabelAuto, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_bottomLabelAuto, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_rightLabelAuto, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_topLabelAuto, SIGNAL(toggled(bool)), this, SLOT(activateFields())); connect(_leftLabelAuto, SIGNAL(toggled(bool)), this, SLOT(activateFields())); connect(_bottomLabelAuto, SIGNAL(toggled(bool)), this, SLOT(activateFields())); connect(_rightLabelAuto, SIGNAL(toggled(bool)), this, SLOT(activateFields())); } LabelTab::~LabelTab() { } void LabelTab::update() { } void LabelTab::buttonUpdate() { _fontDirty = true; } void LabelTab::activateFields() { _topLabelText->setEnabled(_topLabelAuto->checkState() != Qt::Checked); _leftLabelText->setEnabled(_leftLabelAuto->checkState() != Qt::Checked); _bottomLabelText->setEnabled(_bottomLabelAuto->checkState() != Qt::Checked); _rightLabelText->setEnabled(_rightLabelAuto->checkState() != Qt::Checked); } QString LabelTab::leftLabel() const { return _leftLabelText->text(); } bool LabelTab::leftLabelDirty() const { return (_leftLabelText->isModified()); } void LabelTab::setLeftLabel(const QString &label) { _leftLabelLabel->setEnabled(true); _leftLabelText->setText(label); } bool LabelTab::leftLabelAuto() const { return _leftLabelAuto->isChecked(); } bool LabelTab::leftLabelAutoDirty() const { return _leftLabelAuto->checkState() != Qt::PartiallyChecked; } void LabelTab::setLeftLabelAuto(bool a) { _leftLabelAuto->setChecked(a); } QString LabelTab::bottomLabel() const { return _bottomLabelText->text(); } bool LabelTab::bottomLabelDirty() const { return (_bottomLabelText->isModified()); } void LabelTab::setBottomLabel(const QString &label) { _bottomLabelLabel->setEnabled(true); _bottomLabelText->setText(label); } bool LabelTab::bottomLabelAuto() const { return _bottomLabelAuto->isChecked(); } bool LabelTab::bottomLabelAutoDirty() const { return _bottomLabelAuto->checkState() != Qt::PartiallyChecked; } void LabelTab::setBottomLabelAuto(bool a) { _bottomLabelAuto->setChecked(a); } QString LabelTab::rightLabel() const { return _rightLabelText->text(); } bool LabelTab::rightLabelDirty() const { return (_rightLabelText->isModified()); } void LabelTab::setRightLabel(const QString &label) { _rightLabelLabel->setEnabled(true); _rightLabelText->setText(label); } bool LabelTab::rightLabelAuto() const { return _rightLabelAuto->isChecked(); } bool LabelTab::rightLabelAutoDirty() const { return _rightLabelAuto->checkState() != Qt::PartiallyChecked; } void LabelTab::setRightLabelAuto(bool a) { _rightLabelAuto->setChecked(a); } QString LabelTab::topLabel() const { return _topLabelText->text(); } bool LabelTab::topLabelDirty() const { return (_topLabelText->isModified()); } void LabelTab::setTopLabel(const QString &label) { _topLabelLabel->setEnabled(true); _topLabelText->setText(label); } bool LabelTab::topLabelAuto() const { return _topLabelAuto->isChecked(); } bool LabelTab::topLabelAutoDirty() const { return _topLabelAuto->checkState() != Qt::PartiallyChecked; } void LabelTab::setTopLabelAuto(bool a) { _topLabelAuto->setChecked(a); } void LabelTab::setGlobalFont(const QFont &font) { _fontDirty = false; _globalLabelFontFamily->setCurrentFont(font); _globalLabelBold->setChecked(font.bold()); _globalLabelItalic->setChecked(font.italic()); } QFont LabelTab::globalLabelFont(const QFont ref_font) const { QString family = (_globalLabelFontFamily->currentIndex() == -1) ? ref_font.family() : _globalLabelFontFamily->currentFont().family(); QFont font(family); font.setItalic(_globalLabelItalic->isChecked()); font.setBold(_globalLabelBold->isChecked()); return font; } bool LabelTab::globalLabelFontDirty() const { return (_globalLabelFontFamily->currentIndex() != -1 || _fontDirty); } qreal LabelTab::globalLabelFontScale() const { return _globalLabelFontSize->value(); } bool LabelTab::globalLabelFontScaleDirty() const { return (!_globalLabelFontSize->text().isEmpty()); } QColor LabelTab::globalLabelColor() const { return _globalLabelColor->color(); } bool LabelTab::globalLabelColorDirty() const { return _globalLabelColor->colorDirty(); } bool LabelTab::showLegend() const { return _showLegend->isChecked(); } bool LabelTab::showLegendDirty() const { return _showLegend->checkState() != Qt::PartiallyChecked; } void LabelTab::setShowLegend(const bool show) { _showLegend->setChecked(show); } bool LabelTab::autoScaleNumbers() const { return _autoScaleNumberAxis->isChecked(); } bool LabelTab::autoScaleNumbersDirty() const { return _autoScaleNumberAxis->checkState() != Qt::PartiallyChecked; } void LabelTab::setAutoScaleNumbers(const bool scale) { _autoScaleNumberAxis->setChecked(scale); } void LabelTab::labelUpdate(const QString& string) { if (_activeLineEdit) { QString label = _activeLineEdit->text(); label += '[' + string + ']'; _activeLineEdit->setText(label); } } void LabelTab::labelSelected() { if (_rightLabelText->hasFocus()) { _activeLineEdit = _rightLabelText; } else if (_bottomLabelText->hasFocus()) { _activeLineEdit = _bottomLabelText; } else if (_leftLabelText->hasFocus()) { _activeLineEdit = _leftLabelText; } else { _activeLineEdit = _topLabelText; } } void LabelTab::clearTabValues() { _showLegend->setCheckState(Qt::PartiallyChecked); _globalLabelFontSize->clear(); _globalLabelFontFamily->setCurrentIndex(-1); _globalLabelBold->setChecked(false); _globalLabelItalic->setChecked(false); _autoScaleNumberAxis->setCheckState(Qt::PartiallyChecked); _topLabelText->clear(); _bottomLabelText->clear(); _leftLabelText->clear(); _rightLabelText->clear(); _topLabelText->setModified(false); _bottomLabelText->setModified(false); _leftLabelText->setModified(false); _rightLabelText->setModified(false); _topLabelLabel->setEnabled(false); _bottomLabelLabel->setEnabled(false); _leftLabelLabel->setEnabled(false); _rightLabelLabel->setEnabled(false); _globalLabelColor->clearSelection(); _topLabelAuto->setCheckState(Qt::PartiallyChecked); _bottomLabelAuto->setCheckState(Qt::PartiallyChecked); _leftLabelAuto->setCheckState(Qt::PartiallyChecked); _rightLabelAuto->setCheckState(Qt::PartiallyChecked); activateFields(); } void LabelTab::enableSingleEditOptions(bool enabled) { _editLegendContents->setEnabled(enabled); if (enabled) { setGlobalFont(_plotItem->globalFont()); _showLegend->setTristate(false); _topLabelAuto->setTristate(false); _bottomLabelAuto->setTristate(false); _leftLabelAuto->setTristate(false); _rightLabelAuto->setTristate(false); _autoScaleNumberAxis->setTristate(false); activateFields(); } } void LabelTab::_enableLabelLabels() { _topLabelLabel->setEnabled(_topLabelText->isModified()); _bottomLabelLabel->setEnabled(_bottomLabelText->isModified()); _leftLabelLabel->setEnabled(_leftLabelText->isModified()); _rightLabelLabel->setEnabled(_rightLabelText->isModified()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewdialog.cpp000644 001750 001750 00000006554 11544160207 020321 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "viewdialog.h" #include "view.h" #include "filltab.h" #include "gridtab.h" #include "childviewoptionstab.h" #include "dialogpage.h" #include "document.h" #include "mainwindow.h" #include "application.h" #include #include namespace Kst { ViewDialog::ViewDialog(View *view, QWidget *parent) : Dialog(parent), _view(view) { setWindowTitle(tr("Edit View")); _fillTab = new FillTab(this); _gridTab = new GridTab(this); // _childViewOptionsTab = new ChildViewOptionsTab(this); connect(_fillTab, SIGNAL(apply()), this, SLOT(fillChanged())); connect(_gridTab, SIGNAL(apply()), this, SLOT(gridChanged())); // connect(_childViewOptionsTab, SIGNAL(apply()), this, SLOT(childViewOptionsChanged())); DialogPage *grid = new DialogPage(this); grid->setPageTitle(tr("Grid")); grid->addDialogTab(_gridTab); addDialogPage(grid); DialogPage *fill = new DialogPage(this); fill->setPageTitle(tr("Fill")); fill->addDialogTab(_fillTab); addDialogPage(fill); // DialogPage *childViewOptions = new DialogPage(this); // childViewOptions->setPageTitle(tr("Child View Options")); // childViewOptions->addDialogTab(_childViewOptionsTab); // addDialogPage(childViewOptions); setupFill(); setupGrid(); // setupChildViewOptions(); selectDialogPage(grid); } ViewDialog::~ViewDialog() { } void ViewDialog::setupFill() { Q_ASSERT(_view); QBrush b = _view->backgroundBrush(); _fillTab->setColor(b.color()); _fillTab->setStyle(b.style()); if (const QGradient *gradient = b.gradient()) { _fillTab->setGradient(*gradient); } } void ViewDialog::setupGrid() { _gridTab->setShowGrid(_view->showGrid()); _gridTab->setSnapToGrid(_view->snapToGrid()); _gridTab->setGridHorizontalSpacing(_view->gridSpacing().width()); _gridTab->setGridVerticalSpacing(_view->gridSpacing().height()); } void ViewDialog::setupChildViewOptions() { } void ViewDialog::fillChanged() { Q_ASSERT(_view); QBrush b = _view->backgroundBrush(); b.setColor(_fillTab->color()); b.setStyle(_fillTab->style()); QGradient gradient = _fillTab->gradient(); if (gradient.type() != QGradient::NoGradient) { b = QBrush(gradient); } kstApp->mainWindow()->document()->setChanged(true); _view->setBackgroundBrush(b); } void ViewDialog::gridChanged() { _view->setShowGrid(_gridTab->showGrid()); _view->setSnapToGrid(_gridTab->snapToGrid()); _view->setGridSpacing(QSizeF(_gridTab->gridHorizontalSpacing(), _gridTab->gridVerticalSpacing())); } void ViewDialog::childViewOptionsChanged() { } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/arrowpropertiestab.ui000644 001750 001750 00000006354 11544160207 021756 0ustar00synthsynth000000 000000 ArrowPropertiesTab Qt::NonModal 0 0 336 289 Form Arrow at &start 0 0 S&tart arrow scale Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _startArrowScale 0 0 Arrow Head Size The size of the arrow head is proportional to this value. Arrow at &end 0 0 E&nd arrow scale Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _endArrowScale Arrow Head Size The size of the arrow head is proportional to this value. Qt::Vertical 20 40 kst-2.0.3/src/libkstapp/tabwidget.h000644 001750 001750 00000003051 11544160207 017573 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TABWIDGET_H #define TABWIDGET_H #include namespace Kst { class View; class TabWidget : public QTabWidget { Q_OBJECT public: TabWidget(QWidget *parent); ~TabWidget(); View *currentView() const; QList views() const; // pass tab name as objectName void addView(View*); void deleteView(View* view); void clear(); Q_SIGNALS: void currentViewModeChanged(); public Q_SLOTS: View *createView(); void renameCurrentView(); void closeCurrentView(); void setCurrentViewName(QString name); private Q_SLOTS: void contextMenu(const QPoint&); private: int _cnt; void checkedShowTabbar(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotmarkers.h000644 001750 001750 00000005042 11544160207 020166 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef _PLOTMARKERS_H #define _PLOTMARKERS_H #include "kst_export.h" #include "vector.h" #include "curve.h" #include #include namespace Kst { class PlotMarkers { public: enum CurveMarkerMode { RisingEdge = 0, FallingEdge = 1, BothEdges = 2 }; PlotMarkers(bool xAxis = true); virtual ~PlotMarkers(); QList markers(); QList manualMarkers() const { return _manualMarkers; } void setManualMarkers(const QList &markers) { _manualMarkers = markers; } Qt::PenStyle lineStyle() const { return _lineStyle; } void setLineStyle(Qt::PenStyle style) { _lineStyle = style; } QColor lineColor() const { return _lineColor; } void setLineColor(const QColor &color) { _lineColor = color; } double lineWidth() const { return _lineWidth; } void setLineWidth(const double width) { _lineWidth = width; } bool isVectorSource() const { return (_vector != 0); } VectorPtr vector() const { return _vector; } void setVector(VectorPtr vector) { _vector = vector; } bool isCurveSource() const { return (_curve != 0); } CurvePtr curve() const { return _curve; } void setCurve(CurvePtr curve) { _curve = curve; } CurveMarkerMode curveMarkerMode() const { return _curveMode; } void setCurveMarkerMode(const CurveMarkerMode mode) { _curveMode = mode; } void saveInPlot(QXmlStreamWriter &xml); bool configureFromXml(QXmlStreamReader &xml, ObjectStore *store); private: bool _xAxis; QColor _lineColor; Qt::PenStyle _lineStyle; double _lineWidth; CurveMarkerMode _curveMode; VectorPtr _vector; CurvePtr _curve; QList _manualMarkers; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/arrowpropertiestab.cpp000644 001750 001750 00000005056 11544160207 022121 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "arrowpropertiestab.h" namespace Kst { ArrowPropertiesTab::ArrowPropertiesTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("ArrowProperties")); connect(_startArrow, SIGNAL(stateChanged(int)), this, SLOT(update())); connect(_endArrow, SIGNAL(stateChanged(int)), this, SLOT(update())); connect(_startArrow, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_endArrow, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_startArrowScale, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_endArrowScale, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); update(); } ArrowPropertiesTab::~ArrowPropertiesTab() { } void ArrowPropertiesTab::update() { _startArrowScale->setEnabled(_startArrow->isChecked()); _endArrowScale->setEnabled(_endArrow->isChecked()); _startArrowLabel->setEnabled(_startArrow->isChecked()); _endArrowLabel->setEnabled(_endArrow->isChecked()); } bool ArrowPropertiesTab::startArrowHead() { return _startArrow->isChecked(); } void ArrowPropertiesTab::setStartArrowHead(const bool enabled) { _startArrow->setChecked(enabled); } bool ArrowPropertiesTab::endArrowHead() { return _endArrow->isChecked(); } void ArrowPropertiesTab::setEndArrowHead(const bool enabled) { _endArrow->setChecked(enabled); } qreal ArrowPropertiesTab::startArrowScale() { return _startArrowScale->value(); } void ArrowPropertiesTab::setStartArrowScale(const qreal scale) { _startArrowScale->setValue(scale); } qreal ArrowPropertiesTab::endArrowScale() { return _endArrowScale->value(); } void ArrowPropertiesTab::setEndArrowScale(const qreal scale) { _endArrowScale->setValue(scale); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/equationdialog.cpp000644 001750 001750 00000027310 11544160207 021165 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "equationdialog.h" #include "dialogpage.h" #include "editmultiplewidget.h" #include "datacollection.h" #include "equation.h" #include "plotitem.h" #include "plotrenderitem.h" #include "curve.h" #include "document.h" #include "objectstore.h" #include namespace Kst { EquationTab::EquationTab(QWidget *parent) : DataTab(parent) { setupUi(this); setTabTitle(tr("Equation")); populateFunctionList(); _curvePlacement->setExistingPlots(Data::self()->plotList()); _xVectors->setIsX(true); _xVectorLabel->setBuddy(_xVectors->_vector); _scalarsLabel->setBuddy(_scalars->_scalar); _vectorsLabel->setBuddy(_vectors->_vector); connect(_xVectors, SIGNAL(selectionChanged(QString)), this, SLOT(selectionChanged())); connect(_equation, SIGNAL(textChanged(const QString &)), this, SLOT(selectionChanged())); connect(Operators, SIGNAL(activated(QString)), this, SLOT(equationOperatorUpdate(const QString&))); connect(_vectors, SIGNAL(selectionChanged(QString)), this, SLOT(equationUpdate(const QString&))); connect(_scalars, SIGNAL(selectionChanged(QString)), this, SLOT(equationUpdate(const QString&))); connect(_xVectors, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos())); connect(_vectors, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos())); connect(_xVectors, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); connect(_equation, SIGNAL(textChanged(const QString &)), this, SIGNAL(modified())); connect(_doInterpolation, SIGNAL(clicked()), this, SIGNAL(modified())); } EquationTab::~EquationTab() { } void EquationTab::selectionChanged() { emit optionsChanged(); } void EquationTab::equationUpdate(const QString& string) { QString cleanString = string; cleanString.remove('[').remove(']'); // HACK: '[' in descriptive names mess up parser. Remove them. _equation->insert('[' + cleanString + ']'); } void EquationTab::equationOperatorUpdate(const QString& string) { QString equation = _equation->text(); equation += string; _equation->setText(equation); } void EquationTab::populateFunctionList() { Operators->clear(); Operators->addItem("+"); Operators->addItem("-"); Operators->addItem("*"); Operators->addItem("/"); Operators->addItem("%"); Operators->addItem("^"); Operators->addItem("&"); Operators->addItem("|"); Operators->addItem("&&"); Operators->addItem("||"); Operators->addItem("!"); Operators->addItem("<"); Operators->addItem("<="); Operators->addItem("=="); Operators->addItem(">="); Operators->addItem(">"); Operators->addItem("!="); Operators->addItem("PI"); Operators->addItem("e"); Operators->addItem("STEP()"); Operators->addItem("ABS()"); Operators->addItem("SQRT()"); Operators->addItem("CBRT()"); Operators->addItem("SIN()"); Operators->addItem("COS()"); Operators->addItem("TAN()"); Operators->addItem("ASIN()"); Operators->addItem("ACOS()"); Operators->addItem("ATAN()"); Operators->addItem("SEC()"); Operators->addItem("CSC()"); Operators->addItem("COT()"); Operators->addItem("SINH()"); Operators->addItem("COSH()"); Operators->addItem("TANH()"); Operators->addItem("EXP()"); Operators->addItem("LN()"); Operators->addItem("LOG()"); Operators->addItem("PLUGIN()"); } VectorPtr EquationTab::xVector() const { return _xVectors->selectedVector(); } bool EquationTab::xVectorDirty() const { return _xVectors->selectedVectorDirty(); } void EquationTab::setXVector(VectorPtr vector) { _xVectors->setSelectedVector(vector); } QString EquationTab::equation() const { return _equation->text(); } bool EquationTab::equationDirty() const { return (!_equation->text().isEmpty()); } void EquationTab::setEquation(const QString &equation) { _equation->setText(equation); } bool EquationTab::doInterpolation() const { return _doInterpolation->isChecked(); } bool EquationTab::doInterpolationDirty() const { return _doInterpolation->checkState() != Qt::PartiallyChecked; } void EquationTab::setDoInterpolation(bool doInterpolation) { _doInterpolation->setChecked(doInterpolation); } CurveAppearance* EquationTab::curveAppearance() const { return _curveAppearance; } CurvePlacement* EquationTab::curvePlacement() const { return _curvePlacement; } void EquationTab::setObjectStore(ObjectStore *store) { _vectors->setObjectStore(store); _scalars->setObjectStore(store); _xVectors->setObjectStore(store); } void EquationTab::hideCurveOptions() { _curvePlacement->setVisible(false); _curveAppearance->setVisible(false); } void EquationTab::clearTabValues() { _xVectors->clearSelection(); _equation->clear(); _doInterpolation->setCheckState(Qt::PartiallyChecked); } void EquationTab::updateVectorCombos() { _xVectors->fillVectors(); _vectors->fillVectors(); _scalars->fillScalars(); } EquationDialog::EquationDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Equation")); else setWindowTitle(tr("New Equation")); _equationTab = new EquationTab(this); addDataTab(_equationTab); _equationTab->setEquation(""); if (editMode() == Edit) { configureTab(dataObject); } else { configureTab(0); } connect(_equationTab, SIGNAL(optionsChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_equationTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } EquationDialog::~EquationDialog() { } // QString EquationDialog::tagString() const { // return DataDialog::tagString(); // } void EquationDialog::editMultipleMode() { _equationTab->clearTabValues(); } void EquationDialog::editSingleMode() { configureTab(dataObject()); } void EquationDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled((_equationTab->xVector() && !_equationTab->equation().isEmpty()) || (editMode() == EditMultiple)); } void EquationDialog::configureTab(ObjectPtr object) { if (!object) { _equationTab->curveAppearance()->loadWidgetDefaults(); _equationTab->setToLastX(); } else if (EquationPtr equation = kst_cast(object)) { _equationTab->setXVector(equation->vXIn()); _equationTab->setEquation(equation->equation()); _equationTab->setDoInterpolation(equation->doInterp()); _equationTab->hideCurveOptions(); if (_editMultipleWidget) { EquationList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(EquationPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } ObjectPtr EquationDialog::createNewDataObject() { Q_ASSERT(_document && _document->objectStore()); EquationPtr equation = _document->objectStore()->createObject(); Q_ASSERT(equation); equation->setEquation(_equationTab->equation()); equation->setExistingXVector(_equationTab->xVector(), _equationTab->doInterpolation()); if (DataDialog::tagStringAuto()) { equation->setDescriptiveName(QString()); } else { equation->setDescriptiveName(DataDialog::tagString()); } equation->writeLock(); equation->registerChange(); equation->unlock(); CurvePtr curve = _document->objectStore()->createObject(); Q_ASSERT(curve); curve->setXVector(equation->vX()); curve->setYVector(equation->vY()); curve->setColor(_equationTab->curveAppearance()->color()); curve->setHeadColor(_equationTab->curveAppearance()->headColor()); curve->setHasPoints(_equationTab->curveAppearance()->showPoints()); curve->setHasLines(_equationTab->curveAppearance()->showLines()); curve->setHasBars(_equationTab->curveAppearance()->showBars()); curve->setHasHead(_equationTab->curveAppearance()->showHead()); curve->setLineWidth(_equationTab->curveAppearance()->lineWidth()); curve->setLineStyle(_equationTab->curveAppearance()->lineStyle()); curve->setPointType(_equationTab->curveAppearance()->pointType()); curve->setHeadType(_equationTab->curveAppearance()->headType()); curve->setPointDensity(_equationTab->curveAppearance()->pointDensity()); curve->setBarStyle(_equationTab->curveAppearance()->barStyle()); curve->writeLock(); curve->registerChange(); curve->unlock(); _equationTab->curveAppearance()->setWidgetDefaults(); PlotItem *plotItem = 0; switch (_equationTab->curvePlacement()->place()) { case CurvePlacement::NoPlot: break; case CurvePlacement::ExistingPlot: { plotItem = static_cast(_equationTab->curvePlacement()->existingPlot()); break; } case CurvePlacement::NewPlotNewTab: _document->createView(); // fall through to case NewPlot. case CurvePlacement::NewPlot: { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); if (_equationTab->curvePlacement()->scaleFonts()) { plotItem->view()->resetPlotFontSizes(); } break; } default: break; } if (_equationTab->curvePlacement()->place() != CurvePlacement::NoPlot) { PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(curve)); plotItem->update(); plotItem->view()->appendToLayout(_equationTab->curvePlacement()->layout(), plotItem, _equationTab->curvePlacement()->gridColumns()); } return ObjectPtr(equation.data()); } ObjectPtr EquationDialog::editExistingDataObject() const { if (EquationPtr equation = kst_cast(dataObject())) { if (editMode() == EditMultiple) { QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { EquationPtr equation = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (equation) { VectorPtr xVector = _equationTab->xVectorDirty() ? _equationTab->xVector() : equation->vXIn(); const QString equationString = _equationTab->equationDirty() ? _equationTab->equation() : equation->equation(); const bool doInterpolation = _equationTab->doInterpolationDirty() ? _equationTab->doInterpolation() : equation->doInterp(); equation->writeLock(); equation->setEquation(equationString); equation->setExistingXVector(xVector, doInterpolation); equation->registerChange(); equation->unlock(); } } } else { equation->writeLock(); equation->setEquation(_equationTab->equation()); equation->setExistingXVector(_equationTab->xVector(), _equationTab->doInterpolation()); if (DataDialog::tagStringAuto()) { equation->setDescriptiveName(QString()); } else { equation->setDescriptiveName(DataDialog::tagString()); } equation->registerChange(); equation->unlock(); } } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotitemmanager.h000644 001750 001750 00000005315 11544160207 021016 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLOTITEMMANAGER_H #define PLOTITEMMANAGER_H #include #include #include namespace Kst { class View; class ViewItem; class PlotItem; class SharedAxisBoxItem; class PlotItemManager : public QObject { Q_OBJECT public: static PlotItemManager *self(); static QList plotsForView(View *view); static void clearPlotsForView(View *view); static QList tiedZoomPlotsForView(View *view); static QList tiedZoomPlotsForViewItem(ViewItem *viewItem); static QList tiedZoomPlots(PlotItem* plotItem); static QList tiedZoomViewItems(PlotItem* plotItem); void toggleAllTiedZoom(View *view); Q_SIGNALS: void tiedZoomRemoved(); void allPlotsTiedZoom(); public Q_SLOTS: void clearFocusedPlots(); private: static void cleanup(); PlotItemManager(); virtual ~PlotItemManager(); void addPlot(PlotItem *plotItem); void addViewItem(ViewItem *viewItem); void removePlot(PlotItem *plotItem); void removeViewItem(ViewItem *viewItem); void addTiedZoomPlot(PlotItem *plotItem, bool checkAll = true); void addTiedZoomViewItem(ViewItem *viewItem, bool checkAll = true); void removeTiedZoomPlot(PlotItem *plotItem); void removeTiedZoomViewItem(ViewItem *viewItem); void setFocusPlot(PlotItem *plotItem); void removeFocusPlot(PlotItem *plotItem); void checkAllTied(View* view); private: friend class ViewItem; friend class PlotItem; friend class SharedAxisBoxItem; QHash< View*, QList > _plotLists; QHash< View*, QList > _viewItemLists; QHash< View*, QList > _tiedZoomViewPlotLists; QHash< View*, QList > _tiedZoomViewItemLists; QHash< ViewItem*, QList > _tiedZoomViewItemPlotLists; QList _focusedPlots; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/commandlineparser.cpp000644 001750 001750 00000053636 11544160207 021675 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include "commandlineparser.h" #include "datasource.h" #include "objectstore.h" #include "colorsequence.h" #ifdef KST_HAVE_SVN_REVISION_H #include "svnrevision.h" #endif #include #include #include #include #include "curve.h" #include "psd.h" #include "histogram.h" #include "datamatrix.h" #include "image.h" #include "palette.h" #include "kst_i18n.h" #include "updatemanager.h" #include "dialogdefaults.h" #include "datasourcepluginmanager.h" namespace Kst { static const char *usageMessage = "KST Command Line Usage\n" "************************\n" "*** Load a kst file: ***\n" "kst [OPTIONS] kstfile\n" "\n" "[OPTIONS] will override the datasource parameters for all data sources in the kst file:\n" " -F \n" " -f \n" " -n \n" " -s \n" " -a (apply averaging filter: requires -s)\n\n" "************************\n"; static const char *usageDetailsMessage = "*** Read a data file ***\n" "kst datasource OPTIONS [datasource OPTIONS []]\n" "\n" "OPTIONS are read and interpreted in order. Except for data object options, all are applied to all future data objects, unless later overridden.\n" "Output Options:\n" " --print Print to file and exit.\n" " --landscape Print in landscape mode.\n" " --portrait Print in portrait mode.\n" " --Letter Print to Letter sized paper.\n" " --A4 Print to A4 sized paper.\n" " --png Render to a png image, and exit.\n" "File Options:\n" " -f default: 'end' counts from end.\n" " -n default: 'end' reads to end of file\n" " -s default: 0 (read every sample)\n" " -a apply averaging filter: requires -s\n\n" "Position:\n" " -P : Place curves in one plot.\n" " -A Place future curves in individual plots.\n" "Appearance\n" " -d: use points for the next curve\n" " -l: use lines for the next curve\n" " -b: use bargraph for the next curve\n" "Data Object Modifiers\n" " -x : Create vector and use as X vector for curves.\n" " -e : Create vector and use as Y-error vector for next -y.\n" " -r : sample rate (spectra & spectograms).\n" "Data Objects:\n" " -y plot an XY curve of field.\n" " -p plot the spectrum of field.\n" " -h plot a histogram of field.\n" " -z plot an image of matrix field.\n" "\n" "****************\n" "*** Examples ***\n" "\n" "Data sources and fields:\n" "Plot all data in column 2 from data.dat.\n" " kst data.dat -y 2\n" "\n" "Same as above, except only read 20 lines, starting at line 10.\n" " kst data.dat -f 10 -n 20 -y 2\n" "\n" "... also read col 1. One plot per curve.\n" " kst data.dat -f 10 -n 20 -y 1 -y 2\n" "\n" "Read col 1 from data2.dat and col 1 from data.dat\n" " kst data.dat -f 10 -n 20 -y 2 data2.dat -y 1\n" "\n" "Same as above, except read 40 lines starting at 30 in data2.dat\n" " kst data.dat -f 10 -n 20 -y 2 data2.dat -f 30 -n 40 -y 1\n" "\n" "Specify the X vector and error bars:\n" "Plot x = col 1 and Y = col 2 and error flags = col 3 from data.dat\n" " kst data.dat -x 1 -e 3 -y 2\n" "\n" "Get the X vector from data1.dat, and the Y vector from data2.dat.\n" " kst data1.dat -x 1 data2.dat -y 1\n" "\n" "Placement:\n" "Plot column 2 and column 3 in plot P1 and column 4 in plot P2\n" " kst data.dat -P P1 -y 2 -y 3 -P P2 -y 4\n"; static void printText(const QString& text, const QString& detailText = QString(), const QString& t = QString()) { #ifdef Q_OS_WIN // No console on Windows. QMessageBox box(QMessageBox::Information, "Kst", text + t); if (!detailText.isEmpty()) { box.setDetailedText(detailText); } box.exec(); #else QString displayText = QString(text) + QString(detailText) + t; qWarning("%s", qPrintable(displayText)); #endif } static void printUsage(const QString &t) { printText(QString(usageMessage), QString(usageDetailsMessage), "\n" + t); } CommandLineParser::CommandLineParser(Document *doc, MainWindow* mw) : _mainWindow(mw), _doAve(false), _doSkip(false), _doConsecutivePlots(true), _useBargraph(false), _useLines(true), _usePoints(false), _overrideStyle(false), _sampleRate(1.0), _numFrames(-1), _startFrame(-1), _skip(0), _plotName(), _errorField(), _fileName(), _xField(QString("INDEX")), _pngFile(QString()), _printFile(QString()), _landscape(false), _plotItem(0) { Q_ASSERT(QCoreApplication::instance()); _arguments = QCoreApplication::instance()->arguments(); _arguments.takeFirst(); //appname _document = doc; _fileNames.clear(); _vectors.clear(); _plotItems.clear(); } CommandLineParser::~CommandLineParser() { } bool CommandLineParser::_setIntArg(int *arg, QString Message, bool accept_end) { QString param; bool ok = true; if (_arguments.count()> 0) { param = _arguments.takeFirst(); if ((param==i18n("end") || (param=="end")) && (accept_end)) { *arg = -1; } else { *arg = param.toInt(&ok); } } else { ok=false; } if (!ok) printUsage(Message); return ok; } bool CommandLineParser::_setDoubleArg(double *arg, QString Message) { QString param; bool ok = true; if (_arguments.count()> 0) { param = _arguments.takeFirst(); *arg = param.toDouble(&ok); } else { ok=false; } if (!ok) printUsage(Message); return ok; } bool CommandLineParser::_setStringArg(QString &arg, QString Message) { bool ok = true; if (_arguments.count()> 0) { arg = _arguments.takeFirst(); } else { ok=false; } if (!ok) printUsage(Message); return ok; } DataVectorPtr CommandLineParser::createOrFindDataVector(QString field, DataSourcePtr ds) { DataVectorPtr xv; bool found = false; if ((_startFrame==-1) && (_numFrames==-1)) { // count from end and read to end _startFrame = 0; } // Flaky magic: if ds is an ascii file, change fields named 0 to 99 to // Column xx. This allows "-y 2" but prevents ascii files with fields // actually named "0 to 99" from being read from the command line. if (ds->fileType() == "ASCII file") { QRegExp num("^[0-9]{1,2}$"); if (num.exactMatch(field)) { field = i18n("Column %1", field); } } // check to see if an identical vector already exists. If so, use it. for (int i=0; i<_vectors.count(); i++) { xv = _vectors.at(i); if (field == xv->field()) { if ((xv->reqStartFrame() == _startFrame) && (xv->reqNumFrames() == _numFrames) && (xv->skip() == _skip) && (xv->doSkip() == (_skip>0)) && (xv->doAve() == _doAve) ){ if (xv->filename()==ds->fileName()) { found = true; break; } } } } if (!found) { Q_ASSERT(_document && _document->objectStore()); xv = _document->objectStore()->createObject(); xv->writeLock(); xv->change(ds, field, _startFrame, _numFrames, _skip, _skip>0, _doAve); xv->registerChange(); xv->unlock(); _vectors.append(xv); } return xv; } void CommandLineParser::createCurveInPlot(VectorPtr xv, VectorPtr yv, VectorPtr ev) { CurvePtr curve = _document->objectStore()->createObject(); curve->setXVector(xv); curve->setYVector(yv); curve->setXError(0); curve->setXMinusError(0); curve->setYMinusError(0); curve->setColor(ColorSequence::self().next()); curve->setHasPoints(_usePoints); curve->setHasLines(_useLines); curve->setHasBars(_useBargraph); curve->setLineWidth(1); //FIXME: use defaults //curve->setPointType(ptype++ % KSTPOINT_MAXTYPE); if (ev) { curve->setYError(ev); } else { curve->setYError(0); } curve->writeLock(); curve->registerChange(); curve->unlock(); addCurve(curve); } void CommandLineParser::addCurve(CurvePtr curve) { if (_doConsecutivePlots) { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); _plotItem = static_cast(cmd->item()); _plotItem->view()->appendToLayout(CurvePlacement::Auto, _plotItem); } PlotRenderItem *renderItem = _plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(curve)); _plotItem->update(); } void CommandLineParser::createImageInPlot(MatrixPtr m) { ImagePtr image = _document->objectStore()->createObject(); image->changeToColorOnly(m, 0.0, 1.0, true, Palette::getPaletteList().at(0)); image->writeLock(); image->registerChange(); image->unlock(); if (_doConsecutivePlots) { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); _plotItem = static_cast(cmd->item()); _plotItem->view()->appendToLayout(CurvePlacement::Auto, _plotItem); } PlotRenderItem *renderItem = _plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(image)); _plotItem->update(); } void CommandLineParser::createOrFindPlot( const QString plot_name ) { bool found = false; PlotItem *pi; // check to see if a plot with this name exists. If so, use it. for (int i=0; i<_plotItems.count(); i++) { pi = _plotItems.at(i); if (plot_name == pi->descriptiveName()) { found = true; break; } } if (!found) { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); pi = static_cast ( cmd->item() ); pi->setDescriptiveName( plot_name ); _plotItems.append(pi); pi->view()->appendToLayout(CurvePlacement::Auto, pi); } _plotItem = pi; } QString CommandLineParser::kstFileName() { if (_fileNames.size()>0) { return (_fileNames.at(0)); } else { return QString(); } } bool CommandLineParser::processCommandLine(bool *ok) { QString arg, param; *ok=true; bool new_fileList=true; bool dataPlotted = false; // set paper settings to match defaults. _paperSize = QPrinter::PaperSize(_dialogDefaults->value("print/paperSize", QPrinter::Letter).toInt()); if (_dialogDefaults->value("print/landscape",true).toBool()) { _landscape = true; } else { _landscape = false; } while (*ok) { if (_arguments.count() < 1) { break; } arg = _arguments.takeFirst(); if ((arg == "--help")||(arg == "-help")) { printUsage(QString()); *ok = false; } else if (arg == "--version" || arg == "-version") { printText(QString("Kst ") + KSTVERSION + " Revision " + SVN_REVISION); *ok = false; } else if (arg == "-f") { *ok = _setIntArg(&_startFrame, i18n("Usage: -f \n"), true); _document->objectStore()->override.f0 = _startFrame; } else if (arg == "-n") { *ok = _setIntArg(&_numFrames, i18n("Usage: -n \n"), true); _document->objectStore()->override.N = _numFrames; } else if (arg == "-s") { *ok = _setIntArg(&_skip, i18n("Usage: -s \n")); _document->objectStore()->override.skip = _skip; } else if (arg == "-a") { _doAve = true; _document->objectStore()->override.doAve = _doAve; } else if (arg == "-P") { QString plot_name; *ok = _setStringArg(plot_name,i18n("Usage: -P \n")); _doConsecutivePlots=false; createOrFindPlot(plot_name); } else if (arg == "-A") { _doConsecutivePlots = true; } else if (arg == "-d") { _useBargraph=false; _useLines = false; _usePoints = true; _overrideStyle = true; } else if (arg == "-l") { _useBargraph=false; _useLines = true; _usePoints = false; _overrideStyle = true; } else if (arg == "-b") { _useBargraph=true; _useLines = false; _usePoints = false; _overrideStyle = true; } else if (arg == "-x") { *ok = _setStringArg(_xField,i18n("Usage: -x \n")); } else if (arg == "-e") { *ok = _setStringArg(_errorField,i18n("Usage: -e \n")); } else if (arg == "-r") { *ok = _setDoubleArg(&_sampleRate,i18n("Usage: -r \n")); } else if (arg == "-y") { QString field; *ok = _setStringArg(field,i18n("Usage: -y \n")); if (_fileNames.size()<1) { printUsage(i18n("No data files specified\n")); *ok = false; break; } for (int i_file=0; i_file<_fileNames.size(); i_file++) { QString file = _fileNames.at(i_file); QFileInfo info(file); if (!info.exists()) { printUsage(i18n("file %1 does not exist\n").arg(file)); *ok = false; break; } DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), file); DataVectorPtr xv = createOrFindDataVector(_xField, ds); DataVectorPtr yv = createOrFindDataVector(field, ds); DataVectorPtr ev; if (!_errorField.isEmpty()) { DataVectorPtr ev = createOrFindDataVector(_errorField, ds); if (!_overrideStyle) { _useBargraph=false; _useLines = false; _usePoints = true; } } else { ev = 0; if (!_overrideStyle) { _useBargraph=false; _useLines = true; _usePoints = false; } } createCurveInPlot(xv, yv, ev); dataPlotted = true; } _errorField.clear(); new_fileList = true; _overrideStyle = false; } else if (arg == "-p") { QString field; *ok = _setStringArg(field,i18n("Usage: -p \n")); if (*ok) { for (int i_file=0; i_file<_fileNames.size(); i_file++) { QString file = _fileNames.at(i_file); QFileInfo info(file); if (!info.exists()) { printUsage(i18n("file %1 does not exist\n").arg(file)); *ok = false; break; } DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), file); DataVectorPtr pv = createOrFindDataVector(field, ds); Q_ASSERT(_document && _document->objectStore()); PSDPtr powerspectrum = _document->objectStore()->createObject(); Q_ASSERT(powerspectrum); powerspectrum->writeLock(); powerspectrum->change(pv, _sampleRate, true, 14, true, true, QString(), QString()); powerspectrum->registerChange(); powerspectrum->unlock(); VectorPtr ev=0; if ( !_overrideStyle ) { _useBargraph=false; _useLines = true; _usePoints = false; } createCurveInPlot(powerspectrum->vX(), powerspectrum->vY(), ev); dataPlotted = true; } new_fileList = true; _overrideStyle = false; } } else if (arg == "-h") { QString field; *ok = _setStringArg(field,i18n("Usage: -h \n")); if (!*ok) { for ( int i_file=0; i_file<_fileNames.size(); i_file++ ) { QString file = _fileNames.at ( i_file ); QFileInfo info ( file ); if ( !info.exists() || !info.isFile() ) { printUsage ( i18n ( "file %1 does not exist\n" ).arg ( file ) ); *ok = false; break; } DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource ( _document->objectStore(), file ); DataVectorPtr hv = createOrFindDataVector ( field, ds ); Q_ASSERT ( _document && _document->objectStore() ); HistogramPtr histogram = _document->objectStore()->createObject (); histogram->change(hv, -1, 1, 60, Histogram::Number, true); histogram->writeLock(); histogram->registerChange(); histogram->unlock(); VectorPtr ev=0; if ( !_overrideStyle ) { _useBargraph=true; _useLines = false; _usePoints = false; } createCurveInPlot(histogram->vX(), histogram->vY(), ev); dataPlotted = true; } new_fileList = true; _overrideStyle = false; } } else if (arg == "-z") { QString field; *ok = _setStringArg(field,i18n("Usage: -z \n")); if (*ok) { for (int i_file=0; i_file<_fileNames.size(); i_file++) { QString file = _fileNames.at(i_file); QFileInfo info(file); if (!info.exists() || !info.isFile()) { printUsage(i18n("file %1 does not exist\n").arg(file)); *ok = false; break; } DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), file); DataMatrixPtr dm = _document->objectStore()->createObject(); dm->writeLock(); dm->change(ds, field, 0, 0, -1, -1, _doAve, _skip>0, _skip, 0.0, 0.0, 1.0, 1.0); dm->registerChange(); dm->unlock(); createImageInPlot(dm); } new_fileList = true; dataPlotted = true; } } else if (arg == "-F") { *ok = _setStringArg(_document->objectStore()->override.fileName, i18n("Usage: -F \n")); } else if (arg == "--png") { *ok = _setStringArg(_pngFile, i18n("Usage: --png \n")); } else if (arg == "--print") { *ok = _setStringArg(_printFile, i18n("Usage: --print \n")); } else if (arg == "--landscape") { _landscape = true; } else if (arg == "--portrait") { _landscape = false; } else if (arg == "--A4") { _paperSize = QPrinter::A4; } else if (arg == "--letter") { _paperSize = QPrinter::Letter; } else { // arg is not an option... must be a file if (new_fileList) { // if the file list has been used, clear it. _fileNames.clear(); new_fileList = false; } _fileNames.append(arg); if (!arg.endsWith(".kst") && _arguments.count() == 0) { // try loading data without user interaction DataSourcePtr ds = DataSourcePluginManager::findOrLoadSource(_document->objectStore(), arg); if (ds) { ObjectList curves = ds->autoCurves(*_document->objectStore()); if (curves.isEmpty()) { curves = autoCurves(ds); } int curve_count = 0; foreach(const ObjectPtr& ptr, curves) { if (kst_cast(ptr)) { curve_count++; } } if (curve_count > 0) { _mainWindow->updateRecentDataFiles(arg); int count = 0; const int max_count = 6 * 6; bool asked = false; foreach(const ObjectPtr& ptr, curves) { if (kst_cast(ptr)) { if (!asked && count >= max_count) { asked = true; QMessageBox::StandardButton res = QMessageBox::question(0, "Kst reading datafile", QString( "Kst found %1 Curves in the specified data file.\n" "Should Kst plot all %1 curves?\n" "If not, Kst plots only %2 curves.").arg(curve_count).arg(max_count), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (res == QMessageBox::No) { break; } } addCurve(kst_cast(ptr)); count++; } } } } } } } // set defaults to match what has been set. _dialogDefaults->setValue("print/landscape", _landscape); _dialogDefaults->setValue("print/paperSize", int(_paperSize)); if (_plotItem) { _plotItem->view()->resetPlotFontSizes(); } UpdateManager::self()->doUpdates(true); return (dataPlotted); } Kst::ObjectList CommandLineParser::autoCurves(DataSourcePtr ds) { QStringList fieldList = ds->vector().list(); if (fieldList.isEmpty()) { return ObjectList(); } ObjectList curves; DataVectorPtr xv = _document->objectStore()->createObject(); xv->writeLock(); xv->change(ds, "INDEX", 0, -1, 0, false, false); xv->registerChange(); xv->unlock(); foreach(const QString& field, fieldList) { if (field != "INDEX") { DataVectorPtr yv= _document->objectStore()->createObject(); yv->writeLock(); yv->change(ds, field, 0, -1, 0, false, false); yv->registerChange(); yv->unlock(); CurvePtr curve = _document->objectStore()->createObject(); curve->setXVector(xv); curve->setYVector(yv); curve->setXError(0); curve->setXMinusError(0); curve->setYMinusError(0); curve->setColor(Kst::ColorSequence::self().next()); curve->setLineWidth(1); curve->writeLock(); curve->registerChange(); curve->unlock(); curves << curve; } } return curves; } } kst-2.0.3/src/libkstapp/changefiledialog.h000644 001750 001750 00000003557 11544160207 021101 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CHANGEFILEDIALOG_H #define CHANGEFILEDIALOG_H #include #include "vector.h" #include "matrix.h" #include "relation.h" #include "datasource.h" #include "ui_changefiledialog.h" #include "kst_export.h" namespace Kst { class ObjectStore; class ChangeFileDialog : public QDialog, Ui::ChangeFileDialog { Q_OBJECT public: ChangeFileDialog(QWidget *parent); virtual ~ChangeFileDialog(); void show(); private Q_SLOTS: void fileNameChanged(const QString &file); void sourceValid(QString filename, int requestID); void addButtonClicked(); void removeButtonClicked(); void addAll(); void removeAll(); void selectAllFromFile(); void availableDoubleClicked(QListWidgetItem * item); void selectedDoubleClicked(QListWidgetItem * item); void showConfigWidget(); void updateButtons(); void OKClicked(); void apply(); private: void updatePrimitiveList(); ObjectStore *_store; DataSourcePtr _dataSource; int _requestID; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dimensionstab.cpp000644 001750 001750 00000005407 11544160207 021022 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "dimensionstab.h" namespace Kst { DimensionsTab::DimensionsTab(ViewItem* viewItem, QWidget *parent) : DialogTab(parent), _viewItem(viewItem) { setupUi(this); setTabTitle(tr("Dimensions")); connect(_fixAspectRatio, SIGNAL(toggled(bool)), this, SLOT(updateButtons())); } DimensionsTab::~DimensionsTab() { } void DimensionsTab::setupDimensions() { _x->setValue(_viewItem->relativeCenter().x()); _y->setValue(_viewItem->relativeCenter().y()); _width->setValue(_viewItem->relativeWidth()); _height->setValue(_viewItem->relativeHeight()); _rotation->setValue(_viewItem->rotationAngle()); _fixAspectRatio->setChecked(_viewItem->lockAspectRatio()); _fixAspectRatio->setEnabled(!_viewItem->lockAspectRatioFixed()); _fixAspectRatio->setTristate(false); _height->setHidden(_viewItem->lockAspectRatio()); _dimXlabel->setHidden(_viewItem->lockAspectRatio()); if (_viewItem->fixedSize()) { _height->setHidden(true); _dimXlabel->setHidden(true); _width->setEnabled(false); _fixAspectRatio->setHidden(true); } } void DimensionsTab::updateButtons() { _height->setHidden(_fixAspectRatio->checkState() == Qt::Checked); _dimXlabel->setHidden(_fixAspectRatio->checkState() == Qt::Checked); } void DimensionsTab::modified() { emit tabModified(); } void DimensionsTab::clearTabValues() { _fixAspectRatio->setCheckState(Qt::PartiallyChecked); _width->clear(); _height->clear(); _rotation->clear(); } void DimensionsTab::enableSingleEditOptions(bool enabled) { _x->setEnabled(enabled); _y->setEnabled(enabled); } bool DimensionsTab::widthDirty() const { return (!_width->text().isEmpty()); } bool DimensionsTab::heightDirty() const { return (!_height->text().isEmpty()); } bool DimensionsTab::rotationDirty() const { return (!_rotation->text().isEmpty()); } bool DimensionsTab::fixedAspectDirty() const { return _fixAspectRatio->checkState() != Qt::PartiallyChecked; } } kst-2.0.3/src/libkstapp/editmultiplewidget.h000644 001750 001750 00000002776 11544160207 021543 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EDITMULTIPLEWIDGET_H #define EDITMULTIPLEWIDGET_H #include #include "ui_editmultiplewidget.h" #include "kst_export.h" namespace Kst { class EditMultipleWidget : public QWidget, public Ui::EditMultipleWidget { Q_OBJECT public: EditMultipleWidget(QWidget *parent = 0); virtual ~EditMultipleWidget(); // void addObjects(QStringList &objects); void clearObjects(); void addObject(QString name, QString descriptionTip); QStringList selectedObjects() const; void selectObjects(const QStringList &objects); private Q_SLOTS: void selectAllObjects(); void applyFilter(const QString &filter); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datasourcedialog.h000644 001750 001750 00000003044 11544160207 021135 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATASOURCEDIALOG_H #define DATASOURCEDIALOG_H #include #include "kst_export.h" #include "datadialog.h" #include "datasource.h" class QAbstractButton; class QDialogButtonBox; namespace Kst { class DataSourceDialog : public QDialog { Q_OBJECT public: DataSourceDialog(DataDialog::EditMode mode, DataSourcePtr dataSource, QWidget *parent = 0); virtual ~DataSourceDialog(); DataSourcePtr dataSource() const { return _dataSource; } Q_SIGNALS: void ok(); void cancel(); private Q_SLOTS: void disableReuse(); void buttonClicked(QAbstractButton *button); private: DataSourcePtr _dataSource; QDialogButtonBox *_buttonBox; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/childviewoptionstab.ui000644 001750 001750 00000001624 11544160207 022074 0ustar00synthsynth000000 000000 ChildViewOptionsTab 0 0 212 131 Form Share axis when possible Qt::Vertical 20 40 kst-2.0.3/src/libkstapp/pluginmenuitemaction.h000644 001750 001750 00000002403 11544160207 022061 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLUGINMENUITEMACTION_H #define PLUGINMENUITEMACTION_H #include namespace Kst { class PluginMenuItemAction : public QAction { Q_OBJECT public: explicit PluginMenuItemAction(const QString &text, QWidget *parent = 0); Q_SIGNALS: void triggered(QString &name); public Q_SLOTS: void triggerWithName(); private: QString m_text; }; } #endif // PLUGINMENUITEMACTION_H // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datawizardpagedatasource.ui000644 001750 001750 00000013125 11544160207 023054 0ustar00synthsynth000000 000000 DataWizardPageDataSource 0 0 670 420 660 350 0 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Please select a </span><span style=" font-size:8pt; font-style:italic;">data source</span><span style=" font-size:8pt;"> to work from. This will typically be your file containing data points or vectors.</span></p></body></html> Qt::AlignTop true 0 0 30 24 Qt::Horizontal 40 20 10 0 Unknown file type false false 0 0 Con&figure... Qt::Horizontal 40 20 10 0 Update type; use 'Time Interval' for non-local data false 0 0 Qt::Vertical 20 322 Kst::DataSourceSelector QWidget
datasourceselector.h
kst-2.0.3/src/libkstapp/datagui.cpp000644 001750 001750 00000004160 11544160207 017574 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datagui.h" #include "application.h" #include "mainwindow.h" #include "tabwidget.h" #include "view.h" #include "viewitem.h" #include "viewgridlayout.h" #include "plotitem.h" #include "plotitemmanager.h" namespace Kst { DataGui::DataGui() { } DataGui::~DataGui() { } QList DataGui::plotList() const { QList plots; View *view = kstApp->mainWindow()->tabWidget()->currentView(); if (!view) return plots; QList list = PlotItemManager::plotsForView(view); foreach (PlotItem *plotItem, list) { plots << plotItem; } return plots; } int DataGui::rows() const { return -1; } int DataGui::columns() const { return -1; } void DataGui::removeCurveFromPlots(Relation *relation) { View *view = kstApp->mainWindow()->tabWidget()->currentView(); if (view) { QList list = PlotItemManager::plotsForView(view); foreach (PlotItem *plotItem, list) { bool plotUpdated = false; foreach (PlotRenderItem* renderItem, plotItem->renderItems()) { if (renderItem->relationList().contains(relation)) { renderItem->removeRelation(relation); plotUpdated = true; } } if (plotUpdated) { plotItem->update(); } } } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/childviewoptionstab.cpp000644 001750 001750 00000002541 11544160207 022240 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "childviewoptionstab.h" namespace Kst { ChildViewOptionsTab::ChildViewOptionsTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("Child View Options")); connect(_shareAxis, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); } ChildViewOptionsTab::~ChildViewOptionsTab() { } bool ChildViewOptionsTab::shareAxis() const { return _shareAxis->isChecked(); } void ChildViewOptionsTab::setShareAxis(bool shareAxis) { _shareAxis->setChecked(shareAxis); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labeltab.ui000644 001750 001750 00000025035 11544160207 017563 0ustar00synthsynth000000 000000 LabelTab 0 0 584 366 Form Default plot font &size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _globalLabelFontSize 1 -25.000000000000000 Automatically scale number axis labels 0 0 Qt::Horizontal Insert scalar in label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Insert string in label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false &Top label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _topLabelText false Botto&m label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _bottomLabelText false Auto true &Left label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _leftLabelText false Auto true &Right label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _rightLabelText false Auto true 0 0 Qt::Horizontal 0 0 0 Show le&gend 0 0 E&dit Qt::Vertical 20 40 Qt::Horizontal 376 0 Auto true 0 0 22 22 Alt+I true 0 0 22 22 Alt+B true points Kst::ColorButton QToolButton
colorbutton.h
Kst::ScalarSelector QWidget
scalarselector.h
Kst::StringSelector QWidget
stringselector.h
Kst::LabelLineEdit QLineEdit
labellineedit.h
_topLabelText _bottomLabelText _leftLabelText _rightLabelText _globalLabelFontSize _globalLabelBold _globalLabelItalic _globalLabelColor _globalLabelFontFamily _showLegend _editLegendContents
kst-2.0.3/src/libkstapp/legenditemdialog.h000644 001750 001750 00000003012 11544160207 021113 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LEGENDITEMDIALOG_H #define LEGENDITEMDIALOG_H #include "viewitemdialog.h" #include "kst_export.h" namespace Kst { class LegendTab; class LegendItem; class ObjectStore; class LegendItemDialog : public ViewItemDialog { Q_OBJECT public: explicit LegendItemDialog(LegendItem *item, QWidget *parent = 0); virtual ~LegendItemDialog(); private Q_SLOTS: void legendChanged(); void editMultiple(); void editSingle(); void slotApply(); private: void setupLegend(); void saveLegend(LegendItem *item, bool save_relations); private: LegendItem* _legendItem; LegendTab *_legendTab; ObjectStore* _store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datatab.cpp000644 001750 001750 00000002246 11544160207 017561 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datatab.h" #include "datadialog.h" namespace Kst { DataTab::DataTab(QWidget *parent) : DialogTab(parent) { } DataTab::~DataTab() { } void DataTab::setObjectStore(ObjectStore *store) { Q_UNUSED(store); } DataDialog *DataTab::dataDialog() const { return qobject_cast(dialog()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/eventmonitordialog.cpp000644 001750 001750 00000030160 11544160207 022066 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "eventmonitordialog.h" #include "dialogpage.h" #include "editmultiplewidget.h" #include "datacollection.h" #include "document.h" #include "objectstore.h" #include "eventmonitorentry.h" namespace Kst { EventMonitorTab::EventMonitorTab(QWidget *parent) : DataTab(parent), _logLevelDirty(false) { setupUi(this); setTabTitle(tr("Event Monitor")); connect(_equation, SIGNAL(textChanged(const QString &)), this, SLOT(selectionChanged())); connect(_equationOperator, SIGNAL(activated(QString)), this, SLOT(equationOperatorUpdate(const QString&))); connect(_vectorSelector, SIGNAL(selectionChanged(QString)), this, SLOT(equationUpdate(const QString&))); connect(_scalarSelector, SIGNAL(selectionChanged(QString)), this, SLOT(equationUpdate(const QString&))); connect(_debugLog, SIGNAL(toggled(const bool&)), this, SIGNAL(modified())); connect(_emailNotify, SIGNAL(toggled(const bool&)), this, SIGNAL(modified())); connect(_ELOGNotify, SIGNAL(toggled(const bool&)), this, SIGNAL(modified())); connect(_executeScript, SIGNAL(toggled(const bool&)), this, SIGNAL(modified())); connect(_equation, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_description, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_emailRecipients, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_script, SIGNAL(textChanged()), this, SIGNAL(modified())); connect(_debugLogNotice, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_debugLogWarning, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_debugLogError, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_debugLogNotice, SIGNAL(clicked()), this, SLOT(logLevelChanged())); connect(_debugLogWarning, SIGNAL(clicked()), this, SLOT(logLevelChanged())); connect(_debugLogError, SIGNAL(clicked()), this, SLOT(logLevelChanged())); } EventMonitorTab::~EventMonitorTab() { } void EventMonitorTab::selectionChanged() { emit optionsChanged(); } void EventMonitorTab::equationUpdate(const QString& string) { QString equation = _equation->text(); equation += '[' + string + ']'; _equation->setText(equation); } void EventMonitorTab::equationOperatorUpdate(const QString& string) { QString equation = _equation->text(); equation += string; _equation->setText(equation); } void EventMonitorTab::logLevelChanged() { _logLevelDirty = true; } void EventMonitorTab::resetLogLevelDirty() { _logLevelDirty = false; } QString EventMonitorTab::script() const { return _script->toPlainText(); } bool EventMonitorTab::scriptDirty() const { return !_script->toPlainText().isEmpty(); } void EventMonitorTab::setScript(const QString script) { return _script->setText(script); } QString EventMonitorTab::event() const { return _equation->text(); } bool EventMonitorTab::eventDirty() const { return !_equation->text().isEmpty(); } void EventMonitorTab::setEvent(const QString event) { return _equation->setText(event); } QString EventMonitorTab::description() const { return _description->text(); } bool EventMonitorTab::descriptionDirty() const { return !_description->text().isEmpty(); } void EventMonitorTab::setDescription(const QString description) { return _description->setText(description); } QString EventMonitorTab::emailRecipients() const { return _emailRecipients->text(); } bool EventMonitorTab::emailRecipientsDirty() const { return !_emailRecipients->text().isEmpty(); } void EventMonitorTab::setEmailRecipients(const QString emailRecipients) { return _emailRecipients->setText(emailRecipients); } Debug::LogLevel EventMonitorTab::logLevel() const { if (_debugLogNotice->isChecked()) { return Debug::Notice; } else if (_debugLogWarning->isChecked()) { return Debug::Warning; } else { return Debug::Error; } } bool EventMonitorTab::logLevelDirty() const { return _logLevelDirty; } void EventMonitorTab::setLogLevel(const Debug::LogLevel logLevel) { switch (logLevel) { case Debug::Notice: _debugLogNotice->setChecked(true); break; case Debug::Warning: _debugLogWarning->setChecked(true); break; case Debug::Error: _debugLogError->setChecked(true); break; default: break; } resetLogLevelDirty(); } bool EventMonitorTab::logDebug() const { return _debugLog->isChecked(); } bool EventMonitorTab::logDebugDirty() const { return _debugLog->checkState() != Qt::PartiallyChecked; } void EventMonitorTab::setLogDebug(const bool logDebug) { return _debugLog->setChecked(logDebug); } bool EventMonitorTab::logEMail() const { return _emailNotify->isChecked(); } bool EventMonitorTab::logEMailDirty() const { return _emailNotify->checkState() != Qt::PartiallyChecked; } void EventMonitorTab::setLogEMail(const bool logEMail) { return _emailNotify->setChecked(logEMail); } bool EventMonitorTab::logELOG() const { return _ELOGNotify->isChecked(); } bool EventMonitorTab::logELOGDirty() const { return _ELOGNotify->checkState() != Qt::PartiallyChecked; } void EventMonitorTab::setLogELOG(const bool logELOG) { return _ELOGNotify->setChecked(logELOG); } void EventMonitorTab::setObjectStore(ObjectStore *store) { _vectorSelector->setObjectStore(store); _scalarSelector->setObjectStore(store); } void EventMonitorTab::clearTabValues() { _equation->clear(); _emailRecipients->clear(); _description->clear(); _script->clear(); _executeScript->setCheckState(Qt::PartiallyChecked); _ELOGNotify->setCheckState(Qt::PartiallyChecked); _emailNotify->setCheckState(Qt::PartiallyChecked); _debugLog->setCheckState(Qt::PartiallyChecked); resetLogLevelDirty(); } EventMonitorDialog::EventMonitorDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Event Monitor")); else setWindowTitle(tr("New Event Monitor")); _eventMonitorTab = new EventMonitorTab(this); addDataTab(_eventMonitorTab); if (editMode() == Edit) { configureTab(dataObject); } connect(_eventMonitorTab, SIGNAL(optionsChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_eventMonitorTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } EventMonitorDialog::~EventMonitorDialog() { } // QString EventMonitorDialog::tagString() const { // return DataDialog::tagString(); // } void EventMonitorDialog::editMultipleMode() { _eventMonitorTab->clearTabValues(); } void EventMonitorDialog::editSingleMode() { configureTab(dataObject()); } void EventMonitorDialog::configureTab(ObjectPtr object) { if (EventMonitorEntryPtr eventMonitorEntry = kst_cast(object)) { _eventMonitorTab->setScript(eventMonitorEntry->scriptCode()); _eventMonitorTab->setEvent(eventMonitorEntry->event()); _eventMonitorTab->setDescription(eventMonitorEntry->description()); _eventMonitorTab->setLogLevel(eventMonitorEntry->level()); _eventMonitorTab->setLogDebug(eventMonitorEntry->logDebug()); _eventMonitorTab->setLogEMail(eventMonitorEntry->logEMail()); _eventMonitorTab->setLogELOG(eventMonitorEntry->logELOG()); _eventMonitorTab->setEmailRecipients(eventMonitorEntry->eMailRecipients()); if (_editMultipleWidget) { EventMonitorEntryList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(EventMonitorEntryPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } void EventMonitorDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!_eventMonitorTab->event().isEmpty() || (editMode() == EditMultiple)); } ObjectPtr EventMonitorDialog::createNewDataObject() { Q_ASSERT(_document && _document->objectStore()); EventMonitorEntryPtr eventMonitor = _document->objectStore()->createObject(); eventMonitor->setScriptCode(_eventMonitorTab->script()); eventMonitor->setEvent(_eventMonitorTab->event()); eventMonitor->setDescription(_eventMonitorTab->description()); eventMonitor->setLevel(_eventMonitorTab->logLevel()); eventMonitor->setLogDebug(_eventMonitorTab->logDebug()); eventMonitor->setLogEMail(_eventMonitorTab->logEMail()); eventMonitor->setLogELOG(_eventMonitorTab->logELOG()); eventMonitor->setEMailRecipients(_eventMonitorTab->emailRecipients()); eventMonitor->reparse(); eventMonitor->writeLock(); eventMonitor->registerChange(); eventMonitor->unlock(); return ObjectPtr(eventMonitor.data()); } ObjectPtr EventMonitorDialog::editExistingDataObject() const { if (EventMonitorEntryPtr eventMonitor = kst_cast(dataObject())) { if (editMode() == EditMultiple) { QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { EventMonitorEntryPtr eventMonitor = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (eventMonitor) { const QString script = _eventMonitorTab->scriptDirty() ? _eventMonitorTab->script() : eventMonitor->scriptCode(); const QString event = _eventMonitorTab->eventDirty() ? _eventMonitorTab->event() : eventMonitor->event(); const QString description = _eventMonitorTab->descriptionDirty() ? _eventMonitorTab->description() : eventMonitor->description(); const QString emailRecipients = _eventMonitorTab->emailRecipientsDirty() ? _eventMonitorTab->emailRecipients() : eventMonitor->eMailRecipients(); const Debug::LogLevel logLevel = _eventMonitorTab->logLevelDirty() ? _eventMonitorTab->logLevel() : eventMonitor->level(); const bool logDebug = _eventMonitorTab->logDebugDirty() ? _eventMonitorTab->logDebug() : eventMonitor->logDebug(); const bool logEMail = _eventMonitorTab->logEMailDirty() ? _eventMonitorTab->logEMail() : eventMonitor->logEMail(); const bool logELOG = _eventMonitorTab->logELOGDirty() ? _eventMonitorTab->logELOG() : eventMonitor->logELOG(); eventMonitor->writeLock(); eventMonitor->setScriptCode(script); eventMonitor->setEvent(event); eventMonitor->setDescription(description); eventMonitor->setLevel(logLevel); eventMonitor->setLogDebug(logDebug); eventMonitor->setLogEMail(logEMail); eventMonitor->setLogELOG(logELOG); eventMonitor->setEMailRecipients(emailRecipients); eventMonitor->reparse(); eventMonitor->registerChange(); eventMonitor->unlock(); } } } else { eventMonitor->writeLock(); eventMonitor->setScriptCode(_eventMonitorTab->script()); eventMonitor->setEvent(_eventMonitorTab->event()); eventMonitor->setDescription(_eventMonitorTab->description()); eventMonitor->setLevel(_eventMonitorTab->logLevel()); eventMonitor->setLogDebug(_eventMonitorTab->logDebug()); eventMonitor->setLogEMail(_eventMonitorTab->logEMail()); eventMonitor->setLogELOG(_eventMonitorTab->logELOG()); eventMonitor->setEMailRecipients(_eventMonitorTab->emailRecipients()); eventMonitor->reparse(); eventMonitor->registerChange(); eventMonitor->unlock(); } } return dataObject();} } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/boxitem.h000644 001750 001750 00000003230 11544160207 017267 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BOXITEM_H #define BOXITEM_H #include "viewitem.h" #include "graphicsfactory.h" namespace Kst { class BoxItem : public ViewItem { Q_OBJECT public: BoxItem(View *parent); virtual ~BoxItem(); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); }; class CreateBoxCommand : public CreateCommand { public: CreateBoxCommand() : CreateCommand(QObject::tr("Create Box")) {} CreateBoxCommand(View *view) : CreateCommand(view, QObject::tr("Create Box")) {} virtual ~CreateBoxCommand() {} virtual void createItem(); }; class BoxItemFactory : public GraphicsFactory { public: BoxItemFactory(); ~BoxItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/logdialog.ui000644 001750 001750 00000031116 11544160207 017753 0ustar00synthsynth000000 000000 LogDialog 0 0 644 421 Make a log entry false 0 0 &Rerun Script Script: Qt::Horizontal 321 21 &Apply &Close 0 Message &Message: _message Clear Script output: Configuration Plot Properties &Width: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _xSize Qt::Horizontal 250 20 Width and Maintain Aspect Ratio Height and Maintain Aspect Ratio Width and Height Size of Square 0 0 &Height: false _ySize Height of the image (in pixels). 5 10000 20 768 0 0 &File format: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _formats 0 0 S&pecify: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _sizeOption Width (in Pixels) of the image. 5 10000 20 1024 0 0 Local log directory: false &Script: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _script The variables $user, $imagefile and $messagefile can be used in the argument list. &User name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _user Qt::Vertical 20 40 Kst::FileRequester QWidget
filerequester.h
_message pushButton _tab _apply _close _rerunScript _scriptOutput _sizeOption _formats _xSize _ySize _script _user _close clicked() LogDialog close() 629 380 256 328 pushButton clicked() _message clear() 419 50 137 109
kst-2.0.3/src/libkstapp/stroketab.ui000644 001750 001750 00000007520 11544160207 020012 0ustar00synthsynth000000 000000 StrokeTab 0 0 386 218 Form &Style: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _style 0 0 &Width: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _width Brush &color: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _brushColor &Brush style: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _brushStyle &Join style: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _joinStyle Ca&p style: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _capStyle Qt::Vertical 20 40 Kst::ColorButton QToolButton
colorbutton.h
kst-2.0.3/src/libkstapp/csddialog.h000644 001750 001750 00000004275 11544160207 017563 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CSDDIALOG_H #define CSDDIALOG_H #include "datadialog.h" #include "datatab.h" #include "csd.h" #include "ui_csdtab.h" #include #include "kst_export.h" namespace Kst { class CSDTab : public DataTab, Ui::CSDTab { Q_OBJECT public: CSDTab(QWidget *parent = 0); virtual ~CSDTab(); void setObjectStore(ObjectStore *store); VectorPtr vector() const; bool vectorDirty() const; void setVector(const VectorPtr vector); int windowSize() const; bool windowSizeDirty() const; void setWindowSize(const int windowSize); CurvePlacement* curvePlacement() const; FFTOptions* FFTOptionsWidget() const; ColorPalette* colorPalette() const; void hideImageOptions(); void clearTabValues(); private Q_SLOTS: void selectionChanged(); Q_SIGNALS: void optionsChanged(); }; class CSDDialog : public DataDialog { Q_OBJECT public: explicit CSDDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~CSDDialog(); void setVector(VectorPtr vector); protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: void configureTab(ObjectPtr object); CSDTab *_CSDTab; }; } #endif kst-2.0.3/src/libkstapp/plotitemdialog.cpp000644 001750 001750 00000115656 11544160207 021210 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "plotitemdialog.h" #include "contenttab.h" #include "axistab.h" #include "rangetab.h" #include "markerstab.h" #include "labeltab.h" #include "overridelabeltab.h" #include "dialogpage.h" #include "application.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" #include "curve.h" #include "curvedialog.h" #include "plotrenderitem.h" #include "plotitem.h" #include "image.h" #include "imagedialog.h" #include "filltab.h" #include "stroketab.h" #include "math_kst.h" namespace Kst { PlotItemDialog::PlotItemDialog(PlotItem *item, QWidget *parent) : ViewItemDialog(item, parent), _plotItem(item), _defaultTagString("") { Q_ASSERT(_plotItem); _store = kstApp->mainWindow()->document()->objectStore(); setWindowTitle(tr("Edit Plot Item")); _contentTab = new ContentTab(this, _store); connect(_contentTab, SIGNAL(apply()), this, SLOT(contentChanged())); DialogPage *contentsPage = new DialogPage(this); contentsPage->setPageTitle(tr("Contents")); contentsPage->addDialogTab(_contentTab); addDialogPage(contentsPage, true); _labelTab = new LabelTab(_plotItem, this); _topLabelTab = new OverrideLabelTab(tr("Top Font"), this); _bottomLabelTab = new OverrideLabelTab(tr("Bottom Font"), this); _leftLabelTab = new OverrideLabelTab(tr("Left Font"), this); _rightLabelTab = new OverrideLabelTab(tr("Right Font"), this); _axisLabelTab = new OverrideLabelTab(tr("Axis Font"), this); _labelPage = new DialogPageTab(this); _labelPage->setPageTitle(tr("Labels")); _labelPage->addDialogTab(_labelTab); _labelPage->addDialogTab(_topLabelTab); _labelPage->addDialogTab(_bottomLabelTab); _labelPage->addDialogTab(_leftLabelTab); _labelPage->addDialogTab(_rightLabelTab); _labelPage->addDialogTab(_axisLabelTab); addDialogPage(_labelPage, true); connect(_labelTab, SIGNAL(apply()), this, SLOT(labelsChanged())); connect(_labelTab, SIGNAL(globalFontUpdate()), this, SLOT(globalFontUpdate())); connect(_topLabelTab, SIGNAL(useDefaultChanged(bool)), this, SLOT(useTopDefaultChanged(bool))); connect(_bottomLabelTab, SIGNAL(useDefaultChanged(bool)), this, SLOT(useBottomDefaultChanged(bool))); connect(_leftLabelTab, SIGNAL(useDefaultChanged(bool)), this, SLOT(useLeftDefaultChanged(bool))); connect(_rightLabelTab, SIGNAL(useDefaultChanged(bool)), this, SLOT(useRightDefaultChanged(bool))); connect(_axisLabelTab, SIGNAL(useDefaultChanged(bool)), this, SLOT(useAxisDefaultChanged(bool))); _rangeTab = new RangeTab(_plotItem, this); DialogPage *rangePage = new DialogPage(this); rangePage->setPageTitle(tr("Range/Zoom")); rangePage->addDialogTab(_rangeTab); addDialogPage(rangePage, true); connect(_rangeTab, SIGNAL(apply()), this, SLOT(rangeChanged())); _xAxisTab = new AxisTab(this); DialogPage *xAxisPage = new DialogPage(this); xAxisPage->setPageTitle(tr("X-Axis")); xAxisPage->addDialogTab(_xAxisTab); addDialogPage(xAxisPage, true); connect(_xAxisTab, SIGNAL(apply()), this, SLOT(xAxisChanged())); _yAxisTab = new AxisTab(this); _yAxisTab->setAsYAxis(); DialogPage *yAxisPage = new DialogPage(this); yAxisPage->setPageTitle(tr("Y-Axis")); yAxisPage->addDialogTab(_yAxisTab); addDialogPage(yAxisPage, true); connect(_yAxisTab, SIGNAL(apply()), this, SLOT(yAxisChanged())); _xMarkersTab = new MarkersTab(this); DialogPage *xMarkersPage = new DialogPage(this); xMarkersPage->setPageTitle(tr("X-Axis Markers")); xMarkersPage->addDialogTab(_xMarkersTab); addDialogPage(xMarkersPage, true); _xMarkersTab->setObjectStore(_store); connect(_xMarkersTab, SIGNAL(apply()), this, SLOT(xAxisPlotMarkersChanged())); _yMarkersTab = new MarkersTab(this); DialogPage *yMarkersPage = new DialogPage(this); yMarkersPage->setPageTitle(tr("Y-Axis Markers")); yMarkersPage->addDialogTab(_yMarkersTab); addDialogPage(yMarkersPage, true); _yMarkersTab->setObjectStore(_store); connect(yMarkersPage, SIGNAL(apply()), this, SLOT(yAxisPlotMarkersChanged())); // addRelations(); This tends to clutter the plot dialog, let's test skipping it setupContent(); setupAxis(); setupRange(); setupLabels(); setupMarkers(); setSupportsMultipleEdit(true); if (_plotItem->descriptiveNameIsManual()) { setTagString(_plotItem->descriptiveName()); } else { setTagString(_defaultTagString); } QList list = ViewItem::getItems(); clearMultipleEditOptions(); foreach(PlotItem* plot, list) { addMultipleEditOption(plot->plotName(), plot->descriptionTip(), plot->shortName()); } QList > moveItems; moveItems << _listWidget->findItems("Appearance", Qt::MatchFixedString); moveItems << _listWidget->findItems("Dimensions", Qt::MatchFixedString); foreach(const QList& found, moveItems) { if (found.size() > 0) { _listWidget->addItem(_listWidget->takeItem(_listWidget->row(found.first()))); } } selectDialogPage(contentsPage); _saveAsDefault->show(); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultiple())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingle())); connect(this, SIGNAL(apply()), this, SLOT(slotApply())); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // Make sure the labels are visible, doesn't work right now :-) } PlotItemDialog::~PlotItemDialog() { } void PlotItemDialog::editMultiple() { _xAxisTab->clearTabValues(); _yAxisTab->clearTabValues(); _rangeTab->clearTabValues(); _labelTab->clearTabValues(); _labelTab->enableSingleEditOptions(false); _topLabelTab->clearTabValues(); _bottomLabelTab->clearTabValues(); _leftLabelTab->clearTabValues(); _rightLabelTab->clearTabValues(); _axisLabelTab->clearTabValues(); _xMarkersTab->clearTabValues(); _yMarkersTab->clearTabValues(); _contentTab->setEnabled(false); foreach(DialogPage* page, _relationPages) { removeDialogPage(page); } _relationPages.clear(); } void PlotItemDialog::editSingle() { _contentTab->setEnabled(true); updateRelations(); setupContent(); setupAxis(); setupRange(); setupLabels(); setupMarkers(); setAlwaysAllowApply(false); } void PlotItemDialog::slotApply() { if (editMode() == Single) { _plotItem->setDescriptiveName(tagString().remove(_defaultTagString)); } //FIXME: it is not clear that slotApply must be executed last. // experimentally, it seems to be... if (_saveAsDefault->isChecked()) { _plotItem->saveAsDialogDefaults(); } } void PlotItemDialog::setupLabels() { Q_ASSERT(_plotItem); _labelTab->enableSingleEditOptions(true); _labelTab->setLeftLabel(_plotItem->leftLabel()); _labelTab->setBottomLabel(_plotItem->bottomLabel()); _labelTab->setTopLabel(_plotItem->topLabel()); _labelTab->setRightLabel(_plotItem->rightLabel()); _labelTab->setAutoScaleNumbers(_plotItem->isUseAxisScale()); _labelTab->setLeftLabelAuto(_plotItem->leftLabelDetails()->isAuto()); _labelTab->setBottomLabelAuto(_plotItem->bottomLabelDetails()->isAuto()); _labelTab->setTopLabelAuto(_plotItem->topLabelDetails()->isAuto()); _labelTab->setRightLabelAuto(_plotItem->rightLabelDetails()->isAuto()); _labelTab->setShowLegend(_plotItem->showLegend()); _topLabelTab->enableSingleEditOptions(true); _topLabelTab->setUseDefault(_plotItem->topLabelDetails()->fontUseGlobal()); _topLabelTab->setLabelFont(_plotItem->topLabelDetails()->font()); _topLabelTab->setLabelFontScale(_plotItem->topLabelDetails()->fontScale()); _topLabelTab->setLabelColor(_plotItem->topLabelDetails()->fontColor()); _bottomLabelTab->enableSingleEditOptions(true); _bottomLabelTab->setUseDefault(_plotItem->bottomLabelDetails()->fontUseGlobal()); _bottomLabelTab->setLabelFont(_plotItem->bottomLabelDetails()->font()); _bottomLabelTab->setLabelFontScale(_plotItem->bottomLabelDetails()->fontScale()); _bottomLabelTab->setLabelColor(_plotItem->bottomLabelDetails()->fontColor()); _leftLabelTab->enableSingleEditOptions(true); _leftLabelTab->setUseDefault(_plotItem->leftLabelDetails()->fontUseGlobal()); _leftLabelTab->setLabelFont(_plotItem->leftLabelDetails()->font()); _leftLabelTab->setLabelFontScale(_plotItem->leftLabelDetails()->fontScale()); _leftLabelTab->setLabelColor(_plotItem->leftLabelDetails()->fontColor()); _rightLabelTab->enableSingleEditOptions(true); _rightLabelTab->setUseDefault(_plotItem->rightLabelDetails()->fontUseGlobal()); _rightLabelTab->setLabelFont(_plotItem->rightLabelDetails()->font()); _rightLabelTab->setLabelFontScale(_plotItem->rightLabelDetails()->fontScale()); _rightLabelTab->setLabelColor(_plotItem->rightLabelDetails()->fontColor()); _axisLabelTab->enableSingleEditOptions(true); _axisLabelTab->setUseDefault(_plotItem->numberLabelDetails()->fontUseGlobal()); _axisLabelTab->setLabelFont(_plotItem->numberLabelDetails()->font()); _axisLabelTab->setLabelFontScale(_plotItem->numberLabelDetails()->fontScale()); _axisLabelTab->setLabelColor(_plotItem->numberLabelDetails()->fontColor()); } void PlotItemDialog::setupRange() { _rangeTab->setupRange(); } void PlotItemDialog::setupAxis() { Q_ASSERT(_plotItem); _xAxisTab->enableSingleEditOptions(true); _xAxisTab->setAxisMajorTickSpacing(_plotItem->xAxis()->axisMajorTickMode()); _xAxisTab->setDrawAxisMajorTicks(_plotItem->xAxis()->drawAxisMajorTicks()); _xAxisTab->setDrawAxisMajorGridLines(_plotItem->xAxis()->drawAxisMajorGridLines()); _xAxisTab->setDrawAxisMinorTicks(_plotItem->xAxis()->drawAxisMinorTicks()); _xAxisTab->setDrawAxisMinorGridLines(_plotItem->xAxis()->drawAxisMinorGridLines()); _xAxisTab->setAutoMinorTickCount(_plotItem->xAxis()->axisAutoMinorTicks()); _xAxisTab->setAxisMajorGridLineColor(_plotItem->xAxis()->axisMajorGridLineColor()); _xAxisTab->setAxisMinorGridLineColor(_plotItem->xAxis()->axisMinorGridLineColor()); _xAxisTab->setAxisMajorGridLineWidth(_plotItem->xAxis()->axisMajorGridLineWidth()); _xAxisTab->setAxisMinorGridLineWidth(_plotItem->xAxis()->axisMinorGridLineWidth()); _xAxisTab->setAxisMajorGridLineStyle(_plotItem->xAxis()->axisMajorGridLineStyle()); _xAxisTab->setAxisMinorGridLineStyle(_plotItem->xAxis()->axisMinorGridLineStyle()); _xAxisTab->setLog(_plotItem->xAxis()->axisLog()); _xAxisTab->setReversed(_plotItem->xAxis()->axisReversed()); _xAxisTab->setAutoBaseOffset(_plotItem->xAxis()->axisAutoBaseOffset()); _xAxisTab->setBaseOffset(_plotItem->xAxis()->axisBaseOffset()); _xAxisTab->setInterpret(_plotItem->xAxis()->axisInterpret()); _xAxisTab->setAxisDisplay(_plotItem->xAxis()->axisDisplay()); _xAxisTab->setAxisInterpretation(_plotItem->xAxis()->axisInterpretation()); _xAxisTab->setHideTopRight(_plotItem->manuallyHideTopAxisLabel()); _xAxisTab->setHideBottomLeft(_plotItem->manuallyHideBottomAxisLabel()); _xAxisTab->setAxisMinorTickCount(_plotItem->xAxis()->axisMinorTickCount()); _xAxisTab->setSignificantDigits(_plotItem->xAxis()->axisSignificantDigits()); _xAxisTab->setLabelRotation(_plotItem->xAxis()->axisLabelRotation()); _yAxisTab->enableSingleEditOptions(true); _yAxisTab->setAxisMajorTickSpacing(_plotItem->yAxis()->axisMajorTickMode()); _yAxisTab->setDrawAxisMajorTicks(_plotItem->yAxis()->drawAxisMajorTicks()); _yAxisTab->setDrawAxisMajorGridLines(_plotItem->yAxis()->drawAxisMajorGridLines()); _yAxisTab->setDrawAxisMinorTicks(_plotItem->yAxis()->drawAxisMinorTicks()); _yAxisTab->setAutoMinorTickCount(_plotItem->yAxis()->axisAutoMinorTicks()); _yAxisTab->setDrawAxisMinorGridLines(_plotItem->yAxis()->drawAxisMinorGridLines()); _yAxisTab->setAxisMajorGridLineColor(_plotItem->yAxis()->axisMajorGridLineColor()); _yAxisTab->setAxisMinorGridLineColor(_plotItem->yAxis()->axisMinorGridLineColor()); _yAxisTab->setAxisMajorGridLineWidth(_plotItem->yAxis()->axisMajorGridLineWidth()); _yAxisTab->setAxisMinorGridLineWidth(_plotItem->yAxis()->axisMinorGridLineWidth()); _yAxisTab->setAxisMajorGridLineStyle(_plotItem->yAxis()->axisMajorGridLineStyle()); _yAxisTab->setAxisMinorGridLineStyle(_plotItem->yAxis()->axisMinorGridLineStyle()); _yAxisTab->setLog(_plotItem->yAxis()->axisLog()); _yAxisTab->setReversed(_plotItem->yAxis()->axisReversed()); _yAxisTab->setAutoBaseOffset(_plotItem->yAxis()->axisAutoBaseOffset()); _yAxisTab->setBaseOffset(_plotItem->yAxis()->axisBaseOffset()); _yAxisTab->setInterpret(_plotItem->yAxis()->axisInterpret()); _yAxisTab->setAxisDisplay(_plotItem->yAxis()->axisDisplay()); _yAxisTab->setAxisInterpretation(_plotItem->yAxis()->axisInterpretation()); _yAxisTab->setHideTopRight(_plotItem->manuallyHideRightAxisLabel()); _yAxisTab->setHideBottomLeft(_plotItem->manuallyHideLeftAxisLabel()); _yAxisTab->setAxisMinorTickCount(_plotItem->yAxis()->axisMinorTickCount()); _yAxisTab->setSignificantDigits(_plotItem->yAxis()->axisSignificantDigits()); _yAxisTab->setLabelRotation(_plotItem->yAxis()->axisLabelRotation()); } void PlotItemDialog::setupMarkers() { Q_ASSERT(_plotItem); _xMarkersTab->enableSingleEditOptions(true); _xMarkersTab->setPlotMarkers(_plotItem->xAxis()->axisPlotMarkers()); _yMarkersTab->enableSingleEditOptions(true); _yMarkersTab->setPlotMarkers(_plotItem->yAxis()->axisPlotMarkers()); } void PlotItemDialog::setupContent() { QStringList displayedRelations; QStringList availableRelations; QStringList allRelations; QStringList displayedRelationTips; QStringList availableRelationTips; QStringList allRelationTips; CurveList curves = _store->getObjects(); ImageList images = _store->getObjects(); foreach (RelationPtr relation, _plotItem->renderItem(PlotRenderItem::Cartesian)->relationList()) { displayedRelations.append(relation->Name()); displayedRelationTips.append(relation->descriptionTip()); } foreach (CurvePtr curve, curves) { allRelations.append(curve->Name()); allRelationTips.append(curve->descriptionTip()); if (!displayedRelations.contains(curve->Name())) { availableRelations.append(curve->Name()); availableRelationTips.append(curve->descriptionTip()); } } foreach (ImagePtr image, images) { allRelations.append(image->Name()); allRelationTips.append(image->descriptionTip()); if (!displayedRelations.contains(image->Name())) { availableRelations.append(image->Name()); availableRelationTips.append(image->descriptionTip()); } } _contentTab->setDisplayedRelations(displayedRelations, displayedRelationTips); _contentTab->setAvailableRelations(availableRelations, availableRelationTips); } void PlotItemDialog::addRelations() { foreach (RelationPtr relation, _plotItem->renderItem(PlotRenderItem::Cartesian)->relationList()) { if (CurvePtr curve = kst_cast(relation)) { CurveTab* curveTab = new CurveTab(this); curveTab->setObjectStore(_store); curveTab->setXVector(curve->xVector()); curveTab->setYVector(curve->yVector()); if (curve->hasXError()) { curveTab->setXError(curve->xErrorVector()); } if (curve->hasYError()) { curveTab->setYError(curve->yErrorVector()); } if (curve->hasXMinusError()) { curveTab->setXMinusError(curve->xMinusErrorVector()); } if (curve->hasYMinusError()) { curveTab->setYMinusError(curve->yMinusErrorVector()); } curveTab->curveAppearance()->setColor(curve->color()); curveTab->curveAppearance()->setShowPoints(curve->hasPoints()); curveTab->curveAppearance()->setShowLines(curve->hasLines()); curveTab->curveAppearance()->setShowBars(curve->hasBars()); curveTab->curveAppearance()->setLineWidth(curve->lineWidth()); curveTab->curveAppearance()->setLineStyle(curve->lineStyle()); curveTab->curveAppearance()->setPointType(curve->pointType()); curveTab->curveAppearance()->setPointDensity(curve->pointDensity()); curveTab->curveAppearance()->setBarStyle(curve->barStyle()); curveTab->hidePlacementOptions(); DialogPage *curvePage = new DialogPage(this); curvePage->setPageTitle(curve->Name()); curvePage->addDialogTab(curveTab); addDialogPage(curvePage, false); _relationPages.append(curvePage); } else if (ImagePtr image = kst_cast(relation)) { ImageTab* imageTab = new ImageTab(this); imageTab->setObjectStore(_store); imageTab->setMatrix(image->matrix()); if (image->hasContourMap() && image->hasColorMap()) { imageTab->setColorAndContour(true); imageTab->setNumberOfContourLines(image->numContourLines()); imageTab->setContourColor(image->contourColor()); imageTab->setContourWeight(image->contourWeight()); imageTab->setLowerThreshold(image->lowerThreshold()); imageTab->setUpperThreshold(image->upperThreshold()); imageTab->setRealTimeAutoThreshold(image->autoThreshold()); imageTab->colorPalette()->setPalette(image->paletteName()); imageTab->setUseVariableLineWeight(image->contourWeight() == -1); } else if (image->hasContourMap()) { imageTab->setContourOnly(true); imageTab->setNumberOfContourLines(image->numContourLines()); imageTab->setContourColor(image->contourColor()); imageTab->setContourWeight(image->contourWeight()); imageTab->setUseVariableLineWeight(image->contourWeight() == -1); } else { imageTab->setColorOnly(true); imageTab->setLowerThreshold(image->lowerThreshold()); imageTab->setUpperThreshold(image->upperThreshold()); imageTab->setRealTimeAutoThreshold(image->autoThreshold()); imageTab->colorPalette()->setPalette(image->paletteName()); } imageTab->hidePlacementOptions(); DialogPage *imagePage = new DialogPage(this); imagePage->setPageTitle(image->Name()); imagePage->addDialogTab(imageTab); addDialogPage(imagePage, false); _relationPages.append(imagePage); } } } void PlotItemDialog::updateRelations() { foreach(DialogPage* page, _relationPages) { removeDialogPage(page); } _relationPages.clear(); addRelations(); } void PlotItemDialog::contentChanged() { relationChanged(); QStringList currentRelations; QStringList displayedRelations = _contentTab->displayedRelations(); foreach (RelationPtr relation, _plotItem->renderItem(PlotRenderItem::Cartesian)->relationList()) { currentRelations.append(relation->Name()); if (!displayedRelations.contains(relation->Name())) { _plotItem->renderItem(PlotRenderItem::Cartesian)->removeRelation(relation); _plotItem->update(); } } foreach (QString relationName, displayedRelations) { if (!currentRelations.contains(relationName)) { if (RelationPtr relation = kst_cast(_store->retrieveObject(relationName))) { _plotItem->renderItem(PlotRenderItem::Cartesian)->addRelation(relation); _plotItem->update(); } } } updateRelations(); } void PlotItemDialog::relationChanged() { foreach(DialogPage* page, _relationPages) { if (CurvePtr curve = kst_cast(_store->retrieveObject(page->pageTitle()))) { CurveTab* curveTab = static_cast(page->currentWidget()); if (curveTab) { curve->writeLock(); curve->setXVector(curveTab->xVector()); curve->setYVector(curveTab->yVector()); curve->setXError(curveTab->xError()); curve->setYError(curveTab->yError()); curve->setXMinusError(curveTab->xMinusError()); curve->setYMinusError(curveTab->yMinusError()); curve->setColor(curveTab->curveAppearance()->color()); curve->setHasPoints(curveTab->curveAppearance()->showPoints()); curve->setHasLines(curveTab->curveAppearance()->showLines()); curve->setHasBars(curveTab->curveAppearance()->showBars()); curve->setLineWidth(curveTab->curveAppearance()->lineWidth()); curve->setLineStyle(curveTab->curveAppearance()->lineStyle()); curve->setPointType(curveTab->curveAppearance()->pointType()); curve->setPointDensity(curveTab->curveAppearance()->pointDensity()); curve->setBarStyle(curveTab->curveAppearance()->barStyle()); curve->registerChange(); curve->unlock(); } } else if (ImagePtr image = kst_cast(_store->retrieveObject(page->pageTitle()))) { ImageTab* imageTab = static_cast(page->currentWidget()); if (imageTab) { image->writeLock(); if (imageTab->colorOnly()) { image->changeToColorOnly(imageTab->matrix(), imageTab->lowerThreshold(), imageTab->upperThreshold(), imageTab->realTimeAutoThreshold(), imageTab->colorPalette()->selectedPalette()); } else if (imageTab->contourOnly()) { image->changeToContourOnly(imageTab->matrix(), imageTab->numberOfContourLines(), imageTab->contourColor(), imageTab->useVariableLineWeight() ? -1 : imageTab->contourWeight()); } else { image->changeToColorAndContour(imageTab->matrix(), imageTab->lowerThreshold(), imageTab->upperThreshold(), imageTab->realTimeAutoThreshold(), imageTab->colorPalette()->selectedPalette(), imageTab->numberOfContourLines(), imageTab->contourColor(), imageTab->useVariableLineWeight() ? -1 : imageTab->contourWeight()); } image->registerChange(); image->unlock(); } } } } void PlotItemDialog::rangeChanged() { Q_ASSERT(_plotItem); if (editMode() == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { PlotItem* plotItem = (PlotItem*)item; saveRange(plotItem); } } else { saveRange(_plotItem); } kstApp->mainWindow()->document()->setChanged(true); } void PlotItemDialog::saveRange(PlotItem *item) { ZoomState zoomstate; double newXMin, newXMax; double newYMin, newYMax; zoomstate = item->currentZoomState(); qreal xRange = _rangeTab->xRangeDirty() ? _rangeTab->xRange() :fabs(item->xMax() - item->xMin()); qreal xMax = _rangeTab->xMaxDirty() ? _rangeTab->xMax() :item->xMax(); qreal xMin = _rangeTab->xMinDirty() ? _rangeTab->xMin() :item->xMin(); if (item->xAxis()->axisLog()) { if (xMax != item->xMax()) { xMax = pow(10, xMax); } else { xMax = item->projectionRect().right(); } if (xMin != item->xMin()) { xMin = pow(10, xMin); } else { xMin = item->projectionRect().left(); } } qreal yRange = _rangeTab->yRangeDirty() ? _rangeTab->yRange() :fabs(item->yMax() - item->yMin()); qreal yMax = _rangeTab->yMaxDirty() ? _rangeTab->yMax() :item->yMax(); qreal yMin = _rangeTab->yMinDirty() ? _rangeTab->yMin() :item->yMin(); if (item->yAxis()->axisLog()) { if (yMax != item->yMax()) { yMax = pow(10, yMax); } else { yMax = item->projectionRect().bottom(); } if (yMin != item->yMin()) { yMin = pow(10, yMin); } else { yMin = item->projectionRect().top(); } } zoomstate.item = item; if ((_rangeTab->xModeDirty() && _rangeTab->xMean()) || (!_rangeTab->xModeDirty() && zoomstate.xAxisZoomMode == PlotAxis::MeanCentered)) { if (item->xAxis()->axisLog()) { qreal min = (item->xMin() + item->xMax() - xRange) / 2.0; newXMin = pow(10, min); newXMax = pow(10, min+xRange); } else { newXMax = xRange; newXMin = (item->xMin() + item->xMax() - newXMax)/2.0; } } else { newXMin = qMin(xMax, xMin); newXMax = fabs(xMax - xMin); } if (newXMax == 0.0) newXMax = 0.2; if ((_rangeTab->yModeDirty() && _rangeTab->yMean()) || (!_rangeTab->yModeDirty() && zoomstate.yAxisZoomMode == PlotAxis::MeanCentered)) { if (item->yAxis()->axisLog()) { qreal min = (item->yMin() + item->yMax() - yRange) / 2.0; newYMin = pow(10, min); newYMax = pow(10, min+yRange); } else { newYMax = yRange; newYMin = (item->yMin() + item->yMax() - newYMax)/2.0; } } else { newYMin = qMin(yMax, yMin); newYMax = fabs(yMax - yMin); } if (newYMax == 0.0) newYMax = 0.2; PlotAxis::ZoomMode xZoomMode = item->yAxis()->axisZoomMode(); PlotAxis::ZoomMode yZoomMode = item->yAxis()->axisZoomMode(); if (_rangeTab->xModeDirty()) { if (_rangeTab->xAuto()) { xZoomMode = PlotAxis::Auto; } else if (_rangeTab->xSpike()) { xZoomMode = PlotAxis::SpikeInsensitive; } else if (_rangeTab->xBorder()) { xZoomMode = PlotAxis::AutoBorder; } else if (_rangeTab->xMean()) { xZoomMode = PlotAxis::MeanCentered; } else if (_rangeTab->xFixed()) { xZoomMode = PlotAxis::FixedExpression; } } if (_rangeTab->yModeDirty()) { if (_rangeTab->yAuto()) { yZoomMode = PlotAxis::Auto; } else if (_rangeTab->ySpike()) { yZoomMode = PlotAxis::SpikeInsensitive; } else if (_rangeTab->yBorder()) { yZoomMode = PlotAxis::AutoBorder; } else if (_rangeTab->yMean()) { yZoomMode = PlotAxis::MeanCentered; } else if (_rangeTab->yFixed()) { yZoomMode = PlotAxis::FixedExpression; } } QRectF newProjectionRect(newXMin, newYMin, newXMax, newYMax); if (_rangeTab->xModeDirty()) { if (xZoomMode == PlotAxis::Auto) { item->zoomXMaximum(); } else if (xZoomMode == PlotAxis::AutoBorder) { item->zoomXAutoBorder(); } else if (xZoomMode == PlotAxis::SpikeInsensitive) { item->zoomXNoSpike(); } } if (xZoomMode == PlotAxis::FixedExpression) { item->zoomXRange(newProjectionRect); } if (xZoomMode == PlotAxis::MeanCentered) { item->zoomXMeanCentered(_rangeTab->xRange()); } if (_rangeTab->yModeDirty()) { if (yZoomMode == PlotAxis::Auto) { item->zoomYMaximum(); } else if (yZoomMode == PlotAxis::AutoBorder) { item->zoomYAutoBorder(); } else if (yZoomMode == PlotAxis::SpikeInsensitive) { item->zoomYNoSpike(); } } if (yZoomMode == PlotAxis::FixedExpression) { item->zoomYRange(newProjectionRect); } if (yZoomMode == PlotAxis::MeanCentered) { item->zoomYMeanCentered(_rangeTab->yRange()); } } void PlotItemDialog::xAxisChanged() { Q_ASSERT(_plotItem); if (editMode() == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { PlotItem* plotItem = (PlotItem*)item; saveAxis(plotItem->xAxis(), _xAxisTab); plotItem->setProjectionRect(plotItem->projectionRect(), plotItem->xAxis()->isDirty()); if (_xAxisTab->hideBottomLeftDirty()) { plotItem->setManuallyHideBottomAxisLabel(_xAxisTab->hideBottomLeft()); } if (_xAxisTab->hideTopRightDirty()) { plotItem->setManuallyHideTopAxisLabel(_xAxisTab->hideTopRight()); } } } else { saveAxis(_plotItem->xAxis(), _xAxisTab); _plotItem->setProjectionRect(_plotItem->projectionRect(), _plotItem->xAxis()->isDirty()); _plotItem->setManuallyHideBottomAxisLabel(_xAxisTab->hideBottomLeft()); _plotItem->setManuallyHideTopAxisLabel(_xAxisTab->hideTopRight()); } kstApp->mainWindow()->document()->setChanged(true); } void PlotItemDialog::yAxisChanged() { Q_ASSERT(_plotItem); if (editMode() == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { PlotItem* plotItem = (PlotItem*)item; saveAxis(plotItem->yAxis(), _yAxisTab); plotItem->setProjectionRect(plotItem->projectionRect(), plotItem->yAxis()->isDirty()); if (_yAxisTab->hideBottomLeftDirty()) { plotItem->setManuallyHideLeftAxisLabel(_yAxisTab->hideBottomLeft()); } if (_yAxisTab->hideTopRightDirty()) { plotItem->setManuallyHideRightAxisLabel(_yAxisTab->hideTopRight()); } } } else { saveAxis(_plotItem->yAxis(), _yAxisTab); _plotItem->setProjectionRect(_plotItem->projectionRect(), _plotItem->yAxis()->isDirty()); _plotItem->setManuallyHideLeftAxisLabel(_yAxisTab->hideBottomLeft()); _plotItem->setManuallyHideRightAxisLabel(_yAxisTab->hideTopRight()); } kstApp->mainWindow()->document()->setChanged(true); } void PlotItemDialog::saveAxis(PlotAxis *axis, AxisTab *axisTab) { Q_ASSERT(axis); if (axisTab->axisMajorTickSpacingDirty()) { axis->setAxisMajorTickMode(axisTab->axisMajorTickSpacing()); } if (axisTab->drawAxisMajorTicksDirty()) { axis->setDrawAxisMajorTicks(axisTab->drawAxisMajorTicks()); } if (axisTab->drawAxisMajorGridLinesDirty()) { axis->setDrawAxisMajorGridLines(axisTab->drawAxisMajorGridLines()); } if (axisTab->drawAxisMinorTicksDirty()) { axis->setDrawAxisMinorTicks(axisTab->drawAxisMinorTicks()); } if (axisTab->drawAxisMinorGridLinesDirty()) { axis->setDrawAxisMinorGridLines(axisTab->drawAxisMinorGridLines()); } if (axisTab->axisMajorGridLineColorDirty()) { axis->setAxisMajorGridLineColor(axisTab->axisMajorGridLineColor()); } if (axisTab->axisMinorGridLineColorDirty()) { axis->setAxisMinorGridLineColor(axisTab->axisMinorGridLineColor()); } if (axisTab->axisMajorGridLineWidthDirty()) { axis->setAxisMajorGridLineWidth(axisTab->axisMajorGridLineWidth()); } if (axisTab->axisMinorGridLineWidthDirty()) { axis->setAxisMinorGridLineWidth(axisTab->axisMinorGridLineWidth()); } if (axisTab->axisMajorGridLineStyleDirty()) { axis->setAxisMajorGridLineStyle(axisTab->axisMajorGridLineStyle()); } if (axisTab->axisMinorGridLineStyleDirty()) { axis->setAxisMinorGridLineStyle(axisTab->axisMinorGridLineStyle()); } if (axisTab->isLogDirty()) { axis->setAxisLog(axisTab->isLog()); } if (axisTab->isReversedDirty()) { axis->setAxisReversed(axisTab->isReversed()); } if (axisTab->isInterpretDirty()) { axis->setAxisInterpret(axisTab->isInterpret()); } if (axisTab->axisDisplayDirty()) { axis->setAxisDisplay(axisTab->axisDisplay()); } if (axisTab->axisInterpretationDirty()) { axis->setAxisInterpretation(axisTab->axisInterpretation()); } if (axisTab->isBaseOffsetDirty()) { axis->setAxisBaseOffset(axisTab->isBaseOffset()); } if (axisTab->axisMinorTickCountDirty()) { axis->setAxisMinorTickCount(axisTab->axisMinorTickCount()); } if (axisTab->isAutoMinorTickCountDirty()) { axis->setAxisAutoMinorTicks(axisTab->isAutoMinorTickCount()); } if (axisTab->significantDigitsDirty()) { axis->setAxisSignificantDigits(axisTab->significantDigits()); } if (axisTab->isBaseOffsetDirty()) { axis->setAxisBaseOffset(axisTab->isBaseOffset()); } if (axisTab->isAutoBaseOffsetDirty()) { axis->setAxisAutoBaseOffset(axisTab->isAutoBaseOffset()); } if (axisTab->labelRotationDirty()) { axis->setAxisLabelRotation(axisTab->labelRotation()); } } void PlotItemDialog::labelsChanged() { Q_ASSERT(_plotItem); if (editMode() == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { PlotItem* plotItem = (PlotItem*)item; saveLabels(plotItem); } } else { saveLabels(_plotItem); } kstApp->mainWindow()->document()->setChanged(true); } void PlotItemDialog::saveLabels(PlotItem *item) { QString leftLabel = _labelTab->leftLabelDirty() ? _labelTab->leftLabel() :item->leftLabel(); bool leftLabelAuto = _labelTab->leftLabelAutoDirty() ? _labelTab->leftLabelAuto() :item->leftLabelDetails()->isAuto(); bool leftUseDefault = _leftLabelTab->useDefaultDirty() ? _leftLabelTab->useDefault() :item->leftLabelDetails()->fontUseGlobal(); QFont leftFont = _leftLabelTab->labelFontDirty() ? _leftLabelTab->labelFont(item->leftLabelDetails()->font()) :item->leftLabelDetails()->font(); qreal leftFontScale = _leftLabelTab->labelFontScaleDirty() ? _leftLabelTab->labelFontScale() :item->leftLabelDetails()->fontScale(); QColor leftFontColor = _leftLabelTab->labelColorDirty() ? _leftLabelTab->labelColor() :item->leftLabelDetails()->fontColor(); QString bottomLabel = _labelTab->bottomLabelDirty() ? _labelTab->bottomLabel() :item->bottomLabel(); bool bottomLabelAuto = _labelTab->bottomLabelAutoDirty() ? _labelTab->bottomLabelAuto() :item->bottomLabelDetails()->isAuto(); bool bottomUseDefault = _bottomLabelTab->useDefaultDirty() ? _bottomLabelTab->useDefault() :item->bottomLabelDetails()->fontUseGlobal(); QFont bottomFont = _bottomLabelTab->labelFontDirty() ? _bottomLabelTab->labelFont(item->bottomLabelDetails()->font()) :item->bottomLabelDetails()->font(); qreal bottomFontScale = _bottomLabelTab->labelFontScaleDirty() ? _bottomLabelTab->labelFontScale() :item->bottomLabelDetails()->fontScale(); QColor bottomFontColor = _bottomLabelTab->labelColorDirty() ? _bottomLabelTab->labelColor() :item->bottomLabelDetails()->fontColor(); QString rightLabel = _labelTab->rightLabelDirty() ? _labelTab->rightLabel() :item->rightLabel(); bool rightLabelAuto = _labelTab->rightLabelAutoDirty() ? _labelTab->rightLabelAuto() :item->rightLabelDetails()->isAuto(); bool rightUseDefault = _rightLabelTab->useDefaultDirty() ? _rightLabelTab->useDefault() :item->rightLabelDetails()->fontUseGlobal(); QFont rightFont = _rightLabelTab->labelFontDirty() ? _rightLabelTab->labelFont(item->rightLabelDetails()->font()) :item->rightLabelDetails()->font(); qreal rightFontScale = _rightLabelTab->labelFontScaleDirty() ? _rightLabelTab->labelFontScale() :item->rightLabelDetails()->fontScale(); QColor rightFontColor = _rightLabelTab->labelColorDirty() ? _rightLabelTab->labelColor() :item->rightLabelDetails()->fontColor(); QString topLabel = _labelTab->topLabelDirty() ? _labelTab->topLabel() :item->topLabel(); bool topLabelAuto = _labelTab->topLabelAutoDirty() ? _labelTab->topLabelAuto() :item->topLabelDetails()->isAuto(); bool topUseDefault = _topLabelTab->useDefaultDirty() ? _topLabelTab->useDefault() :item->topLabelDetails()->fontUseGlobal(); QFont topFont = _topLabelTab->labelFontDirty() ? _topLabelTab->labelFont(item->topLabelDetails()->font()) :item->topLabelDetails()->font(); qreal topFontScale = _topLabelTab->labelFontScaleDirty() ? _topLabelTab->labelFontScale() :item->topLabelDetails()->fontScale(); QColor topFontColor = _topLabelTab->labelColorDirty() ? _topLabelTab->labelColor() :item->topLabelDetails()->fontColor(); bool axisUseDefault = _axisLabelTab->useDefaultDirty() ? _axisLabelTab->useDefault() :item->numberLabelDetails()->fontUseGlobal(); QFont axisFont = _axisLabelTab->labelFontDirty() ? _axisLabelTab->labelFont(item->numberLabelDetails()->font()) :item->numberLabelDetails()->font(); qreal axisFontScale = _axisLabelTab->labelFontScaleDirty() ? _axisLabelTab->labelFontScale() :item->numberLabelDetails()->fontScale(); QColor axisFontColor = _axisLabelTab->labelColorDirty() ? _axisLabelTab->labelColor() :item->numberLabelDetails()->fontColor(); QFont globalFont = _labelTab->globalLabelFontDirty() ? _labelTab->globalLabelFont(item->globalFont()) :item->globalFont(); qreal globalFontScale = _labelTab->globalLabelFontScaleDirty() ? _labelTab->globalLabelFontScale() :item->globalFontScale(); QColor globalFontColor = _labelTab->globalLabelColorDirty() ? _labelTab->globalLabelColor() :item->globalFontColor(); bool showLegend = _labelTab->showLegendDirty() ? _labelTab->showLegend() :item->showLegend(); bool axisLabelScale = _labelTab->autoScaleNumbersDirty() ? _labelTab->autoScaleNumbers() :item->isUseAxisScale(); item->leftLabelDetails()->setDetails(leftLabel, leftLabelAuto, leftUseDefault, leftFont, leftFontScale, leftFontColor); item->bottomLabelDetails()->setDetails(bottomLabel, bottomLabelAuto, bottomUseDefault, bottomFont, bottomFontScale, bottomFontColor); item->rightLabelDetails()->setDetails(rightLabel, rightLabelAuto, rightUseDefault, rightFont, rightFontScale, rightFontColor); item->topLabelDetails()->setDetails(topLabel, topLabelAuto, topUseDefault, topFont, topFontScale, topFontColor); item->numberLabelDetails()->setDetails(QString(), false, axisUseDefault, axisFont, axisFontScale, axisFontColor); item->setGlobalFont(globalFont); item->setGlobalFontScale(globalFontScale); item->setGlobalFontColor(globalFontColor); item->setUseAxisScale(axisLabelScale); item->setShowLegend(showLegend); } void PlotItemDialog::xAxisPlotMarkersChanged() { Q_ASSERT(_plotItem); if (!_xMarkersTab->markersDirty()) { return; } PlotMarkers markers = _xMarkersTab->plotMarkers(); if (editMode() == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { PlotItem* plotItem = (PlotItem*)item; saveMarkers(plotItem->xAxis(), markers); } } else { saveMarkers(_plotItem->xAxis(), markers); } kstApp->mainWindow()->document()->setChanged(true); } void PlotItemDialog::yAxisPlotMarkersChanged() { Q_ASSERT(_plotItem); if (!_yMarkersTab->markersDirty()) { return; } PlotMarkers markers = _yMarkersTab->plotMarkers(); if (editMode() == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { PlotItem* plotItem = (PlotItem*)item; saveMarkers(plotItem->yAxis(), markers); } } else { saveMarkers(_plotItem->yAxis(), markers); } kstApp->mainWindow()->document()->setChanged(true); } void PlotItemDialog::saveMarkers(PlotAxis *axis, PlotMarkers &markers) { axis->setAxisPlotMarkers(markers); } void PlotItemDialog::useTopDefaultChanged(bool use) { if (use) { _labelPage->setTabText(1, tr("Top Font")); globalFontUpdate(); } else { _labelPage->setTabText(1, tr("Top Font*")); } } void PlotItemDialog::useBottomDefaultChanged(bool use) { if (use) { _labelPage->setTabText(2, tr("Bottom Font")); globalFontUpdate(); } else { _labelPage->setTabText(2, tr("Bottom Font*")); } } void PlotItemDialog::useLeftDefaultChanged(bool use) { if (use) { _labelPage->setTabText(3, tr("Left Font")); globalFontUpdate(); } else { _labelPage->setTabText(3, tr("Left Font*")); } } void PlotItemDialog::useRightDefaultChanged(bool use) { if (use) { _labelPage->setTabText(4, tr("Right Font")); globalFontUpdate(); } else { _labelPage->setTabText(4, tr("Right Font*")); } } void PlotItemDialog::useAxisDefaultChanged(bool use) { if (use) { _labelPage->setTabText(5, tr("Axis Font")); globalFontUpdate(); } else { _labelPage->setTabText(5, tr("Axis Font*")); } } void PlotItemDialog::globalFontUpdate() { qreal fontScale = _labelTab->globalLabelFontScale(); QFont font = _labelTab->globalLabelFont(QFont()); QColor color = _labelTab->globalLabelColor(); _topLabelTab->setFontSpecsIfDefault(font, fontScale, color); _bottomLabelTab->setFontSpecsIfDefault(font, fontScale, color); _leftLabelTab->setFontSpecsIfDefault(font, fontScale, color); _rightLabelTab->setFontSpecsIfDefault(font, fontScale, color); _axisLabelTab->setFontSpecsIfDefault(font, fontScale, color); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotrenderitem.h000644 001750 001750 00000010652 11544160207 020663 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLOTRENDERITEM_H #define PLOTRENDERITEM_H #include "viewitem.h" #include #include #include "relation.h" #include "selectionrect.h" namespace Kst { class PlotItem; class PlotRenderItem; class PlotRenderItem : public ViewItem { Q_OBJECT public: enum RenderType {First, Cartesian, Polar, Sinusoidal }; PlotRenderItem(PlotItem *parentItem); virtual ~PlotRenderItem(); PlotItem *plotItem() const; RenderType type(); void setType(RenderType type); QRectF plotRect() const; QRectF projectionRect() const; RelationList relationList() const; void addRelation(RelationPtr relation); void removeRelation(RelationPtr relation); void clearRelations(); virtual void save(QXmlStreamWriter &xml); virtual void saveInPlot(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); virtual void paintRelations(QPainter *painter) = 0; void paintReferencePoint(QPainter *painter); void paintHighlightPoint(QPainter *painter); virtual bool configureFromXml(QXmlStreamReader &xml, ObjectStore *store); QString leftLabel() const; QString bottomLabel() const; QString rightLabel() const; QString topLabel() const; QString multiRenderItemLabel(bool isX) const; QRectF computedProjectionRect() const; void computeBorder(Qt::Orientation orientation, qreal *min, qreal *max) const; void resetSelectionRect(); virtual bool tryShortcut(const QString &keySequence); public Q_SLOTS: virtual void edit(); virtual void raise(); virtual void lower(); virtual void createAutoLayout(); virtual void createCustomLayout(); virtual void remove(); virtual void referenceMode(); virtual void referenceModeDisabled(); protected: virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); virtual void keyPressEvent(QKeyEvent *event); virtual void keyReleaseEvent(QKeyEvent *event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); virtual QPainterPath shape() const; virtual bool updateViewItemParent(); private Q_SLOTS: void updateGeometry(); void updateViewMode(); private: virtual void addToMenuForContextEvent(QMenu &menu); void updateCursor(const QPointF &pos); void updateSelectionRect(); void computeXAxisRange(qreal *min, qreal *max) const; void computeYAxisRange(qreal *min, qreal *max) const; void computeAuto(Qt::Orientation orientation, qreal *min, qreal *max) const; void computeMeanCentered(Qt::Orientation orientation, qreal *min, qreal *max) const; void computeNoSpike(Qt::Orientation orientation, qreal *min, qreal *max) const; void highlightNearestDataPoint(const QPointF& position); void setReferencePoint(const QPointF& point); void processHoverMoveEvent(const QPointF& p); private: RenderType _type; QPointF _lastPos; QPointF _hoverPos; bool _referencePointMode; QPointF _referencePoint; bool _highlightPointActive; bool _invertHighlight; QPointF _highlightPoint; QAction *_referenceMode; QAction *_referenceModeDisabled; RelationList _relationList; SelectionRect _selectionRect; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/logwidget.cpp000644 001750 001750 00000005222 11544160207 020143 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "logwidget.h" #include #include #include #include "kst_i18n.h" #include namespace Kst { LogWidget::LogWidget(QWidget *parent) : QTextBrowser(parent) { _show = Debug::Warning | Debug::Error | Debug::Notice | Debug::DebugLog; } LogWidget::~LogWidget() { } void LogWidget::logAdded(const Debug::LogMessage& msg) { QString sym; switch (msg.level) { case Debug::Warning: sym = " "; break; case Debug::Error: sym = " "; break; case Debug::Notice: sym = " "; break; case Debug::DebugLog: sym = " "; break; default: return; } if ((_show & int(msg.level)) == 0) { return; } append(i18n("%1%2 %3").arg(sym).arg(msg.date.toString()).arg(msg.msg)); } void LogWidget::setShowDebug(bool show) { int old = _show; if (show) { _show |= Debug::DebugLog; } else { _show &= ~Debug::DebugLog; } if (_show != old) { regenerate(); } } void LogWidget::setShowNotice(bool show) { int old = _show; if (show) { _show |= Debug::Notice; } else { _show &= ~Debug::Notice; } if (_show != old) { regenerate(); } } void LogWidget::setShowWarning(bool show) { int old = _show; if (show) { _show |= Debug::Warning; } else { _show &= ~Debug::Warning; } if (_show != old) { regenerate(); } } void LogWidget::setShowError(bool show) { int old = _show; if (show) { _show |= Debug::Error; } else { _show &= ~Debug::Error; } if (_show != old) { regenerate(); } } void LogWidget::regenerate() { clear(); foreach(Debug::LogMessage message, Debug::self()->messages()) { logAdded(message); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialogtab.cpp000644 001750 001750 00000002364 11544160207 020110 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dialogtab.h" #include "dialog.h" #include "dialogpage.h" namespace Kst { DialogTab::DialogTab(QWidget *parent) : QWidget(parent) { } DialogTab::~DialogTab() { } Dialog *DialogTab::dialog() const { if (dialogPage()) return dialogPage()->dialog(); else return 0; } DialogPage *DialogTab::dialogPage() const { return qobject_cast(parentWidget()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/gridtab.cpp000644 001750 001750 00000003775 11544160207 017605 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "gridtab.h" namespace Kst { GridTab::GridTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("Grid")); connect(_showGrid, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_snapToGrid, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_gridHorSpacing, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_gridVerSpacing, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); } GridTab::~GridTab() { } bool GridTab::showGrid() const { return _showGrid->isChecked(); } void GridTab::setShowGrid(bool showGrid) { _showGrid->setChecked(showGrid); } bool GridTab::snapToGrid() const { return _snapToGrid->isChecked(); } void GridTab::setSnapToGrid(bool snapToGrid) { _snapToGrid->setChecked(snapToGrid); } qreal GridTab::gridHorizontalSpacing() const { return _gridHorSpacing->value(); } void GridTab::setGridHorizontalSpacing(qreal spacing) { _gridHorSpacing->setValue(spacing); } qreal GridTab::gridVerticalSpacing() const { return _gridVerSpacing->value(); } void GridTab::setGridVerticalSpacing(qreal spacing) { _gridVerSpacing->setValue(spacing); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/logdialog.h000644 001750 001750 00000003505 11544160207 017566 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 C. Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "ui_logdialog.h" #ifndef LOGDIALOG_H #define LOGDIALOG_H #include #include #include "kst_export.h" #include "kst_i18n.h" namespace Kst { class MainWindow; class LogDialog : public QDialog, Ui::LogDialog { Q_OBJECT public: LogDialog(MainWindow *parent); virtual ~LogDialog(); public slots: void changed(); void enableApply(); void apply(); void enableWidthHeight(); void runScript(); void scriptStdErr(); void scriptStdOut(); void scriptStarted(); void scriptFinished(int); void scriptError(QProcess::ProcessError); Q_SIGNALS: void exportLog(const QString &_logdir, time_t _logtime, const QString &_format, int x_size, int y_size, int size_option_index, const QString &message); private: time_t _logtime; QString _format; QString _logdir; QProcess *_proc; MainWindow *_parent; QString _imagename; QString _msgfilename; QString _username; }; } #endif // LOGDIALOG_H kst-2.0.3/src/libkstapp/contenttab.h000644 001750 001750 00000003432 11544160207 017765 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CONTENTTAB_H #define CONTENTTAB_H #include "dialogtab.h" #include "ui_contenttab.h" #include "kst_export.h" namespace Kst { class ObjectStore; class ContentTab : public DialogTab, Ui::ContentTab { Q_OBJECT public: ContentTab(QWidget *parent, ObjectStore* store); virtual ~ContentTab(); void setDisplayedRelations(QStringList displayedRelations, QStringList displayedRelationTips); void setAvailableRelations(QStringList availableRelations, QStringList availableRelationTips); QStringList displayedRelations(); private: ObjectStore* _store; private Q_SLOTS: void updateButtons(); void addButtonClicked(); void removeButtonClicked(); void upButtonClicked(); void downButtonClicked(); void availableDoubleClicked(QListWidgetItem * item); void displayedDoubleClicked(QListWidgetItem * item); void editSelectedAvailable(); void editSelectedDisplayed(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialogpage.cpp000644 001750 001750 00000004614 11544160207 020256 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dialogpage.h" #include "dialog.h" #include "dialogtab.h" #include namespace Kst { DialogPage::DialogPage(Dialog *parent) : QWidget(parent), _dialog(parent) { } DialogPage::~DialogPage() { } Dialog *DialogPage::dialog() const { return _dialog; } void DialogPage::addDialogTab(DialogTab *tab) { connect(this, SIGNAL(ok()), tab, SIGNAL(ok())); connect(this, SIGNAL(apply()), tab, SIGNAL(apply())); connect(this, SIGNAL(cancel()), tab, SIGNAL(cancel())); connect(tab, SIGNAL(modified()), this, SIGNAL(modified())); _widget = tab; QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(tab); setLayout(layout); } QWidget* DialogPage::currentWidget() { return _widget; } DialogPageTab::DialogPageTab(Dialog *parent) : DialogPage(parent) { _tabWidget = new QTabWidget(this); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(_tabWidget); setLayout(layout); } DialogPageTab::~DialogPageTab() { } void DialogPageTab::addDialogTab(DialogTab *tab) { connect(this, SIGNAL(ok()), tab, SIGNAL(ok())); connect(this, SIGNAL(apply()), tab, SIGNAL(apply())); connect(this, SIGNAL(cancel()), tab, SIGNAL(cancel())); connect(tab, SIGNAL(modified()), this, SIGNAL(modified())); _tabWidget->addTab(tab, tab->tabTitle()); } void DialogPageTab::setTabText(int i, const QString &text) { _tabWidget->setTabText(i, text); } QWidget* DialogPageTab::currentWidget() { return _tabWidget->currentWidget(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/stringmodel.h000644 001750 001750 00000002333 11544160207 020152 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STRINGMODEL_H #define STRINGMODEL_H #include "primitivemodel.h" namespace Kst { class StringModel : public PrimitiveModel { enum ColumnID { Name, Value }; public: StringModel(ObjectStore *store) : PrimitiveModel(store) { createTree(); } void addDataSourcesMetas(DataSourcePtr dataSource, PrimitiveTreeItem* parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datawizardpagefilters.ui000644 001750 001750 00000005331 11544160207 022372 0ustar00synthsynth000000 000000 DataWizardPageFilters 0 0 593 221 Filters 0 0 &New Filter... Qt::Horizontal QSizePolicy::Expanding 121 21 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If you wish, select a filter to apply to the fields that are read in:</p></body></html> false Qt::Vertical QSizePolicy::Expanding 51 151 kst-2.0.3/src/libkstapp/TODO000644 001750 001750 00000002024 11544160207 016137 0ustar00synthsynth000000 000000 View ---- - arrows - Box the objects so they can't be dragged out of the visible size of scene - Create an ItemModel to map the items into a model - gradient editor doesn't work - Edit dialog needs to be parented and probably should be one-per-view Dialogs ------- - Finish off DataManager - Add DataWizard - Polish the vector dialog and hook it up - Item dialogs - Matrix Dialog - make an item view that is a set of tabs containing tableviews - String+Scalar dialog - Dialogs for data objects - Add view manager -> just a view onto the item model Models ------ - Add support for objects appearing/disappearing - Implement SessionModel for the datamanager - Implement MatrixTableModel - Implement PrimitiveScalarModel (Strings+Scalars) - support grouping by parent Plotting -------- - Move algorithms into libkstmath - Separate Kst2DPlot into pieces - axis - ?? Document -------- - Move data collections into here somehow? Updates ------- - Add update loop Other ----- - Move actions from MainWindow to each Item kst-2.0.3/src/libkstapp/histogramtab.ui000644 001750 001750 00000023674 11544160207 020510 0ustar00synthsynth000000 000000 HistogramTab 0 0 898 298 0 0 0 0 0 Histogram Properties 0 0 Data vecto&r: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Bins from&: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _min 0 0 The lower limit of the lowest bin. Values below this limit will not be counted in any bin. -10.0 0 0 to: false _max 0 0 The upper limit of the highest bin. Values above this limit will not be counted in any bin. 10.0 0 0 Num bin&s: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _numberOfBins 0 0 The number of bins in the Histogram. 1000000 5 60 0 0 0 Set the upper and lower limits, and the number of bins to a reasonable default. A&uto Bin Real&-time auto bin Y-axis Normalization 11 6 The Y axis of the histogram reports the percent of the samples in the bin. Percent& in bin The Y axis of the histogram reports the fraction of samples in the bin. &Fraction in bin The Y axis of the histogram reports the number of samples in the bin. Nu&mber in bin true The Y axis of the histogram is normalized so that the highest bin is 1. Peak bin = &1.0 Alt+1 Kst::CurvePlacement QWidget
curveplacement.h
Kst::VectorSelector QWidget
vectorselector.h
Kst::CurveAppearance QWidget
curveappearance.h
_vector _min _max _numberOfBins AutoBin _realTimeAutoBin _normalizationIsNumber _curveAppearance _curvePlacement
kst-2.0.3/src/libkstapp/stroketab.h000644 001750 001750 00000003455 11544160207 017627 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STROKETAB_H #define STROKETAB_H #include "dialogtab.h" #include "ui_stroketab.h" #include "kst_export.h" namespace Kst { class StrokeTab : public DialogTab, Ui::StrokeTab { Q_OBJECT public: StrokeTab(QWidget *parent = 0); virtual ~StrokeTab(); Qt::PenStyle style() const; bool styleDirty() const; void setStyle(Qt::PenStyle style); qreal width() const; bool widthDirty() const; void setWidth(qreal width); QColor brushColor() const; bool brushColorDirty() const; void setBrushColor(const QColor &color); Qt::BrushStyle brushStyle() const; bool brushStyleDirty() const; void setBrushStyle(Qt::BrushStyle style); Qt::PenJoinStyle joinStyle() const; bool joinStyleDirty() const; void setJoinStyle(Qt::PenJoinStyle style); Qt::PenCapStyle capStyle() const; bool capStyleDirty() const; void setCapStyle(Qt::PenCapStyle style); void clearTabValues(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labelitem.cpp000644 001750 001750 00000016721 11544160207 020122 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labelitem.h" #include #include "labelrenderer.h" #include "labelitemdialog.h" #include "labelcreator.h" #include "applicationsettings.h" #include "debug.h" #include #include #include #include namespace Kst { LabelItem::LabelItem(View *parent, const QString& txt) : ViewItem(parent), _labelRc(0), _dirty(true), _text(txt), _height(0) { setTypeName("Label"); setFixedSize(true); setAllowedGripModes(Move /*| Resize*/ | Rotate /*| Scale*/); _scale = ApplicationSettings::self()->defaultFontScale(); _color = ApplicationSettings::self()->defaultFontColor(); _font = view()->defaultFont(_scale); } LabelItem::~LabelItem() { delete _labelRc; } void LabelItem::generateLabel() { if (_labelRc) { delete _labelRc; } Label::Parsed *parsed = Label::parse(_text); if (parsed) { parsed->chunk->attributes.color = _color; _dirty = false; QRectF box = rect(); QFont font(_font); font.setPointSizeF(view()->defaultFont(_scale).pointSizeF()); QFontMetrics fm(font); _paintTransform.reset(); _paintTransform.translate(box.x(), box.y() + fm.ascent()); _labelRc = new Label::RenderContext(font, 0); Label::renderLabel(*_labelRc, parsed->chunk); _height = fm.height(); // Make sure we have a rect for selection, movement, etc setViewRect(QRectF(rect().x(), rect().y(), _labelRc->xMax, (_labelRc->lines+1) * _height)); connect(_labelRc, SIGNAL(labelDirty()), this, SLOT(setDirty())); connect(_labelRc, SIGNAL(labelDirty()), this, SLOT(triggerUpdate())); delete parsed; } } void LabelItem::paint(QPainter *painter) { // possible optimization: make _dirty actually work to save label // regeneration on 'paint'. Unlikely to be noticable though. //if (_dirty || 1) { generateLabel(); //} if (_labelRc) { painter->save(); painter->setTransform(_paintTransform, true); Label::paintLabel(*_labelRc, painter); painter->restore(); } } void LabelItem::triggerUpdate() { update(); } void LabelItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("label"); xml.writeAttribute("text", _text); xml.writeAttribute("scale", QVariant(_scale).toString()); xml.writeAttribute("color", QVariant(_color).toString()); xml.writeAttribute("font", QVariant(_font).toString()); ViewItem::save(xml); xml.writeEndElement(); } } QString LabelItem::labelText() { return _text; } void LabelItem::setLabelText(const QString &text) { _text = text; setDirty(); } qreal LabelItem::labelScale() { return _scale; } void LabelItem::setLabelScale(const qreal scale) { _scale = scale; setDirty(); } QColor LabelItem::labelColor() const { return _color; } void LabelItem::setLabelColor(const QColor &color) { _color = color; setDirty(); } void LabelItem::edit() { LabelItemDialog *editDialog = new LabelItemDialog(this); editDialog->show(); } QFont LabelItem::labelFont() const { return _font; } void LabelItem::setLabelFont(const QFont &font) { _font = font; setDirty(); } void LabelItem::creationPolygonChanged(View::CreationEvent event) { if (event == View::MouseMove) { if (view()->creationPolygon(View::MouseMove).size()>0) { const QPointF P = view()->creationPolygon(View::MouseMove).last(); setPos(P); setDirty(); } } else if (event == View::MouseRelease) { const QPointF P = mapFromScene(view()->creationPolygon(event).last()); QRectF newRect(rect().x(), rect().y(), P.x() - rect().x(), P.y() - rect().y()); if (newRect.isNull()) { // Special case for labels that don't need to have a size for creation to ensure proper parenting. newRect.setSize(QSize(1, 1)); } setViewRect(newRect.normalized()); view()->disconnect(this, SLOT(deleteLater())); //Don't delete ourself view()->disconnect(this, SLOT(creationPolygonChanged(View::CreationEvent))); view()->setMouseMode(View::Default); updateViewItemParent(); emit creationComplete(); setDirty(); return; } else if (event != View::MousePress) { ViewItem::creationPolygonChanged(event); } } void CreateLabelCommand::createItem(QString *inText) { if (inText) { _item = new LabelItem(_view, *inText); } else { bool ok = false; QString text; LabelCreator dialog; if (dialog.exec() == QDialog::Accepted) { text = dialog.labelText(); ok = true; } if (!ok || text.isEmpty()) { return; } _item = new LabelItem(_view, text); LabelItem *label = qobject_cast(_item); label->setLabelScale(dialog.labelScale()); label->setLabelColor(dialog.labelColor()); label->setLabelFont(dialog.labelFont()); } _item->view()->scene()->addItem(_item); _view->setCursor(Qt::IBeamCursor); CreateCommand::createItem(); } LabelItemFactory::LabelItemFactory() : GraphicsFactory() { registerFactory("label", this); } LabelItemFactory::~LabelItemFactory() { } ViewItem* LabelItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { LabelItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "label") { QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; av = attrs.value("text"); if (!av.isNull()) { Q_ASSERT(!rc); rc = new LabelItem(view, av.toString()); if (parent) { rc->setParentViewItem(parent); // Add any new specialized LabelItem Properties here. } } av = attrs.value("scale"); if (!av.isNull()) { rc->setLabelScale(QVariant(av.toString()).toInt()); } av = attrs.value("color"); if (!av.isNull()) { rc->setLabelColor(QColor(av.toString())); } av = attrs.value("font"); if (!av.isNull()) { QFont font; font.fromString(av.toString()); rc->setLabelFont(font); } } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "label") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating box object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/vectormodel.cpp000644 001750 001750 00000006234 11544160207 020505 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "vectormodel.h" #include #include namespace Kst { VectorModel::VectorModel(Vector *v) : QAbstractTableModel (), _vector(v) { assert(v); } VectorModel::~VectorModel() { } int VectorModel::columnCount(const QModelIndex&) const { return 2; } int VectorModel::rowCount(const QModelIndex&) const { return _vector ? _vector->length() : 0; } QVariant VectorModel::data(const QModelIndex& index, int role) const { if (index.isValid() && _vector) { switch (role) { case Qt::DisplayRole: if (index.column() == 0) { return QVariant(index.row()); } else if (index.column() == 1) { return QVariant(_vector->value(index.row())); } break; case Qt::FontRole: { if (_vector->editable()) { QFont f; f.setBold(true); return QVariant(f); } } break; default: break; } } return QVariant(); } QModelIndex VectorModel::parent(const QModelIndex&) const { return QModelIndex(); } QVariant VectorModel::headerData(int section, Qt::Orientation orientation, int role) const { if (!_vector || role != Qt::DisplayRole || orientation == Qt::Vertical || section > 1) { return QAbstractItemModel::headerData(section, orientation, role); } if (section == 0) { return QVariant("Index"); } else if(section == 1) { return QVariant(_vector->Name()); } return QVariant(); } Qt::ItemFlags VectorModel::flags(const QModelIndex& index) const { Qt::ItemFlags f = QAbstractItemModel::flags(index); if (!_vector || !index.isValid()) { return f; } if (_vector->editable() && index.row() >= 0 && index.row() < _vector->length()) { f |= Qt::ItemIsEditable; } return f; } bool VectorModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (role != Qt::EditRole) { return QAbstractItemModel::setData(index, value, role); } if (!_vector || !index.isValid() || !_vector->editable() || index.row() < 0 || index.row() >= _vector->length()) { return false; } bool ok = false; double v = value.toDouble(&ok); if (!ok) { return false; } qDebug() << "UGLY!! Add setData API to KstVector!"; double *d = const_cast(_vector->value()); d[index.row()] = v; return true; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/vectordialog.cpp000644 001750 001750 00000041523 11544160207 020644 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "vectordialog.h" #include "dialogpage.h" #include "datasourcedialog.h" #include "editmultiplewidget.h" #include "datavector.h" #include "generatedvector.h" #include "datacollection.h" #include "document.h" #include "objectstore.h" #include "datasourcepluginmanager.h" #include "dialogdefaults.h" #include #include namespace Kst { VectorTab::VectorTab(ObjectStore *store, QWidget *parent) : DataTab(parent), _mode(DataVector), _store(store), _initField(QString()), _requestID(0) { setupUi(this); setTabTitle(tr("Vector")); connect(_generatedVectorGroup, SIGNAL(clicked(bool)), this, SLOT(generateClicked())); connect(_dataVectorGroup, SIGNAL(clicked(bool)), this, SLOT(readFromSourceClicked())); connect(_fileName, SIGNAL(changed(const QString &)), this, SLOT(fileNameChanged(const QString &))); connect(_configure, SIGNAL(clicked()), this, SLOT(showConfigWidget())); connect(_field, SIGNAL(editTextChanged(const QString &)), this, SIGNAL(fieldChanged())); connect(_dataRange, SIGNAL(modified()), this, SIGNAL(modified())); connect(_numberOfSamples, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_from, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_to, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); // embed data range in the data source box _dataRange->groupBox2->setFlat(true); _dataRange->groupBox2->setTitle(""); int top_margin; _dataRange->groupBox2->layout()->getContentsMargins(NULL,&top_margin,NULL,NULL); _dataRange->groupBox2->layout()->setContentsMargins(0,top_margin,0,0); _connect->setVisible(false); _updateBox->addItem("Time interval"); _updateBox->addItem("Change detection"); _updateBox->addItem("Don't update"); updateUpdateBox(); connect(_updateBox, SIGNAL(activated(int)), this, SLOT(updateTypeActivated(int))); connect(_updateBox, SIGNAL(activated(int)), this, SIGNAL(modified())); } VectorTab::~VectorTab() { } void VectorTab::updateUpdateBox() { if (_dataSource) { _updateBox->setEnabled(true); switch (_dataSource->updateType()) { case DataSource::Timer: _updateBox->setCurrentIndex(0); break; case DataSource::File: _updateBox->setCurrentIndex(1); break; case DataSource::None: _updateBox->setCurrentIndex(2); break; default: break; }; } else { _updateBox->setEnabled(false); } } void VectorTab::updateTypeActivated(int idx) { if (!_dataSource) { _updateBox->setEnabled(false); return; } switch (idx) { _updateBox->setEnabled(true); case 0: _dataSource->setUpdateType(DataSource::Timer); break; case 1: _dataSource->setUpdateType(DataSource::File); break; case 2: _dataSource->setUpdateType(DataSource::None); break; default: break; }; } DataSourcePtr VectorTab::dataSource() const { return _dataSource; } void VectorTab::setDataSource(DataSourcePtr dataSource) { _dataSource = dataSource; } void VectorTab::setVectorMode(VectorMode mode) { _mode = mode; _dataVectorGroup->setChecked(mode == DataVector); _dataRange->setEnabled(mode == DataVector); _generatedVectorGroup->setChecked(mode == GeneratedVector); } QString VectorTab::file() const { return _fileName->file(); } void VectorTab::setFile(const QString &file) { QFileInfo info(file); _fileName->setFile(file); } QString VectorTab::field() const { return _field->currentText(); } void VectorTab::setField(const QString &field) { _initField = field; // for delayed index setting _field->setCurrentIndex(_field->findText(field)); } void VectorTab::setFieldList(const QStringList &fieldList) { _field->clear(); _field->addItems(fieldList); } DataRange *VectorTab::dataRange() const { return _dataRange; } qreal VectorTab::from() const { return _from->text().toDouble(); } bool VectorTab::fromDirty() const { return (!_from->text().isEmpty()); } void VectorTab::setFrom(qreal from) { _from->setText(QString::number(from)); } qreal VectorTab::to() const { return _to->text().toDouble(); } bool VectorTab::toDirty() const { return (!_to->text().isEmpty()); } void VectorTab::setTo(qreal to) { _to->setText(QString::number(to)); } int VectorTab::numberOfSamples() const { return _numberOfSamples->value(); } bool VectorTab::numberOfSamplesDirty() const { return (!_numberOfSamples->text().isEmpty()); } void VectorTab::setNumberOfSamples(int numberOfSamples) { _numberOfSamples->setValue(numberOfSamples); } void VectorTab::generateClicked() { if (_generatedVectorGroup->isChecked()) setVectorMode(GeneratedVector); else setVectorMode(DataVector); emit sourceChanged(); } void VectorTab::readFromSourceClicked() { if (_dataVectorGroup->isChecked()) setVectorMode(DataVector); else setVectorMode(GeneratedVector); emit sourceChanged(); } void VectorTab::hideGeneratedOptions() { _generatedVectorGroup->setVisible(false); _dataVectorGroup->setCheckable(false); _dataVectorGroup->setTitle(""); _dataVectorGroup->setFlat(true); int top_margin; _dataVectorGroup->layout()->getContentsMargins(NULL,&top_margin,NULL,NULL); _dataVectorGroup->layout()->setContentsMargins(0,top_margin,0,0); } void VectorTab::hideDataOptions() { _dataVectorGroup->setVisible(false); _dataRange->setVisible(false); _generatedVectorGroup->setCheckable(false); _generatedVectorGroup->setTitle(""); _generatedVectorGroup->setFlat(true); int top_margin; _generatedVectorGroup->layout()->getContentsMargins(NULL,&top_margin,NULL,NULL); _generatedVectorGroup->layout()->setContentsMargins(0,top_margin,0,0); } void VectorTab::clearTabValues() { _numberOfSamples->clear(); _from->clear(); _to->clear(); _dataRange->clearValues(); } void VectorTab::enableSingleEditOptions(bool enabled) { _dataVectorGroup->setEnabled(enabled); } void VectorTab::sourceValid(QString filename, int requestID) { if (_requestID != requestID) { return; } _dataSource = DataSourcePluginManager::findOrLoadSource(_store, filename); _field->setEnabled(true); _dataSource->readLock(); _field->addItems(_dataSource->vector().list()); if (!_initField.isEmpty()) { setField(_initField); } _field->setEditable(!_dataSource->vector().isListComplete()); _configure->setEnabled(_dataSource->hasConfigWidget()); updateUpdateBox(); _dataSource->unlock(); emit sourceChanged(); } void VectorTab::fileNameChanged(const QString &file) { _field->clear(); _field->setEnabled(false); _configure->setEnabled(false); emit sourceChanged(); _requestID += 1; ValidateDataSourceThread *validateDSThread = new ValidateDataSourceThread(file, _requestID); connect(validateDSThread, SIGNAL(dataSourceValid(QString, int)), this, SLOT(sourceValid(QString, int))); QThreadPool::globalInstance()->start(validateDSThread); } void VectorTab::showConfigWidget() { QPointer dialog = new DataSourceDialog(dataDialog()->editMode(), _dataSource, this); if ( dialog->exec() == QDialog::Accepted ) { fileNameChanged(_dataSource->fileName()); } delete dialog; } VectorDialog::VectorDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent, false) { if (editMode() == Edit) setWindowTitle(tr("Edit Vector")); else setWindowTitle(tr("New Vector")); Q_ASSERT(_document); _vectorTab = new VectorTab(_document->objectStore(), this); addDataTab(_vectorTab); if (editMode() == Edit) { configureTab(dataObject); } else { configureTab(0); } connect(_vectorTab, SIGNAL(sourceChanged()), this, SLOT(updateButtons())); connect(_vectorTab, SIGNAL(fieldChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_vectorTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } VectorDialog::~VectorDialog() { } void VectorDialog::editMultipleMode() { _vectorTab->enableSingleEditOptions(false); _vectorTab->clearTabValues(); } void VectorDialog::editSingleMode() { _vectorTab->enableSingleEditOptions(true); configureTab(dataObject()); } void VectorDialog::updateButtons() { bool valid = _vectorTab->vectorMode() == VectorTab::GeneratedVector || !_vectorTab->field().isEmpty(); // FIXME: add stricter validity testing. _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid); _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(valid); } void VectorDialog::configureTab(ObjectPtr vector) { if (!vector) { _vectorTab->dataRange()->loadWidgetDefaults(); _vectorTab->setFile(_dialogDefaults->value("vector/datasource",_vectorTab->file()).toString()); _vectorTab->setFrom(_dialogDefaults->value("genVector/min",-10).toInt()); _vectorTab->setTo(_dialogDefaults->value("genVector/max",10).toInt()); _vectorTab->setNumberOfSamples(_dialogDefaults->value("genVector/length",1000).toInt()); } else if (DataVectorPtr dataVector = kst_cast(vector)) { _vectorTab->setVectorMode(VectorTab::DataVector); _vectorTab->setFile(dataVector->dataSource()->fileName()); _vectorTab->setDataSource(dataVector->dataSource()); _vectorTab->setField(dataVector->field()); _vectorTab->dataRange()->setRange(dataVector->numFrames()); _vectorTab->dataRange()->setStart(dataVector->startFrame()); _vectorTab->dataRange()->setCountFromEnd(dataVector->countFromEOF()); _vectorTab->dataRange()->setReadToEnd(dataVector->readToEOF()); _vectorTab->dataRange()->setSkip(dataVector->skip()); _vectorTab->dataRange()->setDoSkip(dataVector->doSkip()); _vectorTab->dataRange()->setDoFilter(dataVector->doAve()); _vectorTab->hideGeneratedOptions(); if (_editMultipleWidget) { DataVectorList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(DataVectorPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } else if (GeneratedVectorPtr generatedVector = kst_cast(vector)) { _vectorTab->setVectorMode(VectorTab::GeneratedVector); _vectorTab->setFrom(generatedVector->min()); _vectorTab->setTo(generatedVector->max()); _vectorTab->setNumberOfSamples(generatedVector->length()); _vectorTab->hideDataOptions(); if (_editMultipleWidget) { DataVectorList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(DataVectorPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } ObjectPtr VectorDialog::createNewDataObject() { switch(_vectorTab->vectorMode()) { case VectorTab::DataVector: return createNewDataVector(); case VectorTab::GeneratedVector: return createNewGeneratedVector(); default: return 0; } } ObjectPtr VectorDialog::createNewDataVector() { const DataSourcePtr dataSource = _vectorTab->dataSource(); //FIXME better validation than this please... if (!dataSource) return 0; const QString field = _vectorTab->field(); const DataRange *dataRange = _vectorTab->dataRange(); Q_ASSERT(_document && _document->objectStore()); DataVectorPtr vector = _document->objectStore()->createObject(); vector->writeLock(); vector->change(dataSource, field, dataRange->countFromEnd() ? -1 : int(dataRange->start()), dataRange->readToEnd() ? -1 : int(dataRange->range()), dataRange->skip(), dataRange->doSkip(), dataRange->doFilter()); if (DataDialog::tagStringAuto()) { vector->setDescriptiveName(QString()); } else { vector->setDescriptiveName(DataDialog::tagString()); } setDataVectorDefaults(vector); _vectorTab->dataRange()->setWidgetDefaults(); vector->registerChange(); vector->unlock(); _dataObjectName = vector->Name(); return vector; } ObjectPtr VectorDialog::createNewGeneratedVector() { const qreal from = _vectorTab->from(); const qreal to = _vectorTab->to(); const int numberOfSamples = _vectorTab->numberOfSamples(); Q_ASSERT(_document && _document->objectStore()); GeneratedVectorPtr vector = _document->objectStore()->createObject(); vector->changeRange(from, to, numberOfSamples); setGenVectorDefaults(vector); if (DataDialog::tagStringAuto()) { vector->setDescriptiveName(QString()); } else { vector->setDescriptiveName(DataDialog::tagString()); } _dataObjectName = vector->Name(); return vector; } ObjectPtr VectorDialog::editExistingDataObject() const { if (DataVectorPtr dataVector = kst_cast(dataObject())) { if (editMode() == EditMultiple) { const DataRange *dataRange = _vectorTab->dataRange(); QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { DataVectorPtr vector = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (vector) { int start = dataRange->startDirty() ? dataRange->start() : vector->startFrame(); int range = dataRange->rangeDirty() ? dataRange->range() : vector->numFrames(); int skip = dataRange->skipDirty() ? dataRange->skip() : vector->skip(); if (dataRange->countFromEndDirty()) { start = dataRange->countFromEnd() ? -1 : dataRange->start(); range = dataRange->readToEnd() ? -1 : dataRange->range(); } bool doSkip = dataRange->doSkipDirty() ? dataRange->doSkip() : vector->doSkip(); bool doAve = dataRange->doFilterDirty() ? dataRange->doFilter() : vector->doAve(); vector->writeLock(); vector->changeFrames(start, range, skip, doSkip, doAve); vector->registerChange(); vector->unlock(); } } } else { const DataSourcePtr dataSource = _vectorTab->dataSource(); //FIXME better validation than this please... if (!dataSource) return 0; const QString field = _vectorTab->field(); const DataRange *dataRange = _vectorTab->dataRange(); dataVector->writeLock(); dataVector->change(dataSource, field, dataRange->countFromEnd() ? -1 : int(dataRange->start()), dataRange->readToEnd() ? -1 : int(dataRange->range()), dataRange->skip(), dataRange->doSkip(), dataRange->doFilter()); if (DataDialog::tagStringAuto()) { dataVector->setDescriptiveName(QString()); } else { dataVector->setDescriptiveName(DataDialog::tagString()); } dataVector->registerChange(); dataVector->unlock(); setDataVectorDefaults(dataVector); _vectorTab->dataRange()->setWidgetDefaults(); } } else if (GeneratedVectorPtr generatedVector = kst_cast(dataObject())) { if (editMode() == EditMultiple) { QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { GeneratedVectorPtr vector = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (vector) { double min = _vectorTab->fromDirty() ? _vectorTab->from() : vector->min(); double max = _vectorTab->toDirty() ? _vectorTab->to() : vector->max(); double length = _vectorTab->numberOfSamplesDirty() ? _vectorTab->numberOfSamples() : vector->length(); vector->writeLock(); vector->changeRange(min, max, length); vector->registerChange(); vector->unlock(); } } } else { const qreal from = _vectorTab->from(); const qreal to = _vectorTab->to(); const int numberOfSamples = _vectorTab->numberOfSamples(); generatedVector->writeLock(); generatedVector->changeRange(from, to, numberOfSamples); if (DataDialog::tagStringAuto()) { generatedVector->setDescriptiveName(QString()); } else { generatedVector->setDescriptiveName(DataDialog::tagString()); } generatedVector->registerChange(); generatedVector->unlock(); setGenVectorDefaults(generatedVector); } } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/vectordialog.h000644 001750 001750 00000006435 11544160207 020314 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VECTORDIALOG_H #define VECTORDIALOG_H #include "datadialog.h" #include "datatab.h" #include "ui_vectortab.h" #include #include "kst_export.h" #include "datasource.h" namespace Kst { class ObjectStore; class VectorTab : public DataTab, Ui::VectorTab { Q_OBJECT public: enum VectorMode { DataVector, GeneratedVector }; explicit VectorTab(ObjectStore *store, QWidget *parent = 0); virtual ~VectorTab(); VectorMode vectorMode() const { return _mode; } void setVectorMode(VectorMode mode); //DataVector mode methods... DataSourcePtr dataSource() const; void setDataSource(DataSourcePtr dataSource); QString file() const; void setFile(const QString &file); QString field() const; void setField(const QString &field); void setFieldList(const QStringList &fieldList); DataRange *dataRange() const; //GeneratedVector methods... qreal from() const; void setFrom(qreal from); bool fromDirty() const; qreal to() const; void setTo(qreal to); bool toDirty() const; int numberOfSamples() const; void setNumberOfSamples(int numberOfSamples); bool numberOfSamplesDirty() const; void hideGeneratedOptions(); void hideDataOptions(); void enableSingleEditOptions(bool enabled); void clearTabValues(); Q_SIGNALS: void sourceChanged(); void fieldChanged(); private Q_SLOTS: void readFromSourceClicked(); void generateClicked(); void fileNameChanged(const QString &file); void showConfigWidget(); void sourceValid(QString filename, int requestID); void updateTypeActivated(int); private: VectorMode _mode; ObjectStore *_store; DataSourcePtr _dataSource; QString _initField; int _requestID; void updateUpdateBox(); }; class VectorDialog : public DataDialog { Q_OBJECT public: explicit VectorDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~VectorDialog(); void setField(QString field) {_vectorTab->setField(field);} protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private: ObjectPtr createNewDataVector(); ObjectPtr createNewGeneratedVector(); void configureTab(ObjectPtr vector=0); private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: VectorTab *_vectorTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/overridelabeltab.cpp000644 001750 001750 00000010134 11544160207 021462 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "overridelabeltab.h" #include "application.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" namespace Kst { OverrideLabelTab::OverrideLabelTab(QString title, QWidget *parent) : DialogTab(parent), _fontDirty(false) { setupUi(this); _bold->setIcon(QPixmap(":kst_bold.png")); _bold->setFixedWidth(32); _italic->setIcon(QPixmap(":kst_italic.png")); _italic->setFixedWidth(32); _labelColor->setFixedWidth(32); _labelColor->setFixedHeight(32); setTabTitle(title); connect(_fontSize, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_bold, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_italic, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_family, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_labelColor, SIGNAL(changed(const QColor &)), this, SIGNAL(modified())); connect(_useDefault, SIGNAL(toggled(bool)), this, SIGNAL(useDefaultChanged(bool))); connect(_bold, SIGNAL(toggled(bool)), this, SLOT(buttonUpdate())); connect(_italic, SIGNAL(toggled(bool)), this, SLOT(buttonUpdate())); } OverrideLabelTab::~OverrideLabelTab() { } void OverrideLabelTab::buttonUpdate() { _fontDirty = true; } QFont OverrideLabelTab::labelFont(QFont ref_font) const { QString family = (_family->currentIndex() == -1) ? ref_font.family() : _family->currentFont().family(); QFont font(family); font.setItalic(_italic->isChecked()); font.setBold(_bold->isChecked()); return font; } bool OverrideLabelTab::labelFontDirty() const { return (_family->currentIndex() != -1 || _fontDirty); } void OverrideLabelTab::setLabelFont(const QFont &font) { _fontDirty = false; _family->setCurrentFont(font); _bold->setChecked(font.bold()); _italic->setChecked(font.italic()); } qreal OverrideLabelTab::labelFontScale() const { return _fontSize->value(); } bool OverrideLabelTab::labelFontScaleDirty() const { return (!_fontSize->text().isEmpty()); } void OverrideLabelTab::setLabelFontScale(const qreal scale) { _fontSize->setValue(scale); } QColor OverrideLabelTab::labelColor() const { return _labelColor->color(); } bool OverrideLabelTab::labelColorDirty() const { return _labelColor->colorDirty(); } void OverrideLabelTab::setLabelColor(const QColor &color) { _labelColor->setColor(color); } void OverrideLabelTab::setFontSpecsIfDefault(const QFont &font, const qreal scale, const QColor &color) { if (_useDefault->isChecked()) { _fontDirty = false; setLabelFontScale(scale); setLabelFont(font); setLabelColor(color); } } void OverrideLabelTab::setUseDefault(bool use_default) { _useDefault->setChecked(use_default); } bool OverrideLabelTab::useDefault() const { return (_useDefault->isChecked()); } bool OverrideLabelTab::useDefaultDirty() const { return _useDefault->checkState() != Qt::PartiallyChecked; } void OverrideLabelTab::clearTabValues() { _fontDirty = false; _useDefault->setCheckState(Qt::PartiallyChecked); _fontSize->clear(); _family->setCurrentIndex(-1); _bold->setChecked(false); _italic->setChecked(false); _labelColor->clearSelection(); } void OverrideLabelTab::enableSingleEditOptions(bool enabled) { if (enabled) { _useDefault->setTristate(false); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/histogramdialog.cpp000644 001750 001750 00000034553 11544160207 021344 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "histogramdialog.h" #include "dialogpage.h" #include "editmultiplewidget.h" #include "histogram.h" #include "view.h" #include "plotitem.h" #include "tabwidget.h" #include "mainwindow.h" #include "application.h" #include "plotrenderitem.h" #include "curve.h" #include "document.h" #include "objectstore.h" #include "datacollection.h" #include "dialogdefaults.h" namespace Kst { HistogramTab::HistogramTab(QWidget *parent) : DataTab(parent), _normalizationDirty(false) { setupUi(this); setTabTitle(tr("Histogram")); connect(AutoBin, SIGNAL(clicked()), this, SLOT(generateAutoBin())); connect(_realTimeAutoBin, SIGNAL(clicked()), this, SLOT(updateButtons())); connect(_vector, SIGNAL(selectionChanged(QString)), this, SLOT(selectionChanged())); connect(_vector, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); connect(_min, SIGNAL(textChanged(const QString &)), this, SIGNAL(modified())); connect(_max, SIGNAL(textChanged(const QString &)), this, SIGNAL(modified())); connect(_numberOfBins, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_realTimeAutoBin, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_normalizationIsNumber, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_normalizationIsFraction, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_normalizationIsPercent, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_normalizationMaximumOne, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_normalizationIsNumber, SIGNAL(clicked()), this, SLOT(normalizationChanged())); connect(_normalizationIsFraction, SIGNAL(clicked()), this, SLOT(normalizationChanged())); connect(_normalizationIsPercent, SIGNAL(clicked()), this, SLOT(normalizationChanged())); connect(_normalizationMaximumOne, SIGNAL(clicked()), this, SLOT(normalizationChanged())); _vectorLabel->setBuddy(_vector->_vector); _curvePlacement->setExistingPlots(Data::self()->plotList()); _curveAppearance->setShowLines(false); _curveAppearance->setShowPoints(false); _curveAppearance->setShowHead(false); _curveAppearance->setShowBars(true); _curveAppearance->setColor(_curveAppearance->color()); _curveAppearance->setPointType(0); _curveAppearance->setLineWidth(0); _curveAppearance->setLineStyle(0); _curveAppearance->setBarStyle(1); _curveAppearance->setPointDensity(0); } HistogramTab::~HistogramTab() { } void HistogramTab::normalizationChanged() { _normalizationDirty = true; } void HistogramTab::resetNormalizationDirty() { _normalizationDirty = false; } void HistogramTab::selectionChanged() { emit vectorChanged(); } void HistogramTab::generateAutoBin() { VectorPtr selectedVector = vector(); if (selectedVector) { selectedVector->readLock(); // Hmm should we really lock here? AutoBin should I think int n; double max, min; Histogram::AutoBin(selectedVector, &n, &max, &min); selectedVector->unlock(); _numberOfBins->setValue(n); _min->setText(QString::number(min)); _max->setText(QString::number(max)); } } void HistogramTab::updateButtons() { if (_realTimeAutoBin->isChecked()) { generateAutoBin(); } _min->setEnabled(!_realTimeAutoBin->isChecked()); _max->setEnabled(!_realTimeAutoBin->isChecked()); _numberOfBins->setEnabled(!_realTimeAutoBin->isChecked()); AutoBin->setEnabled(!_realTimeAutoBin->isChecked()); } VectorPtr HistogramTab::vector() const { return _vector->selectedVector(); } bool HistogramTab::vectorDirty() const { return _vector->selectedVectorDirty(); } void HistogramTab::setVector(const VectorPtr vector) { _vector->setSelectedVector(vector); } double HistogramTab::min() const { return _min->text().toDouble(); } bool HistogramTab::minDirty() const { return !_min->text().isEmpty(); } void HistogramTab::setMin(const double min) { _min->setText(QString::number(min)); } double HistogramTab::max() const { return _max->text().toDouble(); } bool HistogramTab::maxDirty() const { return !_max->text().isEmpty(); } void HistogramTab::setMax(const double max) { _max->setText(QString::number(max)); } int HistogramTab::bins() const { return _numberOfBins->text().toInt(); } bool HistogramTab::binsDirty() const { return !_numberOfBins->text().isEmpty(); } void HistogramTab::setBins(const int bins) { _numberOfBins->setValue(bins); } bool HistogramTab::realTimeAutoBin() const { return _realTimeAutoBin->isChecked(); } bool HistogramTab::realTimeAutoBinDirty() const { return _realTimeAutoBin->checkState() != Qt::PartiallyChecked; } void HistogramTab::setRealTimeAutoBin(const bool autoBin) { _realTimeAutoBin->setChecked(autoBin); } Histogram::NormalizationType HistogramTab::normalizationType() const { Histogram::NormalizationType normalization = Histogram::Number; if (_normalizationIsFraction->isChecked()) { normalization = Histogram::Fraction; } else if (_normalizationIsPercent->isChecked()) { normalization = Histogram::Percent; } else if (_normalizationMaximumOne->isChecked()) { normalization = Histogram::MaximumOne; } return normalization; } bool HistogramTab::normalizationTypeDirty() const { return _normalizationDirty; } void HistogramTab::setNormalizationType(const Histogram::NormalizationType normalizationType) { switch (normalizationType) { case Histogram::Fraction: _normalizationIsFraction->setChecked(true); break; case Histogram::MaximumOne: _normalizationMaximumOne->setChecked(true); break; case Histogram::Number: _normalizationIsNumber->setChecked(true); break; case Histogram::Percent: _normalizationIsPercent->setChecked(true); break; } resetNormalizationDirty(); } CurveAppearance* HistogramTab::curveAppearance() const { return _curveAppearance; } CurvePlacement* HistogramTab::curvePlacement() const { return _curvePlacement; } void HistogramTab::setObjectStore(ObjectStore *store) { _vector->setObjectStore(store); } void HistogramTab::hideCurveOptions() { _curvePlacement->setVisible(false); _curveAppearance->setVisible(false); } void HistogramTab::clearTabValues() { _vector->clearSelection(); _min->clear(); _max->clear(); _numberOfBins->clear(); _realTimeAutoBin->setCheckState(Qt::PartiallyChecked); _normalizationIsNumber->setChecked(true); resetNormalizationDirty(); } HistogramDialog::HistogramDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Histogram")); else setWindowTitle(tr("New Histogram")); _histogramTab = new HistogramTab(this); addDataTab(_histogramTab); if (editMode() == Edit) { configureTab(dataObject); } else { configureTab(0); } connect(_histogramTab, SIGNAL(vectorChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_histogramTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } HistogramDialog::~HistogramDialog() { } // QString HistogramDialog::tagString() const { // return DataDialog::tagString(); // } void HistogramDialog::editMultipleMode() { _histogramTab->clearTabValues(); } void HistogramDialog::editSingleMode() { configureTab(dataObject()); } void HistogramDialog::configureTab(ObjectPtr object) { if (!object) { _histogramTab->setRealTimeAutoBin(_dialogDefaults->value("histogram/realTimeAutoBin", false).toBool()); _histogramTab->setNormalizationType(Histogram::NormalizationType(_dialogDefaults->value("histogram/normalizationType",Histogram::Number).toInt())); } else if (HistogramPtr histogram = kst_cast(object)) { _histogramTab->setVector(histogram->vector()); _histogramTab->setMin(histogram->xMin()); _histogramTab->setMax(histogram->xMax()); _histogramTab->setBins(histogram->numberOfBins()); _histogramTab->setRealTimeAutoBin(histogram->realTimeAutoBin()); _histogramTab->setNormalizationType(histogram->normalizationType()); _histogramTab->hideCurveOptions(); if (_editMultipleWidget) { HistogramList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(HistogramPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } void HistogramDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_histogramTab->vector() || (editMode() == EditMultiple)); } void HistogramDialog::setVector(VectorPtr vector) { _histogramTab->setVector(vector); } ObjectPtr HistogramDialog::createNewDataObject() { Q_ASSERT(_document && _document->objectStore()); HistogramPtr histogram = _document->objectStore()->createObject(); histogram->change(_histogramTab->vector(), _histogramTab->min(), _histogramTab->max(), _histogramTab->bins(), _histogramTab->normalizationType(), _histogramTab->realTimeAutoBin()); if (DataDialog::tagStringAuto()) { histogram->setDescriptiveName(QString()); } else { histogram->setDescriptiveName(DataDialog::tagString()); } histogram->writeLock(); histogram->registerChange(); histogram->unlock(); setHistogramDefaults(histogram); CurvePtr curve = _document->objectStore()->createObject(); curve->setXVector(histogram->vX()); curve->setYVector(histogram->vY()); curve->setColor(_histogramTab->curveAppearance()->color()); curve->setHeadColor(_histogramTab->curveAppearance()->headColor()); curve->setHasPoints(_histogramTab->curveAppearance()->showPoints()); curve->setHasLines(_histogramTab->curveAppearance()->showLines()); curve->setHasBars(_histogramTab->curveAppearance()->showBars()); curve->setHasHead(_histogramTab->curveAppearance()->showHead()); curve->setLineWidth(_histogramTab->curveAppearance()->lineWidth()); curve->setLineStyle(_histogramTab->curveAppearance()->lineStyle()); curve->setPointType(_histogramTab->curveAppearance()->pointType()); curve->setHeadType(_histogramTab->curveAppearance()->headType()); curve->setPointDensity(_histogramTab->curveAppearance()->pointDensity()); curve->setBarStyle(_histogramTab->curveAppearance()->barStyle()); curve->writeLock(); curve->registerChange(); curve->unlock(); PlotItem *plotItem = 0; switch (_histogramTab->curvePlacement()->place()) { case CurvePlacement::NoPlot: break; case CurvePlacement::ExistingPlot: { plotItem = static_cast(_histogramTab->curvePlacement()->existingPlot()); break; } case CurvePlacement::NewPlotNewTab: _document->createView(); // fall through to case NewPlot. case CurvePlacement::NewPlot: { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); if (_histogramTab->curvePlacement()->scaleFonts()) { plotItem->view()->resetPlotFontSizes(); } break; } default: break; } if (_histogramTab->curvePlacement()->place() != CurvePlacement::NoPlot) { PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(curve)); plotItem->update(); plotItem->view()->appendToLayout(_histogramTab->curvePlacement()->layout(), plotItem, _histogramTab->curvePlacement()->gridColumns()); } return ObjectPtr(histogram.data()); } ObjectPtr HistogramDialog::editExistingDataObject() const { if (HistogramPtr histogram = kst_cast(dataObject())) { if (editMode() == EditMultiple) { QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { HistogramPtr histogram = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (histogram) { VectorPtr vector = _histogramTab->vectorDirty() ? _histogramTab->vector() : histogram->vector(); const double min = _histogramTab->minDirty() ? _histogramTab->min() : histogram->xMin(); const double max = _histogramTab->maxDirty() ? _histogramTab->max() : histogram->xMax(); const int bins = _histogramTab->binsDirty() ? _histogramTab->bins() : histogram->numberOfBins(); Histogram::NormalizationType normalizationType = _histogramTab->normalizationTypeDirty() ? _histogramTab->normalizationType() : histogram->normalizationType(); const bool realTimeAutoBin = _histogramTab->realTimeAutoBinDirty() ? _histogramTab->realTimeAutoBin() : histogram->realTimeAutoBin(); histogram->writeLock(); histogram->setVector(vector); histogram->setXRange(min, max); histogram->setNumberOfBins(bins); histogram->setNormalizationType(normalizationType); histogram->setRealTimeAutoBin(realTimeAutoBin); histogram->unlock(); histogram->registerChange(); } } } else { histogram->writeLock(); histogram->setVector(_histogramTab->vector()); histogram->setXRange(_histogramTab->min(), _histogramTab->max()); histogram->setNumberOfBins(_histogramTab->bins()); histogram->setNormalizationType(_histogramTab->normalizationType()); histogram->setRealTimeAutoBin(_histogramTab->realTimeAutoBin()); if (DataDialog::tagStringAuto()) { histogram->setDescriptiveName(QString()); } else { histogram->setDescriptiveName(DataDialog::tagString()); } histogram->unlock(); histogram->registerChange(); setHistogramDefaults(histogram); } } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/scalardialog.h000644 001750 001750 00000005465 11544160207 020261 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SCALARDIALOG_H #define SCALARDIALOG_H #include "datadialog.h" #include "datatab.h" #include "datasource.h" #include "ui_scalartab.h" #include #include "kst_export.h" namespace Kst { class ScalarTab : public DataTab, Ui::ScalarTab { Q_OBJECT public: enum ScalarMode { DataScalar, GeneratedScalar, RVectorScalar }; explicit ScalarTab(ObjectStore *store, QWidget *parent = 0); virtual ~ScalarTab(); ScalarMode scalarMode() const { return _mode; } QString value() const; void setValue(const QString &value); DataSourcePtr dataSource() const; void setDataSource(DataSourcePtr dataSource); QString file() const; void setFile(const QString &file); QString field() const; void setField(const QString &field); QString fieldRV() const; void setFieldRV(const QString &field); int F0() const; void setF0(int f0); void hideGeneratedOptions(); void hideDataOptions(); void setRVOptions(); void setDataOptions(); Q_SIGNALS: void valueChanged(); void sourceChanged(); private Q_SLOTS: void readFromSourceChanged(); void entryChanged(); void fileNameChanged(const QString &file); void showConfigWidget(); void sourceValid(QString filename, int requestID); private: void updateDataSource(); ScalarMode _mode; ObjectStore *_store; DataSourcePtr _dataSource; int _requestID; }; class ScalarDialog : public DataDialog { Q_OBJECT public: explicit ScalarDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~ScalarDialog(); protected: virtual ObjectPtr createNewDataObject(); virtual ObjectPtr createNewGeneratedScalar(); virtual ObjectPtr createNewDataScalar(); virtual ObjectPtr createNewVScalar(); virtual ObjectPtr editExistingDataObject() const; private: void configureTab(ObjectPtr object); private Q_SLOTS: void updateButtons(); private: ScalarTab *_scalarTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/ellipseitem.h000644 001750 001750 00000003373 11544160207 020144 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ELLIPSEITEM_H #define ELLIPSEITEM_H #include "viewitem.h" #include "graphicsfactory.h" namespace Kst { class EllipseItem : public ViewItem { Q_OBJECT public: EllipseItem(View *parent); virtual ~EllipseItem(); virtual void save(QXmlStreamWriter &xml); virtual QPainterPath itemShape() const; virtual void paint(QPainter *painter); }; class CreateEllipseCommand : public CreateCommand { public: CreateEllipseCommand() : CreateCommand(QObject::tr("Create Ellipse")) {} CreateEllipseCommand(View *view) : CreateCommand(view, QObject::tr("Create Ellipse")) {} virtual ~CreateEllipseCommand() {} virtual void createItem(); }; class EllipseItemFactory : public GraphicsFactory { public: EllipseItemFactory(); ~EllipseItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/vectormodel.h000644 001750 001750 00000003203 11544160207 020143 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VECTORMODEL_H #define VECTORMODEL_H #include #include #include namespace Kst { class VectorModel : public QAbstractTableModel { public: VectorModel(Vector *v); ~VectorModel(); int columnCount(const QModelIndex& parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; QModelIndex parent(const QModelIndex& index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; Qt::ItemFlags flags(const QModelIndex& index) const; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); private: QPointer _vector; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/arrowpropertiestab.h000644 001750 001750 00000003022 11544160207 021555 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ARROWPROPERTIESTAB_H #define ARROWPROPERTIESTAB_H #include "dialogtab.h" #include "ui_arrowpropertiestab.h" #include "kst_export.h" namespace Kst { class ArrowPropertiesTab : public DialogTab, Ui::ArrowPropertiesTab { Q_OBJECT public: ArrowPropertiesTab(QWidget *parent = 0); virtual ~ArrowPropertiesTab(); bool startArrowHead(); void setStartArrowHead(const bool enabled); bool endArrowHead(); void setEndArrowHead(const bool enabled); qreal startArrowScale(); void setStartArrowScale(const qreal scale); qreal endArrowScale(); void setEndArrowScale(const qreal scale); public Q_SLOTS: void update(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/circleitem.h000644 001750 001750 00000003406 11544160207 017745 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CIRCLEITEM_H #define CIRCLEITEM_H #include "viewitem.h" #include "graphicsfactory.h" namespace Kst { class CircleItem : public ViewItem { Q_OBJECT public: CircleItem(View *parent); virtual ~CircleItem(); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); virtual void creationPolygonChanged(View::CreationEvent event); }; class CreateCircleCommand : public CreateCommand { public: CreateCircleCommand() : CreateCommand(QObject::tr("Create Circle")) {} CreateCircleCommand(View *view) : CreateCommand(view, QObject::tr("Create Circle")) {} virtual ~CreateCircleCommand() {} virtual void createItem(); }; class CircleItemFactory : public GraphicsFactory { public: CircleItemFactory(); ~CircleItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/cartesianrenderitem.cpp000644 001750 001750 00000007576 11544160207 022224 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 Theodore Kisner * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "cartesianrenderitem.h" #include #include #include "math_kst.h" #include "plotitem.h" namespace Kst { CartesianRenderItem::CartesianRenderItem(PlotItem *parentItem) : PlotRenderItem(parentItem) { setType(Cartesian); setTypeName(tr("Cartesian Plot")); } CartesianRenderItem::~CartesianRenderItem() { } void CartesianRenderItem::paintRelations(QPainter *painter) { QRectF normalRect = rect(); normalRect = normalRect.normalized(); painter->save(); painter->translate(normalRect.x(), normalRect.y()); foreach (RelationPtr relation, relationList()) { CurveRenderContext context; context.painter = painter; context.window = QRect(); //no idea if this should be floating point context.penWidth = painter->pen().width(); //floating point?? context.xLog = plotItem()->xAxis()->axisLog(); context.yLog = plotItem()->yAxis()->axisLog(); context.xLogBase = 10.0/*plotItem()->xLogBase()*/; context.yLogBase = 10.0/*plotItem()->yLogBase()*/; context.foregroundColor = painter->pen().color(); context.backgroundColor = painter->brush().color(); //FIXME rename these methods in kstvcurve //FIXME Completely refactor KstCurveRenderContext now that we know what these are //Set the projection box... context.XMin = projectionRect().left(); context.XMax = projectionRect().right(); context.YMin = projectionRect().top(); context.YMax = projectionRect().bottom(); //Set the log box... context.x_max = plotItem()->xAxis()->axisLog() ? logXHi(context.XMax, context.xLogBase) : context.XMax; context.y_max = plotItem()->yAxis()->axisLog() ? logXHi(context.YMax, context.yLogBase) : context.YMax; context.x_min = plotItem()->xAxis()->axisLog() ? logXLo(context.XMin, context.xLogBase) : context.XMin; context.y_min = plotItem()->yAxis()->axisLog() ? logXLo(context.YMin, context.yLogBase) : context.YMin; //These are the bounding box in regular QGV coord context.Lx = plotRect().left(); context.Hx = plotRect().right(); context.Ly = plotRect().top(); context.Hy = plotRect().bottom(); //To convert between the last two... double m_X = double(plotRect().width()-1)/(context.x_max - context.x_min); double m_Y = -double(plotRect().height()-1)/(context.y_max - context.y_min); double b_X = context.Lx - m_X * context.x_min; double b_Y = context.Ly - m_Y * context.y_max; context.m_X = m_X; context.m_Y = m_Y; context.b_X = b_X; context.b_Y = b_Y; relation->paint(context); } painter->restore(); } void CartesianRenderItem::saveInPlot(QXmlStreamWriter &xml) { xml.writeStartElement("cartesianrender"); PlotRenderItem::saveInPlot(xml); xml.writeEndElement(); } bool CartesianRenderItem::configureFromXml(QXmlStreamReader &xml, ObjectStore *store) { bool validTag = false; if (xml.isStartElement() && xml.name().toString() == "cartesianrender") { validTag = PlotRenderItem::configureFromXml(xml, store); if (validTag && xml.isEndElement() && xml.name().toString() == "cartesianrender") { validTag = true; } } return validTag; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/mainwindow.h000644 001750 001750 00000017673 11544160207 020014 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include class QMenu; class QAction; class QProgressBar; class QUndoGroup; class QPrinter; namespace Kst { class DataManager; class DebugDialog; class Document; class ExportGraphicsDialog; class ExportVectorsDialog; class LogDialog; class DifferentiateCurvesDialog; class ChooseColorDialog; class ChangeDataSampleDialog; class ChangeFileDialog; class BugReportWizard; class ApplicationSettingsDialog; class AboutDialog; class TabWidget; class View; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); ~MainWindow(); QUndoGroup *undoGroup() const; TabWidget *tabWidget() const; Document *document() const; QProgressBar *progressBar() const; bool initFromCommandLine(); bool isHighlightPoint() { return _highlightPoint; } bool isTiedTabs(); void setStatusMessage(QString message); static void setWidgetFlags(QWidget*); public Q_SLOTS: void showDataManager(); void showDebugDialog(); void showExportGraphicsDialog(); void showExportVectorsDialog(); void showLogDialog(); void showVectorEditor(); void showScalarEditor(); void showMatrixEditor(); void showStringEditor(); void showSettingsDialog(); void showDifferentiateCurvesDialog(); void showChooseColorDialog(); void showChangeDataSampleDialog(); void showChangeFileDialog(); void showDataWizard(); void showBugReportWizard(); void showPluginDialog(QString &pluginName); void readFromEnd(); void readToEnd(); void pause(bool pause); void back(); void forward(); void reload(); void updateViewItems(qint64 serial); void save(); void saveAs(); void open(); void newDoc(); void openFile(const QString &file); void print(); void setPrinterDefaults(QPrinter *printer); void savePrinterDefaults(QPrinter *printer); void printToPrinter(QPrinter *printer); void printFromCommandLine(const QString &printFileName); void exportGraphicsFile(const QString &filename, const QString &format, int w, int h, int display); void exportLog(const QString &imagename, QString &msgfilename, const QString &_format, int x_size, int y_size, int size_option_index, const QString &message); void clearDrawingMarker(); void tiedZoomRemoved(); void allPlotsTiedZoom(); void updateRecentDataFiles(const QString& newfilename = QString()); private Q_SLOTS: void aboutToQuit(); void about(); void currentViewChanged(); void currentViewModeChanged(); void createBox(); void createEllipse(); void createLabel(); void createCircle(); void createLine(); void createArrow(); void createPicture(); void createPlot(); void createSvg(); void createSharedAxisBox(); void createScalar(); void createVector(); void createMatrix(); void createString(); void createCurve(); void createPSD(); void createEquation(); void createHistogram(); void createImage(); void createSpectogram(); void createEventMonitor(); void performHeavyStartupActions(); void cleanup(); void setLayoutMode(bool layoutMode); void toggleTiedZoom(); void setHighlightPoint(bool); void changeZoomOnlyMode(QAction*); void openRecentKstFile(); void openRecentDataFile(); void updateRecentKstFiles(const QString& newfilename = QString()); void checkRecentFilesOnExistence(); protected: void closeEvent(QCloseEvent *e); private: void createActions(); void createMenus(); void createStatusBar(); void createToolBars(); void readSettings(); void writeSettings(); bool promptSave(); QAction* createRecentFileAction(const QString& filename, int idx, const QString& text, const char* openslot); void updateRecentFiles(const QString& key, QMenu *menu, QList& actions, QMenu* submenu, const QString& newfilename, const char* openslot); private: Document *_doc; TabWidget *_tabWidget; QUndoGroup *_undoGroup; DataManager *_dataManager; DebugDialog *_debugDialog; ExportGraphicsDialog *_exportGraphics; ExportVectorsDialog *_exportVectors; LogDialog *_logDialog; DifferentiateCurvesDialog *_differentiateCurvesDialog; ChooseColorDialog *_chooseColorDialog; ChangeDataSampleDialog *_changeDataSampleDialog; ChangeFileDialog *_changeFileDialog; BugReportWizard *_bugReportWizard; ApplicationSettingsDialog *_applicationSettingsDialog; AboutDialog* _aboutDialog; QPointer _progressBar; QLabel *_messageLabel; bool _highlightPoint; QMenu *_fileMenu; QMenu *_editMenu; QMenu *_viewMenu; QMenu *_createMenu; QMenu *_pluginsMenu; QMenu *_fitsPluginsMenu; QMenu *_filterPluginsMenu; QMenu *_modeMenu; QMenu *_rangeMenu; QMenu *_toolsMenu; QMenu *_settingsMenu; QMenu *_helpMenu; QToolBar *_fileToolBar; QToolBar *_editToolBar; QToolBar *_rangeToolBar; QToolBar *_modeToolBar; QToolBar *_toolsToolBar; QToolBar *_annotationToolBar; QAction *_undoAct; QAction *_redoAct; // FIXME: move these into each object, along with the creation slot? QAction *_createLabelAct; QAction *_createBoxAct; QAction *_createCircleAct; QAction *_createEllipseAct; QAction *_createLineAct; QAction *_createArrowAct; QAction *_createPictureAct; QAction *_createPlotAct; QAction *_createSvgAct; QAction *_createSharedAxisBoxAct; QAction *_aboutAct; QAction *_dataManagerAct; QAction *_debugDialogAct; QAction *_exitAct; QAction *_exportGraphicsAct; QAction *_exportVectorsAct; QAction *_logAct; QAction *_openAct; QAction *_saveAct; QAction *_saveAsAct; QAction *_closeAct; QAction *_printAct; QAction *_newTabAct; QAction *_closeTabAct; QAction *_scalarEditorAct; QAction *_vectorEditorAct; QAction *_matrixEditorAct; QAction *_stringEditorAct; QAction *_layoutModeAct; QAction *_tiedZoomAct; QAction *_tabTiedAct; QAction *_highlightPointAct; QAction *_standardZoomAct; QAction *_xOnlyZoomAct; QAction *_yOnlyZoomAct; QAction *_settingsDialogAct; QAction *_differentiateCurvesDialogAct; QAction *_chooseColorDialogAct; QAction *_changeDataSampleDialogAct; QAction *_changeFileDialogAct; QAction *_dataWizardAct; QAction *_bugReportWizardAct; QAction *_readFromEndAct; QAction *_readToEndAct; QAction *_pauseAct; QAction *_backAct; QAction *_forwardAct; QAction *_reloadAct; QAction *_newScalarAct; QAction *_newVectorAct; QAction *_newMatrixAct; QAction *_newStringAct; QAction *_newCurveAct; QAction *_newEquationAct; QAction *_newPSDAct; QAction *_newHistogramAct; QAction *_newImageAct; QAction *_newSpectrogramAct; QAction *_newEventMonitorAct; QMenu* _recentKstFilesMenu; QMenu* _recentDataFilesMenu; QList _bottomRecentKstActions; QList _bottomRecentDataActions; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/csddialog.cpp000644 001750 001750 00000024741 11544160207 020116 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "csddialog.h" #include "dialogpage.h" #include "editmultiplewidget.h" #include "psd.h" #include "view.h" #include "plotitem.h" #include "tabwidget.h" #include "mainwindow.h" #include "document.h" #include "objectstore.h" #include "application.h" #include "plotrenderitem.h" #include "curve.h" #include "palette.h" #include "image.h" #include "datacollection.h" #include namespace Kst { CSDTab::CSDTab(QWidget *parent) : DataTab(parent) { setupUi(this); setTabTitle(tr("Cumulative Spectral Decay")); connect(_vector, SIGNAL(selectionChanged(QString)), this, SLOT(selectionChanged())); connect(_FFTOptions, SIGNAL(modified()), this, SIGNAL(modified())); connect(_vector, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); connect(_windowSize, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); } CSDTab::~CSDTab() { } void CSDTab::selectionChanged() { emit optionsChanged(); } VectorPtr CSDTab::vector() const { return _vector->selectedVector(); } bool CSDTab::vectorDirty() const { return _vector->selectedVectorDirty(); } void CSDTab::setVector(const VectorPtr vector) { _vector->setSelectedVector(vector); } CurvePlacement* CSDTab::curvePlacement() const { return _curvePlacement; } FFTOptions* CSDTab::FFTOptionsWidget() const { return _FFTOptions; } ColorPalette* CSDTab::colorPalette() const { return _colorPalette; } int CSDTab::windowSize() const { return _windowSize->value(); } bool CSDTab::windowSizeDirty() const { return !_windowSize->text().isEmpty(); } void CSDTab::setWindowSize(const int windowSize) { _windowSize->setValue(windowSize); } void CSDTab::setObjectStore(ObjectStore *store) { _vector->setObjectStore(store); } void CSDTab::hideImageOptions() { _imageOptionsGroup->setVisible(false); _curvePlacement->setVisible(false); } void CSDTab::clearTabValues() { _vector->clearSelection(); _windowSize->clear(); _FFTOptions->clearValues(); _FFTOptions->disableInterpolateOverHoles(); } CSDDialog::CSDDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Cumulative Spectral Decay")); else setWindowTitle(tr("New Cumulative Spectral Decay")); _CSDTab = new CSDTab(this); addDataTab(_CSDTab); if (editMode() == Edit) { configureTab(dataObject); } _CSDTab->FFTOptionsWidget()->disableInterpolateOverHoles(); connect(_CSDTab, SIGNAL(optionsChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_CSDTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } CSDDialog::~CSDDialog() { } // QString CSDDialog::tagString() const { // return DataDialog::tagString(); // } void CSDDialog::editMultipleMode() { _CSDTab->clearTabValues(); } void CSDDialog::editSingleMode() { configureTab(dataObject()); } void CSDDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_CSDTab->vector() || (editMode() == EditMultiple)); } void CSDDialog::setVector(VectorPtr vector) { _CSDTab->setVector(vector); } void CSDDialog::configureTab(ObjectPtr object) { if (CSDPtr csd = kst_cast(object)) { _CSDTab->setVector(csd->vector()); _CSDTab->setWindowSize(csd->windowSize()); _CSDTab->FFTOptionsWidget()->setSampleRate(csd->frequency()); _CSDTab->FFTOptionsWidget()->setInterleavedAverage(csd->average()); _CSDTab->FFTOptionsWidget()->setFFTLength(csd->length()); _CSDTab->FFTOptionsWidget()->setApodize(csd->apodize()); _CSDTab->FFTOptionsWidget()->setRemoveMean(csd->removeMean()); _CSDTab->FFTOptionsWidget()->setVectorUnits(csd->vectorUnits()); _CSDTab->FFTOptionsWidget()->setRateUnits(csd->rateUnits()); _CSDTab->FFTOptionsWidget()->setApodizeFunction(csd->apodizeFxn()); _CSDTab->FFTOptionsWidget()->setSigma(csd->gaussianSigma()); _CSDTab->FFTOptionsWidget()->setOutput(csd->output()); _CSDTab->hideImageOptions(); if (_editMultipleWidget) { CSDList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(CSDPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } ObjectPtr CSDDialog::createNewDataObject() { Q_ASSERT(_document && _document->objectStore()); CSDPtr csd = _document->objectStore()->createObject(); csd->change(_CSDTab->vector(), _CSDTab->FFTOptionsWidget()->sampleRate(), _CSDTab->FFTOptionsWidget()->interleavedAverage(), _CSDTab->FFTOptionsWidget()->removeMean(), _CSDTab->FFTOptionsWidget()->apodize(), _CSDTab->FFTOptionsWidget()->apodizeFunction(), _CSDTab->windowSize(), _CSDTab->FFTOptionsWidget()->FFTLength(), _CSDTab->FFTOptionsWidget()->sigma(), _CSDTab->FFTOptionsWidget()->output(), _CSDTab->FFTOptionsWidget()->vectorUnits(), _CSDTab->FFTOptionsWidget()->rateUnits()); if (DataDialog::tagStringAuto()) { csd->setDescriptiveName(QString()); } else { csd->setDescriptiveName(DataDialog::tagString()); } csd->writeLock(); csd->registerChange(); csd->unlock(); ImagePtr image = _document->objectStore()->createObject(); image->changeToColorOnly(csd->outputMatrix(), 0, 1, true, _CSDTab->colorPalette()->selectedPalette()); image->writeLock(); image->registerChange(); image->unlock(); PlotItem *plotItem = 0; switch (_CSDTab->curvePlacement()->place()) { case CurvePlacement::NoPlot: break; case CurvePlacement::ExistingPlot: { plotItem = static_cast(_CSDTab->curvePlacement()->existingPlot()); break; } case CurvePlacement::NewPlot: { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); if (_CSDTab->curvePlacement()->scaleFonts()) { plotItem->view()->resetPlotFontSizes(); } break; } default: break; } if (_CSDTab->curvePlacement()->place() != CurvePlacement::NoPlot) { PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(image)); plotItem->update(); plotItem->view()->appendToLayout(_CSDTab->curvePlacement()->layout(), plotItem, _CSDTab->curvePlacement()->gridColumns()); } return ObjectPtr(image.data()); } ObjectPtr CSDDialog::editExistingDataObject() const { if (CSDPtr csd = kst_cast(dataObject())) { if (editMode() == EditMultiple) { const FFTOptions *options = _CSDTab->FFTOptionsWidget(); QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { CSDPtr csd = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (csd) { VectorPtr vector = _CSDTab->vectorDirty() ? _CSDTab->vector() : csd->vector(); const double frequency = options->sampleRateDirty() ? options->sampleRate() : csd->frequency(); const double sigma = options->sigmaDirty() ? options->sigma() : csd->gaussianSigma(); const bool apodize = options->apodizeDirty() ? options->apodize() : csd->apodize(); const bool removeMean = options->removeMeanDirty() ? options->removeMean() : csd->removeMean(); const bool interleavedAverage = options->interleavedAverageDirty() ? options->interleavedAverage() : csd->average(); const int FFTLength = options->FFTLengthDirty() ? options->FFTLength() : csd->length(); const ApodizeFunction apodizeFunction = options->apodizeFunctionDirty() ? options->apodizeFunction() : csd->apodizeFxn(); const PSDType output = options->outputDirty() ? options->output() : csd->output(); const QString vectorUnits = options->vectorUnitsDirty() ? options->vectorUnits() : csd->vectorUnits(); const QString rateUnits = options->rateUnitsDirty() ? options->rateUnits() : csd->rateUnits(); const int windowSize = _CSDTab->windowSizeDirty() ? _CSDTab->windowSize() : csd->windowSize(); csd->writeLock(); csd->change(vector, frequency, interleavedAverage, removeMean, apodize, apodizeFunction, windowSize, FFTLength, sigma, output, vectorUnits, rateUnits); csd->registerChange(); csd->unlock(); } } } else { csd->writeLock(); csd->change(_CSDTab->vector(), _CSDTab->FFTOptionsWidget()->sampleRate(), _CSDTab->FFTOptionsWidget()->interleavedAverage(), _CSDTab->FFTOptionsWidget()->removeMean(), _CSDTab->FFTOptionsWidget()->apodize(), _CSDTab->FFTOptionsWidget()->apodizeFunction(), _CSDTab->windowSize(), _CSDTab->FFTOptionsWidget()->FFTLength(), _CSDTab->FFTOptionsWidget()->sigma(), _CSDTab->FFTOptionsWidget()->output(), _CSDTab->FFTOptionsWidget()->vectorUnits(), _CSDTab->FFTOptionsWidget()->rateUnits()); if (DataDialog::tagStringAuto()) { csd->setDescriptiveName(QString()); } else { csd->setDescriptiveName(DataDialog::tagString()); } csd->registerChange(); csd->unlock(); } } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/sharedaxisboxitem.cpp000644 001750 001750 00000106653 11544160207 021713 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "sharedaxisboxitem.h" #include "plotitem.h" #include "plotitemmanager.h" #include "gridlayouthelper.h" #include "viewgridlayout.h" #include "application.h" #include #include #include #include #include // Zoom Debugging. 0 Off, 1 On. #define DEBUG_ZOOM 0 namespace Kst { SharedAxisBoxItem::SharedAxisBoxItem(View *parent) : ViewItem(parent), _layout(0), _loaded(false), _firstPaint(true), _dirty(false), _shareX(true), _shareY(true), _xAxisZoomMode(PlotAxis::Auto), _yAxisZoomMode(PlotAxis::Auto), _sharedIsDirty(false) { setTypeName("Shared Axis Box"); setBrush(Qt::transparent); _breakAction = new QAction(tr("Break Shared Axis Box"), this); _breakAction->setShortcut(Qt::Key_B); registerShortcut(_breakAction); connect(_breakAction, SIGNAL(triggered()), this, SLOT(breakShare())); connect(this, SIGNAL(breakShareSignal()), this, SLOT(breakShare())); } SharedAxisBoxItem::~SharedAxisBoxItem() { } void SharedAxisBoxItem::paint(QPainter *painter) { if (_dirty) { if (_firstPaint && _loaded) { sharePlots(painter, true); _firstPaint = false; } else if (_sharedIsDirty) { sharePlots(painter, false); } _sharedIsDirty = false; updatePlotTiedZoomSupport(); _keyPlot = 0; foreach (PlotItem* plotItem, _sharedPlots) { if (!_keyPlot) { _keyPlot = plotItem; } else { if ((plotItem->pos().x() > _keyPlot->pos().x()) || ((plotItem->pos().y() < _keyPlot->pos().y()))) { _keyPlot = plotItem; } } } _dirty = false; } painter->drawRect(rect()); } void SharedAxisBoxItem::updatePlotTiedZoomSupport() { foreach (PlotItem* plot, _sharedPlots) { plot->setSupportsTiedZoom(!(_shareX && _shareY)); } } void SharedAxisBoxItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("sharedaxisbox"); xml.writeAttribute("sharex", QVariant(isXAxisShared()).toString()); xml.writeAttribute("sharey", QVariant(isYAxisShared()).toString()); xml.writeAttribute("xzoommode", QVariant(xAxisZoomMode()).toString()); xml.writeAttribute("yzoommode", QVariant(yAxisZoomMode()).toString()); ViewItem::save(xml); xml.writeEndElement(); } } void SharedAxisBoxItem::setXAxisZoomMode(PlotAxis::ZoomMode mode) { _xAxisZoomMode = mode; } void SharedAxisBoxItem::setYAxisZoomMode(PlotAxis::ZoomMode mode) { _yAxisZoomMode = mode; } void SharedAxisBoxItem::setXAxisShared(const bool shared) { _shareX = shared; if (shared) { _xAxisZoomMode = PlotAxis::Auto; } else { _xAxisZoomMode = PlotAxis::FixedExpression; } _sharedIsDirty = true; } void SharedAxisBoxItem::setYAxisShared(const bool shared) { _shareY = shared; if (shared) { _yAxisZoomMode = PlotAxis::Auto; } else { _yAxisZoomMode = PlotAxis::FixedExpression; } _sharedIsDirty = true; } bool SharedAxisBoxItem::acceptItems() { bool bReturn = false; if (_loaded) { return true; } else { _loaded = true; } _sharedPlots.clear(); QRectF maxSize(mapToParent(viewRect().topLeft()), mapToParent(viewRect().bottomRight())); ViewItem* child = 0; if (view()) { QList list = view()->items(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem || !viewItem->isVisible() || viewItem == this || viewItem == parentItem() || !collidesWithItem(viewItem, Qt::IntersectsItemBoundingRect)) { continue; } if (PlotItem *plotItem = qobject_cast(viewItem)) { if (plotItem->parentItem()) { ViewItem *parent = static_cast(plotItem->parentItem()); SharedAxisBoxItem *shareBox = qobject_cast(parent); if (shareBox) { shareBox->breakShare(); } else if (parent != parentItem()) { continue; } } else if (parentItem()) { continue; } plotItem->setSharedAxisBox(this); _sharedPlots << plotItem; connect(plotItem, SIGNAL(breakShareTriggered()), this, SLOT(breakShare())); connect(plotItem, SIGNAL(shareXAxisTriggered()), this, SLOT(shareXAxis())); connect(plotItem, SIGNAL(shareYAxisTriggered()), this, SLOT(shareYAxis())); child = plotItem; if (!maxSize.contains(plotItem->mapToParent(plotItem->viewRect().topLeft()))) { maxSize.setTop(qMin(plotItem->mapToParent(plotItem->viewRect().topLeft()).y(), maxSize.top())); maxSize.setLeft(qMin(plotItem->mapToParent(plotItem->viewRect().topLeft()).x(), maxSize.left())); } if (!maxSize.contains(plotItem->mapToParent(plotItem->viewRect().bottomRight()))) { maxSize.setBottom(qMax(plotItem->mapToParent(plotItem->viewRect().bottomRight()).y(), maxSize.bottom())); maxSize.setRight(qMax(plotItem->mapToParent(plotItem->viewRect().bottomRight()).x(), maxSize.right())); } } } if (child) { setPen(QPen(Qt::white)); setBrush(Qt::white); ViewGridLayout::updateProjections(this); _dirty = true; bReturn = true; } } if (maxSize != viewRect()) { setPos(maxSize.topLeft()); setViewRect(QRectF(mapFromParent(maxSize.topLeft()), mapFromParent(maxSize.bottomRight()))); } return bReturn; } void SharedAxisBoxItem::breakShare() { _loaded = false; QList list = getSharedPlots(); foreach (PlotItem *plotItem, list) { plotItem->setPos(mapToParent(plotItem->pos())); plotItem->setSharedAxisBox(0); plotItem->setTopSuppressed(false); plotItem->setBottomSuppressed(false); plotItem->setLeftSuppressed(false); plotItem->setRightSuppressed(false); plotItem->update(); } if (_layout) { _layout->reset(); } hide(); } void SharedAxisBoxItem::lockItems() { _sharedPlots.clear(); QList list = QGraphicsItem::children(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem) continue; if (PlotItem *plotItem = qobject_cast(viewItem)) { plotItem->setAllowedGripModes(0); plotItem->setFlags(0); _sharedPlots << plotItem; } } if (!list.isEmpty()) { setPen(QPen(Qt::white)); setBrush(Qt::white); } } void SharedAxisBoxItem::shareXAxis() { _shareX = !_shareX; _sharedIsDirty = true; updateShare(); } void SharedAxisBoxItem::shareYAxis() { _shareY = !_shareY; _sharedIsDirty = true; updateShare(); } void SharedAxisBoxItem::updateShare() { if (!_shareX && !_shareY) { breakShare(); } else { ViewGridLayout::updateProjections(this, _shareX, _shareY); view()->setPlotBordersDirty(true); setDirty(); update(); } } void SharedAxisBoxItem::addToMenuForContextEvent(QMenu &menu) { menu.addAction(_breakAction); } void SharedAxisBoxItem::triggerContextEvent(QGraphicsSceneContextMenuEvent *event) { contextMenuEvent(event); } void SharedAxisBoxItem::creationPolygonChanged(View::CreationEvent event) { if (event == View::MousePress) { ViewItem::creationPolygonChanged(event); return; } if (event == View::MouseMove) { ViewItem::creationPolygonChanged(event); if (creationState() == ViewItem::None) { return; } QList plots; if (view()) { QList list = view()->items(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem || !viewItem->isVisible() || viewItem == this || viewItem == parentItem() || !collidesWithItem(viewItem, Qt::IntersectsItemBoundingRect)) { continue; } if (PlotItem *plotItem = qobject_cast(viewItem)) { plots.append(plotItem); } } highlightPlots(plots); } return; } if (event == View::EscapeEvent || event == View::MouseRelease) { ViewItem::creationPolygonChanged(event); highlightPlots(QList()); return; } } void SharedAxisBoxItem::highlightPlots(QList plots) { QList currentlyHighlighted = _highlightedPlots; _highlightedPlots.clear(); foreach(PlotItem *plotItem, plots) { _highlightedPlots.append(plotItem); if (!currentlyHighlighted.contains(plotItem)) { plotItem->setHighlighted(true); plotItem->update(); } } foreach(PlotItem* plotItem, currentlyHighlighted) { if (!_highlightedPlots.contains(plotItem)) { plotItem->setHighlighted(false); plotItem->update(); } } } bool SharedAxisBoxItem::tryMousePressEvent(ViewItem* viewItem, QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { if (checkBox().contains(viewItem->mapToParent(event->pos()))) { setTiedZoom(!isTiedZoom(), !isTiedZoom()); return true; } } return false; } QList SharedAxisBoxItem::getSharedPlots() { return _sharedPlots; } QList SharedAxisBoxItem::getTiedPlots(PlotItem* originPlotItem) { QList plots; if (originPlotItem) { return PlotItemManager::tiedZoomPlotsForView(view()); } return plots; } QRectF SharedAxisBoxItem::computeRect(PlotAxis::ZoomMode xZoomMode, PlotAxis::ZoomMode yZoomMode) { QRectF computedRect; foreach(PlotItem* plot, getSharedPlots()) { PlotAxis::ZoomMode existingXMode = plot->xAxis()->axisZoomMode(); PlotAxis::ZoomMode existingYMode = plot->yAxis()->axisZoomMode(); plot->xAxis()->setAxisZoomMode(xZoomMode); plot->yAxis()->setAxisZoomMode(yZoomMode); if (computedRect.isValid()) { computedRect = computedRect.united(plot->computedProjectionRect()); } else { computedRect = plot->computedProjectionRect(); } plot->xAxis()->setAxisZoomMode(existingXMode); plot->yAxis()->setAxisZoomMode(existingYMode); } return computedRect; } void SharedAxisBoxItem::applyZoom(const QRectF &projection, PlotItem* originPlotItem, bool applyX, bool applyY) { QList allPlots = getSharedPlots(); QList plotTied; if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach (PlotItem* plotItem, plotTied) { // tie only changes the unshared axis for shared plots if (!_shareX || !plotItem->isInSharedAxisBox()) { switch (xAxisZoomMode()) { case PlotAxis::Auto: plotItem->zoomXMaximum(true); break; case PlotAxis::AutoBorder: plotItem->zoomXAutoBorder(true); break; case PlotAxis::SpikeInsensitive: plotItem->zoomXNoSpike(true); break; default: plotItem->zoomXRange(projection,true); break; } } if (!_shareY || !plotItem->isInSharedAxisBox()) { switch (yAxisZoomMode()) { case PlotAxis::Auto: plotItem->zoomYMaximum(true); break; case PlotAxis::AutoBorder: plotItem->zoomYAutoBorder(true); break; case PlotAxis::SpikeInsensitive: plotItem->zoomYNoSpike(true); break; default: plotItem->zoomYRange(projection,true); break; } } } } foreach (PlotItem* plotItem, allPlots) { if ((applyX && applyY) && ((_shareX && _shareY) || (isXTiedZoom() && isYTiedZoom()))) { plotItem->zoomFixedExpression(projection, true); } else if (applyX && (_shareX || isXTiedZoom() || (plotItem == originPlotItem))) { plotItem->zoomXRange(QRectF(projection.x(), plotItem->projectionRect().y(), projection.width(), plotItem->projectionRect().height()), true); } else if (applyY && (_shareY || isYTiedZoom() || (plotItem == originPlotItem))) { plotItem->zoomYRange(QRectF(plotItem->projectionRect().x(), projection.y(), plotItem->projectionRect().width(), projection.height()), true); } } } void SharedAxisBoxItem::zoomFixedExpression(const QRectF &projection, PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomFixedExpression" << projection; #endif _xAxisZoomMode = PlotAxis::FixedExpression; _yAxisZoomMode = PlotAxis::FixedExpression; if (originPlotItem) { originPlotItem->zoomFixedExpression(projection, true); } applyZoom(projection, originPlotItem); } void SharedAxisBoxItem::zoomXRange(const QRectF &projection, PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXRange" << projection << endl; #endif if (!_shareX) { if (originPlotItem) { originPlotItem->zoomXRange(projection, true); if (originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { plotItem->zoomXRange(projection, true); } } } } else { _xAxisZoomMode = PlotAxis::FixedExpression; applyZoom(projection, originPlotItem, true, false); } } void SharedAxisBoxItem::zoomYRange(const QRectF &projection, PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYRange" << projection << endl; #endif if (!_shareY) { if (originPlotItem) { originPlotItem->zoomYRange(projection, true); if (originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { plotItem->zoomYRange(projection, true); } } } } else { _yAxisZoomMode = PlotAxis::FixedExpression; applyZoom(projection, originPlotItem, false, true); } } void SharedAxisBoxItem::zoomMaximum(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomMaximum" << endl; #endif if (!originPlotItem) { originPlotItem = keyPlot(); } _xAxisZoomMode = PlotAxis::Auto; _yAxisZoomMode = PlotAxis::AutoBorder; if (originPlotItem) { originPlotItem->zoomMaximum(true); } applyZoom(computeRect(PlotAxis::Auto, PlotAxis::AutoBorder), originPlotItem); } void SharedAxisBoxItem::zoomMaxSpikeInsensitive(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomMaxSpikeInsensitive" << endl; #endif _xAxisZoomMode = PlotAxis::Auto; _yAxisZoomMode = PlotAxis::SpikeInsensitive; if (originPlotItem) { originPlotItem->zoomMaxSpikeInsensitive(true); } applyZoom(computeRect(PlotAxis::Auto, PlotAxis::SpikeInsensitive), originPlotItem); } void SharedAxisBoxItem::zoomMeanCentered(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomMeanCentered" << endl; #endif _yAxisZoomMode = PlotAxis::MeanCentered; applyZoom(computeRect(PlotAxis::Auto, PlotAxis::MeanCentered), originPlotItem, false, true); } void SharedAxisBoxItem::zoomYMeanCentered(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYMeanCentered" << endl; #endif _yAxisZoomMode = PlotAxis::MeanCentered; if (originPlotItem) { originPlotItem->zoomYMeanCentered(true); } applyZoom(computeRect(PlotAxis::Auto, PlotAxis::MeanCentered), originPlotItem, false, true); } void SharedAxisBoxItem::zoomXMeanCentered(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXMeanCentered" << endl; #endif _xAxisZoomMode = PlotAxis::MeanCentered; if (originPlotItem) { originPlotItem->zoomXMeanCentered(true); } applyZoom(computeRect(PlotAxis::MeanCentered, PlotAxis::MeanCentered), originPlotItem, true, false); } void SharedAxisBoxItem::zoomXMaximum(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXMaximum" << endl; #endif _xAxisZoomMode = PlotAxis::Auto; if (originPlotItem) { originPlotItem->zoomXMaximum(true); } applyZoom(computeRect(PlotAxis::Auto, PlotAxis::Auto), originPlotItem, true, false); } void SharedAxisBoxItem::zoomXNoSpike(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXNoSpike" << endl; #endif _xAxisZoomMode = PlotAxis::SpikeInsensitive; if (originPlotItem) { originPlotItem->zoomXNoSpike(true); } applyZoom(computeRect(PlotAxis::SpikeInsensitive, PlotAxis::Auto), originPlotItem, true, false); } void SharedAxisBoxItem::zoomXAutoBorder(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXAutoBorder" << endl; #endif _xAxisZoomMode = PlotAxis::AutoBorder; if (originPlotItem) { originPlotItem->zoomXAutoBorder(true); } applyZoom(computeRect(PlotAxis::AutoBorder, PlotAxis::Auto), originPlotItem, true, false); } void SharedAxisBoxItem::zoomXRight(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXRight" << endl; #endif QList allPlots; if (_shareX) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareX || origin_tied)) { if (originPlotItem) { originPlotItem->zoomXRight(true); } } else { _xAxisZoomMode = PlotAxis::FixedExpression; foreach(PlotItem* plotItem, allPlots) { plotItem->zoomXRight(true); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomXRight(true); } } } } void SharedAxisBoxItem::zoomXLeft(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXLeft" << endl; #endif QList allPlots; if (_shareX) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareX || origin_tied)) { if (originPlotItem) { originPlotItem->zoomXLeft(true); } } else { _xAxisZoomMode = PlotAxis::FixedExpression; foreach(PlotItem* plotItem, allPlots) { plotItem->zoomXLeft(true); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomXLeft(true); } } } } void SharedAxisBoxItem::zoomXOut(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXOut" << endl; #endif QList allPlots; if (_shareX) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareX || origin_tied)) { if (originPlotItem) { originPlotItem->zoomXOut(true); } } else { _xAxisZoomMode = PlotAxis::FixedExpression; foreach(PlotItem* plotItem, allPlots) { plotItem->zoomXOut(true); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomXOut(true); } } } } void SharedAxisBoxItem::zoomXIn(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomXIn" << endl; #endif QList allPlots; if (_shareX) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareX || origin_tied)) { if (originPlotItem) { originPlotItem->zoomXIn(true); } } else { _xAxisZoomMode = PlotAxis::FixedExpression; foreach(PlotItem* plotItem, allPlots) { plotItem->zoomXIn(true); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomXIn(true); } } } } void SharedAxisBoxItem::zoomNormalizeXtoY(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomNormalizeXtoY" << endl; #endif if (!(_shareX || isXTiedZoom())) { if (originPlotItem) { originPlotItem->zoomNormalizeXtoY(true); } } else { QRectF computedRect; foreach(PlotItem *plotItem, getSharedPlots()) { QRectF compute = plotItem->projectionRect(); qreal mean = compute.center().x(); qreal range = plotItem->plotRect().width() * compute.height() / plotItem->plotRect().height(); compute.setLeft(mean - (range / 2.0)); compute.setRight(mean + (range / 2.0)); if (computedRect.isValid()) { computedRect = computedRect.united(compute); } else { computedRect = compute; } } _xAxisZoomMode = PlotAxis::FixedExpression; if (originPlotItem) { originPlotItem->zoomNormalizeXtoY(true); } applyZoom(computedRect, originPlotItem, true, false); } } void SharedAxisBoxItem::zoomLogX(PlotItem* originPlotItem, bool autoEnable, bool enable) { #if DEBUG_ZOOM qDebug() << "zoomLogX" << endl; #endif bool enableLog; if (autoEnable && originPlotItem) { enableLog = !originPlotItem->xAxis()->axisLog(); } else { enableLog = enable; } QList allPlots; if (_shareX) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareX || origin_tied)) { if (originPlotItem) { originPlotItem->zoomLogX(true, false, enableLog); } } else { foreach(PlotItem* plotItem, allPlots) { plotItem->zoomLogX(true, false, enableLog); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomLogX(true, false, enableLog); } } } } void SharedAxisBoxItem::zoomYLocalMaximum(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYLocalMaximum" << endl; #endif bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareY || origin_tied)) { if (originPlotItem) { originPlotItem->zoomYLocalMaximum(true); } } else { QRectF computedRect; foreach(PlotItem *plotItem, getSharedPlots()) { qreal minimum = plotItem->yAxis()->axisLog() ? 0.0 : -0.1; qreal maximum = 0.1; plotItem->computedRelationalMax(minimum, maximum); plotItem->computeBorder(Qt::Vertical, minimum, maximum); QRectF compute = plotItem->projectionRect(); compute.setTop(minimum); compute.setBottom(maximum); if (computedRect.isValid()) { computedRect = computedRect.united(compute); } else { computedRect = compute; } } _yAxisZoomMode = PlotAxis::FixedExpression; if (originPlotItem) { originPlotItem->zoomYLocalMaximum(true); } applyZoom(computedRect, originPlotItem, false, true); } } void SharedAxisBoxItem::zoomYMaximum(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYMaximum" << endl; #endif _yAxisZoomMode = PlotAxis::Auto; if (originPlotItem) { originPlotItem->zoomYMaximum(true); } applyZoom(computeRect(PlotAxis::Auto, PlotAxis::Auto), originPlotItem, false, true); } void SharedAxisBoxItem::zoomYNoSpike(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYNoSpike" << endl; #endif _yAxisZoomMode = PlotAxis::SpikeInsensitive; if (originPlotItem) { originPlotItem->zoomYNoSpike(true); } applyZoom(computeRect(PlotAxis::Auto, PlotAxis::SpikeInsensitive), originPlotItem, false, true); } void SharedAxisBoxItem::zoomYAutoBorder(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYAutoBorder" << endl; #endif _yAxisZoomMode = PlotAxis::AutoBorder; if (originPlotItem) { originPlotItem->zoomYAutoBorder(true); } applyZoom(computeRect(PlotAxis::Auto, PlotAxis::AutoBorder), originPlotItem, false, true); } void SharedAxisBoxItem::zoomYUp(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYUp" << endl; #endif QList allPlots; if (_shareY) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareY || origin_tied)) { if (originPlotItem) { originPlotItem->zoomYUp(true); } } else { _yAxisZoomMode = PlotAxis::FixedExpression; foreach(PlotItem* plotItem, allPlots) { plotItem->zoomYUp(true); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomYUp(true); } } } } void SharedAxisBoxItem::zoomYDown(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYDown" << endl; #endif QList allPlots; if (_shareY) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareY || origin_tied)) { if (originPlotItem) { originPlotItem->zoomYDown(true); } } else { _yAxisZoomMode = PlotAxis::FixedExpression; foreach(PlotItem* plotItem, allPlots) { plotItem->zoomYDown(true); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomYDown(true); } } } } void SharedAxisBoxItem::zoomYOut(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYOut" << endl; #endif QList allPlots; if (_shareY) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareY || origin_tied)) { if (originPlotItem) { originPlotItem->zoomYOut(true); } } else { _yAxisZoomMode = PlotAxis::FixedExpression; foreach(PlotItem* plotItem, allPlots) { plotItem->zoomYOut(true); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomYOut(true); } } } } void SharedAxisBoxItem::zoomYIn(PlotItem* originPlotItem) { #if DEBUG_ZOOM qDebug() << "zoomYIn" << endl; #endif QList allPlots; if (_shareY) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareY || origin_tied)) { if (originPlotItem) { originPlotItem->zoomYIn(true); } } else { _yAxisZoomMode = PlotAxis::FixedExpression; foreach(PlotItem* plotItem, allPlots) { plotItem->zoomYIn(true); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomYIn(true); } } } } void SharedAxisBoxItem::zoomNormalizeYtoX(PlotItem* originPlotItem) { if (!originPlotItem) { return; } #if DEBUG_ZOOM qDebug() << "zoomNormalizeYtoX" << endl; #endif bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareY || origin_tied)) { if (originPlotItem) { originPlotItem->zoomNormalizeXtoY(true); } } else { QRectF computedRect; foreach(PlotItem *plotItem, getSharedPlots()) { QRectF compute = plotItem->projectionRect(); if (computedRect.isValid()) { computedRect = computedRect.united(compute); } else { computedRect = compute; } } qreal mean = computedRect.center().y(); qreal range = originPlotItem->plotRect().width() * computedRect.height() / originPlotItem->plotRect().height(); computedRect.setTop(mean - (range / 2.0)); computedRect.setBottom(mean + (range / 2.0)); _yAxisZoomMode = PlotAxis::FixedExpression; originPlotItem->zoomNormalizeYtoX(true); applyZoom(computedRect, originPlotItem, false, true); } } void SharedAxisBoxItem::zoomLogY(PlotItem* originPlotItem, bool autoEnable, bool enable) { #if DEBUG_ZOOM qDebug() << "zoomLogY" << endl; #endif QList allPlots; if (_shareY) { allPlots = getSharedPlots(); } else { allPlots = getTiedPlots(originPlotItem); } bool enableLog; if (autoEnable && originPlotItem) { enableLog = !originPlotItem->yAxis()->axisLog(); } else { enableLog = enable; } bool origin_tied = false; if (originPlotItem) { origin_tied = originPlotItem->isTiedZoom(); } if (!(_shareY || origin_tied)) { if (originPlotItem) { originPlotItem->zoomLogY(true, false, enableLog); } } else { foreach(PlotItem* plotItem, allPlots) { plotItem->zoomLogY(true, false, enableLog); } } if (originPlotItem && originPlotItem->isTiedZoom() && originPlotItem->isInSharedAxisBox() && (originPlotItem->sharedAxisBox() == this)) { QList plotTied = PlotItemManager::tiedZoomPlotsForView(view()); foreach(PlotItem* plotItem, plotTied) { if (!allPlots.contains(plotItem)) { plotItem->zoomLogY(true, false, enableLog); } } } } void SharedAxisBoxItem::updateZoomForDataUpdate(qint64 serial) { if (serial == _serialOfLastChange) { return; } _serialOfLastChange = serial; if (_shareX) { switch (xAxisZoomMode()) { case PlotAxis::Auto: zoomXMaximum(0); break; case PlotAxis::AutoBorder: zoomXAutoBorder(0); break; case PlotAxis::SpikeInsensitive: zoomXNoSpike(0); break; default: break; } } if (_shareY) { switch (yAxisZoomMode()) { case PlotAxis::Auto: zoomYMaximum(0); break; case PlotAxis::AutoBorder: zoomYAutoBorder(0); break; case PlotAxis::SpikeInsensitive: zoomYNoSpike(0); break; case PlotAxis::MeanCentered: zoomMeanCentered(0); break; default: break; } } } void CreateSharedAxisBoxCommand::createItem() { _item = new SharedAxisBoxItem(_view); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } void CreateSharedAxisBoxCommand::undo() { Q_ASSERT(_item); _item->hide(); SharedAxisBoxItem *shareBox = qobject_cast(_item); if (shareBox) { shareBox->breakShare(); } } void CreateSharedAxisBoxCommand::redo() { Q_ASSERT(_item); _item->show(); SharedAxisBoxItem *shareBox = qobject_cast(_item); if (shareBox) { if (!shareBox->acceptItems()) { _item->hide(); } } } void CreateSharedAxisBoxCommand::creationComplete() { Q_ASSERT(_item); SharedAxisBoxItem *shareBox = qobject_cast(_item); if (shareBox) { if (shareBox->acceptItems()) { CreateCommand::creationComplete(); } else { delete _item; deleteLater(); kstApp->mainWindow()->clearDrawingMarker(); } } } SharedAxisBoxItemFactory::SharedAxisBoxItemFactory() : GraphicsFactory() { registerFactory("sharedaxisbox", this); } SharedAxisBoxItemFactory::~SharedAxisBoxItemFactory() { } ViewItem* SharedAxisBoxItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { SharedAxisBoxItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "sharedaxisbox") { Q_ASSERT(!rc); rc = new SharedAxisBoxItem(view); if (parent) { rc->setParentViewItem(parent); } QXmlStreamAttributes attrs = xml.attributes(); QStringRef av = attrs.value("sharex"); if (!av.isNull()) { rc->setXAxisShared(QVariant(av.toString()).toBool()); } av = attrs.value("sharey"); if (!av.isNull()) { rc->setYAxisShared(QVariant(av.toString()).toBool()); } av = attrs.value("xzoommode"); if (!av.isNull()) { rc->setXAxisZoomMode((PlotAxis::ZoomMode)av.toString().toInt()); } av = attrs.value("yzoommode"); if (!av.isNull()) { rc->setYAxisZoomMode((PlotAxis::ZoomMode)av.toString().toInt()); } // Add any new specialized SharedAxisBoxItem Properties here. } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (PlotItem *plotItem = qobject_cast(i)) { plotItem->setSharedAxisBox(rc); rc->_sharedPlots << plotItem; rc->connect(plotItem, SIGNAL(breakShareTriggered()), rc, SLOT(breakShare())); rc->connect(plotItem, SIGNAL(shareXAxisTriggered()), rc, SLOT(shareXAxis())); rc->connect(plotItem, SIGNAL(shareYAxisTriggered()), rc, SLOT(shareYAxis())); } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "sharedaxisbox") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating sharedaxisbox object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } rc->lockItems(); return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/matrixdialog.cpp000644 001750 001750 00000067150 11544160207 020652 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #define NO_GENERATED_OPTIONS #include "matrixdialog.h" #include "dialogpage.h" #include "datasourcedialog.h" #include "editmultiplewidget.h" #include "datamatrix.h" #include "generatedmatrix.h" #include "datacollection.h" #include "document.h" #include "objectstore.h" #include "datasourcepluginmanager.h" #include "dialogdefaults.h" #include #include namespace Kst { MatrixTab::MatrixTab(ObjectStore *store, QWidget *parent) : DataTab(parent), _mode(DataMatrix), _store(store), _initField(QString()), _requestID(0) { setupUi(this); setTabTitle(tr("Matrix")); connect(_readFromSource, SIGNAL(toggled(bool)), this, SLOT(readFromSourceChanged())); connect(_fileName, SIGNAL(changed(const QString &)), this, SLOT(fileNameChanged(const QString &))); connect(_configure, SIGNAL(clicked()), this, SLOT(showConfigWidget())); connect(_xStartCountFromEnd, SIGNAL(clicked()), this, SLOT(xStartCountFromEndClicked())); connect(_yStartCountFromEnd, SIGNAL(clicked()), this, SLOT(yStartCountFromEndClicked())); connect(_xNumStepsReadToEnd, SIGNAL(clicked()), this, SLOT(xNumStepsReadToEndClicked())); connect(_yNumStepsReadToEnd, SIGNAL(clicked()), this, SLOT(yNumStepsReadToEndClicked())); connect(_readFromSource, SIGNAL(clicked()), this, SLOT(updateEnables())); connect(_generateGradient, SIGNAL(clicked()), this, SLOT(updateEnables())); connect(_doSkip, SIGNAL(clicked()), this, SLOT(updateEnables())); connect(_xStart, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_yStart, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_xNumSteps, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_yNumSteps, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_skip, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_nX, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_nY, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_gradientZAtMin, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_gradientZAtMax, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_minX, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_minX, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_xStep, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_yStep, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_xStartCountFromEnd, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_yStartCountFromEnd, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_xNumStepsReadToEnd, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_yNumStepsReadToEnd, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_doSkip, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_doAverage, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_gradientX, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_gradientY, SIGNAL(clicked()), this, SIGNAL(modified())); _connect->setVisible(false); } MatrixTab::~MatrixTab() { } void MatrixTab::xStartCountFromEndClicked() { _xNumStepsReadToEnd->setChecked(_xNumStepsReadToEnd->isChecked() && !_xStartCountFromEnd->isChecked()); _xStart->setEnabled(!_xStartCountFromEnd->isChecked()); _xNumSteps->setEnabled(!_xNumStepsReadToEnd->isChecked()); } void MatrixTab::xNumStepsReadToEndClicked() { _xStartCountFromEnd->setChecked(_xStartCountFromEnd->isChecked() && !_xNumStepsReadToEnd->isChecked()); _xNumSteps->setEnabled(!_xNumStepsReadToEnd->isChecked()); _xStart->setEnabled(!_xStartCountFromEnd->isChecked()); } void MatrixTab::yStartCountFromEndClicked() { _yNumStepsReadToEnd->setChecked(_yNumStepsReadToEnd->isChecked() && !_yStartCountFromEnd->isChecked()); _yStart->setEnabled(!_yStartCountFromEnd->isChecked()); _yNumSteps->setEnabled(!_yNumStepsReadToEnd->isChecked()); } void MatrixTab::yNumStepsReadToEndClicked() { _yStartCountFromEnd->setChecked(_yStartCountFromEnd->isChecked() && !_yNumStepsReadToEnd->isChecked()); _yNumSteps->setEnabled(!_yNumStepsReadToEnd->isChecked()); _yStart->setEnabled(!_yStartCountFromEnd->isChecked()); } void MatrixTab::updateEnables() { _dataSourceGroup->setEnabled(_readFromSource->isChecked()); _dataRangeGroup->setEnabled(_readFromSource->isChecked()); _gradientGroup->setEnabled(_generateGradient->isChecked()); if (_dataRangeGroup->isEnabled()) { _skip->setEnabled(_doSkip->isChecked()); _doAverage->setEnabled(_doSkip->isChecked()); xStartCountFromEndClicked(); xNumStepsReadToEndClicked(); yStartCountFromEndClicked(); yNumStepsReadToEndClicked(); } } void MatrixTab::hideGeneratedOptions() { _sourceGroup->setVisible(false); _gradientGroup->setVisible(false); } void MatrixTab::hideDataOptions() { _sourceGroup->setVisible(false); _dataSourceGroup->setVisible(false); _dataRangeGroup->setVisible(false); } DataSourcePtr MatrixTab::dataSource() const { return _dataSource; } void MatrixTab::setDataSource(DataSourcePtr dataSource) { _dataSource = dataSource; } QString MatrixTab::file() const { return _fileName->file(); } void MatrixTab::setFile(const QString &file) { _fileName->setFile(file); } QString MatrixTab::field() const { return _field->currentText(); } void MatrixTab::setField(const QString &field) { _initField = field; // for delayed index setting _field->setCurrentIndex(_field->findText(field)); } void MatrixTab::setFieldList(const QStringList &fieldList) { _field->clear(); _field->addItems(fieldList); } uint MatrixTab::nX() const { return _nX->text().toInt(); } bool MatrixTab::nXDirty() const { return (!_nX->text().isEmpty()); } void MatrixTab::setNX(uint nX) { _nX->setValue(nX); } uint MatrixTab::nY() const { return _nY->text().toInt(); } bool MatrixTab::nYDirty() const { return (!_nY->text().isEmpty()); } void MatrixTab::setNY(uint nY) { _nY->setValue(nY); } double MatrixTab::minX() const { return _minX->text().toDouble(); } bool MatrixTab::minXDirty() const { return (!_minX->text().isEmpty()); } void MatrixTab::setMinX(double minX) { _minX->setText(QString::number(minX)); } double MatrixTab::minY() const { return _minY->text().toDouble(); } bool MatrixTab::minYDirty() const { return (!_minY->text().isEmpty()); } void MatrixTab::setMinY(double minY) { _minY->setText(QString::number(minY)); } double MatrixTab::stepX() const { return _xStep->text().toDouble(); } bool MatrixTab::stepXDirty() const { return (!_xStep->text().isEmpty()); } void MatrixTab::setStepX(double stepX) { _xStep->setText(QString::number(stepX)); } double MatrixTab::stepY() const { return _yStep->text().toDouble(); } bool MatrixTab::stepYDirty() const { return (!_yStep->text().isEmpty()); } void MatrixTab::setStepY(double stepY) { _yStep->setText(QString::number(stepY)); } int MatrixTab::xStart() const { return _xStart->text().toInt(); } bool MatrixTab::xStartDirty() const { return (!_xStart->text().isEmpty()); } void MatrixTab::setXStart(int xStart) { _xStart->setValue(xStart); } int MatrixTab::yStart() const { return _yStart->text().toInt(); } bool MatrixTab::yStartDirty() const { return (!_yStart->text().isEmpty()); } void MatrixTab::setYStart(int yStart) { _yStart->setValue(yStart); } int MatrixTab::xNumSteps() const { return _xNumSteps->text().toInt(); } bool MatrixTab::xNumStepsDirty() const { return (!_xNumSteps->text().isEmpty()); } void MatrixTab::setXNumSteps(int xNumSteps) { _xNumSteps->setValue(xNumSteps); } int MatrixTab::yNumSteps() const { return _yNumSteps->text().toInt(); } bool MatrixTab::yNumStepsDirty() const { return (!_yNumSteps->text().isEmpty()); } void MatrixTab::setYNumSteps(int yNumSteps) { _yNumSteps->setValue(yNumSteps); } int MatrixTab::skip() const { return _skip->text().toInt(); } bool MatrixTab::skipDirty() const { return (!_skip->text().isEmpty()); } void MatrixTab::setSkip(int skip) { _skip ->setValue(skip); } double MatrixTab::gradientZAtMin() const { return _gradientZAtMin->text().toDouble(); } bool MatrixTab::gradientZAtMinDirty() const { return (!_gradientZAtMin->text().isEmpty()); } void MatrixTab::setGradientZAtMin(double gradientZAtMin) { _gradientZAtMin->setText(QString::number(gradientZAtMin)); } double MatrixTab::gradientZAtMax() const { return _gradientZAtMax->text().toDouble(); } bool MatrixTab::gradientZAtMaxDirty() const { return (!_gradientZAtMax->text().isEmpty()); } void MatrixTab::setGradientZAtMax(double gradientZAtMax) { _gradientZAtMax->setText(QString::number(gradientZAtMax)); } bool MatrixTab::xDirection() const { return _gradientX->isChecked(); } void MatrixTab::setXDirection(bool xDirection) { _gradientX->setChecked(xDirection); _gradientY->setChecked(!xDirection); } bool MatrixTab::doAverage() const { return _doAverage->isChecked(); } bool MatrixTab::doAverageDirty() const { return _doAverage->checkState() == Qt::PartiallyChecked; } void MatrixTab::setDoAverage(bool doAverage) { _doAverage->setChecked(doAverage); } bool MatrixTab::doSkip() const { return _doSkip->isChecked(); } bool MatrixTab::doSkipDirty() const { return _doSkip->checkState() == Qt::PartiallyChecked; } void MatrixTab::setDoSkip(bool doSkip) { _doSkip->setChecked(doSkip); } bool MatrixTab::xStartCountFromEnd() const { return _xStartCountFromEnd->isChecked(); } bool MatrixTab::xStartCountFromEndDirty() const { return _xNumStepsReadToEnd->checkState() == Qt::PartiallyChecked; } void MatrixTab::setXStartCountFromEnd(bool xStartCountFromEnd) { _xStartCountFromEnd->setChecked(xStartCountFromEnd); } bool MatrixTab::yStartCountFromEnd() const { return _yStartCountFromEnd->isChecked(); } bool MatrixTab::yStartCountFromEndDirty() const { return _yNumStepsReadToEnd->checkState() == Qt::PartiallyChecked; } void MatrixTab::setYStartCountFromEnd(bool yStartCountFromEnd) { _yStartCountFromEnd->setChecked(yStartCountFromEnd); } bool MatrixTab::xReadToEnd() const { return _xNumStepsReadToEnd->isChecked(); } bool MatrixTab::xReadToEndDirty() const { return _xNumStepsReadToEnd->checkState() == Qt::PartiallyChecked; } void MatrixTab::setXReadToEnd(bool xReadToEnd) { _xNumStepsReadToEnd->setChecked(xReadToEnd); } bool MatrixTab::yReadToEnd() const { return _yNumStepsReadToEnd->isChecked(); } bool MatrixTab::yReadToEndDirty() const { return _yNumStepsReadToEnd->checkState() == Qt::PartiallyChecked; } void MatrixTab::setYReadToEnd(bool yReadToEnd) { _yNumStepsReadToEnd->setChecked(yReadToEnd); } void MatrixTab::readFromSourceChanged() { if (_readFromSource->isChecked()) setMatrixMode(DataMatrix); else setMatrixMode(GeneratedMatrix); _dataSourceGroup->setEnabled(_readFromSource->isChecked()); _dataRangeGroup->setEnabled(_readFromSource->isChecked()); _gradientGroup->setEnabled(!_readFromSource->isChecked()); emit sourceChanged(); } void MatrixTab::setMatrixMode(MatrixMode mode) { _mode = mode; _readFromSource->setChecked(mode == DataMatrix); _generateGradient->setChecked(mode == GeneratedMatrix); } void MatrixTab::sourceValid(QString filename, int requestID) { if (_requestID != requestID) { return; } _dataSource = DataSourcePluginManager::findOrLoadSource(_store, filename); _field->setEnabled(true); _dataSource->readLock(); _field->addItems(_dataSource->matrix().list()); if (!_initField.isEmpty()) { setField(_initField); } _field->setEditable(!_dataSource->matrix().isListComplete() && !_dataSource->matrix().list().empty()); _configure->setEnabled(_dataSource->hasConfigWidget()); _dataSource->unlock(); emit sourceChanged(); } void MatrixTab::fileNameChanged(const QString &file) { _field->clear(); _field->setEnabled(false); _configure->setEnabled(false); emit sourceChanged(); _requestID += 1; ValidateDataSourceThread *validateDSThread = new ValidateDataSourceThread(file, _requestID); connect(validateDSThread, SIGNAL(dataSourceValid(QString, int)), this, SLOT(sourceValid(QString, int))); QThreadPool::globalInstance()->start(validateDSThread); } void MatrixTab::showConfigWidget() { QPointer dialog = new DataSourceDialog(dataDialog()->editMode(), _dataSource, this); if ( dialog->exec() == QDialog::Accepted ) { fileNameChanged(_dataSource->fileName()); } delete dialog; } void MatrixTab::clearTabValues() { _xStart->clear(); _yStart->clear(); _xNumSteps->clear(); _yNumSteps->clear(); _xNumStepsReadToEnd->setCheckState(Qt::PartiallyChecked); _yNumStepsReadToEnd->setCheckState(Qt::PartiallyChecked); _doSkip->setCheckState(Qt::PartiallyChecked); _doAverage->setCheckState(Qt::PartiallyChecked); _gradientZAtMin->clear(); _gradientZAtMax->clear(); _nX->clear(); _nY->clear(); _minX->clear(); _minY->clear(); _xStep->clear(); _yStep->clear(); setXDirection(true); } void MatrixTab::enableSingleEditOptions(bool enabled) { _dataSourceGroup->setEnabled(enabled); } MatrixDialog::MatrixDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Matrix")); else setWindowTitle(tr("New Matrix")); Q_ASSERT(_document && _document->objectStore()); _matrixTab = new MatrixTab(_document->objectStore(), this); addDataTab(_matrixTab); if (editMode() == Edit) { configureTab(dataObject); } else { configureTab(0); } connect(_matrixTab, SIGNAL(sourceChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_matrixTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } MatrixDialog::~MatrixDialog() { } // QString MatrixDialog::tagString() const { // return DataDialog::tagString(); // } void MatrixDialog::configureTab(ObjectPtr matrix) { if (!matrix) { _matrixTab->setMatrixMode(MatrixTab::DataMatrix); _matrixTab->setFile(_dialogDefaults->value("matrix/datasource",_matrixTab->file()).toString()); _matrixTab->setXStartCountFromEnd(_dialogDefaults->value("matrix/xCountFromEnd",false).toBool()); _matrixTab->setYStartCountFromEnd(_dialogDefaults->value("matrix/yCountFromEnd",false).toBool()); _matrixTab->setXReadToEnd(_dialogDefaults->value("matrix/xReadToEnd",false).toBool()); _matrixTab->setYReadToEnd(_dialogDefaults->value("matrix/yReadToEnd",false).toBool()); _matrixTab->setXNumSteps(_dialogDefaults->value("matrix/xNumSteps",1000).toInt()); _matrixTab->setYNumSteps(_dialogDefaults->value("matrix/yNumSteps",1000).toInt()); _matrixTab->setXStart(_dialogDefaults->value("matrix/reqXStart",0).toInt()); _matrixTab->setYStart(_dialogDefaults->value("matrix/reqYStart",0).toInt()); #ifdef NO_GENERATED_OPTIONS _matrixTab->hideGeneratedOptions(); #endif } else if (DataMatrixPtr dataMatrix = kst_cast(matrix)) { _matrixTab->setMatrixMode(MatrixTab::DataMatrix); _matrixTab->setFile(dataMatrix->dataSource()->fileName()); _matrixTab->setDataSource(dataMatrix->dataSource()); _matrixTab->setField(dataMatrix->field()); _matrixTab->setXStartCountFromEnd(dataMatrix->xCountFromEnd()); _matrixTab->setYStartCountFromEnd(dataMatrix->yCountFromEnd()); _matrixTab->setXNumSteps(dataMatrix->xNumSteps()); _matrixTab->setYNumSteps(dataMatrix->yNumSteps()); _matrixTab->setMinX(dataMatrix->minX()); _matrixTab->setMinY(dataMatrix->minY()); _matrixTab->setStepX(dataMatrix->xStepSize()); _matrixTab->setStepY(dataMatrix->yStepSize()); _matrixTab->setXStart(dataMatrix->reqXStart()); _matrixTab->setYStart(dataMatrix->reqYStart()); _matrixTab->setXReadToEnd(dataMatrix->xReadToEnd()); _matrixTab->setYReadToEnd(dataMatrix->yReadToEnd()); _matrixTab->setSkip(dataMatrix->skip()); _matrixTab->setDoSkip(dataMatrix->doSkip()); _matrixTab->setDoAverage(dataMatrix->doAverage()); _matrixTab->hideGeneratedOptions(); if (_editMultipleWidget) { DataMatrixList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(DataMatrixPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } else if (GeneratedMatrixPtr generatedMatrix = kst_cast(matrix)) { _matrixTab->setMatrixMode(MatrixTab::GeneratedMatrix); _matrixTab->setNX(generatedMatrix->xNumSteps()); _matrixTab->setNY(generatedMatrix->yNumSteps()); _matrixTab->setMinX(generatedMatrix->minX()); _matrixTab->setMinY(generatedMatrix->minY()); _matrixTab->setStepX(generatedMatrix->xStepSize()); _matrixTab->setStepY(generatedMatrix->yStepSize()); _matrixTab->setGradientZAtMin(generatedMatrix->gradZMin()); _matrixTab->setGradientZAtMax(generatedMatrix->gradZMax()); _matrixTab->setXDirection(generatedMatrix->xDirection()); _matrixTab->hideDataOptions(); if (_editMultipleWidget) { DataMatrixList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(DataMatrixPtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } void MatrixDialog::editMultipleMode() { _matrixTab->enableSingleEditOptions(false); _matrixTab->clearTabValues(); } void MatrixDialog::editSingleMode() { _matrixTab->enableSingleEditOptions(true); configureTab(dataObject()); } void MatrixDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_matrixTab->matrixMode() == MatrixTab::GeneratedMatrix || !_matrixTab->field().isEmpty()); } ObjectPtr MatrixDialog::createNewDataObject() { switch(_matrixTab->matrixMode()) { case MatrixTab::DataMatrix: return createNewDataMatrix(); case MatrixTab::GeneratedMatrix: return createNewGeneratedMatrix(); default: return 0; } } ObjectPtr MatrixDialog::createNewDataMatrix() { const DataSourcePtr dataSource = _matrixTab->dataSource(); //FIXME better validation than this please... if (!dataSource) return 0; const QString field = _matrixTab->field(); const int skip = _matrixTab->skip(); const bool doAverage = _matrixTab->doAverage(); const bool doSkip = _matrixTab->doSkip(); const int xStart = _matrixTab->xStartCountFromEnd() ? -1 : _matrixTab->xStart(); const int yStart = _matrixTab->yStartCountFromEnd() ? -1 : _matrixTab->yStart(); const int xNumSteps = _matrixTab->xReadToEnd() ? -1 : _matrixTab->xNumSteps(); const int yNumSteps = _matrixTab->yReadToEnd() ? -1 : _matrixTab->yNumSteps(); const double minX = _matrixTab->minX(); const double minY = _matrixTab->minY(); const double stepX = _matrixTab->stepX(); const double stepY = _matrixTab->stepY(); // qDebug() << "Creating new data matrix ===>" // << "\n\tfileName:" << dataSource->fileName() // << "\n\tfileType:" << dataSource->fileType() // << "\n\tfield:" << field // << "\n\ttag:" << tag.tag() // << "\n\txStart:" << xStart // << "\n\tyStart:" << yStart // << "\n\txNumSteps:" << xNumSteps // << "\n\tyNumSteps:" << yNumSteps // << "\n\tskip:" << skip // << "\n\tdoSkip:" << doSkip // << "\n\tdoAve:" << doAve // << endl; Q_ASSERT(_document && _document->objectStore()); DataMatrixPtr matrix = _document->objectStore()->createObject(); matrix->change(dataSource, field, xStart, yStart, xNumSteps, yNumSteps, doAverage, doSkip, skip, minX, minY, stepX, stepY); if (DataDialog::tagStringAuto()) { matrix->setDescriptiveName(QString()); } else { matrix->setDescriptiveName(DataDialog::tagString()); } matrix->writeLock(); matrix->registerChange(); matrix->unlock(); setDataMatrixDefaults(matrix); _dataObjectName = matrix->Name(); return static_cast(matrix); } ObjectPtr MatrixDialog::createNewGeneratedMatrix() { const uint nX = _matrixTab->nX(); const uint nY = _matrixTab->nY(); const double minX = _matrixTab->minX(); const double minY = _matrixTab->minY(); const double stepX = _matrixTab->stepX(); const double stepY = _matrixTab->stepY(); const double gradZMin = _matrixTab->gradientZAtMin(); const double gradZMax = _matrixTab->gradientZAtMax(); const bool xDirection = _matrixTab->xDirection(); // qDebug() << "Creating new generated matrix ===>" // << "\n\ttag:" << tag.tag() // << "\n\tnX:" << nX // << "\n\tnY:" << nY // << "\n\tminX:" << minX // << "\n\tminY:" << minY // << "\n\tstepX:" << stepX // << "\n\tstepY:" << stepY // << "\n\tgradZMin:" << gradZMin // << "\n\tgradZMax:" << gradZMax // << "\n\txDirection:" << xDirection // << endl; Q_ASSERT(_document && _document->objectStore()); GeneratedMatrixPtr matrix = _document->objectStore()->createObject(); matrix->change(nX, nY, minX, minY, stepX, stepY, gradZMin, gradZMax, xDirection); if (DataDialog::tagStringAuto()) { matrix->setDescriptiveName(QString()); } else { matrix->setDescriptiveName(DataDialog::tagString()); } matrix->writeLock(); matrix->registerChange(); matrix->unlock(); _dataObjectName = matrix->Name(); return static_cast(matrix); } ObjectPtr MatrixDialog::editExistingDataObject() const { if (DataMatrixPtr dataMatrix = kst_cast(dataObject())) { if (editMode() == EditMultiple) { QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { DataMatrixPtr matrix = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (matrix) { const int skip = _matrixTab->skipDirty() ? _matrixTab->skip() : matrix->skip(); int xStart = _matrixTab->xStartDirty() ? _matrixTab->xStart() : matrix->reqXStart(); int yStart = _matrixTab->yStartDirty() ? _matrixTab->yStart() : matrix->reqYStart(); int xNumSteps = _matrixTab->xNumStepsDirty() ? _matrixTab->xNumSteps() : matrix->xNumSteps(); int yNumSteps = _matrixTab->yNumStepsDirty() ? _matrixTab->yNumSteps() : matrix->yNumSteps(); const double minX = _matrixTab->minXDirty() ? _matrixTab->minX() : matrix->minX(); const double minY = _matrixTab->minYDirty() ? _matrixTab->minY() : matrix->minY(); const double stepX = _matrixTab->stepXDirty() ? _matrixTab->stepX() : matrix->xStepSize(); const double stepY = _matrixTab->stepYDirty() ? _matrixTab->stepY() : matrix->yStepSize(); if (_matrixTab->xStartCountFromEndDirty()) { xStart = _matrixTab->xStartCountFromEnd() ? -1 : _matrixTab->xStart(); xNumSteps = _matrixTab->xReadToEnd() ? -1 : _matrixTab->xNumSteps(); } if (_matrixTab->yStartCountFromEndDirty()) { yStart = _matrixTab->yStartCountFromEnd() ? -1 : _matrixTab->yStart(); yNumSteps = _matrixTab->yReadToEnd() ? -1 : _matrixTab->yNumSteps(); } bool doSkip = _matrixTab->doSkipDirty() ? _matrixTab->doSkip() : matrix->doSkip(); bool doAve = _matrixTab->doAverageDirty() ? _matrixTab->doAverage() : matrix->doAverage(); matrix->writeLock(); matrix->changeFrames(xStart, yStart, xNumSteps, yNumSteps, doAve, doSkip, skip, minX, minY, stepX, stepY); matrix->registerChange(); matrix->unlock(); } } } else { const DataSourcePtr dataSource = _matrixTab->dataSource(); //FIXME better validation than this please... if (!dataSource) return 0; const QString field = _matrixTab->field(); const int skip = _matrixTab->skip(); const bool doAverage = _matrixTab->doAverage(); const bool doSkip = _matrixTab->doSkip(); const int xStart = _matrixTab->xStartCountFromEnd() ? -1 : _matrixTab->xStart(); const int yStart = _matrixTab->yStartCountFromEnd() ? -1 : _matrixTab->yStart(); const int xNumSteps = _matrixTab->xReadToEnd() ? -1 : _matrixTab->xNumSteps(); const int yNumSteps = _matrixTab->yReadToEnd() ? -1 : _matrixTab->yNumSteps(); const double minX = _matrixTab->minX(); const double minY = _matrixTab->minY(); const double stepX = _matrixTab->stepX(); const double stepY = _matrixTab->stepY(); dataMatrix->writeLock(); dataMatrix->change(dataSource, field, xStart, yStart, xNumSteps, yNumSteps, doAverage, doSkip, skip, minX, minY, stepX, stepY); dataMatrix->registerChange(); dataMatrix->unlock(); setDataMatrixDefaults(dataMatrix); } } else if (GeneratedMatrixPtr generatedMatrix = kst_cast(dataObject())) { if (editMode() == EditMultiple) { QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { GeneratedMatrixPtr matrix = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (matrix) { const uint nX = _matrixTab->nXDirty() ? _matrixTab->nX() : matrix->xNumSteps(); const uint nY = _matrixTab->nYDirty() ? _matrixTab->nY() : matrix->yNumSteps(); const double minX = _matrixTab->minXDirty() ? _matrixTab->minX() : matrix->minX(); const double minY = _matrixTab->minYDirty() ? _matrixTab->minY() : matrix->minY(); const double stepX = _matrixTab->stepXDirty() ? _matrixTab->stepX() : matrix->xStepSize(); const double stepY = _matrixTab->stepYDirty() ? _matrixTab->stepY() : matrix->yStepSize(); const double gradientZAtMin = _matrixTab->gradientZAtMinDirty() ? _matrixTab->gradientZAtMin() : matrix->gradZMin(); const double gradientZAtMax = _matrixTab->gradientZAtMaxDirty() ? _matrixTab->gradientZAtMax() : matrix->gradZMax(); const bool xDirection = _matrixTab->gradientZAtMaxDirty() || _matrixTab->gradientZAtMinDirty() ? _matrixTab->xDirection() : matrix->xDirection(); matrix->writeLock(); matrix->change(nX, nY, minX, minY, stepX, stepY, gradientZAtMin, gradientZAtMax, xDirection); matrix->registerChange(); matrix->unlock(); } } } else { const uint nX = _matrixTab->nX(); const uint nY = _matrixTab->nY(); const double minX = _matrixTab->minX(); const double minY = _matrixTab->minY(); const double stepX = _matrixTab->stepX(); const double stepY = _matrixTab->stepY(); const double gradZMin = _matrixTab->gradientZAtMin(); const double gradZMax = _matrixTab->gradientZAtMax(); const bool xDirection = _matrixTab->xDirection(); generatedMatrix->writeLock(); generatedMatrix->change(nX, nY, minX, minY, stepX, stepY, gradZMin, gradZMax, xDirection); generatedMatrix->registerChange(); generatedMatrix->unlock(); } } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/document.h000644 001750 001750 00000003302 11544160207 017436 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DOCUMENT_H #define DOCUMENT_H #include #include #include "coredocument.h" namespace Kst { class MainWindow; class SessionModel; class View; class ViewItem; class CommandLineParser; class Document : public CoreDocument { public: Document(MainWindow *win); ~Document(); SessionModel* session() const; QString fileName() const; bool initFromCommandLine(CommandLineParser *P); bool open(const QString& file); bool save(const QString& to = QString()); bool isChanged() const; void setChanged(bool changed); bool isOpen() const; QString lastError() const; void createView(); View *currentView() const; private: QPointer _win; SessionModel *_session; bool _dirty; bool _isOpen; QString _fileName; QString _lastError; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/cartesianrenderitem.h000644 001750 001750 00000002337 11544160207 021657 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 Theodore Kisner * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CARTESIANRENDERITEM_H #define CARTESIANRENDERITEM_H #include "plotrenderitem.h" namespace Kst { class CartesianRenderItem : public PlotRenderItem { Q_OBJECT public: CartesianRenderItem(PlotItem *parentItem); virtual ~CartesianRenderItem(); virtual void saveInPlot(QXmlStreamWriter &xml); virtual void paintRelations(QPainter *painter); bool configureFromXml(QXmlStreamReader &xml, ObjectStore *store); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotitemmanager.cpp000644 001750 001750 00000021053 11544160207 021346 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "plotitemmanager.h" #include "view.h" #include "plotitem.h" #include #include namespace Kst { static PlotItemManager *_self = 0; void PlotItemManager::cleanup() { delete _self; _self = 0; } PlotItemManager *PlotItemManager::self() { if (!_self) { _self = new PlotItemManager; qAddPostRoutine(cleanup); } return _self; } PlotItemManager::PlotItemManager() { } PlotItemManager::~PlotItemManager() { } void PlotItemManager::addPlot(PlotItem *plotItem) { if (!_plotLists.contains(plotItem->view())) { _plotLists.insert(plotItem->view(), QList() << plotItem); } else { QList list = _plotLists.value(plotItem->view()); list << plotItem; _plotLists.insert(plotItem->view(), list); } } void PlotItemManager::addViewItem(ViewItem *viewItem) { if (!_viewItemLists.contains(viewItem->view())) { _viewItemLists.insert(viewItem->view(), QList() << viewItem); } else { QList list = _viewItemLists.value(viewItem->view()); list << viewItem; _viewItemLists.insert(viewItem->view(), list); } } void PlotItemManager::removePlot(PlotItem *plotItem) { if (!_plotLists.contains(plotItem->view())) return; QList list = _plotLists.value(plotItem->view()); list.removeAll(plotItem); _plotLists.insert(plotItem->view(), list); } void PlotItemManager::removeViewItem(ViewItem *viewItem) { if (!_viewItemLists.contains(viewItem->view())) return; QList list = _viewItemLists.value(viewItem->view()); list.removeAll(viewItem); _viewItemLists.insert(viewItem->view(), list); } void PlotItemManager::addTiedZoomPlot(PlotItem *plotItem, bool checkAll) { if (!_tiedZoomViewPlotLists.contains(plotItem->view())) { _tiedZoomViewPlotLists.insert(plotItem->view(), QList() << plotItem); } else { QList list = _tiedZoomViewPlotLists.value(plotItem->view()); list << plotItem; _tiedZoomViewPlotLists.insert(plotItem->view(), list); } if (checkAll) { checkAllTied(plotItem->view()); } } void PlotItemManager::checkAllTied(View* view) { bool bAllTied = true; if (_plotLists.contains(view)) { foreach(PlotItem* plot, _plotLists[view]) { if (plot->supportsTiedZoom() && !plot->isTiedZoom()) { bAllTied = false; } } } if (_viewItemLists.contains(view)) { foreach(ViewItem* viewItem, _viewItemLists[view]) { if (viewItem->supportsTiedZoom() && !viewItem->isTiedZoom()) { bAllTied = false; } } } if (bAllTied) { emit allPlotsTiedZoom(); } } void PlotItemManager::toggleAllTiedZoom(View *view) { bool tiedZoom; // vote on if we should tie all, or untie all int n_plots=0, n_tied=0; if (_viewItemLists.contains(view)) { foreach(ViewItem* viewItem, _viewItemLists[view]) { if (viewItem->supportsTiedZoom()) { ++n_plots; if (viewItem->isTiedZoom()) { ++n_tied; } } } } if (double(n_tied) > (double)n_plots*0.5) { tiedZoom = false; } else { tiedZoom = true; } if (_viewItemLists.contains(view)) { foreach(ViewItem* viewItem, _viewItemLists[view]) { if (viewItem->supportsTiedZoom()) { viewItem->setTiedZoom(tiedZoom, tiedZoom, false); } } } } void PlotItemManager::addTiedZoomViewItem(ViewItem *viewItem, bool checkAll) { if (!_tiedZoomViewItemLists.contains(viewItem->view())) { _tiedZoomViewItemLists.insert(viewItem->view(), QList() << viewItem); } else { QList list = _tiedZoomViewItemLists.value(viewItem->view()); list << viewItem; _tiedZoomViewItemLists.insert(viewItem->view(), list); } if (checkAll) { checkAllTied(viewItem->view()); } } void PlotItemManager::removeTiedZoomPlot(PlotItem *plotItem) { if (_tiedZoomViewItemPlotLists.contains(plotItem->parentViewItem())) { QList list = _tiedZoomViewItemPlotLists.value(plotItem->parentViewItem()); list.removeAll(plotItem); _tiedZoomViewItemPlotLists.insert(plotItem->parentViewItem(), list); } else if (_tiedZoomViewPlotLists.contains(plotItem->view())) { QList list = _tiedZoomViewPlotLists.value(plotItem->view()); list.removeAll(plotItem); _tiedZoomViewPlotLists.insert(plotItem->view(), list); emit tiedZoomRemoved(); } } void PlotItemManager::removeTiedZoomViewItem(ViewItem *viewItem) { if (_tiedZoomViewItemLists.contains(viewItem->view())) { QList list = _tiedZoomViewItemLists.value(viewItem->view()); list.removeAll(viewItem); _tiedZoomViewItemLists.insert(viewItem->view(), list); emit tiedZoomRemoved(); } } QList PlotItemManager::plotsForView(View *view) { if (PlotItemManager::self()->_plotLists.contains(view)) { return PlotItemManager::self()->_plotLists.value(view); } return QList(); } void PlotItemManager::clearPlotsForView(View *view) { if (PlotItemManager::self()->_plotLists.contains(view)) { PlotItemManager::self()->_plotLists.remove(view); } } QList PlotItemManager::tiedZoomPlotsForView(View *view) { if (kstApp->mainWindow()->isTiedTabs()) { QList plots; foreach (View *view, PlotItemManager::self()->_tiedZoomViewPlotLists.keys()) { const QList plotlist = PlotItemManager::self()->_tiedZoomViewPlotLists.value(view); foreach(PlotItem* item, plotlist) { plots.append(item); } } return plots; } else { if (PlotItemManager::self()->_tiedZoomViewPlotLists.contains(view)) { QList plots = PlotItemManager::self()->_tiedZoomViewPlotLists.value(view); if (PlotItemManager::self()->_tiedZoomViewItemLists.contains(view)) { foreach (ViewItem *viewItem, PlotItemManager::self()->_tiedZoomViewItemLists.value(view)) { plots << tiedZoomPlotsForViewItem(viewItem); } } return plots; } } return QList(); } QList PlotItemManager::tiedZoomPlotsForViewItem(ViewItem *viewItem) { if (PlotItemManager::self()->_tiedZoomViewItemPlotLists.contains(viewItem)) { return PlotItemManager::self()->_tiedZoomViewItemPlotLists.value(viewItem); } return QList(); } void PlotItemManager::setFocusPlot(PlotItem *plotItem) { _focusedPlots.append(plotItem); if (_plotLists.contains(plotItem->view())) { foreach (PlotItem* plot, _plotLists.value(plotItem->view())) { if (plotItem != plot) { plot->setAllowUpdates(false); } } } } QList PlotItemManager::tiedZoomPlots(PlotItem* plotItem) { if (kstApp->mainWindow()->isTiedTabs()) { QList plots; foreach (View *view, PlotItemManager::self()->_tiedZoomViewPlotLists.keys()) { const QList plotlist = PlotItemManager::self()->_tiedZoomViewPlotLists.value(view); foreach(PlotItem* item, plotlist) { plots.append(item); } } return plots; } else { if (plotItem->isInSharedAxisBox() && !plotItem->parentViewItem()->isTiedZoom()) { return tiedZoomPlotsForViewItem(plotItem->parentViewItem()); } else { return tiedZoomPlotsForView(plotItem->view()); } } } QList PlotItemManager::tiedZoomViewItems(PlotItem* plotItem) { return PlotItemManager::self()->_tiedZoomViewItemLists.value(plotItem->view()); } void PlotItemManager::removeFocusPlot(PlotItem *plotItem) { _focusedPlots.removeAll(plotItem); if (_plotLists.contains(plotItem->view())) { foreach (PlotItem* plot, _plotLists.value(plotItem->view())) { if (plotItem != plot) { plot->setAllowUpdates(true); } } } } void PlotItemManager::clearFocusedPlots() { foreach (PlotItem* plotItem, _focusedPlots) { plotItem->plotMaximize(); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/ellipseitem.cpp000644 001750 001750 00000005603 11544160207 020475 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "ellipseitem.h" #include #include #include #include namespace Kst { EllipseItem::EllipseItem(View *parent) : ViewItem(parent) { setTypeName("Ellipse"); setBrush(Qt::white); } EllipseItem::~EllipseItem() { } void EllipseItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("ellipse"); ViewItem::save(xml); xml.writeEndElement(); } } QPainterPath EllipseItem::itemShape() const { QPainterPath path; path.addEllipse(rect()); return path; } void EllipseItem::paint(QPainter *painter) { const qreal w = pen().widthF(); painter->drawEllipse(rect().adjusted(w, w, -w, -w)); } void CreateEllipseCommand::createItem() { _item = new EllipseItem(_view); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } EllipseItemFactory::EllipseItemFactory() : GraphicsFactory() { registerFactory("ellipse", this); } EllipseItemFactory::~EllipseItemFactory() { } ViewItem* EllipseItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { EllipseItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "ellipse") { Q_ASSERT(!rc); rc = new EllipseItem(view); if (parent) { rc->setParentViewItem(parent); // Add any new specialized BoxItem Properties here. } } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "ellipse") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating ellipse object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/debugdialog.h000644 001750 001750 00000002716 11544160207 020076 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DEBUGDIALOG_H #define DEBUGDIALOG_H #include #include "ui_debugdialog.h" #include "kst_export.h" #include "objectstore.h" namespace Kst { class LogWidget; class DebugDialog : public QDialog, Ui::DebugDialog { Q_OBJECT public: DebugDialog(QWidget *parent); virtual ~DebugDialog(); void setObjectStore(ObjectStore* store) { _store = store; } Q_SIGNALS: void notifyOfError(); void notifyAllClear(); public Q_SLOTS: void clear(); void show(); protected: bool event(QEvent *e); private: LogWidget *_log; ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/gridlayouthelper.h000644 001750 001750 00000007756 11544160207 021224 0ustar00synthsynth000000 000000 /**************************************************************************** ** ** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved. ** ** This file is part of the Qt Designer of the Qt Toolkit. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://trolltech.com/products/qt/licenses/licensing/opensource/ ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview ** or contact the sales department at sales@trolltech.com. ** ** In addition, as a special exception, Trolltech gives you certain ** additional rights. These rights are described in the Trolltech GPL ** Exception version 1.0, which can be found at ** http://www.trolltech.com/products/qt/gplexception/ and in the file ** GPL_EXCEPTION.txt in this package. ** ** In addition, as a special exception, Trolltech, as the sole copyright ** holder for Qt Designer, grants users of the Qt/Eclipse Integration ** plug-in the right for the Qt/Eclipse Integration to link to ** functionality provided by Qt Designer and its related libraries. ** ** Trolltech reserves all rights not expressly granted herein. ** ** Trolltech ASA (c) 2007 ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* These classes were taken from Qt designer in Qt 4.3 and adapted to work with our layouts and items.*/ #ifndef GRIDLAYOUTHELPER_H #define GRIDLAYOUTHELPER_H #include "viewitem.h" #include namespace Kst { class Grid { public: static Grid *buildGrid(const QList &itemList); static Grid *buildGrid(const QList &itemList, int columns); Grid(int rows, int cols); ~Grid(); ViewItem* cell(int row, int col) const { return m_cells[ row * m_ncols + col]; } bool setCell(int row, int col, ViewItem* w); void setCells(QRect c, ViewItem* w); int numRows() const { return m_nrows; } int numCols() const { return m_ncols; } void simplify(); bool locateWidget(ViewItem* w, int& row, int& col, int& rowspan, int& colspan); void appendItem(ViewItem *w); private: void merge(); int countRow(int r, int c) const; int countCol(int r, int c) const; void setRow(int r, int c, ViewItem* w, int count); void setCol(int r, int c, ViewItem* w, int count); bool isWidgetStartCol(int c) const; bool isWidgetEndCol(int c) const; bool isWidgetStartRow(int r) const; bool isWidgetEndRow(int r) const; bool isWidgetTopLeft(int r, int c) const; void extendLeft(); void extendRight(); void extendUp(); void extendDown(); const int m_nrows; const int m_ncols; ViewItem** m_cells; bool* m_cols; bool* m_rows; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/imagedialog.cpp000644 001750 001750 00000043606 11544160207 020430 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "imagedialog.h" #include "dialogpage.h" #include "editmultiplewidget.h" #include "view.h" #include "plotitem.h" #include "tabwidget.h" #include "mainwindow.h" #include "application.h" #include "plotrenderitem.h" #include "curve.h" #include "palette.h" #include "image.h" #include "document.h" #include "objectstore.h" #include "datacollection.h" namespace Kst { ImageTab::ImageTab(QWidget *parent) : DataTab(parent), _modeDirty(false) { setupUi(this); setTabTitle(tr("Image")); connect(_realTimeAutoThreshold, SIGNAL(toggled(const bool&)), this, SLOT(realTimeAutoThresholdToggled(const bool&))); connect(_colorOnly, SIGNAL(toggled(const bool&)), this, SLOT(updateEnabled(const bool&))); connect(_colorAndContour, SIGNAL(toggled(const bool&)), this, SLOT(updateEnabled(const bool&))); connect(_contourOnly, SIGNAL(toggled(const bool&)), this, SLOT(updateEnabled(const bool&))); connect(_autoThreshold, SIGNAL(clicked()), this, SLOT(calculateAutoThreshold())); connect(_smartThreshold, SIGNAL(clicked()), this, SLOT(calculateSmartThreshold())); connect(_matrix, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); connect(_matrix, SIGNAL(selectionChanged()), this, SIGNAL(modified())); connect(_colorOnly, SIGNAL(toggled(const bool&)), this, SIGNAL(modified())); connect(_colorAndContour, SIGNAL(toggled(const bool&)), this, SIGNAL(modified())); connect(_contourOnly, SIGNAL(toggled(const bool&)), this, SIGNAL(modified())); connect(_lowerThreshold, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_upperThreshold, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_realTimeAutoThreshold, SIGNAL(toggled(const bool&)), this, SIGNAL(modified())); connect(_contourColor, SIGNAL(changed(const QColor&)), this, SIGNAL(modified())); connect(_numContourLines, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_contourWeight, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_useVariableWeight, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_colorPalette, SIGNAL(selectionChanged()), this, SIGNAL(modified())); connect(_colorOnly, SIGNAL(clicked()), this, SLOT(modeChanged())); connect(_contourOnly, SIGNAL(clicked()), this, SLOT(modeChanged())); connect(_colorAndContour, SIGNAL(clicked()), this, SLOT(modeChanged())); _matrixLabel->setBuddy(_matrix->_matrix); } ImageTab::~ImageTab() { } void ImageTab::selectionChanged() { _autoThreshold->setEnabled(_matrix->selectedMatrix() && !realTimeAutoThreshold()); _smartThreshold->setEnabled(_matrix->selectedMatrix() && !realTimeAutoThreshold()); emit optionsChanged(); } void ImageTab::modeChanged() { _modeDirty = true; } void ImageTab::resetModeDirty() { _modeDirty = false; } CurvePlacement* ImageTab::curvePlacement() const { return _curvePlacement; } ColorPalette* ImageTab::colorPalette() const { return _colorPalette; } bool ImageTab::realTimeAutoThreshold() const { return _realTimeAutoThreshold->isChecked(); } bool ImageTab::realTimeAutoThresholdDirty() const { return _realTimeAutoThreshold->checkState() != Qt::PartiallyChecked; } void ImageTab::setRealTimeAutoThreshold(const bool realTimeAutoThreshold) { _realTimeAutoThreshold->setChecked(realTimeAutoThreshold); } bool ImageTab::colorOnly() const { return _colorOnly->isChecked(); } void ImageTab::setColorOnly(const bool colorOnly) { _colorOnly->setChecked(colorOnly); resetModeDirty(); } bool ImageTab::contourOnly() const { return _contourOnly->isChecked(); } void ImageTab::setContourOnly(const bool contourOnly) { _contourOnly->setChecked(contourOnly); resetModeDirty(); } bool ImageTab::colorAndContour() const { return _colorAndContour->isChecked(); } void ImageTab::setColorAndContour(const bool colorAndContour) { _colorAndContour->setChecked(colorAndContour); resetModeDirty(); } bool ImageTab::modeDirty() const { return _modeDirty; } bool ImageTab::useVariableLineWeight() const { return _useVariableWeight->isChecked(); } bool ImageTab::useVariableLineWeightDirty() const { return _useVariableWeight->checkState() != Qt::PartiallyChecked; } void ImageTab::setUseVariableLineWeight(const bool useVariableLineWeight) { _useVariableWeight->setChecked(useVariableLineWeight); } MatrixPtr ImageTab::matrix() const { return _matrix->selectedMatrix(); } bool ImageTab::matrixDirty() const { return _matrix->selectedMatrixDirty(); } void ImageTab::setMatrix(const MatrixPtr matrix) { _matrix->setSelectedMatrix(matrix); } double ImageTab::lowerThreshold() const { return _lowerThreshold->text().toDouble(); } bool ImageTab::lowerThresholdDirty() const { return !_lowerThreshold->text().isEmpty(); } void ImageTab::setLowerThreshold(const double lowerThreshold) { _lowerThreshold->setText(QString::number(lowerThreshold)); } double ImageTab::upperThreshold() const { return _upperThreshold->text().toDouble(); } bool ImageTab::upperThresholdDirty() const { return !_upperThreshold->text().isEmpty(); } void ImageTab::setUpperThreshold(const double upperThreshold) { _upperThreshold->setText(QString::number(upperThreshold)); } int ImageTab::numberOfContourLines() const { return _numContourLines->value(); } bool ImageTab::numberOfContourLinesDirty() const { return !_numContourLines->text().isEmpty(); } void ImageTab::setNumberOfContourLines(const int numberOfContourLines) { _numContourLines->setValue(numberOfContourLines); } int ImageTab::contourWeight() const { return _contourWeight->value(); } bool ImageTab::contourWeightDirty() const { return !_contourWeight->text().isEmpty(); } void ImageTab::setContourWeight(const int contourWeight) { _contourWeight->setValue(contourWeight); } QColor ImageTab::contourColor() const { return _contourColor->color(); } bool ImageTab::contourColorDirty() const { return !_contourColor->colorDirty(); } void ImageTab::setContourColor(const QColor contourColor) { _contourColor->setColor(contourColor); } void ImageTab::realTimeAutoThresholdToggled(const bool checked) { _lowerThreshold->setEnabled(!checked); _upperThreshold->setEnabled(!checked); _smartThresholdValue->setEnabled(!checked); _autoThreshold->setEnabled(_matrix->selectedMatrix() && !checked); _smartThreshold->setEnabled(_matrix->selectedMatrix() && !checked); } void ImageTab::updateEnabled(const bool checked) { Q_UNUSED(checked); _colorMapGroup->setEnabled(_colorOnly->isChecked() || _colorAndContour->isChecked()); _contourMapGroup->setEnabled(_contourOnly->isChecked() || _colorAndContour->isChecked()); } void ImageTab::calculateAutoThreshold() { MatrixPtr matrix = _matrix->selectedMatrix(); if (matrix) { matrix->readLock(); _lowerThreshold->setText(QString::number(matrix->minValue())); _upperThreshold->setText(QString::number(matrix->maxValue())); matrix->unlock(); } } void ImageTab::calculateSmartThreshold() { MatrixPtr matrix = _matrix->selectedMatrix(); if (matrix) { matrix->readLock(); double per = _smartThresholdValue->text().toDouble()/100.0; matrix->calcNoSpikeRange(per); _lowerThreshold->setText(QString::number(matrix->minValueNoSpike())); _upperThreshold->setText(QString::number(matrix->maxValueNoSpike())); matrix->unlock(); } } void ImageTab::setObjectStore(ObjectStore *store) { _matrix->setObjectStore(store); _store = store; } void ImageTab::hidePlacementOptions() { _curvePlacement->setVisible(false); } void ImageTab::clearTabValues() { _matrix->clearSelection(); _lowerThreshold->clear(); _upperThreshold->clear(); _numContourLines->clear(); _contourWeight->clear(); _contourColor->clearSelection(); _colorPalette->clearSelection(); _realTimeAutoThreshold->setCheckState(Qt::PartiallyChecked); _useVariableWeight->setCheckState(Qt::PartiallyChecked); _colorOnly->setChecked(true); resetModeDirty(); } ImageDialog::ImageDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Image")); else setWindowTitle(tr("New Image")); _imageTab = new ImageTab(this); addDataTab(_imageTab); if (editMode() == Edit) { configureTab(dataObject); } connect(_imageTab, SIGNAL(optionsChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_imageTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } ImageDialog::~ImageDialog() { } // QString ImageDialog::tagString() const { // return DataDialog::tagString(); // } void ImageDialog::editMultipleMode() { _imageTab->clearTabValues(); } void ImageDialog::editSingleMode() { configureTab(dataObject()); } void ImageDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_imageTab->matrix() || (editMode() == EditMultiple)); } void ImageDialog::setMatrix(MatrixPtr matrix) { _imageTab->setMatrix(matrix); } void ImageDialog::configureTab(ObjectPtr object) { if (!object) { } else if (ImagePtr image = kst_cast(object)) { _imageTab->setMatrix(image->matrix()); if (image->hasContourMap() && image->hasColorMap()) { _imageTab->setColorAndContour(true); _imageTab->setNumberOfContourLines(image->numContourLines()); _imageTab->setContourColor(image->contourColor()); _imageTab->setContourWeight(image->contourWeight()); _imageTab->setLowerThreshold(image->lowerThreshold()); _imageTab->setUpperThreshold(image->upperThreshold()); _imageTab->setRealTimeAutoThreshold(image->autoThreshold()); _imageTab->colorPalette()->setPalette(image->paletteName()); _imageTab->setUseVariableLineWeight(image->contourWeight() == -1); } else if (image->hasContourMap()) { _imageTab->setContourOnly(true); _imageTab->setNumberOfContourLines(image->numContourLines()); _imageTab->setContourColor(image->contourColor()); _imageTab->setContourWeight(image->contourWeight()); _imageTab->setUseVariableLineWeight(image->contourWeight() == -1); } else { _imageTab->setColorOnly(true); _imageTab->setLowerThreshold(image->lowerThreshold()); _imageTab->setUpperThreshold(image->upperThreshold()); _imageTab->setRealTimeAutoThreshold(image->autoThreshold()); _imageTab->colorPalette()->setPalette(image->paletteName()); } _imageTab->hidePlacementOptions(); if (_editMultipleWidget) { ImageList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(ImagePtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } ObjectPtr ImageDialog::createNewDataObject() { Q_ASSERT(_document && _document->objectStore()); ImagePtr image = _document->objectStore()->createObject(); if (_imageTab->colorOnly()) { image->changeToColorOnly(_imageTab->matrix(), _imageTab->lowerThreshold(), _imageTab->upperThreshold(), _imageTab->realTimeAutoThreshold(), _imageTab->colorPalette()->selectedPalette()); } else if (_imageTab->contourOnly()) { image->changeToContourOnly(_imageTab->matrix(), _imageTab->numberOfContourLines(), _imageTab->contourColor(), _imageTab->useVariableLineWeight() ? -1 : _imageTab->contourWeight()); } else { image->changeToColorAndContour(_imageTab->matrix(), _imageTab->lowerThreshold(), _imageTab->upperThreshold(), _imageTab->realTimeAutoThreshold(), _imageTab->colorPalette()->selectedPalette(), _imageTab->numberOfContourLines(), _imageTab->contourColor(), _imageTab->useVariableLineWeight() ? -1 : _imageTab->contourWeight()); } if (DataDialog::tagStringAuto()) { image->setDescriptiveName(QString()); } else { image->setDescriptiveName(DataDialog::tagString()); } image->writeLock(); image->registerChange(); image->unlock(); PlotItem *plotItem = 0; switch (_imageTab->curvePlacement()->place()) { case CurvePlacement::NoPlot: break; case CurvePlacement::ExistingPlot: { plotItem = static_cast(_imageTab->curvePlacement()->existingPlot()); break; } case CurvePlacement::NewPlotNewTab: _document->createView(); // fall through to case NewPlot. case CurvePlacement::NewPlot: { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); if (_imageTab->curvePlacement()->scaleFonts()) { plotItem->view()->resetPlotFontSizes(); } break; } default: break; } if (_imageTab->curvePlacement()->place() != CurvePlacement::NoPlot) { PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(image)); plotItem->update(); plotItem->view()->appendToLayout(_imageTab->curvePlacement()->layout(), plotItem, _imageTab->curvePlacement()->gridColumns()); } return ObjectPtr(image.data()); } ObjectPtr ImageDialog::editExistingDataObject() const { if (ImagePtr image = kst_cast(dataObject())) { if (editMode() == EditMultiple) { QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { ImagePtr image = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (image) { MatrixPtr matrix = _imageTab->matrixDirty() ? _imageTab->matrix() : image->matrix(); const double lowerThreshold = _imageTab->lowerThresholdDirty() ? _imageTab->lowerThreshold() : image->lowerThreshold(); const double upperThreshold = _imageTab->upperThresholdDirty() ? _imageTab->upperThreshold() : image->upperThreshold(); const bool realTimeAutoThreshold = _imageTab->realTimeAutoThresholdDirty() ? _imageTab->realTimeAutoThreshold() : image->autoThreshold(); const bool useVariableLineWeight = _imageTab->useVariableLineWeightDirty() ? _imageTab->useVariableLineWeight() : (image->contourWeight() == -1); const QString colorPalette = _imageTab->colorPalette()->selectedPaletteDirty() ? _imageTab->colorPalette()->selectedPalette() : image->paletteName(); const int numberOfContourLines = _imageTab->numberOfContourLinesDirty() ? _imageTab->numberOfContourLines() : image->numContourLines(); const int contourWeight = _imageTab->contourWeightDirty() ? _imageTab->contourWeight() : image->contourWeight(); const QColor color = _imageTab->contourColorDirty() ? _imageTab->contourColor() : image->contourColor(); bool colorMap; bool contourMap; if (_imageTab->modeDirty()) { colorMap = _imageTab->colorOnly() || _imageTab->colorAndContour(); contourMap = _imageTab->contourOnly() || _imageTab->colorAndContour(); } else { colorMap = image->hasColorMap(); contourMap = image->hasContourMap(); } image->writeLock(); if (colorMap && contourMap) { image->changeToColorAndContour(matrix, lowerThreshold, upperThreshold, realTimeAutoThreshold, colorPalette, numberOfContourLines, color, useVariableLineWeight ? -1 : contourWeight); } else if (colorMap) { image->changeToColorOnly(matrix, lowerThreshold, upperThreshold, realTimeAutoThreshold, colorPalette); } else { image->changeToContourOnly(matrix, numberOfContourLines, color, useVariableLineWeight ? -1 : contourWeight); } image->registerChange(); image->unlock(); } } } else { image->writeLock(); if (_imageTab->colorOnly()) { image->changeToColorOnly(_imageTab->matrix(), _imageTab->lowerThreshold(), _imageTab->upperThreshold(), _imageTab->realTimeAutoThreshold(), _imageTab->colorPalette()->selectedPalette()); } else if (_imageTab->contourOnly()) { image->changeToContourOnly(_imageTab->matrix(), _imageTab->numberOfContourLines(), _imageTab->contourColor(), _imageTab->useVariableLineWeight() ? -1 : _imageTab->contourWeight()); } else { image->changeToColorAndContour(_imageTab->matrix(), _imageTab->lowerThreshold(), _imageTab->upperThreshold(), _imageTab->realTimeAutoThreshold(), _imageTab->colorPalette()->selectedPalette(), _imageTab->numberOfContourLines(), _imageTab->contourColor(), _imageTab->useVariableLineWeight() ? -1 : _imageTab->contourWeight()); } if (DataDialog::tagStringAuto()) { image->setDescriptiveName(QString()); } else { image->setDescriptiveName(DataDialog::tagString()); } image->registerChange(); image->unlock(); } } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/rangetab.ui000644 001750 001750 00000023742 11544160207 017603 0ustar00synthsynth000000 000000 RangeTab 0 0 517 375 Form X Zoom Mode true A&uto true Auto with bor&der S&pike insensitive auto 0 0 Mean c&entered, false 0 0 ran&ge: _xRange false 0 0 F&ixed, false 0 0 fro&m: _xMin false false 0 0 t&o: _xMax false 0 0 SHOULD BE HIDDEN Y Zoom Mode true &Auto true Auto with &border &Spike insensitive auto 0 0 Mean &centered, false 0 0 &range: _yRange false 0 0 &Fixed, false 0 0 f&rom: _yMin false false 0 0 &to: _yMax false 0 0 SHOULD BE HIDDEN kst-2.0.3/src/libkstapp/legenditem.cpp000644 001750 001750 00000034034 11544160207 020276 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "legenditem.h" #include #include "labelrenderer.h" #include "debug.h" #include "plotitem.h" #include "legenditemdialog.h" #include "objectstore.h" #include "dialogdefaults.h" #include #include #include #define LEGENDITEMMAXWIDTH 400 #define LEGENDITEMMAXHEIGHT 100 namespace Kst { struct DrawnLegendItem { QPixmap pixmap; QSize size; }; LegendItem::LegendItem(PlotItem *parentPlot) : ViewItem(parentPlot->view()), _plotItem(parentPlot), _auto(true), _verticalDisplay(true) { setTypeName("Legend"); _initializeShortName(); setFixedSize(true); setAllowedGripModes(Move /*| Resize*/ /*| Rotate*/ /*| Scale*/); setViewRect(0.0, 0.0, 0.0, 0.0); view()->scene()->addItem(this); setParentViewItem(_plotItem->renderItem()); QPointF origin = QPointF(_plotItem->plotRect().width() * 0.15, _plotItem->plotRect().height() * 0.15); setPos(origin); applyDefaults(); } void LegendItem::_initializeShortName() { _shortName = 'L'+QString::number(_lnum); if (_lnum>max_lnum) max_lnum = _lnum; _lnum++; } LegendItem::~LegendItem() { } void LegendItem::paint(QPainter *painter) { if (!isVisible()) { return; } RelationList legendItems; if (_auto) { legendItems = plot()->renderItem(PlotRenderItem::Cartesian)->relationList(); } else { legendItems = _relations; } QList legendPixmaps; QSize legendSize(0, 0); QFont font(_font); font.setPointSizeF(view()->defaultFont(_fontScale).pointSizeF()); // generate string list of relation names QStringList names; int count = legendItems.count(); bool allAuto = true; bool sameX = true; bool sameYUnits = true; LabelInfo label_info = legendItems.at(0)->xLabelInfo(); QString yUnits = legendItems.at(0)->yLabelInfo().units; for (int i = 0; idescriptiveNameIsManual()) { allAuto = false; } if (relation->xLabelInfo() != label_info) { sameX = false; } // sameYUnits is false if any non empty units are defined differently. if (yUnits.isEmpty()) { yUnits = relation->yLabelInfo().units; } else if (relation->yLabelInfo().units != yUnits) { if (!relation->yLabelInfo().units.isEmpty()) { sameYUnits = false; } } } if (!allAuto) { for (int i = 0; idescriptiveName()); } } else { for (int i = 0; ititleInfo().singleRenderItemLabel(); if (label.isEmpty()) { label_info = relation->yLabelInfo(); QString y_label = label_info.name; if (!sameYUnits) { if (!label_info.units.isEmpty()) { y_label = i18n("%1 \\[%2\\]").arg(y_label).arg(label_info.units); } } if (!y_label.isEmpty()) { LabelInfo xlabel_info = relation->xLabelInfo(); if (!sameX) { label = i18n("%1 vs %2").arg(y_label).arg(xlabel_info.name); } else if (xlabel_info.quantity.isEmpty()) { label = y_label; } else if (xlabel_info.quantity != xlabel_info.name) { label = i18n("%1 vs %2").arg(y_label).arg(xlabel_info.name); } else { label = y_label; } } else { label = relation->descriptiveName(); } } names.append(label); } } for (int i = 0; isave(); if (!_title.isEmpty()) { // Paint the title Label::Parsed *parsed = Label::parse(_title); if (parsed) { painter->save(); QPixmap pixmap(400, 100); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); Label::RenderContext rc(font, &pixmapPainter); QFontMetrics fm(font); rc.y = fm.ascent(); Label::renderLabel(rc, parsed->chunk, false); int startPoint = qMax(0, (legendSize.width() / 2) - (rc.x / 2)); int paddingValue = fm.height() / 4; setViewRect(viewRect().x(), viewRect().y(), qMax(rc.x, legendSize.width()), rc.y + legendSize.height() + paddingValue * 3); painter->drawRect(rect()); painter->drawPixmap(QPoint(x + startPoint, y + paddingValue), pixmap, QRect(0, 0, rc.x, fm.height())); painter->restore(); y += fm.height() + (paddingValue *2); delete parsed; parsed = 0; } } else { // No Title setViewRect(viewRect().x(), viewRect().y(), legendSize.width(), legendSize.height()); painter->drawRect(rect()); } foreach(DrawnLegendItem item, legendPixmaps) { painter->drawPixmap(QPoint(x, y), item.pixmap, QRect(0, 0, item.size.width(), item.size.height())); if (_verticalDisplay) { y += item.size.height(); } else { x += item.size.width(); } } painter->restore(); } QSize LegendItem::paintRelation(QString name, RelationPtr relation, QPixmap *pixmap, const QFont &font) { Label::Parsed *parsed = Label::parse(name); pixmap->fill(Qt::transparent); QPainter pixmapPainter(pixmap); QFontMetrics fm(font); int paddingValue = fm.height() / 4; pixmapPainter.translate(paddingValue, paddingValue / 2); relation->paintLegendSymbol(&pixmapPainter, QRect(0, 0, 4 * fm.ascent(), fm.height())); pixmapPainter.translate(4 * fm.ascent() + paddingValue, 0); Label::RenderContext rc(font, &pixmapPainter); rc.y = fm.ascent(); if (parsed) { Label::renderLabel(rc, parsed->chunk, false); delete parsed; parsed = 0; } return QSize((4 * fm.ascent()) + (paddingValue * 3) + rc.x, fm.height() + paddingValue); } void LegendItem::save(QXmlStreamWriter &xml) { Q_UNUSED(xml); } void LegendItem::applyDefaults() { _auto = _dialogDefaults->value("legend/auto",true).toBool(); QFont font; font.fromString(_dialogDefaults->value("legend/font",font.toString()).toString()); setFont(font); setFontScale(_dialogDefaults->value("legend/fontScale", 12.0).toDouble()); _verticalDisplay = _dialogDefaults->value("legend/verticalDisplay",true).toBool(); // set the pen QPen pen; pen.setStyle((Qt::PenStyle)_dialogDefaults->value("legend/strokeStyle", 1).toInt()); pen.setWidthF(_dialogDefaults->value("legend/strokeWidth",0).toDouble()); pen.setJoinStyle((Qt::PenJoinStyle)_dialogDefaults->value("legend/strokeJoinStyle",64).toInt()); pen.setCapStyle((Qt::PenCapStyle)_dialogDefaults->value("legend/strokeCapStyle",16).toInt()); QBrush brush; QColor color = _dialogDefaults->value("legend/strokeBrushColor",QColor(Qt::black)).value(); brush.setColor(color); brush.setStyle((Qt::BrushStyle)_dialogDefaults->value("legend/strokeBrushStyle",1).toInt()); pen.setBrush(brush); setPen(pen); //set the brush bool useGradient = _dialogDefaults->value("legend/fillBrushUseGradient", false).toBool(); if (useGradient) { QStringList stopInfo = _dialogDefaults->value("legend/fillBrushGradient", "0,#000000,1,#ffffff,"). toString().split(',', QString::SkipEmptyParts); QLinearGradient gradient(1,0,0,0); gradient.setCoordinateMode(QGradient::ObjectBoundingMode); for (int i = 0; i < stopInfo.size(); i+=2) { gradient.setColorAt(stopInfo.at(i).toDouble(), QColor(stopInfo.at(i+1))); } brush = QBrush(gradient); } else { color = _dialogDefaults->value("legend/fillBrushColor",QColor(Qt::white)).value(); brush.setColor(color); brush.setStyle((Qt::BrushStyle)_dialogDefaults->value("legend/fillBrushStyle",1).toInt()); } setBrush(brush); } void LegendItem::saveAsDialogDefaults() const { _dialogDefaults->setValue("legend/auto",_auto); _dialogDefaults->setValue("legend/title", _title); _dialogDefaults->setValue("legend/font", QVariant(_font).toString()); _dialogDefaults->setValue("legend/fontScale",_fontScale); _dialogDefaults->setValue("legend/verticalDisplay", _verticalDisplay); _dialogDefaults->setValue("legend/strokeStyle", QVariant(pen().style()).toString()); _dialogDefaults->setValue("legend/strokeWidth", QVariant(pen().widthF()).toString()); _dialogDefaults->setValue("legend/strokeCap", QVariant(pen().capStyle()).toString()); _dialogDefaults->setValue("legend/strokeJoinStyle", QVariant(pen().joinStyle()).toString()); _dialogDefaults->setValue("legend/strokeBrushColor", pen().brush().color().name()); _dialogDefaults->setValue("legend/strokeBrushStyle", QVariant(pen().brush().style()).toString()); QBrush b = brush(); _dialogDefaults->setValue("legend/fillBrushColor", b.color().name()); _dialogDefaults->setValue("legend/fillBrushStyle", QVariant(b.style()).toString()); _dialogDefaults->setValue("legend/fillBrushUseGradient", QVariant(bool(b.gradient())).toString()); if (b.gradient()) { QString stopList; foreach(QGradientStop stop, b.gradient()->stops()) { qreal point = (qreal)stop.first; QColor color = (QColor)stop.second; stopList += QString::number(point); stopList += ','; stopList += color.name(); stopList += ','; } _dialogDefaults->setValue("legend/fillBrushGradient", stopList); } // Save legend defaults here } void LegendItem::saveInPlot(QXmlStreamWriter &xml) { xml.writeStartElement("legend"); xml.writeAttribute("auto", QVariant(_auto).toString()); xml.writeAttribute("title", QVariant(_title).toString()); xml.writeAttribute("font", QVariant(_font).toString()); xml.writeAttribute("fontscale", QVariant(_fontScale).toString()); xml.writeAttribute("verticaldisplay", QVariant(_verticalDisplay).toString()); ViewItem::save(xml); foreach (RelationPtr relation, _relations) { xml.writeStartElement("relation"); xml.writeAttribute("tag", relation->Name()); xml.writeEndElement(); } xml.writeEndElement(); } bool LegendItem::configureFromXml(QXmlStreamReader &xml, ObjectStore *store) { bool validTag = true; QString primaryTag = xml.name().toString(); QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; av = attrs.value("auto"); if (!av.isNull()) { setAutoContents(QVariant(av.toString()).toBool()); } av = attrs.value("title"); if (!av.isNull()) { setTitle(av.toString()); } av = attrs.value("font"); if (!av.isNull()) { QFont font; font.fromString(av.toString()); setFont(font); } av = attrs.value("fontscale"); if (!av.isNull()) { setFontScale(QVariant(av.toString()).toDouble()); } av = attrs.value("verticaldisplay"); if (!av.isNull()) { setVerticalDisplay(QVariant(av.toString()).toBool()); } QString expectedEnd; while (!(xml.isEndElement() && (xml.name().toString() == primaryTag))) { if (xml.isStartElement()) { if (xml.name().toString() == "relation") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString tagName = attrs.value("tag").toString(); RelationPtr relation = kst_cast(store->retrieveObject(tagName)); if (relation) { _relations.append(relation); } } else { parse(xml, validTag); } } else if (xml.isEndElement()) { if (xml.name().toString() != expectedEnd) { validTag = false; break; } } xml.readNext(); } return validTag; } void LegendItem::edit() { LegendItemDialog *editDialog = new LegendItemDialog(this); editDialog->show(); } void LegendItem::remove() { if (_plotItem) { _plotItem->setShowLegend(false); } ViewItem::remove(); } void LegendItem::setAutoContents(const bool autoContents) { _auto = autoContents; } bool LegendItem::autoContents() const { return _auto; } void LegendItem::setVerticalDisplay(const bool vertical) { _verticalDisplay = vertical; } bool LegendItem::verticalDisplay() const { return _verticalDisplay; } void LegendItem::setTitle(const QString &title) { _title = title; } QString LegendItem::title() const { return _title; } QFont LegendItem::font() const { return _font; } void LegendItem::setFont(const QFont &font) { _font = font; } qreal LegendItem::fontScale() const { return _fontScale; } void LegendItem::setFontScale(const qreal scale) { _fontScale = scale; } QString LegendItem::_automaticDescriptiveName() const { QString name = i18n("Empty Legend"); if (_auto) { name = _plotItem->descriptiveName(); } else if (_relations.size()>0) { name = _relations.at(0)->descriptiveName(); if (_relations.size()>1) { name += ", ..."; } } //qDebug() << "a desc name called: " << name << " relation.length: " << _relations.length(); return name; } QString LegendItem::descriptionTip() const { QString contents; foreach (Relation *relation, _relations) { contents += QString(" %1\n").arg(relation->Name()); } return i18n("Plot: %1 \nContents:\n %2").arg(Name()).arg(contents); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewitem.cpp000644 001750 001750 00000173333 11544160207 020020 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "viewitem.h" #include "applicationsettings.h" #include "viewitemdialog.h" #include "viewgridlayout.h" #include "plotitem.h" #include "plotitemmanager.h" #include "document.h" #include "layoutboxitem.h" #include "gridlayouthelper.h" #include #include #include #include #include #include #include #include #include #include #include static const double ONE_PI = 3.14159265358979323846264338327950288419717; static double TWO_PI = 2.0 * ONE_PI; static double RAD2DEG = 180.0 / ONE_PI; static const int DRAWING_ZORDER = 500; #define DEBUG_GEOMETRY 0 #define DEBUG_REPARENT 0 #define DEBUG_CHILD_GEOMETRY 0 // enable drag & drop #define KST_ENABLE_DD namespace Kst { ViewItem::ViewItem(View *parentView) : QObject(parentView), NamedObject(), _isXTiedZoom(false), _isYTiedZoom(false), _plotMaximized(false), _gripMode(Move), _allowedGripModes(Move | Resize | Rotate /*| Scale*/), _creationState(None), _typeName("View Item"), _zoomOnlyMode(View::ZoomOnlyDisabled), _supportsTiedZoom(false), _fixedSize(false), _lockAspectRatio(false), _lockAspectRatioFixed(false), _hasStaticGeometry(false), _lockParent(false), _skipNextParentCheck(false), _allowsLayout(true), _hovering(false), _acceptsChildItems(true), _acceptsContextMenuEvents(true), _updatingLayout(false), _highlighted(false), _activeGrip(NoGrip), _allowedGrips(TopLeftGrip | TopRightGrip | BottomRightGrip | BottomLeftGrip | TopMidGrip | RightMidGrip | BottomMidGrip | LeftMidGrip), _parentRelativeHeight(0), _parentRelativeWidth(0) { _initializeShortName(); setZValue(DRAWING_ZORDER); setAcceptsHoverEvents(true); setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable); connect(parentView, SIGNAL(mouseModeChanged(View::MouseMode)), this, SLOT(viewMouseModeChanged(View::MouseMode))); connect(parentView, SIGNAL(viewModeChanged(View::ViewMode)), this, SLOT(updateView())); connect(this, SIGNAL(geometryChanged()), parentView, SLOT(viewChanged())); setLayoutMargins(ApplicationSettings::self()->layoutMargins()); setLayoutSpacing(ApplicationSettings::self()->layoutSpacing()); // Add actions common to all view objects // create them here in the constructor so we // can register shortcuts. _editAction = new QAction(tr("Edit"), this); _editAction->setShortcut(Qt::Key_E); registerShortcut(_editAction); connect(_editAction, SIGNAL(triggered()), this, SLOT(edit())); _deleteAction = new QAction(tr("Delete"), this); _deleteAction->setShortcut(Qt::Key_Delete); registerShortcut(_deleteAction); connect(_deleteAction, SIGNAL(triggered()), this, SLOT(remove())); _raiseAction = new QAction(tr("Raise"), this); connect(_raiseAction, SIGNAL(triggered()), this, SLOT(raise())); _lowerAction = new QAction(tr("Lower"), this); connect(_lowerAction, SIGNAL(triggered()), this, SLOT(lower())); _autoLayoutAction = new QAction(tr("Automatic"), this); connect(_autoLayoutAction, SIGNAL(triggered()), this, SLOT(createAutoLayout())); _customLayoutAction = new QAction(tr("Custom"), this); connect(_customLayoutAction, SIGNAL(triggered()), this, SLOT(createCustomLayout())); // only drop plots onto TabBar setAcceptDrops(false); } ViewItem::~ViewItem() { } void ViewItem::_initializeShortName() { _shortName = 'D'+QString::number(_dnum); if (_dnum>max_dnum) max_dnum = _dnum; _dnum++; } void ViewItem::save(QXmlStreamWriter &xml) { xml.writeAttribute("name", typeName()); xml.writeStartElement("position"); xml.writeAttribute("x", QVariant(pos().x()).toString()); xml.writeAttribute("y", QVariant(pos().y()).toString()); xml.writeEndElement(); xml.writeStartElement("rect"); xml.writeAttribute("x", QVariant(viewRect().x()).toString()); xml.writeAttribute("y", QVariant(viewRect().y()).toString()); xml.writeAttribute("width", QVariant(viewRect().width()).toString()); xml.writeAttribute("height", QVariant(viewRect().height()).toString()); xml.writeEndElement(); xml.writeStartElement("relativesize"); xml.writeAttribute("width", QVariant(_parentRelativeWidth).toString()); xml.writeAttribute("height", QVariant(_parentRelativeHeight).toString()); xml.writeAttribute("centerx", QVariant(_parentRelativeCenter.x()).toString()); xml.writeAttribute("centery", QVariant(_parentRelativeCenter.y()).toString()); xml.writeAttribute("posx", QVariant(_parentRelativePosition.x()).toString()); xml.writeAttribute("posy", QVariant(_parentRelativePosition.y()).toString()); xml.writeEndElement(); xml.writeStartElement("transform"); xml.writeAttribute("m11", QVariant(transform().m11()).toString()); xml.writeAttribute("m12", QVariant(transform().m12()).toString()); xml.writeAttribute("m13", QVariant(transform().m13()).toString()); xml.writeAttribute("m21", QVariant(transform().m21()).toString()); xml.writeAttribute("m22", QVariant(transform().m22()).toString()); xml.writeAttribute("m23", QVariant(transform().m23()).toString()); xml.writeAttribute("m31", QVariant(transform().m31()).toString()); xml.writeAttribute("m32", QVariant(transform().m32()).toString()); xml.writeAttribute("m33", QVariant(transform().m33()).toString()); xml.writeEndElement(); xml.writeStartElement("pen"); xml.writeAttribute("style", QVariant(pen().style()).toString()); xml.writeAttribute("width", QVariant(pen().widthF()).toString()); xml.writeAttribute("miterlimit", QVariant(pen().miterLimit()).toString()); xml.writeAttribute("cap", QVariant(pen().capStyle()).toString()); xml.writeAttribute("joinStyle", QVariant(pen().joinStyle()).toString()); xml.writeStartElement("brush"); xml.writeAttribute("color", pen().brush().color().name()); xml.writeAttribute("style", QVariant(pen().brush().style()).toString()); xml.writeEndElement(); xml.writeEndElement(); xml.writeStartElement("brush"); xml.writeAttribute("color", brush().color().name()); xml.writeAttribute("style", QVariant(brush().style()).toString()); if (brush().gradient()) { QString stopList; foreach(QGradientStop stop, brush().gradient()->stops()) { qreal point = (qreal)stop.first; QColor color = (QColor)stop.second; stopList += QString::number(point); stopList += ','; stopList += color.name(); stopList += ','; } xml.writeAttribute("gradient", stopList); } xml.writeEndElement(); QList list = QGraphicsItem::children(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem) continue; viewItem->save(xml); } } bool ViewItem::parse(QXmlStreamReader &xml, bool &validChildTag) { bool knownTag = false; QString expectedTag; if (xml.isStartElement()) { expectedTag = xml.name().toString(); QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; if (xml.name().toString() == "name") { knownTag = true; av = attrs.value("name"); if (!av.isNull()) { setTypeName(av.toString()); } } else if (xml.name().toString() == "position") { knownTag = true; double x = 0, y = 0; av = attrs.value("x"); if (!av.isNull()) { x = av.toString().toDouble(); } av = attrs.value("y"); if (!av.isNull()) { y = av.toString().toDouble(); } setPos(x, y); } else if (xml.name().toString() == "brush") { knownTag = true; QBrush brush; av = attrs.value("gradient"); if (!av.isNull()) { QStringList stopInfo = av.toString().split(',', QString::SkipEmptyParts); QLinearGradient gradient(1,0,0,0); gradient.setCoordinateMode(QGradient::ObjectBoundingMode); for (int i = 0; i < stopInfo.size(); i+=2) { gradient.setColorAt(stopInfo.at(i).toDouble(), QColor(stopInfo.at(i+1))); } brush = QBrush(gradient); } else { av = attrs.value("color"); if (!av.isNull()) { brush.setColor(QColor(av.toString())); } av = attrs.value("style"); if (!av.isNull()) { brush.setStyle((Qt::BrushStyle)av.toString().toInt()); } } setBrush(brush); } else if (xml.name().toString() == "pen") { knownTag = true; QPen pen; av = attrs.value("style"); if (!av.isNull()) { pen.setStyle((Qt::PenStyle)av.toString().toInt()); } av = attrs.value("width"); if (!av.isNull()) { pen.setWidthF(av.toString().toDouble()); } av = attrs.value("miterlimit"); if (!av.isNull()) { pen.setMiterLimit(av.toString().toDouble()); } av = attrs.value("cap"); if (!av.isNull()) { pen.setCapStyle((Qt::PenCapStyle)av.toString().toInt()); } av = attrs.value("joinstyle"); if (!av.isNull()) { pen.setJoinStyle((Qt::PenJoinStyle)av.toString().toInt()); } xml.readNext(); xml.readNext(); if (xml.isStartElement() && (xml.name().toString() == "brush")) { QBrush penBrush; attrs = xml.attributes(); av = attrs.value("color"); if (!av.isNull()) { penBrush.setColor(QColor(av.toString())); } av = attrs.value("style"); if (!av.isNull()) { penBrush.setStyle((Qt::BrushStyle)av.toString().toInt()); } pen.setBrush(penBrush); xml.readNext(); if (!xml.isEndElement() || (xml.name().toString() != "brush")) { expectedTag = "InvalidTag"; } xml.readNext(); } setPen(pen); } else if (xml.name().toString() == "rect") { knownTag = true; double x = 0, y = 0, w = 10, h = 10; av = attrs.value("width"); if (!av.isNull()) { w = av.toString().toDouble(); } av = attrs.value("height"); if (!av.isNull()) { h = av.toString().toDouble(); } av = attrs.value("x"); if (!av.isNull()) { x = av.toString().toDouble(); } av = attrs.value("y"); if (!av.isNull()) { y = av.toString().toDouble(); } setViewRect(QRectF(QPointF(x, y), QSizeF(w, h))); } else if (xml.name().toString() == "relativesize") { knownTag = true; double width = 0, height = 0, centerx = 0, centery = 0, posx = 0, posy = 0; av = attrs.value("width"); if (!av.isNull()) { width = av.toString().toDouble(); } av = attrs.value("height"); if (!av.isNull()) { height = av.toString().toDouble(); } av = attrs.value("centerx"); if (!av.isNull()) { centerx = av.toString().toDouble(); } av = attrs.value("centery"); if (!av.isNull()) { centery = av.toString().toDouble(); } av = attrs.value("posx"); if (!av.isNull()) { posx = av.toString().toDouble(); } av = attrs.value("posy"); if (!av.isNull()) { posy = av.toString().toDouble(); } setRelativeWidth(width); setRelativeHeight(height); setRelativeCenter(QPointF(centerx, centery)); setRelativePosition(QPointF(posx, posy)); } else if (xml.name().toString() == "transform") { knownTag = true; double m11 = 1.0, m12 = 0, m13 = 0, m21 = 0, m22 = 1.0, m23 = 0, m31 = 0, m32= 0, m33 = 1.0; av = attrs.value("m11"); if (!av.isNull()) { m11 = av.toString().toDouble(); } av = attrs.value("m12"); if (!av.isNull()) { m12 = av.toString().toDouble(); } av = attrs.value("m13"); if (!av.isNull()) { m13 = av.toString().toDouble(); } av = attrs.value("m21"); if (!av.isNull()) { m21 = av.toString().toDouble(); } av = attrs.value("m22"); if (!av.isNull()) { m22 = av.toString().toDouble(); } av = attrs.value("m23"); if (!av.isNull()) { m23 = av.toString().toDouble(); } av = attrs.value("m31"); if (!av.isNull()) { m31 = av.toString().toDouble(); } av = attrs.value("m32"); if (!av.isNull()) { m32 = av.toString().toDouble(); } av = attrs.value("m33"); if (!av.isNull()) { m33 = av.toString().toDouble(); } setTransform(QTransform(m11, m12, m13, m21, m22, m23, m31, m32, m33)); } } if (knownTag) { xml.readNext(); if (xml.isEndElement()) { if ((xml.name().toString() == expectedTag) ) { validChildTag = true; } } } return knownTag; } View *ViewItem::view() const { return qobject_cast(QObject::parent()); } void ViewItem::setView(View* parentView) { QObject::setParent(parentView); reRegisterShortcut(); } ViewItem *ViewItem::parentViewItem() const { return qgraphicsitem_cast(parentItem()); } void ViewItem::setParentViewItem(ViewItem* parent) { QGraphicsItem::setParentItem(parent); updateRelativeSize(); } ViewItem::GripMode ViewItem::gripMode() const { return _gripMode; } void ViewItem::setGripMode(GripMode mode) { _gripMode = mode; update(); } ViewItem::GripModes ViewItem::allowedGripModes() const { return _allowedGripModes; } void ViewItem::setAllowedGripModes(GripModes modes) { _allowedGripModes = modes; } bool ViewItem::isAllowed(GripMode mode) const { return _allowedGripModes & mode; } QRectF ViewItem::viewRect() const { return rect(); } void ViewItem::setViewRect(const QRectF &viewRect, bool automaticChange) { QRectF oldViewRect = rect(); if (oldViewRect == viewRect) return; setRect(viewRect); emit geometryChanged(); if (!automaticChange) { updateRelativeSize(); } foreach (QGraphicsItem *item, QGraphicsItem::children()) { if (item->parentItem() != this) continue; ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem) continue; if (viewItem->hasStaticGeometry()) continue; viewItem->setSkipNextParentCheck(true); viewItem->updateChildGeometry(oldViewRect, viewRect); } } void ViewItem::setViewRect(qreal x, qreal y, qreal width, qreal height, bool automaticChange) { setViewRect(QRectF(x, y, width, height), automaticChange); } QSizeF ViewItem::sizeOfGrip() const { if (!view()) return QSizeF(); int base = 9; return view()->mapToScene(QRect(0, 0, base, base)).boundingRect().size(); } QPainterPath ViewItem::topLeftGrip() const { QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.topLeft(), sizeOfGrip()); QPainterPath path; if (_gripMode == Resize || _gripMode == Scale || _gripMode == Move) path.addRect(grip); else path.addEllipse(grip); return path; } QPainterPath ViewItem::topRightGrip() const { QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.topRight() - QPointF(sizeOfGrip().width(), 0), sizeOfGrip()); QPainterPath path; if (_gripMode == Resize || _gripMode == Scale || _gripMode == Move) path.addRect(grip); else path.addEllipse(grip); return path; } QPainterPath ViewItem::bottomRightGrip() const { QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.bottomRight() - QPointF(sizeOfGrip().width(), sizeOfGrip().height()), sizeOfGrip()); QPainterPath path; if (_gripMode == Resize || _gripMode == Scale || _gripMode == Move) path.addRect(grip); else path.addEllipse(grip); return path; } QPainterPath ViewItem::bottomLeftGrip() const { QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.bottomLeft() - QPointF(0, sizeOfGrip().height()), sizeOfGrip()); QPainterPath path; if (_gripMode == Resize || _gripMode == Scale || _gripMode == Move) path.addRect(grip); else path.addEllipse(grip); return path; } QPainterPath ViewItem::topMidGrip() const { if (_gripMode == Move || _gripMode == Rotate || _lockAspectRatio) return QPainterPath(); QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.topLeft(), sizeOfGrip()); grip.moveCenter(QPointF(bound.center().x(), grip.center().y())); QPainterPath path; path.addRect(grip); return path; } QPainterPath ViewItem::rightMidGrip() const { if (_gripMode == Move || _gripMode == Rotate || _lockAspectRatio) return QPainterPath(); QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.topRight() - QPointF(sizeOfGrip().width(), 0), sizeOfGrip()); grip.moveCenter(QPointF(grip.center().x(), bound.center().y())); QPainterPath path; path.addRect(grip); return path; } QPainterPath ViewItem::bottomMidGrip() const { if (_gripMode == Move || _gripMode == Rotate || _lockAspectRatio) return QPainterPath(); QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.bottomLeft() - QPointF(0, sizeOfGrip().height()), sizeOfGrip()); grip.moveCenter(QPointF(bound.center().x(), grip.center().y())); QPainterPath path; path.addRect(grip); return path; } QPainterPath ViewItem::leftMidGrip() const { if (_gripMode == Move || _gripMode == Rotate || _lockAspectRatio) return QPainterPath(); QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.topLeft(), sizeOfGrip()); grip.moveCenter(QPointF(grip.center().x(), bound.center().y())); QPainterPath path; path.addRect(grip); return path; } QPainterPath ViewItem::grips() const { QPainterPath grips; grips.addPath(topLeftGrip()); grips.addPath(topRightGrip()); grips.addPath(bottomRightGrip()); grips.addPath(bottomLeftGrip()); grips.addPath(topMidGrip()); grips.addPath(rightMidGrip()); grips.addPath(bottomMidGrip()); grips.addPath(leftMidGrip()); return grips; } ViewItem::ActiveGrip ViewItem::activeGrip() const { return _activeGrip; } void ViewItem::setActiveGrip(ActiveGrip grip) { _activeGrip = grip; } ViewItem::ActiveGrips ViewItem::allowedGrips() const { return _allowedGrips; } void ViewItem::setAllowedGrips(ActiveGrips grips) { _allowedGrips = grips; } bool ViewItem::isAllowed(ActiveGrip grip) const { return _allowedGrips & grip; } QRectF ViewItem::selectBoundingRect() const { return rect(); } QRectF ViewItem::gripBoundingRect() const { QRectF bound = selectBoundingRect(); bound.setTopLeft(bound.topLeft() - QPointF(sizeOfGrip().width() / 2.0, sizeOfGrip().height() / 2.0)); bound.setWidth(bound.width() + sizeOfGrip().width() / 2.0); bound.setHeight(bound.height() + sizeOfGrip().height() / 2.0); return bound; } QRectF ViewItem::boundingRect() const { bool inCreation = false; if (view()) /* false when exiting */ inCreation = view()->mouseMode() == View::Create; if ((!isSelected() && !isHovering()) || inCreation) return QGraphicsRectItem::boundingRect(); QPolygonF gripBound = gripBoundingRect(); return QRectF(gripBound[0], gripBound[2]); } QPainterPath ViewItem::shape() const { if ((!isSelected() && !isHovering()) || (view()->mouseMode() == View::Create)) return itemShape(); QPainterPath selectPath; selectPath.setFillRule(Qt::WindingFill); selectPath.addPolygon(rect()); selectPath.addPath(grips()); return selectPath; } bool ViewItem::isMaximized() { if (_plotMaximized) { return true; } else if (parentViewItem()) { return parentViewItem()->isMaximized(); } else { return false; } } void ViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); if ((!isMaximized()) && view()->childMaximized()) { return; } painter->setPen(pen()); painter->setBrush(brush()); paint(painter); //this is the overload that subclasses should use... if (!view()->isPrinting() && !view()->childMaximized()) { painter->save(); painter->setPen(Qt::DotLine); painter->setBrush(Qt::NoBrush); if ((isSelected() || isHovering()) && view()->mouseMode() != View::Create && view()->viewMode() != View::Data) { painter->drawPath(shape()); if (_gripMode == Resize) painter->fillPath(grips(), Qt::blue); else if (_gripMode == Scale) painter->fillPath(grips(), Qt::black); else if (_gripMode == Rotate) painter->fillPath(grips(), Qt::red); else if (_gripMode == Move) painter->fillPath(grips(), Qt::transparent); } else if (isHighlighted()) { QColor highlightColor(QColor(255, 255, 0, 120)); painter->fillPath(shape(), highlightColor); } if (supportsTiedZoom()) { painter->save(); painter->setPen(Qt::black); painter->setRenderHint(QPainter::Antialiasing, true); painter->fillPath(checkBox(), Qt::white); if (isHovering()) { QRectF check = checkBox().controlPointRect(); check.setSize(QSizeF(check.width() / 1.8, check.height() / 1.8)); check.moveCenter(checkBox().controlPointRect().center()); QPainterPath p; p.addEllipse(check); painter->fillPath(p, Qt::black); } if (isTiedZoom()) { painter->save(); QColor c = Qt::black; c.setAlphaF(c.alphaF() * 0.5); painter->fillPath(tiedZoomCheck(), c); painter->restore(); } painter->setBrush(Qt::transparent); painter->drawPath(checkBox()); painter->restore(); } #if DEBUG_GEOMETRY // painter->fillRect(selectBoundingRect(), Qt::blue); QColor semiRed(QColor(255, 0, 0, 50)); painter->fillPath(shape(), semiRed); QPen p = painter->pen(); painter->setPen(Qt::white); painter->drawLine(_normalLine); painter->setPen(Qt::red); painter->drawLine(_rotationLine); painter->setPen(p); painter->drawText(rect().topLeft(), "TL"); painter->drawText(rect().topRight(), "TR"); painter->drawText(rect().bottomLeft(), "BL"); painter->drawText(rect().bottomRight(), "BR"); #endif painter->restore(); } } void ViewItem::paint(QPainter *painter) { Q_UNUSED(painter); } void ViewItem::edit() { ViewItemDialog *editDialog = new ViewItemDialog(this, kstApp->mainWindow()); editDialog->show(); } void ViewItem::sharePlots(QPainter *painter, bool creation) { if (!_updatingLayout) { _updatingLayout = true; ViewGridLayout::sharePlots(this, painter, creation); _updatingLayout = false; } } void ViewItem::createAutoLayout() { if (parentViewItem()) { LayoutCommand *layout = new LayoutCommand(parentViewItem()); layout->createLayout(); } else if (view()) { view()->createLayout(); } } void ViewItem::createCustomLayout() { bool ok; int columns = QInputDialog::getInteger(view(), tr("Kst"), tr("Select Number of Columns"),1, 0, 10, 1, &ok); if (ok) { if (parentViewItem()) { LayoutCommand *layout = new LayoutCommand(parentViewItem()); layout->createLayout(columns); } else if (view()) { view()->createLayout(columns); } } } void ViewItem::raise() { RaiseCommand *up = new RaiseCommand(this); up->redo(); } void ViewItem::lower() { LowerCommand *down = new LowerCommand(this); down->redo(); } void ViewItem::remove() { RemoveCommand *remove = new RemoveCommand(this); remove->redo(); } void ViewItem::creationPolygonChanged(View::CreationEvent event) { if (event == View::EscapeEvent) { deleteLater(); kstApp->mainWindow()->clearDrawingMarker(); return; } if (event == View::MousePress) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MousePress)); setPos(poly.first().x(), poly.first().y()); setViewRect(0.0, 0.0, 0.0, 0.0); view()->scene()->addItem(this); _creationState = InProgress; return; } if (event == View::MouseMove) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MouseMove)); QRectF newRect(rect().x(), rect().y(), poly.last().x() - rect().x(), poly.last().y() - rect().y()); setViewRect(newRect); return; } if (event == View::MouseRelease) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MouseRelease)); QRectF newRect(rect().x(), rect().y(), poly.last().x() - rect().x(), poly.last().y() - rect().y()); if (!newRect.isValid()) { newRect = newRect.normalized(); setPos(pos() + newRect.topLeft()); newRect.moveTopLeft(QPointF(0, 0)); setViewRect(newRect); view()->setPlotBordersDirty(true); } else { setViewRect(newRect.normalized()); } view()->disconnect(this, SLOT(deleteLater())); //Don't delete ourself view()->disconnect(this, SLOT(creationPolygonChanged(View::CreationEvent))); view()->setMouseMode(View::Default); updateViewItemParent(); _creationState = Completed; setZValue(1); emit creationComplete(); return; } } void ViewItem::addTitle(QMenu *menu) const { QWidgetAction *action = new QWidgetAction(menu); action->setEnabled(false); QLabel *label = new QLabel(typeName() + tr(" Menu"), menu); label->setAlignment(Qt::AlignCenter); label->setStyleSheet("QLabel {" "border-bottom: 2px solid lightGray;" "font: bold large;" "padding: 3px;" "margin: 1px;" "}"); action->setDefaultWidget(label); menu->addAction(action); } void ViewItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; addTitle(&menu); menu.addAction(_editAction); QMenu layoutMenu; if (!(lockParent() || (parentViewItem() && parentViewItem()->lockParent()))) { menu.addAction(_raiseAction); menu.addAction(_lowerAction); layoutMenu.setTitle(tr("Cleanup Layout")); layoutMenu.addAction(_autoLayoutAction); layoutMenu.addAction(_customLayoutAction); menu.addMenu(&layoutMenu); menu.addAction(_deleteAction); } addToMenuForContextEvent(menu); menu.exec(event->screenPos()); } void ViewItem::addToMenuForContextEvent(QMenu &menu) { Q_UNUSED(menu); } void ViewItem::startDragging(QWidget *widget, const QPointF& hotspot) { // UNDO tied zoom settings done in PlotItem::mousePressEvent setTiedZoom(false, false); QDrag *drag = new QDrag(widget); MimeDataViewItem* mimeData = new MimeDataViewItem; mimeData->item = this; mimeData->hotSpot = hotspot; drag->setMimeData(mimeData); QPixmap pixmap(sceneBoundingRect().size().toSize()); pixmap.fill(Qt::white); // Qt::transparent is maybe too expensive, and when // not moving a plot it also has no transparent background //pixmap.fill(Qt::transparent); QPainter painter(&pixmap); painter.translate(-rect().left(), -rect().top()); paint(&painter); // TODO also paint annotations QList children = childItems(); foreach(QGraphicsItem* child, children) { ViewItem* item = qgraphicsitem_cast(child); if (item) { item->paint(&painter); } } painter.end(); drag->setPixmap(pixmap); drag->setHotSpot(hotspot.toPoint()- rect().topLeft().toPoint()); hide(); Qt::DropActions dact = Qt::MoveAction; Qt::DropAction dropAction = drag->exec(dact); if (dropAction != Qt::MoveAction) { show(); } } void ViewItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (view()->viewMode() == View::Data) { event->ignore(); return; } #ifdef KST_ENABLE_DD if (!dragStartPosition.isNull() && event->buttons() & Qt::LeftButton) { if (view()->mouseMode() == View::Move) { startDragging(event->widget(), dragStartPosition.toPoint()); return; } } #endif if (view()->mouseMode() == View::Default) { if (gripMode() == ViewItem::Move || activeGrip() == NoGrip) { view()->setMouseMode(View::Move); view()->undoStack()->beginMacro(tr("Move")); } else if (gripMode() == ViewItem::Resize) { view()->setMouseMode(View::Resize); view()->undoStack()->beginMacro(tr("Resize")); } else if (gripMode() == ViewItem::Scale) { view()->setMouseMode(View::Scale); view()->undoStack()->beginMacro(tr("Scale")); } else if (gripMode() == ViewItem::Rotate) { view()->setMouseMode(View::Rotate); view()->undoStack()->beginMacro(tr("Rotate")); } } if (activeGrip() == NoGrip) return QGraphicsRectItem::mouseMoveEvent(event); QPointF p = event->pos(); QPointF s = event->scenePos(); if (gripMode() == ViewItem::Rotate) { switch(_activeGrip) { case TopLeftGrip: rotateTowards(topLeftGrip().controlPointRect().center(), p); break; case TopRightGrip: rotateTowards(topRightGrip().controlPointRect().center(), p); break; case BottomRightGrip: rotateTowards(bottomRightGrip().controlPointRect().center(), p); break; case BottomLeftGrip: rotateTowards(bottomLeftGrip().controlPointRect().center(), p); break; case TopMidGrip: rotateTowards(topMidGrip().controlPointRect().center(), p); break; case RightMidGrip: rotateTowards(rightMidGrip().controlPointRect().center(), p); break; case BottomMidGrip: rotateTowards(bottomMidGrip().controlPointRect().center(), p); break; case LeftMidGrip: rotateTowards(leftMidGrip().controlPointRect().center(), p); break; case NoGrip: break; } } else if (gripMode() == ViewItem::Resize) { switch(_activeGrip) { case TopLeftGrip: resizeTopLeft(p - topLeftGrip().controlPointRect().center()); break; case TopRightGrip: resizeTopRight(p - topRightGrip().controlPointRect().center()); break; case BottomRightGrip: resizeBottomRight(p - bottomRightGrip().controlPointRect().center()); break; case BottomLeftGrip: resizeBottomLeft(p - bottomLeftGrip().controlPointRect().center()); break; case TopMidGrip: resizeTop(p.y() - topMidGrip().controlPointRect().center().y()); break; case RightMidGrip: resizeRight(p.x() - rightMidGrip().controlPointRect().center().x()); break; case BottomMidGrip: resizeBottom(p.y() - bottomMidGrip().controlPointRect().center().y()); break; case LeftMidGrip: resizeLeft(p.x() - leftMidGrip().controlPointRect().center().x()); break; case NoGrip: break; } } else if (gripMode() == ViewItem::Scale) { switch(_activeGrip) { case TopLeftGrip: setTopLeft(s); break; case TopRightGrip: setTopRight(s); break; case BottomRightGrip: setBottomRight(s); break; case BottomLeftGrip: setBottomLeft(s); break; case TopMidGrip: setTop(s.y()); break; case RightMidGrip: setRight(s.x()); break; case BottomMidGrip: setBottom(s.y()); break; case LeftMidGrip: setLeft(s.x()); break; case NoGrip: break; } } updateRelativeSize(); } void ViewItem::resizeTopLeft(const QPointF &offset) { const qreal oldAspect = rect().width() / rect().height(); QRectF r = rect(); QPointF o = _lockAspectRatio ? lockOffset(offset, oldAspect, false) : offset; r.setTopLeft(r.topLeft() + o); if (!r.isValid()) return; const qreal newAspect = r.width() / r.height(); Q_ASSERT_X(_lockAspectRatio ? qFuzzyCompare(newAspect, oldAspect) : true, "lockAspect error", QString(QString::number(newAspect) + "!=" + QString::number(oldAspect)).toLatin1().constData()); Q_UNUSED(newAspect); setViewRect(r); } void ViewItem::resizeTopRight(const QPointF &offset) { const qreal oldAspect = rect().width() / rect().height(); QRectF r = rect(); QPointF o = _lockAspectRatio ? lockOffset(offset, oldAspect, true) : offset; r.setTopRight(r.topRight() + o); if (!r.isValid()) return; const qreal newAspect = r.width() / r.height(); Q_ASSERT_X(_lockAspectRatio ? qFuzzyCompare(newAspect, oldAspect) : true, "lockAspect error", QString(QString::number(newAspect) + "!=" + QString::number(oldAspect)).toLatin1().constData()); Q_UNUSED(newAspect); setViewRect(r); } void ViewItem::resizeBottomLeft(const QPointF &offset) { const qreal oldAspect = rect().width() / rect().height(); QRectF r = rect(); QPointF o = _lockAspectRatio ? lockOffset(offset, oldAspect, true) : offset; r.setBottomLeft(r.bottomLeft() + o); if (!r.isValid()) return; const qreal newAspect = r.width() / r.height(); Q_ASSERT_X(_lockAspectRatio ? qFuzzyCompare(newAspect, oldAspect) : true, "lockAspect error", QString(QString::number(newAspect) + "!=" + QString::number(oldAspect)).toLatin1().constData()); Q_UNUSED(newAspect); setViewRect(r); } void ViewItem::resizeBottomRight(const QPointF &offset) { const qreal oldAspect = rect().width() / rect().height(); QRectF r = rect(); QPointF o = _lockAspectRatio ? lockOffset(offset, oldAspect, false) : offset; r.setBottomRight(r.bottomRight() + o); if (!r.isValid()) return; const qreal newAspect = r.width() / r.height(); Q_ASSERT_X(_lockAspectRatio ? qFuzzyCompare(newAspect, oldAspect) : true, "lockAspect error", QString(QString::number(newAspect) + "!=" + QString::number(oldAspect)).toLatin1().constData()); Q_UNUSED(newAspect); setViewRect(r); } void ViewItem::resizeTop(qreal offset) { QRectF r = rect(); r.setTop(r.top() + offset); if (!r.isValid()) return; setViewRect(r); } void ViewItem::resizeBottom(qreal offset) { QRectF r = rect(); r.setBottom(r.bottom() + offset); if (!r.isValid()) return; setViewRect(r); } void ViewItem::resizeLeft(qreal offset) { QRectF r = rect(); r.setLeft(r.left() + offset); if (!r.isValid()) return; setViewRect(r); } void ViewItem::resizeRight(qreal offset) { QRectF r = rect(); r.setRight(r.right() + offset); if (!r.isValid()) return; setViewRect(r); } void ViewItem::setTopLeft(const QPointF &point) { QPointF p = point; QPointF anchor = selectTransform().map(rect().bottomRight()); QRectF from = selectBoundingRect(); QRectF to = from; to.setTopLeft(p); from.moveBottomRight(anchor); to.moveBottomRight(anchor); transformToRect(from, to); } void ViewItem::setTopRight(const QPointF &point) { QPointF p = point; QPointF anchor = selectTransform().map(rect().bottomLeft()); QRectF from = selectBoundingRect(); QRectF to = from; to.setTopRight(p); from.moveBottomLeft(anchor); to.moveBottomLeft(anchor); transformToRect(from, to); } void ViewItem::setBottomLeft(const QPointF &point) { QPointF p = point; QPointF anchor = selectTransform().map(rect().topRight()); QRectF from = selectBoundingRect(); QRectF to = from; to.setBottomLeft(p); from.moveTopRight(anchor); to.moveTopRight(anchor); transformToRect(from, to); } void ViewItem::setBottomRight(const QPointF &point) { QPointF p = point; QPointF anchor = selectTransform().map(rect().topLeft()); QRectF from = selectBoundingRect(); QRectF to = from; to.setBottomRight(p); from.moveTopLeft(anchor); to.moveTopLeft(anchor); transformToRect(from, to); } void ViewItem::setTop(qreal y) { QPointF anchor = selectTransform().map(rect().bottomLeft()); QRectF from = selectBoundingRect(); QRectF to = from; to.setTop(y); from.moveBottomLeft(anchor); to.moveBottomLeft(anchor); transformToRect(from, to); } void ViewItem::setBottom(qreal y) { QPointF anchor = selectTransform().map(rect().topLeft()); QRectF from = selectBoundingRect(); QRectF to = from; to.setBottom(y); from.moveTopLeft(anchor); to.moveTopLeft(anchor); transformToRect(from, to); } void ViewItem::setLeft(qreal x) { QPointF anchor = selectTransform().map(rect().topRight()); QRectF from = selectBoundingRect(); QRectF to = from; to.setLeft(x); from.moveTopRight(anchor); to.moveTopRight(anchor); transformToRect(from, to); } void ViewItem::setRight(qreal x) { QPointF anchor = selectTransform().map(rect().topLeft()); QRectF from = selectBoundingRect(); QRectF to = from; to.setRight(x); from.moveTopLeft(anchor); to.moveTopLeft(anchor); transformToRect(from, to); } QTransform ViewItem::selectTransform() const { /* Converts a point on the rect() to a point on the selectBoundingRect() or the inverse by using selectTransform().inverted(). */ QRectF from = rect(); QRectF to = selectBoundingRect(); QTransform rt = _rotationTransform.inverted(); //inverse rotation so far QPolygonF from_ = QPolygonF(rt.map(from)); from_.pop_back(); //get rid of last closed point QPolygonF to_ = QPolygonF(mapFromScene(to)); to_.pop_back(); //get rid of last closed point QTransform select; QTransform::quadToQuad(from_, to_, select); return _rotationTransform.inverted() * select * transform(); } bool ViewItem::transformToRect(const QRectF &from, const QRectF &to) { //Not sure how to handle yet if (!to.isValid()) { return false; } QPolygonF from_(from); from_.pop_back(); //get rid of last closed point QPolygonF to_(to); to_.pop_back(); //get rid of last closed point return transformToRect(from_, to_); } bool ViewItem::transformToRect(const QPolygonF &from, const QPolygonF &to) { QTransform t; bool success = QTransform::quadToQuad(from, to, t); t = transform() * t; if (success) setTransform(t, false); return success; } void ViewItem::rotateTowards(const QPointF &corner, const QPointF &point) { QPointF origin = centerOfRotation(); if (origin == corner || origin == point) return; _normalLine = QLineF(origin, corner); _rotationLine = QLineF(origin, point); qreal angle1 = ::acos(_normalLine.dx() / _normalLine.length()); if (_normalLine.dy() >= 0) angle1 = TWO_PI - angle1; qreal angle2 = ::acos(_rotationLine.dx() / _rotationLine.length()); if (_rotationLine.dy() >= 0) angle2 = TWO_PI - angle2; qreal angle = RAD2DEG * (angle1 - angle2); QTransform t; t.translate(origin.x(), origin.y()); t.rotate(angle); t.translate(-origin.x(), -origin.y()); _rotationTransform = t * _rotationTransform; setTransform(t, true); } QPointF ViewItem::lockOffset(const QPointF &offset, qreal ratio, bool oddCorner) const { qreal x; qreal y; bool xKey; if (offset.x() < 0 && offset.y() > 0) { xKey = true; x = offset.x(); y = x == 0 ? 0 : (1 / ratio) * x; } else if (offset.y() < 0 && offset.x() > 0) { xKey = false; y = offset.y(); x = y == 0 ? 0 : ratio * y; } else if (qAbs(offset.x()) < qAbs(offset.y())) { xKey = true; x = offset.x(); y = x == 0 ? 0 : (1 / ratio) * x; } else { xKey = false; y = offset.y(); x = y == 0 ? 0 : ratio * y; } QPointF o = offset; if (oddCorner) { o = QPointF(!xKey ? -x : x, xKey ? -y : y); } else { o = QPointF(x, y); } return o; } bool ViewItem::updateViewItemParent() { if (lockParent() || skipNextParentCheck()) { setSkipNextParentCheck(false); return false; } //First get a list of all items that collide with this one QList collisions = collidingItems(Qt::IntersectsItemShape); bool topLevel = !parentItem(); QPointF origin = mapToScene(QPointF(0,0)); #if DEBUG_REPARENT qDebug() << "updateViewItemParent" << this << "topLevel:" << (topLevel ? "true" : "false") << "origin:" << origin << "rect:" << rect() << "collision count:" << collisions.count() << endl; #endif //Doesn't collide then reparent to top-level if (collisions.isEmpty() && !topLevel) { #if DEBUG_REPARENT qDebug() << "reparent to topLevel" << endl; qDebug() << "before transform" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif /*bring the old parent's transform with us*/ setTransform(parentItem()->transform(), true); #if DEBUG_REPARENT qDebug() << "after transform" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif setParentViewItem(0); setPos(mapToParent(mapFromScene(origin)) + pos() - mapToParent(QPointF(0,0))); updateRelativeSize(); #if DEBUG_REPARENT qDebug() << "after new parent" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif return true; } //Look for collisions that completely contain us foreach (QGraphicsItem *item, collisions) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem || !viewItem->acceptsChildItems() || isAncestorOf(viewItem) || !collidesWithItem(viewItem, Qt::ContainsItemBoundingRect)) { #if DEBUG_REPARENT qDebug() << "rejecting collision" << viewItem << !viewItem->acceptsChildItems() << isAncestorOf(viewItem) << !collidesWithItem(viewItem, Qt::ContainsItemBoundingRect); #endif continue; } if (parentItem() == viewItem) { /*already done*/ #if DEBUG_REPARENT qDebug() << "already in containing parent" << endl; #endif return false; } #if DEBUG_REPARENT qDebug() << "reparent to" << viewItem << endl; qDebug() << "before transform" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif if (!topLevel) { /*bring the old parent's transform with us*/ setTransform(parentItem()->transform(), true); } /*cancel out the new parent's initial transform*/ setTransform(viewItem->transform().inverted(), true); #if DEBUG_REPARENT qDebug() << "after transform" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif setParentViewItem(viewItem); setPos(mapToParent(mapFromScene(origin)) + pos() - mapToParent(QPointF(0,0))); updateRelativeSize(); #if DEBUG_REPARENT qDebug() << "after new parent" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif return true; } //No suitable collisions then reparent to top-level if (!topLevel) { #if DEBUG_REPARENT qDebug() << "reparent to topLevel" << endl; qDebug() << "before transform" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif /*bring the old parent's transform with us*/ setTransform(parentItem()->transform(), true); #if DEBUG_REPARENT qDebug() << "after transform" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif setParentViewItem(0); setPos(mapToParent(mapFromScene(origin)) + pos() - mapToParent(QPointF(0,0))); updateRelativeSize(); #if DEBUG_REPARENT qDebug() << "after new parent" << "origin:" << mapToScene(QPointF(0,0)) << endl; #endif return true; } return false; } void ViewItem::updateRelativeSize() { if (parentViewItem()) { _parentRelativeHeight = (height() / parentViewItem()->height()); _parentRelativeWidth = (width() / parentViewItem()->width()); _parentRelativeCenter = mapToParent(rect().center()) - parentViewItem()->rect().topLeft(); _parentRelativeCenter = QPointF(_parentRelativeCenter.x() / parentViewItem()->width(), _parentRelativeCenter.y() / parentViewItem()->height()); _parentRelativePosition = mapToParent(rect().topLeft()) - parentViewItem()->rect().topLeft(); _parentRelativePosition = QPointF(_parentRelativePosition.x() / parentViewItem()->width(), _parentRelativePosition.y() / parentViewItem()->height()); } else if (view()) { _parentRelativeHeight = (height() / view()->height()); _parentRelativeWidth = (width() / view()->width()); _parentRelativeCenter = mapToParent(rect().center()) - view()->rect().topLeft(); _parentRelativeCenter = QPointF(_parentRelativeCenter.x() / view()->width(), _parentRelativeCenter.y() / view()->height()); _parentRelativePosition = mapToParent(rect().topLeft()) - view()->rect().topLeft(); _parentRelativePosition = QPointF(_parentRelativePosition.x() / view()->width(), _parentRelativePosition.y() / view()->height()); } else { _parentRelativeHeight = 0; _parentRelativeWidth = 0; _parentRelativeCenter = QPointF(0, 0); _parentRelativePosition = QPointF(0, 0); } } void ViewItem::updateChildGeometry(const QRectF &oldParentRect, const QRectF &newParentRect) { #if DEBUG_CHILD_GEOMETRY qDebug() << "ViewItem::updateChildGeometry" << this << oldParentRect << newParentRect << endl; #else Q_UNUSED(oldParentRect); #endif QRectF itemRect = rect(); //Lock aspect ratio for rotating objects or children with a lockedAspectRatio //FIXME is the child rotated with respect to the parent is the real question... if (transform().isRotating() || lockAspectRatio()) { #if DEBUG_CHILD_GEOMETRY qDebug() << "ViewItem::updateChildGeometry Fixed Ratio" << mapToParent(rect().center()) << _parentRelativeCenter; #endif if (!_fixedSize) { qreal newHeight = relativeHeight() * newParentRect.height(); qreal newWidth = relativeWidth() * newParentRect.width(); qreal aspectRatio = rect().width() / rect().height(); if ((newWidth / newHeight) > aspectRatio) { // newWidth is too large. Use newHeight as key. newWidth = newHeight * aspectRatio; } else { // newHeight is either too large, or perfect. use newWidth as key. newHeight = newWidth / aspectRatio; } itemRect.setBottom(itemRect.top() + newHeight); itemRect.setRight(itemRect.left() + newWidth); } QPointF newCenter = newParentRect.topLeft() + QPointF(newParentRect.width() * _parentRelativeCenter.x(), newParentRect.height() * _parentRelativeCenter.y()); QRectF r = itemRect; r.moveCenter(mapFromParent(newCenter)); QPointF centerOffset = mapToParent(r.topLeft()) - mapToParent(itemRect.topLeft()); setPos(pos() + centerOffset); } else { qreal newHeight = relativeHeight() * newParentRect.height(); qreal newWidth = relativeWidth() * newParentRect.width(); #if DEBUG_CHILD_GEOMETRY qDebug() << "ViewItem::updateChildGeometry non-Fixed Ratio" << "relativeHeight = " << relativeHeight() << "relative Width" << relativeWidth(); #endif QPointF newTopLeft = newParentRect.topLeft() - itemRect.topLeft() + QPointF(newParentRect.width() * _parentRelativePosition.x(), newParentRect.height() * _parentRelativePosition.y()); itemRect.setWidth(newWidth); itemRect.setHeight(newHeight); setPos(newTopLeft); } #if DEBUG_CHILD_GEOMETRY qDebug() << "resize" << "\nbefore:" << rect() << "\nafter:" << itemRect << endl; #endif setViewRect(itemRect, true); } void ViewItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { if (view()->viewMode() == View::Data) { event->ignore(); return; } } void ViewItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (view()->viewMode() == View::Data) { event->ignore(); return; } const QPointF p = event->pos(); dragStartPosition = p; if (isAllowed(TopLeftGrip) && topLeftGrip().contains(p)) { setActiveGrip(TopLeftGrip); } else if (isAllowed(TopRightGrip) && topRightGrip().contains(p)) { setActiveGrip(TopRightGrip); } else if (isAllowed(BottomRightGrip) && bottomRightGrip().contains(p)) { setActiveGrip(BottomRightGrip); } else if (isAllowed(BottomLeftGrip) && bottomLeftGrip().contains(p)) { setActiveGrip(BottomLeftGrip); } else if (isAllowed(TopMidGrip) && topMidGrip().contains(p)) { setActiveGrip(TopMidGrip); } else if (isAllowed(RightMidGrip) && rightMidGrip().contains(p)) { setActiveGrip(RightMidGrip); } else if (isAllowed(BottomMidGrip) && bottomMidGrip().contains(p)) { setActiveGrip(BottomMidGrip); } else if (isAllowed(LeftMidGrip) && leftMidGrip().contains(p)) { setActiveGrip(LeftMidGrip); } else { setActiveGrip(NoGrip); } if (!grips().contains(event->pos()) && event->button() & Qt::LeftButton) { setGripMode(nextGripMode(_gripMode)); } QGraphicsRectItem::mousePressEvent(event); } ViewItem::GripMode ViewItem::nextGripMode(GripMode currentMode) const { if (!(_allowedGripModes & (Resize | Rotate | Scale))) return currentMode; switch (currentMode) { case Move: if (isAllowed(Resize)) return Resize; else return nextGripMode(Resize); break; case Resize: if (isAllowed(Scale)) return Scale; else return nextGripMode(Scale); break; case Scale: if (isAllowed(Rotate)) return Rotate; else return nextGripMode(Rotate); break; case Rotate: if (isAllowed(Resize)) return Resize; else return nextGripMode(Resize); break; default: break; } return currentMode; } void ViewItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (view()->viewMode() == View::Data) { event->ignore(); return; } dragStartPosition = QPointF(0, 0); if (view()->mouseMode() != View::Default) { view()->setMouseMode(View::Default); view()->undoStack()->endMacro(); } QGraphicsRectItem::mouseReleaseEvent(event); } void ViewItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { QGraphicsRectItem::hoverMoveEvent(event); if (view()->viewMode() == View::Data) { return; } if (isSelected()) { QPointF p = event->pos(); if ((isAllowed(TopLeftGrip) && topLeftGrip().contains(p)) || (isAllowed(BottomRightGrip) && bottomRightGrip().contains(p))) { if (gripMode() == ViewItem::Rotate) { view()->setCursor(Qt::CrossCursor); } else if (gripMode() == ViewItem::Resize) { view()->setCursor(Qt::SizeFDiagCursor); } } else if ((isAllowed(TopRightGrip) && topRightGrip().contains(p)) || (isAllowed(BottomLeftGrip) && bottomLeftGrip().contains(p))) { if (gripMode() == ViewItem::Rotate) { view()->setCursor(Qt::CrossCursor); } else if (gripMode() == ViewItem::Resize) { view()->setCursor(Qt::SizeBDiagCursor); } } else if ((isAllowed(TopMidGrip) && topMidGrip().contains(p)) || (isAllowed(BottomMidGrip) && bottomMidGrip().contains(p))) { if (gripMode() == ViewItem::Rotate) { view()->setCursor(Qt::CrossCursor); } else if (gripMode() == ViewItem::Resize) { view()->setCursor(Qt::SizeVerCursor); } } else if ((isAllowed(RightMidGrip) && rightMidGrip().contains(p)) || (isAllowed(LeftMidGrip) && leftMidGrip().contains(p))) { if (gripMode() == ViewItem::Rotate) { view()->setCursor(Qt::CrossCursor); } else if (gripMode() == ViewItem::Resize) { view()->setCursor(Qt::SizeHorCursor); } } else { view()->setCursor(Qt::SizeAllCursor); } } else { view()->setCursor(Qt::SizeAllCursor); } } void ViewItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { QGraphicsRectItem::hoverMoveEvent(event); _hovering = true; update(); } void ViewItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { QGraphicsRectItem::hoverMoveEvent(event); view()->setCursor(Qt::ArrowCursor); _hovering = false; update(); } QVariant ViewItem::itemChange(GraphicsItemChange change, const QVariant &value) { if (change == ItemSelectedChange) { bool selected = value.toBool(); if (!selected) { setGripMode(ViewItem::Move); update(); } } return QGraphicsItem::itemChange(change, value); } void ViewItem::moveTo(const QPointF& pos) { QPointF newpos = view()->snapPoint(pos); if (parentViewItem()) { newpos -= parentViewItem()->scenePos(); } setPos(newpos); new MoveCommand(this, _originalPosition, pos); updateViewItemParent(); updateRelativeSize(); } void ViewItem::viewMouseModeChanged(View::MouseMode oldMode) { if (view()->mouseMode() == View::Move) { _originalPosition = pos(); } else if (view()->mouseMode() == View::Resize || view()->mouseMode() == View::Scale || view()->mouseMode() == View::Rotate) { _originalRect = rect(); _originalTransform = transform(); } else if (oldMode == View::Move && _originalPosition != pos()) { #ifndef KST_ENABLE_DD moveTo(pos()); #endif } else if (oldMode == View::Resize && _originalRect != rect()) { new ResizeCommand(this, _originalRect, rect()); updateViewItemParent(); } else if (oldMode == View::Scale && _originalTransform != transform()) { new ScaleCommand(this, _originalTransform, transform()); updateViewItemParent(); } else if (oldMode == View::Rotate && _originalTransform != transform()) { new RotateCommand(this, _originalTransform, transform()); updateViewItemParent(); } } void ViewItem::registerShortcut(QAction *action) { Q_ASSERT(action->parent() == this); view()->grabShortcut(action->shortcut()); _shortcutMap.insert(action->shortcut(), action); } void ViewItem::reRegisterShortcut() { QHashIterator it(_shortcutMap); while (it.hasNext()) { it.next(); view()->grabShortcut(it.key()); } } bool ViewItem::tryShortcut(const QString &shortcut) { if (!_shortcutMap.contains(shortcut)) return false; QAction *action = _shortcutMap.value(shortcut); if (!action->isEnabled()) return false; action->trigger(); return true; } QPainterPath ViewItem::checkBox() const { QRectF bound = selectBoundingRect(); QRectF grip = QRectF(bound.topRight() - QPointF(sizeOfGrip().width() * 1.25, sizeOfGrip().height() * -.25), sizeOfGrip()); QPainterPath path; path.addEllipse(grip); return path; } QPainterPath ViewItem::tiedZoomCheck() const { QRectF bound = selectBoundingRect(); QRectF grip = QRectF(bound.topRight() - QPointF(sizeOfGrip().width() * 1.25, sizeOfGrip().height() * -.25), sizeOfGrip()); QPainterPath path; if (isXTiedZoom() && isYTiedZoom()) { path.addEllipse(grip); } else if (isXTiedZoom()) { path.moveTo(grip.center()); path.arcTo(grip, 225, 180); } else if (isYTiedZoom()) { path.moveTo(grip.center()); path.arcTo(grip, 45, 180); } return path; } void ViewItem::updateView() { update(); } qreal ViewItem::rotationAngle() const { return 180.0/ONE_PI * atan2(transform().m12(), transform().m11()); } void ViewItem::setSupportsTiedZoom(const bool supports) { if (supports != _supportsTiedZoom) { _supportsTiedZoom = supports; if (_supportsTiedZoom && ((layoutMargins().width() < tiedZoomSize().width()) || (layoutMargins().height() < tiedZoomSize().height()))) { setLayoutMargins(layoutMargins().expandedTo(tiedZoomSize())); } if (_supportsTiedZoom) { PlotItemManager::self()->addViewItem(this); } else { setTiedZoom(false, false, false); PlotItemManager::self()->removeViewItem(this); } } } void ViewItem::setTiedZoom(bool tiedXZoom, bool tiedYZoom, bool checkAllTied) { Q_UNUSED(checkAllTied) if ((_isXTiedZoom == tiedXZoom) && (_isYTiedZoom == tiedYZoom)) return; bool wasTiedZoom = isTiedZoom(); _isXTiedZoom = tiedXZoom; _isYTiedZoom = tiedYZoom; if (isTiedZoom() && !wasTiedZoom) { PlotItemManager::self()->addTiedZoomViewItem(this); } else if (!isTiedZoom() && wasTiedZoom) { PlotItemManager::self()->removeTiedZoomViewItem(this); } //FIXME ugh, this is expensive, but need to redraw the checkboxes... update(); } QString ViewItem::_automaticDescriptiveName() const { return typeName(); } QString ViewItem::descriptionTip() const { return typeName(); } #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, ViewItem *viewItem) { dbg.nospace() << viewItem->typeName(); return dbg.space(); } #endif ViewItemCommand::ViewItemCommand(ViewItem *item, const QString &text, bool addToStack, QUndoCommand *parent) : QUndoCommand(text, parent), _item(item) { if (addToStack) _item->view()->undoStack()->push(this); } ViewItemCommand::~ViewItemCommand() { } CreateCommand::CreateCommand(const QString &text, QUndoCommand *parent) : ViewCommand(text, false, parent) { } CreateCommand::CreateCommand(View *view, const QString &text, QUndoCommand *parent) : ViewCommand(view, text, false, parent) { } CreateCommand::~CreateCommand() { } void CreateCommand::undo() { Q_ASSERT(_item); _item->hide(); } void CreateCommand::redo() { Q_ASSERT(_item); _item->show(); } void CreateCommand::createItem() { Q_ASSERT(_item); Q_ASSERT(_view); _view->setMouseMode(View::Create); //If the mouseMode is changed again before we're done with creation //delete ourself. connect(_view, SIGNAL(mouseModeChanged(View::MouseMode)), _item, SLOT(deleteLater())); connect(_view, SIGNAL(creationPolygonChanged(View::CreationEvent)), _item, SLOT(creationPolygonChanged(View::CreationEvent))); connect(_item, SIGNAL(creationComplete()), this, SLOT(creationComplete())); //If the item is interrupted while creating itself it will destroy itself //need to delete this too in response... connect(_item, SIGNAL(destroyed(QObject*)), this, SLOT(deleteLater())); } void CreateCommand::creationComplete() { _view->undoStack()->push(this); kstApp->mainWindow()->clearDrawingMarker(); } void LayoutCommand::undo() { Q_ASSERT(_layout); _layout->reset(); } void LayoutCommand::redo() { Q_ASSERT(_layout); _layout->apply(); } void LayoutCommand::createLayout(int columns) { Q_ASSERT(_item); Q_ASSERT(_item->view()); QList viewItems; QList list = _item->QGraphicsItem::children(); if (list.isEmpty()) return; //not added to undostack foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem || viewItem->hasStaticGeometry() || !viewItem->allowsLayout() || viewItem->parentItem() != _item) continue; viewItems.append(viewItem); } if (viewItems.isEmpty()) return; //not added to undostack Grid *grid = Grid::buildGrid(viewItems, columns); Q_ASSERT(grid); _layout = new ViewGridLayout(_item); foreach (ViewItem *v, viewItems) { int r = 0, c = 0, rs = 0, cs = 0; if (grid->locateWidget(v, r, c, rs, cs)) { _layout->addViewItem(v, r, c, rs, cs); } else { grid->appendItem(v); if (grid->locateWidget(v, r, c, rs, cs)) { _layout->addViewItem(v, r, c, rs, cs); } else { qDebug() << "ooops, viewItem does not fit in layout" << endl; } } } delete grid; if (qobject_cast(_item)) { QObject::connect(_layout, SIGNAL(enabledChanged(bool)), _item, SLOT(setEnabled(bool))); } _layout->apply(); _item->view()->undoStack()->push(this); } void AppendLayoutCommand::undo() { if (_layout) { _layout->reset(); } } void AppendLayoutCommand::redo() { Q_ASSERT(_layout); _layout->apply(); } void AppendLayoutCommand::appendLayout(CurvePlacement::Layout layout, ViewItem* item, int columns) { Q_ASSERT(_item); Q_ASSERT(_item->view()); Q_ASSERT(item); _layout = new ViewGridLayout(_item); QPointF center = _item->view()->sceneRect().center(); center -= QPointF(100.0, 100.0); item->setPos(center); item->setViewRect(0.0, 0.0, 200.0, 200.0); _item->view()->scene()->addItem(item); if (layout == CurvePlacement::Auto) { columns = 0; } if (layout != CurvePlacement::Protect) { QList viewItems; QList list = _item->QGraphicsItem::children(); foreach (QGraphicsItem *graphicsItem, list) { ViewItem *viewItem = qgraphicsitem_cast(graphicsItem); if (!viewItem || viewItem->hasStaticGeometry() || !viewItem->allowsLayout() || viewItem->parentItem() != _item || viewItem == item) continue; viewItems.append(viewItem); } bool appendRequired = true; if (viewItems.isEmpty()) { viewItems.append(item); appendRequired = false; } if (layout == CurvePlacement::Auto) { columns = (int)sqrt((double)viewItems.count()+1); } Grid *grid = Grid::buildGrid(viewItems, columns); Q_ASSERT(grid); grid->appendItem(item); if (appendRequired) { viewItems.append(item); } _layout = new ViewGridLayout(_item); foreach (ViewItem *v, viewItems) { int r = 0, c = 0, rs = 0, cs = 0; if (grid->locateWidget(v, r, c, rs, cs)) { if (rs * cs == 1) { _layout->addViewItem(v, r, c, 1, 1); } else { _layout->addViewItem(v, r, c, rs, cs); } } else { qDebug() << "ooops, viewItem does not fit in layout" << endl; } } delete grid; if (qobject_cast(_item)) { QObject::connect(_layout, SIGNAL(enabledChanged(bool)), _item, SLOT(setEnabled(bool))); } _layout->apply(); } _item->view()->undoStack()->push(this); } void MoveCommand::undo() { Q_ASSERT(_item); _item->setPos(_originalPos); } void MoveCommand::redo() { Q_ASSERT(_item); _item->setPos(_newPos); } void ResizeCommand::undo() { Q_ASSERT(_item); _item->setViewRect(_originalRect, true); } void ResizeCommand::redo() { Q_ASSERT(_item); _item->setViewRect(_newRect, true); } void RemoveCommand::undo() { Q_ASSERT(_item); _item->show(); } void RemoveCommand::redo() { Q_ASSERT(_item); _item->hide(); // hmmm... view items aren't really deleted!! if we delete them, // then we run into trouble with the undo stack. If we don't, then // they keep holding onto the curves, preventing purge. } void RaiseCommand::undo() { Q_ASSERT(_item); _item->setZValue(_item->zValue() - 1); } void RaiseCommand::redo() { Q_ASSERT(_item); _item->setZValue(_item->zValue() + 1); } void LowerCommand::undo() { Q_ASSERT(_item); _item->setZValue(_item->zValue() + 1); } void LowerCommand::redo() { Q_ASSERT(_item); _item->setZValue(_item->zValue() - 1); } void TransformCommand::undo() { Q_ASSERT(_item); _item->setTransform(_originalTransform); } void TransformCommand::redo() { Q_ASSERT(_item); _item->setTransform(_newTransform); } MimeDataViewItem::MimeDataViewItem() : QMimeData() { } const MimeDataViewItem* MimeDataViewItem::downcast(const QMimeData* m) { return qobject_cast(m); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dimensionstab.h000644 001750 001750 00000003545 11544160207 020470 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) C. Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIMENSIONSTAB_H #define DIMENSIONSTAB_H #include "dialogtab.h" #include "viewitem.h" #include "ui_dimensionstab.h" #include "kst_export.h" namespace Kst { class DimensionsTab : public DialogTab, Ui::DimensionsTab { Q_OBJECT public: explicit DimensionsTab(ViewItem* viewItem, QWidget *parent = 0); virtual ~DimensionsTab(); void setupDimensions(); double x() {return _x->value();} double y() {return _y->value();} double width() {return _width->value();} bool widthDirty() const; double height() {return _height->value();} bool heightDirty() const; double rotation() {return _rotation->value();} bool rotationDirty() const; bool fixedAspect() {return _fixAspectRatio->isChecked();} bool fixedAspectDirty() const; void enableSingleEditOptions(bool enabled); void clearTabValues(); private: ViewItem *_viewItem; private Q_SLOTS: void modified(); void updateButtons(); Q_SIGNALS: void tabModified(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialog.ui000644 001750 001750 00000012441 11544160207 017251 0ustar00synthsynth000000 000000 Dialog Qt::NonModal 0 0 462 299 0 0 Dialog false 0 0 0 true 0 0 0 0 0 0 0 0 1 1 Qt::LeftToRight Qt::Horizontal false 0 0 QListView::Adjust true 1 0 -1 Save as default Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok _buttonBox accepted() Dialog accept() 248 254 157 274 _buttonBox rejected() Dialog reject() 316 260 286 274 kst-2.0.3/src/libkstapp/logdialog.cpp000644 001750 001750 00000015115 11544160207 020121 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 C. Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "logdialog.h" #include "dialogdefaults.h" #include "mainwindow.h" #include #include namespace Kst { LogDialog::LogDialog(MainWindow *parent) : QDialog(parent), _logtime(0), _format(QString()), _logdir(QString()), _parent(parent) { setupUi(this); QStringList formats; foreach(QByteArray array, QImageWriter::supportedImageFormats()) { formats.append(QString(array)); } _formats->addItems(formats); _formats->setCurrentIndex( _formats->findText(_dialogDefaults->value("log/format","png").toString())); _xSize->setValue(_dialogDefaults->value("log/xsize","1024").toInt()); _ySize->setValue(_dialogDefaults->value("log/ysize","768").toInt()); _sizeOption->setCurrentIndex(_dialogDefaults->value("log/sizeOption","0").toInt()); enableWidthHeight(); _saveLocation->setFile(_dialogDefaults->value("log/logdir",QDir::currentPath()).toString()); _script->setText(_dialogDefaults->value("log/script", QString()).toString()); _tab->setCurrentIndex(0); _user->setText(_dialogDefaults->value("log/user", QString()).toString()); connect(_message, SIGNAL(textChanged()), this, SLOT(changed())); connect(_sizeOption, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); connect(_formats, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); connect(_sizeOption, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); connect(_sizeOption, SIGNAL(currentIndexChanged(int)), this, SLOT(enableWidthHeight())); connect(_xSize, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(_ySize, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(_saveLocation, SIGNAL(changed(QString)), this, SLOT(changed())); connect(_saveLocation, SIGNAL(changed(QString)), this, SLOT(enableApply())); connect(_script, SIGNAL(textChanged(QString)), this, SLOT(enableApply())); connect(_close, SIGNAL(clicked()), this, SLOT(close())); connect(_apply, SIGNAL(clicked()), this, SLOT(apply())); _proc = new QProcess(this); connect(_proc, SIGNAL(readyReadStandardError()), this, SLOT(scriptStdErr())); connect(_proc, SIGNAL(readyReadStandardOutput()), this, SLOT(scriptStdOut())); connect(_proc, SIGNAL(started()), this, SLOT(scriptStarted())); connect(_proc, SIGNAL(finished(int)), this, SLOT(scriptFinished(int))); connect(_rerunScript, SIGNAL(clicked()), this, SLOT(runScript())); connect(_proc, SIGNAL(error(QProcess::ProcessError)), this, SLOT(scriptError(QProcess::ProcessError))); _saveLocation->setMode(QFileDialog::Directory); QFileInfo info(_saveLocation->file()); bool valid = info.isDir() && info.isWritable(); _apply->setEnabled(valid); _scriptRunning->clear(); } LogDialog::~LogDialog() { } void LogDialog::changed() { _rerunScript->setEnabled(false); _scriptRunning->clear(); } void LogDialog::enableApply() { QFileInfo info(_saveLocation->file()); bool file_valid = info.isDir() && info.isWritable(); _apply->setEnabled(file_valid); } void LogDialog::apply() { _logdir = _saveLocation->file(); _format = _formats->currentText(); _username = _user->text(); int x_size = _xSize->value(); int y_size = _ySize->value(); int size_option_index = _sizeOption->currentIndex(); _dialogDefaults->setValue("log/logdir", _logdir); _dialogDefaults->setValue("log/format", _format); _dialogDefaults->setValue("log/xsize", x_size); _dialogDefaults->setValue("log/ysize", y_size); _dialogDefaults->setValue("log/sizeOption", size_option_index); _dialogDefaults->setValue("log/script", _script->text()); _dialogDefaults->setValue("log/user", _username); _logtime = time(NULL); if (_logdir.endsWith('/')) { _imagename = _logdir; } else { _imagename = _logdir + '/'; } _imagename += QString::number(_logtime)+'.'; _msgfilename = _imagename + "txt"; _imagename += _format; _parent->exportLog(_imagename, _msgfilename, _format, x_size, y_size, size_option_index, _message->toPlainText()); runScript(); _rerunScript->setEnabled(true); } void LogDialog::runScript() { QString script = _script->text().simplified().replace("$imagefile",_imagename). replace("$messagefile", _msgfilename).replace("$user", _username); _proc->start(script); } void LogDialog::scriptStdErr() { } void LogDialog::scriptStdOut() { _scriptOutput->appendPlainText(_proc->readAllStandardOutput()); } void LogDialog::scriptStarted() { _scriptRunning->setText(i18n("Script: Running")); } void LogDialog::scriptFinished(int code) { if (code == 0) { _scriptRunning->setText(i18n("Script: Finished")); } else { _scriptRunning->setText(i18n("Script: return code %1").arg(code)); } } void LogDialog::scriptError(QProcess::ProcessError p) { if (p==QProcess::FailedToStart) { _scriptRunning->setText(i18n("Script error: Failed to start")); } else if (p==QProcess::Crashed) { _scriptRunning->setText(i18n("Script error: Crashed")); } else { _scriptRunning->setText(i18n("Script error:")); } } void LogDialog::enableWidthHeight() { int size_option_index = _sizeOption->currentIndex(); switch (size_option_index) { case 0: // Width and Maintain Aspect Ratio _xSize->setEnabled(true); _ySize->setEnabled(false); _widthLabel->setEnabled(true); _heightLabel->setEnabled(false); break; case 1: // Height and Maintain Aspect Ratio _xSize->setEnabled(false); _ySize->setEnabled(true); _widthLabel->setEnabled(false); _heightLabel->setEnabled(true); break; case 2: // Width and Height _xSize->setEnabled(true); _ySize->setEnabled(true); _widthLabel->setEnabled(true); _heightLabel->setEnabled(true); break; case 3: // Size of Square _xSize->setEnabled(true); _ySize->setEnabled(false); _widthLabel->setEnabled(true); _heightLabel->setEnabled(false); break; } } } kst-2.0.3/src/libkstapp/applicationsettingsdialog.cpp000644 001750 001750 00000020535 11544160207 023426 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "applicationsettingsdialog.h" #include "applicationsettings.h" #include "gridtab.h" #include "generaltab.h" #include "filltab.h" #include "dialogpage.h" #include "childviewoptionstab.h" #include "defaultlabelpropertiestab.h" #include "layouttab.h" #include namespace Kst { ApplicationSettingsDialog::ApplicationSettingsDialog(QWidget *parent) : Dialog(parent) { setWindowTitle(tr("Kst Settings")); setAttribute(Qt::WA_DeleteOnClose, false); _generalTab = new GeneralTab(this); _gridTab = new GridTab(this); _fillTab = new FillTab(this); _defaultLabelPropertiesTab = new DefaultLabelPropertiesTab(this); _layoutTab = new LayoutTab(this); // _childViewOptionsTab = new ChildViewOptionsTab(this); connect(_generalTab, SIGNAL(apply()), this, SLOT(generalChanged())); connect(_gridTab, SIGNAL(apply()), this, SLOT(gridChanged())); connect(_fillTab, SIGNAL(apply()), this, SLOT(fillChanged())); // connect(_childViewOptionsTab, SIGNAL(apply()), this, SLOT(childViewOptionsChanged())); connect(_defaultLabelPropertiesTab, SIGNAL(apply()), this, SLOT(defaultLabelPropertiesChanged())); connect(_layoutTab, SIGNAL(apply()), this, SLOT(layoutChanged())); DialogPage *general = new DialogPage(this); general->setPageTitle(tr("General")); general->addDialogTab(_generalTab); addDialogPage(general); DialogPage *defaultLabelProperties = new DialogPage(this); defaultLabelProperties->setPageTitle(tr("Fonts")); defaultLabelProperties->addDialogTab(_defaultLabelPropertiesTab); addDialogPage(defaultLabelProperties); DialogPage *grid = new DialogPage(this); grid->setPageTitle(tr("Grid")); grid->addDialogTab(_gridTab); addDialogPage(grid); DialogPage *fill = new DialogPage(this); fill->setPageTitle(tr("Default Fill Properties")); fill->addDialogTab(_fillTab); addDialogPage(fill); DialogPage *layout = new DialogPage(this); layout->setPageTitle(tr("Default Layout Properties")); layout->addDialogTab(_layoutTab); addDialogPage(layout); // DialogPage *childViewOptions = new DialogPage(this); // childViewOptions->setPageTitle(tr("Child View Options")); // childViewOptions->addDialogTab(_childViewOptionsTab); // addDialogPage(childViewOptions); setupGeneral(); setupGrid(); setupFill(); setupDefaultLabelProperties(); setupLayout(); // setupChildViewOptions(); selectDialogPage(general); } ApplicationSettingsDialog::~ApplicationSettingsDialog() { } void ApplicationSettingsDialog::setupGeneral() { _generalTab->setUseOpenGL(ApplicationSettings::self()->useOpenGL()); _generalTab->setMinimumUpdatePeriod(ApplicationSettings::self()->minimumUpdatePeriod()); } void ApplicationSettingsDialog::setupGrid() { _gridTab->setShowGrid(ApplicationSettings::self()->showGrid()); _gridTab->setSnapToGrid(ApplicationSettings::self()->snapToGrid()); _gridTab->setGridHorizontalSpacing(ApplicationSettings::self()->gridHorizontalSpacing()); _gridTab->setGridVerticalSpacing(ApplicationSettings::self()->gridVerticalSpacing()); } void ApplicationSettingsDialog::setupFill() { QGradientStops stops; stops.append(qMakePair(1.0, QColor(Qt::white))); stops.append(qMakePair(0.0, QColor(Qt::lightGray))); _fillTab->gradientEditor()->setDefaultGradientStops(stops); QBrush b = ApplicationSettings::self()->backgroundBrush(); _fillTab->setColor(b.color()); _fillTab->setStyle(b.style()); if (const QGradient *gradient = b.gradient()) { _fillTab->setGradient(*gradient); } } void ApplicationSettingsDialog::setupDefaultLabelProperties() { _defaultLabelPropertiesTab->setLabelFont(ApplicationSettings::self()->defaultFont()); _defaultLabelPropertiesTab->setLabelScale(ApplicationSettings::self()->defaultFontScale()); _defaultLabelPropertiesTab->setLabelColor(ApplicationSettings::self()->defaultFontColor()); _defaultLabelPropertiesTab->setReferenceViewWidth(ApplicationSettings::self()->referenceViewWidthCM()); _defaultLabelPropertiesTab->setReferenceViewHeight(ApplicationSettings::self()->referenceViewHeightCM()); _defaultLabelPropertiesTab->setMinimumFontSize(ApplicationSettings::self()->minimumFontSize()); } void ApplicationSettingsDialog::setupLayout() { _layoutTab->setHorizontalMargin(ApplicationSettings::self()->layoutMargins().width()); _layoutTab->setVerticalMargin(ApplicationSettings::self()->layoutMargins().height()); _layoutTab->setHorizontalSpacing(ApplicationSettings::self()->layoutSpacing().width()); _layoutTab->setVerticalSpacing(ApplicationSettings::self()->layoutSpacing().height()); } void ApplicationSettingsDialog::generalChanged() { //Need to block the signals so that the modified signal only goes out once... ApplicationSettings::self()->blockSignals(true); ApplicationSettings::self()->setUseOpenGL(_generalTab->useOpenGL()); ApplicationSettings::self()->setMinimumUpdatePeriod(_generalTab->minimumUpdatePeriod()); ApplicationSettings::self()->blockSignals(false); emit ApplicationSettings::self()->modified(); } void ApplicationSettingsDialog::gridChanged() { //Need to block the signals so that the modified signal only goes out once... ApplicationSettings::self()->blockSignals(true); ApplicationSettings::self()->setShowGrid(_gridTab->showGrid()); ApplicationSettings::self()->setSnapToGrid(_gridTab->snapToGrid()); ApplicationSettings::self()->setGridHorizontalSpacing(_gridTab->gridHorizontalSpacing()); ApplicationSettings::self()->setGridVerticalSpacing(_gridTab->gridVerticalSpacing()); ApplicationSettings::self()->blockSignals(false); emit ApplicationSettings::self()->modified(); } void ApplicationSettingsDialog::fillChanged() { QBrush b = ApplicationSettings::self()->backgroundBrush(); b.setColor(_fillTab->color()); b.setStyle(_fillTab->style()); QGradient gradient = _fillTab->gradient(); if (gradient.type() != QGradient::NoGradient) { QLinearGradient linearGradient; linearGradient.setStops(gradient.stops()); b = QBrush(linearGradient); } ApplicationSettings::self()->setBackgroundBrush(b); emit ApplicationSettings::self()->modified(); } void ApplicationSettingsDialog::defaultLabelPropertiesChanged() { //Need to block the signals so that the modified signal only goes out once... ApplicationSettings::self()->blockSignals(true); ApplicationSettings::self()->setDefaultFont(_defaultLabelPropertiesTab->labelFont()); ApplicationSettings::self()->setDefaultFontScale(_defaultLabelPropertiesTab->labelScale()); ApplicationSettings::self()->setDefaultFontColor(_defaultLabelPropertiesTab->labelColor()); ApplicationSettings::self()->blockSignals(false); ApplicationSettings::self()->setReferenceViewWidthCM(_defaultLabelPropertiesTab->referenceViewWidth()); ApplicationSettings::self()->setReferenceViewHeightCM(_defaultLabelPropertiesTab->referenceViewHeight()); ApplicationSettings::self()->setMinimumFontSize(_defaultLabelPropertiesTab->minimumFontSize()); emit ApplicationSettings::self()->modified(); } void ApplicationSettingsDialog::layoutChanged() { //Need to block the signals so that the modified signal only goes out once... ApplicationSettings::self()->blockSignals(true); ApplicationSettings::self()->setLayoutMargins(QSizeF(_layoutTab->horizontalMargin(), _layoutTab->verticalMargin())); ApplicationSettings::self()->setLayoutSpacing(QSizeF(_layoutTab->horizontalSpacing(), _layoutTab->verticalSpacing())); ApplicationSettings::self()->blockSignals(false); emit ApplicationSettings::self()->modified(); } void ApplicationSettingsDialog::setupChildViewOptions() { } void ApplicationSettingsDialog::childViewOptionsChanged() { } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialog.cpp000644 001750 001750 00000011376 11544160207 017424 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "dialog.h" #include "dialogpage.h" #include #include namespace Kst { Dialog::Dialog(QWidget *parent) : QDialog(parent), _allowApply(false) { setupUi(this); _saveAsDefault->hide(); extensionWidget()->hide(); connect(_listWidget, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(selectPageForItem(QListWidgetItem *))); connect(_buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *))); setAttribute(Qt::WA_DeleteOnClose); resize(minimumSizeHint()); } Dialog::~Dialog() { } void Dialog::addDialogPage(DialogPage *page, bool addMinSize) { connect(page, SIGNAL(modified()), this, SLOT(modified())); connect(this, SIGNAL(apply()), page, SIGNAL(apply())); QListWidgetItem *item = new QListWidgetItem(page->pageIcon(), page->pageTitle(), _listWidget); _listWidget->addItem(item); _stackedWidget->addWidget(page); _itemHash.insert(item, page); int itemWidth = _listWidget->visualItemRect(item).width() + 4; if (addMinSize && _listWidget->width() < itemWidth) { _listWidget->setMinimumSize(itemWidth, _listWidget->size().height()); } } void Dialog::removeDialogPage(DialogPage *page) { disconnect(page, SIGNAL(modified()), this, SLOT(modified())); disconnect(this, SIGNAL(apply()), page, SIGNAL(apply())); QList items = _listWidget->findItems(page->pageTitle(), Qt::MatchExactly); foreach (QListWidgetItem* item, items) { _itemHash.remove(item); _listWidget->takeItem(_listWidget->row(item)); _stackedWidget->removeWidget(page); } resetListWidget(); } void Dialog::resetListWidget() { int extraSize = _listWidget->width() - 100; _listWidget->setMaximumWidth(100); _listWidget->setMinimumWidth(100); if (extraSize > 0 ) { QList splitterSize; splitterSize << 100; splitterSize << _splitter->sizes()[1] + extraSize; _splitter->setSizes(splitterSize); } } DialogPage* Dialog::getDialogPage(const QString& pageName) { QList items = _listWidget->findItems(pageName, Qt::MatchExactly); if (!items.empty()) { return _itemHash.value(items[0]); } return 0; } void Dialog::selectDialogPage(DialogPage *page) { QList items = _listWidget->findItems(page->pageTitle(), Qt::MatchExactly); foreach (QListWidgetItem* item, items) { _listWidget->setCurrentItem(item); selectPageForItem(item); } } void Dialog::setVisible(bool visible) { _listWidget->setVisible(_itemHash.count() > 1); _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); QDialog::setVisible(visible); } QWidget *Dialog::leftCustomWidget() const { return _leftCustom; } QWidget *Dialog::rightCustomWidget() const { return _rightCustom; } QWidget *Dialog::topCustomWidget() const { return _topCustom; } QWidget *Dialog::bottomCustomWidget() const { return _bottomCustom; } QWidget *Dialog::extensionWidget() const { return _extensionWidget; } QDialogButtonBox *Dialog::buttonBox() const { return _buttonBox; } void Dialog::selectPageForItem(QListWidgetItem *item) { if (_itemHash.contains(item)) _stackedWidget->setCurrentWidget(_itemHash.value(item)); } void Dialog::buttonClicked(QAbstractButton *button) { QDialogButtonBox::StandardButton std = _buttonBox->standardButton(button); switch(std) { case QDialogButtonBox::Ok: emit apply(); emit ok(); break; case QDialogButtonBox::Apply: if (!_allowApply) { _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); } emit apply(); break; case QDialogButtonBox::Cancel: emit cancel(); break; default: break; } } void Dialog::setAlwaysAllowApply(const bool allow) { _allowApply = allow; if (!allow) { _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); } } void Dialog::modified() { _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/filltab.h000644 001750 001750 00000003375 11544160207 017247 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILLTAB_H #define FILLTAB_H #include "dialogtab.h" #include "ui_filltab.h" #include "kst_export.h" namespace Kst { class FillTab : public DialogTab, Ui::FillTab { Q_OBJECT public: FillTab(QWidget *parent = 0); virtual ~FillTab(); QColor color() const; bool colorDirty() const; void setColor(const QColor &color); Qt::BrushStyle style() const; bool styleDirty() const; void setStyle(Qt::BrushStyle style); QGradient gradient() const; bool gradientDirty() const; void setGradient(const QGradient &gradient); bool useGradient() const; bool useGradientDirty() const; void setUseGradient(const bool useGradient); GradientEditor *gradientEditor() { return _gradientEditor; } void enableSingleEditOptions(bool enabled); void clearTabValues(); public Q_SLOTS: void updateButtons(); private: bool _multiEdit; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datawizardpageplot.ui000644 001750 001750 00000027260 11544160207 021705 0ustar00synthsynth000000 000000 DataWizardPagePlot 0 0 653 376 Curve Placement &All curves in one plot false &1 new plot per curve Alt+1 true 0 Cycle t&hrough false QAbstractSpinBox::PlusMinus plots 2 64 Cycle through exis&ting plots false 0 All curv&es in plot false Plot Placement (Tabs) All in &current tab true All in ne&w tab XY and spectra in &separate new tabs Plot Layout Automatic &layout true Custo&m grid Columns: false 1 10 P&rotect existing layout Labels Rescale all labels on tab true Share axis on tab Cur&ve Style L&ines only true &Points only Lines an&d points Spectrum Axis Mode Lo&g X-axis &Log Y-axis Qt::Vertical 20 40 Legends O&n &Off A&uto true &Vertical Kst::ComboBox QComboBox
combobox.h
_cycleThrough toggled(bool) _plotNumber setEnabled(bool) 128 110 225 112 _customGrid toggled(bool) _gridColumns setEnabled(bool) 632 112 760 114 _existingPlot toggled(bool) _existingPlotName setEnabled(bool) 143 172 225 174 _currentTab toggled(bool) _cycleExisting setEnabled(bool) 251 54 101 133 _currentTab toggled(bool) _existingPlotName setEnabled(bool) 357 62 189 152 _currentTab toggled(bool) _existingPlot setEnabled(bool) 389 62 55 166
kst-2.0.3/src/libkstapp/labelcreator.ui000644 001750 001750 00000011777 11544160207 020464 0ustar00synthsynth000000 000000 LabelCreator 0 0 562 162 Dialog 0 0 Font &size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _labelFontScale 1 -25.000000000000000 1.000000000000000 0 0 Font famil&y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _family Color Bold Alt+B true Italic Alt+I true 0 0 points Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Kst::ColorButton QToolButton
colorbutton.h
Kst::LabelBuilder QWidget
labelbuilder.h
buttonBox accepted() LabelCreator accept() 248 254 157 274 buttonBox rejected() LabelCreator reject() 316 260 286 274
kst-2.0.3/src/libkstapp/powerspectrumdialog.h000644 001750 001750 00000004323 11544160207 021723 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef POWERSPECTRUMDIALOG_H #define POWERSPECTRUMDIALOG_H #include "datadialog.h" #include "datatab.h" #include "psd.h" #include "ui_powerspectrumtab.h" #include #include "kst_export.h" namespace Kst { class PowerSpectrumTab : public DataTab, Ui::PowerSpectrumTab { Q_OBJECT public: PowerSpectrumTab(QWidget *parent = 0); virtual ~PowerSpectrumTab(); void setObjectStore(ObjectStore *store); VectorPtr vector() const; bool vectorDirty() const; void setVector(const VectorPtr vector); CurveAppearance* curveAppearance() const; CurvePlacement* curvePlacement() const; FFTOptions* FFTOptionsWidget() const; void hideCurveOptions(); void clearTabValues(); private Q_SLOTS: void selectionChanged(); Q_SIGNALS: void vectorChanged(); }; class PowerSpectrumDialog : public DataDialog { Q_OBJECT public: explicit PowerSpectrumDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~PowerSpectrumDialog(); void setVector(VectorPtr vector); protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: void configureTab(ObjectPtr object=0); PowerSpectrumTab *_powerSpectrumTab; }; } #endif kst-2.0.3/src/libkstapp/generaltab.cpp000644 001750 001750 00000003056 11544160207 020265 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kst_i18n.h" #include "generaltab.h" namespace Kst { GeneralTab::GeneralTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("General")); connect(_useOpenGL, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_maxUpdate, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); } GeneralTab::~GeneralTab() { } bool GeneralTab::useOpenGL() const { return _useOpenGL->isChecked(); } void GeneralTab::setUseOpenGL(const bool useOpenGL) { _useOpenGL->setChecked(useOpenGL); } int GeneralTab::minimumUpdatePeriod() const { return _maxUpdate->value(); } void GeneralTab::setMinimumUpdatePeriod(const int period) { _maxUpdate->setValue(period); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotitem.h000644 001750 001750 00000073340 11544160207 017466 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLOTITEM_H #define PLOTITEM_H #include "viewitem.h" #include "graphicsfactory.h" #include "namedobject.h" #include #include "plotrenderitem.h" #include "plotiteminterface.h" #include "plotdefines.h" #include "plotmarkers.h" #include "namedobject.h" #include "plotaxis.h" #include "legenditem.h" #include "curveplacement.h" #include "labelrenderer.h" namespace Kst { class PlotItem; class PlotAxis; class SharedAxisBoxItem; struct ZoomState { QPointer item; QRectF projectionRect; int xAxisZoomMode; int yAxisZoomMode; bool isXAxisLog; bool isYAxisLog; }; struct CachedLabel { CachedLabel() { valid = false; dirty = true; parsed = 0; rc = 0; }; ~CachedLabel() { delete parsed; delete rc; }; bool valid; bool dirty; Label::Parsed *parsed; Label::RenderContext *rc; QTransform transform; }; struct CachedPlotLabel { CachedPlotLabel() { baseLabel = false; }; bool baseLabel; QRectF bound; QString value; }; class PlotLabel : public QObject { Q_OBJECT public: PlotLabel(PlotItem *plotItem); bool isVisible() const; void setVisible(bool visible); bool isAuto() {return _isAuto;} void setIsAuto(bool is_auto) { _isAuto = is_auto;} QString text() const; void setText(const QString &label); bool fontUseGlobal() const; void setFontUseGlobal(const bool use_global); QFont font() const; void setFont(const QFont &font); qreal fontScale() const; void setFontScale(const qreal scale); QColor fontColor() const; void setFontColor(const QColor &color); QFont calculatedFont(); void setDetails(const QString &label, bool is_auto, const bool use_global, const QFont &font, const qreal scale, const QColor &color); void saveInPlot(QXmlStreamWriter &xml, QString labelId); bool configureFromXml(QXmlStreamReader &xml, ObjectStore *store); void saveAsDialogDefaults(const QString &group) const; Q_SIGNALS: void labelChanged(); public: PlotItem* _plotItem; bool _visible; QString _text; QFont _font; qreal _fontScale; QColor _fontColor; bool _fontUseGlobal; bool _isAuto; }; class PlotItem : public ViewItem, public PlotItemInterface { Q_OBJECT public: PlotItem(View *parent); virtual ~PlotItem(); virtual QString plotName() const; //from PlotItemInterface QList renderItems() const; PlotRenderItem *renderItem(PlotRenderItem::RenderType type=PlotRenderItem::First); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); /* This is the rectangle of the PlotAxis and includes the axis labels. */ QRectF plotAxisRect(); /* This is the rectangle of the PlotRenderItem's and includes the actual curves. */ QRectF plotRect(); QRectF projectionRect() const; void setProjectionRect(const QRectF &rect, bool forceAxisUpdate = false); QRectF computedProjectionRect(); void computedRelationalMax(qreal &minimum, qreal &maximum); void computeBorder(Qt::Orientation orientation, qreal &minimum, qreal &maximum) const; PlotAxis* xAxis() { return _xAxis; } PlotAxis* yAxis() { return _yAxis; } virtual void setTiedZoom(bool tiedXZoom, bool tiedYZoom, bool checkAllTied = true); bool isInSharedAxisBox() const; void setInSharedAxisBox(bool inSharedBox); SharedAxisBoxItem* sharedAxisBox() const; void setSharedAxisBox(SharedAxisBoxItem* parent); void setPadding(const qreal, const qreal, const qreal, const qreal); void setLeftPadding(const qreal); void setBottomPadding(const qreal); void setRightPadding(const qreal); void setTopPadding(const qreal); qreal leftMarginSize() const; qreal bottomMarginSize() const; qreal rightMarginSize() const; qreal topMarginSize() const; QString leftLabel() const; QString bottomLabel() const; QString rightLabel() const; QString topLabel() const; QString autoLeftLabel() const; QString autoBottomLabel() const; QString autoRightLabel() const; QString autoTopLabel() const; // These are for explicitly hiding the axis and labels and are // not by being in a shared axis box or cleared by 'z' mode. bool manuallyHideLeftAxisLabel() const {return _manuallyHideLeftAxisLabel;} bool manuallyHideRightAxisLabel() const {return _manuallyHideRightAxisLabel;} bool manuallyHideTopAxisLabel() const {return _manuallyHideTopAxisLabel;} bool manuallyHideBottomAxisLabel() const {return _manuallyHideBottomAxisLabel;} void setManuallyHideLeftAxisLabel(bool hide); void setManuallyHideRightAxisLabel(bool hide); void setManuallyHideTopAxisLabel(bool hide); void setManuallyHideBottomAxisLabel(bool hide); PlotLabel* leftLabelDetails() const { return _leftLabelDetails; } PlotLabel* rightLabelDetails() const { return _rightLabelDetails; } PlotLabel* topLabelDetails() const { return _topLabelDetails; } PlotLabel* bottomLabelDetails() const { return _bottomLabelDetails; } PlotLabel* numberLabelDetails() const { return _numberLabelDetails; } void setTopSuppressed(bool suppressed); void setBottomSuppressed(bool suppressed); void setLeftSuppressed(bool suppressed); void setRightSuppressed(bool suppressed); void setLabelsVisible(bool visible); qreal axisMarginWidth() const; qreal axisMarginHeight() const; QString titleOverride() const; void setTitleOverride(const QString &label); QFont globalFont() const; void setGlobalFont(const QFont &font); qreal globalFontScale() const; void setGlobalFontScale(const qreal scale); QColor globalFontColor() const; void setGlobalFontColor(const QColor &color); bool showLegend() const; void setShowLegend(const bool show, const bool resetFonts = false); qreal mapXToPlot(const qreal &x); qreal mapYToPlot(const qreal &y); QPointF mapToPlot(const QPointF &point); QPointF mapToProjection(const QPointF &point); QRectF mapToProjection(const QRectF &rect); void updateScale(); qreal xMin() { return _xMin; } qreal xMax() { return _xMax; } qreal yMin() { return _yMin; } qreal yMax() { return _yMax; } void triggerUpdate() { emit geometryChanged(); update(rect()); } virtual void addToMenuForContextEvent(QMenu &menu); virtual bool tryShortcut(const QString &keySequence); virtual bool handleChangedInputs(qint64 serial); LegendItem* legend(); virtual QString descriptionTip() const; // description for tooltips ZoomState currentZoomState(); void setAllowUpdates(bool allowed); virtual void setItemPen(const QPen & pen) { ViewItem::setPen(pen); setPlotPixmapDirty();} void scaleAxisLabels(qreal scaleFactor); void resetScaleAxisLabels(); bool isUseAxisScale() const; void setUseAxisScale(bool useScale); virtual QPainterPath checkBox() const; virtual QPainterPath tiedZoomCheck() const; virtual bool supportsTiedZoom() const; void saveAsDialogDefaults() const; void applyDefaults(); bool maskedByMaximization() {return (view()->childMaximized() && !_plotMaximized);} protected: virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void updateChildGeometry(const QRectF &oldParentRect, const QRectF &newParentRect); Q_SIGNALS: void updatePlotRect(); void updateAxes(); void triggerRedraw(); void breakShareTriggered(); void shareXAxisTriggered(); void shareYAxisTriggered(); public Q_SLOTS: void zoomFixedExpression(const QRectF &projection, bool force = false); void zoomXRange(const QRectF &projection, bool force = false); void zoomYRange(const QRectF &projection, bool force = false); void zoomMaximum(bool force = false); void zoomMaxSpikeInsensitive(bool force = false); void zoomPrevious(); void adjustImageColorScale(); void zoomTied(); void zoomXTied(); void zoomYTied(); //void zoomXMeanCentered(bool force = false); void zoomXMaximum(bool force = false); void zoomXNoSpike(bool force = false); void zoomXAutoBorder(bool force = false); void zoomXRight(bool force = false); void zoomXLeft(bool force = false); void zoomXOut(bool force = false); void zoomXIn(bool force = false); void zoomNormalizeXtoY(bool force = false); void zoomLogX(bool force = false, bool autoLog = true, bool enableLog = false); void zoomMeanCentered(bool force = false); void zoomYMeanCentered(qreal dY, bool force = false); void zoomXMeanCentered(qreal dX, bool force = false); void zoomYLocalMaximum(bool force = false); void zoomYMaximum(bool force = false); void zoomYNoSpike(bool force = false); void zoomYAutoBorder(bool force = false); void zoomYUp(bool force = false); void zoomYDown(bool force = false); void zoomYOut(bool force = false); void zoomYIn(bool force = false); void zoomNormalizeYtoX(bool force = false); void zoomLogY(bool force = false, bool autoLog = true, bool enableLog = false); void setPlotBordersDirty(bool dirty = true); virtual void edit(); void plotMaximize(); void redrawPlot(); void setPlotRectsDirty(); void showFilterDialog(QAction*); void showFitDialog(QAction*); void setLeftLabelDirty() { _leftLabel.dirty = true; setPlotPixmapDirty(); } void setRightLabelDirty() { _rightLabel.dirty = true; setPlotPixmapDirty(); } void setTopLabelDirty() { _topLabel.dirty = true; setPlotPixmapDirty(); } void setBottomLabelDirty() { _bottomLabel.dirty = true; setPlotPixmapDirty(); } void setLabelsDirty() { _leftLabel.dirty = true; _rightLabel.dirty = true; _topLabel.dirty = true; _bottomLabel.dirty = true; setPlotPixmapDirty(); } void setPlotPixmapDirty(bool dirty = true) {_plotPixmapDirty = dirty; } void setAxisLabelsDirty(bool dirty = true) { _axisLabelsDirty = dirty; } private: void createActions(); void createZoomMenu(); void createFilterMenu(); void createFitMenu(); void createSharedAxisBoxMenu(); void resetSelectionRect(); void updatePlotPixmap(); virtual void paintPixmap(QPainter *painter); void updateXAxisLines(); void updateYAxisLines(); void updateXAxisLabels(QPainter* painter); void updateYAxisLabels(QPainter* painter); virtual void paintPlot(QPainter *painter, bool xUpdated, bool yUpdated); virtual void paintMajorGridLines(QPainter *painter); virtual void paintMinorGridLines(QPainter *painter); virtual void paintMajorTicks(QPainter *painter); virtual void paintMinorTicks(QPainter *painter); virtual void paintTickLabels(QPainter *painter); virtual void paintBottomTickLabels(QPainter *painter); virtual void paintLeftTickLabels(QPainter *painter); virtual void paintPlotMarkers(QPainter *painter); void calculateBorders(QPainter *painter); qreal labelMarginWidth() const; qreal labelMarginHeight() const; qreal leftLabelMargin() const; qreal rightLabelMargin() const; qreal topLabelMargin() const; qreal bottomLabelMargin() const; QRectF topLabelRect() const; QRectF bottomLabelRect() const; QRectF leftLabelRect() const; QRectF rightLabelRect() const; void calculatePlotRects(); void calculateLeftLabelMargin(QPainter *painter); void calculateBottomLabelMargin(QPainter *painter); void calculateRightLabelMargin(QPainter *painter); void calculateTopLabelMargin(QPainter *painter); void calculateMargins(); void generateLeftLabel(); void generateBottomLabel(); void generateRightLabel(); void generateTopLabel(); void paintLeftLabel(QPainter *painter); void paintBottomLabel(QPainter *painter); void paintRightLabel(QPainter *painter); void paintTopLabel(QPainter *painter); void calculateBottomTickLabelBound(QPainter *painter); void calculateLeftTickLabelBound(QPainter *painter); void setCurrentZoomState(ZoomState zoomState); void showFitFilterDialog(QAction* action, const QString& plugin); CurveList curveList() const; private: QHash _renderers; bool _isInSharedAxisBox; PlotLabel* _leftLabelDetails; PlotLabel* _rightLabelDetails; PlotLabel* _topLabelDetails; PlotLabel* _bottomLabelDetails; PlotLabel* _numberLabelDetails; bool _manuallyHideLeftAxisLabel; bool _manuallyHideRightAxisLabel; bool _manuallyHideTopAxisLabel; bool _manuallyHideBottomAxisLabel; bool _plotRectsDirty; QRectF _calculatedPlotRect; QRectF _calculatedPlotAxisRect; qreal _calculatedLeftLabelMargin; qreal _calculatedLeftLabelWidth; qreal _calculatedLeftBaseOffset; qreal _calculatedRightLabelMargin; qreal _calculatedTopLabelMargin; qreal _calculatedTopLabelHeight; qreal _calculatedBottomLabelMargin; qreal _calculatedBottomLabelWidth; qreal _calculatedLabelMarginWidth; qreal _calculatedLabelMarginHeight; qreal _calculatedAxisMarginWidth; qreal _calculatedAxisMarginHeight; qreal _calculatedAxisMarginVLead; qreal _calculatedAxisMarginHLead; qreal _calculatedAxisMarginROverflow; qreal _calculatedAxisMarginTOverflow; qreal _leftPadding; qreal _bottomPadding; qreal _rightPadding; qreal _topPadding; PlotAxis *_xAxis; PlotAxis *_yAxis; QRectF _projectionRect; qreal _xMax; qreal _xMin; qreal _yMax; qreal _yMin; QFont _globalFont; qreal _globalFontScale; QColor _globalFontColor; qreal _numberAxisLabelScaleFactor; bool _useNumberAxisLabelScale; bool _showLegend; QPointF _plotMaximizedSourcePosition; QRectF _plotMaximizedSourceRect; QRectF _plotMaximizedSourceParentRect; qreal _plotMaximizedSourceZValue; ViewItem* _plotMaximizedSourceParent; bool _plotMaximizedBottomVisible; bool _plotMaximizedTopVisible; bool _plotMaximizedLeftVisible; bool _plotMaximizedRightVisible; bool _allowUpdates; LegendItem* _legend; QMenu *_zoomMenu; QAction *_zoomMaximum; QAction *_zoomMaxSpikeInsensitive; QAction *_zoomPrevious; QAction *_zoomTied; QAction *_zoomXTied; QAction *_zoomYTied; QAction *_zoomMeanCentered; QAction *_zoomXMaximum; QAction *_zoomXAutoBorder; QAction *_zoomXNoSpike; QAction *_zoomXRight; QAction *_zoomXLeft; QAction *_zoomXOut; QAction *_zoomXIn; QAction *_zoomNormalizeXtoY; QAction *_zoomLogX; QAction *_zoomYLocalMaximum; QAction *_zoomYMaximum; QAction *_zoomYAutoBorder; QAction *_zoomYNoSpike; QAction *_zoomYUp; QAction *_zoomYDown; QAction *_zoomYOut; QAction *_zoomYIn; QAction *_zoomNormalizeYtoX; QAction *_zoomLogY; QAction *_plotMaximize; QAction *_adjustImageColorscale; QMenu *_filterMenu; QAction *_filterAction; QMenu *_fitMenu; QAction *_fitAction; QMenu *_sharedAxisBoxMenu; QAction *_shareBoxShareX; QAction *_shareBoxShareY; QAction *_breakSharedBox; SharedAxisBoxItem * _sharedBox; bool _axisLabelsDirty; CachedLabel _leftLabel; CachedLabel _rightLabel; CachedLabel _topLabel; CachedLabel _bottomLabel; QVector _xMajorGridLines; QVector _yMajorGridLines; QVector _xMinorGridLines; QVector _yMinorGridLines; QVector _xMajorTickLines; QVector _yMajorTickLines; QVector _xMinorTickLines; QVector _yMinorTickLines; QVector _xPlotMarkerLines; QVector _yPlotMarkerLines; QVector _xPlotLabels; QVector _yPlotLabels; bool _plotPixmapDirty; QPixmap _plotPixmap; QUndoStack *_undoStack; int _i_per; // index for image smart ranges friend class ZoomCommand; friend class ZoomMaximumCommand; friend class ZoomGeneralCommand; friend class ZoomMaxSpikeInsensitiveCommand; friend class ZoomMeanCenteredCommand; friend class ZoomXMeanCenteredCommand; friend class ZoomYMeanCenteredCommand; friend class ZoomXMaximumCommand; friend class ZoomYLocalMaximumCommand; friend class ZoomYMaximumCommand; friend class ViewGridLayout; }; class CreatePlotCommand : public CreateCommand { public: CreatePlotCommand() : CreateCommand(QObject::tr("Create Plot")) {} CreatePlotCommand(View *view) : CreateCommand(view, QObject::tr("Create Plot")) {} virtual ~CreatePlotCommand() {} virtual void createItem(); }; class CreatePlotForCurve : public CreateCommand { public: CreatePlotForCurve() : CreateCommand(QObject::tr("Create Plot For Curve")) {} CreatePlotForCurve(View *view) : CreateCommand(view, QObject::tr("Create Plot For Curve")) {} virtual ~CreatePlotForCurve() {} virtual void createItem(); }; class PlotItemFactory : public GraphicsFactory { public: PlotItemFactory(); ~PlotItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; class ZoomCommand : public ViewItemCommand { public: ZoomCommand(PlotItem *item, const QString &text, bool forced = false); virtual ~ZoomCommand(); virtual void undo(); virtual void redo(); virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true) = 0; virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true) = 0; private: QList _originalStates; QList _viewItems; QList _sharedPlotItems; PlotItem* _plotItem; }; class ZoomFixedExpressionCommand : public ZoomCommand { public: ZoomFixedExpressionCommand(PlotItem *item, const QRectF &fixed, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Fixed Expression"), forced), _fixed(fixed) {} virtual ~ZoomFixedExpressionCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); private: QRectF _fixed; }; class ZoomXRangeCommand : public ZoomCommand { public: ZoomXRangeCommand(PlotItem *item, const QRectF &fixed, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X Range Expression"), forced), _fixed(fixed) {} virtual ~ZoomXRangeCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); private: QRectF _fixed; }; class ZoomYRangeCommand : public ZoomCommand { public: ZoomYRangeCommand(PlotItem *item, const QRectF &fixed, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X Range Expression"), forced), _fixed(fixed) {} virtual ~ZoomYRangeCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); private: QRectF _fixed; }; class ZoomMaximumCommand : public ZoomCommand { public: explicit ZoomMaximumCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Maximum"), forced) {} virtual ~ZoomMaximumCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomMaxSpikeInsensitiveCommand : public ZoomCommand { public: explicit ZoomMaxSpikeInsensitiveCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Max Spike Insensitive"), forced) {} virtual ~ZoomMaxSpikeInsensitiveCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomMeanCenteredCommand : public ZoomCommand { public: explicit ZoomMeanCenteredCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Mean Centered"), forced) {} virtual ~ZoomMeanCenteredCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomXMeanCenteredCommand : public ZoomCommand { public: explicit ZoomXMeanCenteredCommand(PlotItem *item, qreal dX, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X Mean Centered"), forced), _dX(dX) {} virtual ~ZoomXMeanCenteredCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); private: qreal _dX; }; class ZoomYMeanCenteredCommand : public ZoomCommand { public: explicit ZoomYMeanCenteredCommand(PlotItem *item, qreal dY, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y Mean Centered"), forced), _dY(dY) {} virtual ~ZoomYMeanCenteredCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); private: qreal _dY; }; class ZoomXMaximumCommand : public ZoomCommand { public: explicit ZoomXMaximumCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X Maximum"), forced) {} virtual ~ZoomXMaximumCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomXAutoBorderCommand : public ZoomCommand { public: explicit ZoomXAutoBorderCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X Auto Border"), forced) {} virtual ~ZoomXAutoBorderCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomXNoSpikeCommand : public ZoomCommand { public: explicit ZoomXNoSpikeCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X No Spike"), forced) {} virtual ~ZoomXNoSpikeCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomXRightCommand : public ZoomCommand { public: explicit ZoomXRightCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Scroll X Right"), forced) {} virtual ~ZoomXRightCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomXLeftCommand : public ZoomCommand { public: explicit ZoomXLeftCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Scroll X Left"), forced) {} virtual ~ZoomXLeftCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomXOutCommand : public ZoomCommand { public: explicit ZoomXOutCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X Out"), forced) {} virtual ~ZoomXOutCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomXInCommand : public ZoomCommand { public: explicit ZoomXInCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X In"), forced) {} virtual ~ZoomXInCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomNormalizeXToYCommand : public ZoomCommand { public: explicit ZoomNormalizeXToYCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Normalize X to Y"), forced) {} virtual ~ZoomNormalizeXToYCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomYLocalMaximumCommand : public ZoomCommand { public: explicit ZoomYLocalMaximumCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y Local Maximum"), forced) {} virtual ~ZoomYLocalMaximumCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomYMaximumCommand : public ZoomCommand { public: explicit ZoomYMaximumCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y Maximum"), forced) {} virtual ~ZoomYMaximumCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomYAutoBorderCommand : public ZoomCommand { public: explicit ZoomYAutoBorderCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y Auto Border"), forced) {} virtual ~ZoomYAutoBorderCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomYNoSpikeCommand : public ZoomCommand { public: explicit ZoomYNoSpikeCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y No Spike"), forced) {} virtual ~ZoomYNoSpikeCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomYUpCommand : public ZoomCommand { public: explicit ZoomYUpCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y Up"), forced) {} virtual ~ZoomYUpCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomYDownCommand : public ZoomCommand { public: explicit ZoomYDownCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y Down"), forced) {} virtual ~ZoomYDownCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomYOutCommand : public ZoomCommand { public: explicit ZoomYOutCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y Out"), forced) {} virtual ~ZoomYOutCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomYInCommand : public ZoomCommand { public: explicit ZoomYInCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y In"), forced) {} virtual ~ZoomYInCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomNormalizeYToXCommand : public ZoomCommand { public: explicit ZoomNormalizeYToXCommand(PlotItem *item, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Normalize Y to X"), forced) {} virtual ~ZoomNormalizeYToXCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); }; class ZoomXLogCommand : public ZoomCommand { public: explicit ZoomXLogCommand(PlotItem *item, bool enableLog, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom X Log"), forced), _enableLog(enableLog) {} virtual ~ZoomXLogCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); private: bool _enableLog; }; class ZoomYLogCommand : public ZoomCommand { public: explicit ZoomYLogCommand(PlotItem *item, bool enableLog, bool forced = false) : ZoomCommand(item, QObject::tr("Zoom Y Log"), forced), _enableLog(enableLog) {} virtual ~ZoomYLogCommand() {} virtual void applyZoomTo(PlotItem *item, bool applyX = true, bool applyY = true); virtual void applyZoomTo(ViewItem *item, bool applyX = true, bool applyY = true); private: bool _enableLog; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewvectordialog.ui000644 001750 001750 00000003656 11544160207 021377 0ustar00synthsynth000000 000000 ViewVectorDialog 0 0 528 536 View Vector Values 0 0 Qt::Horizontal QDialogButtonBox::Close Kst::VectorSelector QWidget
vectorselector.h
buttonBox accepted() ViewVectorDialog accept() 263 513 263 267 buttonBox rejected() ViewVectorDialog reject() 263 513 263 267
kst-2.0.3/src/libkstapp/databutton.cpp000644 001750 001750 00000003307 11544160207 020325 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "databutton.h" #include #include namespace Kst { DataButton::DataButton(const QString &text, QWidget *parent) : QPushButton(text, parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); setStyleSheet("QPushButton {" "border: 0px solid;" "background-color: white;" "margin: 5;" "}" "QPushButton:hover {" "border-bottom: 1px solid;" "border-right: 1px solid;" "}" "QPushButton:pressed {" "border-bottom: 0px solid;" "border-right: 0px solid;" "border-top: 1px solid;" "border-left: 1px solid;" "}" ); } DataButton::~DataButton() { } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/application.h000644 001750 001750 00000002450 11544160207 020126 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef APPLICATION_H #define APPLICATION_H #include #include #include "mainwindow.h" #define kstApp \ (static_cast(QCoreApplication::instance())) namespace Kst { class Application : public QApplication { Q_OBJECT public: Application(int &argc, char **argv); virtual ~Application(); MainWindow *mainWindow() const; private: QPointer _mainWindow; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/logwidget.h000644 001750 001750 00000002572 11544160207 017615 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LOGWIDGET_H #define LOGWIDGET_H #include #include "debug.h" #include "kst_export.h" namespace Kst { class LogWidget : public QTextBrowser { Q_OBJECT public: LogWidget(QWidget *parent); virtual ~LogWidget(); public Q_SLOTS: void logAdded(const Debug::LogMessage&); void setShowDebug(bool show); void setShowNotice(bool show); void setShowWarning(bool show); void setShowError(bool show); private slots: void regenerate(); private: int _show; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/graphicsfactory.h000644 001750 001750 00000003130 11544160207 021007 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GRAPHICSFACTORY_H #define GRAPHICSFACTORY_H #include #include #include "dataobject.h" #include "kst_export.h" #include "view.h" namespace Kst { class ViewItem; class ObjectStore; class GraphicsFactory { public: GraphicsFactory(); virtual ~GraphicsFactory(); // This takes ownership static void registerFactory(const QString& node, GraphicsFactory *factory); static void registerFactory(const QStringList& nodes, GraphicsFactory *factory); static ViewItem *parse(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); virtual ViewItem *generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0) = 0; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/childviewoptionstab.h000644 001750 001750 00000002412 11544160207 021702 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CHILDVIEWOPTIONSTAB_H #define CHILDVIEWOPTIONSTAB_H #include "dialogtab.h" #include "ui_childviewoptionstab.h" #include "kst_export.h" namespace Kst { class ChildViewOptionsTab : public DialogTab, Ui_ChildViewOptionsTab { Q_OBJECT public: ChildViewOptionsTab(QWidget *parent = 0); virtual ~ChildViewOptionsTab(); bool shareAxis() const; void setShareAxis(bool shareAxis); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/generaltab.ui000644 001750 001750 00000005061 11544160207 020116 0ustar00synthsynth000000 000000 GeneralTab 0 0 587 246 Form &Period between updates (ms): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _maxUpdate 0 0 Dynamic files update this fast,. or slower. Minimum time between updates when looking at dynamic files. If there is a lot of processing, it might take longer. 10 60000 500 2000 Qt::Vertical 44 16 Render using openGL. This is not always better. Rendering using OpenGL is faster on some architectures, but very buggy on others (depending on the video driver). This might help, or might cause things to go horribly wrong. Use Open&GL kst-2.0.3/src/libkstapp/contenttab.ui000644 001750 001750 00000023725 11544160207 020162 0ustar00synthsynth000000 000000 ContentTab 0 0 726 510 0 0 0 &Available objects: false _availableRelationList QAbstractItemView::ExtendedSelection Deselect All Select All Edit Qt::Vertical QSizePolicy::Expanding 31 50 0 false 0 0 Raise in plot order: Alt+up Alt+Up false 0 0 Lower in plot order: Alt+down Alt+Down false 0 0 Select: Alt+s Alt+S false 0 0 Remove: Alt+r Alt+R Qt::Vertical QSizePolicy::Expanding 31 110 0 0 &Displayed objects: false _displayedRelationList QAbstractItemView::ExtendedSelection Deselect All buttonGroup Select All buttonGroup Edit buttonGroup Qt::Horizontal _displayedRelationList _availableRelationList _down _add _remove _up _deselectAllAvailable clicked() _availableRelationList clearSelection() 74 481 76 405 _selectAllAvailable clicked() _availableRelationList selectAll() 177 482 177 433 _deselectAllDisplayed clicked() _displayedRelationList clearSelection() 517 487 518 436 _selectAllDisplayed clicked() _displayedRelationList selectAll() 592 480 591 447 kst-2.0.3/src/libkstapp/scalardialog.cpp000644 001750 001750 00000030032 11544160207 020600 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasourcedialog.h" #include "scalardialog.h" #include "enodes.h" #include "document.h" #include "objectstore.h" #include "datascalar.h" #include "vscalar.h" #include "dialogdefaults.h" #include "datasourcepluginmanager.h" #include #include namespace Kst { ScalarTab::ScalarTab(ObjectStore *store, QWidget *parent) : DataTab(parent), _mode(DataScalar), _store(store), _requestID(0) { setupUi(this); setTabTitle(tr("Scalar")); setDataOptions(); connect(_scalarValue, SIGNAL(textChanged(const QString&)), this, SLOT(entryChanged())); connect(_start, SIGNAL(textChanged(const QString&)), this, SLOT(entryChanged())); connect(_field, SIGNAL(editTextChanged(const QString&)), this, SLOT(entryChanged())); connect(_fieldRV, SIGNAL(editTextChanged(const QString&)), this, SLOT(entryChanged())); connect(_readFromSource, SIGNAL(toggled(bool)), this, SLOT(readFromSourceChanged())); connect(_readFromRVector, SIGNAL(toggled(bool)), this, SLOT(readFromSourceChanged())); connect(_fileName, SIGNAL(changed(const QString &)), this, SLOT(fileNameChanged(const QString &))); connect(_configure, SIGNAL(clicked()), this, SLOT(showConfigWidget())); } ScalarTab::~ScalarTab() { } QString ScalarTab::value() const { return _scalarValue->text(); } void ScalarTab::setValue(const QString &value) { _scalarValue->setText(value); } void ScalarTab::entryChanged() { emit valueChanged(); } void ScalarTab::readFromSourceChanged() { if (_readFromSource->isChecked()) { _mode = DataScalar; setDataOptions(); } else if (_readFromRVector->isChecked()) { _mode = RVectorScalar; setRVOptions(); } else { _mode = GeneratedScalar; } _dataScalarGroup->setEnabled((_readFromSource->isChecked())||(_readFromRVector->isChecked())); bool isRV = _readFromRVector->isChecked(); label_6->setEnabled(isRV); label_7->setEnabled(isRV); _start->setEnabled(isRV); _countFromEnd->setEnabled(isRV); _generatedScalarGroup->setEnabled(_generateX->isChecked()); emit sourceChanged(); } void ScalarTab::hideGeneratedOptions() { _readFromSource->setVisible(false); _generateX->setVisible(false); _readFromRVector->setVisible(false); _generatedScalarGroup->setVisible(false); } void ScalarTab::hideDataOptions() { _readFromSource->setVisible(false); _generateX->setVisible(false); _readFromRVector->setVisible(false); _dataScalarGroup->setVisible(false); _generatedScalarGroup->setEnabled(true); } void ScalarTab::setRVOptions() { // replace in right order to avoid flicker _field->setVisible(false); label_5->setVisible(false); _fieldRV->setVisible(true); label_8->setVisible(true); _readFromRVector->setChecked(true); } void ScalarTab::setDataOptions() { _fieldRV->setVisible(false); label_8->setVisible(false); _field->setVisible(true); label_5->setVisible(true); _readFromSource->setChecked(true); } DataSourcePtr ScalarTab::dataSource() const { return _dataSource; } void ScalarTab::setDataSource(DataSourcePtr dataSource) { _dataSource = dataSource; } QString ScalarTab::file() const { return _fileName->file(); } void ScalarTab::setFile(const QString &file) { _fileName->setFile(file); } QString ScalarTab::field() const { return _field->currentText(); } void ScalarTab::setField(const QString &field) { _field->setCurrentIndex(_field->findText(field)); } QString ScalarTab::fieldRV() const { return _fieldRV->currentText(); } void ScalarTab::setFieldRV(const QString &field) { _fieldRV->setCurrentIndex(_fieldRV->findText(field)); } void ScalarTab::setF0(int f0) { _start->setText(QString::number(f0)); } int ScalarTab::F0() const { return _start->text().toInt(); } void ScalarTab::updateDataSource() { fileNameChanged(_fileName->file()); } void ScalarTab::sourceValid(QString filename, int requestID) { if (_requestID != requestID) { return; } _dataSource = DataSourcePluginManager::findOrLoadSource(_store, filename); _field->setEnabled(true); _fieldRV->setEnabled(true); _dataSource->readLock(); _field->addItems(_dataSource->scalar().list()); _field->setEditable(!_dataSource->scalar().isListComplete()); _fieldRV->addItems(_dataSource->vector().list()); _fieldRV->setEditable(!_dataSource->vector().isListComplete()); _configure->setEnabled(_dataSource->hasConfigWidget()); _dataSource->unlock(); modified(); emit sourceChanged(); } void ScalarTab::fileNameChanged(const QString &file) { _field->clear(); _fieldRV->clear(); _field->setEnabled(false); _fieldRV->setEnabled(false); _configure->setEnabled(false); emit sourceChanged(); _requestID += 1; ValidateDataSourceThread *validateDSThread = new ValidateDataSourceThread(file, _requestID); connect(validateDSThread, SIGNAL(dataSourceValid(QString, int)), this, SLOT(sourceValid(QString, int))); QThreadPool::globalInstance()->start(validateDSThread); } void ScalarTab::showConfigWidget() { QPointer dialog = new DataSourceDialog(dataDialog()->editMode(), _dataSource, this); if ( dialog->exec() == QDialog::Accepted ) { fileNameChanged(_dataSource->fileName()); } delete dialog; } ScalarDialog::ScalarDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Scalar")); else setWindowTitle(tr("New Scalar")); _scalarTab = new ScalarTab(_document->objectStore(), this); addDataTab(_scalarTab); if (editMode() == Edit) { configureTab(dataObject); } else { configureTab(0); } connect(_scalarTab, SIGNAL(valueChanged()), this, SLOT(updateButtons())); connect(_scalarTab, SIGNAL(valueChanged()), this, SLOT(modified())); updateButtons(); } ScalarDialog::~ScalarDialog() { } void ScalarDialog::configureTab(ObjectPtr object) { if (DataScalarPtr dataScalar = kst_cast(object)) { _scalarTab->setFile(dataScalar->dataSource()->fileName()); _scalarTab->setDataSource(dataScalar->dataSource()); _scalarTab->setField(dataScalar->field()); _scalarTab->hideGeneratedOptions(); _scalarTab->setDataOptions(); } else if (VScalarPtr vScalar = kst_cast(object)) { _scalarTab->setFile(vScalar->dataSource()->fileName()); _scalarTab->setDataSource(vScalar->dataSource()); _scalarTab->setFieldRV(vScalar->field()); _scalarTab->setF0(vScalar->F0()); _scalarTab->hideGeneratedOptions(); _scalarTab->setRVOptions(); } else if (ScalarPtr scalar = kst_cast(object)) { // edit value scalar _scalarTab->hideDataOptions(); _scalarTab->setValue(QString::number(scalar->value())); } else { // new scalar _scalarTab->setFile(_dialogDefaults->value("vector/datasource",_scalarTab->file()).toString()); } } void ScalarDialog::updateButtons() { bool valid=false; switch(_scalarTab->scalarMode()) { case ScalarTab::DataScalar: valid = !_scalarTab->field().isEmpty(); break; case ScalarTab::RVectorScalar: valid = !_scalarTab->fieldRV().isEmpty(); break; case ScalarTab::GeneratedScalar: valid = !_scalarTab->value().isEmpty(); break; default: valid = false; } _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid); //_buttonBox->button(QDialogButtonBox::Apply)->setEnabled(valid); } ObjectPtr ScalarDialog::createNewDataObject() { switch(_scalarTab->scalarMode()) { case ScalarTab::DataScalar: return createNewDataScalar(); case ScalarTab::RVectorScalar: return createNewVScalar(); case ScalarTab::GeneratedScalar: return createNewGeneratedScalar(); default: return 0; } } ObjectPtr ScalarDialog::createNewGeneratedScalar(){ bool ok = false; Q_ASSERT(_document && _document->objectStore()); double value = _scalarTab->value().toDouble(&ok); if (!ok) { value = Equations::interpret(_document->objectStore(), _scalarTab->value().toLatin1(), &ok); } if (!ok) { return 0; //invalid } ScalarPtr scalar = _document->objectStore()->createObject(); scalar->setValue(value); scalar->setOrphan(true); scalar->setEditable(true); if (DataDialog::tagStringAuto()) { scalar->setDescriptiveName(QString()); } else { scalar->setDescriptiveName(DataDialog::tagString()); } scalar->writeLock(); scalar->registerChange(); scalar->unlock(); _dataObjectName = scalar->Name(); return static_cast(scalar); } ObjectPtr ScalarDialog::createNewDataScalar() { const DataSourcePtr dataSource = _scalarTab->dataSource(); if (!dataSource) return 0; const QString field = _scalarTab->field(); Q_ASSERT(_document && _document->objectStore()); DataScalarPtr scalar = _document->objectStore()->createObject(); scalar->writeLock(); scalar->change(dataSource, field); if (DataDialog::tagStringAuto()) { scalar->setDescriptiveName(QString()); } else { scalar->setDescriptiveName(DataDialog::tagString()); } scalar->registerChange(); scalar->unlock(); _dataObjectName = scalar->Name(); return scalar; } ObjectPtr ScalarDialog::createNewVScalar() { const DataSourcePtr dataSource = _scalarTab->dataSource(); if (!dataSource) return 0; const QString field = _scalarTab->fieldRV(); const int f0 = _scalarTab->F0(); Q_ASSERT(_document && _document->objectStore()); VScalarPtr scalar = _document->objectStore()->createObject(); scalar->writeLock(); scalar->change(dataSource, field, f0); if (DataDialog::tagStringAuto()) { scalar->setDescriptiveName(QString()); } else { scalar->setDescriptiveName(DataDialog::tagString()); } scalar->registerChange(); scalar->unlock(); _dataObjectName = scalar->Name(); return scalar; } ObjectPtr ScalarDialog::editExistingDataObject() const { if (DataScalarPtr scalar = kst_cast(dataObject())) { const DataSourcePtr dataSource = _scalarTab->dataSource(); if (dataSource) { const QString field = _scalarTab->field(); scalar->writeLock(); scalar->change(dataSource, field); if (DataDialog::tagStringAuto()) { scalar->setDescriptiveName(QString()); } else { scalar->setDescriptiveName(DataDialog::tagString()); } scalar->registerChange(); scalar->unlock(); } } else if (VScalarPtr scalar = kst_cast(dataObject())) { const DataSourcePtr dataSource = _scalarTab->dataSource(); if (dataSource) { const QString field = _scalarTab->fieldRV(); int f0 = _scalarTab->F0();; scalar->writeLock(); scalar->change(dataSource, field, f0); if (DataDialog::tagStringAuto()) { scalar->setDescriptiveName(QString()); } else { scalar->setDescriptiveName(DataDialog::tagString()); } scalar->registerChange(); scalar->unlock(); } } else if (ScalarPtr scalar = kst_cast(dataObject())) { bool ok; double value = _scalarTab->value().toDouble(&ok); if (!ok) { value = Equations::interpret(_document->objectStore(), _scalarTab->value().toLatin1(), &ok); } if (DataDialog::tagStringAuto()) { scalar->setDescriptiveName(QString()); } else { scalar->setDescriptiveName(DataDialog::tagString()); } scalar->writeLock(); scalar->setValue(value); scalar->registerChange(); scalar->unlock(); } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/curvedialog.h000644 001750 001750 00000005567 11544160207 020143 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CURVEDIALOG_H #define CURVEDIALOG_H #include "datadialog.h" #include "datatab.h" #include "ui_curvetab.h" #include #include "kst_export.h" namespace Kst { class CurveTab : public DataTab, Ui::CurveTab { Q_OBJECT public: CurveTab(QWidget *parent = 0); virtual ~CurveTab(); VectorPtr xVector() const; bool xVectorDirty() const; void setXVector(VectorPtr vector); VectorPtr yVector() const; bool yVectorDirty() const; void setYVector(VectorPtr vector); VectorPtr xError() const; bool xErrorDirty() const; void setXError(VectorPtr vector); VectorPtr yError() const; bool yErrorDirty() const; void setYError(VectorPtr vector); VectorPtr xMinusError() const; bool xMinusErrorDirty() const; void setXMinusError(VectorPtr vector); VectorPtr yMinusError() const; bool yMinusErrorDirty() const; void setYMinusError(VectorPtr vector); CurveAppearance* curveAppearance() const; CurvePlacement* curvePlacement() const; bool ignoreAutoScale() const; bool ignoreAutoScaleDirty() const; void setIgnoreAutoScale(bool ignoreAutoScale); void setObjectStore(ObjectStore *store); void hidePlacementOptions(); void clearTabValues(); void setToLastX() {_xVector->setToLastX();} Q_SIGNALS: void vectorsChanged(); public Q_SLOTS: void xCheckboxClicked(); void yCheckboxClicked(); void xErrorChanged(); void yErrorChanged(); void updateVectorCombos(); }; class CurveDialog : public DataDialog { Q_OBJECT public: explicit CurveDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~CurveDialog(); void setVector(VectorPtr vector); protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: void configureTab(ObjectPtr curve=0); CurveTab *_curveTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/histogramdialog.h000644 001750 001750 00000005646 11544160207 021012 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef HISTOGRAMDIALOG_H #define HISTOGRAMDIALOG_H #include "datadialog.h" #include "datatab.h" #include "histogram.h" #include "ui_histogramtab.h" #include #include "kst_export.h" #ifdef min #undef min #endif #ifdef max #undef max #endif namespace Kst { class HistogramTab : public DataTab, Ui::HistogramTab { Q_OBJECT public: HistogramTab(QWidget *parent = 0); virtual ~HistogramTab(); void setObjectStore(ObjectStore *store); VectorPtr vector() const; bool vectorDirty() const; void setVector(VectorPtr vector); double min() const; bool minDirty() const; void setMin(const double min); double max() const; bool maxDirty() const; void setMax(const double max); int bins() const; bool binsDirty() const; void setBins(const int bins); bool realTimeAutoBin() const; bool realTimeAutoBinDirty() const; void setRealTimeAutoBin(const bool autoBin); Histogram::NormalizationType normalizationType() const; bool normalizationTypeDirty() const; void setNormalizationType(const Histogram::NormalizationType normalizationType); CurveAppearance* curveAppearance() const; CurvePlacement* curvePlacement() const; void hideCurveOptions(); void clearTabValues(); void resetNormalizationDirty(); private Q_SLOTS: void generateAutoBin(); void updateButtons(); void selectionChanged(); void normalizationChanged(); Q_SIGNALS: void vectorChanged(); private: bool _normalizationDirty; }; class HistogramDialog : public DataDialog { Q_OBJECT public: explicit HistogramDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~HistogramDialog(); void setVector(VectorPtr vector); protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: void configureTab(ObjectPtr object=0); HistogramTab *_histogramTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/matrixmodel.cpp000644 001750 001750 00000006154 11544160207 020510 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "matrixmodel.h" #include #include namespace Kst { MatrixModel::MatrixModel(MatrixPtr m) : QAbstractItemModel(), _m(m) { assert(m.data()); } MatrixModel::~MatrixModel() { } int MatrixModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return _m->xNumSteps(); } int MatrixModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent) return _m->yNumSteps(); } QVariant MatrixModel::data(const QModelIndex& index, int role) const { Q_UNUSED(role) QVariant rc; if (index.isValid()) { switch (role) { case Qt::DisplayRole: rc = QVariant(_m->value(index.column(), index.row())); break; case Qt::FontRole: { if (_m->editable()) { QFont f; f.setBold(true); rc = f; } } break; default: break; } } return rc; } QModelIndex MatrixModel::index(int row, int col, const QModelIndex& parent) const { Q_UNUSED(parent) if (row >= 0 && row < _m->yNumSteps() && col >= 0 && col < _m->xNumSteps()) { return createIndex(row, col); } return QModelIndex(); } QModelIndex MatrixModel::parent(const QModelIndex& index) const { Q_UNUSED(index) return QModelIndex(); } QVariant MatrixModel::headerData(int section, Qt::Orientation orientation, int role) const { return QAbstractItemModel::headerData(section, orientation, role); } Qt::ItemFlags MatrixModel::flags(const QModelIndex& index) const { Qt::ItemFlags f = QAbstractItemModel::flags(index); if (!index.isValid()) { return f; } if (_m->editable() && index.row() >= 0 && index.row() < _m->yNumSteps() && index.column() >= 0 && index.column() < _m->xNumSteps()) { f |= Qt::ItemIsEditable; } return f; } bool MatrixModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (role != Qt::EditRole) { return QAbstractItemModel::setData(index, value, role); } if (!index.isValid() || !_m->editable() || index.row() < 0 || index.row() >= _m->yNumSteps() || index.column() < 0 || index.column() >= _m->xNumSteps()) { return false; } bool ok = false; double v = value.toDouble(&ok); if (!ok) { return false; } return _m->setValue(index.column(), index.row(), v); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/imagedialog.h000644 001750 001750 00000007045 11544160207 020072 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef IMAGEDIALOG_H #define IMAGEDIALOG_H #include "datadialog.h" #include "datatab.h" #include "image.h" #include "ui_imagetab.h" #include #include "kst_export.h" namespace Kst { class ObjectStore; class ImageTab : public DataTab, Ui::ImageTab { Q_OBJECT public: ImageTab(QWidget *parent = 0); virtual ~ImageTab(); CurvePlacement* curvePlacement() const; ColorPalette* colorPalette() const; void setObjectStore(ObjectStore *store); bool realTimeAutoThreshold() const; bool realTimeAutoThresholdDirty() const; void setRealTimeAutoThreshold(const bool realTimeAutoThreshold); bool colorOnly() const; void setColorOnly(const bool colorOnly); bool contourOnly() const; void setContourOnly(const bool contourOnly); bool colorAndContour() const; void setColorAndContour(const bool colorAndContour); bool modeDirty() const; double lowerThreshold() const; bool lowerThresholdDirty() const; void setLowerThreshold(const double lowerThreshold); double upperThreshold() const; bool upperThresholdDirty() const; void setUpperThreshold(const double upperThreshold); int numberOfContourLines() const; bool numberOfContourLinesDirty() const; void setNumberOfContourLines(const int numberOfContourLines); int contourWeight() const; bool contourWeightDirty() const; void setContourWeight(const int contourWeight); QColor contourColor() const; bool contourColorDirty() const; void setContourColor(const QColor contourColor); MatrixPtr matrix() const; bool matrixDirty() const; void setMatrix(const MatrixPtr matrix); bool useVariableLineWeight() const; bool useVariableLineWeightDirty() const; void setUseVariableLineWeight(const bool useVariableLineWeight); void hidePlacementOptions(); void clearTabValues(); void resetModeDirty(); private Q_SLOTS: void realTimeAutoThresholdToggled(const bool checked); void updateEnabled(const bool checked); void selectionChanged(); void calculateAutoThreshold(); void calculateSmartThreshold(); void modeChanged(); Q_SIGNALS: void optionsChanged(); private: ObjectStore* _store; bool _modeDirty; }; class ImageDialog : public DataDialog { Q_OBJECT public: explicit ImageDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~ImageDialog(); void setMatrix(MatrixPtr matrix); protected: virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: void configureTab(ObjectPtr object); ImageTab *_imageTab; }; } #endif kst-2.0.3/src/libkstapp/differentiatecurvesdialog.h000644 001750 001750 00000003027 11544160207 023045 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIFFERENTIATECURVESDIALOG_H #define DIFFERENTIATECURVESDIALOG_H #include #include "ui_differentiatecurvesdialog.h" #include "kst_export.h" namespace Kst { class ObjectStore; class DifferentiateCurvesDialog : public QDialog, Ui::DifferentiateCurvesDialog { Q_OBJECT public: DifferentiateCurvesDialog(QWidget *parent); virtual ~DifferentiateCurvesDialog(); void show(); private slots: void updateButtons(); void addButtonClicked(); void removeButtonClicked(); void upButtonClicked(); void downButtonClicked(); void OKClicked(); void apply(); private: void resetLists(); ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/changefiledialog.ui000644 001750 001750 00000026503 11544160207 021263 0ustar00synthsynth000000 000000 ChangeFileDialog 0 0 603 452 Change Data File Select by Source File false Add All &From: false 0 0 Vector and Matrix Selection 1 0 The source file for the vectors selected in this list will be changed. QAbstractItemView::ExtendedSelection Qt::Vertical 20 40 Select all vectors in the list. Add A&ll Select all vectors in the list. &Add Unselect all vectors in the list. &Remove Unselect all vectors in the list. R&emove All Qt::Vertical QSizePolicy::Expanding 80 51 1 0 The source file for the vectors selected in this list will be changed. QAbstractItemView::ExtendedSelection New Data File 0 0 0 0 &File: false _dataFile 0 0 C&hange selected vectors and matrices true Qt::Vertical QSizePolicy::Expanding 16 20 0 Qt::Vertical QSizePolicy::Expanding 16 20 false D&uplicate derived objects (curves, equations, ...) true &Duplicate selected vectors and matrices Qt::Horizontal 40 20 10 0 Unknown File Type false false 0 0 Con&figure... Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok Kst::ComboBox QComboBox
combobox.h
Kst::DataSourceSelector QWidget
datasourceselector.h
_changeFilePrimitiveList _removeAll _addAll _dataFile _changeSelected _duplicateSelected _duplicateDependents
kst-2.0.3/src/libkstapp/matrixmodel.h000644 001750 001750 00000003273 11544160207 020154 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MATRIXMODEL_H #define MATRIXMODEL_H #include #include namespace Kst { class MatrixModel : public QAbstractItemModel { public: MatrixModel(MatrixPtr v); ~MatrixModel(); int columnCount(const QModelIndex& parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; QModelIndex index(int row, int col, const QModelIndex& parent = QModelIndex()) const; QModelIndex parent(const QModelIndex& index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; Qt::ItemFlags flags(const QModelIndex& index) const; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); private: MatrixPtr _m; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewdialog.h000644 001750 001750 00000003015 11544160207 017753 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEWDIALOG_H #define VIEWDIALOG_H #include "dialog.h" #include #include "kst_export.h" namespace Kst { class View; class FillTab; class GridTab; class ChildViewOptionsTab; class ViewDialog : public Dialog { Q_OBJECT public: explicit ViewDialog(View *view, QWidget *parent = 0); virtual ~ViewDialog(); private Q_SLOTS: void fillChanged(); void gridChanged(); void childViewOptionsChanged(); private: void setupFill(); void setupGrid(); void setupChildViewOptions(); private: QPointer _view; FillTab *_fillTab; GridTab *_gridTab; ChildViewOptionsTab * _childViewOptionsTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/graphicsfactory.cpp000644 001750 001750 00000003643 11544160207 021353 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "graphicsfactory.h" #include #include namespace Kst { static QMap *factories = 0; void cleanupGraphics() { foreach (GraphicsFactory *f, *factories) { delete f; } delete factories; factories = 0; } GraphicsFactory::GraphicsFactory() { } GraphicsFactory::~GraphicsFactory() { } void GraphicsFactory::registerFactory(const QString& node, GraphicsFactory *factory) { if (!factories) { factories = new QMap; qAddPostRoutine(cleanupGraphics); } factories->insert(node, factory); } void GraphicsFactory::registerFactory(const QStringList& nodes, GraphicsFactory *factory) { foreach (const QString n, nodes) { registerFactory(n, factory); } } ViewItem *GraphicsFactory::parse(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent) { if (!factories) { return 0; } GraphicsFactory *f = factories->value(stream.name().toString()); if (!f) { return 0; } return f->generateGraphics(stream, store, view, parent); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/legendtab.h000644 001750 001750 00000004361 11544160207 017553 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LEGENDTAB_H #define LEGENDTAB_H #include "dialogtab.h" #include "ui_legendtab.h" #include "kst_export.h" namespace Kst { class ObjectStore; class LegendTab : public DialogTab, Ui::LegendTab { Q_OBJECT public: LegendTab(QWidget *parent = 0); virtual ~LegendTab(); void setDisplayedRelations(const QStringList& displayedRelations, const QStringList& displayedRelationTips); void setAvailableRelations(const QStringList& availableRelations, const QStringList& availableRelationTips); QStringList displayedRelations(); QString title() const; void setTitle(const QString& title); bool titleDirty() const; bool autoContents() const; void setAutoContents(const bool value); bool autoContentsDirty() const; QFont font(const QFont font) const; void setFont(const QFont &font); bool fontDirty() const; qreal fontScale() const; void setFontScale(const qreal scale); bool fontScaleDirty() const; bool verticalDisplay() const; void setVerticalDisplay(const bool vertical); bool verticalDisplayDirty() const; void clearTabValues(); void setSingle(bool single); private: ObjectStore* _store; bool _single; private Q_SLOTS: void updateActive(); void updateButtons(); void addButtonClicked(); void removeButtonClicked(); void upButtonClicked(); void downButtonClicked(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/rangetab.h000644 001750 001750 00000004617 11544160207 017415 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RANGETAB_H #define RANGETAB_H #include "dialogtab.h" #include "plotitem.h" #include "ui_rangetab.h" #include "kst_export.h" namespace Kst { class RangeTab : public DialogTab, Ui::RangeTab { Q_OBJECT public: explicit RangeTab(PlotItem* plotItem, QWidget *parent = 0); virtual ~RangeTab(); void setupRange(); bool xAuto() {return _xAuto->isChecked();} bool xSpike() {return _xSpike->isChecked();} bool xBorder() {return _xBorder->isChecked();} bool xMean() {return _xMean->isChecked();} bool xFixed() { return _xFixed->isChecked();} bool xModeDirty() const; double xRange() {return _xRange->text().toDouble();} bool xRangeDirty() const; double xMin() {return _xMin->text().toDouble();} bool xMinDirty() const; double xMax() {return _xMax->text().toDouble();} bool xMaxDirty() const; bool yAuto() {return _yAuto->isChecked();} bool ySpike() {return _ySpike->isChecked();} bool yBorder() {return _yBorder->isChecked();} bool yMean() {return _yMean->isChecked();} bool yFixed() { return _yFixed->isChecked();} bool yModeDirty() const; double yRange() {return _yRange->text().toDouble();} bool yRangeDirty() const; double yMin() {return _yMin->text().toDouble();} bool yMinDirty() const; double yMax() {return _yMax->text().toDouble();} bool yMaxDirty() const; void clearTabValues(); private: PlotItem *_plotItem; private Q_SLOTS: void modified(); void updateButtons(); Q_SIGNALS: void tabModified(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/contenttab.cpp000644 001750 001750 00000016431 11544160207 020323 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "contenttab.h" #include "objectstore.h" #include "relation.h" #include "dialoglauncher.h" #include namespace Kst { ContentTab::ContentTab(QWidget *parent, ObjectStore *store) : DialogTab(parent), _store(store) { setupUi(this); _up->setIcon(QPixmap(":kst_uparrow.png")); _down->setIcon(QPixmap(":kst_downarrow.png")); _add->setIcon(QPixmap(":kst_rightarrow.png")); _remove->setIcon(QPixmap(":kst_leftarrow.png")); _up->setToolTip(i18n("Raise in plot order: Alt+Up")); _down->setToolTip(i18n("Lower in plot order: Alt+Down")); _add->setToolTip(i18n("Select: Alt+s")); _remove->setToolTip(i18n("Remove: Alt+r")); connect(_add, SIGNAL(clicked()), this, SLOT(addButtonClicked())); connect(_remove, SIGNAL(clicked()), this, SLOT(removeButtonClicked())); connect(_up, SIGNAL(clicked()), this, SLOT(upButtonClicked())); connect(_down, SIGNAL(clicked()), this, SLOT(downButtonClicked())); connect(_add, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_remove, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_up, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_down, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_availableRelationList, SIGNAL(itemDoubleClicked ( QListWidgetItem * )), this, SLOT(availableDoubleClicked(QListWidgetItem *))); connect(_displayedRelationList, SIGNAL(itemDoubleClicked ( QListWidgetItem * )), this, SLOT(displayedDoubleClicked(QListWidgetItem *))); connect(_availableRelationList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_displayedRelationList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_editSelectedAvailable, SIGNAL(clicked()), this, SLOT(editSelectedAvailable())); connect(_editSelectedDisplayed, SIGNAL(clicked()), this, SLOT(editSelectedDisplayed())); } ContentTab::~ContentTab() { } void ContentTab::editSelectedAvailable() { QList selected = _availableRelationList->selectedItems(); if (selected.count()>1) { QList objects; int n = selected.count(); for (int i=0; iretrieveObject(selected.at(i)->text())); } DialogLauncher::self()->showMultiObjectDialog(objects); } else if (selected.count() > 0) { QString name = selected.at(0)->text(); RelationPtr relation = kst_cast(_store->retrieveObject(name)); DialogLauncher::self()->showObjectDialog(relation); } } void ContentTab::editSelectedDisplayed() { QList selected = _displayedRelationList->selectedItems(); if (selected.count()>1) { QList objects; int n = selected.count(); for (int i=0; iretrieveObject(selected.at(i)->text())); } DialogLauncher::self()->showMultiObjectDialog(objects); } else if (selected.count() > 0) { QString name = selected.at(0)->text(); RelationPtr relation = kst_cast(_store->retrieveObject(name)); DialogLauncher::self()->showObjectDialog(relation); } } void ContentTab::updateButtons() { QList displayedItems = _displayedRelationList->selectedItems(); QListWidgetItem *displayedItem = 0; if (displayedItems.count() > 0) displayedItem = displayedItems.first(); _remove->setEnabled(displayedItems.count() > 0); _up->setEnabled(_displayedRelationList->row(displayedItem) > 0); _down->setEnabled(_displayedRelationList->row(displayedItem) >= 0 && _displayedRelationList->row(displayedItem) < (int)_displayedRelationList->count() - 1); _add->setEnabled(_availableRelationList->selectedItems().count() > 0); } void ContentTab::removeButtonClicked() { foreach (QListWidgetItem* item, _displayedRelationList->selectedItems()) { _availableRelationList->addItem(_displayedRelationList->takeItem(_displayedRelationList->row(item))); } _availableRelationList->clearSelection(); updateButtons(); } void ContentTab::displayedDoubleClicked(QListWidgetItem * item) { if (item) { _availableRelationList->addItem(_displayedRelationList->takeItem(_displayedRelationList->row(item))); _availableRelationList->clearSelection(); emit modified(); updateButtons(); } } void ContentTab::addButtonClicked() { foreach (QListWidgetItem* item, _availableRelationList->selectedItems()) { _displayedRelationList->addItem(_availableRelationList->takeItem(_availableRelationList->row(item))); } _displayedRelationList->clearSelection(); updateButtons(); } void ContentTab::availableDoubleClicked(QListWidgetItem * item) { if (item) { _displayedRelationList->addItem(_availableRelationList->takeItem(_availableRelationList->row(item))); _displayedRelationList->clearSelection(); emit modified(); updateButtons(); } } void ContentTab::upButtonClicked() { _displayedRelationList->setFocus(); int i = _displayedRelationList->currentRow(); if (i != -1) { QListWidgetItem *item = _displayedRelationList->takeItem(i); _displayedRelationList->insertItem(i-1, item); _displayedRelationList->clearSelection(); _displayedRelationList->setCurrentItem(item); //item->setSelected(true); updateButtons(); } } void ContentTab::downButtonClicked() { _displayedRelationList->setFocus(); // move item down int i = _displayedRelationList->currentRow(); if (i != -1) { QListWidgetItem *item = _displayedRelationList->takeItem(i); _displayedRelationList->insertItem(i+1, item); _displayedRelationList->clearSelection(); _displayedRelationList->setCurrentItem(item); //item->setSelected(true); updateButtons(); } } void ContentTab::setDisplayedRelations(QStringList displayedRelations, QStringList displayedRelationTips) { _displayedRelationList->clear(); _displayedRelationList->addItems(displayedRelations); for (int i=0; i<_displayedRelationList->count(); i++) { _displayedRelationList->item(i)->setToolTip(displayedRelationTips.at(i)); } } void ContentTab::setAvailableRelations(QStringList availableRelations, QStringList availableRelationTips) { _availableRelationList->clear(); _availableRelationList->addItems(availableRelations); for (int i=0; i<_availableRelationList->count(); i++) { _availableRelationList->item(i)->setToolTip(availableRelationTips.at(i)); } } QStringList ContentTab::displayedRelations() { QStringList relations; for (int i = 0; i < _displayedRelationList->count(); i++) { relations.append(_displayedRelationList->item(i)->text()); } return relations; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/boxitem.cpp000644 001750 001750 00000005147 11544160207 017633 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "boxitem.h" #include #include #include namespace Kst { BoxItem::BoxItem(View *parent) : ViewItem(parent) { setTypeName("Box"); setBrush(Qt::white); } BoxItem::~BoxItem() { } void BoxItem::paint(QPainter *painter) { painter->drawRect(rect()); } void BoxItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("box"); ViewItem::save(xml); xml.writeEndElement(); } } void CreateBoxCommand::createItem() { _item = new BoxItem(_view); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } BoxItemFactory::BoxItemFactory() : GraphicsFactory() { registerFactory("box", this); } BoxItemFactory::~BoxItemFactory() { } ViewItem* BoxItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { BoxItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "box") { Q_ASSERT(!rc); rc = new BoxItem(view); if (parent) { rc->setParentViewItem(parent); } // Add any new specialized BoxItem Properties here. } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "box") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating box object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/scene.h000644 001750 001750 00000002510 11544160207 016715 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SCENE_H #define SCENE_H #include #include "kst_export.h" namespace Kst { class View; class Scene : public QGraphicsScene { Q_OBJECT public: Scene(View *view); virtual ~Scene(); protected: virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); void dragEnterEvent(QGraphicsSceneDragDropEvent*); void dragMoveEvent(QGraphicsSceneDragDropEvent*); void dropEvent(QGraphicsSceneDragDropEvent*); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/bugreportwizard.cpp000644 001750 001750 00000003524 11544160207 021413 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "bugreportwizard.h" #include "config.h" #include "kst_i18n.h" #include #include #include namespace Kst { BugReportWizard::BugReportWizard(QWidget *parent) : QDialog(parent) { setupUi(this); _kstVersion->setText(KSTVERSION); #if defined(Q_OS_MAC9) _OS->setText("Mac OS 9"); #elif defined(Q_WS_MACX) _OS->setText("Mac OS X"); #elif defined(Q_WS_WIN32) _OS->setText("Windows 32-Bit"); #elif defined(Q_WS_WIN64) _OS->setText("Windows 64-Bit"); #else _OS->setText("Linux"); #endif connect(_reportBugButton, SIGNAL(clicked()), this, SLOT(reportBug())); } BugReportWizard::~BugReportWizard() { } void BugReportWizard::reportBug() { QUrl url("http://bugs.kde.org/wizard.cgi"); url.addQueryItem("os", _OS->text()); url.addQueryItem("appVersion", _kstVersion->text()); url.addQueryItem("package", "kst"); url.addQueryItem("kbugreport", "1"); url.addQueryItem("kdeVersion", "unspecified"); QDesktopServices::openUrl(url); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewgridlayout.h000644 001750 001750 00000006631 11544160207 020706 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEWGRIDLAYOUT_H #define VIEWGRIDLAYOUT_H #include #include #include #include #include #include namespace Kst { class View; class ViewItem; class PlotItem; class ViewGridLayout : public QObject { Q_OBJECT public: ViewGridLayout(ViewItem *parent); virtual ~ViewGridLayout(); ViewItem *parentItem() const; void addViewItem(ViewItem *viewItem, int row, int column); void addViewItem(ViewItem *viewItem, int row, int column, int rowSpan, int columnSpan); int rowCount() const; int columnCount() const; QSizeF spacing() const { return _spacing; } void setSpacing(const QSizeF &spacing) { _spacing = spacing; } QSizeF margin() const { return _margin; } void setMargin(const QSizeF &margin) { _margin = margin; } qreal plotLabelMarginWidth(const PlotItem *plotItem) const; qreal plotLabelMarginHeight(const PlotItem *plotItem) const; qreal plotAxisMarginWidth(const PlotItem *plotItem) const; qreal plotAxisMarginHeight(const PlotItem *plotItem) const; bool isEnabled() const; void setEnabled(bool enabled); void calculateSharing(); static void updateProjections(ViewItem *item, bool forceXShare = false, bool forceYShare = false); static void standardizePlotMargins(ViewItem *item, QPainter *painter); static void sharePlots(ViewItem *item, QPainter *painter, bool creation); void reset(); public Q_SLOTS: void apply(); void shareAxis(QPainter *painter, bool creation); Q_SIGNALS: void enabledChanged(bool enabled); private Q_SLOTS: void updatePlotMargins(); private: struct LayoutItem { ViewItem *viewItem; int row; int column; int rowSpan; int columnSpan; QTransform transform; QPointF position; QRectF rect; }; struct PlotMargins { qreal labelMargin; qreal axisMargin; }; private: void updateSharedAxis(); void unshareAxis(); void shareAxisWithPlotToLeft(LayoutItem item); void shareAxisWithPlotToRight(LayoutItem item); void shareAxisWithPlotAbove(LayoutItem item); void shareAxisWithPlotBelow(LayoutItem item); private: bool _enabled; int _rowCount; int _columnCount; bool _shareX; bool _shareY; QSizeF _spacing; QSizeF _margin; QList _items; QHash _plotMarginWidth; QHash _plotMarginHeight; QHash _itemInfos; QHash< QPair, LayoutItem> _itemLayouts; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/lineitem.h000644 001750 001750 00000004732 11544160207 017436 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LINEITEM_H #define LINEITEM_H #include "viewitem.h" #include "graphicsfactory.h" namespace Kst { class LineItem : public ViewItem { Q_OBJECT public: LineItem(View *parent); virtual ~LineItem(); QLineF line() const; //void setLine(const QLineF &line); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); virtual QPainterPath grips() const; virtual QPointF centerOfRotation() const; protected Q_SLOTS: virtual void creationPolygonChanged(View::CreationEvent event); protected: virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); virtual QPainterPath leftMidGrip() const; virtual QPainterPath rightMidGrip() const; private: virtual void updateChildGeometry(const QRectF &oldParentRect, const QRectF &newParentRect); bool _created; }; class CreateLineCommand : public CreateCommand { public: CreateLineCommand() : CreateCommand(QObject::tr("Create Line")) {} CreateLineCommand(View *view) : CreateCommand(view, QObject::tr("Create Line")) {} virtual ~CreateLineCommand() {} virtual void createItem(); }; class LineItemFactory : public GraphicsFactory { public: LineItemFactory(); ~LineItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewprimitivedialog.h000644 001750 001750 00000003545 11544160207 021714 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEWPRIMITIVEDIALOG_H #define VIEWPRIMITIVEDIALOG_H #include #include "ui_viewprimitivedialog.h" #include "kst_export.h" namespace Kst { class Document; class ObjectStore; class ViewPrimitiveDialog : public QDialog, Ui::ViewPrimitiveDialog { Q_OBJECT public: enum PrimitiveType { Scalar, String }; ViewPrimitiveDialog(QWidget *parent, Document *doc); virtual ~ViewPrimitiveDialog(); protected Q_SLOTS: void update(); private: virtual QAbstractItemModel* createModel(ObjectStore *store) = 0; void deleteModel(); Document *_doc; QAbstractItemModel *_model; }; class ViewStringDialog : public ViewPrimitiveDialog { public: ViewStringDialog(QWidget *parent, Document *doc); private: QAbstractItemModel* createModel(ObjectStore *store); }; class ViewScalarDialog : public ViewPrimitiveDialog { public: ViewScalarDialog(QWidget *parent, Document *doc); private: QAbstractItemModel* createModel(ObjectStore *store); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labelitem.h000644 001750 001750 00000004741 11544160207 017566 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELITEM_H #define LABELITEM_H #include "viewitem.h" #include "labelrenderer.h" #include "graphicsfactory.h" namespace Label { struct Parsed; } namespace Kst { class LabelItem : public ViewItem { Q_OBJECT public: LabelItem(View *parent, const QString& labelText); virtual ~LabelItem(); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); QString labelText(); void setLabelText(const QString &text); qreal labelScale(); void setLabelScale(const qreal scale); QColor labelColor() const; void setLabelColor(const QColor &color); QFont labelFont() const; void setLabelFont(const QFont &font); public Q_SLOTS: virtual void edit(); void setDirty() { _dirty = true; }; void triggerUpdate(); protected Q_SLOTS: virtual void creationPolygonChanged(View::CreationEvent event); private: void generateLabel(); Label::RenderContext *_labelRc; QTransform _paintTransform; bool _dirty; QString _text; qreal _scale; QColor _color; QFont _font; qreal _height; }; class CreateLabelCommand : public CreateCommand { public: CreateLabelCommand() : CreateCommand(QObject::tr("Create Label")) {} CreateLabelCommand(View *view): CreateCommand(view, QObject::tr("Create Label")) {} virtual ~CreateLabelCommand() {} virtual void createItem(QString *inText = 0); }; class LabelItemFactory : public GraphicsFactory { public: LabelItemFactory(); ~LabelItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/imagetab.ui000644 001750 001750 00000033606 11544160207 017571 0ustar00synthsynth000000 000000 ImageTab 0 0 748 613 Form Image Contents 0 0 &Matrix: 0 0 Image Type 0 0 Color m&ap true Con&tour map &Color map and contour map 0 0 Color Map Parameters 0 0 &Upper: false _upperThreshold false 0 0 0 Threshold - &Lower: false _lowerThreshold false 0 0 0 false 0 0 &Smart 0 0 Percent&ile: false _smartThresholdValue false 1 45.000000000000000 0.500000000000000 Qt::Vertical QSizePolicy::Expanding 41 21 0 0 false 0 0 Max&/Min &Real-time auto threshold true false Contour Map Parameters 0 0 0 0 Co&lor: false _contourColor 0 0 0 0 0 0 Num&ber of contour levels: false _numContourLines 0 0 1 10 0 0 0 &Weight: false _contourWeight QAbstractSpinBox::UpDownArrows 5 0 Use &variable line weight Qt::Vertical QSizePolicy::Expanding 76 25 Kst::ColorButton QToolButton
colorbutton.h
Kst::CurvePlacement QWidget
curveplacement.h
Kst::ColorPalette
colorpalette.h
Kst::MatrixSelector
matrixselector.h
kst-2.0.3/src/libkstapp/mainwindow.cpp000644 001750 001750 00000162301 11544160207 020334 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "mainwindow.h" #include "boxitem.h" #include "datamanager.h" #include "debugdialog.h" #include "debugnotifier.h" #include "document.h" #include "ellipseitem.h" #include "exportgraphicsdialog.h" #include "exportvectorsdialog.h" #include "logdialog.h" #include "application.h" #include "debug.h" #include "labelitem.h" #include "lineitem.h" #include "circleitem.h" #include "arrowitem.h" #include "memorywidget.h" #include "objectstore.h" #include "pictureitem.h" #include "plotitem.h" #include "plotitemmanager.h" #include "svgitem.h" #include "tabwidget.h" #include "sharedaxisboxitem.h" #include "ui_aboutdialog.h" #include "viewvectordialog.h" #include "viewmatrixdialog.h" #include "viewprimitivedialog.h" #include "view.h" #include "applicationsettings.h" #include "updatemanager.h" #include "datasourcepluginmanager.h" #include "pluginmenuitemaction.h" #include "applicationsettingsdialog.h" #include "differentiatecurvesdialog.h" #include "choosecolordialog.h" #include "changedatasampledialog.h" #include "changefiledialog.h" #include "bugreportwizard.h" #include "datawizard.h" #include "aboutdialog.h" #include "datavector.h" #include "commandlineparser.h" #include "dialogdefaults.h" #include "dialoglauncher.h" #include namespace Kst { MainWindow::MainWindow() : _dataManager(0), _exportGraphics(0), _exportVectors(0), _logDialog(0), _differentiateCurvesDialog(0), _chooseColorDialog(0), _changeDataSampleDialog(0), _changeFileDialog(0), _bugReportWizard(0), _applicationSettingsDialog(0), _aboutDialog(0), _highlightPoint(false) { _doc = new Document(this); _tabWidget = new TabWidget(this); _undoGroup = new QUndoGroup(this); _debugDialog = new DebugDialog(this); Debug::self()->setHandler(_debugDialog); setWindowTitle("Kst"); createActions(); createMenus(); createToolBars(); createStatusBar(); _tabWidget->createView(); setCentralWidget(_tabWidget); connect(_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentViewChanged())); connect(_tabWidget, SIGNAL(currentViewModeChanged()), this, SLOT(currentViewModeChanged())); connect(PlotItemManager::self(), SIGNAL(tiedZoomRemoved()), this, SLOT(tiedZoomRemoved())); connect(PlotItemManager::self(), SIGNAL(allPlotsTiedZoom()), this, SLOT(allPlotsTiedZoom())); readSettings(); connect(UpdateManager::self(), SIGNAL(objectsUpdated(qint64)), this, SLOT(updateViewItems(qint64))); QTimer::singleShot(0, this, SLOT(performHeavyStartupActions())); updateRecentKstFiles(); } MainWindow::~MainWindow() { delete _dataManager; _dataManager = 0; delete _doc; _doc = 0; } void MainWindow::performHeavyStartupActions() { // Set the timer for the UpdateManager. UpdateManager::self()->setMinimumUpdatePeriod(ApplicationSettings::self()->minimumUpdatePeriod()); DataObject::init(); DataSourcePluginManager::init(); } void MainWindow::cleanup() { if (document() && document()->objectStore()) { document()->objectStore()->clear(); } } void MainWindow::setLayoutMode(bool layoutMode) { View *v = tabWidget()->currentView(); Q_ASSERT(v); if (layoutMode) { v->setViewMode(View::Layout); _highlightPointAct->setEnabled(false); _tiedZoomAct->setEnabled(false); } else { v->setViewMode(View::Data); _highlightPointAct->setEnabled(true); _tiedZoomAct->setEnabled(true); } } void MainWindow::setHighlightPoint(bool highlight) { _highlightPoint = highlight; } void MainWindow::changeZoomOnlyMode(QAction* act) { if (act == _layoutModeAct && act->isChecked()) { setLayoutMode(true); } else { setLayoutMode(false); } tabWidget()->currentView()->setZoomOnly((View::ZoomOnlyMode)act->data().toInt()); } void MainWindow::toggleTiedZoom() { PlotItemManager::self()->toggleAllTiedZoom(tabWidget()->currentView()); } void MainWindow::tiedZoomRemoved() { _tiedZoomAct->setChecked(false); } void MainWindow::allPlotsTiedZoom() { _tiedZoomAct->setChecked(true); } bool MainWindow::promptSave() { int rc = QMessageBox::warning(this, tr("Kst"), tr("Your document has been modified.\nSave changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); if (rc == QMessageBox::Save) { save(); } else if (rc == QMessageBox::Cancel) { return false; } return true; } void MainWindow::closeEvent(QCloseEvent *e) { if (_doc->isChanged() && !promptSave()) { e->ignore(); return; } //cleanup(); QMainWindow::closeEvent(e); } Document *MainWindow::document() const { return _doc; } QUndoGroup *MainWindow::undoGroup() const { return _undoGroup; } TabWidget *MainWindow::tabWidget() const { return _tabWidget; } void MainWindow::save() { if (_doc->isOpen()) { _doc->save(); } else { saveAs(); } } void MainWindow::saveAs() { QString fn = QFileDialog::getSaveFileName(this, tr("Kst: Save File"), _doc->fileName(), tr("Kst Sessions (*.kst)")); if (fn.isEmpty()) { return; } QString restorePath = QDir::currentPath(); QString kstfiledir = fn.left(fn.lastIndexOf('/')) + '/'; QDir::setCurrent(kstfiledir); QString currentP = QDir::currentPath(); _doc->save(fn); QDir::setCurrent(restorePath); setWindowTitle("Kst - " + fn); updateRecentKstFiles(fn); } void MainWindow::newDoc() { bool clearApproved = false; if (_doc->isChanged()) { clearApproved = promptSave(); } else { int rc = QMessageBox::warning(this, tr("Kst"), tr("Delete everything?"), QMessageBox::Ok, QMessageBox::Cancel); clearApproved = (rc == QMessageBox::Ok); } if (clearApproved) { delete _dataManager; _dataManager = 0; delete _doc; _doc = new Document(this); } else { return; } tabWidget()->clear(); tabWidget()->createView(); } void MainWindow::open() { if (_doc->isChanged() && !promptSave()) { return; } QSettings settings("Kst2"); const QString lastKey = "lastOpenedKstFile"; QString fn = settings.value(lastKey).toString(); if (fn.isEmpty()) { fn = _doc->fileName(); } fn = QFileDialog::getOpenFileName(this, tr("Kst: Open File"), fn, tr("Kst Sessions (*.kst)")); if (fn.isEmpty()) { return; } settings.setValue(lastKey, fn); openFile(fn); } QAction* MainWindow::createRecentFileAction(const QString& filename, int idx, const QString& name, const char* openslot) { QAction* action = new QAction(this); QString text = tr("&%1 %2").arg(idx).arg(name); action->setText(text); action->setData(filename); action->setStatusTip(filename); action->setVisible(true); connect(action, SIGNAL(triggered()), this, openslot); return action; } void MainWindow::updateRecentKstFiles(const QString& filename) { updateRecentFiles("recentKstFileList", _fileMenu, _bottomRecentKstActions, _recentKstFilesMenu, filename, SLOT(openRecentKstFile())); } void MainWindow::updateRecentDataFiles(const QString& filename) { updateRecentFiles("recentDataFileList", _toolsMenu, _bottomRecentDataActions, _recentDataFilesMenu, filename, SLOT(openRecentDataFile())); if (!filename.isEmpty()) { _dialogDefaults->setValue("vector/datasource", filename); } } void MainWindow::updateRecentFiles(const QString& key, QMenu* menu, QList& actions, QMenu* submenu, const QString& newfilename, const char* openslot) { foreach(QAction* it, actions) { menu->removeAction(it); delete it; } actions.clear(); QSettings settings("Kst2"); QStringList recentFiles = settings.value(key).toStringList(); if (recentFiles.removeDuplicates() > 0) { settings.setValue(key, recentFiles); } if (!newfilename.isEmpty()) { recentFiles.removeOne(newfilename); recentFiles.push_front(newfilename); recentFiles = recentFiles.mid(0, 30); settings.setValue(key, recentFiles); } submenu->clear(); QAction* check = new QAction(this); check->setText("&Cleanup Non-Existent Files"); check->setData(key); check->setVisible(true); connect(check, SIGNAL(triggered()), this, SLOT(checkRecentFilesOnExistence())); submenu->addAction(check); submenu->addSeparator(); int i = 0; foreach(const QString& it, recentFiles) { i++; if (i <= 5) { // don't make file menu to wide, show complete path in statusbar QAction* action = createRecentFileAction(it, i, QFileInfo(it).fileName(), openslot); actions << action; menu->addAction(action); } submenu->addAction(createRecentFileAction(it, i, it, openslot)); } } void MainWindow::openRecentKstFile() { QAction *action = qobject_cast(sender()); if (action) { openFile(action->data().toString()); } } void MainWindow::checkRecentFilesOnExistence() { QAction *action = qobject_cast(sender()); if (action) { QSettings settings("Kst2"); QStringList recentFiles = settings.value(action->data().toString()).toStringList(); recentFiles.removeDuplicates(); foreach(const QString& it, recentFiles) { if (!QFileInfo(it).exists()) { recentFiles.removeOne(it); } } settings.setValue(action->data().toString(), recentFiles); updateRecentKstFiles(); updateRecentDataFiles(); } } bool MainWindow::initFromCommandLine() { delete _doc; _doc = new Document(this); CommandLineParser P(_doc, this); bool ok = _doc->initFromCommandLine(&P); if (!P.pngFile().isEmpty()) { exportGraphicsFile(P.pngFile(), "png", 1280, 1024,0); ok = false; } if (!P.printFile().isEmpty()) { printFromCommandLine(P.printFile()); ok = false; } if (!P.kstFileName().isEmpty()) { setWindowTitle("Kst - " + P.kstFileName()); } _doc->setChanged(false); return ok; } void MainWindow::openFile(const QString &file) { QDir::setCurrent(file.left(file.lastIndexOf('/')) + '/'); QDir::setCurrent(file.left(file.lastIndexOf('/'))); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); delete _dataManager; _dataManager = 0; delete _doc; _doc = new Document(this); bool ok = _doc->open(file); QApplication::restoreOverrideCursor(); if (!ok) { QMessageBox::critical(this, tr("Kst"), tr("Error opening document '%1':\n%2\n" "Maybe it is a Kst 1 file which could not be read by Kst 2.").arg(file, _doc->lastError())); delete _doc; _doc = new Document(this); } setWindowTitle("Kst - " + file); updateRecentKstFiles(file); } void MainWindow::exportGraphicsFile( const QString &filename, const QString &format, int width, int height, int display) { int viewCount = 0; int n_views = _tabWidget->views().size(); foreach (View *view, _tabWidget->views()) { QSize size; if (display == 0) { size.setWidth(width); size.setHeight(height); } else if (display == 1) { size.setWidth(width); size.setHeight(width); } else if (display == 2) { QSize sizeWindow(view->geometry().size()); size.setWidth(width); size.setHeight((int)((double)width * (double)sizeWindow.height() / (double)sizeWindow.width())); } else { QSize sizeWindow(view->geometry().size()); size.setHeight(height); size.setWidth((int)((double)height * (double)sizeWindow.width() / (double)sizeWindow.height())); } QImage image(size, QImage::Format_ARGB32); QPainter painter(&image); QSize currentSize(view->size()); view->resize(size); view->processResize(size); view->setPrinting(true); view->render(&painter); view->setPrinting(false); view->resize(currentSize); view->processResize(currentSize); QString file = filename; if (n_views != 1) { QFileInfo QFI(filename); file = QFI.completeBaseName() + '_' + QString::number(viewCount+1) + '.' + QFI.suffix(); } QImageWriter imageWriter(file, format.toLatin1()); imageWriter.write(image); viewCount++; } } void MainWindow::exportLog(const QString &imagename, QString &msgfilename, const QString &format, int x_size, int y_size, int size_option_index, const QString &message) { View *view = _tabWidget->currentView(); QSize size; if (size_option_index == 0) { size.setWidth(x_size); size.setHeight(y_size); } else if (size_option_index == 1) { size.setWidth(x_size); size.setHeight(y_size); } else if (size_option_index == 2) { QSize sizeWindow(view->geometry().size()); size.setWidth(x_size); size.setHeight((int)((double)x_size * (double)sizeWindow.height() / (double)sizeWindow.width())); } else { QSize sizeWindow(view->geometry().size()); size.setHeight(y_size); size.setWidth((int)((double)y_size * (double)sizeWindow.width() / (double)sizeWindow.height())); } QImage image(size, QImage::Format_ARGB32); QPainter painter(&image); QSize currentSize(view->size()); view->resize(size); view->processResize(size); view->setPrinting(true); view->render(&painter); view->setPrinting(false); view->resize(currentSize); view->processResize(currentSize); QImageWriter imageWriter(imagename, format.toLatin1()); imageWriter.write(image); QFile file(msgfilename); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&file); out << message; file.close(); } } void MainWindow::printToPrinter(QPrinter *printer) { QPainter painter(printer); QList pages; switch (printer->printRange()) { case QPrinter::PageRange: if (printer->fromPage()>0) { for (int i_page = printer->fromPage(); i_page<=printer->toPage(); i_page++) { pages.append(_tabWidget->views().at(i_page-1)); } } break; case QPrinter::AllPages: foreach (View *view, _tabWidget->views()) { pages.append(view); } break; case QPrinter::Selection: default: pages.append(_tabWidget->currentView()); break; } QSize printerPageSize = printer->pageRect().size(); for (int i = 0; i < printer->numCopies(); ++i) { for (int i_page = 0; i_pagesize()); view->resize(printerPageSize); view->processResize(printerPageSize); view->setPrinting(true); view->render(&painter); view->setPrinting(false); view->resize(currentSize); view->processResize(currentSize); if (i_pagenewPage(); } } } void MainWindow::printFromCommandLine(const QString &printFileName) { QPrinter printer(QPrinter::ScreenResolution); printer.setOutputFileName(printFileName); setPrinterDefaults(&printer); printer.setPrintRange(QPrinter::AllPages); printToPrinter(&printer); } void MainWindow::setPrinterDefaults(QPrinter *printer) { if (_dialogDefaults->value("print/landscape",true).toBool()) { printer->setOrientation(QPrinter::Landscape); } else { printer->setOrientation(QPrinter::Portrait); } printer->setPaperSize(QPrinter::PaperSize(_dialogDefaults->value("print/paperSize", QPrinter::Letter).toInt())); QPointF topLeft =_dialogDefaults->value("print/topLeftMargin", QPointF(15.0,15.0)).toPointF(); QPointF bottomRight =_dialogDefaults->value("print/bottomRightMargin", QPointF(15.0,15.0)).toPointF(); printer->setPageMargins(topLeft.x(), topLeft.y(), bottomRight.x(), bottomRight.y(), QPrinter::Millimeter); // Apparent Qt bug: setting the page margins here doesn't set the correspoding values in the print // dialog->printer-options sub-dialog under linux. If you don't open the printer-options sub-dialog, // the values here are honored. } void MainWindow::savePrinterDefaults(QPrinter *printer) { _dialogDefaults->setValue("print/landscape", printer->orientation() == QPrinter::Landscape); _dialogDefaults->setValue("print/paperSize", int(printer->paperSize())); double left, top, right, bottom; printer->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter); _dialogDefaults->setValue("print/topLeftMargin", QPointF(left, top)); _dialogDefaults->setValue("print/bottomRightMargin", QPointF(right, bottom)); } void MainWindow::print() { // line widths in pixels make sense when using ScreenResolution // FIXME: come up with a better definition of line width! QPrinter printer(QPrinter::ScreenResolution); //QPrinter printer(QPrinter::HighResolution); setPrinterDefaults(&printer); QPointer pd = new QPrintDialog(&printer, this); #if QT_VERSION >= 0x040500 pd->setOption(QPrintDialog::PrintToFile); pd->setOption(QPrintDialog::PrintPageRange, true); pd->setOption(QAbstractPrintDialog::PrintShowPageSize,true); #endif if (pd->exec() == QDialog::Accepted) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); printToPrinter(&printer); QApplication::restoreOverrideCursor(); savePrinterDefaults(&printer); } delete pd; } void MainWindow::currentViewChanged() { if(!_tabWidget->currentView()) return; _undoGroup->setActiveStack(_tabWidget->currentView()->undoStack()); currentViewModeChanged(); } void MainWindow::currentViewModeChanged() { if(!_tabWidget->currentView()) return; _layoutModeAct->setChecked(_tabWidget->currentView()->viewMode() == View::Layout); } void MainWindow::aboutToQuit() { writeSettings(); } void MainWindow::about() { if (!_aboutDialog) { _aboutDialog = new AboutDialog(this); } if (_aboutDialog->isVisible()) { _aboutDialog->raise(); _aboutDialog->activateWindow(); } _aboutDialog->show(); } void MainWindow::clearDrawingMarker() { _createBoxAct->setChecked(false); _createSharedAxisBoxAct->setChecked(false); _createCircleAct->setChecked(false); _createEllipseAct->setChecked(false); _createLabelAct->setChecked(false); _createLineAct->setChecked(false); _createArrowAct->setChecked(false); _createPictureAct->setChecked(false); _createPlotAct->setChecked(false); _createSvgAct->setChecked(false); } void MainWindow::createBox() { if (_createBoxAct->isChecked()) { clearDrawingMarker(); _createBoxAct->setChecked(true); CreateBoxCommand *cmd = new CreateBoxCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createSharedAxisBox() { if (_createSharedAxisBoxAct->isChecked()) { clearDrawingMarker(); _createSharedAxisBoxAct->setChecked(true); CreateSharedAxisBoxCommand *cmd = new CreateSharedAxisBoxCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createVector() { QString tmp; DialogLauncher::self()->showVectorDialog(tmp); } void MainWindow::createMatrix() { QString tmp; DialogLauncher::self()->showMatrixDialog(tmp); } void MainWindow::createScalar() { QString scalarName; DialogLauncher::self()->showScalarDialog(scalarName); } void MainWindow::createString() { QString stringName; DialogLauncher::self()->showStringDialog(stringName); } void MainWindow::createCircle() { if (_createCircleAct->isChecked()) { clearDrawingMarker(); _createCircleAct->setChecked(true); CreateCircleCommand *cmd = new CreateCircleCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createEllipse() { if (_createEllipseAct->isChecked()) { clearDrawingMarker(); _createEllipseAct->setChecked(true); CreateEllipseCommand *cmd = new CreateEllipseCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createLabel() { if (_createLabelAct->isChecked()) { clearDrawingMarker(); _createLabelAct->setChecked(true); CreateLabelCommand *cmd = new CreateLabelCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createLine() { if (_createLineAct->isChecked()) { clearDrawingMarker(); _createLineAct->setChecked(true); CreateLineCommand *cmd = new CreateLineCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createArrow() { if (_createArrowAct->isChecked()) { clearDrawingMarker(); _createArrowAct->setChecked(true); CreateArrowCommand *cmd = new CreateArrowCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createPicture() { if (_createPictureAct->isChecked()) { clearDrawingMarker(); _createPictureAct->setChecked(true); CreatePictureCommand *cmd = new CreatePictureCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createPlot() { if (_createPlotAct->isChecked()) { clearDrawingMarker(); _createPlotAct->setChecked(true); CreatePlotCommand *cmd = new CreatePlotCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createSvg() { if (_createSvgAct->isChecked()) { clearDrawingMarker(); _createSvgAct->setChecked(true); CreateSvgCommand *cmd = new CreateSvgCommand; cmd->createItem(); } else { _tabWidget->currentView()->setMouseMode(View::Default); } } void MainWindow::createCurve() { DialogLauncher::self()->showCurveDialog(); } void MainWindow::createPSD() { DialogLauncher::self()->showPowerSpectrumDialog(); } void MainWindow::createEquation() { DialogLauncher::self()->showEquationDialog(); } void MainWindow::createHistogram() { DialogLauncher::self()->showHistogramDialog(); } void MainWindow::createImage() { DialogLauncher::self()->showImageDialog(); } void MainWindow::createSpectogram() { DialogLauncher::self()->showCSDDialog(); } void MainWindow::createEventMonitor() { DialogLauncher::self()->showEventMonitorDialog(); } void MainWindow::createActions() { // ***************************** File actions ******************************** // _openAct = new QAction(tr("&Open..."), this); _openAct->setStatusTip(tr("Open a new session")); _openAct->setShortcut(tr("Ctrl+O")); _openAct->setIcon(QPixmap(":document-open.png")); connect(_openAct, SIGNAL(triggered()), this, SLOT(open())); _saveAct = new QAction(tr("&Save"), this); _saveAct->setStatusTip(tr("Save the current session")); _saveAct->setShortcut(tr("Ctrl+S")); _saveAct->setIcon(QPixmap(":document-save.png")); connect(_saveAct, SIGNAL(triggered()), this, SLOT(save())); _saveAsAct = new QAction(tr("Save &as..."), this); _saveAsAct->setStatusTip(tr("Save the current session")); _saveAsAct->setIcon(QPixmap(":document-save-as.png")); connect(_saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); _closeAct = new QAction(tr("C&lose"), this); _closeAct->setStatusTip(tr("Close current session")); _closeAct->setIcon(QPixmap(":document-close.png")); connect(_closeAct, SIGNAL(triggered()), this, SLOT(newDoc())); _reloadAct = new QAction(tr("Reload All &Data Sources"), this); _reloadAct->setStatusTip(tr("Reload all data sources")); _reloadAct->setIcon(QPixmap(":kst_reload.png")); connect(_reloadAct, SIGNAL(triggered()), this, SLOT(reload())); _printAct = new QAction(tr("&Print..."), this); _printAct->setStatusTip(tr("Print the current view")); _printAct->setIcon(QPixmap(":document-print.png")); connect(_printAct, SIGNAL(triggered()), this, SLOT(print())); _exportGraphicsAct = new QAction(tr("&Export as Image..."), this); _exportGraphicsAct->setStatusTip(tr("Export graphics to disk")); _exportGraphicsAct->setIcon(QPixmap(":image-x-generic.png")); connect(_exportGraphicsAct, SIGNAL(triggered()), this, SLOT(showExportGraphicsDialog())); _exportVectorsAct = new QAction(tr("Save &Vectors to Disk..."), this); _exportVectorsAct->setStatusTip(tr("Export vectors to ascii file")); _exportVectorsAct->setIcon(QPixmap(":save-vectors.png")); connect(_exportVectorsAct, SIGNAL(triggered()), this, SLOT(showExportVectorsDialog())); _logAct = new QAction(tr("&Log Entry..."), this); _logAct->setStatusTip(tr("Commit a log entry")); _logAct->setIcon(QPixmap(":new-log-event.png")); connect(_logAct, SIGNAL(triggered()), this, SLOT(showLogDialog())); _newTabAct = new QAction(tr("&New Tab"), this); _newTabAct->setStatusTip(tr("Create a new tab")); _newTabAct->setIcon(QPixmap(":tab-new.png")); connect(_newTabAct, SIGNAL(triggered()), tabWidget(), SLOT(createView())); _closeTabAct = new QAction(tr("&Close Tab"), this); _closeTabAct->setStatusTip(tr("Close the current tab")); _closeTabAct->setIcon(QPixmap(":tab-close.png")); connect(_closeTabAct, SIGNAL(triggered()), tabWidget(), SLOT(closeCurrentView())); _exitAct = new QAction(tr("E&xit"), this); _exitAct->setShortcut(tr("Ctrl+Q")); _exitAct->setStatusTip(tr("Exit the application")); _exitAct->setIcon(QPixmap(":application-exit.png")); connect(_exitAct, SIGNAL(triggered()), this, SLOT(close())); // ************************** Edit Actions ******************************* // _undoAct = _undoGroup->createUndoAction(this); _undoAct->setShortcut(tr("Ctrl+Z")); _undoAct->setIcon(QPixmap(":edit-undo.png")); _redoAct = _undoGroup->createRedoAction(this); _redoAct->setShortcut(tr("Ctrl+Shift+Z")); _redoAct->setIcon(QPixmap(":edit-redo.png")); // ********************* View Actions ********************************** // _vectorEditorAct = new QAction(tr("&Vectors"), this); _vectorEditorAct->setStatusTip(tr("Show all vectors in a spreadsheet")); connect(_vectorEditorAct, SIGNAL(triggered()), this, SLOT(showVectorEditor())); _scalarEditorAct = new QAction(tr("&Scalars"), this); _scalarEditorAct->setStatusTip(tr("Show all scalars in a spreadsheet")); connect(_scalarEditorAct, SIGNAL(triggered()), this, SLOT(showScalarEditor())); _matrixEditorAct = new QAction(tr("&Matrices"), this); _matrixEditorAct->setStatusTip(tr("Show all matrices in a spreadsheet")); connect(_matrixEditorAct, SIGNAL(triggered()), this, SLOT(showMatrixEditor())); _stringEditorAct = new QAction(tr("S&trings"), this); _stringEditorAct->setStatusTip(tr("Show all strings in a spreadsheet")); connect(_stringEditorAct, SIGNAL(triggered()), this, SLOT(showStringEditor())); // ************************ Data Range 1 click Actions ************************** // _backAct = new QAction(tr("&Back One Screen"), this); _backAct->setStatusTip(tr("Back one screen")); _backAct->setIcon(QPixmap(":page-previous.png")); connect(_backAct, SIGNAL(triggered()), this, SLOT(back())); _forwardAct = new QAction(tr("&Forward One Screen"), this); _forwardAct->setStatusTip(tr("Forward one screen")); _forwardAct->setIcon(QPixmap(":page-next.png")); connect(_forwardAct, SIGNAL(triggered()), this, SLOT(forward())); _readFromEndAct = new QAction(tr("&Count from End"), this); _readFromEndAct->setStatusTip(tr("Set all data vectors to count from end mode")); _readFromEndAct->setIcon(QPixmap(":count-from-end.png")); connect(_readFromEndAct, SIGNAL(triggered()), this, SLOT(readFromEnd())); _readToEndAct = new QAction(tr("&Read to End"), this); _readToEndAct->setStatusTip(tr("Set all data vectors to read to end mode")); _readToEndAct->setIcon(QPixmap(":read-to-end.png")); connect(_readToEndAct, SIGNAL(triggered()), this, SLOT(readToEnd())); _pauseAct = new QAction(tr("&Pause"), this); _pauseAct->setStatusTip(tr("Toggle pause updates of data sources")); _pauseAct->setIcon(QPixmap(":pause.png")); _pauseAct->setCheckable(true); _pauseAct->setShortcut(QString("p")); connect(_pauseAct, SIGNAL(toggled(bool)), this, SLOT(pause(bool))); _changeDataSampleDialogAct = new QAction(tr("Change Data &Sample Range..."), this); _changeDataSampleDialogAct->setStatusTip(tr("Show Kst's Change Data Sample Range Dialog")); _changeDataSampleDialogAct->setIcon(QPixmap(":kst_changenpts.png")); connect(_changeDataSampleDialogAct, SIGNAL(triggered()), this, SLOT(showChangeDataSampleDialog())); // ************************ Create Actions ************************** // _createPlotAct = new QAction(tr("&Plot"), this); _createPlotAct->setStatusTip(tr("Create a plot for the current view")); _createPlotAct->setIcon(QPixmap(":office-chart-area-stacked.png")); _createPlotAct->setShortcut(QString("F11")); _createPlotAct->setCheckable(true); connect(_createPlotAct, SIGNAL(triggered()), this, SLOT(createPlot())); _newScalarAct = new QAction(tr("&Scalar"), this); connect(_newScalarAct, SIGNAL(triggered()), this, SLOT(createScalar())); _newVectorAct = new QAction(tr("&Vector"), this); connect(_newVectorAct, SIGNAL(triggered()), this, SLOT(createVector())); _newMatrixAct = new QAction(tr("&Matrix"), this); connect(_newMatrixAct, SIGNAL(triggered()), this, SLOT(createMatrix())); _newStringAct = new QAction(tr("Strin&g"), this); connect(_newStringAct, SIGNAL(triggered()), this, SLOT(createString())); _newCurveAct = new QAction(tr("&Curve"), this); connect(_newCurveAct, SIGNAL(triggered()), this, SLOT(createCurve())); _newEquationAct = new QAction(tr("&Equation"), this); connect(_newEquationAct, SIGNAL(triggered()), this, SLOT(createEquation())); _newPSDAct = new QAction(tr("Po&wer Spectrum"), this); connect(_newPSDAct, SIGNAL(triggered()), this, SLOT(createPSD())); _newHistogramAct = new QAction(tr("&Histogram"), this); connect(_newHistogramAct, SIGNAL(triggered()), this, SLOT(createHistogram())); _newImageAct = new QAction(tr("&Image"), this); connect(_newImageAct, SIGNAL(triggered()), this, SLOT(createImage())); _newSpectrogramAct = new QAction(tr("Spectr&ogram"), this); connect(_newSpectrogramAct, SIGNAL(triggered()), this, SLOT(createSpectogram())); _newEventMonitorAct = new QAction(tr("Eve&nt Monitor"), this); connect(_newEventMonitorAct, SIGNAL(triggered()), this, SLOT(createEventMonitor())); // Advanced layout _createLabelAct = new QAction(tr("&Label"), this); _createLabelAct->setStatusTip(tr("Create a label for the current view")); _createLabelAct->setIcon(QPixmap(":kst_gfx_label.png")); _createLabelAct->setShortcut(QString("F3")); _createLabelAct->setCheckable(true); connect(_createLabelAct, SIGNAL(triggered()), this, SLOT(createLabel())); _createBoxAct = new QAction(tr("&Box"), this); _createBoxAct->setStatusTip(tr("Create a box for the current view")); _createBoxAct->setIcon(QPixmap(":kst_gfx_rectangle.png")); _createBoxAct->setShortcut(QString("F4")); _createBoxAct->setCheckable(true); connect(_createBoxAct, SIGNAL(triggered()), this, SLOT(createBox())); _createCircleAct = new QAction(tr("&Circle"), this); _createCircleAct->setStatusTip(tr("Create a circle for the current view")); _createCircleAct->setIcon(QPixmap(":kst_gfx_circle.png")); _createCircleAct->setShortcut(QString("F5")); _createCircleAct->setCheckable(true); connect(_createCircleAct, SIGNAL(triggered()), this, SLOT(createCircle())); _createEllipseAct = new QAction(tr("&Ellipse"), this); _createEllipseAct->setStatusTip(tr("Create an ellipse for the current view")); _createEllipseAct->setIcon(QPixmap(":kst_gfx_ellipse.png")); _createEllipseAct->setShortcut(QString("F6")); _createEllipseAct->setCheckable(true); connect(_createEllipseAct, SIGNAL(triggered()), this, SLOT(createEllipse())); _createLineAct = new QAction(tr("&Line"), this); _createLineAct->setStatusTip(tr("Create a line for the current view")); _createLineAct->setIcon(QPixmap(":kst_gfx_line.png")); _createLineAct->setShortcut(QString("F7")); _createLineAct->setCheckable(true); connect(_createLineAct, SIGNAL(triggered()), this, SLOT(createLine())); _createArrowAct = new QAction(tr("&Arrow"), this); _createArrowAct->setStatusTip(tr("Create a arrow for the current view")); _createArrowAct->setIcon(QPixmap(":kst_gfx_arrow.png")); _createArrowAct->setShortcut(QString("F8")); _createArrowAct->setCheckable(true); connect(_createArrowAct, SIGNAL(triggered()), this, SLOT(createArrow())); _createPictureAct = new QAction(tr("&Picture"), this); _createPictureAct->setStatusTip(tr("Create a picture for the current view")); _createPictureAct->setIcon(QPixmap(":image-x-generic.png")); _createPictureAct->setShortcut(QString("F9")); _createPictureAct->setCheckable(true); connect(_createPictureAct, SIGNAL(triggered()), this, SLOT(createPicture())); _createSvgAct = new QAction(tr("&Svg"), this); _createSvgAct->setStatusTip(tr("Create a svg for the current view")); _createSvgAct->setIcon(QPixmap(":draw-bezier-curves.png")); _createSvgAct->setShortcut(QString("F10")); _createSvgAct->setCheckable(true); connect(_createSvgAct, SIGNAL(triggered()), this, SLOT(createSvg())); _createSharedAxisBoxAct = new QAction(tr("Shared Axis &Box"), this); _createSharedAxisBoxAct->setStatusTip(tr("Create a shared axis box for the current item")); _createSharedAxisBoxAct->setIcon(QPixmap(":kst_gfx_sharedaxisbox.png")); _createSharedAxisBoxAct->setCheckable(true); //_createSharedAxisBoxAct->setEnabled(false); connect(_createSharedAxisBoxAct, SIGNAL(triggered()), this, SLOT(createSharedAxisBox())); // ************************** Mode Actions ******************************* // // First, general options _tiedZoomAct = new QAction(tr("&Toggle Tied Zoom"), this); _tiedZoomAct->setStatusTip(tr("Toggle the current view's tied zoom")); _tiedZoomAct->setIcon(QPixmap(":tied-zoom.png")); _tiedZoomAct->setCheckable(false); _tiedZoomAct->setShortcut(QString("t")); connect(_tiedZoomAct, SIGNAL(triggered()), this, SLOT(toggleTiedZoom())); _tabTiedAct = new QAction(tr("Tie &Across All Tabs"), this); _tabTiedAct->setStatusTip(tr("Tied zoom applies between tabs")); //_tiedZoomAct->setIcon(QPixmap(":tied-zoom.png")); _tabTiedAct->setCheckable(true); //connect(_tiedZoomAct, SIGNAL(triggered()), this, SLOT(toggleTiedZoom())); _highlightPointAct = new QAction(tr("&Highlight Data Points"), this); _highlightPointAct->setStatusTip(tr("Highlight closest data point")); _highlightPointAct->setIcon(QPixmap(":kst_datamode.png")); _highlightPointAct->setCheckable(true); connect(_highlightPointAct, SIGNAL(toggled(bool)), this, SLOT(setHighlightPoint(bool))); // Then, exclusive interaction modes QActionGroup* _interactionModeGroup = new QActionGroup(this); _standardZoomAct = _interactionModeGroup->addAction(tr("X-Y &Zoom/Scroll")); _standardZoomAct->setStatusTip(tr("Zoom arbitrarily in X- or Y-direction")); //TODO _standardZoomAct->setShortcut(QString("a")); _standardZoomAct->setCheckable(true); _standardZoomAct->setData(View::ZoomOnlyDisabled); _standardZoomAct->setIcon(QPixmap(":xy-zoom.png")); _xOnlyZoomAct = _interactionModeGroup->addAction(tr("&X-only Zoom")); _xOnlyZoomAct->setStatusTip(tr("Zoom only in X direction")); //TODO _xOnlyZoomAct->setShortcut(QString("x")); _xOnlyZoomAct->setCheckable(true); _xOnlyZoomAct->setData(View::ZoomOnlyX); _xOnlyZoomAct->setIcon(QPixmap(":x-zoom.png")); _yOnlyZoomAct = _interactionModeGroup->addAction(tr("&Y-only Zoom")); _yOnlyZoomAct->setStatusTip(tr("Zoom only in X direction")); //TODO _yOnlyZoomAct->setShortcut(QString("y")); _yOnlyZoomAct->setData(View::ZoomOnlyY); _yOnlyZoomAct->setCheckable(true); _yOnlyZoomAct->setIcon(QPixmap(":y-zoom.png")); _layoutModeAct = _interactionModeGroup->addAction(tr("&Layout Mode")); _layoutModeAct->setStatusTip(tr("Toggle the current view's layout mode")); _layoutModeAct->setIcon(QPixmap(":transform-move.png")); _layoutModeAct->setCheckable(true); _layoutModeAct->setShortcut(QString("F2")); connect(_layoutModeAct, SIGNAL(toggled(bool)), this, SLOT(setLayoutMode(bool))); _interactionModeGroup->setExclusive(true); connect(_interactionModeGroup, SIGNAL(triggered(QAction*)), this, SLOT(changeZoomOnlyMode(QAction*))); // *********************** Tools actions ************************************** // _dataManagerAct = new QAction(tr("Data &Manager"), this); _dataManagerAct->setStatusTip(tr("Show Kst's data manager window")); _dataManagerAct->setIcon(QPixmap(":data-manager.png")); _dataManagerAct->setShortcut(QString("d")); connect(_dataManagerAct, SIGNAL(triggered()), this, SLOT(showDataManager())); _dataWizardAct = new QAction(tr("&Data Wizard"), this); _dataWizardAct->setStatusTip(tr("Show Kst's Data Wizard")); _dataWizardAct->setIcon(QPixmap(":tools-wizard.png")); _dataWizardAct->setShortcut(QString("w")); connect(_dataWizardAct, SIGNAL(triggered()), this, SLOT(showDataWizard())); _changeFileDialogAct = new QAction(tr("Change Data &File"), this); _changeFileDialogAct->setStatusTip(tr("Show Kst's Change Data File Dialog")); _changeFileDialogAct->setIcon(QPixmap(":change-data-file.png")); _changeFileDialogAct->setShortcut(QString("f")); connect(_changeFileDialogAct, SIGNAL(triggered()), this, SLOT(showChangeFileDialog())); _chooseColorDialogAct = new QAction(tr("Assign Curve &Color per File"), this); _chooseColorDialogAct->setStatusTip(tr("Show Kst's Choose Color Dialog")); _chooseColorDialogAct->setIcon(QPixmap(":code-class.png")); connect(_chooseColorDialogAct, SIGNAL(triggered()), this, SLOT(showChooseColorDialog())); _differentiateCurvesDialogAct = new QAction(tr("D&ifferentiate Curves"), this); _differentiateCurvesDialogAct->setStatusTip(tr("Show Kst's Differentiate Curves Dialog")); _differentiateCurvesDialogAct->setIcon(QPixmap(":kst_differentiatecurves.png")); connect(_differentiateCurvesDialogAct, SIGNAL(triggered()), this, SLOT(showDifferentiateCurvesDialog())); // *********************** Settings actions ************************************** // _settingsDialogAct = new QAction(tr("&Configure Kst"), this); _settingsDialogAct->setStatusTip(tr("Show Kst's Configuration Dialog")); _settingsDialogAct->setIcon(QPixmap(":configure.png")); connect(_settingsDialogAct, SIGNAL(triggered()), this, SLOT(showSettingsDialog())); // *********************** Help actions ************************************** // _debugDialogAct = new QAction(tr("&Debug Dialog"), this); _debugDialogAct->setStatusTip(tr("Show the Kst debugging dialog")); _debugDialogAct->setIcon(QPixmap(":text-x-log.png")); connect(_debugDialogAct, SIGNAL(triggered()), this, SLOT(showDebugDialog())); _bugReportWizardAct = new QAction(tr("&Bug Report Wizard"), this); _bugReportWizardAct->setStatusTip(tr("Show Kst's Bug Report Wizard")); _bugReportWizardAct->setIcon(QPixmap(":kbugbuster.png")); connect(_bugReportWizardAct, SIGNAL(triggered()), this, SLOT(showBugReportWizard())); _aboutAct = new QAction(tr("&About"), this); _aboutAct->setStatusTip(tr("Show Kst's About box")); _aboutAct->setIcon(QPixmap(":dialog-information.png")); connect(_aboutAct, SIGNAL(triggered()), this, SLOT(about())); } void MainWindow::createMenus() { _fileMenu = menuBar()->addMenu(tr("&File")); // Session operations _fileMenu->addAction(_openAct); _fileMenu->addAction(_saveAct); _fileMenu->addAction(_saveAsAct); _fileMenu->addAction(_closeAct); _fileMenu->addSeparator(); _recentKstFilesMenu = _fileMenu->addMenu(tr("&Recent Sessions")); _recentDataFilesMenu = _fileMenu->addMenu("Recent Data &Files"); _fileMenu->addSeparator(); // Reload, isolate it a bit from the other entries to avoid inadvertent triggering _fileMenu->addAction(_reloadAct); _fileMenu->addSeparator(); // Print/export _fileMenu->addAction(_printAct); _fileMenu->addAction(_exportGraphicsAct); _fileMenu->addAction(_exportVectorsAct); _fileMenu->addAction(_logAct); _fileMenu->addSeparator(); // Tabs _fileMenu->addAction(_newTabAct); _fileMenu->addAction(_closeTabAct); _fileMenu->addSeparator(); // exit _fileMenu->addAction(_exitAct); // recent files _fileMenu->addSeparator(); updateRecentKstFiles(); _editMenu = menuBar()->addMenu(tr("&Edit")); _editMenu->addAction(_undoAct); _editMenu->addAction(_redoAct); // Cut/Copy/Paste will come here _viewMenu = menuBar()->addMenu(tr("&View")); _viewMenu->addAction(_vectorEditorAct); _viewMenu->addAction(_scalarEditorAct); _viewMenu->addAction(_matrixEditorAct); _viewMenu->addAction(_stringEditorAct); _rangeMenu = menuBar()->addMenu(tr("&Range")); _rangeMenu->addAction(_backAct); _rangeMenu->addAction(_forwardAct); _rangeMenu->addSeparator(); _rangeMenu->addAction(_readFromEndAct); _rangeMenu->addAction(_readToEndAct); _rangeMenu->addAction(_pauseAct); _rangeMenu->addSeparator(); _rangeMenu->addAction(_changeDataSampleDialogAct); _createMenu = menuBar()->addMenu(tr("&Create")); // Containers _createMenu->addAction(_createPlotAct); _createMenu->addAction(_createSharedAxisBoxAct); _createMenu->addSeparator(); // Primitives _createMenu->addAction(_newScalarAct); _createMenu->addAction(_newVectorAct); _createMenu->addAction(_newMatrixAct); _createMenu->addAction(_newStringAct); _createMenu->addSeparator(); // Data objects _createMenu->addAction(_newCurveAct); _createMenu->addAction(_newEquationAct); _createMenu->addAction(_newPSDAct); _createMenu->addAction(_newHistogramAct); _createMenu->addAction(_newImageAct); _createMenu->addAction(_newSpectrogramAct); _createMenu->addAction(_newEventMonitorAct); _createMenu->addSeparator(); // Now, create the dynamic plugin menus QMenu* _pluginsMenu = _createMenu->addMenu(tr("Standard P&lugin")); QMenu* _fitPluginsMenu = _createMenu->addMenu(tr("Fit Pl&ugin")); QMenu* _filterPluginsMenu = _createMenu->addMenu(tr("Fil&ter Plugin")); PluginMenuItemAction* action; foreach (QString pluginName, DataObject::dataObjectPluginList()) { action = new PluginMenuItemAction(pluginName, this); connect(action, SIGNAL(triggered(QString&)), this, SLOT(showPluginDialog(QString&))); _pluginsMenu->addAction(action); } foreach (QString pluginName, DataObject::fitsPluginList()) { action = new PluginMenuItemAction(pluginName, this); connect(action, SIGNAL(triggered(QString&)), this, SLOT(showPluginDialog(QString&))); _fitPluginsMenu->addAction(action); } foreach (QString pluginName, DataObject::filterPluginList()) { action = new PluginMenuItemAction(pluginName, this); connect(action, SIGNAL(triggered(QString&)), this, SLOT(showPluginDialog(QString&))); _filterPluginsMenu->addAction(action); } _createMenu->addSeparator(); // Annotation objects QMenu* annotations = _createMenu->addMenu(tr("&Annotation")); annotations->addAction(_createLabelAct); annotations->addAction(_createBoxAct); annotations->addAction(_createCircleAct); annotations->addAction(_createEllipseAct); annotations->addAction(_createLineAct); annotations->addAction(_createArrowAct); annotations->addAction(_createPictureAct); annotations->addAction(_createSvgAct); _modeMenu = menuBar()->addMenu(tr("&Mode")); // Interaction mode _modeMenu->addSeparator()->setText(tr("Interaction mode")); _modeMenu->addAction(_standardZoomAct); _modeMenu->addAction(_xOnlyZoomAct); _modeMenu->addAction(_yOnlyZoomAct); _modeMenu->addAction(_layoutModeAct); _standardZoomAct->setChecked(true); _modeMenu->addSeparator(); // Tied zoom options _modeMenu->addAction(_tiedZoomAct); _modeMenu->addAction(_tabTiedAct); _modeMenu->addSeparator(); // Data mode _modeMenu->addAction(_highlightPointAct); _toolsMenu = menuBar()->addMenu(tr("&Tools")); _toolsMenu->addAction(_dataManagerAct); _toolsMenu->addAction(_dataWizardAct); _toolsMenu->addAction(_changeFileDialogAct); _toolsMenu->addAction(_chooseColorDialogAct); _toolsMenu->addAction(_differentiateCurvesDialogAct); _toolsMenu->addSeparator(); updateRecentDataFiles(); _settingsMenu = menuBar()->addMenu(tr("&Settings")); _settingsMenu->addAction(_settingsDialogAct); menuBar()->addSeparator(); _helpMenu = menuBar()->addMenu(tr("&Help")); _helpMenu->addAction(_debugDialogAct); _helpMenu->addAction(_bugReportWizardAct); _helpMenu->addSeparator(); _helpMenu->addAction(_aboutAct); } void MainWindow::createToolBars() { setToolButtonStyle(Qt::ToolButtonIconOnly); _fileToolBar = addToolBar(tr("File")); _fileToolBar->setObjectName("File Toolbar"); _fileToolBar->addAction(_openAct); _fileToolBar->addAction(_saveAct); _fileToolBar->addAction(_reloadAct); _fileToolBar->addAction(_printAct); _fileToolBar->addAction(_logAct); _editToolBar = addToolBar(tr("Edit")); _editToolBar->setObjectName("Edit Toolbar"); _editToolBar->addAction(_undoAct); _editToolBar->addAction(_redoAct); _toolsToolBar = addToolBar(tr("Tools")); _toolsToolBar->setObjectName("Tools Toolbar"); _toolsToolBar->addAction(_dataManagerAct); _toolsToolBar->addAction(_dataWizardAct); _toolsToolBar->addAction(_changeDataSampleDialogAct); _toolsToolBar->addAction(_changeFileDialogAct); _rangeToolBar = addToolBar(tr("Data Range")); _rangeToolBar->setObjectName("Data Range Toolbar"); _rangeToolBar->addAction(_backAct); _rangeToolBar->addAction(_forwardAct); _rangeToolBar->addAction(_readFromEndAct); _rangeToolBar->addAction(_readToEndAct); _rangeToolBar->addAction(_pauseAct); _modeToolBar = addToolBar(tr("Mode")); _modeToolBar->setObjectName("Mode Toolbar"); _modeToolBar->addAction(_tiedZoomAct); _modeToolBar->addAction(_highlightPointAct); _modeToolBar->addSeparator(); _modeToolBar->addAction(_standardZoomAct); _modeToolBar->addAction(_xOnlyZoomAct); _modeToolBar->addAction(_yOnlyZoomAct); _modeToolBar->addAction(_layoutModeAct); _annotationToolBar = addToolBar(tr("Advanced Layout")); _annotationToolBar->setObjectName("Advanced Layout Toolbar"); _annotationToolBar->addAction(_createSharedAxisBoxAct); _annotationToolBar->addSeparator(); _annotationToolBar->addAction(_createLabelAct); _annotationToolBar->addAction(_createBoxAct); _annotationToolBar->addAction(_createCircleAct); _annotationToolBar->addAction(_createEllipseAct); _annotationToolBar->addAction(_createLineAct); _annotationToolBar->addAction(_createArrowAct); _annotationToolBar->addAction(_createPictureAct); _annotationToolBar->addAction(_createSvgAct); } void MainWindow::createStatusBar() { _messageLabel = new QLabel(statusBar()); statusBar()->addWidget(_messageLabel); setStatusMessage(tr("Ready")); _progressBar = new QProgressBar(statusBar()); _progressBar->hide(); statusBar()->addPermanentWidget(_progressBar); MemoryWidget *mw = new MemoryWidget(statusBar()); statusBar()->addPermanentWidget(mw); DebugNotifier *dn = new DebugNotifier(statusBar()); connect(dn, SIGNAL(showDebugLog()), this, SLOT(showDebugDialog())); connect(_debugDialog, SIGNAL(notifyOfError()), dn, SLOT(reanimate())); connect(_debugDialog, SIGNAL(notifyAllClear()), dn, SLOT(close())); statusBar()->addPermanentWidget(dn); } void MainWindow::setStatusMessage(QString message) { _messageLabel->setText(message); } QProgressBar *MainWindow::progressBar() const { return _progressBar; } void MainWindow::readFromEnd() { int nf = 0; int skip; bool do_skip; bool do_filter; DataVectorList dataVectors = document()->objectStore()->getObjects(); foreach (DataVectorPtr v, dataVectors) { v->readLock(); nf = v->reqNumFrames(); if (nf <=0 ) { nf = v->numFrames(); } skip = v->skip(); do_skip = v->doSkip(); do_filter = v->doAve(); v->unlock(); v->writeLock(); v->changeFrames(-1, nf, skip, do_skip, do_filter); v->registerChange(); v->unlock(); } UpdateManager::self()->doUpdates(true); _dialogDefaults->setValue("vector/range", nf); _dialogDefaults->setValue("vector/countFromEnd", true); _dialogDefaults->setValue("vector/readToEnd", false); } void MainWindow::readToEnd() { int f0 = 0; int skip; bool do_skip; bool do_filter; DataVectorList dataVectors = document()->objectStore()->getObjects(); foreach (DataVectorPtr v, dataVectors) { v->readLock(); f0 = v->startFrame(); skip = v->skip(); do_skip = v->doSkip(); do_filter = v->doAve(); v->unlock(); v->writeLock(); v->changeFrames(f0, -1, skip, do_skip, do_filter); v->registerChange(); v->unlock(); } _dialogDefaults->setValue("vector/start", f0); _dialogDefaults->setValue("vector/countFromEnd", false); _dialogDefaults->setValue("vector/readToEnd", true); UpdateManager::self()->doUpdates(true); } void MainWindow::pause(bool pause) { UpdateManager::self()->setPaused(pause); if (!pause) { foreach (DataSourcePtr s, document()->objectStore()->dataSourceList()) { s->checkUpdate(); } } } void MainWindow::forward() { int f0 = 0; int nf = 0; int skip; int filelength; bool count_from_end; bool read_to_end; bool do_skip; bool do_filter; DataVectorList dataVectors = document()->objectStore()->getObjects(); foreach (DataVectorPtr v, dataVectors) { v->readLock(); f0 = v->startFrame(); nf = v->numFrames(); count_from_end = v->countFromEOF(); read_to_end = v->readToEOF(); filelength = v->fileLength(); skip = v->skip(); do_skip = v->doSkip(); do_filter = v->doAve(); v->unlock(); if ((!count_from_end) && (!read_to_end)) { f0 += nf; if (f0+nf>=filelength) { f0 = filelength - nf; } v->writeLock(); v->changeFrames(f0, nf, skip, do_skip, do_filter); v->registerChange(); v->unlock(); } } _dialogDefaults->setValue("vector/range", nf); _dialogDefaults->setValue("vector/start", f0); _dialogDefaults->setValue("vector/countFromEnd", false); _dialogDefaults->setValue("vector/readToEnd", false); UpdateManager::self()->doUpdates(true); } void MainWindow::back() { int f0 = 0; int nf = 0; int skip; int filelength; bool count_from_end; bool read_to_end; bool do_skip; bool do_filter; DataVectorList dataVectors = document()->objectStore()->getObjects(); foreach (DataVectorPtr v, dataVectors) { v->readLock(); f0 = v->startFrame(); nf = v->numFrames(); count_from_end = v->countFromEOF(); read_to_end = v->readToEOF(); filelength = v->fileLength(); skip = v->skip(); do_skip = v->doSkip(); do_filter = v->doAve(); v->unlock(); if (f0 != 0) { if (count_from_end) { f0 = filelength - nf; } if (read_to_end) { nf = filelength - f0; } f0 -= nf; if (f0<0) { f0 = 0; } v->writeLock(); v->changeFrames(f0, nf, skip, do_skip, do_filter); v->registerChange(); v->unlock(); } } _dialogDefaults->setValue("vector/range", nf); _dialogDefaults->setValue("vector/start", f0); _dialogDefaults->setValue("vector/countFromEnd", false); _dialogDefaults->setValue("vector/readToEnd", false); UpdateManager::self()->doUpdates(true); } void MainWindow::reload() { document()->objectStore()->rebuildDataSourceList(); UpdateManager::self()->doUpdates(true); //document()->setChanged(true); } void MainWindow::showDataManager() { if (!_dataManager) { _dataManager = new DataManager(this, _doc); } if (_dataManager->isVisible()) { _dataManager->raise(); _dataManager->activateWindow(); } _dataManager->show(); } void MainWindow::updateViewItems(qint64 serial) { QList plots = ViewItem::getItems(); bool changed = false; foreach (PlotItem *plot, plots) { changed |= plot->handleChangedInputs(serial); } if (changed) { _tabWidget->currentView()->update(); } QTimer::singleShot(20, UpdateManager::self(), SLOT(viewItemUpdateFinished())); } void MainWindow::showVectorEditor() { ViewVectorDialog *viewVectorDialog = new ViewVectorDialog(this, _doc); viewVectorDialog->show(); } void MainWindow::showScalarEditor() { ViewPrimitiveDialog *viewScalarDialog = new ViewScalarDialog(this, _doc); viewScalarDialog->show(); } void MainWindow::showStringEditor() { ViewPrimitiveDialog *viewStringDialog = new ViewStringDialog(this, _doc); viewStringDialog->show(); } void MainWindow::showMatrixEditor() { ViewMatrixDialog *viewMatrixDialog = new ViewMatrixDialog(this, _doc); viewMatrixDialog->show(); } void MainWindow::showDebugDialog() { if (!_debugDialog) { _debugDialog = new DebugDialog(this); } _debugDialog->setObjectStore(document()->objectStore()); if (_debugDialog->isVisible()) { _debugDialog->raise(); _debugDialog->activateWindow(); } _debugDialog->show(); } void MainWindow::showExportGraphicsDialog() { if (!_exportGraphics) { _exportGraphics = new ExportGraphicsDialog(this); connect(_exportGraphics, SIGNAL(exportGraphics(const QString &, const QString &, int, int, int)), this, SLOT(exportGraphicsFile(const QString &, const QString &, int, int, int))); } if (_exportGraphics->isVisible()) { _exportGraphics->raise(); _exportGraphics->activateWindow(); } _exportGraphics->show(); } void MainWindow::showExportVectorsDialog() { if (!_exportVectors) { _exportVectors = new ExportVectorsDialog(this); //connect(_exportVectors, SIGNAL(exportGraphics(const QString &, const QString &, int, int, int)), // this, SLOT(exportGraphicsFile(const QString &, const QString &, int, int, int))); } if (_exportVectors->isVisible()) { _exportVectors->raise(); _exportVectors->activateWindow(); } _exportVectors->show(); } void MainWindow::showLogDialog() { if (!_logDialog) { _logDialog = new LogDialog(this); //connect(_logDialog, SIGNAL(exportLog(const QString &, time_t, const QString &, int, int, int, const QString &)), // this, SLOT(exportLog(const QString &, time_t, const QString &, int, int, int, const QString &))); } if (_logDialog->isVisible()) { _logDialog->raise(); _logDialog->activateWindow(); } _logDialog->show(); } void MainWindow::showSettingsDialog() { if (!_applicationSettingsDialog) { _applicationSettingsDialog = new ApplicationSettingsDialog(this); } if (_applicationSettingsDialog->isVisible()) { _applicationSettingsDialog->raise(); _applicationSettingsDialog->activateWindow(); } _applicationSettingsDialog->show(); } void MainWindow::showDifferentiateCurvesDialog() { if (!_differentiateCurvesDialog) { _differentiateCurvesDialog = new DifferentiateCurvesDialog(this); } if (_differentiateCurvesDialog->isVisible()) { _differentiateCurvesDialog->raise(); _differentiateCurvesDialog->activateWindow(); } _differentiateCurvesDialog->show(); } void MainWindow::showChooseColorDialog() { if (!_chooseColorDialog) { _chooseColorDialog = new ChooseColorDialog(this); } if (_chooseColorDialog->isVisible()) { _chooseColorDialog->raise(); _chooseColorDialog->activateWindow(); } _chooseColorDialog->show(); } void MainWindow::showChangeDataSampleDialog() { if (!_changeDataSampleDialog) { _changeDataSampleDialog = new ChangeDataSampleDialog(this); } if (_changeDataSampleDialog->isVisible()) { _changeDataSampleDialog->raise(); _changeDataSampleDialog->activateWindow(); } _changeDataSampleDialog->show(); } void MainWindow::showDataWizard() { DataWizard *dataWizard = new DataWizard(this); connect(dataWizard, SIGNAL(dataSourceLoaded(const QString&)), this, SLOT(updateRecentDataFiles(const QString&))); dataWizard->show(); } void MainWindow::openRecentDataFile() { QAction *action = qobject_cast(sender()); if (action) { DataWizard *dataWizard = new DataWizard(this, action->data().toString()); connect(dataWizard, SIGNAL(dataSourceLoaded(const QString&)), this, SLOT(updateRecentDataFiles(const QString&))); dataWizard->show(); } } void MainWindow::showBugReportWizard() { if (!_bugReportWizard) { _bugReportWizard = new BugReportWizard(this); } if (_bugReportWizard->isVisible()) { _bugReportWizard->raise(); _bugReportWizard->activateWindow(); } _bugReportWizard->show(); } void MainWindow::showChangeFileDialog() { if (!_changeFileDialog) { _changeFileDialog = new ChangeFileDialog(this); } if (_changeFileDialog->isVisible()) { _changeFileDialog->raise(); _changeFileDialog->activateWindow(); } _changeFileDialog->show(); } void MainWindow::showPluginDialog(QString &pluginName) { DialogLauncher::self()->showBasicPluginDialog(pluginName); } bool MainWindow::isTiedTabs() { return _tabTiedAct->isChecked(); } void MainWindow::readSettings() { QSettings settings("Kst2"); QByteArray geo = settings.value("geometry").toByteArray(); if (!geo.isEmpty()) { restoreGeometry(geo); } else { setGeometry(50, 50, 800, 600); } restoreState(settings.value("toolbarState").toByteArray()); _tabTiedAct->setChecked(settings.value("tieTabs").toBool()); } void MainWindow::writeSettings() { QSettings settings("Kst2"); settings.setValue("geometry", saveGeometry()); settings.setValue("toolbarState", saveState()); settings.setValue("tieTabs", _tabTiedAct->isChecked()); } void MainWindow::setWidgetFlags(QWidget* widget) { if (widget) { // Make sure the dialog gets maximize and minimize buttons under Windows widget->QWidget::setWindowFlags((Qt::WindowFlags) Qt::Dialog | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint #if QT_VERSION >= 0x040500 | Qt::WindowCloseButtonHint #endif ); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/sharedaxisboxitem.h000644 001750 001750 00000012344 11544160207 021351 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SHAREDAXISBOXITEM_H #define SHAREDAXISBOXITEM_H #include "viewitem.h" #include "plotitem.h" #include "graphicsfactory.h" namespace Kst { class SharedAxisBoxItem : public ViewItem { Q_OBJECT public: friend class SharedAxisBoxItemFactory; SharedAxisBoxItem(View *parent); virtual ~SharedAxisBoxItem(); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); virtual void addToMenuForContextEvent(QMenu &menu); void triggerContextEvent(QGraphicsSceneContextMenuEvent *event); bool tryMousePressEvent(ViewItem* viewItem, QGraphicsSceneMouseEvent *event); void setDirty() { _dirty = true; } bool isXAxisShared() const { return _shareX; } void setXAxisShared(const bool shared); bool isYAxisShared() const { return _shareY; } void setYAxisShared(const bool shared); PlotAxis::ZoomMode xAxisZoomMode() const { return _xAxisZoomMode; } void setXAxisZoomMode(PlotAxis::ZoomMode mode); PlotAxis::ZoomMode yAxisZoomMode() const { return _yAxisZoomMode; } void setYAxisZoomMode(PlotAxis::ZoomMode mode); void updateZoomForDataUpdate(qint64 serial); PlotItem* keyPlot() { return _keyPlot; }; Q_SIGNALS: void breakShareSignal(); public Q_SLOTS: void breakShare(); bool acceptItems(); void lockItems(); void shareXAxis(); void shareYAxis(); void zoomFixedExpression(const QRectF &projection, PlotItem* originPlotItem); void zoomXRange(const QRectF &projection, PlotItem* originPlotItem); void zoomYRange(const QRectF &projection, PlotItem* originPlotItem); void zoomMaximum(PlotItem* originPlotItem); void zoomMaxSpikeInsensitive(PlotItem* originPlotItem); void zoomMeanCentered(PlotItem* originPlotItem); void zoomXMeanCentered(PlotItem* originPlotItem); void zoomXMaximum(PlotItem* originPlotItem); void zoomXNoSpike(PlotItem* originPlotItem); void zoomXAutoBorder(PlotItem* originPlotItem); void zoomXRight(PlotItem* originPlotItem); void zoomXLeft(PlotItem* originPlotItem); void zoomXOut(PlotItem* originPlotItem); void zoomXIn(PlotItem* originPlotItem); void zoomNormalizeXtoY(PlotItem* originPlotItem); void zoomLogX(PlotItem* originPlotItem, bool autoEnable = true, bool enable = true); void zoomYMeanCentered(PlotItem* originPlotItem); void zoomYLocalMaximum(PlotItem* originPlotItem); void zoomYMaximum(PlotItem* originPlotItem); void zoomYNoSpike(PlotItem* originPlotItem); void zoomYAutoBorder(PlotItem* originPlotItem); void zoomYUp(PlotItem* originPlotItem); void zoomYDown(PlotItem* originPlotItem); void zoomYOut(PlotItem* originPlotItem); void zoomYIn(PlotItem* originPlotItem); void zoomNormalizeYtoX(PlotItem* originPlotItem); void zoomLogY(PlotItem* originPlotItem, bool autoEnable = true, bool enable = true); protected Q_SLOTS: virtual void creationPolygonChanged(View::CreationEvent event); private: void updateShare(); void updatePlotTiedZoomSupport(); void highlightPlots(QList plots); QRectF computeRect(PlotAxis::ZoomMode xMode, PlotAxis::ZoomMode yMode); void applyZoom(const QRectF &projection, PlotItem* originPlotItem, bool applyX = true, bool applyY = true); QList getSharedPlots(); QList getTiedPlots(PlotItem* originPlotItem); QAction *_breakAction; QPointer _layout; QList _highlightedPlots; QList _sharedPlots; PlotItem* _keyPlot; bool _loaded; bool _firstPaint; bool _dirty; bool _shareX, _shareY; qint64 _serialOfLastChange; PlotAxis::ZoomMode _xAxisZoomMode, _yAxisZoomMode; bool _sharedIsDirty; }; class CreateSharedAxisBoxCommand : public CreateCommand { Q_OBJECT public: CreateSharedAxisBoxCommand() : CreateCommand(QObject::tr("Create Shared Axis Box")) {} CreateSharedAxisBoxCommand(View *view) : CreateCommand(view, QObject::tr("Create Shared Axis Box")) {} virtual ~CreateSharedAxisBoxCommand() {} virtual void undo(); virtual void redo(); virtual void createItem(); public Q_SLOTS: virtual void creationComplete(); }; class SharedAxisBoxItemFactory : public GraphicsFactory { public: SharedAxisBoxItemFactory(); ~SharedAxisBoxItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/basicplugindialog.cpp000644 001750 001750 00000006077 11544160207 021647 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "basicplugindialog.h" #include "dialogpage.h" #include "objectstore.h" #include "datacollection.h" #include "document.h" #include "basicplugin.h" #include namespace Kst { BasicPluginTab::BasicPluginTab(QString& pluginName, QWidget *parent) : DataTab(parent) { setupUi(this); setTabTitle(tr("Basic Plugin")); QGridLayout *layout = new QGridLayout(_inputOutputBox); _configWidget = DataObject::pluginWidget(pluginName); _configWidget->setupSlots(this); layout->addWidget(_configWidget, 0, 0); layout->activate(); } BasicPluginTab::~BasicPluginTab() { } void BasicPluginTab::setObjectStore(ObjectStore *store) { _configWidget->setObjectStore(store); } BasicPluginDialog::BasicPluginDialog(QString& pluginName, ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent), _pluginName(pluginName) { QString title; if (editMode() == Edit) title = tr("Edit ") + pluginName + tr(" Plugin"); else title = tr("New ") + pluginName + tr(" Plugin"); setWindowTitle(title); _basicPluginTab = new BasicPluginTab(pluginName, this); addDataTab(_basicPluginTab); if (dataObject) { _basicPluginTab->configWidget()->setupFromObject(dataObject); } else { _basicPluginTab->configWidget()->load(); } } BasicPluginDialog::~BasicPluginDialog() { } QString BasicPluginDialog::tagString() const { return DataDialog::tagString(); } ObjectPtr BasicPluginDialog::createNewDataObject() { BasicPluginPtr dataObject = kst_cast(DataObject::createPlugin(_pluginName, _document->objectStore(), _basicPluginTab->configWidget())); _basicPluginTab->configWidget()->save(); if (!dataObject->isValid()) { _document->objectStore()->removeObject(dataObject); QString msg(tr("Unable to create Plugin Object using provided parameters.\n\n")); msg += dataObject->errorMessage(); QMessageBox::warning(this, tr("Kst"), msg); return 0; } return dataObject; } ObjectPtr BasicPluginDialog::editExistingDataObject() const { if (BasicPlugin* plugin = kst_cast(dataObject())) { plugin->writeLock(); plugin->change(_basicPluginTab->configWidget()); plugin->registerChange(); plugin->unlock(); } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotitem.cpp000644 001750 001750 00000416010 11544160207 020014 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "plotitem.h" #include "plotitemmanager.h" #include "plotrenderitem.h" #include "image.h" #include "layoutboxitem.h" #include "viewgridlayout.h" #include "debug.h" #include "application.h" #include "mainwindow.h" #include "document.h" #include "tabwidget.h" #include "labelrenderer.h" #include "datacollection.h" #include "cartesianrenderitem.h" #include "plotitemdialog.h" #include "dialoglauncher.h" #include "sharedaxisboxitem.h" #include "applicationsettings.h" #include "updatemanager.h" #include "math_kst.h" #include "settings.h" #include "dialogdefaults.h" #include #include #include // Zoom Debugging. 0 Off, 1 On. #define DEBUG_ZOOM 0 // Label Region Debugging. 0 Off, 1 On. #define DEBUG_LABEL_REGION 0 // Benchmark drawing // undefined = None, 1 = PlotItem, 2 = More Details //#define BENCHMARK 1 static const int PLOT_MAXIMIZED_ZORDER = 1000; namespace Kst { PlotItem::PlotItem(View *parent) : ViewItem(parent), PlotItemInterface(), _isInSharedAxisBox(false), _manuallyHideLeftAxisLabel(false), _manuallyHideRightAxisLabel(false), _manuallyHideTopAxisLabel(false), _manuallyHideBottomAxisLabel(false), _plotRectsDirty(true), _calculatedLeftLabelMargin(0.0), _calculatedLeftLabelWidth(0.0), _calculatedLeftBaseOffset(0.0), _calculatedRightLabelMargin(0.0), _calculatedTopLabelMargin(0.0), _calculatedTopLabelHeight(0.0), _calculatedBottomLabelMargin(0.0), _calculatedBottomLabelWidth(0.0), _calculatedLabelMarginWidth(0.0), _calculatedLabelMarginHeight(0.0), _calculatedAxisMarginWidth(0.0), _calculatedAxisMarginHeight(0.0), _calculatedAxisMarginVLead(0.0), _calculatedAxisMarginHLead(0.0), _calculatedAxisMarginROverflow(0.0), _calculatedAxisMarginTOverflow(0.0), _leftPadding(0.0), _bottomPadding(0.0), _rightPadding(0.0), _topPadding(0.0), _globalFontScale(0.0), _numberAxisLabelScaleFactor(1.0), _useNumberAxisLabelScale(true), _showLegend(false), _allowUpdates(true), _legend(0), _zoomMenu(0), _filterMenu(0), _fitMenu(0), _sharedAxisBoxMenu(0), _sharedBox(0), _axisLabelsDirty(true), _plotPixmapDirty(true), _i_per(0) { setTypeName("Plot"); _initializeShortName(); setBrush(Qt::white); setSupportsTiedZoom(true); _xAxis = new PlotAxis(this, Qt::Horizontal); _yAxis = new PlotAxis(this, Qt::Vertical); connect(this, SIGNAL(geometryChanged()), _xAxis, SLOT(setTicksUpdated())); connect(this, SIGNAL(geometryChanged()), _yAxis, SLOT(setTicksUpdated())); connect(this, SIGNAL(geometryChanged()), this, SLOT(setPlotRectsDirty())); _leftLabelDetails = new PlotLabel(this); _rightLabelDetails = new PlotLabel(this); _topLabelDetails = new PlotLabel(this); _bottomLabelDetails = new PlotLabel(this); _numberLabelDetails = new PlotLabel(this); //view()->configurePlotFontDefaults(this); connect(_leftLabelDetails, SIGNAL(labelChanged()), this, SLOT(setPlotBordersDirty())); connect(_leftLabelDetails, SIGNAL(labelChanged()), this, SLOT(setLeftLabelDirty())); connect(_rightLabelDetails, SIGNAL(labelChanged()), this, SLOT(setPlotBordersDirty())); connect(_rightLabelDetails, SIGNAL(labelChanged()), this, SLOT(setRightLabelDirty())); connect(_topLabelDetails, SIGNAL(labelChanged()), this, SLOT(setPlotBordersDirty())); connect(_topLabelDetails, SIGNAL(labelChanged()), this, SLOT(setTopLabelDirty())); connect(_bottomLabelDetails, SIGNAL(labelChanged()), this, SLOT(setPlotBordersDirty())); connect(_bottomLabelDetails, SIGNAL(labelChanged()), this, SLOT(setBottomLabelDirty())); connect(_numberLabelDetails, SIGNAL(labelChanged()), this, SLOT(setPlotBordersDirty())); connect(_numberLabelDetails, SIGNAL(labelChanged()), this, SLOT(setAxisLabelsDirty())); _undoStack = new QUndoStack(this); createActions(); PlotItemManager::self()->addPlot(this); // Set the initial projection. setProjectionRect(QRectF(QPointF(-0.1, -0.1), QPointF(0.1, 0.1))); renderItem(PlotRenderItem::Cartesian); setPlotBordersDirty(true); connect(this, SIGNAL(triggerRedraw()), this, SLOT(redrawPlot())); connect(this, SIGNAL(geometryChanged()), this, SLOT(setLabelsDirty())); connect(this, SIGNAL(updateAxes()), this, SLOT(setPlotPixmapDirty())); connect(this, SIGNAL(geometryChanged()), this, SLOT(setPlotPixmapDirty())); applyDefaults(); } void PlotItem::applyDefaults() { QFont font; // Global Font Settings QFont globalfont; globalfont.fromString(_dialogDefaults->value("plot/globalFontFamily",globalfont.toString()).toString()); setGlobalFont(globalfont); setGlobalFontScale(ApplicationSettings::self()->defaultFontScale()); QColor color; color = _dialogDefaults->value("plot/globalFontColor", QColor(Qt::black)).value(); setGlobalFontColor(color); // Left Font Settings leftLabelDetails()->setFontUseGlobal(_dialogDefaults->value("plot/leftFontGlobal", true).toBool()); font.fromString(_dialogDefaults->value("plot/leftFontFamily",globalfont.toString()).toString()); leftLabelDetails()->setFont(font); leftLabelDetails()->setFontScale(_dialogDefaults->value("plot/leftFontScale",0).toDouble()); color = _dialogDefaults->value("plot/leftFontColor", QColor(Qt::black)).value(); leftLabelDetails()->setFontColor(color); // right Font Settings rightLabelDetails()->setFontUseGlobal(_dialogDefaults->value("plot/rightFontGlobal", true).toBool()); font.fromString(_dialogDefaults->value("plot/rightFontFamily",globalfont.toString()).toString()); rightLabelDetails()->setFont(font); rightLabelDetails()->setFontScale(_dialogDefaults->value("plot/rightFontScale",0).toDouble()); color = _dialogDefaults->value("plot/rightFontColor", QColor(Qt::black)).value(); rightLabelDetails()->setFontColor(color); // top Font Settings topLabelDetails()->setFontUseGlobal(_dialogDefaults->value("plot/topFontGlobal", true).toBool()); font.fromString(_dialogDefaults->value("plot/topFontFamily",globalfont.toString()).toString()); topLabelDetails()->setFont(font); topLabelDetails()->setFontScale(_dialogDefaults->value("plot/topFontScale",0).toDouble()); color = _dialogDefaults->value("plot/topFontColor", QColor(Qt::black)).value(); topLabelDetails()->setFontColor(color); // bottom Font Settings bottomLabelDetails()->setFontUseGlobal(_dialogDefaults->value("plot/bottomFontGlobal", true).toBool()); font.fromString(_dialogDefaults->value("plot/bottomFontFamily",globalfont.toString()).toString()); bottomLabelDetails()->setFont(font); bottomLabelDetails()->setFontScale(_dialogDefaults->value("plot/bottomFontScale",0).toDouble()); color = _dialogDefaults->value("plot/bottomFontColor", QColor(Qt::black)).value(); bottomLabelDetails()->setFontColor(color); // number Font Settings numberLabelDetails()->setFontUseGlobal(_dialogDefaults->value("plot/numberFontGlobal", true).toBool()); font.fromString(_dialogDefaults->value("plot/numberFontFamily",globalfont.toString()).toString()); numberLabelDetails()->setFont(font); numberLabelDetails()->setFontScale(_dialogDefaults->value("plot/numberFontScale",0).toDouble()); color = _dialogDefaults->value("plot/numberFontColor", QColor(Qt::black)).value(); numberLabelDetails()->setFontColor(color); // set the pen QPen pen; pen.setStyle((Qt::PenStyle)_dialogDefaults->value("plot/strokeStyle", 1).toInt()); pen.setWidthF(_dialogDefaults->value("plot/strokeWidth",0).toDouble()); pen.setJoinStyle((Qt::PenJoinStyle)_dialogDefaults->value("plot/strokeJoinStyle",64).toInt()); pen.setCapStyle((Qt::PenCapStyle)_dialogDefaults->value("plot/strokeCapStyle",16).toInt()); QBrush brush; color = _dialogDefaults->value("plot/strokeBrushColor",QColor(Qt::black)).value(); brush.setColor(color); brush.setStyle((Qt::BrushStyle)_dialogDefaults->value("plot/strokeBrushStyle",1).toInt()); pen.setBrush(brush); setPen(pen); //set the brush bool useGradient = _dialogDefaults->value("plot/fillBrushUseGradient", false).toBool(); if (useGradient) { QStringList stopInfo = _dialogDefaults->value("plot/fillBrushGradient", "0,#000000,1,#ffffff,"). toString().split(',', QString::SkipEmptyParts); QLinearGradient gradient(1,0,0,0); gradient.setCoordinateMode(QGradient::ObjectBoundingMode); for (int i = 0; i < stopInfo.size(); i+=2) { gradient.setColorAt(stopInfo.at(i).toDouble(), QColor(stopInfo.at(i+1))); } brush = QBrush(gradient); } else { color = _dialogDefaults->value("plot/fillBrushColor",QColor(Qt::white)).value(); brush.setColor(color); brush.setStyle((Qt::BrushStyle)_dialogDefaults->value("plot/fillBrushStyle",1).toInt()); } setBrush(brush); xAxis()->setAxisVisible(_dialogDefaults->value("plot/xAxisVisible", true).toBool()); xAxis()->setAxisLog(_dialogDefaults->value("plot/xAxisLog", false).toBool()); xAxis()->setAxisReversed(_dialogDefaults->value("plot/xAxisReversed", false).toBool()); xAxis()->setAxisAutoBaseOffset(_dialogDefaults->value("plot/xAxisAutoBaseOffset", true).toBool()); xAxis()->setAxisBaseOffset(_dialogDefaults->value("plot/xAxisBaseOffset", false).toBool()); xAxis()->setAxisInterpret(_dialogDefaults->value("plot/xAxisInterpret", false).toBool()); xAxis()->setAxisInterpretation((AxisInterpretationType)_dialogDefaults->value("plot/xAxisInterpretation", 1).toInt()); xAxis()->setAxisDisplay((AxisDisplayType)_dialogDefaults->value("plot/xAxisDisplay", 4).toInt()); xAxis()->setAxisMajorTickMode((PlotAxis::MajorTickMode)_dialogDefaults->value("plot/xAxisMajorTickMode", 5).toInt()); xAxis()->setAxisMinorTickCount(_dialogDefaults->value("plot/xAxisMinorTickCount", 5).toInt()); xAxis()->setAxisAutoMinorTicks(_dialogDefaults->value("plot/xAxisautoMinorTickCount", true).toBool()); xAxis()->setDrawAxisMajorTicks(_dialogDefaults->value("plot/xAxisDrawMajorTicks", true).toBool()); xAxis()->setDrawAxisMinorTicks(_dialogDefaults->value("plot/xAxisDrawMinorTicks", true).toBool()); xAxis()->setDrawAxisMajorGridLines(_dialogDefaults->value("plot/xAxisDrawMajorGridLines", true).toBool()); xAxis()->setDrawAxisMinorGridLines(_dialogDefaults->value("plot/xAxisDrawMinorGridLines", false).toBool()); xAxis()->setAxisMajorGridLineStyle((Qt::PenStyle)_dialogDefaults->value("plot/xAxisDrawMajorGridLineStyle", 2).toInt()); xAxis()->setAxisMajorGridLineWidth(_dialogDefaults->value("plot/xAxisDrawMajorGridLineWidth",1).toDouble()); color = _dialogDefaults->value("plot/xAxisDrawMajorGridLineColor", "#a0a0a4").value(); xAxis()->setAxisMajorGridLineColor(color); xAxis()->setAxisMinorGridLineStyle((Qt::PenStyle)_dialogDefaults->value("plot/xAxisDrawMinorGridLineStyle", 2).toInt()); xAxis()->setAxisMinorGridLineWidth(_dialogDefaults->value("plot/xAxisDrawMinorGridLineWidth",1).toDouble()); color = _dialogDefaults->value("plot/xAxisDrawMinorGridLineColor", "#a0a0a4").value(); xAxis()->setAxisMinorGridLineColor(color); xAxis()->setAxisSignificantDigits(_dialogDefaults->value("plot/xAxisSignificantDigits",9).toInt()); xAxis()->setAxisLabelRotation(_dialogDefaults->value("plot/xAxisRotation",0).toDouble()); yAxis()->setAxisVisible(_dialogDefaults->value("plot/yAxisVisible", true).toBool()); yAxis()->setAxisLog(_dialogDefaults->value("plot/yAxisLog", false).toBool()); yAxis()->setAxisReversed(_dialogDefaults->value("plot/yAxisReversed", false).toBool()); yAxis()->setAxisAutoBaseOffset(_dialogDefaults->value("plot/yAxisAutoBaseOffset", true).toBool()); yAxis()->setAxisBaseOffset(_dialogDefaults->value("plot/yAxisBaseOffset", false).toBool()); yAxis()->setAxisInterpret(_dialogDefaults->value("plot/yAxisInterpret", false).toBool()); yAxis()->setAxisInterpretation((AxisInterpretationType)_dialogDefaults->value("plot/yAxisInterpretation", 1).toInt()); yAxis()->setAxisDisplay((AxisDisplayType)_dialogDefaults->value("plot/yAxisDisplay", 4).toInt()); yAxis()->setAxisMajorTickMode((PlotAxis::MajorTickMode)_dialogDefaults->value("plot/yAxisMajorTickMode", 5).toInt()); yAxis()->setAxisMinorTickCount(_dialogDefaults->value("plot/yAxisMinorTickCount", 5).toInt()); yAxis()->setAxisAutoMinorTicks(_dialogDefaults->value("plot/yAxisautoMinorTickCount", true).toBool()); yAxis()->setDrawAxisMajorTicks(_dialogDefaults->value("plot/yAxisDrawMajorTicks", true).toBool()); yAxis()->setDrawAxisMinorTicks(_dialogDefaults->value("plot/yAxisDrawMinorTicks", true).toBool()); yAxis()->setDrawAxisMajorGridLines(_dialogDefaults->value("plot/yAxisDrawMajorGridLines", true).toBool()); yAxis()->setDrawAxisMinorGridLines(_dialogDefaults->value("plot/yAxisDrawMinorGridLines", false).toBool()); yAxis()->setAxisMajorGridLineStyle((Qt::PenStyle)_dialogDefaults->value("plot/yAxisDrawMajorGridLineStyle", 2).toInt()); yAxis()->setAxisMajorGridLineWidth(_dialogDefaults->value("plot/yAxisDrawMajorGridLineWidth",1).toDouble()); color = _dialogDefaults->value("plot/yAxisDrawMajorGridLineColor", "#a0a0a4").value(); yAxis()->setAxisMajorGridLineColor(color); yAxis()->setAxisMinorGridLineStyle((Qt::PenStyle)_dialogDefaults->value("plot/yAxisDrawMinorGridLineStyle", 2).toInt()); yAxis()->setAxisMinorGridLineWidth(_dialogDefaults->value("plot/yAxisDrawMinorGridLineWidth",1).toDouble()); color = _dialogDefaults->value("plot/yAxisDrawMinorGridLineColor", "#a0a0a4").value(); yAxis()->setAxisMinorGridLineColor(color); yAxis()->setAxisSignificantDigits(_dialogDefaults->value("plot/yAxisSignificantDigits",9).toInt()); yAxis()->setAxisLabelRotation(_dialogDefaults->value("plot/yAxisRotation",0).toDouble()); } PlotItem::~PlotItem() { delete _xAxis; delete _yAxis; delete _leftLabelDetails; delete _rightLabelDetails; delete _topLabelDetails; delete _bottomLabelDetails; delete _numberLabelDetails; delete _zoomMenu; delete _filterMenu; PlotItemManager::self()->removePlot(this); } void PlotItem::_initializeShortName() { _shortName = 'P'+QString::number(_plotnum); if (_plotnum>max_plotnum) max_plotnum = _plotnum; _plotnum++; } QString PlotItem::plotName() const { return Name(); } void PlotItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("plot"); xml.writeAttribute("tiedxzoom", QVariant(isXTiedZoom()).toString()); xml.writeAttribute("tiedyzoom", QVariant(isYTiedZoom()).toString()); xml.writeAttribute("leftlabelvisible", QVariant(_leftLabelDetails->isVisible()).toString()); xml.writeAttribute("bottomlabelvisible", QVariant(_bottomLabelDetails->isVisible()).toString()); xml.writeAttribute("rightlabelvisible", QVariant(_rightLabelDetails->isVisible()).toString()); xml.writeAttribute("toplabelvisible", QVariant(_topLabelDetails->isVisible()).toString()); xml.writeAttribute("globalfont", QVariant(_globalFont).toString()); xml.writeAttribute("globalfontscale", QVariant(_globalFontScale).toString()); xml.writeAttribute("globalfontcolor", QVariant(_globalFontColor).toString()); xml.writeAttribute("showlegend", QVariant(_showLegend).toString()); xml.writeAttribute("hidebottomaxislabel", QVariant(_manuallyHideBottomAxisLabel).toString()); xml.writeAttribute("hidetopaxislabel", QVariant(_manuallyHideTopAxisLabel).toString()); xml.writeAttribute("hideleftaxislabel", QVariant(_manuallyHideLeftAxisLabel).toString()); xml.writeAttribute("hiderightaxislabel", QVariant(_manuallyHideRightAxisLabel).toString()); saveNameInfo(xml, PLOTNUM); ViewItem::save(xml); legend()->saveInPlot(xml); foreach (PlotRenderItem *renderer, renderItems()) { renderer->saveInPlot(xml); } _xAxis->saveInPlot(xml, QString("xaxis")); _yAxis->saveInPlot(xml, QString("yaxis")); _leftLabelDetails->saveInPlot(xml, QString("leftlabel")); _rightLabelDetails->saveInPlot(xml, QString("rightlabel")); _topLabelDetails->saveInPlot(xml, QString("toplabel")); _bottomLabelDetails->saveInPlot(xml, QString("bottomlabel")); _numberLabelDetails->saveInPlot(xml, QString("numberlabel")); xml.writeStartElement("projectionrect"); xml.writeAttribute("x", QVariant(projectionRect().x()).toString()); xml.writeAttribute("y", QVariant(projectionRect().y()).toString()); xml.writeAttribute("width", QVariant(projectionRect().width()).toString()); xml.writeAttribute("height", QVariant(projectionRect().height()).toString()); xml.writeEndElement(); xml.writeEndElement(); } } void PlotItem::edit() { PlotItemDialog *editDialog = new PlotItemDialog(this, kstApp->mainWindow()); editDialog->show(); } void PlotItem::createActions() { _zoomMaximum = new QAction(tr("Zoom Maximum"), this); _zoomMaximum->setShortcut(Qt::Key_M); registerShortcut(_zoomMaximum); connect(_zoomMaximum, SIGNAL(triggered()), this, SLOT(zoomMaximum())); _zoomMaxSpikeInsensitive = new QAction(tr("Zoom Max Spike Insensitive"), this); _zoomMaxSpikeInsensitive->setShortcut(Qt::Key_S); registerShortcut(_zoomMaxSpikeInsensitive); connect(_zoomMaxSpikeInsensitive, SIGNAL(triggered()), this, SLOT(zoomMaxSpikeInsensitive())); _zoomPrevious = _undoStack->createUndoAction(this, tr("Zoom Previous")); _zoomPrevious->setShortcut(Qt::Key_R); registerShortcut(_zoomPrevious); _zoomTied = new QAction(tr("Zoom Tied"), this); _zoomTied->setShortcut(Qt::Key_T); _zoomTied->setCheckable(true); registerShortcut(_zoomTied); connect(_zoomTied, SIGNAL(triggered()), this, SLOT(zoomTied())); _zoomXTied = new QAction(tr("Zoom X Tied"), this); _zoomXTied->setShortcut(Qt::CTRL+Qt::Key_T); _zoomXTied->setCheckable(true); registerShortcut(_zoomXTied); connect(_zoomXTied, SIGNAL(triggered()), this, SLOT(zoomXTied())); _zoomYTied = new QAction(tr("Zoom Y Tied"), this); _zoomYTied->setShortcut(Qt::SHIFT+Qt::Key_T); _zoomYTied->setCheckable(true); registerShortcut(_zoomYTied); connect(_zoomYTied, SIGNAL(triggered()), this, SLOT(zoomYTied())); _zoomMeanCentered = new QAction(tr("Zoom Mean-centered Y"), this); _zoomMeanCentered->setShortcut(Qt::Key_A); registerShortcut(_zoomMeanCentered); connect(_zoomMeanCentered, SIGNAL(triggered()), this, SLOT(zoomMeanCentered())); _zoomXMaximum = new QAction(tr("X-Zoom Maximum"), this); _zoomXMaximum->setShortcut(Qt::CTRL+Qt::Key_M); registerShortcut(_zoomXMaximum); connect(_zoomXMaximum, SIGNAL(triggered()), this, SLOT(zoomXMaximum())); _zoomXAutoBorder = new QAction(tr("X-Zoom Auto Border"), this); _zoomXAutoBorder->setShortcut(Qt::CTRL+Qt::Key_B); registerShortcut(_zoomXAutoBorder); connect(_zoomXAutoBorder, SIGNAL(triggered()), this, SLOT(zoomXAutoBorder())); _zoomXNoSpike = new QAction(tr("X-Zoom Spike Insensitive"), this); //_zoomXNoSpike->setShortcut(Qt::CTRL+Qt::Key_S); registerShortcut(_zoomXNoSpike); connect(_zoomXNoSpike, SIGNAL(triggered()), this, SLOT(zoomXNoSpike())); _zoomXRight = new QAction(tr("X-Zoom Right"), this); _zoomXRight->setShortcut(Qt::Key_Right); registerShortcut(_zoomXRight); connect(_zoomXRight, SIGNAL(triggered()), this, SLOT(zoomXRight())); _zoomXLeft= new QAction(tr("X-Zoom Left"), this); _zoomXLeft->setShortcut(Qt::Key_Left); registerShortcut(_zoomXLeft); connect(_zoomXLeft, SIGNAL(triggered()), this, SLOT(zoomXLeft())); _zoomXOut = new QAction(tr("X-Zoom Out"), this); _zoomXOut->setShortcut(Qt::SHIFT+Qt::Key_Right); registerShortcut(_zoomXOut); connect(_zoomXOut, SIGNAL(triggered()), this, SLOT(zoomXOut())); _zoomXIn = new QAction(tr("X-Zoom In"), this); _zoomXIn->setShortcut(Qt::SHIFT+Qt::Key_Left); registerShortcut(_zoomXIn); connect(_zoomXIn, SIGNAL(triggered()), this, SLOT(zoomXIn())); _zoomNormalizeXtoY = new QAction(tr("Normalize X-axis to Y-axis"), this); _zoomNormalizeXtoY->setShortcut(Qt::Key_N); registerShortcut(_zoomNormalizeXtoY); connect(_zoomNormalizeXtoY, SIGNAL(triggered()), this, SLOT(zoomNormalizeXtoY())); _zoomLogX = new QAction(tr("Log X-axis"), this); _zoomLogX->setShortcut(Qt::Key_G); _zoomLogX->setCheckable(true); registerShortcut(_zoomLogX); connect(_zoomLogX, SIGNAL(triggered()), this, SLOT(zoomLogX())); _zoomYLocalMaximum = new QAction(tr("Y-Zoom Local Maximum"), this); _zoomYLocalMaximum->setShortcut(Qt::SHIFT+Qt::Key_L); registerShortcut(_zoomYLocalMaximum); connect(_zoomYLocalMaximum, SIGNAL(triggered()), this, SLOT(zoomYLocalMaximum())); _zoomYMaximum = new QAction(tr("Y-Zoom Maximum"), this); _zoomYMaximum->setShortcut(Qt::SHIFT+Qt::Key_M); registerShortcut(_zoomYMaximum); connect(_zoomYMaximum, SIGNAL(triggered()), this, SLOT(zoomYMaximum())); _zoomYAutoBorder = new QAction(tr("Y-Zoom Auto Border"), this); _zoomYAutoBorder->setShortcut(Qt::SHIFT+Qt::Key_B); registerShortcut(_zoomYAutoBorder); connect(_zoomYAutoBorder, SIGNAL(triggered()), this, SLOT(zoomYAutoBorder())); _zoomYNoSpike = new QAction(tr("Y-Zoom Spike Insensitive"), this); _zoomYNoSpike->setShortcut(Qt::SHIFT+Qt::Key_S); registerShortcut(_zoomYNoSpike); connect(_zoomYNoSpike, SIGNAL(triggered()), this, SLOT(zoomYNoSpike())); _zoomYUp= new QAction(tr("Y-Zoom Up"), this); _zoomYUp->setShortcut(Qt::Key_Up); registerShortcut(_zoomYUp); connect(_zoomYUp, SIGNAL(triggered()), this, SLOT(zoomYUp())); _zoomYDown= new QAction(tr("Y-Zoom Down"), this); _zoomYDown->setShortcut(Qt::Key_Down); registerShortcut(_zoomYDown); connect(_zoomYDown, SIGNAL(triggered()), this, SLOT(zoomYDown())); _zoomYOut = new QAction(tr("Y-Zoom Out"), this); _zoomYOut->setShortcut(Qt::SHIFT+Qt::Key_Up); registerShortcut(_zoomYOut); connect(_zoomYOut, SIGNAL(triggered()), this, SLOT(zoomYOut())); _zoomYIn = new QAction(tr("Y-Zoom In"), this); _zoomYIn->setShortcut(Qt::SHIFT+Qt::Key_Down); registerShortcut(_zoomYIn); connect(_zoomYIn, SIGNAL(triggered()), this, SLOT(zoomYIn())); _zoomNormalizeYtoX = new QAction(tr("Normalize Y-axis to X-axis"), this); _zoomNormalizeYtoX->setShortcut(Qt::SHIFT+Qt::Key_N); registerShortcut(_zoomNormalizeYtoX); connect(_zoomNormalizeYtoX, SIGNAL(triggered()), this, SLOT(zoomNormalizeYtoX())); _zoomLogY = new QAction(tr("Log Y Axis"), this); _zoomLogY->setShortcut(Qt::Key_L); _zoomLogY->setCheckable(true); registerShortcut(_zoomLogY); connect(_zoomLogY, SIGNAL(triggered()), this, SLOT(zoomLogY())); _adjustImageColorscale = new QAction(tr("Adjust Image Color Scale"), this); _adjustImageColorscale->setShortcut(Qt::Key_I); registerShortcut(_adjustImageColorscale); connect(_adjustImageColorscale, SIGNAL(triggered()), this, SLOT(adjustImageColorScale())); createZoomMenu(); _plotMaximize = new QAction(tr("Maximize Plot"), this); _plotMaximize->setShortcut(Qt::Key_Z); _plotMaximize->setCheckable(true); registerShortcut(_plotMaximize); connect(_plotMaximize, SIGNAL(triggered()), this, SLOT(plotMaximize())); _shareBoxShareX = new QAction(tr("Share Plots on X-Axis"), this); _shareBoxShareX->setShortcut(Qt::Key_X); _shareBoxShareX->setCheckable(true); registerShortcut(_shareBoxShareX); connect(_shareBoxShareX, SIGNAL(triggered()), this, SIGNAL(shareXAxisTriggered())); _shareBoxShareY = new QAction(tr("Share Plots on Y-Axis"), this); _shareBoxShareY->setShortcut(Qt::Key_Y); _shareBoxShareY->setCheckable(true); registerShortcut(_shareBoxShareY); connect(_shareBoxShareY, SIGNAL(triggered()), this, SIGNAL(shareYAxisTriggered())); _breakSharedBox = new QAction(tr("Break Shared Axis Box"), this); _breakSharedBox->setShortcut(Qt::Key_B); registerShortcut(_breakSharedBox); connect(_breakSharedBox, SIGNAL(triggered()), this, SIGNAL(breakShareTriggered())); } void PlotItem::createZoomMenu() { if (_zoomMenu) { delete _zoomMenu; } _zoomMenu = new QMenu; _zoomMenu->setTitle(tr("Zoom")); _zoomMenu->addAction(_zoomMaximum); _zoomMenu->addAction(_zoomMaxSpikeInsensitive); _zoomMenu->addAction(_zoomPrevious); _zoomMenu->addAction(_zoomMeanCentered); _zoomMenu->addAction(_zoomTied); _zoomMenu->addAction(_adjustImageColorscale); _zoomMenu->addSeparator(); _zoomMenu->addAction(_zoomXTied); _zoomMenu->addAction(_zoomXMaximum); _zoomMenu->addAction(_zoomXAutoBorder); _zoomMenu->addAction(_zoomXNoSpike); _zoomMenu->addAction(_zoomXRight); _zoomMenu->addAction(_zoomXLeft); _zoomMenu->addAction(_zoomXOut); _zoomMenu->addAction(_zoomXIn); _zoomMenu->addAction(_zoomNormalizeXtoY); _zoomMenu->addAction(_zoomLogX); _zoomMenu->addSeparator(); _zoomMenu->addAction(_zoomYTied); _zoomMenu->addAction(_zoomYLocalMaximum); _zoomMenu->addAction(_zoomYMaximum); _zoomMenu->addAction(_zoomYAutoBorder); _zoomMenu->addAction(_zoomYNoSpike); _zoomMenu->addAction(_zoomYUp); _zoomMenu->addAction(_zoomYDown); _zoomMenu->addAction(_zoomYOut); _zoomMenu->addAction(_zoomYIn); _zoomMenu->addAction(_zoomNormalizeYtoX); _zoomMenu->addAction(_zoomLogY); } CurveList PlotItem::curveList() const { CurveList list; foreach (PlotRenderItem *renderer, renderItems()) { foreach (RelationPtr relation, renderer->relationList()) { if (CurvePtr curve = kst_cast(relation)) { list << curve; } } } return list; } void PlotItem::createFilterMenu() { if (_filterMenu) { delete _filterMenu; } _filterMenu = new QMenu; _filterMenu->setTitle(tr("Filter")); CurveList curves = curveList(); foreach (const CurvePtr& curve, curves) { _filterMenu->addAction(new QAction(curve->Name(), this)); } connect(_filterMenu, SIGNAL(triggered(QAction*)), this, SLOT(showFilterDialog(QAction*))); } void PlotItem::createFitMenu() { if (_fitMenu) { delete _fitMenu; } _fitMenu = new QMenu; _fitMenu->setTitle(tr("Fit")); CurveList curves = curveList(); foreach (const CurvePtr& curve, curves) { _fitMenu->addAction(new QAction(curve->Name(), this)); } connect(_fitMenu, SIGNAL(triggered(QAction*)), this, SLOT(showFitDialog(QAction*))); } void PlotItem::createSharedAxisBoxMenu() { if (_sharedAxisBoxMenu) { delete _sharedAxisBoxMenu; } _sharedAxisBoxMenu = new QMenu; _sharedAxisBoxMenu->setTitle(tr("Shared Axis Box Settings")); _sharedAxisBoxMenu->addAction(_shareBoxShareX); _sharedAxisBoxMenu->addAction(_shareBoxShareY); } void PlotItem::addToMenuForContextEvent(QMenu &menu) { if (parentItem() && isInSharedAxisBox() && _sharedBox) { if (view()->viewMode() == View::Data) { menu.addMenu(_sharedAxisBoxMenu); menu.addAction(_breakSharedBox); _shareBoxShareX->setChecked(_sharedBox->isXAxisShared()); _shareBoxShareY->setChecked(_sharedBox->isYAxisShared()); } } if (view()->viewMode() == View::Data) { _plotMaximize->setChecked(_plotMaximized); menu.addAction(_plotMaximize); } _zoomLogX->setChecked(xAxis()->axisLog()); _zoomLogY->setChecked(yAxis()->axisLog()); _zoomTied->setChecked(isTiedZoom()); _zoomXTied->setChecked(isXTiedZoom()); _zoomYTied->setChecked(isYTiedZoom()); _zoomPrevious->setVisible(!isInSharedAxisBox()); menu.addMenu(_zoomMenu); if (!DataObject::filterPluginList().empty()) { createFilterMenu(); menu.addMenu(_filterMenu); } if (!DataObject::fitsPluginList().empty()) { createFitMenu(); menu.addMenu(_fitMenu); } } void PlotItem::showFitFilterDialog(QAction* action, const QString& plugin) { CurveList curves = curveList(); foreach (const CurvePtr& curve, curves) { if (curve->Name() == action->text()) { DialogLauncher::self()->showBasicPluginDialog(plugin, 0, curve->xVector(), curve->yVector(), this); } } } void PlotItem::showFilterDialog(QAction* action) { showFitFilterDialog(action, DataObject::filterPluginList().first()); } void PlotItem::showFitDialog(QAction* action) { showFitFilterDialog(action, DataObject::fitsPluginList().first()); } void PlotItem::redrawPlot() { update(); } bool PlotItem::handleChangedInputs(qint64 serial) { if (!_allowUpdates) { return false; } // decide if the inputs have changed bool no_change = true; if (_serialOfLastChange==Forced) { no_change = false; } else { foreach (PlotRenderItem *renderer, renderItems()) { foreach (RelationPtr relation, renderer->relationList()) { if (relation->serialOfLastChange() > _serialOfLastChange) { no_change = false; } } } } if (no_change) { return false; } _serialOfLastChange = serial; if (isInSharedAxisBox()) { // Need to update the box's projectionRect. sharedAxisBox()->updateZoomForDataUpdate(serial); } QRectF compute = computedProjectionRect(); QRectF newProjectionRec = projectionRect(); if ((xAxis()->axisZoomMode() == PlotAxis::Auto) || (xAxis()->axisZoomMode() == PlotAxis::MeanCentered) || (xAxis()->axisZoomMode() == PlotAxis::AutoBorder) || (xAxis()->axisZoomMode() == PlotAxis::SpikeInsensitive)) { newProjectionRec.setLeft(compute.x()); newProjectionRec.setWidth(compute.width()); } if ((yAxis()->axisZoomMode() == PlotAxis::AutoBorder) || (yAxis()->axisZoomMode() == PlotAxis::Auto) || (yAxis()->axisZoomMode() == PlotAxis::SpikeInsensitive) || (yAxis()->axisZoomMode() == PlotAxis::MeanCentered)) { newProjectionRec.setTop(compute.y()); newProjectionRec.setHeight(compute.height()); } setProjectionRect(newProjectionRec); #if 0 else { setProjectionRect(QRectF(compute.x(), projectionRect().y(), compute.width(), projectionRect().height())); } } else if (yAxis()->axisZoomMode() == PlotAxis::Auto) { setProjectionRect(QRectF(projectionRect().x(), compute.y(), projectionRect().width(), compute.height())); } else { update(); } } #endif setLabelsDirty(); return true; } QList PlotItem::renderItems() const { return _renderers.values(); } PlotRenderItem *PlotItem::renderItem(PlotRenderItem::RenderType type) { if ((type == PlotRenderItem::First) && (_renderers.count()>0)) { return _renderers.values().at(0); } if (_renderers.contains(type)) return _renderers.value(type); switch (type) { case PlotRenderItem::Cartesian: { CartesianRenderItem *renderItem = new CartesianRenderItem(this); _renderers.insert(type, renderItem); return renderItem; } case PlotRenderItem::Polar: case PlotRenderItem::Sinusoidal: default: return 0; } } void PlotItem::calculateBorders(QPainter *painter) { calculateLeftLabelMargin(painter); calculateRightLabelMargin(painter); calculateTopLabelMargin(painter); calculateBottomLabelMargin(painter); calculateBottomTickLabelBound(painter); calculateLeftTickLabelBound(painter); calculateMargins(); setPlotRectsDirty(); } void PlotItem::updatePlotPixmap() { #if BENCHMARK QTime bench_time; bench_time.start(); #endif _plotPixmapDirty = false; if (maskedByMaximization()) { return; } QPixmap pixmap(rect().width()+1, rect().height()+1); pixmap.fill(Qt::transparent); QPainter pixmapPainter(&pixmap); //pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.save(); if (rect().topLeft() != QPointF(0, 0)) { pixmapPainter.translate(-rect().topLeft()); } paintPixmap(&pixmapPainter); pixmapPainter.restore(); _plotPixmap = pixmap; #if BENCHMARK int i = bench_time.elapsed(); qDebug() << "Total Time to update plot pixmap " << (void *)this << ": " << i << "ms"; #endif } void PlotItem::paint(QPainter *painter) { if (maskedByMaximization()) { return; } #if BENCHMARK QTime bench_time; bench_time.start(); #endif if (view()->isPrinting()) { paintPixmap(painter); } else { if (_plotPixmapDirty && rect().isValid()) { updatePlotPixmap(); } painter->save(); painter->setPen(Qt::NoPen); painter->drawRect(rect()); painter->restore(); painter->drawPixmap(rect().topLeft(), _plotPixmap); } #if BENCHMARK int i = bench_time.elapsed(); qDebug() << "Total Time to paint " << (void *)this << ": " << i << "ms" << endl; #endif } void PlotItem::paintPixmap(QPainter *painter) { if ((view()->plotBordersDirty() || (creationState() == ViewItem::InProgress)) && rect().isValid()) { ViewGridLayout::standardizePlotMargins(this, painter); setPlotBordersDirty(false); } #if BENCHMARK QTime bench_time, benchtmp; int b_1 = 0, b_2 = 0, b_3 = 0, b_4 = 0, b_5 = 0; bench_time.start(); benchtmp.start(); #endif painter->save(); painter->setPen(Qt::NoPen); painter->drawRect(rect()); painter->restore(); painter->save(); bool xTicksUpdated = xAxis()->ticksUpdated(); bool yTicksUpdated = yAxis()->ticksUpdated(); if (xTicksUpdated ||yTicksUpdated) { resetScaleAxisLabels(); } painter->setFont(numberLabelDetails()->calculatedFont()); #if BENCHMARK b_1 = benchtmp.elapsed(); #endif #if DEBUG_LABEL_REGION // qDebug() << "=============> leftLabel:" << leftLabel() << endl; #endif paintLeftLabel(painter); #if DEBUG_LABEL_REGION // qDebug() << "=============> bottomLabel:" << bottomLabel() << endl; #endif paintBottomLabel(painter); #if DEBUG_LABEL_REGION // qDebug() << "=============> rightLabel:" << rightLabel() << endl; #endif paintRightLabel(painter); #if BENCHMARK b_2 = benchtmp.elapsed(); #endif paintPlot(painter, xTicksUpdated, yTicksUpdated); #if BENCHMARK b_3 = benchtmp.elapsed(); #endif paintTickLabels(painter); #if BENCHMARK b_4 = benchtmp.elapsed(); #endif paintPlotMarkers(painter); #if DEBUG_LABEL_REGION // qDebug() << "=============> topLabel:" << topLabel() << endl; #endif paintTopLabel(painter); #if BENCHMARK b_5 = benchtmp.elapsed(); #endif painter->restore(); #if BENCHMARK int i = bench_time.elapsed(); qDebug() << "Painting Plot Pixmap " << (void *)this << ": " << i << "ms"; if (b_1 > 0) qDebug() << " Setup: " << b_1 << "ms"; if (b_2 - b_1 > 0) qDebug() << " Labels: " << (b_2 - b_1) << "ms"; if (b_3 - b_2 > 0) qDebug() << " Plot: " << (b_3 - b_2) << "ms"; if (b_4 - b_3 > 0) qDebug() << " Tick Labels: " << (b_4 - b_3) << "ms"; if (b_5 - b_4 > 0) qDebug() << " Markers: " << (b_5 - b_4) << "ms"; #endif } void PlotItem::paintPlot(QPainter *painter, bool xUpdated, bool yUpdated) { if (xUpdated) { xAxis()->validateDrawingRegion(painter); updateXAxisLines(); updateXAxisLabels(painter); } if (yUpdated) { yAxis()->validateDrawingRegion(painter); updateYAxisLines(); updateYAxisLabels(painter); } if (isUseAxisScale()) { QFont font(painter->font()); qreal pointSize = qMax((font.pointSizeF() * _numberAxisLabelScaleFactor), ApplicationSettings::self()->minimumFontSize()); font.setPointSizeF(pointSize); painter->setFont(font); } if (_axisLabelsDirty) { if (!xUpdated) { updateXAxisLabels(painter); } if (!yUpdated) { updateYAxisLabels(painter); } } #if BENCHMARK > 1 QTime bench_time, benchtmp; int b_1 = 0, b_2 = 0, b_3 = 0, b_4 = 0, b_5 = 0; bench_time.start(); benchtmp.start(); #endif paintMajorGridLines(painter); #if BENCHMARK > 1 b_1 = benchtmp.elapsed(); #endif paintMinorGridLines(painter); #if BENCHMARK > 1 b_2 = benchtmp.elapsed(); #endif painter->save(); painter->setBrush(Qt::NoBrush); painter->setPen(pen()); painter->drawRect(plotRect()); #if BENCHMARK > 1 b_3 = benchtmp.elapsed(); #endif paintMajorTicks(painter); #if BENCHMARK > 1 b_4 = benchtmp.elapsed(); #endif paintMinorTicks(painter); #if BENCHMARK > 1 b_5 = benchtmp.elapsed(); #endif painter->restore(); #if BENCHMARK > 1 int i = bench_time.elapsed(); qDebug() << "Painting Plot - PaintPlot " << (void *)this << ": " << i << "ms"; if (b_1 > 0) qDebug() << " Major Lines: " << b_1 << "ms"; if (b_2 - b_1 > 0) qDebug() << " Minor Lines: " << (b_2 - b_1) << "ms"; if (b_3 - b_2 > 0) qDebug() << " Rect: " << (b_3 - b_2) << "ms"; if (b_4 - b_3 > 0) qDebug() << " Major Ticks: " << (b_4 - b_3) << "ms"; if (b_5 - b_4 > 0) qDebug() << " Minor Ticks: " << (b_5 - b_4) << "ms"; #endif } void PlotItem::updateXAxisLines() { qreal majorTickLength = qMin(rect().width(), rect().height()) * .02; //two percent qreal minorTickLength = qMin(rect().width(), rect().height()) * 0.01; //one percent QRectF rect = plotRect(); _xMajorGridLines.clear(); _xMajorTickLines.clear(); foreach (qreal x, _xAxis->axisMajorTicks()) { QPointF p1 = QPointF(mapXToPlot(x), rect.bottom()); QPointF p2 = p1 - QPointF(0, rect.height()); _xMajorGridLines << QLineF(p1, p2); p2 = p1 - QPointF(0, majorTickLength); _xMajorTickLines << QLineF(p1, p2); p1.setY(rect.top()); p2 = p1 + QPointF(0, majorTickLength); _xMajorTickLines << QLineF(p1, p2); } _xMinorGridLines.clear(); _xMinorTickLines.clear(); foreach (qreal x, _xAxis->axisMinorTicks()) { QPointF p1 = QPointF(mapXToPlot(x), rect.bottom()); QPointF p2 = p1 - QPointF(0, rect.height()); _xMinorGridLines << QLineF(p1, p2); p2 = p1 - QPointF(0, minorTickLength); _xMinorTickLines << QLineF(p1, p2); p1.setY(rect.top()); p2 = p1 + QPointF(0, minorTickLength); _xMinorTickLines << QLineF(p1, p2); } _xPlotMarkerLines.clear(); foreach (double x, _xAxis->axisPlotMarkers().markers()) { if (x > _xMin && x < _xMax) { QPointF p1 = QPointF(mapXToPlot(x), rect.bottom()); QPointF p2 = p1 - QPointF(0, rect.height()); _xPlotMarkerLines << QLineF(p1, p2); } } } void PlotItem::updateXAxisLabels(QPainter* painter) { int flags = Qt::TextSingleLine | Qt::AlignCenter; _xPlotLabels.clear(); int rotation = _xAxis->axisLabelRotation(); painter->save(); QTransform t; t.rotate(rotation); QMapIterator xLabelIt(_xAxis->axisLabels()); while (xLabelIt.hasNext()) { xLabelIt.next(); QRectF bound = painter->boundingRect(QRectF(), flags, xLabelIt.value()); QPointF p; if (rotation == 0) { p = QPointF(mapXToPlot(xLabelIt.key()), plotRect().bottom() + bound.height()*0.5 + _calculatedAxisMarginVLead); bound.moveCenter(p); } else { if (rotation < 0) { qreal theta = (rotation >-30 ? rotation : -30); qreal right = mapXToPlot(xLabelIt.key()) - bound.height() * (sin(theta*M_PI/180.0)); bound = t.mapRect(bound); p = QPointF(right, plotRect().bottom() + _calculatedAxisMarginVLead); bound.moveTopRight(p); } else { qreal theta = (rotation <30 ? rotation : 30); qreal left = mapXToPlot(xLabelIt.key()) - bound.height() * (sin(theta*M_PI/180.0)); bound = t.mapRect(bound); p = QPointF(left, plotRect().bottom() + _calculatedAxisMarginVLead); bound.moveTopLeft(p); } } if (rect().left() > bound.left()) { bound.setLeft(rect().left()); } if (rect().right() >= bound.right()) { // if no overflow to the right... CachedPlotLabel label; label.bound = bound; label.value = xLabelIt.value(); _xPlotLabels.append(label); } } painter->restore(); if (!_xAxis->baseLabel().isEmpty()) { QRectF bound = painter->boundingRect(QRectF(), flags, _xAxis->baseLabel()); QPointF p = QPointF(plotRect().left(), plotRect().bottom() + bound.height() * 2.0 + _calculatedAxisMarginVLead); bound.moveBottomLeft(p); CachedPlotLabel label; label.bound = bound; label.value = _xAxis->baseLabel(); label.baseLabel = true; _xPlotLabels.append(label); } } void PlotItem::setPlotRectsDirty() { _plotRectsDirty = true; xAxis()->setTicksUpdated(); yAxis()->setTicksUpdated(); setPlotPixmapDirty(); } void PlotItem::updateYAxisLines() { qreal majorTickLength = qMin(rect().width(), rect().height()) * .02; //two percent qreal minorTickLength = qMin(rect().width(), rect().height()) * 0.01; //one percent QRectF rect = plotRect(); _yMajorGridLines.clear(); _yMajorTickLines.clear(); foreach (qreal y, _yAxis->axisMajorTicks()) { QPointF p1 = QPointF(rect.left(), mapYToPlot(y)); QPointF p2 = p1 + QPointF(rect.width(), 0); _yMajorGridLines << QLineF(p1, p2); p2 = p1 + QPointF(majorTickLength, 0); _yMajorTickLines << QLineF(p1, p2); p1.setX(rect.right()); p2 = p1 - QPointF(majorTickLength, 0); _yMajorTickLines << QLineF(p1, p2); } _yMinorGridLines.clear(); _yMinorTickLines.clear(); foreach (qreal y, _yAxis->axisMinorTicks()) { QPointF p1 = QPointF(rect.left(), mapYToPlot(y)); QPointF p2 = p1 + QPointF(rect.width(), 0); _yMinorGridLines << QLineF(p1, p2); p2 = p1 + QPointF(minorTickLength, 0); _yMinorTickLines << QLineF(p1, p2); p1.setX(rect.right()); p2 = p1 - QPointF(minorTickLength, 0); _yMinorTickLines << QLineF(p1, p2); } _yPlotMarkerLines.clear(); foreach (double y, _yAxis->axisPlotMarkers().markers()) { if (y > _yMin && y < _yMax) { QPointF p1 = QPointF(rect.left(), mapYToPlot(y)); QPointF p2 = p1 + QPointF(rect.width(), 0); _yPlotMarkerLines << QLineF(p1, p2); } } } void PlotItem::updateYAxisLabels(QPainter* painter) { int flags = Qt::TextSingleLine | Qt::AlignCenter; _yPlotLabels.clear(); int rotation = _yAxis->axisLabelRotation(); QTransform t; t.rotate(rotation); QMapIterator yLabelIt(_yAxis->axisLabels()); while (yLabelIt.hasNext()) { yLabelIt.next(); QRectF bound = painter->boundingRect(QRectF(), flags, yLabelIt.value()); QPointF p; if (rotation < 0) { qreal theta = (rotation >-45.0) ? rotation : -45.0; qreal top; if (rotation >-89) { top = mapYToPlot(yLabelIt.key()) - bound.height()*0.5*cos(theta*2.0*M_PI/180.0); } else { top = mapYToPlot(yLabelIt.key()) - bound.width()*0.5; } bound = t.mapRect(bound); bound.moveRight(plotRect().left() - _calculatedAxisMarginHLead); bound.moveTop(top); } else if (rotation > 0) { qreal theta = (rotation <45.0) ? rotation : 45.0; qreal bottom; if (rotation < 89) { bottom = mapYToPlot(yLabelIt.key()) + bound.height()*0.5*cos(theta*2.0*M_PI/180.0); } else { bottom = mapYToPlot(yLabelIt.key()) + bound.width()*0.5; } bound = t.mapRect(bound); bound.moveRight(plotRect().left() - _calculatedAxisMarginHLead); bound.moveBottom(bottom); } else { // no rotation. p = QPointF(plotRect().left() - _calculatedAxisMarginHLead, mapYToPlot(yLabelIt.key()) - bound.height() * 0.5); bound.moveTopRight(p); } if (rect().top() > bound.top()) bound.setTop(rect().top()); if (rect().bottom() < bound.bottom()) bound.setBottom(rect().bottom()); CachedPlotLabel label; label.bound = bound; label.value = yLabelIt.value(); _yPlotLabels.append(label); } if (!_yAxis->baseLabel().isEmpty()) { painter->save(); painter->rotate(-90.0); QRectF bound = painter->boundingRect(QRectF(), flags, _yAxis->baseLabel()); bound = QRectF(bound.x(), bound.bottomRight().y() - bound.width(), bound.height(), bound.width()); QPointF p = QPointF(rect().left() + _calculatedLeftBaseOffset, plotRect().bottom()); bound.moveBottomLeft(p); CachedPlotLabel label; label.bound = bound; label.value = _yAxis->baseLabel(); label.baseLabel = true; _yPlotLabels.append(label); painter->restore(); } } void PlotItem::paintMajorGridLines(QPainter *painter) { if (xAxis()->drawAxisMajorGridLines()) { painter->save(); painter->setPen(QPen(QBrush(_xAxis->axisMajorGridLineColor()), _xAxis->axisMajorGridLineWidth(), _xAxis->axisMajorGridLineStyle())); painter->drawLines(_xMajorGridLines); painter->restore(); } if (yAxis()->drawAxisMajorGridLines()) { painter->save(); painter->setPen(QPen(QBrush(_yAxis->axisMajorGridLineColor()), _yAxis->axisMajorGridLineWidth(), _yAxis->axisMajorGridLineStyle())); painter->drawLines(_yMajorGridLines); painter->restore(); } } void PlotItem::paintMinorGridLines(QPainter *painter) { if (xAxis()->drawAxisMinorGridLines()) { painter->save(); painter->setPen(QPen(QBrush(_xAxis->axisMinorGridLineColor()), _xAxis->axisMinorGridLineWidth(), _xAxis->axisMinorGridLineStyle())); painter->drawLines(_xMinorGridLines); painter->restore(); } if (yAxis()->drawAxisMinorGridLines()) { painter->save(); painter->setPen(QPen(QBrush(_yAxis->axisMinorGridLineColor()), _yAxis->axisMinorGridLineWidth(), _yAxis->axisMinorGridLineStyle())); painter->drawLines(_yMinorGridLines); painter->restore(); } } void PlotItem::paintMajorTicks(QPainter *painter) { if (xAxis()->drawAxisMajorTicks()) { painter->drawLines(_xMajorTickLines); } if (yAxis()->drawAxisMajorTicks()) { painter->drawLines(_yMajorTickLines); } } void PlotItem::paintMinorTicks(QPainter *painter) { if (xAxis()->drawAxisMinorTicks()) { painter->drawLines(_xMinorTickLines); } if (yAxis()->drawAxisMinorTicks()) { painter->drawLines(_yMinorTickLines); } } void PlotItem::scaleAxisLabels(qreal scaleFactor) { _numberAxisLabelScaleFactor = qMin(_numberAxisLabelScaleFactor, scaleFactor); } void PlotItem::resetScaleAxisLabels() { _numberAxisLabelScaleFactor = 1.0; } bool PlotItem::isUseAxisScale() const { return _useNumberAxisLabelScale; } void PlotItem::setUseAxisScale(bool useScale) { if (_useNumberAxisLabelScale != useScale) { _useNumberAxisLabelScale = useScale; setPlotPixmapDirty(); } } void PlotItem::paintBottomTickLabels(QPainter *painter) { int flags = Qt::TextSingleLine/* | Qt::AlignCenter*/; painter->save(); painter->setPen(_numberLabelDetails->fontColor()); int rotation = _xAxis->axisLabelRotation(); foreach(CachedPlotLabel label, _xPlotLabels) { QRectF bound = label.bound; if (_numberAxisLabelScaleFactor<0.9999) { bound.translate( bound.width() *(1.0-_numberAxisLabelScaleFactor)*0.5, 0.0); } if (rotation != 0) { painter->save(); QTransform t; t.rotate(-1*rotation); painter->rotate(rotation); painter->drawText(t.mapRect(bound), Qt::TextSingleLine | Qt::AlignCenter, label.value); painter->restore(); } else { painter->drawText(bound, flags, label.value); } } painter->restore(); } void PlotItem::paintLeftTickLabels(QPainter *painter) { int flags = Qt::TextSingleLine | Qt::AlignVCenter | Qt::AlignRight; painter->save(); painter->setPen(_numberLabelDetails->fontColor()); int rotation = _yAxis->axisLabelRotation(); foreach(CachedPlotLabel label, _yPlotLabels) { if (label.baseLabel) { painter->save(); QTransform t; t.rotate(90.0); painter->rotate(-90.0); painter->drawText(t.mapRect(label.bound), flags, label.value); painter->restore(); } else { if (rotation != 0) { painter->save(); QTransform t; t.rotate(-1*rotation); painter->rotate(rotation); painter->drawText(t.mapRect(label.bound), flags, label.value); painter->restore(); } else { painter->drawText(label.bound, flags, label.value); } } } painter->restore(); #if DEBUG_LABEL_REGION QRectF yLabelRect; foreach(CachedPlotLabel label, _yPlotLabels) { if (yLabelRect.isValid()) { yLabelRect = yLabelRect.united(label.bound); } else { yLabelRect = label.bound; } } painter->save(); painter->setOpacity(0.3); qDebug() << "Left Tick Labels - yLabelRect:" << yLabelRect; painter->fillRect(yLabelRect, Qt::green); painter->restore(); #endif } void PlotItem::paintTickLabels(QPainter *painter) { if (_xAxis->isAxisVisible()) { paintBottomTickLabels(painter); } if (_yAxis->isAxisVisible()) { paintLeftTickLabels(painter); } } void PlotItem::paintPlotMarkers(QPainter *painter) { if (!_xPlotMarkerLines.isEmpty()) { painter->save(); painter->setPen(QPen(QBrush(_xAxis->axisPlotMarkers().lineColor()), _xAxis->axisPlotMarkers().lineWidth(), _xAxis->axisPlotMarkers().lineStyle())); painter->drawLines(_xPlotMarkerLines); painter->restore(); } if (!_yPlotMarkerLines.isEmpty()) { painter->save(); painter->setPen(QPen(QBrush(_yAxis->axisPlotMarkers().lineColor()), _yAxis->axisPlotMarkers().lineWidth(), _yAxis->axisPlotMarkers().lineStyle())); painter->drawLines(_yPlotMarkerLines); painter->restore(); } } void PlotItem::calculatePlotRects() { // Calculate the plotAxisRect first. qreal left = _leftLabelDetails->isVisible() ? leftLabelMargin() : 0.0; qreal bottom = _bottomLabelDetails->isVisible() ? bottomLabelMargin() : 0.0; qreal right = _rightLabelDetails->isVisible() ? rightMarginSize() : 0.0; qreal top = _topLabelDetails->isVisible() ? topMarginSize() : 0.0; QPointF topLeft(rect().topLeft() + QPointF(left, top)); if (_manuallyHideRightAxisLabel && !_isInSharedAxisBox) { right += 1; } if (_manuallyHideBottomAxisLabel && !_isInSharedAxisBox) { bottom += 1; } QPointF bottomRight(rect().bottomRight() - QPointF(right, bottom)); _calculatedPlotAxisRect = QRectF(topLeft, bottomRight); // Use the PlotAxisRect as basis to calculate PlotRect. QRectF plot = _calculatedPlotAxisRect; qreal xOffset = _xAxis->isAxisVisible() ? axisMarginHeight() : 0.0; qreal yOffset = _yAxis->isAxisVisible() ? axisMarginWidth() : 0.0; qreal bottomPadding = _xAxis->isAxisVisible() ? _bottomPadding : 0.0; qreal leftPadding = _yAxis->isAxisVisible() ? _leftPadding : 0.0; qreal rightPadding = _rightLabelDetails->isVisible() ? _rightPadding : 0.0; qreal topPadding = _topLabelDetails->isVisible() ? _topPadding : 0.0; plot.setLeft(plot.left() + yOffset + leftPadding); plot.setBottom(plot.bottom() - xOffset - bottomPadding); plot.setRight(plot.right() - rightPadding); plot.setTop(plot.top() + topPadding); if (!plot.isValid()) { if (plot.width() <= 0) { plot.setWidth(0.1); } if (plot.height() <= 0) { plot.setHeight(0.1); } } _calculatedPlotRect = plot; _plotRectsDirty = false; emit updatePlotRect(); } QRectF PlotItem::plotAxisRect() { if (_plotRectsDirty) { calculatePlotRects(); } return _calculatedPlotAxisRect; } QRectF PlotItem::plotRect() { if (_plotRectsDirty) { calculatePlotRects(); } return _calculatedPlotRect; } qreal PlotItem::leftMarginSize() const { qreal margin = _leftLabelDetails->isVisible() ? leftLabelMargin() : 0.0; margin += _yAxis->isAxisVisible() ? axisMarginWidth() : 0.0; return margin; } qreal PlotItem::bottomMarginSize() const { qreal margin = _bottomLabelDetails->isVisible() ? bottomLabelMargin() : 0.0; margin += _xAxis->isAxisVisible() ? axisMarginHeight() : 0.0; return margin; } qreal PlotItem::rightMarginSize() const { qreal margin = _rightLabelDetails->isVisible() ? rightLabelMargin() : 0.0; if (supportsTiedZoom() && margin < tiedZoomSize().width()) margin = tiedZoomSize().width(); return margin; } qreal PlotItem::topMarginSize() const { qreal margin = _topLabelDetails->isVisible() ? topLabelMargin() : 0.0; if (supportsTiedZoom() && margin < tiedZoomSize().height()) margin = tiedZoomSize().height(); return margin; } void PlotItem::setPadding(const qreal left, const qreal right, const qreal top, const qreal bottom) { if ((left == _leftPadding) && (right == _rightPadding) && (top == _topPadding) && (bottom == _bottomPadding)) { return; } _leftPadding = left; _rightPadding = right; _topPadding = top; _bottomPadding = bottom; setPlotRectsDirty(); emit triggerRedraw(); } void PlotItem::setLeftPadding(const qreal padding) { if (padding != _leftPadding) { _leftPadding = padding; setPlotRectsDirty(); } } void PlotItem::setBottomPadding(const qreal padding) { if (padding != _bottomPadding) { _bottomPadding = padding; setPlotRectsDirty(); } } void PlotItem::setRightPadding(const qreal padding) { if (padding != _rightPadding) { _rightPadding = padding; setPlotRectsDirty(); } } void PlotItem::setTopPadding(const qreal padding) { if (padding != _topPadding) { _topPadding = padding; setPlotRectsDirty(); } } void PlotItem::setManuallyHideLeftAxisLabel(bool hide) { _manuallyHideLeftAxisLabel = hide; if (!_isInSharedAxisBox) { setLeftSuppressed(hide); } } void PlotItem::setManuallyHideRightAxisLabel(bool hide) { _manuallyHideRightAxisLabel = hide; if (!_isInSharedAxisBox) { setRightSuppressed(hide); } } void PlotItem::setManuallyHideTopAxisLabel(bool hide) { _manuallyHideTopAxisLabel = hide; if (!_isInSharedAxisBox) { setTopSuppressed(hide); } } void PlotItem::setManuallyHideBottomAxisLabel(bool hide) { _manuallyHideBottomAxisLabel = hide; if (!_isInSharedAxisBox) { setBottomSuppressed(hide); } } QRectF PlotItem::projectionRect() const { return _projectionRect; } void PlotItem::setTiedZoom(bool tiedXZoom, bool tiedYZoom, bool checkAllTied) { if ((_isXTiedZoom == tiedXZoom) && (_isYTiedZoom == tiedYZoom)) return; bool wasTiedZoom = isTiedZoom(); _isXTiedZoom = tiedXZoom; _isYTiedZoom = tiedYZoom; if (isTiedZoom() && !wasTiedZoom) { PlotItemManager::self()->addTiedZoomPlot(this, checkAllTied); } else if (!isTiedZoom() && wasTiedZoom) { PlotItemManager::self()->removeTiedZoomPlot(this); } //FIXME ugh, this is expensive, but need to redraw the checkboxes... update(); } bool PlotItem::isInSharedAxisBox() const { return _isInSharedAxisBox; } void PlotItem::setInSharedAxisBox(bool inSharedBox) { _isInSharedAxisBox = inSharedBox; setLockParent(inSharedBox); } SharedAxisBoxItem* PlotItem::sharedAxisBox() const { return _sharedBox; } void PlotItem::setSharedAxisBox(SharedAxisBoxItem* parent) { if (parent) { if (isTiedZoom()) { setTiedZoom(false, false); } setInSharedAxisBox(true); setAllowedGripModes(0); setFlags(0); setParentViewItem(parent); setBrush(Qt::transparent); _sharedBox = parent; createSharedAxisBoxMenu(); } else { setSupportsTiedZoom(true); setInSharedAxisBox(false); setAllowedGripModes(Move | Resize | Rotate); setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable); setParentViewItem(0); setBrush(Qt::white); _sharedBox = 0; } } void PlotItem::setPlotBordersDirty(bool dirty) { if (isInSharedAxisBox() && dirty && _sharedBox) { _sharedBox->setDirty(); } else { view()->setPlotBordersDirty(dirty); } if (dirty) { setPlotRectsDirty(); } } void PlotItem::updateScale() { if (_xAxis->axisLog()) { _xMax = logXHi(projectionRect().right()); _xMin = logXLo(projectionRect().left()); } else { _xMax = projectionRect().right(); _xMin = projectionRect().left(); } if (_yAxis->axisLog()) { _yMax = logYHi(projectionRect().bottom()); _yMin = logYLo(projectionRect().top()); } else { _yMax = projectionRect().bottom(); _yMin = projectionRect().top(); } } QRectF PlotItem::mapToProjection(const QRectF &rect) { QRectF projRect; // Invert and convert points. QPointF topLeft; QPointF bottomRight; if (!(_xAxis->axisReversed() || _yAxis->axisReversed())) { topLeft = mapToProjection(rect.bottomLeft()); bottomRight = mapToProjection(rect.topRight()); } else if (_xAxis->axisReversed() && _yAxis->axisReversed()) { topLeft = mapToProjection(rect.topRight()); bottomRight = mapToProjection(rect.bottomLeft()); } else if (_yAxis->axisReversed()) { topLeft = mapToProjection(rect.topLeft()); bottomRight = mapToProjection(rect.bottomRight()); } else { topLeft = mapToProjection(rect.bottomRight()); bottomRight = mapToProjection(rect.topLeft()); } projRect.setTopLeft(topLeft); projRect.setWidth(bottomRight.x() - topLeft.x()); projRect.setHeight(bottomRight.y() - topLeft.y()); return projRect; } QPointF PlotItem::mapToProjection(const QPointF &point) { QRectF pr = plotRect(); double xpos, ypos; updateScale(); if (_xAxis->axisReversed()) { xpos = (double)(pr.right() - point.x())/(double)pr.width(); } else { xpos = (double)(point.x() - pr.left())/(double)pr.width(); } xpos = xpos * (_xMax - _xMin) + _xMin; if (_xAxis->axisLog()) { xpos = pow(10, xpos); } if (_yAxis->axisReversed()) { ypos = (double)(point.y() - pr.top())/(double)pr.height(); } else { ypos = (double)(pr.bottom() - point.y())/(double)pr.height(); } ypos = ypos * (_yMax - _yMin) + _yMin; if (_yAxis->axisLog()) { ypos = pow(10, ypos); } return QPointF(xpos, ypos); } QPointF PlotItem::mapToPlot(const QPointF &point) { return QPointF(mapXToPlot(point.x()), mapYToPlot(point.y())); } qreal PlotItem::mapXToPlot(const qreal &x) { QRectF pr = plotRect(); double newX = x; if (_xAxis->axisLog()) { newX = logXLo(x); } newX -= _xMin; newX = newX / (_xMax - _xMin); newX = newX * pr.width(); if (_xAxis->axisLog() && x == -350) { newX = 0; } if (_xAxis->axisReversed()) { newX = pr.right() - newX; } else { newX = newX + pr.left(); } return newX; } qreal PlotItem::mapYToPlot(const qreal &y) { QRectF pr = plotRect(); double newY = y; if (_yAxis->axisLog()) { newY = logYLo(y); } newY -= _yMin; newY = newY / (_yMax - _yMin); newY = newY * pr.height(); if (_yAxis->axisLog() && y == -350) { newY = 0; } if (_yAxis->axisReversed()) { newY = newY + pr.top(); } else { newY = pr.bottom() - newY; } return newY; } QFont PlotItem::globalFont() const { return _globalFont; } void PlotItem::setGlobalFont(const QFont &font) { if (font != _globalFont) { _globalFont = font; setPlotBordersDirty(true); setLabelsDirty(); } } qreal PlotItem::globalFontScale() const { return _globalFontScale; } void PlotItem::setGlobalFontScale(const qreal scale) { if (scale != _globalFontScale) { _globalFontScale = scale; setPlotBordersDirty(true); setLabelsDirty(); } } QColor PlotItem::globalFontColor() const { return _globalFontColor; } void PlotItem::setGlobalFontColor(const QColor &color) { if (color != _globalFontColor) { _globalFontColor = color; setLabelsDirty(); } } QString PlotItem::leftLabel() const { if (!leftLabelDetails()->isAuto()) { return leftLabelDetails()->text(); } else { return autoLeftLabel(); } } QString PlotItem::autoLeftLabel() const { foreach (PlotRenderItem *renderer, renderItems()) { QString label = renderer->leftLabel(); if (!label.isEmpty()) { if (_yAxis->axisInterpret()) { // remove units QRegExp rx(" \\[*\\]"); rx.setPatternSyntax(QRegExp::Wildcard); return label.remove(rx); } else { return label; } } } return QString(); } QString PlotItem::bottomLabel() const { if (!bottomLabelDetails()->isAuto()) { return bottomLabelDetails()->text(); } else { return autoBottomLabel(); } } QString PlotItem::autoBottomLabel() const { foreach (PlotRenderItem *renderer, renderItems()) { QString label = renderer->bottomLabel(); if (!label.isEmpty()) { if (_xAxis->axisInterpret()) { // remove units if time interpretation QRegExp rx(" \\[*\\]"); rx.setPatternSyntax(QRegExp::Wildcard); return label.remove(rx); } else { return label; } } } return QString(); } QString PlotItem::rightLabel() const { if (!rightLabelDetails()->isAuto()) { return rightLabelDetails()->text(); } else { return autoRightLabel(); } } QString PlotItem::autoRightLabel() const { foreach (PlotRenderItem *renderer, renderItems()) { QString label = renderer->rightLabel(); if (!label.isEmpty()) return label; } return QString(); } QString PlotItem::topLabel() const { if (!topLabelDetails()->isAuto()) { return topLabelDetails()->text(); } else { return autoTopLabel(); } } QString PlotItem::autoTopLabel() const { if (showLegend()) { return QString(); } else { QString label; int count = renderItems().count(); for (int i=0; itopLabel(); if (isetVisible(!suppressed); } void PlotItem::setRightSuppressed(bool suppressed) { if (!_isInSharedAxisBox) { if (_manuallyHideRightAxisLabel) { suppressed = true; } } _rightLabelDetails->setVisible(!suppressed); } void PlotItem::setLeftSuppressed(bool suppressed) { if (!_isInSharedAxisBox) { if (_manuallyHideLeftAxisLabel) { suppressed = true; } } _leftLabelDetails->setVisible(!suppressed); _yAxis->setAxisVisible(!suppressed); } void PlotItem::setBottomSuppressed(bool suppressed) { if (!_isInSharedAxisBox) { if (_manuallyHideBottomAxisLabel) { suppressed = true; } } _bottomLabelDetails->setVisible(!suppressed); _xAxis->setAxisVisible(!suppressed); } void PlotItem::setLabelsVisible(bool visible) { _leftLabelDetails->setVisible(visible); _rightLabelDetails->setVisible(visible); _topLabelDetails->setVisible(visible); _bottomLabelDetails->setVisible(visible); _xAxis->setAxisVisible(visible); _yAxis->setAxisVisible(visible); } qreal PlotItem::labelMarginWidth() const { return _calculatedLabelMarginWidth; } qreal PlotItem::leftLabelMargin() const { return _calculatedLeftLabelMargin; } qreal PlotItem::rightLabelMargin() const { return _calculatedRightLabelMargin; } qreal PlotItem::labelMarginHeight() const { return _calculatedLabelMarginHeight; } qreal PlotItem::topLabelMargin() const { return _calculatedTopLabelMargin; } qreal PlotItem::bottomLabelMargin() const { return _calculatedBottomLabelMargin; } QRectF PlotItem::topLabelRect() const { if (topLabelMargin()>0) { return QRectF(0.0, 0.0, width() - leftLabelMargin() - rightLabelMargin(), topLabelMargin()); } else { return QRectF(0.0, 0.0, width() - leftLabelMargin() - rightLabelMargin(), _calculatedTopLabelHeight); } } QRectF PlotItem::bottomLabelRect() const { return QRectF(0.0, 0.0, width() - leftLabelMargin() - rightLabelMargin(), bottomLabelMargin()); } QRectF PlotItem::leftLabelRect() const { return QRectF(0.0, 0.0, leftLabelMargin(), height() - topLabelMargin() - bottomLabelMargin()); } QRectF PlotItem::rightLabelRect() const { return QRectF(0.0, 0.0, rightLabelMargin(), height() - topLabelMargin() - bottomLabelMargin()); } void PlotItem::generateLeftLabel() { if (!_leftLabel.dirty) { return; } _leftLabel.valid = false; _leftLabel.dirty = false; Label::Parsed *parsed = Label::parse(leftLabel()); if (parsed) { parsed->chunk->attributes.color = _leftLabelDetails->fontColor(); if (_leftLabel.rc) { delete _leftLabel.rc; } Label::RenderContext *rc = new Label::RenderContext(leftLabelDetails()->calculatedFont(), 0); QFontMetrics fm(leftLabelDetails()->calculatedFont()); rc->y = fm.ascent(); Label::renderLabel(*rc, parsed->chunk); QTransform t; t.translate(rect().left(),plotRect().center().y() + rc->x/2); t.rotate(-90.0); connect(rc, SIGNAL(labelDirty()), this, SLOT(setLeftLabelDirty())); connect(rc, SIGNAL(labelDirty()), this, SLOT(redrawPlot())); _leftLabel.rc = rc; _leftLabel.transform = t; _leftLabel.valid = true; delete parsed; } } void PlotItem::paintLeftLabel(QPainter *painter) { if (!_leftLabelDetails->isVisible() || leftLabel().isEmpty()) return; generateLeftLabel(); if (_leftLabel.valid) { painter->save(); painter->setTransform(_leftLabel.transform, true); Label::paintLabel(*_leftLabel.rc, painter); painter->restore(); } } void PlotItem::calculateLeftLabelMargin(QPainter *painter) { if (!_leftLabelDetails->isVisible()) { _calculatedLeftLabelMargin = 0; } else { painter->save(); QTransform t; t.rotate(90.0); painter->rotate(-90.0); painter->setFont(leftLabelDetails()->calculatedFont()); QRectF leftLabelBound = painter->boundingRect(t.mapRect(leftLabelRect()), Qt::AlignCenter, leftLabel()); painter->restore(); _calculatedLeftLabelMargin = leftLabelBound.height(); _calculatedLeftLabelWidth = leftLabelBound.width(); //No more than 1/4 the width of the plot if (width() < _calculatedLeftLabelMargin * 4) _calculatedLeftLabelMargin = width() / 4; } } void PlotItem::generateBottomLabel() { if (!_bottomLabel.dirty) { return; } _bottomLabel.valid = false; _bottomLabel.dirty = false; Label::Parsed *parsed = Label::parse(bottomLabel()); if (parsed) { parsed->chunk->attributes.color = _bottomLabelDetails->fontColor(); if (_bottomLabel.rc) { delete _bottomLabel.rc; } Label::RenderContext *rc = new Label::RenderContext(bottomLabelDetails()->calculatedFont(), 0); QFontMetrics fm(bottomLabelDetails()->calculatedFont()); rc->y = fm.ascent(); Label::renderLabel(*rc, parsed->chunk); QTransform t; t.translate(plotRect().center().x() - rc->x / 2, plotAxisRect().bottom()); connect(rc, SIGNAL(labelDirty()), this, SLOT(setBottomLabelDirty())); connect(rc, SIGNAL(labelDirty()), this, SLOT(redrawPlot())); _bottomLabel.rc = rc; _bottomLabel.transform = t; _bottomLabel.valid = true; delete parsed; } } void PlotItem::paintBottomLabel(QPainter *painter) { if (!_bottomLabelDetails->isVisible() || bottomLabel().isEmpty()) return; generateBottomLabel(); if (_bottomLabel.valid) { painter->save(); painter->setTransform(_bottomLabel.transform, true); Label::paintLabel(*_bottomLabel.rc, painter); painter->restore(); } #if DEBUG_LABEL_REGION painter->save(); QRectF bottomLabel = bottomLabelRect(); bottomLabel.moveTopLeft(plotAxisRect().bottomLeft()); painter->save(); painter->setOpacity(0.3); qDebug() << "bottomLabel:" << bottomLabel; painter->fillRect(bottomLabel, Qt::red); painter->restore(); painter->restore(); #endif } void PlotItem::calculateBottomLabelMargin(QPainter *painter) { if (!_bottomLabelDetails->isVisible()) { _calculatedBottomLabelMargin = 0; } else { painter->save(); painter->setFont(bottomLabelDetails()->calculatedFont()); QRectF bottomLabelBound = painter->boundingRect(bottomLabelRect(), Qt::AlignCenter, bottomLabel()); painter->restore(); _calculatedBottomLabelMargin = bottomLabelBound.height(); _calculatedBottomLabelWidth = bottomLabelBound.width(); //No more than 1/4 the height of the plot if (height() < _calculatedBottomLabelMargin * 4) _calculatedLeftLabelMargin = height() / 4; } } void PlotItem::generateRightLabel() { if (!_rightLabel.dirty) { return; } _rightLabel.valid = false; _rightLabel.dirty = false; Label::Parsed *parsed = Label::parse(rightLabel()); if (parsed && rightLabelRect().isValid()) { parsed->chunk->attributes.color = _rightLabelDetails->fontColor(); if (_rightLabel.parsed) { delete _rightLabel.parsed; } Label::RenderContext *rc = new Label::RenderContext(rightLabelDetails()->calculatedFont(), 0); QFontMetrics fm(rightLabelDetails()->calculatedFont()); rc->y = fm.ascent(); Label::renderLabel(*rc, parsed->chunk); QTransform t; t.translate(rect().right(), plotRect().center().y() - rc->x/2); t.rotate(90.0); connect(rc, SIGNAL(labelDirty()), this, SLOT(setRightLabelDirty())); connect(rc, SIGNAL(labelDirty()), this, SLOT(redrawPlot())); _rightLabel.rc = rc; _rightLabel.transform = t; _rightLabel.valid = true; delete parsed; } } void PlotItem::paintRightLabel(QPainter *painter) { if (!_rightLabelDetails->isVisible() || rightLabel().isEmpty()) return; generateRightLabel(); if (_rightLabel.valid) { painter->save(); painter->setTransform(_rightLabel.transform, true); Label::paintLabel(*_rightLabel.rc, painter); painter->restore(); } #if DEBUG_LABEL_REGION painter->save(); QTransform t; t.rotate(-90.0); painter->rotate(90.0); QRectF rightLabel = rightLabelRect(); rightLabel.moveTopLeft(plotAxisRect().topRight()); painter->save(); painter->setOpacity(0.3); qDebug() << "rightLabel:" << t.mapRect(rightLabel)<< endl; painter->fillRect(t.mapRect(rightLabel), Qt::red); painter->restore(); painter->restore(); #endif } void PlotItem::calculateRightLabelMargin(QPainter *painter) { if (!_rightLabelDetails->isVisible()) { _calculatedRightLabelMargin = 0; } else { painter->save(); QTransform t; t.rotate(-90.0); painter->rotate(90.0); painter->setFont(rightLabelDetails()->calculatedFont()); QRectF rightLabelBound = painter->boundingRect(t.mapRect(rightLabelRect()), Qt::AlignCenter, rightLabel()); painter->restore(); _calculatedRightLabelMargin = qMax(_calculatedAxisMarginROverflow, rightLabelBound.height()); //No more than 1/4 the width of the plot if (width() < _calculatedRightLabelMargin * 4) _calculatedRightLabelMargin = width() / 4; } } void PlotItem::generateTopLabel() { if (!_topLabel.dirty) { return; } _topLabel.valid = false; _topLabel.dirty = false; Label::Parsed *parsed = Label::parse(topLabel()); if (parsed && topLabelRect().isValid()) { parsed->chunk->attributes.color = _topLabelDetails->fontColor(); if (_topLabel.rc) { delete _topLabel.rc; } Label::RenderContext *rc = new Label::RenderContext(topLabelDetails()->calculatedFont(), 0); QFontMetrics fm(topLabelDetails()->calculatedFont()); rc->y = fm.ascent(); Label::renderLabel(*rc, parsed->chunk); QTransform t; if (_topLabelDetails->isVisible()) { t.translate(plotRect().center().x() - rc->x / 2, rect().top()); } else { t.translate(plotRect().center().x() - rc->x / 2, rect().top() + topLabelRect().height()/2); } connect(rc, SIGNAL(labelDirty()), this, SLOT(setTopLabelDirty())); connect(rc, SIGNAL(labelDirty()), this, SLOT(redrawPlot())); _topLabel.rc = rc; _topLabel.transform = t; _topLabel.valid = true; delete parsed; } } void PlotItem::paintTopLabel(QPainter *painter) { if (topLabel().isEmpty()) return; generateTopLabel(); if (_topLabel.valid) { painter->save(); painter->setTransform(_topLabel.transform, true); Label::paintLabel(*_topLabel.rc, painter); painter->restore(); } #if DEBUG_LABEL_REGION painter->save(); QRectF topLabel = topLabelRect(); topLabel.moveBottomLeft(plotAxisRect().topLeft()); painter->save(); painter->setOpacity(0.3); qDebug() << "topLabel:" << topLabel; painter->fillRect(topLabel, Qt::red); painter->restore(); painter->restore(); #endif } void PlotItem::calculateTopLabelMargin(QPainter *painter) { painter->save(); painter->setFont(topLabelDetails()->calculatedFont()); QRectF topLabelBound = painter->boundingRect(topLabelRect(), Qt::AlignCenter, topLabel()); painter->restore(); _calculatedTopLabelHeight = topLabelBound.height(); if (!_topLabelDetails->isVisible()) { _calculatedTopLabelMargin = 0; } else { _calculatedTopLabelMargin = qMax(_calculatedAxisMarginTOverflow, topLabelBound.height()); //No more than 1/4 the height of the plot if (height() < _calculatedTopLabelMargin * 4) _calculatedTopLabelMargin = height() / 4; } } void PlotItem::calculateMargins() { qreal m = qMax(_calculatedLeftLabelMargin, _calculatedRightLabelMargin); //No more than 1/4 the width of the plot if (width() < m * 4) m = width() / 4; _calculatedLabelMarginWidth = m; m = qMax(_calculatedTopLabelMargin, _calculatedBottomLabelMargin); //No more than 1/4 the height of the plot if (height() < m * 4) m = height() / 4; _calculatedLabelMarginHeight = m; } qreal PlotItem::axisMarginWidth() const { return _calculatedAxisMarginWidth; } qreal PlotItem::axisMarginHeight() const { return _calculatedAxisMarginHeight; } /** This function calculates and sets three things: _calculatedAxisMarginVLead: spacing between bottom of plotRect and top of axis labels _calculatedAxisMarginROverflow: rightmost axis number extension beyond plotRect _calculatedAxisMarginHeight: the height of the axis numbers */ void PlotItem::calculateBottomTickLabelBound(QPainter *painter) { QRectF xLabelRect; painter->save(); painter->setFont(numberLabelDetails()->calculatedFont()); int flags = Qt::TextSingleLine | Qt::AlignCenter; _calculatedAxisMarginVLead = painter->fontMetrics().boundingRect('0').height()/2; if (_xAxis->isAxisVisible()) { // future potential optimization: only get bounds of the rightmost label // but remember: the axis may be reversed. QMapIterator xLabelIt(_xAxis->axisLabels()); while (xLabelIt.hasNext()) { xLabelIt.next(); QRectF bound = painter->boundingRect(QRectF(), flags, xLabelIt.value()); QPointF p(mapXToPlot(xLabelIt.key()), plotRect().bottom() + bound.height() / 2.0 + _calculatedAxisMarginVLead); bound.moveCenter(p); int rotation = _xAxis->axisLabelRotation(); QTransform t; t.rotate(rotation); if (rotation != 0) { bound.setHeight(t.mapRect(bound).height()); } if (xLabelRect.isValid()) { xLabelRect = xLabelRect.united(bound); } else { xLabelRect = bound; } } } xLabelRect.setHeight(xLabelRect.height() + _calculatedAxisMarginVLead); if (!_xAxis->baseLabel().isEmpty()) { qreal height = painter->boundingRect(QRectF(), flags, _xAxis->baseLabel()).height(); if (painter->boundingRect(QRectF(), flags, _xAxis->baseLabel()).width() + _calculatedBottomLabelWidth/2 + xLabelRect.height()/2 > plotRect().width()/2) { height += bottomLabelMargin(); } if (bottomLabelMargin() < height) { xLabelRect.setHeight(xLabelRect.height() + (height - bottomLabelMargin())); } } _calculatedAxisMarginHeight = xLabelRect.height(); _calculatedAxisMarginROverflow = 2*ViewItem::sizeOfGrip().width(); painter->restore(); } /** This function calculates and sets three things: _calculatedAxisMarginHLead: spacing between left of plotRect and right of axis labels _calculatedAxisMarginVOverflow: topmost axis number extension beyond plotRect _calculatedAxisMarginWidth: the width of the widest axis number */ void PlotItem::calculateLeftTickLabelBound(QPainter *painter) { QRectF yLabelRect; int flags = Qt::TextSingleLine | Qt::AlignCenter; painter->save(); painter->setFont(numberLabelDetails()->calculatedFont()); _calculatedAxisMarginHLead = painter->fontMetrics().boundingRect('[').height()/2; if (_yAxis->isAxisVisible()) { QMapIterator yLabelIt(_yAxis->axisLabels()); while (yLabelIt.hasNext()) { yLabelIt.next(); QRectF bound = painter->boundingRect(QRectF(), flags, yLabelIt.value()); QPointF p(plotRect().left() - bound.width() / 2.0 - _calculatedAxisMarginHLead, mapYToPlot(yLabelIt.key())); bound.moveCenter(p); int rotation = _yAxis->axisLabelRotation(); QTransform t; t.rotate(rotation); if (rotation != 0) { bound.setWidth(t.mapRect(bound).width()); bound.setHeight(t.mapRect(bound).height()); } if (yLabelRect.isValid()) { yLabelRect = yLabelRect.united(bound); } else { yLabelRect = bound; } } } yLabelRect.setWidth(yLabelRect.width() + _calculatedAxisMarginHLead); _calculatedLeftBaseOffset = 0.0; if (!_yAxis->baseLabel().isEmpty()) { qreal height = painter->boundingRect(QRectF(), flags, _yAxis->baseLabel()).height(); if (painter->boundingRect(QRectF(), flags, _yAxis->baseLabel()).width() + _calculatedLeftLabelWidth/2 + yLabelRect.width()/2 > plotRect().height()/2) { height += leftLabelMargin(); _calculatedLeftBaseOffset = leftLabelMargin(); } if (leftLabelMargin() < height) { yLabelRect.setWidth(yLabelRect.width() + (height - leftLabelMargin())); } } _calculatedAxisMarginWidth = yLabelRect.width(); if (yLabelRect.top() < plotRect().top()) { _calculatedAxisMarginTOverflow = qMax(ViewItem::sizeOfGrip().width(), -yLabelRect.top() + plotRect().top()); } else { _calculatedAxisMarginTOverflow = ViewItem::sizeOfGrip().width(); } painter->restore(); } bool PlotItem::showLegend() const { return _showLegend; } LegendItem* PlotItem::legend() { if (!_legend) { _legend = new LegendItem(this); _legend->setVisible(false); _legend->setPos(rect().x() + plotRect().width()*0.05, rect().y() + plotRect().height()*0.15); _legend->updateRelativeSize(); } return _legend; } void PlotItem::setShowLegend(const bool show, const bool resetFonts) { if (show != _showLegend) { legend()->setVisible(show); _showLegend = show; if (show && resetFonts) { legend()->setFontScale(qMax(globalFontScale()*0.6, ApplicationSettings::self()->minimumFontSize())); } } } bool PlotItem::tryShortcut(const QString &keySequence) { return ViewItem::tryShortcut(keySequence); } void PlotItem::setProjectionRect(const QRectF &rect, bool forceAxisUpdate) { if (!(rect.isEmpty() || !rect.isValid())) { _projectionRect = rect; setPlotBordersDirty(true); emit updateAxes(); update(); //slow, but need to update everything... } else if (forceAxisUpdate) { setPlotBordersDirty(true); emit updateAxes(); update(); //slow, but need to update everything... } } QRectF PlotItem::computedProjectionRect() { QRectF rect; foreach (PlotRenderItem *renderer, renderItems()) { if (!renderer->computedProjectionRect().isEmpty()) { if (rect.isValid()) { rect = rect.united(renderer->computedProjectionRect()); } else { rect = renderer->computedProjectionRect(); } } } if (!rect.isValid()) rect = QRectF(QPointF(-0.1, -0.1), QPointF(0.1, 0.1)); //default return rect; } void PlotItem::computedRelationalMax(qreal &minimum, qreal &maximum) { QRectF rect; foreach (PlotRenderItem *renderer, renderItems()) { foreach (RelationPtr relation, renderer->relationList()) { if (relation->ignoreAutoScale()) continue; qreal min, max; relation->yRange(projectionRect().left(), projectionRect().right(), &min, &max); //If the axis is in log mode, the lower extent will be the //minimum value larger than zero. if (yAxis()->axisLog()) minimum = minimum <= 0.0 ? min : qMin(min, minimum); else minimum = qMin(min, minimum); maximum = qMax(max, maximum); } } } void PlotItem::computeBorder(Qt::Orientation orientation, qreal &minimum, qreal &maximum) const { QRectF rect; foreach (PlotRenderItem *renderer, renderItems()) { qreal min = maximum; qreal max = minimum; renderer->computeBorder(orientation, &min, &max); minimum = qMin(min, minimum); maximum = qMax(max, maximum); } } void PlotItem::resetSelectionRect() { foreach (PlotRenderItem *renderer, renderItems()) { renderer->resetSelectionRect(); } } void PlotItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { if (checkBox().contains(event->pos())) { setTiedZoom(!isTiedZoom(), !isTiedZoom()); ViewItem::mousePressEvent(event); } else if (view()->viewMode() == View::Data) { edit(); } else { ViewItem::mousePressEvent(event); } } } QPainterPath PlotItem::checkBox() const { if (!isInSharedAxisBox() || (sharedAxisBox() && sharedAxisBox()->isXAxisShared() && sharedAxisBox()->isYAxisShared())) { return ViewItem::checkBox(); } else { QRectF bound = selectBoundingRect(); QRectF grip; if (sharedAxisBox()->isXAxisShared()) { grip = QRectF(QPointF(_calculatedPlotRect.topRight().x() + sizeOfGrip().width() * .25, _calculatedPlotRect.topRight().y() - sizeOfGrip().height() * -.25), sizeOfGrip()); } else if (sharedAxisBox()->isYAxisShared()) { grip = QRectF(QPointF(_calculatedPlotRect.topRight().x() - sizeOfGrip().width() * 1.25, _calculatedPlotRect.topRight().y() - sizeOfGrip().height() * 1.25), sizeOfGrip()); } QPainterPath path; path.addEllipse(grip); return path; } } QPainterPath PlotItem::tiedZoomCheck() const { if (!isInSharedAxisBox() || (sharedAxisBox() && sharedAxisBox()->isXAxisShared() && sharedAxisBox()->isYAxisShared())) { return ViewItem::tiedZoomCheck(); } else { QRectF bound = selectBoundingRect(); QRectF grip; if (sharedAxisBox()->isXAxisShared()) { grip = QRectF(QPointF(_calculatedPlotRect.topRight().x() + sizeOfGrip().width() * .25, _calculatedPlotRect.topRight().y() - sizeOfGrip().height() * -.25), sizeOfGrip()); } else if (sharedAxisBox()->isYAxisShared()) { grip = QRectF(QPointF(_calculatedPlotRect.topRight().x() - sizeOfGrip().width() * 1.25, _calculatedPlotRect.topRight().y() - sizeOfGrip().height() * 1.25), sizeOfGrip()); } QPainterPath path; if (isXTiedZoom() && isYTiedZoom()) { path.addEllipse(grip); } else if (isXTiedZoom()) { path.moveTo(grip.center()); path.arcTo(grip, 225, 180); } else if (isYTiedZoom()) { path.moveTo(grip.center()); path.arcTo(grip, 45, 180); } return path; } } bool PlotItem::supportsTiedZoom() const { if (isInSharedAxisBox()) { if (sharedAxisBox() && sharedAxisBox()->isXAxisShared() && sharedAxisBox()->isYAxisShared() && sharedAxisBox()->keyPlot() == this) { return true; } } return ViewItem::supportsTiedZoom(); } void PlotItem::setAllowUpdates(bool allowed) { _allowUpdates = allowed; UpdateManager::self()->doUpdates(true); } void PlotItem::plotMaximize() { if (!_plotMaximized && view()->viewMode() != View::Data) { return; } if (_plotMaximized) { double x_rescale; double y_rescale; x_rescale = view()->sceneRect().width()/_plotMaximizedSourceParentRect.width(); y_rescale = view()->sceneRect().height()/_plotMaximizedSourceParentRect.height(); _plotMaximizedSourceRect.setWidth(_plotMaximizedSourceRect.width()*x_rescale); _plotMaximizedSourceRect.setHeight(_plotMaximizedSourceRect.height()*y_rescale); _plotMaximizedSourcePosition.setX(_plotMaximizedSourcePosition.x()*x_rescale); _plotMaximizedSourcePosition.setY(_plotMaximizedSourcePosition.y()*y_rescale); xAxis()->setAxisVisible(_plotMaximizedBottomVisible); yAxis()->setAxisVisible(_plotMaximizedLeftVisible); _leftLabelDetails->setVisible(_plotMaximizedLeftVisible); _bottomLabelDetails->setVisible(_plotMaximizedBottomVisible); _rightLabelDetails->setVisible(_plotMaximizedRightVisible); _topLabelDetails->setVisible(_plotMaximizedTopVisible); _plotMaximized = false; PlotItemManager::self()->removeFocusPlot(this); setParentViewItem(_plotMaximizedSourceParent); setPos(_plotMaximizedSourcePosition); setViewRect(_plotMaximizedSourceRect); setZValue(_plotMaximizedSourceZValue); view()->setChildMaximized(false); view()->setFontRescale(1.0); } else { _plotMaximizedBottomVisible = _bottomLabelDetails->isVisible(); xAxis()->setAxisVisible(true); _bottomLabelDetails->setVisible(true); _plotMaximizedLeftVisible = _leftLabelDetails->isVisible(); yAxis()->setAxisVisible(true); _leftLabelDetails->setVisible(true); _plotMaximizedRightVisible = _rightLabelDetails->isVisible(); _rightLabelDetails->setVisible(true); _plotMaximizedTopVisible = _topLabelDetails->isVisible(); _topLabelDetails->setVisible(true); _plotMaximized = true; _plotMaximizedSourcePosition = pos(); _plotMaximizedSourceRect = viewRect(); _plotMaximizedSourceZValue = zValue(); _plotMaximizedSourceParent = parentViewItem(); _plotMaximizedSourceParentRect = view()->sceneRect(); setParentViewItem(0); setPos(0, 0); setViewRect(view()->sceneRect()); setZValue(PLOT_MAXIMIZED_ZORDER); PlotItemManager::self()->setFocusPlot(this); double rescale = double(view()->sceneRect().width() + view()->sceneRect().height())/ double(_plotMaximizedSourceRect.width() + _plotMaximizedSourceRect.height()); view()->setChildMaximized(true); view()->setFontRescale(rescale); } if (isInSharedAxisBox()) { view()->setPlotBordersDirty(true); } setPlotBordersDirty(); } void PlotItem::zoomFixedExpression(const QRectF &projection, bool force) { #if DEBUG_ZOOM qDebug() << "zoomFixedExpression" << projection << "current" << projectionRect(); #endif if (projection.isValid()) { if (isInSharedAxisBox()) { if (!force) { sharedAxisBox()->zoomFixedExpression(projection, this); } else { yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); setProjectionRect(QRectF(projection.x(), projection.y(), projection.width(), projection.height())); } } else { ZoomCommand *cmd = new ZoomFixedExpressionCommand(this, projection, force); _undoStack->push(cmd); cmd->redo(); } } } void PlotItem::zoomXRange(const QRectF &projection, bool force) { #if DEBUG_ZOOM qDebug() << "zoomXRange" << projection << endl; #endif if (projection.isValid()) { if (isInSharedAxisBox()) { if (!force) { qDebug() << "zoom X range: telling shared axis box"; sharedAxisBox()->zoomXRange(projection, this); } else { xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); setProjectionRect(QRectF(projection.x(), projectionRect().y(), projection.width(), projectionRect().height())); } } else { ZoomCommand *cmd = new ZoomXRangeCommand(this, projection, force); _undoStack->push(cmd); cmd->redo(); } } } void PlotItem::zoomYRange(const QRectF &projection, bool force) { #if DEBUG_ZOOM qDebug() << "zoomYRange" << projection << endl; #endif if (projection.isValid()) { if (isInSharedAxisBox()) { if (!force) { sharedAxisBox()->zoomYRange(projection, this); } else { yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); setProjectionRect(QRectF(projectionRect().x(), projection.y(), projectionRect().width(), projection.height())); } } else { ZoomCommand *cmd = new ZoomYRangeCommand(this, projection, force); _undoStack->push(cmd); cmd->redo(); } } } void PlotItem::zoomMaximum(bool force) { #if DEBUG_ZOOM qDebug() << "zoomMaximum" << endl; #endif if (isInSharedAxisBox() && (!force)) { sharedAxisBox()->zoomMaximum(this); } else { ZoomCommand *cmd = new ZoomMaximumCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::adjustImageColorScale() { const double per[] = {0.0, 0.0001, 0.001, 0.005, 0.02}; const int length = sizeof(per) / sizeof(double); if (++_i_per >= length) { _i_per = 0; } foreach (PlotRenderItem *renderer, renderItems()) { foreach (RelationPtr relation, renderer->relationList()) { if (ImagePtr image = kst_cast(relation)) { image->writeLock(); image->setThresholdToSpikeInsensitive(per[_i_per]); image->registerChange(); image->unlock(); } } } UpdateManager::self()->doUpdates(true); } void PlotItem::zoomMaxSpikeInsensitive(bool force) { #if DEBUG_ZOOM qDebug() << "zoomMaxSpikeInsensitive" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomMaxSpikeInsensitive(this); } else { ZoomCommand *cmd = new ZoomMaxSpikeInsensitiveCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomPrevious() { #if DEBUG_ZOOM qDebug() << "zoomPrevious" << endl; #endif if (!isInSharedAxisBox()) { if (_undoStack->canUndo()) { QAction *undoAction = _undoStack->createUndoAction(this); if (undoAction) { undoAction->activate(QAction::Trigger); } } } } void PlotItem::zoomTied() { #if DEBUG_ZOOM qDebug() << "zoomTied" << endl; #endif setTiedZoom(!isTiedZoom(), !isTiedZoom()); } void PlotItem::zoomXTied() { #if DEBUG_ZOOM qDebug() << "zoomXTied" << endl; #endif setTiedZoom(!isXTiedZoom(), isYTiedZoom()); } void PlotItem::zoomYTied() { #if DEBUG_ZOOM qDebug() << "zoomYTied" << endl; #endif setTiedZoom(isXTiedZoom(), !isYTiedZoom()); } void PlotItem::zoomMeanCentered(bool force) { #if DEBUG_ZOOM qDebug() << "zoomMeanCentered" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomMeanCentered(this); } else { ZoomCommand *cmd = new ZoomMeanCenteredCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYMeanCentered(qreal dY, bool force) { #if DEBUG_ZOOM qDebug() << "zoomYMeanCentered" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYMeanCentered(this); } else { ZoomCommand *cmd = new ZoomYMeanCenteredCommand(this, dY, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomXMeanCentered(qreal dX, bool force) { #if DEBUG_ZOOM qDebug() << "zoomXMeanCentered" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomXMeanCentered(this); } else { ZoomCommand *cmd = new ZoomXMeanCenteredCommand(this, dX, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomXMaximum(bool force) { #if DEBUG_ZOOM qDebug() << "zoomXMaximum" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomXMaximum(this); } else { ZoomCommand *cmd = new ZoomXMaximumCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomXNoSpike(bool force) { #if DEBUG_ZOOM qDebug() << "zoomXNoSpike" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomXNoSpike(this); } else { ZoomCommand *cmd = new ZoomXNoSpikeCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomXAutoBorder(bool force) { #if DEBUG_ZOOM qDebug() << "zoomXAutoBorder" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomXAutoBorder(this); } else { ZoomCommand *cmd = new ZoomXAutoBorderCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomXRight(bool force) { //if (zoomOnlyMode() == View::ZoomOnlyX) { // zoomXOut(force); // return; //} #if DEBUG_ZOOM qDebug() << "zoomXRight" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomXRight(this); } else { ZoomCommand *cmd = new ZoomXRightCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomXLeft(bool force) { //if (zoomOnlyMode() == View::ZoomOnlyX) { // zoomXIn(force); // return; //} #if DEBUG_ZOOM qDebug() << "zoomXLeft" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomXLeft(this); } else { ZoomCommand *cmd = new ZoomXLeftCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomXOut(bool force) { #if DEBUG_ZOOM qDebug() << "zoomXOut" << endl; #endif resetSelectionRect(); if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomXOut(this); } else { ZoomCommand *cmd = new ZoomXOutCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomXIn(bool force) { #if DEBUG_ZOOM qDebug() << "zoomXIn" << endl; #endif resetSelectionRect(); if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomXIn(this); } else { ZoomCommand *cmd = new ZoomXInCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomNormalizeXtoY(bool force) { #if DEBUG_ZOOM qDebug() << "zoomNormalizeXtoY" << endl; #endif if (xAxis()->axisLog() || yAxis()->axisLog()) return; //apparently we don't want to do anything here according to kst2dplot... if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomNormalizeXtoY(this); } else { ZoomCommand *cmd = new ZoomNormalizeXToYCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomLogX(bool force, bool autoLog, bool enableLog) { #if DEBUG_ZOOM qDebug() << "zoomLogX" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomLogX(this); } else { bool log = enableLog; if (autoLog) { log = !xAxis()->axisLog(); } ZoomCommand *cmd = new ZoomXLogCommand(this, log, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYLocalMaximum(bool force) { #if DEBUG_ZOOM qDebug() << "zoomYLocalMaximum" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYLocalMaximum(this); } else { ZoomCommand *cmd = new ZoomYLocalMaximumCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYMaximum(bool force) { #if DEBUG_ZOOM qDebug() << "zoomYMaximum" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYMaximum(this); } else { ZoomCommand *cmd = new ZoomYMaximumCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYNoSpike(bool force) { #if DEBUG_ZOOM qDebug() << "zoomYNoSpike" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYNoSpike(this); } else { ZoomCommand *cmd = new ZoomYNoSpikeCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYAutoBorder(bool force) { #if DEBUG_ZOOM qDebug() << "zoomYAutoBorder" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYAutoBorder(this); } else { ZoomCommand *cmd = new ZoomYAutoBorderCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYUp(bool force) { #if DEBUG_ZOOM qDebug() << "zoomYUp" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYUp(this); } else { ZoomCommand *cmd = new ZoomYUpCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYDown(bool force) { #if DEBUG_ZOOM qDebug() << "zoomYDown" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYDown(this); } else { ZoomCommand *cmd = new ZoomYDownCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYOut(bool force) { #if DEBUG_ZOOM qDebug() << "zoomYOut" << endl; #endif resetSelectionRect(); if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYOut(this); } else { ZoomCommand *cmd = new ZoomYOutCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomYIn(bool force) { #if DEBUG_ZOOM qDebug() << "zoomYIn" << endl; #endif resetSelectionRect(); if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomYIn(this); } else { ZoomCommand *cmd = new ZoomYInCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomNormalizeYtoX(bool force) { #if DEBUG_ZOOM qDebug() << "zoomNormalizeYtoX" << endl; #endif if (xAxis()->axisLog() || yAxis()->axisLog()) return; //apparently we don't want to do anything here according to kst2dplot... if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomNormalizeYtoX(this); } else { ZoomCommand *cmd = new ZoomNormalizeYToXCommand(this, force); _undoStack->push(cmd); cmd->redo(); } } void PlotItem::zoomLogY(bool force, bool autoLog, bool enableLog) { #if DEBUG_ZOOM qDebug() << "zoomLogY" << endl; #endif if (isInSharedAxisBox() && !force) { sharedAxisBox()->zoomLogY(this); } else { bool log = enableLog; if (autoLog) { log = !yAxis()->axisLog(); } ZoomCommand *cmd = new ZoomYLogCommand(this, log, force); _undoStack->push(cmd); cmd->redo(); } } QString PlotItem::descriptionTip() const { QString contents; foreach (PlotRenderItem *renderer, renderItems()) { foreach (RelationPtr relation, renderer->relationList()) { contents += QString(" %1\n").arg(relation->Name()); } } return i18n("Plot: %1 \nContents:\n %2").arg(Name()).arg(contents); } QString PlotItem::_automaticDescriptiveName() const { QString name = i18n("Empty Plot"); int n=0; foreach (PlotRenderItem *renderer, renderItems()) { foreach (RelationPtr relation, renderer->relationList()) { if (n==0) { name = relation->descriptiveName(); } n++; } } if (n>1) { name += ", ..."; } return name; } ZoomState PlotItem::currentZoomState() { ZoomState zoomState; zoomState.item = this; //the origin of this ZoomState zoomState.projectionRect = projectionRect(); zoomState.xAxisZoomMode = xAxis()->axisZoomMode(); zoomState.yAxisZoomMode = yAxis()->axisZoomMode(); zoomState.isXAxisLog = xAxis()->axisLog(); zoomState.isYAxisLog = yAxis()->axisLog(); return zoomState; } void PlotItem::setCurrentZoomState(ZoomState zoomState) { _xAxis->setAxisZoomMode(PlotAxis::ZoomMode(zoomState.xAxisZoomMode)); _yAxis->setAxisZoomMode(PlotAxis::ZoomMode(zoomState.yAxisZoomMode)); _xAxis->setAxisLog(zoomState.isXAxisLog); _yAxis->setAxisLog(zoomState.isYAxisLog); setProjectionRect(zoomState.projectionRect); } void PlotItem::updateChildGeometry(const QRectF &oldParentRect, const QRectF &newParentRect) { ViewItem::updateChildGeometry(oldParentRect, newParentRect); setPlotBordersDirty(true); setLabelsDirty(); setAxisLabelsDirty(); setPlotPixmapDirty(); } void PlotItem::saveAsDialogDefaults() const { _dialogDefaults->setValue("plot/globalFontFamily", QVariant(globalFont()).toString()); ApplicationSettings::self()->setDefaultFontScale(globalFontScale()); _dialogDefaults->setValue("plot/globalFontColor", QVariant(globalFontColor()).toString()); leftLabelDetails()->saveAsDialogDefaults(QString("plot/leftFont")); rightLabelDetails()->saveAsDialogDefaults(QString("plot/rightFont")); topLabelDetails()->saveAsDialogDefaults(QString("plot/topFont")); bottomLabelDetails()->saveAsDialogDefaults(QString("plot/bottomFont")); numberLabelDetails()->saveAsDialogDefaults(QString("plot/numberFont")); // Save stroke... QPen p = pen(); QBrush b = p.brush(); _dialogDefaults->setValue("plot/strokeStyle", QVariant(p.style()).toString()); _dialogDefaults->setValue("plot/strokeWidth", p.widthF()); _dialogDefaults->setValue("plot/strokeJoinStyle", QVariant(p.joinStyle()).toString()); _dialogDefaults->setValue("plot/strokeCapStyle", QVariant(p.capStyle()).toString()); _dialogDefaults->setValue("plot/strokeBrushColor", QVariant(b.color()).toString()); _dialogDefaults->setValue("plot/strokeBrushStyle", QVariant(b.style()).toString()); // Save the brush b = brush(); _dialogDefaults->setValue("plot/fillBrushColor", QVariant(b.color()).toString()); _dialogDefaults->setValue("plot/fillBrushStyle", QVariant(b.style()).toString()); _dialogDefaults->setValue("plot/fillBrushUseGradient", QVariant(bool(b.gradient())).toString()); if (b.gradient()) { QString stopList; foreach(QGradientStop stop, b.gradient()->stops()) { qreal point = (qreal)stop.first; QColor color = (QColor)stop.second; stopList += QString::number(point); stopList += ','; stopList += color.name(); stopList += ','; } _dialogDefaults->setValue("plot/fillBrushGradient", stopList); } _xAxis->saveAsDialogDefaults("plot/xAxis"); _yAxis->saveAsDialogDefaults("plot/yAxis"); } PlotLabel::PlotLabel(PlotItem *plotItem) : QObject(), _plotItem(plotItem), _visible(true), _fontUseGlobal(true), _isAuto(true) { _fontColor = ApplicationSettings::self()->defaultFontColor(); _fontScale = ApplicationSettings::self()->defaultFontScale(); _font = _plotItem->view()->defaultFont(_fontScale); } void PlotLabel::setDetails(const QString &label, bool is_auto, const bool use_global, const QFont &font, const qreal scale, const QColor &color) { if ((label != _text) || (_isAuto != is_auto) || (use_global != _fontUseGlobal) || (font != _font) || (scale != _fontScale) || (color != _fontColor)) { _text = label; _isAuto = is_auto; _fontUseGlobal = use_global; _font = font; _fontScale = scale; _fontColor = color; emit labelChanged(); } } QFont PlotLabel::calculatedFont() { QFont tempFont; if (fontUseGlobal()) { tempFont = _plotItem->globalFont(); tempFont.setPointSizeF(_plotItem->view()->defaultFont(_plotItem->globalFontScale()).pointSizeF()); } else { tempFont = font(); tempFont.setPointSizeF(_plotItem->view()->defaultFont(fontScale()).pointSizeF()); } return tempFont; } bool PlotLabel::isVisible() const { return _visible; } void PlotLabel::setVisible(bool visible) { if (_visible == visible) return; _visible = visible; emit labelChanged(); } bool PlotLabel::fontUseGlobal() const { return _fontUseGlobal; } void PlotLabel::setFontUseGlobal(const bool use_global) { if (_fontUseGlobal == use_global) return; _fontUseGlobal = use_global; emit labelChanged(); } QString PlotLabel::text() const { return _text; } void PlotLabel::setText(const QString &label) { if (label == _text) { return; } _text = label; emit labelChanged(); } qreal PlotLabel::fontScale() const { return _fontScale; } void PlotLabel::setFontScale(const qreal scale) { if (scale != _fontScale) { _fontScale = scale; emit labelChanged(); } } QFont PlotLabel::font() const { return _font; } void PlotLabel::setFont(const QFont &font) { if (font != _font) { _font = font; emit labelChanged(); } } QColor PlotLabel::fontColor() const { return _fontColor; } void PlotLabel::setFontColor(const QColor &color) { if (color != _fontColor) { _fontColor = color; emit labelChanged(); } } void PlotLabel::saveInPlot(QXmlStreamWriter &xml, QString labelId) { xml.writeStartElement("plotlabel"); xml.writeAttribute("id", labelId); xml.writeAttribute("visible", QVariant(_visible).toString()); xml.writeAttribute("overridetext", _text); xml.writeAttribute("autolabel", QVariant(_isAuto).toString()); xml.writeAttribute("font", QVariant(_font).toString()); xml.writeAttribute("fontscale", QVariant(_fontScale).toString()); xml.writeAttribute("fontcolor", QVariant(_fontColor).toString()); xml.writeAttribute("fontuseglobal", QVariant(_fontUseGlobal).toString()); xml.writeEndElement(); } bool PlotLabel::configureFromXml(QXmlStreamReader &xml, ObjectStore *store) { Q_UNUSED(store); bool validTag = true; QString primaryTag = xml.name().toString(); QXmlStreamAttributes attrs = xml.attributes(); QStringRef av = attrs.value("visible"); if (!av.isNull()) { setVisible(QVariant(av.toString()).toBool()); } av = attrs.value("overridetext"); if (!av.isNull()) { setText(av.toString()); } av = attrs.value("autolabel"); if (!av.isNull()) { setIsAuto(QVariant(av.toString()).toBool()); } av = attrs.value("fontuseglobal"); if (!av.isNull()) { setFontUseGlobal(QVariant(av.toString()).toBool()); } av = attrs.value("font"); if (!av.isNull()) { QFont font; font.fromString(av.toString()); setFont(font); } av = attrs.value("fontcolor"); if (!av.isNull()) { setFontColor(QColor(av.toString())); } av = attrs.value("fontscale"); if (!av.isNull()) { setFontScale(QVariant(av.toString()).toDouble()); } QString expectedEnd; while (!(xml.isEndElement() && (xml.name().toString() == primaryTag))) { if (xml.isEndElement()) { if (xml.name().toString() != expectedEnd) { validTag = false; break; } } xml.readNext(); } return validTag; } void PlotLabel::saveAsDialogDefaults(const QString &group) const { _dialogDefaults->setValue(group+QString("Global"), fontUseGlobal()); _dialogDefaults->setValue(group+QString("Family"), QVariant(font()).toString()); _dialogDefaults->setValue(group+QString("Scale"), fontScale()); _dialogDefaults->setValue(group+QString("Color"), QVariant(fontColor()).toString()); } void CreatePlotCommand::createItem() { _item = new PlotItem(_view); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } void CreatePlotForCurve::createItem() { _item = new PlotItem(_view); creationComplete(); //add to undo stack } PlotItemFactory::PlotItemFactory() : GraphicsFactory() { registerFactory("plot", this); } PlotItemFactory::~PlotItemFactory() { } ViewItem* PlotItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { PlotItem *rc = 0; double x = 0, y = 0, w = 10, h = 10; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "plot") { Q_ASSERT(!rc); rc = new PlotItem(view); if (parent) { rc->setParentViewItem(parent); } QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; bool xTiedZoom = false, yTiedZoom = false; av = attrs.value("tiedxzoom"); if (!av.isNull()) { xTiedZoom = QVariant(av.toString()).toBool(); } av = attrs.value("tiedyzoom"); if (!av.isNull()) { yTiedZoom = QVariant(av.toString()).toBool(); } rc->setTiedZoom(xTiedZoom, yTiedZoom); av = attrs.value("leftlabelvisible"); if (!av.isNull()) { rc->leftLabelDetails()->setVisible(QVariant(av.toString()).toBool()); } av = attrs.value("bottomlabelvisible"); if (!av.isNull()) { rc->bottomLabelDetails()->setVisible(QVariant(av.toString()).toBool()); } av = attrs.value("rightlabelvisible"); if (!av.isNull()) { rc->rightLabelDetails()->setVisible(QVariant(av.toString()).toBool()); } av = attrs.value("toplabelvisible"); if (!av.isNull()) { rc->topLabelDetails()->setVisible(QVariant(av.toString()).toBool()); } av = attrs.value("globalfont"); if (!av.isNull()) { QFont font; font.fromString(av.toString()); rc->setGlobalFont(font); } av = attrs.value("globalfontscale"); if (!av.isNull()) { rc->setGlobalFontScale(QVariant(av.toString()).toDouble()); } av = attrs.value("globalfontcolor"); if (!av.isNull()) { rc->setGlobalFontColor(QColor(av.toString())); } av = attrs.value("showlegend"); if (!av.isNull()) { rc->setShowLegend(QVariant(av.toString()).toBool()); } av = attrs.value("hidebottomaxislabel"); if (!av.isNull()) { rc->setManuallyHideBottomAxisLabel(QVariant(av.toString()).toBool()); } av = attrs.value("hidetopaxislabel"); if (!av.isNull()) { rc->setManuallyHideTopAxisLabel(QVariant(av.toString()).toBool()); } av = attrs.value("hideleftaxislabel"); if (!av.isNull()) { rc->setManuallyHideLeftAxisLabel(QVariant(av.toString()).toBool()); } av = attrs.value("hiderightaxislabel"); if (!av.isNull()) { rc->setManuallyHideRightAxisLabel(QVariant(av.toString()).toBool()); } if (attrs.value("descriptiveNameIsManual").toString() == "true") { rc->setDescriptiveName(attrs.value("descriptiveName").toString()); } Object::processShortNameIndexAttributes(attrs); // Add any new specialized PlotItem Properties here. } else if (xml.name().toString() == "projectionrect") { QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; av = attrs.value("width"); if (!av.isNull()) { w = av.toString().toDouble(); } av = attrs.value("height"); if (!av.isNull()) { h = av.toString().toDouble(); } av = attrs.value("x"); if (!av.isNull()) { x = av.toString().toDouble(); } av = attrs.value("y"); if (!av.isNull()) { y = av.toString().toDouble(); } xml.readNext(); } else if (xml.name().toString() == "plotaxis") { Q_ASSERT(rc); QXmlStreamAttributes subattrs = xml.attributes(); QStringRef av = subattrs.value("id"); if (!av.isNull()) { if (av == "xaxis") { rc->xAxis()->configureFromXml(xml, store); } else if (av == "yaxis") { rc->yAxis()->configureFromXml(xml, store); } } xml.readNext(); } else if (xml.name().toString() == "plotlabel") { Q_ASSERT(rc); QXmlStreamAttributes subattrs = xml.attributes(); QStringRef av = subattrs.value("id"); if (!av.isNull()) { if (av == "leftlabel") { rc->leftLabelDetails()->configureFromXml(xml, store); } else if (av == "rightlabel") { rc->rightLabelDetails()->configureFromXml(xml, store); } else if (av == "toplabel") { rc->topLabelDetails()->configureFromXml(xml, store); } else if (av == "bottomlabel") { rc->bottomLabelDetails()->configureFromXml(xml, store); } else if (av == "numberlabel") { rc->numberLabelDetails()->configureFromXml(xml, store); } } xml.readNext(); } else if (xml.name().toString() == "cartesianrender") { Q_ASSERT(rc); PlotRenderItem * renderItem = rc->renderItem(PlotRenderItem::Cartesian); if (renderItem) { validTag = renderItem->configureFromXml(xml, store); } } else if (xml.name().toString() == "legend") { Q_ASSERT(rc); validTag = rc->legend()->configureFromXml(xml, store); } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "plot") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating plot object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } rc->setProjectionRect(QRectF(QPointF(x, y), QSizeF(w, h))); return rc; } ZoomCommand::ZoomCommand(PlotItem *item, const QString &text, bool forced) : ViewItemCommand(item, text, false), _plotItem(item) { if (!item->isTiedZoom() || forced) { _originalStates << item->currentZoomState(); } else { _viewItems = PlotItemManager::tiedZoomViewItems(item); QList plots = PlotItemManager::tiedZoomPlots(item); foreach (PlotItem *plotItem, plots) { if (plotItem->isInSharedAxisBox()) { if (!_viewItems.contains(plotItem->sharedAxisBox())) { _viewItems << plotItem->sharedAxisBox(); } } _originalStates << plotItem->currentZoomState(); } } } ZoomCommand::~ZoomCommand() { } void ZoomCommand::undo() { foreach (ZoomState state, _originalStates) { state.item->setCurrentZoomState(state); } kstApp->mainWindow()->document()->setChanged(true); } void ZoomCommand::redo() { bool tiedX = _plotItem->isXTiedZoom(); bool tiedY = _plotItem->isYTiedZoom(); foreach (ZoomState state, _originalStates) { if (state.item == _plotItem) { applyZoomTo(state.item, true, true); } else { applyZoomTo(state.item, state.item->isXTiedZoom() && tiedX, state.item->isYTiedZoom() && tiedY); } } foreach (ViewItem* item, _viewItems) { applyZoomTo(item, tiedX, tiedY); } kstApp->mainWindow()->document()->setChanged(true); } /* * X axis zoom to FixedExpression, Y axis zoom to FixedExpression. */ void ZoomFixedExpressionCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { if (applyX && applyY) { item->xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); item->setProjectionRect(_fixed); } else if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); item->setProjectionRect(QRectF(_fixed.x(), item->projectionRect().y(), _fixed.width(), item->projectionRect().height())); } else if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); item->setProjectionRect(QRectF(item->projectionRect().x(), _fixed.y(), item->projectionRect().width(), _fixed.height())); } } void ZoomFixedExpressionCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX && applyY) { shareBox->zoomFixedExpression(_fixed, 0); } else if (applyX) { shareBox->zoomXRange(_fixed, 0); } else if (applyY) { shareBox->zoomYRange(_fixed, 0); } } } /* * X axis zoom to Range. */ void ZoomXRangeCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); item->setProjectionRect(QRectF(_fixed.x(), item->projectionRect().y(), _fixed.width(), item->projectionRect().height())); } } void ZoomXRangeCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXRange(_fixed, 0); } } } /* * Y axis zoom to Range. */ void ZoomYRangeCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); item->setProjectionRect(QRectF(item->projectionRect().x(), _fixed.y(), item->projectionRect().width(), _fixed.height())); } } void ZoomYRangeCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYRange(_fixed, 0); } } } /* * X axis zoom to Auto, Y axis zoom to AutoBorder. */ void ZoomMaximumCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { if (applyX && applyY) { item->xAxis()->setAxisZoomMode(PlotAxis::Auto); item->yAxis()->setAxisZoomMode(PlotAxis::AutoBorder); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(compute); } else if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::Auto); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(compute.x(), item->projectionRect().y(), compute.width(), item->projectionRect().height())); } else if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::AutoBorder); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(item->projectionRect().x(), compute.y(), item->projectionRect().width(), compute.height())); } } void ZoomMaximumCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX && applyY) { shareBox->zoomMaximum(0); } else if (applyX) { shareBox->zoomXMaximum(0); } else if (applyY) { shareBox->zoomYMaximum(0); } } } /* * X axis zoom to Auto, Y axis zoom to SpikeInsensitive. */ void ZoomMaxSpikeInsensitiveCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { if (applyX && applyY) { item->xAxis()->setAxisZoomMode(PlotAxis::Auto); item->yAxis()->setAxisZoomMode(PlotAxis::SpikeInsensitive); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(compute); } else if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::Auto); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(compute.x(), item->projectionRect().y(), compute.width(), item->projectionRect().height())); } else if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::SpikeInsensitive); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(item->projectionRect().x(), compute.y(), item->projectionRect().width(), compute.height())); } } void ZoomMaxSpikeInsensitiveCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX && applyY) { shareBox->zoomMaxSpikeInsensitive(0); } else if (applyX) { shareBox->zoomXMaximum(0); } else if (applyY) { shareBox->zoomYNoSpike(0); } } } /* * X axis zoom to Auto, Y axis zoom to Mean Centered. */ void ZoomMeanCenteredCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { if (applyX && applyY) { item->xAxis()->setAxisZoomMode(PlotAxis::Auto); item->yAxis()->setAxisZoomMode(PlotAxis::MeanCentered); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(compute); } else if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::Auto); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(compute.x(), item->projectionRect().y(), compute.width(), item->projectionRect().height())); } else if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::MeanCentered); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(item->projectionRect().x(), compute.y(), item->projectionRect().width(), compute.height())); } } void ZoomMeanCenteredCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX && applyY) { shareBox->zoomMeanCentered(0); } else if (applyX) { shareBox->zoomXMaximum(0); } else if (applyY) { shareBox->zoomMeanCentered(0); } } } /* * X axis zoom unchanged, Y axis zoom to Mean Centered. */ void ZoomYMeanCenteredCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::MeanCentered); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(item->projectionRect().x(), compute.y(), item->projectionRect().width(), _dY)); } } void ZoomYMeanCenteredCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYMeanCentered(0); } } } /* * X axis zoom to Mean Centered, Y axis unchanged. */ void ZoomXMeanCenteredCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::MeanCentered); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(compute.x(), item->projectionRect().y(), _dX, item->projectionRect().height())); } } void ZoomXMeanCenteredCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXMeanCentered(0); } } } /* * X axis zoom to auto, Y zoom not changed. */ void ZoomXMaximumCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::Auto); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(compute.x(), item->projectionRect().y(), compute.width(), item->projectionRect().height())); } } void ZoomXMaximumCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXMaximum(0); } } } /* * X axis zoom to auto border, Y zoom not changed. */ void ZoomXAutoBorderCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::AutoBorder); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(compute.x(), item->projectionRect().y(), compute.width(), item->projectionRect().height())); } } void ZoomXAutoBorderCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXAutoBorder(0); } } } /* * X axis zoom to no spike, Y zoom not changed. */ void ZoomXNoSpikeCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::SpikeInsensitive); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(compute.x(), item->projectionRect().y(), compute.width(), item->projectionRect().height())); } } void ZoomXNoSpikeCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXNoSpike(0); } } } /* * X axis zoom changed to fixed and shifted to right: * new_xmin = xmin + (xmax - xmin)*0.10; * new_xmax = xmax + (xmax – xmin)*0.10; */ void ZoomXRightCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); qreal dx = (item->xMax() - item->xMin())*0.10; if (item->xAxis()->axisReversed()) { dx *=-1; } if (item->xAxis()->axisLog()) { compute.setLeft(pow(10, item->xMin() + dx)); compute.setRight(pow(10, item->xMax() + dx)); } else { compute.setLeft(compute.left() + dx); compute.setRight(compute.right() + dx); } item->setProjectionRect(compute); } } void ZoomXRightCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXRight(0); } } } /* * X axis zoom changed to fixed and shifted to : * new_xmin = xmin - (xmax - xmin)*0.10; * new_xmax = xmax - (xmax – xmin)*0.10; */ void ZoomXLeftCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); qreal dx = (item->xMax() - item->xMin())*0.10; if (item->xAxis()->axisReversed()) { dx *=-1; } if (item->xAxis()->axisLog()) { compute.setLeft(pow(10, item->xMin() - dx)); compute.setRight(pow(10, item->xMax() - dx)); } else { compute.setLeft(compute.left() - dx); compute.setRight(compute.right() - dx); } item->setProjectionRect(compute); } } void ZoomXLeftCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXLeft(0); } } } /* * X axis zoom changed to fixed and increased: * new_xmin = xmin - (xmax - xmin)*0.25; * new_xmax = xmax + (xmax – xmin)*0.25; */ void ZoomXOutCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); qreal dx = (item->xMax() - item->xMin())*0.25; if (item->xAxis()->axisLog()) { compute.setLeft(pow(10, item->xMin() - dx)); compute.setRight(pow(10, item->xMax() + dx)); } else { compute.setLeft(compute.left() - dx); compute.setRight(compute.right() + dx); } item->setProjectionRect(compute); // item->update(); } } void ZoomXOutCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXOut(0); } } } /* * X axis zoom changed to fixed and decreased: * new_xmin = xmin + (xmax - xmin)*0.1666666; * new_xmax = xmax - (xmax – xmin)*0.1666666; */ void ZoomXInCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); qreal dx = (item->xMax() - item->xMin())*0.1666666; if (item->xAxis()->axisLog()) { compute.setLeft(pow(10, item->xMin() + dx)); compute.setRight(pow(10, item->xMax() - dx)); } else { compute.setLeft(compute.left() + dx); compute.setRight(compute.right() - dx); } item->setProjectionRect(compute); } } void ZoomXInCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomXIn(0); } } } /* * Normalize X axis to Y axis: Given the current plot aspect ratio, change * the X axis range to have the same units per mm as the Y axis range. Particularly * useful for images. */ void ZoomNormalizeXToYCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { QRectF compute = item->projectionRect(); qreal mean = compute.center().x(); qreal range = item->plotRect().width() * compute.height() / item->plotRect().height(); compute.setLeft(mean - (range / 2.0)); compute.setRight(mean + (range / 2.0)); item->xAxis()->setAxisZoomMode(PlotAxis::FixedExpression); item->setProjectionRect(compute); } } void ZoomNormalizeXToYCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomNormalizeXtoY(0); } } } /* * When zoomed in in X, auto zoom Y, only * counting points within the current X range. (eg, curve goes from x=0 to 100, but * we are zoomed in to x = 30 to 40. Adjust Y zoom to include all points with x * values between 30 and 40. */ void ZoomYLocalMaximumCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { qreal minimum = item->yMax(); qreal maximum = item->yMin(); item->computedRelationalMax(minimum, maximum); item->computeBorder(Qt::Vertical, minimum, maximum); item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); compute.setTop(minimum); compute.setBottom(maximum); item->setProjectionRect(compute); } } void ZoomYLocalMaximumCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYLocalMaximum(0); } } } /* * Y axis zoom to auto, X zoom not changed. */ void ZoomYMaximumCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::Auto); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(item->projectionRect().x(), compute.y(), item->projectionRect().width(), compute.height())); } } void ZoomYMaximumCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYMaximum(0); } } } /* * Y axis zoom to auto border, X zoom not changed. */ void ZoomYAutoBorderCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::AutoBorder); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(item->projectionRect().x(), compute.y(), item->projectionRect().width(), compute.height())); } } void ZoomYAutoBorderCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYAutoBorder(0); } } } /* * Y axis zoom to no spike, X zoom not changed. */ void ZoomYNoSpikeCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { item->yAxis()->setAxisZoomMode(PlotAxis::SpikeInsensitive); QRectF compute = item->computedProjectionRect(); item->setProjectionRect(QRectF(item->projectionRect().x(), compute.y(), item->projectionRect().width(), compute.height())); } } void ZoomYNoSpikeCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYNoSpike(0); } } } /* * Y axis zoom up. If the Y zoom mode is not * Mean Centered, change to Fixed (expression). * new_ymin = ymin + (ymax - ymin)*0.1; * new_ymax = ymax + (ymax - ymin)*0.1; */ void ZoomYUpCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { if (item->yAxis()->axisZoomMode() != PlotAxis::MeanCentered) item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); qreal dy = (item->yMax() - item->yMin())*0.1; if (item->yAxis()->axisLog()) { compute.setTop(pow(10, item->yMin() + dy)); compute.setBottom(pow(10, item->yMax() + dy)); } else { compute.setTop(compute.top() + dy); compute.setBottom(compute.bottom() + dy); } item->setProjectionRect(compute); } } void ZoomYUpCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYUp(0); } } } /* * Y axis zoom down. If the Y zoom mode is not * Mean Centered, change to Fixed (expression). * new_ymin = ymin - (ymax - ymin)*0.10; * new_ymax = ymax - (ymax - ymin)*0.10; */ void ZoomYDownCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { if (item->yAxis()->axisZoomMode() != PlotAxis::MeanCentered) item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); qreal dy = (item->yMax() - item->yMin())*0.1; if (item->yAxis()->axisLog()) { compute.setTop(pow(10, item->yMin() - dy)); compute.setBottom(pow(10, item->yMax() - dy)); } else { compute.setTop(compute.top() - dy); compute.setBottom(compute.bottom() - dy); } item->setProjectionRect(compute); } } void ZoomYDownCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYDown(0); } } } /* * Y axis zoom increased. If the Y zoom mode is not * Mean Centered, change to Fixed (expression). * new_ymin = ymin - (ymax - ymin)*0.25; * new_ymax = ymax + (ymax - ymin)*0.25; */ void ZoomYOutCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { if (item->yAxis()->axisZoomMode() != PlotAxis::MeanCentered) item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); qreal dy = (item->yMax() - item->yMin())*0.25; if (item->yAxis()->axisLog()) { compute.setTop(pow(10, item->yMin() - dy)); compute.setBottom(pow(10, item->yMax() + dy)); } else { compute.setTop(compute.top() - dy); compute.setBottom(compute.bottom() + dy); } item->setProjectionRect(compute); // item->update(); } } void ZoomYOutCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYOut(0); } } } /* * Y axis zoom decreased. If the Y zoom mode is not * Mean Centered, change to Fixed (expression). * new_ymin = ymin + (ymax - ymin)*0.1666666; * new_ymax = ymax - (ymax – ymin)*0.1666666; */ void ZoomYInCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { if (item->yAxis()->axisZoomMode() != PlotAxis::MeanCentered) item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); QRectF compute = item->projectionRect(); qreal dy = (item->yMax() - item->yMin())*0.1666666; if (item->yAxis()->axisLog()) { compute.setTop(pow(10, item->yMin() + dy)); compute.setBottom(pow(10, item->yMax() - dy)); } else { compute.setTop(compute.top() + dy); compute.setBottom(compute.bottom() - dy); } item->setProjectionRect(compute); // item->update(); } } void ZoomYInCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomYIn(0); } } } /* * Normalize Y axis to X axis: Given the current plot aspect ratio, * change the Y axis range to have the same units per mm as the X axis range. * Particularly useful for images. */ void ZoomNormalizeYToXCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { QRectF compute = item->projectionRect(); qreal mean = compute.center().y(); qreal range = item->plotRect().height() * compute.width() / item->plotRect().width(); compute.setTop(mean - (range / 2.0)); compute.setBottom(mean + (range / 2.0)); item->yAxis()->setAxisZoomMode(PlotAxis::FixedExpression); item->setProjectionRect(compute); } } void ZoomNormalizeYToXCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomNormalizeYtoX(0); } } } /* * Switch the X Axis to a Log Scale. */ void ZoomXLogCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); if (applyX) { item->xAxis()->setAxisLog(_enableLog); item->setProjectionRect(item->computedProjectionRect(), true); //need to recompute } } void ZoomXLogCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyY); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyX) { shareBox->zoomLogX(0, false, _enableLog); } } } /* * Switch the Y Axis to a Log Scale. */ void ZoomYLogCommand::applyZoomTo(PlotItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); if (applyY) { item->yAxis()->setAxisLog(_enableLog); item->setProjectionRect(item->computedProjectionRect(), true); //need to recompute } } void ZoomYLogCommand::applyZoomTo(ViewItem *item, bool applyX, bool applyY) { Q_UNUSED(applyX); SharedAxisBoxItem *shareBox = qobject_cast(item); if (shareBox) { if (applyY) { shareBox->zoomLogY(0, false, _enableLog); } } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/stroketab.cpp000644 001750 001750 00000012054 11544160207 020155 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "stroketab.h" namespace Kst { StrokeTab::StrokeTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("Stroke")); _style->addItem("NoPen", Qt::NoPen); _style->addItem("SolidLine", Qt::SolidLine); _style->addItem("DashLine", Qt::DashLine); _style->addItem("DotLine", Qt::DotLine); _style->addItem("DashDotLine", Qt::DashDotLine); _style->addItem("DashDotDotLine", Qt::DashDotDotLine); _style->addItem("CustomDashLine", Qt::CustomDashLine); _brushStyle->addItem("NoBrush", Qt::NoBrush); _brushStyle->addItem("SolidPattern", Qt::SolidPattern); _brushStyle->addItem("Dense1Pattern", Qt::Dense1Pattern); _brushStyle->addItem("Dense2Pattern", Qt::Dense2Pattern); _brushStyle->addItem("Dense3Pattern", Qt::Dense3Pattern); _brushStyle->addItem("Dense4Pattern", Qt::Dense4Pattern); _brushStyle->addItem("Dense5Pattern", Qt::Dense5Pattern); _brushStyle->addItem("Dense6Pattern", Qt::Dense6Pattern); _brushStyle->addItem("Dense7Pattern", Qt::Dense7Pattern); _brushStyle->addItem("HorPattern", Qt::HorPattern); _brushStyle->addItem("VerPattern", Qt::VerPattern); _brushStyle->addItem("CrossPattern", Qt::CrossPattern); _brushStyle->addItem("BDiagPattern", Qt::BDiagPattern); _brushStyle->addItem("FDiagPattern", Qt::FDiagPattern); _brushStyle->addItem("DiagCrossPattern", Qt::DiagCrossPattern); _joinStyle->addItem("MiterJoin", Qt::MiterJoin); _joinStyle->addItem("BevelJoin", Qt::BevelJoin); _joinStyle->addItem("RoundJoin", Qt::RoundJoin); _joinStyle->addItem("SvgMiterJoin", Qt::SvgMiterJoin); _capStyle->addItem("FlatCap", Qt::FlatCap); _capStyle->addItem("SquareCap", Qt::SquareCap); _capStyle->addItem("RoundCap", Qt::RoundCap); connect(_style, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_width, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_brushColor, SIGNAL(changed(const QColor &)), this, SIGNAL(modified())); connect(_brushStyle, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_joinStyle, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_capStyle, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); } StrokeTab::~StrokeTab() { } Qt::PenStyle StrokeTab::style() const { return Qt::PenStyle(_style->itemData(_style->currentIndex()).toInt()); } bool StrokeTab::styleDirty() const { return _style->currentIndex() != -1; } void StrokeTab::setStyle(Qt::PenStyle style) { _style->setCurrentIndex(_style->findData(QVariant(style))); } qreal StrokeTab::width() const { return _width->value(); } bool StrokeTab::widthDirty() const { return (!_width->text().isEmpty()); } void StrokeTab::setWidth(qreal width) { _width->setValue(width); } QColor StrokeTab::brushColor() const { return _brushColor->color(); } bool StrokeTab::brushColorDirty() const { return _brushColor->colorDirty(); } void StrokeTab::setBrushColor(const QColor &color) { _brushColor->setColor(color); } Qt::BrushStyle StrokeTab::brushStyle() const { return Qt::BrushStyle(_brushStyle->itemData(_brushStyle->currentIndex()).toInt()); } bool StrokeTab::brushStyleDirty() const { return _brushStyle->currentIndex() != -1; } void StrokeTab::setBrushStyle(Qt::BrushStyle style) { _brushStyle->setCurrentIndex(_brushStyle->findData(QVariant(style))); } Qt::PenJoinStyle StrokeTab::joinStyle() const { return Qt::PenJoinStyle(_joinStyle->itemData(_joinStyle->currentIndex()).toInt()); } bool StrokeTab::joinStyleDirty() const { return _joinStyle->currentIndex() != -1; } void StrokeTab::setJoinStyle(Qt::PenJoinStyle style) { _joinStyle->setCurrentIndex(_joinStyle->findData(QVariant(style))); } Qt::PenCapStyle StrokeTab::capStyle() const { return Qt::PenCapStyle(_capStyle->itemData(_capStyle->currentIndex()).toInt()); } bool StrokeTab::capStyleDirty() const { return _capStyle->currentIndex() != -1; } void StrokeTab::setCapStyle(Qt::PenCapStyle style) { _capStyle->setCurrentIndex(_capStyle->findData(QVariant(style))); } void StrokeTab::clearTabValues() { _width->clear(); _style->setCurrentIndex(-1); _brushStyle->setCurrentIndex(-1); _joinStyle->setCurrentIndex(-1); _capStyle->setCurrentIndex(-1); _brushColor->clearSelection(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewitemdialog.h000644 001750 001750 00000005430 11544160207 020635 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEWITEMDIALOG_H #define VIEWITEMDIALOG_H #include "dialog.h" #include "editmultiplewidget.h" #include #include #include "kst_export.h" namespace Kst { class ViewItem; class FillTab; class StrokeTab; class LayoutTab; class DimensionsTab; class EditMultipleWidget; class ViewItemDialog : public Dialog { Q_OBJECT public: enum EditMode { Single, Multiple }; explicit ViewItemDialog(ViewItem *item, QWidget *parent = 0); virtual ~ViewItemDialog(); void setSupportsMultipleEdit(bool enabled); void setTagString(const QString& tagString) { _tagString->setText(tagString); } QString tagString() const { return _tagString->text(); } void addMultipleEditOption(QString name, QString descriptionTip, QString shortName); QList selectedMultipleEditObjects(); void clearMultipleEditOptions(); EditMode editMode() const { return _mode; } DialogPage *dimensionsPage; DimensionsTab *_dimensionsTab; public Q_SLOTS: void setSingleEdit(); void setMultipleEdit(); Q_SIGNALS: void editMultipleMode(); void editSingleMode(); private Q_SLOTS: void fillChanged(); void strokeChanged(); void layoutChanged(); void dimensionsChanged(); void slotEditMultiple(); private: void setupFill(); void setupStroke(); void setupLayout(); void setupChildViewOptions(); void setupDimensions(); void saveFill(ViewItem *item); void saveStroke(ViewItem *item); void saveLayout(ViewItem *item); void saveDimensions(ViewItem *item); private: QPointer _item; QMap _multiNameShortName; QLabel *_tagStringLabel; QLineEdit *_tagString; EditMultipleWidget *_editMultipleWidget; QPushButton *_editMultipleButton; EditMode _mode; QWidget *_editMultipleBox; protected: FillTab *_fillTab; StrokeTab *_strokeTab; LayoutTab *_layoutTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotitemdialog.h000644 001750 001750 00000005501 11544160207 020640 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLOTITEMDIALOG_H #define PLOTITEMDIALOG_H #include "viewitemdialog.h" #include "kst_export.h" namespace Kst { class ContentTab; class PlotMarkersTab; class AxisTab; class RangeTab; class MarkersTab; class LabelTab; class ObjectStore; class PlotItem; class OverrideLabelTab; class DialogPageTab; class PlotAxis; class PlotMarkers; class PlotItemDialog : public ViewItemDialog { Q_OBJECT public: explicit PlotItemDialog(PlotItem *item, QWidget *parent = 0); virtual ~PlotItemDialog(); private Q_SLOTS: void contentChanged(); void relationChanged(); void xAxisChanged(); void yAxisChanged(); void labelsChanged(); void xAxisPlotMarkersChanged(); void yAxisPlotMarkersChanged(); void globalFontUpdate(); void useTopDefaultChanged(bool); void useBottomDefaultChanged(bool); void useLeftDefaultChanged(bool); void useRightDefaultChanged(bool); void useAxisDefaultChanged(bool); void rangeChanged(); void editMultiple(); void editSingle(); void slotApply(); private: void setupContent(); void setupAxis(); void setupRange(); void setupLabels(); void setupMarkers(); void addRelations(); void updateRelations(); void saveAxis(PlotAxis *item, AxisTab *axisTab); void saveRange(PlotItem *item); void saveLabels(PlotItem *item); void saveMarkers(PlotAxis *item, PlotMarkers& markers); private: PlotItem* _plotItem; QString _defaultTagString; ContentTab *_contentTab; AxisTab *_xAxisTab; AxisTab *_yAxisTab; RangeTab *_rangeTab; MarkersTab *_xMarkersTab; MarkersTab *_yMarkersTab; LabelTab *_labelTab; OverrideLabelTab *_topLabelTab; OverrideLabelTab *_bottomLabelTab; OverrideLabelTab *_leftLabelTab; OverrideLabelTab *_rightLabelTab; OverrideLabelTab *_axisLabelTab; PlotMarkersTab* _plotMarkersTab; DialogPageTab *_labelPage; QList _relationPages; ObjectStore* _store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/document.cpp000644 001750 001750 00000022415 11544160207 017777 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "document.h" #include "mainwindow.h" #include "sessionmodel.h" #include "tabwidget.h" #include #include #include #include #include #include #include #include #include "objectstore.h" #include "updatemanager.h" #include #include #include namespace Kst { Document::Document(MainWindow *window) : CoreDocument(), _win(window), _dirty(false), _isOpen(false) { _session = new SessionModel(objectStore()); _fileName.clear(); UpdateManager::self()->setStore(objectStore()); } Document::~Document() { delete _session; _session = 0; } SessionModel* Document::session() const { return _session; } QString Document::fileName() const { return _fileName; } bool Document::save(const QString& to) { QString file = !to.isEmpty() ? to : _fileName; if (!file.endsWith(".kst")) { file.append(".kst"); } QFile f(file); if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) { _lastError = QObject::tr("File could not be opened for writing."); return false; } Q_ASSERT(objectStore()); objectStore()->cleanUpDataSourceList(); _fileName = file; QXmlStreamWriter xml; xml.setDevice(&f); xml.setAutoFormatting(true); xml.writeStartDocument(); xml.writeStartElement("kst"); xml.writeAttribute("version", "2.0"); xml.writeStartElement("data"); foreach (DataSourcePtr s, objectStore()->dataSourceList()) { s->saveSource(xml); } xml.writeEndElement(); xml.writeStartElement("variables"); foreach (VectorPtr s, objectStore()->getObjects()) { s->save(xml); } foreach (MatrixPtr s, objectStore()->getObjects()) { s->save(xml); } foreach (ScalarPtr s, objectStore()->getObjects()) { s->save(xml); } foreach (StringPtr s, objectStore()->getObjects()) { s->save(xml); } xml.writeEndElement(); xml.writeStartElement("objects"); foreach (DataObjectPtr s, objectStore()->getObjects()) { s->save(xml); } xml.writeEndElement(); xml.writeStartElement("relations"); foreach (RelationPtr s, objectStore()->getObjects()) { s->save(xml); } xml.writeEndElement(); xml.writeStartElement("graphics"); for (int i = 0; i < _win->tabWidget()->count(); ++i) { View *v = qobject_cast(_win->tabWidget()->widget(i)); xml.writeStartElement("view"); xml.writeAttribute("name", _win->tabWidget()->tabText(i)); v->save(xml); xml.writeEndElement(); } xml.writeEndElement(); xml.writeEndDocument(); setChanged(false); return true; } bool Document::initFromCommandLine(CommandLineParser *P) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); bool ok; bool dataPlotted = P->processCommandLine(&ok); if (!dataPlotted && ok) { QString kstfile = P->kstFileName(); if (!kstfile.isEmpty()) { dataPlotted = open(kstfile); if (dataPlotted) { UpdateManager::self()->doUpdates(true); setChanged(false); } } } objectStore()->override.fileName = QString(); objectStore()->override.f0 = objectStore()->override.N = objectStore()->override.skip = objectStore()->override.doAve = -5; QApplication::restoreOverrideCursor(); return ok; } #define malformed() \ return false; bool Document::open(const QString& file) { _isOpen = false; QFile f(file); if (!f.open(QIODevice::ReadOnly)) { _lastError = QObject::tr("File could not be opened for reading."); return false; } _fileName = file; // If we move this into the block then we could, if desired, open // .kst files that contained only data and basically "merge" that data into // the current session View *loadedView = 0; bool firstView = true; QRectF currentSceneRect; QXmlStreamReader xml; xml.setDevice(&f); enum State { Unknown=0, Data, Variables, Objects, Relations, Graphics, View }; State state = Unknown; while (!xml.atEnd()) { if (xml.isStartElement()) { QString n = xml.name().toString(); if (n == "kst") { } else if (n == "data") { if (state != Unknown) { malformed(); } state = Data; } else if (n == "variables") { if (state != Unknown) { malformed(); } state = Variables; } else if (n == "objects") { if (state != Unknown) { malformed(); } state = Objects; } else if (n == "relations") { if (state != Unknown) { malformed(); } state = Relations; } else if (n == "graphics") { if (state != Unknown) { malformed(); } state = Graphics; } else { switch (state) { case Objects: { DataObjectPtr object = ObjectFactory::parse(objectStore(), xml); if (object) { // addDataObjectToList(object); } else { malformed(); } break; } case Graphics: { if (n == "view") { loadedView = new Kst::View(0); if (firstView) { _win->tabWidget()->clear(); firstView = false; } _win->tabWidget()->addView(loadedView); QXmlStreamAttributes attrs = xml.attributes(); loadedView->setObjectName(attrs.value("name").toString()); _win->tabWidget()->setCurrentViewName(attrs.value("name").toString()); qreal width = 1.0, height = 1.0; QStringRef string = attrs.value("width"); if (!string.isNull()) { width = string.toString().toDouble(); } string = attrs.value("height"); if (!string.isNull()) { height = string.toString().toDouble(); } currentSceneRect = QRectF(QPointF(0, 0), QSizeF(width, height)); state = View; } else { malformed(); } } break; case View: { ViewItem *i = GraphicsFactory::parse(xml, objectStore(), loadedView); if (i) { loadedView->scene()->addItem(i); } } break; case Data: DataSourceFactory::parse(objectStore(), xml); break; case Variables: PrimitiveFactory::parse(objectStore(), xml); break; case Relations: RelationFactory::parse(objectStore(), xml); break; case Unknown: malformed(); break; } } } else if (xml.isEndElement()) { QString n = xml.name().toString(); if (n == "kst") { if (state != Unknown) { malformed(); } break; } else if (n == "view") { if (loadedView->sceneRect() != currentSceneRect) { loadedView->forceChildResize(currentSceneRect, loadedView->sceneRect()); } state = Graphics; } else if (n == "data") { state = Unknown; } else if (n == "objects") { state = Unknown; } else if (n == "variables") { state = Unknown; } else if (n == "relations") { state = Unknown; } else if (n == "graphics") { state = Unknown; } } xml.readNext(); } if (xml.hasError()) { _lastError = QObject::tr("File is malformed and encountered an error while reading."); return false; } _vnum = max_vnum+1; _xnum = max_xnum+1; _pnum = max_pnum+1; _csdnum = max_csdnum+1; _cnum = max_cnum+1; _enum = max_enum+1; _hnum = max_hnum+1; _inum = max_inum+1; _psdnum = max_psdnum+1; _tnum = max_tnum+1; _mnum = max_mnum+1; UpdateManager::self()->doUpdates(true); setChanged(false); return _isOpen = true; } #undef malformed void Document::createView() { _win->tabWidget()->createView(); } QString Document::lastError() const { return _lastError; } bool Document::isChanged() const { return _dirty; } bool Document::isOpen() const { return _isOpen; } void Document::setChanged(bool dirty) { _dirty = dirty; } View* Document::currentView() const { return _win->tabWidget()->currentView(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/layouttab.cpp000644 001750 001750 00000005110 11544160207 020156 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "layouttab.h" namespace Kst { LayoutTab::LayoutTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("Layout")); connect(_horMargin, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_verMargin, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_horSpacing, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_verSpacing, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); } LayoutTab::~LayoutTab() { } double LayoutTab::horizontalMargin() const { return _horMargin->value(); } bool LayoutTab::horizontalMarginDirty() const { return (!_horMargin->text().isEmpty()); } void LayoutTab::setHorizontalMargin(double horizontalMargin) { _horMargin->setValue(horizontalMargin); } double LayoutTab::verticalMargin() const { return _verMargin->value(); } bool LayoutTab::verticalMarginDirty() const { return (!_verMargin->text().isEmpty()); } void LayoutTab::setVerticalMargin(double verticalMargin) { _verMargin->setValue(verticalMargin); } double LayoutTab::horizontalSpacing() const { return _horSpacing->value(); } bool LayoutTab::horizontalSpacingDirty() const { return (!_horSpacing->text().isEmpty()); } void LayoutTab::setHorizontalSpacing(double horizontalSpacing) { _horSpacing->setValue(horizontalSpacing); } double LayoutTab::verticalSpacing() const { return _verSpacing->value(); } bool LayoutTab::verticalSpacingDirty() const { return (!_verSpacing->text().isEmpty()); } void LayoutTab::setVerticalSpacing(double verticalSpacing) { _verSpacing->setValue(verticalSpacing); } void LayoutTab::clearTabValues() { _horMargin->clear(); _verMargin->clear(); _horSpacing->clear(); _verSpacing->clear(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/scalartab.ui000644 001750 001750 00000022764 11544160207 017757 0ustar00synthsynth000000 000000 ScalarTab 0 0 633 343 Read from data &source true Generate a new vector with the properties given here as the independent variable. Read from data &vector Generate a new vector with the properties given here as the independent variable. &Generate Read from data source 0 0 File name: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 &Field: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false _field false 0 0 &Field: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false _fieldRV false 0 Qt::Horizontal QSizePolicy::Expanding 21 0 false &Connect false Co&nfigure... false F&rame: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _start false Input a number (starting from 0 for the first value), or the format [[[[YYYY:]MM:]DD:]HH:]MM[.SS] for dates. The index of the first data read. For ASCII files, this is the data row number in the file. For frame based files, this is the first frame. 0 false or false false Select this to read data from the end of the file. This is useful for scrolling displays when the file is being appended by another application. &last frame false Generate 0 6 0 0 0 V&alue: false _scalarValue The maximum value of the independent variable. Kst::ComboBox QComboBox
combobox.h
Kst::DataSourceSelector QWidget
datasourceselector.h
kst-2.0.3/src/libkstapp/generaltab.h000644 001750 001750 00000002454 11544160207 017733 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GENERALTAB_H #define GENERALTAB_H #include "dialogtab.h" #include "ui_generaltab.h" #include "kst_export.h" namespace Kst { class GeneralTab : public DialogTab, Ui::GeneralTab { Q_OBJECT public: GeneralTab(QWidget *parent = 0); virtual ~GeneralTab(); bool useOpenGL() const; void setUseOpenGL(const bool useOpenGL); int minimumUpdatePeriod() const; void setMinimumUpdatePeriod(const int Period); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/primitivemodel.cpp000644 001750 001750 00000011001 11544160207 021177 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2011 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "primitivemodel.h" #include #include #include #include #include #include #include #include #include namespace Kst { PrimitiveTreeItem::PrimitiveTreeItem(const QList &data, PrimitiveTreeItem *parent) { parentItem = parent; itemData = data; if (parent) { parent->addChild(this); } } PrimitiveTreeItem::~PrimitiveTreeItem() { qDeleteAll(childItems); } void PrimitiveTreeItem::addChild(PrimitiveTreeItem *item) { childItems.append(item); } PrimitiveTreeItem *PrimitiveTreeItem::child(int row) { return childItems.value(row); } int PrimitiveTreeItem::childCount() const { return childItems.count(); } int PrimitiveTreeItem::row() const { if (parentItem) return parentItem->childItems.indexOf(const_cast(this)); return 0; } int PrimitiveTreeItem::columnCount() const { return itemData.count(); } QVariant PrimitiveTreeItem::data(int column) const { return itemData.value(column); } PrimitiveTreeItem *PrimitiveTreeItem::parent() { return parentItem; } PrimitiveModel::PrimitiveModel(ObjectStore *store) : QAbstractItemModel(), _store(store) { QList rootData; rootData << "Scalars"; _rootItem = new PrimitiveTreeItem(rootData); } PrimitiveModel::~PrimitiveModel() { } int PrimitiveModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return 2; } PrimitiveTreeItem* PrimitiveModel::addPrimitiveTreeItem(const QList& data, PrimitiveTreeItem* parent) { PrimitiveTreeItem* parentItem; if (parent) { parentItem = parent; } else { parentItem = _rootItem; } return new PrimitiveTreeItem(data, parentItem); } int PrimitiveModel::rowCount(const QModelIndex& parent) const { PrimitiveTreeItem *parentItem; if (parent.column() > 0) return 0; if (!parent.isValid()) parentItem = _rootItem; else parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(); } QVariant PrimitiveModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } if (role != Qt::DisplayRole) { return QVariant(); } PrimitiveTreeItem *item = static_cast(index.internalPointer()); return item->data(index.column()); } QModelIndex PrimitiveModel::index(int row, int col, const QModelIndex& parent) const { if (row < 0 || col < 0 || col > 1) { return QModelIndex(); } if (!hasIndex(row, col, parent)) return QModelIndex(); PrimitiveTreeItem *parentItem; if (!parent.isValid()) parentItem = _rootItem; else parentItem = static_cast(parent.internalPointer()); PrimitiveTreeItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, col, childItem); else return QModelIndex(); } QModelIndex PrimitiveModel::parent(const QModelIndex& index) const { Q_ASSERT(_store); if (!index.isValid()) return QModelIndex(); PrimitiveTreeItem *childItem = static_cast(index.internalPointer()); PrimitiveTreeItem *parentItem = childItem->parent(); if (parentItem == _rootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); } QVariant PrimitiveModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) { return QAbstractItemModel::headerData(section, orientation, role); } switch (section) { case Name: return tr("Name"); case Value: return tr("Value"); default: break; } return QVariant(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/aboutdialog.cpp000644 001750 001750 00000005315 11544160207 020453 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2009 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #ifdef KST_HAVE_SVN_REVISION_H #include "svnrevision.h" #include "authors.h" #endif #include "aboutdialog.h" #include #include #include #include namespace Kst { AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent) { setupUi(this); #ifdef KST_HAVE_SVN_REVISION_H QStringList utf8Authors = QString::fromUtf8(kst_authors).trimmed().split(";"); QStringList authors; foreach(const QString& a, utf8Authors) { if (!a.startsWith("#")) { authors << a; } } #else // qmake support QStringList authors = QStringList() << "Barth Netterfield" << "Matthew Truch" << "Nicolas Brisset" << "Staikos Computing Services Inc." << "Rick Chern" << "Sumus Technology Limited" << "Ted Kisner" << "The University of British Columbia" << "The University of Toronto" << "Andrew Walker" << "Peter Kmmel" << "Zongyi Zang"; #endif authors.sort(); authors.replaceInStrings("<", "<"); authors.replaceInStrings(">", ">"); authors.replaceInStrings(QRegExp("^(.*)"), "
  • \\1
  • "); QStringList msg = QStringList() << tr("

    Kst "KSTVERSION" - A data viewing program.

    ") << tr("Revision "SVN_REVISION"

    ") << tr("Copyright © 2000-2011 Barth Netterfield

    ") << tr("Homepage: http://kst-plot.kde.org/
    ") << tr("Please report bugs with the 'Bug Report Wizard' of the 'Help' menu.
    ") << tr("
    Authors and contributors (sorted alphabetically):") << QString("
      ") << authors << QString("
    "); text->setText(msg.join("\n")); connect(text, SIGNAL(anchorClicked(const QUrl &)), this, SLOT(launchURL(const QUrl&))); } AboutDialog::~AboutDialog() { } void AboutDialog::launchURL(const QUrl &link) { QDesktopServices::openUrl ( link ); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/markerstab.ui000644 001750 001750 00000022434 11544160207 020150 0ustar00synthsynth000000 000000 MarkersTab 0 0 611 551 Form Axis Markers Qt::Vertical 20 40 &New marker point: _newMarker 0 0 &Add Qt::Vertical 20 40 C&urrent markers _currentMarkersList QAbstractItemView::ExtendedSelection Qt::Vertical 20 40 &Clear &Remove Qt::Vertical 20 40 Marker Appearance Line st&yle: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _markerLineStyle 0 0 Line co&lor: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _markerLineColor Line &width: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _markerLineWidth Automatic Markers Use curve as marker &source: 0 0 SHOULD NOT BE VISIBLE Create makers on: R&ising edge &Falling edge &Both Use &vector as marker source: Qt::Vertical 20 16 Kst::ColorButton QToolButton
    colorbutton.h
    Kst::VectorSelector QWidget
    vectorselector.h
    Kst::CurveSelector QWidget
    curveselector.h
    kst-2.0.3/src/libkstapp/legendtab.ui000644 001750 001750 00000022636 11544160207 017746 0ustar00synthsynth000000 000000 LegendTab 0 0 660 653 Title: Use automatic plot-based contents true false false GroupBox 0 0 &Available objects: false _availableRelationList Qt::Vertical QSizePolicy::Expanding 128 71 0 0 &Displayed objects: false _displayedRelationList false 0 0 Raise in plot order: Alt+up Alt+Up false 0 0 Remove: Alt+r Alt+R false 0 0 Select: Alt+s Alt+S false 0 0 Lower in plot order: Alt+down Alt+Down Qt::Vertical QSizePolicy::Expanding 128 61 Legend Font Settings 0 0 Font si&ze: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _fontSize 1 -25.000000000000000 1.000000000000000 &Font family Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _family &Bold &Underline &Italics Layout Display &vertically _title _autoContents _availableRelationList _displayedRelationList _up _remove _add _down _fontSize _bold _underline _italic _family _displayVertically kst-2.0.3/src/libkstapp/scene.cpp000644 001750 001750 00000006336 11544160207 017262 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "scene.h" #include "view.h" #include "viewitem.h" #include "plotitem.h" #include "plotrenderitem.h" #include #include #include namespace Kst { Scene::Scene(View *view) : QGraphicsScene(view) { } Scene::~Scene() { } /* * This is reimplemented because of a bug in Qt 4.3 QGraphicScene in the * way it handles context menu events. The docs say that if an item ignores * this event that it'll be passed down to the next item underneath. However, * this does not happen in the default implementation. */ void Scene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QList list = items(event->scenePos()); if (list.isEmpty()) { if (View *view = qobject_cast(parent())) { view->contextMenuEvent(); } } else { foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem) continue; if (viewItem->acceptsContextMenuEvents()) { event->setPos(viewItem->mapFromScene(event->scenePos())); if (viewItem->doSceneEvent(event)) return; } } } QGraphicsScene::contextMenuEvent(event); } void Scene::dragEnterEvent(QGraphicsSceneDragDropEvent* event) { if (MimeDataViewItem::downcast(event->mimeData())) { event->acceptProposedAction(); } } void Scene::dragMoveEvent(QGraphicsSceneDragDropEvent* event) { if (MimeDataViewItem::downcast(event->mimeData())) { event->acceptProposedAction(); } } void Scene::dropEvent(QGraphicsSceneDragDropEvent* event) { const MimeDataViewItem* m = MimeDataViewItem::downcast(event->mimeData()); if (m && m->item) { View* view = qobject_cast(parent()); if (view->viewMode() != View::Layout) { view->setViewMode(View::Layout); } if (view != m->item->view()) { m->item->setView(view); PlotItem* plotItem = qobject_cast(m->item); if (plotItem) { QList renderItems = plotItem->renderItems(); foreach (PlotRenderItem* renderItem, renderItems) { renderItem->setView(view); } } m->item->setParentViewItem(0); addItem(m->item); } m->item->show(); QPointF viewpos = view->mapFromScene(event->scenePos()); m->item->moveTo(viewpos - m->hotSpot); event->acceptProposedAction(); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/legenditemdialog.cpp000644 001750 001750 00000012602 11544160207 021453 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "legenditemdialog.h" #include "legendtab.h" #include "dialogpage.h" #include "application.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" #include "curve.h" #include "curvedialog.h" #include "plotrenderitem.h" #include "plotitem.h" #include "image.h" #include "imagedialog.h" namespace Kst { LegendItemDialog::LegendItemDialog(LegendItem *item, QWidget *parent) : ViewItemDialog(item, parent), _legendItem(item) { _store = kstApp->mainWindow()->document()->objectStore(); _legendTab = new LegendTab(this); connect(_legendTab, SIGNAL(apply()), this, SLOT(legendChanged())); DialogPage *page = new DialogPage(this); page->setPageTitle(tr("Legend")); page->addDialogTab(_legendTab); addDialogPage(page); setupLegend(); setSupportsMultipleEdit(true); QList legends = ViewItem::getItems(); clearMultipleEditOptions(); foreach(LegendItem* legend, legends) { addMultipleEditOption(legend->Name(), legend->descriptionTip(), legend->shortName()); } _saveAsDefault->show(); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultiple())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingle())); connect(this, SIGNAL(apply()), this, SLOT(slotApply())); } LegendItemDialog::~LegendItemDialog() { } void LegendItemDialog::slotApply() { //FIXME: it is not clear that slotApply must be executed last. // experimentally, it seems to be... if (_saveAsDefault->isChecked()) { _legendItem->saveAsDialogDefaults(); } } void LegendItemDialog::setupLegend() { QStringList displayedRelations; QStringList availableRelations; QStringList allRelations; QStringList displayedRelationTips; QStringList availableRelationTips; QStringList allRelationTips; CurveList curves = _store->getObjects(); ImageList images = _store->getObjects(); if (_legendItem->relations().isEmpty()) { foreach (RelationPtr relation, _legendItem->plot()->renderItem(PlotRenderItem::Cartesian)->relationList()) { displayedRelations.append(relation->Name()); displayedRelationTips.append(relation->descriptionTip()); } } else { foreach (RelationPtr relation, _legendItem->relations()) { displayedRelations.append(relation->Name()); displayedRelationTips.append(relation->descriptionTip()); } } foreach (CurvePtr curve, curves) { allRelations.append(curve->Name()); allRelationTips.append(curve->descriptionTip()); if (!displayedRelations.contains(curve->Name())) { availableRelations.append(curve->Name()); availableRelationTips.append(curve->descriptionTip()); } } foreach (ImagePtr image, images) { allRelations.append(image->Name()); allRelationTips.append(image->descriptionTip()); if (!displayedRelations.contains(image->Name())) { availableRelations.append(image->Name()); availableRelationTips.append(image->descriptionTip()); } } _legendTab->setDisplayedRelations(displayedRelations, displayedRelationTips); _legendTab->setAvailableRelations(availableRelations, availableRelationTips); _legendTab->setFont(_legendItem->font()); _legendTab->setFontScale(_legendItem->fontScale()); _legendTab->setTitle(_legendItem->title()); _legendTab->setAutoContents(_legendItem->autoContents()); _legendTab->setVerticalDisplay(_legendItem->verticalDisplay()); } void LegendItemDialog::editMultiple() { _legendTab->clearTabValues(); _legendTab->setSingle(false); } void LegendItemDialog::editSingle() { _legendTab->setSingle(true); setupLegend(); } void LegendItemDialog::legendChanged() { if (editMode() == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { LegendItem* legendItem = (LegendItem*)item; saveLegend(legendItem, false); } } else { saveLegend(_legendItem, true); } } void LegendItemDialog::saveLegend(LegendItem *legendItem, bool save_relations) { legendItem->setFont(_legendTab->font(legendItem->font())); legendItem->setFontScale(_legendTab->fontScale()); legendItem->setTitle(_legendTab->title()); legendItem->setAutoContents(_legendTab->autoContents()); legendItem->setVerticalDisplay(_legendTab->verticalDisplay()); QStringList displayedRelations = _legendTab->displayedRelations(); if (save_relations) { RelationList newRelations; foreach (QString relationName, displayedRelations) { if (RelationPtr relation = kst_cast(_store->retrieveObject(relationName))) { newRelations.append(relation); } } legendItem->setRelations(newRelations); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/exportvectorsdialog.h000644 001750 001750 00000003135 11544160207 021733 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 C. Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EXPORTVECTORSDIALOG_H #define EXPORTVECTORSDIALOG_H #include #include "ui_exportvectorsdialog.h" namespace Kst { class ObjectStore; class ExportVectorsDialog : public QDialog, Ui::ExportVectorsDialog { Q_OBJECT public: ExportVectorsDialog(QWidget *parent = 0); ~ExportVectorsDialog(); void show(); private Q_SLOTS: void addButtonClicked(); void removeButtonClicked(); void addAll(); void removeAll(); void availableDoubleClicked(QListWidgetItem * item); void selectedDoubleClicked(QListWidgetItem * item); void updateButtons(); void OKClicked(); bool apply(); private: Ui::ExportVectorsDialog *ui; void updateVectorList(); ObjectStore *_store; }; } #endif // EXPORTVECTORSDIALOG_H kst-2.0.3/src/libkstapp/plotmarkers.cpp000644 001750 001750 00000012550 11544160207 020523 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // application specific includes #include "plotmarkers.h" #include "objectstore.h" #include #include #include namespace Kst { PlotMarkers::PlotMarkers(bool xAxis) : _xAxis(xAxis), _lineStyle(Qt::SolidLine), _lineWidth(1.0), _vector(0), _curve(0) { } PlotMarkers::~PlotMarkers() { } QList PlotMarkers::markers() { QList calculatedMarkers = _manualMarkers; if (_vector != 0) { _vector->readLock(); for (int i = 0; i < _vector->length(); ++i) { calculatedMarkers << _vector->value(i); } _vector->unlock(); } if (_curve != 0) { _curve->readLock(); int count = _curve->sampleCount(); if (count > 0) { double prevX, prevY; double curX, curY; // scan through the whole curve _curve->point(0, prevX, prevY); for (int i = 1; i < count; i++) { _curve->point(i, curX, curY); if (_xAxis) { if ((_curveMode == RisingEdge || _curveMode == BothEdges) && prevY == 0.0 && curY > 0.0) { calculatedMarkers << curX; } if ((_curveMode == FallingEdge || _curveMode == BothEdges) && prevY > 0.0 && curY == 0.0) { calculatedMarkers << prevX; } } else { if ((_curveMode == RisingEdge || _curveMode == BothEdges) && prevX == 0.0 && curX > 0.0) { calculatedMarkers << curY; } if ((_curveMode == FallingEdge || _curveMode == BothEdges) && prevX > 0.0 && curX == 0.0) { calculatedMarkers << prevY; } } prevX = curX; prevY = curY; } } _curve->unlock(); } return calculatedMarkers; } void PlotMarkers::saveInPlot(QXmlStreamWriter &xml) { xml.writeStartElement("plotmarkers"); xml.writeAttribute("xaxis", QVariant(_xAxis).toString()); xml.writeAttribute("linecolor", QVariant(_lineColor).toString()); xml.writeAttribute("linestyle", QVariant(_lineStyle).toString()); xml.writeAttribute("linewidth", QVariant(_lineWidth).toString()); xml.writeAttribute("curvemode", QVariant(_curveMode).toString()); if (_vector != 0) { xml.writeStartElement("vector"); xml.writeAttribute("tag", _vector->Name()); xml.writeEndElement(); } if (_curve != 0) { xml.writeStartElement("curve"); xml.writeAttribute("tag", _curve->Name()); xml.writeEndElement(); } foreach (double marker, _manualMarkers) { xml.writeStartElement("manualmarker"); xml.writeAttribute("location", QVariant(marker).toString()); xml.writeEndElement(); } xml.writeEndElement(); } bool PlotMarkers::configureFromXml(QXmlStreamReader &xml, ObjectStore *store) { bool validTag = true; QString primaryTag = xml.name().toString(); QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; av = attrs.value("xaxis"); if (!av.isNull()) { _xAxis = QVariant(av.toString()).toBool(); } av = attrs.value("linecolor"); if (!av.isNull()) { _lineColor = QColor(av.toString()); } av = attrs.value("linestyle"); if (!av.isNull()) { _lineStyle = (Qt::PenStyle)QVariant(av.toString()).toInt(); } av = attrs.value("linewidth"); if (!av.isNull()) { _lineWidth = QVariant(av.toString()).toDouble(); } av = attrs.value("curvemode"); if (!av.isNull()) { _curveMode = (CurveMarkerMode)QVariant(av.toString()).toInt(); } QString expectedEnd; while (!(xml.isEndElement() && (xml.name().toString() == primaryTag))) { if (xml.isStartElement() && xml.name().toString() == "vector") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString tagName = attrs.value("tag").toString(); VectorPtr vector = kst_cast(store->retrieveObject(tagName)); if (vector) { setVector(vector); } } else if (xml.isStartElement() && xml.name().toString() == "curve") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString tagName = attrs.value("tag").toString(); CurvePtr curve = kst_cast(store->retrieveObject(tagName)); if (curve) { setCurve(curve); } } else if (xml.isStartElement() && xml.name().toString() == "manualmarker") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); av = attrs.value("location"); if (!av.isNull()) { _manualMarkers << av.toString().toDouble(); } } else if (xml.isEndElement()) { if (xml.name().toString() != expectedEnd) { validTag = false; break; } } xml.readNext(); } return validTag; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datamanager.ui000644 001750 001750 00000005435 11544160207 020263 0ustar00synthsynth000000 000000 DataManager 0 0 750 235 Data Manager Qt::LeftToRight Qt::Horizontal false 0 0 true Qt::Horizontal 601 20 Purge 0 0 Qt::Horizontal QDialogButtonBox::Close _buttonBox accepted() DataManager accept() 248 254 157 274 _buttonBox rejected() DataManager reject() 316 260 286 274 kst-2.0.3/src/libkstapp/editmultiplewidget.cpp000644 001750 001750 00000005330 11544160207 022063 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "editmultiplewidget.h" #include #include namespace Kst { EditMultipleWidget::EditMultipleWidget(QWidget *parent) : QWidget(parent) { setupUi(this); connect(_selectAllBut, SIGNAL(clicked()), this, SLOT(selectAllObjects())); connect(_selectNoneBut, SIGNAL(clicked()), _objectList, SLOT(clearSelection())); connect(_filterEdit, SIGNAL(textChanged(const QString&)), this, SLOT(applyFilter(const QString&))); } EditMultipleWidget::~EditMultipleWidget() {} void EditMultipleWidget::selectAllObjects() { _objectList->selectAll(); } void EditMultipleWidget::applyFilter(const QString& filter) { _objectList->clearSelection(); // case insensitive and wildcards QRegExp re(filter, Qt::CaseInsensitive, QRegExp::Wildcard); uint c = _objectList->count(); for (uint i = 0; i < c; ++i) { if (re.exactMatch(_objectList->item(i)->text())) { _objectList->item(i)->setSelected(true); } } } // void EditMultipleWidget::addObjects(QStringList &objects) { // _objectList->clear(); // _objectList->addItems(objects); // } void EditMultipleWidget::clearObjects() { _objectList->clear(); } void EditMultipleWidget::addObject(QString name, QString descriptionTip) { QListWidgetItem *wi = new QListWidgetItem(name); wi->setToolTip(descriptionTip); _objectList->addItem(wi); } QStringList EditMultipleWidget::selectedObjects() const{ QStringList objects; QList selectedItems = _objectList->selectedItems(); foreach (QListWidgetItem *item, selectedItems) { objects.append(item->text()); } return objects; } void EditMultipleWidget::selectObjects(const QStringList &objects) { int n = _objectList->count(); for (int i=0; iitem(i); if (item) { if (objects.contains(item->text())) { item->setSelected(true); } } } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datadialog.cpp000644 001750 001750 00000015150 11544160207 020250 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include "datadialog.h" #include "datatab.h" #include "dialogpage.h" #include "editmultiplewidget.h" #include "dataobject.h" #include "document.h" #include "mainwindow.h" #include "application.h" #include "updatemanager.h" #include "sessionmodel.h" namespace Kst { DataDialog::DataDialog(Kst::ObjectPtr dataObject, QWidget *parent, bool edit_multiple) : Dialog(parent), _dataObject(dataObject), _modified(false) { _dataObjectName.clear(); if (_dataObject) _mode = Edit; else _mode = New; if (MainWindow *mw = qobject_cast(parent)) { _document = mw->document(); } else { // FIXME: we need a document qFatal("ERROR: can't construct a Data Dialog without a document"); } createGui(edit_multiple); } DataDialog::~DataDialog() { } void DataDialog::createGui(bool edit_multiple) { if (_mode == New) { buttonBox()->button(QDialogButtonBox::Apply)->setVisible(false); } connect(this, SIGNAL(apply()), this, SLOT(slotApply())); QWidget *extension = extensionWidget(); QVBoxLayout *extensionLayout = new QVBoxLayout(extension); extensionLayout->setContentsMargins(0, -1, 0, -1); if (edit_multiple) { _editMultipleWidget = new EditMultipleWidget(); extensionLayout->addWidget(_editMultipleWidget); } else { _editMultipleWidget = 0L; } extension->setLayout(extensionLayout); QWidget *box = topCustomWidget(); QHBoxLayout *layout = new QHBoxLayout(box); _nameLabel = new QLabel(tr("&Name:"), box); _tagString = new QLineEdit(box); connect(_tagString, SIGNAL(textChanged(QString)), this, SLOT(modified())); _nameLabel->setBuddy(_tagString); _shortName = new QLabel(QString(), box); _tagStringAuto = new QCheckBox(tr("&Auto","automatic"), box); connect(_tagStringAuto, SIGNAL(toggled(bool)), _tagString, SLOT(setDisabled(bool))); if (edit_multiple) { _editMultipleButton = new QPushButton(tr("Edit Multiple >>")); _editMultipleButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); connect(_editMultipleButton, SIGNAL(clicked()), this, SLOT(slotEditMultiple())); } QLabel *spacer = new QLabel(); if (_dataObject) { setTagString(_dataObject->descriptiveName()); setShortName(_dataObject->shortName()); _tagStringAuto->setChecked(!_dataObject->descriptiveNameIsManual()); } else { _tagStringAuto->setChecked(true); setTagString(QString()); if (edit_multiple) { _editMultipleButton->setVisible(false); } } layout->addWidget(_nameLabel); layout->addWidget(_tagString); layout->addWidget(_shortName); layout->addWidget(_tagStringAuto); layout->addWidget(spacer); if (edit_multiple) { layout->addWidget(_editMultipleButton); } box->setLayout(layout); } QString DataDialog::tagString() const { return _tagString->text(); } void DataDialog::setTagString(const QString &tagString) { _tagString->setText(tagString); } void DataDialog::setShortName(const QString &name) { _shortName->setText('('+name+')'); } bool DataDialog::tagStringAuto() const { return _tagStringAuto->isChecked(); } void DataDialog::addDataTab(DataTab *tab) { Q_ASSERT(tab); Q_ASSERT(_document); tab->setObjectStore(_document->objectStore()); DialogPage *page = new DialogPage(this); page->setPageTitle(tab->tabTitle()); page->addDialogTab(tab); addDialogPage(page); } void DataDialog::slotApply() { Kst::ObjectPtr ptr; bool do_session_reset = false; if (!dataObject()) { ptr = createNewDataObject(); do_session_reset = true; } else { ptr = editExistingDataObject(); } setDataObject(ptr); UpdateManager::self()->doUpdates(); kstApp->mainWindow()->document()->setChanged(true); if (do_session_reset) { kstApp->mainWindow()->document()->session()->triggerReset(); } clearModified(); } void DataDialog::modified() { _modified = true; updateApplyButton(); } void DataDialog::clearModified() { _modified = false; updateApplyButton(); } void DataDialog::updateApplyButton() { _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(_modified); _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_modified); } void DataDialog::editMultiple(const QList &objects) { slotEditMultiple(); QStringList names; int n = objects.count(); for (int i = 0; i < n; i++) { names.append(objects.at(i)->Name()); } _editMultipleWidget->selectObjects(names); } void DataDialog::slotEditMultiple() { int charWidth = fontMetrics().averageCharWidth(); int currentWidth = width(); int extensionWidth = extensionWidget()->width(); if (extensionWidthsetVisible(!extensionWidget()->isVisible()); if (!extensionWidget()->isVisible()) { _tagString->setVisible(true); _shortName->setVisible(true); _tagStringAuto->setVisible(true); _nameLabel->setVisible(true); setMinimumWidth(currentWidth - extensionWidth); resize(currentWidth - extensionWidth, height()); _mode = Edit; _editMultipleButton->setText(tr("Edit Multiple >>")); emit editSingleMode(); } else { if (currentWidthsetVisible(false); _shortName->setVisible(false); _tagStringAuto->setVisible(false); _nameLabel->setVisible(false); setMinimumWidth(currentWidth + extensionWidth); resize(currentWidth + extensionWidth, height()); _mode = EditMultiple; _editMultipleButton->setText(tr("<< Edit one %1").arg(_shortName->text())); emit editMultipleMode(); } clearModified(); } QString DataDialog::dataObjectName() const { return _dataObjectName; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/bugreportwizard.h000644 001750 001750 00000002336 11544160207 021060 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUGREPORTWIZARD_H #define BUGREPORTWIZARD_H #include #include "ui_bugreportwizard.h" #include "kst_export.h" namespace Kst { class ObjectStore; class BugReportWizard : public QDialog, Ui::BugReportWizard { Q_OBJECT public: BugReportWizard(QWidget *parent); virtual ~BugReportWizard(); private slots: void reportBug(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/svgitem.cpp000644 001750 001750 00000007456 11544160207 017647 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "svgitem.h" #include "debug.h" #include #include #include #include namespace Kst { SvgItem::SvgItem(View *parent, const QString &file) : ViewItem(parent) { if (!file.isNull()) { _svg = new QSvgRenderer(file); QFile svgfile(file); if (svgfile.open(QIODevice::ReadOnly | QIODevice::Text)) { while (!svgfile.atEnd()) { _svgData.append(svgfile.readLine()); } } } else { _svg = new QSvgRenderer(); } setTypeName("Svg"); setLockAspectRatio(true); setLockAspectRatioFixed(true); } SvgItem::~SvgItem() { } void SvgItem::paint(QPainter *painter) { // We can do better here. Cache the svg also. if (_svg->isValid() && rect().isValid()) { _svg->render(painter, rect()); } } void SvgItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("svg"); ViewItem::save(xml); xml.writeStartElement("data"); xml.writeCharacters(qCompress(_svgData).toBase64()); xml.writeEndElement(); xml.writeEndElement(); } } void SvgItem::setSvgData(const QByteArray &svgData) { _svg->load(svgData); _svgData = svgData; } void CreateSvgCommand::createItem() { QString file = QFileDialog::getOpenFileName(_view, tr("Kst: Open Svg Image")); if (file.isEmpty()) return; _item = new SvgItem(_view, file); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } SvgItemFactory::SvgItemFactory() : GraphicsFactory() { registerFactory("svg", this); } SvgItemFactory::~SvgItemFactory() { } ViewItem* SvgItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { SvgItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "svg") { Q_ASSERT(!rc); rc = new SvgItem(view); if (parent) { rc->setParentViewItem(parent); } // Add any new specialized SvgItem Properties here. } else if (xml.name().toString() == "data") { Q_ASSERT(rc); xml.readNext(); QByteArray qbca = QByteArray::fromBase64(xml.text().toString().toLatin1()); rc->setSvgData(qUncompress(qbca)); xml.readNext(); if (!xml.isEndElement() || (xml.name().toString() != "data")) { validTag = false; } xml.readNext(); } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "svg") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating svg object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewcommand.cpp000644 001750 001750 00000002737 11544160207 020477 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "viewcommand.h" #include "application.h" #include "tabwidget.h" #include "view.h" #include #include namespace Kst { ViewCommand::ViewCommand(const QString &text, bool addToStack, QUndoCommand *parent) : QUndoCommand(text, parent), _view(kstApp->mainWindow()->tabWidget()->currentView()) { if (addToStack) { _view->undoStack()->push(this); } } ViewCommand::ViewCommand(View *view, const QString &text, bool addToStack, QUndoCommand *parent) : QUndoCommand(text, parent), _view(view) { if (addToStack) { _view->undoStack()->push(this); } } ViewCommand::~ViewCommand() { } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/scalarmodel.cpp000644 001750 001750 00000003235 11544160207 020446 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "scalarmodel.h" #include #include #include #include #include #include #include #include #include namespace Kst { void ScalarModel::addDataSourcesMetas(DataSourcePtr dataSource, PrimitiveTreeItem* parent) { QStringList scalars = dataSource->scalar().list(); if (scalars.isEmpty()) { return; } PrimitiveTreeItem* item = addPrimitiveTreeItem(QList() << dataSource->descriptiveName(), parent); scalars.sort(); foreach(const QString& scalar, scalars) { double value; DataScalar::ReadInfo readInfo(&value); dataSource->scalar().read(scalar, readInfo); new PrimitiveTreeItem(QList() << scalar << value, item); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/differentiatecurvesdialog.ui000644 001750 001750 00000020733 11544160207 023236 0ustar00synthsynth000000 000000 DifferentiateCurvesDialog 0 0 507 401 Differentiate Curves Property Selection and Cycle Order 0 0 0 0 Raise in Selection Order: Alt+up Alt+Up 0 0 Lower in Selection Order: Alt+down Alt+Down 0 0 Select: Alt+s 0 0 Remove: Alt+r 0 Available: false 0 Selected: false Qt::Vertical QSizePolicy::Expanding 21 61 Qt::Vertical QSizePolicy::Expanding 20 51 Options 0 Qt::Vertical QSizePolicy::Expanding 16 20 0 1 Maximum line width: false 0 Point density: false All High Medium Low Qt::Vertical QSizePolicy::Expanding 40 20 Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok kst-2.0.3/src/libkstapp/exportvectorsdialog.ui000644 001750 001750 00000014123 11544160207 022120 0ustar00synthsynth000000 000000 ExportVectorsDialog 0 0 578 251 Export Vectors Vector Selection 1 0 The source file for the vectors selected in this list will be changed. QAbstractItemView::ExtendedSelection Qt::Vertical 20 40 Select all vectors in the list. Add A&ll Select all vectors in the list. &Add Unselect all vectors in the list. &Remove Unselect all vectors in the list. R&emove All Qt::Vertical QSizePolicy::Expanding 80 51 1 0 The source file for the vectors selected in this list will be changed. QAbstractItemView::ExtendedSelection 0 0 &Save location: false Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok Kst::FileRequester QWidget
    filerequester.h
    _buttonBox accepted() ExportVectorsDialog accept() 310 334 157 274 _buttonBox rejected() ExportVectorsDialog reject() 378 340 286 274
    kst-2.0.3/src/libkstapp/labelpropertiestab.ui000644 001750 001750 00000007300 11544160207 021673 0ustar00synthsynth000000 000000 LabelPropertiesTab Qt::NonModal 0 0 645 229 Form Font &size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _labelFontScale 1 -25.000000000000000 1.000000000000000 Font famil&y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _family Italic Alt+I true Bold Alt+B true points Qt::Vertical 20 131 Kst::ColorButton QToolButton
    colorbutton.h
    Kst::LabelBuilder QWidget
    labelbuilder.h
    kst-2.0.3/src/libkstapp/legenditem.h000644 001750 001750 00000004736 11544160207 017751 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LEGENDITEM_H #define LEGENDITEM_H #include "viewitem.h" #include "graphicsfactory.h" #include "relation.h" namespace Label { struct Parsed; } namespace Kst { class PlotItem; class PlotRenderItem; class LegendItem : public ViewItem { Q_OBJECT public: LegendItem(PlotItem *parent); virtual ~LegendItem(); virtual void paint(QPainter *painter); void setAutoContents(const bool autoContent); bool autoContents() const; void setVerticalDisplay(const bool vertical); bool verticalDisplay() const; QFont font() const; void setFont(const QFont &font); qreal fontScale() const; void setFontScale(const qreal scale); QString title() const; void setTitle(const QString &title); PlotItem* plot() { return _plotItem; } RelationList relations() { return _relations; } void setRelations(RelationList relations) { _relations = relations; } virtual void save(QXmlStreamWriter &xml); virtual void saveInPlot(QXmlStreamWriter &xml); virtual bool configureFromXml(QXmlStreamReader &xml, ObjectStore *store); QString descriptionTip() const; void saveAsDialogDefaults() const; void applyDefaults(); public Q_SLOTS: virtual void edit(); virtual void remove(); protected: virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); private: QSize paintRelation(QString name, RelationPtr relation, QPixmap *pixmap, const QFont &font); PlotItem *_plotItem; bool _auto; QString _title; QFont _font; qreal _fontScale; bool _verticalDisplay; RelationList _relations; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/pluginmenuitemaction.cpp000644 001750 001750 00000002302 11544160207 022412 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "pluginmenuitemaction.h" namespace Kst { PluginMenuItemAction::PluginMenuItemAction(const QString &text, QWidget *parent) : QAction(parent), m_text(text) { connect(this, SIGNAL(triggered()), this, SLOT(triggerWithName())); this->setText(text); } void PluginMenuItemAction::triggerWithName() { emit triggered(m_text); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/pictureitem.cpp000644 001750 001750 00000010746 11544160207 020517 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "pictureitem.h" #include "debug.h" #include "dialogdefaults.h" #include #include #include #include #include #include namespace Kst { PictureItem::PictureItem(View *parent, const QImage &image) : ViewItem(parent) { if (!image.isNull()) { _image = QPixmap::fromImage(image); } setTypeName("Picture"); setLockAspectRatio(true); setLockAspectRatioFixed(true); } PictureItem::~PictureItem() { } void PictureItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("picture"); ViewItem::save(xml); xml.writeStartElement("data"); QByteArray qba; QBuffer buffer(&qba); buffer.open(QIODevice::WriteOnly); _image.toImage().save(&buffer, "PNG"); // writes image into ba in PNG format xml.writeCharacters(qCompress(qba).toBase64()); xml.writeEndElement(); xml.writeEndElement(); } } void PictureItem::setImage(const QImage &image) { _image = QPixmap::fromImage(image); } void PictureItem::paint(QPainter *painter) { // We can do better here. Cache the scaled pixmap also. if (!_image.isNull() && rect().isValid()) { const qreal w = pen().widthF(); painter->drawPixmap(rect().adjusted(w, w, -w, -w), _image, _image.rect()); } } void CreatePictureCommand::createItem() { QString start_dir = _dialogDefaults->value("picture/startdir", ".").toString(); QString filter = "Images ("; QList formats = QImageReader::supportedImageFormats (); for (int i=0; isetValue("picture/startdir", QFileInfo(file).path()); _item = new PictureItem(_view, QImage(file)); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } PictureItemFactory::PictureItemFactory() : GraphicsFactory() { registerFactory("picture", this); } PictureItemFactory::~PictureItemFactory() { } ViewItem* PictureItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { PictureItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "picture") { Q_ASSERT(!rc); rc = new PictureItem(view); if (parent) { rc->setParentViewItem(parent); } // Add any new specialized PictureItem Properties here. } else if (xml.name().toString() == "data") { Q_ASSERT(rc); xml.readNext(); QImage loadedImage; QByteArray qbca = QByteArray::fromBase64(xml.text().toString().toLatin1()); loadedImage.loadFromData(qUncompress(qbca)); rc->setImage(loadedImage); xml.readNext(); if (!xml.isEndElement() || (xml.name().toString() != "data")) { validTag = false; } xml.readNext(); } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "picture") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating picture object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/basicplugindialog.h000644 001750 001750 00000003536 11544160207 021311 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BASICPLUGINDIALOG_H #define BASICPLUGINDIALOG_H #include "datadialog.h" #include "datatab.h" #include "kst_export.h" #include "ui_basicplugintab.h" namespace Kst { class BasicPluginTab : public DataTab, Ui::BasicPluginTab { Q_OBJECT public: explicit BasicPluginTab(QString& pluginName, QWidget *parent = 0); virtual ~BasicPluginTab(); void setObjectStore(ObjectStore *store); DataObjectConfigWidget* configWidget() { return _configWidget; } void loadSettings(); void saveSettings(); private: DataObjectConfigWidget* _configWidget; }; class BasicPluginDialog : public DataDialog { Q_OBJECT public: BasicPluginDialog(QString& pluginName, ObjectPtr dataObject, QWidget *parent = 0); virtual ~BasicPluginDialog(); protected: virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private: BasicPluginTab *_basicPluginTab; QString _pluginName; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/defaultlabelpropertiestab.cpp000644 001750 001750 00000012707 11544160207 023414 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kst_i18n.h" #include "defaultlabelpropertiestab.h" #include namespace Kst { const double USLetterWidth = (11.0 - 1.0)*2.54; // 11 inches with a 1/2" margin in cm const double USLetterHeight = ((8.5 - 1)*2.54); // 8.5 inches, with a 1/2" margin, in cm. const double A4Width = (29.7 - 3.0); // A4 with a 1.5 cm margin; const double A4Height = (21.0 - 3.0); // A4 with a 1.5 cm margin; const double J2cWidth = 9.0; const double J2cHeight = 9.0; DefaultLabelPropertiesTab::DefaultLabelPropertiesTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("Fonts")); _referenceViewSizeCombo->addItem(i18n("Letter"/*, "US Letter sized paper"*/)); _referenceViewSizeCombo->addItem(i18n("A4"/*, "A4 sized paper"*/)); _referenceViewSizeCombo->addItem(i18n("Journal Plot")); _referenceViewSizeCombo->addItem(i18n("Custom"/*, "Custom page size"*/)); _referenceViewSizeCombo->setCurrentIndex(0); referenceViewSizeComboChanged(0); connect(_referenceViewSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(referenceViewSizeComboChanged(int))); connect(_labelFontScale, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_refViewWidth, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_refViewHeight, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_minFontSize, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_labelColor, SIGNAL(changed(const QColor &)), this, SIGNAL(modified())); connect(_family, SIGNAL(currentFontChanged(const QFont &)), this, SIGNAL(modified())); } DefaultLabelPropertiesTab::~DefaultLabelPropertiesTab() { } void DefaultLabelPropertiesTab::referenceViewSizeComboChanged(int i) { switch (i) { case 0: // US Letter _refViewWidth->setValue(USLetterWidth); _refViewWidth->setEnabled(false); _refViewHeight->setValue(USLetterHeight); // 8.5 inches, in cm, with a 1/2" margin. _refViewHeight->setEnabled(false); break; case 1: // A4 210 x 297 mm, _refViewWidth->setValue(A4Width); // A4 with a 1.5 cm margin _refViewWidth->setEnabled(false); _refViewHeight->setValue(A4Height); // A4 with a 1.5 cm margin _refViewHeight->setEnabled(false); break; case 2: // half a page.. _refViewWidth->setValue(J2cWidth); _refViewWidth->setEnabled(false); _refViewHeight->setValue(J2cHeight); _refViewHeight->setEnabled(false); break; case 3: _refViewWidth->setEnabled(true); _refViewHeight->setEnabled(true); break; default: _refViewWidth->setEnabled(true); _refViewHeight->setEnabled(true); } } double DefaultLabelPropertiesTab::referenceViewWidth() const { return (_refViewWidth->value()); } void DefaultLabelPropertiesTab::setReferenceViewWidth(const double width) { _refViewWidth->setValue(width); checkSizeDefaults(); } double DefaultLabelPropertiesTab::referenceViewHeight() const { return (_refViewHeight->value()); } #define isClose(x,y) (fabs(x-y)<0.0001) void DefaultLabelPropertiesTab::checkSizeDefaults() { if (isClose(referenceViewHeight(),USLetterHeight) && isClose(referenceViewWidth(),USLetterWidth) && (_referenceViewSizeCombo->currentIndex() !=0)) { _referenceViewSizeCombo->setCurrentIndex(0); } else if (isClose(referenceViewHeight(),A4Height) && isClose(referenceViewWidth(),A4Width) && (_referenceViewSizeCombo->currentIndex() !=1)) { _referenceViewSizeCombo->setCurrentIndex(1); } else if (isClose(referenceViewHeight(),J2cHeight) && isClose(referenceViewWidth(),J2cWidth) && (_referenceViewSizeCombo->currentIndex() !=2)) { _referenceViewSizeCombo->setCurrentIndex(2); } else { _referenceViewSizeCombo->setCurrentIndex(3); // custom } } void DefaultLabelPropertiesTab::setReferenceViewHeight(const double height) { _refViewHeight->setValue(height); checkSizeDefaults(); } int DefaultLabelPropertiesTab::minimumFontSize() const { return _minFontSize->value(); } void DefaultLabelPropertiesTab::setMinimumFontSize(const int points) { _minFontSize->setValue(points); } qreal DefaultLabelPropertiesTab::labelScale() const { return _labelFontScale->value(); } void DefaultLabelPropertiesTab::setLabelScale(const qreal scale) { _labelFontScale->setValue(scale); } QColor DefaultLabelPropertiesTab::labelColor() const { return _labelColor->color(); } void DefaultLabelPropertiesTab::setLabelColor(const QColor &color) { _labelColor->setColor(color); } QFont DefaultLabelPropertiesTab::labelFont() const { QFont font(_family->currentFont()); return font; } void DefaultLabelPropertiesTab::setLabelFont(const QFont &font) { _family->setCurrentFont(font); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dimensionstab.ui000644 001750 001750 00000017654 11544160207 020664 0ustar00synthsynth000000 000000 DimensionsTab 0 0 324 174 Form 0 0 &Rotation: _rotation -180.000000000000000 360.000000000000000 &Size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _width 4 1.000000000000000 0.010000000000000 0 0 &x _height 4 1.000000000000000 0.010000000000000 &Position: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _x 0 0 &, _y 4 1.000000000000000 0.010000000000000 &Fix aspect ratio 4 1.000000000000000 0.010000000000000 Qt::Vertical 20 23 _fixAspectRatio _x _y _width _height _rotation _fixAspectRatio toggled(bool) _height setHidden(bool) 134 15 223 84 _fixAspectRatio toggled(bool) _dimXlabel setHidden(bool) 105 15 186 89 _x valueChanged(double) DimensionsTab modified() 132 47 36 13 _y valueChanged(double) DimensionsTab modified() 252 45 49 17 _width valueChanged(double) DimensionsTab modified() 95 81 12 64 _height valueChanged(double) DimensionsTab modified() 216 71 207 112 _rotation valueChanged(double) DimensionsTab modified() 174 120 278 111 _fixAspectRatio toggled(bool) DimensionsTab modified() 262 10 72 24 modified() kst-2.0.3/src/libkstapp/rangetab.cpp000644 001750 001750 00000012731 11544160207 017744 0ustar00synthsynth000000 000000 // // C++ Interface: rangetab // // Description: // // // Author: Barth Netterfield , (C) 2008 /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "rangetab.h" namespace Kst { RangeTab::RangeTab(PlotItem* plotItem, QWidget *parent) : DialogTab(parent), _plotItem(plotItem) { setupUi(this); setTabTitle(tr("Range")); connect(_xAuto, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_xMean, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_xBorder, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_xSpike, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_xFixed, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_yAuto, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_yMean, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_yBorder, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_ySpike, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_yFixed, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_xMin, SIGNAL(textEdited(const QString &)), this, SIGNAL(modified())); connect(_xMax, SIGNAL(textEdited(const QString &)), this, SIGNAL(modified())); connect(_xRange, SIGNAL(textEdited(const QString &)), this, SIGNAL(modified())); connect(_yMin, SIGNAL(textEdited(const QString &)), this, SIGNAL(modified())); connect(_yMax, SIGNAL(textEdited(const QString &)), this, SIGNAL(modified())); connect(_yRange, SIGNAL(textEdited(const QString &)), this, SIGNAL(modified())); connect(this, SIGNAL(modified()), this, SLOT(updateButtons())); } RangeTab::~RangeTab() { } void RangeTab::setupRange() { Q_ASSERT(_plotItem); _xRange->setText(QString::number(fabs(_plotItem->xMax() - _plotItem->xMin()),'g', 13)); _xMin->setText(QString::number(_plotItem->xMin(),'g', 13)); _xMax->setText(QString::number(_plotItem->xMax(),'g', 13)); _yRange->setText(QString::number(fabs(_plotItem->yMax() - _plotItem->yMin()),'g', 13)); _yMin->setText(QString::number(_plotItem->yMin(),'g', 13)); _yMax->setText(QString::number(_plotItem->yMax(),'g', 13)); switch (_plotItem->xAxis()->axisZoomMode()) { case PlotAxis::Auto: _xAuto->setChecked(true); break; case PlotAxis::AutoBorder: _xBorder->setChecked(true); break; case PlotAxis::FixedExpression: _xFixed->setChecked(true); break; case PlotAxis::SpikeInsensitive: _xSpike->setChecked(true); break; case PlotAxis::MeanCentered: _xMean->setChecked(true); break; default: break; } switch (_plotItem->yAxis()->axisZoomMode()) { case PlotAxis::Auto: _yAuto->setChecked(true); break; case PlotAxis::AutoBorder: _yBorder->setChecked(true); break; case PlotAxis::FixedExpression: _yFixed->setChecked(true); break; case PlotAxis::SpikeInsensitive: _ySpike->setChecked(true); break; case PlotAxis::MeanCentered: _yMean->setChecked(true); break; default: break; } } void RangeTab::modified() { emit tabModified(); } void RangeTab::clearTabValues() { _xHidden->setChecked(true); _yHidden->setChecked(true); _xRange->clear(); _xMin->clear(); _xMax->clear(); _yRange->clear(); _yMin->clear(); _yMax->clear(); } void RangeTab::updateButtons() { if (!_xHidden->isChecked()) { label->setEnabled(_xMean->isChecked()); _xRange->setEnabled(_xMean->isChecked()); label_2->setEnabled(_xFixed->isChecked()); _xMin->setEnabled(_xFixed->isChecked()); label_3->setEnabled(_xFixed->isChecked()); _xMax->setEnabled(_xFixed->isChecked()); } else { label->setEnabled(true); _xRange->setEnabled(true); label_2->setEnabled(true); _xMin->setEnabled(true); label_3->setEnabled(true); _xMax->setEnabled(true); } if (!_yHidden->isChecked()) { label_4->setEnabled(_yMean->isChecked()); _yRange->setEnabled(_yMean->isChecked()); label_5->setEnabled(_yFixed->isChecked()); _yMin->setEnabled(_yFixed->isChecked()); label_6->setEnabled(_yFixed->isChecked()); _yMax->setEnabled(_yFixed->isChecked()); } else { label_4->setEnabled(true); _yRange->setEnabled(true); label_5->setEnabled(true); _yMin->setEnabled(true); label_6->setEnabled(true); _yMax->setEnabled(true); } } bool RangeTab::xModeDirty() const { return (!_xHidden->isChecked()); } bool RangeTab::xRangeDirty() const { return (!_xRange->text().isEmpty()); } bool RangeTab::xMinDirty() const { return (!_xMin->text().isEmpty()); } bool RangeTab::xMaxDirty() const { return (!_xMax->text().isEmpty()); } bool RangeTab::yModeDirty() const { return (!_yHidden->isChecked()); } bool RangeTab::yRangeDirty() const { return (!_yRange->text().isEmpty()); } bool RangeTab::yMinDirty() const { return (!_yMin->text().isEmpty()); } bool RangeTab::yMaxDirty() const { return (!_yMax->text().isEmpty()); } } kst-2.0.3/src/libkstapp/tabwidget.cpp000644 001750 001750 00000012025 11544160207 020127 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "tabwidget.h" #include "mainwindow.h" #include "view.h" #include "viewitem.h" #include "curveplacement.h" #include "plotitem.h" #include "plotrenderitem.h" #include #include #include #include #include #include namespace Kst { class TabBar : public QTabBar { public: TabBar(); void dragEnterEvent(QDragEnterEvent* event); void dragMoveEvent(QDragMoveEvent* event); void dropEvent(QDropEvent* event); }; TabBar::TabBar() { setAcceptDrops(true); } void TabBar::dragEnterEvent(QDragEnterEvent* event) { if (MimeDataViewItem::downcast(event->mimeData())) { setCurrentIndex(tabAt(event->pos())); event->acceptProposedAction(); } } void TabBar::dragMoveEvent(QDragMoveEvent* event) { if (MimeDataViewItem::downcast(event->mimeData())) { setCurrentIndex(tabAt(event->pos())); event->acceptProposedAction(); } } void TabBar::dropEvent(QDropEvent* event) { event->setDropAction(Qt::IgnoreAction); event->accept(); } TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) { setTabBar(new TabBar); tabBar()->setContextMenuPolicy(Qt::CustomContextMenu); connect(tabBar(), SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(contextMenu(const QPoint&))); _cnt = 0; #if QT_VERSION >= 0x040500 tabBar()->setMovable(true); tabBar()->setExpanding(true); #endif } TabWidget::~TabWidget() { } View *TabWidget::createView() { View *view = new View; addView(view); return view; } void TabWidget::checkedShowTabbar() { if (count() < 2) { tabBar()->hide(); } else { tabBar()->show(); } } void TabWidget::addView(View* view) { MainWindow *parent = qobject_cast(this->parent()); if (parent) { parent->undoGroup()->addStack(view->undoStack()); parent->undoGroup()->setActiveStack(view->undoStack()); } connect(view, SIGNAL(viewModeChanged(View::ViewMode)), this, SIGNAL(currentViewModeChanged())); QString label = view->objectName().isEmpty() ? tr("View &%1").arg(++_cnt) : view->objectName(); addTab(view, label); checkedShowTabbar(); setCurrentWidget(view); } View *TabWidget::currentView() const { return qobject_cast(currentWidget()); } QList TabWidget::views() const { QList v; for (int i = 0; i < count(); ++i) { v.append(qobject_cast(widget(i))); } return v; } void TabWidget::deleteView(View* view) { MainWindow *parent = qobject_cast(this->parent()); if (parent) { parent->undoGroup()->removeStack(view->undoStack()); } removeTab(indexOf(view)); delete view; checkedShowTabbar(); } void TabWidget::clear() { QList tabs = views(); foreach(View* view, tabs) { deleteView(view); } _cnt = 0; checkedShowTabbar(); } void TabWidget::closeCurrentView() { deleteView(currentView()); if (count() == 0) createView(); } void TabWidget::renameCurrentView() { QTabBar *tb = tabBar(); int idx = tb->currentIndex(); bool ok = false; QString rc = QInputDialog::getText(this, tr("Rename Tab"), tr("Enter a new tab name:"), QLineEdit::Normal, tb->tabText(idx), &ok); if (ok) { tb->setTabText(idx, rc); } } void TabWidget::setCurrentViewName(QString name) { int idx = tabBar()->currentIndex(); tabBar()->setTabText(idx, name); } void TabWidget::contextMenu(const QPoint& pos) { QTabBar *tb = tabBar(); int idx = tb->currentIndex(); for (int i = 0; i < tb->count(); ++i) { if (tb->tabRect(i).contains(pos)) { idx = i; tb->setCurrentIndex(i); break; } } const QString txt = tb->tabText(idx); QMenu m(txt, tb); m.addAction(tr("&Add tab"), this, SLOT(createView())); m.addAction(tr("&Rename tab"), this, SLOT(renameCurrentView())); m.addAction(tr("&Close tab"), this, SLOT(closeCurrentView())); m.addSeparator(); m.addAction(tr("&Edit View"), currentView(), SLOT(edit())); QMenu layoutMenu; layoutMenu.setTitle(tr("Cleanup Layout")); layoutMenu.addAction(tr("Automatic"), currentView(), SLOT(createLayout())); layoutMenu.addAction(tr("Custom"), currentView(), SLOT(createCustomLayout())); m.addMenu(&layoutMenu); m.exec(tb->mapToGlobal(pos)); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/matrixtab.ui000644 001750 001750 00000063327 11544160207 020016 0ustar00synthsynth000000 000000 MatrixTab 0 0 516 623 9 4 true Scaling and Translation 0 0 0 X step si&ze: false _xStep 0 0 &X minimum: false _minX 0 0 0 60 0 0 0 0 60 0 1 0 0 &Y minimum: false _minY 0 0 Y ste&p size: false _yStep 0 0 0 60 0 0 0 0 60 0 1 false Gradient Parameters 0 0 Increment/decrement Z values along: false X-axis true Qt::Vertical QSizePolicy::Expanding 40 20 Y-axis 0 1 999999999 100 999999999 100 Z at minimum: false _gradientZAtMin X steps: false _nX Y steps: false _nY Z at maximum: false _gradientZAtMax 100 Data Range 0 0 0 0 or false false 1 999999999 0 0 Y s&tarting frame: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _yStart 0 0 or false 0 0 X n&umber of frames: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _xNumSteps 999999999 false 1 999999999 0 0 C&ount from end 0 0 &Read to end true 0 0 or false 0 0 Y nu&mber of frames: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _yNumSteps 0 0 R&ead to end true 0 0 Count from en&d 0 0 or false 999999999 0 0 X &starting frame: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _xStart 0 false frames 1 999999999 false Boxcar &filter first Read &1 sample per Source 0 Read from data source true Generate gradient Qt::Vertical QSizePolicy::Expanding 40 20 0 0 Data Source Parameters 0 F&ield or column: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _field File name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _fileName false true false 0 Qt::Vertical QSizePolicy::Expanding 181 21 &Connect false Co&nfigure... Kst::ComboBox QComboBox
    combobox.h
    Kst::DataSourceSelector QWidget
    datasourceselector.h
    _readFromSource _generateGradient _fileName _field _configure _xStart _xStartCountFromEnd _yStart _yStartCountFromEnd _xNumSteps _xNumStepsReadToEnd _yNumSteps _yNumStepsReadToEnd _doSkip _skip _doAverage _gradientX _gradientY _gradientZAtMin _gradientZAtMax _nX _nY _minX _minY _xStep _yStep
    kst-2.0.3/src/libkstapp/datawizardpagevectors.ui000644 001750 001750 00000020412 11544160207 022404 0ustar00synthsynth000000 000000 DataWizardPageVectors 0 0 779 313 0 Qt::Vertical QSizePolicy::Expanding 121 102 0 0 0 Raise in plot order (Alt-up) Alt+Up 0 0 Alt+Down 0 0 Select (Alt-s): Move highlighted fields from the Available data list to the Selected data list for plotting. Alt+S 0 0 Remove (Alt-s): Move highlighted fields from the Selected data list to the Available data list so that they will not be plotted. Alt+R Qt::Vertical QSizePolicy::Expanding 138 97 0 Selected data: All fields in this list are plotted. Selected data: All fields in this list are plotted. To remove fields from this list, drag them to the Available data list, double click on them, or select them and use the Remove button (right arrow icon or Alt-r). The order in which fields appear in this list is the order in which they will be plotted. Selected data: false 0 0 0 Appends the '*' wild card to the beginning and end of the search filter to match everything containing the search filter text. S&earch Search Filter Search Filter: Fields matching this filter will be highlighted and moved to the top of the Available data list. '*' and '?' wild cards are supported. Field selection: Checked fields are plotted. Available data: This box lists all fields which have not been selected for plotting. To select a field for plotting, move it to the Selected data list, by dragging it with the mouse, by double clicking, or by highlighting it, and clicking on the select button (Right Arrow - accelerator is Alt-s). QAbstractItemView::ExtendedSelection Available data: false _vectorReduction _vectors _vectorsToPlot _add _remove _up _down _vectorSearch _add clicked() _vectorReduction setFocus() 480 154 237 31 _add clicked() _vectorReduction selectAll() 500 152 256 43 _vectors clicked(QModelIndex) _vectorReduction clear() 94 95 104 30 kst-2.0.3/src/libkstapp/defaultlabelpropertiestab.ui000644 001750 001750 00000015315 11544160207 023245 0ustar00synthsynth000000 000000 DefaultLabelPropertiesTab 0 0 481 303 Form Default font &size (points): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _labelFontScale Size of default font when page is displayed at 'Reference View Size'. Fonts are scaled with the size of window or page. This is the default font size when the window or page is resized to 'Reverence View Size'. 1 -25.000000000000000 1.000000000000000 Font &family: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _family Label &color: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _labelColor &Minimum font size (points): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _minFontSize 0 0 On window resize, fonts will be displayed at least this large. Reference view size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter When the window is this large, fonts will have stated size. Fonts are scaled with the window or print size. When the window/print is this large, the font sizes stated will be accurate. Custom reference size (cm): Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _refViewWidth 0 0 2000.000000000000000 0 0 x Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _refViewHeight 0 0 2000.000000000000000 Qt::Vertical 20 40 Kst::ColorButton QToolButton
    colorbutton.h
    kst-2.0.3/src/libkstapp/arrowitemdialog.h000644 001750 001750 00000002544 11544160207 021020 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ARROWITEMDIALOG_H #define ARROWITEMDIALOG_H #include "viewitemdialog.h" #include "kst_export.h" namespace Kst { class ArrowPropertiesTab; class ArrowItem; class ArrowItemDialog : public ViewItemDialog { Q_OBJECT public: explicit ArrowItemDialog(ArrowItem *item, QWidget *parent = 0); virtual ~ArrowItemDialog(); private Q_SLOTS: void propertiesChanged(); private: void setupProperties(); ArrowPropertiesTab *_propertiesTab; ArrowItem *_arrowItem; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/stringdialog.h000644 001750 001750 00000005365 11544160207 020321 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STRINGDIALOG_H #define STRINGDIALOG_H #include "datadialog.h" #include "datatab.h" #include "datasource.h" #include "ui_stringtab.h" #include #include "kst_export.h" namespace Kst { class StringTab : public DataTab, Ui::StringTab { Q_OBJECT public: enum StringMode { DataString, GeneratedString }; explicit StringTab(ObjectStore *store, QWidget *parent = 0); virtual ~StringTab(); StringMode stringMode() const { return _mode; } void setStringMode(StringMode mode); QString value() const; void setValue(const QString &value); DataSourcePtr dataSource() const; void setDataSource(DataSourcePtr dataSource); QString file() const; void setFile(const QString &file); QString field() const; void setField(const QString &field); void setFieldList(const QStringList &fieldList); void hideGeneratedOptions(); void hideDataOptions(); Q_SIGNALS: void valueChanged(); void sourceChanged(); private Q_SLOTS: void readFromSourceClicked(); void generateClicked(); void textChanged(); void fileNameChanged(const QString &file); void showConfigWidget(); void sourceValid(QString filename, int requestID); private: void updateDataSource(); StringMode _mode; ObjectStore *_store; DataSourcePtr _dataSource; int _requestID; }; class StringDialog : public DataDialog { Q_OBJECT public: explicit StringDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~StringDialog(); protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr createNewGeneratedString(); virtual ObjectPtr createNewDataString(); virtual ObjectPtr editExistingDataObject() const; private: void configureTab(ObjectPtr object); private Q_SLOTS: void updateButtons(); private: StringTab *_stringTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labeltab.h000644 001750 001750 00000005730 11544160207 017375 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELTAB_H #define LABELTAB_H #include "dialogtab.h" #include "plotitem.h" #include "ui_labeltab.h" #include "kst_export.h" namespace Kst { class LabelTab : public DialogTab, Ui::LabelTab { Q_OBJECT public: explicit LabelTab(PlotItem* plotItem, QWidget *parent = 0); virtual ~LabelTab(); QString leftLabel() const; bool leftLabelDirty() const; void setLeftLabel(const QString &label); QString bottomLabel() const; bool bottomLabelDirty() const; void setBottomLabel(const QString &label); QString topLabel() const; bool topLabelDirty() const; void setTopLabel(const QString &label); QString rightLabel() const; bool rightLabelDirty() const; void setRightLabel(const QString &label); bool leftLabelAuto() const; bool leftLabelAutoDirty() const; void setLeftLabelAuto(bool a); bool rightLabelAuto() const; bool rightLabelAutoDirty() const; void setRightLabelAuto(bool a); bool topLabelAuto() const; bool topLabelAutoDirty() const; void setTopLabelAuto(bool a); bool bottomLabelAuto() const; bool bottomLabelAutoDirty() const; void setBottomLabelAuto(bool a); bool showLegend() const; bool showLegendDirty() const; void setShowLegend(const bool show); QFont globalLabelFont(const QFont ref_font) const; bool globalLabelFontDirty() const; qreal globalLabelFontScale() const; bool globalLabelFontScaleDirty() const; QColor globalLabelColor() const; bool globalLabelColorDirty() const; bool autoScaleNumbers() const; bool autoScaleNumbersDirty() const; void setAutoScaleNumbers(const bool scale); void enableSingleEditOptions(bool enabled); void clearTabValues(); Q_SIGNALS: void test(); void globalFontUpdate(); public Q_SLOTS: void update(); private Q_SLOTS: void labelUpdate(const QString&); void labelSelected(); void activateFields(); void buttonUpdate(); void _enableLabelLabels(); private: void setGlobalFont(const QFont &font); PlotItem *_plotItem; QLineEdit* _activeLineEdit; bool _fontDirty; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/choosecolordialog.cpp000644 001750 001750 00000012521 11544160207 021655 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "choosecolordialog.h" #include "datavector.h" #include "datacollection.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" #include "application.h" #include "updatemanager.h" #include "colorsequence.h" #include namespace Kst { ChooseColorDialog::ChooseColorDialog(QWidget *parent) : QDialog(parent) { setupUi(this); MainWindow::setWidgetFlags(this); _grid = 0; if (MainWindow *mw = qobject_cast(parent)) { _store = mw->document()->objectStore(); } else { // FIXME: we need the object store qFatal("ERROR: can't construct a ChooseColorDialog without the object store"); } QMap _dataSourceColors; connect(_buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(OKClicked())); connect(_buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); } ChooseColorDialog::~ChooseColorDialog() { delete _grid; } void ChooseColorDialog::show() { updateColorGroup(); QDialog::show(); } void ChooseColorDialog::updateColorGroup() { // cannot use dataSourceList.fileNames() as it contains datasources that // are not used by any curves or vectors DataVectorList vcList = _store->getObjects(); _dataSourceColors.clear(); for (DataVectorList::Iterator vc_iter = vcList.begin(); vc_iter != vcList.end(); ++vc_iter) { if (! (_dataSourceColors.contains((*vc_iter)->dataSource()))) _dataSourceColors[(*vc_iter)->dataSource()] = (*vc_iter)->dataSource()->color(); } cleanColorGroup(); _grid = new QGridLayout(colorFrame); _grid->setSpacing(8); _grid->setColumnStretch(1,0); int i=0; QMapIterator it(_dataSourceColors); while (it.hasNext()) { it.next(); QLineEdit* dataSourceName = new QLineEdit(colorFrame); dataSourceName->setReadOnly(true); dataSourceName->setText(it.key()->fileName()); _grid->addWidget(dataSourceName,i,0); _lineEdits.push_back(dataSourceName); dataSourceName->show(); ColorButton* dataSourceColor = new ColorButton(colorFrame); dataSourceColor->setColor(it.value()); _grid->addWidget(dataSourceColor,i,1); _colorButtons.push_back(dataSourceColor); dataSourceColor->show(); i++; } adjustSize(); resize(QSize(500, minimumSizeHint().height())); setFixedHeight(height()); } void ChooseColorDialog::cleanColorGroup() { while (!_lineEdits.isEmpty()) { QLineEdit* tempLineEdit = _lineEdits.back(); _lineEdits.pop_back(); delete tempLineEdit; } while (!_colorButtons.isEmpty()) { ColorButton* tempColorButton = _colorButtons.back(); _colorButtons.pop_back(); delete tempColorButton; } delete _grid; } void ChooseColorDialog::OKClicked() { if (_buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) { apply(); } accept(); } void ChooseColorDialog::apply() { CurveList curveList = _store->getObjects(); for (CurveList::iterator curve_iter = curveList.begin(); curve_iter != curveList.end(); ++curve_iter) { VectorPtr vector; CurvePtr curve = kst_cast(*curve_iter); if (_xVector->isChecked()) { vector = curve->xVector(); } else { vector = curve->yVector(); } if (DataVectorPtr dataVector = kst_cast(vector)) { curve->writeLock(); curve->setColor(getColorForFile(dataVector->filename())); curve->registerChange(); curve->unlock(); } } // Store the selected colors in the corresponding datasource objects QMutableMapIterator itDatasource(_dataSourceColors); QListIterator itColorButton(_colorButtons); DataSourcePtr ds; while (itDatasource.hasNext()) { ds = itDatasource.next().key(); ds->setColor(itColorButton.next()->color()); // Per construction there should always be as many color buttons as datasources } updateColorGroup(); // This will update the _dataSourceColors map UpdateManager::self()->doUpdates(true); kstApp->mainWindow()->document()->setChanged(true); } QColor ChooseColorDialog::getColorForFile(const QString &fileName) { QList::Iterator kc_iter = _colorButtons.begin(); for (QList::Iterator fn_iter = _lineEdits.begin(); fn_iter != _lineEdits.end(); ++fn_iter) { if (fileName == (*fn_iter)->text()) { return (*kc_iter)->color(); } ++kc_iter; } return QColor(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/arrowitem.h000644 001750 001750 00000004637 11544160207 017645 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ARROWITEM_H #define ARROWITEM_H #include "lineitem.h" #include "graphicsfactory.h" namespace Kst { class ArrowItem : public LineItem { Q_OBJECT public: ArrowItem(View *parent); virtual ~ArrowItem(); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); bool startArrowHead() { return _startArrowHead; } void setStartArrowHead(const bool enabled) { _startArrowHead = enabled; } bool endArrowHead() { return _endArrowHead; } void setEndArrowHead(const bool enabled) { _endArrowHead = enabled; } qreal startArrowScale() { return _startArrowScale; } void setStartArrowScale(const qreal scale) { _startArrowScale = scale; } qreal endArrowScale() { return _endArrowScale; } void setEndArrowScale(const qreal scale) { _endArrowScale = scale; } virtual QPainterPath shape() const; public Q_SLOTS: virtual void edit(); private: bool _startArrowHead; bool _endArrowHead; qreal _startArrowScale; qreal _endArrowScale; QPolygonF start, end; }; class CreateArrowCommand : public CreateCommand { public: CreateArrowCommand() : CreateCommand(QObject::tr("Create Arrow")) {} CreateArrowCommand(View *view) : CreateCommand(view, QObject::tr("Create Arrow")) {} virtual ~CreateArrowCommand() {} virtual void createItem(); }; class ArrowItemFactory : public GraphicsFactory { public: ArrowItemFactory(); ~ArrowItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/filltab.ui000644 001750 001750 00000006657 11544160207 017443 0ustar00synthsynth000000 000000 FillTab 0 0 400 171 400 0 Form 0 0 &Color: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _color 0 0 &Style: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _style Use &linear gradient false &Reset Gradient false 0 22 Qt::Vertical 20 40 Kst::ColorButton QToolButton
    colorbutton.h
    Kst::GradientEditor QWidget
    gradienteditor.h
    kst-2.0.3/src/libkstapp/matrixdialog.h000644 001750 001750 00000011512 11544160207 020306 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MATRIXDIALOG_H #define MATRIXDIALOG_H #include "datadialog.h" #include "datatab.h" #include "ui_matrixtab.h" #include #include "kst_export.h" #include "datasource.h" namespace Kst { class ObjectStore; class MatrixTab : public DataTab, Ui::MatrixTab { Q_OBJECT public: enum MatrixMode { DataMatrix, GeneratedMatrix }; explicit MatrixTab(ObjectStore *store, QWidget *parent = 0); virtual ~MatrixTab(); MatrixMode matrixMode() const { return _mode; } void setMatrixMode(MatrixMode mode); //DataMatrix mode methods... DataSourcePtr dataSource() const; void setDataSource(DataSourcePtr dataSource); QString file() const; void setFile(const QString &file); QString field() const; void setField(const QString &field); void setFieldList(const QStringList &fieldList); uint nX() const; bool nXDirty() const; void setNX(uint nX); uint nY() const; bool nYDirty() const; void setNY(uint nY); double minX() const; bool minXDirty() const; void setMinX(double minX); double minY() const; bool minYDirty() const; void setMinY(double minY); double stepX() const; bool stepXDirty() const; void setStepX(double stepX); double stepY() const; bool stepYDirty() const; void setStepY(double stepY); int xStart() const; bool xStartDirty() const; void setXStart(int xStart); int yStart() const; bool yStartDirty() const; void setYStart(int yStart); int xNumSteps() const; bool xNumStepsDirty() const; void setXNumSteps(int xNumSteps); int yNumSteps() const; bool yNumStepsDirty() const; void setYNumSteps(int yNumSteps); double gradientZAtMin() const; bool gradientZAtMinDirty() const; void setGradientZAtMin(double gradientZAtMin); double gradientZAtMax() const; bool gradientZAtMaxDirty() const; void setGradientZAtMax(double gradientZAtMax); bool xDirection() const; void setXDirection(bool xDirection); bool doAverage() const; bool doAverageDirty() const; void setDoAverage(bool doAve); bool doSkip() const; bool doSkipDirty() const; void setDoSkip(bool doSkip); int skip() const; bool skipDirty() const; void setSkip(int skip); bool xStartCountFromEnd() const; bool xStartCountFromEndDirty() const; void setXStartCountFromEnd(bool xStartCountFromEnd); bool yStartCountFromEnd() const; bool yStartCountFromEndDirty() const; void setYStartCountFromEnd(bool yStartCountFromEnd); bool xReadToEnd() const; bool xReadToEndDirty() const; void setXReadToEnd(bool xReadToEnd); bool yReadToEnd() const; bool yReadToEndDirty() const; void setYReadToEnd(bool yReadToEnd); void hideGeneratedOptions(); void hideDataOptions(); void enableSingleEditOptions(bool enabled); void clearTabValues(); Q_SIGNALS: void sourceChanged(); private Q_SLOTS: void readFromSourceChanged(); void fileNameChanged(const QString &file); void showConfigWidget(); void sourceValid(QString filename, int requestID); void updateEnables(); void xStartCountFromEndClicked(); void xNumStepsReadToEndClicked(); void yStartCountFromEndClicked(); void yNumStepsReadToEndClicked(); private: MatrixMode _mode; DataSourcePtr _dataSource; ObjectStore *_store; QString _initField; int _requestID; }; class MatrixDialog : public DataDialog { Q_OBJECT public: explicit MatrixDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~MatrixDialog(); protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private: ObjectPtr createNewDataMatrix(); ObjectPtr createNewGeneratedMatrix(); void configureTab(ObjectPtr vector); private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: MatrixTab *_matrixTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/axistab.cpp000644 001750 001750 00000034322 11544160207 017614 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "axistab.h" #include "plotdefines.h" namespace Kst { AxisTab::AxisTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("Axis")); _axisMajorTickSpacing->addItem(tr("Coarse"), 2); _axisMajorTickSpacing->addItem(tr("Normal"), 5); _axisMajorTickSpacing->addItem(tr("Fine"), 10); _axisMajorTickSpacing->addItem(tr("VeryFine"), 15); setAxisMajorTickSpacing(PlotAxis::Normal); _axisMajorLineStyle->addItem("SolidLine", Qt::SolidLine); _axisMajorLineStyle->addItem("DashLine", Qt::DashLine); _axisMajorLineStyle->addItem("DotLine", Qt::DotLine); _axisMajorLineStyle->addItem("DashDotLine", Qt::DashDotLine); _axisMajorLineStyle->addItem("DashDotDotLine", Qt::DashDotDotLine); _axisMajorLineStyle->addItem("CustomDashLine", Qt::CustomDashLine); setAxisMajorGridLineStyle(Qt::DashLine); _axisMinorLineStyle->addItem("SolidLine", Qt::SolidLine); _axisMinorLineStyle->addItem("DashLine", Qt::DashLine); _axisMinorLineStyle->addItem("DotLine", Qt::DotLine); _axisMinorLineStyle->addItem("DashDotLine", Qt::DashDotLine); _axisMinorLineStyle->addItem("DashDotDotLine", Qt::DashDotDotLine); _axisMinorLineStyle->addItem("CustomDashLine", Qt::CustomDashLine); setAxisMinorGridLineStyle(Qt::DashLine); setAxisMajorGridLineColor(Qt::gray); setAxisMinorGridLineColor(Qt::gray); for (uint i = 0; i < numAxisDisplays; i++) { _scaleDisplayType->addItem(AxisDisplays[i].label, QVariant(AxisDisplays[i].type)); } for (uint i = 0; i < numAxisInterpretations; i++) { _scaleInterpretType->addItem(AxisInterpretations[i].label, QVariant(AxisInterpretations[i].type)); } connect(_drawAxisMajorTicks, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_drawAxisMajorGridLines, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_drawAxisMinorGridLines, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_drawAxisMinorTicks, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_axisMajorTickSpacing, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_axisMajorLineStyle, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_axisMinorLineStyle, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_axisMajorLineColor, SIGNAL(changed(const QColor &)), this, SIGNAL(modified())); connect(_axisMinorLineColor, SIGNAL(changed(const QColor &)), this, SIGNAL(modified())); connect(_axisMajorLineWidth, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_axisMinorLineWidth, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_autoMinorTicks, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_autoMinorTicks, SIGNAL(stateChanged(int)), this, SLOT(updateButtons())); connect(_hideBottomLeft, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_hideTopRight, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_scaleInterpret, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_scaleInterpret, SIGNAL(stateChanged(int)), this, SLOT(updateButtons())); connect(_scaleLog, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_scaleReverse, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_scaleDisplayType, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_scaleInterpretType, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_axisMinorTickCount, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_scaleAutoBaseOffset, SIGNAL(stateChanged(int)), this, SLOT(updateButtons())); connect(_scaleAutoBaseOffset, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_scaleBaseOffset, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_significantDigits, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_rotation, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); } AxisTab::~AxisTab() { } PlotAxis::MajorTickMode AxisTab::axisMajorTickSpacing() const { return PlotAxis::MajorTickMode(_axisMajorTickSpacing->itemData(_axisMajorTickSpacing->currentIndex()).toInt()); } bool AxisTab::axisMajorTickSpacingDirty() const { return _axisMajorTickSpacing->currentIndex() != -1; } void AxisTab::setAxisMajorTickSpacing(PlotAxis::MajorTickMode spacing) { _axisMajorTickSpacing->setCurrentIndex(_axisMajorTickSpacing->findData(QVariant(spacing))); } bool AxisTab::drawAxisMajorTicks() const { return _drawAxisMajorTicks->isChecked(); } bool AxisTab::drawAxisMajorTicksDirty() const { return _drawAxisMajorTicks->checkState() != Qt::PartiallyChecked; } void AxisTab::setDrawAxisMajorTicks(const bool enabled) { _drawAxisMajorTicks->setChecked(enabled); } bool AxisTab::drawAxisMajorGridLines() const { return _drawAxisMajorGridLines->isChecked(); } bool AxisTab::drawAxisMajorGridLinesDirty() const { return _drawAxisMajorGridLines->checkState() != Qt::PartiallyChecked; } void AxisTab::setDrawAxisMajorGridLines(const bool enabled) { _drawAxisMajorGridLines->setChecked(enabled); } bool AxisTab::drawAxisMinorTicks() const { return _drawAxisMinorTicks->isChecked(); } bool AxisTab::drawAxisMinorTicksDirty() const { return _drawAxisMinorTicks->checkState() != Qt::PartiallyChecked; } void AxisTab::setDrawAxisMinorTicks(const bool enabled) { _drawAxisMinorTicks->setChecked(enabled); } bool AxisTab::drawAxisMinorGridLines() const { return _drawAxisMinorGridLines->isChecked(); } bool AxisTab::drawAxisMinorGridLinesDirty() const { return _drawAxisMinorGridLines->checkState() != Qt::PartiallyChecked; } void AxisTab::setDrawAxisMinorGridLines(const bool enabled) { _drawAxisMinorGridLines->setChecked(enabled); } Qt::PenStyle AxisTab::axisMajorGridLineStyle() const { return Qt::PenStyle(_axisMajorLineStyle->itemData(_axisMajorLineStyle->currentIndex()).toInt()); } bool AxisTab::axisMajorGridLineStyleDirty() const { return _axisMajorLineStyle->currentIndex() != -1; } void AxisTab::setAxisMajorGridLineStyle(Qt::PenStyle style) { _axisMajorLineStyle->setCurrentIndex(_axisMajorLineStyle->findData(QVariant(style))); } QColor AxisTab::axisMajorGridLineColor() const { return _axisMajorLineColor->color(); } bool AxisTab::axisMajorGridLineColorDirty() const { return _axisMajorLineColor->colorDirty(); } void AxisTab::setAxisMajorGridLineColor(const QColor &color) { _axisMajorLineColor->setColor(color); } qreal AxisTab::axisMajorGridLineWidth() const { return _axisMajorLineWidth->value(); } bool AxisTab::axisMajorGridLineWidthDirty() const { return (!_axisMajorLineWidth->text().isEmpty()); } void AxisTab::setAxisMajorGridLineWidth(qreal width) { _axisMajorLineWidth->setValue(width); } Qt::PenStyle AxisTab::axisMinorGridLineStyle() const { return Qt::PenStyle(_axisMinorLineStyle->itemData(_axisMinorLineStyle->currentIndex()).toInt()); } bool AxisTab::axisMinorGridLineStyleDirty() const { return _axisMinorLineStyle->currentIndex() != -1; } void AxisTab::setAxisMinorGridLineStyle(Qt::PenStyle style) { _axisMinorLineStyle->setCurrentIndex(_axisMinorLineStyle->findData(QVariant(style))); } QColor AxisTab::axisMinorGridLineColor() const { return _axisMinorLineColor->color(); } bool AxisTab::axisMinorGridLineColorDirty() const { return _axisMinorLineColor->colorDirty(); } void AxisTab::setAxisMinorGridLineColor(const QColor &color) { _axisMinorLineColor->setColor(color); } qreal AxisTab::axisMinorGridLineWidth() const { return _axisMinorLineWidth->value(); } bool AxisTab::axisMinorGridLineWidthDirty() const { return (!_axisMinorLineWidth->text().isEmpty());} void AxisTab::setAxisMinorGridLineWidth(qreal width) { _axisMinorLineWidth->setValue(width); } int AxisTab::axisMinorTickCount() const { return _axisMinorTickCount->value(); } bool AxisTab::axisMinorTickCountDirty() const { return (!_axisMinorTickCount->text().isEmpty()); } void AxisTab::setAxisMinorTickCount(const int count) { _axisMinorTickCount->setValue(count); } bool AxisTab::isAutoMinorTickCount() const { return _autoMinorTicks->isChecked(); } bool AxisTab::isAutoMinorTickCountDirty() const { return _autoMinorTicks->checkState() != Qt::PartiallyChecked; } void AxisTab::setAutoMinorTickCount(const bool enabled) { _autoMinorTicks->setChecked(enabled); } int AxisTab::significantDigits() const { return _significantDigits->value(); } bool AxisTab::significantDigitsDirty() const { return (!_significantDigits->text().isEmpty()); } void AxisTab::setSignificantDigits(const int digits) { _significantDigits->setValue(digits); } bool AxisTab::isLog() const { return _scaleLog->isChecked(); } bool AxisTab::isLogDirty() const { return _scaleLog->checkState() != Qt::PartiallyChecked; } void AxisTab::setLog(const bool enabled) { _scaleLog->setChecked(enabled); } bool AxisTab::isAutoBaseOffset() const { return _scaleAutoBaseOffset->isChecked(); } bool AxisTab::isAutoBaseOffsetDirty() const { return _scaleAutoBaseOffset->checkState() != Qt::PartiallyChecked; } void AxisTab::setAutoBaseOffset(const bool enabled) { _scaleAutoBaseOffset->setChecked(enabled); } bool AxisTab::isBaseOffset() const { return _scaleBaseOffset->isChecked(); } bool AxisTab::isBaseOffsetDirty() const { return _scaleBaseOffset->checkState() != Qt::PartiallyChecked; } void AxisTab::setBaseOffset(const bool enabled) { _scaleBaseOffset->setChecked(enabled); } bool AxisTab::isReversed() const { return _scaleReverse->isChecked(); } bool AxisTab::isReversedDirty() const { return _scaleReverse->checkState() != Qt::PartiallyChecked; } void AxisTab::setReversed(const bool enabled) { _scaleReverse->setChecked(enabled); } bool AxisTab::isInterpret() const { return _scaleInterpret->isChecked(); } bool AxisTab::isInterpretDirty() const { return _scaleInterpret->checkState() != Qt::PartiallyChecked; } void AxisTab::setInterpret(const bool enabled) { _scaleInterpret->setChecked(enabled); } AxisDisplayType AxisTab::axisDisplay() const { return AxisDisplayType(_scaleDisplayType->itemData(_scaleDisplayType->currentIndex()).toInt()); } bool AxisTab::axisDisplayDirty() const { return _scaleDisplayType->currentIndex() != -1; } void AxisTab::setAxisDisplay(AxisDisplayType display) { _scaleDisplayType->setCurrentIndex(_scaleDisplayType->findData(QVariant(display))); } AxisInterpretationType AxisTab::axisInterpretation() const { return AxisInterpretationType(_scaleInterpretType->itemData(_scaleInterpretType->currentIndex()).toInt()); } bool AxisTab::axisInterpretationDirty() const { return _scaleInterpretType->currentIndex() != -1; } void AxisTab::setAxisInterpretation(AxisInterpretationType interpret) { _scaleInterpretType->setCurrentIndex(_scaleInterpretType->findData(QVariant(interpret))); } int AxisTab::labelRotation() const { return _rotation->value(); } bool AxisTab::labelRotationDirty() const { return (!_rotation->text().isEmpty()); } void AxisTab::setLabelRotation(const int rotation) { _rotation->setValue(rotation); } bool AxisTab::hideTopRight() const { return (_hideTopRight->isChecked()); } bool AxisTab::hideTopRightDirty() const { return _hideTopRight->checkState() != Qt::PartiallyChecked; } void AxisTab::setHideTopRight(bool hide) { _hideTopRight->setChecked(hide); } bool AxisTab::hideBottomLeft() const { return (_hideBottomLeft->isChecked()); } bool AxisTab::hideBottomLeftDirty() const { return _hideBottomLeft->checkState() != Qt::PartiallyChecked; } void AxisTab::setHideBottomLeft(bool hide) { _hideBottomLeft->setChecked(hide); } void AxisTab::updateButtons() { _scaleBaseOffset->setEnabled(!(_scaleInterpret->checkState() == Qt::PartiallyChecked || _scaleAutoBaseOffset->checkState() == Qt::PartiallyChecked)); _axisMinorTickCount->setEnabled(_autoMinorTicks->checkState() != Qt::Checked); } void AxisTab::enableSingleEditOptions(bool enabled) { if (enabled) { _scaleLog->setTristate(false); _scaleBaseOffset->setTristate(false); _scaleReverse->setTristate(false); _scaleInterpret->setTristate(false); _drawAxisMajorTicks->setTristate(false); _drawAxisMajorGridLines->setTristate(false); _drawAxisMinorTicks->setTristate(false); _drawAxisMinorGridLines->setTristate(false); _autoMinorTicks->setTristate(false); } } void AxisTab::clearTabValues() { _scaleLog->setCheckState(Qt::PartiallyChecked); _scaleAutoBaseOffset->setCheckState(Qt::PartiallyChecked); _scaleBaseOffset->setCheckState(Qt::PartiallyChecked); _scaleReverse->setCheckState(Qt::PartiallyChecked); _scaleInterpret->setCheckState(Qt::PartiallyChecked); _autoMinorTicks->setCheckState(Qt::PartiallyChecked); _significantDigits->clear(); _rotation->clear(); _scaleInterpretType->setCurrentIndex(-1); _scaleDisplayType->setCurrentIndex(-1); _drawAxisMajorTicks->setCheckState(Qt::PartiallyChecked); _drawAxisMajorGridLines->setCheckState(Qt::PartiallyChecked); _drawAxisMinorTicks->setCheckState(Qt::PartiallyChecked); _drawAxisMinorGridLines->setCheckState(Qt::PartiallyChecked); _axisMajorTickSpacing->setCurrentIndex(-1); _axisMajorLineStyle->setCurrentIndex(-1); _axisMinorLineStyle->setCurrentIndex(-1); _axisMajorLineColor->clearSelection(); _axisMinorLineColor->clearSelection(); _axisMinorTickCount->clear(); _hideBottomLeft->setCheckState(Qt::PartiallyChecked); _hideTopRight->setCheckState(Qt::PartiallyChecked); } void AxisTab::setAsYAxis() { _hideBottomLeft->setText(i18n("Hide left")); _hideTopRight->setText(i18n("Hide right")); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewitemdialog.cpp000644 001750 001750 00000031750 11544160207 021174 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "viewitemdialog.h" #include "viewitem.h" #include "filltab.h" #include "stroketab.h" #include "layouttab.h" #include "dimensionstab.h" #include "dialogpage.h" #include "viewgridlayout.h" #include "document.h" #include "mainwindow.h" #include "application.h" #include "editmultiplewidget.h" #include #include #include #include namespace Kst { ViewItemDialog::ViewItemDialog(ViewItem *item, QWidget *parent) : Dialog(parent), _item(item), _mode(Single) { setWindowTitle(tr("Edit View Item")); // semi-hack: set the width of the list widget to 15 characters, which is enough // to say "X-Axis Markers" in english. This is better than setting it to a fixed // number of pixels, as it scales with font size or screen resolution, but // it won't necessairly survive translations, or someone adding a option like // "Do something super important", which has more than 15 characters. // We have to do it here, before the layout is set, and we don't yet know how // what is going into the listWidget. _listWidget->setMinimumWidth(_listWidget->fontMetrics().averageCharWidth()*15); QWidget *extension = extensionWidget(); QVBoxLayout *extensionLayout = new QVBoxLayout(extension); extensionLayout->setContentsMargins(0, -1, 0, -1); _editMultipleWidget = new EditMultipleWidget(); extensionLayout->addWidget(_editMultipleWidget); extension->setLayout(extensionLayout); _editMultipleBox = topCustomWidget(); QHBoxLayout *layout = new QHBoxLayout(_editMultipleBox); _tagStringLabel = new QLabel(tr("&Name:"), _editMultipleBox); _tagString = new QLineEdit(_editMultipleBox); connect(_tagString, SIGNAL(textChanged(QString)), this, SLOT(modified())); _tagStringLabel->setBuddy(_tagString); _editMultipleButton = new QPushButton(tr("Edit Multiple >>")); connect(_editMultipleButton, SIGNAL(clicked()), this, SLOT(slotEditMultiple())); layout->addWidget(_tagStringLabel); layout->addWidget(_tagString); layout->addWidget(_editMultipleButton); _editMultipleBox->setLayout(layout); setSupportsMultipleEdit(false); _fillTab = new FillTab(this); _strokeTab = new StrokeTab(this); _layoutTab = new LayoutTab(this); connect(_fillTab, SIGNAL(apply()), this, SLOT(fillChanged())); connect(_strokeTab, SIGNAL(apply()), this, SLOT(strokeChanged())); connect(_layoutTab, SIGNAL(apply()), this, SLOT(layoutChanged())); DialogPageTab *page = new DialogPageTab(this); page->setPageTitle(tr("Appearance")); page->addDialogTab(_fillTab); page->addDialogTab(_strokeTab); page->addDialogTab(_layoutTab); addDialogPage(page); _dimensionsTab = new DimensionsTab(_item, this); DialogPage *dimensionsPage = new DialogPage(this); dimensionsPage->setPageTitle(tr("Dimensions")); dimensionsPage->addDialogTab(_dimensionsTab); addDialogPage(dimensionsPage); connect(_dimensionsTab, SIGNAL(apply()), this, SLOT(dimensionsChanged())); QList dialogPages = _item->dialogPages(); foreach (DialogPage *dialogPage, dialogPages) addDialogPage(dialogPage); setupFill(); setupStroke(); setupLayout(); setupDimensions(); selectDialogPage(page); connect(_dimensionsTab, SIGNAL(tabModified()), this, SLOT(modified())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(setMultipleEdit())); connect(this, SIGNAL(editSingleMode()), this, SLOT(setSingleEdit())); } ViewItemDialog::~ViewItemDialog() { } void ViewItemDialog::setSupportsMultipleEdit(bool enabled) { _editMultipleBox->setVisible(enabled); } void ViewItemDialog::slotEditMultiple() { int currentWidth = width(); int extensionWidth = extensionWidget()->width(); if (extensionWidth<204) extensionWidth = 204; // FIXME: magic number hack... extensionWidget()->setVisible(!extensionWidget()->isVisible()); _tagString->setEnabled(!extensionWidget()->isVisible()); if (!extensionWidget()->isVisible()) { setMinimumWidth(currentWidth - extensionWidth); resize(currentWidth - extensionWidth, height()); _mode = Single; emit editSingleMode(); } else { setMinimumWidth(currentWidth + extensionWidth); resize(currentWidth + extensionWidth, height()); _mode = Multiple; emit editMultipleMode(); } } void ViewItemDialog::addMultipleEditOption(QString name, QString descriptionTip, QString shortName) { _editMultipleWidget->addObject(name, descriptionTip); _multiNameShortName.insert(name, shortName); } QList ViewItemDialog::selectedMultipleEditObjects() { QList selectedItems; QList allItiems = ViewItem::getItems(); foreach(QString name, _editMultipleWidget->selectedObjects()) { if (_multiNameShortName.contains(name)) { QString shortName = _multiNameShortName[name]; foreach (ViewItem *item, allItiems) { if (item->shortName() == shortName) { selectedItems.append(item); } } // selectedItems.append(multiItems[name]); } } return selectedItems; } void ViewItemDialog::clearMultipleEditOptions() { _editMultipleWidget->clearObjects(); _multiNameShortName.clear(); } void ViewItemDialog::setupFill() { Q_ASSERT(_item); QBrush b = _item->brush(); _fillTab->enableSingleEditOptions(true); _fillTab->setColor(b.color()); _fillTab->setStyle(b.style()); if (const QGradient *gradient = b.gradient()) { _fillTab->setGradient(*gradient); } else { _fillTab->setUseGradient(false); } } void ViewItemDialog::setupStroke() { Q_ASSERT(_item); QPen p = _item->pen(); QBrush b = p.brush(); _strokeTab->setStyle(p.style()); _strokeTab->setWidth(p.widthF()); _strokeTab->setBrushColor(b.color()); _strokeTab->setBrushStyle(b.style()); _strokeTab->setJoinStyle(p.joinStyle()); _strokeTab->setCapStyle(p.capStyle()); } void ViewItemDialog::setupLayout() { Q_ASSERT(_item); _layoutTab->setHorizontalMargin(_item->layoutMargins().width()); _layoutTab->setVerticalMargin(_item->layoutMargins().height()); _layoutTab->setHorizontalSpacing(_item->layoutSpacing().width()); _layoutTab->setVerticalSpacing(_item->layoutSpacing().height()); } void ViewItemDialog::setupDimensions() { _dimensionsTab->enableSingleEditOptions(true); _dimensionsTab->setupDimensions(); } void ViewItemDialog::fillChanged() { Q_ASSERT(_item); if (_mode == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { saveFill(item); } } else { saveFill(_item); } kstApp->mainWindow()->document()->setChanged(true); } void ViewItemDialog::saveFill(ViewItem *item) { QBrush b = item->brush(); QColor color = _fillTab->colorDirty() ? _fillTab->color() : b.color(); Qt::BrushStyle style = _fillTab->styleDirty() ? _fillTab->style() : b.style(); if (_fillTab->useGradientDirty()) { // Apply / unapply gradient if (_fillTab->useGradient()) { b = QBrush(_fillTab->gradient()); } else { b.setColor(color); b.setStyle(style); } } else { // Leave gradient but make other changes. QGradient gradient; if (const QGradient *grad = b.gradient()) { if (_fillTab->gradientDirty()) { gradient = _fillTab->gradient(); } else { gradient = *grad; } b = QBrush(gradient); } else { b.setColor(color); b.setStyle(style); } } item->setBrush(b); } void ViewItemDialog::strokeChanged() { Q_ASSERT(_item); if (_mode == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { saveStroke(item); } } else { saveStroke(_item); } kstApp->mainWindow()->document()->setChanged(true); } void ViewItemDialog::saveStroke(ViewItem *item) { QPen p = item->pen(); QBrush b = p.brush(); Qt::PenStyle style = _strokeTab->styleDirty() ? _strokeTab->style() : p.style(); qreal width = _strokeTab->widthDirty() ? _strokeTab->width() : p.widthF(); QColor brushColor = _strokeTab->brushColorDirty() ? _strokeTab->brushColor() : b.color(); Qt::BrushStyle brushStyle = _strokeTab->brushStyleDirty() ? _strokeTab->brushStyle() : b.style(); Qt::PenJoinStyle joinStyle = _strokeTab->joinStyleDirty() ? _strokeTab->joinStyle() : p.joinStyle(); Qt::PenCapStyle capStyle = _strokeTab->capStyleDirty() ? _strokeTab->capStyle() : p.capStyle(); p.setStyle(style); p.setWidthF(width); b.setColor(brushColor); b.setStyle(brushStyle); p.setJoinStyle(joinStyle); p.setCapStyle(capStyle); p.setBrush(b); #ifdef Q_WS_WIN32 if (p.isCosmetic()) { p.setWidth(1); } #endif item->setItemPen(p); } void ViewItemDialog::layoutChanged() { Q_ASSERT(_item); if (_mode == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { saveLayout(item); } } else { saveLayout(_item); } kstApp->mainWindow()->document()->setChanged(true); } void ViewItemDialog::saveLayout(ViewItem *item) { Q_ASSERT(_item); qreal horizontalMargin = _layoutTab->horizontalMarginDirty() ? _layoutTab->horizontalMargin() :item->layoutMargins().width(); qreal verticalMargin = _layoutTab->verticalMarginDirty() ? _layoutTab->verticalMargin() :item->layoutMargins().height(); qreal horizontalSpacing = _layoutTab->horizontalSpacingDirty() ? _layoutTab->horizontalSpacing() :item->layoutSpacing().width(); qreal verticalSpacing = _layoutTab->verticalSpacingDirty() ? _layoutTab->verticalSpacing() :item->layoutSpacing().height(); item->setLayoutMargins(QSizeF(horizontalMargin, verticalMargin)); item->setLayoutSpacing(QSizeF(horizontalSpacing, verticalSpacing)); } void ViewItemDialog::dimensionsChanged() { Q_ASSERT(_item); if (_mode == Multiple) { foreach(ViewItem* item, selectedMultipleEditObjects()) { saveDimensions(item); } } else { saveDimensions(_item); } kstApp->mainWindow()->document()->setChanged(true); } void ViewItemDialog::saveDimensions(ViewItem *item) { Q_ASSERT(item); qreal parentWidth; qreal parentHeight; qreal parentX; qreal parentY; if (item->parentViewItem()) { parentWidth = item->parentViewItem()->width(); parentHeight = item->parentViewItem()->height(); parentX = item->parentViewItem()->rect().x(); parentY = item->parentViewItem()->rect().y(); } else if (item->view()) { parentWidth = item->view()->width(); parentHeight = item->view()->height(); parentX = item->view()->rect().x(); parentY = item->view()->rect().y(); } else { Q_ASSERT_X(false,"parent test", "item has no parentview item"); parentWidth = parentHeight = 1.0; parentX = parentY = 0.0; } qreal aspectRatio; if (rect().width() > 0) { aspectRatio = qreal(item->rect().height()) / qreal(item->rect().width()); } else { aspectRatio = 10000.0; } qreal relativeWidth = _dimensionsTab->widthDirty() ? _dimensionsTab->width() :item->relativeWidth(); qreal relativeHeight = _dimensionsTab->heightDirty() ? _dimensionsTab->height() :item->relativeHeight(); bool fixedAspect = _dimensionsTab->fixedAspectDirty() ? _dimensionsTab->fixedAspect() :item->lockAspectRatio(); qreal width = relativeWidth * parentWidth; qreal height; if (fixedAspect) { height = width * aspectRatio; item->setLockAspectRatio(true); } else { height = relativeHeight * parentHeight; item->setLockAspectRatio(false); } if (_mode == Multiple) { item->setPos(parentX + item->relativeCenter().x()*parentWidth, parentY + item->relativeCenter().y()*parentHeight); } else { item->setPos(parentX + _dimensionsTab->x()*parentWidth, parentY + _dimensionsTab->y()*parentHeight); } item->setViewRect(-width/2, -height/2, width, height); qreal rotation = _dimensionsTab->rotationDirty() ? _dimensionsTab->rotation() :item->rotationAngle(); QTransform transform; transform.rotate(rotation); item->setTransform(transform); item->updateRelativeSize(); } void ViewItemDialog::setSingleEdit() { setupFill(); setupStroke(); setupLayout(); setupDimensions(); _mode = Single; _editMultipleButton->setText(tr("Edit Multiple >>")); } void ViewItemDialog::setMultipleEdit() { _mode = Multiple; _dimensionsTab->clearTabValues(); _dimensionsTab->enableSingleEditOptions(false); _fillTab->clearTabValues(); _strokeTab->clearTabValues(); _layoutTab->clearTabValues(); _editMultipleButton->setText(tr("<< Edit One")); setAlwaysAllowApply(true); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/libkstapp.pro000644 001750 001750 00000015513 11544160207 020171 0ustar00synthsynth000000 000000 TOPOUT_REL = ../.. include($$PWD/$$TOPOUT_REL/kst.pri) QT += gui \ network \ svg \ opengl TEMPLATE = lib TARGET = $$kstlib(kst2app) DESTDIR = $$OUTPUT_DIR/lib win32:CONFIG += staticlib !isEmpty(INSTALL_PREFIX) { target.path = $$INSTALL_PREFIX/$$INSTALL_LIBDIR INSTALLS += target } INCLUDEPATH += tmp \ $$TOPLEVELDIR/src/libkst \ $$TOPLEVELDIR/src/libkstmath \ $$TOPLEVELDIR/src/widgets \ $$TOPOUTDIR/src/widgets \ $$TOPOUTDIR/src/libkstapp/tmp macx { CONFIG += lib_bundle LIBS += -F$$OUTPUT_DIR/lib qtAddLibrary(kst2lib) qtAddLibrary(kst2widgets) qtAddLibrary(kst2math) } else { LIBS += -L$$OUTPUT_DIR/lib \ -L$$OUTPUT_DIR/plugin \ -l$$kstlib(kst2widgets) \ -l$$kstlib(kst2math) \ -l$$kstlib(kst2lib) } SOURCES += aboutdialog.cpp \ application.cpp \ applicationsettings.cpp \ applicationsettingsdialog.cpp \ arrowitem.cpp \ arrowitemdialog.cpp \ arrowpropertiestab.cpp \ axis.cpp \ axistab.cpp \ basicplugindialog.cpp \ boxitem.cpp \ bugreportwizard.cpp \ builtingraphics.cpp \ cartesianrenderitem.cpp \ changedatasampledialog.cpp \ changefiledialog.cpp \ childviewoptionstab.cpp \ choosecolordialog.cpp \ circleitem.cpp \ commandlineparser.cpp \ contenttab.cpp \ csddialog.cpp \ curvedialog.cpp \ databutton.cpp \ databuttonaction.cpp \ datadialog.cpp \ datagui.cpp \ datamanager.cpp \ datasourcedialog.cpp \ datatab.cpp \ datawizard.cpp \ debugdialog.cpp \ debugnotifier.cpp \ defaultlabelpropertiestab.cpp \ dialog.cpp \ dialoglaunchergui.cpp \ dialogpage.cpp \ dialogtab.cpp \ differentiatecurvesdialog.cpp \ dimensionstab.cpp \ document.cpp \ editmultiplewidget.cpp \ ellipseitem.cpp \ equationdialog.cpp \ eventmonitordialog.cpp \ exportgraphicsdialog.cpp \ filltab.cpp \ filterfitdialog.cpp \ generaltab.cpp \ graphicsfactory.cpp \ gridlayouthelper.cpp \ gridtab.cpp \ histogramdialog.cpp \ imagedialog.cpp \ labelcreator.cpp \ labelitem.cpp \ labelitemdialog.cpp \ labelpropertiestab.cpp \ labelrenderer.cpp \ labeltab.cpp \ layoutboxitem.cpp \ layouttab.cpp \ legenditem.cpp \ legenditemdialog.cpp \ legendtab.cpp \ lineitem.cpp \ logdialog.cpp \ logwidget.cpp \ mainwindow.cpp \ markerstab.cpp \ matrixdialog.cpp \ matrixmodel.cpp \ memorywidget.cpp \ overridelabeltab.cpp \ pictureitem.cpp \ plotaxis.cpp \ plotitem.cpp \ plotitemdialog.cpp \ plotitemmanager.cpp \ plotmarkers.cpp \ plotrenderitem.cpp \ powerspectrumdialog.cpp \ primitivemodel.cpp \ rangetab.cpp \ scalardialog.cpp \ scalarmodel.cpp \ scene.cpp \ selectionrect.cpp \ sessionmodel.cpp \ sharedaxisboxitem.cpp \ stringdialog.cpp \ stringmodel.cpp \ stroketab.cpp \ svgitem.cpp \ tabwidget.cpp \ vectordialog.cpp \ vectormodel.cpp \ viewcommand.cpp \ view.cpp \ viewdialog.cpp \ viewgridlayout.cpp \ viewitem.cpp \ viewitemdialog.cpp \ viewmatrixdialog.cpp \ viewprimitivedialog.cpp \ viewvectordialog.cpp \ pluginmenuitemaction.cpp \ exportvectorsdialog.cpp HEADERS += aboutdialog.h \ application.h \ applicationsettings.h \ applicationsettingsdialog.h \ arrowitem.h \ arrowitemdialog.h \ arrowpropertiestab.h \ axis.h \ axistab.h \ basicplugindialog.h \ boxitem.h \ bugreportwizard.h \ builtingraphics.h \ cartesianrenderitem.h \ changedatasampledialog.h \ changefiledialog.h \ childviewoptionstab.h \ choosecolordialog.h \ circleitem.h \ commandlineparser.h \ contenttab.h \ csddialog.h \ curvedialog.h \ databutton.h \ databuttonaction.h \ datadialog.h \ datagui.h \ datamanager.h \ dataref.h \ datasourcedialog.h \ datatab.h \ datawizard.h \ debugdialog.h \ debugnotifier.h \ defaultlabelpropertiestab.h \ dialog.h \ dialoglaunchergui.h \ dialogpage.h \ dialogtab.h \ differentiatecurvesdialog.h \ dimensionstab.h \ document.h \ editmultiplewidget.h \ ellipseitem.h \ equationdialog.h \ eventmonitordialog.h \ exportgraphicsdialog.h \ filltab.h \ filterfitdialog.h \ generaltab.h \ graphicsfactory.h \ gridlayouthelper.h \ gridtab.h \ histogramdialog.h \ imagedialog.h \ labelcreator.h \ labelitem.h \ labelitemdialog.h \ labelpropertiestab.h \ labelrenderer.h \ labeltab.h \ layoutboxitem.h \ layouttab.h \ legenditem.h \ legenditemdialog.h \ legendtab.h \ lineitem.h \ logdialog.cpp\ logwidget.h \ mainwindow.h \ markerstab.h \ matrixdialog.h \ matrixmodel.h \ memorywidget.h \ overridelabeltab.h \ pictureitem.h \ plotaxis.h \ plotitem.h \ plotitemdialog.h \ plotmarkers.h \ plotitemmanager.h \ plotrenderitem.h \ powerspectrumdialog.h \ primitivemodel.h \ rangetab.h \ scalardialog.h \ scalarmodel.h \ scene.h \ selectionrect.h \ sessionmodel.h \ sharedaxisboxitem.h \ stringdialog.h \ stringmodel.h \ svgitem.h \ stroketab.h \ tabwidget.h \ vectordialog.h \ vectormodel.h \ viewcommand.h \ view.h \ viewdialog.h \ viewgridlayout.h \ viewitemdialog.h \ viewitem.h \ viewmatrixdialog.h \ viewprimitivedialog.h \ viewvectordialog.h \ pluginmenuitemaction.h \ logdialog.h \ exportvectorsdialog.h FORMS += aboutdialog.ui \ arrowpropertiestab.ui \ axistab.ui \ basicplugintab.ui \ bugreportwizard.ui \ changedatasampledialog.ui \ changefiledialog.ui \ childviewoptionstab.ui \ choosecolordialog.ui \ contenttab.ui \ csdtab.ui \ curvetab.ui \ datamanager.ui \ datawizardpagedatapresentation.ui \ datawizardpagedatasource.ui \ datawizardpagefilters.ui \ datawizardpageplot.ui \ datawizardpagevectors.ui \ debugdialog.ui \ defaultlabelpropertiestab.ui \ dialog.ui \ differentiatecurvesdialog.ui \ dimensionstab.ui \ editmultiplewidget.ui \ equationtab.ui \ eventmonitortab.ui \ exportgraphicsdialog.ui \ filltab.ui \ filterfittab.ui \ generaltab.ui \ gridtab.ui \ histogramtab.ui \ imagetab.ui \ labelcreator.ui \ labeltab.ui \ labelpropertiestab.ui \ layouttab.ui \ legendtab.ui \ logdialog.ui \ markerstab.ui \ matrixtab.ui \ powerspectrumtab.ui \ overridelabeltab.ui \ rangetab.ui \ scalartab.ui \ stringtab.ui \ stroketab.ui \ vectortab.ui \ viewmatrixdialog.ui \ viewprimitivedialog.ui \ viewvectordialog.ui \ exportvectorsdialog.ui RESOURCES += $$TOPLEVELDIR/src/images/images.qrc kst-2.0.3/src/libkstapp/debugnotifier.cpp000644 001750 001750 00000005011 11544160207 021000 0ustar00synthsynth000000 000000 /*************************************************************************** debugnotifier.cpp ----------------- begin : Sep 13 2005 copyright : (C) 2005 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "debugnotifier.h" #include #include #include #define TIMER_TICK 250 #define TIMER_ITERATIONS 10 namespace Kst { DebugNotifier::DebugNotifier(QWidget *parent) : QLabel(parent) { _animationStage = 0; _gotPress = false; setToolTip(tr("An error has occurred. Click on this icon for more details.")); #define IMAGE_STAGES 2 _pm.resize(IMAGE_STAGES); _pm[0] = QPixmap("kst/pics/kst_error_1.png"); // FIXME _pm[1] = QPixmap("kst/pics/kst_error_2.png"); // FIXME setPixmap(_pm[0]); show(); QTimer::singleShot(TIMER_TICK, this, SLOT(animate())); } DebugNotifier::~DebugNotifier() { } void DebugNotifier::close() { _animationStage = 999; deleteLater(); } void DebugNotifier::animate() { if (_animationStage > TIMER_ITERATIONS) { setPixmap(_pm[0]); return; } setPixmap(_pm[_animationStage % IMAGE_STAGES]); QTimer::singleShot(TIMER_TICK, this, SLOT(animate())); ++_animationStage; } void DebugNotifier::reanimate() { if (_animationStage <= TIMER_ITERATIONS) { return; } _animationStage = 0; setPixmap(_pm[0]); QTimer::singleShot(TIMER_TICK, this, SLOT(animate())); } void DebugNotifier::mousePressEvent(QMouseEvent *e) { if (rect().contains(e->pos())) { _gotPress = true; } } void DebugNotifier::mouseReleaseEvent(QMouseEvent *e) { if (_gotPress && rect().contains(e->pos()) && e->button() == Qt::LeftButton) { emit showDebugLog(); close(); } _gotPress = false; } } #undef TIMER_ITERATIONS // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialogpage.h000644 001750 001750 00000003736 11544160207 017727 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIALOGPAGE_H #define DIALOGPAGE_H #include #include #include "kst_export.h" namespace Kst { class Dialog; class DialogTab; class DialogPage : public QWidget { Q_OBJECT public: DialogPage(Dialog *parent); virtual ~DialogPage(); Dialog *dialog() const; QString pageTitle() const { return _pageTitle; } void setPageTitle(const QString &pageTitle) { _pageTitle = pageTitle; } QPixmap pageIcon() const { return _pageIcon; } void setPageIcon(const QPixmap &pageIcon) { _pageIcon = pageIcon; } void addDialogTab(DialogTab *tab); virtual QWidget* currentWidget(); Q_SIGNALS: void ok(); void apply(); void cancel(); void modified(); private: QString _pageTitle; QPixmap _pageIcon; QPointer _dialog; QWidget* _widget; }; class DialogPageTab : public DialogPage { Q_OBJECT public: DialogPageTab(Dialog *parent); virtual ~DialogPageTab(); void addDialogTab(DialogTab *tab); void setTabText(int i, const QString &title); QWidget* currentWidget(); private: QTabWidget* _tabWidget; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialoglaunchergui.h000644 001750 001750 00000005101 11544160207 021305 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIALOGLAUNCHERGUI_H #define DIALOGLAUNCHERGUI_H #include "dialoglauncher.h" #include "kst_export.h" namespace Kst { class DialogLauncherGui : public DialogLauncher { public: DialogLauncherGui(); virtual ~DialogLauncherGui(); //primitives virtual void showVectorDialog(QString &vectorname, ObjectPtr objectPtr = 0, bool modal = false); virtual void showMatrixDialog(QString &matrixName, ObjectPtr objectPtr = 0, bool modal = false); virtual void showScalarDialog(QString &scalarname, ObjectPtr objectPtr = 0, bool modal = false); virtual void showStringDialog(QString &stringname, ObjectPtr objectPtr = 0, bool modal = false); //standard objects virtual void showCurveDialog(ObjectPtr objectPtr = 0, VectorPtr vector = 0); virtual void showMultiCurveDialog(QList curves); virtual void showImageDialog(ObjectPtr objectPtr = 0, MatrixPtr matrix = 0); virtual void showMultiImageDialog(QList images); //standard data objects virtual void showEquationDialog(ObjectPtr objectPtr = 0); virtual void showHistogramDialog(ObjectPtr objectPtr = 0, VectorPtr vector = 0); virtual void showPowerSpectrumDialog(ObjectPtr objectPtr = 0, VectorPtr vector = 0); virtual void showCSDDialog(ObjectPtr objectPtr = 0, VectorPtr vector = 0); virtual void showEventMonitorDialog(ObjectPtr objectPtr = 0); //plugins virtual void showBasicPluginDialog(QString pluginName, ObjectPtr objectPtr = 0, VectorPtr vectorX = 0, VectorPtr vectorY = 0, PlotItemInterface *plotItem = 0 ); //show appropriate dialog virtual void showObjectDialog(ObjectPtr objectPtr = 0); virtual void showMultiObjectDialog(QList objects); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/sessionmodel.cpp000644 001750 001750 00000017633 11544160207 020673 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "sessionmodel.h" #include #include #include #include #include #include #include #include #include #include namespace Kst { SessionModel::SessionModel(ObjectStore *store) : QAbstractItemModel(), _store(store) { generateObjectList(); } SessionModel::~SessionModel() { } int SessionModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return 4; } void SessionModel::triggerReset() { generateObjectList(); reset(); } void SessionModel::generateObjectList() { ObjectList pol = _store->getObjects(); ObjectList rol = _store->getObjects(); ObjectList dol = _store->getObjects(); _objectList.clear(); foreach(Primitive* P, pol) { if (!P->provider()) { _objectList.append(P); } } foreach(Relation* relation, rol) { _objectList.append(relation); } foreach(DataObject* dataObject, dol) { _objectList.append(dataObject); } } int SessionModel::rowCount(const QModelIndex& parent) const { Q_ASSERT(_store); //ObjectList dol = generateObjectList(); int rc = 0; if (!parent.isValid()) { rc = _objectList.count(); /* + generated primitives */ return rc; } if (parent.parent().isValid()) { return rc; } DataObject *pdo = kst_cast(_objectList.at(parent.row())); if (pdo) { pdo->readLock(); rc = pdo->outputVectors().count(); rc += pdo->outputMatrices().count(); pdo->unlock(); } return rc; } QVariant SessionModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } if (role == Qt::UserRole) { if (index.parent().isValid()) { Q_ASSERT(!index.parent().parent().isValid()); QVariant p = data(index.parent(), role); DataObjectPtr parent = qVariantValue(p); const int vectorCount = parent->outputVectors().count(); if (index.row() < vectorCount) { if (VectorPtr v = parent->outputVectors().values()[index.row()]) { return qVariantFromValue(v.data()); } } else if (MatrixPtr m = parent->outputMatrices().values()[index.row() - vectorCount]) { return qVariantFromValue(m.data()); } } else { Q_ASSERT(_store); DataObjectPtr p = kst_cast(_objectList.at(index.row())); return qVariantFromValue(p.data()); } } if (role != Qt::DisplayRole) { return QVariant(); } if (index.internalPointer()) { //parent().isValid()) { Q_ASSERT(!index.parent().parent().isValid()); DataObject *parent = static_cast(index.internalPointer()); return dataObjectOutputData(parent, index); } Q_ASSERT(_store); //ObjectList objectList = generateObjectList(); const int row = index.row(); if (row >= _objectList.count()) { return QVariant(); } if (DataObjectPtr p = kst_cast(_objectList.at(row))) { return dataObjectData(p, index); } else if (RelationPtr p = kst_cast(_objectList.at(row))) { return relationData(p, index); } else if (PrimitivePtr p=kst_cast(_objectList.at(row))) { return primitiveData(p, index); } else { return QVariant(); } } QVariant SessionModel::dataObjectOutputData(DataObjectPtr parent, const QModelIndex& index) const { QVariant rc; if (!parent) { return rc; } const int row = index.row(); const int vectorCount = parent->outputVectors().count(); if (parent->outputVectors().count() > row) { if (VectorPtr v = parent->outputVectors().values()[row]) { return primitiveData(v, index); } } else if (MatrixPtr m = parent->outputMatrices().values()[row - vectorCount]) { return primitiveData(m, index); } return rc; } QVariant SessionModel::primitiveData(PrimitivePtr p, const QModelIndex& index) const { QVariant rc; if (!p) { return rc; } p->readLock(); switch (index.column()) { case 0: rc.setValue(p->Name()); break; case 1: rc = p->typeString(); break; case 2: rc = p->sizeString(); break; case 3: rc = p->propertyString(); break; default: break; } p->unlock(); return rc; } QVariant SessionModel::dataObjectData(DataObjectPtr p, const QModelIndex& index) const { QVariant rc; if (!p) { return rc; } switch (index.column()) { case 0: p->readLock(); rc.setValue(p->Name()); p->unlock(); break; case 1: p->readLock(); rc = p->typeString(); p->unlock(); break; case 2: p->readLock(); rc = p->sampleCount(); p->unlock(); break; case 3: p->readLock(); rc = p->propertyString(); p->unlock(); break; default: break; } return rc; } QVariant SessionModel::relationData(RelationPtr p, const QModelIndex& index) const { QVariant rc; if (!p) { return rc; } switch (index.column()) { case 0: p->readLock(); rc.setValue(p->Name()); p->unlock(); break; case 1: p->readLock(); rc = p->typeString(); p->unlock(); break; case 2: p->readLock(); rc = p->sampleCount(); p->unlock(); break; case 3: p->readLock(); rc = p->propertyString(); p->unlock(); break; default: break; } return rc; } QModelIndex SessionModel::index(int row, int col, const QModelIndex& parent) const { if (row < 0 || col < 0 || col > 4) { return QModelIndex(); } Q_ASSERT(_store); //ObjectList dol = generateObjectList(); if (!parent.isValid()) { const int cnt = _objectList.count(); if (row >= cnt) { return QModelIndex(); } return createIndex(row, col); } const int cnt = _objectList.count(); DataObject *p = 0; if (parent.row() >= 0 && parent.row() < cnt) { p = kst_cast(_objectList.at(parent.row())); } if (!p) { return QModelIndex(); } p->readLock(); if (row >= (p->outputVectors().count() + p->outputMatrices().count())) { p->unlock(); return QModelIndex(); } p->unlock(); return createIndex(row, col, p); } QModelIndex SessionModel::parent(const QModelIndex& index) const { // If it is a primitive and has a provider, return the index of that provider DataObject *dop = static_cast(index.internalPointer()); if (!dop) { return QModelIndex(); } Q_ASSERT(_store); const int cnt = _objectList.indexOf(dop); if (cnt < 0) { return QModelIndex(); } return createIndex(cnt, index.column()); } QVariant SessionModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) { return QAbstractItemModel::headerData(section, orientation, role); } switch (section) { case 0: return tr("Name"); case 1: return tr("Type"); case 2: return tr("Samples"); case 3: return tr("Properties"); default: break; } return QVariant(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/application.cpp000644 001750 001750 00000004423 11544160207 020463 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "application.h" #include "builtinprimitives.h" #include "builtindatasources.h" #include "builtinobjects.h" #include "builtingraphics.h" #include "builtinrelations.h" #include "datagui.h" #include "datacollection.h" #include "dialoglaunchergui.h" #include "datasource.h" #include "dialogdefaults.h" #include namespace Kst { Application::Application(int &argc, char **argv) : QApplication(argc, argv) { QCoreApplication::setApplicationName("Kst"); setWindowIcon(QPixmap(":kst.png")); _dialogDefaults = new QSettings("kst", "dialog"); Builtins::initPrimitives(); //libkst Builtins::initDataSources(); //libkst Builtins::initObjects(); //libkstmath Builtins::initRelations(); //libkstmath Builtins::initGraphics(); //libkstapp _mainWindow = new MainWindow; //Replace the data singleton with one that actually works Data::replaceSelf(new DataGui); //Replace the dialoglauncher singleton with one that actually works DialogLauncher::replaceSelf(new DialogLauncherGui); connect(this, SIGNAL(aboutToQuit()), _mainWindow, SLOT(aboutToQuit())); //_mainWindow->show(); //_mainWindow->hide(); } Application::~Application() { // lets not clean up before we leave.... // if we do, we'll end up crashing on exit // unless we fix some stuff related to destruction delete _mainWindow; delete _dialogDefaults; } MainWindow *Application::mainWindow() const { return _mainWindow; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/stringtab.ui000644 001750 001750 00000012324 11544160207 020007 0ustar00synthsynth000000 000000 StringTab 0 0 698 269 Read from data &source true 0 0 &File name: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false F&ield: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _field false 0 Qt::Horizontal QSizePolicy::Expanding 21 0 false &Connect false Co&nfigure... &Generate true false 0 6 0 0 0 &Value: false _stringValue Kst::DataSourceSelector QWidget
    datasourceselector.h
    Kst::ComboBox QComboBox
    combobox.h
    kst-2.0.3/src/libkstapp/selectionrect.h000644 001750 001750 00000002337 11544160207 020472 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SELECTIONRECT_H #define SELECTIONRECT_H #include #include class SelectionRect { public: SelectionRect(); ~SelectionRect(); bool isValid() const; void setFrom(const QPointF&); void setTo(const QPointF&); void reset(); QRectF rect() const; private: QPointF _from, _to; bool _validFrom, _validTo; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/editmultiplewidget.ui000644 001750 001750 00000007063 11544160207 021723 0ustar00synthsynth000000 000000 EditMultipleWidget 0 0 208 316 0 0 EditMultipleWidget 0 Select Objects to Edit 0 0 Filter: false _filterEdit QAbstractItemView::ExtendedSelection Clear Select &All _filterEdit _selectAllBut clicked() EditMultipleWidget selectAllObjects() 20 20 20 20 _selectNoneBut clicked() _objectList clearSelection() 20 20 136 142 _filterEdit textChanged(QString) EditMultipleWidget applyFilter(QString) 20 20 20 20 kst-2.0.3/src/libkstapp/equationtab.ui000644 001750 001750 00000015121 11544160207 020324 0ustar00synthsynth000000 000000 EquationTab 0 0 535 350 Equation 0 0 &Operators: false Operators 0 0 Select an operator from this list to insert it into the equation. All valid operators are listed here. 0 0 &Scalars: false 0 0 &Vectors: false 0 0 Eq&uation: false _equation Enter the equation to be evaluated here. Use 'x' as the independent variable. Vectors an operators are selected from the above lists. &X vector: false true 0 0 0 0 Inte&rpolate to highest resolution vector true Kst::CurvePlacement QWidget
    curveplacement.h
    Kst::VectorSelector QWidget
    vectorselector.h
    Kst::CurveAppearance QWidget
    curveappearance.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    Operators _vectors _scalars _equation _xVectors _doInterpolation _curveAppearance _curvePlacement Operators activated(QString) _equation setFocus() 20 20 20 20
    kst-2.0.3/src/libkstapp/filltab.cpp000644 001750 001750 00000010751 11544160207 017576 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "filltab.h" #include namespace Kst { FillTab::FillTab(QWidget *parent) : DialogTab(parent), _multiEdit(false) { setupUi(this); setTabTitle(tr("Fill")); _style->addItem("NoBrush", Qt::NoBrush); _style->addItem("SolidPattern", Qt::SolidPattern); _style->addItem("Dense1Pattern", Qt::Dense1Pattern); _style->addItem("Dense2Pattern", Qt::Dense2Pattern); _style->addItem("Dense3Pattern", Qt::Dense3Pattern); _style->addItem("Dense4Pattern", Qt::Dense4Pattern); _style->addItem("Dense5Pattern", Qt::Dense5Pattern); _style->addItem("Dense6Pattern", Qt::Dense6Pattern); _style->addItem("Dense7Pattern", Qt::Dense7Pattern); _style->addItem("HorPattern", Qt::HorPattern); _style->addItem("VerPattern", Qt::VerPattern); _style->addItem("CrossPattern", Qt::CrossPattern); _style->addItem("BDiagPattern", Qt::BDiagPattern); _style->addItem("FDiagPattern", Qt::FDiagPattern); _style->addItem("DiagCrossPattern", Qt::DiagCrossPattern); connect(_color, SIGNAL(changed(const QColor &)), this, SIGNAL(modified())); connect(_style, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_gradientEditor, SIGNAL(changed(const QGradient &)), this, SIGNAL(modified())); connect(_gradientReset, SIGNAL(pressed()), this, SIGNAL(modified())); connect(_useGradient, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_gradientReset, SIGNAL(pressed()), _gradientEditor, SLOT(resetGradient())); connect(_useGradient, SIGNAL(stateChanged(int)), this, SLOT(updateButtons())); updateButtons(); } FillTab::~FillTab() { } void FillTab::updateButtons() { if (!_multiEdit) { _color->setEnabled(!_useGradient->isChecked()); _style->setEnabled(!_useGradient->isChecked()); _gradientReset->setEnabled(_useGradient->isChecked()); _gradientEditor->setEnabled(_useGradient->isChecked()); } } QColor FillTab::color() const { return _color->color(); } void FillTab::setColor(const QColor &color) { if (color.isValid()) { _color->setColor(color); } else { _color->setColor(Qt::white); } } bool FillTab::colorDirty() const { return _color->colorDirty(); } Qt::BrushStyle FillTab::style() const { return Qt::BrushStyle(_style->itemData(_style->currentIndex()).toInt()); } bool FillTab::styleDirty() const { return _style->currentIndex() != -1; } void FillTab::setStyle(Qt::BrushStyle style) { if (style == Qt::LinearGradientPattern) { _style->setCurrentIndex(Qt::SolidPattern); } else { _style->setCurrentIndex(_style->findData(QVariant(style))); } } QGradient FillTab::gradient() const { if (_useGradient->isChecked()) { return _gradientEditor->gradient(); } else { return QGradient(); } } bool FillTab::gradientDirty() const { return _gradientEditor->dirty(); } void FillTab::setGradient(const QGradient &gradient) { _useGradient->setChecked(!gradient.stops().empty()); _gradientEditor->setGradient(gradient); updateButtons(); } bool FillTab::useGradient() const { return _useGradient->isChecked(); } bool FillTab::useGradientDirty() const { return _useGradient->checkState() != Qt::PartiallyChecked; } void FillTab::setUseGradient(const bool useGradient) { _useGradient->setChecked(useGradient); updateButtons(); } void FillTab::clearTabValues() { _useGradient->setCheckState(Qt::PartiallyChecked); _style->setCurrentIndex(-1); _color->clearSelection(); _color->setEnabled(true); _style->setEnabled(true); _gradientReset->setEnabled(true); _gradientEditor->setEnabled(true); } void FillTab::enableSingleEditOptions(bool enabled) { _multiEdit = !enabled; if (enabled) { _useGradient->setTristate(false); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/differentiatecurvesdialog.cpp000644 001750 001750 00000015733 11544160207 023407 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "differentiatecurvesdialog.h" #include "linestyle.h" #include "curve.h" #include "colorsequence.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" #include "application.h" #include "updatemanager.h" namespace Kst { DifferentiateCurvesDialog::DifferentiateCurvesDialog(QWidget *parent) : QDialog(parent) { setupUi(this); if (MainWindow *mw = qobject_cast(parent)) { _store = mw->document()->objectStore(); } else { // FIXME: we need the object store qFatal("ERROR: can't construct a DifferentiateCurvesDialog without the object store"); } resetLists(); connect(_buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(OKClicked())); connect(_buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); connect(_add, SIGNAL(clicked()), this, SLOT(addButtonClicked())); connect(_remove, SIGNAL(clicked()), this, SLOT(removeButtonClicked())); connect(_up, SIGNAL(clicked()), this, SLOT(upButtonClicked())); connect(_down, SIGNAL(clicked()), this, SLOT(downButtonClicked())); connect(_availableListBox, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_selectedListBox, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); // Use the standard icons _up->setIcon(QPixmap(":kst_uparrow.png")); _down->setIcon(QPixmap(":kst_downarrow.png")); _add->setIcon(QPixmap(":kst_rightarrow.png")); _remove->setIcon(QPixmap(":kst_leftarrow.png")); _up->setToolTip(i18n("Move the selected property up the priority list")); _down->setToolTip(i18n("Move the selected property down the priority list")); _add->setToolTip(i18n("Add the selected property to the list of properties to cycle through")); _remove->setToolTip(i18n("Remove the selected property from the list of properties to cycle through")); _maxLineWidth->setMaximum(LINEWIDTH_MAX); } DifferentiateCurvesDialog::~DifferentiateCurvesDialog() { } void DifferentiateCurvesDialog::show() { updateButtons(); QDialog::show(); } void DifferentiateCurvesDialog::resetLists() { _availableListBox->clear(); _selectedListBox->clear(); _availableListBox->addItem(tr("Line Color")); _availableListBox->addItem(tr("Point Style")); _availableListBox->addItem(tr("Line Style")); _availableListBox->addItem(tr("Line Width")); _maxLineWidth->setValue(1); _pointDensity->setCurrentIndex(0); } void DifferentiateCurvesDialog::updateButtons() { QList selectedItems = _selectedListBox->selectedItems(); QListWidgetItem *selectedItem = 0; if (selectedItems.count() > 0) selectedItem = selectedItems.first(); _remove->setEnabled(selectedItems.count() > 0); _up->setEnabled(_selectedListBox->row(selectedItem) > 0); _down->setEnabled(_selectedListBox->row(selectedItem) >= 0 && _selectedListBox->row(selectedItem) < (int)_selectedListBox->count() - 1); _add->setEnabled(_availableListBox->selectedItems().count() > 0); _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(_selectedListBox->selectedItems().count() > 0); } void DifferentiateCurvesDialog::removeButtonClicked() { for (int i = 0; i < _selectedListBox->count(); i++) { if (_selectedListBox->item(i) && _selectedListBox->item(i)->isSelected()) { _availableListBox->addItem(_selectedListBox->takeItem(i)); _availableListBox->clearSelection(); _availableListBox->item(_availableListBox->count() - 1)->setSelected(true); } } updateButtons(); } void DifferentiateCurvesDialog::addButtonClicked() { for (int i = 0; i < _availableListBox->count(); i++) { if (_availableListBox->item(i) && _availableListBox->item(i)->isSelected()) { _selectedListBox->addItem(_availableListBox->takeItem(i)); _selectedListBox->clearSelection(); _selectedListBox->item(_selectedListBox->count() - 1)->setSelected(true); } } updateButtons(); } void DifferentiateCurvesDialog::upButtonClicked() { int i = _selectedListBox->currentRow(); if (i != -1) { QListWidgetItem *item = _selectedListBox->takeItem(i); _selectedListBox->insertItem(i-1, item); _selectedListBox->clearSelection(); item->setSelected(true); updateButtons(); } } void DifferentiateCurvesDialog::downButtonClicked() { // move item down int i = _selectedListBox->currentRow(); if (i != -1) { QListWidgetItem *item = _selectedListBox->takeItem(i); _selectedListBox->insertItem(i+1, item); _selectedListBox->clearSelection(); item->setSelected(true); updateButtons(); } } void DifferentiateCurvesDialog::OKClicked() { if (_buttonBox->button(QDialogButtonBox::Apply)->isEnabled()) { apply(); } accept(); } void DifferentiateCurvesDialog::apply() { bool lineColorOrder = !_selectedListBox->findItems(tr("Line Color"), Qt::MatchExactly).empty(); bool pointStyleOrder = !_selectedListBox->findItems(tr("Point Style"), Qt::MatchExactly).empty(); bool lineStyleOrder = !_selectedListBox->findItems(tr("Line Style"), Qt::MatchExactly).empty(); bool lineWidthOrder = !_selectedListBox->findItems(tr("Line Width"), Qt::MatchExactly).empty(); int maxLineWidth = _maxLineWidth->value(); int pointDensity = _pointDensity->currentIndex(); int sequenceNum = 0; CurveList curveList = _store->getObjects(); for (CurveList::iterator curve_iter = curveList.begin(); curve_iter != curveList.end(); ++curve_iter) { CurvePtr curve = kst_cast(*curve_iter); curve->writeLock(); if (lineColorOrder) { curve->setColor(ColorSequence::self().entry(sequenceNum)); } if (pointStyleOrder) { curve->setPointType(sequenceNum % KSTPOINT_MAXTYPE); curve->setHasPoints(true); curve->setPointDensity(pointDensity); } if (lineStyleOrder) { curve->setLineStyle(sequenceNum % LINESTYLE_MAXTYPE); } if (lineWidthOrder) { curve->setLineWidth((sequenceNum + 1) % maxLineWidth); } curve->registerChange(); curve->unlock(); ++sequenceNum; } resetLists(); UpdateManager::self()->doUpdates(true); kstApp->mainWindow()->document()->setChanged(true); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/basicplugintab.ui000644 001750 001750 00000001456 11544160207 021005 0ustar00synthsynth000000 000000 BasicPluginTab Qt::NonModal 0 0 182 52 9 -1 Inputs and Outputs kst-2.0.3/src/libkstapp/scalarmodel.h000644 001750 001750 00000002334 11544160207 020112 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SCALARMODEL_H #define SCALARMODEL_H #include "primitivemodel.h" namespace Kst { class ScalarModel : public PrimitiveModel { enum ColumnID { Name, Value }; public: ScalarModel(ObjectStore *store) : PrimitiveModel(store) { createTree(); } void addDataSourcesMetas(DataSourcePtr dataSource, PrimitiveTreeItem* parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/primitivemodel.h000644 001750 001750 00000012723 11544160207 020660 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2011 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PRIMITIVE_MODEL_H #define PRIMITIVE_MODEL_H #include #include "dataobject.h" #include "datasource.h" #include "object.h" #include "objectstore.h" #include "datavector.h" #include "generatedvector.h" #include "datamatrix.h" #include "generatedmatrix.h" #include "datasource.h" namespace Kst { class ObjectStore; class PrimitiveTreeItem { public: explicit PrimitiveTreeItem(const QList &data, PrimitiveTreeItem *parent = 0); ~PrimitiveTreeItem(); void addChild(PrimitiveTreeItem *child); PrimitiveTreeItem *child(int row); int childCount() const; int columnCount() const; QVariant data(int column) const; int row() const; PrimitiveTreeItem *parent(); private: QList childItems; QList itemData; PrimitiveTreeItem *parentItem; }; class PrimitiveModel : public QAbstractItemModel { enum ColumnID { Name, Value }; public: PrimitiveModel(ObjectStore *store); ~PrimitiveModel(); int columnCount(const QModelIndex& parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; QModelIndex index(int row, int col, const QModelIndex& parent = QModelIndex()) const; QModelIndex parent(const QModelIndex& index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; template void createTree(); template void addMeta(T* m, PrimitiveTreeItem* parent = 0); template void addOrphanMeta(T* m, PrimitiveTreeItem* parent = 0); template void addMetas(const PrimitiveMap& metarMap, PrimitiveTreeItem* parent); template void addPrimitivesMetas(const PrimitivePtr& prim, PrimitiveTreeItem* parent = 0); template void addDataObjectsMetas(DataObjectPtr dataObject, PrimitiveTreeItem* parent = 0); virtual void addDataSourcesMetas(DataSourcePtr dataSource, PrimitiveTreeItem* parent = 0) = 0; protected: PrimitiveTreeItem* addPrimitiveTreeItem(const QList& data, PrimitiveTreeItem* parent); private: ObjectStore *_store; PrimitiveTreeItem *_rootItem; }; template void PrimitiveModel::createTree() { QList objects = _store->objectList(); foreach(const ObjectPtr& obj, objects) { if ( kst_cast(obj) || kst_cast(obj) || kst_cast(obj) || kst_cast(obj) || kst_cast(obj) || kst_cast(obj)) { addPrimitivesMetas(kst_cast(obj)); } else if (kst_cast(obj)) { if (kst_cast(obj) && kst_cast(obj)->orphan()) { addOrphanMeta(kst_cast(obj)); } } else if (kst_cast(obj)) { addDataObjectsMetas(kst_cast(obj)); } } DataSourceList datasoucres = _store->dataSourceList(); foreach(const DataSourcePtr& ds, datasoucres) { addDataSourcesMetas(ds); } } template void PrimitiveModel::addMeta(T* m, PrimitiveTreeItem* parent) { addPrimitiveTreeItem(QList() << QString("%1 (%2)").arg(m->slaveName()).arg(m->shortName()) << m->value(), parent); } template void PrimitiveModel::addOrphanMeta(T* m, PrimitiveTreeItem* parent) { addPrimitiveTreeItem(QList() << m->Name() << m->value(), parent); } template void PrimitiveModel::addMetas(const PrimitiveMap& metarMap, PrimitiveTreeItem* parent) { foreach(const PrimitivePtr& m, metarMap) { if(kst_cast(m)) { addMeta(kst_cast(m), parent); } } } template void PrimitiveModel::addPrimitivesMetas(const PrimitivePtr& prim, PrimitiveTreeItem* parent) { bool metas_available = false; PrimitiveMap metas = prim->metas(); foreach(const PrimitivePtr& m, metas) { if (kst_cast(m)) { metas_available = true; break; } } if (metas_available) { PrimitiveTreeItem* item = addPrimitiveTreeItem(QList() << prim->Name(), parent); addMetas(prim->metas(), item); } } template void PrimitiveModel::addDataObjectsMetas(DataObjectPtr dataObject, PrimitiveTreeItem* parent) { PrimitiveTreeItem* item = addPrimitiveTreeItem(QList() << dataObject->Name(), parent); ObjectList primitives = dataObject->outputPrimitives(false); foreach(PrimitivePtr prim, primitives) { if ( kst_cast(prim) || kst_cast(prim) || kst_cast(prim)) { addPrimitivesMetas(prim.data(), item); } if (kst_cast(prim)) { addMeta(kst_cast(prim), item); } } } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labelitemdialog.h000644 001750 001750 00000002544 11544160207 020745 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELITEMDIALOG_H #define LABELITEMDIALOG_H #include "viewitemdialog.h" #include "kst_export.h" namespace Kst { class LabelPropertiesTab; class LabelItem; class LabelItemDialog : public ViewItemDialog { Q_OBJECT public: explicit LabelItemDialog(LabelItem *item, QWidget *parent = 0); virtual ~LabelItemDialog(); private Q_SLOTS: void propertiesChanged(); private: void setupProperties(); LabelPropertiesTab *_propertiesTab; LabelItem *_labelItem; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/aboutdialog.h000644 001750 001750 00000002276 11544160207 020123 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2009 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ABOUTDIALOG_H #define ABOUTDIALOG_H #include #include "ui_aboutdialog.h" #include "kst_export.h" namespace Kst { class AboutDialog : public QDialog, Ui::AboutDialog { Q_OBJECT public: AboutDialog(QWidget *parent); virtual ~AboutDialog(); private Q_SLOTS: void launchURL(const QUrl &link); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/changefiledialog.cpp000644 001750 001750 00000043144 11544160207 021430 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "changefiledialog.h" #include "datacollection.h" #include "datasourcedialog.h" #include "datavector.h" #include "datamatrix.h" #include "datascalar.h" #include "datastring.h" #include "vscalar.h" #include "primitive.h" #include "plotitem.h" #include "objectstore.h" #include "document.h" #include "mainwindow.h" #include "application.h" #include "updatemanager.h" #include "datasourcepluginmanager.h" #include #include #include namespace Kst { ChangeFileDialog::ChangeFileDialog(QWidget *parent) : QDialog(parent), _dataSource(0), _requestID(0) { setupUi(this); MainWindow::setWidgetFlags(this); if (MainWindow *mw = qobject_cast(parent)) { _store = mw->document()->objectStore(); } else { // FIXME: we need the object store qFatal("ERROR: can't construct a ChangeFileDialog without the object store"); } connect(_add, SIGNAL(clicked()), this, SLOT(addButtonClicked())); connect(_remove, SIGNAL(clicked()), this, SLOT(removeButtonClicked())); connect(_removeAll, SIGNAL(clicked()), this, SLOT(removeAll())); connect(_addAll, SIGNAL(clicked()), this, SLOT(addAll())); connect(_changeFilePrimitiveList, SIGNAL(itemDoubleClicked ( QListWidgetItem * )), this, SLOT(availableDoubleClicked(QListWidgetItem *))); connect(_selectedFilePrimitiveList, SIGNAL(itemDoubleClicked ( QListWidgetItem * )), this, SLOT(selectedDoubleClicked(QListWidgetItem *))); connect(_allFromFile, SIGNAL(clicked()), this, SLOT(selectAllFromFile())); connect(_changeFilePrimitiveList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_selectedFilePrimitiveList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_duplicateSelected, SIGNAL(toggled(bool)), _duplicateDependents, SLOT(setEnabled(bool))); connect(_dataFile, SIGNAL(changed(const QString &)), this, SLOT(fileNameChanged(const QString &))); connect(_buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(OKClicked())); connect(_buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); connect(_configure, SIGNAL(clicked()), this, SLOT(showConfigWidget())); _dataFile->setFile(QDir::currentPath()); updateButtons(); } ChangeFileDialog::~ChangeFileDialog() { } void ChangeFileDialog::show() { updatePrimitiveList(); QDialog::show(); } void ChangeFileDialog::showConfigWidget() { QPointer dialog = new DataSourceDialog(DataDialog::New, _dataSource, this); if ( dialog->exec() == QDialog::Accepted ) { fileNameChanged(_dataSource->fileName()); } delete dialog; } void ChangeFileDialog::removeButtonClicked() { foreach (QListWidgetItem* item, _selectedFilePrimitiveList->selectedItems()) { _changeFilePrimitiveList->addItem(_selectedFilePrimitiveList->takeItem(_selectedFilePrimitiveList->row(item))); } _changeFilePrimitiveList->clearSelection(); updateButtons(); } void ChangeFileDialog::selectedDoubleClicked(QListWidgetItem * item) { if (item) { _changeFilePrimitiveList->addItem(_selectedFilePrimitiveList->takeItem(_selectedFilePrimitiveList->row(item))); _changeFilePrimitiveList->clearSelection(); updateButtons(); } } void ChangeFileDialog::addButtonClicked() { foreach (QListWidgetItem* item, _changeFilePrimitiveList->selectedItems()) { _selectedFilePrimitiveList->addItem(_changeFilePrimitiveList->takeItem(_changeFilePrimitiveList->row(item))); } _selectedFilePrimitiveList->clearSelection(); updateButtons(); } void ChangeFileDialog::availableDoubleClicked(QListWidgetItem * item) { if (item) { _selectedFilePrimitiveList->addItem(_changeFilePrimitiveList->takeItem(_changeFilePrimitiveList->row(item))); _selectedFilePrimitiveList->clearSelection(); updateButtons(); } } void ChangeFileDialog::sourceValid(QString filename, int requestID) { if (_requestID != requestID) { return; } _dataSource = DataSourcePluginManager::findOrLoadSource(_store, filename); _fileType->setText(_dataSource->fileType()); updateButtons(); _configure->setEnabled(_dataSource->hasConfigWidget()); } void ChangeFileDialog::fileNameChanged(const QString &file) { _dataSource = 0; updateButtons(); _configure->setEnabled(false); _requestID += 1; ValidateDataSourceThread *validateDSThread = new ValidateDataSourceThread(file, _requestID); connect(validateDSThread, SIGNAL(dataSourceValid(QString, int)), this, SLOT(sourceValid(QString, int))); QThreadPool::globalInstance()->start(validateDSThread); } void ChangeFileDialog::updatePrimitiveList() { PrimitiveList allPrimitives = _store->getObjects(); QStringList fileNameList; ObjectList primitives; foreach (const PrimitivePtr& P, allPrimitives) { DataPrimitive* dp = qobject_cast(P); if (dp) { primitives.append(P); fileNameList.append(dp->filename()); } } // make sure all items in _changeFilePrimitiveList exist in the store; remove if they don't. for (int i_item = 0; i_item < _changeFilePrimitiveList->count(); i_item++) { bool exists=false; for (int i_primitive = 0; i_primitiveName() == _changeFilePrimitiveList->item(i_item)->text()) { exists = true; break; } } if (!exists) { QListWidgetItem *item = _changeFilePrimitiveList->takeItem(i_item); delete item; } } // make sure all items in _selectedFilePrimitiveList exist in the store; remove if they don't. for (int i_item = 0; i_item < _selectedFilePrimitiveList->count(); i_item++) { bool exists=false; for (int i_primitive = 0; i_primitiveName() == _selectedFilePrimitiveList->item(i_item)->text()) { exists = true; break; } } if (!exists) { QListWidgetItem *item = _selectedFilePrimitiveList->takeItem(i_item); delete item; } } // insert into _changeFilePrimitiveList all items in store not in one of the lists. for (int i_primitive = 0; i_primitivecount(); i_item++) { if (primitives.at(i_primitive)->Name() == _changeFilePrimitiveList->item(i_item)->text()) { _changeFilePrimitiveList->item(i_item)->setToolTip(primitives.at(i_primitive)->descriptionTip()); listed = true; break; } } for (int i_item = 0; i_item<_selectedFilePrimitiveList->count(); i_item++) { if (primitives.at(i_primitive)->Name() == _selectedFilePrimitiveList->item(i_item)->text()) { _selectedFilePrimitiveList->item(i_item)->setToolTip(primitives.at(i_primitive)->descriptionTip()); listed = true; break; } } if (!listed) { QListWidgetItem *wi = new QListWidgetItem(primitives.at(i_primitive)->Name()); _changeFilePrimitiveList->addItem(wi); wi->setToolTip(primitives.at(i_primitive)->descriptionTip()); } } // fill _files QString currentFile = _files->currentText(); _files->clear(); for (QStringList::Iterator it = fileNameList.begin(); it != fileNameList.end(); ++it) { if (_files->findText(*it) == -1) { _files->addItem(*it); } } _allFromFile->setEnabled(_files->count() > 0); _files->setEnabled(_files->count() > 0); updateButtons(); } void ChangeFileDialog::updateButtons() { bool valid = _selectedFilePrimitiveList->count() > 0 && _dataSource; _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid); _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(valid); _add->setEnabled(_changeFilePrimitiveList->selectedItems().count() > 0); _addAll->setEnabled(_changeFilePrimitiveList->count() > 0); _remove->setEnabled(_selectedFilePrimitiveList->selectedItems().count() > 0); _removeAll->setEnabled(_selectedFilePrimitiveList->count() > 0); } void ChangeFileDialog::addAll() { _changeFilePrimitiveList->selectAll(); addButtonClicked(); } void ChangeFileDialog::removeAll() { _selectedFilePrimitiveList->selectAll(); removeButtonClicked(); } void ChangeFileDialog::selectAllFromFile() { if (_files->count() <= 0) { return; } _changeFilePrimitiveList->clearSelection(); for (int i = 0; i < _changeFilePrimitiveList->count(); i++) { if (DataVectorPtr vector = kst_cast(_store->retrieveObject(_changeFilePrimitiveList->item(i)->text()))) { _changeFilePrimitiveList->item(i)->setSelected(vector->filename() == _files->currentText()); } else if (DataMatrixPtr matrix = kst_cast(_store->retrieveObject(_changeFilePrimitiveList->item(i)->text()))) { _changeFilePrimitiveList->item(i)->setSelected(matrix->filename() == _files->currentText()); } } addButtonClicked(); } void ChangeFileDialog::OKClicked() { apply(); accept(); } void ChangeFileDialog::apply() { Q_ASSERT(_store); if (!_dataSource->isValid() || _dataSource->isEmpty()) { QMessageBox::critical(this, tr("Kst"), tr("The file could not be loaded or contains no data."), QMessageBox::Ok); return; } // we need a list which preservs the order things are added, and a map to associate the duplicated // primitive with its duplicate. QMap duplicatedPrimitiveMap; // associate duplicated with duplicates. PrimitiveList duplicatedPrimitiveList; // list of duplicated primitives in order they were found DataSourceList oldSources; QString invalidSources; int invalid = 0; _selectedFilePrimitiveList->selectAll(); QList selectedItems = _selectedFilePrimitiveList->selectedItems(); int n_selectedItems = selectedItems.size(); for (int i = 0; i < n_selectedItems; ++i) { PrimitivePtr prim = kst_cast(_store->retrieveObject(selectedItems[i]->text())); if (prim) { DataPrimitive* dp = qobject_cast(prim); if (dp) { prim->readLock(); _dataSource->readLock(); bool valid = dp->checkValidity(_dataSource); _dataSource->unlock(); prim->unlock(); if (!valid) { if (invalid > 0) { invalidSources += ", "; } invalidSources += dp->field(); ++invalid; } else if (_duplicateSelected->isChecked()) { prim->readLock(); PrimitivePtr newPrim = dp->makeDuplicate(); DataPrimitive* newdp = qobject_cast(newPrim); prim->unlock(); newPrim->writeLock(); newdp->changeFile(_dataSource); newPrim->unlock(); duplicatedPrimitiveMap[prim] = newPrim; duplicatedPrimitiveList.append(prim); PrimitiveList output_prims = prim->outputPrimitives(); PrimitiveList dup_output_prims = newPrim->outputPrimitives(); // add output primitives to list of primitives that have been duplicated. int n = qMin(output_prims.count(), dup_output_prims.count()); for (int i_output=0; i_outputdescriptiveName() == dup_output_prims.at(i_output)->descriptiveName()) { duplicatedPrimitiveList.append(output_prims.at(i_output)); duplicatedPrimitiveMap[output_prims.at(i_output)] = dup_output_prims.at(i_output); } } } else { prim->readLock(); if (!oldSources.contains(dp->dataSource())) { oldSources << dp->dataSource(); } prim->unlock(); prim->writeLock(); dp->changeFile(_dataSource); prim->unlock(); } } } prim = 0; } // Duplicate data objects: // list of all data objects before we start duplication DataObjectList dataObjects = _store->getObjects(); // map of data objects which have been duplicated. QMap duplicatedDataObjects; // Lookup list to record if the data object has already been duplicated // (We could have just checked if it was in the map, but that is slower) QVector dataObjectDuplicated(dataObjects.count()); int n_dataObjects = dataObjects.count(); for (int i_OB = 0; i_OB < n_dataObjects; i_OB++) { dataObjectDuplicated[i_OB] = false; } // go through whole list until nothing is duplicated bool new_duplicate_found; do { new_duplicate_found = false; for (int i_DP =0; i_DPinputPrimitives(); if (input_primitives.contains(duplicatedPrimitiveList.at(i_DP))) { DataObjectPtr duplicate_object; if (!dataObjectDuplicated[i_OB]) { duplicate_object = dataObjects.at(i_OB)->makeDuplicate(); // put the outputs of the new data object into the list of duplicated primitives. PrimitiveList dup_output_prims = duplicate_object->outputPrimitives(); PrimitiveList output_prims = dataObjects.at(i_OB)->outputPrimitives(); int n = output_prims.count(); for (int i_output=0; i_outputreplaceInput(old_input_primitive, new_input_primitive); } } } } while (new_duplicate_found); // Duplicate Relations RelationList relations = _store->getObjects(); // map of data objects which have been duplicated. QMap duplicatedRelations; // Lookup list to record if the relation has already been duplicated // (We could have just checked if it was in the map, but that is slower) int n_relations = relations.count(); QVector relationDuplicated(n_relations); for (int i_R = 0; i_R < n_relations; i_R++) { relationDuplicated[i_R] = false; } for (int i_DP =0; i_DPinputPrimitives(); if (input_primitives.contains(duplicatedPrimitiveList.at(i_DP))) { RelationPtr duplicate_relation; if (!relationDuplicated[i_R]) { duplicate_relation = relations.at(i_R)->makeDuplicate(); duplicatedRelations[relations.at(i_R)] = duplicate_relation; relationDuplicated[i_R] = true; } else { duplicate_relation = duplicatedRelations[relations.at(i_R)]; } // replace the input primitive with its copy. PrimitivePtr old_input_primitive = duplicatedPrimitiveList.at(i_DP); PrimitivePtr new_input_primitive = duplicatedPrimitiveMap[old_input_primitive]; duplicate_relation->replaceInput(old_input_primitive, new_input_primitive); } } } // Plot the items. foreach (PlotItemInterface *plot, Data::self()->plotList()) { PlotItem* plotItem = static_cast(plot); foreach (PlotRenderItem* renderItem, plotItem->renderItems()) { for (QMap::ConstIterator iter = duplicatedRelations.begin(); iter != duplicatedRelations.end(); ++iter) { if (renderItem->relationList().contains(kst_cast(iter.key())) && !renderItem->relationList().contains(kst_cast(iter.value()))) { renderItem->addRelation(kst_cast(iter.value())); } } } } // clean up unused data sources for (DataSourceList::Iterator it = oldSources.begin(); it != oldSources.end(); ++it) { if ((*it)->getUsage() == 1) { _store->removeObject(*it); } } if (!invalidSources.isEmpty()) { if (invalid == 1) { QMessageBox::warning(this, tr("Kst"), tr("The following field is not defined for the requested file:\n%1").arg(invalidSources), QMessageBox::Ok); } else { QMessageBox::warning(this, tr("Kst"), tr("The following fields are not defined for the requested file:\n%1").arg(invalidSources), QMessageBox::Ok); } } else { updatePrimitiveList(); } UpdateManager::self()->doUpdates(true); kstApp->mainWindow()->document()->setChanged(true); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/applicationsettingsdialog.h000644 001750 001750 00000003613 11544160207 023071 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef APPLICATIONSETTINGSDIALOG_H #define APPLICATIONSETTINGSDIALOG_H #include "dialog.h" #include #include "kst_export.h" namespace Kst { class GeneralTab; class GridTab; class FillTab; class ChildViewOptionsTab; class DefaultLabelPropertiesTab; class LayoutTab; class ApplicationSettingsDialog : public Dialog { Q_OBJECT public: ApplicationSettingsDialog(QWidget *parent = 0); virtual ~ApplicationSettingsDialog(); private Q_SLOTS: void generalChanged(); void gridChanged(); void fillChanged(); void childViewOptionsChanged(); void defaultLabelPropertiesChanged(); void layoutChanged(); private: void setupGeneral(); void setupGrid(); void setupFill(); void setupChildViewOptions(); void setupDefaultLabelProperties(); void setupLayout(); private: GeneralTab *_generalTab; GridTab *_gridTab; FillTab *_fillTab; ChildViewOptionsTab *_childViewOptionsTab; DefaultLabelPropertiesTab *_defaultLabelPropertiesTab; LayoutTab *_layoutTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/view.h000644 001750 001750 00000012354 11544160207 016601 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEW_H #define VIEW_H #include #include "kst_export.h" #include "curveplacement.h" class QUndoStack; class QXmlStreamWriter; namespace Kst { class ViewItem; class LayoutBoxItem; class PlotItem; class View : public QGraphicsView { Q_OBJECT public: enum ViewMode { Data, Layout }; enum MouseMode { Default, Move, Create, Resize, Scale, Rotate }; enum ZoomOnlyMode { ZoomOnlyDisabled, ZoomOnlyX, ZoomOnlyY }; enum CreationEvent { MousePress = 0x0, MouseRelease =0x1, MouseMove = 0x2, EscapeEvent = 0x3 }; Q_DECLARE_FLAGS(CreationEvents, CreationEvent) View(); View(QWidget* parent); virtual ~View(); void init(); virtual void save(QXmlStreamWriter &xml); bool useOpenGL() const; void setUseOpenGL(bool useOpenGL); QUndoStack *undoStack() const; ViewItem *selectedViewItem() const; ViewMode viewMode() const; void setViewMode(ViewMode mode); MouseMode mouseMode() const; void setMouseMode(MouseMode mode); QPolygonF creationPolygon(CreationEvents events) const; LayoutBoxItem* layoutBoxItem() const { return _layoutBoxItem; } void setLayoutBoxItem(LayoutBoxItem *layoutBoxItem) { _layoutBoxItem = layoutBoxItem; } bool showGrid() const { return _showGrid; } void setShowGrid(bool showGrid); QFont defaultFont(double pointSize) const; QSizeF gridSpacing() const { return _gridSpacing; } void setGridSpacing(const QSizeF &gridSpacing); bool snapToGridHorizontal() const { return _snapToGridHorizontal; } void setSnapToGridHorizontal(bool snapToGridHorizontal) { _snapToGridHorizontal = snapToGridHorizontal; } bool snapToGridVertical() const { return _snapToGridVertical; } void setSnapToGridVertical(bool snapToGridVertical) { _snapToGridVertical = snapToGridVertical; } bool snapToGrid() const { return _snapToGridHorizontal && _snapToGridVertical; } void setSnapToGrid(bool snapToGrid) { _snapToGridHorizontal = snapToGrid; _snapToGridVertical = snapToGrid; } QPointF snapPoint(const QPointF &point); void setPrinting(bool printing) { _printing = printing; } bool isPrinting() { return _printing; } //TODO cleanup/remove void setDataMode(bool dataMode) { _dataMode = dataMode; } bool isDataMode() { return _dataMode; } virtual void contextMenuEvent(); bool plotBordersDirty() const {return _plotBordersDirty;} void setPlotBordersDirty(bool dirty) {_plotBordersDirty = dirty;} void configurePlotFontDefaults(PlotItem *plot); void resetPlotFontSizes(double pointSize = 0); void setFontRescale(double rescale) {_fontRescale = rescale;} double fontRescale() const {return _fontRescale;} void setChildMaximized(bool isMax) { _childMaximized = isMax;} bool childMaximized() const {return _childMaximized;} Q_SIGNALS: void viewModeChanged(View::ViewMode oldMode); void mouseModeChanged(View::MouseMode oldMode); void creationPolygonChanged(View::CreationEvent event); public Q_SLOTS: void createLayout(int columns = 0); void appendToLayout(CurvePlacement::Layout layout, ViewItem* item, int columns = 0); void createCustomLayout(); void viewChanged(); void forceChildResize(QRectF oldRect, QRectF newRect); void processResize(QSize size); void setZoomOnly(ZoomOnlyMode); protected: bool event(QEvent *event); bool eventFilter(QObject *obj, QEvent *event); void resizeEvent(QResizeEvent *event=NULL); void drawBackground(QPainter *painter, const QRectF &rect); void addTitle(QMenu *menu) const; QAction *_editAction; QAction *_autoLayoutAction; QAction *_customLayoutAction; private Q_SLOTS: void updateSettings(); void loadSettings(); void updateFont(); void updateBrush(); virtual void edit(); private: void updateChildGeometry(const QRectF &oldSceneRect); private: QUndoStack *_undoStack; ViewMode _viewMode; MouseMode _mouseMode; LayoutBoxItem *_layoutBoxItem; QPolygonF _creationPolygonPress; QPolygonF _creationPolygonMove; QPolygonF _creationPolygonRelease; QFont _defaultFont; bool _useOpenGL; QSizeF _gridSpacing; bool _showGrid; bool _snapToGridHorizontal; bool _snapToGridVertical; bool _plotBordersDirty; bool _printing; bool _dataMode; double _fontRescale; bool _childMaximized; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/builtingraphics.h000644 001750 001750 00000002003 11544160207 021004 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUILTINGRAPHICS_H #define BUILTINGRAPHICS_H #include "kst_export.h" namespace Kst { namespace Builtins { void initGraphics(); } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/gridtab.h000644 001750 001750 00000002657 11544160207 017250 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GRIDTAB_H #define GRIDTAB_H #include "dialogtab.h" #include "ui_gridtab.h" #include "kst_export.h" namespace Kst { class GridTab : public DialogTab, Ui::GridTab { Q_OBJECT public: GridTab(QWidget *parent = 0); virtual ~GridTab(); bool showGrid() const; void setShowGrid(bool showGrid); bool snapToGrid() const; void setSnapToGrid(bool snapToGrid); qreal gridHorizontalSpacing() const; void setGridHorizontalSpacing(qreal spacing); qreal gridVerticalSpacing() const; void setGridVerticalSpacing(qreal spacing); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/axis.cpp000644 001750 001750 00000001726 11544160207 017127 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 Theodore Kisner * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "axis.h" namespace Kst { Axis::Axis() { reversed = false; isLog = false; logBase = 0.0; } Axis::~Axis() { } AxisStyle::AxisStyle() { } AxisStyle::~AxisStyle() { } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labelrenderer.cpp000644 001750 001750 00000016130 11544160207 020764 0ustar00synthsynth000000 000000 /*************************************************************************** labelrenderer.cpp ------------------ begin : Jun 17 2005 copyright : (C) 2005 by The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labelrenderer.h" #include "enodes.h" #include "datacollection.h" #include "ksttimers.h" #include "labelparser.h" #include "document.h" #include "objectstore.h" #include "application.h" #include "applicationsettings.h" #include const double subscript_scale = 0.60; const double subscript_drop = 0.16; const double superscript_scale = 0.60; const double superscript_raise = 0.44; namespace Label { void renderLabel(RenderContext& rc, Label::Chunk *fi, bool cache) { // FIXME: RTL support int oldSize = rc.size = rc.fontSize(); int oldY = rc.y; int oldX = rc.x; Kst::Document *doc = kstApp->mainWindow()->document(); Q_ASSERT(doc); Kst::ObjectStore *store = doc->objectStore(); Q_ASSERT(store); while (fi) { if (fi->vOffset != Label::Chunk::None) { if (fi->vOffset == Label::Chunk::Up) { rc.size = int(double(rc.size)*superscript_scale); rc.y -= int(superscript_raise * rc.fontHeight()); } else { // Down rc.size = int(double(rc.size)*subscript_scale); rc.y += int(subscript_drop * rc.fontHeight()); } if (rc.sizeminimumFontSize()) { rc.size = Kst::ApplicationSettings::self()->minimumFontSize(); } } QFont f = rc.font(); if (rc.fontSize() != rc.size) { f.setPointSizeF(rc.size); } f.setBold(fi->attributes.bold); f.setItalic(fi->attributes.italic); f.setUnderline(fi->attributes.underline); f.setOverline(fi->attributes.overline); QPen pen = rc.pen; if (fi->attributes.color.isValid()) { pen.setColor(fi->attributes.color); } if (rc.p) { rc.p->setPen(pen); } rc.setFont(f); if (fi->linebreak) { rc.x = oldX; rc.y += rc.fontAscent() + rc.fontDescent() + 1; fi = fi->next; rc.lines++; continue; } if (!rc.substitute && (fi->scalar || fi->vector)) { QString txt = QString('[') + fi->text + ']'; if (rc.p) { rc.p->drawText(rc.x, rc.y, txt); } if (cache) { rc.addToCache(QPointF(rc.x, rc.y), txt, f, pen); } rc.x += rc.fontWidth(txt); } else if (fi->scalar) { // do scalar/string/fit substitution QString txt; if (!fi->text.isEmpty() && fi->text[0] == '=') { // Parse and evaluate as an equation bool ok = false; const QString s = fi->text.mid(1); const double eqResult(Equations::interpret(store, s.toLatin1(), &ok, s.length())); txt = QString::number(eqResult, 'g', rc.precision); } else { Kst::ObjectPtr op = store->retrieveObject(fi->text); Kst::ScalarPtr scp = Kst::kst_cast(op); if (scp) { KstReadLocker l(scp); txt = QString::number(scp->value(), 'g', rc.precision); if (cache) { rc.addObject(scp); } } else { Kst::StringPtr stp = Kst::kst_cast(op); if (stp) { KstReadLocker l(stp); txt = stp->value(); if (cache) { rc.addObject(stp); } } } } if (rc.p) { rc.p->drawText(rc.x, rc.y, txt); } if (cache) { rc.addToCache(QPointF(rc.x, rc.y), txt, f, pen); } rc.x += rc.fontWidth(txt); } else if (fi->vector) { QString txt; Kst::VectorPtr vp = Kst::kst_cast(store->retrieveObject(fi->text)); if (vp) { if (!fi->expression.isEmpty()) { // Parse and evaluate as an equation bool ok = false; // FIXME: make more efficient: cache the parsed equation const double idx = Equations::interpret(store, fi->expression.toLatin1(), &ok, fi->expression.length()); if (ok) { KstReadLocker l(vp); const double vVal(vp->value()[int(idx)]); txt = QString::number(vVal, 'g', rc.precision); if (cache) { rc.addObject(vp); } } else { txt = "NAN"; } } } if (rc.p) { rc.p->drawText(rc.x, rc.y, txt); } if (cache) { rc.addToCache(QPointF(rc.x, rc.y), txt, f, pen); } rc.x += rc.fontWidth(txt); } else if (fi->tab) { const int tabWidth = rc.fontWidth("MMMM"); const int toSkip = tabWidth - (rc.x - rc.xStart) % tabWidth; if (rc.p && (fi->attributes.underline || fi->attributes.overline)) { const int spaceWidth = rc.fontWidth(" "); const int spacesToSkip = tabWidth / spaceWidth + (tabWidth % spaceWidth > 0 ? 1 : 0); QString txt(QString().fill(' ', spacesToSkip)); rc.p->drawText(rc.x, rc.y, txt); if (cache) { rc.addToCache(QPointF(rc.x, rc.y), txt, f, pen); } } rc.x += toSkip; } else { if (rc.p) { #ifdef BENCHMARK QTime t; t.start(); #endif rc.p->drawText(rc.x, rc.y, fi->text); #ifdef BENCHMARK qDebug() << "Renderer did draw, time: " << t.elapsed(); #endif } if (cache) { rc.addToCache(QPointF(rc.x, rc.y), fi->text, f, pen); } rc.x += rc.fontWidth(fi->text); } if (!rc.p) { // No need to compute ascent and descent when really painting rc.ascent = qMax(rc.ascent, -rc.y + rc.fontAscent()); if (-rc.y - rc.fontDescent() < 0) { rc.descent = qMax(rc.descent, rc.fontDescent() + rc.y); } } int xNext = rc.x; if (fi->group) { renderLabel(rc, fi->group); xNext = rc.x; } if (fi->up) { int xPrev = rc.x; renderLabel(rc, fi->up); xNext = qMax(xNext, rc.x); rc.x = xPrev; } if (fi->down) { renderLabel(rc, fi->down); xNext = qMax(xNext, rc.x); } rc.x = xNext; rc.xMax = qMax(rc.xMax, rc.x); fi = fi->next; } rc.size = oldSize; rc.y = oldY; } void paintLabel(RenderContext& rc, QPainter *p) { if (p) { foreach (RenderedText text, rc.cachedText) { p->save(); p->setPen(text.pen); p->setFont(text.font); p->drawText(text.location, text.text); p->restore(); } } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/databutton.h000644 001750 001750 00000002167 11544160207 017775 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATABUTTON_H #define DATABUTTON_H #include namespace Kst { class Document; class DataButton : public QPushButton { Q_OBJECT public: explicit DataButton(const QString & text, QWidget * parent = 0); virtual ~DataButton(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialogpage.ui000644 001750 001750 00000002343 11544160207 020106 0ustar00synthsynth000000 000000 DialogPage 0 0 400 300 Form 0 0 0 0 12 false Qt::AlignCenter -1 kst-2.0.3/src/libkstapp/datawizard.h000644 001750 001750 00000011775 11544160207 017767 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAWIZARD_H #define DATAWIZARD_H #include #include #include "kst_export.h" #include "ui_datawizardpagedatasource.h" #include "ui_datawizardpagevectors.h" #include "ui_datawizardpagefilters.h" #include "ui_datawizardpageplot.h" #include "ui_datawizardpagedatapresentation.h" #include "datasource.h" #include "curveplacement.h" namespace Kst { class Document; class ObjectStore; class PlotItemInterface; class ValidateDataSourceThread; class DataWizardPageDataSource : public QWizardPage, Ui::DataWizardPageDataSource { Q_OBJECT public: DataWizardPageDataSource(ObjectStore *store, QWidget *parent, const QString& filename); virtual ~DataWizardPageDataSource(); bool isComplete() const; QStringList dataSourceFieldList() const; DataSourcePtr dataSource() const; public Q_SLOTS: void sourceChanged(const QString&); void configureSource(); void sourceValid(QString filename, int requestID); void updateTypeActivated(int); Q_SIGNALS: void dataSourceChanged(); private: bool _pageValid; ObjectStore *_store; DataSourcePtr _dataSource; int _requestID; void updateUpdateBox(); }; class DataWizardPageVectors : public QWizardPage, Ui::DataWizardPageVectors { Q_OBJECT public: DataWizardPageVectors(QWidget *parent); virtual ~DataWizardPageVectors(); bool isComplete() const; QListWidget* plotVectors() const; public Q_SLOTS: void add(); void remove(); void up(); void down(); void filterVectors(const QString&); void searchVectors(); void updateVectors(); private: bool vectorsSelected() const; }; class DataWizardPageFilters : public QWizardPage, Ui::DataWizardPageFilters { Q_OBJECT public: DataWizardPageFilters(QWidget *parent); virtual ~DataWizardPageFilters(); }; class DataWizardPagePlot : public QWizardPage, Ui::DataWizardPagePlot { Q_OBJECT public: enum CurvePlotPlacement { OnePlot, MultiplePlots, CyclePlotCount, CycleExisting, ExistingPlot }; enum PlotTabPlacement { CurrentTab, NewTab, SeparateTabs }; DataWizardPagePlot(QWidget *parent); virtual ~DataWizardPagePlot(); CurvePlacement::Layout layout() const; int gridColumns() const; bool drawLines() const; bool drawPoints() const; bool drawLinesAndPoints() const; bool PSDLogX() const; bool PSDLogY() const; bool legendsOn() const; bool legendsAuto() const; bool legendsVertical() const; bool rescaleFonts() const; bool shareAxis() const; CurvePlotPlacement curvePlacement() const; PlotItemInterface *existingPlot() const; PlotTabPlacement plotTabPlacement() const; int plotCount() const; public Q_SLOTS: void updatePlotBox(); void updateButtons(); }; class DataWizardPageDataPresentation : public QWizardPage, Ui::DataWizardPageDataPresentation { Q_OBJECT public: DataWizardPageDataPresentation(ObjectStore *store, QWidget *parent); virtual ~DataWizardPageDataPresentation(); int nextId() const; bool isComplete() const; bool createXAxisFromField() const; QString vectorField() const; bool plotPSD() const; bool plotData() const; bool plotDataPSD() const; VectorPtr selectedVector() const; FFTOptions* getFFTOptions() const; DataRange* dataRange() const; public Q_SLOTS: void applyFilter(bool); void updateVectors(); void optionsUpdated(); Q_SIGNALS: void filterApplied(bool); private: bool _pageValid; bool validOptions(); }; class DataWizard : public QWizard { Q_OBJECT public: enum DataWizardPages {PageDataSource, PageVectors, PageDataPresentation, PageFilters, PagePlot}; DataWizard(QWidget *parent, const QString& fn = QString()); virtual ~DataWizard(); QStringList dataSourceFieldList() const; private: DataWizardPageDataSource *_pageDataSource; DataWizardPageVectors *_pageVectors; DataWizardPageFilters *_pageFilters; DataWizardPagePlot *_pagePlot; DataWizardPageDataPresentation *_pageDataPresentation; Q_SIGNALS: void dataSourceLoaded(const QString&); private Q_SLOTS: void finished(); private: Document *_document; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/exportgraphicsdialog.ui000644 001750 001750 00000026050 11544160207 022235 0ustar00synthsynth000000 000000 ExportGraphicsDialog 0 0 402 278 Export to Graphics File 11 6 0 0 &Save location: false &File format: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _comboBoxFormats 0 0 Save Options 6 0 Do not autosave. Instead, on OK or Apply, save once. Sa&ve once true Save image on timer When checked, the image will be repeatedly saved using the indicated period. This is useful, for example, for live web page images. &Autosave every false Autosave timer s 1 100000 15 Qt::Horizontal QSizePolicy::Expanding 21 21 Qt::Horizontal QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok Size 0 6 6 0 0 0 &Width: false _xSize Width (in Pixels) of the image. 5 10000 20 640 0 0 &Height: false _ySize Height of the image (in pixels). 5 10000 20 480 Qt::Horizontal QSizePolicy::Expanding 120 31 6 0 S&pecify: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false _comboBoxSizeOption Width and Maintain Aspect Ratio Height and Maintain Aspect Ratio Width and Height Size of Square Qt::Horizontal QSizePolicy::Expanding 61 21 Automatic &extension true Kst::ComboBox QComboBox
    combobox.h
    Kst::FileRequester QWidget
    filerequester.h
    _comboBoxFormats _comboBoxSizeOption _xSize _ySize _saveOnce _autosave _period _buttonBox _autosave toggled(bool) _period setEnabled(bool) 20 20 20 20
    kst-2.0.3/src/libkstapp/debugdialog.ui000644 001750 001750 00000015252 11544160207 020263 0ustar00synthsynth000000 000000 DebugDialog 0 0 666 422 Kst Debug Dialog 0 Build Information 0 6 Qt::RichText false Qt::Vertical QSizePolicy::Expanding 530 250 &Email Debugging Information Qt::Horizontal QSizePolicy::Expanding 301 21 Log Log level: &Debug true &Notice true &Warning true &Error true Qt::Horizontal 221 20 Clea&r Data Sources 0 6 true Plugin Loaded Instance Qt::Horizontal QSizePolicy::Expanding 421 20 &Close _email _close _close clicked() DebugDialog close() 20 20 20 20 kst-2.0.3/src/libkstapp/datawizard.cpp000644 001750 001750 00000104675 11544160207 020324 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datawizard.h" #include #include #include #include #include #include "colorsequence.h" #include "curve.h" #include "datacollection.h" #include "datasourcedialog.h" #include "datavector.h" #include "dialogdefaults.h" #include "document.h" #include "mainwindow.h" #include "objectstore.h" #include "plotitem.h" #include "plotiteminterface.h" #include "settings.h" #include "applicationsettings.h" #include "updatemanager.h" #include "datasourcepluginmanager.h" #include "sharedaxisboxitem.h" #include "boxitem.h" namespace Kst { // // DataWizardPageDataSource // DataWizardPageDataSource::DataWizardPageDataSource(ObjectStore *store, QWidget *parent, const QString& default_source) : QWizardPage(parent), _pageValid(false), _store(store), _requestID(0) { setupUi(this); MainWindow::setWidgetFlags(this); connect(_url, SIGNAL(changed(const QString&)), this, SLOT(sourceChanged(const QString&))); connect(_configureSource, SIGNAL(clicked()), this, SLOT(configureSource())); if (default_source.isEmpty()) { _url->setFile(_dialogDefaults->value("vector/datasource", ".").toString()); } else { _url->setFile(default_source); } _url->setFocus(); _updateBox->addItem("Time Interval"); _updateBox->addItem("Change Detection"); _updateBox->addItem("No Update"); updateUpdateBox(); connect(_updateBox, SIGNAL(activated(int)), this, SLOT(updateTypeActivated(int))); } DataWizardPageDataSource::~DataWizardPageDataSource() { } void DataWizardPageDataSource::updateUpdateBox() { if (_dataSource) { _updateBox->setEnabled(true); switch (_dataSource->updateType()) { case DataSource::Timer: _updateBox->setCurrentIndex(0); break; case DataSource::File: _updateBox->setCurrentIndex(1); break; case DataSource::None: _updateBox->setCurrentIndex(2); break; default: break; }; } else { _updateBox->setEnabled(false); } } void DataWizardPageDataSource::updateTypeActivated(int idx) { if (!_dataSource) { _updateBox->setEnabled(false); return; } switch (idx) { _updateBox->setEnabled(true); case 0: _dataSource->setUpdateType(DataSource::Timer); break; case 1: _dataSource->setUpdateType(DataSource::File); break; case 2: _dataSource->setUpdateType(DataSource::None); break; default: break; }; } bool DataWizardPageDataSource::isComplete() const { return _pageValid; } DataSourcePtr DataWizardPageDataSource::dataSource() const { return _dataSource; } QStringList DataWizardPageDataSource::dataSourceFieldList() const { return _dataSource->vector().list(); } void DataWizardPageDataSource::configureSource() { QPointer dialog = new DataSourceDialog(DataDialog::New, _dataSource, this); if ( dialog->exec() == QDialog::Accepted ) { sourceChanged(_dataSource->fileName()); } delete dialog; } void DataWizardPageDataSource::sourceValid(QString filename, int requestID) { if (_requestID != requestID) { return; } _pageValid = true; _dataSource = DataSourcePluginManager::findOrLoadSource(_store, filename); _fileType->setText(_dataSource->fileType()); _dataSource->readLock(); _configureSource->setEnabled(_dataSource->hasConfigWidget()); _dataSource->unlock(); { DataSourcePtr tmpds = _dataSource; // increase usage count _store->cleanUpDataSourceList(); } updateUpdateBox(); emit completeChanged(); emit dataSourceChanged(); } void DataWizardPageDataSource::sourceChanged(const QString& file) { _pageValid = false; _fileType->setText(QString()); _configureSource->setEnabled(false); _updateBox->setEnabled(false); emit completeChanged(); _requestID += 1; ValidateDataSourceThread *validateDSThread = new ValidateDataSourceThread(file, _requestID); connect(validateDSThread, SIGNAL(dataSourceValid(QString, int)), this, SLOT(sourceValid(QString, int))); QThreadPool::globalInstance()->start(validateDSThread); } // // DataWizardPageVectors // DataWizardPageVectors::DataWizardPageVectors(QWidget *parent) : QWizardPage(parent) { setupUi(this); _up->setIcon(QPixmap(":kst_uparrow.png")); _down->setIcon(QPixmap(":kst_downarrow.png")); _add->setIcon(QPixmap(":kst_rightarrow.png")); _remove->setIcon(QPixmap(":kst_leftarrow.png")); _up->setToolTip(i18n("Raise in plot order: Alt+Up")); _down->setToolTip(i18n("Lower in plot order: Alt+Down")); _add->setToolTip(i18n("Select: Alt+s")); _remove->setToolTip(i18n("Remove: Alt+r")); connect(_add, SIGNAL(clicked()), this, SLOT(add())); connect(_remove, SIGNAL(clicked()), this, SLOT(remove())); connect(_up, SIGNAL(clicked()), this, SLOT(up())); connect(_down, SIGNAL(clicked()), this, SLOT(down())); connect(_vectors, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(add())); connect(_vectorsToPlot, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(remove())); connect(_vectorReduction, SIGNAL(textChanged(const QString&)), this, SLOT(filterVectors(const QString&))); connect(_vectorSearch, SIGNAL(clicked()), this, SLOT(searchVectors())); _vectors->setSortingEnabled(false); _vectorsToPlot->setSortingEnabled(false); } DataWizardPageVectors::~DataWizardPageVectors() { } QListWidget* DataWizardPageVectors::plotVectors() const { return _vectorsToPlot; } void DataWizardPageVectors::updateVectors() { _vectors->clear(); _vectorsToPlot->clear(); _vectors->addItems(((DataWizard*)wizard())->dataSourceFieldList()); } bool DataWizardPageVectors::vectorsSelected() const { return _vectorsToPlot->count() > 0; } bool DataWizardPageVectors::isComplete() const { return vectorsSelected(); } void DataWizardPageVectors::remove() { int j=0; for (int i = 0; i < _vectorsToPlot->count(); i++) { if (_vectorsToPlot->item(i) && _vectorsToPlot->item(i)->isSelected()) { _vectors->addItem(_vectorsToPlot->takeItem(i)); j = i; } } if (j>=_vectorsToPlot->count()) { j = _vectorsToPlot->count()-1; } _vectorsToPlot->setFocus(); _vectorsToPlot->setCurrentRow(j); _vectors->clearSelection(); emit completeChanged(); } void DataWizardPageVectors::add() { for (int i = 0; i < _vectors->count(); i++) { if (_vectors->item(i) && _vectors->item(i)->isSelected()) { _vectorsToPlot->addItem(_vectors->takeItem(i)); i--; } } _vectorsToPlot->setCurrentRow(_vectorsToPlot->count() - 1); emit completeChanged(); } void DataWizardPageVectors::up() { _vectorsToPlot->setFocus(); int i = _vectorsToPlot->currentRow(); if (i != -1) { QListWidgetItem *item = _vectorsToPlot->takeItem(i); _vectorsToPlot->insertItem(i-1, item); _vectorsToPlot->clearSelection(); _vectorsToPlot->setCurrentItem(item); emit completeChanged(); } } void DataWizardPageVectors::down() { // move item down int i = _vectorsToPlot->currentRow(); if (i != -1) { QListWidgetItem *item = _vectorsToPlot->takeItem(i); _vectorsToPlot->insertItem(i+1, item); _vectorsToPlot->clearSelection(); _vectorsToPlot->setCurrentItem(item); emit completeChanged(); } } void DataWizardPageVectors::filterVectors(const QString& filter) { _vectors->clearSelection(); if (filter=="*") { // optimization _vectors->selectAll(); return; } QRegExp re(filter, Qt::CaseSensitive, QRegExp::Wildcard); QStringList selected; for (int i = 0; i < _vectors->count(); i++) { QListWidgetItem *item = _vectors->item(i); if (re.exactMatch(item->text())) { item = _vectors->takeItem(i); selected.append(item->text()); i--; } } _vectors->insertItems(0, selected); for (int i=0; iitem(i)->setSelected(true); } } void DataWizardPageVectors::searchVectors() { QString s = _vectorReduction->text(); if (!s.isEmpty()) { if (s[0] != '*') { s = '*' + s; } if (s[s.length()-1] != '*') { s += '*'; } _vectorReduction->setText(s); } } // // DataWizardPageFilters // DataWizardPageFilters::DataWizardPageFilters(QWidget *parent) : QWizardPage(parent) { setupUi(this); } DataWizardPageFilters::~DataWizardPageFilters() { } DataWizardPagePlot::DataWizardPagePlot(QWidget *parent) : QWizardPage(parent) { setupUi(this); connect(_customGrid, SIGNAL(toggled(bool)), this, SLOT(updateButtons())); updatePlotBox(); updateButtons(); } // // DataWizardPagePlot // DataWizardPagePlot::~DataWizardPagePlot() { } void DataWizardPagePlot::updateButtons() { _gridColumns->setEnabled(_customGrid->isChecked()); } DataWizardPagePlot::CurvePlotPlacement DataWizardPagePlot::curvePlacement() const { CurvePlotPlacement placement = OnePlot; if (_multiplePlots->isChecked()) { placement = MultiplePlots; } else if (_cycleThrough->isChecked()) { placement = CyclePlotCount; } else if (_cycleExisting->isChecked()) { placement = CycleExisting; } else if (_existingPlot->isChecked()) { placement = ExistingPlot; } return placement; } DataWizardPagePlot::PlotTabPlacement DataWizardPagePlot::plotTabPlacement() const { PlotTabPlacement placement = CurrentTab; if (_newTab->isChecked()) { placement = NewTab; } else if (_separateTabs->isChecked()) { placement = SeparateTabs; } return placement; } CurvePlacement::Layout DataWizardPagePlot::layout() const { if (_autoLayout->isChecked()) return CurvePlacement::Auto; else if (_customGrid->isChecked()) return CurvePlacement::Custom; else return CurvePlacement::Protect; } int DataWizardPagePlot::gridColumns() const { return _gridColumns->value(); } bool DataWizardPagePlot::drawLines() const { return _drawLines->isChecked(); } bool DataWizardPagePlot::drawPoints() const { return _drawPoints->isChecked(); } bool DataWizardPagePlot::drawLinesAndPoints() const { return _drawBoth->isChecked(); } bool DataWizardPagePlot::PSDLogX() const { return _psdLogX->isChecked(); } bool DataWizardPagePlot::PSDLogY() const { return _psdLogY->isChecked(); } bool DataWizardPagePlot::legendsOn() const { return _legendsOn->isChecked(); } bool DataWizardPagePlot::legendsAuto() const { return _legendsAuto->isChecked(); } bool DataWizardPagePlot::legendsVertical() const { return _legendsVertical->isChecked(); } bool DataWizardPagePlot::rescaleFonts() const { return _rescaleFonts->isChecked(); } bool DataWizardPagePlot::shareAxis() const { return _shareAxis->isChecked(); } int DataWizardPagePlot::plotCount() const { return _plotNumber->value(); } PlotItemInterface *DataWizardPagePlot::existingPlot() const { return qVariantValue(_existingPlotName->itemData(_existingPlotName->currentIndex())); } void DataWizardPagePlot::updatePlotBox() { _plotNumber->setValue(_dialogDefaults->value("wizard/plotCount",2).toInt()); if (_dialogDefaults->value("wizard/legendsAuto",true).toBool()) { _legendsOn->setChecked(true); } else if (_dialogDefaults->value("wizard/legendsOn",false).toBool()) { _legendsAuto->setChecked(true); } else { _legendsOff->setChecked(true); } _psdLogX->setChecked(_dialogDefaults->value("wizard/logX",false).toBool()); _psdLogY->setChecked(_dialogDefaults->value("wizard/logY",false).toBool()); _legendsOn->setChecked(_dialogDefaults->value("wizard/legendsOn",false).toBool()); _legendsAuto->setChecked(_dialogDefaults->value("wizard/legendsAuto",false).toBool()); _legendsVertical->setChecked(_dialogDefaults->value("legend/verticalDisplay",false).toBool()); _rescaleFonts->setChecked(_dialogDefaults->value("wizard/rescaleFonts", true).toBool()); _shareAxis->setChecked(_dialogDefaults->value("wizard/shareAxis", false).toBool()); _shareAxis->hide(); //FIXME - not done yet. if (_dialogDefaults->value("wizard/linesOnly", true).toBool()) { _drawLines->setChecked(true); } else if (_dialogDefaults->value("wizard/pointsOnly", true).toBool()) { _drawPoints->setChecked(true); } else { _drawBoth->setChecked(true); } foreach (PlotItemInterface *plot, Data::self()->plotList()) { _existingPlotName->addItem(plot->plotName(), qVariantFromValue(plot)); } bool havePlots = _existingPlotName->count() > 0; _cycleExisting->setEnabled(havePlots); _existingPlot->setEnabled(havePlots); _existingPlotName->setEnabled(havePlots && _existingPlot->isChecked()); CurvePlotPlacement placement = static_cast(_dialogDefaults->value("wizard/curvePlacement",MultiplePlots).toInt()); switch (placement) { case OnePlot: _onePlot->setChecked(true); break; case MultiplePlots: _multiplePlots->setChecked(true); break; case CyclePlotCount: _cycleThrough->setChecked(true); break; case CycleExisting: if (havePlots) { _cycleExisting->setChecked(true); } else { _multiplePlots->setChecked(true); } break; case ExistingPlot: if (havePlots) { _existingPlot->setChecked(true); } else { _onePlot->setChecked(true); } break; default: _multiplePlots->setChecked(true); break; } CurvePlacement::Layout layout = static_cast(_dialogDefaults->value("wizard/plotLayout", CurvePlacement::Auto).toInt()); switch (layout) { case CurvePlacement::Auto: _autoLayout->setChecked(true); break; case CurvePlacement::Custom: _customGrid->setChecked(true); break; case CurvePlacement::Protect: _protectLayout->setChecked(true); break; } _gridColumns->setValue(_dialogDefaults->value("wizard/gridColumns", CurvePlacement::Auto).toInt()); } // // DataWizardPageDataPresentation // DataWizardPageDataPresentation::DataWizardPageDataPresentation(ObjectStore *store, QWidget *parent) : QWizardPage(parent), _pageValid(false) { setupUi(this); _xVectorExisting->setObjectStore(store); _xVectorExisting->setToLastX(_dialogDefaults->value("curve/xvectorfield","INDEX").toString()); _xAxisUseExisting->setChecked(_xVectorExisting->count()>0); dataRange()->loadWidgetDefaults(); getFFTOptions()->loadWidgetDefaults(); connect(_xAxisCreateFromField, SIGNAL(toggled(bool)), this, SLOT(optionsUpdated())); connect(_xVector, SIGNAL(currentIndexChanged(int)), this, SLOT(optionsUpdated())); connect(_xVectorExisting, SIGNAL(selectionChanged(QString)), this, SLOT(optionsUpdated())); _FFTOptions->GroupBoxFFTOptions->setCheckable(true); _FFTOptions->GroupBoxFFTOptions->setTitle(i18n("Create S&pectra Plots. Set FFT options below:")); _FFTOptions->GroupBoxFFTOptions->setChecked(false); // fixme: use persistant defaults _FFTOptions->GroupBoxFFTOptions->setChecked(_dialogDefaults->value("wizard/doPSD",false).toBool()); _xAxisGroup->setChecked(_dialogDefaults->value("wizard/doXY",true).toBool()); } DataWizardPageDataPresentation::~DataWizardPageDataPresentation() { } FFTOptions* DataWizardPageDataPresentation::getFFTOptions() const { return _FFTOptions; } DataRange* DataWizardPageDataPresentation::dataRange() const { return _DataRange; } bool DataWizardPageDataPresentation::createXAxisFromField() const { return _xAxisCreateFromField->isChecked(); } QString DataWizardPageDataPresentation::vectorField() const { return _xVector->currentText(); } VectorPtr DataWizardPageDataPresentation::selectedVector() const { return _xVectorExisting->selectedVector(); } bool DataWizardPageDataPresentation::plotPSD() const { return _FFTOptions->GroupBoxFFTOptions->isChecked(); } bool DataWizardPageDataPresentation::plotData() const { return _xAxisGroup->isChecked(); } bool DataWizardPageDataPresentation::plotDataPSD() const { return (plotPSD() && plotData()); } void DataWizardPageDataPresentation::optionsUpdated() { _pageValid = validOptions(); emit completeChanged(); } void DataWizardPageDataPresentation::updateVectors() { _xVector->clear(); _xVector->addItems(((DataWizard*)wizard())->dataSourceFieldList()); _pageValid = validOptions(); int x_index = _xVector->findText(_dialogDefaults->value("curve/xvectorfield","INDEX").toString()); if (x_index<0) { x_index = _xVector->findText("INDEX"); } if (x_index<0) { x_index = 0; } _xVector->setCurrentIndex(x_index); emit completeChanged(); } void DataWizardPageDataPresentation::applyFilter(bool filter) { emit filterApplied(filter); } bool DataWizardPageDataPresentation::isComplete() const { return _pageValid; } bool DataWizardPageDataPresentation::validOptions() { if (!_xAxisGroup->isEnabled()) { return true; } if (_xAxisCreateFromField->isChecked()) { QString txt = _xVector->currentText(); for (int i = 0; i < _xVector->count(); ++i) { if (_xVector->itemText(i) == txt) { return true; } } return false; } else { return (_xVectorExisting->selectedVector()); } } int DataWizardPageDataPresentation::nextId() const { // if (_applyFilters->isChecked()) { // return DataWizard::PageFilters; // } else { return DataWizard::PagePlot; // } } // // DataWizard // DataWizard::DataWizard(QWidget *parent, const QString& fileToOpen) : QWizard(parent), _document(0) { if (MainWindow *mw = qobject_cast(parent)) { _document = mw->document(); } else { // FIXME: we need a document qFatal("ERROR: can't construct a DataWizard without a document"); } Q_ASSERT(_document); _pageDataSource = new DataWizardPageDataSource(_document->objectStore(), this, fileToOpen); _pageVectors = new DataWizardPageVectors(this); _pageDataPresentation = new DataWizardPageDataPresentation(_document->objectStore(), this); _pageFilters = new DataWizardPageFilters(this); _pagePlot = new DataWizardPagePlot(this); setPage(PageDataSource, _pageDataSource); setPage(PageVectors, _pageVectors); setPage(PageDataPresentation, _pageDataPresentation); setPage(PageFilters, _pageFilters); setPage(PagePlot, _pagePlot); setWindowTitle("Data Wizard"); setAttribute(Qt::WA_DeleteOnClose); show(); connect(_pageDataSource, SIGNAL(dataSourceChanged()), _pageVectors, SLOT(updateVectors())); connect(_pageDataSource, SIGNAL(dataSourceChanged()), _pageDataPresentation, SLOT(updateVectors())); disconnect(button(QWizard::FinishButton), SIGNAL(clicked()), (QDialog*)this, SLOT(accept())); connect(button(QWizard::FinishButton), SIGNAL(clicked()), this, SLOT(finished())); // the dialog needs to know that the default has been set.... _pageDataSource->sourceChanged(_dialogDefaults->value("vector/datasource",".").toString()); if (!fileToOpen.isEmpty()) { _pageDataSource->sourceChanged(fileToOpen); } } DataWizard::~DataWizard() { } QStringList DataWizard::dataSourceFieldList() const { return _pageDataSource->dataSourceFieldList(); } void DataWizard::finished() { DataVectorList vectors; uint n_curves = 0; uint n_steps = 0; _dialogDefaults->setValue("wizard/doPSD", _pageDataPresentation->plotPSD()); _dialogDefaults->setValue("wizard/doXY", _pageDataPresentation->plotData()); _dialogDefaults->setValue("wizard/curvePlacement", _pagePlot->curvePlacement()); _dialogDefaults->setValue("wizard/plotCount", _pagePlot->plotCount()); _dialogDefaults->setValue("wizard/legendsOn", _pagePlot->legendsOn()); _dialogDefaults->setValue("wizard/legendsAuto", _pagePlot->legendsAuto()); _dialogDefaults->setValue("legend/verticalDisplay", _pagePlot->legendsVertical()); _dialogDefaults->setValue("wizard/logX", _pagePlot->PSDLogX()); _dialogDefaults->setValue("wizard/logY", _pagePlot->PSDLogY()); _dialogDefaults->setValue("wizard/rescaleFonts", _pagePlot->rescaleFonts()); _dialogDefaults->setValue("wizard/shareAxis", _pagePlot->shareAxis()); _dialogDefaults->setValue("wizard/linesOnly", _pagePlot->drawLines()); _dialogDefaults->setValue("wizard/pointsOnly", _pagePlot->drawPoints()); _dialogDefaults->setValue("wizard/plotLayout", _pagePlot->layout()); _dialogDefaults->setValue("wizard/gridColumns", _pagePlot->gridColumns()); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); DataSourcePtr ds = _pageDataSource->dataSource(); if (!ds.isPtrValid()) { return; } emit dataSourceLoaded(ds->fileName()); // check for sufficient memory unsigned long memoryRequested = 0, memoryAvailable = 1024*1024*1024; // 1GB double frames; #ifdef __linux__ meminfo(); memoryAvailable = S(kb_main_free + kb_main_buffers + kb_main_cached); #endif ds->writeLock(); double startOffset = _pageDataPresentation->dataRange()->start(); double rangeCount = _pageDataPresentation->dataRange()->range(); // only add to memory requirement if xVector is to be created if (_pageDataPresentation->createXAxisFromField()) { if (_pageDataPresentation->dataRange()->readToEnd()) { frames = ds->vector().dataInfo(_pageDataPresentation->vectorField()).frameCount - startOffset; } else { frames = qMin(rangeCount,double(ds->vector().dataInfo(_pageDataPresentation->vectorField()).frameCount)); } if (_pageDataPresentation->dataRange()->doSkip() && _pageDataPresentation->dataRange()->skip() > 0) { memoryRequested += frames / _pageDataPresentation->dataRange()->skip() * sizeof(double); } else { memoryRequested += frames * ds->vector().dataInfo(_pageDataPresentation->vectorField()).samplesPerFrame * sizeof(double); } } // memory estimate for the y vectors { int fftLen = int(pow(2.0, double(_pageDataPresentation->getFFTOptions()->FFTLength() - 1))); for (int i = 0; i < _pageVectors->plotVectors()->count(); i++) { QString field = _pageVectors->plotVectors()->item(i)->text(); if (_pageDataPresentation->dataRange()->readToEnd()) { frames = ds->vector().dataInfo(field).frameCount - startOffset; } else { frames = rangeCount; int fc = ds->vector().dataInfo(field).frameCount; if (frames > (unsigned long) fc) { frames = fc; } } if (_pageDataPresentation->dataRange()->doSkip() && _pageDataPresentation->dataRange()->skip() > 0) { memoryRequested += frames / _pageDataPresentation->dataRange()->skip()*sizeof(double); } else { memoryRequested += frames * ds->vector().dataInfo(field).samplesPerFrame * sizeof(double); } if (_pageDataPresentation->plotPSD()) { memoryRequested += fftLen * 6; } } } ds->unlock(); if (memoryRequested > memoryAvailable) { QApplication::restoreOverrideCursor(); QMessageBox::warning(this, i18n("Insufficient Memory"), i18n("You requested to read in %1 MB of data but it seems that you only have approximately %2 MB of usable memory available. You cannot load this much data.").arg(memoryRequested/(1024*1024)).arg(memoryAvailable/(1024*1024))); return; } n_steps += _pageVectors->plotVectors()->count(); if (_pageDataPresentation->plotPSD()) { n_steps += _pageVectors->plotVectors()->count(); } VectorPtr xv; // only create x vector if needed if (_pageDataPresentation->createXAxisFromField()) { n_steps += 1; // for the creation of the x-vector const QString field = _pageDataPresentation->vectorField(); _dialogDefaults->setValue("curve/xvectorfield",field); Q_ASSERT(_document && _document->objectStore()); DataVectorPtr dxv = _document->objectStore()->createObject(); dxv->writeLock(); dxv->change(ds, field, _pageDataPresentation->dataRange()->countFromEnd() ? -1 : startOffset, _pageDataPresentation->dataRange()->readToEnd() ? -1 : rangeCount, _pageDataPresentation->dataRange()->skip(), _pageDataPresentation->dataRange()->doSkip(), _pageDataPresentation->dataRange()->doFilter()); dxv->registerChange(); dxv->unlock(); xv = dxv; } else { xv = kst_cast(_pageDataPresentation->selectedVector()); } // only create create the y-vectors { DataVectorPtr vector; for (int i = 0; i < _pageVectors->plotVectors()->count(); i++) { QString field = _pageVectors->plotVectors()->item(i)->text(); Q_ASSERT(_document && _document->objectStore()); vector = _document->objectStore()->createObject(); vector->writeLock(); vector->change(ds, field, _pageDataPresentation->dataRange()->countFromEnd() ? -1 : startOffset, _pageDataPresentation->dataRange()->readToEnd() ? -1 : rangeCount, _pageDataPresentation->dataRange()->skip(), _pageDataPresentation->dataRange()->doSkip(), _pageDataPresentation->dataRange()->doFilter()); vector->registerChange(); vector->unlock(); vectors.append(vector); ++n_curves; } if (n_curves>0) { _pageDataPresentation->dataRange()->setWidgetDefaults(); setDataVectorDefaults(vector); } } // Create a new tab, if we asked for it and the current tab isn't empty. if ((_pagePlot->plotTabPlacement() == DataWizardPagePlot::NewTab) || (_pagePlot->plotTabPlacement() == DataWizardPagePlot::SeparateTabs)) { if (_document->currentView()->scene()->items().count()>0) { _document->createView(); } } // create the necessary plots QList plotList; PlotItem *plotItem = 0; bool relayout = true; int plotsInPage = _document->currentView()->scene()->items().count(); bool separate_plots = ((_pagePlot->plotTabPlacement() == DataWizardPagePlot::SeparateTabs) && _pageDataPresentation->plotPSD() && _pageDataPresentation->plotData()); switch (_pagePlot->curvePlacement()) { case DataWizardPagePlot::ExistingPlot: { plotItem = static_cast(_pagePlot->existingPlot()); plotList.append(plotItem); relayout = false; break; } case DataWizardPagePlot::OnePlot: { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); plotList.append(plotItem); if (_pageDataPresentation->plotDataPSD()) { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); plotList.append(plotItem); } break; } case DataWizardPagePlot::MultiplePlots: { int nplots = vectors.count() * (_pageDataPresentation->plotPSD() + _pageDataPresentation->plotData()); if (separate_plots) nplots/=2; for (int i = 0; i < nplots; ++i) { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); plotList.append(plotItem); } if (separate_plots) { _document->createView(); for (int i = 0; i < nplots; ++i) { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); plotList.append(plotItem); } } break; } case DataWizardPagePlot::CycleExisting: { foreach (PlotItemInterface *plot, Data::self()->plotList()) { plotItem = static_cast(plot); plotList.append(plotItem); } relayout = false; break; } case DataWizardPagePlot::CyclePlotCount: { int nplots = _pagePlot->plotCount() * (_pageDataPresentation->plotPSD() + _pageDataPresentation->plotData()); for (int i = 0; i < nplots; ++i) { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); plotList.append(plotItem); } } default: break; } // create the data curves QList colors; QColor color; int ptype = 0; int i_plot = 0; for (DataVectorList::Iterator it = vectors.begin(); it != vectors.end(); ++it) { if (_pageDataPresentation->plotData()) { color = ColorSequence::self().next(); colors.append(color); DataVectorPtr vector = kst_cast(*it); Q_ASSERT(vector); Q_ASSERT(_document && _document->objectStore()); CurvePtr curve = _document->objectStore()->createObject(); curve->setXVector(xv); curve->setYVector(vector); curve->setXError(0); curve->setYError(0); curve->setXMinusError(0); curve->setYMinusError(0); curve->setColor(color); curve->setHasPoints(_pagePlot->drawLinesAndPoints() || _pagePlot->drawPoints()); curve->setHasLines(_pagePlot->drawLinesAndPoints() || _pagePlot->drawLines()); curve->setLineWidth(Settings::globalSettings()->defaultLineWeight); curve->setPointType(ptype++ % KSTPOINT_MAXTYPE); curve->writeLock(); curve->registerChange(); curve->unlock(); Q_ASSERT(plotList[i_plot]); PlotRenderItem *renderItem = plotList[i_plot]->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(curve)); // increment i_plot, as appropriate; if (_pagePlot->curvePlacement() != DataWizardPagePlot::OnePlot) { ++i_plot; if (_pagePlot->curvePlacement()==DataWizardPagePlot::CyclePlotCount) { if (i_plot == _pagePlot->plotCount()) { i_plot = 0; } } else if (i_plot == plotList.count()) { i_plot = 0; } } } } if (_pagePlot->curvePlacement() == DataWizardPagePlot::OnePlot) { // if we are one plot, now we can move to the psd plot if (++i_plot == plotList.count()) { i_plot = 0; } } else if (_pageDataPresentation->plotDataPSD()) { i_plot = plotList.count()/2; } // create the PSDs if (_pageDataPresentation->plotPSD()) { int indexColor = 0; ptype = 0; PSDPtr powerspectrum; int n_psd=0; for (DataVectorList::Iterator it = vectors.begin(); it != vectors.end(); ++it) { if ((*it)->length() > 0) { Q_ASSERT(_document && _document->objectStore()); powerspectrum = _document->objectStore()->createObject(); n_psd++; Q_ASSERT(powerspectrum); powerspectrum->writeLock(); powerspectrum->change(*it, _pageDataPresentation->getFFTOptions()->sampleRate(), _pageDataPresentation->getFFTOptions()->interleavedAverage(), _pageDataPresentation->getFFTOptions()->FFTLength(), _pageDataPresentation->getFFTOptions()->apodize(), _pageDataPresentation->getFFTOptions()->removeMean(), _pageDataPresentation->getFFTOptions()->vectorUnits(), _pageDataPresentation->getFFTOptions()->rateUnits(), _pageDataPresentation->getFFTOptions()->apodizeFunction(), _pageDataPresentation->getFFTOptions()->sigma(), _pageDataPresentation->getFFTOptions()->output(), _pageDataPresentation->getFFTOptions()->interpolateOverHoles()); powerspectrum->registerChange(); powerspectrum->unlock(); CurvePtr curve = _document->objectStore()->createObject(); Q_ASSERT(curve); curve->setXVector(powerspectrum->vX()); curve->setYVector(powerspectrum->vY()); curve->setHasPoints(_pagePlot->drawLinesAndPoints() || _pagePlot->drawPoints()); curve->setHasLines(_pagePlot->drawLinesAndPoints() || _pagePlot->drawLines()); curve->setLineWidth(Settings::globalSettings()->defaultLineWeight); curve->setPointType(ptype++ % KSTPOINT_MAXTYPE); if (!_pageDataPresentation->plotDataPSD() || colors.count() <= indexColor) { color = ColorSequence::self().next(); } else { color = colors[indexColor]; indexColor++; } curve->setColor(color); curve->writeLock(); curve->registerChange(); curve->unlock(); Q_ASSERT(plotList[i_plot]); PlotRenderItem *renderItem = plotList[i_plot]->renderItem(PlotRenderItem::Cartesian); plotList[i_plot]->xAxis()->setAxisLog(_pagePlot->PSDLogX()); plotList[i_plot]->yAxis()->setAxisLog(_pagePlot->PSDLogY()); renderItem->addRelation(kst_cast(curve)); if (_pagePlot->curvePlacement() != DataWizardPagePlot::OnePlot) { // change plots if we are not onePlot if (++i_plot == plotList.count()) { if (_pageDataPresentation->plotDataPSD()) { // if xy and psd i_plot = plotList.count()/2; } else { i_plot = 0;; } } } } } if (n_psd>0) { _pageDataPresentation->getFFTOptions()->setWidgetDefaults(); } } if (plotsInPage==0 || _pagePlot->rescaleFonts()) { int np = plotList.count(); if (np > 0) { plotList.at(0)->view()->resetPlotFontSizes(); // set font sizes on first page. if (plotList.at(np-1)->view() != plotList.at(0)->view()) { // and second, if there is one. plotList.at(np-1)->view()->resetPlotFontSizes(); } } } else { foreach (PlotItem* plot, plotList) { _document->currentView()->configurePlotFontDefaults(plot); // copy plots already in window } } foreach (PlotItem* plot, plotList) { plot->update(); plot->view()->appendToLayout(_pagePlot->layout(), plot, _pagePlot->gridColumns()); } double fontScale; fontScale = ApplicationSettings::self()->defaultFontScale(); foreach (PlotItem* plot, plotList) { if (_pagePlot->legendsOn()) { plot->setShowLegend(true, true); plot->legend()->setVerticalDisplay(_pagePlot->legendsVertical()); } else if (_pagePlot->legendsAuto()) { if (plot->renderItem(PlotRenderItem::Cartesian)->relationList().count() > 1) { plot->setShowLegend(true, true); plot->legend()->setVerticalDisplay(_pagePlot->legendsVertical()); } } } if (_pagePlot->shareAxis()) { //FIXME: apply shared axis // also delete the line _shareAxis->hide(); } UpdateManager::self()->doUpdates(true); kstApp->mainWindow()->document()->setChanged(true); QApplication::restoreOverrideCursor(); accept(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datawizardpagedatapresentation.ui000644 001750 001750 00000006266 11544160207 024277 0ustar00synthsynth000000 000000 DataWizardPageDataPresentation 0 0 852 355 0 Create &XY plots. Set X-axis vector properties below: true 0 0 Create fr&om field: true 0 0 Use existin&g: 1 0 The field to be used as the X-axis in XY curves. Kst::ComboBox QComboBox
    combobox.h
    Kst::DataRange QWidget
    datarange.h
    Kst::VectorSelector QWidget
    vectorselector.h
    Kst::FFTOptions QWidget
    fftoptions.h
    kst-2.0.3/src/libkstapp/dialog.h000644 001750 001750 00000004027 11544160207 017064 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIALOG_H #define DIALOG_H #include #include "kst_export.h" #include "ui_dialog.h" template class QHash; namespace Kst { class DialogPage; class Dialog : public QDialog, public Ui::Dialog { Q_OBJECT public: Dialog(QWidget *parent = 0); virtual ~Dialog(); void addDialogPage(DialogPage *page, bool addMinSize = true); void removeDialogPage(DialogPage *page); DialogPage* getDialogPage(const QString &pageName); void selectDialogPage(DialogPage *page); void setAlwaysAllowApply(const bool allow); Q_SIGNALS: void ok(); void apply(); void cancel(); protected: void setVisible(bool visible); QWidget *leftCustomWidget() const; QWidget *rightCustomWidget() const; QWidget *topCustomWidget() const; QWidget *bottomCustomWidget() const; QWidget *extensionWidget() const; QDialogButtonBox *buttonBox() const; private Q_SLOTS: void selectPageForItem(QListWidgetItem *item); void buttonClicked(QAbstractButton *button); void modified(); private: void resetListWidget(); QHash _itemHash; bool _allowApply; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/debugnotifier.h000644 001750 001750 00000003147 11544160207 020455 0ustar00synthsynth000000 000000 /*************************************************************************** debugnotifier.h --------------- begin : Sep 13 2005 copyright : (C) 2005 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DEBUGNOTIFIER_H #define DEBUGNOTIFIER_H #include #include #include class QMouseEvent; namespace Kst { class DebugNotifier : public QLabel { Q_OBJECT public: DebugNotifier(QWidget *parent); ~DebugNotifier(); Q_SIGNALS: void showDebugLog(); public Q_SLOTS: void close(); void reanimate(); private Q_SLOTS: void animate(); protected: void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); private: int _animationStage; bool _gotPress; QVector _pm; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/powerspectrumtab.ui000644 001750 001750 00000004573 11544160207 021427 0ustar00synthsynth000000 000000 PowerSpectrumTab 0 0 687 674 Power Spectrum Contents 0 0 Data vecto&r: false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::CurvePlacement QWidget
    curveplacement.h
    Kst::CurveAppearance QWidget
    curveappearance.h
    Kst::FFTOptions QWidget
    fftoptions.h
    _FFTOptions _curveAppearance _curvePlacement
    kst-2.0.3/src/libkstapp/sessionmodel.h000644 001750 001750 00000004133 11544160207 020327 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SESSIONMODEL_H #define SESSIONMODEL_H #include #include "dataobject.h" #include "object.h" #include "relation.h" namespace Kst { class ObjectStore; class SessionModel : public QAbstractItemModel { public: SessionModel(ObjectStore *store); ~SessionModel(); int columnCount(const QModelIndex& parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; QModelIndex index(int row, int col, const QModelIndex& parent = QModelIndex()) const; QModelIndex parent(const QModelIndex& index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; void generateObjectList(); void triggerReset(); ObjectList *objectList() {return &_objectList;} private: QVariant dataObjectOutputData(DataObjectPtr parent, const QModelIndex& index) const; QVariant primitiveData(PrimitivePtr parent, const QModelIndex& index) const; QVariant dataObjectData(DataObjectPtr dataObject, const QModelIndex& index) const; QVariant relationData(RelationPtr relation, const QModelIndex& index) const; ObjectList _objectList; ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialoglaunchergui.cpp000644 001750 001750 00000017571 11544160207 021656 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dialoglaunchergui.h" #include "application.h" #include "curvedialog.h" #include "equationdialog.h" #include "histogramdialog.h" #include "vectordialog.h" #include "scalardialog.h" #include "stringdialog.h" #include "matrixdialog.h" #include "powerspectrumdialog.h" #include "csddialog.h" #include "imagedialog.h" #include "eventmonitordialog.h" #include "basicplugindialog.h" #include "filterfitdialog.h" #include "curve.h" #include "equation.h" #include "vector.h" #include "matrix.h" #include "histogram.h" #include "psd.h" #include "eventmonitorentry.h" #include "image.h" #include "csd.h" #include "basicplugin.h" namespace Kst { DialogLauncherGui::DialogLauncherGui() { } DialogLauncherGui::~DialogLauncherGui() { } void DialogLauncherGui::showVectorDialog(QString &vectorname, ObjectPtr objectPtr, bool modal) { VectorDialog *dialog = new VectorDialog(objectPtr, kstApp->mainWindow()); if (!vectorname.isEmpty()) { dialog->setField(vectorname); } if (modal) { dialog->setAttribute(Qt::WA_DeleteOnClose, false); dialog->exec(); vectorname = dialog->dataObjectName(); delete dialog; } else { dialog->show(); } } void DialogLauncherGui::showMatrixDialog(QString &matrixName, ObjectPtr objectPtr, bool modal) { MatrixDialog *dialog = new MatrixDialog(objectPtr, kstApp->mainWindow()); if (modal) { dialog->setAttribute(Qt::WA_DeleteOnClose, false); dialog->exec(); matrixName = dialog->dataObjectName(); delete dialog; } else { dialog->show(); } } void DialogLauncherGui::showScalarDialog(QString &scalarname, ObjectPtr objectPtr, bool modal) { ScalarDialog *dialog = new ScalarDialog(objectPtr, kstApp->mainWindow()); if (modal) { dialog->setAttribute(Qt::WA_DeleteOnClose, false); dialog->exec(); scalarname = dialog->dataObjectName(); delete dialog; } else { dialog->show(); } } void DialogLauncherGui::showStringDialog(QString &stringname, ObjectPtr objectPtr, bool modal) { StringDialog *dialog = new StringDialog(objectPtr, kstApp->mainWindow()); if (modal) { dialog->setAttribute(Qt::WA_DeleteOnClose, false); dialog->exec(); stringname = dialog->dataObjectName(); delete dialog; } else { dialog->show(); } } void DialogLauncherGui::showCurveDialog(ObjectPtr objectPtr, VectorPtr vector) { CurveDialog *dialog = new CurveDialog(objectPtr, kstApp->mainWindow()); if (vector) { dialog->setVector(vector); } dialog->show(); } void DialogLauncherGui::showMultiCurveDialog(QList curves) { CurveDialog *dialog = new CurveDialog(curves.at(0), kstApp->mainWindow()); dialog->show(); dialog->editMultiple(curves); } void DialogLauncherGui::showImageDialog(ObjectPtr objectPtr, MatrixPtr matrix) { ImageDialog *dialog = new ImageDialog(objectPtr, kstApp->mainWindow()); if (matrix) { dialog->setMatrix(matrix); } dialog->show(); } void DialogLauncherGui::showMultiImageDialog(QList images) { ImageDialog *dialog = new ImageDialog(images.at(0), kstApp->mainWindow()); dialog->show(); dialog->editMultiple(images); } void DialogLauncherGui::showEquationDialog(ObjectPtr objectPtr) { EquationDialog *dialog = new EquationDialog(objectPtr, kstApp->mainWindow()); dialog->show(); } void DialogLauncherGui::showHistogramDialog(ObjectPtr objectPtr, VectorPtr vector) { HistogramDialog *dialog = new HistogramDialog(objectPtr, kstApp->mainWindow()); if (vector) { dialog->setVector(vector); } dialog->show(); } void DialogLauncherGui::showPowerSpectrumDialog(ObjectPtr objectPtr, VectorPtr vector) { PowerSpectrumDialog *dialog = new PowerSpectrumDialog(objectPtr, kstApp->mainWindow()); if (vector) { dialog->setVector(vector); } dialog->show(); } void DialogLauncherGui::showCSDDialog(ObjectPtr objectPtr, VectorPtr vector) { CSDDialog *dialog = new CSDDialog(objectPtr, kstApp->mainWindow()); if (vector) { dialog->setVector(vector); } dialog->show(); } void DialogLauncherGui::showEventMonitorDialog(ObjectPtr objectPtr) { EventMonitorDialog *dialog = new EventMonitorDialog(objectPtr, kstApp->mainWindow()); dialog->show(); } void DialogLauncherGui::showBasicPluginDialog(QString pluginName, ObjectPtr objectPtr, VectorPtr vectorX, VectorPtr vectorY, PlotItemInterface *plotItem) { if (DataObject::pluginType(pluginName) == DataObjectPluginInterface::Generic) { BasicPluginDialog *dialog = new BasicPluginDialog(pluginName, objectPtr, kstApp->mainWindow()); dialog->show(); } else { FilterFitDialog *dialog = new FilterFitDialog(pluginName, objectPtr, kstApp->mainWindow()); if (!objectPtr) { if (vectorX) { dialog->setVectorX(vectorX); } if (vectorY) { dialog->setVectorY(vectorY); } if (plotItem) { dialog->setPlotMode((PlotItem*)plotItem); } } dialog->show(); // FIXME: Total hack to make the window appear at a good place. // This is not necessary for other dialogs, and I can't figure out why (!) QRect r = kstApp->mainWindow()->rect(); int x = r.x() + 30; int y = r.y() + 30; dialog->move(x,y); } } void DialogLauncherGui::showMultiObjectDialog(QList objects) { if (objects.count() > 0) { if (CurvePtr curve = kst_cast(objects.at(0))) { DialogLauncher::self()->showMultiCurveDialog(objects); } else if (ImagePtr image = kst_cast(objects.at(0))) { DialogLauncher::self()->showMultiImageDialog(objects); } } } void DialogLauncherGui::showObjectDialog(ObjectPtr objectPtr) { if (CurvePtr curve = kst_cast(objectPtr)) { DialogLauncher::self()->showCurveDialog(curve); } else if (EquationPtr equation = kst_cast(objectPtr)) { DialogLauncher::self()->showEquationDialog(equation); } else if (HistogramPtr histogram = kst_cast(objectPtr)) { DialogLauncher::self()->showHistogramDialog(histogram); } else if (PSDPtr psd = kst_cast(objectPtr)) { DialogLauncher::self()->showPowerSpectrumDialog(psd); } else if (EventMonitorEntryPtr eventMonitorEntry = kst_cast(objectPtr)) { DialogLauncher::self()->showEventMonitorDialog(eventMonitorEntry); } else if (ImagePtr image = kst_cast(objectPtr)) { DialogLauncher::self()->showImageDialog(image); } else if (CSDPtr csd = kst_cast(objectPtr)) { DialogLauncher::self()->showCSDDialog(csd); } else if (VectorPtr vector = kst_cast(objectPtr)) { QString tmp; DialogLauncher::self()->showVectorDialog(tmp, vector); } else if (MatrixPtr matrix = kst_cast(objectPtr)) { QString tmp; DialogLauncher::self()->showMatrixDialog(tmp, matrix); } else if (BasicPluginPtr plugin = kst_cast(objectPtr)) { DialogLauncher::self()->showBasicPluginDialog(plugin->pluginName(), plugin); } else if (ScalarPtr scalar = kst_cast(objectPtr)) { QString tmp; DialogLauncher::self()->showScalarDialog(tmp, scalar); } else if (StringPtr string = kst_cast(objectPtr)) { QString tmp; DialogLauncher::self()->showStringDialog(tmp, string); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datadialog.h000644 001750 001750 00000005010 11544160207 017707 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATADIALOG_H #define DATADIALOG_H #include "dialog.h" #include "kst_export.h" #include "dataobject.h" class QLineEdit; class QCheckBox; class QLabel; namespace Kst { class DataTab; class Document; class EditMultipleWidget; class DataDialog : public Dialog { Q_OBJECT public: enum EditMode { New, Edit, EditMultiple }; explicit DataDialog(ObjectPtr dataObject = 0, QWidget *parent = 0, bool edit_multiple = true); virtual ~DataDialog(); EditMode editMode() const { return _mode; } void addDataTab(DataTab *tab); QString dataObjectName() const; void editMultiple(const QList &objects); protected: virtual QString tagString() const; void setTagString(const QString &tagString); void setShortName(const QString &name); bool tagStringAuto() const; ObjectPtr dataObject() const { return _dataObject; } void setDataObject(ObjectPtr dataObject) { _dataObject = dataObject; } virtual ObjectPtr createNewDataObject() = 0; virtual ObjectPtr editExistingDataObject() const = 0; Document *_document; EditMultipleWidget *_editMultipleWidget; QString _dataObjectName; public Q_SLOTS: void slotEditMultiple(); private Q_SLOTS: void slotApply(); void modified(); void clearModified(); Q_SIGNALS: void editMultipleMode(); void editSingleMode(); private: void createGui(bool edit_multiple = true); void updateApplyButton(); private: QLineEdit *_tagString; QCheckBox *_tagStringAuto; QLabel *_shortName; QLabel *_nameLabel; QPushButton *_editMultipleButton; ObjectPtr _dataObject; EditMode _mode; bool _modified; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/memorywidget.h000644 001750 001750 00000002303 11544160207 020334 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MEMORYWIDGET_H #define MEMORYWIDGET_H #include #include namespace Kst { class MemoryWidget : public QLabel { Q_OBJECT public: explicit MemoryWidget(QWidget *parent, int updateMilliSeconds = 5000); ~MemoryWidget(); public Q_SLOTS: void updateFreeMemory(); private: QTimer _timer; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/datatab.h000644 001750 001750 00000002313 11544160207 017221 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATATAB_H #define DATATAB_H #include "dialogtab.h" #include "kst_export.h" namespace Kst { class DataDialog; class ObjectStore; class DataTab : public DialogTab { Q_OBJECT public: DataTab(QWidget *parent); virtual ~DataTab(); virtual void setObjectStore(ObjectStore *store); DataDialog *dataDialog() const; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewitem.h000644 001750 001750 00000043451 11544160207 017462 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VIEWITEM_H #define VIEWITEM_H #include #include #include #include #include #include #include #include "namedobject.h" #include "kst_export.h" #include "viewcommand.h" #include "view.h" #include "curveplacement.h" //#include "sharedptr.h" #include "application.h" #include "tabwidget.h" namespace Kst { class DialogPage; class ViewGridLayout; class ViewItem; typedef QList ViewItemList; class ViewItem : public QObject, public NamedObject, public QGraphicsRectItem { Q_OBJECT public: enum GripMode { Move = 1, Resize = 2, Scale = 4, Rotate = 8 }; Q_DECLARE_FLAGS(GripModes, GripMode) enum ActiveGrip { NoGrip = 1, TopLeftGrip = 2, TopRightGrip = 4, BottomRightGrip = 8, BottomLeftGrip = 16, TopMidGrip = 32, RightMidGrip = 64, BottomMidGrip = 128, LeftMidGrip = 256 }; Q_DECLARE_FLAGS(ActiveGrips, ActiveGrip) enum CreationState { None, InProgress, Completed }; ViewItem(View *parent); virtual ~ViewItem(); virtual void save(QXmlStreamWriter &xml); bool parse(QXmlStreamReader &xml, bool &validChildTag); enum { Type = UserType + 1 }; int type() const { return Type; } void setTypeName(const QString& name) { _typeName = name; } const QString typeName() const { return _typeName; } View* view() const; void setView(View*); ViewItem *parentViewItem() const; void setParentViewItem(ViewItem *parent); virtual void updateRelativeSize(); void moveTo(const QPointF& pos); qreal relativeHeight() const { return _parentRelativeHeight; } void setRelativeHeight(const qreal height) { _parentRelativeHeight = height; } qreal relativeWidth() const { return _parentRelativeWidth; } void setRelativeWidth(const qreal width) { _parentRelativeWidth = width; } QPointF relativeCenter() const { return _parentRelativeCenter; } void setRelativeCenter(const QPointF center) { _parentRelativeCenter = center; } QPointF relativePosition() const { return _parentRelativePosition; } void setRelativePosition(const QPointF pos) { _parentRelativePosition = pos; } qreal rotationAngle() const; GripMode gripMode() const; void setGripMode(GripMode mode); GripModes allowedGripModes() const; void setAllowedGripModes(GripModes modes); bool isAllowed(GripMode mode) const; bool fixedSize() const { return _fixedSize; } void setFixedSize(bool fixedSize) { _fixedSize = fixedSize; } bool lockAspectRatio() const { return _lockAspectRatio; } void setLockAspectRatio(bool lockAspectRatio) { _lockAspectRatio = lockAspectRatio; } bool lockAspectRatioFixed() const { return _lockAspectRatioFixed; } void setLockAspectRatioFixed(bool enable) { _lockAspectRatioFixed = enable; } bool hasStaticGeometry() const { return _hasStaticGeometry; } void setHasStaticGeometry(bool hasStaticGeometry ) { _hasStaticGeometry = hasStaticGeometry; } bool lockParent() const { return _lockParent; } void setLockParent(bool lockParent ) { _lockParent = lockParent; } bool skipNextParentCheck() const { return _skipNextParentCheck; } void setSkipNextParentCheck(bool skipNextParentCheck) { _skipNextParentCheck = skipNextParentCheck; } bool allowsLayout() const { return _allowsLayout; } void setAllowsLayout(bool allowsLayout ) { _allowsLayout = allowsLayout; } bool isHighlighted() const { return _highlighted; } void setHighlighted(bool highlighted ) { _highlighted = highlighted; } //NOTE This should be used in place of QGraphicsRectItem::setRect()... QRectF viewRect() const; void setViewRect(const QRectF &viewRect, bool automaticChange = false); void setViewRect(qreal x, qreal y, qreal width, qreal height, bool automaticChange = false); qreal width() const { return viewRect().normalized().width(); } qreal height() const { return viewRect().normalized().height(); } ActiveGrip activeGrip() const; void setActiveGrip(ActiveGrip grip); ActiveGrips allowedGrips() const; void setAllowedGrips(ActiveGrips grips); bool isAllowed(ActiveGrip grip) const; virtual QSizeF sizeOfGrip() const; virtual QPainterPath grips() const; virtual QRectF selectBoundingRect() const; virtual QRectF gripBoundingRect() const; virtual QRectF boundingRect() const; virtual QPainterPath shape() const; virtual QPainterPath itemShape() const { return QGraphicsRectItem::shape(); } virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); virtual void paint(QPainter *painter); virtual QList dialogPages() const { return QList(); } virtual QPointF centerOfRotation() const { return rect().center(); } bool isHovering() const { return _hovering; } bool acceptsChildItems() const { return _acceptsChildItems; } void setAcceptsChildItems(bool acceptsChildItems) { _acceptsChildItems = acceptsChildItems; } QSizeF layoutMargins() const { return _layoutMargins; } void setLayoutMargins(const QSizeF margins) { _layoutMargins = margins; } QSizeF layoutSpacing() const { return _layoutSpacing; } void setLayoutSpacing(const QSizeF spacing) { _layoutSpacing = spacing; } //This is a workaround for context menu bug in Qt4.3 graphicsview bool acceptsContextMenuEvents() const { return _acceptsContextMenuEvents; } void setAcceptsContextMenuEvents(bool acceptsContextMenuEvents) { _acceptsContextMenuEvents = acceptsContextMenuEvents; } virtual bool tryShortcut(const QString &keySequence); virtual QPainterPath checkBox() const; virtual QPainterPath tiedZoomCheck() const; virtual QSizeF tiedZoomSize() const { return QSizeF(checkBox().controlPointRect().size() * 1.5); } virtual bool isTiedZoom() const { return (_isXTiedZoom || _isYTiedZoom); } virtual bool isXTiedZoom() const { return _isXTiedZoom; } virtual bool isYTiedZoom() const { return _isYTiedZoom; } virtual void setTiedZoom(bool tiedXZoom, bool tiedYZoom, bool checkAllTied = true); virtual bool supportsTiedZoom() const { return _supportsTiedZoom; } virtual void setSupportsTiedZoom(const bool supports); View::ZoomOnlyMode zoomOnlyMode() const { return _zoomOnlyMode; } void setZoomOnly(View::ZoomOnlyMode val) { _zoomOnlyMode = val; } CreationState creationState() const { return _creationState; } virtual void setItemPen(const QPen & pen) { setPen(pen); }; virtual void setItemBrush(const QBrush & brush) { setBrush(brush); }; template static QList getItems(); // TODO: Remove, needed only for a Qt 4.3 bug workaround bool doSceneEvent(QGraphicsSceneContextMenuEvent *event) { return sceneEvent(event); } virtual bool isMaximized(); Q_SIGNALS: void geometryChanged(); void creationComplete(); /*FIXME these should be made private for only undo commands to access*/ public Q_SLOTS: virtual void edit(); virtual void raise(); virtual void lower(); virtual void createAutoLayout(); virtual void createCustomLayout(); virtual void sharePlots(QPainter *painter, bool creation); virtual void remove(); void resizeTopLeft(const QPointF &offset); void resizeTopRight(const QPointF &offset); void resizeBottomLeft(const QPointF &offset); void resizeBottomRight(const QPointF &offset); void resizeTop(qreal offset); void resizeBottom(qreal offset); void resizeLeft(qreal offset); void resizeRight(qreal offset); void setTopLeft(const QPointF &point); void setTopRight(const QPointF &point); void setBottomLeft(const QPointF &point); void setBottomRight(const QPointF &point); void setTop(qreal y); void setBottom(qreal y); void setLeft(qreal x); void setRight(qreal x); protected: virtual QPainterPath topLeftGrip() const; virtual QPainterPath topRightGrip() const; virtual QPainterPath bottomRightGrip() const; virtual QPainterPath bottomLeftGrip() const; virtual QPainterPath topMidGrip() const; virtual QPainterPath rightMidGrip() const; virtual QPainterPath bottomMidGrip() const; virtual QPainterPath leftMidGrip() const; QTransform selectTransform() const; bool transformToRect(const QRectF &from, const QRectF &to); bool transformToRect(const QPolygonF &from, const QPolygonF &to); void rotateTowards(const QPointF &corner, const QPointF &point); QPointF lockOffset(const QPointF &offset, qreal ratio, bool oddCorner) const; virtual bool updateViewItemParent(); GripMode nextGripMode(GripMode currentMode) const; void addTitle(QMenu *menu) const; void registerShortcut(QAction *action); void reRegisterShortcut(); QString descriptionTip() const; protected Q_SLOTS: virtual void creationPolygonChanged(View::CreationEvent event); protected: virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); virtual void addToMenuForContextEvent(QMenu &menu); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); QAction *_editAction; QAction *_deleteAction; QAction *_raiseAction; QAction *_lowerAction; QAction *_autoLayoutAction; QAction *_customLayoutAction; bool _isXTiedZoom; bool _isYTiedZoom; bool _plotMaximized; private Q_SLOTS: void viewMouseModeChanged(View::MouseMode oldMode); void updateView(); protected: public: // TODO why does View need it? virtual void updateChildGeometry(const QRectF &oldParentRect, const QRectF &newParentRect); protected: virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); private: GripMode _gripMode; GripModes _allowedGripModes; CreationState _creationState; QString _typeName; View::ZoomOnlyMode _zoomOnlyMode; bool _supportsTiedZoom; bool _fixedSize; bool _lockAspectRatio; bool _lockAspectRatioFixed; bool _hasStaticGeometry; bool _lockParent; bool _skipNextParentCheck; bool _allowsLayout; bool _hovering; bool _acceptsChildItems; bool _acceptsContextMenuEvents; bool _updatingLayout; bool _highlighted; QPointF _originalPosition; QPointF _parentRelativeCenter; QPointF _parentRelativePosition; QRectF _originalRect; QTransform _originalTransform; QLineF _normalLine; QLineF _rotationLine; ActiveGrip _activeGrip; ActiveGrips _allowedGrips; QTransform _rotationTransform; QHash _shortcutMap; qreal _parentRelativeHeight, _parentRelativeWidth; QSizeF _layoutMargins, _layoutSpacing; // use view() / setView(View*) QObject* parent() const; void setParent(QObject*); // use setParentViewItem(ViewItem*) void setParentItem(QGraphicsItem*); QPointF dragStartPosition; void startDragging(QWidget *widget, const QPointF& hotspot); }; Q_DECLARE_OPERATORS_FOR_FLAGS(ViewItem::GripModes) Q_DECLARE_OPERATORS_FOR_FLAGS(ViewItem::ActiveGrips) #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug, ViewItem*); #endif class ViewItemCommand : public QUndoCommand { public: ViewItemCommand(ViewItem *item, const QString &text, bool addToStack = true, QUndoCommand *parent = 0); virtual ~ViewItemCommand(); protected: QPointer _item; }; class CreateCommand : public QObject, public ViewCommand { Q_OBJECT public: explicit CreateCommand(const QString &text, QUndoCommand *parent = 0); CreateCommand(View *view, const QString &text, QUndoCommand *parent = 0); virtual ~CreateCommand(); virtual void undo(); virtual void redo(); virtual void createItem(); ViewItem *item() const { return _item; } public Q_SLOTS: virtual void creationComplete(); protected: QPointer _item; }; class LayoutCommand : public ViewItemCommand { public: LayoutCommand(ViewItem *item) : ViewItemCommand(item, QObject::tr("Create layout"), false) {} virtual ~LayoutCommand() {} virtual void undo(); virtual void redo(); void createLayout(int columns = 0); private: QPointer _layout; }; class AppendLayoutCommand : public ViewItemCommand { public: AppendLayoutCommand(ViewItem *item) : ViewItemCommand(item, QObject::tr("Append Item to Layout"), false) {} virtual ~AppendLayoutCommand() {} virtual void undo(); virtual void redo(); void appendLayout(CurvePlacement::Layout layout, ViewItem* item, int columns = 0); private: QPointer _layout; }; class MoveCommand : public ViewItemCommand { public: MoveCommand(ViewItem *item, const QPointF &originalPos, const QPointF &newPos) : ViewItemCommand(item, QObject::tr("Move")), _originalPos(originalPos), _newPos(newPos) {} virtual ~MoveCommand() {} virtual void undo(); virtual void redo(); private: QPointF _originalPos; QPointF _newPos; }; class ResizeCommand : public ViewItemCommand { public: ResizeCommand(ViewItem *item, const QRectF &originalRect, const QRectF &newRect) : ViewItemCommand(item, QObject::tr("Resize")), _originalRect(originalRect), _newRect(newRect) {} virtual ~ResizeCommand() {} virtual void undo(); virtual void redo(); private: QRectF _originalRect; QRectF _newRect; }; class RemoveCommand : public ViewItemCommand { public: RemoveCommand(ViewItem *item) : ViewItemCommand(item, QObject::tr("Remove")) {} virtual ~RemoveCommand() {} virtual void undo(); virtual void redo(); }; class RaiseCommand : public ViewItemCommand { public: RaiseCommand(ViewItem *item) : ViewItemCommand(item, QObject::tr("Raise")) {} virtual ~RaiseCommand() {} virtual void undo(); virtual void redo(); }; class LowerCommand : public ViewItemCommand { public: LowerCommand(ViewItem *item) : ViewItemCommand(item, QObject::tr("Lower")) {} virtual ~LowerCommand() {} virtual void undo(); virtual void redo(); }; class TransformCommand : public ViewItemCommand { public: TransformCommand(ViewItem *item, const QTransform &originalTransform, const QTransform &newTransform, const QString &text) : ViewItemCommand(item, text), _originalTransform(originalTransform), _newTransform(newTransform) {} virtual ~TransformCommand() {} virtual void undo(); virtual void redo(); private: QTransform _originalTransform; QTransform _newTransform; }; class ScaleCommand : public TransformCommand { public: ScaleCommand(ViewItem *item, const QTransform &originalTransform, const QTransform &newTransform) : TransformCommand(item, originalTransform, newTransform, QObject::tr("Scale")) {} virtual ~ScaleCommand() {} }; class RotateCommand : public TransformCommand { public: RotateCommand(ViewItem *item, const QTransform &originalTransform, const QTransform &newTransform) : TransformCommand(item, originalTransform, newTransform, QObject::tr("Rotate")) {} virtual ~RotateCommand() {} }; // FIXME: This returns a list of ungaurded pointers; if the object is deleted // between when the list is aquired and when one of the pointers is de-referenced, // there will be a crash. They are unguarded, because they are normally held by the // scene as unguarded pointers, so it is too late to add a guard. // I can't see a way of fixing it easily. The best option // for now is to minimize the cross section of this: use the pointers // immediately after getting them, and don't hold them waiting for the // user to delete the object they refer to... The user might still be able to arrange // a crash, however. template QList ViewItem::getItems() { QList tItems; ViewItem *viewItem; T* tItem; QList views = kstApp->mainWindow()->tabWidget()->views(); for (int i_view = 0; i_view items = views.at(i_view)->scene()->items(); for (int i_item = 0; i_item(items[i_item]); tItem = dynamic_cast(viewItem); if (tItem) { tItems.append(tItem); } } } return tItems; } class MimeDataViewItem : public QMimeData { Q_OBJECT public: MimeDataViewItem(); ViewItem* item; QPointF hotSpot; static const MimeDataViewItem* downcast(const QMimeData*); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/memorywidget.cpp000644 001750 001750 00000002651 11544160207 020675 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #include "memorywidget.h" #include #include namespace Kst { MemoryWidget::MemoryWidget(QWidget *parent, int updateMilliSeconds) : QLabel(parent) { connect(&_timer, SIGNAL(timeout()), this, SLOT(updateFreeMemory())); _timer.start(updateMilliSeconds); updateFreeMemory(); } MemoryWidget::~MemoryWidget() { } void MemoryWidget::updateFreeMemory() { #ifdef __linux__ meminfo(); unsigned long mi = S(kb_main_free + kb_main_buffers + kb_main_cached); setText(tr("%1 MB available").arg(mi / (1024 * 1024))); #endif } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotrenderitem.cpp000644 001750 001750 00000072752 11544160207 021227 0ustar00synthsynth000000 000000 /********************************************************************************* * * * copyright : (C) 2007 Theodore Kisner * * copyright : (C) 2000-2010 Barth Netterfield * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ********************************************************************************/ #include "plotrenderitem.h" #include "plotitem.h" #include "plotitemmanager.h" #include "application.h" #include "objectstore.h" #include "updatemanager.h" #include "sharedaxisboxitem.h" #include "application.h" #include "image.h" #include "debug.h" #include #include #include #include #include #include #include // #define CURVE_DRAWING_TIME namespace Kst { PlotRenderItem::PlotRenderItem(PlotItem *parentItem) : ViewItem(parentItem->view()), _referencePointMode(false), _highlightPointActive(false), _invertHighlight(false) { setTypeName(tr("Plot Render")); setParentViewItem(parentItem); setHasStaticGeometry(true); setAllowedGripModes(0); setAllowedGrips(0); connect(parentItem, SIGNAL(geometryChanged()), this, SLOT(updateGeometry())); connect(parentItem, SIGNAL(updatePlotRect()), this, SLOT(updateGeometry())); connect(parentItem->view(), SIGNAL(viewModeChanged(View::ViewMode)), this, SLOT(updateViewMode())); updateGeometry(); //the initial rect updateViewMode(); //the initial view _referenceMode = new QAction(tr("Reference Mode"), this); _referenceMode->setShortcut(Qt::Key_C); registerShortcut(_referenceMode); connect(_referenceMode, SIGNAL(triggered()), this, SLOT(referenceMode())); _referenceModeDisabled = new QAction(tr("Reference Mode"), this); _referenceModeDisabled->setShortcut(Qt::SHIFT + Qt::Key_C); registerShortcut(_referenceModeDisabled); connect(_referenceModeDisabled, SIGNAL(triggered()), this, SLOT(referenceModeDisabled())); disconnect(this, SIGNAL(geometryChanged()), view(), SLOT(viewChanged())); } PlotRenderItem::~PlotRenderItem() { } PlotItem *PlotRenderItem::plotItem() const { return static_cast(parentItem()); } void PlotRenderItem::referenceMode() { _referencePointMode = true; if (_highlightPointActive) { _referencePoint = _highlightPoint; } else { _referencePoint = plotItem()->mapToProjection(_lastPos); } update(); } void PlotRenderItem::referenceModeDisabled() { _referencePointMode = false; } void PlotRenderItem::setReferencePoint(const QPointF& point) { _referencePointMode = true; _referencePoint = point; } PlotRenderItem::RenderType PlotRenderItem::type() { return _type; } void PlotRenderItem::setType(PlotRenderItem::RenderType type) { _type = type; } QRectF PlotRenderItem::plotRect() const { QRectF plotRect = rect(); plotRect = plotRect.normalized(); plotRect.moveTopLeft(QPointF(0.0, 0.0)); return plotRect; } QRectF PlotRenderItem::projectionRect() const { return plotItem()->projectionRect(); } RelationList PlotRenderItem::relationList() const { return _relationList; } void PlotRenderItem::addRelation(RelationPtr relation) { if (relation) { _relationList.append(relation); if (_relationList.count() == 1) { plotItem()->zoomMaximum(); plotItem()->xAxis()->setAxisReversed(relation->invertXHint()); plotItem()->yAxis()->setAxisReversed(relation->invertYHint()); } } } void PlotRenderItem::removeRelation(RelationPtr relation) { if (relation) { _relationList.removeAll(relation); plotItem()->registerChange(); UpdateManager::self()->doUpdates(true); } } void PlotRenderItem::clearRelations() { _relationList.clear(); plotItem()->zoomMaximum(); } void PlotRenderItem::save(QXmlStreamWriter &xml) { Q_UNUSED(xml); } void PlotRenderItem::saveInPlot(QXmlStreamWriter &xml) { xml.writeAttribute("name", typeName()); xml.writeAttribute("type", QVariant(_type).toString()); if (_referencePointMode) { xml.writeStartElement("referencepoint"); xml.writeAttribute("x", QVariant(_referencePoint.x()).toString()); xml.writeAttribute("y", QVariant(_referencePoint.y()).toString()); xml.writeEndElement(); } foreach (RelationPtr relation, relationList()) { xml.writeStartElement("relation"); xml.writeAttribute("tag", relation->Name()); xml.writeEndElement(); } QList list = QGraphicsItem::children(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem) continue; viewItem->save(xml); } } bool PlotRenderItem::configureFromXml(QXmlStreamReader &xml, ObjectStore *store) { bool validTag = true; QString primaryTag = xml.name().toString(); QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; av = attrs.value("type"); if (!av.isNull()) { setType((RenderType)av.toString().toInt()); } QString expectedEnd; while (!(xml.isEndElement() && (xml.name().toString() == primaryTag))) { if (xml.isStartElement() && xml.name().toString() == "relation") { expectedEnd = xml.name().toString(); attrs = xml.attributes(); QString tagName = attrs.value("tag").toString(); RelationPtr relation = kst_cast(store->retrieveObject(tagName)); if (relation) { addRelation(relation); } } else if (xml.isStartElement() && xml.name().toString() == "referencepoint") { expectedEnd = xml.name().toString(); double x = 0, y = 0; attrs = xml.attributes(); av = attrs.value("x"); if (!av.isNull()) { x = av.toString().toDouble(); } av = attrs.value("y"); if (!av.isNull()) { y = av.toString().toDouble(); } setReferencePoint(QPointF(x, y)); } else if (xml.isStartElement()) { if (!parse(xml, validTag) && validTag) { GraphicsFactory::parse(xml, store, view(), this); } } else if (xml.isEndElement()) { if (xml.name().toString() != expectedEnd) { validTag = false; break; } } xml.readNext(); } return validTag; } void PlotRenderItem::addToMenuForContextEvent(QMenu &menu) { plotItem()->addToMenuForContextEvent(menu); } void PlotRenderItem::paint(QPainter *painter) { if (!rect().isValid()) { return; } if (plotItem()->maskedByMaximization()) { return; } painter->setRenderHint(QPainter::Antialiasing, false); #ifdef CURVE_DRAWING_TIME QTime time; time.start(); #endif painter->save(); if (plotItem()->xAxis()->axisReversed()) { painter->scale(-1, 1); painter->translate(-1.0 * rect().right() - rect().left(), 0); } if (plotItem()->yAxis()->axisReversed()) { painter->scale(1, -1); painter->translate(0, -1.0 * rect().bottom() - rect().top()); } painter->setClipRect(rect()); paintRelations(painter); painter->restore(); if (!view()->isPrinting()) { processHoverMoveEvent(_hoverPos); } paintReferencePoint(painter); paintHighlightPoint(painter); if (!view()->isPrinting()) { if (_selectionRect.isValid()) { painter->setPen(QPen(QBrush(Qt::black), 1.0, Qt::DotLine)); painter->drawRect(_selectionRect.rect()); } } #ifdef CURVE_DRAWING_TIME int elapsed = time.elapsed(); qDebug()<<"curve drawing took" << elapsed << "to render."; #endif } void PlotRenderItem::paintReferencePoint(QPainter *painter) { if (_referencePointMode && plotItem()->projectionRect().contains(_referencePoint)) { QPointF point = plotItem()->mapToPlot(_referencePoint); painter->save(); painter->setPen(QPen(QColor("gray"), 1)); CurvePointSymbol::draw(7, painter, point.x(), point.y(), 1); painter->restore(); } } void PlotRenderItem::paintHighlightPoint(QPainter *painter) { if (_highlightPointActive && kstApp->mainWindow()->isHighlightPoint() && plotItem()->projectionRect().contains(_highlightPoint)) { QPointF point = plotItem()->mapToPlot(_highlightPoint); painter->save(); painter->setPen(QPen(QColor("gray"), 1)); painter->setBrush(Qt::SolidPattern); QColor highlightColor(QColor(0, 0, 0, 127)); if (_invertHighlight) { highlightColor = QColor(255, 255, 255, 127); } painter->setBrush(highlightColor); painter->drawEllipse(point.x()-3, point.y()-3, 7, 7); painter->restore(); } } QString PlotRenderItem::multiRenderItemLabel(bool isX) const { QString units; QString quantity; LabelInfo label_info; LabelInfo first_label_info; units.clear(); quantity.clear(); bool nameSame = true; bool unitsSame = true; bool quantitySame = true; int count; count = relationList().size(); if (isX) { first_label_info = relationList().at(0)->xLabelInfo(); } else { first_label_info = relationList().at(0)->yLabelInfo(); } for (int i=1; ixLabelInfo(); } else { label_info = relationList().at(i)->yLabelInfo(); } if (label_info.name != first_label_info.name) { nameSame = false; } if (!label_info.units.isEmpty()) { if (units.isEmpty()) { units = label_info.units; } else { if (label_info.units != units) { unitsSame = false; } } } if (!label_info.quantity.isEmpty()) { if (quantity.isEmpty()) { quantity = label_info.quantity; } else { if (label_info.quantity != quantity) { quantitySame = false; } } } } if (nameSame && unitsSame && quantitySame) { return label_info.singleRenderItemLabel(); } if (!quantitySame) { quantity.clear(); } if (!unitsSame) { units.clear(); } if (!units.isEmpty() && !quantity.isEmpty()) { return QString("%1 \\[%2\\]").arg(quantity).arg(units); } else if (!units.isEmpty()) { return units; } else { return quantity; } } QString PlotRenderItem::leftLabel() const { if (relationList().size() == 1) { return relationList().at(0)->yLabelInfo().singleRenderItemLabel(); } else { // multiple curves: quantity [units] return multiRenderItemLabel(false); } } QString PlotRenderItem::bottomLabel() const { if (relationList().size() == 1) { return relationList().at(0)->xLabelInfo().singleRenderItemLabel(); } else { // multiple curves: quantity [units] return multiRenderItemLabel(true); } } QString PlotRenderItem::rightLabel() const { // right labels should only be used where there is more than one // projection in the plot... return QString(); } QString PlotRenderItem::topLabel() const { if (relationList().size() == 1) { LabelInfo label_info = relationList().at(0)->titleInfo(); QString label = label_info.singleRenderItemLabel(); if (label.isEmpty()) { label_info = relationList().at(0)->yLabelInfo(); if (label_info.singleRenderItemLabel().isEmpty()) { label = relationList().at(0)->descriptiveName(); } else if ((!label_info.name.isEmpty()) && (!label_info.quantity.isEmpty())) { LabelInfo xlabel_info = relationList().at(0)->xLabelInfo(); if ((!xlabel_info.name.isEmpty()) && (!xlabel_info.quantity.isEmpty())) { label = i18n("%1 vs %2").arg(label_info.name).arg(xlabel_info.name); } else { label = label_info.name; } } } return label; } else { return QString(); } } void PlotRenderItem::keyPressEvent(QKeyEvent *event) { if (view()->viewMode() != View::Data) { event->ignore(); return; } const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (modifiers & Qt::SHIFT) { // show cursor as Qt::SizeVerCursor only on mouse events // because shift is also used for arrow key controlled zooming } else if (modifiers & Qt::CTRL) { view()->setCursor(Qt::SizeHorCursor); } ViewItem::keyPressEvent(event); updateSelectionRect(); } void PlotRenderItem::keyReleaseEvent(QKeyEvent *event) { if (view()->viewMode() != View::Data) { event->ignore(); return; } const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (modifiers & Qt::SHIFT || zoomOnlyMode() == View::ZoomOnlyY) { view()->setCursor(Qt::SizeVerCursor); } else if (modifiers & Qt::CTRL || zoomOnlyMode() == View::ZoomOnlyX) { view()->setCursor(Qt::SizeHorCursor); } else { view()->setCursor(Qt::CrossCursor); resetSelectionRect(); } ViewItem::keyReleaseEvent(event); } void PlotRenderItem::resetSelectionRect() { if (_selectionRect.isValid()) { _selectionRect.reset(); updateCursor(_lastPos); update(); } } void PlotRenderItem::updateSelectionRect() { if (_selectionRect.isValid()) { update(); //FIXME should optimize instead of redrawing entire curve? } } void PlotRenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (view()->viewMode() != View::Data) { event->ignore(); return; } const QPointF p = event->pos(); const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (modifiers & Qt::SHIFT || zoomOnlyMode() == View::ZoomOnlyY) { view()->setCursor(Qt::SizeVerCursor); _selectionRect.setTo(QPointF(rect().right(), p.y())); } else if (modifiers & Qt::CTRL || zoomOnlyMode() == View::ZoomOnlyX) { _selectionRect.setTo(QPointF(p.x(), rect().bottom())); } else { _selectionRect.setTo(p); } updateSelectionRect(); } void PlotRenderItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { const QPointF point = plotItem()->mapToProjection(event->pos()); qreal range = qMax(plotItem()->xMax() - plotItem()->xMin(), plotItem()->yMax() - plotItem()->yMin()); double distance = 1000; bool first = true; RelationPtr closestRelation = 0; foreach (RelationPtr relation, _relationList) { double relationsDistance = relation->distanceToPoint(point.x(), range, point.y()); if (first) { distance = relationsDistance; closestRelation = relation; first = false; } else { if (distance > relationsDistance) { distance = relationsDistance; closestRelation = relation; } } } if (closestRelation) { closestRelation->showEditDialog(); } } void PlotRenderItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (view()->viewMode() != View::Data) { event->ignore(); return; } if (event->button() == Qt::MidButton) { plotItem()->zoomPrevious(); event->ignore(); } const QPointF p = event->pos(); const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (modifiers & Qt::SHIFT || zoomOnlyMode() == View::ZoomOnlyY) { view()->setCursor(Qt::SizeVerCursor); _selectionRect.setFrom(QPointF(rect().left(), p.y())); _selectionRect.setTo(QPointF(rect().right(), p.y())); } else if (modifiers & Qt::CTRL || zoomOnlyMode() == View::ZoomOnlyX) { view()->setCursor(Qt::SizeHorCursor); _selectionRect.setFrom(QPointF(p.x(), rect().top())); _selectionRect.setTo(QPointF(p.x(), rect().bottom())); } else { _selectionRect.setFrom(p); } } void PlotRenderItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { if (view()->viewMode() != View::Data) { event->ignore(); return; } updateCursor(event->pos()); const QRectF projection = plotItem()->mapToProjection(_selectionRect.rect()); _selectionRect.reset(); const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (modifiers & Qt::SHIFT || zoomOnlyMode() == View::ZoomOnlyY) { plotItem()->zoomYRange(projection); } else if (modifiers & Qt::CTRL || zoomOnlyMode() == View::ZoomOnlyX) { plotItem()->zoomXRange(projection); } else { plotItem()->zoomFixedExpression(projection); } } //FIXME: store event or pos, and re-call this when window is redrawn void PlotRenderItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { ViewItem::hoverMoveEvent(event); if (view()->viewMode() != View::Data) { event->ignore(); return; } QPointF p = event->pos(); _hoverPos = p; const Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); if (modifiers & Qt::SHIFT || zoomOnlyMode() == View::ZoomOnlyY) { _lastPos = p; view()->setCursor(Qt::SizeVerCursor); _selectionRect.setFrom(QPointF(rect().left(), p.y())); _selectionRect.setTo(QPointF(rect().right(), p.y())); update(); //FIXME should optimize instead of redrawing entire curve! } else if (modifiers & Qt::CTRL || zoomOnlyMode() == View::ZoomOnlyX) { _lastPos = p; view()->setCursor(Qt::SizeHorCursor); _selectionRect.setFrom(QPointF(p.x(), rect().top())); _selectionRect.setTo(QPointF(p.x(), rect().bottom())); update(); //FIXME should optimize instead of redrawing entire curve! } else { resetSelectionRect(); updateCursor(p); } processHoverMoveEvent(p); if (kstApp->mainWindow()->isHighlightPoint()) { update(); } } void PlotRenderItem::processHoverMoveEvent(const QPointF &p) { if (p.isNull()) { return; } const QPointF point = plotItem()->mapToProjection(p); if (kstApp->mainWindow()->isHighlightPoint()) { highlightNearestDataPoint(point); } else { _highlightPointActive = false; QString message = QString("(%1, %2)"). arg(plotItem()->xAxis()->statusBarString(point.x())). arg(QString::number(point.y())); if (_referencePointMode) { message += QString(" [Offset: %1, %2]").arg(QString::number(point.x() - _referencePoint.x(), 'G')).arg(QString::number(point.y() - _referencePoint.y())); } kstApp->mainWindow()->setStatusMessage(message); } } void PlotRenderItem::highlightNearestDataPoint(const QPointF& position) { QString curveMsg; QString imageMsg; _highlightPointActive = false; _invertHighlight = false; if (!relationList().isEmpty()) { QString curveName, imageName; bool bFirst = true; bool bFoundImage = false; qreal distance, minDistance = 1.0E300; qreal x, y; QPointF matchedPoint; qreal imageZ; qreal dxPerPix = double(projectionRect().width())/double(rect().width()); foreach(RelationPtr relation, relationList()) { if (Curve* curve = kst_cast(relation)) { int index = curve->getIndexNearXY(position.x(), dxPerPix, position.y()); curve->point(index, x, y); distance = fabs(position.y() - y); if (bFirst || distance < minDistance) { matchedPoint = QPointF(x, y); bFirst = false; minDistance = distance; curveName = curve->CleanedName(); if (curve->color() == Qt::black) { _invertHighlight = true; } } } else if (Image* image = kst_cast(relation)) { if (!bFoundImage && image->getNearestZ(position.x(), position.y(), imageZ)) { bFoundImage = true; imageName = image->CleanedName(); } } } if (!curveName.isEmpty()) { QString message = curveName + QString(" (%1, %2)"). arg(plotItem()->xAxis()->statusBarString(matchedPoint.x())). arg(QString::number(matchedPoint.y())); if (_referencePointMode) { message += QString(" [Offset: %1, %2]"). arg(QString::number(matchedPoint.x() - _referencePoint.x(), 'G')). arg(QString::number(matchedPoint.y() - _referencePoint.y())); } kstApp->mainWindow()->setStatusMessage(message); _highlightPointActive = true; _highlightPoint = QPointF(matchedPoint.x(), matchedPoint.y()); } else if (!imageName.isEmpty()) { QString message = imageName + QString(" (%1, %2, %3)"). arg(plotItem()->xAxis()->statusBarString(position.x())). arg(QString::number(position.y())). arg(QString::number(imageZ, 'G')); kstApp->mainWindow()->setStatusMessage(message); } } } void PlotRenderItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { ViewItem::hoverEnterEvent(event); if (view()->viewMode() != View::Data) { event->ignore(); return; } setFocus(Qt::MouseFocusReason); // Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-8188 if (!hasFocus()) { QEvent activate(QEvent::WindowActivate); View* v = view(); if (v) { QApplication::sendEvent(v->scene(), &activate); setFocus(Qt::MouseFocusReason); if (!hasFocus()) { Debug::self()->log("PlotRenderItem::hoverEnterEvent: could not set focus", Debug::Warning); } } } updateCursor(event->pos()); const QPointF p = plotItem()->mapToProjection(event->pos()); QString message = QString("(%1, %2)"). arg(plotItem()->xAxis()->statusBarString(p.x())). arg(QString::number(p.y())); kstApp->mainWindow()->setStatusMessage(message); } void PlotRenderItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { ViewItem::hoverLeaveEvent(event); _hoverPos = QPointF(0,0); _highlightPointActive = false; if (view()->viewMode() != View::Data) { event->ignore(); return; } clearFocus(); resetSelectionRect(); updateCursor(event->pos()); kstApp->mainWindow()->setStatusMessage(QString()); } QPainterPath PlotRenderItem::shape() const { QPainterPath selectPath; selectPath.setFillRule(Qt::WindingFill); selectPath.addPolygon(rect()); selectPath.addPath(checkBox()); return selectPath; } bool PlotRenderItem::updateViewItemParent() { return false; //never reparent a plot renderer } void PlotRenderItem::updateGeometry() { setViewRect(plotItem()->plotRect()); } void PlotRenderItem::updateViewMode() { switch (view()->viewMode()) { case View::Data: view()->setCursor(Qt::CrossCursor); break; case View::Layout: view()->setCursor(Qt::ArrowCursor); break; default: break; } } void PlotRenderItem::edit() { plotItem()->edit(); } void PlotRenderItem::raise() { plotItem()->raise(); } void PlotRenderItem::lower() { plotItem()->lower(); } void PlotRenderItem::createAutoLayout() { plotItem()->createAutoLayout(); } void PlotRenderItem::createCustomLayout() { plotItem()->createCustomLayout(); } void PlotRenderItem::remove() { plotItem()->remove(); } void PlotRenderItem::updateCursor(const QPointF &pos) { _lastPos = pos; if (checkBox().contains(pos)) { view()->setCursor(Qt::ArrowCursor); } else { updateViewMode(); } } QRectF PlotRenderItem::computedProjectionRect() const { qreal minX, minY, maxX, maxY; //initialize to current projection rect... projectionRect().getCoords(&minX, &minY, &maxX, &maxY); computeXAxisRange(&minX, &maxX); computeYAxisRange(&minY, &maxY); return QRectF(QPointF(minX, minY), QPointF(maxX, maxY)); } void PlotRenderItem::computeXAxisRange(qreal *min, qreal *max) const { qreal minimum = *min; qreal maximum = *max; switch (plotItem()->xAxis()->axisZoomMode()) { case PlotAxis::Auto: computeAuto(Qt::Horizontal, &minimum, &maximum); break; case PlotAxis::AutoBorder: //auto mode, plus a 2.5% border on top and bottom. computeAuto(Qt::Horizontal, &minimum, &maximum); computeBorder(Qt::Horizontal, &minimum, &maximum); break; case PlotAxis::SpikeInsensitive: //auto with algorithm to detect spikes TBD computeNoSpike(Qt::Horizontal, &minimum, &maximum); break; case PlotAxis::MeanCentered: //the mean of all active curves computeMeanCentered(Qt::Horizontal, &minimum, &maximum); break; case PlotAxis::FixedExpression: // limits are set by user interaction default: break; } *min = minimum; *max = maximum; } void PlotRenderItem::computeYAxisRange(qreal *min, qreal *max) const { qreal minimum = *min; qreal maximum = *max; switch (plotItem()->yAxis()->axisZoomMode()) { case PlotAxis::Auto: computeAuto(Qt::Vertical, &minimum, &maximum); break; case PlotAxis::AutoBorder: //auto mode, plus a 2.5% border on top and bottom. computeAuto(Qt::Vertical, &minimum, &maximum); computeBorder(Qt::Vertical, &minimum, &maximum); break; case PlotAxis::SpikeInsensitive: //auto with algorithm to detect spikes TBD computeNoSpike(Qt::Vertical, &minimum, &maximum); break; case PlotAxis::MeanCentered: //the mean of all active curves computeMeanCentered(Qt::Vertical, &minimum, &maximum); break; case PlotAxis::FixedExpression: // limits are set by user interaction default: break; } *min = minimum; *max = maximum; } void PlotRenderItem::computeAuto(Qt::Orientation orientation, qreal *min, qreal *max) const { //The previous values are of no consequence as this algorithm does not depend //on the previous values. So start over so that first active relation initializes. qreal minimum=-0.1; qreal maximum= 0.1;; bool unInitialized = true; bool axisLog = orientation == Qt::Horizontal ? plotItem()->xAxis()->axisLog() : plotItem()->yAxis()->axisLog(); foreach (RelationPtr relation, relationList()) { if (relation->ignoreAutoScale()) continue; qreal minPos_ = orientation == Qt::Horizontal ? relation->minPosX() : relation->minPosY(); qreal min_ = orientation == Qt::Horizontal ? relation->minX() : relation->minY(); qreal max_ = orientation == Qt::Horizontal ? relation->maxX() : relation->maxY(); //If the axis is in log mode, the lower extent will be the //minimum value larger than zero. if (axisLog) minimum = unInitialized ? minPos_ : qMin(minPos_, minimum); else minimum = unInitialized ? min_ : qMin(min_, minimum); maximum = unInitialized ? max_ : qMax(max_, maximum); unInitialized = false; } if (axisLog) { if (unInitialized){ maximum = 100.0; minimum = 0.01; } if (minimum < 0) { minimum = 0; } if (minimum >= maximum) { if (minimum <=0) maximum = 1; else maximum = minimum * 1.1; minimum = minimum * 0.9; } } else { if (maximum <= minimum) { minimum = maximum -0.1; maximum += 0.1; } } *min = minimum; *max = maximum; } void PlotRenderItem::computeBorder(Qt::Orientation orientation, qreal *min, qreal *max) const { qreal minimum = *min; qreal maximum = *max; bool axisLog = orientation == Qt::Horizontal ? plotItem()->xAxis()->axisLog() : plotItem()->yAxis()->axisLog(); qreal logBase = 10.0/*orientation == Qt::Horizontal ? xLogBase() : yLogBase()*/; if (axisLog) { minimum = log10(minimum)/log10(logBase); maximum = maximum > 0.0 ? log10(maximum) : 0.0; qreal d = qAbs(maximum - minimum) * 0.025; maximum = pow(logBase, maximum + d); minimum = pow(logBase, minimum - d); } else { qreal d = qAbs(maximum - minimum) * 0.025; maximum += d; minimum -= d; } *min = minimum; *max = maximum; } void PlotRenderItem::computeMeanCentered(Qt::Orientation orientation, qreal *min, qreal *max) const { qreal minimum = *min; qreal maximum = *max; int count = 0; qreal mid = 0.0; foreach (RelationPtr relation, relationList()) { if (relation->ignoreAutoScale()) continue; mid += orientation == Qt::Horizontal ? relation->midX() : relation->midY(); ++count; } if (count) { mid /= qreal(count); qreal delta = maximum - minimum; minimum = mid - delta / 2.0; maximum = mid + delta / 2.0; } *min = minimum; *max = maximum; } void PlotRenderItem::computeNoSpike(Qt::Orientation orientation, qreal *min, qreal *max) const { //The previous values are of no consequence as this algorithm does not depend //on the previous values. So start over so that first active relation initializes. bool unInitialized = true; bool axisLog = orientation == Qt::Horizontal ? plotItem()->xAxis()->axisLog() : plotItem()->yAxis()->axisLog(); qreal minimum = axisLog ? 0.0 : -0.1; qreal maximum = 0.2; foreach (RelationPtr relation, relationList()) { if (relation->ignoreAutoScale()) continue; qreal minPos_ = orientation == Qt::Horizontal ? relation->minPosX() : relation->minPosY(); qreal min_ = orientation == Qt::Horizontal ? relation->ns_minX() : relation->ns_minY(); qreal max_ = orientation == Qt::Horizontal ? relation->ns_maxX() : relation->ns_maxY(); //If the axis is in log mode, the lower extent will be the //minimum value larger than zero. if (axisLog) minimum = unInitialized ? minPos_ : qMin(minPos_, minimum); else minimum = unInitialized ? min_ : qMin(min_, minimum); maximum = unInitialized ? max_ : qMax(max_, maximum); unInitialized = false; } if (maximum <= minimum) { minimum = axisLog ? 0.0 : -0.1; maximum = 0.2; } if (axisLog && minimum < 0.0) { minimum = pow(10, -350.0); } *min = minimum; *max = maximum; } bool PlotRenderItem::tryShortcut(const QString &keySequence) { if (ViewItem::tryShortcut(keySequence)) { return true; } else { return plotItem()->tryShortcut(keySequence); } } void PlotRenderItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { if (plotItem() && plotItem()->parentItem() && plotItem()->isInSharedAxisBox()) { if (plotItem()->view()->viewMode() == View::Layout) { plotItem()->sharedAxisBox()->triggerContextEvent(event); return; } } ViewItem::contextMenuEvent(event); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewgridlayout.cpp000644 001750 001750 00000071512 11544160207 021241 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "viewgridlayout.h" #include "view.h" #include "viewitem.h" #include "plotitem.h" #include "layoutboxitem.h" #include "gridlayouthelper.h" #include "sharedaxisboxitem.h" #include // 0 off, 1 On #define DEBUG_LAYOUT 0 #define DEBUG_PLOT_STANDARDIZATION 0 #define DEBUG_SHAREDAXIS 0 // What factor should be used to determine "close" plot sizes. #define PLOT_STANDARDIZATION_FACTOR .2 namespace Kst { ViewGridLayout::ViewGridLayout(ViewItem *parent) : QObject(parent), _enabled(false), _rowCount(0), _columnCount(0), _shareX(false), _shareY(false) { _spacing = parent->layoutSpacing(); _margin = parent->layoutMargins(); } ViewGridLayout::~ViewGridLayout() { } ViewItem *ViewGridLayout::parentItem() const { return qobject_cast(parent()); } void ViewGridLayout::addViewItem(ViewItem *viewItem, int row, int column) { addViewItem(viewItem, row, column, 1, 1); } void ViewGridLayout::addViewItem(ViewItem *viewItem, int row, int column, int rowSpan, int columnSpan) { LayoutItem item; item.viewItem = viewItem; item.row = row; item.column = column; item.rowSpan = rowSpan; item.columnSpan = columnSpan; item.transform = viewItem->transform(); item.position = viewItem->pos(); item.rect = viewItem->rect(); //Update the row/column counts... int maxRow = row + rowSpan; int maxColumn = column + columnSpan; _rowCount = maxRow > _rowCount ? maxRow : _rowCount; _columnCount = maxColumn > _columnCount ? maxColumn : _columnCount; //FIXME these could be consolidated _items.append(item); _itemInfos.insert(viewItem, item); _itemLayouts.insert(qMakePair(item.row, item.column), item); } int ViewGridLayout::rowCount() const { return _rowCount; } int ViewGridLayout::columnCount() const { return _columnCount; } qreal ViewGridLayout::plotLabelMarginWidth(const PlotItem *plotItem) const { if (_itemInfos.contains(plotItem)) { LayoutItem item = _itemInfos.value(plotItem); if (_plotMarginWidth.contains(item.columnSpan)) return _plotMarginWidth.value(item.columnSpan).labelMargin; } return 0.0; } qreal ViewGridLayout::plotLabelMarginHeight(const PlotItem *plotItem) const { if (_itemInfos.contains(plotItem)) { LayoutItem item = _itemInfos.value(plotItem); if (_plotMarginHeight.contains(item.rowSpan)) return _plotMarginHeight.value(item.rowSpan).labelMargin; } return 0.0; } qreal ViewGridLayout::plotAxisMarginWidth(const PlotItem *plotItem) const { if (_itemInfos.contains(plotItem)) { LayoutItem item = _itemInfos.value(plotItem); if (_plotMarginWidth.contains(item.columnSpan)) return _plotMarginWidth.value(item.columnSpan).axisMargin; } return 0.0; } qreal ViewGridLayout::plotAxisMarginHeight(const PlotItem *plotItem) const { if (_itemInfos.contains(plotItem)) { LayoutItem item = _itemInfos.value(plotItem); if (_plotMarginHeight.contains(item.rowSpan)) return _plotMarginHeight.value(item.rowSpan).axisMargin; } return 0.0; } bool ViewGridLayout::isEnabled() const { return _enabled; } void ViewGridLayout::setEnabled(bool enabled) { _enabled = enabled; emit enabledChanged(_enabled); } void ViewGridLayout::reset() { foreach (LayoutItem item, _items) { item.viewItem->setTransform(item.transform); item.viewItem->setPos(item.position); item.viewItem->setViewRect(item.rect); } } void ViewGridLayout::sharePlots(ViewItem *item, QPainter *painter, bool creation) { Q_ASSERT(item); Q_ASSERT(item->view()); // Gather all children of the SharedAxisBoxItem. QList viewItems; QList list = item->QGraphicsItem::children(); if (list.isEmpty()) return; //not added to undostack foreach (QGraphicsItem *graphicsItem, list) { ViewItem *viewItem = qgraphicsitem_cast(graphicsItem); if (!viewItem || viewItem->hasStaticGeometry() || !viewItem->allowsLayout() || viewItem->parentItem() != item) continue; viewItems.append(viewItem); } if (viewItems.isEmpty()) return; //not added to undostack // Build an automatic layout to try to maintain the existing layout. Grid *grid = Grid::buildGrid(viewItems, 0); Q_ASSERT(grid); ViewGridLayout *layout = new ViewGridLayout(item); foreach (ViewItem *v, viewItems) { int r = 0, c = 0, rs = 0, cs = 0; if (grid->locateWidget(v, r, c, rs, cs)) { layout->addViewItem(v, r, c, rs, cs); } else { grid->appendItem(v); if (grid->locateWidget(v, r, c, rs, cs)) { layout->addViewItem(v, r, c, rs, cs); } else { qDebug() << "ooops, viewItem does not fit in layout" << endl; } } } layout->apply(); layout->apply(); // Using the automatic layout as a basis, build a custom grid with the same column count, // this will remove all spans, making each plot the same size. When this is built, the // sharedAxis layout will be applied. int columnCount = layout->columnCount(); grid = Grid::buildGrid(viewItems, columnCount); Q_ASSERT(grid); layout = new ViewGridLayout(item); foreach (ViewItem *v, viewItems) { int r = 0, c = 0, rs = 0, cs = 0; if (grid->locateWidget(v, r, c, rs, cs)) { layout->addViewItem(v, r, c, rs, cs); } else { grid->appendItem(v); if (grid->locateWidget(v, r, c, rs, cs)) { layout->addViewItem(v, r, c, rs, cs); } else { qDebug() << "ooops, viewItem does not fit in layout" << endl; } } } layout->shareAxis(painter, creation); } void ViewGridLayout::standardizePlotMargins(ViewItem *item, QPainter *painter) { QList plotItems; if (item->view()) { QList list = item->view()->items(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem || !viewItem->isVisible()) continue; if (PlotItem *plotItem = qobject_cast(viewItem)) { plotItems.append(plotItem); } } } #if DEBUG_PLOT_STANDARDIZATION qDebug() << "Ready to standarize" << plotItems.count() << "plots"; #endif QMap leftMarginWidths; QMap rightMarginWidths; QMap topMarginWidths; QMap bottomMarginHeights; foreach (PlotItem* plotItem, plotItems) { plotItem->calculateBorders(painter); if (leftMarginWidths[floor(plotItem->width()*PLOT_STANDARDIZATION_FACTOR)] < plotItem->leftMarginSize()) { leftMarginWidths[floor(plotItem->width()*PLOT_STANDARDIZATION_FACTOR)] = plotItem->leftMarginSize(); } if (rightMarginWidths[floor(plotItem->width()*PLOT_STANDARDIZATION_FACTOR)] < plotItem->rightMarginSize()) { rightMarginWidths[floor(plotItem->width()*PLOT_STANDARDIZATION_FACTOR)] = plotItem->rightMarginSize(); } if (topMarginWidths[floor(plotItem->height()*PLOT_STANDARDIZATION_FACTOR)] < plotItem->topMarginSize()) { topMarginWidths[floor(plotItem->height()*PLOT_STANDARDIZATION_FACTOR)] = plotItem->topMarginSize(); } if (bottomMarginHeights[floor(plotItem->height()*PLOT_STANDARDIZATION_FACTOR)] < plotItem->bottomMarginSize()) { bottomMarginHeights[floor(plotItem->height()*PLOT_STANDARDIZATION_FACTOR)] = plotItem->bottomMarginSize(); } } #if DEBUG_PLOT_STANDARDIZATION qDebug() << "Maximum left margin widths" << leftMarginWidths; qDebug() << "Maximum right margin widths" << rightMarginWidths; qDebug() << "Maximum top margin widths" << topMarginWidths; qDebug() << "Maximum bottom margin heights" << bottomMarginHeights; #endif foreach (PlotItem* plotItem, plotItems) { #if DEBUG_PLOT_STANDARDIZATION qDebug() << "Margin left width is " << plotItem->leftMarginSize() << "setting to" << leftMarginWidths[floor(plotItem->width()*PLOT_STANDARDIZATION_FACTOR)] - plotItem->leftMarginSize(); qDebug() << "Margin right width is " << plotItem->rightMarginSize() << "setting to" << rightMarginWidths[floor(plotItem->width()*PLOT_STANDARDIZATION_FACTOR)] - plotItem->rightMarginSize(); qDebug() << "Margin top width is " << plotItem->topMarginSize() << "setting to" << topMarginWidths[floor(plotItem->height()*PLOT_STANDARDIZATION_FACTOR)] - plotItem->topMarginSize(); qDebug() << "Margin bottom height is " << plotItem->bottomMarginSize() << "setting to" << bottomMarginHeights[floor(plotItem->height()*PLOT_STANDARDIZATION_FACTOR)] - plotItem->bottomMarginSize(); #endif qreal leftPadding = leftMarginWidths[floor(plotItem->width()*PLOT_STANDARDIZATION_FACTOR)] - plotItem->leftMarginSize(); qreal rightPadding = rightMarginWidths[floor(plotItem->width()*PLOT_STANDARDIZATION_FACTOR)] - plotItem->rightMarginSize(); qreal topPadding = topMarginWidths[floor(plotItem->height()*PLOT_STANDARDIZATION_FACTOR)] - plotItem->topMarginSize(); qreal bottomPadding = bottomMarginHeights[floor(plotItem->height()*PLOT_STANDARDIZATION_FACTOR)] - plotItem->bottomMarginSize(); plotItem->setPadding(leftPadding, rightPadding, topPadding, bottomPadding); } } void ViewGridLayout::apply() { updatePlotMargins(); //For now we divide up equally... can do stretch factors and such later... QSizeF layoutSize(parentItem()->width() - _margin.width() * 2, parentItem()->height() - _margin.height() * 2); QPointF layoutTopLeft = parentItem()->rect().topLeft(); layoutTopLeft += QPointF(_margin.width(), _margin.height()); QRectF layoutRect(layoutTopLeft, layoutSize); qreal itemWidth = layoutSize.width() / columnCount(); qreal itemHeight = layoutSize.height() / rowCount(); #if DEBUG_LAYOUT qDebug() << "layouting" << _items.count() << "itemWidth:" << itemWidth << "itemHeight:" << itemHeight << endl; #endif PlotItem *plot = 0; foreach (LayoutItem item, _items) { QPointF topLeft(itemWidth * item.column, itemHeight * item.row); QSizeF size(itemWidth * item.columnSpan, itemHeight * item.rowSpan); topLeft += layoutTopLeft; QRectF itemRect(topLeft, size); if (itemRect.top() != layoutRect.top()) itemRect.setTop(itemRect.top() + _spacing.height() / 2); if (itemRect.left() != layoutRect.left()) itemRect.setLeft(itemRect.left() + _spacing.width() / 2); if (itemRect.bottom() != layoutRect.bottom()) itemRect.setBottom(itemRect.bottom() - _spacing.height() / 2); if (itemRect.right() != layoutRect.right()) itemRect.setRight(itemRect.right() - _spacing.width() / 2); item.viewItem->resetTransform(); item.viewItem->setPos(itemRect.topLeft()); if (item.viewItem->fixedSize()) { itemRect.setBottom(itemRect.top() + item.viewItem->rect().height()); itemRect.setRight(itemRect.left() + item.viewItem->rect().width()); } else if (item.viewItem->lockAspectRatio()) { qreal newHeight = itemRect.height(); qreal newWidth = itemRect.width(); qreal aspectRatio = item.viewItem->rect().width() / item.viewItem->rect().height(); if ((newWidth / newHeight) > aspectRatio) { // newWidth is too large. Use newHeight as key. newWidth = newHeight * aspectRatio; } else { // newHeight is either too large, or perfect. use newWidth as key. newHeight = newWidth / aspectRatio; } itemRect.setBottom(itemRect.top() + newHeight); itemRect.setRight(itemRect.left() + newWidth); } item.viewItem->setViewRect(QRectF(QPoint(0,0), itemRect.size())); if (PlotItem *plotItem = qobject_cast(item.viewItem)) { plot = plotItem; emit plotItem->updatePlotRect(); } #if DEBUG_LAYOUT qDebug() << "layout" << "row:" << item.row << "column:" << item.column << "rowSpan:" << item.rowSpan << "columnSpan:" << item.columnSpan << "itemRect:" << itemRect << endl; #endif } if (plot) { plot->setPlotBordersDirty(true); } } void ViewGridLayout::shareAxis(QPainter *painter, bool creation) { SharedAxisBoxItem *shareBox = qobject_cast(parentItem()); if (!shareBox) { return; } if (creation) { calculateSharing(); updateSharedAxis(); shareBox->setXAxisShared(_shareX); shareBox->setYAxisShared(_shareY); } else { _shareX = shareBox->isXAxisShared(); _shareY = shareBox->isYAxisShared(); unshareAxis(); updateSharedAxis(); } // Determine area of layout. Minimal spacing on SharedAxisBoxItems. QSizeF layoutSize(parentItem()->width() - 1, parentItem()->height() - 1); QPointF layoutTopLeft = parentItem()->rect().topLeft(); layoutTopLeft += QPointF(0, 1); QRectF layoutRect(layoutTopLeft, layoutSize); QMap leftLabelBounds; QMap rightLabelBounds; QMap topLabelBounds; QMap bottomLabelBounds; #if DEBUG_SHAREDAXIS qDebug() << "Creating Shared Axis Layout in rect " << layoutRect << "rowCount" << rowCount() << "columnCount" << columnCount(); #endif foreach (LayoutItem item, _items) { if (PlotItem *plotItem = qobject_cast(item.viewItem)) { plotItem->calculateBorders(painter); if (plotItem->leftMarginSize() > leftLabelBounds[item.column]) { leftLabelBounds[item.column] = plotItem->leftMarginSize(); } if (plotItem->rightMarginSize() > rightLabelBounds[item.column]) { rightLabelBounds[item.column] = plotItem->rightMarginSize(); } if (plotItem->topMarginSize() > topLabelBounds[item.row]) { topLabelBounds[item.row] = plotItem->topMarginSize(); } if (plotItem->bottomMarginSize() > bottomLabelBounds[item.row]) { bottomLabelBounds[item.row] = plotItem->bottomMarginSize(); } } } // Adjust to make sure there is sufficient room for the tiedzoom box. if (topLabelBounds[0] < parentItem()->tiedZoomSize().height()) { topLabelBounds[0] = parentItem()->tiedZoomSize().height(); } if (rightLabelBounds[columnCount()] < parentItem()->tiedZoomSize().width()) { rightLabelBounds[columnCount()] = parentItem()->tiedZoomSize().width(); } #if DEBUG_SHAREDAXIS qDebug() << "Calculated maximum bounds for labels."; qDebug() << "Left bounds by column" << leftLabelBounds; qDebug() << "Right bounds by column" << rightLabelBounds; qDebug() << "Top bounds by row" << topLabelBounds; qDebug() << "Bottom bounds by row" << bottomLabelBounds; #endif bool blockMode = false; bool rowMode = false; bool colMode = false; #if DEBUG_SHAREDAXIS qDebug() << "Calculated sharing modes" << "sharing X = " << _shareX << "sharing Y = " << _shareY; #endif if (_shareX && _shareY) { #if DEBUG_SHAREDAXIS qDebug() << "Sharing X & Y, one block, all projectionRect's inside frame"; #endif blockMode = true; } else if (_shareX) { if (columnCount() == 1) { #if DEBUG_SHAREDAXIS qDebug() << "Sharing only X, one column, use block logic"; #endif blockMode = true; } else { #if DEBUG_SHAREDAXIS qDebug() << "Sharing only X, multiple columns, use block for each column, columns divide space equally - number of columns" << columnCount(); #endif colMode = true; } } else if (_shareY) { if (rowCount() == 1) { #if DEBUG_SHAREDAXIS qDebug() << "Sharing only Y, one row, use block logic"; #endif blockMode = true; } else { #if DEBUG_SHAREDAXIS qDebug() << "Sharing only Y, multiple rows, use block for each row, rows divide space equally - number of rows" << rowCount(); #endif rowMode = true; } } int totalProjWidth; int totalProjHeight; if (blockMode) { totalProjWidth = (layoutRect.width() - leftLabelBounds[0]) - rightLabelBounds[columnCount() - 1]; totalProjHeight = (layoutRect.height() - topLabelBounds[0]) - bottomLabelBounds[rowCount() - 1]; } else if (rowMode) { int totalHeight = 0; for (int i = 0; i < rowCount(); i++) { totalHeight += topLabelBounds[i] + bottomLabelBounds[i]; } totalProjWidth = layoutRect.width() - leftLabelBounds[0] - rightLabelBounds[columnCount() - 1]; totalProjHeight = layoutRect.height() - totalHeight; } else if (colMode) { int totalWidth = 0; for (int i = 0; i < columnCount(); i++) { totalWidth += leftLabelBounds[i] + rightLabelBounds[i]; } totalProjWidth = layoutRect.width() - totalWidth; totalProjHeight = layoutRect.height() - topLabelBounds[0] - bottomLabelBounds[rowCount() - 1]; } else { return; } int columnProjWidth = totalProjWidth / (columnCount()); int rowProjHeight = totalProjHeight / (rowCount()); QMap > cellHeights; QMap > cellWidths; foreach (LayoutItem item, _items) { if (PlotItem *plotItem = qobject_cast(item.viewItem)) { int width = columnProjWidth; if (plotItem->leftLabelDetails()->isVisible()) { width += leftLabelBounds[item.column]; } if (plotItem->rightLabelDetails()->isVisible()) { width += rightLabelBounds[item.column]; } cellWidths[item.row][item.column] = width; int height = rowProjHeight; if (plotItem->topLabelDetails()->isVisible()) { height += topLabelBounds[item.row]; } if (plotItem->bottomLabelDetails()->isVisible()) { height += bottomLabelBounds[item.row]; } cellHeights[item.row][item.column] = height; } } #if DEBUG_SHAREDAXIS qDebug() << "Calculated Total projectRect values - width = " << totalProjWidth << " height = " << totalProjHeight; qDebug() << "Column Projection Width" << columnProjWidth << "Row Projection Height" << rowProjHeight; qDebug() << "Calculated cell widths (row x column)" << cellWidths; qDebug() << "Calculated cell heights (row x column)" << cellHeights; #endif foreach (LayoutItem item, _items) { int columnStart = 0; for (int i = 0; i < item.column; i++) { columnStart += cellWidths[item.row][i]; } int rowStart = 0; for (int i = 0; i < item.row; i++) { rowStart += cellHeights[i][item.column]; } QPointF itemTopLeft(columnStart, rowStart); itemTopLeft += layoutTopLeft; QSizeF itemSize(cellWidths[item.row][item.column], cellHeights[item.row][item.column]); QRectF itemRect(itemTopLeft, itemSize); if (PlotItem *plotItem = qobject_cast(item.viewItem)) { if (plotItem->leftLabelDetails()->isVisible()) { plotItem->setLeftPadding(leftLabelBounds[item.column] - plotItem->leftMarginSize()); } if (plotItem->rightLabelDetails()->isVisible()) { plotItem->setRightPadding(rightLabelBounds[item.column] - plotItem->rightMarginSize()); } if (plotItem->topLabelDetails()->isVisible()) { plotItem->setTopPadding(topLabelBounds[item.row] - plotItem->topMarginSize()); } if (plotItem->bottomLabelDetails()->isVisible()) { plotItem->setBottomPadding(bottomLabelBounds[item.row] - plotItem->bottomMarginSize()); } } item.viewItem->resetTransform(); item.viewItem->setPos(itemRect.topLeft()); item.viewItem->setViewRect(QRectF(QPoint(0,0), itemRect.size())); if (PlotItem *plotItem = qobject_cast(item.viewItem)) { emit plotItem->updatePlotRect(); } #if DEBUG_SHAREDAXIS qDebug() << "Shared Axis Plot item details:" << "row:" << item.row << "column:" << item.column << "itemRect:" << itemRect << endl; #endif } } void ViewGridLayout::updatePlotMargins() { _plotMarginWidth.clear(); _plotMarginHeight.clear(); foreach (LayoutItem item, _items) { PlotItem *plotItem = qobject_cast(item.viewItem); if (!plotItem) continue; { qreal labelMargin = plotItem->labelMarginWidth(); qreal axisMargin = plotItem->axisMarginWidth(); if (_plotMarginWidth.contains(item.columnSpan)) { labelMargin = qMax(labelMargin, _plotMarginWidth.value(item.columnSpan).labelMargin); axisMargin = qMax(axisMargin, _plotMarginWidth.value(item.columnSpan).axisMargin); } PlotMargins marginsForColumnSpan; marginsForColumnSpan.labelMargin = labelMargin; marginsForColumnSpan.axisMargin = axisMargin; _plotMarginWidth.insert(item.columnSpan, marginsForColumnSpan); } { qreal labelMargin = plotItem->labelMarginHeight(); qreal axisMargin = plotItem->axisMarginHeight(); if (_plotMarginHeight.contains(item.rowSpan)) { labelMargin = qMax(labelMargin, _plotMarginHeight.value(item.rowSpan).labelMargin); axisMargin = qMax(axisMargin, _plotMarginHeight.value(item.rowSpan).axisMargin); } PlotMargins marginsForRowSpan; marginsForRowSpan.labelMargin = labelMargin; marginsForRowSpan.axisMargin = axisMargin; _plotMarginHeight.insert(item.rowSpan, marginsForRowSpan); } } } void ViewGridLayout::unshareAxis() { foreach (LayoutItem item, _items) { PlotItem *plotItem = qobject_cast(item.viewItem); if (!plotItem) continue; plotItem->setLabelsVisible(true); plotItem->update(); } } void ViewGridLayout::updateSharedAxis() { if (!_shareX && !_shareY) { return; } foreach (LayoutItem item, _items) { PlotItem *plotItem = qobject_cast(item.viewItem); if (!plotItem) continue; //same horizontal range and same row/rowspan //same vertical range and same col/colspan if (_shareX) { shareAxisWithPlotAbove(item); shareAxisWithPlotBelow(item); } if (_shareY) { shareAxisWithPlotToLeft(item); shareAxisWithPlotToRight(item); } } } void ViewGridLayout::calculateSharing() { bool xMatch = true; bool yMatch = true; bool first = true; qreal xStart = 0.0, xStop = 0.0; qreal yStart = 0.0, yStop = 0.0; foreach (LayoutItem item, _items) { PlotItem *plotItem = qobject_cast(item.viewItem); if (!plotItem) continue; if (first) { xStart = plotItem->projectionRect().left(); xStop = plotItem->projectionRect().right(); yStart = plotItem->projectionRect().top(); yStop = plotItem->projectionRect().bottom(); first = false; } else { if (xMatch && (plotItem->projectionRect().left() != xStart || plotItem->projectionRect().right() != xStop)) { xMatch = false; } if (yMatch && (plotItem->projectionRect().top() != yStart || plotItem->projectionRect().bottom() != yStop)) { yMatch = false; } } } if (xMatch || yMatch) { _shareX = xMatch; _shareY = yMatch; } else { _shareX = true; _shareY = true; } } // static function void ViewGridLayout::updateProjections(ViewItem *item, bool forceXShare, bool forceYShare) { bool xMatch = true; bool yMatch = true; bool first = true; qreal xStart = 0.0, xStop = 0.0; qreal yStart = 0.0, yStop = 0.0; qreal xMin = 0.0, xMax = 0.0, yMin = 0.0, yMax = 0.0; QList viewItems; QList list = item->QGraphicsItem::children(); if (list.isEmpty()) return; //not added to undostack foreach (QGraphicsItem *graphicsItem, list) { ViewItem *viewItem = qgraphicsitem_cast(graphicsItem); if (!viewItem || viewItem->hasStaticGeometry() || !viewItem->allowsLayout() || viewItem->parentItem() != item) continue; PlotItem *plotItem = qobject_cast(viewItem); if (!plotItem) continue; if (first) { xStart = plotItem->projectionRect().left(); xStop = plotItem->projectionRect().right(); yStart = plotItem->projectionRect().top(); yStop = plotItem->projectionRect().bottom(); xMin = xStart; xMax = xStop; yMin = yStart; yMax = yStop; first = false; } else { if (xMatch && (plotItem->projectionRect().left() != xStart || plotItem->projectionRect().right() != xStop)) { xMatch = false; } if (yMatch && (plotItem->projectionRect().top() != yStart || plotItem->projectionRect().bottom() != yStop)) { yMatch = false; } if (xMin > plotItem->projectionRect().left()) { xMin = plotItem->projectionRect().left(); } if (xMax < plotItem->projectionRect().right()) { xMax = plotItem->projectionRect().right(); } if (yMin > plotItem->projectionRect().top()) { yMin = plotItem->projectionRect().top(); } if (yMax < plotItem->projectionRect().bottom()) { yMax = plotItem->projectionRect().bottom(); } } } xMatch = xMatch || forceXShare; yMatch = yMatch || forceYShare; if (!xMatch && !yMatch) { xMatch = true; yMatch = true; } QRectF projectionRect(QPointF(xMin, yMin), QPointF(xMax, yMax)); foreach (QGraphicsItem *graphicsItem, list) { ViewItem *viewItem = qgraphicsitem_cast(graphicsItem); if (!viewItem || viewItem->hasStaticGeometry() || !viewItem->allowsLayout() || viewItem->parentItem() != item) continue; if (PlotItem *plotItem = qobject_cast(viewItem)) { if (xMatch && yMatch) { plotItem->zoomFixedExpression(projectionRect, true); } else if (xMatch) { plotItem->zoomXRange(projectionRect, true); } else if (yMatch) { plotItem->zoomYRange(projectionRect, true); } } } } void ViewGridLayout::shareAxisWithPlotToLeft(LayoutItem item) { PlotItem *plotItem = qobject_cast(item.viewItem); QPair key = qMakePair(item.row, item.column - 1); if (!_itemLayouts.contains(key)) { plotItem->setLeftSuppressed(false); setSpacing(QSizeF(spacing().width(), spacing().height())); return; } LayoutItem left = _itemLayouts.value(key); PlotItem *leftItem = qobject_cast(left.viewItem); if (!leftItem) { plotItem->setLeftSuppressed(false); setSpacing(QSizeF(spacing().width(), spacing().height())); return; } if (item.rowSpan == left.rowSpan && item.columnSpan == left.columnSpan) { plotItem->setLeftSuppressed(true); leftItem->setRightSuppressed(true); setSpacing(QSizeF(0.0, spacing().height())); } } void ViewGridLayout::shareAxisWithPlotToRight(LayoutItem item) { PlotItem *plotItem = qobject_cast(item.viewItem); QPair key = qMakePair(item.row, item.column + 1); if (!_itemLayouts.contains(key)) { plotItem->setRightSuppressed(false); setSpacing(QSizeF(spacing().width(), spacing().height())); return; } LayoutItem right = _itemLayouts.value(key); PlotItem *rightItem = qobject_cast(right.viewItem); if (!rightItem) { plotItem->setRightSuppressed(false); setSpacing(QSizeF(spacing().width(), spacing().height())); return; } if (item.rowSpan == right.rowSpan && item.columnSpan == right.columnSpan) { plotItem->setRightSuppressed(true); rightItem->setLeftSuppressed(true); setSpacing(QSizeF(0.0, spacing().height())); } } void ViewGridLayout::shareAxisWithPlotAbove(LayoutItem item) { PlotItem *plotItem = qobject_cast(item.viewItem); QPair key = qMakePair(item.row - 1, item.column); if (!_itemLayouts.contains(key)) { plotItem->setTopSuppressed(false); setSpacing(QSizeF(spacing().width(), spacing().height())); return; } LayoutItem top = _itemLayouts.value(key); PlotItem *topItem = qobject_cast(top.viewItem); if (!topItem) { plotItem->setTopSuppressed(false); setSpacing(QSizeF(spacing().width(), spacing().height())); return; } if (item.rowSpan == top.rowSpan && item.columnSpan == top.columnSpan) { plotItem->setTopSuppressed(true); topItem->setBottomSuppressed(true); setSpacing(QSizeF(spacing().width(), 0.0)); } } void ViewGridLayout::shareAxisWithPlotBelow(LayoutItem item) { PlotItem *plotItem = qobject_cast(item.viewItem); QPair key = qMakePair(item.row + 1, item.column); if (!_itemLayouts.contains(key)) { plotItem->setBottomSuppressed(false); setSpacing(QSizeF(spacing().width(), spacing().height())); return; } LayoutItem bottom = _itemLayouts.value(key); PlotItem *bottomItem = qobject_cast(bottom.viewItem); if (!bottomItem) { plotItem->setBottomSuppressed(false); setSpacing(QSizeF(spacing().width(), spacing().height())); return; } if (item.rowSpan == bottom.rowSpan && item.columnSpan == bottom.columnSpan) { plotItem->setBottomSuppressed(true); bottomItem->setTopSuppressed(true); setSpacing(QSizeF(spacing().width(), 0.0)); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewmatrixdialog.ui000644 001750 001750 00000003364 11544160207 021375 0ustar00synthsynth000000 000000 ViewMatrixDialog 0 0 597 536 Matrix View Qt::Horizontal QDialogButtonBox::Close Kst::MatrixSelector QWidget
    matrixselector.h
    buttonBox accepted() ViewMatrixDialog accept() 298 513 298 267 buttonBox rejected() ViewMatrixDialog reject() 298 513 298 267
    kst-2.0.3/src/libkstapp/filterfitdialog.cpp000644 001750 001750 00000020625 11544160207 021332 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "filterfitdialog.h" #include "dialogpage.h" #include "datacollection.h" #include "document.h" #include "basicplugin.h" #include "objectstore.h" #include "curve.h" #include "labelitem.h" #include namespace Kst { FilterFitTab::FilterFitTab(QString& pluginName, QWidget *parent) : DataTab(parent), _configWidget(0), _layout(0), _store(0), _vectorX(0), _vectorY(0), _lockVectors(false) { setupUi(this); setTabTitle(tr("Plugin")); _type = (DataObjectPluginInterface::PluginTypeID)DataObject::pluginType(pluginName); if (_type == DataObjectPluginInterface::Filter) { _pluginCombo->addItems(DataObject::filterPluginList()); } else if (_type == DataObjectPluginInterface::Fit) { _pluginCombo->addItems(DataObject::fitsPluginList()); } _curveAppearance->setVisible(false); _curvePlacement->setVisible(false); _ignoreAutoScale->setVisible(false); pluginChanged(pluginName); connect(_pluginCombo, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(pluginChanged(const QString&))); } FilterFitTab::~FilterFitTab() { } void FilterFitTab::setObjectStore(ObjectStore *store) { _store = store; _configWidget->setObjectStore(store); } void FilterFitTab::setVectorX(VectorPtr vector) { _vectorX = vector; if (_configWidget) { _configWidget->setVectorX(vector); } lockVectors(); } void FilterFitTab::setVectorY(VectorPtr vector) { _vectorY = vector; if (_configWidget) { _configWidget->setVectorY(vector); } lockVectors(); } void FilterFitTab::setPlotMode(PlotItem* plot) { _curvePlacement->setPlace(CurvePlacement::ExistingPlot); _curvePlacement->setExistingPlots(Data::self()->plotList()); _curvePlacement->setCurrentPlot(plot); _curveAppearance->setVisible(true); _curvePlacement->setVisible(true); _ignoreAutoScale->setVisible(true); lockVectors(); } void FilterFitTab::lockVectors() { if (!_lockVectors) { _lockVectors = true; if (_configWidget) { _configWidget->setVectorsLocked(true); } } } CurveAppearance* FilterFitTab::curveAppearance() const { return _curveAppearance; } CurvePlacement* FilterFitTab::curvePlacement() const { return _curvePlacement; } QString FilterFitTab::pluginName() { return _pluginCombo->currentText(); } void FilterFitTab::pluginChanged(const QString &plugin) { if (plugin != _pluginCombo->currentText()) { _pluginCombo->setCurrentIndex(_pluginCombo->findText(plugin)); } _pluginLabel->setText(plugin); _descriptionLabel->setText(DataObject::pluginDescription(plugin)); if (_layout) { delete _layout; } if (_configWidget) { delete _configWidget; } _layout = new QGridLayout(_inputOutputBox); _configWidget = DataObject::pluginWidget(plugin); _configWidget->setupSlots(this); if (_store) { _configWidget->setObjectStore(_store); } if (_vectorX) { _configWidget->setVectorX(_vectorX); } if (_vectorY) { _configWidget->setVectorY(_vectorY); } if (_lockVectors) { _configWidget->setVectorsLocked(true); } _layout->addWidget(_configWidget, 0, 0); _layout->activate(); } FilterFitDialog::FilterFitDialog(QString& pluginName, ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent), _vectorX(0), _vectorY(0) { QString title; if (editMode() == Edit) title = tr("Edit ") + pluginName + tr(" Plugin"); else title = tr("New ") + pluginName + tr(" Plugin"); setWindowTitle(title); _filterFitTab = new FilterFitTab(pluginName, this); addDataTab(_filterFitTab); if (dataObject) { _filterFitTab->configWidget()->setupFromObject(dataObject); } else { _filterFitTab->configWidget()->load(); configureTab(); } } FilterFitDialog::~FilterFitDialog() { } void FilterFitDialog::configureTab() { _filterFitTab->curveAppearance()->loadWidgetDefaults(); } QString FilterFitDialog::tagString() const { return DataDialog::tagString(); } void FilterFitDialog::setVectorX(VectorPtr vector) { _vectorX = vector; _filterFitTab->setVectorX(vector); } void FilterFitDialog::setVectorY(VectorPtr vector) { _vectorY = vector; _filterFitTab->setVectorY(vector); } void FilterFitDialog::setPlotMode(PlotItem* plot) { _filterFitTab->setPlotMode(plot); } ObjectPtr FilterFitDialog::createNewDataObject() { BasicPluginPtr dataObject = kst_cast(DataObject::createPlugin(_filterFitTab->pluginName(), _document->objectStore(), _filterFitTab->configWidget())); Q_ASSERT(dataObject); if (!dataObject->isValid()) { _document->objectStore()->removeObject(dataObject); QString msg(tr("Unable to create Plugin Object using provided parameters.\n\n")); msg += dataObject->errorMessage(); QMessageBox::warning(this, tr("Kst"), msg); return 0; } PlotItem *plotItem = 0; switch (_filterFitTab->curvePlacement()->place()) { case CurvePlacement::NoPlot: break; case CurvePlacement::ExistingPlot: { plotItem = static_cast(_filterFitTab->curvePlacement()->existingPlot()); break; } case CurvePlacement::NewPlotNewTab: _document->createView(); // fall through to case NewPlot. case CurvePlacement::NewPlot: { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); if (_filterFitTab->curvePlacement()->scaleFonts()) { plotItem->view()->resetPlotFontSizes(); } plotItem->view()->appendToLayout(_filterFitTab->curvePlacement()->layout(), plotItem, _filterFitTab->curvePlacement()->gridColumns()); break; } default: break; } if (plotItem) { CurvePtr curve = _document->objectStore()->createObject(); Q_ASSERT(curve); if (!_vectorX) { setVectorX(dataObject->inputVectors().value(dataObject->inputVectorList().first())); } Q_ASSERT(_vectorX); curve->setXVector(_vectorX); VectorPtr yVector = dataObject->outputVectors().value(dataObject->outputVectorList().first()); Q_ASSERT(yVector); curve->setYVector(yVector); curve->setColor(_filterFitTab->curveAppearance()->color()); curve->setHasPoints(_filterFitTab->curveAppearance()->showPoints()); curve->setHasLines(_filterFitTab->curveAppearance()->showLines()); curve->setHasBars(_filterFitTab->curveAppearance()->showBars()); curve->setLineWidth(_filterFitTab->curveAppearance()->lineWidth()); curve->setLineStyle(_filterFitTab->curveAppearance()->lineStyle()); curve->setPointType(_filterFitTab->curveAppearance()->pointType()); curve->setPointDensity(_filterFitTab->curveAppearance()->pointDensity()); curve->setBarStyle(_filterFitTab->curveAppearance()->barStyle()); curve->writeLock(); curve->registerChange(); curve->unlock(); _filterFitTab->curveAppearance()->setWidgetDefaults(); PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(curve)); dataObject->writeLock(); dataObject->internalUpdate(); dataObject->unlock(); if (dataObject->hasParameterVector()) { CreateLabelCommand *cmd = new CreateLabelCommand; QString *tmpstring = new QString(dataObject->parameterVectorToString()); cmd->createItem(tmpstring); } plotItem->update(); } _filterFitTab->configWidget()->save(); return dataObject; } ObjectPtr FilterFitDialog::editExistingDataObject() const { if (BasicPlugin* plugin = kst_cast(dataObject())) { plugin->writeLock(); plugin->change(_filterFitTab->configWidget()); plugin->registerChange(); plugin->unlock(); } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/circleitem.cpp000644 001750 001750 00000010262 11544160207 020276 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "circleitem.h" #include #include #include namespace Kst { CircleItem::CircleItem(View *parent) : ViewItem(parent) { setTypeName("Circle"); setBrush(Qt::white); setLockAspectRatio(true); setLockAspectRatioFixed(true); } CircleItem::~CircleItem() { } void CircleItem::paint(QPainter *painter) { const qreal w = pen().widthF(); painter->drawEllipse(rect().adjusted(w, w, -w, -w)); } void CircleItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("circle"); ViewItem::save(xml); xml.writeEndElement(); } } void CircleItem::creationPolygonChanged(View::CreationEvent event) { if (event == View::EscapeEvent) { ViewItem::creationPolygonChanged(event); return; } if (event == View::MousePress) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MousePress)); setPos(poly.first().x(), poly.first().y()); setViewRect(QRectF(0.0, 0.0, 0.0, sizeOfGrip().height())); view()->scene()->addItem(this); return; } if (event == View::MouseMove) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MouseMove)); qreal size = (fabs(poly.last().x() - rect().x()) < fabs(poly.last().y() - rect().y())) ? fabs(poly.last().x() - rect().x()) : fabs(poly.last().y() - rect().y()); qreal width = (poly.last().x() - rect().x()) < 0 ? size * -1.0 : size; qreal height = (poly.last().y() - rect().y()) < 0 ? size * -1.0 : size; QRectF newRect(rect().x(), rect().y(), width, height); setViewRect(newRect); return; } if (event == View::MouseRelease) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MouseRelease)); view()->disconnect(this, SLOT(deleteLater())); //Don't delete ourself view()->disconnect(this, SLOT(creationPolygonChanged(View::CreationEvent))); view()->setMouseMode(View::Default); updateViewItemParent(); emit creationComplete(); return; } } void CreateCircleCommand::createItem() { _item = new CircleItem(_view); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } CircleItemFactory::CircleItemFactory() : GraphicsFactory() { registerFactory("circle", this); } CircleItemFactory::~CircleItemFactory() { } ViewItem* CircleItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { CircleItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "circle") { Q_ASSERT(!rc); rc = new CircleItem(view); if (parent) { rc->setParentViewItem(parent); } // Add any new specialized CircleItem Properties here. } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "circle") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating circle object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/debugdialog.cpp000644 001750 001750 00000005764 11544160207 020437 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "debugdialog.h" #include "logwidget.h" #include "debug.h" #include "events.h" #include "logevents.h" #include "datasource.h" #include "datasourcepluginmanager.h" #include "kst_i18n.h" #include namespace Kst { DebugDialog::DebugDialog(QWidget *parent) : QDialog(parent), _store(0) { setupUi(this); _log = new LogWidget(_logTab); _logTabLayout->addWidget(_log,0,0); connect(_clear, SIGNAL(clicked()), this, SLOT(clear())); connect(_showDebug, SIGNAL(toggled(bool)), _log, SLOT(setShowDebug(bool))); connect(_showWarning, SIGNAL(toggled(bool)), _log, SLOT(setShowWarning(bool))); connect(_showNotice, SIGNAL(toggled(bool)), _log, SLOT(setShowNotice(bool))); connect(_showError, SIGNAL(toggled(bool)), _log, SLOT(setShowError(bool))); if (!Debug::self()->kstRevision().isEmpty()) _buildInfo->setText(i18n("

    Kst

    Version %1 (%2)").arg(KSTVERSION).arg(Debug::self()->kstRevision())); else _buildInfo->setText(i18n("

    Kst

    Version %1").arg(KSTVERSION)); } DebugDialog::~DebugDialog() { } bool DebugDialog::event(QEvent* e) { if (e->type() == EventTypeLog) { LogEvent *le = dynamic_cast(e); if (le) { switch (le->_eventType) { case LogEvent::LogAdded: _log->logAdded(le->_msg); if (le->_msg.level == Debug::Error) { emit notifyOfError(); } break; case LogEvent::LogCleared: _log->clear(); emit notifyAllClear(); break; default: break; } } } return QDialog::event(e); } void DebugDialog::clear() { Debug::self()->clear(); } void DebugDialog::show() { Q_ASSERT(_store); _dataSources->clear(); _dataSources->setColumnCount(2); const QStringList pl = DataSourcePluginManager::pluginList(); foreach (const QString& pluginName, pl) { QTreeWidgetItem* name = new QTreeWidgetItem(QStringList() << pluginName); name->setData(1, Qt::DisplayRole, DataSourcePluginManager::pluginFileName(pluginName)); _dataSources->insertTopLevelItem (0, name); } _dataSources->header()->resizeSections(QHeaderView::ResizeToContents); QDialog::show(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/kstapp_pch000644 001750 001750 00000001263 11544160207 017532 0ustar00synthsynth000000 000000 #include "kstwidgets_pch.h" #ifdef KST_PCH_RECURSIVE // widgets headers #include "colorbutton.h" #include "combobox.h" #include "curveplacement.h" #include "datarange.h" #include "datasourceselector.h" #include "fftoptions.h" #include "gradienteditor.h" #include "labellineedit.h" #include "scalarlistselector.h" #include "stringselector.h" #include "widgets.h" #include "colorpalette.h" #include "curveappearance.h" #include "curveselector.h" #include "datasourceselectordialog.h" #include "dialogdefaults.h" #include "filerequester.h" #include "kstwidgets_export.h" #include "labelbuilder.h" #include "matrixselector.h" #include "scalarselector.h" #include "vectorselector.h" #endif kst-2.0.3/src/libkstapp/arrowitem.cpp000644 001750 001750 00000013446 11544160207 020176 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "arrowitem.h" #include "view.h" #include "arrowitemdialog.h" #include "math_kst.h" #include #include #include #include namespace Kst { ArrowItem::ArrowItem(View *parent) : LineItem(parent), _startArrowHead(false), _endArrowHead(true), _startArrowScale(12.0), _endArrowScale(12.0) { setTypeName("Arrow"); QBrush b = brush(); b.setStyle(Qt::SolidPattern); setBrush(b); } ArrowItem::~ArrowItem() { } void ArrowItem::paint(QPainter *painter) { painter->drawLine(line()); start.clear(); end.clear(); if (_startArrowHead) { //FIXME: this assumes that pixelSize == pointSize, which it only might... double deltax = view()->defaultFont(_startArrowScale).pointSizeF()*0.5; double theta = atan2(double(line().y2() - line().y1()), double(line().x2() - line().x1())) - M_PI / 2.0; double sina = sin(theta); double cosa = cos(theta); double yin = sqrt(3.0) * deltax; double x1, y1, x2, y2; QMatrix m(cosa, sina, -sina, cosa, 0.0, 0.0); m.map( deltax, yin, &x1, &y1); m.map(-deltax, yin, &x2, &y2); QPolygonF pts; pts.append(line().p1()); pts.append(line().p1() + QPointF(x1, y1)); pts.append(line().p1() + QPointF(x2, y2)); painter->drawPolygon(pts); start = pts; } if (_endArrowHead) { //FIXME: this assumes that pixelSize == pointSize, which it only might... double deltax = view()->defaultFont(_endArrowScale).pointSizeF()*0.5; double theta = atan2(double(line().y1() - line().y2()), double(line().x1() - line().x2())) - M_PI / 2.0; double sina = sin(theta); double cosa = cos(theta); double yin = sqrt(3.0) * deltax; double x1, y1, x2, y2; QMatrix m(cosa, sina, -sina, cosa, 0.0, 0.0); m.map( deltax, yin, &x1, &y1); m.map(-deltax, yin, &x2, &y2); QPolygonF pts; pts.append(line().p2()); pts.append(line().p2() + QPointF(x1, y1)); pts.append(line().p2() + QPointF(x2, y2)); painter->drawPolygon(pts); end = pts; } } QPainterPath ArrowItem::shape() const { QPainterPath selectPath; selectPath.setFillRule(Qt::WindingFill); selectPath.addPolygon(rect()); selectPath.addPolygon(start); selectPath.addPolygon(end); if ((!isSelected() && !isHovering()) || (view()->mouseMode() == View::Create)) { } else { selectPath.addPath(grips()); } return selectPath; } void ArrowItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("arrow"); xml.writeAttribute("startarrowhead", QVariant(_startArrowHead).toString()); xml.writeAttribute("endarrowhead", QVariant(_endArrowHead).toString()); xml.writeAttribute("startarrowheadscale", QVariant(_startArrowScale).toString()); xml.writeAttribute("endarrowheadscale", QVariant(_endArrowScale).toString()); ViewItem::save(xml); xml.writeEndElement(); } } void ArrowItem::edit() { ArrowItemDialog *editDialog = new ArrowItemDialog(this); editDialog->show(); } void CreateArrowCommand::createItem() { _item = new ArrowItem(_view); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } ArrowItemFactory::ArrowItemFactory() : GraphicsFactory() { registerFactory("arrow", this); } ArrowItemFactory::~ArrowItemFactory() { } ViewItem* ArrowItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { ArrowItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "arrow") { Q_ASSERT(!rc); rc = new ArrowItem(view); if (parent) { rc->setParentViewItem(parent); } QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; av = attrs.value("startarrowhead"); if (!av.isNull()) { rc->setStartArrowHead(QVariant(av.toString()).toBool()); } av = attrs.value("endarrowhead"); if (!av.isNull()) { rc->setEndArrowHead(QVariant(av.toString()).toBool()); } av = attrs.value("startarrowheadscale"); if (!av.isNull()) { rc->setStartArrowScale(QVariant(av.toString()).toDouble()); } av = attrs.value("endarrowheadscale"); if (!av.isNull()) { rc->setEndArrowScale(QVariant(av.toString()).toDouble()); } // Add any new specialized ArrowItem Properties here. } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "arrow") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating arrow object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/layoutboxitem.cpp000644 001750 001750 00000012722 11544160207 021066 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "layoutboxitem.h" #include "viewgridlayout.h" #include "debug.h" #include #include #include #include #include namespace Kst { LayoutBoxItem::LayoutBoxItem(View *parent) : ViewItem(parent) { setTypeName("Layout Box"); setPen(Qt::NoPen); setBrush(Qt::NoBrush); setAllowedGripModes(Move); view()->scene()->addItem(this); setPos(view()->sceneRect().topLeft()); setViewRect(view()->sceneRect()); setEnabled(true); } void LayoutBoxItem::appendItem(ViewItem *item) { if (item->parentItem() == this) return; item->setParentViewItem(this); // layout()->addViewItem(item, layout()->rowCount(), 0, 1, layout()->columnCount()); setPos(view()->sceneRect().topLeft()); setViewRect(view()->sceneRect()); //singleshot to give plots a chance to set a projection rect // QTimer::singleShot(0, layout(), SLOT(update())); } void LayoutBoxItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("layoutbox"); ViewItem::save(xml); QList list = QGraphicsItem::children(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem) continue; xml.writeStartElement("layoutitem"); xml.writeAttribute("name", viewItem->typeName()); xml.writeEndElement(); } xml.writeEndElement(); } } void LayoutBoxItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); painter->setPen(pen()); painter->setBrush(brush()); painter->drawRect(rect()); } LayoutBoxItem::~LayoutBoxItem() { } void LayoutBoxItem::setEnabled(bool enabled) { if (!view()) return; if (enabled) { QList list = view()->items(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem || viewItem->parentItem() || !viewItem->isVisible() || viewItem == this) continue; viewItem->setParentViewItem(this); } view()->setLayoutBoxItem(this); show(); } else { QList list = QGraphicsItem::children(); foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem) continue; viewItem->setParentViewItem(0); } view()->setLayoutBoxItem(0); hide(); } } void LayoutBoxItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { event->ignore(); } void LayoutBoxItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { event->ignore(); } bool LayoutBoxItem::appendItemFromXml(QXmlStreamReader &xml) { bool validTag = false; if (xml.isStartElement() && xml.name().toString() == "layoutitem") { QXmlStreamAttributes attrs = xml.attributes(); QStringRef av; av = attrs.value("name"); if (!av.isNull()) { //TODO Use ObjectTag to locate the correct item and add it to this layout. } xml.readNext(); if (xml.isEndElement() && xml.name().toString() == "layoutitem") { validTag = true; } } return validTag; } LayoutBoxItemFactory::LayoutBoxItemFactory() : GraphicsFactory() { registerFactory("layoutbox", this); } LayoutBoxItemFactory::~LayoutBoxItemFactory() { } ViewItem* LayoutBoxItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { LayoutBoxItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "layoutbox") { Q_ASSERT(!rc); rc = new LayoutBoxItem(view); if (parent) { rc->setParentViewItem(parent); } // Add any specialized BoxItem Properties here. } else if (xml.name().toString() == "layoutitem") { Q_ASSERT(rc); validTag = rc->appendItemFromXml(xml); } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "layoutbox") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating layoutbox object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } // LayoutBoxItem automatically adds itself to the parent. Don't return the item here as it // has already been added to the scene. return 0; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/gridlayouthelper.cpp000644 001750 001750 00000036445 11544160207 021554 0ustar00synthsynth000000 000000 /**************************************************************************** ** ** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved. ** ** This file is part of the Qt Designer of the Qt Toolkit. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://trolltech.com/products/qt/licenses/licensing/opensource/ ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview ** or contact the sales department at sales@trolltech.com. ** ** In addition, as a special exception, Trolltech gives you certain ** additional rights. These rights are described in the Trolltech GPL ** Exception version 1.0, which can be found at ** http://www.trolltech.com/products/qt/gplexception/ and in the file ** GPL_EXCEPTION.txt in this package. ** ** In addition, as a special exception, Trolltech, as the sole copyright ** holder for Qt Designer, grants users of the Qt/Eclipse Integration ** plug-in the right for the Qt/Eclipse Integration to link to ** functionality provided by Qt Designer and its related libraries. ** ** Trolltech reserves all rights not expressly granted herein. ** ** Trolltech ASA (c) 2007 ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* These classes were taken from Qt designer in Qt 4.3 and adapted to work with our layouts and items.*/ #include "gridlayouthelper.h" #include #include #define DEBUG_GRID_BUILDING 0 namespace Kst { Grid *Grid::buildGrid(const QList &itemList) { if (!itemList.count()) return 0; // qDebug() << "building Automatic grid" << itemList.count(); // Pixel to cell conversion: // By keeping a list of start'n'stop values (x & y) for each viewitem, // it is possible to create a very small grid of cells to represent // the item layout. // ----------------------------------------------------------------- // modified by cbn to have a tolerance of 1/8 the size of the smallest object // We need a list of both start and stop values for x- & y-axis QVector x( itemList.count()*2 ); QVector y( itemList.count()*2 ); // Using push_back would look nicer, but operator[] is much faster int index = 0; ViewItem* v = 0; int minWidth = itemList.at(0)->viewRect().width(); int minHeight = itemList.at(0)->viewRect().height(); for (int i = 0; i < itemList.size(); ++i) { v = itemList.at(i); QRect itemPos = QRect(v->pos().toPoint(), v->viewRect().size().toSize()); x[index] = itemPos.left(); x[index+1] = itemPos.right(); y[index] = itemPos.top(); y[index+1] = itemPos.bottom(); if (itemPos.width() < minWidth) { minWidth = itemPos.width(); } if (itemPos.height() < minHeight) { minHeight = itemPos.height(); } index += 2; } qSort(x); qSort(y); // Remove duplicate x enteries (Remove next, if equal to current) if ( !x.empty() ) { for (QVector::iterator current = x.begin() ; (current != x.end()) && ((current+1) != x.end()) ; ) if ( abs(*current - *(current+1)) < minWidth/8 ) x.erase(current+1); else current++; } // Remove duplicate y enteries (Remove next, if equal to current) if ( !y.empty() ) { for (QVector::iterator current = y.begin() ; (current != y.end()) && ((current+1) != y.end()) ; ) if ( abs(*current - *(current+1)) < minHeight/8 ) y.erase(current+1); else current++; } int rows = y.size() - 1; int cols = x.size() - 1; rows++; #if DEBUG_GRID_BUILDING qDebug() << "Building automatic grid with" << rows << "rows and" << cols << "columns"; #endif Grid *grid = new Grid(rows, cols); // Mark the cells in the grid that contains a widget foreach (ViewItem *v, itemList) { QRect itemPos = QRect(v->pos().toPoint(), v->viewRect().size().toSize()); QRect c(0, 0, 0, 0); // From left til right (not including) for (int cw=0; cwsetCells(c, v); // Mark cellblock } grid->simplify(); return grid; } void Grid::setCells(QRect c, ViewItem* w) { #if DEBUG_GRID_BUILDING qDebug() << "setCells requested for rect" << c; #endif QVector skippedRows; QVector skippedColumns; for (int rows = c.bottom()-c.top()-1; rows >= 0; rows--) for (int cols = c.right()-c.left()-1; cols >= 0; cols--) { if (!(skippedRows.contains(c.top()+rows) || skippedColumns.contains(c.left()+cols))) { if (!setCell(c.top()+rows, c.left()+cols, w)) { skippedRows.append(c.top()+rows); skippedColumns.append(c.left()+cols); #if DEBUG_GRID_BUILDING qDebug() << "skipping rows" << skippedRows << "skipping columns" << skippedColumns; #endif } } } } bool Grid::setCell(int row, int col, ViewItem* w) { #if DEBUG_GRID_BUILDING qDebug() << "Setting cell" << row << col; #endif if (cell(row, col)) { #if DEBUG_GRID_BUILDING qDebug() << "Cell has already been added"; #endif return false; } else { m_cells[ row * m_ncols + col] = w; return true; } } Grid *Grid::buildGrid(const QList &itemList, int columns) { if (!itemList.count()) return 0; if (columns == 0) { return buildGrid(itemList); } int rows = ceil((qreal)itemList.count() / columns); if (rows * columns == itemList.count()) { rows++; #if DEBUG_GRID_BUILDING qDebug() << "Padding required, row count is now" << rows; #endif } #if DEBUG_GRID_BUILDING qDebug() << "Building custom grid with" << rows << "rows and" << columns << "columns"; #endif QMap sortedItems; foreach(ViewItem* item, itemList) { int sortId = item->pos().x() + item->pos().y() * 10; sortedItems.insert(sortId, item); } Grid *grid = new Grid(rows, columns); // Mark the cells in the grid that contains a widget int row = 0, col = 0; foreach (ViewItem *v, sortedItems) { grid->setCell(row, col, v); col++; if (col == columns) { row++; col = 0; } } grid->simplify(); return grid; } Grid::Grid(int r, int c) : m_nrows(r), m_ncols(c), m_cells(new ViewItem*[ r * c ]), m_cols(new bool[ c ]), m_rows(new bool[ r ]) { qFill(m_cells, m_cells + r * c, static_cast(0)); } Grid::~Grid() { delete [] m_cells; delete [] m_cols; delete [] m_rows; } int Grid::countRow(int r, int c) const { ViewItem* w = cell(r, c); int i = c + 1; while (i < m_ncols && cell(r, i) == w) i++; return i - c; } int Grid::countCol(int r, int c) const { ViewItem* w = cell(r, c); int i = r + 1; while (i < m_nrows && cell(i, c) == w) i++; return i - r; } void Grid::setCol(int r, int c, ViewItem* w, int count) { for (int i = 0; i < count; i++) setCell(r + i, c, w); } void Grid::setRow(int r, int c, ViewItem* w, int count) { for (int i = 0; i < count; i++) setCell(r, c + i, w); } bool Grid::isWidgetStartCol(int c) const { int r; for (r = 0; r < m_nrows; r++) { if (cell(r, c) && ((c==0) || (cell(r, c) != cell(r, c-1)))) { return true; } } return false; } bool Grid::isWidgetEndCol(int c) const { int r; for (r = 0; r < m_nrows; r++) { if (cell(r, c) && ((c == m_ncols-1) || (cell(r, c) != cell(r, c+1)))) return true; } return false; } bool Grid::isWidgetStartRow(int r) const { int c; for (c = 0; c < m_ncols; c++) { if (cell(r, c) && ((r==0) || (cell(r, c) != cell(r-1, c)))) return true; } return false; } bool Grid::isWidgetEndRow(int r) const { int c; for (c = 0; c < m_ncols; c++) { if (cell(r, c) && ((r == m_nrows-1) || (cell(r, c) != cell(r+1, c)))) return true; } return false; } bool Grid::isWidgetTopLeft(int r, int c) const { ViewItem* w = cell(r, c); if (!w) return false; return (!r || cell(r-1, c) != w) && (!c || cell(r, c-1) != w); } void Grid::extendLeft() { int r,c,i; for (c = 1; c < m_ncols; c++) { for (r = 0; r < m_nrows; r++) { ViewItem* w = cell(r, c); if (!w) continue; int cc = countCol(r, c); int stretch = 0; for (i = c-1; i >= 0; i--) { if (cell(r, i)) break; if (countCol(r, i) < cc) break; if (isWidgetEndCol(i)) break; if (isWidgetStartCol(i)) { stretch = c - i; break; } } if (stretch) { for (i = 0; i < stretch; i++) setCol(r, c-i-1, w, cc); } } } } void Grid::extendRight() { int r,c,i; for (c = m_ncols - 2; c >= 0; c--) { for (r = 0; r < m_nrows; r++) { ViewItem* w = cell(r, c); if (!w) continue; int cc = countCol(r, c); int stretch = 0; for (i = c+1; i < m_ncols; i++) { if (cell(r, i)) break; if (countCol(r, i) < cc) break; if (isWidgetStartCol(i)) break; if (isWidgetEndCol(i)) { stretch = i - c; break; } } if (stretch) { for (i = 0; i < stretch; i++) setCol(r, c+i+1, w, cc); } } } } void Grid::extendUp() { int r,c,i; for (r = 1; r < m_nrows; r++) { for (c = 0; c < m_ncols; c++) { ViewItem* w = cell(r, c); if (!w) continue; int cr = countRow(r, c); int stretch = 0; for (i = r-1; i >= 0; i--) { if (cell(i, c)) break; if (countRow(i, c) < cr) break; if (isWidgetEndRow(i)) break; if (isWidgetStartRow(i)) { stretch = r - i; break; } } if (stretch) { for (i = 0; i < stretch; i++) setRow(r-i-1, c, w, cr); } } } } void Grid::extendDown() { int r,c,i; for (r = m_nrows - 2; r >= 0; r--) { for (c = 0; c < m_ncols; c++) { ViewItem* w = cell(r, c); if (!w) continue; int cr = countRow(r, c); int stretch = 0; for (i = r+1; i < m_nrows; i++) { if (cell(i, c)) break; if (countRow(i, c) < cr) break; if (isWidgetStartRow(i)) break; if (isWidgetEndRow(i)) { stretch = i - r; break; } } if (stretch) { for (i = 0; i < stretch; i++) setRow(r+i+1, c, w, cr); } } } } void Grid::simplify() { extendLeft(); extendRight(); extendUp(); extendDown(); merge(); } void Grid::merge() { int r,c; for (c = 0; c < m_ncols; c++) m_cols[c] = false; for (r = 0; r < m_nrows; r++) m_rows[r] = false; for (c = 0; c < m_ncols; c++) { for (r = 0; r < m_nrows; r++) { if (isWidgetTopLeft(r, c)) { m_rows[r] = true; m_cols[c] = true; } } } } bool Grid::locateWidget(ViewItem *w, int &row, int &col, int &rowspan, int &colspan) { int r, c, r2, c2; for (c = 0; c < m_ncols; c++) { for (r = 0; r < m_nrows; r++) { if (cell(r, c) == w) { row = 0; for (r2 = 1; r2 <= r; r2++) { if (m_rows[r2-1]) row++; } col = 0; for (c2 = 1; c2 <= c; c2++) { if (m_cols[c2-1]) col++; } rowspan = 0; for (r2 = r ; r2 < m_nrows && cell(r2, c) == w; r2++) { if (m_rows[r2]) rowspan++; } colspan = 0; for (c2 = c; c2 < m_ncols && cell(r, c2) == w; c2++) { if (m_cols[c2]) colspan++; } return true; } } } return false; } void Grid::appendItem(ViewItem *w) { // qDebug() << "Appending Item to grid"; for (int c = 0; c < m_ncols; c++) { for (int r = 0; r < m_nrows; r++) { if ((cell(r, c) == 0) && m_rows[r] && m_cols[c]) { #if DEBUG_GRID_BUILDING qDebug() << "Found empty cell" << r << c; #endif setCell(r, c, w); simplify(); return; } } } #if DEBUG_GRID_BUILDING qDebug() << "No empty cell located. Appending to end."; #endif if (cell(m_nrows - 1, 0) == 0) { setCell(m_nrows - 1, 0, w); simplify(); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/applicationsettings.h000644 001750 001750 00000006226 11544160207 021714 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef APPLICATIONSETTINGS_H #define APPLICATIONSETTINGS_H #include #include #include class QSettings; namespace Kst { class ApplicationSettingsDialog; class ApplicationSettings : public QObject { Q_OBJECT public: static ApplicationSettings *self(); bool useOpenGL() const; void setUseOpenGL(bool useOpenGL); int referenceViewWidth() const; int referenceViewHeight() const; double referenceViewWidthCM() const; void setReferenceViewWidthCM(const double width); double referenceViewHeightCM() const; void setReferenceViewHeightCM(const double height); double minimumFontSize() const; void setMinimumFontSize(const double points); QFont defaultFont() const; void setDefaultFont(const QFont &font); qreal defaultFontScale() const; void setDefaultFontScale(const qreal scale); QColor defaultFontColor() const; void setDefaultFontColor(const QColor &color); int minimumUpdatePeriod() const; void setMinimumUpdatePeriod(const int period); bool showGrid() const; void setShowGrid(bool showGrid); bool snapToGrid() const; void setSnapToGrid(bool snapToGrid); qreal gridHorizontalSpacing() const; void setGridHorizontalSpacing(qreal spacing); qreal gridVerticalSpacing() const; void setGridVerticalSpacing(qreal spacing); QBrush backgroundBrush() const; void setBackgroundBrush(const QBrush brush); QGradientStops gradientStops() const; QSizeF layoutMargins() const; void setLayoutMargins(QSizeF margins); QSizeF layoutSpacing() const; void setLayoutSpacing(QSizeF spacing); Q_SIGNALS: void modified(); private: ApplicationSettings(); ~ApplicationSettings(); static void cleanup(); private: QSettings *_settings; bool _useOpenGL; double _refViewWidth; double _refViewHeight; double _minFontSize; QString _defaultFontFamily; QFont _defaultFont; qreal _defaultFontScale; QColor _defaultFontColor; int _maxUpdate; bool _showGrid; bool _snapToGrid; qreal _gridHorSpacing; qreal _gridVerSpacing; QBrush _backgroundBrush; QGradientStops _gradientStops; bool _shareAxis; QSizeF _layoutMargins; QSizeF _layoutSpacing; friend class ApplicationSettingsDialog; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/axistab.ui000644 001750 001750 00000062012 11544160207 017444 0ustar00synthsynth000000 000000 AxisTab 0 0 543 413 Form Scale &Logarithmic Reverse the direction of the axis, so the numbers are decreasing, rather than increasing.f &Reverse 0 0 Axis is time Interpret the axis as time. &Interpret as: false Time encoding type The axis represents time, whose encoding is selected here. false 0 0 &Display as: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _scaleDisplayType false Time display format If the axis is to be intpreted as time, then display the time on the axis with this format. 0 0 Hide Margins and Labels Hide top Hide bottom Qt::Vertical 20 40 Base / Offset Mode Auto base / offset mode true false false The axis numbers are displayed relative to a reference value, which is displayed on the same line as the axis label. This option is designed to allow small differences from large offsets to be easily seen. &Base and offset mode Digits before automatic base/offset mode: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _significantDigits If this many digits are required to display the tick numbers, then the axis will revert to Base/Offset mode. 2 15 9 Label Rotation Rotation : -90 90 Qt::Vertical 20 52 Major Ticks and Lines 0 0 Dra&w ticks true 0 0 Draw &grid lines true 0 0 Major s&pacing: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _axisMajorTickSpacing 0 0 Density of major ticks Specify the density of major ticks. The major tick interval will automatically be chosen as a power of 10 times 1,2, or 5. This changes the target tick spacing within this constraint. 0 0 Grid line &style: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _axisMajorLineStyle 0 0 0 0 Grid line &color: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _axisMajorLineColor 0 0 Width: Minor Ticks and Lines 0 0 Dr&aw ticks true 0 0 Draw grid lines true 0 0 Minor tic&k count: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _axisMinorTickCount 0 0 1 10 4 Auto Line st&yle: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _axisMinorLineStyle 0 0 Lin&e color: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _axisMinorLineColor 0 0 Width: Kst::ColorButton QToolButton
    colorbutton.h
    _drawAxisMajorGridLines toggled(bool) _Label_3 setEnabled(bool) 146 299 34 366 _drawAxisMajorGridLines toggled(bool) label_10 setEnabled(bool) 170 299 57 397 _drawAxisMajorGridLines toggled(bool) _axisMajorLineColor setEnabled(bool) 243 299 136 396 _drawAxisMajorGridLines toggled(bool) _axisMajorLineStyle setEnabled(bool) 158 297 254 366 _drawAxisMinorGridLines toggled(bool) _axisMinorLineStyleLabel setEnabled(bool) 473 294 340 366 _drawAxisMinorGridLines toggled(bool) label_12 setEnabled(bool) 407 300 342 397 _drawAxisMinorGridLines toggled(bool) _axisMinorLineColor setEnabled(bool) 407 300 409 396 _drawAxisMinorGridLines toggled(bool) _axisMinorLineStyle setEnabled(bool) 407 300 527 366 _scaleInterpret toggled(bool) _scaleDisplayType setEnabled(bool) 76 81 528 117 _scaleInterpret toggled(bool) _Label_6 setEnabled(bool) 104 81 114 117 _scaleInterpret toggled(bool) _scaleInterpretType setEnabled(bool) 114 81 305 84 _scaleAutoBaseOffset toggled(bool) label_2 setEnabled(bool) 110 168 276 209 _scaleAutoBaseOffset toggled(bool) _significantDigits setEnabled(bool) 110 168 340 209 _drawAxisMajorGridLines toggled(bool) label_5 setEnabled(bool) 190 285 156 381 _drawAxisMajorGridLines toggled(bool) _axisMajorLineWidth setEnabled(bool) 213 284 206 386 _drawAxisMinorGridLines toggled(bool) label_6 setEnabled(bool) 438 284 424 376 _drawAxisMinorGridLines toggled(bool) _axisMinorLineWidth setEnabled(bool) 445 284 487 383
    kst-2.0.3/src/libkstapp/curvedialog.cpp000644 001750 001750 00000046043 11544160207 020470 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "curvedialog.h" #include "dialogpage.h" #include "editmultiplewidget.h" #include "curve.h" #include "view.h" #include "plotitem.h" #include "tabwidget.h" #include "mainwindow.h" #include "application.h" #include "plotrenderitem.h" #include "datacollection.h" #include "document.h" #include "objectstore.h" #include namespace Kst { CurveTab::CurveTab(QWidget *parent) : DataTab(parent) { setupUi(this); setTabTitle(tr("Curve")); _xError->setAllowEmptySelection(true); _yError->setAllowEmptySelection(true); _xMinusError->setAllowEmptySelection(true); _yMinusError->setAllowEmptySelection(true); _curvePlacement->setExistingPlots(Data::self()->plotList()); _xVectorLabel->setBuddy(_xVector->_vector); _yVectorLabel->setBuddy(_yVector->_vector); _xErrorLabel->setBuddy(_xError->_vector); _yErrorLabel->setBuddy(_yError->_vector); _xMinusErrorLabel->setBuddy(_xMinusError->_vector); _yMinusErrorLabel->setBuddy(_yMinusError->_vector); _xVector->setIsX(true); int maxComboWidth = 200; _xVector->setMaximumWidth(maxComboWidth); _yVector->setMaximumWidth(maxComboWidth); _xError->setMaximumWidth(maxComboWidth); _yError->setMaximumWidth(maxComboWidth); _xMinusError->setMaximumWidth(maxComboWidth); _yMinusError->setMaximumWidth(maxComboWidth); connect(_xVector, SIGNAL(selectionChanged(QString)), this, SIGNAL(vectorsChanged())); connect(_yVector, SIGNAL(selectionChanged(QString)), this, SIGNAL(vectorsChanged())); connect(_xMinusSameAsPlus, SIGNAL(toggled(bool)), this, SLOT(xCheckboxClicked())); connect(_yMinusSameAsPlus, SIGNAL(toggled(bool)), this, SLOT(yCheckboxClicked())); connect(_xError, SIGNAL(selectionChanged(QString)), this, SLOT(xErrorChanged())); connect(_yError, SIGNAL(selectionChanged(QString)), this, SLOT(xErrorChanged())); connect(_xVector, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); connect(_yVector, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); connect(_xError, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); connect(_yError, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); connect(_xMinusError, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); connect(_yMinusError, SIGNAL(selectionChanged(QString)), this, SIGNAL(modified())); // if the content of any of the vector combos is changed (new or edit), update them all. connect(_xVector, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos())); connect(_yVector, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos())); connect(_xError, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos())); connect(_yError, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos())); connect(_xMinusError, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos())); connect(_yMinusError, SIGNAL(contentChanged()), this, SLOT(updateVectorCombos())); connect(_curveAppearance, SIGNAL(modified()), this, SIGNAL(modified())); connect(_ignoreAutoScale, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_xMinusSameAsPlus, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_yMinusSameAsPlus, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); } CurveTab::~CurveTab() { } VectorPtr CurveTab::xVector() const { return _xVector->selectedVector(); } bool CurveTab::xVectorDirty() const { return _xVector->selectedVectorDirty(); } void CurveTab::setXVector(VectorPtr vector) { _xVector->setSelectedVector(vector); } VectorPtr CurveTab::yVector() const { return _yVector->selectedVector(); } bool CurveTab::yVectorDirty() const { return _yVector->selectedVectorDirty(); } void CurveTab::setYVector(VectorPtr vector) { _yVector->setSelectedVector(vector); } VectorPtr CurveTab::xError() const { return _xError->selectedVector(); } bool CurveTab::xErrorDirty() const { return _xError->selectedVectorDirty(); } void CurveTab::setXError(VectorPtr vector) { _xError->setSelectedVector(vector); } VectorPtr CurveTab::yError() const { return _yError->selectedVector(); } bool CurveTab::yErrorDirty() const { return _yError->selectedVectorDirty(); } void CurveTab::setYError(VectorPtr vector) { _yError->setSelectedVector(vector); } VectorPtr CurveTab::xMinusError() const { return _xMinusError->selectedVector(); } bool CurveTab::xMinusErrorDirty() const { return _xMinusError->selectedVectorDirty(); } void CurveTab::setXMinusError(VectorPtr vector) { _xMinusError->setSelectedVector(vector); } VectorPtr CurveTab::yMinusError() const { return _yMinusError->selectedVector(); } bool CurveTab::yMinusErrorDirty() const { return _yMinusError->selectedVectorDirty(); } void CurveTab::setYMinusError(VectorPtr vector) { _yMinusError->setSelectedVector(vector); } void CurveTab::xCheckboxClicked() { _xMinusError->setEnabled(!_xMinusSameAsPlus->isChecked()); _xMinusErrorLabel->setEnabled(!_xMinusSameAsPlus->isChecked()); xErrorChanged(); } void CurveTab::yCheckboxClicked() { _yMinusError->setEnabled(!_yMinusSameAsPlus->isChecked()); _yMinusErrorLabel->setEnabled(!_yMinusSameAsPlus->isChecked()); yErrorChanged(); } void CurveTab::xErrorChanged() { if (_xMinusSameAsPlus->isChecked()) { _xMinusError->setSelectedVector(_xError->selectedVector()); } } void CurveTab::yErrorChanged() { if (_yMinusSameAsPlus->isChecked()) { _yMinusError->setSelectedVector(_yError->selectedVector()); } } void CurveTab::setObjectStore(ObjectStore *store) { _xVector->setObjectStore(store); _yVector->setObjectStore(store); _xError->setObjectStore(store); _yError->setObjectStore(store); _xMinusError->setObjectStore(store); _yMinusError->setObjectStore(store); } void CurveTab::hidePlacementOptions() { _curvePlacement->setVisible(false); } CurveAppearance* CurveTab::curveAppearance() const { return _curveAppearance; } CurvePlacement* CurveTab::curvePlacement() const { return _curvePlacement; } bool CurveTab::ignoreAutoScale() const { return _ignoreAutoScale->isChecked(); } bool CurveTab::ignoreAutoScaleDirty() const { return _ignoreAutoScale->checkState() != Qt::PartiallyChecked; } void CurveTab::setIgnoreAutoScale(bool ignoreAutoScale) { _ignoreAutoScale->setChecked(ignoreAutoScale); } void CurveTab::clearTabValues() { _xVector->clearSelection(); _yVector->clearSelection(); _xError->clearSelection(); _yError->clearSelection(); _xMinusError->clearSelection(); _yMinusError->clearSelection(); _ignoreAutoScale->setCheckState(Qt::PartiallyChecked); _curveAppearance->clearValues(); } void CurveTab::updateVectorCombos() { _xVector->fillVectors(); _yVector->fillVectors(); _xError->fillVectors(); _yError->fillVectors(); _xMinusError->fillVectors(); _yMinusError->fillVectors(); } CurveDialog::CurveDialog(ObjectPtr dataObject, QWidget *parent) : DataDialog(dataObject, parent) { if (editMode() == Edit) setWindowTitle(tr("Edit Curve")); else setWindowTitle(tr("New Curve")); _curveTab = new CurveTab(this); addDataTab(_curveTab); if (editMode() == Edit) { configureTab(dataObject); } else { configureTab(0); } connect(_curveTab, SIGNAL(vectorsChanged()), this, SLOT(updateButtons())); connect(this, SIGNAL(editMultipleMode()), this, SLOT(editMultipleMode())); connect(this, SIGNAL(editSingleMode()), this, SLOT(editSingleMode())); connect(_curveTab, SIGNAL(modified()), this, SLOT(modified())); updateButtons(); } CurveDialog::~CurveDialog() { } // QString CurveDialog::tagString() const { // return DataDialog::tagString(); // } // void CurveDialog::editMultipleMode() { _curveTab->clearTabValues(); } void CurveDialog::editSingleMode() { configureTab(dataObject()); } void CurveDialog::configureTab(ObjectPtr object) { if (!object) { _curveTab->curveAppearance()->loadWidgetDefaults(); _curveTab->setToLastX(); } else if (CurvePtr curve = kst_cast(object)) { _curveTab->curveAppearance()->loadWidgetDefaults(); _curveTab->setXVector(curve->xVector()); _curveTab->setYVector(curve->yVector()); if (curve->hasXError()) { _curveTab->setXError(curve->xErrorVector()); } if (curve->hasYError()) { _curveTab->setYError(curve->yErrorVector()); } if (curve->hasXMinusError()) { _curveTab->setXMinusError(curve->xMinusErrorVector()); } if (curve->hasYMinusError()) { _curveTab->setYMinusError(curve->yMinusErrorVector()); } _curveTab->setIgnoreAutoScale(curve->ignoreAutoScale()); _curveTab->curveAppearance()->setColor(curve->color()); _curveTab->curveAppearance()->setHeadColor(curve->headColor()); _curveTab->curveAppearance()->setShowPoints(curve->hasPoints()); _curveTab->curveAppearance()->setShowLines(curve->hasLines()); _curveTab->curveAppearance()->setShowBars(curve->hasBars()); _curveTab->curveAppearance()->setShowHead(curve->hasHead()); _curveTab->curveAppearance()->setLineWidth(curve->lineWidth()); _curveTab->curveAppearance()->setLineStyle(curve->lineStyle()); _curveTab->curveAppearance()->setPointType(curve->pointType()); _curveTab->curveAppearance()->setPointDensity(curve->pointDensity()); _curveTab->curveAppearance()->setBarStyle(curve->barStyle()); _curveTab->curveAppearance()->setHeadType(curve->headType()); _curveTab->hidePlacementOptions(); if (_editMultipleWidget) { CurveList objects = _document->objectStore()->getObjects(); _editMultipleWidget->clearObjects(); foreach(CurvePtr object, objects) { _editMultipleWidget->addObject(object->Name(), object->descriptionTip()); } } } } void CurveDialog::setVector(VectorPtr vector) { _curveTab->setYVector(vector); } void CurveDialog::updateButtons() { _buttonBox->button(QDialogButtonBox::Ok)->setEnabled((_curveTab->xVector() && _curveTab->yVector()) || (editMode() == EditMultiple)); } ObjectPtr CurveDialog::createNewDataObject() { Q_ASSERT(_document && _document->objectStore()); ObjectStore *os = _document->objectStore(); CurvePtr curve = os->createObject(); curve->setXVector(_curveTab->xVector()); curve->setYVector(_curveTab->yVector()); curve->setXError(_curveTab->xError()); curve->setYError(_curveTab->yError()); curve->setXMinusError(_curveTab->xMinusError()); curve->setYMinusError(_curveTab->yMinusError()); curve->setColor(_curveTab->curveAppearance()->color()); curve->setHeadColor(_curveTab->curveAppearance()->headColor()); curve->setHasPoints(_curveTab->curveAppearance()->showPoints()); curve->setHasLines(_curveTab->curveAppearance()->showLines()); curve->setHasBars(_curveTab->curveAppearance()->showBars()); curve->setHasHead(_curveTab->curveAppearance()->showHead()); curve->setLineWidth(_curveTab->curveAppearance()->lineWidth()); curve->setLineStyle(_curveTab->curveAppearance()->lineStyle()); curve->setPointType(_curveTab->curveAppearance()->pointType()); curve->setPointDensity(_curveTab->curveAppearance()->pointDensity()); curve->setBarStyle(_curveTab->curveAppearance()->barStyle()); curve->setHeadType(_curveTab->curveAppearance()->headType()); curve->setIgnoreAutoScale(_curveTab->ignoreAutoScale()); if (DataDialog::tagStringAuto()) { curve->setDescriptiveName(QString()); } else { curve->setDescriptiveName(DataDialog::tagString()); } curve->writeLock(); curve->registerChange(); curve->unlock(); _curveTab->curveAppearance()->setWidgetDefaults(); PlotItem *plotItem = 0; switch (_curveTab->curvePlacement()->place()) { case CurvePlacement::NoPlot: break; case CurvePlacement::ExistingPlot: { plotItem = static_cast(_curveTab->curvePlacement()->existingPlot()); break; } case CurvePlacement::NewPlotNewTab: _document->createView(); // fall through to case NewPlot. case CurvePlacement::NewPlot: { CreatePlotForCurve *cmd = new CreatePlotForCurve(); cmd->createItem(); plotItem = static_cast(cmd->item()); if (_curveTab->curvePlacement()->scaleFonts()) { plotItem->view()->resetPlotFontSizes(); } break; } default: break; } if (_curveTab->curvePlacement()->place() != CurvePlacement::NoPlot) { PlotRenderItem *renderItem = plotItem->renderItem(PlotRenderItem::Cartesian); renderItem->addRelation(kst_cast(curve)); plotItem->update(); plotItem->view()->appendToLayout(_curveTab->curvePlacement()->layout(), plotItem, _curveTab->curvePlacement()->gridColumns()); } return ObjectPtr(curve.data()); } ObjectPtr CurveDialog::editExistingDataObject() const { if (CurvePtr curve = kst_cast(dataObject())) { if (editMode() == EditMultiple) { QStringList objects = _editMultipleWidget->selectedObjects(); foreach (QString objectName, objects) { CurvePtr curve = kst_cast(_document->objectStore()->retrieveObject(objectName)); if (curve) { VectorPtr xVector = _curveTab->xVectorDirty() ? _curveTab->xVector() : curve->xVector(); VectorPtr yVector = _curveTab->yVectorDirty() ? _curveTab->yVector() : curve->yVector(); VectorPtr xError = 0; if (_curveTab->xErrorDirty()) { xError = _curveTab->xError(); } else if (curve->hasXError()) { xError = curve->xErrorVector(); } VectorPtr yError = 0; if (_curveTab->yErrorDirty()) { yError = _curveTab->yError(); } else if (curve->hasYError()) { yError = curve->yErrorVector(); } VectorPtr xMinusError = 0; if (_curveTab->xMinusErrorDirty()) { xMinusError = _curveTab->xMinusError(); } else if (curve->hasXMinusError()) { xMinusError = curve->xMinusErrorVector(); } VectorPtr yMinusError = 0; if (_curveTab->yMinusErrorDirty()) { yMinusError = _curveTab->yMinusError(); } else if (curve->hasYMinusError()) { yMinusError = curve->yMinusErrorVector(); } QColor color = _curveTab->curveAppearance()->colorDirty() ? _curveTab->curveAppearance()->color() : curve->color(); QColor headColor = _curveTab->curveAppearance()->headColorDirty() ? _curveTab->curveAppearance()->headColor() : curve->headColor(); int lineWidth = _curveTab->curveAppearance()->lineWidthDirty() ? _curveTab->curveAppearance()->lineWidth() : curve->lineWidth(); int lineStyle = _curveTab->curveAppearance()->lineStyleDirty() ? _curveTab->curveAppearance()->lineStyle() : curve->lineStyle(); int pointType = _curveTab->curveAppearance()->pointTypeDirty() ? _curveTab->curveAppearance()->pointType() : curve->pointType(); int pointDensity = _curveTab->curveAppearance()->pointDensityDirty() ? _curveTab->curveAppearance()->pointDensity() : curve->pointDensity(); int barStyle = _curveTab->curveAppearance()->barStyleDirty() ? _curveTab->curveAppearance()->barStyle() : curve->barStyle(); int headType = _curveTab->curveAppearance()->headTypeDirty() ? _curveTab->curveAppearance()->headType() : curve->headType(); bool showPoints = _curveTab->curveAppearance()->showPointsDirty() ? _curveTab->curveAppearance()->showPoints() : curve->hasPoints(); bool showLines = _curveTab->curveAppearance()->showLinesDirty() ? _curveTab->curveAppearance()->showLines() : curve->hasLines(); bool showBars = _curveTab->curveAppearance()->showBarsDirty() ? _curveTab->curveAppearance()->showBars() : curve->hasBars(); bool showHead = _curveTab->curveAppearance()->showHeadDirty() ? _curveTab->curveAppearance()->showHead() : curve->hasHead(); bool ignoreAutoScale = _curveTab->ignoreAutoScaleDirty() ? _curveTab->ignoreAutoScale() : curve->ignoreAutoScale(); curve->writeLock(); curve->setXVector(xVector); curve->setYVector(yVector); curve->setXError(xError); curve->setYError(yError); curve->setXMinusError(xMinusError); curve->setYMinusError(yMinusError); curve->setColor(color); curve->setHeadColor(headColor); curve->setHasPoints(showPoints); curve->setHasLines(showLines); curve->setHasBars(showBars); curve->setHasHead(showHead); curve->setLineWidth(lineWidth); curve->setLineStyle(lineStyle); curve->setPointType(pointType); curve->setPointDensity(pointDensity); curve->setBarStyle(barStyle); curve->setHeadType(headType); curve->setIgnoreAutoScale(ignoreAutoScale); if (DataDialog::tagStringAuto()) { curve->setDescriptiveName(QString()); } else { curve->setDescriptiveName(DataDialog::tagString()); } curve->registerChange(); curve->unlock(); } } } else { curve->writeLock(); curve->setXVector(_curveTab->xVector()); curve->setYVector(_curveTab->yVector()); curve->setXError(_curveTab->xError()); curve->setYError(_curveTab->yError()); curve->setXMinusError(_curveTab->xMinusError()); curve->setYMinusError(_curveTab->yMinusError()); curve->setColor(_curveTab->curveAppearance()->color()); curve->setHeadColor(_curveTab->curveAppearance()->headColor()); curve->setHasPoints(_curveTab->curveAppearance()->showPoints()); curve->setHasLines(_curveTab->curveAppearance()->showLines()); curve->setHasBars(_curveTab->curveAppearance()->showBars()); curve->setHasHead(_curveTab->curveAppearance()->showHead()); curve->setLineWidth(_curveTab->curveAppearance()->lineWidth()); curve->setLineStyle(_curveTab->curveAppearance()->lineStyle()); curve->setPointType(_curveTab->curveAppearance()->pointType()); curve->setPointDensity(_curveTab->curveAppearance()->pointDensity()); curve->setBarStyle(_curveTab->curveAppearance()->barStyle()); curve->setHeadType(_curveTab->curveAppearance()->headType()); curve->setIgnoreAutoScale(_curveTab->ignoreAutoScale()); if (DataDialog::tagStringAuto()) { curve->setDescriptiveName(QString()); } else { curve->setDescriptiveName(DataDialog::tagString()); } curve->registerChange(); curve->unlock(); _curveTab->curveAppearance()->setWidgetDefaults(false); } } return dataObject(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/exportgraphicsdialog.h000644 001750 001750 00000003024 11544160207 022043 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EXPORTGRAPHICSDIALOG_H #define EXPORTGRAPHICSDIALOG_H #include #include "ui_exportgraphicsdialog.h" #include "kst_export.h" namespace Kst { class MainWindow; class ExportGraphicsDialog : public QDialog, Ui::ExportGraphicsDialog { Q_OBJECT public: ExportGraphicsDialog(MainWindow *win); virtual ~ExportGraphicsDialog(); public slots: void createFile(); void enableWidthHeight(); void OKClicked(); void apply(); void applyAutosave(); void updateButtons(); Q_SIGNALS: void exportGraphics(const QString &filename, const QString &format, int w, int h, int display); private: QTimer *_autoSaveTimer; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/overridelabeltab.ui000644 001750 001750 00000017142 11544160207 021323 0ustar00synthsynth000000 000000 OverrideLabelTab 0 0 451 271 400 0 Form 0 false 0 0 Font &size: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _fontSize false 1 -25.000000000000000 1.000000000000000 false 0 0 22 22 Alt+I true false 0 0 Font famil&y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _family false false 0 0 22 22 Alt+B true &Use plot default font true false points Qt::Vertical 20 129 Kst::ColorButton QToolButton
    colorbutton.h
    _useDefault toggled(bool) _Label_11 setDisabled(bool) 52 13 54 45 _useDefault toggled(bool) _Label_12 setDisabled(bool) 33 23 37 82 _useDefault toggled(bool) _labelColor setDisabled(bool) 71 25 138 125 _useDefault toggled(bool) _family setDisabled(bool) 90 20 142 91 _useDefault toggled(bool) _fontSize setDisabled(bool) 105 21 138 55 _useDefault toggled(bool) _italic setDisabled(bool) 136 25 523 40 _useDefault toggled(bool) _bold setDisabled(bool) 122 24 427 46
    kst-2.0.3/src/libkstapp/labelitemdialog.cpp000644 001750 001750 00000004216 11544160207 021276 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labelitemdialog.h" #include "labelitem.h" #include "labelpropertiestab.h" #include "dialogpage.h" #include "application.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" namespace Kst { LabelItemDialog::LabelItemDialog(LabelItem *item, QWidget *parent) : ViewItemDialog(item, parent), _labelItem(item) { _propertiesTab = new LabelPropertiesTab(this); DialogPage *propertiesPage = new DialogPage(this); propertiesPage->setPageTitle(tr("Properties")); propertiesPage->addDialogTab(_propertiesTab); addDialogPage(propertiesPage); selectDialogPage(propertiesPage); connect(_propertiesTab, SIGNAL(apply()), this, SLOT(propertiesChanged())); setupProperties(); } LabelItemDialog::~LabelItemDialog() { } void LabelItemDialog::setupProperties() { _propertiesTab->setLabelText(_labelItem->labelText()); _propertiesTab->setLabelScale(_labelItem->labelScale()); _propertiesTab->setLabelColor(_labelItem->labelColor()); _propertiesTab->setLabelFont(_labelItem->labelFont()); } void LabelItemDialog::propertiesChanged() { _labelItem->setLabelText(_propertiesTab->labelText()); _labelItem->setLabelScale(_propertiesTab->labelScale()); _labelItem->setLabelColor(_propertiesTab->labelColor()); _labelItem->setLabelFont(_propertiesTab->labelFont()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/eventmonitordialog.h000644 001750 001750 00000005716 11544160207 021544 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EVENTMONITORDIALOG_H #define EVENTMONITORDIALOG_H #include "datadialog.h" #include "datatab.h" #include "debug.h" #include "kst_export.h" #include "ui_eventmonitortab.h" namespace Kst { class EventMonitorTab : public DataTab, Ui::EventMonitorTab { Q_OBJECT public: EventMonitorTab(QWidget *parent = 0); virtual ~EventMonitorTab(); void setObjectStore(ObjectStore *store); QString script() const; bool scriptDirty() const; void setScript(const QString script); QString event() const; bool eventDirty() const; void setEvent(const QString event); QString description() const; bool descriptionDirty() const; void setDescription(const QString description); Debug::LogLevel logLevel() const; bool logLevelDirty() const; void setLogLevel(const Debug::LogLevel level); bool logDebug() const; bool logDebugDirty() const; void setLogDebug(const bool logDebug); bool logEMail() const; bool logEMailDirty() const; void setLogEMail(const bool logEMail); bool logELOG() const; bool logELOGDirty() const; void setLogELOG(const bool logELOG); QString emailRecipients() const; bool emailRecipientsDirty() const; void setEmailRecipients(const QString emailRecipients); void clearTabValues(); void resetLogLevelDirty(); private Q_SLOTS: void selectionChanged(); void logLevelChanged(); void equationUpdate(const QString& string); void equationOperatorUpdate(const QString& string); Q_SIGNALS: void optionsChanged(); private: bool _logLevelDirty; }; class EventMonitorDialog : public DataDialog { Q_OBJECT public: explicit EventMonitorDialog(ObjectPtr dataObject, QWidget *parent = 0); virtual ~EventMonitorDialog(); protected: // virtual QString tagString() const; virtual ObjectPtr createNewDataObject(); virtual ObjectPtr editExistingDataObject() const; private Q_SLOTS: void updateButtons(); void editMultipleMode(); void editSingleMode(); private: void configureTab(ObjectPtr object); EventMonitorTab *_eventMonitorTab; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/aboutdialog.ui000644 001750 001750 00000004460 11544160207 020306 0ustar00synthsynth000000 000000 AboutDialog 0 0 383 278 About Kst :/kst.png 26 Kst Qt::Horizontal 40 20 true false Qt::Horizontal QDialogButtonBox::Close buttonBox clicked(QAbstractButton*) AboutDialog accept() 191 257 191 138 kst-2.0.3/src/libkstapp/markerstab.cpp000644 001750 001750 00000021344 11544160207 020314 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "markerstab.h" #include "plotdefines.h" #include namespace Kst { MarkersTab::MarkersTab(QWidget *parent) : DialogTab(parent) { setupUi(this); setTabTitle(tr("Markers")); _markerLineStyle->addItem("SolidLine", Qt::SolidLine); _markerLineStyle->addItem("DashLine", Qt::DashLine); _markerLineStyle->addItem("DotLine", Qt::DotLine); _markerLineStyle->addItem("DashDotLine", Qt::DashDotLine); _markerLineStyle->addItem("DashDotDotLine", Qt::DashDotDotLine); _markerLineStyle->addItem("CustomDashLine", Qt::CustomDashLine); connect(_curveMarkers, SIGNAL(stateChanged(int)), this, SLOT(update())); connect(_vectorMarkers, SIGNAL(stateChanged(int)), this, SLOT(update())); connect(_currentMarkersList, SIGNAL(itemSelectionChanged()), this, SLOT(update())); connect(_newMarker, SIGNAL(textChanged(const QString&)), this, SLOT(update())); connect(_markerLineStyle, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_markerLineColor, SIGNAL(changed(const QColor &)), this, SIGNAL(modified())); connect(_curveMarkers, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_vectorMarkers, SIGNAL(stateChanged(int)), this, SIGNAL(modified())); connect(_vector, SIGNAL(selectionChanged(const QString&)), this, SIGNAL(modified())); connect(_curve, SIGNAL(selectionChanged(const QString&)), this, SIGNAL(modified())); connect(_risingEdge, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_fallingEdge, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_both, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_markerLineWidth, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_addMarker, SIGNAL(clicked()), this, SLOT(add())); connect(_removeMarker, SIGNAL(clicked()), this, SLOT(remove())); connect(_clearMarkers, SIGNAL(clicked()), this, SLOT(clear())); connect(this, SIGNAL(modified()), this, SLOT(setDirty())); update(); } MarkersTab::~MarkersTab() { } void MarkersTab::setObjectStore(ObjectStore *store) { _vector->setObjectStore(store); _curve->setObjectStore(store); } void MarkersTab::update() { _curve->setEnabled(_curveMarkers->isChecked()); _risingEdge->setEnabled(_curveMarkers->isChecked()); _fallingEdge->setEnabled(_curveMarkers->isChecked()); _both->setEnabled(_curveMarkers->isChecked()); _vector->setEnabled(_vectorMarkers->isChecked()); _removeMarker->setEnabled(_currentMarkersList->selectedItems().count() > 0); _clearMarkers->setEnabled(_currentMarkersList->count() > 0); _addMarker->setEnabled(!_newMarker->text().isEmpty()); } Qt::PenStyle MarkersTab::lineStyle() const { return Qt::PenStyle(_markerLineStyle->itemData(_markerLineStyle->currentIndex()).toInt()); } void MarkersTab::setLineStyle(Qt::PenStyle style) { _markerLineStyle->setCurrentIndex(_markerLineStyle->findData(QVariant(style))); } QColor MarkersTab::lineColor() const { return _markerLineColor->color(); } void MarkersTab::setLineColor(const QColor &color) { _markerLineColor->setColor(color); } double MarkersTab::lineWidth() const { return _markerLineWidth->value(); } void MarkersTab::setLineWidth(const double width) { _markerLineWidth->setValue(width); } bool MarkersTab::isCurveSource() const { return _curveMarkers->isChecked(); } void MarkersTab::setCurveSource(const bool enabled) { _curveMarkers->setChecked(enabled); } bool MarkersTab::isVectorSource() const { return _vectorMarkers->isChecked(); } void MarkersTab::setVectorSource(const bool enabled) { _vectorMarkers->setChecked(enabled); } VectorPtr MarkersTab::vector() const { return _vector->selectedVector(); } void MarkersTab::setVector(const VectorPtr vector) { _vector->setSelectedVector(vector); } PlotMarkers::CurveMarkerMode MarkersTab::curveMarkerMode() const { if (_risingEdge->isChecked()) { return PlotMarkers::RisingEdge; } else if (_fallingEdge->isChecked()) { return PlotMarkers::FallingEdge; } else { return PlotMarkers::BothEdges; } } void MarkersTab::setCurveMarkerMode(const PlotMarkers::CurveMarkerMode mode) { if (mode == PlotMarkers::RisingEdge) { _risingEdge->setChecked(true); } else if (mode == PlotMarkers::FallingEdge) { _fallingEdge->setChecked(true); } else { _both->setChecked(true); } } QList MarkersTab::markers() const { QList markerList; foreach(QListWidgetItem *item, _currentMarkersList->findItems("*", Qt::MatchWildcard)) { markerList << item->text().toDouble(); } return markerList; } void MarkersTab::setMarkers(const QList &markers) { QStringList markerList; foreach(double marker, markers) { markerList << QString::number(marker, 'g', MARKER_LABEL_PRECISION); } _currentMarkersList->clear(); _currentMarkersList->addItems(markerList); } CurvePtr MarkersTab::curve() const { return _curve->selectedCurve(); } void MarkersTab::setCurve(CurvePtr curve) { _curve->setSelectedCurve(curve); } void MarkersTab::add() { if (!_newMarker->text().isEmpty()) { bool ok; double newMarkerValue = _newMarker->text().toDouble(&ok); if (ok) { int i = 0; QString newMarkerString; newMarkerString.setNum(newMarkerValue, 'g', MARKER_LABEL_PRECISION); while (i < _currentMarkersList->count() && _currentMarkersList->item(i)->text().toDouble() < newMarkerValue) { i++; } if (i == _currentMarkersList->count()) { _currentMarkersList->addItem(newMarkerString); _newMarker->clear(); update(); emit modified(); } else if (newMarkerValue != _currentMarkersList->item(i)->text().toDouble()) { _currentMarkersList->insertItem(i, newMarkerString); _newMarker->clear(); update(); emit modified(); } else { QMessageBox::warning(this, tr("Kst"), tr("A plot marker with equal (or very close) value already exists.")); } } else { QMessageBox::warning(this, tr("Kst"), tr("The text you have entered is not a valid number.")); } } } void MarkersTab::remove() { foreach(QListWidgetItem *item, _currentMarkersList->selectedItems()) { _currentMarkersList->takeItem(_currentMarkersList->row(item)); } emit modified(); } void MarkersTab::clear() { _currentMarkersList->clear(); emit modified(); } PlotMarkers MarkersTab::plotMarkers() const { PlotMarkers plotMarker = _plotMarkers; plotMarker.setManualMarkers(markers()); plotMarker.setLineStyle(lineStyle()); plotMarker.setLineColor(lineColor()); plotMarker.setLineWidth(lineWidth()); if (isVectorSource()) { plotMarker.setVector(vector()); } else { plotMarker.setVector(0); } if (isCurveSource()) { plotMarker.setCurve(curve()); } else { plotMarker.setCurve(0); } plotMarker.setCurveMarkerMode(curveMarkerMode()); return plotMarker; } void MarkersTab::setPlotMarkers(const PlotMarkers &plotMarkers) { _plotMarkers = plotMarkers; setMarkers(plotMarkers.manualMarkers()); setLineStyle(plotMarkers.lineStyle()); setLineColor(plotMarkers.lineColor()); setLineWidth(plotMarkers.lineWidth()); setCurveMarkerMode(plotMarkers.curveMarkerMode()); if (plotMarkers.isVectorSource()) { setVector(plotMarkers.vector()); setVectorSource(true); } else { setVectorSource(false); } if (plotMarkers.isCurveSource()) { setCurve(plotMarkers.curve()); setCurveSource(true); } else { setCurveSource(false); } _dirty = false; } void MarkersTab::clearTabValues() { _currentMarkersList->clear(); _hidden->setChecked(true); _markerLineStyle->setCurrentIndex(-1); _markerLineColor->clearSelection(); _markerLineWidth->clear(); _curve->clearSelection(); _vector->clearSelection(); _curveMarkers->setCheckState(Qt::PartiallyChecked); _vectorMarkers->setCheckState(Qt::PartiallyChecked); } void MarkersTab::enableSingleEditOptions(bool enabled) { if (enabled) { _curveMarkers->setTristate(false); _vectorMarkers->setTristate(false); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dialogtab.h000644 001750 001750 00000002765 11544160207 017562 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIALOGTAB_H #define DIALOGTAB_H #include #include "kst_export.h" namespace Kst { class Dialog; class DialogPage; //FIXME maybe we should really have a model... class DialogTab : public QWidget { Q_OBJECT public: DialogTab(QWidget *parent); virtual ~DialogTab(); Dialog *dialog() const; DialogPage *dialogPage() const; QString tabTitle() const { return _tabTitle; } void setTabTitle(const QString &tabTitle) { _tabTitle = tabTitle; } Q_SIGNALS: void ok(); void apply(); void cancel(); //subclasses must emit... void modified(); private: QString _tabTitle; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/layouttab.h000644 001750 001750 00000003251 11544160207 017627 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LAYOUTTAB_H #define LAYOUTTAB_H #include "dialogtab.h" #include "ui_layouttab.h" #include "kst_export.h" namespace Kst { class LayoutTab : public DialogTab, Ui::LayoutTab { Q_OBJECT public: LayoutTab(QWidget *parent = 0); virtual ~LayoutTab(); double horizontalMargin() const; bool horizontalMarginDirty() const; void setHorizontalMargin(double horizontalMargin); double verticalMargin() const; bool verticalMarginDirty() const; void setVerticalMargin(double verticalMargin); double horizontalSpacing() const; bool horizontalSpacingDirty() const; void setHorizontalSpacing(double horizontalSpacing); double verticalSpacing() const; bool verticalSpacingDirty() const; void setVerticalSpacing(double verticalSpacing); void clearTabValues(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/view.cpp000644 001750 001750 00000050443 11544160207 017135 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "view.h" #include "scene.h" #include "viewitem.h" #include "layoutboxitem.h" #include "mainwindow.h" #include "application.h" #include "applicationsettings.h" #include "viewdialog.h" #include "viewgridlayout.h" #include "document.h" #include "plotitemmanager.h" #include "plotitem.h" #include "dialogdefaults.h" #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Kst { View::View() : QGraphicsView(kstApp->mainWindow()) { init(); } View::View(QWidget* parent) : QGraphicsView(parent) { init(); } void View::init() { _viewMode = Data; _mouseMode = Default; _layoutBoxItem = 0; _gridSpacing = QSizeF(20,20); _showGrid = false; _snapToGridHorizontal = false; _snapToGridVertical = false; _plotBordersDirty = false; _printing = false; _dataMode = false; _fontRescale = 1.0; _childMaximized = false; _undoStack = new QUndoStack(this); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setScene(new Scene(this)); scene()->setSceneRect(rect()); scene()->installEventFilter(this); setInteractive(true); setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); setFrameStyle(QFrame::NoFrame); setContextMenuPolicy(Qt::DefaultContextMenu); _useOpenGL = ApplicationSettings::self()->useOpenGL(); if (_useOpenGL) { setViewportUpdateMode(QGraphicsView::FullViewportUpdate); setViewport(new QGLWidget); } else { setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate); setViewport(0); } connect(ApplicationSettings::self(), SIGNAL(modified()), this, SLOT(updateSettings())); loadSettings(); _editAction = new QAction(tr("Edit"), this); _editAction->setShortcut(Qt::Key_E); // registerShortcut(_editAction); connect(_editAction, SIGNAL(triggered()), this, SLOT(edit())); _autoLayoutAction = new QAction(tr("Automatic"), this); connect(_autoLayoutAction, SIGNAL(triggered()), this, SLOT(createLayout())); _customLayoutAction = new QAction(tr("Custom"), this); connect(_customLayoutAction, SIGNAL(triggered()), this, SLOT(createCustomLayout())); connect(this, SIGNAL(viewModeChanged(View::ViewMode)), PlotItemManager::self(), SLOT(clearFocusedPlots())); } View::~View() { // PlotItems are QGraphicsItems and managed by Qt's graphic view PlotItemManager::clearPlotsForView(this); delete _undoStack; delete _layoutBoxItem; } bool View::useOpenGL() const { return _useOpenGL; } void View::setUseOpenGL(bool useOpenGL) { //This is an expensive operation... if (_useOpenGL == useOpenGL) return; _useOpenGL = useOpenGL; if (useOpenGL) { setViewportUpdateMode(QGraphicsView::FullViewportUpdate); setViewport(new QGLWidget); } else { setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate); setViewport(0); } } QUndoStack *View::undoStack() const { return _undoStack; } ViewItem *View::selectedViewItem() const { QList items = scene()->selectedItems(); if (items.isEmpty()) return 0; //return the first item return qgraphicsitem_cast(items.first()); } void View::save(QXmlStreamWriter &xml) { QList items = scene()->items(); xml.writeAttribute("width", QVariant(sceneRect().width()).toString()); xml.writeAttribute("height", QVariant(sceneRect().height()).toString()); foreach(QGraphicsItem* viewItem, items) { if (!viewItem->parentItem()) { qgraphicsitem_cast(viewItem)->save(xml); } } } View::ViewMode View::viewMode() const { return _viewMode; } void View::setViewMode(ViewMode mode) { ViewMode oldMode = _viewMode; _viewMode = mode; emit viewModeChanged(oldMode); } View::MouseMode View::mouseMode() const { return _mouseMode; } void View::setMouseMode(MouseMode mode) { //Clear the creation polygons if we're currently //in Create mouse mode. MouseMode oldMode = _mouseMode; if (oldMode == Create) { _creationPolygonPress.clear(); _creationPolygonRelease.clear(); _creationPolygonMove.clear(); } _mouseMode = mode; if (_mouseMode != Create) { setCursor(Qt::ArrowCursor); setDragMode(QGraphicsView::RubberBandDrag); } else { setDragMode(QGraphicsView::NoDrag); } emit mouseModeChanged(oldMode); } void View::setZoomOnly(ZoomOnlyMode zoomMode) { QList plots = PlotItemManager::plotsForView(this); foreach (PlotItem* plot, plots) { plot->setZoomOnly(zoomMode); // should we overload setZoomOnly? QList renderers = plot->renderItems(); foreach (PlotRenderItem* renderer, renderers) { renderer->setZoomOnly(zoomMode); } } } QPolygonF View::creationPolygon(CreationEvents events) const { if (events == View::MousePress) return _creationPolygonPress; if (events == View::MouseRelease) return _creationPolygonRelease; if (events == View::MouseMove) return _creationPolygonMove; return QPolygonF(); } void View::setShowGrid(bool showGrid) { //Don't repaint unless absolutely necessary if (_showGrid == showGrid) return; _showGrid = showGrid; invalidateScene(sceneRect(), QGraphicsScene::BackgroundLayer); } void View::setGridSpacing(const QSizeF &gridSpacing) { //Don't repaint unless absolutely necessary if (_gridSpacing == gridSpacing) return; _gridSpacing = gridSpacing; invalidateScene(sceneRect(), QGraphicsScene::BackgroundLayer); } QPointF View::snapPoint(const QPointF &point) { qreal x = point.x(); qreal y = point.y(); if (_snapToGridHorizontal && gridSpacing().width() > 0) x -= fmod(point.x(), gridSpacing().width()); if (_snapToGridVertical && gridSpacing().height() > 0) y -= fmod(point.y(), gridSpacing().height()); return QPointF(x, y); } bool View::event(QEvent *event) { if (event->type() == QEvent::Shortcut) { QShortcutEvent *e = static_cast(event); QPointF mousePos = mapToScene(mapFromGlobal(QCursor::pos())); QList list = scene()->items(mousePos); if (list.isEmpty()) { if (e->key() == _editAction->shortcut()) { _editAction->trigger(); } } else { foreach (QGraphicsItem *item, list) { ViewItem *viewItem = qgraphicsitem_cast(item); if (!viewItem) continue; // Qt bug: http://bugreports.qt.nokia.com/browse/QTBUG-8188 // also see PlotRenderItem::hoverEnterEvent, there is a workaround. //if (viewItem && viewItem->tryShortcut(e->key())) { if (viewItem && viewItem->hasFocus() && viewItem->tryShortcut(e->key())) { return true; } } } } else if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *e = static_cast(event); if (e->button() == Qt::RightButton) { contextMenuEvent(); return true; } } return QGraphicsView::event(event); } bool View::eventFilter(QObject *obj, QEvent *event) { if (obj != scene() || _mouseMode != Create) return QGraphicsView::eventFilter(obj, event); switch (event->type()) { case QEvent::GraphicsSceneMousePress: { QGraphicsSceneMouseEvent *e = static_cast(event); if (e->button() == Qt::LeftButton) { _creationPolygonPress << snapPoint(e->buttonDownScenePos(Qt::LeftButton)); emit creationPolygonChanged(MousePress); return true; //filter this otherwise something can grab our mouse... } } case QEvent::GraphicsSceneMouseRelease: { QGraphicsSceneMouseEvent *e = static_cast(event); if (e->button() != Qt::LeftButton) break; _creationPolygonRelease << snapPoint(e->scenePos()); emit creationPolygonChanged(MouseRelease); break; } case QEvent::GraphicsSceneMouseMove: { QGraphicsSceneMouseEvent *e = static_cast(event); _creationPolygonMove << snapPoint(e->scenePos()); emit creationPolygonChanged(MouseMove); break; } case QEvent::KeyPress: { QKeyEvent *e = static_cast(event); if (e->key() == Qt::Key_Escape) { emit creationPolygonChanged(EscapeEvent); } } default: break; } return QGraphicsView::eventFilter(obj, event); } void View::createCustomLayout() { bool ok; int columns = QInputDialog::getInteger(this, tr("Kst"), tr("Select Number of Columns"),1, 0, 10, 1, &ok); if (ok) { createLayout(columns); } } void View::createLayout(int columns) { PlotItemManager::self()->clearFocusedPlots(); LayoutCommand *layout = new LayoutCommand(new LayoutBoxItem(this)); layout->createLayout(columns); if (_layoutBoxItem) { _layoutBoxItem->setEnabled(false); delete _layoutBoxItem; _layoutBoxItem = 0; } } void View::appendToLayout(CurvePlacement::Layout layout, ViewItem* item, int columns) { AppendLayoutCommand *appendlayout = new AppendLayoutCommand(new LayoutBoxItem(this)); appendlayout->appendLayout(layout, item, columns); if (_layoutBoxItem) { LayoutBoxItem *layoutBox = _layoutBoxItem; _layoutBoxItem->setEnabled(false); delete layoutBox; } } void View::processResize(QSize size) { setPlotBordersDirty(true); if (size != sceneRect().size()) { QRectF oldSceneRect = sceneRect(); viewport()->resize(size); setSceneRect(QRectF(0.0, 0.0, size.width() - 1.0, size.height() - 1.0)); updateBrush(); setCacheMode(QGraphicsView::CacheBackground); foreach (QGraphicsItem *item, items()) { if (item->parentItem()) continue; ViewItem *viewItem = qgraphicsitem_cast(item); Q_ASSERT(viewItem); viewItem->updateChildGeometry(oldSceneRect, sceneRect()); } } updateFont(); } void View::resizeEvent(QResizeEvent *event) { if (event) { QGraphicsView::resizeEvent(event); } setPlotBordersDirty(true); if (size() != sceneRect().size()) { QRectF oldSceneRect = sceneRect(); setSceneRect(QRectF(0.0, 0.0, width() - 1.0, height() - 1.0)); updateBrush(); setCacheMode(QGraphicsView::CacheBackground); foreach (QGraphicsItem *item, items()) { if (item->parentItem()) continue; ViewItem *viewItem = qgraphicsitem_cast(item); Q_ASSERT(viewItem); viewItem->updateChildGeometry(oldSceneRect, sceneRect()); } } updateFont(); } void View::forceChildResize(QRectF oldRect, QRectF newRect) { foreach (QGraphicsItem *item, items()) { if (item->parentItem()) continue; ViewItem *viewItem = qgraphicsitem_cast(item); Q_ASSERT(viewItem); viewItem->updateChildGeometry(oldRect, newRect); } } void View::updateBrush() { if (!ApplicationSettings::self()->gradientStops().empty()) { QLinearGradient l(0.0, height() - 4.0, 0.0, 0.0); l.setStops(ApplicationSettings::self()->gradientStops()); setBackgroundBrush(l); } else { setBackgroundBrush(ApplicationSettings::self()->backgroundBrush()); } } void View::drawBackground(QPainter *painter, const QRectF &rect) { if (isPrinting()) { QBrush currentBrush(backgroundBrush()); setBackgroundBrush(Qt::white); QGraphicsView::drawBackground(painter, rect); setBackgroundBrush(currentBrush); return; } QGraphicsView::drawBackground(painter, rect); if (!showGrid()) return; painter->save(); QColor c = Qt::gray; c.setAlphaF(c.alphaF() * 0.2); painter->setPen(c); // http://techbase.kde.org/Development/Tutorials/Graphics/Performance says // setOpacity turns off hardware acceleration. // they suggest setting alpha in the color instead, which // we have done, above. //painter->setOpacity(0.2); const QRectF r = sceneRect(); qreal spacing = gridSpacing().width(); //FIXME We should probably only draw those lines that intercept rect //vertical lines qreal x = r.left() + spacing; while (x < r.right() && spacing > 0) { QLineF line(QPointF(x, r.top()), QPointF(x, r.bottom())); painter->drawLine(line); x += spacing; } spacing = gridSpacing().height(); //horizontal lines qreal y = r.top() + spacing; while (y < r.bottom() && spacing > 0) { QLineF line(QPointF(r.left(), y), QPointF(r.right(), y)); painter->drawLine(line); y += spacing; } painter->restore(); } void View::updateSettings() { setUseOpenGL(ApplicationSettings::self()->useOpenGL()); setShowGrid(ApplicationSettings::self()->showGrid()); setSnapToGrid(ApplicationSettings::self()->snapToGrid()); setGridSpacing(QSizeF(ApplicationSettings::self()->gridHorizontalSpacing(), ApplicationSettings::self()->gridVerticalSpacing())); QFont oldFont = _defaultFont; updateFont(); if (oldFont != _defaultFont) { forceChildResize(sceneRect(), sceneRect()); } } void View::loadSettings() { setUseOpenGL(ApplicationSettings::self()->useOpenGL()); setShowGrid(ApplicationSettings::self()->showGrid()); setSnapToGrid(ApplicationSettings::self()->snapToGrid()); setGridSpacing(QSizeF(ApplicationSettings::self()->gridHorizontalSpacing(), ApplicationSettings::self()->gridVerticalSpacing())); updateFont(); updateBrush(); } void View::updateChildGeometry(const QRectF &oldSceneRect) { foreach (QGraphicsItem *item, items()) { if (item->parentItem()) continue; ViewItem *viewItem = qgraphicsitem_cast(item); Q_ASSERT(viewItem); viewItem->updateChildGeometry(oldSceneRect, sceneRect()); } } // the view's default font size will be the application's default font size, // scaled by the size of the window compared to the reference plot size. void View::updateFont() { _defaultFont = ApplicationSettings::self()->defaultFont(); } // returns a font of size pointSize, rescaled if the window size // is different than the reference window size. QFont View::defaultFont(double pointSize) const { QFont font(_defaultFont); qreal fontSize = (qreal)(height() + width()) / (ApplicationSettings::self()->referenceViewHeight() + ApplicationSettings::self()->referenceViewWidth()) * pointSize * _fontRescale; if (fontSize < ApplicationSettings::self()->minimumFontSize()) { fontSize = ApplicationSettings::self()->minimumFontSize(); } if (fontSize < 0) return font; #ifdef Q_OS_WIN // On Windows more and more memory gets allocated when fontsize // is to detailed, somewhere some strange caching happens. const double fontPrecision = 4; fontSize = floor(fontSize * fontPrecision + 0.5) / fontPrecision; #endif font.setPointSizeF(fontSize); return font; } // Set the font sizes of all plots in the view to a default size, scaled // by the default global font scale, and the application minimum font scale. void View::resetPlotFontSizes(double pointSize) { if (pointSize < 0.1) { pointSize = _dialogDefaults->value("plot/globalFontScale",16.0).toDouble(); } double count = PlotItemManager::self()->plotsForView(this).count(); double newPointSize = pointSize/sqrt(count) + ApplicationSettings::self()->minimumFontSize(); if (newPointSizeminimumFontSize()); foreach(PlotItem* plotItem, PlotItemManager::self()->plotsForView(this)) { plotItem->setGlobalFontScale(pointSize); plotItem->rightLabelDetails()->setFontScale(pointSize); plotItem->leftLabelDetails()->setFontScale(pointSize); plotItem->bottomLabelDetails()->setFontScale(pointSize); plotItem->topLabelDetails()->setFontScale(pointSize); plotItem->numberLabelDetails()->setFontScale(pointSize); if (plotItem->showLegend()) { plotItem->legend()->setFontScale(legendPointSize); } } } // copy the font settings of the first plotItem in the view into // plot, then break. void View::configurePlotFontDefaults(PlotItem *plot) { if (plot) { bool configured = false; foreach(PlotItem* plotItem, PlotItemManager::self()->plotsForView(this)) { if (plot != plotItem) { configured = true; plot->setGlobalFont(plotItem->globalFont()); plot->setGlobalFontScale(plotItem->globalFontScale()); plot->setGlobalFontColor(plotItem->globalFontColor()); plot->leftLabelDetails()->setFontUseGlobal(plotItem->leftLabelDetails()->fontUseGlobal()); plot->leftLabelDetails()->setFont(plotItem->leftLabelDetails()->font()); plot->leftLabelDetails()->setFontScale(plotItem->leftLabelDetails()->fontScale()); plot->leftLabelDetails()->setFontColor(plotItem->leftLabelDetails()->fontColor()); plot->rightLabelDetails()->setFontUseGlobal(plotItem->rightLabelDetails()->fontUseGlobal()); plot->rightLabelDetails()->setFont(plotItem->rightLabelDetails()->font()); plot->rightLabelDetails()->setFontScale(plotItem->rightLabelDetails()->fontScale()); plot->rightLabelDetails()->setFontColor(plotItem->rightLabelDetails()->fontColor()); plot->topLabelDetails()->setFontUseGlobal(plotItem->topLabelDetails()->fontUseGlobal()); plot->topLabelDetails()->setFont(plotItem->topLabelDetails()->font()); plot->topLabelDetails()->setFontScale(plotItem->topLabelDetails()->fontScale()); plot->topLabelDetails()->setFontColor(plotItem->topLabelDetails()->fontColor()); plot->bottomLabelDetails()->setFontUseGlobal(plotItem->bottomLabelDetails()->fontUseGlobal()); plot->bottomLabelDetails()->setFont(plotItem->bottomLabelDetails()->font()); plot->bottomLabelDetails()->setFontScale(plotItem->bottomLabelDetails()->fontScale()); plot->bottomLabelDetails()->setFontColor(plotItem->bottomLabelDetails()->fontColor()); plot->numberLabelDetails()->setFontUseGlobal(plotItem->numberLabelDetails()->fontUseGlobal()); plot->numberLabelDetails()->setFont(plotItem->numberLabelDetails()->font()); plot->numberLabelDetails()->setFontScale(plotItem->numberLabelDetails()->fontScale()); plot->numberLabelDetails()->setFontColor(plotItem->numberLabelDetails()->fontColor()); plot->setItemPen(plotItem->pen()); plot->setItemBrush(plotItem->brush()); plot->xAxis()->copyProperties(plotItem->xAxis()); plot->yAxis()->copyProperties(plotItem->yAxis()); break; } } } } void View::contextMenuEvent() { QMenu menu; addTitle(&menu); menu.addAction(_editAction); QMenu layoutMenu; layoutMenu.setTitle(tr("Cleanup Layout")); layoutMenu.addAction(_autoLayoutAction); layoutMenu.addAction(_customLayoutAction); menu.addMenu(&layoutMenu); menu.exec(QCursor::pos()); } void View::addTitle(QMenu *menu) const { QWidgetAction *action = new QWidgetAction(menu); action->setEnabled(false); QLabel *label = new QLabel(tr("View Menu"), menu); label->setAlignment(Qt::AlignCenter); label->setStyleSheet("QLabel {" "border-bottom: 2px solid lightGray;" "font: bold large;" "padding: 3px;" "margin: 1px;" "}"); action->setDefaultWidget(label); menu->addAction(action); } void View::edit() { ViewDialog *editDialog = new ViewDialog(this, kstApp->mainWindow()); editDialog->show(); } void View::viewChanged() { //kstApp->mainWindow()->document()->setChanged(true); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/selectionrect.cpp000644 001750 001750 00000002725 11544160207 021026 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "selectionrect.h" #include SelectionRect::SelectionRect() { reset(); } SelectionRect::~SelectionRect() { } bool SelectionRect::isValid() const { return _validFrom && _validTo && _from != _to; } void SelectionRect::setFrom(const QPointF& point) { _from = point; _validFrom = true; } void SelectionRect::setTo(const QPointF& point) { _to = point; _validTo = true; } void SelectionRect::reset() { _from = _to = QPointF(); _validFrom = _validTo = false; } QRectF SelectionRect::rect() const { if (!isValid()) return QRectF(); return QRectF(_from, _to).normalized(); } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labelcreator.h000644 001750 001750 00000002432 11544160207 020262 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELCREATOR_H #define LABELCREATOR_H #include #include "ui_labelcreator.h" #include "kst_export.h" namespace Kst { class ObjectStore; class LabelCreator : public QDialog, Ui::LabelCreator { Q_OBJECT public: LabelCreator(QWidget *parent = 0); virtual ~LabelCreator(); QString labelText(); qreal labelScale() const; QColor labelColor() const; QFont labelFont() const; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/exportgraphicsdialog.cpp000644 001750 001750 00000011217 11544160207 022401 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "exportgraphicsdialog.h" #include "dialogdefaults.h" #include "mainwindow.h" #include #include #include #include #include #include #include #include namespace Kst { ExportGraphicsDialog::ExportGraphicsDialog(MainWindow *parent) : QDialog(parent) { setupUi(this); _saveLocation->setFile(_dialogDefaults->value("export/filename",QDir::currentPath()).toString()); _autoSaveTimer = new QTimer(this); QStringList formats;// = QPictureIO::outputFormats(); foreach(QByteArray array, QImageWriter::supportedImageFormats()) { formats.append(QString(array)); } _comboBoxFormats->addItems(formats); _comboBoxFormats->setCurrentIndex( _comboBoxFormats->findText(_dialogDefaults->value("export/format","png").toString())); _xSize->setValue(_dialogDefaults->value("export/xsize","1024").toInt()); _ySize->setValue(_dialogDefaults->value("export/ysize","768").toInt()); _comboBoxSizeOption->setCurrentIndex(_dialogDefaults->value("export/sizeOption","0").toInt()); enableWidthHeight(); _saveLocationLabel->setBuddy(_saveLocation->_fileEdit); connect(_autoSaveTimer, SIGNAL(timeout()), this, SLOT(createFile())); connect(_comboBoxSizeOption, SIGNAL(activated(int)), this, SLOT(enableWidthHeight())); connect(_buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); connect(_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(OKClicked())); connect(_buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); } ExportGraphicsDialog::~ExportGraphicsDialog() { } void ExportGraphicsDialog::enableWidthHeight() { int displayOption = _comboBoxSizeOption->currentIndex(); switch (displayOption) { case 0: // Width and Maintain Aspect Ratio _xSize->setEnabled(true); _ySize->setEnabled(false); _widthLabel->setEnabled(true); _heightLabel->setEnabled(false); break; case 1: // Height and Maintain Aspect Ratio _xSize->setEnabled(false); _ySize->setEnabled(true); _widthLabel->setEnabled(false); _heightLabel->setEnabled(true); break; case 2: // Width and Height _xSize->setEnabled(true); _ySize->setEnabled(true); _widthLabel->setEnabled(true); _heightLabel->setEnabled(true); break; case 3: // Size of Square _xSize->setEnabled(true); _ySize->setEnabled(false); _widthLabel->setEnabled(true); _heightLabel->setEnabled(false); break; } } void ExportGraphicsDialog::applyAutosave() { if (_autosave->isChecked()) { _autoSaveTimer->start(_period->value()*1000); } else { _autoSaveTimer->stop(); } } void ExportGraphicsDialog::apply() { applyAutosave(); if (!_autosave->isChecked()) { createFile(); } } void ExportGraphicsDialog::createFile() { QString filename = _saveLocation->file(); QString format = _comboBoxFormats->currentText(); if (_autoExtension->isChecked()) { if (QFileInfo(filename).suffix().toLower() != format.toLower()) { filename += '.' + format; } } _dialogDefaults->setValue("export/filename", filename); _dialogDefaults->setValue("export/format", format); _dialogDefaults->setValue("export/xsize", _xSize->value()); _dialogDefaults->setValue("export/ysize", _ySize->value()); _dialogDefaults->setValue("export/sizeOption", _comboBoxSizeOption->currentIndex()); emit exportGraphics(filename, format, _xSize->value(), _ySize->value(), _comboBoxSizeOption->currentIndex()); } void ExportGraphicsDialog::updateButtons() { bool valid = QFileInfo(_saveLocation->file()).isFile(); _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid); _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(valid); } void ExportGraphicsDialog::OKClicked() { apply(); accept(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/viewprimitivedialog.cpp000644 001750 001750 00000004537 11544160207 022251 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "viewprimitivedialog.h" #include "document.h" #include "objectstore.h" #include "scalarmodel.h" #include "stringmodel.h" #include #include namespace Kst { ViewPrimitiveDialog::ViewPrimitiveDialog(QWidget *parent, Document *doc) : QDialog(parent), _doc(doc) { _model = 0; setupUi(this); setAttribute(Qt::WA_DeleteOnClose); connect(updateButton, SIGNAL(clicked()), this, SLOT(update())); } ViewPrimitiveDialog::~ViewPrimitiveDialog() { deleteModel(); } void ViewPrimitiveDialog::deleteModel() { if (_model) { _tree->setModel(0); delete _model; _model = 0; } } void ViewPrimitiveDialog::update() { deleteModel(); _model = createModel(_doc->objectStore()); _tree->setModel(_model); _tree->header()->setResizeMode(QHeaderView::ResizeToContents); _tree->header()->setStretchLastSection(false); QApplication::processEvents(); _tree->header()->setResizeMode(QHeaderView::Interactive); } ViewStringDialog::ViewStringDialog(QWidget *parent, Document *doc) : ViewPrimitiveDialog(parent, doc) { setWindowTitle(tr("View String Values")); update(); } QAbstractItemModel* ViewStringDialog::createModel(ObjectStore *store) { return new StringModel(store); } ViewScalarDialog::ViewScalarDialog(QWidget *parent, Document *doc) : ViewPrimitiveDialog(parent, doc) { setWindowTitle(tr("View Scalar Values")); update(); } QAbstractItemModel* ViewScalarDialog::createModel(ObjectStore *store) { return new ScalarModel(store); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labelpropertiestab.h000644 001750 001750 00000002753 11544160207 021514 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELPROPERTIESTAB_H #define LABELPROPERTIESTAB_H #include "dialogtab.h" #include "ui_labelpropertiestab.h" #include "kst_export.h" namespace Kst { class LabelPropertiesTab : public DialogTab, Ui::LabelPropertiesTab { Q_OBJECT public: LabelPropertiesTab(QWidget *parent = 0); virtual ~LabelPropertiesTab(); QString labelText() const; void setLabelText(const QString &text); qreal labelScale() const; void setLabelScale(const qreal scale); QColor labelColor() const; void setLabelColor(const QColor &color); QFont labelFont() const; void setLabelFont(const QFont &font); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/overridelabeltab.h000644 001750 001750 00000003664 11544160207 021141 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OVERRIDETAB_H #define OVERRIDETAB_H #include "dialogtab.h" #include "ui_overridelabeltab.h" #include "kst_export.h" namespace Kst { class OverrideLabelTab : public DialogTab, Ui::OverrideLabelTab { Q_OBJECT public: explicit OverrideLabelTab(QString title, QWidget *parent = 0); virtual ~OverrideLabelTab(); QFont labelFont(QFont ref_font) const; bool labelFontDirty() const; void setLabelFont(const QFont &font); qreal labelFontScale() const; bool labelFontScaleDirty() const; void setLabelFontScale(const qreal scale); QColor labelColor() const; bool labelColorDirty() const; void setLabelColor(const QColor &color); bool useDefault() const; bool useDefaultDirty() const; void setUseDefault(const bool useDefault); void setFontSpecsIfDefault(const QFont &font, const qreal scale, const QColor &color); void enableSingleEditOptions(bool enabled); void clearTabValues(); Q_SIGNALS: void useDefaultChanged(bool); private Q_SLOTS: void buttonUpdate(); private: bool _fontDirty; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/changedatasampledialog.cpp000644 001750 001750 00000022542 11544160207 022623 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "changedatasampledialog.h" #include "datacollection.h" #include "datavector.h" #include "objectstore.h" #include "document.h" #include "mainwindow.h" #include "application.h" #include "dialogdefaults.h" #include "updatemanager.h" namespace Kst { ChangeDataSampleDialog::ChangeDataSampleDialog(QWidget *parent) : QDialog(parent) { setupUi(this); MainWindow::setWidgetFlags(this); if (MainWindow *mw = qobject_cast(parent)) { _store = mw->document()->objectStore(); } else { // FIXME: we need the object store qFatal("ERROR: can't construct a ChangeDataSampleDialog without the object store"); } connect(_add, SIGNAL(clicked()), this, SLOT(addButtonClicked())); connect(_remove, SIGNAL(clicked()), this, SLOT(removeButtonClicked())); connect(_removeAll, SIGNAL(clicked()), this, SLOT(removeAll())); connect(_addAll, SIGNAL(clicked()), this, SLOT(addAll())); connect(_vectorList, SIGNAL(itemDoubleClicked ( QListWidgetItem * )), this, SLOT(availableDoubleClicked(QListWidgetItem *))); connect(_selectedVectorList, SIGNAL(itemDoubleClicked ( QListWidgetItem * )), this, SLOT(selectedDoubleClicked(QListWidgetItem *))); connect(_vectorList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_selectedVectorList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_dataRange, SIGNAL(modified()), this, SLOT(modified())); connect(_buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); connect(_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(OKClicked())); connect(_buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); initializeEntries(); updateButtons(); } ChangeDataSampleDialog::~ChangeDataSampleDialog() { } void ChangeDataSampleDialog::show() { updateCurveListDialog(); updateButtons(); QDialog::show(); } void ChangeDataSampleDialog::removeButtonClicked() { foreach (QListWidgetItem* item, _selectedVectorList->selectedItems()) { _vectorList->addItem(_selectedVectorList->takeItem(_selectedVectorList->row(item))); } _vectorList->clearSelection(); updateButtons(); } void ChangeDataSampleDialog::selectedDoubleClicked(QListWidgetItem * item) { if (item) { _vectorList->addItem(_selectedVectorList->takeItem(_selectedVectorList->row(item))); _vectorList->clearSelection(); updateButtons(); } } void ChangeDataSampleDialog::addButtonClicked() { foreach (QListWidgetItem* item, _vectorList->selectedItems()) { _selectedVectorList->addItem(_vectorList->takeItem(_vectorList->row(item))); } _selectedVectorList->clearSelection(); updateButtons(); } void ChangeDataSampleDialog::availableDoubleClicked(QListWidgetItem * item) { if (item) { _selectedVectorList->addItem(_vectorList->takeItem(_vectorList->row(item))); _selectedVectorList->clearSelection(); updateButtons(); } } void ChangeDataSampleDialog::updateButtons() { bool valid = _selectedVectorList->count() > 0; _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid); _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(valid); _add->setEnabled(_vectorList->selectedItems().count() > 0); _addAll->setEnabled(_vectorList->count() > 0); _remove->setEnabled(_selectedVectorList->selectedItems().count() > 0); _removeAll->setEnabled(_selectedVectorList->count() > 0); } void ChangeDataSampleDialog::modified() { updateButtons(); } void ChangeDataSampleDialog::updateCurveListDialog() { DataVectorList dataVectors = _store->getObjects(); _vectorList->blockSignals(true); _vectorList->clearSelection(); _selectedVectorList->clearSelection(); // make sure all items in _vectorList exist in the store; remove if they don't. for (int i_item = 0; i_item < _vectorList->count(); i_item++) { bool exists=false; for (int i_vector = 0; i_vectorName() == _vectorList->item(i_item)->text()) { exists = true; break; } } if (!exists) { QListWidgetItem *item = _vectorList->takeItem(i_item); delete item; } } // make sure all items in _selectedVectorList exist in the store; remove if they don't. for (int i_item = 0; i_item<_selectedVectorList->count(); i_item++) { bool exists=false; for (int i_vector = 0; i_vectorName() == _selectedVectorList->item(i_item)->text()) { exists = true; break; } } if (!exists) { QListWidgetItem *item = _selectedVectorList->takeItem(i_item); delete item; } } // insert into _vectorList all items in store not in one of the lists. for (int i_vector = 0; i_vectorcount(); i_item++) { if (dataVectors.at(i_vector)->Name() == _selectedVectorList->item(i_item)->text()) { _selectedVectorList->item(i_item)->setToolTip(dataVectors.at(i_vector)->descriptionTip()); listed = true; break; } } for (int i_item = 0; i_item<_vectorList->count(); i_item++) { if (dataVectors.at(i_vector)->Name() == _vectorList->item(i_item)->text()) { _vectorList->item(i_item)->setToolTip(dataVectors.at(i_vector)->descriptionTip()); listed = true; break; } } if (!listed) { QListWidgetItem *wi = new QListWidgetItem(dataVectors.at(i_vector)->Name()); _vectorList->addItem(wi); wi->setToolTip(dataVectors.at(i_vector)->descriptionTip()); } } _vectorList->blockSignals(false); } void ChangeDataSampleDialog::addAll() { _vectorList->selectAll(); addButtonClicked(); } void ChangeDataSampleDialog::removeAll() { _selectedVectorList->selectAll(); removeButtonClicked(); } void ChangeDataSampleDialog::initializeEntries() { _dataRange->setCountFromEnd(_dialogDefaults->value("vector/countFromEnd",false).toBool()); _dataRange->setStart(_dialogDefaults->value("vector/start", 0).toInt()); _dataRange->setReadToEnd(_dialogDefaults->value("vector/readToEnd",true).toBool()); _dataRange->setRange(_dialogDefaults->value("vector/range", 1).toInt()); _dataRange->setSkip(_dialogDefaults->value("vector/skip", 0).toInt()); _dataRange->setDoSkip(_dialogDefaults->value("vector/doSkip", false).toBool()); _dataRange->setDoFilter(_dialogDefaults->value("vector/doAve",false).toBool()); } void ChangeDataSampleDialog::updateDefaults(QListWidgetItem* item) { if (!item) { return; } if (DataVectorPtr vector = kst_cast(_store->retrieveObject(item->text()))) { vector->readLock(); _dataRange->setCountFromEnd(vector->countFromEOF()); _dataRange->setStart(vector->countFromEOF() ? 0 : vector->reqStartFrame()); _dataRange->setReadToEnd(vector->readToEOF()); _dataRange->setRange(vector->readToEOF() ? 0 : vector->reqNumFrames()); _dataRange->setSkip(vector->skip()); _dataRange->setDoSkip(vector->doSkip()); _dataRange->setDoFilter(vector->doAve()); vector->unlock(); } } void ChangeDataSampleDialog::OKClicked() { apply(); accept(); } void ChangeDataSampleDialog::apply() { _selectedVectorList->selectAll(); QList selectedItems = _selectedVectorList->selectedItems(); for (int i = 0; i < selectedItems.size(); ++i) { if (DataVectorPtr vector = kst_cast(_store->retrieveObject(selectedItems.at(i)->text()))) { vector->writeLock(); int from = (_dataRange->countFromEnd() ? -1 : (int)_dataRange->start()); int range = (_dataRange->readToEnd() ? -1 : (int)_dataRange->range()); vector->changeFrames( from, range, _dataRange->skip(), _dataRange->doSkip(), _dataRange->doFilter()); vector->registerChange(); vector->unlock(); } } UpdateManager::self()->doUpdates(true); _dialogDefaults->setValue("vector/range", _dataRange->range()); _dialogDefaults->setValue("vector/start", _dataRange->start()); _dialogDefaults->setValue("vector/countFromEnd", _dataRange->countFromEnd()); _dialogDefaults->setValue("vector/readToEnd", _dataRange->readToEnd()); _dialogDefaults->setValue("vector/skip", _dataRange->skip()); _dialogDefaults->setValue("vector/doSkip", _dataRange->doSkip()); _dialogDefaults->setValue("vector/doAve", _dataRange->doFilter()); updateCurveListDialog(); kstApp->mainWindow()->document()->setChanged(true); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/vectortab.ui000644 001750 001750 00000022773 11544160207 020014 0ustar00synthsynth000000 000000 VectorTab 0 0 745 552 0 0 &Generate true false 0 0 &Number of samples: false _numberOfSamples 0 0 The number of samples for the new independent variable. 1000000000 1000 1000 0 0 Fro&m: false _from The minimum value of the independent variable. -10.0 0 0 &to: false _to The maximum value of the independent variable. 10.0 Read from &data source true File name: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter false 0 0 F&ield or column: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _field false 0 Qt::Horizontal QSizePolicy::Expanding 21 0 false &Connect false Co&nfigure... Qt::Horizontal 40 20 10 0 Update type. Use 'Time Interval' for non local data. false 0 0 0 0 Kst::DataRange QWidget
    datarange.h
    Kst::ComboBox QComboBox
    combobox.h
    Kst::DataSourceSelector QWidget
    datasourceselector.h
    kst-2.0.3/src/libkstapp/plotaxis.h000644 001750 001750 00000014562 11544160207 017475 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLOTAXIS_H #define PLOTAXIS_H #include #include "plotitem.h" #include "plotmarkers.h" namespace Kst { class PlotAxis : public QObject { Q_OBJECT public: enum MajorTickMode { None = 0, Coarse = 2, Normal = 5, Fine = 10, VeryFine = 15 }; enum ZoomMode { Auto, AutoBorder, FixedExpression, SpikeInsensitive, MeanCentered }; enum timeUnits {Hour, Minute, Second}; PlotAxis(PlotItem *plotItem, Qt::Orientation orientation); ~PlotAxis(); PlotItem* plotItem() { return _plotItem; } bool isAxisVisible() const; void setAxisVisible(bool visible); MajorTickMode axisMajorTickMode() const; void setAxisMajorTickMode(MajorTickMode mode); int axisMinorTickCount() const; void setAxisMinorTickCount(const int count); bool axisAutoMinorTicks() const; void setAxisAutoMinorTicks(const bool enabled); bool drawAxisMajorTicks() const; void setDrawAxisMajorTicks(const bool draw); bool drawAxisMinorTicks() const; void setDrawAxisMinorTicks(const bool draw); bool drawAxisMajorGridLines() const; void setDrawAxisMajorGridLines(const bool draw); bool drawAxisMinorGridLines() const; void setDrawAxisMinorGridLines(const bool draw); QColor axisMajorGridLineColor() const; void setAxisMajorGridLineColor(const QColor &color); QColor axisMinorGridLineColor() const; void setAxisMinorGridLineColor(const QColor &color); Qt::PenStyle axisMajorGridLineStyle() const; void setAxisMajorGridLineStyle(const Qt::PenStyle style); Qt::PenStyle axisMinorGridLineStyle() const; void setAxisMinorGridLineStyle(const Qt::PenStyle style); qreal axisMajorGridLineWidth() const; void setAxisMajorGridLineWidth(qreal width); qreal axisMinorGridLineWidth() const; void setAxisMinorGridLineWidth(qreal width); int axisSignificantDigits() const; void setAxisSignificantDigits(const int digits); ZoomMode axisZoomMode() const; void setAxisZoomMode(ZoomMode mode); bool axisLog() const; void setAxisLog(bool log); bool axisReversed() const; void setAxisReversed(const bool enabled); bool axisAutoBaseOffset() const; void setAxisAutoBaseOffset(const bool enabled); bool axisBaseOffset() const; void setAxisBaseOffset(const bool enabled); bool axisInterpret() const; void setAxisInterpret(const bool enabled); AxisDisplayType axisDisplay() const; void setAxisDisplay(const AxisDisplayType display); AxisInterpretationType axisInterpretation() const; void setAxisInterpretation(const AxisInterpretationType interpret); int axisLabelRotation() const; void setAxisLabelRotation(const int rotation); PlotMarkers axisPlotMarkers() { return _axisPlotMarkers; } void setAxisPlotMarkers(const PlotMarkers &plotMarkers) { _axisPlotMarkers = plotMarkers; _ticksUpdated = true; } QMap axisLabels() { return _axisLabels; } QList axisMajorTicks() { return _axisMajorTicks; } QList axisMinorTicks() { return _axisMinorTicks; } QString baseLabel() { return _baseLabel; } void saveInPlot(QXmlStreamWriter &xml, QString axisId); bool configureFromXml(QXmlStreamReader &xml, ObjectStore *store); void validateDrawingRegion(QPainter *painter); // return the value and reset. bool ticksUpdated() { bool bReturn = _ticksUpdated; _ticksUpdated = false; return bReturn; } bool isDirty() { return _dirty; } void copyProperties(PlotAxis *source); void saveAsDialogDefaults(const QString &group) const; QString statusBarString(double X); public Q_SLOTS: void updateTicks(bool useOverrideTicks = false); void setTicksUpdated() { _ticksUpdated = true; } private: double convertTimeValueToJD(double valueIn); double convertJDtoDisplayTime(double T); QString convertJDToDateString(double jday, double range_jd); double computeMajorTickSpacing(MajorTickMode majorTickCount, double range); double computeMajorTickSpacing(MajorTickMode majorTickCount, double range, timeUnits time_units); void updateLogTicks(MajorTickMode tickMode); void updateInterpretTicks(MajorTickMode tickMode); void updateLinearTicks(MajorTickMode tickMode); bool isLinearTickMode(); MajorTickMode convertToMajorTickMode(int tickCount, PlotAxis::MajorTickMode old_mode = VeryFine); private: PlotItem *_plotItem; Qt::Orientation _orientation; bool _dirty; ZoomMode _axisZoomMode; bool _isAxisVisible; bool _ticksUpdated; QRectF _labelRect; QMap _axisLabels; QList _axisMajorTicks; QList _axisMinorTicks; QString _baseLabel; bool _axisLog; bool _axisReversed; bool _axisAutoBaseOffset; bool _axisBaseOffset; bool _axisBaseOffsetOverride; bool _axisInterpret; AxisDisplayType _axisDisplay; AxisInterpretationType _axisInterpretation; MajorTickMode _axisMajorTickMode; MajorTickMode _axisOverrideMajorTicks; int _axisMinorTickCount; bool _automaticMinorTicks; int _automaticMinorTickCount; int _axisSignificantDigits; bool _drawAxisMajorTicks; bool _drawAxisMinorTicks; bool _drawAxisMajorGridLines; bool _drawAxisMinorGridLines; QColor _axisMajorGridLineColor; QColor _axisMinorGridLineColor; Qt::PenStyle _axisMajorGridLineStyle; Qt::PenStyle _axisMinorGridLineStyle; qreal _axisMajorGridLineWidth; qreal _axisMinorGridLineWidth; PlotMarkers _axisPlotMarkers; int _labelRotation; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/axistab.h000644 001750 001750 00000010612 11544160207 017255 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef AXISTAB_H #define AXISTAB_H #include "dialogtab.h" #include "plotitem.h" #include "plotdefines.h" #include "ui_axistab.h" #include "kst_export.h" namespace Kst { class AxisTab : public DialogTab, Ui::AxisTab { Q_OBJECT public: AxisTab(QWidget *parent = 0); virtual ~AxisTab(); bool drawAxisMajorTicks() const; bool drawAxisMajorTicksDirty() const; void setDrawAxisMajorTicks(const bool enabled); bool drawAxisMajorGridLines() const; bool drawAxisMajorGridLinesDirty() const; void setDrawAxisMajorGridLines(const bool enabled); bool drawAxisMinorTicks() const; bool drawAxisMinorTicksDirty() const; void setDrawAxisMinorTicks(const bool enabled); bool drawAxisMinorGridLines() const; bool drawAxisMinorGridLinesDirty() const; void setDrawAxisMinorGridLines(const bool enabled); PlotAxis::MajorTickMode axisMajorTickSpacing() const; bool axisMajorTickSpacingDirty() const; void setAxisMajorTickSpacing(PlotAxis::MajorTickMode spacing); Qt::PenStyle axisMajorGridLineStyle() const; bool axisMajorGridLineStyleDirty() const; void setAxisMajorGridLineStyle(Qt::PenStyle style); QColor axisMajorGridLineColor() const; bool axisMajorGridLineColorDirty() const; void setAxisMajorGridLineColor(const QColor &color); qreal axisMajorGridLineWidth() const; bool axisMajorGridLineWidthDirty() const; void setAxisMajorGridLineWidth(qreal width); Qt::PenStyle axisMinorGridLineStyle() const; bool axisMinorGridLineStyleDirty() const; void setAxisMinorGridLineStyle(Qt::PenStyle style); QColor axisMinorGridLineColor() const; bool axisMinorGridLineColorDirty() const; void setAxisMinorGridLineColor(const QColor &color); qreal axisMinorGridLineWidth() const; bool axisMinorGridLineWidthDirty() const; void setAxisMinorGridLineWidth(qreal width); bool isAutoMinorTickCount() const; bool isAutoMinorTickCountDirty() const; void setAutoMinorTickCount(const bool enabled); int axisMinorTickCount() const; bool axisMinorTickCountDirty() const; void setAxisMinorTickCount(const int count); int significantDigits() const; bool significantDigitsDirty() const; void setSignificantDigits(const int digits); bool isLog() const; bool isLogDirty() const; void setLog(const bool enabled); bool isAutoBaseOffset() const; bool isAutoBaseOffsetDirty() const; void setAutoBaseOffset(const bool enabled); bool isBaseOffset() const; bool isBaseOffsetDirty() const; void setBaseOffset(const bool enabled); bool isReversed() const; bool isReversedDirty() const; void setReversed(const bool enabled); bool isInterpret() const; bool isInterpretDirty() const; void setInterpret(const bool enabled); AxisDisplayType axisDisplay() const; bool axisDisplayDirty() const; void setAxisDisplay(AxisDisplayType display); AxisInterpretationType axisInterpretation() const; bool axisInterpretationDirty() const; void setAxisInterpretation(AxisInterpretationType interpretation); int labelRotation() const; bool labelRotationDirty() const; void setLabelRotation(const int rotation); bool hideTopRight() const; bool hideTopRightDirty() const; void setHideTopRight( bool hide); bool hideBottomLeft() const; bool hideBottomLeftDirty() const; void setHideBottomLeft( bool hide); void enableSingleEditOptions(bool enabled); void clearTabValues(); void setAsYAxis(); public Q_SLOTS: void updateButtons(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/labelcreator.cpp000644 001750 001750 00000004426 11544160207 020622 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labelcreator.h" #include "application.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" #include "applicationsettings.h" namespace Kst { LabelCreator::LabelCreator(QWidget *parent) : QDialog(parent) { setupUi(this); setWindowTitle(tr("Create Label Dialog")); _bold->setFixedWidth(32); _bold->setFixedHeight(32); _bold->setIcon(QPixmap(":kst_bold.png")); _italic->setFixedWidth(32); _italic->setFixedHeight(32); _italic->setIcon(QPixmap(":kst_italic.png")); _labelColor->setFixedWidth(32); _labelColor->setFixedHeight(32); _labelText->setObjectStore(kstApp->mainWindow()->document()->objectStore()); QFont defaultFont(ApplicationSettings::self()->defaultFont()); _family->setCurrentFont(defaultFont); _bold->setChecked(defaultFont.bold()); _italic->setChecked(defaultFont.italic()); _labelColor->setColor(ApplicationSettings::self()->defaultFontColor()); _labelFontScale->setValue(ApplicationSettings::self()->defaultFontScale()); } LabelCreator::~LabelCreator() { } QString LabelCreator::labelText() { return _labelText->labelText(); } qreal LabelCreator::labelScale() const { return _labelFontScale->value(); } QColor LabelCreator::labelColor() const { return _labelColor->color(); } QFont LabelCreator::labelFont() const { QFont font(_family->currentFont()); font.setItalic(_italic->isChecked()); font.setBold(_bold->isChecked()); return font; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/pictureitem.h000644 001750 001750 00000003454 11544160207 020162 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PICTUREITEM_H #define PICTUREITEM_H #include "viewitem.h" #include "graphicsfactory.h" namespace Kst { class PictureItem : public ViewItem { Q_OBJECT public: explicit PictureItem(View *parent, const QImage &image = QImage()); ~PictureItem(); virtual void save(QXmlStreamWriter &xml); virtual void paint(QPainter *painter); void setImage(const QImage &image); private: QPixmap _image; }; class CreatePictureCommand : public CreateCommand { public: CreatePictureCommand() : CreateCommand(QObject::tr("Create Picture")) {} CreatePictureCommand(View *view) : CreateCommand(view, QObject::tr("Create Picture")) {} ~CreatePictureCommand() {} void createItem(); }; class PictureItemFactory : public GraphicsFactory { public: PictureItemFactory(); ~PictureItemFactory(); ViewItem* generateGraphics(QXmlStreamReader& stream, ObjectStore *store, View *view, ViewItem *parent = 0); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/dataref.h000644 001750 001750 00000002774 11544160207 017242 0ustar00synthsynth000000 000000 /*************************************************************************** dataref.h ---------------- begin : Feb 22 2006 Copyright (C) 2006, The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAREF_H #define DATAREF_H #include #include struct DataRef { enum Type { DRScalar, DRString, DRVector, DRExpression, DRFit }; DataRef() { type = DRScalar; } DataRef(Type type, const QString& name, const QString& index, double indexValue, const QVariant& value) : type(type), name(name), index(index), indexValue(indexValue), value(value) {} Type type; QString name; QString index; double indexValue; QVariant value; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/exportvectorsdialog.cpp000644 001750 001750 00000017505 11544160207 022274 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 C. Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "exportvectorsdialog.h" #include "dialogdefaults.h" #include "datavector.h" #include "objectstore.h" #include "mainwindow.h" #include "document.h" #include namespace Kst { ExportVectorsDialog::ExportVectorsDialog(QWidget *parent) : QDialog(parent) { setupUi(this); MainWindow::setWidgetFlags(this); _saveLocationLabel->setBuddy(_saveLocation->_fileEdit); _saveLocation->setFile(_dialogDefaults->value("vectorexport/filename",QDir::currentPath()).toString()); if (MainWindow *mw = qobject_cast(parent)) { _store = mw->document()->objectStore(); } else { // FIXME: we need the object store qFatal("ERROR: can't construct a ExportVectorsDialog without the object store"); } connect(_add, SIGNAL(clicked()), this, SLOT(addButtonClicked())); connect(_remove, SIGNAL(clicked()), this, SLOT(removeButtonClicked())); connect(_removeAll, SIGNAL(clicked()), this, SLOT(removeAll())); connect(_addAll, SIGNAL(clicked()), this, SLOT(addAll())); connect(_changeVectorList, SIGNAL(itemDoubleClicked ( QListWidgetItem * )), this, SLOT(availableDoubleClicked(QListWidgetItem *))); connect(_selectedVectorList, SIGNAL(itemDoubleClicked ( QListWidgetItem * )), this, SLOT(selectedDoubleClicked(QListWidgetItem *))); connect(_changeVectorList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_selectedVectorList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButtons())); connect(_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(OKClicked())); connect(_buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply())); } ExportVectorsDialog::~ExportVectorsDialog() { } void ExportVectorsDialog::show() { updateVectorList(); QDialog::show(); } void ExportVectorsDialog::updateVectorList() { VectorList allVectors = _store->getObjects(); QStringList vectorNameList; ObjectList vectors; foreach (VectorPtr P, allVectors) { vectors.append(P); vectorNameList.append(P->Name()); } // make sure all items in _changeVectorList exist in the store; remove if they don't. for (int i_item = 0; i_item < _changeVectorList->count(); i_item++) { bool exists=false; for (int i_vector = 0; i_vectorName() == _changeVectorList->item(i_item)->text()) { exists = true; break; } } if (!exists) { QListWidgetItem *item = _changeVectorList->takeItem(i_item); delete item; } } // make sure all items in _selectedVectorList exist in the store; remove if they don't. for (int i_item = 0; i_item < _selectedVectorList->count(); i_item++) { bool exists=false; for (int i_vector = 0; i_vectorName() == _selectedVectorList->item(i_item)->text()) { exists = true; break; } } if (!exists) { QListWidgetItem *item = _selectedVectorList->takeItem(i_item); delete item; } } // insert into _changeVectorList all items in store not in one of the lists. for (int i_vector = 0; i_vectorcount(); i_item++) { if (vectors.at(i_vector)->Name() == _changeVectorList->item(i_item)->text()) { _changeVectorList->item(i_item)->setToolTip(vectors.at(i_vector)->descriptionTip()); listed = true; break; } } for (int i_item = 0; i_item<_selectedVectorList->count(); i_item++) { if (vectors.at(i_vector)->Name() == _selectedVectorList->item(i_item)->text()) { _selectedVectorList->item(i_item)->setToolTip(vectors.at(i_vector)->descriptionTip()); listed = true; break; } } if (!listed) { QListWidgetItem *wi = new QListWidgetItem(vectors.at(i_vector)->Name()); _changeVectorList->addItem(wi); wi->setToolTip(vectors.at(i_vector)->descriptionTip()); } } updateButtons(); } void ExportVectorsDialog::removeButtonClicked() { foreach (QListWidgetItem* item, _selectedVectorList->selectedItems()) { _changeVectorList->addItem(_selectedVectorList->takeItem(_selectedVectorList->row(item))); } _changeVectorList->clearSelection(); updateButtons(); } void ExportVectorsDialog::selectedDoubleClicked(QListWidgetItem * item) { if (item) { _changeVectorList->addItem(_selectedVectorList->takeItem(_selectedVectorList->row(item))); _changeVectorList->clearSelection(); updateButtons(); } } void ExportVectorsDialog::addButtonClicked() { foreach (QListWidgetItem* item, _changeVectorList->selectedItems()) { _selectedVectorList->addItem(_changeVectorList->takeItem(_changeVectorList->row(item))); } _selectedVectorList->clearSelection(); updateButtons(); } void ExportVectorsDialog::availableDoubleClicked(QListWidgetItem * item) { if (item) { _selectedVectorList->addItem(_changeVectorList->takeItem(_changeVectorList->row(item))); _selectedVectorList->clearSelection(); updateButtons(); } } void ExportVectorsDialog::addAll() { _changeVectorList->selectAll(); addButtonClicked(); } void ExportVectorsDialog::removeAll() { _selectedVectorList->selectAll(); removeButtonClicked(); } void ExportVectorsDialog::updateButtons() { bool valid = _selectedVectorList->count(); QFileInfo qfi(_saveLocation->file()); if (qfi.isFile()) { valid &= qfi.isWritable(); } _buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid); _buttonBox->button(QDialogButtonBox::Apply)->setEnabled(valid); _add->setEnabled(_changeVectorList->selectedItems().count() > 0); _addAll->setEnabled(_changeVectorList->count() > 0); _remove->setEnabled(_selectedVectorList->selectedItems().count() > 0); _removeAll->setEnabled(_selectedVectorList->count() > 0); } void ExportVectorsDialog::OKClicked() { if (apply()) { accept(); } } bool ExportVectorsDialog::apply() { QFile file(_saveLocation->file()); VectorList vectors; QList lengths; if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) return false; QTextStream out(&file); out << "#"; int count = _selectedVectorList->count(); for (int i = 0; i(_store->retrieveObject(_selectedVectorList->item(i)->text())); if (V) { vectors.append(V); out << " " << V->descriptiveName(); lengths << V->length(); } } out << "\n"; int maxLength = 0; for (int i=0; imaxLength) { maxLength = lengths.at(i); } } out.setRealNumberPrecision(14); int ncols = vectors.size(); for (int row = 0; row < maxLength; row++) { for (int col = 0; col < ncols; col++) { out << " " << vectors.at(col)->interpolate(row, maxLength); } out << "\n"; } out.flush(); file.close(); _dialogDefaults->setValue("vectorexport/filename", _saveLocation->file()); return(true); } } kst-2.0.3/src/libkstapp/labelrenderer.h000644 001750 001750 00000010405 11544160207 020430 0ustar00synthsynth000000 000000 /*************************************************************************** labelrenderer.h ------------------ begin : Jun 17 2005 copyright : (C) 2005 by The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELRENDERER_H #define LABELRENDERER_H #include #include #include #include #include #include "vector.h" #include "scalar.h" #include "string.h" #include "kst_export.h" namespace Label { struct RenderedText { QPointF location; QString text; QFont font; QPen pen; }; // inline for speed. class RenderContext : public QObject { Q_OBJECT public: RenderContext(const QFont& font, QPainter *p) : QObject(), p(p), _fm(_font) { x = y = xMax = xStart = 0; ascent = descent = 0; precision = 8; substitute = true; setFont(font); lines = 0; } inline void addToCache(QPointF location, QString &text, QFont &font, QPen &pen) { RenderedText cacheEntry; cacheEntry.location = location; cacheEntry.text = text; cacheEntry.font = font; cacheEntry.pen = pen; cachedText.append(cacheEntry); } inline const QFont& font() const { if (p) { return p->font(); } else { return _font; } } inline void setFont(const QFont& f_in) { QFont f = f_in; _fontSize = f.pointSize(); if (p) { p->setFont(f); _ascent = p->fontMetrics().ascent(); _descent = p->fontMetrics().descent(); _height = p->fontMetrics().height(); _lineSpacing = p->fontMetrics().lineSpacing(); } else { _font = f; _fm = QFontMetrics(_font); _ascent = _fm.ascent(); _lineSpacing = _fm.lineSpacing(); _descent = _fm.descent(); _height = _fm.height(); } } inline void addObject(Kst::VectorPtr vp) { _refObjects.append(vp); //connect(vp, SIGNAL(updated(ObjectPtr)), this, SIGNAL(labelDirty())); } inline void addObject(Kst::ScalarPtr scalar) { _refObjects.append(scalar); //connect(scalar, SIGNAL(updated(ObjectPtr)), this, SIGNAL(labelDirty())); } inline void addObject(Kst::StringPtr string) { _refObjects.append(string); //connect(string, SIGNAL(updated(ObjectPtr)), this, SIGNAL(labelDirty())); } inline int fontSize() const { return _fontSize; } inline int fontAscent() const { return _ascent; } inline int lineSpacing() const { return _lineSpacing; } inline int fontDescent() const { return _descent; } inline int fontHeight() const { return _height; } inline int fontWidth(const QString& txt) const { if (p) { return p->fontMetrics().width(txt); } else { return _fm.width(txt); } } inline bool substituteScalars() const { return substitute; } inline void setSubstituteScalars(bool on) { substitute = on; } int x, y; // Coordinates we're rendering at int xMax, xStart; int ascent, descent; QString fontName; int size; QPainter *p; int precision; bool substitute; QList _refObjects; QPen pen; int lines; QVector cachedText; Q_SIGNALS: void labelDirty(); private: QFont _font; QFontMetrics _fm; int _ascent, _descent, _height, _lineSpacing; // caches to avoid performance problem // with QFont* int _fontSize; }; struct Chunk; void renderLabel(RenderContext& rc, Chunk *fi, bool cache = true); void paintLabel(RenderContext& rc, QPainter *p); } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/plotaxis.cpp000644 001750 001750 00000115313 11544160207 020024 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "plotaxis.h" #include "math_kst.h" #include "settings.h" #include "dialogdefaults.h" #include #define MAJOR_TICK_DEBUG 0 static int FULL_PRECISION = 15; static qreal JD1900 = 2415020.5; static qreal JD1970 = 2440587.5; static qreal JD_RJD = 2400000.0; static qreal JD_MJD = 2400000.5; namespace Kst { PlotAxis::PlotAxis(PlotItem *plotItem, Qt::Orientation orientation) : _plotItem(plotItem), _orientation(orientation), _dirty(true), _axisZoomMode(Auto), _isAxisVisible(true), _ticksUpdated(true), _axisLog(false), _axisReversed(false), _axisAutoBaseOffset(true), _axisBaseOffset(false), _axisBaseOffsetOverride(false), _axisInterpret(false), _axisDisplay(AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS), _axisInterpretation(AXIS_INTERP_CTIME), _axisMajorTickMode(Normal), _axisOverrideMajorTicks(Normal), _axisMinorTickCount(4), _automaticMinorTicks(true), _automaticMinorTickCount(5), _axisSignificantDigits(9), _drawAxisMajorTicks(true), _drawAxisMinorTicks(true), _drawAxisMajorGridLines(true), _drawAxisMinorGridLines(false), _axisMajorGridLineColor(Qt::gray), _axisMinorGridLineColor(Qt::gray), _axisMajorGridLineStyle(Qt::DashLine), _axisMinorGridLineStyle(Qt::DashLine), _axisMajorGridLineWidth(1.0), _axisMinorGridLineWidth(1.0), _axisPlotMarkers(orientation == Qt::Horizontal), _labelRotation(0) { connect(_plotItem, SIGNAL(updateAxes()), this, SLOT(updateTicks())); } PlotAxis::~PlotAxis() { } double PlotAxis::convertJDtoDisplayTime(double T) { switch (_axisDisplay) { case AXIS_DISPLAY_YEAR: T -= JD1900 + 0.5; T *= 1.0/365.25; // FIXME: make sure this is right T += 1900.0; break; case AXIS_DISPLAY_JD: break; case AXIS_DISPLAY_MJD: T -= JD_MJD; break; case AXIS_DISPLAY_RJD: T -= JD_RJD; break; default: break; } return T; } double PlotAxis::convertTimeValueToJD(double valueIn) { double value = valueIn; switch (_axisInterpretation) { case AXIS_INTERP_YEAR: value -= 1900.0; value *= 365.25; // FIXME: seems wrong value += JD1900 + 0.5; break; case AXIS_INTERP_CTIME: value /= 24.0 * 60.0 * 60.0; value += JD1970; break; case AXIS_INTERP_JD: break; case AXIS_INTERP_MJD: value += JD_MJD; break; case AXIS_INTERP_RJD: value += JD_RJD; break; case AXIS_INTERP_AIT: value -= 86400.0 * (365.0 * 12.0 + 3.0); // current difference (seconds) between UTC and AIT // refer to the following for more information: // http://hpiers.obspm.fr/eop-pc/earthor/utc/TAI-UTC_tab.html value -= 32.0; value /= 24.0 * 60.0 * 60.0; value += JD1970; default: break; } return value; } QString PlotAxis::convertJDToDateString(double jd, double range_jd) { QString label; QDate date; int accuracy; range_jd *= 24.0 * 60.0 * 60.0; if (range_jd == 0.0) { accuracy = FULL_PRECISION; } else { accuracy = 1 - int(log10(range_jd)); if (accuracy < 0) { accuracy = 0; } } // utcOffset() is returned in seconds... as it must be since // some time zones are not an integer number of hours offset // from UTC... jd += double(Settings::globalSettings()->utcOffset()) / 86400.0; // get the date from the Julian day number double jd_day = floor(jd); double jd_fraction = jd - jd_day; // gregorian calendar correction if (jd >= 2299160.5) { double tmp = int( ( (jd_day - 1867216.0) - 0.25 ) / 36524.25 ); jd_day += 1.0 + tmp - floor(0.25*tmp); } // correction for half day offset double dDayFraction = jd_fraction + 0.5; if (dDayFraction >= 1.0) { dDayFraction -= 1.0; jd_day += 1.0; } // get time of day from day fraction int hour = int(dDayFraction*24.0); int minute = int((dDayFraction*24.0 - double(hour))*60.0); double second = ((dDayFraction*24.0 - double(hour))*60.0 - double(minute))*60.0; if (accuracy >= 0) { second *= pow(10.0, accuracy); second = floor(second+0.5); second /= pow(10.0,accuracy); if (second >= 60.0) { second -= 60.0; minute++; if (minute == 60) { minute = 0; hour++; if (hour == 24) { hour = 0; } } } } double j2 = jd_day + 1524.0; double j3 = floor(6680.0 + ( (j2 - 2439870.0) - 122.1 )/365.25); double j4 = floor(j3 * 365.25); double j5 = floor((j2 - j4)/30.6001); int day = int(j2 - j4 - floor(j5*30.6001)); int month = int(j5 - 1.0); if (month > 12) { month -= 12; } int year = int(j3 - 4715.0); if (month > 2) { --year; } if (year <= 0) { --year; } // check how many decimal places for the seconds we actually need to show if (accuracy > 0) { QString strSecond; strSecond.sprintf("%02.*f", accuracy, second); for (int i=strSecond.length()-1; i>0; i--) { if (strSecond.at(i) == '0') { accuracy--; } else if (!strSecond.at(i).isDigit()) { break; } } } if (accuracy < 0) { accuracy = 0; } QString seconds; QString hourminute; hourminute.sprintf(" %02d:%02d:", hour, minute); seconds.sprintf("%02.*f", accuracy, second); switch (_axisDisplay) { case AXIS_DISPLAY_YYMMDDHHMMSS_SS: label.sprintf("%d/%02d/%02d", year, month, day); label += hourminute + seconds; break; case AXIS_DISPLAY_DDMMYYHHMMSS_SS: label.sprintf("%02d/%02d/%d", day, month, year); label += hourminute + seconds; break; case AXIS_DISPLAY_QTTEXTDATEHHMMSS_SS: date.setYMD(year, month, day); label = date.toString(Qt::TextDate).toAscii(); label += hourminute + seconds; break; case AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS: date.setYMD(year, month, day); label = date.toString(Qt::LocalDate).toAscii(); label += hourminute + seconds; break; default: label = QString::number(convertJDtoDisplayTime(jd), 'G', FULL_PRECISION-2); break; } return label; } PlotAxis::ZoomMode PlotAxis::axisZoomMode() const { return _axisZoomMode; } void PlotAxis::setAxisZoomMode(ZoomMode mode) { if (_axisZoomMode != mode) { _axisZoomMode = mode; _dirty = true; } } bool PlotAxis::axisLog() const { return _axisLog; } void PlotAxis::setAxisLog(bool log) { if (_axisLog != log) { _axisLog = log; _dirty = true; } } int PlotAxis::axisSignificantDigits() const { return _axisSignificantDigits; } void PlotAxis::setAxisSignificantDigits(const int digits) { if (_axisSignificantDigits != digits) { _axisSignificantDigits = digits; _dirty = true; } } PlotAxis::MajorTickMode PlotAxis::axisMajorTickMode() const { return _axisMajorTickMode; } void PlotAxis::setAxisMajorTickMode(PlotAxis::MajorTickMode mode) { if (_axisMajorTickMode != mode) { _axisMajorTickMode = mode; _dirty = true; } } int PlotAxis::axisMinorTickCount() const { return _axisMinorTickCount; } void PlotAxis::setAxisMinorTickCount(const int count) { if (_axisMinorTickCount != count) { _axisMinorTickCount = count; _dirty = true; } } bool PlotAxis::axisAutoMinorTicks() const { return _automaticMinorTicks; } void PlotAxis::setAxisAutoMinorTicks(const bool enabled) { if (_automaticMinorTicks != enabled) { _automaticMinorTicks = enabled; _dirty = true; } } bool PlotAxis::drawAxisMajorTicks() const { return _drawAxisMajorTicks; } void PlotAxis::setDrawAxisMajorTicks(bool draw) { if (_drawAxisMajorTicks != draw) { _drawAxisMajorTicks = draw; _dirty = true; } } bool PlotAxis::drawAxisMinorTicks() const { return _drawAxisMinorTicks; } void PlotAxis::setDrawAxisMinorTicks(bool draw) { if (_drawAxisMinorTicks != draw) { _drawAxisMinorTicks = draw; _dirty = true; } } bool PlotAxis::drawAxisMajorGridLines() const { return _drawAxisMajorGridLines; } void PlotAxis::setDrawAxisMajorGridLines(bool draw) { if (_drawAxisMajorGridLines != draw) { _drawAxisMajorGridLines = draw; _dirty = true; } } bool PlotAxis::drawAxisMinorGridLines() const { return _drawAxisMinorGridLines; } void PlotAxis::setDrawAxisMinorGridLines(bool draw) { if (_drawAxisMinorGridLines != draw) { _drawAxisMinorGridLines = draw; _dirty = true; } } QColor PlotAxis::axisMajorGridLineColor() const { return _axisMajorGridLineColor; } void PlotAxis::setAxisMajorGridLineColor(const QColor &color) { if (_axisMajorGridLineColor != color) { _axisMajorGridLineColor = color; _dirty = true; } } QColor PlotAxis::axisMinorGridLineColor() const { return _axisMinorGridLineColor; } void PlotAxis::setAxisMinorGridLineColor(const QColor &color) { if (_axisMinorGridLineColor != color) { _axisMinorGridLineColor = color; _dirty = true; } } Qt::PenStyle PlotAxis::axisMajorGridLineStyle() const { return _axisMajorGridLineStyle; } void PlotAxis::setAxisMajorGridLineStyle(const Qt::PenStyle style) { if (_axisMajorGridLineStyle != style) { _axisMajorGridLineStyle = style; _dirty = true; } } Qt::PenStyle PlotAxis::axisMinorGridLineStyle() const { return _axisMinorGridLineStyle; } void PlotAxis::setAxisMinorGridLineStyle(const Qt::PenStyle style) { if (_axisMinorGridLineStyle != style) { _axisMinorGridLineStyle = style; _dirty = true; } } qreal PlotAxis::axisMajorGridLineWidth() const { return _axisMajorGridLineWidth; } void PlotAxis::setAxisMajorGridLineWidth(qreal width) { if (_axisMajorGridLineWidth != width) { _axisMajorGridLineWidth = width; _dirty = true; } } qreal PlotAxis::axisMinorGridLineWidth() const { return _axisMinorGridLineWidth; } void PlotAxis::setAxisMinorGridLineWidth(qreal width) { if (_axisMinorGridLineWidth != width) { _axisMinorGridLineWidth = width; _dirty = true; } } bool PlotAxis::isAxisVisible() const { return _isAxisVisible; } void PlotAxis::setAxisVisible(bool visible) { if (_isAxisVisible == visible) { return; } _isAxisVisible = visible; _dirty = true; } bool PlotAxis::axisReversed() const { return _axisReversed; } void PlotAxis::setAxisReversed(const bool enabled) { if (_axisReversed != enabled) { _axisReversed = enabled; _dirty = true; } } bool PlotAxis::axisAutoBaseOffset() const { return _axisAutoBaseOffset; } void PlotAxis::setAxisAutoBaseOffset(const bool enabled) { if (_axisAutoBaseOffset != enabled) { _axisAutoBaseOffset = enabled; _dirty = true; } } bool PlotAxis::axisBaseOffset() const { return _axisBaseOffset; } void PlotAxis::setAxisBaseOffset(const bool enabled) { if (_axisBaseOffset != enabled) { _axisBaseOffset = enabled; _dirty = true; } } bool PlotAxis::axisInterpret() const { return _axisInterpret; } void PlotAxis::setAxisInterpret(const bool enabled) { if (_axisInterpret != enabled) { _axisInterpret = enabled; _dirty = true; } } AxisDisplayType PlotAxis::axisDisplay() const { return _axisDisplay; } void PlotAxis::setAxisDisplay(const AxisDisplayType display) { if (_axisDisplay != display) { _axisDisplay = display; _dirty = true; } } AxisInterpretationType PlotAxis::axisInterpretation() const { return _axisInterpretation; } void PlotAxis::setAxisInterpretation(const AxisInterpretationType display) { if (_axisInterpretation != display) { _axisInterpretation = display; _dirty = true; } } int PlotAxis::axisLabelRotation() const { return _labelRotation; } void PlotAxis::setAxisLabelRotation(const int rotation) { if (_labelRotation != rotation) { _labelRotation = rotation; _dirty = true; } } // Function validates that the labels will not overlap. Only functions for X-axis. void PlotAxis::validateDrawingRegion(QPainter *painter) { // Always try to use the settings requested. if (_axisOverrideMajorTicks != _axisMajorTickMode) { _axisBaseOffsetOverride = false; updateTicks(); } int flags = Qt::TextSingleLine | Qt::AlignCenter; int rotation = axisLabelRotation(); QTransform t; t.rotate(rotation); QVector labels; QMapIterator iLabelCheck(_axisLabels); while (iLabelCheck.hasNext()) { iLabelCheck.next(); QRectF bound = painter->boundingRect(QRectF(), flags, iLabelCheck.value()); QPointF p; QPolygonF mappedPoly; if (rotation == 0) { if (_orientation == Qt::Horizontal) { p = QPointF(plotItem()->mapXToPlot(iLabelCheck.key()), 0); } else { p = QPointF(0, plotItem()->mapYToPlot(iLabelCheck.key())); } bound.moveCenter(p); mappedPoly = QPolygonF(bound); } else { if (_orientation == Qt::Horizontal) { p = QPointF(plotItem()->mapXToPlot(iLabelCheck.key()) - bound.height() * 0.5, 0); } else { p = QPointF(0, plotItem()->mapYToPlot(iLabelCheck.key()) - bound.height() * 0.5); } mappedPoly = t.map(QPolygonF(bound)); mappedPoly.translate(p - bound.topLeft()); } labels << mappedPoly; } for (int i = 0; i < (labels.count() - 1); i++) { if (!labels[i].intersected(labels[i+1]).isEmpty()) { qreal labelSize; qreal plotSize; PlotAxis::MajorTickMode old_override_major_ticks = _axisOverrideMajorTicks; if (_orientation == Qt::Horizontal) { labelSize = qMax(labels[i].boundingRect().width(), labels[i+1].boundingRect().width()); plotSize = plotItem()->plotRect().width(); } else { labelSize = qMax(labels[i].boundingRect().height(), labels[i+1].boundingRect().height()); plotSize = plotItem()->plotRect().height(); } _axisOverrideMajorTicks = convertToMajorTickMode((plotSize / labelSize) - 1, old_override_major_ticks); if (_axisOverrideMajorTicks == None) { qreal scale = plotSize / (labelSize * (Normal - 1)); if (scale < 1) { plotItem()->scaleAxisLabels(scale); } _axisOverrideMajorTicks = Coarse; } updateTicks(true); break; } } setTicksUpdated(); } PlotAxis::MajorTickMode PlotAxis::convertToMajorTickMode(int tickCount, PlotAxis::MajorTickMode old_mode) { MajorTickMode mode = None; if ((tickCount >= VeryFine) && (old_mode > VeryFine)) { mode = VeryFine; } else if ((tickCount >= Fine) && (old_mode > Fine)) { mode = Fine; } else if ((tickCount >= Normal) && (old_mode > Normal)) { mode = Normal; } else if ((tickCount >= Coarse) && (old_mode > Coarse)) { mode = Coarse; } return mode; } void PlotAxis::updateLogTicks(MajorTickMode tickMode) { QMap labels; QList ticks; QList minTicks; const int format_precision = 5; qreal min = _orientation == Qt::Horizontal ? plotItem()->xMin() : plotItem()->yMin(); qreal max = _orientation == Qt::Horizontal ? plotItem()->xMax() : plotItem()->yMax(); qreal tick; if (max - min <= (double)tickMode*1.5) { // show in logarithmic mode with major ticks nicely labelled and the // specified number of minor ticks between each major label tick = 1.0; } else { // show in logarithmic mode with major ticks nicely labelled and no minor ticks tick = floor((max - min) / (double)tickMode); } int Low = ceil(min); int High = floor(max)+1; bool minorLabels = ((High - Low) <= 1); for (int i = Low - 1; i <= High; i+=tick) { qreal majorPoint = pow(10.0, i); if (majorPoint == 0) majorPoint = -350; if (i >= min && i <= max) { ticks << majorPoint; labels.insert(majorPoint, QString::number(majorPoint, 'g', format_precision)); } if (tick == 1.0) { // draw minor lines bool first = true; qreal powMin = pow(10, min), powMax = pow(10, max); for (int j = 2; j < 10; j++) { qreal minorPoint = majorPoint * j; if (minorPoint >= powMin && minorPoint <= powMax) { minTicks << minorPoint; if (minorLabels && first) { labels.insert(minorPoint, QString::number(minorPoint, 'g', format_precision)); first = false; } } } } } if (minorLabels && !minTicks.isEmpty()) { qreal lastMinorTick = minTicks.last(); if (ticks.isEmpty() || ticks.last() < lastMinorTick) { if (labels.contains(lastMinorTick)) { labels.insert(lastMinorTick, QString::number(lastMinorTick, 'g', format_precision)); } } } if (_axisMajorTicks == ticks && _axisMinorTicks == minTicks && !_dirty) { return; } _dirty = false; _axisMajorTicks = ticks; _axisMinorTicks = minTicks; _ticksUpdated = true; _axisLabels = labels; _baseLabel.clear(); } // returns true if axis is linear ticks // with no specially formatted time. bool PlotAxis::isLinearTickMode() { if (_axisLog) { return false; } if (_axisInterpret) { switch (_axisDisplay) { case AXIS_DISPLAY_YYMMDDHHMMSS_SS: case AXIS_DISPLAY_DDMMYYHHMMSS_SS: case AXIS_DISPLAY_QTTEXTDATEHHMMSS_SS: case AXIS_DISPLAY_QTLOCALDATEHHMMSS_SS: return false; default: return true; } } return true; } void PlotAxis::updateInterpretTicks(MajorTickMode tickMode) { double min; double max; if (_orientation == Qt::Horizontal) { min = plotItem()->projectionRect().left(); max = plotItem()->projectionRect().right(); } else { min = plotItem()->projectionRect().top(); max = plotItem()->projectionRect().bottom(); } double range = max - min; double min_jd = convertTimeValueToJD(min); double max_jd = convertTimeValueToJD(max); double range_jd = fabs(max_jd - min_jd); double base_jd; double range_u; double tickspacing_u; double tickspacing; QString units; double minimum_units = tickMode; // find base_jd, range_u, units if (range_jd > minimum_units*365.0) { // use years range_u = range_jd/365.25; units = i18n(" [Years]"); tickspacing_u = computeMajorTickSpacing(tickMode, range_u); // round base to year; base_jd = floor((min_jd - (JD1900 + 0.5))/365.25) * 365.25 + (JD1900 + 0.5) + 1.0; } else if (range_jd > minimum_units) { // use days range_u = range_jd; units = i18n(" [Days]"); tickspacing_u = computeMajorTickSpacing(tickMode, range_u); // round base to day base_jd = floor(min_jd)+1.0; } else if (range_jd > minimum_units/24.0) { // use hours range_u = range_jd*24.0; units = i18n(" [Hours]"); tickspacing_u = computeMajorTickSpacing(tickMode, range_u, Hour); // round base to hour double d_jd = min_jd - floor(min_jd); base_jd = floor(min_jd) + (floor(d_jd*24.0/tickspacing_u)+1.0)/(24.0/tickspacing_u); } else if (range_jd > minimum_units/(24.0*60.0)) { // use minutes range_u = range_jd*24.0*60.0; units = i18n(" [Minutes]"); tickspacing_u = computeMajorTickSpacing(tickMode, range_u, Minute); double d_jd = min_jd - floor(min_jd); base_jd = floor(min_jd) + (floor(d_jd*24.0*60.0/tickspacing_u)+1.0)/(24.0*60.0/tickspacing_u); } else { // use seconds range_u = range_jd*24.0*3600.0; units = i18n(" [Seconds]"); double d_jd = min_jd - floor(min_jd); tickspacing_u = computeMajorTickSpacing(tickMode, range_u, Second); base_jd = floor(min_jd) + (floor(d_jd*24.0*3600.0/tickspacing_u)+1.0)/(24.0*3600.0/tickspacing_u); if (base_jd < min_jd) base_jd = min_jd; if (base_jd > max_jd) base_jd = min_jd; } tickspacing = tickspacing_u * range/range_u; double base = (base_jd - min_jd) * range/range_jd + min; int i0 = -floor((base-min)/tickspacing); double tick; double first_tick; QMap labels; QList ticks; QList minTicks; QString tick_label; first_tick = base+i0*tickspacing; for (int i_tick = i0; base + i_tick*tickspacing<=max; i_tick++) { tick = base+i_tick*tickspacing; ticks << tick; tick_label = '[' + QString::number(i_tick*tickspacing_u, 'g', FULL_PRECISION-2) + ']'; labels.insert(tick, tick_label); } double minorTickSpacing = 0.0; int desiredTicks; if (_automaticMinorTicks) { desiredTicks = _automaticMinorTickCount; } else { desiredTicks = _axisMinorTickCount; } if (desiredTicks > 0) { minorTickSpacing = tickspacing / double(desiredTicks); } if (minorTickSpacing != 0) { double firstMinorTick = (first_tick - tickspacing) + minorTickSpacing; int i_minor = 0; double nextMinorTick = firstMinorTick; while (1) { nextMinorTick = firstMinorTick + (i_minor++ * minorTickSpacing); if (nextMinorTick > max) break; if (!ticks.contains(nextMinorTick) && (nextMinorTick > min)) { minTicks << nextMinorTick; } } } if (_axisMajorTicks == ticks && _axisMinorTicks == minTicks && !_dirty) { _ticksUpdated = false; return; } _axisLabels = labels; _axisMinorTicks = minTicks; _axisMajorTicks = ticks; _baseLabel = convertJDToDateString(base_jd, range_jd) + units; _dirty = false; _ticksUpdated = true; } QString PlotAxis::statusBarString(double X) { if (_axisInterpret) { double X_jd = convertTimeValueToJD(X); double min; double max; if (_orientation == Qt::Horizontal) { min = plotItem()->projectionRect().left(); max = plotItem()->projectionRect().right(); } else { min = plotItem()->projectionRect().top(); max = plotItem()->projectionRect().bottom(); } double min_jd = convertTimeValueToJD(min); double max_jd = convertTimeValueToJD(max); double range_jd = fabs(max_jd - min_jd); return convertJDToDateString(X_jd, range_jd/100.0); } else { return QString::number(X, 'G', FULL_PRECISION-2); } } void PlotAxis::updateLinearTicks(MajorTickMode tickMode) { QMap labels; QList ticks; QList minTicks; qreal min; qreal max; qreal R; qreal uR; // range in interpreted units qreal uMin; // min and max in interpreted units qreal uMax; qreal drdu = 1.0; // interpreted units per raw units; qreal rOffset = 0.0; // r = drdu*u + rOffset; qreal uMajorTickSpacing; // major Tick spacing in iterpreted units if (_orientation == Qt::Horizontal) { min = plotItem()->projectionRect().left(); max = plotItem()->projectionRect().right(); R = plotItem()->projectionRect().width(); } else { min = plotItem()->projectionRect().top(); max = plotItem()->projectionRect().bottom(); R = plotItem()->projectionRect().height(); } if (_axisInterpret) { uMin = convertJDtoDisplayTime(convertTimeValueToJD(min)); uMax = convertJDtoDisplayTime(convertTimeValueToJD(max)); uR = fabs(uMax - uMin); drdu = (max - min)/(uMax - uMin); rOffset = min - drdu * uMin; } else { uR = R; uMin = min; uMax = max; } uMajorTickSpacing = computeMajorTickSpacing(tickMode, uR); qreal uFirstTick = ceil(uMin / uMajorTickSpacing) * uMajorTickSpacing; qreal firstTick = uFirstTick*drdu + rOffset; qreal majorTickSpacing = uMajorTickSpacing * drdu; int i = 0; qreal lastTick = 12345678; while (1) { qreal uNextTick = uFirstTick + i++ * uMajorTickSpacing; if (fabs(uNextTick) uMax) break; qreal nextTick = uNextTick * drdu + rOffset; if (lastTick == uNextTick) // prevent endless loop break; lastTick = nextTick; ticks << nextTick; // FULL_PRECISION - 2 because round off errors mean you never actually quite get // full precision... labels.insert(nextTick, QString::number(uNextTick, 'g', FULL_PRECISION-2)); } qreal minorTickSpacing = 0; int desiredTicks; if (_automaticMinorTicks) { desiredTicks = _automaticMinorTickCount; } else { desiredTicks = _axisMinorTickCount; } if (desiredTicks > 0) { minorTickSpacing = majorTickSpacing / desiredTicks; } if (minorTickSpacing != 0) { qreal firstMinorTick = (firstTick - majorTickSpacing) + minorTickSpacing; i = 0; qreal nextMinorTick = firstMinorTick; while (1) { nextMinorTick = firstMinorTick + (i++ * minorTickSpacing); if (nextMinorTick > max) break; if (!ticks.contains(nextMinorTick) && nextMinorTick > min) { minTicks << nextMinorTick; } } } if (_axisMajorTicks == ticks && _axisMinorTicks == minTicks && !_dirty) { return; } _dirty = false; _axisMajorTicks = ticks; _axisMinorTicks = minTicks; _ticksUpdated = true; _axisLabels.clear(); _baseLabel.clear(); int longest = 0, shortest = 1000; qreal base=10; QMapIterator iLabel(labels); while (iLabel.hasNext()) { iLabel.next(); if (iLabel.value().length() < shortest) { shortest = iLabel.value().length(); base = iLabel.key(); } if (iLabel.value().length() > longest) { longest = iLabel.value().length(); } } // (shortest > 3) so that you don't use automatic base/offset mode when // it wouldn't actually take up less space. if (_axisBaseOffset || ((longest > _axisSignificantDigits)&&(shortest>3)) || _axisBaseOffsetOverride ) { _baseLabel = QString::number(base, 'g', FULL_PRECISION-2); QMapIterator i(labels); while (i.hasNext()) { i.next(); qreal offset; offset = i.key() - base; QString label, num; if (offset < 0) { label += "-["; offset = offset * -1; } else if (offset > 0) { label += "+["; } if (offset==0.0) { num = "[0"; } else if ((fabs(offset)>9.9E3)||(fabs(offset)<0.99E-3)) { num = QString::number(offset, 'e', 1); } else { num = QString::number(offset, 'g', 5); } label = label + num + ']'; _axisLabels.insert(i.key(), label); } } else { _axisLabels = labels; } } void PlotAxis::updateTicks(bool useOverrideTicks) { MajorTickMode majorTickCount; if (useOverrideTicks) { majorTickCount = _axisOverrideMajorTicks; } else { _axisOverrideMajorTicks = _axisMajorTickMode; majorTickCount = _axisMajorTickMode; _axisBaseOffsetOverride = false; } plotItem()->updateScale(); if (_axisLog) { updateLogTicks(majorTickCount); return; } else if (isLinearTickMode()) { updateLinearTicks(majorTickCount); return; } else { updateInterpretTicks(majorTickCount); return; } } /* * Major ticks are always spaced by D = A*10^B where B is an integer, * and A is 1, 2 or 5. So: 1, 0.02, 50, 2000 are all possible major tick * spacings, but 30 is not. * * A and B are chosen so that there are as close as possible to M major ticks * on the axis (but at least 2). The value of M is set by the requested * MajorTickMode. */ double PlotAxis::computeMajorTickSpacing(MajorTickMode majorTickCount, double R) { qreal M = majorTickCount; qreal B = floor(log10(R/M)); qreal d1 = 1 * pow(10, B); // tick spacing qreal d2 = 2 * pow(10, B); qreal d5 = 5 * pow(10, B); qreal r1 = d1 * M; // tick range qreal r2 = d2 * M; qreal r5 = d5 * M; qreal s1 = qAbs(r1 - R); qreal s2 = qAbs(r2 - R); qreal s5 = qAbs(r5 - R); _automaticMinorTickCount = 5; if (s1 <= s2 && s1 <= s5) { return d1; } else if (s2 <= s5) { if ((M == 2) && (r2 > R)) { return d1; // Minimum ticks not met using d2 using d1 instead } else { _automaticMinorTickCount = 4; return d2; } } else { if ((M == 2) && (r5 > R)) { _automaticMinorTickCount = 4; return d2; // Minimum ticks not met using d5 using d2 instead } else { return d5; } } } // compute the major ticks for hours (base = 24) or min/sec (base = 60) double PlotAxis::computeMajorTickSpacing(MajorTickMode majorTickCount, double R, timeUnits time_units) { double base60list[] = {1.0,2.0,5.0,10.0,20.0,30.0,60.0}; int minorlist_minutes[] = { 6, 4, 5, 5, 4, 6, 4}; int minorlist_seconds[] = { 5, 4, 5, 5, 4, 6, 6}; int n60 = 7; double base24list[] = {1.0,2.0,4.0,6.0,12.0,24.0}; int minorlist_hours[] = { 4, 4, 4, 6, 6, 6}; int n24 = 6; double *baselist; int *minorlist; double n; if (R <= majorTickCount) { return computeMajorTickSpacing(majorTickCount, R); } if (time_units == Hour) { baselist = base24list; minorlist = minorlist_hours; n = n24; } else if (time_units == Minute) { baselist = base60list; minorlist = minorlist_minutes; n = n60; } else if (time_units == Second) { baselist = base60list; minorlist = minorlist_seconds; n = n60; } else { // unknown base - use base 10; return computeMajorTickSpacing(majorTickCount, R); } int best_i=0; double best_err = 1E88; double err; for (int i=0; iisAxisVisible()); setAxisLog(source->axisLog()); setAxisReversed(source->axisReversed()); setAxisBaseOffset(source->axisBaseOffset()); setAxisInterpret(source->axisInterpret()); setAxisInterpretation(source->axisInterpretation()); setAxisDisplay(source->axisDisplay()); setAxisMajorTickMode(source->axisMajorTickMode()); setAxisMinorTickCount(source->axisMinorTickCount()); setAxisAutoMinorTicks(source->axisAutoMinorTicks()); setDrawAxisMajorTicks(source->drawAxisMajorTicks()); setDrawAxisMinorTicks(source->drawAxisMinorTicks()); setDrawAxisMajorGridLines(source->drawAxisMajorGridLines()); setDrawAxisMinorGridLines(source->drawAxisMinorGridLines()); setAxisMajorGridLineColor(source->axisMajorGridLineColor()); setAxisMinorGridLineColor(source->axisMinorGridLineColor()); setAxisMajorGridLineStyle(source->axisMajorGridLineStyle()); setAxisMinorGridLineStyle(source->axisMinorGridLineStyle()); setAxisMajorGridLineWidth(source->axisMinorGridLineWidth()); setAxisMinorGridLineWidth(source->axisMinorGridLineWidth()); setAxisSignificantDigits(source->axisSignificantDigits()); setAxisLabelRotation(source->axisLabelRotation()); setAxisZoomMode(source->axisZoomMode()); } } void PlotAxis::saveAsDialogDefaults(const QString &group) const { _dialogDefaults->setValue(group+"Visible", QVariant(isAxisVisible()).toString()); _dialogDefaults->setValue(group+"Log", QVariant(axisLog()).toString()); _dialogDefaults->setValue(group+"Reversed", QVariant(axisReversed()).toString()); _dialogDefaults->setValue(group+"AutoBaseOffset", QVariant(axisAutoBaseOffset()).toString()); _dialogDefaults->setValue(group+"BaseOffset", QVariant(axisBaseOffset()).toString()); _dialogDefaults->setValue(group+"Interpret", QVariant(axisInterpret()).toString()); _dialogDefaults->setValue(group+"Interpretation", QVariant(axisInterpretation()).toString()); _dialogDefaults->setValue(group+"Display", QVariant(axisDisplay()).toString()); _dialogDefaults->setValue(group+"MajorTickMode", QVariant(axisMajorTickMode()).toString()); _dialogDefaults->setValue(group+"MinorTickCount", QVariant(axisMinorTickCount()).toString()); _dialogDefaults->setValue(group+"AutoMinorTickCount", QVariant(axisAutoMinorTicks()).toString()); _dialogDefaults->setValue(group+"DrawMajorTicks", QVariant(drawAxisMajorTicks()).toString()); _dialogDefaults->setValue(group+"DrawMajorTicks", QVariant(drawAxisMajorTicks()).toString()); _dialogDefaults->setValue(group+"DrawMinorTicks", QVariant(drawAxisMinorTicks()).toString()); _dialogDefaults->setValue(group+"DrawMajorGridLines", QVariant(drawAxisMajorGridLines()).toString()); _dialogDefaults->setValue(group+"DrawMinorGridLines", QVariant(drawAxisMinorGridLines()).toString()); _dialogDefaults->setValue(group+"DrawMajorGridLinecolor", QVariant(axisMajorGridLineColor()).toString()); _dialogDefaults->setValue(group+"DrawMinorGridLinecolor", QVariant(axisMinorGridLineColor()).toString()); _dialogDefaults->setValue(group+"DrawMajorGridLinestyle", QVariant(axisMajorGridLineStyle()).toString()); _dialogDefaults->setValue(group+"DrawMinorGridLinestyle", QVariant(axisMinorGridLineStyle()).toString()); _dialogDefaults->setValue(group+"DrawMajorGridLinewidth", QVariant(axisMajorGridLineWidth()).toString()); _dialogDefaults->setValue(group+"DrawMinorGridLinewidth", QVariant(axisMinorGridLineWidth()).toString()); _dialogDefaults->setValue(group+"SignificantDigits", QVariant(axisSignificantDigits()).toString()); _dialogDefaults->setValue(group+"Rotation", QVariant(axisLabelRotation()).toString()); } void PlotAxis::saveInPlot(QXmlStreamWriter &xml, QString axisId) { xml.writeStartElement("plotaxis"); xml.writeAttribute("id", axisId); xml.writeAttribute("visible", QVariant(isAxisVisible()).toString()); xml.writeAttribute("log", QVariant(axisLog()).toString()); xml.writeAttribute("reversed", QVariant(axisReversed()).toString()); xml.writeAttribute("autobaseoffset", QVariant(axisAutoBaseOffset()).toString()); xml.writeAttribute("baseoffset", QVariant(axisBaseOffset()).toString()); xml.writeAttribute("interpret", QVariant(axisInterpret()).toString()); xml.writeAttribute("interpretation", QVariant(axisInterpretation()).toString()); xml.writeAttribute("display", QVariant(axisDisplay()).toString()); xml.writeAttribute("majortickmode", QVariant(axisMajorTickMode()).toString()); xml.writeAttribute("minortickcount", QVariant(axisMinorTickCount()).toString()); xml.writeAttribute("autominortickcount", QVariant(axisAutoMinorTicks()).toString()); xml.writeAttribute("drawmajorticks", QVariant(drawAxisMajorTicks()).toString()); xml.writeAttribute("drawminorticks", QVariant(drawAxisMinorTicks()).toString()); xml.writeAttribute("drawmajorgridlines", QVariant(drawAxisMajorGridLines()).toString()); xml.writeAttribute("drawminorgridlines", QVariant(drawAxisMinorGridLines()).toString()); xml.writeAttribute("drawmajorgridlinecolor", QVariant(axisMajorGridLineColor()).toString()); xml.writeAttribute("drawminorgridlinecolor", QVariant(axisMinorGridLineColor()).toString()); xml.writeAttribute("drawmajorgridlinestyle", QVariant(axisMajorGridLineStyle()).toString()); xml.writeAttribute("drawminorgridlinestyle", QVariant(axisMinorGridLineStyle()).toString()); xml.writeAttribute("drawmajorgridlinewidth", QVariant(axisMajorGridLineWidth()).toString()); xml.writeAttribute("drawminorgridlinewidth", QVariant(axisMinorGridLineWidth()).toString()); xml.writeAttribute("significantdigits", QVariant(axisSignificantDigits()).toString()); xml.writeAttribute("rotation", QVariant(axisLabelRotation()).toString()); xml.writeAttribute("zoommode", QVariant(axisZoomMode()).toString()); _axisPlotMarkers.saveInPlot(xml); xml.writeEndElement(); } bool PlotAxis::configureFromXml(QXmlStreamReader &xml, ObjectStore *store) { bool validTag = true; QString primaryTag = xml.name().toString(); QXmlStreamAttributes attrs = xml.attributes(); QStringRef av = attrs.value("visible"); if (!av.isNull()) { setAxisVisible(QVariant(av.toString()).toBool()); } av = attrs.value("log"); if (!av.isNull()) { setAxisLog(QVariant(av.toString()).toBool()); } av = attrs.value("reversed"); if (!av.isNull()) { setAxisReversed(QVariant(av.toString()).toBool()); } av = attrs.value("autobaseoffset"); if (!av.isNull()) { setAxisAutoBaseOffset(QVariant(av.toString()).toBool()); } av = attrs.value("baseoffset"); if (!av.isNull()) { setAxisBaseOffset(QVariant(av.toString()).toBool()); } av = attrs.value("interpret"); if (!av.isNull()) { setAxisInterpret(QVariant(av.toString()).toBool()); } av = attrs.value("interpretation"); if (!av.isNull()) { setAxisInterpretation((AxisInterpretationType)QVariant(av.toString()).toInt()); } av = attrs.value("display"); if (!av.isNull()) { setAxisDisplay((AxisDisplayType)QVariant(av.toString()).toInt()); } av = attrs.value("majortickmode"); if (!av.isNull()) { setAxisMajorTickMode((PlotAxis::MajorTickMode)QVariant(av.toString()).toInt()); } av = attrs.value("minortickcount"); if (!av.isNull()) { setAxisMinorTickCount(QVariant(av.toString()).toInt()); } av = attrs.value("autominortickcount"); if (!av.isNull()) { setAxisAutoMinorTicks(QVariant(av.toString()).toBool()); } av = attrs.value("drawmajorticks"); if (!av.isNull()) { setDrawAxisMajorTicks(QVariant(av.toString()).toBool()); } av = attrs.value("drawminorticks"); if (!av.isNull()) { setDrawAxisMinorTicks(QVariant(av.toString()).toBool()); } av = attrs.value("drawmajorgridlines"); if (!av.isNull()) { setDrawAxisMajorGridLines(QVariant(av.toString()).toBool()); } av = attrs.value("drawminorgridlines"); if (!av.isNull()) { setDrawAxisMinorGridLines(QVariant(av.toString()).toBool()); } av = attrs.value("drawmajorgridlinecolor"); if (!av.isNull()) { setAxisMajorGridLineColor(QColor(av.toString())); } av = attrs.value("drawminorgridlinecolor"); if (!av.isNull()) { setAxisMinorGridLineColor(QColor(av.toString())); } av = attrs.value("drawmajorgridlinestyle"); if (!av.isNull()) { setAxisMajorGridLineStyle((Qt::PenStyle)QVariant(av.toString()).toInt()); } av = attrs.value("drawminorgridlinestyle"); if (!av.isNull()) { setAxisMinorGridLineStyle((Qt::PenStyle)QVariant(av.toString()).toInt()); } av = attrs.value("drawmajorgridlinewidth"); if (!av.isNull()) { setAxisMajorGridLineWidth((qreal)QVariant(av.toString()).toDouble()); } av = attrs.value("drawminorgridlinewidth"); if (!av.isNull()) { setAxisMinorGridLineWidth((qreal)QVariant(av.toString()).toDouble()); } av = attrs.value("significantdigits"); if (!av.isNull()) { setAxisSignificantDigits(QVariant(av.toString()).toInt()); } av = attrs.value("rotation"); if (!av.isNull()) { setAxisLabelRotation(QVariant(av.toString()).toInt()); } av = attrs.value("zoommode"); if (!av.isNull()) { setAxisZoomMode((PlotAxis::ZoomMode)av.toString().toInt()); } QString expectedEnd; while (!(xml.isEndElement() && (xml.name().toString() == primaryTag))) { if (xml.isStartElement() && xml.name().toString() == "plotmarkers") { validTag = _axisPlotMarkers.configureFromXml(xml, store); } else if (xml.isEndElement()) { if (xml.name().toString() != expectedEnd) { validTag = false; break; } } xml.readNext(); } return validTag; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/lineitem.cpp000644 001750 001750 00000021425 11544160207 017767 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "lineitem.h" #include "view.h" #include #include #include #include namespace Kst { LineItem::LineItem(View *parent) : ViewItem(parent) { _created = false; setTypeName("Line"); setAllowedGrips(RightMidGrip | LeftMidGrip); setAllowedGripModes(Resize); setAllowsLayout(false); QPen p = pen(); p.setWidthF(1); setPen(p); } LineItem::~LineItem() { } void LineItem::paint(QPainter *painter) { painter->drawLine(line()); } void LineItem::save(QXmlStreamWriter &xml) { if (isVisible()) { xml.writeStartElement("line"); ViewItem::save(xml); xml.writeEndElement(); } } QLineF LineItem::line() const { return QLineF(rect().left(), rect().center().y(), rect().right(), rect().center().y()); } //void LineItem::setLine(const QLineF &line_) { // setPos(line_.p1()); // setViewRect(QRectF(0.0, 0.0, 0.0, sizeOfGrip().height())); // // if (!rect().isEmpty()) { // rotateTowards(line().p2(), line_.p2()); // } // // QRectF r = rect(); // r.setSize(QSizeF(QLineF(line().p1(), line_.p2()).length(), r.height())); // setViewRect(r); //} QPainterPath LineItem::leftMidGrip() const { QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.topLeft(), sizeOfGrip()); grip.moveCenter(QPointF(grip.center().x(), bound.center().y())); QPainterPath path; path.addEllipse(grip); return path; } QPainterPath LineItem::rightMidGrip() const { QRectF bound = gripBoundingRect(); QRectF grip = QRectF(bound.topRight() - QPointF(sizeOfGrip().width(), 0), sizeOfGrip()); grip.moveCenter(QPointF(grip.center().x(), bound.center().y())); QPainterPath path; path.addEllipse(grip); return path; } QPainterPath LineItem::grips() const { QPainterPath grips; grips.addPath(leftMidGrip()); grips.addPath(rightMidGrip()); return grips; } QPointF LineItem::centerOfRotation() const { if (activeGrip() == RightMidGrip) return line().p1(); else if (activeGrip() == LeftMidGrip) return line().p2(); // when creating the object with the mouse, use p1 as the rotation point. // otherwise, use the center if (_created) { return QPointF((line().x1()+line().x2())*0.5, (line().y1()+line().y2())*0.5); } else { return QPointF(line().p1()); } } void LineItem::creationPolygonChanged(View::CreationEvent event) { if (event == View::EscapeEvent) { ViewItem::creationPolygonChanged(event); return; } if (event == View::MousePress) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MousePress)); setPos(poly.first().x(), poly.first().y()); setViewRect(QRectF(0.0, 0.0, 0.0, sizeOfGrip().height())); view()->scene()->addItem(this); return; } if (event == View::MouseMove) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MouseMove)); if (!rect().isEmpty()) { rotateTowards(line().p2(), poly.last()); } QRectF r = rect(); r.setSize(QSizeF(QLineF(line().p1(), poly.last()).length(), r.height())); setViewRect(r); return; } if (event == View::MouseRelease) { const QPolygonF poly = mapFromScene(view()->creationPolygon(View::MouseRelease)); view()->disconnect(this, SLOT(deleteLater())); //Don't delete ourself view()->disconnect(this, SLOT(creationPolygonChanged(View::CreationEvent))); view()->setMouseMode(View::Default); updateViewItemParent(); _created = true; emit creationComplete(); return; } } void LineItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (view()->viewMode() == View::Data) { event->ignore(); return; } if (view()->mouseMode() == View::Default) { if (gripMode() == ViewItem::Move || activeGrip() == NoGrip) { view()->setMouseMode(View::Move); view()->undoStack()->beginMacro(tr("Move")); } else if (gripMode() == ViewItem::Resize) { view()->setMouseMode(View::Resize); view()->undoStack()->beginMacro(tr("Resize")); } } if (activeGrip() == NoGrip) return QGraphicsRectItem::mouseMoveEvent(event); QPointF p = event->pos(); QPointF s = event->scenePos(); if (gripMode() == ViewItem::Resize) { switch(activeGrip()) { case RightMidGrip: resizeRight(p.x() - rightMidGrip().controlPointRect().center().x()); rotateTowards(rightMidGrip().controlPointRect().center(), p); break; case LeftMidGrip: resizeLeft(p.x() - leftMidGrip().controlPointRect().center().x()); rotateTowards(leftMidGrip().controlPointRect().center(), p); break; default: break; } } } void LineItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { ViewItem::mousePressEvent(event); } void LineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { ViewItem::mouseReleaseEvent(event); } void LineItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { ViewItem::mouseDoubleClickEvent(event); } void LineItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { QGraphicsRectItem::hoverMoveEvent(event); if (isSelected()) { QPointF p = event->pos(); if ((isAllowed(RightMidGrip) && rightMidGrip().contains(p)) || (isAllowed(LeftMidGrip) && leftMidGrip().contains(p))) { view()->setCursor(Qt::CrossCursor); } else { view()->setCursor(Qt::SizeAllCursor); } } else { view()->setCursor(Qt::SizeAllCursor); } } void LineItem::updateChildGeometry(const QRectF &oldParentRect, const QRectF &newParentRect) { // parent has been resized: update the line's dimensions: // we would like to have lines in terms of relative endpoint locations, // but instead they are in terms of length (relative to parent width) // and angle, relative to the parent. qreal theta = rotationAngle()*M_PI/180.0; qreal oldL = relativeWidth()*oldParentRect.width(); // we want to keep the endpoints fixed relative to the parent, so // we need to calculate new lengths and angles. qreal newDx = cos(theta)*oldL*newParentRect.width()/oldParentRect.width(); qreal newDy = sin(theta)*oldL*newParentRect.height()/oldParentRect.height(); qreal newWidth = sqrt(newDx*newDx + newDy*newDy); QTransform transform; transform.rotate(atan2(newDy, newDx)*180.0/M_PI); // my brain hurts less for rotations when we center the object at 0,0 QRectF itemRect(-newWidth*0.5, -rect().height()*0.5, newWidth, rect().height()); // we don't now what the parents's origin is, so, add .x() and .y() setPos(relativeCenter().x() * newParentRect.width() + newParentRect.x(), relativeCenter().y() * newParentRect.height()+ newParentRect.y()); setViewRect(itemRect, true); setTransform(transform); setRelativeWidth(newWidth / newParentRect.width()); } void CreateLineCommand::createItem() { _item = new LineItem(_view); _view->setCursor(Qt::CrossCursor); CreateCommand::createItem(); } LineItemFactory::LineItemFactory() : GraphicsFactory() { registerFactory("line", this); } LineItemFactory::~LineItemFactory() { } ViewItem* LineItemFactory::generateGraphics(QXmlStreamReader& xml, ObjectStore *store, View *view, ViewItem *parent) { LineItem *rc = 0; while (!xml.atEnd()) { bool validTag = true; if (xml.isStartElement()) { if (!rc && xml.name().toString() == "line") { Q_ASSERT(!rc); rc = new LineItem(view); if (parent) { rc->setParentViewItem(parent); } // Add any new specialized LineItem Properties here. } else { Q_ASSERT(rc); if (!rc->parse(xml, validTag) && validTag) { ViewItem *i = GraphicsFactory::parse(xml, store, view, rc); if (!i) { } } } } else if (xml.isEndElement()) { if (xml.name().toString() == "line") { break; } else { validTag = false; } } if (!validTag) { qDebug("invalid Tag\n"); Debug::self()->log(QObject::tr("Error creating line object from Kst file."), Debug::Warning); delete rc; return 0; } xml.readNext(); } return rc; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkstapp/defaultlabelpropertiestab.h000644 001750 001750 00000003661 11544160207 023060 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DEFAULTLABELPROPERTIESTAB_H #define DEFAULTLABELPROPERTIESTAB_H #include "dialogtab.h" #include "ui_defaultlabelpropertiestab.h" #include "kst_export.h" namespace Kst { class DefaultLabelPropertiesTab : public DialogTab, Ui_DefaultLabelPropertiesTab { Q_OBJECT public: DefaultLabelPropertiesTab(QWidget *parent = 0); virtual ~DefaultLabelPropertiesTab(); qreal labelScale() const; void setLabelScale(const qreal scale); QColor labelColor() const; void setLabelColor(const QColor &color); QFont labelFont() const; void setLabelFont(const QFont &font); double referenceViewWidth() const; void setReferenceViewWidth(const double width); double referenceViewHeight() const; void setReferenceViewHeight(const double height); int minimumFontSize() const; void setMinimumFontSize(const int points); void checkSizeDefaults(); public Q_SLOTS: void referenceViewSizeComboChanged(int i); }; extern const double A4Width; // A4 with a 1.5 cm margin; extern const double A4Height; // A4 with a 1.5 cm margin; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/differentiation/differentiationconfig.ui000644 001750 001750 00000004404 11544160207 026664 0ustar00synthsynth000000 000000 DifferentiationConfig 0 0 428 44 400 0 0 0 Y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Step (dX): false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/filters/differentiation/differentiation.h000644 001750 001750 00000005227 11544160207 025314 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIFFERENTIATIONPLUGIN_H #define DIFFERENTIATIONPLUGIN_H #include #include #include class DifferentiationSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; virtual QString descriptionTip() const; Kst::VectorPtr vector() const; Kst::ScalarPtr scalarStep() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: DifferentiationSource(Kst::ObjectStore *store); ~DifferentiationSource(); friend class Kst::ObjectStore; }; class DifferentiationPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~DifferentiationPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Filter; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/differentiation/differentiation.pro000644 001750 001750 00000000272 11544160207 025660 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_differentiation) SOURCES += \ differentiation.cpp HEADERS += \ differentiation.h FORMS += differentiationconfig.ui kst-2.0.3/src/plugins/filters/differentiation/kstplugin_differentiation.desktop000644 001750 001750 00000000426 11544160207 030632 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=differentiation X-Kst-Plugin-Author=The University of Toronto Name=Differentiation Data Object Plugin Comment=Implements a Differentiation Data Object Plugin for Kst. kst-2.0.3/src/plugins/filters/differentiation/differentiation.cpp000644 001750 001750 00000017771 11544160207 025656 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "differentiation.h" #include "objectstore.h" #include "ui_differentiationconfig.h" static const QString& VECTOR_IN = "Y Vector"; static const QString& SCALAR_IN = "Scale Scalar"; static const QString& VECTOR_OUT = "dY/dX"; class ConfigDifferentiationPlugin : public Kst::DataObjectConfigWidget, public Ui_DifferentiationConfig { public: ConfigDifferentiationPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_DifferentiationConfig() { setupUi(this); } ~ConfigDifferentiationPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarStep->setObjectStore(store); _scalarStep->setDefaultValue(1.0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarStep, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorsLocked(bool locked = true) { _vector->setEnabled(!locked); } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalar() { return _scalarStep->selectedScalar(); }; void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarStep->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (DifferentiationSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedScalar(source->scalarStep()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Differentiation DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Input Scalar", _scalarStep->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Differentiation DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Input Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarStep = static_cast(object); if (scalarStep) { setSelectedScalar(scalarStep); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; DifferentiationSource::DifferentiationSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } DifferentiationSource::~DifferentiationSource() { } QString DifferentiationSource::_automaticDescriptiveName() const { return QString(vector()->descriptiveName() + " Derivative"); } QString DifferentiationSource::descriptionTip() const { QString tip; tip = i18n("Derivative: %1\n dX: %2\n").arg(Name()).arg(scalarStep()->value()); tip += i18n("\nInput: %1").arg(vector()->descriptionTip()); return tip; } void DifferentiationSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigDifferentiationPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_IN, config->selectedScalar()); } } void DifferentiationSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool DifferentiationSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; if (inputScalar->value() == 0) { _errorString = "Error: Input Scalar Step must be not be 0."; return false; } /* Memory allocation */ outputVector->resize(inputVector->length(), true); outputVector->value()[0] = (inputVector->value()[1] - inputVector->value()[0]) / inputScalar->value(); int i = 1; for (; i < inputVector->length()-1; i++) { outputVector->value()[i] = (inputVector->value()[i+1] - inputVector->value()[i-1])/(2*inputScalar->value()); } outputVector->value()[i] = (inputVector->value()[i] - inputVector->value()[i-1]) / inputScalar->value(); return true; } Kst::VectorPtr DifferentiationSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr DifferentiationSource::scalarStep() const { return _inputScalars[SCALAR_IN]; } QStringList DifferentiationSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList DifferentiationSource::inputScalarList() const { return QStringList( SCALAR_IN ); } QStringList DifferentiationSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList DifferentiationSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList DifferentiationSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList DifferentiationSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void DifferentiationSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString DifferentiationPlugin::pluginName() const { return "Fixed Step Differentiation"; } QString DifferentiationPlugin::pluginDescription() const { return "Computes the discrete derivative of an input vector"; } Kst::DataObject *DifferentiationPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigDifferentiationPlugin* config = static_cast(configWidget)) { DifferentiationSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_IN, config->selectedScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *DifferentiationPlugin::configWidget(QSettings *settingsObject) const { ConfigDifferentiationPlugin *widget = new ConfigDifferentiationPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, DifferentiationPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_bandpass/filterbutterworthbandpassconfig.ui000644 001750 001750 00000007673 11544160207 032132 0ustar00synthsynth000000 000000 FilterButterworthBandPassConfig 0 0 500 100 400 0 0 0 0 0 Input Vector - Y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 Filter Order: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 Central Frequency / Sample Rate: false 0 0 Band width: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/filters/butterworth_bandpass/butterworth_bandpass.pro000755 001750 001750 00000000360 11544160207 030045 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_filterbutterworthbandpass) LIBS += -l$$kstlib(gsl) SOURCES += \ butterworth_bandpass.cpp HEADERS += \ butterworth_bandpass.h FORMS += filterbutterworthbandpassconfig.ui kst-2.0.3/src/plugins/filters/butterworth_bandpass/kstplugin_filter_butterworth_bandpass.desktop000644 001750 001750 00000000444 11544160207 034363 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=filterbutterworthbandpass X-Kst-Plugin-Author=The University of Toronto Name=Filter - Butterworth Band Pass Plugin Comment=Implements a Butterworth Band Pass Filter Plugin for Kst. kst-2.0.3/src/plugins/filters/butterworth_bandpass/butterworth_bandpass.h000644 001750 001750 00000005354 11544160207 027501 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUTTERWORTHBANDPASSPLUGIN_H #define BUTTERWORTHBANDPASSPLUGIN_H #include #include #include class FilterButterworthBandPassSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr orderScalar() const; Kst::ScalarPtr rateScalar() const; Kst::ScalarPtr bandwidthScalar() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FilterButterworthBandPassSource(Kst::ObjectStore *store); ~FilterButterworthBandPassSource(); friend class Kst::ObjectStore; }; class ButterworthBandPassPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~ButterworthBandPassPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Filter; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_bandpass/butterworth_bandpass.cpp000644 001750 001750 00000026425 11544160207 030036 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "butterworth_bandpass.h" #include "objectstore.h" #include "ui_filterbutterworthbandpassconfig.h" #include "../filters.h" static const QString& VECTOR_IN = "Y Vector"; static const QString& SCALAR_ORDER_IN = "Order Scalar"; static const QString& SCALAR_RATE_IN = "Central Frequency / Sample Rate Scalar"; static const QString& SCALAR_BANDWIDTH_IN = "Band width Scalar"; static const QString& VECTOR_OUT = "Y"; class ConfigFilterButterworthBandPassPlugin : public Kst::DataObjectConfigWidget, public Ui_FilterButterworthBandPassConfig { public: ConfigFilterButterworthBandPassPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FilterButterworthBandPassConfig() { setupUi(this); } ~ConfigFilterButterworthBandPassPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarOrder->setObjectStore(store); _scalarRate->setObjectStore(store); _scalarBandwidth->setObjectStore(store); _scalarOrder->setDefaultValue(4); _scalarRate->setDefaultValue(0.052); _scalarBandwidth->setDefaultValue(0.096); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarOrder, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarRate, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarBandwidth, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorsLocked(bool locked = true) { _vector->setEnabled(!locked); } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedOrderScalar() { return _scalarOrder->selectedScalar(); }; void setSelectedOrderScalar(Kst::ScalarPtr scalar) { return _scalarOrder->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedRateScalar() { return _scalarRate->selectedScalar(); }; void setSelectedRateScalar(Kst::ScalarPtr scalar) { return _scalarRate->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedBandwidthScalar() { return _scalarBandwidth->selectedScalar(); }; void setSelectedBandwidthScalar(Kst::ScalarPtr scalar) { return _scalarBandwidth->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FilterButterworthBandPassSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedOrderScalar(source->orderScalar()); setSelectedRateScalar(source->rateScalar()); setSelectedBandwidthScalar(source->bandwidthScalar()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Filter Band Pass Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Order Scalar", _scalarOrder->selectedScalar()->Name()); _cfg->setValue("Central Frequency / Sample Rate Scalar", _scalarRate->selectedScalar()->Name()); _cfg->setValue("Band width Scalar", _scalarBandwidth->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Filter Band Pass Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Order Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* orderScalar = static_cast(object); if (orderScalar) { setSelectedOrderScalar(orderScalar); } scalarName = _cfg->value("Central Frequency / Sample Rate Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* rateScalar = static_cast(object); if (rateScalar) { setSelectedRateScalar(rateScalar); } scalarName = _cfg->value("Band width Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* bandwidthScalar = static_cast(object); if (bandwidthScalar) { setSelectedBandwidthScalar(bandwidthScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FilterButterworthBandPassSource::FilterButterworthBandPassSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FilterButterworthBandPassSource::~FilterButterworthBandPassSource() { } QString FilterButterworthBandPassSource::_automaticDescriptiveName() const { return QString(vector()->descriptiveName() + " Band Pass"); } void FilterButterworthBandPassSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigFilterButterworthBandPassPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar()); setInputScalar(SCALAR_RATE_IN, config->selectedRateScalar()); setInputScalar(SCALAR_BANDWIDTH_IN, config->selectedBandwidthScalar()); } } void FilterButterworthBandPassSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } double filter_calculate( double dFreqValue, Kst::ScalarList scalars ) { double dValue; int order2 = int(2.0 * scalars.at(0)->value()); double lowpass = scalars.at(1)->value() + 0.5*scalars.at(2)->value(); double highpass = scalars.at(1)->value() - 0.5*scalars.at(2)->value(); if( dFreqValue > 0.0 ) { dValue = 1.0 / ( 1.0 + gsl_pow_int( dFreqValue / lowpass, order2) ); dValue *= 1.0 / ( 1.0 + gsl_pow_int( highpass / dFreqValue, order2) ); } else { dValue = 0.0; } return dValue; } bool FilterButterworthBandPassSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr orderScalar = _inputScalars[SCALAR_ORDER_IN]; Kst::ScalarPtr rateScalar = _inputScalars[SCALAR_RATE_IN]; Kst::ScalarPtr bandwidthScalar = _inputScalars[SCALAR_BANDWIDTH_IN]; Kst::VectorPtr outputVector; // maintain kst file compatibility if the output vector name is changed. if (_outputVectors.contains(VECTOR_OUT)) { outputVector = _outputVectors[VECTOR_OUT]; } else { outputVector = _outputVectors.values().at(0); } Kst::ScalarList scalars; scalars.insert(0, orderScalar); scalars.insert(1, rateScalar); scalars.insert(2, bandwidthScalar); Kst::LabelInfo label_info = inputVector->labelInfo(); label_info.name = i18n("Filtered %1").arg(label_info.name); outputVector->setLabelInfo(label_info); return kst_pass_filter( inputVector, scalars, outputVector); } Kst::VectorPtr FilterButterworthBandPassSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr FilterButterworthBandPassSource::orderScalar() const { return _inputScalars[SCALAR_ORDER_IN]; } Kst::ScalarPtr FilterButterworthBandPassSource::rateScalar() const { return _inputScalars[SCALAR_RATE_IN]; } Kst::ScalarPtr FilterButterworthBandPassSource::bandwidthScalar() const { return _inputScalars[SCALAR_BANDWIDTH_IN]; } QStringList FilterButterworthBandPassSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList FilterButterworthBandPassSource::inputScalarList() const { QStringList inputScalars( SCALAR_ORDER_IN ); inputScalars += SCALAR_RATE_IN; inputScalars += SCALAR_BANDWIDTH_IN; return inputScalars; } QStringList FilterButterworthBandPassSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FilterButterworthBandPassSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList FilterButterworthBandPassSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList FilterButterworthBandPassSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FilterButterworthBandPassSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } // Name used to identify the plugin. Used when loading the plugin. QString ButterworthBandPassPlugin::pluginName() const { return "Band Pass Filter"; } QString ButterworthBandPassPlugin::pluginDescription() const { return "Filters a vector with a zero phase band pass filter with a butterworth amplitude response."; } Kst::DataObject *ButterworthBandPassPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigFilterButterworthBandPassPlugin* config = static_cast(configWidget)) { FilterButterworthBandPassSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar()); object->setInputScalar(SCALAR_RATE_IN, config->selectedRateScalar()); object->setInputScalar(SCALAR_BANDWIDTH_IN, config->selectedBandwidthScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *ButterworthBandPassPlugin::configWidget(QSettings *settingsObject) const { ConfigFilterButterworthBandPassPlugin *widget = new ConfigFilterButterworthBandPassPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ButterworthBandPassPlugin, ButterworthBandPassPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/filters.pro000644 001750 001750 00000000473 11544160207 021007 0ustar00synthsynth000000 000000 include($$PWD/../../../config.pri) TEMPLATE = subdirs CONFIG += ordered SUBDIRS += \ despike \ cumulativesum \ differentiation LibExists(gsl) { SUBDIRS += butterworth_bandpass \ butterworth_bandstop \ butterworth_highpass \ butterworth_lowpass } kst-2.0.3/src/plugins/filters/butterworth_lowpass/butterworth_lowpass.cpp000644 001750 001750 00000023217 11544160207 027624 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "butterworth_lowpass.h" #include "objectstore.h" #include "ui_filterbutterworthlowpassconfig.h" #include "scalar.h" #include "../filters.h" static const QString& VECTOR_IN = "Y Vector"; static const QString& SCALAR_ORDER_IN = "Order Scalar"; static const QString& SCALAR_CUTOFF_IN = "Cutoff / Spacing Scalar"; static const QString& VECTOR_OUT = "Y"; class ConfigFilterButterworthLowPassPlugin : public Kst::DataObjectConfigWidget, public Ui_FilterButterworthLowPassConfig { public: ConfigFilterButterworthLowPassPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FilterButterworthLowPassConfig() { setupUi(this); } ~ConfigFilterButterworthLowPassPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarOrder->setObjectStore(store); _scalarCutoff->setObjectStore(store); _scalarOrder->setDefaultValue(4); _scalarCutoff->setDefaultValue(0.1); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarOrder, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarCutoff, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorsLocked(bool locked = true) { _vector->setEnabled(!locked); } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedOrderScalar() { return _scalarOrder->selectedScalar(); }; void setSelectedOrderScalar(Kst::ScalarPtr scalar) { return _scalarOrder->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedCutoffScalar() { return _scalarCutoff->selectedScalar(); }; void setSelectedCutoffScalar(Kst::ScalarPtr scalar) { return _scalarCutoff->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FilterButterworthLowPassSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedOrderScalar(source->orderScalar()); setSelectedCutoffScalar(source->cutoffScalar()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Filter Low Pass Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Order Scalar", _scalarOrder->selectedScalar()->Name()); _cfg->setValue("Cutoff / Spacing Scalar", _scalarCutoff->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Filter Low Pass Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Order Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* orderScalar = static_cast(object); if (orderScalar) { setSelectedOrderScalar(orderScalar); } scalarName = _cfg->value("Cutoff / Spacing Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* cutoffScalar = static_cast(object); if (cutoffScalar) { setSelectedCutoffScalar(cutoffScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FilterButterworthLowPassSource::FilterButterworthLowPassSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FilterButterworthLowPassSource::~FilterButterworthLowPassSource() { } QString FilterButterworthLowPassSource::_automaticDescriptiveName() const { return QString(vector()->descriptiveName() + " Low Pass"); } void FilterButterworthLowPassSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigFilterButterworthLowPassPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar()); setInputScalar(SCALAR_CUTOFF_IN, config->selectedCutoffScalar()); } } void FilterButterworthLowPassSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } double filter_calculate( double dFreqValue, Kst::ScalarList scalars ) { double dValue; dValue = 1.0 / ( 1.0 + pow( dFreqValue / scalars.at(1)->value(), 2.0 * scalars.at(0)->value() ) ); return dValue; } bool FilterButterworthLowPassSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr orderScalar = _inputScalars[SCALAR_ORDER_IN]; Kst::ScalarPtr cutoffScalar = _inputScalars[SCALAR_CUTOFF_IN]; Kst::VectorPtr outputVector; // maintain kst file compatibility if the output vector name is changed. if (_outputVectors.contains(VECTOR_OUT)) { outputVector = _outputVectors[VECTOR_OUT]; } else { outputVector = _outputVectors.values().at(0); } Kst::ScalarList scalars; scalars.insert(0, orderScalar); scalars.insert(1, cutoffScalar); Kst::LabelInfo label_info = inputVector->labelInfo(); label_info.name = i18n("Filtered %1").arg(label_info.name); outputVector->setLabelInfo(label_info); return kst_pass_filter( inputVector, scalars, outputVector); } Kst::VectorPtr FilterButterworthLowPassSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr FilterButterworthLowPassSource::cutoffScalar() const { return _inputScalars[SCALAR_CUTOFF_IN]; } Kst::ScalarPtr FilterButterworthLowPassSource::orderScalar() const { return _inputScalars[SCALAR_ORDER_IN]; } QStringList FilterButterworthLowPassSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList FilterButterworthLowPassSource::inputScalarList() const { QStringList inputScalars( SCALAR_CUTOFF_IN ); inputScalars += SCALAR_ORDER_IN; return inputScalars; } QStringList FilterButterworthLowPassSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FilterButterworthLowPassSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList FilterButterworthLowPassSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList FilterButterworthLowPassSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FilterButterworthLowPassSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } // Name used to identify the plugin. Used when loading the plugin. QString ButterworthLowPassPlugin::pluginName() const { return "Low Pass Filter"; } QString ButterworthLowPassPlugin::pluginDescription() const { return "Filters a vector with a zero phase low pass filter with a butterworth amplitude response."; } Kst::DataObject *ButterworthLowPassPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigFilterButterworthLowPassPlugin* config = static_cast(configWidget)) { FilterButterworthLowPassSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_CUTOFF_IN, config->selectedCutoffScalar()); object->setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *ButterworthLowPassPlugin::configWidget(QSettings *settingsObject) const { ConfigFilterButterworthLowPassPlugin *widget = new ConfigFilterButterworthLowPassPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ButterworthLowPassPlugin, ButterworthLowPassPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_lowpass/butterworth_lowpass.h000644 001750 001750 00000005273 11544160207 027273 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUTTERWORTHLOWPASSPLUGIN_H #define BUTTERWORTHLOWPASSPLUGIN_H #include #include #include class FilterButterworthLowPassSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr orderScalar() const; Kst::ScalarPtr cutoffScalar() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FilterButterworthLowPassSource(Kst::ObjectStore *store); ~FilterButterworthLowPassSource(); friend class Kst::ObjectStore; }; class ButterworthLowPassPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~ButterworthLowPassPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Filter; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_lowpass/butterworth_lowpass.pro000755 001750 001750 00000000421 11544160207 027635 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_filterbutterworthlowpass) LIBS += -l$$kstlib(gsl) !win32:LIBS += -l$$kstlib(gsl)cblas SOURCES += \ butterworth_lowpass.cpp HEADERS += \ butterworth_lowpass.h FORMS += filterbutterworthlowpassconfig.ui kst-2.0.3/src/plugins/filters/butterworth_lowpass/filterbutterworthlowpassconfig.ui000644 001750 001750 00000005744 11544160207 031721 0ustar00synthsynth000000 000000 FilterButterworthLowPassConfig 0 0 423 75 400 0 0 0 Input Vector: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Filter Order: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 Cutoff Frequency / Sample Rate: false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/filters/butterworth_lowpass/kstplugin_filter_butterworth_lowpass.desktop000644 001750 001750 00000000441 11544160207 034152 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=filterbutterworthlowpass X-Kst-Plugin-Author=The University of Toronto Name=Filter - Butterworth Low Pass Plugin Comment=Implements a Butterworth Low Pass Filter Plugin for Kst. kst-2.0.3/src/plugins/filters/cumulativesum/kstplugin_cumulativesum.desktop000644 001750 001750 00000000422 11544160207 030110 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=cumulativesum X-Kst-Plugin-Author=The University of Toronto Name=Cumulative Sum Data Object Plugin Comment=Implements a Cumulative Sum Data Object Plugin for Kst. kst-2.0.3/src/plugins/filters/cumulativesum/cumulativesumconfig.ui000644 001750 001750 00000004402 11544160207 026144 0ustar00synthsynth000000 000000 CumulativeSumConfig 0 0 425 55 400 0 0 0 0 0 Step (dX): false 0 0 Y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/filters/cumulativesum/cumulativesum.cpp000644 001750 001750 00000017462 11544160207 025135 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "cumulativesum.h" #include "objectstore.h" #include "ui_cumulativesumconfig.h" static const QString& VECTOR_IN = "Vector In"; static const QString& SCALAR_IN = "Scale Scalar"; static const QString& VECTOR_OUT = "sum(Y)dX"; class ConfigCumulativeSumPlugin : public Kst::DataObjectConfigWidget, public Ui_CumulativeSumConfig { public: ConfigCumulativeSumPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_CumulativeSumConfig() { setupUi(this); } ~ConfigCumulativeSumPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarStep->setObjectStore(store); _scalarStep->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarStep, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorsLocked(bool locked = true) { _vector->setEnabled(!locked); } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalar() { return _scalarStep->selectedScalar(); }; void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarStep->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (CumulativeSumSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedScalar(source->scalarStep()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Cumulative Sum DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Input Scalar", _scalarStep->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Cumulative Sum DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Input Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarStep = static_cast(object); if (scalarStep) { setSelectedScalar(scalarStep); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; CumulativeSumSource::CumulativeSumSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } CumulativeSumSource::~CumulativeSumSource() { } QString CumulativeSumSource::_automaticDescriptiveName() const { return QString(vector()->descriptiveName() + " Integral"); } QString CumulativeSumSource::descriptionTip() const { QString tip; tip = i18n("Integral: %1\n dX: %2\n").arg(Name()).arg(scalarStep()->value()); tip += i18n("\nInput: %1").arg(vector()->descriptionTip()); return tip; } void CumulativeSumSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigCumulativeSumPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_IN, config->selectedScalar()); } } void CumulativeSumSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool CumulativeSumSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN]; Kst::VectorPtr outputVector; // maintain kst file compatibility if the output vector name is changed. if (_outputVectors.contains(VECTOR_OUT)) { outputVector = _outputVectors[VECTOR_OUT]; } else { outputVector = _outputVectors.values().at(0); } /* Memory allocation */ outputVector->resize(inputVector->length()+1, true); outputVector->value()[0] = 0.0; for (int i = 0; i < inputVector->length(); i++) { outputVector->value()[i+1] = inputVector->value()[i]*inputScalar->value() + outputVector->value()[i]; } return true; } Kst::VectorPtr CumulativeSumSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr CumulativeSumSource::scalarStep() const { return _inputScalars[SCALAR_IN]; } QStringList CumulativeSumSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList CumulativeSumSource::inputScalarList() const { return QStringList( SCALAR_IN ); } QStringList CumulativeSumSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList CumulativeSumSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList CumulativeSumSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList CumulativeSumSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void CumulativeSumSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString CumulativeSumPlugin::pluginName() const { return "Cumulative Sum"; } QString CumulativeSumPlugin::pluginDescription() const { return "Computes the cumulative sum (integral) of the input vector."; } Kst::DataObject *CumulativeSumPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigCumulativeSumPlugin* config = static_cast(configWidget)) { CumulativeSumSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_IN, config->selectedScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *CumulativeSumPlugin::configWidget(QSettings *settingsObject) const { ConfigCumulativeSumPlugin *widget = new ConfigCumulativeSumPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, CumulativeSumPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/cumulativesum/cumulativesum.h000644 001750 001750 00000005211 11544160207 024567 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CUMULATIVESUMPLUGIN_H #define CUMULATIVESUMPLUGIN_H #include #include #include class CumulativeSumSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; virtual QString descriptionTip() const; Kst::VectorPtr vector() const; Kst::ScalarPtr scalarStep() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: CumulativeSumSource(Kst::ObjectStore *store); ~CumulativeSumSource(); friend class Kst::ObjectStore; }; class CumulativeSumPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~CumulativeSumPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Filter; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/cumulativesum/cumulativesum.pro000644 001750 001750 00000000262 11544160207 025141 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_cumulativesum) SOURCES += \ cumulativesum.cpp HEADERS += \ cumulativesum.h FORMS += cumulativesumconfig.ui kst-2.0.3/src/plugins/filters/filters.h000644 001750 001750 00000007602 11544160207 020437 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* * Generic pass filter plugin for KST. * Released under the terms of the GPL */ #include #include #include #include #include #include #include "vector.h" #include "scalar.h" double filter_calculate( double dFreqValue, Kst::ScalarList scalars ); bool kst_pass_filter( Kst::VectorPtr vector, Kst::ScalarList scalars, Kst::VectorPtr outVector) { gsl_fft_real_wavetable* real; gsl_fft_real_workspace* work; gsl_fft_halfcomplex_wavetable* hc; double* pPadded; double dFreqValue; int iLengthData; int iLengthDataPadded; bool bReturn = false; int iStatus; int i; if( scalars.at(1)->value() > 0.0 ) { iLengthData = vector->length(); if( iLengthData > 0 ) { // // round up to the nearest power of 2... // iLengthDataPadded = (int)pow( 2.0, ceil( log10( (double)iLengthData ) / log10( 2.0 ) ) ); pPadded = (double*)malloc( iLengthDataPadded * sizeof( double ) ); if( pPadded != 0L ) { outVector->resize(iLengthData); real = gsl_fft_real_wavetable_alloc( iLengthDataPadded ); if( real != NULL ) { work = gsl_fft_real_workspace_alloc( iLengthDataPadded ); if( work != NULL ) { memcpy( pPadded, vector->value(), iLengthData * sizeof( double ) ); // // linear extrapolation on the padded values... // for( i=iLengthData; ivalue()[iLengthData-1] - (double)( i - iLengthData + 1 ) * ( vector->value()[iLengthData-1] - vector->value()[0] ) / (double)( iLengthDataPadded - iLengthData ); } // // calculate the FFT... // iStatus = gsl_fft_real_transform( pPadded, 1, iLengthDataPadded, real, work ); if( !iStatus ) { // // apply the filter... // for( i=0; ivalue(), pPadded, iLengthData * sizeof( double ) ); bReturn = true; } gsl_fft_halfcomplex_wavetable_free( hc ); } } gsl_fft_real_workspace_free( work ); } gsl_fft_real_wavetable_free( real ); } free( pPadded ); } } } return bReturn; } kst-2.0.3/src/plugins/filters/butterworth_highpass/butterworth_highpass.cpp000644 001750 001750 00000023351 11544160207 030057 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "butterworth_highpass.h" #include "objectstore.h" #include "ui_filterbutterworthhighpassconfig.h" #include "../filters.h" static const QString& VECTOR_IN = "Y Vector"; static const QString& SCALAR_ORDER_IN = "Order Scalar"; static const QString& SCALAR_CUTOFF_IN = "Cutoff / Spacing Scalar"; static const QString& VECTOR_OUT = "Y"; class ConfigFilterButterworthHighPassPlugin : public Kst::DataObjectConfigWidget, public Ui_FilterButterworthHighPassConfig { public: ConfigFilterButterworthHighPassPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FilterButterworthHighPassConfig() { setupUi(this); } ~ConfigFilterButterworthHighPassPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarOrder->setObjectStore(store); _scalarCutoff->setObjectStore(store); _scalarOrder->setDefaultValue(4); _scalarCutoff->setDefaultValue(0.02); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarOrder, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarCutoff, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorsLocked(bool locked = true) { _vector->setEnabled(!locked); } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedOrderScalar() { return _scalarOrder->selectedScalar(); }; void setSelectedOrderScalar(Kst::ScalarPtr scalar) { return _scalarOrder->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedCutoffScalar() { return _scalarCutoff->selectedScalar(); }; void setSelectedCutoffScalar(Kst::ScalarPtr scalar) { return _scalarCutoff->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FilterButterworthHighPassSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedOrderScalar(source->orderScalar()); setSelectedCutoffScalar(source->cutoffScalar()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Filter High Pass Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Order Scalar", _scalarOrder->selectedScalar()->Name()); _cfg->setValue("Cutoff / Spacing Scalar", _scalarCutoff->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Filter High Pass Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Order Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* orderScalar = static_cast(object); if (orderScalar) { setSelectedOrderScalar(orderScalar); } scalarName = _cfg->value("Cutoff / Spacing Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* cutoffScalar = static_cast(object); if (cutoffScalar) { setSelectedCutoffScalar(cutoffScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FilterButterworthHighPassSource::FilterButterworthHighPassSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FilterButterworthHighPassSource::~FilterButterworthHighPassSource() { } QString FilterButterworthHighPassSource::_automaticDescriptiveName() const { return QString(vector()->descriptiveName() + " High Pass"); } void FilterButterworthHighPassSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigFilterButterworthHighPassPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar()); setInputScalar(SCALAR_CUTOFF_IN, config->selectedCutoffScalar()); } } void FilterButterworthHighPassSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } double filter_calculate( double dFreqValue, Kst::ScalarList scalars ) { double dValue; if( dFreqValue > 0.0 ) { dValue = 1.0 / ( 1.0 + pow( scalars.at(1)->value() / dFreqValue, 2.0 * scalars.at(0)->value() ) ); } else { dValue = 0.0; } return dValue; } bool FilterButterworthHighPassSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr orderScalar = _inputScalars[SCALAR_ORDER_IN]; Kst::ScalarPtr cutoffScalar = _inputScalars[SCALAR_CUTOFF_IN]; Kst::VectorPtr outputVector; // maintain kst file compatibility if the output vector name is changed. if (_outputVectors.contains(VECTOR_OUT)) { outputVector = _outputVectors[VECTOR_OUT]; } else { outputVector = _outputVectors.values().at(0); } Kst::ScalarList scalars; scalars.insert(0, orderScalar); scalars.insert(1, cutoffScalar); Kst::LabelInfo label_info = inputVector->labelInfo(); label_info.name = i18n("Filtered %1").arg(label_info.name); outputVector->setLabelInfo(label_info); return kst_pass_filter( inputVector, scalars, outputVector); } Kst::VectorPtr FilterButterworthHighPassSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr FilterButterworthHighPassSource::cutoffScalar() const { return _inputScalars[SCALAR_CUTOFF_IN]; } Kst::ScalarPtr FilterButterworthHighPassSource::orderScalar() const { return _inputScalars[SCALAR_ORDER_IN]; } QStringList FilterButterworthHighPassSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList FilterButterworthHighPassSource::inputScalarList() const { QStringList inputScalars( SCALAR_CUTOFF_IN ); inputScalars += SCALAR_ORDER_IN; return inputScalars; } QStringList FilterButterworthHighPassSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FilterButterworthHighPassSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList FilterButterworthHighPassSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList FilterButterworthHighPassSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FilterButterworthHighPassSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } // Name used to identify the plugin. Used when loading the plugin. QString ButterworthHighPassPlugin::pluginName() const { return "High Pass Filter"; } QString ButterworthHighPassPlugin::pluginDescription() const { return "Filters a vector with a zero phase high pass filter with a butterworth amplitude response."; } Kst::DataObject *ButterworthHighPassPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigFilterButterworthHighPassPlugin* config = static_cast(configWidget)) { FilterButterworthHighPassSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_CUTOFF_IN, config->selectedCutoffScalar()); object->setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *ButterworthHighPassPlugin::configWidget(QSettings *settingsObject) const { ConfigFilterButterworthHighPassPlugin *widget = new ConfigFilterButterworthHighPassPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ButterworthHighPassPlugin, ButterworthHighPassPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_highpass/butterworth_highpass.h000644 001750 001750 00000005302 11544160207 027520 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUTTERWORTHHIGHPASSPLUGIN_H #define BUTTERWORTHHIGHPASSPLUGIN_H #include #include #include class FilterButterworthHighPassSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr orderScalar() const; Kst::ScalarPtr cutoffScalar() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FilterButterworthHighPassSource(Kst::ObjectStore *store); ~FilterButterworthHighPassSource(); friend class Kst::ObjectStore; }; class ButterworthHighPassPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~ButterworthHighPassPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Filter; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_highpass/butterworth_highpass.pro000755 001750 001750 00000000360 11544160207 030073 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_filterbutterworthhighpass) LIBS += -l$$kstlib(gsl) SOURCES += \ butterworth_highpass.cpp HEADERS += \ butterworth_highpass.h FORMS += filterbutterworthhighpassconfig.ui kst-2.0.3/src/plugins/filters/butterworth_highpass/kstplugin_filter_butterworth_highpass.desktop000644 001750 001750 00000000444 11544160207 034411 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=filterbutterworthhighpass X-Kst-Plugin-Author=The University of Toronto Name=Filter - Butterworth High Pass Plugin Comment=Implements a Butterworth High Pass Filter Plugin for Kst. kst-2.0.3/src/plugins/filters/butterworth_highpass/filterbutterworthhighpassconfig.ui000644 001750 001750 00000005746 11544160207 032157 0ustar00synthsynth000000 000000 FilterButterworthHighPassConfig 0 0 429 91 400 0 0 0 Input Vector: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Filter Order: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 Cutoff Frequency / Sample Rate: false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/filters/despike/despike.pro000755 001750 001750 00000000262 11544160207 022406 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_filterdespike) SOURCES += \ filterdespike.cpp HEADERS += \ filterdespike.h FORMS += filterdespikeconfig.ui kst-2.0.3/src/plugins/filters/despike/filterdespike.h000644 001750 001750 00000005265 11544160207 023250 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTERDESPIKEPLUGIN_H #define FILTERDESPIKEPLUGIN_H #include #include #include class FilterDespikeSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; virtual QString descriptionTip() const; Kst::VectorPtr vector() const; Kst::ScalarPtr nSigmaScalar() const; Kst::ScalarPtr spacingScalar() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FilterDespikeSource(Kst::ObjectStore *store); ~FilterDespikeSource(); friend class Kst::ObjectStore; }; class FilterDespikePlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FilterDespikePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Filter; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/despike/filterdespikeconfig.ui000644 001750 001750 00000006050 11544160207 024615 0ustar00synthsynth000000 000000 FilterDespikeConfig 0 0 400 75 400 0 0 0 Input Vector: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Spacing: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 NSigma: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/filters/despike/kstplugin_filter_despike.desktop000644 001750 001750 00000000374 11544160207 026725 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=filterdespike X-Kst-Plugin-Author=The University of Toronto Name=Filter - Despike Plugin Comment=Implements a Despike Filter Plugin for Kst. kst-2.0.3/src/plugins/filters/despike/filterdespike.cpp000644 001750 001750 00000027170 11544160207 023602 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "filterdespike.h" #include "objectstore.h" #include "ui_filterdespikeconfig.h" static const QString& VECTOR_IN = "Y Vector"; static const QString& SCALAR_NSIGMA_IN = "NSigma Scalar"; static const QString& SCALAR_SPACING_IN = "Spacing Scalar"; static const QString& VECTOR_OUT = "Y"; class ConfigWidgetFilterDespikePlugin : public Kst::DataObjectConfigWidget, public Ui_FilterDespikeConfig { public: ConfigWidgetFilterDespikePlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FilterDespikeConfig() { setupUi(this); } ~ConfigWidgetFilterDespikePlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarNSigma->setObjectStore(store); _scalarSpacing->setObjectStore(store); _scalarNSigma->setDefaultValue(5.0); _scalarSpacing->setDefaultValue(1); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarNSigma, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarSpacing, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorsLocked(bool locked = true) { _vector->setEnabled(!locked); } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedNSigmaScalar() { return _scalarNSigma->selectedScalar(); }; void setSelectedNSigmaScalar(Kst::ScalarPtr scalar) { return _scalarNSigma->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedSpacingScalar() { return _scalarSpacing->selectedScalar(); }; void setSelectedSpacingScalar(Kst::ScalarPtr scalar) { return _scalarSpacing->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FilterDespikeSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedNSigmaScalar(source->nSigmaScalar()); setSelectedSpacingScalar(source->spacingScalar()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Filter Despike Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Spacing Scalar", _scalarNSigma->selectedScalar()->Name()); _cfg->setValue("NSigma Scalar", _scalarNSigma->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Filter Despike Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Spacing Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* spacingScalar = static_cast(object); if (spacingScalar) { setSelectedSpacingScalar(spacingScalar); } scalarName = _cfg->value("NSigma Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* nSigmaScalar = static_cast(object); if (nSigmaScalar) { setSelectedNSigmaScalar(nSigmaScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FilterDespikeSource::FilterDespikeSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FilterDespikeSource::~FilterDespikeSource() { } QString FilterDespikeSource::_automaticDescriptiveName() const { return QString(vector()->descriptiveName() + " Despike"); } QString FilterDespikeSource::descriptionTip() const { QString tip; tip = i18n("Despike Filter: %1\n Spacing: %2\n NSigma: %3").arg(Name()).arg(spacingScalar()->value()).arg(nSigmaScalar()->value()); tip += i18n("\nInput: %1").arg(vector()->descriptionTip()); return tip; } void FilterDespikeSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFilterDespikePlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_NSIGMA_IN, config->selectedNSigmaScalar()); setInputScalar(SCALAR_SPACING_IN, config->selectedSpacingScalar()); } } void FilterDespikeSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool FilterDespikeSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr nSigmaScalar = _inputScalars[SCALAR_NSIGMA_IN]; Kst::ScalarPtr spacingScalar = _inputScalars[SCALAR_SPACING_IN]; Kst::VectorPtr outputVector; // maintain kst file compatibility if the output vector name is changed. if (_outputVectors.contains(VECTOR_OUT)) { outputVector = _outputVectors[VECTOR_OUT]; } else { outputVector = _outputVectors.values().at(0); } int N = inputVector->length(); double last_good; double mdev = 0; double cut = nSigmaScalar->value(); int dx = int(spacingScalar->value()); int i; int spike_start = -1; int border = dx*2; if ( (N < 1) || (cut <= 0) || (dx < 1) || (dx > N/2) ) { return false; } /* get mean deviation of 3 pt difference */ for (i=dx; ivalue(i)-(inputVector->value(i-dx) + inputVector->value(i+dx))*0.5); } mdev /= double(N); cut *= mdev; // resize the output array outputVector->resize(inputVector->length(), false); // for first dx points, do a 2 point difference last_good = inputVector->value(0); for (i=0; ivalue(i) - inputVector->value(i+dx))>cut) { if (spike_start<0) { spike_start = i-border; if (spike_start<0) { spike_start = 0; } } } else { if (spike_start>=0) { i += 4*border-1; if (i>=N) { i=N-1; } for (int j=spike_start; j<=i; j++) { outputVector->value()[j] = last_good; } spike_start = -1; } last_good = outputVector->value()[i] = inputVector->value(i); } } // do a 3 point difference where it is possible for (i=dx; ivalue(i) - (inputVector->value(i-dx) + inputVector->value(i+dx))*0.5)>cut) { if (spike_start<0) { spike_start = i-border; if (spike_start<0) { spike_start = 0; } } } else { if (spike_start>=0) { i += 4*border-1; if (i>=N) { i=N-1; } for (int j=spike_start; j<=i; j++) { outputVector->value()[j] = last_good; } spike_start = -1; } else { last_good = outputVector->value()[i] = inputVector->value(i); } } } // do a 2 point difference for lat dx points for (i=N-dx; ivalue(i-dx) - inputVector->value(i))>cut) { if (spike_start<0) { spike_start = i-border; if (spike_start<0) { spike_start = 0; } } } else { if (spike_start>=0) { i += 4*border-1; if (i>=N) { i=N-1; } for (int j=spike_start; j<=i; j++) { outputVector->value()[j] = last_good; } spike_start = -1; } else { last_good = outputVector->value()[i] = inputVector->value(i); } } } Kst::LabelInfo label_info = inputVector->labelInfo(); label_info.name = i18n("Despiked %1").arg(label_info.name); outputVector->setLabelInfo(label_info); return true; } Kst::VectorPtr FilterDespikeSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr FilterDespikeSource::spacingScalar() const { return _inputScalars[SCALAR_SPACING_IN]; } Kst::ScalarPtr FilterDespikeSource::nSigmaScalar() const { return _inputScalars[SCALAR_NSIGMA_IN]; } QStringList FilterDespikeSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList FilterDespikeSource::inputScalarList() const { QStringList inputScalars( SCALAR_NSIGMA_IN ); inputScalars += SCALAR_SPACING_IN; return inputScalars; } QStringList FilterDespikeSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FilterDespikeSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList FilterDespikeSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList FilterDespikeSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FilterDespikeSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } // Name used to identify the plugin. Used when loading the plugin. QString FilterDespikePlugin::pluginName() const { return "Despike Filter"; } QString FilterDespikePlugin::pluginDescription() const { return "Finds and removes spikes using a 3 point difference."; } Kst::DataObject *FilterDespikePlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFilterDespikePlugin* config = static_cast(configWidget)) { FilterDespikeSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_NSIGMA_IN, config->selectedNSigmaScalar()); object->setInputScalar(SCALAR_SPACING_IN, config->selectedSpacingScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FilterDespikePlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFilterDespikePlugin *widget = new ConfigWidgetFilterDespikePlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FilterDespikePlugin, FilterDespikePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_bandstop/butterworth_bandstop.cpp000644 001750 001750 00000026453 11544160207 030075 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "butterworth_bandstop.h" #include "objectstore.h" #include "ui_filterbutterworthbandstopconfig.h" #include "../filters.h" static const QString& VECTOR_IN = "Y Vector"; static const QString& SCALAR_ORDER_IN = "Order Scalar"; static const QString& SCALAR_RATE_IN = "Central Frequency / Sample Rate Scalar"; static const QString& SCALAR_BANDWIDTH_IN = "Band width Scalar"; static const QString& VECTOR_OUT = "Y"; class ConfigFilterButterworthBandStopPlugin : public Kst::DataObjectConfigWidget, public Ui_FilterButterworthBandStopConfig { public: ConfigFilterButterworthBandStopPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FilterButterworthBandStopConfig() { setupUi(this); } ~ConfigFilterButterworthBandStopPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarOrder->setObjectStore(store); _scalarRate->setObjectStore(store); _scalarBandwidth->setObjectStore(store); _scalarOrder->setDefaultValue(4); _scalarRate->setDefaultValue(.2); _scalarBandwidth->setDefaultValue(.02); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarOrder, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarRate, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarBandwidth, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVector(vector); } void setVectorsLocked(bool locked = true) { _vector->setEnabled(!locked); } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedOrderScalar() { return _scalarOrder->selectedScalar(); }; void setSelectedOrderScalar(Kst::ScalarPtr scalar) { return _scalarOrder->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedRateScalar() { return _scalarRate->selectedScalar(); }; void setSelectedRateScalar(Kst::ScalarPtr scalar) { return _scalarRate->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedBandwidthScalar() { return _scalarBandwidth->selectedScalar(); }; void setSelectedBandwidthScalar(Kst::ScalarPtr scalar) { return _scalarBandwidth->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FilterButterworthBandStopSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedOrderScalar(source->orderScalar()); setSelectedRateScalar(source->rateScalar()); setSelectedBandwidthScalar(source->bandwidthScalar()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Filter Band Stop Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Order Scalar", _scalarOrder->selectedScalar()->Name()); _cfg->setValue("Central Frequency / Sample Rate Scalar", _scalarRate->selectedScalar()->Name()); _cfg->setValue("Band width Scalar", _scalarBandwidth->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Filter Band Stop Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Order Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* orderScalar = static_cast(object); if (orderScalar) { setSelectedOrderScalar(orderScalar); } scalarName = _cfg->value("Central Frequency / Sample Rate Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* rateScalar = static_cast(object); if (rateScalar) { setSelectedRateScalar(rateScalar); } scalarName = _cfg->value("Band width Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* bandwidthScalar = static_cast(object); if (bandwidthScalar) { setSelectedBandwidthScalar(bandwidthScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FilterButterworthBandStopSource::FilterButterworthBandStopSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FilterButterworthBandStopSource::~FilterButterworthBandStopSource() { } QString FilterButterworthBandStopSource::_automaticDescriptiveName() const { return QString(vector()->descriptiveName() + " Band Stop"); } void FilterButterworthBandStopSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigFilterButterworthBandStopPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar()); setInputScalar(SCALAR_RATE_IN, config->selectedRateScalar()); setInputScalar(SCALAR_BANDWIDTH_IN, config->selectedBandwidthScalar()); } } void FilterButterworthBandStopSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } double filter_calculate( double dFreqValue, Kst::ScalarList scalars ) { double dValue; int order2 = int(2.0 * scalars.at(0)->value()); double lowpass = scalars.at(1)->value() + 0.5*scalars.at(2)->value(); double highpass = scalars.at(1)->value() - 0.5*scalars.at(2)->value(); if( dFreqValue > 0.0 ) { dValue = 1.0 / ( 1.0 + gsl_pow_int( dFreqValue / lowpass, order2) ); dValue *= 1.0 / ( 1.0 + gsl_pow_int( highpass / dFreqValue, order2) ); dValue = 1.0 - dValue; } else { dValue = 0.0; } return dValue; } bool FilterButterworthBandStopSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr orderScalar = _inputScalars[SCALAR_ORDER_IN]; Kst::ScalarPtr rateScalar = _inputScalars[SCALAR_RATE_IN]; Kst::ScalarPtr bandwidthScalar = _inputScalars[SCALAR_BANDWIDTH_IN]; Kst::VectorPtr outputVector; // maintain kst file compatibility if the output vector name is changed. if (_outputVectors.contains(VECTOR_OUT)) { outputVector = _outputVectors[VECTOR_OUT]; } else { outputVector = _outputVectors.values().at(0); } Kst::ScalarList scalars; scalars.insert(0, orderScalar); scalars.insert(1, rateScalar); scalars.insert(2, bandwidthScalar); Kst::LabelInfo label_info = inputVector->labelInfo(); label_info.name = i18n("Filtered %1").arg(label_info.name); outputVector->setLabelInfo(label_info); return kst_pass_filter( inputVector, scalars, outputVector); } Kst::VectorPtr FilterButterworthBandStopSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr FilterButterworthBandStopSource::orderScalar() const { return _inputScalars[SCALAR_ORDER_IN]; } Kst::ScalarPtr FilterButterworthBandStopSource::rateScalar() const { return _inputScalars[SCALAR_RATE_IN]; } Kst::ScalarPtr FilterButterworthBandStopSource::bandwidthScalar() const { return _inputScalars[SCALAR_BANDWIDTH_IN]; } QStringList FilterButterworthBandStopSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList FilterButterworthBandStopSource::inputScalarList() const { QStringList inputScalars( SCALAR_ORDER_IN ); inputScalars += SCALAR_RATE_IN; inputScalars += SCALAR_BANDWIDTH_IN; return inputScalars; } QStringList FilterButterworthBandStopSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FilterButterworthBandStopSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList FilterButterworthBandStopSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList FilterButterworthBandStopSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FilterButterworthBandStopSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } // Name used to identify the plugin. Used when loading the plugin. QString ButterworthBandStopPlugin::pluginName() const { return "Band Stop Filter"; } QString ButterworthBandStopPlugin::pluginDescription() const { return "Filters a vector with a zero phase band stop filter with a butterworth amplitude response."; } Kst::DataObject *ButterworthBandStopPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigFilterButterworthBandStopPlugin* config = static_cast(configWidget)) { FilterButterworthBandStopSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar()); object->setInputScalar(SCALAR_RATE_IN, config->selectedRateScalar()); object->setInputScalar(SCALAR_BANDWIDTH_IN, config->selectedBandwidthScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *ButterworthBandStopPlugin::configWidget(QSettings *settingsObject) const { ConfigFilterButterworthBandStopPlugin *widget = new ConfigFilterButterworthBandStopPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ButterworthBandStopPlugin, ButterworthBandStopPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_bandstop/butterworth_bandstop.pro000755 001750 001750 00000000360 11544160207 030103 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_filterbutterworthbandstop) LIBS += -l$$kstlib(gsl) SOURCES += \ butterworth_bandstop.cpp HEADERS += \ butterworth_bandstop.h FORMS += filterbutterworthbandstopconfig.ui kst-2.0.3/src/plugins/filters/butterworth_bandstop/butterworth_bandstop.h000644 001750 001750 00000005354 11544160207 027537 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUTTERWORTHBANDSTOPPLUGIN_H #define BUTTERWORTHBANDSTOPPLUGIN_H #include #include #include class FilterButterworthBandStopSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr orderScalar() const; Kst::ScalarPtr rateScalar() const; Kst::ScalarPtr bandwidthScalar() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FilterButterworthBandStopSource(Kst::ObjectStore *store); ~FilterButterworthBandStopSource(); friend class Kst::ObjectStore; }; class ButterworthBandStopPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~ButterworthBandStopPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Filter; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/filters/butterworth_bandstop/kstplugin_filter_butterworth_bandstop.desktop000644 001750 001750 00000000444 11544160207 034421 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=filterbutterworthbandstop X-Kst-Plugin-Author=The University of Toronto Name=Filter - Butterworth Band Stop Plugin Comment=Implements a Butterworth Band Stop Filter Plugin for Kst. kst-2.0.3/src/plugins/filters/butterworth_bandstop/filterbutterworthbandstopconfig.ui000644 001750 001750 00000010616 11544160207 032157 0ustar00synthsynth000000 000000 FilterButterworthBandStopConfig 0 0 400 103 400 0 0 0 Input Vector: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Filter Order: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Central Frequency / Sample Rate: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Band width: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/plugins.pri000644 001750 001750 00000000110 11544160207 017326 0ustar00synthsynth000000 000000 include($$PWD/../../kst.pri) include($$PWD/../../dataobjectplugin.pri) kst-2.0.3/src/plugins/plugins_sub.pri000644 001750 001750 00000000054 11544160207 020206 0ustar00synthsynth000000 000000 TOPOUT_REL=../../../.. include(plugins.pri) kst-2.0.3/src/plugins/plugins_subsub.pri000644 001750 001750 00000000060 11544160207 020715 0ustar00synthsynth000000 000000 TOPOUT_REL=../../../../.. include(plugins.pri) kst-2.0.3/src/plugins/plugins.pro000644 001750 001750 00000000265 11544160207 017347 0ustar00synthsynth000000 000000 include($$PWD/../../config.pri) TEMPLATE = subdirs CONFIG += ordered DEMOS += \ sampleplugin SUBDIRS += \ filters \ dataobject LibExists(gsl) { SUBDIRS += fits } kst-2.0.3/src/plugins/fits/gradient_weighted/fitgradient_weighted.cpp000644 001750 001750 00000027350 11544160207 026456 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitgradient_weighted.h" #include "objectstore.h" #include "ui_fitgradient_weightedconfig.h" #include #include "../common.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_IN_WEIGHTS = "Weights Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& VECTOR_OUT_Y_LO = "Lo Vector"; static const QString& VECTOR_OUT_Y_HI = "Hi Vector"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitGradientWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitGradient_WeightedConfig { public: ConfigWidgetFitGradientWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitGradient_WeightedConfig() { setupUi(this); } ~ConfigWidgetFitGradientWeightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorWeights->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorWeights, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorWeights() { return _vectorWeights->selectedVector(); }; void setSelectedVectorWeights(Kst::VectorPtr vector) { return _vectorWeights->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitGradientWeightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorWeights(source->vectorWeights()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Gradient Weighted Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector Weights", _vectorWeights->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Gradient Weighted Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } vectorName = _cfg->value("Input Vector Weights").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorweights = static_cast(object); if (vectorweights) { setSelectedVectorX(vectorweights); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitGradientWeightedSource::FitGradientWeightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitGradientWeightedSource::~FitGradientWeightedSource() { } QString FitGradientWeightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Weighted Gradient"); } void FitGradientWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitGradientWeightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } } void FitGradientWeightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputVector(VECTOR_OUT_Y_LO, ""); setOutputVector(VECTOR_OUT_Y_HI, ""); setOutputScalar(SCALAR_OUT, ""); } bool FitGradientWeightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorWeights = _inputVectors[VECTOR_IN_WEIGHTS]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::VectorPtr outputVectorYLo = _outputVectors[VECTOR_OUT_Y_LO]; Kst::VectorPtr outputVectorYHi = _outputVectors[VECTOR_OUT_Y_HI]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Gradient Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Gradient Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); label_info.name = i18n("Gradient Fit Lower Limit"); outputVectorYLo->setLabelInfo(label_info); label_info.name = i18n("Gradient Fit Upper Limit"); outputVectorYHi->setLabelInfo(label_info); int i = 0; int iLength; bool bReturn = false; double* pInputs[3]; double c0 = 0.0; double cov00 = 0.0; double dSumSq = 0.0; double y; double yErr; if( precursor( inputVectorX, inputVectorY, inputVectorWeights, &iLength, true, true, 2, pInputs, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputVectorYLo, outputVectorYHi ) ) { if( !gsl_fit_wmul( pInputs[XVALUES], 1, pInputs[WEIGHTS], 1, pInputs[YVALUES], 1, iLength, &c0, &cov00, &dSumSq ) ) { for( i=0; ivalue()[i] = y; outputVectorYResiduals->value()[i] = pInputs[YVALUES][i] - y; outputVectorYLo->value()[i] = y - yErr; outputVectorYHi->value()[i] = y + yErr; } outputVectorYParameters->value()[0] = c0; outputVectorYCovariance->value()[0] = cov00; outputScalar->setValue(dSumSq / ( (double)iLength - 2.0 )); bReturn = true; } } postcursor( true, pInputs ); return bReturn; } Kst::VectorPtr FitGradientWeightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitGradientWeightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr FitGradientWeightedSource::vectorWeights() const { return _inputVectors[VECTOR_IN_WEIGHTS]; } QStringList FitGradientWeightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_WEIGHTS; return vectors; } QStringList FitGradientWeightedSource::inputScalarList() const { return QStringList(); } QStringList FitGradientWeightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitGradientWeightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_LO; vectors += VECTOR_OUT_Y_HI; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitGradientWeightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitGradientWeightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitGradientWeightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitGradientWeightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Gradient"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitGradientWeightedPlugin::pluginName() const { return "Gradient Weighted Fit"; } QString FitGradientWeightedPlugin::pluginDescription() const { return "Generates a gradient weighted fit for a set of data."; } Kst::DataObject *FitGradientWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitGradientWeightedPlugin* config = static_cast(configWidget)) { FitGradientWeightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitGradientWeightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitGradientWeightedPlugin *widget = new ConfigWidgetFitGradientWeightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitGradientWeightedPlugin, FitGradientWeightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/gradient_weighted/kstplugin_fits_gradient_weighted.desktop000644 001750 001750 00000000423 11544160207 031757 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitgradient_weighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Gradient Weighted Plugin Comment=Implements a Gradient Weighted Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/gradient_weighted/fitgradient_weighted.h000644 001750 001750 00000005340 11544160207 026116 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITGRADIENTWEIGHTEDPLUGIN_H #define FITGRADIENTWEIGHTEDPLUGIN_H #include #include #include class FitGradientWeightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorWeights() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitGradientWeightedSource(Kst::ObjectStore *store); ~FitGradientWeightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitGradientWeightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitGradientWeightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/gradient_weighted/fitgradient_weightedconfig.ui000644 001750 001750 00000006320 11544160207 027471 0ustar00synthsynth000000 000000 FitGradient_WeightedConfig 0 0 422 101 400 0 0 0 X: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Weights: false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/gradient_weighted/gradient_weighted.pro000755 001750 001750 00000000346 11544160207 025770 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitgradient_weighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitgradient_weighted.cpp HEADERS += \ fitgradient_weighted.h FORMS += fitgradient_weightedconfig.ui kst-2.0.3/src/plugins/fits/non_linear_weighted.h000644 001750 001750 00000017536 11544160207 022277 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "common.h" struct data { size_t n; const double* pdX; const double* pdY; const double* pdWeight; }; void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ); double function_calculate( double dX, double* pdParameters ); void function_derivative( double dX, double* pdParameters, double* pdDerivatives ); int function_f( const gsl_vector* pVectorX, void* pParams, gsl_vector* pVectorF ); int function_df( const gsl_vector* pVectorX, void* pParams, gsl_matrix* pMatrixJ ); int function_fdf( const gsl_vector* pVectorX, void* pParams, gsl_vector* pVectorF, gsl_matrix* pMatrixJ ); bool kstfit_nonlinear_weighted( Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr weightedVector, Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals, Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance, Kst::ScalarPtr scalarOutChi ); int function_f( const gsl_vector* pVectorX, void* pParams, gsl_vector* pVectorF ) { double dParameters[NUM_PARAMS]; double dY; data* pData = (data*)pParams; size_t i; for( i=0; in; i++ ) { dY = function_calculate( pData->pdX[i], dParameters ); gsl_vector_set( pVectorF, i, (dY - pData->pdY[i])*pData->pdWeight[i] ); } return GSL_SUCCESS; } int function_df( const gsl_vector* pVectorX, void* pParams, gsl_matrix* pMatrixJ ) { double dParameters[NUM_PARAMS]; double dDerivatives[NUM_PARAMS]; data* pData = (data*)pParams; size_t i; size_t j; for( i=0; in; i++ ) { function_derivative( pData->pdX[i], dParameters, dDerivatives ); for( j=0; jpdWeight[i] ); } } return GSL_SUCCESS; } int function_fdf( const gsl_vector* pVectorX, void* pParams, gsl_vector* pVectorF, gsl_matrix* pMatrixJ ) { function_f( pVectorX, pParams, pVectorF ); function_df( pVectorX, pParams, pMatrixJ ); return GSL_SUCCESS; } bool kstfit_nonlinear_weighted( Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr weightsVector, Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals, Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance, Kst::ScalarPtr scalarOutChi ) { const gsl_multifit_fdfsolver_type* pType; gsl_multifit_fdfsolver* pSolver; gsl_multifit_function_fdf function; gsl_vector_view vectorViewInitial; gsl_matrix* pMatrixCovariance; struct data d; double dXInitial[NUM_PARAMS]; double* pInputs[3]; int iIterations = 0; int iLength; int bReturn = false; int iStatus; int i; int j; if (xVector->length() >= 2 && yVector->length() >= 2 && weightsVector->length() >= 2) { iLength = yVector->length(); if( xVector->length() > iLength ) { iLength = xVector->length(); } // do any necessary interpolation... pInputs[XVALUES] = (double*)malloc(iLength * sizeof( double )); if (xVector->length() == iLength) { for( i=0; ivalue()[i]; } } else { for( i=0; ivalue(), xVector->length() ); } } pInputs[YVALUES] = (double*)malloc(iLength * sizeof( double )); if (yVector->length() == iLength) { for( i=0; ivalue()[i]; } } else { for( i=0; ivalue(), yVector->length() ); } } pInputs[WEIGHTS] = (double*)malloc(iLength * sizeof( double )); if (weightsVector->length() == iLength) { for( i=0; ivalue()[i]; } } else { for( i=0; ivalue(), weightsVector->length() ); } } if( iLength > NUM_PARAMS ) { vectorOutYFitted->resize(iLength); vectorOutYResiduals->resize(iLength); vectorOutYParameters->resize(NUM_PARAMS); vectorOutYCovariance->resize(NUM_PARAMS * NUM_PARAMS); pType = gsl_multifit_fdfsolver_lmsder; pSolver = gsl_multifit_fdfsolver_alloc( pType, iLength, NUM_PARAMS ); if( pSolver != NULL ) { d.n = iLength; d.pdX = pInputs[XVALUES]; d.pdY = pInputs[YVALUES]; d.pdWeight = pInputs[WEIGHTS]; function.f = function_f; function.df = function_df; function.fdf = function_fdf; function.n = iLength; function.p = NUM_PARAMS; function.params = &d; pMatrixCovariance = gsl_matrix_alloc( NUM_PARAMS, NUM_PARAMS ); if( pMatrixCovariance != NULL ) { function_initial_estimate( pInputs[XVALUES], pInputs[YVALUES], iLength, dXInitial ); vectorViewInitial = gsl_vector_view_array( dXInitial, NUM_PARAMS ); gsl_multifit_fdfsolver_set( pSolver, &function, &vectorViewInitial.vector ); // // iterate to a solution... // do { iStatus = gsl_multifit_fdfsolver_iterate( pSolver ); if( iStatus == GSL_SUCCESS ) { iStatus = gsl_multifit_test_delta( pSolver->dx, pSolver->x, 1.0e-4, 1.0e-4 ); } iIterations++; } while( iStatus == GSL_CONTINUE && iIterations < MAX_NUM_ITERATIONS ); gsl_multifit_covar( pSolver->J, 0.0, pMatrixCovariance ); // // determine the fitted values... // for( i=0; ix, i ); } for( i=0; ivalue()[i] = function_calculate( pInputs[XVALUES][i], dXInitial ); vectorOutYResiduals->value()[i] = pInputs[YVALUES][i] - vectorOutYFitted->value()[i]; } // // fill in the parameter values and covariance matrix... // for( i=0; ivalue()[i] = gsl_vector_get( pSolver->x, i ); for( j=0; jvalue()[(i*NUM_PARAMS)+j] = gsl_matrix_get( pMatrixCovariance, i, j ); } } // // determine the value of chi^2/nu // scalarOutChi->setValue(gsl_blas_dnrm2( pSolver->f )); bReturn = true; gsl_matrix_free( pMatrixCovariance ); } gsl_multifit_fdfsolver_free( pSolver ); } } postcursor(true, pInputs); } return bReturn; } kst-2.0.3/src/plugins/fits/polynomial_weighted/fitpolynomial_weighted.h000644 001750 001750 00000005513 11544160207 027074 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITPOLYNOMIALWEIGHTEDPLUGIN_H #define FITPOLYNOMIALWEIGHTEDPLUGIN_H #include #include #include class FitPolynomialWeightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorWeights() const; Kst::ScalarPtr scalarOrder() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitPolynomialWeightedSource(Kst::ObjectStore *store); ~FitPolynomialWeightedSource(); virtual QString parameterName(int index) const; virtual QString parameterVectorToString() const; friend class Kst::ObjectStore; }; class FitPolynomialWeightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitPolynomialWeightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/polynomial_weighted/kstplugin_fits_polynomial_weighted.desktop000644 001750 001750 00000000431 11544160207 032732 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitpolynomial_weighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Polynomial Weighted Plugin Comment=Implements a Polynomial Weighted Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/polynomial_weighted/polynomial_weighted.pro000755 001750 001750 00000000356 11544160207 026745 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitpolynomial_weighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitpolynomial_weighted.cpp HEADERS += \ fitpolynomial_weighted.h FORMS += fitpolynomial_weightedconfig.ui kst-2.0.3/src/plugins/fits/polynomial_weighted/fitpolynomial_weighted.cpp000644 001750 001750 00000031614 11544160207 027430 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitpolynomial_weighted.h" #include "objectstore.h" #include "ui_fitpolynomial_weightedconfig.h" #include // #include "../common.h" #include "../linear_weighted.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_IN_WEIGHTS = "Weights Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_IN = "Order Scalar"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitPolynomialWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitPolynomial_WeightedConfig { public: ConfigWidgetFitPolynomialWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitPolynomial_WeightedConfig() { setupUi(this); } ~ConfigWidgetFitPolynomialWeightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorWeights->setObjectStore(store); _scalarOrder->setObjectStore(store); _scalarOrder->setDefaultValue(2); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorWeights, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarOrder, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorWeights() { return _vectorWeights->selectedVector(); }; void setSelectedVectorWeights(Kst::VectorPtr vector) { return _vectorWeights->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarOrder() { return _scalarOrder->selectedScalar(); }; void setSelectedScalarOrder(Kst::ScalarPtr scalar) { return _scalarOrder->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitPolynomialWeightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorWeights(source->vectorWeights()); setSelectedScalarOrder(source->scalarOrder()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Polynomial Weighted Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector Weights", _vectorWeights->selectedVector()->Name()); _cfg->setValue("Input Scalar Order", _scalarOrder->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Polynomial Weighted Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } vectorName = _cfg->value("Input Vector Weights").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorweights = static_cast(object); if (vectorweights) { setSelectedVectorX(vectorweights); } QString scalarName = _cfg->value("Order Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* orderScalar = static_cast(object); if (orderScalar) { setSelectedScalarOrder(orderScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitPolynomialWeightedSource::FitPolynomialWeightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitPolynomialWeightedSource::~FitPolynomialWeightedSource() { } QString FitPolynomialWeightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Weighted Polynomial"); } void FitPolynomialWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitPolynomialWeightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); setInputScalar(SCALAR_IN, config->selectedScalarOrder()); } } void FitPolynomialWeightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } double calculate_matrix_entry( double dX, int iPos ) { double dY; dY = pow( dX, (double)iPos ); return dY; } bool FitPolynomialWeightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorWeights = _inputVectors[VECTOR_IN_WEIGHTS]; Kst::ScalarPtr inputScalarOrder = _inputScalars[SCALAR_IN]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Polynomial Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Polynomial Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; int iNumParams; iNumParams = 1 + (int)floor( inputScalarOrder->value() ); if( iNumParams > 0 ) { bReturn = kstfit_linear_weighted( inputVectorX, inputVectorY, inputVectorWeights, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar, iNumParams ); } return bReturn; } QString FitPolynomialWeightedSource::parameterVectorToString() const { QString str = Name(); if (hasParameterVector()) { Kst::VectorPtr vectorParam = _outputVectors["Parameters Vector"]; for (int i = 0; i < vectorParam->length(); i++) { QString paramName = parameterName(i); if (!paramName.isEmpty()) { if (_outputScalars.contains(paramName)) { QString name = _outputScalars[paramName]->Name(); double value = _outputScalars[paramName]->value(); QString sign; if (value >= 0) { sign = " +"; } else { sign = " "; // Just for the space, the "-" is already in the number } if (i == 0) { str += QString("\n[%1]").arg(name); } else if (i == 1) { // Special case x^1 to x str += QString("%1[%2]x").arg(sign).arg(name); } else { str += QString("%1[%2]%3").arg(sign).arg(name).arg(paramName); } } } } } return str; } Kst::VectorPtr FitPolynomialWeightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitPolynomialWeightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr FitPolynomialWeightedSource::vectorWeights() const { return _inputVectors[VECTOR_IN_WEIGHTS]; } Kst::ScalarPtr FitPolynomialWeightedSource::scalarOrder() const { return _inputScalars[SCALAR_IN]; } QStringList FitPolynomialWeightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_WEIGHTS; return vectors; } QStringList FitPolynomialWeightedSource::inputScalarList() const { return QStringList(SCALAR_IN); } QStringList FitPolynomialWeightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitPolynomialWeightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitPolynomialWeightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitPolynomialWeightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitPolynomialWeightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitPolynomialWeightedSource::parameterName(int index) const { return QString("x^%1").arg(index); } // Name used to identify the plugin. Used when loading the plugin. QString FitPolynomialWeightedPlugin::pluginName() const { return "Polynomial Weighted Fit"; } QString FitPolynomialWeightedPlugin::pluginDescription() const { return "Generates a polynomial weighted fit for a set of data."; } Kst::DataObject *FitPolynomialWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitPolynomialWeightedPlugin* config = static_cast(configWidget)) { Kst::ScalarPtr order; if (setupInputsOutputs) { order = config->selectedScalarOrder(); } FitPolynomialWeightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); object->setInputScalar(SCALAR_IN, order); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitPolynomialWeightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitPolynomialWeightedPlugin *widget = new ConfigWidgetFitPolynomialWeightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitPolynomialWeightedPlugin, FitPolynomialWeightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/polynomial_weighted/fitpolynomial_weightedconfig.ui000644 001750 001750 00000012611 11544160207 030445 0ustar00synthsynth000000 000000 FitPolynomial_WeightedConfig 0 0 429 186 400 0 0 0 Input Vector - X false Qt::Horizontal 40 20 0 0 0 0 Input Vector - Y false Qt::Horizontal 40 20 0 0 0 0 Input Vector - Weights false Qt::Horizontal 40 20 0 0 0 0 Input Scalar - Order false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/fits/gradient_unweighted/fitgradient_unweighted.cpp000644 001750 001750 00000025104 11544160207 027357 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitgradient_unweighted.h" #include "objectstore.h" #include "ui_fitgradient_unweightedconfig.h" #include #include "../common.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& VECTOR_OUT_Y_LO = "Lo Vector"; static const QString& VECTOR_OUT_Y_HI = "Hi Vector"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitGradientUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitGradient_UnweightedConfig { public: ConfigWidgetFitGradientUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitGradient_UnweightedConfig() { setupUi(this); } ~ConfigWidgetFitGradientUnweightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitGradientUnweightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Gradient Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Gradient Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitGradientUnweightedSource::FitGradientUnweightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitGradientUnweightedSource::~FitGradientUnweightedSource() { } QString FitGradientUnweightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Unweighted Gradient"); } void FitGradientUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitGradientUnweightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } } void FitGradientUnweightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputVector(VECTOR_OUT_Y_LO, ""); setOutputVector(VECTOR_OUT_Y_HI, ""); setOutputScalar(SCALAR_OUT, ""); } bool FitGradientUnweightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::VectorPtr outputVectorYLo = _outputVectors[VECTOR_OUT_Y_LO]; Kst::VectorPtr outputVectorYHi = _outputVectors[VECTOR_OUT_Y_HI]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Gradient Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Gradient Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); label_info.name = i18n("Gradient Fit Lower Limit"); outputVectorYLo->setLabelInfo(label_info); label_info.name = i18n("Gradient Fit Upper Limit"); outputVectorYHi->setLabelInfo(label_info); int i = 0; int iLength; bool bReturn = false; double* pInputs[3]; double c0 = 0.0; double cov00 = 0.0; double dSumSq = 0.0; double y; double yErr; if( precursor( inputVectorX, inputVectorY, 0, &iLength, false, true, 2, pInputs, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputVectorYLo, outputVectorYHi ) ) { if( !gsl_fit_mul( pInputs[XVALUES], 1, pInputs[YVALUES], 1, iLength, &c0, &cov00, &dSumSq ) ) { for( i=0; ivalue()[i] = y; outputVectorYResiduals->value()[i] = pInputs[YVALUES][i] - y; outputVectorYLo->value()[i] = y - yErr; outputVectorYHi->value()[i] = y + yErr; } outputVectorYParameters->value()[0] = c0; outputVectorYCovariance->value()[0] = cov00; outputScalar->setValue(dSumSq / ( (double)iLength - 2.0 )); bReturn = true; } } postcursor( false, pInputs ); return bReturn; } Kst::VectorPtr FitGradientUnweightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitGradientUnweightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } QStringList FitGradientUnweightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList FitGradientUnweightedSource::inputScalarList() const { return QStringList(); } QStringList FitGradientUnweightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitGradientUnweightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_LO; vectors += VECTOR_OUT_Y_HI; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitGradientUnweightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitGradientUnweightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitGradientUnweightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitGradientUnweightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Gradient"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitGradientUnweightedPlugin::pluginName() const { return "Gradient Fit"; } QString FitGradientUnweightedPlugin::pluginDescription() const { return "Generates a gradient fit for a set of data."; } Kst::DataObject *FitGradientUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitGradientUnweightedPlugin* config = static_cast(configWidget)) { FitGradientUnweightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitGradientUnweightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitGradientUnweightedPlugin *widget = new ConfigWidgetFitGradientUnweightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitGradientUnweightedPlugin, FitGradientUnweightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/gradient_unweighted/kstplugin_fits_gradient_unweighted.desktop000644 001750 001750 00000000403 11544160207 032663 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitgradient_unweighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Gradient Plugin Comment=Implements a Gradient Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/gradient_unweighted/fitgradient_unweightedconfig.ui000644 001750 001750 00000004664 11544160207 030410 0ustar00synthsynth000000 000000 FitGradient_UnweightedConfig 0 0 422 91 400 0 0 0 X: false 0 0 0 0 Y: false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/gradient_unweighted/gradient_unweighted.pro000755 001750 001750 00000000356 11544160207 026677 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitgradient_unweighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitgradient_unweighted.cpp HEADERS += \ fitgradient_unweighted.h FORMS += fitgradient_unweightedconfig.ui kst-2.0.3/src/plugins/fits/gradient_unweighted/fitgradient_unweighted.h000644 001750 001750 00000005304 11544160207 027024 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITGRADIENTUNWEIGHTEDPLUGIN_H #define FITGRADIENTUNWEIGHTEDPLUGIN_H #include #include #include class FitGradientUnweightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitGradientUnweightedSource(Kst::ObjectStore *store); ~FitGradientUnweightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitGradientUnweightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitGradientUnweightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/exponential_unweighted/fitexponential_unweighted.cpp000644 001750 001750 00000024743 11544160207 030651 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitexponential_unweighted.h" #include "objectstore.h" #include "ui_fitexponential_unweightedconfig.h" #define NUM_PARAMS 3 #define MAX_NUM_ITERATIONS 500 #include #include "../non_linear.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitExponentialUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitExponential_UnweightedConfig { public: ConfigWidgetFitExponentialUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitExponential_UnweightedConfig() { setupUi(this); } ~ConfigWidgetFitExponentialUnweightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitExponentialUnweightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Exponential Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Exponential Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitExponentialUnweightedSource::FitExponentialUnweightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitExponentialUnweightedSource::~FitExponentialUnweightedSource() { } QString FitExponentialUnweightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Unweighted Exponential"); } void FitExponentialUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitExponentialUnweightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } } void FitExponentialUnweightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) { Q_UNUSED( pdX ) Q_UNUSED( pdY ) Q_UNUSED( iLength ) pdParameterEstimates[0] = 1.0; pdParameterEstimates[1] = 0.0; pdParameterEstimates[2] = 0.0; } double function_calculate( double dX, double* pdParameters ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dOffset = pdParameters[2]; double dY; dY = ( dScale * exp( -dLambda * dX ) ) + dOffset; return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dExp; double ddScale; double ddLambda; double ddOffset; dExp = exp( -dLambda * dX ); ddScale = dExp; ddLambda = -dX * dScale * dExp; ddOffset = 1.0; pdDerivatives[0] = ddScale; pdDerivatives[1] = ddLambda; pdDerivatives[2] = ddOffset; } bool FitExponentialUnweightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Exponential Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Exponential Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; bReturn = kstfit_nonlinear( inputVectorX, inputVectorY, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar ); return bReturn; } Kst::VectorPtr FitExponentialUnweightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitExponentialUnweightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } QStringList FitExponentialUnweightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList FitExponentialUnweightedSource::inputScalarList() const { return QStringList(); } QStringList FitExponentialUnweightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitExponentialUnweightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitExponentialUnweightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitExponentialUnweightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitExponentialUnweightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitExponentialUnweightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Scale"; break; case 1: parameter = "Lambda"; break; case 2: parameter = "Offset"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitExponentialUnweightedPlugin::pluginName() const { return "Exponential Fit"; } QString FitExponentialUnweightedPlugin::pluginDescription() const { return "Generates a exponential fit for a set of data."; } Kst::DataObject *FitExponentialUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitExponentialUnweightedPlugin* config = static_cast(configWidget)) { FitExponentialUnweightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitExponentialUnweightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitExponentialUnweightedPlugin *widget = new ConfigWidgetFitExponentialUnweightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitExponentialUnweightedPlugin, FitExponentialUnweightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/exponential_unweighted/kstplugin_fits_exponential_unweighted.desktop000644 001750 001750 00000000414 11544160207 034147 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitexponential_unweighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Exponential Plugin Comment=Implements a Exponential Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/exponential_unweighted/fitexponential_unweighted.h000644 001750 001750 00000005331 11544160207 030306 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITEXPONENTIALUNWEIGHTEDPLUGIN_H #define FITEXPONENTIALUNWEIGHTEDPLUGIN_H #include #include #include class FitExponentialUnweightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitExponentialUnweightedSource(Kst::ObjectStore *store); ~FitExponentialUnweightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitExponentialUnweightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitExponentialUnweightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/exponential_unweighted/fitexponential_unweightedconfig.ui000644 001750 001750 00000004673 11544160207 031672 0ustar00synthsynth000000 000000 FitExponential_UnweightedConfig 0 0 429 119 400 0 0 0 X: false 0 0 0 0 Y: false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/exponential_unweighted/exponential_unweighted.pro000755 001750 001750 00000000372 11544160207 030157 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitexponential_unweighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitexponential_unweighted.cpp HEADERS += \ fitexponential_unweighted.h FORMS += fitexponential_unweightedconfig.ui kst-2.0.3/src/plugins/fits/lorentzian_unweighted/fitlorentzian_unweightedconfig.ui000644 001750 001750 00000004671 11544160207 031366 0ustar00synthsynth000000 000000 FitLorentzian_UnweightedConfig 0 0 433 115 400 0 0 0 X: false 0 0 0 0 Y: false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/lorentzian_unweighted/fitlorentzian_unweighted.h000644 001750 001750 00000005322 11544160207 030004 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITLORENTZIANUNWEIGHTEDPLUGIN_H #define FITLORENTZIANUNWEIGHTEDPLUGIN_H #include #include #include class FitLorentzianUnweightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitLorentzianUnweightedSource(Kst::ObjectStore *store); ~FitLorentzianUnweightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitLorentzianUnweightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitLorentzianUnweightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/lorentzian_unweighted/lorentzian_unweighted.pro000755 001750 001750 00000000366 11544160207 027660 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitlorentzian_unweighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitlorentzian_unweighted.cpp HEADERS += \ fitlorentzian_unweighted.h FORMS += fitlorentzian_unweightedconfig.ui kst-2.0.3/src/plugins/fits/lorentzian_unweighted/kstplugin_fits_lorentzian_unweighted.desktop000644 001750 001750 00000000411 11544160207 033642 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitlorentzian_unweighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Lorentzian Plugin Comment=Implements a Lorentzian Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/lorentzian_unweighted/fitlorentzian_unweighted.cpp000644 001750 001750 00000025473 11544160207 030350 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitlorentzian_unweighted.h" #include "objectstore.h" #include "ui_fitlorentzian_unweightedconfig.h" #define NUM_PARAMS 3 #define MAX_NUM_ITERATIONS 500 #include #include "../non_linear.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitLorentzianUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitLorentzian_UnweightedConfig { public: ConfigWidgetFitLorentzianUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitLorentzian_UnweightedConfig() { setupUi(this); } ~ConfigWidgetFitLorentzianUnweightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitLorentzianUnweightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Lorentzian Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Lorentzian Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitLorentzianUnweightedSource::FitLorentzianUnweightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitLorentzianUnweightedSource::~FitLorentzianUnweightedSource() { } QString FitLorentzianUnweightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Lorentzian"); } void FitLorentzianUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitLorentzianUnweightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } } void FitLorentzianUnweightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) { double dMin; double dMax; gsl_stats_minmax( &dMin, &dMax, pdX, 1, iLength ); pdParameterEstimates[0] = gsl_stats_mean( pdX, 1, iLength ); pdParameterEstimates[1] = ( dMax - dMin ) / 2.0; pdParameterEstimates[2] = gsl_stats_max( pdY, 1, iLength ); } double function_calculate( double dX, double* pdParameters ) { double dMean = pdParameters[0]; double dHW = pdParameters[1]; double dScale = pdParameters[2]; double dY; dY = ( dScale / M_PI ) * ( dHW / 2.0 ); dY /= ( ( dX - dMean ) * ( dX - dMean ) )+( ( dHW / 2.0 ) * ( dHW / 2.0 ) ); return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) { double dMean = pdParameters[0]; double dHW = pdParameters[1]; double dScale = pdParameters[2]; double dDenom; double ddMean; double ddHW; double ddScale; dDenom = ( ( dX - dMean ) * ( dX - dMean ) ) + ( ( dHW / 2.0 ) * ( dHW / 2.0 ) ); ddMean = ( dScale / M_PI ) * dHW * ( dMean - dX ) / ( dDenom * dDenom ); ddHW = ( dScale / ( 2.0 * M_PI ) ) / ( dDenom * dDenom ); ddHW *= dDenom - ( dHW * dHW / 2.0 ); ddScale = ( 1.0 / M_PI ) * ( dHW / 2.0 ) / dDenom; pdDerivatives[0] = ddMean; pdDerivatives[1] = ddHW; pdDerivatives[2] = ddScale; } bool FitLorentzianUnweightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Lorentzian Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Lorentzian Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; bReturn = kstfit_nonlinear( inputVectorX, inputVectorY, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar ); return bReturn; } Kst::VectorPtr FitLorentzianUnweightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitLorentzianUnweightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } QStringList FitLorentzianUnweightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList FitLorentzianUnweightedSource::inputScalarList() const { return QStringList(); } QStringList FitLorentzianUnweightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitLorentzianUnweightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitLorentzianUnweightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitLorentzianUnweightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitLorentzianUnweightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitLorentzianUnweightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Mean"; break; case 1: parameter = "Half-width"; break; case 2: parameter = "Scale"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitLorentzianUnweightedPlugin::pluginName() const { return "Lorentzian Fit"; } QString FitLorentzianUnweightedPlugin::pluginDescription() const { return "Generates a lorentzian fit for a set of data."; } Kst::DataObject *FitLorentzianUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitLorentzianUnweightedPlugin* config = static_cast(configWidget)) { FitLorentzianUnweightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitLorentzianUnweightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitLorentzianUnweightedPlugin *widget = new ConfigWidgetFitLorentzianUnweightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitLorentzianUnweightedPlugin, FitLorentzianUnweightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/linear.h000644 001750 001750 00000012136 11544160207 017534 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "common.h" double calculate_matrix_entry( double dX, int iPos ); extern "C" bool kstfit_linear_unweighted( Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals, Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance, Kst::ScalarPtr scalarOutChi, int iNumParams); bool kstfit_linear_unweighted( Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals, Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance, Kst::ScalarPtr scalarOutChi, int iNumParams) { gsl_matrix* pMatrixX = NULL; gsl_matrix* pMatrixCovariance = NULL; gsl_vector* pVectorY = NULL; gsl_vector* pVectorParameters = NULL; gsl_multifit_linear_workspace* pWork = NULL; double dXInterpolated; double dX; double dY; double dChiSq = 0.0; int i = 0; int j; int iStatus = 0; int iLength; bool bReturn = false; if (xVector->length() >= 2 && yVector->length() >= 2 ) { iLength = yVector->length(); if( xVector->length() > iLength ) { iLength = xVector->length(); } if( iLength > iNumParams + 1 ) { vectorOutYFitted->resize(iLength); vectorOutYResiduals->resize(iLength); vectorOutYParameters->resize(iNumParams); vectorOutYCovariance->resize(iNumParams * iNumParams); // // create the matrices and vectors... // pMatrixX = gsl_matrix_alloc( iLength, iNumParams ); if( pMatrixX != NULL ) { pVectorY = gsl_vector_alloc( iLength ); if( pVectorY != NULL ) { pVectorParameters = gsl_vector_alloc( iNumParams ); if( pVectorParameters != NULL ) { pMatrixCovariance = gsl_matrix_alloc( iNumParams, iNumParams ); if( pMatrixCovariance != NULL ) { pWork = gsl_multifit_linear_alloc( iLength, iNumParams ); if( pWork != NULL ) { // // fill in the matrices and vectors... // for( i=0; ivalue(), yVector->length())); dXInterpolated = interpolate(i, iLength, xVector->value(), xVector->length()); for( j=0; jvalue()[i] = dY; vectorOutYResiduals->value()[i] = interpolate(i, iLength, yVector->value(), yVector->length()) - dY; } for( i=0; ivalue()[i] = gsl_vector_get( pVectorParameters, i ); for( j=0; jvalue()[(i*iNumParams)+j] = gsl_matrix_get( pMatrixCovariance, i, j ); } } scalarOutChi->setValue(dChiSq / ( (double)iLength - (double)iNumParams )); bReturn = true; } gsl_multifit_linear_free( pWork ); } gsl_matrix_free( pMatrixCovariance ); } gsl_vector_free( pVectorParameters ); } gsl_vector_free( pVectorY ); } gsl_matrix_free( pMatrixX ); } } } return bReturn; } kst-2.0.3/src/plugins/fits/gaussian_weighted/fitgaussian_weighted.h000644 001750 001750 00000005340 11544160207 026150 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITGAUSSIANWEIGHTEDPLUGIN_H #define FITGAUSSIANWEIGHTEDPLUGIN_H #include #include #include class FitGaussianWeightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorWeights() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitGaussianWeightedSource(Kst::ObjectStore *store); ~FitGaussianWeightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitGaussianWeightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitGaussianWeightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/gaussian_weighted/kstplugin_fits_gaussian_weighted.desktop000644 001750 001750 00000000423 11544160207 032011 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitgaussian_weighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Gradient Gaussian Plugin Comment=Implements a Gradient Gaussian Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/gaussian_weighted/fitgaussian_weighted.cpp000644 001750 001750 00000027646 11544160207 026520 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitgaussian_weighted.h" #include "objectstore.h" #include "ui_fitgaussian_weightedconfig.h" #define NUM_PARAMS 3 #define MAX_NUM_ITERATIONS 500 #include #include "../non_linear_weighted.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_IN_WEIGHTS = "Weights Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitGaussianWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitGaussian_WeightedConfig { public: ConfigWidgetFitGaussianWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitGaussian_WeightedConfig() { setupUi(this); } ~ConfigWidgetFitGaussianWeightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorWeights->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorWeights, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorWeights() { return _vectorWeights->selectedVector(); }; void setSelectedVectorWeights(Kst::VectorPtr vector) { return _vectorWeights->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitGaussianWeightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorWeights(source->vectorWeights()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Gaussian Weighted Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector Weights", _vectorWeights->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Gaussian Weighted Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } vectorName = _cfg->value("Input Vector Weights").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorweights = static_cast(object); if (vectorweights) { setSelectedVectorX(vectorweights); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitGaussianWeightedSource::FitGaussianWeightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitGaussianWeightedSource::~FitGaussianWeightedSource() { } QString FitGaussianWeightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Weighted Gaussian"); } void FitGaussianWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitGaussianWeightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } } void FitGaussianWeightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) { double dMin; double dMax; gsl_stats_minmax( &dMin, &dMax, pdX, 1, iLength ); pdParameterEstimates[0] = gsl_stats_mean( pdX, 1, iLength ); pdParameterEstimates[1] = ( dMax - dMin ) / 2.0; pdParameterEstimates[2] = gsl_stats_max( pdY, 1, iLength ); } double function_calculate( double dX, double* pdParameters ) { double dMean = pdParameters[0]; double dSD = pdParameters[1]; double dScale = pdParameters[2]; double dY; dY = ( dScale / ( dSD * M_SQRT2 * M_SQRTPI ) ); dY *= exp( -( ( dX - dMean ) * ( dX - dMean ) ) / ( 2.0 * dSD * dSD ) ); return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) { double dMean = pdParameters[0]; double dSD = pdParameters[1]; double dScale = pdParameters[2]; double dExp; double ddMean; double ddSD; double ddScale; dExp = exp( -( ( dX - dMean ) * ( dX - dMean ) ) / ( 2.0 * dSD * dSD ) ); ddMean = ( dX - dMean ) * dScale * dExp / ( dSD * dSD * dSD * M_SQRT2 * M_SQRTPI ); ddSD = dScale * dExp / ( dSD * dSD * M_SQRT2 * M_SQRTPI ); ddSD *= ( ( dX - dMean ) * ( dX - dMean ) / ( dSD * dSD ) ) - 1.0; ddScale = dExp / ( dSD * M_SQRT2 * M_SQRTPI ); pdDerivatives[0] = ddMean; pdDerivatives[1] = ddSD; pdDerivatives[2] = ddScale; } bool FitGaussianWeightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorWeights = _inputVectors[VECTOR_IN_WEIGHTS]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Gaussian Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Gaussian Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; bReturn = kstfit_nonlinear_weighted( inputVectorX, inputVectorY, inputVectorWeights, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar ); return bReturn; } Kst::VectorPtr FitGaussianWeightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitGaussianWeightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr FitGaussianWeightedSource::vectorWeights() const { return _inputVectors[VECTOR_IN_WEIGHTS]; } QStringList FitGaussianWeightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_WEIGHTS; return vectors; } QStringList FitGaussianWeightedSource::inputScalarList() const { return QStringList(); } QStringList FitGaussianWeightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitGaussianWeightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitGaussianWeightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitGaussianWeightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitGaussianWeightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitGaussianWeightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Mean"; break; case 1: parameter = "SD"; break; case 2: parameter = "Scale"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitGaussianWeightedPlugin::pluginName() const { return "Gaussian Weighted Fit"; } QString FitGaussianWeightedPlugin::pluginDescription() const { return "Generates a gaussian weighted fit for a set of data."; } Kst::DataObject *FitGaussianWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitGaussianWeightedPlugin* config = static_cast(configWidget)) { FitGaussianWeightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitGaussianWeightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitGaussianWeightedPlugin *widget = new ConfigWidgetFitGaussianWeightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitGaussianWeightedPlugin, FitGaussianWeightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/gaussian_weighted/fitgaussian_weightedconfig.ui000644 001750 001750 00000006320 11544160207 027523 0ustar00synthsynth000000 000000 FitGaussian_WeightedConfig 0 0 428 116 400 0 0 0 X: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Weights: false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/gaussian_weighted/gaussian_weighted.pro000755 001750 001750 00000000346 11544160207 026022 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitgaussian_weighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitgaussian_weighted.cpp HEADERS += \ fitgaussian_weighted.h FORMS += fitgaussian_weightedconfig.ui kst-2.0.3/src/plugins/fits/fits.pro000644 001750 001750 00000001004 11544160207 017570 0ustar00synthsynth000000 000000 include($$PWD/../../../config.pri) TEMPLATE = subdirs CONFIG += ordered LibExists(gsl) { SUBDIRS += \ exponential_unweighted \ exponential_weighted \ gaussian_unweighted \ gaussian_weighted \ gradient_weighted \ gradient_unweighted \ kneefrequency \ linear_weighted \ linear_unweighted \ lorentzian_unweighted \ lorentzian_weighted \ polynomial_unweighted \ polynomial_weighted \ sinusoid_unweighted \ sinusoid_weighted } kst-2.0.3/src/plugins/fits/common.h000644 001750 001750 00000011137 11544160207 017552 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #define XVALUES 0 #define YVALUES 1 #define WEIGHTS 2 double interpolate(int iIndex, int iLengthDesired, const double* pArray, int iLengthActual) { double value; double fj; double fdj; int j; if (iLengthDesired == iLengthActual) { value = pArray[iIndex]; } else { fj = (double)(iIndex * (iLengthActual-1)) / (double)(iLengthDesired-1); j = (int)floor(fj); fdj = fj - (double)j; //Don't read an invalid index from pArray... found by valgrind double A = j+1 < iLengthActual ? pArray[j+1] : 0; double B = j < iLengthActual ? pArray[j] : 0; value = A * fdj + B * (1.0 - fdj); } return value; } void assign( Kst::VectorPtr targetVector, double* pResult[], int iIndex, int iLength ) { for (int i = 0; i < iLength; i++) { targetVector->value()[i] = pResult[iIndex][i]; } } bool precursor( Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr weightsVector, int *piLength, bool bWeighted, bool bLowHigh, int iNumParams, double* pInputs[], Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals, Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance, Kst::VectorPtr vectorOutYLo, Kst::VectorPtr vectorOutYHi) { bool bRetVal = false; int iNumCovar = ( iNumParams * ( iNumParams + 1 ) ) / 2; int i; pInputs[XVALUES] = 0L; pInputs[YVALUES] = 0L; if (bWeighted) { pInputs[WEIGHTS] = 0L; } if( xVector->length() >= 2 && yVector->length() >= 2 && (!bWeighted || weightsVector->length() >= 2) ) { *piLength = xVector->length(); if( yVector->length() > *piLength ) { *piLength = yVector->length(); } // // do any necessary interpolations... // pInputs[XVALUES] = (double*)malloc(*piLength * sizeof( double )); if (xVector->length() == *piLength) { for( i=0; i<*piLength; i++) { pInputs[XVALUES][i] = xVector->value()[i]; } } else { for( i=0; i<*piLength; i++) { pInputs[XVALUES][i] = interpolate( i, *piLength, xVector->value(), xVector->length() ); } } pInputs[YVALUES] = (double*)malloc(*piLength * sizeof( double )); if (yVector->length() == *piLength) { for( i=0; i<*piLength; i++) { pInputs[YVALUES][i] = yVector->value()[i]; } } else { for( i=0; i<*piLength; i++) { pInputs[YVALUES][i] = interpolate( i, *piLength, yVector->value(), yVector->length() ); } } if (bWeighted) { pInputs[WEIGHTS] = (double*)malloc(*piLength * sizeof( double )); if (weightsVector->length() == *piLength) { for( i=0; i<*piLength; i++) { pInputs[WEIGHTS][i] = weightsVector->value()[i]; } } else { for( i=0; i<*piLength; i++) { pInputs[WEIGHTS][i] = interpolate( i, *piLength, weightsVector->value(), weightsVector->length() ); } } } if( *piLength > iNumParams + 1 ) { vectorOutYFitted->resize(*piLength); vectorOutYResiduals->resize(*piLength); vectorOutYParameters->resize(iNumParams); vectorOutYCovariance->resize(iNumCovar); if( bLowHigh ) { vectorOutYLo->resize(*piLength); vectorOutYHi->resize(*piLength); } bRetVal = true; } } return bRetVal; } void postcursor( bool bWeighted, double* pInputs[]) { if (pInputs[XVALUES] != 0L ) { free( pInputs[XVALUES] ); } if (pInputs[YVALUES] != 0L ) { free( pInputs[YVALUES] ); } if( bWeighted ) { if (pInputs[WEIGHTS] != 0L ) { free( pInputs[WEIGHTS] ); } } } kst-2.0.3/src/plugins/fits/sinusoid_weighted/fitsinusoid_weighted.h000644 001750 001750 00000005465 11544160207 026226 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITSINUSOIDWEIGHTEDPLUGIN_H #define FITSINUSOIDWEIGHTEDPLUGIN_H #include #include #include class FitSinusoidWeightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorWeights() const; Kst::ScalarPtr scalarHarmonics() const; Kst::ScalarPtr scalarPeriod() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitSinusoidWeightedSource(Kst::ObjectStore *store); ~FitSinusoidWeightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitSinusoidWeightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitSinusoidWeightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/sinusoid_weighted/kstplugin_fits_sinusoid_weighted.desktop000644 001750 001750 00000000423 11544160207 032057 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitsinusoid_weighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Sinusoid Weighted Plugin Comment=Implements a Sinusoid Weighted Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/sinusoid_weighted/fitsinusoid_weighted.cpp000644 001750 001750 00000033442 11544160207 026555 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitsinusoid_weighted.h" #include "objectstore.h" #include "ui_fitsinusoid_weightedconfig.h" #include // #include "../common.h" #include "../linear_weighted.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_IN_WEIGHTS = "Weights Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_IN_PERIOD = "Period Scalar"; static const QString& SCALAR_IN_HARMONICS = "Harmonics Scalar"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitSinusoidWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitSinusoid_WeightedConfig { public: ConfigWidgetFitSinusoidWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitSinusoid_WeightedConfig() { setupUi(this); } ~ConfigWidgetFitSinusoidWeightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorWeights->setObjectStore(store); _scalarHarmonics->setObjectStore(store); _scalarPeriod->setObjectStore(store); _scalarHarmonics->setDefaultValue(0); _scalarPeriod->setDefaultValue(1); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorWeights, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarHarmonics, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarPeriod, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorWeights() { return _vectorWeights->selectedVector(); }; void setSelectedVectorWeights(Kst::VectorPtr vector) { return _vectorWeights->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarHarmonics() { return _scalarHarmonics->selectedScalar(); }; void setSelectedScalarHarmonics(Kst::ScalarPtr scalar) { return _scalarHarmonics->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarPeriod() { return _scalarPeriod->selectedScalar(); }; void setSelectedScalarPeriod(Kst::ScalarPtr scalar) { return _scalarPeriod->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitSinusoidWeightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorWeights(source->vectorWeights()); setSelectedScalarHarmonics(source->scalarHarmonics()); setSelectedScalarPeriod(source->scalarPeriod()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Sinusoid Weighted Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector Weights", _vectorWeights->selectedVector()->Name()); _cfg->setValue("Input Scalar Harmonics", _scalarHarmonics->selectedScalar()->Name()); _cfg->setValue("Input Scalar Period", _scalarPeriod->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Sinusoid Weighted Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } vectorName = _cfg->value("Input Vector Weights").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorweights = static_cast(object); if (vectorweights) { setSelectedVectorX(vectorweights); } QString scalarName = _cfg->value("Harmonics Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* harmonicsScalar = static_cast(object); if (harmonicsScalar) { setSelectedScalarHarmonics(harmonicsScalar); } scalarName = _cfg->value("Period Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* periodScalar = static_cast(object); if (periodScalar) { setSelectedScalarPeriod(periodScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitSinusoidWeightedSource::FitSinusoidWeightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitSinusoidWeightedSource::~FitSinusoidWeightedSource() { } QString FitSinusoidWeightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Weighted Sinusoid"); } void FitSinusoidWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitSinusoidWeightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); setInputScalar(SCALAR_IN_HARMONICS, config->selectedScalarHarmonics()); setInputScalar(SCALAR_IN_PERIOD, config->selectedScalarPeriod()); } } void FitSinusoidWeightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } double g_dPeriod; double calculate_matrix_entry( double dX, int iPos ) { double dY; if( iPos == 0 ) { dY = 1.0; } else if( iPos % 2 == 1 ) { dY = cos( (double)( ( iPos + 1 ) / 2 ) * 2.0 * M_PI * dX / g_dPeriod ); } else { dY = -sin( (double)( ( iPos + 0 ) / 2 ) * 2.0 * M_PI * dX / g_dPeriod ); } return dY; } bool FitSinusoidWeightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorWeights = _inputVectors[VECTOR_IN_WEIGHTS]; Kst::ScalarPtr inputScalarHarmonics = _inputScalars[SCALAR_IN_HARMONICS]; Kst::ScalarPtr inputScalarPeriod = _inputScalars[SCALAR_IN_PERIOD]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Sinusoidal Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Sinusoidal Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; int iNumParams; iNumParams = 3 + ( 2 * (int)floor( inputScalarHarmonics->value() ) ); if( iNumParams >= 3 ) { g_dPeriod = inputScalarPeriod->value(); if( g_dPeriod > 0.0 ) { bReturn = kstfit_linear_weighted( inputVectorX, inputVectorY, inputVectorWeights, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar, iNumParams ); } } return bReturn; } Kst::VectorPtr FitSinusoidWeightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitSinusoidWeightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr FitSinusoidWeightedSource::vectorWeights() const { return _inputVectors[VECTOR_IN_WEIGHTS]; } Kst::ScalarPtr FitSinusoidWeightedSource::scalarHarmonics() const { return _inputScalars[SCALAR_IN_HARMONICS]; } Kst::ScalarPtr FitSinusoidWeightedSource::scalarPeriod() const { return _inputScalars[SCALAR_IN_PERIOD]; } QStringList FitSinusoidWeightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_WEIGHTS; return vectors; } QStringList FitSinusoidWeightedSource::inputScalarList() const { QStringList scalars(SCALAR_IN_HARMONICS); scalars += SCALAR_IN_PERIOD; return scalars; } QStringList FitSinusoidWeightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitSinusoidWeightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitSinusoidWeightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitSinusoidWeightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitSinusoidWeightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitSinusoidWeightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Mean"; break; case 1: parameter = "cos(%1 2PI x/P)"; parameter.arg((index + 1 ) / 2); break; case 2: parameter = "-sin(%1 2PI x/P)"; parameter.arg((index + 0 ) / 2); break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitSinusoidWeightedPlugin::pluginName() const { return "Sinusoid Weighted Fit"; } QString FitSinusoidWeightedPlugin::pluginDescription() const { return "Generates a sinusoid weighted fit for a set of data."; } Kst::DataObject *FitSinusoidWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitSinusoidWeightedPlugin* config = static_cast(configWidget)) { Kst::ScalarPtr harmonics; Kst::ScalarPtr period; if (setupInputsOutputs) { harmonics = config->selectedScalarHarmonics(); period = config->selectedScalarPeriod(); } FitSinusoidWeightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); object->setInputScalar(SCALAR_IN_HARMONICS, harmonics); object->setInputScalar(SCALAR_IN_PERIOD, period); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitSinusoidWeightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitSinusoidWeightedPlugin *widget = new ConfigWidgetFitSinusoidWeightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitSinusoidWeightedPlugin, FitSinusoidWeightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/sinusoid_weighted/sinusoid_weighted.pro000755 001750 001750 00000000346 11544160207 026070 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitsinusoid_weighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitsinusoid_weighted.cpp HEADERS += \ fitsinusoid_weighted.h FORMS += fitsinusoid_weightedconfig.ui kst-2.0.3/src/plugins/fits/sinusoid_weighted/fitsinusoid_weightedconfig.ui000644 001750 001750 00000014563 11544160207 027601 0ustar00synthsynth000000 000000 FitSinusoid_WeightedConfig 0 0 426 193 400 0 0 0 Input Vector - X false Qt::Horizontal 40 20 0 0 0 0 Input Vector - Y false Qt::Horizontal 40 20 0 0 0 0 Input Vector - Weights false Qt::Horizontal 40 20 0 0 0 0 Input Scalar - Harmonics false Qt::Horizontal 40 20 0 0 Input Scalar - Period false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/fits/linear_unweighted/fitlinear_unweighted.cpp000644 001750 001750 00000025427 11544160207 026521 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitlinear_unweighted.h" #include "objectstore.h" #include "ui_fitlinear_unweightedconfig.h" #include #include "../common.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& VECTOR_OUT_Y_LO = "Lo Vector"; static const QString& VECTOR_OUT_Y_HI = "Hi Vector"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitLinearUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitLinear_UnweightedConfig { public: ConfigWidgetFitLinearUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitLinear_UnweightedConfig() { setupUi(this); } ~ConfigWidgetFitLinearUnweightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitLinearUnweightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Linear Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Linear Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitLinearUnweightedSource::FitLinearUnweightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitLinearUnweightedSource::~FitLinearUnweightedSource() { } QString FitLinearUnweightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Unweighted Linear"); } void FitLinearUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitLinearUnweightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } } void FitLinearUnweightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputVector(VECTOR_OUT_Y_LO, ""); setOutputVector(VECTOR_OUT_Y_HI, ""); setOutputScalar(SCALAR_OUT, ""); } bool FitLinearUnweightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::VectorPtr outputVectorYLo = _outputVectors[VECTOR_OUT_Y_LO]; Kst::VectorPtr outputVectorYHi = _outputVectors[VECTOR_OUT_Y_HI]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; int i = 0; int iLength; bool bReturn = false; double* pInputs[3]; double c0 = 0.0; double c1 = 0.0; double cov00 = 0.0; double cov01 = 0.0; double cov11 = 0.0; double dSumSq = 0.0; double y; double yErr; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Linear Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Linear Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); label_info.name = i18n("Linear Fit Lower Limit"); outputVectorYLo->setLabelInfo(label_info); label_info.name = i18n("Linear Fit Upper Limit"); outputVectorYHi->setLabelInfo(label_info); if( precursor( inputVectorX, inputVectorY, 0, &iLength, false, true, 2, pInputs, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputVectorYLo, outputVectorYHi ) ) { if( !gsl_fit_linear( pInputs[XVALUES], 1, pInputs[YVALUES], 1, iLength, &c0, &c1, &cov00, &cov01, &cov11, &dSumSq ) ) { for( i=0; ivalue()[i] = y; outputVectorYResiduals->value()[i] = pInputs[YVALUES][i] - y; outputVectorYLo->value()[i] = y - yErr; outputVectorYHi->value()[i] = y + yErr; } outputVectorYParameters->value()[0] = c0; outputVectorYParameters->value()[1] = c1; outputVectorYCovariance->value()[0] = cov00; outputVectorYCovariance->value()[1] = cov01; outputVectorYCovariance->value()[2] = cov11; outputScalar->setValue(dSumSq / ( (double)iLength - 2.0 )); bReturn = true; } } // postcursor( false, pInputs ); return bReturn; } Kst::VectorPtr FitLinearUnweightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitLinearUnweightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } QStringList FitLinearUnweightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList FitLinearUnweightedSource::inputScalarList() const { return QStringList(); } QStringList FitLinearUnweightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitLinearUnweightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_LO; vectors += VECTOR_OUT_Y_HI; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitLinearUnweightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitLinearUnweightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitLinearUnweightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitLinearUnweightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Intercept"; break; case 1: parameter = "Gradient"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitLinearUnweightedPlugin::pluginName() const { return "Linear Fit"; } QString FitLinearUnweightedPlugin::pluginDescription() const { return "Generates a linear fit for a set of data."; } Kst::DataObject *FitLinearUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitLinearUnweightedPlugin* config = static_cast(configWidget)) { FitLinearUnweightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitLinearUnweightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitLinearUnweightedPlugin *widget = new ConfigWidgetFitLinearUnweightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitLinearUnweightedPlugin, FitLinearUnweightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/linear_unweighted/linear_unweighted.pro000755 001750 001750 00000000346 11544160207 026030 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitlinear_unweighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitlinear_unweighted.cpp HEADERS += \ fitlinear_unweighted.h FORMS += fitlinear_unweightedconfig.ui kst-2.0.3/src/plugins/fits/linear_unweighted/fitlinear_unweighted.h000644 001750 001750 00000005266 11544160207 026165 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITLINEARUNWEIGHTEDPLUGIN_H #define FITLINEARUNWEIGHTEDPLUGIN_H #include #include #include class FitLinearUnweightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitLinearUnweightedSource(Kst::ObjectStore *store); ~FitLinearUnweightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitLinearUnweightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitLinearUnweightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/linear_unweighted/fitlinear_unweightedconfig.ui000644 001750 001750 00000004662 11544160207 027540 0ustar00synthsynth000000 000000 FitLinear_UnweightedConfig 0 0 440 124 400 0 0 0 X: false 0 0 0 0 Y: false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/linear_unweighted/kstplugin_fits_linear_unweighted.desktop000644 001750 001750 00000000375 11544160207 032025 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitlinear_unweighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Linear Plugin Comment=Implements a Linear Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/non_linear.h000644 001750 001750 00000016203 11544160207 020405 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "common.h" struct data { size_t n; const double* pdX; const double* pdY; }; void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ); double function_calculate( double dX, double* pdParameters ); void function_derivative( double dX, double* pdParameters, double* pdDerivatives ); int function_f( const gsl_vector* pVectorX, void* pParams, gsl_vector* pVectorF ); int function_df( const gsl_vector* pVectorX, void* pParams, gsl_matrix* pMatrixJ ); int function_fdf( const gsl_vector* pVectorX, void* pParams, gsl_vector* pVectorF, gsl_matrix* pMatrixJ ); bool kstfit_nonlinear( Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals, Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance, Kst::ScalarPtr scalarOutChi ); int function_f( const gsl_vector* pVectorX, void* pParams, gsl_vector* pVectorF ) { double dParameters[NUM_PARAMS]; double dY; data* pData = (data*)pParams; size_t i; for( i=0; in; i++ ) { dY = function_calculate( pData->pdX[i], dParameters ); gsl_vector_set( pVectorF, i, dY - pData->pdY[i] ); } return GSL_SUCCESS; } int function_df( const gsl_vector* pVectorX, void* pParams, gsl_matrix* pMatrixJ ) { double dParameters[NUM_PARAMS]; double dDerivatives[NUM_PARAMS]; data* pData = (data*)pParams; size_t i; size_t j; for( i=0; in; i++ ) { function_derivative( pData->pdX[i], dParameters, dDerivatives ); for( j=0; jlength() >= 2 && yVector->length() >= 2 ) { iLength = yVector->length(); if( xVector->length() > iLength ) { iLength = xVector->length(); } pInputX = (double*)malloc(iLength * sizeof( double )); if (xVector->length() == iLength) { for( i=0; ivalue()[i]; } } else { for( i=0; ivalue(), xVector->length() ); } } pInputY = (double*)malloc(iLength * sizeof( double )); if (yVector->length() == iLength) { for( i=0; ivalue()[i]; } } else { for( i=0; ivalue(), yVector->length() ); } } if( iLength > NUM_PARAMS ) { vectorOutYFitted->resize(iLength); vectorOutYResiduals->resize(iLength); vectorOutYParameters->resize(NUM_PARAMS); vectorOutYCovariance->resize(NUM_PARAMS * NUM_PARAMS); pType = gsl_multifit_fdfsolver_lmsder; pSolver = gsl_multifit_fdfsolver_alloc( pType, iLength, NUM_PARAMS ); if( pSolver != NULL ) { d.n = iLength; d.pdX = pInputX; d.pdY = pInputY; function.f = function_f; function.df = function_df; function.fdf = function_fdf; function.n = iLength; function.p = NUM_PARAMS; function.params = &d; pMatrixCovariance = gsl_matrix_alloc( NUM_PARAMS, NUM_PARAMS ); if( pMatrixCovariance != NULL ) { function_initial_estimate( pInputX, pInputY, iLength, dXInitial ); vectorViewInitial = gsl_vector_view_array( dXInitial, NUM_PARAMS ); gsl_multifit_fdfsolver_set( pSolver, &function, &vectorViewInitial.vector ); // // iterate to a solution... // do { iStatus = gsl_multifit_fdfsolver_iterate( pSolver ); if( iStatus == GSL_SUCCESS ) { iStatus = gsl_multifit_test_delta( pSolver->dx, pSolver->x, 1.0e-4, 1.0e-4 ); } iIterations++; } while( iStatus == GSL_CONTINUE && iIterations < MAX_NUM_ITERATIONS ); gsl_multifit_covar( pSolver->J, 0.0, pMatrixCovariance ); // // determine the fitted values... // for( i=0; ix, i ); } for( i=0; ivalue()[i] = function_calculate( pInputX[i], dXInitial ); vectorOutYResiduals->value()[i] = pInputY[i] - vectorOutYFitted->value()[i]; } // // fill in the parameter values and covariance matrix... // for( i=0; ivalue()[i] = gsl_vector_get( pSolver->x, i ); for( j=0; jvalue()[(i*NUM_PARAMS)+j] = gsl_matrix_get( pMatrixCovariance, i, j ); } } // // determine the value of chi^2/nu // scalarOutChi->setValue(gsl_blas_dnrm2( pSolver->f )); bReturn = true; gsl_matrix_free( pMatrixCovariance ); } gsl_multifit_fdfsolver_free( pSolver ); } } free( pInputX ); free( pInputY ); } return bReturn; } kst-2.0.3/src/plugins/fits/gaussian_unweighted/fitgaussian_unweightedconfig.ui000644 001750 001750 00000004664 11544160207 030442 0ustar00synthsynth000000 000000 FitGaussian_UnweightedConfig 0 0 428 81 400 0 0 0 X: false 0 0 0 0 Y: false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/gaussian_unweighted/kstplugin_fits_gaussian_unweighted.desktop000644 001750 001750 00000000403 11544160207 032715 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitgaussian_unweighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Gaussian Plugin Comment=Implements a Gaussian Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/gaussian_unweighted/fitgaussian_unweighted.h000644 001750 001750 00000005304 11544160207 027056 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITGAUSSIANUNWEIGHTEDPLUGIN_H #define FITGAUSSIANUNWEIGHTEDPLUGIN_H #include #include #include class FitGaussianUnweightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitGaussianUnweightedSource(Kst::ObjectStore *store); ~FitGaussianUnweightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitGaussianUnweightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitGaussianUnweightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/gaussian_unweighted/fitgaussian_unweighted.cpp000644 001750 001750 00000025401 11544160207 027411 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitgaussian_unweighted.h" #include "objectstore.h" #include "ui_fitgaussian_unweightedconfig.h" #define NUM_PARAMS 3 #define MAX_NUM_ITERATIONS 500 #include #include "../non_linear.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitGaussianUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitGaussian_UnweightedConfig { public: ConfigWidgetFitGaussianUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitGaussian_UnweightedConfig() { setupUi(this); } ~ConfigWidgetFitGaussianUnweightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitGaussianUnweightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Gaussian Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Gaussian Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitGaussianUnweightedSource::FitGaussianUnweightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitGaussianUnweightedSource::~FitGaussianUnweightedSource() { } QString FitGaussianUnweightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Unweighted Gaussian"); } void FitGaussianUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitGaussianUnweightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } } void FitGaussianUnweightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) { double dMin; double dMax; gsl_stats_minmax( &dMin, &dMax, pdX, 1, iLength ); pdParameterEstimates[0] = gsl_stats_mean( pdX, 1, iLength ); pdParameterEstimates[1] = ( dMax - dMin ) / 2.0; pdParameterEstimates[2] = gsl_stats_max( pdY, 1, iLength ); } double function_calculate( double dX, double* pdParameters ) { double dMean = pdParameters[0]; double dSD = pdParameters[1]; double dScale = pdParameters[2]; double dY; dY = ( dScale / ( dSD * M_SQRT2 * M_SQRTPI ) ); dY *= exp( -( ( dX - dMean ) * ( dX - dMean ) ) / ( 2.0 * dSD * dSD ) ); return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) { double dMean = pdParameters[0]; double dSD = pdParameters[1]; double dScale = pdParameters[2]; double dExp; double ddMean; double ddSD; double ddScale; dExp = exp( -( ( dX - dMean ) * ( dX - dMean ) ) / ( 2.0 * dSD * dSD ) ); ddMean = ( dX - dMean ) * dScale * dExp / ( dSD * dSD * dSD * M_SQRT2 * M_SQRTPI ); ddSD = dScale * dExp / ( dSD * dSD * M_SQRT2 * M_SQRTPI ); ddSD *= ( ( dX - dMean ) * ( dX - dMean ) / ( dSD * dSD ) ) - 1.0; ddScale = dExp / ( dSD * M_SQRT2 * M_SQRTPI ); pdDerivatives[0] = ddMean; pdDerivatives[1] = ddSD; pdDerivatives[2] = ddScale; } bool FitGaussianUnweightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Gaussian Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Gaussian Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; bReturn = kstfit_nonlinear( inputVectorX, inputVectorY, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar ); return bReturn; } Kst::VectorPtr FitGaussianUnweightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitGaussianUnweightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } QStringList FitGaussianUnweightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList FitGaussianUnweightedSource::inputScalarList() const { return QStringList(); } QStringList FitGaussianUnweightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitGaussianUnweightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitGaussianUnweightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitGaussianUnweightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitGaussianUnweightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitGaussianUnweightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Mean"; break; case 1: parameter = "SD"; break; case 2: parameter = "Scale"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitGaussianUnweightedPlugin::pluginName() const { return "Gaussian Fit"; } QString FitGaussianUnweightedPlugin::pluginDescription() const { return "Generates a gaussian fit for a set of data."; } Kst::DataObject *FitGaussianUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitGaussianUnweightedPlugin* config = static_cast(configWidget)) { FitGaussianUnweightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitGaussianUnweightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitGaussianUnweightedPlugin *widget = new ConfigWidgetFitGaussianUnweightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitGaussianUnweightedPlugin, FitGaussianUnweightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/gaussian_unweighted/gaussian_unweighted.pro000755 001750 001750 00000000356 11544160207 026731 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitgaussian_unweighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitgaussian_unweighted.cpp HEADERS += \ fitgaussian_unweighted.h FORMS += fitgaussian_unweightedconfig.ui kst-2.0.3/src/plugins/fits/lorentzian_weighted/fitlorentzian_weightedconfig.ui000644 001750 001750 00000006503 11544160207 030454 0ustar00synthsynth000000 000000 FitLorentzian_WeightedConfig 0 0 436 113 400 0 0 0 Input Vector - X false 0 0 0 0 Input Vector - Y false 0 0 0 0 Input Vector - Weights false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/lorentzian_weighted/lorentzian_weighted.pro000755 001750 001750 00000000356 11544160207 026751 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitlorentzian_weighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitlorentzian_weighted.cpp HEADERS += \ fitlorentzian_weighted.h FORMS += fitlorentzian_weightedconfig.ui kst-2.0.3/src/plugins/fits/lorentzian_weighted/kstplugin_fits_lorentzian_weighted.desktop000644 001750 001750 00000000431 11544160207 032736 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitlorentzian_weighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Gradient Lorentzian Plugin Comment=Implements a Gradient Lorentzian Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/lorentzian_weighted/fitlorentzian_weighted.cpp000644 001750 001750 00000027756 11544160207 027450 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitlorentzian_weighted.h" #include "objectstore.h" #include "ui_fitlorentzian_weightedconfig.h" #define NUM_PARAMS 3 #define MAX_NUM_ITERATIONS 500 #include #include "../non_linear_weighted.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_IN_WEIGHTS = "Weights Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitLorentzianWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitLorentzian_WeightedConfig { public: ConfigWidgetFitLorentzianWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitLorentzian_WeightedConfig() { setupUi(this); } ~ConfigWidgetFitLorentzianWeightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorWeights->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorWeights, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorWeights() { return _vectorWeights->selectedVector(); }; void setSelectedVectorWeights(Kst::VectorPtr vector) { return _vectorWeights->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitLorentzianWeightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorWeights(source->vectorWeights()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Lorentzian Weighted Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector Weights", _vectorWeights->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Lorentzian Weighted Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } vectorName = _cfg->value("Input Vector Weights").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorweights = static_cast(object); if (vectorweights) { setSelectedVectorX(vectorweights); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitLorentzianWeightedSource::FitLorentzianWeightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitLorentzianWeightedSource::~FitLorentzianWeightedSource() { } QString FitLorentzianWeightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Weighted Lorentzian"); } void FitLorentzianWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitLorentzianWeightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } } void FitLorentzianWeightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) { double dMin; double dMax; gsl_stats_minmax( &dMin, &dMax, pdX, 1, iLength ); pdParameterEstimates[0] = gsl_stats_mean( pdX, 1, iLength ); pdParameterEstimates[1] = ( dMax - dMin ) / 2.0; pdParameterEstimates[2] = gsl_stats_max( pdY, 1, iLength ); } double function_calculate( double dX, double* pdParameters ) { double dMean = pdParameters[0]; double dHW = pdParameters[1]; double dScale = pdParameters[2]; double dY; dY = ( dScale / M_PI ) * ( dHW / 2.0 ); dY /= ( ( dX - dMean ) * ( dX - dMean ) )+( ( dHW / 2.0 ) * ( dHW / 2.0 ) ); return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) { double dMean = pdParameters[0]; double dHW = pdParameters[1]; double dScale = pdParameters[2]; double dDenom; double ddMean; double ddHW; double ddScale; dDenom = ( ( dX - dMean ) * ( dX - dMean ) ) + ( ( dHW / 2.0 ) * ( dHW / 2.0 ) ); ddMean = ( dScale / M_PI ) * dHW * ( dMean - dX ) / ( dDenom * dDenom ); ddHW = ( dScale / ( 2.0 * M_PI ) ) / ( dDenom * dDenom ); ddHW *= dDenom - ( dHW * dHW / 2.0 ); ddScale = ( 1.0 / M_PI ) * ( dHW / 2.0 ) / dDenom; pdDerivatives[0] = ddMean; pdDerivatives[1] = ddHW; pdDerivatives[2] = ddScale; } bool FitLorentzianWeightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorWeights = _inputVectors[VECTOR_IN_WEIGHTS]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Lorentzian Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Lorentzian Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; bReturn = kstfit_nonlinear_weighted( inputVectorX, inputVectorY, inputVectorWeights, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar ); return bReturn; } Kst::VectorPtr FitLorentzianWeightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitLorentzianWeightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr FitLorentzianWeightedSource::vectorWeights() const { return _inputVectors[VECTOR_IN_WEIGHTS]; } QStringList FitLorentzianWeightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_WEIGHTS; return vectors; } QStringList FitLorentzianWeightedSource::inputScalarList() const { return QStringList(); } QStringList FitLorentzianWeightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitLorentzianWeightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitLorentzianWeightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitLorentzianWeightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitLorentzianWeightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitLorentzianWeightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Mean"; break; case 1: parameter = "Half-width"; break; case 2: parameter = "Scale"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitLorentzianWeightedPlugin::pluginName() const { return "Lorentzian Weighted Fit"; } QString FitLorentzianWeightedPlugin::pluginDescription() const { return "Generates a lorentzian weighted fit for a set of data."; } Kst::DataObject *FitLorentzianWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitLorentzianWeightedPlugin* config = static_cast(configWidget)) { FitLorentzianWeightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitLorentzianWeightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitLorentzianWeightedPlugin *widget = new ConfigWidgetFitLorentzianWeightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitLorentzianWeightedPlugin, FitLorentzianWeightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/lorentzian_weighted/fitlorentzian_weighted.h000644 001750 001750 00000005356 11544160207 027105 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITLORENTZIANWEIGHTEDPLUGIN_H #define FITLORENTZIANWEIGHTEDPLUGIN_H #include #include #include class FitLorentzianWeightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorWeights() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitLorentzianWeightedSource(Kst::ObjectStore *store); ~FitLorentzianWeightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitLorentzianWeightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitLorentzianWeightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/linear_weighted/fitlinear_weighted.h000644 001750 001750 00000005323 11544160207 025251 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITLINEARWEIGHTEDPLUGIN_H #define FITLINEARWEIGHTEDPLUGIN_H #include #include #include class FitLinearWeightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorWeights() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitLinearWeightedSource(Kst::ObjectStore *store); ~FitLinearWeightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitLinearWeightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitLinearWeightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/linear_weighted/kstplugin_fits_linear_weighted.desktop000644 001750 001750 00000000415 11544160207 031112 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitlinear_weighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Linear Weighted Plugin Comment=Implements a Linear Weighted Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/linear_weighted/fitlinear_weightedconfig.ui000644 001750 001750 00000006473 11544160207 026634 0ustar00synthsynth000000 000000 FitLinear_WeightedConfig 0 0 447 138 400 0 0 0 Input Vector - X false 0 0 0 0 Input Vector - Y false 0 0 0 0 Input Vector - Weights false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/linear_weighted/linear_weighted.pro000755 001750 001750 00000000336 11544160207 025121 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitlinear_weighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitlinear_weighted.cpp HEADERS += \ fitlinear_weighted.h FORMS += fitlinear_weightedconfig.ui kst-2.0.3/src/plugins/fits/linear_weighted/fitlinear_weighted.cpp000644 001750 001750 00000027671 11544160207 025616 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitlinear_weighted.h" #include "objectstore.h" #include "ui_fitlinear_weightedconfig.h" #include #include "../common.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_IN_WEIGHTS = "Weights Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& VECTOR_OUT_Y_LO = "Lo Vector"; static const QString& VECTOR_OUT_Y_HI = "Hi Vector"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitLinearWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitLinear_WeightedConfig { public: ConfigWidgetFitLinearWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitLinear_WeightedConfig() { setupUi(this); } ~ConfigWidgetFitLinearWeightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorWeights->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorWeights, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorWeights() { return _vectorWeights->selectedVector(); }; void setSelectedVectorWeights(Kst::VectorPtr vector) { return _vectorWeights->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitLinearWeightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorWeights(source->vectorWeights()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Linear Weighted Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector Weights", _vectorWeights->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Linear Weighted Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } vectorName = _cfg->value("Input Vector Weights").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorweights = static_cast(object); if (vectorweights) { setSelectedVectorX(vectorweights); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitLinearWeightedSource::FitLinearWeightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitLinearWeightedSource::~FitLinearWeightedSource() { } QString FitLinearWeightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Weighted Linear"); } void FitLinearWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitLinearWeightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } } void FitLinearWeightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputVector(VECTOR_OUT_Y_LO, ""); setOutputVector(VECTOR_OUT_Y_HI, ""); setOutputScalar(SCALAR_OUT, ""); } bool FitLinearWeightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorWeights = _inputVectors[VECTOR_IN_WEIGHTS]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::VectorPtr outputVectorYLo = _outputVectors[VECTOR_OUT_Y_LO]; Kst::VectorPtr outputVectorYHi = _outputVectors[VECTOR_OUT_Y_HI]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Linear Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Linear Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); label_info.name = i18n("Linear Fit Lower Limit"); outputVectorYLo->setLabelInfo(label_info); label_info.name = i18n("Linear Fit Upper Limit"); outputVectorYHi->setLabelInfo(label_info); int i = 0; int iLength; bool bReturn = false; double* pInputs[3]; double c0 = 0.0; double c1 = 0.0; double cov00 = 0.0; double cov01 = 0.0; double cov11 = 0.0; double dSumSq = 0.0; double y; double yErr; if( precursor( inputVectorX, inputVectorY, inputVectorWeights, &iLength, true, true, 2, pInputs, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputVectorYLo, outputVectorYHi ) ) { if( !gsl_fit_wlinear( pInputs[XVALUES], 1, pInputs[WEIGHTS], 1, pInputs[YVALUES], 1, iLength, &c0, &c1, &cov00, &cov01, &cov11, &dSumSq ) ) { for( i=0; ivalue()[i] = y; outputVectorYResiduals->value()[i] = pInputs[YVALUES][i] - y; outputVectorYLo->value()[i] = y - yErr; outputVectorYHi->value()[i] = y + yErr; } outputVectorYParameters->value()[0] = c0; outputVectorYParameters->value()[1] = c1; outputVectorYCovariance->value()[0] = cov00; outputVectorYCovariance->value()[1] = cov01; outputVectorYCovariance->value()[2] = cov11; outputScalar->setValue(dSumSq / ( (double)iLength - 2.0 )); bReturn = true; } } postcursor( true, pInputs ); return bReturn; } Kst::VectorPtr FitLinearWeightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitLinearWeightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr FitLinearWeightedSource::vectorWeights() const { return _inputVectors[VECTOR_IN_WEIGHTS]; } QStringList FitLinearWeightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_WEIGHTS; return vectors; } QStringList FitLinearWeightedSource::inputScalarList() const { return QStringList(); } QStringList FitLinearWeightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitLinearWeightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_LO; vectors += VECTOR_OUT_Y_HI; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitLinearWeightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitLinearWeightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitLinearWeightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitLinearWeightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Intercept"; break; case 1: parameter = "Gradient"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitLinearWeightedPlugin::pluginName() const { return "Linear Weighted Fit"; } QString FitLinearWeightedPlugin::pluginDescription() const { return "Generates a linear weighted fit for a set of data."; } Kst::DataObject *FitLinearWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitLinearWeightedPlugin* config = static_cast(configWidget)) { FitLinearWeightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitLinearWeightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitLinearWeightedPlugin *widget = new ConfigWidgetFitLinearWeightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitLinearWeightedPlugin, FitLinearWeightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/linear_weighted.h000644 001750 001750 00000013170 11544160207 021413 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include "common.h" double calculate_matrix_entry( double dX, int iPos ); extern "C" bool kstfit_linear_weighted( Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr weightsVector, Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals, Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance, Kst::ScalarPtr scalarOutChi, int iNumParams); bool kstfit_linear_weighted( Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr weightsVector, Kst::VectorPtr vectorOutYFitted, Kst::VectorPtr vectorOutYResiduals, Kst::VectorPtr vectorOutYParameters, Kst::VectorPtr vectorOutYCovariance, Kst::ScalarPtr scalarOutChi, int iNumParams) { gsl_matrix* pMatrixX = NULL; gsl_matrix* pMatrixCovariance = NULL; gsl_vector* pVectorY = NULL; gsl_vector* pVectorWeights = NULL; gsl_vector* pVectorParameters = NULL; gsl_multifit_linear_workspace* pWork = NULL; double dX; double dY; double dChiSq = 0.0; int i = 0; int j; int iStatus = 0; int iLength; bool bReturn = false; if (xVector->length() >= 2 && yVector->length() >= 2 && weightsVector->length() >= 2) { iLength = yVector->length(); if( xVector->length() > iLength ) { iLength = xVector->length(); } if( iLength > iNumParams + 1 ) { vectorOutYFitted->resize(iLength); vectorOutYResiduals->resize(iLength); vectorOutYParameters->resize(iNumParams); vectorOutYCovariance->resize(iNumParams * iNumParams); // create the matrices and vectors... // pMatrixX = gsl_matrix_alloc( iLength, iNumParams ); if( pMatrixX != NULL ) { pVectorY = gsl_vector_alloc( iLength ); if( pVectorY != NULL ) { pVectorParameters = gsl_vector_alloc( iNumParams ); if( pVectorParameters != NULL ) { pMatrixCovariance = gsl_matrix_alloc( iNumParams, iNumParams ); if( pMatrixCovariance != NULL ) { pWork = gsl_multifit_linear_alloc( iLength, iNumParams ); if( pWork != NULL ) { pVectorWeights = gsl_vector_alloc( iLength ); if( pVectorWeights != NULL ) { // // fill in the matrices and vectors... // for( i=0; ivalue(), yVector->length())); gsl_vector_set( pVectorWeights, i, interpolate(i, iLength, weightsVector->value(), weightsVector->length())); for( j=0; jvalue(), xVector->length()), j ); gsl_matrix_set( pMatrixX, i, j, dX ); } } iStatus = gsl_multifit_wlinear( pMatrixX, pVectorWeights, pVectorY, pVectorParameters, pMatrixCovariance, &dChiSq, pWork ); if( iStatus == 0 ) { // // fill in the output arrays and scalars... // for( i=0; ivalue()[i] = dY; vectorOutYResiduals->value()[i] = interpolate(i, iLength, yVector->value(), yVector->length()) - dY; } for( i=0; ivalue()[i] = gsl_vector_get( pVectorParameters, i ); for( j=0; jvalue()[(i*iNumParams)+j] = gsl_matrix_get( pMatrixCovariance, i, j ); } } scalarOutChi->setValue(dChiSq / ( (double)iLength - (double)iNumParams )); bReturn = true; } gsl_vector_free( pVectorWeights ); } gsl_multifit_linear_free( pWork ); } gsl_matrix_free( pMatrixCovariance ); } gsl_vector_free( pVectorParameters ); } gsl_vector_free( pVectorY ); } gsl_matrix_free( pMatrixX ); } } } return bReturn; } kst-2.0.3/src/plugins/fits/kneefrequency/kneefrequency.pro000755 001750 001750 00000000326 11544160207 024344 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitkneefrequency) LIBS += -l$$kstlib(gsl) SOURCES += \ fitkneefrequency.cpp HEADERS += \ fitkneefrequency.h FORMS += fitkneefrequencyconfig.ui kst-2.0.3/src/plugins/fits/kneefrequency/kstplugin_fits_kneefrequency.desktop000644 001750 001750 00000000411 11544160207 030332 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitkneefrequency X-Kst-Plugin-Author=The University of Toronto Name=Fits - Knee Frequency Plugin Comment=Implements a Knee Frequency Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/kneefrequency/fitkneefrequency.h000644 001750 001750 00000005420 11544160207 024473 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITKNEEFREQPLUGIN_H #define FITKNEEFREQPLUGIN_H #include #include #include class FitKneeFrequencySource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::ScalarPtr scalarMax() const; Kst::ScalarPtr scalarMin() const; Kst::ScalarPtr scalarWhiteNoise() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitKneeFrequencySource(Kst::ObjectStore *store); ~FitKneeFrequencySource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitKneeFrequencyPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitKneeFrequencyPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/kneefrequency/fitkneefrequencyconfig.ui000644 001750 001750 00000014231 11544160207 026047 0ustar00synthsynth000000 000000 FitKneeFrequencyConfig 0 0 427 215 400 0 0 0 Input Vector - X false Qt::Horizontal 40 20 0 0 0 0 Input Vector - Y false Qt::Horizontal 40 20 0 0 0 0 Input Scalar - Max. 1/f^a Freq false Qt::Horizontal 40 20 0 0 Input Scalar -Min. White Noise Freq false Qt::Horizontal 40 20 0 0 Input Scalar - White Noise C false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/fits/kneefrequency/fitkneefrequency.cpp000644 001750 001750 00000037357 11544160207 025044 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitkneefrequency.h" #include "objectstore.h" #include "ui_fitkneefrequencyconfig.h" #include #include "../common.h" #define KNEEFREQ_NUMPARAMETERS 5 static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& SCALAR_IN_MAX = "Max 1/f^a Freq Scalar"; static const QString& SCALAR_IN_MIN = "Min. White Noise Freq Scalar"; static const QString& SCALAR_IN_WHITENOISE = "White Noise C Scalar"; static const QString& VECTOR_OUT_Y_FITTED = "Y Fitted Vector"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals Vector"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; class ConfigWidgetFitKneeFrequencyPlugin : public Kst::DataObjectConfigWidget, public Ui_FitKneeFrequencyConfig { public: ConfigWidgetFitKneeFrequencyPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitKneeFrequencyConfig() { setupUi(this); } ~ConfigWidgetFitKneeFrequencyPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _scalarMax->setObjectStore(store); _scalarMin->setObjectStore(store); _scalarWhiteNoise->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarMax, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarMin, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarWhiteNoise, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarMax() { return _scalarMax->selectedScalar(); }; void setSelectedScalarMax(Kst::ScalarPtr scalar) { return _scalarMax->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarMin() { return _scalarMin->selectedScalar(); }; void setSelectedScalarMin(Kst::ScalarPtr scalar) { return _scalarMin->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarWhiteNoise() { return _scalarWhiteNoise->selectedScalar(); }; void setSelectedScalarWhiteNoise(Kst::ScalarPtr scalar) { return _scalarWhiteNoise->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitKneeFrequencySource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedScalarMax(source->scalarMax()); setSelectedScalarMin(source->scalarMin()); setSelectedScalarWhiteNoise(source->scalarWhiteNoise()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Knee Frequency Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Scalar Max 1/f^a Freq", _scalarMax->selectedScalar()->Name()); _cfg->setValue("Input Scalar Min. White Noise Freq", _scalarMin->selectedScalar()->Name()); _cfg->setValue("Input Scalar White Noise C", _scalarWhiteNoise->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Knee Frequency Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } QString scalarName = _cfg->value("Input Scalar Max 1/f^a Freq").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* maxScalar = static_cast(object); if (maxScalar) { setSelectedScalarMax(maxScalar); } scalarName = _cfg->value("Input Scalar Min. White Noise Freq").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* minScalar = static_cast(object); if (minScalar) { setSelectedScalarMin(minScalar); } scalarName = _cfg->value("Input Scalar White Noise C").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* whiteNoiseScalar = static_cast(object); if (whiteNoiseScalar) { setSelectedScalarWhiteNoise(whiteNoiseScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitKneeFrequencySource::FitKneeFrequencySource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitKneeFrequencySource::~FitKneeFrequencySource() { } QString FitKneeFrequencySource::_automaticDescriptiveName() const { return QString("Fit Knee Frequency Plugin"); } void FitKneeFrequencySource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitKneeFrequencyPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputScalar(SCALAR_IN_MAX, config->selectedScalarMax()); setInputScalar(SCALAR_IN_MIN, config->selectedScalarMin()); setInputScalar(SCALAR_IN_WHITENOISE, config->selectedScalarWhiteNoise()); } } void FitKneeFrequencySource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); } bool FitKneeFrequencySource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::ScalarPtr inputScalarMax = _inputScalars[SCALAR_IN_MAX]; Kst::ScalarPtr inputScalarMin = _inputScalars[SCALAR_IN_MIN]; Kst::ScalarPtr inputScalarWhiteNoise = _inputScalars[SCALAR_IN_WHITENOISE]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; if (inputVectorX->length() != inputVectorY->length()) { _errorString = "Error: Input Vector Sizes do not match"; return false; } if (inputVectorX->length() < 1) { _errorString = "Error: Input Vector X invalid"; return false; } int inArraysLength = inputVectorX->length(); outputVectorYFitted->resize(inArraysLength); outputVectorYResiduals->resize(inArraysLength); outputVectorYParameters->resize(KNEEFREQ_NUMPARAMETERS); double xi, yi; int i; double maxOneOverFFreq, minWhiteNoiseFreq, whiteNoiseC; maxOneOverFFreq = inputScalarMax->value(); minWhiteNoiseFreq = inputScalarMin->value(); whiteNoiseC = inputScalarWhiteNoise->value(); int maxOneOverFIndex, minWhiteNoiseIndex; //fast calculation of index for maxOneOverFFreq int i_bot = 0; int i_top = inArraysLength - 1; while (i_bot + 1 < i_top) { int i0 = (i_top + i_bot)/2; if (maxOneOverFFreq < inputVectorX->value()[i0]) { i_top = i0; } else { i_bot = i0; } } maxOneOverFIndex = i_top; //top because we use i_bot+1. //fast calculation of index for minWhiteNoiseFreq i_bot = 0; i_top = inArraysLength - 1; while (i_bot + 1 < i_top) { int i0 = (i_top + i_bot)/2; if (minWhiteNoiseFreq < inputVectorX->value()[i0]) { i_top = i0; } else { i_bot = i0; } } minWhiteNoiseIndex = i_top; //verify calculated indices. if ( !(maxOneOverFIndex>0) || !(minWhiteNoiseIndex>=maxOneOverFIndex) || !(minWhiteNoiseIndex<(inArraysLength-1)) ) { _errorString = "Error: Input Frequencies are Invalid\n"; return false; } // calculate white noise limit double sumY, sumY2; sumY = sumY2 = 0; for (i = minWhiteNoiseIndex; i < inArraysLength; i++) { yi = inputVectorY->value()[i]; sumY += yi; sumY2 += pow(yi,2); } double ybar, ysigma; ybar = sumY/(inArraysLength - minWhiteNoiseIndex); ysigma = sqrt((sumY2 - 2*ybar*sumY + pow(ybar,2)*(inArraysLength - minWhiteNoiseIndex))/(inArraysLength - minWhiteNoiseIndex)); // end calculate white noise limit // fit 1/f noise double sumLnXLnY, sumLnX, sumLnY, sumLnX2; sumLnXLnY = sumLnX = sumLnY = sumLnX2 = 0; for (i = 0; i < maxOneOverFIndex; i++) { xi = inputVectorX->value()[i]; yi = inputVectorY->value()[i]; if (!(xi>0) || !((yi-ybar)>0)) { _errorString = "Error: Input Data Invalid.\n"; return false; } sumLnXLnY += log(xi)*log(yi-ybar); //-ybar to isolate 1/f noise. sumLnX += log(xi); sumLnY += log(yi-ybar); sumLnX2 += pow(log(xi),2); } double a, b; a = (maxOneOverFIndex*sumLnXLnY - sumLnX*sumLnY)/(maxOneOverFIndex*sumLnX2 - pow(sumLnX,2)); b = exp((sumLnY - a*sumLnX)/maxOneOverFIndex); // end fit 1/f noise double knee_freq = pow(ybar*whiteNoiseC/b,1.0/a); // calculate knee frequency. // output fit data for (i = 0; i < maxOneOverFIndex; i++) { outputVectorYFitted->value()[i] = b * pow(inputVectorX->value()[i],a) + ybar; outputVectorYResiduals->value()[i] = inputVectorY->value()[i] - outputVectorYFitted->value()[i]; } for (i = maxOneOverFIndex; i < minWhiteNoiseIndex; i++) { // zeros for unfitted region. outputVectorYFitted->value()[i] = 0; outputVectorYResiduals->value()[i] = 0; } for (i = minWhiteNoiseIndex; i < inArraysLength; i++) { outputVectorYFitted->value()[i] = ybar; outputVectorYResiduals->value()[i] = outputVectorYFitted->value()[i] - ybar; } outputVectorYParameters->value()[0] = ybar; outputVectorYParameters->value()[1] = ysigma; outputVectorYParameters->value()[2] = b; outputVectorYParameters->value()[3] = -a; outputVectorYParameters->value()[4] = knee_freq; return true; } Kst::VectorPtr FitKneeFrequencySource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitKneeFrequencySource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::ScalarPtr FitKneeFrequencySource::scalarMax() const { return _inputScalars[SCALAR_IN_MAX]; } Kst::ScalarPtr FitKneeFrequencySource::scalarMin() const { return _inputScalars[SCALAR_IN_MIN]; } Kst::ScalarPtr FitKneeFrequencySource::scalarWhiteNoise() const { return _inputScalars[SCALAR_IN_WHITENOISE]; } QStringList FitKneeFrequencySource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList FitKneeFrequencySource::inputScalarList() const { QStringList scalars(SCALAR_IN_MAX); scalars += SCALAR_IN_MIN; scalars += SCALAR_IN_WHITENOISE; return scalars; } QStringList FitKneeFrequencySource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitKneeFrequencySource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitKneeFrequencySource::outputScalarList() const { return QStringList( /*SCALAR_OUT */); } QStringList FitKneeFrequencySource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitKneeFrequencySource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitKneeFrequencySource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "White Noise Limit"; break; case 1: parameter = "White Noise Sigma"; break; case 2: parameter = "1/f^a Amplitude"; break; case 3: parameter = "1/f^a Power Law a"; break; case 4: parameter = "Knee Frequency"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitKneeFrequencyPlugin::pluginName() const { return "Knee Frequency Fit"; } QString FitKneeFrequencyPlugin::pluginDescription() const { return "Generates a knee frequency fit for a set of data."; } Kst::DataObject *FitKneeFrequencyPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitKneeFrequencyPlugin* config = static_cast(configWidget)) { Kst::ScalarPtr max; Kst::ScalarPtr min; Kst::ScalarPtr noise; if (setupInputsOutputs) { max = config->selectedScalarMax(); min = config->selectedScalarMin(); noise = config->selectedScalarWhiteNoise(); } FitKneeFrequencySource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputScalar(SCALAR_IN_MAX, max); object->setInputScalar(SCALAR_IN_MIN, min); object->setInputScalar(SCALAR_IN_WHITENOISE, noise); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitKneeFrequencyPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitKneeFrequencyPlugin *widget = new ConfigWidgetFitKneeFrequencyPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitKneeFrequencyPlugin, FitKneeFrequencyPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/exponential_weighted/kstplugin_fits_exponential_weighted.desktop000644 001750 001750 00000000434 11544160207 033243 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitexponential_weighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Gradient Exponential Plugin Comment=Implements a Gradient Exponential Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/exponential_weighted/exponential_weighted.pro000755 001750 001750 00000000362 11544160207 027250 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitexponential_weighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitexponential_weighted.cpp HEADERS += \ fitexponential_weighted.h FORMS += fitexponential_weightedconfig.ui kst-2.0.3/src/plugins/fits/exponential_weighted/fitexponential_weightedconfig.ui000644 001750 001750 00000006350 11544160207 030756 0ustar00synthsynth000000 000000 FitExponential_WeightedConfig 0 0 559 100 0 0 X: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Weights: false 0 0 400 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/fits/exponential_weighted/fitexponential_weighted.cpp000644 001750 001750 00000027213 11544160207 027736 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitexponential_weighted.h" #include "objectstore.h" #include "ui_fitexponential_weightedconfig.h" #define NUM_PARAMS 3 #define MAX_NUM_ITERATIONS 500 #include #include "../non_linear_weighted.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_IN_WEIGHTS = "Weights Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitExponentialWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitExponential_WeightedConfig { public: ConfigWidgetFitExponentialWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitExponential_WeightedConfig() { setupUi(this); } ~ConfigWidgetFitExponentialWeightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorWeights->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorWeights, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorWeights() { return _vectorWeights->selectedVector(); }; void setSelectedVectorWeights(Kst::VectorPtr vector) { return _vectorWeights->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitExponentialWeightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorWeights(source->vectorWeights()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Exponential Weighted Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector Weights", _vectorWeights->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Exponential Weighted Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } vectorName = _cfg->value("Input Vector Weights").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorweights = static_cast(object); if (vectorweights) { setSelectedVectorX(vectorweights); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitExponentialWeightedSource::FitExponentialWeightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitExponentialWeightedSource::~FitExponentialWeightedSource() { } QString FitExponentialWeightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Weighted Exponential"); } void FitExponentialWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitExponentialWeightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } } void FitExponentialWeightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) { Q_UNUSED( pdX ) Q_UNUSED( pdY ) Q_UNUSED( iLength ) pdParameterEstimates[0] = 1.0; pdParameterEstimates[1] = 0.0; pdParameterEstimates[2] = 0.0; } double function_calculate( double dX, double* pdParameters ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dOffset = pdParameters[2]; double dY; dY = ( dScale * exp( -dLambda * dX ) ) + dOffset; return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dExp; double ddScale; double ddLambda; double ddOffset; dExp = exp( -dLambda * dX ); ddScale = dExp; ddLambda = -dX * dScale * dExp; ddOffset = 1.0; pdDerivatives[0] = ddScale; pdDerivatives[1] = ddLambda; pdDerivatives[2] = ddOffset; } bool FitExponentialWeightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorWeights = _inputVectors[VECTOR_IN_WEIGHTS]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Exponential Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Exponential Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; bReturn = kstfit_nonlinear_weighted( inputVectorX, inputVectorY, inputVectorWeights, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar ); return bReturn; } Kst::VectorPtr FitExponentialWeightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitExponentialWeightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr FitExponentialWeightedSource::vectorWeights() const { return _inputVectors[VECTOR_IN_WEIGHTS]; } QStringList FitExponentialWeightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_WEIGHTS; return vectors; } QStringList FitExponentialWeightedSource::inputScalarList() const { return QStringList(); } QStringList FitExponentialWeightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitExponentialWeightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitExponentialWeightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitExponentialWeightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitExponentialWeightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitExponentialWeightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Scale"; break; case 1: parameter = "Lambda"; break; case 2: parameter = "Offset"; break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitExponentialWeightedPlugin::pluginName() const { return "Exponential Weighted Fit"; } QString FitExponentialWeightedPlugin::pluginDescription() const { return "Generates a exponential weighted fit for a set of data."; } Kst::DataObject *FitExponentialWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitExponentialWeightedPlugin* config = static_cast(configWidget)) { FitExponentialWeightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitExponentialWeightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitExponentialWeightedPlugin *widget = new ConfigWidgetFitExponentialWeightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitExponentialWeightedPlugin, FitExponentialWeightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/exponential_weighted/fitexponential_weighted.h000644 001750 001750 00000005365 11544160207 027407 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITEXPONENTIALWEIGHTEDPLUGIN_H #define FITEXPONENTIALWEIGHTEDPLUGIN_H #include #include #include class FitExponentialWeightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorWeights() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitExponentialWeightedSource(Kst::ObjectStore *store); ~FitExponentialWeightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitExponentialWeightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitExponentialWeightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/polynomial_unweighted/fitpolynomial_unweightedconfig.ui000644 001750 001750 00000006317 11544160207 031361 0ustar00synthsynth000000 000000 FitPolynomial_UnweightedConfig 0 0 421 165 400 0 0 0 X: false 0 0 0 0 Y: false 0 0 0 0 Order: false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/fits/polynomial_unweighted/fitpolynomial_unweighted.cpp000644 001750 001750 00000027441 11544160207 030341 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitpolynomial_unweighted.h" #include "objectstore.h" #include "ui_fitpolynomial_unweightedconfig.h" #include // #include "../common.h" #include "../linear.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_IN = "Order Scalar"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitPolynomialUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitPolynomial_UnweightedConfig { public: ConfigWidgetFitPolynomialUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitPolynomial_UnweightedConfig() { setupUi(this); } ~ConfigWidgetFitPolynomialUnweightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _scalarOrder->setObjectStore(store); _scalarOrder->setDefaultValue(2); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarOrder, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarOrder() { return _scalarOrder->selectedScalar(); }; void setSelectedScalarOrder(Kst::ScalarPtr scalar) { return _scalarOrder->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitPolynomialUnweightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedScalarOrder(source->scalarOrder()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Polynomial Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Scalar Order", _scalarOrder->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Polynomial Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } QString scalarName = _cfg->value("Input Order Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* orderScalar = static_cast(object); if (orderScalar) { setSelectedScalarOrder(orderScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitPolynomialUnweightedSource::FitPolynomialUnweightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitPolynomialUnweightedSource::~FitPolynomialUnweightedSource() { } QString FitPolynomialUnweightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Polynomial"); } void FitPolynomialUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitPolynomialUnweightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputScalar(SCALAR_IN, config->selectedScalarOrder()); } } void FitPolynomialUnweightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } double calculate_matrix_entry( double dX, int iPos ) { double dY; dY = pow( dX, (double)iPos ); return dY; } bool FitPolynomialUnweightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::ScalarPtr inputScalarOrder = _inputScalars[SCALAR_IN]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Polynomial Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Polynomial Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; int iNumParams; iNumParams = 1 + (int)floor( inputScalarOrder->value() ); if( iNumParams > 0 ) { bReturn = kstfit_linear_unweighted( inputVectorX, inputVectorY, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar, iNumParams ); } return bReturn; } // TODO merge with FitPolynomialWeightedSource QString FitPolynomialUnweightedSource::parameterVectorToString() const { QString str = Name(); if (hasParameterVector()) { Kst::VectorPtr vectorParam = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; for (int i = 0; i < vectorParam->length(); i++) { QString paramName = parameterName(i); if (!paramName.isEmpty()) { if (_outputScalars.contains(paramName)) { QString name = _outputScalars[paramName]->Name(); double value = _outputScalars[paramName]->value(); QString sign; if (value >= 0) { sign = " +"; } else { sign = " "; // Just for the space, the "-" is already in the number } if (i == 0) { str += QString("\n[%1]").arg(name); } else if (i == 1) { // Special case x^1 to x str += QString("%1[%2]x").arg(sign).arg(name); } else { str += QString("%1[%2]%3").arg(sign).arg(name).arg(paramName); } } } } } return str; } Kst::VectorPtr FitPolynomialUnweightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitPolynomialUnweightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::ScalarPtr FitPolynomialUnweightedSource::scalarOrder() const { return _inputScalars[SCALAR_IN]; } QStringList FitPolynomialUnweightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList FitPolynomialUnweightedSource::inputScalarList() const { return QStringList(SCALAR_IN); } QStringList FitPolynomialUnweightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitPolynomialUnweightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitPolynomialUnweightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitPolynomialUnweightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitPolynomialUnweightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitPolynomialUnweightedSource::parameterName(int index) const { return QString("x^%1").arg(index); } // Name used to identify the plugin. Used when loading the plugin. QString FitPolynomialUnweightedPlugin::pluginName() const { return "Polynomial Fit"; } QString FitPolynomialUnweightedPlugin::pluginDescription() const { return "Generates a polynomial fit for a set of data."; } Kst::DataObject *FitPolynomialUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitPolynomialUnweightedPlugin* config = static_cast(configWidget)) { Kst::ScalarPtr order; if (setupInputsOutputs) { order = config->selectedScalarOrder(); } FitPolynomialUnweightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputScalar(SCALAR_IN, order); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitPolynomialUnweightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitPolynomialUnweightedPlugin *widget = new ConfigWidgetFitPolynomialUnweightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitPolynomialUnweightedPlugin, FitPolynomialUnweightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/polynomial_unweighted/fitpolynomial_unweighted.h000644 001750 001750 00000005457 11544160207 030011 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITPOLYNOMIALUNWEIGHTEDPLUGIN_H #define FITPOLYNOMIALUNWEIGHTEDPLUGIN_H #include #include #include class FitPolynomialUnweightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::ScalarPtr scalarOrder() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitPolynomialUnweightedSource(Kst::ObjectStore *store); ~FitPolynomialUnweightedSource(); virtual QString parameterName(int index) const; virtual QString parameterVectorToString() const; friend class Kst::ObjectStore; }; class FitPolynomialUnweightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitPolynomialUnweightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/polynomial_unweighted/kstplugin_fits_polynomial_unweighted.desktop000644 001750 001750 00000000411 11544160207 033636 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitpolynomial_unweighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Polynomial Plugin Comment=Implements a Polynomial Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/polynomial_unweighted/polynomial_unweighted.pro000755 001750 001750 00000000366 11544160207 027654 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitpolynomial_unweighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitpolynomial_unweighted.cpp HEADERS += \ fitpolynomial_unweighted.h FORMS += fitpolynomial_unweightedconfig.ui kst-2.0.3/src/plugins/fits/sinusoid_unweighted/fitsinusoid_unweighted.cpp000644 001750 001750 00000031176 11544160207 027465 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fitsinusoid_unweighted.h" #include "objectstore.h" #include "ui_fitsinusoid_unweightedconfig.h" #include // #include "../common.h" #include "../linear.h" static const QString& VECTOR_IN_X = "X Vector"; static const QString& VECTOR_IN_Y = "Y Vector"; static const QString& VECTOR_OUT_Y_FITTED = "Fit"; static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals"; static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector"; static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance"; static const QString& SCALAR_IN_PERIOD = "Period Scalar"; static const QString& SCALAR_IN_HARMONICS = "Harmonics Scalar"; static const QString& SCALAR_OUT = "chi^2/nu"; class ConfigWidgetFitSinusoidUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitSinusoid_UnweightedConfig { public: ConfigWidgetFitSinusoidUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitSinusoid_UnweightedConfig() { setupUi(this); } ~ConfigWidgetFitSinusoidUnweightedPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _scalarHarmonics->setObjectStore(store); _scalarPeriod->setObjectStore(store); _scalarHarmonics->setDefaultValue(0); _scalarPeriod->setDefaultValue(1); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarHarmonics, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarPeriod, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } void setVectorX(Kst::VectorPtr vector) { setSelectedVectorX(vector); } void setVectorY(Kst::VectorPtr vector) { setSelectedVectorY(vector); } void setVectorsLocked(bool locked = true) { _vectorX->setEnabled(!locked); _vectorY->setEnabled(!locked); } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarHarmonics() { return _scalarHarmonics->selectedScalar(); }; void setSelectedScalarHarmonics(Kst::ScalarPtr scalar) { return _scalarHarmonics->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarPeriod() { return _scalarPeriod->selectedScalar(); }; void setSelectedScalarPeriod(Kst::ScalarPtr scalar) { return _scalarPeriod->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (FitSinusoidUnweightedSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedScalarHarmonics(source->scalarHarmonics()); setSelectedScalarPeriod(source->scalarPeriod()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Fit Sinusoid Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Scalar Harmonics", _scalarHarmonics->selectedScalar()->Name()); _cfg->setValue("Input Scalar Period", _scalarPeriod->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Fit Sinusoid Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorx = static_cast(object); if (vectorx) { setSelectedVectorX(vectorx); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorX(vectory); } QString scalarName = _cfg->value("Harmonics Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* harmonicsScalar = static_cast(object); if (harmonicsScalar) { setSelectedScalarHarmonics(harmonicsScalar); } scalarName = _cfg->value("Period Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* periodScalar = static_cast(object); if (periodScalar) { setSelectedScalarPeriod(periodScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; FitSinusoidUnweightedSource::FitSinusoidUnweightedSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } FitSinusoidUnweightedSource::~FitSinusoidUnweightedSource() { } QString FitSinusoidUnweightedSource::_automaticDescriptiveName() const { return vectorY()->descriptiveName() + i18n(" Sinusoid"); } void FitSinusoidUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetFitSinusoidUnweightedPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputScalar(SCALAR_IN_HARMONICS, config->selectedScalarHarmonics()); setInputScalar(SCALAR_IN_PERIOD, config->selectedScalarPeriod()); } } void FitSinusoidUnweightedSource::setupOutputs() { setOutputVector(VECTOR_OUT_Y_FITTED, ""); setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); setOutputScalar(SCALAR_OUT, ""); } double g_dPeriod; double calculate_matrix_entry( double dX, int iPos ) { double dY; if( iPos == 0 ) { dY = 1.0; } else if( iPos % 2 == 1 ) { dY = cos( (double)( ( iPos + 1 ) / 2 ) * 2.0 * M_PI * dX / g_dPeriod ); } else { dY = -sin( (double)( ( iPos + 0 ) / 2 ) * 2.0 * M_PI * dX / g_dPeriod ); } return dY; } bool FitSinusoidUnweightedSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::ScalarPtr inputScalarHarmonics = _inputScalars[SCALAR_IN_HARMONICS]; Kst::ScalarPtr inputScalarPeriod = _inputScalars[SCALAR_IN_PERIOD]; Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; Kst::LabelInfo label_info = inputVectorY->labelInfo(); label_info.name = i18n("Sinusoidal Fit to %1").arg(label_info.name); outputVectorYFitted->setLabelInfo(label_info); label_info.name = i18n("Sinusoidal Fit Residuals"); outputVectorYResiduals->setLabelInfo(label_info); bool bReturn = false; int iNumParams; iNumParams = 3 + ( 2 * (int)floor( inputScalarHarmonics->value() ) ); if( iNumParams >= 3 ) { g_dPeriod = inputScalarPeriod->value(); if( g_dPeriod > 0.0 ) { bReturn = kstfit_linear_unweighted( inputVectorX, inputVectorY, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputScalar, iNumParams ); } } return bReturn; } Kst::VectorPtr FitSinusoidUnweightedSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr FitSinusoidUnweightedSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::ScalarPtr FitSinusoidUnweightedSource::scalarHarmonics() const { return _inputScalars[SCALAR_IN_HARMONICS]; } Kst::ScalarPtr FitSinusoidUnweightedSource::scalarPeriod() const { return _inputScalars[SCALAR_IN_PERIOD]; } QStringList FitSinusoidUnweightedSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList FitSinusoidUnweightedSource::inputScalarList() const { QStringList scalars(SCALAR_IN_HARMONICS); scalars += SCALAR_IN_PERIOD; return scalars; } QStringList FitSinusoidUnweightedSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList FitSinusoidUnweightedSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_Y_FITTED); vectors += VECTOR_OUT_Y_RESIDUALS; vectors += VECTOR_OUT_Y_PARAMETERS; vectors += VECTOR_OUT_Y_COVARIANCE; vectors += VECTOR_OUT_Y_PARAMETERS; return vectors; } QStringList FitSinusoidUnweightedSource::outputScalarList() const { return QStringList( SCALAR_OUT ); } QStringList FitSinusoidUnweightedSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void FitSinusoidUnweightedSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString FitSinusoidUnweightedSource::parameterName(int index) const { QString parameter; switch (index) { case 0: parameter = "Mean"; break; case 1: parameter = "cos(%1 2PI x/P)"; parameter.arg((index + 1 ) / 2); break; case 2: parameter = "-sin(%1 2PI x/P)"; parameter.arg((index + 0 ) / 2); break; } return parameter; } // Name used to identify the plugin. Used when loading the plugin. QString FitSinusoidUnweightedPlugin::pluginName() const { return "Sinusoid Fit"; } QString FitSinusoidUnweightedPlugin::pluginDescription() const { return "Generates a sinusoid fit for a set of data."; } Kst::DataObject *FitSinusoidUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetFitSinusoidUnweightedPlugin* config = static_cast(configWidget)) { Kst::ScalarPtr harmonics; Kst::ScalarPtr period; if (setupInputsOutputs) { harmonics = config->selectedScalarHarmonics(); period = config->selectedScalarPeriod(); } FitSinusoidUnweightedSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputScalar(SCALAR_IN_HARMONICS, harmonics); object->setInputScalar(SCALAR_IN_PERIOD, period); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *FitSinusoidUnweightedPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetFitSinusoidUnweightedPlugin *widget = new ConfigWidgetFitSinusoidUnweightedPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_FitSinusoidUnweightedPlugin, FitSinusoidUnweightedPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/sinusoid_unweighted/sinusoid_unweighted.pro000755 001750 001750 00000000356 11544160207 026777 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_fitsinusoid_unweighted) LIBS += -l$$kstlib(gsl) SOURCES += \ fitsinusoid_unweighted.cpp HEADERS += \ fitsinusoid_unweighted.h FORMS += fitsinusoid_unweightedconfig.ui kst-2.0.3/src/plugins/fits/sinusoid_unweighted/kstplugin_fits_sinusoid_unweighted.desktop000644 001750 001750 00000000403 11544160207 032763 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=fitsinusoid_unweighted X-Kst-Plugin-Author=The University of Toronto Name=Fits - Sinusoid Plugin Comment=Implements a Sinusoid Fits Plugin for Kst. kst-2.0.3/src/plugins/fits/sinusoid_unweighted/fitsinusoid_unweighted.h000644 001750 001750 00000005431 11544160207 027125 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITSINUSOIDUNWEIGHTEDPLUGIN_H #define FITSINUSOIDUNWEIGHTEDPLUGIN_H #include #include #include class FitSinusoidUnweightedSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::ScalarPtr scalarHarmonics() const; Kst::ScalarPtr scalarPeriod() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: FitSinusoidUnweightedSource(Kst::ObjectStore *store); ~FitSinusoidUnweightedSource(); virtual QString parameterName(int index) const; friend class Kst::ObjectStore; }; class FitSinusoidUnweightedPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~FitSinusoidUnweightedPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Fit; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/fits/sinusoid_unweighted/fitsinusoid_unweightedconfig.ui000644 001750 001750 00000007464 11544160207 030511 0ustar00synthsynth000000 000000 FitSinusoid_UnweightedConfig 0 0 421 200 400 0 0 0 X: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Y: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false 0 0 0 0 Harmonics: false 0 0 Period: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/shift/shift.h000644 001750 001750 00000005041 11544160207 021644 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SHIFTPLUGIN_H #define SHIFTPLUGIN_H #include #include #include class ShiftSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr scalar() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: ShiftSource(Kst::ObjectStore *store); ~ShiftSource(); friend class Kst::ObjectStore; }; class ShiftPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~ShiftPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/shift/shiftconfig.ui000644 001750 001750 00000005744 11544160207 023232 0ustar00synthsynth000000 000000 ShiftConfig 0 0 426 106 400 0 0 0 Input Vector false Qt::Horizontal 40 20 0 0 0 0 Shift value (# points, negative allowed) false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/shift/shift.cpp000644 001750 001750 00000017433 11544160207 022207 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* shift a vector by an integer number of samples */ #include "shift.h" #include "objectstore.h" #include "ui_shiftconfig.h" #include "math_kst.h" static const QString& VECTOR_IN = "Vector In"; static const QString& SCALAR_IN = "Shift value (# points, negative allowed)"; static const QString& VECTOR_OUT = "Shifted Vector"; class ConfigWidgetShiftPlugin : public Kst::DataObjectConfigWidget, public Ui_ShiftConfig { public: ConfigWidgetShiftPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_ShiftConfig() { setupUi(this); } ~ConfigWidgetShiftPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarShift->setObjectStore(store); _scalarShift->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarShift, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalar() { return _scalarShift->selectedScalar(); }; void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarShift->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (ShiftSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedScalar(source->scalar()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Shift DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Input Scalar Shift", _scalarShift->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Shift DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Input Scalar Shift").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalar = static_cast(object); if (scalar) { setSelectedScalar(scalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; ShiftSource::ShiftSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } ShiftSource::~ShiftSource() { } QString ShiftSource::_automaticDescriptiveName() const { return QString("Shift Plugin Object"); } void ShiftSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetShiftPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_IN, config->selectedScalar()); } } void ShiftSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool ShiftSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; int delay = 0; /* Memory allocation */ outputVector->resize(inputVector->length(), false); delay = (int)inputScalar->value(); /* Protect against invalid inputs */ if (delay > inputVector->length()) { delay = inputVector->length(); } else if (delay < -inputVector->length()) { delay = -inputVector->length(); } /* First case: positive shift (forwards/right shift)*/ if (delay >= 0) { /* Pad beginning with zeros */ for (int i = 0; i < delay; i++) { outputVector->value()[i] = NAN; } /* Then, copy values with the right offset */ for (int i = delay; i < inputVector->length(); i++) { outputVector->value()[i] = inputVector->value()[i-delay]; } } /* Second case: negative shift (backwards/left shift)*/ else if (delay < 0) { delay = -delay; /* Easier to visualize :-) */ /* Copy values with the right offset */ for (int i = 0; i < inputVector->length()-delay; i++) { outputVector->value()[i] = inputVector->value()[i+delay]; } /* Pad end with zeros */ for (int i = inputVector->length()-delay; i < inputVector->length(); i++) { outputVector->value()[i] = NAN; } } return true; } Kst::VectorPtr ShiftSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr ShiftSource::scalar() const { return _inputScalars[SCALAR_IN]; } QStringList ShiftSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList ShiftSource::inputScalarList() const { return QStringList( SCALAR_IN ); } QStringList ShiftSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList ShiftSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList ShiftSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList ShiftSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void ShiftSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString ShiftPlugin::pluginName() const { return "Shift"; } QString ShiftPlugin::pluginDescription() const { return "Shifts (and truncates) a vector."; } Kst::DataObject *ShiftPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetShiftPlugin* config = static_cast(configWidget)) { ShiftSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_IN, config->selectedScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *ShiftPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetShiftPlugin *widget = new ConfigWidgetShiftPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, ShiftPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/shift/shift.pro000644 001750 001750 00000000222 11544160207 022211 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_shift) SOURCES += \ shift.cpp HEADERS += \ shift.h FORMS += shiftconfig.ui kst-2.0.3/src/plugins/dataobject/shift/kstplugin_shift.desktop000644 001750 001750 00000000370 11544160207 025166 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=shift X-Kst-Plugin-Author=The University of Toronto Name=Shift Data Object Plugin Comment=Implements a Shift Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/statistics/statistics.cpp000644 001750 001750 00000024642 11544160207 024341 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "statistics.h" #include "objectstore.h" #include "ui_statisticsconfig.h" static const QString& VECTOR_IN = "Vector In"; static const QString& SCALAR_OUT_MEAN = "Mean"; static const QString& SCALAR_OUT_MINIMUM = "Minimum"; static const QString& SCALAR_OUT_MAXIMUM = "Maximum"; static const QString& SCALAR_OUT_VARIANCE = "Variance"; static const QString& SCALAR_OUT_STANDARD_DEVIATION = "Standard deviation"; static const QString& SCALAR_OUT_MEDIAN = "Median"; static const QString& SCALAR_OUT_ABSOLUTE_DEVIATION = "Absolute deviation"; static const QString& SCALAR_OUT_SKEWNESS = "Skewness"; static const QString& SCALAR_OUT_KURTOSIS = "Kurtosis"; class ConfigWidgetStatisticsPlugin : public Kst::DataObjectConfigWidget, public Ui_StatisticsConfig { public: ConfigWidgetStatisticsPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_StatisticsConfig() { setupUi(this); } ~ConfigWidgetStatisticsPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (StatisticsSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Statistics DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Statistics DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; StatisticsSource::StatisticsSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } StatisticsSource::~StatisticsSource() { } QString StatisticsSource::_automaticDescriptiveName() const { return QString("Statistics Plugin Object"); } void StatisticsSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetStatisticsPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); } } void StatisticsSource::setupOutputs() { setOutputScalar(SCALAR_OUT_MEAN, ""); setOutputScalar(SCALAR_OUT_MINIMUM, ""); setOutputScalar(SCALAR_OUT_MAXIMUM, ""); setOutputScalar(SCALAR_OUT_VARIANCE, ""); setOutputScalar(SCALAR_OUT_STANDARD_DEVIATION, ""); setOutputScalar(SCALAR_OUT_MEDIAN, ""); setOutputScalar(SCALAR_OUT_ABSOLUTE_DEVIATION, ""); setOutputScalar(SCALAR_OUT_SKEWNESS, ""); setOutputScalar(SCALAR_OUT_KURTOSIS, ""); } bool StatisticsSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr outputScalarMean = _outputScalars[SCALAR_OUT_MEAN]; Kst::ScalarPtr outputScalarMin = _outputScalars[SCALAR_OUT_MINIMUM]; Kst::ScalarPtr outputScalarMax = _outputScalars[SCALAR_OUT_MAXIMUM]; Kst::ScalarPtr outputScalarVariance = _outputScalars[SCALAR_OUT_VARIANCE]; Kst::ScalarPtr outputScalarSD = _outputScalars[SCALAR_OUT_STANDARD_DEVIATION]; Kst::ScalarPtr outputScalarMedian = _outputScalars[SCALAR_OUT_MEDIAN]; Kst::ScalarPtr outputScalarAD = _outputScalars[SCALAR_OUT_ABSOLUTE_DEVIATION]; Kst::ScalarPtr outputScalarSkewness = _outputScalars[SCALAR_OUT_SKEWNESS]; Kst::ScalarPtr outputScalarKurtosis = _outputScalars[SCALAR_OUT_KURTOSIS]; //Make sure there is at least 1 element in the input vector if (inputVector->length() < 1) { _errorString = "Error: Input Vector invalid size"; return false; } double* pCopy; double dMean = 0.0; double dMedian = 0.0; double dStandardDeviation = 0.0; double dTotal = 0.0; double dSquaredTotal = 0.0; double dMinimum = 0.0; double dMaximum = 0.0; double dVariance = 0.0; double dAbsoluteDeviation = 0.0; double dSkewness = 0.0; double dKurtosis = 0.0; int iLength = inputVector->length(); for (int i=0; ivalue()[i] < dMinimum) { dMinimum = inputVector->value()[i]; } if (i == 0 || inputVector->value()[i] > dMaximum) { dMaximum = inputVector->value()[i]; } dTotal += inputVector->value()[i]; dSquaredTotal += inputVector->value()[i] * inputVector->value()[i]; } dMean = dTotal / (double)iLength; if (iLength > 1) { dVariance = 1.0 / ( (double)iLength - 1.0 ); dVariance *= dSquaredTotal - ( dTotal * dTotal / (double)iLength ); if (dVariance > 0.0) { dStandardDeviation = sqrt( dVariance ); } else { dVariance = 0.0; dStandardDeviation = 0.0; } } for (int i=0; ivalue()[i] - dMean ); dSkewness += pow( inputVector->value()[i] - dMean, 3.0 ); dKurtosis += pow( inputVector->value()[i] - dMean, 4.0 ); } dAbsoluteDeviation /= (double)iLength; dSkewness /= (double)iLength * pow( dStandardDeviation, 3.0 ); dKurtosis /= (double)iLength * pow( dStandardDeviation, 4.0 ); dKurtosis -= 3.0; /* sort by phase... */ pCopy = (double*)calloc( iLength, sizeof( double ) ); if (pCopy != NULL) { memcpy( pCopy, inputVector->value(), iLength * sizeof( double ) ); quicksort( pCopy, 0, iLength-1 ); dMedian = pCopy[ iLength / 2 ]; free( pCopy ); } outputScalarMean->setValue(dMean); outputScalarMin->setValue(dMinimum); outputScalarMax->setValue(dMaximum); outputScalarVariance->setValue(dVariance); outputScalarSD->setValue(dStandardDeviation); outputScalarMedian->setValue(dMedian); outputScalarAD->setValue(dAbsoluteDeviation); outputScalarSkewness->setValue(dSkewness); outputScalarKurtosis->setValue(dKurtosis); return true; } void StatisticsSource::swap( double* pData, int iOne, int iTwo) { double dTemp; dTemp = pData[iOne]; pData[iOne] = pData[iTwo]; pData[iTwo] = dTemp; } void StatisticsSource::quicksort( double* pData, int iLeft, int iRight) { double dVal = pData[iRight]; int i = iLeft - 1; int j = iRight; if (iRight <= iLeft) { return; } while (1) { while (pData[++i] < dVal) { } while(dVal < pData[--j]) { if (j == iLeft) { break; } } if (i >= j) { break; } swap( pData, i, j ); } swap( pData, i, iRight ); quicksort( pData, iLeft, i-1 ); quicksort( pData, i+1, iRight ); } Kst::VectorPtr StatisticsSource::vector() const { return _inputVectors[VECTOR_IN]; } QStringList StatisticsSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList StatisticsSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList StatisticsSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList StatisticsSource::outputVectorList() const { return QStringList( /*VECTOR_OUT*/ ); } QStringList StatisticsSource::outputScalarList() const { QStringList scalars(SCALAR_OUT_MEAN); scalars += SCALAR_OUT_MINIMUM; scalars += SCALAR_OUT_MAXIMUM; scalars += SCALAR_OUT_VARIANCE; scalars += SCALAR_OUT_STANDARD_DEVIATION; scalars += SCALAR_OUT_MEDIAN; scalars += SCALAR_OUT_ABSOLUTE_DEVIATION; scalars += SCALAR_OUT_SKEWNESS; scalars += SCALAR_OUT_KURTOSIS; return scalars; } QStringList StatisticsSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void StatisticsSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString StatisticsPlugin::pluginName() const { return "Statistics"; } QString StatisticsPlugin::pluginDescription() const { return "Determines statistics for a given inputVector set."; } Kst::DataObject *StatisticsPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetStatisticsPlugin* config = static_cast(configWidget)) { StatisticsSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *StatisticsPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetStatisticsPlugin *widget = new ConfigWidgetStatisticsPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ChopPlugin, StatisticsPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/statistics/statisticsconfig.ui000644 001750 001750 00000003043 11544160207 025352 0ustar00synthsynth000000 000000 StatisticsConfig 0 0 429 57 400 0 0 0 Input Vector false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/statistics/statistics.h000644 001750 001750 00000005235 11544160207 024003 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STATISTICSPLUGIN_H #define STATISTICSPLUGIN_H #include #include #include class StatisticsSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: StatisticsSource(Kst::ObjectStore *store); ~StatisticsSource(); private: void swap( double* pData, int iOne, int iTwo ); void quicksort( double* pData, int iLeft, int iRight ); friend class Kst::ObjectStore; }; class StatisticsPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~StatisticsPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/statistics/statistics.pro000644 001750 001750 00000000246 11544160207 024351 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_statistics) SOURCES += \ statistics.cpp HEADERS += \ statistics.h FORMS += statisticsconfig.ui kst-2.0.3/src/plugins/dataobject/statistics/kstplugin_statistics.desktop000644 001750 001750 00000000407 11544160207 027321 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=statistics X-Kst-Plugin-Author=The University of Toronto Name=Statistics Data Object Plugin Comment=Implements a Statistics Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/differentiation/differentiationconfig.ui000644 001750 001750 00000005746 11544160207 027326 0ustar00synthsynth000000 000000 DifferentiationConfig 0 0 422 76 400 0 0 0 Input Vector false Qt::Horizontal 40 20 0 0 0 0 Scale Factor (Time Step) false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/differentiation/differentiation.h000644 001750 001750 00000004604 11544160207 025742 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIFFERENTIATIONPLUGIN_H #define DIFFERENTIATIONPLUGIN_H #include #include #include class DifferentiationSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr scalarStep() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: DifferentiationSource(Kst::ObjectStore *store); ~DifferentiationSource(); friend class Kst::ObjectStore; }; class DifferentiationPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~DifferentiationPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/differentiation/differentiation.pro000644 001750 001750 00000000272 11544160207 026310 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_differentiation) SOURCES += \ differentiation.cpp HEADERS += \ differentiation.h FORMS += differentiationconfig.ui kst-2.0.3/src/plugins/dataobject/differentiation/kstplugin_differentiation.desktop000644 001750 001750 00000000426 11544160207 031262 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=differentiation X-Kst-Plugin-Author=The University of Toronto Name=Differentiation Data Object Plugin Comment=Implements a Differentiation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/differentiation/differentiation.cpp000644 001750 001750 00000016433 11544160207 026300 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "differentiation.h" #include "objectstore.h" #include "ui_differentiationconfig.h" static const QString& VECTOR_IN = "Vector In"; static const QString& SCALAR_IN = "Scalar In"; static const QString& VECTOR_OUT = "Y'"; class ConfigDifferentiationPlugin : public Kst::DataObjectConfigWidget, public Ui_DifferentiationConfig { public: ConfigDifferentiationPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_DifferentiationConfig() { setupUi(this); } ~ConfigDifferentiationPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarStep->setObjectStore(store); _scalarStep->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarStep, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalar() { return _scalarStep->selectedScalar(); }; void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarStep->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (DifferentiationSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedScalar(source->scalarStep()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Differentiation DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Input Scalar", _scalarStep->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Differentiation DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Input Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarStep = static_cast(object); if (scalarStep) { setSelectedScalar(scalarStep); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; DifferentiationSource::DifferentiationSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } DifferentiationSource::~DifferentiationSource() { } QString DifferentiationSource::_automaticDescriptiveName() const { return QString(vector()->descriptiveName() + " Derivative"); } void DifferentiationSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigDifferentiationPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_IN, config->selectedScalar()); } } void DifferentiationSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool DifferentiationSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; if (inputScalar->value() == 0) { _errorString = "Error: Input Scalar Step must be not be 0."; return false; } /* Memory allocation */ outputVector->resize(inputVector->length(), true); outputVector->value()[0] = (inputVector->value()[1] - inputVector->value()[0]) / inputScalar->value(); int i = 1; for (; i < inputVector->length()-1; i++) { outputVector->value()[i] = (inputVector->value()[i+1] - inputVector->value()[i-1])/(2*inputScalar->value()); } outputVector->value()[i] = (inputVector->value()[i] - inputVector->value()[i-1]) / inputScalar->value(); return true; } Kst::VectorPtr DifferentiationSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr DifferentiationSource::scalarStep() const { return _inputScalars[SCALAR_IN]; } QStringList DifferentiationSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList DifferentiationSource::inputScalarList() const { return QStringList( SCALAR_IN ); } QStringList DifferentiationSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList DifferentiationSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList DifferentiationSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList DifferentiationSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void DifferentiationSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString DifferentiationPlugin::pluginName() const { return "Fixed Step Differentiation"; } QString DifferentiationPlugin::pluginDescription() const { return "Computes the discrete derivative of an input vector"; } Kst::DataObject *DifferentiationPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigDifferentiationPlugin* config = static_cast(configWidget)) { DifferentiationSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_IN, config->selectedScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *DifferentiationPlugin::configWidget(QSettings *settingsObject) const { ConfigDifferentiationPlugin *widget = new ConfigDifferentiationPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, DifferentiationPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/bin/bin.cpp000644 001750 001750 00000016536 11544160207 021300 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* 'boxcar decimation filter': not very useful. */ #include "bin.h" #include "objectstore.h" #include "ui_binconfig.h" static const QString& VECTOR_IN = "Vector In"; static const QString& SCALAR_IN = "Scalar In"; static const QString& VECTOR_OUT = "Bins"; class ConfigWidgetBinPlugin : public Kst::DataObjectConfigWidget, public Ui_BinConfig { public: ConfigWidgetBinPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_BinConfig() { setupUi(this); } ~ConfigWidgetBinPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarBin->setObjectStore(store); _scalarBin->setDefaultValue(10); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarBin, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalar() { return _scalarBin->selectedScalar(); }; void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarBin->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (BinSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedScalar(source->binScalar()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Bin DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Input Bin Scalar", _scalarBin->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Bin DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Input Bin Scalar").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* binScalar = static_cast(object); if (binScalar) { setSelectedScalar(binScalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; BinSource::BinSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } BinSource::~BinSource() { } QString BinSource::_automaticDescriptiveName() const { return QString("Bin Plugin Object"); } void BinSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetBinPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_IN, config->selectedScalar()); } } void BinSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool BinSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; //Make sure there is at least 1 element in the input vector if (inputVector->length() < 1) { _errorString = "Error: Input Vector invalid size"; return false; } //Make sure the bin size is at least 1 if (inputScalar->value() < 1) { _errorString = "Error: No Bins"; return false; } // allocate the lengths outputVector->resize(int(inputVector->length() / inputScalar->value()), false); //now bin the data for (int i = 0; i < outputVector->length(); i++) { outputVector->value()[i] = 0; //add up the elements for this bin for (int j = 0; j < inputScalar->value(); j++) { outputVector->value()[i] += inputVector->value()[int(i*inputScalar->value()+j)]; } //find the mean outputVector->value()[i] /= inputScalar->value(); } return true; } Kst::VectorPtr BinSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr BinSource::binScalar() const { return _inputScalars[SCALAR_IN]; } QStringList BinSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList BinSource::inputScalarList() const { return QStringList( SCALAR_IN ); } QStringList BinSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList BinSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList BinSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList BinSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void BinSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString BinPlugin::pluginName() const { return "Bin"; } QString BinPlugin::pluginDescription() const { return "Bins data into the given size bins. Each bin contains the mean of the elements belonging to the bin."; } Kst::DataObject *BinPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetBinPlugin* config = static_cast(configWidget)) { BinSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_IN, config->selectedScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *BinPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetBinPlugin *widget = new ConfigWidgetBinPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, BinPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/bin/binconfig.ui000644 001750 001750 00000005675 11544160207 022323 0ustar00synthsynth000000 000000 BinConfig 0 0 423 78 400 0 0 0 Input Vector false Qt::Horizontal 40 20 0 0 0 0 Bin Size false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/bin/kstplugin_bin.desktop000644 001750 001750 00000000362 11544160207 024255 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=bin X-Kst-Plugin-Author=The University of Toronto Name=Bin Data Object Plugin Comment=Implements a Bin Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/bin/bin.h000644 001750 001750 00000005026 11544160207 020735 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BINPLUGIN_H #define BINPLUGIN_H #include #include #include class BinSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr binScalar() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: BinSource(Kst::ObjectStore *store); ~BinSource(); friend class Kst::ObjectStore; }; class BinPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~BinPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/bin/bin.pro000644 001750 001750 00000000212 11544160207 021276 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_bin) SOURCES += \ bin.cpp HEADERS += \ bin.h FORMS += binconfig.ui kst-2.0.3/src/plugins/dataobject/genericfilter/genericfilter.cpp000644 001750 001750 00000026005 11544160207 025414 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "genericfilter.h" #include "objectstore.h" #include "ui_genericfilterconfig.h" #include "polynom.h" #include "filter.h" static const QString& VECTOR_IN = "Vector In"; static const QString& SCALAR_IN = "Scalar In"; static const QString& STRING_IN_NUMERATOR = "String In Numerator"; static const QString& STRING_IN_DENOMINATOR = "String In Denominator"; static const QString& VECTOR_OUT = "Filtered"; class ConfigGenericFilterPlugin : public Kst::DataObjectConfigWidget, public Ui_GenericFilterConfig { public: ConfigGenericFilterPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_GenericFilterConfig() { setupUi(this); } ~ConfigGenericFilterPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarInterval->setObjectStore(store); _stringNumerator->setObjectStore(store); _stringDenominator->setObjectStore(store); _scalarInterval->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarInterval, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_stringNumerator, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_stringDenominator, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalar() { return _scalarInterval->selectedScalar(); }; void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarInterval->setSelectedScalar(scalar); }; Kst::StringPtr selectedStringNumerator() { return _stringNumerator->selectedString(); }; void setSelectedStringNumerator(Kst::StringPtr string) { return _stringNumerator->setSelectedString(string); }; Kst::StringPtr selectedStringDenominator() { return _stringDenominator->selectedString(); }; void setSelectedStringDenominator(Kst::StringPtr string) { return _stringDenominator->setSelectedString(string); }; virtual void setupFromObject(Kst::Object* dataObject) { if (GenericFilterSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedScalar(source->scalarInterval()); setSelectedStringNumerator(source->stringNumerator()); setSelectedStringDenominator(source->stringDenominator()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Generic Filter DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Input Scalar Interval", _scalarInterval->selectedScalar()->Name()); if (_stringNumerator->selectedString()) { _cfg->setValue("Input String Numerator", _stringNumerator->selectedString()->Name()); } if (_stringDenominator->selectedString()) { _cfg->setValue("Input String Denominator", _stringDenominator->selectedString()->Name()); } _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Generic Filter DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Input Scalar Interval").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* binScalar = static_cast(object); if (binScalar) { setSelectedScalar(binScalar); } QString stringName = _cfg->value("Input String Numerator").toString(); object = _store->retrieveObject(stringName); Kst::String* stringNum = static_cast(object); if (stringNum) { setSelectedStringNumerator(stringNum); } stringName = _cfg->value("Input String Denominator").toString(); object = _store->retrieveObject(stringName); Kst::String* stringDenom = static_cast(object); if (stringDenom) { setSelectedStringDenominator(stringDenom); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; GenericFilterSource::GenericFilterSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } GenericFilterSource::~GenericFilterSource() { } QString GenericFilterSource::_automaticDescriptiveName() const { return QString("Generic Filter Plugin Object"); } void GenericFilterSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigGenericFilterPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_IN, config->selectedScalar()); setInputString(STRING_IN_NUMERATOR, config->selectedStringNumerator()); setInputString(STRING_IN_DENOMINATOR, config->selectedStringDenominator()); } } void GenericFilterSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool GenericFilterSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN]; Kst::StringPtr inputStringNumerator = _inputStrings[STRING_IN_NUMERATOR]; Kst::StringPtr inputStringDenominator = _inputStrings[STRING_IN_DENOMINATOR]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; //Validate the Numerator. if (!inputStringNumerator || inputStringNumerator->value().isEmpty()) { _errorString = "Error: Input String Numerator is Empty"; return false; } //Validate the Denominator. if (!inputStringDenominator || inputStringDenominator->value().isEmpty()) { _errorString = "Error: Input String Denominator is Empty"; return false; } int length = inputVector->length(); // Extract polynom coefficients and instantiate polynoms QStringList numCoeffs = inputStringNumerator->value().split(QRegExp("\\s*(,|;|:)\\s*")); QStringList denCoeffs = inputStringDenominator->value().split(QRegExp("\\s*(,|;|:)\\s*")); int numDegree = numCoeffs.count() - 1, denDegree = denCoeffs.count() - 1; polynom Num(numDegree), Den(denDegree); double tmpDouble = 0.0; bool ok = false; for (int i=0; i<=numDegree; i++) { tmpDouble = numCoeffs[i].toDouble(&ok); if (ok) Num[i]= tmpDouble; else Num[i] = 0.0; } for (int i=0; i<=denDegree; i++) { tmpDouble = denCoeffs[i].toDouble(&ok); if (ok) Den[i] = tmpDouble; else Den[i] = 0.0; } // Time step double DeltaT = inputScalar->value(); // Allocate storage for output vectors outputVector->resize(length, true); // Create filter filter theFilter(Num,Den,DeltaT); double in = 0.0; theFilter.ConnectTo(in); theFilter.Reset(); for (int i=0; ivalue()[i]; theFilter.NextTimeStep(); outputVector->value()[i] = theFilter.out; } return true; } Kst::VectorPtr GenericFilterSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr GenericFilterSource::scalarInterval() const { return _inputScalars[SCALAR_IN]; } Kst::StringPtr GenericFilterSource::stringNumerator() const { return _inputStrings[STRING_IN_NUMERATOR]; } Kst::StringPtr GenericFilterSource::stringDenominator() const { return _inputStrings[STRING_IN_DENOMINATOR]; } QStringList GenericFilterSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList GenericFilterSource::inputScalarList() const { return QStringList( SCALAR_IN ); } QStringList GenericFilterSource::inputStringList() const { QStringList strings(STRING_IN_NUMERATOR); strings += STRING_IN_DENOMINATOR; return strings; } QStringList GenericFilterSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList GenericFilterSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList GenericFilterSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void GenericFilterSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString GenericFilterPlugin::pluginName() const { return "Generic Filter"; } QString GenericFilterPlugin::pluginDescription() const { return "Generates a discrete filter from a continuous-time definition."; } Kst::DataObject *GenericFilterPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigGenericFilterPlugin* config = static_cast(configWidget)) { GenericFilterSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_IN, config->selectedScalar()); object->setInputString(STRING_IN_NUMERATOR, config->selectedStringNumerator()); object->setInputString(STRING_IN_DENOMINATOR, config->selectedStringDenominator()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *GenericFilterPlugin::configWidget(QSettings *settingsObject) const { ConfigGenericFilterPlugin *widget = new ConfigGenericFilterPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, GenericFilterPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/genericfilter/filter.h000644 001750 001750 00000006651 11544160207 023531 0ustar00synthsynth000000 000000 /****************************************************************************** * filter.h : Digital Filter. Specified by its "s" transfer function. * * Synthesis of "z" transfert function is done by bilinear * * transformation : 2 z-1 * * p -> --- ----- * * T z+1 * * Copyright 2005, Jean-Paul Petillon * * Released under the terms of the GPL. * ******************************************************************************/ #ifndef FILTER_H #define FILTER_H #include "polynom.h" template class filter { public: S out; // output filter( // constructor // "s" transfert function polynom& Ns, // numerator polynom& Ds, // denominator double dT // sampling period (s) ); void Reset(); // reset void ConnectTo( // connector S& in // input address ); void NextTimeStep(); // update ~filter(); // destructor private: // pointer on input S* in; // order int n; // "z" transfert function polynom Nz; // numerator polynom Dz; // denominator // state vector S* x; }; template filter::filter(polynom& Ns, polynom& Ds, double dT) :Nz(0), Dz(0) { // the greatest degree between N & D n=Ns.GetDegree()>Ds.GetDegree() ? Ns.GetDegree() : Ds.GetDegree(); // allocate memory for state vector x = new S[n]; // reset it Reset(); // as well as the output out=0.0; // computes "z" transfer function polynom potzm1odt(0); potzm1odt[0]=1.0; // [2(z-1)/dT]^i polynom dzm1odt(1); dzm1odt[1]=2.0/dT; dzm1odt[0]=-2.0/dT; // 2(z-1)/dT for (int i=0; i<=n; i++) { // (z+1)^(n-i) = 1 polynom pozp1(0); pozp1[0]=1.0; // z+1 polynom zp1(1); zp1[1]=1.0; zp1[0]=1.0; // (z+1)^(n-i) for (int j=i+1; j<=n; j++) pozp1 = pozp1 * zp1; polynom dNz(0); dNz[0]=Ns[i]; dNz = dNz * pozp1 * potzm1odt; Nz = Nz + dNz; polynom dDz(0); dDz[0]=Ds[i]; dDz = dDz * pozp1 * potzm1odt; Dz = Dz + dDz; potzm1odt = potzm1odt * dzm1odt; } } //------------------------------------------------------------------------------ template void filter::Reset() // reset state vector { for (int i=0; i void filter::ConnectTo(S& in) { // memorizes input address this->in = ∈ } //------------------------------------------------------------------------------ template void filter::NextTimeStep() { // Compute output out = (x[n-1] + *in * Nz[n])/ Dz[n]; // update state vector x[0] .. x[n-1] (goes from output to input) for (int i=n-1; i>0; i--) { x[i] = x[i-1] + Nz[i]*(*in) - Dz[i]*out; } x[0] = Nz[0]*(*in) - Dz[0]*out; } //------------------------------------------------------------------------------ template filter::~filter() { // deallocate memory used by state vector delete[] x; } //------------------------------------------------------------------------------ #endif // #ifndef FILTER_H kst-2.0.3/src/plugins/dataobject/genericfilter/genericfilterconfig.ui000644 001750 001750 00000012124 11544160207 026432 0ustar00synthsynth000000 000000 GenericFilterConfig 0 0 426 170 400 0 0 0 Input Vector false Qt::Horizontal 40 20 0 0 0 0 Sampling interval (s) false Qt::Horizontal 40 20 0 0 Numerator (increasing order) false Qt::Horizontal 40 20 0 0 Denominator (increasing order) false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    Kst::StringSelector QWidget
    stringselector.h
    kst-2.0.3/src/plugins/dataobject/genericfilter/genericfilter.h000644 001750 001750 00000005041 11544160207 025056 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GENERICFILTERPLUGIN_H #define GENERICFILTERPLUGIN_H #include #include #include class GenericFilterSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr scalarInterval() const; Kst::StringPtr stringNumerator() const; Kst::StringPtr stringDenominator() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: GenericFilterSource(Kst::ObjectStore *store); ~GenericFilterSource(); friend class Kst::ObjectStore; }; class GenericFilterPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~GenericFilterPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/genericfilter/polynom.h000644 001750 001750 00000013166 11544160207 023740 0ustar00synthsynth000000 000000 /****************************************************************************** * polynom.h : polynom class. Implements the following operations: * * - the sum, the difference and the product between polynoms ; * * - the multiplication and the division by a scalar ; * * - the derivative and the integrate. * * * * Copyright 2005, Jean-Paul Petillon * * Released under the terms of the GPL V2, or (at your option) any later * * version * * * ******************************************************************************/ #ifndef POLYNOM_H #define POLYNOM_H template class polynom { public: polynom(int n); // constructor polynom(const polynom& P); // copy constructor ~polynom(); // destructor S& operator[] (int i); // ith coefficient acces (read/write) S operator() (S x); // value at x polynom& operator=(const polynom& P); // set a polynom equal to another one polynom operator+(const polynom& P); // sum of 2 polynoms polynom operator-(const polynom& P); // difference between 2 polynoms polynom operator*(const polynom& P); // product of 2 polynoms polynom operator*(const S& x); // product by a scalar polynom operator/(const S& x); // division by a scalar polynom Derivative(); // derivative polynom Integrate(); // integrate int GetDegree(); void SetDegree(int n); private: S* C; // coefficients S NulC; // null coefficient (for i>n) int n; // degree of polynom (table size is n+1) }; // constructor template polynom::polynom(int n) { C = new S[n+1]; for (int i=0; i<=n; i++) C[i]=0.0; NulC = 0.0; this->n = n; }; //------------------------------------------------------------------------------ // copy constructor template polynom::polynom(const polynom& P) { n = P.n; C = new S[n+1]; for (int i=0; i<=n; i++) C[i]=P.C[i]; } //------------------------------------------------------------------------------ // destructor template polynom::~polynom() { delete[] C; }; //------------------------------------------------------------------------------ // coefficient acces (read or write) template S& polynom::operator[] (int i) { return i<=n ? C[i] : NulC; }; //------------------------------------------------------------------------------ // value at x template S polynom::operator() (S x) { S r=0.0; S xpi=1.0; // x at the power i for (int i=0; i<=n; i++) { r+=C[i]*xpi; xpi*=x; } return r; }; //------------------------------------------------------------------------------ // set a polynom equal to another one template polynom& polynom::operator=(const polynom& P) { if (n!=P.n) { // reallocate memory if different size delete[] C; n = P.n; C = new S[n+1]; this->n = n; } for (int i=0; i<=n; i++) C[i]=P.C[i]; return *this; }; //------------------------------------------------------------------------------ // polynom sum template polynom polynom::operator+(const polynom& P) { polynom r(n>P.n?n:P.n); for (int i=0; i<= n; i++) r.C[i]+= C[i]; for (int i=0; i<=P.n; i++) r.C[i]+=P.C[i]; return r; }; //------------------------------------------------------------------------------ // polynom difference template polynom polynom::operator-(const polynom& P) { polynom r(n>P.n?n:P.n); for (int i=0; i<= n; i++) r.C[i]+= C[i]; for (int i=0; i<=P.n; i++) r.C[i]-=P.C[i]; return r; }; //------------------------------------------------------------------------------ // polynom product template polynom polynom::operator*(const polynom& P) { polynom r(n+P.n); for (int i=0; i<=r.n; i++) { r.C[i]=0; for (int j=(0>i-n?0:i-n); j<=(i polynom polynom::operator*(const S& x) { polynom r(n); for (int i=0; i<=n; i++) r.C[i]=C[i]*x; return r; }; //------------------------------------------------------------------------------ // scalar division template polynom polynom::operator/(const S& x) { polynom r(n); for (int i=0; i<=n; i++) r.C[i]=C[i]/x; return r; }; //------------------------------------------------------------------------------ // derivative template polynom polynom::Derivative() { polynom r(n-1); for (int i=0; i<=r.n; i++) r.C[i]=(i+1)*C[i+1]; return r; }; //------------------------------------------------------------------------------ // integrate template polynom polynom::Integrate() { polynom r(n+1); r.C[0]=0; for (int i=1; i<=r.n; i++) r.C[i]=C[i-1]/i; return r; }; //------------------------------------------------------------------------------ template int polynom::GetDegree() { return n; } //------------------------------------------------------------------------------ template void polynom::SetDegree(int n) { if (this->n != n) { delete[] C; C = new double[n+1]; this->n = n; for (int i=0; i<=n; i++) C[i]=0.0; } } #endif // ifndef POLYNOM_H kst-2.0.3/src/plugins/dataobject/genericfilter/kstplugin_genericfilter.desktop000644 001750 001750 00000000422 11544160207 030376 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=genericfilter X-Kst-Plugin-Author=The University of Toronto Name=Generic Filter Data Object Plugin Comment=Implements a Generic Filter Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/genericfilter/genericfilter.pro000644 001750 001750 00000000321 11544160207 025423 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_genericfilter) SOURCES += \ genericfilter.cpp HEADERS += \ genericfilter.h \ polynom.h \ filter.h FORMS += genericfilterconfig.ui kst-2.0.3/src/plugins/dataobject/periodogram/periodogram.h000644 001750 001750 00000007441 11544160207 024240 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PERIODOGRAMPLUGIN_H #define PERIODOGRAMPLUGIN_H #include #include #include class PeriodogramSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorTime() const; Kst::VectorPtr vectorData() const; Kst::ScalarPtr scalarOversampling() const; Kst::ScalarPtr scalarANFF() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: PeriodogramSource(Kst::ObjectStore *store); ~PeriodogramSource(); private: int max(int a, int b); int min(int a, int b); void spread(double y, double yy[], unsigned long n, double x, int m); void four1(double data[], unsigned long nn, int isign); void realft(double data[], unsigned long n, int isign); void avevar(double const data[], unsigned long n, double* ave, double* var); void FastLombPeriodogram( double const x[], double const y[], unsigned long n, double ofac, double hifac, double wk1[], double wk2[], unsigned long ndim, unsigned long* nout, unsigned long* jmax, double* prob, double* pvar, int iIsWindowFunction); void SlowLombPeriodogram( double const x[], double const y[], unsigned long n, double ofac, double hifac, double px[], double py[], unsigned long ndim, unsigned long* nout, unsigned long* jmax, double* prob, double* pvar, int iIsWindowFunction); friend class Kst::ObjectStore; }; class PeriodogramPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~PeriodogramPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/periodogram/periodogram.cpp000644 001750 001750 00000057116 11544160207 024577 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* a type of spectrum. I'm not sure how this relates to the built in power spectrums. It could be removed from the default build (?) */ #include "periodogram.h" #include "objectstore.h" #include "ui_periodogramconfig.h" #define ONE_PI 3.1415926535897930475926 #define TWO_PI 6.2831853071795858696103 #define MACC 4.0 static const QString& VECTOR_IN_TIME = "Vector In Time"; static const QString& VECTOR_IN_DATA = "Vector In Data"; static const QString& SCALAR_IN_OVERSAMPLING = "Oversampling factor"; static const QString& SCALAR_IN_ANFF = "Average Nyquist outputVectorFrequency factor"; static const QString& VECTOR_OUT_FREQUENCY = "Frequency"; static const QString& VECTOR_OUT_PERIODOGRAM = "Periodogram"; class ConfigPeriodogramPlugin : public Kst::DataObjectConfigWidget, public Ui_PeriodogramConfig { public: ConfigPeriodogramPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_PeriodogramConfig() { setupUi(this); } ~ConfigPeriodogramPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorTime->setObjectStore(store); _vectorData->setObjectStore(store); _scalarOversampling->setObjectStore(store); _scalarANFF->setObjectStore(store); _scalarOversampling->setDefaultValue(0); _scalarANFF->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorTime, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorData, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarOversampling, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarANFF, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorTime() { return _vectorTime->selectedVector(); }; void setSelectedVectorTime(Kst::VectorPtr vector) { return _vectorTime->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorData() { return _vectorData->selectedVector(); }; void setSelectedVectorData(Kst::VectorPtr vector) { return _vectorData->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarOversampling() { return _scalarOversampling->selectedScalar(); }; void setSelectedScalarOversampling(Kst::ScalarPtr scalar) { return _scalarOversampling->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarANFF() { return _scalarANFF->selectedScalar(); }; void setSelectedScalarANFF(Kst::ScalarPtr scalar) { return _scalarANFF->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (PeriodogramSource* source = static_cast(dataObject)) { setSelectedVectorTime(source->vectorTime()); setSelectedVectorData(source->vectorData()); setSelectedScalarOversampling(source->scalarOversampling()); setSelectedScalarANFF(source->scalarANFF()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Periodogram DataObject Plugin"); _cfg->setValue("Input Vector Time", _vectorTime->selectedVector()->Name()); _cfg->setValue("Input Vector Data", _vectorData->selectedVector()->Name()); _cfg->setValue("Input Scalar Oversampling factor", _scalarOversampling->selectedScalar()->Name()); _cfg->setValue("Input Scalar Average Nyquist outputVectorFrequency factor", _scalarANFF->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Periodogram DataObject Plugin"); QString vectorName = _cfg->value("Input Vector Time").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorTime = static_cast(object); if (vectorTime) { setSelectedVectorTime(vectorTime); } vectorName = _cfg->value("Input Vector Data").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorData = static_cast(object); if (vectorData) { setSelectedVectorData(vectorData); } QString scalarName = _cfg->value("Input Scalar Oversampling factor").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarOversampling = static_cast(object); if (scalarOversampling) { setSelectedScalarOversampling(scalarOversampling); } scalarName = _cfg->value("Input Scalar Average Nyquist outputVectorFrequency factor").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarANFF = static_cast(object); if (scalarANFF) { setSelectedScalarANFF(scalarANFF); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; PeriodogramSource::PeriodogramSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } PeriodogramSource::~PeriodogramSource() { } QString PeriodogramSource::_automaticDescriptiveName() const { return QString("Periodogram Plugin Object"); } void PeriodogramSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigPeriodogramPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_TIME, config->selectedVectorTime()); setInputVector(VECTOR_IN_DATA, config->selectedVectorData()); setInputScalar(SCALAR_IN_OVERSAMPLING, config->selectedScalarOversampling()); setInputScalar(SCALAR_IN_ANFF, config->selectedScalarANFF()); } } void PeriodogramSource::setupOutputs() { setOutputVector(VECTOR_OUT_FREQUENCY, ""); setOutputVector(VECTOR_OUT_PERIODOGRAM, ""); } bool PeriodogramSource::algorithm() { Kst::VectorPtr inputVectorTime = _inputVectors[VECTOR_IN_TIME]; Kst::VectorPtr inputVectorData = _inputVectors[VECTOR_IN_DATA]; Kst::ScalarPtr inputScalarOversampling = _inputScalars[SCALAR_IN_OVERSAMPLING]; Kst::ScalarPtr inputScalarANFF = _inputScalars[SCALAR_IN_ANFF]; Kst::VectorPtr outputVectorFrequency = _outputVectors[VECTOR_OUT_FREQUENCY]; Kst::VectorPtr outputVectorPeriodogram = _outputVectors[VECTOR_OUT_PERIODOGRAM]; unsigned long lSizeWork; unsigned long lSizeOut = 0; unsigned long lSizeIn; unsigned long lFreqt; unsigned long lFreq; unsigned long lMax; double dProb; double dVar; double* pResult[2]; bool bReturn = false; //Make sure the input sizes match if (inputVectorTime->length() != inputVectorData->length()) { _errorString = "Error: Input Vector lengths do not match"; return false; } lSizeIn = inputVectorTime->length(); if (lSizeIn > 1) { lFreqt = (unsigned long)( MACC * inputScalarOversampling->value() * inputScalarANFF->value() * lSizeIn ); lFreq = 64; while (lFreq < lFreqt) { lFreq *= 2; } lSizeWork = lFreq * 2; outputVectorFrequency->resize(lSizeWork, true); pResult[0] = outputVectorFrequency->value(); outputVectorPeriodogram->resize(lSizeWork, true); pResult[1] = outputVectorPeriodogram->value(); if (pResult[0] != NULL && pResult[1] != NULL) { for (int i = 0; i < outputVectorFrequency->length(); ++i) { outputVectorFrequency->value()[i] = pResult[0][i]; } for (int i = 0; i < outputVectorPeriodogram->length(); ++i) { outputVectorPeriodogram->value()[i] = pResult[1][i]; } if (lSizeIn > 100) { FastLombPeriodogram( (double*)&(inputVectorTime->value()[-1]), (double*)&(inputVectorData->value()[-1]), inputVectorTime->length(), inputScalarOversampling->value(), inputScalarANFF->value(), (double*)&(outputVectorFrequency->value()[-1]), (double*)&(outputVectorPeriodogram->value()[-1]), lSizeWork, &lSizeOut, &lMax, &dProb, &dVar, 0 ); } else { SlowLombPeriodogram( (double*)&(inputVectorTime->value()[-1]), (double*)&(inputVectorData->value()[-1]), inputVectorTime->length(), inputScalarOversampling->value(), inputScalarANFF->value(), (double*)&(outputVectorFrequency->value()[-1]), (double*)&(outputVectorPeriodogram->value()[-1]), lSizeWork, &lSizeOut, &lMax, &dProb, &dVar, 0 ); } if (lSizeOut > 0 && lSizeOut <= lSizeWork) { outputVectorFrequency->resize(lSizeOut, false); outputVectorPeriodogram->resize(lSizeOut, false); bReturn = true; } } } return bReturn; } Kst::VectorPtr PeriodogramSource::vectorTime() const { return _inputVectors[VECTOR_IN_TIME]; } Kst::VectorPtr PeriodogramSource::vectorData() const { return _inputVectors[VECTOR_IN_DATA]; } Kst::ScalarPtr PeriodogramSource::scalarOversampling() const { return _inputScalars[SCALAR_IN_OVERSAMPLING]; } Kst::ScalarPtr PeriodogramSource::scalarANFF() const { return _inputScalars[SCALAR_IN_ANFF]; } QStringList PeriodogramSource::inputVectorList() const { QStringList vectors(VECTOR_IN_TIME); vectors += VECTOR_IN_DATA; return vectors; } QStringList PeriodogramSource::inputScalarList() const { QStringList scalars(SCALAR_IN_OVERSAMPLING); scalars += SCALAR_IN_ANFF; return scalars; } QStringList PeriodogramSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList PeriodogramSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_FREQUENCY); vectors += VECTOR_OUT_PERIODOGRAM; return vectors; } QStringList PeriodogramSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList PeriodogramSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void PeriodogramSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } int PeriodogramSource::max(int a, int b) { if (a > b) { return a; } return b; } int PeriodogramSource::min(int a, int b) { if (a < b) { return a; } return b; } void PeriodogramSource::spread(double y, double yy[], unsigned long n, double x, int m) { int ihi; int ilo; int ix; int j; int nden; double fac; static int nfac[] = { 0, 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 39916800, 479001600 }; ix = (int)x; if (x == (double)ix) { yy[ix] += y; } else { ilo = min(max((int)(x - 0.5*m + 1.0), 1), (int)(n - m + 1)); ihi = ilo + m - 1; nden = nfac[m]; fac = x - ilo; for (j = ilo + 1;j <= ihi;j++) { fac *= x - (double)j; } yy[ihi] += y*fac/(double)(nden*(x - ihi)); for (j = ihi-1;j >= ilo;j--) { nden=(nden/(j+1-ilo))*(j-ihi); yy[j] += y*fac/(double)(nden*(x - j)); } } } void PeriodogramSource::four1(double data[], unsigned long nn, int isign) { unsigned long n; unsigned long mmax; unsigned long m; unsigned long j; unsigned long istep; unsigned long i; double dtemp; double wtemp; double wr; double wpr; double wpi; double wi; double theta; double tempr; double tempi; n = nn << 1; j = 1; for (i = 1;i < n;i += 2) { if (j > i) { dtemp = data[i]; data[i] = data[j]; data[j] = dtemp; dtemp = data[i+1]; data[i+1] = data[j+1]; data[j+1] = dtemp; } m = n >> 1; while (m >= 2 && j > m) { j -= m; m >>= 1; } j += m; } mmax = 2; while (n > mmax) { istep = mmax * 2; theta = isign*(TWO_PI/mmax); wtemp = sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi = sin(theta); wr = 1.0; wi = 0.0; for (m = 1;m < mmax;m += 2) { for (i = m;i <= n;i += istep) { j = i + mmax; tempr = wr*data[j] - wi*data[j+1]; tempi = wr*data[j+1] + wi*data[j]; data[j] = data[i] - tempr; data[j+1] = data[i+1] - tempi; data[i] += tempr; data[i+1] += tempi; } wr = (wtemp = wr)*wpr - wi*wpi + wr; wi = wi*wpr + wtemp*wpi + wi; } mmax = istep; } } void PeriodogramSource::realft(double data[], unsigned long n, int isign) { unsigned long i; unsigned long i1; unsigned long i2; unsigned long i3; unsigned long i4; unsigned long np3; double c1 = 0.5; double c2; double h1r; double h1i; double h2r; double h2i; double wr; double wi; double wpr; double wpi; double wtemp; double theta; theta = ONE_PI / (double)(n>>1); if (isign == 1) { c2 = -0.5; four1(data, n>>1, 1); } else { c2 = 0.5; theta = -theta; } wtemp = sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi = sin(theta); wr = 1.0 + wpr; wi = wpi; np3 = n+3; for (i = 2;i <= (n>>2);i++) { i1 = (2*i) - 1; i2 = i1 + 1; i3 = np3 - i2; i4 = i3 + 1; h1r = c1*(data[i1] + data[i3]); h1i = c1*(data[i2] - data[i4]); h2r = -c2*(data[i2] + data[i4]); h2i = c2*(data[i1] - data[i3]); data[i1] = h1r + wr*h2r - wi*h2i; data[i2] = h1i + wr*h2i + wi*h2r; data[i3] = h1r - wr*h2r + wi*h2i; data[i4] = -h1i + wr*h2i + wi*h2r; wtemp = wr; wr = wr*wpr - wi*wpi + wr; wi = wi*wpr + wtemp*wpi + wi; } if (isign == 1) { h1r = data[1]; data[1] = h1r + data[2]; data[2] = h1r - data[2]; } else { h1r = data[1]; data[1] = c1*(h1r + data[2]); data[2] = c1*(h1r - data[2]); four1(data, n>>1, -1); } } void PeriodogramSource::avevar( double const data[], unsigned long n, double* ave, double* var) { unsigned long j; double s; double ep; *ave = 0.0; *var = 0.0; ep = 0.0; if (n > 0) { for (*ave = 0.0, j = 1;j <= n;j++) { *ave += data[j]; } *ave /= n; if (n > 1) { for (j = 1;j <= n;j++) { s = data[j] - (*ave); ep += s; *var += s*s; } *var = (*var - ep * ep / n) / (n - 1); } } } void PeriodogramSource::FastLombPeriodogram( double const x[], double const y[], unsigned long n, double ofac, double hifac, double wk1[], double wk2[], unsigned long ndim, unsigned long* nout, unsigned long* jmax, double* prob, double* pvar, int iIsWindowFunction) { unsigned long j; unsigned long k; double ave; double ck; double ckk; double cterm; double cwt; double den; double df; double effm; double expy; double fac; double fndim; double hc2wt; double hs2wt; double hypo; double pmax; double sterm; double swt; double xdif; double xmax; double xmin; if (n > 0) { *nout = (unsigned long)(0.5 * ofac * hifac * n); if (iIsWindowFunction) { ave = 0.0; *pvar = 0.0; } else { avevar(y, n, &ave, pvar); } xmax = x[1]; xmin = x[1]; for (j = 2;j <= n;j++) { if (x[j] < xmin) { xmin = x[j]; } if (x[j] > xmax) { xmax = x[j]; } } xdif = xmax - xmin; for (j = 1;j <= ndim;j++) { wk1[j] = 0.0; wk2[j] = 0.0; } fac = ndim / (xdif * ofac); fndim = ndim; for (j = 1;j <= n;j++) { ck = (x[j] - xmin) * fac; ck = fmod(ck, fndim); ckk = 2.0*(ck++); ckk = fmod(ckk, fndim); ++ckk; spread(y[j] - ave, wk1, ndim, ck, (int)MACC); spread(1.0, wk2, ndim, ckk, (int)MACC); } realft(wk1, ndim, 1); realft(wk2, ndim, 1); df = 1.0 / (xdif * ofac); pmax = -1.0; for (k = 3, j = 1;j <= (*nout);j++, k += 2) { hypo = sqrt(wk2[k]*wk2[k] + wk2[k+1]*wk2[k+1]); hc2wt = 0.5 * wk2[k ] / hypo; hs2wt = 0.5 * wk2[k+1] / hypo; cwt = sqrt(0.5 + hc2wt); swt = fabs(sqrt(0.5 - hc2wt)); if (hs2wt < 0.0) { swt *= -1.0; } den = 0.5*n + hc2wt*wk2[k] + hs2wt*wk2[k+1]; cterm = pow(cwt*wk1[k+0] + swt*wk1[k+1], 2.0) / den; if ((double)n - den == 0.0) { sterm = 0.0; } else { sterm = pow(cwt*wk1[k+1] - swt*wk1[k+0], 2.0) / ((double)n - den); } wk1[j] = (double)j * df; wk2[j] = (cterm + sterm); if (*pvar > 0.0) { wk2[j] /= (2.0 * *pvar); } if (wk2[j] > pmax) { pmax = wk2[ (*jmax = j) ]; } } expy = exp(-pmax); effm = 2.0 * (*nout) / ofac; *prob = effm * expy; if (*prob > 0.01) { *prob = 1.0 - pow(1.0 - expy, effm); } } else { *nout = 0; } } void PeriodogramSource::SlowLombPeriodogram( double const x[], double const y[], unsigned long n, double ofac, double hifac, double px[], double py[], unsigned long /*ndim*/, unsigned long* nout, unsigned long* jmax, double* prob, double* pvar, int iIsWindowFunction) { unsigned long i; unsigned long j; double* wi = NULL; double* wpi = NULL; double* wpr = NULL; double* wr = NULL; double arg; double wtemp; double ave; double c; double cc; double cwtau; double effm; double expy; double pnow; double pymax; double s; double ss; double sumc; double sumcy; double sums; double sumsh; double sumsy; double swtau; double wtau; double xave; double xdif; double xmax; double xmin; double yy; if (n > 0) { wi = (double*)calloc(n+1, sizeof(double)); wpi = (double*)calloc(n+1, sizeof(double)); wpr = (double*)calloc(n+1, sizeof(double)); wr = (double*)calloc(n+1, sizeof(double)); if (wi != NULL && wpi != NULL && wpr != NULL && wr != NULL) { *nout = (unsigned long)(0.5*ofac*hifac*n); if (iIsWindowFunction) { ave = 0.0; *pvar = 0.0; } else { avevar(y, n, &ave, pvar); } xmax = x[1]; xmin = x[1]; for (j=1;j<=n;j++) { if (x[j] > xmax) { xmax = x[j]; } if (x[j] < xmin) { xmin = x[j]; } } xdif = xmax-xmin; xave = 0.5*(xmax+xmin); pymax = 0.0; pnow = 1.0/(xdif*ofac); for (j=1;j<=n;j++) { arg = TWO_PI*((x[j]-xave)*pnow); wpr[j] = -2.0*(sin(0.5*arg)*sin(0.5*arg)); wpi[j] = sin(arg); wr[j] = cos(arg); wi[j] = wpi[j]; } for (i=1;i<=(*nout);i++) { sumsh = 0.0; sumc = 0.0; px[i] = pnow; for (j=1;j<=n;j++) { c = wr[j]; s = wi[j]; sumsh += s*c; sumc += (c-s)*(c+s); } wtau = 0.5 * atan2(2.0 * sumsh, sumc); swtau = sin(wtau); cwtau = cos(wtau); sums = 0.0; sumc = 0.0; sumsy = 0.0; sumcy = 0.0; for (j=1;j<=n;j++) { s = wi[j]; c = wr[j]; ss = s*cwtau-c*swtau; cc = c*cwtau+s*swtau; sums += ss*ss; sumc += cc*cc; yy = y[j]-ave; sumsy += yy*ss; sumcy += yy*cc; wtemp = wr[j]; wr[j] = (wr[j]*wpr[j]-wi[j]*wpi[j])+wr[j]; wi[j] = (wi[j]*wpr[j]+wtemp*wpi[j])+wi[j]; } py[i] = (sumcy * sumcy / sumc + sumsy * sumsy / sums); if (*pvar > 0.0) { py[i] /= (2.0 * (*pvar)); } if (py[i] >= pymax) { *jmax = i; pymax = py[i]; } pnow += 1.0/(xdif*ofac); } expy = exp(-pymax); effm = 2.0*(*nout)/ofac; *prob = effm*expy; if (*prob > 0.01) { *prob = 1.0 - pow(1.0 - expy, effm); } } if (wi != NULL) { free(wi); } if (wpi != NULL) { free(wpi); } if (wpr != NULL) { free(wpr); } if (wr != NULL) { free(wr); } } else { *nout = 0; } } QString PeriodogramPlugin::pluginName() const { return "Periodogram"; } QString PeriodogramPlugin::pluginDescription() const { return "Takes the outputVectorPeriodogram of a given inputVectorData set. The inputVectorData is not assumed to be sampled at equal inputVectorTime intervals."; } Kst::DataObject *PeriodogramPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigPeriodogramPlugin* config = static_cast(configWidget)) { PeriodogramSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_TIME, config->selectedVectorTime()); object->setInputVector(VECTOR_IN_DATA, config->selectedVectorData()); object->setInputScalar(SCALAR_IN_OVERSAMPLING, config->selectedScalarOversampling()); object->setInputScalar(SCALAR_IN_ANFF, config->selectedScalarANFF()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *PeriodogramPlugin::configWidget(QSettings *settingsObject) const { ConfigPeriodogramPlugin *widget = new ConfigPeriodogramPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, PeriodogramPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/periodogram/periodogram.pro000644 001750 001750 00000000252 11544160207 024602 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_periodogram) SOURCES += \ periodogram.cpp HEADERS += \ periodogram.h FORMS += periodogramconfig.ui kst-2.0.3/src/plugins/dataobject/periodogram/kstplugin_periodogram.desktop000644 001750 001750 00000000412 11544160207 027551 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=periodogram X-Kst-Plugin-Author=The University of Toronto Name=Periodogram Data Object Plugin Comment=Implements a Periodogram Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/periodogram/periodogramconfig.ui000644 001750 001750 00000012241 11544160207 025606 0ustar00synthsynth000000 000000 PeriodogramConfig 0 0 424 183 400 0 0 0 Input Vector Time false Qt::Horizontal 40 20 0 0 0 0 Input Vector Data false Qt::Horizontal 40 20 0 0 0 0 Oversampling factor false Qt::Horizontal 40 20 0 0 Average Nyquist frequency factor false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/phase/phase.h000644 001750 001750 00000005372 11544160207 021621 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PHASEPLUGIN_H #define PHASEPLUGIN_H #include #include #include class PhaseSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorTime() const; Kst::VectorPtr vectorData() const; Kst::ScalarPtr scalarPeriod() const; Kst::ScalarPtr scalarZeroPhase() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: PhaseSource(Kst::ObjectStore *store); ~PhaseSource(); private: void swap(double* pData[], int iOne, int iTwo); void quicksort(double* pData[], int iLeft, int iRight); friend class Kst::ObjectStore; }; class PhasePlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~PhasePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/phase/phaseconfig.ui000644 001750 001750 00000012161 11544160207 023167 0ustar00synthsynth000000 000000 PhaseConfig 0 0 430 205 400 0 0 0 Input Vector Time false Qt::Horizontal 40 20 0 0 0 0 Input Vector Data false Qt::Horizontal 40 20 0 0 0 0 Period false Qt::Horizontal 40 20 0 0 Zero Phase false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/phase/phase.pro000644 001750 001750 00000000222 11544160207 022157 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_phase) SOURCES += \ phase.cpp HEADERS += \ phase.h FORMS += phaseconfig.ui kst-2.0.3/src/plugins/dataobject/phase/kstplugin_phase.desktop000644 001750 001750 00000000370 11544160207 025134 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=phase X-Kst-Plugin-Author=The University of Toronto Name=Phase Data Object Plugin Comment=Implements a Phase Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/phase/phase.cpp000644 001750 001750 00000027106 11544160207 022153 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* FIXME: figure out what this plugin is supposed to do, and comment accordingly. */ #include "phase.h" #include "objectstore.h" #include "ui_phaseconfig.h" static const QString& VECTOR_IN_TIME = "Vector In Time"; static const QString& VECTOR_IN_DATA = "Vector In Data"; static const QString& SCALAR_IN_PERIOD = "Period"; static const QString& SCALAR_IN_ZEROPHASE = "Zero Phase"; static const QString& VECTOR_OUT_PHASE = "Phase"; static const QString& VECTOR_OUT_DATA = "Data Out"; class ConfigPhasePlugin : public Kst::DataObjectConfigWidget, public Ui_PhaseConfig { public: ConfigPhasePlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_PhaseConfig() { setupUi(this); } ~ConfigPhasePlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorTime->setObjectStore(store); _vectorData->setObjectStore(store); _scalarPeriod->setObjectStore(store); _scalarZeroPhase->setObjectStore(store); _scalarPeriod->setDefaultValue(0); _scalarZeroPhase->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorTime, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorData, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarPeriod, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarZeroPhase, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorTime() { return _vectorTime->selectedVector(); }; void setSelectedVectorTime(Kst::VectorPtr vector) { return _vectorTime->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorData() { return _vectorData->selectedVector(); }; void setSelectedVectorData(Kst::VectorPtr vector) { return _vectorData->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarPeriod() { return _scalarPeriod->selectedScalar(); }; void setSelectedScalarPeriod(Kst::ScalarPtr scalar) { return _scalarPeriod->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarZeroPhase() { return _scalarZeroPhase->selectedScalar(); }; void setSelectedScalarZeroPhase(Kst::ScalarPtr scalar) { return _scalarZeroPhase->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (PhaseSource* source = static_cast(dataObject)) { setSelectedVectorTime(source->vectorTime()); setSelectedVectorData(source->vectorData()); setSelectedScalarPeriod(source->scalarPeriod()); setSelectedScalarZeroPhase(source->scalarZeroPhase()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Phase DataObject Plugin"); _cfg->setValue("Input Vector Time", _vectorTime->selectedVector()->Name()); _cfg->setValue("Input Vector Data", _vectorData->selectedVector()->Name()); _cfg->setValue("Input Scalar Period", _scalarPeriod->selectedScalar()->Name()); _cfg->setValue("Input Scalar Zero Phase", _scalarZeroPhase->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Phase DataObject Plugin"); QString vectorName = _cfg->value("Input Vector Time").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorTime = static_cast(object); if (vectorTime) { setSelectedVectorTime(vectorTime); } vectorName = _cfg->value("Input Vector Data").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorData = static_cast(object); if (vectorData) { setSelectedVectorData(vectorData); } QString scalarName = _cfg->value("Input Scalar Period").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarPeriod = static_cast(object); if (scalarPeriod) { setSelectedScalarPeriod(scalarPeriod); } scalarName = _cfg->value("Input Scalar Zero Phase").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarZeroPhase = static_cast(object); if (scalarZeroPhase) { setSelectedScalarZeroPhase(scalarZeroPhase); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; PhaseSource::PhaseSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } PhaseSource::~PhaseSource() { } QString PhaseSource::_automaticDescriptiveName() const { return QString("Phase Plugin Object"); } void PhaseSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigPhasePlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_TIME, config->selectedVectorTime()); setInputVector(VECTOR_IN_DATA, config->selectedVectorData()); setInputScalar(SCALAR_IN_PERIOD, config->selectedScalarPeriod()); setInputScalar(SCALAR_IN_ZEROPHASE, config->selectedScalarZeroPhase()); } } void PhaseSource::setupOutputs() { setOutputVector(VECTOR_OUT_PHASE, ""); setOutputVector(VECTOR_OUT_DATA, ""); } bool PhaseSource::algorithm() { Kst::VectorPtr inputVectorTime = _inputVectors[VECTOR_IN_TIME]; Kst::VectorPtr inputVectorData = _inputVectors[VECTOR_IN_DATA]; Kst::ScalarPtr inputScalarPeriod = _inputScalars[SCALAR_IN_PERIOD]; Kst::ScalarPtr inputScalarZeroPhase = _inputScalars[SCALAR_IN_ZEROPHASE]; Kst::VectorPtr outputVectorPhase = _outputVectors[VECTOR_OUT_PHASE]; Kst::VectorPtr outputVectorDataOut = _outputVectors[VECTOR_OUT_DATA]; double* pResult[2]; double dPhasePeriod = inputScalarPeriod->value(); double dPhaseZero = inputScalarZeroPhase->value(); int iLength; bool bReturn = false; if (dPhasePeriod <= 0.0) { _errorString = "Error: Input Scalar Phase must be greater than zero."; return false; } if (inputVectorTime->length() != inputVectorData->length()) { _errorString = "Error: Input Vector lengths do not match."; return false; } iLength = inputVectorTime->length(); outputVectorPhase->resize(iLength, true); pResult[0] = outputVectorPhase->value(); outputVectorDataOut->resize(iLength, true); pResult[1] = outputVectorDataOut->value(); if (pResult[0] != NULL && pResult[1] != NULL) { for (int i = 0; i < outputVectorPhase->length(); ++i) { outputVectorPhase->value()[i] = pResult[0][i]; } for (int i = 0; i < outputVectorDataOut->length(); ++i) { outputVectorDataOut->value()[i] = pResult[1][i]; } /* determine the outputVectorPhase... */ for (int i=0; ivalue()[i] = fmod( ( inputVectorTime->value()[i] - dPhaseZero ) / dPhasePeriod, 1.0 ); } /* sort by outputVectorPhase... */ memcpy( outputVectorDataOut->value(), inputVectorData->value(), iLength * sizeof( double ) ); double* sort[2]; sort[0] = outputVectorPhase->value(); sort[1] = outputVectorDataOut->value(); quicksort( sort, 0, iLength-1 ); bReturn = true; } return bReturn; } void PhaseSource::swap(double* pData[], int iOne, int iTwo) { double dTemp; for (int i=0; i<2; i++) { dTemp = pData[i][iOne]; pData[i][iOne] = pData[i][iTwo]; pData[i][iTwo] = dTemp; } } void PhaseSource::quicksort( double* pData[], int iLeft, int iRight) { double dVal = pData[0][iRight]; int i = iLeft - 1; int j = iRight; if (iRight <= iLeft) { return; } while (1) { while (pData[0][++i] < dVal) {} while (dVal < pData[0][--j]) { if (j == iLeft) { break; } } if (i >= j) { break; } swap( pData, i, j ); } swap( pData, i, iRight ); quicksort( pData, iLeft, i-1 ); quicksort( pData, i+1, iRight ); } Kst::VectorPtr PhaseSource::vectorTime() const { return _inputVectors[VECTOR_IN_TIME]; } Kst::VectorPtr PhaseSource::vectorData() const { return _inputVectors[VECTOR_IN_DATA]; } Kst::ScalarPtr PhaseSource::scalarPeriod() const { return _inputScalars[SCALAR_IN_PERIOD]; } Kst::ScalarPtr PhaseSource::scalarZeroPhase() const { return _inputScalars[SCALAR_IN_ZEROPHASE]; } QStringList PhaseSource::inputVectorList() const { QStringList vectors(VECTOR_IN_TIME); vectors += VECTOR_IN_DATA; return vectors; } QStringList PhaseSource::inputScalarList() const { QStringList scalars(SCALAR_IN_PERIOD); scalars += SCALAR_IN_ZEROPHASE; return scalars; } QStringList PhaseSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList PhaseSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_PHASE); vectors += VECTOR_OUT_DATA; return vectors; } QStringList PhaseSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList PhaseSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void PhaseSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString PhasePlugin::pluginName() const { return "Phase"; } QString PhasePlugin::pluginDescription() const { return "Phases a given data set to the specified period and zero outputVectorPhase."; } Kst::DataObject *PhasePlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigPhasePlugin* config = static_cast(configWidget)) { PhaseSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_TIME, config->selectedVectorTime()); object->setInputVector(VECTOR_IN_DATA, config->selectedVectorData()); object->setInputScalar(SCALAR_IN_PERIOD, config->selectedScalarPeriod()); object->setInputScalar(SCALAR_IN_ZEROPHASE, config->selectedScalarZeroPhase()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *PhasePlugin::configWidget(QSettings *settingsObject) const { ConfigPhasePlugin *widget = new ConfigPhasePlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, PhasePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/chop/chop.cpp000644 001750 001750 00000016147 11544160207 021640 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* FIXME: rename to something more clear */ /* differences even samples from odd samples. Used for LFI, whose Dicky-switch produces even samples looking at a cold load, and odd samples looking at the sky */ #include "chop.h" #include "objectstore.h" #include "ui_chopconfig.h" static const QString& VECTOR_IN = "Vector In"; static const QString& VECTOR_OUT_ODD = "Odd Vector"; static const QString& VECTOR_OUT_EVEN = "Even Vector"; static const QString& VECTOR_OUT_DIFFERENCE = "Difference Vector"; static const QString& VECTOR_OUT_INDEX = "Index Vector"; class ConfigWidgetChopPlugin : public Kst::DataObjectConfigWidget, public Ui_ChopConfig { public: ConfigWidgetChopPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_ChopConfig() { setupUi(this); } ~ConfigWidgetChopPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (ChopSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Chop DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Chop DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; ChopSource::ChopSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } ChopSource::~ChopSource() { } QString ChopSource::_automaticDescriptiveName() const { return QString("Chop Plugin Object"); } void ChopSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetChopPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); } } void ChopSource::setupOutputs() { setOutputVector(VECTOR_OUT_ODD, ""); setOutputVector(VECTOR_OUT_EVEN, ""); setOutputVector(VECTOR_OUT_DIFFERENCE, ""); setOutputVector(VECTOR_OUT_INDEX, ""); } bool ChopSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::VectorPtr outputVectorOdd = _outputVectors[VECTOR_OUT_ODD]; Kst::VectorPtr outputVectorEven = _outputVectors[VECTOR_OUT_EVEN]; Kst::VectorPtr outputVectorDifference = _outputVectors[VECTOR_OUT_DIFFERENCE]; Kst::VectorPtr outputVectorIndex = _outputVectors[VECTOR_OUT_INDEX]; //Make sure there is at least 1 element in the input vector if (inputVector->length() < 1) { _errorString = "Error: Input Vector invalid size"; return false; } int iLength = inputVector->length(); int iLengthNew = (int)ceil(iLength / 2.0); outputVectorOdd->resize(iLengthNew, false); outputVectorEven->resize(iLengthNew, false); outputVectorDifference->resize(iLengthNew, false); outputVectorIndex->resize(iLengthNew, false); for (int i = 0; i < iLength; i+=2) { outputVectorOdd->value()[i/2] = inputVector->value()[i]; outputVectorEven->value()[i/2] = inputVector->value()[i+1]; outputVectorDifference->value()[i/2] = inputVector->value()[i] - inputVector->value()[i+1]; outputVectorIndex->value()[i/2] = i/2; } return true; } Kst::VectorPtr ChopSource::vector() const { return _inputVectors[VECTOR_IN]; } QStringList ChopSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList ChopSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList ChopSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList ChopSource::outputVectorList() const { QStringList vectorList(VECTOR_OUT_ODD); vectorList += VECTOR_OUT_EVEN; vectorList += VECTOR_OUT_DIFFERENCE; vectorList += VECTOR_OUT_INDEX; return vectorList; } QStringList ChopSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList ChopSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void ChopSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString ChopPlugin::pluginName() const { return "Chop"; } QString ChopPlugin::pluginDescription() const { return "Chops a given data set into odd, even, difference, and Index data sets."; } Kst::DataObject *ChopPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetChopPlugin* config = static_cast(configWidget)) { ChopSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *ChopPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetChopPlugin *widget = new ConfigWidgetChopPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ChopPlugin, ChopPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/chop/chopconfig.ui000644 001750 001750 00000003027 11544160207 022652 0ustar00synthsynth000000 000000 ChopConfig 0 0 423 43 400 0 0 0 Input Vector false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/chop/kstplugin_chop.desktop000644 001750 001750 00000000365 11544160207 024622 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=chop X-Kst-Plugin-Author=The University of Toronto Name=Chop Data Object Plugin Comment=Implements a Chop Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/chop/chop.pro000644 001750 001750 00000000216 11544160207 021644 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_chop) SOURCES += \ chop.cpp HEADERS += \ chop.h FORMS += chopconfig.ui kst-2.0.3/src/plugins/dataobject/chop/chop.h000644 001750 001750 00000004767 11544160207 021312 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CHOPPLUGIN_H #define CHOPPLUGIN_H #include #include #include class ChopSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: ChopSource(Kst::ObjectStore *store); ~ChopSource(); friend class Kst::ObjectStore; }; class ChopPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~ChopPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/effectivebandwidth/effectivebandwidth.pro000644 001750 001750 00000000306 11544160207 027434 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_effectivebandwidth) SOURCES += \ effectivebandwidth.cpp HEADERS += \ effectivebandwidth.h FORMS += effectivebandwidthconfig.ui kst-2.0.3/src/plugins/dataobject/effectivebandwidth/kstplugin_effectivebandwidth.desktop000644 001750 001750 00000000441 11544160207 032405 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=effectivebandwidth X-Kst-Plugin-Author=The University of Toronto Name=Effective Bandwidth Data Object Plugin Comment=Implements a Effective Bandwidth Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/effectivebandwidth/effectivebandwidthconfig.ui000644 001750 001750 00000014140 11544160207 030440 0ustar00synthsynth000000 000000 EffectiveBandwidthConfig 0 0 430 181 400 0 0 0 Input Vector X false Qt::Horizontal 40 20 0 0 0 0 Input Vector Y false Qt::Horizontal 40 20 0 0 0 0 Min. White Noise Freq. false Qt::Horizontal 40 20 0 0 SamplingFrequency (Hz) false Qt::Horizontal 40 20 0 0 K false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/effectivebandwidth/effectivebandwidth.h000644 001750 001750 00000005357 11544160207 027076 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EFFECTIVEBANDWIDTHPLUGIN_H #define EFFECTIVEBANDWIDTHPLUGIN_H #include #include #include class EffectiveBandwidthSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::ScalarPtr scalarMin() const; Kst::ScalarPtr scalarFreq() const; Kst::ScalarPtr scalarK() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: EffectiveBandwidthSource(Kst::ObjectStore *store); ~EffectiveBandwidthSource(); friend class Kst::ObjectStore; }; class EffectiveBandwidthPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~EffectiveBandwidthPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/effectivebandwidth/effectivebandwidth.cpp000644 001750 001750 00000031540 11544160207 027422 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "effectivebandwidth.h" #include "objectstore.h" #include "ui_effectivebandwidthconfig.h" static const QString& VECTOR_IN_X = "Vector In X"; static const QString& VECTOR_IN_Y = "Vector In Y"; static const QString& SCALAR_IN_MIN = "Min. White Noise Freq."; static const QString& SCALAR_IN_FREQ = "Sampling Frequency (Hz)"; static const QString& SCALAR_IN_K = "K"; static const QString& SCALAR_OUT_LIMIT = "White Noise Limit"; static const QString& SCALAR_OUT_SIGMA = "White Noise Sigma"; static const QString& SCALAR_OUT_BANDWIDTH = "Effective Bandwidth"; class ConfigEffectiveBandwidthPlugin : public Kst::DataObjectConfigWidget, public Ui_EffectiveBandwidthConfig { public: ConfigEffectiveBandwidthPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_EffectiveBandwidthConfig() { setupUi(this); } ~ConfigEffectiveBandwidthPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _scalarMin->setObjectStore(store); _scalarFreq->setObjectStore(store); _scalarK->setObjectStore(store); _scalarMin->setDefaultValue(0); _scalarFreq->setDefaultValue(0); _scalarK->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarMin, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarFreq, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarK, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarMin() { return _scalarMin->selectedScalar(); }; void setSelectedScalarMin(Kst::ScalarPtr scalar) { return _scalarMin->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarFreq() { return _scalarFreq->selectedScalar(); }; void setSelectedScalarFreq(Kst::ScalarPtr scalar) { return _scalarFreq->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarK() { return _scalarK->selectedScalar(); }; void setSelectedScalarK(Kst::ScalarPtr scalar) { return _scalarK->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (EffectiveBandwidthSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedScalarMin(source->scalarMin()); setSelectedScalarFreq(source->scalarFreq()); setSelectedScalarK(source->scalarK()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Effective Bandwidth DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Scalar Min. White Noise Freq.", _scalarMin->selectedScalar()->Name()); _cfg->setValue("Input Scalar Sampling Frequency (Hz)", _scalarFreq->selectedScalar()->Name()); _cfg->setValue("Input Scalar K", _scalarK->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Effective Bandwidth DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorX = static_cast(object); if (vectorX) { setSelectedVectorX(vectorX); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorY = static_cast(object); if (vectorY) { setSelectedVectorY(vectorY); } QString scalarName = _cfg->value("Input Scalar Min. White Noise Freq.").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarMin = static_cast(object); if (scalarMin) { setSelectedScalarMin(scalarMin); } scalarName = _cfg->value("Input Scalar Sampling Frequency (Hz)").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarFreq = static_cast(object); if (scalarFreq) { setSelectedScalarFreq(scalarFreq); } scalarName = _cfg->value("Input Scalar K").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarK = static_cast(object); if (scalarK) { setSelectedScalarK(scalarK); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; EffectiveBandwidthSource::EffectiveBandwidthSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } EffectiveBandwidthSource::~EffectiveBandwidthSource() { } QString EffectiveBandwidthSource::_automaticDescriptiveName() const { return QString("Effective Bandwidth Plugin Object"); } void EffectiveBandwidthSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigEffectiveBandwidthPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputScalar(SCALAR_IN_MIN, config->selectedScalarMin()); setInputScalar(SCALAR_IN_FREQ, config->selectedScalarFreq()); setInputScalar(SCALAR_IN_K, config->selectedScalarK()); } } void EffectiveBandwidthSource::setupOutputs() { setOutputScalar(SCALAR_OUT_LIMIT, ""); setOutputScalar(SCALAR_OUT_SIGMA, ""); setOutputScalar(SCALAR_OUT_BANDWIDTH, ""); } bool EffectiveBandwidthSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::ScalarPtr inputScalarMin = _inputScalars[SCALAR_IN_MIN]; Kst::ScalarPtr inputScalarFreq = _inputScalars[SCALAR_IN_FREQ]; Kst::ScalarPtr inputScalarK = _inputScalars[SCALAR_IN_K]; Kst::ScalarPtr outputScalarLimit = _outputScalars[SCALAR_OUT_LIMIT]; Kst::ScalarPtr outputScalarSigma = _outputScalars[SCALAR_OUT_SIGMA]; Kst::ScalarPtr outputScalarBandwidth = _outputScalars[SCALAR_OUT_BANDWIDTH]; //Make sure there is at least 1 element in the input vector if (inputVectorX->length() < 1) { _errorString = "Error: Input Vector X invalid size"; return false; } // Make sure the input vectors match. if (inputVectorX->length() != inputVectorY->length()) { _errorString = "Error: Input Vector X and Input Vector Y are not the same length"; return false; } double minWhiteNoiseFreq, samplingFrequency, radiometerConstantK; minWhiteNoiseFreq = inputScalarMin->value(); samplingFrequency = inputScalarFreq->value(); radiometerConstantK = inputScalarK->value(); int minWhiteNoiseIndex; //fast calculation of index for minWhiteNoiseFreq int i_bot, i_top; i_bot = 0; i_top = inputVectorX->length() - 1; while (i_bot + 1 < i_top) { int i0 = (i_top + i_bot)/2; if (minWhiteNoiseFreq < inputVectorX->value()[i0]) { i_top = i0; } else { i_bot = i0; } } minWhiteNoiseIndex = i_top; //verify calculated indices. if ( !(minWhiteNoiseIndex>0) || !(minWhiteNoiseIndex<(inputVectorX->length()-1)) ) { _errorString = "Error: Calculated Indices invalid"; return false; } // calculate white noise limit double sumY, sumY2; sumY = sumY2 = 0; int i; double yi; for (i = minWhiteNoiseIndex; i < inputVectorX->length(); i++) { yi = inputVectorY->value()[i]; sumY += yi; sumY2 += pow(yi,2); } double ybar, ysigma; ybar = sumY/(inputVectorX->length() - minWhiteNoiseIndex); ysigma = sqrt((sumY2 - 2*ybar*sumY + pow(ybar,2)*(inputVectorX->length() - minWhiteNoiseIndex))/(inputVectorX->length() - minWhiteNoiseIndex)); // end calculate white noise limit double effectiveBandwidth = 2*samplingFrequency*pow(radiometerConstantK*inputVectorY->value()[0]/ysigma,2); // output fit data outputScalarLimit->setValue(ybar); outputScalarSigma->setValue(ysigma); outputScalarBandwidth->setValue(effectiveBandwidth); return true; } Kst::VectorPtr EffectiveBandwidthSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr EffectiveBandwidthSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::ScalarPtr EffectiveBandwidthSource::scalarMin() const { return _inputScalars[SCALAR_IN_MIN]; } Kst::ScalarPtr EffectiveBandwidthSource::scalarFreq() const { return _inputScalars[SCALAR_IN_FREQ]; } Kst::ScalarPtr EffectiveBandwidthSource::scalarK() const { return _inputScalars[SCALAR_IN_K]; } QStringList EffectiveBandwidthSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList EffectiveBandwidthSource::inputScalarList() const { QStringList scalars(SCALAR_IN_MIN); scalars += SCALAR_IN_FREQ; scalars += SCALAR_IN_K; return scalars; } QStringList EffectiveBandwidthSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList EffectiveBandwidthSource::outputVectorList() const { return QStringList( /*VECTOR_OUT*/ ); } QStringList EffectiveBandwidthSource::outputScalarList() const { QStringList scalars(SCALAR_OUT_LIMIT); scalars += SCALAR_OUT_SIGMA; scalars += SCALAR_OUT_BANDWIDTH; return scalars; } QStringList EffectiveBandwidthSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void EffectiveBandwidthSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString EffectiveBandwidthPlugin::pluginName() const { return "Effective Bandwidth"; } QString EffectiveBandwidthPlugin::pluginDescription() const { return "Calculates effective bandwidth from an amplitude spectrum."; } Kst::DataObject *EffectiveBandwidthPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigEffectiveBandwidthPlugin* config = static_cast(configWidget)) { EffectiveBandwidthSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputScalar(SCALAR_IN_MIN, config->selectedScalarMin()); object->setInputScalar(SCALAR_IN_FREQ, config->selectedScalarFreq()); object->setInputScalar(SCALAR_IN_K, config->selectedScalarK()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *EffectiveBandwidthPlugin::configWidget(QSettings *settingsObject) const { ConfigEffectiveBandwidthPlugin *widget = new ConfigEffectiveBandwidthPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, EffectiveBandwidthPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/lockin/lockin.cpp000644 001750 001750 00000025676 11544160207 022523 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * sbenton@phsyics.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "lockin.h" #include "objectstore.h" #include "ui_lockinconfig.h" #include "iirfilter.h" #include #include using std::vector; typedef std::complex complex; //TODO maybe use Qt vector types, and kst filters //TODO allow reference waveforms other than square wave //TODO these parameters, and filter cutoffs, and the guess period should be made commandable const double f_samp = 4.0E6/384.0/104.0; //sample frequency const int DELAY = 0; static const QString& SHORT_NAME = "Lock-In"; static const QString& PLUGIN_NAME = "Lock-In DataObject Plugin"; static const QString& PLUGIN_DESCRIPTION = "Lock-In amplifies Input using a Reference carrier wave"; static const QString& IN_INPUT_VECTOR = "Input Vector"; static const QString& IN_REF_VECTOR = "Reference Vector"; static const QString& OUT_REF_VECTOR_NORM = "Normalized Reference Vector"; static const QString& OUT_LOCKIN_RESULT = "Lock-In Result"; class ConfigLockInPlugin : public Kst::DataObjectConfigWidget, public Ui_LockInConfig { public: ConfigLockInPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_LockInConfig() { setupUi(this); } ~ConfigLockInPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _inputVector->setObjectStore(store); _refVector->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_inputVector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_refVector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedInputVector() { return _inputVector->selectedVector(); }; void setSelectedInputVector(Kst::VectorPtr vector) { return _inputVector->setSelectedVector(vector); }; Kst::VectorPtr selectedRefVector() { return _refVector->selectedVector(); }; void setSelectedRefVector(Kst::VectorPtr vector) { return _refVector->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (LockInSource* source = static_cast(dataObject)) { setSelectedInputVector(source->inputVector()); setSelectedRefVector(source->refVector()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup(PLUGIN_NAME); _cfg->setValue(IN_INPUT_VECTOR, _inputVector->selectedVector()->Name()); _cfg->setValue(IN_REF_VECTOR, _refVector->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup(PLUGIN_NAME); QString vectorName = _cfg->value(IN_INPUT_VECTOR).toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedInputVector(vector); } vectorName = _cfg->value(IN_REF_VECTOR).toString(); Kst::Object* object2 = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object2); if (vector2) { setSelectedRefVector(vector2); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; LockInSource::LockInSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } LockInSource::~LockInSource() { } QString LockInSource::_automaticDescriptiveName() const { return PLUGIN_NAME; } void LockInSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigLockInPlugin* config = static_cast(configWidget)) { setInputVector(IN_INPUT_VECTOR, config->selectedInputVector()); setInputVector(IN_REF_VECTOR, config->selectedRefVector()); } } void LockInSource::setupOutputs() { setOutputVector(OUT_REF_VECTOR_NORM, ""); setOutputVector(OUT_LOCKIN_RESULT, ""); } /* REALLY BAD CODE * use two copies of this function, to have independent static variables */ static complex f_pll(double ref) { static double period = 20.0; static double phase = 0.0; static double T = 0.0; static int ref_edge = 0; static int pll_edge = 0; static double ph = 0.0; static double dph = 0.0; static BesselHP1 fref(0.0125/f_samp); static BesselLP1 fperiod(0.15/f_samp); static BesselLP1 fphase(0.15/f_samp); double ref_ = fref(ref); ph += dph; T += 1.0; double pll_ref = cos(ph); if(ref_edge == 0 && ref_ >= 0.0) { period = fperiod(T); ref_edge = 1; dph = (2.0*M_PI)/period; T = 0.0; } else if(ref_edge == 1 && ref_ < 0.0 && T > 1.0) { ref_edge = 0; } if(pll_edge == 0 && (pll_ref >= 0.0)) { phase = fphase(T*dph); pll_edge = 1; } else if(pll_edge == 1 && (pll_ref < 0.0)) { pll_edge = 0; } return complex( ((cos(ph+phase) > 0.0) ? 1 : -1), ((sin(ph+phase) > 0.0) ? 1 : -1) ); } static complex b_pll(double ref) { static double period = 20.0; static double phase = 0.0; static double T = 0.0; static int ref_edge = 0; static int pll_edge = 0; static double ph = 0.0; static double dph = 0.0; static BesselHP1 fref(0.0125/f_samp); static BesselLP1 fperiod(0.15/f_samp); static BesselLP1 fphase(0.15/f_samp); double ref_ = fref(ref); ph += dph; T += 1.0; double pll_ref = cos(ph); if(ref_edge == 0 && ref_ >= 0.0) { period = fperiod(T); ref_edge = 1; dph = (2.0*M_PI)/period; T = 0.0; } else if(ref_edge == 1 && ref_ < 0.0 && T > 1.0) { ref_edge = 0; } if(pll_edge == 0 && (pll_ref >= 0.0)) { phase = fphase(T*dph); pll_edge = 1; } else if(pll_edge == 1 && (pll_ref < 0.0)) { pll_edge = 0; } return complex( ((cos(ph+phase) > 0.0) ? 1 : -1), ((sin(ph+phase) > 0.0) ? 1 : -1) ); } bool LockInSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[IN_INPUT_VECTOR]; Kst::VectorPtr refVector = _inputVectors[IN_REF_VECTOR]; Kst::VectorPtr normRefVector = _outputVectors[OUT_REF_VECTOR_NORM]; Kst::VectorPtr lockinResult = _outputVectors[OUT_LOCKIN_RESULT]; if (inputVector->length() <= 0 || refVector->length() <= 0 || inputVector->length() != refVector->length()) { _errorString = "Error: Input Vectors - invalid size"; return false; } int iLength = inputVector->length(); normRefVector->resize(iLength, false); lockinResult->resize(iLength, false); double* pdInput = inputVector->value(); double* pdRef = refVector->value(); double* pdNormRef = normRefVector->value(); double* pdResult = lockinResult->value(); /* to remove initial settling, evaluate the result separately in forward and backward direction */ BesselHP1 f_filt_d(0.15/f_samp); BesselLP4 f_filt_li(0.39/f_samp); BesselHP1 b_filt_d(0.15/f_samp); BesselLP4 b_filt_li(0.39/f_samp); for (int i=0; i= iLength/2) { if (i >= (iLength*3)/4) { //for first and last quarter of the domain, use backward and forward result pdResult[i] = f_result; pdResult[iLength-i-1] = b_result; } else { //for middle half, use weight that changes linearly between the extremes double weight = 2.0*double(i)/double(iLength) - 0.5; pdResult[i] = weight*f_result + (1.0-weight)*b_result; pdResult[iLength-i-1] = weight*b_result + (1.0-weight)*f_result; } //for the reference, just split the result at the middle pdNormRef[i] = f_pll_ref.real(); pdNormRef[iLength-i-1] = b_pll_ref.real(); } } return true; } Kst::VectorPtr LockInSource::inputVector() const { return _inputVectors[IN_INPUT_VECTOR]; } Kst::VectorPtr LockInSource::refVector() const { return _inputVectors[IN_REF_VECTOR]; } QStringList LockInSource::inputVectorList() const { QStringList vectors(IN_INPUT_VECTOR); vectors += IN_REF_VECTOR; return vectors; } QStringList LockInSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList LockInSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList LockInSource::outputVectorList() const { QStringList vectors(OUT_LOCKIN_RESULT); vectors += OUT_REF_VECTOR_NORM; return vectors; } QStringList LockInSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList LockInSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void LockInSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString LockInPlugin::pluginName() const { return SHORT_NAME; } QString LockInPlugin::pluginDescription() const { return PLUGIN_DESCRIPTION; } Kst::DataObject *LockInPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigLockInPlugin* config = static_cast(configWidget)) { LockInSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(IN_INPUT_VECTOR, config->selectedInputVector()); object->setInputVector(IN_REF_VECTOR, config->selectedRefVector()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *LockInPlugin::configWidget(QSettings *settingsObject) const { ConfigLockInPlugin *widget = new ConfigLockInPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_LockInPlugin, LockInPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/lockin/lockin.h000644 001750 001750 00000004626 11544160207 022160 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * sbenton@physics.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LOCKINPLUGIN_H #define LOCKINPLUGIN_H #include #include #include class LockInSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr inputVector() const; Kst::VectorPtr refVector() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: LockInSource(Kst::ObjectStore *store); ~LockInSource(); friend class Kst::ObjectStore; }; class LockInPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~LockInPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/lockin/lockinconfig.ui000644 001750 001750 00000004662 11544160207 023534 0ustar00synthsynth000000 000000 LockInConfig 0 0 428 86 400 0 0 0 Input Vector false 0 0 0 0 Reference Vector false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/lockin/lockin.pro000644 001750 001750 00000000226 11544160207 022521 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_lockin) SOURCES += lockin.cpp HEADERS += lockin.h iirfilter.h FORMS += lockinconfig.ui kst-2.0.3/src/plugins/dataobject/lockin/kstplugin_lockin.desktop000644 001750 001750 00000000444 11544160207 025474 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=lockin X-Kst-Plugin-Author=The University of Toronto Name=Lock-In Amplification Data Object Plugin Comment=Lock-In amplification of channel to reference Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/lockin/iirfilter.h000644 001750 001750 00000016627 11544160207 022676 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * sbenton@phsyics.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #ifndef _IIRFILTER_H #define _IIRFILTER_H using std::deque; using std::vector; typedef std::complex complex; /* * allows for definition of general recursive/IIR filters * * Probably doesn't need to be a template, but I was experimenting * now you can filter a series of vectors! (or rather float/long double/complex) * */ template class IIRFilter { public: IIRFilter(unsigned int order); //do fitlering by calling your instance with most recent input T operator() (T x); //clear the filter history void clear(); //evaluate transfer function at complex point z complex transfer(complex z); //function generates data stream containing impulse and frequency response //clears filter both before and after int FilterResponse(const char* out, double max_f=0.5, unsigned int n=100); protected: //to be used in derived class constructors void setCoefficients(vector na, vector nb); private: deque x0; //last filter input deque y0; //last filter output vector a; //coefficients to multiply y0 vector b; //coefficients to multiply x, x0 unsigned int order; //order of the filter }; /* * A few sample filter types. Analytic forms for a few low-order Bessel filters * * TODO: it would be great to use numerically designed filters * */ //1st order bessel low-pass, with knee frequency f (in sample rate units) template class BesselLP1 : public IIRFilter { public: BesselLP1(double f); }; //1st order bessel high-pass, with knee frequency f (in sample rate units) template class BesselHP1 : public IIRFilter { public: BesselHP1(double f); }; //4th order bessel low-pass, with knee frequency f (in sample rate units) template class BesselLP4 : public IIRFilter { public: BesselLP4(double f); }; /******************************************************************************* * IMPLEMENTATION * g++ doesn't support 'export' for template implementations in another file * so, all the implementations are here ******************************************************************************/ #include #include #include #include #include "iirfilter.h" using std::cerr; using std::endl; template IIRFilter::IIRFilter(unsigned int order) { this->order = order; x0.resize(order, 0.0); y0.resize(order, 0.0); a.resize(order, 0.0); b.resize(order+1, 0.0); //includes coefficient for new inupt x } template T IIRFilter::operator() (T x) { T y = b[0]*x; //cerr << "y = (" << b[0] << ")*x[n]" << endl; for (unsigned int i=0; i void IIRFilter::clear() { x0.resize(order, T()); y0.resize(order, T()); } template complex IIRFilter::transfer(complex z) { complex numer = pow(z,4)*b[0]; complex denom = pow(z,4); for (unsigned int i=0; i int IIRFilter::FilterResponse(const char* out, double max_f, unsigned int n) { std::ofstream oo(out); if (!oo) { cerr << "Couldn't open FilterResponse output file" << endl; return 1; } this->clear(); oo << "INDEX\timpulse\tfreq\tgain\tphase" << endl; for (unsigned int i=0; iclear(); return 0; } template void IIRFilter::setCoefficients(vector na, vector nb) { if (na.size() != order || nb.size() != order+1) { cerr << "Invalid size of coefficient vector\n" << endl; return; } a = na; b = nb; } //The filter forms below were solved analytically using a bilinear transform //bessel scale factors //convert normalization from unit delay at f=0 to 3dB attenutation at 1rad/s const double norm_bessel_O1 = 1.0; const double norm_bessel_O2 = 1.36165412871613; const double norm_bessel_O3 = 1.75567236868121; const double norm_bessel_O4 = 2.11391767490422; const double norm_bessel_O5 = 2.42741070215263; const double norm_bessel_O6 = 2.70339506120292; const double norm_bessel_O7 = 2.95172214703872; const double norm_bessel_O8 = 3.17961723751065; const double norm_bessel_O9 = 3.39169313891166; const double norm_bessel_O10 = 3.59098059456916; template BesselLP1::BesselLP1(double f) : IIRFilter(1) { vector a(1), b(2); double alpha = M_PI*f/norm_bessel_O1; alpha = tan(alpha); //pre-warp a[0] = (alpha-1.0)/(1.0+alpha); b[0] = alpha/(1.0+alpha); b[1] = alpha/(1.0+alpha); this->setCoefficients(a, b); } template BesselHP1::BesselHP1(double f) : IIRFilter(1) { vector a(1), b(2); double alpha = M_PI*f/norm_bessel_O1; alpha = tan(alpha); //pre-warp a[0] = (alpha-1.0)/(1.0+alpha); b[0] = 1.0/(1.0+alpha); b[1] = -1.0/(1.0+alpha); this->setCoefficients(a, b); } template BesselLP4::BesselLP4(double f) : IIRFilter(4) { vector a(4), b(5); double alpha = M_PI*f/norm_bessel_O4; alpha = tan(alpha); //pre-warp double denom = (1.0 + 1.0/alpha + 45.0/105.0/pow(alpha,2) + 10.0/105.0/pow(alpha,3) + 1.0/105.0/pow(alpha,4)); a[0] = (4.0 + 2.0/alpha - 20.0/105.0/pow(alpha,3) - 4.0/105.0/pow(alpha,4))/denom; a[1] = (6.0 - 90.0/105.0/pow(alpha,2) + 6.0/105.0/pow(alpha,4))/denom; a[2] = (4.0 - 2.0/alpha + 20.0/105.0/pow(alpha,3) - 4.0/105.0/pow(alpha,4))/denom; a[3] = (1.0 - 1.0/alpha + 45.0/105.0/pow(alpha,2) - 10.0/105.0/pow(alpha,3) + 1.0/105.0/pow(alpha,4))/denom; b[0] = 1.0/denom; b[1] = 4.0/denom; b[2] = 6.0/denom; b[3] = 4.0/denom; b[4] = 1.0/denom; /* cerr << "y = (" << b[0] << ")*x[n]" << endl; for (unsigned int i=0; i<4; i++) { cerr << " + (" << b[i+1] << ")*x[n-" << i+1 << "]"; cerr << " - (" << a[i] << ")*y[n-" << i+1 << "]" << endl; } */ this->setCoefficients(a, b); } #endif kst-2.0.3/src/plugins/dataobject/linefit/linefit.h000644 001750 001750 00000005061 11544160207 022500 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LINEFITPLUGIN_H #define LINEFITPLUGIN_H #include #include #include class LineFitSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: LineFitSource(Kst::ObjectStore *store); ~LineFitSource(); friend class Kst::ObjectStore; }; class LineFitPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~LineFitPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/linefit/linefitconfig.ui000644 001750 001750 00000004631 11544160207 024056 0ustar00synthsynth000000 000000 LineFitConfig 0 0 421 78 400 0 0 0 Input Vector X false 0 0 0 0 Input Vector Y false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/linefit/linefit.cpp000644 001750 001750 00000023455 11544160207 023042 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "linefit.h" #include "objectstore.h" #include "ui_linefitconfig.h" #include "math_kst.h" static const QString& VECTOR_IN_X = "Vector In X"; static const QString& VECTOR_IN_Y = "Vector In Y"; static const QString& VECTOR_OUT_X = "X Interpolated"; static const QString& VECTOR_OUT_Y = "Y Interpolated"; static const QString& SCALAR_OUT_A = "a"; static const QString& SCALAR_OUT_B = "b"; static const QString& SCALAR_OUT_CHI2 = "chi^2"; class ConfigWidgetLineFitPlugin : public Kst::DataObjectConfigWidget, public Ui_LineFitConfig { public: ConfigWidgetLineFitPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_LineFitConfig() { setupUi(this); } ~ConfigWidgetLineFitPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (LineFitSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Line Fit DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Line Fit DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorX(vector); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectory = static_cast(object); if (vectory) { setSelectedVectorY(vectory); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; LineFitSource::LineFitSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } LineFitSource::~LineFitSource() { } QString LineFitSource::_automaticDescriptiveName() const { return QString("Line Fit Plugin Object"); } void LineFitSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetLineFitPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } } void LineFitSource::setupOutputs() { setOutputVector(VECTOR_OUT_X, ""); setOutputVector(VECTOR_OUT_Y, ""); setOutputScalar(SCALAR_OUT_A, ""); setOutputScalar(SCALAR_OUT_B, ""); setOutputScalar(SCALAR_OUT_CHI2, ""); } bool LineFitSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr outputVectorX = _outputVectors[VECTOR_OUT_X]; Kst::VectorPtr outputVectorY = _outputVectors[VECTOR_OUT_Y]; Kst::ScalarPtr outputScalarA = _outputScalars[SCALAR_OUT_A]; Kst::ScalarPtr outputScalarB = _outputScalars[SCALAR_OUT_B]; Kst::ScalarPtr outputScalarChi = _outputScalars[SCALAR_OUT_CHI2]; int i = 0; double a = 0.0, b = 0.0, sx = 0.0, sy = 0.0, sxoss = 0.0, st2 = 0.0, chi2 = 0.0; double xScale; if (inputVectorY->length() < 1) { _errorString = "Error: Input Vector Y Length invalid"; return false; } if (inputVectorX->length() < 1) { _errorString = "Error: Input Vector X Length invalid"; return false; } outputVectorX->resize( 2, false ); outputVectorY->resize( 2, false ); if (inputVectorY->length() == 1) { outputVectorX->value()[0] = inputVectorX->value()[0]; outputVectorX->value()[1] = inputVectorX->value()[inputVectorX->length() - 1]; outputVectorY->value()[0] = inputVectorY->value()[0]; outputVectorY->value()[1] = inputVectorY->value()[0]; outputScalarA->setValue( inputVectorY->value()[0] ); outputScalarB->setValue( 0 ); outputScalarChi->setValue( chi2 ); return true; } xScale = inputVectorX->length()/inputVectorY->length(); for (i = 0; i < inputVectorY->length(); i++) { double z = xScale*i; long int idx = long(Kst::roundDouble(z)); double skew = z - floor(z); /* [0..1] */ long int idx2 = idx + 1; sy += inputVectorY->value()[i]; while (idx2 >= inputVectorY->length()) { idx2--; } sx += inputVectorX->value()[idx] + (inputVectorX->value()[idx2] - inputVectorX->value()[idx])*skew; } sxoss = sx / inputVectorX->length(); for (i = 0; i < inputVectorX->length(); i++) { double t = inputVectorX->value()[i] - sxoss; st2 += t * t; b += t * inputVectorY->value()[i]; } b /= st2; a = (sy - sx*b)/inputVectorX->length(); /* could put goodness of fit, etc, in here */ outputVectorX->value()[0] = inputVectorX->value()[0]; outputVectorX->value()[1] = inputVectorX->value()[inputVectorX->length()-1]; outputVectorY->value()[0] = a+b*outputVectorX->value()[0]; outputVectorY->value()[1] = a+b*outputVectorX->value()[1]; for (i = 0; i < inputVectorX->length(); i++) { double z = xScale*i; long int idx = long(Kst::roundDouble(z)); double skew = z - floor(z); /* [0..1] */ long int idx2 = idx + 1; double newX; double ci; while (idx2 >= inputVectorX->length()) { idx2--; } newX = inputVectorX->value()[idx] + (inputVectorX->value()[idx2] - inputVectorX->value()[idx])*skew; ci = inputVectorY->value()[i] - a - b*newX; chi2 += ci*ci; } outputScalarA->setValue( a ); outputScalarB->setValue( b ); outputScalarChi->setValue( chi2 ); return true; } Kst::VectorPtr LineFitSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr LineFitSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } QStringList LineFitSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList LineFitSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList LineFitSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList LineFitSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_X); vectors += VECTOR_OUT_Y; return vectors; } QStringList LineFitSource::outputScalarList() const { QStringList scalars(SCALAR_OUT_A); scalars += SCALAR_OUT_B; scalars += SCALAR_OUT_CHI2; return scalars; } QStringList LineFitSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void LineFitSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString LineFitPlugin::pluginName() const { return "Line Fit"; } QString LineFitPlugin::pluginDescription() const { return "Generates a line of best fit for a set of data."; } Kst::DataObject *LineFitPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetLineFitPlugin* config = static_cast(configWidget)) { LineFitSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *LineFitPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetLineFitPlugin *widget = new ConfigWidgetLineFitPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, LineFitPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/linefit/kstplugin_linefit.desktop000644 001750 001750 00000000400 11544160207 026012 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=linefit X-Kst-Plugin-Author=The University of Toronto Name=Line Fit Data Object Plugin Comment=Implements a Line Fit Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/linefit/linefit.pro000644 001750 001750 00000000232 11544160207 023044 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_linefit) SOURCES += \ linefit.cpp HEADERS += \ linefit.h FORMS += linefitconfig.ui kst-2.0.3/src/plugins/dataobject/syncbin/syncbin.cpp000644 001750 001750 00000032666 11544160207 023074 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* bin Y values into N bins from X min to X max, according to their X values. This is like a 1D map, where X specifices the pixel the data go into. */ #include "syncbin.h" #include "objectstore.h" #include "ui_syncbinconfig.h" // macros to find the top, bottom, and middle of a bin #define BINMID(x) XMin+(XMax-XMin)*(double(x)+0.5)/double(nbins) #define BIN( x ) int(double(nbins)*(x-XMin)/(XMax-XMin)) static const QString& VECTOR_IN_X = "Vector In X"; static const QString& VECTOR_IN_Y = "Vector In Y"; static const QString& SCALAR_IN_BINS = "Number of Bins"; static const QString& SCALAR_IN_XMIN = "X Min"; static const QString& SCALAR_IN_XMAX = "X Max"; static const QString& VECTOR_OUT_X_OUT = "X out"; static const QString& VECTOR_OUT_Y_OUT = "Y out"; static const QString& VECTOR_OUT_Y_ERROR = "Y error"; static const QString& VECTOR_OUT_N = "N"; class ConfigSyncBinPlugin : public Kst::DataObjectConfigWidget, public Ui_SyncBinConfig { public: ConfigSyncBinPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_SyncBinConfig() { setupUi(this); } ~ConfigSyncBinPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _scalarBins->setObjectStore(store); _scalarXMin->setObjectStore(store); _scalarXMax->setObjectStore(store); _scalarBins->setDefaultValue(0); _scalarXMin->setDefaultValue(0); _scalarXMax->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarBins, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarXMin, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarXMax, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarBins() { return _scalarBins->selectedScalar(); }; void setSelectedScalarBins(Kst::ScalarPtr scalar) { return _scalarBins->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarXMin() { return _scalarXMin->selectedScalar(); }; void setSelectedScalarXMin(Kst::ScalarPtr scalar) { return _scalarXMin->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarXMax() { return _scalarXMax->selectedScalar(); }; void setSelectedScalarXMax(Kst::ScalarPtr scalar) { return _scalarXMax->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (SyncBinSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedScalarBins(source->scalarBins()); setSelectedScalarXMin(source->scalarXMin()); setSelectedScalarXMax(source->scalarXMax()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("SyncBin DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Scalar Number of Bins", _scalarBins->selectedScalar()->Name()); _cfg->setValue("Input Scalar X Min", _scalarXMin->selectedScalar()->Name()); _cfg->setValue("Input Scalar X Max", _scalarXMax->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("SyncBin DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorX = static_cast(object); if (vectorX) { setSelectedVectorX(vectorX); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorY = static_cast(object); if (vectorY) { setSelectedVectorY(vectorY); } QString scalarName = _cfg->value("Input Scalar Number of Bins").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarBins = static_cast(object); if (scalarBins) { setSelectedScalarBins(scalarBins); } scalarName = _cfg->value("Input Scalar X Min").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarXMin = static_cast(object); if (scalarXMin) { setSelectedScalarXMin(scalarXMin); } scalarName = _cfg->value("Input Scalar X Max").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarXMax = static_cast(object); if (scalarXMax) { setSelectedScalarXMax(scalarXMax); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; SyncBinSource::SyncBinSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } SyncBinSource::~SyncBinSource() { } QString SyncBinSource::_automaticDescriptiveName() const { return QString("SyncBin Plugin Object"); } void SyncBinSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigSyncBinPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputScalar(SCALAR_IN_BINS, config->selectedScalarBins()); setInputScalar(SCALAR_IN_XMIN, config->selectedScalarXMin()); setInputScalar(SCALAR_IN_XMAX, config->selectedScalarXMax()); } } void SyncBinSource::setupOutputs() { setOutputVector(VECTOR_OUT_X_OUT, ""); setOutputVector(VECTOR_OUT_Y_OUT, ""); setOutputVector(VECTOR_OUT_Y_ERROR, ""); setOutputVector(VECTOR_OUT_N, ""); } bool SyncBinSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::ScalarPtr inputScalarBins = _inputScalars[SCALAR_IN_BINS]; Kst::ScalarPtr inputScalarXMin = _inputScalars[SCALAR_IN_XMIN]; Kst::ScalarPtr inputScalarXMax = _inputScalars[SCALAR_IN_XMAX]; Kst::VectorPtr outputVectorX = _outputVectors[VECTOR_OUT_X_OUT]; Kst::VectorPtr outputVectorY = _outputVectors[VECTOR_OUT_Y_OUT]; Kst::VectorPtr outputVectorYError = _outputVectors[VECTOR_OUT_Y_ERROR]; Kst::VectorPtr outputVectorN = _outputVectors[VECTOR_OUT_N]; int nbins = int( inputScalarBins->value() ); int n_in; double XMin = inputScalarXMin->value(); double XMax = inputScalarXMax->value(); double *Xout, *Yout, *Yerr, *N; //Make sure there is at least 1 element in the input vector if (inputVectorX->length() < 1) { _errorString = "Error: Input Vector X invalid size"; return false; } if (inputVectorX->length() != inputVectorY->length()) { _errorString = "Error: Input Vector lengths do not match"; return false; } if (nbins < 2) { _errorString = "Error: Bins must be at least 2"; return false; } //resize the output arrays outputVectorX->resize(nbins, true); outputVectorY->resize(nbins, true); outputVectorYError->resize(nbins, true); outputVectorN->resize(nbins, true); // convenience definitions n_in = int( inputVectorX->length() ); const double *Xin = inputVectorX->value(); const double *Yin = inputVectorY->value(); Xout = outputVectorX->value(); Yout = outputVectorY->value(); Yerr = outputVectorYError->value(); N = outputVectorN->value(); // set/check XMax and XMin if ( XMax <= XMin ) { // autobin XMax = XMin = Xin[0]; for (int i=1; iXin[i] ) XMax = Xin[i]; if ( XMin0) { last_sY/=last_N; if ( (last_bin>=0) && (last_bin0) { last_sY/=last_N; if ( (last_bin>=0) && (last_bin0 ) { Yerr[i] = sqrt( Yerr[i] - Yout[i]*Yout[i]/N[i] )/N[i]; Yout[i]/=N[i]; } } return true; } Kst::VectorPtr SyncBinSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr SyncBinSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::ScalarPtr SyncBinSource::scalarBins() const { return _inputScalars[SCALAR_IN_BINS]; } Kst::ScalarPtr SyncBinSource::scalarXMin() const { return _inputScalars[SCALAR_IN_XMIN]; } Kst::ScalarPtr SyncBinSource::scalarXMax() const { return _inputScalars[SCALAR_IN_XMAX]; } QStringList SyncBinSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; return vectors; } QStringList SyncBinSource::inputScalarList() const { QStringList scalars(SCALAR_IN_BINS); scalars += SCALAR_IN_XMIN; scalars += SCALAR_IN_XMAX; return scalars; } QStringList SyncBinSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList SyncBinSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_X_OUT); vectors += VECTOR_OUT_Y_OUT; vectors += VECTOR_OUT_Y_ERROR; vectors += VECTOR_OUT_N; return vectors; } QStringList SyncBinSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList SyncBinSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void SyncBinSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString SyncBinPlugin::pluginName() const { return "SyncBin"; } QString SyncBinPlugin::pluginDescription() const { return "Synchronously coadd vector Y into inputScalarBins defined by vector X. Like a 1D map."; } Kst::DataObject *SyncBinPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigSyncBinPlugin* config = static_cast(configWidget)) { SyncBinSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputScalar(SCALAR_IN_BINS, config->selectedScalarBins()); object->setInputScalar(SCALAR_IN_XMIN, config->selectedScalarXMin()); object->setInputScalar(SCALAR_IN_XMAX, config->selectedScalarXMax()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *SyncBinPlugin::configWidget(QSettings *settingsObject) const { ConfigSyncBinPlugin *widget = new ConfigSyncBinPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, SyncBinPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/syncbin/syncbinconfig.ui000644 001750 001750 00000014071 11544160207 024103 0ustar00synthsynth000000 000000 SyncBinConfig 0 0 438 209 400 0 0 0 Input Vector X false Qt::Horizontal 40 20 0 0 0 0 Input Vector Y false Qt::Horizontal 40 20 0 0 0 0 Number of Bins false Qt::Horizontal 40 20 0 0 X Min false Qt::Horizontal 40 20 0 0 X Max false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/syncbin/syncbin.h000644 001750 001750 00000005246 11544160207 022533 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SYNCBINPLUGIN_H #define SYNCBINPLUGIN_H #include #include #include class SyncBinSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::ScalarPtr scalarBins() const; Kst::ScalarPtr scalarXMin() const; Kst::ScalarPtr scalarXMax() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: SyncBinSource(Kst::ObjectStore *store); ~SyncBinSource(); friend class Kst::ObjectStore; }; class SyncBinPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~SyncBinPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/syncbin/syncbin.pro000644 001750 001750 00000000232 11544160207 023072 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_syncbin) SOURCES += \ syncbin.cpp HEADERS += \ syncbin.h FORMS += syncbinconfig.ui kst-2.0.3/src/plugins/dataobject/syncbin/kstplugin_syncbin.desktop000644 001750 001750 00000000400 11544160207 026040 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=syncbin X-Kst-Plugin-Author=The University of Toronto Name=Sync Bin Data Object Plugin Comment=Implements a Sync Bin Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/noiseaddition/kstplugin_noiseaddition.desktop000644 001750 001750 00000000422 11544160207 030414 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=noiseaddition X-Kst-Plugin-Author=The University of Toronto Name=Noise Addition Data Object Plugin Comment=Implements a Noise Addition Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/noiseaddition/noiseadditionconfig.ui000644 001750 001750 00000005720 11544160207 026454 0ustar00synthsynth000000 000000 NoiseAdditionConfig 0 0 419 97 400 0 0 0 Input Vector false Qt::Horizontal 40 20 0 0 0 0 Sigma false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/noiseaddition/noiseaddition.pro000644 001750 001750 00000000312 11544160207 025441 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_noiseaddition) LIBS += -l$$kstlib(gsl) SOURCES += \ noiseaddition.cpp HEADERS += \ noiseaddition.h FORMS += noiseadditionconfig.ui kst-2.0.3/src/plugins/dataobject/noiseaddition/noiseaddition.cpp000644 001750 001750 00000017337 11544160207 025442 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "noiseaddition.h" #include "objectstore.h" #include "ui_noiseadditionconfig.h" #include #include static const QString& VECTOR_IN = "Vector In"; static const QString& SCALAR_IN = "Scalar In"; static const QString& VECTOR_OUT = "Vector Out"; class ConfigNoiseAdditionPlugin : public Kst::DataObjectConfigWidget, public Ui_NoiseAdditionConfig { public: ConfigNoiseAdditionPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_NoiseAdditionConfig() { setupUi(this); } ~ConfigNoiseAdditionPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); _scalarSigma->setObjectStore(store); _scalarSigma->setDefaultValue(0); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarSigma, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalar() { return _scalarSigma->selectedScalar(); }; void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarSigma->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (NoiseAdditionSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); setSelectedScalar(source->scalarSigma()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Noise Addition DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->setValue("Input Scalar Sigma", _scalarSigma->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Noise Addition DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } QString scalarName = _cfg->value("Input Scalar Sigma").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalar = static_cast(object); if (scalar) { setSelectedScalar(scalar); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; NoiseAdditionSource::NoiseAdditionSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } NoiseAdditionSource::~NoiseAdditionSource() { } QString NoiseAdditionSource::_automaticDescriptiveName() const { return QString("Noise Addition Plugin Object"); } void NoiseAdditionSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigNoiseAdditionPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); setInputScalar(SCALAR_IN, config->selectedScalar()); } } void NoiseAdditionSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool NoiseAdditionSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; //Make sure there is at least 1 element in the input vector if (inputVector->length() < 1) { _errorString = "Error: Input Vector invalid size"; return false; } const gsl_rng_type* pGeneratorType; gsl_rng* pRandomNumberGenerator; double* pResult[1]; int iRetVal = false; int iLength = inputVector->length(); outputVector->resize(iLength, false); pResult[0] = outputVector->value(); pGeneratorType = gsl_rng_default; pRandomNumberGenerator = gsl_rng_alloc( pGeneratorType ); if (pRandomNumberGenerator != NULL) { if (pResult[0] != NULL) { for (int i=0; ivalue()[i] = inputVector->value()[i] + gsl_ran_gaussian( pRandomNumberGenerator, inputScalar->value() ); } iRetVal = true; } gsl_rng_free( pRandomNumberGenerator ); } return true; } Kst::VectorPtr NoiseAdditionSource::vector() const { return _inputVectors[VECTOR_IN]; } Kst::ScalarPtr NoiseAdditionSource::scalarSigma() const { return _inputScalars[SCALAR_IN]; } QStringList NoiseAdditionSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList NoiseAdditionSource::inputScalarList() const { return QStringList( SCALAR_IN ); } QStringList NoiseAdditionSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList NoiseAdditionSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList NoiseAdditionSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList NoiseAdditionSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void NoiseAdditionSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString NoiseAdditionPlugin::pluginName() const { return "Noise Addition"; } QString NoiseAdditionPlugin::pluginDescription() const { return "Adds Gaussian noise to a set of data, of a specified standard deviation."; } Kst::DataObject *NoiseAdditionPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigNoiseAdditionPlugin* config = static_cast(configWidget)) { NoiseAdditionSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); object->setInputScalar(SCALAR_IN, config->selectedScalar()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *NoiseAdditionPlugin::configWidget(QSettings *settingsObject) const { ConfigNoiseAdditionPlugin *widget = new ConfigNoiseAdditionPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, NoiseAdditionPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/noiseaddition/noiseaddition.h000644 001750 001750 00000005136 11544160207 025101 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef NOISEADDITIONPLUGIN_H #define NOISEADDITIONPLUGIN_H #include #include #include class NoiseAdditionSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; Kst::ScalarPtr scalarSigma() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: NoiseAdditionSource(Kst::ObjectStore *store); ~NoiseAdditionSource(); friend class Kst::ObjectStore; }; class NoiseAdditionPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~NoiseAdditionPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/akimaperiodic/akimaperiodic.pro000644 001750 001750 00000000321 11544160207 030433 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_akimaperiodic) LIBS += -l$$kstlib(gsl) SOURCES += \ akimaperiodic.cpp HEADERS += \ akimaperiodic.h FORMS += akimaperiodicconfig.ui kst-2.0.3/src/plugins/dataobject/interpolations/akimaperiodic/akimaperiodicconfig.ui000644 001750 001750 00000006441 11544160207 031447 0ustar00synthsynth000000 000000 AkimaPeriodicConfig 0 0 424 110 400 0 0 0 Input Vector X false 0 0 0 0 Input Vector Y false 0 0 0 0 Input Vector X' false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/interpolations/akimaperiodic/akimaperiodic.h000644 001750 001750 00000005200 11544160207 030063 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef AKIMAPERIODICPLUGIN_H #define AKIMAPERIODICPLUGIN_H #include #include #include class AkimaPeriodicSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorX1() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: AkimaPeriodicSource(Kst::ObjectStore *store); ~AkimaPeriodicSource(); friend class Kst::ObjectStore; }; class AkimaPeriodicPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~AkimaPeriodicPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/akimaperiodic/akimaperiodic.cpp000644 001750 001750 00000020303 11544160207 030417 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "akimaperiodic.h" #include "objectstore.h" #include "ui_akimaperiodicconfig.h" #include #include "../interpolations.h" static const QString& VECTOR_IN_X = "Vector X In"; static const QString& VECTOR_IN_Y = "Vector Y In"; static const QString& VECTOR_IN_X1 = "Vector X' In"; static const QString& VECTOR_OUT = "Y Interpolated"; class ConfigWidgetAkimaPeriodicPlugin : public Kst::DataObjectConfigWidget, public Ui_AkimaPeriodicConfig { public: ConfigWidgetAkimaPeriodicPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_AkimaPeriodicConfig() { setupUi(this); } ~ConfigWidgetAkimaPeriodicPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorX1->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorX1, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorX1() { return _vectorX1->selectedVector(); }; void setSelectedVectorX1(Kst::VectorPtr vector) { return _vectorX1->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (AkimaPeriodicSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorX1(source->vectorX1()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Interpolation Akima Periodic DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector X1", _vectorX1->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Interpolation Akima Periodic DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorX(vector); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object); if (vector2) { setSelectedVectorY(vector2); } vectorName = _cfg->value("Input Vector X'").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorX1 = static_cast(object); if (vectorX1) { setSelectedVectorX1(vectorX1); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; AkimaPeriodicSource::AkimaPeriodicSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } AkimaPeriodicSource::~AkimaPeriodicSource() { } QString AkimaPeriodicSource::_automaticDescriptiveName() const { return QString("Interpolation Akima Periodic Plugin Object"); } void AkimaPeriodicSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetAkimaPeriodicPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } } void AkimaPeriodicSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool AkimaPeriodicSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorX1 = _inputVectors[VECTOR_IN_X1]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; return interpolate( inputVectorX, inputVectorY, inputVectorX1, outputVector, gsl_interp_akima_periodic); } Kst::VectorPtr AkimaPeriodicSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr AkimaPeriodicSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr AkimaPeriodicSource::vectorX1() const { return _inputVectors[VECTOR_IN_X1]; } QStringList AkimaPeriodicSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_X1; return vectors; } QStringList AkimaPeriodicSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList AkimaPeriodicSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList AkimaPeriodicSource::outputVectorList() const { return QStringList(VECTOR_OUT); } QStringList AkimaPeriodicSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList AkimaPeriodicSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void AkimaPeriodicSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString AkimaPeriodicPlugin::pluginName() const { return "Interpolation Akima Periodic Spline"; } QString AkimaPeriodicPlugin::pluginDescription() const { return "Generates a non-rounded periodic Akima interpolation for a set of data."; } Kst::DataObject *AkimaPeriodicPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetAkimaPeriodicPlugin* config = static_cast(configWidget)) { AkimaPeriodicSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *AkimaPeriodicPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetAkimaPeriodicPlugin *widget = new ConfigWidgetAkimaPeriodicPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, AkimaPeriodicPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/akimaperiodic/kstplugin_akimaperiodic.desktop000644 001750 001750 00000000456 11544160207 033415 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=akimaperiodic X-Kst-Plugin-Author=The University of Toronto Name=Akima Periodic Interpolation Data Object Plugin Comment=Implements a Akima Periodic Interpolation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/interpolations/linear/linearconfig.ui000644 001750 001750 00000006423 11544160207 026571 0ustar00synthsynth000000 000000 LinearConfig 0 0 421 113 400 0 0 0 Input Vector X false 0 0 0 0 Input Vector Y false 0 0 0 0 Input Vector X' false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/interpolations/linear/linear.cpp000644 001750 001750 00000017557 11544160207 025562 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "linear.h" #include "objectstore.h" #include "ui_linearconfig.h" #include #include "../interpolations.h" static const QString& VECTOR_IN_X = "Vector X In"; static const QString& VECTOR_IN_Y = "Vector Y In"; static const QString& VECTOR_IN_X1 = "Vector X' In"; static const QString& VECTOR_OUT = "Y Interpolated"; class ConfigWidgetLinearPlugin : public Kst::DataObjectConfigWidget, public Ui_LinearConfig { public: ConfigWidgetLinearPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_LinearConfig() { setupUi(this); } ~ConfigWidgetLinearPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorX1->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorX1, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorX1() { return _vectorX1->selectedVector(); }; void setSelectedVectorX1(Kst::VectorPtr vector) { return _vectorX1->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (LinearSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorX1(source->vectorX1()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Interpolation Linear DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector X1", _vectorX1->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Interpolation Linear DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorX(vector); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object); if (vector2) { setSelectedVectorY(vector2); } vectorName = _cfg->value("Input Vector X'").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorX1 = static_cast(object); if (vectorX1) { setSelectedVectorX1(vectorX1); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; LinearSource::LinearSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } LinearSource::~LinearSource() { } QString LinearSource::_automaticDescriptiveName() const { return QString("Interpolation Linear Plugin Object"); } void LinearSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetLinearPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } } void LinearSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool LinearSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorX1 = _inputVectors[VECTOR_IN_X1]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; return interpolate( inputVectorX, inputVectorY, inputVectorX1, outputVector, gsl_interp_linear); } Kst::VectorPtr LinearSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr LinearSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr LinearSource::vectorX1() const { return _inputVectors[VECTOR_IN_X1]; } QStringList LinearSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_X1; return vectors; } QStringList LinearSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList LinearSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList LinearSource::outputVectorList() const { return QStringList(VECTOR_OUT); } QStringList LinearSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList LinearSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void LinearSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString LinearPlugin::pluginName() const { return "Interpolation Linear Spline"; } QString LinearPlugin::pluginDescription() const { return "Generates a linear interpolation for a set of data."; } Kst::DataObject *LinearPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetLinearPlugin* config = static_cast(configWidget)) { LinearSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *LinearPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetLinearPlugin *widget = new ConfigWidgetLinearPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, LinearPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/linear/kstplugin_linear.desktop000644 001750 001750 00000000444 11544160207 030534 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=linearinterpolation X-Kst-Plugin-Author=The University of Toronto Name=Linear Interpolation Data Object Plugin Comment=Implements a Linear Interpolation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/interpolations/linear/linear.h000644 001750 001750 00000005117 11544160207 025214 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LINEARPLUGIN_H #define LINEARPLUGIN_H #include #include #include class LinearSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorX1() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: LinearSource(Kst::ObjectStore *store); ~LinearSource(); friend class Kst::ObjectStore; }; class LinearPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~LinearPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/linear/linear.pro000644 001750 001750 00000000301 11544160207 025553 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_linearinterpolation) LIBS += -l$$kstlib(gsl) SOURCES += \ linear.cpp HEADERS += \ linear.h FORMS += linearconfig.ui kst-2.0.3/src/plugins/dataobject/interpolations/interpolations.pro000644 001750 001750 00000000224 11544160207 026105 0ustar00synthsynth000000 000000 TEMPLATE = subdirs CONFIG += ordered SUBDIRS += \ akima \ akimaperiodic \ cspline \ csplineperiodic \ linear \ polynomial kst-2.0.3/src/plugins/dataobject/interpolations/akima/akima.pro000644 001750 001750 00000000260 11544160207 025177 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_akima) LIBS += -l$$kstlib(gsl) SOURCES += \ akima.cpp HEADERS += \ akima.h FORMS += akimaconfig.ui kst-2.0.3/src/plugins/dataobject/interpolations/akima/akima.h000644 001750 001750 00000005110 11544160207 024625 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef AKIMAPLUGIN_H #define AKIMAPLUGIN_H #include #include #include class AkimaSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorX1() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: AkimaSource(Kst::ObjectStore *store); ~AkimaSource(); friend class Kst::ObjectStore; }; class AkimaPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~AkimaPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/akima/kstplugin_akima.desktop000644 001750 001750 00000000424 11544160207 030152 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=akima X-Kst-Plugin-Author=The University of Toronto Name=Akima Interpolation Data Object Plugin Comment=Implements a Akima Interpolation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/interpolations/akima/akimaconfig.ui000644 001750 001750 00000006421 11544160207 026207 0ustar00synthsynth000000 000000 AkimaConfig 0 0 422 127 400 0 0 0 Input Vector X false 0 0 0 0 Input Vector Y false 0 0 0 0 Input Vector X' false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/interpolations/akima/akima.cpp000644 001750 001750 00000017515 11544160207 025174 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "akima.h" #include "objectstore.h" #include "ui_akimaconfig.h" #include #include "../interpolations.h" static const QString& VECTOR_IN_X = "Vector X In"; static const QString& VECTOR_IN_Y = "Vector Y In"; static const QString& VECTOR_IN_X1 = "Vector X' In"; static const QString& VECTOR_OUT = "Y Interpolated"; class ConfigWidgetAkimaPlugin : public Kst::DataObjectConfigWidget, public Ui_AkimaConfig { public: ConfigWidgetAkimaPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_AkimaConfig() { setupUi(this); } ~ConfigWidgetAkimaPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorX1->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorX1, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorX1() { return _vectorX1->selectedVector(); }; void setSelectedVectorX1(Kst::VectorPtr vector) { return _vectorX1->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (AkimaSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorX1(source->vectorX1()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Interpolation Akima DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector X1", _vectorX1->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Interpolation Akima DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorX(vector); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object); if (vector2) { setSelectedVectorY(vector2); } vectorName = _cfg->value("Input Vector X'").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorX1 = static_cast(object); if (vectorX1) { setSelectedVectorX1(vectorX1); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; AkimaSource::AkimaSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } AkimaSource::~AkimaSource() { } QString AkimaSource::_automaticDescriptiveName() const { return QString("Interpolation Akima Plugin Object"); } void AkimaSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetAkimaPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } } void AkimaSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool AkimaSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorX1 = _inputVectors[VECTOR_IN_X1]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; return interpolate( inputVectorX, inputVectorY, inputVectorX1, outputVector, gsl_interp_akima); } Kst::VectorPtr AkimaSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr AkimaSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr AkimaSource::vectorX1() const { return _inputVectors[VECTOR_IN_X1]; } QStringList AkimaSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_X1; return vectors; } QStringList AkimaSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList AkimaSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList AkimaSource::outputVectorList() const { return QStringList(VECTOR_OUT); } QStringList AkimaSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList AkimaSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void AkimaSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString AkimaPlugin::pluginName() const { return "Interpolation Akima Spline"; } QString AkimaPlugin::pluginDescription() const { return "Generates a non-rounded Akima interpolation for a set of data."; } Kst::DataObject *AkimaPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetAkimaPlugin* config = static_cast(configWidget)) { AkimaSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *AkimaPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetAkimaPlugin *widget = new ConfigWidgetAkimaPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, AkimaPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/cspline/cspline.pro000644 001750 001750 00000000270 11544160207 026126 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_cspline) LIBS += -l$$kstlib(gsl) SOURCES += \ cspline.cpp HEADERS += \ cspline.h FORMS += csplineconfig.ui kst-2.0.3/src/plugins/dataobject/interpolations/cspline/kstplugin_akima.desktop000644 001750 001750 00000000432 11544160207 030524 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=cspline X-Kst-Plugin-Author=The University of Toronto Name=CSpline Interpolation Data Object Plugin Comment=Implements a CSpline Interpolation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/interpolations/cspline/cspline.cpp000644 001750 001750 00000020110 11544160207 026103 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "cspline.h" #include "objectstore.h" #include "ui_csplineconfig.h" #include #include "../interpolations.h" static const QString& VECTOR_IN_X = "Vector X In"; static const QString& VECTOR_IN_Y = "Vector Y In"; static const QString& VECTOR_IN_X1 = "Vector X' In"; static const QString& VECTOR_OUT = "Y Interpolated"; class ConfigWidgetCubicSplinePlugin : public Kst::DataObjectConfigWidget, public Ui_CubicSplineConfig { public: ConfigWidgetCubicSplinePlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_CubicSplineConfig() { setupUi(this); } ~ConfigWidgetCubicSplinePlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorX1->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorX1, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorX1() { return _vectorX1->selectedVector(); }; void setSelectedVectorX1(Kst::VectorPtr vector) { return _vectorX1->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (CubicSplineSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorX1(source->vectorX1()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Interpolation Cubic Spline DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector X1", _vectorX1->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Interpolation Cubic Spline DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorX(vector); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object); if (vector2) { setSelectedVectorY(vector2); } vectorName = _cfg->value("Input Vector X'").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorX1 = static_cast(object); if (vectorX1) { setSelectedVectorX1(vectorX1); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; CubicSplineSource::CubicSplineSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } CubicSplineSource::~CubicSplineSource() { } QString CubicSplineSource::_automaticDescriptiveName() const { return QString("Interpolation Cubic Spline Plugin Object"); } void CubicSplineSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetCubicSplinePlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } } void CubicSplineSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool CubicSplineSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorX1 = _inputVectors[VECTOR_IN_X1]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; return interpolate( inputVectorX, inputVectorY, inputVectorX1, outputVector, gsl_interp_cspline); } Kst::VectorPtr CubicSplineSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr CubicSplineSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr CubicSplineSource::vectorX1() const { return _inputVectors[VECTOR_IN_X1]; } QStringList CubicSplineSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_X1; return vectors; } QStringList CubicSplineSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList CubicSplineSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList CubicSplineSource::outputVectorList() const { return QStringList(VECTOR_OUT); } QStringList CubicSplineSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList CubicSplineSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void CubicSplineSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString CubicSplinePlugin::pluginName() const { return "Interpolation Cubic Spline Spline"; } QString CubicSplinePlugin::pluginDescription() const { return "Generates a spline interpolation for a set of data."; } Kst::DataObject *CubicSplinePlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetCubicSplinePlugin* config = static_cast(configWidget)) { CubicSplineSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *CubicSplinePlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetCubicSplinePlugin *widget = new ConfigWidgetCubicSplinePlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, CubicSplinePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/cspline/csplineconfig.ui000644 001750 001750 00000006435 11544160207 027142 0ustar00synthsynth000000 000000 CubicSplineConfig 0 0 423 125 400 0 0 0 Input Vector X false 0 0 0 0 Input Vector Y false 0 0 0 0 Input Vector X' false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/interpolations/cspline/cspline.h000644 001750 001750 00000005162 11544160207 025562 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CUBICSPLINEPLUGIN_H #define CUBICSPLINEPLUGIN_H #include #include #include class CubicSplineSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorX1() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: CubicSplineSource(Kst::ObjectStore *store); ~CubicSplineSource(); friend class Kst::ObjectStore; }; class CubicSplinePlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~CubicSplinePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/interpolations.h000644 001750 001750 00000005550 11544160207 025543 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include bool interpolate(Kst::VectorPtr xVector, Kst::VectorPtr yVector, Kst::VectorPtr x1Vector, Kst::VectorPtr yOutVector, const gsl_interp_type* pType) { gsl_interp_accel *pAccel = NULL; gsl_interp *pInterp = NULL; gsl_spline *pSpline = NULL; int iLengthData; int iLengthInterp; bool bReturn = false; double* pResult[1]; iLengthData = xVector->length(); if (yVector->length() < iLengthData) { iLengthData = yVector->length(); } iLengthInterp = x1Vector->length(); if (iLengthInterp > 0) { if (yOutVector->length() != iLengthInterp) { yOutVector->resize(iLengthInterp, true); pResult[0] = (double*)realloc( yOutVector->value(), iLengthInterp * sizeof( double ) ); } else { pResult[0] = yOutVector->value(); } if (pResult[0] != NULL) { for (int i = 0; i < iLengthInterp; ++i) { yOutVector->value()[i] = pResult[0][i]; } pInterp = gsl_interp_alloc( pType, iLengthData ); if (pInterp != NULL) { // // check that we have enough data points... // if ((unsigned int)iLengthData > gsl_interp_min_size( pInterp )) { pAccel = gsl_interp_accel_alloc( ); if (pAccel != NULL) { pSpline = gsl_spline_alloc( pType, iLengthData ); if (pSpline != NULL) { if (!gsl_spline_init( pSpline, xVector->value(), yVector->value(), iLengthData )) { for( int i=0; ivalue()[i] = gsl_spline_eval( pSpline, x1Vector->value()[i], pAccel ); } bReturn = true; } gsl_spline_free( pSpline ); } gsl_interp_accel_free( pAccel ); } } gsl_interp_free( pInterp ); } } } return bReturn; } kst-2.0.3/src/plugins/dataobject/interpolations/csplineperiodic/csplineperiodic.h000644 001750 001750 00000005252 11544160207 031020 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CUBICSPLINEPERIODICPLUGIN_H #define CUBICSPLINEPERIODICPLUGIN_H #include #include #include class CubicSplinePeriodicSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorX1() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: CubicSplinePeriodicSource(Kst::ObjectStore *store); ~CubicSplinePeriodicSource(); friend class Kst::ObjectStore; }; class CubicSplinePeriodicPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~CubicSplinePeriodicPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/csplineperiodic/csplineperiodic.cpp000644 001750 001750 00000020673 11544160207 031357 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "csplineperiodic.h" #include "objectstore.h" #include "ui_csplineperiodicconfig.h" #include #include "../interpolations.h" static const QString& VECTOR_IN_X = "Vector X In"; static const QString& VECTOR_IN_Y = "Vector Y In"; static const QString& VECTOR_IN_X1 = "Vector X' In"; static const QString& VECTOR_OUT = "Y Interpolated"; class ConfigWidgetCubicSplinePeriodicPlugin : public Kst::DataObjectConfigWidget, public Ui_CubicSplinePeriodicConfig { public: ConfigWidgetCubicSplinePeriodicPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_CubicSplinePeriodicConfig() { setupUi(this); } ~ConfigWidgetCubicSplinePeriodicPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorX1->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorX1, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorX1() { return _vectorX1->selectedVector(); }; void setSelectedVectorX1(Kst::VectorPtr vector) { return _vectorX1->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (CubicSplinePeriodicSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorX1(source->vectorX1()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Interpolation Cubic Spline Periodic DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector X1", _vectorX1->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Interpolation Cubic Spline Periodic DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorX(vector); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object); if (vector2) { setSelectedVectorY(vector2); } vectorName = _cfg->value("Input Vector X'").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorX1 = static_cast(object); if (vectorX1) { setSelectedVectorX1(vectorX1); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; CubicSplinePeriodicSource::CubicSplinePeriodicSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } CubicSplinePeriodicSource::~CubicSplinePeriodicSource() { } QString CubicSplinePeriodicSource::_automaticDescriptiveName() const { return QString("Interpolation Cubic Spline Periodic Plugin Object"); } void CubicSplinePeriodicSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetCubicSplinePeriodicPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } } void CubicSplinePeriodicSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool CubicSplinePeriodicSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorX1 = _inputVectors[VECTOR_IN_X1]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; return interpolate( inputVectorX, inputVectorY, inputVectorX1, outputVector, gsl_interp_cspline_periodic); } Kst::VectorPtr CubicSplinePeriodicSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr CubicSplinePeriodicSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr CubicSplinePeriodicSource::vectorX1() const { return _inputVectors[VECTOR_IN_X1]; } QStringList CubicSplinePeriodicSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_X1; return vectors; } QStringList CubicSplinePeriodicSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList CubicSplinePeriodicSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList CubicSplinePeriodicSource::outputVectorList() const { return QStringList(VECTOR_OUT); } QStringList CubicSplinePeriodicSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList CubicSplinePeriodicSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void CubicSplinePeriodicSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString CubicSplinePeriodicPlugin::pluginName() const { return "Interpolation Cubic Spline Periodic Spline"; } QString CubicSplinePeriodicPlugin::pluginDescription() const { return "Generates a cubic spline interpolation for a set of data."; } Kst::DataObject *CubicSplinePeriodicPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetCubicSplinePeriodicPlugin* config = static_cast(configWidget)) { CubicSplinePeriodicSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *CubicSplinePeriodicPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetCubicSplinePeriodicPlugin *widget = new ConfigWidgetCubicSplinePeriodicPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, CubicSplinePeriodicPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/csplineperiodic/kstplugin_csplineperiodic.desktop000644 001750 001750 00000000476 11544160207 034345 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=csplineperiodic X-Kst-Plugin-Author=The University of Toronto Name=Cubic Spline Periodic Interpolation Data Object Plugin Comment=Implements a Cubic Spline Periodic Interpolation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/interpolations/csplineperiodic/csplineperiodic.pro000644 001750 001750 00000000330 11544160207 031361 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_csplineperiodic) LIBS += -l$$kstlib(gsl) SOURCES += \ csplineperiodic.cpp HEADERS += \ csplineperiodic.h FORMS += csplineperiodicconfig.ui kst-2.0.3/src/plugins/dataobject/interpolations/csplineperiodic/csplineperiodicconfig.ui000644 001750 001750 00000006455 11544160207 032402 0ustar00synthsynth000000 000000 CubicSplinePeriodicConfig 0 0 422 126 400 0 0 0 Input Vector X false 0 0 0 0 Input Vector Y false 0 0 0 0 Input Vector X' false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/interpolations/polynomial/kstplugin_polynomial.desktop000644 001750 001750 00000000460 11544160207 032354 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=polynomialinterpolation X-Kst-Plugin-Author=The University of Toronto Name=Polynomial Interpolation Data Object Plugin Comment=Implements a Polynomial Interpolation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/interpolations/polynomial/polynomial.h000644 001750 001750 00000005153 11544160207 027036 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef POLYNOMIALPLUGIN_H #define POLYNOMIALPLUGIN_H #include #include #include class PolynomialSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorX() const; Kst::VectorPtr vectorY() const; Kst::VectorPtr vectorX1() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: PolynomialSource(Kst::ObjectStore *store); ~PolynomialSource(); friend class Kst::ObjectStore; }; class PolynomialPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~PolynomialPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/polynomial/polynomial.pro000644 001750 001750 00000000321 11544160207 027377 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_polynomialinterpolation) LIBS += -l$$kstlib(gsl) SOURCES += \ polynomial.cpp HEADERS += \ polynomial.h FORMS += polynomialconfig.ui kst-2.0.3/src/plugins/dataobject/interpolations/polynomial/polynomial.cpp000644 001750 001750 00000020047 11544160207 027370 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "polynomial.h" #include "objectstore.h" #include "ui_polynomialconfig.h" #include #include "../interpolations.h" static const QString& VECTOR_IN_X = "Vector X In"; static const QString& VECTOR_IN_Y = "Vector Y In"; static const QString& VECTOR_IN_X1 = "Vector X' In"; static const QString& VECTOR_OUT = "Y Interpolated"; class ConfigWidgetPolynomialPlugin : public Kst::DataObjectConfigWidget, public Ui_PolynomialConfig { public: ConfigWidgetPolynomialPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_PolynomialConfig() { setupUi(this); } ~ConfigWidgetPolynomialPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorX->setObjectStore(store); _vectorY->setObjectStore(store); _vectorX1->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorX1, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorX1() { return _vectorX1->selectedVector(); }; void setSelectedVectorX1(Kst::VectorPtr vector) { return _vectorX1->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (PolynomialSource* source = static_cast(dataObject)) { setSelectedVectorX(source->vectorX()); setSelectedVectorY(source->vectorY()); setSelectedVectorX1(source->vectorX1()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Interpolation Polynomial DataObject Plugin"); _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); _cfg->setValue("Input Vector X1", _vectorX1->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Interpolation Polynomial DataObject Plugin"); QString vectorName = _cfg->value("Input Vector X").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorX(vector); } vectorName = _cfg->value("Input Vector Y").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object); if (vector2) { setSelectedVectorY(vector2); } vectorName = _cfg->value("Input Vector X'").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorX1 = static_cast(object); if (vectorX1) { setSelectedVectorX1(vectorX1); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; PolynomialSource::PolynomialSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } PolynomialSource::~PolynomialSource() { } QString PolynomialSource::_automaticDescriptiveName() const { return QString("Interpolation Polynomial Plugin Object"); } void PolynomialSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetPolynomialPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_X, config->selectedVectorX()); setInputVector(VECTOR_IN_Y, config->selectedVectorY()); setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } } void PolynomialSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool PolynomialSource::algorithm() { Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; Kst::VectorPtr inputVectorX1 = _inputVectors[VECTOR_IN_X1]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; return interpolate( inputVectorX, inputVectorY, inputVectorX1, outputVector, gsl_interp_polynomial); } Kst::VectorPtr PolynomialSource::vectorX() const { return _inputVectors[VECTOR_IN_X]; } Kst::VectorPtr PolynomialSource::vectorY() const { return _inputVectors[VECTOR_IN_Y]; } Kst::VectorPtr PolynomialSource::vectorX1() const { return _inputVectors[VECTOR_IN_X1]; } QStringList PolynomialSource::inputVectorList() const { QStringList vectors(VECTOR_IN_X); vectors += VECTOR_IN_Y; vectors += VECTOR_IN_X1; return vectors; } QStringList PolynomialSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList PolynomialSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList PolynomialSource::outputVectorList() const { return QStringList(VECTOR_OUT); } QStringList PolynomialSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList PolynomialSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void PolynomialSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString PolynomialPlugin::pluginName() const { return "Interpolation Polynomial Spline"; } QString PolynomialPlugin::pluginDescription() const { return "Generates a polynomial interpolation for a set of data."; } Kst::DataObject *PolynomialPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetPolynomialPlugin* config = static_cast(configWidget)) { PolynomialSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); object->setInputVector(VECTOR_IN_X1, config->selectedVectorX1()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *PolynomialPlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetPolynomialPlugin *widget = new ConfigWidgetPolynomialPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, PolynomialPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/interpolations/polynomial/polynomialconfig.ui000644 001750 001750 00000006433 11544160207 030414 0ustar00synthsynth000000 000000 PolynomialConfig 0 0 419 121 400 0 0 0 Input Vector X false 0 0 0 0 Input Vector Y false 0 0 0 0 Input Vector X' false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/crossspectrum/crossspectrum.pro000644 001750 001750 00000000302 11544160207 025606 0ustar00synthsynth000000 000000 include(../../plugins_sub.pri) TARGET = $$kstlib(kstplugin_crossspectrum) SOURCES += \ fftsg_h.c \ crossspectrum.cpp HEADERS += \ crossspectrum.h FORMS += crossspectrumconfig.ui kst-2.0.3/src/plugins/dataobject/crossspectrum/crossspectrumconfig.ui000644 001750 001750 00000012200 11544160207 026611 0ustar00synthsynth000000 000000 CrossSpectrumConfig 0 0 425 148 400 0 0 0 Input Vector One false Qt::Horizontal 40 20 0 0 0 0 Input Vector Two false Qt::Horizontal 40 20 0 0 0 0 FFT Length = 2^: false Qt::Horizontal 40 20 0 0 Sample Rate false Qt::Horizontal 40 20 Kst::VectorSelector QWidget
    vectorselector.h
    Kst::ScalarSelector QWidget
    scalarselector.h
    kst-2.0.3/src/plugins/dataobject/crossspectrum/crossspectrum.cpp000644 001750 001750 00000031416 11544160207 025602 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "crossspectrum.h" #include "objectstore.h" #include "ui_crossspectrumconfig.h" static const QString& VECTOR_IN_ONE = "Vector In One"; static const QString& VECTOR_IN_TWO = "Vector In Two"; static const QString& SCALAR_IN_FFT = "Scalar In FFT"; static const QString& SCALAR_IN_RATE = "Scalar In Sample Rate"; static const QString& VECTOR_OUT_FREQ = "Frequency"; static const QString& VECTOR_OUT_IMAG = "Imaginary"; static const QString& VECTOR_OUT_REAL = "Real"; class ConfigCrossSpectrumPlugin : public Kst::DataObjectConfigWidget, public Ui_CrossSpectrumConfig { public: ConfigCrossSpectrumPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_CrossSpectrumConfig() { setupUi(this); } ~ConfigCrossSpectrumPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorOne->setObjectStore(store); _vectorTwo->setObjectStore(store); _scalarFFT->setObjectStore(store); _scalarRate->setObjectStore(store); _scalarFFT->setDefaultValue(10); _scalarRate->setDefaultValue(100); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorOne, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorTwo, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarFFT, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_scalarRate, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorOne() { return _vectorOne->selectedVector(); }; void setSelectedVectorOne(Kst::VectorPtr vector) { return _vectorOne->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorTwo() { return _vectorTwo->selectedVector(); }; void setSelectedVectorTwo(Kst::VectorPtr vector) { return _vectorTwo->setSelectedVector(vector); }; Kst::ScalarPtr selectedScalarFFT() { return _scalarFFT->selectedScalar(); }; void setSelectedScalarFFT(Kst::ScalarPtr scalar) { return _scalarFFT->setSelectedScalar(scalar); }; Kst::ScalarPtr selectedScalarRate() { return _scalarRate->selectedScalar(); }; void setSelectedScalarRate(Kst::ScalarPtr scalar) { return _scalarRate->setSelectedScalar(scalar); }; virtual void setupFromObject(Kst::Object* dataObject) { if (CrossSpectrumSource* source = static_cast(dataObject)) { setSelectedVectorOne(source->vectorOne()); setSelectedVectorTwo(source->vectorTwo()); setSelectedScalarFFT(source->scalarFFT()); setSelectedScalarRate(source->scalarRate()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Cross Spectrum DataObject Plugin"); _cfg->setValue("Input Vector One", _vectorOne->selectedVector()->Name()); _cfg->setValue("Input Vector Two", _vectorTwo->selectedVector()->Name()); _cfg->setValue("Input Scalar FFT", _scalarFFT->selectedScalar()->Name()); _cfg->setValue("Input Scalar Sample Rate", _scalarRate->selectedScalar()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Cross Spectrum DataObject Plugin"); QString vectorName = _cfg->value("Input Vector One").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vectorOne = static_cast(object); if (vectorOne) { setSelectedVectorOne(vectorOne); } vectorName = _cfg->value("Input Vector Two").toString(); object = _store->retrieveObject(vectorName); Kst::Vector* vectorTwo = static_cast(object); if (vectorTwo) { setSelectedVectorTwo(vectorTwo); } QString scalarName = _cfg->value("Input Scalar FFT").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarFFT = static_cast(object); if (scalarFFT) { setSelectedScalarFFT(scalarFFT); } scalarName = _cfg->value("Input Scalar Sample Rate").toString(); object = _store->retrieveObject(scalarName); Kst::Scalar* scalarRate = static_cast(object); if (scalarRate) { setSelectedScalarRate(scalarRate); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; CrossSpectrumSource::CrossSpectrumSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } CrossSpectrumSource::~CrossSpectrumSource() { } QString CrossSpectrumSource::_automaticDescriptiveName() const { return QString("Cross Spectrum Plugin Object"); } void CrossSpectrumSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigCrossSpectrumPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_ONE, config->selectedVectorOne()); setInputVector(VECTOR_IN_TWO, config->selectedVectorTwo()); setInputScalar(SCALAR_IN_FFT, config->selectedScalarFFT()); setInputScalar(SCALAR_IN_RATE, config->selectedScalarRate()); } } void CrossSpectrumSource::setupOutputs() { setOutputVector(VECTOR_OUT_FREQ, ""); setOutputVector(VECTOR_OUT_IMAG, ""); setOutputVector(VECTOR_OUT_REAL, ""); } #define KSTPSDMAXLEN 27 extern "C" void rdft(int n, int isgn, double *a); //fast fourier transform... bool CrossSpectrumSource::algorithm() { Kst::VectorPtr inputVectorOne = _inputVectors[VECTOR_IN_ONE]; Kst::VectorPtr inputVectorTwo = _inputVectors[VECTOR_IN_TWO]; Kst::ScalarPtr inputScalarFFT = _inputScalars[SCALAR_IN_FFT]; Kst::ScalarPtr inputScalarRate = _inputScalars[SCALAR_IN_RATE]; Kst::VectorPtr outputVectorFrequency = _outputVectors[VECTOR_OUT_FREQ]; Kst::VectorPtr outputVectorImaginary = _outputVectors[VECTOR_OUT_IMAG]; Kst::VectorPtr outputVectorReal = _outputVectors[VECTOR_OUT_REAL]; double SR = inputScalarRate->value(); // sample rate double df; int i, xps_len; double *a, *b; double mean_a, mean_b; int dv0, dv1, v_len; int i_subset, n_subsets; int i_samp, copyLen; double norm_factor; /* parse fft length */ xps_len = int( inputScalarRate->value() - 0.99); if ( xps_len > KSTPSDMAXLEN ) { xps_len = KSTPSDMAXLEN; } if ( xps_len<2 ) { xps_len = 2; } xps_len = int ( pow( 2.0, xps_len ) ); /* input vector lengths */ v_len = ( ( inputVectorOne->length() < inputVectorTwo->length() ) ? inputVectorOne->length() : inputVectorTwo->length() ); dv0 = v_len/inputVectorOne->length(); dv1 = v_len/inputVectorTwo->length(); while ( xps_len > v_len ) { xps_len/=2; } // allocate the lengths outputVectorReal->resize( xps_len, false ); outputVectorImaginary->resize( xps_len, false ); outputVectorFrequency->resize( xps_len, false ); /* Fill the frequency and zero the xps */ df = SR/( 2.0*double( xps_len-1 ) ); for ( i=0; ivalue()[i] = double( i ) * df; outputVectorReal->value()[i] = 0.0; outputVectorImaginary->value()[i] = 0.0; } /* allocate input arrays */ int ALen = xps_len * 2; a = new double[ALen]; b = new double[ALen]; /* do the fft's */ n_subsets = v_len/xps_len + 1; for ( i_subset=0; i_subsetvalue()[i] ); i = ( i_samp + i_subset*xps_len )/dv1; mean_b += ( b[i_samp] = inputVectorTwo->value()[i] ); } if (copyLen>1) { mean_a/=(double)copyLen; mean_b/=(double)copyLen; } /* Remove Mean and apodize */ for (i_samp=0; i_sampvalue()[0] += ( a[0]*b[0] ); outputVectorReal->value()[xps_len-1] += ( a[1]*b[1] ); for (i_samp=1; i_sampvalue()[i_samp]+= ( a[i_samp*2] * b[i_samp*2] - a[i_samp*2+1] * b[i_samp*2+1] ); outputVectorImaginary->value()[i_samp]+= ( -a[i_samp*2] * b[i_samp*2+1] + a[i_samp*2+1] * b[i_samp*2] ); }// (a+ci)(b+di)* = ab+cd +i(-ad + cb) } /* renormalize */ norm_factor = 1.0/((double(SR)*double(xps_len))*double(n_subsets)); for ( i=0; ivalue()[i]*=norm_factor; outputVectorImaginary->value()[i]*=norm_factor; } delete[] b; delete[] a; return true; } Kst::VectorPtr CrossSpectrumSource::vectorOne() const { return _inputVectors[VECTOR_IN_ONE]; } Kst::VectorPtr CrossSpectrumSource::vectorTwo() const { return _inputVectors[VECTOR_IN_TWO]; } Kst::ScalarPtr CrossSpectrumSource::scalarFFT() const { return _inputScalars[SCALAR_IN_FFT]; } Kst::ScalarPtr CrossSpectrumSource::scalarRate() const { return _inputScalars[SCALAR_IN_RATE]; } QStringList CrossSpectrumSource::inputVectorList() const { QStringList vectors(VECTOR_IN_ONE); vectors += VECTOR_IN_TWO; return vectors; } QStringList CrossSpectrumSource::inputScalarList() const { QStringList scalars(SCALAR_IN_FFT); scalars += SCALAR_IN_RATE; return scalars; } QStringList CrossSpectrumSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList CrossSpectrumSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_FREQ); vectors += VECTOR_OUT_IMAG; vectors += VECTOR_OUT_REAL; return vectors; } QStringList CrossSpectrumSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList CrossSpectrumSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void CrossSpectrumSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString CrossSpectrumPlugin::pluginName() const { return "Cross Spectrum DataObject Plugin"; } QString CrossSpectrumPlugin::pluginDescription() const { return "Generates the cross power spectrum of one vector with another."; } Kst::DataObject *CrossSpectrumPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigCrossSpectrumPlugin* config = static_cast(configWidget)) { CrossSpectrumSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_ONE, config->selectedVectorOne()); object->setInputVector(VECTOR_IN_TWO, config->selectedVectorTwo()); object->setInputScalar(SCALAR_IN_FFT, config->selectedScalarFFT()); object->setInputScalar(SCALAR_IN_RATE, config->selectedScalarRate()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *CrossSpectrumPlugin::configWidget(QSettings *settingsObject) const { ConfigCrossSpectrumPlugin *widget = new ConfigCrossSpectrumPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, CrossSpectrumPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/crossspectrum/fftsg_h.c000644 001750 001750 00000257421 11544160207 023754 0ustar00synthsynth000000 000000 /* Fast Fourier/Cosine/Sine Transform dimension :one data length :power of 2 decimation :frequency radix :split-radix data :inplace table :not use functions cdft: Complex Discrete Fourier Transform rdft: Real Discrete Fourier Transform ddct: Discrete Cosine Transform ddst: Discrete Sine Transform dfct: Cosine Transform of RDFT (Real Symmetric DFT) dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) function prototypes void cdft(int, int, double *); void rdft(int, int, double *); void ddct(int, int, double *); void ddst(int, int, double *); void dfct(int, double *); void dfst(int, double *); macro definitions USE_CDFT_PTHREADS : default=not defined CDFT_THREADS_BEGIN_N : must be >= 512, default=8192 CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536 USE_CDFT_WINTHREADS : default=not defined CDFT_THREADS_BEGIN_N : must be >= 512, default=32768 CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288 -------- Complex DFT (Discrete Fourier Transform) -------- [definition] X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k cdft(2*n, 1, a); cdft(2*n, -1, a); [parameters] 2*n :data length (int) n >= 1, n = power of 2 a[0...2*n-1] :input/output data (double *) input data a[2*j] = Re(x[j]), a[2*j+1] = Im(x[j]), 0<=j RDFT R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0 IRDFT (excluding scale) a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k rdft(n, 1, a); rdft(n, -1, a); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[2*k] = R[k], 0<=k input data a[2*j] = R[j], 0<=j IDCT (excluding scale) C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k DCT C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k ddct(n, 1, a); ddct(n, -1, a); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[k] = C[k], 0<=k IDST (excluding scale) S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k DST S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0 ddst(n, 1, a); ddst(n, -1, a); [parameters] n :data length (int) n >= 2, n = power of 2 a[0...n-1] :input/output data (double *) input data a[j] = A[j], 0 output data a[k] = S[k], 0= 2, n = power of 2 a[0...n] :input/output data (double *) output data a[k] = C[k], 0<=k<=n [remark] Inverse of a[0] *= 0.5; a[n] *= 0.5; dfct(n, a); is a[0] *= 0.5; a[n] *= 0.5; dfct(n, a); for (j = 0; j <= n; j++) { a[j] *= 2.0 / n; } . -------- Sine Transform of RDFT (Real Anti-symmetric DFT) -------- [definition] S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0= 2, n = power of 2 a[0...n-1] :input/output data (double *) output data a[k] = S[k], 0= 0) { cftfsub(n, a); } else { cftbsub(n, a); } } void rdft(int n, int isgn, double *a) { double xi; if (isgn >= 0) { if (n > 4) { cftfsub(n, a); rftfsub(n, a); } else if (n == 4) { cftfsub(n, a); } xi = a[0] - a[1]; a[0] += a[1]; a[1] = xi; } else { a[1] = 0.5 * (a[0] - a[1]); a[0] -= a[1]; if (n > 4) { rftbsub(n, a); cftbsub(n, a); } else if (n == 4) { cftbsub(n, a); } } } static void ddct(int n, int isgn, double *a) { int j; double xr; if (isgn < 0) { xr = a[n - 1]; for (j = n - 2; j >= 2; j -= 2) { a[j + 1] = a[j] - a[j - 1]; a[j] += a[j - 1]; } a[1] = a[0] - xr; a[0] += xr; if (n > 4) { rftbsub(n, a); cftbsub(n, a); } else if (n == 4) { cftbsub(n, a); } } if (n > 4) { dctsub(n, a); } else { dctsub4(n, a); } if (isgn >= 0) { if (n > 4) { cftfsub(n, a); rftfsub(n, a); } else if (n == 4) { cftfsub(n, a); } xr = a[0] - a[1]; a[0] += a[1]; for (j = 2; j < n; j += 2) { a[j - 1] = a[j] - a[j + 1]; a[j] += a[j + 1]; } a[n - 1] = xr; } } static void ddst(int n, int isgn, double *a) { int j; double xr; if (isgn < 0) { xr = a[n - 1]; for (j = n - 2; j >= 2; j -= 2) { a[j + 1] = -a[j] - a[j - 1]; a[j] -= a[j - 1]; } a[1] = a[0] + xr; a[0] -= xr; if (n > 4) { rftbsub(n, a); cftbsub(n, a); } else if (n == 4) { cftbsub(n, a); } } if (n > 4) { dstsub(n, a); } else { dstsub4(n, a); } if (isgn >= 0) { if (n > 4) { cftfsub(n, a); rftfsub(n, a); } else if (n == 4) { cftfsub(n, a); } xr = a[0] - a[1]; a[0] += a[1]; for (j = 2; j < n; j += 2) { a[j - 1] = -a[j] - a[j + 1]; a[j] -= a[j + 1]; } a[n - 1] = -xr; } } void dfct(int n, double *a) { int j, k, m, mh; double xr, xi, yr, yi, an; m = n >> 1; for (j = 0; j < m; j++) { k = n - j; xr = a[j] + a[k]; a[j] -= a[k]; a[k] = xr; } an = a[n]; while (m >= 2) { ddct(m, 1, a); if (m > 2) { bitrv1(m, a); } mh = m >> 1; xi = a[m]; a[m] = a[0]; a[0] = an - xi; an += xi; for (j = 1; j < mh; j++) { k = m - j; xr = a[m + k]; xi = a[m + j]; yr = a[j]; yi = a[k]; a[m + j] = yr; a[m + k] = yi; a[j] = xr - xi; a[k] = xr + xi; } xr = a[mh]; a[mh] = a[m + mh]; a[m + mh] = xr; m = mh; } xi = a[1]; a[1] = a[0]; a[0] = an + xi; a[n] = an - xi; if (n > 2) { bitrv1(n, a); } } void dfst(int n, double *a) { int j, k, m, mh; double xr, xi, yr, yi; m = n >> 1; for (j = 1; j < m; j++) { k = n - j; xr = a[j] - a[k]; a[j] += a[k]; a[k] = xr; } a[0] = a[m]; while (m >= 2) { ddst(m, 1, a); if (m > 2) { bitrv1(m, a); } mh = m >> 1; for (j = 1; j < mh; j++) { k = m - j; xr = a[m + k]; xi = a[m + j]; yr = a[j]; yi = a[k]; a[m + j] = yr; a[m + k] = yi; a[j] = xr + xi; a[k] = xr - xi; } a[m] = a[0]; a[0] = a[m + mh]; a[m + mh] = a[mh]; m = mh; } a[1] = a[0]; a[0] = 0; if (n > 2) { bitrv1(n, a); } } /* -------- child routines -------- */ #include #ifndef M_PI_2 #define M_PI_2 1.570796326794896619231321691639751442098584699687 #endif #ifndef WR5000 /* cos(M_PI_2*0.5000) */ #define WR5000 0.707106781186547524400844362104849039284835937688 #endif #ifndef WR2500 /* cos(M_PI_2*0.2500) */ #define WR2500 0.923879532511286756128183189396788286822416625863 #endif #ifndef WI2500 /* sin(M_PI_2*0.2500) */ #define WI2500 0.382683432365089771728459984030398866761344562485 #endif #ifndef WR1250 /* cos(M_PI_2*0.1250) */ #define WR1250 0.980785280403230449126182236134239036973933730893 #endif #ifndef WI1250 /* sin(M_PI_2*0.1250) */ #define WI1250 0.195090322016128267848284868477022240927691617751 #endif #ifndef WR3750 /* cos(M_PI_2*0.3750) */ #define WR3750 0.831469612302545237078788377617905756738560811987 #endif #ifndef WI3750 /* sin(M_PI_2*0.3750) */ #define WI3750 0.555570233019602224742830813948532874374937190754 #endif #ifdef USE_CDFT_PTHREADS #define USE_CDFT_THREADS #ifndef CDFT_THREADS_BEGIN_N #define CDFT_THREADS_BEGIN_N 8192 #endif #ifndef CDFT_4THREADS_BEGIN_N #define CDFT_4THREADS_BEGIN_N 65536 #endif #include #include #include #define cdft_thread_t pthread_t #define cdft_thread_create(thp,func,argp) { \ if (pthread_create(thp, NULL, func, (void *) argp) != 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #define cdft_thread_wait(th) { \ if (pthread_join(th, NULL) != 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #endif /* USE_CDFT_PTHREADS */ #ifdef USE_CDFT_WINTHREADS #define USE_CDFT_THREADS #ifndef CDFT_THREADS_BEGIN_N #define CDFT_THREADS_BEGIN_N 32768 #endif #ifndef CDFT_4THREADS_BEGIN_N #define CDFT_4THREADS_BEGIN_N 524288 #endif #include #include #include #define cdft_thread_t HANDLE #define cdft_thread_create(thp,func,argp) { \ DWORD thid; \ *(thp) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, (LPVOID) argp, 0, &thid); \ if (*(thp) == 0) { \ fprintf(stderr, "cdft thread error\n"); \ exit(1); \ } \ } #define cdft_thread_wait(th) { \ WaitForSingleObject(th, INFINITE); \ CloseHandle(th); \ } #endif /* USE_CDFT_WINTHREADS */ #ifndef CDFT_LOOP_DIV /* control of the CDFT's speed & tolerance */ #define CDFT_LOOP_DIV 32 #endif #ifndef RDFT_LOOP_DIV /* control of the RDFT's speed & tolerance */ #define RDFT_LOOP_DIV 64 #endif #ifndef DCST_LOOP_DIV /* control of the DCT,DST's speed & tolerance */ #define DCST_LOOP_DIV 64 #endif static void cftfsub(int n, double *a) { if (n > 8) { if (n > 32) { cftmdl1(n, a); #ifdef USE_CDFT_THREADS if (n > CDFT_THREADS_BEGIN_N) { cftrec4_th(n, a); } else #endif /* USE_CDFT_THREADS */ if (n > 512) { cftrec4(n, a); } else if (n > 128) { cftleaf(n, 1, a); } else { cftfx41(n, a); } bitrv2(n, a); } else if (n == 32) { cftf161(a); bitrv216(a); } else { cftf081(a); bitrv208(a); } } else if (n == 8) { cftf040(a); } else if (n == 4) { cftx020(a); } } static void cftbsub(int n, double *a) { if (n > 8) { if (n > 32) { cftb1st(n, a); #ifdef USE_CDFT_THREADS if (n > CDFT_THREADS_BEGIN_N) { cftrec4_th(n, a); } else #endif /* USE_CDFT_THREADS */ if (n > 512) { cftrec4(n, a); } else if (n > 128) { cftleaf(n, 1, a); } else { cftfx41(n, a); } bitrv2conj(n, a); } else if (n == 32) { cftf161(a); bitrv216neg(a); } else { cftf081(a); bitrv208neg(a); } } else if (n == 8) { cftb040(a); } else if (n == 4) { cftx020(a); } } void bitrv2(int n, double *a) { int _j0, k0, _j1, k1, l, m, i, j, k, nh; double xr, xi, yr, yi; m = 4; for (l = n >> 2; l > 8; l >>= 2) { m <<= 1; } nh = n >> 1; if (l == 8) { _j0 = 0; for (k0 = 0; k0 < m; k0 += 4) { k = k0; for (j = _j0; j < _j0 + k0; j += 4) { xr = a[j]; xi = a[j + 1]; yr = a[k]; yi = a[k + 1]; a[j] = yr; a[j + 1] = yi; a[k] = xr; a[k + 1] = xi; _j1 = j + m; k1 = k + 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh; k1 += 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 += m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += 2; k1 += nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh; k1 -= 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 += m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 2; k1 += nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= 2; k1 -= nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh + 2; k1 += nh + 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh - m; k1 += 2 * m - 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); } } else { _j0 = 0; for (k0 = 0; k0 < m; k0 += 4) { k = k0; for (j = _j0; j < _j0 + k0; j += 4) { xr = a[j]; xi = a[j + 1]; yr = a[k]; yi = a[k + 1]; a[j] = yr; a[j + 1] = yi; a[k] = xr; a[k + 1] = xi; _j1 = j + m; k1 = k + m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh; k1 += 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += 2; k1 += nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh; k1 -= 2; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 2; k1 += nh; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += m; xr = a[_j1]; xi = a[_j1 + 1]; yr = a[k1]; yi = a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); } } } void bitrv2conj(int n, double *a) { int _j0, k0, _j1, k1, l, m, i, j, k, nh; double xr, xi, yr, yi; m = 4; for (l = n >> 2; l > 8; l >>= 2) { m <<= 1; } nh = n >> 1; if (l == 8) { _j0 = 0; for (k0 = 0; k0 < m; k0 += 4) { k = k0; for (j = _j0; j < _j0 + k0; j += 4) { xr = a[j]; xi = -a[j + 1]; yr = a[k]; yi = -a[k + 1]; a[j] = yr; a[j + 1] = yi; a[k] = xr; a[k + 1] = xi; _j1 = j + m; k1 = k + 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh; k1 += 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 += m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += 2; k1 += nh; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh; k1 -= 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 += m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 2; k1 += nh; a[_j1 - 1] = -a[_j1 - 1]; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; _j1 += m; k1 += 2 * m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= 2; k1 -= nh; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh + 2; k1 += nh + 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh - m; k1 += 2 * m - 2; a[_j1 - 1] = -a[_j1 - 1]; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); } } else { _j0 = 0; for (k0 = 0; k0 < m; k0 += 4) { k = k0; for (j = _j0; j < _j0 + k0; j += 4) { xr = a[j]; xi = -a[j + 1]; yr = a[k]; yi = -a[k + 1]; a[j] = yr; a[j + 1] = yi; a[k] = xr; a[k + 1] = xi; _j1 = j + m; k1 = k + m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += nh; k1 += 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += 2; k1 += nh; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 += m; k1 += m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= nh; k1 -= 2; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; _j1 -= m; k1 -= m; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 2; k1 += nh; a[_j1 - 1] = -a[_j1 - 1]; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; _j1 += m; k1 += m; a[_j1 - 1] = -a[_j1 - 1]; xr = a[_j1]; xi = -a[_j1 + 1]; yr = a[k1]; yi = -a[k1 + 1]; a[_j1] = yr; a[_j1 + 1] = yi; a[k1] = xr; a[k1 + 1] = xi; a[k1 + 3] = -a[k1 + 3]; for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); } } } void bitrv216(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x7r = a[14]; x7i = a[15]; x8r = a[16]; x8i = a[17]; x10r = a[20]; x10i = a[21]; x11r = a[22]; x11i = a[23]; x12r = a[24]; x12i = a[25]; x13r = a[26]; x13i = a[27]; x14r = a[28]; x14i = a[29]; a[2] = x8r; a[3] = x8i; a[4] = x4r; a[5] = x4i; a[6] = x12r; a[7] = x12i; a[8] = x2r; a[9] = x2i; a[10] = x10r; a[11] = x10i; a[14] = x14r; a[15] = x14i; a[16] = x1r; a[17] = x1i; a[20] = x5r; a[21] = x5i; a[22] = x13r; a[23] = x13i; a[24] = x3r; a[25] = x3i; a[26] = x11r; a[27] = x11i; a[28] = x7r; a[29] = x7i; } void bitrv216neg(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x6r = a[12]; x6i = a[13]; x7r = a[14]; x7i = a[15]; x8r = a[16]; x8i = a[17]; x9r = a[18]; x9i = a[19]; x10r = a[20]; x10i = a[21]; x11r = a[22]; x11i = a[23]; x12r = a[24]; x12i = a[25]; x13r = a[26]; x13i = a[27]; x14r = a[28]; x14i = a[29]; x15r = a[30]; x15i = a[31]; a[2] = x15r; a[3] = x15i; a[4] = x7r; a[5] = x7i; a[6] = x11r; a[7] = x11i; a[8] = x3r; a[9] = x3i; a[10] = x13r; a[11] = x13i; a[12] = x5r; a[13] = x5i; a[14] = x9r; a[15] = x9i; a[16] = x1r; a[17] = x1i; a[18] = x14r; a[19] = x14i; a[20] = x6r; a[21] = x6i; a[22] = x10r; a[23] = x10i; a[24] = x2r; a[25] = x2i; a[26] = x12r; a[27] = x12i; a[28] = x4r; a[29] = x4i; a[30] = x8r; a[31] = x8i; } void bitrv208(double *a) { double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i; x1r = a[2]; x1i = a[3]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x6r = a[12]; x6i = a[13]; a[2] = x4r; a[3] = x4i; a[6] = x6r; a[7] = x6i; a[8] = x1r; a[9] = x1i; a[12] = x3r; a[13] = x3i; } void bitrv208neg(double *a) { double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i; x1r = a[2]; x1i = a[3]; x2r = a[4]; x2i = a[5]; x3r = a[6]; x3i = a[7]; x4r = a[8]; x4i = a[9]; x5r = a[10]; x5i = a[11]; x6r = a[12]; x6i = a[13]; x7r = a[14]; x7i = a[15]; a[2] = x7r; a[3] = x7i; a[4] = x3r; a[5] = x3i; a[6] = x5r; a[7] = x5i; a[8] = x1r; a[9] = x1i; a[10] = x6r; a[11] = x6i; a[12] = x2r; a[13] = x2i; a[14] = x4r; a[15] = x4i; } void bitrv1(int n, double *a) { int _j0, k0, _j1, k1, l, m, i, j, k, nh; double x; nh = n >> 1; x = a[1]; a[1] = a[nh]; a[nh] = x; m = 2; for (l = n >> 2; l > 2; l >>= 2) { m <<= 1; } if (l == 2) { _j1 = m + 1; k1 = m + nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j0 = 0; for (k0 = 2; k0 < m; k0 += 2) { for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); k = k0; for (j = _j0; j < _j0 + k0; j += 2) { x = a[j]; a[j] = a[k]; a[k] = x; _j1 = j + m; k1 = k + m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 += nh; k1++; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 -= m; k1 -= m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1++; k1 += nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 += m; k1 += m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 -= nh; k1--; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 -= m; k1 -= m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 1; k1 += nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 += m; k1 += m; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; } } else { _j0 = 0; for (k0 = 2; k0 < m; k0 += 2) { for (i = nh >> 1; i > (_j0 ^= i); i >>= 1); k = k0; for (j = _j0; j < _j0 + k0; j += 2) { x = a[j]; a[j] = a[k]; a[k] = x; _j1 = j + nh; k1 = k + 1; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1++; k1 += nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; _j1 -= nh; k1--; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; for (i = nh >> 1; i > (k ^= i); i >>= 1); } k1 = _j0 + k0; _j1 = k1 + 1; k1 += nh; x = a[_j1]; a[_j1] = a[k1]; a[k1] = x; } } } void cftb1st(int n, double *a) { int i, i0, j, _j0, _j1, j2, j3, m, mh; double ew, w1r, w1i, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i, ss1, ss3; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; mh = n >> 3; m = 2 * mh; _j1 = m; j2 = _j1 + m; j3 = j2 + m; x0r = a[0] + a[j2]; x0i = -a[1] - a[j2 + 1]; x1r = a[0] - a[j2]; x1i = -a[1] + a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[0] = x0r + x2r; a[1] = x0i - x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i + x2i; a[j2] = x1r + x3i; a[j2 + 1] = x1i + x3r; a[j3] = x1r - x3i; a[j3 + 1] = x1i - x3r; wd1r = 1; wd1i = 0; wd3r = 1; wd3i = 0; ew = M_PI_2 / m; w1r = cos(2 * ew); w1i = sin(2 * ew); wk1r = w1r; wk1i = w1i; ss1 = 2 * w1i; wk3i = 2 * ss1 * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; ss3 = 2 * wk3i; i = 0; for (;;) { i0 = i + 4 * CDFT_LOOP_DIV; if (i0 > mh - 4) { i0 = mh - 4; } for (j = i + 2; j < i0; j += 4) { wd1r -= ss1 * wk1i; wd1i += ss1 * wk1r; wd3r -= ss3 * wk3i; wd3i += ss3 * wk3r; _j1 = j + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[j] + a[j2]; x0i = -a[j + 1] - a[j2 + 1]; x1r = a[j] - a[j2]; x1i = -a[j + 1] + a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i - x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wk1r * x0r - wk1i * x0i; a[j2 + 1] = wk1r * x0i + wk1i * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r + wk3i * x0i; a[j3 + 1] = wk3r * x0i - wk3i * x0r; x0r = a[j + 2] + a[j2 + 2]; x0i = -a[j + 3] - a[j2 + 3]; x1r = a[j + 2] - a[j2 + 2]; x1i = -a[j + 3] + a[j2 + 3]; x2r = a[_j1 + 2] + a[j3 + 2]; x2i = a[_j1 + 3] + a[j3 + 3]; x3r = a[_j1 + 2] - a[j3 + 2]; x3i = a[_j1 + 3] - a[j3 + 3]; a[j + 2] = x0r + x2r; a[j + 3] = x0i - x2i; a[_j1 + 2] = x0r - x2r; a[_j1 + 3] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 + 2] = wd1r * x0r - wd1i * x0i; a[j2 + 3] = wd1r * x0i + wd1i * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 + 2] = wd3r * x0r + wd3i * x0i; a[j3 + 3] = wd3r * x0i - wd3i * x0r; _j0 = m - j; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0] + a[j2]; x0i = -a[_j0 + 1] - a[j2 + 1]; x1r = a[_j0] - a[j2]; x1i = -a[_j0 + 1] + a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[_j0] = x0r + x2r; a[_j0 + 1] = x0i - x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wk1i * x0r - wk1r * x0i; a[j2 + 1] = wk1i * x0i + wk1r * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = wk3i * x0r + wk3r * x0i; a[j3 + 1] = wk3i * x0i - wk3r * x0r; x0r = a[_j0 - 2] + a[j2 - 2]; x0i = -a[_j0 - 1] - a[j2 - 1]; x1r = a[_j0 - 2] - a[j2 - 2]; x1i = -a[_j0 - 1] + a[j2 - 1]; x2r = a[_j1 - 2] + a[j3 - 2]; x2i = a[_j1 - 1] + a[j3 - 1]; x3r = a[_j1 - 2] - a[j3 - 2]; x3i = a[_j1 - 1] - a[j3 - 1]; a[_j0 - 2] = x0r + x2r; a[_j0 - 1] = x0i - x2i; a[_j1 - 2] = x0r - x2r; a[_j1 - 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 - 2] = wd1i * x0r - wd1r * x0i; a[j2 - 1] = wd1i * x0i + wd1r * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 - 2] = wd3i * x0r + wd3r * x0i; a[j3 - 1] = wd3i * x0i - wd3r * x0r; wk1r -= ss1 * wd1i; wk1i += ss1 * wd1r; wk3r -= ss3 * wd3i; wk3i += ss3 * wd3r; } if (i0 == mh - 4) { break; } wd1r = cos(ew * i0); wd1i = sin(ew * i0); wd3i = 4 * wd1i * wd1r; wd3r = wd1r - wd3i * wd1i; wd3i = wd1i - wd3i * wd1r; wk1r = w1r * wd1r - w1i * wd1i; wk1i = w1r * wd1i + w1i * wd1r; wk3i = 4 * wk1i * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; i = i0; } wd1r = WR5000; _j0 = mh; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0 - 2] + a[j2 - 2]; x0i = -a[_j0 - 1] - a[j2 - 1]; x1r = a[_j0 - 2] - a[j2 - 2]; x1i = -a[_j0 - 1] + a[j2 - 1]; x2r = a[_j1 - 2] + a[j3 - 2]; x2i = a[_j1 - 1] + a[j3 - 1]; x3r = a[_j1 - 2] - a[j3 - 2]; x3i = a[_j1 - 1] - a[j3 - 1]; a[_j0 - 2] = x0r + x2r; a[_j0 - 1] = x0i - x2i; a[_j1 - 2] = x0r - x2r; a[_j1 - 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 - 2] = wk1r * x0r - wk1i * x0i; a[j2 - 1] = wk1r * x0i + wk1i * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 - 2] = wk3r * x0r + wk3i * x0i; a[j3 - 1] = wk3r * x0i - wk3i * x0r; x0r = a[_j0] + a[j2]; x0i = -a[_j0 + 1] - a[j2 + 1]; x1r = a[_j0] - a[j2]; x1i = -a[_j0 + 1] + a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[_j0] = x0r + x2r; a[_j0 + 1] = x0i - x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2] = wd1r * (x0r - x0i); a[j2 + 1] = wd1r * (x0i + x0r); x0r = x1r - x3i; x0i = x1i - x3r; a[j3] = -wd1r * (x0r + x0i); a[j3 + 1] = -wd1r * (x0i - x0r); x0r = a[_j0 + 2] + a[j2 + 2]; x0i = -a[_j0 + 3] - a[j2 + 3]; x1r = a[_j0 + 2] - a[j2 + 2]; x1i = -a[_j0 + 3] + a[j2 + 3]; x2r = a[_j1 + 2] + a[j3 + 2]; x2i = a[_j1 + 3] + a[j3 + 3]; x3r = a[_j1 + 2] - a[j3 + 2]; x3i = a[_j1 + 3] - a[j3 + 3]; a[_j0 + 2] = x0r + x2r; a[_j0 + 3] = x0i - x2i; a[_j1 + 2] = x0r - x2r; a[_j1 + 3] = x0i + x2i; x0r = x1r + x3i; x0i = x1i + x3r; a[j2 + 2] = wk1i * x0r - wk1r * x0i; a[j2 + 3] = wk1i * x0i + wk1r * x0r; x0r = x1r - x3i; x0i = x1i - x3r; a[j3 + 2] = wk3i * x0r + wk3r * x0i; a[j3 + 3] = wk3i * x0i - wk3r * x0r; } #ifdef USE_CDFT_THREADS struct cdft_arg_st { int n0; int n; double *a; }; typedef struct cdft_arg_st cdft_arg_t; void cftrec4_th(int n, double *a) { void *cftrec1_th(void *p); void *cftrec2_th(void *p); int i, idiv4, m, nthread; cdft_thread_t th[4]; cdft_arg_t ag[4]; nthread = 2; idiv4 = 0; m = n >> 1; if (n > CDFT_4THREADS_BEGIN_N) { nthread = 4; idiv4 = 1; m >>= 1; } for (i = 0; i < nthread; i++) { ag[i].n0 = n; ag[i].n = m; ag[i].a = &a[i * m]; if (i != idiv4) { cdft_thread_create(&th[i], cftrec1_th, &ag[i]); } else { cdft_thread_create(&th[i], cftrec2_th, &ag[i]); } } for (i = 0; i < nthread; i++) { cdft_thread_wait(th[i]); } } void *cftrec1_th(void *p) { int cfttree(int n, int j, int k, double *a); void cftleaf(int n, int isplt, double *a); void cftmdl1(int n, double *a); int isplt, j, k, m, n, n0; double *a; n0 = ((cdft_arg_t *) p)->n0; n = ((cdft_arg_t *) p)->n; a = ((cdft_arg_t *) p)->a; m = n0; while (m > 512) { m >>= 2; cftmdl1(m, &a[n - m]); } cftleaf(m, 1, &a[n - m]); k = 0; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a); cftleaf(m, isplt, &a[j - m]); } return (void *) 0; } void *cftrec2_th(void *p) { int cfttree(int n, int j, int k, double *a); void cftleaf(int n, int isplt, double *a); void cftmdl2(int n, double *a); int isplt, j, k, m, n, n0; double *a; n0 = ((cdft_arg_t *) p)->n0; n = ((cdft_arg_t *) p)->n; a = ((cdft_arg_t *) p)->a; k = 1; m = n0; while (m > 512) { m >>= 2; k <<= 2; cftmdl2(m, &a[n - m]); } cftleaf(m, 0, &a[n - m]); k >>= 1; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a); cftleaf(m, isplt, &a[j - m]); } return (void *) 0; } #endif /* USE_CDFT_THREADS */ void cftrec4(int n, double *a) { int isplt, j, k, m; m = n; while (m > 512) { m >>= 2; cftmdl1(m, &a[n - m]); } cftleaf(m, 1, &a[n - m]); k = 0; for (j = n - m; j > 0; j -= m) { k++; isplt = cfttree(m, j, k, a); cftleaf(m, isplt, &a[j - m]); } } int cfttree(int n, int j, int k, double *a) { int i, isplt, m; if ((k & 3) != 0) { isplt = k & 1; if (isplt != 0) { cftmdl1(n, &a[j - n]); } else { cftmdl2(n, &a[j - n]); } } else { m = n; for (i = k; (i & 3) == 0; i >>= 2) { m <<= 2; } isplt = i & 1; if (isplt != 0) { while (m > 128) { cftmdl1(m, &a[j - m]); m >>= 2; } } else { while (m > 128) { cftmdl2(m, &a[j - m]); m >>= 2; } } } return isplt; } void cftleaf(int n, int isplt, double *a) { if (n == 512) { cftmdl1(128, a); cftf161(a); cftf162(&a[32]); cftf161(&a[64]); cftf161(&a[96]); cftmdl2(128, &a[128]); cftf161(&a[128]); cftf162(&a[160]); cftf161(&a[192]); cftf162(&a[224]); cftmdl1(128, &a[256]); cftf161(&a[256]); cftf162(&a[288]); cftf161(&a[320]); cftf161(&a[352]); if (isplt != 0) { cftmdl1(128, &a[384]); cftf161(&a[480]); } else { cftmdl2(128, &a[384]); cftf162(&a[480]); } cftf161(&a[384]); cftf162(&a[416]); cftf161(&a[448]); } else { cftmdl1(64, a); cftf081(a); cftf082(&a[16]); cftf081(&a[32]); cftf081(&a[48]); cftmdl2(64, &a[64]); cftf081(&a[64]); cftf082(&a[80]); cftf081(&a[96]); cftf082(&a[112]); cftmdl1(64, &a[128]); cftf081(&a[128]); cftf082(&a[144]); cftf081(&a[160]); cftf081(&a[176]); if (isplt != 0) { cftmdl1(64, &a[192]); cftf081(&a[240]); } else { cftmdl2(64, &a[192]); cftf082(&a[240]); } cftf081(&a[192]); cftf082(&a[208]); cftf081(&a[224]); } } void cftmdl1(int n, double *a) { int i, i0, j, _j0, _j1, j2, j3, m, mh; double ew, w1r, w1i, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i, ss1, ss3; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; mh = n >> 3; m = 2 * mh; _j1 = m; j2 = _j1 + m; j3 = j2 + m; x0r = a[0] + a[j2]; x0i = a[1] + a[j2 + 1]; x1r = a[0] - a[j2]; x1i = a[1] - a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i - x2i; a[j2] = x1r - x3i; a[j2 + 1] = x1i + x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i - x3r; wd1r = 1; wd1i = 0; wd3r = 1; wd3i = 0; ew = M_PI_2 / m; w1r = cos(2 * ew); w1i = sin(2 * ew); wk1r = w1r; wk1i = w1i; ss1 = 2 * w1i; wk3i = 2 * ss1 * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; ss3 = 2 * wk3i; i = 0; for (;;) { i0 = i + 4 * CDFT_LOOP_DIV; if (i0 > mh - 4) { i0 = mh - 4; } for (j = i + 2; j < i0; j += 4) { wd1r -= ss1 * wk1i; wd1i += ss1 * wk1r; wd3r -= ss3 * wk3i; wd3i += ss3 * wk3r; _j1 = j + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[j] + a[j2]; x0i = a[j + 1] + a[j2 + 1]; x1r = a[j] - a[j2]; x1i = a[j + 1] - a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wk1r * x0r - wk1i * x0i; a[j2 + 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r + wk3i * x0i; a[j3 + 1] = wk3r * x0i - wk3i * x0r; x0r = a[j + 2] + a[j2 + 2]; x0i = a[j + 3] + a[j2 + 3]; x1r = a[j + 2] - a[j2 + 2]; x1i = a[j + 3] - a[j2 + 3]; x2r = a[_j1 + 2] + a[j3 + 2]; x2i = a[_j1 + 3] + a[j3 + 3]; x3r = a[_j1 + 2] - a[j3 + 2]; x3i = a[_j1 + 3] - a[j3 + 3]; a[j + 2] = x0r + x2r; a[j + 3] = x0i + x2i; a[_j1 + 2] = x0r - x2r; a[_j1 + 3] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 + 2] = wd1r * x0r - wd1i * x0i; a[j2 + 3] = wd1r * x0i + wd1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 + 2] = wd3r * x0r + wd3i * x0i; a[j3 + 3] = wd3r * x0i - wd3i * x0r; _j0 = m - j; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0] + a[j2]; x0i = a[_j0 + 1] + a[j2 + 1]; x1r = a[_j0] - a[j2]; x1i = a[_j0 + 1] - a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[_j0] = x0r + x2r; a[_j0 + 1] = x0i + x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wk1i * x0r - wk1r * x0i; a[j2 + 1] = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3i * x0r + wk3r * x0i; a[j3 + 1] = wk3i * x0i - wk3r * x0r; x0r = a[_j0 - 2] + a[j2 - 2]; x0i = a[_j0 - 1] + a[j2 - 1]; x1r = a[_j0 - 2] - a[j2 - 2]; x1i = a[_j0 - 1] - a[j2 - 1]; x2r = a[_j1 - 2] + a[j3 - 2]; x2i = a[_j1 - 1] + a[j3 - 1]; x3r = a[_j1 - 2] - a[j3 - 2]; x3i = a[_j1 - 1] - a[j3 - 1]; a[_j0 - 2] = x0r + x2r; a[_j0 - 1] = x0i + x2i; a[_j1 - 2] = x0r - x2r; a[_j1 - 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 - 2] = wd1i * x0r - wd1r * x0i; a[j2 - 1] = wd1i * x0i + wd1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 - 2] = wd3i * x0r + wd3r * x0i; a[j3 - 1] = wd3i * x0i - wd3r * x0r; wk1r -= ss1 * wd1i; wk1i += ss1 * wd1r; wk3r -= ss3 * wd3i; wk3i += ss3 * wd3r; } if (i0 == mh - 4) { break; } wd1r = cos(ew * i0); wd1i = sin(ew * i0); wd3i = 4 * wd1i * wd1r; wd3r = wd1r - wd3i * wd1i; wd3i = wd1i - wd3i * wd1r; wk1r = w1r * wd1r - w1i * wd1i; wk1i = w1r * wd1i + w1i * wd1r; wk3i = 4 * wk1i * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; i = i0; } wd1r = WR5000; _j0 = mh; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0 - 2] + a[j2 - 2]; x0i = a[_j0 - 1] + a[j2 - 1]; x1r = a[_j0 - 2] - a[j2 - 2]; x1i = a[_j0 - 1] - a[j2 - 1]; x2r = a[_j1 - 2] + a[j3 - 2]; x2i = a[_j1 - 1] + a[j3 - 1]; x3r = a[_j1 - 2] - a[j3 - 2]; x3i = a[_j1 - 1] - a[j3 - 1]; a[_j0 - 2] = x0r + x2r; a[_j0 - 1] = x0i + x2i; a[_j1 - 2] = x0r - x2r; a[_j1 - 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 - 2] = wk1r * x0r - wk1i * x0i; a[j2 - 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 - 2] = wk3r * x0r + wk3i * x0i; a[j3 - 1] = wk3r * x0i - wk3i * x0r; x0r = a[_j0] + a[j2]; x0i = a[_j0 + 1] + a[j2 + 1]; x1r = a[_j0] - a[j2]; x1i = a[_j0 + 1] - a[j2 + 1]; x2r = a[_j1] + a[j3]; x2i = a[_j1 + 1] + a[j3 + 1]; x3r = a[_j1] - a[j3]; x3i = a[_j1 + 1] - a[j3 + 1]; a[_j0] = x0r + x2r; a[_j0 + 1] = x0i + x2i; a[_j1] = x0r - x2r; a[_j1 + 1] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2] = wd1r * (x0r - x0i); a[j2 + 1] = wd1r * (x0i + x0r); x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = -wd1r * (x0r + x0i); a[j3 + 1] = -wd1r * (x0i - x0r); x0r = a[_j0 + 2] + a[j2 + 2]; x0i = a[_j0 + 3] + a[j2 + 3]; x1r = a[_j0 + 2] - a[j2 + 2]; x1i = a[_j0 + 3] - a[j2 + 3]; x2r = a[_j1 + 2] + a[j3 + 2]; x2i = a[_j1 + 3] + a[j3 + 3]; x3r = a[_j1 + 2] - a[j3 + 2]; x3i = a[_j1 + 3] - a[j3 + 3]; a[_j0 + 2] = x0r + x2r; a[_j0 + 3] = x0i + x2i; a[_j1 + 2] = x0r - x2r; a[_j1 + 3] = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; a[j2 + 2] = wk1i * x0r - wk1r * x0i; a[j2 + 3] = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3 + 2] = wk3i * x0r + wk3r * x0i; a[j3 + 3] = wk3i * x0i - wk3r * x0r; } void cftmdl2(int n, double *a) { int i, i0, j, _j0, _j1, j2, j3, m, mh; double ew, w1r, w1i, wn4r, wk1r, wk1i, wk3r, wk3i, wl1r, wl1i, wl3r, wl3i, wd1r, wd1i, wd3r, wd3i, we1r, we1i, we3r, we3i, ss1, ss3; double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i; mh = n >> 3; m = 2 * mh; wn4r = WR5000; _j1 = m; j2 = _j1 + m; j3 = j2 + m; x0r = a[0] - a[j2 + 1]; x0i = a[1] + a[j2]; x1r = a[0] + a[j2 + 1]; x1i = a[1] - a[j2]; x2r = a[_j1] - a[j3 + 1]; x2i = a[_j1 + 1] + a[j3]; x3r = a[_j1] + a[j3 + 1]; x3i = a[_j1 + 1] - a[j3]; y0r = wn4r * (x2r - x2i); y0i = wn4r * (x2i + x2r); a[0] = x0r + y0r; a[1] = x0i + y0i; a[_j1] = x0r - y0r; a[_j1 + 1] = x0i - y0i; y0r = wn4r * (x3r - x3i); y0i = wn4r * (x3i + x3r); a[j2] = x1r - y0i; a[j2 + 1] = x1i + y0r; a[j3] = x1r + y0i; a[j3 + 1] = x1i - y0r; wl1r = 1; wl1i = 0; wl3r = 1; wl3i = 0; we1r = wn4r; we1i = wn4r; we3r = -wn4r; we3i = -wn4r; ew = M_PI_2 / (2 * m); w1r = cos(2 * ew); w1i = sin(2 * ew); wk1r = w1r; wk1i = w1i; wd1r = wn4r * (w1r - w1i); wd1i = wn4r * (w1i + w1r); ss1 = 2 * w1i; wk3i = 2 * ss1 * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; ss3 = 2 * wk3i; wd3r = -wn4r * (wk3r - wk3i); wd3i = -wn4r * (wk3i + wk3r); i = 0; for (;;) { i0 = i + 4 * CDFT_LOOP_DIV; if (i0 > mh - 4) { i0 = mh - 4; } for (j = i + 2; j < i0; j += 4) { wl1r -= ss1 * wk1i; wl1i += ss1 * wk1r; wl3r -= ss3 * wk3i; wl3i += ss3 * wk3r; we1r -= ss1 * wd1i; we1i += ss1 * wd1r; we3r -= ss3 * wd3i; we3i += ss3 * wd3r; _j1 = j + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[j] - a[j2 + 1]; x0i = a[j + 1] + a[j2]; x1r = a[j] + a[j2 + 1]; x1i = a[j + 1] - a[j2]; x2r = a[_j1] - a[j3 + 1]; x2i = a[_j1 + 1] + a[j3]; x3r = a[_j1] + a[j3 + 1]; x3i = a[_j1 + 1] - a[j3]; y0r = wk1r * x0r - wk1i * x0i; y0i = wk1r * x0i + wk1i * x0r; y2r = wd1r * x2r - wd1i * x2i; y2i = wd1r * x2i + wd1i * x2r; a[j] = y0r + y2r; a[j + 1] = y0i + y2i; a[_j1] = y0r - y2r; a[_j1 + 1] = y0i - y2i; y0r = wk3r * x1r + wk3i * x1i; y0i = wk3r * x1i - wk3i * x1r; y2r = wd3r * x3r + wd3i * x3i; y2i = wd3r * x3i - wd3i * x3r; a[j2] = y0r + y2r; a[j2 + 1] = y0i + y2i; a[j3] = y0r - y2r; a[j3 + 1] = y0i - y2i; x0r = a[j + 2] - a[j2 + 3]; x0i = a[j + 3] + a[j2 + 2]; x1r = a[j + 2] + a[j2 + 3]; x1i = a[j + 3] - a[j2 + 2]; x2r = a[_j1 + 2] - a[j3 + 3]; x2i = a[_j1 + 3] + a[j3 + 2]; x3r = a[_j1 + 2] + a[j3 + 3]; x3i = a[_j1 + 3] - a[j3 + 2]; y0r = wl1r * x0r - wl1i * x0i; y0i = wl1r * x0i + wl1i * x0r; y2r = we1r * x2r - we1i * x2i; y2i = we1r * x2i + we1i * x2r; a[j + 2] = y0r + y2r; a[j + 3] = y0i + y2i; a[_j1 + 2] = y0r - y2r; a[_j1 + 3] = y0i - y2i; y0r = wl3r * x1r + wl3i * x1i; y0i = wl3r * x1i - wl3i * x1r; y2r = we3r * x3r + we3i * x3i; y2i = we3r * x3i - we3i * x3r; a[j2 + 2] = y0r + y2r; a[j2 + 3] = y0i + y2i; a[j3 + 2] = y0r - y2r; a[j3 + 3] = y0i - y2i; _j0 = m - j; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0] - a[j2 + 1]; x0i = a[_j0 + 1] + a[j2]; x1r = a[_j0] + a[j2 + 1]; x1i = a[_j0 + 1] - a[j2]; x2r = a[_j1] - a[j3 + 1]; x2i = a[_j1 + 1] + a[j3]; x3r = a[_j1] + a[j3 + 1]; x3i = a[_j1 + 1] - a[j3]; y0r = wd1i * x0r - wd1r * x0i; y0i = wd1i * x0i + wd1r * x0r; y2r = wk1i * x2r - wk1r * x2i; y2i = wk1i * x2i + wk1r * x2r; a[_j0] = y0r + y2r; a[_j0 + 1] = y0i + y2i; a[_j1] = y0r - y2r; a[_j1 + 1] = y0i - y2i; y0r = wd3i * x1r + wd3r * x1i; y0i = wd3i * x1i - wd3r * x1r; y2r = wk3i * x3r + wk3r * x3i; y2i = wk3i * x3i - wk3r * x3r; a[j2] = y0r + y2r; a[j2 + 1] = y0i + y2i; a[j3] = y0r - y2r; a[j3 + 1] = y0i - y2i; x0r = a[_j0 - 2] - a[j2 - 1]; x0i = a[_j0 - 1] + a[j2 - 2]; x1r = a[_j0 - 2] + a[j2 - 1]; x1i = a[_j0 - 1] - a[j2 - 2]; x2r = a[_j1 - 2] - a[j3 - 1]; x2i = a[_j1 - 1] + a[j3 - 2]; x3r = a[_j1 - 2] + a[j3 - 1]; x3i = a[_j1 - 1] - a[j3 - 2]; y0r = we1i * x0r - we1r * x0i; y0i = we1i * x0i + we1r * x0r; y2r = wl1i * x2r - wl1r * x2i; y2i = wl1i * x2i + wl1r * x2r; a[_j0 - 2] = y0r + y2r; a[_j0 - 1] = y0i + y2i; a[_j1 - 2] = y0r - y2r; a[_j1 - 1] = y0i - y2i; y0r = we3i * x1r + we3r * x1i; y0i = we3i * x1i - we3r * x1r; y2r = wl3i * x3r + wl3r * x3i; y2i = wl3i * x3i - wl3r * x3r; a[j2 - 2] = y0r + y2r; a[j2 - 1] = y0i + y2i; a[j3 - 2] = y0r - y2r; a[j3 - 1] = y0i - y2i; wk1r -= ss1 * wl1i; wk1i += ss1 * wl1r; wk3r -= ss3 * wl3i; wk3i += ss3 * wl3r; wd1r -= ss1 * we1i; wd1i += ss1 * we1r; wd3r -= ss3 * we3i; wd3i += ss3 * we3r; } if (i0 == mh - 4) { break; } wl1r = cos(ew * i0); wl1i = sin(ew * i0); wl3i = 4 * wl1i * wl1r; wl3r = wl1r - wl3i * wl1i; wl3i = wl1i - wl3i * wl1r; we1r = wn4r * (wl1r - wl1i); we1i = wn4r * (wl1i + wl1r); we3r = -wn4r * (wl3r - wl3i); we3i = -wn4r * (wl3i + wl3r); wk1r = w1r * wl1r - w1i * wl1i; wk1i = w1r * wl1i + w1i * wl1r; wk3i = 4 * wk1i * wk1r; wk3r = wk1r - wk3i * wk1i; wk3i = wk1i - wk3i * wk1r; wd1r = wn4r * (wk1r - wk1i); wd1i = wn4r * (wk1i + wk1r); wd3r = -wn4r * (wk3r - wk3i); wd3i = -wn4r * (wk3i + wk3r); i = i0; } wl1r = WR2500; wl1i = WI2500; _j0 = mh; _j1 = _j0 + m; j2 = _j1 + m; j3 = j2 + m; x0r = a[_j0 - 2] - a[j2 - 1]; x0i = a[_j0 - 1] + a[j2 - 2]; x1r = a[_j0 - 2] + a[j2 - 1]; x1i = a[_j0 - 1] - a[j2 - 2]; x2r = a[_j1 - 2] - a[j3 - 1]; x2i = a[_j1 - 1] + a[j3 - 2]; x3r = a[_j1 - 2] + a[j3 - 1]; x3i = a[_j1 - 1] - a[j3 - 2]; y0r = wk1r * x0r - wk1i * x0i; y0i = wk1r * x0i + wk1i * x0r; y2r = wd1r * x2r - wd1i * x2i; y2i = wd1r * x2i + wd1i * x2r; a[_j0 - 2] = y0r + y2r; a[_j0 - 1] = y0i + y2i; a[_j1 - 2] = y0r - y2r; a[_j1 - 1] = y0i - y2i; y0r = wk3r * x1r + wk3i * x1i; y0i = wk3r * x1i - wk3i * x1r; y2r = wd3r * x3r + wd3i * x3i; y2i = wd3r * x3i - wd3i * x3r; a[j2 - 2] = y0r + y2r; a[j2 - 1] = y0i + y2i; a[j3 - 2] = y0r - y2r; a[j3 - 1] = y0i - y2i; x0r = a[_j0] - a[j2 + 1]; x0i = a[_j0 + 1] + a[j2]; x1r = a[_j0] + a[j2 + 1]; x1i = a[_j0 + 1] - a[j2]; x2r = a[_j1] - a[j3 + 1]; x2i = a[_j1 + 1] + a[j3]; x3r = a[_j1] + a[j3 + 1]; x3i = a[_j1 + 1] - a[j3]; y0r = wl1r * x0r - wl1i * x0i; y0i = wl1r * x0i + wl1i * x0r; y2r = wl1i * x2r - wl1r * x2i; y2i = wl1i * x2i + wl1r * x2r; a[_j0] = y0r + y2r; a[_j0 + 1] = y0i + y2i; a[_j1] = y0r - y2r; a[_j1 + 1] = y0i - y2i; y0r = wl1i * x1r - wl1r * x1i; y0i = wl1i * x1i + wl1r * x1r; y2r = wl1r * x3r - wl1i * x3i; y2i = wl1r * x3i + wl1i * x3r; a[j2] = y0r - y2r; a[j2 + 1] = y0i - y2i; a[j3] = y0r + y2r; a[j3 + 1] = y0i + y2i; x0r = a[_j0 + 2] - a[j2 + 3]; x0i = a[_j0 + 3] + a[j2 + 2]; x1r = a[_j0 + 2] + a[j2 + 3]; x1i = a[_j0 + 3] - a[j2 + 2]; x2r = a[_j1 + 2] - a[j3 + 3]; x2i = a[_j1 + 3] + a[j3 + 2]; x3r = a[_j1 + 2] + a[j3 + 3]; x3i = a[_j1 + 3] - a[j3 + 2]; y0r = wd1i * x0r - wd1r * x0i; y0i = wd1i * x0i + wd1r * x0r; y2r = wk1i * x2r - wk1r * x2i; y2i = wk1i * x2i + wk1r * x2r; a[_j0 + 2] = y0r + y2r; a[_j0 + 3] = y0i + y2i; a[_j1 + 2] = y0r - y2r; a[_j1 + 3] = y0i - y2i; y0r = wd3i * x1r + wd3r * x1i; y0i = wd3i * x1i - wd3r * x1r; y2r = wk3i * x3r + wk3r * x3i; y2i = wk3i * x3i - wk3r * x3r; a[j2 + 2] = y0r + y2r; a[j2 + 3] = y0i + y2i; a[j3 + 2] = y0r - y2r; a[j3 + 3] = y0i - y2i; } void cftfx41(int n, double *a) { if (n == 128) { cftf161(a); cftf162(&a[32]); cftf161(&a[64]); cftf161(&a[96]); } else { cftf081(a); cftf082(&a[16]); cftf081(&a[32]); cftf081(&a[48]); } } void cftf161(double *a) { double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; wn4r = WR5000; wk1r = WR2500; wk1i = WI2500; x0r = a[0] + a[16]; x0i = a[1] + a[17]; x1r = a[0] - a[16]; x1i = a[1] - a[17]; x2r = a[8] + a[24]; x2i = a[9] + a[25]; x3r = a[8] - a[24]; x3i = a[9] - a[25]; y0r = x0r + x2r; y0i = x0i + x2i; y4r = x0r - x2r; y4i = x0i - x2i; y8r = x1r - x3i; y8i = x1i + x3r; y12r = x1r + x3i; y12i = x1i - x3r; x0r = a[2] + a[18]; x0i = a[3] + a[19]; x1r = a[2] - a[18]; x1i = a[3] - a[19]; x2r = a[10] + a[26]; x2i = a[11] + a[27]; x3r = a[10] - a[26]; x3i = a[11] - a[27]; y1r = x0r + x2r; y1i = x0i + x2i; y5r = x0r - x2r; y5i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y9r = wk1r * x0r - wk1i * x0i; y9i = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; y13r = wk1i * x0r - wk1r * x0i; y13i = wk1i * x0i + wk1r * x0r; x0r = a[4] + a[20]; x0i = a[5] + a[21]; x1r = a[4] - a[20]; x1i = a[5] - a[21]; x2r = a[12] + a[28]; x2i = a[13] + a[29]; x3r = a[12] - a[28]; x3i = a[13] - a[29]; y2r = x0r + x2r; y2i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y10r = wn4r * (x0r - x0i); y10i = wn4r * (x0i + x0r); x0r = x1r + x3i; x0i = x1i - x3r; y14r = wn4r * (x0r + x0i); y14i = wn4r * (x0i - x0r); x0r = a[6] + a[22]; x0i = a[7] + a[23]; x1r = a[6] - a[22]; x1i = a[7] - a[23]; x2r = a[14] + a[30]; x2i = a[15] + a[31]; x3r = a[14] - a[30]; x3i = a[15] - a[31]; y3r = x0r + x2r; y3i = x0i + x2i; y7r = x0r - x2r; y7i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; y11r = wk1i * x0r - wk1r * x0i; y11i = wk1i * x0i + wk1r * x0r; x0r = x1r + x3i; x0i = x1i - x3r; y15r = wk1r * x0r - wk1i * x0i; y15i = wk1r * x0i + wk1i * x0r; x0r = y12r - y14r; x0i = y12i - y14i; x1r = y12r + y14r; x1i = y12i + y14i; x2r = y13r - y15r; x2i = y13i - y15i; x3r = y13r + y15r; x3i = y13i + y15i; a[24] = x0r + x2r; a[25] = x0i + x2i; a[26] = x0r - x2r; a[27] = x0i - x2i; a[28] = x1r - x3i; a[29] = x1i + x3r; a[30] = x1r + x3i; a[31] = x1i - x3r; x0r = y8r + y10r; x0i = y8i + y10i; x1r = y8r - y10r; x1i = y8i - y10i; x2r = y9r + y11r; x2i = y9i + y11i; x3r = y9r - y11r; x3i = y9i - y11i; a[16] = x0r + x2r; a[17] = x0i + x2i; a[18] = x0r - x2r; a[19] = x0i - x2i; a[20] = x1r - x3i; a[21] = x1i + x3r; a[22] = x1r + x3i; a[23] = x1i - x3r; x0r = y5r - y7i; x0i = y5i + y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); x0r = y5r + y7i; x0i = y5i - y7r; x3r = wn4r * (x0r - x0i); x3i = wn4r * (x0i + x0r); x0r = y4r - y6i; x0i = y4i + y6r; x1r = y4r + y6i; x1i = y4i - y6r; a[8] = x0r + x2r; a[9] = x0i + x2i; a[10] = x0r - x2r; a[11] = x0i - x2i; a[12] = x1r - x3i; a[13] = x1i + x3r; a[14] = x1r + x3i; a[15] = x1i - x3r; x0r = y0r + y2r; x0i = y0i + y2i; x1r = y0r - y2r; x1i = y0i - y2i; x2r = y1r + y3r; x2i = y1i + y3i; x3r = y1r - y3r; x3i = y1i - y3i; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x0r - x2r; a[3] = x0i - x2i; a[4] = x1r - x3i; a[5] = x1i + x3r; a[6] = x1r + x3i; a[7] = x1i - x3r; } void cftf162(double *a) { double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; wn4r = WR5000; wk1r = WR1250; wk1i = WI1250; wk2r = WR2500; wk2i = WI2500; wk3r = WR3750; wk3i = WI3750; x1r = a[0] - a[17]; x1i = a[1] + a[16]; x0r = a[8] - a[25]; x0i = a[9] + a[24]; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); y0r = x1r + x2r; y0i = x1i + x2i; y4r = x1r - x2r; y4i = x1i - x2i; x1r = a[0] + a[17]; x1i = a[1] - a[16]; x0r = a[8] + a[25]; x0i = a[9] - a[24]; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); y8r = x1r - x2i; y8i = x1i + x2r; y12r = x1r + x2i; y12i = x1i - x2r; x0r = a[2] - a[19]; x0i = a[3] + a[18]; x1r = wk1r * x0r - wk1i * x0i; x1i = wk1r * x0i + wk1i * x0r; x0r = a[10] - a[27]; x0i = a[11] + a[26]; x2r = wk3i * x0r - wk3r * x0i; x2i = wk3i * x0i + wk3r * x0r; y1r = x1r + x2r; y1i = x1i + x2i; y5r = x1r - x2r; y5i = x1i - x2i; x0r = a[2] + a[19]; x0i = a[3] - a[18]; x1r = wk3r * x0r - wk3i * x0i; x1i = wk3r * x0i + wk3i * x0r; x0r = a[10] + a[27]; x0i = a[11] - a[26]; x2r = wk1r * x0r + wk1i * x0i; x2i = wk1r * x0i - wk1i * x0r; y9r = x1r - x2r; y9i = x1i - x2i; y13r = x1r + x2r; y13i = x1i + x2i; x0r = a[4] - a[21]; x0i = a[5] + a[20]; x1r = wk2r * x0r - wk2i * x0i; x1i = wk2r * x0i + wk2i * x0r; x0r = a[12] - a[29]; x0i = a[13] + a[28]; x2r = wk2i * x0r - wk2r * x0i; x2i = wk2i * x0i + wk2r * x0r; y2r = x1r + x2r; y2i = x1i + x2i; y6r = x1r - x2r; y6i = x1i - x2i; x0r = a[4] + a[21]; x0i = a[5] - a[20]; x1r = wk2i * x0r - wk2r * x0i; x1i = wk2i * x0i + wk2r * x0r; x0r = a[12] + a[29]; x0i = a[13] - a[28]; x2r = wk2r * x0r - wk2i * x0i; x2i = wk2r * x0i + wk2i * x0r; y10r = x1r - x2r; y10i = x1i - x2i; y14r = x1r + x2r; y14i = x1i + x2i; x0r = a[6] - a[23]; x0i = a[7] + a[22]; x1r = wk3r * x0r - wk3i * x0i; x1i = wk3r * x0i + wk3i * x0r; x0r = a[14] - a[31]; x0i = a[15] + a[30]; x2r = wk1i * x0r - wk1r * x0i; x2i = wk1i * x0i + wk1r * x0r; y3r = x1r + x2r; y3i = x1i + x2i; y7r = x1r - x2r; y7i = x1i - x2i; x0r = a[6] + a[23]; x0i = a[7] - a[22]; x1r = wk1i * x0r + wk1r * x0i; x1i = wk1i * x0i - wk1r * x0r; x0r = a[14] + a[31]; x0i = a[15] - a[30]; x2r = wk3i * x0r - wk3r * x0i; x2i = wk3i * x0i + wk3r * x0r; y11r = x1r + x2r; y11i = x1i + x2i; y15r = x1r - x2r; y15i = x1i - x2i; x1r = y0r + y2r; x1i = y0i + y2i; x2r = y1r + y3r; x2i = y1i + y3i; a[0] = x1r + x2r; a[1] = x1i + x2i; a[2] = x1r - x2r; a[3] = x1i - x2i; x1r = y0r - y2r; x1i = y0i - y2i; x2r = y1r - y3r; x2i = y1i - y3i; a[4] = x1r - x2i; a[5] = x1i + x2r; a[6] = x1r + x2i; a[7] = x1i - x2r; x1r = y4r - y6i; x1i = y4i + y6r; x0r = y5r - y7i; x0i = y5i + y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[8] = x1r + x2r; a[9] = x1i + x2i; a[10] = x1r - x2r; a[11] = x1i - x2i; x1r = y4r + y6i; x1i = y4i - y6r; x0r = y5r + y7i; x0i = y5i - y7r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[12] = x1r - x2i; a[13] = x1i + x2r; a[14] = x1r + x2i; a[15] = x1i - x2r; x1r = y8r + y10r; x1i = y8i + y10i; x2r = y9r - y11r; x2i = y9i - y11i; a[16] = x1r + x2r; a[17] = x1i + x2i; a[18] = x1r - x2r; a[19] = x1i - x2i; x1r = y8r - y10r; x1i = y8i - y10i; x2r = y9r + y11r; x2i = y9i + y11i; a[20] = x1r - x2i; a[21] = x1i + x2r; a[22] = x1r + x2i; a[23] = x1i - x2r; x1r = y12r - y14i; x1i = y12i + y14r; x0r = y13r + y15i; x0i = y13i - y15r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[24] = x1r + x2r; a[25] = x1i + x2i; a[26] = x1r - x2r; a[27] = x1i - x2i; x1r = y12r + y14i; x1i = y12i - y14r; x0r = y13r - y15i; x0i = y13i + y15r; x2r = wn4r * (x0r - x0i); x2i = wn4r * (x0i + x0r); a[28] = x1r - x2i; a[29] = x1i + x2r; a[30] = x1r + x2i; a[31] = x1i - x2r; } void cftf081(double *a) { double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; wn4r = WR5000; x0r = a[0] + a[8]; x0i = a[1] + a[9]; x1r = a[0] - a[8]; x1i = a[1] - a[9]; x2r = a[4] + a[12]; x2i = a[5] + a[13]; x3r = a[4] - a[12]; x3i = a[5] - a[13]; y0r = x0r + x2r; y0i = x0i + x2i; y2r = x0r - x2r; y2i = x0i - x2i; y1r = x1r - x3i; y1i = x1i + x3r; y3r = x1r + x3i; y3i = x1i - x3r; x0r = a[2] + a[10]; x0i = a[3] + a[11]; x1r = a[2] - a[10]; x1i = a[3] - a[11]; x2r = a[6] + a[14]; x2i = a[7] + a[15]; x3r = a[6] - a[14]; x3i = a[7] - a[15]; y4r = x0r + x2r; y4i = x0i + x2i; y6r = x0r - x2r; y6i = x0i - x2i; x0r = x1r - x3i; x0i = x1i + x3r; x2r = x1r + x3i; x2i = x1i - x3r; y5r = wn4r * (x0r - x0i); y5i = wn4r * (x0r + x0i); y7r = wn4r * (x2r - x2i); y7i = wn4r * (x2r + x2i); a[8] = y1r + y5r; a[9] = y1i + y5i; a[10] = y1r - y5r; a[11] = y1i - y5i; a[12] = y3r - y7i; a[13] = y3i + y7r; a[14] = y3r + y7i; a[15] = y3i - y7r; a[0] = y0r + y4r; a[1] = y0i + y4i; a[2] = y0r - y4r; a[3] = y0i - y4i; a[4] = y2r - y6i; a[5] = y2i + y6r; a[6] = y2r + y6i; a[7] = y2i - y6r; } void cftf082(double *a) { double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; wn4r = WR5000; wk1r = WR2500; wk1i = WI2500; y0r = a[0] - a[9]; y0i = a[1] + a[8]; y1r = a[0] + a[9]; y1i = a[1] - a[8]; x0r = a[4] - a[13]; x0i = a[5] + a[12]; y2r = wn4r * (x0r - x0i); y2i = wn4r * (x0i + x0r); x0r = a[4] + a[13]; x0i = a[5] - a[12]; y3r = wn4r * (x0r - x0i); y3i = wn4r * (x0i + x0r); x0r = a[2] - a[11]; x0i = a[3] + a[10]; y4r = wk1r * x0r - wk1i * x0i; y4i = wk1r * x0i + wk1i * x0r; x0r = a[2] + a[11]; x0i = a[3] - a[10]; y5r = wk1i * x0r - wk1r * x0i; y5i = wk1i * x0i + wk1r * x0r; x0r = a[6] - a[15]; x0i = a[7] + a[14]; y6r = wk1i * x0r - wk1r * x0i; y6i = wk1i * x0i + wk1r * x0r; x0r = a[6] + a[15]; x0i = a[7] - a[14]; y7r = wk1r * x0r - wk1i * x0i; y7i = wk1r * x0i + wk1i * x0r; x0r = y0r + y2r; x0i = y0i + y2i; x1r = y4r + y6r; x1i = y4i + y6i; a[0] = x0r + x1r; a[1] = x0i + x1i; a[2] = x0r - x1r; a[3] = x0i - x1i; x0r = y0r - y2r; x0i = y0i - y2i; x1r = y4r - y6r; x1i = y4i - y6i; a[4] = x0r - x1i; a[5] = x0i + x1r; a[6] = x0r + x1i; a[7] = x0i - x1r; x0r = y1r - y3i; x0i = y1i + y3r; x1r = y5r - y7r; x1i = y5i - y7i; a[8] = x0r + x1r; a[9] = x0i + x1i; a[10] = x0r - x1r; a[11] = x0i - x1i; x0r = y1r + y3i; x0i = y1i - y3r; x1r = y5r + y7r; x1i = y5i + y7i; a[12] = x0r - x1i; a[13] = x0i + x1r; a[14] = x0r + x1i; a[15] = x0i - x1r; } void cftf040(double *a) { double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; x0r = a[0] + a[4]; x0i = a[1] + a[5]; x1r = a[0] - a[4]; x1i = a[1] - a[5]; x2r = a[2] + a[6]; x2i = a[3] + a[7]; x3r = a[2] - a[6]; x3i = a[3] - a[7]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x1r - x3i; a[3] = x1i + x3r; a[4] = x0r - x2r; a[5] = x0i - x2i; a[6] = x1r + x3i; a[7] = x1i - x3r; } void cftb040(double *a) { double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; x0r = a[0] + a[4]; x0i = a[1] + a[5]; x1r = a[0] - a[4]; x1i = a[1] - a[5]; x2r = a[2] + a[6]; x2i = a[3] + a[7]; x3r = a[2] - a[6]; x3i = a[3] - a[7]; a[0] = x0r + x2r; a[1] = x0i + x2i; a[2] = x1r + x3i; a[3] = x1i - x3r; a[4] = x0r - x2r; a[5] = x0i - x2i; a[6] = x1r - x3i; a[7] = x1i + x3r; } void cftx020(double *a) { double x0r, x0i; x0r = a[0] - a[2]; x0i = a[1] - a[3]; a[0] += a[2]; a[1] += a[3]; a[2] = x0r; a[3] = x0i; } void rftfsub(int n, double *a) { int i, i0, j, k; double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; ec = 2 * M_PI_2 / n; wkr = 0; wki = 0; wdi = cos(ec); wdr = sin(ec); wdi *= wdr; wdr *= wdr; w1r = 1 - 2 * wdr; w1i = 2 * wdi; ss = 2 * w1i; i = n >> 1; for (;;) { i0 = i - 4 * RDFT_LOOP_DIV; if (i0 < 4) { i0 = 4; } for (j = i - 4; j >= i0; j -= 4) { k = n - j; xr = a[j + 2] - a[k - 2]; xi = a[j + 3] + a[k - 1]; yr = wdr * xr - wdi * xi; yi = wdr * xi + wdi * xr; a[j + 2] -= yr; a[j + 3] -= yi; a[k - 2] += yr; a[k - 1] -= yi; wkr += ss * wdi; wki += ss * (0.5 - wdr); xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr - wki * xi; yi = wkr * xi + wki * xr; a[j] -= yr; a[j + 1] -= yi; a[k] += yr; a[k + 1] -= yi; wdr += ss * wki; wdi += ss * (0.5 - wkr); } if (i0 == 4) { break; } wkr = 0.5 * sin(ec * i0); wki = 0.5 * cos(ec * i0); wdr = 0.5 - (wkr * w1r - wki * w1i); wdi = wkr * w1i + wki * w1r; wkr = 0.5 - wkr; i = i0; } xr = a[2] - a[n - 2]; xi = a[3] + a[n - 1]; yr = wdr * xr - wdi * xi; yi = wdr * xi + wdi * xr; a[2] -= yr; a[3] -= yi; a[n - 2] += yr; a[n - 1] -= yi; } void rftbsub(int n, double *a) { int i, i0, j, k; double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; ec = 2 * M_PI_2 / n; wkr = 0; wki = 0; wdi = cos(ec); wdr = sin(ec); wdi *= wdr; wdr *= wdr; w1r = 1 - 2 * wdr; w1i = 2 * wdi; ss = 2 * w1i; i = n >> 1; for (;;) { i0 = i - 4 * RDFT_LOOP_DIV; if (i0 < 4) { i0 = 4; } for (j = i - 4; j >= i0; j -= 4) { k = n - j; xr = a[j + 2] - a[k - 2]; xi = a[j + 3] + a[k - 1]; yr = wdr * xr + wdi * xi; yi = wdr * xi - wdi * xr; a[j + 2] -= yr; a[j + 3] -= yi; a[k - 2] += yr; a[k - 1] -= yi; wkr += ss * wdi; wki += ss * (0.5 - wdr); xr = a[j] - a[k]; xi = a[j + 1] + a[k + 1]; yr = wkr * xr + wki * xi; yi = wkr * xi - wki * xr; a[j] -= yr; a[j + 1] -= yi; a[k] += yr; a[k + 1] -= yi; wdr += ss * wki; wdi += ss * (0.5 - wkr); } if (i0 == 4) { break; } wkr = 0.5 * sin(ec * i0); wki = 0.5 * cos(ec * i0); wdr = 0.5 - (wkr * w1r - wki * w1i); wdi = wkr * w1i + wki * w1r; wkr = 0.5 - wkr; i = i0; } xr = a[2] - a[n - 2]; xi = a[3] + a[n - 1]; yr = wdr * xr + wdi * xi; yi = wdr * xi - wdi * xr; a[2] -= yr; a[3] -= yi; a[n - 2] += yr; a[n - 1] -= yi; } void dctsub(int n, double *a) { int i, i0, j, k, m; double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; ec = M_PI_2 / n; wkr = 0.5; wki = 0.5; w1r = cos(ec); w1i = sin(ec); wdr = 0.5 * (w1r - w1i); wdi = 0.5 * (w1r + w1i); ss = 2 * w1i; m = n >> 1; i = 0; for (;;) { i0 = i + 2 * DCST_LOOP_DIV; if (i0 > m - 2) { i0 = m - 2; } for (j = i + 2; j <= i0; j += 2) { k = n - j; xr = wdi * a[j - 1] - wdr * a[k + 1]; xi = wdr * a[j - 1] + wdi * a[k + 1]; wkr -= ss * wdi; wki += ss * wdr; yr = wki * a[j] - wkr * a[k]; yi = wkr * a[j] + wki * a[k]; wdr -= ss * wki; wdi += ss * wkr; a[k + 1] = xr; a[k] = yr; a[j - 1] = xi; a[j] = yi; } if (i0 == m - 2) { break; } wdr = cos(ec * i0); wdi = sin(ec * i0); wkr = 0.5 * (wdr - wdi); wki = 0.5 * (wdr + wdi); wdr = wkr * w1r - wki * w1i; wdi = wkr * w1i + wki * w1r; i = i0; } xr = wdi * a[m - 1] - wdr * a[m + 1]; a[m - 1] = wdr * a[m - 1] + wdi * a[m + 1]; a[m + 1] = xr; a[m] *= WR5000; } void dstsub(int n, double *a) { int i, i0, j, k, m; double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; ec = M_PI_2 / n; wkr = 0.5; wki = 0.5; w1r = cos(ec); w1i = sin(ec); wdr = 0.5 * (w1r - w1i); wdi = 0.5 * (w1r + w1i); ss = 2 * w1i; m = n >> 1; i = 0; for (;;) { i0 = i + 2 * DCST_LOOP_DIV; if (i0 > m - 2) { i0 = m - 2; } for (j = i + 2; j <= i0; j += 2) { k = n - j; xr = wdi * a[k + 1] - wdr * a[j - 1]; xi = wdr * a[k + 1] + wdi * a[j - 1]; wkr -= ss * wdi; wki += ss * wdr; yr = wki * a[k] - wkr * a[j]; yi = wkr * a[k] + wki * a[j]; wdr -= ss * wki; wdi += ss * wkr; a[j - 1] = xr; a[j] = yr; a[k + 1] = xi; a[k] = yi; } if (i0 == m - 2) { break; } wdr = cos(ec * i0); wdi = sin(ec * i0); wkr = 0.5 * (wdr - wdi); wki = 0.5 * (wdr + wdi); wdr = wkr * w1r - wki * w1i; wdi = wkr * w1i + wki * w1r; i = i0; } xr = wdi * a[m + 1] - wdr * a[m - 1]; a[m + 1] = wdr * a[m + 1] + wdi * a[m - 1]; a[m - 1] = xr; a[m] *= WR5000; } void dctsub4(int n, double *a) { int m; double wki, wdr, wdi, xr; wki = WR5000; m = n >> 1; if (m == 2) { wdr = wki * WI2500; wdi = wki * WR2500; xr = wdi * a[1] - wdr * a[3]; a[1] = wdr * a[1] + wdi * a[3]; a[3] = xr; } a[m] *= wki; } void dstsub4(int n, double *a) { int m; double wki, wdr, wdi, xr; wki = WR5000; m = n >> 1; if (m == 2) { wdr = wki * WI2500; wdi = wki * WR2500; xr = wdi * a[3] - wdr * a[1]; a[3] = wdr * a[3] + wdi * a[1]; a[1] = xr; } a[m] *= wki; } kst-2.0.3/src/plugins/dataobject/crossspectrum/crossspectrum.h000644 001750 001750 00000005254 11544160207 025250 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CROSSSPECTRUMPLUGIN_H #define CROSSSPECTRUMPLUGIN_H #include #include #include class CrossSpectrumSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorOne() const; Kst::VectorPtr vectorTwo() const; Kst::ScalarPtr scalarFFT() const; Kst::ScalarPtr scalarRate() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: CrossSpectrumSource(Kst::ObjectStore *store); ~CrossSpectrumSource(); friend class Kst::ObjectStore; }; class CrossSpectrumPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~CrossSpectrumPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/crossspectrum/kstplugin_crossspectrum.desktop000644 001750 001750 00000000422 11544160207 030562 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=crossspectrum X-Kst-Plugin-Author=The University of Toronto Name=Cross Spectrum Data Object Plugin Comment=Implements a Cross Spectrum Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/dataobject.pro000644 001750 001750 00000000651 11544160207 022065 0ustar00synthsynth000000 000000 include($$PWD/../../../config.pri) TEMPLATE = subdirs CONFIG += ordered DEMOS += \ linefit \ genericfilter SUBDIRS += \ bin \ chop \ crossspectrum \ effectivebandwidth \ lockin \ periodogram \ phase \ shift \ statistics \ syncbin LibExists(gsl) { SUBDIRS += convolution \ correlation \ interpolations \ noiseaddition } kst-2.0.3/src/plugins/dataobject/convolution/convolve/kstplugin_convolve.desktop000644 001750 001750 00000000401 11544160207 030774 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=convolve X-Kst-Plugin-Author=The University of Toronto Name=Convolve Data Object Plugin Comment=Implements a Convolve Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/convolution/convolve/convolveconfig.ui000644 001750 001750 00000004643 11544160207 027042 0ustar00synthsynth000000 000000 ConvolveConfig 0 0 429 70 400 0 0 0 Input Vector One false 0 0 0 0 Input Vector Two false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/convolution/convolve/convolve.cpp000644 001750 001750 00000024115 11544160207 026015 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "convolve.h" #include "objectstore.h" #include "ui_convolveconfig.h" #include #include static const QString& VECTOR_IN_ONE = "Vector One In"; static const QString& VECTOR_IN_TWO = "Vector Two In"; static const QString& VECTOR_OUT = "Vector Out"; class ConfigWidgetConvolvePlugin : public Kst::DataObjectConfigWidget, public Ui_ConvolveConfig { public: ConfigWidgetConvolvePlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_ConvolveConfig() { setupUi(this); } ~ConfigWidgetConvolvePlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorOne->setObjectStore(store); _vectorTwo->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorOne, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorTwo, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorOne() { return _vectorOne->selectedVector(); }; void setSelectedVectorOne(Kst::VectorPtr vector) { return _vectorOne->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorTwo() { return _vectorTwo->selectedVector(); }; void setSelectedVectorTwo(Kst::VectorPtr vector) { return _vectorTwo->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (ConvolveSource* source = static_cast(dataObject)) { setSelectedVectorOne(source->vectorOne()); setSelectedVectorTwo(source->vectorTwo()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Convolve DataObject Plugin"); _cfg->setValue("Input Vector One", _vectorOne->selectedVector()->Name()); _cfg->setValue("Input Vector Two", _vectorTwo->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Convolve DataObject Plugin"); QString vectorName = _cfg->value("Input Vector One").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorOne(vector); } vectorName = _cfg->value("Input Vector Two").toString(); Kst::Object* object2 = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object2); if (vector2) { setSelectedVectorTwo(vector2); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; ConvolveSource::ConvolveSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } ConvolveSource::~ConvolveSource() { } QString ConvolveSource::_automaticDescriptiveName() const { return QString("Convolve Plugin Object"); } void ConvolveSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetConvolvePlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_ONE, config->selectedVectorOne()); setInputVector(VECTOR_IN_TWO, config->selectedVectorTwo()); } } void ConvolveSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool ConvolveSource::algorithm() { Kst::VectorPtr inputVectorOne = _inputVectors[VECTOR_IN_ONE]; Kst::VectorPtr inputVectorTwo = _inputVectors[VECTOR_IN_TWO]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; if (inputVectorOne->length() <= 0 && inputVectorTwo->length() <= 0) { _errorString = "Error: Input Vectors - invalid size"; return false; } double* pdResponse; double* pdConvolve; double* pdResult; double dReal; double dImag; Kst::VectorPtr response; Kst::VectorPtr convolve; int iLength; int iLengthNew; bool bReturn = false; int iResponseMidpoint; // determine which is the response function: // i.e. which is shorter... if (inputVectorOne->length() < inputVectorTwo->length()) { response = inputVectorOne; convolve = inputVectorTwo; } else { response = inputVectorTwo; convolve = inputVectorOne; } outputVector->resize(convolve->length(), false); iResponseMidpoint = response->length() / 2; iLength = convolve->length() + iResponseMidpoint; // round iLength up to the nearest factor of two... iLengthNew = 64; while (iLengthNew < iLength && iLengthNew > 0) { iLengthNew *= 2; } iLength = iLengthNew; if (iLength <= 0) { _errorString = "Error: Invalid Input length calculated"; return false; } pdResponse = new double[iLength]; pdConvolve = new double[iLength]; if (pdResponse != NULL && pdConvolve != NULL) { // // sort the response function into wrap-around order... // memset( pdResponse, 0, iLength * sizeof( double ) ); for (int i = 0; i < iResponseMidpoint; i++) { pdResponse[i] = response->value()[iResponseMidpoint+i]; pdResponse[iLength-iResponseMidpoint+i] = response->value()[i]; } // // handle the case where the response function has an odd number of points... // if (iResponseMidpoint % 2 == 1) { pdResponse[iResponseMidpoint] = response->value()[response->length()-1]; } // // zero-pad the convolve array... // memset( pdConvolve, 0, iLength * sizeof( double ) ); memcpy( pdConvolve, convolve->value(), convolve->length() * sizeof( double ) ); // // calculate the FFTs of the two functions... // if (gsl_fft_real_radix2_transform( pdResponse, 1, iLength ) == 0) { if (gsl_fft_real_radix2_transform( pdConvolve, 1, iLength ) == 0) { // // multiply the FFTs together... // for (int i=0; i < iLength/2; i++) { if (i==0 || i==(iLength/2)-1) { pdResponse[i] = pdResponse[i] * pdConvolve[i]; } else { dReal = pdResponse[i] * pdConvolve[i] - pdResponse[iLength-i] * pdConvolve[iLength-i]; dImag = pdResponse[i] * pdConvolve[iLength-i] + pdResponse[iLength-i] * pdConvolve[i]; pdResponse[i] = dReal; pdResponse[iLength-i] = dImag; } } // // do the inverse FFT... // if (gsl_fft_halfcomplex_radix2_inverse( pdResponse, 1, iLength) == 0) { pdResult = outputVector->value(); if (pdResult != NULL) { for (int i = 0; i < convolve->length(); ++i) { outputVector->value()[i] = pdResult[i]; } memcpy( pdResult, pdResponse, convolve->length() * sizeof( double ) ); bReturn = true; } } } } } delete[] pdResponse; delete[] pdConvolve; return bReturn; } Kst::VectorPtr ConvolveSource::vectorOne() const { return _inputVectors[VECTOR_IN_ONE]; } Kst::VectorPtr ConvolveSource::vectorTwo() const { return _inputVectors[VECTOR_IN_TWO]; } QStringList ConvolveSource::inputVectorList() const { QStringList vectors(VECTOR_IN_ONE); vectors += VECTOR_IN_TWO; return vectors; } QStringList ConvolveSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList ConvolveSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList ConvolveSource::outputVectorList() const { return QStringList(VECTOR_OUT); } QStringList ConvolveSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList ConvolveSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void ConvolveSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString ConvolvePlugin::pluginName() const { return "Convolve"; } QString ConvolvePlugin::pluginDescription() const { return "Generates the convolution of one vector with another."; } Kst::DataObject *ConvolvePlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetConvolvePlugin* config = static_cast(configWidget)) { ConvolveSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_ONE, config->selectedVectorOne()); object->setInputVector(VECTOR_IN_TWO, config->selectedVectorTwo()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *ConvolvePlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetConvolvePlugin *widget = new ConfigWidgetConvolvePlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, ConvolvePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/convolution/convolve/convolve.pro000644 001750 001750 00000000274 11544160207 026033 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_convolve) LIBS += -l$$kstlib(gsl) SOURCES += \ convolve.cpp HEADERS += \ convolve.h FORMS += convolveconfig.ui kst-2.0.3/src/plugins/dataobject/convolution/convolve/convolve.h000644 001750 001750 00000005074 11544160207 025465 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CONVOLVEPLUGIN_H #define CONVOLVEPLUGIN_H #include #include #include class ConvolveSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorOne() const; Kst::VectorPtr vectorTwo() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: ConvolveSource(Kst::ObjectStore *store); ~ConvolveSource(); friend class Kst::ObjectStore; }; class ConvolvePlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~ConvolvePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/convolution/convolution.pro000644 001750 001750 00000000122 11544160207 024714 0ustar00synthsynth000000 000000 TEMPLATE = subdirs CONFIG += ordered SUBDIRS += \ convolve \ deconvolve kst-2.0.3/src/plugins/dataobject/convolution/deconvolve/kstplugin_deconvolve.desktop000644 001750 001750 00000000407 11544160207 031624 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=deconvolve X-Kst-Plugin-Author=The University of Toronto Name=Deconvolve Data Object Plugin Comment=Implements a Deconvolve Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/convolution/deconvolve/deconvolve.pro000644 001750 001750 00000000304 11544160207 026647 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_deconvolve) LIBS += -l$$kstlib(gsl) SOURCES += \ deconvolve.cpp HEADERS += \ deconvolve.h FORMS += deconvolveconfig.ui kst-2.0.3/src/plugins/dataobject/convolution/deconvolve/deconvolve.h000644 001750 001750 00000005116 11544160207 026304 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DEDeconvolvePlugin_H #define DEDeconvolvePlugin_H #include #include #include class DeconvolveSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorOne() const; Kst::VectorPtr vectorTwo() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: DeconvolveSource(Kst::ObjectStore *store); ~DeconvolveSource(); friend class Kst::ObjectStore; }; class DeconvolvePlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~DeconvolvePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/convolution/deconvolve/deconvolveconfig.ui000644 001750 001750 00000004647 11544160207 027670 0ustar00synthsynth000000 000000 DeconvolveConfig 0 0 429 73 400 0 0 0 Input Vector One false 0 0 0 0 Input Vector Two false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/convolution/deconvolve/deconvolve.cpp000644 001750 001750 00000024561 11544160207 026644 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "deconvolve.h" #include "objectstore.h" #include "ui_deconvolveconfig.h" #include #include static const QString& VECTOR_IN_ONE = "Vector One In"; static const QString& VECTOR_IN_TWO = "Vector Two In"; static const QString& VECTOR_OUT = "Vector Out"; class ConfigWidgetDeconvolvePlugin : public Kst::DataObjectConfigWidget, public Ui_DeconvolveConfig { public: ConfigWidgetDeconvolvePlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_DeconvolveConfig() { setupUi(this); } ~ConfigWidgetDeconvolvePlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorOne->setObjectStore(store); _vectorTwo->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorOne, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorTwo, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorOne() { return _vectorOne->selectedVector(); }; void setSelectedVectorOne(Kst::VectorPtr vector) { return _vectorOne->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorTwo() { return _vectorTwo->selectedVector(); }; void setSelectedVectorTwo(Kst::VectorPtr vector) { return _vectorTwo->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (DeconvolveSource* source = static_cast(dataObject)) { setSelectedVectorOne(source->vectorOne()); setSelectedVectorTwo(source->vectorTwo()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Deconvolve DataObject Plugin"); _cfg->setValue("Input Vector One", _vectorOne->selectedVector()->Name()); _cfg->setValue("Input Vector Two", _vectorTwo->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Deconvolve DataObject Plugin"); QString vectorName = _cfg->value("Input Vector One").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorOne(vector); } vectorName = _cfg->value("Input Vector Two").toString(); Kst::Object* object2 = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object2); if (vector2) { setSelectedVectorTwo(vector2); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; DeconvolveSource::DeconvolveSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } DeconvolveSource::~DeconvolveSource() { } QString DeconvolveSource::_automaticDescriptiveName() const { return QString("Deconvolve Plugin Object"); } void DeconvolveSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetDeconvolvePlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_ONE, config->selectedVectorOne()); setInputVector(VECTOR_IN_TWO, config->selectedVectorTwo()); } } void DeconvolveSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } bool DeconvolveSource::algorithm() { Kst::VectorPtr inputVectorOne = _inputVectors[VECTOR_IN_ONE]; Kst::VectorPtr inputVectorTwo = _inputVectors[VECTOR_IN_TWO]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; if (inputVectorOne->length() <= 0 && inputVectorTwo->length() <= 0) { _errorString = "Error: Input Vectors - invalid size"; return false; } double* pdResponse; double* pdConvolve; double* pdResult; double dReal; double dImag; double dSize; Kst::VectorPtr response; Kst::VectorPtr deconvolve; int iLength; int iLengthNew; bool bReturn = false; int iResponseMidpoint; // determine which is the response function: // i.e. which is shorter... if (inputVectorOne->length() < inputVectorTwo->length()) { response = inputVectorOne; deconvolve = inputVectorTwo; } else { response = inputVectorTwo; deconvolve = inputVectorOne; } outputVector->resize(deconvolve->length(), false); iResponseMidpoint = response->length() / 2; iLength = deconvolve->length() + iResponseMidpoint; // round iLength up to the nearest factor of two... iLengthNew = 64; while (iLengthNew < iLength && iLengthNew > 0) { iLengthNew *= 2; } iLength = iLengthNew; if (iLength <= 0) { _errorString = "Error: Invalid Input length calculated"; return false; } pdResponse = new double[iLength]; pdConvolve = new double[iLength]; if (pdResponse != NULL && pdConvolve != NULL) { // // sort the response function into wrap-around order... // memset( pdResponse, 0, iLength * sizeof( double ) ); for ( int i=0; i < iResponseMidpoint; i++) { pdResponse[i] = response->value()[iResponseMidpoint+i]; pdResponse[iLength-iResponseMidpoint+i] = response->value()[i]; } // // handle the case where the response function has an odd number of points... // if (iResponseMidpoint % 2 == 1) { pdResponse[iResponseMidpoint] = response->value()[response->length()]; } // // zero-pad the convolve array... // memset( pdConvolve, 0, iLength * sizeof( double ) ); memcpy( pdConvolve, deconvolve->value(), deconvolve->length() * sizeof( double ) ); // // calculate the FFTs of the two functions... // if (gsl_fft_real_radix2_transform( pdResponse, 1, iLength ) == 0) { if (gsl_fft_real_radix2_transform( pdConvolve, 1, iLength ) == 0) { // // divide one FFT by the other... // for ( int i=0; i < iLength/2; i++) { if (i==0 || i==(iLength/2)-1) { pdResponse[i] = pdConvolve[i] / pdResponse[i]; } else { dSize = ( pdResponse[i] * pdResponse[i] ) + ( pdResponse[iLength-i] * pdResponse[iLength-i] ); dReal = pdResponse[i] * pdConvolve[i] + pdResponse[iLength-i] * pdConvolve[iLength-i]; dImag = pdResponse[i] * pdConvolve[iLength-i] - pdResponse[iLength-i] * pdConvolve[i]; dReal /= dSize; dImag /= dSize; pdResponse[i] = dReal; pdResponse[iLength-i] = dImag; } } // // do the inverse FFT... // if (gsl_fft_halfcomplex_radix2_inverse( pdResponse, 1, iLength ) == 0) { pdResult = outputVector->value(); if (pdResult != NULL) { for (int i = 0; i < deconvolve->length(); ++i) { outputVector->value()[i] = pdResult[i]; } memcpy( pdResult, pdResponse, deconvolve->length() * sizeof( double ) ); bReturn = true; } } } } } delete[] pdResponse; delete[] pdConvolve; return bReturn; } Kst::VectorPtr DeconvolveSource::vectorOne() const { return _inputVectors[VECTOR_IN_ONE]; } Kst::VectorPtr DeconvolveSource::vectorTwo() const { return _inputVectors[VECTOR_IN_TWO]; } QStringList DeconvolveSource::inputVectorList() const { QStringList vectors(VECTOR_IN_ONE); vectors += VECTOR_IN_TWO; return vectors; } QStringList DeconvolveSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList DeconvolveSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList DeconvolveSource::outputVectorList() const { return QStringList(VECTOR_OUT); } QStringList DeconvolveSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList DeconvolveSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void DeconvolveSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString DeconvolvePlugin::pluginName() const { return "Deconvolve"; } QString DeconvolvePlugin::pluginDescription() const { return "Generates the deconvolution of one vector with another."; } Kst::DataObject *DeconvolvePlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetDeconvolvePlugin* config = static_cast(configWidget)) { DeconvolveSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_ONE, config->selectedVectorOne()); object->setInputVector(VECTOR_IN_TWO, config->selectedVectorTwo()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *DeconvolvePlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetDeconvolvePlugin *widget = new ConfigWidgetDeconvolvePlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_DeconvolvePlugin, DeconvolvePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/correlation/correlation.pro000644 001750 001750 00000000137 11544160207 024626 0ustar00synthsynth000000 000000 TEMPLATE = subdirs CONFIG += ordered SUBDIRS += \ autocorrelation \ crosscorrelation kst-2.0.3/src/plugins/dataobject/correlation/autocorrelation/autocorrelation.pro000644 001750 001750 00000000330 11544160207 030724 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_autocorrelation) LIBS += -l$$kstlib(gsl) SOURCES += \ autocorrelation.cpp HEADERS += \ autocorrelation.h FORMS += autocorrelationconfig.ui kst-2.0.3/src/plugins/dataobject/correlation/autocorrelation/autocorrelationconfig.ui000644 001750 001750 00000003055 11544160207 031736 0ustar00synthsynth000000 000000 AutoCorrelationConfig 0 0 429 49 400 0 0 0 Input Vector false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/correlation/autocorrelation/autocorrelation.cpp000644 001750 001750 00000021755 11544160207 030724 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "autocorrelation.h" #include "objectstore.h" #include "ui_autocorrelationconfig.h" #include #include static const QString& VECTOR_IN = "Vector In"; static const QString& VECTOR_OUT_AUTO = "Auto-Correlated"; static const QString& VECTOR_OUT_STEP = "Step Value"; class ConfigAutoCorrelationPlugin : public Kst::DataObjectConfigWidget, public Ui_AutoCorrelationConfig { public: ConfigAutoCorrelationPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_AutoCorrelationConfig() { setupUi(this); } ~ConfigAutoCorrelationPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vector->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (AutoCorrelationSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Auto Correlation DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Auto Correlation DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; AutoCorrelationSource::AutoCorrelationSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } AutoCorrelationSource::~AutoCorrelationSource() { } QString AutoCorrelationSource::_automaticDescriptiveName() const { return QString("Auto Correlation Plugin Object"); } void AutoCorrelationSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigAutoCorrelationPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); } } void AutoCorrelationSource::setupOutputs() { setOutputVector(VECTOR_OUT_AUTO, ""); setOutputVector(VECTOR_OUT_STEP, ""); } bool AutoCorrelationSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::VectorPtr outputVectorAuto = _outputVectors[VECTOR_OUT_AUTO]; Kst::VectorPtr outputVectorStep = _outputVectors[VECTOR_OUT_STEP]; //Make sure there is at least 1 element in the input vector if (inputVector->length() < 1) { _errorString = "Error: Input Vector invalid size"; return false; } double* pdArrayOne; double* pdResult; double* pdCorrelate; double dReal; double dImag; int iLength; int iLengthNew; bool bReturn = false; // // zero-pad the array... // iLength = inputVector->length(); iLength *= 2; outputVectorAuto->resize(inputVector->length(), false); outputVectorStep->resize(inputVector->length(), false); // // round iLength up to the nearest power of two... // iLengthNew = 64; while( iLengthNew < iLength && iLengthNew > 0) { iLengthNew *= 2; } iLength = iLengthNew; if (iLength <= 0) { _errorString = "Error: Invalid Input length calculated"; return false; } pdArrayOne = new double[iLength]; if (pdArrayOne != NULL) { // // zero-pad the two arrays... // memset( pdArrayOne, 0, iLength * sizeof( double ) ); memcpy( pdArrayOne, inputVector->value(), inputVector->length() * sizeof( double ) ); // // calculate the FFTs of the two functions... // if (gsl_fft_real_radix2_transform( pdArrayOne, 1, iLength ) == 0) { // // multiply the FFT by its complex conjugate... // for (int i=0; ivalue(); pdCorrelate = outputVectorAuto->value(); if (pdResult != NULL && pdCorrelate != NULL) { for (int i = 0; i < inputVector->length(); ++i) { outputVectorStep->value()[i] = pdResult[i]; } for (int i = 0; i < inputVector->length(); ++i) { outputVectorAuto->value()[i] = pdCorrelate[i]; } for (int i = 0; i < inputVector->length(); i++) { outputVectorStep->value()[i] = (double)( i - ( inputVector->length() / 2 ) ); } memcpy( &(outputVectorAuto->value()[inputVector->length() / 2]), &(pdArrayOne[0]), ( ( inputVector->length() + 1 ) / 2 ) * sizeof( double ) ); memcpy( &(outputVectorAuto->value()[0]), &(pdArrayOne[iLength - (inputVector->length() / 2)]), ( inputVector->length() / 2 ) * sizeof( double ) ); bReturn = true; } } } } delete[] pdArrayOne; return bReturn; } Kst::VectorPtr AutoCorrelationSource::vector() const { return _inputVectors[VECTOR_IN]; } QStringList AutoCorrelationSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList AutoCorrelationSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList AutoCorrelationSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList AutoCorrelationSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_AUTO); vectors += VECTOR_OUT_STEP; return vectors; } QStringList AutoCorrelationSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList AutoCorrelationSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void AutoCorrelationSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString AutoCorrelationPlugin::pluginName() const { return "Auto Correlation"; } QString AutoCorrelationPlugin::pluginDescription() const { return "Generates the auto-correlation of a vector."; } Kst::DataObject *AutoCorrelationPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigAutoCorrelationPlugin* config = static_cast(configWidget)) { AutoCorrelationSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN, config->selectedVector()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *AutoCorrelationPlugin::configWidget(QSettings *settingsObject) const { ConfigAutoCorrelationPlugin *widget = new ConfigAutoCorrelationPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, AutoCorrelationPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/correlation/autocorrelation/kstplugin_autocorrelation.desktop000644 001750 001750 00000000413 11544160207 033677 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=autocorrelation X-Kst-Plugin-Author=The University of Toronto Name=Bin Data Object Plugin Comment=Implements a Auto Correlation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/correlation/autocorrelation/autocorrelation.h000644 001750 001750 00000005104 11544160207 030357 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef AUTOCORRELATIONPLUGIN_H #define AUTOCORRELATIONPLUGIN_H #include #include #include class AutoCorrelationSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: AutoCorrelationSource(Kst::ObjectStore *store); ~AutoCorrelationSource(); friend class Kst::ObjectStore; }; class AutoCorrelationPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~AutoCorrelationPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/correlation/crosscorrelation/kstplugin_crosscorrelation.desktop000644 001750 001750 00000000433 11544160207 034243 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=crosscorrelation X-Kst-Plugin-Author=The University of Toronto Name=Cross Correlation Data Object Plugin Comment=Implements a Cross Correlation Data Object Plugin for Kst. kst-2.0.3/src/plugins/dataobject/correlation/crosscorrelation/crosscorrelation.cpp000644 001750 001750 00000025364 11544160207 031266 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "crosscorrelation.h" #include "objectstore.h" #include "ui_crosscorrelationconfig.h" #include #include static const QString& VECTOR_IN_ONE = "Vector One In"; static const QString& VECTOR_IN_TWO = "Vector Two In"; static const QString& VECTOR_OUT_STEP = "Offset"; static const QString& VECTOR_OUT_CORRELATED = "C"; class ConfigCrossCorrelationPlugin : public Kst::DataObjectConfigWidget, public Ui_CrossCorrelationConfig { public: ConfigCrossCorrelationPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_CrossCorrelationConfig() { setupUi(this); } ~ConfigCrossCorrelationPlugin() {} void setObjectStore(Kst::ObjectStore* store) { _store = store; _vectorOne->setObjectStore(store); _vectorTwo->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { connect(_vectorOne, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); connect(_vectorTwo, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } Kst::VectorPtr selectedVectorOne() { return _vectorOne->selectedVector(); }; void setSelectedVectorOne(Kst::VectorPtr vector) { return _vectorOne->setSelectedVector(vector); }; Kst::VectorPtr selectedVectorTwo() { return _vectorTwo->selectedVector(); }; void setSelectedVectorTwo(Kst::VectorPtr vector) { return _vectorTwo->setSelectedVector(vector); }; virtual void setupFromObject(Kst::Object* dataObject) { if (CrossCorrelationSource* source = static_cast(dataObject)) { setSelectedVectorOne(source->vectorOne()); setSelectedVectorTwo(source->vectorTwo()); } } virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: virtual void save() { if (_cfg) { _cfg->beginGroup("Cross Correlation DataObject Plugin"); _cfg->setValue("Input Vector One", _vectorOne->selectedVector()->Name()); _cfg->setValue("Input Vector Two", _vectorTwo->selectedVector()->Name()); _cfg->endGroup(); } } virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Cross Correlation DataObject Plugin"); QString vectorName = _cfg->value("Input Vector One").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVectorOne(vector); } vectorName = _cfg->value("Input Vector Two").toString(); Kst::Object* object2 = _store->retrieveObject(vectorName); Kst::Vector* vector2 = static_cast(object2); if (vector2) { setSelectedVectorTwo(vector2); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; CrossCorrelationSource::CrossCorrelationSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } CrossCorrelationSource::~CrossCorrelationSource() { } QString CrossCorrelationSource::_automaticDescriptiveName() const { return QString("Cross Correlation"); } void CrossCorrelationSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigCrossCorrelationPlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN_ONE, config->selectedVectorOne()); setInputVector(VECTOR_IN_TWO, config->selectedVectorTwo()); } } void CrossCorrelationSource::setupOutputs() { setOutputVector(VECTOR_OUT_STEP, ""); setOutputVector(VECTOR_OUT_CORRELATED, ""); } bool CrossCorrelationSource::algorithm() { Kst::VectorPtr inputVectorOne = _inputVectors[VECTOR_IN_ONE]; Kst::VectorPtr inputVectorTwo = _inputVectors[VECTOR_IN_TWO]; Kst::VectorPtr outputVectorStep = _outputVectors[VECTOR_OUT_STEP]; Kst::VectorPtr outputVectorCorrelated = _outputVectors[VECTOR_OUT_CORRELATED]; if (inputVectorOne->length() <= 0 || inputVectorTwo->length() <= 0 || inputVectorOne->length() != inputVectorTwo->length()) { _errorString = "Error: Input Vectors - invalid size"; return false; } double* pdArrayOne; double* pdArrayTwo; double* pdResult[2]; double dReal; double dImag; int iLength; int iLengthNew; bool bReturn = false; // // zero-pad the array... // iLength = inputVectorOne->length(); iLength *= 2; outputVectorStep->resize(inputVectorOne->length(), false); outputVectorCorrelated->resize(inputVectorTwo->length(), false); // // round iLength up to the nearest power of two... // iLengthNew = 64; while( iLengthNew < iLength && iLengthNew > 0) { iLengthNew *= 2; } iLength = iLengthNew; if (iLength <= 0) { _errorString = "Error: Invalid Input length calculated"; return false; } pdArrayOne = new double[iLength]; pdArrayTwo = new double[iLength]; if (pdArrayOne != NULL && pdArrayTwo != NULL) { // // zero-pad the two arrays... // memset( pdArrayOne, 0, iLength * sizeof( double ) ); memcpy( pdArrayOne, inputVectorOne->value(), inputVectorOne->length() * sizeof( double ) ); memset( pdArrayTwo, 0, iLength * sizeof( double ) ); memcpy( pdArrayTwo, inputVectorTwo->value(), inputVectorTwo->length() * sizeof( double ) ); // // calculate the FFTs of the two functions... // if (gsl_fft_real_radix2_transform( pdArrayOne, 1, iLength ) == 0) { if (gsl_fft_real_radix2_transform( pdArrayTwo, 1, iLength ) == 0) { // // multiply one FFT by the complex conjugate of the other... // for (int i=0; ivalue(); pdResult[1] = outputVectorCorrelated->value(); if (pdResult[0] != NULL && pdResult[1] != NULL) { for (int i = 0; i < inputVectorOne->length(); ++i) { outputVectorStep->value()[i] = pdResult[0][i]; } for (int i = 0; i < inputVectorTwo->length(); ++i) { outputVectorCorrelated->value()[i] = pdResult[1][i]; } for (int i = 0; i < inputVectorOne->length(); i++) { outputVectorStep->value()[i] = (double)( i - ( inputVectorOne->length() / 2 ) ); } memcpy( &(outputVectorCorrelated->value()[inputVectorOne->length() / 2]), &(pdArrayOne[0]), ( ( inputVectorOne->length() + 1 ) / 2 ) * sizeof( double ) ); memcpy( &(outputVectorCorrelated->value()[0]), &(pdArrayOne[iLength - (inputVectorOne->length() / 2)]), ( inputVectorOne->length() / 2 ) * sizeof( double ) ); bReturn = true; } } } } } delete[] pdArrayOne; delete[] pdArrayTwo; return bReturn; } Kst::VectorPtr CrossCorrelationSource::vectorOne() const { return _inputVectors[VECTOR_IN_ONE]; } Kst::VectorPtr CrossCorrelationSource::vectorTwo() const { return _inputVectors[VECTOR_IN_TWO]; } QStringList CrossCorrelationSource::inputVectorList() const { QStringList vectors(VECTOR_IN_ONE); vectors += VECTOR_IN_TWO; return vectors; } QStringList CrossCorrelationSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList CrossCorrelationSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList CrossCorrelationSource::outputVectorList() const { QStringList vectors(VECTOR_OUT_CORRELATED); vectors += VECTOR_OUT_STEP; return vectors; } QStringList CrossCorrelationSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList CrossCorrelationSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } void CrossCorrelationSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } QString CrossCorrelationPlugin::pluginName() const { return "Cross Correlation"; } QString CrossCorrelationPlugin::pluginDescription() const { return "Generates the correlation of one vector with another."; } Kst::DataObject *CrossCorrelationPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigCrossCorrelationPlugin* config = static_cast(configWidget)) { CrossCorrelationSource* object = store->createObject(); if (setupInputsOutputs) { object->setupOutputs(); object->setInputVector(VECTOR_IN_ONE, config->selectedVectorOne()); object->setInputVector(VECTOR_IN_TWO, config->selectedVectorTwo()); } object->setPluginName(pluginName()); object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } Kst::DataObjectConfigWidget *CrossCorrelationPlugin::configWidget(QSettings *settingsObject) const { ConfigCrossCorrelationPlugin *widget = new ConfigCrossCorrelationPlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_ConvolvePlugin, CrossCorrelationPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/dataobject/correlation/crosscorrelation/crosscorrelationconfig.ui000644 001750 001750 00000004663 11544160207 032306 0ustar00synthsynth000000 000000 CrossCorrelationConfig 0 0 428 86 400 0 0 0 Input Vector One false 0 0 0 0 Input Vector Two false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/dataobject/correlation/crosscorrelation/crosscorrelation.pro000644 001750 001750 00000000335 11544160207 031273 0ustar00synthsynth000000 000000 include(../../../plugins_subsub.pri) TARGET = $$kstlib(kstplugin_crosscorrelation) LIBS += -l$$kstlib(gsl) SOURCES += \ crosscorrelation.cpp HEADERS += \ crosscorrelation.h FORMS += crosscorrelationconfig.ui kst-2.0.3/src/plugins/dataobject/correlation/crosscorrelation/crosscorrelation.h000644 001750 001750 00000005164 11544160207 030727 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CROSSCORRELATIONPLUGIN_H #define CROSSCORRELATIONPLUGIN_H #include #include #include class CrossCorrelationSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vectorOne() const; Kst::VectorPtr vectorTwo() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: CrossCorrelationSource(Kst::ObjectStore *store); ~CrossCorrelationSource(); friend class Kst::ObjectStore; }; class CrossCorrelationPlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~CrossCorrelationPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/sampleplugin/sampleplugin.h000644 001750 001750 00000005027 11544160207 022516 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SAMPLEPLUGIN_H #define SAMPLEPLUGIN_H #include #include #include class SamplePluginSource : public Kst::BasicPlugin { Q_OBJECT public: virtual QString _automaticDescriptiveName() const; Kst::VectorPtr vector() const; virtual void change(Kst::DataObjectConfigWidget *configWidget); void setupOutputs(); virtual bool algorithm(); virtual QStringList inputVectorList() const; virtual QStringList inputScalarList() const; virtual QStringList inputStringList() const; virtual QStringList outputVectorList() const; virtual QStringList outputScalarList() const; virtual QStringList outputStringList() const; virtual void saveProperties(QXmlStreamWriter &s); protected: SamplePluginSource(Kst::ObjectStore *store); ~SamplePluginSource(); friend class Kst::ObjectStore; }; class SamplePlugin : public QObject, public Kst::DataObjectPluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataObjectPluginInterface) public: virtual ~SamplePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual DataObjectPluginInterface::PluginTypeID pluginType() const { return Generic; } virtual bool hasConfigWidget() const { return true; } virtual Kst::DataObject *create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs = true) const; virtual Kst::DataObjectConfigWidget *configWidget(QSettings *settingsObject) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/sampleplugin/sampleplugin.cpp000644 001750 001750 00000025514 11544160207 023054 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "sampleplugin.h" #include "objectstore.h" #include "ui_samplepluginconfig.h" static const QString& VECTOR_IN = "Vector In"; static const QString& SCALAR_IN = "Scalar In"; static const QString& STRING_IN = "String In"; static const QString& VECTOR_OUT = "Vector Out"; static const QString& SCALAR_OUT = "Scalar Out"; static const QString& STRING_OUT = "String Out"; /********************** ConfigWidgetSamplePlugin - This class defines the config widget that will be added to the BasicPluginDialog container for configuring the plugin. By default the BasicPluginDialog has no controls and thus all desired inputs/outputs/options should included in the .ui. DataObjectConfigWidget is defined in dataobject.h ***********************/ class ConfigWidgetSamplePlugin : public Kst::DataObjectConfigWidget, public Ui_SamplePluginConfig { public: ConfigWidgetSamplePlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_SamplePluginConfig() { setupUi(this); } ~ConfigWidgetSamplePlugin() {} void setObjectStore(Kst::ObjectStore* store) { // _store must be set here. Any additional controls requiring the objectstore should also // have it set at this time. _store = store; _vector->setObjectStore(store); } void setupSlots(QWidget* dialog) { if (dialog) { // In order to for Apply button logic to function. All controls change state must be linked to // the dialog's modified signal. connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); } } // All information in the config widget must be publically accessible so that the plugin can pull // the required information and use it construct the object. Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; // This function is required and is used when editing of the object is triggered. It must be able // to configure the widget with the settings currently in use by the object. virtual void setupFromObject(Kst::Object* dataObject) { if (SamplePluginSource* source = static_cast(dataObject)) { setSelectedVector(source->vector()); } } // This function is used when loading a .kst file from disk. The plugins are expected to store any // required parameters as attributes of the plugin tag. The name and type are handled by BasicPluginFactory // as are all inputs and outputs. This should be used for any non-generic attributes associated with the plugin. // If false is returned, the creation of the object will not occur. // NOTE: Saving of the object is done in the objects saveProperties function. Values must match between them. virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { Q_UNUSED(store); Q_UNUSED(attrs); bool validTag = true; // QStringRef av; // av = attrs.value("value"); // if (!av.isNull()) { // _configValue = QVariant(av.toString()).toBool(); // } return validTag; } public slots: // Dialog Defaults control - Save // Uses the provided QSettings Object to save the plugin default details as a new group. // Called everytime a new dialog request is made. Does not affect editing. virtual void save() { if (_cfg) { _cfg->beginGroup("Sample DataObject Plugin"); _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); _cfg->endGroup(); } } // Dialog Defaults control - Load // Uses the provided QSettings Object to load the plugin default details. // Called everytime a new dialog request is completed. Does not get called on edit. virtual void load() { if (_cfg && _store) { _cfg->beginGroup("Sample DataObject Plugin"); QString vectorName = _cfg->value("Input Vector").toString(); Kst::Object* object = _store->retrieveObject(vectorName); Kst::Vector* vector = static_cast(object); if (vector) { setSelectedVector(vector); } _cfg->endGroup(); } } private: Kst::ObjectStore *_store; }; /********************** SamplePluginSource - This class defines the main DataObject which derives from BasicPlugin (a DataObject). The key functions that this class must provide is the ability to create/modify the object, setup outputs, and be able to process the data (algorithm function). ***********************/ SamplePluginSource::SamplePluginSource(Kst::ObjectStore *store) : Kst::BasicPlugin(store) { } SamplePluginSource::~SamplePluginSource() { } QString SamplePluginSource::_automaticDescriptiveName() const { return QString("Test Plugin Object"); } // Change is used to configure the DataObject and will be run immediately after initial creation as well as // when modifications have occured. void SamplePluginSource::change(Kst::DataObjectConfigWidget *configWidget) { if (ConfigWidgetSamplePlugin* config = static_cast(configWidget)) { setInputVector(VECTOR_IN, config->selectedVector()); } } void SamplePluginSource::setupOutputs() { setOutputVector(VECTOR_OUT, ""); } // The algorithm function must handle all the data calculations for the plugin. This function is run during // each update of the input objects which includes after creation of the object. Only output objects that have // have setOutputVector/setOutputScalar/setOutputString should be updated as others will not appear outside of // the plugin. bool SamplePluginSource::algorithm() { Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; outputVector->resize(inputVector->length(), false); // Sample only. Copy all values from input vector to output vector. for (int i = 0; i < inputVector->length(); i++) { outputVector->value()[i] = inputVector->value(i); } // Return true to continue update. Returning false indicates that the update did not result in the output // objects changing and will not trigger updates of objects using them. return true; } Kst::VectorPtr SamplePluginSource::vector() const { return _inputVectors[VECTOR_IN]; } QStringList SamplePluginSource::inputVectorList() const { return QStringList( VECTOR_IN ); } QStringList SamplePluginSource::inputScalarList() const { return QStringList( /*SCALAR_IN*/ ); } QStringList SamplePluginSource::inputStringList() const { return QStringList( /*STRING_IN*/ ); } QStringList SamplePluginSource::outputVectorList() const { return QStringList( VECTOR_OUT ); } QStringList SamplePluginSource::outputScalarList() const { return QStringList( /*SCALAR_OUT*/ ); } QStringList SamplePluginSource::outputStringList() const { return QStringList( /*STRING_OUT*/ ); } // This function allows for support of saving / loading this object from a .kst file. The function should only // write attributes as any other advancement of the StreamWriter will result in a malformed Xml document. All // values required to recreate the should be saved here. All Input/Output Objects are saved by BasicPlugin and do // not need to be stored here. This should be used for any non-generic attributes associated with the plugin. // NOTE: Loading of the object is done in the configWidgets configurePropertiesFromXml function. Values must match between them. void SamplePluginSource::saveProperties(QXmlStreamWriter &s) { Q_UNUSED(s); // s.writeAttribute("value", _configValue); } // Name used to identify the plugin. Used when loading the plugin. QString SamplePlugin::pluginName() const { return "Sample DataObject Plugin"; } QString SamplePlugin::pluginDescription() const { return "Sample DataObject Plugin Description"; } /********************** SamplePlugin - This class defines the plugin interface to the DataObject defined by the plugin. The primary requirements of this class are to provide the necessary connections to create the object which includes providing access to the configuration widget. ***********************/ // The create function is responsible for creating the DataObject. It is provided the ObjectStore as well as a // fully configured configWidget to setup the object from. // setupInputOutputs is a flag to mark whether the object should automatically setup the inputs and outputs. New // creations will always configure them. When loading from a .kst file they will be done manually. Kst::DataObject *SamplePlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { if (ConfigWidgetSamplePlugin* config = static_cast(configWidget)) { // Create a generic object. SamplePluginSource* object = store->createObject(); // Setup the object values based on the config widget. // object->setValue(config->value()); // If the inputs/outputs should be configured, setup them up from the configWidget. if (setupInputsOutputs) { object->setInputVector(VECTOR_IN, config->selectedVector()); object->setupOutputs(); } // Set the pluginName. object->setPluginName(pluginName()); // Trigger an update of the object. This is required to trigger the algorithm call and creation of the output. // If inputs/outputs was not triggered, this will also be run a second time after all inputs/outputs have been // configured. object->writeLock(); object->registerChange(); object->unlock(); return object; } return 0; } // Request for this plugins configuration widget. Kst::DataObjectConfigWidget *SamplePlugin::configWidget(QSettings *settingsObject) const { ConfigWidgetSamplePlugin *widget = new ConfigWidgetSamplePlugin(settingsObject); return widget; } Q_EXPORT_PLUGIN2(kstplugin_sampleplugin, SamplePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/plugins/sampleplugin/kstplugin_sampleplugin.desktop000644 001750 001750 00000000401 11544160207 026027 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=sampleplugin X-Kst-Plugin-Author=The University of Toronto Name=Sample Data Object Plugin Comment=Implements a sample Data Object Plugin for Kst. kst-2.0.3/src/plugins/sampleplugin/samplepluginconfig.ui000644 001750 001750 00000003056 11544160207 024072 0ustar00synthsynth000000 000000 SamplePluginConfig 0 0 425 50 400 0 0 0 Sample Input Vector false 0 0 Kst::VectorSelector QWidget
    vectorselector.h
    kst-2.0.3/src/plugins/sampleplugin/sampleplugin.pro000644 001750 001750 00000000370 11544160207 023063 0ustar00synthsynth000000 000000 TOPOUT_REL=../../.. include($$PWD/$$TOPOUT_REL/kst.pri) include($$PWD/$$TOPOUT_REL/dataobjectplugin.pri) TARGET = $$kstlib(kstplugin_sampleplugin) SOURCES += \ sampleplugin.cpp HEADERS += \ sampleplugin.h FORMS += samplepluginconfig.ui kst-2.0.3/src/datasources/datasources.pro000644 001750 001750 00000000706 11544160207 021037 0ustar00synthsynth000000 000000 include($$PWD/../../config.pri) TEMPLATE = subdirs CONFIG += ordered SUBDIRS += \ ascii \ qimagesource \ sampledatasource LibExists(cfitsio) { message(CFITSIO configured. Plugins will be built.) SUBDIRS += fitsimage } LibExists(getdata) { message(DIRFILE configured. Plugins will be built.) SUBDIRS += dirfilesource } LibExists(netcdf) { message(netCDF configured. Plugins will be built.) SUBDIRS += netcdf } kst-2.0.3/src/datasources/dirfilesource/dirfilesource.h000644 001750 001750 00000011503 11544160207 023644 0ustar00synthsynth000000 000000 /*************************************************************************** dirfile.h - data source plugin for dirfiles ------------------- begin : Tue Oct 21 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DIRFILE_H #define DIRFILE_H #include #include #include using namespace GetData; class QFileSystemWatcher; class DataInterfaceDirFileVector; class DirFileSource : public Kst::DataSource { Q_OBJECT public: DirFileSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e); ~DirFileSource(); bool init(); virtual UpdateType internalDataSourceUpdate(); int readField(double *v, const QString &field, int s, int n); // int writeField(const double *v, const QString &field, int s, int n); int samplesPerFrame(const QString &field); int frameCount(const QString& field = QString()) const; QString fileType() const; void save(QXmlStreamWriter &streamWriter); bool isEmpty() const; virtual void reset(); class Config; int readScalar(double &S, const QString& scalar); int readString(QString &S, const QString& string); virtual QStringList fieldScalars(const QString& field); virtual int readFieldScalars(QList &v, const QString& field, bool init); virtual QStringList fieldStrings(const QString& field); virtual int readFieldStrings(QStringList &v, const QString& field, bool init); virtual const QString& typeString() const; //static const QString staticTypeString; //static const QString staticTypeTag; private: QString _directoryName; Dirfile *_dirfile; QStringList _scalarList; QStringList _stringList; QStringList _fieldList; int _frameCount; mutable Config *_config; DataInterfaceDirFileVector* iv; // TODO remove friend class DataInterfaceDirFileVector; }; class DirFilePlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~DirFilePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return false; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; static QString getDirectory(QString filepath); virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/dirfilesource/kstdata_dirfilesource.desktop000644 001750 001750 00000006060 11544160207 026603 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=dirfilesource X-Kst-Plugin-Author=The University of Toronto Name=DirFile Reader Name[bs]=DirFile čitač Name[ca]=Lector de DirFile Name[cs]=DirFile čtečka Name[da]=DirFile-læser Name[de]=DirFile-Betrachter Name[el]=Αναγνώστης DirFile Name[es]=Lector de DirFile Name[et]=Kataloogifaili lugeja Name[fr]=Lecteur DirFile Name[ga]=Léitheoir DirFile Name[gl]=Leitor de DirFile Name[hi]=डिर-फाइल रीडर Name[hr]=DirFile čitač Name[hu]=DirFile-olvasó Name[is]=DirFile skráalesari Name[it]=Lettore DirFile Name[ja]=DirFile リーダー Name[ka]=DirFile-ის წამკითხველი Name[nl]=Dirfile-leesprogramma Name[pa]=ਡਾਇਰੈ ਫਾਇਲ ਰੀਡਰ Name[pt]=Leitor de DirFile Name[pt_BR]=Leitor de DirFile Name[sr]=Читач за DirFile Name[sr@Latn]=Čitač za DirFile Name[sv]=Dirfile-läsare Name[ta]=டிஐஆர்கோப்புப் படித்தல் Name[tg]=Хонандаи Файли Dir Name[tr]=DizinDosya Okuyucu Name[vi]=Bộ xem tập tin DirFile Name[xx]=xxDirFile Readerxx Name[zh_CN]=目录文件阅读器 Comment=Plugin to read the dirfile format. Comment[bs]=Dodatak za čitanje dirfile formata. Comment[ca]=Connector per a llegir el format dirfile. Comment[cs]=Modul pro čtení formátu dirfile Comment[da]=Plugin til at læse dirfile-formatet. Comment[de]=Modul zum Lesen des dirfile-Formats Comment[el]=Πρόσθετο για την ανάγνωση της μορφής dirfile. Comment[es]=Plugin para leer el formato dirfile. Comment[et]=Plugin kataloogifailide (dirfile) vormingu lugemiseks. Comment[fr]=Module de lecture du format DirFile. Comment[ga]=Breiseán a léann an fhormáid dirfile. Comment[gl]=Un plugin para ler o formato dirfile. Comment[hi]=डिरफाइल फॉर्मेट पढ़ने हेतु प्लगइन Comment[hr]=Dodatak za čitanje oblika dirfile. Comment[hu]=Bővítőmodul Dirfile fájlok beolvasásához Comment[is]=Íforrit til að lesa dirfile snið. Comment[it]=Plugin per leggere il formato dirfile. Comment[ja]=dirfile フォーマットを読むためのプラグイン Comment[ka]= dirfile ფორმატის წამკითხველი მოდული. Comment[nl]=Plugin voor het lezen van het dirfile-formaat. Comment[pt]=Um 'plugin' para ler o formato 'dirfile'. Comment[pt_BR]=Plug-in para a leitura do formato dirfile. Comment[sr]=Прикључак за читање формата dirfile. Comment[sr@Latn]=Priključak za čitanje formata dirfile. Comment[sv]=Insticksprogram för att läsa dirfile-format. Comment[ta]=சொருகி டிஐஆர் கோப்பின் வடிவத்தைப் படிக்கவும் Comment[tg]=Модул барои хондани файли формати dir. Comment[tr]=Dizin dosya biçimi okuma eklentisi Comment[vi]=Bổ sung đọc định dạng dirfile. Comment[xx]=xxPlugin to read the dirfile format.xx Comment[zh_CN]=读取目录文件格式的插件 kst-2.0.3/src/datasources/dirfilesource/README000644 001750 001750 00000000302 11544160207 021507 0ustar00synthsynth000000 000000 Kst Data source for reading dirfiles using the getdata library Get and install getdata from http://getdata.sourceforge.net/ or this datasource won't build. Requires version 0.4.2 or better. kst-2.0.3/src/datasources/dirfilesource/dirfilesource.cpp000644 001750 001750 00000033563 11544160207 024211 0ustar00synthsynth000000 000000 /*************************************************************************** dirfile.cpp - data source for dirfiles ------------------- begin : Tue Oct 21 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dirfilesource.h" #include "kst_i18n.h" #include #include #include using namespace Kst; static const QString dirfileTypeString = I18N_NOOP("Directory of Binary Files"); class DirFileSource::Config { public: Config() { } void read(QSettings *cfg, const QString& fileName = QString()) { Q_UNUSED(fileName); cfg->beginGroup(dirfileTypeString); cfg->endGroup(); } void save(QXmlStreamWriter& s) { Q_UNUSED(s); } void load(const QDomElement& e) { Q_UNUSED(e); } }; // // Vector interface // class DataInterfaceDirFileVector : public DataSource::DataInterface { public: DataInterfaceDirFileVector(DirFileSource& d) : dir(d) {} // read one element int read(const QString&, DataVector::ReadInfo&); // named elements QStringList list() const { return dir._fieldList; } bool isListComplete() const { return true; } bool isValid(const QString& field) const { return dir._fieldList.contains( field ); } // T specific const DataVector::DataInfo dataInfo(const QString&) const; void setDataInfo(const QString&, const DataVector::DataInfo&) {} // meta data QMap metaScalars(const QString&); QMap metaStrings(const QString&); DirFileSource& dir; }; const DataVector::DataInfo DataInterfaceDirFileVector::dataInfo(const QString &field) const { if (!dir._fieldList.contains(field)) return DataVector::DataInfo(); return DataVector::DataInfo(dir._frameCount, dir.samplesPerFrame(field)); } int DataInterfaceDirFileVector::read(const QString& field, DataVector::ReadInfo& p) { return dir.readField(p.data, field, p.startingFrame, p.numberOfFrames); } QMap DataInterfaceDirFileVector::metaScalars(const QString& field) { QStringList keys = dir.fieldScalars(field); QList values; int scalars = dir.readFieldScalars(values, field, true); QMap m; for (int i = 0; i < scalars; i++) { if (values.size() > i && keys.size() > i) m[keys.at(i)] = values.at(i); } return m; } QMap DataInterfaceDirFileVector::metaStrings(const QString& field) { QStringList keys = dir.fieldStrings(field); QStringList values; int strings = dir.readFieldStrings(values, field, true); QMap m; for (int i = 0; i < strings; i++) { if (values.size() > i && keys.size() > i) m[keys.at(i)] = values.at(i); } return m; } // // DirFileSource // DirFileSource::DirFileSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type), _config(0L), iv(new DataInterfaceDirFileVector(*this)) { setInterface(iv); setUpdateType(None); _valid = false; if (!type.isEmpty() && type != dirfileTypeString) { return; } _config = new DirFileSource::Config; _config->read(cfg, _filename); if (!e.isNull()) { _config->load(e); } _valid = true; _directoryName = DirFilePlugin::getDirectory(_filename); init(); registerChange(); } DirFileSource::~DirFileSource() { delete _config; _config = 0L; delete _dirfile; _dirfile = 0L; } void DirFileSource::reset() { resetFileWatcher(); if (_dirfile) { delete _dirfile; } init(); Object::reset(); } bool DirFileSource::init() { _fieldList.clear(); _scalarList.clear(); _stringList.clear(); _frameCount = 0; _dirfile = new Dirfile(_directoryName.toLatin1(), GD_RDONLY); if (_dirfile->Error() == GD_E_OK) { const char **vl = _dirfile->VectorList(); for (int i = 0; vl[i]!=NULL; i++) { _fieldList.append(QString::fromUtf8(vl[i])); } _scalarList.append("FRAMES"); const char **xl = _dirfile->FieldListByType(ConstEntryType); for (int i = 0; xl[i]!=NULL; i++) { _scalarList.append(QString::fromUtf8(xl[i])); } _stringList.append("FILE"); const char **tl = _dirfile->FieldListByType(StringEntryType); for (int i = 0; tl[i]!=NULL; i++) { _stringList.append(QString::fromUtf8(tl[i])); } _writable = true; _frameCount = _dirfile->NFrames(); } if (_fieldList.count() > 1) { QString filePath = _dirfile->ReferenceFilename(); //setUpdateType(File, filePath); } setUpdateType(Timer); registerChange(); return true; } Kst::Object::UpdateType DirFileSource::internalDataSourceUpdate() { int newNF = _dirfile->NFrames(); bool isnew = newNF != _frameCount; bool isNewFile = (_frameCount>newNF); _frameCount = newNF; if (isNewFile) { reset(); } return (isnew ? Updated : NoChange); } int DirFileSource::readField(double *v, const QString& field, int s, int n) { if (n < 0) { return _dirfile->GetData(field.toUtf8().constData(), s, 0, /* 1st sframe, 1st samp */ 0, 1, /* num sframes, num samps */ Float64, (void*)v); } else { return _dirfile->GetData(field.toUtf8().constData(), s, 0, /* 1st sframe, 1st samp */ n, 0, /* num sframes, num samps */ Float64, (void*)v); } } // int DirFileSource::writeField(const double *v, const QString& field, int s, int n) { // int err = 0; // // return PutData(_directoryName.toLatin1(), field.left(FIELD_LENGTH).toLatin1(), // s, 0, /* 1st sframe, 1st samp */ // n, 0, /* num sframes, num samps */ // 'd', (void*)v, // &err); // } int DirFileSource::samplesPerFrame(const QString &field) { return int(_dirfile->SamplesPerFrame(field.toUtf8().constData())); } int DirFileSource::frameCount(const QString& field) const { Q_UNUSED(field) return _frameCount; } bool DirFileSource::isEmpty() const { return _frameCount < 1; } QString DirFileSource::fileType() const { return dirfileTypeString; } void DirFileSource::save(QXmlStreamWriter &streamWriter) { Kst::DataSource::save(streamWriter); } int DirFileSource::readScalar(double &S, const QString& scalar) { if (scalar == "FRAMES") { S = _frameCount; return 1; } else { _dirfile->GetConstant(scalar.toUtf8().constData(), Float64, (void *)&S); if (_dirfile->Error() == GD_E_OK) { return 1; } } return 0; } int DirFileSource::readString(QString &S, const QString& string) { if (string == "FILE") { S = _filename; return 1; } else { char tmpstr[4097]; _dirfile->GetString(string.toUtf8().constData(), 4097, tmpstr); if (_dirfile->Error() == GD_E_OK) { S = QString::fromUtf8(tmpstr); return 1; } } return 0; } //QStringList fieldScalars(const QString& field); QStringList DirFileSource::fieldScalars(const QString& field) { const char **mflist = _dirfile->MFieldListByType(field.toAscii(), ConstEntryType); if (!mflist) { return QStringList(); } QStringList scalars; for (int i=0; mflist[i]; i++) { scalars.append(mflist[i]); } return scalars; } int DirFileSource::readFieldScalars(QList &v, const QString& field, bool init) { int nc=0; if (init) { // only update if we need to initialize. Otherwise preserve old values. v.clear(); nc = _dirfile->NMFieldsByType(field.toAscii(),ConstEntryType); double *vin = (double *)_dirfile->MConstants(field.toAscii(), Float64); for (int i=0; iMFieldListByType(field.toAscii(), StringEntryType); if (!mflist) { return QStringList(); } QStringList strings; for (int i=0; mflist[i]; i++) { strings.append(mflist[i]); } return strings; } int DirFileSource::readFieldStrings(QStringList &v, const QString& field, bool init) { int nc=0; if (init) { // only update if we need to initialize. Otherwise preserve old values. v.clear(); nc = _dirfile->NMFieldsByType(field.toAscii(),StringEntryType); char **str_in = (char **)_dirfile->MStrings(field.toAscii()); for (int i=0; i #include #include #include "kst_i18n.h" using namespace Kst; static const QString fitsTypeString = I18N_NOOP("FITS image"); static const QString DefaultMatrixName = I18N_NOOP("1"); class FitsImageSource::Config { public: Config() { } void read(QSettings *cfg, const QString& fileName = QString()) { Q_UNUSED(fileName); cfg->beginGroup(fitsTypeString); cfg->endGroup(); } void save(QXmlStreamWriter& s) { Q_UNUSED(s); } void load(const QDomElement& e) { Q_UNUSED(e); } }; // // String interface // class DataInterfaceFitsImageString : public DataSource::DataInterface { public: DataInterfaceFitsImageString(FitsImageSource& s) : source(s) {} // read one element int read(const QString&, DataString::ReadInfo&); // named elements QStringList list() const { return source._strings.keys(); } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataString::DataInfo dataInfo(const QString&) const { return DataString::DataInfo(); } void setDataInfo(const QString&, const DataString::DataInfo&) {} // meta data QMap metaScalars(const QString&) { return QMap(); } QMap metaStrings(const QString&) { return QMap(); } private: FitsImageSource& source; }; //------------------------------------------------------------------------------------------- int DataInterfaceFitsImageString::read(const QString& string, DataString::ReadInfo& p) { // TODO read strings from file if (isValid(string) && p.value) { *p.value = source._strings[string]; return 1; } return 0; } //------------------------------------------------------------------------------------------- bool DataInterfaceFitsImageString::isValid(const QString& string) const { // TODO read strings from file return source._strings.contains( string ); } // // Matrix interface // class DataInterfaceFitsImageMatrix : public DataSource::DataInterface { public: DataInterfaceFitsImageMatrix(fitsfile **fitsfileptr) : _fitsfileptr(fitsfileptr) {} // read one element int read(const QString&, DataMatrix::ReadInfo&); // named elements QStringList list() const { return _matrixHash.keys(); } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataMatrix::DataInfo dataInfo(const QString&) const; void setDataInfo(const QString&, const DataMatrix::DataInfo&) {} // meta data QMap metaScalars(const QString &m); QMap metaStrings(const QString &m); // no interface fitsfile **_fitsfileptr; QHash _matrixHash; void init(); void clear(); }; void DataInterfaceFitsImageMatrix::clear() { _matrixHash.clear(); } void DataInterfaceFitsImageMatrix::init() { int hdu; int nhdu; int status=0; int type; QString name; char instr[32]; char tmpstr[1024]; fits_get_hdu_num(*_fitsfileptr, &hdu); _matrixHash.insert(DefaultMatrixName, hdu); fits_get_num_hdus(*_fitsfileptr, &nhdu, &status); for (hdu = 1; hdu <= nhdu; ++hdu) { fits_movabs_hdu(*_fitsfileptr, hdu, &type, &status); fits_get_hdu_type(*_fitsfileptr, &type, &status); if (type == IMAGE_HDU) { fits_read_key_str(*_fitsfileptr, "EXTNAME", instr, tmpstr, &status); if (status) { name = QString("HDU%1").arg(hdu); } else { name = QString(instr).trimmed(); } _matrixHash.insert(name, hdu); } } } const DataMatrix::DataInfo DataInterfaceFitsImageMatrix::dataInfo(const QString& matrix) const { long n_axes[3]; int status = 0; int type; if ( !*_fitsfileptr || !_matrixHash.contains( matrix ) ) { return DataMatrix::DataInfo(); } fits_movabs_hdu(*_fitsfileptr, _matrixHash[matrix], &type, &status); fits_get_img_size( *_fitsfileptr, 2, n_axes, &status ); if (status) { return DataMatrix::DataInfo(); } DataMatrix::DataInfo info; info.samplesPerFrame = 1; info.xSize = n_axes[0]; info.ySize = n_axes[1]; char charCDelt1[] = "CDELT1"; char charCDelt2[] = "CDELT2"; double dx,dy; fits_read_key(*_fitsfileptr, TDOUBLE, charCDelt1, &dx, NULL, &status); fits_read_key(*_fitsfileptr, TDOUBLE, charCDelt2, &dy, NULL, &status); if (!status) { info.invertXHint = (dx<0); info.invertYHint = (dy<0); } return info; } QMap DataInterfaceFitsImageMatrix::metaScalars(const QString &matrix) { qDebug() << "metascalars for " << matrix; QMap M; return M; } QMap DataInterfaceFitsImageMatrix::metaStrings(const QString &matrix) { QMap M; int status = 0; int type; char instr[128]; M.clear(); if ( !*_fitsfileptr || !_matrixHash.contains( matrix ) ) { return M; } fits_movabs_hdu(*_fitsfileptr, _matrixHash[matrix], &type, &status); fits_read_key(*_fitsfileptr, TSTRING, "CTYPE1", instr, NULL, &status); if (!status) { M.insert("x_quantity", QString(instr).trimmed()); } status = 0; fits_read_key(*_fitsfileptr, TSTRING, "CTYPE2", instr, NULL, &status); if (!status) { M.insert("y_quantity", QString(instr).trimmed()); } status = 0; fits_read_key(*_fitsfileptr, TSTRING, "CRUNIT1", instr, NULL, &status); if (!status) { M.insert("x_units", QString(instr).trimmed()); } status = 0; fits_read_key(*_fitsfileptr, TSTRING, "CRUNIT2", instr, NULL, &status); if (!status) { M.insert("y_units", QString(instr).trimmed()); } status = 0; fits_read_key(*_fitsfileptr, TSTRING, "BUNIT", instr, NULL, &status); if (!status) { M.insert("z_units", QString(instr).trimmed()); } status = 0; return M; } int DataInterfaceFitsImageMatrix::read(const QString& field, DataMatrix::ReadInfo& p) { long n_axes[2], fpixel[2] = {1, 1}; double nullval = NAN; double blank = 0.0; long n_elements; int px, py, anynull; int status = 0, type; double *buffer; if ((!*_fitsfileptr) || (!_matrixHash.contains(field))) { return 0; } fits_movabs_hdu(*_fitsfileptr, _matrixHash[field], &type, &status); fits_get_img_size( *_fitsfileptr, 2, n_axes, &status ); if (status) { return 0; } n_elements = n_axes[0]*n_axes[1]; buffer = (double*)malloc(n_elements*sizeof(double)); fits_read_pix( *_fitsfileptr, TDOUBLE, fpixel, n_elements, &nullval, buffer, &anynull, &status ); // Check to see if the file is using the BLANK keyword // to indicate the NULL value for the image. This is // not correct useage for floating point images, but // it is used frequently nonetheless... char charBlank[] = "BLANK"; fits_read_key(*_fitsfileptr, TDOUBLE, charBlank, &blank, NULL, &status); if (status) { //keyword does not exist, ignore it status = 0; } else { //keyword is used, replace pixels with this value double epsilon = fabs(1e-4 * blank); for (long j = 0; j < n_elements; j++) { if (fabs(buffer[j]-blank) < epsilon) { buffer[j] = NAN; } } } int y0 = p.yStart; int y1 = p.yStart + p.yNumSteps; int x0 = p.xStart; int x1 = p.xStart + p.xNumSteps; double* z = p.data->z; int ni = p.xNumSteps * p.yNumSteps - 1; // set the suggested matrix transform params: pixel index.... double x, y, dx, dy, cx, cy; char charCRVal1[] = "CRVAL1"; char charCRVal2[] = "CRVAL2"; char charCDelt1[] = "CDELT1"; char charCDelt2[] = "CDELT2"; char charCRPix1[] = "CRPIX1"; char charCRPix2[] = "CRPIX2"; fits_read_key(*_fitsfileptr, TDOUBLE, charCRVal1, &x, NULL, &status); fits_read_key(*_fitsfileptr, TDOUBLE, charCRVal2, &y, NULL, &status); fits_read_key(*_fitsfileptr, TDOUBLE, charCDelt1, &dx, NULL, &status); fits_read_key(*_fitsfileptr, TDOUBLE, charCDelt2, &dy, NULL, &status); fits_read_key(*_fitsfileptr, TDOUBLE, charCRPix1, &cx, NULL, &status); fits_read_key(*_fitsfileptr, TDOUBLE, charCRPix2, &cy, NULL, &status); int i = 0; if ((dx<0) && (dy>0)) { for (px = p.xStart; px < x1; px++) { for (py = y1-1; py >= p.yStart; py--) { z[ni - i] = buffer[px + py*n_axes[0]]; i++; } } } else if ((dx>0) && (dy>0)) { for (px = x1-1; px >= p.xStart; px--) { for (py = y1-1; py >= p.yStart; py--) { z[ni - i] = buffer[px + py*n_axes[0]]; i++; } } } else if ((dx>0) && (dy<0)) { for (px = x1-1; px >= p.xStart; px--) { for (py = p.yStart; py < y1; py++) { z[ni - i] = buffer[px + py*n_axes[0]]; i++; } } } else if ((dx<0) && (dy<0)) { for (px = p.xStart; px < x1; px++) { for (py = p.yStart; py < y1; py++) { z[ni - i] = buffer[px + py*n_axes[0]]; i++; } } } free(buffer); if (status) { p.data->xMin = x0; p.data->yMin = y0; p.data->xStepSize = 1; p.data->yStepSize = 1; } else { dx = fabs(dx); dy = fabs(dy); p.data->xStepSize = dx; p.data->yStepSize = dy; p.data->xMin = x - cx*dx; p.data->yMin = y - cy*dy; } return(i); } bool DataInterfaceFitsImageMatrix::isValid(const QString& field) const { return _matrixHash.contains( field ); } FitsImageSource::FitsImageSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type), _config(0L), is(new DataInterfaceFitsImageString(*this)), im(new DataInterfaceFitsImageMatrix(&_fptr)) { setInterface(is); setInterface(im); setUpdateType(None); _fptr = 0L; _valid = false; if (!type.isEmpty() && type != fitsTypeString) { return; } _config = new FitsImageSource::Config; _config->read(cfg, filename); if (!e.isNull()) { _config->load(e); } if (init()) { _valid = true; } registerChange(); } FitsImageSource::~FitsImageSource() { int status = 0; if (_fptr) { fits_close_file( _fptr, &status ); _fptr = 0L; } delete _config; _config = 0L; } const QString& FitsImageSource::typeString() const { return fitsTypeString; } void FitsImageSource::reset() { init(); Object::reset(); } bool FitsImageSource::init() { int status = 0; fits_open_image( &_fptr, _filename.toAscii(), READONLY, &status ); im->clear(); _strings = fileMetas(); if (status == 0) { im->init(); registerChange(); return true; } else { fits_close_file( _fptr, &status ); _fptr = 0L; return false; } } Kst::Object::UpdateType FitsImageSource::internalDataSourceUpdate() { return (Kst::Object::NoChange); } bool FitsImageSource::isEmpty() const { return im->dataInfo(DefaultMatrixName).xSize < 1; } QString FitsImageSource::fileType() const { return fitsTypeString; } void FitsImageSource::save(QXmlStreamWriter &streamWriter) { Kst::DataSource::save(streamWriter); } QString FitsImagePlugin::pluginName() const { return "FITS Image Source Reader"; } QString FitsImagePlugin::pluginDescription() const { return "FITS Image Source Reader"; } Kst::DataSource *FitsImagePlugin::create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const { return new FitsImageSource(store, cfg, filename, type, element); } QStringList FitsImagePlugin::matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(type) QStringList matrixList; if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = fitsTypeString; } if ( understands(cfg, filename) ) { fitsfile* ffits; int status = 0; int hdu; int nhdu; int type; QString name; char instr[32]; char tmpstr[1024]; fits_open_image( &ffits, filename.toAscii(), READONLY, &status ); matrixList.append( DefaultMatrixName ); fits_get_num_hdus(ffits, &nhdu, &status); for (hdu = 1; hdu <= nhdu; ++hdu) { fits_movabs_hdu(ffits, hdu, &type, &status); fits_get_hdu_type(ffits, &type, &status); if (type == IMAGE_HDU) { fits_read_key_str(ffits, "EXTNAME", instr, tmpstr, &status); if (status) { name = QString("HDU%1").arg(hdu); } else { name = QString(instr).trimmed(); } matrixList.append(name); } } fits_close_file( ffits , &status ); } return matrixList; } QStringList FitsImagePlugin::scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList scalarList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = fitsTypeString; } scalarList.append("FRAMES"); return scalarList; } QStringList FitsImagePlugin::stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList stringList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = fitsTypeString; } stringList.append("FILENAME"); return stringList; } QStringList FitsImagePlugin::fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(type) Q_UNUSED(cfg) Q_UNUSED(filename) QStringList fieldList; if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = fitsTypeString; } return fieldList; } int FitsImagePlugin::understands(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) fitsfile* ffits; int status = 0; int ret_val = 0; int naxis; fits_open_image( &ffits, filename.toAscii(), READONLY, &status ); fits_get_img_dim( ffits, &naxis, &status); if ((status == 0) && (naxis > 1)) { ret_val = 95; } else { ret_val = 0; } // status !=0 should prevent close from having trouble... fits_close_file( ffits , &status ); return ret_val; } bool FitsImagePlugin::supportsTime(QSettings *cfg, const QString& filename) const { //FIXME Q_UNUSED(cfg) Q_UNUSED(filename) return false; } QStringList FitsImagePlugin::provides() const { QStringList rc; rc += fitsTypeString; return rc; } Kst::DataSourceConfigWidget *FitsImagePlugin::configWidget(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) Q_UNUSED(filename) return 0;; } Q_EXPORT_PLUGIN2(kstdata_qimagesource, FitsImagePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/fitsimage/fitsimage.h000644 001750 001750 00000007506 11544160207 022076 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITSIMAGE_H #define FITSIMAGE_H #include #include //#include #include class DataInterfaceFitsImageMatrix; class DataInterfaceFitsImageString; class FitsImageSource : public Kst::DataSource { Q_OBJECT public: FitsImageSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e); ~FitsImageSource(); bool init(); virtual void reset(); Kst::Object::UpdateType internalDataSourceUpdate(); bool isEmpty() const; QString fileType() const; void save(QXmlStreamWriter &streamWriter); virtual const QString& typeString() const; class Config; private: int _frameCount; fitsfile *_fptr; mutable Config *_config; QMap _strings; DataInterfaceFitsImageString* is; DataInterfaceFitsImageMatrix* im; friend class DataInterfaceFitsImageString; }; class FitsImagePlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~FitsImagePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return false; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/fitsimage/kstdata_fitsimage.desktop000644 001750 001750 00000003335 11544160207 025027 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=fitsimage X-Kst-Plugin-Author=The University of Toronto Name=fitsimage Name[el]=εικόναfits Name[es]=Imagen FITS Name[gl]=fitsimaxe Name[it]=Immagini FITS Name[nl]=FITS-afbeelding Name[pt_BR]=Image fits Name[sv]=FITS-bild Name[tg]=fits-тасвир Name[xx]=xxfitsimagexx Comment=Plugin to read a FITS image. Comment[br]=Lugent evit lenn ur skeudenn FITS. Comment[ca]=Connector per llegir una imatge FITS. Comment[cs]=Modul pro čtení FITS obrázků. Comment[da]=Plugin til at læse et FITS-billede. Comment[de]=Modul zum Lesen von FITS-Bildern Comment[el]=Πρόσθετο για ανάγνωση μιας εικόνας FITS. Comment[es]=Plugin para leer una imagen en formato FITS. Comment[et]=Plugin FITS-piltide lugemiseks. Comment[ga]=Breiseán a léann íomhá FITS. Comment[gl]=Un plugin para ler unha imaxe FITS. Comment[hr]=Dodatak za čitanje FITS slika. Comment[is]=Íforrit til að lesa FITS myndskrár. Comment[it]=Plugin per leggere un'immagine FITS. Comment[ja]=FITS 画像を読むためのプラグイン Comment[ka]=FITS გამოსახულების წამკითხველი მოდული. Comment[nl]=Plugin voor het lezen van een FITS-afbeelding. Comment[pt]=Um 'plugin' para ler uma imagem FITS. Comment[pt_BR]=Plug-in para a leitura de uma imagem FITS. Comment[sr]=Прикључак за читање FITS слика. Comment[sr@Latn]=Priključak za čitanje FITS slika. Comment[sv]=Insticksprogram för att läsa en FITS-bild. Comment[tg]=Модул барои хондани тасвири FITS. Comment[vi]=Bổ sung đọc ảnh kiểu FITS. Comment[xx]=xxPlugin to read a FITS image.xx kst-2.0.3/src/datasources/lfiio/kstdata_lfiio.desktop000644 001750 001750 00000006555 11544160207 023322 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=lfiio X-Kst-Plugin-Author=The University of Toronto Name=LFIIO Reader Name[br]=Lenner LFIIO Name[ca]=Lector LFIIO Name[cs]=LFIIO čtečka Name[da]=LFIIO-læser Name[de]=LFIIO-Betrachter Name[el]=Αναγνώστης LFIIO Name[es]=Lector de LFIIO Name[et]=LFIIO lugeja Name[fr]=Lecteur LFIIO Name[ga]=Léitheoir LFIIO Name[gl]=Leitor da LFIIO Name[hi]=एलएफ़आईआईओ रीडर Name[hr]=LFIIO čitač Name[is]=LFIIO skráalesari Name[it]=Lettore LFIIO Name[ja]=LFIIO リーダー Name[ka]=LFIIO-ის წამკითხველი Name[nl]=LFIIO-leesprogramma Name[pa]=LFIIO ਰੀਡਰ Name[pt]=Leitor da LFIIO Name[pt_BR]=Leitor de LFIIO Name[sr]=LFIIO читач Name[sr@Latn]=LFIIO čitač Name[sv]=LFIIO-läsare Name[ta]=LFIIO படிப்பான் Name[tg]=Хонандаи LFIIO Name[tr]=LFIIO okuyucu Name[vi]=Bộ đọc LFIIO Name[xx]=xxLFIIO Readerxx Name[zh_CN]=LFIIO 阅读器 Comment=Implements support for reading FITS files into Kst. Comment[bs]=Implementira podršku za čitanje FITS datoteka u Kst. Comment[ca]=Implementa en Kst el funcionament per a llegir fitxers FITS. Comment[cs]=Podpora čtení FITS souborů pro Kst. Comment[da]=Implementerer støtte for at læse FITS-filer i Kst. Comment[de]=Unterstützung für das Einlesen von FITS-Dateien in Kst Comment[el]=Υλοποιεί την υποστήριξη για ανάγνωση αρχείων FITS στο Kst. Comment[es]=Implementa soporte para leer archivos FITS en Kst. Comment[et]=Kst FITS-failide lugemise toetus. Comment[fr]=Prise en charge de la lecture des fichiers FITS dans Kst. Comment[gl]=Permite a leitura de ficheiros FITS en Kst. Comment[hi]=केएसटी में एफ़आईटीएस फाइलें पढ़ने हेतु समर्थन इम्प्लीमेंट करता है. Comment[hr]=Implementira podršku za čitanje FITS datoteka u Kst. Comment[hu]=Lehetővé teszi FITS-fájlok beolvasását a Kst-be. Comment[is]=Gefur stuðning við lestur FITS skráa inn í Kst. Comment[it]=Implementa supporto per leggere file FITS in Kst. Comment[ja]=FITS ファイルの Kst への読み込みをサポート Comment[ka]=უზრუნველყოფს FITS ფაილების Kst-ში წაკითხვას. Comment[nl]=Implementeert de ondersteuning voor het inlezen van FITS-bestanden in Kst. Comment[pt]=Implementa o suporte para a leitura de ficheiros do FITS no Kst. Comment[pt_BR]=Implementa o suporte a leitura de arquivos FITS dentro do Kst. Comment[sr]=Имплементира подршку за читање FITS фајлова у Kst. Comment[sr@Latn]=Implementira podršku za čitanje FITS fajlova u Kst. Comment[sv]=Implementerar stöd för att läsa in FITS-filer i Kst. Comment[ta]=FITS கோப்பிலிருந்து Kstடிற்குச் செய்முறைப்படுத்தித் துணைப் படி. Comment[tg]=Иҷро намудани пуштибонӣ барои хондани файлҳои FITS ба Kst. Comment[tr]=Kst içine FITS dosyaları okuma desteği verenler Comment[vi]=Thực hiện vào Kst khả năng đọc các tập tin FITS. Comment[xx]=xxImplements support for reading FITS files into Kst.xx Comment[zh_CN]=将 FITS 文件读入 Kst. 的应用支持 kst-2.0.3/src/datasources/lfiio/lfiio.h000644 001750 001750 00000010206 11544160207 020351 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LFIIO_H #define LFIIO_H #include #include #include class LFIIOSource : public Kst::DataSource { Q_OBJECT public: LFIIOSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e); ~LFIIOSource(); bool init(); bool reset(); Kst::Object::UpdateType update(); int readField(double *v, const QString &field, int s, int n); bool isValidField(const QString &field) const; int samplesPerFrame(const QString &field); int frameCount(const QString& field = QString::null) const; bool isEmpty() const; QString fileType() const; void save(QXmlStreamWriter &streamWriter); class Config; int readScalar(double &S, const QString& scalar); int readString(QString &S, const QString& string); private: bool getColNumber(const QString& field, int* piColNumber) const; double _dTimeZero; double _dTimeDelta; bool _bHasTime; bool _first; int _numFrames; int _numCols; mutable Config *_config; QMap _metaData; }; class LFIIOPlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~LFIIOPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return false; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/lfiio/lfiio.cpp000644 001750 001750 00000042246 11544160207 020715 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "lfiio.h" #include //#include #include #define TIME_FIELD "TIME" #include "kst_i18n.h" static const QString lfiioTypeString = I18N_NOOP("LFIIO image"); class LFIIOSource::Config { public: Config() { } void read(QSettings *cfg, const QString& fileName = QString::null) { Q_UNUSED(fileName); cfg->beginGroup(lfiioTypeString); cfg->endGroup(); } void save(QXmlStreamWriter& s) { Q_UNUSED(s); } void load(const QDomElement& e) { Q_UNUSED(e); } }; LFIIOSource::LFIIOSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type, None), _config(0L) { _first = true; _valid = false; if (!type.isEmpty() && type != "LFIIO Image Source") { return; } _config = new LFIIOSource::Config; _config->read(cfg, filename); if (!e.isNull()) { _config->load(e); } if (init()) { _valid = true; } update(); } LFIIOSource::~LFIIOSource() { } bool LFIIOSource::reset() { init(); return true; } bool LFIIOSource::init() { Kst::Object::UpdateType updateType; bool bRetVal = false; int iResult = 0; _numFrames = 0; // read the metadata if (!_filename.isNull() && !_filename.isEmpty()) { QString str; fitsfile* ffits; int iStatus = 0; if (_first) { iResult = fits_open_table( &ffits, _filename.ascii(), READONLY, &iStatus ); if (iResult == 0) { int keysexist; int morekeys; iResult = fits_get_hdrspace( ffits, &keysexist, &morekeys, &iStatus ); if (iResult == 0) { char keyname[FLEN_KEYWORD]; char value[FLEN_VALUE]; char comment[FLEN_COMMENT]; int keynum; for (keynum = 1; keynum <= keysexist; ++keynum) { iResult = fits_read_keyn( ffits, keynum, keyname, value, comment, &iStatus ); if (iResult == 0) { str.sprintf("%s %s", value, comment); _metaData.insert(keyname, str); } } _first = false; } } } } updateType = update(); if(updateType == Kst::Object::UPDATE) { bRetVal = true; } return bRetVal; } Kst::Object::UpdateType LFIIOSource::update() { Kst::Object::UpdateType updateType = Kst::Object::NO_CHANGE; QString strTemplate; QString strName; fitsfile* ffits; char charTemplate[FLEN_CARD]; char charName[FLEN_CARD]; long lNumFrames; long lMaxRepeat = 1; long lRepeat; long lWidth; int iColNumber; int iNumCols; int iStatus = 0; int iResult = 0; int iTypeCode; int i; int newNF = 0; _valid = false; if(!_filename.isNull() && !_filename.isEmpty()) { iResult = fits_open_table( &ffits, _filename.ascii(), READONLY, &iStatus ); if(iResult == 0) { // determine size of data... iResult = fits_get_num_cols( ffits, &iNumCols, &iStatus ); if(iResult == 0) { iResult = fits_get_num_rows( ffits, &lNumFrames, &iStatus ); if(iResult == 0) { _fieldList.clear(); _fieldList.append("INDEX"); _valid = true; _bHasTime = false; // need to multiply lNumFrames by the maximum value of the vector repeat value... for(i = 0; i lMaxRepeat) { lMaxRepeat = lRepeat; } } } // check if we have a time field defined by the header keys TIMEZERO and DELTA_T. // If so then we create a new field called $TIME_FIELD, unless such a field already // exists, in which case we do nothing... char charTimeZero[] = "TIMEZERO"; iStatus = 0; iResult = fits_read_key( ffits, TDOUBLE, charTimeZero, &_dTimeZero, 0L, &iStatus ); if(iResult == 0) { char charTimeDelta[] = "DELTA_T"; iResult = fits_read_key( ffits, TDOUBLE, charTimeDelta, &_dTimeDelta, 0L, &iStatus ); if(iResult == 0) { if(_fieldList.find(QString(TIME_FIELD)) == _fieldList.end()) { _bHasTime = true; _fieldList.append(TIME_FIELD); } } } if(lNumFrames * lMaxRepeat != _numFrames) { _numCols = iNumCols; newNF = lNumFrames * lMaxRepeat; updateType = Kst::Object::UPDATE; } } } iStatus = 0; fits_close_file( ffits, &iStatus ); } } bool isnew = newNF != _numFrames; _numFrames = newNF; return (isnew ? Kst::Object::UPDATE : Kst::Object::NO_CHANGE); } int LFIIOSource::readField(double *v, const QString& field, int s, int n) { double dNan = strtod("nan", NULL); fitsfile* ffits; bool bOk; int i; int iCol; int iRead = -1; int iStatus = 0; int iAnyNull; int iResult = 0; if (n < 0) { n = 1; /* n < 0 means read one sample, not frame - irrelavent here */ } if (field == "INDEX") { for(i = 0; i < n; i++) { v[i] = (double)(s + i) ; } iRead = n; } else if (_bHasTime && field == TIME_FIELD) { for(i = 0; i < n; i++) { v[i] = _dTimeZero + ((double)(s + i) * _dTimeDelta); } iRead = n; } else { memset(v, 0, n * sizeof(double)); bOk = getColNumber(field, &iCol); if (bOk) { _valid = false; if (!_filename.isNull() && !_filename.isEmpty()) { iResult = fits_open_table( &ffits, _filename.ascii(), READONLY, &iStatus ); if (iResult == 0) { _valid = true; // copy the data... // N.B. fitsio column indices are 1 based, so we ask for iCol+1 instead of just iCol iResult = fits_read_col( ffits, TDOUBLE, iCol+1, s+1, 1, n, &dNan, v, &iAnyNull, &iStatus ); if (iResult == 0) { iRead = n; } iStatus = 0; fits_close_file( ffits, &iStatus ); } } } } return iRead; } bool LFIIOSource::getColNumber( const QString& field, int* piColNumber ) const { QString strName; bool bOk = false; bool bRetVal = false; int iCount; int iCol; int i; iCol = field.toUInt(&bOk); if (bOk) { if (iCol >= 0 && iCol < _numCols) { *piColNumber = iCol; bRetVal = true; } } else { iCount = _fieldList.count(); // start at 1, because the first entry is INDEX... for (i=1; i lMaxRepeat) { lMaxRepeat = lRepeat; } } } // Check if we have a time field defined by the header keys TIMEZERO and DELTA_T. // If so then we create a new field called $TIME_FIELD, unless such a field already // exists, in which case we do nothing... char charTimeZero[] = "TIMEZERO"; double timeZero; double timeDelta; iStatus = 0; iResult = fits_read_key( ffits, TDOUBLE, charTimeZero, &timeZero, 0L, &iStatus ); if (iResult == 0) { char charTimeDelta[] = "DELTA_T"; iResult = fits_read_key( ffits, TDOUBLE, charTimeDelta, &timeDelta, 0L, &iStatus ); if (iResult == 0) { if (fieldList.find(QString(TIME_FIELD)) == fieldList.end()) { hasTime = true; fieldList.append(TIME_FIELD); } } } } } iStatus = 0; fits_close_file( ffits, &iStatus ); } } return fieldList; } int LFIIOPlugin::understands(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) fitsfile* ffits; int iStatus = 0; int iRetVal = 0; // determine if it is a FITS file... if (fits_open_table( &ffits, filename.ascii(), READONLY, &iStatus ) == 0 ) { fits_close_file( ffits, &iStatus ); iRetVal = 90; } return iRetVal; } bool LFIIOPlugin::supportsTime(QSettings *cfg, const QString& filename) const { //FIXME Q_UNUSED(cfg) Q_UNUSED(filename) return true; } QStringList LFIIOPlugin::provides() const { QStringList rc; rc += "LFIIO Image Source"; return rc; } Kst::DataSourceConfigWidget *LFIIOPlugin::configWidget(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) Q_UNUSED(filename) return 0;; } Q_EXPORT_PLUGIN2(kstdata_qimagesource, LFIIOPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/lfiio/lfiio.pro000644 001750 001750 00000000360 11544160207 020722 0ustar00synthsynth000000 000000 include($$PWD/../../../kst.pri) include($$PWD/../../../datasourceplugin.pri) TARGET = $$kstlib(kst2data_lfiio) INCLUDEPATH += $$OUTPUT_DIR/src/datasources/lfiio/tmp LIBS += -lcfitsio SOURCES += \ lfiio.cpp HEADERS += \ lfiio.h kst-2.0.3/src/datasources/healpix/healpix_tools_pix.cpp000644 001750 001750 00000054201 11544160207 023667 0ustar00synthsynth000000 000000 /*************************************************************************** healpix_tools.cpp - tools for healpix datasource ------------------- begin : Wed June 01 2005 copyright : (C) 2005 Ted Kisner email : tskisner.public@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /*************************************************************************** * Some of these pixel tools are based on code from Healpix_cxx 2.00. * * See http://sourceforge.net/projects/healpix/ for the original code * * * * Healpix 2.00 was developed by by E. Hivon, M. Reinecke, W. O'Mullane, * * H.K. Eriksen, K.M. Gorski, A.J. Banday * ***************************************************************************/ #include "healpix_tools.h" #include #define HEALPIX_CHK if(!healpix_doneinit)healpix_init() static size_t healpix_ctab[0x100]; static size_t healpix_utab[0x100]; static const size_t healpix_jrll[] = {2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}; static const size_t healpix_jpll[] = {1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7}; static int healpix_doneinit = 0; void healpix_init(); /* NULL checking */ int healpix_is_dnull(double val) { if ((val > HEALPIX_NULL - HEALPIX_EPSILON) && (val < HEALPIX_NULL + HEALPIX_EPSILON)) { return 1; } else { return 0; } } int healpix_is_fnull(float val) { if ((val > HEALPIX_NULL - HEALPIX_EPSILON) && (val < HEALPIX_NULL + HEALPIX_EPSILON)) { return 1; } else { return 0; } } int healpix_is_inull(int val) { if (val == HEALPIX_INT_NULL) { return 1; } else { return 0; } } /* simple tools */ char **healpix_strarr_alloc(size_t nstring) { size_t i,j; char **array = NULL; if (nstring == 0) { return NULL; } array = (char **)calloc(nstring, sizeof(char *)); if (!array) { return NULL; } for (i = 0; i < nstring; i++) { array[i] = NULL; array[i] = (char *)calloc(HEALPIX_STRNL, sizeof(char)); if (!array[i]) { for (j = 0; j < i; j++) { free(array[j]); } free(array); return NULL; } } return array; } int healpix_strarr_free(char **array, size_t nstring) { size_t i; if ((array == NULL)||(nstring == 0)) { return 0; } for (i = 0; i < nstring; i++) { free(array[i]); } free(array); return 0; } int healpix_nsidecheck(size_t nside) { if (nside > HEALPIX_NSIDE_MAX) { return 1; } if (nside == 0) { return 1; } if (((~nside)&(nside-1)) != (nside-1)) { return 1; } return 0; } size_t healpix_npix2nside(size_t npix) { double fpix; int err; fpix = ((double)npix) / 12.0; fpix = sqrt(fpix); err = healpix_nsidecheck((size_t) fpix); if (err) { return 0; } return (size_t) fpix; } size_t healpix_nside2npix(size_t nside) { int err; err = healpix_nsidecheck(nside); if (err) { return 0; } return 12 * nside * nside; } size_t healpix_nside2factor(size_t nside) { int err; size_t factor = 0; err = healpix_nsidecheck(nside); if (err) { return 0; } while (nside != (1ul< HEALPIX_NSIDE_MAX) { return 0; } return nside; } /* initialization */ void healpix_init() { size_t m; QMutex tablock; tablock.lock(); for (m = 0; m < 0x100; m++) { healpix_ctab[m] = (m&0x1) | ((m&0x2) << 7) | ((m&0x4) >> 1) | ((m&0x8) << 6) | ((m&0x10) >> 2) | ((m&0x20) << 5) | ((m&0x40) >> 3) | ((m&0x80) << 4); healpix_utab[m] = (m&0x1) | ((m&0x2) << 1) | ((m&0x4) << 2) | ((m&0x8) << 3) | ((m&0x10) << 4) | ((m&0x20) << 5) | ((m&0x40) << 6) | ((m&0x80) << 7); } healpix_doneinit = 1; tablock.unlock(); return; } /* Definitions for 32bit pixel values. Note that */ /* HEALPIX_NSIDE_MAX must be <= 2^14 in order to have */ /* 12*nside^2 be < 2^32. */ int healpix_xy2pix(size_t x, size_t y, size_t *pix) { HEALPIX_CHK; (*pix) = healpix_utab[x&0xff] | (healpix_utab[x>>8]<<16) | (healpix_utab[y&0xff]<<1) | (healpix_utab[y>>8]<<17); return 0; } int healpix_x2pix(size_t x, size_t *pix) { HEALPIX_CHK; (*pix) = healpix_utab[x&0xff] | (healpix_utab[x>>8]<<16); return 0; } int healpix_y2pix(size_t y, size_t *pix) { HEALPIX_CHK; (*pix) = (healpix_utab[y&0xff]<<1) | (healpix_utab[y>>8]<<17); return 0; } int healpix_pix2xy(size_t pix, size_t *x, size_t *y) { size_t raw; HEALPIX_CHK; raw = (pix&0x5555) | ((pix&0x55550000)>>15); (*x) = healpix_ctab[raw&0xff] | (healpix_ctab[raw>>8]<<4); raw = ((pix&0xaaaa)>>1) | ((pix&0xaaaa0000)>>16); (*y) = healpix_ctab[raw&0xff] | (healpix_ctab[raw>>8]<<4); return 0; } /* low level pixel routines */ int healpix_nest2xyf (size_t nside, size_t pix, size_t *x, size_t *y, size_t *face_num) { int err; size_t factor = healpix_nside2factor(nside); (*face_num) = pix >> (2*factor); err = healpix_pix2xy(pix & (nside*nside-1), x, y); return err; } int healpix_xyf2nest (size_t nside, size_t x, size_t y, size_t face_num, size_t *pix) { int err; size_t factor = healpix_nside2factor(nside); err = healpix_xy2pix(x, y, pix); (*pix) += (face_num<<(2*factor)); return err; } int healpix_ring2xyf (size_t nside, size_t pix, size_t *x, size_t *y, size_t *face_num) { long iring, iphi, kshift, nr; long nl2 = 2 * nside; size_t ncap = 2 * (nside*nside - nside); long tmp, ip, ire, irm, ifm, ifp, irt, ipt; long factor = (long int)healpix_nside2factor(nside); long face; if (pix < ncap) { iring = (long)(0.5*(1.0+sqrt((double)(1+2*pix)))); iphi = (long)(pix+1) - 2*iring*(iring-1); kshift = 0; nr = iring; face = 0; tmp = iphi-1; if (tmp >= (2*iring)) { face = 2; tmp -= 2*iring; } if (tmp >= iring) { face++; } } else if (pix < (12*nside*nside - ncap)) { ip = (long)(pix - ncap); iring = (ip>>(factor+2)) + (long)nside; iphi = (ip&(4*(long)nside-1)) + 1; kshift = (iring+(long)nside)&1; nr = (long)nside; ire = iring - (long)nside + 1; irm = nl2+2-ire; ifm = (iphi - ire/2 + (long)nside - 1) >> factor; ifp = (iphi - irm/2 + (long)nside - 1) >> factor; if (ifp == ifm) /* faces 4 to 7 */ face = (ifp==4) ? 4 : ifp+4; else if (ifp < ifm) /* (half-)faces 0 to 3 */ face = ifp; else /* (half-)faces 8 to 11 */ face = ifm + 8; } else { ip = (long)(12*nside*nside - pix); iring = (long)(0.5*(1.0+sqrt((double)(2*ip-1)))); iphi = 4*iring + 1 - (ip - 2*iring*(iring-1)); kshift = 0; nr = iring; iring = 2*nl2-iring; face = 8; tmp = iphi-1; if (tmp >= (2*nr)) { face = 10; tmp -= 2*nr; } if (tmp >= nr) face++; } irt = iring - (long)(healpix_jrll[face]*nside) + 1; ipt = 2*iphi - (long)healpix_jpll[face]*nr - kshift -1; if (ipt >= nl2) ipt -= 8*nside; (*face_num) = face; (*x) = (size_t)((ipt-irt) >> 1); (*y) = (size_t)((-(ipt+irt)) >> 1); return 0; } int healpix_xyf2ring (size_t nside, size_t x, size_t y, size_t face_num, size_t *pix) { long nl4 = 4*(long)nside; long jr = (long)healpix_jrll[face_num]; long nr, kshift, n_before; long ncap = 2 * (long)(nside*nside - nside); long jp; jr = (jr*(long)nside) - (long)x - (long)y - 1; if (jr < (long)nside) { nr = jr; n_before = 2 * nr * (nr-1); kshift = 0; } else if (jr > (long)(3*nside)) { nr = nl4 - jr; n_before = (long)(12*nside*nside) - 2*(nr+1)*nr; kshift = 0; } else { nr = (long)nside; n_before = ncap + (jr - (long)nside)*nl4; kshift = (jr - (long)nside)&1; } jp = (long)((long)((long)healpix_jpll[face_num]*nr + (long)x - (long)y + 1 + kshift) / 2); if (jp > nl4) { jp -= nl4; } else { if (jp < 1) jp += nl4; } (*pix) = (size_t)(n_before + jp - 1); return 0; } /* slightly higher-level functions */ int healpix_nest2ring (size_t nside, size_t pnest, size_t *pring) { int err; size_t x, y, face_num; err = healpix_nsidecheck(nside); if (err) { return err; } if (pnest > (12 * nside * nside - 1)) { return 1; } err = healpix_nest2xyf(nside, pnest, &x, &y, &face_num); if (err) { return err; } err = healpix_xyf2ring(nside, x, y, face_num, pring); fflush(stdout); return err; } int healpix_ring2nest(size_t nside, size_t pring, size_t *pnest) { int err; size_t x, y, face_num; err = healpix_nsidecheck(nside); if (err) { return err; } if (pring > (12 * nside * nside - 1)) { return 1; } err = healpix_ring2xyf(nside, pring, &x, &y, &face_num); fflush(stdout); if (err) { return err; } err = healpix_xyf2nest(nside, x, y, face_num, pnest); fflush(stdout); return err; } // In normal healpix operations, we want to convert the angle // to a pixel value *at the maximum resolution*, and then degrade // this pixel number to the desired NSIDE. This ensures that // round-off error is consistent between different resolutions. // This is the method used in the HPIC library (for example). // For the purposes of display, we don't really care that much // about round-off error- we want speed. These functions do a // straight conversion to the desired NSIDE in order to eliminate // the need to do many degrade operations. int healpix_ang2pix_ring(size_t nside, double theta, double phi, size_t *pix) { double z = cos(theta); double za = fabs(z); double tt; double intpart; long longpart; double temp1, temp2; long jp, jm; long ip, ir, kshift; size_t ncap = 2 * (nside*nside - nside); double tp, tmp; while (phi < 0.0) { phi += 2.0 * HEALPIX_PI; } intpart = floor(phi / (2.0*HEALPIX_PI)); phi -= intpart; tt = 2.0 * phi / HEALPIX_PI; if (za <= (2.0/3.0)) { temp1 = (double)nside * (0.5+tt); temp2 = (double)nside * z * 0.75; jp = (long)(temp1 - temp2); /* index of ascending edge line */ jm = (long)(temp1 + temp2); /* index of descending edge line */ /* ring number counted from z=2/3 */ ir = nside + 1 + jp - jm; /* in {1,2n+1} */ kshift = 1 - (ir&1); /* kshift=1 if ir even, 0 otherwise */ ip = (long)((long)(jp + jm - nside + kshift + 1) / 2); /* in {0,4n-1} */ ip = ip % (long)(4*nside); (*pix) = ncap + (size_t)((ir-1) * 4 * nside + ip); } else { tp = tt - floor(tt); tmp = (double)(nside) * sqrt(3.0 * (1.0 - za)); jp = (long)(tp * tmp); /* increasing edge line index */ jm = (long)((1.0-tp)*tmp); /* decreasing edge line index */ ir = jp + jm + 1; /* ring number counted from the closest pole */ ip = (long)(tt * (double)ir); /* in {0,4*ir-1} */ longpart = (long)(ip / (4*ir)); ip -= longpart; if (z > 0.0) { (*pix) = (size_t)(2 * ir * (ir-1) + ip); } else { (*pix) = (size_t)((long)(12*nside*nside) - 2*ir*(ir+1) + ip); } } return 0; } int healpix_ang2pix_nest(size_t nside, double theta, double phi, size_t *pix) { double z = cos(theta); double za = fabs(z); double tt; double intpart; double temp1, temp2; long jp, jm; long face, x, y; long ifp, ifm, ntt; size_t sipf; size_t factor; int err; double tp, tmp; while (phi < 0.0) { phi += 2.0 * HEALPIX_PI; } intpart = floor(phi / (2.0*HEALPIX_PI)); phi -= intpart; tt = 2.0 * phi / HEALPIX_PI; factor = healpix_nside2factor(nside); if (za <= (2.0/3.0)) { temp1 = (double)nside * (0.5+tt); temp2 = (double)nside * z * 0.75; jp = (long)(temp1-temp2); /* index of ascending edge line */ jm = (long)(temp1+temp2); /* index of descending edge line */ ifp = jp >> factor; /* in {0,4} */ ifm = jm >> factor; if (ifp == ifm) { /* faces 4 to 7 */ face = (ifp==4) ? (long)4 : ifp+4; } else if (ifp < ifm) { /* (half-)faces 0 to 3 */ face = ifp; } else { /* (half-)faces 8 to 11 */ face = ifm + 8; } x = jm & (long)(nside-1); y = (long)nside - (jp & (long)(nside-1)) - 1; } else { ntt = (long)tt; tp = tt - (double)ntt; tmp = (double)nside * sqrt(3.0*(1.0-za)); jp = (long)(tp*tmp); /* increasing edge line index */ jm = (long)((1.0-tp)*tmp); /* decreasing edge line index */ if (jp >= (long)nside) { jp = (long)nside-1; /* for points too close to the boundary */ } if (jm >= (long)nside) { jm = (long)nside-1; } if (z >= 0) { face = ntt; /* in {0,3} */ x = nside - jm - 1; y = nside - jp - 1; } else { face = ntt + 8; /* in {8,11} */ x = jp; y = jm; } } err = healpix_xy2pix((size_t)x, (size_t)y, &sipf); if (err) { return err; } (*pix) = sipf + (size_t)(face << (2*factor)); return err; } int healpix_pix2ang_ring(size_t nside, size_t pix, double *theta, double *phi){ size_t ncap = 2 * (nside*nside - nside); long iring, iphi; long ip, nl2; double fodd; if (pix < ncap) { iring = (long)(0.5*(1.0+sqrt(1.0+2.0*(double)pix))); iphi = (long)(pix+1) - 2 * iring * (iring-1); (*theta) = acos(1.0 - (double)(iring*iring) / (double)(3*nside*nside)); (*phi) = ((double)iphi - 0.5) * HEALPIX_PI / (2.0 * (double)iring); } else if (pix < (12*nside*nside-ncap)) { ip = (long)pix - (long)ncap; iring = (long)(ip / (4*(long)nside)) + (long)nside; /* counted from North pole */ iphi = ip % (4*(long)nside) + 1; /* 1 if iring+nside is odd, 1/2 otherwise */ fodd = ((iring+(long)nside)&1) ? 1.0 : 0.5; nl2 = 2 * (long)nside; (*theta) = acos((double)(nl2-iring) * 2.0 / (double)(3*nside)); (*phi) = ((double)iphi - fodd) * HEALPIX_PI / (double)nl2; } else { ip = (long)(12*nside*nside - pix); iring = (long)(0.5*(1.0+sqrt((double)(2*ip-1)))); iphi = 4*iring + 1 - (ip - 2*iring*(iring-1)); (*theta) = acos(-1.0 + (double)(iring*iring) / (double)(3*nside*nside)); (*phi) = ((double)iphi - 0.5) * HEALPIX_PI / (double)(2*iring); } return 0; } int healpix_pix2ang_nest(size_t nside, size_t pix, double *theta, double *phi){ size_t factor = healpix_nside2factor(nside); long nl4 = (long)(nside*4); long face = (long)pix >> (2*factor); long ipf = (long)pix & (long)(nside*nside-1); long x, y; size_t sx, sy; long jr, nr, kshift, jp; double z; int err; err = healpix_pix2xy((size_t)ipf, &sx, &sy); if (err) { return err; } x = (long)sx; y = (long)sy; jr = (long)(healpix_jrll[face]< (long)(3*nside)) { nr = nl4 - jr; z = (double)(nr*nr) / (double)(3*nside*nside) - 1.0; kshift = 0; } else { nr = (long)nside; z = (double)((long)(2*nside)-jr) * 2.0 / (double)(3*nside); kshift = (jr-(long)nside)&1; } jp = (long)((long)((long)healpix_jpll[face]*nr + x - y + 1 + kshift) / 2); if (jp > nl4) jp -= nl4; if (jp < 1) jp += nl4; (*theta) = acos(z); (*phi) = ((double)jp - (double)(kshift+1)*0.5) * HEALPIX_HALFPI / (double)nr; return 0; } /* degrade */ int healpix_degrade_nest(size_t oldnside, size_t oldpix, size_t newnside, size_t * newpix) { size_t oldfactor; size_t newfactor; size_t face; int err; err = healpix_nsidecheck(oldnside); if (err) { return err; } err = healpix_nsidecheck(newnside); if (err) { return err; } if (oldnside < newnside) { return 1; } oldfactor = healpix_nside2factor(oldnside); newfactor = healpix_nside2factor(newnside); face = oldpix >> 2*oldfactor; (*newpix) = ((oldpix & (oldnside*oldnside-1)) >> (2*(oldfactor-newfactor))) + (face << 2*newfactor); return 0; } int healpix_degrade_ring(size_t oldnside, size_t oldpix, size_t newnside, size_t * newpix) { size_t oldnest; size_t newnest; int err; err = healpix_ring2nest(oldnside, oldpix, &oldnest); if (err) { return err; } err = healpix_degrade_nest(oldnside, oldnest, newnside, &newnest); if (err) { return err; } err = healpix_nest2ring(newnside, newnest, newpix); if (err) { return err; } return 0; } /* unit sphere vectors */ int healpix_vec2ang(double xcomp, double ycomp, double zcomp, double *theta, double *phi) { double sint; (*theta) = acos(zcomp); sint = sin((*theta)); if (ycomp >= 0.0) { (*phi) = acos(xcomp / sint); } else { (*phi) = acos(xcomp / sint) + HEALPIX_PI; } return 0; } int healpix_ang2vec(double theta, double phi, double *xcomp, double *ycomp, double *zcomp) { (*xcomp) = sin(theta) * cos(phi); (*ycomp) = sin(theta) * sin(phi); (*zcomp) = cos(theta); return 0; } int healpix_pix2vec_ring(size_t nside, size_t pix, double *xcomp, double *ycomp, double *zcomp) { double theta; double phi; int err; err = healpix_pix2ang_ring(nside, pix, &theta, &phi); if (err) { return err; } err = healpix_ang2vec(theta, phi, xcomp, ycomp, zcomp); if (err) { return err; } return 0; } int healpix_pix2vec_nest(size_t nside, size_t pix, double *xcomp, double *ycomp, double *zcomp) { double theta; double phi; int err; err = healpix_pix2ang_nest(nside, pix, &theta, &phi); if (err) { return err; } err = healpix_ang2vec(theta, phi, xcomp, ycomp, zcomp); if (err) { return err; } return 0; } int healpix_vec2pix_ring(size_t nside, double xcomp, double ycomp, double zcomp, size_t * pix) { double theta; double phi; int err; err = healpix_vec2ang(xcomp, ycomp, zcomp, &theta, &phi); if (err) { return err; } err = healpix_ang2pix_ring(nside, theta, phi, pix); if (err) { return err; } return 0; } int healpix_vec2pix_nest(size_t nside, double xcomp, double ycomp, double zcomp, size_t * pix) { double theta; double phi; int err; err = healpix_vec2ang(xcomp, ycomp, zcomp, &theta, &phi); if (err) { return err; } err = healpix_ang2pix_nest(nside, theta, phi, pix); if (err) { return err; } return 0; } /* nearest neighbors */ int healpix_neighbors(size_t nside, int ordering, size_t pixel, long *parray) { int err; size_t i; size_t ptemp; static const int xoffset[] = { -1, 1, 0, 0,-1,-1, 1, 1 }; static const int yoffset[] = { 0, 0,-1, 1,-1, 1, 1,-1 }; static const int facearray[][12] = { { 8, 9,10,11,-1,-1,-1,-1,10,11, 8, 9 }, /* S */ { 5, 6, 7, 4, 8, 9,10,11, 9,10,11, 8 }, /* SE */ { -1,-1,-1,-1, 5, 6, 7, 4,-1,-1,-1,-1 }, /* E */ { 4, 5, 6, 7,11, 8, 9,10,11, 8, 9,10 }, /* SW */ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }, /* center */ { 1, 2, 3, 0, 0, 1, 2, 3, 5, 6, 7, 4 }, /* NE */ { -1,-1,-1,-1, 7, 4, 5, 6,-1,-1,-1,-1 }, /* W */ { 3, 0, 1, 2, 3, 0, 1, 2, 4, 5, 6, 7 }, /* NW */ { 2, 3, 0, 1,-1,-1,-1,-1, 0, 1, 2, 3 } }; /* N */ static const int swaparray[][12] = { { 0,0,0,0,0,0,0,0,3,3,3,3 }, /* S */ { 0,0,0,0,0,0,0,0,6,6,6,6 }, /* SE */ { 0,0,0,0,0,0,0,0,0,0,0,0 }, /* E */ { 0,0,0,0,0,0,0,0,5,5,5,5 }, /* SW */ { 0,0,0,0,0,0,0,0,0,0,0,0 }, /* center */ { 5,5,5,5,0,0,0,0,0,0,0,0 }, /* NE */ { 0,0,0,0,0,0,0,0,0,0,0,0 }, /* W */ { 6,6,6,6,0,0,0,0,0,0,0,0 }, /* NW */ { 3,3,3,3,0,0,0,0,0,0,0,0 } }; /* N */ int x, y, ix, iy, f; size_t stx, sty; size_t face; const size_t nsm1 = nside - 1; size_t nbnum; int tmp; if (ordering == HEALPIX_RING) { err = healpix_ring2xyf(nside, pixel, &stx, &sty, &face); } else { err = healpix_nest2xyf(nside, pixel, &stx, &sty, &face); } if (err) { return err; } ix = (int)stx; iy = (int)sty; for (i = 0; i < 8; i++) { parray[i] = -1l; } if ((ix > 0)&&(ix < (int)nsm1)&&(iy > 0)&&(iy < (int)nsm1)) { if (ordering == HEALPIX_RING) { for (i = 0; i < 8; i++) { err = healpix_xyf2ring(nside, (size_t)(ix + xoffset[i]), (size_t)(iy+yoffset[i]), face, &ptemp); parray[i] = ptemp; } } else { for (i = 0; i < 8; i++) { err = healpix_xyf2nest(nside, (size_t)(ix + xoffset[i]), (size_t)(iy+yoffset[i]), face, &ptemp); parray[i] = ptemp; } } } else { for (i = 0; i < 8; i++) { x = ix + xoffset[i]; y = iy + yoffset[i]; nbnum = 4; if (x < 0) { x += (int)nside; nbnum -= 1; } else if (x >= (int)nside) { x -= (int)nside; nbnum += 1; } if (y < 0) { y += (int)nside; nbnum -= 3; } else if (y >= (int)nside) { y -= (int)nside; nbnum += 3; } f = facearray[nbnum][face]; if (f >= 0) { if (swaparray[nbnum][face]&1) { x = (int)nside - x - 1; } if (swaparray[nbnum][face]&2) { y = (int)nside - y - 1; } if (swaparray[nbnum][face]&4) { tmp = x; x = y; y = tmp; } if (ordering == HEALPIX_RING) { err = healpix_xyf2ring(nside, (size_t)x, (size_t)y, (size_t)f, &ptemp); } else { err = healpix_xyf2nest(nside, (size_t)x, (size_t)y, (size_t)f, &ptemp); } parray[i] = ptemp; } } } return 0; } /* angular distance between two pixels */ double healpix_loc_dist(size_t nside, int order, size_t pix1, size_t pix2) { double x1, y1, z1; double x2, y2, z2; double alpha; if (healpix_nsidecheck(nside)) { return 0.0; } if (pix1 > 12 * nside * nside) { return 0.0; } if (pix2 > 12 * nside * nside) { return 0.0; } if (order == HEALPIX_NEST) { healpix_pix2vec_nest(nside, pix1, &x1, &y1, &z1); healpix_pix2vec_nest(nside, pix2, &x2, &y2, &z2); } else { healpix_pix2vec_ring(nside, pix1, &x1, &y1, &z1); healpix_pix2vec_ring(nside, pix2, &x2, &y2, &z2); } alpha = acos((x1 * x2) + (y1 * y2) + (z1 * z2)); return alpha; } kst-2.0.3/src/datasources/healpix/healpix_tools.h000644 001750 001750 00000020640 11544160207 022454 0ustar00synthsynth000000 000000 /*************************************************************************** healpix_tools.h - tools for healpix datasource ------------------- begin : Wed June 01 2005 copyright : (C) 2005 Ted Kisner email : tskisner.public@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef HEALPIX_TOOLS_H #define HEALPIX_TOOLS_H #include #include #include # ifdef HEALPIX_PI # undef HEALPIX_PI # endif /* define pi... */ # define HEALPIX_PI M_PI # ifdef HEALPIX_INVPI # undef HEALPIX_INVPI # endif /* define 1/pi... */ # define HEALPIX_INVPI M_1_PI # ifdef HEALPIX_PISQ # undef HEALPIX_PISQ # endif /* define pi squared... */ # define HEALPIX_PISQ 9.86960440108936 # ifdef HEALPIX_HALFPI # undef HEALPIX_HALFPI # endif /* define half pi... */ # define HEALPIX_HALFPI M_PI_2 # ifdef HEALPIX_NSIDE_MAX # undef HEALPIX_NSIDE_MAX # endif /* max nside value */ # define HEALPIX_NSIDE_MAX 8192 # ifdef HEALPIX_STRNL # undef HEALPIX_STRNL # endif /* max string length */ # define HEALPIX_STRNL 200 # ifdef HEALPIX_MIN_EXP # undef HEALPIX_MIN_EXP # endif /* smallest IEEE double exponent */ # define HEALPIX_MIN_EXP -1022 # ifdef HEALPIX_MAX_EXP # undef HEALPIX_MAX_EXP # endif /* smallest IEEE double exponent */ # define HEALPIX_MAX_EXP 1023 /* map parameters */ # ifdef HEALPIX_RING # undef HEALPIX_RING # endif /* ordering = ring */ # define HEALPIX_RING 0 # ifdef HEALPIX_NEST # undef HEALPIX_NEST # endif /* ordering = nested */ # define HEALPIX_NEST 1 # ifdef HEALPIX_COORD_C # undef HEALPIX_COORD_C # endif /* coordsys = celestial/equatorial */ # define HEALPIX_COORD_C 0 # ifdef HEALPIX_COORD_G # undef HEALPIX_COORD_G # endif /* coordsys = galactic */ # define HEALPIX_COORD_G 1 # ifdef HEALPIX_COORD_E # undef HEALPIX_COORD_E # endif /* coordsys = ecliptic */ # define HEALPIX_COORD_E 2 # ifdef HEALPIX_COORD_O # undef HEALPIX_COORD_O # endif /* coordsys = other */ # define HEALPIX_COORD_O 3 /* projection parameters */ # ifdef HEALPIX_PROJ_CAR # undef HEALPIX_PROJ_CAR # endif /* projection = cartesian */ # define HEALPIX_PROJ_CAR 0 # ifdef HEALPIX_PROJ_SIN # undef HEALPIX_PROJ_SIN # endif /* projection = sinusoidal */ # define HEALPIX_PROJ_SIN 1 /* FITS parameters */ # ifdef HEALPIX_FITS_FULL # undef HEALPIX_FITS_FULL # endif /* file contains full-sphere map(s) */ # define HEALPIX_FITS_FULL 0 # ifdef HEALPIX_FITS_CUT # undef HEALPIX_FITS_CUT # endif /* file contains cut-sphere map(s) */ # define HEALPIX_FITS_CUT 1 # ifdef HEALPIX_FITS_MAXCOL # undef HEALPIX_FITS_MAXCOL # endif /* maximum number of table columns supported */ # define HEALPIX_FITS_MAXCOL 50 # ifdef HEALPIX_NULL # undef HEALPIX_NULL # endif /* null value for float maps */ # define HEALPIX_NULL (-1.6375e30) # ifdef HEALPIX_EPSILON # undef HEALPIX_EPSILON # endif /* range around HEALPIX_NULL that is considered equal to NULL */ # define HEALPIX_EPSILON (0.0001e30) # ifdef HEALPIX_INT_NULL # undef HEALPIX_INT_NULL # endif /* null value for int maps */ # define HEALPIX_INT_NULL (-2147483646) typedef struct { /* healpix FITS keys */ size_t nskeys; size_t nikeys; size_t nfkeys; char **skeynames; char **skeyvals; char **skeycoms; char **ikeynames; int *ikeyvals; char **ikeycoms; char **fkeynames; float *fkeyvals; char **fkeycoms; } healpix_keys; int healpix_is_dnull(double val); int healpix_is_fnull(float val); int healpix_is_inull(int val); char **healpix_strarr_alloc(size_t nstring); int healpix_strarr_free(char **array, size_t nstring); int healpix_nsidecheck(size_t nside); size_t healpix_nside2npix(size_t nside); size_t healpix_npix2nside(size_t npix); size_t healpix_nside2factor(size_t nside); size_t healpix_factor2nside(size_t factor); int healpix_xy2pix(size_t x, size_t y, size_t *pix); int healpix_x2pix(size_t x, size_t *pix); int healpix_y2pix(size_t y, size_t *pix); int healpix_pix2xy(size_t pix, size_t *x, size_t *y); int healpix_nest2xyf (size_t nside, size_t pix, size_t *x, size_t *y, size_t *face_num); int healpix_xyf2nest (size_t nside, size_t x, size_t y, size_t face_num, size_t *pix); int healpix_ring2xyf (size_t nside, size_t pix, size_t *x, size_t *y, size_t *face_num); int healpix_xyf2ring (size_t nside, size_t x, size_t y, size_t face_num, size_t *pix); int healpix_nest2ring (size_t nside, size_t pnest, size_t *pring); int healpix_ring2nest(size_t nside, size_t pring, size_t *pnest); int healpix_ang2pix_ring(size_t nside, double theta, double phi, size_t *pix); int healpix_ang2pix_nest(size_t nside, double theta, double phi, size_t *pix); int healpix_pix2ang_ring(size_t nside, size_t pix, double *theta, double *phi); int healpix_pix2ang_nest(size_t nside, size_t pix, double *theta, double *phi); int healpix_degrade_nest(size_t oldnside, size_t oldpix, size_t newnside, size_t * newpix); int healpix_degrade_ring(size_t oldnside, size_t oldpix, size_t newnside, size_t * newpix); int healpix_neighbors(size_t nside, int ordering, size_t pixel, long *parray); int healpix_proj_car(double mintheta, double maxtheta, double minphi, double maxphi, double xmax, double ymax, double theta, double phi, double *x, double *y); int healpix_proj_sin(double mintheta, double maxtheta, double minphi, double maxphi, double xmax, double ymax, double theta, double phi, double *x, double *y); int healpix_proj_rev_car(double mintheta, double maxtheta, double minphi, double maxphi, double xmax, double ymax, double x, double y, double *theta, double *phi); int healpix_proj_rev_sin(double mintheta, double maxtheta, double minphi, double maxphi, double xmax, double ymax, double x, double y, double *theta, double *phi); double healpix_loc_dist(size_t nside, int order, size_t pix1, size_t pix2); /* FITS keys operations */ healpix_keys *healpix_keys_alloc(); int healpix_keys_free(healpix_keys * keys); int healpix_keys_clear(healpix_keys * keys); int healpix_keys_sadd(healpix_keys * keys, char *keyname, char *keyval, char *keycom); int healpix_keys_iadd(healpix_keys * keys, char *keyname, int keyval, char *keycom); int healpix_keys_fadd(healpix_keys * keys, char *keyname, float keyval, char *keycom); int healpix_keys_read(healpix_keys * keys, fitsfile * fp, int *ret); /* file info */ int healpix_fits_map_test(char *filename, size_t * nside, int *order, int *coord, int *type, size_t * nmaps); int healpix_fits_map_info(char *filename, size_t * nside, int *order, int *coord, int *type, size_t * nmaps, char *creator, char *extname, char **names, char **units, healpix_keys *keys); #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/healpix/healpix.pro000644 001750 001750 00000000601 11544160207 021600 0ustar00synthsynth000000 000000 include($$PWD/../../../kst.pri) include($$PWD/../../../datasourceplugin.pri) TARGET = $$kstlib(kst2data_healpix) INCLUDEPATH += $$OUTPUT_DIR/src/datasources/fitsimage/tmp LIBS += -lcfitsio SOURCES += \ healpix.cpp \ healpix_tools_fits.cpp \ healpix_tools_pix.cpp \ healpix_tools_proj.cpp HEADERS += \ healpix.h \ healpix_tools.h FORMS += healpixconfig.ui kst-2.0.3/src/datasources/healpix/kstdata_healpix.desktop000644 001750 001750 00000004605 11544160207 024174 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=healpix X-Kst-Plugin-Author=The University of Toronto Name=Healpix File Reader Name[br]=Lenner ar restroù Healpix Name[ca]=Lector de fitxer Healpix Name[cs]=Čtečka Healpix souborů Name[da]=Healpix fillæser Name[de]=Healpix-Betrachter Name[el]=Αναγνώστης αρχείων Healpix Name[es]=Lector de archivos Healpix Name[et]=Healpix-faili lugeja Name[ga]=Léitheoir Comhad Healpix Name[gl]=Leitor de Arquivos Healpix Name[hr]=Healpix čitač datoteka Name[is]=Healpix skráalesari Name[it]=Lettore file Healpix Name[ja]=Healpix ファイルリーダー Name[ka]=Healpix ფაილის წამკითხველი Name[nl]=Healpix-bestandleesprogramma Name[pa]=ਹੀਲਪਿਕਸ ਫਾਇਲ ਰੀਡਰ Name[pt]=Leitor de Ficheiros Healpix Name[pt_BR]=Leitor de Arquivos Healpix Name[sr]=Читач Healpix фајлова Name[sr@Latn]=Čitač Healpix fajlova Name[sv]=Healpix-filläsare Name[tg]=Хонандаи Файли Healpix Name[vi]=Bộ đọc tập tin Healpix Name[xx]=xxHealpix File Readerxx Comment=Plugin to read Healpix FITS files. Comment[br]=Lugent evit lenn ar restroù FITS. Comment[ca]=Connector per llegir fitxers FITS Healpix. Comment[cs]=Modul pro čtení Healpix FITS obrázků. Comment[da]=Plugin til at læse Healpix FITS filer. Comment[de]=Modul zum Lesen von Healpix FITS-Bildern Comment[el]=Πρόσθετο για ανάγνωση αρχείων Healpix FITS. Comment[es]=Plugin para leer archivos en formato Healpix FITS. Comment[et]=Plugin Healpix FITS-failide lugemiseks. Comment[ga]=Breiseán a léann comhaid Healpix FITS. Comment[gl]= Plugin para ler ficheiros Healpix FITS. Comment[hr]=Dodatak za čitanje Healpix FITS slika. Comment[is]=Íforrit til að lesa Healpix FITS skrár. Comment[it]=Plugin per leggere i file Healpix FITS. Comment[ja]=Healpix FITS ファイルを読むためのプラグイン Comment[ka]=Healpix FITS ფაილების წამკითხველი მოდული. Comment[nl]=Plugin voor het lezen van Healpix FITS-bestanden. Comment[pt]=Um 'plugin' para ler ficheiros FITS do Healpix. Comment[pt_BR]=Plugin para a leitura de uma imagem FITS. Comment[sv]=Insticksprogram för att läsa Healpix FITS-filer. Comment[vi]=Bổ sung đọc tập tin kiểu Healpix FITS. Comment[xx]=xxPlugin to read Healpix FITS files.xx kst-2.0.3/src/datasources/healpix/healpixconfig.ui000644 001750 001750 00000023671 11544160207 022617 0ustar00synthsynth000000 000000 HealpixConfig 0 0 425 383 Projection Matrix Dimensions: false X = false matDimX 10000 1200 Y = false matDimY 10000 90 Theta Range: false Autoscale Theta true Min = false matThetaMin Max = false matThetaMax Phi Range: false Autoscale Phi true Min = false Max = false Vector Field Theta Component: false Phi Component: false Degrade Factor Relative to Scalar Field: false vecDegrade 12 1 Max Magnitude: false vecMag Autoscale Magnitude true Interpret Components as Q/U Stokes Parameters vecMagAuto toggled(bool) vecMag setDisabled(bool) 549 760 386 760 kst-2.0.3/src/datasources/healpix/healpix_tools_proj.cpp000644 001750 001750 00000017656 11544160210 024050 0ustar00synthsynth000000 000000 /*************************************************************************** healpix_tools.cpp - tools for healpix datasource ------------------- begin : Wed June 01 2005 copyright : (C) 2005 Ted Kisner email : tskisner.public@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "healpix_tools.h" /* single pixel forward projections */ int healpix_proj_car(double mintheta, double maxtheta, double minphi, double maxphi, double xmax, double ymax, double theta, double phi, double *x, double *y) { if ((mintheta < 0.0) || (mintheta > HEALPIX_PI)) { return 0; } if ((maxtheta < 0.0) || (maxtheta > HEALPIX_PI)) { return 0; } if ((minphi < 0.0) || (minphi > 2 * HEALPIX_PI)) { return 0; } if ((maxphi < 0.0) || (maxphi > 2 * HEALPIX_PI)) { return 0; } if (maxtheta <= mintheta) { return 0; } if (maxphi == minphi) { return 0; } if ((theta < 0.0) || (theta > HEALPIX_PI)) { return 0; } if ((phi < 0.0) || (phi > 2 * HEALPIX_PI)) { return 0; } if ((theta > maxtheta) || (theta < mintheta)) { (*x) = HEALPIX_NULL; (*y) = HEALPIX_NULL; return 0; } if (maxphi > minphi) { if ((phi > maxphi) || (phi < minphi)) { (*x) = HEALPIX_NULL; (*y) = HEALPIX_NULL; return 0; } } else { if ((phi > maxphi) && (phi < minphi)) { (*x) = HEALPIX_NULL; (*y) = HEALPIX_NULL; return 0; } } (*y) = ((maxtheta - theta) / (maxtheta - mintheta)) * ymax; if (maxphi > minphi) { (*x) = ((phi - minphi) / (maxphi - minphi)) * xmax; } else { if (phi <= maxphi) { (*x) = ((phi + (2.0 * HEALPIX_PI - minphi)) / (maxphi + (2.0 * HEALPIX_PI - minphi))) * xmax; } else { (*x) = ((phi - minphi) / (maxphi + (2.0 * HEALPIX_PI - minphi))) * xmax; } } return 0; } int healpix_proj_sin(double mintheta, double maxtheta, double minphi, double maxphi, double xmax, double ymax, double theta, double phi, double *x, double *y) { double centphi; double centtheta; double halfx; double tempx; if ((mintheta < 0.0) || (mintheta > HEALPIX_PI)) { return 0; } if ((maxtheta < 0.0) || (maxtheta > HEALPIX_PI)) { return 0; } if ((minphi < 0.0) || (minphi > 2 * HEALPIX_PI)) { return 0; } if ((maxphi < 0.0) || (maxphi > 2 * HEALPIX_PI)) { return 0; } if (maxtheta <= mintheta) { return 0; } if (maxphi == minphi) { return 0; } if ((theta < 0.0) || (theta > HEALPIX_PI)) { return 0; } if ((phi < 0.0) || (phi > 2 * HEALPIX_PI)) { return 0; } (*y) = ((maxtheta - theta) / (maxtheta - mintheta)) * ymax; if (((*y) > ymax) || ((*y) < 0.0)) { (*x) = HEALPIX_NULL; (*y) = HEALPIX_NULL; return 0; } /* find half width of viewing area */ centtheta = (maxtheta + mintheta) / 2.0; if (maxphi > minphi) { centphi = (maxphi + minphi) / 2.0; halfx = ((maxphi - minphi) / 2.0) * cos(-(centtheta - HEALPIX_PI / 2.0)); } else { centphi = minphi + (minphi + (2.0 * HEALPIX_PI - maxphi)) / 2.0; if (minphi >= 2.0 * HEALPIX_PI) { centphi -= 2.0 * HEALPIX_PI; } halfx = ((minphi + (2.0 * HEALPIX_PI - maxphi)) / 2.0) * cos(-(centtheta - HEALPIX_PI / 2.0)); } /* find x offset from center */ if (maxphi > minphi) { tempx = phi - centphi; } else { if (centphi > maxphi) { if (phi <= centphi) { tempx = phi - centphi; } else { if (phi < maxphi) { tempx = phi + (2.0 * HEALPIX_PI - centphi); } else { tempx = phi - centphi; } } } else { if (phi < centphi) { if (phi > minphi) { tempx = -(centphi + 2.0 * HEALPIX_PI - phi); } else { tempx = phi - centphi; } } else { tempx = phi - centphi; } } } tempx *= cos(-(theta - HEALPIX_PI / 2.0)); if ((tempx > halfx) || (tempx < -halfx)) { (*x) = HEALPIX_NULL; (*y) = HEALPIX_NULL; return 0; } (*x) = (xmax / 2.0) * ((tempx / halfx) + 1.0); return 0; } /* single pixel reverse projections */ int healpix_proj_rev_car(double mintheta, double maxtheta, double minphi, double maxphi, double xmax, double ymax, double x, double y, double *theta, double *phi) { if ((mintheta < 0.0) || (mintheta > HEALPIX_PI)) { return 0; } if ((maxtheta < 0.0) || (maxtheta > HEALPIX_PI)) { return 0; } if ((minphi < 0.0) || (minphi > 2 * HEALPIX_PI)) { return 0; } if ((maxphi < 0.0) || (maxphi > 2 * HEALPIX_PI)) { return 0; } if (maxtheta <= mintheta) { return 0; } if (maxphi == minphi) { return 0; } if ((y > ymax) || (y < 0.0) || (x > xmax) || (x < 0.0)) { (*theta) = HEALPIX_NULL; (*phi) = HEALPIX_NULL; return 0; } (*theta) = maxtheta - (y / ymax) * (maxtheta - mintheta); if (maxphi > minphi) { (*phi) = minphi + (x / xmax) * (maxphi - minphi); } else { (*phi) = minphi + (x / xmax) * (maxphi + (2.0 * HEALPIX_PI - minphi)); if ((*phi) >= 2.0 * HEALPIX_PI) { (*phi) -= 2.0 * HEALPIX_PI; } } return 0; } int healpix_proj_rev_sin(double mintheta, double maxtheta, double minphi, double maxphi, double xmax, double ymax, double x, double y, double *theta, double *phi) { double centphi; double centtheta; double halfx; double ph, th; if ((mintheta < 0.0) || (mintheta > HEALPIX_PI)) { return 0; } if ((maxtheta < 0.0) || (maxtheta > HEALPIX_PI)) { return 0; } if ((minphi < 0.0) || (minphi > 2 * HEALPIX_PI)) { return 0; } if ((maxphi < 0.0) || (maxphi > 2 * HEALPIX_PI)) { return 0; } if (maxtheta <= mintheta) { return 0; } if (maxphi == minphi) { return 0; } if ((y > ymax) || (y < 0.0) || (x > xmax) || (x < 0.0)) { (*theta) = HEALPIX_NULL; (*phi) = HEALPIX_NULL; return 0; } th = maxtheta - (y / ymax) * (maxtheta - mintheta); if ((th == 0.0) || (th == HEALPIX_PI)) { /*at a pole */ if (x != (xmax / 2.0)) { (*theta) = HEALPIX_NULL; (*phi) = HEALPIX_NULL; return 0; } else { (*theta) = th; if (maxphi > minphi) { (*phi) = (maxphi + minphi) / 2.0; } else { ph = minphi + (maxphi + (2.0 * HEALPIX_PI - minphi)) / 2.0; if (ph >= 2.0 * HEALPIX_PI) { ph -= 2.0 * HEALPIX_PI; } (*phi) = ph; } return 0; } } /* find half width of viewing area */ centtheta = (maxtheta + mintheta) / 2.0; if (maxphi > minphi) { centphi = (maxphi + minphi) / 2.0; halfx = ((maxphi - minphi) / 2.0) * cos(-(centtheta - HEALPIX_PI / 2.0)); } else { centphi = minphi + (maxphi + (2.0 * HEALPIX_PI - minphi)) / 2.0; if (centphi >= 2.0 * HEALPIX_PI) { centphi -= 2.0 * HEALPIX_PI; } halfx = ((maxphi + (2.0 * HEALPIX_PI - minphi)) / 2.0) * cos(-(centtheta - HEALPIX_PI / 2.0)); } /* find phi offset from center */ ph = ((2.0 * x / xmax - 1.0) * halfx) / (cos(-(th - HEALPIX_PI / 2.0))); if ((ph > HEALPIX_PI) || (ph < -HEALPIX_PI)) { (*theta) = HEALPIX_NULL; (*phi) = HEALPIX_NULL; return 0; } ph = ph + centphi; while (ph >= 2.0 * HEALPIX_PI) { ph -= 2.0 * HEALPIX_PI; } while (ph < 0.0) { ph += 2.0 * HEALPIX_PI; } (*theta) = th; (*phi) = ph; return 0; } kst-2.0.3/src/datasources/healpix/healpix.cpp000644 001750 001750 00000160506 11544160210 021567 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "healpix.h" #include #include #include #include "ui_healpixconfig.h" #define DEFAULT_XDIM 800 #define DEFAULT_YDIM 600 #define HPUNIT_RAD 0 #define HPUNIT_DEG 1 #define HPUNIT_RADEC 2 #define HPUNIT_LATLON 3 #include "kst_i18n.h" static const QString healpixTypeString = I18N_NOOP("HEALPIX image"); class HealpixSource::Config { public: Config() { _nX = 800; _nY = 600; _autoTheta = true; _autoPhi = true; //FIXME switch to radians default later _thetaUnits = HPUNIT_RADEC; _phiUnits = HPUNIT_RADEC; _vecUnits = HPUNIT_RADEC; _autoMag = true; _vecDegrade = 0; _vecTheta = 0; _vecPhi = 0; _vecQU = false; } void read(QSettings *cfg, const QString& fileName = QString::null) { Q_UNUSED(fileName); cfg->beginGroup(healpixTypeString); double confThetaMin; double confThetaMax; double confPhiMin; double confPhiMax; int tempdegrade; if (!fileName.isEmpty()) { cfg->endGroup(); cfg->beginGroup(fileName); } _nX = cfg->value("Matrix X Dimension", DEFAULT_XDIM).toInt(); _nY = cfg->value("Matrix Y Dimension", DEFAULT_YDIM).toInt(); _autoTheta = cfg->value("Theta Autoscale", true).toBool(); _thetaUnits = cfg->value("Theta Units", HPUNIT_RADEC).toInt(); confThetaMin = cfg->value("Theta Min", 0).toDouble(); confThetaMax = cfg->value("Theta Max", 0).toDouble(); _autoPhi = cfg->value("Phi Autoscale", true).toBool(); _phiUnits = cfg->value("Phi Units", HPUNIT_RADEC).toInt(); confPhiMin = cfg->value("Phi Min", 0).toDouble(); confPhiMax = cfg->value("Phi Max", 0).toDouble(); _vecTheta = cfg->value("Vector Theta", 0).toInt(); _vecPhi = cfg->value("Vector Phi", 0).toInt(); tempdegrade = cfg->value("Vector Degrade Factor", 1).toInt(); _autoMag = cfg->value("Vector Magnitude Autoscale", true).toBool(); _maxMag = cfg->value("Vector Max Magnitude", 0).toDouble(); _vecQU = cfg->value("Vector is QU", false).toBool(); // check degrade factor checkDegrade(tempdegrade); _vecDegrade = tempdegrade; // convert the entered range values into radians and // force them to the correct range. theta2Internal(_thetaUnits, confThetaMin); theta2Internal(_thetaUnits, confThetaMax); phi2Internal(_phiUnits, confPhiMin); phi2Internal(_phiUnits, confPhiMax); // swap theta min/max if coordinate system requires it if (confThetaMax < confThetaMin) { double temp = confThetaMax; confThetaMax = confThetaMin; confThetaMin = temp; } _thetaMin = confThetaMin; _thetaMax = confThetaMax; _phiMin = confPhiMin; _phiMax = confPhiMax; cfg->endGroup(); } void save(QXmlStreamWriter& s) { double confThetaMin = _thetaMin; double confThetaMax = _thetaMax; double confPhiMin = _phiMin; double confPhiMax = _phiMax; // export the internal range (in radians) to the // selected coordinate system theta2External(_thetaUnits, confThetaMin); theta2External(_thetaUnits, confThetaMax); phi2External(_phiUnits, confPhiMin); phi2External(_phiUnits, confPhiMax); // swap theta min/max if coordinate system requires it if (confThetaMax < confThetaMin) { double temp = confThetaMax; confThetaMax = confThetaMin; confThetaMin = temp; } s.writeStartElement("properties"); s.writeAttribute("dim-x", QString::number(_nX)); s.writeAttribute("dim-y", QString::number(_nY)); s.writeAttribute("theta-auto", QVariant(_autoTheta).toString()); s.writeAttribute("theta-units", QString::number(_thetaUnits)); s.writeAttribute("theta-min", QString::number(confThetaMin)); s.writeAttribute("theta-max", QString::number(confThetaMax)); s.writeAttribute("phi-auto", QVariant(_autoPhi).toString()); s.writeAttribute("phi-units", QString::number(_phiUnits)); s.writeAttribute("phi-min", QString::number(confPhiMin)); s.writeAttribute("phi-max", QString::number(confPhiMax)); s.writeAttribute("vector-theta", QString::number(_vecTheta)); s.writeAttribute("vector-phi", QString::number(_vecPhi)); s.writeAttribute("vector-degrade", QVariant(_vecDegrade).toString()); s.writeAttribute("vector-auto", QVariant(_autoMag).toString()); s.writeAttribute("vector-max", QString::number(_maxMag)); s.writeAttribute("vector-QU", QVariant(_vecQU).toString()); s.writeEndElement(); } void parseProperties(QXmlStreamAttributes &properties) { double confThetaMin; double confThetaMax; double confPhiMin; double confPhiMax; int tempdegrade; _nX = properties.value("dim-x").toString().toInt(); _nY = properties.value("dim-y").toString().toInt(); _autoTheta = QVariant(properties.value("theta-auto").toString()).toBool(); _thetaUnits = properties.value("theta-units").toString().toInt(); confThetaMin = properties.value("theta-min").toString().toDouble(); confThetaMax = properties.value("theta-max").toString().toDouble(); _autoPhi = QVariant(properties.value("phi-auto").toString()).toBool(); _phiUnits = properties.value("phi-units").toString().toInt(); confPhiMin = properties.value("phi-min").toString().toDouble(); confPhiMax = properties.value("phi-max").toString().toDouble(); _vecTheta = properties.value("vector-theta").toString().toInt(); _vecPhi = properties.value("vector-phi").toString().toInt(); tempdegrade = QVariant(properties.value("vector-degrade").toString()).toBool(); _autoMag = QVariant(properties.value("vector-auto").toString()).toBool(); _vecQU = QVariant(properties.value("vector-QU").toString()).toBool(); _maxMag = properties.value("vector-max").toString().toDouble(); checkDegrade(tempdegrade); _vecDegrade = tempdegrade; // convert the entered range values into radians and // force them to the correct range. theta2Internal(_thetaUnits, confThetaMin); theta2Internal(_thetaUnits, confThetaMax); phi2Internal(_phiUnits, confPhiMin); phi2Internal(_phiUnits, confPhiMax); // swap theta min/max if coordinate system requires it if (confThetaMax < confThetaMin) { double temp = confThetaMax; confThetaMax = confThetaMin; confThetaMin = temp; } _thetaMin = confThetaMin; _thetaMax = confThetaMax; _phiMin = confPhiMin; _phiMax = confPhiMax; } void load(const QDomElement& e) { double confThetaMin; double confThetaMax; double confPhiMin; double confPhiMax; int tempdegrade; QDomNode n = e.firstChild(); while (!n.isNull()) { QDomElement e = n.toElement(); if (!e.isNull()) { if (e.tagName() == "dim") { if (e.hasAttribute("x")) { _nX = e.attribute("x").toInt(); } if (e.hasAttribute("y")) { _nX = e.attribute("y").toInt(); } } else if (e.tagName() == "theta") { if (e.hasAttribute("auto")) { _autoTheta = e.attribute("auto").toInt(); } if (e.hasAttribute("units")) { _thetaUnits = e.attribute("units").toInt(); } if (e.hasAttribute("min")) { confThetaMin = e.attribute("min").toDouble(); } if (e.hasAttribute("max")) { confThetaMax = e.attribute("max").toDouble(); } } else if (e.tagName() == "phi") { if (e.hasAttribute("auto")) { _autoPhi = e.attribute("auto").toInt(); } if (e.hasAttribute("units")) { _phiUnits = e.attribute("units").toInt(); } if (e.hasAttribute("min")) { confPhiMin = e.attribute("min").toDouble(); } if (e.hasAttribute("max")) { confPhiMax = e.attribute("max").toDouble(); } } else if (e.tagName() == "vector") { if (e.hasAttribute("auto")) { _autoMag = e.attribute("auto").toInt(); } if (e.hasAttribute("degrade")) { tempdegrade = e.attribute("degrade").toInt(); checkDegrade(tempdegrade); _vecDegrade = tempdegrade; } if (e.hasAttribute("theta")) { _vecTheta = e.attribute("theta").toInt(); } if (e.hasAttribute("phi")) { _vecPhi = e.attribute("phi").toInt(); } if (e.hasAttribute("QU")) { _vecQU = e.attribute("QU").toInt(); } if (e.hasAttribute("max")) { _maxMag = e.attribute("max").toDouble(); } } } n = n.nextSibling(); } // convert the entered range values into radians and // force them to the correct range. theta2Internal(_thetaUnits, confThetaMin); theta2Internal(_thetaUnits, confThetaMax); phi2Internal(_phiUnits, confPhiMin); phi2Internal(_phiUnits, confPhiMax); // swap theta min/max if coordinate system requires it if (confThetaMax < confThetaMin) { double temp = confThetaMax; confThetaMax = confThetaMin; confThetaMin = temp; } _thetaMin = confThetaMin; _thetaMax = confThetaMax; _phiMin = confPhiMin; _phiMax = confPhiMax; } // data range int _nX; int _nY; double _thetaMin; double _phiMin; double _thetaMax; double _phiMax; bool _autoTheta; bool _autoPhi; //values are // 0 : Radians // 1 : Degrees // 2 : Degrees RA/DEC // 3 : Degrees Lat/Long int _thetaUnits; int _phiUnits; int _vecUnits; // vector field int _vecDegrade; int _vecTheta; int _vecPhi; bool _autoMag; double _maxMag; bool _vecQU; size_t _mapNside; void checkDegrade(int& degrade) { int nside = _mapNside; if (!degrade) { return; } if ((nside == 1) && (degrade != 0)) { degrade = 0; return; } for (int i = 0; i < degrade; i++) { nside = (int)(nside/2); if (nside == 1) { degrade = i+1; return; } } return; } void theta2Internal(int units, double& theta) { switch (units) { case HPUNIT_RAD: break; case HPUNIT_DEG: theta *= HEALPIX_PI/180.0; break; case HPUNIT_RADEC: case HPUNIT_LATLON: theta = (90.0 - theta) * HEALPIX_PI/180.0; break; default: break; } while (theta < 0.0) { theta += HEALPIX_PI; } while (theta > HEALPIX_PI) { theta -= HEALPIX_PI; } return; } void theta2External(int units, double& theta) { switch (units) { case HPUNIT_RAD: break; case HPUNIT_DEG: theta *= 180.0/HEALPIX_PI; break; case HPUNIT_RADEC: case HPUNIT_LATLON: theta = 90.0 - theta*180.0/HEALPIX_PI; break; default: break; } return; } void phi2Internal(int units, double& phi) { switch (units) { case HPUNIT_RAD: break; case HPUNIT_DEG: case HPUNIT_RADEC: case HPUNIT_LATLON: phi *= HEALPIX_PI/180.0; break; default: break; } while (phi < 0.0) { phi += 2.0*HEALPIX_PI; } while (phi > 2.0*HEALPIX_PI) { phi -= 2.0*HEALPIX_PI; } return; } void phi2External(int units, double& phi) { switch (units) { case HPUNIT_RAD: break; case HPUNIT_DEG: case HPUNIT_RADEC: phi *= 180.0/HEALPIX_PI; break; case HPUNIT_LATLON: phi *= 180.0/HEALPIX_PI; if (phi >= 180.0) { phi -= 360.0; } break; default: break; } return; } }; HealpixSource::HealpixSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type, None), _config(0L) { _valid = false; if (!type.isEmpty() && type != "HEALPIX Source") { return; } _config = new HealpixSource::Config; _config->read(cfg, filename); if (!e.isNull()) { _config->load(e); } if (init()) { _valid = true; } update(); } HealpixSource::~HealpixSource() { if (_keys) { healpix_keys_free(_keys); } if (_names) { healpix_strarr_free(_names, HEALPIX_FITS_MAXCOL); } if (_units) { healpix_strarr_free(_units, HEALPIX_FITS_MAXCOL); } } bool HealpixSource::reset() { return true; } bool HealpixSource::init() { size_t poff; strncpy(_healpixfile, _filename.toLatin1().data(), HEALPIX_STRNL); _names = healpix_strarr_alloc(HEALPIX_FITS_MAXCOL); _units = healpix_strarr_alloc(HEALPIX_FITS_MAXCOL); _keys = healpix_keys_alloc(); if (!healpix_fits_map_info(_healpixfile, &_mapNside, &_mapOrder, &_mapCoord, &_mapType, &_nMaps, _creator, _extname, _names, _units, _keys)) { healpix_keys_free(_keys); healpix_strarr_free(_names, HEALPIX_FITS_MAXCOL); healpix_strarr_free(_units, HEALPIX_FITS_MAXCOL); return false; } _config->_mapNside = _mapNside; if (_mapType == HEALPIX_FITS_CUT) { poff = 1; } else { poff = 0; } _mapNpix = 12 * _mapNside * _mapNside; // populate the metadata QString metaVal; QString metaName; metaName = "NSIDE"; metaVal.sprintf("%lu", (long unsigned int)_mapNside); _metaData.insert(metaName, metaVal); metaName = "NPIX"; metaVal.sprintf("%lu", (long unsigned int)_mapNpix); _metaData.insert(metaName, metaVal); metaName = "ORDER"; metaVal.sprintf("%d", _mapOrder); _metaData.insert(metaName, metaVal); metaName = "COORD"; metaVal.sprintf("%d", _mapCoord); _metaData.insert(metaName, metaVal); metaName = "TYPE"; metaVal.sprintf("%d", _mapType); _metaData.insert(metaName, metaVal); metaName = "NMAPS"; metaVal.sprintf("%lu", (long unsigned int)_nMaps); _metaData.insert(metaName, metaVal); metaName = "CREATOR"; metaVal.sprintf("%s", _creator); _metaData.insert(metaName, metaVal); metaName = "EXTNAME"; metaVal.sprintf("%s", _extname); _metaData.insert(metaName, metaVal); for (size_t j = 0; j < _keys->nskeys; j++) { metaName.sprintf("%s", _keys->skeynames[j]); metaVal.sprintf("%s", _keys->skeyvals[j]); _metaData.insert(metaName, metaVal); } for (size_t j = 0; j < _keys->nikeys; j++) { metaName.sprintf("%s", _keys->ikeynames[j]); metaVal.sprintf("%d", _keys->ikeyvals[j]); _metaData.insert(metaName, metaVal); } for (size_t j = 0; j < _keys->nfkeys; j++) { metaName.sprintf("%s", _keys->fkeynames[j]); metaVal.sprintf("%e", _keys->fkeyvals[j]); _metaData.insert(metaName, metaVal); } // populate the field list QString mapName; for (size_t i = 0; i < _nMaps; i++) { if (strlen(_names[i+poff]) == 0) { mapName.sprintf("%d - %s",(int)(i+1),"MAP"); } else { mapName.sprintf("%d - %s",(int)(i+1),_names[i+poff]); } if (strlen(_units[i+poff]) == 0) { mapName.sprintf("%s (%s)",mapName.toLatin1().data(),"Unknown Units"); } else { mapName.sprintf("%s (%s)",mapName.toLatin1().data(),_units[i+poff]); } _matrixList.append(mapName); } if (_mapType == HEALPIX_FITS_CUT) { if (strlen(_names[_nMaps+1]) == 0) { mapName.sprintf("%s","HITS"); } else { mapName.sprintf("%s",_names[_nMaps+1]); } _matrixList.append(mapName); if (strlen(_names[_nMaps+2]) == 0) { mapName.sprintf("%s","ERRORS"); } else { mapName.sprintf("%s",_names[_nMaps+2]); } if (strlen(_units[_nMaps+2]) == 0) { mapName.sprintf("%s (%s)",mapName.toLatin1().data(),"Unknown Units"); } else { mapName.sprintf("%s (%s)",mapName.toLatin1().data(),_units[_nMaps+2]); } _matrixList.append(mapName); } _fieldList.append("1 - Vector Field Head Theta"); _fieldList.append("2 - Vector Field Head Phi"); _fieldList.append("3 - Vector Field Tail Theta"); _fieldList.append("4 - Vector Field Tail Phi"); return true; } Kst::Object::UpdateType HealpixSource::update() { // updates not supported yet // we should check to see if the FITS file has changed on disk return Kst::Object::NO_CHANGE; } bool HealpixSource::matrixDimensions( const QString& matrix, int* xDim, int* yDim) { Q_UNUSED(matrix) if (_valid) { (*xDim) = _config->_nX; (*yDim) = _config->_nY; return true; } return false; } int HealpixSource::readMatrix(Kst::MatrixData* data, const QString& field, int xStart, int yStart, int xNumSteps, int yNumSteps) { // If the file is _valid, then we already // have all the header information- no need to read it again. // We also know that the matrix index is not out-of-range. if (_valid && isValidMatrix(field)) { fitsfile *fp; int colnum; int fieldnum; int ret = 0; int ncol; int ttype; long nrows; long pcount; int tfields; char extname[HEALPIX_STRNL]; char comment[HEALPIX_STRNL]; float *datavec; int *pixvec; float *mapdata; float nullval = 0.0; int nnull = 0; int keynpix; int keyfirst; int ischunk; long nelem; if (_matrixList.contains(field)) { fieldnum = _matrixList.findIndex(field); } else { fieldnum = field.toInt(); fieldnum--; } // check range if ((xStart >= _config->_nX) || (yStart >= _config->_nY)) { return -1; } int nxread = xNumSteps; if (nxread < 0) { nxread = 1; } if (xStart + nxread > _config->_nX) { nxread = _config->_nX - xStart; } int nyread = yNumSteps; if (nyread < 0) { nyread = 1; } if (yStart + nyread > _config->_nY) { nyread = _config->_nY - yStart; } if (_mapType == HEALPIX_FITS_CUT) { // cut-sphere files have extra pixel/hits/error columns colnum = fieldnum + 2; ncol = (int)_nMaps + 3; } else { colnum = fieldnum + 1; ncol = (int)_nMaps; } // open file and move to second header unit if (fits_open_file(&fp, _healpixfile, READONLY, &ret)) { return -1; } if (fits_movabs_hdu(fp, 2, &ttype, &ret)) { return -1; } // read the number of rows if (fits_read_btblhdr(fp, ncol, &nrows, &tfields, NULL, NULL, NULL, extname, &pcount, &ret)) { ret = 0; fits_close_file(fp, &ret); return -1; } mapdata = (float*)calloc(_mapNpix, sizeof(float)); //initialize data to HEALPIX_NULL for (size_t j = 0; j < _mapNpix; j++) { mapdata[j] = HEALPIX_NULL; } if (_mapType == HEALPIX_FITS_CUT) { // For a cut-sphere file, we must read the entire // file and then re-map the data onto a full-sphere // vector. datavec = (float*)calloc((size_t) nrows, sizeof(float)); pixvec = (int*)calloc((size_t) nrows, sizeof(int)); if (fits_read_col(fp, TINT, 1, 1, 1, nrows, &nullval, pixvec, &nnull, &ret)) { free(pixvec); free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } if (fits_read_col(fp, TFLOAT, colnum, 1, 1, nrows, &nullval, datavec, &nnull, &ret)) { free(pixvec); free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } for (long j = 0; j < nrows; j++) { if ((pixvec[j] >= 0) && (pixvec[j] < (int)_mapNpix)) { mapdata[pixvec[j]] = datavec[j]; } } free(pixvec); free(datavec); } else { /* is this a chunk? */ if ((nrows != (long)(_mapNpix))&&(1024*nrows != (long)(_mapNpix))) { /*this must be a chunk file*/ char charFirstPix[] = "FIRSTPIX"; if (fits_read_key(fp, TLONG, charFirstPix, &keyfirst, comment, &ret)) { /*must at least have FIRSTPIX key*/ fits_close_file(fp, &ret); return 0; } else { char charNPix[] = "NPIX"; if (fits_read_key(fp, TLONG, charNPix, &keynpix, comment, &ret)) { ret = 0; /*might be using LASTPIX instead*/ char charLastPix[] = "LASTPIX"; if (fits_read_key(fp, TLONG, charLastPix, &keynpix, comment, &ret)) { fits_close_file(fp, &ret); return 0; } else { keynpix = keynpix - keyfirst + 1; ischunk = 1; } } else { ischunk = 1; } } } else { ischunk = 0; } if (ischunk) { datavec = (float*)calloc((size_t)keynpix, sizeof(float)); nelem = (long)keynpix; } else { datavec = (float*)calloc(_mapNpix, sizeof(float)); nelem = (long)(_mapNpix); } if (fits_read_col(fp, TFLOAT, colnum, 1, 1, nelem, &nullval, datavec, &nnull, &ret)) { free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } if (ischunk) { for (long j = 0; j < nelem; j++) { mapdata[j+keyfirst] = datavec[j]; } } else { for (long j = 0; j < nelem; j++) { mapdata[j] = datavec[j]; } } free(datavec); } fits_close_file(fp, &ret); // set the matrix to NULL for (int i = 0; i < nxread*nyread; i++) { data->z[i] = NAN; } double theta, phi; size_t ppix; // compute autorange parameters if necessary if (_config->_autoTheta || _config->_autoPhi) { double mapMinTheta = HEALPIX_PI; double mapMaxTheta = 0.0; double mapMinPhi = 2.0*HEALPIX_PI; double mapMaxPhi = 0.0; for (size_t i = 0; i < _mapNpix; i++) { if (!healpix_is_fnull(mapdata[i])) { if (_mapOrder == HEALPIX_RING) { healpix_pix2ang_ring(_mapNside, i, &theta, &phi); } else { healpix_pix2ang_nest(_mapNside, i, &theta, &phi); } if (theta < mapMinTheta) { mapMinTheta = theta; } if (theta > mapMaxTheta) { mapMaxTheta = theta; } if (phi < mapMinPhi) { mapMinPhi = phi; } if (phi > mapMaxPhi) { mapMaxPhi = phi; } } } if (mapMaxTheta < mapMinTheta) { // no valid data in map mapMaxTheta = HEALPIX_PI; mapMinTheta = 0.0; mapMaxPhi = 2.0*HEALPIX_PI; mapMinPhi = 0.0; } if (_config->_autoTheta) { _config->_thetaMin = mapMinTheta; _config->_thetaMax = mapMaxTheta; } if (_config->_autoPhi) { _config->_phiMin = mapMinPhi; _config->_phiMax = mapMaxPhi; } //qDebug() << "HEALPIX autorange is Theta=[" << mapMinTheta << "..." << mapMaxTheta << "] Phi=[" << mapMinPhi << "..." << mapMaxPhi << "]"; } //qDebug() << "HEALPIX using range Theta=[" << _thetaMin << "..." << _thetaMax << "] Phi=[" << _phiMin << "..." << _phiMax << "]"; // copy sphere data to matrix. for (int i = xStart; i < nxread; i++) { for (int j = yStart; j < nyread; j++) { healpix_proj_rev_car(_config->_thetaMin, _config->_thetaMax, _config->_phiMin, _config->_phiMax, (double)_config->_nX, (double)_config->_nY, (double)i, (double)j, &theta, &phi); if ((!healpix_is_dnull(theta)) && (!healpix_is_dnull(phi))) { if (_mapOrder == HEALPIX_RING) { healpix_ang2pix_ring(_mapNside, theta, phi, &ppix); } else { healpix_ang2pix_nest(_mapNside, theta, phi, &ppix); } if (!healpix_is_fnull(mapdata[ppix])) { data->z[i*nyread+j] = (double)mapdata[ppix]; } } } } free(mapdata); // FIXME // Eventually, we can just always use radians for the // matrix range, since actual display units will be // handled by the Kst2DRenderer. For now, set the matrix // range to the same units used in the config dialog. // Note that this behaviour is broken, since 2 maps // from different files could be put on the same plot // in different units. It's the best we can do for now. // //data->yMin = _thetaMax; //data->yStepSize = -(_thetaMax - _thetaMin)/(double)_nY; //data->xMin = _phiMin; //if (_phiMin > _phiMax) { // data->xStepSize = (_phiMax + (2.0*HEALPIX_PI - _phiMin)) / (double)_nX; //} else { // data->xStepSize = ((_phiMax - _phiMin) / (double)_nX; //} double tMin = _config->_thetaMin; double tMax = _config->_thetaMax; double pMin = _config->_phiMin; double pMax = _config->_phiMax; _config->theta2External(_config->_thetaUnits, tMin); _config->theta2External(_config->_thetaUnits, tMax); _config->phi2External(_config->_phiUnits, pMin); _config->phi2External(_config->_phiUnits, pMax); //qDebug() << "HEALPIX exported range Theta=[" << tMin << "..." << tMax << "] Phi=[" << pMin << "..." << pMax << "]"; switch (_config->_thetaUnits) { case HPUNIT_RAD: case HPUNIT_DEG: data->yMin = tMax; data->yStepSize = (tMin - tMax)/(double)_config->_nY; break; case HPUNIT_RADEC: case HPUNIT_LATLON: data->yMin = tMax; data->yStepSize = (tMin - tMax)/(double)_config->_nY; break; default: break; } data->xMin = pMin; switch (_config->_phiUnits) { case HPUNIT_RAD: if (pMin > pMax) { data->xStepSize = (pMax + (2.0*HEALPIX_PI-pMin)) / (double)_config->_nX; } else { data->xStepSize = (pMax - pMin) / (double)_config->_nX; } break; case HPUNIT_DEG: case HPUNIT_RADEC: if (pMin > pMax) { data->xStepSize = (pMax + (360.0-pMin)) / (double)_config->_nX; } else { data->xStepSize = (pMax - pMin) / (double)_config->_nX; } break; case HPUNIT_LATLON: if (pMin > pMax) { data->xStepSize = ((180.0+pMax) + (180.0-pMin)) / (double)_config->_nX; } else { data->xStepSize = (pMax - pMin) / (double)_config->_nX; } break; default: break; } return nxread*nyread; } else { return -1; } } int HealpixSource::readField(double *v, const QString& field, int s, int n) { Q_UNUSED(s) if (_valid && isValidField(field)) { fitsfile *fp; int coltheta; int colphi; int ret = 0; int ncol; int ttype; long nrows; long pcount; int tfields; char extname[HEALPIX_STRNL]; char comment[HEALPIX_STRNL]; float *datavec; int *pixvec; int *hits; float *mapdata; float *comptheta; float *compphi; float nullval; int nnull; size_t vecNside; size_t temppix; int fieldnum; double theta, phi; long nearest[8]; int keynpix; int keyfirst; int ischunk; long nelem; if (_fieldList.contains(field)) { fieldnum = _fieldList.findIndex(field); } else { fieldnum = field.toInt(); fieldnum--; } // check range if (n <= 0) { return -1; } vecNside = _mapNside; for (int i = 0; i < _config->_vecDegrade; i++) { vecNside = (size_t)(vecNside/2); } if (_mapType == HEALPIX_FITS_CUT) { // cut-sphere files have extra pixel/hits/error columns coltheta = _config->_vecTheta + 2; colphi = _config->_vecPhi + 2; ncol = (int)_nMaps + 3; } else { coltheta = _config->_vecTheta + 1; colphi = _config->_vecPhi + 1; ncol = (int)_nMaps; } // open file and move to second header unit if (fits_open_file(&fp, _healpixfile, READONLY, &ret)) { return -1; } if (fits_movabs_hdu(fp, 2, &ttype, &ret)) { return -1; } // read the number of rows if (fits_read_btblhdr(fp, ncol, &nrows, &tfields, NULL, NULL, NULL, extname, &pcount, &ret)) { ret = 0; fits_close_file(fp, &ret); return -1; } mapdata = (float*)calloc(_mapNpix, sizeof(float)); hits = (int*)calloc(12*vecNside*vecNside, sizeof(int)); //----------------------------------------- // Read in the first component and degrade //----------------------------------------- for (size_t j = 0; j < _mapNpix; j++) { mapdata[j] = HEALPIX_NULL; } if (_mapType == HEALPIX_FITS_CUT) { datavec = (float*)calloc((size_t) nrows, sizeof(float)); pixvec = (int*)calloc((size_t) nrows, sizeof(int)); if (fits_read_col(fp, TINT, 1, 1, 1, nrows, &nullval, pixvec, &nnull, &ret)) { free(pixvec); free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } if (fits_read_col(fp, TFLOAT, coltheta, 1, 1, nrows, &nullval, datavec, &nnull, &ret)) { free(pixvec); free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } for (long j = 0; j < nrows; j++) { if ((pixvec[j] >= 0) && (pixvec[j] < (int)_mapNpix)) { mapdata[pixvec[j]] = datavec[j]; } } free(pixvec); free(datavec); } else { /* is this a chunk? */ if ((nrows != (long)(_mapNpix))&&(1024*nrows != (long)(_mapNpix))) { /*this must be a chunk file*/ char charFirstPix[] = "FIRSTPIX"; if (fits_read_key(fp, TLONG, charFirstPix, &keyfirst, comment, &ret)) { /*must at least have FIRSTPIX key*/ fits_close_file(fp, &ret); return 0; } else { char charNPix[] = "NPIX"; if (fits_read_key(fp, TLONG, charNPix, &keynpix, comment, &ret)) { ret = 0; /*might be using LASTPIX instead*/ char charLastPix[] = "LASTPIX"; if (fits_read_key(fp, TLONG, charLastPix, &keynpix, comment, &ret)) { fits_close_file(fp, &ret); return 0; } else { keynpix = keynpix - keyfirst + 1; ischunk = 1; } } else { ischunk = 1; } } } else { ischunk = 0; } if (ischunk) { datavec = (float*)calloc((size_t)keynpix, sizeof(float)); nelem = (long)keynpix; } else { datavec = (float*)calloc(_mapNpix, sizeof(float)); nelem = (long)(_mapNpix); } if (fits_read_col(fp, TFLOAT, coltheta, 1, 1, nelem, &nullval, datavec, &nnull, &ret)) { free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } if (ischunk) { for (long j = 0; j < nelem; j++) { mapdata[j+keyfirst] = datavec[j]; } } else { for (long j = 0; j < nelem; j++) { mapdata[j] = datavec[j]; } } free(datavec); } comptheta = (float*)calloc(12*vecNside*vecNside, sizeof(float)); for (size_t i = 0; i < 12*vecNside*vecNside; i++) { comptheta[i] = HEALPIX_NULL; hits[i] = 0; } for (size_t i = 0; i < _mapNpix; i++) { if (!healpix_is_fnull(mapdata[i])) { if (_mapOrder == HEALPIX_NEST) { healpix_degrade_nest(_mapNside, i, vecNside, &temppix); } else { healpix_degrade_ring(_mapNside, i, vecNside, &temppix); } if (!healpix_is_fnull(comptheta[temppix])) { comptheta[temppix] += mapdata[i]; } else { comptheta[temppix] = mapdata[i]; } hits[temppix] += 1; } } for (size_t i = 0; i < 12*vecNside*vecNside; i++) { if (!healpix_is_fnull(comptheta[i])) { comptheta[i] = comptheta[i] / (double)hits[i]; } } //----------------------------------------- // Read in the second component and degrade //----------------------------------------- for (size_t j = 0; j < _mapNpix; j++) { mapdata[j] = HEALPIX_NULL; } if (_mapType == HEALPIX_FITS_CUT) { datavec = (float*)calloc((size_t) nrows, sizeof(float)); pixvec = (int*)calloc((size_t) nrows, sizeof(int)); if (fits_read_col(fp, TINT, 1, 1, 1, nrows, &nullval, pixvec, &nnull, &ret)) { free(pixvec); free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } if (fits_read_col(fp, TFLOAT, colphi, 1, 1, nrows, &nullval, datavec, &nnull, &ret)) { free(pixvec); free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } for (long j = 0; j < nrows; j++) { if ((pixvec[j] >= 0) && (pixvec[j] < (int)_mapNpix)) { mapdata[pixvec[j]] = datavec[j]; } } free(pixvec); free(datavec); } else { /* is this a chunk? */ if ((nrows != (long)(_mapNpix))&&(1024*nrows != (long)(_mapNpix))) { /*this must be a chunk file*/ char charFirstPix[] = "FIRSTPIX"; if (fits_read_key(fp, TLONG, charFirstPix, &keyfirst, comment, &ret)) { /*must at least have FIRSTPIX key*/ fits_close_file(fp, &ret); return 0; } else { char charNPix[] = "NPIX"; if (fits_read_key(fp, TLONG, charNPix, &keynpix, comment, &ret)) { ret = 0; /*might be using LASTPIX instead*/ char charLastPix[] = "LASTPIX"; if (fits_read_key(fp, TLONG, charLastPix, &keynpix, comment, &ret)) { fits_close_file(fp, &ret); return 0; } else { keynpix = keynpix - keyfirst + 1; ischunk = 1; } } else { ischunk = 1; } } } else { ischunk = 0; } if (ischunk) { datavec = (float*)calloc((size_t)keynpix, sizeof(float)); nelem = (long)keynpix; } else { datavec = (float*)calloc(_mapNpix, sizeof(float)); nelem = (long)(_mapNpix); } if (fits_read_col(fp, TFLOAT, colphi, 1, 1, nelem, &nullval, datavec, &nnull, &ret)) { free(datavec); free(mapdata); ret = 0; fits_close_file(fp, &ret); return -1; } if (ischunk) { for (long j = 0; j < nelem; j++) { mapdata[j+keyfirst] = datavec[j]; } } else { for (long j = 0; j < nelem; j++) { mapdata[j] = datavec[j]; } } free(datavec); } compphi = (float*)calloc(12*vecNside*vecNside, sizeof(float)); for (size_t i = 0; i < 12*vecNside*vecNside; i++) { compphi[i] = HEALPIX_NULL; hits[i] = 0; } for (size_t i = 0; i < _mapNpix; i++) { if (!healpix_is_fnull(mapdata[i])) { if (_mapOrder == HEALPIX_NEST) { healpix_degrade_nest(_mapNside, i, vecNside, &temppix); } else { healpix_degrade_ring(_mapNside, i, vecNside, &temppix); } if (!healpix_is_fnull(compphi[temppix])) { compphi[temppix] += mapdata[i]; } else { compphi[temppix] = mapdata[i]; } hits[temppix] += 1; } } for (size_t i = 0; i < 12*vecNside*vecNside; i++) { if (!healpix_is_fnull(compphi[i])) { compphi[i] = compphi[i] / (double)hits[i]; } } free(hits); free(mapdata); fits_close_file(fp, &ret); //---------------------------------------------- // compute head and tail coordinates in radians //---------------------------------------------- // autoscale magnitude if necessary double vecMag = 0.0; if (_config->_autoMag) { for (size_t i = 0; i < 12*vecNside*vecNside; i++) { if (sqrt((double)(comptheta[i]*comptheta[i] + compphi[i]*compphi[i])) > vecMag) { vecMag = sqrt((double)(comptheta[i]*comptheta[i] + compphi[i]*compphi[i])); } } } else { vecMag = _config->_maxMag; } // find distance to 4 nearest neighbor pixels and // use the average to compute how "long" the max // valued vector should be for a given pixel. // This is *expensive*, but we only load vector // fields infrequently, so should be ok. // only actually compute the component of the // vectorfield that is requested. double maxang; double thetapart; double phipart; double headtheta; double tailtheta; double headphi; double tailphi; double pmag; double alpha; // only compute as many elements as requested for (size_t i = 0; i < (size_t)n; i++) { if (!healpix_is_fnull(comptheta[i]) && !healpix_is_fnull(compphi[i])) { if (_config->_vecQU) { //theta is really Q, phi really U pmag = sqrt((double)(comptheta[i]*comptheta[i] + compphi[i]*compphi[i])); alpha = 0.5 * atan((double)compphi[i] / (double)comptheta[i]); thetapart = pmag * cos(alpha); phipart = pmag * sin(alpha); } else { thetapart = (double)comptheta[i]; phipart = (double)compphi[i]; } if (_mapOrder == HEALPIX_RING) { healpix_pix2ang_ring(vecNside, i, &theta, &phi); } else { healpix_pix2ang_nest(vecNside, i, &theta, &phi); } //find max angle for this pixel healpix_neighbors(vecNside, _mapOrder, i, nearest); maxang = healpix_loc_dist(vecNside, _mapOrder, i, nearest[0]); maxang += healpix_loc_dist(vecNside, _mapOrder, i, nearest[1]); maxang += healpix_loc_dist(vecNside, _mapOrder, i, nearest[2]); maxang += healpix_loc_dist(vecNside, _mapOrder, i, nearest[3]); maxang /= 4.0; thetapart *= maxang / vecMag; phipart *= maxang / vecMag; //find coordinates of head and tail headtheta = theta + 0.5 * thetapart; tailtheta = theta - 0.5 * thetapart; headphi = phi + 0.5 * phipart; tailphi = phi - 0.5 * phipart; while (headtheta > HEALPIX_PI) { headtheta -= HEALPIX_PI; } while (headtheta < 0.0) { headtheta += HEALPIX_PI; } while (tailtheta > HEALPIX_PI) { tailtheta -= HEALPIX_PI; } while (tailtheta < 0.0) { tailtheta += HEALPIX_PI; } while (headphi > 2.0 * HEALPIX_PI) { headphi -= 2.0 * HEALPIX_PI; } while (headphi < 0.0) { headphi += 2.0 * HEALPIX_PI; } while (tailphi > 2.0 * HEALPIX_PI) { tailphi -= 2.0 * HEALPIX_PI; } while (tailphi < 0.0) { tailphi += 2.0 * HEALPIX_PI; } switch (fieldnum) { case 0: //head theta v[i] = headtheta; break; case 1: //head phi v[i] = headphi; break; case 2: //tail theta v[i] = tailtheta; break; case 3: //tail phi v[i] = tailphi; break; default: break; } } } return n; } else { return -1; } } bool HealpixSource::isValidField(const QString& field) const { // need to allow for referencing fields by number, so // that command line options work. if (_fieldList.contains(field)) { return true; } else { bool ok = false; int num = field.toInt(&ok); if (ok && num <= (int)_fieldList.count() && num != 0) { return true; } else { return false; } } return _fieldList.contains(field); } bool HealpixSource::isValidMatrix(const QString& field) const { // need to allow for referencing fields by number, so // that command line options work. if (_matrixList.contains(field)) { return true; } else { bool ok = false; int num = field.toInt(&ok); if (ok && num <= (int)_matrixList.count() && num != 0) { return true; } else { return false; } } } int HealpixSource::samplesPerFrame(const QString &field) { Q_UNUSED(field) return 1; } int HealpixSource::frameCount(const QString& field) const { Q_UNUSED(field) if (_valid) { // return the number of pixels in the sky for // the degraded vectorfield size_t vecNside = _mapNside; for (int i = 0; i < _config->_vecDegrade; i++) { vecNside = (size_t)(vecNside/2); } return (int)(12*vecNside*vecNside); } else { return 0; } } bool HealpixSource::isEmpty() const { return !_valid; } QString HealpixSource::fileType() const { return healpixTypeString; } void HealpixSource::save(QXmlStreamWriter &streamWriter) { Kst::DataSource::save(streamWriter); } void HealpixSource::parseProperties(QXmlStreamAttributes &properties) { _config->parseProperties(properties); } int HealpixSource::readScalar(double &S, const QString& scalar) { if (scalar == "FRAMES") { S = 1; return 1; } return 0; } int HealpixSource::readString(QString &S, const QString& string) { if (string == "FILE") { S = _filename; return 1; } else if (_metaData.contains(string)) { S = _metaData[string]; return 1; } return 0; } class ConfigWidgetHealpixInternal : public QWidget, public Ui_HealpixConfig { public: ConfigWidgetHealpixInternal(QWidget *parent) : QWidget(parent), Ui_HealpixConfig() { setupUi(this); } }; class ConfigWidgetHealpix : public Kst::DataSourceConfigWidget { public: ConfigWidgetHealpix() : Kst::DataSourceConfigWidget() { QGridLayout *layout = new QGridLayout(this); _hc = new ConfigWidgetHealpixInternal(this); layout->addWidget(_hc, 0, 0); layout->activate(); } ~ConfigWidgetHealpix() {} void setConfig(QSettings *cfg) { Kst::DataSourceConfigWidget::setConfig(cfg); } void load() { QStringList unitList; //FIXME add back in when we have a renderer //unitList.append("(Radians)"); //unitList.append("(Degrees)"); unitList.append("(RA/DEC)"); //unitList.append("(Lat/Long)"); _cfg->beginGroup("Healpix General"); _hc->matThetaUnits->clear(); _hc->matPhiUnits->clear(); _hc->vecTheta->clear(); _hc->vecPhi->clear(); _hc->matThetaUnits->insertStringList(unitList); _hc->matPhiUnits->insertStringList(unitList); //FIXME change to HPUNIT_RAD _hc->matThetaUnits->setCurrentItem(0); _hc->matPhiUnits->setCurrentItem(0); _hc->matDimX->setValue(_cfg->value("Matrix X Dimension", DEFAULT_XDIM).toInt()); _hc->matDimY->setValue(_cfg->value("Matrix Y Dimension", DEFAULT_YDIM).toInt()); _hc->matThetaAuto->setChecked(_cfg->value("Theta Autoscale", true).toBool()); //FIXME Only one combobox item for now... //_hc->matThetaUnits->setCurrentItem(_cfg->readEntry("Theta Units", HPUNIT_RAD)); _hc->matThetaUnits->setCurrentItem(0); _hc->matThetaMin->setText(_cfg->value("Theta Min").toString()); _hc->matThetaMax->setText(_cfg->value("Theta Max").toString()); _hc->matPhiAuto->setChecked(_cfg->value("Phi Autoscale", true).toBool()); //FIXME Only one combobox item for now... //_hc->matPhiUnits->setCurrentItem(_cfg->readEntry("Phi Units", HPUNIT_RAD)); _hc->matPhiUnits->setCurrentItem(0); _hc->matPhiMin->setText(_cfg->value("Phi Min").toString()); _hc->matPhiMax->setText(_cfg->value("Phi Max").toString()); _hc->vecTheta->setCurrentItem(_cfg->value("Vector Theta", 0).toInt()); _hc->vecPhi->setCurrentItem(_cfg->value("Vector Phi", 0).toInt()); _hc->vecDegrade->setValue(_cfg->value("Vector Degrade Factor", 1).toInt()); _hc->vecMagAuto->setChecked(_cfg->value("Vector Magnitude Autoscale", true).toBool()); _hc->vecMag->setText(_cfg->value("Vector Max Magnitude").toString()); _hc->vecQU->setChecked(_cfg->value("Vector is QU", false).toBool()); bool hasInstance = (_instance != 0L); if (hasInstance) { _hc->vecTheta->insertStringList(_instance->matrixList()); _hc->vecPhi->insertStringList(_instance->matrixList()); Kst::SharedPtr src = Kst::kst_cast(_instance); assert(src); _cfg->endGroup(); _cfg->beginGroup(src->fileName()); _hc->matDimX->setValue(_cfg->value("Matrix X Dimension", DEFAULT_XDIM).toInt()); _hc->matDimY->setValue(_cfg->value("Matrix Y Dimension", DEFAULT_YDIM).toInt()); _hc->matThetaAuto->setChecked(_cfg->value("Theta Autoscale", true).toBool()); //FIXME Only one combobox item for now... //_hc->matThetaUnits->setCurrentItem(_cfg->readEntry("Theta Units", HPUNIT_RAD)); _hc->matThetaUnits->setCurrentItem(0); _hc->matThetaMin->setText(_cfg->value("Theta Min").toString()); _hc->matThetaMax->setText(_cfg->value("Theta Max").toString()); _hc->matPhiAuto->setChecked(_cfg->value("Phi Autoscale", true).toBool()); //FIXME Only one combobox item for now... //_hc->matPhiUnits->setCurrentItem(_cfg->readEntry("Phi Units", HPUNIT_RAD)); _hc->matPhiUnits->setCurrentItem(0); _hc->matPhiMin->setText(_cfg->value("Phi Min").toString()); _hc->matPhiMax->setText(_cfg->value("Phi Max").toString()); _hc->vecTheta->setCurrentItem(_cfg->value("Vector Theta", 0).toInt()); _hc->vecPhi->setCurrentItem(_cfg->value("Vector Phi", 0).toInt()); _hc->vecDegrade->setValue(_cfg->value("Vector Degrade Factor", 1).toInt()); _hc->vecMagAuto->setChecked(_cfg->value("Vector Magnitude Autoscale", true).toBool()); _hc->vecMag->setText(_cfg->value("Vector Max Magnitude").toString()); _hc->vecQU->setChecked(_cfg->value("Vector is QU", false).toBool()); _cfg->endGroup(); } } void save() { assert(_cfg); _cfg->beginGroup("Healpix General"); // If we have an instance, save settings for that instance only Kst::SharedPtr src = Kst::kst_cast(_instance); if (src) { _cfg->endGroup(); _cfg->beginGroup(src->fileName()); } _cfg->writeEntry("Matrix X Dimension", _hc->matDimX->value()); _cfg->writeEntry("Matrix Y Dimension", _hc->matDimY->value()); _cfg->writeEntry("Theta Autoscale", _hc->matThetaAuto->isChecked()); //FIXME override for now //_cfg->writeEntry("Theta Units", _hc->matThetaUnits->currentItem()); _cfg->writeEntry("Theta Units", HPUNIT_RADEC); _cfg->writeEntry("Theta Min", _hc->matThetaMin->text()); _cfg->writeEntry("Theta Max", _hc->matThetaMax->text()); _cfg->writeEntry("Phi Autoscale", _hc->matPhiAuto->isChecked()); //FIXME override for now //_cfg->writeEntry("Phi Units", _hc->matPhiUnits->currentItem()); _cfg->writeEntry("Phi Units", HPUNIT_RADEC); _cfg->writeEntry("Phi Min", _hc->matPhiMin->text()); _cfg->writeEntry("Phi Max", _hc->matPhiMax->text()); _cfg->writeEntry("Vector Theta", _hc->vecTheta->currentItem()); _cfg->writeEntry("Vector Phi", _hc->vecPhi->currentItem()); _cfg->writeEntry("Vector Degrade Factor", _hc->vecDegrade->value()); _cfg->writeEntry("Vector Magnitude Autoscale", _hc->vecMagAuto->isChecked()); _cfg->writeEntry("Vector Max Magnitude", _hc->vecMag->text()); _cfg->writeEntry("Vector is QU", _hc->vecQU->isChecked()); _cfg->endGroup(); // Update the instance from our new settings if (src && src->reusable()) { src->_config->read(_cfg, src->fileName()); src->reset(); } } ConfigWidgetHealpixInternal *_hc; }; QString HealpixPlugin::pluginName() const { return "HEALPIX Source Reader"; } QString HealpixPlugin::pluginDescription() const { return "HEALPIX Source Reader"; } Kst::DataSource *HealpixPlugin::create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const { return new HealpixSource(store, cfg, filename, type, element); } QStringList HealpixPlugin::matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(type) QStringList matrixList; if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = healpixTypeString; } if ( understands(cfg, filename) ) { size_t poff; int mapType; int mapOrder; int mapCoord; size_t mapNside; size_t nMaps; char healpixfile[HEALPIX_STRNL]; healpix_keys *keys; char creator[HEALPIX_STRNL]; char extname[HEALPIX_STRNL]; char **names; char **units; strncpy(healpixfile, filename.toLatin1().data(), HEALPIX_STRNL); names = healpix_strarr_alloc(HEALPIX_FITS_MAXCOL); units = healpix_strarr_alloc(HEALPIX_FITS_MAXCOL); keys = healpix_keys_alloc(); if (healpix_fits_map_info(healpixfile, &mapNside, &mapOrder, &mapCoord, &mapType, &nMaps, creator, extname, names, units, keys)) { if (mapType == HEALPIX_FITS_CUT) { poff = 1; } else { poff = 0; } // populate the field list QString mapName; for (size_t i = 0; i < nMaps; i++) { if (strlen(names[i+poff]) == 0) { mapName.sprintf("%d - %s",(int)(i+1),"MAP"); } else { mapName.sprintf("%d - %s",(int)(i+1),names[i+poff]); } if (strlen(units[i+poff]) == 0) { mapName.sprintf("%s (%s)",mapName.toLatin1().data(),"Unknown Units"); } else { mapName.sprintf("%s (%s)",mapName.toLatin1().data(),units[i+poff]); } matrixList.append(mapName); } if (mapType == HEALPIX_FITS_CUT) { if (strlen(names[nMaps+1]) == 0) { mapName.sprintf("%s","HITS"); } else { mapName.sprintf("%s",names[nMaps+1]); } matrixList.append(mapName); if (strlen(names[nMaps+2]) == 0) { mapName.sprintf("%s","ERRORS"); } else { mapName.sprintf("%s",names[nMaps+2]); } if (strlen(units[nMaps+2]) == 0) { mapName.sprintf("%s (%s)",mapName.toLatin1().data(),"Unknown Units"); } else { mapName.sprintf("%s (%s)",mapName.toLatin1().data(),units[nMaps+2]); } matrixList.append(mapName); } } healpix_keys_free(keys); healpix_strarr_free(names, HEALPIX_FITS_MAXCOL); healpix_strarr_free(units, HEALPIX_FITS_MAXCOL); } return matrixList; } QStringList HealpixPlugin::scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList scalarList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = healpixTypeString; } scalarList.append("FRAMES"); return scalarList; } QStringList HealpixPlugin::stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList stringList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = healpixTypeString; } stringList.append("FILENAME"); int mapType; int mapOrder; int mapCoord; size_t mapNside; size_t nMaps; char healpixfile[HEALPIX_STRNL]; healpix_keys *keys; char creator[HEALPIX_STRNL]; char extname[HEALPIX_STRNL]; char **names; char **units; strncpy(healpixfile, filename.toLatin1().data(), HEALPIX_STRNL); names = healpix_strarr_alloc(HEALPIX_FITS_MAXCOL); units = healpix_strarr_alloc(HEALPIX_FITS_MAXCOL); keys = healpix_keys_alloc(); if (healpix_fits_map_info(healpixfile, &mapNside, &mapOrder, &mapCoord, &mapType, &nMaps, creator, extname, names, units, keys)) { // populate the metadata QString metaVal; QString metaName; metaName = "NSIDE"; metaVal.sprintf("%lu", (long unsigned int)mapNside); stringList.append(metaName); metaName = "NPIX"; size_t mapNpix = 12 * mapNside * mapNside; metaVal.sprintf("%lu", (long unsigned int)mapNpix); stringList.append(metaName); metaName = "ORDER"; metaVal.sprintf("%d", mapOrder); stringList.append(metaName); metaName = "COORD"; metaVal.sprintf("%d", mapCoord); stringList.append(metaName); metaName = "TYPE"; metaVal.sprintf("%d", mapType); stringList.append(metaName); metaName = "NMAPS"; metaVal.sprintf("%lu", (long unsigned int)nMaps); stringList.append(metaName); metaName = "CREATOR"; metaVal.sprintf("%s", creator); stringList.append(metaName); metaName = "EXTNAME"; metaVal.sprintf("%s", extname); stringList.append(metaName); for (size_t j = 0; j < keys->nskeys; j++) { metaName.sprintf("%s", keys->skeynames[j]); metaVal.sprintf("%s", keys->skeyvals[j]); stringList.append(metaName); } for (size_t j = 0; j < keys->nikeys; j++) { metaName.sprintf("%s", keys->ikeynames[j]); metaVal.sprintf("%d", keys->ikeyvals[j]); stringList.append(metaName); } for (size_t j = 0; j < keys->nfkeys; j++) { metaName.sprintf("%s", keys->fkeynames[j]); metaVal.sprintf("%e", keys->fkeyvals[j]); stringList.append(metaName); } } healpix_keys_free(keys); healpix_strarr_free(names, HEALPIX_FITS_MAXCOL); healpix_strarr_free(units, HEALPIX_FITS_MAXCOL); return stringList; } QStringList HealpixPlugin::fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(type) QStringList fieldList; if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = healpixTypeString; } if ( understands(cfg, filename) ) { fieldList.append("1 - Vector Field Head Theta"); fieldList.append("2 - Vector Field Head Phi"); fieldList.append("3 - Vector Field Tail Theta"); fieldList.append("4 - Vector Field Tail Phi"); } return fieldList; } int HealpixPlugin::understands(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) int ret; char thealpixfile[HEALPIX_STRNL]; int tOrder; int tCoord; int tType; size_t tNside; size_t tMaps; strncpy(thealpixfile, filename.toLatin1().data(), HEALPIX_STRNL); ret = healpix_fits_map_test(thealpixfile, &tNside, &tOrder, &tCoord, &tType, &tMaps); if (ret) { // MUST return 100, since LFIIO datasource returns 99 // for *all* valid FITS files return 100; } else { return 0; } } bool HealpixPlugin::supportsTime(QSettings *cfg, const QString& filename) const { //FIXME Q_UNUSED(cfg) Q_UNUSED(filename) return true; } QStringList HealpixPlugin::provides() const { QStringList rc; rc += "HEALPIX Source"; return rc; } Kst::DataSourceConfigWidget *HealpixPlugin::configWidget(QSettings *cfg, const QString& filename) const { Q_UNUSED(filename) ConfigWidgetHealpix *config = new ConfigWidgetHealpix; config->setConfig(cfg); config->load(); return config; } Q_EXPORT_PLUGIN2(kstdata_qimagesource, HealpixPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/healpix/healpix.h000644 001750 001750 00000010734 11544160210 021231 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef HEALPIX_H #define HEALPIX_H #include #include //#include #include "healpix_tools.h" class HealpixSource : public Kst::DataSource { Q_OBJECT public: HealpixSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e); ~HealpixSource(); bool init(); bool reset(); Kst::Object::UpdateType update(); bool matrixDimensions( const QString& matrix, int* xDim, int* yDim); int readMatrix(Kst::MatrixData* data, const QString& matrix, int xStart, int yStart, int xNumSteps, int yNumSteps); bool isValidMatrix(const QString& field) const; int readField(double *v, const QString &field, int s, int n); bool isValidField(const QString &field) const; int samplesPerFrame(const QString &field); int frameCount(const QString& field = QString::null) const; bool isEmpty() const; QString fileType() const; void save(QXmlStreamWriter &streamWriter); void parseProperties(QXmlStreamAttributes &properties); class Config; int readScalar(double &S, const QString& scalar); int readString(QString &S, const QString& string); private: mutable Config *_config; friend class ConfigWidgetHealpix; // file parameters int _mapType; int _mapOrder; int _mapCoord; size_t _mapNside; size_t _nMaps; size_t _mapNpix; char _healpixfile[HEALPIX_STRNL]; healpix_keys *_keys; char _creator[HEALPIX_STRNL]; char _extname[HEALPIX_STRNL]; char **_names; char **_units; QMap _metaData; }; class HealpixPlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~HealpixPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return false; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/healpix/healpix_tools_fits.cpp000644 001750 001750 00000051455 11544160210 024036 0ustar00synthsynth000000 000000 /*************************************************************************** healpix_tools.cpp - tools for healpix datasource ------------------- begin : Wed June 01 2005 copyright : (C) 2005 Ted Kisner email : tskisner.public@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "healpix_tools.h" /* FITS keys */ healpix_keys *healpix_keys_alloc() { healpix_keys *keys; keys = (healpix_keys *) calloc(1, sizeof(healpix_keys)); keys->nskeys = 0; keys->nikeys = 0; keys->nfkeys = 0; keys->skeynames = NULL; keys->skeyvals = NULL; keys->skeycoms = NULL; keys->ikeynames = NULL; keys->ikeyvals = NULL; keys->ikeycoms = NULL; keys->fkeynames = NULL; keys->fkeyvals = NULL; keys->fkeycoms = NULL; return keys; } int healpix_keys_free(healpix_keys * keys) { size_t i; if (keys) { for (i = 0; i < (keys->nskeys); i++) { free(keys->skeynames[i]); free(keys->skeyvals[i]); free(keys->skeycoms[i]); } if (keys->nskeys != 0) { free(keys->skeynames); free(keys->skeyvals); free(keys->skeycoms); } for (i = 0; i < (keys->nikeys); i++) { free(keys->ikeynames[i]); free(keys->ikeycoms[i]); } if (keys->nikeys != 0) { free(keys->ikeynames); free(keys->ikeyvals); free(keys->ikeycoms); } for (i = 0; i < (keys->nfkeys); i++) { free(keys->fkeynames[i]); free(keys->fkeycoms[i]); } if (keys->nfkeys != 0) { free(keys->fkeynames); free(keys->fkeyvals); free(keys->fkeycoms); } free(keys); } return 0; } int healpix_keys_clear(healpix_keys * keys) { size_t i; if (keys) { for (i = 0; i < (keys->nskeys); i++) { free(keys->skeynames[i]); free(keys->skeyvals[i]); free(keys->skeycoms[i]); } if (keys->nskeys != 0) { free(keys->skeynames); free(keys->skeyvals); free(keys->skeycoms); } for (i = 0; i < (keys->nikeys); i++) { free(keys->ikeynames[i]); free(keys->ikeycoms[i]); } if (keys->nikeys != 0) { free(keys->ikeynames); free(keys->ikeyvals); free(keys->ikeycoms); } for (i = 0; i < (keys->nfkeys); i++) { free(keys->fkeynames[i]); free(keys->fkeycoms[i]); } if (keys->nfkeys != 0) { free(keys->fkeynames); free(keys->fkeyvals); free(keys->fkeycoms); } keys->nskeys = 0; keys->nikeys = 0; keys->nfkeys = 0; keys->skeynames = NULL; keys->skeyvals = NULL; keys->skeycoms = NULL; keys->ikeynames = NULL; keys->ikeyvals = NULL; keys->ikeycoms = NULL; keys->fkeynames = NULL; keys->fkeyvals = NULL; keys->fkeycoms = NULL; } return 0; } /* add keys */ int healpix_keys_sadd(healpix_keys * keys, char *keyname, char *keyval, char *keycom) { if (keys) { (keys->skeynames) = (char **)realloc(keys->skeynames, ((keys->nskeys) + 1) * sizeof(char *)); (keys->skeynames[keys->nskeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char)); (keys->skeyvals) = (char **)realloc(keys->skeyvals, ((keys->nskeys) + 1) * sizeof(char *)); (keys->skeyvals[keys->nskeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char)); (keys->skeycoms) = (char **)realloc(keys->skeycoms, ((keys->nskeys) + 1) * sizeof(char *)); (keys->skeycoms[keys->nskeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char)); strncpy(keys->skeynames[keys->nskeys], keyname, HEALPIX_STRNL); strncpy(keys->skeyvals[keys->nskeys], keyval, HEALPIX_STRNL); strncpy(keys->skeycoms[keys->nskeys], keycom, HEALPIX_STRNL); (keys->nskeys)++; } return 0; } int healpix_keys_iadd(healpix_keys * keys, char *keyname, int keyval, char *keycom) { if (keys) { (keys->ikeynames) = (char **)realloc(keys->ikeynames, ((keys->nikeys) + 1) * sizeof(char *)); (keys->ikeynames[keys->nikeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char)); (keys->ikeyvals) = (int *)realloc(keys->ikeyvals, ((keys->nikeys) + 1) * sizeof(int)); (keys->ikeycoms) = (char **)realloc(keys->ikeycoms, ((keys->nikeys) + 1) * sizeof(char *)); (keys->ikeycoms[keys->nikeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char)); strncpy(keys->ikeynames[keys->nikeys], keyname, HEALPIX_STRNL); keys->ikeyvals[keys->nikeys] = keyval; strncpy(keys->ikeycoms[keys->nikeys], keycom, HEALPIX_STRNL); (keys->nikeys)++; } return 0; } int healpix_keys_fadd(healpix_keys * keys, char *keyname, float keyval, char *keycom) { if (keys) { (keys->fkeynames) = (char **)realloc(keys->fkeynames, ((keys->nfkeys) + 1) * sizeof(char *)); (keys->fkeynames[keys->nfkeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char)); (keys->fkeyvals) = (float *)realloc(keys->fkeyvals, ((keys->nfkeys) + 1) * sizeof(float)); (keys->fkeycoms) = (char **)realloc(keys->fkeycoms, ((keys->nfkeys) + 1) * sizeof(char *)); (keys->fkeycoms[keys->nfkeys]) = (char *)calloc(HEALPIX_STRNL, sizeof(char)); strncpy(keys->fkeynames[keys->nfkeys], keyname, HEALPIX_STRNL); keys->fkeyvals[keys->nfkeys] = keyval; strncpy(keys->fkeycoms[keys->nfkeys], keycom, HEALPIX_STRNL); (keys->nfkeys)++; } return 0; } /* read keys */ int healpix_keys_read(healpix_keys * keys, fitsfile * fp, int *ret) { int nread = 0; int rec = 0; size_t nexc = 21; char **exclist; char **inclist; char card[HEALPIX_STRNL]; char keyval[HEALPIX_STRNL]; char keycom[HEALPIX_STRNL]; char keytype; char keyname[HEALPIX_STRNL]; int keylen; exclist = healpix_strarr_alloc(nexc); inclist = healpix_strarr_alloc(1); /*exclude required keywords */ strcpy(exclist[0], "XTENSION"); strcpy(exclist[1], "BITPIX"); strcpy(exclist[2], "NAXIS*"); strcpy(exclist[3], "PCOUNT"); strcpy(exclist[4], "GCOUNT"); strcpy(exclist[5], "TFIELDS"); strcpy(exclist[6], "TTYPE*"); strcpy(exclist[7], "TFORM*"); strcpy(exclist[8], "TUNIT*"); strcpy(exclist[9], "EXTNAME"); strcpy(exclist[10], "PIXTYPE"); strcpy(exclist[11], "ORDERING"); strcpy(exclist[12], "NSIDE"); strcpy(exclist[13], "COORDSYS"); strcpy(exclist[14], "INDXSCHM"); strcpy(exclist[15], "GRAIN"); strcpy(exclist[16], "COMMENT"); strcpy(exclist[17], "TBCOL*"); strcpy(exclist[18], "SIMPLE"); strcpy(exclist[19], "EXTEND"); strcpy(exclist[19], "CREATOR"); strcpy(inclist[0], "*"); (*ret) = 0; if (fits_read_record(fp, rec, card, ret)) { return 0; } while (!fits_find_nextkey(fp, inclist, 1, exclist, (int)nexc, card, ret)) { fits_get_keyname(card, keyname, &keylen, ret); fits_parse_value(card, keyval, keycom, ret); fits_get_keytype(keyval, &keytype, ret); switch (keytype) { case 'I': healpix_keys_iadd(keys, keyname, atoi(keyval), keycom); break; case 'F': healpix_keys_fadd(keys, keyname, (float)atof(keyval), keycom); break; default: healpix_keys_sadd(keys, keyname, keyval, keycom); break; } nread++; } (*ret = 0); healpix_strarr_free(exclist, nexc); healpix_strarr_free(inclist, 1); return nread; } /* FITS file tests */ int healpix_fits_map_test(char *filename, size_t * nside, int *order, int *coord, int *type, size_t * nmaps) { fitsfile *fp; int ret = 0; int ttype; int inside; long nrows; long pcount; int tfields; int grain; char pixtype[HEALPIX_STRNL]; char coordstr[HEALPIX_STRNL]; char orderstr[HEALPIX_STRNL]; char indxstr[HEALPIX_STRNL]; char comment[HEALPIX_STRNL]; char extname[HEALPIX_STRNL]; float nullval = HEALPIX_NULL; int nnull; float testval; long keynpix; long keyfirst; int ischunk = 0; int lastcol; /* open file */ if (fits_open_file(&fp, filename, READONLY, &ret)) { return 0; } /* make sure extension is a binary table */ if (fits_movabs_hdu(fp, 2, &ttype, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } if (ttype != BINARY_TBL) { ret = 0; fits_close_file(fp, &ret); return 0; } /* determine the number of maps */ if (fits_read_btblhdr(fp, HEALPIX_FITS_MAXCOL, &nrows, &tfields, NULL, NULL, NULL, extname, &pcount, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } /* make sure this is a HEALPIX file */ char charPixType[] = "PIXTYPE"; if (fits_read_key(fp, TSTRING, charPixType, pixtype, comment, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } if (strncmp(pixtype, "HEALPIX", HEALPIX_STRNL) != 0) { ret = 0; fits_close_file(fp, &ret); return 0; } /* check required keywords (NSIDE, ORDERING, COORDSYS) */ char charNSide[] = "NSIDE"; char charOrdering[] = "ORDERING"; char charCoordSys[] = "COORDSYS"; if (fits_read_key(fp, TINT, charNSide, &inside, comment, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } (*nside) = (size_t) inside; if (healpix_nsidecheck(*nside)) { ret = 0; fits_close_file(fp, &ret); return 0; } if (fits_read_key(fp, TSTRING, charOrdering, orderstr, comment, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } if (strncmp(orderstr, "RING", HEALPIX_STRNL) == 0) { (*order) = HEALPIX_RING; } else if (strncmp(orderstr, "NESTED", HEALPIX_STRNL) == 0) { (*order) = HEALPIX_NEST; } else { ret = 0; fits_close_file(fp, &ret); return 0; } if (fits_read_key(fp, TSTRING, charCoordSys, coordstr, comment, &ret)) { ret = 0; (*coord) = HEALPIX_COORD_C; } else { if (strncmp(coordstr, "C", HEALPIX_STRNL) == 0) { (*coord) = HEALPIX_COORD_C; } else if (strncmp(coordstr, "G", HEALPIX_STRNL) == 0) { (*coord) = HEALPIX_COORD_G; } else if (strncmp(coordstr, "E", HEALPIX_STRNL) == 0) { (*coord) = HEALPIX_COORD_E; } else { (*coord) = HEALPIX_COORD_O; } } /* check for INDXSCHM and GRAIN. if not found, assume implicit */ char charObject[] = "OBJECT"; char charIndxSchm[] = "INDXSCHM"; char charGrain[] = "GRAIN"; strcpy(indxstr,""); if (fits_read_key(fp, TSTRING, charObject, indxstr, comment, &ret)) { ret = 0; if (fits_read_key(fp, TSTRING, charIndxSchm, indxstr, comment, &ret)) { ret = 0; (*type) = HEALPIX_FITS_FULL; } else { if (strncmp(indxstr, "EXPLICIT", HEALPIX_STRNL) == 0) { (*type) = HEALPIX_FITS_CUT; } else { (*type) = HEALPIX_FITS_FULL; } } if (fits_read_key(fp, TINT, charGrain, &grain, comment, &ret)) { ret = 0; grain = 0; } if (((grain == 0) && ((*type) == HEALPIX_FITS_CUT)) || ((grain != 0) && ((*type) == HEALPIX_FITS_FULL))) { ret = 0; fits_close_file(fp, &ret); return 0; } } else { if (strncmp(indxstr, "PARTIAL", HEALPIX_STRNL) == 0) { (*type) = HEALPIX_FITS_CUT; } else { if (strncmp(indxstr, "FULLSKY", HEALPIX_STRNL) == 0) { (*type) = HEALPIX_FITS_FULL; } else { if (fits_read_key(fp, TSTRING, charIndxSchm, indxstr, comment, &ret)) { ret = 0; (*type) = HEALPIX_FITS_FULL; } else { if (strncmp(indxstr, "EXPLICIT", HEALPIX_STRNL) == 0) { (*type) = HEALPIX_FITS_CUT; } else { (*type) = HEALPIX_FITS_FULL; } } if (fits_read_key(fp, TINT, charGrain, &grain, comment, &ret)) { ret = 0; grain = 0; } if (((grain == 0) && ((*type) == HEALPIX_FITS_CUT)) || ((grain != 0) && ((*type) == HEALPIX_FITS_FULL))) { ret = 0; fits_close_file(fp, &ret); return 0; } } } } /* check for chunk file and truncation */ char charFirstPix[] = "FIRSTPIX"; char charNPix[] = "NPIX"; char charLastPix[] = "LASTPIX"; if ((*type) == HEALPIX_FITS_FULL) { (*nmaps) = tfields; if ((nrows != (long)(12*inside*inside))&&(1024*nrows != (long)(12*inside*inside))) { /*is this a chunk file?*/ if (fits_read_key(fp, TLONG, charFirstPix, &keyfirst, comment, &ret)) { /*must at least have FIRSTPIX key*/ ret = 0; ischunk = 0; } else { if (fits_read_key(fp, TLONG, charNPix, &keynpix, comment, &ret)) { ret = 0; /*might be using LASTPIX instead*/ if (fits_read_key(fp, TLONG, charLastPix, &keynpix, comment, &ret)) { ret = 0; ischunk = 0; } else { keynpix = keynpix - keyfirst + 1; if ((keyfirst < 0)||(keynpix < 0)||(keynpix+keyfirst > (long)(12*inside*inside))) { ischunk = 0; } else { ischunk = 1; } } } else { if ((keyfirst < 0)||(keynpix < 0)||(keynpix+keyfirst > (long)(12*inside*inside))) { ischunk = 0; } else { ischunk = 1; } } } } else { /*header doesn't matter, since we have entire map*/ if (nrows == (long)(12*inside*inside)) { lastcol = 1; } else { lastcol = 1024; } } if (ischunk) { if (nrows == keynpix) { lastcol = 1; } else { lastcol = keynpix % 1024; if (lastcol == 0) { lastcol = 1024; } } } if (fits_read_col(fp, TFLOAT, 1, nrows, lastcol, 1, &nullval, &testval, &nnull, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } } else { (*nmaps) = tfields - 3; if (fits_read_col(fp, TFLOAT, 2, nrows, 1, 1, &nullval, &testval, &nnull, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } } fits_close_file(fp, &ret); return 1; } int healpix_fits_map_info(char *filename, size_t * nside, int *order, int *coord, int *type, size_t * nmaps, char *creator, char *extname, char **names, char **units, healpix_keys *keys) { fitsfile *fp; int ret = 0; int ttype; int inside; long nrows; long pcount; int tfields; int grain; char pixtype[HEALPIX_STRNL]; char coordstr[HEALPIX_STRNL]; char orderstr[HEALPIX_STRNL]; char indxstr[HEALPIX_STRNL]; char comment[HEALPIX_STRNL]; float nullval = HEALPIX_NULL; int nnull; float testval; long keynpix; long keyfirst; int ischunk = 0; int lastcol; /* open file */ if (fits_open_file(&fp, filename, READONLY, &ret)) { return 0; } /* read header info */ char charCreator[] = "CREATOR"; fits_read_key(fp, TSTRING, charCreator, creator, comment, &ret); ret = 0; /* make sure extension is a binary table */ if (fits_movabs_hdu(fp, 2, &ttype, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } if (ttype != BINARY_TBL) { ret = 0; fits_close_file(fp, &ret); return 0; } /* determine the number of maps */ if (fits_read_btblhdr(fp, HEALPIX_FITS_MAXCOL, &nrows, &tfields, names, NULL, units, extname, &pcount, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } /* make sure this is a HEALPIX file */ char charPixtype[] = "PIXTYPE"; if (fits_read_key(fp, TSTRING, charPixtype, pixtype, comment, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } if (strncmp(pixtype, "HEALPIX", HEALPIX_STRNL) != 0) { ret = 0; fits_close_file(fp, &ret); return 0; } /* check required keywords (NSIDE, ORDERING, COORDSYS) */ char charNSide[] = "NSIDE"; char charOrdering[] = "ORDERING"; char charCoordSys[] = "COORDSYS"; if (fits_read_key(fp, TINT, charNSide, &inside, comment, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } (*nside) = (size_t) inside; if (healpix_nsidecheck(*nside)) { ret = 0; fits_close_file(fp, &ret); return 0; } if (fits_read_key(fp, TSTRING, charOrdering, orderstr, comment, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } if (strncmp(orderstr, "RING", HEALPIX_STRNL) == 0) { (*order) = HEALPIX_RING; } else if (strncmp(orderstr, "NESTED", HEALPIX_STRNL) == 0) { (*order) = HEALPIX_NEST; } else { ret = 0; fits_close_file(fp, &ret); return 0; } if (fits_read_key(fp, TSTRING, charCoordSys, coordstr, comment, &ret)) { ret = 0; (*coord) = HEALPIX_COORD_C; } else { if (strncmp(coordstr, "C", HEALPIX_STRNL) == 0) { (*coord) = HEALPIX_COORD_C; } else if (strncmp(coordstr, "G", HEALPIX_STRNL) == 0) { (*coord) = HEALPIX_COORD_G; } else if (strncmp(coordstr, "E", HEALPIX_STRNL) == 0) { (*coord) = HEALPIX_COORD_E; } else { (*coord) = HEALPIX_COORD_O; } } /* check for INDXSCHM and GRAIN. if not found, assume implicit */ char charObject[] = "OBJECT"; char charIndxSchm[] = "INDXSCHM"; char charGrain[] = "GRAIN"; strcpy(indxstr,""); if (fits_read_key(fp, TSTRING, charObject, indxstr, comment, &ret)) { ret = 0; if (fits_read_key(fp, TSTRING, charIndxSchm, indxstr, comment, &ret)) { ret = 0; (*type) = HEALPIX_FITS_FULL; } else { if (strncmp(indxstr, "EXPLICIT", HEALPIX_STRNL) == 0) { (*type) = HEALPIX_FITS_CUT; } else { (*type) = HEALPIX_FITS_FULL; } } if (fits_read_key(fp, TINT, charGrain, &grain, comment, &ret)) { ret = 0; grain = 0; } if (((grain == 0) && ((*type) == HEALPIX_FITS_CUT)) || ((grain != 0) && ((*type) == HEALPIX_FITS_FULL))) { ret = 0; fits_close_file(fp, &ret); return 0; } } else { if (strncmp(indxstr, "PARTIAL", HEALPIX_STRNL) == 0) { (*type) = HEALPIX_FITS_CUT; } else { if (strncmp(indxstr, "FULLSKY", HEALPIX_STRNL) == 0) { (*type) = HEALPIX_FITS_FULL; } else { if (fits_read_key(fp, TSTRING, charIndxSchm, indxstr, comment, &ret)) { ret = 0; (*type) = HEALPIX_FITS_FULL; } else { if (strncmp(indxstr, "EXPLICIT", HEALPIX_STRNL) == 0) { (*type) = HEALPIX_FITS_CUT; } else { (*type) = HEALPIX_FITS_FULL; } } if (fits_read_key(fp, TINT, charGrain, &grain, comment, &ret)) { ret = 0; grain = 0; } if (((grain == 0) && ((*type) == HEALPIX_FITS_CUT)) || ((grain != 0) && ((*type) == HEALPIX_FITS_FULL))) { ret = 0; fits_close_file(fp, &ret); return 0; } } } } /* read extension keys */ healpix_keys_read(keys, fp, &ret); /* check for chunk file and truncation */ char charFirstPix[] = "FIRSTPIX"; char charNPix[] = "NPIX"; char charLastPix[] = "LASTPIX"; if ((*type) == HEALPIX_FITS_FULL) { (*nmaps) = tfields; if ((nrows != (long)(12*inside*inside))&&(1024*nrows != (long)(12*inside*inside))) { /*is this a chunk file?*/ if (fits_read_key(fp, TLONG, charFirstPix, &keyfirst, comment, &ret)) { /*must at least have FIRSTPIX key*/ ret = 0; ischunk = 0; } else { if (fits_read_key(fp, TLONG, charNPix, &keynpix, comment, &ret)) { ret = 0; /*might be using LASTPIX instead*/ if (fits_read_key(fp, TLONG, charLastPix, &keynpix, comment, &ret)) { ret = 0; ischunk = 0; } else { keynpix = keynpix - keyfirst + 1; if ((keyfirst < 0)||(keynpix < 0)||(keynpix+keyfirst > (long)(12*inside*inside))) { ischunk = 0; } else { ischunk = 1; } } } else { if ((keyfirst < 0)||(keynpix < 0)||(keynpix+keyfirst > (long)(12*inside*inside))) { ischunk = 0; } else { ischunk = 1; } } } } else { /*header doesn't matter, since we have entire map*/ if (nrows == (long)(12*inside*inside)) { lastcol = 1; } else { lastcol = 1024; } } if (ischunk) { if (nrows == keynpix) { lastcol = 1; } else { lastcol = keynpix % 1024; if (lastcol == 0) { lastcol = 1024; } } } if (fits_read_col(fp, TFLOAT, 1, nrows, lastcol, 1, &nullval, &testval, &nnull, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } } else { (*nmaps) = tfields - 3; if (fits_read_col(fp, TFLOAT, 2, nrows, 1, 1, &nullval, &testval, &nnull, &ret)) { ret = 0; fits_close_file(fp, &ret); return 0; } } fits_close_file(fp, &ret); return 1; } kst-2.0.3/src/datasources/dmc/dmcdata.h000644 001750 001750 00000003366 11544160210 020310 0ustar00synthsynth000000 000000 /*************************************************************************** dmcdata.h - Part of KST ------------------- begin : Wed July 4 2007 copyright : (C) 2007 The University of Toronto email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_DMCDATA_H #define KST_DMCDATA_H #include #include "sharedptr.h" extern "C" { #include "HL2_DMC/PIODB.h" } #include #include #include namespace DMC { extern bool haveDMC(); extern bool validDatabase(const QString&); class Source : public Kst::Shared { public: Source(); virtual ~Source(); virtual bool isValid() const; virtual bool updated() const; virtual bool setGroup(const QString& group); virtual QStringList fields() const; virtual void reset(); virtual int readObject(const QString& object, double *buf, long start, long end); virtual QSize range(const QString& object) const; protected: bool _isValid; QString _group; }; } #endif kst-2.0.3/src/datasources/dmc/dmcsource.cpp000644 001750 001750 00000023577 11544160210 021240 0ustar00synthsynth000000 000000 /*************************************************************************** dmc.cpp - data source - planck DMC ------------------- begin : Wed July 4 2007 copyright : (C) 2007 The University of Toronto email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dmcsource.h" #include "debug.h" #include "kst_i18n.h" #include #include #include #include using namespace Kst; // // Vector interface // //------------------------------------------------------------------------------------------- class DataInterfaceDmcVector : public DataSource::DataInterface { public: DataInterfaceDmcVector(DmcSource& s) : src(s) {} // read one element int read(const QString&, DataVector::ReadInfo&); // named elements QStringList list() const { return src._fieldList; } bool isListComplete() const { #warning port/ review return true; } bool isValid(const QString& field) const { return src._fieldList.contains( field ); } // T specific const DataVector::DataInfo dataInfo(const QString&) const; void setDataInfo(const QString&, const DataVector::DataInfo&) {} // meta data QMap metaScalars(const QString&); QMap metaStrings(const QString&) { return QMap(); } DmcSource& src; }; //------------------------------------------------------------------------------------------- const DataVector::DataInfo DataInterfaceDmcVector::dataInfo(const QString &field) const { if (!src._fieldList.contains(field)) return DataVector::DataInfo(); return DataVector::DataInfo(src._numFrames, 1); } //------------------------------------------------------------------------------------------- int DataInterfaceDmcVector::read(const QString& field, DataVector::ReadInfo& p) { return src.readField(p.data, field, p.startingFrame, p.numberOfFrames); } //------------------------------------------------------------------------------------------- // TODO FRAMES only in vector? QMap DataInterfaceDmcVector::metaScalars(const QString&) { QMap m; m["FRAMES"] = src._numFrames;; return m; } // // DmcSource // static QString dmcTypeString = I18N_NOOP("PLANCK DMC I/O"); const QString& DmcSource::typeString() const { return dmcTypeString; } const QString DmcSource::dmcTypeKey() { return ::dmcTypeString; } DmcSource::DmcSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type), iv(new DataInterfaceDmcVector(*this)) { _filename = filename; _dmcObject = new DMC::Object; if (!_dmcObject->setGroup(filename)) { _dmcObject = 0L; // deref } if (_dmcObject && _dmcObject->isValid()) { _fieldList = _dmcObject->fields(); _fieldList.prepend("INDEX"); update(); _valid = true; } //qDebug() << "Planck source " << (void*)this << " created" << endl; } DmcSource::~DmcSource() { //qDebug() << "Planck source " << (void*)this << " destroyed" << endl; } void DmcSource::reset() { _valid = false; _dmcObject = new DMC::Object; // kshared - deletes the old one if (!_dmcObject->setGroup(_filename)) { _dmcObject = 0L; // deref } _fieldList.clear(); if (_dmcObject && _dmcObject->isValid()) { _fieldList = _dmcObject->fields(); _fieldList.prepend("INDEX"); update(); _valid = true; } } Object::UpdateType DmcSource::internalDataSourceUpdate() { #warning port /* if (_valid && _dmcObject && _dmcObject->updated()) { updateNumFramesScalar(); return setLastUpdateResult(Object::Updated); } return setLastUpdateResult(Object::NoChange); */ return Object::UpdateType(); } int DmcSource::readField(double *v, const QString& field, int s, int n) { //qDebug() << "Planck read field " << field << " - " << n << " samples from " << s << endl; if (field.toLower() == "index") { if (n < 0) { v[0] = double(s); return 1; } for (int i = 0; i < n; ++i) { v[i] = double(s + i); } return n > 0 ? n : 0; } if (!_valid || !_dmcObject || !_dmcObject->isValid()) { qDebug() << "tried to read from an invalid planck dmc source" << endl; qDebug() << "plugin is valid? " << _valid << endl; qDebug() << "Object object is non-null? " << (_dmcObject.data() != 0) << endl; return -1; } QSize sz = _dmcObject->range(field); long start = sz.width(), end = sz.height(); long count = end - start + 1; if (s >= count) { // start past the end return 0; } if (n < 0) { // reading less than 0 -> read only one sample! n = 1; } if (s + n > count) { // trying to read past the end n = count - s; } if (s + start > end) { qDebug() << "Nothing to read: (" << start << "," << end << ") " << s << endl; return 0; } assert(n != 0); return _dmcObject->readObject(field, v, start + s, start + s + n - 1); } int DmcSource::readField(double *v, const QString& field, int s, int n, int skip, int *lastFrameRead) { if (*lastFrameRead) { *lastFrameRead = -1; } if (field.toLower() == "index") { if (n < 0) { v[0] = double(s); if (*lastFrameRead) { *lastFrameRead = -1; // FIXME } return 1; } for (int i = 0; i < n; ++i) { v[i] = double(s + i*skip); } if (*lastFrameRead) { *lastFrameRead = -1; // FIXME } return n > 0 ? n : 0; } if (!_valid || !_dmcObject || !_dmcObject->isValid()) { return -1; } QSize sz = _dmcObject->range(field); long start = sz.width(), end = sz.height(); long count = end - start + 1; if (s >= count) { // start past the end return 0; } if (n < 0) { // reading less than 0 -> read only one sample! n = 1; } if (s + (n-1)*skip >= count) { // trying to read past the end qDebug() << "TRYING TO READ PAST END. n=" << n << endl; // n = ceil((count-s)/skip) if ((count - s) % skip == 0) { n = (count - s) / skip; } else { n = (count - s) / skip + 1; } qDebug() << "N IS NOW=" << n << endl; } if (s + start > end) { qDebug() << "Nothing to read: (" << start << "," << end << ") " << s << endl; return 0; } // PIOLib doesn't have a mechanism to read with skip. This needs to be added // later. For now, we read into a temp buffer, then extract what we need. double *tmp = new double[(n - 1) * skip + 1]; int rc = _dmcObject->readObject(field, tmp, start + s, start + s + (n - 1) * skip); //qDebug() << "readObject rc=" << rc << " from=" << start+s << " to=" << start + s + (n - 1) * skip << endl; int i = 0; while (i < n && i*skip < rc) { v[i] = tmp[i * skip]; ++i; } delete[] tmp; if (*lastFrameRead) { *lastFrameRead = -1; // FIXME } return i; } bool DmcSource::isValidField(const QString& field) const { return field.toLower() == "index" || _fieldList.contains(field); } int DmcSource::samplesPerFrame(const QString &field) { Q_UNUSED(field) return 1; } int DmcSource::frameCount(const QString& field) const { if (!_valid) { return 0; } if (field.isEmpty() || field.toLower() == "index" || !_fieldList.contains(field)) { int maxLen = 0; for (QStringList::ConstIterator i = _fieldList.begin(); i != _fieldList.end(); ++i) { assert(!(*i).isEmpty()); QSize sz = _dmcObject->range(*i); maxLen = qMax(sz.height() - sz.width() + 1, maxLen); } return maxLen; } QSize sz = _dmcObject->range(field); return sz.height() - sz.width() + 1; } QString DmcSource::fileType() const { return dmcTypeString; } void DmcSource::save(QTextStream &ts, const QString& indent) { #warning port //DataSource::save(ts, indent); } bool DmcSource::isEmpty() const { if (!_valid) { return true; } for (QStringList::ConstIterator i = _fieldList.begin(); i != _fieldList.end(); ++i) { QSize sz = _dmcObject->range(*i); if (sz.height() - sz.width() + 1 > 0) { return false; } } return true; } bool DmcSource::supportsTimeConversions() const { return _fieldList.contains("TIMES_OF_SAMPLES") || _fieldList.contains("TIMESEC"); } int DmcSource::sampleForTime(const QDateTime& time, bool *ok) { if (!_valid) { if (ok) { *ok = false; } return -1; } int tai = time.toTime_t() + 86400 * (365 * 12 + 3); return _dmcObject->sampleForTime(tai, ok); } int DmcSource::sampleForTime(double ms, bool *ok) { if (!_valid) { if (ok) { *ok = false; } return -1; } return _dmcObject->sampleForTimeRelative(ms, ok); } QDateTime DmcSource::timeForSample(int sample, bool *ok) { if (!_valid) { if (ok) { *ok = false; } return QDateTime(); } double t = _dmcObject->timeForSample(sample); if (t != t) { if (ok) { *ok = false; } return QDateTime(); } QDateTime dt; dt.setTime_t(int(floor(t + 0.5)) - (86400 * (365 * 12 + 3))); return dt; } double DmcSource::relativeTimeForSample(int sample, bool *ok) { if (!_valid) { if (ok) { *ok = false; } return -1; } double i = _dmcObject->timeForSample(0); double t = _dmcObject->timeForSample(sample); if (t != t || i != i) { if (ok) { *ok = false; } return -1; } return floor(t - i + 0.5) * 1000.0; } kst-2.0.3/src/datasources/dmc/dmcsource.h000644 001750 001750 00000005373 11544160210 020677 0ustar00synthsynth000000 000000 /*************************************************************************** dmc.h - data source plugin for planck DMC ------------------- begin : Wed July 4 2007 copyright : (C) 2007 The University of Toronto email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_DMCSOURCE_H #define KST_DMCSOURCE_H #include "datasource.h" #include "dmcdata.h" #include "dmcobj.h" #include "datasource.h" #include "dataplugin.h" class DataInterfaceDmcVector; class DmcSource : public Kst::DataSource { public: DmcSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement &element); ~DmcSource(); bool initFile(); Kst::Object::UpdateType internalDataSourceUpdate(); virtual const QString& typeString() const; static const QString dmcTypeKey(); int readScalar(double *v, const QString& field); int readString(QString *stringValue, const QString& stringName); int readField(double *v, const QString& field, int s, int n); int readMatrix(double *v, const QString& field); int samplesPerFrame(const QString& field); int frameCount(const QString& field = QString()) const; QString fileType() const; void save(QTextStream &ts, const QString& indent = QString()); bool isEmpty() const; void reset(); private: QMap _frameCounts; int _numFrames; QStringList _fieldList; DataInterfaceDmcVector* iv; // TODO remove friend friend class DataInterfaceDmcVector; // from kst1 old dmc code Kst::SharedPtr _dmcObject; QString _filename; void update(); int readField(double *v, const QString& field, int s, int n, int skip, int *lastFrameRead) ; bool isValidField(const QString& field) const; bool supportsTimeConversions() const; int sampleForTime(const QDateTime& time, bool *ok); QDateTime timeForSample(int sample, bool *ok); int sampleForTime(double ms, bool *ok); double relativeTimeForSample(int sample, bool *ok); }; #endif kst-2.0.3/src/datasources/dmc/Makefile.am000644 001750 001750 00000000624 11544160210 020570 0ustar00synthsynth000000 000000 INCLUDES=-I$(top_srcdir)/kst/src/libkst -I$(srcdir)/../../extdate $(DMCINCLUDES) $(TFINCLUDES) $(all_includes) kde_module_LTLIBRARIES=kstdata_dmc.la kstdata_dmc_la_LIBADD=$(DMCLIBS) $(TRANSFUNCS) kstdata_dmc_la_LDFLAGS=$(all_libraries) -module -avoid-version kstdata_dmc_la_SOURCES=dmc.cpp dmcdata.cpp dmcobj.cpp METASOURCES=AUTO services_DATA=kstdata_dmc.desktop servicesdir=$(kde_servicesdir)/kst kst-2.0.3/src/datasources/dmc/kstdata_dmc.desktop000644 001750 001750 00000003077 11544160210 022412 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=dmc X-Kst-Plugin-Author=The University of Toronto Name=PLANCK DMC Plugin Name[da]=PLANCK DMC-Plugin Name[el]=Πρόσθετο PLANCK DMC Name[es]=Plugin PLANCK DMC Name[et]=PLANCK DMC plugin Name[is]=PLANCK DMC íforrit Name[it]=Plugin PLANCK DMC Name[nds]=Moduul för't Lesen vun PLANCK-DMC-Daten Name[pt]='Plugin' DMC do PLANCK Name[pt_BR]='Plugin' DMC do PLANCK Name[sr]=PLANCK DMC прикључак Name[sr@Latn]=PLANCK DMC прикључак Name[sv]=Planck DMC-insticksprogram Name[vi]=Phần bổ sung DMC PLANCK Name[xx]=xxPLANCK DMC Pluginxx Comment=Plugin to read PLANCK DMC data. Comment[da]=Plugin til at læse PLANCK DMC-data. Comment[el]=Πρόσθετο για την ανάγνωση δεδομένων PLANCK DMC. Comment[es]=Plugin para leer datos PLANCK DMC. Comment[et]=Plugin PLANCK DMC andmete lugemiseks. Comment[is]=Íforrit til að lesa PLANCK DMC gögn. Comment[it]=Plugin per leggere dati PLANCK DMC. Comment[nds]=Moduul för't Lesen vun PLANCK-DMC-Daten Comment[nl]=Plugin voor het lezen van PLANCK DMC-gegevens. Comment[pt]=Um 'plugin' para ler os dados DMC do PLANCK. Comment[pt_BR]=Um 'plugin' para ler os dados DMC do PLANCK. Comment[sr]=Прикључак за читање PLANCK DMC података. Comment[sr@Latn]=Прикључак за читање PLANCK DMC података. Comment[sv]=Insticksprogram för att läsa Planck DMC-data. Comment[vi]=Phần bổ sung đọc dữ liệu DMC PLANCK. Comment[xx]=xxPlugin to read PLANCK DMC data.xx kst-2.0.3/src/datasources/dmc/dmcdata.cpp000644 001750 001750 00000004773 11544160210 020646 0ustar00synthsynth000000 000000 /*************************************************************************** dmcdata.cpp - Part of KST ------------------- begin : Wed July 4 2007 copyright : (C) 2007 The University of Toronto email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dmcdata.h" #include "stdlib.h" using namespace DMC; namespace DMC { bool haveDMC() { return true; } bool validDatabase(const QString& db) { if (getenv("PGUSER") == NULL || getenv("DBROOT") == NULL) { qDebug("DMC is missing environment variables"); /* DMC will lock up if these environment variables are not set */ return false; } PIOGroup *g = PIOOpenVoidGrp(const_cast(db.toLatin1().constData()), const_cast("r")); if (g) { PIOCloseVoidGrp(&g); // the call PIOOpenVoidGrp open the database, // the PIOCloseVoidGrp call do not close it // once one db is opened, // any subsequent open call will fail unless it is the same database // lets close it int rtc; #warning "Kst2 port use PIOQuitDB()" //rtc = PIOQuitDB(); if(rtc != 0) { // closing failed, dont care } return true; } return false; } } Source::Source() : Kst::Shared() { _isValid = false; } Source::~Source() { } bool Source::setGroup(const QString& group) { Q_UNUSED(group) return false; } void Source::reset() { _isValid = false; } bool Source::isValid() const { return _isValid; } QStringList Source::fields() const { return QStringList(); } int Source::readObject(const QString& object, double *buf, long start, long end) { Q_UNUSED(object) Q_UNUSED(buf) Q_UNUSED(start) Q_UNUSED(end) return 0; } bool Source::updated() const { return false; } QSize Source::range(const QString& object) const { Q_UNUSED(object) return QSize(); } kst-2.0.3/src/datasources/dmc/dmcplugin.cpp000644 001750 001750 00000013230 11544160210 021217 0ustar00synthsynth000000 000000 /*************************************************************************** dmcplugin.cpp ------------------- copyright : (C) 2010 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dmcplugin.h" #include "dmcsource.h" using namespace Kst; // // DmcPlugin // static const char* plugin_name= "PLANCK DMC I/O plugin"; QString DmcPlugin::pluginName() const { return plugin_name; } QString DmcPlugin::pluginDescription() const { return plugin_name; } Kst::DataSource *DmcPlugin::create( Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const { return new DmcSource(store, cfg, filename, type, element); } QStringList DmcPlugin::matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(cfg); Q_UNUSED(filename); Q_UNUSED(type); Q_UNUSED(typeSuggestion); Q_UNUSED(complete); return QStringList(); } QStringList DmcPlugin::scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(cfg); Q_UNUSED(filename); Q_UNUSED(type); Q_UNUSED(typeSuggestion); Q_UNUSED(complete); return QStringList(); } QStringList DmcPlugin::stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(cfg); Q_UNUSED(filename); Q_UNUSED(type); Q_UNUSED(typeSuggestion); Q_UNUSED(complete); QStringList stringList; return stringList; } QStringList DmcPlugin::fieldList( QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { /* old code QStringList fieldList_dmc(KConfig*, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) { if (!type.isEmpty() && !provides_dmc().contains(type)) { return QStringList(); } KstSharedPtr pobj = new DMC::Object; if (!pobj->setGroup(filename) || !pobj->isValid()) { return QStringList(); } if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = "PLANCK DMC I/O"; } QStringList rc = pobj->fields(); rc.prepend("INDEX"); return rc; } */ Q_UNUSED(cfg); Q_UNUSED(filename); Q_UNUSED(type); Q_UNUSED(typeSuggestion); Q_UNUSED(complete); if (!type.isEmpty() && !provides().contains(type)) { return QStringList(); } SharedPtr pobj = new DMC::Object; if (!pobj->setGroup(filename) || !pobj->isValid()) { return QStringList(); } if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = DmcSource::dmcTypeKey(); } QStringList rc = pobj->fields(); rc.prepend("INDEX"); return rc; } bool DmcPlugin::supportsTime( QSettings *cfg, const QString& filename) const { /* old code bool supportsTime_dmc(KConfig*, const QString& filename) { KstSharedPtr pobj = new DMC::Object; if (!pobj->setGroup(filename) || !pobj->isValid()) { return false; } return pobj->fields().contains("TIMES_OF_SAMPLES") || pobj->fields().contains("TIMESEC"); }*/ Q_UNUSED(cfg) Q_UNUSED(filename) SharedPtr pobj = new DMC::Object; if (!pobj->setGroup(filename) || !pobj->isValid()) { return false; } return pobj->fields().contains("TIMES_OF_SAMPLES") || pobj->fields().contains("TIMESEC"); } QStringList DmcPlugin::provides() const { return QStringList() << DmcSource::dmcTypeKey(); } Kst::DataSourceConfigWidget *DmcPlugin::configWidget( QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) Q_UNUSED(filename) return 0;; } int DmcPlugin::understands( QSettings *cfg, const QString& filename) const { /* old code int understands_dmc(KConfig*, const QString& filename) { bool rc = DMC::validDatabase(filename); qDebug() << "-> Valid dmc database? " << rc << endl; return rc ? 100 : 0; }*/ bool rc = DMC::validDatabase(filename); qDebug() << "-> Valid dmc database? " << rc << endl; return rc ? 100 : 0; } Q_EXPORT_PLUGIN2(kstdata_dmcsource, DmcPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/dmc/dmcplugin.h000644 001750 001750 00000006113 11544160210 020666 0ustar00synthsynth000000 000000 /*************************************************************************** dmcplugin.h ------------------- copyright : (C) 2010 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_DMC_PLUGIN_H #define KST_DMC_PLUGIN_H #include "datasource.h" #include "dataplugin.h" class DmcPlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~DmcPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return true; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/dmc/dmcobj.cpp000644 001750 001750 00000035667 11544160210 020515 0ustar00synthsynth000000 000000 /*************************************************************************** dmcobj.cpp - Part of KST ------------------- begin : Mon Oct 06 2003 copyright : (C) 2003 The University of Toronto email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include "debug.h" #include //#define PIOLIBDEBUG #include "dmcobj.h" #include "HL2_PIOLIB/PIOErr.h" #ifdef NAN double NOPOINT = NAN; #else double NOPOINT = 0.0/0.0; // NaN #endif using namespace DMC; class DMC::ObjectGroup { friend class Object; public: ObjectGroup(); ~ObjectGroup(); bool open(const QString& groupURL); void close(); bool updateObjectList(); PIOSTRING *objTypes; PIOSTRING *objNames; PIOINT objectListSize; PIOLONG *firstIndex; PIOLONG *lastIndex; PIOSTRING *TOItypes; PIOSTRING *Datatypes; PIOGroup *_group; bool _valid; }; DMC::TimeType Object::typeOfTime() { PIOParseData MyData, MyDataFlag; PIOObject *obj = 0L; char range[128]; DMC::ObjectGroup *g = findGroup(_group); assert(g); #ifdef PIOLONG_FMT snprintf(range, 127, "Begin=" PIOLONG_FMT "\nEnd=" PIOLONG_FMT, *g->firstIndex, *g->firstIndex); #else snprintf(range, 127, "Begin=%lld\nEnd=%lld", *g->firstIndex, *g->firstIndex); #endif long n = PIORead_1(const_cast("TIMES_OF_SAMPLES"), const_cast("Written"), const_cast("PIODOUBLE"), range, &g->_group, &obj, &MyData, &MyDataFlag); if (n != 1) { n = PIORead_1(const_cast("TIMESEC"), const_cast("Written"), const_cast("PIODOUBLE"), range, &g->_group, &obj, &MyData, &MyDataFlag); if (n != 1) { return DMC::Unknown; } else { return DMC::TimeSec; } } return DMC::TimesOfSamples; } double Object::fetchTimePoint(PIOLONG idx) { PIOParseData MyData, MyDataFlag; PIOObject *obj = 0L; char range[128]; long n; #ifdef PIOLONG_FMT snprintf(range, 127, "Begin=" PIOLONG_FMT "\nEnd=" PIOLONG_FMT, idx, idx); #else snprintf(range, 127, "Begin=%lld\nEnd=%lld", idx, idx); #endif double buf[1]; DMC::ObjectGroup *g = findGroup(_group); assert(g); static PIOFLAG Mask[1]; switch (_tt) { case DMC::TimeSec: n = PIORead_1(const_cast("TIMESEC"), const_cast("Written"), const_cast("PIODOUBLE"), range, &g->_group, &obj, &MyData, &MyDataFlag); PIORead_2(buf, 0L, Mask, const_cast("TIMESEC"), const_cast("PIODOUBLE"), range, const_cast("Written"), g->_group, &obj, &MyData, &MyDataFlag, PIOLONG(n)); break; case DMC::TimesOfSamples: n = PIORead_1(const_cast("TIMES_OF_SAMPLES"), const_cast("Written"), const_cast("PIODOUBLE"), range, &g->_group, &obj, &MyData, &MyDataFlag); PIORead_2(buf, 0L, Mask, const_cast("TIMES_OF_SAMPLES"), const_cast("PIODOUBLE"), range, const_cast("Written"), g->_group, &obj, &MyData, &MyDataFlag, PIOLONG(n)); break; default: return NOPOINT; } return buf[0]; } Object::Object() : Source() { #ifdef PIOLIBDEBUG kdDebug() << ">>>>>>>>> Object created " << (void*)this << endl; #endif _tt = Undetermined; } Object::~Object() { reset(); #ifdef PIOLIBDEBUG kdDebug() << "<<<<<<<<< Object deleted " << (void*)this << endl; #endif } bool Object::updated() const { if (_isValid) { ObjectGroup *tg = findGroup(_group); if (tg) { bool rc = PIOUPDATE == PIOCheckUpdateGrp(tg->_group); if (rc) { tg->updateObjectList(); } return rc; } } return false; } void Object::reset() { #ifdef PIOLIBDEBUG kdDebug() << ">>>>>>>>> Object reset" << endl; #endif for (QMap::Iterator i = _groupInfo.begin(); i != _groupInfo.end(); ++i) { delete (*i); } _groupInfo.clear(); Source::reset(); } bool Object::setGroup(const QString& group) { #ifdef PIOLIBDEBUG kdDebug() << ">>>>>>>>> Object set group - " << group << endl; #endif // FIXME: verify the source if (group != _group) { reset(); _group = group; } _isValid = true; return true; } QStringList Object::fields() const { QStringList rc; if (_isValid) { const ObjectGroup *tg = findGroup(_group); if (tg) { for (PIOINT i = 0; i < tg->objectListSize; ++i) { rc += tg->objNames[i]; } } } return rc; } QSize Object::range(const QString& object) const { if (isValid()) { const ObjectGroup *g = findGroup(_group); if (!g) { return QSize(0, 0); } int i; for (i = 0; i < g->objectListSize; ++i) { if (object == g->objNames[i]) { break; } } if (i == g->objectListSize) { #ifdef PIOLIBDEBUG kdDebug() << "Error finding object " << object << endl; #endif return QSize(0, 0); } return QSize(g->firstIndex[i], g->lastIndex[i]); } return QSize(0, 0); } int Object::readObject(const QString& object, double *buf, long start, long end) { #ifdef PIOLIBDEBUG kdDebug() << ">>>>>>>>> Object read object - " << _group << ":" << object << " from " << start << " to " << end << endl; #endif if (isValid()) { ObjectGroup *g = findGroup(_group); if (!g) { return 0; } int i; for (i = 0; i < g->objectListSize; ++i) { if (object == g->objNames[i]) { break; } } if (i == g->objectListSize) { return 0; } #ifdef PIOLIBDEBUG kdDebug() << "Found object " << object << " in group " << _group << " , type is " << g->objTypes[i] << ", data type is " << g->Datatypes[i] << endl; #endif QString range(""); if (start < 0 || end < start) { // Leave blank } else { range = QString("Begin=%1\nEnd=%2").arg(start).arg(end); } PIOObject *MyObject = 0L; PIOParseData MyData; /* Specific data description needed to check that sample were written */ PIOParseData MyDataFlag; PIOSTRING ObjName; // sprintf(ObjName, "%s/%s", g->_group->HTMLName, g->objNames[i]); sprintf(ObjName, "%s/%s", g->_group->Name, g->objNames[i]); /* open the group only for reading this object */ PIOGroup *MyGroup=NULL; long n=0; if (strncmp(g->Datatypes[i], "PIOFLAG", 7) == 0) { n = PIORead_1(ObjName, const_cast("Written"), const_cast("PIOFLAG"), const_cast(range.toLatin1().constData()), &MyGroup, &MyObject, &MyData, &MyDataFlag); #ifdef PIOLIBDEBUG kdDebug() << "READ " << n << " flags." << endl; #endif if (n < 0) { // error // FIXME - might have to reset() here abort(); n = 0; return n; } { /* table to store the sample validity */ PIOFLAG *Mask = (PIOFLAG*)_PIOMALLOC(n); /* temporary buffer */ PIOFLAG *flagbuf = (PIOFLAG*)_PIOMALLOC(n); PIORead_2(flagbuf, 0L, Mask, ObjName, const_cast("PIOFLAG"), const_cast(range.toLatin1().constData()), const_cast("Written"), MyGroup, &MyObject, &MyData, &MyDataFlag, PIOLONG(n)); for (i = 0; i < n; i++) { if (Mask[i] == 0) { buf[i] = NOPOINT; } else { // just cast flags to doubles buf[i] = (PIODOUBLE)flagbuf[i]; } } _PIOFREE(flagbuf); _PIOFREE(Mask); } } else { n = PIORead_1(ObjName, const_cast("Written"), const_cast("PIODOUBLE"), const_cast(range.toLatin1().constData()), &MyGroup, &MyObject, &MyData, &MyDataFlag); #ifdef PIOLIBDEBUG kdDebug() << "READ " << n << " doubles." << endl; #endif if (n < 0) { // error // FIXME - might have to reset() here abort(); n = 0; return n; } { /* table to store the sample validity */ PIOFLAG *Mask = (PIOFLAG*)_PIOMALLOC(n); PIORead_2(buf, 0L, Mask, ObjName, const_cast("PIODOUBLE"), const_cast(range.toLatin1().constData()), const_cast("Written"), MyGroup, &MyObject, &MyData, &MyDataFlag, PIOLONG(n)); /* the group is close no need to deletelink */ //PIODeleteLink(buf, g->_group); for (i = 0; i < n; i++) { if (Mask[i] == 0) { buf[i] = NOPOINT; } } _PIOFREE(Mask); } } #ifdef PIOLIBDEBUG kdDebug() << "Read " << n << " samples of data. Range = [" << range << "]" << endl; if (n > 0) { kdDebug() << "this = " << (void*)this << endl; kdDebug() << "buf = " << (void*)buf << endl; } #endif return int(n); } return 0; } ObjectGroup *Object::findGroup(const QString& group) const { if (_groupInfo.contains(group)) { return _groupInfo[group]; } ObjectGroup *grp = new ObjectGroup; if (!grp->open(group)) { delete grp; grp = 0L; } else { _groupInfo.insert(group, grp); } #ifdef PIOLIBDEBUG if (!grp) { kdDebug() << "Error finding group " << group << endl; } #endif return grp; } double Object::timeForSample(int sample) { if (_tt == Undetermined) { _tt = typeOfTime(); } return fetchTimePoint(sample); } int Object::sampleForTimeRelative(double ms, bool *ok) { if (_tt == Undetermined) { _tt = typeOfTime(); } DMC::ObjectGroup *g = findGroup(_group); if (!g) { if (ok) { *ok = false; } return -1; } double left = fetchTimePoint(*g->firstIndex); if (left != left) { if (ok) { *ok = false; } return -1; } return sampleForTime(floor(left + 0.5) + ms / 1000, ok); } int Object::sampleForTime(double ms, bool *ok) { PIOLONG location = -1; bool found = false; if (_tt == Undetermined) { _tt = typeOfTime(); } DMC::ObjectGroup *g = findGroup(_group); if (!g || _tt == Unknown) { if (ok) { *ok = false; } return -1; } PIOLONG FirstIndex = *g->firstIndex; PIOLONG LastIndex = *g->lastIndex; double left = fetchTimePoint(FirstIndex); double right = fetchTimePoint(LastIndex); double sch = ms; if (sch >= left && sch <= right) { if (sch == left) { found = true; location = FirstIndex; } else if (sch == right) { found = true; location = LastIndex; } else { while (FirstIndex < LastIndex) { PIOLONG point = (LastIndex - FirstIndex) / 2 + FirstIndex; if (LastIndex - FirstIndex < 3) { double left = fetchTimePoint(FirstIndex); double right = fetchTimePoint(LastIndex); double mid = fetchTimePoint(point); found = true; double ld = fabs(left - sch); double rd = fabs(right - sch); double md = fabs(mid - sch); if (ld <= rd && ld <= md) { location = FirstIndex; } else if (md <= ld && md <= rd) { location = point; } else if (rd <= ld && rd <= md) { location = LastIndex; } else { location = -1; } break; } double pt = fetchTimePoint(point); if (pt > sch) { LastIndex = point - 1; } else if (pt < sch) { FirstIndex = point + 1; } else if (pt == sch) { found = true; location = point; break; } if (LastIndex == FirstIndex) { found = true; location = FirstIndex; } } } } if (ok) { *ok = found; } return location; } /* * We may want to consider storing with a Qt datatype instead so we can * index these things and get far better performance. */ ObjectGroup::ObjectGroup() { objNames = 0L; objTypes = 0L; firstIndex = 0L; lastIndex = 0L; objectListSize = 0; TOItypes = 0L; Datatypes = 0L; _group = 0L; _valid = false; } ObjectGroup::~ObjectGroup() { close(); } void ObjectGroup::close() { //kdDebug() << "Close group" << endl; if (_valid) { _PIOFREE(objNames); objNames = 0L; _PIOFREE(objTypes); objTypes = 0L; delete[] TOItypes; TOItypes = 0L; delete[] Datatypes; Datatypes = 0L; objectListSize = 0; _valid = false; } delete[] firstIndex; firstIndex = 0L; delete[] lastIndex; lastIndex = 0L; if (_group) { PIOCloseVoidGrp(&_group); _group = 0L; } } bool ObjectGroup::updateObjectList() { if (objNames) { _PIOFREE(objNames); objNames = 0L; _PIOFREE(objTypes); objTypes = 0L; } _valid = false; PIOErr e = PIOGetObjectList(&objNames, &objTypes, _group); if (e > 0) { delete[] firstIndex; delete[] lastIndex; firstIndex = new PIOLONG[e]; lastIndex = new PIOLONG[e]; delete[] TOItypes; TOItypes = new PIOSTRING[e]; delete[] Datatypes; Datatypes = new PIOSTRING[e]; objectListSize = e; _valid = true; #ifdef PIOLIBDEBUG kdDebug() << " -> info acquired." << endl; kdDebug() << " -> objects: " << e << endl; #endif /* there are two solution: - get directly only the group maximal size, - get the object size (it depend how KST manage index after. */ PIOLONG LastIdx, FirstIdx; PIOGetGrpSize(&FirstIdx, &LastIdx, _group); for (int i = 0; i < e; ++i) { firstIndex[i] = FirstIdx; lastIndex[i] = LastIdx; PIOLONG beginIdx, endIdx; PIOSTRING author, date; PIOErr ret = PIOInfoObject(TOItypes[i], Datatypes[i], &beginIdx, &endIdx, author, date, objNames[i], _group); #ifdef PIOLIBDEBUG kdDebug() << " PIOInfoObject(" << TOItypes[i] << "," << Datatypes[i] << "," << beginIdx << "," << endIdx << "," << author << "," << date << "," << objNames[i] << ") returned " << ret << endl; #endif if (ret != 0) { _valid = false; } } } return _valid; } bool ObjectGroup::open(const QString& groupURL) { #ifdef PIOLIBDEBUG kdDebug() << ">>>>>>>>> ObjectGroup open - " << groupURL << endl; #endif close(); // API bug _group = PIOOpenVoidGrp(const_cast(groupURL.toLatin1().constData()), const_cast("r")); if (_group) { #ifdef PIOLIBDEBUG kdDebug() << " -> opened." << endl; #endif if (!updateObjectList()) { PIOCloseVoidGrp(&_group); objectListSize = 0; _group = 0L; } } return _valid; } kst-2.0.3/src/datasources/dmc/dmcobj.h000644 001750 001750 00000003765 11544160210 020154 0ustar00synthsynth000000 000000 /*************************************************************************** dmcobj.h - Part of KST ------------------- begin : Mon Oct 06 2003 copyright : (C) 2003 The University of Toronto email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_DMOBJECT_H #define KST_DMOBJECT_H #include "dmcdata.h" #include namespace DMC { enum TimeType { Undetermined = -1, Unknown = 0, TimeSec = 1, TimesOfSamples = 2 }; class ObjectGroup; class Object : public Source { public: Object(); virtual ~Object(); virtual bool setGroup(const QString& group); virtual QStringList fields() const; virtual void reset(); virtual bool updated() const; virtual int readObject(const QString& object, double *buf, long start, long end); // FIXME: QSize is a bogus class to use here virtual QSize range(const QString& object) const; TimeType typeOfTime(); double fetchTimePoint(PIOLONG); int sampleForTime(double ms, bool *ok); int sampleForTimeRelative(double ms, bool *ok); double timeForSample(int sample); private: // We lazy load the groups, hence mutable mutable QMap _groupInfo; ObjectGroup *findGroup(const QString& group) const; TimeType _tt; }; } #endif kst-2.0.3/src/datasources/planckIDEF/planckIDEF.cpp000644 001750 001750 00000127442 11544160210 022305 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "planckIDEF.h" #include #include #include #include #include #include "ui_planckIDEFconfig.h" #include "kst_i18n.h" static const QString PlanckIDEFTypeString = I18N_NOOP("PlanckIDEF image"); class PlanckIDEFSource::Config { public: Config() { _checkFilename = true; } bool _checkFilename; void read(QSettings *cfg, const QString& fileName = QString::null) { Q_UNUSED(fileName); cfg->beginGroup(PlanckIDEFTypeString); _checkFilename = cfg->readBoolEntry("Check Filename", true); cfg->endGroup(); } void save(QXmlStreamWriter& s) { s.writeStartElement("properties"); s.writeAttribute("checkfilename", QVariant(_checkFilename).toString()); s.writeEndElement(); } void parseProperties(QXmlStreamAttributes &properties) { _checkFilename = QVariant(properties.value("checkfilename").toString()).toBool(); } void load(const QDomElement& e) { _checkFilename = false; QDomNode n = e.firstChild(); while (!n.isNull()) { QDomElement e = n.toElement(); if (!e.isNull()) { if (e.tagName() == "checkfilename") { _checkFilename = true; } } n = n.nextSibling(); } } }; PlanckIDEFSource::PlanckIDEFSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type, None), _config(0L) { _valid = false; if (!type.isEmpty() && type != "PlanckIDEF Source") { return; } _config = new PlanckIDEFSource::Config; _config->read(cfg, filename); if (!e.isNull()) { _config->load(e); } if (init()) { _valid = true; } update(); } PlanckIDEFSource::~PlanckIDEFSource() { delete _config; _config = 0L; } bool PlanckIDEFSource::isValidFilename(const QString& filename, Config *config) { bool ok = false; if (!config || config->_checkFilename) { unsigned gzLength; if (filename.right(3).lower() == ".gz") { gzLength = 3; } else { gzLength = 0; } if (!ok) { // // check for a valid science timeline file... // // Accc-xxxx-T-yyyymmdd.fits // A = one character coding the instrument identifier // ccc = three character coding the obervation frequency // xxxx = four digits identifying the operational day to which the data belong // T = {C,R} one letter identifying if the timeline is converted or reduced // yyyy = four digits coding the start timeline year // mm = two digits coding the start timeline month // dd = two digits coding the start timeline day int checkLength = gzLength + 25; if (filename.length() >= checkLength) { QString tail = filename.right(checkLength); char instrument; char frequency[3]; char timeline; int operationalDay; int year; int month; int day; if (sscanf(tail.latin1(), "%c%c%c%c-%4d-%c-%4d%2d%2d.fits", &instrument, &frequency[0], &frequency[1], &frequency[2], &operationalDay, &timeline, &year, &month, &day) == 9) { if (year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= 31 ) { ok = true; } } } } if (!ok) { // // check for a valid HK timeline file... // // A-namefile-xxxx-yyyymmdd.fits // A = one character coding the instrument identifier // xxxx = four digits identifying the operational day to which the data belong // yyyy = four digits coding the start timeline year // mm = two digits coding the start timeline month // dd = two digits coding the start timeline day int checkLength = gzLength + 19; if (filename.length() >= checkLength) { QString tail = filename.right(checkLength); int operationalDay; int year; int month; int day; if (sscanf(tail.latin1(), "-%4d-%4d%2d%2d.fits", &operationalDay, &year, &month, &day) == 4) { if (year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= 31 ) { ok = true; } } } } if (!ok) { // // check for a previosuly valid definition of the filename... // // *_yyyymmddhhmm_vv.fits // yyyy = four digits coding the start timeline year // mm = two digits coding the start timeline month // dd = two digits coding the start timeline day // hh = two digits coding the start timeline hour // mm = two digits coding the start timeline minute // vv = version number (to be used in case of regeneration of HK timelines, starting from 00) int checkLength = gzLength + 21; if (filename.length() >= checkLength) { QString tail = filename.right(checkLength); int year; int month; int day; int hour; int minute; int version; if (sscanf(tail.latin1(), "_%4d%2d%2d%2d%2d_%2d.fits", &year, &month, &day, &hour, &minute, &version) == 6) { if (year > 0 && month >= 1 && month <= 12 && day >= 1 && day <= 31 ) { ok = true; } } } } } else { ok = true; } return ok; } QString PlanckIDEFSource::baseFilename(const QString& filename) { QString base; int minLength = 14; if (filename.right(3).lower() == ".gz") { minLength += 3; } // -yyyymmdd.fits // yyyy = four digits coding the start timeline year // mm = two digits coding the start timeline month // dd = two digits coding the start timeline day if (filename.length() > minLength) { base = filename.left(filename.length() - minLength); } return base; } bool PlanckIDEFSource::reset() { return true; } bool PlanckIDEFSource::init() { bool bRetVal = true; _numFrames = 0; if (!_filename.isNull() && !_filename.isEmpty()) { QFileInfo fileInfo(_filename); if (fileInfo.isFile()) { bRetVal = initFile(); if (bRetVal) { _isSingleFile = true; } } else if (fileInfo.isDir()) { bRetVal = initFolder(); if (bRetVal) { _isSingleFile = false; } } } return bRetVal; } bool PlanckIDEFSource::initFile() { bool bRetVal = false; if (initFile(_filename)) { field *fld = new field; fld->table = 0; fld->column = 0; _fields.insert(QString("INDEX"), fld); _fieldList.prepend("INDEX"); bRetVal = true; } return bRetVal; } bool PlanckIDEFSource::initFile(const QString& filename) { QString prefixNew; QString str; fitsfile* ffits; bool bRetVal = false; int iResult = 0; int iStatus = 0; iResult = fits_open_file(&ffits, filename.ascii(), READONLY, &iStatus); if (iResult == 0) { int iNumHeaderDataUnits; if (fits_get_num_hdus(ffits, &iNumHeaderDataUnits, &iStatus) == 0) { long lNumRows; int iHDUType; int i; _numFrames = getNumFrames(ffits, iNumHeaderDataUnits); if (_numFrames > 0) { fits_movabs_hdu(ffits, 1, &iHDUType, &iStatus); // add the fields and metadata... for (i=0; i 0) { // create the field entries... fits_get_hdu_type(ffits, &iHDUType, &iStatus); if (iStatus == 0) { if (iHDUType == BINARY_TBL) { int iNumCols; iResult = fits_get_num_cols(ffits, &iNumCols, &iStatus); if (iResult == 0) { iResult = fits_get_num_rows(ffits, &lNumRows, &iStatus); if (iResult == 0) { if (iResult == 0) { addToFieldList(ffits, iNumCols, iStatus); } } } } } } fits_movrel_hdu(ffits, 1, &iHDUType, &iStatus); } } bRetVal = true; } } iStatus = 0; fits_close_file(ffits, &iStatus); } return bRetVal; } bool PlanckIDEFSource::initFolderFile(const QString& filename, const QString& prefix, const QString& baseName) { QString prefixNew; QString str; fitsfile* ffits; bool bRetVal = false; int iResult = 0; int iStatus = 0; iResult = fits_open_file(&ffits, filename.ascii(), READONLY, &iStatus); if (iResult == 0) { int iNumHeaderDataUnits; if (fits_get_num_hdus(ffits, &iNumHeaderDataUnits, &iStatus) == 0) { long lNumRows; int iHDUType; int i; _numFrames = getNumFrames(ffits, iNumHeaderDataUnits); if (_numFrames > 0) { fits_movabs_hdu(ffits, 1, &iHDUType, &iStatus); // add the fields and metadata... char charExtName[] = "EXTNAME"; for (i = 0; i < iNumHeaderDataUnits; i++) { if (iStatus == 0) { addToMetadata(ffits, iStatus); // the first table never contains data... if (i > 0) { // create the field entries... fits_get_hdu_type(ffits, &iHDUType, &iStatus); if (iStatus == 0) { if (iHDUType == BINARY_TBL) { int iNumCols; iResult = fits_get_num_cols(ffits, &iNumCols, &iStatus); if (iResult == 0) { iResult = fits_get_num_rows(ffits, &lNumRows, &iStatus); if (iResult == 0) { if (!prefix.isEmpty()) { char value[FLEN_VALUE]; char comment[FLEN_COMMENT]; prefixNew.truncate(0); iResult = fits_read_keyword(ffits, charExtName, value, comment, &iStatus); if (iResult == 0) { prefixNew = prefix + QDir::separator() + QString(value).remove(QChar('\'')); } iResult = 0; iStatus = 0; } if (iResult == 0) { addToFieldList(ffits, prefixNew, baseName, iNumCols, iStatus); } } } } } } fits_movrel_hdu(ffits, 1, &iHDUType, &iStatus); } } bRetVal = true; } } iStatus = 0; fits_close_file(ffits, &iStatus); } return bRetVal; } bool PlanckIDEFSource::initFolder() { QDir folder(_filename, "*.fits *.fits.gz", QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::Readable); QStringList files; QStringList filesBase; bool bRetVal = true; files = folder.entryList(); if (files.size() > 0) { for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) { if (isValidFilename(*it, 0L)) { fileList* folderFields; folderField folderField; QString baseName = baseFilename(*it); QString pathname = folder.path() + QDir::separator() + *it; int numFrames; folderFields = *_basefiles.find(baseName); if (folderFields == 0L) { fileList* folderFieldsNew = new fileList; if (initFolderFile(pathname, baseName, baseName)) { // first add the INDEX field... QString strIndex; field *fld = new field; fld->basefile = baseName; fld->table = 0; fld->column = 0; strIndex = baseName + QDir::separator() + "INDEX"; _fields.insert(strIndex, fld); _fieldList.append(strIndex); // // now add everything else... // folderField.frameLo = 0; folderField.frames = _numFrames; folderField.file = pathname; folderFieldsNew->append(folderField); _basefiles.replace(baseName, folderFieldsNew); } } else { numFrames = getNumFrames(pathname); if (numFrames > 0) { folderField.frameLo = folderFields->back().frameLo + folderFields->back().frames; folderField.frames = numFrames; folderField.file = pathname; folderFields->append(folderField); } } } } } return bRetVal; } QStringList PlanckIDEFSource::fieldList(const QString& filename) { QStringList fields; if (!filename.isNull() && !filename.isEmpty()) { QFileInfo fileInfo(filename); if (fileInfo.isFile()) { fields = fieldListFromFile(filename); } else if (fileInfo.isDir()) { } } return fields; } QStringList PlanckIDEFSource::fieldListFromFile(const QString& filename) { QStringList fields; QString prefixNew; QString str; fitsfile* ffits; int iResult = 0; int iStatus = 0; fields.append("INDEX"); iResult = fits_open_file(&ffits, filename.ascii(), READONLY, &iStatus); if (iResult == 0) { int iNumHeaderDataUnits; if (fits_get_num_hdus(ffits, &iNumHeaderDataUnits, &iStatus) == 0) { long lNumRows; int iHDUType; int i; int numFrames = getNumFrames(ffits, iNumHeaderDataUnits); if (numFrames > 0) { fits_movabs_hdu(ffits, 1, &iHDUType, &iStatus); // add the fields and metadata... for (i=0; i 0) { // create the field entries... fits_get_hdu_type(ffits, &iHDUType, &iStatus); if (iStatus == 0) { if (iHDUType == BINARY_TBL) { int iNumCols; iResult = fits_get_num_cols(ffits, &iNumCols, &iStatus); if (iResult == 0) { iResult = fits_get_num_rows(ffits, &lNumRows, &iStatus); if (iResult == 0) { if (iResult == 0) { QString str; char charTemplate[FLEN_CARD]; char charName[FLEN_CARD]; long lRepeat; long lWidth; int iHDUNumber; int iTypeCode; int iColNumber; int iResult; int table; int col; table = fits_get_hdu_num(ffits, &iHDUNumber); for (col=0; col 0) { for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) { if (isValidFilename(*it, 0L)) { QString baseName = baseFilename(*it); QString pathname = folder.path() + QDir::separator() + *it; QString prefixNew; QString str; fitsfile* ffits; bool bRetVal = false; int iResult = 0; int iStatus = 0; iResult = fits_open_file(&ffits, filename.ascii(), READONLY, &iStatus); if (iResult == 0) { int iNumHeaderDataUnits; if (fits_get_num_hdus(ffits, &iNumHeaderDataUnits, &iStatus) == 0) { long lNumRows; int iHDUType; int i; int numFrames = getNumFrames(ffits, iNumHeaderDataUnits); if (numFrames > 0) { fits_movabs_hdu(ffits, 1, &iHDUType, &iStatus); // add the fields and metadata... char charExtName[] = "EXTNAME"; for (i = 0; i < iNumHeaderDataUnits; i++) { if (iStatus == 0) { // the first table never contains data... if (i > 0) { // create the field entries... fits_get_hdu_type(ffits, &iHDUType, &iStatus); if (iStatus == 0) { if (iHDUType == BINARY_TBL) { int iNumCols; iResult = fits_get_num_cols(ffits, &iNumCols, &iStatus); if (iResult == 0) { iResult = fits_get_num_rows(ffits, &lNumRows, &iStatus); if (iResult == 0) { if (!baseName.isEmpty()) { char value[FLEN_VALUE]; char comment[FLEN_COMMENT]; prefixNew.truncate(0); iResult = fits_read_keyword(ffits, charExtName, value, comment, &iStatus); if (iResult == 0) { prefixNew = baseName + QDir::separator() + QString(value).remove(QChar('\'')); } iResult = 0; iStatus = 0; } if (iResult == 0) { QString str; char charTemplate[FLEN_CARD]; char charName[FLEN_CARD]; long lRepeat; long lWidth; int iHDUNumber; int iTypeCode; int iColNumber; int iResult; int table; int col; table = fits_get_hdu_num(ffits, &iHDUNumber); for (col=0; col 0) { fits_movabs_hdu(ffits, 1, &iHDUType, &iStatus); // add the fields and metadata... for (i=0; i 0) { for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) { if (isValidFilename(*it, 0L)) { QString baseName = baseFilename(*it); QString pathname = folder.path() + QDir::separator() + *it; QString prefixNew; QString str; fitsfile* ffits; int iResult = 0; int iStatus = 0; iResult = fits_open_file(&ffits, filename.ascii(), READONLY, &iStatus); if (iResult == 0) { int iNumHeaderDataUnits; if (fits_get_num_hdus(ffits, &iNumHeaderDataUnits, &iStatus) == 0) { int iHDUType; int i; int numFrames = getNumFrames(ffits, iNumHeaderDataUnits); if (numFrames > 0) { fits_movabs_hdu(ffits, 1, &iHDUType, &iStatus); // add the fields and metadata... for (i = 0; i < iNumHeaderDataUnits; i++) { if (iStatus == 0) { int keysexist; int morekeys; iResult = fits_get_hdrspace(ffits, &keysexist, &morekeys, &iStatus); if (iResult == 0) { QString strKey; char keyname[FLEN_KEYWORD]; char value[FLEN_VALUE]; char comment[FLEN_COMMENT]; int keynum; int hdu; fits_get_hdu_num(ffits, &hdu); for (keynum=1; keynum<=keysexist; ++keynum) { iResult = fits_read_keyn(ffits, keynum, keyname, value, comment, &iStatus); if (iResult == 0) { strKey.sprintf("%02d_%03d %s", hdu, keynum, keyname); strings.append(strKey); } } } fits_movrel_hdu(ffits, 1, &iHDUType, &iStatus); } } } } iStatus = 0; fits_close_file(ffits, &iStatus); } } } } return strings; } long PlanckIDEFSource::getNumFrames(fitsfile* ffits, int iNumHeaderDataUnits) { long lNumRows = 0; if (iNumHeaderDataUnits > 1) { int iHDUType; int iResult = 0; int iStatus = 0; if (fits_movabs_hdu(ffits, 2, &iHDUType, &iStatus) == 0) { if (fits_get_hdu_type(ffits, &iHDUType, &iStatus) == 0) { if (iHDUType == BINARY_TBL) { iResult = fits_get_num_rows(ffits, &lNumRows, &iStatus); } } } } return lNumRows; } long PlanckIDEFSource::getNumFrames(const QString& filename) { fitsfile* ffits; int numFrames = 0; int iResult = 0; int iStatus = 0; iResult = fits_open_file(&ffits, filename.ascii(), READONLY, &iStatus); if (iResult == 0) { int iNumHeaderDataUnits; if (fits_get_num_hdus(ffits, &iNumHeaderDataUnits, &iStatus) == 0) { numFrames = getNumFrames(ffits, iNumHeaderDataUnits); } iStatus = 0; fits_close_file(ffits, &iStatus); } return numFrames; } void PlanckIDEFSource::addToMetadata(fitsfile *ffits, int &iStatus) { int iResult; int keysexist; int morekeys; iResult = fits_get_hdrspace(ffits, &keysexist, &morekeys, &iStatus); if (iResult == 0) { QString strKey; char keyname[FLEN_KEYWORD]; char value[FLEN_VALUE]; char comment[FLEN_COMMENT]; int keynum; int hdu; fits_get_hdu_num(ffits, &hdu); for (keynum=1; keynum<=keysexist; ++keynum) { iResult = fits_read_keyn(ffits, keynum, keyname, value, comment, &iStatus); if (iResult == 0) { strKey.sprintf("%02d_%03d %s", hdu, keynum, keyname); QString str; if (strlen(comment) > 0) { if (strlen(value) > 0) { str.sprintf("%s / %s", value, comment); } else { str.sprintf("%s", comment); } } else if (strlen(value) > 0) { str.sprintf("%s", value); } _metaData.insert(keyname, str); } } } } void PlanckIDEFSource::addToFieldList(fitsfile *ffits, const int iNumCols, int &iStatus) { QString str; char charTemplate[FLEN_CARD]; char charName[FLEN_CARD]; long lRepeat; long lWidth; int iHDUNumber; int iTypeCode; int iColNumber; int iResult; int table; int col; table = fits_get_hdu_num(ffits, &iHDUNumber); for (col=0; colbasefile = QString(""); fld->table = table; fld->column = iColNumber; _fields.insert(str, fld); _fieldList.append(str); } } } } } void PlanckIDEFSource::addToFieldList(fitsfile *ffits, const QString& prefix, const QString& baseName, const int iNumCols, int &iStatus) { QString str; char charTemplate[FLEN_CARD]; char charName[FLEN_CARD]; long lRepeat; long lWidth; int iHDUNumber; int iTypeCode; int iColNumber; int iResult; int table; int col; table = fits_get_hdu_num(ffits, &iHDUNumber); for (col=0; colbasefile = baseName; fld->table = table; fld->column = iColNumber; _fields.insert(str, fld); _fieldList.append(str); } } } } } Kst::Object::UpdateType PlanckIDEFSource::update() { // updates not supported yet // we should check to see if the FITS file has changed on disk return Kst::Object::NO_CHANGE; } int PlanckIDEFSource::readField(double *v, const QString& fieldName, int s, int n) { int i; int iRead = -1; if (fieldName == "INDEX") { for (i = 0; i < n; ++i) { v[i] = (double)(s + i); } iRead = n; } else { field *fld = 0L; fld = *_fields.find(fieldName); if (fld != 0L) { if (fieldName == fld->basefile + QDir::separator() + QString("INDEX")) { for (i = 0; i < n; ++i) { v[i] = (double)(s + i); } iRead = n; } else { _valid = false; if (!_filename.isNull() && !_filename.isEmpty()) { if (_isSingleFile) { iRead = readFileFrames(_filename, fld, v, s, n); } else { iRead = readFolderFrames(fld, v, s, n); } } } } } return iRead; } int PlanckIDEFSource::readFileFrames(const QString& filename, field *fld, double *v, int s, int n) { double dNan = strtod("nan", NULL); fitsfile* ffits; int iRead = -1; int iStatus = 0; int iAnyNull; int iResult = 0; iResult = fits_open_file(&ffits, filename.ascii(), READONLY, &iStatus); if (iResult == 0) { int iHDUType; if (fits_movabs_hdu(ffits, fld->table, &iHDUType, &iStatus) == 0) { if (iHDUType == BINARY_TBL) { _valid = true; if (n < 0) { iResult = fits_read_col(ffits, TDOUBLE, fld->column, s+1, 1, 1, &dNan, v, &iAnyNull, &iStatus); if (iResult == 0) { iRead = 1; } } else { iResult = fits_read_col(ffits, TDOUBLE, fld->column, s+1, 1, n, &dNan, v, &iAnyNull, &iStatus); if (iResult == 0) { iRead = n; } } iStatus = 0; } } fits_close_file(ffits, &iStatus); } return iRead; } int PlanckIDEFSource::readFolderFrames(field *fld, double *v, int s, int n) { int iRead = -1; if (!fld->basefile.isEmpty()) { fileList* folderFields; double* vNew = v; int sNew = s; int nNew = n; int iReadSub = 0; folderFields = *_basefiles.find(fld->basefile); if (folderFields != 0L) { for (fileList::ConstIterator it = folderFields->begin(); it != folderFields->end(); ++it) { // check if we need to read any frames from the current file... if (n < 0 && (*it).frameLo + (*it).frames > s) { sNew = s - (*it).frameLo; if (sNew < 0) { sNew = 0; } nNew = -1; vNew = v + (*it).frameLo + sNew; iReadSub = readFileFrames((*it).file, fld, vNew, sNew, nNew); if (iReadSub > 0) { if (iRead < 0) { iRead = iReadSub; } else { iRead += iReadSub; } } } else if ((*it).frameLo < s + n && (*it).frameLo + (*it).frames > s) { sNew = s - (*it).frameLo; if (sNew < 0) { sNew = 0; } nNew = n; if (sNew + nNew > (*it).frames) { nNew = (*it).frames - sNew; } vNew = v + (*it).frameLo + sNew; if (nNew > 0) { iReadSub = readFileFrames((*it).file, fld, vNew, sNew, nNew); if (iReadSub > 0) { if (iRead < 0) { iRead = iReadSub; } else { iRead += iReadSub; } } } } } } } return iRead; } bool PlanckIDEFSource::isValidField(const QString& field) const { bool bRetVal = false; if (field == "INDEX") { bRetVal = true; } else { if (*_fields.find(field) != 0L) { bRetVal = true; } } return bRetVal; } int PlanckIDEFSource::samplesPerFrame(const QString &field) { Q_UNUSED(field) return 1; } int PlanckIDEFSource::frameCount(const QString& fieldName) const { int rc = 0; if (_isSingleFile) { rc = _numFrames; } else { field* fld; if (!fieldName.isEmpty()) { fld = *_fields.find(fieldName); if (fld != 0L) { fileList* folderFields; folderFields = *_basefiles.find(fld->basefile); if (folderFields != 0L) { for (fileList::ConstIterator it = folderFields->begin(); it != folderFields->end(); ++it) { rc += (*it).frames; } } } } } return rc; } bool PlanckIDEFSource::isEmpty() const { return _fields.isEmpty(); } QString PlanckIDEFSource::fileType() const { return PlanckIDEFTypeString; } void PlanckIDEFSource::save(QXmlStreamWriter &streamWriter) { Kst::DataSource::save(streamWriter); } void PlanckIDEFSource::parseProperties(QXmlStreamAttributes &properties) { _config->parseProperties(properties); } int PlanckIDEFSource::readScalar(double &S, const QString& scalar) { if (scalar == "FRAMES") { S = 1; return 1; } return 0; } int PlanckIDEFSource::readString(QString &S, const QString& string) { if (string == "FILE") { S = _filename; return 1; } else if (_metaData.contains(string)) { S = _metaData[string]; return 1; } return 0; } bool PlanckIDEFSource::checkValidPlanckIDEFFolder(const QString& filename) { QDir folder(filename, "*.fits *.fits.gz", QDir::Name | QDir::IgnoreCase, QDir::Files | QDir::Readable); QStringList files; QString pathname; bool ok = false; files = folder.entryList(); if (files.size() > 0) { for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) { pathname = folder.path() + QDir::separator() + *it; if (checkValidPlanckIDEFFile(pathname, 0L)) { ok = true; break; } } } return ok; } bool PlanckIDEFSource::checkValidPlanckIDEFFile(const QString& filename, Config *cfg) { bool ok = false; fitsfile* ffits; int iStatus = 0; // determine if it is a Planck IDIS DMC Exchange Format file... if (isValidFilename(filename, cfg)) { if (fits_open_file(&ffits, filename.ascii(), READONLY, &iStatus) == 0) { int iNumHeaderDataUnits; if (fits_get_num_hdus(ffits, &iNumHeaderDataUnits, &iStatus) == 0) { char value[FLEN_VALUE]; char comment[FLEN_COMMENT]; int iHDUType; int iValue; int i; char charSimple[] = "SIMPLE"; char charExtend[] = "EXTEND"; char charNAxis[] = "NAXIS"; // the primary header should never have any data... if (fits_get_hdu_type(ffits, &iHDUType, &iStatus) == 0) { if (iHDUType == IMAGE_HDU) { if (fits_read_key(ffits, TLOGICAL, charSimple, &iValue, comment, &iStatus) == 0) { if (iValue != 0) { if (fits_read_key(ffits, TLOGICAL, charExtend, &iValue, comment, &iStatus) == 0) { if (iValue != 0) { if (fits_read_key(ffits, TINT, charNAxis, &iValue, comment, &iStatus) == 0) { if (iValue == 0) { ok = true; } } } } } } } } // the name of each binary table must conform to aaa-bbbb[-ccc] // where bbbb is a member of {OBTT, TOD., OBTH, HKP.}... if (ok && iStatus == 0) { if (iNumHeaderDataUnits > 1) { long rowsCompare = 0; long rows; int cols; char charExtName[] = "EXTNAME"; for (i=0; i 0) { okCols = true; } } if (okCols) { if (fits_get_num_rows(ffits, &rows, &iStatus) == 0) { if (i == 0) { rowsCompare = rows; } else if (rowsCompare == rows) { ok = true; } else { ok = false; } } else { ok = false; } } } } } else { ok = false; } } } else { ok = false; } } } if (iStatus != 0) { ok = false; } iStatus = 0; fits_close_file(ffits, &iStatus); } } return ok; } class ConfigWidgetPlanckIDEFInternal : public QWidget, public Ui_PlanckIDEFConfig { public: ConfigWidgetPlanckIDEFInternal(QWidget *parent) : QWidget(parent), Ui_PlanckIDEFConfig() { setupUi(this); } }; class ConfigWidgetPlanckIDEF : public Kst::DataSourceConfigWidget { public: ConfigWidgetPlanckIDEF() : Kst::DataSourceConfigWidget() { QGridLayout *layout = new QGridLayout(this); _hc = new ConfigWidgetPlanckIDEFInternal(this); layout->addWidget(_hc, 0, 0); layout->activate(); } ~ConfigWidgetPlanckIDEF() {} void setConfig(QSettings *cfg) { Kst::DataSourceConfigWidget::setConfig(cfg); } void load() { _cfg->beginGroup("PlanckIDEF General"); _hc->_checkFilename->setChecked(_cfg->readBoolEntry("Check Filename", true)); } void save() { _cfg->beginGroup("PlanckIDEF General"); _cfg->writeEntry("Check Filename", (int)_hc->_checkFilename->isChecked()); } ConfigWidgetPlanckIDEFInternal *_hc; }; QString PlanckIDEFPlugin::pluginName() const { return "PlanckIDEF Source Reader"; } QString PlanckIDEFPlugin::pluginDescription() const { return "PlanckIDEF Source Reader"; } Kst::DataSource *PlanckIDEFPlugin::create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const { return new PlanckIDEFSource(store, cfg, filename, type, element); } QStringList PlanckIDEFPlugin::matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { if (typeSuggestion) { *typeSuggestion = PlanckIDEFTypeString; } if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } return QStringList(); } QStringList PlanckIDEFPlugin::scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList scalarList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = PlanckIDEFTypeString; } scalarList.append("FRAMES"); return scalarList; } QStringList PlanckIDEFPlugin::stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList stringList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = PlanckIDEFTypeString; } stringList = PlanckIDEFSource::stringList(filename); return stringList; } QStringList PlanckIDEFPlugin::fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(type) QStringList fieldList; if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = PlanckIDEFTypeString; } if (understands(cfg, filename)) { fieldList = PlanckIDEFSource::fieldList(filename); } return fieldList; } int PlanckIDEFPlugin::understands(QSettings *cfg, const QString& filename) const { PlanckIDEFSource::Config config; QFileInfo fileinfo(filename); int iRetVal = 0; config.read(cfg, filename); if (fileinfo.isFile()) { if (PlanckIDEFSource::checkValidPlanckIDEFFile(filename, &config)) { iRetVal = 99; } } else if (fileinfo.isDir()) { if (PlanckIDEFSource::checkValidPlanckIDEFFolder(filename)) { iRetVal = 99; } } return iRetVal; } bool PlanckIDEFPlugin::supportsTime(QSettings *cfg, const QString& filename) const { //FIXME Q_UNUSED(cfg) Q_UNUSED(filename) return true; } QStringList PlanckIDEFPlugin::provides() const { QStringList rc; rc += "PlanckIDEF Source"; return rc; } Kst::DataSourceConfigWidget *PlanckIDEFPlugin::configWidget(QSettings *cfg, const QString& filename) const { Q_UNUSED(filename) ConfigWidgetPlanckIDEF *config = new ConfigWidgetPlanckIDEF; config->setConfig(cfg); return config; } Q_EXPORT_PLUGIN2(kstdata_qimagesource, PlanckIDEFPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/planckIDEF/planckIDEF.pro000644 001750 001750 00000000441 11544160210 022310 0ustar00synthsynth000000 000000 include($$PWD/../../../kst.pri) include($$PWD/../../../datasourceplugin.pri) TARGET = $$kstlib(kst2data_planckIDEF) INCLUDEPATH += $$OUTPUT_DIR/src/datasources/fitsimage/tmp LIBS += -lcfitsio SOURCES += \ planckIDEF.cpp HEADERS += \ planckIDEF.h FORMS += planckIDEFconfig.ui kst-2.0.3/src/datasources/planckIDEF/planckIDEFconfig.ui000644 001750 001750 00000002064 11544160210 023316 0ustar00synthsynth000000 000000 PlanckIDEFConfig 0 0 497 82 PlanckIDEFConfig Qt::Vertical QSizePolicy::Expanding 320 30 Check filename for individual files kst-2.0.3/src/datasources/planckIDEF/kstdata_planckIDEF.desktop000644 001750 001750 00000002233 11544160210 024675 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=planckIDEF X-Kst-Plugin-Author=The University of Toronto Name=Planck IDIS DMC Exchange Format Reader Name[bg]=Четене на формат за обмен Planck IDIS DMC Name[da]=Planck IDIS DMC-udvekslingsformat-læser Name[de]=Planck IDIS DMC Austauschformatleser Name[el]=Προβολέας τύπου Planck IDIS DMC Exchange Name[es]=Lector del formato de intercambio Planck IDIS DMC Name[et]=Planck IDIS DMC Exchange vormingu lugeja Name[is]=Planck IDIS DMC Exchange Format lesari Name[it]=Lettore del formato di scambio Planck IDIS DMC Name[nds]=Leser för't Planck-IDIS-DMC-Formaat Name[nl]=Leesprogramma voor het Planck IDIS DMC Exchange Format (IDEF) Name[pt]=Leitor do Formato de Intercâmbio Planck IDIS DMC Name[pt_BR]=Leitor do Formato de Intercâmbio Planck IDIS DMC Name[sr]=Читач формата размене Planck IDIS DMC Name[sr@Latn]=Čitač formata razmene Planck IDIS DMC Name[sv]=Planck IDIS DMC-utbytesformatläsare Name[vi]=Bộ đọc Định dạng Trao đổi DMC IDIS Planck Name[xx]=xxPlanck IDIS DMC Exchange Format Readerxx kst-2.0.3/src/datasources/planckIDEF/planckIDEF.h000644 001750 001750 00000013376 11544160210 021752 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLANCKIDEF_H #define PLANCKIDEF_H #include #include #include typedef struct { QString file; double dTimeZero; double dTimeDelta; long frameLo; long frames; } folderField; typedef QList fileList; typedef struct { QString basefile; int table; int column; } field; class PlanckIDEFSource : public Kst::DataSource { Q_OBJECT public: PlanckIDEFSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e); ~PlanckIDEFSource(); bool init(); bool reset(); Kst::Object::UpdateType update(); int readField(double *v, const QString &field, int s, int n); bool isValidField(const QString &field) const; int samplesPerFrame(const QString &field); int frameCount(const QString& field = QString::null) const; bool isEmpty() const; QString fileType() const; void save(QXmlStreamWriter &streamWriter); void parseProperties(QXmlStreamAttributes &properties); class Config; int readScalar(double &S, const QString& scalar); int readString(QString &S, const QString& string); static bool isValidFilename(const QString& filename, Config *config); static QString baseFilename(const QString& filename); static bool checkValidPlanckIDEFFile(const QString& filename, PlanckIDEFSource::Config *config); static bool checkValidPlanckIDEFFolder(const QString& filename); static QStringList fieldList(const QString& filename); static QStringList stringList(const QString& filename); static QStringList fieldListFromFile(const QString& filename); static QStringList stringListFromFile(const QString& filename); static QStringList fieldListFromFolder(const QString& filename); static QStringList stringListFromFolder(const QString& filename); private: bool initFile(const QString& filename); bool initFile(); bool initFolderFile(const QString& filename, const QString& prefix, const QString& baseName); bool initFolder(); void addToMetadata(fitsfile *ffits, int &iStatus); void addToFieldList(fitsfile *ffits, const int iNumCols, int &iStatus); void addToFieldList(fitsfile *ffits, const QString& prefix, const QString& baseName, const int iNumCols, int &iStatus); long getNumFrames(const QString& filename); static long getNumFrames(fitsfile* ffits, int iNumHeaderDataUnits); int readFileFrames(const QString& filename, field *fld, double *v, int s, int n); int readFolderFrames(field *fld, double *v, int s, int n); mutable Config *_config; friend class ConfigWidgetPlanckIDEF; QMap _metaData; QMap _fields; QMap _basefiles; double _dTimeZero; double _dTimeDelta; bool _bHasTime; bool _first; bool _isSingleFile; int _numFrames; int _numCols; }; class PlanckIDEFPlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~PlanckIDEFPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return false; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/sampledatasource/kstdata_sampledatasource.desktop000644 001750 001750 00000007231 11544160210 027770 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=sampledatasource X-Kst-Plugin-Author=The University of Toronto Name=File Reader Template Name[br]=Patrom lenner ar restroù netCDF Name[bs]=Šablon čitača datoteka Name[ca]=Plantilla del lector de fitxers Name[cs]=Šablona souboru čtečky Name[da]=Fillæser-skabelon Name[de]=Vorlage für Dateibetrachter Name[el]=Πρότυπο αναγνώστη αρχείων Name[es]=Plantilla de lectura de archivos Name[et]=Faililugeja mall Name[fr]=Modèle de lecteur de fichiers Name[gl]=Modelo do Leitor de Arquivos Name[hi]=फाइल रीडर टेम्पलेट Name[hr]=Predložak čitača datoteka Name[hu]=Fájlbeolvasó sablon Name[is]=Forsnið skráalesara Name[it]=Modello di lettore file Name[ja]=ファイルリーダー テンプレート Name[ka]=ფაილის წამკითხველის შაბლონი Name[nl]=Sjabloon voor bestandleesprogramma Name[pa]=ਫਾਇਲ ਰੀਡਰ ਨਮੂਨਾ Name[pt]=Modelo do Leitor de Ficheiros Name[pt_BR]=Modelo de Leitor de Arquivos Name[sr]=Шаблон читача фајлова Name[sr@Latn]=Šablon čitača fajlova Name[sv]=Filläsningsmall Name[ta]=வார்ப்புக் கோப்புப் படித்தல் Name[tg]=Қолаби хонандаи файл Name[tr]=Dosya Okuyucu Şablonu Name[vi]=Mẫu bộ đọc tập tin Name[xx]=xxFile Reader Templatexx Name[zh_CN]=文件阅读器模板 Comment=Code template for a file reader plugin. Comment[bs]=Šablon koda za dodatak za čitanje datoteka. Comment[ca]=Plantilla de codi per a un connector lector de fiters. Comment[cs]=Šablona zdrojového kódu zásuvného modulu pro čtení souborů. Comment[da]=Kodeskabelon for et fillæser-plugin. Comment[de]=Code-Vorlage für Dateibetrachter-Module Comment[el]=Πρότυπο κώδικα για ένα πρόσθετο του αναγνώστη αρχείων. Comment[es]=Plantilla de código para hacer un plugin de lectura de archivos. Comment[et]=Koodimall faililugeja pluginale. Comment[fr]=Modèle de code pour un module de lecture de fichiers. Comment[gl]=Modelo de código para un plugin de leitura de ficheiros. Comment[hi]=फाइल रीडर प्लगइन हेतु कोड टेम्पलेट Comment[hr]=Predložak koda za dodatak čitača datoteka. Comment[hu]=Kódsablon fájlbeolvasó bővítőmodulhoz Comment[is]=Forsnið kóda fyrir íforrit skráalesturs. Comment[it]=Modello di codice per un plugin per lettore di file. Comment[ja]=ファイルリーダープラグインのためのコードテンプレート Comment[ka]=კოდის შაბლონი ფაილის წამკითხველის მოდულისათვის. Comment[nl]=Sjabloon voor een plugin voor een bestandleesprogramma. Comment[pt]=Modelo de código para um 'plugin' de leitura de ficheiros. Comment[pt_BR]= Modelo de código para um plug-in de leitor de arquivos. Comment[sr]=Шаблон кôда за прикључке за читање фајлова. Comment[sr@Latn]=Šablon kôda za priključke za čitanje fajlova. Comment[sv]=Kodmall för ett insticksprogram för filläsning Comment[ta]=கோப்பு படித்தல் சொருகிற்குக் குறிமுறை வார்ப்புகள் Comment[tg]=Рамзгузории қолаб барои модули хонандаи файл. Comment[tr]=Kod şablonu için bir dosya okuyucu eklenti. Comment[vi]=Mẫu mã nguồn cho bổ sung đọc tập tin. Comment[xx]=xxCode template for a file reader plugin.xx Comment[zh_CN]=文件阅读器插件的代码模板 kst-2.0.3/src/datasources/sampledatasource/sampledatasource.cpp000644 001750 001750 00000021072 11544160210 025365 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "sampledatasource.h" #include #include #include /********************** SampleDatasourceSource::Config - This class defines the config widget that will be added to the Dialog Config Button for configuring the plugin. This is only needed for special handling required by the plugin. Many plugins will not require configuration. See plugins/sampleplugin for additional details. ***********************/ class SampleDatasourceSource::Config { public: Config() { } void read(QSettings *cfg, const QString& fileName = QString()) { Q_UNUSED(fileName); cfg->beginGroup("Sample Datasource"); cfg->endGroup(); } void save(QXmlStreamWriter& s) { Q_UNUSED(s); } void load(const QDomElement& e) { Q_UNUSED(e); } }; /********************** SampleDatasourceSource - This class defines the main DataSource which derives from DataSource. The key functions that this class must provide is the ability to create the source, provide details about the source be able to process the data. ***********************/ SampleDatasourceSource::SampleDatasourceSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type), _config(0L) { setUpdateType(None); _valid = false; if (!type.isEmpty() && type != "Sample Datasource") { return; } _config = new SampleDatasourceSource::Config; _config->read(cfg, filename); if (!e.isNull()) { _config->load(e); } if (init()) { _valid = true; } registerChange(); } SampleDatasourceSource::~SampleDatasourceSource() { } void SampleDatasourceSource::reset() { init(); Object::reset(); } // If the datasource has any predefined fields they should be populated here. bool SampleDatasourceSource::init() { registerChange(); return true; // false if something went wrong } // Check if the data in the from the source has updated. Typically done by checking the frame count of the datasource for // changes. Kst::Object::UpdateType SampleDatasourceSource::internalDataSourceUpdate() { return Kst::Object::NoChange; } // TODO a DataSource::DataInterface implementation as example QString SampleDatasourceSource::fileType() const { return "Sample Datasource"; } void SampleDatasourceSource::save(QXmlStreamWriter &streamWriter) { Kst::DataSource::save(streamWriter); } // Name used to identify the plugin. Used when loading the plugin. QString SampleDatasourcePlugin::pluginName() const { return "Sample Datasource Reader"; } QString SampleDatasourcePlugin::pluginDescription() const { return "Sample Datasource Reader"; } /********************** SampleDatasourcePlugin - This class defines the plugin interface to the DataSource defined by the plugin. The primary requirements of this class are to provide the necessary connections to create the object which includes providing access to the configuration widget. ***********************/ Kst::DataSource *SampleDatasourcePlugin::create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const { return new SampleDatasourceSource(store, cfg, filename, type, element); } // Provides the matrix list that this dataSource can provide from the provided filename. // This function should use understands to validate the file and then open and calculate the // list of matrices. QStringList SampleDatasourcePlugin::matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { if (typeSuggestion) { *typeSuggestion = "Sample Datasource"; } if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } QStringList matrixList; return matrixList; } // Provides the scalar list that this dataSource can provide from the provided filename. // This function should use understands to validate the file and then open and calculate the // list of scalars if necessary. QStringList SampleDatasourcePlugin::scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList scalarList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = "Sample Datasource"; } scalarList.append("FRAMES"); return scalarList; } // Provides the string list that this dataSource can provide from the provided filename. // This function should use understands to validate the file and then open and calculate the // list of strings if necessary. QStringList SampleDatasourcePlugin::stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList stringList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = "Sample Datasource"; } stringList.append("FILENAME"); return stringList; } // Provides the field list that this dataSource can provide from the provided filename. // This function should use understands to validate the file and then open and calculate the // list of fields if necessary. QStringList SampleDatasourcePlugin::fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(cfg) Q_UNUSED(filename) Q_UNUSED(type) if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = "Sample Datasource"; } QStringList fieldList; return fieldList; } // The main function used to determine if this plugin knows how to process the provided file. // Each datasource plugin should check the file and return a number between 0 and 100 based // on the likelyhood of the file being this type. 100 should only be returned if there is no way // that the file could be any datasource other than this one. int SampleDatasourcePlugin::understands(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) Q_UNUSED(filename) return 0; } bool SampleDatasourcePlugin::supportsTime(QSettings *cfg, const QString& filename) const { //FIXME Q_UNUSED(cfg) Q_UNUSED(filename) return true; } QStringList SampleDatasourcePlugin::provides() const { QStringList rc; rc += "Sample Datasource"; return rc; } // Request for this plugins configuration widget. Kst::DataSourceConfigWidget *SampleDatasourcePlugin::configWidget(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) Q_UNUSED(filename) return 0;; } Q_EXPORT_PLUGIN2(kstdata_sampledatasource, SampleDatasourcePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/sampledatasource/sampledatasource.h000644 001750 001750 00000006742 11544160210 025041 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SAMPLEDATASOURCE_H #define SAMPLEDATASOURCE_H #include #include class SampleDatasourceSource : public Kst::DataSource { Q_OBJECT public: SampleDatasourceSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e); ~SampleDatasourceSource(); bool init(); virtual void reset(); Kst::Object::UpdateType internalDataSourceUpdate(); QString fileType() const; void save(QXmlStreamWriter &streamWriter); class Config; private: mutable Config *_config; }; class SampleDatasourcePlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~SampleDatasourcePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return false; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/sampledatasource/sampledatasource.pro000644 001750 001750 00000000440 11544160210 025377 0ustar00synthsynth000000 000000 TOPOUT_REL=../../.. include($$PWD/$$TOPOUT_REL/kst.pri) include($$PWD/../../../datasourceplugin.pri) TARGET = $$kstlib(kst2data_sampledatasource) INCLUDEPATH += $$OUTPUT_DIR/src/datasources/sampledatasource/tmp SOURCES += \ sampledatasource.cpp HEADERS += \ sampledatasource.h kst-2.0.3/src/datasources/ascii/kstdata_ascii.desktop000644 001750 001750 00000007324 11544160210 023263 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=ascii X-Kst-Plugin-Author=The University of Toronto Name=ASCII File Reader Name[br]=Lenner ar restroù ASCII Name[bs]=Čitač ASCII datoteka Name[ca]=Lector de fitxers ASCII Name[cs]=Čtečka ASCII souborů Name[da]=ASCII Fillæser Name[de]=ASCII-Datei-Leser Name[el]=Αναγνώστης αρχείων ASCII Name[es]=Lector de archivos ASCII Name[et]=ASCII-failide lugeja Name[fr]=Lecteur de fichier ASCII Name[ga]=Léitheoir Comhad ASCII Name[gl]=Leitor de Arquivos ASCII Name[hi]=आस्की फ़ाइल रीडर Name[hr]=ASCII čitač datoteka Name[hu]=ASCII-fájlolvasó Name[is]=ASCII skráalesari Name[it]=Lettore file ASCII Name[ja]=ASCII ファイルリーダー Name[ka]=ASCII ფაილის წამკითხველი Name[nl]=ASCII-bestandleesprogramma Name[pa]=ASCII ਫਾਇਲ ਰੀਡਰ Name[pt]=Leitor de Ficheiros ASCII Name[pt_BR]=Leitor de Arquivos ASCII Name[ru]=Чтение файлов ASCII Name[sr]=Читач ASCII фајлова Name[sr@Latn]=Čitač ASCII fajlova Name[sv]=ASCII-filläsare Name[ta]=ASCII கோப்புப் படித்தல் Name[tg]=Хонандаи файли ASCII Name[tr]=ASCII Dosya Okuyucu Name[vi]=Bộ đọc tập tin ASCII Name[xx]=xxASCII File Readerxx Name[zh_CN]=ASCII 文件阅读器 Comment=Implements support for reading ASCII files into Kst. Comment[bs]=Implementira podršku za čitanje ASCII datoteka u Kst. Comment[ca]=Implementa al Kst el funcionament per llegir fitxers ASCII. Comment[cs]=Podpora čtení ASCII souborů pro Kst. Comment[da]=Implementerer støtte for at læse ASCII-filer i Kst. Comment[de]=Unterstützung für das Einlesen von ASCII-Dateien in Kst Comment[el]=Υλοποιεί την υποστήριξη για ανάγνωση αρχείων ASCII στο Kst. Comment[es]=Implementa soporte para leer archivos ASCII en Kst. Comment[et]=Kst ASCII-failide lugemise toetus. Comment[fr]=Prise en charge de la lecture des fichiers ASCII dans Kst. Comment[gl]=Permite a leitura de ficheiros ASCII en Kst. Comment[hi]=केएसटी में आस्की फाइलों के पढ़ने हेतु समर्थन इम्प्लीमेंट करता है. Comment[hr]=Implementira podršku za čitanje ASCII datoteka u Kst. Comment[hu]=ASCII-fájlok beolvasását végzi a Kst-be Comment[is]=Gefur stuðning við lestur ASCII skráa inn í Kst. Comment[it]=Implementa supporto per leggere file ASCII in Kst. Comment[ja]=ASCII ファイルの Kst への読み込みをサポート Comment[ka]=უზრუნველყოფს ASCII ფაილების Kst-ში წაკითხვას. Comment[nl]=Implementeert de ondersteuning voor het inlezen van ASCII-bestanden in Kst. Comment[pt]=Implementa o suporte para a leitura de ficheiros ASCII no Kst. Comment[pt_BR]=Implementa o suporte a leitura de arquivos ASCII dentro do Kst. Comment[sr]=Имплементира подршку за читање ASCII фајлова у Kst. Comment[sr@Latn]=Implementira podršku za čitanje ASCII fajlova u Kst. Comment[sv]=Implementerar stöd för att läsa in ASCII-filer i Kst. Comment[ta]= ASCII கோப்பிலிருந்து Kstடிற்குச் செய்முறைப்படுத்தித் துணை. Comment[tg]=Иҷро намудани пуштибонӣ барои хондани файлҳои ASCII ба Kst. Comment[tr]=Kst içine ASCII dosyaları okuma desteği verenler Comment[vi]=Thực hiện vào Kst khả năng đọc các tập tin ASCII. Comment[xx]=xxImplements support for reading ASCII files into Kst.xx Comment[zh_CN]=将 ASCII 文件读入 Kst 的应用支持。 kst-2.0.3/src/datasources/ascii/asciisource.h000644 001750 001750 00000017336 11544160210 021553 0ustar00synthsynth000000 000000 /************************* ************************************************** ascii.h - ASCII data source ------------------- begin : Fri Oct 17 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ASCII_H #define ASCII_H #include "datasource.h" #include "dataplugin.h" #include "asciisourceconfig.h" #include #include #include class DataInterfaceAsciiString; class DataInterfaceAsciiVector; struct LexicalCast; class AsciiSource : public Kst::DataSource { Q_OBJECT public: AsciiSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e = QDomElement()); ~AsciiSource(); bool initRowIndex(); UpdateType internalDataSourceUpdate(bool read_completely); virtual UpdateType internalDataSourceUpdate(); int readField(double *v, const QString &field, int s, int n); QString fileType() const; void save(QXmlStreamWriter &s); void parseProperties(QXmlStreamAttributes &properties); bool isEmpty() const; bool supportsTimeConversions() const; int sampleForTime(double ms, bool *ok); int sampleForTime(const QDateTime& time, bool *ok); virtual void reset(); virtual const QString& typeString() const; static const QString asciiTypeKey(); static QStringList fieldListFor(const QString& filename, AsciiSourceConfig *cfg); static QStringList unitListFor(const QString& filename, AsciiSourceConfig* cfg); static QStringList scalarListFor(const QString& filename, AsciiSourceConfig *cfg); static QStringList stringListFor(const QString& filename, AsciiSourceConfig *cfg); Kst::ObjectList autoCurves(Kst::ObjectStore& objectStore); private: // TODO Is this too big or should we use even more: 1MB on the stack? #define KST_PREALLOC 1 * 1024 * 1024 QVarLengthArray _tmpBuffer; QVarLengthArray _rowIndex; friend class ConfigWidgetAscii; mutable AsciiSourceConfig _config; int _numFrames; int _byteLength; bool _haveHeader; bool _fieldListComplete; QStringList _scalarList; QMap _strings; QStringList _fieldList; QMap _fieldUnits; int columnOfField(const QString& field) const; static QStringList splitHeaderLine(const QByteArray& line, AsciiSourceConfig* cfg); DataInterfaceAsciiString* is; DataInterfaceAsciiVector* iv; bool openValidFile(QFile &file); static bool openFile(QFile &file); template int readFromFile(QFile&, T& buffer, int start, int numberOfBytes, int maximalBytes = -1); struct LineEndingType { bool is_crlf; char character; bool isCR() const { return character == '\r'; } bool isLF() const { return character == '\n'; } }; LineEndingType detectLineEndingType(QFile& file) const; // column and comment delimiter functions struct AlwaysTrue { AlwaysTrue() { } inline bool operator()() const { return true; } }; struct AlwaysFalse { AlwaysFalse() { } inline bool operator()() const { return false; } }; struct NoDelimiter { NoDelimiter() { } inline bool operator()(const char) const { return false; } }; struct IsWhiteSpace { IsWhiteSpace() { } inline bool operator()(const char c) const { return c == ' ' || c == '\t'; } }; struct IsDigit { IsDigit() { } inline bool operator()(const char c) const { return (c >= 48) && (c <= 57) ? true : false; } }; struct IsCharacter { IsCharacter(char c) : character(c) { } const char character; inline bool operator()(const char c) const { return character == c; } }; struct IsInString { IsInString(const QString& s) : str(s), chars(s.size()) { QByteArray ascii = str.toAscii(); for (int i = 0; i < 6 && i < chars; i++) { ch[i] = ascii[i]; } } const QString str; const int chars; char ch[6]; inline bool operator()(const char c) const { switch (chars) { case 0: return false; case 1: return ch[0]==c; case 2: return ch[0]==c || ch[1]==c; case 3: return ch[0]==c || ch[1]==c || ch[2]==c; case 4: return ch[0]==c || ch[1]==c || ch[2]==c || ch[3]==c; case 5: return ch[0]==c || ch[1]==c || ch[2]==c || ch[3]==c || ch[4]==c; case 6: return ch[0]==c || ch[1]==c || ch[2]==c || ch[3]==c || ch[4]==c || ch[5]==c; default: return str.contains(c); } } }; struct IsLineBreakLF { IsLineBreakLF(const LineEndingType&) : size(1) { } const int size; inline bool operator()(const char c) const { return c == '\n'; } }; struct IsLineBreakCR { IsLineBreakCR(const LineEndingType& t) : size( t.is_crlf ? 2 : 1 ) { } const int size; inline bool operator()(const char c) const { return c == '\r'; } }; template int readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n, const LineEndingType&, const ColumnDelimiter&); template int readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n, const LineEndingType&, const ColumnDelimiter&, const CommentDelimiter&); template int readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n, const IsLineBreak&, const ColumnDelimiter&, const CommentDelimiter&, const ColumnWidthsAreConst&); template bool findDataRows(const char* buffer, int bufstart, int bufread, const IsLineBreak&, const CommentDelimiter&); void toDouble(const LexicalCast& lexc, const char* buffer, int bufread, int ch, double* v, int row); const IsDigit isDigit; const IsWhiteSpace isWhiteSpace; // TODO remove friend class DataInterfaceAsciiString; friend class DataInterfaceAsciiVector; }; template int AsciiSource::readFromFile(QFile& file, T& buffer, int start, int bytesToRead, int maximalBytes) { if (maximalBytes == -1) { buffer.resize(bytesToRead + 1); } else { bytesToRead = qMin(bytesToRead, maximalBytes); if (buffer.size() <= bytesToRead) { buffer.resize(bytesToRead + 1); } } file.seek(start); // expensive? int bytesRead = file.read(buffer.data(), bytesToRead); if (buffer.size() <= bytesRead) { buffer.resize(bytesRead + 1); } buffer.data()[bytesRead] = '\0'; return bytesRead; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/ascii/asciisource.cpp000644 001750 001750 00000066374 11544160210 022114 0ustar00synthsynth000000 000000 /*************************************************************************** ASCII file data source ------------------- begin : Fri Oct 17 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "asciisource.h" #include "asciisourceconfig.h" #include "curve.h" #include "colorsequence.h" #include "objectstore.h" #include "math_kst.h" #include "kst_inf.h" #include "kst_i18n.h" #include "kst_atof.h" #include "measuretime.h" #include #include #include #include #include // Load faster in debug mode: // disable QASSERT when using [] on data #define KST_DONT_CHECK_INDEX_IN_DEBUG using namespace Kst; // // Vector interface // //------------------------------------------------------------------------------------------- class DataInterfaceAsciiVector : public DataSource::DataInterface { public: DataInterfaceAsciiVector(AsciiSource& a) : ascii(a) {} // read one element int read(const QString&, DataVector::ReadInfo&); // named elements QStringList list() const { return ascii._fieldList; } bool isListComplete() const { return ascii._fieldListComplete; } bool isValid(const QString& field) const { return ascii._fieldList.contains( field ); } // T specific const DataVector::DataInfo dataInfo(const QString&) const; void setDataInfo(const QString&, const DataVector::DataInfo&) {} // meta data QMap metaScalars(const QString&); QMap metaStrings(const QString&); AsciiSource& ascii; }; //------------------------------------------------------------------------------------------- const DataVector::DataInfo DataInterfaceAsciiVector::dataInfo(const QString &field) const { if (!ascii._fieldList.contains(field)) return DataVector::DataInfo(); return DataVector::DataInfo(ascii._numFrames, 1); } //------------------------------------------------------------------------------------------- int DataInterfaceAsciiVector::read(const QString& field, DataVector::ReadInfo& p) { return ascii.readField(p.data, field, p.startingFrame, p.numberOfFrames); } //------------------------------------------------------------------------------------------- // TODO FRAMES only in vector? QMap DataInterfaceAsciiVector::metaScalars(const QString&) { QMap m; m["FRAMES"] = ascii._numFrames;; return m; } QMap DataInterfaceAsciiVector::metaStrings(const QString& field) { QMap m; if (ascii._fieldUnits.contains(field)) { m["units"] = ascii._fieldUnits[field]; } return m; } // // String interface // class DataInterfaceAsciiString : public DataSource::DataInterface { public: DataInterfaceAsciiString(AsciiSource& s) : ascii(s) {} // read one element int read(const QString&, DataString::ReadInfo&); // named elements QStringList list() const { return ascii._strings.keys(); } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataString::DataInfo dataInfo(const QString&) const { return DataString::DataInfo(); } void setDataInfo(const QString&, const DataString::DataInfo&) {} // meta data QMap metaScalars(const QString&) { return QMap(); } QMap metaStrings(const QString&) { return QMap(); } private: AsciiSource& ascii; }; //------------------------------------------------------------------------------------------- int DataInterfaceAsciiString::read(const QString& string, DataString::ReadInfo& p) { if (isValid(string) && p.value) { *p.value = ascii._strings[string]; return 1; } return 0; } //------------------------------------------------------------------------------------------- bool DataInterfaceAsciiString::isValid(const QString& string) const { return ascii._strings.contains( string ); } // // AsciiSource // //------------------------------------------------------------------------------------------- static const QString asciiTypeString = I18N_NOOP("ASCII file"); //------------------------------------------------------------------------------------------- const QString AsciiSource::asciiTypeKey() { return asciiTypeString; } //------------------------------------------------------------------------------------------- AsciiSource::AsciiSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type), _tmpBuffer(), _rowIndex(), is(new DataInterfaceAsciiString(*this)), iv(new DataInterfaceAsciiVector(*this)) { setInterface(is); setInterface(iv); reset(); // TODO only works for local files setUpdateType(File); _source = asciiTypeString; if (!type.isEmpty() && type != asciiTypeString) { return; } _config.readGroup(*cfg, filename); if (!e.isNull()) { _config.load(e); } _valid = true; registerChange(); internalDataSourceUpdate(false); } //------------------------------------------------------------------------------------------- AsciiSource::~AsciiSource() { } //------------------------------------------------------------------------------------------- void AsciiSource::reset() { _tmpBuffer.clear(); _rowIndex.clear(); _valid = false; _byteLength = 0; _numFrames = 0; _haveHeader = false; _fieldListComplete = false; _fieldList.clear(); _scalarList.clear(); _strings.clear(); Object::reset(); _strings = fileMetas(); } //------------------------------------------------------------------------------------------- bool AsciiSource::openFile(QFile &file) { // Don't use 'QIODevice::Text'! // Because CR LF line ending breaks row offset calculation return file.open(QIODevice::ReadOnly); } //------------------------------------------------------------------------------------------- bool AsciiSource::openValidFile(QFile &file) { _valid = openFile(file); return _valid; } //------------------------------------------------------------------------------------------- bool AsciiSource::initRowIndex() { // capacity is at least the pre-allocated memory _rowIndex.resize(_rowIndex.capacity()); _rowIndex[0] = 0; _byteLength = 0; _numFrames = 0; if (_config._dataLine > 0) { QFile file(_filename); if (!openValidFile(file)) { return false; } int header_row = 0; int left = _config._dataLine; int didRead = 0; while (left > 0) { QByteArray line = file.readLine(); if (line.isEmpty() || file.atEnd()) { return false; } didRead += line.size(); --left; if (header_row != _config._fieldsLine && header_row != _config._unitsLine) { _strings[QString("Header %1").arg(header_row, 2, 10, QChar('0'))] = QString::fromAscii(line).trimmed(); } header_row++; } _rowIndex[0] = didRead; } return true; } //------------------------------------------------------------------------------------------- AsciiSource::LineEndingType AsciiSource::detectLineEndingType(QFile& file) const { QByteArray line; int line_size = 0; while (line_size < 2 && !file.atEnd()) { line = file.readLine(); line_size = line.size(); } file.seek(0); if (line_size < 2) { return LineEndingType(); } LineEndingType end; end.is_crlf = line[line_size - 2] == '\r' && line[line_size - 1] == '\n' ; end.character = end.is_crlf ? line[line_size - 2] : line[line_size - 1]; return end; } //------------------------------------------------------------------------------------------- Kst::Object::UpdateType AsciiSource::internalDataSourceUpdate() { return internalDataSourceUpdate(true); } //------------------------------------------------------------------------------------------- #define MAXBUFREADLEN KST_PREALLOC Kst::Object::UpdateType AsciiSource::internalDataSourceUpdate(bool read_completely) { MeasureTime t("AsciiSource::internalDataSourceUpdate"); if (!_haveHeader) { _haveHeader = initRowIndex(); if (!_haveHeader) { return NoChange; } // Re-update the field list since we have one now _fieldList = fieldListFor(_filename, &_config); QStringList units; if (_config._readUnits) { units += unitListFor(_filename, &_config); for (int index = 0; index < _fieldList.size(); ++index) { if (index >= units.size()) { break; // Missing units => the user's fault, but at least don't crash } _fieldUnits[_fieldList[index]] = units[index]; } } _fieldListComplete = _fieldList.count() > 1; // Re-update the scalar list since we have one now _scalarList = scalarListFor(_filename, &_config); } QFile file(_filename); if (!openValidFile(file)) { // Qt: If the device is closed, the size returned will not reflect the actual size of the device. return NoChange; } LineEndingType lineending = detectLineEndingType(file); bool new_data = false; bool force_update = true; if (_byteLength == file.size()) { force_update = false; } _byteLength = file.size(); int bufread = 0; int bufstart = _rowIndex[_numFrames]; do { // Read the tmpbuffer, starting at row_index[_numFrames] QVarLengthArray varBuffer; varBuffer.resize(varBuffer.capacity()); bufstart += bufread; bufread = readFromFile(file, varBuffer, bufstart, _byteLength - bufstart, MAXBUFREADLEN); #ifdef KST_DONT_CHECK_INDEX_IN_DEBUG const char* bufferData = varBuffer.constData(); const char* buffer = bufferData; #else QVarLengthArray& bufferData = varBuffer; const char* buffer = bufferData.data(); #endif if (_config._delimiters.value().size() == 0) { const NoDelimiter comment_del; if (lineending.isLF()) { new_data = findDataRows(buffer, bufstart, bufread, IsLineBreakLF(lineending), comment_del); } else { new_data = findDataRows(buffer, bufstart, bufread, IsLineBreakCR(lineending), comment_del); } } else if (_config._delimiters.value().size() == 1) { const IsCharacter comment_del(_config._delimiters.value()[0].toAscii()); if (lineending.isLF()) { new_data = findDataRows(buffer, bufstart, bufread, IsLineBreakLF(lineending), comment_del); } else { new_data = findDataRows(buffer, bufstart, bufread, IsLineBreakCR(lineending), comment_del); } } else if (_config._delimiters.value().size() > 1) { const IsInString comment_del(_config._delimiters.value()); if (lineending.isLF()) { new_data = findDataRows(buffer, bufstart, bufread, IsLineBreakLF(lineending), comment_del); } else { new_data = findDataRows(buffer, bufstart, bufread, IsLineBreakCR(lineending), comment_del); } } } while (bufread == MAXBUFREADLEN && read_completely); _rowIndex.resize(_numFrames + 1); return (!new_data && !force_update ? NoChange : Updated); } template bool AsciiSource::findDataRows(const char* buffer, int bufstart, int bufread, const IsLineBreak& isLineBreak, const CommentDelimiter& comment_del) { const IsWhiteSpace isWhiteSpace; bool new_data = false; bool is_data = false; bool is_comment = false; const int row_offset = bufstart + isLineBreak.size; for (int i = 0; i < bufread; i++) { if (comment_del(buffer[i])) { is_comment = true; } else if (isLineBreak(buffer[i])) { is_comment = false; if (is_data) { is_data = false; ++_numFrames; if (_numFrames >= _rowIndex.size()) { _rowIndex.resize(_rowIndex.size() + MAXBUFREADLEN); } _rowIndex[_numFrames] = row_offset + i; new_data = true; } } else if (!is_data && !isWhiteSpace(buffer[i]) && !comment_del(buffer[i])) { is_data = is_comment ? false : true; } } return new_data; } //------------------------------------------------------------------------------------------- int AsciiSource::columnOfField(const QString& field) const { if (_fieldList.contains(field)) { return _fieldList.indexOf(field); } if (_fieldListComplete) { return -1; } bool ok = false; int col = field.toInt(&ok); if (ok) { return col; } return -1; } //------------------------------------------------------------------------------------------- int AsciiSource::readField(double *v, const QString& field, int s, int n) { if (n < 0) { n = 1; /* n < 0 means read one sample, not frame - irrelevent here */ } if (field == "INDEX") { for (int i = 0; i < n; i++) { v[i] = double(s + i); } return n; } int col = columnOfField(field); if (col == -1) { return 0; } int bufstart = _rowIndex[s]; int bufread = _rowIndex[s + n] - bufstart; if (bufread <= 0) { return 0; } QFile file(_filename); if (!openValidFile(file)) { return 0; } LineEndingType lineending = detectLineEndingType(file); bufread = readFromFile(file, _tmpBuffer, bufstart, bufread); #ifdef KST_DONT_CHECK_INDEX_IN_DEBUG const char* buffer = _tmpBuffer.constData(); #else const QVarLengthArray& buffer = _tmpBuffer; #endif if (_config._columnType == AsciiSourceConfig::Fixed) { MeasureTime t("AsciiSource::readField: same width for all columns"); LexicalCast lexc; lexc.setDecimalSeparator(_config._useDot); // &buffer[0] points to first row at _rowIndex[0] , so if we wanna find // the column in row i by adding _rowIndex[i] we have to start at: const char* col_start = &buffer[0] - _rowIndex[0] + _config._columnWidth * (col - 1); for (int i = 0; i < n; ++i) { v[i] = lexc.toDouble(_rowIndex[i] + col_start); } return n; } else if (_config._columnType == AsciiSourceConfig::Custom) { if (_config._columnDelimiter.value().size() == 1) { MeasureTime t("AsciiSource::readField: 1 custom column delimiter"); const IsCharacter column_del(_config._columnDelimiter.value()[0].toAscii()); return readColumns(v, buffer, bufstart, bufread, col, s, n, lineending, column_del); } if (_config._columnDelimiter.value().size() > 1) { MeasureTime t(QString("AsciiSource::readField: %1 custom column delimiters").arg(_config._columnDelimiter.value().size())); const IsInString column_del(_config._columnDelimiter.value()); return readColumns(v, buffer, bufstart, bufread, col, s, n, lineending, column_del); } } else if (_config._columnType == AsciiSourceConfig::Whitespace) { MeasureTime t("AsciiSource::readField: whitespace separated columns"); const IsWhiteSpace column_del; return readColumns(v, buffer, bufstart, bufread, col, s, n, lineending, column_del); } return 0; } //------------------------------------------------------------------------------------------- template int AsciiSource::readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n, const LineEndingType& lineending, const ColumnDelimiter& column_del) { if (_config._delimiters.value().size() == 0) { const NoDelimiter comment_del; return readColumns(v, buffer, bufstart, bufread, col, s, n, lineending, column_del, comment_del); } else if (_config._delimiters.value().size() == 1) { const IsCharacter comment_del(_config._delimiters.value()[0].toAscii()); return readColumns(v, buffer, bufstart, bufread, col, s, n, lineending, column_del, comment_del); } else if (_config._delimiters.value().size() > 1) { const IsInString comment_del(_config._delimiters.value()); return readColumns(v, buffer, bufstart, bufread, col, s, n, lineending, column_del, comment_del); } return 0; } template int AsciiSource::readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n, const LineEndingType& lineending, const ColumnDelimiter& column_del, const CommentDelimiter& comment_del) { if (_config._columnWidthIsConst) { const AlwaysTrue column_withs_const; if (lineending.isLF()) { return readColumns(v, buffer, bufstart, bufread, col, s, n, IsLineBreakLF(lineending), column_del, comment_del, column_withs_const); } else { return readColumns(v, buffer, bufstart, bufread, col, s, n, IsLineBreakCR(lineending), column_del, comment_del, column_withs_const); } } else { const AlwaysFalse column_withs_const; if (lineending.isLF()) { return readColumns(v, buffer, bufstart, bufread, col, s, n, IsLineBreakLF(lineending), column_del, comment_del, column_withs_const); } else { return readColumns(v, buffer, bufstart, bufread, col, s, n, IsLineBreakCR(lineending), column_del, comment_del, column_withs_const); } } } template int AsciiSource::readColumns(double* v, const char* buffer, int bufstart, int bufread, int col, int s, int n, const IsLineBreak& isLineBreak, const ColumnDelimiter& column_del, const CommentDelimiter& comment_del, const ColumnWidthsAreConst& are_column_widths_const) { LexicalCast lexc; lexc.setDecimalSeparator(_config._useDot); const QString delimiters = _config._delimiters.value(); int col_start = -1; for (int i = 0; i < n; i++, s++) { bool incol = false; int i_col = 0; if (are_column_widths_const()) { if (col_start != -1) { v[i] = lexc.toDouble(&buffer[0] + _rowIndex[s] + col_start); continue; } } v[i] = Kst::NOPOINT; for (int ch = _rowIndex[s] - bufstart; ch < bufread; ++ch) { if (isLineBreak(buffer[ch])) { break; } else if (column_del(buffer[ch])) { //<- check for column start incol = false; } else if (comment_del(buffer[ch])) { break; } else { if (!incol) { incol = true; ++i_col; if (i_col == col) { toDouble(lexc, buffer, bufread, ch, &v[i], i); if (are_column_widths_const()) { if (col_start == -1) { col_start = ch - _rowIndex[s]; } } break; } } } } } return n; } //------------------------------------------------------------------------------------------- void AsciiSource::toDouble(const LexicalCast& lexc, const char* buffer, int bufread, int ch, double* v, int) { if ( isDigit(buffer[ch]) || buffer[ch] == '-' || buffer[ch] == '.' || buffer[ch] == '+' || isWhiteSpace(buffer[ch])) { *v = lexc.toDouble(&buffer[0] + ch); } else if ( ch + 2 < bufread && tolower(buffer[ch]) == 'i' && tolower(buffer[ch + 1]) == 'n' && tolower(buffer[ch + 2]) == 'f') { *v = INF; } #if 0 // TODO enable by option: "Add unparsable lines as strings" else { if (_rowIndex.size() > row + 1) { QString unparsable = QString::fromAscii(&buffer[_rowIndex[row]], _rowIndex[row + 1] - _rowIndex[row]); _strings[QString("Unparsable %1").arg(row)] = unparsable.trimmed(); } } #endif } //------------------------------------------------------------------------------------------- QString AsciiSource::fileType() const { return asciiTypeString; } //------------------------------------------------------------------------------------------- bool AsciiSource::isEmpty() const { return _numFrames < 1; } //------------------------------------------------------------------------------------------- QStringList AsciiSource::scalarListFor(const QString& filename, AsciiSourceConfig*) { QFile file(filename); if (!openFile(file)) { return QStringList(); } return QStringList() << "FRAMES"; } //------------------------------------------------------------------------------------------- QStringList AsciiSource::stringListFor(const QString& filename, AsciiSourceConfig*) { QFile file(filename); if (!openFile(file)) { return QStringList(); } return QStringList() << "FILE"; } //------------------------------------------------------------------------------------------- QStringList AsciiSource::splitHeaderLine(const QByteArray& line, AsciiSourceConfig* cfg) { QStringList parts; const QRegExp regexColumnDelimiter(QString("[%1]").arg(QRegExp::escape(cfg->_columnDelimiter.value()))); if (cfg->_columnType == AsciiSourceConfig::Custom && !cfg->_columnDelimiter.value().isEmpty()) { parts += QString(line).trimmed().split(regexColumnDelimiter, QString::SkipEmptyParts); } else if (cfg->_columnType == AsciiSourceConfig::Fixed) { int cnt = line.length() / cfg->_columnWidth; for (int i = 0; i < cnt; ++i) { QString sub = line.mid(i * cfg->_columnWidth).left(cfg->_columnWidth); parts += sub.trimmed(); } } else { parts += QString(line).trimmed().split(QRegExp("\\s"), QString::SkipEmptyParts); } return parts; } //------------------------------------------------------------------------------------------- QStringList AsciiSource::fieldListFor(const QString& filename, AsciiSourceConfig* cfg) { QFile file(filename); if (!openFile(file)) { return QStringList(); } QStringList fields; fields += "INDEX"; if (cfg->_readFields) { int fieldsLine = cfg->_fieldsLine; int currentLine = 0; // Explicit line counter, to make the code easier to understand while (currentLine < cfg->_dataLine) { const QByteArray line = file.readLine(); int r = line.size(); if (currentLine == fieldsLine && r >= 0) { fields += AsciiSource::splitHeaderLine(line, cfg); break; } currentLine++; } QStringList trimmed; foreach(const QString& str, fields) { trimmed << str.trimmed(); } return trimmed; } QRegExp regex; if (cfg->_columnType == AsciiSourceConfig::Custom && !cfg->_columnDelimiter.value().isEmpty()) { regex.setPattern(QString("^[%1]*[%2].*").arg(QRegExp::escape(cfg->_columnDelimiter.value())).arg(cfg->_delimiters)); } else { regex.setPattern(QString("^\\s*[%1].*").arg(cfg->_delimiters)); } bool done = false; int skip = cfg->_dataLine; //FIXME This is a hack which should eventually be fixed by specifying // the starting frame of the data when calling KstDataSource::fieldListForSource // and KstDataSource::fieldList. If the skip value is not specified, then // we scan a few lines and take the maximum number of fields that we find. int maxcnt; if (skip > 0) { maxcnt = -1; } else { maxcnt = 0; } int cnt; int nextscan = 0; int curscan = 0; while (!file.atEnd() && !done && (nextscan < 200)) { QByteArray line = file.readLine(); int r = line.size(); if (skip > 0) { //keep skipping until desired line --skip; if (r < 0) { return fields; } continue; } if (maxcnt >= 0) { //original skip value == 0, so scan some lines if (curscan >= nextscan) { if (r > 1 && !regex.exactMatch(line)) { cnt = splitHeaderLine(line, cfg).count(); if (cnt > maxcnt) { maxcnt = cnt; } } else if (r < 0) { return fields; } nextscan += nextscan + 1; } curscan++; continue; } if (r > 1 && !regex.exactMatch(line)) { //at desired line, find count maxcnt = splitHeaderLine(line, cfg).count(); done = true; } else if (r < 0) { return fields; } } for (int i = 1; i <= maxcnt; ++i) { fields += i18n("Column %1").arg(i).trimmed(); } return fields; } QStringList AsciiSource::unitListFor(const QString& filename, AsciiSourceConfig* cfg) { QFile file(filename); if (!openFile(file)) { return QStringList(); } QStringList units; units += ""; // To go with INDEX int unitsLine = cfg->_unitsLine; int currentLine = 0; while (currentLine < cfg->_dataLine) { const QByteArray line = file.readLine(); int r = line.size(); if (currentLine == unitsLine && r >= 0) { units += AsciiSource::splitHeaderLine(line, cfg); break; } currentLine++; } QStringList trimmed; foreach(const QString& str, units) { trimmed << str.trimmed(); } return trimmed; } //------------------------------------------------------------------------------------------- void AsciiSource::save(QXmlStreamWriter &s) { Kst::DataSource::save(s); _config.save(s); } //------------------------------------------------------------------------------------------- void AsciiSource::parseProperties(QXmlStreamAttributes &properties) { _config.parseProperties(properties); reset(); internalDataSourceUpdate(); } //------------------------------------------------------------------------------------------- bool AsciiSource::supportsTimeConversions() const { return false; //fieldList().contains(_config._indexVector) && _config._indexInterpretation != AsciiSourceConfig::Unknown && _config._indexInterpretation != AsciiSourceConfig::INDEX; } //------------------------------------------------------------------------------------------- int AsciiSource::sampleForTime(double ms, bool *ok) { switch (_config._indexInterpretation) { case AsciiSourceConfig::Seconds: // FIXME: make sure "seconds" exists in _indexVector if (ok) { *ok = true; } return 0; case AsciiSourceConfig::CTime: // FIXME: make sure "seconds" exists in _indexVector (different than above?) if (ok) { *ok = true; } return 0; default: return Kst::DataSource::sampleForTime(ms, ok); } } //------------------------------------------------------------------------------------------- const QString& AsciiSource::typeString() const { return asciiTypeString; } //------------------------------------------------------------------------------------------- int AsciiSource::sampleForTime(const QDateTime& time, bool *ok) { switch (_config._indexInterpretation) { case AsciiSourceConfig::Seconds: // FIXME: make sure "time" exists in _indexVector if (ok) { *ok = true; } return time.toTime_t(); case AsciiSourceConfig::CTime: // FIXME: make sure "time" exists in _indexVector (different than above?) if (ok) { *ok = true; } return time.toTime_t(); default: return Kst::DataSource::sampleForTime(time, ok); } } Kst::ObjectList AsciiSource::autoCurves(ObjectStore& objectStore) { // here we could do more sophisticated stuff when generating a list of curves return ObjectList(); } // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/ascii/asciiplugin.h000644 001750 001750 00000007514 11544160210 021546 0ustar00synthsynth000000 000000 /*************************************************************************** asciiplugin.h ------------------- begin : Fri Oct 17 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ASCII_PLUGIN_H #define ASCII_PLUGIN_H #include "asciisource.h" #include "dataplugin.h" #include "ui_asciiconfig.h" class AsciiPlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~AsciiPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return true; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; class ConfigWidgetAsciiInternal : public QWidget, public Ui_AsciiConfig { Q_OBJECT public: ConfigWidgetAsciiInternal(QWidget *parent); AsciiSourceConfig config(); void setConfig(const AsciiSourceConfig&); void setFilename(const QString& filename); private Q_SLOTS: void columnLayoutChanged(int); void showBeginning(); private: const int _index_offset; QString _filename; }; class ConfigWidgetAscii : public Kst::DataSourceConfigWidget { public: ConfigWidgetAscii(QSettings&); ~ConfigWidgetAscii(); void load(); void save(); void setFilename(const QString& filename); ConfigWidgetAsciiInternal *_ac; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/ascii/kst_atof.h000644 001750 001750 00000001052 11544160210 021040 0ustar00synthsynth000000 000000 #ifndef KST_ATOF_H #define KST_ATOF_H #include #include struct LexicalCast { LexicalCast(); ~LexicalCast(); char localSeparator() const; // use second parameter when useDot is false void setDecimalSeparator(bool useDot); #ifdef KST_USE_KST_ATOF double toDouble(const char* p) const; #else inline double toDouble(const char* p) const { return atof(p); } #endif private: char _separator; QByteArray _originalLocal; void resetLocal(); bool isDigit(const char) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/ascii/namedparameter.h000644 001750 001750 00000005062 11544160210 022220 0ustar00synthsynth000000 000000 /*************************************************************************** namedparameter.h - ------------------- begin : Mar 15 2010 copyright : (C) 2010 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_NAMED_PARAMETER #define KST_NAMED_PARAMETER #include #include #include #include template class NamedParameter { public: // this is not nice, it sets not the value but its default NamedParameter(const T& default_value) : _default_value(default_value), _value_set(false) { } void operator>>(QSettings& settings) { const QVariant var = QVariant::fromValue(value()); settings.setValue(Key, var); } void operator<<(QSettings& settings) { const QVariant var = settings.value(Key); if (!var.isNull()) { Q_ASSERT(var.canConvert()); setValue(var.value()); } } void operator>>(QXmlStreamWriter& xml) { xml.writeAttribute(Tag, QVariant(value()).toString()); } void operator<<(QXmlStreamAttributes& att) { setValue(QVariant(att.value(Tag).toString()).value()); } void operator<<(const QDomElement& e) { if (e.hasAttribute(Tag)) { setValue(QVariant(e.attribute(Tag)).value()); } } void setValue(const T& t) { _value = t; _value_set = true; } const T& value() const { if (!_value_set) { //qDebug() << "Using unset value " << Key << " using default: " << _default_value; return _default_value; } return _value; } operator const T&() const { return value(); } NamedParameter& operator=(const T& t) { setValue(t); return *this; } private: T _value; T _default_value; bool _value_set; }; #endif kst-2.0.3/src/datasources/ascii/ascii.pro000644 001750 001750 00000000744 11544160210 020676 0ustar00synthsynth000000 000000 TOPOUT_REL=../../.. include($$PWD/$$TOPOUT_REL/kst.pri) include($$PWD/../../../datasourceplugin.pri) TARGET = $$kstlib(kst2data_ascii) INCLUDEPATH += $$OUTPUT_DIR/src/datasources/ascii/tmp SOURCES += \ asciisource.cpp \ asciisourceconfig.cpp \ asciiplugin.cpp \ kst_atof.cpp HEADERS += \ asciisource.h \ asciisourceconfig.h \ asciiplugin.h \ namedparameter.h \ kst_atof.h \ ../../libkst/kst_inf.h FORMS += asciiconfig.ui win32:DEFINES += KST_USE_KST_ATOF kst-2.0.3/src/datasources/ascii/asciiplugin.cpp000644 001750 001750 00000030665 11544160210 022104 0ustar00synthsynth000000 000000 /*************************************************************************** asciiplugin.cpp ------------------- begin : Mar 16 2010 copyright : (C) 2010 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "asciiplugin.h" #include "asciisourceconfig.h" #include "kst_atof.h" #include #include #include #include // // ConfigWidgetAsciiInternal // ConfigWidgetAsciiInternal::ConfigWidgetAsciiInternal(QWidget *parent) : QWidget(parent), Ui_AsciiConfig(), _index_offset(1) { setupUi(this); QButtonGroup* bgroup = new QButtonGroup(this); bgroup->addButton(_whitespace, AsciiSourceConfig::Whitespace); bgroup->addButton(_custom, AsciiSourceConfig::Custom); bgroup->addButton(_fixed, AsciiSourceConfig::Fixed); connect(bgroup, SIGNAL(buttonClicked(int)), this, SLOT(columnLayoutChanged(int))); _showBeginning->setFont( QFont("Courier")); _showBeginning->setReadOnly(true); _showBeginning->setLineWrapMode(QPlainTextEdit::NoWrap); } void ConfigWidgetAsciiInternal::columnLayoutChanged(int idx) { if (idx == AsciiSourceConfig::Fixed) { widthButtonGroup->setEnabled(false); } else { widthButtonGroup->setEnabled(true); } } void ConfigWidgetAsciiInternal::showBeginning() { QFile file(_filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } int lines_read = 1; QTextStream in(&file); QStringList lines; while (!in.atEnd() && lines_read <= 100) { lines << QString("%1:").arg(lines_read, 3) + in.readLine(); lines_read++; } _showBeginning->setPlainText(lines.join("\n")); _showBeginning->moveCursor(QTextCursor::Start); _labelBeginning->setText(QString("First 100 lines in file '%1'").arg(QFileInfo(_filename).fileName())); } AsciiSourceConfig ConfigWidgetAsciiInternal::config() { AsciiSourceConfig config; config._fileNamePattern = _fileNamePattern->text(); config._indexInterpretation = (AsciiSourceConfig::Interpretation) (1 + _indexType->currentIndex()); config._delimiters = _delimiters->text(); if (_whitespace->isChecked()) { config._columnType = AsciiSourceConfig::Whitespace; } else if (_custom->isChecked()) { config._columnType = AsciiSourceConfig::Custom; } else if (_fixed->isChecked()) { config._columnType = AsciiSourceConfig::Fixed; } config._columnDelimiter = _columnDelimiter->text(); config._columnWidth = _columnWidth->value(); config._columnWidthIsConst = _columnWidthIsConst->isChecked(); config._readFields = _readFields->isChecked(); config._readUnits = _readUnits->isChecked(); config._useDot = _useDot->isChecked(); config._dataLine = _startLine->value() - _index_offset; config._fieldsLine = _fieldsLine->value() - _index_offset; config._unitsLine = _unitsLine->value() - _index_offset; return config; } void ConfigWidgetAsciiInternal::setFilename(const QString& filename) { _filename = filename; showBeginning(); } void ConfigWidgetAsciiInternal::setConfig(const AsciiSourceConfig& config) { _delimiters->setText(config._delimiters); _fileNamePattern->setText(config._fileNamePattern); _columnDelimiter->setText(config._columnDelimiter); _columnWidth->setValue(config._columnWidth); _columnWidthIsConst->setChecked(config._columnWidthIsConst); _readFields->setChecked(config._readFields); _readUnits->setChecked(config._readUnits); _useDot->setChecked(config._useDot); _useComma->setChecked(!config._useDot); _startLine->setValue(config._dataLine + _index_offset); _fieldsLine->setValue(config._fieldsLine + _index_offset); _unitsLine->setValue(config._unitsLine + _index_offset); AsciiSourceConfig::ColumnType ct = (AsciiSourceConfig::ColumnType) config._columnType.value(); if (ct == AsciiSourceConfig::Fixed) { _fixed->setChecked(true); } else if (ct == AsciiSourceConfig::Custom) { _custom->setChecked(true); } else { _whitespace->setChecked(true); } columnLayoutChanged(ct); } ConfigWidgetAscii::ConfigWidgetAscii(QSettings& s) : Kst::DataSourceConfigWidget(s) { QGridLayout *layout = new QGridLayout(this); _ac = new ConfigWidgetAsciiInternal(this); layout->addWidget(_ac, 0, 0); layout->activate(); } ConfigWidgetAscii::~ConfigWidgetAscii() { } void ConfigWidgetAscii::setFilename(const QString& filename) { _ac->setFilename(filename); } void ConfigWidgetAscii::load() { AsciiSourceConfig config; if (hasInstance()) config.readGroup(settings(), instance()->fileName()); else config.readGroup(settings()); _ac->setConfig(config); // Now handle index _ac->_indexVector->clear(); if (hasInstance()) { Kst::SharedPtr src = Kst::kst_cast(instance()); _ac->_indexVector->addItems(src->vector().list()); _ac->_indexVector->setCurrentIndex(src->_config._indexInterpretation - 1); if (src->vector().list().contains(src->_config._indexVector)) { _ac->_indexVector->setEditText(src->_config._indexVector); } } else { _ac->_indexVector->addItem("INDEX"); int x = config._indexInterpretation; if (x > 0 && x <= _ac->_indexType->count()) { _ac->_indexType->setCurrentIndex(x - 1); } else { _ac->_indexType->setCurrentIndex(0); } } _ac->_indexVector->setEnabled(hasInstance()); } void ConfigWidgetAscii::save() { if (hasInstance()) { Kst::SharedPtr src = Kst::kst_cast(instance()); if (_ac->_applyDefault->isChecked()) { _ac->config().saveGroup(settings()); } _ac->config().saveGroup(settings(), src->fileName()); // Update the instance from our new settings if (src->reusable()) { src->_config.readGroup(settings(), src->fileName()); src->reset(); src->internalDataSourceUpdate(); } } } // // AsciiPlugin // QString AsciiPlugin::pluginName() const { return "ASCII File Reader"; } QString AsciiPlugin::pluginDescription() const { return "ASCII File Reader"; } Kst::DataSource *AsciiPlugin::create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const { return new AsciiSource(store, cfg, filename, type, element); } QStringList AsciiPlugin::matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { if (typeSuggestion) { *typeSuggestion = AsciiSource::asciiTypeKey(); } if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } return QStringList(); } QStringList AsciiPlugin::fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = AsciiSource::asciiTypeKey(); } AsciiSourceConfig config; config.readGroup(*cfg, filename); QStringList rc = AsciiSource::fieldListFor(filename, &config); if (complete) { *complete = rc.count() > 1; } return rc; } QStringList AsciiPlugin::scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = AsciiSource::asciiTypeKey(); } AsciiSourceConfig config; config.readGroup(*cfg, filename); QStringList rc = AsciiSource::scalarListFor(filename, &config); if (complete) { *complete = rc.count() > 1; } return rc; } QStringList AsciiPlugin::stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = AsciiSource::asciiTypeKey(); } AsciiSourceConfig config; config.readGroup(*cfg, filename); QStringList rc = AsciiSource::stringListFor(filename, &config); if (complete) { *complete = rc.count() > 1; } return rc; } int AsciiPlugin::understands(QSettings *cfg, const QString& filename) const { AsciiSourceConfig config; config.readGroup(*cfg, filename); if (!QFile::exists(filename) || QFileInfo(filename).isDir()) { return 0; } if (!config._fileNamePattern.value().isEmpty()) { QRegExp filenamePattern(config._fileNamePattern); filenamePattern.setPatternSyntax(QRegExp::Wildcard); if (filenamePattern.exactMatch(filename)) { return 100; } } QFile f(filename); if (f.open(QIODevice::ReadOnly)) { QRegExp commentRE; QRegExp dataRE; if (config._columnType == AsciiSourceConfig::Custom && !config._columnDelimiter.value().isEmpty()) { commentRE.setPattern(QString("^[%1]*[%2].*").arg(QRegExp::escape(config._columnDelimiter)).arg(config._delimiters)); dataRE.setPattern(QString("^[%1]*(([Nn][Aa][Nn]|(\\-\\+)?[Ii][Nn][Ff]|[0-9\\+\\-\\.eE]+)[\\s]*)+").arg(QRegExp::escape(config._columnDelimiter))); } else { commentRE.setPattern(QString("^\\s*[%1].*").arg(config._delimiters)); dataRE.setPattern(QString("^[\\s]*(([Nn][Aa][Nn]|(\\-\\+)?[Ii][Nn][Ff]|[0-9\\+\\-\\.eE]+)[\\s]*)+")); } int skip = config._dataLine; bool done = false; while (!done) { const QByteArray line = f.readLine(); const qint64 rc = line.size(); if (skip > 0) { --skip; if (rc <= 0) { done = true; } continue; } if (rc <= 0) { done = true; } else if (rc == 1) { // empty line; do nothing } else if (commentRE.exactMatch(line)) { // comment; do nothing } else if (dataRE.exactMatch(line)) { // a number - this may be an ascii file - assume that it is // This line checks for an indirect file and gives that a chance too. // Indirect files look like ascii files. return 75; //return QFile::exists(line.trimmed()) ? 49 : 75; } else { return 20; } } } else { return 0; } return 1; // still might be ascii - ex: header with no data yet. } bool AsciiPlugin::supportsTime(QSettings *cfg, const QString& filename) const { //FIXME Q_UNUSED(cfg) Q_UNUSED(filename) return true; } QStringList AsciiPlugin::provides() const { return QStringList() <load(); config->setFilename(filename); return config; } Q_EXPORT_PLUGIN2(kstdata_ascii, AsciiPlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/ascii/asciiconfig.ui000644 001750 001750 00000034630 11544160210 021702 0ustar00synthsynth000000 000000 AsciiConfig 0 0 357 545 3 3 First 100 lines 9 Comment indicators: false _delimiters You can use more than one symbol here, like "#!C" for instance, but it will slow down reading ASCII files Always accept files matching: false Interpret: false _indexVector 1 0 As: false _indexType 1 0 INDEX C Time Seconds Header 3 3 3 3 0 Data starts at line: false _startLine 2 0 1 9999999 1 Read field names from line: false 2 0 1 9999999 1 false Read units from line: false 2 0 1 9999999 1 Line numbers start at 1 Data Column Layout 3 3 3 Space/tab delimited true Custom delimiter false All columns have the same width false characters 1 16 Data Column Width Options 3 3 3 Do not make assumptions on column width true Each column has its own constant width Decimal Separator 3 3 3 Dot false Comma true Qt::Horizontal 204 20 Apply these settings as default Qt::Vertical 20 24 _delimiters _indexVector _indexType _fixed toggled(bool) _columnWidth setEnabled(bool) 34 342 243 341 _readFields toggled(bool) _fieldsLine setEnabled(bool) 33 171 233 171 _readUnits toggled(bool) _unitsLine setEnabled(bool) 95 191 234 189 _readFields toggled(bool) _readUnits setEnabled(bool) 62 162 65 186 _readFields toggled(bool) _unitsLine setEnabled(bool) 100 162 331 192 _custom toggled(bool) _columnDelimiter setEnabled(bool) 34 312 158 311 kst-2.0.3/src/datasources/ascii/asciisourceconfig.cpp000644 001750 001750 00000014573 11544160210 023274 0ustar00synthsynth000000 000000 /*************************************************************************** asciispource_p.cpp ------------------- begin : Mar 16 2010 copyright : (C) 2010 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "asciisourceconfig.h" #include "asciisource.h" // // AsciiSourceConfig // #define DEFAULT_COMMENT_DELIMITERS "#" #define DEFAULT_COLUMN_WIDTH 16 const char AsciiSourceConfig::Key_fileNamePattern[] = "Filename Pattern"; const char AsciiSourceConfig::Tag_fileNamePattern[] = "filenamepattern"; const char AsciiSourceConfig::Key_delimiters[] = "Comment Delimiters"; const char AsciiSourceConfig::Tag_delimiters[] = "delimiters"; const char AsciiSourceConfig::Key_indexVector[] ="Index"; const char AsciiSourceConfig::Tag_indexVector[] ="vector"; const char AsciiSourceConfig::Key_indexInterpretation[] = "Default INDEX Interpretation"; const char AsciiSourceConfig::Tag_indexInterpretation[] = "interpretation"; const char AsciiSourceConfig::Key_columnType[] = "Column Type"; const char AsciiSourceConfig::Tag_columnType[] = "columntype"; const char AsciiSourceConfig::Key_columnDelimiter[] = "Column Delimiter"; const char AsciiSourceConfig::Tag_columnDelimiter[] = "columndelimiter"; const char AsciiSourceConfig::Key_columnWidth[] = "Column Width"; const char AsciiSourceConfig::Tag_columnWidth[] = "columnwidth"; const char AsciiSourceConfig::Key_columnWidthIsConst[] = "Column Width is const"; const char AsciiSourceConfig::Tag_columnWidthIsConst[] = "columnwidthisconst"; const char AsciiSourceConfig::Key_dataLine[] = "Data Start"; const char AsciiSourceConfig::Tag_dataLine[] = "headerstart"; const char AsciiSourceConfig::Key_readFields[] = "Read Fields"; const char AsciiSourceConfig::Tag_readFields[] = "readfields"; const char AsciiSourceConfig::Key_readUnits[] = "Read Units"; const char AsciiSourceConfig::Tag_readUnits[] = "readunits"; const char AsciiSourceConfig::Key_useDot[] = "Use Dot"; const char AsciiSourceConfig::Tag_useDot[] = "usedot"; const char AsciiSourceConfig::Key_fieldsLine[] = "Fields Line"; const char AsciiSourceConfig::Tag_fieldsLine[] = "fields"; const char AsciiSourceConfig::Key_unitsLine[] = "Units Line"; const char AsciiSourceConfig::Tag_unitsLine[] = "units"; AsciiSourceConfig::AsciiSourceConfig() : _delimiters(DEFAULT_COMMENT_DELIMITERS), _indexVector("INDEX"), _fileNamePattern(""), _indexInterpretation(Unknown), _columnType(Whitespace), _columnDelimiter(","), _columnWidth(DEFAULT_COLUMN_WIDTH), _columnWidthIsConst(false), _dataLine(0), _readFields(false), _readUnits(false), _fieldsLine(0), _unitsLine(0), _useDot(true) { } void AsciiSourceConfig::save(QSettings& cfg) { _fileNamePattern >> cfg; _indexVector >> cfg; _delimiters >> cfg; _indexInterpretation >> cfg; _columnType >> cfg; _columnDelimiter >> cfg; _columnWidth >> cfg; _dataLine >> cfg; _readFields >> cfg; _useDot >> cfg; _fieldsLine >> cfg; _columnWidthIsConst >> cfg; _readUnits >> cfg; _unitsLine >> cfg; } void AsciiSourceConfig::saveGroup(QSettings& cfg, const QString& fileName) { cfg.beginGroup(AsciiSource::asciiTypeKey()); if (fileName.isEmpty()) { save(cfg); } else { cfg.beginGroup(fileName); save(cfg); cfg.endGroup(); } cfg.endGroup(); } void AsciiSourceConfig::read(QSettings& cfg) { _fileNamePattern << cfg; _indexVector << cfg; _delimiters << cfg; _indexInterpretation << cfg; _columnType << cfg; _columnDelimiter << cfg; _columnWidth << cfg; _dataLine << cfg; _readFields << cfg; _useDot << cfg; _fieldsLine << cfg; _columnWidthIsConst << cfg; _readUnits << cfg; _unitsLine << cfg; } void AsciiSourceConfig::readGroup(QSettings& cfg, const QString& fileName) { cfg.beginGroup(AsciiSource::asciiTypeKey()); read(cfg); if (!fileName.isEmpty()) { cfg.beginGroup(fileName); read(cfg); cfg.endGroup(); } _delimiters = QRegExp::escape(_delimiters).toLatin1(); cfg.endGroup(); } void AsciiSourceConfig::save(QXmlStreamWriter& s) { s.writeStartElement("properties"); if (_indexInterpretation != AsciiSourceConfig::Unknown) { _indexVector >> s; _indexInterpretation >> s; } _delimiters >> s; _columnType >> s; if (_columnType == Fixed) { _columnWidth >> s; } else if (_columnType == Custom) { _columnDelimiter >> s; } _dataLine >> s; _fieldsLine >> s; _readFields >> s; _useDot >> s; _columnWidthIsConst >> s; _readUnits >> s; _unitsLine >> s; s.writeEndElement(); } void AsciiSourceConfig::parseProperties(QXmlStreamAttributes& attributes) { _fileNamePattern << attributes; _indexVector << attributes; _delimiters << attributes; _indexInterpretation << attributes; _columnType << attributes; _columnDelimiter << attributes; _columnWidth << attributes; _dataLine << attributes; _readFields << attributes; _useDot << attributes; _fieldsLine << attributes; _columnWidthIsConst << attributes; _readUnits << attributes; _unitsLine << attributes; } void AsciiSourceConfig::load(const QDomElement& e) { QDomNode n = e.firstChild(); while (!n.isNull()) { QDomElement elem = n.toElement(); if (!elem.isNull()) { if (elem.tagName() == "properties") { _fileNamePattern << elem; _indexVector << elem; _delimiters << elem; _indexInterpretation << elem; _columnType << elem; _columnDelimiter << elem; _columnWidth << elem; _dataLine << elem; _readFields << elem; _useDot << elem; _fieldsLine << elem; _columnWidthIsConst << elem; _readUnits << elem; _unitsLine << elem; } } n = n.nextSibling(); } } kst-2.0.3/src/datasources/ascii/asciisourceconfig.h000644 001750 001750 00000007750 11544160210 022740 0ustar00synthsynth000000 000000 /*************************************************************************** asciisource_p.h ------------------- begin : Mar 16 2010 copyright : (C) 2010 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_ASCII_SOURCE_CONFIG_H #define KST_ASCII_SOURCE_CONFIG_H #include "namedparameter.h" #include class AsciiSourceConfig { // TODO translate keys? static const char Key_fileNamePattern[]; static const char Tag_fileNamePattern[]; static const char Key_delimiters[]; static const char Tag_delimiters[]; static const char Key_indexVector[]; static const char Tag_indexVector[]; static const char Key_indexInterpretation[]; static const char Tag_indexInterpretation[]; static const char Key_columnType[]; static const char Tag_columnType[]; static const char Key_columnDelimiter[]; static const char Tag_columnDelimiter[]; static const char Key_columnWidth[]; static const char Tag_columnWidth[]; static const char Key_columnWidthIsConst[]; static const char Tag_columnWidthIsConst[]; static const char Key_dataLine[]; static const char Tag_dataLine[]; static const char Key_readFields[]; static const char Tag_readFields[]; static const char Key_readUnits[]; static const char Tag_readUnits[]; static const char Key_useDot[]; static const char Tag_useDot[]; static const char Key_fieldsLine[]; static const char Tag_fieldsLine[]; static const char Key_unitsLine[]; static const char Tag_unitsLine[]; public: AsciiSourceConfig(); void saveGroup(QSettings& cfg, const QString& fileName = QString()); void readGroup(QSettings& cfg, const QString& fileName = QString()); void save(QXmlStreamWriter& s); void parseProperties(QXmlStreamAttributes &properties); void load(const QDomElement& e); enum Interpretation { Unknown = 0, INDEX, CTime, Seconds, IntEnd = 0xffff }; enum ColumnType { Whitespace = 0, Fixed, Custom, ColEnd = 0xffff }; NamedParameter _delimiters; NamedParameter _indexVector; NamedParameter _fileNamePattern; NamedParameter _indexInterpretation; NamedParameter _columnType; NamedParameter _columnDelimiter; NamedParameter _columnWidth; NamedParameter _columnWidthIsConst; NamedParameter _dataLine; NamedParameter _readFields; NamedParameter _readUnits; NamedParameter _fieldsLine; NamedParameter _unitsLine; NamedParameter _useDot; private: void save(QSettings& cfg); void read(QSettings& cfg); }; Q_DECLARE_METATYPE(AsciiSourceConfig::Interpretation) Q_DECLARE_METATYPE(AsciiSourceConfig::ColumnType) #endif kst-2.0.3/src/datasources/ascii/kst_atof.cpp000644 001750 001750 00000004355 11544160210 021404 0ustar00synthsynth000000 000000 // patched BSD V7 code // http://www.bsdlover.cn/study/UnixTree/V7/usr/src/libc/gen/atof.c.html #include "kst_atof.h" #include #include #include #define LOGHUGE 39 inline bool LexicalCast::isDigit(const char c) const { return (c >= 48) && (c <= 57) ? true : false; } #ifdef KST_USE_KST_ATOF double LexicalCast::toDouble(const char* signedp) const { unsigned char* p = (unsigned char*)signedp; unsigned char c; double fl, flexp, exp5; double big = 72057594037927936.; /*2^56*/ int nd; int eexp, exp, neg, negexp, bexp; neg = 1; while((c = *p++) == ' ') ; if (c == '-') neg = -1; else if (c=='+') ; else --p; exp = 0; fl = 0; nd = 0; while ((c = *p++), isDigit(c)) { if (fl>= 1; if (exp==0) break; exp5 *= exp5; } if (negexp<0) fl /= flexp; else fl *= flexp; fl = ldexp(fl, negexp*bexp); if (neg<0) fl = -fl; return(fl); } #endif LexicalCast::LexicalCast() { } LexicalCast::~LexicalCast() { resetLocal(); }; void LexicalCast::resetLocal() { if (!_originalLocal.isEmpty()) { setlocale(LC_NUMERIC, _originalLocal.constData()); _originalLocal.clear(); } } void LexicalCast::setDecimalSeparator(bool useDot) { useDot ? _separator = '.' : _separator = ','; if (_separator != localSeparator()) { _originalLocal = QByteArray((const char*) setlocale(LC_NUMERIC, 0)); if (useDot) { setlocale(LC_NUMERIC, "C"); } else { setlocale(LC_NUMERIC, "de"); } } else { resetLocal(); } } char LexicalCast::localSeparator() const { return *setlocale(LC_NUMERIC, 0); } // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/ascii/notes.txt000644 001750 001750 00000001070 11544160210 020746 0ustar00synthsynth000000 000000 Notes for the ASCII data source ------------------------------- Time ---- Two time modes are supported: 1) C Time Equivalent to time_t, including epoch. This is an absolute measure. 2) Seconds This is a relative measure. Time is equivalent to the value of the index vector in seconds Broken ------ 1) We have to update() from the constructor because KstRVector doesn't update the data source. This has to be reworked in Kst-core so that the update thread no longer does data sources. Should give a performance boost. 2) Time code is unfinished. kst-2.0.3/src/datasources/netcdf/kstdata_netcdf.desktop000644 001750 001750 00000006660 11544160210 023613 0ustar00synthsynth000000 000000 s[Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=netcdf X-Kst-Plugin-Author=Nicolas Brisset Name=netCDF File Reader Name[bg]=Четене на файлове netCDF Name[br]=Lenner ar restroù netCDF Name[ca]=Lector de fitxers netCDF Name[cs]=Čtečka netCDF souborů Name[da]=netCDF-fillæser Name[de]=netCDF-Dateileser Name[el]=Αναγνώστης αρχείων netCDF Name[es]=Lector de archivos netCDF Name[et]=netCDF-faili lugeja Name[ga]=Léitheoir Comhad netCDF Name[gl]=Leitor de Arquivos netCDF Name[hr]=netCDF čitač datoteka Name[is]=netCDF skráalesari Name[it]=Lettore file netCDF Name[ja]=netCDF ファイルリーダー Name[ka]=netCDF ფაილის წამკითხველი Name[nds]=netCDF-Dateiinleser Name[nl]=netCDF-bestandenlezer Name[pa]=netCDF ਫਾਇਲ ਰੀਡਰ Name[pt]=Leitor de Ficheiros netCDF Name[pt_BR]=Leitor de Arquivos netCDF Name[sr]=Читач netCDF фајлова Name[sr@Latn]=Čitač netCDF fajlova Name[sv]=netCDF-filläsare Name[ta]=netCDF கோப்பு படிப்பான் Name[tg]=Хонандаи файли netCDF Name[tr]=netCDF Dosyası Okuyucusu Name[vi]=Bộ đọc tập tin netCDF Name[xx]=xxnetCDF File Readerxx Name[zh_CN]=netCDF 文件阅读器 Comment=Implements support for reading netCDF files into Kst. Comment[bg]=Поддръжка за четене на netCDF-файлове в Kst. Comment[ca]=Implementa el funcionament per llegir fitxers netCDF en el Kst. Comment[cs]=Podpora čtení netCDF souborů pro Kst. Comment[da]=Implementerer støtte for at læse netCDF-filer i Kst. Comment[de]=Unterstützung für das Einlesen von netCDF-Dateien in Kst. Comment[el]=Υλοποιεί την υποστήριξη για ανάγνωση αρχείων netCDF στο Kst. Comment[es]=Implementa soporte para leer archivos netCDF en Kst. Comment[et]=Kst netCDF-failide lugemise toetus. Comment[gl]=Permite a leitura de ficheiros netCDF en Kst. Comment[hr]=Implementira podršku za čitanje netCDF datoteka u Kst. Comment[is]=Gefur stuðning við lestur netCDF skráa inn í Kst. Comment[it]=Implementa supporto per leggere file netCDF in Kst. Comment[ja]=netCDF ファイルの Kst への読み込みをサポート Comment[ka]=უზრუნველყოფს netCDF ფაილების Kst-ში წაკითხვას. Comment[nds]=Stellt Ünnerstütten för't Inlesen vun netCDF-Dateien na Kst praat. Comment[nl]=Implementeert de ondersteuning voor het inlezen van netCDF-bestanden in Kst. Comment[pt]=Implementa o suporte para a leitura de ficheiros do netCDF no Kst. Comment[pt_BR]=Implementa o suporte para a leitura de arquivos netCDF dentro do Kst. Comment[sr]=Имплементира подршку за читање netCDF фајлова у Kst. Comment[sr@Latn]=Implementira podršku za čitanje netCDF fajlova u Kst. Comment[sv]=Implementerar stöd för att läsa in netCDF-filer i Kst. Comment[ta]=Kstக்குள் netCDF கோப்புகளை படிக்க ஆதரவை அமுலாக்குகிறது Comment[tg]=Иҷро намудани пуштибонӣ барои хондани файлҳои netCDF ба Kst. Comment[tr]=Kst içine netCDF dosyalarını okuma desteği sağlar. Comment[vi]=Cài đặt hỗ trợ đọc tập tin netCDF vào Kst. Comment[xx]=xxImplements support for reading netCDF files into Kst.xx Comment[zh_CN]=将 netCDF 文件读入 Kst 的应用支持。 kst-2.0.3/src/datasources/netcdf/netcdfsource.h000644 001750 001750 00000005617 11544160210 022100 0ustar00synthsynth000000 000000 /*************************************************************************** netcdf_source.h - netCDF data source reader ------------------- begin : 28/01/2005 copyright : (C) 2004 Nicolas Brisset email : kst@kde.org modified : 03/16/05 by K. Scott ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_NETCDF_H #define KST_NETCDF_H #include "datasource.h" #include "dataplugin.h" #include #include class DataInterfaceNetCdfScalar; class DataInterfaceNetCdfString; class DataInterfaceNetCdfVector; class DataInterfaceNetCdfMatrix; class NetcdfSource : public Kst::DataSource { public: NetcdfSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement &element); ~NetcdfSource(); bool initFile(); Kst::Object::UpdateType internalDataSourceUpdate(); virtual const QString& typeString() const; static const QString netcdfTypeKey(); int readScalar(double *v, const QString& field); int readString(QString *stringValue, const QString& stringName); int readField(double *v, const QString& field, int s, int n); int readMatrix(double *v, const QString& field); int samplesPerFrame(const QString& field); int frameCount(const QString& field = QString()) const; QString fileType() const; void save(QTextStream &ts, const QString& indent = QString()); bool isEmpty() const; void reset(); private: QMap _frameCounts; int _maxFrameCount; NcFile *_ncfile; // we must hold an NcError to overwrite the exit-on-error behaviour of netCDF NcError _ncErr; QMap _strings; // TODO remove friend QStringList _scalarList; QStringList _fieldList; QStringList _matrixList; //QStringList _stringList; friend class DataInterfaceNetCdfScalar; friend class DataInterfaceNetCdfString; friend class DataInterfaceNetCdfVector; friend class DataInterfaceNetCdfMatrix; DataInterfaceNetCdfScalar* is; DataInterfaceNetCdfString* it; DataInterfaceNetCdfVector* iv; DataInterfaceNetCdfMatrix* im; }; #endif kst-2.0.3/src/datasources/netcdf/netcdf.pro000644 001750 001750 00000000553 11544160210 021222 0ustar00synthsynth000000 000000 TOPOUT_REL=../../.. include($$PWD/$$TOPOUT_REL/kst.pri) include($$PWD/../../../datasourceplugin.pri) TARGET = $$kstlib(kst2data_netcdfsource) INCLUDEPATH += $$OUTPUT_DIR/src/datasources/netcdf/tmp LIBS += -l$$kstlib(netcdf_c++) -l$$kstlib(netcdf) SOURCES += \ netcdfsource.cpp \ netcdfplugin.cpp HEADERS += \ netcdfsource.h \ netcdfplugin.h kst-2.0.3/src/datasources/netcdf/netcdfplugin.cpp000644 001750 001750 00000010504 11544160210 022420 0ustar00synthsynth000000 000000 /*************************************************************************** netcdf.cpp - netCDF file data source reader ------------------- begin : 17/06/2004 copyright : (C) 2004 Nicolas Brisset email : kst@kde.org modified : 03/14/05 by K. Scott ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "netcdfplugin.h" #include "netcdfsource.h" #include // // NetCdfPlugin // static const char* plugin_name = "netCDF Reader"; QString NetCdfPlugin::pluginName() const { return plugin_name; } QString NetCdfPlugin::pluginDescription() const { return plugin_name; } Kst::DataSource *NetCdfPlugin::create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const { return new NetcdfSource(store, cfg, filename, type, element); } QStringList NetCdfPlugin::matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { return QStringList(); } QStringList NetCdfPlugin::scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(cfg); Q_UNUSED(type) QStringList scalarList; return scalarList; } QStringList NetCdfPlugin::stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(cfg); Q_UNUSED(type) QStringList stringList; return stringList; } QStringList NetCdfPlugin::fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(cfg); Q_UNUSED(type) QStringList fieldList; return fieldList; } bool NetCdfPlugin::supportsTime(QSettings *cfg, const QString& filename) const { //FIXME Q_UNUSED(cfg) Q_UNUSED(filename) return true; } QStringList NetCdfPlugin::provides() const { return QStringList() << NetcdfSource::netcdfTypeKey(); } Kst::DataSourceConfigWidget *NetCdfPlugin::configWidget(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) Q_UNUSED(filename) return 0;; } /** understands_netcdf: returns true if: - the file is readable (!) - the file can be opened by the netcdf library **/ int NetCdfPlugin::understands(QSettings *cfg, const QString& filename) const { QFile f(filename); if (!f.open(QFile::ReadOnly)) { KST_DBG qDebug() << "Unable to read file !" << endl; return 0; } NcFile *ncfile = new NcFile(filename.toUtf8().data()); if (ncfile->is_valid()) { KST_DBG qDebug() << filename << " looks like netCDF !" << endl; delete ncfile; return 80; } else { delete ncfile; return 0; } } Q_EXPORT_PLUGIN2(kstdata_netcdfsource, NetCdfPlugin) kst-2.0.3/src/datasources/netcdf/netcdfsource.cpp000644 001750 001750 00000041326 11544160210 022430 0ustar00synthsynth000000 000000 /*************************************************************************** netcdf.cpp - netCDF file data source reader ------------------- begin : 17/06/2004 copyright : (C) 2004 Nicolas Brisset email : kst@kde.org modified : 03/14/05 by K. Scott ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // TODO move //#define KST_DEBUG_SHARED #include "sharedptr.h" #include "netcdfsource.h" #include "kst_i18n.h" #include "debug.h" #include #include #include #include using namespace Kst; static const QString netCdfTypeString = I18N_NOOP("netCDF Files"); // // Scalar interface // class DataInterfaceNetCdfScalar : public DataSource::DataInterface { public: DataInterfaceNetCdfScalar(NetcdfSource& s) : netcdf(s) {} // read one element int read(const QString&, DataScalar::ReadInfo&); // named elements QStringList list() const { return netcdf._scalarList; } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataScalar::DataInfo dataInfo(const QString&) const { return DataScalar::DataInfo(); } void setDataInfo(const QString&, const DataScalar::DataInfo&) {} // meta data QMap metaScalars(const QString&) { return QMap(); } QMap metaStrings(const QString&) { return QMap(); } private: NetcdfSource& netcdf; }; int DataInterfaceNetCdfScalar::read(const QString& scalar, DataScalar::ReadInfo& p) { return netcdf.readScalar(p.value, scalar); } bool DataInterfaceNetCdfScalar::isValid(const QString& scalar) const { return netcdf._scalarList.contains( scalar ); } // // String interface // class DataInterfaceNetCdfString : public DataSource::DataInterface { public: DataInterfaceNetCdfString(NetcdfSource& s) : netcdf(s) {} // read one element int read(const QString&, DataString::ReadInfo&); // named elements QStringList list() const { return netcdf._strings.keys(); } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataString::DataInfo dataInfo(const QString&) const { return DataString::DataInfo(); } void setDataInfo(const QString&, const DataString::DataInfo&) {} // meta data QMap metaScalars(const QString&) { return QMap(); } QMap metaStrings(const QString&) { return QMap(); } private: NetcdfSource& netcdf; }; //------------------------------------------------------------------------------------------- int DataInterfaceNetCdfString::read(const QString& string, DataString::ReadInfo& p) { //return netcdf.readString(p.value, string); if (isValid(string) && p.value) { *p.value = netcdf._strings[string]; return 1; } return 0; } bool DataInterfaceNetCdfString::isValid(const QString& string) const { return netcdf._strings.contains( string ); } // // Vector interface // class DataInterfaceNetCdfVector : public DataSource::DataInterface { public: DataInterfaceNetCdfVector(NetcdfSource& s) : netcdf(s) {} // read one element int read(const QString&, DataVector::ReadInfo&); // named elements QStringList list() const { return netcdf._fieldList; } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataVector::DataInfo dataInfo(const QString&) const; void setDataInfo(const QString&, const DataVector::DataInfo&) {} // meta data QMap metaScalars(const QString&); QMap metaStrings(const QString&); private: NetcdfSource& netcdf; }; const DataVector::DataInfo DataInterfaceNetCdfVector::dataInfo(const QString &field) const { if (!netcdf._fieldList.contains(field)) return DataVector::DataInfo(); return DataVector::DataInfo(netcdf.frameCount(field), netcdf.samplesPerFrame(field)); } int DataInterfaceNetCdfVector::read(const QString& field, DataVector::ReadInfo& p) { return netcdf.readField(p.data, field, p.startingFrame, p.numberOfFrames); } bool DataInterfaceNetCdfVector::isValid(const QString& field) const { return netcdf._fieldList.contains( field ); } QMap DataInterfaceNetCdfVector::metaScalars(const QString& field) { NcVar *var = netcdf._ncfile->get_var(field.toLatin1().constData()); if (!var) { KST_DBG qDebug() << "Queried field " << field << " which can't be read" << endl; return QMap(); } QMap fieldScalars; fieldScalars["NbAttributes"] = var->num_atts(); for (int i=0; inum_atts(); ++i) { NcAtt *att = var->get_att(i); // Only handle char attributes as fieldStrings, the others as fieldScalars if (att->type() == NC_BYTE || att->type() == NC_SHORT || att->type() == NC_INT || att->type() == NC_LONG || att->type() == NC_FLOAT || att->type() == NC_DOUBLE) { // Some attributes may have multiple values => load the first as is, and for the others // add a -2, -3, etc... suffix as obviously we can have only one value per scalar. // Do it in two steps to avoid a test in the loop while keeping a "clean" name for the first one fieldScalars[QString(att->name())] = att->values()->as_double(0); for (int j=1; jvalues()->num(); ++j) { fieldScalars[QString(att->name()) + QString("-") + QString::number(j+1)] = att->values()->as_double(j); } } } return fieldScalars; } QMap DataInterfaceNetCdfVector::metaStrings(const QString& field) { NcVar *var = netcdf._ncfile->get_var(field.toLatin1().constData()); if (!var) { KST_DBG qDebug() << "Queried field " << field << " which can't be read" << endl; return QMap(); } QMap fieldStrings; QString tmpString; for (int i=0; inum_atts(); ++i) { NcAtt *att = var->get_att(i); // Only handle char/unspecified attributes as fieldStrings, the others as fieldScalars if (att->type() == NC_CHAR || att->type() == NC_UNSPECIFIED) { fieldStrings[att->name()] = QString(att->values()->as_string(0)); } // qDebug() << att->name() << ": " << att->values()->num() << endl; } return fieldStrings; } // // Matrix interface // class DataInterfaceNetCdfMatrix : public DataSource::DataInterface { public: DataInterfaceNetCdfMatrix(NetcdfSource& s) : netcdf(s) {} // read one element int read(const QString&, DataMatrix::ReadInfo&); // named elements QStringList list() const { return netcdf._matrixList; } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataMatrix::DataInfo dataInfo (const QString&) const; void setDataInfo(const QString&, const DataMatrix::DataInfo&) {} // meta data QMap metaScalars(const QString&) { return QMap(); } QMap metaStrings(const QString&) { return QMap(); } private: NetcdfSource& netcdf; }; const DataMatrix::DataInfo DataInterfaceNetCdfMatrix::dataInfo(const QString& matrix) const { if (!netcdf._matrixList.contains( matrix ) ) { return DataMatrix::DataInfo(); } QByteArray bytes = matrix.toLatin1(); NcVar *var = netcdf._ncfile->get_var(bytes.constData()); // var is owned by _ncfile if (!var) { return DataMatrix::DataInfo(); } if (var->num_dims() != 2) { return DataMatrix::DataInfo(); } DataMatrix::DataInfo info; info.samplesPerFrame = 1; // TODO is this right? info.xSize = var->get_dim(0)->size(); info.ySize = var->get_dim(1)->size(); return info; } int DataInterfaceNetCdfMatrix::read(const QString& field, DataMatrix::ReadInfo& p) { int count = netcdf.readMatrix(p.data->z, field); p.data->xMin = 0; p.data->yMin = 0; p.data->xStepSize = 1; p.data->yStepSize = 1; return count; } bool DataInterfaceNetCdfMatrix::isValid(const QString& field) const { return netcdf._matrixList.contains( field ); } // // NetcdfSource // NetcdfSource::NetcdfSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement &element) : Kst::DataSource(store, cfg, filename, type), _ncfile(0L), _ncErr(NcError::silent_nonfatal), is(new DataInterfaceNetCdfScalar(*this)), it(new DataInterfaceNetCdfString(*this)), iv(new DataInterfaceNetCdfVector(*this)), im(new DataInterfaceNetCdfMatrix(*this)) { setInterface(is); setInterface(it); setInterface(iv); setInterface(im); setUpdateType(None); if (!type.isEmpty() && type != "netCDF") { return; } _valid = false; _maxFrameCount = 0; _filename = filename; _strings = fileMetas(); _valid = initFile(); } NetcdfSource::~NetcdfSource() { delete _ncfile; _ncfile = 0L; } void NetcdfSource::reset() { delete _ncfile; _ncfile = 0L; _maxFrameCount = 0; _valid = initFile(); } bool NetcdfSource::initFile() { _ncfile = new NcFile(_filename.toUtf8().data(), NcFile::ReadOnly); if (!_ncfile->is_valid()) { qDebug() << _filename << ": failed to open in initFile()" << endl; return false; } KST_DBG qDebug() << _filename << ": building field list" << endl; _fieldList.clear(); _fieldList += "INDEX"; int nb_vars = _ncfile->num_vars(); KST_DBG qDebug() << nb_vars << " vars found in total" << endl; _maxFrameCount = 0; for (int i = 0; i < nb_vars; i++) { NcVar *var = _ncfile->get_var(i); if (!var) { continue; } if (var->num_dims() == 0) { _scalarList += var->name(); } else if (var->num_dims() == 1) { _fieldList += var->name(); int fc = var->num_vals() / var->rec_size(); _maxFrameCount = qMax(_maxFrameCount, fc); _frameCounts[var->name()] = fc; } else if (var->num_dims() == 2) { _matrixList += var->name(); } } // Get strings int globalAttributesNb = _ncfile->num_atts(); for (int i = 0; i < globalAttributesNb; ++i) { // Get only first value, should be enough for a start especially as strings are complete NcAtt *att = _ncfile->get_att(i); if (att) { QString attrName = QString(att->name()); char *attString = att->as_string(0); QString attrValue = QString(att->as_string(0)); delete[] attString; //TODO port //KstString *ms = new KstString(KstObjectTag(attrName, tag()), this, attrValue); _strings[attrName] = attrValue; } delete att; } // TODO update(); // necessary? slows down initial loading return true; } Kst::Object::UpdateType NetcdfSource::internalDataSourceUpdate() { //TODO port /* if (KstObject::checkUpdateCounter(u)) { return lastUpdateResult(); } */ _ncfile->sync(); bool updated = false; /* Update member variables _ncfile, _maxFrameCount, and _frameCounts and indicate that an update is needed */ int nb_vars = _ncfile->num_vars(); for (int j = 0; j < nb_vars; j++) { NcVar *var = _ncfile->get_var(j); if (!var) { continue; } int fc = var->num_vals() / var->rec_size(); _maxFrameCount = qMax(_maxFrameCount, fc); updated = updated || (_frameCounts[var->name()] != fc); _frameCounts[var->name()] = fc; } return updated ? Object::Updated : Object::NoChange; } int NetcdfSource::readScalar(double *v, const QString& field) { // TODO error handling QByteArray bytes = field.toLatin1(); NcVar *var = _ncfile->get_var(bytes.constData()); // var is owned by _ncfile if (var) { var->get(v); return 1; } return 0; } int NetcdfSource::readString(QString *stringValue, const QString& stringName) { // TODO more error handling? NcAtt *att = _ncfile->get_att((NcToken) stringName.toLatin1().data()); if (att) { *stringValue = QString(att->as_string(0)); delete att; return 1; } return 0; } int NetcdfSource::readField(double *v, const QString& field, int s, int n) { NcType dataType = ncNoType; /* netCDF data type */ /* Values for one record */ NcValues *record = 0;// = new NcValues(dataType,numFrameVals); KST_DBG qDebug() << "Entering NetcdfSource::readField with params: " << field << ", from " << s << " for " << n << " frames" << endl; /* For INDEX field */ if (field.toLower() == "index") { if (n < 0) { v[0] = double(s); return 1; } for (int i = 0; i < n; ++i) { v[i] = double(s + i); } return n; } /* For a variable from the netCDF file */ QByteArray bytes = field.toLatin1(); NcVar *var = _ncfile->get_var(bytes.constData()); // var is owned by _ncfile if (!var) { KST_DBG qDebug() << "Queried field " << field << " which can't be read" << endl; return -1; } dataType = var->type(); if (s >= var->num_vals() / var->rec_size()) { return 0; } bool oneSample = n < 0; int recSize = var->rec_size(); switch (dataType) { case ncShort: { if (oneSample) { record = var->get_rec(s); v[0] = record->as_short(0); delete record; } else { for (int i = 0; i < n; i++) { record = var->get_rec(i+s); for (int j = 0; j < recSize; j++) { v[i*recSize + j] = record->as_short(j); } delete record; } } } break; case ncInt: { if (oneSample) { record = var->get_rec(s); v[0] = record->as_int(0); delete record; } else { for (int i = 0; i < n; i++) { record = var->get_rec(i+s); KST_DBG qDebug() << "Read record " << i+s << endl; for (int j = 0; j < recSize; j++) { v[i*recSize + j] = record->as_int(j); } delete record; } } } break; case ncFloat: { if (oneSample) { record = var->get_rec(s); v[0] = record->as_float(0); delete record; } else { for (int i = 0; i < n; i++) { record = var->get_rec(i+s); for (int j = 0; j < recSize; j++) { v[i*recSize + j] = record->as_float(j); } delete record; } } } break; case ncDouble: { if (oneSample) { record = var->get_rec(s); v[0] = record->as_double(0); delete record; } else { for (int i = 0; i < n; i++) { record = var->get_rec(i+s); for (int j = 0; j < recSize; j++) { v[i*recSize + j] = record->as_double(j); } delete record; } } } break; default: KST_DBG qDebug() << field << ": wrong datatype for kst, no values read" << endl; return -1; break; } KST_DBG qDebug() << "Finished reading " << field << endl; return oneSample ? 1 : n * recSize; } int NetcdfSource::readMatrix(double *v, const QString& field) { /* For a variable from the netCDF file */ QByteArray bytes = field.toLatin1(); NcVar *var = _ncfile->get_var(bytes.constData()); // var is owned by _ncfile if (!var) { KST_DBG qDebug() << "Queried field " << field << " which can't be read" << endl; return -1; } int xSize = var->get_dim(0)->size(); int ySize = var->get_dim(1)->size(); var->get(v, xSize, ySize); return xSize * ySize; } int NetcdfSource::samplesPerFrame(const QString& field) { if (field.toLower() == "index") { return 1; } QByteArray bytes = field.toLatin1(); NcVar *var = _ncfile->get_var(bytes.constData()); if (!var) { KST_DBG qDebug() << "Queried field " << field << " which can't be read" << endl; return 0; } return var->rec_size(); } int NetcdfSource::frameCount(const QString& field) const { if (field.isEmpty() || field.toLower() == "index") { return _maxFrameCount; } else { return _frameCounts[field]; } } QString NetcdfSource::fileType() const { return "netCDF"; } bool NetcdfSource::isEmpty() const { return frameCount() < 1; } const QString& NetcdfSource::typeString() const { return netCdfTypeString; } const QString NetcdfSource::netcdfTypeKey() { return ::netCdfTypeString; } kst-2.0.3/src/datasources/netcdf/netcdfplugin.h000644 001750 001750 00000006246 11544160210 022075 0ustar00synthsynth000000 000000 /*************************************************************************** netcdf_source.h - netCDF data source reader ------------------- begin : 28/01/2005 copyright : (C) 2004 Nicolas Brisset email : kst@kde.org modified : 03/16/05 by K. Scott ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_NETCDF_H #define KST_NETCDF_PLUGIN_H #include "dataplugin.h" class NetCdfPlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~NetCdfPlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return false; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif kst-2.0.3/src/datasources/qimagesource/qimagesource.h000644 001750 001750 00000007415 11544160210 023317 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2005 C. Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef QIMAGESOURCE_H #define QIMAGESOURCE_H #include #include class DataInterfaceQImageVector; class DataInterfaceQImageMatrix; class QImageSource : public Kst::DataSource { Q_OBJECT public: QImageSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e); ~QImageSource(); bool init(); virtual void reset(); Kst::Object::UpdateType internalDataSourceUpdate(); bool isEmpty() const; QString fileType() const; void save(QXmlStreamWriter &streamWriter); virtual const QString& typeString() const; class Config; //int readScalar(double &S, const QString& scalar); //int readString(QString &S, const QString& string); private: QImage _image; mutable Config *_config; DataInterfaceQImageVector* iv; DataInterfaceQImageMatrix* im; }; class QImageSourcePlugin : public QObject, public Kst::DataSourcePluginInterface { Q_OBJECT Q_INTERFACES(Kst::DataSourcePluginInterface) public: virtual ~QImageSourcePlugin() {} virtual QString pluginName() const; virtual QString pluginDescription() const; virtual bool hasConfigWidget() const { return false; } virtual Kst::DataSource *create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const; virtual int understands(QSettings *cfg, const QString& filename) const; virtual bool supportsTime(QSettings *cfg, const QString& filename) const; virtual QStringList provides() const; virtual Kst::DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/qimagesource/kstdata_qimagesource.desktop000644 001750 001750 00000004137 11544160210 026252 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-KDE-Library=qimagesource X-Kst-Plugin-Author=The University of Toronto Name=qimagesource Name[el]=Πηγή qimage Name[it]=sorgenteqimage Name[nl]=qimage-bron Name[sr]=qimage извор Name[sr@Latn]=qimage izvor Name[sv]=QImage-källa Name[tg]=манбаъи тасвир Name[xx]=xxqimagesourcexx Comment=Plugin to read a qimage compatible image. Comment[ca]=Connector per llegir una imatge compatible amb qimage. Comment[cs]=Modul pro čtení obrázků kompatibilních s qimage. Comment[da]=Plugin til at læse et qimage-kompatibelt billede. Comment[de]=Modul zum Lesen von QImage-kompatiblen Bildern Comment[el]=Πρόσθετο για την ανάγνωση συμβατών με qimage εικόνων. Comment[es]=Plugin para leer una imagen compatible con qimage. Comment[et]=Plugin qimage'iga ühilduvate piltide lugemiseks. Comment[ga]=Breiseán a léann íomhánna atá comhoiriúnach le qimage. Comment[gl]=Un plugin para ler imaxes compatíbeis con qimage. Comment[hr]=Dodatak za čitanje qimage kompatibilnih slika. Comment[is]=Íforrit til að lesa qimage-samhæfðar myndskrár. Comment[it]=Plugin per leggere un'immagine compatibile con qimage. Comment[ja]=qimage 互換の画像を読むためのプラグイン Comment[ka]=qimage-თან თავსებადი გამოსახულების წამკითხველი მოდული. Comment[nl]=Plugin voor het lezen van een afbeelding die compatibel is met qimage. Comment[pt]=Um 'plugin' para ler imagens compatível com qimage. Comment[pt_BR]=Plug-in para a leitura de uma imagem compatível com qimage. Comment[sr]=Прикључак за читање qimage компатибилних слика. Comment[sr@Latn]=Priključak za čitanje qimage kompatibilnih slika. Comment[sv]=Insticksprogram för att en bild som kan hanteras av QImage. Comment[tg]=Модул барои хондани тасвири ҳамсозӣ. Comment[vi]=Bổ sung đọc ảnh tương thích với qimage. Comment[xx]=xxPlugin to read a qimage compatible image.xx kst-2.0.3/src/datasources/qimagesource/qimagesource.cpp000644 001750 001750 00000032554 11544160210 023654 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2005 C. Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "qimagesource.h" #include "kst_i18n.h" #include #include #include using namespace Kst; static const QString qimageTypeString = I18N_NOOP("QImage image"); class QImageSource::Config { public: Config() { } void read(QSettings *cfg, const QString& fileName = QString()) { Q_UNUSED(fileName); cfg->beginGroup(qimageTypeString); cfg->endGroup(); } void save(QXmlStreamWriter& s) { Q_UNUSED(s); } void load(const QDomElement& e) { Q_UNUSED(e); } }; // // Vector interface // class DataInterfaceQImageVector : public DataSource::DataInterface { public: DataInterfaceQImageVector(QImage* img) : _image(img) {} // read one element int read(const QString&, DataVector::ReadInfo&); // named elements QStringList list() const { return _vectorList; } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataVector::DataInfo dataInfo(const QString&) const; void setDataInfo(const QString&, const DataVector::DataInfo&) {} // meta data QMap metaScalars(const QString&); QMap metaStrings(const QString&) { return QMap(); } // no interface QImage* _image; QStringList _vectorList; int _frameCount; void init(); void clear(); }; void DataInterfaceQImageVector::clear() { _vectorList.clear(); _frameCount = 0; } void DataInterfaceQImageVector::init() { _vectorList.append( "GRAY" ); _vectorList.append( "RED" ); _vectorList.append( "GREEN" ); _vectorList.append( "BLUE" ); } const DataVector::DataInfo DataInterfaceQImageVector::dataInfo(const QString &field) const { if (!_vectorList.contains(field)) return DataVector::DataInfo(); return DataVector::DataInfo(_frameCount, 1); } int DataInterfaceQImageVector::read(const QString& field, DataVector::ReadInfo& p) { int i = 0; int s = p.startingFrame; int n = p.numberOfFrames; if ( field=="INDEX" ) { for ( i=0; iwidth(); int py = i/_image->width(); p.data[i-s] = qGray( _image->pixel( px, py ) ); } } else if ( field=="RED" ) { for ( i=s; iwidth(); int py = i/_image->width(); p.data[i-s] = qRed( _image->pixel( px, py ) ); } } else if ( field=="GREEN" ) { for ( i=s; iwidth(); int py = i/_image->width(); p.data[i-s] = qGreen( _image->pixel( px, py ) ); } } else if ( field=="BLUE" ) { for ( i=s; iwidth(); int py = i/_image->width(); p.data[i-s] = qBlue( _image->pixel( px, py ) ); } } return i; } bool DataInterfaceQImageVector::isValid(const QString& field) const { return _vectorList.contains( field ); } // TODO FRAMES only in vector? QMap DataInterfaceQImageVector::metaScalars(const QString&) { QMap m; m["FRAMES"] = _frameCount; return m; } // // Matrix interface // class DataInterfaceQImageMatrix : public DataSource::DataInterface { public: DataInterfaceQImageMatrix(QImage* img) : _image(img) {} // read one element int read(const QString&, DataMatrix::ReadInfo&); // named elements QStringList list() const { return _matrixList; } bool isListComplete() const { return true; } bool isValid(const QString&) const; // T specific const DataMatrix::DataInfo dataInfo(const QString&) const; void setDataInfo(const QString&, const DataMatrix::DataInfo&) {} // meta data QMap metaScalars(const QString&) { return QMap(); } QMap metaStrings(const QString&) { return QMap(); } // no interface QImage* _image; QStringList _matrixList; void init(); void clear(); }; void DataInterfaceQImageMatrix::clear() { _matrixList.clear(); } void DataInterfaceQImageMatrix::init() { _matrixList.append( "GRAY" ); _matrixList.append( "RED" ); _matrixList.append( "GREEN" ); _matrixList.append( "BLUE" ); } const DataMatrix::DataInfo DataInterfaceQImageMatrix::dataInfo(const QString& matrix) const { if ( !_image || _image->isNull() || !_matrixList.contains( matrix ) ) { return DataMatrix::DataInfo(); } DataMatrix::DataInfo info; info.samplesPerFrame = 1; info.xSize = _image->width(); info.ySize = _image->height(); return info; } int DataInterfaceQImageMatrix::read(const QString& field, DataMatrix::ReadInfo& p) { if ( _image->isNull() ) { return 0; } int y0 = p.yStart; int y1 = p.yStart + p.yNumSteps; int x0 = p.xStart; int x1 = p.xStart + p.xNumSteps; double* z = p.data->z; int i = 0; if ( field=="GRAY") { for (int px = p.xStart; px=p.yStart; py-- ) { z[i] = qGray( _image->pixel( px, py ) ); i++; } } } else if ( field=="RED" ) { for (int px = p.xStart; px=p.yStart; py-- ) { z[i] = qRed( _image->pixel( px, py ) ); i++; } } } else if ( field=="GREEN" ) { for (int px = p.xStart; px=p.yStart; py-- ) { z[i] = qGreen( _image->pixel( px, py ) ); i++; } } } else if ( field=="BLUE" ) { for (int px = p.xStart; px=p.yStart; py-- ) { z[i] = qBlue( _image->pixel( px, py ) ); i++; } } } // set the suggested matrix transform params: pixel index.... p.data->xMin = x0; p.data->yMin = y0; p.data->xStepSize = 1; p.data->yStepSize = 1; return i; } bool DataInterfaceQImageMatrix::isValid(const QString& field) const { return _matrixList.contains( field ); } // // QImageSource // QImageSource::QImageSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) : Kst::DataSource(store, cfg, filename, type), _config(0L), iv(new DataInterfaceQImageVector(&_image)), im(new DataInterfaceQImageMatrix(&_image)) { setInterface(iv); setInterface(im); setUpdateType(None); _valid = false; if (!type.isEmpty() && type != qimageTypeString) { return; } _config = new QImageSource::Config; _config->read(cfg, filename); if (!e.isNull()) { _config->load(e); } _image = QImage(); if (init()) { _valid = true; } registerChange(); } QImageSource::~QImageSource() { delete _config; _config = 0L; } const QString& QImageSource::typeString() const { return qimageTypeString; } void QImageSource::reset() { init(); Object::reset(); } bool QImageSource::init() { _image = QImage(); iv->clear(); im->clear(); if (!_image.load( _filename ) ) { return false; } iv->init(); im->init(); registerChange(); return true; } Kst::Object::UpdateType QImageSource::internalDataSourceUpdate() { int newNF = _image.width()*_image.height(); bool isnew = newNF != iv->_frameCount; iv->_frameCount = newNF; return (isnew ? Kst::Object::Updated : Kst::Object::NoChange); } bool QImageSource::isEmpty() const { return iv->_frameCount < 1; } QString QImageSource::fileType() const { return qimageTypeString; } void QImageSource::save(QXmlStreamWriter &streamWriter) { Kst::DataSource::save(streamWriter); } /* TODO needed? int QImageSource::readScalar(double &S, const QString& scalar) { if (scalar == "FRAMES") { S = _frameCount; return 1; } return 0; } int QImageSource::readString(QString &S, const QString& string) { if (string == "FILE") { S = _filename; return 1; } return 0; } */ // // QImageSourcePlugin // QString QImageSourcePlugin::pluginName() const { return "QImage Source Reader"; } QString QImageSourcePlugin::pluginDescription() const { return "QImage Source Reader"; } Kst::DataSource *QImageSourcePlugin::create(Kst::ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const { return new QImageSource(store, cfg, filename, type, element); } QStringList QImageSourcePlugin::matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { if (typeSuggestion) { *typeSuggestion = qimageTypeString; } if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } QStringList matrixList; if (complete) { *complete = true; } if ( !QImageReader::imageFormat( filename ).isEmpty() ) { matrixList.append( "GRAY" ); matrixList.append( "RED" ); matrixList.append( "GREEN" ); matrixList.append( "BLUE" ); } return matrixList; } QStringList QImageSourcePlugin::scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList scalarList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = qimageTypeString; } scalarList.append("FRAMES"); return scalarList; } QStringList QImageSourcePlugin::stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { QStringList stringList; if ((!type.isEmpty() && !provides().contains(type)) || 0 == understands(cfg, filename)) { if (complete) { *complete = false; } return QStringList(); } if (typeSuggestion) { *typeSuggestion = qimageTypeString; } stringList.append("FILENAME"); return stringList; } QStringList QImageSourcePlugin::fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const { Q_UNUSED(type) Q_UNUSED(cfg) QStringList fieldList; if (complete) { *complete = true; } if (typeSuggestion) { *typeSuggestion = qimageTypeString; } if ( !QImageReader::imageFormat( filename ).isEmpty() ) { fieldList.append("INDEX"); fieldList.append( "GRAY" ); fieldList.append( "RED" ); fieldList.append( "GREEN" ); fieldList.append( "BLUE" ); } return fieldList; } int QImageSourcePlugin::understands(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) QList formats = QImageReader::supportedImageFormats(); bool matches = false; foreach (QByteArray ext, formats) { if (filename.toLower().endsWith(ext.toLower())) { matches = true; break; } } if (!matches) { return 0; } QString ftype( QImageReader::imageFormat( filename ) ); if ( ftype.isEmpty() ) return 0; //QImageReader is incorrectly identifying some ascii files with // images. Enforce filenames (may not be needed anymore, since // we already know that the extension matches *some* image format. //if ( ftype == "TIFF" ) { // if ( !filename.toLower().endsWith(".tif") ) return 0; //} //if ( ftype == "pcx" ) { // if ( !filename.toLower().endsWith(".pcx") ) return 0; //} return 90; } bool QImageSourcePlugin::supportsTime(QSettings *cfg, const QString& filename) const { //FIXME Q_UNUSED(cfg) Q_UNUSED(filename) return true; } QStringList QImageSourcePlugin::provides() const { QStringList rc; rc += qimageTypeString; return rc; } Kst::DataSourceConfigWidget *QImageSourcePlugin::configWidget(QSettings *cfg, const QString& filename) const { Q_UNUSED(cfg) Q_UNUSED(filename) return 0;; } Q_EXPORT_PLUGIN2(kstdata_qimagesource, QImageSourcePlugin) // vim: ts=2 sw=2 et kst-2.0.3/src/datasources/qimagesource/qimagesource.pro000644 001750 001750 00000000420 11544160210 023655 0ustar00synthsynth000000 000000 TOPOUT_REL=../../.. include($$PWD/$$TOPOUT_REL/kst.pri) include($$PWD/../../../datasourceplugin.pri) TARGET = $$kstlib(kst2data_qimagesource) INCLUDEPATH += $$OUTPUT_DIR/src/datasources/qimagesource/tmp SOURCES += \ qimagesource.cpp HEADERS += \ qimagesource.h kst-2.0.3/src/libkst/editablematrix.h000644 001750 001750 00000003075 11544160210 020116 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EDITABLEMATRIX_H #define EDITABLEMATRIX_H #include "matrix.h" #include "kst_export.h" namespace Kst { class KSTCORE_EXPORT EditableMatrix : public Matrix { Q_OBJECT public: virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; virtual void save(QXmlStreamWriter &xml); protected: EditableMatrix(ObjectStore *store); friend class ObjectStore; }; typedef SharedPtr EditableMatrixPtr; typedef ObjectList EditableMatrixList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/sysinfo.c000644 001750 001750 00000015140 11544160210 016601 0ustar00synthsynth000000 000000 // Copyright (C) 1992-1998 by Michael K. Johnson, johnsonm@redhat.com // Copyright 1998-2003 Albert Cahalan // // This file is placed under the conditions of the GNU Library // General Public License, version 2, or any later version. // See file COPYING for information on distribution conditions. // // File for parsing top-level /proc entities. // This file is from the procps project at http://procps.sourceforge.net/ #include #include #include #include #include #include #include #include #define BAD_OPEN_MESSAGE \ "Error: /proc must be mounted\n" \ " To mount /proc at boot you need an /etc/fstab line like:\n" \ " /proc /proc proc defaults\n" \ " In the meantime, mount /proc /proc -t proc\n" #define MEMINFO_FILE "/proc/meminfo" static int meminfo_fd = -1; static char buf[1024]; /* This macro opens filename only if necessary and seeks to 0 so * that successive calls to the functions are more efficient. * It also reads the current contents of the file into the global buf. */ #define FILE_TO_BUF(filename, fd) do{ \ static int local_n; \ if (fd == -1 && (fd = open(filename, O_RDONLY)) == -1) { \ fprintf(stderr, BAD_OPEN_MESSAGE); \ fflush(NULL); \ _exit(102); \ } \ lseek(fd, 0L, SEEK_SET); \ if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) { \ perror(filename); \ fflush(NULL); \ _exit(103); \ } \ buf[local_n] = '\0'; \ }while(0) /* evals 'x' twice */ #define SET_IF_DESIRED(x,y) do{ if(x) *(x) = (y); }while(0) /***********************************************************************/ /* * Copyright 1999 by Albert Cahalan; all rights reserved. * This file may be used subject to the terms and conditions of the * GNU Library General Public License Version 2, or any later version * at your option, as published by the Free Software Foundation. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. */ typedef struct mem_table_struct { const char *name; /* memory type name */ unsigned long *slot; /* slot in return struct */ } mem_table_struct; static int compare_mem_table_structs(const void *a, const void *b){ return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name); } /* example data, following junk, with comments added: * * MemTotal: 61768 kB old * MemFree: 1436 kB old * MemShared: 0 kB old (now always zero; not calculated) * Buffers: 1312 kB old * Cached: 20932 kB old * Active: 12464 kB new * Inact_dirty: 7772 kB new * Inact_clean: 2008 kB new * Inact_target: 0 kB new * Inact_laundry: 0 kB new, and might be missing too * HighTotal: 0 kB * HighFree: 0 kB * LowTotal: 61768 kB * LowFree: 1436 kB * SwapTotal: 122580 kB old * SwapFree: 60352 kB old * Inactive: 20420 kB 2.5.41+ * Dirty: 0 kB 2.5.41+ * Writeback: 0 kB 2.5.41+ * Mapped: 9792 kB 2.5.41+ * Slab: 4564 kB 2.5.41+ * Committed_AS: 8440 kB 2.5.41+ * PageTables: 304 kB 2.5.41+ * ReverseMaps: 5738 2.5.41+ * SwapCached: 0 kB 2.5.??+ * HugePages_Total: 220 2.5.??+ * HugePages_Free: 138 2.5.??+ * Hugepagesize: 4096 kB 2.5.??+ */ /* obsolete */ unsigned long kb_main_shared; /* old but still kicking -- the important stuff */ unsigned long kb_main_buffers; unsigned long kb_main_cached; unsigned long kb_main_free; unsigned long kb_main_total; unsigned long kb_swap_free; unsigned long kb_swap_total; /* recently introduced */ unsigned long kb_high_free; unsigned long kb_high_total; unsigned long kb_low_free; unsigned long kb_low_total; /* 2.4.xx era */ unsigned long kb_active; unsigned long kb_inact_laundry; unsigned long kb_inact_dirty; unsigned long kb_inact_clean; unsigned long kb_inact_target; unsigned long kb_swap_cached; /* late 2.4 only */ /* derived values */ unsigned long kb_swap_used; unsigned long kb_main_used; /* 2.5.41+ */ unsigned long kb_writeback; unsigned long kb_slab; unsigned long nr_reversemaps; unsigned long kb_committed_as; unsigned long kb_dirty; unsigned long kb_inactive; unsigned long kb_mapped; unsigned long kb_pagetables; void meminfo(void){ char namebuf[16]; /* big enough to hold any row name */ mem_table_struct findme = { namebuf, NULL}; mem_table_struct *found; char *head; char *tail; static const mem_table_struct mem_table[] = { {"Active", &kb_active}, {"Buffers", &kb_main_buffers}, {"Cached", &kb_main_cached}, {"Committed_AS", &kb_committed_as}, {"Dirty", &kb_dirty}, {"HighFree", &kb_high_free}, {"HighTotal", &kb_high_total}, {"Inact_clean", &kb_inact_clean}, {"Inact_dirty", &kb_inact_dirty}, {"Inact_laundry",&kb_inact_laundry}, {"Inact_target", &kb_inact_target}, {"Inactive", &kb_inactive}, {"LowFree", &kb_low_free}, {"LowTotal", &kb_low_total}, {"Mapped", &kb_mapped}, {"MemFree", &kb_main_free}, {"MemShared", &kb_main_shared}, {"MemTotal", &kb_main_total}, {"PageTables", &kb_pagetables}, {"ReverseMaps", &nr_reversemaps}, {"Slab", &kb_slab}, {"SwapCached", &kb_swap_cached}, {"SwapFree", &kb_swap_free}, {"SwapTotal", &kb_swap_total}, {"Writeback", &kb_writeback}, }; const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct); FILE_TO_BUF(MEMINFO_FILE,meminfo_fd); kb_inactive = ~0UL; head = buf; for(;;){ tail = strchr(head, ':'); if(!tail) break; *tail = '\0'; if(strlen(head) >= sizeof(namebuf)){ head = tail+1; goto nextline; } strcpy(namebuf,head); found = bsearch(&findme, mem_table, mem_table_count, sizeof(mem_table_struct), compare_mem_table_structs ); head = tail+1; if(!found) goto nextline; *(found->slot) = strtoul(head,&tail,10); nextline: tail = strchr(head, '\n'); if(!tail) break; head = tail+1; } if(!kb_low_total){ /* low==main except with large-memory support */ kb_low_total = kb_main_total; kb_low_free = kb_main_free; } if(kb_inactive==~0UL){ kb_inactive = kb_inact_dirty + kb_inact_clean + kb_inact_laundry; } kb_swap_used = kb_swap_total - kb_swap_free; kb_main_used = kb_main_total - kb_main_free; } kst-2.0.3/src/libkst/plotiteminterface.h000644 001750 001750 00000002617 11544160210 020637 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLOTITEMINTERFACE_H #define PLOTITEMINTERFACE_H #include #include #include "kst_export.h" namespace Kst { class KSTCORE_EXPORT PlotItemInterface { public: static const qint64 Forced = -1; PlotItemInterface(); virtual ~PlotItemInterface(); virtual QString plotName() const = 0; virtual bool handleChangedInputs(qint64 serial) = 0; void registerChange() {_serialOfLastChange = Forced;} protected: qint64 _serialOfLastChange; }; } Q_DECLARE_METATYPE(Kst::PlotItemInterface*) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/builtindatasources.cpp000644 001750 001750 00000002042 11544160210 021350 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "builtindatasources.h" #include "datasourcepluginfactory.h" namespace Kst { namespace Builtins { void initDataSources() { new DataSourcePluginFactory(); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/sharedptr.h000644 001750 001750 00000013060 11544160210 017107 0ustar00synthsynth000000 000000 /* This file is derived from the KDE libraries Copyright (c) 1999 Waldo Bastian Copyright (c) 2004 The University of Toronto This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SharedPTR_H #define SharedPTR_H #include #include //#define KST_DEBUG_SHARED #ifdef KST_DEBUG_SHARED #define KST_DBG if (true) #else #define KST_DBG if (false) #endif // NOTE: In order to preserve binary compatibility with plugins, you must // not add, remove, or change member variables or virtual functions. // You must also not remove or change non-virtual functions. // See KSharedPtr in KDE libraries for more information namespace Kst { #define SEMAPHORE_COUNT 999999 class Shared { public: /** * Standard constructor. This will initialize the reference count * on this object to 0. */ Shared() : sem(SEMAPHORE_COUNT) { } /** * Copy constructor. This will @em not actually copy the objects * but it will initialize the reference count on this object to 0. */ Shared( const Shared & ) : sem(SEMAPHORE_COUNT) { } /** * Overloaded assignment operator. */ Shared &operator=(const Shared & ) { return *this; } /** * Increases the reference count by one. */ void _KShared_ref() const { sem.acquire(1); KST_DBG qDebug() << "KShared_ref: " << (void*)this << " -> " << _KShared_count() << endl; } /** * Releases a reference (decreases the reference count by one). If * the count goes to 0, this object will delete itself. */ void _KShared_unref() const { sem.release(1); KST_DBG qDebug() << "KShared_unref: " << (void*)this << " -> " << _KShared_count() << endl; if (SEMAPHORE_COUNT == sem.available()) delete this; } /** * Return the current number of references held. * * @return Number of references */ int _KShared_count() const { return SEMAPHORE_COUNT - sem.available(); } protected: virtual ~Shared() { } private: mutable QSemaphore sem; }; template< class T > struct SharedPtr { public: /** * Creates a null pointer. */ SharedPtr() : ptr(0) { isPtrValid(); } /** * Creates a new pointer. * @param t the pointer */ SharedPtr( T* t ) : ptr(t) { if (isPtrValid()) ptr->_KShared_ref(); } /** * Copies a pointer. * @param p the pointer to copy */ SharedPtr( const SharedPtr& p ) : ptr(p.ptr) { if (isPtrValid()) ptr->_KShared_ref(); } template SharedPtr(SharedPtr& p) : ptr(p.data()) { if (isPtrValid()) ptr->_KShared_ref(); } /** * Unreferences the object that this pointer points to. If it was * the last reference, the object will be deleted. */ ~SharedPtr() { if (isPtrValid()) ptr->_KShared_unref(); } SharedPtr& operator= ( const SharedPtr& p ) { isPtrValid(); if ( ptr == p.ptr ) return *this; if (isPtrValid()) ptr->_KShared_unref(); ptr = p.ptr; if (isPtrValid()) ptr->_KShared_ref(); return *this; } template SharedPtr& operator=(SharedPtr& p) { isPtrValid(); if (ptr == p.data()) return *this; if (isPtrValid()) ptr->_KShared_unref(); ptr = p.data(); if (isPtrValid()) ptr->_KShared_ref(); return *this; } SharedPtr& operator= ( T* p ) { isPtrValid(); if (ptr == p) return *this; if (isPtrValid()) ptr->_KShared_unref(); ptr = p; if (isPtrValid()) ptr->_KShared_ref(); return *this; } bool operator== ( const SharedPtr& p ) const { isPtrValid(); return ( ptr == p.ptr ); } bool operator!= ( const SharedPtr& p ) const { isPtrValid(); return ( ptr != p.ptr ); } bool operator== ( const T* p ) const { isPtrValid(); return ( ptr == p ); } bool operator!= ( const T* p ) const { isPtrValid(); return ( ptr != p ); } bool operator!() const { isPtrValid(); return ( ptr == 0 ); } operator T*() const { isPtrValid(); return ptr; } /** * Returns the pointer. * @return the pointer */ T* data() { isPtrValid(); return ptr; } /** * Returns the pointer. * @return the pointer */ const T* data() const { isPtrValid(); return ptr; } const T& operator*() const { Q_ASSERT(isPtrValid()); return *ptr; } T& operator*() { Q_ASSERT(isPtrValid()); return *ptr; } const T* operator->() const { Q_ASSERT(isPtrValid()); return ptr; } T* operator->() { Q_ASSERT(isPtrValid()); return ptr; } /** * Returns the number of references. * @return the number of references */ int count() const { Q_ASSERT(isPtrValid()); return ptr->_KShared_count(); } // for debugging purposes bool isPtrValid() const { return ptr != 0; } private: T* ptr; }; template inline SharedPtr kst_cast(SharedPtr object) { return qobject_cast(object.data()); } // FIXME: make this safe template inline SharedPtr kst_cast(QObject *object) { return qobject_cast(object); } } #endif kst-2.0.3/src/libkst/measuretime.cpp000644 001750 001750 00000004715 11544160210 017775 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "measuretime.h" #include "debug.h" #ifdef Q_OS_WIN #include #else #include #endif #include MeasureTime::MeasureTime(const QString& n) : started(0), interval(0), name(n), other_interval(0) { setFrequency(); restart(); } void MeasureTime::setFrequency() { #ifdef Q_OS_WIN LARGE_INTEGER proc_freq; QueryPerformanceFrequency(&proc_freq); frequency = 1.0 / proc_freq.QuadPart; #endif } MeasureTime::MeasureTime(MeasureTime& rhs) : started(0), interval(0), frequency(rhs.frequency), other_interval(&rhs.interval) { restart(); } MeasureTime::~MeasureTime() { if (other_interval) { measure(); *other_interval += interval; } else { print(); } } double MeasureTime::getTime() const { #ifdef Q_OS_WIN LARGE_INTEGER st; QueryPerformanceCounter(&st); return st.QuadPart * frequency; #else #if defined(Q_OS_MAC) // TODO return 0; #else timespec t; #if defined(CLOCK_PROCESS_CPUTIME_ID) clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t); #elif defined(CLOCK_PROF) clock_gettime(CLOCK_PROF, &t); #else clock_gettime(CLOCK_REALTIME, &t); #endif return 1.0 * t.tv_sec + 1e-9 * t.tv_nsec; #endif #endif } void MeasureTime::restart() { started = getTime(); interval = 0; } void MeasureTime::measure() { double now = getTime(); interval += now - started; started = now; } void MeasureTime::print() { measure(); //std::cout << qPrintable(name) << ": " << interval << " seconds\n"; Kst::Debug::self()->log(QString("Timing: %2 sec, Scope: %1").arg(name).arg(interval), Kst::Debug::DebugLog); } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/extension.h000644 001750 001750 00000002727 11544160210 017137 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EXTENSION_H #define EXTENSION_H #include #include #include "kst_export.h" class QMainWindow; namespace Kst { class KSTCORE_EXPORT Extension : public QObject { Q_OBJECT public: Extension(QObject *parent, const QStringList&); virtual ~Extension(); virtual void processArguments(const QString& args); // To save state virtual void load(const QDomElement& e); virtual void save(QTextStream& ts, const QString& indent = QString()); // Clear internal state virtual void clear(); QMainWindow *app() const; signals: void unregister(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/primitive.cpp000644 001750 001750 00000004746 11544160210 017471 0ustar00synthsynth000000 000000 /*************************************************************************** primitive.cpp ------------------- begin : Tue Jun 20, 2006 copyright : Copyright (C) 2006, The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * Permission is granted to link with any opensource library * * * ***************************************************************************/ //#define UPDATEDEBUG #include #include #include "kst_i18n.h" #include "primitive.h" #include "updatemanager.h" #include "datasource.h" namespace Kst { const QString Primitive::staticTypeString = I18N_NOOP("Primitive"); Primitive::Primitive(ObjectStore *store, Object *provider) : _provider(provider) { Q_UNUSED(store); _slaveName = "fixme: set _slaveName"; } Primitive::~Primitive() { } const QString& Primitive::typeString() const { return staticTypeString; } void Primitive::setProvider(Object* obj) { _provider = obj; } void Primitive::setSlaveName(QString slaveName) { _slaveName=slaveName; } QString Primitive::_automaticDescriptiveName() const { QString name; if (_provider) { name = _provider->descriptiveName() + ':'; } name += _slaveName; return name; } qint64 Primitive::minInputSerial() const { if (_provider) { return (_provider->serial()); } return LLONG_MAX; } qint64 Primitive::minInputSerialOfLastChange() const { if (_provider) { return (_provider->serialOfLastChange()); } return LLONG_MAX; } QString Primitive::propertyString() const { return QString("Base Class Property String"); } QString Primitive::sizeString() const { return QString("Base Class Size String"); } bool Primitive::used() const { if (_provider) { return true; } else { return Object::used(); } } } // vim: et sw=2 ts=2 kst-2.0.3/src/libkst/plotiteminterface.cpp000644 001750 001750 00000002014 11544160210 021161 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "plotiteminterface.h" namespace Kst { PlotItemInterface::PlotItemInterface(): _serialOfLastChange(0) { } PlotItemInterface::~PlotItemInterface() { } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datastring.h000644 001750 001750 00000005243 11544160210 017257 0ustar00synthsynth000000 000000 /*************************************************************************** dataststring.h - a string from a data source ------------------- begin : September, 2008 copyright : (C) 2008 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATASTRING_H #define DATASTRING_H #include "kst_export.h" #include "dataprimitive.h" #include "string_kst.h" class QXmlStreamWriter; namespace Kst { /**A class for handling data strings for kst. *@author cbn */ /** A string which gets its value from a data file. */ class KSTCORE_EXPORT DataString : public String, public DataPrimitive { Q_OBJECT protected: DataString(ObjectStore *store); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; /** Update the string */ virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; public: virtual ~DataString(); virtual void internalUpdate(); struct KSTCORE_EXPORT ReadInfo { ReadInfo(QString* s) : value(s) {} QString* value; }; struct KSTCORE_EXPORT DataInfo { }; void reload(); virtual void reset(); virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; /** change the properties of a DataString */ void change(DataSourcePtr file, const QString &field); void changeFile(DataSourcePtr file); /** Save scalar information */ virtual void save(QXmlStreamWriter &s); virtual QString descriptionTip() const; virtual QString propertyString() const; bool isValid() const; private: /** make a copy of the DataString */ virtual PrimitivePtr makeDuplicate() const; virtual bool checkValidity(const DataSourcePtr& ds) const; }; typedef SharedPtr DataStringPtr; typedef ObjectList DataStringList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/stringfactory.cpp000644 001750 001750 00000004635 11544160210 020354 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "stringfactory.h" #include "debug.h" #include "string_kst.h" #include "objectstore.h" namespace Kst { StringFactory::StringFactory() : PrimitiveFactory() { registerFactory(String::staticTypeTag, this); } StringFactory::~StringFactory() { } PrimitivePtr StringFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QByteArray data; Q_ASSERT(store); bool orphan, editable; QString value, descriptiveName; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == "string") { QXmlStreamAttributes attrs = xml.attributes(); value = attrs.value("value").toString(); orphan = attrs.value("orphan").toString() == "true" ? true : false; editable = attrs.value("editable").toString() == "true" ? true : false; if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == "string") { break; } else { Debug::self()->log(QObject::tr("Error creating string from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } StringPtr string = store->createObject(); string->setValue(value); string->setOrphan(true); string->setEditable(true); string->setDescriptiveName(descriptiveName); return string; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/generatedmatrix.cpp000644 001750 001750 00000006773 11544160210 020646 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "kst_i18n.h" #include "generatedmatrix.h" #include #include namespace Kst { const QString GeneratedMatrix::staticTypeString = I18N_NOOP("Generated Matrix"); const QString GeneratedMatrix::staticTypeTag = I18N_NOOP("generatedmatrix"); GeneratedMatrix::GeneratedMatrix(ObjectStore *store) : Matrix(store) { _saveable = true; _editable = true; _zSize = 0; change(1, 0, 0, 0, 1, 1, 0, 1, true); } const QString& GeneratedMatrix::typeString() const { return staticTypeString; } void GeneratedMatrix::save(QXmlStreamWriter &xml) { xml.writeStartElement(staticTypeTag); xml.writeAttribute("xmin", QString::number(minX())); xml.writeAttribute("ymin", QString::number(minY())); xml.writeAttribute("nx", QString::number(xNumSteps())); xml.writeAttribute("ny", QString::number(yNumSteps())); xml.writeAttribute("xstep", QString::number(xStepSize())); xml.writeAttribute("ystep", QString::number(yStepSize())); xml.writeAttribute("gradzmin", QString::number(_gradZMin)); xml.writeAttribute("gradzmax", QString::number(_gradZMax)); xml.writeAttribute("xdirection", QVariant(_xDirection).toString()); saveNameInfo(xml, VNUM|MNUM|XNUM); xml.writeEndElement(); } void GeneratedMatrix::change(uint nX, uint nY, double minX, double minY, double stepX, double stepY, double gradZMin, double gradZMax, bool xDirection) { // some checks on parameters if (nX < 1) { nX = 1; } if (nY < 1) { nY = 1; } if (stepX <= 0) { stepX = 0.1; } if (stepY <= 0) { stepY = 0.1; } _nX = nX; _nY = nY; _minX = minX; _minY = minY; _stepX = stepX; _stepY = stepY; _gradZMin = gradZMin; _gradZMax = gradZMax; _xDirection = xDirection; if (_nX*_nY != _zSize) { resizeZ(_nX*_nY, false); } // zIncrement can be negative, to reverse gradient direction double zIncrement; if (_xDirection) { if (_nX > 1) { zIncrement = (_gradZMax - _gradZMin) / (_nX - 1); } else { zIncrement = 0; } } else { if (_nY > 1) { zIncrement = (_gradZMax - _gradZMin) / (_nY - 1); } else { zIncrement = 0; } } // fill in the matrix with the gradient for (int i = 0; i < _nX; i++) { for (int j = 0; j < _nY; j++) { if (_xDirection) { _z[i*nY + j] = _gradZMin + i*zIncrement; } else { _z[i*nY + j] = _gradZMin + j*zIncrement; } } } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/libkst.pro000644 001750 001750 00000005021 11544160210 016752 0ustar00synthsynth000000 000000 TOPOUT_REL=../.. include($$PWD/$$TOPOUT_REL/kst.pri) TEMPLATE = lib CONFIG += dll DEFINES += BUILD_KSTCORE TARGET = $$kstlib(kst2lib) DESTDIR = $$OUTPUT_DIR/lib unix:QMAKE_LFLAGS_SHLIB *= -lrt macx:CONFIG += lib_bundle !isEmpty(INSTALL_PREFIX) { target.path = $$INSTALL_PREFIX/$$INSTALL_LIBDIR INSTALLS += target } INCLUDEPATH += tmp \ $$OUTPUT_DIR/src/libkst/tmp SOURCES += builtindatasources.cpp \ builtinprimitives.cpp \ coredocument.cpp \ datacollection.cpp \ datamatrix.cpp \ dataprimitive.cpp \ datasource.cpp \ datasourcefactory.cpp \ datasourcepluginfactory.cpp \ datasourcepluginmanager.cpp \ datavector.cpp \ datascalar.cpp \ datastring.cpp \ dateparser.cpp \ debug.cpp \ editablematrix.cpp \ editablevector.cpp \ extension.cpp \ generatedmatrix.cpp \ generatedvector.cpp \ labelinfo.cpp \ math_kst.cpp \ matrix.cpp \ matrixfactory.cpp \ measuretime.cpp \ namedobject.cpp \ nextcolor.cpp \ object.cpp \ objectlist.cpp \ objectmap.cpp \ objectstore.cpp \ plotiteminterface.cpp \ primitive.cpp \ primitivefactory.cpp \ rwlock.cpp \ scalar.cpp \ scalarfactory.cpp \ shortnameindex.cpp \ string_kst.cpp \ stringfactory.cpp \ updatemanager.cpp \ vector.cpp \ vectorfactory.cpp \ vscalar.cpp #!win32:SOURCES += stdinsource.cpp !macx:!win32:SOURCES += sysinfo.c \ psversion.c HEADERS += builtindatasources.h \ builtinprimitives.h \ coredocument.h \ datacollection.h \ datamatrix.h \ dataplugin.h \ dataprimitive.h \ datasource.h \ datasourcefactory.h \ datasourcepluginfactory.h \ datasourcepluginmanager.h \ datavector.h \ datascalar.h \ datastring.h \ dateparser.h \ debug.h \ editablematrix.h \ editablevector.h \ events.h \ extension.h \ generatedmatrix.h \ generatedvector.h \ kst_export.h \ kst_i18n.h \ ksttimers.h \ index_kst.h \ labelinfo.h \ logevents.h \ math_kst.h \ matrix.h \ matrixfactory.h \ measuretime.h \ namedobject.h \ object.h \ objectlist.h \ objectmap.h \ objectstore.h \ plotiteminterface.h \ primitive.h \ primitivefactory.h \ procps.h \ psversion.h \ rwlock.h \ scalar.h \ scalarfactory.h \ sharedptr.h \ # stdinsource.h \ string_kst.h \ stringfactory.h \ sysinfo.h \ timezones.h \ updatemanager.h \ vector.h \ vectorfactory.h \ vscalar.h kst-2.0.3/src/libkst/datacollection.cpp000644 001750 001750 00000004770 11544160210 020443 0ustar00synthsynth000000 000000 /*************************************************************************** datacollection.cpp ------------------- begin : June 12, 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include "datacollection.h" #include "sysinfo.h" #include "psversion.h" namespace Kst { static QMutex bigLock; void *realloc(void *ptr, size_t size) { #ifdef __linux__ QMutexLocker ml(&bigLock); meminfo(); unsigned long bFree = S(kb_main_free + kb_main_buffers + kb_main_cached); if (size > bFree) { const unsigned long sz = size; qDebug("Tried to allocate too much memory! (Wanted %lu, had %lu)", sz, bFree); return 0L; } #endif return ::realloc(ptr, size); } void *malloc(size_t size) { #ifdef __linux__ QMutexLocker ml(&bigLock); meminfo(); unsigned long bFree = S(kb_main_free + kb_main_buffers + kb_main_cached); if (size > bFree) { const unsigned long sz = size; qDebug("Tried to allocate too much memory! (Wanted %lu, had %lu)", sz, bFree); return 0L; } #endif return ::malloc(size); } Data *Data::_self = 0L; void Data::cleanup() { delete _self; _self = 0; } Data *Data::self() { Q_ASSERT(_self); return _self; } void Data::replaceSelf(Data *newInstance) { cleanup(); _self = newInstance; } Data::Data() { qAddPostRoutine(Data::cleanup); } Data::~Data() { } void Data::removeCurveFromPlots(Relation *c) { Q_UNUSED(c) // meaningless in no GUI: no plots! } QList Data::plotList() const { return QList(); } int Data::rows() const { return -1; } int Data::columns() const { return -1; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/coredocument.h000644 001750 001750 00000003361 11544160210 017605 0ustar00synthsynth000000 000000 /*************************************************************************** coredocument.h ------------------- begin : October 3, 2007 copyright : (C) 2007 by The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef COREDOCUMENT_H #define COREDOCUMENT_H #include #include #include "kst_export.h" namespace Kst { class ObjectStore; class KSTCORE_EXPORT CoreDocument { public: CoreDocument(); virtual ~CoreDocument(); virtual QString fileName() const; virtual ObjectStore *objectStore() const; virtual bool open(const QString& file); virtual bool save(const QString& to = QString()); virtual bool isChanged() const; virtual void setChanged(bool changed); virtual bool isOpen() const; virtual QString lastError() const; private: ObjectStore *_objectStore; bool _dirty; bool _isOpen; QString _fileName; QString _lastError; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/psversion.c000644 001750 001750 00000002461 11544160210 017141 0ustar00synthsynth000000 000000 /* Suite version information for procps utilities * Copyright (c) 1995 Martin Schulze * Ammended by cblake to only export the function symbol. * * Modified by Albert Cahalan, 2003 * * Redistributable under the terms of the * GNU Library General Public License; see COPYING */ #include #include #include #include "psversion.h" const char procps_version[] = "procps copy"; void display_version(void) { fprintf(stdout, "%s\n", procps_version); } /* Linux kernel version information for procps utilities * Copyright (c) 1996 Charles Blake */ #include #define LINUX_VERSION(x,y,z) (0x10000*(x) + 0x100*(y) + z) int linux_version_code; static void init_Linux_version(void) __attribute__((constructor)); static void init_Linux_version(void) { static struct utsname uts; int x = 0, y = 0, z = 0; /* cleared in case sscanf() < 3 */ if (uname(&uts) == -1) /* failure implies impending death */ exit(1); if (sscanf(uts.release, "%d.%d.%d", &x, &y, &z) < 3) fprintf(stderr, /* *very* unlikely to happen by accident */ "Non-standard uts for running kernel:\n" "release %s=%d.%d.%d gives version code %d\n", uts.release, x, y, z, LINUX_VERSION(x,y,z)); linux_version_code = LINUX_VERSION(x, y, z); } kst-2.0.3/src/libkst/stringfactory.h000644 001750 001750 00000002215 11544160210 020011 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STRINGFACTORY_H #define STRINGFACTORY_H #include "primitivefactory.h" namespace Kst { class StringFactory : public PrimitiveFactory { public: StringFactory(); ~StringFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/scalar.h000644 001750 001750 00000005554 11544160210 016371 0ustar00synthsynth000000 000000 /*************************************************************************** kstscalar.h - the base scalar type ------------------- begin : March 24, 2003 copyright : (C) 2003 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SCALAR_H #define SCALAR_H #include "primitive.h" class QXmlStreamWriter; namespace Kst { /** The base class for all scalars. */ class KSTCORE_EXPORT Scalar : public Primitive { Q_OBJECT Q_PROPERTY(bool orphan READ orphan WRITE setOrphan) Q_PROPERTY(double value READ value WRITE setValue) Q_PROPERTY(bool displayable READ displayable WRITE setDisplayable) protected: Scalar(ObjectStore *store); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); public: virtual ~Scalar(); /** Update the scalar.*/ virtual void internalUpdate(); virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; /* return a string representation of the scalar */ QString label() const; /** Save scalar information */ virtual void save(QXmlStreamWriter &s); Scalar& operator=(double v); virtual QString descriptionTip() const; virtual QString propertyString() const; virtual QString sizeString() const; virtual ObjectList outputPrimitives() const { return ObjectList(); } virtual PrimitiveMap metas() const { return PrimitiveMap(); } public slots: double value() const; /** Set the value of the scalar - ignored for some types */ void setValue(double inV); bool orphan() const; void setOrphan(bool orphan); bool displayable() const; void setDisplayable(bool displayable); bool editable() const; void setEditable(bool editable); protected: double _value; private: bool _orphan; bool _displayable; bool _editable; }; typedef SharedPtr ScalarPtr; typedef ObjectList ScalarList; typedef ObjectMap ScalarMap; } Q_DECLARE_METATYPE(Kst::Scalar*) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/string_kst.h000644 001750 001750 00000005360 11544160210 017306 0ustar00synthsynth000000 000000 /*************************************************************************** string.h - the base string type ------------------- begin : Sept 29, 2004 copyright : (C) 2004 by The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STRING_H #define STRING_H #include "primitive.h" class QXmlStreamWriter; namespace Kst { class KSTCORE_EXPORT String : public Primitive { Q_OBJECT Q_PROPERTY(bool orphan READ orphan WRITE setOrphan) public: virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; virtual QString descriptionTip() const; virtual QString sizeString() const; virtual QString propertyString() const; protected: String(ObjectStore *store); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _initializeShortName(); public: /** Update the string. */ virtual void internalUpdate(); virtual ~String(); /** Save information */ void save(QXmlStreamWriter &s); String& operator=(const QString& v); String& operator=(const char *v); virtual ObjectList outputPrimitives() const { return ObjectList(); } virtual PrimitiveMap metas() const { return PrimitiveMap(); } public slots: /* return the value of the string */ const QString& value() const { return _value; } /** Set the value of the string - ignored for some types */ void setValue(const QString& inV); bool orphan() const { return _orphan; } void setOrphan(bool orphan) { _orphan = orphan; } bool editable() const { return _editable; } void setEditable(bool editable) { _editable = editable; } protected: QString _value; private: bool _orphan : 1; bool _editable; }; typedef SharedPtr StringPtr; typedef ObjectList StringList; typedef ObjectMap StringMap; } Q_DECLARE_METATYPE(Kst::String*) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/vector.h000644 001750 001750 00000014332 11544160210 016420 0ustar00synthsynth000000 000000 /*************************************************************************** vector.h - description ------------------- begin : Fri Sep 22 2000 copyright : (C) 2000 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VECTOR_H #define VECTOR_H #include #include #include "primitive.h" #include "scalar.h" #include "string_kst.h" #include "labelinfo.h" #include "kst_export.h" class QXmlStreamWriter; namespace Equation { class Node; } namespace Kst { class KstDataObject; // KST::interpolate is still too polluting KSTCORE_EXPORT double kstInterpolate(double *v, int _size, int in_i, int ns_i); KSTCORE_EXPORT double kstInterpolateNoHoles(double *v, int _size, int in_i, int ns_i); class Vector; typedef SharedPtr VectorPtr; /**A class for handling data vectors for kst. *@author cbn */ class KSTCORE_EXPORT Vector : public Primitive { Q_OBJECT public: virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; protected: Vector(ObjectStore *store); virtual ~Vector(); friend class ObjectStore; virtual void _initializeShortName(); public: void change(QByteArray& data); inline int length() const { return _size; } /** Return V[i], interpolated/decimated to have ns_i total samples */ double interpolate(int i, int ns_i) const; /** Return V[i], interpolated/decimated to have ns_i total samples, without any holes */ double interpolateNoHoles(int i, int ns_i) const; /** Return V[i] uninterpolated */ double value(int i) const; /** Return Minimum value in Vector */ inline double min() const { return _min; } /** Return max value in Vector */ inline double max() const { return _max; } /** Return SpikeInsensitive max value in vector **/ inline double ns_max() const { return _ns_max; } /** Return SpikeInsensitive min value in vector **/ inline double ns_min() const { return _ns_min; } /** Return Mean value in Vector */ inline double mean() const { return _mean; } /** Return Least Positive value in Vector */ inline double minPos() const { return _minPos; } /** Number of new samples in the vector since last newSync */ inline int numNew() const { return NumNew; } /** Number of samples shifted since last newSync */ inline int numShift() const { return NumShifted; } inline bool isRising() const { return _is_rising; } /** reset New Samples and Shifted samples */ void newSync(); virtual bool resize(int sz, bool init = true); virtual void setNewAndShift(int inNew, int inShift); /** Clear out the vector by setting everything to 0.0 */ void zero(); /** Make the vector truly empty. All values set to NOPOINT (NaN). */ void blank(); /* Generally you don't need to call this */ void updateScalars(); /** return information for building a label for this vector */ virtual LabelInfo labelInfo() const; virtual LabelInfo titleInfo() const; virtual void setLabelInfo(const LabelInfo &label_info); virtual void setTitleInfo(const LabelInfo &label_info); virtual int getUsage() const; /** Save vector information */ virtual void save(QXmlStreamWriter &s); /** Return a pointer to the raw vector */ double *value() const; /** access functions for _isScalarList */ bool isScalarList() const { return _isScalarList; } bool saveable() const; bool editable() const; void setEditable(bool editable); bool saveData() const; virtual void setSaveData(bool save); virtual QString descriptionTip() const; virtual QString sizeString() const; virtual void internalUpdate(); // output primitives: statistics scalars, etc. ScalarMap scalars() const {return _scalars;} StringMap strings() const {return _strings;} virtual PrimitiveMap metas() const; virtual ObjectList outputPrimitives() const; virtual QString propertyString() const; protected: /** current number of samples */ int _size; /** number of valid points */ int _nsum; /** variables for SpikeInsensitiveAutoscale **/ double _ns_max; double _ns_min; /** Where the vector is held */ double *_v; /** number of samples shifted since last newSync */ int NumShifted; /** number of new samples since last newSync */ int NumNew; /** is the vector monotonically rising */ bool _is_rising : 1; /** if true then we have a scalar list and do not want to be able to use it in a curve, display statistics for it, etc. */ bool _isScalarList : 1; /** The user should not be permitted to edit the contents of the vector if this is false. */ bool _editable : 1; /** can/should the vector be saved */ bool _saveable : 1; /** should the vector data be saved? */ bool _saveData : 1; double _min, _max, _mean, _minPos; /** Scalar Maintenance methods */ void CreateScalars(ObjectStore *store); virtual void deleteDependents(); LabelInfo _labelInfo; LabelInfo _titleInfo; friend class DataObject; friend class Matrix; virtual double* realloced(double *memptr, int newSize); virtual void setV(double *memptr, int newSize); ObjectMap _scalars; ObjectMap _strings; }; typedef ObjectList VectorList; typedef ObjectMap VectorMap; } Q_DECLARE_METATYPE(Kst::Vector*) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/matrixfactory.cpp000644 001750 001750 00000017361 11544160210 020352 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "matrixfactory.h" #include "debug.h" #include "matrix.h" #include "generatedmatrix.h" #include "editablematrix.h" #include "datamatrix.h" #include "objectstore.h" #include "datasourcepluginmanager.h" namespace Kst { GeneratedMatrixFactory::GeneratedMatrixFactory() : PrimitiveFactory() { registerFactory(GeneratedMatrix::staticTypeTag, this); } GeneratedMatrixFactory::~GeneratedMatrixFactory() { } PrimitivePtr GeneratedMatrixFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QByteArray data; QString descriptiveName; Q_ASSERT(store); bool xDirection=1; double gradZMin=-1, gradZMax=1, minX=0, minY=0, nX=10, nY=10, stepX=1, stepY=1; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == GeneratedMatrix::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); gradZMin = attrs.value("gradzmin").toString().toDouble(); gradZMax = attrs.value("gradzmax").toString().toDouble(); minX = attrs.value("xmin").toString().toDouble(); minY = attrs.value("ymin").toString().toDouble(); nX = attrs.value("nx").toString().toDouble(); nY = attrs.value("ny").toString().toDouble(); stepX = attrs.value("xstep").toString().toDouble(); stepY = attrs.value("ystep").toString().toDouble(); xDirection = attrs.value("xdirection").toString() == "true" ? true : false; if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == GeneratedMatrix::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating Generated Matrix from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } GeneratedMatrixPtr matrix = store->createObject(); matrix->change(uint(nX), uint(nY), minX, minY, stepX, stepY, gradZMin, gradZMax, xDirection); matrix->setDescriptiveName(descriptiveName); matrix->writeLock(); matrix->registerChange(); matrix->unlock(); return matrix; } EditableMatrixFactory::EditableMatrixFactory() : PrimitiveFactory() { registerFactory(EditableMatrix::staticTypeTag, this); } EditableMatrixFactory::~EditableMatrixFactory() { } PrimitivePtr EditableMatrixFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QByteArray data; QString descriptiveName; Q_ASSERT(store); double minX=0, minY=0, nX=10, nY=10, stepX=1, stepY=1; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == EditableMatrix::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); minX = attrs.value("xmin").toString().toDouble(); minY = attrs.value("ymin").toString().toDouble(); nX = attrs.value("nx").toString().toDouble(); nY = attrs.value("ny").toString().toDouble(); stepX = attrs.value("xstep").toString().toDouble(); stepY = attrs.value("ystep").toString().toDouble(); if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else if (n == "data") { QString qcs(xml.readElementText().toLatin1()); QByteArray qbca = QByteArray::fromBase64(qcs.toLatin1()); data = qUncompress(qbca); } else { return 0; } } else if (xml.isEndElement()) { if (n == EditableMatrix::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating Editable Matrix from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } EditableMatrixPtr matrix = store->createObject(); matrix->change(data, uint(nX), uint(nY), minX, minY, stepX, stepY); matrix->setDescriptiveName(descriptiveName); matrix->writeLock(); matrix->registerChange(); matrix->unlock(); return matrix; } DataMatrixFactory::DataMatrixFactory() : PrimitiveFactory() { registerFactory(DataMatrix::staticTypeTag, this); } DataMatrixFactory::~DataMatrixFactory() { } PrimitivePtr DataMatrixFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QByteArray data; QString descriptiveName; Q_ASSERT(store); bool doAve=false, doSkip=false; int requestedXStart=0, requestedYStart=0, requestedXCount=-1, requestedYCount=-1, skip=0; double minX=0, minY=0, stepX=1, stepY=1; QString provider, file, field; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == DataMatrix::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); provider = attrs.value("provider").toString(); file = DataPrimitive::readFilename(attrs); field = attrs.value("field").toString(); requestedXStart = attrs.value("reqxstart").toString().toInt(); requestedYStart = attrs.value("reqystart").toString().toInt(); requestedXCount = attrs.value("reqnx").toString().toInt(); requestedYCount = attrs.value("reqny").toString().toInt(); doAve = attrs.value("doave").toString() == "true" ? true : false; doSkip = attrs.value("doskip").toString() == "true" ? true : false; skip = attrs.value("skip").toString().toInt(); minX = attrs.value("xmin").toString().toDouble(); minY = attrs.value("ymin").toString().toDouble(); stepX = attrs.value("xstep").toString().toDouble(); stepY = attrs.value("ystep").toString().toDouble(); if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == DataMatrix::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating Data Matrix from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } Q_ASSERT(store); DataSourcePtr dataSource = DataSourcePluginManager::findOrLoadSource(store, file); if (!dataSource) { return 0; //Couldn't find a suitable datasource } DataMatrixPtr matrix = store->createObject(); matrix->change(dataSource, field, requestedXStart, requestedYStart, requestedXCount, requestedYCount, doAve, doSkip, skip, minX, minY, stepX, stepY); matrix->setDescriptiveName(descriptiveName); matrix->writeLock(); matrix->registerChange(); matrix->unlock(); return matrix; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/vscalar.h000644 001750 001750 00000005632 11544160210 016554 0ustar00synthsynth000000 000000 /*************************************************************************** vscalar.h - a scalar from a sample of a vector field ------------------- begin : September, 2008 copyright : (C) 2008 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VSCALAR_H #define VSCALAR_H #include "scalar.h" #include "datasource.h" #include "kst_export.h" class QXmlStreamWriter; namespace Kst { /**A class for handling vector scalars for kst. *@author cbn */ /** A scalar which gets its value from a vector field in a data file. */ class KSTCORE_EXPORT VScalar : public Scalar { Q_OBJECT protected: VScalar(ObjectStore *store); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; public: virtual ~VScalar(); /** Update the scalar. */ virtual void internalUpdate(); virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; /** change the properties of a VScalar */ void change(DataSourcePtr file, const QString &field, int f0); void changeFile(DataSourcePtr file); /** return the name of the file */ QString filename() const; /** return the field name */ const QString& field() const; /** return sample number */ int F0() const; /** Save scalar information */ virtual void save(QXmlStreamWriter &s); /** the data source */ DataSourcePtr dataSource() const; virtual QString descriptionTip() const; /** return true if it has a valid file and field, or false otherwise */ bool isValid() const; virtual QString propertyString() const; private: /** file to read for rvectors */ DataSourcePtr _file; /** For the scalar field in the data source */ QString _field; int _f0; /** make a copy of the VScalar */ virtual PrimitivePtr _makeDuplicate() const; virtual bool _checkValidity(const DataSourcePtr ds) const; }; typedef SharedPtr VScalarPtr; typedef ObjectList VScalarList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/timezones.h000644 001750 001750 00000023144 11544160210 017134 0ustar00synthsynth000000 000000 /* This file is part of the KDE libraries Copyright (c) 2005 S.R.Haque . This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _TIMEZONES_H #define _TIMEZONES_H #include #include #include #include #include "sharedptr.h" #include namespace Kst { class TimezoneDetails; class TimezoneDetailsPrivate; class TimezonePrivate; class TimezonesPrivate; /** * The KTimezoneSource class contains information source-dependent functions * related to a timezone. Create subclasses to implement custom sources of * timezone information. * * For example, to be able to create {@link KTimezone } objects from libical's * VTIMEZONE objects: *
      *
    • Subclass this class with a custom {@link parse() } routine. *
    • Create one or more instances of this class. *
    • Use the instance(s) to create {@link KTimezone } objects. *
    • If required, add the objects to a {@link KTimezones } database. *
    * @since 3.5 * @author S.R.Haque . */ class KSTCORE_EXPORT TimezoneSource : public Shared { public: TimezoneSource(const QString &db); virtual ~TimezoneSource(); /** * Location of system timezone information. * @return value which can be combined with zone name to retrieve timezone info. */ virtual QString db(); /** * Extract timezone detail information. The default implementation consists * of a parser for zoneinfo files in tzfile(5). * @return true if the parse encountered no errors. */ virtual bool parse(const QString &zone, TimezoneDetails &dataReceiver) const; private: QString m_db; }; /** * The Timezone class contains core functions related to a timezone. Instances * are created in the context of a {@link TimezoneSource } which provides * extended functionality via {@link TimezoneDetails }. * * @see TimezoneSource * @see TimezoneDetails * @since 3.5 * @author S.R.Haque . */ class KSTCORE_EXPORT Timezone { public: /** * A representation for unknown locations; this is a float * that does not represent a real latitude or longitude. */ static const float UNKNOWN; /** * A test for a valid latitude. The valid range is +90.0 (North Pole) * to -90.0 (South Pole). */ static bool isValidLatitude(float latitude); /** * A test for a valid longitude. The valid range is +180.0 (east of * Greenwich) to -180.0 (west of Greenwich). */ static bool isValidLongitude(float longitude); /** * Create a timezone. * * @param db database of timezones. * @param name in system-dependent format. * @param countryCode ISO 3166 2-character country code, empty if unknown. * @param latitude in degrees, UNKNOWN if not known. * @param longitude in degrees, UNKNOWN if not known. * @param comment description of the timezone, if any. */ Timezone( SharedPtr db, const QString &name, const QString &countryCode = QString(), float latitude = UNKNOWN, float longitude = UNKNOWN, const QString &comment = QString()); ~Timezone(); /** * Returns the name of the timezone. * * @return name in system-dependent format. */ QString name() const; /** * Returns the two-letter country code of the timezone. * * @return ISO 3166 2-character country code, empty if unknown. */ QString countryCode() const; /** * Returns the latitude of the timezone. * * @return latitude in degrees, UNKNOWN if not known. */ float latitude() const; /** * Returns the latitude of the timezone. * * @return latitude in degrees, UNKNOWN if not known. */ float longitude() const; /** * Returns the current offset of this timezone to UTC or the local * timezone in seconds. * * Take care if you cache the results of this routine; that would * break if the result were stored across a daylight savings change. * * @return offset in seconds. */ int offset(Qt::TimeSpec basisSpec = Qt::UTC) const; /** * Returns the offset of the given timezone to UTC at the given * date/time (which is interpreted as being UTC). * * @return offset in seconds. */ int offset(const QDateTime &dateTime) const; /** * Convert a date/time (which is interpreted as being localtime in this * timezone) into localtime in the given timezone. * * @return converted date/time. */ QDateTime convert(const Timezone *newZone, const QDateTime &dateTime) const; /** * Returns any comment for the timezone. * * @return comment, may be empty. */ QString comment() const; /** * Extract timezone detail information. * @return true if the parse encountered no errors. */ bool parse(TimezoneDetails &dataReceiver) const; private: SharedPtr m_db; QString m_name; QString m_countryCode; float m_latitude; float m_longitude; QString m_comment; TimezonePrivate *d; }; /** * The TimezoneDetails class contains extended functions related to a * timezone. * * The parser must be customised by overriding the given virtual callbacks: *
      *
    • {@link parseEnded() } *
    • {@link parseStarted() } *
    • {@link gotHeader() } *
    • {@link gotTransitionTime() } *
    • {@link gotLocalTimeIndex() } *
    • {@link gotLocalTime() } *
    • {@link gotAbbreviation() } *
    • {@link gotLeapAdjustment() } *
    • {@link gotIsStandard() } *
    • {@link gotIsUTC() } *
    * * @see Timezone * @since 3.5 * @author S.R.Haque . */ class KSTCORE_EXPORT TimezoneDetails { public: TimezoneDetails(); virtual ~TimezoneDetails(); /** * Always called after all other callbacks. */ virtual void parseEnded(); /** * Always called before any other callback. */ virtual void parseStarted(); /** * Called when the header is seen. */ virtual void gotHeader( unsigned ttIsGmtCnt, unsigned ttIsStdCnt, unsigned leapCnt, unsigned timeCnt, unsigned typeCnt, unsigned charCnt); /** * Called when a transition time is seen. */ virtual void gotTransitionTime(int index, unsigned transitionTime); /** * Called when a local time index is seen. */ virtual void gotLocalTimeIndex(int index, unsigned localTimeIndex); /** * Called when a local time is seen. */ virtual void gotLocalTime(int index, int gmtOff, bool isDst, unsigned abbrIndex); /** * Called when a timezone abbreviation is seen. Note that the index here * is NOT a simple incrementing integer, rather it matches the sequence * of abbrIndex values from {@link gotLocalTime() }. */ virtual void gotAbbreviation(int index, const QString &abbr); /** * Called when a leap second adjustment is seen. */ virtual void gotLeapAdjustment(int index, unsigned leapTime, unsigned leapSeconds); /** * Called when a standard/wall time indicator is seen. */ virtual void gotIsStandard(int index, bool isStandard); /** * Called when a UTC/local time indicator is seen. */ virtual void gotIsUTC(int index, bool isUTC); private: TimezoneDetailsPrivate *d; }; /** * The Timezones class models a timezone database. It supports system * timezones, and also has support for private timezone entries. * * @since 3.5 * @author S.R.Haque . */ class KSTCORE_EXPORT Timezones { public: Timezones(); ~Timezones(); /** * Returns the local timezone. The idea of this routine is to provide a * robust lookup of the local timezone. * * The problem is that on Unix systems, there are a variety of mechanisms * for setting this information, and no real way of getting it. For example, * if you set your timezone to "Europe/London", then the tzname[] * maintained by tzset() typically returns { "GMT", "BST" }. The point of * this routine is to actually return "Europe/London" (or rather, the * corresponding Timezone). * * @return local timezone. If necessary, we will use a series of heuristics * which end by returning UTC. We will never return NULL. */ const Timezone *local(); /** * Returns the given timezone. * * @param name Name of timezone. Empty is equivalent to UTC. * @return named timezone, NULL on error. */ const Timezone *zone(const QString &name); typedef QMap ZoneMap; /** * Return timezone database. * @return known timezones. */ const ZoneMap allZones(); /** * Add user-defined timezone to database. */ void add(Timezone *zone); private: float convertCoordinate(const QString &coordinate); QString m_zoneinfoDir; ZoneMap *m_zones; Timezone *m_UTC; TimezonesPrivate *d; }; } #endif kst-2.0.3/src/libkst/objectmap.cpp000644 001750 001750 00000001576 11544160210 017423 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "objectmap.h" // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/builtindatasources.h000644 001750 001750 00000002061 11544160210 021016 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUILTINDATASOURCES_H #define BUILTINDATASOURCES_H #include "kst_export.h" namespace Kst { class ObjectStore; namespace Builtins { KSTCORE_EXPORT void initDataSources(); } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/namedobject.h000644 001750 001750 00000011123 11544160210 017364 0ustar00synthsynth000000 000000 /*************************************************************************** namedobject.h: adds naming features to objects... ------------------- begin : May 29, 2008 copyright : (C) 2008 C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // name system: see object names devel doc for intended behavior #ifndef NAMEDOBJECT_H #define NAMEDOBJECT_H #include #include #include "kst_export.h" namespace Kst { // short name index variables KSTCORE_EXPORT extern int _vnum; // vectors KSTCORE_EXPORT extern int _pnum; // plugins KSTCORE_EXPORT extern int _csdnum; // csd KSTCORE_EXPORT extern int _cnum; // curves KSTCORE_EXPORT extern int _enum; // equations KSTCORE_EXPORT extern int _hnum; // histograms KSTCORE_EXPORT extern int _inum; // images KSTCORE_EXPORT extern int _psdnum; // psd KSTCORE_EXPORT extern int _xnum; // scalars KSTCORE_EXPORT extern int _tnum; // text string KSTCORE_EXPORT extern int _mnum; // matrix KSTCORE_EXPORT extern int _plotnum; // plot item KSTCORE_EXPORT extern int _lnum; // legend KSTCORE_EXPORT extern int _dnum; // view item (drawable) KSTCORE_EXPORT extern int _dsnum; // datasource KSTCORE_EXPORT extern int max_vnum; // vectors KSTCORE_EXPORT extern int max_pnum; // plugins KSTCORE_EXPORT extern int max_csdnum; // csd KSTCORE_EXPORT extern int max_cnum; // curves KSTCORE_EXPORT extern int max_enum; // equations KSTCORE_EXPORT extern int max_hnum; // histograms KSTCORE_EXPORT extern int max_inum; // images KSTCORE_EXPORT extern int max_psdnum; // psd KSTCORE_EXPORT extern int max_xnum; // scalars KSTCORE_EXPORT extern int max_tnum; // string KSTCORE_EXPORT extern int max_mnum; // matrix KSTCORE_EXPORT extern int max_plotnum; // plot item KSTCORE_EXPORT extern int max_lnum; // legend KSTCORE_EXPORT extern int max_dnum; // view item KSTCORE_EXPORT extern int max_dsnum; // datasource class KSTCORE_EXPORT NamedObject { public: NamedObject(); virtual ~NamedObject(); enum ShortNameIndex { VNUM = 0x0001, PNUM = 0x0002, CSDNUM = 0x0004, CNUM = 0x0008, ENUM = 0x0010, HNUM = 0x0020, INUM = 0x0040, PSDNUM = 0x0080, XNUM = 0x0100, TNUM = 0x0200, MNUM = 0x0400, PLOTNUM= 0x0800, LNUM = 0x1000, DNUM = 0x2000, DSNUM = 0x4000 }; // name system: see object names devel doc QString Name() const; // eg GYRO1 (V1) QString CleanedName() const; // all \_ replaced with _ QString descriptiveName() const; // eg GYRO1: automatic or manual QString shortName() const; // eg V1: always automatically generated virtual QString descriptionTip() const = 0; // description for tooltips void setDescriptiveName(QString new_name); // auto if new_name.isEmpty() bool descriptiveNameIsManual() const; static void processShortNameIndexAttributes(QXmlStreamAttributes &attrs); // Reset all name indexes. Should only be used by ObjectStore when clearing the store entirely. static void resetNameIndex(); protected: virtual QString _automaticDescriptiveName() const= 0; virtual void _initializeShortName() = 0; QString _manualDescriptiveName; QString _shortName; virtual void saveNameInfo(QXmlStreamWriter &s, unsigned I = 0xffff); // object indices used for saving/resorting shortnames int _initial_vnum; // vectors int _initial_pnum; // plugins int _initial_csdnum; // csd int _initial_cnum; // curves int _initial_enum; // equations int _initial_hnum; // histograms int _initial_inum; // images int _initial_psdnum; // psd int _initial_xnum; // scalars int _initial_tnum; // text string int _initial_mnum; // matrix int _initial_plotnum; // plot item int _initial_lnum; // legend int _initial_dnum; // view item int _initial_dsnum; // datasource }; } #endif kst-2.0.3/src/libkst/datacollection.h000644 001750 001750 00000004103 11544160210 020076 0ustar00synthsynth000000 000000 /*************************************************************************** datacollection.h ------------------- begin : June 12, 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATACOLLECTION_H #define DATACOLLECTION_H #include "datasource.h" #include "string_kst.h" #include "vector.h" #include "matrix.h" #include "kst_export.h" class QFile; namespace Kst { class Relation; class PlotItemInterface; class KSTCORE_EXPORT Data { protected: static Data *_self; static void cleanup(); Data(); virtual ~Data(); public: static Data *self(); static void replaceSelf(Data *newInstance); virtual void removeCurveFromPlots(Relation *c); // no sharedptr here /** The list of plots for the current view. */ virtual QList plotList() const; /** Returns the number of rows in the current view's layout. * -1 if not in layout. */ virtual int rows() const; /** Returns the number of columns in the given view's layout. * -1 if not in layout. */ virtual int columns() const; }; /** Bad choice for location - maybe move it later */ KSTCORE_EXPORT void *malloc(size_t size); KSTCORE_EXPORT void *realloc(void *ptr, size_t size); } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/primitivefactory.cpp000644 001750 001750 00000003747 11544160210 021061 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "primitivefactory.h" #include #include namespace Kst { static QMap *primitive_factories = 0; void cleanupPrimitives() { foreach (PrimitiveFactory *f, *primitive_factories) { delete f; } delete primitive_factories; primitive_factories = 0; } PrimitiveFactory::PrimitiveFactory() { } PrimitiveFactory::~PrimitiveFactory() { } void PrimitiveFactory::registerFactory(const QString& node, PrimitiveFactory *factory) { if (!primitive_factories) { primitive_factories = new QMap; qAddPostRoutine(cleanupPrimitives); } primitive_factories->insert(node, factory); } void PrimitiveFactory::registerFactory(const QStringList& nodes, PrimitiveFactory *factory) { foreach (const QString n, nodes) { registerFactory(n, factory); } } PrimitivePtr PrimitiveFactory::parse(ObjectStore *store, QXmlStreamReader& stream) { if (!primitive_factories) { return 0; } PrimitiveFactory *f = primitive_factories->value(stream.name().toString()); if (!f) { return 0; } return f->generatePrimitive(store, stream); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/matrixfactory.h000644 001750 001750 00000003101 11544160210 020002 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MATRIXFACTORY_H #define MATRIXFACTORY_H #include "primitivefactory.h" namespace Kst { class GeneratedMatrixFactory : public PrimitiveFactory { public: GeneratedMatrixFactory(); ~GeneratedMatrixFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; class EditableMatrixFactory : public PrimitiveFactory { public: EditableMatrixFactory(); ~EditableMatrixFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; class DataMatrixFactory : public PrimitiveFactory { public: DataMatrixFactory(); ~DataMatrixFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/editablevector.h000644 001750 001750 00000003357 11544160210 020117 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EDITABLEVECTOR_H #define EDITABLEVECTOR_H #include "vector.h" #include "kst_export.h" /**A vector with n editable pts *@author cbn */ namespace Kst { class EditableVector : public Vector { Q_OBJECT public: virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; void save(QXmlStreamWriter &s); void setSaveData(bool save); virtual QString descriptionTip() const; protected: KSTCORE_EXPORT EditableVector(ObjectStore *store); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; }; typedef SharedPtr EditableVectorPtr; typedef ObjectList EditableVectorList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/matrix.cpp000644 001750 001750 00000037763 11544160210 016772 0ustar00synthsynth000000 000000 /*************************************************************************** matrix.cpp: 2D matrix type for kst ------------------- begin : July 2004 ***************************************************************************/ /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * netterfield@astro.utoronto.ca * copyright : (C) 2004 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "matrix.h" //#include //#include #include "debug.h" #include "kst_i18n.h" #include "math_kst.h" #include "datacollection.h" #include "objectstore.h" // used for resizing; set to 1 for loop zeroing, 2 to use memset #define ZERO_MEMORY 2 namespace Kst { const QString Matrix::staticTypeString = I18N_NOOP("Matrix"); Matrix::Matrix(ObjectStore *store) : Primitive(store, 0L), _NS(0), _NRealS(0), _nX(1), _nY(0), _minX(0), _minY(0), _stepX(1), _stepY(1), _invertXHint(false), _invertYHint(false), _editable(false), _saveable(false), _z(0L), _zSize(0) { _initializeShortName(); _scalars.clear(); _strings.clear(); _vectors.clear(); createScalars(store); } Matrix::~Matrix() { if (_z) { _vectors["z"]->setV(0L, 0); free(_z); _z = 0L; } } void Matrix::_initializeShortName() { _shortName = 'M'+QString::number(_mnum); if (_mnum>max_mnum) max_mnum = _mnum; _mnum++; } void Matrix::deleteDependents() { for (QHash::Iterator it = _scalars.begin(); it != _scalars.end(); ++it) { _store->removeObject(it.value()); } for (QHash::Iterator it = _vectors.begin(); it != _vectors.end(); ++it) { _store->removeObject(it.value()); } Object::deleteDependents(); } const QString& Matrix::typeString() const { return staticTypeString; } int Matrix::sampleCount() const { return _nX*_nY; } double Matrix::value(double x, double y, bool* ok) const { int x_index = (int)((x - _minX) / (double)_stepX); int y_index = (int)((y - _minY) / (double)_stepY); int index = zIndex(x_index, y_index); if ((index < 0) || !finite(_z[index]) || KST_ISNAN(_z[index])) { if (ok) (*ok) = false; return 0.0; } if (ok) (*ok) = true; return _z[index]; } double Matrix::valueRaw(int x, int y, bool* ok) const { int index = zIndex(x,y); if ((index < 0) || !finite(_z[index]) || KST_ISNAN(_z[index])) { if (ok) { (*ok) = false; } return 0.0; } if (ok) { (*ok) = true; } return _z[index]; } int Matrix::zIndex(int x, int y) const { if (x >= _nX || x < 0 || y >= _nY || y < 0) { return -1; } int index = x * _nY + y; if (index >= _zSize || index < 0 ) { return -1; } return index; } bool Matrix::setValue(double x, double y, double z) { int x_index = (int)floor((x - _minX) / (double)_stepX); int y_index = (int)floor((y - _minY) / (double)_stepY); return setValueRaw(x_index, y_index, z); } bool Matrix::setValueRaw(int x, int y, double z) { int index = zIndex(x,y); if (index < 0) { return false; } _z[index] = z; return true; } double Matrix::minValue() const { return _scalars["min"]->value(); } double Matrix::maxValue() const { return _scalars["max"]->value(); } double Matrix::minValueNoSpike() const { // FIXME: it is expensive to calcNoSpikeRange // so we have chosen here to only call it expicitly // and no attempt is made to check if it is still up to date... // It would be better to have these calls call // calcNoSpikeRange iff the values were obsolete. return _minNoSpike; } double Matrix::maxValueNoSpike() const { // FIXME: it is expensive to calcNoSpikeRange // so we have chosen here to only call it expicitly // and no attempt is made to check if it is still up to date... // It would be better to have these calls call // calcNoSpikeRange iff the values were obsolete. return _maxNoSpike; } void Matrix::calcNoSpikeRange(double per) { double *min_list, *max_list, min_of_max, max_of_min; int n_list; int max_n = 50000; // the most samples we will look at... double n_skip; double x=0; int n_notnan; int i,j, k; // count number of points which aren't nans. for (i=n_notnan=0; i<_NS; i++) { if (!KST_ISNAN(_z[i])) { n_notnan++; } } if (n_notnan==0) { _minNoSpike = 0; _maxNoSpike = 0; return; } if (per < 0) { per = 0; } per *= (double)n_notnan/(double)_NS; max_n *= int((double)_NS/(double)n_notnan); n_skip = (double)_NS/max_n; if (n_skip<1.0) n_skip = 1.0; n_list = int(double(_NS)*per/n_skip); min_list = (double *)malloc(n_list * sizeof(double)); max_list = (double *)malloc(n_list * sizeof(double)); // prefill the list for (i=0; i max_of_min) { max_of_min = min_list[k]; } } } if (_z[j] > min_of_max) { // member for the max list //printf("******** z: %g min_of_max: %g\n", _z[j], min_of_max); // replace min of max with the new value for (k=0; kvalue(); } double Matrix::minValuePositive() const { return _scalars["minpos"]->value(); } int Matrix::numNew() const { return _numNew; } void Matrix::resetNumNew() { _numNew = 0; } void Matrix::zero() { for (int i = 0; i < _zSize; i++) { _z[i] = 0.0; } updateScalars(); } void Matrix::blank() { for (int i = 0; i < _zSize; ++i) { _z[i] = NOPOINT; } updateScalars(); } int Matrix::getUsage() const { int scalarUsage = 0; for (QHash::ConstIterator it = _scalars.begin(); it != _scalars.end(); ++it) { scalarUsage += it.value()->getUsage() - 1; } return Object::getUsage() + scalarUsage; } void Matrix::internalUpdate() { // calculate stats _NS = _nX * _nY; if (_zSize > 0) { double min = NAN; double max = NAN; double minpos = NAN; double sum = 0.0, sumsquared = 0.0; bool initialized = false; _NRealS = 0; for (int i = 0; i < _zSize; i++) { if (finite(_z[i]) && !KST_ISNAN(_z[i])) { if (!initialized) { min = _z[i]; max = _z[i]; minpos = (_z[0] > 0) ? _z[0] : 1.0E300; initialized = true; _NRealS++; } else { if (min > _z[i]) { min = _z[i]; } if (max < _z[i]) { max = _z[i]; } if (minpos > _z[i] && _z[i] > 0) { minpos = _z[i]; } sum += _z[i]; sumsquared += _z[i] * _z[i]; _NRealS++; } } } _scalars["sum"]->setValue(sum); _scalars["sumsquared"]->setValue(sumsquared); _scalars["max"]->setValue(max); _scalars["min"]->setValue(min); _scalars["minpos"]->setValue(minpos); updateScalars(); } } void Matrix::setXLabelInfo(const LabelInfo &label_info) { _xLabelInfo = label_info; } void Matrix::setYLabelInfo(const LabelInfo &label_info) { _yLabelInfo = label_info; } void Matrix::setTitleInfo(const LabelInfo &label_info) { _titleInfo = label_info; } LabelInfo Matrix::xLabelInfo() const { return _xLabelInfo; } LabelInfo Matrix::yLabelInfo() const { return _yLabelInfo; } LabelInfo Matrix::titleInfo() const { return _titleInfo; } bool Matrix::editable() const { return _editable; } void Matrix::setEditable(bool editable) { _editable = editable; } void Matrix::createScalars(ObjectStore *store) { Q_ASSERT(store); ScalarPtr sp; VectorPtr vp; _scalars.insert("max", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("Max"); _scalars.insert("min", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("Min"); _scalars.insert("mean", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("Mean"); _scalars.insert("sigma", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("Sigma"); _scalars.insert("rms", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("Rms"); _scalars.insert("ns", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("NS"); _scalars.insert("sum", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("Sum"); _scalars.insert("sumsquared", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("SumSquared"); _scalars.insert("minpos", sp=store->createObject()); sp->setProvider(this); sp->setSlaveName("MinPos"); _vectors.insert("z", vp = store->createObject()); vp->setProvider(this); vp->setSlaveName("Z"); } void Matrix::updateScalars() { _scalars["ns"]->setValue(_NS); if (_NRealS >= 2) { _scalars["mean"]->setValue(_scalars["sum"]->value()/double(_NRealS)); _scalars["sigma"]->setValue( sqrt( (_scalars["sumsquared"]->value() - _scalars["sum"]->value()*_scalars["sum"]->value()/double(_NRealS))/ double(_NRealS-1) ) ); _scalars["rms"]->setValue(sqrt(_scalars["sumsquared"]->value()/double(_NRealS))); } else { _scalars["sigma"]->setValue(_scalars["max"]->value() - _scalars["min"]->value()); _scalars["rms"]->setValue(sqrt(_scalars["sumsquared"]->value())); _scalars["mean"]->setValue(0); } } bool Matrix::resizeZ(int sz, bool reinit) { // qDebug() << "resizing to: " << sz << endl; if (sz >= 1) { _z = static_cast(Kst::realloc(_z, sz*sizeof(double))); _vectors["z"]->setV(_z, sz); if (!_z) { return false; } #ifdef ZERO_MEMORY if (reinit && _zSize < sz) { #if ZERO_MEMORY == 2 memset(&_z[_zSize], 0, (sz - _zSize)*sizeof(double)); #else for (int i = _zSize; i < sz; i++) { _z[i] = 0.0; } #endif } #else abort(); // avoid unpleasant surprises #endif _zSize = sz; updateScalars(); } return true; } #if 0 bool Matrix::resize(int xSize, int ySize, bool reinit) { int oldNX = _nX; int oldNY = _nY; _nX = xSize; _nY = ySize; if (resizeZ(xSize*ySize, reinit)) { return true; } else { _nX = oldNX; _nY = oldNY; return false; } } #endif // Resize the matrix to xSize x ySize, maintaining the values in the current // positions. If reinit is set, new entries will be initialized to 0. bool Matrix::resize(int xSize, int ySize, bool reinit) { if (xSize <= 0 || ySize <= 0) { return false; } // NOTE: _zSize is assumed to correctly represent the state of _z, while _nX // and _nY are the desired (but not necessarily actual) current size of the // matrix bool valid = (_zSize == _nX * _nY); // is the current matrix properly initialized? int sz = xSize * ySize; if (sz > _zSize) { // array is getting bigger, so resize before moving _z = static_cast(Kst::realloc(_z, sz*sizeof(double))); _vectors["z"]->setV(_z, sz); if (!_z) { qCritical() << "Matrix resize failed"; return false; } } if (valid && ySize != _nY && _nY > 0) { // move old values to new spots int source = 0; int target = 0; for (int row=1; row < qMin(xSize, _nX); ++row) { source += _nY; target += ySize; memmove(_z + target, _z + source, qMin(ySize, _nY)*sizeof(double)); if (reinit && ySize > _nY) { // initialize memory in new column(s) of previous row vacated by memmove memset(_z + source, 0, (ySize - _nY)*sizeof(double)); } } } if (sz < _zSize) { // array is getting smaller, so resize after moving _z = static_cast(Kst::realloc(_z, sz*sizeof(double))); _vectors["z"]->setV(_z, sz); if (!_z) { qCritical() << "Matrix resize failed"; return false; } } if (reinit && _zSize < sz) { // initialize new memory after old values for (int row=0; row < qMin(xSize, _nX); ++row) { for (int col = qMin(ySize,_nY); col> _z[i]; // stored in the same order as it was saved } if (i < nX*nY) { Debug::self()->log(i18n("Saved matrix contains less data than it claims."), Debug::Warning); resizeZ(i, false); } } QString Matrix::descriptionTip() const { return i18n("Matrix: %1\n %2 x %3").arg(Name()).arg(_nX).arg(_nY); } QString Matrix::sizeString() const { return QString("%1x%2").arg(_nX).arg(_nY); } ObjectList Matrix::outputPrimitives() const { PrimitiveList primitive_list; int n; n = _scalars.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_scalars.values().at(i))); } n = _strings.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_strings.values().at(i))); } n = _vectors.count(); for (int i = 0; i< n; i++) { VectorPtr V = _vectors.values().at(i); primitive_list.append(kst_cast(V)); primitive_list.append(V->outputPrimitives()); } return primitive_list; } PrimitiveMap Matrix::metas() const { PrimitiveMap meta; for (QHash::ConstIterator it = _strings.begin(); it != _strings.end(); ++it) { meta[it.key()] = it.value(); } for (QHash::ConstIterator it = _scalars.begin(); it != _scalars.end(); ++it) { meta[it.key()] = it.value(); } for (QHash::ConstIterator it = _vectors.begin(); it != _vectors.end(); ++it) { meta[it.key()] = it.value(); } return meta; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/vscalar.cpp000644 001750 001750 00000011430 11544160210 017100 0ustar00synthsynth000000 000000 /*************************************************************************** vscalar.cpp - a scalar from a data source ------------------- begin : September, 2008 copyright : (C) 2008 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include "kst_i18n.h" #include "vscalar.h" #include "debug.h" #include "objectstore.h" #include "updatemanager.h" namespace Kst { const QString VScalar::staticTypeString = I18N_NOOP("Vector Field Scalar"); const QString VScalar::staticTypeTag = I18N_NOOP("vscalar"); /** Create a VScalar: a scalar from a single sample of a vector field */ VScalar::VScalar(ObjectStore *store) : Scalar(store) { _file = 0L; _field.clear(); setOrphan(true); } VScalar::~VScalar() { _file = 0; } QString VScalar::_automaticDescriptiveName() const { return field(); } const QString& VScalar::typeString() const { return staticTypeString; } void VScalar::change(DataSourcePtr in_file, const QString &in_field, int in_f0) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); _field = in_field; _file = in_file; _f0 = in_f0; } void VScalar::changeFile(DataSourcePtr in_file) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (!in_file) { Debug::self()->log(i18n("Data file for scalar %1 was not opened.", Name()), Debug::Warning); } } /** return the name of the file */ QString VScalar::filename() const { QString rc; if (_file) { _file->readLock(); rc = _file->fileName(); _file->unlock(); } return rc; } /** return the field */ const QString& VScalar::field() const { return _field; } /** return the sample number */ int VScalar::F0() const { return _f0; } /** Save data scalar information */ void VScalar::save(QXmlStreamWriter &s) { if (_file) { s.writeStartElement("vscalar"); _file->readLock(); s.writeAttribute("provider", _file->Name()); DataPrimitive::saveFilename(_file->fileName(), s); _file->unlock(); s.writeAttribute("field", _field); s.writeAttribute("f0", QString::number(_f0)); saveNameInfo(s, XNUM); s.writeEndElement(); } } /** Update a data Scalar */ void VScalar::internalUpdate() { if (_file) { int f0; if (_f0<0) { f0 = _file->vector().dataInfo(_field).frameCount; } else { f0 = _f0; } _file->writeLock(); DataVector::ReadInfo p = {&_value, f0, -1, -1, 0}; _file->vector().read(_field, p); _file->unlock(); } } qint64 VScalar::minInputSerial() const { if (_file) { return (_file->serial()); } return LLONG_MAX; } qint64 VScalar::minInputSerialOfLastChange() const { if (_file) { return (_file->serialOfLastChange()); } return LLONG_MAX; } PrimitivePtr VScalar::_makeDuplicate() const { Q_ASSERT(store()); VScalarPtr scalar = store()->createObject(); scalar->writeLock(); scalar->change(_file, _field, _f0); if (descriptiveNameIsManual()) { scalar->setDescriptiveName(descriptiveName()); } scalar->registerChange(); scalar->unlock(); return kst_cast(scalar); } DataSourcePtr VScalar::dataSource() const { return _file; } QString VScalar::descriptionTip() const { QString IDstring; IDstring = i18n( "Data Scalar: %1 = %4\n" " %2\n" " Field: %3\n" " Frame: %5" ).arg(Name()).arg(dataSource()->fileName()).arg(field()).arg(value()).arg(F0()); return IDstring; } /** return true if it has a valid file and field, or false otherwise */ bool VScalar::isValid() const { if (_file) { _file->readLock(); bool rc = _file->vector().isValid(_field); _file->unlock(); return rc; } return false; } bool VScalar::_checkValidity(const DataSourcePtr ds) const { if (ds) { ds->readLock(); bool rc = ds->vector().isValid(_field); ds->unlock(); return rc; } return false; } QString VScalar::propertyString() const { return i18n("%2 frame %3 of %1 = %4").arg(dataSource()->fileName()).arg(field()).arg(F0()).arg(value()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/rwlock.cpp000644 001750 001750 00000013720 11544160210 016752 0ustar00synthsynth000000 000000 /*************************************************************************** rwlock.cpp ------------------- begin : Feb 21, 2004 copyright : (C) 2004 The University of toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "rwlock.h" #include //#define LOCKTRACE #ifdef ONE_LOCK_TO_RULE_THEM_ALL QMutex KstRWLock::_mutex(true); #endif KstRWLock::KstRWLock() : _readCount(0), _writeCount(0), _waitingReaders(0), _waitingWriters(0) { } KstRWLock::~KstRWLock() { } void KstRWLock::readLock() const { #ifndef ONE_LOCK_TO_RULE_THEM_ALL QMutexLocker lock(&_mutex); #ifdef LOCKTRACE qDebug() << (void*)this << " KstRWLock::readLock() by tid=" << (int)QThread::currentThreadId() << endl; // qDebug() << kstdBacktrace(6) << endl; #endif Qt::HANDLE me = QThread::currentThreadId(); if (_writeCount > 0 && _writeLocker == me) { // thread already has a write lock #ifdef LOCKTRACE qDebug() << "Thread " << (int)QThread::currentThreadId() << " has a write lock on KstRWLock " << (void*)this << ", getting a read lock" << endl; #endif } else { QMap::Iterator it = _readLockers.find(me); if (it != _readLockers.end() && it.value() > 0) { // thread already has another read lock } else { while (_writeCount > 0 || _waitingWriters) { // writer priority otherwise ++_waitingReaders; _readerWait.wait(&_mutex); --_waitingReaders; } } } _readLockers[me] = _readLockers[me] + 1; ++_readCount; #ifdef LOCKTRACE qDebug() << (void*)this << " KstRWLock::readLock() done by tid=" << (int)QThread::currentThread() << endl; #endif #else _mutex.lock(); #endif } void KstRWLock::writeLock() const { #ifndef ONE_LOCK_TO_RULE_THEM_ALL QMutexLocker lock(&_mutex); #ifdef LOCKTRACE qDebug() << (void*)this << " KstRWLock::writeLock() by tid=" << (int)QThread::currentThreadId() << endl; // qDebug() << kstdBacktrace(6) << endl; #endif Qt::HANDLE me = QThread::currentThreadId(); if (_readCount > 0) { QMap::Iterator it = _readLockers.find(me); if (it != _readLockers.end() && it.value() > 0) { // cannot acquire a write lock if I already have a read lock -- ERROR qDebug() << "Thread " << QThread::currentThread() << " tried to write lock KstRWLock " << (void*)this << " while holding a read lock" << endl; return; } } while (_readCount > 0 || (_writeCount > 0 && _writeLocker != me)) { ++_waitingWriters; _writerWait.wait(&_mutex); --_waitingWriters; } _writeLocker = me; ++_writeCount; #ifdef LOCKTRACE qDebug() << (void*)this << " KstRWLock::writeLock() done by tid=" << (int)QThread::currentThread() << endl; #endif #else _mutex.lock(); #endif } void KstRWLock::unlock() const { #ifndef ONE_LOCK_TO_RULE_THEM_ALL QMutexLocker lock(&_mutex); #ifdef LOCKTRACE qDebug() << (void*)this << " KstRWLock::unlock() by tid=" << (int)QThread::currentThreadId() << endl; #endif Qt::HANDLE me = QThread::currentThreadId(); if (_readCount > 0) { QMap::Iterator it = _readLockers.find(me); if (it == _readLockers.end()) { // read locked but not by me -- ERROR qDebug() << "Thread " << QThread::currentThread() << " tried to unlock KstRWLock " << (void*)this << " (read locked) without holding the lock" << endl; return; } else { --_readCount; if (it.value() == 1) { _readLockers.remove(it.key()); } else { --(it.value()); } } } else if (_writeCount > 0) { if (_writeLocker != me) { // write locked but not by me -- ERROR qDebug() << "Thread " << QThread::currentThread() << " tried to unlock KstRWLock " << (void*)this << " (write locked) without holding the lock" << endl; return; } else { --_writeCount; } } else if (_readCount == 0 && _writeCount == 0) { // not locked -- ERROR qDebug() << "Thread " << QThread::currentThread() << " tried to unlock KstRWLock " << (void*)this << " (unlocked) without holding the lock" << endl; return; } if (_readCount == 0 && _writeCount == 0) { // no locks remaining if (_waitingWriters) { _writerWait.wakeOne(); } else if (_waitingReaders) { _readerWait.wakeAll(); } } #ifdef LOCKTRACE qDebug() << (void*)this << " KstRWLock::unlock() done by tid=" << (int)QThread::currentThread() << endl; #endif #else _mutex.unlock(); #endif } KstRWLock::LockStatus KstRWLock::lockStatus() const { #ifndef ONE_LOCK_TO_RULE_THEM_ALL QMutexLocker lock(&_mutex); if (_writeCount > 0) { return WRITELOCKED; } else if (_readCount > 0) { return READLOCKED; } else { return UNLOCKED; } #else #error lockStatus() not supported using the single lock return UNLOCKED; #endif } KstRWLock::LockStatus KstRWLock::myLockStatus() const { #ifndef ONE_LOCK_TO_RULE_THEM_ALL QMutexLocker lock(&_mutex); Qt::HANDLE me = QThread::currentThreadId(); if (_writeCount > 0 && _writeLocker == me) { return WRITELOCKED; } else if (_readCount > 0 && _readLockers.find(me) != _readLockers.end()) { return READLOCKED; } else { return UNLOCKED; } #else #error myLockStatus() not supported using the single lock return UNLOCKED; #endif } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/scalarfactory.h000644 001750 001750 00000003021 11544160210 017744 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SCALARFACTORY_H #define SCALARFACTORY_H #include "primitivefactory.h" namespace Kst { class ScalarFactory : public PrimitiveFactory { public: ScalarFactory(); ~ScalarFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; class DataScalarFactory : public PrimitiveFactory { public: DataScalarFactory(); ~DataScalarFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; class VScalarFactory : public PrimitiveFactory { public: VScalarFactory(); ~VScalarFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/generatedvector.cpp000644 001750 001750 00000005414 11544160210 020633 0ustar00synthsynth000000 000000 /*************************************************************************** generatedvector.cpp - a vector from x0 to x1 with n pts ------------------- begin : March, 2005 copyright : (C) 2005 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "kst_i18n.h" #include "generatedvector.h" namespace Kst { const QString GeneratedVector::staticTypeString = I18N_NOOP("Generated Vector"); const QString GeneratedVector::staticTypeTag = I18N_NOOP("generatedvector"); GeneratedVector::GeneratedVector(ObjectStore *store) : Vector(store) { _saveable = true; _saveData = false; } const QString& GeneratedVector::typeString() const { return staticTypeString; } void GeneratedVector::save(QXmlStreamWriter &s) { s.writeStartElement("generatedvector"); s.writeAttribute("min", QString::number(min())); s.writeAttribute("max", QString::number(max())); s.writeAttribute("count", QString::number(length())); saveNameInfo(s, VNUM|XNUM); s.writeEndElement(); } void GeneratedVector::changeRange(double x0, double x1, int n) { if (n < 2) { n = 2; } if (n != length()) { resize(n, false); } if (x0 > x1) { double tx; tx = x0; x0 = x1; x1 = tx; } else if (x0 == x1) { x1 = x0 + 0.1; } for (int i = 0; i < n; i++) { _v[i] = x0 + double(i) * (x1 - x0) / double(n - 1); } _scalars["min"]->setValue(x0); _scalars["max"]->setValue(x1); registerChange(); } void GeneratedVector::setSaveData(bool save) { Q_UNUSED(save) } QString GeneratedVector::_automaticDescriptiveName() const { return QString::number(_v[0])+".."+QString::number(_v[length()-1]); } QString GeneratedVector::descriptionTip() const { return i18n("Generated Vector: %1\n" " %2 values from %3 to %4").arg(Name()).arg(length()).arg(_v[0]).arg(_v[length()-1]); } QString GeneratedVector::propertyString() const { return i18n("%3 points from %1 to %2").arg(_v[0]).arg(_v[length()-1]).arg(length()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datasource.h000644 001750 001750 00000025725 11544160210 017260 0ustar00synthsynth000000 000000 /*************************************************************************** datasource.h - abstract data source ------------------- begin : Thu Oct 16 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATASOURCE_H #define DATASOURCE_H #include "kst_export.h" #include "object.h" #include "dateparser.h" #include "objectlist.h" #include "datascalar.h" #include "datastring.h" #include "datavector.h" #include "datamatrix.h" #include #include #include class QSettings; class QXmlStreamWriter; class QXmlStreamAttributes; class QFileSystemWatcher; namespace Kst { class DataSourceConfigWidget; class DataSourcePlugin; class KSTCORE_EXPORT DataSource : public Object { Q_OBJECT public: DataSource(ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type); virtual ~DataSource(); /************************************************************/ /* Same interface for all supported Primitives */ /************************************************************/ template struct DataInterface { // read one element virtual int read(const QString& name, typename T::ReadInfo&) = 0; // named elements virtual QStringList list() const = 0; virtual bool isListComplete() const = 0; virtual bool isValid(const QString& name) const = 0; // T specific virtual const typename T::DataInfo dataInfo(const QString& name) const = 0; virtual void setDataInfo(const QString& name, const typename T::DataInfo&) = 0; // meta data virtual QMap metaScalars(const QString& name) = 0; virtual QMap metaStrings(const QString& name) = 0; }; DataInterface& scalar() {Q_ASSERT(interf_scalar); return *interf_scalar; } DataInterface& string() {Q_ASSERT(interf_string); return *interf_string; } DataInterface& vector() {Q_ASSERT(interf_vector); return *interf_vector; } DataInterface& matrix() {Q_ASSERT(interf_matrix); return *interf_matrix; } const DataInterface& scalar() const {Q_ASSERT(interf_scalar); return *interf_scalar; } const DataInterface& string() const {Q_ASSERT(interf_string); return *interf_string; } const DataInterface& vector() const {Q_ASSERT(interf_vector); return *interf_vector; } const DataInterface& matrix() const {Q_ASSERT(interf_matrix); return *interf_matrix; } /************************************************************/ /* Dynamic type system */ /************************************************************/ virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; /************************************************************/ /* Methods for update system */ /************************************************************/ enum UpdateCheckType { Timer, File, None }; void setUpdateType(UpdateCheckType updateType, const QString& file = QString()); UpdateCheckType updateType() const; virtual UpdateType objectUpdate(qint64 newSerial); void internalUpdate() {return;} qint64 minInputSerial() const {return 0;} qint64 minInputSerialOfLastChange() const {return 0;} /** Updates number of samples. For ascii files, it also reads and writes to a temporary binary file. It must be implemented by the datasource. */ virtual UpdateType internalDataSourceUpdate() = 0; /************************************************************/ /* Methods for handling time in vectors. */ /* not currently used - may be reworked (remove this note */ /* if you use it) */ /************************************************************/ static bool supportsTime(const QString& plugin, const QString& type = QString()); /** Does it support time conversion of sample numbers, in general? */ virtual bool supportsTimeConversions() const; virtual int sampleForTime(const QDateTime& time, bool *ok = 0L); virtual int sampleForTime(double milliseconds, bool *ok = 0L); virtual QDateTime timeForSample(int sample, bool *ok = 0L); // in (ms) virtual double relativeTimeForSample(int sample, bool *ok = 0L); /************************************************************/ /* UI TODO leave here? */ /************************************************************/ bool hasConfigWidget() const; DataSourceConfigWidget *configWidget(); virtual void parseProperties(QXmlStreamAttributes &properties); bool reusable() const; void disableReuse(); /************************************************************/ /* Color for the "assign curve color per file" tool */ /************************************************************/ QColor color() const; void setColor(const QColor& color); /************************************************************/ /* File/data specific */ /************************************************************/ virtual bool isValid() const; // generally you don't need to change this virtual QString fileName() const; QMap fileMetas() const; /** Returns the file type or an error message in a static string The string is stored in a separate static variable, so changes to this are ignored. It is updated each time the fn is called */ virtual QString fileType() const; void saveSource(QXmlStreamWriter &s); /** Save file description info into stream s. */ virtual void save(QXmlStreamWriter &s); const QString& sourceName() const { return _source; } // These malloc calls do not appear to be used. virtual void *bufferMalloc(size_t size); virtual void bufferFree(void *ptr); virtual void *bufferRealloc(void *ptr, size_t size); /** Returns true if this file is empty */ virtual bool isEmpty() const; /** Reset to initial state of the source, just as though no data had been * read and the file had just been opened. */ virtual void reset(); virtual void deleteDependents(); virtual QString descriptionTip() const; /** Creates a list of curves without user interaction */ virtual ObjectList autoCurves(ObjectStore&) { return ObjectList(); } public Q_SLOTS: virtual void checkUpdate(); Q_SIGNALS: void sourceUpdated(ObjectPtr sourceObject); protected: /** Is the object valid? */ bool _valid; bool _reusable; bool _writable; /** The filename. Populated by the base class constructor. */ QString _filename; friend class DataSourcePlugin; /** The source type name. */ QString _source; QSettings *_cfg; UpdateCheckType _updateCheckType; void resetFileWatcher(); virtual QString _automaticDescriptiveName() const; void _initializeShortName(); void setInterface(DataInterface*); void setInterface(DataInterface*); void setInterface(DataInterface*); void setInterface(DataInterface*); private: DataSource(); DataInterface* interf_scalar; DataInterface* interf_string; DataInterface* interf_vector; DataInterface* interf_matrix; QFileSystemWatcher *_watcher; QColor _color; // NOTE: You must bump the version key if you add new member variables // or change or add virtual functions. }; class DataSourceList : public QList { public: DataSourceList() : QList() {} DataSourceList(const DataSourceList& x) : QList(x) {} virtual ~DataSourceList() {} virtual DataSourcePtr findName(const QString name) { for (DataSourceList::Iterator it = begin(); it != end(); ++it) { if ((*it)->Name() == name) { return *it; } } return 0; } virtual DataSourcePtr findFileName(const QString& x) { for (DataSourceList::Iterator it = begin(); it != end(); ++it) { if ((*it)->fileName() == x) { return *it; } } return 0; } // @since 1.1.0 DataSourcePtr findReusableFileName(const QString& x) { for (DataSourceList::Iterator it = begin(); it != end(); ++it) { if ((*it)->reusable() && (*it)->fileName() == x) { return *it; } } return 0; } // @since 1.1.0 QStringList fileNames() const { QStringList rc; for (DataSourceList::ConstIterator it = begin(); it != end(); ++it) { rc << (*it)->fileName(); } return rc; } #if QT_VERSION < 0x040500 void append(const DataSourcePtr& ptr) { QList::append(ptr); } void append(const DataSourceList& list) { foreach(const DataSourcePtr& ptr, list) { QList::append(ptr); } } #endif }; // @since 1.1.0 class KSTCORE_EXPORT DataSourceConfigWidget : public QWidget { Q_OBJECT public: DataSourceConfigWidget(QSettings&); // will be reparented later virtual ~DataSourceConfigWidget(); QSettings& settings() const; // If _instance is nonzero, then your settings are to be saved for this // particular instance of the source, as opposed to globally. void setInstance(DataSourcePtr inst); DataSourcePtr instance() const; bool hasInstance() const; public slots: virtual void load() = 0; virtual void save() = 0; private: DataSourcePtr _instance; QSettings& _cfg; friend class DataSource; }; class KSTCORE_EXPORT ValidateDataSourceThread : public QObject, public QRunnable { Q_OBJECT public: ValidateDataSourceThread(const QString& file, const int requestID); void run(); Q_SIGNALS: void dataSourceValid(QString filename, int requestID); void dataSourceInvalid(int requestID); private: ObjectStore *_store; QString _file; int _requestID; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/nextcolor.cpp000644 001750 001750 00000002146 11544160210 017466 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "nextcolor.h" using namespace Kst; NextColor* NextColor::_instance = 0; NextColor::NextColor() { NextColor::_instance = this; } NextColor::~NextColor() { NextColor::_instance = 0; } QColor NextColor::next() { return QColor(); } NextColor& NextColor::self() { Q_ASSERT(NextColor::_instance); return *NextColor::_instance; } kst-2.0.3/src/libkst/datasource.cpp000644 001750 001750 00000024162 11544160210 017605 0ustar00synthsynth000000 000000 /*************************************************************************** datasource.cpp - abstract data source ------------------- begin : Thu Oct 16 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasource.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kst_i18n.h" #include "datacollection.h" #include "debug.h" #include "objectstore.h" #include "scalar.h" #include "string.h" #include "nextcolor.h" #include "updatemanager.h" #include "dataplugin.h" // TODO DataSource should not need the plugin code #include "datasourcepluginmanager.h" using namespace Kst; template struct NotSupportedImp : public DataSource::DataInterface { // read one element int read(const QString&, typename T::ReadInfo&) { return -1; } // named elements QStringList list() const { return QStringList(); } bool isListComplete() const { return false; } bool isValid(const QString&) const { return false; } // T specific const typename T::DataInfo dataInfo(const QString&) const { return typename T::DataInfo(); } void setDataInfo(const QString&, const typename T::DataInfo&) {} // meta data QMap metaScalars(const QString&) { return QMap(); } QMap metaStrings(const QString&) { return QMap(); } }; const QString DataSource::staticTypeString = I18N_NOOP("Data Source"); const QString DataSource::staticTypeTag = I18N_NOOP("source"); Object::UpdateType DataSource::objectUpdate(qint64 newSerial) { if (_serial==newSerial) { return NoChange; } UpdateType updated = NoChange; if (!UpdateManager::self()->paused()) { // update the datasource updated = internalDataSourceUpdate(); if (updated == Updated) { _serialOfLastChange = newSerial; // tell data objects it is new } } _serial = newSerial; return updated; } void DataSource::_initializeShortName() { _shortName = QString("DS%1").arg(_dsnum); if (_dsnum>max_dsnum) max_dsnum = _dsnum; _dsnum++; } bool DataSource::isValid() const { return _valid; } bool DataSource::hasConfigWidget() const { return DataSourcePluginManager::sourceHasConfigWidget(_filename, fileType()); } DataSourceConfigWidget* DataSource::configWidget() { if (!hasConfigWidget()) return 0; DataSourceConfigWidget *w = DataSourcePluginManager::configWidgetForSource(_filename, fileType()); Q_ASSERT(w); //This is still ugly to me... w->_instance = this; w->load(); return w; } DataSource::DataSource(ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type) : Object(), _filename(filename), _cfg(cfg), interf_scalar(new NotSupportedImp), interf_string(new NotSupportedImp), interf_vector(new NotSupportedImp), interf_matrix(new NotSupportedImp), _watcher(0), _color(NextColor::self().next()) { Q_UNUSED(type) Q_UNUSED(store) _valid = false; _reusable = true; _writable = false; _watcher = 0L; _initializeShortName(); setDescriptiveName(QFileInfo(_filename).fileName() + " (" + shortName() + ")"); // TODO What is the better default? setUpdateType(File); } DataSource::~DataSource() { resetFileWatcher(); delete interf_scalar; delete interf_string; delete interf_vector; delete interf_matrix; } QMap DataSource::fileMetas() const { QMap map; QFileInfo info(_filename); map["File name"] = info.fileName(); map["File path"] = info.path(); map["File creation"] = info.created().toString(Qt::ISODate).replace("T", " "); map["File modification"] = info.lastModified().toString(Qt::ISODate).replace("T", " "); return map; } void DataSource::resetFileWatcher() { if (_watcher) { disconnect(_watcher, SIGNAL(fileChanged ( const QString & )), this, SLOT(checkUpdate())); disconnect(_watcher, SIGNAL(directoryChanged ( const QString & )), this, SLOT(checkUpdate())); delete _watcher; _watcher = 0L; } } void DataSource::setInterface(DataInterface* i) { delete interf_scalar; interf_scalar = i; } void DataSource::setInterface(DataInterface* i) { delete interf_string; interf_string = i; } void DataSource::setInterface(DataInterface* i) { delete interf_vector; interf_vector = i; } void DataSource::setInterface(DataInterface* i) { delete interf_matrix; interf_matrix = i; } DataSource::UpdateCheckType DataSource::updateType() const { return _updateCheckType; } void DataSource::setUpdateType(UpdateCheckType updateType, const QString& file) { _updateCheckType = updateType; resetFileWatcher(); if (_updateCheckType == Timer) { QTimer::singleShot(UpdateManager::self()->minimumUpdatePeriod()-1, this, SLOT(checkUpdate())); } else if (_updateCheckType == File) { // TODO only works on local files: // http://bugreports.qt.nokia.com/browse/QTBUG-8351 // http://bugreports.qt.nokia.com/browse/QTBUG-13248 _watcher = new QFileSystemWatcher(); const QString usedfile = (file.isEmpty() ? _filename : file); _watcher->addPath(usedfile); connect(_watcher, SIGNAL(fileChanged ( const QString & )), this, SLOT(checkUpdate())); connect(_watcher, SIGNAL(directoryChanged ( const QString & )), this, SLOT(checkUpdate())); } } void DataSource::checkUpdate() { if (!UpdateManager::self()->paused()) { UpdateManager::self()->doUpdates(false); } if (_updateCheckType == Timer) { QTimer::singleShot(UpdateManager::self()->minimumUpdatePeriod()-1, this, SLOT(checkUpdate())); } } void DataSource::deleteDependents() { } const QString& DataSource::typeString() const { return staticTypeString; } QString DataSource::fileName() const { // Look to see if it was a URL and save the URL instead const QMap urlMap = DataSourcePluginManager::urlMap(); for (QMap::ConstIterator i = urlMap.begin(); i != urlMap.end(); ++i) { if (i.value() == _filename) { return i.key(); } } return _filename; } QString DataSource::fileType() const { return QString(); } void DataSource::save(QXmlStreamWriter &s) { Q_UNUSED(s) } void DataSource::saveSource(QXmlStreamWriter &s) { QString name = _filename; // Look to see if it was a URL and save the URL instead const QMap urlMap = DataSourcePluginManager::urlMap(); for (QMap::ConstIterator i = urlMap.begin(); i != urlMap.end(); ++i) { if (i.value() == _filename) { name = i.key(); break; } } s.writeStartElement("source"); s.writeAttribute("reader", fileType()); DataPrimitive::saveFilename(name, s); save(s); s.writeEndElement(); } void DataSource::parseProperties(QXmlStreamAttributes &properties) { Q_UNUSED(properties); } void *DataSource::bufferMalloc(size_t size) { return malloc(size); } void DataSource::bufferFree(void *ptr) { return ::free(ptr); } void *DataSource::bufferRealloc(void *ptr, size_t size) { return realloc(ptr, size); } bool DataSource::isEmpty() const { return true; } void DataSource::reset() { Object::reset(); } bool DataSource::supportsTimeConversions() const { return false; } int DataSource::sampleForTime(const QDateTime& time, bool *ok) { Q_UNUSED(time) if (ok) { *ok = false; } return 0; } int DataSource::sampleForTime(double ms, bool *ok) { Q_UNUSED(ms) if (ok) { *ok = false; } return 0; } QDateTime DataSource::timeForSample(int sample, bool *ok) { Q_UNUSED(sample) if (ok) { *ok = false; } return QDateTime::currentDateTime(); } double DataSource::relativeTimeForSample(int sample, bool *ok) { Q_UNUSED(sample) if (ok) { *ok = false; } return 0; } bool DataSource::reusable() const { return _reusable; } void DataSource::disableReuse() { _reusable = false; } QString DataSource::_automaticDescriptiveName() const { return fileName(); } QString DataSource::descriptionTip() const { return fileName(); } QColor DataSource::color() const { return _color; } void DataSource::setColor(const QColor& color) { _color = color; } ///////////////////////////////////////////////////////////////////////////// DataSourceConfigWidget::DataSourceConfigWidget(QSettings& settings) : QWidget(0L), _cfg(settings) { } DataSourceConfigWidget::~DataSourceConfigWidget() { } void DataSourceConfigWidget::setInstance(DataSourcePtr inst) { _instance = inst; } DataSourcePtr DataSourceConfigWidget::instance() const { return _instance; } QSettings& DataSourceConfigWidget::settings() const { return _cfg; } bool DataSourceConfigWidget::hasInstance() const { return _instance != 0L; } ValidateDataSourceThread::ValidateDataSourceThread(const QString& file, const int requestID) : QRunnable(), _file(file), _requestID(requestID) { } void ValidateDataSourceThread::run() { QFileInfo info(_file); if (!info.exists()) { emit dataSourceInvalid(_requestID); return; } if (!DataSourcePluginManager::validSource(_file)) { emit dataSourceInvalid(_requestID); return; } emit dataSourceValid(_file, _requestID); } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/timezones.cpp000644 001750 001750 00000046626 11544160210 017501 0ustar00synthsynth000000 000000 /* This file is part of the KDE libraries Copyright (c) 2005 S.R.Haque . This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "timezones.h" #include #include #include #include #include #include #include #include #include #include #define UTC_ZONE "UTC" #ifndef HAVE_UNSETENV #ifdef HAVE_ALLOCA_H #include #endif #include #include #include #include #ifndef environ extern char ** environ; #endif namespace Kst { void unsetenv(const char *name) { size_t len; char **ep; if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) { errno = EINVAL; return; } len = strlen (name); ep = environ; while (*ep != NULL) { if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { /* Found it. Remove this pointer by moving later ones back. */ char **dp = ep; do { dp[0] = dp[1]; } while (*dp++); /* Continue the loop in case NAME appears again. */ } else { ++ep; } } } #endif /* !HAVE_UNSETENV */ /** * Find out if the given standard (e.g. "GMT") and daylight savings time * (e.g. "BST", but which may be empty) abbreviated timezone names match * this timezone. * * Thus, this class can be used as a heuristic when trying to lookup the * real timezone from the abbreviated zone names. */ class AbbreviationsMatch : public TimezoneDetails { public: AbbreviationsMatch(const QString &stdZone, const QString &dstZone = "") { m_stdZone = stdZone; m_dstZone = dstZone; } void parseStarted() { m_foundStd = false; m_foundDst = m_dstZone.isEmpty(); } bool test() { return (m_foundStd && m_foundDst); } private: bool m_foundStd; bool m_foundDst; QString m_stdZone; QString m_dstZone; virtual void gotAbbreviation(int /*index*/, const QString &value) { if (m_stdZone == value) { m_foundStd = true; } if (m_dstZone == value) { m_foundDst = true; } } }; /** * Internal dummy source for UTC timezone. */ class DummySource : public TimezoneSource { public: DummySource() : TimezoneSource("") { } virtual bool parse(const QString &/*zone*/, TimezoneDetails &/*dataReceiver*/) const { return true; } }; /** * Find offset at a particular point in time. */ class OffsetFind : public TimezoneDetails { public: OffsetFind(unsigned dateTime) { m_dateTime = dateTime; } void parseStarted() { m_transitionTimeIndex = 0; m_localTimeIndex = -1; m_abbrIndex = -1; m_offset = 0; m_isDst = false; m_abbr = UTC_ZONE; } int offset() { return m_offset; } bool isDst() { return m_isDst; } QString abbreviation() { return m_abbr; } private: unsigned m_dateTime; int m_transitionTimeIndex; int m_localTimeIndex; int m_abbrIndex; int m_offset; bool m_isDst; QString m_abbr; virtual void gotTransitionTime(int index, unsigned transitionTime) { if (transitionTime <= m_dateTime) { // Remember the index of the transition time that relates to dateTime. m_transitionTimeIndex = index; } } virtual void gotLocalTimeIndex(int index, unsigned localTimeIndex) { if (index == m_transitionTimeIndex) { // Remember the index of the local time that relates to dateTime. m_localTimeIndex = localTimeIndex; } } virtual void gotLocalTime(int index, int gmtOff, bool isDst, unsigned abbrInd) { if (index == m_localTimeIndex) { // Remember the results that relate to gmtOffset. m_offset = gmtOff; m_isDst = isDst; m_abbrIndex = abbrInd; } } virtual void gotAbbreviation(int index, const QString &value) { if (index == m_abbrIndex) { m_abbr = value; } } }; const float Timezone::UNKNOWN = 1000.0; bool Timezone::isValidLatitude(float latitude) { return (latitude >= -90.0) && (latitude <= 90.0); } bool Timezone::isValidLongitude(float longitude) { return (longitude >= -180.0) && (longitude <= 180.0); } Timezone::Timezone( KSharedPtr db, const QString& name, const QString &countryCode, float latitude, float longitude, const QString &comment) : m_db(db), m_name(name), m_countryCode(countryCode), m_latitude(latitude), m_longitude(longitude), m_comment(comment), d(0) { // Detect duff values. if (m_latitude * m_latitude > 90 * 90) m_latitude = UNKNOWN; if (m_longitude * m_longitude > 180 * 180) m_longitude = UNKNOWN; } Timezone::~Timezone() { // FIXME when needed: // delete d; } QString Timezone::comment() const { return m_comment; } QDateTime Timezone::convert(const Timezone *newZone, const QDateTime &dateTime) const { char *originalZone = ::getenv("TZ"); // Convert the given localtime to UTC. ::putenv(strdup(QString("TZ=:").append(m_name).toUtf8())); tzset(); unsigned utc = dateTime.toTime_t(); // Set the timezone and convert UTC to localtime. ::putenv(strdup(QString("TZ=:").append(newZone->name()).toUtf8())); tzset(); QDateTime remoteTime; remoteTime.setTime_t(utc); remoteTime.setTimeSpec(Qt::LocalTime); // Now restore things if (!originalZone) { ::unsetenv("TZ"); } else { ::putenv(strdup(QString("TZ=").append(originalZone).toUtf8())); } tzset(); return remoteTime; } QString Timezone::countryCode() const { return m_countryCode; } float Timezone::latitude() const { return m_latitude; } float Timezone::longitude() const { return m_longitude; } QString Timezone::name() const { return m_name; } int Timezone::offset(Qt::TimeSpec basisSpec) const { char *originalZone = ::getenv("TZ"); // Get the time in the current timezone. QDateTime basisTime = QDateTime::currentDateTime().toTimeSpec(basisSpec); // Set the timezone and find out what time it is there compared to the basis. ::putenv(strdup(QString("TZ=:").append(m_name).toUtf8())); tzset(); QDateTime remoteTime = QDateTime::currentDateTime().toLocalTime(); int offset = remoteTime.secsTo(basisTime); // Now restore things if (!originalZone) { ::unsetenv("TZ"); } else { ::putenv(strdup(QString("TZ=").append(originalZone).toUtf8())); } tzset(); return offset; } int Timezone::offset(const QDateTime &dateTime) const { OffsetFind finder(dateTime.toTime_t()); int result = 0; if (parse(finder)) { result = finder.offset(); } return result; } bool Timezone::parse(TimezoneDetails &dataReceiver) const { dataReceiver.parseStarted(); bool result = m_db->parse(m_name, dataReceiver); dataReceiver.parseEnded(); return result; } Timezones::Timezones() : m_zoneinfoDir(), m_zones(0), d(0) { // Create the database (and resolve m_zoneinfoDir!). allZones(); m_UTC = new Timezone(KSharedPtr(new DummySource()), QString(UTC_ZONE)); add(m_UTC); } Timezones::~Timezones() { // FIXME when needed: // delete d; // Autodelete behavior. if (m_zones) { for (ZoneMap::ConstIterator it = m_zones->begin(); it != m_zones->end(); ++it) { delete it.value(); } } delete m_zones; } void Timezones::add(Timezone *zone) { m_zones->insert(zone->name(), zone); } const Timezones::ZoneMap Timezones::allZones() { // Have we already done all the hard work? If not, create the cache. if (m_zones) return *m_zones; m_zones = new ZoneMap(); // Go read the database. // // On Windows, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones // is the place to look. The TZI binary value is the TIME_ZONE_INFORMATION structure. // // For Unix its all easy except knowing where to look. Try the LSB location first. QFile f; m_zoneinfoDir = "/usr/share/zoneinfo"; f.setFileName(m_zoneinfoDir + "/zone.tab"); if (!f.open(QIODevice::ReadOnly)) { m_zoneinfoDir = "/usr/lib/zoneinfo"; f.setFileName(m_zoneinfoDir + "/zone.tab"); if (!f.open(QIODevice::ReadOnly)) { m_zoneinfoDir = ::getenv("TZDIR"); f.setFileName(m_zoneinfoDir + "/zone.tab"); if (m_zoneinfoDir.isEmpty() || !f.open(QIODevice::ReadOnly)) { // Solaris support. Synthesise something that looks like a zone.tab. // // /bin/grep -h ^Zone /usr/share/lib/zoneinfo/src/* | /bin/awk '{print "??\t+9999+99999\t" $2}' // // where the country code is set to "??" and the lattitude/longitude // values are dummies. m_zoneinfoDir = "/usr/share/lib/zoneinfo"; K3TempFile temp; KShellProcess reader; reader << "/bin/grep" << "-h" << "^Zone" << m_zoneinfoDir << "/src/*" << temp.name() << "|" << "/bin/awk" << "'{print \"??\\t+9999+99999\\t\" $2}'"; // Note the use of blocking here...it is a trivial amount of data! temp.close(); reader.start(KProcess::Block); f.setFileName(temp.name()); if (!temp.status() || !f.open(QIODevice::ReadOnly)) { return *m_zones; } } } } // Parse the zone.tab. QTextStream str(&f); QRegExp lineSeparator("[ \t]"); QRegExp ordinateSeparator("[+-]"); KSharedPtr db(new TimezoneSource(m_zoneinfoDir)); while (!str.atEnd()) { QString line = str.readLine(); if (line.isEmpty() || '#' == line[0]) continue; QStringList tokens = KStringHandler::perlSplit(lineSeparator, line, 4); if (tokens.count() < 3) { continue; } // Got three tokens. Now check for two ordinates plus first one is "". QStringList ordinates = KStringHandler::perlSplit(ordinateSeparator, tokens[1], 2); if (ordinates.count() < 2) { continue; } float latitude = convertCoordinate(ordinates[1]); float longitude = convertCoordinate(ordinates[2]); // Add entry to list. if (tokens[0] == "??") tokens[0] = ""; Timezone *timezone = new Timezone(db, tokens[2], tokens[0], latitude, longitude, tokens[3]); add(timezone); } f.close(); return *m_zones; } /** * Convert sHHMM or sHHMMSS to a floating point number of degrees. */ float Timezones::convertCoordinate(const QString &coordinate) { int value = coordinate.toInt(); int degrees = 0; int minutes = 0; int seconds = 0; if (coordinate.length() > 11) { degrees = value / 10000; value -= degrees * 10000; minutes = value / 100; value -= minutes * 100; seconds = value; } else { degrees = value / 100; value -= degrees * 100; minutes = value; } value = degrees * 3600 + minutes * 60 + seconds; return value / 3600.0; } const Timezone *Timezones::local() { const Timezone *local = 0; // First try the simplest solution of checking for well-formed TZ setting. char *envZone = ::getenv("TZ"); if (envZone) { if (envZone[0] == '\0') { return m_UTC; } else if (envZone[0] == ':') { envZone++; } local = zone(envZone); } if (local) return local; // Try to match /etc/localtime against the list of zoneinfo files. QFile f; f.setFileName("/etc/localtime"); if (f.open(QIODevice::ReadOnly)) { // Compute the MD5 sum of /etc/localtime. KMD5 context(""); context.reset(); context.update(f); qlonglong referenceSize = f.size(); QString referenceMd5Sum = context.hexDigest(); f.close(); if (!m_zoneinfoDir.isEmpty()) { // Compare it with each zoneinfo file. for (ZoneMap::Iterator it = m_zones->begin(); it != m_zones->end(); ++it) { Timezone *zone = it.value(); f.setFileName(m_zoneinfoDir + '/' + zone->name()); if (f.open(QIODevice::ReadOnly)) { qlonglong candidateSize = f.size(); QString candidateMd5Sum; if (candidateSize == referenceSize) { // Only do the heavy lifting for file sizes which match. context.reset(); context.update(f); candidateMd5Sum = context.hexDigest(); } f.close(); if (candidateMd5Sum == referenceMd5Sum) { local = zone; break; } } } } } if (local) return local; // BSD support. QString fileZone; f.setFileName("/etc/timezone"); if (!f.open(QIODevice::ReadOnly)) { // Solaris support using /etc/default/init. f.setFileName("/etc/default/init"); if (f.open(QIODevice::ReadOnly)) { QTextStream ts(&f); ts.setCodec("latin1"); // Read the last line starting "TZ=". while (!ts.atEnd()) { fileZone = ts.readLine(); if (fileZone.startsWith("TZ=")) { fileZone = fileZone.mid(3); local = zone(fileZone); } } f.close(); } } else { QTextStream ts(&f); ts.setCodec("latin1"); // Read the first line. if (!ts.atEnd()) { fileZone = ts.readLine(); local = zone(fileZone); } f.close(); } if (local) return local; // None of the deterministic stuff above has worked: try a heuristic. We // try to find a pair of matching timezone abbreviations...that way, we'll // likely return a value in the user's own country. if (!m_zoneinfoDir.isEmpty()) { tzset(); AbbreviationsMatch matcher(tzname[0], tzname[1]); int bestOffset = INT_MAX; for (ZoneMap::Iterator it = m_zones->begin(); it != m_zones->end(); ++it) { Timezone *zone = it.value(); int candidateOffset = qAbs(zone->offset(Qt::LocalTime)); if (zone->parse(matcher) && matcher.test() && (candidateOffset < bestOffset)) { bestOffset = candidateOffset; local = zone; } } } if (local) return local; return m_UTC; } const Timezone *Timezones::zone(const QString &name) { if (name.isEmpty()) return m_UTC; ZoneMap::ConstIterator it = m_zones->find(name); if (it != m_zones->end()) return it.value(); // Error. return 0; } TimezoneDetails::TimezoneDetails() { } TimezoneDetails::~TimezoneDetails() { } void TimezoneDetails::gotAbbreviation(int /*index*/, const QString &) {} void TimezoneDetails::gotHeader( unsigned, unsigned, unsigned, unsigned, unsigned, unsigned) {} void TimezoneDetails::gotLeapAdjustment(int /*index*/, unsigned, unsigned) {} void TimezoneDetails::gotLocalTime(int /*index*/, int, bool, unsigned) {} void TimezoneDetails::gotLocalTimeIndex(int /*index*/, unsigned) {} void TimezoneDetails::gotIsStandard(int /*index*/, bool) {} void TimezoneDetails::gotTransitionTime(int /*index*/, unsigned) {} void TimezoneDetails::gotIsUTC(int /*index*/, bool) {} void TimezoneDetails::parseEnded() {} void TimezoneDetails::parseStarted() {} TimezoneSource::TimezoneSource(const QString &db) : m_db(db) { } TimezoneSource::~TimezoneSource() { } QString TimezoneSource::db() { return m_db; } bool TimezoneSource::parse(const QString &zone, TimezoneDetails &dataReceiver) const { QFile f(m_db + '/' + zone); if (!f.open(QIODevice::ReadOnly)) { return false; } // Structures that represent the zoneinfo file. quint8 T, z, i_, f_; struct { quint32 ttisgmtcnt; quint32 ttisstdcnt; quint32 leapcnt; quint32 timecnt; quint32 typecnt; quint32 charcnt; } tzh; quint32 transitionTime; quint8 localTimeIndex; struct { qint32 gmtoff; qint8 isdst; quint8 abbrind; } tt; quint32 leapTime; quint32 leapSeconds; quint8 isStandard; quint8 isUTC; QDataStream str(&f); str >> T >> z >> i_ >> f_; unsigned i; for (i = 0; i < 4; i++) str >> tzh.ttisgmtcnt; str >> tzh.ttisgmtcnt >> tzh.ttisstdcnt >> tzh.leapcnt >> tzh.timecnt >> tzh.typecnt >> tzh.charcnt; dataReceiver.gotHeader(tzh.ttisgmtcnt, tzh.ttisstdcnt, tzh.leapcnt, tzh.timecnt, tzh.typecnt, tzh.charcnt); for (i = 0; i < tzh.timecnt; i++) { str >> transitionTime; dataReceiver.gotTransitionTime(i, transitionTime); } for (i = 0; i < tzh.timecnt; i++) { // NB: these appear to be 1-based, not zero-based! str >> localTimeIndex; dataReceiver.gotLocalTimeIndex(i, localTimeIndex); } for (i = 0; i < tzh.typecnt; i++) { str >> tt.gmtoff >> tt.isdst >> tt.abbrind; dataReceiver.gotLocalTime(i, tt.gmtoff, (tt.isdst != 0), tt.abbrind); } // Make sure we don't run foul of maliciously coded timezone abbreviations. if (tzh.charcnt > 64) { return false; } QByteArray array(tzh.charcnt, '\0'); str.readRawData(array.data(), array.size()); char *abbrs = array.data(); if (abbrs[tzh.charcnt - 1] != 0) { // These abbrevations are corrupt! return false; } char *abbr = abbrs; while (abbr < abbrs + tzh.charcnt) { dataReceiver.gotAbbreviation((abbr - abbrs), abbr); abbr += strlen(abbr) + 1; } for (i = 0; i < tzh.leapcnt; i++) { str >> leapTime >> leapSeconds; dataReceiver.gotLeapAdjustment(i, leapTime, leapSeconds); } for (i = 0; i < tzh.ttisstdcnt; i++) { str >> isStandard; dataReceiver.gotIsStandard(i, (isStandard != 0)); } for (i = 0; i < tzh.ttisgmtcnt; i++) { str >> isUTC; dataReceiver.gotIsUTC(i, (isUTC != 0)); } return true; } } kst-2.0.3/src/libkst/datasourcefactory.h000644 001750 001750 00000003032 11544160210 020633 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATASOURCEFACTORY_H #define DATASOURCEFACTORY_H #include #include #include "datasource.h" #include "kst_export.h" namespace Kst { class ObjectStore; class DataSourceFactory { public: DataSourceFactory(); virtual ~DataSourceFactory(); // This takes ownership static void registerFactory(const QString& node, DataSourceFactory *factory); static void registerFactory(const QStringList& nodes, DataSourceFactory *factory); KSTCORE_EXPORT static DataSourcePtr parse(ObjectStore *store, QXmlStreamReader& stream); virtual DataSourcePtr generateDataSource(ObjectStore *store, QXmlStreamReader& stream) = 0; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/psversion.h000644 001750 001750 00000002116 11544160210 017143 0ustar00synthsynth000000 000000 #include "config.h" #ifdef __linux__ #ifndef PROC_VERSION_H #define PROC_VERSION_H #ifndef S #define S(X) ((unsigned long long)(X) << 10) #endif #include "procps.h" /* Suite version information for procps utilities * Copyright (c) 1995 Martin Schulze * Linux kernel version information for procps utilities * Copyright (c) 1996 Charles Blake * Distributable under the terms of the GNU Library General Public License * * Copy right 2002 Albert Cahalan */ EXTERN_C_BEGIN extern void display_version(void); /* display suite version */ extern const char procps_version[]; /* global buf for suite version */ extern int linux_version_code; /* runtime version of LINUX_VERSION_CODE in /usr/include/linux/version.h */ /* Convenience macros for composing/decomposing version codes */ #define LINUX_VERSION(x,y,z) (0x10000*(x) + 0x100*(y) + z) #define LINUX_VERSION_MAJOR(x) (((x)>>16) & 0xFF) #define LINUX_VERSION_MINOR(x) (((x)>> 8) & 0xFF) #define LINUX_VERSION_PATCH(x) ( (x) & 0xFF) EXTERN_C_END #endif /* PROC_VERSION_H */ #endif kst-2.0.3/src/libkst/labelinfo.cpp000644 001750 001750 00000003436 11544160210 017407 0ustar00synthsynth000000 000000 /* Keeps track of information relevant to label creation. Copyright (C) 2011 Barth Netterfield netterfield@astro.utoronto.ca This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "labelinfo.h" namespace Kst { QString LabelInfo::singleRenderItemLabel() const { if (units.isEmpty() && quantity.isEmpty()) { // Nxx xxx return name; } else if (quantity.isEmpty()) { if (!name.isEmpty()) { return QString("%1 \\[%2\\]").arg(name).arg(units); // NxU } else { return units; // xxU } } else if (units.isEmpty()) { if (name.isEmpty()) { return quantity; // xQx } else { if (name.toLower().contains(quantity.toLower())) { return name; // NQx A } else { return QString("%1: %2").arg(name).arg(quantity); // NQx B } } } else if (name.isEmpty()) { return QString("%1 \\[%2\\]").arg(quantity).arg(units); // xQU } else { return QString("%1 \\[%2\\]").arg(quantity).arg(units); // NQU B } } } kst-2.0.3/src/libkst/rwlock.h000644 001750 001750 00000004724 11544160210 016423 0ustar00synthsynth000000 000000 /*************************************************************************** rwlock.h ------------------- begin : Feb 21, 2004 copyright : (C) 2004 The University of toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RWLOCK_H #define RWLOCK_H #include #include #include #include #include #include "kst_export.h" // NOTE: In order to preserve binary compatibility with plugins, you must // update the plugin keys whenever you add, remove, or change member // variables or virtual functions, or when you remove or change // non-virtual functions. class KSTCORE_EXPORT KstRWLock { public: KstRWLock(); virtual ~KstRWLock(); virtual void readLock() const; virtual void writeLock() const; virtual void unlock() const; enum LockStatus {UNLOCKED, READLOCKED, WRITELOCKED}; virtual LockStatus lockStatus() const; virtual LockStatus myLockStatus() const; protected: #ifdef ONE_LOCK_TO_RULE_THEM_ALL static #else mutable #endif QMutex _mutex; mutable QWaitCondition _readerWait, _writerWait; mutable int _readCount, _writeCount; mutable int _waitingReaders, _waitingWriters; mutable Qt::HANDLE _writeLocker; mutable QMap _readLockers; }; class KSTCORE_EXPORT KstReadLocker { public: KstReadLocker(KstRWLock *l) : _l(l) { _l->readLock(); } ~KstReadLocker() { _l->unlock(); } private: KstRWLock *_l; }; class KSTCORE_EXPORT KstWriteLocker { public: KstWriteLocker(KstRWLock *l) : _l(l) { _l->writeLock(); } ~KstWriteLocker() { _l->unlock(); } private: KstRWLock *_l; }; #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/debug.h000644 001750 001750 00000004472 11544160210 016210 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DEBUG_H #define DEBUG_H #include #include #include #include #include #include "kst_export.h" namespace Kst { // This class has to be threadsafe class KSTCORE_EXPORT Debug : public QObject { Q_OBJECT public: enum LogLevel { Unknown = 0, Notice = 1, Warning = 2, Error = 4, DebugLog = 8, None = 16384 }; struct LogMessage { QDateTime date; QString msg; LogLevel level; }; static Debug *self(); void clear(); void log(const QString& msg, LogLevel level = Notice); void setLimit(bool applyLimit, int limit); QString text(); int logLength() const; QList messages() const; Debug::LogMessage message(unsigned n) const; QStringList dataSourcePlugins() const; QString label(LogLevel level) const; const QString& kstRevision() const; int limit() const; bool hasNewError() const; void clearHasNewError(); #ifdef BENCHMARK QMap& drawCounter() { return _drawCounter; } #endif void setHandler(QObject *handler); private: Debug(); ~Debug(); static Debug *_self; static void cleanup(); QList _messages; bool _applyLimit; bool _hasNewError; int _limit; mutable QMutex _lock; #ifdef BENCHMARK // If this is ever public we can't do this QMap _drawCounter; #endif QPointer _handler; QString _kstRevision; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/objectstore.cpp000644 001750 001750 00000011120 11544160210 017764 0ustar00synthsynth000000 000000 /*************************************************************************** objectstore.cpp: store of Objects ------------------- begin : November 22, 2006 copyright : (C) 2006 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include "object.h" #include "objectstore.h" #include "datavector.h" #include "datastring.h" #include "datascalar.h" #include "datamatrix.h" // NAMEDEBUG: 0 for no debug, 1 for some debug, 2 for more debug, 3 for all debug #define NAMEDEBUG 0 namespace Kst { ObjectStore::ObjectStore() { override.fileName = QString(); override.f0 = override.N = override.skip = override.doAve = -5; } ObjectStore::~ObjectStore() { } bool ObjectStore::removeObject(Object *o) { if (!this) { return false; } if (!o) { return false; } KstWriteLocker l(&this->_lock); DataSourcePtr ds = kst_cast(o); if (ds) { if (!_dataSourceList.contains(ds)) { #if NAMEDEBUG > 1 qDebug() << "Trying to delete a non-existant data source from the store: " << ds->tag().tagString(); #endif return false; } } else if (!_list.contains(o)) { #if NAMEDEBUG > 1 qDebug() << "Trying to delete a non-existant object from the store: " << o->tag().tagString(); #endif return false; } if (ds) { ds->deleteDependents(); _dataSourceList.removeAll(ds); } else { o->deleteDependents(); _list.removeAll(o); } o->_store = 0; return true; } ObjectPtr ObjectStore::retrieveObject(const QString& name) const { int match = -1; if (name.isEmpty()) { return NULL; } QString shortName; QRegExp rx("(\\(|^)([A-Z]\\d+)(\\)$|$)"); rx.indexIn(name); shortName = rx.cap(2); // 1) search for short names int size = _list.size(); for (int i = 0; i < size; ++i) { if (_list.at(i)->shortName()==shortName) return _list.at(i); } // 3) search for descriptive names: must be unique for (int i = 0; i < size; ++i) { if (_list.at(i)->descriptiveName() == name) { if (match != -1) return NULL; // not unique, so... no match match = i; } } if (match >-1) return _list.at(match); return NULL; } void ObjectStore::rebuildDataSourceList() { cleanUpDataSourceList(); foreach (DataSourcePtr ds, _dataSourceList) { ds->writeLock(); ds->reset(); ds->unlock(); } foreach (ObjectPtr object, _list) { object->writeLock(); object->reset(); object->unlock(); } } void ObjectStore::cleanUpDataSourceList() { DataSourceList currentSourceList; currentSourceList.clear(); currentSourceList.append(_dataSourceList); // clean up unused data sources for (DataSourceList::Iterator it = currentSourceList.begin(); it != currentSourceList.end(); ++it) { if ((*it)->getUsage() <= 1) { removeObject(*it); } } currentSourceList.clear(); } bool ObjectStore::isEmpty() const { KstReadLocker l(&_lock); return _list.isEmpty(); } void ObjectStore::clear() { KstWriteLocker l(&_lock); #if NAMEDEBUG > 0 qDebug () << "Clearing object store " << (void*) this; #endif foreach(DataSource *ds, _dataSourceList) { removeObject(ds); } foreach(Object *o, _list) { removeObject(o); } // Reset the named objects id's. NamedObject::resetNameIndex(); } DataSourceList ObjectStore::dataSourceList() const { KstReadLocker l(&_lock); return _dataSourceList; } QList ObjectStore::objectList() { KstReadLocker l(&_lock); return _list; } void ObjectStore::clearUsedFlags() { foreach (ObjectPtr p, _list) { p->setUsed(false); } } bool ObjectStore::deleteUnsetUsedFlags() { QList list = _list; bool some_deleted = false; foreach (ObjectPtr p, list) { if (!p->used()) { removeObject(p); some_deleted = true; } } return some_deleted; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/procps.h000644 001750 001750 00000010016 11544160210 016417 0ustar00synthsynth000000 000000 /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This file is from the procps project at http://procps.sourceforge.net/ * * Copyright 1998-2003 Albert Cahalan * * * ***************************************************************************/ #ifndef PROCPS_PROC_PROCPS_H #define PROCPS_PROC_PROCPS_H #ifdef __cplusplus #define EXTERN_C_BEGIN extern "C" { #define EXTERN_C_END } #else #define EXTERN_C_BEGIN #define EXTERN_C_END #endif /* Some ports make the mistake of running a 32-bit userspace */ /* on a 64-bit kernel. Shame on them. It's not at all OK to */ /* make everything "long long", since that causes unneeded */ /* slowness on 32-bit hardware. */ /* */ /* SPARC: 32-bit kernel is an ex-penguin, so use "long long". */ /* */ /* MIPS: Used for embedded systems and obsolete hardware. */ /* Oh, there's a 64-bit version? SGI is headed toward IA-64, */ /* so don't worry about 64-bit MIPS. */ /* */ /* PowerPC: Big ugly problem! Macs are popular. :-/ */ /* */ /* Unknown: PA-RISC, zSeries, and x86-64 */ /* */ #if defined(k64test) || defined(__sparc__) /* || defined(__mips__) || defined(__powerpc__) */ #define KLONG long long /* not typedef; want "unsigned KLONG" to work */ #define KLF "L" #define STRTOUKL strtoull #else #define KLONG long #define KLF "l" #define STRTOUKL strtoul #endif /* since gcc-2.5 */ #define NORETURN __attribute__((__noreturn__)) #define FUNCTION __attribute__((__const__)) /* no access to global mem, even via ptr, and no side effect */ #ifndef __STDC_VERSION__ #define __STDC_VERSION__ 0 #endif #if !defined(restrict) && __STDC_VERSION__ < 199901 #if __GNUC__ > 2 || __GNUC_MINOR__ >= 92 #define restrict __restrict__ #else #warning No restrict keyword? #define restrict #endif #endif #if __GNUC__ > 2 || __GNUC_MINOR__ >= 96 /* won't alias anything, and aligned enough for anything */ #define MALLOC __attribute__ ((__malloc__)) /* no side effect, may read globals */ #define PURE __attribute__ ((__pure__)) /* tell gcc what to expect: if(unlikely(err)) die(err); */ #define likely(x) __builtin_expect(!!(x),1) #define unlikely(x) __builtin_expect(!!(x),0) #define expected(x,y) __builtin_expect((x),(y)) #else #define MALLOC #define PURE #define likely(x) (x) #define unlikely(x) (x) #define expected(x,y) (x) #endif #if defined(SHARED) && SHARED == 1 && (__GNUC__ > 2 || __GNUC_MINOR__ >= 96) #define LABEL_OFFSET #endif #define STRINGIFY_ARG(a) #a #define STRINGIFY(a) STRINGIFY_ARG(a) /* marks old junk, to warn non-procps library users */ #if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3 #define OBSOLETE __attribute__((deprecated)) #else #define OBSOLETE #endif #if ( __GNUC__ == 3 && __GNUC_MINOR__ > 1 ) || __GNUC__ > 3 /* Tells gcc that function is library-internal; */ /* so no need to do dynamic linking at run-time. */ /* This might work with slightly older compilers too. */ #define HIDDEN __attribute__((visibility("hidden"))) /* Tell g++ that a function won't throw exceptions. */ #define NOTHROW __attribute__((__nothrow__)) #else #define HIDDEN #define NOTHROW #endif /* Like HIDDEN, but for an alias that gets created. */ /* In gcc-3.2 there is an alias+hidden conflict. */ /* Many will have patched this bug, but oh well. */ #if ( __GNUC__ == 3 && __GNUC_MINOR__ > 2 ) || __GNUC__ > 3 #define HIDDEN_ALIAS(x) extern __typeof(x) x##_direct __attribute__((alias(#x),visibility("hidden"))) #else #define HIDDEN_ALIAS(x) extern __typeof(x) x##_direct __attribute__((alias(#x))) #endif #endif kst-2.0.3/src/libkst/labelinfo.h000644 001750 001750 00000002547 11544160210 017056 0ustar00synthsynth000000 000000 /* Keeps track of information relevant to label creation. Copyright (C) 2011 Barth Netterfield netterfield@astro.utoronto.ca This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef LABELINFO_H #define LABELINFO_H #include #include "kst_export.h" namespace Kst { struct KSTCORE_EXPORT LabelInfo { LabelInfo() : name(QString()), quantity(QString()), units(QString()) {} bool operator==(const LabelInfo &l) const { return (l.name==name) && (l.quantity==quantity) && (l.units==units); } bool operator!=(const LabelInfo &l) const { return !(*this==l); } QString name; QString quantity; QString units; QString singleRenderItemLabel() const; }; } #endif // LABELINFO_H kst-2.0.3/src/libkst/debug.cpp000644 001750 001750 00000011260 11544160210 016534 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "config.h" #ifdef KST_HAVE_SVN_REVISION_H #include "svnrevision.h" #endif #include "datasource.h" #include "debug.h" #include "logevents.h" #include #include #include #include "kst_i18n.h" #include "datasourcepluginmanager.h" #include "ksttimers.h" namespace Kst { Debug *Debug::_self = 0L; void Debug::cleanup() { delete _self; _self = 0; } static QMutex soLock; Debug *Debug::self() { QMutexLocker ml(&soLock); if (!_self) { _self = new Debug; qAddPostRoutine(Debug::cleanup); } return _self; } Debug::Debug() : QObject() { _applyLimit = false; _limit = 10000; _kstRevision = QString::fromLatin1(SVN_REVISION); _hasNewError = false; } Debug::~Debug() { #ifdef BENCHMARK qDebug() << "DRAW COUNTS ---------------------------------------" << endl; for (QMap::ConstIterator i = _drawCounter.begin(); i != _drawCounter.end(); ++i) { qDebug() << i.key() << ": " << i.value() << endl; } #endif } int Debug::limit() const { QMutexLocker ml(&_lock); return _limit; } QStringList Debug::dataSourcePlugins() const { return DataSourcePluginManager::pluginList(); } void Debug::setHandler(QObject *handler) { _handler = handler; } void Debug::log(const QString& msg, LogLevel level) { QMutexLocker ml(&_lock); LogMessage message; message.date = QDateTime::currentDateTime(); message.msg = msg; message.level = level; _messages.append(message); if (_applyLimit && int(_messages.size()) > _limit) { QList::Iterator first = _messages.begin(); QList::Iterator last = first; last += _messages.size() - _limit; _messages.erase(first, last); } if (level == Error) { _hasNewError = true; } if (_handler) { LogEvent *e = new LogEvent(LogEvent::LogAdded); e->_msg = message; QApplication::postEvent(_handler, e); } } void Debug::clear() { clearHasNewError(); // has to be before the lock is acquired QMutexLocker ml(&_lock); _messages.clear(); LogEvent *e = new LogEvent(LogEvent::LogCleared); QApplication::postEvent(_handler, e); } QString Debug::label(LogLevel level) const { switch (level) { case Notice: return i18nc("log level notice", "Notice"); case Warning: return i18nc("log level warning", "Warning"); case Error: return i18nc("log level error", "Error"); case DebugLog: return i18nc("log level debug", "Debug"); default: return i18nc("log level other", "Other"); } } QString Debug::text() { QMutexLocker ml(&_lock); QString body = i18n("Kst version %1\n\n\nKst log:\n").arg(KSTVERSION); QLocale locale; for (int i = 0; i < _messages.count(); i++ ) { body += i18nc("date leveltext: message", "%1 %2: %3\n", _messages[i].date.toString(locale.dateFormat()), label(_messages[i].level), _messages[i].msg); } body += i18n("\n\nData-source plugins:"); QStringList dsp = dataSourcePlugins(); for (QStringList::ConstIterator it = dsp.begin(); it != dsp.end(); ++it) { body += '\n'; body += *it; } body += "\n\n"; return body; } void Debug::setLimit(bool applyLimit, int limit) { QMutexLocker ml(&_lock); _applyLimit = applyLimit; _limit = limit; } QList Debug::messages() const { QMutexLocker ml(&_lock); return _messages; } Debug::LogMessage Debug::message(unsigned n) const { QMutexLocker ml(&_lock); if (_messages.size() > int(n)) { return _messages[n]; } return Debug::LogMessage(); } int Debug::logLength() const { QMutexLocker ml(&_lock); return _messages.size(); } const QString& Debug::kstRevision() const { QMutexLocker ml(&_lock); return _kstRevision; } bool Debug::hasNewError() const { QMutexLocker ml(&_lock); return _hasNewError; } void Debug::clearHasNewError() { QMutexLocker ml(&_lock); _hasNewError = false; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datavector.cpp000644 001750 001750 00000047534 11544160210 017617 0ustar00synthsynth000000 000000 /*************************************************************************** datavector.cpp - a vector which gets its data from a datasource. ------------------- begin : Fri Sep 22 2000 copyright : (C) 2000-2010 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * Permission is granted to link with any opensource library * * * ***************************************************************************/ #include #include #include #include #include #include "kst_i18n.h" #include "datacollection.h" #include "debug.h" #include "datavector.h" #include "datasource.h" #include "math_kst.h" #include "objectstore.h" #include "updatemanager.h" // ReqNF <=0 means read from ReqF0 to end of File // ReqF0 < means start at EndOfFile-ReqNF. // // ReqNF ReqF0 Action // < 1 >=0 read from ReqF0 to end of file // < 1 < 0 illegal: fixed in checkIntegrity // 1 ?? illegal: fixed in checkIntegrity // > 1 < 0 read the last ReqNF frames from the file // > 1 >=0 Read ReqNF frames starting at frame ReqF0 namespace Kst { const QString DataVector::staticTypeString = I18N_NOOP("Data Vector"); const QString DataVector::staticTypeTag = I18N_NOOP("datavector"); DataVector::DataInfo::DataInfo() : frameCount(-1), samplesPerFrame(-1) { } DataVector::DataInfo::DataInfo(int fc, int spf) : frameCount(fc), samplesPerFrame(spf) { } /** Create a DataVector: raw data from a file */ DataVector::DataVector(ObjectStore *store) : Vector(store), DataPrimitive(this) { _saveable = true; _dontUseSkipAccel = false; _numSamples = 0; _scalars["sum"]->setValue(0.0); _scalars["sumsquared"]->setValue(0.0); F0 = NF = 0; // nothing read yet N_AveReadBuf = 0; AveReadBuf = 0L; ReqF0 = 0; ReqNF = -1; Skip = 1; DoSkip = false; DoAve = false; } const QString& DataVector::typeString() const { return staticTypeString; } /** return true if it has a valid file and field, or false otherwise */ bool DataVector::isValid() const { if (dataSource()) { dataSource()->readLock(); bool rc = dataSource()->vector().isValid(_field); dataSource()->unlock(); return rc; } return false; } bool DataVector::checkValidity(const DataSourcePtr& ds) const { if (ds) { ds->readLock(); bool rc = ds->vector().isValid(_field); ds->unlock(); return rc; } return false; } void DataVector::change(DataSourcePtr in_file, const QString &in_field, int in_f0, int in_n, int in_skip, bool in_DoSkip, bool in_DoAve) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); Skip = in_skip; DoSkip = in_DoSkip; DoAve = in_DoAve; if (DoSkip && Skip < 1) { Skip = 1; } _dontUseSkipAccel = false; setDataSource(in_file); ReqF0 = in_f0; ReqNF = in_n; _field = in_field; if (dataSource()) { dataSource()->writeLock(); } reset(); if (dataSource()) { dataSource()->unlock(); } if (ReqNF <= 0 && ReqF0 < 0) { ReqF0 = 0; } registerChange(); } qint64 DataVector::minInputSerial() const { if (dataSource()) { return (dataSource()->serial()); } return LLONG_MAX; } qint64 DataVector::minInputSerialOfLastChange() const { if (dataSource()) { return (dataSource()->serialOfLastChange()); } return LLONG_MAX; } void DataVector::changeFile(DataSourcePtr in_file) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (!in_file) { Debug::self()->log(i18n("Data file for vector %1 was not opened.", Name()), Debug::Warning); } setDataSource(in_file); if (dataSource()) { dataSource()->writeLock(); } reset(); if (dataSource()) { dataSource()->unlock(); } registerChange(); } void DataVector::changeFrames(int in_f0, int in_n, int in_skip, bool in_DoSkip, bool in_DoAve) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (dataSource()) { dataSource()->writeLock(); } reset(); if (dataSource()) { dataSource()->unlock(); } Skip = in_skip; DoSkip = in_DoSkip; DoAve = in_DoAve; if (DoSkip && Skip < 1) { Skip = 1; } ReqF0 = in_f0; ReqNF = in_n; if (ReqNF <= 0 && ReqF0 < 0) { ReqF0 = 0; } registerChange(); } void DataVector::setFromEnd() { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); ReqF0 = -1; if (ReqNF < 2) { ReqNF = numFrames(); if (ReqNF < 2) { ReqF0 = 0; } } registerChange(); } DataVector::~DataVector() { if (AveReadBuf) { free(AveReadBuf); AveReadBuf = 0L; } } bool DataVector::readToEOF() const { return ReqNF <= 0; } bool DataVector::countFromEOF() const { return ReqF0 < 0; } /** Return Starting Frame of Vector */ int DataVector::startFrame() const { return F0; } /** Return frames per skip to read */ int DataVector::skip() const { return DoSkip ? Skip : 0; } bool DataVector::doSkip() const { return DoSkip; } bool DataVector::doAve() const { return DoAve; } /** Return frames held in Vector */ int DataVector::numFrames() const { return NF; } int DataVector::reqNumFrames() const { return ReqNF; } int DataVector::reqStartFrame() const { return ReqF0; } /** Save vector information */ void DataVector::save(QXmlStreamWriter &s) { if (dataSource()) { s.writeStartElement("datavector"); saveFilename(s); s.writeAttribute("field", _field); s.writeAttribute("start", QString::number(ReqF0)); s.writeAttribute("count", QString::number(ReqNF)); if (doSkip()) { s.writeAttribute("skip", QString::number(Skip)); if (doAve()) { s.writeAttribute("doAve", "true"); } } else { s.writeAttribute("skip", QString::number(-1)); s.writeAttribute("doAve", "false"); } saveNameInfo(s, VNUM|XNUM); s.writeEndElement(); } } /** * @brief Generate default label info for axis associated with this vector. * Use meta-scalars "units" or "quantity" if they are defined. * Escape special characters in the field name. * * @return LabelInfo **/ LabelInfo DataVector::labelInfo() const { LabelInfo label_info; if (_fieldStrings.contains("quantity")) { label_info.quantity = _fieldStrings.value("quantity")->value(); label_info.quantity.replace('[', "\\[").replace(']', "\\]"); } else { label_info.quantity = QString(); } if (_fieldStrings.contains("units")) { label_info.units = _fieldStrings.value("units")->value(); label_info.units.replace('[', "\\[").replace(']', "\\]"); } else { label_info.units = QString(); } label_info.name = descriptiveName();// _field; // un-escape escaped special characters so they aren't escaped 2x. //label_info.name.replace("\\_", "_").replace("\\^","^").replace("\\[", "[").replace("\\]", "]"); // now escape the special characters. //label_info.name.replace('_', "\\_").replace('^', "\\^").replace('[', "\\[").replace(']', "\\]"); return label_info; } void DataVector::reset() { // must be called with a lock Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); _dontUseSkipAccel = false; if (dataSource()) { SPF = dataInfo(_field).samplesPerFrame; } F0 = NF = 0; resize(0); _numSamples = 0; _dirty = true; _resetFieldMetadata(); Object::reset(); } void DataVector::checkIntegrity() { if (DoSkip && Skip < 1) { Skip = 1; } if (_dirty) { reset(); } // if it looks like we have a new file, reset const DataInfo info = dataInfo(_field); if (dataSource() && (SPF != info.samplesPerFrame || info.frameCount < NF)) { reset(); } // check for illegal NF and F0 values if (ReqNF < 1 && ReqF0 < 0) { ReqF0 = 0; // for this illegal case, read the whole file } if (ReqNF == 1) { ReqNF = 2; } } // Some things to consider about the following routine... // Frames: // Some data sources have data devided into frames. Each field // has a fixed number of samples per frame. For some (eg, ascii files) // each frame has 1 sample. For others (eg, dirfiles) you may have more. // Different fields in the same data source may have different samples per frame. // Within a data source, it is assumed that the first sample of each frame is // simultaneous between fields. // Last Frame Read: // Only read the first sample of the last frame read, in cases where there are more // than one sample per frame. This allows for more sensible association of vectors // into curves, when the X and Y vectors have different numbers of samples per frame. // The rule is that we assume is that the first sample of each frame is simultaneous. // Skip reading: // -'Skip' means read 1 sample each 'Skip' frames (not read one sample, // then skip 'Skip' samples or something else). // -In order that the data are not re-drawn each time a new sample arrives, and to // ensure the re-usability (via shifting) of previously read data, and to make a // region of data look the same regardless of the chouse of f0, all samples // read with skip enabled are read on 'skip boundries'... ie, the first samples of // frame 0, Skip, 2*Skip... N*skip, and never M*Skip+1. void DataVector::internalUpdate() { int i, k, shift, n_read=0; int ave_nread; int new_f0, new_nf; bool start_past_eof = false; if (dataSource()) { dataSource()->writeLock(); } else { return; } const DataInfo info = dataInfo(_field); checkIntegrity(); if (DoSkip && Skip < 2 && SPF == 1) { DoSkip = false; } // set new_nf and new_f0 int fc = info.frameCount; if (ReqNF < 1) { // read to end of file new_f0 = ReqF0; new_nf = fc - new_f0; } else if (ReqF0 < 0) { // count back from end of file new_nf = fc; if (new_nf > ReqNF) { new_nf = ReqNF; } new_f0 = fc - new_nf; } else { new_f0 = ReqF0; new_nf = ReqNF; if (new_f0 + new_nf > fc) { new_nf = fc - new_f0; } if (new_nf <= 0) { // Tried to read starting past the end. new_f0 = 0; new_nf = 1; start_past_eof = true; } } if (DoSkip) { // change new_f0 and new_nf so they both lie on skip boundaries if (new_f0 != 0) { new_f0 = ((new_f0-1)/Skip+1)*Skip; } new_nf = (new_nf/Skip)*Skip; } // shift vector if necessary if (new_f0 < F0 || new_f0 >= F0 + NF) { // No useful data around. reset(); } else { // shift stuff rather than re-read if (DoSkip) { shift = (new_f0 - F0)/Skip; NF -= (new_f0 - F0); _numSamples = NF/Skip; } else { shift = SPF*(new_f0 - F0); NF -= (new_f0 - F0); _numSamples = (NF-1)*SPF+1; } // FIXME: use memmove() for (i = 0; i < _numSamples; i++) { _v[i] = _v[i+shift]; } } if (DoSkip) { // reallocate V if necessary if (new_nf / Skip != _size) { bool rc = resize(new_nf/Skip); if (!rc) { // FIXME: handle failed resize } } // FIXME: // -skip acceleration is not supported by any current data sources. // -there is no API implemented to report if a data source implements skip accel // so: for now, just say it isn't supported here. Fix if we ever implement a data source // where skip accel is important (eg, planck HFI...) _dontUseSkipAccel = true; if (!_dontUseSkipAccel) { int rc; int lastRead = -1; if (DoAve) { // We don't support boxcar inside data sources yet. _dontUseSkipAccel = true; } else { rc = readField(_v + _numSamples, _field, new_f0, (new_nf - NF)/Skip, Skip, &lastRead); if (rc != -9999) { if (rc >= 0) { n_read = rc; } else { n_read = 0; } } else { _dontUseSkipAccel = true; } } } if (_dontUseSkipAccel) { n_read = 0; /** read each sample from the File */ double *t = _v + _numSamples; int new_nf_Skip = new_nf - Skip; if (DoAve) { for (i = NF; new_nf_Skip >= i; i += Skip) { /* enlarge AveReadBuf if necessary */ if (N_AveReadBuf < Skip*SPF) { N_AveReadBuf = Skip*SPF; AveReadBuf = static_cast(realloc(AveReadBuf, N_AveReadBuf*sizeof(double))); if (!AveReadBuf) { // FIXME: handle failed resize } } ave_nread = readField(AveReadBuf, _field, new_f0+i, Skip); for (k = 1; k < ave_nread; k++) { AveReadBuf[0] += AveReadBuf[k]; } if (ave_nread > 0) { *t = AveReadBuf[0]/double(ave_nread); n_read++; } ++t; } } else { for (i = NF; new_nf_Skip >= i; i += Skip) { n_read += readField(t++, _field, new_f0 + i, -1); } } } } else { // reallocate V if necessary if ((new_nf - 1)*SPF + 1 != _size) { bool rc = resize((new_nf - 1)*SPF + 1); if (!rc) { // FIXME: handle failed resize abort(); } } if (NF > 0) { NF--; /* last frame read was only partially read... */ } // read the new data from file if (start_past_eof) { _v[0] = NOPOINT; n_read = 1; } else if (info.samplesPerFrame > 1) { int safe_nf = (new_nf>0 ? new_nf : 0); assert(new_f0 + NF >= 0); assert(new_f0 + safe_nf - 1 >= 0); n_read = readField(_v+NF*SPF, _field, new_f0 + NF, safe_nf - NF - 1); n_read += readField(_v+(safe_nf-1)*SPF, _field, new_f0 + safe_nf - 1, -1); } else { assert(new_f0 + NF >= 0); if (new_nf - NF > 0 || new_nf - NF == -1) { n_read = readField(_v+NF*SPF, _field, new_f0 + NF, new_nf - NF); } } } NumNew = _size - _numSamples; NF = new_nf; F0 = new_f0; _numSamples += n_read; // if for some reason (eg, realtime reading an nfs mounted // dirfile) not all of the data was read, the data will never // be read; the samples will be filled in with the last data // point read, and a complete reset will be requested. // This is bad - I think it will be worthwhile // to add blocking w/ timeout to KstFile. // As a first fix, mount all nsf mounted dirfiles with "-o noac" _dirty = false; if (_numSamples != _size && !(_numSamples == 0 && _size == 1)) { _dirty = true; for (i = _numSamples; i < _size; i++) { _v[i] = _v[0]; } } if (NumNew > _size) { NumNew = _size; } if (NumShifted > _size) { NumShifted = _size; } if (dataSource()) { dataSource()->unlock(); } Vector::internalUpdate(); } /** Returns intrinsic samples per frame */ int DataVector::samplesPerFrame() const { return SPF; } int DataVector::fileLength() const { if (dataSource()) { int rc = dataInfo(_field).frameCount; return rc; } return 0; } void DataVector::reload() { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (dataSource()) { dataSource()->writeLock(); dataSource()->reset(); dataSource()->unlock(); reset(); _resetFieldMetadata(); registerChange(); } } void DataVector::_resetFieldMetadata() { _resetFieldScalars(); _resetFieldStrings(); } void DataVector::_resetFieldStrings() { const QMap meta_strings = dataSource()->vector().metaStrings(_field); QStringList fieldStringKeys = _fieldStrings.keys(); // remove field strings that no longer need to exist readLock(); for (int i=0; i it(meta_strings); while (it.hasNext()) { it.next(); QString key = it.key(); StringPtr sp; if (!_fieldStrings.contains(key)) { // insert a new one _strings.insert(key, sp = store()->createObject()); _fieldStrings.insert(key, sp); sp->setProvider(this); sp->setSlaveName(key); } else { // find it sp = _fieldStrings[key]; } sp->setValue(it.value()); } unlock(); } void DataVector::_resetFieldScalars() { const QMap meta_scalars = dataSource()->vector().metaScalars(_field); QStringList fieldScalarKeys = _fieldScalars.keys(); // remove field scalars that no longer need to exist readLock(); for (int i=0; i it(meta_scalars); while (it.hasNext()) { it.next(); QString key = it.key(); ScalarPtr sp; if (!_fieldScalars.contains(key)) { // insert a new one _scalars.insert(key, sp = store()->createObject()); _fieldScalars.insert(key, sp); sp->setProvider(this); sp->setSlaveName(key); } else { // find it sp = _fieldScalars[key]; } sp->setValue(it.value()); } unlock(); } PrimitivePtr DataVector::makeDuplicate() const { Q_ASSERT(store()); DataVectorPtr vector = store()->createObject(); vector->writeLock(); vector->change(dataSource(), _field, ReqF0, ReqNF, Skip, DoSkip, DoAve); if (descriptiveNameIsManual()) { vector->setDescriptiveName(descriptiveName()); } vector->registerChange(); vector->unlock(); return kst_cast(vector); } QString DataVector::_automaticDescriptiveName() const { QString name; name = _field; // un-escape escaped special characters so they aren't escaped 2x. name.replace("\\_", "_").replace("\\^","^").replace("\\[", "[").replace("\\]", "]"); // now escape the special characters. name.replace('_', "\\_").replace('^', "\\^").replace('[', "\\[").replace(']', "\\]"); return name; } QString DataVector::descriptionTip() const { QString IDstring; //QString range_string; IDstring = i18n( "Data Vector: %1\n" " %2\n" " Field: %3" ).arg(Name()).arg(dataSource()->fileName()).arg(_field); if (countFromEOF()) { IDstring += i18n("\n Last %1 frames.").arg(numFrames()); } else if (readToEOF()) { IDstring += i18n("\n Frame %1 to end.").arg(startFrame()); } else { IDstring += i18n("\n %1 Frames starting at %2.").arg(numFrames()).arg(startFrame()); } if (skip()) { if (!doAve()) { IDstring+=i18n("\n Read 1 sample per %1 frames.").arg(skip()); } else { IDstring+=i18n("\n Average each %1 frames.").arg(skip()); } } return IDstring; } QString DataVector::propertyString() const { return i18n("%2 F0: %3 N: %4 of %1").arg(dataSource()->fileName()).arg(_field).arg(startFrame()).arg(numFrames()); } int DataVector::readField(double *v, const QString& field, int s, int n, int skip, int *lastFrameRead) { ReadInfo par = {v, s, n, skip, lastFrameRead}; return dataSource()->vector().read(field, par); } const DataVector::DataInfo DataVector::dataInfo(const QString& field) const { dataSource()->readLock(); const DataInfo info = dataSource()->vector().dataInfo(field); dataSource()->unlock(); return info; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/objectlist.h000644 001750 001750 00000002516 11544160210 017261 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OBJECTLIST_H #define OBJECTLIST_H #include #include #include "rwlock.h" #include "sharedptr.h" namespace Kst { template class ObjectList : public QList > { #if QT_VERSION < 0x040500 public: void append(const SharedPtr& ptr) { QList >::append(ptr); } void append(const ObjectList& list) { foreach(const SharedPtr& ptr, list) { QList >::append(ptr); } } #endif }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/scalar.cpp000644 001750 001750 00000006600 11544160210 016715 0ustar00synthsynth000000 000000 /*************************************************************************** scalar.cpp - the base scalar type ------------------- begin : March 24, 2003 copyright : (C) 2003 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include "kst_i18n.h" #include "scalar.h" namespace Kst { const QString Scalar::staticTypeString = I18N_NOOP("Scalar"); const QString Scalar::staticTypeTag = I18N_NOOP("scalar"); /** Create the base scalar */ Scalar::Scalar(ObjectStore *store) : Primitive(store, 0L), _value(0.0), _orphan(false), _displayable(true), _editable(false) { _initializeShortName(); } void Scalar::_initializeShortName() { _shortName = 'X'+QString::number(_xnum); if (_xnum>max_xnum) max_xnum = _xnum; _xnum++; } Scalar::~Scalar() { //qDebug() << "scalar destructor for: " << Name(); } const QString& Scalar::typeString() const { return staticTypeString; } void Scalar::internalUpdate() { // do nothing } void Scalar::save(QXmlStreamWriter &s) { if (provider()) { return; } s.writeStartElement("scalar"); if (_orphan) { s.writeAttribute("orphan", "true"); } if (_editable) { s.writeAttribute("editable", "true"); } s.writeAttribute("value", QString::number(value())); saveNameInfo(s, XNUM); s.writeEndElement(); } Scalar& Scalar::operator=(double v) { setValue(v); return *this; } void Scalar::setValue(double inV) { writeLock(); if (_value != inV) { _value = inV; registerChange(); } unlock(); } QString Scalar::label() const { return QString::number(_value); } double Scalar::value() const { return _value; } bool Scalar::orphan() const { return _orphan; } void Scalar::setOrphan(bool orphan) { _orphan = orphan; } bool Scalar::displayable() const { return _displayable; } void Scalar::setDisplayable(bool displayable) { _displayable = displayable; } bool Scalar::editable() const { return _editable; } void Scalar::setEditable(bool editable) { _editable = editable; } QString Scalar::descriptionTip() const { if (_provider) { return i18n("Scalar: %1 = %2\n%3").arg(Name()).arg(value()).arg(_provider->descriptionTip()); } else { return i18n("Scalar: %1 = %2").arg(Name()).arg(value()); } } QString Scalar::_automaticDescriptiveName() const { if (_orphan) { return QString::number(value()); } else { return Primitive::_automaticDescriptiveName(); } } QString Scalar::sizeString() const { return QString("1"); } QString Scalar::propertyString() const { return i18n("Value: %1").arg(value()); } } // vim: et ts=2 sw=2 kst-2.0.3/src/libkst/stdinsource.cpp000644 001750 001750 00000007744 11544160210 020024 0ustar00synthsynth000000 000000 /*************************************************************************** stdinsource.cpp - data source for stdin ------------------- begin : Fri Oct 31 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kst_i18n.h" #include "config.h" #include "stdinsource.h" #include #include #include #include #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif namespace Kst { const QString StdinSource::staticTypeString = I18N_NOOP("Stdin Data Source"); StdinSource::StdinSource(ObjectStore *store, QSettings *cfg) : DataSource(store, cfg, "stdin", "stdin") { _file = new QTemporaryFile; _filename = _file->fileName(); // Unfortunately we have to update here. stdin is a special case. update(); _src = DataSource::loadSource(this->store(), _filename, "ASCII"); if (_src && _src->isValid()) { _valid = true; } } StdinSource::~StdinSource() { _file->close(); delete _file; _file = 0L; } const QString& StdinSource::typeString() const { return staticTypeString; } Object::UpdateType StdinSource::internalDataSourceUpdate() { if (!_valid) { _src = DataSource::loadSource(store(), _filename, "ASCII"); if (_src && _src->isValid()) { _valid = true; } else { return NoChange; } } fd_set rfds; struct timeval tv; int retval; char instr[4097]; int i = 0; bool new_data = false; bool got_some = false; int handle = _file->handle(); FILE *fp = fdopen(handle, "w+"); if (!fp) { return Object::NO_CHANGE; } do { /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to 0 seconds. */ tv.tv_sec = 0; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); new_data = false; if (retval > 0) { char *fgs = fgets(instr, 4096, stdin); if (fgs && fp) { got_some = true; fputs(instr, fp); new_data = true; } } } while (++i < 100000 && new_data); fclose(fp); if (got_some && _src) { return _src->update(); } return NoChange; } int StdinSource::readField(double *v, const QString& field, int s, int n) { if (isValid()) { return _src->readField(v, field, s, n); } return -1; } bool StdinSource::isValidField(const QString& field) const { if (isValid()) { return _src->isValidField(field); } return false; } int StdinSource::samplesPerFrame(const QString& field) { if (isValid()) { return _src->samplesPerFrame(field); } return 0; } int StdinSource::frameCount(const QString& field) const { if (isValid()) { return _src->frameCount(field); } return 0; } QString StdinSource::fileType() const { if (isValid()) { return _src->fileType(); } return QString::null; } void StdinSource::save(QXmlStreamWriter &s) { if (isValid()) { return _src->save(s); } DataSource::save(s); } bool StdinSource::isValid() const { return _valid && _src && _src->isValid(); } bool StdinSource::isEmpty() const { return !isValid() || _src->isEmpty(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/kst_export.h000644 001750 001750 00000002475 11544160210 017325 0ustar00synthsynth000000 000000 /*************************************************************************** kst_export.h ------------------- begin : Feb 07 2005 copyright : (C) 2005 Dirk Mueller email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_EXPORT_H #define KST_EXPORT_H #include #if (defined(Q_OS_WIN32) || defined(Q_OS_WIN64)) # if defined(BUILD_KSTCORE) # define KSTCORE_EXPORT Q_DECL_EXPORT # else # define KSTCORE_EXPORT Q_DECL_IMPORT # endif #else # define KSTCORE_EXPORT #endif #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/generatedmatrix.h000644 001750 001750 00000003766 11544160210 020312 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GENERATEDMATRIX_H #define GENERATEDMATRIX_H #include "matrix.h" #include "kst_export.h" namespace Kst { class KSTCORE_EXPORT GeneratedMatrix : public Matrix { Q_OBJECT public: virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; virtual void save(QXmlStreamWriter &xml); void change(uint nX, uint nY, double minX, double minY, double stepX, double stepY, double gradZMin, double gradZMax, bool xDirection); // return gradient min and maxes in order double gradZMin() { return _gradZMin; } double gradZMax() { return _gradZMax; } bool xDirection() { return _xDirection; } protected: GeneratedMatrix(ObjectStore *store); friend class ObjectStore; private: double _gradZMin; double _gradZMax; bool _xDirection; }; typedef SharedPtr GeneratedMatrixPtr; typedef ObjectList GeneratedMatrixList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/stdinsource.h000644 001750 001750 00000003713 11544160210 017461 0ustar00synthsynth000000 000000 /*************************************************************************** stdin.h - data source plugin for stdin ------------------- begin : Fri Oct 31 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STDINSRC_H #define STDINSRC_H #include "datasource.h" #include "kst_export.h" class QTemporaryFile; namespace Kst { class KST_EXPORT StdinSource : public DataSource { Q_OBJECT public: StdinSource(ObjectStore *store, QSettings *cfg); virtual ~StdinSource(); virtual const QString& typeString() const; static const QString staticTypeString; virtual Object::UpdateType internalDataSourceUpdate(); virtual int readField(double *v, const QString &field, int s, int n); virtual bool isValidField(const QString &field) const; virtual int samplesPerFrame(const QString &field); virtual int frameCount(const QString& field = QString::null) const; virtual QString fileType() const; virtual void save(QXmlStreamWriter& s); virtual bool isValid() const; virtual bool isEmpty() const; private: DataSourcePtr _src; QTemporaryFile *_file; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/primitivefactory.h000644 001750 001750 00000002773 11544160210 020524 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PRIMITIVEFACTORY_H #define PRIMITIVEFACTORY_H #include #include #include "primitive.h" #include "kst_export.h" namespace Kst { class PrimitiveFactory { public: PrimitiveFactory(); virtual ~PrimitiveFactory(); // This takes ownership static void registerFactory(const QString& node, PrimitiveFactory *factory); static void registerFactory(const QStringList& nodes, PrimitiveFactory *factory); KSTCORE_EXPORT static PrimitivePtr parse(ObjectStore *store, QXmlStreamReader& stream); virtual PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream) = 0; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/objectmap.h000644 001750 001750 00000003177 11544160210 017067 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OBJECTMAP_H #define OBJECTMAP_H #include #include #include "sharedptr.h" namespace Kst { template class ObjectMap : public QHash > { public: typedef QHash > HashMap; typename HashMap::iterator insert(const QString& key, const SharedPtr& value) { addKey(key); return HashMap::insert(key, value); } SharedPtr& operator[](const QString& key) { addKey(key); return HashMap::operator[](key); } const SharedPtr operator[](const QString& key) const { addKey(key); return HashMap::operator[](key); } void addKey(const QString& key) const { if (!ordered.contains(key)) { ordered << key; } } mutable QStringList ordered; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/editablevector.cpp000644 001750 001750 00000004775 11544160210 020457 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // use KCodecs::base64Encode() in kmdcodecs.h // Create QDataStream into a QByteArray // qCompress the bytearray #include #include "editablevector.h" #include "debug.h" #include "kst_i18n.h" namespace Kst { const QString EditableVector::staticTypeString = I18N_NOOP("Editable Vector"); const QString EditableVector::staticTypeTag = I18N_NOOP("editablevector"); EditableVector::EditableVector(ObjectStore *store) : Vector(store) { _editable = true; _saveable = true; _saveData = true; } const QString& EditableVector::typeString() const { return staticTypeString; } void EditableVector::setSaveData(bool save) { Q_UNUSED(save) } /** Save vector information */ void EditableVector::save(QXmlStreamWriter &s) { s.writeStartElement("editablevector"); saveNameInfo(s, VNUM|XNUM); if (_saveData) { QByteArray qba(length()*sizeof(double), '\0'); QDataStream qds(&qba, QIODevice::WriteOnly); for (int i = 0; i < length(); i++) { qds << _v[i]; } s.writeTextElement("data", qCompress(qba).toBase64()); } s.writeEndElement(); } QString EditableVector::_automaticDescriptiveName() const { QString name("("); if (length()>=1) { name += QString::number(_v[0]); } if (length()>=2) { name += ", " + QString::number(_v[1]); } if (length()>=3) { name += ", ..."; } name += ')'; return name; } QString EditableVector::descriptionTip() const { return i18n("Editable Vector: %1\n" " %2 values").arg(Name()).arg(length()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/logevents.h000644 001750 001750 00000002676 11544160210 017134 0ustar00synthsynth000000 000000 /*************************************************************************** logevents.h ---------------- begin : Apr 01 2005 copyright : (C) 2005 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LOGEVENTS_H #define LOGEVENTS_H #include "debug.h" #include "events.h" //Added by qt3to4: #include namespace Kst { class LogEvent : public QEvent { public: enum LogEventType { Unknown = 0, LogAdded, LogCleared }; LogEvent(LogEventType et) : QEvent(QEvent::Type(EventTypeLog)), _eventType(et) {} virtual ~LogEvent() {} LogEventType _eventType; Debug::LogMessage _msg; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datamatrix.cpp000644 001750 001750 00000041657 11544160210 017621 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include "kst_i18n.h" #include "datacollection.h" #include "debug.h" #include "datamatrix.h" #include "objectstore.h" // xStart, yStart < 0 count from end // xNumSteps, yNumSteps < 1 read to end namespace Kst { const QString DataMatrix::staticTypeString = I18N_NOOP("Data Matrix"); const QString DataMatrix::staticTypeTag = I18N_NOOP("datamatrix"); DataMatrix::DataInfo::DataInfo() : samplesPerFrame(-1), xSize(-1), ySize(-1), invertXHint(false), invertYHint(false) { } DataMatrix::DataMatrix(ObjectStore *store) : Matrix(store), DataPrimitive(this) { } const QString& DataMatrix::typeString() const { return staticTypeString; } void DataMatrix::save(QXmlStreamWriter &xml) { if (dataSource()) { xml.writeStartElement(staticTypeTag); saveFilename(xml); xml.writeAttribute("field", _field); xml.writeAttribute("reqxstart", QString::number(_reqXStart)); xml.writeAttribute("reqystart", QString::number(_reqYStart)); xml.writeAttribute("reqnx", QString::number(_reqNX)); xml.writeAttribute("reqny", QString::number(_reqNY)); xml.writeAttribute("doave", QVariant(_doAve).toString()); xml.writeAttribute("doskip", QVariant(_doSkip).toString()); xml.writeAttribute("skip", QString::number(_skip)); xml.writeAttribute("xmin", QString::number(minX())); xml.writeAttribute("ymin", QString::number(minY())); xml.writeAttribute("xstep", QString::number(xStepSize())); xml.writeAttribute("ystep", QString::number(yStepSize())); saveNameInfo(xml, VNUM|MNUM|XNUM); xml.writeEndElement(); } } DataMatrix::~DataMatrix() { } void DataMatrix::change(DataSourcePtr file, const QString &field, int xStart, int yStart, int xNumSteps, int yNumSteps, bool doAve, bool doSkip, int skip, double minX, double minY, double stepX, double stepY) { KstWriteLocker l(this); commonConstructor(file, field, xStart, yStart, xNumSteps, yNumSteps, doAve, doSkip, skip, minX, minY, stepX, stepY); } void DataMatrix::changeFrames(int xStart, int yStart, int xNumSteps, int yNumSteps, bool doAve, bool doSkip, int skip, double minX, double minY, double stepX, double stepY) { KstWriteLocker l(this); commonConstructor(dataSource(), _field, xStart, yStart, xNumSteps, yNumSteps, doAve, doSkip, skip, minX, minY, stepX, stepY); } int DataMatrix::reqXStart() const { return _reqXStart; } int DataMatrix::reqYStart() const { return _reqYStart; } int DataMatrix::reqXNumSteps() const { return _reqNX; } int DataMatrix::reqYNumSteps() const { return _reqNY; } /* QString DataMatrix::filename() const { if (dataSource()) { return QString(dataSource()->fileName()); } return QString::null; } */ const QString& DataMatrix::field() const { return _field; } bool DataMatrix::xReadToEnd() const { return (_reqNX <= 0); } bool DataMatrix::yReadToEnd() const { return (_reqNY <= 0); } bool DataMatrix::xCountFromEnd() const { return (_reqXStart < 0); } bool DataMatrix::yCountFromEnd() const { return (_reqYStart < 0); } QString DataMatrix::label() const { bool ok; QString returnLabel; _field.toInt(&ok); if (ok && dataSource()) { dataSource()->readLock(); if (dataSource()->fileType() == "ASCII") { returnLabel = i18n("Column %1").arg(_field); } else { returnLabel = _field; } dataSource()->unlock(); } else { returnLabel = _field; } return returnLabel; } bool DataMatrix::isValid() const { if (dataSource()) { dataSource()->readLock(); bool fieldValid = dataSource()->matrix().isValid(_field); dataSource()->unlock(); return fieldValid; } return false; } bool DataMatrix::checkValidity(const DataSourcePtr& ds) const { if (ds) { ds->readLock(); bool rc = ds->matrix().isValid(_field); ds->unlock(); return rc; } return false; } void DataMatrix::doUpdateSkip(int realXStart, int realYStart) { // since we are skipping, we don't need all the pixels // also, samples per frame is always 1 with skipping _nX = _nX / _skip; _nY = _nY / _skip; // resize the array if necessary int requiredSize = _nX * _nY; if (requiredSize != _zSize) { bool resizeOK = resizeZ(requiredSize); if (!resizeOK) { abort(); // FIXME: what to do? } } // return data from readMatrix MatrixData matData; if (!_doAve) { // try to use the datasource's read with skip function - it will automatically // enlarge each pixel to correct for the skipping matData.z=_z; _NS = readMatrix(&matData, _field, realXStart, realYStart, _nX, _nY, _skip); // -9999 means the skipping function is not supported by datasource if (_NS != -9999) { // set the recommended translate and scaling, and return _minX = matData.xMin; _minY = matData.yMin; _stepX = matData.xStepSize; _stepY = matData.yStepSize; } } // the skipping function is not supported by datasource; we need to manually skip if (_doAve) { // boxcar filtering is not supported by datasources currently; need to manually average if (_aveReadBufferSize < _samplesPerFrameCache*_skip*_samplesPerFrameCache*_skip) { _aveReadBufferSize = _samplesPerFrameCache*_skip*_samplesPerFrameCache*_skip; _aveReadBuffer = static_cast(realloc(_aveReadBuffer, _aveReadBufferSize*sizeof(double))); } _NS = 0; bool first = true; matData.z = _aveReadBuffer; double* zPos = _z; for (int i = 0; i < _nX; i++) { for (int j = 0; j < _nY; j++) { // read one buffer size in readMatrix(&matData, _field, realXStart + _skip*i, realYStart + _skip*j, _skip, _skip, -1); // take average of the buffer double bufferAverage = 0; for (int k = 0; k < _samplesPerFrameCache*_skip*_samplesPerFrameCache*_skip; k++) { bufferAverage += _aveReadBuffer[k]; } bufferAverage = bufferAverage / _aveReadBufferSize; // insert the average into the matrix *zPos = bufferAverage; zPos++; _NS++; if (first) { _minX = matData.xMin; _minY = matData.yMin; _stepX = matData.xStepSize * _skip * _samplesPerFrameCache; _stepY = matData.yStepSize * _skip * _samplesPerFrameCache; first = false; } } } } else { _NS = 0; bool first = true; for (int i = 0; i < _nX; i++) { for (int j = 0; j < _nY; j++) { // read one sample int samples = readMatrix(&matData, _field, realXStart + _skip*i, realYStart + _skip*j, -1, -1, -1); matData.z += samples; _NS += samples; if (first) { _minX = matData.xMin; _minY = matData.yMin; _stepX = matData.xStepSize * _skip * _samplesPerFrameCache; _stepY = matData.yStepSize * _skip * _samplesPerFrameCache; first = false; } } } } } void DataMatrix::doUpdateNoSkip(int realXStart, int realYStart) { // resize _z if necessary int requiredSize = _nX*_nY*_samplesPerFrameCache*_samplesPerFrameCache; if (requiredSize != _zSize) { bool resizeOK = resizeZ(requiredSize); if (!resizeOK) { abort(); // FIXME: what to do? } } // read new data from file MatrixData matData; matData.z=_z; _NS = readMatrix(&matData, _field, realXStart, realYStart, _nX, _nY, -1); // set the recommended translate and scaling _minX = matData.xMin; _minY = matData.yMin; _stepX = matData.xStepSize; _stepY = matData.yStepSize; } qint64 DataMatrix::minInputSerial() const { if (dataSource()) { return (dataSource()->serial()); } return LLONG_MAX; } qint64 DataMatrix::minInputSerialOfLastChange() const { if (dataSource()) { return (dataSource()->serialOfLastChange()); } return LLONG_MAX; } void DataMatrix::_resetFieldMetadata() { _resetFieldScalars(); _resetFieldStrings(); } void DataMatrix::_resetFieldScalars() { } void DataMatrix::_resetFieldStrings() { const QMap meta_strings = dataSource()->matrix().metaStrings(_field); QStringList fieldStringKeys = _fieldStrings.keys(); // remove field strings that no longer need to exist readLock(); for (int i=0; i it(meta_strings); while (it.hasNext()) { it.next(); QString key = it.key(); StringPtr sp; if (!_fieldStrings.contains(key)) { // insert a new one _fieldStrings.insert(key, sp = store()->createObject()); sp->setProvider(this); sp->setSlaveName(key); } else { // find it sp = _fieldStrings[key]; } sp->setValue(it.value()); } unlock(); } LabelInfo DataMatrix::xLabelInfo() const { LabelInfo label_info; if (_fieldStrings.contains("x_quantity")) { label_info.quantity = _fieldStrings.value("x_quantity")->value(); } else { label_info.quantity = QString(); } if (_fieldStrings.contains("x_units")) { label_info.units = _fieldStrings.value("x_units")->value(); } else { label_info.units = QString(); } label_info.name = QString(); return label_info; } LabelInfo DataMatrix::yLabelInfo() const { LabelInfo label_info; if (_fieldStrings.contains("y_quantity")) { label_info.quantity = _fieldStrings.value("y_quantity")->value(); } else { label_info.quantity = QString(); } if (_fieldStrings.contains("y_units")) { label_info.units = _fieldStrings.value("y_units")->value(); } else { label_info.units = QString(); } label_info.name = QString(); return label_info; } LabelInfo DataMatrix::titleInfo() const { LabelInfo label_info; if (_fieldStrings.contains("z_quantity")) { label_info.quantity = _fieldStrings.value("z_quantity")->value(); } else { label_info.quantity = QString(); } if (_fieldStrings.contains("z_units")) { label_info.units = _fieldStrings.value("z_units")->value(); } else { label_info.units = QString(); } label_info.name = _field; return label_info; } void DataMatrix::internalUpdate() { if (dataSource()) { dataSource()->writeLock(); } else { return; } // see if we can turn off skipping (only check if skipping enabled) if (_doSkip && _samplesPerFrameCache == 1 && _skip < 2) { _doSkip = false; } // first get the real start and end range int realXStart; int realYStart; const DataInfo info = dataSource()->matrix().dataInfo(_field); int xSize = info.xSize; int ySize = info.ySize; _invertXHint = info.invertXHint; _invertYHint = info.invertYHint; if (_reqXStart < 0) { // counting from end realXStart = xSize - _reqNX; } else { realXStart = _reqXStart; } if (_reqYStart < 0) { // counting from end realYStart = ySize - _reqNY; } else { realYStart = _reqYStart; } if (_reqNX < 1) { // read to end _nX = xSize - _reqXStart; } else { _nX = _reqNX; } if (_reqNY < 1) { // read to end _nY = ySize - _reqYStart; } else { _nY = _reqNY; } // now do some sanity checks if (realXStart > xSize - 1) { realXStart = xSize - 1; } if (realXStart < 0) { realXStart = 0; } if (realYStart > ySize - 1) { realYStart = ySize - 1; } if (realYStart < 0) { realYStart = 0; } if (_nX < 1) { _nX = 1; } if (realXStart + _nX > xSize) { _nX = xSize - realXStart; } if (_nY < 1) { _nY = 1; } if (realYStart + _nY > ySize) { _nY = ySize - realYStart; } // do the reading; skip or non-skip version if (_doSkip) { doUpdateSkip(realXStart, realYStart); } else { doUpdateNoSkip(realXStart, realYStart); } // remember these as the last updated range _lastXStart = realXStart; _lastYStart = realYStart; _lastNX = _nX; _lastNY = _nY; _lastDoAve = _doAve; _lastDoSkip = _doSkip; _lastSkip = _skip; dataSource()->unlock(); Matrix::internalUpdate(); } void DataMatrix::reload() { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (dataSource()) { dataSource()->writeLock(); dataSource()->reset(); dataSource()->unlock(); reset(); } } PrimitivePtr DataMatrix::makeDuplicate() const { Q_ASSERT(store()); DataMatrixPtr matrix = store()->createObject(); matrix->writeLock(); matrix->change(dataSource(), _field, _reqXStart, _reqYStart, _reqNX, _reqNY, _doAve, _doSkip, _skip, _minX, _minY, _stepX, _stepY); if (descriptiveNameIsManual()) { matrix->setDescriptiveName(descriptiveName()); } matrix->registerChange(); matrix->unlock(); return kst_cast(matrix); } void DataMatrix::commonConstructor(DataSourcePtr in_file, const QString &field, int reqXStart, int reqYStart, int reqNX, int reqNY, bool doAve, bool doSkip, int skip, double minX, double minY, double stepX, double stepY) { _reqXStart = reqXStart; _reqYStart = reqYStart; _reqNX = reqNX; _reqNY = reqNY; setDataSource(in_file); _field = field; _doAve = doAve; _doSkip = doSkip; _skip = skip; _minX = minX; _minY = minY; _stepX = stepX; _stepY = stepY; _invertXHint = false; _invertYHint = false; _saveable = true; _editable = true; if (!dataSource()) { Debug::self()->log(i18n("Data file for matrix %1 was not opened.", Name()), Debug::Warning); } else { const DataInfo info = dataSource()->matrix().dataInfo(_field); _samplesPerFrameCache = info.samplesPerFrame; _invertXHint = info.invertXHint; _invertYHint = info.invertYHint; } _aveReadBuffer = 0L; _aveReadBufferSize = 0; _lastXStart = 0; _lastYStart = 0; _lastNX = 1; _lastNY = 1; _lastDoAve = false; _lastDoSkip = false;; _lastSkip = 1; _resetFieldMetadata(); } void DataMatrix::reset() { // must be called with a lock Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (dataSource()) { const DataInfo info = dataSource()->matrix().dataInfo(_field); _samplesPerFrameCache = info.samplesPerFrame; _invertXHint = info.invertXHint; _invertYHint = info.invertYHint; } resizeZ(0); _NS = 0; _nX = 1; _nY = 0; _resetFieldMetadata(); } bool DataMatrix::doSkip() const { return _doSkip; } bool DataMatrix::doAverage() const { return _doAve; } int DataMatrix::skip() const { return _skip; } void DataMatrix::changeFile(DataSourcePtr in_file) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (!in_file) { Debug::self()->log(i18n("Data file for vector %1 was not opened.", Name()), Debug::Warning); } setDataSource(in_file); if (dataSource()) { dataSource()->writeLock(); } reset(); if (dataSource()) { dataSource()->unlock(); } } QString DataMatrix::_automaticDescriptiveName() const{ QString name = field(); // un-escape escaped special characters so they aren't escaped 2x. name.replace("\\_", "_").replace("\\^","^").replace("\\[", "[").replace("\\]", "]"); // now escape the special characters. name.replace('_', "\\_").replace('^', "\\^").replace('[', "\\[").replace(']', "\\]"); return name; } QString DataMatrix::descriptionTip() const { return i18n( "Data Matrix: %1\n" " %2\n" " Field: %3\n" " %4 x %5" ).arg(Name()).arg(dataSource()->fileName()).arg(field()).arg(_nX).arg(_nY); } QString DataMatrix::propertyString() const { return i18n("%1 of %2").arg(field()).arg(dataSource()->fileName()); } int DataMatrix::readMatrix(MatrixData* data, const QString& matrix, int xStart, int yStart, int xNumSteps, int yNumSteps, int skip) { ReadInfo p = { data, xStart, yStart, xNumSteps, yNumSteps, skip}; return dataSource()->matrix().read(matrix, p); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/vectorfactory.h000644 001750 001750 00000003375 11544160210 020015 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VECTORFACTORY_H #define VECTORFACTORY_H #include "primitivefactory.h" namespace Kst { class VectorFactory : public PrimitiveFactory { public: VectorFactory(); ~VectorFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; class GeneratedVectorFactory : public PrimitiveFactory { public: GeneratedVectorFactory(); ~GeneratedVectorFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; class EditableVectorFactory : public PrimitiveFactory { public: EditableVectorFactory(); ~EditableVectorFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; class DataVectorFactory : public PrimitiveFactory { public: DataVectorFactory(); ~DataVectorFactory(); PrimitivePtr generatePrimitive(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/editablematrix.cpp000644 001750 001750 00000004501 11544160210 020444 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // use KCodecs::base64Encode() in kmdcodecs.h // Create QDataStream into a QByteArray // qCompress the bytearray #include "editablematrix.h" #include "debug.h" #include #include #include "kst_i18n.h" namespace Kst { const QString EditableMatrix::staticTypeString = I18N_NOOP("Editable Matrix"); const QString EditableMatrix::staticTypeTag = I18N_NOOP("editablematrix"); EditableMatrix::EditableMatrix(ObjectStore *store) : Matrix(store) { _editable = true; _saveable = true; resizeZ(1, true); } const QString& EditableMatrix::typeString() const { return staticTypeString; } void EditableMatrix::save(QXmlStreamWriter &xml) { QByteArray qba(_zSize*sizeof(double), '\0'); QDataStream qds(&qba, QIODevice::WriteOnly); for (int i = 0; i < _zSize; i++) { qds << _z[i]; } xml.writeStartElement(staticTypeTag); xml.writeAttribute("xmin", QString::number(minX())); xml.writeAttribute("ymin", QString::number(minY())); xml.writeAttribute("nx", QString::number(xNumSteps())); xml.writeAttribute("ny", QString::number(yNumSteps())); xml.writeAttribute("xstep", QString::number(xStepSize())); xml.writeAttribute("ystep", QString::number(yStepSize())); xml.writeTextElement("data", qCompress(qba).toBase64()); saveNameInfo(xml, VNUM|MNUM|XNUM); xml.writeEndElement(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/math_kst.cpp000644 001750 001750 00000001752 11544160210 017265 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "math_kst.h" namespace Kst { #ifdef NAN const double NOPOINT = NAN; #else const double NOPOINT = 0.0/0.0; // NaN #endif } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/updatemanager.cpp000644 001750 001750 00000007245 11544160210 020273 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "updatemanager.h" #include "primitive.h" #include "datasource.h" #include "objectstore.h" #include #include #include #define DEFAULT_MIN_UPDATE_PERIOD 2000 namespace Kst { static UpdateManager *_self = 0; void UpdateManager::cleanup() { delete _self; _self = 0; } UpdateManager *UpdateManager::self() { if (!_self) { _self = new UpdateManager; qAddPostRoutine(cleanup); } return _self; } UpdateManager::UpdateManager() { _serial = 0; _minUpdatePeriod = DEFAULT_MIN_UPDATE_PERIOD; _paused = false; _store = 0; _delayedUpdateScheduled = false; _updateInProgress = false; _time.start(); } UpdateManager::~UpdateManager() { } void UpdateManager::delayedUpdates() { _delayedUpdateScheduled = false; doUpdates(); } void UpdateManager::doUpdates(bool forceImmediate) { if (_delayedUpdateScheduled && !forceImmediate) { return; } if (!_store) { return; } //FIXME: should we just skip updating data sources in this case? if (_paused && !forceImmediate) { return; } int dT = _time.elapsed(); if (((dT<_minUpdatePeriod) || (_updateInProgress)) && (!forceImmediate)) { if (!_delayedUpdateScheduled) { _delayedUpdateScheduled = true; int deferTime = _minUpdatePeriod-dT; if (deferTime <= 0) { deferTime = 20; // if an update is already in progess, wait this long to check again. } QTimer::singleShot(deferTime, this, SLOT(delayedUpdates())); } return; } _updateInProgress = true; _time.restart(); _serial++; int n_updated=0, n_deferred=0, n_unchanged = 0; qint64 retval; // update the datasources foreach (DataSourcePtr ds, _store->dataSourceList()) { ds->writeLock(); retval = ds->objectUpdate(_serial); ds->unlock(); if (retval == Object::Updated) n_updated++; else if (retval == Object::Deferred) n_deferred++; else if (retval == Object::NoChange) n_unchanged++; } //qDebug() << "ds up: " << n_updated << " ds def: " << n_deferred << " n_no: " << n_unchanged; int i_loop = retval = 0; int maxloop = _store->objectList().size(); //qDebug() << "starting update loop. Maxloop: " << maxloop; do { n_updated = n_unchanged = n_deferred = 0; // update data objects foreach (ObjectPtr p, _store->objectList()) { p->writeLock(); retval = p->objectUpdate(_serial); p->unlock(); if (retval == Object::Updated) n_updated++; else if (retval == Object::Deferred) n_deferred++; else if (retval == Object::NoChange) n_unchanged++; } maxloop = qMin(maxloop,n_deferred); //qDebug() << "loop: " << i_loop << " obj up: " << n_updated << " obj def: " << n_deferred << " obj_no: " << n_unchanged; i_loop++; } while ((n_deferred + n_updated > 0) && (i_loop<=maxloop)); emit objectsUpdated(_serial); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/builtinprimitives.cpp000644 001750 001750 00000002632 11544160210 021233 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "builtinprimitives.h" #include "vectorfactory.h" #include "scalarfactory.h" #include "stringfactory.h" #include "matrixfactory.h" namespace Kst { namespace Builtins { void initPrimitives() { new VectorFactory(); new GeneratedVectorFactory(); new EditableVectorFactory(); new DataVectorFactory(); new ScalarFactory(); new DataScalarFactory(); new VScalarFactory(); new StringFactory(); new GeneratedMatrixFactory(); new EditableMatrixFactory(); new DataMatrixFactory(); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/objectlist.cpp000644 001750 001750 00000001577 11544160210 017622 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "objectlist.h" // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/math_kst.h000644 001750 001750 00000007540 11544160210 016733 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // NOTE: only include this from .cpp files #ifndef MATH_KST_H #define MATH_KST_H #include #include #include #include #ifdef __sun #include #endif #include "kst_export.h" namespace Kst { /* ** For systems without NAN, this is a NAN in IEEE double format. ** Code from KDE's kjs libarary. */ #if !defined(NAN) #include static double nan__() { /* work around some strict alignment requirements for double variables on some architectures (e.g. PA-RISC) */ typedef union { unsigned char b[8]; double d; } kjs_double_t; #if Q_BYTE_ORDER == Q_BIG_ENDIAN static const kjs_double_t NaN_Bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } }; #elif defined(arm) static const kjs_double_t NaN_Bytes = { { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 } }; #else static const kjs_double_t NaN_Bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } }; #endif const double NaN = NaN_Bytes.d; return NaN; } #define NAN (Kst::nan__()) #endif /* ** Both Solaris and FreeBSD-current do weird things with the ** isnan() defined in math.h - in particular on FreeBSD it ** gets #undeffed by the C++ math routines later. Use the ** std:: version in those cases. */ #ifdef isnan #define KST_ISNAN(a) isnan(a) #elif defined(__APPLE__) #define KST_ISNAN(a) (a == NAN ? 1 : 0) #else // HUH? Ok let's get rid of the silliness here sometime. #define KST_ISNAN(a) isnan(a) #endif KSTCORE_EXPORT extern const double NOPOINT; inline int d2i(double x) { return int(floor(x+0.5)); } inline bool samePixel(double x1, double x2) { //return (int(floor(x1)) == int(floor(x2))); return (int(x1) == int(x2)); } #if defined(__SVR4) && defined(__sun) inline int isinf(double x) { return x == x && !finite(x); } #endif #ifdef Q_WS_WIN32 #ifndef isnan #define isnan _isnan #endif #ifndef finite #define finite _finite #endif #ifndef M_PI #define M_PI 3.14159265358979323 #endif #ifndef isinf #define isinf !_finite #endif #endif #if 0 #define isnan _isnan #define finite _finite #ifndef M_PI #define M_PI 3.14159265358979323 #endif #define isinf !_finite #endif inline double logXLo(double x, double base = 10.0) { if (base == 10.0) { return x > 0.0 ? log10(x) : -350.0; } else { return x > 0.0 ? log10(x)/log10(base) : -350.0; } } inline double logXHi(double x, double base = 10.0) { if (base == 10.0) { return x > 0.0 ? log10(x) : -340.0; } else { return x > 0.0 ? log10(x)/log10(base) : -340.0; } } inline double logYLo(double x, double base = 10.0) { if (base == 10.0) { return x > 0.0 ? log10(x) : -350.0; } else { return x > 0.0 ? log10(x)/log10(base) : -350.0; } } inline double logYHi(double x, double base = 10.0) { if (base == 10.0) { return x > 0.0 ? log10(x) : -340.0; } else { return x > 0.0 ? log10(x)/log10(base) : -340.0; } } inline double roundDouble (double x) { #ifdef rint return rint(x); #else int i = (int) x; if (x >= 0.0) { return ((x-i) >= 0.5) ? (i + 1) : (i); } else { return (-x+i >= 0.5) ? (i - 1) : (i); } #endif } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datascalar.cpp000644 001750 001750 00000011340 11544160210 017544 0ustar00synthsynth000000 000000 /*************************************************************************** datastscalar.cpp - a scalar from a data source ------------------- begin : September, 2008 copyright : (C) 2008 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include "kst_i18n.h" #include "datascalar.h" #include "debug.h" #include "objectstore.h" namespace Kst { const QString DataScalar::staticTypeString = I18N_NOOP("Data Scalar"); const QString DataScalar::staticTypeTag = I18N_NOOP("datascalar"); /** Create a DataVector: raw data from a file */ DataScalar::DataScalar(ObjectStore *store) : Scalar(store), DataPrimitive(this) { setOrphan(true); } DataScalar::~DataScalar() { } QString DataScalar::_automaticDescriptiveName() const { QString name = _field; // un-escape escaped special characters so they aren't escaped 2x. name.replace("\\_", "_").replace("\\^","^").replace("\\[", "[").replace("\\]", "]"); // now escape the special characters. name.replace('_', "\\_").replace('^', "\\^").replace('[', "\\[").replace(']', "\\]"); return name; } const QString& DataScalar::typeString() const { return staticTypeString; } /** return true if it has a valid file and field, or false otherwise */ bool DataScalar::isValid() const { if (dataSource()) { dataSource()->readLock(); bool rc = dataSource()->scalar().isValid(_field); dataSource()->unlock(); return rc; } return false; } bool DataScalar::checkValidity(const DataSourcePtr& ds) const { if (ds) { ds->readLock(); bool rc = ds->scalar().isValid(_field); ds->unlock(); return rc; } return false; } void DataScalar::change(DataSourcePtr in_file, const QString &in_field) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); _field = in_field; setDataSource(in_file); } void DataScalar::changeFile(DataSourcePtr in_file) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (!in_file) { Debug::self()->log(i18n("Data file for scalar %1 was not opened.", Name()), Debug::Warning); } setDataSource(in_file); } /** Save data scalar information */ void DataScalar::save(QXmlStreamWriter &s) { if (dataSource()) { s.writeStartElement("datascalar"); saveFilename(s); s.writeAttribute("field", _field); saveNameInfo(s, XNUM); s.writeEndElement(); } } /** Update a data Scalar */ void DataScalar::internalUpdate() { if (dataSource()) { dataSource()->writeLock(); ReadInfo readInfo(&_value); dataSource()->scalar().read(_field, readInfo); dataSource()->unlock(); } } PrimitivePtr DataScalar::makeDuplicate() const { Q_ASSERT(store()); DataScalarPtr scalar = store()->createObject(); scalar->writeLock(); scalar->change(dataSource(), _field); if (descriptiveNameIsManual()) { scalar->setDescriptiveName(descriptiveName()); } scalar->registerChange(); scalar->unlock(); return kst_cast(scalar); } qint64 DataScalar::minInputSerial() const { if (dataSource()) { return (dataSource()->serial()); } return LLONG_MAX; } qint64 DataScalar::minInputSerialOfLastChange() const { if (dataSource()) { return (dataSource()->serialOfLastChange()); } return LLONG_MAX; } QString DataScalar::descriptionTip() const { QString IDstring; IDstring = i18n( "Data Scalar: %1 = %4\n" " %2\n" " Field: %3" ).arg(Name()).arg(dataSource()->fileName()).arg(_field).arg(value()); return IDstring; } QString DataScalar::propertyString() const { return i18n("%2 of %1 = %3").arg(dataSource()->fileName()).arg(_field).arg(value()); } void DataScalar::reload() { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (dataSource()) { dataSource()->writeLock(); dataSource()->reset(); dataSource()->unlock(); reset(); registerChange(); } } void DataScalar::reset() { ReadInfo readInfo(&_value); dataSource()->scalar().read(_field, readInfo); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/objectstore.h000644 001750 001750 00000007654 11544160210 017452 0ustar00synthsynth000000 000000 /*************************************************************************** objectstore.h: store of Objects ------------------- begin : November 22, 2006 copyright : (C) 2006-2010 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OBJECTSTORE_H #define OBJECTSTORE_H #include #include "kst_export.h" #include "kst_i18n.h" #include "object.h" #include "objectlist.h" #include "rwlock.h" #include "datasource.h" namespace Kst { class ObjectNameIndex; // The ObjectStore is responsible for storing all the Objects in an // application. class KSTCORE_EXPORT ObjectStore { public: ObjectStore(); ~ObjectStore(); template SharedPtr createObject(); template bool addObject(T *o); bool removeObject(Object *o); ObjectPtr retrieveObject(const QString& name) const; bool isEmpty() const; void clear(); /** get a list containing only objects of type T in the object store ** T must inherit from Kst::Object */ template const ObjectList getObjects() const; /** get just the data sources */ DataSourceList dataSourceList() const; /** Close all data sources, and reopen ones that are needed */ void rebuildDataSourceList(); /** remove unused data sources from the list */ void cleanUpDataSourceList(); /** get everything but the data sources */ QList objectList(); /** locking */ KstRWLock& lock() const { return _lock; } /** clear the 'used' flag on all objects in list */ void clearUsedFlags(); /** delete everything that doesn't have the used flag set. * Note: the caller is responsible to make sure that the * used flags are set properly. It is not done here! */ bool deleteUnsetUsedFlags(); // void deleteDependentObjects(const Primitive &p); // some variables for overriding data source properties // from the command line when opening a .kst file struct { QString fileName; int f0; int N; int skip; int doAve; } override; private: Q_DISABLE_COPY(ObjectStore) mutable KstRWLock _lock; // objects are stored in these lists DataSourceList _dataSourceList; QList _list; }; // this is an inefficient implementation for now template const ObjectList ObjectStore::getObjects() const { KstReadLocker l(&(this->_lock)); ObjectList rc; for (QList::ConstIterator it = _list.begin(); it != _list.end(); ++it) { SharedPtr x = kst_cast(*it); if (x != 0) { rc.append(x); } } return rc; } template SharedPtr ObjectStore::createObject() { KstWriteLocker l(&(this->_lock)); T *object = new T(this); addObject(object); return SharedPtr(object); } // Add an object to the store. template bool ObjectStore::addObject(T *o) { if (!o) { return false; } KstWriteLocker l(&this->_lock); o->_store = this; // put the object in the right place depending on its type if (DataSourcePtr ds = kst_cast(o)) { _dataSourceList.append(ds); } else { _list.append(o); } return true; } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/generatedvector.h000644 001750 001750 00000003627 11544160210 020304 0ustar00synthsynth000000 000000 /*************************************************************************** generatedvector.h - a vector from x0 to x1 with n pts ------------------- begin : March, 2005 copyright : (C) 2005 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GENERATEDVECTOR_H #define GENERATEDVECTOR_H #include "vector.h" //#include "kst_i18n.h" #include "kst_export.h" namespace Kst { /**A vector from x0 to x1 with n pts *@author cbn */ class KSTCORE_EXPORT GeneratedVector : public Vector { Q_OBJECT public: virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; void save(QXmlStreamWriter &s); void changeRange(double x0, double x1, int n); void setSaveData(bool save); virtual QString descriptionTip() const; virtual QString propertyString() const; protected: GeneratedVector(ObjectStore *store); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; }; typedef SharedPtr GeneratedVectorPtr; typedef ObjectList GeneratedVectorList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/matrix.h000644 001750 001750 00000013573 11544160210 016430 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2004 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MATRIX_H #define MATRIX_H #include "scalar.h" #include "vector.h" #include "primitive.h" class QXmlStreamWriter; namespace Kst { class Matrix; typedef SharedPtr MatrixPtr; class KSTCORE_EXPORT Matrix : public Primitive { Q_OBJECT public: virtual const QString& typeString() const; static const QString staticTypeString; virtual QString descriptionTip() const; protected: Matrix(ObjectStore *store); virtual ~Matrix(); friend class ObjectStore; virtual void _initializeShortName(); public: void change(uint nX, uint nY, double minX=0, double minY=0, double stepX=1, double stepY=1); void change(QByteArray& data, uint nX, uint nY, double minX=0, double minY=0, double stepX=1, double stepY=1); // Return the sample count (x times y) of the matrix virtual int sampleCount() const; // return the z value of the rectangle in which the specified point lies // ok is false if the point is out of bounds double value(double x, double y, bool *ok = 0L) const; // set the z value of the rectangle in which the specified point lies // return false if the point is out of bounds bool setValue(double x, double y, double z); // return the value of the specified rectangle // ok is false if the rectangle does not exist double valueRaw(int x, int y, bool *ok = 0L) const; // set the value of the specified rectangle // return false if the rectangle does not exist bool setValueRaw(int x, int y, double z); // return some stats on the z values double minValue() const; double maxValue() const; // spike insensitive values void calcNoSpikeRange(double per = 0.005); double maxValueNoSpike() const; double minValueNoSpike() const; // return mean of the z values double meanValue() const; // return least positive z value double minValuePositive() const; // number of new samples in the matrix since last resetNumNew() int numNew() const; // reset numNew to 0 void resetNumNew(); // labels for plots virtual void setXLabelInfo(const LabelInfo &label_info); virtual void setYLabelInfo(const LabelInfo &label_info); virtual void setTitleInfo(const LabelInfo &label_info); virtual LabelInfo xLabelInfo() const; virtual LabelInfo yLabelInfo() const; virtual LabelInfo titleInfo() const; void zero(); // clear out the matrix void blank(); // get usage of this matrix by other objects virtual int getUsage() const; // save the matrix virtual void save(QXmlStreamWriter &s); // set the labels for this matrix void setLabel(const QString& newLabel); // whether or not this matrix can be edited bool editable() const; void setEditable(bool editable); // whether or not this matrix can be saved bool saveable() const; // matrix dimensions int xNumSteps() const { return _nX; } int yNumSteps() const { return _nY; } double xStepSize() const { return _stepX; } double yStepSize() const { return _stepY; } virtual bool invertXHint() const {return _invertXHint; } virtual bool invertYHint() const {return _invertYHint; } double minX() const { return _minX; } double minY() const { return _minY; } virtual bool resize(int xSize, int ySize, bool reinit = true); virtual void deleteDependents(); virtual QString sizeString() const; virtual void internalUpdate(); double Z(int i) const {return _z[i];} // output primitives: statistics scalars, etc. VectorMap vectors() const {return _vectors;} ScalarMap scalars() const {return _scalars;} StringMap strings() const {return _strings;} virtual PrimitiveMap metas() const; virtual ObjectList outputPrimitives() const; protected: int _NS; int _NRealS; // number of samples with real values int _nX; //this can be 0 int _nY; //this should never be 0 double _minX; double _minY; double _stepX; double _stepY; bool _invertXHint; bool _invertYHint; int _numNew; // number of new samples bool _editable : 1; bool _saveable : 1; double _minNoSpike; double _maxNoSpike; // labels for this matrix LabelInfo _xLabelInfo; LabelInfo _yLabelInfo; LabelInfo _titleInfo; void createScalars(ObjectStore *store); void renameScalars(); void updateScalars(); // the flat-packed array in row-major order double *_z; int _zSize; // internally keep track of real _z size // for resizing the internal array _z only virtual bool resizeZ(int sz, bool reinit = true); // returns -1 if (x,y) is out of bounds int zIndex(int x, int y) const; ObjectMap _scalars; ObjectMap _vectors; ObjectMap _strings; }; typedef ObjectList MatrixList; typedef ObjectMap MatrixMap; } Q_DECLARE_METATYPE(Kst::Matrix*) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datascalar.h000644 001750 001750 00000005161 11544160210 017215 0ustar00synthsynth000000 000000 /*************************************************************************** datastscalar.h - a scalar from a data source ------------------- begin : September, 2008 copyright : (C) 2008 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATASCALAR_H #define DATASCALAR_H #include "kst_export.h" #include "dataprimitive.h" #include "scalar.h" class QXmlStreamWriter; namespace Kst { /**A class for handling data scalars for kst. *@author cbn */ /** A scalar which gets its value from a data file. */ class KSTCORE_EXPORT DataScalar : public Scalar, public DataPrimitive { Q_OBJECT protected: DataScalar(ObjectStore *store); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; /** Update the scalar.*/ virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; public: virtual ~DataScalar(); struct ReadInfo { ReadInfo(double* d) : value(d) {} double* value; }; struct DataInfo { }; virtual void internalUpdate(); virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; /** change the properties of a DataScalar */ void change(DataSourcePtr file, const QString &field); void changeFile(DataSourcePtr file); /** Save scalar information */ virtual void save(QXmlStreamWriter &s); virtual QString descriptionTip() const; virtual QString propertyString() const; bool isValid() const; virtual void reset(); void reload(); private: /** make a copy of the DataScalar */ virtual PrimitivePtr makeDuplicate() const; virtual bool checkValidity(const DataSourcePtr& ds) const; }; typedef SharedPtr DataScalarPtr; typedef ObjectList DataScalarList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/measuretime.h000644 001750 001750 00000003261 11544160210 017435 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_MEASURE_TIME #define KST_MEASURE_TIME #include "kst_export.h" #include class KSTCORE_EXPORT MeasureTime { public: MeasureTime(const QString& name); /// Init with other instance to increment parent's interval in detor /// Needed to sum over multiple measurements. MeasureTime(MeasureTime& parent); ~MeasureTime(); void restart();; /// print interval to console void print(); private: double started; double interval; double frequency; QString name; double* other_interval; void setFrequency(); /// Increment interval by interval since last call/restart(). void measure(); double getTime() const; }; #define TIME_IN_SCOPE(x) MeasureTime x(QString("%1 at %2, line %3, time in scope").arg(#x).arg(__FILE__).arg(__LINE__)) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/object.h000644 001750 001750 00000005440 11544160210 016364 0ustar00synthsynth000000 000000 /*************************************************************************** object.h: abstract base class for all Kst objects ------------------- begin : May 22, 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OBJECT_H #define OBJECT_H #include #include #include #include #include #include #include #include #include "namedobject.h" #include "kst_export.h" #include "sharedptr.h" #include "rwlock.h" namespace Kst { class ObjectStore; class Object; typedef SharedPtr ObjectPtr; class KSTCORE_EXPORT Object : public QObject, public Shared, public KstRWLock, public NamedObject { Q_OBJECT public: static QString type(); static const qint64 Forced = -1; enum UpdateType { NoChange = 0, Updated, Deferred }; virtual UpdateType objectUpdate(qint64 newSerial); virtual void registerChange() {_serial = Forced;} virtual void reset(); qint64 serial() const {return _serial;} qint64 serialOfLastChange() const {return _serialOfLastChange;} virtual const QString& typeString() const; static const QString staticTypeString; ObjectStore *store() const; // Returns count - 2 to account for "this" and the list pointer, therefore // you MUST have a reference-counted pointer to call this function virtual int getUsage() const; virtual void deleteDependents(); virtual void internalUpdate() = 0; virtual bool used() const {return _used;} void setUsed(bool used_in) {_used = used_in;} virtual bool uses(ObjectPtr p) const; protected: Object(); virtual ~Object(); friend class ObjectStore; ObjectStore *_store; // set by ObjectStore virtual qint64 minInputSerial() const = 0; virtual qint64 minInputSerialOfLastChange() const = 0; qint64 _serial; qint64 _serialOfLastChange; private: bool _used; }; } Q_DECLARE_METATYPE(Kst::Object*) #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/ksttimers.h000644 001750 001750 00000001713 11544160210 017142 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KSTTIMERS_H #define KSTTIMERS_H #include #ifdef HAVE_KST_USE_TIMERS #define BENCHMARK #endif #endif kst-2.0.3/src/libkst/datasourcepluginfactory.h000644 001750 001750 00000002303 11544160210 022052 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATASOURCEPLUGINFACTORY_H #define DATASOURCEPLUGINFACTORY_H #include "datasourcefactory.h" namespace Kst { class DataSourcePluginFactory : public DataSourceFactory { public: DataSourcePluginFactory(); ~DataSourcePluginFactory(); DataSourcePtr generateDataSource(ObjectStore *store, QXmlStreamReader& stream); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datasourcefactory.cpp000644 001750 001750 00000003636 11544160210 021200 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasourcefactory.h" #include #include namespace Kst { static QMap *factories = 0; void cleanupDataSources() { foreach (DataSourceFactory *f, *factories) { delete f; } delete factories; factories = 0; } DataSourceFactory::DataSourceFactory() { } DataSourceFactory::~DataSourceFactory() { } void DataSourceFactory::registerFactory(const QString& node, DataSourceFactory *factory) { if (!factories) { factories = new QMap; qAddPostRoutine(cleanupDataSources); } factories->insert(node, factory); } void DataSourceFactory::registerFactory(const QStringList& nodes, DataSourceFactory *factory) { foreach (const QString n, nodes) { registerFactory(n, factory); } } DataSourcePtr DataSourceFactory::parse(ObjectStore *store, QXmlStreamReader& stream) { if (!factories) { return 0; } DataSourceFactory *f = factories->value(stream.name().toString()); if (!f) { return 0; } return f->generateDataSource(store, stream); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/coredocument.cpp000644 001750 001750 00000003673 11544160210 020146 0ustar00synthsynth000000 000000 /*************************************************************************** coredocument.cpp ------------------- begin : October 3, 2007 copyright : (C) 2007 by The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "coredocument.h" #include #include #include #include "objectstore.h" namespace Kst { CoreDocument::CoreDocument() : _objectStore(new ObjectStore()), _dirty(false), _isOpen(false) { _fileName.clear(); } CoreDocument::~CoreDocument() { delete _objectStore; _objectStore = 0; } QString CoreDocument::fileName() const { return _fileName; } ObjectStore* CoreDocument::objectStore() const { return _objectStore; } bool CoreDocument::save(const QString& to) { Q_UNUSED(to); return true; } bool CoreDocument::open(const QString& file) { Q_UNUSED(file); _isOpen = false; return _isOpen = true; } QString CoreDocument::lastError() const { return _lastError; } bool CoreDocument::isChanged() const { return _dirty; } bool CoreDocument::isOpen() const { return _isOpen; } void CoreDocument::setChanged(bool dirty) { _dirty = dirty; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/sysinfo.h000644 001750 001750 00000011765 11544160210 016617 0ustar00synthsynth000000 000000 /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This file is from the procps project at http://procps.sourceforge.net/ * * * ***************************************************************************/ #ifdef __linux__ #ifndef PROC_SYSINFO_H #define PROC_SYSINFO_H #include #include #include "procps.h" EXTERN_C_BEGIN extern unsigned long long Hertz; /* clock tick frequency */ extern long smp_num_cpus; /* number of CPUs */ #if 0 #define JT double extern void seven_cpu_numbers(JT *uret, JT *nret, JT *sret, JT *iret, JT *wret, JT *xret, JT *yret); #undef JT #endif extern int uptime (double *uptime_secs, double *idle_secs); extern void loadavg(double *av1, double *av5, double *av15); /* obsolete */ extern unsigned long kb_main_shared; /* old but still kicking -- the important stuff */ extern unsigned long kb_main_buffers; extern unsigned long kb_main_cached; extern unsigned long kb_main_free; extern unsigned long kb_main_total; extern unsigned long kb_swap_free; extern unsigned long kb_swap_total; /* recently introduced */ extern unsigned long kb_high_free; extern unsigned long kb_high_total; extern unsigned long kb_low_free; extern unsigned long kb_low_total; /* 2.4.xx era */ extern unsigned long kb_active; extern unsigned long kb_inact_laundry; /* grrr... */ extern unsigned long kb_inact_dirty; extern unsigned long kb_inact_clean; extern unsigned long kb_inact_target; extern unsigned long kb_swap_cached; /* late 2.4+ */ /* derived values */ extern unsigned long kb_swap_used; extern unsigned long kb_main_used; /* 2.5.41+ */ extern unsigned long kb_writeback; extern unsigned long kb_slab; extern unsigned long nr_reversemaps; extern unsigned long kb_committed_as; extern unsigned long kb_dirty; extern unsigned long kb_inactive; extern unsigned long kb_mapped; extern unsigned long kb_pagetables; #define BUFFSIZE 8192 typedef unsigned long long jiff; extern void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, jiff *restrict cxxx, jiff *restrict cyyy, unsigned long *restrict pin, unsigned long *restrict pout, unsigned long *restrict s_in, unsigned long *restrict sout, unsigned *restrict intr, unsigned *restrict ctxt, unsigned int *restrict running, unsigned int *restrict blocked, unsigned int *restrict btime, unsigned int *restrict processes); extern void meminfo(void); extern unsigned long vm_nr_dirty; extern unsigned long vm_nr_writeback; extern unsigned long vm_nr_pagecache; extern unsigned long vm_nr_page_table_pages; extern unsigned long vm_nr_reverse_maps; extern unsigned long vm_nr_mapped; extern unsigned long vm_nr_slab; extern unsigned long vm_pgpgin; extern unsigned long vm_pgpgout; extern unsigned long vm_pswpin; extern unsigned long vm_pswpout; extern unsigned long vm_pgalloc; extern unsigned long vm_pgfree; extern unsigned long vm_pgactivate; extern unsigned long vm_pgdeactivate; extern unsigned long vm_pgfault; extern unsigned long vm_pgmajfault; extern unsigned long vm_pgscan; extern unsigned long vm_pgrefill; extern unsigned long vm_pgsteal; extern unsigned long vm_kswapd_steal; extern unsigned long vm_pageoutrun; extern unsigned long vm_allocstall; extern void vminfo(void); typedef struct disk_stat{ unsigned long long reads_sectors; unsigned long long written_sectors; char disk_name [16]; unsigned int disk_type; unsigned inprogress_IO; unsigned merged_reads; unsigned merged_writes; unsigned milli_reading; unsigned milli_spent_IO; unsigned milli_writing; unsigned partitions; unsigned reads; unsigned weighted_milli_spent_IO; unsigned writes; }disk_stat; typedef struct partition_stat{ unsigned int disk_type; unsigned int partition_num; char partition_name [16]; unsigned long long reads_sectors; struct disk_stat* parent_disk; unsigned reads; unsigned writes; unsigned requested_writes; }partition_stat; extern unsigned int getpartitions_num(struct disk_stat *disks, int ndisks); extern unsigned int getdiskstat (struct disk_stat**,struct partition_stat**); typedef struct slab_cache{ char name[48]; unsigned active_objs; unsigned num_objs; unsigned objsize; unsigned objperslab; }slab_cache; extern unsigned int getslabinfo (struct slab_cache**); extern unsigned get_pid_digits(void) FUNCTION; EXTERN_C_END #endif /* SYSINFO_H */ #endif kst-2.0.3/src/libkst/dataplugin.h000644 001750 001750 00000006761 11544160210 017255 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAPLUGIN_H #define DATAPLUGIN_H #include #include #include #include "sharedptr.h" #include "datasource.h" namespace Kst { class ObjectStore; class DataSource; class DataSourceConfigWidget; KSTCORE_EXPORT QStringList pluginSearchPaths(); class PluginInterface : public Shared { public: PluginInterface() {} virtual ~PluginInterface() {} virtual QString pluginName() const { return QString(); } virtual QString pluginDescription() const { return QString::null; } virtual bool hasConfigWidget() const { return false; } }; class DataSourcePluginInterface : public PluginInterface { public: virtual ~DataSourcePluginInterface() {} virtual DataSource *create(ObjectStore *store, QSettings *cfg, const QString &filename, const QString &type, const QDomElement &element) const = 0; virtual QStringList matrixList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const = 0; virtual QStringList scalarList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const = 0; virtual QStringList stringList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const = 0; virtual QStringList fieldList(QSettings *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete) const = 0; virtual int understands(QSettings *cfg, const QString& filename) const = 0; virtual bool supportsTime(QSettings *cfg, const QString& filename) const = 0; virtual QStringList provides() const = 0; bool provides(const QString& type) const { return provides().contains(type); } virtual DataSourceConfigWidget *configWidget(QSettings *cfg, const QString& filename) const = 0; }; } Q_DECLARE_INTERFACE(Kst::PluginInterface, "com.kst.PluginInterface/2.0") Q_DECLARE_INTERFACE(Kst::DataSourcePluginInterface, "com.kst.DataSourcePluginInterface/2.0") #endif kst-2.0.3/src/libkst/datamatrix.h000644 001750 001750 00000013635 11544160210 017261 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * copyright : (C) 2005 University of British Columbia * * dscott@phas.ubc.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAMATRIX_H #define DATAMATRIX_H #include "kst_export.h" #include "dataprimitive.h" #include "matrix.h" namespace Kst { class MatrixData { public: double xMin; double yMin; double xStepSize; double yStepSize; double *z; // the data }; class KSTCORE_EXPORT DataMatrix : public Matrix, public DataPrimitive { Q_OBJECT public: /** Read the specified sub-range of the matrix, flat-packed in z in row-major order xStart - starting x *frame* yStart - starting y *frame* xNumSteps - number of *frames* to read in x direction; -1 to read 1 *sample* from xStart yNumSteps - number of *frames* to read in y direction; -1 to read 1 *sample* from yStart Will skip according to the parameter, but it may not be implemented. If return value is -9999, use the non-skip version instead. The suggested scaling and translation is returned in xMin, yMin, xStepSize, and yStepSize Returns the number of *samples* read **/ struct KSTCORE_EXPORT ReadInfo { MatrixData* data; int xStart; int yStart; int xNumSteps; int yNumSteps; int skip; }; struct KSTCORE_EXPORT DataInfo { DataInfo(); int samplesPerFrame; int xSize; int ySize; bool invertXHint; bool invertYHint; }; virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; // save DataMatrix virtual void save(QXmlStreamWriter &xml); // change properties of DataMatrix void change(DataSourcePtr file, const QString &field, int xStart, int yStart, int xNumSteps, int yNumSteps, bool doAve, bool doSkip, int skip, double minX, double minY, double stepX, double stepY); void changeFrames(int xStart, int yStart, int xNumSteps, int yNumSteps, bool doAve, bool doSkip, int skip, double minX, double minY, double stepX, double stepY); // return properties of DataMatrix int reqXStart() const; int reqYStart() const; int reqXNumSteps() const; int reqYNumSteps() const; //QString filename() const; const QString& field() const; bool xReadToEnd() const; bool yReadToEnd() const; bool xCountFromEnd() const; bool yCountFromEnd() const; bool doSkip() const; bool doAverage() const; int skip() const; // labels for this matrix virtual QString label() const; // returns true if the file and field is valid; false otherwise bool isValid() const; // reload contents of DataMatrix from file void reload(); virtual void reset(); // change the datasource for this matrix void changeFile(DataSourcePtr file); virtual QString descriptionTip() const; virtual QString propertyString() const; virtual void internalUpdate(); virtual LabelInfo xLabelInfo() const; virtual LabelInfo yLabelInfo() const; virtual LabelInfo titleInfo() const; protected: DataMatrix(ObjectStore *store); virtual ~DataMatrix(); // update DataMatrix virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _resetFieldMetadata(); private: void commonConstructor(DataSourcePtr file, const QString &field, int reqXStart, int reqYStart, int reqNX, int reqNY, bool doAve, bool doSkip, int skip, double minX, double minY, double stepX, double stepY); void doUpdateSkip(int realXStart, int realYStart); void doUpdateNoSkip(int realXStart, int realYStart); virtual void _resetFieldScalars(); virtual void _resetFieldStrings(); // values requested; may be different from actual matrix range int _reqXStart, _reqYStart, _reqNX, _reqNY; // matrix params since last update - used to determine if update is needed int _lastXStart, _lastYStart, _lastNX, _lastNY; bool _lastDoAve : 1; bool _lastDoSkip : 1; int _lastSkip; double* _aveReadBuffer; // buffer used when performing boxcar filter int _aveReadBufferSize; DataSourcePtr _file; QString _field; // field to read from _file bool _doAve : 1; bool _doSkip : 1; int _skip; int _samplesPerFrameCache; // cache the samples per frame of the field in datasource int readMatrix(MatrixData* data, const QString& matrix, int xStart, int yStart, int xNumSteps, int yNumSteps, int skip); QHash _fieldScalars; QHash _fieldStrings; // make a "copy" of this DataMatrix virtual PrimitivePtr makeDuplicate() const; virtual bool checkValidity(const DataSourcePtr& ds) const; }; typedef SharedPtr DataMatrixPtr; typedef ObjectList DataMatrixList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/vector.cpp000644 001750 001750 00000040732 11544160210 016756 0ustar00synthsynth000000 000000 /*************************************************************************** vector.cpp - description ------------------- begin : Fri Sep 22 2000 copyright : (C) 2000-2011 by C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * Permission is granted to link with any opensource library * * * ***************************************************************************/ #include #include #include #include #include #include "kst_i18n.h" #include "datacollection.h" #include "math_kst.h" #include "vector.h" #include "debug.h" #include "objectstore.h" #include "updatemanager.h" namespace Kst { #define INITSIZE 1 const QString Vector::staticTypeString = I18N_NOOP("Vector"); const QString Vector::staticTypeTag = I18N_NOOP("vector"); /** Create a vector */ Vector::Vector(ObjectStore *store) : Primitive(store, 0L), _nsum(0), _labelInfo(LabelInfo()), _titleInfo(LabelInfo()) { _initializeShortName(); _editable = false; NumShifted = 0; NumNew = 0; _saveData = false; _isScalarList = false; _saveable = false; _labelInfo.name = QString(); _labelInfo.quantity = QString(); _labelInfo.units = QString(); int size = INITSIZE; _v = static_cast(malloc(size * sizeof(double))); if (!_v) { // Malloc failed _v = static_cast(malloc(sizeof(double))); _size = 1; } else { _size = size; } _is_rising = false; _scalars.clear(); _strings.clear(); CreateScalars(store); blank(); } void Vector::_initializeShortName() { _shortName = 'V'+QString::number(_vnum); if (_vnum>max_vnum) max_vnum = _vnum; _vnum++; } Vector::~Vector() { if (_v) { free(_v); _v = 0; } } void Vector::deleteDependents() { for (QHash::Iterator it = _scalars.begin(); it != _scalars.end(); ++it) { _store->removeObject(it.value()); } for (QHash::Iterator it = _strings.begin(); it != _strings.end(); ++it) { _store->removeObject(it.value()); } Object::deleteDependents(); } const QString& Vector::typeString() const { return staticTypeString; } #define GENERATE_INTERPOLATION \ assert(_size > 0); \ /** Limits checks - optional? **/ \ if (in_i < 0 || _size == 1) { \ return _v[0]; \ } \ \ if (in_i >= ns_i - 1) { \ return _v[_size - 1]; \ } \ \ /** speedup check **/ \ if (ns_i == _size) { /* no extrapolating or decimating needed */ \ return _v[in_i]; \ } \ \ double fj = in_i * double(_size - 1) / double(ns_i-1); /* scaled index */ \ \ int j = int(fj); /* index of sample one lower */ \ /*assert(j==int(floor(fj)));*/ \ assert(j+1 < _size && j >= 0); \ if (_v[j + 1] != _v[j + 1] || _v[j] != _v[j]) { \ return NOPOINT; \ } \ \ double fdj = fj - float(j); /* fdj is fraction between _v[j] and _v[j+1] */ \ \ return _v[j + 1] * fdj + _v[j] * (1.0 - fdj); /** Return v[i], i is sample number, interpolated to have ns_i total samples in vector */ double Vector::interpolate(int in_i, int ns_i) const { GENERATE_INTERPOLATION } double kstInterpolate(double *_v, int _size, int in_i, int ns_i) { GENERATE_INTERPOLATION } #undef GENERATE_INTERPOLATION #define RETURN_FIRST_NON_HOLE \ for (int i = 0; i < _size; ++i) { \ if (_v[i] == _v[i]) { \ return _v[i]; \ } \ } \ return 0.; #define RETURN_LAST_NON_HOLE \ for (int i = _size - 1; i >= 0; --i) { \ if (_v[i] == _v[i]) { \ return _v[i]; \ } \ } \ return 0.; #define FIND_LEFT(val, idx) \ for (; idx >= 0; --idx) { \ if (_v[idx] == _v[idx]) { \ val = _v[idx]; break; \ } \ } #define FIND_RIGHT(val, idx) \ for (; idx < _size; ++idx) { \ if (_v[idx] == _v[idx]) { \ val = _v[idx]; break; \ } \ } #define GENERATE_INTERPOLATION \ assert(_size > 0); \ /** Limits checks - optional? **/ \ if (in_i <= 0 || _size == 1) { \ RETURN_FIRST_NON_HOLE \ } \ \ if (in_i >= ns_i - 1) { \ RETURN_LAST_NON_HOLE \ } \ \ /** speedup check **/ \ if (ns_i == _size) { \ if (_v[in_i] == _v[in_i]) { \ return _v[in_i]; \ } \ double left = 0., right = 0.; \ int leftIndex = in_i, rightIndex = in_i;\ FIND_LEFT(left, leftIndex) \ FIND_RIGHT(right, rightIndex) \ if (leftIndex == -1) { \ return right; \ } \ if (rightIndex == _size) { \ return left; \ } \ return left + (right - left) * double(in_i - leftIndex) / double(rightIndex - leftIndex); \ } \ abort(); /* FIXME; this is effectivly assert(ns_i == _size) */ \ double indexScaleFactor = double(_size - 1) / double(ns_i - 1); \ double fj = in_i * indexScaleFactor; /* scaled index */ \ \ int j = int(floor(fj)); /* index of sample one lower */ \ assert(j+1 < _size && j >= 0); \ if (_v[j + 1] != _v[j + 1] || _v[j] != _v[j]) { \ return NOPOINT; \ } \ \ double fdj = fj - float(j); /* fdj is fraction between _v[j] and _v[j+1] */ \ \ return _v[j + 1] * fdj + _v[j] * (1.0 - fdj); // FIXME: optimize me - possible that floor() (especially) and isnan() are // expensive here. double Vector::interpolateNoHoles(int in_i, int ns_i) const { GENERATE_INTERPOLATION } double kstInterpolateNoHoles(double *_v, int _size, int in_i, int ns_i) { GENERATE_INTERPOLATION } #undef FIND_LEFT #undef FIND_RIGHT #undef RETURN_LAST_NON_HOLE #undef RETURN_FIRST_NON_HOLE #undef GENERATE_INTERPOLATION double Vector::value(int i) const { if (i < 0 || i >= _size) { // can't look before beginning or past end return 0.0; } return _v[i]; } void Vector::CreateScalars(ObjectStore *store) { if (!_isScalarList) { _min = _max = _mean = _minPos = 0.0; Q_ASSERT(store); ScalarPtr sp; _scalars.insert("max", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("Max"); _scalars.insert("min", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("Min"); _scalars.insert("last", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("Last"); _scalars.insert("first", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("First"); _scalars.insert("mean", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("Mean"); _scalars.insert("sigma", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("Sigma"); _scalars.insert("rms", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("Rms"); _scalars.insert("ns", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("NS"); _scalars.insert("sum", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("Sum"); _scalars.insert("sumsquared", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("SumSquared"); _scalars.insert("minpos", sp = store->createObject()); sp->setProvider(this); sp->setSlaveName("MinPos"); } } void Vector::updateScalars() { if (!_isScalarList) { _scalars["ns"]->setValue(_size); if (_nsum >= 2) { double sum = _scalars["sum"]->value(); double sumsq = _scalars["sumsquared"]->value(); _scalars["mean"]->setValue(_mean = sum/double(_nsum)); _scalars["sigma"]->setValue(sqrt((sumsq - sum * sum / double(_nsum)) / double(_nsum-1))); _scalars["rms"]->setValue(sqrt(sumsq/double(_nsum))); } else { _scalars["sigma"]->setValue(_max - _min); _scalars["rms"]->setValue(sqrt(_scalars["sumsquared"]->value())); _scalars["mean"]->setValue(_mean = NOPOINT); } } } double* Vector::realloced(double *memptr, int newSize) { double *old = _v; _v = memptr; if (newSize < _size) { NumNew = newSize; // all new if we shrunk the vector } else { NumNew = newSize - _size; } _size = newSize; updateScalars(); return old; } void Vector::setV(double *memptr, int newSize) { _v = memptr; NumNew = newSize; _size = newSize; } void Vector::zero() { _ns_min = _ns_max = 0.0; memset(_v, 0, sizeof(double)*_size); updateScalars(); } void Vector::blank() { _ns_min = _ns_max = 0.0; for (int i = 0; i < _size; ++i) { _v[i] = NOPOINT; } updateScalars(); } bool Vector::resize(int sz, bool init) { if (sz > 0) { _v = static_cast(realloc(_v, sz*sizeof(double))); if (!_v) { return false; } if (init && _size < sz) { for (int i = _size; i < sz; i++) { _v[i] = NOPOINT; } } _size = sz; updateScalars(); } return true; } void Vector::internalUpdate() { int i, i0; double sum, sum2, last, first, v; double last_v; double dv2 = 0.0, dv, no_spike_max_dv; _max = _min = sum = sum2 = _minPos = last = first = NOPOINT; _nsum = 0; if (_size > 0) { _is_rising = true; // Look for a valid (finite) point... for (i = 0; i < _size && !finite(_v[i]); i++) { // do nothing } if (i == _size) { // there were no finite points: if (!_isScalarList) { _scalars["sum"]->setValue(sum); _scalars["sumsquared"]->setValue(sum2); _scalars["max"]->setValue(_max); _scalars["min"]->setValue(_min); _scalars["minpos"]->setValue(_minPos); _scalars["last"]->setValue(last); _scalars["first"]->setValue(first); } _ns_max = _ns_min = 0; updateScalars(); return; } i0 = i; if (i0 > 0) { _is_rising = false; } _max = _min = _v[i0]; sum = sum2 = 0.0; if (_v[i0] > 0.0) { _minPos = _v[i0]; } else { _minPos = 1.0E300; } last_v = _v[i0]; for (i = i0; i < _size; i++) { v = _v[i]; // get rid of redirections if (finite(v)) { dv = v - last_v; dv2 += dv*dv; if (v <= last_v) { if (i != i0) { _is_rising = false; } } last_v = v; _nsum++; sum += v; sum2 += v*v; if (v > _max) { _max = v; } else if (v < _min) { _min = v; } if (v < _minPos && v > 0.0) { _minPos = v; } } else { _is_rising = false; } } no_spike_max_dv = 7.0*sqrt(dv2/double(_nsum)); _ns_max = _ns_min = last_v = _v[i0]; last = _v[_size-1]; first = _v[0]; for (i = i0; i < _size; i++) { v = _v[i]; // get rid of redirections if (finite(v)) { if (fabs(v - last_v) < no_spike_max_dv) { if (v > _ns_max) { _ns_max = v; } else if (v < _ns_min) { _ns_min = v; } last_v = v; } else { i += 20; if (i < _size) { last_v = _v[i]; } i++; } } } if (_isScalarList) { _max = _min = _minPos = 0.0; } else { _scalars["sum"]->setValue(sum); _scalars["sumsquared"]->setValue(sum2); _scalars["max"]->setValue(_max); _scalars["min"]->setValue(_min); _scalars["minpos"]->setValue(_minPos); _scalars["last"]->setValue(last); _scalars["first"]->setValue(first); } updateScalars(); } } void Vector::save(QXmlStreamWriter &s) { if (provider()) { return; } s.writeStartElement("vector"); if (_saveData) { QByteArray qba(length()*sizeof(double), '\0'); QDataStream qds(&qba, QIODevice::WriteOnly); for (int i = 0; i < length(); i++) { qds << _v[i]; } s.writeTextElement("data", qCompress(qba).toBase64()); } saveNameInfo(s, VNUM|XNUM); s.writeEndElement(); } void Vector::setNewAndShift(int inNew, int inShift) { NumNew = inNew; NumShifted = inShift; } double *Vector::value() const { return _v; } void Vector::newSync() { NumNew = NumShifted = 0; } int Vector::getUsage() const { int adj = 0; for (QHash::ConstIterator it = _scalars.begin(); it != _scalars.end(); ++it) { adj += it.value()->getUsage() - 1; } return Object::getUsage() + adj; } bool Vector::saveable() const { return _saveable; } bool Vector::editable() const { return _editable; } void Vector::setEditable(bool editable) { _editable = editable; } bool Vector::saveData() const { return _saveData; } void Vector::setSaveData(bool save) { _saveData = save; } void Vector::change(QByteArray &data) { if (!data.isEmpty()) { _saveable = true; _saveData = true; int sz = qMax((size_t)(INITSIZE), data.size()/sizeof(double)); resize(sz, true); QDataStream qds(data); for (int i = 0; !qds.atEnd(); ++i) { qds >> _v[i]; } } } QString Vector::propertyString() const { return i18n("Provider: %1").arg(_provider->Name()); } QString Vector::descriptionTip() const { return i18n("Vector: %1\n %2 samples\n%3").arg(Name()).arg(length()).arg(_provider->descriptionTip()); } QString Vector::sizeString() const { return QString::number(length()); } ObjectList Vector::outputPrimitives() const { PrimitiveList primitive_list; int n = _scalars.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_scalars.values().at(i))); } n = _strings.count(); for (int i = 0; i< n; i++) { primitive_list.append(kst_cast(_strings.values().at(i))); } return primitive_list; } PrimitiveMap Vector::metas() const { PrimitiveMap meta; for (QHash::ConstIterator it = _strings.begin(); it != _strings.end(); ++it) { meta[it.key()] = it.value(); } for (QHash::ConstIterator it = _scalars.begin(); it != _scalars.end(); ++it) { meta[it.key()] = it.value(); } return meta; } LabelInfo Vector::labelInfo() const { return _labelInfo; } LabelInfo Vector::titleInfo() const { return _titleInfo; } void Vector::setLabelInfo(const LabelInfo &label_info) { _labelInfo = label_info; } void Vector::setTitleInfo(const LabelInfo &label_info) { _titleInfo = label_info; } #undef INITSIZE } // vim: et sw=2 ts=2 kst-2.0.3/src/libkst/datasourcepluginfactory.cpp000644 001750 001750 00000004722 11544160210 022414 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasourcepluginfactory.h" #include "debug.h" #include "datasource.h" #include "datacollection.h" #include "objectstore.h" #include "datasourcepluginmanager.h" namespace Kst { DataSourcePluginFactory::DataSourcePluginFactory() : DataSourceFactory() { registerFactory(DataSource::staticTypeTag, this); } DataSourcePluginFactory::~DataSourcePluginFactory() { } DataSourcePtr DataSourcePluginFactory::generateDataSource(ObjectStore *store, QXmlStreamReader& xml) { Q_ASSERT(store); QString fileType, fileName; QXmlStreamAttributes propertyAttributes; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == DataSource::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); fileType = attrs.value("reader").toString(); fileName = DataPrimitive::readFilename(attrs); } else if (n == "properties") { propertyAttributes = xml.attributes(); xml.readElementText(); } else { return 0; } } else if (xml.isEndElement()) { if (n == DataSource::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating data source from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } if (!store->override.fileName.isEmpty()) { fileName = store->override.fileName; } DataSourcePtr dataSource = DataSourcePluginManager::loadSource(store, fileName, fileType); if (dataSource) { dataSource->parseProperties(propertyAttributes); } return dataSource; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/object.cpp000644 001750 001750 00000005531 11544160210 016720 0ustar00synthsynth000000 000000 /*************************************************************************** object.cpp: abstract base class for all Kst objects ------------------- begin : May 25, 2003 copyright : (C) 2003 The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kst_i18n.h" #include "object.h" #include "objectstore.h" namespace Kst { const QString Object::staticTypeString = I18N_NOOP("Object"); Object::Object() : Shared(), KstRWLock(), NamedObject(), _store(0L), _serial(0), _serialOfLastChange(0) { } Object::~Object() { } QString Object::type() { return staticMetaObject.className(); } void Object::reset() { _serial = _serialOfLastChange = Forced; } const QString& Object::typeString() const { return staticTypeString; } // Returns count - 1 to account for "this" and the list pointer, therefore // you MUST have a reference-counted pointer to call this function int Object::getUsage() const { return _KShared_count() - 1; } void Object::deleteDependents() { QList Objects = _store->objectList(); foreach (ObjectPtr object, Objects) { if (object->uses(this)) { _store->removeObject(object); } } } bool Object::uses(ObjectPtr p) const { Q_UNUSED(p) return false; } ObjectStore* Object::store() const { return _store; } // decide, based on serial numbers, whether to do an update. // if all inputs are up to date, update. Otherwise, defer. Object::UpdateType Object::objectUpdate(qint64 newSerial) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (newSerial == _serial) { return NoChange; } if (newSerial == Forced) { // register the forced update, but don't do it now. _serial = Forced; return Deferred; } else if (minInputSerial() < newSerial) { // if an input was forced, this will be true return Deferred; } else if ((_serialOfLastChange < minInputSerialOfLastChange()) || (_serial == Object::Forced)) { internalUpdate(); _serialOfLastChange = newSerial; _serial = newSerial; return Updated; } // else _serial = newSerial; return NoChange; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/ksttimers.h.cmake000644 001750 001750 00000000172 11544160210 020217 0ustar00synthsynth000000 000000 #ifndef KSTTIMERS_H #define KSTTIMERS_H #include #ifdef HAVE_KST_USE_TIMERS #define BENCHMARK #endif #endif kst-2.0.3/src/libkst/index_kst.h000644 001750 001750 00000002101 11544160210 017075 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2006 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef INDEX_KST_H #define INDEX_KST_H namespace Kst { class Index { public: Index() : isTime(false), index(0), time(0.0) {} bool isTime; union { int index; double time; }; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/vectorfactory.cpp000644 001750 001750 00000020376 11544160210 020350 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "vectorfactory.h" #include "debug.h" #include "vector.h" #include "generatedvector.h" #include "editablevector.h" #include "datavector.h" #include "datacollection.h" #include "objectstore.h" #include "datasourcepluginmanager.h" namespace Kst { VectorFactory::VectorFactory() : PrimitiveFactory() { registerFactory(Vector::staticTypeTag, this); } VectorFactory::~VectorFactory() { } PrimitivePtr VectorFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QByteArray data; QString descriptiveName; Q_ASSERT(store); while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == Vector::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else if (n == "data") { QString qcs(xml.readElementText().toLatin1()); QByteArray qbca = QByteArray::fromBase64(qcs.toLatin1()); data = qUncompress(qbca); } else { return 0; } } else if (xml.isEndElement()) { if (n == Vector::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating vector from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } VectorPtr vector = store->createObject(); vector->change(data); vector->setDescriptiveName(descriptiveName); vector->writeLock(); vector->registerChange(); vector->unlock(); return vector; } GeneratedVectorFactory::GeneratedVectorFactory() : PrimitiveFactory() { registerFactory(GeneratedVector::staticTypeTag, this); } GeneratedVectorFactory::~GeneratedVectorFactory() { } PrimitivePtr GeneratedVectorFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { double min=-1.0, max=1.0; int count=0; QString descriptiveName; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == GeneratedVector::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); min = attrs.value("min").toString().toDouble(); max = attrs.value("max").toString().toDouble(); count = attrs.value("count").toString().toInt(); if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == GeneratedVector::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating generated vector from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } GeneratedVectorPtr vector = store->createObject(); vector->changeRange(min, max, count); vector->setDescriptiveName(descriptiveName); vector->writeLock(); vector->registerChange(); vector->unlock(); return vector; } EditableVectorFactory::EditableVectorFactory() : PrimitiveFactory() { registerFactory(EditableVector::staticTypeTag, this); } EditableVectorFactory::~EditableVectorFactory() { } PrimitivePtr EditableVectorFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QByteArray data; QString descriptiveName; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == EditableVector::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else if (n == "data") { QString qcs(xml.readElementText().toLatin1()); QByteArray qbca = QByteArray::fromBase64(qcs.toLatin1()); data = qUncompress(qbca); } else { return 0; } } else if (xml.isEndElement()) { if (n == EditableVector::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating vector from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } EditableVectorPtr vector = store->createObject(); vector->change(data); vector->setDescriptiveName(descriptiveName); vector->writeLock(); vector->registerChange(); vector->unlock(); return vector; } DataVectorFactory::DataVectorFactory() : PrimitiveFactory() { registerFactory(DataVector::staticTypeTag, this); } DataVectorFactory::~DataVectorFactory() { } PrimitivePtr DataVectorFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QByteArray data; //QString provider; QString file, field; QString descriptiveName; int start=0, count=0, skip = -1; bool doAve=false; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == DataVector::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); //provider = attrs.value("provider").toString(); file = DataPrimitive::readFilename(attrs); field = attrs.value("field").toString(); start = attrs.value("start").toString().toInt(); count = attrs.value("count").toString().toInt(); skip = attrs.value("skip").toString().toInt(); doAve = attrs.value("doAve").toString() == "true" ? true : false; // set overrides if set from command line if (!store->override.fileName.isEmpty()) { file = store->override.fileName; } if (store->override.f0 != -5) { start = store->override.f0; } if (store->override.N != -5) { count = store->override.N; } if (store->override.skip != -5 ) { skip = store->override.skip; } if (store->override.doAve != -5) { doAve = store->override.doAve; } if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else if (n == "data") { QString qcs(xml.readElementText().toLatin1()); QByteArray qbca = QByteArray::fromBase64(qcs.toLatin1()); data = qUncompress(qbca); } else { return 0; } } else if (xml.isEndElement()) { if (n == DataVector::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating vector from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } Q_ASSERT(store); DataSourcePtr dataSource = DataSourcePluginManager::findOrLoadSource(store, file); if (!dataSource) { return 0; //Couldn't find a suitable datasource } DataVectorPtr vector = store->createObject(); vector->writeLock(); vector->change(dataSource, field, start, count, skip, (skip != -1), doAve); vector->setDescriptiveName(descriptiveName); vector->registerChange(); vector->unlock(); return vector; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datavector.h000644 001750 001750 00000012750 11544160210 017254 0ustar00synthsynth000000 000000 /*************************************************************************** datavector.h - description ------------------- begin : Fri Sep 22 2000 copyright : (C) 2000 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAVECTOR_H #define DATAVECTOR_H #include "kst_export.h" #include "dataprimitive.h" #include "vector.h" namespace Kst { /**A class for handling data vectors for kst. *@author cbn */ class KSTCORE_EXPORT DataVector : public Vector, public DataPrimitive { Q_OBJECT public: /** Parameters for reading vectors a field from a file. Data is returned in the data; data points to aloocated array which should be filled startingFrame is the starting frame numberOfFrames is the number of frames to read if numberOfFrames is -1, it means to read 1 -sample- from startingFrame. skipFrame skip this frame returns the number of samples read. If it returns -9999, use the skipFrame= -1. */ struct KSTCORE_EXPORT ReadInfo { double* data; int startingFrame; int numberOfFrames; int skipFrame; int *lastFrameRead; }; struct KSTCORE_EXPORT DataInfo { DataInfo(); DataInfo(int frameCount, int samplesPerFrame); int frameCount; int samplesPerFrame; }; virtual const QString& typeString() const; static const QString staticTypeString; static const QString staticTypeTag; virtual void reset(); // must be called with a lock /** change the properties of a DataVector */ void change(DataSourcePtr file, const QString &field, int f0, int n, int skip, bool in_doSkip, bool in_doAve); void changeFile(DataSourcePtr file); void changeFrames(int f0, int n, int skip, bool in_doSkip, bool in_doAve); /** Return frames held in Vector */ int numFrames() const; /** Return the requested number of frames in the vector */ int reqNumFrames() const; /** Return Starting Frame of Vector */ int startFrame() const; /** Return the requested starting frame of the Vector */ int reqStartFrame() const; /** Return frames to skip per read */ bool doSkip() const; bool doAve() const; int skip() const; /** Reload the contents of the vector */ void reload(); /** Returns intrinsic samples per frame */ int samplesPerFrame() const; /** Save vector information */ virtual void save(QXmlStreamWriter &s); /** return a sensible label for this vector */ virtual LabelInfo labelInfo() const; /** return the length of the file */ int fileLength() const; /** return whether the vector is suppose to read to end of file */ bool readToEOF() const; /** read whether the vector is suppose to count back from end of file */ bool countFromEOF() const; /** Read from end */ void setFromEnd(); virtual QString descriptionTip() const; virtual QString propertyString() const; bool isValid() const; virtual void internalUpdate(); protected: DataVector(ObjectStore *store); virtual ~DataVector(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; virtual void _resetFieldMetadata(); virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; private: virtual void _resetFieldScalars(); virtual void _resetFieldStrings(); bool _dirty; // different from the Object dirty flag /** Samples Per Frame */ int SPF; /** current number of frames */ int NF; /** current starting frame */ int F0; /** frames to skip per read */ bool DoSkip; bool DoAve; int Skip; /** max number of frames */ int ReqNF; /** Requested Starting Frame */ int ReqF0; /** Number of Samples allocated to the vector */ int _numSamples; int N_AveReadBuf; double *AveReadBuf; void checkIntegrity(); // must be called with a lock bool _dontUseSkipAccel; // wrappers around DataSource interface functions int readField(double *v, const QString& field, int s, int n, int skip = -1, int *lastFrameRead = 0L); const DataInfo dataInfo(const QString& field) const; QHash _fieldScalars; QHash _fieldStrings; /** make a copy of the DataVector */ virtual PrimitivePtr makeDuplicate() const; virtual bool checkValidity(const DataSourcePtr& ds) const; friend class TestDataSource; friend class TestHistogram; friend class TestCSD; friend class TestPSD; friend class TestScalar; }; typedef SharedPtr DataVectorPtr; typedef ObjectList DataVectorList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datastring.cpp000644 001750 001750 00000011316 11544160210 017610 0ustar00synthsynth000000 000000 /*************************************************************************** dataststring.cpp - a string from a data source ------------------- begin : September, 2008 copyright : (C) 2008 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include "kst_i18n.h" #include "datastring.h" #include "debug.h" #include "objectstore.h" namespace Kst { const QString DataString::staticTypeString = I18N_NOOP("Data String"); const QString DataString::staticTypeTag = I18N_NOOP("datastring"); /** Create a DataVector: raw data from a file */ DataString::DataString(ObjectStore *store) : String(store), DataPrimitive(this) { setOrphan(true); } DataString::~DataString() { } QString DataString::_automaticDescriptiveName() const { QString name = _field; // un-escape escaped special characters so they aren't escaped 2x. name.replace("\\_", "_").replace("\\^","^").replace("\\[", "[").replace("\\]", "]"); // now escape the special characters. name.replace('_', "\\_").replace('^', "\\^").replace('[', "\\[").replace(']', "\\]"); return name; } const QString& DataString::typeString() const { return staticTypeString; } /** return true if it has a valid file and field, or false otherwise */ bool DataString::isValid() const { if (dataSource()) { dataSource()->readLock(); bool rc = dataSource()->string().isValid(_field); dataSource()->unlock(); return rc; } return false; } bool DataString::checkValidity(const DataSourcePtr& ds) const { if (ds) { ds->readLock(); bool rc = ds->string().isValid(_field); ds->unlock(); return rc; } return false; } void DataString::change(DataSourcePtr in_file, const QString &in_field) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); _field = in_field; setDataSource(in_file); } void DataString::changeFile(DataSourcePtr in_file) { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (!in_file) { Debug::self()->log(i18n("Data file for string %1 was not opened.", Name()), Debug::Warning); } setDataSource(in_file); } /** Save data string information */ void DataString::save(QXmlStreamWriter &s) { if (dataSource()) { s.writeStartElement("datastring"); saveFilename(s); s.writeAttribute("field", _field); saveNameInfo(s, XNUM); s.writeEndElement(); } } /** Update a data String */ void DataString::internalUpdate() { if (dataSource()) { dataSource()->writeLock(); ReadInfo readInfo(&_value); dataSource()->string().read(_field, readInfo); dataSource()->unlock(); } } qint64 DataString::minInputSerial() const { if (dataSource()) { return (dataSource()->serial()); } return LLONG_MAX; } qint64 DataString::minInputSerialOfLastChange() const { if (dataSource()) { return (dataSource()->serialOfLastChange()); } return LLONG_MAX; } PrimitivePtr DataString::makeDuplicate() const { Q_ASSERT(store()); DataStringPtr string = store()->createObject(); string->writeLock(); string->change(dataSource(), _field); if (descriptiveNameIsManual()) { string->setDescriptiveName(descriptiveName()); } string->registerChange(); string->unlock(); return kst_cast(string); } QString DataString::descriptionTip() const { QString IDstring; IDstring = i18n( "Data String: %1 = %4\n" " %2\n" " Field: %3" ).arg(Name()).arg(dataSource()->fileName()).arg(_field).arg(value()); return IDstring; } QString DataString::propertyString() const { return i18n("%1 of %2").arg(_field).arg(dataSource()->fileName()); } void DataString::reload() { Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED); if (dataSource()) { dataSource()->writeLock(); dataSource()->reset(); dataSource()->unlock(); reset(); registerChange(); } } void DataString::reset() { ReadInfo readInfo(&_value); dataSource()->string().read(_field, readInfo); } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/string_kst.cpp000644 001750 001750 00000005126 11544160210 017641 0ustar00synthsynth000000 000000 /*************************************************************************** string.cpp - the base string type ------------------- begin : Sept 29, 2004 copyright : (C) 2004 by The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "kst_i18n.h" #include "string_kst.h" namespace Kst { const QString String::staticTypeString = I18N_NOOP("String"); const QString String::staticTypeTag = I18N_NOOP("string"); String::String(ObjectStore *store) : Primitive(store, 0L), _orphan(false), _editable(false) { _value.clear(); _initializeShortName(); } void String::_initializeShortName() { _shortName = 'T'+QString::number(_tnum); if (_tnum>max_tnum) max_tnum = _tnum; _tnum++; } String::~String() { } const QString& String::typeString() const { return staticTypeString; } void String::save(QXmlStreamWriter &s) { s.writeStartElement("string"); if (_orphan) { s.writeAttribute("orphan", "true"); } if (_editable) { s.writeAttribute("editable", "true"); } s.writeAttribute("value", value()); saveNameInfo(s, TNUM); s.writeEndElement(); } void String::internalUpdate() { // do nothing } String& String::operator=(const QString& v) { setValue(v); return *this; } String& String::operator=(const char *v) { setValue(v); return *this; } void String::setValue(const QString& inV) { _value = inV; } QString String::_automaticDescriptiveName() const { if (_orphan) { return value(); } else { return Primitive::_automaticDescriptiveName(); } } QString String::descriptionTip() const { return i18n("String: %1").arg(Name()); } QString String::sizeString() const { return QString::number(_value.size()); } QString String::propertyString() const { return _value; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/dateparser.h000644 001750 001750 00000002610 11544160210 017244 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2005 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATEPARSER_H #define DATEPARSER_H #include #include #include #include "kst_export.h" /* This is a public header */ namespace Kst { /* All times represented as doubles are the number of milliseconds since Jan 01 1970 00:00:00. Negative times are before then. */ KSTCORE_EXPORT extern QDateTime parsePlanckDate(const QString& dateString); KSTCORE_EXPORT extern double extDateTimeToMilliseconds(const QDateTime& edt); KSTCORE_EXPORT extern QDateTime millisecondsToQDateTime(double ms); } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/primitive.h000644 001750 001750 00000005242 11544160210 017126 0ustar00synthsynth000000 000000 /*************************************************************************** primitive.h ------------------- begin : Tue Jun 20 2006 copyright : Copyright (C) 2006, The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PRIMITIVE_H #define PRIMITIVE_H #include #include "kst_export.h" #include "object.h" #include "objectlist.h" #include "objectmap.h" #include "dataprimitive.h" namespace Kst { class Primitive; typedef ObjectMap PrimitiveMap; class KSTCORE_EXPORT Primitive : public Object { Q_OBJECT Q_PROPERTY(Object* provider READ provider WRITE setProvider) public: virtual const QString& typeString() const; static const QString staticTypeString; // Must not be a ObjectPtr! virtual void setProvider(Object* obj); inline ObjectPtr provider() const { return ObjectPtr(_provider); } void setSlaveName(QString slaveName); QString slaveName() const { return _slaveName; } virtual QString propertyString() const; virtual QString sizeString() const; virtual bool used() const; virtual ObjectList outputPrimitives() const = 0; virtual PrimitiveMap metas() const = 0; protected: Primitive(ObjectStore *store, Object* provider = 0L); virtual ~Primitive(); friend class ObjectStore; virtual QString _automaticDescriptiveName() const; QString _slaveName; virtual qint64 minInputSerial() const; virtual qint64 minInputSerialOfLastChange() const; protected: /** Possibly null. Be careful, this is non-standard usage of a KstShared. * FIXME: pretty sure this is wrong: it shouldn't be a qpointer... not sure * what should be going on here! */ QPointer _provider; }; typedef SharedPtr PrimitivePtr; typedef ObjectList PrimitiveList; typedef ObjectMap PrimitiveMap; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/shortnameindex.cpp000644 001750 001750 00000003405 11544160210 020500 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 C. Barth Netterfield * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "namedobject.h" namespace Kst { int _vnum = 1; // vectors int _pnum = 1; // plugins int _csdnum = 1; // csd int _cnum = 1; // curves int _enum = 1; // equations int _hnum = 1; // histograms int _inum = 1; // images int _psdnum = 1; // psd int _xnum = 1; // scalars int _tnum = 1; // text string int _mnum = 1; // matrix int _plotnum = 1; // plots int _lnum = 1; // legend int _dnum = 1; // view item int _dsnum = 1; // datasource int max_vnum = 0; // vectors int max_pnum = 0; // plugins int max_csdnum = 0; // csd int max_cnum = 0; // curves int max_enum = 0; // equations int max_hnum = 0; // histograms int max_inum = 0; // images int max_psdnum = 0; // psd int max_xnum = 0; // scalars int max_tnum = 0; // text string int max_mnum = 0; // matrix int max_plotnum = 0; // plots int max_lnum = 0; // legends int max_dnum = 0; // view item int max_dsnum = 0; // datasource } kst-2.0.3/src/libkst/dataprimitive.h000644 001750 001750 00000004736 11544160210 017767 0ustar00synthsynth000000 000000 /*************************************************************************** datastprimitive.h - add datasource handling capability to a primitive ------------------- begin : October, 2009 copyright : (C) 2009 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATAPRIMITIVE_H #define DATAPRIMITIVE_H #include "sharedptr.h" #include "kst_export.h" #include class QXmlStreamWriter; class QXmlStreamAttributes; namespace Kst { class DataSource; typedef SharedPtr DataSourcePtr; class Primitive; typedef SharedPtr PrimitivePtr; class KSTCORE_EXPORT DataPrimitive { public: virtual ~DataPrimitive(); /** return the name of the file */ QString filename() const; /** save filename to xml stream */ void saveFilename(QXmlStreamWriter&); static void saveFilename(const QString&, QXmlStreamWriter&); static QString readFilename(const QXmlStreamAttributes&); /** return the field name */ const QString& field() const; /** the data source */ DataSourcePtr dataSource() const; void setDataSource(const DataSourcePtr&); /** change the datasource */ virtual void changeFile(DataSourcePtr file); /** return true if it has a valid file and field, or false otherwise */ //virtual bool isValid() const = 0; /** file to read */ QString _field; virtual PrimitivePtr makeDuplicate() const = 0; virtual bool checkValidity(const DataSourcePtr& ds) const = 0; protected: DataPrimitive(Primitive* primitive); private: DataPrimitive(); struct Private; Private& d; }; } Q_DECLARE_INTERFACE(Kst::DataPrimitive, "DataPrimitive") #endif // DATAPRIMITIVE_H kst-2.0.3/src/libkst/extension.cpp000644 001750 001750 00000002747 11544160210 017474 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // include files for KDE // application specific includes #include "extension.h" #include #include namespace Kst { Extension::Extension(QObject *parent, const QStringList&) : QObject(parent) { } Extension::~Extension() { emit unregister(); } void Extension::load(const QDomElement& e) { Q_UNUSED(e) } void Extension::save(QTextStream& ts, const QString& indent) { Q_UNUSED(ts) Q_UNUSED(indent) } void Extension::clear() { } QMainWindow* Extension::app() const { return qobject_cast(parent()); } void Extension::processArguments(const QString& args) { Q_UNUSED(args) } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/scalarfactory.cpp000644 001750 001750 00000013622 11544160210 020307 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "scalarfactory.h" #include "debug.h" #include "scalar.h" #include "datascalar.h" #include "vscalar.h" #include "objectstore.h" #include "datasourcepluginmanager.h" namespace Kst { ScalarFactory::ScalarFactory() : PrimitiveFactory() { registerFactory(Scalar::staticTypeTag, this); } ScalarFactory::~ScalarFactory() { } PrimitivePtr ScalarFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QString descriptiveName; Q_ASSERT(store); bool orphan, editable; double value=0.0; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == Scalar::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); value = attrs.value("value").toString().toDouble(); orphan = attrs.value("orphan").toString() == "true" ? true : false; editable = attrs.value("editable").toString() == "true" ? true : false; if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == "scalar") { break; } else { Debug::self()->log(QObject::tr("Error creating scalar from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } ScalarPtr scalar = store->createObject(); scalar->setValue(value); scalar->setOrphan(true); scalar->setEditable(true); scalar->setDescriptiveName(descriptiveName); return scalar; } //////////////////////////////////////// DataScalarFactory::DataScalarFactory() : PrimitiveFactory() { registerFactory(DataScalar::staticTypeTag, this); } DataScalarFactory::~DataScalarFactory() { } PrimitivePtr DataScalarFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QString descriptiveName; Q_ASSERT(store); QString provider, file, field; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == DataScalar::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); provider = attrs.value("provider").toString(); file = DataPrimitive::readFilename(attrs); field = attrs.value("field").toString(); if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == DataScalar::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating scalar from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } Q_ASSERT(store); DataSourcePtr dataSource = DataSourcePluginManager::findOrLoadSource(store, file); if (!dataSource) { return 0; //Couldn't find a suitable datasource } DataScalarPtr scalar = store->createObject(); scalar->writeLock(); scalar->change(dataSource, field); scalar->setDescriptiveName(descriptiveName); scalar->registerChange(); scalar->unlock(); return scalar; } //////////////////////////////////////// VScalarFactory::VScalarFactory() : PrimitiveFactory() { registerFactory(VScalar::staticTypeTag, this); } VScalarFactory::~VScalarFactory() { } PrimitivePtr VScalarFactory::generatePrimitive(ObjectStore *store, QXmlStreamReader& xml) { QString descriptiveName; Q_ASSERT(store); QString provider, file, field; int f0=0; while (!xml.atEnd()) { const QString n = xml.name().toString(); if (xml.isStartElement()) { if (n == VScalar::staticTypeTag) { QXmlStreamAttributes attrs = xml.attributes(); provider = attrs.value("provider").toString(); file = DataPrimitive::readFilename(attrs); field = attrs.value("field").toString(); f0 = attrs.value("f0").toString().toInt(); if (attrs.value("descriptiveNameIsManual").toString() == "true") { descriptiveName = attrs.value("descriptiveName").toString(); } Object::processShortNameIndexAttributes(attrs); } else { return 0; } } else if (xml.isEndElement()) { if (n == VScalar::staticTypeTag) { break; } else { Debug::self()->log(QObject::tr("Error creating scalar from Kst file."), Debug::Warning); return 0; } } xml.readNext(); } if (xml.hasError()) { return 0; } Q_ASSERT(store); DataSourcePtr dataSource = DataSourcePluginManager::findOrLoadSource(store, file); if (!dataSource) { return 0; //Couldn't find a suitable datasource } VScalarPtr scalar = store->createObject(); scalar->writeLock(); scalar->change(dataSource, field, f0); scalar->setDescriptiveName(descriptiveName); scalar->registerChange(); scalar->unlock(); return scalar; } } // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/nextcolor.h000644 001750 001750 00000002273 11544160210 017134 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2003 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef _NEXTCOLOR_H #define _NEXTCOLOR_H #include #include "kst_export.h" class KPalette; namespace Kst { class KSTCORE_EXPORT NextColor { public: virtual ~NextColor(); virtual QColor next() = 0; static NextColor& self(); protected: NextColor(); private: static NextColor* _instance; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/updatemanager.h000644 001750 001750 00000003623 11544160210 017734 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef UPDATEMANAGER_H #define UPDATEMANAGER_H #include "object.h" #include #include namespace Kst { class ObjectStore; class KSTCORE_EXPORT UpdateManager : public QObject { Q_OBJECT public: static UpdateManager *self(); void setMinimumUpdatePeriod(const int period) { _minUpdatePeriod = period; } int minimumUpdatePeriod() { return _minUpdatePeriod; } void setPaused(bool paused) { _paused = paused;} bool paused() { return _paused; } void setStore(ObjectStore *store) {_store = store;} public Q_SLOTS: void doUpdates(bool forceImmediate = false); void delayedUpdates(); void viewItemUpdateFinished() { _updateInProgress = false; } Q_SIGNALS: void objectsUpdated(qint64 serial); private: UpdateManager(); ~UpdateManager(); static void cleanup(); QTime _time; private: bool _delayedUpdate; int _minUpdatePeriod; bool _paused; bool _delayedUpdateScheduled; bool _updateInProgress; qint64 _serial; ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/kst_i18n.h000644 001750 001750 00000004150 11544160210 016553 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_I18N_H #define KST_I18N_H // #define USE_KDE_I18N #ifdef USE_KDE_I18N #include #else #include #ifndef I18N_NOOP #define I18N_NOOP(x) x #endif #ifndef I18N_NOOP2 #define I18N_NOOP2(comment,x) x #endif //i18n inline QString i18n (const char *text) { return text; } template inline QString i18n (const char *text, const A1 &a1) { return QString(text).arg(a1); } template inline QString i18n (const char *text, const A1 &a1, const A2 &a2) { return QString(text).arg(a1, a2); } template inline QString i18n (const char *text, const A1 &a1, const A2 &a2, const A3 &a3) { return QString(text).arg(a1, a2, a3); } //i18nc inline QString i18nc (const char *, const char *text) { return i18n(text); } template inline QString i18nc (const char *, const char *text, const A1 &a1) { return i18n(text, a1); } template inline QString i18nc (const char *, const char *text, const A1 &a1, const A2 &a2) { return i18n(text, a1, a2); } template inline QString i18nc (const char *, const char *text, const A1 &a1, const A2 &a2, const A3 &a3) { return i18n(text, a1, a2, a3); } #endif #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datasourcepluginmanager.cpp000644 001750 001750 00000037425 11544160210 022365 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2010 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasourcepluginmanager.h" #include "datasource.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kst_i18n.h" #include "datacollection.h" #include "debug.h" #include "objectstore.h" #include "scalar.h" #include "string.h" #include "updatemanager.h" #include "dataplugin.h" #include "datasourcepluginmanager.h" #define DATASOURCE_UPDATE_TIMER_LENGTH 1000 using namespace Kst; QStringList Kst::pluginSearchPaths() { QStringList pluginPaths; QDir rootDir = QApplication::applicationDirPath(); rootDir.cdUp(); QString path = rootDir.canonicalPath() + "/"; pluginPaths << path + QLatin1String("plugins"); pluginPaths << path + QLatin1String(KST_INSTALL_PLUGINS); rootDir.cdUp(); path = rootDir.canonicalPath() + "/"; path += QLatin1String(KST_INSTALL_PLUGINS); pluginPaths << path + QLatin1String("/Release"); pluginPaths << path + QLatin1String("/Debug"); Debug::self()->log(QString("\nPlugin Search Pathes:")); foreach(const QString& p, pluginPaths) { Debug::self()->log(QString("-> %1").arg(p)); } return pluginPaths; } QSettings DataSourcePluginManager::settingsObject("kst", "data"); QMap DataSourcePluginManager::url_map; const QMap DataSourcePluginManager::urlMap() { return url_map; } void DataSourcePluginManager::init() { initPlugins(); } struct FoundPlugin { FoundPlugin(const SharedPtr& plug, const QString& path) : plugin(plug), filePath(path) {} SharedPtr plugin; // TODO add filepath to PluginInterface QString filePath; }; typedef QList PluginList; static PluginList _pluginList; void DataSourcePluginManager::cleanupForExit() { _pluginList.clear(); qDebug() << "cleaning up for exit in datasource"; // for (QMap::Iterator i = urlMap.begin(); i != urlMap.end(); ++i) { // KIO::NetAccess::removeTempFile(i.value()); // } url_map.clear(); } QString DataSourcePluginManager::obtainFile(const QString& source) { QUrl url; if (QFile::exists(source) && QFileInfo(source).isRelative()) { url.setPath(source); } else { url = QUrl(source); } // if (url.isLocalFile() || url.protocol().isEmpty() || url.protocol().toLower() == "nad") { return source; // } if (url_map.contains(source)) { return url_map[source]; } // FIXME: come up with a way to indicate the "widget" and fill it in here so // that KIO dialogs are associated with the proper window // if (!KIO::NetAccess::exists(url, true, 0L)) { // return QString(); // } QString tmpFile; // FIXME: come up with a way to indicate the "widget" and fill it in here so // that KIO dialogs are associated with the proper window // if (!KIO::NetAccess::download(url, tmpFile, 0L)) { // return QString(); // } url_map[source] = tmpFile; return tmpFile; } // Scans for plugins and stores the information for them in "_pluginList" static void scanPlugins() { PluginList tmpList; Debug::self()->log(i18n("Scanning for data-source plugins.")); foreach (QObject *plugin, QPluginLoader::staticInstances()) { //try a cast if (DataSourcePluginInterface *ds = dynamic_cast(plugin)) { tmpList.append(FoundPlugin(ds, "")); } } QStringList pluginPaths = pluginSearchPaths(); foreach (const QString& pluginPath, pluginPaths) { QDir d(pluginPath); foreach (QString fileName, d.entryList(QDir::Files)) { #ifdef Q_OS_WIN if (!fileName.endsWith(".dll")) continue; #endif QPluginLoader loader(d.absoluteFilePath(fileName)); QObject *plugin = loader.instance(); if (plugin) { if (DataSourcePluginInterface *ds = dynamic_cast(plugin)) { tmpList.append(FoundPlugin(ds, d.absoluteFilePath(fileName))); Debug::self()->log(QString("Plugin loaded: %1").arg(fileName)); } } else { Debug::self()->log(QString("instance failed for %1 (%2)").arg(fileName).arg(loader.errorString())); } } } // This cleans up plugins that have been uninstalled and adds in new ones. // Since it is a shared pointer it can't dangle anywhere. _pluginList.clear(); _pluginList = tmpList; } void DataSourcePluginManager::initPlugins() { if (_pluginList.isEmpty()) { scanPlugins(); } } QStringList DataSourcePluginManager::pluginList() { // Ensure state. When using kstapp MainWindow calls init. init(); QStringList plugins; for (PluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { plugins += (*it).plugin->pluginName(); } return plugins; } QString DataSourcePluginManager::pluginFileName(const QString& pluginName) { for (PluginList::ConstIterator it = _pluginList.begin(); it != _pluginList.end(); ++it) { if (it->plugin->pluginName() == pluginName) { return it->filePath; } } return "not avaolable"; } int DataSourcePluginManager::PluginSortContainer::operator<(const PluginSortContainer& x) const { return match > x.match; // yes, this is by design. biggest go first } int DataSourcePluginManager::PluginSortContainer::operator==(const PluginSortContainer& x) const { return match == x.match; } QList DataSourcePluginManager::bestPluginsForSource(const QString& filename, const QString& type) { QList bestPlugins; DataSourcePluginManager::init(); PluginList info = _pluginList; if (!type.isEmpty()) { for (PluginList::Iterator it = info.begin(); it != info.end(); ++it) { if (DataSourcePluginInterface *p = dynamic_cast((*it).plugin.data())) { if (p->provides(type)) { PluginSortContainer psc; psc.match = 100; psc.plugin = p; bestPlugins.append(psc); return bestPlugins; } } } } for (PluginList::Iterator it = info.begin(); it != info.end(); ++it) { PluginSortContainer psc; if (DataSourcePluginInterface *p = dynamic_cast((*it).plugin.data())) { if ((psc.match = p->understands(&settingsObject, filename)) > 0) { psc.plugin = p; bestPlugins.append(psc); } } } qSort(bestPlugins); return bestPlugins; } DataSourcePtr DataSourcePluginManager::findPluginFor(ObjectStore *store, const QString& filename, const QString& type, const QDomElement& e) { QList bestPlugins = bestPluginsForSource(filename, type); // we don't actually iterate here, unless the first plugin fails. (Not sure this helps at all.) for (QList::Iterator i = bestPlugins.begin(); i != bestPlugins.end(); ++i) { DataSourcePtr plugin = (*i).plugin->create(store, &settingsObject, filename, QString(), e); if (plugin) { // add strings const QStringList strings = plugin->string().list(); if (!strings.isEmpty()) { foreach(const QString& key, strings) { QString value; DataString::ReadInfo readInfo(&value); plugin->string().read(key, readInfo); StringPtr s = store->createObject(); s->setProvider(plugin); s->setSlaveName(key); s->setValue(value); } } // add scalars const QStringList scalars = plugin->scalar().list(); if (!scalars.isEmpty()) { foreach(const QString& key, scalars) { double value; DataScalar::ReadInfo readInfo(&value); plugin->scalar().read(key, readInfo); ScalarPtr s = store->createObject(); s->setProvider(plugin); s->setSlaveName(key); s->setValue(value); } } return plugin; } } return 0L; } DataSourcePtr DataSourcePluginManager::loadSource(ObjectStore *store, const QString& filename, const QString& type) { #ifndef Q_WS_WIN32 //if (filename == "stdin" || filename == "-") { // FIXME: what store do we put this in? // return new StdinSource(0, settingsObject); //} #endif QString fn = obtainFile(filename); if (fn.isEmpty()) { return 0L; } DataSourcePtr dataSource = findPluginFor(store, fn, type); if (dataSource) { store->addObject(dataSource); } return dataSource; } DataSourcePtr DataSourcePluginManager::findOrLoadSource(ObjectStore *store, const QString& filename) { Q_ASSERT(store); DataSourcePtr dataSource = store->dataSourceList().findReusableFileName(filename); if (!dataSource) { dataSource = DataSourcePluginManager::loadSource(store, filename); } return dataSource; } bool DataSourcePluginManager::validSource(const QString& filename) { #ifndef Q_WS_WIN32 // if (filename == "stdin" || filename == "-") { // return true; // } #endif QString fn = obtainFile(filename); if (fn.isEmpty()) { return false; } DataSourcePluginManager::init(); PluginList info = _pluginList; for (PluginList::Iterator it = info.begin(); it != info.end(); ++it) { if (DataSourcePluginInterface *p = dynamic_cast((*it).plugin.data())) { if ((p->understands(&settingsObject, filename)) > 0) { return true; } } } return false; } bool DataSourcePluginManager::pluginHasConfigWidget(const QString& plugin) { initPlugins(); PluginList info = _pluginList; for (PluginList::ConstIterator it = info.begin(); it != info.end(); ++it) { if ((*it).plugin->pluginName() == plugin) { return (*it).plugin->hasConfigWidget(); } } return false; } DataSourceConfigWidget* DataSourcePluginManager::configWidgetForPlugin(const QString& plugin) { initPlugins(); PluginList info = _pluginList; for (PluginList::Iterator it = info.begin(); it != info.end(); ++it) { if (DataSourcePluginInterface *p = dynamic_cast((*it).plugin.data())) { if (p->pluginName() == plugin) { return p->configWidget(&settingsObject, QString()); } } } return 0L; } bool DataSourcePluginManager::sourceHasConfigWidget(const QString& filename, const QString& type) { if (filename == "stdin" || filename == "-") { return 0L; } QString fn = obtainFile(filename); if (fn.isEmpty()) { return 0L; } QList bestPlugins = bestPluginsForSource(fn, type); for (QList::Iterator i = bestPlugins.begin(); i != bestPlugins.end(); ++i) { return (*i).plugin->hasConfigWidget(); } Debug::self()->log(i18n("Could not find a datasource for '%1'(%2), but we found one just prior. Something is wrong with Kst.", filename, type), Debug::Error); return false; } DataSourceConfigWidget* DataSourcePluginManager::configWidgetForSource(const QString& filename, const QString& type) { if (filename == "stdin" || filename == "-") { return 0L; } QString fn = obtainFile(filename); if (fn.isEmpty()) { return 0L; } QList bestPlugins = bestPluginsForSource(fn, type); for (QList::Iterator i = bestPlugins.begin(); i != bestPlugins.end(); ++i) { DataSourceConfigWidget *w = (*i).plugin->configWidget(&settingsObject, fn); // Don't iterate. return w; } Debug::self()->log(i18n("Could not find a datasource for '%1'(%2), but we found one just prior. Something is wrong with Kst.", filename, type), Debug::Error); return 0L; } /* QStringList DataSourcePluginManager::fieldListForSource(const QString& filename, const QString& type, QString *outType, bool *complete) { if (filename == "stdin" || filename == "-") { return QStringList(); } QString fn = obtainFile(filename); if (fn.isEmpty()) { return QStringList(); } QList bestPlugins = bestPluginsForSource(fn, type); QStringList rc; for (QList::Iterator i = bestPlugins.begin(); i != bestPlugins.end(); ++i) { QString typeSuggestion; rc = (*i).plugin->fieldList(settingsObject, fn, QString(), &typeSuggestion, complete); if (!rc.isEmpty()) { if (outType) { if (typeSuggestion.isEmpty()) { *outType = (*i).plugin->provides()[0]; } else { *outType = typeSuggestion; } } break; } } return rc; } */ # if 0 QStringList DataSourcePluginManager::matrixListForSource(const QString& filename, const QString& type, QString *outType, bool *complete) { if (filename == "stdin" || filename == "-") { return QStringList(); } QString fn = obtainFile(filename); if (fn.isEmpty()) { return QStringList(); } QList bestPlugins = bestPluginsForSource(fn, type); QStringList rc; for (QList::Iterator i = bestPlugins.begin(); i != bestPlugins.end(); ++i) { QString typeSuggestion; rc = (*i).plugin->matrixList(settingsObject, fn, QString(), &typeSuggestion, complete); if (!rc.isEmpty()) { if (outType) { if (typeSuggestion.isEmpty()) { *outType = (*i).plugin->provides()[0]; } else { *outType = typeSuggestion; } } break; } } return rc; } #endif QStringList DataSourcePluginManager::scalarListForSource(const QString& filename, const QString& type, QString *outType, bool *complete) { if (filename == "stdin" || filename == "-") { return QStringList(); } QString fn = obtainFile(filename); if (fn.isEmpty()) { return QStringList(); } QList bestPlugins = bestPluginsForSource(fn, type); QStringList rc; for (QList::Iterator i = bestPlugins.begin(); i != bestPlugins.end(); ++i) { QString typeSuggestion; rc = (*i).plugin->scalarList(&settingsObject, fn, QString(), &typeSuggestion, complete); if (!rc.isEmpty()) { if (outType) { if (typeSuggestion.isEmpty()) { *outType = (*i).plugin->provides()[0]; } else { *outType = typeSuggestion; } } break; } } return rc; } QStringList DataSourcePluginManager::stringListForSource(const QString& filename, const QString& type, QString *outType, bool *complete) { if (filename == "stdin" || filename == "-") { return QStringList(); } QString fn = obtainFile(filename); if (fn.isEmpty()) { return QStringList(); } QList bestPlugins = bestPluginsForSource(fn, type); QStringList rc; for (QList::Iterator i = bestPlugins.begin(); i != bestPlugins.end(); ++i) { QString typeSuggestion; rc = (*i).plugin->stringList(&settingsObject, fn, QString(), &typeSuggestion, complete); if (!rc.isEmpty()) { if (outType) { if (typeSuggestion.isEmpty()) { *outType = (*i).plugin->provides()[0]; } else { *outType = typeSuggestion; } } break; } } return rc; } kst-2.0.3/src/libkst/kstcore_pch000644 001750 001750 00000000164 11544160210 017172 0ustar00synthsynth000000 000000 #include #include #include #include #include #include kst-2.0.3/src/libkst/builtinprimitives.h000644 001750 001750 00000002056 11544160210 020700 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BUILTINPRIMITIVES_H #define BUILTINPRIMITIVES_H #include "kst_export.h" namespace Kst { class ObjectStore; namespace Builtins { KSTCORE_EXPORT void initPrimitives(); } } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/datasourcepluginmanager.h000644 001750 001750 00000006241 11544160210 022022 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_DATA_SOURCE_PLUGIN_MANAGER_H #define KST_DATA_SOURCE_PLUGIN_MANAGER_H #include "dataplugin.h" #include "sharedptr.h" #include "datasource.h" #include #include namespace Kst { class ObjectStore; class KSTCORE_EXPORT DataSourcePluginManager { public: static const QMap urlMap(); static void init(); static void cleanupForExit(); static void initPlugins(); /** Returns a list of plugins found on the system. */ static QStringList pluginList(); static QString pluginFileName(const QString& pluginName); static SharedPtr loadSource(ObjectStore *store, const QString& filename, const QString& type = QString()); static SharedPtr loadSource(ObjectStore *store, QDomElement& e); static SharedPtr findOrLoadSource(ObjectStore *store, const QString& filename); static bool validSource(const QString& filename); static bool sourceHasConfigWidget(const QString& filename, const QString& type = QString()); static DataSourceConfigWidget *configWidgetForSource(const QString& filename, const QString& type = QString()); static bool pluginHasConfigWidget(const QString& plugin); static DataSourceConfigWidget *configWidgetForPlugin(const QString& plugin); //static QStringList matrixListForSource(const QString& filename, const QString& type = QString(), QString *outType = 0L, bool *complete = 0L); static QStringList scalarListForSource(const QString& filename, const QString& type = QString(), QString *outType = 0L, bool *complete = 0L); static QStringList stringListForSource(const QString& filename, const QString& type = QString(), QString *outType = 0L, bool *complete = 0L); private: static QSettings settingsObject; static QMap url_map; static QString obtainFile(const QString& source); struct PluginSortContainer { SharedPtr plugin; int match; int operator<(const PluginSortContainer& x) const; int operator==(const PluginSortContainer& x) const; }; static QList bestPluginsForSource(const QString& filename, const QString& type); static DataSourcePtr findPluginFor(ObjectStore *store, const QString& filename, const QString& type, const QDomElement& e = QDomElement()); }; } #endif kst-2.0.3/src/libkst/kst_inf.h000644 001750 001750 00000003164 11544160210 016554 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_INF_H #define KST_INF_H #include #include #include #include #ifdef __sun #include #endif #if !defined(INF) #include static double inf__() { /* work around some strict alignment requirements for double variables on some architectures (e.g. PA-RISC) */ typedef union { unsigned char b[8]; double d; } kjs_double_t; #if Q_BYTE_ORDER == Q_BIG_ENDIAN static const kjs_double_t Inf_Bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; #elif defined(arm) static const kjs_double_t Inf_Bytes = { { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } }; #else static const kjs_double_t Inf_Bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; #endif const double Inf = Inf_Bytes.d; return Inf; } #define INF (::inf__()) #endif #endif // KST_INF_H kst-2.0.3/src/libkst/dataprimitive.cpp000644 001750 001750 00000007465 11544160210 020324 0ustar00synthsynth000000 000000 /*************************************************************************** datastprimitive.cpp - add datasource handling capability to a primitive ------------------- begin : October, 2009 copyright : (C) 2009 by cbn email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "debug.h" #include "kst_i18n.h" #include "dataprimitive.h" #include "datasource.h" #include #include namespace Kst { struct DataPrimitive::Private { Primitive* _primitive; DataSourcePtr _file; static void saveFilename(const QString& fn, QXmlStreamWriter& s); }; void DataPrimitive::Private::saveFilename(const QString& fn, QXmlStreamWriter& s) { if (!fn.isEmpty()) { // QDir::current is set to *.kst's file path in mainwindow.cpp QDir current = QDir::current(); QString relFn = current.relativeFilePath(fn); s.writeAttribute("file", current.absoluteFilePath(fn)); if (QDir::isRelativePath(relFn)) { // is absolute if on a differnt disk/network s.writeAttribute("fileRelative", relFn); } } } DataPrimitive::DataPrimitive(Primitive* primitive) : d(*new Private) { d._file = 0; d._primitive = primitive; _field.clear(); } DataPrimitive::~DataPrimitive() { _field = QString::null; d._file = 0; d._primitive = 0; delete &d; } void DataPrimitive::changeFile(DataSourcePtr in_file) { Q_ASSERT(d._primitive->myLockStatus() == KstRWLock::WRITELOCKED); if (!in_file) { Debug::self()->log(i18n("Data file for vector %1 was not opened.", d._primitive->Name()), Debug::Warning); } d._file = in_file; if (d._file) { d._file->writeLock(); } d._primitive->reset(); if (d._file) { d._file->unlock(); } d._primitive->registerChange(); } /** return the name of the file */ QString DataPrimitive::filename() const { QString rc; if (d._file) { d._file->readLock(); rc = d._file->fileName(); d._file->unlock(); } return rc; } void DataPrimitive::saveFilename(QXmlStreamWriter& s) { if (d._file) { d._file->readLock(); DataPrimitive::Private::saveFilename(d._file->fileName(), s); d._file->unlock(); } } void DataPrimitive::saveFilename(const QString& fileName, QXmlStreamWriter& s) { DataPrimitive::Private::saveFilename(fileName, s); } QString DataPrimitive::readFilename(const QXmlStreamAttributes& attrs) { // TODO discuss strategy: // - first try relative path // - fall back to absolute path // QDir::current is set to *.kst's file path in mainwindow.cpp QDir current = QDir::current(); QString fnRel = attrs.value("fileRelative").toString(); if (!fnRel.isEmpty() && current.exists(fnRel)) { // internally only use absolute paths return current.absoluteFilePath(fnRel); } return attrs.value("file").toString(); } /** return the field */ const QString& DataPrimitive::field() const { return _field; } DataSourcePtr DataPrimitive::dataSource() const { return d._file; } void DataPrimitive::setDataSource(const DataSourcePtr& file) { d._file = file; } } kst-2.0.3/src/libkst/events.h000644 001750 001750 00000003433 11544160210 016422 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2004 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef EVENTS_H #define EVENTS_H #include #include class QDataStream; class QWidget; namespace Kst { #define EventTypeThread (QEvent::User + 1) #define ELOGCaptureEvent (QEvent::User + 2) #define ELOGConfigureEvent (QEvent::User + 3) #define ELOGAttrsEvent (QEvent::User + 4) #define ELOGDebugInfoEvent (QEvent::User + 5) #define ELOGAliveEvent (QEvent::User + 6) #define ELOGDeathEvent (QEvent::User + 7) #define EventTypeLog (QEvent::User + 8) struct ELOGCaptureStruct { QDataStream* pBuffer; int iWidth; int iHeight; }; enum ELOGAttribType { AttribTypeText = 0, AttribTypeBool, AttribTypeCombo, AttribTypeRadio, AttribTypeCheck }; struct ELOGAttribStruct { QString attribName; QString comment; QWidget *pWidget; ELOGAttribType type; QStringList values; bool bMandatory; int iMaxLength; }; typedef QList ELOGAttribList; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/libkst/namedobject.cpp000644 001750 001750 00000015446 11544160210 017733 0ustar00synthsynth000000 000000 /*************************************************************************** namedobject.cpp: adds naming to kst object ------------------- begin : May 29, 2008 copyright : (C) 2008 C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "namedobject.h" namespace Kst { NamedObject::NamedObject() : _manualDescriptiveName(QString()), _shortName(QString("FIXME - set _shortName")) { _initial_vnum = _vnum; // vectors _initial_pnum = _pnum; // plugins _initial_csdnum = _csdnum; // csd _initial_cnum = _cnum; // curves _initial_enum = _enum; // equations _initial_hnum = _hnum; // histograms _initial_inum = _inum; // images _initial_psdnum = _psdnum; // psd _initial_xnum = _xnum; // scalars _initial_tnum = _tnum; // text string _initial_mnum = _mnum; // text string _initial_plotnum = _plotnum; // plots _initial_lnum = _lnum; // legend _initial_dnum = _dnum; // view image _initial_dsnum = _dsnum; // datasource } NamedObject::~NamedObject() { } QString NamedObject::Name() const { return descriptiveName()+" ("+shortName()+')'; } QString NamedObject::CleanedName() const { QString clean_name = Name(); clean_name.replace("\\_","_"); clean_name.replace("\\[","["); clean_name.replace("\\]","]"); return clean_name; } QString NamedObject::descriptiveName() const { if (_manualDescriptiveName.isEmpty()) { return _automaticDescriptiveName(); } else { return _manualDescriptiveName; } } QString NamedObject::shortName() const { return _shortName; } void NamedObject::setDescriptiveName(QString new_name) { _manualDescriptiveName = new_name; } bool NamedObject::descriptiveNameIsManual() const { return !(_manualDescriptiveName.isEmpty()); } // to keep the size of the saved xml files smaller, 'I' // should be set to only the types who are effected by the // creation of the Object. (So, the type itself and any slave // objects which are created) eg: Vectors: VNUM|XNUM // It doesn't hurt to add more (the default is all bits set) // except that it increases the size of the .kst file, and // slows loading (not much, but if you have hundreds of // objects....) void NamedObject::saveNameInfo(QXmlStreamWriter &s, unsigned I) { if (descriptiveNameIsManual()) { s.writeAttribute("descriptiveNameIsManual", "true"); s.writeAttribute("descriptiveName", descriptiveName()); } if (I & VNUM) s.writeAttribute("initialVNum", QString::number(_initial_vnum)); if (I & XNUM) s.writeAttribute("initialXNum", QString::number(_initial_xnum)); if (I & PNUM) s.writeAttribute("initialPNum", QString::number(_initial_pnum)); if (I & CSDNUM) s.writeAttribute("initialCSDNum", QString::number(_initial_csdnum)); if (I & CNUM) s.writeAttribute("initialCNum", QString::number(_initial_cnum)); if (I & ENUM) s.writeAttribute("initialENum", QString::number(_initial_enum)); if (I & HNUM) s.writeAttribute("initialHNum", QString::number(_initial_hnum)); if (I & INUM) s.writeAttribute("initialINum", QString::number(_initial_inum)); if (I & PSDNUM) s.writeAttribute("initialPSDNum", QString::number(_initial_psdnum)); if (I & TNUM) s.writeAttribute("initialTNum", QString::number(_initial_tnum)); if (I & MNUM) s.writeAttribute("initialMNum", QString::number(_initial_mnum)); if (I & PLOTNUM) s.writeAttribute("initialPlotNum", QString::number(_initial_plotnum)); if (I & LNUM) s.writeAttribute("initialLNum", QString::number(_initial_lnum)); if (I & DNUM) s.writeAttribute("initialDNum", QString::number(_initial_dnum)); if (I & DSNUM) s.writeAttribute("initialDSNum", QString::number(_initial_dsnum)); } void NamedObject::processShortNameIndexAttributes(QXmlStreamAttributes &attrs) { QStringRef R; R = attrs.value("initialVNum"); if (!R.isEmpty()) _vnum = R.toString().toInt(); R = attrs.value("initialXNum"); if (!R.isEmpty()) _xnum = R.toString().toInt(); R = attrs.value("initialPNum"); if (!R.isEmpty()) _pnum = R.toString().toInt(); R = attrs.value("initialCSDNum"); if (!R.isEmpty()) _csdnum = R.toString().toInt(); R = attrs.value("initialCNum"); if (!R.isEmpty()) _cnum = R.toString().toInt(); R = attrs.value("initialENum"); if (!R.isEmpty()) _enum = R.toString().toInt(); R = attrs.value("initialHNum"); if (!R.isEmpty()) _hnum = R.toString().toInt(); R = attrs.value("initialINum"); if (!R.isEmpty()) _inum = R.toString().toInt(); R = attrs.value("initialPSDNum"); if (!R.isEmpty()) _psdnum = R.toString().toInt(); R = attrs.value("initialTNum"); if (!R.isEmpty()) _tnum = R.toString().toInt(); R = attrs.value("initialMNum"); if (!R.isEmpty()) _mnum = R.toString().toInt(); R = attrs.value("initialPlotNum"); if (!R.isEmpty()) _plotnum = R.toString().toInt(); R = attrs.value("initialLNum"); if (!R.isEmpty()) _lnum = R.toString().toInt(); R = attrs.value("initialDNum"); if (!R.isEmpty()) _dnum = R.toString().toInt(); R = attrs.value("initialDSNum"); if (!R.isEmpty()) _dsnum = R.toString().toInt(); } // Reset all name indexes. Should only be used by ObjectStore when clearing the store entirely. void NamedObject::resetNameIndex() { _vnum = 1; // vectors _pnum = 1; // plugins _csdnum = 1; // csd _cnum = 1; // curves _enum = 1; // equations _hnum = 1; // histograms _inum = 1; // images _psdnum = 1; // psd _xnum = 1; // scalars _tnum = 1; // text string _mnum = 1; // matrix _plotnum = 1; // plots _lnum = 1; // legends _dnum = 1; // other view objects _dsnum = 1; // datasource max_vnum = 0; // vectors max_pnum = 0; // plugins max_csdnum = 0; // csd max_cnum = 0; // curves max_enum = 0; // equations max_hnum = 0; // histograms max_inum = 0; // images max_psdnum = 0; // psd max_xnum = 0; // scalars max_tnum = 0; // text string max_mnum = 0; // matrix max_plotnum = 0; max_lnum = 0; max_dnum = 0; max_dsnum = 0; } //void NamedObject::_initializeShortName() { //} // QString NamedObject::descriptionTip() const { // return Name(); // } } kst-2.0.3/src/libkst/dateparser.cpp000644 001750 001750 00000006415 11544160210 017606 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2005 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dateparser.h" #include #include #include #include namespace Kst { QDateTime millisecondsToQDateTime(double ms) { QDateTime edt; edt.setTime_t(0); if (ms > 0.0) { double milli = fmod(ms, 1000.0); ms = (ms - milli) / 1000.0; assert(ms < 60*365*24*60*60); // we can't handle big dates yet // this will have to change when we do edt.setTime_t(int(ms)); QTime t = edt.time(); t.setHMS(t.hour(), t.minute(), t.second(), int(milli)); edt.setTime(t); } if (ms < 0.0) { abort(); // unhandled at this point } return edt; } double extDateTimeToMilliseconds(const QDateTime& edt) { double rc = 0.0; if (edt.isNull()) { return rc; } int year = edt.date().year(); if (year > 1969 && year < 2030) { // fix later rc = 1000.0 * edt.toTime_t() + edt.time().msec(); } else { // Manually construct rc abort(); } return rc; } QDateTime parsePlanckDate(const QString& dateString) { QStringList secondSplit = dateString.split('.'); if (secondSplit.isEmpty() || secondSplit.count() > 2) { return QDateTime(); } int seconds = 0; if (secondSplit.count() > 1) { seconds = secondSplit[1].toUInt(); } QStringList mainSplit = secondSplit[0].split(':'); QDateTime edt = QDateTime::currentDateTime(); int offset = QDateTime::currentDateTime().toUTC().toTime_t() - edt.toTime_t(); QDate d = edt.date(); QTime t = edt.time(); int i = 0; switch (mainSplit.count()) { default: return QDateTime(); case 5: { int years = mainSplit[i++].toInt(); if (years < 100) { if (years < 0) { years = 1970 - years; } else { years += 2000; } } d.setYMD(years, d.month(), d.day()); } case 4: { unsigned month = mainSplit[i++].toUInt(); d.setYMD(d.year(), month, d.day()); } case 3: { unsigned day = mainSplit[i++].toInt(); d.setYMD(d.year(), d.month(), day); } edt.setDate(d); case 2: { unsigned hour = mainSplit[i++].toInt(); t.setHMS(hour, t.minute(), t.second()); } case 1: { unsigned minute = mainSplit[i].toInt(); t.setHMS(t.hour(), minute, t.second()); } case 0: t.setHMS(t.hour(), t.minute(), seconds); edt.setTime(t); break; } return edt.addSecs(-offset); } } // vim: ts=2 sw=2 et kst-2.0.3/src/kst/kst.1.txt000644 001750 001750 00000012365 11544160210 015763 0ustar00synthsynth000000 000000 .\" The kst man page .\" .\" (C) 2011 Matthew Truch (and other kst authors) .\" .\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\" .\" This file is part of kst .\" .\" Permission is granted to copy, distribute and/or modify this document .\" under the terms of the GNU Free Documentation License, Version 1.2 or .\" any later version published by the Free Software Foundation; with no .\" Invariant Sections, with no Front-Cover Texts, and with no Back-Cover .\" Texts. A copy of the license is included in the `COPYING.DOC' file .\" as part of this distribution. .\" .TH kst 1 "22 February 2011" "Version @kst_version@" "@kst_binary_name@" .SH NAME kst \(em plots scientific data .SH SYNOPSIS .nh .ad l .TP \fBkst .TP \fBkst .RB "[ " \-F " DATASOURCE ] [ " \-f " STARTFRAME ] [ " \-n " NUMFRAMES ] [ " .BR \-s " FRAMESPERSAMPLE [ " \-a " ] ] kstfile" .TP \fBkst .RB "datasource [ " \-f " STARTFRAME ] [ " \-n " NUMFRAMES ] [ " \-s .RB " FRAMESPERSAMPLE [ " \-a " ] ] " .RB "[ " \-P " PLOTNAME ] [ " \-A "] " .RB "[ " \-d " ] [ " \-l " ] [ " \-b " ] " .RB "[ " \-x " FIELD ] [ " \-e " FIELD ] [ " \-r " RATE ] " .RB "[ " \-y " FIELD ] [ " \-p " FIELD ] [ " \-h " FIELD ] [ " \-z " FIELD ] " .RB "[ " \-\-png " filename ] " .RB "[ " \-\-print " filename [ " \-\-landscape " | " \-\-portrait " ] " .RB "[ " \-\-Letter " | " \-\-A4 " ] ]" .hy .ad n .SH DESCRIPTION kst is a graphical data plotting tool, which includes the ability to plot live data (contiuously update the plot as new data becomes available). kst may be run entirely from within its GUI, in which case no command line arguments are needed. kst has a powerful wizard for easily setting up new plots. In the second invocation, kst loads pre-saved plot specifications from the file .I kstfile and optionally may override some of the settings in that file. In the third invocation, kst displays plots of the data as directed in the default manner. Additional datasources may be specified on the command line with options for that datasource following it. Command line options generally apply to all subsequent options unless later overridden. .SH OPTIONS .TP .B \-A\fR plot all curves in separate plots .TP .B \-a\fR average frames (simple mean) when plotting with .B -s\fR. .TP .B \-\-A4\fR use A4 sized paper for printing. Requires .B \-\-print\fR. .TP .B \-b\fR plot as bargraphs. .TP .B \-d\fR use points when plotting curves. .TP .B \-e\ FIELD\fR use .I FIELD as the magnitude of error bars applied to the next plot. .TP .BR \-F\ datasource\fR override the datasource indicated in the .I kstfile and instead use .I datasource\fR. .TP .B \-f\ STARTFRAME\fR begin plotting at .I STARTFRAME frames into the data. Set to -1 to start at .I NUMFRAMES from the end of the data. .TP .B \-h\ FIELD\fR plot .I FIELD as a histogram. .TP .B \-l\fR use lines when plotting curves. .TP .B \-\-landscape\fR use landscape orientation for printing. Requires .B \-\-print\fR. .B \-\-Letter\fR use US Letter sized paper for printing. Requires .B \-\-print\fR. .TP .B \-n\ NUMFRAMES\fR plot at most .I NUMFRAMES frames of data. Set to -1 to indicate all of the data. .TP .B \-P\ PLOTNAME\fR plot all plots in the plot named .I PLOTNAME\fR. .TP .B \-p\ FIELD\fR plot .I FIELD as a power spectrum plot. .TP .B \-\-png\ filename\fR render to a portable network graphics (png) image with file name .I filename and quit. .TP .B \-\-portrait\fR use portrait orientation for printing. Requires .B \-\-print\fR. .TP .B \-\-print\ filename print the plot to file .I filename and quit. .TP .B \-s\ FRAMESPERSAMPLE\fR plot every .I FRAMESPERSAMPLE frames when plotting. .TP .B \-x\ FIELD\fR use .I FIELD as the X-axis vector. .TP .B \-y\ FIELD\fR plot .I FIELD\fR as an XY plot. .TP .B \-z\ FIELD\fR plot .I FIELD as an image. .SH EXAMPLES Plot all data in column 2 from data.dat. kst data.dat -y 2 Same as above, except only read 20 lines, starting at line 10. kst data.dat -f 10 -n 20 -y 2 also read col 1. One plot per curve. kst data.dat -f 10 -n 20 -y 1 -y 2 Read col 1 from data2.dat and col 1 from data.dat kst data.dat -f 10 -n 20 -y 2 data2.dat -y 1 Same as above, except read 40 lines starting at 30 in data2.dat kst data.dat -f 10 -n 20 -y 2 data2.dat -f 30 -n 40 -y 1 Specify the X vector and error bars: Plot x = col 1 and Y = col 2 and error flags = col 3 from data.dat kst data.dat -x 1 -e 3 -y 2 Get the X vector from data1.dat, and the Y vector from data2.dat. kst data1.dat -x 1 data2.dat -y 1 Placement: Plot column 2 and column 3 in plot P1 and column 4 in plot P2 kst data.dat -P P1 -y 2 -y 3 -P P2 -y 4 .SH BUGS Please report bugs to either the kst mailing list at .I kst@kde.org or to the kde bugzilla under the kst product at .I http://bugs.kde.org/\fR. If you can run kst, you can easily report bugs by selecting .I Bug Report Wizard from the .I Help menu. .SH AUTHOR Matthew Truch .SH LICENSE Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the `COPYING.DOC' file as part of the kst distribution. kst-2.0.3/src/kst/kstdatasourceplugin.desktop000644 001750 001750 00000000154 11544160210 021741 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=ServiceType X-KDE-ServiceType=Kst Data Source X-KDE-Derived=Kst/Plugin kst-2.0.3/src/kst/kst_icon.rc000644 001750 001750 00000000104 11544160210 016405 0ustar00synthsynth000000 000000 IDI_ICON1 ICON DISCARDABLE "../images/kst.ico" kst-2.0.3/src/kst/kstextension.desktop000644 001750 001750 00000000304 11544160210 020401 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=ServiceType X-KDE-ServiceType=Kst Extension X-KDE-Derived=Kst/Plugin [PropertyDef::X-Kst-Enabled] Type=bool [PropertyDef::X-Kst-Extension-Name] Type=QString kst-2.0.3/src/kst/kstplugin.desktop000644 001750 001750 00000000261 11544160210 017665 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=ServiceType X-KDE-ServiceType=Kst/Plugin [PropertyDef::X-Kst-Plugin-Author] Type=QString [PropertyDef::X-Kst-Plugin-Version] Type=QString kst-2.0.3/src/kst/x-kst.desktop000644 001750 001750 00000002412 11544160210 016713 0ustar00synthsynth000000 000000 [Desktop Entry] Type=MimeType MimeType=application/x-kst Icon=kst DefaultApp=kst Patterns=*.kst;*.KST; Comment=Kst Data File Comment[br]=Restr roadoù Kst Comment[ca]=Fitxer de dades Kst Comment[cs]=Kst datový soubor Comment[da]=Kst Datafil Comment[de]=Kst Datendatei Comment[el]=Αρχείο δεδομένων Kst Comment[es]=Archivo de datos de Kst Comment[et]=Kst andmefail Comment[fr]=Fichier de données de Kst Comment[ga]=Comhad Sonraí Kst Comment[gl]=Ficheiro de Dados de Kst Comment[hi]=केएसटी डाटा फ़ाइल Comment[hr]=Kst datoteka podataka Comment[is]=Kst gagnaskrá Comment[it]=File dati Kst Comment[ja]=Kst データファイル Comment[ka]=Kst-ის მონაცემებთა ფაილი Comment[nl]=Kst-gegevensbestand Comment[pa]=Kst ਡਾਟਾ ਫਾਇਲ Comment[pt]=Ficheiro de Dados do Kst Comment[pt_BR]=Arquivo de Dados do Kst Comment[ru]=Файл данных Kst Comment[sr]=Kst-ов фајл података Comment[sr@Latn]=Kst-ov fajl podataka Comment[sv]=Kst-datafil Comment[ta]=கேஎஸ்டி தரவுக் கோப்பு Comment[tg]=Маълумоти Файли Kst Comment[tr]=Kst Veri Dosyası Comment[vi]=Tập tin dữ liệu Kst Comment[xx]=xxKst Data Filexx Comment[zh_CN]=Kst 数据文件 kst-2.0.3/src/kst/kstautosave11.upd000644 001750 001750 00000000222 11544160210 017474 0ustar00synthsynth000000 000000 # Update: kstautosaverc goes away in Kst 1.1 # Id=kstautosave1.1 File=kstautosaverc,kstrc Group=AutoSaveImages AllKeys RemoveGroup=AutoSaveImages kst-2.0.3/src/kst/kstfilter.desktop000644 001750 001750 00000000261 11544160210 017654 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=ServiceType X-KDE-ServiceType=Kst/Filter [PropertyDef::X-Kst-Filter-Author] Type=QString [PropertyDef::X-Kst-Filter-Library] Type=QString kst-2.0.3/src/kst/kstdataobjectplugin.desktop000644 001750 001750 00000000154 11544160210 021707 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=ServiceType X-KDE-ServiceType=Kst Data Object X-KDE-Derived=Kst/Plugin kst-2.0.3/src/kst/kst.desktop000644 001750 001750 00000003037 11544160210 016452 0ustar00synthsynth000000 000000 [Desktop Entry] Type=Application Exec=kst2 -caption "%c" %i %m Icon=kst DocPath=kst/index.html MimeType=application/x-kst; Categories=Qt;KDE;Science; Name=Kst Name[hi]=केएसटी Name[ta]=கேஎஸ்டி Name[xx]=xxKstxx GenericName=Data Viewer GenericName[br]=Gweler ar roadoù GenericName[ca]=Visualitzador de dades GenericName[cs]=Prohlížeč dat GenericName[da]=Datafremviser GenericName[de]=Daten-Betrachter GenericName[el]=Προβολέας δεδομένων GenericName[es]=Visualizador de datos GenericName[et]=Andmete näitaja GenericName[fr]=Afficheur de données GenericName[gl]=Visor de Dados GenericName[hi]=डाटा प्रदर्शक GenericName[hr]=Preglednik podataka GenericName[is]=Gagnaskoðari GenericName[it]=Visualizzatore di dati GenericName[ja]=データビューア GenericName[ka]=მონაცემების დამთვალიერებელი GenericName[nl]=Programma voor het weergegeven van gegevens GenericName[pa]=ਡਾਟਾ ਦਰਸ਼ਕ GenericName[pt]=Visualizador de Dados GenericName[pt_BR]=Visualizador de Dados GenericName[ru]=Средство представления данных GenericName[sr]=Приказивач података GenericName[sr@Latn]=Prikazivač podataka GenericName[sv]=Datavisning GenericName[ta]=தரவு காட்சியாளன் GenericName[tg]=Намоишгари маълумот GenericName[tr]=Veri Göstericisi GenericName[vi]=Bộ xem dữ liệu GenericName[xx]=xxData Viewerxx GenericName[zh_CN]=数据查看器 Encoding=UTF-8 kst-2.0.3/src/kst/kstbasicplugin.desktop000644 001750 001750 00000000155 11544160210 020671 0ustar00synthsynth000000 000000 [Desktop Entry] Encoding=UTF-8 Type=ServiceType X-KDE-ServiceType=Kst Basic Plugin X-KDE-Derived=Kst/Plugin kst-2.0.3/src/kst/kstrcmisc11.upd000644 001750 001750 00000002437 11544160210 017137 0ustar00synthsynth000000 000000 # Update: move things around # Id=kstrcmisc1.1 File=kstrc Group=Kst,EMail Key=EMail Sender,Sender Key=EMail Server,Server Key=EMail Port,Port Key=EMail Authenticate,Authenticate Key=EMail Username,Username Key=EMail Password,Password Key=EMail Encryption,Encryption Key=EMail Authentication,Authentication RemoveKey=EMail Sender RemoveKey=EMail Server RemoveKey=EMail Port RemoveKey=EMail Authenticate RemoveKey=EMail Username RemoveKey=EMail Password RemoveKey=EMail Encryption RemoveKey=EMail Authentication Group=Kst,Grid Lines Key=X Major Grid Lines,X Major Key=Y Major Grid Lines,Y Major Key=X Minor Grid Lines,X Minor Key=Y Minor Grid Lines,Y Minor Key=Major Grid Lines Color,Major Color Key=Minor Grid Lines Color,Minor Color Key=Default Major Grid Lines Color,Default Major Color Key=Default Minor Grid Lines Color,Default Minor Color RemoveKey=X Major Grid Lines RemoveKey=Y Major Grid Lines RemoveKey=X Minor Grid Lines RemoveKey=Y Minor Grid Lines RemoveKey=Major Grid Lines Color RemoveKey=Minor Grid Lines Color RemoveKey=Default Major Grid Lines Color RemoveKey=Default Minor Grid Lines Color Group=Kst,X Axis Key=X Axis Interpret,Interpret Key=X Axis Interpretation,Interpretation Key=X Axis Display,Display RemoveKey=X Axis Interpret RemoveKey=X Axis Interpretation RemoveKey=X Axis Display kst-2.0.3/src/kst/kstui.rc000644 001750 001750 00000006437 11544160210 015752 0ustar00synthsynth000000 000000 &File &Edit &Data &Range &Tools &Plots &Graphics Mode &Settings &Help kst-2.0.3/src/kst/main.cpp000644 001750 001750 00000002130 11544160210 015677 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #ifdef Q_CC_MSVC __declspec(dllexport) #endif int main(int argc, char *argv[]) { Kst::Application app(argc, argv); if (app.mainWindow()->initFromCommandLine()) { app.mainWindow()->show(); return app.exec(); } return 0; } kst-2.0.3/src/kst/main-vld.cpp000644 001750 001750 00000000524 11544160210 016467 0ustar00synthsynth000000 000000 #include // Visual Leak Detector // http://sites.google.com/site/dmoulding/vld #include "vld.h" typedef int (*Main)(int argc, char *argv[]); int main(int argc, char *argv[]) { // build kst as Dll HMODULE kst = LoadLibraryA("kst2d.exe"); Main m = (Main)GetProcAddress(kst, "main"); return (*m)(argc, argv); } kst-2.0.3/src/kst/kst.pro000644 001750 001750 00000001540 11544160210 015576 0ustar00synthsynth000000 000000 TOPOUT_REL=../.. include($$PWD/$$TOPOUT_REL/kst.pri) TEMPLATE = app TARGET = $$kstlib(kst2) DESTDIR = $$OUTPUT_DIR/bin CONFIG -= precompile_header !isEmpty(INSTALL_PREFIX) { target.path = $$INSTALL_PREFIX/bin INSTALLS += target } INCLUDEPATH += \ tmp \ $$TOPLEVELDIR/src/libkst \ $$TOPLEVELDIR/src/libkstmath \ $$TOPLEVELDIR/src/widgets \ $$TOPLEVELDIR/src/libkstapp \ $$OUTPUT_DIR/src/kst/tmp macx { LIBS += -F$$OUTPUT_DIR/lib qtAddLibrary(kst2lib) qtAddLibrary(kst2math) qtAddLibrary(kst2widgets) qtAddLibrary(kst2app) } else { LIBS += \ -L$$OUTPUT_DIR/lib \ -L$$OUTPUT_DIR/plugin \ -l$$kstlib(kst2app) \ -l$$kstlib(kst2widgets) \ -l$$kstlib(kst2math) \ -l$$kstlib(kst2lib) } SOURCES += \ main.cpp RESOURCES += \ $$TOPLEVELDIR/src/images/images.qrc win32:QT += svg opengl win32:RC_FILE = kst_icon.rc kst-2.0.3/src/d2asc/d2asc.cpp000644 001750 001750 00000010166 11544160210 016152 0ustar00synthsynth000000 000000 /*************************************************************************** d2asc.cpp ------------------- begin : Tue Aug 22 13:46:13 CST 2000 copyright : (C) 2000 by Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include // atoi #include #include "datavector.h" #include "datacollection.h" #include "coredocument.h" #include "objectstore.h" #include "datasourcepluginmanager.h" static Kst::CoreDocument _document; void Usage() { fprintf(stderr, "usage: d2asc filename [-f ]\n"); fprintf(stderr, " [-n ] [-s skip [-a]] \n"); fprintf(stderr, " [-x] col1 [[-x] col2 ... [-x] coln]\n"); fprintf(stderr, " -x specifies that the field should be printed in hex\n"); } static void exitHelper() { _document.objectStore()->clear(); } int main(int argc, char *argv[]) { atexit(exitHelper); Kst::DataSourcePtr file; int i; Kst::DataSourcePluginManager::init(); QString filename; QString field_list[40]; bool do_hex[40]; int n_field=0; int start_frame=0, n_frames=2000000; bool do_ave = false, do_skip = false; int n_skip = 0; int NS=0, i_S; if (argc < 3 || argv[1][0] == '-') { Usage(); return -1; } for (i = 0; i < 40; i++) do_hex[i] = false; filename = QString::fromLocal8Bit(argv[1]); for (i = 2; i < argc; i++) { if (argv[i][0] == '-') { if (argv[i][1] == 'f') { i++; start_frame = atoi(argv[i]); } else if (argv[i][1] == 'n') { i++; n_frames = atoi(argv[i]); } else if (argv[i][1] == 's') { i++; n_skip = atoi(argv[i]); if (n_skip>0) do_skip = true; } else if (argv[i][1] == 'a') { do_ave = true; } else if (argv[i][1] == 'x') { i++; field_list[n_field] = QString::fromLocal8Bit(argv[i]); do_hex[n_field] = true; n_field++; } else { Usage(); } } else { field_list[n_field] = QString::fromLocal8Bit(argv[i]); n_field++; } } if (!do_skip) do_ave = false; file = Kst::DataSourcePluginManager::loadSource(_document.objectStore(), filename); if (!file || !file->isValid() || file->isEmpty()) { fprintf(stderr, "d2asc error: file %s has no data\n", qPrintable(filename)); return -2; } /** make vectors and fill the list **/ QList vlist; for (i=0; ivector().isValid(field_list[i])) { fprintf(stderr, "d2asc error: field %s in file %s is not valid\n", qPrintable(field_list[i]), qPrintable(filename)); return -3; } Kst::DataVectorPtr v = _document.objectStore()->createObject(); Q_ASSERT(v); v->change(file, field_list[i], start_frame, n_frames, n_skip, n_skip>0, do_ave); vlist.append(v); } /* find NS */ for (i = 0; i < n_field; i++) { // FIXME: need to learn to wait... //while (vlist.at(i)->update() != Kst::Object::NO_CHANGE) // ; // read vector if (vlist.at(i)->length() > NS) NS = vlist.at(i)->length(); } for (i_S = 0; i_S < NS; i_S++) { for (i = 0; i < n_field; i++) { if (do_hex[i]) { printf("%4x ", (int)vlist.at(i)->interpolate(i_S, NS)); } else { printf("%.16g ", vlist.at(i)->interpolate(i_S, NS)); } } printf("\n"); } return 0; } // vim: ts=2 sw=2 et kst-2.0.3/src/d2asc/d2asc.pro000644 001750 001750 00000001106 11544160210 016162 0ustar00synthsynth000000 000000 TOPOUT_REL=../.. include($$PWD/$$TOPOUT_REL/kst.pri) TEMPLATE = app TARGET = $$kstlib(d2asc) DESTDIR = $$OUTPUT_DIR/bin CONFIG -= precompile_header INCLUDEPATH += \ tmp \ $$TOPLEVELDIR/src/libkst \ $$TOPLEVELDIR/src/libkstmath \ $$TOPLEVELDIR/src/widgets \ $$TOPLEVELDIR/src/libkstapp \ $$OUTPUT_DIR/src/kst/tmp LIBS += \ -L$$OUTPUT_DIR/lib \ -L$$OUTPUT_DIR/plugin \ -l$$kstlib(kst2app) \ -l$$kstlib(kst2widgets) \ -l$$kstlib(kst2math) \ -l$$kstlib(kst2lib) SOURCES += \ d2asc.cpp QMAKE_RPATHDIR += $$OUTPUT_DIR/lib $$OUTPUT_DIR/plugin kst-2.0.3/src/d2d/d2d.pro000644 001750 001750 00000001051 11544160210 015313 0ustar00synthsynth000000 000000 include($$PWD/../../kst.pri) TEMPLATE = app TARGET = $$kstlib(d2d) DESTDIR = $$OUTPUT_DIR/bin CONFIG -= precompile_header INCLUDEPATH += \ tmp \ $$TOPLEVELDIR/src/libkst \ $$TOPLEVELDIR/src/libkstmath \ $$TOPLEVELDIR/src/widgets \ $$TOPLEVELDIR/src/libkstapp \ $$OUTPUT_DIR/src/kst/tmp LIBS += \ -L$$OUTPUT_DIR/lib \ -L$$OUTPUT_DIR/plugin \ -l$$kstlib(kst2app) \ -l$$kstlib(kst2widgets) \ -l$$kstlib(kst2math) \ -l$$kstlib(kst2lib) SOURCES += \ d2d.cpp QMAKE_RPATHDIR += $$OUTPUT_DIR/lib $$OUTPUT_DIR/plugin kst-2.0.3/src/d2d/d2d.cpp000644 001750 001750 00000010517 11544160210 015304 0ustar00synthsynth000000 000000 /*************************************************************************** d2d.cpp ------------------- begin : Tue Jan 16 2007 copyright : (C) 2007 by The University of Toronto email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include // atoi #include // hack to make main() a friend of kstdatasource #define protected public #include "datavector.h" #include "datacollection.h" #undef protected #include "dataplugin.h" void Usage() { fprintf(stderr, "usage: d2d in_filename out_filename [-t ]\n"); fprintf(stderr, " [-f ] [-n ] [-s skip [-a]] \n"); fprintf(stderr, " [-x] col1 [[-x] col2 ... [-x] coln]\n"); } static void exitHelper() { Kst::vectorList.clear(); Kst::scalarList.clear(); Kst::dataObjectList.clear(); } int main(int argc, char *argv[]) { atexit(exitHelper); Kst::DataSource::init(); char field_list[40][120], in_filename[180], out_filename[180], out_type[40]; int n_field=0; int start_frame=0, n_frames=-1; bool do_ave = false, do_skip = false; int n_skip = 0; if (argc < 4 || argv[1][0] == '-' || argv[2][0] == '-') { Usage(); return -1; } strncpy(in_filename, argv[1], 180); strncpy(out_filename, argv[2], 180); for (int i = 3; i < argc; i++) { if (argv[i][0] == '-') { if (argv[i][1] == 'f') { i++; start_frame = atoi(argv[i]); } else if (argv[i][1] == 'n') { i++; n_frames = atoi(argv[i]); } else if (argv[i][1] == 's') { i++; n_skip = atoi(argv[i]); if (n_skip>0) do_skip = true; } else if (argv[i][1] == 'a') { do_ave = true; } else if (argv[i][1] == 't') { i++; strncpy(out_type, argv[i], 40); } else { Usage(); } } else { strncpy(field_list[n_field], argv[i], 120); n_field++; } } if (!do_skip) do_ave = false; Kst::DataSourcePtr file = Kst::DataSource::loadSource(in_filename); if (!file || !file->isValid() || file->isEmpty()) { fprintf(stderr, "d2asc error: file %s has no data\n", in_filename); return -2; } if (n_frames < 0) { n_frames = file->frameCount(); } /** make vectors and fill the list **/ QList vlist; for (int i = 0; i < n_field; i++) { if (!file->isValidField(field_list[i])) { fprintf(stderr, "d2asc error: field %s in file %s is not valid\n", field_list[i], in_filename); return -3; } Kst::DataVectorPtr v = new Kst::DataVector(file, field_list[i], Kst::ObjectTag(field_list[i], file->tag()), start_frame, n_frames, n_skip, n_skip>0, do_ave); vlist.append(v); } /* find NS */ int NS=0; for (int i = 0; i < n_field; i++) { while (vlist.at(i)->update(-1) != Kst::Object::NO_CHANGE) ; // read vector if (vlist.at(i)->length() > NS) NS = vlist.at(i)->length(); } Kst::DataSourcePtr out_file; //FIXME #if 0 KService::List sl = KServiceTypeTrader::self()->query("Kst Data Source"); for (KService::List::ConstIterator it = sl.begin(); it != sl.end(); ++it) { if ((*it)->library() == out_type) { KstSharedPtr p = new KST::DataSourcePlugin(*it); out_file = p->create(kConfigObject, out_filename, QString::null); break; } } #endif if (out_file) { for (int i = 0; i < n_field; i++) { double *data = vlist.at(i)->value(); int n = out_file->writeField(data, field_list[i], start_frame, n_frames); qDebug() << "wrote" << n << "samples for field" << field_list[i]; } } } /* vim: sw=2 ts=2 et */ kst-2.0.3/src/widgets/colorpalette.cpp000644 001750 001750 00000006537 11544160210 020334 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "colorpalette.h" #include #include #include "palette.h" namespace Kst { ColorPalette::ColorPalette(QWidget *parent) : QWidget(parent) { setupUi(this); connect(_palette, SIGNAL(highlighted(const QString&)), this, SLOT(updatePalette(const QString&))); connect(_palette, SIGNAL(activated(const QString&)), this, SLOT(updatePalette(const QString&))); connect(_palette, SIGNAL(currentIndexChanged(int)), this, SIGNAL(selectionChanged())); refresh(DefaultPalette); updatePalette(DefaultPalette); } ColorPalette::~ColorPalette() {} void ColorPalette::updatePalette(const QString &palette) { QString paletteName = palette; if (!paletteName.isEmpty()) { paletteName = selectedPalette(); } Palette* newPalette = new Palette(palette); int numberOfColors = newPalette->colorCount(); int height = _palette->height(); int width = 7 * height; int size = 1; int step = 1; if (numberOfColors > 0) { size = width / numberOfColors; if (size == 0) { size = 1; step = numberOfColors / width; } } int pos = 0; QPixmap pix(width, height); QPainter p(&pix); p.fillRect(p.window(), QColor("white")); for (int i=0; iheight(), QBrush(newPalette->color(i))); ++pos; } _paletteDisplay->setPixmap(pix); delete newPalette; } QString ColorPalette::selectedPalette() { return _palette->currentText(); } void ColorPalette::setPalette(const QString palette) { _palette->setCurrentIndex(_palette->findText(palette)); updatePalette(palette); } bool ColorPalette::selectedPaletteDirty() const { return _palette->currentIndex() != -1; } void ColorPalette::clearSelection() { _palette->setCurrentIndex(-1); QPixmap pix(7 *_palette->height(), _palette->height()); QPainter p(&pix); p.fillRect(p.window(), QColor("white")); _paletteDisplay->setPixmap(pix); } void ColorPalette::refresh( const QString & palette ) { _palette->clear(); QStringList paletteList = Palette::getPaletteList(); paletteList.sort(); _palette->addItems(paletteList); if (!palette.isEmpty()) { int i; for (i = 0; i < _palette->count(); ++i) { if (_palette->itemText(i) == palette) { break; } } if (i == _palette->count()) { i = _palette->findText(DefaultPalette); if (i<0) { i=0; } } _palette->setCurrentIndex(i); } } int ColorPalette::currentPaletteIndex() { return _palette->currentIndex(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/curveselector.ui000644 001750 001750 00000002457 11544160210 020354 0ustar00synthsynth000000 000000 CurveSelector 0 0 318 25 Select a curve to utilize. 0 0 0 0 0 0 300 72 Kst::ComboBox QComboBox
    combobox.h
    kst-2.0.3/src/widgets/curveappearance.ui000644 001750 001750 00000031752 11544160210 020633 0ustar00synthsynth000000 000000 CurveAppearance 0 0 486 203 0 0 0 0 0 50 false Appearance 0 0 QFrame::NoFrame QFrame::Plain true false 0 0 Qt::Horizontal QSizePolicy::Expanding 30 21 0 0 Check this to cause the selected points to be drawn at each data point. Show po&ints 0 0 &Type: false _comboPointSymbol false 0 0 Point Type If "Show Points" is checked, the selected point type will be drawn at each data point. 0 0 &Density: false _comboPointDensity false 0 0 Point Type If "Show Points" is checked, the selected point type will be drawn at each data point. All High Medium Low 0 0 Check this to cause lines to be drawn between data points. Show &lines true 0 0 &Type: false _comboLineStyle 0 0 Line Type If "Show Lines" is checked, the selected line style. 0 0 &Weight: false _spinBoxLineWidth 0 0 Line Width If "Show Lines" is checked, the selected line width. 50 0 0 Check this to cause lines to be drawn between data points. &Bargraph false 0 0 &Type: false _barStyle false 0 0 Line Type If "Show Lines" is checked, the selected line style. Lines Solid Show &head &Type: _comboHeadSymbol 0 0 Kst::ColorButton QToolButton
    colorbutton.h
    _color _showPoints _comboPointSymbol _comboPointDensity _showLines _comboLineStyle _spinBoxLineWidth _showBars _barStyle kst_export.h
    kst-2.0.3/src/widgets/gradienteditor.cpp000644 001750 001750 00000012736 11544160210 020641 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "gradienteditor.h" #include #include #include #include #include namespace Kst { GradientEditor::GradientEditor(QWidget *parent) : QWidget(parent), _gradient(0), _movingStop(-1), _dirty(false) { setMouseTracking(true); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); _gradient = new QLinearGradient(1,0,0,0); _gradient->setCoordinateMode(QGradient::ObjectBoundingMode); } GradientEditor::~GradientEditor() { delete _gradient; } QSize GradientEditor::sizeHint() const { return QSize(120,120); } QGradient GradientEditor::gradient() const { _gradient->setStops(gradientStops()); return *_gradient; } void GradientEditor::setGradient(const QGradient &gradient) { _dirty = false; setGradientStops(gradient.stops()); update(); } void GradientEditor::setDefaultGradientStops(QGradientStops stops) { _defaultGradientStops = stops; } void GradientEditor::resetGradient() { _dirty = true; QLinearGradient defaultGradient(1,0,0,0); clearGradientStops(); setGradientStops(_defaultGradientStops); emit changed(gradient()); update(); } void GradientEditor::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); QList stops = _stopHash.values(); foreach (const Stop &stop, stops) { if (stop.path.contains(event->pos())) { _movingStop = stop.pos; return; } } } void GradientEditor::mouseReleaseEvent(QMouseEvent *event) { QWidget::mouseReleaseEvent(event); if (_movingStop != -1) { _movingStop = -1; return; } bool ok; QRgb color = QColorDialog::getRgba(Qt::white, &ok, parentWidget()); if (ok) { int position = event->pos().x(); Stop stop; stop.pos = position; stop.color = color; stop.path = marker(position); _stopHash.insert(position, stop); _dirty = true; emit changed(gradient()); update(); } } void GradientEditor::mouseMoveEvent(QMouseEvent *event) { QWidget::mouseMoveEvent(event); if (_movingStop != -1) { int position = event->pos().x(); Stop stop = _stopHash.take(_movingStop); stop.pos = position; stop.path = marker(position); _stopHash.insert(position, stop); _movingStop = position; _dirty = true; emit changed(gradient()); } update(); } void GradientEditor::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.fillRect(rect(), QBrush(gradient())); if (isEnabled()) { QPoint cursor = QWidget::mapFromGlobal(QCursor::pos()); if (rect().contains(cursor)) { painter.setPen(Qt::black); QLine line(QPoint(cursor.x(), rect().y()), QPoint(cursor.x(), rect().bottom())); painter.drawLine(line); } QList stops = _stopHash.values(); foreach (const Stop &stop, stops) { if (stop.path.contains(cursor)) { painter.setPen(Qt::white); painter.setBrush(Qt::black); painter.drawPath(stop.path); } else { painter.setPen(Qt::black); painter.setBrush(Qt::white); painter.drawPath(stop.path); } } } } bool GradientEditor::isStopAt(const QPoint &point) const { return _stopHash.contains(point.x()); } QPainterPath GradientEditor::marker(int x) const { qreal length = 15.; qreal altitude = length * 0.8660254037844386468; QLine line(QPoint(x, rect().y()), QPoint(x, rect().bottom())); QPainterPath path; //top triangle QPolygonF top; top << line.p1() - QPointF(length/2., 0.) << line.p1() + QPointF(length/2., 0.) << line.p1() + QPointF(0., altitude); path.addPolygon(top); path.closeSubpath(); //bottom triangle QPolygonF bot; bot << line.p2() - QPointF(length/2., 0.) << line.p2() + QPointF(length/2., 0.) << line.p2() + QPointF(0., -altitude); path.addPolygon(bot); path.closeSubpath(); return path; } QGradientStops GradientEditor::gradientStops() const { QGradientStops realStops; QList stops = _stopHash.values(); foreach (const Stop &stop, stops) { qreal realStop = 1.0 - qreal(stop.pos) / qreal(rect().width()); realStops << qMakePair(realStop, stop.color); } return realStops; } void GradientEditor::setGradientStops(const QGradientStops &stops) { _stopHash.clear(); foreach (const QGradientStop &gradientStop, stops) { int position = int(-((gradientStop.first - 1.0) * qreal(rect().width()))); Stop stop; stop.pos = position; stop.color = gradientStop.second; stop.path = marker(position); _stopHash.insert(position, stop); } } void GradientEditor::clearGradientStops() { _stopHash.clear(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/labelbuilder.h000644 001750 001750 00000002777 11544160210 017734 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELBUILDER_H #define LABELBUILDER_H #include #include "ui_labelbuilder.h" #include #include "kstwidgets_export.h" namespace Kst { class ObjectStore; class KSTWIDGETS_EXPORT LabelBuilder : public QWidget, public Ui::LabelBuilder { Q_OBJECT public: explicit LabelBuilder(QWidget *parent = 0, ObjectStore *store = 0); virtual ~LabelBuilder(); void setObjectStore(ObjectStore *store); QString labelText() const; void setLabelText(const QString &label); Q_SIGNALS: void labelChanged(); private Q_SLOTS: void labelUpdate(const QString&); private: ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/datarange.ui000644 001750 001750 00000021222 11544160210 017404 0ustar00synthsynth000000 000000 DataRange 0 0 611 156 0 0 0 0 Data Range false 0 0 Select this to average the skipped frames together. Provides simple low pass filtering. Boxcar &filter first 0 0 Save memory by sparsely sampling the data Select this to skip frames, rather than reading all of the data. This is useful for reading very long but slowly changing data files. Read &1 sample per: 0 0 Select this to read all of the data up to the end of the file. Read to &end true 0 0 or false 0 0 or false Select this to read data from the end of the file. This is useful for scrolling displays when the file is being appended by another application. Co&unt from end false Number of frame to skip, if "Skip Frames" is selected. frame(s) 1 2147483647 0 0 &Start: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _start 0 0 Select this to average the skipped frames together. Provides simple low pass filtering. &Range: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _range Input a number (starting from 0 for the first value), or the format [[[[YYYY:]MM:]DD:]HH:]MM[.SS] for dates. The index of the first data read. For ASCII files, this is the data row number in the file. For frame based files, this is the first frame. 0 false Input a number (starting from 0 for the first value), or the format [[[[YYYY:]MM:]DD:]HH:]MM[.SS] for dates. The amount of data to read into the vector. For ASCII files, this is the number of data rows. For frame files there may be more than one sample per frame. Dates are input in the format [[[[YYYY:]MM:]DD:]HH:]MM[.SS]. frames false frames _start _startUnits _countFromEnd _range _rangeUnits _readToEnd _doSkip _skip _doFilter kst-2.0.3/src/widgets/datasourceselector.cpp000644 001750 001750 00000005466 11544160210 021532 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasourceselector.h" #include "datasourceselectordialog.h" #include #include #include #include #include #include #include #include #include namespace Kst { DataSourceSelector::DataSourceSelector(QWidget *parent) : QWidget(parent), _mode(QFileDialog::ExistingFile) { setup(); } DataSourceSelector::~DataSourceSelector() { } void DataSourceSelector::setup() { _fileEdit = new QLineEdit(this); _fileButton = new QToolButton(this); QHBoxLayout * layout = new QHBoxLayout(this); layout->setMargin(0); layout->addWidget(_fileEdit); layout->addWidget(_fileButton); setLayout(layout); int size = style()->pixelMetric(QStyle::PM_SmallIconSize); _fileButton->setIcon(QPixmap(":kst_changefile.png")); _fileButton->setFixedSize(size + 8, size + 8); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); connect (_fileEdit, SIGNAL(textChanged(const QString &)), this, SIGNAL(changed(const QString &))); connect (_fileButton, SIGNAL(clicked()), this, SLOT(chooseFile())); QDirModel *dirModel = new QDirModel(this); dirModel->setFilter(QDir::AllEntries); QCompleter *completer = new QCompleter(this); completer->setModel(dirModel); _fileEdit->setCompleter(completer); } QString DataSourceSelector::file() const { return _file; } void DataSourceSelector::setFile(const QString &file) { _file = file; //FIXME grrr QLineEdit doc *lies* to me... the textEdited signal is being triggered!! _fileEdit->blockSignals(true); _fileEdit->setText(_file); _fileEdit->blockSignals(false); emit changed(file); } void DataSourceSelector::chooseFile() { QString file; QPointer dialog = new DataSourceSelectorDialog( _file, this ); if (dialog->exec() == QDialog::Accepted) { file = dialog->selectedDataSource(); if (!file.isEmpty()) { setFile(file); } } delete dialog; } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/datarange.h000644 001750 001750 00000004517 11544160210 017226 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATARANGE_H #define DATARANGE_H #include #include "ui_datarange.h" #include "kstwidgets_export.h" namespace Kst { //FIXME Need to add time related methods/functionality class KSTWIDGETS_EXPORT DataRange : public QWidget, public Ui::DataRange { Q_OBJECT public: DataRange(QWidget *parent = 0); virtual ~DataRange(); qreal start() const; bool startDirty() const; void setStart(qreal start); //FIXME Probably should be an enum... QString startUnits() const; void setStartUnits(const QString &startUnits) const; qreal range() const; bool rangeDirty() const; void setRange(qreal range); //FIXME Probably should be an enum... QString rangeUnits() const; void setRangeUnits(const QString &rangeUnits) const; int skip() const; bool skipDirty() const; void setSkip(int skip); bool countFromEnd() const; bool countFromEndDirty() const; void setCountFromEnd(bool countFromEnd); bool readToEnd() const; bool readToEndDirty() const; void setReadToEnd(bool readToEnd); bool doSkip() const; bool doSkipDirty() const; void setDoSkip(bool doSkip); bool doFilter() const; bool doFilterDirty() const; void setDoFilter(bool doFilter); void clearValues(); void setWidgetDefaults(); void loadWidgetDefaults(); Q_SIGNALS: void modified(); private Q_SLOTS: void countFromEndChanged(); void readToEndChanged(); void doSkipChanged(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/fftoptions.h000644 001750 001750 00000005523 11544160210 017471 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FFTOPTIONS_H #define FFTOPTIONS_H #include #include "ui_fftoptions.h" #include "psd.h" #include "kstwidgets_export.h" namespace Kst { class KSTWIDGETS_EXPORT FFTOptions : public QWidget, public Ui::FFTOptions { Q_OBJECT public: FFTOptions(QWidget *parent = 0); ~FFTOptions(); double sampleRate() const; bool sampleRateDirty() const; void setSampleRate(const double sampleRate); double sigma() const; bool sigmaDirty() const; void setSigma(const double sigma); bool interleavedAverage() const; bool interleavedAverageDirty() const; void setInterleavedAverage(const bool interleavedAverage); int FFTLength() const; bool FFTLengthDirty() const; void setFFTLength(const int FFTLength); bool apodize() const; bool apodizeDirty() const; void setApodize(const bool apodize); bool removeMean() const; bool removeMeanDirty() const; void setRemoveMean(const bool removeMean); QString vectorUnits() const; bool vectorUnitsDirty() const; void setVectorUnits(const QString vectorUnits); QString rateUnits() const; bool rateUnitsDirty() const; void setRateUnits(const QString rateUnits); ApodizeFunction apodizeFunction() const; bool apodizeFunctionDirty() const; void setApodizeFunction(const ApodizeFunction apodizeFunction); PSDType output() const; bool outputDirty() const; void setOutput(const PSDType output); bool interpolateOverHoles() const; bool interpolateOverHolesDirty() const; void setInterpolateOverHoles(const bool interpolateOverHoles); void disableInterpolateOverHoles(); void clearValues(); void setWidgetDefaults(); void loadWidgetDefaults(); Q_SIGNALS: void modified(); public slots: void changedApodizeFxn(); void clickedInterleaved(); void clickedApodize(); void synch(); bool checkValues(); bool checkGivenValues(double sampRate, int FFTLen); private: void init(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/kstwidgets_export.h000644 001750 001750 00000002242 11544160210 021062 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KST_WIDGETS_EXPORT_H #define KST_WIDGETS_EXPORT_H #include #if (defined(Q_OS_WIN32) || defined(Q_OS_WIN64)) # if defined(BUILD_KSTWIDGETS) # define KSTWIDGETS_EXPORT Q_DECL_EXPORT # else # define KSTWIDGETS_EXPORT Q_DECL_IMPORT # endif #else # define KSTWIDGETS_EXPORT #endif #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/stringselector.ui000644 001750 001750 00000005261 11544160210 020532 0ustar00synthsynth000000 000000 StringSelector 0 0 300 39 0 0 Select a string to utilize. If you wish to create a new string, select the icon to the right. 0 0 0 0 0 ... 0 0 Create a new string. false 0 0 Edit selected string. Kst::ComboBox QComboBox
    combobox.h
    _string _selectString _newString _editString
    kst-2.0.3/src/widgets/labellineedit.cpp000644 001750 001750 00000004370 11544160210 020425 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labellineedit.h" #include namespace Kst { LabelLineEdit::LabelLineEdit(QWidget *parent) : QLineEdit(parent) { setWhatsThis(tr("The syntax for labels is a derivative of a subset of LaTeX. " "Supported syntax is: \\[greeklettername] and \\[Greeklettername], " "\\approx, \\cdot, \\ge, \\geq, \\inf ," "\\int, \\le, \\leq, \\ne, \\n, " "\\partial, \\prod, \\pm, " "\\textcolor{color name}{colored text}, \\textbf{bold text}, " "\\textit{italicized text}, \\t, \\sum, \\sqrt, " "\\underline{underlined text}, \\overline{overlined text}, " "x^y, x_y. " "Scalars, equations, and vector elements can be embedded. " "Scalar: [V1/Mean]. Vector Element: [V1[4]]. " "Equation: [=[V1/Mean]^2]. A [ character can be inserted as \\[.")); setToolTip(tr("Label text. A subset of LaTeX is supported. See What's This.")); } LabelLineEdit::~LabelLineEdit() { } void LabelLineEdit::focusInEvent ( QFocusEvent * event ) { emit inFocus(); QLineEdit::focusInEvent(event); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/scalarselector.h000644 001750 001750 00000003574 11544160210 020310 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SCALARSELECTOR_H #define SCALARSELECTOR_H #include #include "ui_scalarselector.h" #include "scalarlistselector.h" #include #include "kstwidgets_export.h" namespace Kst { class ObjectStore; class KSTWIDGETS_EXPORT ScalarSelector : public QWidget, public Ui::ScalarSelector { Q_OBJECT public: explicit ScalarSelector(QWidget *parent = 0, ObjectStore *store = 0); virtual ~ScalarSelector(); void setObjectStore(ObjectStore *store); ScalarPtr selectedScalar(); void setSelectedScalar(ScalarPtr selectedScalar); void fillScalars(); QString selectedScalarString(); void setDefaultValue(double value); virtual bool event(QEvent * event); Q_SIGNALS: void selectionChanged(const QString&); private Q_SLOTS: void newScalar(); void editScalar(); void selectScalar(); void emitSelectionChanged(); void updateDescriptionTip(); private: ScalarListSelector* _scalarListSelector; ObjectStore *_store; bool _defaultsSet; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/curveappearance.cpp000644 001750 001750 00000036163 11544160210 021001 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "curveappearance.h" #include "curvepointsymbol.h" #include "linestyle.h" #include #include "dialogdefaults.h" #include "colorsequence.h" namespace Kst { CurveAppearance::CurveAppearance(QWidget *parent) : QWidget(parent) { setupUi(this); populateSymbolCombos(); populateLineStyleCombo(); drawSampleLine(); connect(_showPoints, SIGNAL(stateChanged(int)), this, SLOT(enableSettings())); connect(_showLines, SIGNAL(stateChanged(int)), this, SLOT(enableSettings())); connect(_showBars, SIGNAL(stateChanged(int)), this, SLOT(enableSettings())); connect(_showHead, SIGNAL(stateChanged(int)), this, SLOT(enableSettings())); connect(_color, SIGNAL(changed(const QColor&)), this, SLOT(populateSymbolCombos())); connect(_color, SIGNAL(changed(const QColor&)), this, SLOT(populateLineStyleCombo())); connect(_headColor, SIGNAL(changed(const QColor&)), this, SLOT(populateSymbolCombos())); connect(_headColor, SIGNAL(changed(const QColor&)), this, SLOT(populateLineStyleCombo())); connect(_color, SIGNAL(changed(const QColor&)), this, SLOT(drawSampleLine())); connect(_headColor, SIGNAL(changed(const QColor&)), this, SLOT(drawSampleLine())); connect(_showLines, SIGNAL(clicked()), this, SLOT(drawSampleLine())); connect(_showPoints, SIGNAL(clicked()), this, SLOT(drawSampleLine())); connect(_showHead, SIGNAL(clicked()), this, SLOT(drawSampleLine())); connect(_comboPointSymbol, SIGNAL(activated(int)), this, SLOT(drawSampleLine())); connect(_comboLineStyle, SIGNAL(activated(int)), this, SLOT(drawSampleLine())); connect(_comboHeadSymbol, SIGNAL(activated(int)), this, SLOT(drawSampleLine())); connect(_spinBoxLineWidth, SIGNAL(valueChanged(int)), this, SLOT(drawSampleLine())); connect(_barStyle, SIGNAL(activated(int)), this, SLOT(drawSampleLine())); connect(_showBars, SIGNAL(clicked()), this, SLOT(drawSampleLine())); connect(_color, SIGNAL(changed(const QColor&)), this, SIGNAL(modified())); connect(_showLines, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_showPoints, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_showHead, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_comboPointDensity, SIGNAL(activated(int)), this, SIGNAL(modified())); connect(_comboPointSymbol, SIGNAL(activated(int)), this, SIGNAL(modified())); connect(_comboHeadSymbol, SIGNAL(activated(int)), this, SIGNAL(modified())); connect(_comboLineStyle, SIGNAL(activated(int)), this, SIGNAL(modified())); connect(_spinBoxLineWidth, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_barStyle, SIGNAL(activated(int)), this, SIGNAL(modified())); connect(_showBars, SIGNAL(clicked()), this, SIGNAL(modified())); } CurveAppearance::~CurveAppearance() { } void CurveAppearance::populateSymbolCombos() { populateSymbolCombo(_comboPointSymbol, color()); populateSymbolCombo(_comboHeadSymbol, headColor()); } void CurveAppearance::populateSymbolCombo(QComboBox *combo, QColor symbolColor) { if (symbolColor == Qt::transparent) { symbolColor = Qt::black; } QStyleOptionComboBox option; option.initFrom(combo); option.currentIcon = combo->itemIcon(combo->currentIndex()); option.currentText = combo->itemText(combo->currentIndex()); option.editable = combo->isEditable(); option.frame = combo->hasFrame(); option.iconSize = combo->iconSize(); QRect rect = combo->style()->subControlRect( QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, combo ); rect.setLeft( rect.left() + 2 ); rect.setRight( rect.right() - 2 ); rect.setTop( rect.top() + 2 ); rect.setBottom( rect.bottom() - 2 ); combo->setIconSize(QSize(rect.width(), rect.height())); // fill the point type dialog with point types QPixmap ppix( rect.width(), rect.height() ); QPainter pp( &ppix ); int currentItem = combo->currentIndex(); combo->clear(); pp.setPen(symbolColor); for (int ptype = 0; ptype < KSTPOINT_MAXTYPE; ptype++) { pp.fillRect(pp.window(), QColor("white")); CurvePointSymbol::draw(ptype, &pp, ppix.width()/2, ppix.height()/2, 0, 600); combo->addItem(QIcon(ppix), QString()); } if (currentItem > 0) { combo->setCurrentIndex( currentItem ); } } void CurveAppearance::enableSettings() { bool enable; enable = showLines() || showBars(); _comboLineStyle->setEnabled(enable); _textLabelLineStyle->setEnabled(enable); enable = enable || showPoints(); _textLabelWeight->setEnabled(enable); _spinBoxLineWidth->setEnabled(enable); enable = showBars(); _textLabelBarStyle->setEnabled(enable); _barStyle->setEnabled(enable); enable = showPoints(); _textLabelPointStyle->setEnabled(enable); _comboPointSymbol->setEnabled(enable); enable = enable && showLines(); _textLabelPointDensity->setEnabled(enable); _comboPointDensity->setEnabled(enable); enable = showHead(); _textLabelHeadStyle->setEnabled(enable); _comboHeadSymbol->setEnabled(enable); } bool CurveAppearance::showLines() const { return _showLines->checkState() == Qt::Checked; } bool CurveAppearance::showLinesDirty() const { return _showLines->checkState() != Qt::PartiallyChecked; } void CurveAppearance::setShowLines(const bool showLines) { _showLines->setChecked(showLines); enableSettings(); drawSampleLine(); } bool CurveAppearance::showPoints() const { return _showPoints->checkState() == Qt::Checked; } bool CurveAppearance::showPointsDirty() const { return _showPoints->checkState() != Qt::PartiallyChecked; } void CurveAppearance::setShowPoints(const bool showPoints) { _showPoints->setChecked(showPoints); enableSettings(); drawSampleLine(); } bool CurveAppearance::showHead() const { return _showHead->checkState() == Qt::Checked; } bool CurveAppearance::showHeadDirty() const { return _showHead->checkState() != Qt::PartiallyChecked; } void CurveAppearance::setShowHead(const bool showHead) { _showHead->setChecked(showHead); enableSettings(); drawSampleLine(); } bool CurveAppearance::showBars() const { return _showBars->checkState() == Qt::Checked; } bool CurveAppearance::showBarsDirty() const { return _showBars->checkState() != Qt::PartiallyChecked; } void CurveAppearance::setShowBars(const bool showBars) { _showBars->setChecked(showBars); enableSettings(); drawSampleLine(); } QColor CurveAppearance::color() const { return _color->color(); } bool CurveAppearance::colorDirty() const { return _color->colorDirty(); } void CurveAppearance::setColor(const QColor & c) { _color->setColor(c); enableSettings(); drawSampleLine(); } QColor CurveAppearance::headColor() const { return _headColor->color(); } bool CurveAppearance::headColorDirty() const { return _headColor->colorDirty(); } void CurveAppearance::setHeadColor(const QColor & c) { _headColor->setColor(c); enableSettings(); drawSampleLine(); } int CurveAppearance::pointType() const { return _comboPointSymbol->currentIndex(); } bool CurveAppearance::pointTypeDirty() const { return _comboPointSymbol->currentIndex() != -1; } void CurveAppearance::setPointType(const int pointType) { _comboPointSymbol->setCurrentIndex(pointType); enableSettings(); drawSampleLine(); } int CurveAppearance::headType() const { return _comboHeadSymbol->currentIndex(); } bool CurveAppearance::headTypeDirty() const { return _comboHeadSymbol->currentIndex() != -1; } void CurveAppearance::setHeadType(const int pointType) { _comboHeadSymbol->setCurrentIndex(pointType); enableSettings(); drawSampleLine(); } int CurveAppearance::lineStyle() const { return _comboLineStyle->currentIndex(); } bool CurveAppearance::lineStyleDirty() const { return _comboLineStyle->currentIndex() != -1; } void CurveAppearance::setLineStyle(int lineStyle) { if (lineStyle < 0 || lineStyle >= (int)LINESTYLE_MAXTYPE) { lineStyle = 0; } _comboLineStyle->setCurrentIndex(lineStyle); enableSettings(); drawSampleLine(); } int CurveAppearance::barStyle() const { return _barStyle->currentIndex(); } bool CurveAppearance::barStyleDirty() const { return _barStyle->currentIndex() != -1; } void CurveAppearance::setBarStyle(const int barStyle) { _barStyle->setCurrentIndex(barStyle); enableSettings(); drawSampleLine(); } int CurveAppearance::pointDensity() const { return _comboPointDensity->currentIndex(); } bool CurveAppearance::pointDensityDirty() const { return _comboPointDensity->currentIndex() != -1; } void CurveAppearance::setPointDensity(int pointDensity) { if (pointDensity < 0 || pointDensity >= POINTDENSITY_MAXTYPE) { pointDensity = 0; } _comboPointDensity->setCurrentIndex(pointDensity); enableSettings(); drawSampleLine(); } int CurveAppearance::lineWidth() const { if (_spinBoxLineWidth->text() == " ") { return 0; } else { return _spinBoxLineWidth->value(); } } bool CurveAppearance::lineWidthDirty() const { return !_spinBoxLineWidth->text().isEmpty(); } void CurveAppearance::setLineWidth(const int lineWidth) { _spinBoxLineWidth->setValue(lineWidth); enableSettings(); drawSampleLine(); } void CurveAppearance::clearValues() { _color->clearSelection(); _headColor->clearSelection(); _spinBoxLineWidth->clear(); _comboHeadSymbol->setCurrentIndex(-1); _comboPointSymbol->setCurrentIndex(-1); _comboPointDensity->setCurrentIndex(-1); _comboLineStyle->setCurrentIndex(-1); _barStyle->setCurrentIndex(-1); _showPoints->setCheckState(Qt::PartiallyChecked); _showLines->setCheckState(Qt::PartiallyChecked); _showBars->setCheckState(Qt::PartiallyChecked); drawSampleLine(); } void CurveAppearance::populateLineStyleCombo() { QStyleOptionComboBox option; option.initFrom(_comboLineStyle); option.currentIcon = _comboLineStyle->itemIcon(_comboLineStyle->currentIndex()); option.currentText = _comboLineStyle->itemText(_comboLineStyle->currentIndex()); option.editable = _comboLineStyle->isEditable(); option.frame = _comboLineStyle->hasFrame(); option.iconSize = _comboLineStyle->iconSize(); QRect rect = _comboLineStyle->style()->subControlRect( QStyle::CC_ComboBox, &option, QStyle::SC_ComboBoxEditField, _comboLineStyle ); rect.setLeft(rect.left() + 2); rect.setRight(rect.right() - 2); rect.setTop(rect.top() + 2); rect.setBottom(rect.bottom() - 2); _comboLineStyle->setIconSize(QSize(rect.width(), rect.height())); // fill the point type dialog with point types QPixmap ppix(rect.width(), rect.height()); QPainter pp(&ppix); QColor lineColor(color()); if (lineColor == Qt::transparent) { lineColor = Qt::black; } QPen pen(lineColor, 1); int currentItem = _comboLineStyle->currentIndex(); _comboLineStyle->clear(); for (int style = 0; style < (int)LINESTYLE_MAXTYPE; style++) { pen.setStyle(LineStyle[style]); pp.setPen(pen); pp.fillRect( pp.window(), QColor("white")); pp.drawLine(1,ppix.height()/2,ppix.width()-1, ppix.height()/2); _comboLineStyle->addItem(QIcon(ppix), QString()); } if (currentItem > 0) { _comboLineStyle->setCurrentIndex( currentItem ); } } void CurveAppearance::drawSampleLine() { QPixmap pix(_label->contentsRect().height()*7, _label->contentsRect().height()); QPainter p(&pix); QPen pen(color(),lineWidth(),LineStyle[lineStyle()]); p.fillRect(p.window(), QColor("white")); if (showBars()) { QRect rectBar((pix.width()-pix.height())/2, pix.height()/2, pix.height(), (pix.height()/2)+1); if (barStyle() == 1) { p.fillRect(rectBar,QBrush(QColor(color()))); p.setPen(QPen(QColor("black"),lineWidth(), LineStyle[lineStyle()])); } else { p.setPen(pen); } p.drawRect(rectBar); } #ifdef Q_WS_WIN32 // Note: This modification was made in response to an apparent bug in Qt 4.4.0 in which any // painting done with a cosmetic pen resulted in a crash. // When this is no longer required similar code should also be removed in ViewItemDialog.cpp and // curve.cpp - setLineWidth(). if (pen.isCosmetic()) { pen.setWidth(1); } #endif p.setPen(pen); if (showLines()) { if (showHead()) { p.drawLine(1, pix.height()/2, pix.width()-10, pix.height()/2); } else { p.drawLine(1, pix.height()/2, pix.width()-1, pix.height()/2); } } if (showPoints()) { pen.setStyle(Qt::SolidLine); p.setPen(pen); CurvePointSymbol::draw(pointType(), &p, pix.width()/2, pix.height()/2, lineWidth(), 600); } if (showHead()) { pen.setStyle(Qt::SolidLine); pen.setColor(headColor()); p.setPen(pen); CurvePointSymbol::draw(headType(), &p, pix.width()-10, pix.height()/2, lineWidth(), 600); } _label->setPixmap(pix); } // store the current state of the widget as the default void CurveAppearance::setWidgetDefaults(bool nextColor) { if (nextColor) { ColorSequence::self().next(); } _dialogDefaults->setValue("curves/showPoints",showPoints()); _dialogDefaults->setValue("curves/showLines", showLines()); _dialogDefaults->setValue("curves/showBars",showBars()); _dialogDefaults->setValue("curves/lineWidth",lineWidth()); _dialogDefaults->setValue("curves/lineStyle",lineStyle()); _dialogDefaults->setValue("curves/pointType", pointType()); _dialogDefaults->setValue("curves/headType", headType()); _dialogDefaults->setValue("curves/pointDensity", pointDensity()); _dialogDefaults->setValue("curves/barStyle", barStyle()); _dialogDefaults->setValue("curves/showHead", showHead()); } // set the widget to the stored default values void CurveAppearance::loadWidgetDefaults() { setColor(ColorSequence::self().current()); ColorSequence::self().next(); setHeadColor(ColorSequence::self().current()); setShowPoints(_dialogDefaults->value("curves/showPoints",false).toBool()); setShowLines(_dialogDefaults->value("curves/showLines",true).toBool()); setShowBars(_dialogDefaults->value("curves/showBars",false).toBool()); setShowHead(_dialogDefaults->value("curves/showHead",false).toBool()); setLineWidth(_dialogDefaults->value("curves/lineWidth",0).toInt()); setLineStyle(_dialogDefaults->value("curves/lineStyle",0).toInt()); setPointType(_dialogDefaults->value("curves/pointType",0).toInt()); setHeadType(_dialogDefaults->value("curves/headType",0).toInt()); setPointDensity(_dialogDefaults->value("curves/pointDensity",0).toInt()); setBarStyle(_dialogDefaults->value("curves/barStyle",0).toInt()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/labellineedit.h000644 001750 001750 00000002360 11544160210 020067 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef LABELLINEEDIT_H #define LABELLINEEDIT_H #include #include #include "kstwidgets_export.h" namespace Kst { class KSTWIDGETS_EXPORT LabelLineEdit : public QLineEdit { Q_OBJECT public: LabelLineEdit(QWidget *parent = 0); virtual ~LabelLineEdit(); virtual void focusInEvent ( QFocusEvent * event ); Q_SIGNALS: void inFocus(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/scalarlistselector.ui000644 001750 001750 00000004154 11544160210 021365 0ustar00synthsynth000000 000000 ScalarListSelector 0 0 285 286 Dialog 70 240 201 32 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok 20 10 41 21 Search: 70 10 201 21 20 40 256 192 buttonBox accepted() Dialog accept() 248 254 157 274 buttonBox rejected() Dialog reject() 316 260 286 274 kst-2.0.3/src/widgets/colorpalette.h000644 001750 001750 00000003007 11544160210 017766 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef COLORPALETTE_H #define COLORPALETTE_H #include #include "ui_colorpalette.h" #include "kstwidgets_export.h" namespace Kst { class KSTWIDGETS_EXPORT ColorPalette : public QWidget, public Ui::ColorPalette { Q_OBJECT public: ColorPalette(QWidget *parent = 0); ~ColorPalette(); QString selectedPalette(); bool selectedPaletteDirty() const; void refresh(const QString &palette = QString()); int currentPaletteIndex(); void setPalette(const QString palette); void clearSelection(); public slots: void updatePalette(const QString &palette = QString()); Q_SIGNALS: void selectionChanged(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/labelbuilder.cpp000644 001750 001750 00000006035 11544160210 020256 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2008 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "labelbuilder.h" #include "objectstore.h" namespace Kst { LabelBuilder::LabelBuilder(QWidget *parent, ObjectStore *store) : QWidget(parent), _store(store) { setupUi(this); _label->setWhatsThis(i18n("The syntax for labels is a derivative of a subset of LaTeX. " "Supported syntax is: \\[greeklettername] and \\[Greeklettername], " "\\approx, \\cdot, \\ge, \\geq, \\inf ," "\\int, \\le, \\leq, \\ne, \\n, " "\\partial, \\prod, \\pm, " "\\textcolor{color name}{colored text}, \\textbf{bold text}, " "\\textit{italicized text}, \\t, \\sum, \\sqrt, " "\\underline{underlined text}, \\overline{overlined text}, " "x^y, x_y. " "Scalars, equations, and vector elements can be embedded. " "Scalar: [V1/Mean]. Vector Element: [V1[4]]. " "Equation: [=[V1/Mean]^2]. A [ character can be inserted as \\[.")); _label->setToolTip(tr("Label text. A subset of LaTeX is supported. See What's This.")); connect(_label, SIGNAL(textChanged()), this, SIGNAL(labelChanged())); connect(_strings, SIGNAL(selectionChanged(QString)), this, SLOT(labelUpdate(const QString&))); connect(_scalars, SIGNAL(selectionChanged(QString)), this, SLOT(labelUpdate(const QString&))); } LabelBuilder::~LabelBuilder() { } void LabelBuilder::setObjectStore(ObjectStore *store) { _store = store; _scalars->setObjectStore(store); _strings->setObjectStore(store); } QString LabelBuilder::labelText() const { return _label->toPlainText(); } void LabelBuilder::setLabelText(const QString &label) { _label->setPlainText(label); } void LabelBuilder::labelUpdate(const QString& string) { QString label = _label->toPlainText(); label += '[' + string + ']'; _label->setPlainText(label); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/scalarlistselector.cpp000644 001750 001750 00000003452 11544160210 021532 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "scalarlistselector.h" namespace Kst { ScalarListSelector::ScalarListSelector(QWidget *parent) : QDialog(parent) { setupUi(this); connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(_search, SIGNAL(textChanged(QString)), this, SLOT(filter(const QString&))); } ScalarListSelector::~ScalarListSelector() { } QString ScalarListSelector::selectedScalar() const { if (_scalars->currentItem()) { return _scalars->currentItem()->text(); } return QString(); } void ScalarListSelector::fillScalars(QStringList &scalars) { _scalars->addItems(scalars); } void ScalarListSelector::clear() { _scalars->clear(); } void ScalarListSelector::filter(const QString& filter) { for (int i = 0; i < _scalars->count(); i++) { QListWidgetItem *item = _scalars->item(i); item->setHidden(!item->text().contains(filter, Qt::CaseInsensitive)); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/curveplacement.h000644 001750 001750 00000003410 11544160210 020304 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CURVEPLACEMENT_H #define CURVEPLACEMENT_H #include #include "ui_curveplacement.h" #include "kstwidgets_export.h" namespace Kst { class PlotItemInterface; class KSTWIDGETS_EXPORT CurvePlacement : public QWidget, public Ui::CurvePlacement { Q_OBJECT public: enum Place { NewPlot, ExistingPlot, NoPlot, NewPlotNewTab }; enum Layout { Auto, Custom, Protect }; CurvePlacement(QWidget *parent = 0); virtual ~CurvePlacement(); Place place() const; void setPlace(Place place); bool scaleFonts() const; PlotItemInterface *existingPlot() const; void setExistingPlots(const QList &existingPlots); void setCurrentPlot(const PlotItemInterface *currentPlot); Layout layout() const; void setLayout(Layout layout); int gridColumns() const; void setGridColumns(int gridColumns); public Q_SLOTS: void updateButtons(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/datasourceselectordialog.cpp000644 001750 001750 00000006107 11544160210 022703 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datasourceselectordialog.h" #include "datasource.h" #include "datasourcepluginmanager.h" #include #include namespace Kst { DataSourceSelectorDialog::DataSourceSelectorDialog(QString &file, QWidget *parent) : QFileDialog(parent) { setFileMode(QFileDialog::Directory); selectFile(file); currentChanged(file); connect(this, SIGNAL(currentChanged(const QString &)), this, SLOT(currentChanged(const QString &))); } DataSourceSelectorDialog::~DataSourceSelectorDialog() { } QString DataSourceSelectorDialog::selectedDataSource() { return selectedFiles().first(); } void DataSourceSelectorDialog::currentChanged(const QString ¤t) { // qDebug() << "currentChanged" << current; if (current.isEmpty()) { setFileMode(QFileDialog::Directory); } else { QFileInfo fileInfo(current); if (fileInfo.isDir()) { // qDebug() << "Directory Selected - valid?" << DataSourcePluginManager::validSource(current); if (DataSourcePluginManager::validSource(current)) { setFileMode(QFileDialog::Directory); } else { setFileMode(QFileDialog::ExistingFile); } } else if (fileInfo.exists()) { // qDebug() << "File Selected - valid?" << DataSourcePluginManager::validSource(current); if (DataSourcePluginManager::validSource(current)) { setFileMode(QFileDialog::ExistingFile); } else { setFileMode(QFileDialog::Directory); } } } QStringList filters; filters << "Any files (*)"; setNameFilters(filters); } void DataSourceSelectorDialog::accept() { QStringList files = selectedFiles(); if (files.isEmpty()) { return; } for (int i = 0; i < files.count(); ++i) { QFileInfo info(files.at(i)); if (!info.exists()) { #ifndef QT_NO_MESSAGEBOX QString message = tr("%1\nFile not found.\nPlease verify the " "correct file name was given."); QMessageBox::warning(this, windowTitle(), message.arg(info.fileName())); #endif // QT_NO_MESSAGEBOX return; } if (info.isDir()) { if (info.fileName().isEmpty() || (info.filePath() == directory().path())) { QDialog::accept(); return; } } } QFileDialog::accept(); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/vectorselector.h000644 001750 001750 00000004132 11544160210 020334 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef VECTORSELECTOR_H #define VECTORSELECTOR_H #include #include "ui_vectorselector.h" #include #include "kstwidgets_export.h" namespace Kst { class ObjectStore; class KSTWIDGETS_EXPORT VectorSelector : public QWidget, public Ui::VectorSelector { Q_OBJECT public: explicit VectorSelector(QWidget *parent = 0, ObjectStore *store = 0); virtual ~VectorSelector(); void setObjectStore(ObjectStore *store); VectorPtr selectedVector() const; bool selectedVectorDirty() const; void setSelectedVector(VectorPtr selectedVector); bool allowEmptySelection() const; void setAllowEmptySelection(bool allowEmptySelection); void clearSelection(); void fillVectors(); void setToLastX(QString field = QString()); void setIsX(bool is_x) {_isX = is_x;} int count() {return _vector->count();} virtual bool event(QEvent * event); Q_SIGNALS: void selectionChanged(const QString&); void contentChanged(); // something in the combo changed (new or edit) private Q_SLOTS: void newVector(); void editVector(); void emitSelectionChanged(); void updateDescriptionTip(); private: bool _allowEmptySelection; bool _isX; ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/combobox.h000644 001750 001750 00000002535 11544160210 017106 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef COMBOBOX_H #define COMBOBOX_H #include #include "kstwidgets_export.h" /* FIXME!! This class needs to be rewritten to give completion... */ namespace Kst { class KSTWIDGETS_EXPORT ComboBox : public QComboBox { Q_OBJECT public: explicit ComboBox(QWidget *parent=0); explicit ComboBox(bool editable, QWidget *parent=0); virtual ~ComboBox(); void setEditable(bool editable); private: void setupLineEdit(); private: bool _editable; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/colorbutton.h000644 001750 001750 00000003127 11544160210 017646 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef COLORBUTTON_H #define COLORBUTTON_H #include #include "kstwidgets_export.h" namespace Kst { class KSTWIDGETS_EXPORT ColorButton : public QToolButton { Q_OBJECT Q_PROPERTY(QColor color READ color WRITE setColor USER true) public: explicit ColorButton(QWidget *parent = 0); explicit ColorButton(const QColor &color, QWidget *parent = 0); virtual ~ColorButton(); QColor color() const; bool colorDirty() const; void clearSelection(); public Q_SLOTS: void setColor(const QColor &color); Q_SIGNALS: void changed(const QColor &color); protected: virtual void paintEvent(QPaintEvent *event); private Q_SLOTS: void chooseColor(); private: QColor _color; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/stringselector.h000644 001750 001750 00000003474 11544160210 020350 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STRINGSELECTOR_H #define STRINGSELECTOR_H #include #include "ui_stringselector.h" #include #include "kstwidgets_export.h" namespace Kst { class ObjectStore; class KSTWIDGETS_EXPORT StringSelector : public QWidget, public Ui::StringSelector { Q_OBJECT public: explicit StringSelector(QWidget *parent = 0, ObjectStore *store = 0); virtual ~StringSelector(); void setObjectStore(ObjectStore *store); StringPtr selectedString() const; void setSelectedString(StringPtr selectedString); bool allowEmptySelection() const; void setAllowEmptySelection(bool allowEmptySelection); void fillStrings(); virtual bool event(QEvent * event); Q_SIGNALS: void selectionChanged(const QString&); private Q_SLOTS: void newString(); void editString(); void emitSelectionChanged(); void updateDescriptionTip(); private: bool _allowEmptySelection; ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/scalarlistselector.h000644 001750 001750 00000002571 11544160210 021200 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SCALARLISTSELECTOR_H #define SCALARLISTSELECTOR_H #include #include "ui_scalarlistselector.h" #include "kstwidgets_export.h" namespace Kst { class KSTWIDGETS_EXPORT ScalarListSelector : public QDialog, public Ui::ScalarListSelector { Q_OBJECT public: ScalarListSelector(QWidget *parent = 0); virtual ~ScalarListSelector(); QString selectedScalar() const; void fillScalars(QStringList& scalars); void clear(); public Q_SLOTS: void filter(const QString& filter); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/stringselector.cpp000644 001750 001750 00000010607 11544160210 020677 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "stringselector.h" #include "dialoglauncher.h" #include "objectstore.h" namespace Kst { StringSelector::StringSelector(QWidget *parent, ObjectStore *store) : QWidget(parent), _allowEmptySelection(false), _store(store) { setupUi(this); int size = style()->pixelMetric(QStyle::PM_SmallIconSize); _newString->setIcon(QPixmap(":kst_stringnew.png")); _editString->setIcon(QPixmap(":kst_stringedit.png")); _newString->setFixedSize(size + 8, size + 8); _editString->setFixedSize(size + 8, size + 8); _selectString->setFixedSize(size + 8, size + 8); fillStrings(); connect(_newString, SIGNAL(pressed()), this, SLOT(newString())); connect(_editString, SIGNAL(pressed()), this, SLOT(editString())); connect(_string, SIGNAL(activated(int)), this, SLOT(emitSelectionChanged())); connect(_string, SIGNAL(currentIndexChanged(int)), this, SLOT(updateDescriptionTip())); } StringSelector::~StringSelector() { } void StringSelector::setObjectStore(ObjectStore *store) { _store = store; fillStrings(); } void StringSelector::updateDescriptionTip() { if (selectedString()) { setToolTip(selectedString()->descriptionTip()); } else { setToolTip(QString()); } } void StringSelector::emitSelectionChanged() { emit selectionChanged(_string->currentText()); } StringPtr StringSelector::selectedString() const { return qVariantValue(_string->itemData(_string->currentIndex())); } void StringSelector::setSelectedString(StringPtr selectedString) { int i=-1,j; for (j=0; j<_string->count() ; j++) { if (selectedString.data() == (qVariantValue(_string->itemData(j)))) { i=j; break; } } Q_ASSERT(i != -1); _string->setCurrentIndex(i); } void StringSelector::newString() { QString stringName; DialogLauncher::self()->showStringDialog(stringName, 0, true); fillStrings(); StringPtr string = kst_cast(_store->retrieveObject(stringName)); if (string) { setSelectedString(string); emitSelectionChanged(); } } void StringSelector::editString() { QString stringName; DialogLauncher::self()->showStringDialog(stringName, ObjectPtr(selectedString()), true); fillStrings(); } void StringSelector::fillStrings() { if (!_store) { return; } QHash strings; StringList stringList = _store->getObjects(); StringList::ConstIterator it = stringList.begin(); for (; it != stringList.end(); ++it) { StringPtr string = (*it); string->readLock(); strings.insert(string->Name(), string); string->unlock(); } QStringList list = strings.keys(); qSort(list); StringPtr current = selectedString(); _string->clear(); foreach (const QString &string, list) { StringPtr s = strings.value(string); _string->addItem(string, qVariantFromValue(s.data())); } if (_allowEmptySelection) //reset the setAllowEmptySelection(true); if (current) setSelectedString(current); _editString->setEnabled(_string->count() > 0); } bool StringSelector::allowEmptySelection() const { return _allowEmptySelection; } void StringSelector::setAllowEmptySelection(bool allowEmptySelection) { _allowEmptySelection = allowEmptySelection; int i = _string->findText(tr("")); if (i != -1) _string->removeItem(i); if (_allowEmptySelection) { _string->insertItem(0, tr(""), qVariantFromValue(0)); _string->setCurrentIndex(0); } } bool StringSelector::event(QEvent * event) { if (event->type() == QEvent::WindowActivate) { fillStrings(); } return QWidget::event(event); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/labelbuilder.ui000644 001750 001750 00000007033 11544160210 020110 0ustar00synthsynth000000 000000 LabelBuilder 0 0 614 153 0 0 16777215 16777215 0 0 &Label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter _label 0 0 Insert scalar in label: false _scalars 0 0 0 0 Insert string in label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _scalars 0 0 Kst::ScalarSelector QWidget
    scalarselector.h
    Kst::StringSelector QWidget
    stringselector.h
    kst-2.0.3/src/widgets/curveplacement.cpp000644 001750 001750 00000007056 11544160210 020651 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "curveplacement.h" #include "plotiteminterface.h" namespace Kst { CurvePlacement::CurvePlacement(QWidget *parent) : QWidget(parent) { setupUi(this); connect(_existingPlot, SIGNAL(toggled(bool)), _plotList, SLOT(setEnabled(bool))); connect(_newPlot, SIGNAL(toggled(bool)), this, SLOT(updateButtons())); connect(_customGrid, SIGNAL(toggled(bool)), this, SLOT(updateButtons())); } CurvePlacement::~CurvePlacement() { } void CurvePlacement::updateButtons() { _layoutGroup->setEnabled(_newPlot->isChecked()); _gridColumns->setEnabled(_customGrid->isChecked()); _gridColumnsLabel->setEnabled(_customGrid->isChecked()); _newTab->setEnabled(_newPlot->isChecked()); if (!_newPlot->isChecked()) { _newTab->setChecked(false); } } CurvePlacement::Place CurvePlacement::place() const { if ((!isVisible()) || _noPlot->isChecked()) return NoPlot; else if (_existingPlot->isChecked()) return ExistingPlot; else if (_newTab->isChecked()) return NewPlotNewTab; else return NewPlot; } void CurvePlacement::setPlace(CurvePlacement::Place place) { switch (place) { case NoPlot: _noPlot->setChecked(true); break; case ExistingPlot: _existingPlot->setChecked(true); break; case NewPlot: _newPlot->setChecked(true); break; case NewPlotNewTab: _newPlot->setChecked(true); _newTab->setChecked(true); default: break; } } bool CurvePlacement::scaleFonts() const { return _scaleFonts->isChecked(); } CurvePlacement::Layout CurvePlacement::layout() const { if (_autoLayout->isChecked()) return Auto; else if (_customGrid->isChecked()) return Custom; else return Protect; } void CurvePlacement::setLayout(CurvePlacement::Layout layout) { switch (layout) { case Auto: _autoLayout->setChecked(true); break; case Custom: _customGrid->setChecked(true); break; case Protect: _protectLayout->setChecked(true); break; default: break; } } PlotItemInterface *CurvePlacement::existingPlot() const { return qVariantValue(_plotList->itemData(_plotList->currentIndex())); } void CurvePlacement::setExistingPlots(const QList &existingPlots) { foreach (PlotItemInterface *plot, existingPlots) { _plotList->addItem(plot->plotName(), qVariantFromValue(plot)); } } void CurvePlacement::setCurrentPlot(const PlotItemInterface *currentPlot) { if (currentPlot) { int index = _plotList->findText(currentPlot->plotName()); if (index >= 0) { _plotList->setCurrentIndex(index); } } } int CurvePlacement::gridColumns() const { return _gridColumns->value(); } void CurvePlacement::setGridColumns(int columns) { _gridColumns->setValue(columns); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/curveappearance.h000644 001750 001750 00000005370 11544160210 020442 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CURVEAPPEARANCE_H #define CURVEAPPEARANCE_H #include #include "ui_curveappearance.h" #include "kstwidgets_export.h" namespace Kst { class KSTWIDGETS_EXPORT CurveAppearance : public QWidget, public Ui::CurveAppearance { Q_OBJECT public: CurveAppearance(QWidget *parent = 0); virtual ~CurveAppearance(); bool showLines() const; bool showLinesDirty() const; void setShowLines(const bool showLines); bool showPoints() const; bool showPointsDirty() const; void setShowPoints(const bool showPoints); bool showHead() const; bool showHeadDirty() const; void setShowHead(const bool showHead); bool showBars() const; bool showBarsDirty() const; void setShowBars(const bool showBars); QColor color() const; bool colorDirty() const; void setColor(const QColor &c); QColor headColor() const; bool headColorDirty() const; void setHeadColor(const QColor &c); int pointType() const; bool pointTypeDirty() const; void setPointType(const int pointType); int headType() const; bool headTypeDirty() const; void setHeadType(const int headType); int lineStyle() const; bool lineStyleDirty() const; void setLineStyle(int lineStyle); int lineWidth() const; bool lineWidthDirty() const; void setLineWidth(const int lineWidth); int barStyle() const; bool barStyleDirty() const; void setBarStyle(const int barStyle); int pointDensity() const; bool pointDensityDirty() const; void setPointDensity(int pointDensity); void clearValues(); void setWidgetDefaults(bool nextColor = true); void loadWidgetDefaults(); private slots: void enableSettings(); void drawSampleLine(); void populateSymbolCombos(); void populateSymbolCombo(QComboBox *combo, QColor color); void populateLineStyleCombo(); Q_SIGNALS: void modified(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/kstwidgets_pch000644 001750 001750 00000002161 11544160210 020065 0ustar00synthsynth000000 000000 #include "kstmath_pch.h" #ifdef KST_PCH_RECURSIVE // math headers #include "basicplugin.h" #include "basicpluginfactory.h" #include "builtinobjects.h" #include "builtinpalettes.h" #include "builtinrelations.h" #include "colorsequence.h" #include "csd.h" #include "csdfactory.h" #include "curve.h" #include "curvefactory.h" #include "curvehint.h" #include "curvepointsymbol.h" #include "dataobject.h" #include "dataobjectplugin.h" #include "dialoglauncher.h" #include "doublecompare.h" #include "emailthread.h" #include "enodefactory.h" #include "enodes.h" #include "eparse-eh.h" #include "eparse.h" #include "equation.h" #include "equationfactory.h" #include "eventmonitorentry.h" #include "eventmonitorfactory.h" #include "histogram.h" #include "histogramfactory.h" #include "image.h" #include "imagefactory.h" #include "kstmath_export.h" #include "labelparser.h" #include "linestyle.h" #include "objectfactory.h" #include "painter.h" #include "palette.h" #include "plotdefines.h" #include "psd.h" #include "psdcalculator.h" #include "psdfactory.h" #include "relation.h" #include "relationfactory.h" #include "settings.h" #endif kst-2.0.3/src/widgets/fftoptions.ui000644 001750 001750 00000031225 11544160210 017655 0ustar00synthsynth000000 000000 FFTOptions 0 0 743 200 FFTOptions 0 0 0 0 FFT Options 0 Default Bartlett Blackman Connes cosine Gaussian (Custom Sigma) Hamming Hann Welch false 0 0 S&igma: false _sigma false 0.010000000000000 0 0 Select from this pulldown the source vector for the Curve's y axis error bars. If "<None>" is selected, there will be no y axis error bars drawn. Create new vectors with the "Vectors" tab. Apodi&ze true 0 0 Fun&ction: false _apodizeFunction Remo&ve mean true 0 0 0 FFT &length: 2^ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _FFTLength Sets the length of the FFTs in generating the power spectrum. 2^10 = 1024, etc. The larger the number, the larger the noise and resolution. 4 24 10 Interleave&d average true Interpolate over &holes false 0 0 0 Sa&mple rate: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _sampleRate The sample rate at which the measurements were acquired, for proper normalization. 60.0 0 0 Apply new data sample specifications to selected vectors. Vector units: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _vectorUnits The units of the Data Vector - for automatic labels. V 0 0 Rate units: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _rateUnits The units for the sample rate. Used for automatic labels. Hz 0 0 0 Ou&tput: false _output Amplitude Spectral Density (V/Hz^1/2) Power Spectral Density (V^2/Hz) Amplitude Spectrum (V) Power Spectrum (V^2) _apodize _apodizeFunction _sigma _FFTLength _sampleRate _vectorUnits _rateUnits kst-2.0.3/src/widgets/widgets.h000644 001750 001750 00000021210 11544160210 016733 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef WIDGETS_H #define WIDGETS_H #include #include #include #include "colorbutton.h" #include "gradienteditor.h" #include "filerequester.h" #include "combobox.h" #include "datarange.h" #include "curveselector.h" #include "vectorselector.h" #include "matrixselector.h" #include "scalarselector.h" #include "stringselector.h" #include "curveappearance.h" #include "curveplacement.h" #include "fftoptions.h" #include "colorpalette.h" #include "datasourceselector.h" #include "labelbuilder.h" #include "labellineedit.h" namespace Kst { class Widgets : public QObject, public QDesignerCustomWidgetCollectionInterface { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) public: Widgets(QObject *parent = 0); virtual ~Widgets(); QList customWidgets() const { return _plugins; } private: QList _plugins; }; class WidgetPlugin : public QObject, public QDesignerCustomWidgetInterface { public: WidgetPlugin(QObject *parent = 0); virtual ~WidgetPlugin(); QString group() const; QString toolTip() const; QString whatsThis() const; QString instanceName() const; QString includeFile() const; QString domXml() const; bool isContainer() const; bool isInitialized() const; QIcon icon() const; void initialize(QDesignerFormEditorInterface *); private: bool _initialized; }; class ColorButtonPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: ColorButtonPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("ColorButton"); } //do not translate QWidget *createWidget(QWidget *parent) { return new ColorButton(parent); } }; class DataSourceSelectorPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: DataSourceSelectorPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("DataSourceSelector"); } //do not translate QWidget *createWidget(QWidget *parent) { return new DataSourceSelector(parent); } }; class GradientEditorPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: GradientEditorPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("GradientEditor"); } //do not translate QWidget *createWidget(QWidget *parent) { return new GradientEditor(parent); } }; class FileRequesterPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: FileRequesterPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("FileRequester"); } //do not translate QWidget *createWidget(QWidget *parent) { return new FileRequester(parent); } }; class ComboBoxPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: ComboBoxPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("ComboBox"); } //do not translate QWidget *createWidget(QWidget *parent) { return new ComboBox(parent); } }; class DataRangePlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: DataRangePlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("DataRange"); } //do not translate QWidget *createWidget(QWidget *parent) { return new DataRange(parent); } }; class CurveSelectorPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: CurveSelectorPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("CurveSelector"); } //do not translate QWidget *createWidget(QWidget *parent) { return new CurveSelector(parent); } }; class VectorSelectorPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: VectorSelectorPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("VectorSelector"); } //do not translate QWidget *createWidget(QWidget *parent) { return new VectorSelector(parent); } }; class MatrixSelectorPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: MatrixSelectorPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("MatrixSelector"); } //do not translate QWidget *createWidget(QWidget *parent) { return new MatrixSelector(parent); } }; class ScalarSelectorPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: ScalarSelectorPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("ScalarSelector"); } //do not translate QWidget *createWidget(QWidget *parent) { return new ScalarSelector(parent); } }; class StringSelectorPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: StringSelectorPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("StringSelector"); } //do not translate QWidget *createWidget(QWidget *parent) { return new StringSelector(parent); } }; class CurveAppearancePlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: CurveAppearancePlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("CurveAppearance"); } //do not translate QWidget *createWidget(QWidget *parent) { return new CurveAppearance(parent); } }; class CurvePlacementPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: CurvePlacementPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("CurvePlacement"); } //do not translate QWidget *createWidget(QWidget *parent) { return new CurvePlacement(parent); } }; class FFTOptionsPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: FFTOptionsPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("FFTOptions"); } //do not translate QWidget *createWidget(QWidget *parent) { return new FFTOptions(parent); } }; class ColorPalettePlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: ColorPalettePlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("ColorPalette"); } //do not translate QWidget *createWidget(QWidget *parent) { return new ColorPalette(parent); } }; class LabelBuilderPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: LabelBuilderPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("LabelBuilder"); } //do not translate QWidget *createWidget(QWidget *parent) { return new LabelBuilder(parent); } }; class LabelLineEditPlugin : public WidgetPlugin { Q_OBJECT Q_INTERFACES(QDesignerCustomWidgetInterface) public: LabelLineEditPlugin(QObject *parent = 0) : WidgetPlugin(parent) {} QString name() const { return QLatin1String("LabelLineEdit"); } //do not translate QWidget *createWidget(QWidget *parent) { return new LabelLineEdit(parent); } }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/gradienteditor.h000644 001750 001750 00000004131 11544160210 020274 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GRADIENTEDITOR_H #define GRADIENTEDITOR_H #include #include #include #include "kstwidgets_export.h" namespace Kst { class KSTWIDGETS_EXPORT GradientEditor : public QWidget { Q_OBJECT public: GradientEditor(QWidget *parent = 0); virtual ~GradientEditor(); virtual QSize sizeHint() const; QGradient gradient() const; void setDefaultGradientStops(QGradientStops stops); bool dirty() const { return _dirty; } public Q_SLOTS: void setGradient(const QGradient &gradient); void resetGradient(); Q_SIGNALS: void changed(const QGradient &gradient); protected: virtual void mousePressEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); virtual void paintEvent(QPaintEvent *event); private: bool isStopAt(const QPoint &point) const; QPainterPath marker(int x) const; QGradientStops gradientStops() const; void setGradientStops(const QGradientStops &stops); void clearGradientStops(); struct Stop { int pos; QColor color; QPainterPath path; }; private: QGradient *_gradient; QHash _stopHash; int _movingStop; QGradientStops _defaultGradientStops; bool _dirty; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/datarange.cpp000644 001750 001750 00000013065 11544160210 017557 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "datarange.h" #include "dialogdefaults.h" namespace Kst { DataRange::DataRange(QWidget *parent) : QWidget(parent) { setupUi(this); connect(_countFromEnd, SIGNAL(toggled(bool)), this, SLOT(countFromEndChanged())); connect(_readToEnd, SIGNAL(toggled(bool)), this, SLOT(readToEndChanged())); connect(_doSkip, SIGNAL(toggled(bool)), this, SLOT(doSkipChanged())); connect(_start, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_range, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_skip, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); connect(_doFilter, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_countFromEnd, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_readToEnd, SIGNAL(toggled(bool)), this, SIGNAL(modified())); connect(_doSkip, SIGNAL(toggled(bool)), this, SIGNAL(modified())); } DataRange::~DataRange() { } void DataRange::clearValues() { _start->clear(); _range->clear(); _skip->clear(); _doFilter->setCheckState(Qt::PartiallyChecked); _readToEnd->setCheckState(Qt::PartiallyChecked); _doSkip->setCheckState(Qt::PartiallyChecked); } qreal DataRange::start() const { return _start->text().toDouble(); } bool DataRange::startDirty() const { return !_start->text().isEmpty(); } void DataRange::setStart(qreal start) { _start->setText(QString::number(start)); } QString DataRange::startUnits() const { return _startUnits->currentText(); } void DataRange::setStartUnits(const QString &startUnits) const { _startUnits->setItemText(_startUnits->currentIndex(), startUnits); } qreal DataRange::range() const { return _range->text().toDouble(); } bool DataRange::rangeDirty() const { return !_range->text().isEmpty(); } void DataRange::setRange(qreal range) { _range->setText(QString::number(range)); } QString DataRange::rangeUnits() const { return _rangeUnits->currentText(); } void DataRange::setRangeUnits(const QString &rangeUnits) const { _rangeUnits->setItemText(_startUnits->currentIndex(), rangeUnits); } int DataRange::skip() const { return _skip->value(); } bool DataRange::skipDirty() const { return !_skip->text().isEmpty(); } void DataRange::setSkip(int skip) { _skip->setValue(skip); } bool DataRange::countFromEnd() const { return _countFromEnd->isChecked(); } void DataRange::setCountFromEnd(bool countFromEnd) { _countFromEnd->setChecked(countFromEnd); } bool DataRange::countFromEndDirty() const { return _readToEnd->checkState() == Qt::PartiallyChecked; } bool DataRange::readToEnd() const { return _readToEnd->isChecked(); } bool DataRange::readToEndDirty() const { return _readToEnd->checkState() == Qt::PartiallyChecked; } void DataRange::setReadToEnd(bool readToEnd) { _readToEnd->setChecked(readToEnd); } bool DataRange::doSkip() const { return _doSkip->isChecked(); } bool DataRange::doSkipDirty() const { return _doSkip->checkState() == Qt::PartiallyChecked; } void DataRange::setDoSkip(bool doSkip) { _doSkip->setChecked(doSkip); } bool DataRange::doFilter() const { return _doFilter->isChecked(); } bool DataRange::doFilterDirty() const { return _doFilter->checkState() == Qt::PartiallyChecked; } void DataRange::setDoFilter(bool doFilter) { _doFilter->setChecked(doFilter); } void DataRange::countFromEndChanged() { if (countFromEnd()) { setReadToEnd(false); } _start->setEnabled(!countFromEnd()); _startUnits->setEnabled(!countFromEnd()); } void DataRange::readToEndChanged() { if (readToEnd()) { setCountFromEnd(false); } _range->setEnabled(!readToEnd()); _rangeUnits->setEnabled(!readToEnd()); } void DataRange::doSkipChanged() { _skip->setEnabled(doSkip()); _doFilter->setEnabled(doSkip()); } void DataRange::setWidgetDefaults() { //FIXME Do we need a V->readLock() here? _dialogDefaults->setValue("vector/range", range()); _dialogDefaults->setValue("vector/start", start()); _dialogDefaults->setValue("vector/countFromEnd", countFromEnd()); _dialogDefaults->setValue("vector/readToEnd", readToEnd()); _dialogDefaults->setValue("vector/skip", skip()); _dialogDefaults->setValue("vector/doSkip", doSkip()); _dialogDefaults->setValue("vector/doAve", doFilter()); } void DataRange::loadWidgetDefaults() { setRange(_dialogDefaults->value("vector/range", 1).toInt()); setStart(_dialogDefaults->value("vector/start", 0).toInt()); setCountFromEnd(_dialogDefaults->value("vector/countFromEnd",false).toBool()); setReadToEnd(_dialogDefaults->value("vector/readToEnd",true).toBool()); setSkip(_dialogDefaults->value("vector/skip", 0).toInt()); setDoSkip(_dialogDefaults->value("vector/doSkip", false).toBool()); setDoFilter(_dialogDefaults->value("vector/doAve",false).toBool()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/filerequester.cpp000644 001750 001750 00000005721 11544160210 020510 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "filerequester.h" #include #include #include #include #include #include #include #include namespace Kst { FileRequester::FileRequester(QWidget *parent) : QWidget(parent), _mode(QFileDialog::AnyFile) { setup(); } FileRequester::~FileRequester() { } void FileRequester::setup() { _fileEdit = new QLineEdit(this); _fileButton = new QToolButton(this); QHBoxLayout * layout = new QHBoxLayout(this); layout->setMargin(0); layout->addWidget(_fileEdit); layout->addWidget(_fileButton); setLayout(layout); int size = style()->pixelMetric(QStyle::PM_SmallIconSize); _fileButton->setIcon(QPixmap(":kst_changefile.png")); _fileButton->setFixedSize(size + 8, size + 8); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); connect (_fileEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updateFile(const QString &))); connect (_fileButton, SIGNAL(clicked()), this, SLOT(chooseFile())); QDirModel *dirModel = new QDirModel(this); dirModel->setFilter(QDir::AllEntries); QCompleter *completer = new QCompleter(this); completer->setModel(dirModel); _fileEdit->setCompleter(completer); } QString FileRequester::file() const { return _file; } void FileRequester::setFile(const QString &file) { _file = file; //FIXME grrr QLineEdit doc *lies* to me... the textEdited signal is being triggered!! _fileEdit->blockSignals(true); _fileEdit->setText(_file); _fileEdit->blockSignals(false); emit changed(file); } void FileRequester::updateFile(const QString &file) { _file = file; emit changed(file); } void FileRequester::chooseFile() { QString file; if (_mode == QFileDialog::ExistingFile) { file = QFileDialog::getOpenFileName(this, tr("Open File"), _file, tr("All Files (*)")); } else if (_mode == QFileDialog::Directory) { file = QFileDialog::getExistingDirectory(this, tr("Logfile Directory"), _file); } else { file = QFileDialog::getSaveFileName(this, tr("Save File"), _file, tr("All Files (*)")); } if (!file.isEmpty()) { setFile(file); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/datasourceselectordialog.h000644 001750 001750 00000002536 11544160210 022352 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATASOURCESELECTORDIALOG_H #define DATASOURCESELECTORDIALOG_H #include #include "kstwidgets_export.h" namespace Kst { class KSTWIDGETS_EXPORT DataSourceSelectorDialog : public QFileDialog { Q_OBJECT public: explicit DataSourceSelectorDialog(QString &file, QWidget *parent = 0); virtual ~DataSourceSelectorDialog(); QString selectedDataSource(); public Q_SLOTS: void currentChanged(const QString ¤t); protected: void accept(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/matrixselector.h000644 001750 001750 00000003373 11544160210 020344 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MATRIXSELECTOR_H #define MATRIXSELECTOR_H #include #include "ui_matrixselector.h" #include #include "kstwidgets_export.h" namespace Kst { class ObjectStore; class KSTWIDGETS_EXPORT MatrixSelector : public QWidget, public Ui::MatrixSelector { Q_OBJECT public: explicit MatrixSelector(QWidget *parent = 0, ObjectStore *store = 0); virtual ~MatrixSelector(); void setObjectStore(ObjectStore *store); MatrixPtr selectedMatrix() const; bool selectedMatrixDirty() const; void setSelectedMatrix(MatrixPtr selectedMatrix); void clearSelection(); virtual bool event(QEvent * event); Q_SIGNALS: void selectionChanged(); public Q_SLOTS: void updateMatrices(); void matrixSelected(int index); private Q_SLOTS: void newMatrix(); void editMatrix(); private: ObjectStore *_store; void fillMatrices(); }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/datasourceselector.h000644 001750 001750 00000003220 11544160210 021161 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATASOURCESELECTOR_H #define DATASOURCESELECTOR_H #include #include #include "kstwidgets_export.h" class QLineEdit; class QToolButton; namespace Kst { class KSTWIDGETS_EXPORT DataSourceSelector : public QWidget { Q_OBJECT Q_PROPERTY(QString file READ file WRITE setFile USER true) public: DataSourceSelector(QWidget *parent = 0); virtual ~DataSourceSelector(); QString file() const; void setMode(QFileDialog::FileMode mode) { _mode = mode; } QLineEdit *_fileEdit; public Q_SLOTS: void setFile(const QString &file); Q_SIGNALS: void changed(const QString &file); private Q_SLOTS: void chooseFile(); private: void setup(); QToolButton *_fileButton; QFileDialog::FileMode _mode; QString _file; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/vectorselector.ui000644 001750 001750 00000004552 11544160210 020530 0ustar00synthsynth000000 000000 VectorSelector 0 0 277 32 Select a vector to utilize. If you wish to create a new vector, click on the icon to the right. 0 0 16777215 16777215 M 0 0 Create a new vector. Opens a vector dialog to create a new vector, which will become the selected vector. false 0 0 Edit selected vector. Opens a vector dialog to edit selected vector. Kst::ComboBox QComboBox
    combobox.h
    kst-2.0.3/src/widgets/widgets.cpp000644 001750 001750 00000006127 11544160210 017300 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "widgets.h" namespace Kst { Widgets::Widgets(QObject *parent) : QObject(parent) { _plugins.append(new ColorButtonPlugin(this)); _plugins.append(new DataSourceSelectorPlugin(this)); _plugins.append(new GradientEditorPlugin(this)); _plugins.append(new FileRequesterPlugin(this)); _plugins.append(new ComboBoxPlugin(this)); _plugins.append(new DataRangePlugin(this)); _plugins.append(new CurveSelectorPlugin(this)); _plugins.append(new VectorSelectorPlugin(this)); _plugins.append(new MatrixSelectorPlugin(this)); _plugins.append(new ScalarSelectorPlugin(this)); _plugins.append(new StringSelectorPlugin(this)); _plugins.append(new CurvePlacementPlugin(this)); _plugins.append(new CurveAppearancePlugin(this)); _plugins.append(new FFTOptionsPlugin(this)); _plugins.append(new ColorPalettePlugin(this)); _plugins.append(new LabelBuilderPlugin(this)); _plugins.append(new LabelLineEditPlugin(this)); } Widgets::~Widgets() { } WidgetPlugin::WidgetPlugin(QObject *parent) : QObject(parent), _initialized(false) { } WidgetPlugin::~WidgetPlugin() { } QString WidgetPlugin::group() const { return tr("Kst Widgets"); } QString WidgetPlugin::toolTip() const { return QString(); } QString WidgetPlugin::whatsThis() const { return QString(); } QString WidgetPlugin::instanceName() const { //QString name = static_cast(this)->name().replace("", ""); QString name = static_cast(this)->name(); QChar camel = name.at(0).toLower(); return name.replace(0,1,camel.toLower()); } QString WidgetPlugin::includeFile() const { return instanceName().toLower() + ".h"; } QString WidgetPlugin::domXml() const { QString name = static_cast(this)->name(); return QString::fromUtf8("") .arg(name).arg(instanceName()); } bool WidgetPlugin::isContainer() const { return false; } bool WidgetPlugin::isInitialized() const { return _initialized; } QIcon WidgetPlugin::icon() const { return QIcon(); } void WidgetPlugin::initialize(QDesignerFormEditorInterface *) { if (_initialized) return; _initialized = true; } Q_EXPORT_PLUGIN2(widgets, Widgets) } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/matrixselector.cpp000644 001750 001750 00000007323 11544160210 020676 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "matrixselector.h" #include "objectstore.h" #include "dialoglauncher.h" #include "datacollection.h" namespace Kst { MatrixSelector::MatrixSelector(QWidget *parent, ObjectStore *store) : QWidget(parent), _store(store) { setupUi(this); int size = style()->pixelMetric(QStyle::PM_SmallIconSize); _newMatrix->setIcon(QPixmap(":kst_matrixnew.png")); _editMatrix->setIcon(QPixmap(":kst_matrixedit.png")); _newMatrix->setFixedSize(size + 8, size + 8); _editMatrix->setFixedSize(size + 8, size + 8); fillMatrices(); connect(_newMatrix, SIGNAL(pressed()), this, SLOT(newMatrix())); connect(_editMatrix, SIGNAL(pressed()), this, SLOT(editMatrix())); connect(_matrix, SIGNAL(currentIndexChanged(int)), this, SLOT(matrixSelected(int))); } MatrixSelector::~MatrixSelector() { } void MatrixSelector::setObjectStore(ObjectStore *store) { _store = store; fillMatrices();; } MatrixPtr MatrixSelector::selectedMatrix() const { return qVariantValue(_matrix->itemData(_matrix->currentIndex())); } bool MatrixSelector::selectedMatrixDirty() const { return _matrix->currentIndex() != -1; } void MatrixSelector::matrixSelected(int index) { Q_UNUSED(index) if (index != -1) emit selectionChanged(); } void MatrixSelector::setSelectedMatrix(MatrixPtr selectedMatrix) { int i = _matrix->findData(qVariantFromValue(selectedMatrix.data())); if (i != -1) { _matrix->setCurrentIndex(i); } } void MatrixSelector::newMatrix() { QString matrixName; DialogLauncher::self()->showMatrixDialog(matrixName, 0, true); fillMatrices(); MatrixPtr matrix = kst_cast(_store->retrieveObject(matrixName)); if (matrix) { setSelectedMatrix(matrix); } } void MatrixSelector::editMatrix() { QString matrixName; DialogLauncher::self()->showMatrixDialog(matrixName, ObjectPtr(selectedMatrix()), true); } void MatrixSelector::clearSelection() { _matrix->setCurrentIndex(-1); } void MatrixSelector::updateMatrices() { fillMatrices();; } void MatrixSelector::fillMatrices() { if (!_store) { return; } QHash matrices; MatrixList matrixList = _store->getObjects(); MatrixList::ConstIterator it = matrixList.begin(); for (; it != matrixList.end(); ++it) { MatrixPtr matrix = (*it); matrix->readLock(); matrices.insert(matrix->Name(), matrix); matrix->unlock(); } QStringList list = matrices.keys(); qSort(list); MatrixPtr current = selectedMatrix(); _matrix->clear(); foreach (const QString &string, list) { MatrixPtr m = matrices.value(string); _matrix->addItem(string, qVariantFromValue(m.data())); } if (current) setSelectedMatrix(current); _editMatrix->setEnabled(_matrix->count() > 0); } bool MatrixSelector::event(QEvent * event) { if (event->type() == QEvent::WindowActivate) { fillMatrices(); } return QWidget::event(event); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/colorbutton.cpp000644 001750 001750 00000004623 11544160210 020203 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "colorbutton.h" #include #include #include namespace Kst { ColorButton::ColorButton(QWidget *parent) : QToolButton(parent), _color(Qt::black) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); connect (this, SIGNAL(clicked()), this, SLOT(chooseColor())); } ColorButton::ColorButton(const QColor &color, QWidget *parent) : QToolButton(parent), _color(color) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); connect (this, SIGNAL(clicked()), this, SLOT(chooseColor())); } ColorButton::~ColorButton() { } QColor ColorButton::color() const { return _color; } void ColorButton::clearSelection() { setColor(QColor(Qt::transparent)); } bool ColorButton::colorDirty() const { return _color != QColor(Qt::transparent); } void ColorButton::setColor(const QColor &color) { _color = color; update(); emit changed(color); } void ColorButton::paintEvent(QPaintEvent *event) { QToolButton::paintEvent(event); if (!isEnabled()) return; QPainter painter(this); QBrush brush(_color); int m = (rect().height())/6; qDrawShadePanel(&painter, rect().x() + m, rect().y() + m, rect().width() - 2*m, rect().height() - 2*m, palette(), /*sunken*/ isDown(), /*lineWidth*/ 1, /*fill*/ &brush); } void ColorButton::chooseColor() { bool ok; if (_color == Qt::transparent) { _color = Qt::black; } QRgb rgba = QColorDialog::getRgba(_color.rgba(), &ok, parentWidget()); if (ok) { QColor color; color.setRgba(rgba); setColor(color); } } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/dialogdefaults.h000644 001750 001750 00000007422 11544160210 020265 0ustar00synthsynth000000 000000 /*************************************************************************** dialogdefaults.h ------------------- begin : November 13, 2007 copyright : (C) 2007 C. Barth Netterfield email : netterfield@astro.utoronto.ca ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KSTDIALOGDEFAULTS #define KSTDIALOGDEFAULTS #include "datavector.h" #include "psd.h" #include "generatedvector.h" #include "datamatrix.h" #include "histogram.h" #include "kstwidgets_export.h" class QSettings; namespace Kst { KSTWIDGETS_EXPORT extern QSettings *_dialogDefaults; KSTWIDGETS_EXPORT void setDataVectorDefaults(DataVectorPtr); KSTWIDGETS_EXPORT void setGenVectorDefaults(GeneratedVectorPtr V); KSTWIDGETS_EXPORT void setDataMatrixDefaults(DataMatrixPtr M); KSTWIDGETS_EXPORT void setHistogramDefaults(HistogramPtr H); } #endif // Dialog defaults are stored and retreived from the Kst::dialogDefaults. // As you add defaults, add them here! // Name Type Where used // vector/datasource QString vectordialog datawizard // vector/range int datarange // vector/start int datarange // vector/countFromEnd bool datarange // vector/readToEnd bool datarange // vector/skip int datarange // vector/doSkip bool datarange // vector/doAve bool datarange // // genVector/min" int vectordialog // genVector/max" int vectordialog // genVector/length int vectordialog // spectrum/freq double FFToptions // spectrum/average bool FFToptions // spectrum/len int FFToptions // spectrum/apodize bool FFToptions // spectrum/removeMean bool FFToptions // spectrum/vUnits QString FFToptions // spectrum/rUnits QString FFToptions // spectrum/apodizeFxn int FFToptions // spectrum/gaussianSigma double FFToptions // spectrum/output int FFToptions // spectrum/interpolateHoles bool FFToptions // curve/xvectorfield QString datawizard, curvedialog // export/filename QString exportgraphicsdialog // export/format QString exportgraphicsdialog // export/xsize exportgraphicsdialog // export/ysize exportgraphicsdialog // export/sizeOption exportgraphicsdialog // picture/startdir pictureitem.cpp // histogram/realTimeAutoBin histogramdialog.cpp // matrix/datasource matrixdialog.cpp // matrix/reqXStart matrixdialog.cpp // matrix/reqYStart matrixdialog.cpp // matrix/xCountFromEnd matrixdialog.cpp // matrix/xNumSteps matrixdialog.cpp // matrix/xReadToEnd matrixdialog.cpp // matrix/yCountFromEnd matrixdialog.cpp // matrix/yNumSteps matrixdialog.cpp // matrix/yReadToEnd matrixdialog.cpp // wizard/doPSD bool datawizard.cpp // wizard/doXY bool datawizard.cpp // wizard/curvePlacement enum datawizard.cpp // wizard/plotCount int datawizard.cpp kst-2.0.3/src/widgets/vectorselector.cpp000644 001750 001750 00000013705 11544160210 020675 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "vectorselector.h" #include "dialoglauncher.h" #include "datacollection.h" #include "objectstore.h" #include "dialogdefaults.h" #include "curve.h" namespace Kst { VectorSelector::VectorSelector(QWidget *parent, ObjectStore *store) : QWidget(parent), _allowEmptySelection(false), _isX(false), _store(store) { setupUi(this); int size = style()->pixelMetric(QStyle::PM_SmallIconSize); _newVector->setIcon(QPixmap(":kst_vectornew.png")); _editVector->setIcon(QPixmap(":kst_vectoredit.png")); _newVector->setFixedSize(size + 8, size + 8); _editVector->setFixedSize(size + 8, size + 8); fillVectors(); connect(_newVector, SIGNAL(pressed()), this, SLOT(newVector())); connect(_editVector, SIGNAL(pressed()), this, SLOT(editVector())); connect(_vector, SIGNAL(activated(int)), this, SLOT(emitSelectionChanged())); connect(_vector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateDescriptionTip())); } VectorSelector::~VectorSelector() { } void VectorSelector::setObjectStore(ObjectStore *store) { _store = store; fillVectors(); } void VectorSelector::updateDescriptionTip() { if (selectedVector()) { setToolTip(selectedVector()->descriptionTip()); } else { setToolTip(QString()); } } void VectorSelector::emitSelectionChanged() { if (_allowEmptySelection && (_vector->count()>0)) { _editVector->setDisabled(_vector->currentIndex()==0); } emit selectionChanged(_vector->currentText()); } VectorPtr VectorSelector::selectedVector() const { return qVariantValue(_vector->itemData(_vector->currentIndex())); } bool VectorSelector::selectedVectorDirty() const { return _vector->currentIndex() != -1; } void VectorSelector::setSelectedVector(VectorPtr selectedVector) { if (!selectedVector) { return; } // "findData can't work here" says the trolls... so we do it 'manually'. //int i = _vector->findData(qVariantFromValue(selectedVector.data())); int i=-1,j; for (j=0; j<_vector->count() ; j++) { if (selectedVector.data() == (qVariantValue(_vector->itemData(j)))) { i=j; break; } } Q_ASSERT(i != -1); _vector->setCurrentIndex(i); } void VectorSelector::clearSelection() { _vector->setCurrentIndex(-1); } bool VectorSelector::allowEmptySelection() const { return _allowEmptySelection; } void VectorSelector::setAllowEmptySelection(bool allowEmptySelection) { _allowEmptySelection = allowEmptySelection; int i = _vector->findText(tr("")); if (i != -1) _vector->removeItem(i); if (_allowEmptySelection) { _vector->insertItem(0, tr(""), qVariantFromValue(0)); _vector->setCurrentIndex(0); _editVector->setEnabled(false); } } void VectorSelector::newVector() { QString newName; if (_isX) { newName = _dialogDefaults->value("curve/xvectorfield","INDEX").toString(); } DialogLauncher::self()->showVectorDialog(newName, 0, true); fillVectors(); VectorPtr vector = kst_cast(_store->retrieveObject(newName)); if (vector) { setSelectedVector(vector); emitSelectionChanged(); emit contentChanged(); } } void VectorSelector::editVector() { if (selectedVector()->provider()) { DialogLauncher::self()->showObjectDialog(selectedVector()->provider()); } else { QString vectorname; DialogLauncher::self()->showVectorDialog(vectorname, ObjectPtr(selectedVector()), true); } fillVectors(); // we might have just changed the name, so refill the combo. emit contentChanged(); } void VectorSelector::setToLastX(QString field) { if (!_store) { return; } int match = -1; VectorList vectors = _store->getObjects(); int size = vectors.size(); for (int i = 0; i < size; ++i) { if (vectors.at(i)->descriptiveName() == field) { match = i; } } if (match >-1) { setSelectedVector(vectors.at(match)); } else { CurveList objects = _store->getObjects(); if (objects.count()>0) { setSelectedVector(objects.at(objects.count()-1)->xVector()); } } } void VectorSelector::fillVectors() { if (!_store) { return; } QHash vectors; VectorList vectorList = _store->getObjects(); VectorList::ConstIterator it = vectorList.begin(); for (; it != vectorList.end(); ++it) { VectorPtr vector = (*it); if (vector->isScalarList()) continue; vector->readLock(); vectors.insert(vector->Name(), vector); vector->unlock(); } QStringList list = vectors.keys(); qSort(list); int current_index = _vector->currentIndex(); VectorPtr current = selectedVector(); _vector->clear(); foreach (const QString &string, list) { VectorPtr v = vectors.value(string); _vector->addItem(string, qVariantFromValue(v.data())); } _editVector->setEnabled(_vector->count() > 0); if (_allowEmptySelection) //reset the setAllowEmptySelection(true); if (current_index==-1) { _vector->setCurrentIndex(current_index); } else if (current) { setSelectedVector(current); } } bool VectorSelector::event(QEvent * event) { if (event->type() == QEvent::WindowActivate) { fillVectors(); } return QWidget::event(event); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/widgets.pro000644 001750 001750 00000003741 11544160210 017315 0ustar00synthsynth000000 000000 TOPOUT_REL=../.. include($$PWD/$$TOPOUT_REL/kst.pri) QT += gui TEMPLATE = lib CONFIG += dll DEFINES += BUILD_KSTWIDGETS CONFIG += designer TARGET = $$kstlib(kst2widgets) DESTDIR = $$OUTPUT_DIR/lib QT += core xml gui !isEmpty(INSTALL_PREFIX) { target.path = $$INSTALL_PREFIX/$$INSTALL_LIBDIR INSTALLS += target } INCLUDEPATH += tmp \ $$TOPLEVELDIR/src/libkst \ $$TOPLEVELDIR/src/libkstmath \ $$OUTPUT_DIR/src/widgets/tmp macx { CONFIG += lib_bundle LIBS += -F$$OUTPUT_DIR/lib qtAddLibrary(kst2lib) qtAddLibrary(kst2math) } else { LIBS += \ -L$$OUTPUT_DIR/lib \ -L$$OUTPUT_DIR/plugin \ -l$$kstlib(kst2math) \ -l$$kstlib(kst2lib) } SOURCES += \ colorbutton.cpp \ colorpalette.cpp \ combobox.cpp \ curveappearance.cpp \ curveplacement.cpp \ curveselector.cpp \ datarange.cpp \ datasourceselectordialog.cpp \ datasourceselector.cpp \ dialogdefaults.cpp \ fftoptions.cpp \ filerequester.cpp \ gradienteditor.cpp \ labelbuilder.cpp \ labellineedit.cpp \ matrixselector.cpp \ scalarlistselector.cpp \ scalarselector.cpp \ stringselector.cpp \ vectorselector.cpp \ widgets.cpp HEADERS += \ colorbutton.h \ colorpalette.h \ combobox.h \ curveappearance.h \ curveplacement.h \ curveselector.h \ datarange.h \ datasourceselectordialog.h \ datasourceselector.h \ dialogdefaults.h \ fftoptions.h \ filerequester.h \ gradienteditor.h \ labelbuilder.h \ labellineedit.h \ matrixselector.h \ scalarselector.h \ scalarlistselector.h \ stringselector.h \ vectorselector.h \ widgets.h FORMS += \ colorpalette.ui \ curveappearance.ui \ curveplacement.ui \ curveselector.ui \ datarange.ui \ fftoptions.ui \ labelbuilder.ui \ matrixselector.ui \ scalarlistselector.ui \ scalarselector.ui \ stringselector.ui \ vectorselector.ui RESOURCES += \ $$TOPLEVELDIR/src/images/images.qrc kst-2.0.3/src/widgets/colorpalette.ui000644 001750 001750 00000003635 11544160210 020163 0ustar00synthsynth000000 000000 ColorPalette 0 0 474 30 0 0 0 0 C&olor palette: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false _palette 0 0 false 0 0 false kst-2.0.3/src/widgets/curveplacement.ui000644 001750 001750 00000014450 11544160210 020500 0ustar00synthsynth000000 000000 CurvePlacement 0 0 424 218 0 0 Placement 0 0 0 Qt::Horizontal QSizePolicy::Fixed 28 20 Do not pl&ace in any plot Place in &existing plot: false 1 0 The name of the data file which will be read for this vector. false QComboBox::InsertAtTop true false Place in &new plot true 0 0 true 0 0 Automati&c layout true Custom &grid: false 1 10 false Colu&mns _gridColumns &Protect existing layout In ne&w tab Scale fonts true _noPlot _existingPlot _plotList _newPlot _autoLayout _customGrid _gridColumns _protectLayout kst-2.0.3/src/widgets/matrixselector.ui000644 001750 001750 00000004333 11544160210 020527 0ustar00synthsynth000000 000000 MatrixSelector 0 0 277 32 Select a vector to utilize. If you wish to create a new vector, click on the icon to the right. 0 0 M 0 0 Create a new vector. Opens a vector dialog to create a new vector, which will become the selected vector. false 0 0 Edit selected vector. Opens a vector dialog to edit selected vector. Kst::ComboBox QComboBox
    combobox.h
    kst-2.0.3/src/widgets/fftoptions.cpp000644 001750 001750 00000021174 11544160210 020024 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fftoptions.h" #include "dialogdefaults.h" namespace Kst { FFTOptions::FFTOptions(QWidget *parent) : QWidget(parent) { setupUi(this); connect(_interleavedAverage, SIGNAL(clicked()), this, SLOT(clickedInterleaved())); connect(_apodize, SIGNAL(clicked()), this, SLOT(clickedApodize())); connect(_apodizeFunction, SIGNAL(activated(int)), this, SLOT(changedApodizeFxn())); connect(_apodize, SIGNAL(clicked()), this, SLOT(changedApodizeFxn())); connect(_apodizeFunction, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_output, SIGNAL(currentIndexChanged(int)), this, SIGNAL(modified())); connect(_apodize, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_removeMean, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_interleavedAverage, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_interpolateOverHoles, SIGNAL(clicked()), this, SIGNAL(modified())); connect(_sampleRate, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_vectorUnits, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_rateUnits, SIGNAL(textChanged(const QString&)), this, SIGNAL(modified())); connect(_sigma, SIGNAL(valueChanged(double)), this, SIGNAL(modified())); connect(_FFTLength, SIGNAL(valueChanged(int)), this, SIGNAL(modified())); } FFTOptions::~FFTOptions() {} void FFTOptions::init() { update(); } double FFTOptions::sampleRate() const { return _sampleRate->text().toDouble(); } bool FFTOptions::sampleRateDirty() const { return !_sampleRate->text().isEmpty(); } void FFTOptions::setSampleRate(const double sampleRate) { _sampleRate->setText(QString::number(sampleRate)); } double FFTOptions::sigma() const { return _sigma->value(); } bool FFTOptions::sigmaDirty() const { return !_sigma->text().isEmpty(); } void FFTOptions::setSigma(const double sigma) { _sigma->setValue(sigma); } bool FFTOptions::interleavedAverage() const { return _interleavedAverage->isChecked(); } bool FFTOptions::interleavedAverageDirty() const { return _interleavedAverage->checkState() == Qt::PartiallyChecked; } void FFTOptions::setInterleavedAverage(const bool interleavedAverage) { _interleavedAverage->setChecked(interleavedAverage); } bool FFTOptions::apodize() const { return _apodize->isChecked(); } bool FFTOptions::apodizeDirty() const { return _apodize->checkState() == Qt::PartiallyChecked; } void FFTOptions::setApodize(const bool apodize) { _apodize->setChecked(apodize); } bool FFTOptions::removeMean() const { return _removeMean->isChecked(); } bool FFTOptions::removeMeanDirty() const { return _removeMean->checkState() == Qt::PartiallyChecked; } void FFTOptions::setRemoveMean(const bool removeMean) { _removeMean->setChecked(removeMean); } bool FFTOptions::interpolateOverHoles() const { return _interpolateOverHoles->isChecked(); } bool FFTOptions::interpolateOverHolesDirty() const { return _interpolateOverHoles->checkState() == Qt::PartiallyChecked; } void FFTOptions::setInterpolateOverHoles(const bool interpolateOverHoles) { _interpolateOverHoles->setChecked(interpolateOverHoles); } int FFTOptions::FFTLength() const { return _FFTLength->value(); } bool FFTOptions::FFTLengthDirty() const { return !_FFTLength->text().isEmpty(); } void FFTOptions::setFFTLength(const int FFTLength) { _FFTLength->setValue(FFTLength); } QString FFTOptions::vectorUnits() const { return _vectorUnits->text(); } bool FFTOptions::vectorUnitsDirty() const { return !_vectorUnits->text().isEmpty(); } void FFTOptions::setVectorUnits(const QString vectorUnits) { _vectorUnits->setText(vectorUnits); } QString FFTOptions::rateUnits() const { return _rateUnits->text(); } bool FFTOptions::rateUnitsDirty() const { return !_rateUnits->text().isEmpty(); } void FFTOptions::setRateUnits(const QString rateUnits) { _rateUnits->setText(rateUnits); } ApodizeFunction FFTOptions::apodizeFunction() const { return (ApodizeFunction)_apodizeFunction->currentIndex(); } bool FFTOptions::apodizeFunctionDirty() const { return _apodizeFunction->currentIndex() != -1; } void FFTOptions::setApodizeFunction(const ApodizeFunction apodizeFunction) { _apodizeFunction->setCurrentIndex((ApodizeFunction)apodizeFunction); } PSDType FFTOptions::output() const { return (PSDType)_output->currentIndex(); } bool FFTOptions::outputDirty() const { return _output->currentIndex() != -1; } void FFTOptions::setOutput(const PSDType output) { _output->setCurrentIndex((PSDType)output); } void FFTOptions::clearValues() { _sigma->clear(); _FFTLength->clear(); _sampleRate->clear(); _vectorUnits->clear(); _rateUnits->clear(); _apodize->setCheckState(Qt::PartiallyChecked); _interleavedAverage->setCheckState(Qt::PartiallyChecked); _removeMean->setCheckState(Qt::PartiallyChecked); _interpolateOverHoles->setCheckState(Qt::PartiallyChecked); _apodizeFunction->setCurrentIndex(-1); _output->setCurrentIndex(-1); } void FFTOptions::disableInterpolateOverHoles() { _interpolateOverHoles->setChecked(false); _interpolateOverHoles->setEnabled(false); } void FFTOptions::changedApodizeFxn() { int gaussianIndex = 5; if (_apodizeFunction->itemText(0).isEmpty()) { ++gaussianIndex; } _sigma->setEnabled(_apodizeFunction->currentIndex() == gaussianIndex && _apodize->isChecked()); _sigmaLabel->setEnabled(_apodizeFunction->currentIndex() == gaussianIndex && _apodize->isChecked()); } void FFTOptions::clickedInterleaved() { _FFTLength->setEnabled(_interleavedAverage->isChecked()); } void FFTOptions::clickedApodize() { _apodizeFunction->setEnabled(_apodize->isChecked()); } void FFTOptions::synch() { clickedInterleaved(); clickedApodize(); } bool FFTOptions::checkValues() { double new_freq = _sampleRate->text().toDouble(); int new_len = _FFTLength->text().toInt(); return checkGivenValues(new_freq, new_len); } bool FFTOptions::checkGivenValues(double sampleRate, int FFTLength) { if (sampleRate <= 0) { return false; } if (FFTLength < 2) { return false; } return true; } // store the current state of the widget as the default void FFTOptions::setWidgetDefaults() { _dialogDefaults->setValue("spectrum/freq", sampleRate()); _dialogDefaults->setValue("spectrum/average", interleavedAverage()); _dialogDefaults->setValue("spectrum/len", FFTLength()); _dialogDefaults->setValue("spectrum/apodize", apodize()); _dialogDefaults->setValue("spectrum/removeMean", removeMean()); _dialogDefaults->setValue("spectrum/vUnits", vectorUnits()); _dialogDefaults->setValue("spectrum/rUnits", rateUnits()); _dialogDefaults->setValue("spectrum/apodizeFxn", apodizeFunction()); _dialogDefaults->setValue("spectrum/gaussianSigma", sigma()); _dialogDefaults->setValue("spectrum/output", output()); _dialogDefaults->setValue("spectrum/interpolateHoles", interpolateOverHoles()); } // set the widget to the stored default values void FFTOptions::loadWidgetDefaults() { setSampleRate(_dialogDefaults->value("spectrum/freq",100.0).toDouble()); setInterleavedAverage(_dialogDefaults->value("spectrum/average",true).toBool()); setFFTLength(_dialogDefaults->value("spectrum/len",12).toInt()); setApodize(_dialogDefaults->value("spectrum/apodize",true).toBool()); setRemoveMean(_dialogDefaults->value("spectrum/removeMean",true).toBool()); setVectorUnits(_dialogDefaults->value("spectrum/vUnits","V").toString()); setRateUnits(_dialogDefaults->value("spectrum/rUnits","Hz").toString()); setApodizeFunction(ApodizeFunction(_dialogDefaults->value("spectrum/apodizeFxn",WindowOriginal).toInt())); setSigma(_dialogDefaults->value("spectrum/gaussianSigma",1.0).toDouble()); setOutput(PSDType(_dialogDefaults->value("spectrum/output",PSDPowerSpectralDensity).toInt())); setInterpolateOverHoles(_dialogDefaults->value("spectrum/interpolateHoles",true).toInt()); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/dialogdefaults.cpp000644 001750 001750 00000004350 11544160210 020615 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dialogdefaults.h" #include "datasource.h" namespace Kst { QSettings *_dialogDefaults; void setDataVectorDefaults(DataVectorPtr V) { _dialogDefaults->setValue("vector/datasource", V->filename()); } void setGenVectorDefaults(GeneratedVectorPtr V) { _dialogDefaults->setValue("genVector/min", V->min()); _dialogDefaults->setValue("genVector/max", V->max()); _dialogDefaults->setValue("genVector/length", V->length()); } void setDataMatrixDefaults(DataMatrixPtr M) { //qDebug() << "M...filename: " << M->dataSource()->fileName(); // FIXME: data source filename isn't valid... _dialogDefaults->setValue("matrix/datasource",M->dataSource()->fileName()); _dialogDefaults->setValue("matrix/xCountFromEnd",M->xCountFromEnd()); _dialogDefaults->setValue("matrix/yCountFromEnd",M->yCountFromEnd()); _dialogDefaults->setValue("matrix/xReadToEnd",M->xReadToEnd()); _dialogDefaults->setValue("matrix/yReadToEnd",M->yReadToEnd()); _dialogDefaults->setValue("matrix/xNumSteps",M->xNumSteps()); _dialogDefaults->setValue("matrix/yNumSteps",M->yNumSteps()); _dialogDefaults->setValue("matrix/reqXStart",M->reqXStart()); _dialogDefaults->setValue("matrix/reqYStart",M->reqYStart()); } void setHistogramDefaults(HistogramPtr H) { _dialogDefaults->setValue("histogram/realTimeAutoBin", H->realTimeAutoBin()); _dialogDefaults->setValue("histogram/normalizationType",H->normalizationType()); } } kst-2.0.3/src/widgets/combobox.cpp000644 001750 001750 00000003032 11544160210 017432 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "combobox.h" #include #include namespace Kst { ComboBox::ComboBox(QWidget *parent) : QComboBox(parent), _editable(true) { setupLineEdit(); } ComboBox::ComboBox(bool editable, QWidget *parent) : QComboBox(parent), _editable(editable) { setupLineEdit(); } void ComboBox::setupLineEdit() { setInsertPolicy(QComboBox::NoInsert); setLineEdit(new QLineEdit(this)); QCompleter *currentCompleter = completer(); currentCompleter->setCompletionMode(QCompleter::PopupCompletion); currentCompleter->setCaseSensitivity(Qt::CaseSensitive); } ComboBox::~ComboBox() { } void ComboBox::setEditable(bool editable) { _editable = editable; } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/curveselector.cpp000644 001750 001750 00000007005 11544160210 020513 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "curveselector.h" #include "dialoglauncher.h" #include "datacollection.h" #include "objectstore.h" namespace Kst { CurveSelector::CurveSelector(QWidget *parent, ObjectStore *store) : QWidget(parent), _allowEmptySelection(false), _store(store) { setupUi(this); fillCurves(); connect(_curve, SIGNAL(currentIndexChanged(int)), this, SLOT(emitSelectionChanged())); } CurveSelector::~CurveSelector() { } void CurveSelector::setObjectStore(ObjectStore *store) { _store = store; fillCurves(); } void CurveSelector::emitSelectionChanged() { emit selectionChanged(_curve->currentText()); } CurvePtr CurveSelector::selectedCurve() const { return qVariantValue(_curve->itemData(_curve->currentIndex())); } bool CurveSelector::selectedCurveDirty() const { return _curve->currentIndex() != -1; } void CurveSelector::setSelectedCurve(CurvePtr selectedCurve) { //FIXME: findData doesn't work, but the loop here - which is supposed // to do exactly the same thing - does. WHY??? //int i = _curve->findData(qVariantFromValue(selectedVector.data())); int i=-1,j; for (j=0; j<_curve->count() ; j++) { if (selectedCurve.data() == (qVariantValue(_curve->itemData(j)))) { i=j; break; } } Q_ASSERT(i != -1); _curve->setCurrentIndex(i); } void CurveSelector::clearSelection() { _curve->setCurrentIndex(-1); } bool CurveSelector::allowEmptySelection() const { return _allowEmptySelection; } void CurveSelector::setAllowEmptySelection(bool allowEmptySelection) { _allowEmptySelection = allowEmptySelection; int i = _curve->findText(tr("")); if (i != -1) _curve->removeItem(i); if (_allowEmptySelection) { _curve->insertItem(0, tr(""), qVariantFromValue(0)); _curve->setCurrentIndex(0); } } void CurveSelector::fillCurves() { if (!_store) { return; } QHash curves; CurveList curveList = _store->getObjects(); CurveList::ConstIterator it = curveList.begin(); for (; it != curveList.end(); ++it) { CurvePtr curve = (*it); curve->readLock(); curves.insert(curve->Name(), curve); curve->unlock(); } QStringList list = curves.keys(); qSort(list); CurvePtr current = selectedCurve(); _curve->clear(); foreach (const QString &string, list) { CurvePtr r = curves.value(string); _curve->addItem(string, qVariantFromValue(r.data())); } if (_allowEmptySelection) //reset the setAllowEmptySelection(true); if (current) setSelectedCurve(current); } bool CurveSelector::event(QEvent * event) { if (event->type() == QEvent::WindowActivate) { fillCurves(); } return QWidget::event(event); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/filerequester.h000644 001750 001750 00000003241 11544160210 020150 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILEREQUESTER_H #define FILEREQUESTER_H #include #include #include "kstwidgets_export.h" class QLineEdit; class QToolButton; namespace Kst { class KSTWIDGETS_EXPORT FileRequester : public QWidget { Q_OBJECT Q_PROPERTY(QString file READ file WRITE setFile USER true) public: FileRequester(QWidget *parent = 0); virtual ~FileRequester(); QString file() const; void setMode(QFileDialog::FileMode mode) { _mode = mode; } QLineEdit *_fileEdit; public Q_SLOTS: void setFile(const QString &file); void updateFile(const QString &file); Q_SIGNALS: void changed(const QString &file); private Q_SLOTS: void chooseFile(); private: void setup(); QToolButton *_fileButton; QString _file; QFileDialog::FileMode _mode; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/curveselector.h000644 001750 001750 00000003450 11544160210 020160 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CURVESELECTOR_H #define CURVESELECTOR_H #include #include "ui_curveselector.h" #include #include "kstwidgets_export.h" namespace Kst { class ObjectStore; class KSTWIDGETS_EXPORT CurveSelector : public QWidget, public Ui::CurveSelector { Q_OBJECT public: explicit CurveSelector(QWidget *parent = 0, ObjectStore *store = 0); virtual ~CurveSelector(); void setObjectStore(ObjectStore *store); CurvePtr selectedCurve() const; bool selectedCurveDirty() const; void setSelectedCurve(CurvePtr selectedCurve); bool allowEmptySelection() const; void setAllowEmptySelection(bool allowEmptySelection); void clearSelection(); virtual bool event(QEvent * event); Q_SIGNALS: void selectionChanged(const QString&); private Q_SLOTS: void emitSelectionChanged(); private: void fillCurves(); private: bool _allowEmptySelection; ObjectStore *_store; }; } #endif // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/scalarselector.cpp000644 001750 001750 00000014652 11544160210 020642 0ustar00synthsynth000000 000000 /*************************************************************************** * * * copyright : (C) 2007 The University of Toronto * * netterfield@astro.utoronto.ca * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "scalarselector.h" #include "dialoglauncher.h" #include "datacollection.h" #include "objectstore.h" #include "enodes.h" namespace Kst { ScalarSelector::ScalarSelector(QWidget *parent, ObjectStore *store) : QWidget(parent), _store(store) { _defaultsSet = false; setupUi(this); int size = style()->pixelMetric(QStyle::PM_SmallIconSize); _newScalar->setIcon(QPixmap(":kst_scalarnew.png")); _editScalar->setIcon(QPixmap(":kst_scalaredit.png")); _newScalar->setFixedSize(size + 8, size + 8); _editScalar->setFixedSize(size + 8, size + 8); _selectScalar->setFixedSize(size + 8, size + 8); _scalarListSelector = new ScalarListSelector(this); connect(_newScalar, SIGNAL(pressed()), this, SLOT(newScalar())); connect(_editScalar, SIGNAL(pressed()), this, SLOT(editScalar())); connect(_selectScalar, SIGNAL(pressed()), this, SLOT(selectScalar())); connect(_scalar, SIGNAL(activated(int)), this, SLOT(emitSelectionChanged())); connect(_scalar, SIGNAL(currentIndexChanged(int)), this, SLOT(updateDescriptionTip())); } ScalarSelector::~ScalarSelector() { } void ScalarSelector::setObjectStore(ObjectStore *store) { _store = store; fillScalars(); } void ScalarSelector::updateDescriptionTip() { setToolTip(selectedScalarString()); } void ScalarSelector::emitSelectionChanged() { emit selectionChanged(_scalar->currentText()); } void ScalarSelector::setDefaultValue(double value) { QString string = QString::number(value); _scalar->addItem(string, qVariantFromValue(0)); _scalar->setCurrentIndex(_scalar->findText(string)); _defaultsSet = true; } ScalarPtr ScalarSelector::selectedScalar() { bool existingScalar; if (_scalar->findText(_scalar->currentText(), Qt::MatchExactly) == -1) { // Value typed in. existingScalar = false; } else { if (qVariantValue(_scalar->itemData(_scalar->findText(_scalar->currentText())))) { existingScalar = true; } else { // Default Value. Doesn't exist as scalar yet. existingScalar = false; } } if (!existingScalar) { // Create the Scalar. bool ok = false; double value = _scalar->currentText().toDouble(&ok); if (!ok) { value = Equations::interpret(_store, _scalar->currentText().toLatin1(), &ok); } if (!ok) { return 0; } // Check if a scalar with this value exist & is orphan. foreach(Scalar* scalar, _store->getObjects()) { if (scalar->orphan()) { if (scalar->value() == value) { return scalar; } } } ScalarPtr scalar = _store->createObject(); scalar->setValue(value); scalar->setOrphan(true); scalar->setEditable(true); scalar->setDescriptiveName(QString()); scalar->writeLock(); scalar->registerChange(); scalar->unlock(); _scalar->clearEditText(); fillScalars(); setSelectedScalar(scalar); return scalar; } return qVariantValue(_scalar->itemData(_scalar->currentIndex())); } QString ScalarSelector::selectedScalarString() { if (_scalar->findText(_scalar->currentText(),Qt::MatchExactly) == -1) { return _scalar->currentText(); } Scalar* scalar = qVariantValue(_scalar->itemData(_scalar->currentIndex())); if (scalar) { return scalar->descriptionTip(); } else { return QString(); } } void ScalarSelector::setSelectedScalar(ScalarPtr selectedScalar) { int i=-1,j; for (j=0; j<_scalar->count() ; j++) { if (selectedScalar.data() == (qVariantValue(_scalar->itemData(j)))) { i=j; break; } } Q_ASSERT(i != -1); _scalar->setCurrentIndex(i); _defaultsSet = false; } void ScalarSelector::newScalar() { QString scalarName; DialogLauncher::self()->showScalarDialog(scalarName, 0, true); fillScalars(); ScalarPtr scalar = kst_cast(_store->retrieveObject(scalarName)); if (scalar) { setSelectedScalar(scalar); emitSelectionChanged(); } } void ScalarSelector::editScalar() { if (selectedScalar()->provider()) { DialogLauncher::self()->showObjectDialog(selectedScalar()->provider()); } else { QString scalarName; DialogLauncher::self()->showScalarDialog(scalarName, ObjectPtr(selectedScalar()), true); } fillScalars(); } void ScalarSelector::selectScalar() { if (_scalarListSelector->exec() == QDialog::Accepted) { _scalar->setCurrentIndex(_scalar->findText(_scalarListSelector->selectedScalar())); } } void ScalarSelector::fillScalars() { if (!_store) { return; } QHash scalars; ScalarList scalarList = _store->getObjects(); ScalarList::ConstIterator it = scalarList.begin(); for (; it != scalarList.end(); ++it) { ScalarPtr scalar = (*it); scalar->readLock(); scalars.insert(scalar->Name(), scalar); scalar->unlock(); } QStringList list = scalars.keys(); qSort(list); ScalarPtr current = qVariantValue(_scalar->itemData(_scalar->currentIndex()));; _scalar->clear(); foreach (QString string, list) { ScalarPtr v = scalars.value(string); _scalar->addItem(string, qVariantFromValue(v.data())); } _scalarListSelector->clear(); _scalarListSelector->fillScalars(list); if (current) setSelectedScalar(current); _editScalar->setEnabled(_scalar->count() > 0); _selectScalar->setEnabled(_scalar->count() > 0); } bool ScalarSelector::event(QEvent * event) { if (event->type() == QEvent::WindowActivate) { if (_defaultsSet) { QString defaultText = _scalar->currentText(); fillScalars(); setDefaultValue(defaultText.toDouble()); } else { fillScalars(); } } return QWidget::event(event); } } // vim: ts=2 sw=2 et kst-2.0.3/src/widgets/scalarselector.ui000644 001750 001750 00000005500 11544160210 020465 0ustar00synthsynth000000 000000 ScalarSelector 0 0 300 37 0 0 Select a scalar to utilize. If you wish to create a new scalar, select the icon to the right. 0 0 0 true 0 0 ... 0 0 Create a new scalar. false 0 0 Edit selected scalar. Kst::ComboBox QComboBox
    combobox.h
    _scalar _selectScalar _newScalar _editScalar
    kst-2.0.3/old_tests/dirfile_testcase/15count/ssine000644 001750 001750 00000000104 11544160210 022531 0ustar00synthsynth000000 000000 Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?kst-2.0.3/old_tests/dirfile_testcase/15count/format000644 001750 001750 00000000110 11544160210 022675 0ustar00synthsynth000000 000000 scount RAW f 1 fcount RAW f 20 sine RAW f 20 ssine RAW f 1 cos RAW f 20 kst-2.0.3/old_tests/dirfile_testcase/15count/fcount000644 001750 001750 00000002520 11544160210 022712 0ustar00synthsynth000000 000000 ?@@@@@@@AA A0A@APA`ApAAAAAAAAAAAAAAAAABBB BBBBB B$B(B,B0B4B8BC?C@CACBCCCDCECFCGCHCICJCKCLCMCNCOCPCQCRCSCTCUCVCWCXCYCZC[C\C]C^C_C`CaCbCcCdCeCfCgChCiCjCkClCmCnCoCpCqCrCsCtCuCvCwCxCyCzC{C|C}C~CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCkst-2.0.3/old_tests/dirfile_testcase/15count/scount000644 001750 001750 00000000104 11544160210 022723 0ustar00synthsynth000000 000000 ?@@@@@@@AA A0A@APA`ApAAkst-2.0.3/old_tests/dirfile_testcase/15count/sine000644 001750 001750 00000002520 11544160210 022352 0ustar00synthsynth000000 000000 Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=0 %Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQ0Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=%Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQ0 Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=|0&Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQSQ=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?kst-2.0.3/old_tests/dirfile_testcase/15count/cos000644 001750 001750 00000002520 11544160210 022200 0ustar00synthsynth000000 000000 ?~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=0$Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQSQ=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=|%Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQQ=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=&Q[W?~z7zپk+ y8.#{>/:[@EO%XU`gnqxsw-w{;}~~;}-w{wqxsngU`%XO[@E:{>/8.#y+ kپzz7~?[WQ0Q=[W>?>~>z7>z>>k>+ ?y?8.#?{>/?:?[@E?O?%X?U`?g?n?qxs?w?-w{?;}?~??~?;}?-w{?w?qxs?n?g?U`?%X?O?[@E?:?{>/?8.#?y?+ ?k>>z>z7>~>?>[W>Q=IQ[W?~z7zپk+ y8.#{>/:[@Ekst-2.0.3/old_tests/dirfile_replay/replay.c000644 001750 001750 00000010423 11544160210 021315 0ustar00synthsynth000000 000000 /*************************************************************************** * replay.c * ------------------- * begin : Aug 22 2006 * copyright : (C) 2006 by Barth Netterfield * email : ****************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "getdata.h" #include "getdata_struct.h" #include #include #include #include #define OUTDIR "/data/replay" #define PREPLAY 1000 #define BUFSIZE 1000000 #define DT 0.2; char *dirfile; void usage() { fprintf(stderr,"usage: replay \n"); fprintf(stderr,"Replays a dirfile at a 5Hz frame rate, in %s\n", OUTDIR); fprintf(stderr,"This program is a hack and doesn't create %s\n", OUTDIR); fprintf(stderr,"so you need to do that by hand\n"); exit(0); } void ProcessField(int fp, struct RawEntryType *R, int f0, int nf) { static char buffer[BUFSIZE]; int error_code = 0; GetData(dirfile, R->field, f0, 0, nf, 0, R->type, buffer, &error_code); write(fp, buffer, nf*R->size*R->samples_per_frame); } int main(int argc, char *argv[]) { int error_code = GD_E_OK; int N_frames; int i_raw, j_first; int *fp_out; char fieldfilename[200]; char *first_field; char *field; struct FormatType *P; struct timeval tv; struct timezone zn; double last_t, new_t, dt; int nf; int f0; char copy_command[555]; if (argc !=2) usage(); if (argv[1][0]=='-') usage(); dirfile = argv[1]; P = GetFormat(argv[1], &error_code); if (error_code != GD_E_OK) { fprintf(stderr,"Error Reading format: %s in %s\n", GD_ERROR_CODES[error_code], argv[1]); exit(0); } sprintf(copy_command, "cp %s/format %s/format", argv[1], OUTDIR); system(copy_command); N_frames = GetNFrames(argv[1], &error_code, P->first_field.field); if (error_code != GD_E_OK) { fprintf(stderr,"Error: %s in %s (%s)\n", GD_ERROR_CODES[error_code], argv[1],P->first_field.field); exit(0); } fp_out = malloc(P->n_raw*sizeof(int)); for (i_raw = 0; i_rawn_raw; i_raw++) { sprintf(fieldfilename, "%s/%s", OUTDIR, P->rawEntries[i_raw].field); fp_out[i_raw] = open(fieldfilename, O_CREAT|O_WRONLY, 00644); if (fp_out[i_raw] < 0) { printf("could not create %s for writing\n", fieldfilename); } } printf("%d frames availible\n", N_frames); first_field = P->first_field.field; // preplay the fields for (i_raw = 0; i_raw < P->n_raw; i_raw++) { field = P->rawEntries[i_raw].field; if (strcmp(field,first_field)!=0) { ProcessField(fp_out[i_raw], &(P->rawEntries[i_raw]), 0, PREPLAY); } else { j_first = i_raw; } } ProcessField(fp_out[j_first], &(P->rawEntries[j_first]), 0, PREPLAY); printf("preplay done\n"); f0 = PREPLAY; error_code = gettimeofday(&tv, &zn); last_t = (double)tv.tv_sec + (double)tv.tv_usec/1.0E6; usleep(1000); while (f00) { for (i_raw = 0; i_raw < P->n_raw; i_raw++) { field = P->rawEntries[i_raw].field; if (strcmp(field,first_field)!=0) { ProcessField(fp_out[i_raw], &(P->rawEntries[i_raw]), f0, nf); } else { j_first = i_raw; } } ProcessField(fp_out[j_first], &(P->rawEntries[j_first]), f0, nf); f0 += nf; last_t+=nf*DT; printf("%d\n", f0); } else { usleep(1000); } } } kst-2.0.3/old_tests/dirfile_replay/getdata.c000644 001750 001750 00000212336 11544160210 021441 0ustar00synthsynth000000 000000 /* (C) 2002 C. Barth Netterfield */ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "getdata.h" #include "getdata_struct.h" const char *GD_ERROR_CODES[15] = {"OK", "Could not open Format file", "Error in Format file", "Could not open Data file", "Field name too long", "Field code not found in File Format", "Unrecognized return type", "Could not open field file", "Could not open included Format file", "Internal error", " ", " ", "Size mismatch in linear combination", "Could not open interpolation file", "Too many levels of recursion" }; /* Suberror codes -- these don't need to be public */ #define GD_E_FORMAT_SE_BAD_TYPE 0 #define GD_E_FORMAT_SE_BAD_SPF 1 #define GD_E_FORMAT_SE_N_FIELDS 2 #define GD_E_FORMAT_SE_N_COLS 3 #define GD_E_FORMAT_SE_MAX_I 4 #define GD_E_FORMAT_SE_NUMBITS 5 #define GD_E_FORMAT_SE_BITNUM 6 #define GD_E_FORMAT_SE_BITSIZE 7 #define GD_E_FORMAT_SE_FIELD_LEN 8 #define GD_E_FORMAT_SE_BAD_LINE 9 #define GD_E_FORMAT_SE_N_RAW 10 #define GD_E_LINFILE_SE_OPEN 0 #define GD_E_LINFILE_SE_LENGTH 1 static struct { int n; struct FormatType *F; } Formats; static int recurse_level = 0; static int first_time = 1; static int getdata_error = GD_E_OK; static int getdata_suberror = 0; static char getdata_error_string[MAX_FILENAME_LENGTH + 6]; static char getdata_error_file[MAX_FILENAME_LENGTH + 6]; static int getdata_error_line = 0; static int DoField(struct FormatType *F, const char *field_code, int first_frame, int first_samp, int num_frames, int num_samp, char return_type, void *data_out, int *error_code); /***************************************************************************/ /* */ /* GetLine: read non-comment line from format file */ /* The line is placed in *line. */ /* Returns 1 if successful, 0 if unsuccessful */ /* */ /***************************************************************************/ static int GetLine(FILE *fp, char *line, int* linenum) { char *ret_val; int first_char; int i, len; do { ret_val = fgets(line, MAX_LINE_LENGTH, fp); (*linenum)++; first_char = 0; while (line[first_char] == ' ' || line[first_char] == '\t') ++first_char; line += first_char; } while (ret_val && (line[0] == '#' || line[0] == 0 || line[1] == 0)); if (ret_val) { /* truncate comments from end of lines */ len = strlen(line); for (i = 0; i < len; i++) { if (line[i]=='#') line[i] = '\0'; } return(1); /* a line was read */ } return(0); /* there were no valid lines */ } /* SetGetDataError: Sets the global error variables for a library error */ static int SetGetDataError(int error, int suberror, const char* format_file, int line, const char* token) { getdata_error = error; getdata_suberror = suberror; getdata_error_line = line; if (format_file != NULL) strncpy(getdata_error_file, format_file, MAX_FILENAME_LENGTH + 6); if (token != NULL) strncpy(getdata_error_string, token, MAX_FILENAME_LENGTH + 6); return error; } /***************************************************************************/ /* */ /* GetDataErrorString: Write a descriptive message in the supplied */ /* buffer describing the last library error. The message may be */ /* truncated but should be null terminated. */ /* */ /* buffer: memory into which to write the string */ /* buflen: length of the buffer. GetDataErrorString will not write */ /* more than buflen characters (including the trailing '\0') */ /* */ /* return value: buffer or NULL if buflen < 1 */ /* */ /***************************************************************************/ char* GetDataErrorString(char* buffer, size_t buflen) { char* ptr; /* Sanity check */ if (buffer == NULL || buflen < 1) return NULL; /* Copy the default error message into the buffer and make sure * the result is null terminated */ strncpy(buffer, GD_ERROR_CODES[getdata_error], buflen - 1); buffer[buflen - 1] = 0; /* point to the end of the string and reduce buflen appropriately */ ptr = buffer + strlen(buffer); buflen -= strlen(buffer); /* add the anciliary data - we use snprintfs here to ensure the resultant * string is properly null terminated (while not overflowing the buffer) */ switch (getdata_error) { case GD_E_INTERNAL_ERROR: /* internal error: report line and source file where it happened */ snprintf(ptr, buflen, " [%s,%i]", getdata_error_file, getdata_error_line); break; case GD_E_OPEN_FORMAT: /* main format file couldn't be opened -- report the filename we tried to open */ snprintf(ptr, buflen, " %s", getdata_error_file); break; case GD_E_FORMAT: /* syntax errors in the format file -- lots of suberror types here */ /* No RAW fields specified -- this isn't tied to a particular line */ if (getdata_suberror == GD_E_FORMAT_SE_N_RAW) { snprintf(ptr, buflen, ": no raw fields defined"); break; } /* otherwise, add the format filename and line number where the * syntax error was found */ snprintf(ptr, buflen, " on line %i of %s: ", getdata_error_line, getdata_error_file); buflen -= strlen(ptr); ptr += strlen(ptr); switch (getdata_suberror) { case GD_E_FORMAT_SE_BAD_TYPE: /* bad field type; include the thing we thought was the type specifier */ snprintf(ptr, buflen, "bad raw field type: %c", getdata_error_string[0]); break; case GD_E_FORMAT_SE_BAD_SPF: /* SPF < 0 -- print the column we expected to hold the SPF */ snprintf(ptr, buflen, "samples per frame out of range: %s", getdata_error_string); break; case GD_E_FORMAT_SE_N_FIELDS: /* number of fields in the LINCOM and the number of columns in the format file don't match */ snprintf(ptr, buflen, "lincom field count out of range: %s", getdata_error_string); break; case GD_E_FORMAT_SE_N_COLS: /* missing data we expected to find on this line */ snprintf(ptr, buflen, "missing column"); break; case GD_E_FORMAT_SE_MAX_I: /* max_i out of range (what is an MPLEX?) */ snprintf(ptr, buflen, "max_i out of range: %s", getdata_error_string); break; case GD_E_FORMAT_SE_NUMBITS: /* bitfield numbits is less than 1 */ snprintf(ptr, buflen, "numbits out of range"); break; case GD_E_FORMAT_SE_BITNUM: /* bitnum is less than 0 */ snprintf(ptr, buflen, "starting bit out of range"); break; case GD_E_FORMAT_SE_BITSIZE: /* bitfield extends past 32 bits */ snprintf(ptr, buflen, "end of bitfield is out of bounds"); break; case GD_E_FORMAT_SE_FIELD_LEN: /* field name is too long */ snprintf(ptr, buflen, "field name too long: %s", getdata_error_string); break; case GD_E_FORMAT_SE_BAD_LINE: /* couldn't make heads nor tails of the line -- ie. a mistyped keyword &c. */ snprintf(ptr, buflen, "line indecypherable"); break; } break; case GD_E_OPEN_INCLUDE: /* Couldn't open an INCLUDEd file -- report the included filename as well as the line and name of the format file where it was encountered */ snprintf(ptr, buflen, "%s on line %i of %s", getdata_error_string, getdata_error_line, getdata_error_file); break; case GD_E_BAD_RETURN_TYPE: /* unsupported data return type passed to GetData */ snprintf(ptr, buflen, ": %c", (char)getdata_suberror); break; case GD_E_RECURSE_LEVEL: /* recursion too deep -- report field name for which this happened */ snprintf(ptr, buflen, " while resolving field %s", getdata_error_string); break; case GD_E_BAD_CODE: /* A required field name wasn't defined */ case GD_E_OPEN_RAWFIELD: /* A raw field file wasn't found on disk */ snprintf(ptr, buflen, ": %s", getdata_error_string); break; case GD_E_OPEN_LINFILE: /* problems with LINTERPs: report the linterp filename with the error message */ snprintf(ptr, buflen, " %s: %s", getdata_error_string, (getdata_suberror == GD_E_LINFILE_SE_OPEN) ? "open failed" : "file too short"); break; } return buffer; } /***************************************************************************/ /* */ /* FreeF: free any entries that have been allocated in F */ /* */ /***************************************************************************/ static void FreeF(struct FormatType *F) { if (F->n_raw > 0) free(F->rawEntries); if (F->n_lincom > 0) free(F->lincomEntries); if (F->n_multiply > 0) free(F->multiplyEntries); if (F->n_linterp >0) free(F->linterpEntries); if (F->n_mplex > 0) free(F->mplexEntries); if (F->n_bit > 0) free(F->bitEntries); } /***************************************************************************/ /* */ /* ParseRaw: parse a RAW data type in the formats file */ /* */ /***************************************************************************/ static int ParseRaw(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], struct RawEntryType *R, const char* subdir, const char* format_file, int line) { strcpy(R->field, in_cols[0]); /* field */ snprintf(R->file, MAX_FILENAME_LENGTH + FIELD_LENGTH + 2, "%s/%s", subdir, in_cols[0]); /* path and filename */ R->fp = -1; /* file not opened yet */ switch (in_cols[2][0]) { case 'c': R->size = 1; break; case 's': case 'u': R->size = 2; break; case 'S': case 'U': case 'f': case 'i': R->size = 4; break; case 'd': R->size = 8; break; default: return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BAD_TYPE, format_file, line, in_cols[2]); } R->type = in_cols[2][0]; R->samples_per_frame = atoi(in_cols[3]); if (R->samples_per_frame<=0) { return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BAD_SPF, format_file, line, in_cols[3]); } return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); } /***************************************************************************/ /* */ /* ParseLincom: parse a LINCOM data type in the formats file */ /* */ /***************************************************************************/ static int ParseLincom(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], int n_cols, struct LincomEntryType *L, const char* format_file, int line) { int i; strcpy(L->field, in_cols[0]); /* field */ L->n_infields = atoi(in_cols[2]); if ((L->n_infields<1) || (L->n_infields>MAX_LINCOM) || (n_cols < L->n_infields*3 + 3)) { return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_FIELDS, format_file, line, in_cols[2]); } for (i=0; in_infields; i++) { strncpy(L->in_fields[i], in_cols[i*3+3], FIELD_LENGTH); L->m[i] = atof(in_cols[i*3+4]); L->b[i] = atof(in_cols[i*3+5]); } return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); } /***************************************************************************/ /* */ /* ParseLinterp: parse a LINTERP data type in the formats file */ /* */ /***************************************************************************/ static int ParseLinterp(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], struct LinterpEntryType *L) { strcpy(L->field, in_cols[0]); /* field */ strncpy(L->raw_field, in_cols[2], FIELD_LENGTH); strcpy(L->linterp_file, in_cols[3]); L->n_interp = -1; /* linterp file not read yet */ return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); } /***************************************************************************/ /* */ /* ParseMultiply: parse MULTIPLY data type entry in formats file */ /* */ /***************************************************************************/ static int ParseMultiply(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], int n_cols, struct MultiplyEntryType *M, const char* format_file, int line) { if (n_cols < 4) return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_COLS, format_file, line, NULL); strcpy(M->field, in_cols[0]); /* field */ strncpy(M->in_fields[0], in_cols[2], FIELD_LENGTH); strncpy(M->in_fields[1], in_cols[3], FIELD_LENGTH); return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); } /***************************************************************************/ /* */ /* ParseMplex: parse MPLEX data type entry in formats file */ /* */ /***************************************************************************/ static int ParseMplex(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], int n_cols, struct MplexEntryType *M, const char* format_file, int line) { if (n_cols < 6) return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_COLS, format_file, line, NULL); strcpy(M->field, in_cols[0]); /* field */ strncpy(M->cnt_field, in_cols[2], FIELD_LENGTH); strncpy(M->data_field, in_cols[3], FIELD_LENGTH); M->i = atoi(in_cols[4]); M->max_i = atoi(in_cols[5]); if ((M->max_i < 1) || (M->max_i < M->i)) return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_MAX_I, format_file, line, NULL); return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); } /***************************************************************************/ /* */ /* ParseBit: parse BIT data type entry in formats file */ /* */ /***************************************************************************/ static int ParseBit(char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH], int n_cols, struct BitEntryType *B, const char* format_file, int line) { strcpy(B->field, in_cols[0]); /* field */ strncpy(B->raw_field, in_cols[2], FIELD_LENGTH); /* field */ B->bitnum=atoi(in_cols[3]); if (n_cols>4) { B->numbits=atoi(in_cols[4]); } else { B->numbits=1; } if (B->numbits < 1) return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_NUMBITS, format_file, line, NULL); if (B->bitnum < 0) return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BITNUM, format_file, line, NULL); if (B->bitnum + B->numbits - 1 > 31) return SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BITSIZE, format_file, line, NULL); return SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); } /***************************************************************************/ /* */ /* Compare functions for sorting the lists (using stdlib qsort) */ /* */ /***************************************************************************/ static int RawCmp(const void *A, const void *B) { return (strcmp(((struct RawEntryType *)A)->field, ((struct RawEntryType *)B)->field)); } static int LincomCmp(const void *A, const void *B) { return (strcmp(((struct LincomEntryType *)A)->field, ((struct LincomEntryType *)B)->field)); } static int LinterpCmp(const void *A, const void *B) { return (strcmp(((struct LinterpEntryType *)A)->field, ((struct LinterpEntryType *)B)->field)); } static int MultiplyCmp(const void *A, const void *B) { return (strcmp(((struct MultiplyEntryType *)A)->field, ((struct MultiplyEntryType *)B)->field)); } static int MplexCmp(const void *A, const void *B) { return (strcmp(((struct MplexEntryType *)A)->field, ((struct MplexEntryType *)B)->field)); } static int BitCmp(const void *A, const void *B) { return (strcmp(((struct BitEntryType *)A)->field, ((struct BitEntryType *)B)->field)); } /***************************************************************************/ /* */ /* ParseFormatFile: Perform the actual parsing of the format file. This */ /* function is called from GetFormat once for the main format file and */ /* once for each included file. */ /* */ /***************************************************************************/ static int ParseFormatFile(FILE* fp, struct FormatType *F, const char* filedir, const char* subdir, const char* format_file, char*** IncludeList, int *i_include) { char instring[MAX_LINE_LENGTH]; char in_cols[MAX_IN_COLS][MAX_LINE_LENGTH]; int n_cols, error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); int linenum = 0; /***** start parsing ****/ while (GetLine(fp, instring, &linenum)) { /* ok, brute force parse... slow and ugly but convenient... */ n_cols = sscanf(instring, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", in_cols[0], in_cols[1], in_cols[2], in_cols[3], in_cols[4], in_cols[5], in_cols[6], in_cols[7], in_cols[8], in_cols[9], in_cols[10], in_cols[11], in_cols[12], in_cols[13], in_cols[14]); if (n_cols<2) { error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_COLS, format_file, linenum, NULL); } else if (strlen(in_cols[0])>FIELD_LENGTH) { error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_FIELD_LEN, format_file, linenum, in_cols[0]); } else if (strcmp(in_cols[1], "RAW")==0) { F->n_raw++; F->rawEntries = realloc(F->rawEntries, F->n_raw*sizeof(struct RawEntryType)); error_code = ParseRaw(in_cols, F->rawEntries+F->n_raw - 1, subdir, format_file, linenum); } else if (strcmp(in_cols[1], "LINCOM")==0) { F->n_lincom++; F->lincomEntries = realloc(F->lincomEntries, F->n_lincom*sizeof(struct LincomEntryType)); error_code = ParseLincom(in_cols, n_cols, F->lincomEntries+F->n_lincom - 1, format_file, linenum); } else if (strcmp(in_cols[1], "LINTERP")==0) { F->n_linterp++; F->linterpEntries = realloc(F->linterpEntries, F->n_linterp*sizeof(struct LinterpEntryType)); error_code = ParseLinterp(in_cols, F->linterpEntries+F->n_linterp - 1); } else if (strcmp(in_cols[1], "MULTIPLY")==0) { F->n_multiply++; F->multiplyEntries = realloc(F->multiplyEntries, F->n_multiply*sizeof(struct MultiplyEntryType)); error_code = ParseMultiply(in_cols, n_cols, F->multiplyEntries + F->n_multiply - 1, format_file, linenum); } else if (strcmp(in_cols[1], "MPLEX")==0) { F->n_mplex++; F->mplexEntries = realloc(F->mplexEntries, F->n_mplex*sizeof(struct MplexEntryType)); error_code = ParseMplex(in_cols, n_cols, F->mplexEntries+F->n_mplex - 1, format_file, linenum); } else if (strcmp(in_cols[1], "BIT")==0) { F->n_bit++; F->bitEntries = realloc(F->bitEntries, F->n_bit*sizeof(struct BitEntryType)); error_code = ParseBit(in_cols, n_cols, F->bitEntries+F->n_bit - 1, format_file, linenum); } else if (strcmp(in_cols[0], "FRAMEOFFSET")==0) { F->frame_offset = atoi(in_cols[1]); } else if (strcmp(in_cols[0], "INCLUDE")==0) { int i, found = 0; char new_format_file[MAX_FILENAME_LENGTH + 6]; char new_subdir[MAX_FILENAME_LENGTH + 1]; FILE* new_fp = NULL; /* Run through the include list to see if we've already included this * file */ for (i = 0; i < *i_include; ++i) if (strcmp(in_cols[1], (*IncludeList)[i]) == 0) { found = 1; break; } /* If we found the file, we won't reopen it. Continue parsing. */ if (found) continue; /* Otherwise, try to open the file */ snprintf(new_format_file, MAX_FILENAME_LENGTH + 6, "%s/%s/%s", filedir, subdir, in_cols[1]); new_fp = fopen(new_format_file, "r"); /* If opening the file failed, set the error code and abort parsing. */ if (new_fp == NULL) { error_code = SetGetDataError(GD_E_OPEN_INCLUDE, 0, format_file, linenum, new_format_file); break; } /* If we got here, we managed to open the inlcuded file; parse it */ *IncludeList = realloc(*IncludeList, ++(*i_include) * sizeof(char*)); (*IncludeList)[*i_include - 1] = strdup(in_cols[1]); /* extract the subdirectory name - dirname both returns a volatile string * and modifies its argument, ergo strcpy */ strcpy(new_format_file, in_cols[1]); if (strcmp(subdir, ".") == 0) strcpy(new_subdir, dirname(new_format_file)); else snprintf(new_subdir, MAX_FILENAME_LENGTH, "%s/%s", subdir, dirname(new_format_file)); error_code = ParseFormatFile(new_fp, F, filedir, new_subdir, new_format_file, IncludeList, i_include); fclose(new_fp); } else error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_BAD_LINE, format_file, linenum, NULL); /* break out of loop (so we can return) if we've encountered an error */ if (error_code != GD_E_OK) break; } return error_code; } /***************************************************************************/ /* */ /* GetFormat: Read format file and fill structure. The format */ /* is cached. */ /* */ /***************************************************************************/ struct FormatType *GetFormat(const char *filedir, int *error_code) { int i_format, i; struct stat statbuf; FILE *fp; char format_file[MAX_FILENAME_LENGTH+6]; struct FormatType *F; char raw_data_filename[MAX_FILENAME_LENGTH+FIELD_LENGTH+2]; char **IncludeList = NULL; int i_include; /** first check to see if we have already read it **/ for (i_format=0; i_formatFileDirName, filedir); F->n_raw = F->n_lincom = F->n_multiply = F->n_linterp = F->n_mplex = F->n_bit = 0; F->frame_offset = 0; F->rawEntries = NULL; F->lincomEntries = NULL; F->multiplyEntries = NULL; F->linterpEntries = NULL; F->mplexEntries = NULL; F->bitEntries = NULL; /* Parse the file. This will take care of any necessary inclusions */ i_include = 1; IncludeList = malloc(sizeof(char*)); IncludeList[0] = strdup("format"); *error_code = ParseFormatFile(fp, F, filedir, ".", format_file, &IncludeList, &i_include); fclose(fp); /* Clean up IncludeList. We don't need it anymore */ for (i = 0; i < i_include; ++i) free(IncludeList[i]); free(IncludeList); if (*error_code!=GD_E_OK) { FreeF(F); Formats.n--; return(NULL); } /** Now sort the lists */ if (F->n_raw > 1) { for (i=0; in_raw; i++) { snprintf(raw_data_filename, MAX_FILENAME_LENGTH+FIELD_LENGTH+2, "%s/%s", filedir, F->rawEntries[i].file); if (stat(raw_data_filename, &statbuf) >=0) { F->first_field = F->rawEntries[i]; break; } } qsort(F->rawEntries, F->n_raw, sizeof(struct RawEntryType), RawCmp); } if (F->n_lincom > 1) { qsort(F->lincomEntries, F->n_lincom, sizeof(struct LincomEntryType), LincomCmp); } if (F->n_linterp > 1) { qsort(F->linterpEntries, F->n_linterp, sizeof(struct LinterpEntryType), LinterpCmp); } if (F->n_multiply > 1) { qsort(F->multiplyEntries, F->n_multiply, sizeof(struct MultiplyEntryType), MultiplyCmp); } if (F->n_mplex > 1) { qsort(F->mplexEntries, F->n_mplex, sizeof(struct MplexEntryType), MplexCmp); } if (F->n_bit > 1) { qsort(F->bitEntries, F->n_bit, sizeof(struct BitEntryType), BitCmp); } return(F); } /***************************************************************************/ /* */ /* File File Frame numbers into dataout */ /* */ /***************************************************************************/ static void FillFileFrame(void *dataout, char rtype, int s0, int n) { int i; switch(rtype) { case 'c': for (i=0; i=0) return 0; if (s0+ns>0) nz = -s0; else nz = ns; switch (type) { case 'c': memset(databuffer, 0, nz); break; case 's': case 'u': memset(databuffer, 0, nz*sizeof(short)); break; case 'i': case 'S': case 'U': memset(databuffer, 0, nz*sizeof(int)); break; case 'f': for (i = 0; i < nz; ++i) *((float*)databuffer + i) = (float)NaN; break; case 'd': for (i = 0; i < nz; ++i) *((double*)databuffer + i) = (double)NaN; break; } return (nz); } /***************************************************************************/ /* */ /* Get samples per frame for field, given FormatType *F */ /* */ /***************************************************************************/ static int GetSPF(const char *field_code, struct FormatType *F, int *error_code) { struct RawEntryType tR; struct RawEntryType *R; struct LincomEntryType tL; struct LincomEntryType *L; struct MultiplyEntryType tM; struct MultiplyEntryType *M; struct BitEntryType tB; struct BitEntryType *B; struct LinterpEntryType tI; struct LinterpEntryType *I; int spf; if (!F) { /* don't crash */ return(0); } if (recurse_level > 10) { *error_code = SetGetDataError(GD_E_RECURSE_LEVEL, 0, NULL, 0, field_code); return(0); } if ((strcmp(field_code,"FILEFRAM")==0) || (strcmp(field_code,"INDEX")==0)) { return(1); } /***************************************/ /** Check to see if it is a raw entry **/ /* binary search for the field */ /* make a RawEntry we can compare to */ strncpy(tR.field, field_code, FIELD_LENGTH); /** use the stdlib binary search */ R = bsearch(&tR, F->rawEntries, F->n_raw, sizeof(struct RawEntryType), RawCmp); if (R!=NULL) { spf = R->samples_per_frame; return(spf); } /***************************************/ /** Check to see if it is a lincom entry **/ /* binary search for the field */ /* make a RawEntry we can compare to */ strncpy(tL.field, field_code, FIELD_LENGTH); /** use the stdlib binary search */ L = bsearch(&tL, F->lincomEntries, F->n_lincom, sizeof(struct LincomEntryType), LincomCmp); if (L!=NULL) { recurse_level++; spf = GetSPF(L->in_fields[0], F, error_code); recurse_level--; return(spf); } /***************************************/ /** Check to see if it is a multiply entry **/ /* binary search for the field */ /* make a RawEntry we can compare to */ strncpy(tM.field, field_code, FIELD_LENGTH); /** use the stdlib binary search */ M = bsearch(&tM, F->multiplyEntries, F->n_multiply, sizeof(struct MultiplyEntryType), MultiplyCmp); if (M != NULL) { int spf2; recurse_level++; spf = GetSPF(M->in_fields[0], F, error_code); spf2 = GetSPF(M->in_fields[1], F, error_code); recurse_level--; if (spf2 > spf) spf = spf2; return(spf); } /***************************************/ /** Check to see if it is a bit entry **/ /* binary search for the field */ /* make a BitEntry we can compare to */ strncpy(tB.field, field_code, FIELD_LENGTH); /** use the stdlib binary search */ B = bsearch(&tB, F->bitEntries, F->n_bit, sizeof(struct BitEntryType), BitCmp); if (B!=NULL) { recurse_level++; spf = GetSPF(B->raw_field, F, error_code); recurse_level--; return(spf); } /***************************************/ /** Check to see if it is a linterp entry **/ /* binary search for the field */ /* make a LinterpEntry we can compare to */ strncpy(tI.field, field_code, FIELD_LENGTH); /** use the stdlib binary search */ I = bsearch(&tI, F->linterpEntries, F->n_linterp, sizeof(struct LinterpEntryType), LinterpCmp); if (I!=NULL) { recurse_level++; spf = GetSPF(I->raw_field, F, error_code); recurse_level--; return(spf); } *error_code = SetGetDataError(GD_E_BAD_CODE, 0, NULL, 0, field_code); return(0); } /***************************************************************************/ /* */ /* Look to see if the field code belongs to a raw. If so, parse it. */ /* */ /***************************************************************************/ static int DoIfRaw(struct FormatType *F, const char *field_code, int first_frame, int first_samp, int num_frames, int num_samp, char return_type, void *data_out, int *error_code, int *n_read) { struct RawEntryType tR; struct RawEntryType *R; int s0, ns, bytes_read; char datafilename[2 * MAX_FILENAME_LENGTH + FIELD_LENGTH + 2]; unsigned char *databuffer; /******* binary search for the field *******/ /* make a RawEntry we can compare to */ strncpy(tR.field, field_code, FIELD_LENGTH); /** use the stdlib binary search */ R = bsearch(&tR, F->rawEntries, F->n_raw, sizeof(struct RawEntryType), RawCmp); if (R==NULL) return(0); /** if we got here, we found the field! **/ s0 = first_samp + first_frame*R->samples_per_frame; ns = num_samp + num_frames*R->samples_per_frame; /** open the file (and cache the fp) if it hasn't been opened yet. */ if (R->fp <0) { snprintf(datafilename, 2 * MAX_FILENAME_LENGTH + FIELD_LENGTH + 2, "%s/%s", F->FileDirName, R->file); R->fp = open(datafilename, O_RDONLY); if (R->fp<0) { *n_read = 0; *error_code = SetGetDataError(GD_E_OPEN_RAWFIELD, 0, NULL, 0, datafilename); return(1); } } databuffer = (unsigned char *)malloc(ns*R->size); *n_read = 0; if (s0 < 0) { *n_read = FillZero(databuffer, R->type, s0, ns); ns -= *n_read; s0 = 0; } if (ns>0) { lseek(R->fp, s0*R->size, SEEK_SET); bytes_read = read(R->fp, databuffer + *n_read*R->size, ns*R->size); *n_read += bytes_read/R->size; } *error_code = ConvertType(databuffer, R->type, data_out, return_type, *n_read); free(databuffer); return(1); } /***************************************************************************/ /* */ /* AllocTmpbuff: allocate a buffer of the right type and size */ /* */ /***************************************************************************/ static void *AllocTmpbuff(char type, int n) { assert(n > 0); void *buff=NULL; switch(type) { case 'n': buff = NULL; break; case 'c': buff = malloc(n*sizeof(char)); break; case 'i': case 'S': case 'U': buff = malloc(n*sizeof(int)); break; case 's': case 'u': buff = malloc(n*sizeof(short)); break; case 'f': buff = malloc(n*sizeof(float)); break; case 'd': buff = malloc(n*sizeof(double)); break; default: printf("Unexpected bad type error in AllocTmpbuff (%c)\n",type); abort(); break; } if ((type != 'n') && (buff==NULL)) { printf("Memory Allocation error in AllocTmpbuff\n"); } return(buff); } /***************************************************************************/ /* */ /* ScaleData: out = m*in+b */ /* */ /***************************************************************************/ static void ScaleData(void *data, char type, int npts, double m, double b) { unsigned char *data_c; short *data_s; unsigned short *data_u; unsigned *data_U; int *data_i; float *data_f; double *data_d; int i; switch(type) { case 'n': break; case 'c': data_c = (unsigned char *)data; for (i=0; ilincomEntries, F->n_lincom, sizeof(struct LincomEntryType), LincomCmp); if (L==NULL) return(0); /*****************************************/ /** if we got here, we found the field! **/ /** read into dataout and scale the first element **/ recurse_level++; spf1 = GetSPF(L->in_fields[0], F, error_code); if (*error_code != GD_E_OK) return(1); /* read and scale the first field and record the number of samples * returned */ *n_read = DoField(F, L->in_fields[0], first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code); recurse_level--; if (*error_code != GD_E_OK) return(1); /* Nothing to lincomise */ if (*n_read == 0) return 1; ScaleData(data_out, return_type, *n_read, L->m[0], L->b[0]); if (L->n_infields > 1) { for (i=1; in_infields; i++) { recurse_level++; /* find the samples per frame of the next field */ spf2 = GetSPF(L->in_fields[i], F, error_code); if (*error_code != GD_E_OK) return(1); /* calculate the first sample and number of samples to read of the * next field */ num_samp2 = (int)ceil((double)*n_read * spf2 / spf1); first_samp2 = (first_frame * spf2 + first_samp * spf2 / spf1); /* Allocate a temporary buffer for the next field */ tmpbuf = AllocTmpbuff(return_type, num_samp2); if (!tmpbuf && return_type != 'n') { return(0); } /* read the next field */ n_read2 = DoField(F, L->in_fields[i], 0, first_samp2, 0, num_samp2, return_type, tmpbuf, error_code); recurse_level--; if (*error_code != GD_E_OK) { free(tmpbuf); return(1); } ScaleData(tmpbuf, return_type, n_read2, L->m[i], L->b[i]); if (n_read2 > 0 && n_read2 * spf1 != *n_read * spf2) { *n_read = n_read2 * spf1 / spf2; } AddData(data_out, spf1, tmpbuf, spf2, return_type, *n_read); free(tmpbuf); } } return(1); } /***************************************************************************/ /* */ /* Look to see if the field code belongs to a multiply. If so, parse it. */ /* */ /***************************************************************************/ static int DoIfMultiply(struct FormatType *F, const char *field_code, int first_frame, int first_samp, int num_frames, int num_samp, char return_type, void *data_out, int *error_code, int *n_read) { struct MultiplyEntryType tM; struct MultiplyEntryType *M; void *tmpbuf; int spf1, spf2, num_samp2, first_samp2; int n_read2; /******* binary search for the field *******/ /* make a LincomEntry we can compare to */ strncpy(tM.field, field_code, FIELD_LENGTH); /** use the stdlib binary search */ M = bsearch(&tM, F->multiplyEntries, F->n_multiply, sizeof(struct MultiplyEntryType), MultiplyCmp); if (M==NULL) return(0); /*****************************************/ /** if we got here, we found the field! **/ /** read into dataout and scale the first element **/ recurse_level++; /* find the samples per frame of the first field */ spf1 = GetSPF(M->in_fields[0], F, error_code); if (*error_code != GD_E_OK) return(1); /* read the first field and record the number of samples * returned */ *n_read = DoField(F, M->in_fields[0], first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code); recurse_level--; if (*error_code != GD_E_OK) return 1; /* Nothing to multiply */ if (*n_read == 0) return 1; recurse_level++; /* find the samples per frame of the second field */ spf2 = GetSPF(M->in_fields[1], F, error_code); if (*error_code != GD_E_OK) return(1); /* calculate the first sample and number of samples to read of the * second field */ num_samp2 = (int)ceil((double)*n_read * spf2 / spf1); first_samp2 = (first_frame * spf2 + first_samp * spf2 / spf1); /* Allocate a temporary buffer for the second field */ tmpbuf = AllocTmpbuff(return_type, num_samp2); if (!tmpbuf && return_type != 'n') { return(0); } /* read the second field */ n_read2 = DoField(F, M->in_fields[1], 0, first_samp2, 0, num_samp2, return_type, tmpbuf, error_code); recurse_level--; if (*error_code != GD_E_OK) { free(tmpbuf); return(1); } if (n_read2 > 0 && n_read2 * spf1 < *n_read * spf2) { *n_read = n_read2 * spf1 / spf2; } MultiplyData(data_out, spf1, tmpbuf, spf2, return_type, *n_read); free(tmpbuf); return(1); } /***************************************************************************/ /* */ /* Look to see if the field code belongs to a bitfield. If so, parse it.*/ /* */ /***************************************************************************/ static int DoIfBit(struct FormatType *F, const char *field_code, int first_frame, int first_samp, int num_frames, int num_samp, char return_type, void *data_out, int *error_code, int *n_read) { struct BitEntryType tB; struct BitEntryType *B; unsigned *tmpbuf; int i; int spf; int ns; unsigned mask; /******* binary search for the field *******/ /* make a BitEntry we can compare to */ strncpy(tB.field, field_code, FIELD_LENGTH); /** use the stdlib binary search */ B = bsearch(&tB, F->bitEntries, F->n_bit, sizeof(struct BitEntryType), BitCmp); if (B==NULL) return(0); /*****************************************/ /** if we got here, we found the field! **/ recurse_level++; spf = GetSPF(B->raw_field, F, error_code); recurse_level--; if (*error_code!=GD_E_OK) { *n_read = 0; return(1); } ns = num_samp + num_frames*spf; tmpbuf = (unsigned *)malloc(ns*sizeof(unsigned)); recurse_level++; *n_read = DoField(F, B->raw_field, first_frame, first_samp, num_frames, num_samp, 'U', tmpbuf, error_code); recurse_level--; if (*error_code!=GD_E_OK) { free(tmpbuf); return(1); } if (B->numbits==32) mask = 0xffffffff; else mask = (unsigned)(pow(2,B->numbits)-0.9999); for (i=0; i<*n_read; i++) { tmpbuf[i] = (tmpbuf[i]>>B->bitnum) & mask; } *error_code = ConvertType((unsigned char *)tmpbuf, 'U', data_out, return_type, *n_read); free(tmpbuf); return(1); } /***************************************************************************/ /* */ /* ReadLinterpFile: Read in the linterp data for this field */ /* */ /***************************************************************************/ void MakeDummyLinterp(struct LinterpEntryType *E); /* prototype => no warning... */ void MakeDummyLinterp(struct LinterpEntryType *E) { E->n_interp = 2; E->x = (double *)malloc(2*sizeof(double)); E->y = (double *)malloc(2*sizeof(double)); E->x[0] = 0; E->y[0] = 0; E->x[1] = 1; E->y[1] = 1; } static int ReadLinterpFile(struct LinterpEntryType *E) { FILE *fp; int i; char line[255]; int linenum = 0; fp = fopen(E->linterp_file, "r"); if (fp==NULL) { MakeDummyLinterp(E); return SetGetDataError(GD_E_OPEN_LINFILE, GD_E_LINFILE_SE_OPEN, NULL, 0, E->linterp_file); } /* first read the file to see how big it is */ i=0; while (GetLine(fp, line, &linenum)) { i++; } if (i<2) { MakeDummyLinterp(E); return SetGetDataError(GD_E_OPEN_LINFILE, GD_E_LINFILE_SE_LENGTH, NULL, 0, E->linterp_file); } E->n_interp = i; E->x = (double *)malloc(i*sizeof(double)); E->y = (double *)malloc(i*sizeof(double)); /* now read in the data */ rewind(fp); linenum = 0; for (i=0; in_interp; i++) { GetLine(fp, line, &linenum); sscanf(line, "%lg %lg",&(E->x[i]), &(E->y[i])); } return (GD_E_OK); } /***************************************************************************/ /* */ /* GetIndex: just linearly search - we are probably right to start with */ /* */ /***************************************************************************/ static int GetIndex(double x, double lx[], int idx, int n) { /* increment until we are bigger */ while ((idx < n-2) && (x > lx[idx])) { idx++; } /* decrement until we are smaller */ while ((idx > 0) && (x < lx[idx])) { idx--; } return(idx); } /***************************************************************************/ /* */ /* LinterpData: calibrate data using lookup table lx and ly */ /* */ /***************************************************************************/ static void LinterpData(void *data, char type, int npts, double *lx, double *ly, int n_ln) { int i, idx=0; double x; for (i=0; ilinterpEntries, F->n_linterp, sizeof(struct LinterpEntryType), LinterpCmp); if (I==NULL) return(0); /*****************************************/ /** if we got here, we found the field! **/ if (I->n_interp<0) { *error_code = ReadLinterpFile(I); if (*error_code != GD_E_OK) { *n_read = 0; return(1); } } recurse_level++; *n_read = DoField(F, I->raw_field, first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code); recurse_level--; if (*error_code!=GD_E_OK) return(1); LinterpData(data_out, return_type, *n_read, I->x, I->y, I->n_interp); return(1); } /***************************************************************************/ /* */ /* DoField: Doing one field once F has been identified */ /* */ /***************************************************************************/ static int DoField(struct FormatType *F, const char *field_code, int first_frame, int first_samp, int num_frames, int num_samp, char return_type, void *data_out, int *error_code) { int n_read; if (recurse_level>10) { *error_code = SetGetDataError(GD_E_RECURSE_LEVEL, 0, NULL, 0, field_code); return(0); } /********************************************/ /* if Asking for "FILEFRAM" or "INDEX", just return it */ if ((strcmp(field_code,"FILEFRAM")==0) || (strcmp(field_code,"INDEX")==0)) { n_read = num_frames + num_samp; if (data_out!=NULL) { FillFileFrame(data_out, return_type, first_frame+first_samp+ F->frame_offset, n_read); } *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); return(n_read); } if (DoIfRaw(F, field_code, first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code, &n_read)) { return(n_read); } else if (DoIfLincom(F, field_code, first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code, &n_read)) { return(n_read); } else if (DoIfBit(F, field_code, first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code, &n_read)) { return(n_read); } else if (DoIfLinterp(F, field_code, first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code, &n_read)) { return(n_read); } else if (DoIfMultiply(F, field_code, first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code, &n_read)) { return(n_read); } else { *error_code = SetGetDataError(GD_E_BAD_CODE, 0, NULL, 0, field_code); return(0); } } /***************************************************************************/ /* */ /* GetData: read BLAST format files. */ /* filename_in: the name of the file directory (raw files are in here) */ /* field_code: the name of the field you want to read */ /* first_frame, first_samp: the first sample read is */ /* first_samp + samples_per_frame*first_frame */ /* num_frames, num_samps: the number of samples read is */ /* num_samps + samples_per_frame*num_frames */ /* return_type: data type of *data_out. 's': 16 bit signed */ /* 'u' 16bit unsigned 'S' 32bit signed 'U' 32bit unsigned */ /* 'c' 8 bit unsigned */ /* void *data_out: array to put the data */ /* *error_code: error code is returned here. */ /* */ /* return value: returns number of samples actually read into data_out */ /* */ /***************************************************************************/ int GetData(const char *filename_in, const char *field_code, int first_frame, int first_samp, int num_frames, int num_samp, char return_type, void *data_out, int *error_code) { struct FormatType *F; int n_read=0; char filename[MAX_FILENAME_LENGTH+1]; *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); if (first_time) { Formats.n = 0; Formats.F = NULL; first_time = 0; } strncpy(filename, filename_in, MAX_FILENAME_LENGTH); if (filename[strlen(filename)-1]=='/') filename[strlen(filename)-1]='\0'; F = GetFormat(filename, error_code); if (!F || *error_code != GD_E_OK) { return(0); } first_frame -= F->frame_offset; n_read = DoField(F, field_code, first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code); return(n_read); } /***************************************************************************/ /* */ /* Get the number of frames available */ /* */ /***************************************************************************/ int GetNFrames(const char *filename_in, int *error_code, const char *in_field) { struct FormatType *F; char filename[MAX_FILENAME_LENGTH+1]; char raw_data_filename[2 * MAX_FILENAME_LENGTH + FIELD_LENGTH + 2]; struct stat statbuf; int nf; *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); if (first_time) { Formats.n = 0; Formats.F = NULL; first_time = 0; } strncpy(filename, filename_in, MAX_FILENAME_LENGTH); if (filename[strlen(filename)-1]=='/') filename[strlen(filename)-1]='\0'; F = GetFormat(filename, error_code); if (*error_code != GD_E_OK) { return(0); } if (!F || F->n_raw==0) { *error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_RAW, NULL, 0, NULL); return(0); } /* load the first valid raw field */ snprintf(raw_data_filename, 2 * MAX_FILENAME_LENGTH + FIELD_LENGTH + 2, "%s/%s", filename, F->first_field.file); if (stat(raw_data_filename, &statbuf) < 0) { return(0); } nf = statbuf.st_size/ (F->first_field.size*F->first_field.samples_per_frame); nf += F->frame_offset; nf -= 2; if (nf < 0) nf = 0; return(nf); } /***************************************************************************/ /* */ /* Get the number of samples for each frame for the given field */ /* */ /***************************************************************************/ int GetSamplesPerFrame(const char *filename_in, const char *field_name, int *error_code) { struct FormatType *F; char filename[MAX_FILENAME_LENGTH+1]; *error_code = SetGetDataError(GD_E_OK, 0, NULL, 0, NULL); if (first_time) { Formats.n = 0; Formats.F = NULL; first_time = 0; } strncpy(filename, filename_in, MAX_FILENAME_LENGTH); if (filename[strlen(filename)-1]=='/') filename[strlen(filename)-1]='\0'; F = GetFormat(filename, error_code); if (*error_code!=GD_E_OK) { return(0); } if (!F || F->n_raw==0) { *error_code = SetGetDataError(GD_E_FORMAT, GD_E_FORMAT_SE_N_RAW, NULL, 0, NULL); return(0); } return GetSPF(field_name, F, error_code); } /* vim: ts=2 sw=2 et */ kst-2.0.3/old_tests/dirfile_replay/getdata_struct.h000644 001750 001750 00000004742 11544160210 023052 0ustar00synthsynth000000 000000 /* (C) 2003 C. Barth Netterfield */ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /***************************************************************/ /* */ /* Structures for describing dirfile formats */ /* */ /***************************************************************/ #ifndef GETDATA_STRUCT_H #define GETDATA_STRUCT_H #define FIELD_LENGTH 50 #define MAX_FILENAME_LENGTH 250 #define MAX_LINE_LENGTH 250 #define MAX_LINCOM 3 #define MAX_IN_COLS 15 struct RawEntryType { char field[FIELD_LENGTH+1]; char file[MAX_FILENAME_LENGTH + FIELD_LENGTH + 2]; int fp; char type; int size; int samples_per_frame; }; struct LincomEntryType { char field[FIELD_LENGTH+1]; int n_infields; char in_fields[MAX_LINCOM][FIELD_LENGTH+1]; double m[MAX_LINCOM]; double b[MAX_LINCOM]; }; struct LinterpEntryType { char field[FIELD_LENGTH+1]; char raw_field[FIELD_LENGTH+1]; char linterp_file[MAX_FILENAME_LENGTH]; int n_interp; double *x; double *y; }; struct MultiplyEntryType { char field[FIELD_LENGTH+1]; char in_fields[2][FIELD_LENGTH+1]; }; struct MplexEntryType { char field[FIELD_LENGTH+1]; char cnt_field[FIELD_LENGTH+1]; char data_field[FIELD_LENGTH+1]; int i; int max_i; }; struct BitEntryType { char field[FIELD_LENGTH+1]; char raw_field[FIELD_LENGTH+1]; int bitnum; int numbits; }; struct FormatType { char FileDirName[MAX_FILENAME_LENGTH]; int frame_offset; struct RawEntryType first_field; struct RawEntryType *rawEntries; int n_raw; struct LincomEntryType *lincomEntries; int n_lincom; struct LinterpEntryType *linterpEntries; int n_linterp; struct MultiplyEntryType *multiplyEntries; int n_multiply; struct MplexEntryType *mplexEntries; int n_mplex; struct BitEntryType *bitEntries; int n_bit; }; #endif kst-2.0.3/old_tests/dirfile_replay/Makefile000644 001750 001750 00000000171 11544160210 021314 0ustar00synthsynth000000 000000 CC = gcc -g all: replay replay: replay.o getdata.o getdata.h getdata_struct.h $(CC) -o replay replay.o getdata.o -lm kst-2.0.3/old_tests/dirfile_replay/getdata.h000644 001750 001750 00000013001 11544160210 021432 0ustar00synthsynth000000 000000 #ifndef GETDATA_H #define GETDATA_H //#include /* The following has been extracted from internal.cpp from kjs */ /* ** For systems without NAN, this is a NAN in IEEE double format. */ #if !defined(NAN) static double __NAN() { /* work around some strict alignment requirements for double variables on some architectures (e.g. PA-RISC) */ typedef union { unsigned char b[8]; double d; } kjs_double_t; #ifdef WORDS_BIGENDIAN static const kjs_double_t NaN_Bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } }; #elif defined(arm) static const kjs_double_t NaN_Bytes = { { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 } }; #else static const kjs_double_t NaN_Bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } }; #endif const double NaN = NaN_Bytes.d; return NaN; } #define NAN __NAN() #endif /* !defined(NAN) */ extern const char *GD_ERROR_CODES[15]; #define GD_E_OK 0 #define GD_E_OPEN_FORMAT 1 #define GD_E_FORMAT 2 #define GD_E_FIELD 4 #define GD_E_BAD_CODE 5 #define GD_E_BAD_RETURN_TYPE 6 #define GD_E_OPEN_RAWFIELD 7 #define GD_E_OPEN_INCLUDE 8 #define GD_E_INTERNAL_ERROR 9 #define GD_E_SIZE_MISMATCH 12 #define GD_E_OPEN_LINFILE 13 #define GD_E_RECURSE_LEVEL 14 /***************************************************************************/ /* */ /* GetData: read BLAST format files. */ /* filename_in: the name of the file directory (raw files are in here) */ /* field_code: the name of the field you want to read */ /* first_frame, first_samp: the first sample read is */ /* first_samp + samples_per_frame*first_frame */ /* num_frames, num_samps: the number of samples read is */ /* num_samps + samples_per_frame*num_frames */ /* return_type: data type of *data_out. 's': 16 bit signed */ /* 'u' 16bit unsiged. 'S' 32bit signed 'U' 32bit unsigned */ /* 'c' 8 bit unsigned */ /* void *data_out: array to put the data */ /* *error_code: error code is returned here. If error_code==null, */ /* GetData prints the error message and exits */ /* */ /* return value: returns number of samples actually read into data_out */ /* */ /***************************************************************************/ #ifdef __cplusplus extern "C" #endif int GetData(const char *filename_in, const char *field_code, int first_sframe, int first_samp, int num_sframes, int num_samp, char return_type, void *data_out, int *error_code); /***************************************************************************/ /* */ /* GetDataErrorString: Write a descriptive message in the supplied */ /* buffer describing the last library error. The message may be */ /* truncated but should be null terminated. */ /* */ /* buffer: memory into which to write the string */ /* buflen: length of the buffer. GetDataErrorString will not write */ /* more than buflen characters (including the trailing '\0') */ /* */ /* return value: buffer or NULL if buflen < 1 */ /* */ /***************************************************************************/ #ifdef __cplusplus extern "C" #endif char* GetDataErrorString(char* buffer, size_t buflen); /***************************************************************************/ /* */ /* Get the number of samples for each frame for the given field */ /* */ /***************************************************************************/ #ifdef __cplusplus extern "C" #endif int GetSamplesPerFrame(const char *filename_in, const char *field_name, int *error_code); /***************************************************************************/ /* */ /* Get the number of frames available */ /* */ /***************************************************************************/ #ifdef __cplusplus extern "C" #endif int GetNFrames(const char *filename_in, int *error_code, const char *field); /***************************************************************************/ /* */ /* Get the number format structure */ /* */ /***************************************************************************/ #ifdef __cplusplus extern "C" #endif struct FormatType *GetFormat(const char *filedir, int *error_code); #endif kst-2.0.3/old_tests/testcsd.cpp000644 001750 001750 00000015767 11544160210 017060 0ustar00synthsynth000000 000000 /* * Copyright 2005, The University of Toronto * Licensed under GPL. */ #include "ksttestcase.h" #include "kstcsd.h" #include #include #include #include #include static void exitHelper() { KST::dataSourceList.clear(); KST::scalarList.clear(); KST::dataObjectList.clear(); } int rc = KstTestSuccess; #define doTest(x) testAssert(x, QString("Line %1").arg(__LINE__)) #define doTestD(x, y) testAssert(x, QString("%1: %2").arg(__LINE__).arg(y)) void testAssert(bool result, const QString& text = "Unknown") { if (!result) { KstTestFailed(); printf("Test [%s] failed.\n", text.toLatin1().data()); } } QDomDocument makeDOMElement(const QString& tag, const QString& val) { // Should be some boundary checking in the constructor. QDomDocument csdDOM("csddocument"); QDomElement csdElement, child; QDomText text; csdElement = csdDOM.createElement("csdDOMTest"); child = csdDOM.createElement("tag"); text = csdDOM.createTextNode(tag); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("vectag"); text = csdDOM.createTextNode(val); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("sampRate"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("average"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("fiftLen"); text = csdDOM.createTextNode("5"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("adopize"); text = csdDOM.createTextNode("0"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("apodizefxn"); text = csdDOM.createTextNode("WindowOriginal"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("gaussiansigma"); text = csdDOM.createTextNode("0.01"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("removeMean"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("windowsize"); text = csdDOM.createTextNode("5000"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("vectorunits"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("rateunits"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); child = csdDOM.createElement("output"); text = csdDOM.createTextNode("1"); child.appendChild(text); csdElement.appendChild(child); csdDOM.appendChild(csdElement); return csdDOM; } void doTests() { KstVectorPtr vp = new KstVector(KstObjectTag::fromString("tempVector"), 10); for (int i = 0; i < 10; i++){ vp->value()[i] = i; } KstCSDPtr csd = new KstCSD("csdTest", vp, 0.0, false, false, false, WindowUndefined, 0, 0, 0.0, PSDUndefined, QString::null, QString::null); doTest(csd->tagName() == "csdTest"); doTest(csd->vTag() == "tempVector"); doTest(csd->output() == PSDUndefined); doTest(!csd->apodize()); doTest(!csd->removeMean()); doTest(!csd->average()); doTest(csd->freq() == 1.0); doTest(csd->apodizeFxn() == WindowUndefined); doTest(csd->length() == 0); doTest(csd->windowSize() == 0); doTest(csd->gaussianSigma() == 0); doTest(csd->vectorUnits().isEmpty()); doTest(csd->rateUnits().isEmpty()); csd->setOutput(PSDAmplitudeSpectralDensity); csd->setApodize(true); csd->setRemoveMean(true); csd->setAverage(true); csd->setFreq(0.1); csd->setApodizeFxn(WindowOriginal); csd->setLength(3); csd->setWindowSize(50); csd->setGaussianSigma(0.2); doTest(csd->tagName() == "csdTest"); doTest(csd->vTag() == "tempVector"); doTest(csd->output() == PSDAmplitudeSpectralDensity); doTest(csd->apodize()); doTest(csd->removeMean()); doTest(csd->average()); doTest(csd->freq() == 0.1); doTest(csd->windowSize() == 50); doTest(csd->apodizeFxn() == WindowOriginal); doTest(csd->gaussianSigma() == 0.2); // KTempFile tf(locateLocal("tmp", "kst-csd"), "txt"); // QFile *qf = tf.file(); // QTextStream ts(qf); // csd->save(ts, ""); QDomNode n = makeDOMElement("csdDOMCsd", "csdDOMVector").firstChild(); QDomElement e = n.toElement(); KstCSDPtr csdDOM = new KstCSD(e); doTest(csdDOM->tagName() == "csdDOMCsd"); doTest(csdDOM->output() == PSDPowerSpectralDensity); doTest(csdDOM->apodize()); doTest(csdDOM->removeMean()); doTest(csdDOM->average()); doTest(csdDOM->freq() == 1); doTest(csdDOM->apodizeFxn() == WindowOriginal); doTest(csdDOM->gaussianSigma() == 0.01); doTest(csdDOM->windowSize() == 5000); KstVectorPtr vp2 = new KstVector(KstObjectTag::fromString("tempVector2"), 10); for (int i = 0; i < 10; i++){ vp2->value()[i] = i; } csdDOM->setVector(vp2); doTest(csdDOM->vTag() == "tempVector2"); csdDOM->setWindowSize(9); KstMatrixPtr outMatrix = csdDOM->outputMatrix(); doTest(outMatrix->resize(3, 3, false)); // very odd thing to do? doTest(outMatrix->setValue(0, 0, 1.716299)); doTest(outMatrix->setValue(0, 1, -0.485527)); doTest(outMatrix->setValue(0, 2, -0.288690)); doTest(outMatrix->setValue(1, 0, 1.716299)); doTest(outMatrix->setValue(1, 1, NAN)); doTest(outMatrix->setValue(1, 2, -0.274957)); doTest(outMatrix->setValue(2, 0, 1.711721)); doTest(outMatrix->setValue(2, 1, -0.485527)); doTest(outMatrix->setValue(2, 2, -0.293267)); doTest(outMatrix->sampleCount() == 9); doTest(outMatrix->value(0, 0) == 1.716299); doTest(outMatrix->value(0, 1) == -0.485527); doTest(outMatrix->value(0, 2) == -0.288690); doTest(outMatrix->value(1, 0) == 1.716299); doTest(outMatrix->value(1, 1) == 0); doTest(outMatrix->value(1, 2) == -0.274957); doTest(outMatrix->value(2, 0) == 1.711721); doTest(outMatrix->value(2, 1) == -0.485527); doTest(outMatrix->value(2, 2) == -0.293267); doTest(csdDOM->update(0) == KstObject::UPDATE); outMatrix = csdDOM->outputMatrix(); doTest(outMatrix->sampleCount() == 128); csdDOM->setWindowSize(11); doTest(outMatrix->sampleCount() == 128); doTest(outMatrix->value(0, 0) == 1.716299); doTest(outMatrix->value(0, 1) == -0.485527); doTest(outMatrix->value(0, 2) == -0.288690); doTest(outMatrix->value(1, 0) == 1.716299); doTest(outMatrix->value(1, 1) == 0); doTest(outMatrix->value(1, 2) == -0.274957); doTest(outMatrix->value(2, 0) == 1.711721); doTest(outMatrix->value(2, 1) == -0.485527); doTest(outMatrix->value(2, 2) == -0.293267); } int main(int argc, char **argv) { atexit(exitHelper); QCoreApplication app(argc, argv); doTests(); // Don't put tests in main because we need to ensure that no KstObjects // remain past the exit handler exitHelper(); // need to run it here before kapp goes away in some cases. if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } kst-2.0.3/old_tests/COVERAGE000644 001750 001750 00000003274 11544160210 016007 0ustar00synthsynth000000 000000 Testing Coverage in Kst ======================= Test: testeqparser Last Run: 03/02/05 Failures: 0 File Cov Notes ---------------------------------------------------------------------------- enodes.cpp 91% Mostly missed error cases and some plugin types. enodefactory.cpp 100% eparse.y 94% escan.l 95% kstvector.cpp 79% Not meant to test this file. kstscalar.cpp 36% Not meant to test this file. pluginloader.cpp 70% Not meant to test this file. plugin.cpp 55% Not meant to test this file. Test: testrvector Last Run: 01/17/05 Failures: 7 File Last Test Cov Notes ---------------------------------------------------------------------------- ascii.cpp 81% Missing GUI stuff, some error cases. kstrvector.cpp 40% Lots to do still. Test: testhistogram Last Run: 01/17/05 Failures: 0 File Last Test Cov Notes ---------------------------------------------------------------------------- ksthistogram.cpp 51% Missing loading, real-time auto-bin, percent, fraction, max-one, range with max < min, change vector, y label, x label, saving Test: testscalars Last Run: 01/17/05 Failures: 0 File Last Test Cov Notes ---------------------------------------------------------------------------- kstscalar.cpp 91% Missing saving Test: testvector Last Run: 01/17/05 Failures: 3 File Last Test Cov Notes ---------------------------------------------------------------------------- kstvector.cpp 31% Lots to do Test: testlabelparser Last Run: 01/17/05 Failures: 0 File Last Test Cov Notes ---------------------------------------------------------------------------- labelparser.cpp 59% Lots of untested greek expansions, and some parse corner conditions, uninterpreted parsing kst-2.0.3/old_tests/planck/toigen.c000644 001750 001750 00000002632 11544160210 017567 0ustar00synthsynth000000 000000 /* No Copyright * Written By Staikos Computing Services Inc * Released to the public domain without warranty. */ #include #include #include #include #include #include int main(int argc, char **argv) { int VECSZ = 10240; PIOFLOAT vec[VECSZ]; register int i = 0; char *toi, *roi, *obj; PIOLONG rc1; PIOErr rc2; if (argc < 5) { fprintf(stderr, "usage: %s \n", argv[0]); return -1; } for (; i < VECSZ; ++i) { vec[i] = sin(((float)i) / 2000.0); } toi = (char *)malloc(strlen(argv[1]) + strlen(argv[2]) + 50); sprintf(toi, "group:%s:%s", argv[1], argv[2]); roi = (char *)malloc(strlen(argv[1]) + strlen(argv[3]) + 50); sprintf(roi, "group:%s:%s", argv[1], argv[3]); printf("Writing TOI group:\n[%s]\n[%s]\n", toi, roi); if (0 > (rc1 = PIOCreateTOIGrp(toi, roi, 0))) { fprintf(stderr, "Error writing TOI group. rc=%ld\n", rc1); free(roi); free(toi); return -2; } obj = (char *)malloc(strlen(argv[1]) + strlen(argv[2]) + strlen(argv[4]) + 50); sprintf(obj, "object:%s:%s:%s", argv[1], argv[2], argv[4]); if (VECSZ != (rc2 = PIOWriteTOIObject(vec, obj, "PIOFLOAT", "begin=42;end=10281", NULL))) { fprintf(stderr, "Error writing object. rc=%ld [%s]\n", rc2, PIOErrMess(rc2)); free(obj); free(roi); free(toi); return -3; } free(obj); free(roi); free(toi); return 0; } kst-2.0.3/old_tests/datagenerator.pl000755 001750 001750 00000000631 11544160210 020043 0ustar00synthsynth000000 000000 #!/usr/bin/perl # open(OUTPUT, ">$ARGV[0]") || die "Can't open $ARGV[0]: $!"; $i = 0; while (true) { print OUTPUT "$i "; $ii = $i/10; print OUTPUT sin($ii) + rand(0.4) - 0.2; print OUTPUT " "; print OUTPUT cos($ii) + rand(0.4) - 0.2; print OUTPUT " "; print OUTPUT sin($ii * $ii) * (cos($ii) + rand(0.4) - 0.2); print OUTPUT " "; print OUTPUT "\n"; $i++; select(undef, undef, undef, 0.001); } kst-2.0.3/old_tests/testlabelparser.cpp000644 001750 001750 00000031130 11544160210 020561 0ustar00synthsynth000000 000000 /* * Copyright 2004, The University of Toronto * Licensed under GPL. */ #include "ksttestcase.h" #include #include static void exitHelper() { KST::vectorList.clear(); KST::scalarList.clear(); KST::dataObjectList.clear(); } static void dumpAttributes(Label::Chunk *l, QString indent) { printf("%sb:%d i:%d u:%d c:%s\n", indent.toLatin1().data(), l->attributes.bold, l->attributes.italic, l->attributes.underline, l->attributes.color.name().toLatin1().data()); } static void dumpTree(Label::Chunk *l, QString indent = "") { while (l) { printf("%sNode: %p %s[%s]%s\n", indent.toLatin1().data(), l, l->vOffset == Label::Chunk::None ? "" : (l->vOffset == Label::Chunk::Up ? "U " : "D "), l->text.toLatin1().data(), l->group ? " [G]" : ""); printf("%sPrev: %p Next: %p Up: %p Down: %p\n", indent.toLatin1().data(), l->prev, l->next, l->up, l->down); dumpAttributes(l, indent); if (l->group) { dumpTree(l->group, indent + " "); } if (l->up) { dumpTree(l->up, indent + " "); } if (l->down) { dumpTree(l->down, indent + " "); } l = l->next; } } static void dumpTree(Label::Parsed *l) { dumpTree(l->chunk); } int rc = KstTestSuccess; #define doTest(x) testAssert(x, QString("Line %1").arg(__LINE__)) #define doTestD(x, y) testAssert(x, QString("%1: %2").arg(__LINE__).arg(y)) void testAssert(bool result, const QString& text = "Unknown") { if (!result) { KstTestFailed(); printf("Test [%s] failed.\n", text.toLatin1().data()); } } void doTests() { Label::Parsed *parsed = Label::parse(""); doTestD(parsed != 0L, "Empty label parsed"); doTest(parsed->chunk->prev == 0L); doTest(parsed->chunk->next == 0L); doTest(parsed->chunk->text == QString::null); doTest(parsed->chunk->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("a"); doTest(parsed != 0L); doTest(parsed->chunk->prev == 0L); doTest(parsed->chunk->next == 0L); doTest(parsed->chunk->text == "a"); doTest(parsed->chunk->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("\\]"); doTest(parsed != 0L); doTest(parsed->chunk->prev == 0L); doTest(parsed->chunk->next == 0L); doTest(parsed->chunk->text == "]"); doTest(parsed->chunk->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("\\\\"); doTest(parsed != 0L); doTest(parsed->chunk->prev == 0L); doTest(parsed->chunk->next == 0L); doTest(parsed->chunk->text == "\\"); doTest(parsed->chunk->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("\\tau"); doTest(parsed != 0L); doTest(parsed->chunk->prev == 0L); doTest(parsed->chunk->next == 0L); doTest(parsed->chunk->text == QChar(0x3A4 + 0x20)); doTest(parsed->chunk->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("\\t"); doTest(parsed != 0L); doTest(parsed->chunk->text == ""); doTest(parsed->chunk->tab == true); doTest(parsed->chunk->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("\\n"); doTest(parsed != 0L); doTest(parsed->chunk->text == ""); doTest(parsed->chunk->linebreak == true); doTest(parsed->chunk->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("\\tau\\Theta"); doTest(parsed != 0L); doTest(parsed->chunk->next == 0L); doTest(parsed->chunk->text[0] == QChar(0x3A4 + 0x20)); doTest(parsed->chunk->text[1] == QChar(0x398)); doTest(parsed->chunk->text.length() == 2); delete parsed; Label::Chunk *c = 0L; parsed = Label::parse("\\taufoo bar\\n\\Theta"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next != 0L); doTest(c->text == QString(QChar(0x3A4 + 0x20)) + "foo bar"); c = c->next; doTest(c->prev != 0L); doTest(c->next != 0L); doTest(c->text == ""); doTest(c->linebreak == true); c = c->next; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->text == QChar(0x398)); delete parsed; parsed = Label::parse("x^y^z"); doTest(parsed == 0L); parsed = Label::parse("x_y_z"); doTest(parsed == 0L); parsed = Label::parse("x^y_z"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->prev == 0L); doTest(c->next == 0L); doTest(c->up != 0L); doTest(c->down != 0L); doTest(c->text == "x"); doTest(c->vOffset == Label::Chunk::None); c = c->up; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "y"); doTest(c->vOffset == Label::Chunk::Up); c = c->prev->down; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "z"); doTest(c->vOffset == Label::Chunk::Down); delete parsed; parsed = Label::parse("x^{}"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->prev == 0L); doTest(c->next == 0L); doTest(c->up != 0L); doTest(c->down == 0L); doTest(c->text == "x"); doTest(c->group == 0L); doTest(c->vOffset == Label::Chunk::None); c = c->up; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->group != 0L); doTest(c->vOffset == Label::Chunk::Up); c = c->group; doTest(c->text == ""); doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->group == 0L); doTest(c->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("x^{y+1}_{z-1}"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->prev == 0L); doTest(c->next == 0L); doTest(c->up != 0L); doTest(c->down != 0L); doTest(c->text == "x"); doTest(c->group == 0L); doTest(c->vOffset == Label::Chunk::None); c = c->up; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->group != 0L); doTest(c->vOffset == Label::Chunk::Up); c = c->group; doTest(c->text == "y+1"); doTest(c->group == 0L); doTest(c->vOffset == Label::Chunk::None); c = c->prev->prev->down; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->group != 0L); doTest(c->vOffset == Label::Chunk::Down); c = c->group; doTest(c->text == "z-1"); doTest(c->group == 0L); doTest(c->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("x\\^y"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->prev == 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "x^y"); doTest(c->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("x^{y^{q+1} + 1}_{z-1}"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->prev == 0L); doTest(c->next == 0L); doTest(c->up != 0L); doTest(c->down != 0L); doTest(c->text == "x"); doTest(c->vOffset == Label::Chunk::None); c = c->up; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->group != 0L); doTest(c->vOffset == Label::Chunk::Up); c = c->group; doTest(c->text == "y"); doTest(c->prev != 0L); doTest(c->next != 0L); doTest(c->up != 0L); doTest(c->down == 0L); doTest(c->group == 0L); doTest(c->vOffset == Label::Chunk::None); c = c->up; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->group != 0L); doTest(c->vOffset == Label::Chunk::Up); c = c->group; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "q+1"); doTest(c->vOffset == Label::Chunk::None); c = c->prev->prev->next; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == " + 1"); doTest(c->vOffset == Label::Chunk::None); c = c->prev->prev->prev->down; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->group); doTest(c->vOffset == Label::Chunk::Down); c = c->group; doTest(c->prev != 0L); doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "z-1"); doTest(c->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("{2*2}"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next == 0L); doTest(c->group != 0L); doTest(c->vOffset == Label::Chunk::None); c = c->group; doTest(c->text == "2*2"); doTest(c->vOffset == Label::Chunk::None); delete parsed; parsed = Label::parse("x^100"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next != 0L); doTest(c->up != 0L); doTest(c->text == "x"); doTest(c->vOffset == Label::Chunk::None); c = c->next; doTest(c->next == 0L); doTest(c->text == "00"); doTest(c->vOffset == Label::Chunk::None); c = c->prev->up; doTest(c->next == 0L); doTest(c->text == "1"); doTest(c->vOffset == Label::Chunk::Up); delete parsed; parsed = Label::parse("x^100*200"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next != 0L); doTest(c->up != 0L); doTest(c->text == "x"); doTest(c->vOffset == Label::Chunk::None); c = c->next; doTest(c->next == 0L); doTest(c->text == "00*200"); doTest(c->vOffset == Label::Chunk::None); c = c->prev->up; doTest(c->next == 0L); doTest(c->text == "1"); doTest(c->vOffset == Label::Chunk::Up); delete parsed; parsed = Label::parse("[ a ^label ]"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "a ^label"); doTest(c->scalar); delete parsed; parsed = Label::parse("[vector[2]]"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "vector"); doTest(c->expression == "2"); doTest(c->vector); delete parsed; parsed = Label::parse("[a][b]"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next != 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "a"); doTest(c->scalar); c = c->next; doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "b"); doTest(c->scalar); delete parsed; parsed = Label::parse("[a]*[b]"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next != 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "a"); doTest(c->scalar); c = c->next; doTest(c->next != 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "*"); doTest(!c->scalar); c = c->next; doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "b"); doTest(c->scalar); delete parsed; parsed = Label::parse("[x]^[a]_[b][c]"); doTest(parsed != 0L); c = parsed->chunk; doTest(c->next != 0L); doTest(c->up != 0L); doTest(c->down != 0L); doTest(c->text == "x"); doTest(c->scalar); c = c->up; doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "a"); doTest(c->scalar); c = c->prev->down; doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "b"); doTest(c->scalar); c = c->prev->next; doTest(c->next == 0L); doTest(c->up == 0L); doTest(c->down == 0L); doTest(c->text == "c"); doTest(c->scalar); delete parsed; parsed = Label::parse("Ends in a \\"); delete parsed; parsed = Label::parse("_"); delete parsed; parsed = Label::parse("A weird { case }"); delete parsed; parsed = Label::parse("x^y^foo{ case }"); delete parsed; parsed = Label::parse("x^5\\"); delete parsed; parsed = Label::parse("}"); delete parsed; parsed = Label::parse("Average period (ADU)"); delete parsed; parsed = Label::parse("PSD (ADU/{Hz^{1/2}})"); delete parsed; parsed = Label::parse("\\Sigma^{(x+5)^2}_{5+1} + \\Pi^{\\Sigma^{i-j}_{i+j}}_{x = 0} + 5"); doTest(parsed != 0L); // more to test here delete parsed; parsed = Label::parse("A test \\textbf{bold \\textit{italicbold}} \\textit{italic}\n42^{\\textbf{42}^{42}} 42^\\textbf{42^{42}} 42^{42}\n\\underline{a whole\\tregion underlined}"); //dumpTree(parsed); // FIXME delete parsed; parsed = Label::parse("\\textbf{\\textit{italicbold}bold}"); // FIXME delete parsed; parsed = Label::parse("\\textcolor{red}{red}black"); // FIXME delete parsed; parsed = Label::parse("\\textbf{bold}unbold"); // FIXME delete parsed; // more to test... } int main(int argc, char **argv) { atexit(exitHelper); QCoreApplication app(argc, argv); doTests(); // Don't put tests in main because we need to ensure that no KstObjects // remain past the exit handler exitHelper(); // need to run it here before kapp goes away in some cases. if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } // vim: ts=2 sw=2 et kst-2.0.3/old_tests/healpix/healpix_example_sm.fits000644 001750 001750 00002222000 11544160210 023046 0ustar00synthsynth000000 000000 SIMPLE = T / file does conform to FITS standard BITPIX = 16 / number of bits per data pixel NAXIS = 0 / number of data axes EXTEND = T / FITS dataset may contain extensions COMMENT FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H COMMENT COMMENT DATE = '2005-11-01T22:02:12' / file creation date (YYYY-MM-DDThh:mm:ss UT) CREATOR = 'hpic_convert' / Software creating the map END XTENSION= 'BINTABLE' / binary table extension BITPIX = 8 / 8-bit bytes NAXIS = 2 / 2-dimensional binary table NAXIS1 = 12288 / width of table in bytes NAXIS2 = 48 / number of rows in table PCOUNT = 0 / size of special data area GCOUNT = 1 / one data group (required keyword) TFIELDS = 3 / number of fields in each row TTYPE1 = 'TEMPERATURE' / label for field 1 TFORM1 = '1024E ' / data format of field: 4-byte REAL TUNIT1 = 'Kelvin ' / physical unit of field TTYPE2 = 'Q-POLARISATION' / label for field 2 TFORM2 = '1024E ' / data format of field: 4-byte REAL TUNIT2 = 'Kelvin ' / physical unit of field TTYPE3 = 'U-POLARISATION' / label for field 3 TFORM3 = '1024E ' / data format of field: 4-byte REAL TUNIT3 = 'Kelvin ' / physical unit of field EXTNAME = 'Converted Map' / name of this binary table extension COMMENT COMMENT ----------------------------------------------- COMMENT Pixelization Specific Keywords COMMENT ----------------------------------------------- PIXTYPE = 'HEALPIX ' / HEALPIX Pixelization ORDERING= 'NESTED ' / Pixel ordering scheme, either RING or NESTED NSIDE = 64 / Resolution parameter for HEALPIX COORDSYS= 'C ' / Pixelization coordinate system COMMENT G = Galactic, E = ecliptic, C = celestial = equatorial, O = other COMMENT COMMENT ----------------------------------------------- COMMENT Data Specific Keywords COMMENT ----------------------------------------------- INDXSCHM= 'IMPLICIT' / Indexing : IMPLICIT or EXPLICIT GRAIN = 0 / Grain of pixel indexing COMMENT GRAIN=0 : no indexing of pixel data (IMPLICIT) COMMENT GRAIN=1 : 1 pixel index -> 1 pixel data (EXPLICIT) COMMENT GRAIN>1 : 1 pixel index -> data of GRAIN consecutive pixels (EXPLICIT) COMMENT EXTEND = 'T ' / FITS dataset may contain extensions DATE = '''2005-11-01T20:48:47''' / file creation date (YYYY-MM-DDThh:mm:ss UTEXTEND = '''T ''' / FITS dataset may contain extensions DATE = '''''''2004-10-03T02:19:16''''''' / file creation date (YYYY-MM-DDThh:EXTEND = '''''''T ''''''' / FITS dataset may contain extensions DATE = '''''''''''''''2004-10-03T02:18:43''''''''''''''' / file creation dateEXTEND = '''''''''''''''T ''''''''''''''' / FITS dataset may contain exteDATE = '''''''''''''''''''''''''''''''2004-10-03T02:18:12''''''''''''''''''' EXTEND = '''''''''''''''''''''''''''''''T '''''''''''''''''''''''''''''''DATE = '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''2004-0'VERSION = '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''1.2.0 'FIRSTPIX= 0 / First pixel # (0 based) LASTPIX = 12582911 / Last pixel # (0 based) MAX-LPOL= 2048 / Maximum multipole l used in map synthesis RANDSEED= -1 / Random generator seed FWHM = 0. / [deg] FWHM of gaussian symmetric beam HISTORY = 0. / = 0. / = 0.END @B)@ TdީA3ˆ°uB"9ArB?(bXf!M£]й ¤ڤBBi \@&Al0 HhAApd0¶&s²z=Y™D~ژ•]s-b(>]' J Xe&@9=ţ¶0V8 z£¼@hժ@.p…BӑAArBMBiB§]KBWl"A;fR~MžгrlSb 'T mFAM_C¶f6Q8~Y:§ ¾hϿ, 0r0c[)Ka{? ³hŠ$A2wT@B?¶· nY?SF$+O؆1'AcfY7‹E y/NgNb$?9њ½·, B]O‹RB +hAoKA)bz>7`ïA5Bk?JAdjeup U}+ZœOBKBB bBBcvC)B;BMBB O1“<^PS8+\y$Ǟ2—xeB?EܳM:¶ g%K“ £(A/B9H$ªW椘 BBj"AB  ! ),c´nAIHԟ<@EP£TǀgL=³´bhs`ښAyFqLU@% *Bµ$AD¬mB,^ZRiA|OpBhI@^BgW"A$6ABvAֳ'B(v­sB&Nsd@AGlCBSog·i)³G=m¥ӳ2`% ·­~BT·@ @ZAi}xB?%B`#A APc" ByĐGoAiVB7qŽ/`k™*¸£} KɐFW`ȿAï/~†H=“ݩ-@lhAH?A}^WtU³&A.?¸daB.B(@|/J?`€k´fŠx hA@_zD AY`pP_>`kq‘B(BF<}pCAE7^ƒԪAƖ\;L.'{?B!aB.V@SF B@BlH,|?B 8,<5«ɞVf +B+–:&zrJAf>p(B2 *ACSA B6̊?q?-8™E*B84yAB?(Ax _”: _HJ>ߠMpʚ (>|$5C5Ukt@,Rx ?4E׀EZ@{X+µ7Zf`Ǫ:C¹BgcJqʝ ŸRN¾OD ?kܻ8 UB1— +CuBԗ@3B ˆFB8BxF…B)Žj@DBsp4,A|B02AtcA=O@:«N@,vB‹ ]–wS| B]>'m¼(<6B''BedŠQWµQ 5³pEܞ†`+B­Ҧ1xB}]BrB2¿Z‡>kBjA^"wC'+B, B8A Bb|Bf]3BMl9@NnO“cF#{R B6B~6O`BӿB7!jAY.,f`B'A ŠcI$LB ªZBQ! *Cz‚[w 8N[V%9"n¢qjA"AA"|B~ApQZAȫB/CB\B*rB 0Bµ0+ B3v Bµ{5AOIJB B>BIB"4AWcAm;_dzPBBAYAf³<kJN*e=/ -mf@"CvZ…w&hkDJTA&4°"zBSK­zB ¯zEP2Au‘ܘ4^dh_5wߨ;A:Ԗ)B1.Bf~AmA=B&Q:@7BA0PAz7Ad\£ 5A BKpBjTBAMM79B! "(}'lOuxV:kª^l "ƒ]oµnoV,B}BU1AB{h·œwTD@5N>f@蔺“-:. *@mp@ElhEgY r9R'E(˜,ƒuT7dsAd.–&;l^/B@AD^BYB6ABTAztC,BBbF0'XHB) BK&B!H:B2e˜W}?zBCnBU…Q@|;5"HBALA{/B7 YBfB}BQ8 BS|BtApM*B:A^Bfx-BE8B†BbB0%BBAA.RB)j9l3tBhYhA7_1B@0A ®v nB<ԥ@–Bg3Oo V£eŸ? 1#vEz?@Akľz1(AuVD• A2 d)-CؖT&68XHAuSB e)n·›tB.p¹=N*BsAe28@ NEFhy2=`[<@bAHBy?YM\??+/Clv̇kX5;|.$8>ɿ4?r0:?r.>˾>t??^??_m}>e"z> ?,Pj-~>֐?=Ƌ=H>9`>?+>J6m[mH>7PXAn?$6 ?v>>Llnf 1=XIC9S¾?c3rD?-/?d-Ua>"?%^?>={8>5 BoJ=P=?[?&տk!z? ׾4<ܾ*p.Ve>@O = ?=|R>xL?N4޿Zd>U^> ?1y)Q-?&=v ;X?a7?ʦ&4Ӝ?Mt?2, ?V)> ZIXܿeQ >~>ɛD?"N=: >&)nx=/d?ϛ> ?;J|>Nj?U`H>5 I^Ѻ*K~f$Ƽ>>>ҳ&>v?5.>op>ldo~oo$\K+>ֿB:?ҿgH&>?)r=_W>3sj?,[> n??HX_>H!?'S _>|=?:?5h?mR@NH"S1?M Ni?Htw? >mE\t%r;Ǖ`MV(?IuB=ޠ>#?jo0<?=?Q>mE^2I;-;>Tr?$(q{i?vzƾ1Y ?bz>x%.>ݮH\@?/n>(>m2/h?@Or<2ľ.?1??T|?>kj忄 >㵿t4P&>b>ǿSD ˿76S?R'&=?,>E>Z"CV@Yurjm>|?1F?a<(}н>hz.>\Uܧ.^%\,>,?7@ʶ?,dA>6?v|?v:?х?m=ཹRpH>>f.m? "??ӱ`\>/g6>п< ?nNHn|H=-t1p݇>/ k:=֚\Fmi>n?n>>옴?>OUоҿtwPC 2?(?Nj2?aU%g?e>u14<JK>yL?QgABҲVGdݝ~8?d>>V=m?p?P??>^1#uV>a>¢%?5t?Zϟ>g?yǑ?R@=>kb? iJyps>qſD >K*?2>CCLwAXнmj?>pX>JDo>Ǿ>4XFf=%?TJ\˽Yn=pPXI?՟ RL">jVL?[Z>qj4?|l?bS=վ y>k(I|迭Z?D >^? ľn6P?^ bn>y? 3>u(?z~> -?D2՟?P)8*=OvP>5v̿=ȘFAj=|k? b=?>_>lQ?I]\???W?%?@a=_>TU?.^{Ts¿7a>מ@% >?e?hk?rw?E{Q>R@?. >> 󿨤d? X=ıo ?-B#> i?f>G??h>M:*?Hj?;=>JT@s}?2޾֡Xq? lG?Py?2 i(==GL/?K.h?濵w,?*>A??KMS&>F%&?[?? rL^Nkw?m?.,b>F;iМ =H1?yq?zJw|I">>?ԾSb?5E>榄հi|/e%WkM}<?">VB?(s13rp?= ?Q>F?1;%¿Mh< `%j>>2Y6k?V|?S>T>𯅾6(LA忻?9`%ҿ.=c?0?C? @?9dR ?It>kj: = v>OI _>Ih=4p y-vr_ʾ𮾪z?c>辍?rh־ZA?!(>} [@˯̋ ~j>6HU'k>gR?_A=?[<2_ƾ%x? z>c\S"8- ̀o|i??P`ZbE҇?t2?l;Փ?#ᆾ~>< A˿3:<q`??No!>ֻm=K>$S!]A<ۿn>`?& ?>.%Q8??N>Pxh D?nE&j=>>ٚ⿑?B>겿Tp?GP>WN>I?0?j?~? bMg>\j#9Ⱦ晽>n);W>R >|x>T? ΄o?bg>Ņ? >T< Z>ņ<>słb>*J>E*??:n?"?aL ?оbL?IJ?>?*t90l>c>LX>͐?YI>bທEr?kBL~;䀿vR(*:?/8]+A={Ⱦ]Pe,3;O志{?!C.><=peF?5F>Dr>1>7r['??/DbY% 1#>p=ճ*?i.>.Iҿ ,.^=XJ9>?ZP>?rV?3!?? ?ޖD> ?>P>-.Ha?W>䨙5>?E?e8`x|Y^nJn@o>=VFHӼ"?j?i>?'$>D?=z??)>!?"b>/< 4pߋid? ƒQ:H;>pm\=l,?=" >:?^UD?B#+?V>9o`?H<1H{ĝ>Ch?4؋=(8׌q@n謹 ;l>W>5@n+|?}>E">T(Ug!X?B?Qo? 3?FՒ?L]??8(X>otj@[#Lr<[}>~>7k̿>\.?;$>Y[h>a/+>{i>6*?E?CX;}`=>6>a?.=N>?V?4EHJ> y?~?2Bn@&Q徊D>[x>y?=ĺ>Ue >Z^~Ҵ?"t>H1=X> >.>z>8<>(>?(;?gd(CY?]?f^UTٿHl>X4$;;W#3Ew HԾ> ?(T^kT``=#鐽OA>3J?7{?> 3?2SS??RоŸ?$;)>䀿NT?eB? u> =RmhP ;8wZ?]MCd.>`̀>bN >'xǛܾ=<`=MV$J=y(>7Ă? FVX}!{$3H陿h(v@ ?D?! ?'>T<=Ƚ7=zPy?cp?>7L??jҿS?F>?!1lYUf}?S? #?IӼvH?YI ?)!NDz ?\?UU?IZ>ت=ΐ? "B8K@'NL'T>Z.jbW=azm(=҃>N0GĽgI}HVU>;pu>{]&L鿏ȿ%@%&J6?\[, ] ?"<0?i?>>=>I:@>ɼ| L2"[?s+4>^Y08?>+?1&>썽>mt>ptr?HV "g>]hi y>ڻ׾ [)>x.h˿V?K?D?+?(ǟl̓>ߚ?7 ?E>E֌ =>c#'8;,N<n>?o4?wf?7-$ :?=ؖ?y?G?h?a ?!LՓk?LZ>F>j>X ܿie%hz> k=?"=[?X5?1T ?f>g>ֿ?㿀6>p\P?-^#W5vh? J?l>8 z>=Lv>]S(>O>bj?#2=>*@#vо>H?5f$>8/ >T>ϿVT>=RD>>g?P&=C@?"H=NfP? ?GN]jȾ?fE>-?, Ӿ I>?>x>́>?-??S#>??ub??1k>>~s8>MW>}?_?> >1?Ilx=F"<>? @BSz?TWʿ^ZǼ\> >?92>ſoQ?Dx @NV?2ŁP7>xWz=oJ:?s>ߜKIN;p?!;)&B>bu>`3w@d>=舾*{{; )o? _>Š>X?#w7H=$݄?mп>wA3?_RkO>9P>x>D1/~o cͿFX >^4>Z7?,N?>?)lx࿄?>e-(!V>Eqh?;n>=R͛FDK>>Һ>JQ?Q>R>~پ1ʻ??4?O>->'C>ˇ>B?*?,D>4WE?zto?D?$?{R?]`>CD<>?$lvڴ>co! I>k`?X?@>X>h?~0>¿=e >#?> ?E/ >K(/{tl?:>-ؿ Mؾr,?H?>G?vB?h='8]0ۿ6>zmg k@>ͬ%>?N/8>zOFf' ҷÚǿ0>8@տq=>?q?"?(=/E>CTٿW?e=)@?>j?7=?g?kɿ=U7@? ]?ѽȿH`ֽQp>!W>JJH> ?Y?;>K>3|Խ6Ta+=J>SLP>>J??Cm;A=96?=ؐ>KL^m?>U?4?2?j6g??(9=l#>i>_:~]dJx>E?0‘_>P?J?t(ҿG>+ '#>VS8>B >s\Y?A/~?T??D:#C#⾟=Fb?A>XHxCܿ{o>Pl?GBq?&(?f >ݪS>,>:Qq >?b+<A0>*VQ>b#:?JPF̴av4<=_|>3w?wo?B~@D>`SRs>Rb?+8s>>J%N?Nf>깿WZ>^?to_>7 G>\?W?H?'?iƛ?=i:_?9>% ?㡿9y?K=M1p)y;>?At@?J>!eJ$L4 #|e.K?9?:b?v4>7?~?4>쾒D@=?g/? b ? .=2k0~=8[0?7){|>$@@ʿ2>Ө;x]"= 侒t,?Q;$`?>TN?K?Wb?*?As?#}z?UY*N۾pҪx??H¾ጽ*?k??=??c,6:J? Bb&N2>1*L{>AR~*C?*>?h?&?U^/gM\YcP>gȿeľCdP=q>?0y>_>^ 0lb s-? ƀ>>:r?> >.h|>p >Όܿg P:?p-Oޛ>5?IsR%?q?=?d??Oy? 9?4>2xbXξ8 喿JčPԢ?G>m?'l6p{ľ˅2?/?1Z??H?$"=`*%|>K@?7pzk <`? :|>>'=|k?þg$9r >X?A`>ڜl?P=H?{=?4:>}Zh?ɽ>t<ͦ oYٚu+>qȾu<Θs?~?uI">(=_J>b?tr⽞ 1$cA-0ABABjlBkTB`B{DB@ѽBNžLV3UBBB@8qBWBHC3^AB8_aA$BB9r@aumKmb^qBʫBM~B+qBƾAAmBG /2yO,,KTQ߉ԷBB>BpFF@$QcBe4B"MR'BDPAתB_08=BXrOfM9ه«•GBAs@(B3kM|~;]A|º6J-B͢L BeL@p†S1n#A m4Aq,yABOŒ7B<ԙ?P81oBˆqV“–P¹+A?qB W/0ɵ¹GP“|nB8Btt;"BL_AX·EAoAB1=v¢z*sŒȠB(*tshB¾oΫQ"F­aA~\A`>P2LJn@_S`QY\ª/ۡ!tcˆ11˜P/\BTB}B^CTeQrAJB*4:pBU`AF0BDמB> B%ABBAMBb`"zQBzBBB/Z#B+-fA~C#BRH3JkC)8 @U$B_&BrC C0Bd@CAӱAjBCBBGA>BraBBaBqAAFB="N-C:BHLA©WšQLxP9tI{ZtW!ÂPYˆx[I!,J­šVQEBCΞA›@HxE|*J±HˆF -~1›³'ГBjH#A QB28(x]¼6%y; T@tf!֢¡6c«(n3A$0B}BKBc)pAzJ*AHBC BqBdB|A"RAqDš7vBq_BHBjBܕB>B^BBHC\8BBCw'BBB|BBNp? A'AB82 ^BBbsA+ -1B|B$A|B˃C #BAܵ AF kA7rcBBFx?-PC BCNB8a*|A,B=<>Bp:B A|BA GABRB BdžAB(ASB#6‘7“Ă¾e -/¦?B+PHY‰W6Bi. †5A@-{Bզ$/XBB٩AeB BrBKBCBl„U-½%)CBY0RAcj)H,GѿNADS2H9AIo1n/²fr[^~^˜+‰VA'n jB_^-dBnU=B/OrB{JV€Q³7t ¢?1s8\ȅJM@.5mWBA >sデ@X BIBK!^$A.Ž!YE©J0”CvB.;*EB+BVB,WBvj¹za2{A0e¹nnB}bӶQZ|> <6?YB sB<6W)›XA @!PKc~,!‹ ”U¹04&{7¨5S pzּ̿»W4^ecB[’ BOL›~AKHŽTWAzk0 3AFB Bx[AxTBj@uTBpHA)BIm>>M@\e^AC~@5@+ظA, OA{AuBGvkBA1AB?ANBTB8NB_DCBP0BgsAA#6BX%@ kxAaBaB0l Bz[At ½՛B1)nF ?~ &|ºwGBJatA5g, ¡{&NwP?0=pBo,C K8BbB$Bd&AĝqžBCiB/ˆp r :—&!9WZ!xR?هzGFnT؇:†1¨PC=cT9”`<vw/-a ⬂”Ь.z´Ӭ0½l^#A5´Gdmh fB12BƘB BTBP7(/q;?R2)gR@?TӔXcPeq>̧T93<婀?E R?Qǽ >w?瞟?;*:?W׎Iȸ>od#t`S=7'=?J B$=miؾl >.27?<>p\f`Hξ?g8qjj?|>M5H f?>ȶw ҿ#<@AKh Ÿ>A=("ƿ+38uM0佻{2Dݿ09>+>>u >]5??9>ҿ_y>/L1ʗ?iмf@޿&<>/=>?2>%? 4>N3P4,%a>_?P 7?NǾּ`ꀿ21Ȉ>Deh0A?u??Oz>_R>ِ?a>*jо±?B?٘L>s?E濤|?>pÿ>+>z?}肿/T?XXf4\Kn,=)f@̽?1ԿL\:z>t*VBqq?i>[>> x>/}?9a8>r!~':\ռN>V+??I.sbo>>>?O߽<>elHB?6?h䨾% w۳b>?/ >LQ1uT=p⿪a?+C?+ھQk?y |X@!??d+YE>j?n?bN0v> |>=YrzL@׽3>SW= ) >?m Leƿݿ3`>$ƾǬ2B 8+>9ٿE\>ܿ j>qpMĞM Tz?sIe 425MTyG>>??e>??Q>׾aJ?I>c\xݿ˾/ン㿓3p??h,e??fX~WJB=@⾛?`޶q?ZP#? +Y8?T4p/9h GM:?]p=?!wZ=g@,#8?Odw?9T?z ?|FXs3 ` (>Jۮ>s>"8?>>o#-p?N>쇦=>.?(lK侖4F K?5տ%?>'>zk(L?>4-"%<@>_>w?}? d?kHPT=0j?޴6q*>1i?cY.?CJa\> ?3??NU>hz 8D0k̿^H? >^v=Á?Up࿵$>)A?{2σ?>$P?ʶ>(uy>+?A6I:?R-?<ό?U<`0ʾͲ>HĿX )0#Aг?Vpܿ`y>0J>|J?^F Ѿ|B? ]PȽp!`?= =#?oS0>bS.?M??)?rm"b E?=J?pkh?(VV|N>Ҿ#T?w9=j|Њ=À>ѐ[72?><`>88 ^%o =|5Y5>޾R%?U hO?S[>&>?(G.V>\%?UU?rp>xY=yf?Zc?G=Ka?/q>bJx2F ?$VF>>ٞ>">:$ O>?{)ξ=;fF>%P>p@Ȝ)ʾVz=t$(?s2a?D ^/ɽS =Ay ?? 6?cyHkn>*侣~Q30I2>~??|f"@U>0?-f>E?g>E>xH>7X&?=pr%?!N>=n?;>| Ì>߿fFQ=v(40 !\8gJx0(>J63lS?B`>(?ܓi=m|? nu>%hBʾFV?ۤ6>9$>? MɼP#@d>>`JX?k>2q?$v=<Oy?Ef0<18: `TNξ־y!,p??~.=aG?? =\?!X>m?6BQun=؄Mi?0-?>@%UT m>}>,|F?& n>9?¿75i?)SU>G>t>ݾ̱l^> 6?Zz#w>T>)?V]iw\<>*>/)?I?S7Y@?&?X>=c8YnQP?^o MǾX⾭肿vqſ ?`?̿K4>m1&? >,z>~?Xփ>h;Q|^T?8??Oް?m>f>v=?h|Z@?(4}z6l!Ѽ1B;&?aj?0=E&/?>?>ΝBB ?!,;>_K?٤>stS F?!tV>wNXv>nO{K>|?\55y>mI. =1}?>wǾ寿?i?=,?}0l?-?=̜1?h׿ʿt_t<Wd?H~ ?5KQ=?h>?7k>-D=,+?4[a?r?Bpܮ> 6>1>DԔ?;`~ټ>x>fa+_>+?c e0jgv??L@?0?G9?}_?dA?2{??@?r>M>ul>©d>=P,r?w{?g8Vd?zB?M⿣_:>f~Pu?6ʿ,SZ?LJ>~?A$&>>yWl2ҿM|z<ݳ`O^? ?(>^l9H.G?>z >P<񘿢x@#>E4M>>NhX>+d=$B|t)>qP3?0F<>̽м6lk˺>OeȾ p!?y?.c>ݻ=nsh>wfPy+Կ@?V>'f?W?&}>פt?7ΐ>ͷU>zL>>4G;>>zck¾WkRd>_iAZ>vF?W[tPj >C >_p4nk?r&`V-O>`6>t??*hx>C*>p 1:?uZK?`> jyܾj>H?2;>x,:.hr8/ 迤ʽt4? M?+oc ?QO|=p>?G?H>P=UE>9y Ğ>L2o?n4n6 U|?nd`>k?n>qh??>c6?bԿu%QFJ>U>??l><.?M3>nGW!>[ V*h=s@!/ ?n5W>ZzQ?>vl>&0E~f9?z;>q0c?C?4"bra?l2?R?'ֈ="2~dP[6?=%>;!=%i&[x_=((>ډ?`; %?(>q>$><=oP8@G`?,Q?T?%k?Rrd_f>]W>Ҙ>w}=ǻ?<0>~yz'Z=9x?("=6t>[H?l?F?w岾cTX>:CJ|Iem3>zwp`>?:U??%y?>`?zS8>+T !VAd/ɾ>ҖƿT_>3>M>>?>s(=@\fLF?lL4?{Da`>>Cwni?^Jϒ?pپ6-W>&T߿`?=X>Z|=r?{\>??@׬?c9>Gfn/ྜྷD>kؘ?&.= 4>u?E>?4?Sפ>Ev?|?<>?1fRڿI6/Ф>o;,>ew> >ᶽ-\?q>+(ޡ17>&>Ⱦ*5>wB?>ZH?pd?pH*_=pȿE UP>Pt +">=?P??^b>W"?rF?_^N>? B6}q@T>? ?(>fN>F@&?keg>LZgqdJ?U*?>z>8J=?P|授>R5Əw5܉^ g>>HP??,VTp Z?,\?s?O$??WνھK|>t?j;zy?%&=??L =^>>L?Ųb/È? ?~L࿲W&?A0Fgn>{ >*K?2?- >N@#qb=z?,住<>Se>dO=_0>?>[̾ ٕ>>h>H?:D|?O?$S>ܗk]JL>]w?O[>l9[3QD=?g- ?%? O"$ ?)0>KȿH@ĽL!SK=ĮDJ>O~TgJeN8?5>*jT"?z`>qV?#>8uپG<>붾l2?6>z>wu{Ν+ɿgf6>;瀿A(1?=ʭ>>.9=tPm?_>p> ;e=0YпJ.>9>>> >o!*> >IW>??8m=a>I顿p0?LW7=9? NH?CDO>'>-PƿY¿^>tsP=Ԫ6?A?MY>e?g<>%<>P?jw??P񸿀dm?+H~f?n?l` ?)=Cp?*??A0нy? ( =l`ߝ>@Z?)?̆ uܾv>\|:G>wb̿;s?3;];&N?^_>=H:6ݽA>(>aԿ@)}>3L9Pѿ?ݾd=`w?{ǥ>?:?<;>CgQ;$<<:8?&?3;*zzZɿ}P@~ =p>l)<>?2޿#5:>痒?6^?E?Cz> ?HP=T*T >jݥ)Ŏ?:vb?ӾT>|BƿIn>hyF7?5~?/>p>?x?[i{? ?^MH>*<ℿE?{l?z>Dƿ<?"?O%(Wнή>!>?PND'Wn aw>$>f?*俣;Ҫ>C̿c?H>i,>X?>u?~Yh> >#=\ľN ?Z>Ȟ? ?{8>SXr2@??z?4m c<= >K W>j=t?+?1?- C^>}s#6I?e0}>d`>!?ㄿ 4?Z>O? ߾Y0+fH-=빢?=>Le0tֿq?]\?dh= @?J^ >$x?%+d`@n wP=>Q?.6GоY(p̿Ws>B?3>|?h,? ?.<>???`?Ty?#f|?T6q?7 V N#rOR>_?/DVؾWE|> .?'!>~>z3f׈=X>> j>$>G>z8q?{m*F?^>>ݾ5>Syd`?Y=|L@ ʘ_?H1>0?I}?m%-(QR@Д?(|>?+h  9 s>,+>=ɂ?Ɉ%8>u]>Shd3?L#?2NG`, tV\p .?Z7@?ݛ`:?9?G8>YX?Lqƿ֘X>B>si? i?wJ?H=)Wh=>ھ&?]Bd8? /au=HZoV?6Z?~?b־'b>=Fp?uS??!~OJ7kG??Vf>8?ʎ B?T>M?x? ʿ6?a#>K> ??<>r:>>ȣ?fG?f7 ,P?>,?|˥?qաk}>hkVw?S|-Ȱ?}>}f?Z= Ľ> 7\ϾL쩿F?QUIXQ?">)ٗx>f_:X>=Ϫ?1?Akqw4>kP~?={>S>?*a A<@Tq?(?)D>(j쿕ҾS=E/|=eQX2>r0pw^\ξ. '?=G^Rھǿ b#g6yF゚h5f?*%6?O>ڋ>>кB? D jw?wC?e]djn)?+?>v*L2 ?u>>P6?K?">5:CO?vտ >\? mφ?? >0eBW!TоY5oWeA? ,"d@?=tI<8ػ?n4>*?y?=ˏͲ=yur?nU<͛p<?Lq$nOD'>C?KD?Y? ? ?~?3QDD>V^ JF?kT{>(v?BM6E}?I'c?UjyB%?̰Bt?@vB>iPB8BQBabBaA BBJAPnB E|8BrfA:*LB:?A`r0)#YBzšFCl[;{O4@PaBmB~}B9A dBB4$Bu:dBmAzB3BBB.jB|ƪB ‘5*¦DBؒ(f7C"AsB!Bq_CC1LBB :BM)7Btn[YkB:BBBAA}$ڠBAM??1k0AB74B(@BFL?ҫe^B1xBS߄AJ%FBKBM$9B>'@ZBYBbB+LBwB&ShAa(B=]NBQKB&gB%AFACKBbB=fB: C KB-i?rVB׼BUBBIcB C$eBwBBBBqBBPB?B?*B^C,CWCB̲BBYICBDB7B8 C%BCqAͨC+lBSAzCBPC!B Bw|CBBC'ABbBLBAC}]C3kC !CBC1BkB}xCXBZCBZBAxBiZCJC]IBEBBpBzB0B CB0B҄BCAAίAlB?A+B9B{AyCKBw#BFCA}oA]B1C 7NC,C8hoP T<C lBABl[NA 1C#B0|BFBBeBZB0B dlmBAB->1(AfB TBI?BBmNhj'AA0BzZ]BPBlBR"A73BdXBZB pRCD@%J;C"eBYWAqA!B'A = \?T“7, im±iA)pA[#hAT7w›9CAr BvY|ªAex{8Ah_^(˷a9tB%b˜KRAzc†IB1d BW7Bu?XAHB BOVZ=@B;Tn1(F m œiµ<'~މY_hA dv\C :qK_MgŒKV¡Q)B4EB,YPA¼N†AV*ƒ@"Bw:B=Bf]6-oZ™e*AAToB0BI_9.@BA?Y"7-T\tS Ƈœ˱WBi1B?A0¬²ϠIXa<µ32zB8ABLBBv[.A('5kA.BAgB(҈1zJKZ@*gjx$BtĿhQuC.BuKB {p ctB@&L$BBoPM*+P~?•8}d9[Bx{Bj B0dACxBL2K~ǘ{»{dA{x™A~6k+"º¨ljA` GQdB')XA!Bc[BBG:B AKBm&AUAVOpBם@{PT fA!²wA@J[BrK"AA@l[L`z62ArB0T$:BE"Ź2A°XauCSB BS$C% Bj$CB|zƒ^&AVUB϶/#!–wB.PfB|pVB:B@B A}{`פA2yÊ BgB9Gnµ{c Q(Q߯[psUsA*"@TTOk¾ Po`ZSŠ<$mM9¸yeBz[m@"|B+BAfB2|A\iBB{CP@ȃB &¿@çpVKVB_TBSAKAWt#A?56 ivAvAO„}>bA1B\4–+PBia(ABAͰInb, ZBCZ?\ AP$S¿Ʒ–Q *NnBO†«qŒMBU@L*:A*B90ĽA B C,\@va"A6`B{^AT4’k`ABD>B^'R@pB BIB$BOBA v’QmAB}6|jt@IPB=BABteA@`@>jBМ^fRB^DBAG`JA/N1Av#iAɃ…$…OP5!`10U)3žv0>=וa|9&C+,,,6z.†C—e‰ɑBڣ f42G‡@V73/gcaѸšOAjQs(KAǻ,,u*=:B&rgB6VRȊ0BR@=eo¥R`œª_B|O &Ac•i]A}%sBJA~B1kB BBB2B hBpѓ\ BJAKBBoC5#B>B[oPB6Bq~h!A7 amRuMˆˇ&<6>E>,=̺C?o>p?o1-=?٫?W]マ U?;n?IX= >:'?1P*ECŽC>m6?n?z =Ե~ҽP?7&QG~#1? ^>Ž ='ؿ/j70L>΍.?lC;@?'<$0Ahɾ`?4C?b>j|Q>?1F&\?c(p>.N3XYH ?,#?j>Ȏ:r6>>U>ѣ¿Z9^>>? ??X>m˽ay>aRv !ſa;?Vx쿆?h=L8.C>?gh?nlan?A >"Gl@>TG˅*D @? ݿ#?k?_3Hн̾>>[A?D_=4[.>W?j1>1?>:Ӛ?]>Č>>I9ӿM]#>1 >\*>0T>{7keM?uʿ~C,>G%;>El\*?"V?3Mw?/j ?CWCn?6 >S>R?:=/E?ieRx}yǵ=B 2.bD?C0޶~`u闿G+:`>?!> ?v+* m?L=A4`>V=p?؉t\=t?G"?>eѦ2?? H3h> M -\?4'A?3@?8kn'>>`7L>=nq?|B>C>ew>\s>>>hF>mn"kX?(> F=> 3AW2`X?O?Ce*?1?K>EJ>5e*HX*c?=s"A>a.?UͿ\տ?VD>k"zN,T>xо%X?AK:>:֞ >hϛ>KgO"B\r @?a?>L˻s$T?XR?nP<>%Am>8AR? >` ??Kb*?]0>$? k˿Lf.kت9O`ob?zQ?+L?[m?j6?3k->dH?O>IJ>ѿ.p#?R?ZN?U >pLJITX>ҼD8=lN>X uȿg ==>"҆>ۏ>mv>N׾/g ꆾ>j? ڽ,?<Կ:?l^nV>?73>|=um+=P?0m>n.>p>>>?E:=Xt?.l<&о>g 0O>4 #x?\>G0?=r=Gmq?r>t?V>'xUQߐ 8p?X俀]Yvr%>=IR4?Cܿ?D6?":\>jt?` ?3?xqr(ྗkd`ʾ <kE?6WKѿI?G>c! ?2Y|,? [Rhbkǿ' 5>Ȳ?B=YIO_ >:2?jLBl|ܜn\>.?RJ(>dOپRƿ4?& {v?m,bq?[7>()MK? 1><=H>^?Z?ƖT?V1>mUu\?yz>WĿCտ@K>J>ER??ě[(FK>$ -&?$S>{6T7> <=\?x~P4?x?e=Хp?۷>,nF>+[?@V=8x B&>C[?XQ??T>SX<?FD긽13.>ƶ=;80K\*Z?Pȩ>ӣ7˽Fl?H&?>`W_pԈ?Xo?w[:b}>N\玿!u=EOua>SnDN0?/ ?x?oT?:fH<Uf? %B1&pKF: ?O-MO?q !@6?3T@ ^>T??I=? ?ؿN$>ܿM^>½ٸBgw=t>X.>)l?y^>E>J$+>D?&>0J-Q??m=z`%(9>ͥ^( ##18a>Ѿ#s쿪E> ?Sj? ?=,W??̏Ye[>ɾJپ&>-ֿu5?HwPn羣?%t(M>Fo>by?UI6\>hgҾ|0??ǽ|?&z?(> >Tc ?3&<_ܿ/,>uKȿ,=?8t?@`;?ֿ)>T1`P>޲=6 @KbMUbQ뜾?jq9*FTn]>k~>8r?8op񬾀t>y)|M>2Wl@>:?i?jt>>-Rb>\>h?RK>E2?n:?9F &>}FLV;>>~?W? K$4%:О>yn,?e*>#+Dd">sfڦLXH>&>_zp翱 v=,[>Pm?H+>tž7_=M0?d?S3'?E'@=2?>IP?~Iu̾#=?o?(vwʿJ>\(b>i?bGܦ=QmΘ=ޡ(p>G>(P>V[!ĿrR>RSv㫿z>h?=o$j>n? O6?1?Tڿ1ܿ^> > )>7a?Pl>hS W>y;O@l`[E?j? F>:r4b>?>s5(>spv`>`>? >סC;н?Y'?aa)>D͚>ѿ1*?pZA?LT { =1$T>C$E?R?qt_ >S>\=}`?|?&WJC?g|lw\=> nn?TG(Y?h >>D>X@?/y?L=řC[l>Ъ?m1V=?k2?=%h>9]>P?9>kWq=<?>X >C6B>YH>n*?F\93ֽ`?/?/ cz(|Ŀ a>ux=9? DD׹?Bu?y>H^>4˜>eA>[vOsKC7^er>3>b4T8>=WԀ?3=,>rr~ٿky=> Q !#/.?,*r=PP>#?}?y>E?_>"]kn>0?2V?pL?G?,{?ON<>=I??) >Q羶XNʄ<6%?D?|^?*U?Q>@?5Q>->x⢢*վ>S^>6I\? ?3>ٙ ,(.?&?zӿx R_>^J>S-? -pC?X"8?'H=w߿_U; >?2 ?r> b? $C>$?ɾ>b^>c>ЈF <nj?+a?qh?L?)uj&n3i<5?<>?eW(fe4EX#,?c?[>? =KnڿE"!>>7?9Xc=XL>""]O>=d?B\b?M?b!?t>@潸 F?*V64>uƽ=Vjt匿 P@t&Ҿ\N6͸>Ⱦ??h.?x?R?W]վc=HX?.-U?O>?X?0Nx?C-8>>H_.pf1־9C?y~W?du<5X<%ؿѾE]N?>}>Α>(>Jy>?Hl0">?]1>wv??yx>_$n??D@>f?_Uʾھ0`~??}?>˿d?HEDC ^4P>c>">8@?c>"9?:?:$v\?[?ȣ<@3>{b'>7dهXObE=VuH >(>픿ȿZYſ19U">ML?L??_ҽ?0>? ?.?F,?G?g04nZ>>?& ;=Z>IР> ?sվ$؀V>>E?>l5?:}2;q?:ٿ>q#?gLL?o?#-G +>X/Z?>t>t?P޿鶼??iQ?.??-^=ʜ>?K?CT?D?~>Lr,>|'z?|?q .8?=~P#?>Lp28jν>\ 6>?<@AJ9??h?=h*m>}VD>}?*?QA>=?l7Iܼ>e<5^>4>ϣ*?sal"∽%>iz>c>J=,Z=t# $D辕?AC ɚ>cf>ێph=aD<;+?r? ž ?o>#o% Gٝ?Hw.>XپP?H?`g$> th&ξםrUP%6dD>3?rf7T?x??u?k>E?3U? ?^L\4[ [,ҿ_?Rw>lp?-?p? ?UfX@?X?9?!C>#4P>B,Ѿ>F9?2?7>ˈ ?,?'?g$V7|>(R\HX>e?'Cc?:ɼ?꾒>>9+H>)8 >5>ta7?g?x->X<[`@?B?Oo> ??J=M8a>4&}XW&?|%?5x&½ ޿$%tpN=R?.;?%nžD\ԽP@?<>Y8? 8?rb?<@>,e=">o >?n0?\7>ŵ?a\Kެ?"0+#?'(yT>{=?Dꤿ} >1?xA0U\>ɭ/{?X?>?M=?7SL>K>R>VE=#2K\>]࿃?z9`=?F|>sȸt>>ʾ(5>[οdMX7;F)?5;={ =J>ω-?B(+-0>{ ?j? T2%>wp>=UJܾʸQT!#D>"hF<п;>tv4-(=q`^?e‿~=P A?Kw>%>Z=Zi̾tᔾm>F>x>$LHb>[3e?<&}пm>?>ҿRc??Kh?m>?ӿhӾ(? ?XUΜ>.w>|">!?>u?]A.(>込?^ܿ0LL?/>P?PbQ'?Di?v>?U>½%Z@/ھUg?I">a@?=@)>KHDR}>`,dX>Zϐg>ql-R@4?:\>zQ>?>?Q??r?-tN?H?xhf^úx$x\?q?lu?̇_? M?U:>n- ?:e˾Rc&>?} VKu7!HI>>? 濪7D>2ý?/?v>;S5Z>пY 0>>= @?D>l @?L?k?[?>t>v>?A>;^>?2DT.?~0}ؾ_>~fBuF>?)F?(\=:a޿^?Le]?>A?7/n6缒3H=fB="?FGÌg必p>2O?U?RlҾ@%?>?rf>=ʿД>"?_>s< d>D>Jf?. 2ȿ *B<.%i_Կd f]?&>일ޒ69ź=>g^=oZ$?>~}vQPb@>?G=uiq?@a>}>~??X@4bHۭ< :ryCme?>k=r:?6I?=y?V쿹DD ֎>)d?\?5>% _>̘N%?@?D@&Y`?h¿x*>Paܿ&>^2(??V?56??ܿv?<|?$ ?0? f7>:?Ԅn>?T=?濚.ڽ G,64R>,?? ?5fSۿ>u8j_>';NӿlvX?֡?.?竾u|̾)׿C9 νh.6 >U?@gqQ?=U>ľςu?3 пšldD8п?J5;?0R>8C?zԾ > &_5i"?0?I7_x>k>Ϧ?M >%j<$>1>aˌ?0{tQ?2)?4?K?i=쁈JY0??^pbZcg?w*??gcʿb{|?@~>~e8A'-BM,AR @HmuAgnO 9*`ۮ¥~9¹¤b>@ªI. >(ZN3¢yB1dApbH1L x5½z²//+`+¿2s €2«y·*by2=b2 M/jI7RBs_6h*&re8vT%A: /?é@AQ I#@W(K,Icpzl@BczB BG^B7ߍA@r@c@]A("4A AT’x`BJ º%YW4j&B>j`d˜>Ғ2#BֺŲ]A T ¬X h-Vh£y1<@+sAb·¥3p³uigž_$Ÿ ?5f}]B|!)~»_v‰C4c3׽VPB/pBdHkYN"7.@BoBB&B;VB Q=(@ Bk-ҔB@0fB$3Bx9AЛB B:&1BŠqABbjnB=t`A(¸x@xf¿fBN0A"B8xB@B$*¢^( ߛ 5¶٥¯v 0!–f"AAC0R@x;@s3wA,BPBBI@Do®AiƴeF-Q@&,£X bW|5O*>u[?${Z Bm?BA&Pn0(WAyC2BB4~OG!4ӱ@օŒDcB׳/@ByӬB/B"[ kLAk9XB*A^B;]|œFKRP #OıA$Bs:J"6Z6 PA] 2qG@O=p9Bo@/C B>yRAA> BBZB(b9BZ­,B2<¹—1x(b߱TA`"vx0¼kzzqEB@:ABL:F@qBdBq BJlBzB/~BoۮJ=mbBaC#+!BvBz0^Yˆ?j«R}s T ~‰٦AS/d4@d] pBqRA–M)AYACBB>Bf B%B=>Р 6%A{BlBPByTBc‘s?IB6NB4}RdBB]B'˥BY7ҿn"A3B2[@|kBnYPԆBB#ˑAFA@AtCBhAC%zCbCYKCBքDCBCZCCBED;BAbBA+1B^}UѾ°ADYAaAu9@xh=8BpB>tABA\\NB)uB=ȽNCcAj#A"@…q\]A" ­ ܠpBBί=C^A B£hB¥'ABBjuBCQA6\¸9j[·%+\;"w¶՟B(k,B"AA5*{*ZAy\Av>]B>B,BB>B/BXlC A $X¢tWC <[@PB++2Q2*B Bԁ!3 +Xoi' Rµ(¶D.3f`6B$ŮB`n:B jAJ R+24BuB*?JœŸu -AAH2GV^@ɸBA5…RYvuAB,cbQ{³P0e`µbºYL*@‹A^4´'(Bn>x$bEKaS…+ ƒ$…V[P€lb !B.A-ÿA=< *u4U H@,b. · 2?{„tB4 |¹BA9qѾA@lB1BnO}NoA0]WK±<€1ۡR?gV<ƒt{?†*>XXnƒA A9 J9”|„8dB BBi˧Bh;B02A̓Bg:B^P Bef:hP>`BC]B]CBG@BB/,A$=[ Ag9uB4zBrBFB*;2A^BB ]PB qAB4psg\D‡PK•OףsAҾfze/0ųWA%.B|C4Ap?o@ ABDATa7Brߔ P0dAQG>@OlsM!|!¡_y6loB+ʟ'BVA3A-¡g@p.Y AAABASA2 DAY•E9<S>HᇬAwޛcA(Br-`€awnB^KB?B5j"B8BsA.w?ƵA#OOb1<$?BN]{zAA2A>(B:BB7BkBGSA^D=8^(»}lBAgMd@{Bs,BA4zUN*5*3fD.B$?ƍ-;A"BonH@dB߳BAEApoBlp_B2 B[B B@J @r3B(48lAolA<@?]K>r^Z;ȣ{Oa"> >mx6?l??>)>>̿a 6~>z?7?i=B;>@z ? ?O0>0Ng=}?;& ɘοV?>X_8#>I?r>R?":?g?Ŀ*B5?W:ɬ=j?ϿnD٧+Jb|?mKT俎x>Y?E>>7]>3=|4<ؾVI>⠾ >S?ru~Do?=ӿ㴽 DrS}L?@<xmtLB?VA?uH=.ؿ&b4>SL>kԾu.?>z?OD8?l>v?(7}>V6d?Mz:?!>H??>s>+?O>Cq1sAſ Aþ|>JN?M׾Ϳvɒ?8/>Ұ?6d?&*=ؿ߄P>E뭻k;:6=jȿL>>E?Xvܿ98N?;>#>l?x! R>!?]\>X0j%;@>=>d>Cxٿ%1A;I ?H>L ?U(?xYJ%G?;d;%>1ս%[>D> *W?տBcʿHkSRX?c>`Jb8T=x?4?+>?Sv?L@? *i>@>Ρ?>߾㕿$:-0*X?8?{2nKj>?\B>C=S2>)M>㻿 uaol?yoܹFU?e>I]?Uie?$>O@? 辴?<>ر?.q>C >k?9y<>3ب?KaRҿ?Z^%?J/3&?%? ]j?? N~>D>X6`*>gTZ??@>F>ӌ:?"??P>I>G>+ľNLz?>;Q]>bC?@?qb--?)>?Sy?z7*90?L$?ϖ?P>;?KK>+1]S}G997ov$>Oi1=?]>?~9>־Z #>6׾^%?gSnыL?? >Q>BR[= E%DrM?i#?l??v4A.?-"MY? wq⣾X=?/?9h?Mt6?\ &K?|?>>>>FRm?>F?>\<5ip?>=gLk]>y~ƾ=~9gᅢ pV OB>n @ؿ0h?B>{t??]0?[?5@ +1|?2?-ܾAһ >?>p|>lg~Խ%,ɕ˾>aҽ*2 H><쿗Z>nMTk%\=<8?*?>(=L(U?cϿ6??g~k?)qh?N>c7?4c-./lN*?HK<>4?]5M>?q=S }|Oؾ>#/>UNK6?þ$>ٽZ?jNq#þ ߿JCT>n?$?>ͿSd ?EP=^G ?Ix>nI#?o_2=?@>L=^? ?-?v->i\>G;>s#^|\߿l4:c?0>/ZZwĽ#$/)?;rI?>h!2>.>ɋ>?n?t;j=%Ӳp?ue>^bwс?UO"= > >VQ>RG?&?G?t6? @>\>@i'><lhl??I%>8?4?0?~3!>^?J4ʽd A`?2N?]>~=14=i?h?KvW3$}?/?j~Jzݶ UL?,?*eD>:>S>g=;?Ihؾk!`п{v`>y?('b=1*J!.mkȿzsA܍>4Ҿ:W>[?5.~y=Yɾ*=Z21B:s|x?>|4uT >@B?Q`?:6?v}=.E=*">abl=w=6?5 V0޾G?"?rAYW#x$?>e|>SpB =5[P',M#> 9ľHvS>Dj>T?@p?:_A?"M>-OvZ=Zg?O??8?䖿3i(?[?EPſ4.>2~ZNܿN,}1y #>>?;p?(x4.D?L֠A5RM Pq+>/?V^)W?60,?1?}?u!?Ջ?%0 b?E>Nv_[l@WH >8??;Rv=ϫ{>LDLT>;=ȑο>ĊؿAWI[rhx>_Q>#>"h?/W?F@;M>۫&?GC>m(@>f>b.?Ⱦ[T&??oj>D?>׿s>$+`st??jv@=0?煿E˾]H>MH?þރ ? ?Y;?0y<k%g`>ci?SX?KG> ?? kfȾ_?7uC2c?/'cX^@[??;d6? v[?K% Z64E?5E >?q?E>(>\G?=9ayQ>LUTb?)wSn:2m? N>?qi?$?J5ھD>?V>W>Ouqt6B>s>d>NTpb0q<>~G(0>)? K9>RiA<= ? g?? ƿP?X;??o>[>Bϗt>?ghOpE>*oj҄ )?X==d? >Tа]>;ZI, ξwWH ~=7?>(?0?(O>ǽ3NwR(>K!?A?w!B>*Y?i;?u h?)=Ĵ>Ѷ8}:>zpM/5>mZP>cr>wtXJ=Fb>`L >YK?xv>^?Bu?d>jlpwŶ$P>Gܿ'?=s\`5>4?y?9t?=Z>^"/>x/~rlqCHU>N >AF$==<>>?W>߿Y{? _DV?4q?-b?]E><>#@=ճ ?ۭ־ugHK# LdK\B>>Q侀!l ??R?za==>y='?L>Wl,q2?\Կ7?|o>?K>v ?? ?1?9`x>2 ==??k?s?H?n? 0?Q?4T俦mtC4`kc<2低ֿtu=ؿ%w?P ??=~H?,>D퀿I ??l>U>>-z?@?+ʌ|FؾqȾ|[> 峊ؙ,=K?3ܙ?lv?3G?X:A G~o% dN>$RҶt>Z>f06~tt?ʀ?:?w? vK"X>L?ѥ>rh?T>E6m<>rEd>صƿ<^2]S'_=?uT=1D<P >y?Q??'>α=R>?z><@?7X >>p >s?=Vx?t7>$(>no{X?"=?gq,=Pf>4濸?)?EO?=?D7~?|d4>̀?>6);=IvY>Xqt>6?>/(cq>>w)`?L;O7>ǿmZ3a?mL+?r۳>?\=Z;v>d_>h>ot>K0)t%?&^?D>*r{P=L_>0??{ج?ע?I'į@$3?#ҿ&5=Id=K4kA0пU&B>2$Z;B?G~G>O`8>=?p?zw>^޿{>~H?8eݿ>XW ??/U??}[~=l>V8œvv\?>}ZB=5L;W)>>ԅ?a@ g?k^?:?<= K*%) ?Bb?tHcF?H&lཐB[> ?c2ȾV>|. ۾;=f=p e4=DD>>|6sĽP1EP 2 ~^hUܾ:8־2?B7o= yFʎ7?>?,kz?7]g`5,xԚ?:vT=(?0L~x>#~>Vሿ?Y+͐??}?>Y.>2ߎƿlٽ?XQi>Y>rz $? >NDk_>nGD=?څ>>7P1\E0?\Ƚi6?+M? VvDEV>ϿD>fC;QΤ>C;>s=>&N=?6c>p}c?e>stR?}r>3Rԁ>D>Í>UzcD?a0? -?[>Uv>Kְ>4GtL?;vܿHs'e:>ϰztlHؾ?-c>>۾>Rsп>_?%Ⱦۡ?7&?:U??*1ӿ4x>#??r?QO?^?X5t==>y""j> p>G Ŀc="ޜ8>&x>O =$> п h>V=dB> Y>k0L>G>IEf?:/_?Oh?0N !>#>jjC?sݓ>\Pp快?Q„ =>ޕ?(?s%>=?I??3f{^$<T` y{ɿ4FC;> UҾI>gd>E?t{>kV\rpi?R?[)x?hw?i?vn>0>K?a,]_Ⱦ8?k>=a0b5b??A/hV]F r>?:>V>X'>F>xł? lu?b<Ҭ^,>p&?_*L>0??))s>{?A#$>32N=]?=1>Գ (0?,$=c>>8=¿꿇sq?%D>=?&?N,$7 7? 16?%\?&G[?rf6?)?g>ٿ =ꍾ4? Fg群lv>RN$пZd\>j==YX?EYԼ'?}??e?5M}~.8>4?H"=v?Hi|󿯲>е>ʿ=d=Pp |JM?x(?$vV mȿjuy?=Mf>b5;pb>NO }i??(>Uz:?uo*P>{F??y>= D>>^G>hJ=p@f?`(l??=}}֔?{xTj̉zF|:>RxL>E?{S1?M?~ B0?Wƿ%uZ?+.?DT"ZD.>X>'zw`?Aŏ7j>7<{R L%LrNA>)=t< q??,=φ?(Lux=Ts? 5?w>o?*Vb]23/="E\־Q>Y?QL?G?{`>0 P|?Y? pYN!?hx>m~ >tx> NW? -$>>S*?Mf?r#ʽ ot?pC?R?!n -G>? 5.&H?(H>t,,^\qR? Q?>jr?Ǻ?6N>ܰ?+=v*?'E?LV8Lb|5`hU>r>e7=_k?>辐ܲ>4z9 ?c?scJ.׾P?h巿=|tR'%ʣ>\35`>v6>BR=>;< >c ?B?l>E]Pm>ĿNy>p-[_5e?=xPj>9JaozپKlۑIs.̿ξ,C&?N*Klm>} ?#J??=xM =?/<<@ _?Qb@ @.h>T"䮿ǒ)ҿZv?$?,z>h>-2M>T[y?B>*m$W>?a?ħR"?V^>Y5>?ݫ? ?bW>Z.]/o6>A>n$>l>DT8\c? O>*/Mo>?| }Gҽ߹V,>zdsT__?=k|/?1?h>9@? Ҿo? {>?N *?E?VM>?@Р1$Pg>>>R?l?GC"d?`b?P>g $?:!=N>p>\>9ڿ>4?f?5=%p=>g?+?e(?}ĿdygHBMDW>I9C2H{ox=+>>;oFo&FRAn<*㞙\Ʒ¯PŽh8µ_ дB tz> _KA6A :B>#}9!'s/B$ž$:oɁBIA]A܏.BEͺ hA."AA4BACB`V|aAgAAчo36zm֐7BNk¥A&:f@ $*nCB$ xBb @t‰Ŏ0Pd@f‰A)FxBe4+ f'BD>,C}7k),YA zFN+x®Lmj~^¦SӶB.A!r‘{«|‰F",ŠAB.: ҟHB@R”Jh¶ . ƒ(;‡uF ,P׽b¨gC-XBC>|&C pBBƴB'FBC!cB A"uC CC C$6BBB 5 BBDB&XBޯBBBBUBm)B3nBl@B¬A@CB"BRBbBj.BB^BA/CBvCiTC}BsZBB,|"B A淭BbuBYBB]BB¢A­/hն#ypT?,x?xQBB{`ӆ\m/'O4cAiA䅾^y?B{H㎊rvA-wٰAׇ@ԩH:BU zAօ[Z·Na_QB"SFHs.Iˆc.$x c/=F4€YC w-cWA¥{A_’Q"~|A CAʉCijA"ˆD]APpB-’3Q,‡i<.AF@!b´[BB΀2ę%?> ±.dE¸Aw9)@WJ‘HB ,B![+BDP5"BGB@f&ApZ?b? A]G54A,@ugC}B1BA<(А9C!&B9C_BtB A8AشӊYB(KnB{BA|Aɝ%B@oB0E4A$)+4S„#@o@[AOBBT_HiAYABV2gw—A=ŸdP@Rh™8 `@B ְ=A_AHg/BZT톤BE'BC,]CO$B߱2B0BB_~@#BA60B,Bj.B3–qA]4eBrB BypBo<uA Aq?Bn0B:B%ApABDiBCjBa~C2CpB_gC6@4BN@jBDB!eC8C,)PBnBBBPB'A۷8BPBc5BsBB}3UC /BsBBFCvB#2BHmCC5iXCUC ]OBP!)Ch#B_BC4BBzJBFrC@n:BlBC>BtCKC.C5 CCC'C>B$nC,CV*C8fCUC9PCYC o4C>\CRBAMšRB)AtBC2_ABEB2”2HjNBB@d@`BoBkBFEhAB(BBʰt$BBJ$BʗBc BpA?BH%¡wLPB$7y2@0B,B*BFAcBHB$B=C_#C C?B9B:B4BGCCCgQCLCvCICf1CT6C\giCICC/ @sCBi` ?)$\?<>N@@Wj>1ٽ$p?:~qj?Z8,1!?մ>>6?M?d{c 7?v??*FӽAd>[!Lx>++dt>2opfA< ?ʕr=jL{3oCs>&RϤ=i;[>$>k?7|>=f>Hd0v>J=Ⱦ>`Z=R'F?C?O=??I>C=!;{VL=?!۳>#ʎEj!?vԾ.=@>㏿ $US?<xEh_3Sľ$]?ڿVk?kP_Iֿ? &d&:>Mi'ZrZK4""hϺR4Bp?=| ¾?ļ\qDp>Zп?@վl?F>c˛Nzz=qX?DY5 ??3 {p?*lϾәb?ƴ= CI>s'HE&<] ޲gb.?q OiPyK?Pf^32??y?8dd=P&?O1½u$>tH<=?)?O4>~=yi\xػ>n@~nkR? Lľ>F? F??R?F>ŏ-?=hk>Z']ְ>KBr?nj?^ ?w>= ?۠=d>$?nI?Sw?ȿ#H;?N>2~>Y־I[>d >4==8?VuҾc?i>0ؿ:ʻdg6= ^N?~hSJ>5;ܾeT?->݃^P??SǗQ=gkY6></ ߉>r?f8? j:3\np=51%T>c½D>>ʽpV@`+z>\>Mi=Dj?Sf>|ྗ%ÿA`P>.-+>3[?[O>jh[&>??^\>O>00`?G/2?|?ؿ^?3?ig=9R f?G J\?/?ܵ=I>:>q??Hӿ}|>xP> <^s࿞?O >a?[>?-LA=/Vҿ1W?S>YGؾ h[+;6.`>fPT?=A8>>w(?>>ծZ> p?G=p>2>ޣ?ofi>;X> ¾?Y~?>HP?w޾׸]b>OP?K$,?9pE<]~X?R1Jv>'0m>[Ґ:'?;=ހ?̾GF>?5!?p?Q?D%v?P=˦/? .0?/C5ֿbAPW=QG>OI>n%.=:={>le+?GNȉ1?>{Ge?ld X|>JC>uJ?xZ`=yiM&d ?>?c?`k<1pڿ:D<8>̾&oL@Ɔ?徤7?? >? D%09P?OP]`>OȾ4S>Ԍ?x6 >`~-@@?>}"i>֜R>>F> R?R^>=:~?^?}?>?@'?/=I????v+o>>?L>={Q/=>_p¾:>SҾ9Ѽ2>d?#j?F(> W:1ӬE x>R?A?B⾌e3?#g?^Ϳ*,?JHߘ9gU쯾/9"ur/eؾ.f>.&m=ߨ>(T?%WleBcͽ/? *#== i+,`5p >@>j>u?HN ?K>1-ѿD>>d}? o?ſ?,>na4ouh??!(>8?On>!&?>O>#>j`'m>c>?#0(t?d?f'U+>J=Ӷ>q?v#?V@\?r"<WC>>A>10?y7p>V?x F2<>ZXj4>AD{ߥ_:<2<0?Ƹ=ʭC?>/j>F:>(?#cAn6?RŬI=ȾhE?>؋9%_>iοk`Sp>/?]?w>??x>'޿\%E>xdMaH >5Ao߿1>r>Q>I>}x<_>7>I!=H2N(澍&>@?T?r?&J > ?>tBGe= ƛn>G0>&o6?B>94 ^> 8nP>vNڿ>A;Aiq{n?Y>@)u_v?l5?S+Xz$>@f>*G-Y>T>f?Qh?b=؈? ?23?aK#HS.=%>l>{&>-Q=>/y. ?6 ֿs&? P8g> ڏ>p<|VJ T#?j7>ؚ?/}C<=H<=>In? {|F*>8>&? ?ldx>A F?n8ە>=h?wT)QH?%޾*㽊jƴ?=|Ӱ?3@>fyd>?[w7?Oњ>ԺI?_?A 9Xv=ծU?A/|?K0>>'?'->p?ZDh?>Y9h^`?=m@{?+֦? x&ѿožs;???->Q9r?ܸ=Z2-?{ʿ?N\ 4 >Ėྐྵ־>>?Ht?Gʿ_1>y>PB?>?? ?)KPp L>4Q?>y>zi?7X?I>J ?=`? cd?}::<>KD>,Ey?ɾ:L?;=J?/?ef>ǫ%?0x?߅?/?Ϥ?h2>iƽ`ܿ3?U_>$WȘbQפ>#>->Thҽ>:~@ ƛ?=?:cZ>l??A?4` /h>N(S0p,Th.yҿS='? [x?A-s?B>?'򿉔8>p˾3T?=R@>ld=N Q=xLX`>#x>/z$ó>M?]b>C?z>Q oľ*@Q?X>2+p~=K>3;I?@?uD> ?}C> ?DKpE? 1>o>kͿ->vp)s?YrX? W0jN>r ݼ?Rd?$⽂(=)>?J?A?k>== \50=eD>>ԑ=9?]>.{q$ `Psο* t־/4?Cjh?}R?2? >_q >`r4 ?>\Y?,69^Q(>I/ 4 ?^OG?$۽?5S>zfHm~?m ?h3>}1V>TW=-> ?VϾK?x>m+>?@@#R>WϿZSf t訽>dI?Dڿo?'p3*YL?Bݢ>T\"Cr>=|?:տ?xi;`>5^>~ߚ?IE\f?1ƾ*1>ݾ8?E#T?>??#]>!=?W=UH2>[1X>󻄾L?e>ǹ>1?*?\~?'?,8?P?O4F?_,->\? " ?2&?^j+u>Pm0qLZY+ =,?{2?re`>.&?y̿X@?wIԿ?|^{an4?·>>d>YZ+Ϳ8>#Ǻʽ.пCa?'C>2"k 1a>iZy)?i?Mr?&;k >BY>2?н>W6Ib&K:=0оgﲾRwhweDc4%6?#b>?D>a?eY d?L58u=j:?s?A׾=1 !j=f?kZ>L ?b`? j_?w ሾ.y=V?a>=N?¾ ы-<ڽ5Owsc?#>7&>ʆ>zHL㋿ u &?/;0 ? >!7>ZL1Ѿ@prGzXN6?7>}t>Uph彍`?H?@ξ2tu5?E=ɋv>d)4=M1Hu efΰ?2?M5ཡc>;R?]R???1H?P 9d>vNY?l*'</>=pרbDWjaw>b>K4{X>(n$=ISR^:Bn?˿q?w>=(>5?zgN?LJ>Ad,(`>CZ? k>8L G?iW8l=~)7&kռH½x?9#R?0m?q t_h$@?j?>t<@H`>b?Q@>Hz?">@?)cؾ¿hDO?Ϡ>?ۮCҿ3?KD???8=.sl?e?V?[>r O8?. pwЙ?>?0삹p`qZ=(>ܕz@ugľ=ܾP(>IfW>J>>T>pe>nڿ,쾿>w???y⿴>hb?bjJ|z?&wF?t޿rֿ9=ɵ ?-z8?c?"=h?z;(2Y?k$.Zཷu(>*<$5k ϭ?z>B4>& 𿪖/?v`Vh,ܿ=(??4/:E4g| X\X*b>3`b?TB$??-~?~b¿Æ>rL`P?~1JH?*վ=۴?r=e?;>?a1?ֿMe?@8>v>Jz?_ӱ>Ba?K?OR??ctjW@Tl>ZܿI<%?J'; =b砿5Mv?4] b??I??`-]bk?w[Zo?Y?FH>㦰?c|?td`>Z`=ׄ0 cOronR=`?B?Eb?NȽ?\>^4DC./3?c}bkv$? x,?n辀,J>>I>[X?#?Vl%<9`=d>LԽ н;u?WF>H >J=Co>h P?9(}NSExS?_5>=:?\'?P =ƶ> =R? ɔ#P>s?GA=ȳߦ?#ieO>k>Ӏ羭࿝㿹?|??\?R:ο6E*;?*>>3F?w??g1b?bm>,)4@Ml?*B=qh$`>>`=Hp`=YU/]h?d >v>pKX༗>GNM>O? ?t`v!ͽL>P+?hU?&=?Qjg=0D\G>a=wX?ͣ? /c=&=Vy?$gV? 鸾l߾߾o?k>!p?D|5?‚>==DO/Kwc>(n>˚|>W??D>p>?<!>D?-.?Ss?r1; nk?[L=A$>'?k?&eȿ~T=س=U\R>kq<Y?+X>"?G:>?U`>Tf>ψSU>PZ꾃?_ .?8xW׾3?>Ҿo⾂ȩZ>RɿG2?g??>|H?#Dh>7>:*?_[?? >?n$'?2\*ɾ?[EF>(.>zH?x? ?jx>Ϗ2ʿH.>|gG =Ŀ5?}iCI=>ѽ?qD̅=bu>#Z0@俕 A ^C>u?:|p?!:$׿6!/?{q?h>7f >ㄍAi׿<\>' 辊3=ܾT>?M>O>2 aHA u?<="ҾǕ=u].zd> F?F@D?6j%#d>`?B%%>@`c=Tbxr6{ ?߾3$?B5D>0Єg>>-?G?>Z>c'qpz< ?t>V=Yx>h>>N?w4?=fa?>J<!d>?=hԿ}֤0p>j?Zl'Džj' *&s~ŷ*(n0?+ܼ >|&?a``'?Dxr?;v,?GL+ξ=+>|?(?h ?>@ T@?=Ed?)+W?_IguFZE8<lRNվdY@=z?VͰJ?SQT '\?L?;X?O>gw%1\޿܌k|p={ ?QӚ <8@1)zN @<><P4?j짿߃:,aۿjG"?"/*?#c??#5C@iuR>AI>K?_ZR•;z fAUAǖB\BB @{s~:BB\B @AXBCBBBC BʞB˦BrepB(A͐PASAd&Y4?XBB9ZB@BwB 6:(=Bk ArNA8'C,B CeAwAAf¸کA-A<[OS@.@oMBFbBҀ6BAB5BOafBBBtBC֢@UofB "*C"2An/AB܄BB60B|{BlBϳhAVt<@s9LBF@kSB{[BIB}BԊB{BŽ@ANB.9Z„LN B3QN"E Bģ5BcYBtG}Bт~tPB2B/դ)lCBBBcCI.B밎AzAe Ag:BBV]?BF1@7lC1]PB".B֣BBP*BΑBBHXB_C?[|BBBLB C$.BEBb@RANBB'@BBBu B^!;B=BשA6sBdAAzYBC uB*BBytX|@wB ]ATYhBGnBBB3&B.Byp?B::B4FBHB C$AzB; AAΒoB׈B*B~BBU7AHB/B;B|BAKʣBB?BH|Ao2ž,B`&\ wt¦A,Bu u<kψBMu`A^.~u:°-6’R'°yCQjXW]{B}lAB@F?f(j@{XBH@E@:B,gBB)BB<*b=fC‘?q0²!}qnBApAQPbҾDπBRBB?&€h(AߘB3jՄA敍@/¿LB §Žµ@@B<+ A(A|u@ AV–BGxBB5¹\AB@!8fASAkV¯t'eo\¼ B B0~BE?Z2@ŞBR B0K=ZhQ¿qNv?‚A23C¹7‚tAdBBm"B{p ܊BIKX[s¯ssBe&vhŽA&=š ± V"Ą†¬pœ –DEAEX”A>gN]n›,lEA’[tˆP–u¾L EɚrA:4l@>|“šȆZ5p-3Tty!(+B+0#BnK v}Œ} B>C)B9AeC"BBBWBB&s!zl8A7B97BjBn\A .A?tBP =ABI$B|BbhBsB=VM@ Bs/B_B&rCA|CdB)3A&B"B$?̀§~F¼B1*Œ:BgB=Kn 6Ⱃ BvŸeƒ V1Y%(!*)gSASFBJAA-BlBAvD‘!z@@Aw7^$<%N}BBGgBUAgWBZNZ@یB AjAD†$BZY% pAW-¸.„²pBGBXBäA:ABŽAμpB LB5>IhAT2:ZBmy^AjBDٹB?"B?Bd‚EA€ @hAW<²:~A4‚VT #AB‰@* kLˆ]a{ :W.R̪@l¤2 A²1-T\VBrJ>-{BZA.BhB^BPT:¢Ab3´JŸ#ȜA ߆:{o[4#*¿ENtB BnAAgfEn*S濎AjG623A .@)!LŽG“>UugB]X7HlABœdNr`M0¶jĹ~V´iuMZB©r]AH ` _?):™›NeNz‡PUˆRB<>qB†ID 1JA*^GBko!fAN"‡AD[~@ru•?@h¸bl)ОAE-¾6I:YRBAY4 R(A!0G J5 VuA\Z (•w oB_&TB .@ڱʊBLrBit%C:x½bA{ԇ.A? QA7NBڴ`g[XfB B* BAn»A¾ݥ¡O!A nZӄŽF/L0L%S™'Ÿ Im­sO‡n*¾J¼.jYk@‘`8⻴פԮA(‘ oM@c>8¿q¼Œ dž³g´{pB@!BLJkB׵B02B7šc@x*Q P*1q­rSXe\I|ot¢/a1`~BVBc BJzkWA"GBB XBXBwdC4L!vBO:&C"BhBQ@[?LAmC X¡9޾B|~BX0Bf@9`A=A@ >BABdAhBfB|C>26?kpb0Ԏ+?eЎ"|?ݎs4e2"9h>5O?>J>y??(Q?=?+6?^>X37>s= }=0IB¿$?]J?gV>->?=ud?q\/ܾ*4>G>\Fr=?7>?-#ɸ? j>FA?>H>N1= Ya=*.^>ڡO`?07D??&3>&,zgh>|Ҿ ?#>goZ?`ξۗ>? ; =?46? ?b ۾t,?Gv;?=5h=Z>>U"N\ ?o->z 6zпԠ=^̿j@>t>(t?ݱn=h>Kþ=?3N2{P>-=H@9@$?:KPBտ;O>ZY?!I/>*?{.?S$T?q>z7zLČ,>*j?V >GwD??:x?@W5H>?B ?%X;w>oܿbG>Ú=&?oJ:=6?۔>S?/ʴ>-2>?e ]?l0?z=75>nR]4ҿ;B)sԼ>A>/=JrbҾ KZQ?^>>>1> z>?k]??"$>:=Sy o?! 2?#P8`ԃ6.>/ܿ6ZNq,E'[.]T@>}?` ?rN?==]m?¢נM>5<?RC(?vU.>B4`;Ȑ? * (<*@ľ ,࿰d$?6?e,?0>P&Sw侙r@ ?_>Yr?{x> ??'&L1aJ?=?_)?V0?L𐺽>(??di?V1?e=10?8Y?SƨOվ=> ?^?&J> ?W>6?O"콞27H??[ >>欄>$V,a-Rlk޿{?z09W(>.)@# Ț?®?X( >.pVV`=>s}&9%?">> >?j ?Zӿ-M?~ >S>?w?d>2>{w lS,dsX<`>t!$i_J?ty<Ɛ?o?{ݿ@F?Qٔy?8ψO=ʑξ#>6=S8'b?jC>Ա GVL?:Ǘ!Ͼ.R>}> Ohux>?k]!)}N.ܾ l{Լ}<=~8?j>??[Sb?-j)*wH8b>T`K<8wTD!<?rh?P ,>n>0?C7=>.? X;f?c?I>rhQY3'<>xZ2?>B?=hHW.;3RNOY??QO^L >Lo?!?nۘ?q\R?&9TܬǼ֛?>It?UN >I Z= =ځ>H;?G+#Z>z? (WL>?=C6>5o???)T=>?و?xiV?Wn)?s֞=;X?~S> rMI螘>5>뤼 @t>Gu=1>*?G/u>LT?8&>vG?T>d>~4O?8{d=c>X=~c>S?L@pSA?uxL; |??Y.>e?WBŽ;$u>>#>`L??D:=??Äc9?>?]>ln6?{?o3Rf>$=? :f@? ?2v?Xs?*@?wN|'M;,>b>S>>Ŭ?b&ߐ> >{J?r?o?!>ԞIaTKY^$|uݿjMl?q?P>\SȾ_Ԧ?P7`e>ǖ=á?>LqG֥?>K?pKx>.v?U ?ʿ1>p?]=D?iko|!?C2"V˙U=ρp>^DV>#U?#=߼ PyG<4Ā>՞qP?Uc?!Ҿ/T?mN?T>e(=}?t~?>=>،={ؿi?=:>RAd\?Rl?zҾ!?Ev>wG?(ҿ+Y?E*>we? KNc̿;>@vG>5??|x>?v0]S?6u>ע#>6.^b?hmP(2mFvO>9j|?? ?z;>Z?Z?⹿/]?Ó˿v?kQM?>>W?S6 H=c=zؿ*y>=3Z cB\+[,I.Ip=X>??:GY>[O͋#Uh>/=Gȿ>4a? ?n=zb@=w>B? B>&?E[?9SҿE?QF>[*oJRR>[>JQ ?*~}n=p=zSD*F'7@>?0>:?XT=>=龋0>5?O]_>(t“>Y=>p5>JrP+? ľc?i>k53?>I1?TR=KH>QV>;5Di&>٠?gC?']5?-=C? ?!\+>?>>?d-??>n19>I@>>}y>۬=&=n>>(?I?jʾ9Y濑% >+w`?MY+<?7 ;>1&?y9#?#Ŀ=",?.oR(=³'p>J?̾!? Sڥ8E9>ǯ?a吾@?N#m?(%??w򾙳:Î?[$P,>3g?]">* ?:Rv>nj!^?ik ?G?#]f>]3X`?J ? >S鑿D2?^>0=i?r'=`0ky>M4>=>{= ;6>?^B>g?N^??:o>`C<_;q=q ?Ό'ˢ}B*Fę9? ,-⮞="x['ʿڴd[>x*0ܿP?wh\$>e$]%=pI wf^`=FzT>%8?;4X/0>>ྞB.>/ />->C?6 ?fS6=h>S:?9)>rF>$ [pB <;ٞ?Wf?o4>GmR%?jiG>3ҊK=6hD>!)C*?&.?FK>2˾\~+?|uj>*B"=}>8&&>w>o>*쾧qY<8@>)翔!)bC>;о>B̯=/? 5:l=H@>7<N>d/ș0+쿙%@0.>n:>ꋠ?`?3?Sw9zS?>n%ծ>0U52>ʪ? >R`4= (@?>>]^A|>)ewǿ3DBB a>j3 H>)>t 5&TzľM]f=@=ݜH> ۾ׇ{虰>;)9??]<Űr;R϶3D`i>rf=?vesJ, BѺ6~?"?呇_n55Qƚ?>k)>PAGȿuG?+V>yN>x?# T!u<{w@?)JĿ(?p,??mhv6X>b-0Þ?~ah 1ϾY_>>z? D׽q>z)Fon=0侨L]L{پZ >G]먾;|>۩?K>?8\rW K<ѱȿH>*X?k?ǃ~?:>ֲ=؛>ewN>Ā?&>^>-?vF==ߝN DXxUА?,>&qE6X>R>a=0>L.>ބ)`-iT2 r5>o&p?<ƈ.=>?J*>!w=m>SaD_r[7>Ne?Wnes~?Hۑ}PF|?e3)]HҾI ?>3G?p=zS?5>'XT22.%?pg?Iٵ?5Q?.̾OR?M]> ?8(U?˿uп]?L `ֿ4 ?1^b n> >->5ma=#=\ >>e^͂k) ٦2yxl\|?kݍs}&ẍ́-l>)ќ>U'V4ٿX}=h=%Ew>_ҭX?>$،[Խ?1?KԼPU=l#>?>Sb'@ <Ӭ3K?B?Zt=Del>z>GҴ06?=Og~隿1u@?eoS~'*> d8lcY?f7 ,="l>cx ?"??}J?M?6d>>{K!ʾПѾY?̿F7l`ԟ> =!>E>5x?dZ>Z5u=N!?t?C=<>\?h-Srv\?X"$Q ˾>v6>>߁윺#@>?wK?7t2P>>l7(Z!>T=Rwh >2 ?p>rLŀ``^M=|ҩ?B0Z= >?1TqN??>,IS%Lľ??L۶?&?ʿ3u>q>yK̾ʿD>T??=? er?d>>4??=< p^[ x#0a޲?RTt>6slg`>!wlD>n?ۮ<>:>Vj>i>=ap?,3?+">+"?o%<{>?h60\Td=n >S~>NJ랿|<ؐe?o25Tٿs=~oS>?Yk:>ީj>E'=Z2`>1?+_?W>>@{>>԰?:R2P??T&>/޿?o >E3=v )y0>^w`r/;Hݿ/M\R\U>w?侊?7K(?Q>+D@;?I^=TP?=K*p?7>Cl(BCBĻ$XLx[ܾ|?L?rj??>\ܽ?mh>= =z{z}W?TW{ >>E!u>{g;`>d?H>g0Rb_^(Cp#? Ʈ3 ??&?Wc ?NxaJPi??ˈ>.>%GĢ?>[?7I??c픿vq.Q ^>m?-xt>{$>6A{>=0`#>.R= JԿidљmĿYRjo0 Zk?E f%?2p>E9y><>ƈ? >1K5q??B?xG>it?8'>y?Dz?V ? >=_hHD>K?"x=t&Б3>qֽ{ƈ8=f?@w?s[l⾢/ 6d?&? ϿҎ׿'4?vԽbQ?gG>٥?|B>gpH&q/Q>kxU>>>XDe7!>E?l>>aL=v>~G=d X>?&:>Fq>=h=:?oZ$>GCھ@r=@>YFP8qI>>?@KT>rQt? @>)>W>̒Ԇ  |>O?>S J?B_?i>|>m|>='t>Wv>Ɯ5i>J\(>`>ɸl=>qC?Q=Rh5?LH3e:Jt??)H?'*Q?'ݿ;>s2N>H??D ?|]>r/ұhX|N>4?sEꊾLl? )W[ =:VE̿E8h>ss='ӿoS썎ts˱>I.ݫ̿0̻%i`?%j?Q?)>lۿ? ;^. ];Ā>?=qؘɈPMA4~?Zߔ> _ɶlN.E?# ?>1?4?Tj싿!?q63l?d=?X>YpD=P(=0?n?3+$ D>h<> =ARE>?6p?!=E>nf? {D?_ޮ?.??~̿=4?2'?!ZG´==">=H? VI?LH6|%>`?? θ H>́?6fT? zM?D܈>?Ř2d7>hd>T#?:=H0&Կ;q.`^?Gg =h?wϿ50S>Ŗ>BdU=G3C>V?kh?>9ҿGYW?/=?#:?;U?rPHI=v?O&(>܋? ̾"y?u< V>{?.%=ɾv>B 5Bc i1Af$B8CJPCApCE0B;B˳BwCz@n6C|B\C0cBvB!PBJB?C6C6BsSB[B2BBBZBCç@2BBB+B BRA~BiA6m0A}B6hC yB|6B"cB @4塠B?]?5ހBac@KOCmB7lBԌ_ l9RwGsA̱BQJC PtAyB,@C/KC CfC+|=6%`ŎwBUBCwBpBʹ[BCsBd5BBbB(B؉C^CPC C1MBĦB)BBcbBh2eBHBEBLAAB'B:?͠저B֑B:B6:@BLFBfB/BFBivCB@AqhCA,AB jB]BpBEB*-B_BgtAxxAtA9(A—8v v@ΔABYBnb՗Ak¶#Be^BAJBBqACErC zBzB%BMBi}BLN>bT?˄ EpBvx~AJl츱BL8B΋zC w7BfIBԆBp#BuBBEB6-BS|BxB.B:uA|B2.CaBvC:BB4C)BHBBfBOC%ByrA[mCkA~:BuAnBBBBBBPBBoBaB:=AlB2 Aq CX7C?BڲBBJBpB'B$C(C=HBBAٯBdAB\ BM)BBBu:BBN HBGyBQ#VAk>CBCnB B[oxBLB0BuB C CgRBB֋~BMC2Br C"BwBzB 0BuCfBB"B|KB@@BA B B4C ABǽSBAL@* DB0JVBXBC$yB'\Bm(B$BB@%BGBt@8}B3BmBUNbB>B(v$sA>1hBCw(B/2BBrBu BC5BKAbA-#CTBHC@BrACCBEC޽C DASݴBEjBK@C@9T \A%PiP’ݺB r˜h`BwB,BBx~B B1"B;B@Aj.E6A‘ksBhBbBbB7Bk:%rICXN @{KABABCPByB㗴V@B>NBB8A)T~BqB'Ch0C+C8XC$CfC - BJbAB} BȵnBL{CAބC=C0CA}CV*BM¾Wz+u  !-ABp~ wUAZˆ&A陡MB$>O"BADg!@|iJBtB0AuB)(BAA@vX|&.BB6C'¤BJB&_AI2BIBBBaIB΁}BgkBHCA ½P ~AߊNBo 'B?pBoB BD*yB-C AfǢ@ZB[qAk@xb>BݛqCBM]BpkBCD,CZBEMC*=BlA1BB>we1}1]9g; 8{jBBSO[(5-p^R†ۖDM"j&?`BCBv’B1&MT+zBΚBBD@@|B@֩BB|BQXBBqCxBGB :BΓB~0BC|vBVž`BB6@{A*Џ`ǿ`|,¦- qK @Yx5_Jry§.q~ †$*7|*¥"KEAB~JBAszB5,|Z /<bAsBBCj6<@EBB3‰or TB$lz\B|-B{An·6hBBSHBDL@!BHAҟ A):§"2®C,B s™7$Fn/ZAdA˗-jf4BSdK@0BNC tXBAnڠG. Aì'tt@" T[[ĥC‘ +ABrjBTf&V>?OC>HX1VvY+?Oh=5`1?Jƿ( 26`=ڐ?)rF>4=@?^?%;92=n?(t:g Jx?+*>wl>;/y⽉D=R@? ?`R?U9F,>5?'>u?R پ>?*r?HX0<?ȿI)&P>k-o?sҪzD ҹ>?+>̬?N?[(D??MsUv>~?>?h^;b@?gr?!r?6vFrlP'Nپ ⿀v>]6+6r=^ C?V\D SD&>9n> N/"- fp?]nV>Z,>uP<1>ZL?+R>:ܿrAc>C?HUE2z?1sD`FV>VC?Bܿf?F=g+1?a(=֒ I? U,PBa?6S`mx о > 86|l 0?%_??Ulsۑ>&v4=M|eH[?޿ML?l?|EN޾)NʼpC??o>oԬʾ=*$a>~>=c?ctD?Mxc=T,=Y?=[C??(?s|~?Laj?!צ?E>.y?2_=`0L>>ڿmNl=WH>.uQZ?>]V];'LF*m4?,I/>EQc[?m ??>Щ.Fe=Ge>oBa >ƟڿTS?͇&<"=L?[2?saGTھY?h>2K?,h=2f>+4?dX>yˆ?xO?%&> !>KEU5?I8F5=QJ>'=ļ?Ppap?^Mg9ԾT ;sb+4=>eZ4!7f忶 DXO?]??[>y>?fp>6>ۢ?$ m>?CY?Vf>/J<Ĵ>4a?Hzs?!A>Od޾C==.$?^\W=].>F!?t??[C #= V?2X˷o>U`>/1'?A=&пHo6>tp>2,jςnK>O?:s\>pN:^>?3BݿL6.2??a-N>C6>~ҿb!?Qgq,(?Oʣ?ۆ?`dc=f?/4? 禿? ~&>|==>p ?<> ovj>ω>T&f滗g?^?Qҿ Y>&%>?B27ցDL,>i<<P>M}nrE>7D>V?ٯ>?eE^?>E4f$;;N7ۆ͗=BF&̌/V%?+?< ??d= >B/"h> i>[ʿR 'h<>PfHΖ?>տ8;>' 羅eԞ|>QBκ?}lĿ>᧊?vh=N_diL#PZz}>>7n>>e~>6>x?wk?bDE?n ^?Aue!ȿWVIHg??=熿0?R+?1_??,1{>ő=нnT??.`>ï>;? 0޾|^=K>>hdg܆?}d51^>f>4wMȾ޿~&x=R< >y>a><(?b`@1:?`>2>z7=6?cf&4P>>X>pfc Xݿ͜ r@=f>ͮk>B>=T> ?՟\>6>)o>pp!?&>S?{;4}v{>:,\>e>L P>Uĺ>𲿦^X̂P ?O>W=Ǒ?j®9?R u>">tېſwP>Eڲ>@?4"d>0<<*? 1c=iԼоV VCX:>Tr:?>ഌ>ݘAu翊P?l?t >W>. T>=-x$>RzX>R;g͌b?M>?%;?jO;?^!l?D#$d쩾l>G,>¼?S^>{|?%?>ڿN28?,:0Uɾ6}@G;Fb)?;Z=\>+=?.v?>V>UA~>[:{o>o?K]ez>?h>;!> Zt:>R0=I>֣J`l..9lnX >>$U>?>L?>ѫ8i>4٦>*?gk?>`?)>iSfiWT?lʽ¾5z>>_B 5̞-tZ4?`3>e.??> 5*?!?쿀C)&?;S8sk8!Q]N>[?ygXH>/C?J=(Y,˖>lFp?J3g=ڋ`5>+>Wv>o]vwmw?2PH ?4è=> (d?Nw">?~陿nR=?WH?3Ŀ27^?2C?ֿ=㔾,>`>&?%eXF!C࿣ќA?$E?3T>i|?l{?$T&?I5XF?~wX>Lj>>!?vS?>)y|H"i>>->S3>p>O4򜐿Y^71RNHпa?;?Xc?Wc?r!ξ i?d}:> ׿kֿnpܿ>>E?\%+U+*?su?]fbi?2c?`?B?Qi?y>D?=?}?̈́?޹?d?<5;J i+fLG ?% &?rQ辂#` C}о9C 0⿉i&5?Yo|>Onks<bz9[!: ?bk?n,q+?,v?'Ȫٿ?}_H.簿(ڿe~??K?>-=S>8?> S m%u=@ q%=?? N>yz ?it=~a>MM?Bf??bL?DS> HѾT>Rl>i?v=&~*=BL<c? s> z>#(l1v>\>^wz C?5_7?dB'U;?LJH U?2==ȩ?UP)?dA@a˿fPkl>0>^? >Bp>av?ܖfj?S=K,X ?] ?< ?! 31 @=b=o>GH=_vCX>9TyHJǂн=Nt?N$>!z<0@c=> =tHX>!:?Kc>s?v8>ȸ?X> >%r=LHWf=sPBEhU>pjg&eA?NYn>2y.>W?A?+=Ґ>>H>Ř@ }d?mT? zp=>erD>Kӿ:> ?ǙL>0=0?C>+> >>m>Nu?Ue?ؿ 6,M;ihNU*/ڜ>{SN>j?@C?">o?u=<\>vZr@V5c)uԾ޸A?a( n [ ? ھj?l?>F?[|S| >>Tg?D#>.?b?g{ME>ˤ@*=NTI=Rَ?|=Tӣ࿛=Կ>A?U*?*?7\?W4>4}w? *u>rP$? >?? ?$&\?D >֮><Ͼ =?A$St;sx>{E*&J??%>oK? =J>T?/J_L?[?T?i?H>h֤0lH$0X>,C?KG!{l %=ڽ qiH@?~kx? V?347 A>(?Mp??$4 SKj&.?&A>*t(?Foa?DpUy>ݔ+$>ԉښ'8P>?k?sY5Axf]r7žK?a??'d?.>2??wi5LAG:@=SH>>'=?jo>0^>m҉=?SIƿP1&>&??T3?¾D??4# ?>~>S??g7@?R<1?jq?Kjf?wI\?)b¬~*=ꀿH>?4>j*G@>4Խ^G>Q#90fb,.?>H??0yo>,>B?*S-u>gfsH4=<w5vK?J7J? V>6?X.? }?S8?>i=LԿjkl!<+>=L< ̟?$>?HL??,W>> ̷<侅Kf>t?|.M?@ÿٷR=т|\=La">!@?E=WM>!h6d?vlj<^ؼ? ?b]} |#.=) lN{<0aF>=LĒ֔8WX?5?b1e)2A^??>?tA?˲Կ?Xۿп34>Ef0ڿ=2}=oX?*mO=B󕿢~|4z[~>Yl>Z`<`4=񾹨?<)| l?c?$ν'=fx|?|@>>X:5J}{>#i>(?U4GJ ?tyۿ>Q>D=z>;}/Կm?ν8>?u,<>ug9O"^?:?]?f=Ga>>>#'4“T>m$>ij?!Wkt]RV?xʿP8@*?ϸ`Fi> =3]eT@?(!?{l>}@??a?'"濃t½>Ӛ^!>`Y(?/Jn4?$?D>=>Ҿp;RI/ WF:œD?L?|T/7=y>#>I >:^M?>>H=Nb'o= Z$WR?&>1ῑ +>.OXirA&?6z>?WyF̾E:>=flUk?=4?uA?'N+g@S=@ϴvfTkWj>?I i?>h?vſuM>/?$?r>|$?fڽ>#.x2>DY hpo?>ڦ o=MO@X|=n@> ?JGݿL=\\@> #>M5?O=->>,">^>N?Dh4+=K08gM?hw9?Dc?JiNpe^r5HbIM.I@ݿ\h?B?^B>?NW?'5e?m>݃7>8$Hz,?~ Χ?ul?X濿r}m?>2>7H >^*=H2,G?Q3??lrE ?J5( >0 =?] y@$D{:?Rj˾w>>?On?#i\>+=ѳ?ʀ?،? <? $* B?G?L?[꿉ӽs\M>WP?`>ɐІ=YwOtd83>Y\>|>@Y>BCgG>?x4βu?5?^C'~q,vƣ W>ݿwޤ>E*>?'<Ȓ5$?޽䏎=M?Bg>Y2࿤xv>=(>'⾨C>%Z? lvOVu>e0Ȓ>x?=,F>̉?ܿ??Md>Ⱦb F[Hp>H>z^p>]>$h=1?;8=(Gvvo<>?=7=??Fpm?W,ޥ>`:ؼh>>>æXW7R?!B>݋f?qB`ֽfXz?kR6?@>jοNQ>u?~+8?@?|L>1 *Eӿ~g?Qf?<<<Ӏ`}ܿ?cVm?>3w=>V^>2=~bпc#Il?>N?霾?b´6>Nz!q0|a?ྭ$:?*> r? Gt=C7BBi({BFB5eBCBxBJBiB@=BsBNBeBA!ZA&t‡6ƒjV(zB;ƻ9BBUׅA@$]BkjC k BdAp`|Ko`v b0?N$AeABъ!vB3BAXBXVBfeCB{lPƒ6XNB@Bd@6>?NGgbNBF]B&iA BS~BeM@%#BzJBrdBB#$Y˜*FhGCCtBrB0yAnŠSB<;@BBXBBjB+#@|BC%AB:CE>NBPF5Bc]CwBB܄BAAijBZ@B?B;BAABa}`A^ShCB•o7QFB&B!WB08BoAtBbB6C Bf<¥BtaIAA:$rTLBlەԠ>D07_›j ~XAiSzBBԼB)*[9!]W+±LBx2A\B²zGQ/¶nW$¿x²!D sAB%8@A|ˆ&B\­\ z)_4Xю[ <@PŠ›{m³\&ŸA³B¢&Aw$6@oIkLtµ”Ud- NBA=ѳ®2?F§fy=噳bp B2@ƒB*BSp" Ab>PGu AGBLȑTB!B]o"›­,6(Af}u@k.&B2A(A6 XT*!mr82rݩBHՒBg^RB3R\C)0B©Tˌב, 6.AvBBbTcABfAhA_ B$) p@7A{B:Bf B-B31BRаBBAEB;QBM|BίC8Bo)CBlB'BPC|@KhcϳAAXB7BA0dBuC BBBBZ BCAA0PBBw@15BBL#ABIB@ҡBV_D(FRBCBm@G8BmɛAFBn@B-?PC/[;AĴCC"A[BYpB1%nYBBOeCOAt1BZBa`BpBGH@K%cBֲBy`A(ȽB8|BlAJB`Am#nDڸA.l(@bIv-B,C ,CC(iBr:CBR%GBLAoXBBzBAD?ԠBBBxl@{BBqS`BT"B,n`BMIBAGYO+r~_A:|]B%A_\B-B'oBcM}B<.B\Bz+|z BBb?AC"C%B0'Cn Bs‚F8MYA#ITS496AWn31A)V B:hܨ©2.BhBA9B~Az BAW¢%BmR?fbB\By3BfB>@}0B.BBEB~C=B ~C*OB,+BAMEAŠ~}V8 CA{ʿ@4(C¨vl4H‘;qjA{A1BlC+B*AĻ2B|@P(|U78IBSBa@c'\ A.AAD"©º4BAL$Ⱥ&AzB2@B BMÄ́’46B#>3V@5OBxFBţN;]ŸNB|+RB{G9B5HSB~2BegB B12B{BRuvìB\ܼAm^Bt B C8BHt?!?=6>_&D?)Z?-}eD?ܾj~B\?K ^?ֽ>r?x#=0ؿ.5?r VOY!>g,>X\>[+> hX>9WQ/ֽ0=u>bh5up>?fB?ڸ>>OL?濬"?h> й>u@>ޘI?7(DsE\>`>%6?t>r?7$¾s' =a>ӟ?ה ?= ?@m J>"HG>q?6>MP> d?<N/>ٚ п%?ν̿?N?г>a?Y,.=֏]?(S>?ciTy?L?/(B:N >̾5?A:FB>b(=M>>>W*zP⠽Ձ>?԰`>'w>A?+*,^Ŀ'Z>.>|v?>NC#ϿF?L>;>j?ֲ?8>>9">d޾Ͽkph> >[>>bJNپjI€+nٽ^hi?Q?aJ >i^>Ѷ? "?}=?]<'d }N d?b*+(C7???̿9S=|W>=0>). f??64>uؿxw?#?I9>9K? ?"#vܴml͘A>"#?2@ڨ̺ؿm"=x!n?K,>?}#?/<?wp>& P>:>e>&cP?R:U?O¿.HM?ZB@Ķ4?*a>UJ?A)b\ Z>.?X<X> v?&_7>̖m?P׺n?>8WH?`??P鿺r@n= >vIJPꞿ{x>!դ?mB??Br>I ?*?5W?H*~V?F>оqI}@|30?$q>>??V="\)=D?>jB9G?k>VS3ZS\G={yĸ>g?!?=>V¿lz>ި2>D>տ&> >ش?f-p ??/ݽ8?"L?<=k>W?m?P_(xW =z>?OK>ݿ9S! Dî?R?5 =d x߽POO>??=k@ؾl\>DL??WL#kt:Nr4Ŀ;?%,0$O?Sj8[Ŝ?K>|_#V-_.=Nx>>|a?u>D K?('>+q>O1F?~5>ڼ>">ƶ>\r>YZ*Ѿl>Ð>xfm:O"?Gt͂ؿ1}.?X;l>Xf*e>O?xGGP>&k$nVH,D^X?J؅n?{Jb>8>?=M迒j8?&ڿ>{>X>Dv3>2}hH? @>w"<>e=]>G Ѧ? c >PҾ~p^L?6f?ƼH?W=9G>?>ڀ=\>?>H\>.!9 )==+z?E&vE ' >kP>EM?{N?3r?nk> ?jPPԎp>}K@whf>TXQ?>nrcg67??r?@>_  ?r>n>SU|?n> #>h$->3? V+h4G1=? >x@OS?w?N8`OnB?٘>g>`A>@>w |?i=Έ,=cD?4>eڙG*há'.?>4Q=<s[|<:t>->pO꛾+r`L5=0>^?_o:?#D>mq?Ŀzl*>~?M>ֺ?cʿ-L[6>Oʿ>mw?FM濇ɂɚ ?>lu'>l=Wqп2B>/? c?'jyvyڿZo^Q{iܼ?U>)n7{>DB?%?,?p=G?-# y>/>Y% ?O@uT>eQ?MZ<{>md@r~f0?a>b\G?T>$ľ-?nP>"t>A@MͿ 4?[_?.QkD)ֽk(N>b࿺ھξ¶,ݾ#BA?uH>Rc_ ?NyBp?׾`>V?cڦs=ܾ9?@ɨ!dfF=?:0?0b%?é?>HR|=z``?BWԽ(G+?b׿t~<ؿ?価çpK^>g:b?>ʮXq*ɰ>ПM?,4ߘ ?>տ;nb?ct{P便;TXt?:P>fŽ؀(s>"²>4q>?5>+x2? >3ٿp>iӾbgi> X>{0p˾ >?k ?Xu>Έ?#?IT, \?ek{?XξP&0Z>n"x>j?(]ĤR>;.>$v?)Ș>?k>"6=DT :AYu?O><7? nfnB=}6= ?Nv e>p<>3$=Tj>赍>p= /<>EB=T澂e]< 倾s޿[)?,?dҺə>tIJs? >y>p>=0]]>$?9NW>0J?|?a?ȿB1?s߾?3:>!n>d!=nwx>^ >j>?{?#<>aT5>>2^=Fe;7`FJx>?=2'Ȭ4?,i%.ܾs𦿇YᄇB$VP=#8T߭DȾzH>P?a?&L%?e,?8?1$?dӿ-?T?lk|xbI?x5>@ ?F׽H>$?Zo?e(a>">ٶ/ſGtCE[?2l[;=}Y>>NU:g>=>A?65̿:?Sܘ>`?'z^?cC?')??I@ ?]dS!D*,,x?o̿I<-r?J>7?R?X8?9ⅿ%$ k>{? ?hH?2>é=<>C׋>B*ϼ?ZAپh=HξY&p?t0Ͽ?' ?H,t0e>V]>3M??>ly>,N[(/.6/@g ? "۔ھ 2=; >.#->fN=c?>>y?-/>u#<>;&ާxI4wB?Jw?{>3=b8? >c=8;?&G?$g%W>Jɰ?c}ѿ .Կ 7Vf>5dؿ?>Sſk>X>?,W?eXO?-dAW>R>?р?SV=J>ׂ::t?2>>slᆵTпMu-[>U!=_?2ue?{`>c?ex^?en<V>ʾS|,?=!?'?\ ֺοh=e;m>KْnYy<?uA?Y?'?\??>Ȑ_>[=9T?vBNX?%P>Q>yc<\ʇ?Y_;^>>l p2=H??IǺ>C?`F19O >/PwtP>V?>Z6T3>GB?@<6pz>??7>c?O>^ =]>i=C>ZJWi6-~v>*G'搿e+ri?LP=?5S?). N?d29$2>??z)M#sG\F?ҿz{W?Kr2>H-?F*{z˾$H=N̼H>~ u?fG.xr !?~?*x־ؿ4=?LCH߿ 9?E>4v?K?Z侞= jnX}>H$ f>n<H?$>zKS>hPF^?'?Z>h? z<^>Yv?(^,^>d9?=l`m?^n'\?6 ?,U<>?~dg$>b{?Iv^S=ʼ?ې?'c`=oZ>f>NcDV?A(b?ko~?}/?sam.t> Pڿ,i?=e?,3!?Mz{]>D?_  ?jBt'!1p=?7>r?>/? K\>8(>퇕?~H?ꤾك)?F?7|v?u> W?p????>+\>@?<">XX9?!b]ܨ׉l? R6]-v>f?^B?Vfà?F\̲?lh?UՄ?9&Q> >B>=g>>q|vsq>?)b?HJ>?^&`B=:p?9((ǯ>Γ J= 2c|>'sy)>u_ꉾ2>"?mb?2?Do4/. >٦@d0>W}g?}O>fZ@%>42?80a$[L^7>4?q?9>G)>ŏ;Uat?VP>9~>0*j\?UHW.0~>Ss??ξҸn>? $?xz߿?OνFg 0>>\=e>^6?r>1=n^{P?-Կ'뾷|W>axiRؿcP< PV?4?@?}?4?)??=MH:>=ߙ<ވP*^`=JY?j?i>΢|?/=G ~=+rO%3!> >!Mlپ?CnBE}?{kmq᏿!g>u?c?/z?9e?LX?{??#=F>/>A ?0N>~?N6?9O?>ax>{$ ?g,v;~14@?N??޿yJÿDTt4>>.N>W?9r"9B%>¿F>>{YJ\?=? D>`;:X⾱zJ >?9|(Ƃ>E/?b?Gh??ZpA??>]>g< >V?Y?ZY?2aq?d.Խ^s?e!ؿ?Ca?=~~>N?=Ff5P>q>f'?,9H(^?%0?>@>>')8zϿ am?fbHYH?v>[??Yx諮>ps?A:=*#ѾR@=M>Bk>#6%V>?=J-N?O'=11"?X?޿5O)ʿHsp>~3H>C:?r>$?Ev0>RA}W>݋E*DXk >01=P ,.?!oC?Q=7?Ͼy QDX?/$?Rt?KyS? ƕ?k~J4>D+о>wR?>Fo>n>d;f$?$;Z>>?g@?cpq*ؖ޾z Ŗ?? @?8??bx?W[>?>?Dg=J>faf>ő%邽ۼXibw=p?~/?g6Z&?oD>D>f?aO|_>45Z>F8E`Zy?+?:glT>>y2>h?20a*wh@U<>k)>tⰽ4=?=>?Φ?~CdgF>7.h=gK>]i>v?FF?\<0?/?6=?G\?w%?>'Zv@:J?,? +?Un(|SW?pKaF@?"H?ڴ> ?Rr(7U־Ӛ!=jd`>z??, >;οX j>n?&>Z=v'>y?U8h/e>c)?c?Z>}*0, S\=.\>_Z?j=&@qb?n.>sV'^?rl E>6Dy??&0̌?@/??><#a @FHQ>g>(>oD]B?0> K>Rn=?Gپ%>ۏP2?nX_; u?/l?ԏ?=b;E? l?W?AV ?g?W>??[1?`?ڿf>1@B!?ZA6\ՃB>BD2·0ߓ5‹zyZ".x A2|BDB%PAi6B$;dB#\wº@@hBnB/K@{]$@,=ɮRx>M66FBI‚@0amA%v$Af<‰BC>i~.A² auŠt:Š"^ ‘Y¬+B{BA]BSB(lBXB26B PBBKɜ@nRPBd '}2B@A.ASBUȿ1A>7LBBn¤uŠA*(B?A^tu ‡|}BkAo0@" N4 B<2BIXŒ %A8@?A| =;¢2BNlǭEƴ%Ps¤ 7@W[qBV¦K7B6@x3G– ?QAnX¢A£\A jB\@w&L~f1EDBAjJgjQ͵ ՗ݚE‰/AaBl46r f`f"`‰/݀SV)1/J>B{­nLB:@N@TTBX@ABB]8DBwI*AQBYPJ@B!s|Bw ;9fAg,7Av G '¯B B¹AL?Ch@1A^¨V)U@@T^VB«f;—tBoB,»$$b2 =B%EAg}Z9B7B/QŜABV:B'ZC**B7B-DA0P(A4¢"BiHƒBAz@ (@ДBo .‚B856 D·fq}~ B%LAVwvb7"ABG`BUB&L^E:KB‚)d=BBiOB?oIBzK5BBB]ߘCAվ ?BhIIB*C(OA2&.C)5P@z:rkBv*BVW{BsGAbBfBX`qBzBǿlsB6B ^BrA?B BB/V?WBPBCDBOB BqB: B11'P'@ܕ B;+BBoBWB>BBBD!LBB4BBx=Bn BBCBCBIBB).B*C#2XB IBPArBBIA$B4ACC}PB#C*"BǕ[(BǺA\C(T:BB.CBjB|/tn1)¦ϱB*“|_ C_ĒBV-TAAAA/ :N2@Ǵ¿BJɄBA,LB;A\DhAd\'KB *BXvA:AfaF.PB&7BWBAO)RC m@2BFANB6/A@IgŸ͒»C"BB8B#ТuGhk ¶1Ho·=aAh®$冽A]BBs_ BGBl-BNBBA.e8h‡v<@"BH9BB >uBBœd A0L\0&lơˆRB%}vAKBa´N@w |R!A`#¢&$" B(—@B'k%JE5:$°-a`.}/&J#J«Le1?š6¬̀tk\\A°« ¯^9r”xY7›A•m­R?AbkBx:BUB0FBy =_\A{;ºB\R B6bA=atAkul AP7BXĊ@BBct$B8hByMAqB%Ar&:@–_A(BBFBfBqA2}Bq8B"@BVB^BtJ¼J!B4BBbB{ A/ǃB%BBCBK[B$A>AX3bA{BA%u2BD)ŒUEtB -8Aײ7B'[wLAB/(AzϛBt XBizA}C6BqB}B4}B<B*{CB?gBCŠBBG` CB{^COADЗHԘBMBgzB~>ĖLha"t@>D>tP>kG@2=t>z$>ta+>̿ ෾t17?[λ=8? =G?X4Wy\>)?ݞN\K*\?7LM<>?Wb>??M ^YD!T>K.@ Wk=迨?hnο>qܚ$6 `>Kƾ|!?9~ ?oD.T?>?Y?7?SYH>Ey:0=>l^?G?CE+ 8mQ9vsԾھ:VښI-];ɿ`V ?m/o?_w%[?!?5?#>8?`J?H᧿E?㻾%jN~g?A6t?Oi>ʡ?WϢ(bUYJ1(?oZT!BCQB>}?ft>T'>Ͽwi?:6=Q ?iý,>R?FO2m 7ogԞw6?2:G>):?qoBIa>,>inr?eڿmݿ$?L>==`d;&?fڀ>?JȜ?f>A־.?<=˿[@=8p?mq]l>볶>*+>>6?'@=ؿSDUFNz徤dY>l$?C?^O>Z>8G??3R*'?亾7[ľ8? Ǟ3> >M>WĨt?C4?^' ?Uȿ((?>.p=?YN@>Z\??9Li`Yp)?06~~>?M_=މ>Hy?wّ\?->2!q>X?!wѿMO> ?+0?OI2z >U M+E>z>>Znz'P,޾-Ib>ft闽?瑾s>|_?2ze7.iUb?mܾ>TܴE<Ɲ ?8?Y=b' ?M|>>> >.>ܾZjP˿Gt=3PFwH]*?>j%?7?~c=2Ŀ/K?:t>A>)>ܿ/ >V̿qɼމGh>\=>?o ?>ͼ>ܾnMt>??5;dE>qYN>l?4~(n:?pq*< >Sh?zN$=H?S{|!@ ҽ;q LM?[[=*> ſハo->Q $߿`(~Qeb>;ZMX0Ͼͅ=KV7=ʹ>?D@??֯=:n> >'~ꩿ x>= .zp=n ?0LBG?>?t? K*?(R=,R??AaLӾG> mнv?U*/v= C?$?{|P=*I3@:6꺊?`4^{j?08>/x? >.0?\?Cu=0?oڽ_L S >B@?*>>S?A?޿ $]@>֛6(,?6~HJ?>=/=%`X>LPxe?^?qsv>$?9O>Z>-!@&?Z.>/&ux2@?:"Rɗ¿?S :>->͏YA$*?:?QFr? ?h?MW?J;iPP>A'?3.XʾQ <Pt<@? ?}z?!yp?>f?B}bZ03"j}ѽW>H#оd=A??$Xֻ=:> ?هA=y4=̿?A@ӰD]>2:K:P?ꄾZѿk ^>h8Sp/2.ft>Q?bq>(]?p?v>㩕>ѱ?T$?4muz?q2=!> (@%P?OÄо]$t????m>e1J= !W? DmKؾuQ>hPjM>= @??<"$?>d?L\2>wl>=`w#F>' ?OpN*A}l+$=r;?/=(> K=* >3ǿh>?>lXI>0>?s~ X>;ľ?>Я?\7>P>Q>x?C?(EG??9.1 h侵?0?y=w=mc PٶԿ>k3=HQ?NS? 0?&4=Wm&?L|d?CW>3(n.,b $l?Ў>:>Ő࿛-v>3?2?@S?<<0]>?ZOkg6>οO| L>k?_oLο ` R}?!0B2>Z> E>?=m?=Iy|>瑏ھt?>?*R@?9?=D&x>3?Og*291^`H[?M>:<=)P@?6?Z "?GEc7?j?^(?Ǟ?x;>9o|h}>ၾN=x? ?0>`?lyZҿj t<1}ܾ̒c>D?=[P>^& H\?'R>W?`gH?`>{a?fm:4#h笿ox jNw>̽?brh&x͸?J>l>B9悿E`ܿ.)HxA@ ܌>h>;>9wP=?y?*n?'R:6,?B*=זM<>v>,M W>`8?D]>#ݾװϾIu,Z> ;? 6?v<f>=j?c>Z>?h>QU>Dn~03>+c> 2=B?*>1?rj4>p`?Fu?!TM=L6H?*?Hﰿ,-=6:8?[+> ?\?Ne?D?~@>.= l^jn?5>H޿,̿K?b# ?T1OU?]@-d>> f???t"?yPO?qԿ>݄W>H?xbI?4=ҋ=>W>߿^ ?XpbX=|{l? 7>Lr? z6THJTWXn:?zt=u?U>e?vŚ%?qSp?d&$>sx>+3\NX>a=¿ӾLc?#oĶ+??+?]>vf6ɿA&>*,u>Z>M=}Rѽ|֎<|6>=օ=H>5L>?\?=5v>//bLq)d>d?˧̃='?56\?2=j;>C⼄㸿ʓ7oS{C8?&)"6R^> ?d=?5>Rᅨj?Y>zտ" ˶?%|>QYG%Y?m?#lL"!UX:~=!x?WA)B,>F ⿗Ȕ=o>z>?M? c?6m`˿g??I=ϝ |?BT+a>??1v=Oj}H>>9"_%X2uḞ ,? ##5TN>5@W?"?g?D{ʿ@Nh>K>lkz?QFV?sbR>Z?,Կ(=%?Ds~;wrLv??JG?]h>C)???4Aƿ=P>Vz / Oqy?Ⱦ]?7@T@c> [>?)>:YN>lLÿ/C>򾅱>*ӿ#<?Nm?>[?J&޻?-L?8eICrdHDֿ6?c Uv->Q>zYN}(!M.>=?R?於t?hؾB`=>%?*n=gp?.2u.?&?;u\>|be_;#`hota>V?p>2Z>;?{? 'N54?<d΅>]>z$?zJ ?\꠿RS̾B?DT5O>+>(0<?L`,>AdR??&>ֽ?ҿ4B>P? !H21= ࿕ՀE4ü|m?>+>4_#j2? >>??r0T?r>hQ}>.>l? Iw?A>p?>)}>!?v(?Vľ1t?H?8]>5>Q>R2܇?,KS< G? ??5.>?f>Z FiC+E?P? 瀿N?=>Y>+6lW<<)p?yaУQc> >#?=0[?USFRȾ ̿$?[}B>ŝ*I^z  (оOϡ4=?,>;?6k꠾ ս Z$6>fbd1Ͼ='@ ?Կʽ?K?>>X=佔T?#Z(>>.C>ZyR?<$ȼQ0>jb=>WG>mT缈<?.ݹe>`L_G^;?bߚ8>N_@=?7ʿa? V?*??b== xV>XJЋ9Կ=4~S^?`(>?j?o>>yž9=X(|;>V?QUO?1f[>>i#?+?S#߿i1ʿ V#j?Ҿe$\쿚8=ۍ>G/^?Ͼ>v0=䗮t85>H9aI-?gſc>U=?sZ?$?Q|i>cT>|? z3ſ8? N>B>^t>ؾ5>⥔7?B/_lp?/?4꾐t_n=:?7n @?R?y?2=. >f=b;ҩB&>J?>/VO{>4E 0>f{t>?xN心 ?Ɗ?yt>s>AJ>b.q?F>6I.>zid ䷽f>~>axN Bp.?TEJ?(>?f x?Lp?ÿx?=t=9:0j>p4PUɞ>ѻ!H=Uä=N>?|8rpe֋? ?l >S=%?e@Ւ?>Ǣx0Liu m'>cl>?o`\NPl2x[9u­>>%T>马>e=x>?PZ˜C pL>Ӆ=㳹>¿S꿄 w3Dan$ ?Tl>}V>>R`b>?K>ou>V>hB]Ҿڿ7VlLv=+z?1Q?^GFȅO8#_?=0>XLp&-Q02>ǾPT>^>ľ`Z*+оBWO樾󃻿_ rNA ?B?5?<>:?^>?PDz?`?>;@ F1h>m?9y??Gy>{q0S4=f"dq?)y!1?Y,7Ky=H8.p=WoA{>t}?f?H>H=|?L>ц?pEjlS=Q?m=? O?*>e?ؿXz ᆲjZ>*? >T?0M>ꧾ=? )?i츾:cL>4j'l ?H6"1پ3+?:fCP? $?u?ԃ>࿳{K?KRvR??#hо׬οQ̓B?r<<нRB|vqOҁ=? >M꾔e>ߛ?ȿ>r?6tg?]?@>|>o?5?bj#Nuڿί׾FP>˱?+???YPl>Ɯy>?xu>WE=ΰnA='Bx=괆!1??70?fT?Y/r?>"%HRri ??IB?Ƽ@:p?h?Z>n0?o\Rb?{g,?_0+?pʏ2/ at?H.~? 5\~? =p>,r<=$7>Ͽ6?&^J#>?S?]aT?%޼=Zp?5Gu?+oub<<"zqtv:m>V1>@mYN?Gl=>ZvD R鍾2s>^^?ۃ|*$x"d?!=? ?ag?=vAt>ĿM>??@4F>O<-\w@Cd?"⾿;|?UqG龖?v )=< =頿5xN`2<>Iڦ>]>D𿂅DP??s]>WkԿL=8Bg>lBBBNm0"O-0BE3BfM&BO@f1>sƘ°Q31B#T@-CA B%B A?u/B'VBB 2B^oRBB\B`]BɝBBȦBHBf?BdCvADZAnBCWSCV(0(KB`B(.B@3AgW@JApmAAOAv¼AQY A>BAz B)B|CUBAB$BByC-ICp@Bo`C0BC C1*CDBe\n@(BڑhB {AHA}BG C2;VBDܔFkB}C3LBAUBDB>4BEtB dB&UʀA7 qBtm@%YBB„A!A@nB:+\"ZALF¸ZCAnwAV.dCW BC0BPAJcGB}Bl kCB+$B0B4q^B^WBAǡBoKB]A-kWdpABBv4Bv@Y>B@ mBGqB`A%G?yBQAZ0 c9^*aRBOEA,=BjAD~A:X\B*C AAh¨{BAQB"B ,AcBJQAf&=+pv&dPi°a„A^mĩ9R<+?I0kAlAwa†ŠRz°MWZBCs:fB&@*pD4yɻA) A-Ap/ª[&~.OCSAztA>¯x>%{jŒ^AµxA?:p¥@}*B> AAj! 0B=G£A@TŽ›6HOnTQ8c‹y,AӏuQ¸j])BhºemB0] B\BCB:KA{„$UAu)B'A<=c@nay1;&9 A"eLI}W<`AyB/sԯ @?O|0fD A B'D>BVA7CCBݢ/pBV{B^)B1vB?'B BV™m_@/A{ABs\[ %BOA&ZAwZRApBzBepADBqA1@\BA`|B@-CL#BeBRB(ZCuBߴ"CJBvB2ԦZ4CA (&BxABPVB? B[?|AaB QzBdABsAټBB߷C .BȬCuqBgB|qAB3uB3EBB6($€ph25mAYABVB /,<AkBV^pB'}BrdNBGB_BBNC'J|BBSJZAkkEƧ¶"BA3BNBABjA@$BdBE[B\eAuZ)D@…X/Fu ʾP@3-;b?‰2 )bn-6q6؜¾!άh(˜g@„\?̡S(I8(+ ǖרtBEBuaI {B ¾$eƂyJߒhJGKHA; B·{B jBcnB}B½AA¥rB⟮¨LANOŠw @ΕB)BgV`CCU£ռ'<›gEAc-dM8q˜ (B[qA"0-B5}3,NM`JB B=dLAlvACzBhBxBu8AkyA݀B+ @ׂ?HY/N/@CBl\}B*s9B,^B9A/UBɔ&AbAF^BH L*cS ƒABBr‹72ؘ@/B#6͋AuB` a-L'E*¶2ˆS±>! A*cOy71©ޫ:@GA\!BTABBGP2E:@BÚBKmB{AќA. 0-·^uAŠBtT9k] x_€/<_#A/l*B[<’BA!)B`ɪBe`vA4AjA>BP}||½Y8]BzA|HxFI’4lf?)%Œ߀1?yk> = ;ND >RV& |cp>!?ծ? L>=>o8=??l?C???ZKhKR?J@@L`>?APTIX?[9?(j8UlX=y>,ҟ1[T 09>l|XH?ļ">>ʊ>\ο$>.?!? ?C2Ⱥ6HNOBx >q.?f?B@YF$p?>>V3V`>n>?Qξhy>?m>)d< ?hW>C=Lp1y ۊ="?]H>O>Ҍ?PJ(>h¿=>l+SF/s@ kɠ?>񠏿ޓ?Zz>;ahο.P?žU?9=>># f[{%&`>?S ?D&V->="AlTٿ ٺ>n`=ܤ߽{?g˿Y3p>ˑF>i_?eOU(a ??4E ?>(i6:T@(zI>`x>?Ih*O>-1?rྋd=4ƾQ_8|?T9\+?NS?^̿iҡ>>̋4?hi>\? 8$<Ԕؿ 9>h?<;?a~8 n4cr|>=]6f>h>,ul>?GDȿgR?m:,"?i?>ŧOݽ)> Dzy&=>ޏ??6>E<[>`=?>>O>֌oA2I?pvZ6> H4F ?Y߿"ǒ>Tx: X3dB!>n=l?8 CJ0 >v? ^>W">+?Ǿt>F`jRr >Ӹm=mo0>A|V?R B?㯿n?6j>K?w?%կ4,=8pQecV?]+:>rL?㾬e_6B _?b4=m>9f=[<|?gfZ>oP祾ް?YOc>NEp?yI)R?> >Z??Kcu@p=H>B\=$Pgſ>¿2۾M?H#?O@?'OؾP>^Uv[??Ҧ>Jdh?f[}=qǨ:?>ۈ3MJcF ~^>p3>>܈>N>>) {=(H/b>i?E>ä?i1?oaٿL+>(>.w? v8S>??!#=Y( ,H꿹 \SD<5&R>[)?d?X>=D𾛱> rI@4a,HJ>SqW?)>{?g:?=(?>__:ShQ /q>>.Eg\>a? ~)=}z??ؿ>!H|? ?h!~?]?U? w=R?%h?Qhy>t?>5@?+@> ?8? V?(I1C>>Sel S>J? ß9q>dN?Ү־8> cl?.-?og?ЂYJ>64%b?**>?*u<`Űxxn+=?&>>5<8$?*?<֝%$  )N_'dt?˷?[K,OQNS?8??(E?SQ6!bB4h?:>}>W?6>/a??K^i>+?:',։ڿ&3Ob?iC??I ?22>w |>_=~??z_?Sa?|"wa>?пnX.?)?=ڽ_ >-?vl6=lVkd|f?^2>i%>ue?=paJp޿I?I?V2?>^ $?`iRQ>V>7Ȇ>~=1|_FFo)K8VuG/9񑴾ORC>a!=l??%ſ.$,W?2d>V:u?$=jl7O??tXпaw>dy>~>f9Y?)>T*pypa?º&"@ʿ?=>]%-?.ۿ6\O5:jHlD>oj?i=5)=c8愿Um<˿?ٝ>(`ی%;:+?uľYJ?v>N"?'5 >>i>w?=ʾ9G`}>s,lA>>g0=ɔ<>Z?_Djܿ?1zG=u>Za \Å kF?'>Y0?{J/㿄쾘q@b>S=KLTNw ,8h U5.?gyܿ(5@>b׾T?-?8=L?1.wȾِw+޻=h?j&cB=䖿m OCR>)m9=nY&>z=?ܩ¾$=PGq?>zWH]?;y {5?Zp=&B۾ټ>3>.?^Ň>?t\>!닿]r]V?7 O=ެ p6blE^DA\z>'"?m%?5?+??Z3|<0&ѭU>N>?G>?aX5Wp>&>Ȯ ?-5>M;~?E5aNQh[=NY0,`O?>{wUp?qbο9?k8< ??\> b<{>䕾¿bw? $?o]B:*)rf8:ڎ`ğ?ht9>oe qyS>ٿ>4P`h>DL?s\>;>$?j?5mg-ڽ;Œ?Doz@ݱ|uɿygr1<ݪ^>>?= ĿNZ]? Np&>?z??rb= x?"+뺂?g*">.ÿ M8 >.,+F>Pi2f=ft`nM+k@?a(T7??6߾,">V?L=`|be\ >c?|C=z=c>l<;n&v⾮S?!dފ%>>>h{#?4_ZԿA?'|(?gg?XXrއS6OL4>? (>ٶ?a/Ba>q'g>۾3D>%> >6>Xi>ݽ~>y?X>܈?Pb`p<<?z'E>=?RT>Q$=z J>pd>Xҿj'<p?L3ѽ@\=t+0?33TV@ >5 Wο* {S?VZ >sOb?2â q0? 9>1+P+ѿ4?[W?2a̦c-ۤ?`4!?3>fo>>]@X=)=7p?}2i̿%?94?I? sB?-F>Ch$]a>>?{d ?~-4*ҿJqYpyhC%6>xL!"?T?1zF?>譠%=|?~)F?or`v"&7 yhدf?VaH>O~Zx´=̊8al^޾?PF?v ?' ?J#>uJ䖾>?_1_uɽoXH[k p=L|y>%;J?G0?? ~Y?[?K?(>?%lqdB??5?v>G?a>r?h=rNH>v>oDξdqG5n<>>- ?5 n>ٲ>pX>^>?1@>%D=?>P=1=<:́Ҿ??K>p(>[J$(?=冕?_HE>-/C?V?xżr?O ?S= (?>wc?9X"ܰ9Zþc%ok辽ķ*h ehRH?J"5r=܌=T ?r<8 ^N??VE۾F?6B> ~>bF=&=x8Ƃʄ?g ?,6?b>Or>>r^?m`?ƈ*Xw?M /?$>>`? ;ֿ_>ę5򽰚P4\=u>"`1h ^0(J??,>s|e?Ak >Z]=p7>k$=[׿0>c,>*6>T[G$N?D}df>t>?c>>6=v>pM=T> Oᅦ>ˈ8>r Rȉ?@~?>?>??T>S gN=/L?Q">>|LҊ}?*?-Rs? K?(f? >!0>bƿ!>r?70? C>"э =)뤠>_~=f?J\>H1x?|?.`+?h8Ҿ ;=>ؕ-??墿,,3:>԰?'YOƽM?,h?>j?whώ>?o[gQ>?7) R>_?I>M4>X|=^?N>ٽ=>=C8_T>zgc(Խ,>,>̼P?>U?-9ֽۊH/6?Kп<9`???HC?J^?O??xֿ%8lOҾ`>B1A1O>HI?>>+>*|NnbqEOU\cD*оB?.sHUz>փ?1|P>O?>x= ?l=?Jʾ.V> K־> ɕ>pj? V?v1? +>mT<5~ ?0ܽU?d>{O}?='ܾ,?:X88tt=\>f?xx?2?aQm8?&X?A Rfk>S ?X.uc,q [?q:?*E]M>*?dy(?($?0+?.>=,h?ξSȑD>?a[jM>½?#?š>_?%>7c>HYľn*^.U3}?@">a0+1e}>f?b>0)=a?Fab>β?1?Qk.~|?N@! ->mC >_h^=,>Aܶ6^>/"?+8j8n=|O>~??!Bi?^?'>/ >>|9׿K?$?6s>+%zU?=«?wZ<@??@?W2?w-0A>2.ֻG@?O7?Bd?+پ촿)/G>,>1ӿ3> >J>f4=/=!qy;(K꾥y?y,>><`?D6?>-֟ds>X6 k=k'$>X?>?X@=q>Ŀoa =i???ofݿ$N>PFցʾ@7۰N>PG=>b>+&=?_?g'2>Ӥ>ZQK6X^CȾi<7?>in>" 9~;H>3@>>t>pr>~?&>b?:g?oY?4=Jr?%`=Q>x,p=|r]  @ܽ2qn>!?)v>E>1? К:o)>DZ0,>%4?+C??thb&>X{x ܔ$ ak(>? \>N:>h h%>h`m>?lQ>[=eV<>r<>^;SDDF>?Vx7=i?xX=bпG|>k?~vt-˯7iˈo>?O&z=ͽ@r>D:?q%?Ȉܻ&0Y! ?ʿ0Y?̾|Pj%x?آ ?N?K<;pUK^?xa%@>z?,Dľk ~=&]*M> :?-DQJD>Mᾨy?6龮LǑƾ>׿3?5>l?AYn?gnY>>#iUL?D>]?s8:Xr˵1N=>D?>3?C?T`>>F= >:>>!>b(?|>[򇻈@>@;4?="辯)Og>I?]?'鿇f= `=Bv/# p-O>4^?n3ῼal> ?FF!=Ͼ˟??~?_>N?> l>\?MW?>?2,>\?+?>l?S2DpzK.>$>L>̿?-> >=E>qW?'^ڹ>=Vؿε>>n|#0 ,>?Rf>I?ڑhΑh .?#|K>-t??f͵?d~<@Jp?!}>3><;>8>7.Z?>UxR@%׵7|?y=>5 >s?kt_eZ>0Oƿp>?6/8>2? ?aO爾Ч~f_>a۾b֢v`?D=R !=пl?3 ?!= >ھB,¾-Z :ޙP?W?HY6>\?UX?~>FO>Ⱦ^MU@)6վ?,5>6!w~0?+>&\?+ir?S?=H4<?X0f>*Ngr,>?WT,t> >Y.?R"\`H?+?W$>Aպ< >M:_sy7X>Nu• ¤Vٴ!@:+["lŽnј¢·BS+Ȉ¬RJA-X^Œg„+pd{ƒl”*t[BPAwDš“sºƞ\&6B:2šx,*.¶װAZ-"BnE@R…EAևeEmzg)~–y;Q “I{ZA[OͩMrBXΔNZAW b9K™HyY۴™[K">gA5BՀrAOVAh@B+A+AZA޺>Q&n,+ /BsBR~j[ }ºˆAbBQ}; 4nKxBUA++BTrX4BM8AKŸ ˜#=AMDBPTB^BrqAUA=ATC*VBkhbN@VAi6¢`9XAXʋE Ž!T‹!@B XNBwǿJ"$A*@w7¬{<1Ւ ;G@BF‚i‰“3*BE RB:[6BPA>DBi`B0BͯBaA cBǷ>AzQB;A\)%CKBsB B3AܠB:/BBP B@A t Bn)'OBLP A^?VA?;Am(xA)?/A+a A7EB\$bjgC :BZ2A*z@VXAuA?.Bt~%šzM|n^Ac*CuLJ¨Z^@V&~͠iX@ LYA߃„P¾y¶64'·ifFM]zBoABcbA]@dS!QxKg!+ėNY] ˜1lFμ(vABBB[ל*¸^A 2“ O)BG7€~+/7j“˹^WVBBA<"0BL"% T‡(%[l&QAp:BHS>*@1"@mia¡U¯>)AARB7$})N`vlQJˮ'›@Xd89s&jOt<–WZÆ(l"?GV_xb™"VM!h()T9Jō n W^Ê)̀~oB`AjzkB[B'A2A.6A-x©AB"hBnAզB)YB=AhJBB.BQA4nPAIA@$B]DNg°x‰ȒA5µ zv§\C7‹o2¼\/Aհ·~@בv&Zc‚Pb6zŒƞ“U`|@YžWAΗCB&ADŽB β?EBmH~’Z`.•@٧B!2AK?趠@KyMvtB2?ڎB=%s_X5AB?Q<§V5]]^)!_.',џf=<:{B_Ö̈́UBaY™!—Vº> r(^•0Rv8O´eqzrY1,l¶¦«xOy‡,A\uB!m€n†ez>BA%A:*h C AXAMۏz 6@z&B]@BC W7ZB"BBSBD(ZzcbBBmBPB }BK#POSBB:B/B.JtB@$B+۶DC i,B,[ M@@Ah—MYA&=P$ AVA#PXA_®{1cr„# B(ZAoy?oAuTrB6-¨RBDB0 @ª>ƒA@8v [%@%Aj[$41T_.WЋAVy€F}¶9§/g ·jS<¥%ӂc V &AŽ@8@'=h4w@A[gS]gJƒ׾`o [gˆvo :l)¦BF[D@தS76-sP@H±_A\EN-sj;ˆL,ѫvPnk&3G@SžrPM~ܣ %x†!Z P0[³-O-]Bup-)|„~ IAA&Ay>w=,H7¹q:šB&*@ttA%6HkewABªB \A]B#"§z5kr܌錅BAAdB8B-WAhAYL@?BF(8x:$BwB mB8yAᲛ?LEBA BU@vBB*If@%~lۜ6BX<­ը „v!*{FlR• ʆ$L„sWdЖ¨,nY(A'LjU 0µ.ž+cAVDuksia&C8Š,q "£DRؼz'BjY r7xC ‰qjMzH>GhB8s$A H&Q{AD’uAu=O&R&7?S"5>=d 0?0%QJ?7>?f`>?'e0??n4&z?kZK1)>>({Y?a ">+?&?Of4o޿|e?h_'?!>|>Z>q@?V0H>>L?t&?Nv[=39g>wJ4,;QD?@:]?;4U>Sut$d?b#>>tоՎmq>D?)꽋j?v|O=M>]zu>"M??>h?T7ن?0\cN>k>v <`>5$???>}|!>ƯaJƞ>>?Cê?!Nj<8>>)6>vjuݿtܾ>F>Ts#B??Td>gm=<>O=>>NpcD>pY>]6>ތP݌>? ?Nn>>>{H?%6~>ff?<@~I3"?A{οjg?t ?B-/=>>c<=cL?b;q?f?J>?gb==? =_p>$j?tnn>88?&t2(}<{=/h>N>F?=<,>=B>b>d?RFpn<\j6?R?;*?)o? /?WB?n=̨T|?6>9W 难Ԧ>Ŀ՘0=ƾ?Ai>#:=?I dz?p 0v ?==?@!꽎̽>?2r*eqvZ??x??o>7*>?=x>?ydLP?ۙ ?yF>A] =󾈖?̙?;3?7X?m{!^>A[8|DoW쿺l=Q|&g?ƤM"V?x7>ӆ?8Dƿu/?#'?s>{ z?ïx>!?Ԛ g}>M}¾[| > LR)|Ex?.ֿ]Oad>7`M>=a3J ??> Ͽ^>l;S? Խ6?~?Vf?+~?mL>>65 Y>O? f?w?C~?& L"6,52b,>9?䗦:!l??7}뾻֒? IN-?c?7=4>b;IK⿒8ſml(e= >P,ؖ?M9=?h?U>| ?g&OG>k?+ k>6Kf?c?jdj>-=np?;>̕>>94 d| ?D m<>Ծ,7q$ƙg(>?oҿoD=}FX>jj>;@??GU?4FU:\«{I;> | ۴4fsJ? <'@>??sk?6c?=N?kٓzL7qڼief?ah?@e">p??O?b/м0p>`lD?辔eֿn>,p=5k}?ܡ■r0r&" ? ~UP?. #O\.&_T??>v>?'PD>x0@?,>ް?za95Ç7j5q>|r?t(?[?UP?V>j?I??]?l?@G-? ު>9zntgvqjnJRϾ >s|t>c楬f D??`??>A?x?ٸ?$?.0"u7?'('>݂??z9=P?t $>> ^>"&>?x=\?wnS?d4y>oSⅸ=D^;S\4C??f>$z?;>cN?,?hud?W?NC?RG5?'}^\>??޽ڎ?\~CK y="@?uˢ=> >P~>ߴ{>p>s~@=@7(?-(>14?WX>inh? >*t>Tc>X{ >?+6 }*>>?ϼ<^H=?*Aƾblz?كV(_Gf?G&>ٓ?=eI->Ohj>d> k.>>j=te@?=>7>-*>7p==k?pd>!nɿF}5 ??]?(tT2,,?.`>$?plRLl>>\w>= 3Ⱦ?F|CaH ?`@c?"rR?"h?",S,]C˾C3?Wtֿ?{1?b%>x.>d=Kֿ `&l>ސe=?5%ս>G>j>Ϯ=>2? F\>}) ur? X3>/.{ƿծ>6=>>kO=e>&?^8>#>ij ~?>E)t?7|?#>%Y:??~?DdV%ь?m>B?]>>reM\"?'V <=̿k=N>Y>^*J@>ȂȾcM꽪'X?>w1>̃ >AiR;>a߿]g龾}?򲿛n>Bur>DVB ,?l>/\\o?2 Xkr<7>=djV>OC>!>x?#??^D?>fr??c>!snǸ?>¿Cmb礿"%>C?sG?h yWlhi?;+?0܊C>Qn?y;[>? ̿r)9o{&?U@P@½BlK>u5ۿ ?J^>T?"I?=nd?UD?}?>ho?U3>o?AV?ᄑ=@?bE?kܿl2??Ĵ>Ht>(?&#Jg4弿:B@€oP&^=>?R>*Y=^:?JHX?>uc@Q>*?*r"ѿj *?@bǾdb?,R ?+?w>??":.Fy???AR R⿋>>N? m>k?C>3K?k4` #>^*ZE?$V?6P?.>8¿>|؜??N>ں?(ε?f rhBtRd":?:tο|>{*_˿u> bn'p??,>B}>"?Կ}߿LX}E7 9xF>>b?9>\?җ?[8ܴB>:>4>(&$ٌ>J?k>?m?\0>P@=`|ʾE?^e>CX]/H?4Z N?%(2>?4"T?Kξ𖔿s_+ɽ(?Lvľ;?mz>?I =e? >+?<#?Cx=>R,>2h?o2F?Ŀ,ub8f;ڿ ?? >TW8>S0?,~>\x& >Ȏ?*?$>ts>%~¿QBa]HJ (vRǨ侤N[F>1 Q4?I"3l>~h4>m?a>;>5ݿ ͚8>COA>ҽjA.=׿.=4쿴-ݿT쿃>=i\n?1 =g< <~-d??&?ͽ4맿H@>N<ސ9>NBl﾿$?x=>ꑿ?W=x B!8> ?RC/?>\">"?T>Z޾E)>)mAg?ڧ}>av)5o8?2K*u><.?ҿ";?7Z>>\*?oNwx?ؿpо?YN?6'?|?F?L=>#>݆>ܾnhZT^6?.?n6LhJнxy< +>7f<Ҿ[?.x>\Ww>pIcZ>=oZ.=Vⰾ HD>߾dbݻ©4 bCD=?R _?V(B?>?AXv?qȿi>M< οNוW`^i?l??Nf?yb?sܽ? @;?\c ?"q6Rl )>W@(kL> $ݿ@gv[f?68>?wϒ>uVR~F?l?~h4 jB4@;&?c㞿Fj̿?!?M>ӗ=6=uN?R?Ʉ=6}"=%=\R>- >B`?>ξôVJC4<I>{x>6u?9>=̢¿ξI!>T"=4>$L>J?+3?<0?xG@>8?CR.1#&š>?6}OzG+xpHYPPIN濍/࿉'7F??%̿]1&?%->?%?޽"ē>>ZEL*hÈ5; ;'SV >?uZ냆y?Gu>Wƾ?|>;>Öv?,?>&l>"ȿef!п8+>֐E=`4kĞ3GP= =q'=>񔾛L,t<(>Ȗ>FiL?rڼgp`d>V/?@#V?r@ؓb̿wо+?kL+z;"2w~Y*wܾοu]¾{[?~jG E/0iȿ\j,>O?"(0>>*F?ryG>K$?-<,?b2?}?6?a̿b-E[?ɿO?9FrTOBpS<@?P|?y9y?D}o>2ܽ$4<Ͽ6 ޮ>6>>{ K8>m[>h>Mf)*?ǝc?^&?$l><)^<6>?8> ? 9%4Ծ";hg>ʟ? +{>°RȂPHm!Ҿ3GlNN!7 ż=>_1?>ͻgpp#dn஦kJ?^S>U$>7=%ݘ>y?a551:?`RIhs?N@0}>HrF>^> =J?wݞ>n>{[>&>\&? Q>=p>> Z-f<~=E?5/vG|>?] '@6Knڿn&ka>Ҩ>_<?q8= t{ \?0i?N럀(NK~>ξn?r:fԾ!?T.>[s>:o=mDB:d>uLX>Kd > ?>ԿҰ࿅"԰>aC&?fׄ>?/ %z?iV?8m>?L7>*0-)Ŀm>|2 >.n>>>U>q"?U?R>U𿝅p=>?4D^[>~-Ⱥnr>h;7?K=>2^<>?uW=\>?4>r>~>:>CJ2:IX?Cb?S]ƻ"0pM̋.37>`A/;Y`?a?kޓ?x>򍦾ns^Y}v=?;Ꮸ>Og_uV O.о?}v1ھ9dʾtp?Q>Տd>?ݸu 2?Wo?B?]6yv=?n?f~ :k[i?x?ؿu@??>M?.ʼx*h`м$H?JE?/;ҿ];??Lſ =A=:|>tO8?iD=P?b]?aϿM~꿙y̾g" ǾR2(>8$z?T(?0<>f>? <>찾he:vfؾY+o%倾 2c#a{>pV࠾46l]F2V _` =?V?b>@>= H{@?Sy.?luLF?o?3)?M?s!?)??K,>U? 7=DUU>n{[`B^r?Y?y%nxH7`>c#8?~>^=f,8I'j>4~7>HdpEh(?:!>S̼ =قҌ?t6[I?hD;>>x,8V=L0 ]?m4oY?<-SK91D>F:>Q.J?Vʿ?6~Xh$B,>Ň 3?x>˨L&??>ښ?t?$3=-(it?VSw}>*'؊=pοH>x%?$!2>d>wlP?"z,l=.#(?JJ1?s½E>.?/>VaKp?G2g;@A1Hn?ֿS5>c>J>ur?5R򓚿UN]?>E>eþ:* ü?[?KEF?h>>VnB15Bv,ޱSA~slG"BOB@ FB€tsA¡7KPkBTs [@Eɐ6KW/‡ߒ){$ߒڐU±t<†>b3v|g³U2]¦Vy8}dIy¸XAJ;EjB@0BV'0-w©†G¤[[0Ͻڤ  5DЎ>²($d.T- 4Ôҗ?B5ƒG {OB`q®0³SƒL`P}4 Iµ6{«Z¦AѱB^A~°X> "l B?(C(CNBAÒ0“ª6+7@m¤֗—Qr®` ^! t”µ*!i«&K¬fv[f'H$u¬(‰R?a8}N4—AUz#mǼ±¿ >¡fr #.QleÈ'7O& !uƔdLT@p Ht»xJ)6Рi1¨­B +AVxÃ{zݶoHB\,B0rN-jPRe(ZXTŽ.7 ٻBI'.|®r.c%}Tm-A5n*Vá4A .:Gp@v5;/Dh1A[ 0g”;L(B \tB_"A< 2s'‰v›H[Ғ®NBAb¬AAsby~Bg:~#ªah0`Q8n^U.<NK -¦J0+'"/=>ŒL$b< Ka¼Jf8"4šWus~¤D@FtK[=—$3ƒ5`+Z)?F†B_E?ޱA hK[&Bp@l؜ `‚Bv =i5+t@$®iNPzZ#`2dmJF£$W#i3khŠ9BBg@EuB>XL)4&µD/6,¿"'pw2(7.֛¬'}rAhBo4AԂ3¡Ӆn6kC6AӷbA4RLdU?w®iAiA[5<_nRAҺA5gA<ۮTZL¦hvˆ9+•²fx@`t0]¶9xyj,A~tI}q cBA30<‰-"f@M B`}i:๹—’z"´6TŸ;_B¢vAQ}h/<|AH{Z/.VB/=kBQ½2GŽ+.Hc`"BZt@+Bli5A< £FQ”#PBpN$pBL<°tvg~GkAF®AdޞBMMBF0B0hAhšnNANBZB*A>AAuC@NBt,H’W©͘AV{Bu ?ApBhAtABOCuv(Bџ+S]9|!K? Va +V¹>u3NT·GS‡)!TL))$8kk]êgD¡CV£f`!ٚ_5ixz _8Ж~Awo@BhBl@jBB@ZB*E>B7B¼:/|mB^Ao0\]AbB.7mBZ6(B3BB@ m&Bc@5}HBVBl¼&&i BA"’{U)0blX?} AόBn,e…M¤!Ċg0jh0d?uBP<—¾A@B@WYB<\yˆI}zA4BL+F:Tw/jAB(^cU0]J@NB.Bq @vwBt=CxBxBi/>…‡|OBš*BLlB:TGyB-_3YtB BA]k1Bz%BT1 *' @IB$„k{> sŠiP?B3JBs BBB"CbBB Bg"ABRe?BQ B+BIABвZBBBKB?AҜpƒ'B TPEBq JZA]BtsBѤB,JBA+GBB`XBBBC/BЍBBBKCIBnC H>B A?C8B=mBtAt@4BPiAϣ" U"B%'BhqA먏B"B@3OӛB',BJ-(A% BaBTBBB6B`}BBզC ~BPBxܬB C 'B!AKRBA9B/BApCQإ^B'fBBdB? CiBDC FC*DB3C I#CQCB(B54BRB[JC sB[YQBݏB\]GB4B%TyBB9BB:BCABBB?AYpB7HB AnBvBxCY BO%nB5BŒ'@/SRB7B}D>ByBd$@,kBګA"B|pB\NAAGB%eBMĐB^B^? ?dS? >Q!?H>nth¸>WI>Oz>:LN?1> ?R*Yp2 jL>OJ`> [TLнrT0(v?x?"I >6F࠿^??L?]7*6?P?moϢǂ#;p>eׄ?%^<,?SNy+?۾% ? kW=PH,L?W? 0о>"0G?)V H  1̾ϣu?*6?C&+> {>6W#;GOΨ?}4E3Ҿ|0_~BEԹ?GrҰ>ο(&??"׿&<@]>.?+> +>aY*7>?s+?mg?d=0[`hۼH@>>XFe1u4-޽(>VZv?H??GP7iz>8=*Z5>θܿE>>zȿvDOӋ>v쿰 >>j1,u> Vl?cZ&>u='> ?P\?)E?oVi=.o(>ʧ? }> 2^>= 8]7z>ȿgV4LUܾ޵>>?_?B?k4?dĿ6|=Q;>+(N=FT{1J>nITzy}?1`>G>}(?,ؿ㌾" "=!%wؿYyl>g?*>jS>@Ž>>?4?V>v5; =͔Z<п2.aS| 0o>_ ;}c?>:>o}s?m>՝>F(!?4)>=(~F?q>|&> ^?iWE>?>> 9h&?þxZ=B࿍h>d)t?>WEԬ>.o?)>GX{ILqG>M?׿-Ir>B=l:h?Ms?rK?Ͼml=*RŧQ?~S<r?`¿7p?nx>dM`^>L\lW WTE"==QDbn5?f??yg?'>fޛ=E?Y==h> ȿ2 @>`+pd;>쿡pb8hm?:z?=`.4%4?Sk׼J꽀51O1"???3 >A]*<.`;btXV7>MǾX=~͡XӿUP>#sPL=~d?*5FaB|7YBZpF{>?H?M?">>c`3翛h>Yt#9D?㍾J=뾌&%>3?ɪb?fh^>y$V=)8DlRèQWO`>~y޿\F?KB?Q<> OH~z尽hl>?<_?ZBlP0d>n>T޿>þц.B R>x| =+'ZHr>"z9:?>M=@hG@? t?/Z? \?" >xa`oֽ?!)@=p?#v>=# u?Y=ǰ>\#~?B$h=ք>Ջ>,=ؾ5>{cĿj>W^=I>K?9RD>H:9?C4>[>w*?F(jf{%[8>-_?+}>{ )??cƄ>B>x >Lп?BӾA;b= :?D?N>-)j?]U?F? lUK>mоFKd>6 j? 28M8??v??0'ٔOK>U:,>ˣ}=I$>)xJ`{?} uE>>%?/?X8`?>扌?jj!쐾];q?N?4=ؽâ?;?˂??AGt?5>yUI>źXR>>>n>>V>Tn?JNpp?P9?fFP>4+?d&=/?<*?A V>6>l>y?>sʾ;u ѾemK=t>r`Q|?o?E?`>8O=>:?Z.c? ;.L??",>?Ue AeHѯ4W>?RV8hs>u9 >Q=?l.ٙ>!@? =Կ%~[RWͿa$"?] NFl?b>f拿#D~>;]\+u5U?6ł>i=t̾P= T?kz'^P=e< >>HN>nt?d+&??]RK.=l\^?=BC?:g/=p;?EI>E?6>*$>?C?@>T{d#0>y`>* xֿ[Q>r<>}h%h ,?=o!ݞ?B.r8?T 9]4=?o]f>Zq=V?0N?/ ?L>ھ)ИtZ>?BT=`=>,0<9Mߠ=J` "j>Ⱦ¾2Կ-? ?i}>#¿`?7 d?-?>H>Rͼg ?ʿ %n?-^윽|O v >l=椿@Z2^SW>&v>+&=?Xٿ00I9s>m?d??c=`+h>z%=o ?qn#=Hl2OZb =XBo>AnF:g ?{>A?^z*?j?"Nl>>:$=ײS+F>=? ?Y?.O ?,,?Ҿ׿DoT?i,?iȿ(Gd?-Mz?@>yIt>gZ>9p?o=$@= ?c4<0/$,?>h}-}6bH^o?6첽0+6cоvV`?rWfc?>nü]u??lY>޿ ?\^?R>+_;>8hD?%īݿL?j>߀?[g?lj?߾eU?+uH>"'F?> ?mq?>)U? >?=>.r? A >s8>U:g:->?U)?Z~HZܿx?>CԾ)?)?F?]?돾ڣR=? > "mG=h>Ylh,"];?藺ُbz^?zJ&L>Gx?^f?;^@d>Ҫ=eu>c?N֎<<>BDr>T$|?c=>>.񌾯>t ==â@?>ϾL?c>V?^Ul?? |>d=־᥍>GDz8\ 3@վkZÃBsؾܿ5h?-i "?\PP? p?8G>ǻo>;*>}>:0h>P`ڿ#)!ѿk?>oH]?6$d??n׿'*)=14޿ۃ 0.AE?1K?D˿p-8(7?E?:?=?\!&⾠M?5/?R*߾`*?r3>d?8^(R{Vhʄ>k>?@WL7gT?Y2?c)<\rx? fc?qs?Wʿv`nJGK-bZ>]>?þO?PaDK)nw[>`Ά1@>{N>H>x<>NQb>6>I ο;q@yRʽ k_0\sO>S<ƿ=xon>^?=adtPa࿒yHu>ܾ?zz>& T>J?Sk>9kH>U%dw@>ȱ;J>Oe?wG%,v!:=qk|b>KH?q?>$=t>D_:I6{=jo<:вxGP-?i4@f&?a>Xu\|GW?B&>>`T=4?p*,7, ?X^>՛?o_>é>ԉ?!@?Ge?u1ʿ0(i!;x? n7+ @"?_q>k>>R>q ?cŽЀ?;*۶=9a(?EX)?V_0?&jsg?ubwLx??Y 9xKl'ح?w?7нau^H>?.`hҿ9tVϾU??b"-=?" ?>:)>]RŐ?=yL?ɗQ?j{>?;pѾ8= [$ բ=D=vj>ߘƿ?Ѧ> >/̿^H?}ip?'&>{+B=>Kv>k>uֶ22Į>0T>Hn2fpQNW>r>#>?xӾ>??iB᜾F?FhbK?r=nIq >>b"MsZ>0R?~?cT{>xC>qP?T5ȭ=s`?ŝ? `YȿN?p)bL7hnb=?]>=^𿉱O'k'=+pn/='?>N*#J>7Dķ>6$,>n:@<DŽZd<`?$?w ?`,YԾAƿ.ߕCW>On>Bw>Z2t>¾?q`?V?#qfYd?\q?=./dl$?l޼qz?o9{%|V<|N֮? U}Tt@=Mx>̿*ۿ?'k >R.6=v(J>>S.?㜿|v|JHӾmm7x?%>?-^C=v?M?φ?fk)h E?QNJ>r=5z?KZ*s9>G=DVC? ? &3?Y=:־ᔆ}i6a?"&B>×?>?I>ʎ ӾᾩшT.Z? >i :>:ltѝs ^ >VlH>>@>ء>GpIKo1=(mǎ>4>P? ޔ=X <>t86>⢿>fŪiԲ?ffW>Z="k?i>e?,_'?g?'n>ҟv>>?2^?s<>"lX=|=d!S?\mN>*rV=` ? @?l2O:z8%Ub\$)ڿ5>m==xx>->>z,~>>Ȧx??6ؾ1M>?oH>ͿI>S5T:>-h>k|?-``Cp>=8оѕ?/C=bד?>I=J?ע>>b?aqL?`>۫>?: UQLڿ`>ƽ^?z=_$>#>$0:?8o =B!c _?Ӆ??/t?7Ͽ| >)໊?.?^|NLN?7"?-:>7F>ľ#b)W>?|?I?l羻>UkF3E?<n>>:Y.=n齊?>i??&@>??Tրbֿyv5=Ol݀?r>p6J;( 8?[T> => q?uK?h! ?r>!-8RҼ}?G>B5? 9>mqh?93nk>f24TsOVॿo5?cx>w>>$?<궿?$@>9>,=?MX(?8?^>Ik?6?}>uVI=͑佥J|>\̿Ƚp?C?lv>BcIhX>x?L>U>>ʦBvW|?7Wn`ɿ%+?N >xl˾`?*X1a?>sDepM?m AU?߿!&0:=e?7[}žUb.?޴= sM"K_?>T?!e\ARܼW09aU x=>oYξ>\ƿ-wؔ? ?XW?[>uZ>? d?&=@1>N/wR2&??CG>InF>?$?P?+t־c$p> ϯ(?IJF_Mq= ?$?-J?<ο/EK??҃ ^93?"|?Ln>o?q5۾zh4ǿ@쩾L4>vUGB6>?B?U?ֿkο?4RO4p#8?UH4 xf>;B?MM* L#RѼ?2> Ls>.,Y ?5a3y>0hnsJF?D6r?&>FNC4]>BY=hф?>$eaD>:r=?VܿzN>O>? l<>D[8">(%?=y!/}=? AhB> , H>_=>*_*=_ t@S?#i0F?n 2 Et0?e?k*'>ˠ?0Q}|ks??[3R}FڀT?as?n?%J>->=ń[>A>`g J2?>@?}?60IPV~vAgA SJvjz%”mVĝ.$;&@ B9JAȓB\BAEBS.$݄BGnAoBEBC kBBB36:«BAV ^v)~'4wº·¼A°X¯,Z@˜e15A7Ѻ:>V6VŸ A4,؋©v1 ‘A«n _BioqB !BT-¡* <#뿕 AR~*mBdЏyrA"t(n[^@/w s6#Ş:vA_LXB"V ³X!Y:v'Wl`fBWC0B?^A/BHjya@P%iipJߑuA8B~BX@AV»BF€.“GaAbbAUz}r@0=<8 $ U›8"@e0r•¾LBf=<‡D& _B'Aem@`@Au@7BnB9BB)A=@tB}D-z7!‹œGS´E†2#v.qPw~ !B-¯[…AOAkgcV11BteBPU‹G!AviŦ:-²BRBh4x¦t0\B'B™®"(„§m’*vl*AG’†5na@RT6@A"AWBA`+A &F²KFhA)p*lBŽHBhBz†oA0‡³BLQV86B$B˥A.BKyB0Bw A'@8¡AB$BI(4 ^BggkABCѸByBA_ȧAR3jZBB=.zW(¿ Bܛ B0¤B«­S4AcªB ' ?/€ {n޶·?SBSBwQxi\fkH.2!$AGT4HuZB /W•~ZOMBo>X]j1¥ ( @lBi‘:œ^-* L@3@.BKA%lZB -jJch†>Q!@B #Aw¯ ;ܡ3JhF„`TAαn«r¯01i[* f#K`„;DAk/eB!mAjA{TaoAo'(@v&2iA>R7G)czej*B`A`Bp`B̛2'+B.skbDžJB@<+Bt"B}Yn†2 9,1<ݯ(¸tP“ƋA#f¦PA1]dAP@Wº>N ¹hiU{~Œ]9-c$¿(<&(¬ҏ`,BB/H:@ D¥![mrž+{rN¥bqj.T7)bCq"BpC )B3B0Bfl0BO6B#Eq¾*oRв۩N"b©¡a ¥T'IiiމVArB63%Adµ=BLZU¦Tq@B|6œ*BHBA&dAөof*{*B_\„+{U5[A\ª (&|…,_8-Sh]uH>2ŸK ^Rv3qޏ§e†DDkH@UM1mxBL`w4‘JdvlAd4j1\‰Zx·,‡Z¿>H[”r"f.w˂š:@‘ª+ۻ4`$ ~'$rNa Sœ «y¨Մ;yep«\ R—)/0/?sy*X7 ^r‰.ovӘB |B_ B|AcB2xA;kBjAB6BpCHBSGCIVCEAڸ‹{I&B9 9DEQfA!~Bc?BBJBkBsGGBMAbBnleBppCZSk°x9d·ю\¹mִº"A޿{A6³t@D<’P8@|UP>@«x%ЎA¹g¥ˆuB$V½vYbTa?NgֻBt6B.@-DB *‰[BUŽ) n6h^ )BX2Aʹ§¯?@]„eAyCAVe~B=5A@n~BI?AVUCBBAA4B˴Bo[vgBgB&AB? \%AsB$ wwtwV£ABCH5ާd4u> '-^bgFF[csb($©XSm)ZB"TX BhA|&f *AxfmCxA5…U¬ (?LJ J5vd¤obkojVBH΃}.¡P~q‘ABƢkֺ,4^,–|BW>B1hB*CBRQBDKB;A͔4AmB2y2C=ABIBw?`ν:Cu?i ?F7?F{8^-?Bj?hoX,U?!`Z,? ?^?ޘ y >8:fԈ >T $>i~_(#S<,` +?0̞x;Lo>t?0T>c2a?}0@>i?&@.)?LE lh?ڼ9w7Z?=<~>'ׅD?vdt>r >W?+ySؽ~?A=c28? Z>YZ?Z?`Xr4>7?ƅ??]"?A4?B¿V޿es?;q>!1Z>"h޿-^||L%F>_笿&>a?.l.r%8j>>#D?6N>kX>"7UDt?6՛nZ>K_=ȜĽe@?b-ʽz#@m~>@==>B~?ϥ?S?R:?+? Z>7D?YoN>5*>L>cr>Խ*>?k2 >俄Q%? s?`_? =`ƿfo>Y {}}YA$ps߿2;>c346]>F=?f>;m>FA]=ݘM?0> ?xP?n<W?.Q? p41>V??P?DD=^>]>zȿ[?$&D=='ʿy>NxC?>? |=j?\OԿ۬?.c$=<>Tr?b=-?e?qHR=óȽy7& 98Ҟ?7(H?1?+? V ?$??K?bDο(=?c >Q>-Sę= ?4~>8?b>ؠ|>iоb)=^ECH?E_B}>vZx)w5?6=T-;E?P<٪P2pf??/gn>BѽYw}b>.>B=>fȦ>zPIZ>Խ3o똾 ł>OпTL>W<`> >?N=3?=YW d>"}=no?ߣ?Qzd2"=9?Fֿ#>g=>z>?5K>YC4>>N;fn? ?>R~b>Q?ۿv>6UhnC[">g?judsh[>?4??=?›>?>i>MDqOH|f?"I@?[ֿ]q">}>ŝW /w'=ts,J?GV=gGмhaz>p?P@>>?lc:C=羦 >y,)>᧿Q9?z?0v==?2=>+`>{2deO>^>iS D>D5-B#O 5y> BIa3;X?>w?>b>-@ӌ?K+?=|D:4>Kf>V?@pbBb?郥?x?oA_yO?2y4>y=/`>q޿b?'?A>;>D?\g>8Ⱦ6VJ$笾oHbOl>~?T^d_%=?}M? .hjJS!(?EпC?+#?y GU@>Y<m?2ҽ tP07>T?o=3=4?<+?kS /0? =4dGPh{7m>\־25ܽvz? p=Hp?[>|r|?YJ==(?f?ީQ?K!?Ɓ v>keҽvx>u?> ?Ph >d?C>p6?w?S0? X>ȣEaS? p CǾT>}Ͽ2?/= 6>.>>?0Ժ>Nb?.>  @=*H꣠>;:?%>bNh۲4=o.b>~l28dV>0=g.dX=>{]>H#1cؿo>"N(>BN]?Qj=>ҶŒ:>S >g4>Z^k?&[>Q"< !(a>apL>L>>,8>T?V?q>+ʿ Pz;Ⱦ þ#?ǡ㒿 >?J?*U.?u =k(??L(23?l3Lj1aj>mܿS6>*<>e>-8?U?^Rh(?-2;eu`5??+\>D !( >$>8 >B>R>K5=>0>Ӏ >B?5?t?>Ĕ,/ K>u?u(> >?kνzl$6>*y=u>'^쾇>,OT>٧>{?^fo=aob>{BP?Œ>`J= q垈?ZL?!6h?A=2¾ȵx>X"P^!3?~-M(:}? &$5>9<>RrU>?qe>^ڭ>ȟm7>!]=،e>9>.̎=>,h%vCz6?tq?YT?? jImܪ??v~?"?|?[ѪQzp XD?>6H?< > >Ԡ? |? =8?zV>{N?@? >?6TVL`.x=o\t*5>{ֿt[>&b>>Og>U=YT>>rg>~j^?3Q@}D%399`~/?=?Vt>VʿUH4>85gRNqmZ?k>D>?-)۾}?yVB?cV??y?Ain?j?gj?bP>f;À?N|UCko?$>P??\fi6(?բ?`{q ; ? i>9>d޾nPN>΍2 ݹ?t>>ݼ3@?/|Z?_=K\?8W־T*?7@=? ?uR>8!:r06?kH_+ݿ S>(>4?ʾ 0y=hϲ>{~\>>f9{>t?8?`8>C??,O>?]+=>g~?t;gd罿?1?]4H\5_??i?dmt>">U> 뾓>B"i1[? R^(: .>U,?_kQ>P?T?GFq$k*l/?:&{?>¶>K>:>R?>R~b <??]j?@+?KtuP>SY:}D>k@?"?Կ`vKx1??_F?rt >$O>!O?ۿ6WiO?۝H?NZ?+?ۭv;lf0i? 7@?=>/3^ԣQ>$?/㿥{r@sB<=|dP"=d> C>]*=U ==~1X[~NR`|?Q>a>j8~g# oI>m?Dh_gH>p? `2?Ъjy>@{>(J>\1 M?Qڹ?bN?2I=7>>R즿$ȿ> I>Ev6Z?9P~>l?)Y>kP >ťݾk?%I_x]6;==>>p? (>ʌ ? ]>BBz=nQM>b[>s=>h>i @>䨿L>(y?2GVn>N>N?V>?S>s?:Azs¿/>ZI dz>3Z%> >⊼B?"q' c4Fk*` @t?C?KBP^r2H.?*|=6>+>sػ?W?h?\>}>9P>=l-W?\>%M>E?V;q̀?4?!?4U8ӾV+).pz?rzAd$'?8>\Z>2˾w @>=P>b$>?tu0?`?ㅿl ?Y>'5Ŀ4 ½6ξ݉?%=d#8j?'|C?_x>K? ?mM?p?xS$5{j?ß~;@*n!ҽ| ̿1э>K ֗x?5c_"t>!|.Cܿ>^~>(>i?yP=MBYr?L?!j) y~"ʾ?#ߐT?'R6:?n= 2(5\G{ܽ򨰿: ޾'=?ܐ:&>:p[> ?E>2[<H>=H>4>(;p?{b?$?Bgs>`+?g%@>$z47 Y?¦?=a>L(we?!¿Ἲ<{Xw`>9 I>Ur??;yIiоvmqhz>_|%%0Jg=h>LfZT> >0?I?0r9X?`,?o(>Lx=coq,S?Qw>ؠ>9?Y?z P>i"MVo=?J?4S{1[HӅ&[6? ?;?48=Ih* !"ҥ>+{>̆V?b ;Z?R {钽x?N*J>K߾<=G?:F?U>g?e>l)p>C# -;>-1>蜿*?x.|0)M5edn ? z>wXBl$p>{$>H??> }^?!Ⱦ??N5?p;VҿM>v ;ehҾ fdɢ?ׇ?믚> b$U?*(6z?]>־n= ~ U2SO>40$==x>0R\ ???(7>>.>0?hYtTO?Ed?09J>3J%q])2>€>yqI?Ϫ>$P2Fi>?[oK%A>U! x?Wd3ŵ>>h1l]p ??+MB?J> pj,n" >J?)@\?$nTj ?P$5sv=?Ͽ{Ke̔=Lx1?p[?nR?& x>W| Pi?z?lĽixO>m¨=b񀽂t?DḰؾB=KA>ٛ3?m!Z@ae'`FJB>⾧۾%V9:>P?̯>`B>P?TMPa?i5=&X"M> ,3O >IH?f?̾^>kj?C \>?Yy?h3?7]=j <0P?/#yݿ ܿ 78>6˓>H?Ex>b$_οp^>r?Cܬ?R,LF>7d#=>xw?A𽑩>>m>H>CP?LyſpG%d<% ?X߻cv̼@0?;No+R=Ů(?6i?Kݦ"6$JCc8@>3GZ?)?#>@\? >A5~?F4?/࿟_c>YR?-Ej>!\?f>cK0=tҿG^n8?ʷV30> Ŀ1#n {xF=qy?.#a9Q|پV=-hl[Hm?^Iu>문? Bp׾J^>]?;+jMhzz>0h\?2>s蓽?JP= `>i޾d?,"4>Xb?/[8>T$?D+?Mؾ-a?B>f(>9,B?p d6R>>>DĿ?\-͖6W S??W>4N=o??#? >Iof=F־P?>ൿ`—VtaZB?Ͻ?Ę>Fi+eX]]>s>ô|Z`?vC>dVC2?9(t?{<{Ό>U0,%ؿMھ+o?RJ.?2 F>>¾P&X̿,?]_>d l~32?5?5J=>`V<*`HӼSr!t6=EH>1/~??T?v'վ*LZ@4r?%?*ſvW~|?>?`SN>Cj ?GűQz,Ӿqܽ志DPN>Q=G04xv`kΘWI(j?0{D>ET>:V=?"u2=}prP>pZ?,@?W0^?fQ?Fɾ>>>G?t PHan>5T?ND?> d<}X?4'7h?xr>`-~q}k?V?7U>=D>J#?y=T>.?"XBc )>mynv4>>h?d>6>C>0Ù>?C4e?6ߙ A?gdf?>'93n΍JIC75zj.A*ŠAA{Oz2(!A Qv@޵WBӜ0vƒw@$@ADB7>WµߋB`ò| gwADEZ="ۦBBsb lAkABBĶnA5_zA-Axj ś~B'?@AP5!O©:B3bAᏖBC ?AZBET@C ƒK IABnB:YHBSVBPUdA-f4 A$B %AIXFE~:AyBj4(Ba\B4B>YAoBC Cp)qAzBB7nA3BcB} B2^AKBlY —c@>)3AQhA_pBFi-A~ABq P ?B g¼ gկ2ޙÉza,nVhµjp@A.BJދAMAu]QBrB_BO>z@AB%A>B>C; Be SB%%°MޮA*Ac#@l BHTx’@=1BfGB@@BӼ )lB@ҦKBLB?"zABL(\A ©xB]Bo_ܣAUBoB^B B$OB Z6C_lA{h³BA @'Kš4’ BUxˆ!BF&BҚBܨB*•#`1ABmByL T: \BHߦB$B0AF„x¼I1KAKA:BCBiB>BBkB|AC]BtlfYARlB)5\BH {AÎCGB%nCOBȶB,*B BEBzB˩CB @BqBNl^BZ2A8#B,C /B,HB ?AnBMoB0BA XBAƪBlB&B[BBxVB:UBj dBM"A7B0U)BD;B2?A*BB cBRB,CB:ByCt@jhBS "B\ABx~AB CB̓BP{B2¿u^°AgA%rq(BA*B.}v@af*ABWBhBzkB}rDɢB Qˆ7e"B2BLkA*j?&BZcB>#AƏ[LBSAQTAuE6@'cBuBJBB AcB̢B aA OM_;4@be.3Qc~+ BƘ?A>Bxiu@YD_kHF}A,¸l:A!®@BcB-A*BoB\tB]$BW‰յBьB CB_C,TC dB^B<0BRCCwBAw{bA BzBB]BJļlBEHA&ACt'BB,BBhA| B]B$vCdB}C6 BSA.NBR}dBkY|£p@4xkrJ%8c؎AgŸ2 nE?ұH?S-»tFftAT|MBЏRFaA+9iNRhXe]@"@um+ŠAʯª$¬Gi BK2YHB BsB+T`BAZb)B?.3?J­Jªx@qs0A⧂A1AY@8.ª†cHQtT–\žA젶KBByBBhBÒaB!AсB:B\BZC0ZgC$ClC"FDB¢C3BVBXC{hBO(`kByBB&BCWB3BB8B.8dB@xBjC C/N@BPA0KwX BD(BgPAK`‰hGOB˴—Ba›reBXC &A,B {BrBBqABq&YBBJ =P5o\(BB5VBABHbA*bC"@IBBfA.rA7’*砠BәXž¶gABݻxBXBBAmAFEBK#AڑhƒAP>A …~tJ`¦s¹/A5q¯>:@[JEJ ŽcbxxB"C!CCC?BAHRBj!2gBBlB8A BB1Aͩnf"e]AV|AK8DBa<@ځAŌc@A ‰ ݬ@ifok BBsnB8YBY9\Bu͠A0Bh͘.QBN B0uAA*2 8b@|»#|xLŒ=¼'Y1XwH“L’+v0A<º+%AWFAUA"k0D5?4r^A!RB2qA-ߓ9"Bw3BBDBBOAGB3B_(BICIAjA7?B VBF`A@сA>΋Ld ?3B M(@hA1S*z?\B+q« AAI8q‰N |Ag‘B'.BT~}’aZA;§0{/%tLzFC %BЄB׮HBhXAaBlB,,AaB,VBACLxBOB|BB"AC1j · &±rBXI6]B>‹;/‚EBMB(1IB@aEB2B"AB|BN?Ež`-NHxA]B˿ʲJ;RUXBABC AU1œBD?^@5B$JBQ ӘqF!AXBMCӠ;jTۼB@:BvB9º^A/~C ^^.)AoAchbB½sAl,WJBB,BQZBAByвtƒ(Az,k5@{,eNAo AtB@BǐCnBuBaA~BLA¢B0|EB;?k#@oB:¢kDJAѨŠ}B@ 7"BejD0NLgBX3@`_$– zxƒ?„K;lBT B@gB_BBo-UA"*MzbB ByAbRi@aP»3WA=B £=B^it Bg_.)B(GBMA BѤBn]frB?BEB*w.Z A&|?B_11AB Bj^B-A~$B3dA(I#.^’`?\;Х5B'Buy #}B‡*Ǭ8BdB A£n¢¦6,dB޽@SBMAoB^:/@*exxAc APB_6;B¾ر5ebyyBţvA8Ѥ—=BҘ2^$x@l&?!6>tͨk%>E>ixB'5q?6hh?Xe=u]=f"?'%>-v->Q澀Cu)忿#7>mT]??+L蒾?ݿw6>8?<01~?*?4v>:>p;7RȾ9KSAuɫ<~?>0W>*>%]?~ 5p=`J4J>>$O=_;{?W˽>辪"łR$Z?Ҹ@mz|?x ? J¾`B=Ď>X>D~?/Vtp?? jlBp>J=ʠ>LUgʿ˿5w.>$>_>>`8"u?!mD>Tuڿf|xE0"L t?>h?A &?9??L?mh?D% 8މV?16L?z̿gSv>Њ6'?zP?c= $?Ty?>S>`>B?2_?>dP;JK>\d:=7=><> Vqсs??B???)== />4V] pw=Nhn<4'? 1?a$6>(?ieھ1xƾ"d|<=Ԛ]'>vf=?" ܤxy?տ3>A?xLQ`ʾ?4n e}n>ā}?EQ???*z|@|Rø0<8=?[^Z.o?XR>= eө>>)l6?!>?v!cc=;?:,>2e?+7<@?1\-&>Djy=6אQ??B?+?Ld},Jb?f>*ؿ7aL>ƺ@xǚʿ>R?~?>sZ>=?b`R>??wW%?->?I2?%X|Q=AD,=T?l=i|>V dTĔ?2jAJ? ,b@]p欿Y>jb@?F1>e>"S??*>A?< [|>U=۾u9g3 ܽVF? Vҿ"?>О<?4C`x?1V?,>$cD@ПAζ?2U??LbWN? 2];?4j>_= 6>'?<)>V׾. #϶>#K^5=`e? w@? >h?X3>һä@>⍿cZ5"GVw?}m>޺jA>N>i?h0*>ŷc6¼d?ɜ;E>D?r侂~?Sb?vS?8޿Y" ?H?5<=t¾$&?P-?3j=R(>$>?ھ@"?:i㨿H"ܾ8??[܊??{g ?e?i'>n0\|>}hH>`Azj\.?B>>a4ҾPq?fB-?Z?@{?"\rת!na44K? p>>r?$ɥ>T-?JS;ҀB??_i??L۹7Bn?M?8?w5轞|)ؿ-苿$>>ϤH?q? v?<֘!"D1L}>ݙ? ? '?&) Ch[>j;"?1^ֿ ">>zM?W$5P&>L?1 &?X9?>B߿N?' >?(׾̾8O!>'̿=J[>r+A>? =FXd>=>Q8z>>?@W-UN??Eп_?p#?P?>?Qb9` >?W/tj]?=4|\;d>,¾,p>0!_e?F>ʞ?WQ4 ? d>-:H?<+>Ot>^?K>Zs7K>Ţ>&-?zU>Ãd=1%4G?'i"??hy=<٨?>$=ϟ?h>Qپn>@j8="L>U J!D?>bԗ1=PB>yX?T=t>ް>^)t>ȯ>Z2>JzZċ]Ͼ8?6knLBþǘ>%;+>P?߃=<?| ?>r=Vx?f?x=6>85Gihξ;<>#X>" r?,T>; v=E4=o$=??@? >?n>M>&?!:_ =clӊ>4ֿYJ=7?,|?!%*n>`1xF15?,ƽN{?5?>XD?+xY=F0c8p6Xَa>wݹ>7ܦ=|?v>b> boX ãY=ƛ=?H1HP4>ei(>&8 >=>@?C?R>;U%>5E?mz=&oD?ĿD>,B!g߼ ?=4b?V=GȶLT͌?=>wj?{;ֿh__d?ar=G?.>l?m=Y>]BXE% ?>ϸ*[tc=b̸z=ku{> h?B^??1$b0˷=c?!?>:|?톙(> j-R>nپ@PW@ƊUEȿF? ->4>b5x|};T(߾7Ja:?g 9HMu>?q9?D>S?~I ?n?? n>=>UcԿ.?j]οgWT`I?Z?Z?=?.2#%`t2a?c,>ȽMH>t?F>?%UqD?} t?oO>NZ>B?&=, QBFti/7&Q?=hH!dSLjE?+N b}Qr6=L \?wO6> q2R@}?ѸUн@y>n2Q-->?i`?L)H>纾8Is?c~ >3Ⱦ?F7U /=L?#ہK*?>I>}8V>f??C4#ž>?tG?.(h?g~=hؿ >Y~WgS-5 ?qRr>>?8_@ 0?I<%@3 wi=> zN[c>)? Ġ?\@"?*`2">?V =K(?4'?ck>,>ǿޕJ? ">K:%>nq?bs?>m*<?QQ>H>\?mVT>`X$=;辄>}X>$R=İ=$Xp< G[h>=p](=y?>f?]Y_1EB<x$L/ޚD*a>?45"</`8}?CBp*;Aȿ-X.mCÜN 7G2?0:ҿ,.Ow:N>:"Ez?^#=dr?-?w>;\<6>,IB>l$' 0r=>}y?3unU5>e?_2 v?{h?L>-v.8r$F=L B<*p(]Pxk\>gH4?1m?^>$Ջ?>i׊L#rz 8?.qBL?< ?S:?C>?MiпU4ؿ!Կ?A鯾_x>?4=E\?!)=?4? >R6?>Yr!$A?32!*>BX\]N?$=ۅ?$=>d?'~x:41Mҩ@>:1ȅX=|pپϲ?"LK̮D?W1?S*X?cVbwP$D=+>Tož >~?W>>\?J]?wM ~?yFq2up=u`?8?C y;h?%O;?4>>F(ƽ37E28y1?.>?@sr?>ƾFc eghT? N`ֿ# m>?y?\s6??= `F7e f? ,>4 4A?]&>?1?? ؾ٢7) ?x߾q)f?$>6 g>\TὭ>T^ؽ>=w >p>Տ?|?h>B̿;;>BϪpo6?F>.j-=,?}M7~f޾̦>4y>?9>:?>.@>ܨ?t&ؾܸT?$^f?<@%FWD1Ӏ>S׿wZ.?|=]u;.Kw?g'7?BL??Aù>w5>N+i+3? gV>J?4A+=6?WI>`|: =Z>Y#?(oԿ >)ξ ;(>@?Osb>"̈́=ܾp~? >-5R#+?ut8}?D>F>?#w%hrj=>ڿ?k!a4?@J?b$?F3>g=$,>s?iS?24bZy?J?;Us?оEa<>TeN6>}T>t>BM?(4?^.zn<>J8?HMXd?^=;?qq?ֿ$Ǽc?>wH=!hH>(>g<ʾZNnK>Vnͮ ¿ G?p2>3?=n>'ĭ?,@lYJ#W%z>T=D ? J1>Í>9@@ο&@?Bмxkfu,x[?y?pPwNڿbM]q.?p3tL7}eR+7>⾉}?s}vx Ұ׳?4?+g?Q6>ݐ?>͎?dO(`̾o־A̿O(*?w?V$2?A>cwH>>Q>D\> h>e><*>ϰ>n*=0DPm5Y>߳>;z>l?h:>OT~>[վء{>3.UM" Z֧>>$.?~'??\b<>>?ePڿ-Ѧ>\0 |B?WrH޾DW?>8Z(?-?Z>-` >u?>C-?+9&?. >H>ҏ=6ƿ44> ?+?ï=,g5?hl?]?j0?k?\?6$?y*I ?%;:z>?S7Z*at?ȽQ̽3!zT;0?cIC>YhT>S^<@O݈= ?u&a=P{ ??f>'=Ö1su>*M~>F? aSrZ>@>B??? v?[i?/y=>1Ҏ?z?->m"=[nĀ8<P.v>`!ry@

    ӿ'.:>h)>?pG?}>b>5?`|=u@>Y߾]>+tbK>\>CľF&p? H?牾L>>>CZԸC1J?>)d>\?c>Ќ0? JV?a&>\?=n>Pc?id׾Ybה>b'?3>HZJ"S ?j!>n$@V8( ?,z>j:6$=>!(>h=?p.>7N>\?潮⽙ܦ氾庾N?"('= p?Ҳ>.=?egY'>b}?hv><`&|?Nܖ>͚cŶo=u>h??O.>Ym>h*=X@寃>n7N{? Z \ND> E4?wnrԿfG??Y:.~?O{l?Oڿ@,S??=оυzql?`%>dQ>{\㜔>.0>1ʽh >,?Wÿ=6g>b?t_#Ɯ$ 樾qҿ?>p0Q>+&墾T?HE?!?Qoӯ=[>cK?*KE=aAl4>>P{?hǠ/pRKܾƾx>6V#BCӲ?*?GqZ"&r?:xn= >!%N?m?,>FST?f=ԾT ?,X??G>-?h=1?$dྈeR?O?X? =f`?*Y?D>pa&ѓD;?a?/L?ENؿvx>vVJ:H,XT=? H?j ?Ԉ??8>䀿qf?(X?"D? =/JLܾv[?/z?>vξod$d(gYBj=Zɝ¥:¬#!BjB@_GBBhxB *ƿ&%qA1b1p3@½ ^B_2Z6A!UB AFkBBBA؎6@WBG BK~BC?@“AAa#dU^R oPtӞ0>9B7@t֦R !G-I\jer¼>܁+P>TB|T‹bL%g}…i Y~.!AzBcB%_B"+]xLxB}$¢J}BPBB֥BqzBl"GB C lABHB둪C2LCeB܉2nA„L_`A>f@@uAM&tnB.B2BN90BIB QAǥ/BN§%BkBu B@ EHBUnBThA9B°Bƒ_? BBTk~>AJBϖXB“A=4B{ A|BoN@AP(31(B*i Ac76ʶQtBR}5W¦2A TB1BuBچABv$AW@?`y~@K"B6$, ASc|eFW DBE3:PAO1AE&cEWG\)%BB`BBWŽPl}AMnBg)rAˆ$TmUv´{KB= A. @^>[ (ʪ&ԝd+TW$=B`‹rAEBsB{B®^?n3–TĀB۹+™<_5œ…B%>܊Btg`B"BȗQdA ¤,1l!i`mAhAőnAU( BAU=bB-)•;B)A@^S— \f0e% 8ŐBˆygrB8BcBy#BwA)f^tA,C*.AG!AroB2.B|YB}0B 4B밦<„ T¦8v&(s6j^eJ6e[A8µ_Z—EzA@#ü˜h“ѼA20@$€,.JmD"@{%7B,,[H砦`#zBZ9s­Lk‰S»7t™#so@xA`º%6WY~4A¡A@A|p@bA;<͆•~ˉ _B uH$Bnwo¡I&+š7”%Ւ"@-A%¾4'B<AlvƒwD@9˨3A ŒA\iBiA8"TAPۖ]^±?FvC 7Y^= ^BǷBsBE;.@GQ%l?&¦BQ n€AtBMCb&B67Y}?xph'º G=ݗ/<ſh?>3?\>.H?" B$=3>`?]/>N>'&oϿ`ѿ'b!:b>L7&><? n"=ֈǿS?ӄ>T ?3ʿp}?%'nGŖoԾ>>8mֿF8<Ѭ?ƌ?E>ZCW>AT=2Dev?JQ*ؽc?=NcǾplr&r?h/1?L׍1󞾨1?-.><6<2@/3?Q?j?s>?6 ?JPx`uG= L ?3><>>J>6="C, >iDEl?A:jF?X>،Н?(?L[T,ҿ>5,2>;>> jnR ?Ax>NE*UЪ>;E?nH?UT->@E߆ЭY' ? 6>tֿ"M>R¾ K}8C8?kSU>DCt?N?H|>Ŧ?kq>ɱ #G???\?^>I>x>d"w=j@:>?3F>I^?t>Ig>.o>ic?S=H, ?`rp?x}}zt=D=0>X%EBͿ=>餽AT?<>N>/>3X>½=>NAS \;mÊ>=6?y?J??0?ξƌ??B=%4?*>=@?jy6O~>J ?Qw{6H>࿕ؽ?$#?WS>`eXP<>.?oXVRm0?~ʹ /=<>->Ҳ?20>k =,ؽMؾf>[#@ ?fkU!>yb??/Cx!|Ϙ?aN?䜾LV=Ʈ?vxXh?:v>0?(쾖yx8>0=y7?,A)>:PLܿƿ H?P@?>H$οIaQK|<>6?€??>Ե>,TJm> uk>??,?Ե߾X;@@>ԣ?[>4V>/?E"?1qM?=Q=,ɰT?wF&e?JO>l?|b522N?"?}Ŀh=-?ۯ ?T>ϗ? ▾=?/?c >&6n@>?S&ڽ9RVNŘ &??7?8g[wD? ?F ?=>lL?$Ӊ?At>+?T?`?O3r?@=Xm ? ,4h>Ȭ=X>Ԕ>C(>ͯN ?,K@? >ց~WTѾBZ<}pk½4?kGi<4Wj?t>TTr>;7?+9?rǚ>ϩ.>Eؿ7> >A?( C@߿@ZBؿ 1"K?t'>":vbbD=ؿ@j?.x< cvL~= >bS1Q(K׶$>@><1#?'E?RΟ|޽t=_mV⾙F|4]> EXh4?Ҹ?=drxvxA?&Wp?M|2~;>?$(xq>2rT((:-|>쁿J;>x?>ai;?a-7.>y>~=:?&y(>_e>,u?(1ejm??:^?)X~?RֿZn>$>{?ju->+>-NcMOؾ&}skq>N?0D?'>ꘛuV?4?8(=>? E?KxJJV'~$]¿>?4}`>?CPj> q>:"^񀪿A-꿎r?|?AHۿȑKNH*!6?GJ?2̳>)Sj>E?Of>/=>&?l??$:^ d? %?F>&NUWN?:m?6c?Ķ=`F0h3D8D?MvJ>K}XA'Q>\>>c>kDs>{V?*4"v>mW?ofȿ9=ؿ>@?ћ>?(p}@?F>pQ>h߻.6&>X\=Ͳ¾uR3Bl\>+LkY?,>*I>ܼTj(F>nK2#'THF? _t" !0"tDUJUĿG>g<( D>WDz@"b]> 8: zV?e߿B>?wbjѰ>>Ll?}C>W=D,?r A<9>ܿt6H_Lu0I>E>[V?,?U?K >> i?\?|{hXv!T*ϰvw=?zy&JZ=Ր?a?{P>i4\.Pf>3 ^S? Z>2sf뿋ɁH?(@xN?ͤ?d%I*+$>Ι3>Av8bSQ=*6?*@9}TT?Pkig+?3?x#>n>k迂-2XP?^n??L2oGOk>N>"q_>ͨ?jt?Z_>w {$=#侱&>*.Ӻ`PTE3?-?q6oѼ>;>Y%>Ί?%>C>U?7x:ݧWU_>u D?? Ie}?>„z&Y>%#a>S?+$< T c >D>ў>oqz>u=d?st?lj̼8~?nV薾>0>Z>Ƚy=R-Ǿo?K?> o7?~~0>u\X>? eN@J>%>Y>Iׯy,W?-K|o j7=*<`??^42>W0Pϲ?1=X;ֿ1Nľs>?*>/=>HGz+d?d پg>a>4I(*JlU?K,>*?}?u?I>w=ڧp&ʾ6?@ {l'H>?MC=G؂7WfLeJ辣ONLm>?!=bx>>T.pn[->>wNP B-Y?Z v.?.>L0A%?~?L?Br> i@_ɟ?|%0?:_ͼ0>?O =uʌ?r =~O%B?%о3 ?z>ժ>>?p=$> QTzj-Z@‿C} =Ƿ >s~>ϸ۾?Ea=2?kͻ?ONY)c?g?aubZ>*}p41 HW࿞E6>('3?cW:?4>5=?59X0YVaѾ2?=t?=M>(@>mH<>l > ?2*>L>?8(H?<?-bZ>?*\g?4?ѽT9|>q&x?5&!??+>0~6B-T[]PX=H >>y@hҘ>B?%">ZP>G?0b?N?$ՔWܾVٓmK4>ldž~D>">qc9))@>S>;X`=oX?& <K.>Ssal$,?lUpg:> H,̞?.?_ϽLH= -:m>vx>J>>Zo?$*b?leZJ?n|=3>a6,?=0D=w<x>63޾Yդ?qm+ٿ?jZy Jvex(=?6?C^/>2|??L?1Z3?!ُ?Bd"Z>(>l?8jW?ބi:?,+3>ob>ܻ9 =΢ts/.¾3Jfl?^X? X??$mV>Vj>O=a ?+g?$rĈ?&X(#>B(=XFX?>1=^ i >>?[=={k'qiTj>{?P?6>`6N"0a tr>IȾ ~>?>Q?1\==D$+Z: ?~ᄿ=wW?cb=#H ǢL$>G?doN>?oǽ8 栽w>'?>_!)nƸV}~L?BS>0??t ^?JW>>_Ls?6I? E><>KB>?W綾D\?j2=퟼z+?`= ?Cq>LǿZ!W=F0?CS3>˴=lLg>Y?u),?:>꺿\FӿR>?$?i>c*>S< >pC]#Ae>E]ʿM>Hк>x;>I<}M?B>x==?E==sо_>|>P> D4? )=? ,=T>"<K>V=>]! >??jn2>_>H K>,~?[lGc>H*ľsEl?.~U$x;3@ djj;8>Cx4>! >uR>?sH?Y(?ѿ^?`>k>I=Pְ?YXr=W,3 ]51>ܼܳ="C?>:?¿C=I?w=t<>W)?"??z9X>L\òL?~<>+?p?C1?ܸV?&_ߔ> E>>y?rA>@ ?1-eƾ~dt=:Q=ۿ>F>u̾O? >?6> F~־Gj?v>O86M=Onɴ)v>=w ?R_?>x @ ʾa~ f >K6?P??}?vC?~3{>xA}={TPX?jbҾ?M?V7?o;> j>?D[]Q,>6x=? >&\?=?+*?D>KR3H>[8?>Q->?Lw;>|[d[??Q?&@:ƽS?j\l8.l?1~?@6P+?{5<$=sk@"N>®@ [HRS>Rg?@Φ?u=c ?XX.?I~?I?翹f}T'>=R?t?Y?3Ѷ>a >LzH=43M>>?V@ M7@?w}[? M??u4? l巐 XԿ&=,4@?:?~6Hv?@a>wV>>:\]0+X?_"L??*>^? B>>??.¿?.? +>S?Oʿۣ?X=v\ ?GH?R>ܾdA=r%t?6>>?4?y*?3;]?cs>g?.>(Y.?o꺾G}?K+?j?lYd?hԿBRƾV>|>?=`?X>{>j?u%~?*?>.;&>=`;@=!>>(11Q? I?Q?%?Sa7?ՠ<)>ϪIK@? >`X??m??>|a@ *;?dX;z>˳u?,b|>{D?C࿂ [?_9"?b%?s?.?%>ϟ׾:̿+?3U>?Ua?Cp(;O>#oB>V=âiG+`T=GھQ>.>jO>˦=?1>4z >?V@?,>hU>/#?/afZ?b?>\ s>m t?46=D6 8yK?-HT?ڨ?jNܿl?(t{?1q??a%?Kx>@?3?elz?ɹ>ډ>!D>">>?݊$wpgJ?DZOgؿ;A?+Ҕ?d?Lst>L>e D==P=N Nz?$=0?"R@޾ ?0}9)A4ҿ3u?%>AVN= "{"|>s|jt? ? 25??U*Z> ?t>ݿ92?ؿD[>?DD?BC?ū:>_-*u,ؿZ?G>>r GF>>>U@>y>Kڜ>,?zHP?AZ>Pj?s >Mr?x.i?E,?ʿ:f?(;(w:?C>>>6?1k?cqHVb>:?H<*?>վś?#>a i>' >e޾4&-?኿Trz?;=ʿ1`?Q榽o?ϥ%+>N|v"3?)p?-+?=Lh>>\V?D?>^?K뽅FxH`=ۿ!73?"P`?2o?b?z"=>&aН?D@=xiĿg8 :?s?v>?Pڻw]?h??1, !qԿ|>6V?'PC>QH?f?k>3"=c O>??-?Y=FҼ!?XS?!|D?[Aп7F>?Jq6=M?)%⮿VѿH`?q?FT?U$2=& d$?@L?PTxm)BBB g8?~AHB-hB’Bj`` X4*¬¥ȉ$+u‚,†]TB:vµsC8_n a7ַt·1\#ˇ³¸gBj,oUV稠½¾w‡lՑ€‰)'ܳѶvpA s$Q>S@Aש\f(5L †Hۑ‚l·š¯t0W³wBFzWBo4kXKtz ^‚A™8'njtq逶 W†~~#@2Tl?.iAW@Aqx慛Bi(*͟Ny7‚ò+BgD" ^BnB^ Bm4 x"B s@I*1\lAl))m„N@H6F0¬VМ:MbBU_B@1qq…w AwU .¯‚RO׶^ h~ Ai#(”f¬7©WBO_²FAMBd:@x6F\\i7BޯTœu•n6§/2Ax; Bx/@B@zBE[Y46BҔA{P`ASM0?X>'B›<['yͯ ʝ3۸H?\K?`AC;B d8BX4C#nBAaHBWB-GŠR>$B,AAo @_@L6PA sA BaBB˜BsA =Bp4JBCBj~BzpBB7ڸ(A:A}*xѮl@ B7BziHA@vBB1JUB D'@rB2HHA>9H˜P/"QB@/ "BslB,iCjBmA׌B CB/u"5p;Q`&߭BB[B ԊB4 COFBFAtB4} BB6 AПC aA i+B1YbBb:|A¨Y!¥VF®A,gClB^A/BŒ6@e漠›wAGEPfZ@\B‚B3tZLºa@vA31׿P8A9%JA@@B,@U¢mAqkAҾ§ B* C3w*?0[AA(vAB9vBe Ž"JA?f/rc^x,´*rή ˆ ¯2X¢Ӑ¥?9H7Ȇ2@跠B'PA†%n(=GBW@BVhB@M]T_-4@VM3BMCCBAX Bn8B/B5AC eA97HHҗq@37a0b;٧¬–®RAA«c@žWBYnOpTpu/~`ޜ“ZBiª-ƒTE¹/lQk尌¡͈•P3{13rP†rA3^?pJ+@'AA6&&9¯QXddAlouA BbK}A.AIB2èB\PA7PBw*\g¾BW |B«(;kA8AǾBz&C$BCCC CoCQY@FBlEB'C1BEB&B:B[(B2vCmc›PRByCE`BLBP;~…8EB=pB3:xB:C(CCBDC%{`t`?R0)¢B\*9AȷX/›•rA)ňBdBfA_"@b0'BȍB/Bn(@EPA:1pXBwAEB ^J 8Q‡9QeB(Cb[Bd?O@A͒BԂBzKB1չAQB?AW¸}L @mBT|NŒyIB@HBH6B ^B9œzvA|BsVBwB[BCBcB[AՉHB#n0AAjB(iA.AX[BP"A_xlAA[?=ID "W`JޣBE6BID)r(\USBs.`^BJ>09@(YA'w2lHRCkAA#\A4@ATA+BBe™d…)9XT e5?7/|EnkBA.0AnBZv3BvBDBnV, ?3Bʯ@BfE@yBG NA¤w 0b; jB€a|BdA69HA!BZA&B;: ?aV ?VW7BHnA/@E•JccFq»_¹%š@9L$: >=¶O#c9KLM|v>B6zV.t ¼stB M¤eBL/ BRdBȿBipQBHBNB*BBpYB;BB2:@}xB`A*)<>BcB>rAVA @=AgBﴎB6A%sB8BAeSCPiBHCKBzBB^HBWRB.A}Aʷ&/"=hx¯8BКB}®©_`w^ LBa,B"EY 2BZ/X Bc\:?B3BdB^u_3Ac`Q¦APyBBB$C=C7B~@BB&BpLAWBCgCBMCBBA'B+B&B>iB)B%@ABŽBP^ AΖ@BA¡k¯BJ AϖC9.*By`>C7`BȳC1 BB3 BB$*B1"BRAgB@,B@B(DBۢBF@"fA}z8¿EC4ioABfBlgpAlB(¦NKB, R(Bb]BQB"8BAhSJA`kBEBQAg2A:B&svC `BK e8^AsB oA?z$BBZBNB|BXAAzA=A`AlWk(FBQCB,^ªK?9LB^dBFS0کR\>Kw_@%v>NN=?8ꐾΐtV|\> .9@"7. >f>79>?B >)ཱྀ@?W>?{=H?">?j b*?"Rw?pNF?wDTd>r(?D,+B>#΂?Y>N/?}x?>8?ۿV>^>?.gkWC+.$7ru\?*??%?-ξp02 ?vv= >> :=DuE^?0=z쯿9\,==?@>>DG}[o;`>o>R>Df7Wپe)HFAp0j?#>&\?/ ?;?QB?h*J=<`P>=?WlvέkyTp?R' ?ZD@ܨf:?mX_>׿Aߔ?My?r*6>;/> U!">Sz{D(!;(?G??> ?0^"5>any*PX>ۛL>RJ?&k?7ϿD< z:œx=z\??? ?Пƞ*0]]K?*Cm*>E?4?N>ߗ@o>&fȃwre >?R?4?y}? '1P$3ɚ9$?nxx?[?e. >SML=Ϻ>ߪ/-J ѽ(?ʾ˽|?--">8>`w>[?h?T㽑?¤h=b ??:P>co>/v\?lZ``4>xoݜ? ??=Bq࿛˾!>;{>Fz?l91=`>$M[?z@x?K5Z>н&?#\?`lB>z?Dx=??>.O?#\>zx?v*?[Y>`^?%R,> >o㺂?$T>2+b5@,>KV(d?(>(2Ͽ )>I0?a>ʊ?׍5T?QdQ(eT$L7?>?6l傾>pL a3>?>2LD俖S?&$>>ҁ21A|HpN?:>ϥ&?+)0>#?.ǒ?OٖS+>>=#>H@>>=Ȣ ?v1??N>%?p#> ?zmȮ=?(XP{>2Wvl =+ ?±>VD'?~И?h#?&y(>qf:?mK?U&}2?o(6Z<>g3?Vd>a>FT?ζ.䡿WH٢D$Zb?>+>̴?>?Z:꾻>>pi0=x>?*a~L0?Sv?BBwF>18=XV?dɸ?f=ֹ@c> 3/>=h>r?*?Mۿ9lxpC &>ZU)X>?"~ )HM>pfx>??,>sO(I>b=E.(*?"H6i> ?J.>.=H? '\⾕%Y7>.|HG6>y>n?|a3?J">?LF?zޮ> '6?Y?} 6>V>G> ?jҾO6>l j>,>PU>(?2>D&?M=V ?>O? ?Y: zxþRmھ>=ܽ\tdPR >Ͷt V>Gp=)\?*w՚>y<?;?RtD (yd@? Z'@s?QL>p=n,~t?)}2f>uUAaMydA5>X?%7rb>˔>_?_??XJʾ~4>uÄ>M u?&^So}@?pͽpR>㲞*n?+ N8>̿ Ff>b>8,od?4޾ev@>;}nT>>?>W>=JSj_(>޿T?l?> 政b;x4?g!=S>~">RB?` vIҾ>r=ν{?k~:]?)?W?ae>?wf}L>j2S<>bed^^~>'?.E?^?/l,}־C;?CQxd>}<+*Lr͕y%xNhS?ٜi#? <>C˾AnvqPtmIk@WxݾS=Zr=>?D>?>u?VA6U?P?PԵb9T>=*UO?&p>;π>w ??bV?|]O!;C&L9`>>nܿ I?X[3 `,E<=俎?B?]f?f:cp0%b>07?Gcyk>X4 @F?3G@?־b?4=,>E >k > =7?2I=07<*?@/;#J>>r҄rWBKvۡg6 rǝg?<L5@ >TaW^c>pŭb8j?^ſ$>؊ M+os>j2?EE+^2?PKxO??sM>lrcp+Jt(ݞ =B>8 ?!e3?(~>H<&?6>ň=0?E<>>ױ ?Q/.|=6=sȾ?s>?W?A; tdtB#9>qPi>Bp F >)?tְ>d{h>?2TƾK>QM+]?vt>;?Vk>>|?~lG>4 ?O,?J1>`"?G?E?|ÿ,ؾ^LAd+D=D(\>n>?>?3@>a2?67>ԿǙ(ܿ'?oY>O>*>ἾI>?ˈ?(!>7$?ki==抿eſ4PĬi~ʿGǫ>[rY? =~SY`fn߾ϖ|;`1gp>?"E ?`> LƠM=??R 9־Wl?oOS|/=󐾝Kg쿃?i<"?s翋} >Jhr>Q>>D S<ֲоO?@kf[SZx>9=;> ??=S?U߾Anr??>t>8d=|o5(?*U 轕~=q>>>>& 0?6\ ,@Q?a~>҂?|?/???^_>-?/=ޘ?[?6 >>!9S4-L?4:㾴4=:A>?F%6r>h5?XӼ>$>m>Mn?{DJIĽ޸QfF>5??H?= Z?#>@?*??#?oh=P>П?H >{>9@=t>#=x?$>z>_D˷Tj?? >>r[ҿWByHĽr?Sz>>?#&}uY?nٳs"v޿Z 2={>?YTԪ?h>vfvZ>z>b>/'>$7SV̾oP <=?xĂ?eҤXp?e^?hcv?ģAFt>Ѿ-! X>[>ܓb? ^*M駿A Qs{ wr꾶̿E>&!>,佑>Ŀۤ? [{j ?#B'?A? ʿ .=(`)`>ކۿd>cZƾ(?w> ?)Njnn4oǨ~>,J?j?.>w?t=p_Uʾϳ ?r?p@{=$?@>5 ,?zgnsl2D<@?Y*?v@&o;L?Ͼ?)>0>B?X>īZH=:>r`f?xy>U?)>Œ@#;c?D>=">=ʜ=>U *(=5ܿEI-? ?=otW>N\o?=>5>(X>?t潸`?k? 2?`.?h>|J?`%j>$09Z:ݢ3`?j&>1>]?BA> ??3[j>> 80EI?.IDNmV?E =Dݹ9L?k>w>>+Z??,z>$XM;pf?s>,r`7"?>A>5Ծ:#cf> >є??F~‿m ̿]>Wg>?0?xF+6?N7 ?:ؾ$>%>fG>K;? >᳿>Y%+tG?,i?a?Ry,&˽;sBL><: >Z?>ؕ ⍿?$?6?wH?I?K2><xuFJLb>r:?HrC-?j>})Zbs7 ھ4>l>_=ZT1H>%#>?6> 4?Kۿ<ÿ&@7AYR=R='p?,?>J>>-?Z@w?=>P#4Y1r>Zфjhs>;c?Q= >G I>-?L?~?hpZv>au?0sk/??ZE?c?_!>¿A+g9?3ZpB>YP>7>&m>࿇Ŀ&j?⯾",K F?x bJ>c圽'>–>",>?*L?r?//bQ&?Bu?9D>a?>><_n?-MM̾q8MO=m(-z?5j>bZ?*??0q>L>!N>=7>aο< ?YЗE?8AL{?0^>??q? >VEL ھ;'A>5F='vJ>Mʀ?k^Qs;>d>Wc>`[2?j`?"? log?dGA!?.Y>h?*=]=6ȿ*Q>W?S`fu>֚? A ?@ſ @ֿQ޿;0KhLw㽳?Sü?P?rHHͷ0?5?)ɾت<>a?M>?Qȅ?¦;ڽp oک?m]OT0˾~#X?3nR9W~? |>>?}?dԤ?Jq?e:4Z d1=(<{?h E;>>?>$`>=>UG>zt?w?9>,\Y?^Zp>IWq?[(=#? ?>?D6f5,Up>[2*@e??Z>>G>=u]ؓ>Y?ʾP 8?ſ4?%0>?lL> T񎼤u>R?jn?v>a=^?Yf?jm:?EЊĸ>,tڿ1h> G@4>|j_??tXm?Tİ>%X?̿Jf1>#uL?kJ<,оRɰ?>Pm? 8)Ni>>|ONL=*8t?cY>rx>&/m0&$>lH BB>>}l?h? ׋?y({R>^Q¾mV?7~? ྋɲ?i??XuCG><_?qT? ?NEFxYP>睢?8Q>p?|uN?z+ ?:>'@> D?ǒ? r-P\k(> ?dY?Od4==0E F6)?1=ƾn=> ]>q;/>\=Xe梾k?$phH>/7>?!׾*?$j>ao?(?oe?4c+A ? r>N)>?F?LXO?=_d̲'>NƠ=YYvA,;?<ľU???ؾC\?@Λ>[?"?Q?^nt<뀾*Iv@-?Rܿ?aqT׈?`j>'?SƿN><:>>|??`FuKz>*?>B?5?r㽩k>Z>jQ?$^ɿs>ed>?h>T<>0ȿ ?Ԇ??;?'?H @?]FB=Ŝ?d>M0?n>#@?<#<>FER&s]U?,+>Kp?0?[w>`?S8?G>ES?HҊ?B>բ2?c"?= ?5v@> >2jQԾ:pX|=FоOj=~$Q?E2  Kfa<]FL?>uP>?t>i<x|?-kKl=K ?F/?"?I;?mWÄ澬1?6 ;@㞣* jq=ᰘ>`> ޮQ,+=鸿XL>>vHV?i ?Z'>"b>>?Z>'z>o[&!?'ӽh>/>d4޿u.Y0?%qg>΋Mx?*~>`%?aH5g&T?pt9.V8l˿#?qĿe>>u=:ɶ?5B•ZnRG²·&w¦d- 'BbA<ǽ ҾyBF9BBw?0„7A`¨7U¦šʂA(DiBOf;%ѠCJBxBaB=BBABjtW:AbBrABJ y f\+¶[9ZBt6.BBu%4bpBB PB.,K˛B>BBYCF3 ;@ZBEAB>C/6BܤbBA" B@r?BCABBARB{6ABR6dABs@BBԗ0BBt"@,B\\!s-‹BBBҚB$ZC}A}|BuC5BVC0C ;BB>:@B jBO¤AB6BCd=7#:tB&=MAq9#AB\™LƷB);B޿BsBs*@~ؿ8A땭9@Kg B9B9gqA AB¿BH1?&pA!AEU|AVBiA?LBE( B:AT.dBɂB|B+מX`A· {rt•/uXA¤n”@)M.BByBB2C(UB9B0զBؕCh{BZiCfNC;C]gC^KBxClB%D"B[YBi BͭTBi BJAA`C)oBNB@Q ApBB;BBۖ-?2QBtf&-B/BqUoAlBRfCB%oB56BצC+BgC18WB8B ?h²C ]Bܳ=s? >BMv@YB0#:+‚] 9ˆj¥ `vA.Aog2qB<IdB"x7B#LAuN-A0B9.WOp59:OhRCfjZA!ngk‰OkPI¢+r9ªO ZD±GY‹7dBY.B!ZA;X  />'44kn*/AWs)pAGyeAMbOd®eBQ»v¶R{hiXSR2© ¡Fж@›UL5WiACB;Av BQ蕼A&Bit–+bd…2D5uhBFBwR$( @>@hT'G&g¼[B@H@I?XoF1rB Gb•?BXdBYer؀AX8ZB(RAS4vB;sB0oB9BB@ ]LBV`jBP.E1B[oALOq@csA8TBgBSB[v¶LA<"4BKB*BjBrBn+AN[B& B@OBBB0BwG6A=B`AB?B:k~AT²BAAXHC4oC5wA.BK3nn@-€OANB#Bm“[s @>yxG>B?v_µMrBB BMA='B"B GBX@BmA&AveJBC_?Bz5@&ZBlAwBB'BwC }BCM|BBѫ^C#Bo+C/C1x?EBCAD@%B=eBy,B$pBAC-eBA)B8ۇB[C1aC>C9UBpCa;FCCT)C1˳BCBTB_CBN1B b B C)B BBPBB=BCBBZ<.B? A!+mBBp>BfBk*A?BUBlC D@BȻB rBB,BӋBABFBK) AiBJBNBқBkBs8B0BٙBBIBPAVAe?ڀBeA„k¯wA B(B[IJB*TA$ BoB,m B`(BԁA ?f [zLBaNBs“3ªBA?4>NB`A`A+BBB) “jA7BWۿB_BBB5@LB;B6BjBB1B9"?_9BO?(B2TBFGB YCyAaCBX@ 0BCl>C%BlBYBDZAJPB\6BB>@.(6 A3W A C ABW݄BBXBRZ@bBV\̻A]PBA BzBSBH{(B qA%I?l>?C>R>B a>>~>XK(?`<֐p;ԿGTW?ۙF> ;0GRp=5@\ (y?wM¿PӨ@(>EY?Q1q>’uT?Z=kLENkcAO]>?a=$>c7>GQ>=??ʾ >?<Xl _|~h >ٿ!?%S{vL?Z6ʿ1h?AF=T % ? @?B??02?[<=f7m?,!%>? T?e?M7Gxf\R?7Lj8Dgqҋ>{>l=&?>?Tl??3@?ccx>?84>\C꘿à >_d>(?qEXDݝ> KU&?w&ӿ.>-:?*|=)?Z>GlSM>zQ{ yV>Xi"@o0޽Ñ?g~T>DX(̞?Z?? =y`>о!RK2 ?Cnc%?rc?Ͽf>qb$??D?컿#..?HU ! $+?5?7o>e|Vv>=f?^?h>|>Ľ"w?M{>8* ? >U >?^f?eϊ*>JS%B#hKyݿq(?i7=i ?-?$x.?šC6]>OWBf|E?ych>znܦ?"?=p74?K?=?5?8Н>{??q>O> !? ?<p4dJ?e?2?8>rɽl>?? f6}?? >I>G>"{\? >ZDUx?T9= ̿ ?mge?U+?ID>>1>٩޿s!?>??P>FRAI?н{?>V?>8?uR>ڨ<>,=> =`=ty30 >@?ל>N>nK P?R>N~?g?2ۿ&}?C?XK?/`,B=4X?V?R\?#"ؿx#?kB?W(=0 N?R?i侞-9>-1V;1=G/q?J*켾?QCM7i?w?>&?[̿j#?Fl?/tCe>:>Q`&#˜x>C}>ՔB?F {4=vpXH+=k=s0?86YP>B?d# >δ>=q?> z>h?A*sW=ؾMj>#>%=lqn>B Џd* #?rĿ\1ļWP>:7d>ֿ=>Ӿ`?˔pu>>tI?.<*L?hN>+<> ?wl+\kR>x@D->V V%>"?hL*=N3vnE[?@|>UF;>p >T?ǻ?+L?+= '@?3?g=p?B⾾4?1?)Z?AO:M>I X?Њ>o[CUZx>B[BZR`?e>E.A2>l_B係,?|?VV>g"?'R?z>-|ԧ=<S>?NuMæ>[-P>j?r?˄Qޡm8`> N6UV>x>3 >?&u?hڻ>'>н>=Ex><Л>(8>0>J=v>tH>O?o0@̿JǿSLN& &|>n[>K>>!@5 ?'k=>kO>&º3侲οq?BH?&u?yx>_ v!IѿH?x>kU ^?.=pj/eY z}%𾀂\eh3`<>1;>z>Ed?V/=3@6??jMB+9?n:h[jRz,c *>Z?0>=R=.?t )?^ [qXCƾ$|>fQ+ M`^꾲J *ɽ ??Ҿ>0?]¿A?'d]>>V?AS?|?>=h0~V>GS>۶ÿ<&_ۄE>T@>?ѿd?/l˽|bG>^밿4[mo??2>!#??!?Su??<ΉpHF?{^0j ̾<>+ g>k墋V>ݧ>͛>?==t)>䀾5?ƽ~п>n<?Di>.@۾A;Bw@.4?$@pep?a ?jrj¸?3|=~?M>~;ow絽h>.? #>l=Z>E `L>w(p?y8!?]?>v@h>:)>m+?=6]?=Gt2?6>#$?(c?b ƿ9`>j?οB2?)DD?T=z=L@?:>?i?ܩbֽT?W쮜?TGt N? >f=̿̐=Ux>ܫ=OL?䧱9=<}Jؿ8;N=^Y?^-?m+?_ >F> F I0?V޿Xris?( ??*$Q>Rs>֜>D>>?c??'?'rT[ 2- 2Z?:?E?ti >hY?*菀>s/?)GvTV>"_?WX*>Y1>WA/ ǣ=.|pgw> >fX>z;\1>6?Z9˥?`f>5?>+1l?G}Ѿ¾>=lg?eb_h\o!>pJ >(@E>?EJ?.B*?Kg¾Hj? z˘ƽྐ}j?%rqhD?jq]=~`>.X? i??; =CGA>Rt \=ǿm ?iWt>Y]p>l>\ ?)=bؾQ ?i*?K>RY|nX?s00=

    m?s>>|=",?J2>8uľ쿅>!n>Ϟ>4n?ǀ?u͖>v?<>>~RnFq*>?1>?-^! >9/IZO Pt?&r?U?a?wJ?n>ۿ$RἹ8=Ғ?K|?,w>[U>aƾ{l=,> X?Q=̾麾>ۛG޺wƾ@@?v=I6h?F?{(zڞ?%>ľ?4>)>>:xf?T<=0P?9`{?z?P\P^8a?W+?L;`>d"ψ̾bh>.-%E"A><`ӾUU> +?HѬl=I(>܎?T?k>H>¾\$Bv5쾮=|<'܏> i?O??-?=>f? =w`F*1?\Uy_[;@>nƾB?AX<'`?%pJ+v]&>S?UlNJξ뱆<==Z!*?u(?s2> (;O6ܾ? >t ?vp? Çz1j?Ev]?F?s8?NCP?f?K? t>v?O>ྻU>?2>Ͼ>y>~K=D?{{y.>ge@O*Ź>m&? ]8ÿ7-6\l#>gZ2/@>ɷ=ؒ>l?4>)*;'ľ(ࡾ4Ըhg̿oS>{C콜^;S@Lc,?P?uŐ>-=1><b"?=G\mU}?,u?p>!KH==SȾ̾$4~Z?dDe8X? d>S&2W迃^>ک,<? [7]1z&8?5L*>'?p?'n7^<X@>Jm+D#X_?j >H=/7뀽%u}>*?!>p?O UL_@ㄾD.@)>}??2Q ?nhnB>>UݿOx~>t?A>Lb>,ݧ>ҿU_l7DPҾ8pԿ䋝/J%2,@>4\A>%ʾ$m>lV*?hH?/?S? ?Bz?fs!0onoI;@v Is`>Ũ<<>15tv?::%@͂Ds!ܾ\?6)>A?<&ʈ\w8,ĕܾ\N?|3>M\?#>#?Rx?xL?#Ͼq1 :lA:3>B->6?^+?/Fx)>ʬƒr}2>c5?H>@b={\pi>?UY>p?&?M>={x??QTY>fiGAr<,`>e 5c<>^J?!կ?BesH]Í>9Tj! 3x?H=?T(ƾTgm>e (x>NP ?m&?>"؟?$>ʰ}$*V#{^='{4?c>$C>>˲x?sIo4Z(>y濢#テsӮZ]LQC>m>O

    οq?u-̞(`&\Zp?/|s H>aϿ+>i?:Ze?u}?U>+$>,=?ȿIȿ߿S%l28w<ί?DN>K?*.>a*SN> >5(ᙄ̽x>Vż?.=>;??JX>>1?,>? >b?\ڕ?Ye>vNt]~璿X'MvooX?>OJeRq=: \?,ԾyӽRV=?/|bbq 7ҽG&cHrȄGC??{%>>۽Ia4꽏EwJK>$B?$?"?2ᅤ!C>ٱ>/4v?J.$Si?显C}" ?Q¾>6~5?;0D`\ʾ>܄4T>xX ?T_Y>n&>pۿQs'J]?0Z=P>ޯ>(ct+[Կ.>(ixM ??#n4a?jǾFt? >>VF.>UEy???J6?6=hۿڽ;?ƿ"?=>;n?T7V_?xn??}?1<;>?ھhz>ܾ?\x?T߄84?F*8y?ǻ_룿8>޸b=pPܿ\>I?-Z?{\>r8>uO&2:?" ~=ۜ>w>x)=P>vP %2?]6G?ýd?ni()>$'=)u4H>ϿվBTg?a?>e?5\5Dš>!j?"?M>1_>A0䜀(T???>>v<˱ I>Qq=7JB ?b>%?fMƸ/b19|(oH?ݖ-qq>8F7 I?1>8@վ{=ֽ0?{=S> " >@?HW>\gi>=&>AԿ+tϿY? ?= `ԏ>7 >:Dv&n9[=6# .oj=t4D>:I>M=ƿŽ>%S}1'v>??=R>:=0/R>&X??Kо΍zyϿ`A?4쾚6%ۑ?J}<`"e>q>]h>t> K?M=\@=B? =fȾy&ھSX?i?8ԛVG|̾=2.=8tM̿2>D㩾Jdн.N>+<<2 >}F:?6sb?? >y=UX?B`O?Y?zL5FsMR>*7/r W!>dF2?h Z=0oTY<<`0??}x@  >樂IGG`?)=p |=W,>E>>u 8?#>[?/>.#L= @>n3?\~>/{FPw=o 0>>> 6h?_?2U<3оs?&ߋ?Bk>=(Κ>t\WƾfO?Z0>?&?"ワ"*Jx=_I.ˑ=??ؗ?p?#>$f?ʕ?oVοSCF>2* >?mM>ܾPXؿ>|dHY)">.7>CmxB `BOAB/LBAB<>BA BZP w@xAwBKA‡ Iٻ„2!¾BF?|j3cCBRJJBxžDiD+ٖA.BufA1§Fc<-8BX@oBRRs˜bp|tB}VBBпBnjB.[1XUBWB!B.BuuB5=z 7::5^K@5T> €,tkAYWeA=Xt'<ɷŽ'PAr2 \JtY¨0AB5zB 1,05&/uAǀH[c‘= } _@{8B+]J&@/v@kƒR" BZBЇpA"r7(JٚAٕ‚AҟBu)E-B'}B+B2A/GLA B:[AݿBmyBBd9jBh 8B BXHA8i\B`4 BpBG–t-#pBd[;n©”@AnBB U4B P>W(BqYB{~”c@/N›>B\NAKBB+6BBBS89A1AŸ“½&CAI;BTO 1*B`B1(BB/"A/BHxBÝAyBf~I8/vB­nB{B@4B9C o:ԱAiHBrbCA'|B1{K¦/A²9`Bl sAjv M j#¶,?€A .q^BVBDxXA@Cj2AYQAE7@:ªeABL}9\Ŵ2J3RfvCNBoRBe[ ("!B\BWQ"rB{ٜABAd ,A{JB@BB,,BBUb9AuA C"B:4BՔmB8 =B\B‡A-UAw³T``Agh~AgrrOB;jvB*;AEj£CiѶmc]VAAEWB}S(0AJABIBSAB5fBĘA´$B|dˆoˆ+@bCXuŽ h]VgBR-BAa_nרB#'BAڢB]|#>AB5BeBBFBZU v\R‘0zAm  B:bc""n½>z›g[Ah‚)UBB`7¡,Q});taFcf†"FCݪBgCtBAACvMBF>Aoՠ+0C1cAB^BI;6Ai}M=,yAucϴ-½0{@| ”3jb^BWA+9AB,ɏ1m]·m;h@Rs@‚2FCOubM•Eo9Bk*@^@vBdkA(ANA# A@-AwA A:BBiMWj eK3BA0Ŋ?#@sb9,J$ =&F‹*@/zJXB_:B1ZamB\hDA+B۷ %@.zmrtH µ®?,x\rBo\B\¸\AZ‡@I@]tBY{Lz6]@a AdxBNPAY)AҪ>’-B D  }KB C@@A6Y@G3A@d@B)Y€*ArqBLC;BsAD±Dݙ|Ԙ…ۓ78eB2Au+ ~\B=B( J$w‚BF{!L@2‹ ¯HAX©l@O B_nA qBAB<^BdBc~B$(BβµhtG1zˆS—0‰6c*@,B3\B:Ŋ/;ZPAʢ:;ALBBJj dA"BB&e:ˆBAt]y2ACOd0lB$AKY?Aw0eZPh~›W¹ZBKAN_7sS<;pBb &Rt70#‘׿@IѺyjj<`? >#(> ^>b+^>rpy?Y^>>cV>7j>P>*V|>'?1v>,>>>Zm2>/?@ڼ⦆?E]>>ɇM?C9? ?pX?W?>F'Rp>_T>]/?#>ƭѽ(_oս?b2>s?T:JUf2*?dd?Cv`?>B3=~><9|B޾=?H^a=`>1@??XH?,5>IJz>KY 9Hs>v>h>FMɿJ?8`?3ܾ=O?u?>>j,<̽61> V?EHlH8W%i`=yr}PV>a>6ڿ%\DX ;g(?`B->8'">o(?2R> i>i9Z$0>b? *<ϔ?;?H?@sW(TZq9?Jb>jҾL#?iL Ծn`=a0>*x >|潇.H r+?*i? =-(?0Y?le?N>e̽%?8J?gl ?wOڽFxI*> ?_>hx?+?Ͼ>c? P>](j=!,>, Ll>Y憿>Ȧ>>fN'l?Pv?{??@>_+>ĉ?L??>G'NX~0H> ?!9>?5,C?FƾՄ:>J,>zl`?3L]@?>r-T?'?4HCm?.ш>/w]>ʾəxlZ->>? q>:j=>lO? bT?99 0tNd'RQ?7>>@rxNҿ7vD;?¸<,.>>HRK>KN?">٨?>pT4?NQ2?DJ8>hB~J6=Ep?x?>TIT1>¾|>%~>,!{??1>/Ef?"l;??R> |( Z>|ǜ*n N>>P?=?)??0>?tؚ? /ؾ 9^MֿU~?9K?>g/? Z1jD>>3\-%>}?Ȳ>܆?zw@?,?>f5W? > $rvz=i>O]?=Y>UC#ะ>h/ٿ ? 5`o?1Sp=\>ሿ?e<>Ou>rII M~?f0hG=mQ? I>Ǿ>nf?>@?QվWվ?*ddX=k սBv> 4<3?jv?F?@>@=>??F> ʾ_Ĕ(F|>'?Bbۖ>K>vq ?^8<>¢>ء> 8?y@5b??2)`ǿBė>$#K?N)?RCoCdj?l>~ʾ{jh=0 ^#nϿuU/*?T};ھ0>ߒL=ξs׮?E?;vR?!;~9\??\:-?>˚Tbgnl?otD"?_q ۨ;?mT?)=? tmL?,)%,7=G_?Dz?j俣>7>Wb?2 {9=_>'>I ?`O>c];M2.6^=Fo/>?)? ?>9>?s^Ӭ:> N¾> x$=?b>_?>2>-?;m>C?:/:-:?+ >'ĥ|B4"r?'me>/Լ| ?.f˟T=o>X ?)ʽ!=?n&9$$>V@?~n0=̿f=Hϝ#?ؿ>i=̔2 <+<(>y?<0Y>^#e}pv>p?޾kꬾ x? pF>b~?X>]!Wj(?2>,:=W_4ȾQ?)6?QT!?Y`?3?D>73N/yl?Z.q?ؿVZ?5nd)g?MN6?dg ) > =?(? @ͽդ>@ӽ?h=>{m?aݴ݆G>>y0>/==ƾ_&TQT?G>?fͿD15>ׇ6Q|r[?^?/#W޿=,O!܀쥐&?lr>!4`KT+,??X> ?>D~;&h>>2>@V?<JD#?j>˿Ż<>Tڿq>-B>>_? ?w>D>Š?ud?Ⱦ%I#?d?>=_?ɻ?ʿ \e^P?jh2>p?>2Vt W? %,u>-=e0?$>AN)5=Uj?.m?m b>J>m{hUcz/??%L=?5.>0`?g|>Ɛ꾮?.Ӿz73 17Կ 6 ⿤">1ؿ̿#!wr?H?ÜG맺lGP??] I>FȠ?z?Uq>:?*+#E?v> Ҿ[?l *D?V?G->==?GA?<( }Oզ??X>jw>ET]Hí>M>?&=6c?B28 Ez>GTڶ>g/?=0D?U9*T8<1i,Կ5'>4?EW᤿"!2(==Bн>OCzw ??G?IT2oz_ߧ¾:>>U?5; >U'>_[\Ew?J־B*(Pn?yNb? )6j?)L?ɜ>>׆=ZY>ϊd?\;iI"T!h>?fB3|1꿆b?>?oG+p?3?l?|>ۤ>^>:nȿy>E>64%X Ef;ڿi=Wvu?Uj?@ ?(?$c>? `?L)=,>*h>ܿ1?;2=YM?D݋{4ץQa/?> -c̿?U.=L?Pe>ٔ?;GgHfԿĶHP*0xJoG?"/==J&za?D>}Z*?N-?`N6X$zQ K?`!ٽ}>:@?Lٸ!?ITa=.>[8䕻9m?v=q?,(9"j3c?o'?rvo@+־C>k῅ ZԐ? /?!N=Sd$ b>f(!rX>N>B>;Y=\ٿLg_ؿͨ=Z? 9> |>c*>PSul?C>^?N?>N$4p2Ǽ'=H>^Y?T> nG}7hR=M:C??R5=(׾Q0a?]C?ɾ?y>]]>9>ju+=.> >*\?<ܠ,#ϼ *=Yx*?2IF?ľM-s?>H>h&?3?$ϥ?$? =|6%c)FIѵ>>ق&>?T5>G>"?V靀N:᰾ڨ⿙#=]?T>ؾS&2Ġ0>h>>8>=鈾Vv-&pd;5⻵pž5vf>4"={p> Tlw*>Uھ4hf?&D={p> Y_?YnfZd?)Wbm8ꢿ&K a߿,"&?FO&?0 IFb8v ?9~>?gQ?|=p<\>?/#'>A/8>?X?$tl,$ O??/YWU?;>`Ұ>[m h?N/¾8=hpp???%>J6. .־?O%R.lT7I?Ei ?q)? ?׾Ͽrh>OR=N?vX5d?K7>׈ǿ`P^[xzi=>P+>N?#>#>pN?6~? lf?9?U*?E5-{>fl?ڀ?0?yٿ[>q?[$U2<? ? x">:?Jᨾ jeSnt?b(a>+u̿ ?ň>A[)dS>lA0Խ\'?V=iO :V &˾r,?v$Qοf4L.>F?s?|m6[?> Mձo3?GkdR$?A= ]B?R0?߾|qP?_?TLd7>R?Su=m0?8d?\ĭ<˾vKb5=7[^+Q>4?T쿢?5?4??c??w=2>$߽y?<]̄?׌> ?Կ=g>>kqN?.kia?#!ҿ>F>@V>W\~=$9о2?|T?|- V >1?>?VmL>}e ?DнNT?پc>=$0>މZ5t>)Կ ?U;|V:>Xp?*q>1`MoP =|?!g??P3?;2?>*?lh>Zƿ>4n p "J>b[=5>b?f `>SG6??5i>K)>_V0> XZ!h>D?c|Q"s>#ݾU5Ӳ?ةR3ʅV$, ?\?U?5>i"?hU?ҽv> Xнݐʿ#L>X8 >n?"\.?4?3[E>!C`>0R??Y;j<>?; m>뉛\H> 80BNܾR`$Ig?\P>@>XR X#>s*þ>z皾T(0Vr?/9} )>C? )|^=|?߾[Yz? #?>i=e+Y >7>Ů ]>Sv?(վpy]ľV>곉?A'>^4,?:.$\pelj(T?f0>8?Ҕ_?O)?wO>ts]?)(>N(?&(>4>l?kF>.sZ=,>"ʽvx>f>Ɩ]GѾ@UGQ&>@O?G?~m=Zh<"4 rr?LX@>GGN~&GCF~=GWp?l`>c>Z ?Iɽ?%fJ;?d9t?/m d舾ת=즠}>_^\?Q-<|F{?>:^QG>&r9?j]GBlq?%ݢ> tj/ mxB?{}([?H?%j=>?)Ά>9?SX?f? L> >4> AS#'W>no`?_nb(r\B$>&W.=bPyy3O>@_>~6=Ǘ=*'?^ ?$H>? \=v|j?]>=+qJlwG*?%fMTt>&?z=ľ.p?+KF( f< S>_ z9ʘ.B>nZ9~?Zo?ܱrFs~>U /s ;}ͿCV=<>6?>l[ 1rQb>v?V> h?`N8?C?>6A?f댾ʽlǃ>e10y>Ph=?Fq#>z]ؿZֿ[`OEۿ8쾡俇ol[?z얾[z?V.k?Q#:>?-4=TK"‚E?6>?Au?}<޿m=>?Yxl7Y@Hi==۠>5f7㽄?~*?r>;=? ˽.>,/̿\=lq?nd}?t?>c>@Q3?x%b=Z?9>[h>B PU> >Ը=]-?h>>8?;>aT;?C?=L>>IʼP0tؿ2>u,>@ >Ys?; ? 5L?n-6T >ˆX> ?zT>>!"f?/%ʿ??\^ڿ1?C,S~]?U.⼇<?$?mI\ZV)j>L濆^s=1tU ? ̔<[?P?>HZ> WN>K="l> `>tbc? >۸Az7?=[xn8L>N| Ef>z=I0?{)Da>54:DLP>l%>?jG>(?,g&?d~ցA=B BDB|A@@s AN&Q%ŸG ҆d0B˿`BM&zE_yœ(dB6q@{AevBf[BBHBBy/BafBAi%BQBhLB8hBAB: z uea¬SE@Q‘kBŽBĞ6BCA pB13bn2$?0k3-BB,fm#AhG׎BkX@`A<A5B HxAUA B2@Jg?!¹ڦ9c/58!A:WBBWB{G]A¥B૶BD&ËBj¯r/nAABNL`BYDAڸBt=gB႖BY@B(UИBaTC sB3CŲB>"qCDBTB DCiCUB5BBB#B^FBlBXBAAd‰BVm+!AkBlB‹ ˜BbnxxW.|BʍB PC7B&B!\AW$B:)C)CBvYB>2BHlCMc-BmA$Bj?JЎB2#Bu@_An-BszP)eBWB/iABAXBC?B&CB1BYCTA8ByzBB>CRbBԓ>xQAB]BmB BBh A*BBDfBjpB@A#iBBq#B`BT*] C#?Bm:BUBABX?K?rB9HB<;B!Y@Q@B= B)E0AL.‰0C CG¤8iAQ 7YAߵBAk@`AB/vBn)q\ACCAʽ4Am q@׽CB^ A.B$Bt7_BALB3;BZlBcBޗBeC BKB=B}C( F.HBDC#/B B'AC'wBB6BV"BB BюB@B,BR#B BHaB:BlxBޮA)BtBoEBYXBw2AW%BC CDB CZB .BcVy^C->BB4AhBCB9@BBB BBBƑCBچB%3BpvBopŒBR5?Bj˜aBAdBBC4E BzzhBHBA B-5 bed?J]‰gG>VY¤$5\o %Ϸ5PR 1Bt-BEBB|Ac7AB*BBJ6AſZBBsIA2*.AϼBB!%RcBgw6[&A5X•*AIgB B^a^`'B*=@uX7`B%BxB?@Ɵ^B6ª6ŒTZ h 7-AsB~̴p*.6A" 媬B¹5@R5B>wA-BB@0PBB@xOABihBEBSBۻB@3j*AXBN@݉ABHmBj@B!X WYA$jo³(FB-iA|BVA098gº@Zu^ §]FA ¹O]hB?BC?#BeaA!*„L#BBAoZ¤@lYBAY0A) B,B&+BV$ @6 BUwCBԽB$@XCCNAA{B׮B PC$sBCC4BAp)CC BXxUB`¾Y~BPNAшOA A);fBBnAB~BBBbWB*BnDJB-:C O(B{eA~4.AdB5@@ĜA/e,WPBcB>UB;*{=x)IAy7B9ANItB#)a)('cAy B@Csf@$ q@\pB 7B/B[«bA)2•8AS RBZ|ŽN]BZbB S2r t@v|B My=„Vi(nA }AAb5 A-U*MHS(^ľhZ ϸZL*> T4=΃c7<΀>3,>nܿ,1>oǿ71>?B>@?,t?7?>$\O> vYRt,ZE4"T?j>>ֿXA

    -ֽ&\zc>>[?>+?F?>2>?7prNpw?5g7}y`f>9?R==6 ?C ?ep0ug=Y>?%EQtXо5?b>祠>W?5?U((:db=P>?=+>6?g^>lT.a aٿ@>T߾nr>#1> R8>M>C?'?xv@:XF?T?c=>>8ZX>v>j?S@aנӻ>3U =?QLZ=zf̿?f?^>-?>M>++ ?A?M???C>>`>%?F=t?OSD> x>"?H=j@EUv?=l<0=(nr(=׆2&>8>9Y?N1?(⿄eE?9?k,͏?pe gĿbÊ>I)?z>nrֿ+?f?l8>^$=>èR\ľ ?ٿ=̿2Ho>W5%>F(>=l>`u?є??ʷ>V2>?Bꟾ1pg]м~X)Na:,4?eA?ZR>Y=א?0)D@?b̈́>gK?}>ɍ?v̾#&ЮK((>2Fڱ?Ԁ>6>`jh\> :S`4hY;@, >>-H>Ξ?9˹.<4>i>Kq<?#G>=_>0?a>e?{J> >焿p?/ٶ?_Y(>웨>cT>>++Y@gGH?''=AjQ>6?D,?p?b(?(>+<6>Ͼ !>? ʽئ> ?Bm?K>sb?B>=#R>ϭ>d2=m>÷DF>XL?oԿ\8f> kE`Im5ؿAAC3>e>'ʒ>՗ =c-J>E>IZg>4ܼr>)E=/YJ>RMJ?A:T8>]fcgu~?,>>*?#?f>e?>H?0_?Zѿfw>M=.=IAȿ.u DF?<ȿC,>\ҿ?B=v?0">΂oi^?V>5>P>5CT.>uy?}v>>L<>Vtȳ R?79Q?b?^=( X=}n?NK?Av޿?}+^?p+I<0?c X_>:RYU;J?~>#a bx?¿ > >_? ?gx>8x?=D>!I?\>~n|d`=Ye_?K0>y68徨׿/,>7s.PZ wп?O?"澀R?i2=D\O(^ ؾ>>_r>c#kG??er;4?@?D>R?Y>)T߉<^t♿B?Kd>U>`h>\;>J?38\X?n=>/> 05 (>R?BKĿVF>`RJs>sFlH?g.3/=0J>&.?p=;- =e?$wR>6%m?d?¾?$> H?IJS#m?ڝ?{9M?5T>뾽xJ?a S? !=J04P?U>E?-->a9>[J=ߚ: $_>?oJ?LE?4>^~i>㢡Yd־\o= PBJ޽:>!r&?><>>_>>}?-w%?]>eHr~c~=|H?Fem.M?F? >?\h>l)\&K徣?ev>?fy==,>&?H{?S?l<?>R>.>bh>'?rHP> ? ??-{p=q>aGNx>ÄN Ӿ#??E/ֽ^_??[>e?;v?s)?Hiu?5>1-?x*>4U(%>TKM?3C?ii6X?g|ܺp&dY$?(>P3>( ?=>?UIb= :]Ev@?Sh-}L)ؽъC-">> (0Vy>(> b>D䍿Fq >w>>nF!??,C?$$?>(d(?`B ׾=Z?)=[9>%G"C!>!|Vb\@֞M~%T?$?j¿Hl?1?h'?m=[p?,hJCO?;2y? /澍f>ڰ݂=4.JF >V⾷6?>J?p?gzo!?>?wI=.^`;kþ <>[?"o?C|]>/?F>x*o?>?"ֿn6C+GD?59`t&?+s?q)r<>WG ?w'B=,@>(>i>k- ?8-<O?XL% 8}?>Dn@! 鰿ս?/=C -[þy࿯"'-0-agܽkp?)4?<%iba??X&?̾6>>ľy>RANMuKܽ hؿc?D?|Z_?o>@:|o >??>;L?>R9=@>=vV?8AOx?]>?>n _6?\ >࿑fP|'R_>lo&R?wN=>_r1`C?)*=? (=qx? 97/? !L?܏'5??UgKH8/&տ э4=lh!=њ?k?6*>LF=>ÈY>zx?iËydg?l?z?k??>>剚?%6? H?;>< ߿'?{F?=bݘ>>p$>PONE?0ht> >\-,10(H?@??Bgk>34^#f=.|=D\??w?[f??vʿ ң?۸u#;7B?dN)mq=(?.M:>?*>Rz8ŬڿO#پ`Wg]=OJ; p;~@<(IR"}>=v :Ը=`>6?j $7>=%N7Pn:F~\?̔? ~?G~>8zh1>n^|=(8?,MB>p?1h?h&?2>,U#9>?yK F,Dێܽq?ҕR/x?7Կ(e?4?&yf>dd<Ľ>H?wS?H43>>|ȿ+n&?*R>I?+NP(q6k῟m|? *);L?<^?@Ȍ?F5R?;z=٥?L i>F;?b/K@==п>K\|>y>3lb?a>_ſm&mf>\ǿ"jFC* T ==kȿw?N: ;Qs?R>>n밽>諭HsNEQ{ha?5[ɽf> >ִ?>?t>w?>R=󰿈_v?M*P?оoҿփ{@@\>juG /9>LN?9>Q#+b?!>[RD>|ٯ?*t?Mጿ>6? \9)`w>8?>1O>mοT?n??Æ$pH0>Mi=ݰ?u>j-8_w5}?*Ӿ20>$>>'|h#뾔._`.>rٽeh>??c>!^w)^Y?>ȾrWɔ=>:T= j?D$>>gVT->?|J!?>`>A?==={ʾ+V>ט@tOj?x0>,oB5T}?, ?%>,S? }Ov=w{?!8b>醿qy<(P?i?#Z?t}bo???s<ۊ> >?;fob5>=)>=?+?J=TBC&?z >~?>? ÿ4Sr?۾ROUpRs?R=c^fCB2=? >f.>- gB쾡 >@Β_? 6?uLvCex>ŗ>`V? "gS? >@I?e>BJ?wt?q>q̦lMٜ?-z? >u\?bӿ>8фXt>c>1qV! />oZo?Hn?_*y=?h?A3?Jp>r 6>2>R>nh M ~G>u>=Vf>=Q@?Oμ;;Ԏ?Gg?L=X=/=A?G|?,M?x>f???P?}=P4>zjF>>"?85 Fs><6p?H||~,>d<п?~ O?W=?Y\>b? "=h<@=S\?U$?&)?":D;7*ѹD9/J?7p?\f>>e >;t?GXjtaHEʾ46fS޾8:>>*ȋh==$>]Z>?6U>^k>I;h">(ľQ?AI"\}{\ ?竔>ˑ?>L> 5@>_>(hDg >: ٍ>?ҍ4I~>B?[z>L>,?8>D?,%>?6=^0/]~=d>in~?d>oþcQ?$?R~2?1J>rz>4b=*`>%tt=ȾL?+ ?N3X.#mS?}U>Ի>0y௾_8hL.֤i>4^X>̾N+PY>>=ʂ z8>۔?/=>jbM?[0?=~>k>X7R??qm; z5[?,V?V̾ Up 2<4j>Rv%&r$ggo(C=sN/;=`=`?ƙk G"RH?|>- 2h>E?/E? >/sֿ'{>TX$˜ ?@п@zY1?zH0>\?.=(Pe\?=, "꿃W>,?þ@8)5Ŀ6jh<>a?t4>4Z?lݾ%e>Fݭҽ8=z%?:hܿQ?5k`Ta?e???v>23 ܿw?ۡ=T?ʁ?!>/)>>?ʽC:>* ?(ej<=?u⫾п5?we?7>;ҿĿ[?>!L+3'`>h¾|J?z?"G.xd??h>zJU?y߱!ݾ%F=S DNv>n$  ?z?W1?K?60>ZL¾s(>Џ=]= ?e:4>T7*ݿW>YM =1?n*#~D> ?KFBҾhR>?Q{ l~=`п8=6򑿍>Ӗ˿&2|?K\>þ?#@ S5>?q=¥ľO> h\?9f?M"]⾱|>m6? ??:IdI>:T>?3X?>ſ >>=>9>{b?J>D@ϳ? ?)|ؽZ%뿐aVJ?Lq?Ry𽑛# *?־S)>nJ>ȵ:?et=T(?;ԿP>"BOFl=X1l?$!?'X:V")>>)-QH\?C<,\@ؾ%'md ſ!$OYw?VRn·u->x>iH&=4>A >>@ >'=x>B., տ pVѿ܈禿3<#?=4=H??2i3Ef7h>?g<>d?.?r';4->?ȹHp6JU?2=Y>?[P>ѵS?rJ5>>b.b3a=h|_G?/пWX>Um,ɜ;%>_CMk)?A;>I>V<ح>?=<>o9[h?'ȽH!\=OIH?>Ȯ5>d==4;?V<?>߾>ƛ`>sq!t>=ܼM>.ۿ3!55޽ ?g:.Bdݼ\ ?} \BsA¤€BO0W;@^ߕh@;$BZB?&B1A?{O*,®YS?rX‡BB<[|'=ŊBORD[|B^K GA<,A$N?.>A}ABdB/ |Š3A1=},bm0B~WKBp1PN¤*C AB%1Iɖ®^A BA5@}C*PRAq¿ŸzmrNBBBǂ˜ѿAA B"B%A\ABWjBp{A/AeSBdCBKBUb^jBdBhB B?/upBd —B,C1BQAC0CB#4B$*Bd Bm4BlBvALzBC:XLC2BC_vB؈AhEyB@}'/.@0@8BFRoiB_Af<3A/Aº}@oUMB=BeDBBECB^1C9~B C(BCBdBɬB5AoBZC*Ag@VlC,SZBB`}B$BoBB CtBUIBkBhC B|BEBB%rBKA/AE@BBPdBELEBN1?j A, BO…5$YkA TBVB B<B"@^=-,!\BF‚jAۇBBV0 8NҦ =¿ zgBjr–DB"A+qAtި!B.467*Iy>ADAB B'K?BcžMœ0ްA @0-B.A} ¢\AL½¯;µSB*%sU>1·jf &`¶-$ZAغBc<8 P]b$@S\nB B¤*ƒSA†/@BWR"B@`4@½9A[ A-B^sB#JGmOlT®.X)\F #B0BrtB~Ap&B v[#DB?T~YBABe>$9ˆSDAi@;Y „?$@’—,BOTB@I^s¤'§^^@0$x>AoU?ʾLj(bΚBoY3AÁA(}@V$@B2cR0e%Ak\BIjn . ­g@61B|?b>,acj{BB|BÐ/P2AG15tBߺ3; ²dy)BoBqBeʹjVBX<5|ANT`@f0+ B-Bw]*A00CzxBVaC@ @BS` ?OYA{A%8@_Vt;pfœ3Ǎ/QO/ZT1B{L ʹB>´bOAĶBAӣB BSB5dB4BƚC+F1Ę)8LB,+C AyBf;C0FAyNX@HeBBBC:YA?ՌA↛B&Bg"B|*A?fCrBA BAIC%9(C7BNlC+:BHB1B@BxB;A07BɄAC*]B),@BBzCC-C 4B2NBB&CQ;6BՉGBxBBHVBXBn>BoACG?,@iAtf=BnBCZB/B˙BmBURA@AB:B%HB_)B B%IPB~AfC,ECIjBzB@B#BbBdrA$BB0BW@ɺ B0B,L/"AQK%AA5SBQ'BvBeB BBjy=$>%?&=' >>Lw ?ֿ ?jO>?Py>O2?p,Hɥ? >IƾV>+Q3#?Fǝz'?4d>?b;4>B>Rr?>5bԿu?=eң1 s,V?>|;e??g<=D>1ݾd???`^?>ƌyS>?!.=$ ?!F?O?_6Ҿ'?GO^00=:dh4˿>/h?>q?<1e#*ݿU">Gߖ=4'=?JU>?r)>Asٿ/O?4I:q?%x=r\?]8>0??,~һԿrt> >W lX>^m=@?N܊>=to?+aiO?i4?ӽC>Op ܿ8'5ռ6=*p>>F=Y?d\7A>N?ƦU>Z?!"*?)?Gpٜ8? Wҿ=tPb?,?h>}Կ.yվ4;c=>B?(>}W> f?D;4?? =L>lMm>zs~,OuH>$t<8 VV?>I<8W>j2>6zx>? _z濟>&@1* >?b Y?A3>;COwRzt? ?XP 4}< >}?\(ܿ'n5r`>f׿2s0L-yys׵mNlc0?a&< ? B(߿!>?clE8?+,R=@:`wC?ҿ~ycY:|>C,?=P`܋?aS=׬[J߿OHFQO>E<v:$ o1?Q$&J? 2I9sB$?7C+(>.`>\,>n?T$M`@> ?1I>Z,>"?nKlJ}G7>Z??I# ?apW@s =LU?}6;#`>??uZV=>Z >L>_T?0=X'>?@>x)?J?_9갿І?/>\A=t F>O$vԾש?TJ>*3&==}g?+£>;?Y?,?R.=ؿ%>g&iͿ#^ n>ީھϼ2>>@WV>*>>νY/>>ō=[p>(wH4Tm->Bߢ?t>OZ>&?>ھXc @?.YXy>7>>Z=`>?!ʿQ{Z?:)2<3@eu￳&Ei`u>r+ID&c\>$,?u > >!e>߰$=fVԝg?BrkX=S$?,zhG\4<>(=?YR˾Ұ>?MW?{v=pd27V8?"N8:6?Tp6u̾` o>i>Mʞ|6'>f,?$>ҩ!>*.>;~>>$p?.1L?A ?v.=q\hR!=?2>ѫ=C&=>8>_m>>=`?v'S=9>\~?ݿ-br>]#?ɮ?)XѿhS>V?i=?)l5h?x?`xپ۾Nh6>̿-VZz> zd)yS侽WG5:J1o /fR)9?h/mCc #>^u<&L1N>X ?vn|![>ZﶿNR a$nbI`dWg?>X]`r??y|\S{?T>|=p=?? =Y>=>?e:4hؿp80|w4?x?}>.?v?oz>G ?@:nm{[>J,enX"㘿F>-ʿ;? 4K?c<Ϫ>?Zo >a? ?t>2v>3P1,B?)&jN=bή$#x HJ>¤(8>{wL^?,}>̡y>7y4𾫝?I?Z+ȿ7Z#$)Tt俛VIg>w=,_?5~^>F߾fG1>?iM?ƾ?%u(-5nǒ\8&>Y;?|¾>"H?ֳ?DnȾᔿ[73l>'H>>Ŀu(>(?VY?I_,A]ᾮKr>?HEr|2HDQ>ۘ87?CK`~?0:fӾ86=d8 ?'?;Ė?A>EPJͿ=WtO> =@<`Z>(>+f>'ݾ7sz@:l?ji?Z ?,\ѿKe~!JOρ*.|Rz/*`>Z>K_*E5tu_Wʽr?/̾!,?D>d?n<;wB?|>΄>OAhhԾ>΄P>xڛ?(Q>˘>h?o>Eةa8YrZC )#u=+? /51f?->|>DQ?,>SBOZ?z?[ŧ?'.E?)п s9TmA ~S>fuĿ6?U>@:dx$^6<ЄLY?sw>=>r zp?Lr?ѷ'??TQA>D?xkM?*m 5=|S~g^?y >¿hGRCK?D>PA>թ=7K? 0>B>пL-Ծ?ƹX~7=J?RQ=U>W )[?>  ?=C>^9ߪeB=ȿ t?? Hc?LiTf?FT?? ÿkt?89>ڸRH7>&콧> ֿaֿVh<>==w~?9?ԈLpr.$?>瘰Zн(HzLrA?k?Tpܾ "žoT?PZ=ゐ?L>+28M_I@>{P=XP펾+Iп DɽX0z.?4'>F>~ >:?Wvz>^?3ҼL=hf?j |,5?d㶿1p=K*?4nȇ?V5mY>h0> <?cY ~?s>>>!m?ts?{80k=>KhIzcT"xQ>=pſ?j=IЯ>F/?Wi?cW?G=ܾz8>& ?| >86kX>?H5>P> ˈ3>>;>腣C?h?6>%,??+H?![X0=|"k= 2-M>Y_?> @?w>?,?Dټk(>t?DȽ@.x?Ž:ht=﹘?8|>BB"<;2? ?)1?SQR>j?PH?z[er Fk?ٙhE۩>=>Z"G0>O?2k?(U1?(?fM?!>5~7qPnB¨Бi=G>Ͼp~tE0=kv;}(w?^L>E??^$I?x>2>ɽm? z?[p?>4}%Kt w2۽>v?2p]> d'>;ڪJr?">$~ҿg9>f8A?C?$7l?B0?r>"???[?IԾܔ9w6?'>w?#>%m!>>Fv"@`?v *>l>;0pV">?z?z^?*>׺?_(?<0?3P?a1[jͿ%Ϙ>>K>z{>=>>:?*?I %H>ś2?-Iʿ?F>?6h<̶@VF? ?B,?7?u? ?_?<]?Ns9B>IѺ>nE4Xо7>$ξC?^>>?ľ[ڿ&w7V<3" ?FZI?6 @H>3~?OYNF=?C^?/TOv?>.\9dbAƒi-;7a?{?=k?HXR>Z>1߰?Lr=L?FS=>y>g3/? ? I> ,? ¿(_>JH>dӿ=>~vk?ޗҾ}ktg?.T>)?>Y޿=O>??=Zvr8>+>n0.h>F 0??h K#?n?X>?I(>Ҿ5V >*c? ? CV??D>>a?O$>*E>D?i~N>zq>??(?|E"!?_?GeVGʌ>\qfhC11?ƜʽG?O5=M(?-[?X?HL[?F>*2~>J>(i(\Y>? $PvȬ?s0 ?sl =ZPʶ?' ?¥(f?BZ8տ*>-$J?N2&?At\=4>KH ?8^> ^wP0<>lľ&? <{#=.L>]Z> tA>=8>6?34n<< n6=bp\?ɽg?T>Xwp? ?"@?u{5"$FU=LK`>?d=X\>???F6>zo?4?c|D?|Qr>9>Q)=m(8>0:b? |GQ?d?:S+?eX?>XU> S8PIFCuH?(??iJ?$lbrȼ^пqnivo"= @?H`=Ct?L?.2?^?z?RY\HhDHa|ƾ+>s?Uyz?4*u>﾿(k>x>H?>Sh>Y+XxI08?G8>#<~>XtT@S>?>MtDCzȿOS)n A?*>t>I~>0>>]Y?M&=>/#h>3d `W7bA)`??Fx= X(2# ?[H>g?i4_?]$?Ɩ?2.Z>o<$`?$?ƾ2\j?<>l?B>眧֫uB? + ?a>E?.>A%E%run?Vmʈ?U>v*#&srgA0>=L>>o>^>]wM6>>P>-|1>̿ywN)>+"ݿP"q+ C)@>Z=J?濚?rý=jpS><>+Q?X=|>t>>5:=(>e0>π?@{ȾȾIL֠>6Sip?l 1{>>A?b^#p >޿q =ᯒ->Jz? ]bA?lGN'>1?\?ʉP>>V,,?9?ZR?y%W?=L> >$?=?[vO(?6?U81\}=^B=, d=Ģx?$oGV=Z=𾊌=>z^[??[?h>2|?m:PفN@F ?Y)?Խ?#3J̀^ھo>?6>^SI.3y>6? i D?/?u~?g%c?R|I>dؿ>k-Pj 6*?;>6[?5>$ cx?~TF$=EH~)(>I6~>>M>偾 >&h=?La(,? O3@L%o>?I?u;>>۬?/?Ui0W?D?=5>zOh? =b\>^ij>Hb@?5i,>7 >_¾#9?H?N&?8#c>YM=/XaP~$10Heaj??/G[?,> ?\z6>܄>>@?e >V}Z];#us!ܿ ?F?>?av>޾_?ݑ? v?A?8?&^fowY0> @> I? su$;?5b>>z6>$j\?3н=?V>K>4hM">@"?,%=$>}. =@=?/??x>Ǩ>Gk?J8,>z;FI>D翾j>zk>L["Md>ȿQ>*<5=$>Ծ'\x,?}˿, s?/RG=ݰ5!>֢:?AB?M">+>:>|>Bn?#Rj꾿fy>$}=>ߛThA`?r%' (?KքF6>W-s> p?Q:侣Ծ|@<Խ`9>%T??C? &"^Կt^F?=𾫈 Ҿ}1?@r?xi?K?f?-=MBxB@zBd@B&CC;gC9FNB~dB[B"?*BBÇBBBX BBB =C$BxAIC#MlAx""BqyU{BUuBA B_6BTBY?B@Be^7B%PBvB9g¬B@.\BxC~B}$BBBB6vBWBYBYAC \B2B!BBRCSuC'qB4AbrATC$m`wA&,S+ !A->bC0 ”w:¾0:JޭdBA;B~žBRC9BBGIA+C CFCVmBӠCAGC;eBЖ@zG# h)B*BR'@SfM?B4BBl:A1B6BS.B]a BRAEBCB}dAouBK…]BO$B2ދB$A}DaAl9RB@ĒBZC$ChC5(&C]Bz@1dBC*+B[BGBb\BByC wC|B C`DBLHB!ABKaA2K8BDBRBmBlB8]cAA(B8B̺BTB2A^B6k}B@ BBːbBE QJTAC`BQB\uUqƒ>1©CpM&pA|>uA"BBGBJ`B02ALzD$"[@|OBz¨X¨61|²Ss4O¸ }0s4RDGA4I(`˜•r ®3A5B0®7D3!IWAS,ºJZ)k9‡6_N;k .L£4@$ej A5vxLޘGŠqBAɩAA"BB4B7a?’wr…B$yA>A&|B-B@B3:YAH  BUMFB&5A_@&eܤ.>B'_  C/|C>AzA؛BB;BTBvB|BiBlBwHͧA CC#*BC5|BnBSrCB`{B%C+'{BH\CC'CvC SBÙAB_Bf.BvBBB1TB˜` BϗABCiCPB,,C8KB^BKo[BAՊP.A"BB,\C0^CMUABӦC`}ͲC5'BBsRA$B9B"šAj?FŠ4tBNڹ{BFdBhBɣBRBBjnBHA͜M8~¼mKpͯTgB[uCOzBIK;BA`b+f-ŽOB٬B$¯BQJAȒApq`C- AdABB&ZOA}ArFM l@ioBnYB$N"BhWC Bdo`BA BAKBB8BB>-Ơ@̼vO@@ ,BBC C9BvUBB샲B~B'<$C)KCjBiB;BtCC2 ?OeBBBRA jB˱C)G+C AvA(UBBhBBB~C {BCBoC3B=ƶB~SCiCAC_C66B܌B6C9.COC=mC`*BzKB?~BJBV@?BC!-C iC }CkA ACGB3B LB\c$BBq@BDBA}BB(VCA@B݌BAB-_BC CXBz#"B-)BBVAIIB,TBqJBpBEBBBfAnB5C)ݓB$C9BCwB lAfBMB BB<~ANB57BDACt- AtYFV&B*PAxB4cyGteœB{пBQBBCJXCBBvC#$AdBC CCCCoRABXnAGbB&BFBtBB:lCpHCBxBByB4!9B@BsB"/2Bk. BjBC!wBqC ~CB_oYA#-o\B3B?BdB*C@U?LpdLBJ'BxOB3,B BzB.B~Bh~AoBB-A((BAAB)0@ݻ­l{fA~jHhQ@2A4 B^-^BNeAB-\A"BJRBL-†/ +0B_.nBlߺ?$|>?EH@qmr=?FNB? C'>fkUf3? 2:@>]u?p:ľNDn3ckYhP?Jj ~4>$rg*N?>ƿBmEe^ ?^ؿ%E1?L߾y?[? wKbg?Jֿ?|ƽ$u=tjֆ?6C?>>,ǿ#`8?Ej)ܢ>>wszmn&>^:g~@> ?Ծ|B?OL>>ɬ's??G29j> ? <~v,?Ƿ,*>=Pj?\ͽ,c"o1?)ҿKy>ZF}>uy>\k?=\E??P?D6c>uuV?>m?M0?T#B?C?I-TN,?^F?꿤iǽf'Z>m|iH&5?^=>TJ?uwtٿ?m=̈́>Pu΢6廿>lP~=l/>Ff>ZOJ?Ҫv1?aoY=p@P>H?zO{<͜={p?E(t???+;L?>>-3يa49>= L >LvU=վj7¾9?? Jp l`0F/Q=?A=ھӥձӿtj3V??L/>ƁTI?$.>盽>!<>B*PJ%?W|п 6'??4?`??Ŀ>>/a0 ??@E>JґXB>/{B>U -իs#>w0>R6 =%0Zu>9"x0?t .?? >;0i*Za>>nqTl>՚1lQ#q'?6(>r5<1DzJ>+F>$?D*ۿA>*>T"澺甿,ޒ圾]P|>O4= =^f>l>J>n]??vzo>``p?mbrȽؿA#w^Z⼬d>C>5vWp?(@~rݿ==B -->I>݂xK==UȿĽˬ<;L=I>{X0>Ⱦ>ŭ>Ľ`Za[+?Pp)>|=_8?쾔RON>e>׬@&`?a|:>V"Ό>4 >@ >z= b2?dr@.l,%ZpL <?x ?5{p m΁>n]ܾ /\1 >,ʿb@E=>iF =7C?V?%츿 >2P?>EF>&S>Ў>d?Ŀ(C>ظR?X>3|]tL> !aγ..=Q>TM 6? ƿ*$澷{?:?>?]]=T늎;?@eyP`>M=?/?%?NS(>>׾P2v$$=;j>&?P>|2rZf?X? >H"n>T ?I/Ͽ+Z>ڿSx4VqO<=|> 3??>!6`ؖ; 7y4??R ,4!7?}=c>?Kt}߽|-W?k<%%PU/2.b>%qz+0>Oߠ=x?ySX?I!1X&%ļﬠ rO??eJV꾄f>j(q3&iF<ϡ?+?{ؿpCYp?,?>7F>reev?'v$?C2?ҳ?0 !Bw>[/>>?p!? U_>(>{=:^>|[>?Sq&>">-p>aSU`=$Fu_?4N?^3X>%n?mľ(pjI?>~U?>)>Q?,pp>kqbj|ϰ?=FI|fj=Ƅ?}??oR@_v>?z?poj> >Z澄G,_H<?ߥ '6Z?& x>>mn>߮?,t=4?-l?&>N?֏¿?ǰ>V/$?=5}N%? )?P20$yU=4=J<޿ >>೩l%?\>&9y@pƽAQ}UT??]>U>ٹ\Jɘ=T0?/x>=#Df?L&\NX?* nϿR% *HU?ON?>?.' ?|QKD?P>?m>r˽?a; {?c>q|ÿ[[|>* ol?=ל>>:¿j>6ڿYо*`>?vX?u ?腿/">*P0? e8>!a\x>>!=>zI>3ט>wD>6?ם7D?$=c8N>x>n?>][𾸬#b=ţ0q?>-Bu>w[ط?b霽׊;/>R>c}>\ҨS?pf?Lj?^>@&?iߑQݿ&6T>ʾ(?I iB>J:&܄sf#!5S?>뗙7[\"=A}޳T>Ӏ*?(?of?VZ>׀ET3? rU>UI> >6?kVo`6%Jc?>Ɩn6-ެO1qEؾ<>>2J> >Ҕ=&пmc}??F>aݽ1? Y* a:El>><`?ya>C>b7~u?L.̾G=sѿ[+F>K\?728>p^=\[I`TDV?˵/"GD?.?jVs-0=>> 5?B?*Mi ?P\?Du?(v?TE>><ƿ4켽?:>(P$H r?>F߾]IRb>P>Bv_>Y>Y| ?D>^? tؽ;?a?L+JX?Wyd>E0FYh>|?(f?Jѐ0r=)`F80:)?J?쩿%п;,}Lz>8>t@P=z>a?w>>T0?DE=.>¿s>#?A?f`VQξ{_7h?bp'>ە~nj=cR?u?N ;w?$?:~.?(DŽN>P?S~K ?獽/E('>:;x,>>q yѽ"b?xA=*,=5CfkN> Y@<> Lb?J u@nD=?D8v>}?':>?p%??/C?وUn #> ܽsZ'>\ CN?=u?O?'ſ pj((?#z?URM%p U= 14 E>02!'`>Pt>O>?¢>/ؾ]T|d?>x(qY=?O>CAZE/?@>"ݒ@xHKLx>19?6=>:W?R?(<8*Q?9e"=mP?ajjnоY/Y;@?;y?k?#6 LLPtyz_ڳ>zڠ>"D?>=WX=@)&=WWj?>|N?FR2B?=Ǿ0>uF??F>L>h'>>7׉?4<`׬?j9U ?Y?H?A տ'=<`Z'j?M&B<+ ,Q? v=;0 >ܾu.K=?T<10>rN>;;?5I^P?j>_?nx?p >L)b{Q?ll?ȿ0>Ri>'M>d?\>>Rk$>>.yX> >==Uj=h?[=M>o>8w?d>>*wh4<*鶽ؽ>꓌?>jp? >>D̿-S'=f?<?2t?H>Z =>HBJ>4@QY = <%&Ap>#ɾ J,0+ߌ 򻒿7>\Q?:RrUj϶?4?F9?X?:ѯ?pIR? p!= ~raþ#>I?3=>bw>? ,=?)6DJ>r=~XfD&B??|К>Ł? /Ѽ<ڱ1`; DpN* F$?H.?^D? <>o>?&,>??Dc?UHӋ>i+>8?e?!ռ??3Ȗag>t>lfR=h>CRf>>z>M=q?0T{T>!?qhмǎ=>A#^>-? OR>N>H|>OEQn umVнQ=5^ݷû?ɻ@/ >sAn⾷'Ì?ύ3?C@=>>)zǾJ)Tz>?ͪR ?}br?=`->O?.:>헫.>0h:?->ܾՑ6?E? /?^ $=] ==>)O?Ͽ4(@>򿠾>&j?6T>f=9.?;?$8?>5IzTf-?L?38??~?KR>+?j?b4?!ܞ? _?'{x>?!*?oJ>h6n?7'>Bw?ud.X>Iҽ*JXoR?BR>>ި>(>ݔ>Ԣ#v>b-[?"ھ!=$@?yGAD?Z?CA,>P=m??D? U>t7>.a?3솿,; C?Y?{??X>^?Ql?*c>@=t訿(i޾}<2>T>^z?|ڮ>mA?a >?&=] >ȍZk࿱1ƚ?`YJ?V?_?KBa?2>?t=k>kZG,>o>O^w>$lT\0@?Y%>0=^Gm߿.'^ƾt>:[}?t=C; ?al=(? ]Z$<Tډ0Y=&=^x>=?Mz= ?;C:$Un2F>S!?U4<{0l4z|>׿n0(>Ԅw=올?j꾼Y?[P?@?3q>=)s>?w)X/>(=xhX>@g?pr̿a?Zھx>=M@6?b:@Հ?R?@v</??><9?Z[?v>H?LнXZ >ʞL`Ľ='(?\r?#E>ou>9?AT=|g8?>Μ(>p>}+Sd?.?۾m >(/01 pيp> ?)txG 0??T}xe>??Yp~=փ8D?c>f?96K?!):>Y@R^_i @d> G]K>>?>ھ?oTQ>DU9ҽ>n]>w =^?F?D?GoND>z s>7W?|=p>q??2Q4?/1>W,>tv`_Ů?VM:Fɐj?P>V>f >>e??F"_wc>x)>$F>^ >>Sħ,?E}><|>=LԾH? ƽTL>H<<$?8s?G/R?lT?>!}ʿh+f>>פ2?CfV.?=0g+^-<>>8N?{Z?>o={|P@?=^?; ?! ȼ͑dc~˘\M?'p ?ҿ>6?Xl? ۜ?>+?]d%û;0?u?+t?30X?ʫ?8=P? E>?$X>r >HAI$w8_L>8V>#??O?ο??"&?Q`??.1οd/MοI8>j~> ?as?UҾ69>UE>!1T?ȐF?` $-[žAZ>W~p?5< TJ5F?G2Z>>(U=?C˽@?W$\|>6&cܞ=Je.?4?(ŌA}c=} Xë?;S־ό?f??=f?\J`>|C>b?Ov]>O?QC޾? ?_A{#T?&i?|We,?Q.? ?.>l2>{r>" K ٿk

    >E`C0>C>s? "'=% ; h?rk>O;?1Ÿ?#PN Tx6X?о>&?H14=>I2?>"?jR>,jfW8㾹Q=k>d=~?$پ젿P=١p>,?$?J?ܿ>>̿>|?`?L?̻@??%?p?\x?_e?S?,?+!%4'@(A`B9zBB B4nŸ7U9&AyA|bzBRƒ¬zCHB>ABp…\{ ( 0C bB $BuA TǴL’k›BT3AV¦=F"7‘D)ŸU2BUX6Bƃ+AEc1ȌXM4> @NB.z竒qAAK*/Rsk~A_=6AnV|BpbtWAG4AA"'tL A3+L=d eAf,º7“.B؜?dthARBAKRo3A8:AAAѿ2?BOABt@6BEBA6KBŎ#櫜>sABUsSBB/B[aB|A9B>GTqBR&ACBUdVAU_«Usƒ!£0B+f@Ӏ˾XB@tB#°n(âVBݲAA B%aJypAwBB&Bf1V<7LB E @BLffB5A.EaRBS,AtsQ2BWBу5A-¼A0B.B>AXzkC ZtB:BsBDzB#CC.RB]cBB ‡d-BWz\Ah(Œ'A`B MqABBN BxB,B{s?B BZt&=|BB`N£BמC/22B CUClB"B*AncC}B×^kvы*QxC3B-7-atBEBpCABlBs5yJB`B:B4 BS.(aBoBc\B:BB^AB%@b=9 \B`CBC`@BPB1B^BSB_BRBzAIBN>yBwؠBnB!y(BBIBBBi.BXBPAC: B0=BwB^/C=`dB|BRNB҇BACB;C:B^BBB>wBBZNlA$@NB|CB:B^yBD—A[xzjB5B|B' BlO'PAY[C BtNBēCDC-~AN2B"BUQBg@֠CX@BB%C-BݗBCB]w@B [oAfCxB dA{#z{0A$BAqB]aBO,ZLAr'wB}PB!AٳBvC=BC $=C2`uBnC $BBRRfA #5BPB2.BBLA܂`ЬB6B>1OAA{|z rA‰]%*V5A¡qfAv‚ Eא/_46Au !B iHbB8ŠVB9Ax,BANž/NB]CMA"B`.B<A襢B&و£htA=BBv_BAx|~B{QBAsSA?'SBJSAWdB@ Br®6"B•fC"@š}AH6 v BnBI^M_BހA?BpHb!BAtA@B_ ¥AAf*o @A\:nKA»Q$UBnrCEBK| [ŠFB 1@TBBg*@&$B? C$yZBY=BӵQEBpBICAzršFeBoWg{%B?nA[ ~& g+r%2 A?jLE-A7!6ЙBpBRf?NHi>"¾n*¹@9BBBBnBw\B*zBl׷ B_·:p]sH…ckTA[:EMej?-A7AO, z??Aa7~AxB-B2&WB"=BjB,H/¢ -B1…4 !j:l’ftc#ʪ#BDB BBݹ5Ata›AYBg&BBB@'Y|c@lAkBȽAjBBDABiAx0atH@A"B@fO8C;L{Ae¹@2AAMB3$Dz?kc0B L:B*B컓oAB[A tBYB95BtA8RBÈ+B(pBi‡fBfHSB=Q(T$@¼6g{0acDjB~t†Qx:˶k¼9%›TBeKCտ8'˂?c>?zPs_"?1>]*DB>iʿ fz_~ N&>tg??2NK\ܿGgpT=?>q?sL&=D[,?>YU*?2>>z=_G=aB0?=R>?Ӣ>!?wпuw5)?4>I >u&ҁJ?Yh>%n(?(+><6P|AG>ä >x>m<=x=?=2A+?j>޳jI= )=Y?B?Eʽ+zG"f<1>n%> ԾO>L@E=Th'>zʿAl $DG=`6> ?=t>Rg >'h<@@=Վ?L>6]+p3<=SU>O O=f>{?ѓ 2J]S">kr$`? ebO:L8Q6kvd4m⾣7W6?Y>= ھ$43aj+>W,=l?nBP=b>U>tГrN>L=fhrOz- ?&nw&~ e=e`?мV?[e>M|vtj>-?@?f? 2A>r]b2`$=rp̆? *ҋk>'9N⾄mѿB>x? ?& b8[?W;`Z" BYXg>%#kR6#m_??OcB^>=V4> j?DX?(?O?>VP4>$?E>il=>?d>>虦>`k/zΪh"?U"g66/?! >?S0??9X?Y?@>> y'=мg̿p$?>YY?SW2 >$a;/'->Z\8=ԿNJ> gBN>;?e-vF> >?Ǜ>NjaV?Xi-^Hv>xʽxd|=8%=R&?>%`wA)>\-6 t[@>ږ?t@6??t~ayZ>+7> !BW?)U\;W.v<< ?ľ^>{բ8v+?=?ƙrF>U Gܿ5 ?uu?8RXLʿ,5fXyZ]4?Ub u侺? ҽq,>6Z>6?.>Ҿ>3,f;>=>J+=X>-?A?+7⿣+IF?&!c>k|U>lNοM?4ҿ,:2??E?`v?ϗrc?K>C6d&`?9?Ͽ9J?>oNr8Gu=%"`Pǿ(h?RA>\R?o߿pxd>>d>m>g?'?lpΐ>$*?a>j?q>JvտL?"aT? .hȇ2> >G?N}{(n=>w $v?F_zhUA*<-пH>yMH>e4>>O?~'wv!3B?>"x} >|AR>(W@AŘJ̾}?W+U"=;^>?s. I5>4ZDtK? ?~F?0+ H ?)@ >$@|?:п?+c>VSӾ=о9Y tF><ؽϞgw?uܿ5mK@2?u?|)O?b`?ο,Y'ǩ<X? >{B>l}SWٿ7Y>_>?\>ς>>BT74>~=;f?cT?w {?>?'=?"?=]??J?)lg>]ѿ?$^s־¾eA< V? xj6HDJQ< <}TzGl^l=&?sYVRξGLӿ(?z>>T"ټ[rߊ=/>N?!KX?R*C~?kS?, >.|?~hIp?X~/k-Q??T>\f>uN?rK>0?.X> +YɕjP\z7iu/$ iJ?HI>8>*fh=$?W# >[?9?>K~?Z?ɸa⾗xJf!0$w`? ??2 a?g?7ѻp?>ܿʳN>5SpR(?$ר۞N.'4 0?MH?o ? (?u?wпa$]=>B$\X> ?Np>*I|?>HĿl R>?n=?V">?=ƿ)^.[f4>v? wA}S#i`ˣ r>"t+??{>N?u޿J?R}=: 7|>nnT>¬?m>R>Ve?P>RXp O=i07>0򿧟࿍B~>xOgl\N_B|Yd}}} 3 D?q?),F?B?=C=?._,?aE><R>?Y P?.>W_^7 ??>츿<5 霓_Kro"$?(txK:Q⛿|4 6?a U $`8= ?w?'> K>Of=N$?pt?>ʾ>^?`lP>WR;a<=@?ܢ>?Cľn>=}=*eE?#5|?Sq?[=zԿԷR> y??!jI=N>k> =;%>J>h?+S>r`=A<6x!,>#Xkп[οC忂re?n|,t`a>xh?f?%ҿ ?yǿK ={`?+#^Pa^gH>`d>iu&>m&-Ⱦ\пć4 d?\O?$#? eod>t ?%]?M@༾0AJ%>34#>У>Z4>SS`> 2\cږ5>?^a-?c&r>H????@3@Eƽ)־iҿm?#ޅ)xA5bCZȠ>j?ンh<Ǔ K>u{&>?2Đ?oI?3?#>R>Dć0?q_>Vֿ?1?W>.ydp>!?w>x>C!(?D!30nK?$z2?vΔ?6$1?ӕož+߿\P:?}8,Cey>> \ ~9?4 }L,>QaȬ>~?޾K wr? sĿ'h?)‹/?^&?ӛ>,̻v@>L= >'?A?7k> ^⾔7(E>Ⱦ)?_l'X`~>V[SA@t(?;l>G?O¾%Qn=X`>_C;(?W[?k7ju^?m!@Z݃?=)9Mr?8N}SĈ?4H9?ھ!?%?T?> ㌽_7!B>j?~ <=Ȁ?Yzg?zT,??l?9_:?P#?^?,?o_ N>/濓P=yP?oG>׆=A>ђ>hH&>`ɉZ&?0['?%?C>L5D_?S&>M!Q?V>.,>Qز>~?з? uk?\yWqۻAnݴ龿sf>>*=8'>ޮ?f > >$ ?>`>p??4j=?M??={>zW:׊>wWi$K>PH><|zT?_/|Y??j=&ԾQ>=5|>~ J=>hi]>УҾ@"l=zS?&ֿdA١< >J̵#/?В?f ?/?P[?m俇Y">Q.? {E0?e0(>o?@>?Cij(<->D>l?U?!;0@`>k$տ-?N~=}p?r\>r?a) 7b޾@ʿL~k==(1G?XǿB?)?d}"?u>jX^4?,?-ֿ<ۿn/HJ L?I?h1?u{K>p?n$k|g>ȿx?F?F0= =ܦ`GL R?i<׿Q>&>@ݿ ?'>@4FT?v[W>߿cҎ˜ʻ>sx>$O4p>R?d?ʮ?, Q?>*#~=⃘ ?>Kq?=R3`%p>3-?Fe62?As]>Ӌ?a|E!C?=>>:n?fP?Jp?3ߖ>Ū9>`Hv Ur??NI?u>$-wIY;l>%?z?~>mu"?6=̾̾VG< /eaF>bؽƣ?"l?I7?Ad;n侵w8Ҩ?l?Zd?;(><^?z?JӾ1:B?ծ?2)쿁PbowYR?oNҿ0*clRIοy8JT>>BA"?b)@?b(:<}?<4!3?z>>G=VD; ?K >k̿*>V?ht?a&?*](f=$h>G_G?.}?q?Bw>>W?e?7Z>O?0s1m>1VOw{ͺ>L?jZ=`?jq?f?l)>;ܿ?W?h'Gj2?"4Z npj5H>3kpu?5$?>>=?Q]>N<->;??L> #h>Cr]8w>0?B x?d#ݾ vln׶>=ʣ"\.B3>ly?g޵<+>άľ<>?9=?>$p4~=>`bz(?l^?1'=:2?|P>1?u|?R!4 >F>Zul=,%H?>ҙ@r>.꿰q ?1?B?'Hj]???6*?&@>.V>(ǔ?j8>俻"?={d྾& >vd>>@?fR?~r??!&}>Ƶb>+T=A i]?>>?r>?U?A=#h??)#>1>9?=&i`?%!?C?>_Sg?4Aa6H>B˾]?n_>?0'=7?'!>E3=&[He>E%CX>l"t ؿ0U?~ب?=b>V6?'= >+?V..>>?6@5?s>u=Z?p>\?a]?lyѽž>f1>>>N>c[?/>4J*>k>J΂&˒<`>TH{>?Z f?>yݻ?-@>s?80+t==ʴ>=̾]kC>b;\ch!??0j?JyF:(?Oi |"9??@>l?>>s=3> >ݿ>@vTu>XLGѮ?Rm?7 Hʿ?H?qՀ,:> xݯ?">cU?&̼ Dlμdv־6?Y9TVv?xP>{?m>t>҉/$>)~>">V>0Aʾsn?d5> ?lR?N P:G? 4vY">``]?S> ?SÆ???)JA?X?{F>տJ ><Չ(½t>ϟ?{?DWX2?!WL3821n>p[C?ʒ?e꿌r`QC>h?D?y\>L$<Ⱡ?L?h>?3μ*ŀ~^SBC>ü8?m"?JG\,>p~8"^>q-n>kR??hs\>:l?>ƾ3E?:??xh?k?N?;?*<>\88Ҿ?ny=S?"%T0 >n2?9v>?8=t.x>>cd?o<2?Jg>?7Ќ?e?-? E'=vl>=@f\:(>Nܺ>qw?Ͽ !#:;?@u>:?#z.B-Tzh>3?ZJ>4??m?X.= ?;P?T?%y?V?t> >:??` ?2??^E >꼦?(ѾW>, vJO^!޿J?H:? >r?]B$EC ?qBB2BptC;C]A<0FA B1!B]Bn˜Bo^A=BԓAApLjB Bv2AZA[ƒA3BAp)4B@jSAV]KvB5vzBBUB|AiBB/BAB[;Jc3QAB$BcBBvBDpHAз,9=­`d!°]AWH_AA C0C$"BC vAWO&BpǍBC?BjCTA-BvBC7x&A@ˆ(BGB"B2CPHBBBRAvÔBÜBUgCsB#O.BѼB9Bė@DrBxBG(?iGBjpB-r BxsAcASBJlBAZLBo Ag1BQwB:N$BmnA&B Bp B?ABJBZBhާ`BP>BJ.ARAMCfBjBDB"aBv?`BgAҗBGoA}n3 hgBwBB BABuB1BBAmADRAB^9Bإ\ByBBcBnB%AQB^]@ A thB(oCbBBdl3BpwBVB"BVB/B&AAAU0BJtB4BBB˾BLA^BbB73l4!ChBB^eBA/6B&]:CqC61B/BzBݴ[B@(BABA`BCkTBB 5.5B>C& Bœ^BxoBBvNŽ?Bn\˜B:uVB0xBڔLABQiRA.C@>CB2B uBBlhB؊*BMGSxs(BB,AHAB~nBՑBh¤ABˆɑ/2;GM1y X-#\|9B6ˢBk|AK*B0\@<­B`0´;AK BH3`@U"B;B*Q$ىATAz~?B9uZ A?3K¦)AnB\(`'y%Bu~A-&›B.FhvAF$BRAn¢AABBa%|BiB@B*BA*BBwBIBhM@o:FB Bšt"v,߾a™A;9,BLB퉇 ‹5@Nf(B+¶IA ­?eA JbAh/Rv,~Ba8¿z/¾¶}†uEA6@vAA!A.NK@[|i2b-)\AMXBlNٵµºB\J(uSl,Bc+£^B 96B‘q'BIB‚ΈB$BrgACA Ž.AI@BN.yB]/Ph>BB ‘2ARB_B06)߲wA@&BtBeQ%Agž80‰KɕKv€1S)$rŽ©zA`GW}P@ onpAhv`B&TBQCA tTC vBIhZ2A{EB>B`:AÚA@ABsf@A&AtoB N0BKBt>[z$@bQB#73@6@B-Bw־WB1CAB@! ,"zAH5-7B6^@V`B`BVBM=B&כH1=A ~BןMKA_ 8S.¿+yªqAB4Z#~A[B{.¸vBLmtĨ=X‹} jcE|)4~°*› 6WnKŠ8~½¼v>YMS)2@<8@L.©'ws<lbTvB[BN C\OAK,BsBWZ&AZ zBkAUA"A%BBd\B>BPMB8BBA, €[h~‚o[! P(~ @>bB3IBy/AJBZ=BUB#¨r(7FX; AA½nl5U?㸒]| i?G9rUt?3.£q‰g-¥[fV9¥ͣ2B9ս?ξP6H?*>$lGiݴHj[q?^3?߿|i_CJ>3?7\?'k?4 \??F? D? ?(?qj^P ?^?&?N ?3a=y?#d=FT~{?Bl>t3JE_<;'@&J`|?=?K>9>,d Dt?qP;߀? E>\=v䈿朾D "RKf0ڿxq=T=˸wƤG*=)]?vOi-n?[;?/ Z?plF>#?-Y"?"6>MV=&֌J>z?6Z0?J9oz?SB> Ⱦ3`P[T?'j=[?ѹ>|Ce>K>f>\?!6{(q=:hξ`"=-L?G=;} <;d~?ሾٛ?H? ]3>|ͨ?}oLG?ʦ? uUO.>ྒ^>M>(Kb~% $Pj*V?R?j<)u>k2>o4?i\={!?>i>d:ۿ;$'־*?g'Q?k??.2>*'? >7?ʦV?L6>3tq(>V j.Uu>?0 ${j<_x ?Z?>HqI`F>>=,?1I\^pH-? QlPr?oM?F ?l;}@!}R>I@7?6?2Jts4?7l쾢> l>fc7.?Z>~ t=?0>dtq羔>蘿̞1 ?WQ> ?"*?)>峾tWL&=nߝ@68=?]?=(=2??5"?/o!<>\ԄZC;d#dcK>`Kľ>->׻=??dͿ@m ? 7=~j=K=b&=4Vy;@@, / >G>g|\>>|??){ EJɺ?ޫ?nb??H*?6:>rvx P?x9Xwjfz?QL%?c(].޿?95'W"9;濗 P>_HUE|s>]6.=;̿S rml K?ooڿ2i^>/̠P D?){?1Њ!a=8>2]?EリB(=L~?&T@$>, '"h uF?,Rn^7??j>3ڿ?=->dwq>~?:>>>Gd=s@X ^>нht:@?OT?䘿kȾH.?w> =[b;tN?N> T>vȾRϿ?8g=ZLmQ:?B=E ?$< IE?'(K01>>pGRÁ_? ά>KlԿfJ=}?K>S>*?4Y@>> H>K?=.m.S>FFa>=>O>ۿTv`fԿ>x:)??;,8F澃v?~ ; =?`?YL?-#D>7(?MJ>=AR?S?"?4P?4o\?="=6=?|>C&s_ ?y"]H'1BT?`>M=ܿuҗ$?C;ȳO>qJ?$t=@=p>-?K;B?Pk`y>䦽h>1"t?׿/Ҽ @? 4 >/U?? ?֌>菽U|=6?Ni?z \;=K(߾6>'p?S=d@IV!8xr?J}?R!=;p>sD?/JP T!@ʾvX|?=zW'.ӽيeٿX2\?ȓ}=`t?$oe >x <='kP=G*VW0? K x?5?O,'̿ Y>Y@>+}]>P򽊗ݮި 2?> &? w*>')wܿ-)`.7)0%E`>>?1; <)C8?(Y>CjX?>"?ӽ?S>̿6v_0n>/>O_w??)=/>6ؾ>qO^UN>5?9??@=?]a?r>p>Ծinvoο,>迧Tco">aM4>B-k?޾/k?R>gT>W\>0`?4b?=rT@?K?>^V>0??7j>>v=N;?Ͼ}y9ch8g> $z#[2>CxYG< ؾ`K' >.?>?FF?Ob>?O?#u>8/EՕ>Ӥ*?Һ>S|>!?1ƿ_2?W= t?>az>AʾıX* M>J{?=~Ub>3?>?->Ew =?{swZ?%>3}T>ˆp*s>cxv?θjI1?~h>駿Jd3佃T҆8?W7>?cٿ_?L`=gY?h2v?QY> C?x"4 >0ĿD׿Q粕)>P*>Y4>z捿@>eZdV_y;%4?ͿHPx=<)`fOH>>9 >p,N?5Z8=пK0dܷ>O@ >^?+pa u'gN2¬>3=?|R@\?>7p>aT>Ȓ>'m\dS 6?˾\^>:Tf쾜@q,,8?k]D-=> >+PZ还|/j>l*xiE>ƿ<=#x?m >EiB9?A ؽɩxľ̿0';?C۶>p3>ޡ3т?Lx->ڼ?0Yv GҎHF?1͝>(f?D ?Z>Yv.T>_?&p>>X??,w>>c= ,k0=%>$=]{9ȾUnnd5d&(W?[=Ϳþ4%3?2>>w`Z$E^0.׾7kƾs?Er+>¤k>ſWEI><;?Btp>T;)48P'?,T2? >{26?q >6?i?5?am>&,Uj}ĿQ>>ѵ ??}߹:$$bȿ.޶?'8~ >0> g:5'->dп?'U3?>mX?*?j@=jjʿ=R-[|hC 8!6=%0?zr=&\>=OzYm?fpyl>?eҿNh?!>>?(*mبa?+?.O>=?5?)i?W??a;忒xp=(?"=hUB [=ȇ>rd\^͋?CxJ?GeR8 q>d\e.>>O ?g>>v?'lP;>??D "!-feV>/ZA>6f?˒|?{>h? N*յSC<`?;f>6>;[>C>=)Z>k)n=yrZ? 'V>+?MսCS? Cqg!>c?{+>058Y=4ۿ??j=1_d>>r?1M&>?7ҿI 9>n\>(>˧?S6~?~Kn>⛿)Q>4>2>繾j>y m> нl??dM2 lŎ>X?}FO??W?h߿ ?zҾP(a?>=`?(4&?i߾s>(>LV~?=,L>J?Zvn>Sp> ?JJ٨?g.?>T$۾sY>j> TXzr>=}8p??=8p?|>>{=B#5쿑6qxX~Js*?MWs>њ?;su?>?tW*? ˶>>?d?B-X{?F>+Z>|9>k Ծ^?>;= +O?j̓6?@%?qaD @>?9?Z0Yʁ Ld>v2㤆>^n>.5?Z?pꇿk ſʫ?aE: 3ؾ\>?PQͻ />ݭ>>!ؔ?+U<~0?lb|x.?>}>#^?Z=#Ⱦ0?dOzU]2>SD=h>3?Z?!޾9Q?o>4?iQ?(?̙&1v>$?Fξ=J 4'?w?d?*?_h?'e>7}nDE=?=?eE?~>^?o(/6)?8pq$?yĽ?H?D?>8>n>B ?SPs =$?mf>>-DwȿWp ?k= Mg>JX=dmG3|>?V*?>(մY[>x%ӿX >?φOU?r6??`=?A'?%Ⱦ_M"Х>ݘh (O1??sྞ9> ;L?'>??m!G? T?2꿢&?"d?Gʽp>hqP>O|??Ak??+Я~<,>y>νWֽF(>fׅ=t4ϰd?$s<> \*= @>ͦF>$5@?a\ >=ؾ<ƿ#Ϳ? TpM>#KU Pn]y<<'?1'1T"JϿD>[S>~~?2 Ks?T?I|>ښ>??Fk?l?.8??g&?A<S ;>Qu={a|_`>Sp">NM?>qB>Q俀)>6(Ͽҿ8l>pL?s4>1H? kcx46=vv?5>”?j?fR= ?1n=$-6=%i?>/dќ>́>*>O>P?6}d?It?HC>2>H=?=C9||?f<ؿR>A6 ^>>Ĉ>?ȑ?5l ?>7L>$?ۋ?^V>>?p?NlB~v=>ڄ1at>`>?LW>{d:¾??v=r]L?MST??o@hNxIk~ȿ2½@(4>b=Ψ>$T 4S7kKƜ@=p>Ƅh?k7?(n<6pL?xހ?;=V>Z>7R.#n+0}¿ <>~?3&>=I_N֦?? PkH>!nr?a>'M?+Ć~p>>a6?4>?_""a￞>ɶ?r?.\ӿR-=\?5ز:;|Q?57o[ٔ?`~=N??A?`? D?+],yw濁e^=JR?r2?y 4>6WȀ?a?al6\9reF>Qb؈X{>N՞?n)? r>,? ?>]?&8; >e=UĿ$Ă>1W->$@{!-?*=e? p龠??k5j?VA=UF>)\pG?r>x?v@elĹ>hc?}?Jv?۰?Q@9/?C&~?/>a>٪O ??y׿5cՆ͛>X,oU-Wq>Α< >d1~Q$:?Kf-e>>c?#>>NJ>4?K`?c>nV@J|[E?}4>> H?Ŀڿfۿ6(><>y?F?36_T>?>7=ѧ7^bU@ȉ?4ᅠb?ؾt=р=[Ѿ#k("<>d?Td?JU>-L.5F ? ?)>7ܿl? *>0UQ?CL) _`>CL~?sD>\UA? >}9McZTry>w>?># >G` ཛྷ>a 2?M%ǽ>?^I?>?p{?>7yW̿F&4E= @J=𔘾.HY0,?6*Jk>a?O?f??JȿkMԾ?PӴ>NX?uRP>Z̽ƍ*>|ljr9⽽q Ᾱ;>^lsF?}<}?]a w%SҾjk>#ս.j-3n 3>>|x¿v>򾍂㿂k?,p&?>#w??3h? =j&|A\A%B=rAa:BE>QByBcWRIBBBpCzJ@?A.µ 0ݝ: `Iw6N~U7Bcr~04@RB[7AB(BkBB2CG6B{sBs# 7uOk:Bq?.0=SZB}eB\J?tdN– ¥UsAB.uAMVN+#3'B#7>27W—¥od_!OMO%hBxABNA B=UlA@hB˙*ɊŠ]O£*‡ӷ  SAUA?ŠJuUh‘XZ=i?rOƒ&A~A߼Ӭ&Fµ>pBM¹ĹA_>jBO7Yb9pB"¦}.B{BD4B B?@jrn >jtAB ӈG$ACUn-\8c @؏ H<|BҌ«eB,¼5hrNœY’A>Jf2pTB4Cd²5B. 濏ސ“@XdeAGq^IU+@¦٠¾E@BD”L²4BNA3KI%`w¿ą \VB-J!@BO3>PS#ŠT9„ᶮB (e& Ar \«JqB)6BBBIO€Ayiꧾ3>¯"»P»qf; "^„9Xj–YBBL ²V•Bn BA <Nrp@Pb0Csa(1@ e¿t’B{u o$Bž5AtpzA[@§IAg?ŋBy >Yœ ;p€vB6^BzBfB@;b DC(aBcBDyn‡kE,DVcAl¨¢;Bkv8P$r,KL+EzBBBJ{(Ah@9#7'ՉBBu`-kfB LˆDBA^B AֲBpA$@:·b׳8!BDflTn='BG9?^YߠˆBrLZ}GSkaBۉ>BbB9oAwA>BwaA8\@5B(lA=pBfBGB6p6@K$^A ;KB+0¢ B^¼BTBq)BOBE0kupB]BLB~BnGC06BXBCBiUB$BR BzBBW6)H+BB BY0B@B AM  *7JBKA3V&yS EgBB+4A <%[@k;pŒ<UOtA=®ew$2II-ֱD<ª|œsĸv¹Q[T6ȁy>hA2BVxAU5_hEšK ‹3H²YBE:FBեBP8;C vM4:Z°Aw*3TgH B BB CBh{/*lBczBBNABAjBuBg>>@A0ABkwB7BJ?d0 ߶‰O޹6ª7}QA_r`&%NTw@siBn˜XSNPSWې89j~=כ±Ϟš!<@&D6€V4 Q€**BiǍ¯BfE*Y%BT2B4nA4BBg. 4¥;f1SW,0¡nFBX>%A BAl.6•pº*$lnAE WP.A¨¥ͪ/f 2D!0A A)ª !:`’ t+A0³WAL@8BrgA'Aӊxf nrw°4#@+rB2BBQ2Ak;A#c!}Y.p-ft8 mW|« Z:Z ¶sy=D2IQ£K]7nb)ŒB8t,^vSG‚L¿DDi^A.a=«QZ®)v‹Z&ƒrv@R›3DE^aAxQAtBC߫/Kʾ:’ܩvAAQADoB:TBBBrQ{.?@B+CahAܞPŸh 1aÈEhN  rUFp-NO K:¶iy"º /!D|¦13QA¶lA®ӘIyccr«-¥ B:/A~Ggc*®hAXBqS$^BBAlAP-<†0՘§~[gNHs*bB*@Bخ$w»S7 5Bԙd3wVDBQAmB‘bAGx@@֎¢: Fuzp3)* zš-B )W[B D)BTQAA >BpoBrB4A-¹ ¸A]Mzl.`Tn|6X¶B;zB+E*ZB[UA[@7?ABlAЊ>nvBTbӉYX$,I4:'«F§B5™A¨|‡>bz?€:M kk&L LAˆ ~ (¢F&¶+YBC:q[ªNB>8_v

    ?v{ajqv"SUcl^vP?>$s?l?8r?>ц>>C> ]:=%?T<)h >>4k&r?ti?:=⿡>? J8?W~ 8W??c^}ư!o #I>B>Et>Nr@>?v?={j2?yj8>Ɓ849ÿ{~-9?Vx?u¬w>>s?D&=Ln=o?.>L=JRP=v( ?#gPl9Oa~¿:&?P>\?_>]=8 uIz>?>j%$7>6H)̾Y?B@?K ?0=?J"k,>asc:?#d?:濱>?ƿ6u?jhۿs>H?$9?8ڿ28+&={>[?\?Z>Gm_:lQƛ{^!V@|>Y4?)d by?5p>vU;>ḿ{ePq܄>?Gn;>:u_P>jj?>Bʽ)Ŀ*>j5ƽgq>ۛv>o"H?; [>? LeǿXýJA*b> 0x2]7=tb>;cY>u[ ݘE>>$?^>Ͼ2h>7b,? c<?4>̙>il?@6?.>D7:Kjxi뿩f$)g??& ()>̀_aZ!>q'2G>3>P?7F?D?'d `o=I=.п2vC8.=d"};$u-p?3?>f?5B> =mD?p0> q*?A LL oQN=/@?`-r翚ݥv??">u|=|H?7C?\ĿbK ?H[@ӀE?[lb'HTޫ #)6;:?@?r3=B?@_l?=p?×4${^O4"?n>?]H?>\&0>d5?_?i>7?_?\LTZ>2z/"׎y`>1`;xq{>&8?Xi?#?z??71?0?H ?">9hпR>XN &@j!UP BN>|>6X$\| ʾh½m?-)0c8>g<[2. l?J>>>>ǿZ O?+ǡD?? $_>?.?r?tK>?s>ʒ~/>X|>?+?eU`>G*έ XdVܿ!w>^X>=Ux)(|ڽB?I\> ?@f>=$?QzEǾT?>T>FF?IM<??i4>|<⿓E? 6t?mg'|r&?ܿG?Ď[䔿B!x#|?3nZJq??6μ?6js־Ek?Dd/4¿1Tܿ, x?Dj8B=>/I>?>Td=*L>*׆>sW1>tἿg?{>< .>{H?QL)>y?p&;Tv>q?x|>ɽ?ۼm8iʰhh=e?fwe.(?1?+.?n3Q>/?LKk>m*%=?yjǿS&i9;^?A\Ǿ>1NGk>D >ο*X?_<?bM);f>b7>ZS>?U? =?8绝KŸ?z >2P?/D>1 >4=%>?<ؠm?#ί">8k)>A?'h>PZQQ࿄7:>7?6v近L?4V?㳮|`=R>?>#96k-xJ Fח+r?k1`>0D?Cs<]4sNn)dr\<5ǿLj\?,>\;$> ~$>23?:B")>w @ً>n?'=.?}?L[ȾYD?N>SX?Go?rU?nd?0ȋ>X?2@>Ы?#|>?IԿ6D?Nþ=(̾}\|=d H>D?F?")C=¾Ge]._7?W>ſeT?@b=U`zj? =Ͽ} ٚ?a=H\O5?g׿3>>>9塚?-~DN^?*F >F-v>r?%hD6om+>sZY?.>?=rK<^ȿy?׭#? o?eH 6>Rݿ?簿4?ۿJ? TTt\KG(y?b þsr?_ +l3[3>ξHzͿ9k29?Nv̽B8>?y>-[ѩd?J?5Lr2> ?'t???0ȿL<)4Sc?h"m>W>`tlkR?Nj?G>*!>4ۻ҈`mO>Vj=vƆXf**F=;=n˫ ?*;>->|?c`l̾.>-=6Ᾰힾ+d? A 9?'q?*/?|?q Oǿ;>r, *,> H>.?-"K:8Jk۠>!>JB<????:#>Y?Y:>}r罊YA|ʕh7L=`P_:< 0=1| 'dAWս.-Dֿy>& T?KC?.`t[H?&Ok4??3`?4` >ܛ~\1X?V?[ҿeB>?w?r.?gp?A?4Zx><>ཽA횿?o'*?> ?eP_>k9?=U<+>J_>쉿;g6dbJ??{8d>$>wg?z?3r,4LG>Xe\ɮ7>|޽p=z;>>9ݻ>>5?4?,m:9H^in.?jȵ>Zd:(,???0?&)??> X>xj՜߿_-^qJ(mJ<: O;j>Zd>ߔ?u;$&϶ʿ?GN==o@=;\?KFt>w@Wj?!ܽ0qm?_<* N>d@hԿ??d?$m^R?=>?=nrf?ߎ8?N?^N>J'5=;@Ix12=Wð?"?Rp`?Hgx?.»?+< ?*N)(Ѿ[>Ӿ#J>gRWX>8?HֿT4?%?N?2">4q#K?}R[n?z ?En`kϬ>7?T?S)>m1h>A??LT?ed?mr\5/h>Ƚ->?72c>v@>;>Xؿc,l>}?m"? ?8쿅g?j>]?@??0 =R6izL}jA?YZ?x>Hp?=4z?a픾nF?^j?'1L?V>\=Z?)M?ľJt=wC~>WȤ>P?U>t-Խdؾn"]>eXO?[ƾdk,UO?Ts> !cy?YIk⵾ <=>D?H9?Мd:t?/@"?yK>:Ǿ0T k;Ȃ? D캚>t=eXC>?U>?͚?" I4̶d|ؠ?ZMD?fR̽ =Y[&q򿅃n>9;>>C>ʿR?˜? f+?/t޿r=B >U=?rQVo3@? TH?6H??U@ 0k{?/jPb?>GV>>8?U?Q)%>B\?' #?<~ؾ\)b־$ >?*nsRd?4{`:?Μ>4?-?C?q@C<46ï >U,=',f?GW>{}%? >(= -8L?RI1~lMAk?<ὗJ?^[2H?$Ǐ=>vt=>,+X?a g0;P?P?-PZ>>z#$a/&>>x*?C>0]?~Z2/< >́>k> 4IV> >k_?3?OF}T`eB?Os? >?= ?d'!c? U?7W1?~1ւ?>a#P=U(=J.?ɺ>k=c= v=e&Z>v0?>w>?c5@l>;M?WÎ=Q ?4>9t>Ňp?Q> F?fc>9ֿ*?-п9{>7JJ?bVJ?$?5o>p M>r3?->%Hr>3S> FBU$n@O:ݵ>誽7>8A8>=a?$>˦¿9i ӏ|?A?nZz3 ? ɾ¿$Y>! l4>Br>a ?z:XK<;v>(Py\L?D9>s>P?Hy?p'1>0?7`=fS?!1? ,=ɀ?m?I0>/>p `>z>N^'c?s?J>fSM=0>ؒ,L?դa?a ",kSA.5[?`dy? />2>"?c%Gj>?A>I(??Ҿ%]ܿ@v^oA:R?1d=
?*xPտ~U?gC?=q%$>y=7r?X?Y>4?OF?G>T>I瓿i<&?7 ?7tF>?{?mfɗ>^返 ? 'r6 c?4O[?Z?>?o,?3ѡ?:>׽]ٿkR>?wW,XB2x?&H|.](? >q$? ?>N?~?? \>%?OZ> ?`s>'A?:)Fɿ`=">>O@ 3@?(P>H?q4X?4?޾-(?<>w>o{?ŭ?u31l*|?<V?,V 7'OCZ>>Q>W_gP>?W H?립GD=?$E>ܿV\>`4?IS?Y?w@dL?$>m(0W~/ZƧٱ߱I>A$8|>mu=h Tv>4}?u?~c?[<89>O=ea@ƿu? mQu w=+?0?s? *>:?E3?v=ŸV>!9"e>(("D?"gb$> +&>U`&?T?_ ?U>*1$߾Sn'?x6>Zl?!c?AfF>h=ac>1| ^>_=',x&>?e? ?BWBvP?&?/>T;>R3*7)Ɛ?TK8=a>xC=@Tj&an.?X=N+=}`H=@Ox>L -?!Op=L???S=>9&> ?ο?wG?Ɉ'>/ľ- >ĕ?)ޅV?$N?[?7=&`?"?IRz8"??qHh?M?&N< ?2+Đ=??Eݱ?䜻LD>i>ɿ ȿK?2?Y. ?L|¿0]CX 25?P]?Y>??RP?Jh>>O=Gqij>4̾>y?^?J\3>7h +?_0 u>*=5?9?UZ !][?.LX*> >r?U>p?M"?n?d^k ؿE1s=$q?> D_Z'? >wZ=оabׇhp=r$8 ְsd%f=?"?=?t/]>>t8?X.=Ġ*?>\t$⿈)Z>E?I৾%?x=Xmβ=uF>uſz?8t :>TZ?t?#/;"D>q?|d>fFѿ6="p` >? # guZ>u4=:^?v>1^ɿ]h>?q >l(8^?23>:9+> 2ɹ?>_'?ɕ??tɰ>>t>8u|ӿ,%?Y??,~\>?"Z?XS-W*>>>ش(=.eܿ5 Ts???}0?sN? F>> Qb>N*?,?tόZ">%%0ʲ>&Pkg>~>Us?Dٿ> = ?&?t3_̾2?,L6ś?aҌ>7> D>?g>`W]>^>%#;0>>?w~?x?i!Y i{m?Ws>l??H?r>$m  ؿ]R>h>U>VC ܶ>|,nQ?$|97{?>>?//;BA%>BwoBx-LB "B:CHBAnB?~kh)B]B~.A]B(eC[BfB+NBBfyC(BwTBD*CyBmABsBX/B1­B2/PBcJ#B]BJe«d:“A:PTOBpY`J~CPA_ z#) YBC4~ LBB\‡BR~tkKBm(?q@ǚXBAbNl%ZQqi'+A@"6B4V¼2„BߗB6C(BB/B̊B@A3jNA\JmB@\DBTpA>SBԪB]@?A.±B ^5*AGHyA &ASj TCBAy\&+"N@od?BuA輜BBAT@NBl:`Bn0BqGA‡A܆AjA B:WZL‹tBCv +¨B AWBZA8ТA@(A ¡zC?+4uӀT¼!ŠWB(<6³"H!]>H`NB&B0in[{-BB*@ Be;Bhj›~B8{q@B@Blj4BWVB V@7B4`Ba¦>Ug507Agh O-½'EiABR-`# BA&8A;B+A<&v9„*BFAf̝$@A|B*#qAsL(BBjERAY]A\?p@dBMB(AAcV1µ¨S~<%BJ+LQC n"› ~vO!x _ABP `ApH@B=YwBB;£OCk.B3~BydA|ml ;P.3p\Uq)@.IdjBbҝBU›CPPŠ1¦V¥AoA -Ay@ƠAō@A$:ANXBDw{B2,.‘7e6AA(A>z@gt9dG0 PMc@&O fv=n!A ϼF@ œePG?);BX >vC&B5fL%„*bB-.*r²5:^€FBjS!D.oMDcNT1<žJA*¼Zz ,D{ 9S7sN/ӘBq@XSBjAzpBdu.Au]AِBJOsB4u5BDBqz}AQP&B BqBY^BvAEB>¥ }BDB6©,º6uxRI' @x‘˵8 4^ HDh@ vpF¥I%Ơ ަBhUš\IAtqBSA8rA`F¢;“&N@ci(x® |@_\¨7wθ+.x¥Z"VÈA3I? Ÿ4AVJB[l`/A~ea¿wC{)K¨“G·k\)š%B!Q8A}%)R?#ho‚݌}‡wŒ^AA &´Y}vל£9¶ku%­½F@X„ P\`1" i)f&WAgS/TEМ@H a @DB>UŠy1{p@M Q!(:qAA)BuQ@⎀By+@BB;;Ai²)Ž º 䟺 /B/BY;Lb[6? W-pl‹__H?ԧBB@ڦ‹0i.Cr2$wy-Ao ªa@NZ–§›nsb#M)T¢|aLu  "B@Ytv]p>)©&4B`GB`H>w&so·iA†O?˝0@)5>=?UC?y >)?U7>>|ľ̿<#@?Q$s?aii?܃?-8l??<]Ȁ> H>>2cv1?)?>Z<𽯕ю?'i>r[?{> h?N O?yӿ@?6U?=؀=6T?l"H"y` &"?J\h>k ??@K??.'v>jt>;ľ{-?p⾰ᇿ5R?LWYSLl?M >A &??E{;>> l?Z ?vP=3UH=Ŀ=rO>>BN ?IwO >x=? ?b#RoJ]">?(s>>D08?"T>|O ?P0演p¡ο .g$>X?D=.>?h W>_=Q>:$?d%Ͼ7>]?Ͼ9ԾGh?#>`lf=8ƒ?w9 >=K@?>sZ?/Xw><_>€?;>}PuM1o'^8>\W>Q=zV[X?O : ]AZ_,i"YAP&`0?}@-ؾ<v?sp?񾕺B>+>!+]迵ƒn(z?,> ʇ>>xg|^#>ݻwͣ?ͽ`[>TLEN?]>#Zu=S;Gt?4\? ?B?+?̎n?ʾcg,?M!?c"T? 5y*>?xn?W??l?2">-(h?}0+ֿ C[s>ݛ? >9W>A?H>j&~?(?oؽ:>"5nj{>Ga?5?->L5z >K4678>? }?:?,T|LJ>0'g=iT >YOHi=:?W+=e?UŽ41">>>T"J?ITL>5=Ι>$>#^,>^`vھ Zj4S\}>$gD->}>׀?/f?D>5&t??? /<h?MG?n?- ÿTImտ|?vvU>r ɾfR%@㿣?2:>ɚ +<}>hu>ō%> 6==.?>&x>Fwľ S??Ns? 6?8TC>[+>0"˴u?F]m?">?n0=#`?K?S>?:l5?< >>%h>hwx>|?, ?o=??"J<=jVx=rXYT '@?tB#?sG>a7m>>es->[p?I?H ھ?Ub?us?&1?>|cx* @??j?8֫?"!V? J?0w=y?l ?l=]?R?@> uV?;>64 ? \=Կ޽>?,)˽1訿h ?M2>,ۿV> >Tھd*>E>=]>͌W (l= `?V9/^?2>;|?5ר6˽v?5?xJ%=0 }>BF>w6 .w{Z?ā>:pپt~;q>?{=Ԁ?1? )ɰ?*??iֱ>i?h?s?J >>???9XT=w>Þ|[9H>~bq?N@*!?E~X> X? r%P d?~3=8>?-T>&>uؿg#?O?4>D¾R?FƂBF>>%?9?OG Ҡ?O>+>/J&0 >`(??a>r>F;{>R?};fؿ H'rJ?ݿltV=yп$?e?Za >D > >AD>G???T?9]?'Έ?}y;?Rtx%>0Ѯ:4߿ۿC?3?>L7}R-9׿>Ծ쿜? _>^?@vh0r=Xs\ٿH>^v?#X=9ܿin>^??== Ô >H?bu[\Uü't,>,]d;??j?˳ ?҂yzft??>twƿ>l?W'2>&Ze@=[? b}~=&H`M?>j?Y@` oh=P>\L>y=\?9bTߏ>h/>N?+ ;)S~}ڿ#Q'̄>ؾ˻>3>ɇ&?@J?&?Ϻ>BU>, ?b* N 3>O|>d@>۳>n>J>/9 >,F?˸7DޮD?A0?V7X>ο6d>itr"?Ȭu ?T=_\='6_ڿuma>^v\>Z,>dпDPڵu5͎>/}>E?g?N=2u@?*L>0?] ? ?忿'>%=d\>.?GYj?y;+=@S?V$>=mN?7? /y\?^.[0?a8>؇L)ξw+r>y=4h?|!2>2>^>d>ݶ",??>`0] |&Yʈ??1d?,N>{:`=B@(/l=濮>9̾^l>Ҩb?gR93fc+b>h20?5u>ʾ1%HP ?!{:?@?Hj> S?O?kn=` ???? :?3H>|?P?&>ok$쿌ֽ+>!¿LN>iW?%lu98fe?cJ?&kE&>-SHhDL? R>&|ȿb68G0X>(>e>, l?!s5=ώXh>>,>=Gfؾ?bۙL&>$B>>>,܂d?jٹB Q4? R>?ε\? ?7>1mP48P5c6?O*ÿ>t?; X> >-o?=Y?r?a>rR?L(??1.]?u;>at(>X{(< @>9>?F>@??bKz>FȻ\f>4>E?ȿ@E>/Z{O/?.laizÿZ? *q(%u e > =D2Ŀ%U^?F;п:ο???%/?7W>"H>JǙ>ڿHi<~~ uV j>y$" ?۾JN=j`n>4?q>F3?2A?YeK?s!?ʒ>r>?(ȿ93>hU`,>NU?\?Hm˾E>I>Bn?'sd?꾲P.r2=?|>>*?qϿt?cA9?@?4g?}J4?>|쾾}'p[?&jiO=N$? Z=;?Cb>1…>D? >c>°^8w41 >at?Ub>Ǩ>u;nƾOn>ۿэȮR??l>J0hY>ܽ6:?bP*Ì%[v2?!@ڠӛ?S񿡓k^?j_?>y1>Г>b?q#* WؾZ=X>= PdCR? ?'_MuwXЬa?/{.Xqs@ L>])>娂>>D߾,y.>;=/?b=%]t=Ѻ=K0?T9v>8+(2I1*k-a=+Ⱦ#M4pT=0>6N?J%>^ >hy=O F?@(W>6@t;:?8?WkRxZOc=@ھ-z?h?EXd>{?@?Nlǿ ?%e?7<@'h/~ھ%^??L? Ǿ7y? G? D?>_@[U?$>|?B>7j#>s~$>]l+H>ب?Ǹe>@87>n?f?eR3>ǼH3â>Ff=]epl^ѾD>JΝ+d? v:վ琿[*dz?:|>yپSḓ=zx?c>J??4?!>/>>.g2@? J?: mG>U߾o==㎬,4>wod?? ?`X> ?Y?GC>Xf>ܿy?1?R.a?3=H(x!H!׿ΕֿKa?J ?Yd#? r>9(>@>+Ͼe>S>\?h6=P>ă(~E~¾! z>=>A濅æ>??d?Y>>]\=zAPU(?A>x?vU?2P=?>/=+ ?q?0d\Ͽ0F+e1/n(?:k>+g~ۢU?t&#m>?' c%H=&􀾸;y?tĿŻ\L> ?{@>М>;'>&VCg=|?u{T?s?hP(?̽fx>_vHX>[پ@M?ar>O>?>>),kHa0$B>7?8ƫrp =nHY?qvֽ?E E>xv 5X>1?>v?>A>d_0qSW2ٿJ."fI?U>4? B=o?!b-?gW{; ?![K}+mPҠ??r$ܹfN?VUٶE?dH=Ug% z>=H.ʾ5&3>T`>`J$>ͺ>>>wξJD>վR/Z>!>\I>2U?dR_>YݾP;HHjt> ?WT?Zf=2K~H>~=#?w> :$\>N3Կz? ڿo& 'L?oRZe':2ſS? ɤ>0u/=1վX,jhrC-_@?9>>?>_> xzX>PpM>b0 ?,>qDyg2?㿾f8>;eb@X>R;>{U>޾?>>z?g2]Ěؿs0?ZyBp?g4>kf? Q>9W^%"?>>?9 >q'?}=?=>O|!gzZ>ag0?2>B̽) +Ӿ)>RDu ?.?-%2=>޿?2>п[$?<&ldǿɚ-9H ?4:?|?}X=.愿f [Ƚ >޾G[>JJ>>؛HH>6=^=h??v$?^X?%?,jr??-m5̿lb?k=<&.G2?x=),>?j_>J¾/=|?22>ޚ>?2?{Jç=\?OOGiUPV9/n tDƠѿfn쾓 =NG?ɿF0?Z?>́>wܾ>>p>Tpz42ѿ^> R E>>zoT$|˿|տ!B$>z>=\ rͮ ,ϿtRs=J<<5|>Qa=Ѯ>롱6==X?n3==>lJ> >nܾ-.>a ܅>"b>y?:H=(>Z=p>J쿆}X \>x$g\y ?!?lR? ȿ6k>h1 R>_">ݟ?T?%<>4*?t^B>byNrC F>즿8U>M>޽V>?->T[.?HN?\N~B>?*"y; 夿V=Y>\ؿ".>8? >o,?C/[)AEA&C*ck:"=>vLQ2Z?*?,>8Y=r*2SUv?-ν,=\8¾9ʿ;QV'C>1 >g@<=X=ز>_f%z!q=r`?sN>/A?cM=wM>Gܿ]=Y=X=L>6;?(? 7ӿ"q02?J;? ?m:=h!Mn>>Áp+B(?>C? #u>եD>X?|澅!p075۪@>z>԰S@|?Al> VE70PJ@=ܺ?nc>hy>0zؿKl4?A?缠@kv?$2&b d-7>$+'y0E?@=>?%yPk?YV?+?6T?%B?Y>WF>oc9=?scwMy>V(?G п=@ࢿt)M> = f?gvO>h"?&6 ?&[?-e AF, U¦W}—:8B:;HJ@w Ad) JDx,†zjeH@"Q3XZUn%kAd1AܔBU±F%u1ž%i#FU B?rD€̥d£eIAzxCFa‘p|xByc@)A^%AKƒ uiAb^ªݮŽ2A9}@jBA>$z>,ŖAD{7;hB%[^COAG6C4(ByAUT o[߃IAsG-c@Hv@~0 zAAA1|A6,C^™]Pf @Y4sLJ†ڳ A(@;fVd §I {?Ax\qf6&d¥LM u;  .J ۆN¶Q2o%%P~“9׮ 5c-(®&¬zW_=Ζ|‹'#0¸`$'SY\5µI\t-d '¢,V"k[dk+Qݶ9&9p©h¢s yn@¢ @AH:?)ZQ"S“HlNy[BFGZlU͐¡ܝ2}ˊ¦]ֲ &OZqDzj*:w7_C'f.B2ª6mzQWZ6zeÒVN9PSÏikfÆEB&df aH'y$Ô=bF *>1C.ZA[u!j_ Ãb;\$6J2§&z\ܻM4a_DE&UB B\βB.`+A!<°(B0¯~ZlʽA'<ZL[L4BRB¿BBA#o=  $Ixiѽ@B\B›ºN]>ƒ>£aD0_@­/…¬:{CµN±_2B4 ¼T ¸sA;2䊮sŠهI¯—6lB:I0&AŸ>/+V‡ÌBuWC%JBFW<*˜(ŠOA)wjA};B BBsCk)BXAܪB˫E2B5@›B,B YA>§u(g9@BP2BGB.B oAHB%B|A_na^ҔBRC B|Bt”m»…^X죒;A:A}JBޔBUFBusD–zG:4@:I&Z¼RfG΢@#h:*eA bSBcv>L ŒB <m‹:ljCh•[M“"ARǬBϖB/{d7¨st@QuS;XzalA{C:X%?Iv$ۺ$P⤧Ai^j@w. p>@¢wchOK‡gAŒ/A?ŸnVx8BVB؂@,hQbA"pbe6.©2=g¥VŽu,\}1žMmBdANBZAh¹£BGtAډqBxipHWB?^e@.B[Bh03 |h!-,5<5$6yS¾:ƒɪZ«Y)"1\*}/¥'<:1 o8&‚DEfŸ%)+©1%,µC:$o/h/­D@nٝRZ@{Y>3u_,w*>~sW7¯‚@՗c-ƒP .´1H0“+v@1=tA=ؘ+܈':gvvo\ H2BRn“cc[M-~K'Œ` d0]&`œIM@kv‹'TA&z?§@.ŖA9)[ۓʖ3@UkpAeGtƒMpmAIsx*LS4F%$™@Țz¢ zn!7RSK_± J1¿UA&΄ky KSb*Ʈc\ sJ*µ¡A•e $4޳uԋϳ•|ZAEp¸!)c‘jT E#BW eŸ h/a¬bZJ9d ڷ$r:!½?A{A”#bg-vJ@>BzBB l²z@ U8BC{An!j#z7EcB B@\«5Y{AbCMKZX˜AwŠ~BzpFk1B݋ĜÕ'¹4|^ǂh«0UBY“jlQSBcPA@LƆAzB] A2,'mp+ `1Œ_@´ػB=xB;AqIˆ@ "P"$”;BB/Ÿ: d@=\`o?.$ulBm—A64gAݴBJBA+MA)AGWLA{8A)+¾D‰O¦‡AD̯«HQ-G_joPFUũXºcCǙVtv aBlܐ»4,*%%B9pf¢W¦AAE2VS?eARȔA<l@9b`@dˤBrBrjBTB7AHJ=pA0B"P~B$JNI&BLAQUA(`ᤪ@P:>TU2cPBSa :mBZ(BV_AB¹e8Yak¡KF@^BFB4ЫB~BC%A\B B|A@6ZBmDBAo•M"nJ?IX? ݶ?(?\ݘ>F ? Rt?~H?ƾ:zd6ѻ?H ڞP=}xl?.1?ﳿ[f?ח>н[H? > ;>E!,r'??􋠿ڽA>r=Xۿ%޿gk>giE0-w]?i9z:?bK>='_ ,\ >1mw?)ο?.G/?/ϗ=l=/(?>(cRޛQ?&)>@p3>P&(?=1C ?=ξǿD=>_>?zqk?j,4=$3k?)*=\Խ!;pB(=1 >PN?9>"^B#?y$=D>R@>SH>ܿe?B2?E%>7F?"0> %>N˿EI.>(?U?&?C8>mf?T?0~$=]?JJ3w/>x?>z>\ Hc> ^>>jƾA–B=cyD=ݢO/e?$*>ᡐZz=?@ ?,Sl?Tz?6^??ٿ >Ru'q?zsg.>!L?ߴ?+ˏa'޿?J?h>4<=Nm]wοRZؿQyxd%|>>XQ>??!!?-H?uV?KZ= 0J?,d'?s?QDe?=w>p=3 @ 9p?LD> o𻿅g;̿ ak>e6@?'?=DPj??~Ȫ1? >b꽑K>% ԾHr?*&>4^\?# 2?2pپ?7˾>c@?6?KGl> 4>?[?⾑<9,=TZG2>܏W(ƒ1=$> D>ǿA]m !?>Ҿ)*>#Ns?oeL>W>=~?Xt>G?啾>ƻn?+HYLML>=+P?]=Qx辸sH8?F<b'?T*ڿ>|d>L!ȿv2>! &'PV? '??&ǿrf>_;C>8𾄶̿:۰|. ?tv>>郘='#J bSZ>A켾2=>do?h(?ò{?e?_t> =W(w? Z >3}N>PJ0D g>bTt?Q? DY>9?yfmy@>ʞ͵־ɾTO9XbĽnπi>v>>?{+>7?i5>fY!?7ϵKo} wr(<0>#?$8?J7 hz>>vy?KvĿ@H>w?0޿$EFψ:]]pv3d!?ǽ>%nδf\?\[=(A>W7>s(Ⱦ>V Jty3"8?8?f^.F=>ۧ=h?e5?b>+gLWT?DV>c>#֜??8v>Z˾.k=nf79?=ꍤ? e4?@<{|>o>@>rD>=c4ľ;n?? FԨn>')uaDO*R>xt>v濰2޿!D@<>n~??B>1>?Hk(=0? ʿ"6?&.t5?\Wg<`?($8>^@y7cL(\>S="mKu?6\=?aV>x=?M= ?^@?3׾5l?Ka?01=dto=->J!޸b?Xr8f s?:pYC:>y>+k!> E#O? ?!吿0^?/oG7"P}>[JE>Y=Ÿv}U* ?HPᾫ=h-@>-2B[?a>нZE> >ѽD6>ۏw[&>7Fp>),>G*+C2>?>>jdn`>k?A>XZ{?ɤPL>uiMj;4GѾ򻮿n%? dhU>N ?*to>N@ݢ?XF& <ʿ ?e-~?.w8?>q> ?l 'JYf3?)#>8Ⱦ?x?<>y"?, ? ё3澈o>> _b}>;?@%\?b ?>K?a'{K>G?">?%OS>>?`:y& R#9}Fk:~^>20>MJ霿 C>f?Q^ot=Й`G?G:?>r>;>M콾= ?:aɄ>%پt{?.E>XB?id>Ξs=H>qy=Z\>\pj?h&V>$?"S>w_?IraU/o6?eT> > ?y?FȽ ?U pn>0J 7!X>B?g\?Ex6غN>KfE>3u3> d2?=P?? =/;??u5( >[ $-C@ ?*|AKG2̾QҿX;?7$>f;Ի???PC?Bh6>>HY?>6Z?ceNhٴ?3(>w? ??>_>L'r=>t?οh>?ıt>GSr (N?]zEB<-> ݍ>.he>>?!?6C #4)X?O T> 9?R?!>AXy?_`Xl cv? O#??/hT<Z??Gz>>M?$lsڿ&N.`-`?֨?`l/>v_?y>Tx?V>|>mx?mܑ=˖ʒs= zN̿Wմ>^ SZ`0?r>4C*D*Nռ;>L(K>2l?M?`?LR;i?qw?>FXK?{x?-> n?D̿CTuBS=Pm|&0=Sdfi<2?|vD>z%?9޿N0|N?$?gP=>N޽b?:I> >C6>>?i`?L@>D?">#98?=#$/_\?=G(Ŗ?3YR>>-?P?R$?=c*?~?%>J?,$bI@&>RoR-?q)˿Uz>i8HoG>?Y>|?ҿ)T:l9J=t h?>??OZ*޿#!la g@ Z?z? 2?[?ݿ6?b@>x%>z?PFw>LO8I@>?M%8ͽ̠?w>4e>P ??_@>ƴ=85>1Ⱦ=(Y>"?N0?>~rfyԾ:?># ?$w>AL?,f*5>H0l>ɷh>;4@-ƿ8B>&?YP>p9?-?ľʿ&d=?%{(? < U@wX(Xl>7>H>T` = >#ؿI?>%?.6?0L.698^#>q_*^n+>Zؠ$>J?1?5FQC;Yx>`n9xh:&KO>A?KSP?[fW#+?!ٍ?(U*˜V`>6I=t?_ſp.Y?':?f>*-~?2^?F?\쾯d==h̿Lz~>Ey >JU]! >i",qI??3B>2?(n=c?0H> x??=n2>i̾6ŒLN=0HAHS>1(?m*>U.PkQ q? X j:(? q?=>e.>n=X>J>C#>п*E~?Eg7>$ۿLԿELE?!Sǂ?e ?=?{傾x.n ?2&}?ROK3&=z;>bQ?ƐKS?$k>A־L*o?⦿daԾe>RL>a?@ S?8r½|~kd܅>hnß=^ ?*>nk>UD"Z6??o?hJ0SiLb E#^?I>Vi8a^0?'>  |$`<2=P ?h(ҽU@?ۿ迮~/?=}?,?l>ND"*<ʀ'¾o;\t?2yr?$?'\>e > +l>v ?@iؾ>h>a;>=?jdQĿIII3zb]< ?66?+$9>,DBDpq>Jz/?=:? ?_T>&ľ'?G[? ?#=>q䋿(i3x쾉50=OP7пxG?l ?8P”TM?-υn= ??[>ЏoP.t?\_9WFS$QY|$pO>hy?=S_d8 `.X?\}n3W8>RH?Gx9fr׿u>V&=>Vҿ[{(J[4>B)|L 3~?r}?Y?ؿ}m7ľ9o>Z1Ҿ:!"@>WA0^a>Lz<'4p3>?iGRF T>f`;>EJɏw+3@=P>2= |SpYпe ?->i?M֧G>U>%Euo??LF?Y?X ?%̾qt?>yC떿O5g>Gcް@%6J>+Y 4 5׿ ە=f?dyy}ʿX߿L?e$FZ(?9,u&?W> a>Z8z> ٘>nLLeScxt)U ?]d?'ڿ>wfs[`>hI>L?9猿ȿ.C>v}d/i%K[X?#1?ޫ> ʾ1i?-? Pp?~A4O~=g?P, >0Uܾ?2h>7?>>S%W?J\>B? '?R?-u>Q>3xD ˂?7>:>v)дʾ>> Fg> ŕUq?>t2ϩE?dh?>&>`h> ?>z>#d=t߽*K>q?dv=Q>2>Hѽ3TľPV>3E:k<O=1;?Tr@>~_2;G⏾M?%?*de'|L?dkY[qi]+<4_@>h?8><'=c?#8#>o`nkz?0ο6?O?eؿ2`3=xȿ 3?}H>;?m? \j>=NME#z=q눿=>?>?RV=ؿznTV ?>'WYZv&~uE>ܔ>&?/j )[ys;?ǿ~?6&?CnAOQXB =p1>>nG4=: h?8/=>:?C9UUþ7=1^-ܕ{n̾09L>~rŵhdy:H??:&`eSV0\?xAl&ښֿ<{5>D>jI?5z=fB'L=8tMS+J@.>EMY?o4?">Jᚯ ?#==4P>F¿j23 \bx>0>ܿ7,>Ϸ=&־#Y?l?a?9Ӿv56 R>Unkv޾>jK9?5b>{3O;ݘ4e? пa\XhVl=V= ?,3.rۀ//?7C¿^>ȿ+e>?>p̿漢S?7>x?h,zِs>HE@<@?=?H[>{`tm$?xݿa?Vt6^0?@=Bg -M"?<24?J >OqF#?F?n? U d< |?:?m?vT?'-?"??0?A?Rx*aZ؜VSֿ& V4>!W?i;$ ly?>_.P>_?yj>|<= ?:=? QA+@&A G ;e@ -A @AKQABnCYilBAT4w’#zBBZ,C6C E3Aj@!i~P@>ABA 4BB2P B٣B{CB_mCBE0BB1BRC!{fCBpBFb7C]CC+i-CPC`pB.BNC?29Bp&AABqA‘*7NGVA@"lCي@1ABM@A-~BSz `#ӟOx+A@hcA+BEВBKBFA>AiBA_lB=A65=wB tV!ϱn\sCB܋B6~BHRrB-BBnBɦC>7ChBBjTBHQ@I´t0E 1_B@BCԇABR.A BBA9@FBdBfNBpa.@;B5GB]MIB҂ݞAB VB=^)Bj`B~B3`b””w­B:A³dFBiB7iBoB@9)BzKBTC{z‚A45NQ B|A[Y^a“ho/ACBB\BP B(B8`BfVA[DB_BTA.N¶Bl@_:Aޠ‹l@IH!mBdxB2AAz޾A}NC+BgCIHBBUC"C'BќC:B(A fB]0,P B5BJB>mnBnqBeB%BBƎ B"fBYMA,œq @NŸG*BLC&B*`BϋBbB/1B{(pZnB8u'~B\Td Qo0\NB–Qna046a"#tAVBECj„0A|hPwSfBZ³1BC$*@tCB9hB5ԪBR}BЪBXUB B`BB/HB@HP7:㙗ӐH­¢?AB< HN7BA@PCA@BhBa‹BwB3]hB%C!QlB'~FBBsBJfWKRB٨BD@MAD%7uAĀ€$.C†4};B*W‡Ag_hC@q BkAB?E»ӢdB.sdRB2q@^vB A BCBBAAPC4ABqܑA8mBABBA ATBV&\ImB@eC `*BBZBBY+/Z«tDr@A%  [™gu”7e\OFuNBݎB>cBX%B_9'n]$؅dAMc9PhAMTBA{Zqc|Bp5,B3¯"B|gBլ³A^GAFA4[wišn AΦ€pTCB)AuCՠB BBTaBPxBAB-A=a=OHA@BoBK]BB*`M_A; yB*NB9 BdCC'<*CBCBvCDB{+BEnO,zNB:+Clk#@ B܅BB +B0B4B!KDBLjBL/CnB „]B#cBCmmBͪ3BSmcBAB>@يB@PC1GdB[BbB(B ,BB`B.oFTu"Ƙ=j}“v?=%e‹C–۞Jt/V"Bw @½B1BBQdBg@BB^BVA6BBœBBA'¸ B4AGkhdĄŸaO$E~B¿il$0<…%IB`j41AgBVBܨBQ A{B3A~DKBğB+,@P(ApMlSA)wtA€:ͤeih'86#A‡J0 ZBbpHBx ;iBB:ZBo;BR0sATB>BBB21pB'TA᳈@BɅHBCBYuCOBo@_@D7h"B~B1-B@B{3BB8qpʇA4DzA3;B@_ċZ B B`@hBOAB.fBF=7)dA)r+B[6>kbqٿB8־>M =n\#6Ɣr>a=?^$=_ƿ?+.|?S=o\>&">>|_`Z澱y_j66B/?!@>ĿOH>?xY>8D3LG?kh?%DWAS*?ܓ>v$><>&ap>H^пl?>Uȿ8 .Qh4?*V?sx>?Dv>^'>nU>E>Ė|JG־@tt<,Fƀ?A !1X?u3cؾ<᤽>$\? ̾$> =m=@?/`?y?@.]>aԿWz?Qء=~рm"=;I>>$>va ?w?B$>ɨ? ?@^>+?p?nf$7 T#x>$ιW=Z?g>+!(? ۤ>(Dz>p >@>T?x־8J?,ِC?n;52&>-ž"־;;Z? x>h>BCh=.Z?iB??b?A>C>Љ >,Fr?f>P?=g4(+V+;ݿm>+"T>>3`?3b?a?@Z>7ھå>:?N=?r?fV>|e?O(='C0>q>?6:>s t?>_CWd?nC=N>WQ?ÿ ҭ|վT>l>'(#+Կ3a>H>>=)t05?J˿I?Srp?M>xʠ?ak;̀??>`>Sl 7Pt!9XD2?4Hi??L>>Df=[?c?iIYY?eiQ&ȾZ࿠??̾ϻ>,8\J%UCcD޿# ? J n?0' ̘<8=epɚ^>SE- -`=-XE?n>8߿iؔ??C=ш޿ar\i?>S:̚ ?=dT?.8N-،ɾJzW(oR?]H>>=i> Fֿn^?@UT<>8K?N?>2hr/0>2?W>?;Kv> (0>:dQa ?0>e ?,r>?d@><#7 gJfBH??V5?N{ `=Y<ھ?4n?AηB>xxgps?9>[(>P?m%w>¼?_9W?7?7PX=VH?4=>ߠ^!YVȿc>3=3?X?C#3?>~?˿(? t?4>>:>=戀?lZ?ž^ʜH>&4xD ͟|>.q=$~>M9?6ӥ??f>m>h>>T>Q>􆒿up >v>2ܿJg;*S wX_>+>fJ>=8>֓M?>ʅ?B=~>?[t,?%#>7czP?.?4'?17? {nÍƿe4X5J`>ad"p>^ ?J?6ƾw?e̼>?c?)8W>Hi^R?ՠq>,R:>z ¿BPؾ6>{Xu>R _9q $꾜]=W>>@>(j+|?yj<6W >ѿ#[,?ĪIxi?90s~JL ~7*>H>ӗ?">&ξ߹ҽo{, 0¾/Q.4?࣊?v'ɡd>(O?i8?H>駦z?Y;>z?>a?8nbi4d=|?[ ?AP7Bv>Ҿ9LCF?I.=?I>DpP?>k2b?^&LfhT?`E &ξЦ??L/h?6?=˶>-=z>N&> X?L#,8?4>ѿ?8>}>p?o>־'Ú>:(P*?Y>ܕb [3>$|ok >8>Q>,? 6?hڲᶠ>߀>̡-XT= p >=>v?D'"9+?N9?zL? 9?l^,No>?׿ W?>`?,?/'G?.S?kP>X:ڿ:&{? C¿Aſ>?nK?sƛ?>R>*c辖>v>Qޠ*HwYٜ>Arײ,ļ>*b)m.F?X> ޲`>?ET>qE?:8!yξ7>vh>1?RF>2Wh?1-@?'?՗u?DaJ=H,m?$?Ya>%1F?˿?;=rPlj=>c?Ui>8mh6׽!Ph`>n+C?[+>֓9=>@A?6>8#>Ŕ?)>.Ǿbͅ?2>Y͵?ejҜ?u@c|^&!UDr`׼=& >AEd_̿ 'a?%?W>8>,=o?ȾG?Pw?ؾB>28?R=M0?!F?leOHھY=f׿SJa/?A5?T?H>??XI|>P⾭X? u??^>>?;->?F"?Bz>?Uޗ+aٴt>쾕~V_nP>8⾖^>~>?q|}>"M⭎*V&_S:?V>=,>\?H8>Ʌ>vvP3>F >?66*Mɿ28=<:?G]?ܤ?&a>q>v [b`?łDl?^b=AsƿT2=@X>/?ԥ=x\>5Ww>_?8a?>ҷ=8?e >r>>幽>>/T?T0>콻T&@ɪ=L,$?l߾??&>o* >fX> (?;?5Bb>!XwJn5$d ?$? =v >}?!2?,6>xz=>>9Ih?vY5>?8;(?@3?/`>` aCܸZt?5l9*]>;>ak?>g>t~bۿ}P?4|p=x8(5^?*(=.ѐY\>F0>,\? >GVF=!P?Ic>ľobbBr=|F/$> C)>G>YW?G[9uF?W<?<&>}c=l>v r ϽV=>R?*%^E_rYK>puJ_I Q̦?Z("muOfNP?־|?>:=ΥB=hxT>51>ྜ?tWq à6d 0u??T@>f53?<Z$ >Ӣ>.?dҾ>ԾW?;bоBʋ/0=Wؿ;8>@>Ӿ/V_KT>>.6\X?9(?<3}(>r>?'T1?mrY>w,[)>5) ? ?,n>^?^Uݾlپ\ɿl??(I>?1~I1?` *>ؾy dM᾿<>a? Sӵu3>[?f>|f?/0?B@>F2?@ !>Y?u?A%ػC?R>=`uKľ=f`v?uԮxF?z*:>n$!=84?%o-0ͮ2>b#=^ 'V>[/?)x?>β?>p??c{?`V9P?`x??/DӾQ?۾yp?#u?ܽ?}S+ c4>@?k$ ?t >nn?XĿyE=?+>I<>,?8o"L <4>8a>>Al?A=`>G$to=h?{&G6RDվ$xֿa~ ot5p7GX>T>u7}H,?1>{Cd=߀Eh>켧?2H>8, =4,>QB=hCh>N,V>=k>Z>>?>n眾B) 6Կn]CTǭ?ajDD^=B6?29>4wش=?3yȽ}`[ؿb>Z(=?N y e>/xZEoxh>?]] "~:`^ts#2>f¾hl?G>GATtH>ڽE>Dd? >PÿJ⎞?q>?!ʧ=އ>4v%?Af(=rt>[V3L9>0D<}P?F5?N> ?c*?xNĿ'{t-[#>ி8se^c1?3?A?J^=t ?^A&UbO>3 >o pH?(>xNW#]`蛿"ue>ǰT ?>-J?9,=&հоoL?u \Z࿊ter:e=51>|6>O>?m>T?I<][>b>l>(>t_?(ٜe>>i@*`T:>+>=ׂ [#^>?E=\-9?:=4o2v<ϯ>{j?x=7ʒ<5>q%?t*<@Ց@%ξp>D=(Խ>A;JAE} ??&>T~lO?5H?d D=l?>]>k G=q?>"(>%2?>h?7S?Ut>wBC&{Vzh оbhT? * Qz>MmʾNG%?{Gi^=UF9([>W7|?Ol>>vM8?7]/>_t=8V kԿK>-(=ĂD>> ¿5\%>j?X̾d>:G?7V?A~8'0# }lR>2?f>2Cpd>xS?:X?>6W?[ ĽT?87?g?߿CUm=;?26=l=>ʿR=ξK?@i,>{?@ ???X?Mi >tS"k92EH)? >=t|>4>O߾`?ƽݰ>[i>?r?> >Q?e?9,v ? }pľ==/ C>YC>t>3_?fL>$ƾfޠ>3>jXJ'?d¾( ?f?E???2F.Rxp`{?UyE?4ގ<ʵ?5>?LRq!ߝ>&پ)-?>K? ҾiY ѿ%->B\G d? "M? >?3l:?"]u+Jag,"l?Ƽ;?q>ge|H@a͉>_>>_?[(A=SH1>f l}|>M𻿞_>Vb>+Z=3?k낿>ؾ쓻qԍW=E>YH?&?6>?ufο,;L?>p@=pGп ־W?8>G^?(=?}([׾ }>,Hh,|^C?9v?0[<1>!=f?>?r?k쿆뿝@>׿]C>*־<>뺼I?)? DFv?)c<0Q> Ks=S>>b$?X7N1yu:=[AQ@OP>l=5]@?,?c>"g YWA?? ?? e.Ϥ{v\>a%ORZ(4?;>X><<пLp?q?m>b1/!$d>걸?i.ݾ俥C?>N>"@Q迓N(?l?w ?-?𽗧>ײ)̈́? _8= /4tQ\UxjnɾNv=6=">WI<D?^#Y\^=m>н{?D>8?ڗՀ>KN>%ٿaDɧz=Ӽ`@5.eJ&պPp? 9?^>h?@?>Qq?[(? ?/C*`<X\$B?:ľ_?M?̨D?Ģ?J;F﫣IeAҾ>^?Ѻ=HJ>8?d?т?Y3>1C8>gw ߾Ӫ>3M>lU}+?L?v ך?< Ϥ?>jXp?Kܾ?"N7v? ?ږ+oh&v!>>m&%g?*0?$?B$t>)߾==% =򸼿} gq>I'?-:o=:{>hu?>5? =Т~4?a"B1B'BM(cAߖAŠ| ‹- jAqO.Z?@4ۻªgAFCLljbMTª8$/͸V\ R«&–h'8<¤[ȥA~M^*fB;X:©/$ e)o3ϼ;RA«>@)"˜vBnwA B.«hWA-!;h@0BuӭkZ!?»K wœWiSZp40BBSD‚C@BK|Ar>B;nfBxAxJBa@⵼BvQEz'AvJj-&K>ttWB@£:aB ´x—a~@zVBxB&:XX (¶ BnAxBmƶCO*BeA5BW7A-Ȝ@AxB@LpABpdBBNBdjiB2_ACCBBc@ZXAё?u|ڻ…Q”z *o;¤j`L$—X,]p&y>BSd^BpB֦Bw0GBB%zR@ºBBB B@3(A~|ړz Be,e‘ 1qBoc|"A@Av@ähBA- B#*¼(b ԿAx(mW?B9£5B[& ˜ٱA ABBqAC f$:`|Ÿ1R !N¦lPB"ļj(GEŠ B’v "¡Ƌ’F#bA oBys[-,J¿H@V0$AAB+Y¡PSµ$R@wBN @^Ai A.BC>Bm0A~¦Boi–}"Yd~ V˜&k}A,ByH|B-sB:B+BB!A@B%BĒB^JBGbC2Ȋ"=’I[A&@BMpBR^BH\A0cB B%VCGg+? c…"@2B_^DBB€̊Mѡ±LEBABP¾²iH&:g_j¾0b?tA(Bwrx¯K127h0pNK&P£Al:9bAȺBԑ@fA1BHh "(AոdBVBw=`BPږAoB A!{BM&AB~KC-@c](A7_T.¢B@p"BZ=A&BBB4BECBS?BXBUwB[B@qB&AuA+C:-_Bg‡7k]o ›A° AA4@S BX0 _B24+~#B0@^B,BӿBKCBAhC&B=B _8B¡݋ko(A@¨g@HB’?LCdA\BnBGh P ­ AC zlY2`C%^BBBT`AjBLBiBudC@ ‡H.CSnJC%pC U>B BnB/BABB'hBu<@3Bf4WC.BiBEfBƶFBBB+&oB@IЍBy1lGNBB_B;BbBb H¤4@1Afl…ipHC C5AAOGBʩAKAlBqA٠B FBBx>BhBGBXBcϡCB,a2 BAC5ϣBB[B׿AMJBa*@nhv~Šm“^4BfDBVA:2BU½@@ݥº .yGr? Ÿ q, B)Y R%A]0B*B>*³ ?= YU NBǫB A 1NVB0C.][eV!VS.pk3A6\|Bz@ѣ@CBC<|YBA&C6v¿fC$Alf8R0A޺WU{B9B|NB7 B*A,J B4> ƒGœ@hbBX.B+PB?AoAe:BذJBudLA޳?>GzغBՔE>@B,“aVwI/${\B jT9B<ΐB%BzAR&B >,^Bz5BB/LA1jA!s Bǵ>B9bBFjAWB,BICZؚBBs%ByBB͵Bƥ$C^nBОcAx/B8RQ‰-BH7¦:Bh.m8L‡Ff*d@%B1|BB|JB)B-}@<[DBQB/B APABh.?oCPB7]BC=& pBwB} C-8C*~BC-[BjBB)A$C, A_L¥¾% fUBaA>"š8Ll­YWSbJޫr*A,kc[AgAͨn]š)AgtB˜@B0B2/CC EB7\B'wBM8B`AVt0‘zBB>@aVo)™&²+BG"A±B|BbBjBqg@edB:B#ҽA&(A@$`TA A—AmAΊ/BAEBHBBPA˜BwBMBmB*B'ΠB-BCW@AI eyŽݔ¿d(BBQB9mBe + BhƆjjB>dhANI6FB{= 8=^\cR=B(jhB6@$pjT\E"|QB]A\uAA!$ y½"a`WW=BΝB֒A~q?@AΟq!?.`BpI8@(AA3!}HTA1¹vsBHyR±@6u՞·(S±Kg3PPd= :ABK4bB4lV8"1`~FP7L®$B+9]Až r48GY A(͢rAzBAmBBuG·IoBHALAm Czp[[B|7"QQ2@pB5!,qRAGAAA4GtBjEiчAV? ¶h”"euо?tխ>#> >ۓ>3@ʿZ? pt'aT? ;>n?ҕ-(d|>>DPg ^#?:ɕ>g>=8‡.?c?O ? ۆ>0 ;>gk??Z?OH>6+^(?8-QB?Wb,? \?u&;?T?dvIIN< *Y<.il=ĢO-Ҿc<^N? 0?Nh'?qy?NDӿ]y?+e>@P?f߿#>˾u>>=H>Ƚ$n[8?s;?"N=c&Dj\:>)ા4Žڿ ݿT'uC?>?,J?4#z>-L>>0t>wJ??$hm>>?vv>!k?%$F?=Y>r2LP>?0f¿.>>8>?w=B?Z?"Su>N8=q?+D? -Vf*>'D?>s̾S>.b”?_"?ؾB>r?>IU0H>n>#?"?%>H`J'b>3>(c;<7Q??A>;<&">>,nK?0^e}?Ij[ȿ3G: &HտD39 ??4b*?#?p-8?x0?m02?)q\p8B>SF޾U? ?Bؾʔfrop~>aG?! ~?4|??gd>q *B$>jT?#4V>SN>ѾL?'>H2?{K73>vifYn?;# >(p>T=?>Sxb?FB>A~?$?Pn`>}y ?@Y>?(!?KB?Yҭ>^>Aj&ߘ@?>bl#X >.{i?F>43?%m}>ʌ ?>:=}? @>g6?\?yj??CJ۬ߧq>\0?r3>f³>> >g?-O>~=P?R>Gtҿ>y`."꾠,<:b 貿X\C¿Dq?7,?lƿ?5>t|來ۨ>lO?%zA}?TՆ>7??e-? Q]>D>6ʾ>"?O?? >:V=Y,/>ݷz?{.?t?Y>m?Mx?>9f= ?cٞ=S>O\> >>?Ro>S?]$?`F9n?(>C]n?",?p?aH>>|z?sZG<#>{=?+4V>e?q!?(FʿHy>?!p>.־_ˣf?}:U=Һ/>6b'뾳 ?Ϧ?ؽӻ?_$Q+?5?2xp=d# ξ=r?A?:-' =>^iZ=?Bà `?l> ?[M@-D?#j= fl?n]? ?uk=א>=?n?c@2?RF|F?!@ ? >odɬ?uF>?V?$r?D>.lP=qȾ?<6"a2˿#?%II,cA?Ml89^&@^?7 uYE? E&h%?6E?'}?4=._п=EI H?j~>a,?#8 ?w5?4S>ֳ>>>z?VЬ{ÿ@ƒ>/(?]N0>(Q?K]>:?; G?L)j# J.qb;3 ?7^K,X?8"J>˿$Dz?6mJl>P=~/@?vxR>m?0?sC>o'*pol ??;Q@>?z???rjwE?`,?P>C k#K>U? !W?&ӷ&=c9>W^(?vOν߶?}=??b?w{?Q*s= >M=q>="?/l|$>a?6Ҵ?>?^Td$@?h?ĥ>P >vk?p?bV3セjc?BpR1?Bb|1?EM>?G۱?X?n*(>Z>B?Sd>G> 8+* XG,?g>pd">>ƾ4>E>V?ԾN?>M>+,l>F?Q@ݻQn9>q?)쾫)w=ؿ C=qV>c?<ֽ<>|?3Xrh=; ,r>?` ?fZ`W?DN?~?S?F(>ZpQ!a?k>?v~<_@?M>cx ¾Kd;kX>?N0[??R<8??r_X=히n?R;p2Á?!6^ >3R˿v>䠴??O?ȣ ?IN?E?A#>A?xt>> ?9>'`αƿh=@>R?\?>ɡ?4V≿ š]h>l>,?ھHy@0?w1Cݞ>6{A>!?Ÿ<>Z>??彽B`p_>|f?>($>>??Z`n?>#6"v?I >⹿LU#j>?, ?5R?~ڇ0>ezc0ȿon?⿉&|?≿ >?vH`>v\?+D:D@M־j??Z=[Q>c=QNPW ?qȽH{[)?>i?!5֮]?4P>| &??R>`B, pw1?*8? *5.>>vA>&j>?M|пE>ۿ8(><UD>_Ʊ?XU*7>UU?{[=P=*Z].?*>3?2>3!?1?Je?ݞ5 =;S!>Z⿊̀>TԾ>4KG ̄??(5ĽXH*@ r*~D>@?r:6 5%Dn>r ?)-?Ϳ?k-Y>>ɭ9?雅?lO`l>>8XоN+??S"F0>tta5> kY&R~?}!?{?^>t?9?j*[> ?6-?}B-jBl̾!?;1>dT>·>?.>Z>>ZBk?ӾRs=ྦྷ_>> R涾!>?܂?oq>jKI`?ֿ2dU?]?y>M>>2=t>u=&3W>{J*l?%Ͼ* ?YVq "?_?>$>re>W&߸lX).=w??8>-{^?>qȿo?@^v8}^q'2B?F??y}p:.XN\$Ǿ^>>r8?R%|οH*׏<?O~>"9i?FA>?S<*b辡/^?B nm+-?6=UU8 q88zN>,ξt?[ Q?2f`>'>XVG?<|@ ^7Kxa'?r>&(qսI5=R`3*<:r͟>{>?0!dg0>q? -f>] .?!8? >?"?sNݾ}<Ħx0?c/>+?Ie?D>B4Rdt׽a70ѿ';¾"$оW^?_>>??м d bI4Kv? ԯ?B}3s=`S;:ֽ.p>۔>pIXQ0]ڿ L">ݾ ttE? ؽִ=pP>ķ伖޷QtH|ؿD8?>lȿj]}>? kDXm.>*džp?K8:꾻:?>? {C@yھҿ)tˇCc>~L???\ b/} ſ1Cʽ˜Z >˨>F;>j->Z>)j:+P);πjYP/x6N?0H>k`g> ?>.n\J7XD?.*QmQӊ?>0>8fžYR?*^0mu->OyBп4=Uݿe>ff>ϩ𖽇P kAX[QmʿX,>!t???XF>>?=t>p2XՐ>[>&=,ͿX?PnP?**?>\]bősY>eʹRi9׎lLov[Ed^J/p?>nfެ?k6?ְp_&?&> EV?rc6@+>6?-cX˾=#= =>CD_팿\?5(r> (?\2?O. >Q>;> ws(W?) ?nր> g>8rDH==t}EĿz6ӴVm?&w'uE?C(MPpy*>暾\H пY? = ^?>lbF?UdؿKXo V?8n=OBH&vQt>򘿑,]述?k8Z)Z>F?9t7?%?m>Ւc?Rj?1RVн>ok?0&]>/!Ӻӿv&>2(; [>:v4?{j?->x>&\?Z?P֔ۥ>V>O> K?ds>>ݙf2? vKX[b>̿L?Z^پVl?(*?T};? )I>Ht>!U4O?uP? 꿇 2?, K&?d#ǻzɀ>~l? >kz ?];]Mj?-Oo>>H:q??NS>94jS'uȿD4"BI?]#>r?=/y={`4~X>y#?WD> ?>=\?p\2?~?Ҿ ?> տXԿGrn>@8?R6?+xe4?Sj@ej>-M?&Nh>]>↚>=> H%׿,BEZ9XڂTŸh#f(?G.=Q?}'?Ypr\dYz?S-¾=7x?7A>=M>-4>>,*w D`?E'>Z?yQ>C>n)~?^QO'((}̾-j?6/FI ?Jn>3~?GV>Y>G,W>Ϥ;'[0?wc=L>3Ot?j#?>4I`;-;6)= "d?}+~>-ؿsO>%>?VJ>bsg>$?5쿼U[=i=?%Dg8?3J>W?&>5,*=F?O\>!5Sd=-1ǾB"!U>)r>ui=?=pJI0޾>v>y*0B S=f?MU?)>atjz#$x?>'G?ge-u>`uR)uӿn?/j?M?"pR2>!s>澟?0ǽ`@?LO>']0?@>.1r>IkP>+>̈́>UoûҿǿʾcNK> >?`*L=z?' PP7>cO?`L=xk콤hup&0^[̿F?5>\?F~Qot{>M>l3IѦ,?FϾq >h]U>l->oc?np=+>E ʽ^lĔJ]@ѿVo>޿I5?5>*(}`/>>'?x 8d?cxPZ6i>IH\FLT>i) XJx} ?lf1? N?p^&uw? /> ?<vlʡ-W?|N|??DO 9 "I >>ڵ?v#\Կ9>yKj-[B+1ھ5h -rVk=&&>"?u:@>z>? nV >e?-=>o!?I끿R(ˁԿ̿@>.^>y>?|nn?Z->ʿmJ9G?|TgͿ3`="˿gך;>d"?-:b>!>E?)c=kd@m?;5&m?5 ?Hx?خEӤ!%̿&`?s}? >L=)>gN>o>_k'о\F?h?J@>FIa=qFr)d?Nʣ.0+N,ҿ=0?L*>>M?,=?K:? К0b}>`=]n5 T/=Sw\ `p 42>@|?<:vfV@?C@?]H?e >\j>>1?fK??{ vq9?Y!.>2;rC{AYC/ BB}B+C#TBFC YMC?|BpBƊbB<7Anwx™PSC+CC3AžBc+NEB0Aھ BM BIB/`C BAi\Bߡ3Bn`rFB-ABI ɍ+E>AAwB*ByBB{4UkBBfBYBBHBArA5AҟA´u†AlVAdCB@ B`BMB,4BvB&,B@[2CALBB20*A=Br K2AL1hB;!AH?A~ B NBBEB4 AiZ€tB<hBh@U(BkBd|@'BjA4B"&½Bf޼AtIBN?0A‡"&?Q@B5BB̦>Ԓ@G6Axn.¶P´m3mj¥|dC(ˆBwB+>kBuvA f9"A?:A K"H>\iA B-Lńsu7|A$c¢k±UFry"B,('X;A`B#p^&fB|AADlo/BcBAbFBh±trA]BWB,CC%B BjZQW(A@*@}vA9#BP]:BϿ^BxBⵢAB-2A}Ao -¢HA ‘L  GBIBqQsY;"„B_"ĶN?"’$AlBCž<Œ#XBy BACB-@?BBBBB+BpBF{Mz‘(A:HB:A$"BA*@uŒ4HB,N[kM$0Oz0B v½,N¿ k3¦BEka qB*B,BRAAsldBQX&oB;:5|lA%"U *B3".>&j@@NxD0фA/l@5? 0~‡b!B+G7A# {BMpBDB[AOB̄@#P2P-B*BQAQ‹ŒbI@9B+ B"-sBkx@oBdBȱBnzl3wB-MB @|BkA˾fgB®BXYD;ACf*B|B|XBf;Ga_ABTaB;ȄB=ABMBg=BpBB$0C9GB׏BB3BXł^AHϐ@:a@@_pBSn–cBI`‹ ADdgB*51BBlBi£Ͻ@ĨnGBJ3B=HtA@O7A=bBBT {-C4BuBd/bAޠB09C)BC 1^FB5B]h«"@>qB_XMpB.ZBa0BlAB:h۴oBgB.B0CQi HB!-4:-|H=ABE,G&݋4ʨAWHˆB5CwBmkuC ^ApQSWBcZAA^C(B4 ҋB䱬ŠXAA,`A@@4B…B'.B'BFB~@ߴBHB OBq%((ABBF2B4AJ@mhC' Ba\A3+ASBB8A)A9QBZBdz—BB—NB{R,ŒbBid\AB$BH^d:Aq B/N vBnG»ŠViVH aǑ":H­ paBx/Ap*+y[IG2B)TPSRAԄ@@fhlB@ )eB-.BB3B8C§oN v© T8'<i"LZAZ~AgZ(A}gzC>*Pq=spADBmO\Ѵ‹UC&r0BOOB;[@^ª)ĉq¤VBMrA:BX"ArL:B^C 0ABIAAEZBSWH06m_/AM\&B!dBFBsڸA N+)YP(@PAWA%0@~*((1mtF$B (Bf):b2B#z?&!*B{A(BKAHAB5>0 4N#JC|B@pC?X%P?>`>}8>D׿?B~WV=W p?Li??7ZD\?:_>?>=ĿKhx?CHܗ!0?>$x??n>;M(x>aٿ'<2~??=}P֡X>>?$4㽦AjT@>?$@?KE[?:3`?K>-r`S,?+(/<= (>1|?5/?U<^x>C径?w>X?~>6g &>:6?r?(;?p ?[t??*c0ިVx(E?]# ?:?%>>>?$^>p.=ܺ?a?ct.> >?>z?y>Wƽ?f'1PC#a(>AϿOAo? 7Dn?7?+>?YS?V)>ٱ?>~4X>p)Լ0>HIQtn'<\۾W?g=y >Ql>L;?? >O$4f|= i9%> Aix>Rfd!?>p?ῄ2h3#%'?7[X?e&d_d>!?L7F-?G0?˾Ɔ>(徿!-KE?,)'?6|?jc?Jn?  >=Pֿ LI> >lൂ>|R>V?O\8ԧb ? @wtE?>\v6J,>~?, ۿ*tJ+ }͆>%=x0>!7yW?ߚB*-2>>݇?lY>V>V>pkvpn>h>m>?k]u?HA`0>4Eir>+>Oi?b@*g]ʗ9=s[ ?Z7>9 ]P?>֗2W E)о7Kf탿=)?h-"?`5v?) ?Y>:IgR>h݆?! >22V^"=GR>]bg(cZ?A=ҾTP?P'Z>̤? x?}o<`p>3>ٲo&> (俎>~IyAA ]??A֖? 9D@u:)c?U<`?DI?0 ;:;?p 9?kڎ?;cH*of?r7T(?ܽ=1?dMf?}S>s>f>zx==x>{?U? />>>JÑ>~-6?ngҞ&>h@ Be?m>y ;F7S I?p_錄^l=4 ? ?W?5?/??$PA>Y>ں<>6A?4XfD>Z>Vp?6Z>׻>_?i>]?֣~v'rҿgbU?&.?+ھ@I=?@>`E*T<>E`G0?) =fԿ #cU=w?Cѻ?am rX?>"0п?j??9?7<>ؾ桻>?nS6>/|"? idE>U $?㽪^>:?[j@q>%=^Ŀ`\V?T,~ӛTOh>`>D!Qsj>St > ??!F`?0?H$v<>=}p4rA|?/d!?@6I >0=?I=>p? >ˆ>o N7?:,Ǿ˿ƈʿ>3=KX(p6ڿG?,?ƴ>B>x?|P[NN>rQ?3.?urư>v1>ǛQ?7۠d]d=,X?,a?>N? ݄@_?!;׽tEQ$>L=> H>W-jӾ%z`=ꁴixP>i)?  Կȯ=[?g|=ժ>ɿj00%#>MmK>m?7?nAͰRi?=><*8pqQ "d >[>>j>?R,t>D?Ϡihzh= ==4>x?=rZ(?q?^=?=ԿX?!<[H=K-?hl>b!L{>[H?.e~e&@fN ?CW>J?o|z?G_:>@?>?w bοo*?Qž$ξ>¾>qwpf*Ÿ|݀88;ȢIt?>L>GF ??%l0U?6; յ>ӽĘ?~(YA>j> ?u|򿔮 >V+? 0>)q=_>@)վ?T+˾?"ނHZ>ZX&?=ԏ>=b9 ?!>+ʽ3H>> WvRyڿ}?l?Zj!,>\=ټ^=1-q9ʾAL =?* S 80?)?7`>?Jp>L"waiĿ7 ⽸u'`=rZ"26HMq~=R=F>#*> vR~4? >B?_ ?:n~?`4־?Bp?*Ԧ>$oWT<=4<3D0??}Ì?o>ߏ?{?| (3G>t>k@jAK>D>>2?ٟӈž殿>?_?FV>a?ÿ?c; ??&7wȾ·oB-؋x+ {㾴*!ľӊL̿{>?c57AH?b0>=RH`M?<>ġ{$=hѿ&v̌>xaعnR-Fou??2<?ypmh[>g~>0?: :F @>+?7b?cE?=#?=?yy}>A?]F>*?:;>2%KZ w?Fd ?|8>. >,S9x ?IFP=*? >"J#B,*?ר>涬c꿇g>;M=[2ܿ?(i>e_A\0¾>%W>=࿆1 H[>Kؽx|b`?x>~!8?AW龫>s >:;`.\16>z~o._c?S|>Կ>(?37?=Z;@?>?3>֧=>?_?HZ?v?b=u-={iJa8?\AL>,3-h촽 @|DI?2g̪]; 3?> d>Q\>4i?G;.fA?jOS?ʿ ?'`>^X>?eԾ F>4O<M9>S>U?*?޿[/> J?#(?Pp/@;?b?C>?%wf=kz%e0ctܾw?Dο$S޿L>Ir>7?q пn>d`JҾ 3Q>83>T`#>[#D>Ǻ>+ ejοl=С#>x==QP>>]o>ݿ7Q?\eR? 쿄:pԿDQ0ֽZ >{?44){?$l >^GF>U{<\C1?W|> rAU?P[5p?!`>(u61,$>5w>?Y= >'G? <>~Sxjw?g>KI(QI?;>J=x?D4(>5?$?_.P?c~?Au??[C=>X>i\?8??Ii8H??\`?1m?|M<>>3?.?*>|뾣6ٽu ο,?M?":>F?+>pzI?/Vjzd?.C>{&">\8"Jؿ l6j?.t?[l>jվ^$ Lِѿ{%~񝋿$=|#Uо=Z=оk?=1Ⱦ{s>5?5):7 ?A=0?B?Ap?>Ù???q2?*>r=^>h뿛'm2>98>([ >޾ ?6?(鿄=M?;?sʿU:=J~ ky?2 ؾ 4L>>Ue?7z?ՠ>i|>9>Y  ]=ցd+߿_>$>}@t>Gm>?E>,ܷy=S-F? 3>,?t}flQ ܓ򻠿,Yjg@>v>Jn>%T+࿬b/d?XH=kPM] ??O>n^$ =ľэJ?}>Վ?\!R߰g(?? ??\Ւ?<@$T?/)b?>R?Eֽpej?oI`f>c>?`i48>]YB>܏ =);żkT>?>>VH?>>J?;xu=?㵾=?ad̿=?.;S>gL^>U/>,)>\b>66=8>]BU&-Ⱦerz:?E[><,_.>>2??bP>?q<ʠ@?ʱ>Q;@`=@?e?(" O?!=H>+Xғ;m.>Ѿ+Z?|u?T?ORky>?t5>"X? ]?i2/\s>ܤ4>t"ox3?. H>ep??^x?QqN>唿 |>>s>n?&c= >5>jsY=پGCJ}[#?!>Ct&>C^?Cg=NW)lh?X v 3DJ`?9H?}? 3j>?)7>KپA#WKX ?5? ?&ֽr ?3>I>?Ǒw?eWҾyCt/?>;??a辪+*pܾA`x?4LʾL=?xg{?O?fe?"t>>O.T?; D>b.>b͘0T#A^gȿ;㽻^?<4H>Cq>ڂr?0?.3P[>~t:>`?,˗@Y*>+Q n^Vh*?]ھ?薿0A ?"(?S:J=ی侽]>|?Z2޿]?.5?|=8R>gz4?bڨ?_" ?>?2`?kw@x3Kڕ1P?VŒ>ۜ!̾ >F?oż>uU>Ԯi&Gr=^`q?;r忀ʏM?/US@!E,=2>s⿦>? g|ٕ?.?,dio>#a?Z(#nÿ.jS ?I`?>ҐC=y>@5><>ρ> >F9E?'>u?0+?_'^>Nj>a>>Zt澓1?ÑcV>-Ɠx7>4 J ?pȿG/r>>!S۾l? lN|.?>q\?>??B_? =`*B~>x5,=_@> hb>-"ؾK2? g/>"C% 2O= d@ ?U$*:?_Dc'?G??ˇM?U>>=2\ 60Z\}?sx>;_N>-ྔ|:ި=>cH7/?ᄃQ?,5?A9VH?I&?)"r?ʼ<͐>??Y.>a?mt?_r\?B$>X?9_]%ĽЖ> >:0U?/0Ͻ̿TӾkC>?.=Bv>s.=i ~?넿 ?,?w~ؾ .+1嵀F?GB-4>>̾^9Y忡*>1T>R ~>Gh>97?>,R-|$>O?ݔ|A?"?,}%r*&>F?Gz?5J?#NC>/>:˿8i<X:1Y?k^>츿`#R? 0 i#SjY>c0>/>e,?|H ["x@hl?dl>#>uv? ff?~ԽU?eD=i|ep*=&=?~}>)b=(>O3>>ߡ>{>?Zr>}<`>·< >NW=#̿ {?Jԁ{>F3T̐>8=ު>:vYU>A #>>+ |>s|"?"{>V>^??).^;?>IJ,r>=G^+.To(_>P?>՘??+>?ʌ={t`>uƿ+X?V ?GTI?u?.=}\ |$A>W> ~lh?8;>F罼>P?%c]>@C^>$!f5&?]Ad?3Z>8N?V?)ʐ6bN"p]ӑ>ށoeiq31?t 0Q?>>!#̾vsb<4? (UW>+Jk?$NS?1S>^?e%k??z=L?/;u><3j>W#BǿP?~?f?j=¶t?? Y=xìc=H*¶?GRO`:>B ZZ¨,¹Z|ʿ ©aZQ˜4B3A}3:Eg*#B3%?ŸAd4q/3$W9ꠍB|œaB/ <)UB+H M6=;pT!>xUOq.¨] N8rr8mŒB^yz^74 o@+CA%A`}‰dwB˙A)".ABY6P£A;C› ¡cA%* OfxAӜpfe’[ž 8bAB@iyh ¤Ҿ¤§BH–A5BNA@ntB G:£'Tb|·#]fAqSUBNBP A{,ª@&w¹¢c\“V,!:c'¬tM ™­P#BAsj.@, qA AxAlH¦̐D)d1AH–+u@JCƆn=b´..¨A&0B2kR·h {&sfAU Ә*I6Ax [A2Azjd)MBjP$„A aAAGCATiQA6p‡vDBv@'+xBQ%BZNB@6zA4A? BWBWBO~B~%="7™iscARA@,a]s&f0xVXfD®]:."Aʍ*bAEқ^£,AޭB0eA$BˊB&@8B,.k‡MTCzrAB"eB@Z]B-hDAh&dB ]B XsG AL k {W¸$8} « ŰR@PBU­«u_g™D@=Bg?B4vBtBYByBT@wJBGi%BkBRB ,CƑp9JBFzBrBdBk,]rB+Bʲܪ@B`A{1. ;T@BB\m|BB{1BJAVAAq+4l>uB4A3ͮB:B1j"«aµGXgZ+$WNhŠ[9`Žyc=n®I = ,]º—=B}UJŸ#x.|J՗C.5Wd¥ ()tQ‡< Af`¸09) žeAJ7fB a%tN¶M^آŠ5ݰQ#Bi~zBn5BwB>%AXAȨBlB*%*A Q“Aj@*,|7RA&‡)1!5Bؚ>!!£K#BkBVG BͮAgxA"A\b\BB AzwB?BBJjB#2AB!bT}xB;BWEB BEAfI6B.CB'_Bɑ`QCKb BŋB(Œ^BS°³K6Y$A °lp3ˆW’AAc‡&AE2PBm}Ÿ65B^\a㛓B1BYŠ D DA/A()7G ""BR8CBخA [c$GClfWp[F:AHJBH.²)G^B_†wO§A)'4?A44BԂyBgB9+,BdkBBBbB%CW6BgBӨC"lBםPBޔLBb˨ҼDG܀ɡETa­ꌛ*+@BlBBZI.@xAA@Xz.f/:pBqa) 4kk¿X—!^BaTBBlBk B@Bd}A IK GpB?؃g&dAmfAV—6aXP™QgɽZxBAAIO$A=AvJByBlBCkA`,=fBIu"jBs8\rBXeBBGAvKZBe‘rB7hBAˋB͈1A糺BBVB2B }^g$#B5*@T#Br&C83Nsz@X?5A@^¦\}0¶_A(CEA2B ZA/QV@1ڧŸNLB)qB?"£A~B@B@`~m>AIA>A2SvB)۫AMt†Ԇ7BA'A@HAM8>»IAۃBQzy?BAwFBEBU~ABMdAB}I5BbB#iW6¤;;‹RBPC ZA6BKS§€@X(*Ah͎A`B@%FA}<Q(²LA5B &- A x˜yCd>N? ؆dr?{?׊> ;2?]pKڿ#> u<>j>|?Gy(ppԽ)վc>?^ /L>2?hƾA?(E42>>2;?e?J2>!>?IN}2 N:?(f?sx H:Z>ͅ>MB- K(?,!?c2[)R4˾?- =HQ??H2?%*AI?QB?Q?v X?ݚམ6\(fCL<) ?`?0>(?v 4#ʿVҾ`p?Srp?Dt LLY??KUML&>H?>IǿpA}=UH>\?2n?D?M?MD ?;X܎R?q2`?D~=0#?]bh?e=rG//>ؤLjd@>Gp;l>\? ?ȿNvF ?k??0?jʾṮ?Yg?Iѿg?;K>i=@P>I>iisHtSo??e\B{l>{1t_>^hs-,9+3>m>:j?0?G7?T? t?_?Jc\?~R~? ?i<@+ྮ5t >_p5?)ZQ3|?i?>0>?@q??` }='ިFJ=??@aٹ+>4R2>gz?J?W n>cw zm}Ei>?:CL?p3,.zpѾ=?d?'S>e?>O'@ܿ>~k?M??Jأ?ͮe1R=Q?~h;Mf4z>t ?nK? 6?t=>*>"w %#fZ=PmH>t i6?Zʂ?\sԾf?+Ǿd>QR??T3?\(>Q(7>PrϓÿA@8y?>d? 6?>j}:? qi?.>L :|#$=_?r_+h?%? W?}?+=匿>>=m?b*?%?@ ?<>,> ?N=޿@!$̲T>>[ #y?-=ȿFW?&DMX? (?n?>΋7=?l?bw4=|??Ⱦ?> ?h&$>`?Ȃ>KHؙg?hBA<,; ``t`>3?"x??{p<ľ;m>樾 Fd?H/v;̀Z?>\/=_ m>Y>bm]?2s>ob9R??8= =|_c,=.\+40::>Ҿ\qk ?dMl?H8?P$>Z R?w?bdB;p&ԽT? t/̿*>甾%@nHmq&?4r?0bL>5٪|=?;ݰ??zU?Tp?sVX>,Mv?1L¤?V?uH>z>tDT>1bT9?׈>eV=8>HOWJ?7?ӈ?S?ZL?/?Dʾͯ?1`? lx~?/)Dv?3\d >?Nn\>p>o>r3?MZ? p=u ?!%⚺[?Ye>2'>,1D۱;`K?`y lF>dҾ 11Ⱦ>$sl?^LK=By+hVz>">DT!<5??\?vG/gV&N?=B @?4h਀>.̿n5*>k]?)>h?L߿ZoN쾅Җ>7:> yl ?>{t?+>ܶ6O?n|˾GUYx?Q$v=keN>X2@?3 >?VY/п;LJȻe>rҿ ? >62=X?)7 ?Ծ6QNz=*b37vQ>Ͷ>PW *"= ^Ǝ=р?6'*>6u[?>i=D@f( r~=b={x@?l>>5?"E>jTT9>c_B>?>q7>a]*ee?nQ?a>|v?{ԇ?_xD^ ?/"h>RBod?,>a }S1>)?{?:/?@YS,.7>#=^_?ag?:sоGl>ʮp6#z ɀ>NM> ݼ[WP6ۨ`˿r? >4W?h>->傾׍J>9x>wU ,ɻ?? T?M?m$ѿ "]?􆿹}>D?DgqnD>>\kt nVI=ЬGh=Hܿq&?z>j>;?@yT> :>uLbȀ>.= >&>.Ff?I W |ܓUa?>*Yp?C`?(?-W?v.?)#H6?!>x?<>OƽmGĿRz->"T=OӸ޿׆*=檾xS?l?>5QrH>Ք>q>@?;>q&Of?_>YNi,[1>&?Ly>\?4<???V8? liuBpn?ˮQ>W> (h>r>ِ|xe>|?l?>L\>>D=rQ>?/aN>ܿ:f?BZ =ѫ?ad?J7f3=IZ$)>|w<f>?8,?Oվ4\Y 8yf?}X=غ??uÿ#d>4b?a?}qڿ>ggq>>aUV>慁?>i{> ?gb>06˛C)@ CY>*?鿍]P<3T>V׾۾+Wz&_?8]>E YL?G"P?)9?ҕw=ǥ|>:>< ?">Ev3d ?/?fǞ?aGO=h >$A |>@$#N9?vüeH>>𤾺f8>vo S ? O1ϐ?]b>wǾ̓??i5@(kMY}=v_(>"r\<~>:ShҽQ?VF^GT??e(VJ,?Xn\4??BEH>.??O޻B"k?>]>)<`P>9>؈ؾK{?"ƿ==1K0? >:?jxy\ ڼ[Z>oIOu?׿FK?ɡ> C>UU>iֿ_<>r?;>j=?ay>u>>h>߮^cg?wզ9M;?뿆w>$?pvA>lm?z>m޽>*>0z_C?Y >SѾr=TT>/?\?l,ؿYng>=jĨ?9>WSݿ h?,?l俵,>>)> ?*?NSo?2+?.?p>|>ex=>dI,5>7`>?-c& X?zJh]=1ؼs?> TFs?`B??9=x0uFXjS^?/f&?O>p۬?iC"w滿Vhҫ(S0>:=L0>6e?@0>"|?lYS<>ͷ`?r-d?f溘G%>Z@? .T>ݗ->_{=\?*>/e<ЀXj~$=Pቬ>&Ľh?h?>">Z ?$WD=*>U _?6m,>?5g?i&?Fs}91 ?{j J,e?2w?>n N'׿_34h4?] ,?$X?/dP6>???:?yON<ӑ;~Q _>3RИ]̝?h?Ot?>Fg>辐꿈}Ї>v??H/?|=?n?45>>؅p[ś\]>鉿+bvп+༳H>Nvfx>z?NI>|FZe4?;?f">оc>aο<>cxAb=C@>-~?+*6~ʽ8?#ٺ½4<'z-ʾI?Uq~[?&4ڔ?~Z>!-? r?@?-`R?& ;?JjjmN]? =ݽ=Ռ??L?A]?~%*>h>jPRR cqX>$ڿ0S ?/sd%)l?u>)J>)>پf > ӿؒy=!ː>H>?G7}>ooU>F=,g?2+~4b>v>K XG?S`j>|~?Ӑ? X?uV;=DpCjz[ؿٌ#?@󿾾ȉ>,[Q=[ Qu*0?QB>YO>(;?A>T,=𫀾09?xy. >p?Hǵ>,TCYؿ{M(E?d?m*>&?o(7'|~\?dzw "_`o>eO߿yF?L?p9s" ?W>.5>.>%7BI>¸G87wJw辀?4U>>>^>?Pڿpk&>??tny>ǾB>?*><̿>`?&pIl?+?`)?7>!s¾>0yg?*զm\'D?s?b>ʏ(7A>޿l=zP0>οa>[V>=> Z?6X>Ph\?Xؾ>0Zxr<>6=Ȭ?b=<7ؾѠm?Q?q>6~? *jM־?*I^<=Q>H l#? ƿ:? >̽=5ͥ ?̂`Je?:O $[CU>>N|fLJ?z{cw<>ƜOg?\?F>K;?p̘?=2?pB >oy;DӀ>?'s>1L5jj HwN>ٻ{*??=f> ݾ@>Ao?\?j> >=>K B>O?A{j?¾ /,u@>>6=(P̿ 277u>5Mm?m?B??ܼ?qs"3^0?\m)'ʾS`?ǽ>%ھ~RC迃!?"8>~>!>2?f>Rg?SJ0> >^ؾ]ܼܽАܿ#E>.? `R4= >绤>N?>‰>><>᰾٠k<*M7gd>?%(-Ͽf?^lH嘿2Hy>ξ=(?2B.Ϳ=i?"={4?U'>8 J7>n?O9? h\?8eA=>Vc=zؾL?9#y>P1$>1ʾ >2?7cn3? )?喾D'>(տ6u%Z͉=.?FL0> ?? S?RNxe =6h=8?>PP cDr?l>A A/h=x>2A?aTJf>ݤ>: ?=$?X:A?=p` >F809?>]?#=?+=D* T[4>2 Q??~=>\+=egҾh>־d?nܿ l?jY?x(d#1:>l/?Ba4?nFC??6?GAȾ6vl>μ~ G>=:п:ھS^z$?U0I?*e>+z?jR=?t>Fm>ƶ?}ӄ?;\?><\?AX>>'@>ㄾtt:,vrG8> seynտH?^/l?#3[?пznW>f*?1> >r&ھaZ׸?{F>0v? ah?4>L?dFy?!;.鑾R|X>ub+>+!>?giga40?E:>$Ξ>?b>>ϑ=J@dF?D38?:5?Y|<4Vi1?n̾c$?6& '*o2n ¾?v>$$޼d6?e{?)>aO?q<=2=֝M?Y>uF?O6yp?>جj>cXc6>l?8>K\n~=>U=p.=5ذ>v>ZY@j`?:?sTt>ڑ5#=ŀT"\֫ǛD?X=d>g>>^?'٢/?=Ψ?x l>ӿ*qm>lܭľ=D>ڰ>>\??d?>QT5J^d<@t4>* =+fؿ=_?ww=J^>ؔTT`G?U?p;=Iy~S#̽@:" fQtYy$ h}GP>`(>vgqױp?im`?c ʿUM>7>Hc> nS>I ѼDྜྷFy^>@9?:Dh?>P*Kb?5RX%?>&?{>H?_ؾB9L;w>܂>?2>:;hо|C_CCiB$sTC0EC BBhB k CCBCB?B1B~ $BƵC9BbB4B͹B\C[cB[CAuA-'jBCCRB.CcBB^BfB>BCPB.CN`C>|BeBϾC0ɉBhBݛBEfBLC BdCC8Bn!cC lC#C*C NB`B\CBt(\=TBZk!~BB\BPB~ B8CWŒA޷1A)*BgB_B@FBsBg<AhZVBqC߷B@BB@BC1YCC 5B@dBBA3B75A2&BBTABC5pBmc2BC? AB@ByB{rB,>2@ZBB(APBWB6C8B9bBLBCBoB8CiMBbCW&C fBˬC+Bs/C/nC6{ BC,\RB.DBtBMC5ϡANaC,BWCvYB:hC=AtB5AhB0BABA(ArBBWk+C.gCKClC^CV0CB C**C,C7XoBԄC9CiuB&BBлtC@RBB]B .BBABv@zx&4B- j0hB>0@Z.BXBAu? 2ׯBAbBuABCbJqC bqf`B,B,luAHHIB8BZCBB̦AkB VgfA(BBBB A^=%◝Bc-BӁB`bA BdBӞ.>,̀B{ϔB@@[A~BBB8{AAABCB7)B.bA=$,¼;BGV _03!Y8/+5߉[I:†|VB3sSE~@ F«VtA9 ˸¡Ax_3(? B ~AlA`?mv@+^BUB_}A` ¹uRPbh@B߲B7BKAoʦBBŅvBdABY:^K؞AJTxRBB BBzxB_,B5B9BBCOBECҿ#`BpBB`ABCBBUCBL/BBWBnkA;BƕBC"B A KBC CC tBsCB+C!ÃBbbC&PC$5CCBB5@QC(BB@=WBqAOԎZB6WBBBtjB=€&?}%g@ B 6>1 fA A@B` :Aɂ+8AYHA%}A_A6Bu`B edB%-A<BO^"B2$4VA >@,JğB}Bڋ8B/@(!BwB%ؽیBAWBRBӵ]!)A.Bɦ BT2BWhAi@Bg?A:A:`?.`B C+c@kBug@B'VB1zB@~Br0yB8B CO,C9~CCYYC&Cc'C>CWAC,VC>C!hCƿB<B/BbB'CԑC 0AYSVioB$BBvBݱ@W @oBֶBC!B8@gBBTB#)HAɫ˩AMȺ}˜B2~SBR]Bw8C-X1~BlBBH&BˆBBe|BBI.B3BBWՓJB05BB,ABn4BR BxRBFB)B@BgFCqB`uCAdٜHZA#*BMAŠxC mCDAP/B56BBC PvB^A*BdBsB~BBNl B\AɋA9BBτBB*Cq4CBNAoFB)C9BlC6BBd1B IC'C`։TA~IBbcB@vAVlp(/B-vv`|KB/cB.A5a@C0:B2gBV2X4D$AB\B{BPBBC(BB[B#AABpADs 2h,B BC"~BB]C~0BlCkH BB}CFvCZHC._B@wC1,CǠB'BB-BBA#2B|C*vW:7B,dAjC !BeA;B:CrBBB1BFCѷyJStABovB1`jϿBGCBCB1…i qAB,_BBB]AHA>MͿI,m?TI?ٝJmR?r?E?W?O.(eE *H/sGa&H>?5X?>SR=$H>"29?}<>y῜2x>YvgA":߸?~ uX ?;Bx@>ڿ"p=]x]" ?| ) >? ׿6\?$>n>]?? >W>`>P<&> > 1> L?^rge ʿ%lam'Ψξ@lj>ٸE(>O䜿ݠ> ="Hl$?&I?~k>7R>>a&Fx:[]z)Dp??8$>6>Lxz%?YI0>uk0k?4v%ʺ? S>/??l 8? D̶&?Bx>D܅ ?}`?nK=?%]Q?>Q- n۽俑&8\-{ >![l?!= l; Nb?f?+R98l?\N䷉q>Xx'Czпok|ƾp4>ka|IԤ? L"-",]k?>a>Q>֔>☾a>𿛠5^>4(#(M lF0?0>>fDsF>>8B?'ۿ*?<]̞o>}/>Կi?}@-.?%gmrÿ_j?w;6@?)8?ެ;t=V!?])z ߹ɽJ`ZLLԌ񋾛+VJ>$?>@= Nc(>XRmR]>W>]>$꿅/=Q="`彿C<:R?O?Ƥq9̽!Z-ÿ?NG)<>wVS2Ҿ]Q-'>w?>0#>Ĥi?$佦f0?f?>D?޲@8>?>љ?Ϳ;>&%vw>M>Ь;ø>A>~Tt頾=}>_=VE(>J͈_xZ]H>bA??Pp?pܿH>&]@>ҕ=XܿB޴[%c߾]辋WD",?iM*,(m??侵Ϳ?LҾ)>=?B?!?< 4> ,9oXt!f%,uT?>ԓd>^侂ty\C?x?&@t?>)? "Tu쐾TK \0CZ>͘Ԙ=f1ƾ<ӀR>'?4KD?=>x8?I>[v>|q"=Z]>*?wz>;>J`XoHZXjF@'Ol?|2Ⱦn6\$>+yj/>Oؾ.=h:Uſ3F6?46Q>׆'<~*>Yڿ.׾W?2>=/(=P>T7=5QпVU>ѿjs?-g?!J>,x?N6aG >p74.ֿ[&󿔋K/:=>H5j!7>ӤoI> zʿ>ʽ:CBJ?&U KXBP(@>^|>>f =2?1l?ghK>@'=VxߺD> Q%#<0 ?!^?>Dx?E8W>VUI6%K ?>e #xrF=?r5 >$?i?ߴ2ZH> 4,XB?%J)c5l?z?-a3c`>`w0?G=␿HP~o$=пC=i;)L>J?_L0V>?v*6>@J:)ZG(.:RN?b`>ӓE+d ?Jܿ*}$vL?TMSgҾ<| t*>۔ҿ(Q?f.?Z;y>>y>p@Ka> >ǽ߿6{_sxMA{?s-*?>{?\0[?N0JA;?-Y>|dS4?;vԿ6d]>Mʱ/l? ?H.ʿEI̽lXw?>0X,?i?ZcpPa]3>6}=ؿm\Hf~>Q>D?vM:&Yoھ-I{դ=x|e:Y#R=F&``=ޞ>O~$\>yn>[Cy俥;JT>U(*?x m?WIr5D*rѴɫ>P>=?5?)R:d>F|>>Dο"?=\X q=ɘ>i?=~=Ҿ3f10,qo?n>h߿WJ0ZY?O蜿>k?t<;?`]·A?,@׾> ?4^>k>4<>2>r>&}m}/׵>|Dˀ>!6v>N?cH>n½H콸Ft=MEJjE>xڿQ->Rx>$u@?{>︿PVܾJ~;,cSWǿ Pd>&!;0?K>fɾ]B2Z>/J(+?~6纰?JM? U?Hf= yPW}":JX8BQ$?NV>h?(Px= \$nZоW(Eh?Z?DS=ËBgi>)?%=Z|)M$?>TB>sg?k҂>@<<뽰1>[=?>|松+F?>`!Lc>qȾέ>"? h?v刾w?-?ھJ>09Pݯȿ?"M1(?S_6Ai,=9LF Fs0=Z8>(> H?s?b?S`= ƾ.<>g>X|!uW}?/Iq?պ ԇ?=>;I"0Tz5?-:?C(>Oc+ҿLu*rۜ~z>q`? ĴL9V*Ĥ>s=?f?=x<=b[|و?ЁN:"l>B?i0Ӿ>=֩8'7w> ?|c?Հ7$X@dhwP+پY 3?;"@k4=>\)?N >fw >_1K>%l>64>n|6> >]\>C{ݶ>|6e>`l?(y˿ Ps?(=Hl\ L>nKz/(Eq>Mz-? :.ܮ>\Ah%ڃ=b/d?Z?$z#>??򿆭(>J"B>D>~l?=+(&,A>4<68>hH,l?r~?8?g{i@ Pu?3>d>#9k> >=?!L? )?W/?>gzT?7? FXT<`"k/]?{?U>⺿H&>~ ??X罐(?>?0?z6>bI$8?5+=:q V3?5m;?cGD??*R?|YŊ@?a >=f?7oyO?8h?kGN>4? G.?;>G>6?&P?GQsY?s|R?)&>@~>?[> ?@O>7>.?P{(?.>?->J?3id(?XWRf.N`>G!?b%&>o>! 0?tG2Ceþ6:_#󾀙B??gO%z >K6 z(>>&?'>w?K=?S?뎿P? iRQ>g?O?>f?=,? Iƿ c/>g ?8?BP?>yM$7?eJ>GU?*\ߓ?x?uQx?NwX>D=>3S>w7N =?I'|?r3 9V=>ܮW>\ Do@\?v?<>/R'L>--Flr4efzp?G[H>"F[>>?@ukA?8?D>8fȿ>+A+>޾:Rbzh?|?'"n6>(?Wj=N8>6>O0r?@ >3`޾E0C >?3#/?#?z"?>u 6K=Ad >z>aԾ~R/>A93f>H?@q??C?t`t?ʾ:Ji j?;V?I $N>͢Bʿ3?IH?9?; -`=(0㼓8>h"?Var= V>L=>,B?d?lIE 4<2=?ľrQ> Q?y?؆?Z?~sV>> >M`@>Z< ?1>{H?;}?:_.?B >c2>)>Ƞ>7>m00?ze>4?彰>=k0&D(3k?fz?$Zžkd>ӬS?%m$@Yi<]?1y>{9g?־+>$?p>D9/H4fs>n&ЬĿn?{?PF>K8C>;_@PD=8 ;N~?wPa=O?7?!qW?e=nvrP{?Gs޿nwz¾($N>ҲO;U" 9%>mR>]iUbľ=0:?&?k9?`>>.}>W`>5T?q,¿B> 5B>y er4>C҈h? !=C|?"#F>x!> Iy?$o>+6VtCq>aJȾ{?XS>?>3†>9+^=P U>ו>ʾ}?Y?|=p:u>hDrƔ?*hb?sֿ?@?Iz׾M?>4?<]>W*CJP?>Ed]>倾?]?/?A=4?>4ˀ>] >w >>(þ?R?e18gM"?.Rȿ<킿&%?/Jp?n?*0G.=)?+? /?I>W;J|??) "??P|Io*>s\^>2(t= ?`}>'8%pN=?׾J?=lF)ܠ>Ĩ?{0vOɘe4>S8K>?x>j8R>=k?FX>2?I?% Y?7'?Qѿ⿨?:ur> ϲ= ?t>?>/P?8-?A>?l?V?E6>q,i>vb4sUW&>\>>NHщ>v> oGv=X> X?6 7!lA>)*8Xf4hs=-6Կx=.*@ 5?0iht>A6d]0>w> B|L?弽$?.c0=;t(>?!>>7?,?1>X>D,L?!;Ys(>*>p 2?Rpm>K=l@tt?D { ?I=U>^ʵ?wW|?'i?q>?=t/?;8<^x d>D!X 7>/E<T>>LP>??T??5?c).D>[d?%: ?4!?zh˿E9\GM?XL?=u> : E> GpDDx?NQN&}?x=6B@S?Eo3 t@J-> =@S?X?d>8?i?rx=et$>8^>X>>+>zg>d> =$T?;u>#?Z?Ax>Ϳ+?+z; >`n?+=S>_ >=p?y6翕+?I?4U¾UV^?|?0>??q?>S6,>w$2a_b _}n?mI:?sҪ9??? ?="?tn>Wql?>cF?i,Pī>T >/?h^(?v>+?=!y>8P~?AQ=Jp?b0.?j[I ?10jbd>eDR I+?Iq:>zh?K?\U>=)k?B²?9?\>E>oO?<߿N6=7 p"?> $=T <9%?D9>y? :'ƽL>?[;lr?W>9 ?`y?WZ]QR=+p>ŒNe}@ TRˎ?] b ?Ͽv񜽽h?k`W?rEy?m?pQ>vQQ@?+X0( O,:<?ΞI'? :ƪ-1?L?>Nj[@?hо>Z> >ނ? 1>>v־<=Q> ̽)`QK?D|?]?@~?X0??c>[>ߢ/>?Fn8>?"'=n@)t0\GV ?CPp?1>]͈?>8>`?,Ӫ=~2 3]22?4>nii1I;hn>bM?jܪ?N?~=nFx??r ;)?0>=O>B+x0= >fe><<-t?-Px?8c>ο(l"ƒY.@BMrA.~A3Ÿp9ԞBEyB{t֝TBǠ@\BN \=9;]@{dr> ~¬"fž1u^L >mk :vŽABuı>|€bvc+AAqDȡ@z]4T u,+BMvc?%zjRCZP8<ȣ±1|B%sB'k~e^„BAw)쁔X<׀@SABCbO}±³n xZ^1@Z9Ο%Х^6BwA¡vpAl>B|28BƼAx^Py3Ag*5A”fAGkbB"—B&_x@}m*vq=“B~;VC%*Eؓ !B¡Wq6Aig"{t¯BQt¿dœg ܬ{e­hۚŠ@>¾[A;AJB| —̃,8:R|Af@PBZeB;B=£;QB0pLªFjAˆU7uȘŸ™4B6B=ˀAe:B1"B?A).BzBBz&ABEjB*M C%7BQBvatKBtLAB1BRW‹ͩB(^AAn;4B_.@:B8BN'ABd@m‚B m#zAvtzJBSXB-«]BsB6Bdt?\LR@%VvBl6AZA{@Ah« YB>,AwB:s`˲BPZBw}Ad188B™ۿ&QL¯0P®5,B*SbBeA0οx¡A¿#41@k{JӔA%BTSjB:j>TruArӨB''A,ATZh~nBaBg VMpBaA}B2BG??@?A5M,TWDx@8AtB@xlWj?AZCi‚^cBϘB}BAɓB^BAjB80lANBçA:B\BAдQBMBSBaB@r”B®%.BB#uUBg_µ65BB~$qA˻Ae!4B qBgeF\N,#Beo1ABU/FuBH7 Au6Fr ¾+"ZA ™;NA4_O /‚®FB˃BBpC@BWPBB/FkQ)¤Lz BSB ‡PvbBpcBUBUB=EDZ0A@^&©+BfBWӇ¸ BBKAvT,B>B,?XB$A3B5A߅5ȕ2pB(Ga¦ršAΩJ $`X"AU‘زBpA#B,Brshi^B!Bm+m$0B6AB8&KAd=B1VByvAlBt&@OP ]B5٬^}uSA>YB As%ŸBAAGA]:±/:®FB>dBeBUfBBd9CD‡, B2lC BY`¿!#A$QAgHB\\BMARIAeAC߼BAFBBBKB CB}BB~rAJBnBR(AQBAAB:B%BHJՆB(G»C%A{BgA`¨_BBºL~4þJ„v<©H?&$@P؆@A%9@A0B1TBMA)f,AZBjM;B*B!rBc@&4B,Uº$P/^TBtyAxHIL1AB~YB$7"š0B#/Kܕ? *hA bj;mcAu@F‰,BuvBejB>BUtA[AXB9. @#xBB< A;C.jChB'C@Q.B&C BCPC=B]CTCBaU^AkBGgyB݅BbAWZI»EBKBnBi @CC%B±كL`nBlC p5?f¹}A#Cw@?꣨BB|BKpBcB.BAAnB\_B"B.BAyB>AñB#\L!Bq0!>@=%¹|1Bz*@ B(BuA9Ag{B8/YB_B_lAiqN|VBW?7 MIAvDBRoBBPhGAkq^„0 B5RZ³K@ ®B.|Smў?h6^~UAbwB BW +@L/L@d|2B?sBאAcBϐBvSB;BZ4AAjB]ASATMOu$AlAsBl~͹Bz4A@6B?B녥A3Q3STBBӕ=ϸB#CI*C-ABAPaLw<8^BhACBܓBpA8AwB#ƒ\DBE@ǂxB$?lBB/=jIO—:,Mƒk:H=}BA3YB83V2F~ AK6B ΍9M‹bfH2´7ˆ;wt* B7Au={9<IEHA㢫<A&鍒B/“D&eB\fA xB4AT@j=!A4B*BZg~a?B/B;?KKΙCC3BAdyUAKUABBcCBݍVX7CJ UBQBy2BZB`tB`B^?qBB WtdBmB,6BŁ@pByBR |ҨB2S@FB ( B;yn/???MB[XBS)$"L?BʠB 'B,>BB*B>BzC,AR?h*QAD1Tu,\x'':N>Wf+O"Jw?ҽ@A)?-`'!=>0>Tlݰ'>gMtED>)=轰tt<DNB*ڕ.>hx>ψ.?ҿǗ>>7޾P}Ǽz1:?4<>F9?V1~ݿx?6EC>t1=li>@C?6l>@ʽC7Tn^hZ#>Ŕ8>}Fi*k*H j?,Rj>?kM>Ϊ?Ɏ?|>?bʾB.&> C@BB>->X??`?οx?`=^nT>??c]>pZ;bSIV&z?. >N>'?N?O?*>3dc3>p8>m+`<3=+klҼ,,??ct}>ȿqT >[ƿ52j|@i~UB?0yg???E88q8O =lPH?NS=q\j>>g"?j_\~?PM?Z>?t;?znJ@Inxc+<ؿ*7>k?l(֊op>0>q(=bH2?f.=9=d?Qc=7p?Ul?Iz?Fv=?꿦_޾r>,Ff>#Cyf T>?>9 >/=T>Ap=m`ki[??o8Ui>G'翎=l@?0>"?[,?܋Ddx=AzVy]4D? ?FrD\0<9޻==?UW,J<>[Cܡ6>=??>8?=ޤ?RW쾞=">w,?GI&Al?eN*Կb?O{?O|xsG0>s>>ɱ~=wP?9M(` ^D>>?}BfM=?¾>@`Jfxh?YӽD0>H? Zb?>&쾧4r'ÿ\#h¿0?X W=EXV?LOB?w:Ud'?)b^}?D{>\_r>1bо6>^d?ΐ, ./` :>?@9 =??k`>?Q>2>F>H*z >}lGcK?TQ=to?TqoW>R>?wy(^I?ʿ Ep?)>HTq>Z=왿 .%p?=ڌ?%>>Uìd??!c=fZRR>1N>Zf>|?`Ti1>D ">b"悿!@E?a>>j?tb?=du3PVl>? Dҿk{ȿ?=?u>Bɾ?'*^>C9?-?'W-\ >d?P>ː?-= >nIHzi?%x?T4Ѿg8?d R8=(?sfHi;؍b ?&}>Q=3k>~>5,8>W?j]a?Y = 6-J>ͣʽJx>ք>jb/>-?,cc>mwh>?xK>i'=]>3)2C>3=Q\>N:??ȅ"Ͽo2w :>7wi??`=迅꠽X->?s88>fT>Y? qÿH,>b)"X={t ]iiF;RþY ?%n8?aB8>\s?MT ?_>H?8o7Iz=D?\'K)lc^X?G7>v??,ڿpſ`W,ƿ@=W?4>Q{btfzڿe?I>Ӝ9\nKQ>嚾alrS?8 rTY?Z!xبa>\7>M<<;'? 4Bv~Ŀ*ԭ=+=Z:چ/|@N?j??g=:x?vg>7B=0@+ȿf?11Z?U?+%}@Y?HU?]Zοz>x>Fl>_MAоZW=fn?? =;.?#r>$X>G=A`ʾ/??9>',?1̽?g\ھ?"c?_$ȏ?l#{=>MA*#b=7>]y׳`kOV!?R(+j5&>*PP7r>VQ?{2l?ob>_?O=j ?>qfȿMshݪf,=b>־;@me?> cM ?>>\d=/QHp> ?]&u?U0?V?߾_ '`` >\Vп{?~?)/,]'p?vu>?=>҆^w?2ˋ?̿%:CJv?^? )?6>3}o4hHܾY$<&b> > o7.5ȿ@@?@n)Ø?8?=Ʀ6=[XhU rF>Ծl.=xܿx'8̽b>m`|=0&>c % ?]?g# ?簾`n=4>xME>&?b>P?a/_?ᅾPD=>]>#=?nb@;Ͼq??P i}(pϴ>G}`?Mྐྵi?>EP=tc=H P,াl}>O6d?F-MB_v[,ѽВ0sо??MH?o>k=Gľk>+j>O?Hl}> Q 澘|6>s? 6>!]?,|=ب?_;@@<2==D?&v'L>/>d7i>2>>ڋ>d>QZ>[@9??'m>?;13L>S*E<6x:L=\0侬>\D~(Ҽg&͢16?-}((D0Y?Р:5Jl?a<*`?]<'?O>z#Q>cVh >??F㲾خ?#lh>Nʼ-_g3="V" U%Ծ|d(0!?U,ź>'?>φRGVJX<`?f?K?i?J f%n?v?`G80V`+T孿*Fq>?Icm?un簿GL1=}ؿ6::?8>df$ >>JV->4q@+>Н?*󾧾e>0(<?D> &cu>]uX>?7V>>JNh >@㬿Jd??>=`?>}ZJ?G6>t=?,?/?o.͢fpg7卿/xxI? ;gԫ *>.?jZF>?¿P=?,Ta>: >p~pt5Z?>E⽣KPCK X=?OR]hKDZ6x >B+=Ҭ>C6=H=.x$j?C ˽餬URt>?<>->A3W??J?b?`Tx?8>`=Ů"ho>+?C??g> ?>c??-=h>'AêD"n?b?? f3P?J?@>L 0< |Q?SL=[={ >E? K%[N B<M?jܹ??Jr?RE ?wgT<~-a?h?ȹ>T:3Q6"> Q>f[G =Ĥ/?9L= Z?20>.?8?&?x]$?,>(>w =MX*!?7,Bѽ?=?ǔ=]?4?о¶??)>h>ָ>}O=ț?&L3I?n?/<{ОS?\@>_>@]_&'}f>#oD>?C+???;>UF?nUȽ>nn=PI5h? T n">ۮ>Fkj=?'ނ=ف >>?>?΃?>K>= ۂ7D>a?p2;0>n?ݿ=TWX?J*v^>w=>\>o >ѳ )+H>wo>?%>(©?1Hf>(})S>m$;ʕ@>A?rܿ"R0? ?]Q>&->ɾ/ɼ>> ?F=P~ѽiBH=Iܼep1l>H?eQYW?5>>?G%???59&4".:{E?n{Z?ax?me^=ݾ?$^>O̿[,>DPa>ezFhĿlڿFK??/>&*?ej0?d>1ѿ`\LBπ :?i~>`?iy?r[>v?zb0[yiNt>?o0Yx8_0Qpٱ;Կk[S.J7߿,O0>~N>~p`\p5H{= o?i/; 6 {>ykPRN>/ſ???>G?d龙˾S>}8>'p6j=e>?vH5? Ͼ7r g?H$2rP??_H?Yþyt?3?Co?9>L=H?lX@;A?CQ>?uo Z9F?[(M>R? ?w?£# qӿ4?`?H㫿>v9X>GKz??>@.>0?>?4>6='ؿG1RcV~?<=XT@>>i>U>5xR?-0X.?p?Pֿ2>ľ-??ʚ쿆Z?}a=࿢'HP#e?P)'zA?ξ>J M??հ>?H?d͈ſ\6\4f8I>h<<~>Y2 =H>?*?s'? toT=L> >ng=? C>>:>w*D?J!h8>t}m8>">+;>&T+v>?94Ǭ?? )?{tF\s>?n^>Q2(??I` 9>zhy>˾?w}>L> =Nؼ4Ͼp0>JW?/࿯D<}?/<|P?|?.,6X?'?+?vǾ|=P?Qۣ?A@>ƅ _?^?;|y?iT *n=R?hw??pS?Yy?*̿:>V> il]Kt? >DwؿJ>S? >o⾀`>Y?:55ÿ%>[A&><˓$>q %iXe? >i@?tWտ@&>OB>-J>9ҿ[Eu?$?ۑ~>ԾkJԾ>=Rh?sm>f?>>s辇?eH긿">f!վq-wHG"&|Z=>+?,&>ZlJ=rS?U8>]?2*:?0>v>А><?h?Mv>4>a=8?Z#>е?6(?=?Xh ??WN\O]ۼR:>ieA>>e>:l>ܽm?4>^ô><?#TL>,?ཊk=jENd`"?ћ?> d>B [$ȾFx_YԾx?ԾN\>V??/>#h?co׽??gX>!?1"ҿ9ґR>:@=$>l>F>?'ƾ=L?kL?2Ԙ<`qJ?W">>d5??[ 6G2l:X<:3 >?>B->9?9N=>V(>>ͽ?AT>?>?e ?n*>#&'?1?2$->@*>kr)>H?窾N n*=`ڽ/ ?<,>򽖧W>?>=)"2@>?6>9=\ju=??;S>lw>oN? N>:LCQn >V>=9M3ᄐ:;>k^=l>"=6a?? ݽ?E!;>4*=E>h#?$tB?4%>1y[?|PTO>>RK>t?@>6> (>n?O#?>̿?Iɼ`><.=!bb?iGV??[HX"Dl@?M>y@>`?Qp8'(]";?q>_[Qkjn?!?`F<>Tl(?Kϖ?Ϳ7?=¿?;՟?DV?8>?ZL?4[~6=$v$H?ܽڻ??'?&,?OK?lsFriU?>3>g>|.?A^=Μ>ZU%$&=#>G>PBJʚ!Ŕª;«bš<01{@Ӌن=)$t$•i2L6 (j°;¹Z4L C֨T>Q 4dO ԙ %g¾RBqr¶Xd"E:IJˆ(٤B´G$'BAXb V;BF]W @5A~#·¨#R0!#LNo³#V®_5»¬>¹$~#*%ma^^6B2;@>TBj 4#w- Ӈ5Jd%-so Shq·I@a&V'9LŒ¬KpM@c:°1¿NGwTA²fAzFTBc1~@!BP1šq¼dB.2:ϤT@·y˯ŸQHBuH &S8ܙJ-G›ڷG7MCS tHA‰ºzA?hirµT!.8#]r5½mp@9:/8G ®S¨Z-*r%iv¦,A!:TdS— D$2E.PhWП@WW w;Tm^4 "{f«œR'iT$6KAAVoGBdJ_J.±1`?¼X@De#-4iYWS_+ ªAwΖ zA㝆£܍@a 2^'Xғ¡'ָaɐU^¾¼N/w*<L/¨pƒl`½ha;Ws6AoR4BOBru_3.'0^[:?:B%SP¶Cz?!g$ H -*gQ–J zՙ",aN|#¡,7rAJ*_—#>œu*Au5 ǃ^%BlC X¿ӧ,\ ºL(8A2AALAٙ[EbJ#VB/4mXvB0|xqcqAmv@^h<AAr]0AsifWE+@7:ǐ#”W.pC1Ak>`e@:z|Rϸ@pEW6D]A[Ж¸LA"\MI9s0©˶@ SP}JC‘@:¸8@FLnv>` AA;@$ϴ?sAH2>©xA"Bvy>ˆ­F†فBhB@AwZEB ;5BM>r˜*«XNcoŠ%\$'‡/nK€)i ȥL>;h@_B@AtB±=-A ”5AqB Ə!vN n.~~Üv,!K7R?;G§3'nµr> yS^ O4<4?AJ`Fx\᥿>Sr{*Vw‡‰prJ VŠAbD «­O+0kK<±h©A0OH#²E0#E-'`Í"v,4³ 4¬[ˆ5¼LlfLh~?o0`BFRAŠf5l„fqJI*WA`e& *߷>Qa8b[N;Q-A #A~ŽLio?H--r^I4†N°n5Y\D$XAªAB]"£KZڔB]W˅RIO°{קis!AB RA3)B}AhB( AHNi¥´K8eC†pBV‹@oB \DMBXB AB#BAlAB4BYBj|}F‘0FxB8<'B$e@ȼ\1҈$ŒB`Ž{$:wA]B!e%BgLG$B? )Bk~k8̘?l=J:>qB=wlʾ?@}f=0?W1e?ֿ̑6?/GR>Cw=οh>d=4/X a-þ+N> "~):пg}? >'>4V{>L?<>0ں=d.y>v>r?羾.>%߿dj"]?fv?pR?F>(]KE=о>ኇ?^*>?v7 4z?,K>>^wθ=[7 d?=Kz?Jި0?X?D;;6eG]=h`' >ú= s2h?߿%:o8?,~?8BǺ?:l>gcA*rT&@>h?4>` ¿cL?Z{=ڿWJ?YPIt4?h>ꉿh2= >qflKz>|>0#>-=о/ȿl>GĿZ`?=f޿)#R<$`м=fm>Qp>K>ݦ.f? >vdo>8=@辴t>ԲԾìd>`H>BhGVZ>?m~vMy>@?)wW? R?Wr(D\[UE?s??3?,ߠ=C7b߾֓zw껕r?B9}?!>k?SP>r~>`=>=5.0>noľ@!>o~>=x2G\Ⱦ mq8=u??}Eֿԧ=4>v>= ?$7?о=.=w'P=˜>Pf>UM?S½)EX%d >PV@.sRy?!>S?L>*B?D?>5?>>Cj>HD?2C?=*>x=B?ՒPѿ> >}{1gN$U^?3uX2M|=>;=o??,{n8Uþ쾽xVd ?I C:y\磾İ}ɶ>>_@T=^L?z?=[g>ݢ?$n>ǂ?>B @Ҹ?>羲s=>ye>v?!='F)[?uXN;\>Y*?b?B?9 ?^K?C>>ɿ!PTɊDKnWؐ>2辬mG?b?a 4"fW$ 28F >VR>GѦ>5><\ > ?[Y>P?A>}(> Ob?B>sY>B?Qt>??, =þA>A/Կ)>%I>۾N?u <\>f> ڴ!Sa@k?:{3=HTe8Ȕw >K^4\,oER W؊^>$:1>r>ou"մ VENzп}pӐ?s:t>2O\k,Iu? >,=GJq?d >0R\?! e8=DI>6>c? ?Wҽ%%E?0 u=R??a.[? z?ǽ\=XR JѾ&}>->>?0?S?`?;j><}ƀOJX1 4p 6+fұ`>P?P<佟L?=>Ump>U=]͎>^e>\Evbȿǽ BA?B2?i3H?f ?vc,x??jؾ%L ؾ=$ l>Tq?"X5;L䰿.?~> '=OY?0m^>?lʁ>\ܾ>R@FMn>><و8}c=uʺ?_>Ӛ>T5ou >M>j?;hT:1i=y,?S>i3WX?w-ĸ?kNDR>݃'4>C=/{??ֿ8H >)* ?lRLL>8U] k@R?5?z"?6?8ƽ_ V+Ʈ@ ?YЀ=ޠ,>(@sle=>880꒿Ul?.c =i^X8?A? > ?)>?ZRC>ϻʿ:MiLfbZR>it??xT=?=B?=C L?2>$C;?L`ʢw?u>$:: K/ڂw=VhM?A?<; \[>ш?t? >Xpr E=>?Wc=بxE,?(@?xh>Ǥ=- ?:2f?3T?bXz:xhI2:P>8V"@j?&_E?2?2$r?.?L?sq:=et>kLH'f=&Q?_?Z y?4=h4>Mi> ~DF?N?B?,B Y? 4 ?|>;?о ۶>VQOL?bJ[E>\J?Xپg@>P)>vV?ɿH;x?۔?1>ڻ>5lo%==\H>^?^h=+>?/J=D,>p n8|3=俚ﳿf=K׿?K?f*3T?S_?XzJƾdF̙?[u(>U@#RC7j9qXa=hB8ྡྷm?ml!?M(>ځi8Dlon-Ay $B?ב?dJ?w?Wja]˶fe<">>0>oֿ\-[:?v~LGF= h?+>R?Z)>f?ςmB>ܯ> =>.> ؿH?T?#g>K>ٮ.F?r>>[Q?? TE;*<)?v?uXØb?>F?x^D?3>N\,?K޽4󰿃j>hiȼ>?6=*?x?[x?#'>?GEc#?%S>/̾D?%E?{B>d?#0#y'">s(۾?9"?>/uS ߦ?\8Ц4쿧>nS>?^7>> Ϳ3p?|?x+?Vx?~F?쾿$=B?Vb~YĿe7>J?Qb 2ھ5l?JI#>ZF? &lx>pJ?Zg>V?&O?W>'|<'6>rj=N?0/?~s/h>ђ|lw0> '?;L=ꚟ?*I?S?96=/=h(`=0(P > ޿=A%>_.>σ=۠/>>2>п+XШ$-ɍ$=@"u?t?\­4D ??zH>l@lC8_?ROؿ¿=??[ξO'A0?1Lh9?KſN3>@XL|~<8?*O?X?B)?#?[>bP>p`z5a;Mb=(>D?a4?3&?< eO?5/q潆U(`D=?lX?u?%[^?9ӿ1#HW=>5>?$?VIھ>vy:?0>u?^*>̕>Dž?AiH??> !>?<\ZNN>4jb> vo ?'-?5}0J>iܽ->Pa5nC>[ή|ڿC>M?ISSO#\z,?c? 4X>>6?8>&W=? 1>'p>J ?TP7>NDZL޿_>*Ŀ> N?@T?#H>$=">l?/E?=H(a}>u>{+?,Y#G> ?&w,?2H;y@?7>y vI>P8?eR?aY ?/?hu>3|>{ʿh=<Ș?C?Dl0>y>51ǘ??aH\?? kO ^?x>q1F?ڭ?-->l?p ?lѼT>_>wvֿ=W^Uؼ#>z >.<ȾJfr=>\?[>D>a?(Ƃ?T @-, >?J#6u6F?Ծ3}?niAl{ ]>ҿr?W? p.?d66?쿆xJDA޾7Y3ͬ.U=Y?cw>.#??H?h?FiX4c?A`a?X使~?Jc/W>, H>) Nʿd,>ʿ8p@? <ܥ?8)0KR;>?`nY@?t?o2V8xp/(@ $L<ߕ@?t$눉+=Q%>yA;>$ ?bt?BŽ>?>X<=?93R(fC?!迿? "-?d[au?(ԽHȾE}?ٍ~aH˦?^ǿ<>}mP=_ZRVuK?V1>_iB?[?>ﹿs=fy¿ھJ&oG?F?ݸ?ȧֿܿp6J==qcݽ>^8_>4|l@ >d@>+RA??"yLo>>d@;272E? K(?ξ6>?IֿV(ʿjA=yD?W> n7? Ͽ7p\/[ ?T>>Q??@1>>S?T U}?)w>mƾƁd?*񒿓9!=׳(ڽ=?=>=S{? ,ھ%?D>R?-KM>5>Ey=>t>rο/=H꾄D=B?+Cu7?m=,?3+?ѿ~?>!')Mft?5X=.b}?D6=:k)$̿pH?xHW>\Q)[>Zq>|=b>oJx>HM+?,D=mLN1[?^ v?y>.8RLh?Ŗ~¿!]xx?2,1E\?b?1>=ztX\F5?>H?4-?^]%7?Ί=Z#? jWt> h? $?0P!+ӈQydB?o@/޸?u>I?W?3f"?L>>X>}?,A~>vm"̍ǘ{C`᏿j=/`4%?gD??'@6>cp<?26iŽ*bZ_ K?9/?1ln[o =ap?S)E4|׿mLW=0?O0W(?p&r>v8&ٚ? tN?'?迃2fD>m8r>?J?>?ƾt6g?`Ȼ&<@?>$>c?>/۠6h>|>"? ?D+??Dp?o<>&"ܾě=8Jو򽓫II=Z@?-?7*v>r?w@%?3>B?>+#T>U[*?b'j|`>=\>p>a?Gd6?u;N?7EL> *?>_?)n譾lj%= >> ?>>h4?/-ǿ#gF?0t4=L5>E=i>.?)Ǿk>\z9'̿P9"?R?fxh->u?!a>.?:?j线! <>2?V?[x?R>>x=ۀ佤z>W<>x?'RD䰾?=Z.߿j?M1>D=(?=R;?3 4?\gl?C?XĽ %hϾ?A=v?R?>*R"ྰLZ?D1?#*?( <duɳ{6fr?O??`?LV_qھC>>*HZ=>h@uT]?`x=uP+?n >0?.x?$F>}ѐ?T>{J?pſ#}.뾴j$>>4>5??=,?l>M ]>OW?V>$V>GSaǿ{?!???4T{D>?Ue?Gh>0P}}\>E>-%V?0z;)v&3Ⱦ|?DD?NH?,&Ӟ_鿿E>ɷq?^,>9?%9>hp?+*=z` <P??.N4b$>Ld>v>ц=ŏVbƾ:y?t?`h?Z F(Xv?p۾%4wt?3⿔[K>? 8~C-A>88?>dռ0Cꯞ&i?N>? 8ۗ>Q L?_[>iM=Ĵ⿴}?'9:w&? pL>>>(?L="<`O/=Xi>Ԩ;^?L\>+/?C?;#>QDH;e8?Q;?\yƽEDrD?c@ž1? #d =hg>>I:'ؾʹa"y>>>DĽ0?%2z;43ZL'>?Fh?tf?#?X.?Ə?l>Q>c>'0p6jLDzY®>%`-½/Ÿ5,-P?ADRSBYp€BL֧.©a T?{AT@.BDBD±gœz^b ŸT£:B85<<针&obfB BEB!eBcwUn›WqtE¨G5AW)B3A7DAZCJCB >٠J‘Gc]#LA:~AXA4A U_-|A8®rBBd^?SArlյ>zBB2Hzxur.A?B`AVAT+qBWx`YB4D¨d7?@DB4C"6iBZB!4BAjZB7 tC{,ZTqpYLB12AX@B ABIBw3^|BA"BZYBP\B~BZ«NBAzQ¦‡g@@80®u-p9u]jB$nBDJB!kA BE¸ByvB[B8 ¶@pA&[C BrB0BʇB22BTAsB7BAp@[Bn`B-YD{]B-FB#C /AѨBLBvCB'B2A4^ʮB$A.[BvtLt¾2@KwѺ£ ,B-cNAzx?›@y'ƣ+Ak0HA‹.BdHB>-&\*x@B BB4TBdxw‹_BB&B=-Ba4B*Bl.A;BA5BƖ\C"kdAAA>AfB bŒdhBC+:T ʛBRB5?BbL,CAOB5 BܩB"xB3XBB\A-Ag߶CB}&A}A䦶B#(C)BبC s=Bj6B7{B{B1A?AVAB'B&:Bm BJBhB4DBQƘB5[ԹLA{tB=BxAHBܫxB٥B…LBX-BP(B&XBFBʤBBp+B&hk'AD?ؘBbBwM¯sg4¢B?0>¨~RBoBOA@J0A|#xIBBgGB aALB^B"B`A\G?+UhBMB@)iASm›M BH6dA=Y@8h+`A 0BRBK#)ANBI@C <7>FހABBC0ZCBCaC ?CMAB؜A>,AU*B xC&BӲC-2CBYBA?C 랧Bo[¡J$VB"#BrGBNz­xGBf,Ay~B3aB iPAڇBBJ:B"B %RC"^C'[CBC&B ֶAB@9CCf~qBB_!*VU~^P&BjBc mAloqBNCOB'ZmB-cp$F>F…LAK@WOAj:@<1R<B NB0ALBaC~@n¡SBU@=u§qB&B?ǂPB9L2AQNA\AA@zA4ݨFBf681mAp7TBUB_^:BN±BB A^@O05[BX0?Y*BzbYEAOAYw2BlTB|ҩCZwEB\lBq Ap5ChB;CG B'A^¤¯h@B1BIBpc?BB\2C C BbB֛C5@AǐC?B BkB#,A]pCDCA/B`IB(N6B(C'BB|ACPrB[Bk,AlB(uρ~@ LO9fBZ?B/53BBGA7bE4BwgA/bBP`AoBܿp >SSZOAXC(BVO=BbB&XnB> AR B[~mG@́PAiub´AVrAڇA'Œ-=[YAhnȧl aY7X @6.1BJBFBl BB7BAcB%BIB~A6E˽BX¥GLCC-`B?BJJBN4BBaC AZAW4AwhAt^BqoDANB*,>.ŠMAc`:*B`BdMARBiBB(YۨAOB}vAAA6BB*+Bv.B#BA~C2O4B.B2A*?@BfNe-@gB:BBQsB+AQBlAAA©ٶk-BB+:`BjExB$AB{AK2L5@BN#yB`ZB;BBHB&?D##9AHB1*@IȬBNB0W#Žl&AW6BBjA3lAhAmS@AڞǧH+BRqd…,:šA*A@Z]B`#A Bo4]xžBYB |rBA5$-X0BU@|AB[@2ḄecƒѰUYC#>2a>!?>8=}=^`>qfl0j!p?(tnG>>= м=`?\>C7<5,J=ؽ3L0>=*Av=aR=>?FݣeAܿ~ hN>C\yο(0>4?HVk?I??Y,ZԿ-w?+>?f!MtLIQ>I ?[>F%Kf=% ,%vIؿ}ővD9 >Kִ?~&=ߠ=+B>Oо2?A-v>f? q;g@>t?31? l? x>'?>,ӽA>~b?qż->b?5>P?Y>m(j;RĀ>t?2%?82RJ<+?8`J;`>=|>>>op>=8TľwſZv=r@>8 /ʾ߰>8>>?+!>:L?9ҤjPs>v~?N?\'n?$ sv6?9 ?Ye?jN>=`>!\?*3?P>E>>9?G?6:?W>X>Tʿ@=8b>>@!3M>h? _i>s4?N?xѫ6(n}y>[KB;>?:?G> , k>0b?#ڿhlK%>߈>>O1>P9d?DB?f#?P>nn>Yd \;^>>==d/Y?0r>瘬>(>~><^Y=Ұ_} ?n?<6~?vx?W~-?h>p3迗N<>?<=m迌}>W>?떾x~ nԾ; wMؾFxqt?k>&ŝ?>ps< >:¿{>w;> МXyl>?<]Td#!"r=.~?>Y>CG= U~.$s?(#?`?HPM3稿5:>Gpc>}I?;?o >| ?>&eܾc [>?-4{J0h꾌GP?*P )cdL= ><>"![$?LpzɼP8>E/Pu@=N?YR?B>I@?7?}?̓??r)6`Aj3|=M L2>BF?81W=>P&?]ʣ V2+ѿ$(?'D#lP>2>ؖ8]? ؾX??ϓ?`?m b?8m~R?R??&ZD>Ei)mӛf$ݨu>崽>d7?Y>?Wy =7D>-|?1ɾn>y&>@()/0Z?}"^ZX*?}?C?c}־=?F|??y:4T)M>Q8׭)>>ة? *>?Gi>I?^2w=Aؽ=@>˺?[<;w bk>J"?1rX>ukCAJl>;QֿK%'Q=_??b/??^7`?8w>=U `uZ|;;$ٻ=㺮 ?<9?0S>gx73%?3𫿠7οSq M?077XN>@4?1 ̾x>׽EҰ?>^>.0K so?l ,ʧ>z=?'H@=YP>M^<'4=&ĕ&>w?9p?^?b>~ > ?I=b;rż=O`P>P%?f ;P>b?^>M~,s<;?$\+>ĿV669=>{E׬?j?4G1{?+&?jȬoEϾdFN>?X= >`>}>4?>ɏ: |*HZ?=>?BCL?>п4G>,ǰAZ0?iտ>>?%1D>d>Fؾ>;n?8νMп}s>Ӿ$jjV?I> 9[1>1xdj$?ȉM!b?Щ,t}?+[>ן)? ]?D?[O?Y.x?>> J?/mڻ2?/=z `?=Nx?Z>W\!`iB>Dd>z^Hp>ʘIμM &[2?5dDV@?"?_->N?7X˿=o|o?zT?ޑ>0?K;>[C].>voVӽзyX?$<5=?o?d>P?G$)=A>EGT`>tu>E?OR=K ʆ?tTS,(?տ6>d?:2>e}?>>@??2PP>>4s\xǿ%P>a= ?9<@l?9]?v0? ?::@>A=Կ}p1F?BT >kf?x>lA2dd= se>!>?>>Ӿc*G?W?>vR?M?,KҾ`>?[Z?>J>;T%ɾ>Š=I( >T0?r>ۄ>?={w??Ԩ0lKW>T>ҏ>'N&B̾?PE>>}>TEl>N?Y'=r@]Zr?葾ĝ>i?/>&~Tt=>ǜR>2q@>tz?j+(>{A;=qe0>X><>>#/>&f7b>>{>&V>> R?i?8?BbG>WO?O[>A>#~|XM? ?pؾ9=~<>X?#r`>&؏hf?P?D7Z?w?<|;>v_R5`?`t>>y?AT?v>]/?1>?X?z?;)>{ Ŀ'?M?oL>n? >BKf=B?l}0?&?{ʽ?*W>PK?v>9a?Iα3?O>)>KzO7n1׾>/Dξu?? ?U*>3)AH>?s˅]ھ⿮@?m()T=K?{?i&*>!{Q7m.輿kH& n>u0K>=Ŗ?{?&>hQ?W>;9`-2L|H?==XE=0%Ո?Ve}t*J >?D٤?޾ ~>?SޡD?gZڻ0$G?>Ծ^:>Gzؿt"Dp|?#?^n>c>r?h=:?*??$̈́>Ѯ<=3? ? #pDqL:h=<1I?qMsW/>i=>f>^0;l nv??Ǚ? ޿74?.boFr(B>޶>b?:Q ?/XY?HsͿU<оL5?: ?)*[?/XM؀ǿl?5>^?)?\=LF?<>FzŎ=Xzd>44s%}.?Ye?{ZAۨ׉,M?3fN׾!߽?zkSsV)ۿ( c[ >BP?bFkn7俷?FĊ>jX? ? ;V>?k0? Y8?(o>4Ȳ?'- R??gfrE>~+?;?>6.? ?M? #^۶<><%S{?l ?GTId־o ?M>F8>&Nm>E KҿE>w¾9@>W^?+¿;E??L`?ʽǻ,_Pl>?%|P?:>/9;><(8Ix}>ZME=ާ?mپ&>'㴿#Ծ8ھ/bY>?A>4 ?˛|e?z;W> >|?W? @_3̾ ,>%?U+?c?:?R%\V*6>hF-="@>i>?z>KV>0m5:W;s0?3$>10%o?mo<°>? \9]43>>A>? ޣZ?<5??vQ%?>;߁usn>)X??ے?u>=>ׂdA\>dM]>T?>(>?h= l>ھ>)F?"ǰ>(w|z?gAԿ ??7JE=5@ X,=?W=@? 3?V>چ?Z>4'I]>)4za=ҿVϑ?4Mdv?B>P~3?оT">%?gAJ'?.v>?-Ѽ pT(~{??r=^?+W`粿4>>S?>׾>>4=y>?G ?!9v>=V?"vc\>Β; ^ʈ?-܉?eAU?p>Z=Xk>9?U <`?\2ĜfUA7f><-&=v>?> ߷>>_у*>? ?6l/?'>WcI9AȍG??Wv=8>gx?>~>þ?~J B>~P>@Ҙ>?;d>t15>/QѶK>?<*R)?G4>JQ[>q1Δ\?b*?wO[>(v :?MU6=?>b C>ۅ3ȍ0l-f>R=> ?7h<;(?9npҾ!VE?0Aj>&6=Z?<Ƥ>ſuupF%󍽥L??R+F?AnxvB{,?w> ? `hɾ/?'#8?־оY?dv>z$<-Za#鿩xFY<3jnv?+>uYxXy>9?/ ?2?$2=p=?f>n>??L>x0>pP?a?.&˭?-I?`K?H@>"g >$,>>1>rB=Ձ?U?M:Q zx;0G>%j+ՇZ0??R?\=r=OI(QQŠ&=?X #?'W>>>b?XT^;ꐀ=L wf#?&?5$>xŶ*3k_D4^WX ?!? ??K??M-d=־s%?)/>_>%Uv ¾7=ŗ?_KL?>_ܿ'JR?.-> >>%?i ֧>.¶V `ٿ?n0?;N?0?R>D?Z >7w?H@?!6=?Hf#Pg`ݿx&@W>"?ZF?U p=#>@IHx">K>??? ?uD ?ӳܿqҿ \ľ~'?ƚ?{? F?=Y>?i%M?u5<6'm@#@ :<>p>/F>?{?em8?L<`?3tp4?id]< :@;K{(S>?(Lw+>0> vD.Kܿ|Z}>>EL>0i24?=K>|F?t?s?ל?8T->L>8> t>^PX2p`?04G2=th?@?-0뾴n0K$=?4O?ohp>ڽྜྷf?kJ?t>>[>I>>K'>6geF>?X!{Vm=?8E@>vSvب>Pك?e?c?=?J޿ 3>{ m?u ?83&y;|l> S2?i> 5OOr >@l\w>>?8첿ƾEk=|r>yFe׶?>k>WgQ῀?">ms><>)>w(?) b P?~>7d?`?ӿ6ῼ'b7=R(>JՐR?V?~>Q[Y}0>6B=FĿ':?a?ˡB?ǀr?9%Ĭ?R}=>ҿ VcXK=a8=OxI?N<=9C8<`=8bP;b}pھ% r**,F@?k-|޽k=S??7?YU?uCim{$?TjȿY7(2?CAa?!==t[x>K?d>>GY=H>gb HEb&+}:??i>.=ޭ ?5?)??ٿ/<̙` AξξZ>䲀?|? yP?v?Ĉ?/>5?8uDGR{W1?|>8Դľt2pdu\"?q?Fn>jq>*wG64? Uw>W8f@DԾM?<+>舨>زR?KƢ?l9hn?36>>Sf?6xP>: G?*>S?νcN?8:> Q/@W>M`H>lмӿep> ? O"пX?7~?5g=O]JgX?|1h?׾@dy?I?L6?>T龨z=xοsd=Y?ſX">K>?/p>N>B_aT£?]?+?D~-.?5wYC3>D? ?r>?Y{?m>]l<"†¡^*A=wW'A2p6œn+œ{8_t=\&'5 mx41A“@L’0­k>Ҙ¸K†1AOoŒlSƒmµEƒ–*QŽ·mAjq>A@\|2At ¢Ih@>N p°Š/jְN D ?N¯%!L,qLZjeA|BZx d $'n <:R`W?  R6RYE`» _@g!SWdDA4ŒBB[4pBL|A>N6©o»’H?A&½´ 2."'o3OO¼K6 =fA@pAOPA|jžy"A掟B%ڄ-d(¯glŸAӌAǃc”*–~оx6B[_M–AUAMJA¡·^}$1@)6‡ %qHA$AsAAA8zHNIBAt•1#@f B7?>A/OBDBB@A3q/B@AgDBB5*B'B0jtB 6BܘžQN`\B8y(N¬'N;J@ }մr‹(AvBBfB@–dل5,AI?>hol@}&A5HBL $qNB?Q‰UA?‹KGB[vA]! ¸:UhVBu¤B\sB@){AA[™r>?J|;d}B>a¦v\BhŠy#^fz’­͸6›l ->_]C"¦UB"Aai-BT+(AFnB<(A1QB0dB c8AIBB^&B±NoU@†}PgqBkA&¦#9;5 -B [,aZh+(B  BT~nizB VAۣlB<H@BXB17BfB{V˜¨߶Bf!¾B B*\ ‰fBKBsތª+¬ŒJ@—5mA

    p‹q›­H#@ABN9AwA„K¼H<¾AN?4GBm&@(JB En^qrA e@!B,h1BDOBxmRB@BV|B=]B¾F@"q8Av7@CBPeŽ %AC̞/Kw¤B-:BZA}6CC7+yB KBI4C onC2BzA3B yuAB-JB0B헎Bh%BCQxJv.BBO;B|B3C8.wJAtMJVBA|BBB<@A5)6^A"3Aq$@B@HȦŽL&`9y?3w "b@x!FTBO AZI·5rMhqnjBa iQYnB 0Q]ixgB@ dĬHX=ZqEM14¾%Ɖ / "A+9’Ⱥk¿GB8MB-bXoBE? !?džFD{yAœ U,°.鯧jɻ: A L:G=Šxt•Af tDaAbA2XA%3BFV̓@ U IA:<¼G›BXB&?(•ŠQ/µ¤»ež/RN¥YyB}?X;BQ+$?}*J3BBxt9ib N˜]’jT•~+*R4D($@¤ůї«ɞ"̹ŸnjATIB"nOcx]A"B*B BG!D9Px?€)-¹Bjl3:A¢œ04x…6BTB: )ƒB LBm)B-a"BmŽW³!B jB=B+ZB)ChhB1…|hBB`[X``äB?BBq;B²B1T!}BB\B[BٻAۇ4AnB#.?BB]DxBBBIF6)RAB^ARBB6Aq~g)PA؍ BRB BKADb6C8A[ȇ/@oBBKKCB3BۦAUBBgBB&RBA(BOC l7CPVB A nR)еBHbHڃwTŽ%„5,B|7{gBhot“|Y@"66Bn3! S ¾cA7"B-?0\௰2B+Av';y=!}@@BC MBY(B?B\BU%4BCCJB҄BByA%B[V B)BC,BB̟B&0bBA׍B֊xC2BB^ +(5B]B8A‡BgfBNB]tXBA B7A@AXbBBUC {?bBlA@B)&BW2A ? B@5BvĂA5½!B+xBB}?B ^Bx xB/P‹^kB2#_|Bt v@B9B"B/ؖKQHKmB4&{ukBXzB3,BxB2BulVB{CD5C%=BHڑB:BeB WA`AwqDB¾kVBdRFH)BPBH {B?5ҀBcBt%’oB`LAeB=@F&BL.B!mABk"@^AgBUgW,?+Fo>=!L%}>*E=K?2@%=@X=&|,?D>2?S^?G?nA>1H>dM?=ȿY)\@O>?W*>?.K.>?:?2fB>?'Tb>SǿJU>WŘ?rC?㦿>ݵپgqJMtl+5%>٦; f?=!!>H{> J>+{}r{*=1B>CAɽ>]ht|>R?'9>x]?/v>g>.=?b¿(x&^t ?'}<>uZ>>o>Ҿ佃hԽ?QBkپα?0>ԃlxK>bKN=>:>f-5>^La?Bо4>>$|?zx?sz>MoоҼl \?s>l<>}(??>XOM*?aU>?'`=ؕ Z>C>ڽ/?OP<|>$J?Tt ȹ=ށIXɦ׏:Wfce?M?xPq?ĭ>4P> ]e>^ ?{P p??`><>%E??4<?X?JzD>O?s? <ャs?uc>>?sP/R> ݾ;B>>}0̿<h\?MH>=k?¿}J?'?W?C>V?:>>Ձ,Wy=|6?6T?.=>B4<`);]\?剽@=?{;*1%y >,@׿@(ܦjhtk>6M`?>0>=>ۯM㾹꿖ʐl ;;)AI3T=? }>[~p>UF6v>VJ>?`?Ri2?&Z>3:?rlul ?Nнݵ'i&?W? d>OP?􈿋ȿ%ܿ>qh.m$W>P>2>=?>7?XV?` ?];9d>J:?W?ƾ=*V"* J?Y!0?u?My?-N?@>ݔ,3j>j/"lx>!?u?m?66W\>b>>vy>ʄ=BZ>QY/.=m\ }0> e50=>G^>qȾ>lՖ?QT>?)?LP,>WDݻ&>Zh >($K|HZ?!Ѿ i?1>)?1V?<ҾF??HDzz1G ?9 ?ƃ+p ?dE? bG{'?`>D?Rn?K=ң? ?+l;ӹ=U>85Z?2ҿ=,?+B?W)Zd?={RD_`-r?(#?HXN>? >}??Rf4>> ɽzJs?/$뿇 ?4AԼA|οlE ?ZR=C%><>Z>Ӯ4 N?A}RI?=?P>R$?P>#v?.n+?~?z?~,9=×M6>7?w?!6YZ@?-b>R>L>G?vR ]>`ӿ*Ql?|?E ?@0L*?Q>"6T ?-Gw>B<\G?6>80>,=j(/D;;]>}ֿCAx*4?@? j?26 `?ИW??K>?Dxl>Q ?Db>?Z??;p?]/=AR#,?!N㿮$%&~?R?#G>?ڿ>,‚nU0>$ ?kZ?]?G ? 4-?'+>l>f?M}>cX>tv? Vؿ[+(?#kL9 ">&>Z,U#?vҤ=ғ?2`?K?\?w>dU>n?#92|ZVwN%?xV|3\??S/ upJོE >4T?;k ?`F>4?@?>V???#?M,׾Z͙0>zS=W@\(= 0=<.>W?N]h>Z1-?}\?XO>[>?Lſ*3ǽ5PL>4Mտɰ>틾]"n`>Foտg>E(/\F\㋾G9?+ Y=+VпCTJn`?)>J^?I{>"!?>?ۣBl߾3?ZM>d,Y>5οoFIy]>{d#?f-+4#>TZ ?U0>4ϖ?z?e&c!?Š?8 ޾Oz?!>8>c?gM/Ց>0>H ^ &V>?;v?,po? 4~^E?C?# ML>(?{=w=rL>Rѓ?U>h>>> T=x?>r߾Fj?G־3TZl@Z6$s#?"x? 2>Qz6?D>~DC?qg`>?v]J? ;s>\LK>^?=jhh?e>Ķx=X?a6<40?n"~>^ؽ>n=m\?P[I;2@q,?z>i;R=צx>T<_*4y?j[?3PH54=CȽF??ml?[?Ja<?p{Ң>U>x?QʾGZN|>[1ؾ&/6v?B>y>=2_@:@D>F'?1e!>?!?<? rR?h?I+z)?[ Bn=U;Ly>"#\?wpsX?W^>`qy?'b>% S$?u?>hib?^~?AV? 3XR/f J?}i??!>{Jsͨ?x}>}?=8>?1%?R>?V`> }>fU3?M.?] @>??>?A|?!?Xd='&?%\ t>>=ܿmt?>>bN> pˤ?{վS?+>SO?^뤾}Rt?g&3 ?x>???̓t?^>4> &?>@X 1?! P&e?(?s =7?#y~#kc Fr?U?e>1[=G>o=XBv+O-?&=?"'?6?[:;> 6?E lTֿ)>ͅ ?N;^(?&?m>r?- )> >o? i>"^??۾?Uq,\w>g>}(>'U6>W ??P>?l>?¿Q >yM_9N?%=O?NξbA>ſP?,?}0h7ax=?{^g?lX%k;>>?*p%\>>K?s??U>]AoXh^f|>vӢ#`п!l?o\=o T?U+>=>ޕ?uv^=?hQdFTA X> >>>H`{J~ >7f>0Z>2>b>x?/B?M">/*=X> ??D<"͠>>C侱?S> d=HT>6G?p=igؾҜ?wBoa+I?T>X>$/?WMvv? 0??a|ݽ֖ ?+0>K7UfֿϞnhEfR(+ຽ>v< l>>-?< ?@ ?B6?Ģ?3ɠ>?"Ǿݮqf>.oI"?~2>y&?dz>u?$m L} ?f8>+c$1o?4@u>>I߾4{?}붿yt>?tV춾rV@ OF9Tg^p2f?]J>rMRi]z%|>!>x=.ξ0?qL>?y=lN>l?S?>C I&?x?|s`?/: U>I;󸀾/7վ ?uĿ>?C\?{_ }Qp5uMT ?-pzdP?>Q߿m?\?hO?.u?U"?2RvӨ3U?Q>?K>W %zMs>Q(xq< ?"w>R?'>A=Cd;?U,Raľƫ^~S=d$?c ?0={??Fľ27Ae)WI\?@Op>>sa> ???)^ ?2~?:m˿/ė:@/?J>KT>?xj/Ęytv5@7>޿40;3OD?.><;[>F?vmdvF?꽴 01>O \/?j>LJŽνv3`=%v?]>> =??]\>X=nfؾ,N?^sb?D>W#>=lB? C(剨?9JC_?.>y?>?s;?s? ,8K>޾S>?(>ԫ|=_ ĮP!1?2{``>C?`?%wUnd?E;_B=Z8>sS"Z`᜾d6 ?IRY6=o=PP^b>z"Yז?(?.?{hPd>fľԠ .?B?v?'LJ?T B> >->Ӄ>c½?0?l=oT?L02?xWv+7ٿr!_:j:?G >((j,?9? F?W =1kwa_7>=OƿGc>>b?|p?3G>MS?gڽFRN>=+# =?ȿJ# k.j(=>.>P?=> >i">>F>!?nmm?qyu?n>0lɼ>2>½\?ktI (>>`tR>d$idjٽqԾ8=Y?M@ź=ݍǰ>UQ"??>r>{տR>jE@ }>pP>ŠJI]Ⱦ/>tԿSy?%?=z4?.>dݿ_\ɯ>b?6RA)yW?đ(?F=?p G?COѿ3\^?TF>]9?B>T^^>Lwj,l> ?d?qxHJH.!=M־>0Ŀ'¿c޿AW?A` 4>\?(0>.ٿ9BT2=? ս'??/*_>GW>elYڽBhh?W$?D~@ ?!B ?%R?h? M!sʿ4^`?Qu*f=>Id7\/B>5 J?NY?" >ͥ8{7HeJ"M4`>M >k1 ?8&?DŽs=2>=?NR?,,T> b?==k gPnC>/>M>e>>Hhf?#M?(Z%h?Pje'՞vL&^}???a?󈿄?=!Dĥ}5,"`?D,uH]L`KHh>YM?TT,5h!L?~*;??%Z?Rj?!e=w`>^U=^?,oQ*)*\C;_ op}ͺ7?@\?/g1a??Z!-"=S$|?Y ?LU=mi?>C? 9>F$޼I󲽟hoZ:p@?}>b?Ə`# q>ʴr?H>s?ǥTeP=uRl @Ə!ſj0U? yQK\?lЂM義?e$Al? F? E>A@>7JJ4?:G?Y{w2ҾD(Am?>Cվa?pn?,{?AĿ Ϳ|k?>4p6ǼN?hB?@*Ӕ>y>ƒ? e>A?`?=łg=&pv=o W5迅lD$zf D>it*B>C>?"hZ#K?-b>g0ν}{Xp=8<< Z+ھ jʿ,$>G1! gg`YTq>f@NlN>GB?G`?v3Ts?F>?;>l{Qy=>oW?A?1>~=)>nؿ>?L?>?!Z7Ͽ6?4ܷ. =N0xL?a%)S=j>>A? &3e%3t>7F>Ȋ>W?IU?|'>. =~684?q>ԥ!hS>$b)?0ˤ>ʿM ?S{=籺?Tν HTJ?}DU|?cȾ`ž+)=q{Ik?OIfܒ߰->EԱRhɾֿ~b?J<?d3?i>L>ݎ>ٿc=lD5)i=j,/Շ?#Dj>*>?Ȼ>7!ͣǛ>d=PؼB8? ?z ?ր>= ȿED h ] LxR>HT>[C￿W >8š n$}BzBB' B,e50B^4B&<@n(2r?8n&m)BtdcA*CKB8 ?5B/&AѣA@HB>:Cˤ@BԽB0DBQ@jB eɿBBA -"A(B6AB6։@fGP9|LWvAB/B`:i<…AB^ܢB-{% A{AJRQ"FAUiMѨ‘'BG&‘+*oxBRA$3=B BPdŗB"@QZEB-SAA+jXA¦d=µEs[fB».‰u}† !22B/A7BvqB"wYn/`x`%> P^B }a A2#%BCB%p@Vп:@?u«BXzmA@B1SA!b:Bt'XBhB,˨BxT|^Bfhk BAaBlnBei1C%BxB(B^B@ʤ AcA! ~~c"»^̓@+ª{@A1.D j± zl@•JVAedB:H@OJB, C#2JFB"B>AARZsALyŽP r\lb ,B,A7@h -M_BBp+BTHB_BH5pHBu rA,hA6µBMGsv#HA&BO0(B3ACAB]kAa BBGBn6` B EJ*BchBB_CB@EpBZFB9B`BH@BvfAvwž,BЀ8C65BcC[B&B&n@ǜBÙW-4¿{P5w{A{[´A3jG5i3P+3BBrBHBB0BVR@_AMB DBXnBCA`CMC$[LB]B/CAIB C7gA۾Bԑ/CmBBTA7Z7+[ž,ABB ںB)½oh'DhAKB-5BUudBrR~C9B%B B ߌuRAHB>|BFR֪B 6t1bnBh XB /OTB|G94HCBB CBUsB C?2C "CB4BsC BA$|9™dA#B,|@L\A ³BkBsrAd>7;YAkG|BgBB3A)AB0B^BC>?IBnAFBNBcB3bBqBcqaBh[B16HxԏA\G[B?BWMjB€yB}se?+µ3vAAL.Bu'A(AyB(B&H vPIB8`LJBLSFLf.V*B,'MHA7B8LBoB?!BmAE?VP€`dG(ŒuVCBH+9Q@b#AuQ{R®Ò?k̆IлI/'3B7dBFA9B-BBAyB(FIBvՑDW/A Bi.ABt|CS{7mBAaFB>EfBRiBIB)qBBAw.uBkğBRpkdAARŠB5nA\:B0AݠA6~>")>ͷxL7$C>peBDBpBCAB+dҹB`ZMg?p\:BHAd@J pB8B)B޾g?j?|9yX}?gSW` %=@?~?|_ھ}tx]N?ȂZ`0?kRY?\t?TCԾFm?kNj?m=b-?ʹX˽/>3ھrQ?=2hVa=_⿾#>Ra? "=ta?B<yJ?qV.V?w?2?oR?<8*[>e;8?[>q? >>'U/꾈? C/?P/&> !?Fl=I܌?EV>D&T?( >lԾ1?.Qh?Swl8DĀ ?t*$?n=ߔ>>0?Rd=P=P>>I 3(( ¿GȀ?&>vAK?^t舿0Q?LvKCοG?\?NL? =.>8#?z=rb>И?b?XN>!)r?nIu#g?/Fuj=)>I+'8b>RrD>]p"?,#?ʾm)B=_>R>0t!?-? Az?(?#>{$(M?i伋U J?2>&3qL3YIh>fb?g=l>Me?T0q֤>>3=>=@?t!͇?%??uԿ,;m ?J>;=;Pe=v=|GF?Fz?Y>A=(? ?5 ?TzRX>eH&>Z⿢>>+>aX?.5>) <3 ?q??Z?-G%ʾ-??&>KNF? Z?UR<`>? 8>`$?K? V=g6>6z~?,,?#1?ht^ֿ*Lt?MؾEky"> zDZ0t*t=6?]>V<9_K\|?*N?v? ?k~?m?>$>=@>z;t=B?Gƾ`ͭ?qP>xa?#K?@l}?wk>տ0*~;‘? M&@=^>T,?˽?QΙg0=ԼP(雾2Y>շ?a?C RfqlпhZ>G?!􁋾RL? o?Id?5b)g'q>~??R??D?[<?-IIܘ$? *{ʽf>">ǿa?7 7 m;`kCj?xS>ZZ">= ?$^tfN%H?{pCx>sV?Ws>\?WiȽ}X=.0:=3|=iw/XNs?/dk?g>_>gH:L?i->?P;?!$#Ew?s>}b>bi?H?OWC\So >L;֠R6?fm >X==L??'4>҅i?Iv=? ?\@>· ew -=9׬\=FDP>д}m?i>{?cq? >>'@&? =%M?!̴0*tC#쀾8+>qs>>2k? (>눾a?.K>SbB>,??6% 5'?c=>n^>%s>,Z=T? )v=<>,ƾ6WF,t0@?5B8?(?sw>M?GmE>Z?VȾ1?~?~>W*ܽ6=P7vG:*=Y??gꪽ?Ez>鋿L?;:?pê?di>V>>e=@P?N)>$+s$k8l@%=j\>_ ?83I ര?+4/j?4?+?QQƾ<`_h?3D>"!>>Y=?.[@??4~>?Fhaٿ7}>־Ɩ>.=b?"?>sV=@-?<٧0 "?׆}cL?>u>^F;цȾ1TS?)iv/76? W? 5\ X>N{#nB.}>R>xZ?¾+?hzZ/>>0>&Qؿa?@>X?5? ?f{[6?`ʽPfTXGm?}?\??^V?qE?K\ʿƾ>?v >6>j=X? Tq>(?Kk>T?V?;~"?|p?`KA?쉩=`>P>?/edt{X?=n0ǿ p?]=0>T>>7>?4=>ωmL>;|?DH=Qx?ľſv.?V=X; ֿv >?1=F?I?ed4|<?6Ӏ?%=8>$?c>⌿TBL&lJRc־Jֽ/\,ZʓI?iT>?k?=5ܿ?;\B?;ڀAS>dT;?>>&>o C>N>[?4z񿍻ƽ쇵>^j ><~?=d>?|=%<=H?W=ex>̠ W?>??)\;Կ> ư? >K?p6>k>ʠGZϿ>5?6VlY⿝<,?8~)>[Fa\P?B$?뾛]?/wA lD?\t?㿤D?+a*>%Y%U>]\?z*?gcJ> >`I??Hb:앜?$`?k?hP=E+ >٦S ^?I,?T?E^Iʿ$>ل=@{ߜտ?m*>G ,?0.|V?%"?u-0Bj恽7;?S[?z?sH%>߇>dƾ2|?OIH>'bhN?Aؾ9K¾f]?lw=ı ?c ?>l¾E>wO`>v?>jM=}~? 6`n>;h  xoܿ{?jtJ?p=2"1>O<=+d5@ٿ >*2>l??69O<ۀ? ?R{>g4> dp֧?I>ΐ?y7ۥ>A?OXV?Z ꦾf;>-,?5+?>bx>>n@L G>α@V0-rB"Dzb翠|;fnp?6(^?c>ɨ>ƪοlr>3<#?X >dQн䎘=޾4?cY=ZPp8?a=;t?dIپ|>ʼn$=?d:>=nq0 c&J޾<&>¾v=b콨)vBP~>[?Ӡk>> BM> dp?/}㾡=lj?X.?ſל|?dh?5? ?R~Q">]?*v>42O2?*>lR>}p>Ț?A8>+,%?&?g $G?KO>bVWCh?%>?,?D$?R-((?h!>糿1yZ?ʁ->E>q >v<- B0Q>~i*=tO>?80or`?7A>?Nd>l? =UK'ʾ}>3???F?3>>%c`= >fpey>Gh+?h}?=ݸ??]f[?%Ip>XI>[@QL>ׇyTƿ>? =^?JjA?Dh+>n>a"BPz6X=Px>R> G.P??$?C?B>>>X9Ā?>%O3CK== ?p>$& I׿ޕ6. ?:>h <ž=nؽN,)'ί<0[E?B?lr<*D?,־ =gDKQ?ƛ>?ƿ.\4rk=l+_/?]>z}K F? X>ܛ?3??FԿ4? =o<P>:S?sI=h?}?cbPU>#-Ⱦ) >:Ļv1Z>ďd][xXv]>zQ=о ?̊\ND=CA=?w?( Z>~ɿQ?f>?b8> OJ> r8t=&>e }9=J|L&v?ξLk=>??V%|?#+8(>"o>_>+?$g>>>-?:|i<8>eƿqo=(֪M"B?I^5BzN>G/>;P佶<=nU?.ܼIp>^?>]e5l{H?#\>? ]>5 ߠ?Ei+8?6T=#>D.?5.8?<=S}d6pTf&?H >5?B>:L#?%ҿ]>m*Ǽ:?gYd>"?_ڿ!?-?jտ_v=,M̑⿅uT<0yq>D¾U4?bd>3"?0?P??%?b)By:쾉k?z-?W7cPζL>2=j\ !?%g&Z?N ?>>T"U?h>>@@X%?e⾢?T}?e?f]lrfྯkTH/ ?3?۲>a> >/gT?-UIKx>۶澷!FE42?Z>lr辒ƿe6Ɂ :(? '>Gт?i??#f>׃=Ph d޽=֒|P=??U?:8?,v>?A!?$g7@>T]>/,?m=&%>V:?,&$? >?'R2ϿhEgl?~=`!e[=+*>rq/Y=|>As.>ns-@?JJ?)>Ζ=;t?8?==S@sCbƿ)Ͼ~ >?%'ӑ;M?B? S?U?DZ>0=/P?G?>-=X)G=> -=pΫhx?KMR@)z>Jv?&;ZT(H-> >MݾSre-,KG+%ھ*á@䬾?$?_پG76!)&o!] p?8G8>?PB ?;H?j=R R>[L?3_?ds`=&=]?lI= @? I?; >Կé??)K {R)>M>S#NQ&-5(Ӽпҿ73w2*ɿ5yԾƽ˦ڿttG?Tھ=俅ۿ?Y7f>*? 2A8>)ؾC$>|þ;X?p?>w{>oP?7?V3>Ȑ>W<),>qF1j> w?R=Td=>D:?p>"?>[ QƜe"0Ѿzu>y>ơoa?P>Zp?[`#> >z= >(ƾR4=?Dd>'8,1? H?F?a>?:?_.-:P@3{>\r<i U_Ů.?^&>>F?E\W{2d`d,m?>ʞb?;ʿ F?O-o $?$~e>0(*>0>ξ=L>J>P>~a?6S>~0>d?g=>@>p>Ҿ7F 0p?#=Rj>b?AvzOν4?h?;r䭿?^T8"y?sh=$HؿN࿨^= =?ƾ.k>w={6?Dݿ>1sB龪%}8?u4>-.?4\>%>~>L?U=",,،U Fý-d>;>[۾`O ?"I?G҇1~y8Tx?1 䤿|=><~W+>lB?%蚼@ȋIs>Z޿/lj?RM>7++=8"s6 &>ъ=Xuf> >pu?Vᄒ0>>M3-A5=L?˾l9p_?]^F,5>b="g"E\?E,?E`eJ~T?Lk Z?M!>>u#/@>w=2?+&W?l?H>g9HG)!>T8l˶h?Gv?Կ&5?Uy?g=%|??ڞ>>(za߾AT3?na?I>!? >Ծ<}8@>6|>>JZܿJ@=q>GؿZO'd?YL)⾩x>kL?_`?GQ @?3[x뿖=y@?>>&cԿJW; >0?E}?0D?J`l>9Ō>Vjdq=S8?/S?J>lK>9տP1>VL8>F>B\}fB25I~꾾i>*?7_^=z?1   >K1y=[B>g =Xĺ?֝j>|>]9h?,6?"P 0׿wRnCX!>"F5ؾ?1)?c#^= * ? URT 4꾤{d"#0=rjH=Ux#W? F?դsj?>d?Yȶ?T0>⦐>?Y)>]ν&z?]B\>j\r??/>t@>/zDFJ[FdB5u7bAk,J$"j<)F ™)X{`$ll½~x, `ՊLRR0s"pH'bs]3aDfV "m+ð}' 0 EŽ +Bk›\Aow¡9䧐]J/0*A{Qx=bʐv¶\AYXdaJLc,Q ŕ(Fj! l±$& >$]R`@j3< ŠW i}\cҠ KQi!b¤ xY"•t˜ªpl¤ok¹ ƒR;VʢČ|B8B{ £ :w†k=ow?eja P+Ctvp,% µȧ­ZZºB0¥ɼ E0* jlu#ByApvQyOB{&uK†žEIT:@b0B¡CɒS_$i,6BIPC%|ˆ +²Y՝5‘n¤G\ M"›E¾›^Ab%!AA¼;¦b8¸Jofz>mA"A_B .B/*hByBA̓x:Lt¢ Kh@W‘9± –iˆJ€u’8+X>¼vpAP߿zB|š;vAK + \AmmAE>i?ѺUpB9?wӬB>¥:a6]~BޤBwBH? 4oB9sBAƒ&.B?BuC>B%BB;A&qANAWHVBB:IA M͓Ba~N>@A˩#+pD¦*~:g@@>nRTxŽhgrNA"A1W4XMqjB ]8š:e9t»Wy@"6eUAtmRRu§~a·7”p”Lg‘»H7Œdn“vgRB+¤J«(J-¥Ÿ{ŽFb)HK-$H雷kHyy&k@i`%MA¿''m}ºS"¿9&NW4[u"N¿e[.O"„*&K px BGA-7s޽@[BB!@ BȜBG"B"!B2<>\‚w†/W,|]L®Y²3)@([OBbc­CBTBV:6°8@tBk7@|Œ?0ºAyBUDQ4Tž sŠ.srSX/T!0NdKSd`H7K+x—J5'ALWÅ8QD`2>A4c(pT;,·;‹sGD:>WzM:žšL7;Ÿd F#D<+hOY">^3f*Bxž0yd]5i^«Z#¤\_\6ºw_·3RMAš7̙q6b`N¬!“»aNAb²Ԛ^1V’?|ɖnz7W… ~RN^‹‰iOR >֦} %I, {6/1« ,¨"DjYt˜3,¶RA08A=kŒW? n d.B I{~ @t^P³¢ 9#tAdoHWOh ?I܆½ zL0N~m. ̎˜VBOpBkVX?zBsVv(AIaA4U#6VB1AלBјAäB^@BB^RBQCV *ZU Qw)#v›%VAܼ‚\6{aA˜\—=®-LD%wüG@}*h1FvB#OR4"N@@B|:FBBB!SBU BzKA}jVpBJV>B4>&(W?¯~$U6ŸX7ҠW\iª+~9X¼fV2WfV[^@6~ “Ÿ;•fnA=мBky (wׄ 6B’ _##e„kžy°}u5[BPª²׶t‚ ![BV`PCG ¼^´Q>?-"s$„zB4¡eAD¨A@fDtZ?!BC°=™/PH}€8&j ~e*€&.7°+B$AB2EBן@FBvB$B/BQnBB7WAB{65B?$rAZBVA Bi A^tAFAg]&AFsBk,GZ–ض@c qe[€ZArM2,Gj…O\.µ4(ABڞr~ie ‚o:QR`NP«gG?7[pPAG*BB`̿0'B)`Bhq?>43w >ѿz~>:/$>Iտx50?":)p?@?z^?!>= /ƿr34Va>}#Z?>S|?rоA=924??Vy|*>\N?2㾨 ?G s =6?>ϥJ?OѾr派jŸcv>[c?S&W>y>t>@?+ˑ?u*=؛?Έ>>X-H?"u=ZX?~g>JꉿY>?5?Z?8?d?>$?:BD?n? q=4?K=MǾ1|ڬ>&=P>>]?5u=WȿE>c륿NW>|x+ľY>"fԾ0i>B?|Y!^>ux>\ĿD> =ֽ>!wd?).?8m?sl??} ?n?fh?QEϾE.?  ݸ>&?O Ζ??!A>U^? 7-"U?l?I=|>ʾn+Z?g._\l=.h>>N"?>p~ p=;=jJ?R9߾=^^?IC}Uk:  > ?A;<="QؿPDR0[f?<)zX?2'>c=Z=_,ۿvd0_sIQ->ބ?¿/保$;`=>꿗9=^(?ITdI??뾘K>x?"??\B? w?d?0==Uq=(=W>zX:>~`?|(?<>QykUk 9>>al?:8M???I~=ӀH>>?D>]?n~T?"+Y>o>|=|='@=z>]^l ?~2g)?Ru?о?T*0 B+}=cx>T[&=`є?^u?x\>?Q? *N/?a??O,0#? ??e==U>~Z>tA>W>J?T?|P[>30?< ?}Qab,>־U''>Nl?Q??3<?mB?q?R޿,=E?H?/?Im?]s?"W>B誾u==/v@?ϾeR ?6U>>`?w>Q?J>۾`>uo>"q"`~?>Td?s?.n٪? >ľT?uИ=;8¾?C:>? ]<*?xy?z? fo`?]??D?L?:Ӽzw<>pީ>6]?LpА(6>i? g?: ?>;%H>R| >@+=1?u}>&=Y>i>>=JའXB=6ox6UX>my=,>??k[-WSj?(?sѿj = ?/>)+!?=OAKB>p>ȗ=drGO? dUg?6뾥SL?S?iE;ʾ?):o>[@?JYU οl'?G?8fp?g\?j(?&߾O>A|?f?>tX<Z>P>=5?(25?0\z>0?A,?.?X?x>>t?F?]?=pl? > qk`,\ڿ=`+?|?>߹dJ>?6T=?bX @ Ǿ便@S;h= >u/ ?? ȿ<@> 翩?fV>=O@Z?#0&?>>FҾz??kbھcR>>ADb>m?3G?i9v??=+?? x?0QK8\>?Gv4ՠ>>rE?OX=9f^`5??X?3y?'?oZd>H >N%{>y>㊺>*>,gO?'I? ?:5u>'M齸??vk?f/XQ@;ؽA=gt>Ņ><[@1B𾖏C?"s>F>=?v>9>p;>өm@=.A?&9?]>ܠa?D}=lпGv? x0 ?N?'!KD8>'&?Iڿn>.@$½9?5?8>V<=+ z"?m4>$N==zl?J |\@ξ*r?|`?:r?>m>x!9cT>DK>'Ax1F=#?3>r?y>h<΀p>>?j(?0?%N:>S??R?]jY?#c?8z>̼?w 4>?8ӿ;?g?h iN}h۾3k?W?f>?I,6'?:Cl@?2>R?%P?&6 2 &sX?@sD?s]?%eFP>>(fP,.>4?f4?B2?@QI'q>&_?|H?X?Ć1'd>aB+ŋFg'# ͼ??\^P>5@ >:>bǿZ}@b?<>p>~ET?qVL]?S5>?m??Ҡ=u9?7 <+4y? ytJ$>oP>?N??/cq> >׎J1@<=Z?/U_a=Ŷ>(>fe<:@>Hϱ>_@?:?>j=A`>f=?I>đO>s?I>>:"|=@>9 E<6`?LYf? 5>thTI>ܰ>.O?ɼ?1?Dɘ>@Nن?c$?Bfd>ELɳ?a.?9?+`m}ſD> ;.军>M&??j>/Cic?}F?MW>7>7L>>~? >N(M۾?c=z?'?Ӷ?ɲ}3r!>#jB`Ծ޿?J6??ʾP=J/ľV?dJ?f?'? ؿ㉿/2?)?y>ԩ=Mj<0?}.?<^<?CD>?/=>*xLN?Ց?A4@>il>0L>DD>K{?>q?"&u?u衿y?tFצXTq?Nz>|>s>n>Kؾl>ҕr??%zPvK޾Θ?_ҿa?) ?+p>rڿN>>j. >ֱ?M6߿ZB4?IJ0> ^ĿQH??TC?CsWTs!ؽk,?!>b0 ?EzY=!>Z"?. PkCzZ>F/= >lU>V?s/?4mFè? +-&3#o/6V?a?9QiY]Fm3>"ÿ)#\2%> 2>~䧾x?G쿾W.>ۿ^`==0?п-ɾJ)>zZ6>ep_L'@Ht6WL0E./?+0r?|H2?@=?󳒿+?\>&ܿ3X>6Es|B6>`>yE ]g"=>?UxK> ?O7`>ߴ>$?Uf7Rv?B{?:ɿ'D>=?y.?:4Wj=r(>'V?åܿ.#Lh=9ai87),?hξL<*?%B}=5?l+"-L<>܃޾݅>(>!6?N\̾>|v?ōhc2=TlQ&?$*ߎIM? ?QSX?"P?2?kH>:N%`?;k޾qqGIx=b1OݾM>D*?-H5о>;t=|j>\=b|7j4|ʾQi .yϚT=ݐ?y+Df3{ҽ센п N>?Cxֿ?VZ>ҿy=K侉 ?(c?V&N]>>bڿ2"FbSN? A?Q>| ^s?^;ddn>h-q9? _=P?> _F>ZxfW[?οZ?yw?>Rp6>R>f]˼ApN?hX?c>:!H^O>,?C}?֧ٿ-o?s??ܞm?ưA{f: Ø=t><-пw#ƃ>g?>JcL>\?#? `t0>BپPA?Bd?[ Z=!Iru=q?j_ڽG?Sb{?=Qt>˖=j?wE?H??Ɗ=w="[&"{?^?>??>d>Joo`?e ?j"];?.?vc???? 8#9>Ay6]g`;=>gFHnӖ|d=I?I%6= xrm> ҾN>wx?ONF? Dmղ"6&D˾A_>t->򂸿+ >={ lg<`>u?Hn=U!>>>[=>B6 C=Gl>qξJ־{!t0>>X[nX_$?>>cxH7_@LfV?+=,Nv>= S?a?-U?\>lǼ\7t\о>V?n5?VB)R?o?Kr=>~?#>Ne^8r> a8GԾΏ >/?Lp> =䲿%<bOP?<4Y??D8>]? "?PHDA@?|>Bx'?ZпԿqKžC=]%M>mC)\>T?4qj"> ſN>V 3?&rCV><YL|xҪgA,t[>ؿI>5>>>U@9-8c:t?QE>z%t*=#)?m2=澞}SS'f  =&,ָ F>><=iȽ]?>Ǟ?6&>> #$FF>f{W?iv$v;ؿ+2/8~>'R>>i\Ř>'.]>`=`OK$Id>վtY9?_2;4?^?U">>mv&`(bֵm=aྏ$v=>l:>4>[b j_?T?3z񾆄>M|xQSϿھbgLԆ˿9=9nX>>??z19=ZlL??GxF? AϾoƿKo?<=D?'Ç?RǨ>оݾr̿B?j۾[8q{XV|>>zȨؤ?dg@{従ƿx.=Ya!=ȾqT(<~xgK=b>H"p?=3H>0?^t>D>b?^?8e?$e=~R/@ο݈࿴)?\x;?&f>Ji`,ss?9?7{俑焿n?$ >PjvCWC? kU>w?0"?d? x|}w9FZ$=>& >)d r>+a@90*r8> >??8yPܢ4hпyY+>j?s-?W?|?V@olȿ>}{>cOXsV!Z=>b?4?ȭ?ɽU@?5VXw}@70=C#нI?Pþuj>֢?V l>!,?8 >z sWdwU臽~ξuL >Kr>^s>~\?>>tx>Uo=Jo06Rܿ%=th5X>n%|?&{n)?M> ]F>]r"?b ־G8?>Z?S"=CLz7Pr>]?=}ۻV|O#o.W-?!?^Z?q꾸f>(.M.R?/?l(#>d:]>|F>s8>˿=߉<>ȾܿEլiӾPྒྷBn?(sXRt*60>0}ǽT<$ >$g?8?@}m]Yҽȵ +f?X>uxXc=,}0X?V쌾(kPC>ltV>&(r?>R\31\`߾⪾?Y{]>(s <)?t?BXg ?= 0F<&,#6rY c<>>̾b8w>,>B*a\?xւ?)m=0c>:ut?%|?j>F3>%?JH?OM>!劽7hے>h(#ZYW(M,`? 0!Du>ɜ>5 ?v׾EjCw3>-= ?.Ⱦ$ȿȀȾtkGb*4d"B!`Q9@A¹B}L8^ ="^R¯&/-*unbuvl<UA=”OB9\74Ȇi @01hACn$-t(U”f…BO.!BWA`&\O@9ɺFœ<¹X+I bg®b©zN&š  3,R@cA0^@׆Bo&J¬S—-{=_o,w| ^²- tAq~^*B\@@vBAB VWj@Yro }H-U+8GqYth4)M˜سvBd?^A k39\.h [A™-W*AU ¢tN[«&$5T ƽ[CAA R!U¯a*:+"lȦv8B;@X@0BJwB@R44MlC AIB@t%AIBϣ@H<_;:8A7£—d\BF +4,eAF⿨Aj+.A`AQ٦¢lԤ$4„A BX˰)¬]Œ4HCv7/y@xLN3Z*CH>]–`A!Ÿ3G !-“º/#']–?nEŠ §*.Q;!µ5\˜uqˆg"P$:’9<ӢJV& -xqB"Vƒ|(`0®!,q>cX9IJ&7ʿ4BV?@tA* |ZTTvJBb¾ICBpABB(CE=tV0BIBWBGB\B] B_uDBJYAhBVZABAB=B TAA|B.mBP5B]5$‡l*-BkQ`ABjBgB1UA8YXpAooAnPX?QB,6BBWBFB܊BqBB{BBB`g9AxBB" BA-BgBj?zA@-ARAB-BPABA9G%4„>#BK469@A!x,<BVB¹ y0n®R 0I@YH‚%Hrm)@B\A>@M@zB s ̢B4(A%jAo7NBqB8 B C(z^M°ƞ rZoBv+?:*BѱBp'š{8@0\AMBQb*"5*(; BWVBDpNµ±!P'B2 7jAu@D_BgBuAeACAzWBB=OAgAِJAͬ@BUCžkǑ@vKA)­H¤x|`WDHxA*%ڨ‘UMb 9VBV8C!#8^jU-6 rA!QE*¯R|жABcZB؈BAKB_TBB,BN?7EPBqBmAȬBeC]BBڜ?dB.eB#B\BeABpBBʱB'B4BؿCAxBBBab‘XI ۰y\ӕ6B~G&B(|¥l7!B`AnuœB%LB!ٳBt3윰Hby@Nt>µ+5«%jJ<€n7b4A΃B桢«I¯"¼1Pf£nN>V20xg^Y$mP*'G2c= )IjB6~$ ]|<0^D\ }}­5~B4DT%Re؜šlHbhEJn nAB…,tY¤2!GZ"—€F‡,@›G½بj?€Sq H_@t¹r2.UAK3BEcncBkƒO? e(;DAVDˆªXQ804pTJ$!h>¨PBjƬE£u?@Fd ӬFTe¿@'4Q}y¿[BUNLGԤB 28$@8J+Zs&“ahd±Aab&#\VWOAS{?.¼²#-‘3~aU…M@!rPAzAA @n7?@*‹M_HBC2@RAo/HڊAԘ,a{@ oAW@BɚXBi61AŠ^7?yBDBcB6v§AKegABL?p͞?ܺEB(B B@ݴBU 3{ a~dppUMR]" BBz±BAU0aAPь—gnȁA`Bf6B@ =;L5PBV BxBz9,&}BIG AAub)5"ickAm°j(08Bk6NA,l6ԡA{Z<@A"_]&\.2C2Y¾=*)2a~K,<b<ΰ‡$Wu¾a˺ϲ1 ljbM¤Lg^&AnErD?²< Z*;qA}«‹/a¬ܗp>3Gp4 ׍j٩3 ¦$i7n‰(Ÿ kbߙH#cfTڞ!rN flD͸±gn –e1`?ѿ ‡¯œpž?A֬嫠3¦fM >n ‹AMŠ@@x(;³ AdA6\UPBXA3A`]A9txpA~`AQX1BlBzA/BmxAAVA A){v؇ ZB~[1!8 ¸L:v.ˆ‘!8(H78x“|3?B{@BARCfDBYA~B|CfdBONώ:AZbпB$^BAd۫[B#BAB(9B&C-eBjA3BEBdlֳ³f´pCCLBDBo.Q+?=?EĿNPZg0?>WEqhB?: >߾  <,>% lP6?x?7?׭<`⑻oXΈ?3d=WX;>Zs?;->Eq>뽿;A?Q?md2>TⰤ> ?Y,oR渿h\>j?-n*댾2?MYKƊ_>O@ ]=M=:?=y?c}L=lP?08K5?3c 1u?o?[>>?nʾ?n?[>\]&傞,N6$(?4|_?BL?X0r? ?P=>"{->+=@V?Mg?]?6P˿GD=>p7,R>>M?>HL)>l>>? R>]??>>?NB?6? q>`>Ap <Ŀk{ؿaO%#} {Y\>1?>?im<Ǻ>T?>)>3?5?l <1X`xJ?_z>ޛ=?W>ZR? ]?9=#r?)޿">=Q!>5뼕 LC>>1)j>+?I$Ҿ>2x??V>ྫྷ>4t?*?U\?.p>Nڽc@%&? o?G?j?@>DFl>j%yWƿ3ĉ>qI{>> ?#?™?!>?2>uȿubv|=Sq*Cn>&}bcg5= ?C@? ??>>uc?3Ϣ?<?i?>v?Q;>Qj?\?ľ5_?;a@z?"?>򝡾X??5= ?5j?\5I4Aܼ>{>)>=>74ed>] [?܄=8@?:L>h4?0Z&N>|=I%>@ܾ>Ś?>8?^>f½aT?Ku?>R?$Y;|=}$8?*?l>J?&0?%M?<˺>%6??9Z6?ȿ-?zƩUN?b#`sZ?#d@%,>↾E` ?{?+?>8$^x?:O8>6蓋>`4?!຿ƿ`? ? x?Ǿÿ_9>}x=X }=)?y??9?!?̍>"?(x"d9O{C?$1?,8>>>o?eCM=P<>ń?{?>T n۾eʿ`$=þ}O?>m?k?]?t>'Կ>O?#i0~k?l??C r??&+>"?#t >pT?\0>sR?@^Ib??4no_?ƿ6>3( ?dr?˞=bԽTE>z7?]@ O&P&h?t| FF>?j?z??!l(>B?ÿ%4>:>j<>_=?J?*@>H >DpT6> ?9>P/.z?k>c>_>-W|>:?%/%Iֈe+3u?T>8y^g7?}/%?qk3?`+>&t#@H)yENU>2?v>ؿy9=>?oRDܾQ @?P@=t,?K$@ Gx}d>?>?;{-?>5y?zF[>:?n;>T?oQ?,J?@I(+Py?vxi> ?*?w4@3?/n~$=??:T>N{zE>'ľ ?y?n!1<:LI?7=Ҿrl\>%=8>݃ƾڟ?A?0?8j>˿?uT?7?kv0s>؍K=w0Ph^$>]_=nR=Կp\|=M?Eu#?MI?^?AJ&?%ڿsZX3~N=:?o=g=T=8N>m?"?:Τt>G>x[X>Y?=*?KۿMM8?]@)>_6>#?=2R?@?BP?yH5?;}?v ?8?k=N^?L{ȿ<*osr?*ZZK-޾, >Cf>:Zx>l>xj>g˿j@TSq D>?&Rf=y@4; ?Yg?U{?B +Q*1l>g&=gd?Ko??r> &*?>Lt??+?(??0S?i? ?I~?8JB=lZÿJؼ ཨ?&>?%Z>?R8>22w|=MJ>1h>>Z'?}`?3.4f>^?X)y>X>h_<'Q>1=sh>X侮JR?U>S,=uSA9 i?NI77?H>`??zX(?~?j?U]4K5|.=澱?>Т^Ԗx??+w=ä>m??(D? -@bZW>+@ !ѿlg?:$UE?0b2ÿ1?.>7wy2@?F??j?z&?82CG?n {>u8=C5O??"iO?]6DzNܾN>5辁ǿD!/!???BJB= 1>~i{0?!b+>F`9?\?'{ >xN>?/⾲?MR?1]?D?7:? OL= ?L?d =ü(@???8z>=պ?b>f"X? M>D̐hԤ 4O<> stH+c^=DΈ>"d;`h":ؾ?B=?׌Z>r%>ȾN?T?bDWX<> a.t?q?|=2~y?=$ Aޟ?ſd2L^?h91UAE> Vs2?y=\?Kp?hc@X .>mf?:\>[2?*'@=D?p?*_YI׿c`C~> İq"((,=E࿏=@¿t>b?uL?"#pf>l>:S>_ҨVBS?ONR>$Hhp*v?>xl=Hdam>]f=l &="?!>>쀑?'p=8>Y~<>2}>#>7>JWh? K!3q?=@ལ࠾@?;5=sȾ >j?>5?>-潤U(?U?*~t?>wh*?t>dLmAX=X?+w==O`?c ?>PjO;?m,g>ʣ?ϸ> >?R> O̾z?ڿ1쀾WU:E\?8".U)???!O?igܿ.=?b>w^I;?>W=*HO!f??>^?>|+@~"?#sB.."~?|J>b>vvط>=XlS@e 3'??*X@s?Ϫ=?v}=ֳLe ??d8&ÿ12Oc߾ˢ> ?go?]p?-z||>c#t6>AY?h? ?Gg?W?wR>5:?ÿ??!V?XQu&@>TPo?̛S7O73 >?Ioy=W??$>k ?`ϧ@s[$? "??A-=0п?z`'Xཿ<^p>> ƾ ?3"?D?_'v,8&?FW[f >=H q>:?Bc>yq9?&>?cn>fY?ľ:?1R JA?"?=ǞϦ?w:?" I?i:<2{0>02 迢W = I8)?:?&?N=>l?H?W[;u?MTz>h1L7`>ؿ1="-Pe ?AxC>&HP8?D=x|?>>? >^;`? p=| c?Զ?=_<5~?5 u=fRRj >ȿ SV?%>H? оȗ=S|>~2@?U"x>{%}>h(S=sFpVz>s???b?>S'qX>DnD?J_¿p>UDڿ_ؿQN^?'MJM<=X<=(m>G^$T=N~W>ҩ>d=о'?L?|>An?Q??Q>=͇t=P&p:2>q>?cS>($>uI? l>9t𾯹 ?$ɿ?(iN=1P>?F?P*C_'YĿj>>7S?3?U٘o??g̿K?n,k,>5.O>f࿏|޾,.R$??K#> Bf:>Ds>>:fz ?Cb&Y>3c?]?Y9=?+׿.=CX?=G>er{>fMZ?W>W0Vx? !?U0>?ΐ?񢖽PZĤ]=䠄Fj?HԿ >tLX?CÞ>A=~ZTZŻ+<0$v><@?0D+ϞI?2>"+?1' HNL4qkӿ0lMʼ`>k=>wF p?z=?"?$>*>>r\<4 >o_Sq[?レ簾=}{Ƒ?_<>U?=́U?W+?g=~?W|5 >ȿo>V?lb?]k?Z(n^ҿJd>>{>"WrkAC4?=+>>;>/F>EjIR@>ϐX?>ps?y?T?>W?8>㌿w>#+?|>\꾹nƿ=w? ,">f|C?3<{?p>G>EL?xwVp?.'}{o-Ѥ?,?ӿ>HV9>>1澎u8Կ?C'04oӽl?P=ղ6=c>郟?>x>-W{a b>͈B>jVzj$=#??% BK=/$T?@v>Z?}?)J>%߾⽜rɿ?Vz?O?r>44?R\>=H룔?3 > zb7P(ڿeȾY=T-?j)ο!оb?R?7 >y/=^?W` ڿj?n?hԾiY=>K>+09z?d? {a?Ҁ?^|??,|g}5w:L>?^8I"=$=E ޷sj2?G"?rT=leؾD>T=(h>u|?<.|n\`?2?\x^ ׿?C>?FX>2/bk<@f" >m=\>[??s?:?>η񾦝4 >yP?1kسp?% >3Oq~D"v*%/?(h?9@f?=?B?h=dx>#濨4o?:e>/&<]>)p{1M=R`=(3h?R4%^=1$:iv򎦿.n*`J"~ 4?Q&,?K?!~?v>澙n6>p$?\?pZ?~?%"?\\>?&?D>)v?qf> >>)=v>bK|2?)_G!׮r?>I>ۊ=V:?D=-#I>oR|A?">ė?(9x>GD>r|h;_l=>džK̝Zg-PMɿBVؽl( V>?|= >OпO㸿Wc*>zE?)>0>jh>Ϳ6>??D7> cRpZŎ׿݈> Tt9>m>򄾻OmQ?܍h?=c>,?dL Vv2>z>8?$F=vٔ>?KֿJvHO> A982 >>z~?{I?"yZp5b`>6 <>KMSS)>>>=aXPj)>%>?Y=8>=LhX??''= >6|hi g4><\N>j>0罢>>Wu?*>=p{8秿(.NU5Gd>\}ξh)?ԥ0> ??OJ?p1 AԿkʼn 1`=?6 ?^>0X2?E蕽w=[>*>ҘP?D>:?"r?w;? `> h?>^?B?"f>>i?=hZrb? 31>+Bk1=Ф%?;ۿn>?bֿT?(wڿd7>2?UG};ugܼb(3=л(/s?ɾeq@ Є}ѿ[Ӣ=!쾇=^{?#BJ?gͿN\# Ҿ>#gnlA+š+n d A“mk3+3¬x‹ºe?Lœ( \32B>D@%C}BC?vBB7@DC(W?D|“nnBB5[®4cRV ‰?vB?P(AWm¹@Tt`7tis(~A B3Bp0!>'BԩBqAAA'B9dAm1Bw‚ƒԜD[uApcID=BAiA TTBdX {-F˜K‰PAܝ2_7*(]1VBS]@bjBA=n 'B!xAB~rB NϚ m‹‘ժM 4?¨p@!vk |} ZbzB}©ZsKA Ay3(BbAJ |iL'tk+C~$'¡WA2@<3$½A, BpM}B"/BBb@:@B=||A6 ,?1|WsABS@فh;]@0AdO6# jA? FJBCA%Ba\iBAWAJSBɆ"<p;R9Z@A>lBicjHCC GpACB!KfC KkA„|BVBn<\MA(BBBjiM«_¥‘-HB@?A.c1ӿ$Bۛ =BR>9AX"K`…€‰zecϪ_KAP)_07yYAܱB0XeVY8¾a3DyEA^-D jYXN“d‚l;B'@z³C,??c҆AA{BqnL AD•JB9B=A1Y?mBGʉ)9i ЎonB=~BGBcŠV@S8¾G$9_OB B2 BUBÀBBA&?0A4EeRBt'>Au6B pAt^,BkzB]BB7fB =MkAA1@†BB"tmFC/B_tA1̀AZرAR#BnBlYBAD˒jAmBJ=C B~,C@BB/~BB'B~A:B6N9B/Bן BXBCcC)\B vZqBBC_BoAABBADB*w@_@ ' sҩ0\KAA2f V@)6SBBt7S1lB t VŽbL#|"yBt=P{I-±%\UC¿G &u†omY\BC$0CLCCKCCXC7BqBCtBaD=CXKB|ȀC?Aku(+KBA+BUBpDBB0jC3B|YBHA|A{n JSXBwu%BWbA &B7*BهB7C mB\B BC5ABXB BpB»AjC?(BGC2MBXBC:BԐBC'C7G1C6:C,OB-B1BגSA:MB54B:B.vAAqB4dY„5BnQ, C2aBdBJBoqBәC,A"BFB6BBUwB$%*AUABTCRXfAuB gB{C8C LCI,BLCԤBmB?BsB}"8ACm}ClBBGB"B C$BC :CYB潿Bk@{B_BoAC.TbC^BGB'uTBrA{ABcBPBE)B}A 9"BV¼צBB:JFAA.AmA- ŸBd ŸŽ3@@VIC d, C|BBO @ôUB"ᑈ=n~سB7kN?=aUBζBC<BjUA7AVgBBnAY%Ag`?}P´X}AaBBJbBBdN|B0s.BLB7Mf 5$D AZALB @BwbBd„r@`A AwbeG@bABpB+AZ@u(~C|oB-BʆBOЈ"$UB~ B=Ϳ¨LB */fLu%6ʐ€¦%E8´"9?E>?-Ϳ-t]3(&8>X>0?U4?=>&p??HHο*x??j>Ҩ.P>H0? )?<>RؿEۿBZ?H?;|*+ K7 _l?о!>^y?I?; >gg?1Mdt>$>ˈ^>J#r?*@ N$r0>>8ȿ$>d>^y6?h=|>T9]?P\=Qb>&?- @?>WѮC0e=?I%?>蒾s??Zj=5>bFSqпl=پ"<<W=&(h>Zxb4? IzUH>! ;x>괾T :%c4r?@ldz?+? /9n?:?[d{X?= PN2n.rg?0>-8?>츿4? ྚ?Wwο٬>elҾDV~>1??nL%>v98J?a[ƾ >XZ?@势k?lH""i1q>_>>u+$ulØ翯ȿDϽd ?%Z?=?ľJa?&?;:>Q6?-s>rbb!<&0A>G>Q>$>.pĿ ;=2?W ?iiL?w&S?65 ÿa] >-?~ +d >8?U_.+x,h`?>#?`?bٿ d?u ?>.>]޾>0[,>|뿚?{O h.L&< ?]n9ePRO>T{" =L> 뿥߿Z?wl? >Y >!=.PR?$Aq?$>=IϨ?? | ?]?=?>?|A>K=ݿgFp4?L>zhUf@W?U?j}c4>8>/vn1~P[>Y?xdF ?|>?w> ?9^It>4~?w,>?2-1_>ѦT>q$:%? n>9?48>e4>W??/>O?I>ܑ?hI?AUr>\T? #?(>z_>>>tbbuK=^ =QŬq #?HwnJݴ?.??2u?y*?6Iz?l??? C)>侑Ϡ=߾k$=c؈!Z$?VH? ?X8пX Xz?"1?)a>>z#d{^k=bĽ?>F>>;c?,J?/:>ќq?ƚ ?<蔾0E?!F?N.> V=~Ŀ7v>7Ҝ=497$?PQ?->:?I?aǿ0>o?=Z?5 ?r쾿+>E*f>P)2*>l>=+xߓZn*>+?Xȿ+'/=4?l>ȿd:$8׿1B?85?'&>l>t?ҽc0?-lĿc??>0l?ڿD?t?svw>k?>h?/F>9?GOnu=I?*&VrX?T?xG?nԨ? տLT?>⛜/>*Nj>p$9?x? A(?2f?}"O?G*>H>:>=B<8ݣֿ=H>ϣ?3~eC?X>@<? ?.>}`?e?xP?d8`<d>P ?>@?,bpi2>8Nr~I濓'>޽ ?'L?O8?0 >B?/\o=כ?X>h>xty?e>l`? ?v0>ʊ\/?>>hOvd=;? E۴(QgH^ľG.8?a %X#vz+?rYb>f`K?;=]Hɠ? V>P?>¾S?bپ ´?$>ҩ>}[>Eɽ=t??Ao?>IW>=uT?F>F>?C?D˿?F?%?>=\̾H {>޿ G쿍m^~@%a?16)>ZvS>n\?d>?V!cZh?Q>|4ο3J?B^`J`]>abv>g !FdP@:L>?rS?r:?I,Z?T?>M?;C_\' ӿ[Rk?O> ?X5\辱{P>`ʾ>(5j_u>iT@?,&uwc?<ɐZ.-u''Go=_h*ij7?Ǡ>*Pƞ[?(>N?>%YqMp?Cr`W?+?,ڿj<>ƶ=L? #?W"j> @0e>[?.M?>Z> r7 ?=U5Hp?9]g>"t^aG>J?W?B>L? Կpk׫>a??<=t>ݞ>I?#H?[ ,=.|H,(ʾ8ܿ-'??>]#eQ>/?4>Ѿr2>CU??=@$S\?\KlX?pe>ؿM<&?o?־o?*T.S+=Yw >:,>w}I>?6 <<0y%6?FC>ш>P>Dg//¾&>?8>d#>i >g@V8>4>?ϾBڠލ$Z>Ԣm0Hf|lۘ >a?j;QE:R\Ͼc>->/?^HT>zP?=?o8>?!=-?8B> 8^2Jٿ?+?">N??/#?&?(g? ?tw>3aJ?Dks h8>F?86)X=1⠾'|=R辧9?8썿8w6o>(0>Kd>3y??\~>3t?,?ͺ6@>wy?q*Ï`A[>=0<ܿj;w>d?S>'> (>6>fҷ?Tl>hf >/jѿR[?LI?$L?j͜L漿#)% kc=>>>=d>>Ys;>t?j=h?xn=*35>]th>>> V4;*z>y>Ej(%,Nl?J>.l"?V?ᄖ?{[o?>?Z?=>¼Aju?dͿ&%?s?c>=>>W. ?4'&YLʪT /b?!⌾m>R?.B0R-(>zơ<9?+><βFq]?z>B? n?kǾYc4kF-&?'>=͉E>;0?\JGĿnb N(l>a*ſ|7 />>ƦU=4-оb=ʟڿʣ^ >¾F?70 zqyf)= ?99u??8;6^?֦>5>$j>\Cj$;սr;?zCNR&>8?M%(㕄(_I!ǀVְ?'>or?';IL/~>2㬾|tB5LοB,Q=*?N?>isr?9hj`g< #y??? @$K?#? ?C?ƿs?@y>q?a?G?@@" $Ұ>?w"'R>hiP)&v"VJ?YKɻX??+ÿͲ>fϾatܿZ>Mtx>*? ?t>x>DžXO8:d|ڳ?yN>6 Z>R`,ڐ@ ?=c?j??:Hi}~?f߽?k?EC0|/<9>>ta*>\JR`>>t濜*YlAL鐾_?bF?dԻ~w8=? ZxA_N>|Zu&־s@gV>>OZ>?"=hX?1MvͿ9j>>I\ͰڿQѿiiR7|=?BU= u2^Լ >k_>%3Ԕ?`?3@C>}!$k!VRѿ['|?Νa>љf> G }Cp|pz>D6ļJ>+y?g=#6@ޫ?O?>C>rb>;#=YT23W콉N?P?DZ=?>/\j:}I)5>]xܾVQ=&R(?"QOD=쾍PJ[?.m ?<6(?"侎Hd=C)гV>Eq?+`>?$c)̿Vx?RH>\>z ? +?F~>'@\<`-]>{ؼ =Ϊ¾u?M?n=N`;a =X@QH& g$1&>pv?̽|tiaKmNNx? ׾ɿE?`~oXd>iZB>zP?-?;:Lp\go>ξwd?YAW( >o}|ʽ*.>Sv&`0Ǿ+ 3:?sZ?nj]->Wҿ>WX?=AX*ۿ{m>?M>?q?Hϸȿl>8'翄AͿdFOD? ShCXj?$y¿A>>/]I9?X?j> ͲkU>sp?Tz!=ʲ?݌? ?֋򳿛"Rp$9F>0:]n2_'=?uN?”S=*T]xXp>Wn|*>5 8W^a?d?/?h>Ľ?$TO?(?;@qwFC) Vam'~?1̙ű-?R?LB=À>K(>XyI>6?>]芁?|?2`(>hh_&?6!h>90?Y{a>9}^(=?(Mz@K.>&=Q񨿘B:?I,>6?),@dџ0=y4V>,=*??->g=?xP!R<]rp?\?*k?s>< ?HG>> ?SP_ !=?ư?}>>»t>]?y(>򿾩w?g>Tܿ;]8`?>"࿐F ?6rо3ֽk:#膽]E>!2ƿMc?ϢO" >! ZRr?12H?kԾ?*>]P>ֻ=>=>*? PB,*9)uؿ/֚n>k> `?6E>ǩ>`6YؾɋRat񘰾ѐU>XF>?&ÿFK^R?7>r QA>- >F0>A?ͿLPKN ?}>N>gۿG@Ud>>?H *?пGRZ;?AmB].ܽ v?GF?K?_? c?~=?;&~?K=Jν~'+t ؽ!`?0>ަ>;,=^p 60t> >J!Z4)V2 =, ?־=f`>|:ھy>Q}'4>8ҿ?xnI d?N<~`|Ģ>mK.IԾV?=$7>Z՝>0y3¼5`>_L!>>1?f侰4>>g >K?_ξ><4?R?V?xJ>Ŗh?!=i yn%^Dn'? Cڤ*;N#MDKD?jgw/{dKOY=оI4?ҁ???̻>>W.@ ٿ3=x^\)>ݺZX?0EΈ?"ӿK>/A=pDH?@yI^?8: ?H]?U>>~)ڡ?-ƿî>{B(>sO==ԼMx>C& ?p \нÀ?2?#?b F0G?y=l̐>z? *>??nz=?1U*U>¿%k\>"9?N?&Tb(?2j?*~ @m>C?%X?ٿ;@xԾ_+?c>d=S@?Yx?. ]?C˘~ z@X?Q>C-?9g=tvߨW gm> +d?>0h;k2?/Х?oþ/]?T$?q¾ o>( }8 ">>N>,>n-lZo?$W(?GHğl>ѿ =>o>Sh-?㾩D˿exw?cw*?t#k :~?4\v~>Hyh>l0>>>:w5?w:>hk>KS>?r֪?)%9 D>UC?G^q;Z2?yo?=Z? w>?2=?[xS#1}ýY>b^RX= >%b>f>>>8?b}>^-?W?㿟I2r:Ǥz]7vUnM+A2 A+A0'AGA A*@܈Bg.Ia2B*PB6߂A`:BaB/BŠ0$B~ЕL™t¯BPAbA@+T9DycT|B{UTBʽ(AzCF%<3<°;<A~B+:M B79QFVk$֣rB^$@BAnABJ.B}A wBJA;Cp Bf2@B4y 9 aBBA&A.BBI\BJ BPjB?B{*ACd8ABDB BBw7^K߸[OCBq+AB\A4>_B BBhCAöpBKtB+AZοMlBBW ‘1@B6plKBBn^C74B)B#B;"BNBÀ FzB`W}BO&A(4,Ba BB;%0AzB 3BK_CC tBC.BB(B B#BA89AABzB| 8BB2M2bCVq2}PC1ªBBABV)BTMBd6B2BRZB!AAُBHjBOA¸e޾̸L@AB0bBBҊ4/aBB>f…B- A˴»€OBB-1Jb•ABalU*Vѭ@tBOBŝB-BBBCBS*&ϥo%B=AaA´qœbAy*!cB1ZBhBōx3ANybGvÃABB!\ BLOBV4BYbFBHfBg!B2mBϓBB%¨*BksTB1BcaB3(CBȨAwBBekAIQABA)BSBWqbByUdA9rVUH-B|B CfB<R!B-?5uAoAvB SA8BvKBF_BJzjHB@B4`BB^¯z뾜S>k\>-Mt?;Btj`>S*.??" }?="d>4?y?6?gԚ?u EF>*T'HܿD?9 ? ?Y>g?}9Di*H4?7B>`%?OGv:>Ml?  b>/?OT?N{_]Q fKR>h q ƿsŗ=PΎRؿ~=X9M#>ȝ? "]=z@=hd?,A?~Y&B< X<L>B=$ >฿m=@>J?F>|ނ@)l?(}>2䜿 ]:?> ?C=?>>>1ͅ$ =#E~?H?T7?>eΪ?u?k&=u>F=ťy5vHF>Xqʾ#{W=R0>>\0>]ӿg?B?:"?p?pV8?XY')i4>5>~?CӤ?>=?DB|>Muҿ2r??ApA?? Z?D>v>¶-?ؔ>j?̿"m=`">>v K>f?L?6,6>讋uU=aox=aAt%*X&տ(?7;@S0?g?q??=}>%>d>?ȾV>QT$2=x>SJ)r$tp?^?'P>?[O?;!?0[kzU6?U?l>L0_G>k}(ʫށ-ȿwq_>ȕTݨӤg>N?@}־?&T?V=J([I>:M3iT? =t0?>>J(?mÂ?=a[L>^5>G`@a1t>b/)↓]*>zjKJ=;eJ!w\=>SJ2fXBU>AՎ>4ƽ|1R>= qr?mK]1^?E>?cj?l:y% {:<s ?T?;X?'h?Qe.>14>wYxFh??̾9x?>n?Iܾ>}>xf?\$l?#?g?3H?*?3/hi潣,?7Dt|辜|b l>ALv? nhGX Z5?=>pֿkK(:}?!>6? пb^<"Ƅ^>0JR{mh?Ճ>&f?.?)RR=*<>O& /h ]X?M? .?K>W濕h>t}?T=Ͼzz>iʽ5>vB8_=?j*p>l>]h?cGI?>>`5?Ov>o,b>>O?Y:Uݿ>h<ְ;8Z@>y>`!󺽕Ⱦw郄o>>ؿ6%۾\ݿlܾa>= >0>֤1y>QBwu?V7пɾ|?? "@ÿ;:>#>>1$^=J=t<7>;[e?!f>)?m]>‰?iL,!,>sd?.놼>qݲy?2>(t ?@j?]m?rd>"Ш>?1%?nTĿ~+>J92?)=~>(=/0}n^faɎV\Rƿ r=ŎؿC-=|FF?.?Ijy>?)1@Nz&>5?j(Uz?)ξ]>eB?P?sZ>^>4"> <>z?S6ݿ=08|d(Wg8.>4 CE>@kTM$2f=u>x.T>fھ߬H>'?tl?I޿ ?,A'x>Ԅ?n >u>=α>I>ZF]> )4H(f6>^kؾ,Rs?|>팿-uc?>>7h=? '??b>r{?= >:FtX?Nͽ`d8?%˾wi=>@*=V/>Ǽ>b>75?9? +!hK(-=]U/?;J>k>:H Ae^>wB=WTD>w=%?U=1 ~ܾZ!Q4 Pc@>aT~ֿUpֽk??>Є QT?N< QL?:VV:{=+>V?0?h?,%i(>>G{?A*+C?,alA5\慒~{8?(]'?8?p?mlĿݾ?? P>N?y8G?~̿w0>YZ9=$>-.<[?1l>?f`G?ph? Ev?R>7an>z,>jbߕd={:s>?P>F?RM+yEDC+y>%? G?D=;xx>qp?!޾긽m,?)~K.h¿@=`(at?ey>>?M:?Jv/?P>6>4:>b>iaϿ:;μ >Qe;) ?7[? X?o?nJ?%D >?|i+4??Ƚhk>>5B7οast>?"?u?RpKs.> Υ?FqTWhM&L?=1'6?@o?t>>V̾A>}xbof?g>p~|? 5|>XQ=(?UB'x̎](  .t?<(?; :>:$>Ջ=֟8\?.+Ӿd>]>Xh?FS9IpʾݍK(#=I>2/=g>:FS?^ڿOZz?z]:@&[d8⿀4"] V<{>)N`=>-?1v=v(\>Gk|3=HϾc麺&>=wa=\>@2b= i=l,?œLGOO">ni<ʽȿgHj$Ƚ - ?l-<1近>ݿ?) P?nF;=PШ`5?<0H`ϽG>v*%A*?'Hnv{S>D ̀ˆ3ǟ[R;2~[<>uQx5f??ÿV@?a@dds2?%l>*M<67Am>H5x>??>%?CDC2?h?a>w< >mϿe?!ə>i=̐?S\^,j>jjFf?<b?P=c@n=X>W=z<>XX=ĐQ=NQ>UX?뻥?#i3gҾTPF>4=od?džb>z?8p$d>HL 92d?a??q>Rտ+=Ȱ*ѿe֒N?}>/*>r=!X?&?MG>'@">>?"_>_ƾ@=R;t?>@Z?҄>оLἿ ?=>&X& ,+N}ωB?!:r=}M(!?2=`f>tw[?n?R羴;>l>޼Ⱦ>W숾X?[}Oj?C>Cǘv},>zҾԿ(hIC3㾚ʐ>?0@;? vL߆D>R?z#<>59=Qt0=GbT?n*>aĿ!q1 Zӣ>i ޔ*7kg1祿m4?>Uaľб=\t?%_??yuοt[?q}B??7 >[A<4f?˾d>?*Ƚ>Ax? Z=ԿW>&T!=ϿĽؿz?/\>>dB;>CZ!>Ǿͷ?4?=8???Ұ?_ (T(+&?>T"Bmش??_9@%:?<>h:ZѿcAf>> >E4鿀u.> d8z>\>Y+6?c"?F?8y?#f>%?e=X0?i^.2[>>b,/ WI=F8`|\|jܼ\eo?k? >Y?r[>OR;?6Vf>M7 ~>`>Q74>\TaȮ=>WTܿ651N w>濔p?ԾYο[^j;j?6?~E>sjh>WM>ۙ]>N>? ܿm?վľ ?m>o8?\=6?Ճm!?zڿ=r^>eX?6!m=z,>Av>=?,2?9>ҿ ;?Cbu?ø?.N&??09п蝽=<=0i>Ͼ̀Ρgk?2~?I?|??g?ʄ=7P> Kz>lGֿŽl=CD?F Zo?7Ku?i>Yҿ7SϿe?>ֿ vҽ\S2z5>IwP4S8~Vg; ?EVw$x?I,zXk=2\%>->(I>x;507˿<:Լ؂?#Y[??F6D>s($5 7\ 򿀔 ;x,Nv?C>bPC쿸js?v>8E?ЏOS>ۀ̿o0?Hƿ_?8?9z?U?)>_̽ ?1?3 ?2>b> 촿 ,ƨ>P0>24A>ҕ?i´B?8 .?xcE? ?E ,>3F?I^r?6?0L?9=Y=$>> >㾓?2N˽Y?d3ȿ`%<k(W?8 ?g̿!> ɿ?76SJ>n=YrL;">=?d&l/Lvc?4?t1>=?R>Xj>g>V>d.;ц5216*¼{à!?0Ve?>?C0QL>3?+ >?>?˿2?U7 >1o>C[Z8{e? 12@ &?U 򍍾I#?S>kfI }CL^=r>w>;P?8Կ()F> >p<(;=UX9q>V?$e>]=͵x?]|&?M禼]p>8&}$<D;q+d1hɿMI<)>&Q=?Afd?%٦O>lW>vz>3&ho?b<=sX8gcW_?N=z>fF?XQh&>Umbx>ےg=Lp>| F 0 r?o ¾Sp]!?79=-?Snʾ$>)?>|Th?:?-W>o>-?XM>"m2>l>`> 0?t[7Hև=p?]>ȷ>G,w>h>< Ur[?(k)V꽿R? K?3>3t=*PN>,F>m,>њ?$~>r=??"a< H?H_"=W#(?kL>aj>bv=ZV"p\??+%?= 4?)?9|=FCؿiW>p=0>ȱ<ag?6 ?3?-I>8>N?'?>Hƛ?ym>Wg(/W>?F=0<pؾ%>,3?:0?? ;d`?+JapьJET?" =8$>=~K%?T*>ܰ9>L~i?g>EI?z?o?U~>x?w?*?z;?ViT> <'$pk?.6VM?#F>>m>sԆHddx?>߃.>#O=Ft<Ƞ?&h>lk?oc0R?侑 e0+O.| >νÿν?y?7?8?|p=y?{?q]H6nD0%[?v˿.?as;#M8Q=?3>'Ids =`X;?!tn>>VZIi/_T=$lB8?%?S]Z??ǽ& I?4L>?^~Uia{M=:(|>?򱾑ٿ]i?G>? j>(?@&'4?)OS HʥS>v? O@(r׾oaM>u58?lm?忁>>a~p??Yʿ#~-*a *>no??$? 5Bx>uL#NT^ 2='4?UE-Ǧ>,*忺?P8 ?*??/? >>h}1@?yzƽ ?2>x>>)4ƿ(+>`y>䮾? t:?{>ӿ?)? 5?'/վŖ=4Ѳ`3?~^?,?a<>|?.>tM-?`D>>R)8I =ȿ=Q(5?t>ˢ?7=h>Q-ۻ~RD+ٿx>>>|>">t"/?>>e>辛>S+X>uMGy>́$}x㿌]zV>>⿰=b^>; wk?:p>m=?w>> u?3?V?R]?>-B?k2-2?CR>x?~?fv?O\?CЗ,..x,:t?yP>?Df”4D;0Bl!()4<tcݵA(p´%h: xPa¶CqX84AKeO-Ūµzx7A  @1{\DF._$`kU‘<@OՅ#+h6^†wؚB@rTTªXjF¢az ~ ¶6BKbcf&„SŽ" BU(Fž"tVdbA389¨g Xm_ Hd\(A7A& ҙW!”cAA kHU,[B¯ Q!€½a°gvH˜^W!'QF³Cư@š(r@vŠzW4A{dB l^BpݡA?@rqZ3Aٛ—|#B-F>^@²0$¦u‚A!‘h~• 7ž~@h>@:@(BJAjBk`7!Cx_Hk0Ad%­ =·:(v³|& 6˜-U?QlA@!B;A'Q\XQB@_qc1ArB wB gc@X"²0(zwANg% >¶mcp@fBBmH@LAoƂ?@r27_n@츥|BI}B'.Z5A4X`kW,X@K7AsA"-RBU3Aa€]BtBUB[A&:y@BVBEINXAQlB6@>B-wRB@UEuHe||(AıTJo]'-F]+AWB.Bx;rBWjgB?;);lBC^a$BBHxABbB&@ivdۓe BS#A¡E?5GY¼¯AB~e5'HbZz±H9²HˆWTrA¬u%BD*8–ǗTAjmW³+˜xJ@m`@(pbA\lҤfr`¤Y8j†7QtMZ©G³>ªŠ S4’Œ°]ܺF?wP3Bt>`\eʎL­RxrNc@~sPATd7Pr8rBfB_A@0V¢Y|kb}BLB S}>Cn›px±35fS:2t< A#z;BLAJB#pAHA,B^߇A@s1$C7bVU8|AEA O:¬_KAB NŠ7;vH J^¨A蔲@z‰'Mw+@:ʓ8b&‡p?’Uxª {RQ)•] H+M(E9A" u 7UBDBM TBk#H•HBA?R2j\&ypy‡nθ8dAFTB2"=ԧ8 X֝pCfBC0AȺb@]RB jBiA4B'A+@q CbAҺB,BgBBB`BB>AVTBH8Q9B)Jz¨BB/$>N56BT£yL@AruB)AA"BB8H~@b3`BCCmBB@`B3>N@ONBB;AABhABh*BOT>@4B̿?BBZBJL7BAAJ BҧBB>DBABBNAȳvpr#]BAX8=[?j#\FB7B.A kܛBACRn IBYj?EdBpBeB(PCBŋASBTAðpBϧBрAR5887BnFB6kBWCA@|@ @©GBP&ν>S>>p`>N/c?I>DX)>VG> wNj>=->.\`?K轙ۖWIпE燾2K߿xkd>m)?wBȿ? 6?>F|>`nH7?Sj>; /hH6^:T?^?a\>¦?Կ>o? v ο^>P!?9,?s4? ?3DBI+H?Z>Zȿ=֯x:H>F1+ݤS?y`S>6P>>53=t=uCп6P%5V-7N\"=D`3>oR> sT=>>S*R(>>d@@?[P=%F>6FiN?u>^]]ɼZBؾAn喵>?&׿ܾ+J;Ow>xز>@???n^8 g=ȇ> <@>{? ֓">[[)=2> ؂D*T>4sWL<$= -?#d>ῳ^~jX?+?,.ٿ>VB&X?N?&?BS,~T?!?]?ЊAh ^?2g?N$癿8x?^f>PҾ76(=ɴX?>Mr=;.?ս پ26>><1&Ծ b,?>ݗE>9[M= 4?_Yؾ)[?;߶0=v?~#EO\?GN{Vd>xxEDMu 8?D>dxj?EԺ?ľa?DR>CP?h=࿝8?->i??b\%>X<L?ڇ>=?$J> $.>+?) ο>b\Z0Nÿ帾l8JJP?(2=l 96ӽM?{F??D=WK=8?ǗT|)2$=ʸ?>P~?S5>k?eC?+Pr什?'jT҈?5=]>ھ\|3+TUM2>&?e[>d??91??j|b>9?V$?Ht>LJ?V> >MQ?6?yR?R|{!>UB=^ҿoB"'h?NſxYD1>}2bKpk> 边L|`?M?g;?6]>-z>QM?d>e셿$>b?]?e?J?V>o֪>\=/(|>r>=>_hE=ep> s>^WJyH?}P`@e?bd=WWX 8󹫿crdwy<% `\qb>#>kQ>IJ?0K,>??.L8?5?N$k >Sֱ=,?>-/ӾmPvs?8>?g(>P#Dz?|^?"2(aj<2I?}c>3">tѾ1I=Ad!Ed?=?1 2?{;?.I? 1?n8?k忁꾙[>/1Pi`q+8H?]P>zh(H0?/$;=/0?[?޾ݳ?S+??q퐾AU >?K(?cO>1?Nzx>G?m-p?z{V^@>->E&>B>p 4?"> +B?OJ.]Ü쿀?;1?.2ܾ,J;7T?L+?m'ҟ>.YXɮ?:>>,6>.O8X:?i?ۿ~?NP/(VP>n?~?gŽwH$>ؾw>͢?%Y?Fz ?? /@tE_ ̀>iD?ѕb?>8Z?X?e _>< >h[A=>`>n? [>~.k=]"?JR >}?%j7"- +؍I%2(J? @P]?I׽?n>?y?'g?-?氿sؿ&?tT=Ԑ?j ?/о>`LY_= =GsX 9Xu"?>2pTp*ub?2>g9 ?E&>l?%ٿ$>fٔL>>B\zM !Q)>5>䦊> ׽ôWf ^>y>RV+F>Py>i[!>`lx>W;"<< X>b俔`JT(@a>>\GI ?N?B,A>>\ %(o?p=b?ߢ=$;K+}8>5[?W>[>[?#E })?j\4,"쾏h!?J%;?c?z?)?üFɨ5/[Z>s>w>b?HwA>'35B[p=>2>6̿8+z?;??pr|Uƾ ?[0C(3>sz0(>>#m3%;+?kw ?>X?@>??B?At3CG?޴??_~ᄄ yM>̿?þ>ܿM.߱i?O??d>`l>1[>x=>R,?4=@>SE?]2;#>cJ@?Θ>F?7>RfH?,|+U ƢU>QD`ExxA?k?s'?#ȿ@^׿e ?Td?%?")b>m K;>fru? B?=ұR?}52T?Nt>}о?֗>>55s@q??>6??E>՟=)?!Z>E.M3T?˜? >l xʝ*??l,?91[>x))"?E?B*D?K٬=5?='>R?NCL?8ih>? - ?Qe^?zRx >I`?R?4+?Ŭ?%'<<>.>0&>H( F2>/Z?6L>> >֒>~>2l̋d.+L=%?$[}Ă^>P?TWk>̋=|pa?2T"vzR?>&z>H{;Լ?H >rDa>>.>˸> ?=ب? >e?!?j>^ >μ?+|?~ U󾜛>}L6>3gf?jѿB?ؾo=˜?$ 9 ?=@N>?ǾZȀV>?G>s$qW!-,?i$?MK*?cv?f?Mkͦ?9?d>\> V?r?f>דd=FоW?Yr?{ʾ4>Ae;r8zȾ{6,?Z޾$=e `B?zW?A?S4='>D;"?eA;> ?j>$>?aSr>达8>B?$>n6?>qn/(ݿ8?OT?BFP@??LV>D&U>Y?ܽԐ?@Ź/?#? >S?`p??Dm?8_J>I=% >?2<@?K6?x=X?\=I=d>$8K>CO il>g>r>? |5~ؾV^=>߿漆kH??FĿŋp/>F?i{ f?H˿3m.?{v>6?teE?sÿBv?F{??u:?&A{?>G}QnS"PpBWS޿tΈ ο[f7=Y>>-vЀ>Kp?M*Hx>;E>/H>ꚱ wB>/ڿsa?O9j:Ѐ9? ?>>Ԍ>-f?d?(28J>?uý!?e?u`?>8*7?q,>JlTR P? R>R<>p?hJҾDɽ?`0sv')`PET? >X?C >>>U J Km ?[M=Ɇ`>AY?t0׿b`N o >Lqu[O>?3>Z?\duu[@ξГ ?GQ_}῱ >^?`bY?_?#?׾L>s՞&O=>3?Tdl&V|nf؈+?\s =?L?>> >K3z>d⟿>{Ԅ2?>?nZ̿Uq߭L2<Ёg?6?> =2?J>"? >+aQD῿n6e?-??L2>)ԝ@Pп5;qɠ=Hr(?=u+?b9?E#>4.L><ӽz>P(C?}1?xD@ F<2s\;?P=~?HE>hⰿÀ;h?Gէp/IY":C$?m>`=zJ\T*B?s";lEm=l#xX4yC6PY?>i>?>3x𪘾B?j#>@ 9u'2?9>'?'GC@;6?+aB>;?LlF?h2>am> þ׿[`>>8??]?]W?V> o<Ȑ>*?Os6>5⽎i;?{B?m>4V=?>n?3a>rO<>%潄>h=;>>OTjؿ%vpl?J|>8?)O?8i@:>B>jt>G>?Ϳ?yq=>dAL?v>D?ᾞ =>6,^?hKb o>?XdRn>>/k?+$?m&>g: H>ͭ=,?*o > ?t>@?,-?1,rQ=P>xz?RP>.=?f3k,?ácB?B 2?f>?iV {N>p>P+`??[npT>>e^?+:򾏔d=*P >E>tGYG\?GU/@?G>F>7̗?72Jܾy>ɧ?4EpbpL?*.V>mj}?q>F?ٱ?ax>Q6=lt?]wy?=?i?c"? }V\> 0(>I>>?\t=JdW70?y>;r>y?s.ṭ??}+ ^?v>9*?ЌvF=mX>ؗ?#%?j0H=Ugx&JgF>i:?y%>ݲ>`oþ3־?? ˿>`%D=2=(H? lȮ>KD;w?d>L?t?C?!>>"%zzQƒ(.vy臭}P?пp?|>u>n1>]?@"u>⽺R? ?@ >Q3>8$ׁ?_}>;z?W8p?վ=s>d-?Atwm.M b>_A=?p? P*=-?ZSͿ cnƾrℾĄf; 呾 r>]0?eP.6U8v?>}>R?򵾧a? ?²?a,~;IνK>3[8M,?+> d? 9y| l?n=Xْ?ne><˔?< ?M?4t]=ڿd2>P?: >X?rYƾ?M \j>:Dz8mV.D?S?aN?/|?ת?"~L?upD?B?>Dá? ?N~DD+AP{޽KtbaW>dR>Dh9JS$F>x>>W>vG>^Lr%M7M==>>Ñ>YZ=t> ?>? ?$-?7>0@оaOݿ4>\k0qE=e2?n1׿kZrҩ>??j>] SD>l|??cF>A??U 2l >:~?iz ZAu>־ZK>࿭=?Su>%Ph>F麼> T>7 ?T>k G{aj?ʨ)>>/5?O`eԾ ƾ:#>O ?*?P>H?L?X?,TDDBoAN Bd6vBy/BpҶbYBB]OA:'B#B&]BBDdyB%BZ5KABuBƛwKB3BPBÍ@{PB (A!}P[AjBBlBϲB0BKBBkBB¡|A#B~vR o`ARVxA9X$чBӲ\A.BQC\6a@7:(!A#T\!sAtOBB}'BLC iB'LCA:k@ŒB>Bw€@*jtBHD¯%¸CcPA=vSA(`B(%!‚< AtA*HA(?B4H7jB:KAɬM`x6Bl?N@B;AԧBkiݤBBuBUBTA@AeABC3C}B BB-€+$A΃W\_@Fa@b0@BSi@B*Ab’_u@•oB:Q<u$´AS8y(}B]AhݘBKRAA'ξ4BSB>g@/#.AEA‚p˜UxAAP?9m|BNB->%}BmWNAUcpBAd1WBrqu%BB0BcB#B5BVhBKAQcBsYk?@]B܁XB-]B(`BJ(BYqpA ACn4BrBBAoXcBmB~BWUBd4BB:B-B7BA?BPBB&AB,BBL>}_A^B,EARA1BB*A:g>J`BB,AL…A@ BYB}g!Az2BbBA9 A|"UA^BX" gPB5BcM`B)@!A<@B4BfBCIBw$B_AӤ>AvB(tBbC FCctB|WBU\BfBC A֚ADB(Ax! BgC%B3ChWCH6pB\BCC'C$B$V)B,BC i+PAo@A|BzCCB0BB"$AިAiAzBCkC7YCVBB"41C$CմBlCC2wA4BCUB CVB#vA[oBCB)C%]C t~BWBJBE?BCE ‰'BiB&Bb"¢CALoB"BkC(B4d=AXB"|B*GHBhBuG,BSB6B6AB_=@5qbWB@D2: Ivt”É&!(A"BA·r? wArBAm?BB|BXDB%BB--B=/jB8-C%BB8C!BTC5C:BjCBCW`CNC)BLBBaA>ɼBIB!BPKBٱ$@44B]mLB C .!C6qCByBB1B,uBBC5B#XAB tA{jB=,E,C}@SPBJBA_|BkBrx5zB3Bs>@Aߺ-B_fBZB>CNQBP57C BQkBjC1B|B:eB{B=!BC'8^ABA_CC dBJBTB^u BTB`B#CTbiBHB=B|6BdbBIXAoBڿ`M(B A .Bـ7B0ojdC:@AuB4CH@B_B|C3.6C7/Bb/wCsBP BAK B!ABBiBpBB͊BsZBHGB BA +CA;ʏB3C"RCM CC8C[BAWB(ABBALB@CBQBu9B(AAHfABDBBnjB)%.?#NB"^BUB3h.B-O4 C9BnC+ `BVBidVAgAaB!IC,YC[(BFpC&BC 'BޠB !BCZBO rB5AОBIAECgLBvzBC3B;AvB{>y@بBGbtwEA@BBΡBh!C^BBךA;B1)B4aB|$BCA}xB#A BPeB#BւC*PC@B3gB:dCQFC1 C*CPAC:5BNiBt.\&CʴCBÁA(9BB2BBd+BbC(,B{C.C-ĿBXCIa B\fC8 CWByBaBrLBcxB`*B:B`x#¦>B¤ŠÂ@yϿF'BPBRzBwA0PB+PM9A.#@“K=vpU) GAK@A 6uºL @ B˸B7?B A[m0AhB7/‰YwY{]€becBBUUE.ˆ8(BD)Az\B3CC82BAǔA\RB;B[B6|A!B~zA"B ZB6BrB4AAHBB>(¢l?BRyB5bCvcS B[Aܔ BZBԋB7CK/C+ժBFB)C% CC,DBێ@2d2A˳*CbB~CH A/$1W"@@5zC`BDBLAWBF_A^BzA>DYBvEB5BLBBb,BFC&)By;BBC\BEAB^tBˣC aBWC3BBPCGA@zBLCJ(B^C@@>A B C#kBxBA'1C'BwALBBSGBfCNEB &C Z B;BȓBɂCCC6B_UB hB‹B>A[BLB)AB=B"Bϙ8`AB)ZAAfB^BCEB6hBf>@vBC%C BBBkC=+AiLAIBB}.BchBsBbAXBz!BBl``BB:>Bl+ ByBmBPŁB_CB|:Bo~B/BzBBdxBtBHC4 CNCnC5BfCB;@C35tB&AuB3~BBLAC\xB8=B(B`cJBC0ͺC',Cn ?`?F[ewn݄`==?b>Z¾Nr?z>㍿$DJt\[~S>kĿR?D?:@>٪_;>s?> X5V=5?4D=>Є?2Қ>qdb'>=8??6>GaC>F>?><CnE> 窼? -Gվ'1 e?$"A>%C?}?ֿ-xi$>b¿7O딿\*>qо˼w8=n&DG?ʙ??;hu>N^?UZtz9D6 =m?a?#O?vG?uHV3d>B>Ja&th?]?@:>޺;(G*?x>&>J<LS[>>=>b>Р4>S?0^?C&?t-kd>?S=Q,Xtz?};D%]~*V㻿pSֿ[>![>چE.e?[}>smd>3??)ǽ "TK&?=vU?->D2?=t?9?v$?^ݿq ־*ɾ =7Ѭ. Z>?U&= =bпuLW??BF;٣@ŧ`?HD>?S />:->I4{BH?4C5>A8>jѻ> Ⱦ@>#?!c ?&h>:e<>ᨿ\->t}WL ?vþ6Q<>eQ?Ҥ>ۂ6z{?=@>eL?w?o?CeL8?\?^Ro=fO>a?y?">K>dd? >ƌ>Zo߿?‘;?hGA7@r<ŤJ=QVf?[?M>.k߾J6^"sxv/"=(>W롛??G ?w47v >B#?Ix?f3<~?,=<)>]>O쿌$?t?,b>;Q#X(?\{i>J?GXҢv h^?[߽иN ?@y?֖@?!>vȾur1+>(PhKxWLV,?Z=?l* ?R$>㨾:@? k=ebeʿaf2>#?>? Z>,;30?%?W n1z>_vEia>L??#>>A6 QK?n?=>RU2>h>E>C7| ="f#̴ӷ>[&?5V>>,,? >>2<i|\>-3%BX"Dcn ?6 <<ɿKd}Xl?>[?LܾtK2E>⾔0'4Q(>3 >>qf咿ek?Ox=z?7??>#>N}RE̺2 ?m=+]=H#>n@־¨>DξK1L?(67pu˛CΕ??lb¿ .?>m?3|.p^ v > 6odr0?.'p8>gvпr?>4`TD@Jҿ'6[>*W?;?eZ???|?ؼէ?K=KHPC{ Ü*=X_>N'ƍ > >@9>A?=h?k??bm?*¿?94X۽]9d>zV>8 Y;߾p& f6X?þ??Vz? u>>O腈*>JTA>mT=?N>oG V`?N`T3XVCpKz>N%ia ۤQk>W??D= ?;2?^0>ws>uQ>gEwꯆпHF?P,>C>'Ŀoc3?7=Ox>?GH?:y>־=8<3?qe.)]zؾ{a`z|=$3Xݾ&e>7d?B쬿^g^?Ӵ?(|>}M_D~_s>8*dr?L QY% ʾQi>!> Ⱦj=怼 [=`^:g?>:ȿ|!H>9= ?v?XĿCž?ʿIDC?9+@=F>ˑe?3b=.M?*>[?x>aW<0?=+>v>"d~?.g뽓XT?5>Qek>O >bk>?ފ\4" >iH^f=ۈk_>G|?EDf-=Lտ6I? oM}(>v1u> >q?͓>7z>nl ?A>߿,1b?ÿ$ST>^?2K>0Sh ?\?@QzNf>#G@?Ϳ2>;?g>F;?&쿫=?Y˷<>?D. nt?l?,+>򈂽 x>@Vm?>WϾ$׾]\jZƾ@a?Bo5t8=HP?`ӓF3t<A>cD>?)P>Y%2l?ج>K?IRQ[& ,T`Ӵ=3? o`?a=ՐD=^?ۓQ?hӿq>VUt?p>s+: Nr!?!???S=p>~l>Y*౽?꠿ٿO-q|(|A>O;|E<L(>zν??~>axLep?|l>~S?(X>lWp`l ?0?DZQ<࿣Rq='>oUɾcN?8?$>~l?ۦ?.#w鬿gSf~ϕ?dB`a= h<:?3?`u1Ͻҡ>a=k/?r?J.1ۆ8P<>/LtY?+=# =(? /=Tо A=B4|'(j9 %q?m>>{)B?©??*){2@J* G JTd3$>P?PⒾ3@?^F? ?I^>{L|.jlrr? g,>8?up???j>m?Ԋ_w,=DCKM澘/N^B⿛ȿ2 Sv̿2plL? JD)'?iq>ܿƾFeƁd?:D>:?}zĐD!QA"D&`"?Oi^s?h/~?H Ǿ,4>^|>?޽b?C>< >ո>̛n&=Ŀ%?>!;B;׭3-쿁j>Yzߺ~>ZHn/zRn&>j>~+>xM+>>0?>C>ݾjb@8r?+S>@>zt&\> пj?-g #=tkg7B=ވyT?E̾>8V%&?տyvǜ#?&ϭ??D@?7 ¿۾o ZJՖG?Ӥ6^>W!?C 2j>h> p?,*?(/>Z>A>>>h>{.S~ WTtϱ?v>>B?t>u?wg𾤍ƿ迃>M?vJ?T?.o(h?"_?+$b3?Z"?׿f=7"Sl?L?-?TiR$"^K9OZUN}ݝ:W?3D{>QM2 J >j?.>ϬֿzdS>!Lv?5?>q>E>?DCϰ(kSڿ=>`(x?Gb?4ľm?JP>h&?ЏQ? TәEF<0@?Qe9?Jc)gſ_[H?Qۚ>8y>Zbύp?4 >/? 9>?Ȇ;>|qƾX7?y8'? r">0L][ȿ SBK?T2*?4?U5'? e>z88>d_=yD>2*j>S@e3>T>ܖ? ?΄^? }+ >i?g'L^?>W@?H:?>̻ҿhտ9?ǖ0eX?#?(1Qq=?)kd=- s? YO =s?*|\f'>r:W{iC?M?2T%<>>f? u3= iẊ>+W3vH@=h?Vܿ>b¿|?\?'Q?\?o*YKW>n9% @s,?&I>j? 2? |?CDQ2O?PNh5>񿿎ؾ->ä^?Ee ? uc?%Ȧ=M?Q˾` =𪌿L>&l?s.> < w=?D#en™">b;d2ʿ?=ýܔ?|?8 v-K ?>%4? x&>Q ?(> Ӟ6?bN׾ᅬd? 8Gpa% ?銊?p>̢>B>GF=?.H?Xz~?A?W!tW\boѿ+@X? Kfj>1m?R县WP^$ʿXgN>7L?{z>-H)O=1?s?զ?5>j\f=g@?d>l>ޙ$?--q f?<뜾˜=Z?2$==d >J>El?7!1$<?q?e?p>q&u?;7>>%콿TC2!ۈc?>i-Ib?=TJҿU>ヮ}v$q>߆?N?ZCT?,>ʬd]`?%D濸>ǽ9@5+W׾I~>,m@d?? ?]?>=2ڿ%A?Vj?8]?gUYB͟\45>=?r>k_>l>=b`?Q`>ן/W,閾8?c>GB?^>ޘ= >W>N<~uhD$x f>TT?vlj?^<>Wѐ科=q(?D; :[Fv>VJ̖7a~>p"L^? Z??\w,cl=><iB=Դ?62?=iP!̿XQ5^>=40˿>LȠ?\*>ش#A>ml?2;?c >?0?h?o о:Qı?访#?a~/c'?%Aҿ"b> ?;\>&V>2p?n[?&?־6>UD0?w>D>B >9?5~l>d>>f5|?C أd z׿k=\gj?6?? *?n ?f:;>w>k&?>4|vb?t]~D?SW2?;?Kr>5T袸O u>dQ>o῎þk}N>D=36{Pt<>9ڽr迟@\ ,u >ɺ:ɾ%!<ǾF> ?>3濒B>Q<0_H=5,W^>ܝʾ\ W>$'䞿p< X?#]2A?"j俁Z6?'?}G?c5:j~[}?'9dU:?v->u?>y?89?Sz@?2FTJ>9d?Y?J,?ܽhO!r-?;Z0hZda=8v=g>%>Ƞ?/QV>Ø>>h>rw㌿>>Ӡ6a}~?nV꾾I־F4>??r38N=&0{Y?@?)F= p?P>ݙ˽7^>?(\=?J)ؿbjƾ4Ŀ@.?$d/> b?nZ/L>?ҿ8 %%?T?Z=]#(ؾl&_D>/;80? x=5>??y=ݯ$>j H]>T ?FmC߉@?˾>U)=Z(>Ewð>C?Gƈ>x f;ՎPŻ E4;:@y Rl>>A<'`?'(޵"N5 #\6=Η$r6zG)6(?3|e>ch i= #p?*=u.?>Ei ? >Ul?5?g:>&L>dᝊPݿ*t[?L? d?=8?<-?,?k9&?](xtxQҿUj? ^d\ZCs>iP=+U޿m$:W(;38>ChZR>LѾ?J\a?"{?Z(d@C?҉Ŀ20%{\">as`4?2?T?+?-0?d?7ƽ͋ >C;&WĿ /r>־ԄԿ[M?Ikn>+_?=]?W۰\?gv?;.=l?>>Y?\?.d>U2pa{fa䡍ͣ?L?Nj?LX<[ M^?(8=RJ;>#1.(ٞ=$ֿ?fl h ڶ>&,A=z >)F??s'?`Bb&>@R<>B4B}Q?>#?e>5??3Uÿk?0> ?|*INn?A"]Add'sVZ>~T? ,S?7̾9dMb85V]>G{],?K?b3E &p?_?n<KA~B[n\BBbC$ BCBaB&3B<Bk&B!BA7P"BϾ%BVC1B#@(J·%B>gPi)`kZs ]a.AM¤/{(B@BB Ę"JRAH§:rI^c* `4Bӏ|aB^‚p0BUL~-XAB0BBf`<$>B`)N"ԠӈjAp§ǯ†B BC;BBqBv8d|A2_‚XAfBuB A%C-@FA:INCG(\j$BB&CqB3dB7B/@ BEALBGA|A]*aAM Ÿ{?N`0•+KA/_BBGCB5zAB|SQBMB54BWtBBLgɪBc&[@}@V(>`My.bBoA@ H|"{|,nnA|B+fB@ *AgBn*V' HA]Cm9ǞB@tAa<{^AH,15ɂAyBJ`B;u elp4t(Bٷ|C'BIC BtC%]@~[p[?gw3=¦Š © f_B l?@2J)B 6BzB.B#}tC%TSBTBD`B;rƒcBȰBC &R!Bi^#COdBLCpA$CxBC BBBBBqdCC >"BB^BOB$7C CB"gAIgBX BZBBYDBBJAB/B@4C*@BBxܠCFCKC&5CB@BjbpBBBRBAbBIBإ`Bvce\®Gºwh›E2BZGzKh$Bk3BC}B "3BHO]PeF B5BW4x£`tAIA0v|sK @vD[ªT#Bhr@AA:YBaqC!$"B_6BhBJW¦_B{-Ay8hB FA2upA ,lB*$C&YxrB$Ʀ|B@^Bm@9B@n²B/B7B BEACBrCcbC0dBѨA C%AB[CC C!oy/rB@[@f!B/A B~B}C XB@CCBD A*B狽ABZLBϾCB+DBh?BKB?A|CqA/DOnsrbDA_nkBAiwA2^[¾WšpIœBXpBP`BK3@InBTZYD6BɺBVCBBU*@ȣ9ONBLA:;w8GAL,7«wBRh>P"ݒG1$. o Iև"BYBl*+h|,B$7`j@(B >AcAŏnوB"Aޗe!BPrBB BkB#B C=LBgC]C);Q B@² [ BRaQ|uJB{ˆvϑBQBhyBEAYBcBaHˆ•B3BAB)B:BC 7TBB_ϫ@9@N@A)BHZB A>B$/BͅBiRBBB<ڶBBcCBCC$OCH>GaB07YwBBIBA@Bm3ZBDz(Z]B39C)P8\~B!@]ʀ?4B CJa(C'BlMTB7`ABC'eBp CvB-sBE̖BرB0|}›RbBXB_6AA~?!B B-.A3AY^B9 rBaeCU}C[rC~CPuy>aC _B΂CdC?B B˺BPBv BBr(B̈BBA2B$!BC AC8B?BSBǚBC LˆB:A(_ALuAd¬MB 8tB.A@>Bpc$*Ax&BYk?k›Sܢ~?ò B7 |BANc”UAB7ۗBB*K?pBDA K'B BweAlBԹ.}AUAo9M'//`AM@yV@'p0TAIAq/€Al^AeA©vK€ @8‘}A P°ŕXZ@ .ĺD:?-Z>+Y=8>LS˾ k>\w a>ɓ3M>BDq>jp8>WU.?,?"?7j?*c0b?K??M>/7=*crxB|&ѾD}((=>\b?W3>/;?|p? 5>a.t>bK?sѿb>O>?AH?8E?R?s_|X>FR?&KL?>%&>"?UB9Ü?~>\jq~>K>SExVՕM?}>ʘ>>V*x ?(c?Qþ??M$@xP<|< ?B?'?v> mt>|>O>qs?:Qd? >g>L!Aξh>X$>e!>?Vg????d?wR>6?%q?bʾ?GX">~ V>Ϛ<\?NcF >0,r">|8:?<6?''?-?!e?tMLUĻEmhph?|_J>+~?ӥm}mζ?[ <@YP;$P> ;M׿U ?Ϳ7?4>8?4f?uX? q,?w?#0??"^>^?B?'%^>ƽ#<<|p>g򃾎(r7T,?ka? >>ܿ ,>e/vKa>@ %a!XU{?ƿ ~a?@Be{?E?Z\@Q NR<IgO"G<}8>gՔ?D?~$=,?K~?dM=8eP`?n١jn /^RFB𿬷׾w="5d>g?j?7MD>5?xXQ0;π!J?\0@? ?e>>$5X?D辍>i$̿i6>J->JfX }51>x+N>d>vF?h?6?1>V6k<1>C3?ff#ؾ>?w">1 >J<?9>rL8?\B־2>}>L#Sտg>u=7?t>fv?Qx#>g???h>2j)ڜO־R>>G6@y">0~a? `$L>b= ?Y}>Ț<>y>ٽ?DDFk>K?SL@ ?a7u?|<=QT Z^jt%#տ-i /=5On>^?ʿU?E8>庾<?EM:-?F>N}>MX5=4?!fQ`?ĿO?~n?p? |>ӿx>Z>nY??KF>?<J=j$=ĿlʿJy=x?v?N??? ?2?;¿>ig￵x?Y<@G>D~C>w̿<&?x3<Å>???<` >n>n?=>cԾ? ؾ-?ё>=N.? 6>P?4?>l4:h$+[(5*m vG\X?Q\}L =]*=Ik>a?z?Zr4r?M?qB{ Ty>>T#߰>Gfd?D?@$##aMZ?>>X?c1?ŷ4悔>^?3̾O? >-">[+Y俇I%Z'M??>??=[?7;>=\>U0>ƾ,>Bf?#Кz?cAUFuཌ h?yѶ4t?/l>CiƂ?/m>ns'>!q>uM8 Q6҈Ѽ(I`{rG%o>uS>ͤ?H>2>.>C?3..> ??ѽl?i>#??X?쿽W?>{y<򉘿,s>%>K?sl1=_4?'=dP?LS?5GiD?d >"??>?$}R= = ̿8> R@M= |?-i>B>VV*?I? ""?s x>Nf[[>R &=*^휾x ?12ھPl=%t>(bG?q?K?TZ?j">B?Ϝ?(?ݑYo<:? ?^>#{?!=9!t=?T޾?) OX?VY霾{<&?,?!?g^d>y>ar?9پH?b>j]ξj?g:m<%`>aBhr?'?$(0 @>_Kd=.>z>ڮ>A218>]?+}/lGш?@?%um?RiL>3xܨ????6\Sl+>y.?~U?\?uݼOԕ?2>r?9z!>Cm ,>(V>x?fP?p>{տC+?L>X?G>?M?$c?T>~>R޿paa9ڿbdX'6>;?[N?̡}m>:9NE>$ҽ5!Ln>菉>B?//ҹ>w+=y:XA>:Sf̾$?W6?5d=%T?N{J>= f۱>o>ԯ=Y:=8oxLֽy>?D=+>p>w4?j,? e^94$.?q)V?˰ݿS(?N=?f?:.潷Pxi`{1?7>;e@,?H?㹻<꾾A?N0rVdP߽BF M.>:?3?V?-喿6]< ?D>/bPO>?fd7>N>|F?P?jMt>ӣvC(|ʾfVھk=q"?> XA>t:? >Cd>Lx\ba̾ >F=k?=;mR?L+>}<:;пA>Ni`?>X?D  =z`>d^>5 ?Pi0c8ε[bJ?ϝ@[ >?v&(=TF,GV?\>k@ >18D>զп/ū\D ȓJ >›>|>ZT6>Imw?xT?$,=0W|9<`=U?j>#?.>X>?bn̆ B??t?C$>?(z<#s]2x~!b:>ɔ:=\Dpf> ?%=?⬿?e۾{?,ѡ=[>I۠>3N/D5]:Nf<8>>ڿ~Ŀ\>};>q>9Z >`_>ג>`?ulGȿʼ@$>ZN%?}~on?"!;>Q>:eߐƻyπL<tȡ>t>1v??x>Wp?S?Z?,#?6?L?; ?߿_k|_W<\ĿD.9?ǿp+Kv?`x^?; =0?#L=ࣿ,9m?f>࿨c>iD&f?l>x=Z?]]??¸H#?vѾYtk"? ɃdѿE$>z_?I?/o>i ^C?4SG?sa\*1=R?࿧%;ܙ2M=Q?C>F?\3Bz?6<>u(>ԫ?w3x: =J9@ L?l?><?.>|Ծ ʾjFL>)i>+ԾO?>x?q"?>̻/?&~?cF?)꾾)Bd=3=N>sT࿢i?\?a' >= ?=>=-?>ݐ>*;0Ӏ=eܻ>Pܿ@$?p??*p?=$S@1?^㢁=f::΂> ?wd N侶l?cp[??CP>g>k> ?Zԉ>?"N)?,?Ƣ>th%?>t8?n? ?>zP*;ز?`@ć?pM?n<\H5=J?4?"S?a?lv?W-q^71]?%9?K?m?u*>KqR Ŀ?+Ҿ@>? t?#V?F?G☿q? < d=nX>?4l>پo?`?;>?b,7?>+OΑ >Q&R\??I?493#ݿ G>)loEv>^?> 俢?8=1S򓿍LQ?vy=ξq? =>G =?f~>F???4Pp>?5-H4h? ?>SῊ%.=[(B'> >n?uǾཿ>H?ByK?kG&_j?J ȿ?i^?B8?y ?{'徯.ƿ{ZIjB?Tt?Qg?>U@ra4>>hj?j?j?yPrڿTt\>Y ?b 8%[4=+=̖?L>Va^>?=f=PX >r> J=>"?^N;>vUSL?1?gg?H5?1Q?=o="RH1=2]J??8?>40X= [>o> ܼ_\?r>{>mo?4<]P?>o` >B?-P Ŀ??%(;>.?4t^?{>8?y9|>Õɿ=6B>3V^V?M?Ql?T;?+e>X-J%::[NO,ھe軿t!!׽?qČ?{??;]]>zY>¾iJѩ??i>Ϳ 6?3M?_WN.=Ӳ>gPZ?:qTZ>Ѫ?#wD?ƿ6?ſGE/?SGn}H>ݺ߈"m?yI=I>m.?^>OH>>nt>?]?z@?\?;Ř?+>Y*#@si>&X? q>?@`>\?]V? M,?@=)x^dt>s,6>q` \?h?ӌ?>>B>οxJ>/j?!RF*DOV=Bh>6>pMOD?f_RϿne?%?q=>%>@?L??>|f>?[ ?(a? >G7?*> ?Is?K?ҿ_nλ> qv?6T,???Y??kl?)Qн*>V"X ??Fhuid>&?$Q+wҿ Z613|f?Ok=n&`=@I?+I+?.?g5F>l\ڦ @6}>q@?B|>~Y½(?\޽#<=j;?W?D5]޽3#Tt1?^84r>>]\?59\?Dٌ?8ԿSWƀVa?GH?V'tG T?{>?I?+?>/O>d?L??b׾↿v(6hLzȣ,_>,9>S>aE?QO >˖l?z3(?FԾw¤;Yȿ3(|{Y|>n>͕?u->G ?Kx>= = Ŀ6 ??~?7??ڿg<0dW>)P>@?*<>䆾?YH:/>b>?M>>B=:mC55>T036>*B>4e3?>?y??Kd| S?E>&>$q>ÌPʵᴄ?* ?#>W6J/w>\ܿW=f9|nNN?KO>?Vf?_+>:5ǝ>O=u>AqJ=,оS˝?2XZm>̾}j>%~?k*͉߾&=lj />2?9n? ??0?Q!_z>4> oL//i&<>vid w[^&+ )=~п+?.F?30>2? >` ?V0f0TY>?XھvB?L^u>Ѿ^v*>?_>['>T쿝.( ?t>n> ?\㘾@?_(?a?]?(=?^I >]=?2p?>&9?l=0h2LPf TQ0O;@Z .?$r>{KS??R>F)=>`2=&ܿ>ʐ?$?9?άbpR?lbu> ?K":=Z@? K>]h?(:?L=D>圽FzHp2>>v>so >o3?B )`>Xr-p>QJ>7^> >ǚ?j9fl?R?PCfz>???#O޴?^? ޣi?>n(a??c>-W=:\c?9X ?j> >d=ML^(=>">">Ȗ>(=`?xD ?Y=o=@o|s\S? W? s>s8?~s>T>G=:>=(>[f=UXK=D??f"=@ݝZ=4(x?@>(1a>?>T2?50=r g&2>j"Ge<: ?ˬ?:MB:SBF*B+B=B]AlTBϋBA;NAB ,BBGBAeMs@΂ C ABԃB,AC2C2B1^BBC7IB[B&ABx zBCA BnB:PH*!B]ǐBAABB'BU@C^BBeB@Ba@GBʔ BkBHCh B7TBBWB;CkBHێB!xA0 C.CB߃ CCE92C]CJC*BEC0B2BeBB $BdChBB_4BjCBTB2C'ךC LCXBg'=-hC,CVCC$CE{BRB @X𿤺B@w` RAi@BB5Uˉ@PBNA[B7 NAM[BHuA*A'X$B,XBB^A4BrzEBMA:<B)ZBa)B1BNDhˆB{4AߍR`AwC2°dRXB5<Bh•, oW6A0…O —'AV*¤B"@B#CkA@rUf)PBYB}^B'4h81AZA1uB;hnp:f™r>¯ѮB|aBˆCb¤}?EJ§SºhBmBT|bAB`BhZBAZB9+¾N(¤A^7ŽœhApnB3B<BrC,vŘC B&B;w|BB=vBtC ,B|B4Bв}ՍNAuF;A.BdA=A'BfZB&B CUBI7]$•HBNAAc~BaNBA?@BB%A{A>WJ?BSVABCB|tB8C$=BnBBBBOnCZC)z]BrC,@BB B{BæcA+“BvPCQTB6WA&>CLhBB%^C0ɨAB!C%KBҵC,CHCK@pBK}BcoNB'V^ d@C^Bo82A^@"BBPAsk@RB\z.fB B〡BtMB0C;C* }B{@&fB;B^C NVCPC#4mBS 8ChDCC;Be,A:B5%C7nCYBB_tpC/CBKCBDFyBHCcbC"&dBt BqBA~BqUC^BCBNBCLABC)CC]_AɷTC3BTBC!4BB CBjC CbBlCCQC-BBAZe}B%BC BaB.ABLC0C0CKICz&C!oB٣BC$mC aCC$~C-C_tC ;CCr"CJICKC:fCqC C-\CC1QJCzGCU.CO:CiC^>EC5VsC(OC:CNBChB*CjB B-=B·ZB艸CxCQ"C*YB{ySY(@O~B+B9ABMŒG@9oc@r*XT:ݛB L(BnDE'¬*YUގmń6:z¯pt¢£ `A "Yy‰2lI!hصzAXAa fxnGHu>º51/MBz@B>v@M:PO¦ЯAS+CMBxDBzAB?BPRCO׋t>r?I>*{D?̗?Ț'B{B\a?ʾ*y|hf&>鲾#`ѐ?_+r? S ?"N1?V>]D>?D>*tnZ =>l?lc ?u;¾.ר*?e@5>9[B?$?}>2z>n>UƈZ>u >Fj?$(? &Q_>ſFƿٳ<@>?Oi2>>B>}>; ?<D??Hҿ iz>?3``N֤>2?qW2P3ac?qD?/\S?+W{q<b&?Vnk9A>ԚF3唿U*?f1Կ*=u>wC ?.#9?:S?S=D?"+}=iȿmE⾅A>=>p*=8 F30J5p$ >?fX dTip"E)>>VxbP?t (6o@# >Y¾2d(?9?'W?Qw>(>4>䥬>EׯZ(D2ջ@>>#?@ ?sv?T=`?rjSF UVE=l?cCk>$>[|b=6?4>"&TҰPl>?w?6=sMCIe(?a&ѿ=څ?hpBM=>龖?R=,>Dh??Ŀ\$L>_<(>+j>]$$?]4?]'>!ֿilпF:@0n$>>M =]>m- j<>P??te;p4ĵL>2 >Fp;m%hV>z>>Z=6t@? b?n>r?+r>Z>{L>"N|?PܿƖn7gȿ`P>zR< 0@Z}[Hjx=: h̽0oBNi??=Q>n3\m?Q>8>> f? ?.=#`5>s=>IlJ?I?\>e2? 4NטmL ̾JJ|b> >j<>\= B>4W*xz) ~>ܯ}Vl.>"%X@=^2>>]?8>C>2$y#>\?XT=vX=1̿diN?6?@[V9@3#l%OH>(7>{?“GJ>7~ ?i~\/>E?Y>h(?tn'X?ƿ#X9?`?s]>%a>V>چ`???7uS<>2R6Zhܿ|<&yx!<aP?˽G(;"|LXBIъ=f=Jtiܾ@6?3a>f>JcR>?e ;<ʾw?c?ZX-N=w)迃~?' <9&>z>5w>?&?6˜?p>V[ЊYQ>Hm⌿ھe ?=9X>>.?C> (>8>=Ci?H6s/^?>FL?`DJx?3l>Fcd*t>[T)ҿqC5?/hz ['?j?<tKKk:>\7y=uH$?37>Ո>:O?+>>Y]?{BU>>֨-E(P$?u?\>>> pXь>W?b=.zpP~<ȿ4cB7 D7ÊҿM˜?7 >S>?6?Z?OXA l(8|fҾοD,>M>!v>ce)=Kln>}V{p=`>K(&P0??B? >pR/JP>A: /|J?#>K"@VE?G?Ł\o>qǾoR>Jj>]1 ?:?1O<ٲsq7w ?*= ?%>/-=`U(?Q?䲾xYȽX{k?L/+3?,|P>dsnd%sԤz>>Ү9pY/=WTtɊ>>9ؿ+dq?긾>>T; ;}@?Ix?L 䪽,d=\L=y=۠\l?m>\Y>+Xո>S-cyT-C>gh̿8>>.7Ɩ?K>'0>#>vh :>U?N\0? XXZ>?|C.>ʿS0¿"S?&" {86kz>`F4u?+$4 ?4sĿ7V> >CO>!>?#)>m_="AzԿ`uo<M?Ub?2#= @=>Z>>wj,=s ȿ 1\f>g>_?q?GZ?sS|ro0>0L`"¿3'C?>Y=1Y?A؇s<<׮a=>Ŀ?jc>Gu^=>Dz:>%qS=~(>-?Z>񻀿W?a>?JVJ?qG^?Y>oHbs3ub?g6=y='%=Il?f> o&'%

    0>n=x?C<>mJ>ټVd?LJB侷g~t~]OvwX> gV?ӿGs-=>3?f8?G͵>rw?o Ϳs:ϢB+,>_>༿ު?<>cTL4?sۿX_W>@?+(FD?d??>쭀>H>>>Z ;8耿U_E?(R<=|Iü%bmtϿ?n}O?ug`ſKDĉ>Ii>:h<+W>}""?Nc<&3x>*˻G_;l`?eミ6?_e=.>4>"QjZMe?D2F=̄?Ĺi?5TVk8?&?@/g]K+= >>E?>$?%_>z?x#?Y=Me>4UN3龽 z6>zϾh:8=-[Q& d?,=.m齒0 >K*)"Z۴=K;X[ASx ?;) > _= a()L0X>x¾ >|@>`>s>Qc{?bH?'h0? ?M?*8>%4bBiPKa`??JFy۫4^ɿ%?긾L? 1 > R4>  A8?\.?P<?=C<@ Vrf~)lT>r?*>>IF?Z=L6<@?";п >zik>?\AZB>2=H`>؎V?-n?>U?B?I>h`?Chަr)b4?k>GD>mǾO;>? >i>'?ZpdHy?>+>6>Ű<\07?\?_+,i>L8?,,3?-?e>b?s1?8N?A8p Wt#?>I>Aq?P?Eyh?!EV=)[!qh>@>@ù>Э]?/_b+RwQ>>~>q&?xvS=0񘾾<]?`BQѾABĞ+u>s,f=B>rAT?TD ś=o8 ?*F?0XѾ4?B h>EL>L>ʥ>+8v?'N?6G=5(?B\V>^>w v=?4UzVP <>l?[T>Ѣp>q?i4|?T>5ɂ ?˿ot?V%>G??K?s;$?F-%5?#> R?ga>ZZ}~k90?80<>T4Aw=a4:@I?5d>b+?kn?B?=5>H>99S1>y(/D><>+>e?i?β?pS8b?H ?*?[?*ifyw?D*b>{zmm,87l?vO>5> T>nPa?ܝ>Id?**?Z=Xs?zþSԽ`>>tGNYq am.?!u>'?7*8рƽs?UΈ>#?V?`kݿe"a?&>~>=&9Ƭ?F/> rn?oj?%xڦ4{/?1$>v[> w>d?7= l=7?Hj_?=?iX>|>?U뿦;,\`>u"?~8>Ư? (ƿ")V ̿"?Lln>nZ>/~iaS< l?K>E?#>ِ?IJ\H .?7?q?(.>0E N?e?&'?8|M >že>?8nyZվ(>+ ki>Q#4>[Eݨt]6<#>|ܾZ>?r>:? b???2>N[Xͮo~ ;0>Y~??-Y?Nu?P =Ydh ?!fp+{5?aFX6?b}RX3sǔ OzI=|ɀR>]=1>X9WVp+?R_טB=C:?<,?W?.?+aV? R>·$q>Xp4:A(Yt?n'?@?ae?UV>\u>ο]HH?A\U]?-?<>/=? ?(;fp=n?` w>>齵d> ?[ؽY>i?A0?hR>+t7߾ 7ZJ>y$?Q>3=z=O2;>֠? > ?>V牾ѣҾ$EF?>=>QR&*j4>+=omGފ>?N>>t$=y_x?G<>f.Y+pK^ ?Fwen?]:>.?=)o=оh#b>08?( pl:?9=64?? `">'*ϽF|YBrᴾ>d|Kfӽ!>Xf>ŲI?[SϽ?=>?iP>T>N?j?H!D5F?.¾hɈ=`Gu$仿C)쀿G>RL{g;c+I?Y[EZ?`?E?Q ?lHb>v?W ?>r->?WϞ[\QIX~?I{m?8=>4?Zw/=?=۠K?54?c?=T(W?օR`?==v;ǿ K.Q1$>Т>BO?#hпu,q>!X>>h `>یF?4tܾk!I)>q{U=N?Թ? 55A\A.f?Gl>C?>v B>5>ĕ ?h?0~v2>4?:)4I<t>?Z71e ?E?i-f?2k?{P? >۽A?j~?Ѯj?<|pH>x>>ۘi[ ޓ+ ?7Y>q>>]>^>p:1>'_qc)d s?Ϝ?򽅠`F?9?R-?7f?n>? K> k?=`?MO]N#?2W>qE@??}>J齔J|\"hK ?o,>C?>S>h?[SCb2Ծ+9Q0- _ER?uʿ+?[?4,kPSÿ/sdԾ(q"~A>y}ɾTLp>OdNo=t>S=J佛S?Ze=o\FԾ^3~d>CbaBr>ڨ;9H?3">2V>==XFDWE{7N>ȷ ?Fj"8þ|?I!0?Kζ#?4/̾)zءw|{a?rWl>?2- ?_e?D@ܘ+W>0?/>p͚> >Be`]?7lL>`_qq-f>辘ֻ?;=4Я>\>l*m̿? !a>[$?D?NՐ?@?W?f2nG>>&> >@>ta>]>1>>(; XUT?nP>??;5 ?tXw>~̧ؾ t# X-c8>݋?|- %>&=+2CLO*>Ⱦ]ʾ!YE=>fGH>ǧ?jrf>vum<t?Nbx>ѿV<ƲBľ:k"K>"G Z>L>l?j{>`?}}|‚. 2Ņ¥›&k,¹eo|v h/]Iº=ML A v:E¼SBgBzAiAKlB@4'X3HAsBpAFAB4:@}+ ]A٫9_O {}T?xœ` BpgT}•BKX ܹ!dl¬8…‡(žL0BBe!Azqk#A'] n"\¡17™Zp%W*AIMhAA|99[^ B@'¤B Br³Xf0]'U­vӞÇ&_E4n®º @<8ƒ;"½Wm 2Ӿ6Ԥ³gA;@6ӈ?B7aZAB^H~gmAL@B;BRB65<17A|ºZb.ŒA·7]sE›ɾBU|1,̊& AwAd-Q³4ÄL”^B [=¤phaZ0 AĊ§’FA)Šc翯lqW8A@BAe@A7#AsJŠ{"B%CC44DBQAqbBPB &BTԚ5¶pOB2:zAwBAB0B$W( AxAMHAp`|w~&W{r92Ox¬´Mt¯% sܧC@?`P' Ad2A\pb"$‹)6&Aa}£ Yf¢‰zB dDBo[Bo A̛(NTRA+Ay_B;µB" A"nA'BvB7B%XeCrB`A (R’JB0qvg¾sM¹VzTdRfy~B}UBLpIA(DBGq …7uZMV* ) b-B(qAn'|@Yt@A;?.=ѐ=‰jNBt:H0%K…&Vo)!BGѯB9zB ZAuLAW>BbޛrCAXRdC[1»WtoMɫZ;A$BqFA,MBOBNAv ۖBpA HF/ wd^C—> >(E!qʟ0D/M Xj܀ C#cAC@A繑œ@rARZg޹g7GQr]p|AFº3M2p—wBDmw,A A?0]k A)A¤ nHg°#__wd7#uµ?A!8)2s Ar~BCSBiAO‹¨jXCBjAl±6Z” 3AaAnEv4Gk|sBHA?n@)HΞY5z1B3B64C5CBDٗAExSBrA/BB˄@:@BA)B=BnKuA+BZ BߊBBDCd#B3VC4BӪBɠCB7(BS?T?BHBb @H@?x3B2JBiHB]pBB|d}ChB=A&BNCB,B!CB"B} &4CHSB?*C[A_^BLB;BGxBU0lQBVt>|rB+:9AAiA'3g!/B dA`dB &>BB=(qBBBĈrAOB ? ?B?BfB\!;L"|AN,B$zAhBeC;AB8Bq`BZB= BWB̪B6mBߣB>ByiA+%B:N]@9C&BBB'6"B7˘AE+AOYBg;B/BJb?ҝB^CFZBbC+CP> K AguAC~nC.{*C A9CUdBeAl~BլAŢBDC$~BilCZB/rCBىB{BUB8;BuB d0A;V>A?BVBkWB jB.`¥ƺJA2BMx|s*AK@}MAM |'ł'@Ob D GBزB&B BYƒ®B׳C_BC !BgnBC 48BMBlBӞBowFC]C? Cq9COmC]:BACr@0AW B3?Bw:C(haBLdBlB\dBB B B:ZBBDBفC HBAO B_BMkBTBC ZaCBBK:B C1BwB6BBZCB:BOAגBSBãKCBBՆXDBwCBg– xBHz{[eGs^@HEEA叿UIkA0‡W5 k*@[’UŽu4B¼CSBFtBPA+1ByBBB*> BKBŒBeA3@|AMQ>RA{ Aµqmx?@ @i@jE(Uw:BzIdAkAss? >>m>?:ᶽ#H=g?hu<=t0Xg?>37>Ŝ???3}_Wֿvн6?Mܷ>@sN=jß>Z >=@> A9=Vv>G>7tp]oh9?C&W?v~?H5>6?x\>j|?"q+ _>Mο!r?0=`>hn> ɿ  F {Hd?ۤ>_B>t?L'?ig?!JV?P4a=S?@i>v*u=?*>^?P>v3Oֿ':>(N>AF?$6?vʅ>ĿN>^?'F(@(cm; @>?{l>ܪ?,>W2?)?_=Gx=b_>:dɜ>k?B m8>A`^>To(= >璾Ɂ?-?4r=6?.V=;@??Q kT>D9\?Cz?q--&?./3>;N;4?a>6?D렿4 >>:?V`q>ZǮH>0%F?w=`?> ??7ӿ MĘ >XݻL-QW?>ځ־S>=<пG?0оp;Mp?%`Ⱦp?S]>tdx<[= %?'j?} ?-;0>.>K?nʿ>7=>(!?lF\ZUO=(h>x>hH>]>1(M?R+?f:ЅW? u?!Ŀ Y> ̾ݠ??:k翝5>uz?4(?6ɔ?hL??0`8?-0?*?/?6NEB>B ⾖@Lq%Ҿ>]k=5JXX?.>V"?O->nҽ+w?_n?f3=|h|=(;49K?:;F>?U?ju]?23?)_i?.GX5ҿ}IPEX?,L\fhKDE6>O'_QKV?8=D??J>!:Ƚ~>! Ŀ%"H>p?g>+j=??H>,̾n?EKa~=?@(?瘿 Kz(Qt/@>p? U~ϼѦ? \?'&=<>'\8N F<+=$>W$ȭU?HU>>>/?H+-_0_4D> ?K?%Z0=E(?,R ?&|?8ľ ޾d>|T?fvH瘾N?;_?>Uakv>e1?p?M¿\[YHR~? 8><  ti?Zn\O8?ː?[e=Z?.K罾T? G%A&>bʉ=F>9ըz?tuz\?=~DE팿4?>u޷XV0 =8ȼ1??)҆=,f?hV?fY|N?d@?Ej?x?(aּ?==>I?w=+̾?5ʾ *|>.=˚ĴFh]4>!@=c? ?.М}> ?Bf@ ; #?(?XD4?[XFs?AxH>P=? bA𖾨>@?7\7TJ>j>QϘ>\>?'>Xq2> _: ?Y>g^C$>F]VH>c?m@>>?>K>H5Y}!;A>垿YVX>)?> m>E?Rv=~$Ϟ<+@?AW>L`?KN?R9;l`rN>v>;`?9b?8\?5k >eR?*z?ir?C?L?$f>A>ҿyQU> ?_>zu w>m0'V>!l ?=>?(տ^?Q̿B7c?dL6~>p2(O=Ⱦ ?i =VB8nz?F$=+>Ԋ?f0B>.?. >!?@.#>yb6l?c>+I> ?\0>T.>??@xP,m{=?r5>|a>⤿ پ>ֿFyÿHV?n>S?$@>T?C?q>>e?m>񽽊>,=R}h?ο-Sjd??!>&^?oBt>Aɝt??tS>GhD?Ğ=k?$>ξ#?#/?$@?Wy =ޠ>b ?.>B?XN?a?L\K>ݺѣ?~<ʠ?z?C$>]< ?{ʿBV>& (y?e|Z>oi6>Ӟ?>D>?8?=>mR>;;I?_M1. Dؼ|F@Fl?Q?_#?:P?rw{ ]4k[?d9?ɕ<>ٛ>R@@>¼{>gL?Xuտ Gc?bv? ߿scZ0>M?=!N=!>h> > ?6Nj?u2?Ǻ5=:=!=PiݿGy1E2>}I4Fm>?[" u a,6㵇 ?<>(w\cU`? ]ٿ~?/Jt?$l?~>v!??PW㿌 ?ֶ?>Cq=bj?/?XS rrC"y%>É?5?#?׮?n>~?x=1D6w>&N={>???{ >΂hi>>u)Ƚ>?E >8#(>N>+9?N>?O?!;^~?)=?lф>L>ČF? >X0^N?+&?M181#"-?H>:>:KR3RPg?I->?>`? C?s⾵Wq ?ctE>UE?8h<_h>/Pp>E>䑾(ˆ>4=dI?1>eۉd㾿i&(>&=Jt~=mG䎾ЌG=ȿ(O]D<>i<$?\>?<p>v>hھcۛ2En_R?Է>׆>@Z>?,?x ?vx?`?B3;-K>~<Ԡ'7M@ ;7>Y@>/D P ?S!}ȿ?z?73>FȿAs>8>阸>x ?iNA?=>uϔG?1̾7?*C>`tt?mch>_,?A?Ղ>?b>aR@&lf=2d> '<Hh?=n>?! ?R>Y>˓=+ǹF%>)r>6J?f?x>)>ᬾn>B@> J)?o?MTj>ҽl>fv?*Q?d?q(?R*?hԣ?2۾h=-d>;>+ >T?m$.=I4ZaD="{^ﲾ4?ێ;F?^#47?p>޺b?>0ጾ? Ox>3 >R7mfh?Fūl?j¾>>DST?':><xV$ ">M?al9_L2 >֫?/W &6}(W|*>>l O‾OD?k!>|?o;(` >.S=|>%@XCVо|u?$1x@[CA_.ؾίVt>>v^>5L*@̼?ޮҾ@E<: >V?!?>1>fd<>?2??u&=ļ=?Nq_#R_f ?2?_>D信Ig7A?>ߝپܿB_҅?)%> qkrNB>e>WL >Za<}B n>S?D?@g,n?5x>=P? ME%E?)ho8H"?ľiD?Q?OξFD~?覆朾4CFN丿 ~2?:? 4!~)6?^t?8½ڥfº'mb;47>m;*=?Qo>c?Y>,";/=n?*𾁹> 63lO>FFx?$]࿆h?u DŽU>AVyǍV$??=&2jO?}¿,L;=4?JX*? >os=|4>ER/>p wwv>m>E ;?:j <"迂OW>:?*E_?> 6p,i?뾜tb>ulF>'Rd>u[=xN?e>sܻK/?p,1V>?Vn>?N? ҿr?l!Kͺ?M?*J?,>Mb?p.*> ?F/e?AνԄ/?x>gY? >zY? ZxP>࿲@>Rj9V>\?~1߾<,>??G$>h? ? o >/<X%4e;?B˾NZ>Q?x[]飗?¿A.?*Ua>?C?XX?|e>;289?Jpp=]>@!>l?sA>0(>4B?>]?jȿ@k0?\>??[?:$? ?Em>?&DB%;?m=R޿^޿Wt $ i%~ ?n??-:dts? ?_?tj ??a>Q~SϖcY{ӿ2~mS>DS'? D4?t??>3 >d>͚Q;[TxV߿78w%N>_V==x?eHt4cK=ideEr>8?17?ղl@Ӣ>pZ?<˄?Rz?WD?N[A?#H?M?M,pJBgzB??-޲?k>?EQj? >:C >l? G?V>J>t3?yտ h>Ŗ>3->>@>h>19{Jcʰ>WX@ic0Q_>~``?;>D?"-X_ݤ>#g>&#%=l?JоCv9= [[I?1?:f俎Q=>s>/>EcXTп>?^6Nl>/Xtv=w]u?=㛿=l>ɮ#*ǀ?Q>4>Ŀg=CMDZl>t4^4?\ =/>'i~>T1>ˬR??p:?!Wؾ$shzٚ=?HF? ڿ>fZ?? ^ m?o=?>9n>k|ݿwt".̿xa)D ?%f,?I.`>?j>eM>/]jq>^?A=-P?茶ɯԿoJ  >Fx6>; l?#>9$>'Dо!Z>X{_yDTőyV>)L?"?=C?7|ij>P\b=?"8ݿbZjѿ˾BA?j=ڨS#^?1Ͽ<4 ?Z?N,>F?+>wpq?/|?q>NxdҿѿǢ>Q>Ŀ<@Y ?J=ۿNR~?8<.?U,==Կ?y= ¾C >wܿfo~o?ܙ?7 i)e?^>?x? 0C?d&>A0砿R=&2&?w?>B 1>L>g~F>{>Rz= :=!Lc`=k=EV >9$$y?->'\UW`?? K=X?O{>$ ".>=P\ SܽnZ?~>"!??Ŵ=;F?r>>`?"]>@?>>]0>{7~>G? cd?9|ſ\ j= žn>#Mh?7d>QrZI> > >Vz1>*gv?BPDR/? Pc?#h?Ĝ>^?o?ܾ,i?wؼPi>6> fۘ™п6[|bk?4kb>y>6>9-о=JG̿4ؾ7> :?X^r?l>a(>kt?;b=>+=h?'?P=?ʬ?BϹ?$(BAI8 j}U!G?L>>.=S >4O> VPMTUI?`0оR|?@&=_c>Ox>C&cp!?u=a>=ǾܾG?Dž?4?ܻ?3/?+]?-Yk?N?zl"O>X=_4ܾt~?9?X?>?ҕj8?zsi>:Sa=ؽHп޿,?z"?V>YI?\Hk-?jf+?<=?&r:ت?.?>m=zVۿ4:п+f>_a[f>%?~w=檿OX;򿆉{?M]=P8> ?%踾DHM??w??+\;M?[?Mo>?Ldhۿ~NP>:^? ؾ?x>/>VK?WB?_+kvO<),?'>S ξ>AD>wTཋ h ?_ȿ^>?UZ+>ZY@jf.?4 :տc>B??h>? N0?km?>/1̿Lt>^>>P>Wζ>~xR?D?N!?-@?aW>h>ԥ> y §|P$M\ºKx–“A\ ¦tk!&?-T¹\P(YyP’šQ‹ \AAa†,]=)_9+2r¸`KQB/Jz.j?\AI>B)AT vx'ђ¶;[/{ª9m€t@DŽJ#1 VE¦OnCa¡UAcB,֍AgA)(9AHV>˨p…!ANBBCW­A͋AQT@k^Cw/L~ALBcAKmA݁ 1@"sOy§&D U @_d@H '“_K*O@, <™WBsuAiAriWŠ4o)ք³9֛PAI[w°nt*H_B3g¦B @A{|A!@jB]%(9^5?Jr@lNo&S¯ APCB,gLB|œsBmMk_A+I¹7E K[AA#_@BD1B B B"㟿.,@BzBJB@کB/RvB2cAz[BH>@0*pB@ ԰"(Q-IgjzB9,vA,h"+ANjAA0,@8BL:Bo2g?* AarBBq\C 7BPBF.BL)BAn!B"„|xAv£An}A+HB[#B $@AQ²H4AN+AjBQMB,pAs8>׾B/` ¥+° pPfEKd!v? aSIAVBf2¬Q:^=eBɭžB9DiAzhB/B`b2B+AA^BlABD?E~ B} BE7+[.BtB=یB4—@&@EVA~<:B–,-4b×CB TBh9@cd~aA¹­AB]1@N@4´BC@LrBm! AcTmIFBB`?B/; BH7BB7A@ Bm|BBƩBlWB2m+BoNyCBMBu@*B eJ‚MBC B#AtBûswSA#AkfBt)B#tBBU5BTCvPBBaB9xBGC;JC/ZJB,+BBiB†BJvBB.BkRAKtBABepBX3BBl=Bg.BBBB@|B B#BӴ@HA`DB;1BivX;5lAE+~B܊BsA3]BIJ@BTCC:WBBlB@qDAqBg@1A C0ŮBhBBPBBAc:aA!BPAXB@Ѳ@ŏ`B.r.1`C#~B?A!B9n5?0‰QDAoC}BhWB\%AvSjAӝR­p~jBBBoAB!A{ BAB6?†BPeAxCf 7(³d'nAw_nB{VpB$mVBdX/TSÒ:@?@ @r0B;^BW%B~yO:B"3JB\ A-^C*CBSB-GA=AC2$fEBNBBMxB&B A.˥pfAKBj€B!#PX5I”H"ū^)A/*B=B\@iBE`}+B0B~qP|BbABB}QABJg…\AO.X `BvALCBnXtABeAB BQr@(ARBs6A $B^‡>Ba6Z@AjBdB6bBp+Bgv>PA62f#0|BHA¦u_V:%.Q~AArf³1BKA1A)@B9A\Av0AkqBACܶ*Y‡w:e@jX9@-A%Bz?%vB|r '^d}BQB4VB%‰g (vA6矚™ȱ3CB?DBBrfB&\\FAȗ@>PGk NAB92_AڻBȯ-Bk ABB‰zBۺeiˆºJBGX@BB@sDBB8P\BAcHaA//Iz׊AU@ٵd^kD3BwrB!SBL?B(>W?w?-d8:?=C^3i/}?˘>- &?&=dx]_.?B_>p>Di=пB$??vߎ),=}l=S>?>=R>>>8?s ?h?P>߹Xm, 7)>ś3T>6>x??^ȿh?DZ?>sL:0?5q?֒=iп "%F>¾ë??:]߃'w=??B4ýJ:?&?f>ˆJ?E ?P8>ڧDg>8˯"uD?3>8@f?MSf>6??Ou>d>dH?)*1?6>!|`?c?Z,05B>s?x;?=4?>u> %*t?X@`E 1ؿ?3r>)߿2W5E>}?`j? w?_#DIN㾻]> >j$.~6;Sr>WA :"=\`L?\@?.?5:e&`>-n$=g<ѼȈ?YĿ`2? 7??C@?&\W>+־YO>ǎ)r; JJS?^?h)n;ͻ?maj>=?C0?j='=RI@@C6? +>ͭ<KU?%?k2>ڋbf`7=6(ɿWτƼ@,* //]!=>w=X?~p=40? >n>T-"^>H?C=OQ`H?1>{R?e! ?#>c>s(=c>Y>$ >@g?L>ߏ. !i B5~?]C?L?1?=l?X"??XUr_7ǢU?(ܽ$?>Z6->GĘ?e=z>p־Iz?bڿdvX?̓??>M%J? ?MMzW6>Qh:ۘv/E=J?Ma?z?#T罅Q8??U? z+V?gG>L?b>\y>U?:?=Wx/=5?TS>>' JywB1[$&>?2F\?T"">`3d%^‚?mz6WKڼ7oMh ?%t?)D>Aľ K ξ > x$4?>}L??5tD k!ʽ$[8=Mp<???"0@?-)J>?g%FP>1bh'g }>uFDx>уZδl^>=>i>H?>ݲ?ռ; ?վӿ ϱ0>?2 FE?63iI=&7ILwV=DR{O| >M=iEɟӿL+=? >#8??^>2:# >~>>>L>4@⽳>9?cve@?BJ?S>Ū?W!ߞ? }N=`T־F2>N?? =hp-? >U!=?-οv?_v1;rw>r>=?,<\:4`?Iw0vn9>j7X>\hO?\Ysdq04 ?;~鎇>4:S(?ҝ?2,?>s? Y>(:rl?=*氽^ ?Z,?}..=R>C?}|E僾0D0ɿB?3Y󗕾 >T=^5>#?ԽXl̿t>?c=V;? $>栳 =>΄>|>%?c?f?^>i?={st>8?|ƾ\D>`?I?)I%W*>-˩fBDJ@dgVi>N? ?U?3=L<M>?>o?$=W4鋿>S?@w? (O%iXfϿk7>g>HBu>|?>e,>q>,ÿE>8>o!>U:mp?6>'q? \?${𿫦=;X?$?ޛ3*K? 꿀⿍4| sB?7>\>0z=>\4?S>$?/?HĿ70<9Cp?p˾޼нء? }=׮=Ũ?U=G:p=>Д e=3?bpt>x?i?1>O> >x+Z?i>q ?g>?kv?F>?0D;04\>\:o[h.ľru Zt?X?Fė>ҿ[x>>]7>o?=]۾O0>$??HsbD?4m; s>QǨĿP[>@A;kX>J>b^"1?@j>$??RN=yU>V(Jt оk=_ܿG2?T?)`Q>]D>1;>I2Fֿ(a? D?o>??A{L>?&?&*v!>\?x<8>[?j  >.=yG?T=>\y>?>Y>AG6?\>p >;(?M=\>)>l~>X#>[ڔ ,b>MMٰ[r??o?Tyؽ<п?6>m|r:⾀Mw2 >y^?+>7| 4>Rî>>Zt>p>"FHjQ??+:?9;Q*u?b> )ST>Jױ>?¾8l>?hY>.u=}0=đؾ >TD=8/I?i?6?B?#"rj ?sw;;=7?z vJA?`U?-?x(Q>98?¾b>?%=>>?Aƿ5ar'<=?a>l=?r?kPYԨ>>>ζ> ξG2>/?->i?*1~LXm>?u=9?=>͵Ծ ?$?$x>ZH9'L? t>z#>c}Ǐ8??A3Ս@K%?Qf?Y29>Vȭ[b܀c?`LE?JhFYㅽ{?Bw?DH ?UvР?"j=]:3oJ>b?*NX?>|O=ƾw?!N=Ηs>^>%4>_[A;J>Cq'}P/? {>X?#n?7|>%3??8ﺂ?>Ҵ?s6; Oth??#f>lX$gF>8m>?qZ/qP^>ݚ3HX=?={j?N-P??v5e? H F?>Ƨ"숨7@?5A?&?"2=t?=Gp>Em?q~>/?>q|?é>h=4?\׽0[@+x}ȿE>$ P?+p= 'f0>ԾA?il<$>}zh?YB?F\-?dj>!>L@=v>>վ|t?h,I?N>r8_o>t>h?Jk?68??u >_h>?GB}?_ETYr5BCNE)n;?w>F>F?6<>&y?=څ8>!MV>>B8=*L?(>ξ_J?)[(;!C??P`ʿ l<8?5nČ=-?T*>콢?BN`? 0\?BV??(T<?}>DO?ྸݗ?= =H?aνc8?O?/,1") @>54>u#??3>Z<`>ű>T\S0 >=x.?W1Q>?pj?p>Kwidt?(D>Rd?.ʘ"Y??#c?XDۿ蓾>=|8?#?+>P?p@eZEb;?Z ?pH0>>_JL޾A/h=ӳ>Z0/?=`>SCAvx1򽅘? lj7>zCTٶU6E~<=8?*RM?>#Mk>2Q>qJ>p¾ƿ+?_N=ɷ ?Fƿ_>}(ؿm?=7I?,IԿ>|?ttP?h?+'!>$?M2*%D8;?>m֍ׄdf`?⾰Q=4p +`k>[>݊ml?lb\3>? ?%I?<?dTT?T>=B?7?)_>7aQs\z>~>j?Zh=p~>>#?ZKT?/{>&?=>%\ȿA?R꾄M.?s˔gg?0v>xV<40?ID*/>1N?%m A?Hm>t8>Nw?=4>`??k->>'8%?Pxry?e=?o*[?&|>+2?"]?QW>ygJ] $?"?p??& ?kv>nVu%?vna(=}V?I;.8* ?*?y.> ĽcP0feP>cbkD~p? =aL뒿'¿s;QQ=Wa5>=ѩL8m=Ţ$>`?LX?O?0*"`?nq?s ?>?>jb?2uh9?$A?'f?h)),>?\?9>J?f?MICl=3_>?&w>D?s4(>R7=0{Pv>>_<]K>f=" ?E?h̿Wп\ўi>7??$z@? -> c&j<ʾ%F^? d=9bt>l r`>9{޻(^i(=#>.B;%?/a?h2?$Ծ?|M?cw>m>A"6$ڦB>ҋH?*">z=ͬڿ L>>4>+=x|=Ä>`þg>- 0? v?/؇?{c ?\iXH@?>?߾?pY>76r?~?aH>?EtU>DZh~? 4򾊢3?D&0??b>!?lhr@?,ϽY?]L>'?*>ҒʿkNl<A>gܯ?<˝?K} >sz+JQ2=d|?;09z?<">>5p>O>s>o~?f?z?,K4y=aq?>>=??1=r$> <3?B> ?!΃?/j?>)h>AS=gv?>l? :?Q+">i>F!GRk04??Z>Ym>>??49>H8꿽QP?[3q>?5?>??8hV)0%"~"?%>jT^?P=$?iH^*+?#?+Q>ɑR>J?'y??Fxd=,V5?F߸>,Ƽ?.J?M5<~7ˀ7>X?sk.>>*Œ/#2/?k1F'^0>^ľSS?$%೾\?a_>W?>">?Ꚙ=t!>?T? S>xp @{DN%Z?K}>?it? ?L^*>#=y=?|b=uv?>z>?=D?j=?n=?X;p??%,><RT^h=h>$d?4pҽvؾ? ˦>>o)>ҿT$W={X?S#6>?+?>=^,>Ʈ>98?zZBx?п->`>~=Ѹv1?{u?>$TUڃ# H=s9!½;l ?k>>z??q?=L>$?>Y ,og>4e? 0h.?L)?*8 >>>? kG#:Rc>G ,>KD?ulq=8l:H?b ^ ?X@ *?"J>?>8?*Ͼ_x=>W>%{u&c'>l|$=s:p;ڎ>Xy>mM,^0?DG~J?Ꮍ?D\bx_?>׌k>DUאֿ6h?#=T=|'?,>Uۊ?>뒿>^=?Zϱmt=3a&>;:?x?(ž:>=l= >Ev>?4i>9>?1X>]Q4#JH@?5cNwǾxڢwVi^?r?0? 6m>D?!?*$Ug>־bF>K欿R?Izq?ީ>?4?u }\?v`?2?`?Q>#?\H >?5 b=Khܽ'-Ŗ >@G>L)>~B?{c?re\<@=?kz4?6?f_dCD>?($ǽO(?=a\T>7>uQ=R>?A]0;ҽz\>N=T?}J?m1?QEd>M?/!?i>@_L?kkD>]zWO>%F2@ڔ?6Y$?N<.>*O>z?fw86BKCA%BBA1UB4›'8[-Aָ;AE{0ir¥pAFAOB0"DBA$4%^B*iqBBЫBB7.aAv T`?2yB@eA۲Bb3G’Xp!R4`BPAWAOB9QLBEBvfA,˜>Aʌx@ݯBXo@DB:BL;B(ŸiB_Pg@JEB0.PrSz*‰3¤-ӣ^O0lrEq)@a*AmDSΨ*c8vtX%:z{l eQs>x\An¬FHC|*_BdB!Y)A@BcbA`B 1BBpjv@л;|™wt@\BZ_ABrA͐5B;D,C ՊBg-AϿB\v@DB0A B>pBF8{MAڕ ABA7AEBp~BB/IChB26oڠA".BC'@ΏB'+D BBCRBBYB+B=]CiNB_BBȳ@]8waB(s‹fhU}A2N7BNiAM1'M8V$A(2wAqPtB[BA?B~+B@K(Aw )VA6ߐA{G6¸"¾‚ʈ…RH!>? ĵu?µh1q$NAbucA {@Ctp*"$8(r{¼Bt @—mr{=u_5< &9:C·FSBBrݫBCHC/C0HBPA93(BAIB0BCBo2C?P=CBBvB{AѭWew[AB޹B BC-vAB"BMBWCtBzC/tC ͛C?3BӆBBqgBXBx `:ARBBRCBCAWBfQ[)rdjCNžz_A[ƒ@`VB7-Ž6ͫBu.0ŠB%`gBBP6.*BbAˍBh]BT+BAy߾ih|YBR!AoCFB|AZ8y{B;[wcAlBZBz }A~BDM‚ЮAUa @o,A‰BLXB2VA-B=pBBTCp@ ANB7~BV$fBBCA!B[:A߭BC9B BGvBBzBC< $B@HCD)BliC;BfB?†1PBtArB!}AB݌AͰCjB"PBhAbBZ'B9jBCFBz9nBhAC A٤y>Aʔ@)(0BBTB sB޴AH&x>B7Ag3BBLZBY:AhuxBaVx~@" ‰FAegSuSB3h?B3vf?H@_@@BA6B1PIB*EVR>MB ABt :‘̤2 p0Uw¹! • &A A FY’C*BXq~CAJBMCzBCT†J#*¹yA(D&U9;2]¼JS5A?:0A shB A!AN+ B㈛Bd^BC,!4B*@C/A[AjI SA?B AmBdBz?BBCBӋFBzBc1B\)`CBC•BʈCB3BABݡ@UA,UM'T/efAGE¡$#T]?KAĊBˀcGBBy-C{B2BB*i-yGB@}@^\Tg6ARXp9A)eABdByHd?/$kPKBEBp/?PzBT\BFr–9AWt;´A+0FBnzt4Crđr)K&&%3µ> A@5A"BBtbgB@AoATA[l8fA*wŠB¶Dž@3BAetAjBuA AC CB^C&cC7'fC7B. B~BBz*G 0_DwB@rAޛAT~AҊ iBmB[BBlBC- BXA2šs@U\Ac’+95|q&t@>ܮ?PB? ?TZK?ht-k >HHF18?=?u> )>R?NѾZM?>> z>J$3>>bQ|>#?9>4?>Z>>?bm?*Z(*>!H.exvi?/?K??kKRS;d^>ؽ* ? ?cGȿ!:>ؾծ?@8^̽p?#m.Y> p=u>y:=?-Q?sƾz(|sIO>>8$?'"?ؿQҿz>>hEjH?G>?C?7)?9q>>2(?|ᆾ\?8<"`>ި$ٍt>h41?դ1JdtR5վ|?"z>-鰭?DeF>i^=X>;?nq(?;&=3?$&? t?F>Ţ?hk?M D?k)7@>\?,?AP8?Z?pD#Y?D@ҾٻF1gk?>>@.9%ʨ?:Du=}?t?'*f$*;2?1Gk> W?H?k M>ɫaJ? ?JD??i1?#L>~?s?윿C?m?E?a=v>M?3J0?*Z*տ;F>8dMJfA?h* ?/?+?>=8t?hh7 X`?<>;?. YN ?PwNT6lk?\?<0?԰_>? 7p?# ?">)?Iv>,* ? ?hL>6PT ȾuӔ>ee?"0* [?F/qe?c?xľL>&UH?5Ϳ$)>Gҿ4B?t?>Wt>p?)=Z?<=(cҿ>ΕȿsC>D:?Qӽ<?4:踿[?+MQt?,?MmԖ>j?z:>>bWk\>Pf><=>H=4`{=P\͢>|>5e?ND?_?&,0浕?}?w?'?? v=Od?tپxмx?^>B?% w? 7?? ??U5E>?-M ?=>/>Uy>nܿ?L?^U?;\>Q 7?濐Tڇ?>s?tP=*? 2?Vɝ dw?gV??FzА?~8K7\H4><\>^?~z?q?6m羹}D?@??H+OR?bT?9?S?ڔ><"*?xT=ݒ4>cM=C𾑙 >d?>>?hj `I>x*??fJQh>4M:5@>$22B#n0MK4=H>R&?0̾:p\>d?s>¤?KF?Ru>R8<>:>R;W@tEſDؿsŽ\9??,>??\mw4=hh=~?:JLcLP>=> ܼ?EIC?se?`J>+=?u"ɢa >}b?>ټ=Ґ@?g33{oȿ8TQ5l4xо=fF=W?8>-v? >[=n8eژ?r?d?ԛ?9ߪ>؞>NbԿBV?>k ڍ6<0; ?{^?*h>]v=/Ѩ> >8? >oьԾf">/f?&?)L?C#>F;>?C>O ~!cUƾgbz {?=>>.>o>?M?K֊#bkl>1B5-Jn+XwT?L>f>M{1ƿS??% ?o"⿻W>ȹ>^h 0>>.>5V?! ĿG?5???b:>6c>1{>\ѿr?Ơ ½>>> 7iV>-?7%?'>J>?C ?8D \r6?<^5dr=>J?:wl>6?u>?b'd>k"ο}2V#+E &>&ψ?ŀ?>> 5>mf@ W? >XZ?K@ٽ( ~C>ޠ>d4-j?ؿ]$Fj?H>?V/;K >`l=.<>>Z<ʿT,>?h?I r?@=PI?(>c0n>K?WN>^=7$z?6b!ֿ&[?,?0ݶ?w4?\?v?t=;޾'.y?? ??Y|{?>ۻ?ؽ:>F.+t>Z?D#?4ÿ_A˾!?Č?3>/l?!?UB>v@l;s =Ӛ@=35#O-r?3ow?>0e?ÿ1 =B^= A _?d0? ='^>>16>fPM? u><;kE>0z,ܾ?G>>3>h?`?޾,Lz?炾cb >\>?>8T>?aH> ? (=Q(*?=Ln>7=(?"E?T.ȿ&^~l?V??uF>Ѫ= >P;-΀> >>b>N?'K?26?*t>>eWx8N?e>rA<9A)4>X??r&D*r?>׭>[?&pgo8oʾľ)DyB?N?@ȿId?J?LW=ᙽl>=귽U @?bUK/о =? v.û4;?P>f=E΀>?_?N*ӯ?je=u>{"?[??X??eZb>y@'$>>$V?!ֿ?#/ @F@ J`?)D?J>82?y:'?`b쀾 ;=X4s<>R=<#?W~`?* >ޫs>>>i?M=(>?T䁒-k? >ӧ=ԾN ?`>/>0>~8 ?Ҟ?>e?Wd03??,{>L\d=Xпfᄊ+l@?CG=@_>_pm ?e~=Ą9b7N?``4Mll>?DJ !? ??4^zԋD>E?uZ>^P>cN`?K^>AĿBm0PK3u;G޾q^W=} =>=@ |R㾡ȿ>K?:??jz>o=??yS?i)DgؾVt?i]SJa>:\*?B}-T[Jt[%>ƾ꿇8;TH nB?ucV??ʿY0> >;2D>?/>wD>?r?RNGO*>=>?$?&\{>i>'1??cC v@X>P.> 3TĜr>{"z= G>"ǰ?PD>Dq>Q??o?{`>\?$?l6R `ԾP?K?H~F޾t|>qž¡="ˢ4 X?UWD??,=]z=F?\?c<>^?aֽ>n/K<2;ǚŽ=u?=>Ϻ?Z®G>˸ >&?P~tRl0D?Tg<V`>7S,̿pF˿=1=FGU7z?a>?C+?8>A㾩^d??.>G> >ћL!?W>8>?v?LyTߏUj?@|e>ѿz>?Sf?5B?.d::>%q[?);|dX>>y:G_?2G?fC?2Tb>߰`t8>sQ,V=Qq=??H@Gƾ ڡ9r76.qCy ?>?f?C>V?̀?܎?) n>,Z?SV"gI<ɐ?l>~[>>_ҿ"gL>Il>b?@=>)>9!1sR>o>T0S#>a>h>'6?W;$=4͍8>(?!?D>=oZ4J)տ[ry==+f@?# UG>o>(e?0ҿ]?&)>>=@z?9M?n>k!>.9ʿsܷ̾?#u>'?[˛>PS>aؿ7>f>??V@?p4=([N=!>Z/\xNF쿌l~b~B,迎1> >ȗ-𿶟ſcyq;>w{?;gH?3JQ>g>>StYQ>.>tI+chp\>Z?X̾^H?9U~-P?>dw~?8ֿ9??5?GI?!(?={?b!=N;I?^?>=dF־'@)4 knLOȿ_n1BN>BȾbB}U}uds ?BDE? ?`7= G83?D:?L>oC>X>zl>͢ Zd("‚Z@?:>XR;멈?QTg\ tw?C ?+?$?ul?a࿳:W> <>>&? "=N(?4>ks?DڌKi>]Bq<>,>E>D?"vp>̩v’?3>Oe>-P:ڣg0r*?|>??g?-=>5!=t?㾡>? bTqp?T?N?=` lpi?#?>J?F>>*>'^#v¾#%>@g>IbA?dw>,?x;5 l<>jc?gd*Ly??po>T>O?Ybm=i?R=о̾@>?D!?A¾f>[?+=e7?<п&a>W>"xf<PWj>#>Q=L ?2?˼?RIl?faC>}>~x>Tơ=1>+:V\pp2rY< =?? >*x>?Gf>]?E(>F? dB 6=|Qn[Sul=\#Ruc>Bƌ>+>:?b?ć?O)Llw=ﳜ?Vv>qd>s? Y;,;0L?Ff?݆>+>WD𒠽0tf"G>=ţJ>/?v?c?H1@*Ͽeh>xl?%:Կ,D?{?QL>Od pc>,޾ 0? u>iƀr'?UXx ?Z?󴾭d??[:BH>?=.ؾ;3>>i>%\?Q?s;⾂K<Kgݾ {[?-p{c6ƾ$h=?a><Y???˱>k<JL??eؿ5G !q?2?E>r.pqAo>n?"(>PМF|)"t>Ge-sU>F#z?>{9>ѫyм?tv>&G^=?b~=*ow. ho?MyY+|>?58=At(?NUpMȿWKQ?8νw|?0*$9P?ȇl4!=B0?dpKTP>:j2b>wM8>h?f?@?^\?>Xr,>>;daphkMBT?h׿y`>}=0bн佌?&c*>JT8>ƿ>}/h>ſ'n=:\Q4J|?_!=?u?wu=ZW>\eX?TD?|u?4?^k>k?1 < RA?:GW?cʿ>|?"^I=>p>s?)lȣ>{Á>¿?#}>8&=><>v>ϳ,??k>W?>/^?Er7#(?>i?9[$>IX?XY>] 8?wXr^>I쾧?=?@a?=򁔿4YvP=?}lfN ?N>>׮w* ɠ >}1N5d<=-@?ѿ~?c=GX Ծ3 ?Qan@4>X>=DF!YgHLT?Y>zӾ?^gE?rJ3T=;v? "+ӿ)*%\F_>щz?[=\>b/|h?B4>?c>#=2^)?(CTX?0>X?tK3?j>A(>ɣʿIf>Э=!;z>Ƣ#x:l>?:0>L?vQCmO?ؾdJ?ݾK2???[,ƾ< > +t?>p??cű?>G[>'B>>*:?)A+P5->4???;>S>`+Yѿ8Rd?~+T?§?, s*>.=>  g>yuҿ`֥ > g3?Vjx兢 ?ˆ!!;6PŸOB1_4,'_,)W9u|.©WQBgBxƒZ$?BMBk&BL‘Ɏ<*T>d{ u³Ffqg¬-ޝ Zœ@)"8՗+!IJ_jJl2 gΫ^@I_BM^”\ª ",AB-'ˁ¬XBlBCRB0B B`¿WCDԸCQBu ,B"BB6@W@Bz*1ſ2AhB\EBB_ICgŒhBqB[Tjº`˟A=DB$A8E@Ms B('Aa@Bm3sBKB {B}$CF?|BC>B;XCC BC)1NB CiBMC 6$3JB9¾vK.³K´ 5; AXn[D¢AP¥I<22¶t=0Gk²{ Aµh4_X,AGvJ"ۜ@蕹¾7A ;tA@T fF"~1M`.DPqvڌ :P’E0[(m9a±Br/ŽBe';GB8yAcv¡>t2B^#( @BDB{vB cBB\B` B*ɉ@_XB AOB+B"B[B|CeB>*CB›@uA|{B6Bn{Bw,BZjCC*,Bp{0BXA8%BC'!B|DBCR-C+1Bw568*e w@żOcBPMB,C7B]N8AzoAByBLzA:BnS$$AAxBDB{BAB>FAUA^HԃB BI$)›3B|C+NBbA0)VT}BFB2BծA$BB&AGC7WCa.°o(A8BoBCNB/HB+mBp_B4˜7BzA% uLC)&BpTB2B*BlBZBҧq: >kBAE>B{~fBtrBB B;ѼBNACV8C!цBBA}5BeArA&B4BseBlawC#1!B"B;n$Bu}EA{w.9BPwV{YB,BD|BJA`EBme9B爆A9aBX@g"B/B@A% QR F.JŠVB2L F2&s[B5C õB]4BAC CDBXCHBBi^m:+.AlhB_AA,B}B^A7A㙃A&YkCopBSHBtBJA#CBŸ7RM³+6LAHItӗLB ¡DQwd²#2m||FAoNza`װA-}?OB B#BWM3B82B4CAZ6B OAMBuzE<¥C qQK´eI£ IT:#A h…muBxb\ XB~BA[BB{A:uQBjȓح>B%{ӑ? r`BwBW}›6#|“( A',A-B$A9 @S2jBB17sBDBWiCPBA3oBBӠ@vB w@A8XfBm=1RBr-nBrZ@.U/A]B(B@B>X$ /ޟ@s`GmAA)^Bn!BuFJ%l*iAAWBWBJBAPN뒅C2(BGAªTΡC9B8A FA_@Z0GG @JcŒ~BB\h,;B:BҔrAdMDAv,rZ AG¼f?WOqAW"@!AA A%ŒpBP z·ˆjC›͍9uš@S4BT7›BB@AB9@ >B8iBQ8BUm-tAŪhAiAnBxBāBBB)sB!9BAAAPvBSBB/B+BiBAVBm1_IAXԺ?=>'㔾N">??GV|>? ?!"S?Q?$2?nԽF_WC!b8h?F26K$⽮Ĉ->WR?ʞ>>~Uf?[-g?T7_0H?U@i>]?fJ]2`˂>wYL?MS?{xW`Qоw?.>; cb=ίG>â< ?2>B&=kx>X\>Y`v?>)P>j>n?)?+OvP<H>%r?<Ⱦ=4.i=J>Z?n6~M{<"?A[? $?*r=]PT>?jjX> ܿ~>) >\?˚??? >D?<ۀ<1>G?B(?U%>ㇾͮf?UҾ۽] >:tm?t٨߾E1R>@?< 8a?`1/ 4?z>rP?XeC%>^>ҿ h??tX?;>#V1R=?-$=?>=Ww>gp>.>?Z=aM8@?Mx<-9`?0䇽Q>[G?@ ?,C>w=>?E?:п9|>@?r>(?#=>Tx>?SgtAڿ%?s2>&ێ޿C> >i?H-n!=d>Ui>s?7 R>AnOֽ{п81?FF?C? 68>^rݐ?=6B?]S=J>zq?%?+8ѣeV3%|N?]_?̿z>?ɏ><1? F??ľg??7NY1?9?ؿ>4l<ƒ=@A?J"?&ntM?>n# >5anD9<8=>ꂺ\򾯋6у?‾>????<~+c??׾VA>q?Il$g>>|=C> %>-,? o?:ӔBZD==!>KI9>D1俀O?B???=6:@>Ժ?3H?@#=|>+VFɦ=t$JEI=P>ݙۿ:>t==ؾ]k<^l>Jo?ƿg$>}>$=a=Bf=H?釾Hl8 =z>~?Wsf<=O"㰿 [9>,L ܼ?`6Qx?v= x="O(G<3?\%a0<*Z]4>9m&l >0g>ο0?!K> &>?o?^I?>a;2n>Yi??U >?tr-^?$:O(P?n~?.:_?_1>Ͽs?My?@=ƭ?>?r?>>8=>,>RG M 8?GZ>%k]?YmQ7e`??3=J>?h?>P{>C\>cPQ?U=P=\0G4:fZ;떠?T;E?C< ?L3W?ʭ?4ؾT?%~Re@?2eD? @&&ʾ">#=5+9L?  ?{.?T]rsF?^?+#[ھU꾦B#>:-Z>|=9>p=cqǾ2=&{Ljq=ȿ ¿>>>2m)?X> u!>I+f >g=/u=>D4@Us=??ӟҾ7Gvڰz?LCt68>+;Ii:Q־v?h!*?$ྂ-?Dr>}~ ؾWEz꾻Ӻ; ?տ UE?ӿ,w;?׍>{"?lI4O|>復SK;;>җ?*(?J?^?mq6n?_,>J!4-xؽP@^ƽp?>==p?*> (??hu?>hQ<0w=:?&P>Ii?>Fl?`T?1=@>9=?>2?o?*C?W(?J>iҿ9(ھW,> 4>꾲?k>h?,>͋>20ᢤ:#1ҽ)=0[gϒr?Z o?^Qb?w?^C?OO ,-RV mLDT&=:X>ǠH6>?{ ?]6D;{ kb?S-n=>ۏ?&v>V?>5?= ,?XJؾ~ˑ> ؽmQ>#B?gwGD"Z??=aT?`??0? Zt>=f.?:? 8\?3v?*J?^?4e+vؿ8?&L# =K>y=P?NP:$N F >8A'M޾ϕAY?U &qZ'? R?l?|W)?&+=\>$$>>*ɤ࿘7t ࿣T>2?Iwu?>>׆ua=0?i6?rh,?9.>!d>?>?4>F<6 ?@?n><7Sm?|Ϝy?v"?Eu>V ļ𾜰qBˑ:!k?XFus?aH()[>VDQ?z<T?I>[.?ûf6?>ƟĤ`!lX)eD ??h_TqQr>(F>0[>xh?B=UԈp?o=n:]??@;?w?%9߾FȾD@D>J9&н$~@>>>͠ ?s>Ur|??$>pfl06/n?~Y>WY9ud"?f{{>(+?r>N ??v>=>oS?Nw6="X>?0⾧>j#>?>?HK3>:>&>O?ME?$p?76hH>lB?P4>?p%6>ˀ>F?H8\hnqj>dOI>%> +9`>- >/?jl  (}?:>f*u?ZvT? ?I+ڼ0>m?Ht?UL=\?]q?"Z| V'>vv>te= ??aլ?&F?w>&?A>-?XB>MҾT>ƀ4>%"6`?-?>ZN?n)w ҽ¤6y@?#&\?q=o?=`? $t>`?I5? ?>?`>v54ۿ*d>#R>p?dEk >SUU?xT>2}'ƿv:> >om꾾J}$?S**}==3%L> K>)>G?.ھҥ?r=E>*)=(*>ޑ?rO>ײ\)h=F?0Y>,j?ć>$<?Z&>d? A&P? 8>Um?#z='?R^>B?YKn޿?f}?2w? >ՒA>>{\9V>R?(~?>d>]=v=??Ml?!j㽄\B ?ʉ>=O0%?Thͤ&p >;l?˽ĭ~?_0?>X?ij?ٿ3jg? J?Lbې7tУ'!=?MC?>ZqGA?=F>1V?!]]oV:O>,?@^>8?v>⨿WU>.?Qw>>ty<^H۲L{#n[>QHɘ{~"̾F<࿔z_7>g<޿`?JB>b>ަ?/ڿ ?4o?/Ȕ?(?k>p_TᾦY?¿!+$>RT~1>Y>3?Gܿ6>/^?;???!P?E?%ў>P ~zP>9?8?"??> >6v>Be>*<π?O?y0>gT.?ZiͲ>%W?VG3`<:,辆?QhSR?;J>u}?q.~?}>P?ow Ƚ& >>Pny?J>,??>4> >'9f>>F>G2?T<5> MJ>M=H?^y ?q1-??Ͼc?ώ=>f?o?p>Gw 覾ؿϬEQ~?ֽK}B9|}g>b?ڀ>& ?:hȾA>8?b? ,:-&>=H콤=~=h>}o6d">2AupJlw=D ̿6ɽvs>??2'#??8K (]?.½Pǀ*^5@?p>Gҟ=e[?It?>/>}>̲><`>s?WW:>d?Ľ>!?B?I¾vN˿ʾ6@?X? (?q,G.{S?&x?"FQ>pw"?(1>a#ڿ7Mv>vG`?+9<׭|J p32bhAOE??>`>G0?gtaޙ?y>o?w뙿K<`MtF߾C.羚==v?'k??>h> r> B4U>ƿkZ.?? p1E$u=?)#q??Fͫ>C?*줽;޿2񾱽?$u*޿ 9,g *=c4>Y==n(>L>l>k?|W2? %c0` ?>*!d?+fz>/>>ϩT>?-f>$'Un[>,?Qu?A(>>,0. zF=}?5`=^ň>^?ag+l*?j?9?q`b~=h?,v> h=>!53= 194=>1=H>g7̼˱`>1a?@U$l?: Fl< ٰ-<>]WݿL? IZ=={p?3e+?td? ?z>Zv=cs??Qw>W*">L=?7ߠ>7>]ֿ"?f?Cྐ?=ƾZUl=d9?ld??n=B p`'h@@>^?/w>WO>,!Q>O+>>4?V)2Μh>ھy5?df?!>>a?̿$־Q[.+4`=oԾ]>dVq>Ǫ=R?k?^[?9\?}> >L/Z/A>2n>>Dľb>>Io;O.M*?y!?&?Sě?n`5>-S=#sոX8?RR?27>t>ɓ;ῃO?c)ܿ7*Ȁ?&hV_p?6?%?z2 >X?P ρ=ED>O? G>'>6?'4'X>hG>V)+׈>M˄>5 ?A?+ze?F?{_(>?"< <>4h>?>c6?jtl><%ZX[0* ">"f>ƾFLC #:?\3e>F>>x;N`?I9`E<0ƿ 㿋uf2>>ᙾ~>>3O??> 2?d2?B"Z??4NX?qNAI:3?RM,?e >56=$oy>>^"p>h>_h>U&?k?>>(>3A|>?%>eSԿ) 1>?E9_v>?⾃}b?lp(<<0>6}>7O?/ž>uC2E)?O\>>>? =ˀ>@l>~z½־ro?ٿ>E"ƾ>t(?ȿ6> ;Q>'C>~ ??2u>.>?Ub>5>T=h)>3?:?(?$?($p<؃06H>>GL\0?Qp>V?u?>W?TU濴8>姄`ܷ=ȾL>|?9g?:2?T->e=a?,r?*w3п9I??? 9?R' ?VWG>@Wm?*>u 㾾? $YvX2?Gz ̽/y?+ ?.| E.6AQ>@>N0}=@sP>O=0&`6og ~P ?@~j= ?R.XV X>?L(>>l$ ҾAD?V>?vID?>~d?v ?=?f>?= ?.=2B?vNzTw>_¼uĿ '<`?.aau;>)b?9q => >>Tsͽ瞾ȶj?i?d?*?YCV>V>(mp?FFh>.?`>=:F>,ƾ{O>N|lo@>2T>-<0{?o>?xB=/Xh??;x?F=Y|=H?Wp>,\qi 8ժ~>F>ĿՙT ?:-C>>?@ޑ> 䘾g@Q=?>>r6!H??U>ÞpA[?`a=x)࿼H; ?e>C7>dj>%+&RS:?"Y? Ӯ / e?[=?3|{Z?JR?y>/},U&? &?HL4>^? T>z?L?0 ?Kbl==B$i>F2>1˞,-v9!>?k?N>wmN ھ?4'?j >RY=%>f۪#L⿐!@!?%S??_m>lDfkst-2.0.3/old_tests/healpix/testhealpix.cpp000644 001750 001750 00000026617 11544160210 021367 0ustar00synthsynth000000 000000 /* * Copyright 2005, Theodore Kisner * Licensed under GPL. */ #include #include #include #include #include #define XDIM 1200 #define YDIM 900 #define DEGRADE 1 QString myName; typedef QMap StringMap; static void exitHelper() { KST::vectorList.clear(); KST::scalarList.clear(); KST::dataObjectList.clear(); } int rc = KstTestSuccess; #define doTest(x) testAssert(x, QString("Line %1").arg(__LINE__)) #define doTestD(x, y) testAssert(x, QString("%1: %2").arg(__LINE__).arg(y)) void testAssert(bool result, const QString& text = "Unknown") { if (!result) { KstTestFailed(); printf("Test [%s] failed.\n", text.latin1()); } } extern "C" { KstDataSource *create_healpix(KConfig *cfg, const QString& filename, const QString& type); KstDataSource *load_healpix(KConfig *cfg, const QString& filename, const QString& type, const QDomElement& e); int understands_healpix(KConfig *cfg, const QString& filename); QStringList matrixList_healpix(KConfig *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete); QStringList fieldList_healpix(KConfig *cfg, const QString& filename, const QString& type, QString *typeSuggestion, bool *complete); } void doTests() { // the data file to use. // first determine the path used to call this program, // and then prepend that to the data file name. QString path = myName.section('/', 0, -3); QString datafile = path; datafile.append("/healpix_example_sm.fits"); // create a temporary config file to use QString cfgfile = "testhealpix.temp"; KConfig *cfg = new KConfig(cfgfile, false, false); cfg->setGroup("Healpix General"); cfg->setGroup(datafile); cfg->writeEntry("Matrix X Dimension", XDIM); cfg->writeEntry("Matrix Y Dimension", YDIM); cfg->writeEntry("Theta Autoscale", true); cfg->writeEntry("Theta Units", 0); cfg->writeEntry("Theta Min", 0.0); cfg->writeEntry("Theta Max", 1.0); cfg->writeEntry("Phi Autoscale", true); cfg->writeEntry("Phi Units", 0); cfg->writeEntry("Phi Min", 0.0); cfg->writeEntry("Phi Max", 1.0); cfg->writeEntry("Vector Theta", 1); cfg->writeEntry("Vector Phi", 2); cfg->writeEntry("Vector Degrade Factor", DEGRADE); cfg->writeEntry("Vector Magnitude Autoscale", true); cfg->writeEntry("Vector Max Magnitude", 1.0); cfg->writeEntry("Vector is QU", true); // use the C functions to test for healpix support int verstehen = understands_healpix(cfg, datafile); if (verstehen) { kstdDebug() << "Data file " << datafile << " is supported" << endl; QString suggestion; bool complete; QStringList matrices = matrixList_healpix(cfg, datafile, "HEALPIX", &suggestion, &complete); kstdDebug() << "Available matrices are:" << endl; for ( QStringList::Iterator it = matrices.begin(); it != matrices.end(); ++it ) { kstdDebug() << " " << *it << endl; } kstdDebug() << " suggestion = " << suggestion << endl; kstdDebug() << " complete = " << complete << endl; QStringList fields = fieldList_healpix(cfg, datafile, "HEALPIX", &suggestion, &complete); kstdDebug() << "Available fields are:" << endl; for ( QStringList::Iterator it = fields.begin(); it != fields.end(); ++it ) { kstdDebug() << " " << *it << endl; } kstdDebug() << " suggestion = " << suggestion << endl; kstdDebug() << " complete = " << complete << endl; // actually create HealpixSource HealpixSource *hpx = new HealpixSource(cfg, datafile, "HEALPIX"); // test that saveConfig produces the same as the // original input configuration QString cfgfile2 = "testhealpix.temp2"; KConfig *chk = new KConfig(cfgfile2, false, false); hpx->saveConfig(chk); StringMap cfgmap = cfg->entryMap(datafile); StringMap chkmap = chk->entryMap(datafile); /* kstdDebug() << cfgmap["Matrix X Dimension"] << " " << chkmap["Matrix X Dimension"] << endl; kstdDebug() << cfgmap["Matrix Y Dimension"] << " " << chkmap["Matrix Y Dimension"] << endl; kstdDebug() << cfgmap["Theta Autoscale"] << " " << chkmap["Theta Autoscale"] << endl; kstdDebug() << cfgmap["Theta Units"] << " " << chkmap["Theta Units"] << endl; kstdDebug() << cfgmap["Theta Min"] << " " << chkmap["Theta Min"] << endl; kstdDebug() << cfgmap["Theta Max"] << " " << chkmap["Theta Max"] << endl; kstdDebug() << cfgmap["Phi Autoscale"] << " " << chkmap["Phi Autoscale"] << endl; kstdDebug() << cfgmap["Phi Units"] << " " << chkmap["Phi Units"] << endl; kstdDebug() << cfgmap["Phi Min"] << " " << chkmap["Phi Min"] << endl; kstdDebug() << cfgmap["Phi Max"] << " " << chkmap["Phi Max"] << endl; kstdDebug() << cfgmap["Vector Theta"] << " " << chkmap["Vector Theta"] << endl; kstdDebug() << cfgmap["Vector Phi"] << " " << chkmap["Vector Phi"] << endl; kstdDebug() << cfgmap["Vector Degrade Factor"] << " " << chkmap["Vector Degrade Factor"] << endl; kstdDebug() << cfgmap["Vector Magnitude Autoscale"] << " " << chkmap["Vector Magnitude Autoscale"] << endl; kstdDebug() << cfgmap["Vector Max Magnitude"] << " " << chkmap["Vector Max Magnitude"] << endl; kstdDebug() << cfgmap["Vector is QU"] << " " << chkmap["Vector is QU"] << endl; */ if (cfgmap["Matrix X Dimension"] != chkmap["Matrix X Dimension"]) { QString msg = "Matrix X Dimension integrity"; testAssert(false, msg); } if (cfgmap["Matrix Y Dimension"] != chkmap["Matrix Y Dimension"]) { QString msg = "Matrix Y Dimension integrity"; testAssert(false, msg); } if (cfgmap["Theta Autoscale"] != chkmap["Theta Autoscale"]) { QString msg = "Theta Autoscale integrity"; testAssert(false, msg); } if (cfgmap["Theta Units"] != chkmap["Theta Units"]) { QString msg = "Theta Units integrity"; testAssert(false, msg); } if (cfgmap["Theta Min"] != chkmap["Theta Min"]) { QString msg = "Theta Min integrity"; testAssert(false, msg); } if (cfgmap["Theta Max"] != chkmap["Theta Max"]) { QString msg = "Theta Max integrity"; testAssert(false, msg); } if (cfgmap["Phi Autoscale"] != chkmap["Phi Autoscale"]) { QString msg = "Phi Autoscale integrity"; testAssert(false, msg); } if (cfgmap["Phi Units"] != chkmap["Phi Units"]) { QString msg = "Phi Units integrity"; testAssert(false, msg); } if (cfgmap["Phi Min"] != chkmap["Phi Min"]) { QString msg = "Phi Min integrity"; testAssert(false, msg); } if (cfgmap["Phi Max"] != chkmap["Phi Max"]) { QString msg = "Phi Max integrity"; testAssert(false, msg); } if (cfgmap["Vector Theta"] != chkmap["Vector Theta"]) { QString msg = "Vector Theta integrity"; testAssert(false, msg); } if (cfgmap["Vector Phi"] != chkmap["Vector Phi"]) { QString msg = "Vector Phi integrity"; testAssert(false, msg); } if (cfgmap["Vector Degrade Factor"] != chkmap["Vector Degrade Factor"]) { QString msg = "Vector Degrade Factor integrity"; testAssert(false, msg); } if (cfgmap["Vector Magnitude Autoscale"] != chkmap["Vector Magnitude Autoscale"]) { QString msg = "Vector Magnitude Autoscale integrity"; testAssert(false, msg); } if (cfgmap["Vector Max Magnitude"] != chkmap["Vector Max Magnitude"]) { QString msg = "Vector Max Magnitude integrity"; testAssert(false, msg); } if (cfgmap["Vector is QU"] != chkmap["Vector is QU"]) { QString msg = "Vector is QU integrity"; testAssert(false, msg); } kstdDebug() << "Save/Load config is consistent." << endl; // print _metaData and compute NSIDE and number // of samples in the vectors int nside = 0; int nvec; QString key; QString data; kstdDebug() << "Checking metaData:" << endl; StringMap metamap = hpx->metaData(); for ( StringMap::Iterator it = metamap.begin(); it != metamap.end(); ++it ) { key = it.key(); data = it.data(); kstdDebug() << " " << key.latin1() << " = " << data.latin1() << endl; if (key == "NSIDE") { nside = data.toInt(); } } kstdDebug() << "Data file has nside = " << nside << endl; testAssert(nside != 0, "data file NSIDE"); for (int i = 0; i < DEGRADE; i++) { nside = (int)(nside/2); } nvec = 12*nside*nside; kstdDebug() << "Degraded vectorfield has nside = " << nside << " and " << nvec << " full-sphere pixels" << endl; // check that all returned fields are valid, and that // optionally field number names are valid. kstdDebug() << "Checking matrix validity:" << endl; int num = 1; int xdim, ydim, nframe, sampframe; for ( QStringList::Iterator it = matrices.begin(); it != matrices.end(); ++it ) { if (hpx->isValidMatrix(*it)) { kstdDebug() << " \"" << *it << "\" is VALID" << endl; hpx->matrixDimensions(*it, &xdim, &ydim); kstdDebug() << " and has dimensions " << xdim << "x" << ydim << endl; testAssert((xdim == XDIM)&&(ydim == YDIM), "dimension integrity"); } else { QString msg = (*it); msg.append(" validity"); testAssert(false, msg); } QString numfield = QString("%1").arg(num); if (hpx->isValidMatrix(numfield)) { kstdDebug() << " \"" << numfield << "\" is VALID" << endl; hpx->matrixDimensions(numfield, &xdim, &ydim); kstdDebug() << " and has dimensions " << xdim << "x" << ydim << endl; testAssert((xdim == XDIM)&&(ydim == YDIM), "dimension integrity"); } else { QString msg = numfield; msg.append(" validity"); testAssert(false, msg); } num++; } kstdDebug() << "Checking field validity:" << endl; num = 1; for ( QStringList::Iterator it = fields.begin(); it != fields.end(); ++it ) { if (hpx->isValidField(*it)) { kstdDebug() << " \"" << *it << "\" is VALID" << endl; nframe = hpx->frameCount(*it); sampframe = hpx->samplesPerFrame(*it); kstdDebug() << " and has " << nframe << " frames of " << sampframe << " sample(s) each" << endl; testAssert(sampframe == 1, "samples per frame"); testAssert(nframe == nvec, "number of frames"); } else { QString msg = (*it); msg.append(" validity"); testAssert(false, msg); } QString numfield = QString("%1").arg(num); if (hpx->isValidField(numfield)) { kstdDebug() << " \"" << numfield << "\" is VALID" << endl; nframe = hpx->frameCount(numfield); sampframe = hpx->samplesPerFrame(numfield); kstdDebug() << " and has " << nframe << " frames of " << sampframe << " sample(s) each" << endl; testAssert(sampframe == 1, "samples per frame"); testAssert(nframe == nvec, "number of frames"); } else { QString msg = numfield; msg.append(" validity"); testAssert(false, msg); } num++; } // check reset function if (hpx->reset()) { kstdDebug() << "Reset function is implemented." << endl; } else { testAssert(false, "reset"); } } else { testAssert(false, "understanding"); } } int main(int argc, char **argv) { atexit(exitHelper); myName = argv[0]; KApplication app(argc, argv, "testhealpix", false, false); doTests(); exitHelper(); // before app dies if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } // vim: ts=2 sw=2 et kst-2.0.3/old_tests/runregression.sh000755 001750 001750 00000003266 11544160210 020136 0ustar00synthsynth000000 000000 #!/bin/sh # VALGRIND= GCOV= if [ "x$1" == "x-g" ]; then GCOV=1 fi if [ "x$1" == "x-v" ]; then VALGRIND="valgrind -v --num-callers=25"; fi if [ "x$1" == "x-t" ]; then VALGRIND="valgrind -v --skin=helgrind --num-callers=25"; fi ######### All settings are above this line CONSOLELOG=`mktemp /tmp/Kst_regressionlog.XXXXXX` || exit 4 echo Logging to $CONSOLELOG make check if [ $? -ne 0 ]; then echo "ERROR BUILDING TESTCASES" exit -1; fi TESTS="testeqparser testhistogram testscalars testlabelparser testrvector testvector healpix/testhealpix" testeqparser_FILES="eparse.y escan.l eparse.c escan.c enodes.cpp enodefactory.cpp" testhistogram_FILES="ksthistogram.cpp" testscalars_FILES="kstscalar.cpp" testlabelparser_FILES="labelparser.cpp" testrvector_FILES="kstrvector.cpp" testvector_FILES="kstvector.cpp" for i in $TESTS; do if [ ! -e $i ]; then echo "ERROR: Couldn't find test $i. Not running." continue; fi echo "-----------------------------------------------------------" >> $CONSOLELOG echo "Running test: $i" >> $CONSOLELOG output=`$VALGRIND ./$i $* 2>&1` FAILED=$? echo "$output" | grep -v QPixmap >>$CONSOLELOG if [ $FAILED -gt 0 ]; then echo "$FAILED testcases failed in $i" | tee -a $CONSOLELOG fi echo >>$CONSOLELOG echo Code coverage: >>$CONSOLELOG pushd ../kst >/dev/null 2>&1 filenames='$'"$i"_FILES; list=`eval echo $filenames` for j in $list; do gcov -o .libs -n $j 2>&1 | while true; do read k if test $? -ne 0; then break; fi echo "$k" | grep "File \`$j'" >/dev/null 2>&1 if test $? -eq 0; then read l echo $j: $l >>$CONSOLELOG break fi done done popd >/dev/null 2>&1 echo >>$CONSOLELOG echo >>$CONSOLELOG done exit 0 kst-2.0.3/old_tests/asciimatrix.txt000644 001750 001750 00000073562 11544160210 017756 0ustar00synthsynth000000 000000 test1 test2 [MATRIX,50,0,0,0.5,0.5] 1.716299 -0.485527 -0.288690 1.716299 -0.476371 -0.274957 1.711721 -0.485527 -0.293267 1.711721 -0.480949 -0.293267 1.716299 -0.494682 -0.284112 1.716299 -0.480949 -0.279535 1.711721 -0.494682 -0.288690 1.707144 -0.490104 -0.284112 1.711721 -0.494682 -0.274957 1.711721 -0.499259 -0.284112 1.707144 -0.503837 -0.288690 1.707144 -0.494682 -0.279535 1.707144 -0.494682 -0.274957 1.707144 -0.503837 -0.279535 1.707144 -0.490104 -0.279535 1.711721 -0.494682 -0.284112 1.702566 -0.499259 -0.288690 1.702566 -0.499259 -0.284112 1.702566 -0.490104 -0.288690 1.697989 -0.490104 -0.293267 1.697989 -0.490104 -0.293267 1.697989 -0.485527 -0.293267 1.697989 -0.485527 -0.297845 1.693411 -0.485527 -0.302423 1.697989 -0.485527 -0.302423 1.693411 -0.490104 -0.307000 1.693411 -0.499259 -0.302423 1.697989 -0.499259 -0.311578 1.693411 -0.499259 -0.297845 1.693411 -0.499259 -0.297845 1.688833 -0.503837 -0.284112 1.684256 -0.503837 -0.274957 1.688833 -0.508415 -0.265802 1.693411 -0.508415 -0.270379 1.679678 -0.494682 -0.256647 1.688833 -0.494682 -0.265802 1.679678 -0.499259 -0.261224 1.665945 -0.490104 -0.265802 1.656790 -0.485527 -0.274957 1.643057 -0.485527 -0.270379 1.620169 -0.490104 -0.279535 1.601859 -0.485527 -0.274957 1.574393 -0.485527 -0.288690 1.551505 -0.485527 -0.284112 1.524040 -0.494682 -0.288690 1.505729 -0.494682 -0.297845 1.478264 -0.494682 -0.311578 1.441643 -0.503837 -0.302423 1.418755 -0.503837 -0.302423 1.386712 -0.508415 -0.297845 1.354669 -0.503837 -0.297845 1.331781 -0.503837 -0.297845 1.290582 -0.494682 -0.297845 1.263117 -0.499259 -0.293267 1.240229 -0.499259 -0.270379 1.203608 -0.494682 -0.279535 1.171565 -0.485527 -0.274957 1.130366 -0.476371 -0.284112 1.098323 -0.480949 -0.279535 1.070857 -0.485527 -0.274957 1.043392 -0.480949 -0.274957 1.006771 -0.476371 -0.279535 0.983883 -0.476371 -0.274957 0.942685 -0.471794 -0.270379 0.915219 -0.476371 -0.270379 0.878598 -0.480949 -0.284112 0.846555 -0.480949 -0.293267 0.809934 -0.480949 -0.293267 0.787046 -0.485527 -0.293267 0.750425 -0.485527 -0.288690 0.727537 -0.480949 -0.302423 0.695494 -0.485527 -0.297845 0.658873 -0.485527 -0.297845 0.640563 -0.480949 -0.307000 0.594787 -0.476371 -0.297845 0.562744 -0.471794 -0.307000 0.521545 -0.476371 -0.302423 0.494080 -0.476371 -0.297845 0.462037 -0.471794 -0.302423 0.429993 -0.471794 -0.297845 0.402528 -0.467216 -0.297845 0.370485 -0.471794 -0.297845 0.333864 -0.471794 -0.284112 0.301821 -0.476371 -0.288690 0.265200 -0.476371 -0.288690 0.237734 -0.476371 -0.284112 0.201113 -0.480949 -0.279535 0.173648 -0.480949 -0.284112 0.137027 -0.480949 -0.279535 0.104984 -0.471794 -0.288690 0.072941 -0.471794 -0.284112 0.040897 -0.476371 -0.274957 -0.004879 -0.471794 -0.284112 -0.032344 -0.469505 -0.288690 -0.059810 -0.467216 -0.293267 -0.096431 -0.467216 -0.293267 -0.123896 -0.462639 -0.297845 -0.151362 -0.458061 -0.307000 -0.192560 -0.462639 -0.297845 -0.229181 -0.462639 -0.307000 -0.261224 -0.462639 -0.307000 -0.288690 -0.467216 -0.302423 -0.320733 -0.471794 -0.302423 -0.357354 -0.471794 -0.311578 -0.380242 -0.476371 -0.311578 -0.421440 -0.480949 -0.307000 -0.444328 -0.476371 -0.302423 -0.476371 -0.476371 -0.311578 -0.512992 -0.476371 -0.297845 -0.545035 -0.476371 -0.288690 -0.577079 -0.490104 -0.288690 -0.604544 -0.471794 -0.284112 -0.641165 -0.458061 -0.284112 -0.664053 -0.462639 -0.279535 -0.709829 -0.462639 -0.274957 -0.737295 -0.458061 -0.288690 -0.769338 -0.462639 -0.279535 -0.796803 -0.453483 -0.284112 -0.833424 -0.448906 -0.297845 -0.865467 -0.453483 -0.297845 -0.888355 -0.462639 -0.288690 -0.924976 -0.458061 -0.297845 -0.961597 -0.467216 -0.297845 -0.993640 -0.467216 -0.316155 -1.034839 -0.462639 -0.297845 -1.062304 -0.467216 -0.307000 -1.080615 -0.480949 -0.316155 -1.117235 -0.462639 -0.320733 -1.158434 -0.467216 -0.307000 -1.185899 -0.467216 -0.311578 -1.227098 -0.471794 -0.316155 -1.249986 -0.467216 -0.307000 -1.286607 -0.453483 -0.307000 -1.314072 -0.458061 -0.311578 -1.346115 -0.458061 -0.302423 -1.382736 -0.448906 -0.293267 -1.405624 -0.448906 -0.293267 -1.442245 -0.444328 -0.293267 -1.465133 -0.453483 -0.293267 -1.501754 -0.453483 -0.284112 -1.538375 -0.453483 -0.279535 -1.561263 -0.458061 -0.284112 -1.588728 -0.462639 -0.288690 -1.616194 -0.453483 -0.284112 -1.652815 -0.462639 -0.284112 -1.689435 -0.458061 -0.288690 -1.707746 -0.453483 -0.288690 -1.739789 -0.453483 -0.293267 -1.753522 -0.453483 -0.302423 -1.790143 -0.444328 -0.302423 -1.817608 -0.444328 -0.307000 -1.840496 -0.439751 -0.316155 -1.863384 -0.439751 -0.311578 -1.881695 -0.435173 -0.320733 -1.913738 -0.435173 -0.325311 -1.941203 -0.448906 -0.325311 -1.959514 -0.439751 -0.311578 -1.991557 -0.444328 -0.311578 -2.005290 -0.453483 -0.316155 -2.032755 -0.453483 -0.302423 -2.064799 -0.448906 -0.311578 -2.078531 -0.462639 -0.311578 -2.101419 -0.458061 -0.302423 -2.119730 -0.458061 -0.307000 -2.142618 -0.453483 -0.302423 -2.165506 -0.453483 -0.288690 -2.188394 -0.453483 -0.288690 -2.202127 -0.444328 -0.307000 -2.225015 -0.444328 -0.297845 -2.243325 -0.444328 -0.293267 -2.270791 -0.439751 -0.293267 -2.284523 -0.435173 -0.293267 -2.302834 -0.435173 -0.302423 -2.321144 -0.430595 -0.302423 -2.339455 -0.435173 -0.302423 -2.366920 -0.439751 -0.307000 -2.389808 -0.439751 -0.302423 -2.403541 -0.448906 -0.311578 -2.426429 -0.439751 -0.307000 -2.440162 -0.444328 -0.316155 -2.458472 -0.458061 -0.316155 -2.481360 -0.448906 -0.334466 -2.490515 -0.448906 -0.325311 -2.499671 -0.458061 -0.329888 -2.527136 -0.448906 -0.325311 -2.540869 -0.448906 -0.311578 -2.554602 -0.444328 -0.311578 -2.568335 -0.439751 -0.316155 -2.586645 -0.444328 -0.311578 -2.591223 -0.444328 -0.307000 -2.614111 -0.439751 -0.302423 -2.623266 -0.453483 -0.307000 -2.636999 -0.444328 -0.293267 -2.641576 -0.448906 -0.293267 -2.646154 -0.458061 -0.293267 -2.664464 -0.444328 -0.293267 -2.664464 -0.453483 -0.293267 -2.669042 -0.462639 -0.293267 -2.682775 -0.458061 -0.297845 -2.687352 -0.453483 -0.307000 -2.696507 -0.448906 -0.307000 -2.705663 -0.435173 -0.316155 -2.701085 -0.430595 -0.316155 -2.710240 -0.426018 -0.316155 -2.714818 -0.416863 -0.307000 -2.733128 -0.421440 -0.307000 -2.719395 -0.416863 -0.311578 -2.719395 -0.421440 -0.311578 -2.728551 -0.421440 -0.307000 -2.733128 -0.421440 -0.311578 -2.728551 -0.430595 -0.311578 -2.728551 -0.444328 -0.311578 -2.733128 -0.453483 -0.311578 -2.737706 -0.458061 -0.320733 -2.728551 -0.462639 -0.311578 -2.737706 -0.471794 -0.316155 -2.733128 -0.467216 -0.316155 -2.728551 -0.471794 -0.316155 -2.737706 -0.462639 -0.320733 -2.733128 -0.458061 -0.320733 -2.723973 -0.453483 -0.311578 -2.733128 -0.439751 -0.311578 -2.728551 -0.435173 -0.320733 -2.723973 -0.426018 -0.307000 -2.728551 -0.421440 -0.307000 -2.719395 -0.416863 -0.297845 -2.719395 -0.421440 -0.293267 -2.719395 -0.412285 -0.297845 -2.710240 -0.416863 -0.297845 -2.719395 -0.430595 -0.293267 -2.710240 -0.430595 -0.316155 -2.714818 -0.435173 -0.297845 -2.723973 -0.435173 -0.302423 -2.719395 -0.439751 -0.307000 -2.714818 -0.453483 -0.316155 -2.719395 -0.448906 -0.316155 -2.714818 -0.444328 -0.325311 -2.714818 -0.448906 -0.320733 -2.719395 -0.439751 -0.329888 -2.705663 -0.439751 -0.334466 -2.701085 -0.448906 -0.316155 -2.710240 -0.435173 -0.311578 -2.710240 -0.430595 -0.316155 -2.705663 -0.435173 -0.311578 -2.705663 -0.426018 -0.293267 -2.705663 -0.444328 -0.302423 -2.696507 -0.453483 -0.302423 -2.701085 -0.448906 -0.288690 -2.687352 -0.448906 -0.302423 -2.691930 -0.453483 -0.307000 -2.696507 -0.458061 -0.302423 -2.687352 -0.462639 -0.311578 -2.691930 -0.458061 -0.311578 -2.696507 -0.453483 -0.320733 -2.691930 -0.453483 -0.316155 -2.691930 -0.458061 -0.329888 -2.687352 -0.435173 -0.325311 -2.691930 -0.430595 -0.329888 -2.691930 -0.421440 -0.325311 -2.687352 -0.421440 -0.316155 -2.687352 -0.421440 -0.311578 -2.678197 -0.412285 -0.307000 -2.682775 -0.412285 -0.302423 -2.678197 -0.416863 -0.293267 -2.678197 -0.416863 -0.288690 -2.673619 -0.421440 -0.293267 -2.659887 -0.435173 -0.293267 -2.669042 -0.442039 -0.300134 -2.678197 -0.448906 -0.307000 -2.673619 -0.453483 -0.316155 -2.673619 -0.467216 -0.320733 -2.673619 -0.471794 -0.320733 -2.673619 -0.471794 -0.334466 -2.669042 -0.471794 -0.339043 -2.669042 -0.476371 -0.334466 -2.673619 -0.467216 -0.348199 -2.669042 -0.458061 -0.334466 -2.669042 -0.453483 -0.325311 -2.664464 -0.444328 -0.329888 -2.673619 -0.435173 -0.316155 -2.659887 -0.430595 -0.311578 -2.659887 -0.430595 -0.297845 -2.659887 -0.416863 -0.279535 -2.655309 -0.416863 -0.284112 -2.650731 -0.416863 -0.284112 -2.655309 -0.426018 -0.279535 -2.659887 -0.416863 -0.279535 -2.655309 -0.416863 -0.279535 -2.650731 -0.435173 -0.297845 -2.659887 -0.439751 -0.311578 -2.655309 -0.444328 -0.311578 -2.655309 -0.453483 -0.320733 -2.646154 -0.462639 -0.352776 -2.650731 -0.467216 -0.343621 -2.650731 -0.467216 -0.339043 -2.650731 -0.467216 -0.348199 -2.650731 -0.476371 -0.334466 -2.655309 -0.458061 -0.334466 -2.655309 -0.458061 -0.325311 -2.646154 -0.453483 -0.307000 -2.650731 -0.453483 -0.307000 -2.641576 -0.444328 -0.293267 -2.650731 -0.430595 -0.284112 -2.636999 -0.439751 -0.279535 -2.646154 -0.430595 -0.274957 -2.646154 -0.430595 -0.284112 -2.641576 -0.430595 -0.284112 -2.646154 -0.421440 -0.284112 -2.646154 -0.421440 -0.293267 -2.646154 -0.426018 -0.297845 -2.641576 -0.430595 -0.307000 -2.641576 -0.444328 -0.334466 -2.641576 -0.444328 -0.334466 -2.646154 -0.448906 -0.343621 -2.646154 -0.439751 -0.343621 -2.646154 -0.448906 -0.343621 -2.636999 -0.448906 -0.325311 -2.636999 -0.458061 -0.334466 -2.636999 -0.453483 -0.329888 -2.636999 -0.448906 -0.316155 -2.641576 -0.448906 -0.316155 -2.641576 -0.448906 -0.302423 -2.636999 -0.444328 -0.284112 -2.646154 -0.448906 -0.293267 -2.632421 -0.439751 -0.279535 -2.627843 -0.439751 -0.288690 -2.636999 -0.439751 -0.288690 -2.627843 -0.439751 -0.288690 -2.646154 -0.444328 -0.297845 -2.641576 -0.435173 -0.307000 -2.641576 -0.448906 -0.316155 -2.646154 -0.435173 -0.316155 -2.641576 -0.439751 -0.334466 -2.641576 -0.444328 -0.334466 -2.641576 -0.435173 -0.339043 -2.636999 -0.435173 -0.329888 -2.641576 -0.444328 -0.325311 -2.632421 -0.439751 -0.325311 -2.636999 -0.439751 -0.320733 -2.627843 -0.435173 -0.311578 -2.623266 -0.435173 -0.293267 -2.632421 -0.435173 -0.288690 -2.627843 -0.430595 -0.293267 -2.632421 -0.426018 -0.288690 -2.627843 -0.435173 -0.288690 -2.623266 -0.439751 -0.288690 -2.632421 -0.430595 -0.302423 -2.650731 -0.444328 -0.302423 -2.636999 -0.448906 -0.302423 -2.632421 -0.453483 -0.320733 -2.632421 -0.453483 -0.320733 -2.632421 -0.453483 -0.325311 -2.636999 -0.467216 -0.334466 -2.636999 -0.458061 -0.325311 -2.627843 -0.462639 -0.325311 -2.632421 -0.458061 -0.325311 -2.627843 -0.462639 -0.325311 -2.627843 -0.458061 -0.320733 -2.618688 -0.453483 -0.311578 -2.627843 -0.439751 -0.307000 -2.623266 -0.435173 -0.302423 -2.618688 -0.430595 -0.297845 -2.623266 -0.430595 -0.288690 -2.623266 -0.421440 -0.293267 -2.618688 -0.416863 -0.293267 -2.614111 -0.416863 -0.288690 -2.627843 -0.421440 -0.293267 -2.627843 -0.421440 -0.311578 -2.627843 -0.430595 -0.302423 -2.627843 -0.444328 -0.311578 -2.632421 -0.444328 -0.325311 -2.636999 -0.453483 -0.320733 -2.632421 -0.453483 -0.329888 -2.623266 -0.462639 -0.329888 -2.627843 -0.458061 -0.329888 -2.627843 -0.471794 -0.334466 -2.614111 -0.458061 -0.329888 -2.618688 -0.453483 -0.311578 -2.627843 -0.453483 -0.316155 -2.623266 -0.458061 -0.302423 -2.623266 -0.444328 -0.297845 -2.618688 -0.439751 -0.302423 -2.614111 -0.435173 -0.297845 -2.623266 -0.421440 -0.297845 -2.614111 -0.426018 -0.302423 -2.618688 -0.416863 -0.293267 -2.609533 -0.421440 -0.302423 -2.627843 -0.421440 -0.297845 -2.623266 -0.426018 -0.316155 -2.618688 -0.430595 -0.325311 -2.618688 -0.426018 -0.311578 -2.623266 -0.435173 -0.325311 -2.623266 -0.439751 -0.320733 -2.614111 -0.444328 -0.320733 -2.618688 -0.453483 -0.320733 -2.623266 -0.453483 -0.316155 -2.618688 -0.458061 -0.307000 -2.609533 -0.453483 -0.316155 -2.600378 -0.458061 -0.302423 -2.586645 -0.453483 -0.302423 -2.568335 -0.448906 -0.307000 -2.559179 -0.444328 -0.297845 -2.531714 -0.444328 -0.302423 -2.517981 -0.448906 -0.316155 -2.504248 -0.448906 -0.307000 -2.472205 -0.444328 -0.311578 -2.449317 -0.444328 -0.311578 -2.421851 -0.444328 -0.316155 -2.394386 -0.444328 -0.316155 -2.366920 -0.439751 -0.316155 -2.344032 -0.444328 -0.320733 -2.311989 -0.448906 -0.320733 -2.279946 -0.439751 -0.316155 -2.252480 -0.444328 -0.329888 -2.220437 -0.444328 -0.311578 -2.188394 -0.435173 -0.297845 -2.147195 -0.435173 -0.297845 -2.105997 -0.435173 -0.288690 -2.073954 -0.435173 -0.288690 -2.046488 -0.439751 -0.270379 -2.019023 -0.439751 -0.288690 -1.977824 -0.435173 -0.293267 -1.945781 -0.435173 -0.293267 -1.922893 -0.435173 -0.284112 -1.886272 -0.444328 -0.297845 -1.858807 -0.453483 -0.297845 -1.822186 -0.453483 -0.302423 -1.776410 -0.458061 -0.316155 -1.748944 -0.467216 -0.320733 -1.712323 -0.467216 -0.329888 -1.689435 -0.467216 -0.316155 -1.648237 -0.471794 -0.343621 -1.616194 -0.480949 -0.316155 -1.579573 -0.462639 -0.329888 -1.542952 -0.467216 -0.316155 -1.515487 -0.458061 -0.316155 -1.478866 -0.448906 -0.307000 -1.442245 -0.444328 -0.300134 -1.405624 -0.439751 -0.293267 -1.382736 -0.439751 -0.293267 -1.336960 -0.439751 -0.284112 -1.309495 -0.430595 -0.284112 -1.263719 -0.426018 -0.279535 -1.236253 -0.426018 -0.279535 -1.204210 -0.435173 -0.265802 -1.172167 -0.439751 -0.288690 -1.140123 -0.444328 -0.284112 -1.108080 -0.448906 -0.297845 -1.080615 -0.453483 -0.297845 -1.039416 -0.467216 -0.307000 -1.007373 -0.467216 -0.307000 -0.975330 -0.471794 -0.311578 -0.957019 -0.476371 -0.325311 -0.920399 -0.476371 -0.320733 -0.888355 -0.476371 -0.316155 -0.856312 -0.471794 -0.320733 -0.824269 -0.471794 -0.311578 -0.792226 -0.462639 -0.302423 -0.760183 -0.462639 -0.316155 -0.718984 -0.458061 -0.297845 -0.686941 -0.458061 -0.297845 -0.659475 -0.458061 -0.279535 -0.627432 -0.444328 -0.293267 -0.586234 -0.448906 -0.288690 -0.563346 -0.448906 -0.293267 -0.535880 -0.453483 -0.288690 -0.494682 -0.448906 -0.288690 -0.471794 -0.458061 -0.293267 -0.435173 -0.458061 -0.288690 -0.407707 -0.453483 -0.288690 -0.366509 -0.462639 -0.293267 -0.343621 -0.462639 -0.293267 -0.307000 -0.467216 -0.297845 -0.274957 -0.471794 -0.288690 -0.247491 -0.471794 -0.288690 -0.206293 -0.471794 -0.279535 -0.178827 -0.471794 -0.288690 -0.155939 -0.471794 -0.284112 -0.119319 -0.471794 -0.297845 -0.082698 -0.471794 -0.284112 -0.046077 -0.471794 -0.279535 -0.018611 -0.467216 -0.293267 0.008854 -0.467216 -0.293267 0.045475 -0.471794 -0.297845 0.077518 -0.476371 -0.311578 0.104984 -0.476371 -0.302423 0.141605 -0.476371 -0.311578 0.173648 -0.471794 -0.302423 0.196536 -0.467216 -0.302423 0.237734 -0.471794 -0.316155 0.269777 -0.471794 -0.307000 0.301821 -0.471794 -0.307000 0.329286 -0.471794 -0.307000 0.365907 -0.471794 -0.293267 0.397950 -0.458061 -0.284112 0.434571 -0.458061 -0.284112 0.457459 -0.458061 -0.265802 0.498657 -0.458061 -0.265802 0.530701 -0.462639 -0.270379 0.562744 -0.462639 -0.265802 0.599365 -0.458061 -0.256647 0.626830 -0.462639 -0.256647 0.654296 -0.471794 -0.261224 0.690917 -0.476371 -0.265802 0.727537 -0.476371 -0.270379 0.759581 -0.480949 -0.284112 0.791624 -0.490104 -0.279535 0.819089 -0.490104 -0.293267 0.851133 -0.499259 -0.297845 0.883176 -0.494682 -0.302423 0.915219 -0.499259 -0.316155 0.951840 -0.490104 -0.320733 0.988461 -0.490104 -0.320733 1.015926 -0.485527 -0.307000 1.047969 -0.485527 -0.302423 1.082301 -0.480949 -0.300134 1.116633 -0.476371 -0.297845 1.162409 -0.471794 -0.284112 1.194453 -0.458061 -0.270379 1.226496 -0.467216 -0.270379 1.249384 -0.462639 -0.265802 1.295160 -0.462639 -0.270379 1.318048 -0.471794 -0.261224 1.350091 -0.471794 -0.270379 1.386712 -0.480949 -0.261224 1.418755 -0.485527 -0.270379 1.450798 -0.480949 -0.270379 1.473686 -0.494682 -0.284112 1.510307 -0.499259 -0.284112 1.542350 -0.499259 -0.270379 1.560661 -0.499259 -0.284112 1.597281 -0.499259 -0.302423 1.620169 -0.494682 -0.284112 1.638480 -0.499259 -0.288690 1.656790 -0.499259 -0.284112 1.675101 -0.494682 -0.293267 1.684256 -0.490104 -0.288690 1.707144 -0.499259 -0.297845 1.720877 -0.485527 -0.288690 1.734609 -0.485527 -0.288690 1.748342 -0.485527 -0.293267 1.762075 -0.485527 -0.288690 1.757497 -0.476371 -0.284112 1.757497 -0.490104 -0.288690 1.780385 -0.480949 -0.288690 1.784963 -0.480949 -0.288690 1.789541 -0.480949 -0.288690 1.798696 -0.490104 -0.288690 1.807851 -0.490104 -0.284112 1.812429 -0.485527 -0.274957 1.817006 -0.485527 -0.284112 1.826161 -0.485527 -0.270379 1.839894 -0.494682 -0.270379 1.830739 -0.490104 -0.274957 1.839894 -0.494682 -0.274957 1.844472 -0.490104 -0.265802 1.849049 -0.494682 -0.274957 1.849049 -0.490104 -0.270379 1.853627 -0.494682 -0.279535 1.853627 -0.499259 -0.270379 1.862782 -0.494682 -0.284112 1.858205 -0.503837 -0.288690 1.858205 -0.512992 -0.293267 1.858205 -0.508415 -0.302423 1.858205 -0.508415 -0.307000 1.858205 -0.517570 -0.311578 1.858205 -0.512992 -0.302423 1.849049 -0.508415 -0.307000 1.853627 -0.508415 -0.311578 1.853627 -0.503837 -0.307000 1.862782 -0.503837 -0.297845 1.862782 -0.499259 -0.284112 1.862782 -0.490104 -0.279535 1.858205 -0.480949 -0.270379 1.858205 -0.480949 -0.274957 1.862782 -0.480949 -0.279535 1.858205 -0.485527 -0.265802 1.862782 -0.471794 -0.261224 1.867360 -0.476371 -0.261224 1.853627 -0.485527 -0.256647 1.862782 -0.485527 -0.265802 1.858205 -0.494682 -0.265802 1.853627 -0.499259 -0.284112 1.858205 -0.503837 -0.265802 1.849049 -0.503837 -0.284112 1.858205 -0.508415 -0.274957 1.853627 -0.517570 -0.297845 1.849049 -0.531303 -0.293267 1.844472 -0.517570 -0.302423 1.849049 -0.508415 -0.311578 1.844472 -0.512992 -0.307000 1.844472 -0.503837 -0.307000 1.849049 -0.508415 -0.293267 1.844472 -0.499259 -0.302423 1.844472 -0.494682 -0.288690 1.839894 -0.490104 -0.288690 1.849049 -0.485527 -0.274957 1.844472 -0.480949 -0.279535 1.826161 -0.480949 -0.279535 1.835317 -0.480949 -0.270379 1.835317 -0.485527 -0.279535 1.839894 -0.476371 -0.270379 1.835317 -0.485527 -0.279535 1.839894 -0.490104 -0.279535 1.835317 -0.494682 -0.284112 1.839894 -0.494682 -0.279535 1.835317 -0.503837 -0.284112 1.835317 -0.503837 -0.288690 1.830739 -0.512992 -0.284112 1.830739 -0.508415 -0.284112 1.826161 -0.503837 -0.288690 1.826161 -0.508415 -0.288690 1.826161 -0.503837 -0.279535 1.821584 -0.499259 -0.284112 1.826161 -0.494682 -0.284112 1.830739 -0.485527 -0.270379 1.826161 -0.485527 -0.284112 1.821584 -0.485527 -0.274957 1.821584 -0.476371 -0.288690 1.812429 -0.485527 -0.297845 1.821584 -0.485527 -0.288690 1.807851 -0.490104 -0.288690 1.812429 -0.490104 -0.297845 1.807851 -0.494682 -0.307000 1.803273 -0.499259 -0.297845 1.807851 -0.503837 -0.293267 1.807851 -0.508415 -0.297845 1.812429 -0.508415 -0.302423 1.817006 -0.508415 -0.293267 1.798696 -0.499259 -0.297845 1.812429 -0.499259 -0.288690 1.807851 -0.499259 -0.284112 1.817006 -0.485527 -0.284112 1.812429 -0.490104 -0.270379 1.798696 -0.476371 -0.284112 1.803273 -0.471794 -0.265802 1.798696 -0.476371 -0.270379 1.798696 -0.476371 -0.261224 1.807851 -0.476371 -0.274957 1.803273 -0.485527 -0.270379 1.794118 -0.490104 -0.274957 1.798696 -0.490104 -0.284112 1.794118 -0.508415 -0.279535 1.780385 -0.499259 -0.302423 1.789541 -0.503837 -0.307000 1.780385 -0.508415 -0.307000 1.789541 -0.517570 -0.307000 1.784963 -0.512992 -0.302423 1.794118 -0.508415 -0.302423 1.794118 -0.494682 -0.297845 1.780385 -0.499259 -0.302423 1.798696 -0.490104 -0.293267 1.794118 -0.499259 -0.279535 1.794118 -0.485527 -0.274957 1.789541 -0.480949 -0.265802 1.789541 -0.476371 -0.265802 1.794118 -0.476371 -0.274957 1.789541 -0.480949 -0.256647 1.789541 -0.480949 -0.261224 1.784963 -0.485527 -0.270379 1.784963 -0.490104 -0.270379 1.775808 -0.485527 -0.270379 1.771230 -0.494682 -0.270379 1.771230 -0.494682 -0.284112 1.775808 -0.499259 -0.288690 1.780385 -0.508415 -0.284112 1.775808 -0.508415 -0.288690 1.775808 -0.503837 -0.293267 1.771230 -0.508415 -0.297845 1.775808 -0.503837 -0.284112 1.771230 -0.503837 -0.293267 1.771230 -0.503837 -0.284112 1.762075 -0.494682 -0.274957 1.771230 -0.494682 -0.288690 1.766653 -0.494682 -0.297845 1.771230 -0.485527 -0.297845 1.766653 -0.480949 -0.288690 1.771230 -0.480949 -0.293267 1.762075 -0.480949 -0.293267 1.762075 -0.485527 -0.293267 1.762075 -0.490104 -0.284112 1.762075 -0.490104 -0.279535 1.762075 -0.503837 -0.284112 1.762075 -0.503837 -0.274957 1.766653 -0.503837 -0.284112 1.757497 -0.503837 -0.279535 1.752920 -0.503837 -0.279535 1.752920 -0.503837 -0.279535 1.748342 -0.503837 -0.293267 1.752920 -0.499259 -0.274957 1.752920 -0.485527 -0.288690 1.752920 -0.485527 -0.284112 1.743765 -0.485527 -0.279535 1.734609 -0.476371 -0.288690 1.752920 -0.476371 -0.293267 1.739187 -0.485527 -0.288690 1.748342 -0.490104 -0.288690 1.748342 -0.480949 -0.297845 1.743765 -0.485527 -0.293267 1.739187 -0.494682 -0.297845 1.739187 -0.499259 -0.293267 1.743765 -0.503837 -0.297845 1.739187 -0.494682 -0.284112 1.734609 -0.499259 -0.293267 1.730032 -0.512992 -0.297845 1.739187 -0.503837 -0.293267 1.730032 -0.499259 -0.293267 1.734609 -0.499259 -0.284112 1.732321 -0.501548 -0.279535 1.730032 -0.503837 -0.274957 1.725454 -0.485527 -0.284112 1.720877 -0.480949 -0.274957 1.730032 -0.480949 -0.279535 1.730032 -0.471794 -0.265802 1.720877 -0.480949 -0.279535 1.734609 -0.476371 -0.279535 1.730032 -0.476371 -0.270379 1.730032 -0.480949 -0.279535 1.748342 -0.485527 -0.279535 1.716299 -0.494682 -0.288690 1.711721 -0.499259 -0.302423 1.716299 -0.499259 -0.284112 1.711721 -0.512992 -0.293267 1.711721 -0.512992 -0.307000 1.716299 -0.512992 -0.297845 1.711721 -0.503837 -0.293267 1.716299 -0.508415 -0.288690 1.711721 -0.508415 -0.293267 1.716299 -0.501548 -0.290979 1.720877 -0.494682 -0.288690 1.697989 -0.490104 -0.288690 1.711721 -0.490104 -0.288690 1.716299 -0.476371 -0.274957 1.707144 -0.476371 -0.284112 1.711721 -0.480949 -0.261224 1.711721 -0.480949 -0.279535 1.711721 -0.476371 -0.270379 1.711721 -0.476371 -0.270379 1.702566 -0.485527 -0.270379 1.707144 -0.490104 -0.284112 1.702566 -0.499259 -0.270379 1.702566 -0.503837 -0.270379 1.707144 -0.503837 -0.284112 1.702566 -0.503837 -0.279535 1.697989 -0.499259 -0.284112 1.707144 -0.503837 -0.284112 1.697989 -0.494682 -0.284112 1.688833 -0.490104 -0.302423 1.697989 -0.494682 -0.288690 1.693411 -0.490104 -0.307000 1.697989 -0.485527 -0.297845 1.693411 -0.485527 -0.302423 1.693411 -0.490104 -0.288690 1.688833 -0.490104 -0.284112 1.688833 -0.494682 -0.274957 1.679678 -0.499259 -0.284112 1.693411 -0.508415 -0.274957 1.697989 -0.494682 -0.270379 1.693411 -0.508415 -0.293267 1.688833 -0.508415 -0.288690 1.684256 -0.508415 -0.279535 1.693411 -0.512992 -0.284112 1.688833 -0.503837 -0.279535 1.684256 -0.503837 -0.284112 1.688833 -0.499259 -0.274957 1.684256 -0.494682 -0.284112 1.675101 -0.490104 -0.279535 1.670523 -0.485527 -0.284112 1.661368 -0.485527 -0.279535 1.647635 -0.471794 -0.284112 1.633902 -0.480949 -0.297845 1.620169 -0.476371 -0.293267 1.601859 -0.476371 -0.297845 1.569816 -0.485527 -0.297845 1.546928 -0.485527 -0.288690 1.524040 -0.494682 -0.297845 1.496574 -0.494682 -0.297845 1.469109 -0.503837 -0.293267 1.441643 -0.494682 -0.297845 1.414177 -0.508415 -0.302423 1.391289 -0.517570 -0.297845 1.345513 -0.508415 -0.288690 1.327203 -0.512992 -0.293267 1.295160 -0.508415 -0.288690 1.263117 -0.512992 -0.302423 1.235651 -0.494682 -0.284112 1.199030 -0.480949 -0.274957 1.166987 -0.490104 -0.288690 1.130366 -0.471794 -0.284112 1.102901 -0.471794 -0.288690 1.070857 -0.467216 -0.284112 1.038814 -0.471794 -0.288690 1.011349 -0.471794 -0.284112 0.974728 -0.471794 -0.284112 0.942685 -0.467216 -0.279535 0.910641 -0.476371 -0.284112 0.878598 -0.480949 -0.293267 0.855710 -0.485527 -0.297845 0.823667 -0.485527 -0.293267 0.791624 -0.490104 -0.288690 0.759581 -0.494682 -0.293267 0.718382 -0.490104 -0.297845 0.690917 -0.485527 -0.293267 0.654296 -0.490104 -0.293267 0.626830 -0.494682 -0.307000 0.594787 -0.485527 -0.302423 0.553589 -0.480949 -0.293267 0.526123 -0.480949 -0.297845 0.494080 -0.485527 -0.284112 0.462037 -0.476371 -0.288690 0.434571 -0.471794 -0.279535 0.402528 -0.476371 -0.284112 0.370485 -0.467216 -0.297845 0.333864 -0.476371 -0.274957 0.306398 -0.471794 -0.288690 0.265200 -0.471794 -0.288690 0.233157 -0.480949 -0.284112 0.196536 -0.471794 -0.279535 0.169070 -0.467216 -0.293267 0.132449 -0.471794 -0.293267 0.104984 -0.467216 -0.293267 0.063785 -0.467216 -0.297845 0.036320 -0.471794 -0.284112 0.013432 -0.462639 -0.307000 -0.027767 -0.467216 -0.307000 -0.059810 -0.462639 -0.307000 -0.087275 -0.458061 -0.302423 -0.123896 -0.467216 -0.293267 -0.165095 -0.458061 -0.293267 -0.197138 -0.462639 -0.288690 -0.224603 -0.462639 -0.293267 -0.252069 -0.467216 -0.293267 -0.284112 -0.467216 -0.293267 -0.325311 -0.480949 -0.288690 -0.343621 -0.485527 -0.288690 -0.389397 -0.480949 -0.293267 -0.421440 -0.476371 -0.284112 -0.458061 -0.485527 -0.284112 -0.485527 -0.480949 -0.288690 -0.522147 -0.485527 -0.284112 -0.545035 -0.476371 -0.293267 -0.581656 -0.471794 -0.297845 -0.609122 -0.471794 -0.293267 -0.645743 -0.458061 -0.293267 -0.682363 -0.462639 -0.293267 -0.718984 -0.453483 -0.297845 -0.741872 -0.448906 -0.288690 -0.769338 -0.444328 -0.297845 -0.801381 -0.444328 -0.293267 -0.838002 -0.444328 -0.297845 -0.865467 -0.453483 -0.297845 -0.897511 -0.448906 -0.293267 -0.938709 -0.458061 -0.302423 -0.966175 -0.458061 -0.297845 -1.002795 -0.471794 -0.293267 -1.030261 -0.467216 -0.297845 -1.062304 -0.471794 -0.307000 -1.094347 -0.471794 -0.302423 -1.126391 -0.476371 -0.297845 -1.167589 -0.476371 -0.302423 -1.190477 -0.471794 -0.307000 -1.227098 -0.471794 -0.293267 -1.259141 -0.471794 -0.297845 -1.288895 -0.467216 -0.297845 -1.318650 -0.462639 -0.297845 -1.350693 -0.453483 -0.297845 -1.387314 -0.458061 -0.307000 -1.419357 -0.444328 -0.293267 -1.451400 -0.448906 -0.302423 -1.483443 -0.444328 -0.297845 -1.520064 -0.448906 -0.297845 -1.547530 -0.453483 -0.297845 -1.584151 -0.444328 -0.302423 -1.611616 -0.448906 -0.302423 -1.639082 -0.453483 -0.302423 -1.671125 -0.458061 -0.311578 -1.694013 -0.453483 -0.302423 -1.721479 -0.453483 -0.316155 -1.762677 -0.453483 -0.316155 -1.780987 -0.458061 -0.307000 -1.808453 -0.448906 -0.320733 -1.822186 -0.458061 -0.320733 -1.863384 -0.444328 -0.307000 -1.886272 -0.448906 -0.307000 -1.913738 -0.448906 -0.302423 -1.932048 -0.448906 -0.297845 -1.959514 -0.458061 -0.297845 -1.982402 -0.453483 -0.302423 -2.009867 -0.453483 -0.297845 -2.032755 -0.453483 -0.302423 -2.055643 -0.444328 -0.302423 -2.083109 -0.453483 -0.302423 -2.096842 -0.448906 -0.302423 -2.115152 -0.448906 -0.307000 -2.138040 -0.439751 -0.307000 -2.165506 -0.448906 -0.316155 -2.188394 -0.444328 -0.320733 -2.206704 -0.435173 -0.316155 -2.225015 -0.439751 -0.311578 -2.261635 -0.430595 -0.320733 -2.275368 -0.439751 -0.311578 -2.293679 -0.426018 -0.302423 -2.316567 -0.426018 -0.307000 -2.330299 -0.426018 -0.311578 -2.348610 -0.435173 -0.293267 -2.376075 -0.435173 -0.297845 -2.389808 -0.439751 -0.307000 -2.408119 -0.444328 -0.297845 -2.435584 -0.444328 -0.302423 -2.449317 -0.467216 -0.288690 -2.472205 -0.448906 -0.297845 -2.490515 -0.458061 -0.297845 -2.499671 -0.458061 -0.316155 -2.531714 -0.458061 -0.316155 -2.540869 -0.448906 -0.325311 -2.559179 -0.462639 -0.320733 -2.572912 -0.453483 -0.316155 -2.591223 -0.448906 -0.316155 -2.600378 -0.453483 -0.311578 -2.618688 -0.444328 -0.311578 -2.623266 -0.439751 -0.311578 -2.646154 -0.444328 -0.316155 -2.655309 -0.435173 -0.311578 -2.659887 -0.435173 -0.297845 -2.669042 -0.435173 -0.302423 -2.678197 -0.426018 -0.302423 -2.682775 -0.430595 -0.307000 -2.701085 -0.426018 -0.307000 -2.701085 -0.426018 -0.311578 -2.705663 -0.435173 -0.316155 -2.710240 -0.421440 -0.311578 -2.714818 -0.426018 -0.311578 -2.719395 -0.435173 -0.316155 -2.723973 -0.435173 -0.307000 -2.733128 -0.430595 -0.316155 -2.728551 -0.439751 -0.316155 -2.737706 -0.439751 -0.320733 -2.737706 -0.448906 -0.316155 -2.737706 -0.453483 -0.307000 -2.733128 -0.453483 -0.302423 -2.728551 -0.453483 -0.311578 -2.733128 -0.458061 -0.311578 -2.746861 -0.458061 -0.307000 -2.737706 -0.458061 -0.316155 -2.742283 -0.453483 -0.316155 -2.746861 -0.444328 -0.316155 -2.746861 -0.444328 -0.311578 -2.742283 -0.435173 -0.320733 -2.746861 -0.430595 -0.311578 -2.733128 -0.430595 -0.320733 -2.737706 -0.430595 -0.329888 -2.737706 -0.416863 -0.316155 -2.723973 -0.421440 -0.311578 -2.737706 -0.416863 -0.320733 -2.733128 -0.421440 -0.311578 -2.719395 -0.426018 -0.297845 -2.728551 -0.430595 -0.316155 -2.737706 -0.435173 -0.307000 -2.719395 -0.448906 -0.297845 -2.728551 -0.444328 -0.293267 -2.723973 -0.448906 -0.293267 -2.719395 -0.462639 -0.307000 -2.723973 -0.453483 -0.307000 -2.728551 -0.448906 -0.325311 -2.723973 -0.458061 -0.320733 -2.719395 -0.448906 -0.320733 -2.719395 -0.444328 -0.316155 -2.714818 -0.439751 -0.320733 -2.719395 -0.439751 -0.320733 -2.714818 -0.426018 -0.320733 -2.701085 -0.439751 -0.325311 -2.705663 -0.430595 -0.316155 -2.705663 -0.439751 -0.325311 -2.705663 -0.430595 -0.316155 -2.705663 -0.435173 -0.316155 -2.701085 -0.444328 -0.320733 -2.691930 -0.448906 -0.311578 -2.691930 -0.448906 -0.320733 -2.701085 -0.453483 -0.307000 -2.691930 -0.448906 -0.316155 -2.696507 -0.444328 -0.311578 -2.696507 -0.448906 -0.325311 -2.682775 -0.444328 -0.325311 -2.696507 -0.435173 -0.320733 -2.678197 -0.439751 -0.325311 -2.682775 -0.435173 -0.325311 -2.682775 -0.426018 -0.311578 -2.682775 -0.430595 -0.302423 -2.682775 -0.421440 -0.311578 -2.687352 -0.430595 -0.302423 -2.678197 -0.439751 -0.297845 -2.673619 -0.439751 -0.307000 -2.678197 -0.444328 -0.302423 -2.678197 -0.453483 -0.293267 -2.678197 -0.453483 -0.302423 -2.669042 -0.458061 -0.297845 -2.673619 -0.458061 -0.307000 -2.678197 -0.458061 -0.316155 -2.669042 -0.462639 -0.329888 kst-2.0.3/old_tests/testpsd.cpp000644 001750 001750 00000013562 11544160210 017064 0ustar00synthsynth000000 000000 /* * Copyright 2006, The University of Toronto * Licensed under GPL. */ #include "ksttestcase.h" #include "kstpsd.h" #include "kstdataobject.h" #include #include #include #include #include static void exitHelper() { // TODO: garbage collection. } int rc = KstTestSuccess; #define doTest(x) testAssert(x, QString("Line %1").arg(__LINE__)) #define doTestD(x, y) testAssert(x, QString("%1: %2").arg(__LINE__).arg(y)) void testAssert(bool result, const QString& text = "Unknown") { if (!result) { KstTestFailed(); printf("Test [%s] failed.\n", text.toLatin1().data()); } } QDomDocument makeDOMElement(const QString& tag, const QString& val) { // Should be some boundary checking in the constructor. QDomDocument psdDOM("psddocument"); QDomElement psdElement, child; QDomText text; psdElement = psdDOM.createElement("psdDOMTest"); child = psdDOM.createElement("tag"); text = psdDOM.createTextNode(tag); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("vectag"); text = psdDOM.createTextNode(val); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("sampRate"); text = psdDOM.createTextNode("128"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("average"); text = psdDOM.createTextNode("1"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("fiftLen"); text = psdDOM.createTextNode("5"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("adopize"); text = psdDOM.createTextNode("0"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("apodizefxn"); text = psdDOM.createTextNode("WindowOriginal"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("gaussiansigma"); text = psdDOM.createTextNode("0.01"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("removeMean"); text = psdDOM.createTextNode("1"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("VUnits"); text = psdDOM.createTextNode("vUnits"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("RUnits"); text = psdDOM.createTextNode("rUnits"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("output"); text = psdDOM.createTextNode("PSDAmplitudeSpectralDensity"); child.appendChild(text); psdElement.appendChild(child); child = psdDOM.createElement("interpolateHoles"); text = psdDOM.createTextNode("1"); child.appendChild(text); psdElement.appendChild(child); psdDOM.appendChild(psdElement); return psdDOM; } void doTests() { KstVectorPtr vp = new KstVector(KstObjectTag::fromString("tempVector"), 10); for (int i = 0; i < 10; i++){ vp->value()[i] = i; } KstPSDPtr psd = new KstPSD(QString("psdTest"), vp, 0.0, false, 10, false, false, QString("vUnits"), QString("rUnits"), WindowUndefined, 0.0, PSDUndefined); doTest(psd->tagName() == "psdTest"); doTest(psd->vTag() == "tempVector"); doTest(psd->output() == PSDUndefined); doTest(!psd->apodize()); doTest(!psd->removeMean()); doTest(!psd->average()); doTest(psd->freq() == 0.0); doTest(psd->apodizeFxn() == WindowUndefined); doTest(psd->gaussianSigma() == 0); KstVectorPtr vpVX = psd->vX(); KstVectorPtr vpVY = psd->vY(); doTest(vpVX->length() == 1); doTest(vpVX->value()[0] != vpVX->value()[0]); doTest(vpVY->length() == 1); doTest(vpVY->value()[0] != vpVY->value()[0]); psd->writeLock(); doTest(psd->update(0) == KstObject::UPDATE); psd->unlock(); for(int j = 0; j < vpVX->length(); j++){ doTest(vpVX->value()[j] == 0); } psd->setOutput(PSDAmplitudeSpectralDensity); psd->setApodize(true); psd->setRemoveMean(true); psd->setAverage(true); psd->setFreq(0.1); psd->setApodizeFxn(WindowOriginal); psd->setGaussianSigma(0.2); doTest(psd->tagName() == "psdTest"); doTest(psd->vTag() == "tempVector"); doTest(psd->output() == PSDAmplitudeSpectralDensity); doTest(psd->apodize()); doTest(psd->removeMean()); doTest(psd->average()); doTest(psd->freq() == 0.1); doTest(psd->apodizeFxn() == WindowOriginal); doTest(psd->gaussianSigma() == 0.2); // doTest(psd->update(0) == KstObject::UPDATE); // QString ps = "PSD: " + psd->vTag(); // doTest(psd->propertyString() == ps); // doTest(!psd->curveHints().curveName() == ""); // printf("Curve name [%s]", kstCHL[0].curveName()); // printf("X Vector name [%s]", kstCHL[0].xVectorName()); // printf("Y Vector name [%s]", kstCHL[0].yVectorName()); QTemporaryFile tf; tf.open(); QTextStream ts(&tf); psd->save(ts, ""); QFile::remove(tf.fileName()); QDomNode n = makeDOMElement("psdDOMPsd", "psdDOMVector").firstChild(); QDomElement e = n.toElement(); KstPSDPtr psdDOM = new KstPSD(e); doTest(psdDOM->tagName() == "psdDOMPsd"); doTest(psdDOM->output() == PSDAmplitudeSpectralDensity); doTest(psdDOM->apodize()); doTest(psdDOM->removeMean()); doTest(psdDOM->average()); doTest(psdDOM->freq() == 128); doTest(psdDOM->apodizeFxn() == WindowOriginal); doTest(psdDOM->gaussianSigma() == 0.01); // KstVectorPtr vpVX = psdDOM->vX(); // for(int j = 0; j < vpVX->length(); j++){ // printf("[%d][%lf]", j, vpVX->value()[j]); // } // KstVectorPtr vpVY = psdDOM->vY(); } int main(int argc, char **argv) { atexit(exitHelper); QCoreApplication app(argc, argv); doTests(); // Don't put tests in main because we need to ensure that no KstObjects // remain past the exit handler exitHelper(); // need to run it here before kapp goes away in some cases. if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } // vim: ts=2 sw=2 et kst-2.0.3/old_tests/testamatrix.cpp000644 001750 001750 00000021245 11544160210 017740 0ustar00synthsynth000000 000000 /* * Copyright 2005, The University of Toronto * Licensed under GPL. */ #include "ksttestcase.h" #include #include #include static void exitHelper() { KST::matrixList.clear(); KST::scalarList.clear(); KST::dataObjectList.clear(); } int rc = KstTestSuccess; #define doTest(x) testAssert(x, QString("Line %1").arg(__LINE__)) #define doTestD(x, y) testAssert(x, QString("%1: %2").arg(__LINE__).arg(y)) void testAssert(bool result, const QString& text = "Unknown") { if (!result) { KstTestFailed(); printf("Test [%s] failed.\n", text.toLatin1().data()); } } QDomDocument makeDOMElement(const QString& tag, const int nx, const int ny, const double xmin, const double ymin, const double xstep, const double ystep, const int dataSize) { // Should be some boundary checking in the constructor. QDomDocument amDOM("amdocument"); QDomElement amElement, child, dataset; QDomText text; amElement = amDOM.createElement("amDOMTest"); child = amDOM.createElement("tag"); text = amDOM.createTextNode(tag); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("nx"); text = amDOM.createTextNode(QString::number(nx)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("ny"); text = amDOM.createTextNode(QString::number(ny)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("xmin"); text = amDOM.createTextNode(QString::number(xmin)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("ymin"); text = amDOM.createTextNode(QString::number(ymin)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("xstep"); text = amDOM.createTextNode(QString::number(xstep)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("ystep"); text = amDOM.createTextNode(QString::number(ystep)); child.appendChild(text); amElement.appendChild(child); child = amDOM.createElement("data"); QByteArray qba; qba.reserve(dataSize*sizeof(double)); QDataStream qds(&qba, QIODevice::WriteOnly); for (int i = 0; i < dataSize; i++) { qds << 1.1; } text = amDOM.createTextNode(QString(qCompress(qba).toBase64())); child.appendChild(text); amElement.appendChild(child); amDOM.appendChild(amElement); return amDOM; } void doTests() { bool ok = true; QDomNode n = makeDOMElement("amDOM", 0, 0, 0, 0, 1, 1, 9).firstChild(); QDomElement e = n.toElement(); //basic default constructor values KstAMatrix* am1 = new KstAMatrix(e); doTest(am1->tagName().startsWith("amDOM")); doTest(am1->sampleCount() == 0); doTest(am1->minValue() == 0); doTest(am1->maxValue() == 0); doTest(am1->value(0, 0, &ok) == 0); doTest(!ok); doTest(am1->value(10, 10, &ok) == 0); //should be outside the boundaries. doTest(!ok); doTest(am1->sampleCount() == 0); doTest(am1->meanValue() == 0); //basic symetrical matrix n = makeDOMElement("Symetrical", 3, 3, 0, 0, 1, 1, 9).firstChild(); e = n.toElement(); //basic default constructor values KstAMatrix* am2 = new KstAMatrix(e); doTest(am2->tagName() == "Symetrical"); doTest(am2->resize(3, 3, true)); for(int i =0 ; i < 3; i++){ for(int j = 0; j < 3; j++){ doTest(am2->value(i, j, &ok) == 1.1); doTest(ok); } } doTest(am2->editable()); doTest(am2->xNumSteps() == 3); doTest(am2->yNumSteps() == 3); doTest(am2->minX() == 0); doTest(am2->minY() == 0); doTest(am2->xStepSize() == 1); doTest(am2->yStepSize() == 1); doTest(am2->sampleCount() == 9); doTest(am2->setValueRaw(1, 1, 5)); ok = true; doTest(am2->value(1, 1, &ok) == 5); doTest(ok); am2->blank(); am2->change(KstObjectTag::fromString(am2->tagName()), 3, 3, 0, 0, 0, 0); //should not be legal doTest(am2->xNumSteps() == 3); doTest(am2->yNumSteps() == 3); doTest(am2->minX() == 0); doTest(am2->minY() == 0); doTest(am2->xStepSize() == 0); doTest(am2->yStepSize() == 0); doTest(am2->sampleCount() == 9); doTest(!am2->setValue(0, 0, 1)); ok = true; doTest(am2->value(0, 0, &ok) == 0); doTest(!ok); doTest(!am2->setValue(1, 1, 5.0)); doTest(am2->value(1, 1) != 5.0); doTest(am2->setValueRaw(2, 2, 6.0)); //fails KstAMatrix* um1 = new KstAMatrix(KstObjectTag::fromString("Unity"), 3, 3, 0.0, 0.0, 1.0, 1.0); um1->setEditable(true); doTest(um1->setValue(0, 0, 1)); doTest(um1->setValue(1, 1, 1)); doTest(um1->setValue(2, 2, 1)); doTest(um1->value(0, 0, &ok) == 1); doTest(ok); doTest(um1->value(0, 1, &ok) == 0); doTest(ok); doTest(um1->value(0, 2, &ok) == 0); doTest(ok); doTest(um1->value(1, 0, &ok) == 0); doTest(ok); doTest(um1->value(1, 1, &ok) == 1); doTest(ok); doTest(um1->value(1, 2, &ok) == 0); doTest(ok); doTest(um1->value(2, 0, &ok) == 0); doTest(ok); doTest(um1->value(2, 1, &ok) == 0); doTest(ok); doTest(um1->value(2, 2, &ok) == 1); doTest(ok); doTest(um1->resize(3, 3, false)); um1->zero(); doTest(um1->value(0, 0, &ok) == 0); doTest(ok); doTest(um1->value(0, 1, &ok) == 0); doTest(ok); doTest(um1->value(0, 2, &ok) == 0); doTest(ok); doTest(um1->value(1, 0, &ok) == 0); doTest(ok); doTest(um1->value(1, 1, &ok) == 0); doTest(ok); doTest(um1->value(1, 2, &ok) == 0); doTest(ok); doTest(um1->value(2, 0, &ok) == 0); doTest(ok); doTest(um1->value(2, 1, &ok) == 0); doTest(ok); doTest(um1->value(2, 2, &ok) == 0); doTest(ok); doTest(um1->setValue(0, 0, 1)); doTest(um1->setValue(1, 1, 1)); doTest(um1->setValue(2, 2, 1)); doTest(um1->resize(2, 2, false)); doTest(um1->sampleCount() == 4); doTest(um1->value(0, 0, &ok) == 1); doTest(ok); doTest(um1->value(0, 1, &ok) == 0); doTest(ok); doTest(um1->value(0, 2, &ok) == 0); doTest(!ok); doTest(um1->value(1, 0, &ok) == 0); doTest(ok); doTest(um1->value(1, 1, &ok) == 1); doTest(ok); doTest(um1->value(1, 2, &ok) == 0); doTest(!ok); doTest(um1->resize(4, 4, false)); doTest(um1->value(0, 0, &ok) == 1); doTest(ok); doTest(um1->value(0, 1, &ok) == 0); doTest(ok); doTest(um1->value(0, 2, &ok) == 0); doTest(ok); doTest(um1->value(0, 3, &ok) == 0); doTest(ok); doTest(um1->value(1, 0, &ok) == 0); doTest(ok); doTest(um1->value(1, 1, &ok) == 1); doTest(ok); doTest(um1->value(1, 2, &ok) == 0); doTest(ok); doTest(um1->value(1, 3, &ok) == 0); doTest(ok); doTest(um1->value(2, 0, &ok) == 0); doTest(ok); doTest(um1->value(2, 1, &ok) == 0); doTest(ok); doTest(um1->value(2, 2, &ok) == 0); doTest(ok); doTest(um1->value(2, 3, &ok) == 0); doTest(ok); doTest(um1->value(3, 0, &ok) == 0); doTest(ok); doTest(um1->value(3, 1, &ok) == 0); doTest(ok); doTest(um1->value(3, 2, &ok) == 0); doTest(ok); doTest(um1->value(3, 3, &ok) == 0); doTest(ok); doTest(um1->resize(3, 3, false)); doTest(um1->setValue(0, 0, 1.716299)); doTest(um1->setValue(0, 1, -0.485527)); doTest(um1->setValue(0, 2, -0.288690)); doTest(um1->setValue(1, 0, 1.716299)); doTest(um1->setValue(1, 1, NAN)); doTest(um1->setValue(1, 2, -0.274957)); doTest(um1->setValue(2, 0, 1.711721)); doTest(um1->setValue(2, 1, -0.485527)); doTest(um1->setValue(2, 2, -0.293267)); doTest(um1->value(0, 0) == 1.716299); doTest(um1->value(0, 1) == -0.485527); doTest(um1->value(0, 2) == -0.288690); doTest(um1->value(1, 0) == 1.716299); doTest(um1->value(1, 1) == 0); doTest(um1->value(1, 2) == -0.274957); doTest(um1->value(2, 0) == 1.711721); doTest(um1->value(2, 1) == -0.485527); doTest(um1->value(2, 2) == -0.293267); doTest(um1->minValue() == 0); doTest(um1->maxValue() == 0); KstAMatrix* sm = new KstAMatrix(KstObjectTag::fromString("Spike"), 2, 2, 0.0, 0.0, 1.0, 1.0); sm->setEditable(true); doTest(sm->resize(2, 2, false)); doTest(sm->xNumSteps() == 2); doTest(sm->yNumSteps() == 2); doTest(sm->setValueRaw(0, 0, 0.0)); doTest(sm->setValueRaw(0, 1, 0.1)); doTest(sm->setValueRaw(1, 0, 1.0)); doTest(sm->setValueRaw(1, 1, 1.1)); sm->calcNoSpikeRange(0); doTest(sm->minValueNoSpike() == 0.0); doTest(sm->maxValueNoSpike() == 0.0); sm->calcNoSpikeRange(-100); doTest(sm->minValueNoSpike() == 0.0); doTest(sm->maxValueNoSpike() == 0.0); sm->calcNoSpikeRange(0.9); doTest(sm->minValueNoSpike() >= 1E+300 ); doTest(sm->maxValueNoSpike() <= -1E+300); } int main(int argc, char **argv) { atexit(exitHelper); QCoreApplication app(argc, argv); doTests(); // Don't put tests in main because we need to ensure that no KstObjects // remain past the exit handler exitHelper(); // need to run it here before app goes away in some cases. if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } kst-2.0.3/old_tests/kstXbench/README000644 001750 001750 00000001317 11544160210 017476 0ustar00synthsynth000000 000000 This program attempts to benchmark the qt/X calls used by kst, to see if your graphics card is a bottleneck to performance. To make it, qmake -project qmake make Typical kst screen updates are 1-5 Hz, so anything over 20Hz is fine. The xorg or XFree drivers are ~20% faster in this bench than the ATI binaries. I have not checked NVIDIA's drivers. You can expect ATI 9600: ~30 Hz NVidia G4 ~35 Hz ATI 9800: ~50 Hz ATI 8500: ~30 Hz S3 on board: 2-6 Hz Laptop Radeons: 12 Hz - 25 Hz, depending on model and driver. As with all benchmarks, make sure nothing else is running. In some cases I have found terrible performance, even though nothing else was running. Restarting the X server fixed it. Not sure why.... kst-2.0.3/old_tests/kstXbench/tw.h000644 001750 001750 00000002604 11544160210 017421 0ustar00synthsynth000000 000000 /*************************************************************************** tw.h ------------------- begin : November, 2004 copyright : (C) 2004 by Barth Netterfield email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TW_H #define TW_H #include #include #include #include #include class TW : public QWidget { Q_OBJECT public: TW(QApplication *a, QWidget *parent = 0); void testPixMapLines(int length); void testPixMapFill(int size); void testDrawPixmap(); void testDrawImage(); void testPlotBench(bool ppressure = false); QApplication *_a; }; #endif kst-2.0.3/old_tests/kstXbench/tw.cpp000644 001750 001750 00000011041 11544160210 017747 0ustar00synthsynth000000 000000 /*************************************************************************** tw.cpp ------------------- begin : November, 2004 copyright : (C) 2004 by Barth Netterfield email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include "tw.h" #define WIDTH 1280 #define HEIGHT 1024 #define NITR 1000 TW::TW(QApplication *a, QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_PaintOutsidePaintEvent); setFixedSize(WIDTH, HEIGHT); _a = a; } void TW::testPixMapLines(int length) { int i, j, et; QTime t; QPixmap pm(WIDTH, HEIGHT); QPainter p( &pm ); t.start(); j = 0; do { for ( i=0; i<1000; i++,j++ ) { p.drawLine(1, 500, length+1, 500); } _a->processEvents(); } while ( ( et=t.elapsed() )<1000 ); printf( "Lines into Pixmaps: length %6d Rate: %g/s\n", length, 1000.0*double( j )/double( et ) ); _a->processEvents(); } void TW::testPixMapFill(int length) { int i, j, et; QTime t; QPixmap pm(WIDTH, HEIGHT); QPainter p( &pm ); t.start(); j = 0; do { for ( i=0; i<100; i++,j++ ) { p.fillRect( 1, 1, length, length, Qt::blue ); } _a->processEvents(); } while ( ( et=t.elapsed() )<1000 ); printf( "fillRect into Pixmaps: size %6d Rate: %g/s\n", length, 1000.0*double( j )/double( et ) ); _a->processEvents(); } void TW::testDrawPixmap() { QPixmap pm(WIDTH, HEIGHT); QTime t; int i, j, et; QPainter p( this ); pm.fill(Qt::red); t.start(); j = 0; do { for ( i=0; i<5; i++,j++ ) { p.drawPixmap(0,0,pm); _a->processEvents(); } } while ( ( et=t.elapsed() )<1000 ); printf( "Draw pixmap into widget (%d x %d). Rate: %g/s\n", WIDTH, HEIGHT, 1000.0*double( j )/double( et ) ); } void TW::testPlotBench(bool ppressure) { QPixmap full(WIDTH, HEIGHT); QPixmap *px[4]; QTime t; int i,j, l, w, h, et; int i_plot; if (ppressure) { QPixmap d1(WIDTH, HEIGHT); QPixmap d2(WIDTH, HEIGHT); QPixmap d3(WIDTH, HEIGHT); QPixmap d4(WIDTH, HEIGHT); QPixmap d5(WIDTH, HEIGHT); QPixmap d6(WIDTH, HEIGHT); QPixmap d7(WIDTH, HEIGHT); QPixmap d8(WIDTH, HEIGHT); } w = WIDTH/2; h = HEIGHT/2; for (i=0; i<4; i++) { px[i] = new QPixmap(w,h); } t.start(); j = 0; do { for (i=0; i<5; i++) { for (i_plot=0; i_plot<4; i_plot++) { QPainter p(px[i_plot]); p.fillRect( 1, 1, w-2, h-2, Qt::white ); p.setPen(QPen(Qt::black, 2)); for (l = 0; lprocessEvents(); } } while ( ( et=t.elapsed() )<1000 ); for (i=0; i<4; i++) { delete px[i]; } if (ppressure) printf("pressured "); printf( "simulated plots (%d x %d). Rate: %g/s\n", WIDTH, HEIGHT, 1000.0*double( j )/double( et ) ); } void TW::testDrawImage() { QImage im(WIDTH, HEIGHT, QImage::Format_ARGB32); QTime t; int i, j, et; QPainter p( this ); im.fill(0x0000ff11); t.start(); j = 0; do { for ( i=0; i<5; i++,j++ ) { p.drawImage(0,0,im); _a->processEvents(); } } while ( ( et=t.elapsed() )<1000 ); printf( "Draw image into widget (%d x %d). Rate: %g/s\n", WIDTH, HEIGHT, 1000.0*double( j )/double( et ) ); } #include "tw.moc" kst-2.0.3/old_tests/kstXbench/main.cpp000644 001750 001750 00000002766 11544160210 020257 0ustar00synthsynth000000 000000 /*************************************************************************** main.cpp ------------------- begin : November, 2004 copyright : (C) 2004 by Barth Netterfield email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include "tw.h" int main( int argc, char **argv ) { QApplication a( argc, argv ); TW tw( &a ); tw.show(); // tw.testPixMapLines(1000); // tw.testPixMapLines(100); // tw.testPixMapLines(10); // tw.testPixMapFill( 1000 ); // tw.testDrawImage(); // tw.testDrawPixmap(); tw.testPlotBench(); tw.testPlotBench(true); tw.testPlotBench(); tw.testPlotBench(true); return( 0 ); return a.exec(); } kst-2.0.3/old_tests/script/test_debug.js000644 001750 001750 00000002017 11544160210 020652 0ustar00synthsynth000000 000000 /* Test bind_debug */ var errors = 0; function assertNoReturn(x) { try { eval(x); } catch (e) { alert("Error: " + e.name + "\nLast test was: " + x); ++errors; } } function assert(x) { try { var xrc = eval(x); if (!xrc) { alert("Failed: " + x); ++errors; } } catch (e) { alert("Error: " + e.name + "\nLast test was: " + x); ++errors; } } assertNoReturn("Debug.clear()"); assertNoReturn("Debug.notice('Kst Test')"); assertNoReturn("Debug.warning('Kst Test')"); assertNoReturn("Debug.error('Kst Test')"); assertNoReturn("Debug.debug('Kst Test')"); assert("Debug.log[0].text == 'Kst Test'"); assert("Debug.log[1].text == 'Kst Test'"); assert("Debug.log[2].text == 'Kst Test'"); assert("Debug.log[3].text == 'Kst Test'"); assert("Debug.log[0].level == 'N'"); assert("Debug.log[1].level == 'W'"); assert("Debug.log[2].level == 'E'"); assert("Debug.log[3].level == 'D'"); assert("Debug.log.text.length > 60"); if (errors > 0) { alert("" + errors + " failed testcases."); } else { alert("All tests passed."); } kst-2.0.3/old_tests/script/test_kst.js000644 001750 001750 00000002363 11544160210 020371 0ustar00synthsynth000000 000000 /* Test bind_kst */ // Can't resetInterpreter because it nukes the script, of course... //try { Kst.resetInterpreter(); } catch(e) { alert("Error: " + e.name); } var errors = 0; function assertNoReturn(x) { try { eval(x); } catch (e) { alert("Error: " + e.name + "\nLast test was: " + x); ++errors; } } function assert(x) { try { var xrc = eval(x); if (!xrc) { alert("Failed: " + x); ++errors; } } catch (e) { alert("Error: " + e.name + "\nLast test was: " + x); ++errors; } } assertNoReturn("Kst.purge()"); assert("Kst.vectors.length == 0"); assert("Kst.scalars.length >= 0"); // the built-ins assert("Kst.strings.length == 0"); assert("Kst.windows.length <= 1"); assert("Kst.dataSources.length == 0"); var v = new Vector; v.tagName = "My Vector"; assert("Kst.vectors.length == 1"); assert("var j = Kst.vectors[0]; j.tagName = 'My Vector'"); assert("Kst.vectors[0].tagName = 'My Vector'"); var sc = Kst.scalars.length; var s = new Scalar; s.tagName = "My Scalar"; assert("Kst.scalars.length == " + (sc + 1)); assert("var j = Kst.scalars[0]; j.tagName = 'My Scalar'"); assert("Kst.scalars[" + sc + "].tagName = 'My Scalar'"); if (errors > 0) { alert("" + errors + " failed testcases."); } else { alert("All tests passed."); } kst-2.0.3/old_tests/dirfile_maker/dirfile_maker.c000644 001750 001750 00000004123 11544160210 022421 0ustar00synthsynth000000 000000 #include #include #include #include #include #include struct DFEntryType { char field[17]; int spf; int fp; }; #define NDF 5 #define SCOUNT 0 #define FCOUNT 1 #define SINE 2 #define SSINE 3 #define COS 4 struct DFEntryType df[NDF] = { {"scount", 1, -1}, {"fcount", 20, -1}, {"sine", 20, -1}, {"ssine", 1, -1}, {"cos", 20, -1} }; int main() { char dirfilename[120]; char tmpstr[150]; FILE *fpf; int i, count = 0; float x; sprintf(dirfilename, "%d.dm", time(NULL)); printf("Writing dirfile %s\n", dirfilename); printf("The fields are:\n"); for (i=0; i #include #include static void exitHelper() { KST::vectorList.clear(); KST::scalarList.clear(); KST::dataObjectList.clear(); } int rc = KstTestSuccess; #define doTest(x) testAssert(x, QString("Line %1").arg(__LINE__)) #define doTestD(x, y) testAssert(x, QString("%1: %2").arg(__LINE__).arg(y)) void testAssert(bool result, const QString& text = "Unknown") { if (!result) { KstTestFailed(); printf("Test [%s] failed.\n", text.toLatin1().data()); } } #define dumpPoints(histogram, n) do { \ for (int i = 0; i < n*4; ++i) { \ printf("%.15f, %.15f\n", histogram->vX()->value(i), histogram->vY()->value(i)); \ } } while(0) void doTests() { KstVectorPtr vp = KstVector::generateVector(0, 10, 100, KstObjectTag::fromString("V1")); KstHistogramPtr h1 = new KstHistogram("H1", vp, 0, 10, 10, KST_HS_NUMBER); KST::dataObjectList.append(h1.data()); doTest(h1->propertyString() == "Histogram: V1"); doTest(!h1->realTimeAutoBin()); // should be false by default doTest(h1->nBins() == 10); h1->update(0); doTest(h1->vMin() == 0.0); doTest(h1->vMax() == 10.0); doTest(h1->vNumSamples() == 100); int count = 0; for (int i=0; i<10; i++) { count += int(h1->vY()->value(i)); } h1->setRealTimeAutoBin(true); doTest(h1->realTimeAutoBin()); //dumpPoints(h1, 10); doTest(count == 100); // should account for the whole vector h1->setNBins(11); doTest(!h1->realTimeAutoBin()); doTest(h1->nBins() == 11); doTest(h1->vMin() == 0.0); doTest(h1->vMax() == 10.0); doTest(h1->vNumSamples() == 100); h1->update(0); count = 0; for (int i=0; i<11; i++) { count += int(h1->vY()->value(i)); } //dumpPoints(h1, 11); doTest(count == 100); // should still account for the whole vector h1->setNBins(9); doTest(h1->nBins() == 9); doTest(h1->vMin() == 0.0); doTest(h1->vMax() == 10.0); doTest(h1->vNumSamples() == 100); h1->update(0); count = 0; for (int i=0; i<9; i++) { count += int(h1->vY()->value(i)); } //dumpPoints(h1, 9); doTest(count == 100); // should still account for the whole vector // min > max h1 = new KstHistogram("H2", vp, 10, 0, 10, KST_HS_NUMBER); doTest(h1->nBins() == 10); doTest(h1->xMin() == 0.0); doTest(h1->xMax() == 10.0); doTest(h1->vMin() == 0.0); doTest(h1->vMax() == 10.0); doTest(h1->vNumSamples() == 100); // min == max h1 = new KstHistogram("H3", vp, 10, 10, 2, KST_HS_NUMBER); doTest(h1->nBins() == 2); doTest(h1->xMin() == 9.0); doTest(h1->xMax() == 11.0); doTest(h1->vMin() == 0.0); doTest(h1->vMax() == 10.0); doTest(h1->vNumSamples() == 100); // max < min h1 = new KstHistogram("H4", vp, 11, 9, 1, KST_HS_NUMBER); doTest(h1->nBins() == 2); doTest(h1->xMax()==11); doTest(h1->xMin()==9); doTest(h1->vMin() == 0.0); doTest(h1->vMax() == 10.0); doTest(h1->vNumSamples() == 100); // set to max == min h1->setXRange(10, 10); doTest(h1->xMin() == 9.0); doTest(h1->xMax() == 11.0); // set to max > min h1->setXRange(1,2); doTest(h1->xMax() - h1->xMin() ==1.0); h1->setXRange(8, 10); doTest(h1->xMin() == 8.0); doTest(h1->xMax() == 10.0); } int main(int argc, char **argv) { atexit(exitHelper); QCoreApplication app(argc, argv); doTests(); exitHelper(); // before app dies if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } // vim: ts=2 sw=2 et kst-2.0.3/old_tests/testeqparser.cpp000644 001750 001750 00000035003 11544160210 020112 0ustar00synthsynth000000 000000 /* * Copyright 2004, The University of Toronto * Licensed under GPL. */ //#define DUMP_FAIL_MSGS #include "ksttestcase.h" #include #include extern "C" int yyparse(); extern "C" void *ParsedEquation; extern "C" struct yy_buffer_state *yy_scan_string(const char*); bool optimizerFailed = false; KstVectorMap vectorsUsed; KstVectorPtr xVector; int rc = KstTestSuccess; void testText(const char *equation, const char *expect) { bool failure = false; QString txt; yy_scan_string(equation); int rc = yyparse(); if (rc == 0) { vectorsUsed.clear(); Equation::Node *eq = static_cast(ParsedEquation); assert(eq); ParsedEquation = 0L; //eq->collectVectors(vectorsUsed); txt = eq->text(); failure = txt != expect; delete eq; } else { // Parse error delete (Equation::Node*)ParsedEquation; ParsedEquation = 0L; failure = true; } if (failure) { if (!Equation::errorStack.isEmpty()) { printf("Failures on [%s] -------------------------\n", equation); for (QStringList::ConstIterator i = Equation::errorStack.constBegin(); i != Equation::errorStack.constEnd(); ++i) { printf("%s\n", (*i).toLatin1().data()); } printf("------------------------------------------\n"); } else { printf("Got [%s], expected [%s]\n", txt.toLatin1().data(), expect); } --rc; } } bool doTest(const char *equation, double x, double result, const double tol = 0.00000000001) { yy_scan_string(equation); int rc = yyparse(); if (rc == 0) { vectorsUsed.clear(); Equation::Node *eq = static_cast(ParsedEquation); assert(eq); ParsedEquation = 0L; Equation::Context ctx; ctx.sampleCount = 2; ctx.noPoint = NOPOINT; ctx.x = x; ctx.xVector = xVector; if (xVector) { ctx.sampleCount = xVector->length(); } Equation::FoldVisitor vis(&ctx, &eq); if (eq->isConst() && !dynamic_cast(eq)) { if (!optimizerFailed) { optimizerFailed = true; ::rc--; printf("Optimizer bug: found an unoptimized const equation. Optimizing for coverage purposes.\n"); } double v = eq->value(&ctx); delete eq; eq = new Equation::Number(v); } KstScalarMap scm; KstStringMap stm; eq->collectObjects(vectorsUsed, scm, stm); eq->update(-1, &ctx); double v = eq->value(&ctx); delete eq; if (fabs(v - result) < tol || (result != result && v != v) || (result == INF && v == INF) || (result == -INF && v == -INF)) { return true; } else { printf("Result: %.16f\n", v); return false; } } else { // Parse error printf("Failures on [%s] -------------------------\n", equation); for (QStringList::ConstIterator i = Equation::errorStack.constBegin(); i != Equation::errorStack.constEnd(); ++i) { printf("%s\n", (*i).toLatin1().data()); } printf("------------------------------------------\n"); delete (Equation::Node*)ParsedEquation; ParsedEquation = 0L; return false; } } void test(const char *equation, double x, double result, const double tol = 0.00000000001) { if (!doTest(equation, x, result, tol)) { rc--; printf("Test of (%s)[%.16f] == %.16f failed.\n", equation, x, result); } } void testParseFail(const char *equation) { yy_scan_string(equation); if (0 == yyparse()) { printf("Test of (%s) parsing passed, but should have failed.\n", equation); rc--; } else { if (Equation::errorStack.count() == 1 && (Equation::errorStack.first() == "parse error" || Equation::errorStack.first() == "syntax error")) { printf("ERROR: [%s] doesn't have error handling yet!\n", equation); rc--; #ifdef DUMP_FAIL_MSGS } else { printf("Failures on [%s] -------------------------\n", equation); for (QStringList::ConstIterator i = Equation::errorStack.constBegin(); i != Equation::errorStack.constEnd(); ++i) { printf("%s\n", (*i).toLatin1().data()); } printf("------------------------------------------\n"); #endif } } } static void exitHelper() { xVector = 0L; vectorsUsed.clear(); KST::vectorList.clear(); KST::scalarList.clear(); } extern int yydebug; int main(int argc, char **argv) { atexit(exitHelper); QCoreApplication app(argc, argv); // Base cases test("0", 1.0, 0.0); test("1.0", 2.0, 1.0); // Basics test("x", -1.0, -1.0); test("-x", -1.0, 1.0); test("x^2", -1.0, 1.0); test(" x^2", -1.0, 1.0); test(" x^2 ", -1.0, 1.0); test("x^2 ", -1.0, 1.0); test("x^2 + x^2", -1.0, 2.0); test("y", 0.0, NOPOINT); test("foo()", 0.0, NOPOINT); test("foo(1.0, 2.0, 3.0)", 0.0, NOPOINT); // Order of evaluation and parser issues test("-x^2", 2.0, -4.0); test("(-x)^2", 2.0, 4.0); test("-(x^2)", 2.0, -4.0); test("(-x^2)", 2.0, -4.0); test("x*x+5", 2.0, 9.0); test("5+x*x", 2.0, 9.0); test("5*4/2*5", 1.0, 50.0); test("asin(sin(x))", 3.14159265358979323, 0.0); test("x^(1/2)", 2.0, sqrt(2.0)); test("x^(1/2)*2", 2.0, 2.0*sqrt(2.0)); test("(1/2)*x^2+3*x-5", 1.0, -1.5); test("2^3^4", 0.0, 2417851639229258349412352.0); test("sin(x)^2", 0.5*3.14159265358979323, 1.0); test("(2)^(3)", 0.0, 8); test("(2*3)^(3*4)", 0.0, 2176782336.0); test("sin(x^2)", sqrt(3.14159265358979323), 0.0); test("5*4/2", 0.0, 10.0); test("5/4*2", 0.0, 2.5); test("10%2", 0.0, 0.0); test("10.5%2", 0.0, 0.5); test("0%2", 0.0, 0.0); test("2%0", 0.0, NOPOINT); test("--x", 1.0, 1.0); test("--x", -1.0, -1.0); test("---x", -1.0, 1.0); test("---x", 1.0, -1.0); // Constants test("e", 0.0, 2.7128182846); test("pi", 0.0, 3.1415926536); // Functions test("sin()", 0.0, NOPOINT); test("sin(0.0)", 0.0, 0.0); test("sin(3.14159265358979323)", 0.0, 0.0); test("sin(3.14159265358979323/2.00000000000000000000000000)", 0.0, 1.0); test("cos()", 0.0, NOPOINT); test("cos(0.0)", 0.0, 1.0); test("cos(3.14159265358979323)", 0.0, -1.0); test("cos(3.14159265358979323/2.00000000000000000000000000)", 0.0, 0.0); test("sec(x) == 1/cos(x)", 0.2332744, 1.0); test("csc(x) == 1/sin(x)", 0.2332744, 1.0); test("cot(x) == 1/tan(x)", 0.2332744, 1.0); test("abs(0.0)", 0.0, 0.0); test("abs(x)", 1.0, 1.0); test("abs(x)", -1.0, 1.0); test("abs(x)", NOPOINT, NOPOINT); test("abs(x)", INF, INF); test("abs(x)", -INF, INF); test("abs(-0.000000000001)", 0.0, 0.000000000001); test("cos(acos(x))", 0.3875823288, 0.3875823288, 0.0000000001); test("acos(cos(x))", 2.3875823288, 2.3875823288, 0.0000000001); test("asin(sin(x))", 0.7540103248, 0.7540103248, 0.0000000001); test("sin(asin(x))", 0.3875823288, 0.3875823288, 0.0000000001); test("tan(atan(x))", 2.3875823288, 2.3875823288, 0.0000000001); test("atan(tan(x))", 0.3875823288, 0.3875823288, 0.0000000001); test("sqrt(4) == 2.0", 0.0, 1.0); test("sqrt(0) == 0.0", 0.0, 1.0); test("sqrt(-1)", 0.0, NOPOINT); test("sqrt(2)", 0.0, 1.4142135623730951); test("cbrt(0.0) == 0.0", 0.0, 1.0); test("cbrt(8.0) == 2.0", 0.0, 1.0); test("cbrt(-1)", 0.0, -1.0); test("cbrt(2)", 0.0, 1.2599210498948734); // TODO: cosh, exp, log, ln, sinh, tanh // Expressions / Comparison test("0.0>0.0", 0.0, 0.0); test("0.0>=0.0", 0.0, 1.0); test("0.0<0.0", 0.0, 0.0); test("0.0<=0.0", 0.0, 1.0); test("0.0=0.0", 0.0, 1.0); test("0.0!=0.0", 0.0, 0.0); test("1.0!=0.0", 0.0, 1.0); test("sin(1.0)!=sin(0.0)", 0.0, 1.0); test("sin()!=sin()", 0.0, 1.0); test("0.0==0.0", 0.0, 1.0); test("1.0>0.0", 0.0, 1.0); test("1.0>=0.0", 0.0, 1.0); test("0.0>1.0", 0.0, 0.0); test("0.0>=1.0", 0.0, 0.0); test("1.0<0.0", 0.0, 0.0); test("1.0<=0.0", 0.0, 0.0); test("0.0<1.0", 0.0, 1.0); test("0.0<=1.0", 0.0, 1.0); test("(0.0/0.0)==(0.0/0.0)", 0.0, 0.0); test("(0.0/0.0)==(1.0/0.0)", 0.0, 0.0); test("(1.0/0.0)==(1.0/0.0)", 0.0, 1.0); // inf == inf test("(1.0/0.0)==-(1.0/0.0)", 0.0, 0.0); test("(0.0/0.0)==-(1.0/0.0)", 0.0, 0.0); test("(1.0/0.0)==(0.0/0.0)", 0.0, 0.0); test("1&&1", 0.0, 1.0); test("1&&0", 0.0, 0.0); test("0&&1", 0.0, 0.0); test("0&&2", 0.0, 0.0); test("3&&2", 0.0, 1.0); test("1||1", 0.0, 1.0); test("0||1", 0.0, 1.0); test("1||0", 0.0, 1.0); test("0||0", 0.0, 0.0); test("2||4", 0.0, 1.0); test("1||(2&&0)", 0.0, 1.0); test("(1||2)&&0", 0.0, 0.0); test("1||2&&0", 0.0, 1.0); test("2&&0||1", 0.0, 1.0); test("2&&1||0", 0.0, 1.0); test("0||1&&0", 0.0, 0.0); test("1.0 == (1.0 == 1.0)", 0.0, 1.0); test("1.0 != (1.0 == 0.0)", 0.0, 1.0); test("1.0 != (1.0 == 1.0)", 0.0, 0.0); test("0.0 == (1.0 == 0.0)", 0.0, 1.0); test("-1==1", 0.0, 0.0); test("-1==-1", 0.0, 1.0); test("1==-1", 0.0, 0.0); test("1!=-1", 0.0, 1.0); test("-1!=1", 0.0, 1.0); test("-1!=-1", 0.0, 0.0); test("!0.0", 0.0, 1.0); test("!1.0", 0.0, 0.0); test("!-1.0", 0.0, 0.0); test("!2.0", 0.0, 0.0); test("!x", INF, 0.0); test("!x", NOPOINT, 1.0); test("!(1 > 2)", 0.0, 1.0); test("!1.0 > -1.0", 0.0, 1.0); // (!1.0) > -1.0 test("!!x", 1.0, 1.0); test("!!!x", 1.0, 0.0); test("!!!!x", 1.0, 1.0); // Bit operations test("32&4", 0.0, 0.0); test("32&4|2", 0.0, 2.0); test("32|4&2", 0.0, 0.0); test("32|4", 0.0, 36.0); test("0&257", 0.0, 0.0); test("257&0", 0.0, 0.0); test("257|0", 0.0, 257.0); test("0|257", 0.0, 257.0); test("-1|257", 0.0, -1); test("257|-1", 0.0, -1); // Scalars new KstScalar(KstObjectTag::fromString("test1"), 0L, 1.0, true); new KstScalar(KstObjectTag::fromString("test2"), 0L, 0.0, true); new KstScalar(KstObjectTag::fromString("test3"), 0L, -1.0, true); new KstScalar(KstObjectTag::fromString("test4"), 0L, NOPOINT, true); new KstScalar(KstObjectTag::fromString("test5"), 0L, INF, true); new KstScalar(KstObjectTag::fromString("test6"), 0L, -INF, true); test("[test1]", 0.0, 1.0); test("[test4]", 0.0, NOPOINT); test("[test4] - [test4]", 0.0, NOPOINT); test("[test4] - [test5]", 0.0, NOPOINT); test("[test4]*[test5]", 0.0, NOPOINT); test("[sdf]", 0.0, NOPOINT); test("[=10+10]", 0.0, 20.0); // Vectors KstVector::generateVector(0, 1.0, 10, KstObjectTag::fromString("1")); KstVector::generateVector(0, 1.0, 10, KstObjectTag::fromString("V1")); KstVector::generateVector(1.0, 2.0, 10, KstObjectTag::fromString("V2")); KstVector::generateVector(0, 1.0, 2, KstObjectTag::fromString("V3")); KstVector::generateVector(-1.0, 1.0, 1000, KstObjectTag::fromString("V4")); KstVector::generateVector(-1.0, 1.0, 1000, KstObjectTag::fromString("V5-%+-_!")); test("[V2] - [V1]", 0.0, 1.0); test("[V2[9]]", 0.0, 2.0); test("[V2[5+4]]", 0.0, 2.0); test("[V2[]]", 0.0, 1.0); test("2*sin([V5-%+-_!])", 0.0, -1.6829419696157930); // TODO: interpolation, more vector combinations // Plugins test("2*plugin(bin, [V4], 12)", 1.0, -1.9779779779779778); test("4*plugin(bin, [V4], x)", 5.0, -3.9839839839839839); test("-3*plugin(bin, x, 12)", 2.0, NOPOINT); xVector = KstVector::generateVector(0, 100, 2000, KstObjectTag::fromString("XVector")); test("-3*plugin(bin, x, 12)", 2.0, -0.8254127063531767); test("-3*plugin(bin, y, 12)", 2.0, NOPOINT); // TODO: more plugin tests // TODO: float notation // Combinations test("1|0&&0", 0.0, 0.0); test("0&&0|1", 0.0, 0.0); test("0&&1|0", 0.0, 0.0); test("0||1&1", 0.0, 1.0); test("0||2&1", 0.0, 0.0); test("2&1||0", 0.0, 0.0); test("1-1||0", 0.0, 0.0); test("2-2||0", 0.0, 0.0); test("0||2-2", 0.0, 0.0); test("8|2*2", 0.0, 12.0); test("2*2|8", 0.0, 12.0); test("[V1] > 0.0", 0.0, 0.0); test("[V1] > -1.0", 0.0, 1.0); test("[1] > 0.0", 0.0, 0.0); test("[1] > -1.0", 0.0, 1.0); test("-([V1]*sin([V1]*[V2])+[V3]*cos([V3]*[V3]))", 0.0, 0.0); test("[V3] * -1", 0.0, 0.0); /* Wrap a testcase with this and run bison with -t in order to get a trace * of the parse stack */ #if 0 yydebug = 1; yydebug = 0; #endif // Errors: testParseFail(""); testParseFail(" "); testParseFail("\t"); testParseFail(" \t \t"); testParseFail("[]"); testParseFail("[[]"); testParseFail("[]]"); testParseFail("]"); testParseFail("["); testParseFail("]["); testParseFail("[]["); testParseFail("foo(, 3)"); testParseFail("foo(3,)"); testParseFail("foo(3,,5)"); testParseFail("foo([])"); testParseFail("foo(4, [])"); testParseFail("/"); testParseFail("/2"); testParseFail("2/"); testParseFail("2//2"); testParseFail("%"); testParseFail("%2"); testParseFail("2%"); testParseFail("2%%2"); testParseFail("|"); testParseFail("||"); testParseFail("|2"); testParseFail("2|"); testParseFail("||2"); testParseFail("2||"); testParseFail("2|||2"); testParseFail("&"); testParseFail("&&"); testParseFail("&2"); testParseFail("2&"); testParseFail("&&2"); testParseFail("2&&"); testParseFail("2&&&2"); testParseFail("*"); testParseFail("*2"); testParseFail("2*"); testParseFail("2**2"); testParseFail("^"); testParseFail("^2"); testParseFail("2^^2"); testParseFail("2^"); testParseFail("+"); testParseFail("+2"); testParseFail("2+"); testParseFail("2++2"); testParseFail("-"); testParseFail("2-"); testParseFail("-2-"); testParseFail("2!"); testParseFail("!"); testParseFail("()"); testParseFail("2()"); testParseFail("()2"); testParseFail("_"); testParseFail("#"); testParseFail("$"); testParseFail(")"); testParseFail("("); testParseFail(")("); testParseFail("2&|2"); testParseFail("2&&||2"); testParseFail("2&&+2"); testParseFail("2+&&2"); testParseFail("2*&&2"); testParseFail("2&&*2"); testParseFail("2<>2"); testParseFail("2=<2"); testParseFail("2=>2"); testParseFail("2><2"); testParseFail("<"); testParseFail("<2"); testParseFail("2<"); testParseFail("2<<2"); testParseFail(">"); testParseFail(">2"); testParseFail("2>"); testParseFail("2>>2"); testParseFail(">="); testParseFail(">=2"); testParseFail("2>="); testParseFail("2>=>=2"); testParseFail("<="); testParseFail("<=2"); testParseFail("2<="); testParseFail("2<=<=2"); testParseFail("2<==2"); testParseFail("."); testParseFail(".2"); testParseFail("2."); testParseFail(","); testParseFail(",2"); testParseFail("2,"); // Doesn't give a specific error - how to catch this? testParseFail("2*sin(x"); testParseFail("2*sin(x)()"); testText("3*x", "3*x"); testText("(3*x)", "(3*x)"); testText("3*(x)", "3*x"); testText("((3*x))", "(3*x)"); testText(" ((3 * x)) ", "(3*x)"); testText(" ((3 * x)) ", "(3*x)"); testText("(-3)", "(-3)"); testText("(x)", "x"); testText("(3*(-(x+5)))", "(3*(-(x+5)))"); testText("(sin((x)))", "sin(x)"); exitHelper(); if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } // vim: ts=2 sw=2 et kst-2.0.3/old_tests/test1.sh000755 001750 001750 00000026411 11544160210 016266 0ustar00synthsynth000000 000000 #!/bin/sh # -xvf # VALGRIND= if [ "x$1" == "x-v" ]; then VALGRIND="valgrind -v --tool=memcheck --num-callers=25"; fi if [ "x$1" == "x-t" ]; then VALGRIND="valgrind -v --tool=helgrind --num-callers=25"; fi ######### All settings are above this line CONSOLELOG=`mktemp /tmp/Kst_ConsoleLog.XXXXXX` || exit 4 echo Logging to $CONSOLELOG $VALGRIND kst --nq >$CONSOLELOG 2>&1 & DCOP="dcop kst-$! KstIface" QUIT="dcop kst-$! MainApplication-Interface quit" TMPFILE=`mktemp /tmp/Kst_TestSuite.XXXXXX` || exit 3 doExit() { $QUIT rm $TMPFILE rm $TESTFILE rm -f $KSTFILE exit $1; } checkEmptyResponse() { if [ ! -s "$TMPFILE" ]; then echo "Test $1 failed. Response was non-empty. [" `cat $TMPFILE` "]" return; fi echo -ne "Test $1 passed.\r" } checkArraySize() { LEN=`wc -l < $TMPFILE` if test ! "x$LEN" = "x$2"; then echo "Test $1 failed. Expected [$2] entries, received [$LEN]." return; fi echo -ne "Test $1 passed.\r" } checkStringResponse() { TESTSTR=`cat $TMPFILE | tr -d '\n'` if test ! "x$2" = "x$TESTSTR"; then echo "Test $1 failed. Expected [$2], received [$TESTSTR]." return; fi echo -ne "Test $1 passed.\r" } echo -n "Waiting for Kst launch completely." while [ 0 ]; do $DCOP >/dev/null 2>&1 if [ $? -eq 0 ]; then break; fi echo -n "." sleep 1; done echo "" declare -i cnt=0 ##### All lists are empty to start $DCOP curveList >$TMPFILE checkEmptyResponse 1 $DCOP plotList >$TMPFILE checkEmptyResponse 2 $DCOP objectList >$TMPFILE checkEmptyResponse 3 $DCOP vectorList >$TMPFILE checkEmptyResponse 4 $DCOP scalarList >$TMPFILE checkEmptyResponse 5 ##### Scalars $DCOP generateScalar "Scalar Test 1" 3.14159265358979 >$TMPFILE checkStringResponse 30 "Scalar Test 1" $DCOP scalar "Scalar Test 1" >$TMPFILE checkStringResponse 31 "3.141593" $DCOP generateScalar "Scalar Test 1" 0.000000000 >$TMPFILE checkStringResponse 32 "Scalar Test 1'" $DCOP scalar "Scalar Test 1'" >$TMPFILE checkStringResponse 33 "0.000000" $DCOP generateScalar "Scalar Test 1" "-33.5e+23" >$TMPFILE checkStringResponse 34 "Scalar Test 1''" $DCOP scalar "Scalar Test 1''" >$TMPFILE checkStringResponse 35 "-3349999999999999970639872.000000" $DCOP scalarList >$TMPFILE checkArraySize 36 25 ##### Vectors $DCOP generateVector "Vector Test 1" -10 10 21 >$TMPFILE checkStringResponse 100 "Vector Test 1" $DCOP vectorSize "Vector Test 1" >$TMPFILE checkStringResponse 101 "21" # tests 102-122 cnt=0 while [ $cnt -lt 21 ]; do $DCOP vector "Vector Test 1" $cnt >$TMPFILE declare -i j=-10+$cnt declare -i n=102+$cnt checkStringResponse $n "$j.000000" cnt=$cnt+1; done $DCOP vector "Vector Test 1" -1 >$TMPFILE checkStringResponse 123 "0.000000" $DCOP vector "Vector Test 1" 21 >$TMPFILE checkStringResponse 124 "0.000000" $DCOP generateVector "Vector Test 2" -10 10 1 >$TMPFILE checkStringResponse 125 "Vector Test 2" # vectors must have at least 2 entries $DCOP vectorSize "Vector Test 2" >$TMPFILE checkStringResponse 126 "2" $DCOP vector "Vector Test 2" 0 >$TMPFILE checkStringResponse 127 "-10.000000" $DCOP vector "Vector Test 2" 1 >$TMPFILE checkStringResponse 128 "10.000000" $DCOP generateVector "Vector Test 3" -10 10 0 >$TMPFILE checkStringResponse 129 "Vector Test 3" $DCOP vectorSize "Vector Test 3" >$TMPFILE checkStringResponse 130 "2" $DCOP vector "Vector Test 3" 0 >$TMPFILE checkStringResponse 131 "-10.000000" $DCOP vector "Vector Test 3" 1 >$TMPFILE checkStringResponse 132 "10.000000" $DCOP generateVector "Vector Test 4" -10 10 -987 >$TMPFILE checkStringResponse 133 "Vector Test 4" $DCOP vectorSize "Vector Test 4" >$TMPFILE checkStringResponse 134 "2" $DCOP vector "Vector Test 4" 0 >$TMPFILE checkStringResponse 135 "-10.000000" $DCOP vector "Vector Test 4" 1 >$TMPFILE checkStringResponse 136 "10.000000" $DCOP generateVector "Vector Test 5" -1 -1 44 >$TMPFILE checkStringResponse 137 "Vector Test 5" $DCOP vectorSize "Vector Test 5" >$TMPFILE checkStringResponse 138 "44" $DCOP vector "Vector Test 5" 33 >$TMPFILE checkStringResponse 139 "-0.923256" $DCOP vector "Vector Test 5" 2 >$TMPFILE checkStringResponse 140 "-0.995349" $DCOP vectorList >$TMPFILE checkArraySize 141 5 $DCOP clearVector "Vector Test 1" >$TMPFILE checkStringResponse 142 "true" $DCOP vectorSize "Vector Test 1" >$TMPFILE checkStringResponse 143 "21" # tests 144-164 cnt=0 while [ $cnt -lt 21 ]; do $DCOP vector "Vector Test 1" $cnt >$TMPFILE declare -i n=144+$cnt checkStringResponse $n "0.000000" cnt=$cnt+1; done $DCOP resizeVector "Vector Test 1" 5 >$TMPFILE checkStringResponse 165 "true" $DCOP vectorSize "Vector Test 1" >$TMPFILE checkStringResponse 166 "5" $DCOP resizeVector "Vector Test 1" 2 >$TMPFILE checkStringResponse 167 "true" $DCOP vectorSize "Vector Test 1" >$TMPFILE checkStringResponse 168 "2" $DCOP resizeVector "Vector Test 1" 1 >$TMPFILE checkStringResponse 169 "true" $DCOP vectorSize "Vector Test 1" >$TMPFILE checkStringResponse 170 "1" $DCOP resizeVector "Vector Test 1" 0 >$TMPFILE checkStringResponse 171 "false" $DCOP vectorSize "Vector Test 1" >$TMPFILE checkStringResponse 172 "1" $DCOP resizeVector "Vector Test 1" -4 >$TMPFILE checkStringResponse 173 "false" $DCOP vectorSize "Vector Test 1" >$TMPFILE checkStringResponse 174 "1" $DCOP resizeVector "Vector Test 1" 3 >$TMPFILE checkStringResponse 175 "true" $DCOP setVector "Vector Test 1" -1 42 >$TMPFILE checkStringResponse 176 "false" $DCOP setVector "Vector Test 1" -2 42 >$TMPFILE checkStringResponse 177 "false" $DCOP setVector "Vector Test 1" 0 42 >$TMPFILE checkStringResponse 178 "true" $DCOP setVector "Vector Test 1" 1 42.42 >$TMPFILE checkStringResponse 179 "true" $DCOP setVector "Vector Test 1" 2 42.4242 >$TMPFILE checkStringResponse 180 "true" $DCOP vector "Vector Test 1" 0 >$TMPFILE checkStringResponse 181 "42.000000" $DCOP vector "Vector Test 1" 1 >$TMPFILE checkStringResponse 182 "42.420000" $DCOP vector "Vector Test 1" 2 >$TMPFILE checkStringResponse 183 "42.424200" $DCOP setVector "Vector Test 1" 3 42.424242 >$TMPFILE checkStringResponse 184 "false" $DCOP vectorSize "Vector Test 1" >$TMPFILE checkStringResponse 185 "3" $DCOP resizeVector "Vector Test 1" 5 >$TMPFILE checkStringResponse 186 "true" $DCOP vector "Vector Test 1" 0 >$TMPFILE checkStringResponse 187 "42.000000" $DCOP vector "Vector Test 1" 1 >$TMPFILE checkStringResponse 188 "42.420000" $DCOP vector "Vector Test 1" 2 >$TMPFILE checkStringResponse 189 "42.424200" $DCOP vector "Vector Test 1" 3 >$TMPFILE checkStringResponse 190 "0.000000" $DCOP vector "Vector Test 1" 4 >$TMPFILE checkStringResponse 191 "0.000000" $DCOP setVector "Vector Test 1" 3 42.424242 >$TMPFILE checkStringResponse 192 "true" $DCOP setVector "Vector Test 1" 4 42424242.42 >$TMPFILE checkStringResponse 193 "true" $DCOP vector "Vector Test 1" 3 >$TMPFILE checkStringResponse 194 "42.424242" $DCOP vector "Vector Test 1" 4 >$TMPFILE checkStringResponse 195 "42424242.420000" $DCOP saveVector "Vector Test 1" "" >$TMPFILE checkStringResponse 196 "false" VTMPFILE=`mktemp /tmp/Kst_Vector.XXXXXX` || exit 3 $DCOP saveVector "Vector Test 1" $VTMPFILE >$TMPFILE checkStringResponse 197 "true" LEN=`wc -l < $VTMPFILE` if test ! "x$LEN" = "x7"; then echo "Test 198 failed. Expected [7] entries, received [$LEN]."; fi echo -ne "Test 198 passed.\r" rm $VTMPFILE ##### Plots $DCOP generateVector "plotinput1" 0 1000 10000 >$TMPFILE checkStringResponse 500 "plotinput1" $DCOP generateVector "plotinput2" 0 100 10000 >$TMPFILE checkStringResponse 501 "plotinput2" $DCOP createCurve "curve-ramp" "plotinput1" "plotinput2" "" "" >$TMPFILE checkStringResponse 502 "curve-ramp" $DCOP createCurve "curve-ramp2" "plotinput2" "plotinput1" "" "" >$TMPFILE checkStringResponse 503 "curve-ramp2" $DCOP createPlot "P0" >$TMPFILE checkStringResponse 504 "P0" $DCOP addCurveToPlot "P0" "curve-ramp" >$TMPFILE checkStringResponse 505 "true" $DCOP createPlot "P1" >$TMPFILE checkStringResponse 506 "P1" $DCOP addCurveToPlot "P1" "curve-ramp2" >$TMPFILE checkStringResponse 507 "true" $DCOP createPlot "P2" >$TMPFILE checkStringResponse 508 "P2" $DCOP plotEquation "plotinput1" "2*sin(x)*cos(x^2)" "P2" >$TMPFILE checkStringResponse 509 "true" VTMPFILE=`mktemp /tmp/Kst_TestPrintOut1.png.XXXXXX` || exit 3 echo "Writing printout image [P0,P1,P2] to $VTMPFILE" $DCOP printImage $VTMPFILE >$TMPFILE checkStringResponse 510 "true" VTMPFILE=`mktemp /tmp/Kst_TestPrintOut1.ps.XXXXXX` || exit 3 echo "Writing printout postscript [P0,P1,P2] to $VTMPFILE" $DCOP printPostScript $VTMPFILE >$TMPFILE checkStringResponse 511 "true" $DCOP deletePlot "P1" >$TMPFILE checkStringResponse 512 "true" $DCOP deletePlot "P0" >$TMPFILE checkStringResponse 513 "true" $DCOP deletePlot "P2" >$TMPFILE checkStringResponse 514 "true" VTMPFILE=`mktemp /tmp/Kst_TestPrintOut1.png.XXXXXX` || exit 3 echo "Writing printout image [blank] to $VTMPFILE" $DCOP printImage $VTMPFILE >$TMPFILE checkStringResponse 515 "true" VTMPFILE=`mktemp /tmp/Kst_TestPrintOut1.ps.XXXXXX` || exit 3 echo "Writing printout postscript [blank] to $VTMPFILE" $DCOP printPostScript $VTMPFILE >$TMPFILE checkStringResponse 516 "true" echo -ne "Generating a test file.\r" TESTFILE=`mktemp /tmp/Kst_TestData.XXXXXX` || exit 3 declare -i ln=0 while [ $ln -lt 1000 ]; do echo $ln | awk "{print $ln, sin($ln/10), ($ln/100)^2, cos($ln/10)}" >>$TESTFILE declare -i ln=1+$ln; done echo -ne " \r" # Must clear out the generated vectors because they don't save properly FIXME # 599 $DCOP newFile >$TMPFILE # Read in the vectors $DCOP loadVector $TESTFILE INDEX >$TMPFILE VINDEX=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 600 $DCOP loadVector $TESTFILE 2 >$TMPFILE V2=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 601 $DCOP loadVector $TESTFILE 3 >$TMPFILE V3=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 602 $DCOP loadVector $TESTFILE 4 >$TMPFILE V4=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 603 $DCOP createCurve "firstCurve" $VINDEX $V2 "" "" >$TMPFILE CURVE1=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 604 $DCOP createPlot "firstPlot" >$TMPFILE PLOT1=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 605 $DCOP addCurveToPlot $PLOT1 $CURVE1 >$TMPFILE checkStringResponse 606 "true" $DCOP createCurve "secondCurve" $VINDEX $V4 "" "" >$TMPFILE CURVE2=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 607 $DCOP addCurveToPlot $PLOT1 $CURVE2 >$TMPFILE checkStringResponse 608 "true" $DCOP createPlot "secondPlot" >$TMPFILE PLOT2=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 609 $DCOP createCurve "thirdCurve" $VINDEX $V3 "" "" >$TMPFILE CURVE3=`cat $TMPFILE | tr -d '\n'` checkEmptyResponse 610 $DCOP addCurveToPlot $PLOT2 $CURVE3 >$TMPFILE checkStringResponse 611 "true" KSTFILE=`mktemp /tmp/Kst_TestFile.XXXXXX` || exit 3 rm $KSTFILE $DCOP saveAs $KSTFILE >$TMPFILE checkStringResponse 612 "true" # 613 $DCOP newFile >$TMPFILE $DCOP curveList >$TMPFILE checkEmptyResponse 614 # crashes Kst generally, bypassed with #599 $DCOP open $KSTFILE >$TMPFILE checkStringResponse 620 "true" rm -f $KSTFILE $DCOP save >$TMPFILE checkStringResponse 621 "true" $DCOP open $KSTFILE >$TMPFILE checkStringResponse 622 "true" $DCOP save >$TMPFILE checkStringResponse 623 "true" echo "" doExit 0 # # Things to test still # -------------------- # # Vector/scalar namespace # Object namespace # Plot content manipulations # Error vectors # PSDs # Histograms # Equations with variables # Plugins # Labels # Data vectors # Plot scales # Saving and loading # Scalars generated for vectors # kst-2.0.3/old_tests/testtemplate.cpp000644 001750 001750 00000001747 11544160210 020113 0ustar00synthsynth000000 000000 /* * Copyright 2004, The University of Toronto * Licensed under GPL. */ #include "ksttestcase.h" static void exitHelper() { KST::vectorList.clear(); KST::scalarList.clear(); KST::dataObjectList.clear(); } int rc = KstTestSuccess; #define doTest(x) testAssert(x, QString("Line %1").arg(__LINE__)) #define doTestD(x, y) testAssert(x, QString("%1: %2").arg(__LINE__).arg(y)) void testAssert(bool result, const QString& text = "Unknown") { if (!result) { KstTestFailed(); printf("Test [%s] failed.\n", text.latin1()); } } void doTests() { } int main(int argc, char **argv) { atexit(exitHelper); KApplication app(argc, argv, "testtemplate", false, false); doTests(); // Don't put tests in main because we need to ensure that no KstObjects // remain past the exit handler exitHelper(); // need to run it here before kapp goes away in some cases. if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } // vim: ts=2 sw=2 et kst-2.0.3/old_tests/testsmatrix.cpp000644 001750 001750 00000013664 11544160210 017770 0ustar00synthsynth000000 000000 /* * Copyright 2005, The University of Toronto * Licensed under GPL. */ #include "ksttestcase.h" // #include #include static void exitHelper() { KST::matrixList.clear(); KST::scalarList.clear(); } int rc = KstTestSuccess; #define doTest(x) testAssert(x, QString("Line %1").arg(__LINE__)) #define doTestD(x, y) testAssert(x, QString("%1: %2").arg(__LINE__).arg(y)) void testAssert(bool result, const QString& text = "Unknown") { if (!result) { KstTestFailed(); printf("Test [%s] failed.\n", text.toLatin1().data()); } } QDomDocument makeDOMElem(const QString& tag, const int nx, const int ny, const double xmin, const double ymin, const double xstep, const double ystep, const double gradzmin, const double gradzmax, const bool xdirection) { // Should be some boundary checking in the constructor. QDomDocument smDOM("smdocument"); QDomElement smElement, child, dataset; QDomText text; smElement = smDOM.createElement("smDOMTest"); child = smDOM.createElement("tag"); text = smDOM.createTextNode(tag); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("nx"); text = smDOM.createTextNode(QString::number(nx)); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("ny"); text = smDOM.createTextNode(QString::number(ny)); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("xmin"); text = smDOM.createTextNode(QString::number(xmin)); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("ymin"); text = smDOM.createTextNode(QString::number(ymin)); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("xstep"); text = smDOM.createTextNode(QString::number(xstep)); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("ystep"); text = smDOM.createTextNode(QString::number(ystep)); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("gradzmin"); text = smDOM.createTextNode(QString::number(gradzmin)); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("gradzmax"); text = smDOM.createTextNode(QString::number(gradzmax)); child.appendChild(text); smElement.appendChild(child); child = smDOM.createElement("xdirection"); text = smDOM.createTextNode(QString::number(xdirection)); child.appendChild(text); smElement.appendChild(child); smDOM.appendChild(smElement); return smDOM; } void doTests() { bool ok = true; QDomNode n = makeDOMElem("smDOM", 0, 0, 0, 0, 1, 1, 1, 1, true).firstChild(); QDomElement e = n.toElement(); //basic default constructor values KstSMatrix* sm1 = new KstSMatrix(e); doTest(sm1->tagName().startsWith("smDOM")); doTest(sm1->sampleCount() == 1); doTest(sm1->minValue() == 0); doTest(sm1->maxValue() == 0); sm1->value(0, 0, &ok); // undefined value doTest(ok); doTest(sm1->value(10, 10, &ok) == 0); //should be outside the boundaries. doTest(!ok); doTest(sm1->sampleCount() == 1); // meaningless doTest(sm1->meanValue() == 0); //basic symetrical matrix n = makeDOMElem("Symetrical", 3, 3, 0, 0, 1, 1, 1, 1, true).firstChild(); e = n.toElement(); //basic default constructor values KstSMatrix* sm2 = new KstSMatrix(e); doTest(sm2->tagName() == "Symetrical"); doTest(sm2->resize(3, 3, true)); doTest(sm2->editable()); doTest(sm2->xNumSteps() == 3); doTest(sm2->yNumSteps() == 3); doTest(sm2->minX() == 0); doTest(sm2->minY() == 0); doTest(sm2->xStepSize() == 1); doTest(sm2->yStepSize() == 1); doTest(sm2->sampleCount() == 9); doTest(sm2->setValueRaw(1, 1, 5)); ok = true; doTest(sm2->value(1, 1, &ok) == 5); doTest(ok); sm2->blank(); sm2->change(KstObjectTag::fromString(sm2->tagName()), 3, 3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false); //should not be legal doTest(sm2->xNumSteps() == 3); doTest(sm2->yNumSteps() == 3); doTest(sm2->minX() == 0); doTest(sm2->minY() == 0); // meaningless //doTest(sm2->xStepSize() == 0); //doTest(sm2->yStepSize() == 0); doTest(sm2->sampleCount() == 9); doTest(sm2->setValue(0, 0, 1.0)); ok = true; doTest(sm2->value(0, 0, &ok) == 1.0); doTest(ok); doTest(!sm2->setValue(1, 1, 5.0)); doTest(sm2->value(1, 1) != 5.0); doTest(sm2->setValueRaw(2, 2, 6.0)); //fails KstSMatrix* um1 = new KstSMatrix(KstObjectTag::fromString("Unity"), 3, 3, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, false); um1->setEditable(true); doTest(um1->resize(3, 3, false)); doTest(um1->setValueRaw(0, 0, 1.0)); doTest(um1->setValueRaw(1, 1, 1.0)); doTest(um1->setValueRaw(2, 2, 1.0)); doTest(um1->value(0, 0, &ok) == 1.0); doTest(um1->value(1, 1, &ok) == 1.0); doTest(um1->value(2, 2, &ok) == 1.0); doTest(ok); doTest(um1->setValue(0, 0, 1.716299)); doTest(um1->setValue(0, 1, -0.485527)); doTest(um1->setValue(0, 2, -0.288690)); doTest(um1->setValue(1, 0, 1.716299)); doTest(um1->setValue(1, 1, NAN)); doTest(um1->setValue(1, 2, -0.274957)); doTest(um1->setValue(2, 0, 1.711721)); doTest(um1->setValue(2, 1, -0.485527)); doTest(um1->setValue(2, 2, -0.293267)); doTest(um1->minValue() == 0); doTest(um1->maxValue() == 0); um1->calcNoSpikeRange(1.9); //this wil produce no change because the variable _NS has no default doTest(um1->maxValueNoSpike() == 0.0); doTest(um1->minValueNoSpike() == 0.0); // KTempFile tf(locateLocal("tmp", "kst-smatrix"), "xml"); // QFile *qf = tf.file(); // QTextStream ts(qf); // sm2->save(ts, " "); // tf.close(); // QFile::remove(tf.name()); } int main(int argc, char **argv) { atexit(exitHelper); QCoreApplication app(argc, argv); doTests(); // Don't put tests in main because we need to ensure that no KstObjects // remain past the exit handler exitHelper(); // need to run it here before kapp goes away in some cases. if (rc == KstTestSuccess) { printf("All tests passed!\n"); } return -rc; } kst-2.0.3/old_tests/sessions/GOTEX.C130_N130AR.LRT.RF06.PNI.nc.gz000644 001750 001750 00007242476 11544160210 023500 0ustar00synthsynth000000 000000 "EGOTEX.C130_N130AR.LRT.RF06.PNI.nc U}7݂ -}&Wvt7ϵ)JwI*VՙawpGGgȎssG{Da]GvP]uYuՑ9\^U"W:Y~NU_{{;B̓Zr$nO)SNt0lOtN q%6V@@A*]\PBA0;1'H3ki2Ds,f&=4CFyUS`EV{+fcjR 0fcJ}/>wcc NmT+Mؒ-pcR,os8qsKW(>'E)ooUt Q3Rؽf\fJեRanS)KSkSdAr-%ܯyOB*[Z;#ׇ)>vRufF*xrY}ѓGTwEk $#s^PKli_ծp% aGνiD=B~;ʒ~Q sf<炭}ua K\_BM1IF>]tmBv q,@BXCXդd){)s f}>GEpf ;*][n{;\T+F4 D":%,+% @ЭתIռ h #(} +]_a,Ϧ^96$h3|}ϞX5$lnCDz #00 P!M<g`hZmغʸ Kb FʁK 3%nh]v|~C䞈o"&Q![&k1Q< af̮3CÐWaߪA,)BD+jiźףN[}|GQw/5^npeH$s0$K 퉺ߥr"or,G!ؠ*^xJsIbF1FcD\j4>/j r-H?KeteJ.qL072SS1fm$Oy1 ϣIpsJ!jmCU1?iq1lH0┶C2Z-"/}n0K3OjMռt9.zkx(C2, $t 7Wsp/?-/En$%iIl_r#R#[[#QABɃ6au\8Ə: !xPYq̩}6>oCilj78[ 5c}ܺu\d襴DB9,On% 91~H Ϩ~,0b]FLbXK$8ҍO4>8g^sRk)p\#D#sӎ>/>]1O]: a y`6'vΗfԧ(wZnt v[ 3zi"K_L+5 \n914y=W1䉳-g;U]wh_,Fd5 ;a]eg2d<]ohpao &a,qW+x#mq4#ehv̈́볼qk}GNca9Nn泱oֵN!pp LJ֑k4 Fy. v/wC7hU[[ȯ 9 scn=#(i(_ zm~FcMz #8@Ɇ(bs>q)\z"!eXfIFD)RBq̱ĒcIT>3+Иѵc *1kg ;V_1~O 4QS9۠|Ók_1'6h=JݔocSmxXMj_A| 񓼛bmruuvv5X1~ѱ>\LQoO-$!a^üBԃ1ꍿtJ® 1;q3FjL4p Sp<L)=1/ IsǏYA}Dv'*w Pۻ8cİ d{f},~lo .HR Ēfό\33Z*l˯!͎YIiqtDu_QHeVtw$D^& <#LvCl= Ec.F_X ֽ>/ˑIJңDC$~<5eǑ Ӑ"L@w"S,>r)jN]̫4S_2p(\a ۩Ѫ/]/b0ݞ7ù"ä=vI{Q˯G٩ ;DdSZ\9IMAM1ۼ([(Of)I6)^݉Itje0sQ3&ŘTfP*>k>y9>gl>/ġ5ќW9`c^uTѻy OV>¹?&G2QlPz8}':W8BLo$3]/tSچ8abeE!Te86ݸ,qUVTrʊ&z5`Eh9ݸbk9zʵ1)kUk燺jo2/i,2Z.H\Ek&D^*%^s=OJK&+>d&TgQQ/ߧc0ITur%zfiu:I:YHS'x{q'/k¨FS_{4lZ"͢5m,^ 7Wcԧ0\VYwBs}Lf%5{OK7j^.͉7j>kmeUV #jM>m@yZc6uhv_j mC[/ohV;^_ZK /־r9sUڏl~VW]\^7%“n-j]tF嗺>LʭC:o2`v|{MI694lrr@֙-GSx ەsϋ17T-6tFԂm4lDԥ]KFnȟׁC9}~V}|=:0HVq aa MW94q.3p dOmԊq"cCGm ^@X-=b$zgc{:AggYlz%i?53q@]%!tu~F:6Xgt﷐}U/3҄ק[w,Nabޗ)5$]ލ)va H/ZQ49o x[}3[+'؅-2OυY/ PF@M`ʇA{V6$B( }Vb0a,97@1GzQրd1B P̶JQ6c=cʶ 1NJ4Cev6}c(!Xh V5b%|4?4Ym_%`dce:0С 2ޜ$5R5fՑCy4iN,F9:mZ `$e37jׅ|zѝsz.\Hڷ0}d۠Ε;2#}R:7mt:؊6IsNZiOBmH,Mݲuvri [^ͅ'KiL7QLbsc1pHhq}峄tOOA U\)k1QW f(Ӑn9;1\cQO1 ;mz{*uɔ>ikaٍIzI)ta7I7Pv s#ٵ 9Ex*N1NQ>zLrxI |^{{.3ņФ ec,2sϧ-$ :ړo??c>:ݻ$mZld=j?͆%7uBؾ1c"NjšĬ_ЈwiʼnWu5s`l[־[! !΄ ? {ֵD{ފ5euB53u s"g+Hxws >-1F&1Za6#2re+Ou*H=Hj.0lL6b \dq{8]yC^WeEGtF(F,zS˼7W5}M;}8C,q9j|OF52|Zىs\1.erɸF0b3¯4}M]?H݁ұ)byar0j˽=D:Q9=ht |cWX[EͧA_'|7}Nu/iOD{gWU$;] @ri-[=g $tf^_Ц2 AEEd) [YD7YANfM& |?$y~<ܳ|1e-3 { ίIY57yLt^j2&{sZ񮺿~X{jSkH6%ɉg=AV7ԇmis}Դ)uͳŶ>ݫȞ#;Z7#\ӳ8cטԤ>/ޘf#oPw47gu}]wWq_k0Sy (|cL-vޕ*=bYWY/ԬUw`}|C3nmu۽Ǹ֯eo՝p|rnK?=Y>҆h&9Qu\ϮwĴ\E?7r[30?h,-UiGWGՖku\x-}#AUŅYi;a{YmK[o#=j b1sZٚ)uAT)q" +wm٬}^<ﻬ|۸W:rHjRqr%]`hcO3Vf4C;Y'WnhM\|'lSѲڂcEi;N,߯S 5E>:Zr>=~> ?+^xw?~P>u)N]K4u^킩~ҿ+ֺ>9f\KU95)MФM-TCj<7=ۇc^[M(G~_ᷗ9ao@9͑ϟKY} 39yENL[͋nu_.G~wqsGؾWZnsS׹pqsC>Om6Ʒ3 's |<\6fu2qB{5~tNlnonJiףr'U!mh^gh|y_L{JI5>h0\S7kM>Q]IZdksA("0ٴz{\* ZY-=s rOs}`~[sW*4uUp/E뿳s*^J.2ߧդa#ߤ^ j_~_ufJCHs6T=E돭H_'fXGУs^U fX,ևCgh_zPqS]|b32i0ϝ}sEp^_:k" kU"hBho5̴H}=^#SuyZ?l B=xѠ֭k5hR֡Oc~jҠ!CwG)ЏDTڶ!}+anؙ⒂\KM3F^Ti-MstxHt[dŲ,_N+!/~PѣӆS`~~<1oU=ˆRvצCQm/Q}Wd{r^j/ϲOQۗ!s-{#Cߓfd.<6o1O6obg."_z[WW}t0ix/y9g4;k>usN}gliy]Q- Z=^y˴:]uRG" _yx)Z`hIX߫;GDuV?nf,t> 5_u7w[ ~޼<:S*V2g_goa_yk7M-/1^ymŗN܏<(wg-bҌBS-~@3̇,>.a)u}~<@L)#'ݡ^ W8܊M6|WTlln}V/|~\R}tĦZϭ%Z/DQU9QԠkuHЇg#󏍉EyVеF,VxF4~)r*=D5cY$I;O=hc,'bS1;^*faL|=r?dUzև2K/Zs덵`/~gSҞ3G*$5Zb:WsLZ,j"/KФ{&kC)9ID[wtͮkccڐ36_GOphUbև=MΤԔlfXܟHU9קwuEf>˥3aqzv5YD\` Y rE{† XhشýKkqܮɧu#4uctYtk:iZYF HT.nA+VUπBκiv. HZeNR-ؑpd;ø.ZۻhG,zdq.XN(Tm ̬&oJ{/\n1[]_xGuQ˶fTm`T^:g?5'sĥZcvx09@Q0mkFCjs79WhP$[T`%7n[r{ 6>i9"޲z=+%u_Xq8\OS}}F81kO;6I8?vj]dϳ|NC>yz+j&̋.gMK<^O7cڀi \geӫ =?tNxOrLjr5mjr-+^ꃧ;\tN<ou!.{SOO~aeZ[_Hd:'yz|I+bLG{N<֡/ϑ2`O 'mx[UOx(禬yf XWy_uQMYwKyW /mʷ5.f[r5*YfIk84^QLN4d''ԌA8 u_VaCqpKH} G{l򾴇bp~.Twi i8 0512nIA1܉†CnBJ |Ξ(ʻwLn֪^ySRH0o׻qNWEQ(C_X\lmF(m`ׅ>sfԗY -$~Unwl}`.5V@DT;ZyĬf~G=|4}|.>F40aoc輿^It_5R#d}gЗ`c1>Nk֫1FϦn֛/`|NUN>Z'OWSa;;/<>b%??])v5v- ~&/۰;0~[ ǰDZ'14ԟƞŞS{3_1j&?02"}Li!ƨ[* " 1BPC^m E F`#1H`a&`+(G76Ldl 6|4l:6,l66FI,¨ #n AKe~DQg l% *"|$X^ Lq0vFX#RX0KVFz(NjðñuSD#1 ؈ $"Q=`"08h邺-Mfz.x:/N¾}ۦl[8<- q*U mD| :u"NOOi;7o#q-[ mJ ҾķAښ8<<݉iGq>xxHNE mV\^ ^ ~v22,~^^Үq#Aڻ /~ ^^55 1A\ H|ׁ׃׃ qx#x6c'9s"n$[[@b%x+x+Hqx'x'H;@b$.{@bk J H100HLow N<=HOO@$ P<#HlOππI,Hσ//O"H,/U*'O 1V x+^__aw 1Y ;; Z||$n}_@7o.>???Ǡn+P@ ~AGBx!N!E"8},Ë#r(|(|(>E +Ep9>>N$GGG(((8}   cccYr7n_r,|,|,Lӯp89>>N'wN'N?(K%8}'|O8 |/8}7|o8?r2|2|2~VNOOʩp_5/r:|:|:>Z΀ππ_˙pn9 > > N?.ggg8 r_}r>|>|>|@.//Rx)N """8\ _ _ 'e2xBpr YW78\ _ _ '$r?~'r*-@0 A3r9|9|9Fȕpr N/W$$$\HK{I.ɋ$I$Q$jJV4II! 7.Np(YWɩjjj8WëZ2p.y0$e\TaBa8&&bwa`b'(=؍-sR@.>0sMsoi &9(i=&CsLk3i_ܗfZI܏~4ӚMڟ4o4yʹy iu4hi5t̓hD314C3iL`i(BLkBP|wSϧOq ӞNZ@zuIR_K}-uIR_K}-uI R/N{@i!Bi?(-^D: EԋQ}tuQ=tuQt=St=S}z1bǔS/^L 7P@ 7P@%KӞTZBz uڟJKR/N{Ui)Ri*-^F:ae˨Qt#7Rt#7R}tM7Q=tM7Qt37St37S}t -ԷP=t -ԷPt+ԷRt+ԷR}tmԷQ=tmԷQt;ԷSt;ԷS}twP=twPt'wRt'wR}t]wQ=t]wQt7wSt7wS}t=P=t=Pt/Rt/R/^Nz9r˩SG}}QG}}QO}?SO}?S?@P?@P?H R?H R?DCQ?DCQ?L0S?L0S?B#ԏP?B#ԏP?J(ԏR?J(ԏR^Az +WP?FcԏQ?FcԏQ^Iz%J+WR^Ez*UԫWQ?N8ԏS?N8ԏS?AOP?AOP^Mz5jԫWS^Cz 5kP^Kz-ZkR^Gz:uQSSSSSSSSE"uH].R@uԁ:PGH#uԑ:R?I$OR?I$OR?ESOQ?ESOQ^Oz=zS?M4OS?M4OS?C 3P?C 3Po@z 7PoHz#F7R?K,R?K,R?GsQ?GsQoDz&Mԛ7QoLz3fԛ7S?OSO>S@P@PH!RH!RoFz6mۨQDGQDGQL1SL1SB 'ԟPB 'ԟPJ)ԟRJ)ԟRFgԟQFgԟQoNz;v۩SN9ԟSN9ԟSA_PA_PI%_RI%_REW_QEW_QM5_SM5_SC 7PC 7PK-RK-RGwQGwQO=SO=S@?P@?PH#?RH#?RDO?QDO?QL3?SL3?SB /ԿPB /ԿPJ+ԿRJ+ԿRFoԿQFoԿQN;ԿSN;ԿSAPAPI'RI'RE_QE_QM7SM7SC?PC?PK/R_(tSP.lC/FGxzW.6^N"yE+W$H^"yE+W$H^y%J+W"D^y%J+W"D^2ye+W&L^2ye+W&L^|w ߁|w ߁|w ߁|w ߁|Gw$ߑ|Gw$ߑ|Gw$ߑ|Gw$ߑ|'w"߉|'w"߉|'w"߉|'w"߉ y*UȫW!B^ y*UȫW!B^*yUUɫW%J^*yUUɫW%J^y5jȫW#F^y5jȫW#F^:yuɫW'N^:yuɫW'N^y 5k A^y 5k A^&yM5k$I^&yM5k$I^ݿnZk"E^y-Zk"E^ymk&M^6ymk&M^6y:u!C^y:u!C^y]u%K^.y]u%K^.y=z#G^y=z#G^y}'O^>y}'O^>y 7 o@ހy 7 o@ހyC 7$oHސ!yC 7$oHސ!y#F7"oDވy#F7"oDވyc7&oLޘ1yc7&oLޘ1y&Mț7!oBބ y&Mț7!oBބ ySMɛ7%oJޔ)ySMɛ7%oJޔ)y3fț7#oFތy3fț7#oFތysɛ7'oNޜ9ysɛ7'oNޜ9y -[ oAނy -[ oAނyK-[$oIޒ%yK-[$oIޒ%y+V["oEފy+V["oEފyk[&oMޚ5yk[&oMޚ5y6mې!oCކ y6mې!oCކ y[mے%oKޖ-y[mے%oKޖ-y;vۑ#oGގy;vۑ#oGގy{ۓ'oOޞ=y{ۓ'oOޞ=y;w @ށy;w @ށ;L3;L3;L3;L3yG;w$Hޑ#yG;w$Hޑ#y'N;w"Dމy'N;w"Dމyg;w&Lޙ3yg;w&Lޙ3y.]Ȼw!Bޅ y.]Ȼw!Bޅ yW]ɻw%Jޕ+yW]ɻw%Jޕ+y7nȻw#Fލy7nȻw#Fލywɻw'Nޝ;ywɻw'Nޝ;y={ Aރy={ AރyO={$Iޓ'yO={$Iޓ'y/^{"Eދy/^{"Eދyo{&Mޛ7yo{&Mޛ7y>}!Cއy>}!Cއy_}%Kޗ/y_}%Kޗ/y?~#Gޏy?~#Gޏy'Oޟ?y'Oޟ?.仐B .仐B .仐B .仐B  @>| @>|@$H>| @$H>| A"D>| A"D>|`&L>|0`&L>|0!Cȇ!B>|!Cȇ!B>|PCɇ%J>|(PCɇ%J>|(0aȇ#F>|0aȇ#F>|pɇ'N>|8pɇ'N>|8#G A>|#G A>|y y y y y y y y y y y y y y y y y@^ /Bxf\Cû_CG>A4/Uh tSqjGa{4Hšτ? |p/^bϩ>a9'l.9sC3_Tl; #WfhW8YNlyߖ?NNNW^ΉŒoIU)uA l}-zz }~H!jkmo0~= kZ_úiA[ ytR}68+Öo:=r8ƫA|!5ǀ'VP/[)MrhOg)Je%< VKWQb0Jm`#: NŊïHDEԞh#noV-_?0L! &̆;OBF1H5:%P8JiP:Ά&t'4wu6ܹm']Ůk53 FJd> ;Pq7:o}4FK|YW&o ^? Tz>vyR98DcX[ z 0"fF,AㅽT #8{!4w>Nax#{&Jm( DnRʆ"zN#j'dlCh[F}ԟ B4LD@47BOPm/|T*[u = mAh+Z9%h|Mu6akA^%4tW 4怆zz_?B7R4W]6K zݨB6 y-P8~yCM7g]vcI_n _nۥL  bD=0rN;1>z]~TW 3X0, z  8,^ކVI8fi ®l9ԎL*pl2wc8.}㪔pJX!`\v>)99'IwBH0P<},;NAH}}09mW G4asmrr6 mF7b=v7mC{ڡ@1hwUoUl9X\oe@}*&YUC^Խ;̅\ڶ@hs ֚{9u>/r4>'~TZ>Ka={c'Uy_§YdxݷZo* ]-Pw>PY2 ph/|Ezp%p\ nˁ[Wnd{6;j?3cFShj1\Ex~ |w ^Q\ iZp Uau%9&Y$TiZn~:_cĤS\ez:4G>h*h!tp^O:|=/ ]!,tD Iz: !/حf|<]kE*4VF;.y31G: :C@ѷ{4}נS4s#~ކMw;zǡm|;E.D3t/ϴ@^?|.Z'f': Ώhj1а--W|F[h&g%ZE5h}9-5DhMGX{4 9fh:-ƢGAxTT@ShV?64ߌE?b2qyؓKgb׈-]x {"1"]Cc;DKtvGq"J3ZyEh{4=dUUZ^g/5?a7ٵmt*F6ot:sCIf{FۯsNGI\@>4s ]'ؙ}-[:عrC x+ԣO¯k |FMF=tA;Pw*< ,Q*45*3TCbG=>j>E7 4z~"lK:ԟ/¯*fkY#i r/~C},pYYFhzju{2:[E^ :nB) PO*EI(? G+`O`*gPy;jf/Qc Y UӠ%jg F::N r;ZWNޠQz58"۱@k1T(%[ O,HjwE5SN?MZFohK:NԘiǠff2UFv j KQ#ůB3.SvZڢ*T >nuXgT\; 5aཡ'(y3VꥃPeZ霅}o9T꧈jg8%nN,4uP7 ~ul4F@mlEm#\:^ZQ 4ekzrIv=_ƔݽPs"ԙbΦhPNA1[ $Q[GBW8} W@>*Q*Ae3&*]D5 7೶-**tY ܟ 4<5P?Vp{;:3g˻XOpǽG@{OEMC 8k50UmJ GgN\[4ﰹe'l <]U[]3bBUo7uO'?u|"\\ 7݂[} 8fnɃ@uj8r ~aPk(ܧt= Uf E?`'q˴ืSazn[ `#؟z-QPz# 2< ^! Hqr ԀuD)%RQ\Px,]e!cȊ2@3TAny^P2i?rS eS 4Y<^SiRU7X-, Yw`GSv&Ha0uĥ+S_s:LT0v՚ Vtϰ;q0آ"]`v/t~yWp[!9"̆^;K%ܗcbm ^c8ɏqxkUyf9]E`tw2wĿFm[:2P)~**:#^vIybU[( : !0\`.#^bh(hχ\߻7@ZK#"~cؒpH8c,+ =}oiPx&|yj>Tz 2Q\^)“{c >ãΣp^mWdե/j\)kkMMhWVvmp[g.\0. pgGд\Bqhc ̈́vY ך@_\YdWKᲲ5oggHQ +}܂P;N{8 ~ 8v,`89NEjPqԍ/ 4ZzCИzNFhCE7oTl0RXj1dϴp'@a8]c]GGvp4~D Bc~hxpwK]-_?M'~i-֑piz\ -Cp|Ǵ g 7Wvp`</§!xq%ӹ4- 鯡*{-}+_mp| _c'S8s~&T}ᅪQGP-h8jGp}4|7imEPjBߨ?Σ*$|?ffЌƉh\M=m$݄]BE˷Bfg6cp)蛣L'tZ뗢Z ;`;Q#T6E.è_?O{H ~ArpP>1րS W! GWqzw'wǩ98#N '%v‰c0vi3NS؇sp|\ "2\|8θ툳VSptapN9X"/M_s0n:Nj98>} ;\'Ext*%g0aF6.Yz yKTqL|oߊ{gچ3i/ p8uhL[+_u6L8n8=7(V/YSw]ǩ1N93k1.<=p]>8r2a89fdb_{{%NDivdzRF % Ʈ[DɸW1r>R7 1x A]}RV3p44ZތcQ,U QJGҡa0vb'v|ʁi}u4/9 Mkm@GPq=ac5u %Y Rw]魰"VwU{aр0 ̙ υg_#p>NtE=>&-Na=^nEX, U&*c8^O! |3tz |w_[rH77 s ;022ɀV΂aaG0+ ^}/U+>LVAA?N@c9FjB4pԼ I}}Xvu G[Qznx `Ek "7NJ芯 Ŷ7⬄\ +mgq뾉֋]ݙr|1~cl:O,g]KSGqmbx.!ukO9Wmp-='|OySO߮(O6y]rT9+o]QԇL,.vEbx" ,oΛ- z*qO^Xl!>X>zuO:]sūċW]wNjkλ"A+hw Z7Zdz wQwk/IF/w&W;_ֿP62]Y⫑ĶK;V[[^7?ż żbb~b9{#[u7A,(#~v/oOL{bDq}' r[0B5UMŚ*|lWqdqsD'ĔbQ<^uPKwx۱^^k۫fJ"l|no{9| Fcx^e_mr7Q2P7l;~.!m5`NetN$tt9s(tD[Xt.K0Oq||UGLgDG%:WD3nkӯ7z+zN}& J:~g6wz2нqz xi3znA+FWt] 1q }1J{b0gm_ēxQ}tRݮun˰'{bf2pTz?s F/A8^c bLI< D~vG-8Oowǥ'S#p3$p8i^#N8']݅p܄'? ٥8N}4Jq▾8 "ݓq8r66郃&,\ |1!8x|=ɩ!&ph ىCny1g㐅W i-}nz#_`-8HI  _2;eS8POc8`68>V;817`̣_{ sv85J!KGע$g KҐ4FVlqtCkQ: Im{JcE jm:@1vWݞ`u sLbC/=` 6,F}>1g߂~@j`c1PqШ#41Lk*F+bxHF#LŮm(`]u_c7+m?JOî3`!HD.UEnRu} 9P 70SC=#P<cCPr5NnUgcwI{ϱQkc>^vZ^`eUN_1l5b nxѧm *C~WQ TF;H.}:՗hBE3h}%P#.?F^ر <N oBt26 `nUUpl9Sr@X3%m`tcQ rgTAʆaX1̚2 ƘO %!Yt_V};3|${v5C5Y| d@z_X2lA0#L8>? P5+ a*@~mpAv{a}^Gg%/8̙ K@/O¬..+rOOj(8.z eoWd]غlSLͼ ŧ`nh ſFŪ@Ѽi܁-6J<FCJ6| [&{.aY#g1lJV^-sw@Qrb꠬LGZ@Za'țx6-gDT ;[uiPlYMS`~C+pq]JV8| 8=ul s ԐcAx|dܓu ^F)qՃIՏg΅r4켱ZChiZh:o Zv\5(]@oib:y:q \%~حb<;1r,fty1d7cll2 |j4 'J1|`/ màQ>c>3ѯWjCz\tnC~zgۀqmNtΥO}=܏Ǟ%0j c3{wq {bsJפpb wɻN'ZFRCz &%[`Lk)1F\]?UqY߅Sj&jHL0s>=</c{n%"Wtǹp].qn6\NφS?ܙq ]rN; 86[#Mz&Y1co=|Bv`7FbP#ݟ]Aھh=;l ߺj9dB){r PܡG4vpr6\O VpiQ ް;Y}B /ѪƗEh8#X A> +GÁq 6NA`C6F@$u4hh#6_qwpι^8O:z (]~BÞ hWA|Vv?Et0.iЩ>_h/ZjlFӾ24s58v>cT {Yzi݊/<сPwD j/9{m(9pz4 @ ٨phQgj/CX4[7uGۢ٫hЎnmh(Ui=u+{αh;עm>~)LARԸ:Bͨr|'躣LT>ʀ{gx9{&niN h! ;1hRx哱S7K[8O;kMT|"/Nzo?Jg1hnEGvÌ.^3tƠNr;|6 Ѯj,>Y Q؆n곱+}ik } 9j wC%`H˫BV V `d@.?Ŧ:l6`,H_S!m.H_ d3ôm0!Ar|" {aQ.t#^Iέt?n͂2:q1u~އ׾75j/H鸱6iԜ埚+#*jlU8VxƺZϟj?0©Vt{5Ի4kk'O[Y/1 գ]. aKGt(яpl}I8_jQqO+3B07vgĦB2WI~nŁ; @]vJs8b߂د4|h'KQc"*J f^kY[S=l$w &SqHt <-N#r0Vᕺi#.WtzS(Ϗe~əW/r}qrHgyj\i~xP _3' 6q6h3[10V{c<;8рO;Fx3f|b),5k.`N=1PAB߻WygZLͲ#Œ噃bF+&&-9&菉,|SE] fA‡ } BA-H# MԆXF$_ {ƀ`~krh\Wn { YD{ªnh(*-3_)LƯՏ@stN0WG@ėfW|7Uj(9Dׁ:dPqNJ1zhQi[0[:z~[7J/oԋ'Uٙ9[%kk޳j%/vK>EDMIɒɊ^ZnbNn(kX{ Eor<=\l~DdIT> 8AiUD<"XG\?)dtntS?䪠1~ zBDb Q_3/dCDѱK|Z 9RO{dOAGZ.LUL a=ݘ'|w%7׻(än;q ϴE3o (EB侒-i^MιhB _֋e 7Ly y,fG؏.G۶3ˣg&;+Xli|5?$oPSҕ93!pzXK ŨPUan<|"(խva^L փ^< 'ՀR}_'~u ƿYq !YީjEsA\LǠ Y n`1h6共8N#N_#F L-fB, wUTAIm^|>F?fUo)(l1nf njf w>Ifוë2斱Mf>#O!ul0,8n[04d:‘&2|غqB~7fǘ ؋b.0-:6t6z,\EL\ ta4cѫ;2Ejf;͉sai ;5L8Հ^2%iA,d2^xQo,g1'f±̥h(6dKYiWl,7asOm/#b#&2c_}aNgg2`y& ݗTb#_އ9ľ`kn(Z 4wL?ΙZ[<3p6>RCp'S~0]بذqgC_-%d=}!TҙNPfU\YB6c9u'[gf.irw^>?N~˹a1S1T®';p}Y~}?>+ dfS[(u'vb$vv0!kƿlî&v7s1ڀU Y(KXk,Kb5uKV:|[W`0 8ty ۗeݎ -  7b^of}RR6HE8`>w6vٛ5d {/ 3ų7 ֭eُ~ap&9[Lԛ=F $VF1jb/Y7լV0=0[|־Bn1,y6sHe8Ӡ5e_cɢb߶*%— Kk<07di>P Xc93GÄѦ#Nqc$ahd&1F!{;8Hp\X4,tgqaAWhr`ҏsXrs|Wd#ٌ郠yy_ɍ<iL(_0֜:q&-٩KYny&[0|up+KgvZ5dpbۼDz@ClEe {PWﶳy,Ig9F,d)۸nO1OC3+_c'ԝUvmzJޝ7 ;6`we{1۽(KigHvow d?؜i٧Ϫ|`I~X잓 pb2WZdy֟1ke ؑfZS>ͣwo _G*U/9XeE6{GHf"Xav-{yɒie7j؉cر=,~'Kka<Kvs~B=6_V׏b cN1XR3vdcT]?e,{ys?[U xUnh9;0KrO){9m W5V8ma6؉Q KKYlF=m6-%%İ~llXV^d.TإA-^m&j0?;B;e aYXb`w`RA/XU0?+iQfUݚ e/r 1Lb{:Eլ(ՎmuV9N43ʶ(d^{ԙ-,oyv8Ԋ1.]yZleZqXţ[2ZN-d+ZUuy/v{z+5QfEQOTg-Z8jc%Uv71tؕ3*2DZLv'Kz%|fsijao8%r{ɎnfBF;v}mvob${?W檥IעXֶ(5Eg~g<9m>} ig Sv=3s_փ}֙;,U^+\ֳoiwYumV9YkkƾN.g(ɥD_H?c籶%VKNG%̋+z-*ܸ\5~ُ+nF_krź˼Srb'MTٯEGxa%{6}Y;#f.Mc;eC8̚_e'dӀmٲPO6z9-VfQY~l3lUfv,2s:ַ-&|aS.IUl@fU1f27>GذY_UaLR4wHg76&8g5y:f ,g3YI̡ɋKdݪrBJVaf;3Njy+ǯ̞뱅zyYU{ӍM`e 39idU.#jcO?0Me5]σSۅ5‘H='\RQI63@1a&u]n'<,mC05) f((Uz:X:fiߘZxzE*7Y%<˶C^] =ltč)=]@ҿ3$-̀Mv}`ge$PRa5`p1Q <@4\!- ?@s7`}H`|5o y0 /!p( dM`v8ǘd : ǨB]>U!tS\ s2j >?aS ;3x3}U!:>rD[[$+cىsmOPܾELvVW3E8a}Ol|N|n#Ub e/[\#{Z/f'[JnN+&Wts|[EY^EGW=`_Dg~n"Q>C4rU@哷ؾRl_[bA*)?BՇ`f=Mgn꽙CLR\Yd팇̆'N}1)La*L_YfLSgN G ]}g꘲)L_GLlS}Q<732,0K3M{&S+pc&/ݙ"YȘ(i'_`{3c ٨?`lzƆzd1M,:8 F69;يClh&мˆ)3wXJc,`GS&Dlg*#&d)UlV#zMwKIRw cKМMx<ŇԂlC`Y*?,a7bng^cy}llШ ,XňEg3kܕlY6q,8bz{fX=llN6/䳅lٲlEylYll3ln,6W$[yڿ-5Oa_)Glt#,v5]-o˦}b2V}]oi8%fʾɇX5C6dofl6",bcm-ܥ,ê'+&6*zM5f󢺰bO6sӞ^a^Yl&?M[i&.gC;(Swc `cGvc Yqll65u űOYܤlq[0߰YX\`l7o9z~`=ZٰD5׹-piTSm0!5PP1"vn78 ̇  [6h6v\IP8~pK!Ss#s+ szD}LauFl<pտ,Tm& : {lڮ3L 3_lBYM^obÛc , rrx! +bc^LeV0G%޺D]cQ.ǂSy #3_Xxv4To=PfCj݇f 9b'̾8s9ytM͂}alձ|{ yL^LKv,z8 }L܇NzYv̴N1oVLAPk$֐_lz*vw֌2Va&BQH;^x/?ԌPmdMGIk Vh]t\ BH)חÙl6y69m¯gBɮBmqAwav{16_joE 7gnZkVC糎‰•o*eiBҦHa"WRT 徂'bې3{ލ9%Yf| % hIq٢i{^GęS${ע`ヒw-k V}gKF)y {fd ޜكA|Тnb&>S0K\ i %kwl8_Ht gp#J*ݿܯeD[/}෮Ɇk@JT|eʡ*i*\v۱b!`g("|UP{n$*Єv-t!2v%~E+]h l<v*|N푰1l_a;VXv8~#ā]?+lRpP0AqPxB"Y"w(PSWݡ{ aO (+>(Zڪö`떩ٱ#(܇=;+rl]8 `'x)["\iV=Hҗp~u LJwL/6U@9P@矡7ab˛%ć/ Bmos;\ijŜ]o1a+^DU>cw:9^1Pf6 6|j$_| %=>Ar 㦅–2daCfn(''~,!e;3X13r讣E{<X%6,~X#>ݫ + ز;W 7gvXrH˚`}y.vA8_4K^u_ݖ'Dɳ{oui q+×[iBBfLZPfEK)l+\P Q6{ < o e8voLVV RWYk!o@n(2?0J۲2C\j e=q\J=9!nTB# nՔ`U4?+Ĵ^#le[tڵ>QqoWԑЙWzebKo?qz[Ze qoKb~Oh@_bjIٓMEw{E4Kh}uBusIޟ&aW•?MZ6H o;~,fAC^2'oX~L#<Ά5c 6Ȏn^ƺ^RebX b4XeN lǴ3,uX6r+>ܞ1 KjcC k}x!S.ta:lǖZm`-bC[0wy»˙zl \bz &lfm\֯,`}ټW%.+$})Te놲AQ_¦?mcYqH}Śdl/ | x_ggFaY+A`lppyf4ͯ/olr&'#sْkS녽#'qW"bp]'f.b'Vg(?$>.)h-Xl^\u+,` &W5{(# Ļha|BSba}z3#Z=: ,#{(;Kph> ;.}ifvY3C6SZcqj; :7 a:_] V2mB[д u66QwqE!\8Sl\_-Ew-b}$Q稗h+N,.k N=ެz5,\#~)1bZ bEPx1boNL$> *xKYlc ErG#$^ebaiax-u YpX+ &'?bh~5ѵTJG+R/Ins>*NP}Z+A]N Zlnk}|`c\(<.{CV|+=VG$=6Zlz9|D:=:⛬! 语  vm% w`qgi"> yr U 6kDOvW,!yyL_~V0HFSviTW|ŷ/sV0{CLʼ)6拫Ե_&$SvB`K(86fGs? 0 Zag^ bQpᙻ)W 4^,q'P .Z 0T&~%~#i0^x|$FX37>DMpy9#Ҽ+wl'na ]"Cy8ҺU  {] l:ip!Oea{ѳbXb!B-j5c*raGX_'oLEI\e]<7EwAp!~A1R'ݒ$ۀ8Sh yw: >!}1C<).mh`6˄wDO aRS*Wp(vQ/:!xUhͮ)$Um{}'Tck~!摽pray\fEN§%[@C16I >WE?ue()9 j%vd0wB?nV3φEuj{HT4 %ljcӄƊ;WȟtP#Z?,"--γW9]xN!4%<{>9gvY?ٳфg;txͳRxVsVs^9K?.x]7g'wxv.Xųd<{ vy :yN=L<sMgxn:^\=q湟s\|s"ṁ{y^cun\yp,p;P><swrg4ܳtQs*[S ܭ< <ِ]=RWx~s^Ky`CxkK,r{Ag\:rY\e72,j+}+9gJw䲋\Y_R.;;˘?2.ey~\ЈpY e,˦;\\{g>e\ۂCx}|3粡)ủAt_set<3.FXUYey}a3:rgL߹0-17glϺ[e]yԓg0o'̘<~+yϘˊ'rYaϔd̋ ;̔/<9z7Lc\3MᙷRy 3zpY89;;t 5Ct7Cr)҆>H?h,]ld\VqgyvYh=Ɨg^Nkq ZYr}+ωzG,׼Y_,jsyst{wާ52]cimYg-KYsy}qק<3}ȿ=ٿkGv֒y֎<{B|֜KlEkRCyM/[yvg[J.<{ 7gI>~mg MyNZgS5眶C^xó6"7: rc}\\ߚ{t=kL8]{'9]ˎwwmF}-9eL,˛g3+Ligqyګy"9eg}3п3vԆ6Ʌ]ʯxڐ<}Jw}e{23*xF7ˀ<}a,ϸF6etjx>7qݥ.=𴨓< Tӛ7=}q'dm.xHnӽ)~tyF*݇{' +& =<#;g$ѽ>73߂_ZOZYո~E9jeu<өg3}= Jyz+2t,Oc<}G\~i%<=-O[ y깧1U)?taQm_{P iQ[fRa@ n0ʜ{9gwym2=y#}{GsķNVqQsd=Dt#;E5矬1rg G#;eMf=֬)a}"LXv k&e"ꏣY"UCGX6U]YaU V}ꍳYP>&nGxw vJޏ5~,K|W;zXGYaVO8b5`NVEL"nnG D LH5fӬ+հfU8[fYύY/BVleuQޙĚ``Vjͬ 14mYc:kt'sZ"Ro:GH6\>)Y‘ 8&܁gj3ema}k8b4趕5=Ntz 9zuqGj9¥?G<ȑFL, _r@9bk"qdH_9"tk^##bO.0b˚7 8苈g8BptwX pDwp# X -kAg "n7? #.r #JaQP093YS35E]:};F+oqY%w!fde`$OK5ڬY<>?cd Fsq,5_ait1wGb+ݶGvC> Asbr:D=sz@Hsָa{`l/j sc]=,ì8|XU+_8VV (@:">FN1QO3Y}O:X5}{|*b>bRfb>V=5s VwEz|O/j.\߰j;l6~5&&or1 9ykxsll;ȚiG7uHꗟ9A!:#o|&yS1h?XSɚ6b1rk'p-GDnym?_kԧ^h"V]ͪŨrX&X?vcMu+YrQcVFYS1>>GlX#֖&.&FnXF:kE-Fvs*q_55P/V?FC @x~&uG[* ^_*M#ڬ}bX>x@gcXi7w1?(3Px?;VT/3 n]r1/ tcV9>T%@-Ff5>jV0V}|:c?qw3ᷗйϲf;_ 0 2hѯ:`3RY m4?FG1وc-wusV_fu:Yj4bOpFv#΃??jT4+rJ rY3*zV㝬3TQ":b}U)UzS@)c9uhfMĜ鈺H%K3ԕ6Ɯnܖ2:IX8ATwgVC롧yŪ@XU Q>OFnNJlRe\vf};|Bh+Vu`Ud+7KXD~}s5AZV`eUXuQrNV/sYwːüY"z4+;w+OfmўfEVLX .>HgV>}ʚ?Y6@hW1:|cLc/Vd1gcVa>;Yy1D=7y[% xbª&ȫzѦʷź7{BlXޓ#*{c:݈O &'Oa/Y1fUAcdheUtcmBR5)J:sf++G﮲GSVdL`]ɊecY'+jgtCoE +]ộc $z mb *V.N CwY V.CDou#jBk /pl5 5Ju;+g`FnXYho`Vb#|<q}ju;gCzeȃX;UXc* =!w+XUʲJS\NhWSE*_3n׆ 82ȯj Gsj*`<&LV~ɬzrF=o3hhJ䆆G*+gB,~bcd'ݽowCWUwR{2Qb߷tчƪȡ IýS%\jȇC;k7#0҈5_YbE*jք:j!^!^F&5vum3lb#Un)Ys^6c鮬OWc6PC^lec383a1䑢|d| 3eA=zO_SYkkϳb[Gb+v7ek]zv&b)+ <㖊{ßbOVTVz6d/P=W+FxU`{V\Ȋo<5;Ȋel{lp+Mi(=Eٔۛ ^XY + "Y7q/JcF01搰 VeE+MrZbPVBovWCrV$B+8Ѩc O}r$Vlެ;- KÎ"9\0Ol9&r?/n}Я(RGmi%}s,>[Ԭ"UysQ>Ş2SlGOsKobs+fM*~v FAC166gEzqϳYk/^c89cF1^P;-o.*x;+ǎa{bWjr 3`;)[ݙiu+[^V߰XF}!Ɨ(W +\>qVƊ2 kwHs" P' M*usY=axmD:b=Eb'Qk9\7çJ)z!K/O{k~FSsrgF?,žSXڊ#,k pWKRcc>t=؜l} Q0l _/c19d+0>Vჽ#C43/_gE/ 7$48t!G8| #1P s Ξt;1PͿYQͅ[q8 ?1W6YQ[ia=}ِX1 [q䎈Q1.z$9.VDv$1%cca- ug:4GWb4#y)|vO:߿8McUl!Ovet{FW|:Fy/1;bܰw3<1r1~VӐ[;̓]7>/)>3ju=ӌZ+e4+[65rbbTZf[}gN/mT_b试ߺk7|2> @'TpW%%oj8Աp97`ՋoZG6Ne#\z }}͙QN9wPuhoLypDLH[ɚ)+6; 1&FX25K܅s;Ī}y j=qw%%è5^^$) 9;ݑ63ӿzC{l}!慳?9EE1mq_ٸyx?R-3bPFj\;{Aibt@q8]e ƠNJzl i%ۀ{ [f=X1xGF߫26 聜ט{_A65Л}w`Q| }ԆAeUb+=Qe\3;S}q(lPu:.5p{c_cyO@|ef@bb϶uք?ܕ5$9',kgNW##Ϭ|ޯkNg3LWޯ;],L~-faK_g?=ourCXK{wIiVF[h"BLox[ow-Ljf/ޯjC|{a61N>4%x}bgd YPLm k=:mc5չ{0PP{jó#% 5yQÑP'QqPM0GjZ`԰ Q -|G4Џ9>{ -vKY70$r/:ycuGz< [Gc|S,a @>쯿Ox~5ڍ'nC3t ֨}VUkf? Ӏ`&r+66n #373G<ހK俧8{8BNz&կ!仧9n+q95s3ҝJc zX#fA 88<%Xz<ߨC3E%Wz촨 Wq!zڏ>{Q/ 0\a7Gȇq 6Fuy Qa7?:SFAlNۑ m#솽*w> rMb̗Ž2o9sP3aEɁ]aBB|Ȗl÷A_-b:A6rVQ]䡦7{> a,vG)žƹL4L"u,M2l"`ܓ}bK4Z$GCا#`(<2ĂVbƳ?vCG}ޱzZc8(2~~h!؈1g l =@ u1"aH(W@4"˟RȻZNG~φ =X)83 ΂ gOwd ow`11g:{:=c~dȸgdD?E }_2H_3x{cHN1 ?E.853w&:!;Aΐ#d{[³5oOm`oOnЩ dy@6̀&sSfLsm S=nzgBz Go|m {]-kZk!%jc ,qxuڠm~ cMЭ) >]2I"$>$>0c0~R/%>U8SUoC1p+|*$>z}}Cz5u>=EY|0(}ÇfW ku 0-mvkl_'sЩX#6ꀆ9pV{j&gz8Si,5Z`k -`o~l _{W3wog6\3i fk.k93| 5>5.A'GfqD~yKĤ0j Yjc5f:`jk昫s5A- {b| >?03I>o sJUbCs /9.ޔl.4Fx/8n۱gx>;yp~/{wYG:}7 w20t2XMXau`8z! xyѨ{934ԈWQo@|\ _ zߡWߡWMA _o!+{gB}'Μƾˠ}4N@Ӡ}o Eyb~X;pf#Yqt+0_َ@ÈS{Nb"?I _ͻ} oes@x9*|w t/n7_>>A*t :ױ.t}m2^u 膞 67}gρvҀq{svs{rysqh렣z @[Ƶس7}o;@=n^[ 3vn;=ߍ y 2}=: w;g!f@en|{ipA6Ǟ~Fl5|p1aA;B}2'ÑF;O`q='Ì; >' >!n037hΧ>q>=ڧ(d9 c{ρ)wr\SgynF.>noXCBmf1xAスQ޳]0gCw N5%w#6o1Ƽ@ 9w5_{_nݺF"_Ş^?{![+t+ԧE PV`n<ņ9Š=*ԴŨKLFs3Asj(WAQ1uQzz=DOuG=ٺ7uC]b24F\s#o,ЍE ę/np2]~Z};cOԷJu/@0&㎇iuZ$r;>]#p߼=)pl({*0p,w$}5εN=w#.b$y{~3ۘ4 wjw[|w` y@q.z q[nvD~*S 9{I]KIt_}$>9oŨ'y!G&wÙ.{; x{χ]co r#T"o7k[@?{s8rsmoXm[{—01 yn0> -Ifat1fa{=(؁Bv{tNH1k0.ޭ>ݱ3;09f`3 lMso$rך16uI&B|;zzy1@"S"oa{ ؽR&7Vf xC;p;-{#M1q6.8z6_8n \ di |>v=Wď/p*,n+ԂXW-a37 ~hyZ@f|.pDk-twA,5'ͥ፹n;#6Al"b:NOy197'NcEb޺#g5['eQjfȝmK dQ ` B1G2CNs눧WZu)S~ĽZnlDΪy$.eG54zU.VcGu?J|H|q_=zy 5Tv %'P+q={$J[~w?Powm No~6:d؆ڻm*֫0jK|CϰwG}oo)B.,I|@# S?У$nݖܕjЃϘi =/Hѷtų a߶Q-zb_CNz ޢ>tЇԀ~{jn :6;dC񭇾?Bufܰj{uw w[gGjzM0B7W;ygZX34S;гŚct}Чn}e0݅=f!RG Bї-w z|crq.t֊qf=z-xnEs[/{w?z}zc~"ؓ6 =X }6d<.3ޕ :۠{>o k!wsI6܉}M`5Z Kr.+-aw{6~oذ.c l15Qt u̍WXBm3~oK Ŝ l7{Q9Ygǻ-dp¹BOXjͦv3nYCOaG :8|{/R*ް W!{aa??B>8^G2F>C?<`!9CJ|Fr\Col>ޣ6 cOhb~l S` { 2/!?zLN }S@g2x|7;L'A=@ɐs"Oi ߅&S r@elbN?'D`g |2q; S17zNlS@kTliQ)87}SᏉb <S1g&@ `-&S@8`>Mv&n D`'x dj2yl29aQFoBq169 r(ja.;C@Ipi ~g As'~L} 4 x݂ɸ66=GNFQa0<rc C]#F5b΀(z-~ c=r{b26 7of}d` 3}|' ݎh0l8lt $М8!cΎ~O5 ]x|<0lWPQ`$ sbO5 yg">Aul;$Cl wcM1Ά,37$PݦH|g L2gt2™8? 6 ΅=faEˢ} k>|46_̀sg&l3_ς s]G٠t;r@;14L$`z l41 vsSVs$|z߬f{1bw4П }g3 3 6 9{A= l22 RfI|B;c.X Kr@Z \¦@{1Z Zaeط6^:Z+o6[\-9lg|vYKo6se1 >`yi>\ 5e_=+ZY9jaYJd%uX_}lzHȕ=7~JjlȘ| .g2PYaC1藣?-G:8aWհ߱ C8q>(z192 x<*~4掣?B{<΂Y)sp [&__";l%a|/{qV Vcn+d+]q0tuq>  o^7> gfA;yz/DLֆLY{k5X{|kcqƣq-gM挪0k%9Cs3M8cTmZw1^F\p8Fܓf1gk9x6]̙8 gYsΑJɋz9׊9_ǹԜ֜sOί[V|Iٶ_9{v% 8g'Ds|܊Zl,hڎs+oކ; ksy\^z3[qYU8κʥM9J?#EJ\⪆\vKL>pA\:b;Vqɕs\rq-j"\2 V%s%cqVR~K6pI}]U\< Nr\p-CH%\E1h,‚\jƯ,|\l P.8_y[w?c'9Dž>pv.vZq r~x?Ջ n!\8LE] \.]-8i؛SLqt,'__i#p0N[)*9EXӂ96z' zqf*x鏣9f+')OrtQ)8ֳGq6p|37iͩx+y]sK5z[s0N1QjNs:估i"S 59#쾝&OL8GΕ]t3:0s˪8A&gOi{s#pRϩK8&yrBNIaxrG_^}V+v9v\1'G 8Rsڒ2Ό591.'&rhN 8 RNIA,mI?rRNߋd2N)8)8MN[ZӜpߜ[NiNO>c#Nv)W8NPSms 攬&;OlNNl/2'F?D|rB`=sB=Gw#9H͢OcVpl|;f/E}T8o&Gʱ88JNg9cX_p-3li9l3g8kLt~҈hc刏X0b*zՖi>TroWYqԖ9%GwK۵'ˉ}9vǞq('d |>ݍ~#t)9&Ni8mMαS9qߥkĉk6q?G=0#(&' Qs’bns 9K'L?p0UЩ'lu9Nj'Y_vNiivo 8y'NިFfsƊq͚9.''/֩8%8V8N=3r8muD|tu֞*85gr ppjj|ӍSֱ/kzqy0i;zyp3qsFr:wŜn3ko>d#g-bLhl8#93pj џ^E8M,XnT;p9]#}s.:+8wC+<rw}vm?8'z7眼y8wg؆܂a>sgqαp:SڒsLywsgwsn?^>3Ϝ½4v;dulg/8Iqg#֫npn@_yAݒi9Ͷ3-nQ{Xk͹ ɜ^w ;sa:NqyEσ|*ͅ}J[.(5rl. _7e[";h.k^kMķtg:4!2%ۗ8 ӛ;7Pr^4[ƅ%TtH{ BKa־ %g?V o/" >q#Sc0qo",(9Zm}][qX]:Y@u+s]?pPWg.!Z0j}IP 3 rBe?!L;WhYwi f Cw}"D ,6#|~Mғhɷe0/-lMsmh~}Zڤ|?u9Қ}нshѼ74w*BǽOy 4oeo-4~iFS40SpHc\c%)WM)[ Y\BS ;(hע9>Ф4щTͧ񺖰+@ERpl 8FfN4UԞ&Vs?Ҥhr14+aJNҺ4ox.nL矣uhMM??mGmFҊi 5 6>[7Mi;)K+\->T:[R-Gw(;Rj@ܢ]H1b F!ղJҤ'_=Qtbi)JIPDt"Ճ(b'(Fb[䑽(~;J(5ԅu)m1J˞InhFYǾQvGv=KُS֒M9e2'4'ٔ wsJGY(o);"c찤\cG֦X)EG u)^яRꓩߒR()52죜W([>eXFWPf۔90l,OND&Tdr p]D0 QޒGpVܥN3y3)ϫ=Se֥l>gwwSN)1y,eDiw?:r¶R1?r'Ɣ{rⷔ5،r<) D|@PV ^%' e'z8!KPQY(iʾ2amU&1`'rͣ\[kn|DR۔;qmW(砻hiDjfSkʍG/^A 垱)U?;LRM'3uμ # )A.Hstn鼄oQfE9-@J}/RV}(}ys3I2s)}>ɤNS(K2ڮ SK Mڐ'J}UE[iVLH+. [n"e~ CEi(#)K1ǧ+eJ8JgQKF%rGws zl9% rbK);{r'S0 }Sq*ʒUs4evx*ՌަT|[KMwyl`ﰇA쫏ӑ2}G<IRT(=?%_>IiҶ^޿HĨ x[BY=;Q-ޖr?(^NmA)WWN psPZ^yoM:ѕRJ{PXEeUQkJ^H|Ou7OȖڨ5y!Ν֦g9ŌR̾Ņ"}(,QteN3P5!Hǒ"ePz um@z^b\!Vz7eR% UI4! :َlI-s!->Qhuhͽ&k$3#N+ڢbZ{s-Hkm+ "uvZU¸7HN ϒb?kWֶAag_`GiIʿ7¶Ŵ JLcia ׶fb%֕֍RX4ZlݹLޕr5A/lZV6A+<.u»AhOڤV +#aȻd wO'^}Ui]aF2nHKc_--K 'JnP^M{}쑮4! '\ٌBuS(Xs}{E5KicK }YNmVhQ/S9>}_%z4%:Ԗn_^q 7i23MIoS)wiHͅ4~@gӐcv#gBڇw=Au&èߐ4/ TlAmW :oE,ɿwР4I ~o-#WO44j A: 4=s@6;Gm\7XM;j#ORIQvHuz$mPI]J}!l9lF>-SԯOS"iwI ZEMߐo=~D}?$HMߑwxJ 9F}-K6($g%3NA=SWkW>"fKjiZ^K֮˩}|ycPծ乸9tC*6R;<:HlHcQkw 5<N#/B_KPQߨsa87Qn?A-$]C*vu ^+vDq۩{cڇP6ԫ[! ·`m>ꚿmmȫ^c uM\שg~uWr3HR$~sߨSԱ_(עvDrVQ;L3;V`C-'{zA#]D]vYCr?Fn}nj%E-\AoQ Z&x"0HPju>y?y}pZ5q"zH% jUqm92<ע66k j(NAVifLE1jnASmX}8PQ8Z۟g]suËpNS[zGS-p8?9.hAC.SSWnTp4%G3z:G jo.9/}Mo[MHJ-zZ9)ϓEd{̊lFZ6dsեr+="Y}jA}dgֈjH4jNpnZ7ZԊ &Dr o~C5iKNz+~)o_ udգЃk}u%bZՅ]QQzs㧅d/YBd68̔ɢX70qC5ӽ1r?r؄ԨyrM8Cqcz&9I֓4 9yS͹۩7ce?}Zl2[##.P-M*w!7Ȫk2{l[,!CȦ'1yNV5|Rf%w9O˛RYd%KoQzT֓MdUM 96c;Y=*v&iہj[F{,'d{`;q#M ba\ r hw9:cIH`CF FIn9 $ڲ\ pwKɩAj2\*ȽV 5<xLnSjx5ExseW+vO{%YbusBrYWr]H-OQgéh/EޘDuJevDڏv˩bWK!zJ̮Ѱڋ5Zě@I!il7MpCd,?>ݢEws,Z-Cw<hlMI:[EFB#FqHye'i?Ee]vs"ľQ3fmM?)*B{x^Zk=Y/<49Mָg|Oj%Z}-؞Ѣ~gY.4cMD+\ZES~d4?سh¨~4uM U4.?uB6R9o MXi[ئ4NSMC,MiDSj9KB]PO*,7fWeU{˾nE~<;c]^òv24SI}H.~ m:"+f6* }A!Y2V[*+So;Y|LO2ح6U5ekBeeS,z -[e̻^鷕eFX,[6࿿yzLKu~Z!^(-ZEj'}t~Ri]~H3,Kv͔K7PHMhޫ]wc__TTZ]{CAiGfдҶ@T }&=e.iz_;4hL9vhgGTRvs2y|hӫޙ.ݤyUsAEMSf1K: V9K{x{Bzf]iq.KR{?RĦҴϤ7?.]]8D/j49&StҰf`'s齥iu }tT+w>oJ-LZI;H7nt,m xIhtKA{id=R҇RᠭtYo֮cϒ*s+@_iKcRYՐ]r{RCGJM^KY,{ɤ-NrwӐ7ٻd7Kr>x1H;>W~%Ay7I|٢"ˊaӯzЙL{Ӱ^jOmP??vŶGt]%-ݩ7Ρ'9>]n!7:8x]n ]\3A,EuwZ~j50jۚ}CHaPt 37 9e2U%DŽu]|g!@!2!_S!5J&hr#Z A 3ao084Rv.Z^*,.,,D߮a)D#](3N+,(%Ns^XeO $FvBŒu^ J9!.,̪$;( ? X; =gL #8 a%jBY= {6 I o[ ?; ][z_S R"HNz(#^#kG7G ճ6 /Л=79(L'D_Zyju;^r}Q5tA[{Q [.;ʚqNK?,'sH.⸰z b^\\w!B rE3K;qA:.ygws! GlJ8 Sq֝C _B]r)'sp9͚ei\9Zp5wA,Wq~aqr־8TNޚCskj3^~.-np“_},ʱ9}'Oi9s Kɜ0s•ۡc-*8;@˱g8}N vXgُq~\c+:Nke)sj|N83ᜊSs"6#ªqn1.79&j6v2+ȹ~Svd+'U9qʖ&rz5N)z r='[)#rl,'5I'9%azpVN6:p|Mi)'I^9~Pd䘲N>Nj6ccMZȪ8{ъ#`UFp,dŻ*VxƑugr%[kो$w:bR85'Dq'9/R.rt璆y3/i˜j'ǝᨯ928jvu7k9Mंې5NXќ=XUۉ5pm Ή'80Nsff́HfӬ#}.^6WkG>pDQ^cpQ'/ȕ궙񉕎8_+ vx]|VeukQu9|V]ƚ{C9CCŭ^YUU~֕#[UpK.: 2֜gx<~=h&G1s65';84N07oYxr-wŶl?5$g1r`')q^6֖rߜاg&pS! 'ɩ89ANla|ͭ^95'>©sŜbNyiәӖ-w ]NJK_qz>ɣWqT{NyS9}8 NprUsR~oNۀS 9'r'qVsj/'{qݗ:G|l#O(*qُnL4E%k{^ROxʹ555g*5-d?j }1Sp\Q{GɀXeGpD1nQS9ksLxߞ۞Xkn1g8~Oˏ36/XY>_IOs!`2s$'?q/p|`g1'ZbMK9v![}ʚcsxONypr NIa:smbތwy8FjR}\w$w_N4+2N/D{cĞ%{mEgrї'(2/9nf&IOvs9Mk{%ڦx^r]YGX^!3'z;wn[N:6G_]>tV0=iB6[Zeo6=ܿ/Г 'S;bM\=.L/"sJ1}CYgQ9TifBGѥ>t0<88IMӸ1$<^S 2K]ѽх6aHﭼ,5ܮ_3n)n d9ξ'VQocY&2òJeo[ Ӯd/__(y{g1#.ˎ6AvQv^KMsdI8>աjdZ>/f1dD:jy{pEuqj@>惨U΋-y7Sw16̗G'Q1e]9֗:nLǑ8zS[ג7g/{MCϫ-4p lcIcvh$4Fm@_S I|LAp Y/4W)E0GMC㏶;i|/@WФirU0M9ьin4+.ʹ̠f/hCp>?syd,ͶB÷w 6$ti siꋭ4uMJKi⹆&xn'*(bRPq(c:1D-֑')p7Qq Jh95Ѓи(`? YQ'Fh䌽4C3ݮ!B#7=94ogd'D|qWӨ^46?MIhr\Zl=9XBs7EL;5ɓ(f.yRiNh~"kr:LVuh~5NŴX{4EZd7-]Z&WRؒVusiXZy.!e^MFktH6EϜFQ)H=t/inx.Rz/& {|JuGQcORԗDKr]Ay| %FiQQ6el)(cL@Q8v?qz(cJYӌR.+)"JNPfKJ9kF) Ϥ;)E%$fSpz9kQŔމwRBS ߭6Gܫ;z7L?R_9?O}NAq(ډw)&JoږR!͟)ehKE\h觛uLi)z9YS'=DY2%y7t?qMk&jJ^G[~J5E7cQ?[7LȻZJ7(5 yGo,fUT3ec28PJ;B)")nOɚUzx^R?e{UU?f Ż%g}3=v1om9@q#Rb?bvKI-QpKHgE3)oII9i*l 5AS(\vui] .MLaG:Dk7Z]ULk>ٗhQKZGb Z-hM¿MiqZܠLh3-|n%-9FOn_E]"ӂ,ZhlJkB ib4-7_xJ Υ/]o9i޻߲ [L7quSIz(S{qoh=B>4d&nSKkh5xD c#b]C6kپz-D%YyFHl"IѻE="nS}5!@ZSxCQxYe =k?;ԽzK^Nu=t+nuQw6ԥmRMG@߄9^w ^2A=F˺P+-+~H]PǞ&g}3D%MC^8u SAg$S%cuط:D:=aOgRz&@TRgѸE:,vN'Sk ĞK<ú~[<: 'wSj^q!65EsX9ЋwǪKKN1qD9`2"y{R԰Wjx5v->.F۩Q|jr]FN5c0TQp S*CMr4ZU&{䶿9\f >q ׌[ e2/oJ-ԣAwyCXD#RĎ׈INͲtt)ơ=IԨfj)5E TOyύau%(99B".TwltumRSg9,mnCvQr_G􁁆_"ўME, 3-9g00#9?&>l7[I֏Q{&ad7l\ߒʫd׈l!V>M;-Qb3Is&reSuv!Rٿ3M-Zͺyds% ɞT-c՘7,kyTn)URok3@6[2 :L&sv>>(^d7xוsdU?>ʾze;~o#o26`֢MUzE^wT3ϓZda+ռRvƇd'kɞEݣZkmu2Mچ-$e̬%m:K Sn2݇Lmuʖ0͒}a."{gj.{w*U&*OqQ2jH&bdv/dU_lM5:Rd L76a-𶼯Vٽa5e׻=+{{{e^=~Ke&t,ٲ~&5F~Y|~\mm}N'ͩG >ceo;߆}?dV@h4t#I6$v'۫db;D|&I X$6g kT-:ZQ_D 5?!éd2,!3TcHURo<2]Co!]Tktsσj4R3vhhsu!CEy,DljEۓՌ5dz &VͿNݗc dgg`5ky1 d/Mc0oo0FHnG} kw_D SזbS'ʕ|~:'?Mcꝥ)ȡ7R4&:1h%ZfDhGػrV~)JonZ}bz˴W8֜EkЪWhGZV_7~W4aizZ7v%֕Ӻ~v5ݡКQa5VOU}[lӗT4;񷛀ԏ4Bh5#F8&4: B!gW@C[zCic4p> hFk!q+ OÀaWhX߳4$#Fo[}"@j۽<4SO԰_x;zGQQ,dcjSVC@|Ȏ}#;< A&jse7mM K)+[vQj $O#Y̊w6էZ.,DYԝŲGnk_uǤGW6v2dd|beͶu+bb2;e.H9#k q[-a EJ~1ѣPcpiroe[z1h=laozHE֫W/&ֹ\s޳۽^W%Uo:OR#VڊCu6V3.NT-+{[8Lm﷯StȿXTmŧC+Xs.:#ttܛEex =tnOz X밵aVJ];] i*;(cNtIgM׭=U=x.zT ?[Sts$W=^'t>Yqռo:ic..YNutsZ(6a:+ǺU\_1ܮ5ޯW^wt&^ u!+߅\ktcO}-$ѥuQvխEC]}QeVt.֯J>S4{KM8VSO|zAu] ޺Žv&Mx[4HoʥN]rl{uHt$O  M̅*5zB;& .ʅ>Bc[¸[knB-k 6ϭ^"a]kfKi:G]QwJpV /^h#Wubp^hX!} )Vڳ4j`Y[Ec[K4\0K< T-׽0Tw``#Whe`q.Ls9ۄ0ݾ7fTY?Bwl1ukVW'P@$Z=v;"Ս|z S]  z%u/J%NXv0K;JZ,Lj'(&{-  4 +1Ko c҅1]B*!\Wa:/q즰zH!rB[!2UP5R\ + ѝ6oB[ wNvzIB4}Ga}\X+Pi)u1qk  ݻBqBVBƔBaBN BJ!gi6xRzeHՄ 歅ٓkݑBBDL!fX(O/h%7==O<8+5?*$BԚwTc![AP+,pRJAK5eF꫐rPn]dP|,]|U]Mx}pxDxWk\T>#|Gob婯|po}zo MWTKoqxj魜tjKyk̪<xMz7W*="^% >~QjAݍN+vAΣmg={AA9ZΫJ߹F}[6[U$=+6{o;Uw<:e~@'^⟞knKN{Mo;]誷U݅k#{[ V)´{&;(+o',N֮<$(ڽV~* ҕ*myK/kB"˾pGi :Sϵ=+yH6Rެt."{W *uvwccgUux_Œؼne'n fKGnݍϝVٵ7nZ ܆sm2nHs{هq2WǞǴACqvf{Iܮ&}nAvLY5=_~ya ss[yiY sA >7A8l_PW^.8et!8x밨n.bmwwww =3(]*-`!5Aws{X۫k:ói'xdwkVyިZʧPY-P5yVGq?T>FU-T>DՋdT7yP=WAAT_yj㨮Bըiu5RP35fkԜCYԸZD}AM4 @MI(j4y5{PS}5%)c^WP=Vf[|Q]/O>T:};:< Bc]Q}2/;z˶=P= /@uo=T{FYMPUUޡT*:B'UZ^UPu Uۿjfnjn[T5a|Ef+*\Ge*^ҹPyTT[%Fҕr2 ϡ|T&y Pb*{PQ4yCQ{Pt>WPQaz gv@ *6ME@TMQ1e *FGE2T[ƃ7VT4EE< MAChr ~ ypsGhlˠ)I̒!Er wPHl>Cv1cqo}OWҙvFu ;h ygx4h>9 |o*DE ST=P>*@ŠPT ߉1Q1QS[B#*tPkTffbc8 }mTuӞb2{f_*@ET v+0߳& x*h.As4:B< ө Mw/hZ._;@]DS uP}:Av[)7cP4Cxcxxܡhus [K?n  'ϼv@}W{C}i>ԧ7B}L C*v/gz{9-9Pom 7z˟B=??QP[9gA, ?s_w!@s8Tߝ|gA u=bsiuPd,z=xC G*>eցUE|a=ut8dY^J~:,Jh/6n Mg 4dF_~wٮ։Aϼz˯7!!P}΅JyBVO\Cu;TAPn TJZVռPLJ;鬟I|gTP ՠPUOS:Tmx)(f@EP!PVR 4(Kd(h|Xe(ze (SWCTe (cw@v }(oIT\s .ctpҞi:1Ot(JPzC)PF@ 4m(s2/"o(^B lzlvK\QP QFPi u8-:?9KYP]eY|fT62.@*IQ@e>*lXBuЙ֏q]ֱ W@T@7 3 V:2P5zP~g~`6 e 붊hvc{_UdP(Arm8l##P(7A[o}(9AM;3`Xxk{uD= f}C62!%}L:u.W_W3K$saPa n (dķdq/CXi/ҩ}{;y)gMyx\g,eYoSs9`4sB{YMGsbhvOf4_As4'iod_#_-3rOے{B33ͩP ͈ǿ'+!KC]pP{l/+Op>vmz8uP/2mIV#|/U*c1sD?ZUy ^+ص*BSyc ToC/|E]p3O:LPNsPsUȵ9&L|bЅr>Pն 'ԍP CՕej^z٩}8/~<)\'q}׳\ +p :ys׭\S\zܣ5O#Q^(_(r(7(_}=P?MJQV{ e91( 2Fq(q@ـ(ka(}{Q*R(=U-3P:Gq v6Aɏ(Ѹ$!JFĿJޠj J.lmePb%?d}t(FIk(~%+Pb(6](^`Q(2~fYG눇# <0[nF ĠPWNPP; q-Q`;{` A~U8㬐g CKG Oă[^xp=o<:}%xиj{!/wBȳ;ӏ#{0r#I䆼FAވ\=9\srrF!Ga7rF!A)E6B4dY!zY+u]EYq9BaȜ? }! >p;cG1k#2z:!xB+5D4@ڇ2e6CJjy/w#R?"5s R m -)#%Rn"eS&Rz"C퐬SGTIVH2&$-ou>"AeHꌄ=p 7 aƻ 3?xZ_e?|2A%qш[ q#WbGlPjbGGly)kۈiL%W}&'ֽp 3ǽY(~݇\wo縻wǤn;Bǣ.عw@]DEψrDwAt=zQg1Q%7EoDFNQ>#JFETjϯYq 2v"i'CU< k 9k "Eds%">5DCDXFE D_5m1 "#g@vUpBE*Af_s |jzNzo#aR",\0~o0;{a*C>V>-ДP?uxk=s{!tm+NDO6 ] <|#-BFHBAF]2Bbz! t+W'B"d}z52Bh;#d:ځe*BZEP Fp>@pXG?Av^` ;A^wsb< Np>4G"#( B% 4Cti"CоھA>VZ h-KCЪѼgs9V h1v{!hL~늠:耠:*Gб0Bm:s Ag"7.t` B;k*? ~<j$UG-Lg˰Ak혧E"_uu{omNBж5Acq#Y3 APP^7-G!Ggsƺs}k0O `wN.`UkY:i[2`BF.GCJ`#!!d~uaS+اf"<!77"6!Nʾ&Io)܀fk>"}Ovv`О}3p| Z!*PUc F"TFq]{˼qucli("[,g1#%O ?B>EHB x낐[M9V."dG4cSo_3N_ɶ@ucg&w`KntW![S~Ӿ""Pp@`7)ԎƝ3qǒpgc=;q4nWpܞ%#BBe6A8pUم[g/V ;wp';w ? ? .}{w cMb|'! >s-|VDgl|Z{xl 7{wP|va[(B져fPoŰ5P4 {{RA YD@62#m AdC k^/+W c,^${-f9Bv>`_\ `n[8 >pX]p67/ 8P±68Z Gp\$x+K8: G8mNtk8 pR¹qg8:h+O̅.\.2}\Ŭ.!oR :n\+HѷZunmfC/ý;'}potg ౡ# 56 6j |9^mrO:U /s ^%+kPd!3SYAy#MCnp-!7c'B;fBj~@9JCV5( P:&>&>+u0|*:|qok m{&|7r:|gu~)[ soƽ^9|ߺ)':;?[3n[q[pTG`y!wn5^}-#v鐇;zgp:q;q$NB4ejCԝ[NAQ:@wG wŌ+ݝP&rv$a5pikk~!sZ"aD^Q1w"vFNDx@}mD܉ cK5,QZeZ< Q"=D]{( DLBT{@t3=>Ǯ |>=#: ]3n;wo]:k.q7Rw nO5 =4ĽpcsHĽ@+ǽn5lh1v#fibG̍ pELF b"yNDJĮކSgk oz dčY^$5qwKTq!-OF B~;/йƏB-$K 4$Ć!U6 !CH/81V#qN#qQ$? I% SHl; ?"H0\!1 ]"7\5ćZ#eM *įzx=9]!&ĽxvG\nW"έ7nA-ĝ@*m9D׈q!n uyqkqM b|Dو ](b_@lZ7WmTǼYzMˈNBl3#Vqn+k?7;#=hb^B챡 ہ w9әϸ >#Vkb'B숗ttb۰4Glq1O"lNB¯Hl"G@tw$Ύ]H<]Ds$lBbPS9u~:MFR;$Xt' ɯ R>"Iב.~$) q%H/r)GmW#uBRW"dR"5R C'.F/@ڼsHiviʑ$z!}ωAH7@LGz.ҕHfc2FFnd,EƦ8 nȸI,GFbd@j:2GƯQl͑7# s2>!s #sPdS54~{t dT 3/292n#Y !Ddރ 5k(Yk"kg32LGUMȲ, d9D'dV"w=#+8: ++ YO"=~Gϵng 1dD@gdeXBP}@?"{Hi ¨ d: {"M#{k/G6"7l@^7 Ǜ!"7lLGvyݐb:!$tș69 #gksېw9I]S9"I W?|{3rܸr>=kcᯐ7y{g> y!/9޶nx0el`x<OG)x"}'yxf.ꇧ74E-~hۣ(PgKzE<7«x~F(>ֳBqM JLlYP!JN2%(z#, %go[q(U(՛(]5 [t gPjlR!(D Jv{'JCJP'(=Pb,ʺ@Y?5ʆF-MA٤ZM9@ lz>e$&9gsĻ ((4ogDq`[(N/$8q(ڈ󺽌"֧. P\*WUsFI#v+QG^(%`X%kv BQ#+A<%3Q5%Y(yを? QrJBi]aP: Y9.b.B隅(mQ Ts^G(R NsP*QV(}ƸDX߈լC(U=GP'vDIE y,lʒߣIjfm7vQ޳d|BB-O+F(_y(7rf(o({nj(Ǐr(7hAy7@i (AʘP&}2+P>}e(PVvj |n勻XWs^uoC9 j;k*}PA Uuԍ\5Aԗ@OA꿙tm ͘9,fzhRhnxBנr&44+yl : 79-Pѽ*b*}Gۻ4T\(FPT8Z*\PwQQkir*\5Pm7*wB9<ʣPyu\@b+TkrVTXߧQQ;Pa ^bb(*nt4a֩8Mߎ:(ԲP]zRuC-AT@*PI 2n5TEl.0Ae*[P@rT6KP P/` GP̈́z'6BQ U>:^ P\&@VP'BݼF>ۥCyx^n} _9"u>u;9\ HN~߽dz8Ar*.PEv*T DxrBw**e\+['Qut͖P(O\6@:J>?Mku9M]!Ob~ޟ}bT@_[O C#uT+Qzp *r>ysG'Hzimڄcp C]si f iIsiz# 9GC]j%H.SA;*1+2} bzbꭆzl<PwYuuPןw+ޅZE񺷟(T?| zcnh,&r?uKԙNc1,zDgu9p-ԧ6 P[B-\: j{QP̀: 'rtiQ MWZ0LP {Bn;4N,BEUĺUWOBg@s`x>XӾq pIu|}w3Wn`C=}Xί:uqecλ5b .`+v{V+TMیJ1gxx?Bj1[g3Q7u2[?&)4?:T  8oX4w0TP!,GlB~^ffY8?Aڭbqcx*zbA'FQ1<*Fg x6iwQT$6E^(ZTEX<}1O }<]S/)?y')G) O x#XqƃVy+@e]1ȫ]k_"wlr|FN)>g9|9Ґ[ߐv<eK4ٷ6 [l>V[H3#{ dwbd՞CV.d CuE72<F!_<2ޏBFUdCƦ<H_}C: xE-$C걝HվVt6RH9):ˑҪ+WS<ɝ!$$ 6A}HĂHU"D g#P$T~@B$CnH蟎x戟=$ q^ڈ۵qcsb#ֲ bW!vbuCL 1YInOw+?ٔqm =Ewv%7½>7]g9]=":v3"DBTXD9#T4{#j!iDGy1"W!rcDC犈t{DxDD?c#Ÿ" UUNGX/DX4yBaZ!)DaBaK#lcͶ@>>a lta=# aM~#^KChx!OFhBo}Fd<)=g"tU@(uC= -7i!ՋR!!#!bSwb9{!!dBBY_.AA7!#SAqk#Xs ":3{"8w]`w ؊צ>oG y'L< DwIBpn M{uj2۟Gp|Ag~DP=ه4G 3#TX4_AS!75@d*}=hgo"p_7k!pE8FjDLD<6&-h_>NB`I>!x_" 1O= h M \-iCMDAХJrkG:m{tt<{ķlYmA B-$FP]e#4A6;A>8[mNJEp4z^!drBA!$~"B#i{Z]Sz$j9/pEhƷFhvLa!Ka#v "8Ao9dRyF 4a\2RB2{v*ւWWxJx-!`<[F!<l͗y6 }a6e_ i`37lFaWLvfU,#6M\Im ظ́l3Ey+E^~͏m >a; lհ]{Ea{`ۧ`Bm!i}ɐ*گΎz.NdA$˛Cn$gAe $@~$+A%$~Lސʄ^a/ڱhhgS6a9O>_d)[ Ey|=HΰܗZ@b1Y6C{7H<C8G@jI\HBtu8Cr$w1 DOH2 !y4A ѐ|/jiɐ-mHtxWHLtjH_T!]9M 15@j~Ri޽ v4/Uv]nY v7}4h9iήŽ e3"m%q;oKэE]cI!x~%v`}s/x?I|v"ە[[cvBgk!-3N.bŊnN{&i H:(>iܺuP0AğSofVAJxktn.&r vonJD]'s|ط`Má8LMZp0 YpȚ ؤ‘.qz8 GpipjNVi3̚5>jy 8o~såeL vptK\^kpgկ\: MI۞psjB7 3p߯wp/{q{Gx܃8 Yյ^u ^_@fٍ|wȷ_5|5qUP{u[6w6ヌ>t3* >KWd5|'|4m1]~gq}[nPj$oy,F8~._5~o+w>Ie_' R3j[Zpk_r[iq`0_ M#inG@tR Px v#=>}'p۪ n=«e6;pgkܱ,-]w!A he:Mg^7xg;'ў0%1 ~&PP+#wDOw#b."A6#19|_(Q f2]%tEY؃2N>QM5+qMyM̾g{Yp~ouG1[{jwۦ$OG p kf1_#{LB|{lcc 1N9t1n#(DBLbg}Cb^F6m7#v5b"vCKYXĺCl#Vun  qW".R׺X nHӐ NeHH}&c~ qnwȐx;H ">lo ^xG,~f w" kV"~Q0#~LďZ-#Q}pD\MJ{".SqaqcsQ#C;.G܅;q'"hG,C^;\>qͪ[Š:q;ğ#1e{!)V'dy}O!bٌk @׾[Y' ު.>+%_t|$e;;f!! EnF $ne_wH7Mn!7Ԏ?g#RAX^؄YӐ=REMfH}Hi-!;Fs~=cfi1wz;H_f~ ?-D892 [!SL4duCrdAV2d A7odwRː'"z-}YdFx4Z}9#)r@qgH]#BN/r!'!r2}G$A!;Uw&? % ޛGo4Nu[߳<>VG! ?\x''S?3}ؿ3 $!ҍ{&f,g?yr Yo2\$EoL&ѝ2m/#svgV#עm]C~k_zD~#W%V~$ߴ);`\_擯YdUL>+g''gP(LmI>#-$c7 !_Mȧe yg$Iq).&ŕ-0+!餸O onRT 'CYJֽ@ߗȻs*)bޒy*!}8y;w@u&-H0wL !#f=yL8oy E4өOIaD*Rbg/Ua8Og$;bOwRj={RX?wW>0I^gl*u"t ĶYN^ IVA^?wdzC _CzN3$k3܎dI6[.O'YXO5C^E%6OeɺY<]:2|'udvsHvu$Fpm!>&YCM- B ~֗e^%ٟW=W/UGHu;Ɏ_!yslALI|dK7,` ɬVuK~f~$$:Ͷa|>̟}o O0Y,}7C&~9XWH)ɪf1$;ւmc_cV岏r̖/e=úo!$5I$oь7'f~ss #$Oレ b_ua]<~r'|.;?p5Euaf$c}[y>`)I{ y=1!Y1n vgA3ؗ$[ξhzMMe쫫YO7IʸonIު4Llt$$8wm,/WtTkʱ9*;yJ'YA-bVLyO{Cﱎ6`%I9mud+8SIƵIvq(If가dGA^=p<ɢo5vyzu|9d78?Ԑ~;u X z#s3[C5{Ŝ's k{!ue2 l${:82H6$p}JgXm>#V웜\IyMŌa/+|Lj:w\ 24g)8G:>d>ͷ/Yf_7܍s{,y6GesI;rB\qN =H0ۍGG=a#i|D= \׎7 ( nŊcY+8Η}#hH>ױ>'3[HkL ɇq C?<\zx_R 6܏s/LORLDsc$Mo5_'yF4 &V}ŝ5$}|+8t%E5%h4I)t*Y2$` expS+^QtX9APKRiqƼ%ot;+'xR5&/^ni[Q1"q=%Dzg{nw'難H΁}r3ܧZ&b~ks'/ z5 63ek.I!4^$|xM/{kK>CƐ7ǖFOǐV?wVwMK0M3wHK7d$9%s qzvk_NAD^u"YϮ'pⶖdrD^8G^d#/׬#kHg@^zBYtq?Q|n6k3ntL7Nit p}G7FFЍtcC^L7:^t]ϱ=Wh]ߕNVdu$wHVɪҒw GV2GA/|K52!fyj:OV3\qYoPW@܋XG Y.yMrG,Z?Htɒ^xcOUd,5' UG(hFVodQܖWbyl@ȢsYSzYGɂt's?d^8̓ړŲndѦ̳&7(&dcS*`?׊/dKs,닉d}d;%EG֫ gNֻ%6 2=}㌯;ۡ  +) σfyj2,j?dށk\H+|t. d~/ۇurMe3n0X!_=>nɌ+=2+t'2O2 LTdp!9!KDfn{d؇$nH$iYb2]Ef]e]{;9̣k5tHfCw5-tmZ1]殠kf;CZUM׆ӵRjcD:kM\Wt5`8]vnMW'Yc!C^d::L ȴ72tL Շȴo72G6idCJ6)2 6įLdڶ>'[ɿ{dRw5dn_A&*-2E&. Ȥ|,|^E&EdH&dz+A&$يL8ߚw$gtm6݆db9L!❢d0&GȤ5m&ĸ/wIg2i{L6%>+[GL{q!̙E& Wx9]H&3gU|_IS?ɧil/fd9@ גjU.dScd H'25`OƋ^{14$Hx22Oƫ>d$_KFRx(2Hƣѫ1d<e=x3}N gxM2CFȈcx2Gzdq 2ݘό }2OƊd OONضd52# [,2~{}'c%~"c/uцڙeMәΤP2nF-\Jf xV+d]tfg=&c-W#2G+3dFƃ:L+2nx>!|^Nd;$DFadDFN1LjџB2bTϒQZ-{HF'#d4=!Sd᳏d;O&]d _&Cdѝ dhZ]K_tɵ BޢKFhJ2:uchOFu\FFgW0Zd]d?٬ hGȈԨe%d󉌞'rdTځuD-_82r]LMd}7 (bwa+\(AFҦ)gK2*iIF#Ȩʝ0߯F)dTx.q=+wDnQH' j욓=8#2:2"zdd:;ϲ/cZ[}XnO2j2;(Qd4VZ6"cX_dT \'!l 2FFJzf6b f;f=HҀ1fng}Kb9MFl3e>P&Y8 1yd-tWO,^%Й ?3' d4 ?OFd 3k֐Q|DAMx9V0u'\$û3p3cG2|bJd GdԂGr2##"[dtfdx('J2 6Mݺ^d" ]}6Ӻʺ]bMoo ]zGN Dv"Wd4.;J>Cph2d1@Ih -d]Ga]~3yiߞ'C oy_nGF=8־a"۠g2'L (x4$Edd7[3d4(}/md1-1&#y_QFD*'+k\۱dB:6̫d,2ds 2ΝF&krM-GdBy ]`9ty,:5t90.yFS{d=]:Z2i.&z $(L#Mĕ׮dk%g2M&y=t|d0}F&LMn)xS;q?)ק+'iW2ZBWVm'GM]9dBW6teyr!]پ|GWԣUGWtubɸOWw-:t:K-o5QtE} 6ětͻYk t- KffY2̮ =2Afm,$yd>ϓ<f)m^ k]}>,u\NGCb/ؑCK\s,^a> }K{~3,+֑dHVsȲlYFVdx8dՁ. du1<MVƭȪĄt}LN(%)vu9^8zNL_&Mkl%m_I9;6{#m&Idk$-dcA3md;W$$jH?o"6 $1Hr$LT2i$c!o"+'.d$dF%+W2_$Myo3Đyd} .@ i?lݘgs}y:lG]c,Rƀ&٬ qy&<|B6yt=fK!6ϝ|'g4}""b"4g7:l>'|ם|y] ۩32=qz@sKƆuca,D 1N*ⶖl-5l# |Ǔ&&Ͼ2l=MώUdS+A}vL!^BId/ZC 9$]7Iqy{$=@Ґ(>Ke< #II_$S$I&< "nT'sJv[k;n#Cd잼$}>^;Mo}D/r%ro:nd_ԔSxޅ&$2rWLV+9,[Ia rDCN7r "F6s%Jn@/C89|ڑCcWN !=GSao9|7jr!džqW90s9YL#rw%Gr1#195WSԻӚQKNI= >du ]5Ƕ$G䌳<ڐ}r>\i:H.q2P Nr$]JHؔd漣7!y$ךD$£ԙ^DR_I3I}O )~ EQ")fOÇwFv&{WL/'+|!_y@>UD1J-:o}'&_ ཇɯoۤ$ȯ ;K~o3K~Z[綘g(=5&+''oKYW{ј{ '_{--%')?~B8?;r)~N&cKoi."7{ &_f '#hk+'?EE~%˹ͯ{o!gnwщߒƞ6[I~G+J#)"?N oO~Q #NWzB/4PhfP3PhXh|'Y Av1g} z?w ;P+!t[%zD30v0la_a„k RaĿ$0F+aJz=D,ar0_WarU0L0uY0E0uf+a´G/ie0}A0-l0OaFVŒ)XAK5Gi[n8PiX*輻*.*OAm3t{t6_޾1fGIق~ޟA`W0!w#o`M@A/RxaH٩g@_=OOГHPg\Ⱦ.h?I=;#Dt :W ړ&Cm}N툧vsA۽mI [К#xk+h&h|flff<!ԾtKtN :A''FtkyIk{uFnuA ZU*%Xt ۂ@^C3O1O#v`T 4 a" J"\)25W|n-c-e~ ,7=g p`_[-ʿ XSN#AggEЛUA{mMʶ{'hmAGY1+dotzc :~K-S=z,t|y=GN`,]--ttOWtRٷ )-N>A믙0m!%L\кsTn,h+3T Z 3396_ 3>f 361-n&h[f aXAgo"WкHо^?UAZYОU1)w®Maz\ azF0C0}0}WaBA0=jNKк9Dm1C%hu_y`֩5y f]">FAAFn_s A\о'~m6ygv.ә'Ŗz=*T@V^ F m('NA׌cA^GЎeI8'tt9rvnۂ0>>ypO α/h[a t@%*sUxX %m@Юa΂n2őZoqQЍtp~eԅu#1ENtc,h=qo.9w.}B1 tϱHt^9k' '0Mf:88[ЙW>SiX>:Zн( eyrZְ :+Y7\j DG,hqlAo6Ab&y-!:6R M3 zw6[s>[5"J0) (k0P/( s4m}@aU݅ # -: z `Ю``0sFAm.,yg-^  !@0q 3Y Boq*ΫMN6Nz@Ч00VЛ%@6_{"8*y,ROW zhܛ?8} fxWj6¬6w`(_.\a.4 auoaV A/˜tAxska A^'<$J+̎ff5x.zof'̪f*~=fofO7Taָa{manZ0g03BMOD=*~sNUM4I`0 ,.e{ BB`-+X|YGml^F''?|, t@Cc~z;aӯ|q&,TEס[) @nn9̵9pGkşƦOwkD[=8v朂Ópk_S2RS,;zy@87ji / E5(cS8WpO7zL[|wʗ1p,kؿIhtnp|NZ?`6gP ʙaG!Va#08Ý)?a;d8,j@ԃl8tW`Sm {|oHw4j9^U*bW&7L]+])gN*??F>םUa "+.:C3-Z[M`G#\ *)P9}}1ɑwp`#W㊡2!;w|Jy D8}# ;kC}X NW(~;PlIv$;_L9ip4'3WÇPFsٔly#TSδN[h8 "?aوGQ{iO)5!Ag>$ByT&ׄWA:_"LU86c]'TJ"lQ;l-[wL;'npv.C;b?p)"Gpv{`M90In_S%Б 9~(& itV4Q n47νM{L˭qO!E;NSНۜI S(W=z[:݄9ɟ|8K:n7Kzӂ}4ߏ/Q_K>j_Ljs~]$]Y88hE1d<Og{^mq~ ln)F %*zG" K|;#;ST:v+LqtTE/Ã=t‰Ip8b ,GG@:; B!}U}?,0Vv.P圀jT3ގ+݅_Iлb=BN|{W`߉bP U TL:@|f[H6Jg$|6`Mx^Pգ#t7(~G dOxLTUNףؒL24vOnT؝ @z7\BoGhEPEv iKqbaO؛?ջCgxáA'7}Y"TY'ɦt`?bC)`P%l}pՁwYZaw0һ|}`7 W>¶r8~zMGG-݃[iۅs`Ζ1`WJgO>+??ma{bAM~{KkFDoc`#0{_gnT5zQ,u6oB 8ٙ|yv]׍oaZ?;oW),ݍ@1,hCQMxF+T.;EpJ8u!/^SAoLOzW&OoClKJ%,2pբ7VB}#zkhzsw#ܒ a+`7 KM~ɛ :W`qo\oeGkW ؍9V`w=.X% \<WM˓p& .FE8a;Ui(ݠ<ג0^uMgD!<8 .þb=,Y`CwT|-\]u_U`{gY`Q&5s\udF߉dw!yv59x0Z?r=ɱ,tv nxߗ`sқ "W; Llv%]Օp3 vmlwχps;7H` G'voov7N|h܇y}>aMp_7'f{^I5Tj_=_nMp1 n9b&4kxW9xJK ތ">ug;<çBxO̅1.5Ȃ_ iFzzNυɁOi~ko_z h _q--H/^ U7`|GIq~5vox^ ?la] g |ovݖ _m ^YD]d[zt uK?>4:G+a=7η $_x)|F:w/q;fg܀ۺ} Hhl5|}xj𽩢6~Ƒ>Dtu;ޥh=!^N' =$[6g\/xlYu^AfH$iJoIz{VW5< l} v/න|w:?µl`j;fզXUkp>ι<NG8'L$pC8=#m4¡z|ܱb|ק~[SEoe oMّ:3J9g%T!p՞OP!ܾ4a88 R WPFf@aBYs{6ZF 8uCoc~8V7#Lu&mh^y$ Z?`G ʓhLX;.NInzOѻ)bmz>ьZ[Մ*v ʷܑt+l!a^a~ EpC>aƔ[ƹJR>a[>` iN.z<4]>n^k;qzl# LmHWλްSsh#A 6Gioa{z:z$mg؝̄m'>Lm5l_WΏ׷{v`߳O|=shl !C6!!=L+W ل^{`58~IES0&.N*Î7#K>ޒ:4wVT =7"4p9d+cƄi8)} L'?iOo+f[57faJ' :/ &^.ɷ m ѶM H>qO+S8ͧM{л3p-ao Nc /^Ez RY#^&v>1~қ;}T3) aZJI癄 ]c tN>(I]Pkg Ӥ-_s8e)քX8W +0ք߮Ԇ` [ ~b̞f`[?`#^kKp|a}kTϸ@9~?x=6xr{p?WWRNO 6{iMζܾ ɲOEx60,Xi`ϹE4w|I7F{؏L\ʇ :K1`sd$>4^sR0joҚj p-M9t¥;WFs ܦsýh@`±pBg;(YO8;\ kp}>n5_p/ikirvb^ Fy" nUgpn۝Aޙpv6НLR6g\p[|Npw[1@-$,&L Gg_&wo_۽! gp/4QvkMx[#dTx/Ǎx^f/x淄 A!?J^ӿ+/^Il /#]Ws6slxև=,'NF֚ O)rƵ^h h<F{x};I4^Aڌx^n~x /Jx5} @x "[xD2N"x N6t:B ]:>9»9G׹F ^J;|t;܁: ?{MZ4X6lOѼL߄o W>7'#>ltj |'>u;§|gI[x_ & Ճw&͵I~WK{I/} >.> itP_]y~TV;}MC~r% v'.OI2kq2X蒴7ѥړ6S/:?@^$sIt:9s<:i]KOaݢ \Oހ\na=* ]= Uư^[k>ݎ^K-gOC،]eC}lۏ=@x?`=J{ vz)]{ =րmӝI4joqw$>۰(hMC~lz&`zDf:G:tݰ~a6Z],KYtDf_ѱK,:VAUbsaU :1x$tªw$3[Ż}ⰜoM;C#,2|sݗ@`h }{XVJ:T_ _`5%|}Xtl_)UX5 /â73g)fl2UAw\bȵh7m+Nڥ٣M[)/z17ua0Z&r6hXEGMV7Gl-A]Ѳ'jMaV0fu`-2a:/Lht4|SHިFm44̦eZ6HA/k*Z>_ڟ`j` ˃iX^<a'z̫+nC/rQUⳌ;l9CK7Ze$LuAL-Ǒ$?L'}cI/ a5ք0߿=;q46F0:F5c݁Qc0P cPk`']h͓0T &]7„;=L:ٶ5 `E8 Ua4qr 3calca ߦpu& @}ױp-tŸx4WQмc 4MNBhڸ3hR>4;C#3ru@Cf{g4 hPnQKuu6ry .LCAU45F* Y-FUPOꮿu3럡{]0uoY-]6!\䕸~kw{/>v]׵Sz^{Z`{5nz1W];xNx$ITٴ%x݀/م;HsTwREw-4G;R""hen1HO^>TK"; ZOYHkL}_!)Kh1_)"e.Rv 1RVAJe=l+FM7\'YίAh_@jD&.EjR">bX;_ ư1P"Ñvm.AzHeHis18d2m#3++"XZFVdmhZnDeÑvr!gr*!:"wES>rz!=rB^wk>{!Ѧyȝ:r*!G"z!'<9ޝӱ1r "ET_Yp٥V!U]2;NBֲ"d-Dָ 聬jGy2ҙW"svd1BflUdƛ"3:ݐ9uYepYIu5&]K(9bȉL)<Ʌș9K6!g͟HsFCN7gY\[9魐W4jGYC7GΞ9 9Ww"Y伳D:-|#7`rr#IsrGoȫ9MyՑEw"yV+ ܻgɶ[3#w$@nٶ 9\#$dﺈ)lԮ>>?ڄ1ȪsyP3'!sKgdA$C2 q2Ry5d `d$G!#Pa1ꋌX3 2!rd.BƟd=9ٲ7y`d!22~q+^AFvdz dm/Qt3񎹉 2#t i)2N#2GK2g#/YAtWg̽$ۼd~Atd[4Dh5E/QA&̆<7ٲ*2^O7#m@ћ9Ә͉rOEkȧg?dfPxHQ$7FkjP郌:ȘMFgY!NHS~ /׌@ tH{i)QL473V7-DZi~͐i.jH4ij -]f?icoH{i 퐖GӘkeHK|>i F!N0NyS&Ny'9iHKiaC ͱjS_H Q%v#-c"HH+ykJ"0ià;i|IH[i#E~-5kbkw]0b'12G[B^;>i"퐾jdHWAz-gEj_NEHCwISd4wEFhDw2UH#{eNTdFj}3둱ωdEfrdz/* "2,g!Hҗ!j@zilqGUΑs S2f =!U9g$C~@:($R0:wvкR/=O&^>H4BzM#>HI{AJZpeHiO3H5Gz?HsA:})ZF3! hnE CzHwǕlcF |Ҷ!ݣނօd*ȇ~gsI)k_@g'䣯#5#:H{@iw_*!=GZ9dFVH#v/=:Mw)CtҾu*}E:Ih@NPt+Lz%&%=L"lb]s;ߒ_|sV nS0~o$GTd<:27QH9od5},kQ5pA'dg%-!Au,!'hr{J1rn# B rnP|v:ӐL!K{0sw$#w%Y6-|Dr W35s9e-/8ܞDD5¢ۏ+X*dm7ߑ}BdOS!{@md#<; Y\ }s?G6+AvtdW M}{M*dML",JYj–.F:AzrYgIWb6GFL!ȾQ do$<3B~OdT%y?CMOhbd#T#oTV2:u r#r#IkrHdQ?t9-MxѐQa9]ܤgۆ "w!d:ao 5Ǒl0VȝOTżqT%ΏBn'&En_©[!Sb/$“3/tdwe)Î#[4EtndMV]y5KN.ڄ6i1p9tgߡr HxI26R.\<-=:Ң36r Kٱ.%0/DjO"H[_$OH|c!y7jBX$/ydHuɦU0M;$7d {\#Uv"nM 9fu0 Br>H\wܶsc70tV MꉡUn~Duw$ۋI&Hj CV=Cc0oÐ8# = =p Ì mmS /Hhpkr?e2+@v8Gܬ$yD!`=Cܽ[x qg )lw"Z&bg]BFmos1x_ 4gcpB[ Ν/`p ~v'cŸ1 b*0(5 S'  0p7k!1C/ +ƀ50`,>01Q/ Uw~CCi_A׳wm/އ%ތA5o!u~e軋H9ljN#GVзy\>B}FOow}ףOۛS.zgU-A;B#лJbn\B툙::991} -bCsf 5@?knCJ6GȏULTA/l@>.#z~]DǭAt'v hhD2Cԧ: Qǀ UxQQ(DٝETǖ2(EˈҺ\ S"r\DFdct='^l> -"Jz!4D7u‹- ڟvk X"lGXU a]P´6!i:B'9#tzN܅иPÇ !g#dfg@HBB׬A(OLEppG@~]썠x ȥF[D s.IE`R5m@ V@f?7gB#ȓP{yBmuÏx=XMev,|o#L!m)_ 1B>Yo74e̓_@1G&uF75|^\x 73>9>ᣟ 5Sxo-Po'n?e^{.k+Mէ+K ^޿j/>Z)[{ESx Kyc9*Zuf٤ uS<<{<Ǿѳ: &<՛<IM y^.9Ux ?Nk;n:d+ Ŷ=K^%UIn«?|90^!E /?ߗBO ^۔3譇Wsk^Fe:d_ZW <ëP|wtҍk|(}vIv GjIgnK}28\y 2$E䇄d3Sruvgsvxz/ȏqY|u2AG"Շ~g-7thte fslx%}9iEo.wgd=*:R⽞t.wHUzaS5K.)?4V¦WɖIt۾!#Ir4麘sA>wƟP| MKୢ<ы]p3b]JcSW{@x<۟|ZOEށO_M7>3b||a#u|6])YenwNϞl۫2ZĒh2og_*TH-=u8Sd'{ |8|K1'1I!GlJrVOpjgOד.{|H^1&~$KAe-ؖ8z+x %n:x Ls]sx7^kj^=lRbC;Zz*M{쁽i[oYkA)>݃f`-vKnf.2'a)wy5`qlͅ]G^ۃa{ ;ba'l0NKa[P 5lJa۷lNvs|a8=+!wSYv/8ͤ3/}"˅IH#z3 ~FAe|Ȟ~Py| TMȟusjAݸTFM8CY\Gbz*Úğ^Ro2*-]t7MK/[iaO}K>Lp6$wף1m}KSl(>^ԅW3{g6ɭIs&'?@ruEzP9kʝg5ޠB47Gu>ɄICm{YD u;Ѿ;(6V٧M_'⎋{#I>1_{(1~"s-Zd~O_Zt1IM>A9q.E'-TVPSLu!L`^>?xFwTq7IiG%RCd^H6-u:Et$:PA$æP$^[@'9oLSu/*ׂDTgCuT:Lgܪ?P 6OX'= K׉=mo/W~MiuAug%ghi:UW)>"ZOd)cgrn!Q݁GW+Bqx8wAm ܦpۉ.RnrM8=۲qN*KCʛ/9Wi(ktrIʗWk] 87 疄<Mpx. f\%.N8dNL6ZoHr\^ 0b`灕|[lHMx=p5a1 |m-?߆3vap ԅp-\jn ׵pF$;scOC̀=m[ pkM͵&"ᖽn v!<ۣp2{p#4>E}%z[A<WOc=L@ЭT!hFЈAcs>Ar3z|ED!(#i:;E}LJ3͜r!/zdod <%< xoEHR3B+y!Cs2qBG֋9Kra,B#~*B uB]A)Pz#yZ4o3Bv!tjHGұ\z9BD"kYAaGo8FF\Kmꋰ a"o:TAxSkNDxKj[!ܩ6­{!\ab'*x\GuwG ;F4Oi_࿯rgR~w~KX-E@[:G{7t{mwhbExToF #N#PWWHo+ކ^)qМ$!7$܁cߦ Mt}ʜ4rS~ZW5Y6K"7Vdբ*BIg?bV0owLeǖEXG;"MO`>˫k'wM= }_CZWϨ>YP٦:䡟3%F|6\D-ЯWk^?vc2 q#*hmb1no[adKT<NF`pG #b|-b' vĵs=?t! yH(]cX*y:#1f+ I!4.`h1C6A1H+ mdHH8 )Ӑ:RHHuԀL.j6Bꍞna{ %GپUi})#}Td4 X4”N/>Ǜ#>ȮBvju}d-D(ڋlBy4 lܦȍX*Xݑ;r"r!ߘyM)F* -k {'#mr9㘆=+6Cn<YMeYryTOidD H;ˑo(!ze"ͷ&5ðI 1-R.Ej`:~CH)O@'3#!FO:2,@JI1R eJL~&]> k!dl|٣"{d_FgwĀ:dvOc^uqy|||>Ϩ)Nc3xykw4}Ng~moxlAو'5=P+Jy<7h8gF4♏gi_# yP7wZYRs {ܭ<*Y=8<{v˳y֨j:g$x-se<C7>|x>3Ӕoć>z?.=y[|L,> wl7݀yBxmp]/RwEe#xSw>!1O9'$ [#%|B >}>%>iG>ѬP)۬GQr|bwEJ?h'!s'<,n6 R>LE󢥓yQcY =EλxQv /]x<^YY/r _⅋ yQh^xa/Yɋj6"慯#yᾷP}W{B|fu7˟o_"? +qus|r>v)>wk<\cfd1k11|L׊'#M8_|E|l{>n>T>6L9bO?"U%>V<q45Gޛx{g*|RD¢G f*C=g{&v<ä)Oo>g#u𴳃xB|x *CId>vcOƓvK|t5;rW2-SƧR+3չ:#s~zOy ޞ{Vn>wi{/Qv<&Şlxzt5;vcMmx]_>6d<)`]7,#󈮃xg :nlq=+OOæ'R}ffć] O3dN_6A·Y Nɹ3kA .mxV<(g8Mj+Ky~g~f7]οbLi:L{'\=嘒5O{b;('rqBȗ4>'<ʇ# AI:Ie&ďGxR)<%ZJ>=zĦ9/u9둫sk!6>Ͻa&nD|`_7^`wGGK1D'.PǕ~q.ynwx?R޷?c"6ӏŝep8Q|-:UȇQ7Oh[v=·Z5*xF)rH Yrn-yN 3O'Tv&xX(#mlE|`x>H;/mn~+<5%OrC^lw(Ǟ!ʶJz/U'ḋT_ [.o6ܓ^+cz|ؤN| -헱'f^ =`1+=O $Qq|~a[}xƶ09.Ix֖|d</PMc|"C4ZsYKyQ2|ټz˳ Mxy%㪧DO>'/1#ы|{W,^0`,{<\to[x-}!Uqr(>zZ>jd:ٿȷf||t>g5ΘG("g_tn/ɼs̭e+P~V=9(ޔ-w68v vCWdW;1{}DNJh-cy ]ǻ8x||U /<ˋZ>qП8_ucnjrcʸP`E5nw)X5"QQ]e|Z76nй-W΋&2!ynGR6-ꯒYywK39G|oR1 p6kA> ]~ kqr޾%Ļ;=<=9o=^>q>}5>;.y12$>\wvbOv{9;*(=uɞެdd/}ٻvfv6v)9ݺYN;;=ݥ+Fؽu؝ص٥O=ؕwص͠n;!^/Md{LlNlO[;XݘnmF+2i6=Ɔ8,~_KaXb<2ԏ%5(߱,`1:FNf#d#ޞgc;Hm(lˊ0+\ȞlO#6)3MUɦ~@t hJҫt6z +Ί%)ɆlrYl;Pސ3z? k ecWhlB6l7[=ލћv( >=Y1dB.֎ݱO.w566w6i=h/XZpӂ=lVlz2-1OdE;؂"͖Igh~ݪ݉\nn4ceN+שڃm8sHbwmtXVWR*۰/(fOSv)MC|`؎U*avdxOpȷ{|){>=k_ž.Ӌ=ًRO'NbW/DZ׎˥٫[ ؛͏՚M)[*{{$-`v}}Lpd7OO ا+Kk? ŤaGٷ-?Bb̏iN\j9ˑN{ԱfO*߯1jμJ}^{^xՓyj%*ay ZA:ލ<[kN5x+x7;xҚoxѼfwe,0פ\k:^C^o}oy-+J(^o-SS^kZ̫f-fdկy-k5Ypx \k$e+yͻ\+ zږkk Ud?6לnkj({nεvZc.^'Jљd>8 ^_6IZoj:G:uxy;x]w^oS^WByٞAa#ޠ%yNcU yy־k|QV9)frTocWOmy6ւ7HJT}<~/㍪  C򆛖Ͻyy#qQxlx<_O,ϑ换(4Ӆ77Zk-\uFCt~-8k_טּv6aיErc9؄7nTur=>uMs\M׽oƏx;541u卽n~\gL"mACgDZ[!Oru|ONpUϥyq5ОD9Q_ֹzZyAKj#:~V;ݖNus- (Dr_s]Ts(Nt6> w AևC7r_;?uS<[#ݍj'+-eNxBESŜy[-t\Ww;SS֟87?]YKu@il^5T,̛dYywX}}P|MdӞ1M1D,.\;q*EWB"K ۈո O/m'Fpv S$yƞPKsF)מƵWS׶ε}ROey{6:T#tfYƄ]\bmK(wgܖwdyN^gd] "]:!d&gyε5o|g7ML_qxӵykڗ7Û漙s޼Mon4N.[df+y}x r oo6Jn&zr=YEI{bF-o`,ozȪ\oW?\Vќt+`HG28 }p չXn7t 36)}y߹Q>7Q.F d28Up>n"]}̍ nqc5'5ړDn\[͍qB[4?)Fz*3e+P57< fFs,nЪo:SѤc}\eXMrs%(?MUr78n}67YMrܤ7W|*ȟd_ J&+As ¯dDU{ IS.lv@ё]Wa3a'Caz >!=j:}Wwn97aes.);=DdCܬn8NRy=duH&wN&Tܴ571e02A[֘ptKei)d*=M&gIsIY2,!l!/D64iamabP#'lEz %;G[DwwduR t%! dZ#2_S'0TxZ؆>"$b۹/B' ?cӎ=y|Ko|o nǰZxlG_V3 Mc[y _}䣵;+|$ ȱmT%fCrA\u,o!r=ȱY /D 62ۦЉYU{zqV~S\\ASYu+|U\"e(WrR%U{%>H=~Rc"qŽo +d]%kq t& Ζoh1_iuC?DɽN;,`LWևСg#=G#,z>rB&r}ugYz3xGb=i~j>-[xxy2h/Kf[,Ҡo›ew)e[KtnRs7-˛͛Mz&&}SH8HƩswD7xYӯ iLŠ ލ[(zzwY}w]rGI-~9Q|3focܬ#oo9oYOKU ޲)rm7ۗ[n[-{hmrekl%9ƚ^#w8#95;:eq_.SkQZ EMtD,.p&?GEfK~KΗxΊkZ)i#Qlaeܼ-Fx[+E]`?y5{1~]׹k{.Qi\\]@|W(XƵ>ZkxMmwL{̎W95WWyQȫT\bt|~}} hTw?wcw]C{+쥳#{;豉X̞~fӂk%{b=y^ΞD'#!pWVcUMdx)߯vSgq`ke3ocgij;oroqM{6>nD=eC"xW[{k#?kǵ KvFRR]ˮl.cW:X+R*ٕS乗+{HvYK|mvt4UŚ؅?y$U\^y.aWW~ =soc'iw 9.{Uyn܁›%GDg]d?O`g9Qc{]bg|?y٧$gKczܳ٩St#;u+_t6x +yF#旯rc&y<8w;0S>8Dk.ܙ@g\)bm¥x\*8ڞ]bg{d,d2b֛ bĎ,y~e{kI7';9d=!v'e%b&*kcb&{ȺkSYB're ̈́Dž<OWt+ge;ةA%:Ίf2 ޲c+F_̗uoff<_-V\r UH>tVg-ݔ}j3 H܂d8Gx${bYyc-vgve%;y1Tlv\Hx'cv"9;~;ВͿŽݖر}YYdvt +@^Wvv[\ٛ_v%&%g=e۷L`GV#UbHv$cW]d6KL[#؁V`Bvp;`wf}G>[lT Gݧ%pbk'=6=q[ޢlocl.ۓRB|:flߥʼw}IlY /۷Հ@!;~].˳K*$zvUewmVlk='93Tm֧fkӓٚغHJg- []u[9[u<9(Vި#bs[[ޚȖ c3ױM兵 G{[(]'UJb+=׬V>g+lE [5O^Xx{D{` '`k|-бy3ؼg|l~yaBzZlNX6pU͈(bӏz%6óզL.aN뱹 [\33xi[ކvalcќmuXv?/s*vZ<٥#gߋ`/~Gw+_7αu'cNU^w/eF'DMAYRl2o{8[v~ͻ6OsUk}mr%Ć{gCyT(p1y)*Yw_0| oO%Q/D^JxY>0-',kc>U٘$;BOmgTkgjw yg6|^|v|}s>ׁϵ s ]6%>aqϾXϱgG.^&YNY||J^ O+ӻ/O:;,ԯxɫd>u?sOoWΧ,iŧLs-Z#stQ||+|j|j&|jpUFY$n,Yͧyg>_כIld®[| >~C^\/ŗx>ܐ(ŇxqFLE|*/'&KY U#Q_^WYx,> BAYxd_*7,響J?,f,t*D]VϜkpm,ܲ 7 Sn^[~SJ ܀wW|Cf$ Ի}Vƅ?>A-Yznk\+~e_R) _@i ֐+qM)ϻCs,,BfQg$t%t$"HMCqO4oh?KFFyE8 q6c_c8FO-řD]NCq!U/HiΉ{8BC"&x {[C"F]DmQY--|'9%4ĘW91GDKE]BF/ZAbD|}GG ibs^Φ[[3Xq41XBrj/H~+l,!&BvE]_PI]DA}oܲ~Du#x\*" ~bг {hFִM޲mȗ~bi' .\ ybW5E}<Yw+^, 讐h v6 ;NX?ejvBW)>+iy5LgO`a+=ȫb[VG?/w+J]Qz~(?"yrND7"i|\kD$O->$SG|M99e FwRWś;)r' !" )E@1}b&b4[S|Eĸ`kF n[+D` D]Pk☰-"i򻈙B_ئ٢4O$ڢF {i򷘫xÚ,H#Oh81]cWABB`K[skm >}sŸb&hkͥSBNL|j0FILjVbЇiί,%xht%nj&➈>-4Iȩk)xh/\yWh3wv_}" Yep%"i_Ӽ!59V741Qk4"5kE9m_/599Tȣ!COSr(E>9Fk2%5UE)jr(#k ^GF($x3Y,lG m;6fa+Yʭ |ea۱e,lE#63-¦&I,lb6Κ:*eԯ J>XX! yzv=)c6`:,U2_Ÿ(Ͷ*}$+cffM):Xp],~Reæ,W[Ƃ~d_-X}J)ڂ>Tw+Y),mu/ z͂>x) C\UoYnJN-tȿMT1CXХJ>A! 8G IłfA{7] J@r{[Ă}cAkXm,hY9 Z͂6SDZYм S)gThq.f/M]+ iyDi { ⌂E[hRjHD 13=E]ƦM]c a+Q |bAv,5P!|ԣYeAi7dDwdMT;M!-e ٛ~x,!n;oYeSxm pOn`G,ps[q \YE,poXN ),0B}Y`j wvc}Y`N{g!3X1R!Xg踙v-Y`,rRo۴gfYOtXAOT9 vb_LR~ԟ0,o2 ~_VOk2L0S߱a ]*cAL]V_C'Zg`ޟr{B2G^ߞ׎eZEL= Spe){z.f Mb˕zV]z*N񇘺[k3u@8:Ȗ3S3w=Z1qV0ۢmCcjLm5ÙBvnԭ*e˳J QŘhW 9S=fR 3 -J1y$S7ݭE}4ezϘQn0+T SWZ1L]%~NIn57/e% ؗ|?oYn =eO߲Gkk7z7Ye5 6CR [4NX@gp. 86?}_rIv J}o,`6 6OXo,`9 XPX2RH>162'uIJ}M9 O%Nb|=R#ꂄB^ѯ[CСDA{ 9{V1GA Ҝ]s^Qž,`$ίYYL+0,x) (}&Uh_0>]E)E͕ho)E]mK3?2 Ӊק[KD%֋R+xW>FP5c>YD]y죙+ʥ9X/&}>A_-xi4Lѵ4rk{!FyՔ2 :Pڂ:1ѽFќUIRxLeOE\veIo2a5 vE/T戺X/R-x b/.46М[У"0'E[w*K5HsGآNsÛR fg)1RuR[dk)1[nǟ*5%@y@]MO"o;L+"/VH49P]0M⿼)(.*UXvZJX`Abh*cÕ.( +uQ|/8CNfʘ9J)$0ϰf:2S+xB`N \!Ӗ0s ͵TkJiziҧ<m`!QHORH'*2L}uҾ{Ce &0 Wc꿓G | (ر8Kڞd X`y,I|BuY`Xjp gMe ,pJtfd3X Mũ ^XycBK/jQ.W}WuJ]5Y,p[R\3/D]Ў,pEsDb~1W[׼4#>Qu# -~hHO|${oD狶滟>~#R|C$o%V,h";)ۤN)uo[)}/=:J!U|Wٻksw]=kg;o/۱,7 |ߣ5߭5߹;UoE!{ 䶁]{fL{2&έ1Ÿ(ZA.XM۽2'E.ֈ1'dBwwb)$~S})7 u78X['bIw M]3.h#_W|4mNԅ.{jH$~[ɩ29 .P=J]̌so5ⷛJ}io<+Y,p >fǂ/S~mĂ_}-oJoߙ}}Us R mBc!Fc3 %~RP~ 5a!XH|_{PL6MT.R~[6ljF'~;@ g!9=B>GPh@QPgڥRRVoN!M 7NA:=̔ӧ{h j~+d__9_!/>+~k֊R~W*t*~CTT d!(庛fpࣼiLcx3ozfoQj zsj'xܰq 7čo?F5\_l oc(7X w` K[ zns\?AusKaOn7p׽xayޗޡr^ý3{߬-{Qm>(IZlU62q}~=١\\WaǞ0@VnA}YXz@.K϶c3,Yњs7Btx8`[0,[>['+XfY,S#t"wc=mfO5Yl 2ss]4{Քj喹˼\; fNkk+li3.J[7I۟ՐvYJ;^vIS?J;R>J{>]O!eʼKGԆg3~;=#R|f:i7 iqF4~iݳ mRiqdN$iʨERq;Ҕ㥩UZJΕf>4m#-*FEK˥Ҫڬ[ oKݯH:K6,mSZa]int>iQONTt]W5"M& #m=$vj&O,7E;z4:iܨRiy[Wm4ziRҔ׾R)ziawK֞ɐ65!m!A?thW$Z&k7F:mtʫt%Z15WF9HzTzYzvU+MF}CqϥcK_t}JVIOo'H;H ގY"="=! ./sG:;ht2htlKttZ^i#ig;iUҁgǖIέ^"6dI'IrH{+o=ʤ݁ۤ=IҹR J-V&Gե+HFד~+G,#y2_:ZZ:}J%UܳI7jKJ?IW?%K7m)ݍ$Uꪥ;I'KOzKOF߁t4rgsgBSRbht>O*A:u|tbUkktt+Iڑ$I mGI=l!wDto)i4imihiIҢ[&Cuv} qriUyJZ0JZzAZq㾴ai*ia'ɶ[[OH HO3{J/uޥ~~:RƊ# \f^vF)?hZZGj8Rtj#U>Ryّ*TUHo<~Y/}~ }|Kzs2\'},U.'n(BGƉ͚Cֹҝ4KSttI.UA:TH:aA*wt,Z]w@ڶ1WڡsVU+]{X[ibS>s^=ҞݥCr zJe3;IG*vHGJS:8a5igGmiy=iS~-= m=:PV)rcinɮҴti~[iڧ 4|iwM;)߯JS} Gƾ )Mr,xJR鉽RqqiR_7(]O*::F**?%'lKٝ)ҨҘ.ҔFǥoQi|Y̬h4K-騒KkIҖҖEǤm-KsgOt6Һii:iVciń,9UGtB%U:1A:X:T}tJIjV*|C:0담i{{i--UH[g&JgSL+Ж9J#%QzfJ-?e`GiiE!ҪQ:} UHVk]LyK{Q~iiN&"A>w u"u;'IyH+le~EkVJ ζWfZ-͜:LQZ^nY]I\>(RJT5Hz#G#>\+-v1%5JbH&G꜇Ҏͥ=7WIU uzuGiZif$l4y@44b))Y (PRBN#H*"% cw`c ( 1QLAa5sϜ9sA"m$hxbxj:YCtOHYublXBTu.Ȇ Kw=ٯ=Mhx*) M!t!LCt"֓ș{̖%g}m77SEygHPJ|]Iϔ,ȱ VFg#HXraUrw ɷB<}Hr ZI:M<8t$sÑ/J>+wfk~ QܰV$8HTJ]H[yB>"mG]7eDL\, CL#"e?ywy>i!Cp\#7%͑ȏ,ƫIW)+H:lI!(mCdW ^ك\Dn O##7[!aZy0dyrNj%|g_HZxx+ҲiNZ#UISli^ %mB24'ukywi#&wY,G*7+;35u1rN"^ۖ_Mx`ĈܒL< %?"W#IΦ$uG)lI5۟l"% Y#xW'tƑ r{u)_A9#wkwr&rQ-MF`mRQO$#1i^7󞐖 @4赑/mOȧmzRQ^s.=)%} ᔱ8uj5néq8$,>x㎡wj{葶OFz~<ӱ5dkpr1Nn>8Vv~Bhn'Qorw> %|.9Pt6CahY6n6Z}BhZ6GRDвp6ZJ_彩h.--;hh6q!86G~{N%h G@q5qP:N@1{PI{)Z wi'3=}^U`8=TQnBǝ6'ɯ]xFd~l|9I˫ Ԋ4Io7VMW4\ CI|).TRk/9)&%޹cEyzk'o_ y+y_K^e=RD*#*#OƑ&|OR3_7kdvN-O|ȴǕ+#q@dqD˜'d2;1S@ّ!-D퍄 ,N'摾JI/ WϞ)Ҏz9sӤӤcJ;/*wU;=(_e'u򮑨N%[ZE4 [A4"DKa <,D lڈ 1gI=s KQSb2u1ڇXING9uqQ#W1B\;d|f0}.G j`2bs;KBdKGWLt_K$K$aCJIx%!3%wQ~$|6UCBR: tO 3fЇkIĺ]AڕH{uk,P2gV:ILj f{ydE_"1_ cEc'/!mȵ_Ia?V) #RXijNYOD>)%"u5j2i!m&.e{<ʰk}נºw8 EVȣ"ETq~AW'pjjME͉Q;jx&:Z0mPg jUS'QW%j^+jnA?aq jXfpxPmTxUءҵ8})*ۣž(.Ϲrw"@{^rrZa{ҵ֚M~#Ƒ7LHpK}AZc@Z&0Ҹ2|}H`q[R]H0 H F>oC','%RRgywω~AL$>_HIm$`)!%LVzKYH.\}MGiɩ"Frf'GF(-IddרlplUB6v#m$믏$k kԿmōUdD`LD]|Dm I"&Gf#3wu$<]0%zP{eEB#ߒdIx2AuCHZ$$< E30-!S) G29&!N3ɄcCff~ۥ^V&V~3J;2b:/Bv c c!cW?$c >o$3Ĵ-#Yw2d;=7TH!}^zIz=#Yza'i[i2馥bV=6KFQWHǥ夂kKf'HMRR:{JUK{- |!}L;Dj2aW$FvH+JJė:$[F3<x%i)P,wTtPTR7RË˥N(HJ >cinT9R0/rdqԿ4 itE/M\/|ۇ"ݻU]iGNyHp)Pz0t ;KHn޿A~Kt2B[iC#iRѳSJ\^K,پ8]0SsU(>yj眛η8_ΛY95(57.-X-Q2,1f!Y',Y)8M(qӔ.uhZJKɡ %U|Y~FJ> tv`|*Uvz-TYᶤR@򶫧%i3Ry<(I$Vrl>[UIT4=$8&]ɦA 9\DCRpDr'ssIc"yw+X*pːUIIsOII$,_IZ=ɤo,eR,E21n$$s2QIINT=T'sHuatZ"#FJ'˟e9K`T( & =B%F̔1bs7b#U|9K:hmgA[CJiޔ1'5k,ZԱ9Z!Կ^:Estfz&ck+NZH7nHwgٳGkht>nMJnz*t7_7rtX9yRa3ؐ*&z{J mn*B:^)F?V:yP=i`4,4bF#QYr1Y4E4z(iLSnFc4g_1JJgtJ&II=>Ս%R:Obe -. J=S6DVl)%8#&_ ]Lp'E$煵.サ^s9 ܠ{8g&ܐ,No!7k)gr@|ݟ{m9~9=݆6υjmqcp3ڹ׸YS>p1*!\}.E37}<|,[8wl/Z2[QȭTm,T*qۮ?W-ܮ'nl6u9ǭVνe]}͑_ #͔K bH\\HXF.5秤,y]I7r97"Ex7gg{ #s9VNߙ r{sGs#ڸ1rf9;-$c3nS4y 3  qm?U-pAq^P,q[5',nҙ\nFnmneZƬ'6 N8[?׀4f勸zreA܈#-ܨ%13Fsc_s{zs3㜝N?A8srz/m7i$)r37qg\9q7n^snќlnŰ Cʹ5vzACܖ)sLmQbnOn_Fn@m,vgxRl,e2?qqrџ۳Ǎwq{qܞ-߸MzsA0ЕMȵy\1w$ˁ};R6;le=+vmOmjXŭIVޛ-;KˉM۹R.ܹӓ0&N]sx$nxXN:.3HUVWi`A ѦE.9+r=%-{N*,]0O;BiZQ~qw65H;I%=n= r[ÉyD7+$w尟ki5^wHXZ&J'K(;K="/O(V>Otqt4!4|ׁERWcSߖeq5%ǒ̐l'ov(}XzhCK)Iz- ֒i-FםLb+qqGssmx?.v.Vo-7ȓϹKH|.,I( lyNM^MZsyCM'z}62Gp*O8~ٛ/[8 ,iNrSqZSWpu9F!۾Fqz-AՂw >4Dqr2o.]sFʛ9, 3ӱX̩Vr}7e8"o0_AxFP1@]kb{ %(3<(8+f8Hp8gx( n_Y &WZeé 2&rNTXA{8z.XE-ŵN+Ԯ<ܒdnZn{ܮ}댸o#^rqg.8qyns6syC o_sGpEӸ 9ݺ[ɕݘ=|ν}ZuK(4Qwtk?a j(bN#GpPLA#p[_ Gv Y+>;GhZh;RhC m{-t W~KAAaNՏzT ]5 ''E _  g Si#& /{*\S "aa8|a! fDŽ϶K>W!|D²Vr! _ _/|$>])|U&|4X'შv{R ,|ps&ayaLCxo4aٟ|D=aRB:A(9pHxC5o^]/Jo$rg ;C!&X3ׄOIC)iGE tSέV)aCH'PjyY(9xMXRPxUIJfa aQHX/,Ey.¢XFkYc12mFMlK07014w"P| RL2D호)<?\ae;X&쾊 CHD0'Hضㅳ1[ZaLbqC`tFQqDL93pJ=\t9.PKEoqY[.}+N.et9Wk:a4$n/\m/uy]~ Nvnqs5n_;f6N9㐋{Fx:VC)-xfǏã#aX<>F?ڏ'\IxgLyxD<ъg$<)2Owi'3a[~~vw?}},#n"ۉ?6wmR[l7[azl 1/뙳X chyk-:m ~au),MB 3>0(6ïձ:u+΀6zX6 ' [o3 ]:"[3]Xc{JYkcop~/d4u>Γ# v,99L8=z߲!Nſ}^bWI<1;-\M{]ڳt 5 l?ڧ59Ӏ:B,7}w>^ ih3h !{yK?b@<=n=t=d?Mc^d v:`6Y2;'3&; ՠ?^Ow Q?|o/lŶ\FxZ[`7lkkUi[G0[C:<a_ ^0az[ W2bk?[l ֜2v͘–fler5F&{[`75|[f X"6lƠlxsG`CfS\G_S˰k~ oc 1ۘa6f;>Æ ؠ= hc 2]h)K&W lU##cl/فg{Os?;0Y?>a= WD*_T'߮m3lG7dk`( };6 l؏M >aӷ4`ظ 6]76d75.2[sX]هXWGn9k+bi6|TھBƷXkuklUX3~nꁟ u/~yA6~vՇbV?auQ?jgcNFy~knksc s]_kg2{8~2[g 17ř߸5[ʍCnV5EY1]5we7kX80:Lڵ?I ?iO*S^-ՎS\&2[٪kR]c-K\ $ /?`]uߚn:.4&Xs 6bu?{`M&qսG / ?D3P?;৪I,yq9VU:b)wn$otVuNu^{ O۲lxF~?†rWlw*}R?&[O_sX9`~5^a>>flclf~/7dlic+ yD!~+w[orkrg7a~dQcSW1?Ζ7/XU; *fe:WÃU<| _ 6|pYgQ|n_.~Ʊ߬֗= #p<~ arVB͞|3e D>=39X2a]!yX d Afoi;7Ͷ29oluMle]Cq0v5b'LӖ!Ya ;ERj fbՉJYM3dzNf6v6f4o2[m~tMrM熿_wcG>;٪;/Nkؙ GSvliه7g_ecVmxM7de c6oL^&0 7~Wӭ<<|d39- 6mځ͢lrCfZvg[ֆa˒b:Oϴ2;!Zu!/c`[]lXjѡl+^>ric{w^^{^ǒd@ O>U޾hfge&L{XH{Y޽w>iSkik}hJ;DLSeuTN0PA|h'/i_U9UA}G}7R{}]HQTU{.UK >z.%J?FG5T 5)HvzT+j9Tw9Q͂da0WI՗LjG_5Uߦ*&Q Ji@G: 4U\mMR'O|-*v UP_@XPө|+*=EV.Td;U:$1+Q]TqPXH\0oQ%75$KmlÆITˌ}jϨZj=U+{JmvM~wRT}&U_éBUҨt;UGJ{QGCR,<[YS,jXFUjtUXfF՞0[P_zDUi"7RTsczLܦC2+:65]С7d{ꖫQ>mTOQ>qQ*T4-M꿧:q^tHh:䡔X:ut3_@hӨRjZT ]Tk;^TvyC+YtH3t:C؎ecyST'd&I=FuSgΪ1,Auά:qt:[Bѡ[ҡJTսE;ؼ8ի2iT?/K7]~?I7QyT?xȧJXN `j15(Хza*tXԠډBj2ZmHa1a 3谛au.5\,k"5(5(F˼ъ(5525EP_֟$_JŁTu }F^][RݜKT7&?C>ҡsГth:[=Tפ'Ϸݷn{ Lڞ`cae ΐlE@ ڮRC3"?&. Y@VQѻvj[M~SfQxKjɜoƗRQӨj\șrj,SIj|pj2&wtxt >'>>.֦7Wt:P0# }=T0AG8S<ΑttoԺHG'7gtK`:Bu::BcT%BG/LwVFjrxHM\ujCM\&d1NM4쨉ñr&&^D&cRy->G9jTmHF\5ޗJS7v}N-`ATPwu55!˨n*|~j殤T6\j'QrT#ϓjN5ԩ_9հo#^R!_bԕAyGe9AHA*zIN)SfKT}e,Rj8;&T} G]Qu&>eCwU{IZԗ}j]VRfՊRHPh7StS7T%/vPU|*=OݳE &|[QT U:G?*T+Uq-U**JG\7SՈT5U=FU?Pq:T-a$U˚jߙT픍,fPxL R&7扨 MY*EU.tʐFSt`:B: o3yXޓ+B0YE(9S{կT1;*nDUS be(x%t0Who ҁ3},GVЁ_URvҁt1S:pm 8WLfE'),:@^*Z'WQ\*xܧ i˴R/?/?MV^iY:PCtT~о]i?asVN뾦Kir>Gřw3Sz*x(TqTGU0 1T!UF|F_q7aUx'ID.wtU*@/PT5Rŵi)PM}^3P%TI*x-*zA>JϥOmrox5*QBK[JTYi4UaBo0CURUT5/XnE?A9F_GH5TR%FTkL_YzLfo!>tH _Kuv?:m_P[:4͂}x9CuWjQ݇'oT`n{^E_=M DWT3@eXapt/j~[I\E(SU &jty5}PejB=5zY꼩s+jTtUF q.h6jF QëpKjB P^t؊tأ jOH Q2ݲԝlziè:b3y?nMCw?Cu:orΡT[Eu+4!Cv:ds::*:8"K[C[v+Z7WRCר7|2jƼTc$jctPA:H|A|\ F+U9D 63UtWFTMq)U-CU vS;@URժ,?Tmjݞ}j틧Pu6weUbzWrVRծm,vn[@dO^/dQ}g 9m^GR;6|;LOStDŽz*TehޮnvrDAPBM(UߣJ4x=2aش*MJ*d:(n]ce ;qT1j/UH )*SŬ fd.+2;'w+^3^TWD坣} h?9}+]^$O{,dgBiО=k&|l[-A{bؾ41F{.\FZ e*hl]3Ez?iWhh۽agۿ¿U7xY;y qytl#סHYu%RC[7a3EA)~Adgtxl]vFX<`lCe3ZyxÇP"ņ9]ml gsSϷ'g!c_ac8 ʶ_ڊص=\D{^H{HihصBF;iPm*I{>zPOTNU*=;bh/'﷭9M=a'Ω#t!LV]ٙc~W <; a;YQC6 6ja8YXo1Zv>[g߂s6c 6̗ݏu} U*FgϽD}E 6-QƦE{[bKlM7Zܧ`sS37eIYiyTisylUb+>Ɩ#lQIdr[Y[ l;Wc󈫲3Ŧb=Fbl =Z[2l.{jk6Z؇CJb6dņco)6r"fc\W&<|_ܟѹ'6dTͮL&csy[~aۦضZrc{¦pyltf6j28`K\jl1vg,7M_tC'.]G{PSTsfD{ݓ}5QTY*ْˠr;nI>r/{ǣLWR9͉[J{˽h[:TN>rײ`ri2ߍXad磿zOpl_۵5Cq.rxskroYFXv%˟=oX~k&;ǼXVժ̹{3G&Xs|WUrVX52[jwn VGnWJ>ZsB;E >|wV-_5YoMM[3ҐHQ%Q2e$cjq;ŢK X rxZ~KnaiglE,_zK(6%If( %ڬ%֞(7ھAw}iB옍%D?xO8,ƒ%(DIn#!T5#6ARɎp$s#{BFS)~Œ7x}ԱN6`8,}܅>?=;H],{&2b`,RVًY, d%2xJ0oL<7F>dz ,<^^/?Ǔ[[+z#Wص!x4f#B/0t5Žwcgp!,],3c0`h̜n:3"pq^0wzƝqgbLp.͹6K&nt^C}xh/:<#^~Yexz<杺糞cţBV<xKg'T>WHM$xEw7>fnᳫ_ef|Xfec3=vwU9~]ɿ%{wa̖6*Ʋ,YxWƸx~g 6RdžsٽgC!:c}{XHvg}\[wkam_NƵkH$"ZI?սOGD'kvҐ36~ ?9b_VwjXjG/ϩewҟf2<و5%X SL)~uwI_N| 7 ݁~U uasrů~_k3k MBU,,#NwݱGw|Jw+|_clr i\b8k{ٝ5[Qe9~װe!6+Ư }{q%Z`Xѧ|*+3 3ޓE=o7-oO5?tK2%ֺ`M&_~v'~^9CvKv?d*aTFC>m37||*>]Z& ܌tەkVQvv5IƷ>mV$s {VwXxC23W=XL,,N7d}y9ێ_;:qOzk> 3s${0 GcjAy6m7UdJߏ|*e|o{s|j >;XqLXa{ ',%|-`匉X.Jke4Y;iXQ+G_ʎL|v*yv[ ?Xfkp|-3|ow)XH7?aԦG6ߊC6j-ImMbxˆ%-kepj6|,bcMno`f?OeSNV&ٝX㥉~OK/Y-=Rw)5^~KJh7)=OYLV3Q5Gdk唱>ԫ<J]Cf߾S;VAtoNdbQgx 8}7VF'{5whp-FtIchsPD}nE_z UcPmhTU0@xv,Tuzƴ}y=z"M:E}ID6}:1cWx4GڧjㄉICǣ_I[U0ޱm85' r17N7~A21~:`Y #nbb; 'a[腩(HG z[M)mp=Nn18aFQo`18W)  R5X; e{%lά°o1' 5™1*`}t!cf/Or?i0d gncen|7^'kSiX)!xE1|}rȘ_Qb~=2T2, o! o m6^zB%^^ w/H W\ ALH D2!2_(T +aax ]`ucXx8. a{0, .X Ԁ&06U|0_<i!m%HW4ni5¼`w1py60oH)Ū0w:;; ͐x;*!5+zv@.H Rub HRU!6ZT H ;!5TeS!5U/RF@ċjښ@i9`9aκ0'xE)|:`(leHY\)sR"!eLl H)7@p}Heʋ!hH/#!BO n$$_gBTHGB1w"V@hHSB c!٤ U@ҟTw 삤G!)+c$iŃ5ď_ Y oxF݄ y b-_+@wYZ B›Ő0$TN' Š} ]H 7J!^H8 !JH +A‚ '$@B_'uѯ zo DW}At'De@TDU@i.jY Z)k C a{H( =F=(+ujA<Du@"DOAH ~9mѺ@- A" 3X=, rH ۢD@DsA4Dh) "*dx;A5@"+ 2, D}{HDڌO e]_+AjK r4ߌ!%`<ğé{VC|3!hğ!o+1#|?@$?Q3E +ړ)VCo(:}fguxoiwY7tߒA4 \RA8C+̯'Wt= Vg/ba "n[lQx8f drd$ ǀs&kATv09 5 eD?΂v50`rNjS[.#< B h$+@d{#!o#$H!aHp .!a}t0$+1ȂoAd3W<QI v :YVeDk @D %b 7 Z0Zw1h*_de-[x:hF69>1=9 Jɏ=^Z5u$:ӍӍ/v^ LzJ=F[H~niQA'?~57ta_'Z^`ztD/3f+V&kCy},2I-Kl3Tm#mdfoCCAt.ku/5L5L a H}ɩ !($nFH8 L*RHT QS@⬞z}Ő "!cH7Ɛ0ĽبĎ7@̙xXN p=Al? [AāW@`e ު}kA|↳ @rA\1ķ/G ޠ N_|ӟx+@@6+Y.H6FT N$i{/,yc;@|j/6Xo[ I i{H2$kI$,@HZ t/n*CHkIA&AHVd]=H| َpArtH^<+Cq ^jiHfRVAQX6B5xBJP=D eEHY) eJH)!JC-{HȄZHim_ o2ӂ9aNbs40ga4g3JXfVV!k=Ru1RfŸ],~}:'B:Hɶxj2$< IiSřo@Q7q/_Xk @QL~/A³xH8 O}D]yuD{3;z8Og>oZ-|Zf@1w<X@"VqbX {iĞz A:bF캡0r)̾ϟl 2fށVn; f !%9ybg!朄 &KbV!&bFCK˗C1l-=D;B]VQ9Un̄]!"@#D\ ^CN\;"CB `V~Z f,t5X":vADD<y bH q1f6f3c,`S# A  gA_L!,Pa@X!?!,3<wBA* BЭ!ttP0BBR!ӎ@D\uO# xW^ lxUwÌ!0Q$8f3V0c!(18A)MY: ܆/Wti.L j0#;K ;# 0N@ @hf7B3H= `]} k2Xa @QF/ӟG&/s>?qWނߑ<$ O zγ0SLpL 3i.0f.L9i-NK} |K e~7RkZ *M0[GajdjSW0L9Swӹ0Ei2׉s-E1Ne,xSC>,%hހ#jj"xmxeO=xfdC^+Sc;xԧx[ 6Zj/:\'qe&*ä T&m 7$0ityK̷5lY&v:30 &^[ V90qL uf1?NS.Br@8Q & T\ j+{~+ ܉{FDr83s4j@1=OA5A BA\2A0: Y .uR.g˚I|@p1[ .{ːXp;l 84+~,8NgR Υ !p/K!+ηqHp._t/8? ߞe5XϓFs/pnm- ͭ͵휌.r+~z]e}l~;z\y8 .lN3\惋5c5?7Cpϡ{.lb5;9.:+< ds\XBp.}y a} by 2;wѽx8d뻟༄F8c`2?:LNcy8ոDpz[tSA8;|zw%_e:pl ӕty/8]ts ;pNαTp:pLiAp N+SpN3_SQp NA')Oo'pZ N.NWiD88 ¾;ɘmdoy'c8M΃>81S$?V\NvF>6S|6?fOI(8gZPxyZSg{8u0uv #f8-Gs~o`X66صM.c-;vQi`vcvr0ض `K7#`{+nی`ֺlvO~#>` 6ςw 6W+T5 6;f,6 փS`d6W&&6LuQ`y3lׂ?<lԞrQT~lNug:XUu|B2X4 4N>twM3zD^ǁW`$VL[]&u2'zX{4XOcXz`T =>UwVO.Kk|:V6զ`_X-D Ud `5X9qKU?mn`U,_-[r`Y`'z呙`y,wu}2:X&րe !`$K7KnXA``, KMK`9#Xj遥}dj?Tf4RqXO˾xhSY0Xi^R[]`Q{)XԿ_`,^׀E,;kBG`q0,m` `_ QYb2 ,xpBEp:`a`XX!XX Km`a #RyzatJ ǃe [-sxpq0~>`^_mW0Ts5S0Wbg}uF1~ُ'GkO( t s;: v&g0[Yf Y 0 f>h0s3Y60uL<(`w c3f|f'٘o`6nk̬ل$03E`Y:0̯IZ0K,9 &Y4=r:R6g| fSB ط{03_5R Wtn3`U0z`7L;πi=0m oK־30L~ӗi`"L+w0}4L`Z既80mw^3濻˻qxyn;Ӎ[?߯6rVvKLoShnS?0~LU0-K3@0={LiK˺480-־LK\9PN2|YH@>//+x?)H3xX<7_^tY>0:/5Ϸ2CX;RY+;fcmcmuԂu`=;XOy|;ԁuW胍m ~f/ 6ǃMl Wl۝q`{l(f? +\'`wneSC'L[_c0طFnp1y 8\ n?w0|;L~ ΅ -0:Wz8ZmGpL=XjϴG68xb8MyNsാq|}SM8ﳺ]);y7?_Se{}"pYr\p6A` }@Y+@ M p\򀋘 uw- gLmǼ{c@"!a!vġi0Qcab? &>~ ~?0bG2@sI޿u&iIi0)%LZ&mzrYwaRJ~6״.w⿹|[[L,ÛǸZ^SOig e8C631(M#~%ѻOU]Z<kQpL7Gѡj]*;i3)`ʈB"t)a`0e:"L` .)_`j:NSSa.]Z@v^o..Rl lu4>iX΁߰0s ~Qo6ۓ ~_E*c JG_4w_כ>w7O<O.' A0a8L !`v 4!Pe= O!03@vmR.ԆK`U0dL77CkrBPq AÌ^0cB X f\+mRUQa _A%2e*B{oP >Bk t~=Ήfk r0OAMs;s!7!|O?6 {a 3W;y/D^7DHB{0k& Rw@(V kBdylQc!* ATmD3]ІČX1!l0;Xf\i2]=j!n8@&ww!> wpod,\_@–l;D?!j D{A|^Ɛd|"^B H>q _6AJ4RV܄; f`i0RTH kBd̕s' `"y{!}F' "9H]w uH]ounW6H`ƿXwoCzK)Kv;!cH&d 1F42" #drd/!c 2v̍! 2AF\4.=r~&Ϳm߷־ |~2};=g2 0W^`uW#u?Z{Hr H2g++H)B-K!D2K!e^瞆@H? ;7BkmHv ғWCCHׄtQ R ^@~.Tgy֐n1BHt{AzDAzXտ`aQXXu 2yc>*ϣaa)kV?`0^W?aM0=]|g ̟ҩ!N}eiCڞې,üs0y%0oJ+̳k-s`n̽  si\0wH+~̇WH=3RSBOHs^2= d/90'/9*R0R{@ʜvR mPHZ % ~sĤKׂx2` @<'īG8 IfQ@| LB{+ IGCfeCRb_H}I)I } Tci ~Ē_A|!r I F 9.cwH c$~6ݺ@wAŻX " p$;ew@b"H !b<$l fCBH0j A^4M DcA - ZDiAĿ sĿğ8?B|RO ^=5 %AO<{2Ѷs!f=1] Y{bo2Kyܫ!6|L=8bs6ޘ8A[V:aHP&_kx}̷aLu l 籾簹lda?w<|RV?ُ+^v̌ucl1[4 ~ondؕlN*L2IG;%=_*ӓ Wa|1uF-fb6j b/W75?{B6<_;X-l]Z3Rq6:qwhf2=Kx]ӛlw8q#?lfЭs@~y[-X٧2cقo̿3w4xg:Y2N>c?5=_bާ΋nE<73 2Dh%lQj%hhtѩd@Tf , s;DoX~ЯՐ̾; !A%$81Y, ط+$Xdq$H0_ !A Aט} X_!A},5Mψj YOX~ jzY5ID,&F/?ς6xv|ٹ= $a:$ 1VXd?qqHdxi$H|j '@F+"$Xk 4 ) 9)7>ʓ >o(7xUwA2X8ŭ Iײu1$'4$٥CeHaI4ٕὁ$A$qHRÏS , ?0aDx`$)cseY3 QE:H8$$C¦.&SATD%g@&" ;0~7FC yϙ=+}ymwF1;ln ~.u0;$v2O!f0ļ1ņ$L1C х z[B ADIvB06K jDMl(g;D Ȋ"oiBd_΄H"O !rgD@DJf5Cdoy ̊a  ( D\ փ B9"̲#033a0Tp!s3W!eB\:B}gRa!, 8Y0sпBfBl WP :B*@+ɜ !B>"@05Z Xc;3lxflKa1O)I! eB }!CA& O3Lre0}L 0ݰV3Pe @l `4lo:e0ߋyc߼:oW ݅(*{klQ1h슽{o[,Qc{;?3s3ͽ3 w3ԚHrHқcIY3uHKJ$&%l6)1{|3s!GpN]Gi}p6Y CI~g $#I^G$q#9&oI| u%I?IzI$')ѓ$$~"Q,Sm"'$%0Ht+A¿H8vwII¤$B3$%5^ r'G_.gbj7aN4~a}-N&nF˾q' *bk>>رGcP{j*v}?n۱]\mIl?f:`-|u\czkjMJֲX\Dz?˂3X.b_i,"vmbHlFU#6G<+U)#fwt'1CTž{ #/ː=# ^%zTwhvL$L^ڌ ھO(* Fč:?BLPH!yc'YAdfDٱi4Jd% Q:EDۛgPkPFDDDAD41o8m1v/G ֖jmkS ~ _:N ϩKxl k'\k#Yo`.b -1yIX' Oɾsc.QLb?L~L`ZN I;8|;5e1o0mtt Ŵ9ө 9nmL?a:;Waz u V ͕Va.&um `nrsϘxqa1/}9攇_1wẺ?bn]J1Ĝ{2sX]>K1tXa dsB&f3R'm^udjanfy%9eDIKIҗf#,˷;՗:eL,16BJc2|w3&:&TO0xɾrKLU`Lnc1~}O1)xnawx1u'b<= 7au]1XqIS~8Ʃg8\b: cvYcci1vۅ1G8)^G|#u=C+וxdCV0ƣs1JH~*VSRWTN*P-oSK LK0K.zWG;1dS9L9q SAL NWu1Y ;.)ߦRO+/>15ۈ;I S+iYw:L `7UoIJ>PIǟ\k2> L)qyb\,V0D¸~=0.Yqacd21~|Lƨߏ1DWc2}jOt®?&|¶Fo [`$:",|Di|ovoӫ] KҋZBr!t"$ !&!n}+~Ϝv Rs%|5{cC)n`(p} +1#rn#'0-a# ` bqE#Cw i %31t4q bÂV0*R^7CFI05V</'!ocy G# W k !pE[놿O} [6?pJ,@#{N _CCUrn 5н=itR }vn~tkڢ+hnptV\FoDyt+=-nNYtUC79 ݲoA7j.o.[? ~VO4fчK+7JH|B_y2Nн؄q GzJ_># }_Cw2F[VtzН[Nu|D{^]3Wنnt\Y< Znaitӗ'y~K(5_ti9C9%|t]QGٸ\x9tr,еj*5><e|>mQFB;$IO␴6PCQ۠E~ h/ţU5h4@ov m)hM0P5Aɒe/(;+P~qC, gQCW>]y@ר]Hwtk]t1F#e.+]Ygdr6xFtm膮BׯKemtDtl\zDYXWok-Sc+) t:tdJCWJP'i( | k^(.;#}e{2ߺbmK(]ף$yy2et:J(mDI;.ciWt8J/Xe~9ʀ(ycd%2d22x{&I9ry(SL7ώ2(J(9((}=uQs\DsP"eTGEz52ǞQ|RQtY Qjʸ4>Rk5J(}c(eˢ}#>wJ=(۠x;6}D9'cS_/B~j?YWvTRk2R5z]<ťߥN}0Oƻ楯%)Y2o/g5>&hMrr_i~оywGS^͕~- hojW%RKԧDTgОqϗKBKt*I}ך7w5}zYU.@{1Oxӻ_VJ/˾|TZZc'uokc_}ɝQ.}>JzSoO8LMWk /oI?&i.=]ϊEWW(&zϏ}Z%2v[FCYo?ʽwlW[?Eׁn]t,/'{~}uY^ЧS~|m~z?_ɝUϐ_{2׫~c} u=ۖߣ7-8~Uۭ M?^׷A 001g6*3R$% 435sOi{D%,#vyoTAoRHP^7ޓLYBgcSN#x "+Zp9!*!dtB%dswB^ *B"4.c&{ F*aqK]ы1Vc4{c_]w\GkLL1e^??`.y;dx̫b&w7/^i a\k< KF~n ݉${$h@DF".@ jdL-c.zꇋD/Id#""#y<>Qքh0-Cd#&6AL8 w*ꉪn#* QY\X.17ѥgmB7-<9u-N%Fх >6H]}.B^S"i+jYp ?x[>T%51y&&1zbB̬3f11r/1[GssZN'ސXe21WZv!v~ob,!v?Ď?AlH21orw؛Yؿ݉=z-tؗӱ4%)K˞X+c&qY͉}t넵;˱] ~~y뱮'Nl)Xag8ˡX3ñ.7a+^HX =l,V{X懭;lc;mGl{< vۢ_h}^[mlS{ߜ>x+)Oo}y;`?v~h?M}87sH\3>c.3/!Džs<]ޟ9MYu= Odbk^e۝nkmyGm=lcuMXwfֱ6X-ꑉN,oXc:hʻ/Xj?HZsNa'k ֺ6J .eGPkl!R i\wH&Xu6?Gڎk?.oxb-kFq _:͉umduAwI?)k8،lYؒrq[KOW? ۄYؾ$+lGcۉخ/v&ۧ6] n5uv/^/#_۸#B\aMvC[rG;CܫY8JN#8d~G3up4Y#%8hG8dxa ¡|82%僣^4vp4f9vx#6RW8qcMp,G|7ZJ|cϔXxmzך$$FBnƙHX 0.'tW[t&Q%qwn;N<3'E~NR vtK!޴M"e5,g8͟pĹ΂8/sz\ Hiڍ7I)w $Jp)ѤVr 6&E<&%>)[IL\B 7R=ڸ+b5HmEN*I㤞)$XU'+ir? XOڸzpvj iOOtHAz9Oiɋsiy:GʑE.h[cZ]%pXwgӺQZ;vzxw1LM5z;m"#2-[X̅<7 MVT z`5GKhy.ݸd'J:dOhuisc_zMNRN9m&牖04at\Ot|Nki;:?-|h:[oɦK_~5*]0nMRN{]k}o(r1l=g zvCom;\Oo=:?7IKOs}k%}gզ B>봐~ߝ%-3 40?eF2й>`v Yˠgt,G1Xw0`ϭc%YC}F՞#SϐlO^D=ț$L~oE5F9EޓMO#ohG#o9Vǐ_.s ?059mGڙU6S1Su#BI\%z6{?w CC)9wt'JZ' }fH{ ю`W"Cʯ'Joo+׊Bދs=' urٴ\'EߵHw;zc-\/\8RC!Iwv z}ϟE(BP"E(BP"E(BP"E(BP"E(BP"E(BPUv5BUƔMըPREM|u]u'ը>fT#U5I52*>UuX55dUgWչԨԈ %GUTPjxk555lgQjGjDB>ܠF.T#j+jj|j-ZZKRcUl5uT0-S;9Zv,ay(XM-PMXYM ڟxUԸvOTۆ'r㘦hΩUSjd/E5vV˼԰Ԑ/kDؔAbߓinؤ2bGu#EWDTLQrr(%Aȟ*JyNOGҥ*2YޢL,QM#^"[KCen*-`p*%6G *wuQaMQbQap+Mt^zp׾%GF fu&Ix|.<SubYcS'<:? ' c ׶ Khp_QLx-_Ɖ*oj=jf꯿5CDˢ*jH5!j["jGD퍓E颎(,| |*-K{`3ΉʈϋE3Cxyv^c. y»CXhj ΃gE;Oj 2᳸='|%|+gT3bM(&|4Q·k'|N>ڥ'M{@3U5>')4 "4W =B ^%&+ son< }8Bx< @x[("W /c ?Rwe{v}V^-bU=м*4f_>7^xIhFnM%wv\,47 g]O~|,4C!shhԶhjhOh shUQ4L.FۈF>+~WV4+#zmo -|o7ߑњW2kE#˖WocBs!|J>o7,, |F+&c.{Bu S|?kl[+/ Ohx\6')W^MǾ_e<0 "}Ҋ 'RW>X؊""Hsҍ &aJ)zrq?`kNt.7"Ð dt5 2C&{|ɸ!2ܩDkxb2H&dvKx]gL2mAޒ62r"ExDEQ8]zE'uXw$CF6}E2}LF3?dE}=(ڕ #b22www-E гG[,I:雭$}Jҿpؑab2n;m%d $d`gJkP w ^dൄ ]Oagdd5xt$pVo2Oη*$IȠՓQ2?O*cɤlO dIG296!cdz3IFN&HӆܵHR$׍Hy$r-IdJNd0GFfF|Ij A3d\ FgCHLC'32_KLŌ̶ !b]2{w/&&~ù|m/B~'ӿL~29Gf\2!3df|:^%e2ݝȭ5I;48?١d޹|pܘKA$і$67I^$7R Hf4巑mJfd-ߨgdnwN&y2ۓG8&7g cp[F |%md}>([+u2;udz_ $!Mlg<ƄwgLzg&' ^2w\D抣l_27O=V3i̶% J2HfKYH2ۥE-& d>t40|I[&X)!oGl#~$U4稩zd5L$)wzqZF*d1N dr vƱ O$yd2"#2깙 FA3Jo2ξJOhy?2,%O#8qK22# dmAY92 EFIu2sX~M ㎞d~:|L " 3 G'ó 3PV&SD b4U!ȰgqhჅd֟ϓ>d0=ZLjdlג/I:rwJ& [E&Yf-[DƶD$/01@&&T?2>>L .ȸs2O"d>^w##2FP 'C]>`2(YMǿd fr3 #C7d0/6>Sp2tL"]Ϭdvl"cs b xdhT%d4(2ԊK2"d4lyOv<_%3ae< /20.W m:aDΒQJ2 !c{ǔ n!2J%cg2re9hwf:šΪQg]lS2t /=#3o2 C4fG.ȌMo;m ؆%UH9~bҳ/#ΤgMz}H3~C{<\^zAzzzפLa;tͲH+WnFLz^l+$yloHzҙ>~UBzNީۤk釾'I7׻xN֤{v?Q=oq2bؾ lגLb2f+Dx*Wn7>LǐB5键&M3_t&#=5 ^kuIV҉?HnDI;P}!퉿H\Ncul~tNs鄖=3d"ajI{#6_MZi9 GҪLZLI'i"GHEWʩ +IksҒ%IgiiOZW7mGZzHkai>ZJE.e+i> -\ԃב'%HkjGeBޒIi="yڔ4{9f LFHs%t!M^FEߚ4ۆf.TIH[>i%1HC&yHƐU i7! 4_# ˤ~\ z,ROR6$A1#i! g(,XO+IbGRߺ&7I#j'iHI,n_׋4ƭ֤e ib6?&9Hc+V_H濲b]QiMǭI+iοؑ4` ҺxRI˥7i #]H[i;t%텃I{防I:HwVaғY^~/H῿烙 ~dp@㑑#\2lOjd񄌷N d ߷& cL2ԋ ȑj2\YʱS 9wJ_g9 E^dxp^),J.F7{:/qKȠ8y  %&2ni72X cM΍rL綛 LLE2p.'Ǚ VʓA?yr%; IvKq\*G-.搁;%vE 2ktKއ9.w#IȊ=:ɥ>r|W$#P0@F=8Wy 8͌'C;d󢷐ax!jIFmC$K2cN.d=6 %QE˶x%Jf_ҚBZofI屓4Wv"M}εSIcpέHtaЙ$;H}d !!KH}&:Mj/ᾤVdNj/jV)ڐ)v"BRsT2HUzT%5㤦3T#U[: ^&Iyq$#IuARM!sH0IIW(#կ܏!}HϤ60m'IA. HW0itd\ތ*ҨLHc#c LH 4u3FDk&̓6~4ǎ&M99%Ws4=_CiJFk)4.6i搦T>OjGHGT~4'_%M_Ҝ@# )X/1_ |wI#-clq4cdɘ2ivI-v5cC*;i CvH ihi(!_^I꧇z&SRO*θXxnPRL|75뺤141&Qls,g2LVƑA/-IJ@ FZod012X ˜wz3ק)dH3Q?2@xJ"KdU0DF돑dtӐkqJF.>\FFjG-G{qA 7d9^#c}Lcu}G;21dojƺ^dRgM!Ad3KǑqk2?CS݄}xͰGdzщu@= n{J$mI<^$6$)fC}7dc6I֩$'IjIb|$H&$)܂g!;7*d,h5q@V>d˺z&WdykO-o-'|>8S,;>Qd)Y[^$KKdq6,Q۠'d9^_X>{@Id1yY:G]T^fו992!',زo,39LoL"s dәLIg2uf,2Kq5)yk HcxB귟Ѥު'uAށ똀l|!HOo +˕nj: %ƤgJJCSGR48C jZ ;QKCԪ֑Z=N V$tF$]Ʒ$gEB?yZr1Vc2Ckj8Q+Ԋ߆=&ju9ZϜNnP*5jsLSe>|Z(P+f)s6:ƧlAmZl)$k7)iB2Rp@ :BQ4) RT3X)8O 9+"_ŽbR_H uH!|)A 3BD6)$R1ߑO ^p^s )w'H#2Ͷf:)}g[yH!π:BCR8Y@ HQ*)|zD=&)v&톅@mޥMRKm5I/R\Jm}MHRvoڑ!uj{+}mGJH3K$%[%)L#qJj7 [ڑewRG*X]IeTRqM*I_^s&GHHԲzi=i(-%/I{g@;_2i؏#A Is4 i֓◚\+ϿyL7^RҮ-m~GIwj54!#f5iW c'>G ސj[5ۿʤu^瓖Wr䚯ifp 84U*F$!IFXaB]g5xH'ƻäsi, }#HU~'2oҹI:'k1(ՔtIog=!y?:o?3ɰ;~r"XS[ 2͸~|<UB2ۖdR ;!<2HFh$CߒݷVdh? ;,%C#28ȵΠT2h7+?$^H/LFQxQN3۟wMC%5~?ˡnn I}ǥ{?Im$R>TW `q&3Ǟu/RwoϤܳ)?$eRDJ)MDmk7SrvyjߟYjךU[rԮ&.v IBRL&N"#mR\DJS;7W:}'JvROR=ږY9)r)'R}JZ߹4],IóEjOHȂԖzzˇTאj7-R󔔇i^%'HȕW )ʠvPǩ`f0ڙR@R(DzHY1GJRmϤC GR[UjosCRyAʱH*r'#cHُn2%kŤlՑmӢvBR9@*{IU1Tu>24T'QԮ|3B  dڒ2R}T֫<džIaN*K]e7RlOms_P[58mEJ9n-Em7vz'[@RS#?Hy j(ژQ̭&UROގvxyKl8#y|THnj{1>)&5KI0RT潚擪B:KZ רzj*?8S%%Qˠ%$Kf wCrB8]|diS=Rߤ:Ҿ>O˥J{֒)<+THr4 n%_/]:dvɯF:ptԟ nq oJ~ ?Ե=R893GIGH*.:b/]D!]ty`ʃ6RWZ7HWH>S7c4D44h4SfI~D* ЗF) ϩ{HZIF=-rp]}Y2=5 aM~hxm#YELr?z ܺ2ܦ3ϟ3%ҡ_sDC--,nWf:1,;OsRs8˺/pϻ6K}:Y ^R2+,s.y\gldls6󳘗9+g>v97b,^+LC\x{y^6˭{ Žt fKg_$2Om8S0-yXהFqo׏sd+-w犻en/zp;K,;a= jsD:[Q?N}ԋZm{QۺQ|5fj'Crfn)IYQ[56F^3e~_!_3= ՍC~/(Wko~m<ލymV_rէx~@u\N6NTBgQ=v+Վc qۑHxmyS9'ɕz1ϙrYl=<'KTx{vռ5ܺ nOwDTO>:MD?Æ0f=E^%yr饓z"Uܿ[!k_ܾ.UՍIT=3Q,y챿t^T]c* UEV祲>T9Q*x_UDd%&m{^׎e0߄:tQ+'*E57QwV\TϮPT>[E%[JQte#ez68ܿUl}+=h6^:mVut1ɀb[+Nk]S\⹝ئ۲,o:op,o^6b^'O;ǶgcUUcyW+>hjϬ;"ﵺSo=YfsP7'cDI_/qwξ]7fمgy_**P >'aUyN.m.}|/x^^ Gy^yN9Y~?kn}<9VWe^o6 zYx=H=?{9j*Ǽ)Nzc<6s^|*/޷/ji%2X/|sJU Zgsײy?zcve52sԲ{gܚc.d<ѕcq7]xܚL&QϪu?{5ozʘǹ*i/l9gvr;lqߵz㳮泮1Rusm<G,\<9uR<ǹ5<~5nD Z%9Q'9tQ+si^6֍[wX"jK%C<ϵ-jkEmc{N<؝BQP~/-8>bK^#xN.kk9VrlkO c_elS֓[+jX(ncSg3yS`okZ웵v#s؞ |V:|OrܮQwd>~ן}q&cƙ!~qsv~+`'3ȱ`>'pTXвh!=aҡI/Ը;\Y''a#wnf\[e/nTیomqߌIPz%n}b:%'ng[|fZZ)nMv4>[on7?ى_sŭ6Y gq󖶸y\,gtq}2$nvs79\K`(np޺i/npܾ3Krߤ^z$Ϯ1vB\ qm|6I\3+W՜tqy ⪓ړǴ$ +έWҔĕrqq1AT<ϚD,QBTl> +L..7ˌS/3FYN\^-.s^Y\pY\8~PB\ ť~Ln"Z;qcńJqq8\\:oe+.\hq&.i S/-:ȉ 9$v<\%Λ%sϱ+,=-΍~8gqW80A=Q(ٵY,Ya+vg r əLE 3 ,gf;3g]^tc8}N>-NQtl8a/Nᱩ;9 3Q^$ʏ^,Fkc`Wc>|_ֻZ"~[s ,k&1smu۲s=?Yr˟'\f#{8d0#֡`"l?}"^sE(a򓙦d1Yy\tm> G5)+2ݩse-m1_y__gY|\`Uym/~)ysE,W.7<~yLsgZ̾9}p:sa\9N^+o8M3T5gi3x>7(Z{`_M {wydYc u5Xu&r?HDJWp*r9L/Dnz#;VF+^5ۣ}=Ü}z& &w'׆y|fἏTd>EyWg8'2ϫg+<um]Zݚ06Ko-1G>Ǒqɂ9V[0&7o~~j|]E?ﶼǞ|Gxo_xlS}Z'뽼̫{id^cW#Gxy:̼#׹y'󲘿&sݛ<ϋZ5Mc];.߻Ůb,{k?b;W2㹌w9rp]P9D9)O9E"@"gg*r6z9?',$r3o.b˺)"GȉG{3{]yM\c,rgsmE.k^Mar\v Et:Ad?cb]+olQE6lٜ9e/ g"kl[asT$boWu|JYR.v1/6)INb's8w\Q[%v2qk4 E"뮳b̺#'nq{lcցz-抬Bd3b̐"Y <1v"լhdܲ^ƣ)̍XSxbg+Y׳,חmsxeIJjŘ2l1m&cFPdֻ̺&&ԋrY-2o,2,GDt/'2yϙ\fE\9 s=ٞu. WpEƛJ\dS2q;qVd ^/2EFd?}E'06ܕ:^Bh\gppo(5Ϗv=\GyLȸmCෞقm眓d{`ܞٛ4y5s* 79e<\eJֳu%Lo3#XW]Xcnun3,1ϗ]KdLEF8OL YG0B%3XgrN"#|\e\9<`^6fkd[^s͝5SYͲט>ʸcX)#< zLmls)lk"q,ψ5" vq$ßcfƪ?-{Xr\dyy-O&E{[3952w9_\Ь_><χw _5a*j˲3d9ҟ9yMm3kg0&XmnYk lJkx[8 "y-pG\xc3^3`"}p?11e]|eٵ@s:V2Bk~WO6Z\9<:ynrV3cfFBe=(fxnlGpc fv9s͟&3X~;k}zNߗ%8gwYL3/resUkƱؑ K9ZYr3ٿ8wq]M$s|sCع'vbsΙO59v*-ΜS繉l[6c }e8eb y܂ \pù('8?`|s:鿘.2/%v׋ݝ !bJ;INg>0Y&At4Uس70b=73S{m^fwJ^1{ľ:r;Nb-yAb1K~4C5Q11Ŝ9'qyqc_&'D>kou2XQ2旳{m__(#WQґہFD~G-a Pϳ8 u%}-תnjطzv8+c X8{ϾkuSeˌMJ{cw(k$ʌEׯe= EY/mQ6Bq}S6Ue *E"n6rs72Ɗe>n̏i WesC״e-طfճbGgìf/o7^oy^Ͽ=I3Ֆ;K{HTm{ҿ~/KJSoҎ?ks_u;O:=?W kK9{ yϧ'[s/KwO?}[ʝOǿ/w7j߇w;3% +nq4cҽȮnHUCiҽ{6!zg }ӣ`z+ C}zuWb9Xz ,gw ZªrCaGibtURK* =R!f(F]xp/iNcFE'sDc0ūcX ,~]%S}˶ŲT-xiUժ[~ru6Lڼ2݀8FM݂[׏9%"*d;"*K1r'_#A󽐴z /LF҄HގTKW^ۄԦH-FH- b1RuEꐾH{imz!MR uR|ɺY?F+#~-⋆1=Bܙш:!nB^-E*qCdǗEL Yb!dl! ْqz#v)'uA|=$D9H|IkO"?HEBk$'DJ;$[些HɡÐ|D F#,V#7_C? 9:){#- #Wc27Bj/_~:+EF |ucX҂`]|GR_ gMT6R! ,o!yf"a`~[9 K䉋r7b3uKQaq; {Q,怰#zo BV"Gwi#:PiNNBX7/M*GuF2XlLGH'NCXc) #| JrBC;BK#8눠k(C-oGpU,va']8 +ߩf"x !3B'"hFplu7+r`%B&ز}*C/)c G?V2 wS{&Bް8a ЇX!;Y!;9Q: f" .Y#:g!N! b"v>lMD/Fj KDoyb fqU!;@#yf Rk?7!e8@DDuOlqkD܄l`"d/""B#"BxDtFX$D""=dRr Cv)fAkwj "%v,{c!" gy*lj+ dG#|Dά7iA `wq ǫ.+@di J:"}DdpdC#DtIGyg~"B:|x  8g #H"B"F5>2D Ss!"y"&Ce항PxsBkv"{^C{FX+~7mV#l+#l d;K0"ڼE0nBx*mgjc=uDD<!d=f" CTqTqujD"j.v {o> "EcD$Kf )IeH S}0{=FMH8ހx߈ 1] &fbӾ#0]|KHjH:͹%I13n#yr$DKOpic+4)֙tƺeKӱXW}MnaӔty6?yAK6asQl܇w[a?g&bi/l̓`^Eln?[|cg]~ v:s26 =3]Æ0\SS.KºH{uX?" {- mR@JD$}3 5ǿ!n<+b sZ#f O#?4 Zq–㈚䏨ΊȍECD{lGk E d ±JrQ#rC"n#v dj )"*>W8> DETǜAEkɈ Q};Asi # "ugpdސ_dw H8V@dDVEdlDNH@dK];_"r"B䁈hRD>4"j/DM+f#VBJ/D*U"U2fJE}F"r+GG)CLa9,ۈ0EG!b#BO?E5AFD)"9|TFG_ a"!g!8m,9WvGP#V h1[#l|بX7YT;  n&}C3;O~.+ƪ7 ~; v' h;?sR\ꇀXk7/-gm,SyXy& >Cçh|Eb🛍LkFuCұF ~ѷ^҇X7ַDS2㳔0}?" x B,dgy,|疽9au,_Rprfl!, V|'W@ >C2~H/t ;[Xce1aՋXV҆P`w'U؁o#a/Y8 >-R>mx/B P_D/5\cx"x2cm)AEP(lA*} /Y A2g['LʇL@iP~Ag-CAj@N+3Vw5r$vO#A7zg#h i9C-V}Umڞ,u+b9E]ӱ"<B;(VVYSXf"brog]%bɕXڵKwDŽTxӯ4|χՆX4Me X:Rc˖tGMM b,G^KdxWdnpH, 81ϰĂ>X al_nbާ_9i-}`M8渻cNt; 15淙CcApkr1gv2n >Í|X0nݰa̟1 s418L_/0Ok?YbB*f;;0*naV5f>s!557`9_3FK1}Lz34b8L?^skc>LWbǘVӾ.IO Vaƥp=Ӯ셫5LĴ12ڄbjUW[i:f NĔ]py'܋b"r+aLt:eEL 8I9 0nLz^$bJ{LzI1[L2I]aҁ/ܡ3&Iz8k)&O<&9`R`,&x`ʼ$|Ŕve.L>a1)v&k`+}Lr܉)C1ŴS/`bL=4Ӵ0[)k\ֿ&/n}LY~SbI \bzRf<덙a5lb]Zva[Xx=ތh,u<Oo"xh)z_ _šc2ּPFO!v;(`u G{"nKwa&_` Vi߯X|"|7 ~wW'2 Fay<ŪY2|&ϒZU0?LX/VI೼ ]Va|u `=-S_ybo{_ǨX!ݧ7?=I] y?ǟ2,WW>6k x}WB+_x ~g,5+pɵH>>HT6,#䵋r *[0w n<ץcs+bAtc$q12S|5"!}?Я2.݅G[UU~` M܌+՝ұH3Mv/0cGXڳavϷ%cN؇s.Sܾq93ue\b4Zi᪹o>vw-J4_ Snbʰ`}p n\L LaL3SNaJ~&7LSڷ9n˥ &>xϊ?0IO1(݃ˎK)a 21ŔCS1LSKcCk3gƔ X.7|xbb. r1&4cbrL<0& XIR0iH_LJdTL^\3ƙE쿁)m#1E`ZaJF(tR0q&Ť{֘iǸn&~ja+L~NWј04x7. pN gO8+aܱSw(XJupn?cܣƅe'eg9_6Zy)s=y Lz,uZIp w5gwwX2\p?_%`ɯX#K΄e[ `eބ?j3'Ǫ#+Fbl+V?faWXm&yXպ9Xݪ/|OWwyz߄U!6X+> jS|Ǫ9cq;UMi}ܱz=|c;`U~:՛ wl՚X-ߦ^X3-@@5 Ś:X35C|gԼCv.gh#v87V"ȠAf"AQ[W GusC=AȺ=!԰ fc:B#4ѱwD(c܃5BD^LG%xa7 9}#P[ |w8" !tExkˏ!k2cW"D|d.Bc(dcWCjȸfY΂w d4d7Cx,#p6"zH7 *w6"nDĽ8&1]Ő_1@C7>\|d%9B^9 ۦ2k_C2ې!CD\QAijx ^"e|aEnp%D;z.@4ID DOGL@Tu@{q j?Pk"/$l H8 ڣt l$2" N Hr%B)HAJg<^)HDHN\qHv| Hnǖ y$C5#%5")a$CJcMHy*ڏ1@Ɓ~"U31_RZ!%1R<"w']G7$2GR^$]a[NArlARE$}7E-*>I!ݐTI%SWT#CIjxg#III. )|-<$Dj>ËXɅHxy Av ܑp,!Q[M$H;|"_$8uCHp9G\ nb6[IzWNFKb"cĄOB`NE黈U|ؙR~LA߈q[wG|;~x.ڃ6JBmx{; ^%=11n\P{#7 - n?[SAHxsϛg*dHnv#HVx|~ QvIf|_㌤c !!S"~:! _*qKk1.6܊91eN9xaئ}#7s *(W?q-񶿗6̻ n5|o\ +x aç`+Xb0=Hļ{M| p^UpK`jp;xW=7/a3抩w*ǼW915;bb,ȭBofpKG` ,{ĢpyKZ`X0$8R2Ē6Gy&_ꆅ/zc{XP> `ќX_Ϸ=γXK7m({[B*AబO])V/C>H[jBݱ@-mcH+!1C%9\` 7m>Րֽ2Y!42:JCz3^PF|zJtQEs`m}*X '?.t:Z=u2CB *sBjKjP Tm@խJE>hJPmDzsmܪ coA|t1VO d,ӄ|< nC~qi]P8fBU'Az(5CqVAM;(Ba7(BYv#ݡ6a1T^A9S*A6D[o(DE[/PܼJP< ~h bw({ P- 0BSsށ[uw.1LC/W(tfNIP/BI TFB(fAEk0Z> (A{PJ}_BҋPjv Pڹm9([B!*gvaV~C/9-7/gmB']v6#BʒitA VR8N[ѺmATN)(@‡W*ҁkiY77@F=אeY#^IN;~vY"3񜻊!tǠ".GJt{WF sHEΐ.}&Q~SPi>*RsSN)ݖuZn(5+U/*\wMvtTÍ{7-. ,mAޡA5F 8*lrP#xuؤ7'!#CDOU{}۲޿-Hٻ>e)xC٧W>(y̤O˾}"ʾy/veM>Wo>XiM٧3ټeJf:7/;n]٩GJ4ʶ-W(=t׾R]F{uvwH PS/5~R:}4pgilOG=+-.rycMq2qϮ~:;ޛ}EojQ{i>u0iB!Re}i͘򜢷ѺJ'z)Б6g43NOWѝ nTgN^vuCϸhmmbv2B TBo$4̀Vdh{&:@@\) \CϯW2LCwt GHuX,zrZ<,'ªj^;¦l{G(?lw~:$*֎؞4D'8E 0ކ}~ M&s0IL^E1cz*fuz*Ap4X<<`QHG +qzݑXSNaڻt Ao ;ߚ!c "lE)»]D]&#R2EeL]7j!"pwõf#E=R!u1uniX^ o0ȞA1FߣUSgDx#bd>!;yxbk՗w@r$Z"#$po/BAq[ q''!6V ;#1[%Y\ :s :pm v#Y$]H>r H4HHԁw"=˰r_֏@Wbc/|u(6tdžN8Xކ#z66n> GZaDlFH2-tI-6&n|k+zaӠbl:s`Ӹ4w6/dž3l|l WcX7}Ҧea/C ?buAt5"}##dս};l/! 6B 2矐M;2² ;8;N!wGD@prkaٗvFDR7bDx"<ǼB·AT&CD^9ij]! 7!,%)FX"ͲziB8 )!7!h`BaُoXa.#p?BGq%,l=T ̟xB~=§#̯! !Z%nZq!s8A2 }~DD"b31)<Q=!zl&X6v/ vV8 7D26z0ZH/TY4-æñ)p+|\19PІch ֯_`]~3鉴Hx~+ >RJ=tVC8/Hq I9Ȑ<=)צ"N u4=r5IaݭX/uA?#]!Wbc ]~{26rYMؘ>!6G}Qwt@ȝ8Q;},Er=MJElw~Z"AmkPߙY<q_%ن=ނxf!8 #wie?De5c2ьb|9.aB]׀ igEȒ}H Axl{_`NXSu7Xj"q'B7A ;ww0(ahDi@OBB7"Oޭ9mb_GXfr{CZv8!X>M7ճroT:| AuR ԱGȐa^#vlBh*nPaqN8u*Hݨ&oiq/-)}qRwwPwx9={'$d23ygADL _ ?;:=EȐc٦ࢧ\ p(I]'>¡Gb8W.2Z' u~s߰ K݃4ݠ ;}Vazx5R؅n5*F`MueO`N:v 6a-kd3a{kfX+MsXYfrrKXfrh +5az,-a1,al/̻kB 'X(R=kFe;X 0;10;g`rf0'0vEbge!5T`|sKaS45`ƚ #at V孬1X=ͨ &zl `3_ Z =>M 2/ ,`Ǘa{F5nuoAA'G8[¥w-! ,[x\ nsICfcUD~ B?ACDOBZI#2d ATQ"_Di!'"wBDDD{.Cw7ICL;7* _"lZ:B#lM;P :C-0sC?$y B'E|=v#$.Bz(Bo BVF"x,DE>I";u@Axm'tZ%_7#0= w#^ Tv=FUgBZuC#'#p_z շ1'7Cm%큗L{k2zY~\@V/#;ª{#bID82/~FĝCf-tC"ddFЋ 0!g(KAAsed)C< j-@@A$[! Db֟l]ZtsG{1Y#d UBXEo܄QFĵ?H:DCD^xګٹ?yq!o؄/ iÞ"t=,f!5N ">_;20!Z }˞#~6+ej&"+jY )e%õ*ߑ3ŃH-4I}Z+غ#3_#+>Ykϑj$rLˑ{EȟS4oĦElz  XL P0PpIQ> s?`-LtF7* ꆢ`?뛤T) TE,"lzC|d| P0"c E5SCZ<`6ۍg`sz6/cc lf>Y2YL #N(6}Ħ)6%~¦ïieȟ|c_O|#F3$樓|{ydr 'r:r!dBֺ[d8.C|zH4?9nx7TbR$)Fb3{Bذ·F&;n ֞*֤xl`s`[ lV6> .aUa ,?C`0u_QɰfMX5ՎpX%ʤVs%Vax9Sa]XOBj [m.UA [u;ؔͼ'zo%M`ݰٹބ5Xsu14F돵O,m}vؽ<|Y5*mgcX(}]X 0g\ f>l~~_02I=L?Llq.HFX>ÍZ"V*j< î4ŠBXQ+XtˇcٳXS {妎Xx</|-,'?,`VbE]Va屇0| gcUhVވ՛oau1*."0ZFe0!`;L\!´e*O|_b-,BOX&·"$ `\kϰN<kװzVkB`s,a9`1WaVe ӿ7`cӽap2b_agU ^_ٷ$^y›aX7UT z R >?HvrW9'Cw{7+ï~3ljI{x?Bx̹1 /R_[4Y,ⱆM{SAi+O1efa5>j1 pRFq "3l:l>+{!"d"B~=x#| ,l.d1cvv »@ؖLQ6ޯXMv@zwn- { ,1+>3""A"˟cODͼ(=)"[N#}"#0Hݾ!* ?F/hI3e"Z- э#W1⭈靈' `~7b. vJ)bS!n1[:j8JeB \HRit?H M49#YH_xߴ9f#\DqˑX= {XiĽ:HĺH|.E\DHQH<IڵH3I34/!'G#i$E$V!<ėOb6s-‘XrGHH23$=:ϑI'ƿIG41HpIHR[{4lD)HvwW!Q/$>CM6l;*D-&*$!YdR 6)EZFuD,{#C;"Id|Dad"Cd~zPl sFv|dCNȱEW-r!wH$r"i!r 3O en0fAr\u\ IE&Q܌Ȏn}$YUuYWK}(b;UZ#eYQ{gڳYԐ{9CV-idf Gƿ[Ȉہ?g 5zxC2A껉HpC@W!qҗBHoXGLof!c{2J~#c  YuSTܽed6w"ӧuKLVdb 2vcmo d 2 F"sEd0L惌dd B'"97} rK"wr qr +";LW{9N"w E9,xd"3\Y-ꈬlLy!c Cڮt&!%! " X[nkr ]<9~s6  !</L)A;72\S"EBw>+«&;Q V8iGéO8< ̕p(`K Ep!p^NNpL]B}8=ІG+855" !\ m ~-~*F[ 6~cqp*;oZSϤ8 p~hc Czڞφ[y/_[y G+x:=RxW{<8zlߥ~ZhOY5 I [L|ֶSXafHĆďp^o0?6J8xZxC`1o %wҺKD; 61a{@wC/Ecp.Z h}8 ͧIO[\6>}Fw z>^&zuB2hԅ`-146@@}\ ~ѯ!1+~f, m.֠Z ZˡY }.:I=s(:GCh1Tt301:[106 4t::7B=:3:G#aЩU&aӡ %Us}Nh >6 >Y /ҝ Z1qb:lN A0 Za3iP \h#}s0pehJY[@iU H¼mezktԅXq+W`j׆U1,MaB0$'<["`5 `>llNeXm3ӟAݰ>;׾%獅#.c5p8cXw .ړ`w} u^C`]i&-5ƚa@ ַ2m00ҤX,A};vWz\ ސ'@vNnji0r!8ck9vSY8E{& `b_ø5r"V`Cގ!;1αc+0:FN1"bBw1>O1N+tGAW+ ;ҡ4cΗAFCw{*ˆݡ;6%B[ č\='2wVMD ݎMC+.zZo΢[ߙ+ۦ^PK!YPzj7`(@pd8ʣ* YJYPX v+(?K~C|m%ԟ\C7[}3P?h[6T0`#9l I\? p6t p^6 'w T. Nq=}z=/c|S" B/Pur?N@~=(?TR&BX<Ba!(~ΚP <7J g (AcܶC==&p9>%L c߾B ;2y"TzC-"TS ^#QP:"P*>Ag,n݁ (+BqgeOC!CSq'mx_jAoW J/dӳ-d/zHn懫'hf 'S\}Qǯ躃|y*鰾[i_ųTez*m&ytl69@6}1!t$.dmK]/0^S)IKRr^~BcIisKO>knWڼҟ>ZmYLCEeW۽vӺ8'knǜkoi|pyBYg7j[ҫCz7unlwGl.ⓏH.N;THLqӋwB/n[[]=]wޙ5zE?;GvN݄z5wy^}6x֏KbxNe2/=gJWK(]$YrdՆ$†K⇸J6͓s)^)+%ʂgdhg@'_&q$W9w"د;[iASEv]OGg-S}ER#f hK}|3hA4 Z`:*oSaŴHw|Ǒn4$D?N5/kCiC 2x3TkB ֞@wMGtK3Y=F_? 5V^1zoD_A;,FJ?8Z~  KEͰ%11/10?5b=9`Z40=b2CC[0l3 A!嘰>S`R7H4L0n,òozV$L" `;k:(~S Sߡp^.&Zn}-<jwOW>cN PUA4!#La71%"^Fd.D!|ؿ nH p8* iW#iHBH Ț \X\W^w_f!dhFg9 A'3LȎRdy@$eAH D6VLBʳHiۃTH9݈g3t #~HӧC* 4g*e@|[[BA#q x:$~xQ>Qlbw"r!fļ*ϵ |ҧW HGHr%Hي-H1@Uk!ŧJiHX;!y< HD"a>ƪ qL>\gw7H ߂T9H ٙDSHk)vo]Yϐ-ߖ!s>2_gqu2'x4Y=Yc}yFl]G do~菜ȶ{ˑd*rN'!{Z,\y͟S܁e?G;=9IWC $:00F?Ҳ$H܃H +RK%lnuk5A|4}A1=H0 q9ӆ]qv͈(B4Io^4 1V"fPOX{! }]0CD&FlzDX-31R8͈i[D>@9'DIBdDNC? o9ՈEp0G= ㅐw&Dc(=9"# 2p( DY""QVAd׮i?p6!m#$zl^"zD݈(UD{hQ7D1OID."v?bsZ w">.GogӐOE|ޖ#q{$> `H IsB@|߆TmazG#V} lB҃$GRQjI}RZk$oKA|\Z AQ GnDSU$@I"^c9q_B ;,ҿň_i&=nm 7`NC> Ր^9݈cc>!~)KC@`#k{o +GH!^-_oċ?˫ѓ?m-#~>HoY@Zwr^$OL>!_w=DFt C!:(qD8w]=<rC*sDw 뗁8) n^؎[V}lvDe)!;,ԯ#1[~!Z Vg"ff=#F3b=DI^ʌ6Bčxxd6l=bM1Fli+\DܹJװ}Ziħ=h # a+#D$>$$~lGl$#YpA>C7HҀzLQCg9R}HGjL;[d<ҺOCڣ H/`d }2K9]~;"*25=aDuPY#CsUBE kdmXRvNnC΃ ]1z2ߙHbkNH IttɦlRs9"*C Ud`Su6[x9au$ c~;/z( k@\  ~7b!&1*|RMD !&b$ ^k[bl? Jbc]f'ri B"~e#bDL2G=z ҽ#|T&2a+#i"c/#R"kd3/ !iqFXV#>R:My`'0=*B!B0"sY5 DTk8g wGx^/u4g^|LoQ1|&? x|zq"$f |>ϾLVD\6&#t|@p~9= aoF!?|@,qz b^&C-̇31G"D]hce{{#ڼ Q!rGg#="|1Э: A! n: > }Mz}Тx Vj0v!As(9XeyXK<} a~eaGouXJ 3{'ô[ Lk<`=&0y KaLgoI/ Ka<``2OeØ W܃w}wx>^7 ľ/ks Jkxgi' ^sexefSOBxЇl~t94}u+.̏ qz\aQlט>p<{y` S7>m}R (!Aj =A><xe7}|W(|ϮnI +OCk{n~TxKL%OV^G6['Fc"ȮErgmt9'3Lj=7gI.rfB<_9k"g lzW<\N|zb}ڐ]Ӂ췽\}9a:"[3ŃLrG%ȼo m|"8CǑ2 "Ց )ґIed$Hp B:9 ~ 3}uѦ]hY JͰk " R+!|l72_0A#wOo~ ȷ5| xoScXnip}z.y9ai(ULZg'5k5w`Z6zC;;_O3 '`k>,E.,އpX "k/,f<;?,``>E&Ys% `vfaly1Y\-8V0_ay`1C `{5C`QV^;a9Id:)0O} s-Yl~"Y 'CX|o>,߃k:ylL`yvlFn` ;X :M_a~CfM0u-ISL4'F<`v0lKѠ0\FcKv^U.0!2,Vθ7'`i?, oc(KROXc<~iXjuK/I,޷cuDc Q߰%s`qD,fg-XeioXgcWX>!\ŠHTFXyOal sXec `ueLYaTFoP#L<zia)Xl4yeKL6\7(2?'avlb z0~0:O70 `᧩0*40 ~ `< 8a>0 aҾ=aJa70}LY3+0}1W0`{^5{z7|`4z! ;az=;:杀F9VohjCXUkUg`ڋX5i * QD' Japxi0:S 08t`n00 }a3U|+K@20͇ e8#0}KXXmY7d0R@g wgqqss_Y-â 7~W/_~ogK8güYfD`T&.XD<!#<!5/BOD>B‡"ܮ >:#fuHcq}cD^@ĹoH;;;%'BԎD+"z'j2D[COs#zs=cu!hDtw~IF%ļ>.(!q$(@ӝHBҪB$݉C҇T$6!eq RBuVg'R!:eHX[&H;$H7MbSt12$09 Y̲Y2JȚQ,C[I"k9d-RFff82Afv#2NDrd郌VȌg呹?L!d0,̾XV,Ȳ *Y' {z_dO@,d+A?dXY|Y瑩xqYy{q dFAfI͞ADd41U(ۏjdĔ u2dc^ 92[#cK 2 YϬ>ddE{d(AbNFp'Eiiw?iWWtsHH)DZP-H[5ivH[iط/#͖"zRFH]y)HA Rdʐ Iې}-#!$)GB9?I7 +NCr[7$7 M&W!y-Rr eSԾ Z4rHaTH)D$.܍Դ|gũTFg!%)iR!S4R53=\tYIRM#-sDӑnۗ~)3V m® Q셄}ҊqbxDx귈t Q#rT6"!bhM*c)B Tw2C"@# `NSy4'g]|9;>Sqb/y/죣n9aUam>VšNK7030kȹ&:b9jĈ0$%~ dh@sNw^@W^=U>O>A^OWx=ׂ 0=g=zW 0&z?G6} !5lCwekFUwS)磟 E﨏qМezMhRh кZЌ hfhmf 4oA[;v ^Q۠g#.AchŚAs)h2ߢYP .huMoWJ0K?<o-pa^ %o#4*b@yk3G| .frhM K)Jh+lvh/ heMhRε< p==*r ]v8!':` .=d0Dwİ{VOC{`;m]E1yE0 ƽ¸a!&(0T8&14Y7S`uLaFs0Aj^ȝD+Ɨ`Hy׿ckcn~ 00護᫘/_qH掆/*#0{fĬ5$f 7cƶØluڵl~&cWfXa<̚fzNBObU f89 :--żo? ca+7IJQX6ooe?`\ꑹX>GLT&a6u 8b,pʖm@l@7@Osbv ^i-0c+`p}L c*Lb՘9&ש`Q!&>c`kegнѹS1Bc4`b F5BtgĘ1V:7n- م1n0N9TQWad1 s1ځڇbQW41z]s0*h^Z Oƀ–ltbl}=wur-~HOeZZgK7J-1hF-=y,Cy#L6-mihBݸƘݢNiD-r:Sr$:Qa8w.klG)'wȧ!BreWRM2wu׉iɣG?$9CU; ҿd, <#]*_Ed$ %)j%&nmӓ6H27mdNdtdɤ%Sr%[KL&(Ht ,p{dU$J%2 !Q\[+Dg ס ?D /Bu&7ڈ~_UM ~D˚BGwc$;5N">=1Do!zȜIdgHz#=߭$=V"=f"=f!˛H#DރoDԗ#jjډN1DuP(QUN&2"c.|"6 bAJ#, *x<N%*}":>%MD>2%h'Q3";G{QQMTF#*KU|i8_"*KXDer,AT"~b;""y3Do_GO?DUkQ5$nD5d1QݼCD ks{9Q=k Duu:GTjP;Qu-&N=Du֌Z$E:Ql!݉2Q&ՈjD:ױyקD\x"N}OY%cxTƉqD<O=J6y QiP"*7pTqt"޴6KDui{zD0(AT$uDs)Q}OT? vDcFOɼL֑߈x ۣˣ+JTL^JDZDS.Q "q$Dt&հDdIDn#3?a'BuDN3]pQ; % D4v!MODơD4͊_~!ooHD>7#*C"lGD6D4:ϋ\#~ݫS"ʪ"Dw"p^$/DEsb0>d"1~%BDط!6_"֛5N4"AW"%Dd$݈.|IFD%A J=Z@]vZI&GӓD ÉNJ= G"A(ϫ:G4ADK"DuޟI~߸zu/^|Ӎcf*D?Dxw<~h~r{jX"4?DXi~  G O?Dp8lzJ=` 4,ɢD"&ix&:"XMrDN~/xA[]b^ѵD`=T7\㟈 *$G>_^DuQ "]/'o`~OhkMωft6wrq0Q>z(gff,Q~C"2f;+i,?h"ZWMDkgx ?. |^0[-a"d\e"< D5R#C̍pQ^}5x٭NZ2t̷Ax˵@D _ioiD%3"QI rl$l߷|i+"Bsylah}Wjgyvw&/m!cK ]ekN{G""%#UD|>w+QZz}n*D+~DJ.07)<&FTdaNk8}](#ʳDܗ(5 Jҭ3DL Qڹ((<(;e-Qx(^9I4}D 9G*Dz"w'"GB{SD*ȣȹ r㼉ОDn"@m}["WZG6iD^i׳Qw"ș$r.DnE"{"6F3k'2OD MdN!2Gюt̝(i//i,iCҶx|5=翓KZ-KZgIZY>}_XjPC[.iuHZwHZݐlfHZg|*"i]&<sI\}_I뉹6?OٜIچJZh)>ȗHں1>~JZu#i֘5?=%R$%k%.3$WvڒV]_AjίmKFҚ(iݽDҺ9+cTJZ/uWJZ1J;I,%mA[$m{%m3$ђՒ߃%nJM%{IDI)H:L$"mIzCA1؜ۑ#T91rNyWs%sH:MJ:_K:ÏK:̐t^{Odd;L4" v%2s̔"3")Df,"c8('"ڛ̩D4\"2oF">l$9";Nu"cw "ҜZo~u#>lH%M6 9Dv[ =4 V"4>@d0>_C "'Jm#r} c62ȑ-]9#t\ˋ!r.]f;O'r#'O}vyOD~ "?ZȏNGwٵD~q}dε#~6̕\ɺD~j aI '"&;%|"'&@G"7f>QDa`0uioP0." VSO(H&]KBN>%/BQp(4)Dc0QhEDQ}*Q(>H'"Dq:(.(fU(n${bj;QlL!b[Q53ȣDiQ(#JViDu Q r J^DiWQ:O<Twe٥]U(>rQnBA?t'ʿ+X7i'4g\5\cVpsMc\.Ǧ,&|c .V0mZ† <6`0?|?!Og؉o;<~b>.~x60g2qc~1񝾜&)gX&;9cse#8pm9n,nL.bH"X)[ÿc>%vEQy(N.<|BϘeCy,<-ǿ$ʫq y_ŕsBUIRמq *OK#:yӇ(Ay?)(ioM\LǷ<&?%y9ٝNv]agj~Lv=F<9s93l+Q}QXs0yM=&ʮ?xSF?hYy}ɇۏٜ?8Qޅc#p:"}q%Ώ2s9bT"tM1p&>\+#V>\W3F^.>G{y#ʪ|\jMTY1)U#*D#Qy7!*_RQig^ϓa|g ߖ2 l63"m!|5/&"?b9=ìDҊMwh\Sqm"q$ND2ΞD|h$gsu8ً'.|y9|ɕ g  ,}㞹\=w'IT~U9+DQ}HTG- 㫉oDuF_#xopq%w{wa9U;1Q\82%ĐNǏe5p%f>ne"IOTX|'.>?eKZxs>|}r}:#So:Osg|9Q+!*绉3+K.sÂPR]yscqG]W6QyqwtQo7ޗq|qV>ynV'*Y yQ7d4q{竕'ѿ]u޻r«DKDoﹻ@i=YHD,>GX\!q."ow~8w/9 {.oֹ;=w1O˜6n&8JǟSy{w.8\΋ˉ)ϻa|w LDTu"u?)-\ǃϽs Yl%D(rZ#|s%?\z.~qY3+9]w(w:3wW_8^Onޣ3@x[ۉ*"|N;{@./yߟpw30كsy.@B=Ncesw,N\\ň_c9ݙp1Op۹Lq"wGn)0WWON(_t?Fw &ʹ~|bG|Q>>޶ cs8긘}J| _3Kywkat=ٹo-I+p=w^|Ηo|Ckx=:*837GD9c>CY.^=sICb+p1e}(^ {]y Cr?,E(eCD))QB<:1Qn!JfG4:Q/(S|4x"cD'2(!CD1?QL]MuD1ԗ(::ŵ3h- &DqQ%G5EշDQ Q0(<@^uyDIQOFDas Q(' YD!:QGB0H"?<2"_W@o9D>ȇ9y>J7"ԃϣ&DO29D${_K{mD$UoDXaD1x匇Ā͝BD1|s{7"ӎȾ!=K>XȞGdٝ݉D6#&)Z"n1U)|t~"g!#2sZ"s7 iD99:FdIDF^<~ 29Yp"څȬ`Dfb"3 SrD)BdDF~)DF󷂤Ig={SUZy:Sҹoss1;I᫬]h>'P IgBI_ҹiߗ̍MdLf"3 ?gn:5q[lP'2N<^~eD&h/3<;HM+\|$"!ȸZ눌iO&+9^- 2KvE""3;@dFliHѩ婟Sɯ#Nz+ٞ+"sJVaOE3I烥pt4ɛR I_^pqq?>K:c%߆+9't$柝Lw s$|xs"[=y(qJ:ߑt^(q\q\[QBQ'.ȿSR#nO%%Q=(2C%ڌr}xŴwVH8Hگ7K˖JڏjsC{|I{A?'=_Ҿ浤y{=b=z=I&{$3G\;I^CҾ1ϗ#p/WǕXV+$OiVOj%|$¥wՒ%mF~E%mWJvIڶ}m*%_E9:E~/;.#fI kSfxZ6}m4;檤m;W=ygYKJb%myqpRO:?7n3$m_K}U5fn '_noOxWE_*ߦG|/5n tL!ЭtH:zwDWn~LsmyH:f0ݜ8>_wkK11S]44x(t,{{4Eq9 f6quղq.겑.[l,6LD;F !nD>ȞşWD"}3gn (lU' WG#;BU(("b60qY!o6ݯRyC]LoidqGkDk֕RETtNWeɮb-u7D5QbF&jMD^1QJ݈ړR}76ϜH R VϾJԳX3&<R~|;QIݏtW{C}"j7KL4-og{% } 79DlH["tn b> |;U.'&*3/v&hce*oQ33uo[_|rq+BT6Whb }QI߂P"zσ:9Dxl4;WBzrM\p_#W%ܽw'ݓpw/ܝ߇o; Fo  ^MDGX>~CNKTDE0;r OJ,5\6;$vYڍv_J; h2dЎG5d4\!sdB&<2w#!+Ae-de@&2!/d#LVH|>2 7j dU kV ه![Y}o' :@&o!82vL̄ǐFl9Xy2 0PMϮɴ}92vFB[fj_[S7藺%j1p}5u}RNߢ[qYzuoCE}yz*ØQOoFO5 1Ws"mIoVһY/=i*5z.W;}W;~owS'W-km%}26LJ+o tMRHG;C=iˉ=Ņ})}@ot@{YR>XA.s/NL.ϭ$}CoSe-}o.}!g?eatD_ڲGz<6}Nү9t},1DZ6L2>[EkzFO1mVӻh:郲+VFk7FG=iԅ64Gi4 Lz6ܠ7Vҫ 7i}vz:=^K21h5j.m)cVB!}\nHߝCZNwUӫ4~<}ysB/ Đ96W>7{2ݶYf H7W̢Xћ;IZOp֖ wOkhC˴]ާlml~&5mSv"eZ2m ٙ9>VХurgپs{{V3Cvr0e}6/EݓiS ^/d+m~>/w>Җs`WzoAzd w2ӆZu!}J-imDzs*CkHA>}`ؗ6к_na9Zَ6K^Lhmbzrzu IY4nҗ'+iFZ羄>s i}Z8LoMDo {ЫQw~Y-}i6:B=NoAkЇQhXzo-7EnmNo=JoJ蝵B1}:>T&i6WCЋ6nf۷MMeлMDz}0{7(_I_tL[Ck;ކx3ۇ6W>=ZwRBF'OaC{DȰm7zj-|MZ^ދN[ROӖ}~;pH936b֎O*IHL :6M?iL[.eЖ$zPo N h }n"mG;魘Lf{hC68kZ/EJ%\ +^gNV #-B>}菲Ys]d6v'K&}~>&>pIhq7z]m6bv4Ie1ڼ6_FoF_;'hSzҙ@_n _[Y.T^yV7;rٰII_y۫1ǿ}+ЛҿE:>6nx~h hiD~Co'M9zؐVMfϠc6gaE,0~wNh轣oNz3^Np{k aEm~Չi8z=~AX)w i[kEG Mu}s'g9>D /k"釓mi,R~WF["_?@Y_°}~|~r~ʏ׭>KYMtQ>TIZGEk?!5 5K鱕ɍ(~7֝IkEi:?KoMi+B2Ѧ'qmP`ztϔ6Sdimևfu5OMҦRlG\:mHN\'shҟ6ɽhCr7Zlm6v?+i}y?6NcLFTZWI냙Ob`r{iW+6?<֪d|Uh孴a"62=l}mh ~q ц9t5>6MmL*i]j E_ ; RMhho1hCβ &&vҦnwڼ6ЦaIULSƄ%L>-֖llWi#moMT?a:Q';wM1-m(hϴr"mLOMӦCІlL 9iӠmMβy-;#^Eđ6 wh"SD[\<0fx 4rvm*5|C[֝ͻaضc,}8}cH}C[lB飚C6m^x_M5,-.9ōMS6wisrڼem!imZۍ= ?mOMִqU)me{DJbNf3r6ӵvk2ѐ6/I[̠+m}j ϩVʘM*/ic ڴ#6t0;hvƿ;iYSZ6|Nӆ̾NMz5OOj7Lo"~^Ia/̾=sؘQًn(Gci՗.2ъ6Cq4cfSƖ|6GWi+/^3 ڨty4mgllR6l?"dRi(xI(ӗh/mv0WY-qmWţh#&3K)<6ȳSۘak9Lw8wfĴEٚ2^PqTiw滚.`GgmD14҆_iO0<9~F;u6KIپ@dMJ Aĕ ^dv;Bai)̷ 70ŏ[a[؇ACh:ZZܛg1|?>wa߆҆@eЇbZnU:v )Wi cUl]ng3;՜69ؘ ҆.Ц.nӺ q w\Kb/YOk0<nEv:i4'hÂbZwS@az&L9n{H{{16^;Ls51b wp;z0-W1wݯzVҋ {@o?#b/zGw75)sazsYz"c q;WM/?AiK_+iʰW=z)%2:^H/M4腕nGk huLkoa|E4>!Cm,0,uVCgt)hGzUzqZV75ߒhCjlzz;@ZjZ7ӡiY-znZLպ#hQ"VЪQkiYe66CaZvVyAUKЪ;iQsZA ChJZWIχӪj/L+'#hEZYVzҊm5rniy&XL+D[p6YZw,zFliOUZ{*}MkZƜNB[hUVg}]D !rZ-VV/h[Z5k;=[zM L"ZLf7|!Zd$չCɋXlҪWiu_& <&{]Zc/Kk5vٲ;ZO/$MڴZMShzw(r^D/L5ʟhͭ%1~^IkiM:Zcާ-hZsza+3 zӱMfZ}ϛoOezSEL5>Ln3܋HZ=SH=F|zZS.5#/5]zg==܏VD+ǰ=gO+6:L%ci`ZV hE6Z~4wOZB+8 pZٜVTӊFSZգVU( ַxZh8NK;iq}k}(N+`kZ!׍ M6EF56m@KַҙʴTDiZZ>auϴ>-f}i:Zb-#C/}ųi`ZCKγhRZɎ|LKO/%h1ZܢUi-},.%:hT;-IK{ԯim -;LwbԛLNKTi|Z}O% iɾ -֦Ŵp-97g|EEpJZtb -~RE}%Z#D\%lhr-KXVzN=bFz"ͥ-lBoEOi9ZO &Z42(Us3Wpe=É@FRZx{UF5Nh3-A\Eg1qܹZ(fcdnthe:-Ա[qhQ4ZlOhɗ̳zgZhmDҳha%Wwzn4>>rzBzeZ4Ţ]-VGKd=i-Z1EiiN-lͦg&sBzn9=m=8 @ 7/1ihԃѫhy+ZtpxI+ᴼ*BA+3_vh -L7PDGeoh+>Y4Z>wh;/ZaޣiyZKhw*-2-`Y,KK`2SewҊi-HKM%riqoKidZLKM?hinZ濊zc6i--D /Ҳ Ѵȉ^|X!O%ٞ`5v\MKa%-}ǰqV--I'&2ye&}M&d8CK1[WekeZ0-{ŮiYsZ~Eв鵴~#9G%lŴd{j>Koru hեRÆVhY븪u [B[ 7 I`({?Ύs>{}>c;ΉZ뻭&z<=jd`x4ee׫>B} .xo[xOnwl܇OHo㝬Ox7{1=/ui>Ox5k d^$Ziwx n~{|˞T)S1^yxx%kzvJy*uA+w`FY^Z|>㭞τT+Ǧo<JM]Um=;1^=}"'|>|G>۲ރ\>xo??:]G> S5s >26}l}c|+7^{wu>9|nY7|\_#;|g2e Jz:]"u'0Sޗ< f;._gIYۥ>_m|1 :x{߹=ԕW_R)W|/6?7i_˩l?:~oo*| J߀6َo /fK6rWH|H/wo=n_Ŀ5o~~ k.s W͑0嚮L|oz^6NoomQXoelʘ z#g.[6gU3#-,m$i%7Oi|W ~;]ߎ.M26<R~w|T ,O%~drI9Axou~3]UxfIos~Bs@U-lu| s3'pKɸ8hxM;q :d=ANeTՔ=S_QxN8xyAJޑ5q6#]N}TS-IWm]<{{p(k sC.f%7qyӭiBw],w쒬oMp.֨<GpTr<-ʩ8W.{dgVA缉zvupX&r8q>-ƚb0r-}K9/[*KG:׀I ;TOJ~Ƹ㮿w8T2QE=EL^kT?ud\jBy9{J9;}mA78`3E.^mF{ !U9v8%N !/I]LNWM A!+zn#anuAHs"1BG|\~AD})'?O]7PʽG*JJ;]M䙎'n2_7\/=+Q%qVƤ=Ḍ?QG}uI2޺Lib>w;L~,yQ%, ׽lE;t0i=)<ӏܘ)$\̟v]NVJdLhlK?W۬ێB_k%]I^iޘ突z@rPRrJWJ}qdy@rڝ3$њC>=ph~?@嫤 Chʧq:)XQ<5)ˇ|,/ߴu|86';Ha#SZ< jN>$Hhr/5%}% F|u:/8R)Nz+OM rN#WHؓ4 w_ȯu|dM1%FčE7!e)m,:DA bŇ֫`s [>\ _/'d+RJ1s 5rV?ʧPO#mO,z&j9d5%crT~=7z񳟓Y.͹dC-|[CGGΈ|(Ն,m^@R NH=ޏOFsMBfl2v5G=Grr-ЗO93GPt?UM}K(ZMl]JOֻ|4F_:'iC=d׌KOf$6Ǔ_o.YU<0N4E"mջHJŕo9Ř OvP6'a2ԏC5|Z$5Kb 2kW-t$ oP+6#kGz|RK)wxP).d'> 9{}P)Zۚ\oE۽9~7^ƏZ|>}O;J<Ȳ@*|yBIӽ?|>_-)OVZrPoh0 ^OjNwRn~QBiuJj{N=gu4(}BOJ7yn׫(G[ԭ1E=WJy VkJ 3FrEh7<ɷ3[(sҗF9TWy\J}JʹJؕJ:˕k+{)^{+-(~,U:̝t\]]mLtEoehwBѻ`vQtWtY*gf)Y+E*wP: htHhxtP*7ɵ6JJJ3J;JrrW~#c^7C2ّJC|O>J%QT[EhxQw8Wis?JыtL>nmZoQ:JU:P v+Q ZTʧA4ŠciTx򈢿|\teɸIRiZѝUtK;虻(zW&)V+Zs*Z:+Z-G*Z݌(V^+Zf(Z*Za-cvXE+khkC:Sg#.v٪]Sg+fIhw326.(LJF׊Jr-7(ڎY\E~E[#ctuDaR&ߚ JGwmNQ)7@GgE{EDE+s`cR~F|R!R.]]XN)_J)__y;U 魔RN^0Fъhl|#CfE',X)ThLU{+:3Rl"c`~ȇD2R.o|hu=)#?Ɠ{e4޿ɸ2a AC$%|Jw^yMҮ[f.K=F[WO vxt>d!Irnyؔ vLΣ =VĄ"b󔔵/k5}A(euM^Kғ@~>H{ȈJ 1f" ᤞ$Pbe/y*cj 5=I5zULЃc!c|m:$FvCR:%jrA,/֍&"&1 #Ӭ^ğ. )I|̼$Nk!wgTC/J"Q$~ZE]$[]/,[k&YUH:A1$Ii-2_cIXD'7"ͥ 3hK~l)&~p}+4%A qٷ"I߉i'i=&"uVC%NZev!3&48zJI&d~3]+ً #<4exm Jt{;y 4Lf4#̉rA~2V-gt+$22.%{hRۈqR\Sk"]WS.D 1/7ѻD>~'zg%I%{&yFDǝ]jEv_]YI%s~8qωݼ؄$\@3`#Ǚċx%H'՟b'|/{5Kp6)GHA$Lܺć!>MImES${"{qĹ5!G$[w/WLҿ#~#U e_П9ĥ̑_oB„精Օ=} MϪ\洎e#mGֶߚL/v1c_MH[gw!V;1=@ekd\Ѭå/HT@7F܋tўMCK^,|k,{fj=e O|LKZRے9czP"WLQ%WM~&o޾!DlhO2u|3BE-qFl jͤ N>܃L [Olx3r9ẠD VEJQ)bĨsUd,Rb|'z?Qx ~Z2Wȳqr.&vԏo:<1dTGf Qʞ9=A7D[ nSI=?-:r9!jP"Jm.*ߜzDDH D{1~4QoP+)Djϕ}[U2_u"ztQ׮HrAdD"$ߎ.O]>9ꋜK $r3/O"jGm"ZКn>!e"g؊pD=xl":77&<7W~.]AX^w&Q"j&aۮ-uD 34=ٯ!l LC}p5Ф^ t>B!`/Bl3S\M Bu3]!$WMPglF`,ܸ8S `~?ڮįy<ŭjg|9eOqx\kM=W<. 8G~b b /?Ք v#hsTEGܞ8 oT'#5Cd_!ܧ^cs7n*G4Tp+Ee!aNDѩ3Ze-Q^F$yC,!6Ge8 .6"و*QMΤn^?p2my.,p偂\?.ojT*\ q5]Knsnĥ&\z*~Ron5pYNpm0נ\R6?h/]O1g 簿 Iı]aP{ KqXǒ&a7[a1}Ұo2_-NGuOK8ތ}&b2:q*8 R:bpsU9/]%k$*pxCcb?E;bNbS_n'l?N =͔E/) f.ЖasM9U6cS 0HvZñ{]Hn+c}2b۝S| u g\b{m|"vEq^I۰Rtg%c a~8<Z8Gqϸ(V8uG.sb0iLa'\ɼ<ךGp['9;/D\58',pm gI/1.[kN cp}4j'qyy+5pn-&P(珺lƥsYgqY"DRGu6Ξ/pv\+.iR/t~7S`0N?)W /ay8 ,odGGX+dnXCo7|e>t9㘿FM8`?5 2~<+qcy8nzo87[S]sBM?)0|N˽w8w{.v ?wkQN}fY.}KYԬ·?uځon*{*A|NΩߔ+$N;>-׾1ti>1x[b+iנ6>uw˻]Y֩xW{x|Nx{wt|}۴ī稔5>GHm{7-x oNO_]Ox`?zε;.>D o.t7Oʹ SGM? %U*X|uQIێvzBҰgDZ]ǷXdzKJUY|/c+8u>ڗ8Ae<~ZKl|oX\)~ZG~&W3|헼7~kEi8cG!=~usއ_vh]6:\M4Wu8~ߦ߳~ C5 o?{"|^!Ol|b-/ ~'IbMVK.sbOc[&@w7<v'`|w?3ߗKhuPK@\?x'?z<ߩ(VpCS$=w2}.;RorCSg'`m`?zۍn )yo?_BVxIO}?TI h?fWI#}<f% lsԩ6RL2|k lϜG }9Ǚu py<4!m:$ mtrRnWԐfw3<~V_p3_>_`|= ߠuG5gpħuy|75m5Rq+x/xv;D[eq];Ϲ sPqC>g}DA19K$ҎL"zr 9yy.7|f>NW#{r>˗K8U}Y/˚,︼xKyٯ:k|d/g78m;j.okɞ,.[֦ٛ,3"Ãs8k[_(i閬qU 8m}õ2p:+Z 8 &硸>[a%\: e.Hxz;U#9kp/+PU}K%܋W9--63%.S6sO{p"Dw@4$}!c οLЉ-KC9'( A0]3Lik$CB$tf֟ Dw!&d|1-yE[7CS !Y ?BP磭HHJBPLTB#E{a JأJ{^. DU^тйAР4Bel=Fhy,!U.!kE/oBV [ğom=8H\j"65~y15$ +>4^wv Z!d)[x 3'lC?z K#,'5DX|"jBJ6%3o7!ܲGD MDE~#$c݆cEX%k"d^2.ۉ0(=Q= C*"$}aD5 "l&PsBG{?'<= ,q[1t+6DZ~ǏU S[Y i!lK* >ND$K*w!%g 1/DYtZҜ+受XCN+C &WND>>HxZ:SKK= 2"$'S)2~m_A"U%~U"00~Jm ;ҚCՄ+_J!B paWy-''\a4poq"|Qy"1u2: [p=oLX]}žJM:"|5#L_3M{`;JEDLoO}i3R" hz ߯U_=lPLU p8EzP|{1_䣔]*rHiDHx;+o~ɼNɾ|ы!c>_^R5|؏_w+ڃ,d[K~2ҢG޵uBڟY|e7FHaJ,9(}OMd'o~5U&Ϫ/﹔(XNC*㲕ݟ)U7R*!3&_)KIB2 d l3ЋnwwՊVz vP-J(UJV+ xa_R؜HSm'wB^lYCj2ɑ=l;|4EM&Õoy yU[oђfCn?!gEc K|\d|92˻.NM&s^;I6O$R!%~EѬ:Jƥh@-@>WPњEadK&|fI9Zx9ͤASd+ uwz+ڢo:aWIw }d{9Ԫ%zJr "ҔگJ_Õm+UWTjԨL_>TSuBcTTשT]RrR5RCGJ'Z+&](Zg mWdO>Tʇ)NLd ـnR3ܭQwǣ*‡_;?HWk~K!mI/BIṅdL@&ݵ֐2)IFOD݌':FjqgԱIӛn2]HՐ"窴dKz)V'ˆкu :.ꏽ;:f>Fx;q#oH1!e^8v}I\{XYx8yIPdD ǑBE9#wH4J$آ{n|YzM0?-xY~Wp֗n@JfK>ܽN|rPȜMl6\&x&q/=KCޯd&He4?Y{Kһ~-)g)e>~| 5q`/#~$-!NM4)Otq_m V5&.>5;B~|&yքK̫Ə-^Onxmr]%S6%2{Ud"cZ~uu$ 7ʚ7E:__aUw?;sYpSO)qol:ayoSzK~)Q瑨/KPi)+4Wʟ z~z\#'$9>5̅"r~:kzYi6XiT4?$m@)w͍)zP 2*GQ[RnUiNsJyJcFz++RoPG+-)mܞ*'W:P:~ W: R\ݠC^^m6^MTƏRt+t\D3]izEi?>^9cJΕN>+W__ht7BRX~;nR`w͙iJ-FϚ)(k*-_*uj(z% Ew6Ewx)?bP'G1C\bm(J_}EH"H[S\bb{_gHkESgtV}WTF)z/bD੢iۢD$U4i'l+z/o-jRG~[OivGy"jx%jϮ/,SzsLEDQDuESj$QWQ+RTXITQT6<,*-똉uE`QmկoT mUՏT?\U'ņ>;Uy5P٬sNZQ=Y[h ګX*BՏ(?QI--jYھcEUkDE¶TXY4-/Z7V+EwJhOW4rP4U}:?Eh򲓨7偨Kx|LT-g.t6ƈ+zވ&'D әe*wh:(--{Yz{NNϞ>DEO+<@3IQ.'u)}-ފ>[>u3OTQ]t%J|] uDMDB7P tk ݇{EG\kDHt|Hz `ѳmg(c:ѣK)\$z,'} zW\.݌Dn)BM)uh_xKT]-^V7 {{ EoDޢ΢]QhC-2 DזDWN{ͭ6Ct€ ӛXA=tujZ[Ѫ Ѧh?AT4- Ee@bHp1죿^T|E d({EwUSS@-=" Y/T(&iw _qĘob_b5bbFbatJ;O,/7G,0@, # ߋy7S#Cݥm.Y3ѪWzs2nvQ;2tlRt-&*&dۋLJbAb01 X ]\IwjzM EʢݘB8L0W Z }=M 3/O{27Wn٢̿CG-Õפ͢[_TEL{V,/վ.Vu#VF;MIX20*8&w<$VL(5K75K CzbYb֕bxEZ~`++GӅIRal0-[ ¸eXA^9BݾH[UAI8Sx\$VD+ #bkCax䡘5඘SWL7AMݿ  RĴzbnbbap/a龘S#Fn}[Nj[#ۧ *ZTeJiGެF2**.w*>JsXs&jWz~.%۵5DmvJPQ.zMշfׄVo+].WN#pPpQe=QuL[QcJ*-C78qW[*Iza󱊪/TEV#x]!Zk7US*}guUʠǨ /+*q5饨=^iBZ]T>S]CtI-g KUy3TT1Ua[ 6nSŷQ%)Tkچ)nm9Ѿ[oID]nFYDOm"G_DG%/o0wNm'bJ9ȧXNX^]"l)V X+Vn+c}Ų ĂCb&bfbFbIs1OA.\!.<*fGT W[޺߈yG ^eO&Unbe^bU0)>* 8O~7az0e(Ekb#Vba8^O(Cnba#YB]pF}a*sN=asS,$V#z&֮.wEH^:'G0S,L*=߸0^J3t{& ctvymfX%sׄID^kXu#_*>&}0=#F5az}dRR9"V'tF*'flaaX^'Vo.5$!&rk aX~{X"CM+\ ýPX\XPpBmn' yĂBbaG1GmX|kXL9Z[l65Pqg/ X v}uĂ.bN5/1{8 X,$ uZEݎQybr1M?&YOWOCkBB_&dW'{?*}'=G{YGlS2}Kgɟur./JD9و>sNJ9br/_ѿCnJ4^m&;/Zã+~m jbbC~ "90Q~R_.&:/1Ek9 ө2o _qTiZTKϋv:eJ-JQ^59a1Z 1#X7X^']LRYTB)Vbj2u}pGW+9 xby[_w|>({8gWlG_Gy{:?b=_wE&LiCZ deX!~v?NJeB, bHyb{ߗU>fu4L{/|xy5a+R|K9}tbEC0LLya%t+Wm aT3cM[u`A bb{uadfSWtxS+ʵ':Ǟ}QB1l!.Sz skTwU]UGGR}* WTvI[VG k[PhIN{ߪs 2U '޷Pͪ쭚{QZjx\f+=JPQCudՅӪS3UP흩Zr#DuܟTs̃U ~vZzʰd6cg{ՅTTOVn?L*ՓOTw^>Q( 1m$/f_/ѡEQEt%G:JUx4k*umU_EEf{8\ŪA8e?۔i9<았T"/fc UuGR>;_0'[t+*?F:cˤuvmm_3iG u!ʜa2۞7t/3Ie1IU,^z.Ϟ#{%ČJbά-2uBļ%bI|Na$ ފ9bšbpgRbbLp1Wy0J?9M V'^)z>=_fA o?>GE&w\ S}e!a7JDǢ]9o&K~oi/&t*s~ KK5JbqX1$Z#f,sӵĜcb:bn7"MϿO?|6Q _QMTKy^>(e-WMmG.?ߛ-^SmXwXe8\n9V6C6J|[ t+| =Ţ5b~A1WuB(1cbbbbzc1qK?1᝗F(JD_PbxBy*ĨqĨsrƜ^(F: ^LĐbP'ˁK&3DG@%V\ŢBx@t|Ct9-o{#j {`RaB)j;\tXEwz+Ͻmkm6׊vZD{MkѢhjMd۷$;+IοGPrj.%39 K!gUer6&g[=rV!rv٭#|ϖkٺM1mAor%gUr#g*o93ߒ_]P'rU!,rjIOK>ߐ]3Α*dN&s3.d[jُ}W>Id#4%ɞ2Qd( mۯ%ck>#%Nd}~@Vw%Y' }Cw[帏,d%an%몴RZ7YZhEx&$k3pY%ry YuUIBI$&3 ^Q~#Iɼsd@dDdnJnd&sz^J_@d*e`AcP-4д胦45Σh2~'{c2>!C6YȘFF2"Ɉ"#:dD4%#!^MFdGHXJF2&ԗT2"7d]##3l&a&rv2ڑo.IFQlGvU4"T[{U)OhjBS:Wshw5Ju2JZM󡂤YDFLk2Tɰ@ƳcdܞG/d@>[2#cH21S?1-'y鶜h5Ȩ}* dG] OQV{N:::u|Q{=׏.6A.gUD}%%Gmy#[Q~x*É;mzNۆS^Nu@8YgK3QOz8ԓ?bz1I`z2}hgC=sPCm$_Y!iE-z.+PDyRI놼o1Kyj{jڻ#%ͤI3PBEc3Z( ȨEF27FF ׿ʞ-=[HlVGo WAF_dT'IO2{}qE:9IƢB2ɣs~m~/ezy2E}]}ע>_ nRGG~>Pz.2mڈtZWKݭzi6f9I/Ô2M> Wڪ2qP݁zQ p%$K e0X w 6@T[{G%e%y%cAAmZo&Sݩ@JE6'wҳƐVxoңJzHg҃ITAF;Gzc=IOHzja=+IO cҋ#B{j{%.SS꼎a]iW$h?_ Kvm^qcifKQЗI;6ӕzL7HSt?v2eùQ/qD۪1 7x! /߹ Eeylgd,iP?x-NXDdwSϤ/xp[x &)C?ws[>e|Sލ 2$.Vqs*;/zo$V҇$G~ uSQUelIi_ߥe\ ̹e)02Ȝ$Ƈ#t92,Wa$s kqY3(5RCY]+dS74md}՗Xl4ƣfH4K{ahfgY:/ Gs v%W0lݬ<+˲]<\vG9`|JYFdٙΎ]Rv/&+sJVC[YZR`e_2~+ڄ24Tz4V,k&0i){IL&M& \YvɷFIc_ ( /,͗vȓ}B4?$Dg1e񗴼%Mi04.rzp^#ٕ乖Ce׺ R&C+Wh[,_K)wow*{pC="AIs-nJ=N~>su2Wl }Ӱϔ$x{yɞL\:2d(w22œq~7ǟq02ֶϑ=26ʘ(tԿ=l-?Y<]Fe`Z,j] 2VBlEId̕LT2&H| r2oL C_rm5ɨ-{^LuYe%kS[oeԢ,Yv6eEcƲWVg,e=.kf)k\0~Ő<_֬{!ݮ>~#I7t㹤Ϗ }L2齷f<՛V;kf5H;>]HMNZ&5#M19zF4#YjR"u|R"u2Rn!mI) &%9)1 I4 9)w/r.ŤCe@JORZiR Ʌ INHIOp7Zg _kIӄwNl’sB!a"N9IhR9BmhJ/*ل63%wBc _kNBWW >V N\A)H١e4pAu*KN$P3p?MEnXɏhj1 O&&}5~r/~wR|s}C·c$>?;!lgL?|>C)nw,;1^񒳍Wp3* ԽG.-? k*쏆cFͱ~{e=Vbz'5gϻi}yk_]yf'yogޔ,Mhy<ʛ]x3ْ7h.WN ^oyҊW_nFpWG^,n Q\Rizbu=#_Ci)חs}6Gz\o gs Y&Xw -|6Kb,Ob{-b\(&rH{,\e,k,>")`,\a[8X[łX0NN,*b^|-ǟlCb>@>Iܽ%^S0XBe̻KX" W˽"$$a>|>#a>R5.i|RO 7LW1gIck0xe|ţAE;m0oJnyE_mBc c[ Dd2KY/f;1 Y*|s1~u<1s?I'B)f~_1 xC;ɻ0YaRFcY9f;Jzј} E~7\ka^U0U:7kly3ߖ昷ywԓ$ubye9&ٯ&惵t3|ؘ2=O;#@<; 0_O'aq`{#̏XKz'ҿcn _w%ߏa|3o1yIC0<4ߧƢU EXnw,¢2,bbtOq1K_Ų:XJ¤1[/`'հ8=KAX\,^z0N E,"c8NX ,~ ;,8eXR}'`9pa5#Wc9Vx=I"r,-rc,c˕O\K6Xnn2Wrq,'cyf&cyq=by'f$ 2u;X-a[±WYB" |cwaR,`KSÂau D)K4,?VНZǸ^5 r֌Fr}|y'w\3!'[Q̿1p)7pcu176ㆥq#0YYAցEǹ7oVu! ~,5VR4Z9['Krr0q[g}a p;'wNt,n;VeݪۯwZs-w]q7w"ިܓ=kyo\}pM_})xPQΫx0]уYUaq<~ێв?'0ٍGWx~+Fy<:ɣgyGٛy\3k<^?d2o8@'<1 OUɜ<2'=O$Ok,N ( x;gU;~9F Q>"9LyO<{糢yՅWǔyq4/Ű^,}Ƌkx/^6)\v'[^Foe^^~yW*2csxI>o^M민Ԃ7;^ބ}0vgy{֕Nx7w7nR0ޥ:;G~6C?}`V3 Vke?}]~`k}}9Eb}6rQӛ 3źؘ5U9Kfb{;bE5݀>-]!vu+}دpT'C d0`SMpXqMppCHԯq8ƱTǎq67x|57(s;i"NKqj-qpepӅ8=݉Nqp2q֭G8/v/MSU gqi,މ˞XzbKT\ gZ/מCqWㆸ<5e ִ2n6k!nFv&n/o̪tN-J5HT[ϣTJ ܃*'Q91bZ#n#%BuSpzq]q_*_'׸C3 ;nxi6 q~ x< <ެxw\)<, b3s1$5h^ j>=!qpuݶqmp2pWp)Vu>#mEh\ܳc.GoA[ YcġUm<bKsPoCDףRZ!ABTwu&*1GM*B'h>*ITϢzxTAeqOՙ6G/6ZmjT/ajSTVZUFIAۻj|+d:n>} nw! 7M8nipK-.; 7+ oܜq3MU-U ܞYy_4nJ\7.fy+Kp|K ۾l곲snPU-ԍ@TIzE6O,3Oy.;3įZ?V7Z{w}~f/T7=X_95?e[aKO_f%wuJ F,#0p| 6p*OKk5TrPI`y-k-$9ZM@. #Ф+!(-|GKomZ@;L4&Pc@] 1A?T,A;!n EMVD\W4"h7Ak_dMV ;&A~t$IHy.w$9,jtA&tǚo=FЋ%* V9&uArݷAWL!(a#A@uG}ҁG'((DH^bV@>o&R+&nGށnO؀D/~NDo]Zg >cF9D]L҇/؊ZD]  'Rb$#13b13}Yѓ79џ b61b01~L'c1SK*sbY{Ϗ2!6fۉfޖ#6qg>sK".*h˽%i8=MhBa?Ep#&-闍Ɠ`P*0KM$C$'h$[<.3ϓ֌}H'Hv,OrPioH* )JIDpCR됲\ERl!VRĒ񞔨y"g,ImԾ3HWԅHD!RI v&5&_;VމIk/HՒHIڢLV# ifLڭݽLߤ9ޫ=hҮL#5Ҏ~#mo+6w)÷;i?F* %$$ffV;DQ,.AQ@Q V^7{9>%<;4Of-]h B ^wAXh*]7LF'_i 4mkдg M 9Y$CӜYkag|f@%?>hڳ#ZdN+/{+='xv[{2w Cp<[?,_+N#nâдl14M$W|d+'oORdoMM~o|Yy“m')M[[64~=,4V@cA94f<zj4:rvr] 7G@Aи܉o;smq24"h6'}qFӋ8t 4r~Шٖj)4*.F hR1|*< ǫ2o 6o}]_h4a|x< YWe̓4dq˫7q,#hX{OBc=4~MkI8`(u/<ùMn 4ASb4_lN 8=+JN_jj9]+/hz6x6Zx(t7 R)>"@S4m&Y>O<qnq- W/u<Sچ|<_w-my|ǣWgVMQj|ɼ}m= 49MД5xc^=-ԡITZ93C)В -I? Z%l)P{Z|6B > ON[Yp} \sc oЉZR*Uh -CK B>5CyhU2Vhյ֡/tVcu3hàuA".z˖BкZCƭ|lm|lW|x<8g#|<}VKЪ-Oj0D_sl<^_U򱞯'Мc_{͏qmoAh66ۨhh>ך'B_߿[+x>g`3_竸9W=9|Y<{gx>xws(~,5y'/ŧcBsŤø6}.Nr1l;4  Mǡ/ ? NJxy$4>b0YA%K~/7qx~\ȋyqLh=ڷAÓ5`1?GR Rath ->eN*g ;:^tW^+P >/'P6gfCدTb$^ˊ`x ^ry˳rW\/dˡR^|Y/E~: /\5& 2xůuݽPWu*P uvustP'vw<>BY3Pf ʆBsPJBP: :CɳEPr[Jl۠di SZ#^Cp(^x BQ9WPt,By( K 2ZBZ:<쉆yJxk2<"+,$-G-(X!$CYǼ|!Oȫy!!WțQyʷ 5ޝ wUK7 tZB^oR͐!%d[W@ad}ҏ0 ,6wGxpl&~X opZ"W{]p@ޜp?Bf%dFfB\2G{BDhy kd !;d w"aiw=pw^3*'Aqrҋu!=-^\ )H ҵfCbc6ypcN\2.;\~kn-ܙL>wL]i!])=+Vwa!/H;o iGCږd k6&@BBי>HRc@HvR*!n[+AGŇçAs*_"2}t@ʫHhJa,ܓx|R~Aʥr>m ee6,)h )Ubb )Z"RDf@TH䖝\'Ar$'=qu4@=@򑋐WE<]'p!Y$sVA(W CR#Hz*@Ri8$千jHJ9IҐIft#GBPH'ieHZCU$M<$ɐ$}U) ܃l7vC}4$nĭƐl'$*I!qFH (D!H蒃dHh /L!-$TCPH(? ( 57O= ePo !aݿ/g3|>yxz ,H|B"$D HTTDG/!C⼟*OC/{um$hAbl$ޏIJ󓮃$ې4 ,wAB6CҾJH:}\V2\ Hzec$u,\!Yo*$m yHH^k9]og9ݼɮ*ajsSX @H~ɽJѯ:R@(OH ]Y!eml4!eH9)6!t Aߞz@k%xp}BJ 7GX-DCJ|HI< ))o9\CRp#ߖ1톔0H)o o3l{ \)߆!e:gc E R Kvނ 6oOGC Hxg!6H\M, W'_O# ZH :o U/Xn?!~[4ď_bWq;!"ͬ8ZbSA)]b $=nЄJ[k pwuL쭀38!:iD;XC=lD:Q *NBW/ }S . d(DHbSqDl1)»V@x[᧋!|dylflB6$Ag尡!Ԯ B7Bր_u*BrFBVADQ[}fB Ӌ  !x!AзZM}NAt HCtA`]!f@<Ẃ@sTUPyb/@5@(ϼf%[[Q?xu}f,q:iKf"&qW|<R_>~c+>4g L޷];"އW ?m eWjY^^~˩N5}x8^jKx>xvg˩YI+d~8;OwnS}}fp_kK>Lpp#Uݰܵ]KrsT6nL'p+n9vv[(Ep2'ܶu'o6 &mTpinu͔[X sx}rkZ7mz.Bo]n~eKpu 89[-Q29o[Y_&l _.(ܞK pU'Q ~?ޞyp]ϟOD$=nn/Tʋ(rg6;3N "{-܂KOƿJ>xx-:yW8*[[,p{z7p'e,xZ[r_ x/9 Ƃ.s]M|zgt9, mizk sw^Ul ~ց~YW~_mC7VwAU. C@a(G-xkK%=XGB:[v1TnY!2n+l7 $U B^zC Bz6Bg@hy~^aj lk2]҅x_a!\1C~" ½Bx"d!b^&j  "v"DT>/5i"K!2~DV{B|&| x DyUQm-m&G!zfDЁ{ :1D _=ٲ bCLN)ꁘp[v2n۶v".k VbM؝!Ħ؆ M.ĝq kWxoX W >9ķA C͸ 6C!! j Q($rr%!q$ \nm#$OH9lb𛆐_OstA9zrFԚ]6e7 Ͷ "5!ro;5pJV;7,*x-~tIn9 @ZH\?]%p7ܝy n wm]p7 --apd gȘ吱2C!dx́2ʎCFdOLZTLȴ KnA2=% ;;!wy N?cWBq!,4wCS)T B 89~srNBΡs=^Yrrb!g& 9Ʃ3DrC_w@vCn!c.Є{W3#!"d| ٗ 6mD {RC͐=/lxV ٲ [$ ~HֻfjZY!d=,mȺ YʐWYS R.d93=udԄedEkY ~C,7Ț@@ B(!>LC>0)?'B!Ț>cW dӯ 4w?JJUzBѽ̷Y9 |!ids>%; ^3ǐ7 r&u' W!_"#ȩٯ'b{ Wӥcrw]FOtc}5j|쮁ɐ'v@2 {\Y.:m}G$ y׋ ?w@^+=󄼷m([C:oj ȏx Yg;H@(`(X @/(^Mp<4N<<={6LBR( B4(Lª(m^OeSLQt$lMVنc6~T']2PTePYe= (SwP e_&AٟP.zeSn GA$'(:KVBP ʏ @!PnP=l<ӹ̥P Ay)ק{VkASn3]xG27!7/V{( ﺠSʻ{A8(&APTB*E¨*F;C9P1k.TXAP TY BO"{šTS<tãhQ3'x ãjYxwCxQx|qi!<}P9"*@屽P{ *sBe{1TɋAP5Bսrz_C5@5 TCu"T='Ɇu<)'@͈#Pj|ݡXYjosk>vgO5cP{g6~'3v<{ :PWx^*w:xP^ {R^]P]@xx@xq*f2« c ;azhp膆3P =#xq0w| ??K}gqwx7xu fg+7x E ֖м|syd x 48@sQB_ E *hѾ-J2R*Chmk{|/xd\w]H{K7瓖n:#8qb O/O\y۶ns6knB 7Wdy뷘-_^\so_,# f?nXyfs!ԨށwQIز]pdN>g,]%2.چq"/;qY3GFWpX4jLAJNq]3qzJ%Z؇pŝ)iY/{2ΪHܶ nk?dj y\+pUH\e WڎӸ;p\ n^[-㮒[x@:$^ GUux7 }ނv9tn<O'6;x6x4Gl{PSx w-,ƵqAF&lUƃo,A`TkvtFhsGpJ GpLs [ Tp \ d: ^W.{ ,@}t իh?  7D7/ú@('/‹vsxqwNA| t">7th,Gd%zDx@aW|AE'ֵkĀ6~;b\Y*&,Nxf:֊ܧh@,JG+?cuG|} _^|/6g`|^-M*vZ(rTM&> @ sὕxWGέZsV b@Ыiśx‹ x^}~}_Մ۪+0])qWK=wo*ݫTp#Gn$ܣY{bpLkqjmwp;nYz'0ufQ ܼiw;Nipϑo~p4:]xԢ-6>V6Exj4s:AAܚ|l!:f7ˣůx^7v@WIxF:OߡJz"9 zNTb /c =~CahP>:v:9a7 5pO^~FRށ>gO>Sƀ<*bHL Tq_ ^vAS!~m>U&84%tTPc|Q2oHY' N?֭,-?msPB!ZdetBf<wTk ]R]1 - sE/<5!׌w Ӝ qݜ9ڗ!5 UjAws EnGF91} {PU5P;e wVK8}E!([r7 @ѧQEޠdۚbpY(#*,@Շ~> jt>TozjOZ Zsv+v$֭Q8ޠ!U9gl7"-Ctp8r8v%ôơwh = &šXu.Eyr'?ai<6GQg9 !QG4wu$ .\SJe0U{QEp1*U'P55,JQC8UkPe*oF%(E?;Q>WD0TtfɢV!2Q zP[cj݉pT<USGTT[Tj:P9UPcT8r+]P$ 6h1Bxm6}_+d-|8zzsx蝦ŬS{1У2 :'WA$wxtfk3Pwt|JC=P)JEj(q%HY5^CQ:k{%2P|Si8EPTŭQ26ep&+ը4*hF}TmG(tM7.Q@yK_nƠZthok=/rP?*ƒ_!$<bW;~Xŋ\l9Ow+]wp1e^{Jsq߆x lG,cA5hx(OxRsXGp_s }~2mܸcى6K<~yœx G;W}Z?KNU[ɸ6.4Yr q8,kU ,lgz3X]LG2F Gwq8p49o8E4_;ͫ1c<Ǿyc;G/NCYqT1>躄#VF4MߡI_@ӢhM3{mh%p>T4. >~OFr ^.Qqb4V2QOE.;Pg^"ZPW5|kQC6_HmԘ=5 9||\ j( רu5Ps0(ZzE5!.FU1v.\P[FW>kzs7j7P[g*Q]lE99C5Mo~}ԢHBULT-=?>U=UrǨ6 / 7vWJ<) ] {RPQNrFT9Uk:TgQU+*G _Pio*7yP T g Pw7Fj4 esP<ʖqmQN5vEƍ݅_4PʮqL8x,(2Pf~s 7EQJtGTl)QfBʄǡ .$xF;Qa5OGلK(3ʒ܆$|"q&g\zt80Erqk"mū-(wi8]F(ՅbPlNF(Z~ EP4D{zܼz(♎"wƠHsdA_8;P5?:˸>laP@?D..8D'(pX j@.RUł+X ~l~ ߻Z໦| {}lQ:|_C߃+l(43(F(.1%tP2K fqg2u/Q+*ltsz..?oPI喖7ލ"=(578a0?F37Q/:p jkŌd~fG3.5\f%p-=GhTIV8rЀ qx40GJ}^8z)^B !o88e mɃf8e,Sl)E\yN))8+NnS7éw_p6s-3!H 1zRld9sgT7.Z7hUzg]dp֔8Gg™_p8{1Ԁ:8هF8?klpnB8G9!? pgzsD܍8OEj<wB$lSOg>Vqng7 ֙"4DhN{ӎ?i18= n)]"8e%|.'|^ 8n p{qT< #TAєS?Z+ e=]zu&ehԶBb.J@BGԸR | U4Kpy^;g6,ΠjwGIpmTQP٨PvF W=r[Q}.F@٥?=OmA*3qhE(}נ7(݄?PRV%UPFi(!1+~(ogQ&ӻQl yr> -A/g䈋(e&qvRܺ(ٺlY=N]LvJG(d)zIpPIJ(9}&JF-@PjJD}I.^^ݥ9}(3ʼy@Y;FY#;|~~ӕ(p:wwF(7~GPmB%(y*`ro\p *eFelN'v/D5]>}s1X.!PHb{Qw꼋C] i^;0ơƑh|5|_oqLӶNB.ME3< u?@h&~\ܸyѢ1h챽fLG(kΎ֡f4QRGghx0ϭʌgOG>paCnÕѬnpq/]#n/;>Z8ۉ&ߦI&.@S;hZ@]h;7s* }D s4AShzN>z#oa8V+)#prqP=U%򬍸eedZ!K.p#மe:]tagpy['  Ocm efiyi*{SIpՊl\Kۖ\q.)Qťy7.c8;y;ҧ78%9v(M.x*,D㛒8Lk8gQp~xw/;ɝ]oF:а&6.݁hQuO4}BݛPwL(!'ޘڇM949Uڟ7^E )*Q;jQI*M86LP% .FKPu7*HD(6|X%\[?^@!9\<)"pYIX#P}bA8qu?F_s$ך#h X/iϸ/6m$P4|-JcsTFQA47P֑wV٨=ߊaU4j|"*:J[bJ֨Ӊ_Qi*ţ|bʍTYҳsQb~2.8XWeN$TTZGie:UF*3򧧨eCNE#Pa^CT{!+pȶ@P}.YyCF.r| Gm!(;\8ɝB(+QPVAegxe[r(Wk򒻹sBwQE(rd9Rn({z='\pO+>ԡ8J-(x ()%nDP\עx.b(} EV5(;*P r ?iַÇU[B:GC{ },PGvCiD<yC~iʅ$5v D> }p"\Åj:lCT8c4]kaa} ,_aX=oy8*XVuB`&;*ua08 .8%#R38xl'Cp!8KK0\Fµwy]gM!lD\ZQ &~#l}ڐ3<׃'/@F}gYC!Ov@A) Ϳ-˜)j; Gqr* A1"ci";4zkchQ8) A89\l-vV6ny{C6qmԇ…7}Mzw~&B_k߁2ItߦFD5%~G3m?1S0@xXc [iЧ`ට#K103 ;1h5 Zp<`У V U18 .nCaHbI70t< cĐ0h!ܕ㠂!`?fCne &z!bO$Ǔ o.X`=0P>c@w Ac6k]1`"'?Ā0n/VUl#,"9b LN OT]0L!Ő!0 Yd"?o!G07'"W C30[6W ^A&1p; U+C'+lAwVR LBߔ{3Grvlل́X%!X6J [||n!Vn*Pj-^>'0/sƏRs!|91+!>Pa]+fl7ûcNSLdLoŸ#*,èź^6CE7`Ф/?}:kZt/[5zxS޸`GOkJty]:HMx)2^:Oxi*^Z$D ٩-nExQ/pSJ;:|k`t(jD-ho| .m`=go9xl=}gll<[%gύs[܍-x. ڊw ?vhw ~ioktn3:tբ&t4}9UC:ڇB{qh%v$>ϽxLwF[h;A]mm~ڶIa h{ږ݁T_ |,:$:/~tWo {pv /墓F":/G*k3ӕUz~y%_9 BzQ+َP7hP ~DLw5S|)Ub6RLaCQ_(: Ϫǔ(QK?~8/7^ϣ8F*Y(n, K7)QJX (~^BRI)nQ?6GyA޿(VnoD ّtGeB *XIBwwm׽T1t= J z0eSұt[87t?rߧBRvAz/58@8s@uyT7#:Nu1r|[r-u^nwFǠ%w;}M#+l&̐ Db"1-)L+3ߢLDy~= Ĭ٠/L^dJfIg&[Y S8N1%_Ly=S`ʟ guS5Y-fILc[)Σ aduELYcS6}2j0)g9/6Y*zdc LZ`&N1Iz&1 >2L6n̄gMk}(եNK\鍃XӫFz.ǝe7&P$)r5T I? :Xb} sw`LWډ1i&ia}D _}è`e0la9Q19kLj@hy:m%]D7c4 h@s^P^J>qROxQՃr5(i3%JI51?G.Ak\gz4=Xs3z49n}Ir%tg%]9$]tOny"XLks(r0OOQ>CIq_).Rw|̈́ȧÖPȽ;(2R\z17Z"mHjop#Lz\7Ro}psO0j߱ނ;5hT!9(QXݸ8;lֲ!M"ah?u:.+(I*OPeOT%DU{zUʡ܎1< +i}KPO*_Dox Sz&J;Sm*=VZG5aaT;-ژ=<SbIFO;Q@)zq^} QÊzXO'ޡ'RTFjVг,z.+BuҚbTz)AͰ\ K nJէJRSBj;޾C>Գ;z:gv'Mҧg };vf"w0LC2U좢,gz؉Z3zkXBQ1ua6݇ߧIo*IGڒ|H I7Ѡ$KHk Ix6 &Sh @E4ppUnh2ۘ*Jw7Um8_]LUPTwT-ʋcyK앓B2di<.@-8TrNݚRWQs-<#AYSk('{r2~kLBZ$|P"}*q$erg)cRJ[MCxڂ?Ӄ!};jyQѰH*ZLyt(Gǜ){Jr);MQC:߲T*0 9\z8">W@%Ah[ UZDխt(WO-I-$>` uHѫETJMH5ڌOWқ%[ݐwFepjoR$bBk.9?+^csxzaqG/6R UJ>vR)2N<[U|@.=D1"fPĪ( r\BU6(RtnP=L!faXgSȸLw\@0m# y;.&ƉS! R lzWHVWd!,&gRxEYR,@a-(5P` Q(Ys(@&_|%(S3 ۼBxRqnK'yאO c@k/m՛xů[HQ܁5h/E^_Am)RuE_EѤbOJ @'fRb\#;Qxҽ%dE+SA!*;6Pu*ͽK%plʿ(w7|9ԧQ=7R`=4r%**fӛ zy$o^Oz%kRwgzD _bj|OSKEjyn@-WSe 5_&6Q5jކv^)ϡH.gFu˩.^Qzj;IK+8fR5BQϚQ 绸USì q;SqjJ-e*VH>R6.m~^oK!j^Iz#|5:$i*uvzQjgQ1GzB+Z'qT,B݊ө[d3uyNS]:nM^R*.}5n?MvЧ"Kҩ@ի<̘Q_#O_{ԩwC-/K'A_ҙi2}p 'cP0}hk }J>Oig:FmLQV^Gow#-;#uΥ.ݐE=˞PɦM]3g_4?ԙ:L;ŀןvHj_vS{/z&BowQy/uK]˨G|7M^SA}xJٷ޹JқsZw^s!cj)ulre~ԱuʘSHaͷRwG͠LcA>ٖm^{(yQ@=G8qi;HQpz=7qu>duzDSWCu,{4X=ZEѻr/xzZYQFڿ.N.ӖE%k7}v~~;]̣vQjCmSE:r}:: S{=oݧ9f(zyjӛk9DͷX.4ޝC/Т.䌣wtO2岐:,uf!utnԕ:nQK Q1z+ٚrg큋8۷5c1 .yG)gPN/ z}_MY}Lͩ+wsIwuU8TB\$TЧ:-yWokg21:I t0!& 1aS &< 6sf¸ ΄g6_L 9U0!D&̄^Di : x1kILpJHla3[l)`g޶3'L*H@S&-K}Lp\oҟ sq6=0X&ѯ`AQM?vܾhC觔"(> 8OR'SK9kp#:|vu*r~GGPwwk}_}pql}:Kzv@OJRw,k6Lj퐣Uj9Z>kq8˨s-_8Fݒ+4Ro$+1F N=}T>zћk%uL">qξr}|Olo.vrGT#:m:_/cRLkSC/BRz,] 5[N@3t]Z֞CIiT'VQ‹cv"b) zzVlh$yP@u4_%7cHsh ]xqݐ9ilX2ZL&sd,ڏFјdi\IݡgtL[Kts+MGL+&~^ѠrGW-ʗ$R3dF'h/3 3Ct#yi?ghlx3y)0k&~/a 2T6fv =1eؘlt$6نSf0x{ƽƷ1Ngd+ęliu6fX$&Lb)1lv6fp7dFĎd?%A1l1 L\2S: M~t1nf´ژ[&-͔DN32 `.˙^ZdȌI1OfnjuƳ.1cd 6q+/M>ŦY Oald޶)f̽~HoefLp;&(6 w`bl`q3ܠO*7蔩tUvK?)v>]yRckz=YC> m{=*1cY yЅw-咭-:co-DgVM=ҏ\S)V./ZeZ4gS: Hnw @xGI@ ـJO*VCsuݢ^Փ*0IO2!T&z0}4p5S^ʹ!3ȳL[*iwaC!LgUWc+&0 f8 3\gC߲PE+fЮtn2wL5rSl#jd:V3qLIc#|d .2`{4k2 s&w(9~=Ŏ{$ⅿSAJeCQ4X&$&dHTRtQ;9AN*q1rةGOqsH bι8-دlf&Hl6.f 9s@ ipgۨaTzPSPRj  fϟ:#*lB6}P, ?e1ldf`Map1GB6C|/>&cKiit:6Ƒ 7*sy>fn,_llC6v 6V{03Wje8!nefcӘM+r}FObWpw6RFh01t3YL?a_2WXkMa7 1fTʌ⼙њlh'z2{ uŌܸNa&966<Ȕ696yY̋mcŚ:fMqM e&2,%f16_ƕe&ElTw"163sR3;L4agn3u>>+0l?0-Ùa)fpalHz iGq~g1=~-6}ϕm_o{WJgLx8 YÆ!%YlH<ƆLcF2mLuBiEgZ2-cZWb]}iW!S!9SNifZ'LsXqwr1ff6S^y0#*2Lٯ)0l[3Xf30q@9:%3JerKQcf-X<'pS43 &e1wӻP4_^f0BbҦG6b&j1q2uK&*x laJuLyO쵣?bYr/S)&E0aLu:S:T1᳘m~T41/Ly%S7t()0yL~d&{|/&;=8/eru9L.,ͯf'2Yӫo}̅9Lp/ULv&k&ygsҘv&=3I,&ͤ*b&F1ql6.x`٠Uؠ3`$ ZfyLz[pwsXfrP&"]YF!\C:G7 L`< g?lޱiޟŴGLF6vIt1LG qׯCz0=LYzd2 x/xEW+IG;j')Jvet8EHX$JĮߴ\OIj>z"Ϟmg($6\s`/]J xAt1DQ\:G'#֐: ֐cZ4]E¶yܣkt؉\^KkkryH=k+tK,٧l.yێ{)ĥžRdPL1D.Hǎ˞A>c0U$Su'5uj6;9!\NPMG\;,?Q˭HjQR`25eZRjH-\r9Zm0MۨuPq~C]g(EI6v~}B{LoM3H:MR{szW}MwCP67WJ e(Vi̠ۖ7}z*'WQ6{wқjQ:r 9D=AVa}O*?d<77#ul+_EG{Q'izz3@]Soa X4>Do3CH QҏzS'65Rkk6e郊 })ZIwzG>ܛHiø=NKکk5(OI?HDItZ@PO>JOs菗 ]n`S!>4~wg2x &j8 ?յDP/:I~^Ƥ2]ߘdZ%wIڧ3mljcw2'+HNv``6&ʓ f"=LDG0T%&2=qzD\[Xf&63MpR&\7 L\yߛĭ &ru&>guL1&z)x 16tޏ ^M|BQ6h#egp.2muϼDlM}rl_g3Be܃TϤ6YO QOAR*%7rBe>5l^?rH>:Gǃn|/p3|tǓP ߇kPxxgsW?*_x.WW(Y a?_07@(0G/䜙[0 !{+dyϕ,k]0(YڏPŊ_hy^rf;|J<^V c3X:/qKG/(umRw](eLJ~#o/O s7O˖^vPʥ«@:~oKw 2v@@q/' N@- ʧ"voLdy,> nyk:ɊM*h<7WPAR(o{꧅<,siNi,M>΃o|?˓~CI S3nH(Oh\<41-hwo?ѡ/xsS9H*jr5TsW7̣BCPe$?m_+Cw?{ j7APy:&jWW^yjFBUPc5ǡfSѿ5Ϯ3"x.<ٍ\[?s~,i0_wx:6a_xzrwyx蓔|[)-M]O(%^GaW.׻gl (۠ѓ|O7C6( ~]<=k|.7Ao8='oƾ◇>Ǖߓ;/m<ʫ_quxu],>߽B?hjګB|wVljUP v?>{ƫڝ^A嬋PQP:.쁢u5Ix?^;\Zd4dL<>tl䷧#s{C!(?wu9[Hʧy|ʡy 4'愙МVjGzþ| G/}?9/˼yǣKIU ~BZWBWgz=RVw>mk-~߽uI]>f>x~d+.˦n ?v4r䀤8欥VV㽼e̓8L9C[id2ϠbiN[ PSTa "{Vχ{׵??ZY{o!rjku%7sOjI6͝Y7zb5 6׭{n[+FUu>PugYʹez"W0`l>P?d1q [6aGg0ČP\ŨG?3No!j;v7/AMD+Ļ J4_Bw%A U/@( }DY?ʹK9珽g\3p0#8o(:9887Nl뤼\wT~/@юP->}\@*׌=Gs*OS cG ]UK]FkFrsgG_e<:TL9}XgPƿ%el|'&S;e`7[OZ`oW6껗ګJKnz g|=3*B/B/ݦ$6cML`%eeG͖͇_[˂Ae:҂;WBΙ8!X/X"sXF9qtx$/* ]Bg?hZӿ֬R"/h͜L?@{4x4<4eBӛjBwhz+~7O^!۸ ߓ$HZ4ʆxo>. 2O dEH'_^@`s]y,?} v32awawv=>J]^ f*d>M/EE_P' OCBG ~1J6~'m*9Œ3f̘1cƌ3f̘1cƌ3f̘1c w !\k/y'ݖ=[Eq2OxIt]He?#YR-b9\q WoHy.sNR^r3\4gThBFbT)s(dcXJ*%]}3We6~LqUVղr^+_'h0wpEP9erS?Kp\ЄIqj){-_UA-+e~#;$܏U02=#3{(d#ҳ ѡH Dn1jWLrNщaLjI9~/n8' XE5a) YhiP ZHdv"ee-'040C0NcѤ8BP}%\.ɨ eJumb}? vc>YaNwQڌdMN4R3>OdܫQgr_=+9Z5"K;Pk>'e5b_7P0tRO4۷jRQZD¸>SQsvLgKHk-)]L>^t,u2wa7iLP7pHQ3))(硆!+ϸ?ճ5o*Սt嬨LAWesss?0+)y'uߩ֗)RuL|}rI䱩&i]oz;'knFH"b{S}+M"{IqQr)c,.JK'#:m ۜpam+y` .H)  )mQDSR|p~IgkJq^P8/eәW)ZcHK?L$~J$TKs0=yƠR j^t,yQ1J^AG )DkXvk_ h.$Z $0 w,'fB;'%OE]fZmi8&}= ٻGyz7OAIMC9z{ƣs<ک]0o<ϾCl эQ˲qVl-ΊshY8k:(2H0 ApK@p$75/}Ow@zx>n7s?1b zH\gwg5;>lc? l7V~f%Cؘq(~zW~q;g;BCQP½;0 7"p(ƓPF0(Zu{xk`ΏV;¹pa. l )'H(9#JAz L@MPv 0,in(;u 5`70C%c{p40Ԗώd0;O0lՂa(0 ǔBPq?*;@eP J[tpʘYP5@Er2TLSB+P?$uT݊ Jݥt AG?f==;}upHr Ig]$/Pށ /0jFO:TLN<>z)_9<+)oy ;(fGy{ t\)R d!o yYbPdt#cP٬C)QTP@ݨ12TQ=9*!V+Dz;APHG=i]P;D-ٌf!h]QhD(A[T^8HW5u[@ռ|QJ^T7HkT).SKU*S9oè F T.F-h뷨,F}!j 偧(ޝCag!_2 ٛdN {TԶ ԟH^}Br TB%e_ |&; |^&%/?#ٖ<)ܯț ;E(.}lXpq'g[A~p ;Wyw]ߟ0T%[Q~G9r(,\{-r$OHLD"&C7 Ns& :("@ڵ#EQz=6D$w8D>!_iH61KEUmB/13PBnȯ^FK4(TP D٨@s}p݃JU˥(@q(f1 P8}@+Ug(̐O|cSܘ=""[/%}3o(U ՝dQ̏'K`DDtvBOW96/;ߟyeWR6 /GR1r^?B5(ߏq(k+Q1~l^S8҅ߩD`KPT׈x*˴@hJys*\nAS^;N{#>HzBryv Ug$MpVR.@9kϢB*ޢ`W =) R].!IH$B=H]o 12^Ȫm䑈 Y8PbR4ri(7D~;T #B^3DTI㇡B (G9m JGPY:Ok3QC=KxvţGa?E(MDLGS=)b0ҍϑ"6Y"{YXD!2tAHFr8 ;L! *f UT,b$ FRa|K$z_1d:MkD.@rVdd]$+! ~_$7Ab<acH8!`dpH@"KrAz҈H5C~# >R3H~ L+4ۂ#Q5D% {v"HG*ĞX!ݯ/B=Rf8"W%έDR$М?W8tZdKF(td~3˝E]܉+QߌUdi4u7uwQ||W-݇CDp(iA}f2!ll ҷE |q6בpR-%&H6@:#PG*ATEkDمY(&04CC( _jW(_?U: .]ā3G4]tg2f8*ӷSy[pEas'Qߍe.ɡ@Q1/HlB6 aQ-Xj{*Q>FutM#vvC3J +sE 8H"ZnZD!"d|&tD%t.֣h Bs>Z9F(3IVvLC>貨g61G>rՂo x;yyk/WML[Dَb8#9^$vƂ댠g#qa{ ^kE܋y ߶ț~An7Z/ s &N]AW/SGw(/HD껒(5DuJp~TC+jw\x/*N&;/D<'̡lS5/lzS}(e}=Dّ N$j;Q[ԵH^ hNYi :=fu΋kyΕx:L-޵Y<އgTrAyEs<u(b};%q, 6ot G|I%3'oJ^z.y-;?UIGNpr'QSrֺ׻ܥlBVt&z#wG3 1+N"n<v&v1v-Hbb= N\K!ߡFEFicb DE]y蒝DYN1>;r۾[jiEDپ=Cސc 9E B%ԃ),Lp$xT-&H '>A(}N{dTPK&#K@'A 㟰kVk_a.1'>xǶ{7~kf㙻^lQx5 }L8: GKqQi(ݱ0)p-˸$hp)|˪}yz7.q9p׎q\4ƥmpn18͏b/|{q >q[ja[Mmv;np WZm -qՎŭn` nM n0qqkEl n[= 5 g[zGp=_<{1'pMMY3z5sT뒶6kYk^Xk_Mey\qшXf8\b%qPs *//Y} v8>8_*Ysu-.]Obk%o,5n.6/ uq  nېոz7ö<6!q󣳸4YD-yZ[rȏSpsSn΍{=!7sg  nLh͍]71ܰF;nvML8LO8vZY.n7Z:D3w}]#B<<ΆGyG<.#_{8q5GD\ k"N[d~A3ꌻܗ}y{~ w7^v1ixX}#by6wYYsrn?5xhYc6ف`|Cou>~*\$Go߾:p ' \N`kBpYA`a$hI౛ZL`YIR[kANH`J*OCfTv&"^'peg u%l)o!@rF(!P2^&G *YNuխ$c- ṕ*!J+0a=;k ?Z+CSԆܔc XA3zX?ݝp/5|/۵ mex;</mVx|sT<"+p_#rfqѸ\J8|z܈| S]>\}ݸbxY<Oq`3.q$E8S3_d 8qi~v9M mݤ^ؾ^bhl^:a=V` ܺox< XEXt],ZbL'w̳1,Cb~av1߶ }C03`&`v{.f0F\ 3c5Se%vĴ L09I˟b| Qb,xe7^ -b|xX[ 9Ib5N{xb|Ƣ3*k&İ{:W: t:f䔈qRW^srn=9z[ߠ9'L8i6_rD,ޯe:?:h;qˑo q?9fuCqS3o'9/b8b Ep} yqk 6`3Ushc-!wwa.ÑQpνQ8V}a,W;:7 kϱ 8vt"q|l 'rb2N\ PqNT\-NLC91|/'Yqy}|.^{2crlPճ@!:,Gg3_?tD 9:?s(1oЩw^̛Κ蘖s:n+{u:Fg1tf]Gg8$7s>x>l rʑ[9"#T. ke_v+G\pXſІ^A~sN901U_5γi,Ԗ_r`\]9YmR[ G-ʥcٷ9~@\#{N~ĉt-G) =iDvdU95s |֢1g.1{~1(և1Ƈ`ܻ7F*FIQ4 f`(0ë1t^( {cPA/ a7 xaP% |a)NDpp\6d'CG6z6Bo Ϳѽ!t?k G]}9ģB(BѳFNnɒaƩ'cyècݘ4aLT 0KT S9ڄ{L=tBL;%&Nľ#&{Wbr>&wbbT¶a*&ScWMd[/I10 1z#Mu1ݘ/d(`l{?Yc#/ \Ee殖a:E G0_ X 8sg0_bdL X"0S 6X _ZzX+qf?lflvtu_Ns탱ҭUG;BV9wJ-ʣXout+Za31Qx1+'ޢz5x|)g xסey c𼡃g@-V}b~ Ϥ<%x³h^g7V5/ZRu KxۅG)FKd&?⹡^'#<57jW@=}lSڟZwů~]>[6] u_}a_GOu7|G+doM5~bD<c &0/A6w; Cig!tmuPDZJ7aoI$/$$"$ڟ׉KLݟ"^ŝ+e)Gogh)\#+I,OĎ@k8".%.'}HG9xmcz֏_$ !4,JI;I|S⧋oeqׇ緝8mBܘu!k3zs[B7b\tbg3l%13n&f]813q1pW׏ݦя~]^Ntt{ڎkӈrIԞKDYEu!D}I/UمjNܽ;ɧ2 zDlnyBe#b qˢ #{-ĿJ$\M“3$|A>$@X %8>Wk> ~']m~;‚鄶'gju1J#x9G#빛\W ϝ !ȯG6JTEn_߁jȿn&}&h6_ޗϯ̺AM3 ɏ.㇑w?Vw"e7zR"x٭?/)7$MґddRQ̩Bq#r06mC#=UPecBUX.UvP5T_ԧFѺ^yu/u󺤈ׇn#^wLMu?7}Jޛn)w͹ûUxY̛{x=͠"|Y޼ɡ_o&5MNZGxEMn-5B7usOe)D]r4ɷQ/B9v$9oV%㢐%@~Un PL!u;lj) SP,LzYכ>Eތ=cJdeJVQ$()LI'%Em(+T/JߢtBKJ;;J陕R灔F4OSHn$QH\ ߐtFB|{}G*0MP6;蚍f)r#ȟ5Ac+rE:}CU3d}lwdݎ#f /~Cz6RW Gr!yHZP݃82T|ȡ"IHZ#IEjYG'd[G1PX;-㿢>u24ơV104< GS&0'w چ|vѶ4@z"M*V"CS 5h]'}X@eTn2̙ KU7UQTvjaOҺQ]6,:Muש|qWjGϧp ޏ=KmFj9S;|SK_qJjjD_vzTY *O#yv9Qlڢu{=T~V֡< E (=/ !ȑT#9"~b芹c$)Hz#IC> $TWPfr졨s/fnE#l=m—:ͨnC9r>R[锆e1myf&wP5C39To Oލ,*(Cʲ/Tz0哛ZP<h~*&uGIt'P.ۆbkt S~ZC==< T/W\wy"oxLEs@Ri( h=vre4?]VUЮdMEf'PGDk3}Cuv*n̢0J3v(IPF.LDv3Y{]\|$mRqZKK#?J%#(!"0fHDj3{G|9|l~iHr }id/D<-4!$wE ER%b AY?XUⷨ7߮!׻䓎"JiUw쵨[C]@fYSH/F=O56A(ul4>X!l@~˶2QD]-@Զ^; USIb>궓Q}{.0rv&ACA^I,ЪSYCoW&UWRy@Feui4CP?}Mf+*.@ems×nFyE ڣ("PE>JyQ%{'X!+5wFH`C9Bk9u xo7/&G}%sm*c{%|& ;]DqEe /F ukE.N't  Nd&MKk+ʑbShsyKckosQB^Z y6ػE(~GѶCPtxmPZl1eM7zi^ Y G҈,jZdj_Q7 Q5C_+"ܜj$THGߤwsyHCoR)f.Cx?2_(nG"&Ю9ʀejX`v |P 'Cqd(oE4x{2P!rr(ο)>*A44;8 (ڱPw~T`c`4ZIU=+Q6'W"U]TLՕQP_Tg5A)h[P'֠~&;r0E]/@sTƣW_QW|Tc_ ueEj}!P E^rv;(tQ^BIԟ~Pe@X!yBc}GT6Fefh FKeQrv{WQ>vou;Z{EP/q}S'KAK.$J(tAse3(Du$nDvYryD JcF;h"ݯ ^12TAehk@s#Fd!A[ұDD;\b=ꮖ l?&A]$8Eu4W:5BMO9P= A/". qTIM1ԾAԎLV:5TSWם_2ĈĿmZ$8`)j*=QQy!g,xGQ(ξ-lgNт[&MC뻸Zxz}:;&>ByG񂛭%x߼j掣*3%h+$"Nw#2B Ζ!kąF@Er?fo_#^@x7.(?)4$ Y'zTXRq>b! u+gg{>jjgVX 1hEa%bc34O?6uNT6YTzCTeQCeG-&@e"jbi'zu(=inaˤ%mB! jDBH\;퐸J s^7KN% P)wD=mdoX=ٜy(F!bBFXjR/sWR% ~tyy僉FNWRϋC]y6/Qxaܕȩ͋dXLF%GScxs%)Ѓ[fu=(k7}[<ّ<#.\DI )@]^0CP/m)_ W;>c8JOXǮ<*gG^Rm8E%FeGn#8?x7%.~^z(x/x5`1M_|Cƽ뻜~p7nupwV[tsQqw--qMZzקJ\}jKp׽pݲ׷_[(\5EU.a˺/8Wv9q>ru8/yg`$~WqḄ2quZkt$n#pڌۻO&]3<q9s7xm<k͓\׋_xty>+;^੹W<gx yAtsY9K {xd4.nJWrvnK6FEnVn;qkbxtxRxzkx5蕈JīvnDn> x-g >&ia}|<6\=NJA$S{WToHt`.AO ^Ifc',yL],]NWxGHLB$'ҴS#˜~MORBz! 9LsB MKpɋ])&&?$88?`@#bF=5AGTiJb]?Z2![Ӆ4'4PAN^8'G rNz^ ^KMNB>N&JOn$(.?tM`Z6_1^1 # ,G."'G<-sp;!!ȃT9f%8[Ek˱6ŞtƠoG8fwxsN q8Q=eѵzbt'z[ 6C/1ms̃u8-Z}7;BV !WP'Ox#ԷSsjNj9cwquz/gw%-|Fzz]Ԡw8sE гwF& [uM G@O`F^DWэ=qtf''YN}ˉ 8fo8޽5y㝿?|slJtesFc\~Qۏs[ܷX}Ȟٹ#8 G}ѱ=7.V6t_,ENIIN臾Wk ` 2n`F,FC1'b80>XQ&`5>ql̜S0t/XōHSXl0-̕*oH12Lwa,_ecv\y y5'>oi8#Ƅb?LN4)n~i^Ǥs^{1 r.FsL0C c?><^AX1"1pЎ80Ն| 5 Cו^mt?FaTu0ܶ^;Y| ̏¢q.wat5Iwթ4.| խX[kv:XUXV~2~XZw,typˑ+Xf*k"nXEXLJN+z]4X?x,䏱tہ%V>lqZ?3aUaiN_lc#釉i;.o$l['csl;/)v lccvdzo~P7~^xžKbwv;-}Pwwc*YؖVJ\glǾ /}VvA拃G>8, at]a]]q+84qC84j\kc^#v_a7 v7bmv3u[S݌]ؾVQ*t`>e?B6W`|/"a3+m.|nvCgne8{=?~ ui]=aKbKRlbmPo}=ì 8l!8N-ѣN]qm5q3l~]Y, \9rޡ/srkZ˅oO8Q\jzKN\c\s+f=/p1\[õ\{rh!opn͍;Q{r3|'Γlfi4eN\:36C٢oAx;!5=<5s Ox֭}>^R{Q'>۷(w_|C}߇ ] ǻ` [3DOox&>/'8~|g3t">7>Ul|;a.2=]1UܚwT ޣGsGQr:$?v𸄀7# x/- s+_N2S>l+L>8i# Nq AAt@B< 'o|.aWFث |8{HD*grknVmnWVrgw#8^fD6$K!ц2vYkN-%f19"V\ܢٜ&NO뉟:ė? $6kO$摘A}5;t)IHSCƚ.INҷ{%9''$s yK;%I|Dΐ>SNłI {|w9FZ~9s;n?⹜{É|ظfĆ'6ы[=([b,l9Jb$f]6ׯSئ]K3-J\yHܩ}ӤG6ďF&_4f"Ag< )I=Zm+Hjٟ$e$IIԧޤ.*:I>aIxxU?"f[ %w ' }~΄mCvn#a/#\ |݋}^B7[?vaC k) ӷ"ь r^'t')~-BX†ZPa= M_G٫ tDÖ*7`FnEф^k&m ]ZSbϳWZ'#߷9a+;au I؉B?3JXB1a/ve4avI˄E}!yjrу ڙW;X*|zz DdfY݉<;V>[{qwn[Ow΁y-%GV>"jjWmmGt ] MTqz41N_( ִ%[-p0V`)%IX:[GIlJ$s$C!ssI鳍mHqLc&)摲)!HJ9,t"*)IّKi$]"y̖$ɛ֋$nJb/ŹH9Ę:$Ij?xFbY$'wx|=~$OR$͜DA||bq~?$>#e>RZzs#izݕt{ "m2 3!dUl&tBγ䊞8wY3aRUM$?xo/pt pRX5Fy0<ݵ]p0. yq zv{ļ{RhNam.KսOT΢'F=Omlj]vP7j u'Y of3ogfk>>Oo~CC|zçʟU7x?>Vc|Xgo;"x}DM ݌{wy;j-uEާ>ūKyjNWӅyMM~Tw*/GІ*H#exN)sQEx9(7iMBeeS7T'iL唯T奡$4Zn뵨BѨJ6\c"+//QDs"Mo  _\_f1&(=Bq96}#>3YQ{G(zFq*{uxlLxmʥ 63("޹|طR^Kg4=(N@q-q(ՑWGZQ,P4P!9ߓb=Cq6 )xh&ŭ>-(BCb.֗Bp _QQҎ1AIdÑ*wb-h&T>@BʫTXx]Z֛Js#Fs,A-IEmC4v݀vl+arrWԪ# "Q/7jDdEz~EXIymXp_@Ҫ ITiHBrwҞfH|_E|33"oG!=WC-n-Q?rZ"t@\b)s#5cd~[ņ!g;ȥ !?z (ΡrCPvB*]Z}(Gk *]U(ߎBh% (Ǣ)b\늉WV#b^&(r`3S|T& ycDByq2;P~Av"VDmB;>hw|^,>T4jr-;R7 ڿFG|*o|jD7eWQ׋wB9Tk;OvR1JTG`wQWY\yU ǥNAe eEI(V94oVAiBi X oOQL^bPPBᙇ"~Pا"/J(n4hrʥQ|ų/Jn( 8te".Q^>NX: [ϜDN̴E#d i-wQAu,WfM QM?ժ T'Q-jO*˿lGU{=P]ꐰ?16oJPh"Bz3KQ[LB}6d*?#LT=FDEsק , (IE+CO>RA {.DS y%RHqOWKE>oh\l wR*A{R` ;zS4ڊH=oP_wNW Zw-Ys?XYz5ai(E)X dՠ GPnvw48K>hD/5;* T1,8TjEoLܤ򀨿G}|"<P=,3TR]kT?IMT)=fmh]6S֣=g/P7N<4g$A۫ȿ'6h5Пh֠9 HTWj_n^lmu3C*'-Ds\ԄT]b-u[9W&ݨQScCMGEP+OJUT>PVq #jZ)' @k)<  dQyZ,֢&aW8Ae*Px.yݍE~tw9P[X]/Z-UCہz ߟun'h#8JhF:D _r|OTWPʗw!|Z#UTO거?" ;5z5f¾ż }#8bZ CxոPg55}쩎58"C#ʩYV(Pl%5Q]gDu Dg< oΈZᢗSu(->T}Jeӂ-cG( h:3^ #CD 34:sT/l@ЁhS~pM5X yHYT oDw>)jN?QsL*Юy4W*ry$uvQw;5"fݢSwͫA5p3ʑP57ʉQV -gD=}Eocd6(Fi'zFBYsW /Wv-mگA DԩQ \+W\GᯰY/2U槨|B#E?OMH: މv.v~@47 <\ģQG4 E~M[ohzfG8+LXSjQQPpz37K# CvҕH]N +liNd]?i4aTTw|¸?9%jd"]|yG9l=ZpHš"&zC?RuT=b]3*+>xisK?6ӕy"9R< } %owvmDOԳilsx\ic$ɭ2SP9))D qt'8)MH:I:J2|]%Iz9d$1'=!YH컝Hj҃uIu|hqMyClR#bwDT^bji w]k{rw7w'+K,DԀ܉IӸ=\íjnEXpkI"DFd}DakÉG!;" +>Հ YؗPP`B#'zЭ#CHmBzlAp&(dAG4@|M z?s߆gM7o(zOůX|/w,|g; JE?z ox-X^ge/]^w~0 sO2k<Y}<[6x8q Z1o3Fex^ijh<<(O 6w![Y2nGpZpmD n=bB[r#<8H<>sr<=A]ڙ#tvë=ޛV]2 ^ٛOB>, aN)^6|%J|S h= k|RI9J|t?e~,,T2ǻ…xKﳉx{7; ޲l4xޗ_wD_z]=1.w6_Mxw~׷ ʇeWɎxx'˄x}tKh ^ϧm}Gx0뱰^QZ/x9uz^;kH/<`v3<'y9|-l(/xcx5j׺Yx{h: %/9žM|nclԑxW{yg=, /x-«<>|9Nxԉ)R|[{3-o=~}s_y~ςߍo'f%E Ǒz?Cv\Ϗ|Ʒ8s`&koZ} z VOA@v# * y@`f"L.A9.$8!-b@HڰPu kB"?N| j9a٫ +K>ᣜ 3 JCa&7;<04.v>k s7$KJX^aM$L3y'Vq ~Jغӄ9A]_]Z#ŖZ ]I.Ehf&4c ԛfoG7/XBxha%rz3PӗθLȇ$7t{'Tك =З10fju%.T,'!RKB#E @ȥ݄liOHDGA{[jLrw3OW H>|pxʹ3υxČţ>UҿvƭW׸9⼤7/F'nL+9kKwsZW22Ξ^۹+\0-Bޜpsg8׶gΤ}ٜ̾8ixcAoqUo¡nq8`b~ {؛v~k9K ϰ ͱ_9`н}طq VbWeb'.vw>cwZagXݱx؍IĮl769+vn#lGvNvJCluxn&؎흩ޒb{5]~y2NXgz~ŪV`ղ;nu޲-X² _a6sg0k7,2f0}]M1{%&19`q07oqra<%?1><csH%w:vXc7G8*֎cƂ-d¸YF1JQD0FB1Ǩl.FCad`@5a2 bo ]`4\A?A[Gs*%Sro'˕LI֜rm}z+Г9`;'Uҟ"1#Oyuh+L7Ea5 ;1kO4Kg},.z+;9Ǔ_¦v,Kͱ"r.EئBa7L-ƨ96`6Wb 5~hi!gNwrNy9_m8}DlX c|(.;!XXd[,`^y'{ogr[^¼^&fo1+KL*֘ϼE=`/ v^.eXu*k˟ַSCWlEb}M鍝qvk]b± [[3lccmnhGc7 v7`mv=:aeŶJ`Bwf5kؚa-)>mvS`:8L5ZK5v_Ż"OLUTprlqԻ0{wNsqz#á)q8ǡx!p4>>8Hq=_q緧p OiBs}8.lB~;3RBuBtj[8[PT-:{SQ1}C-Jq7i.qΜ)T9gNrØ39{$:sέ续C( .񌋗'q}.-˥TusY\.Sqeq8rƀp5j/^3põ7qs;7#r9g)׸ո:b n<-"f/ڄ{*>q1=2 7xER`6]%m_w'෱-~ouUp#=m ]_/hoTafg_<~\ zoM܂tϹ |2;_ǿ~g7B_m_WW/;%F9>>3'heWҥ&3gӘL'xMC>&;܏dџ S1q,;~fFȲY$5 UB^\V9˛?C "gY Ls!ník؆ns!w7N*K'j *V6Dޞϟr;w|sCmgMcyZE?! :/IxA{8N$}MҪ$}%/&HNO<׏IPNJ3\;BJMRbImFja6@j#l&j2iSIT_)%p R!Y݈dY ]H^B49I]o.Hď?I,KbwXDHn#1'RH A v r/`qğoEIwYMܿ5O|sBNs}ȚIOB8Q$L_ osz~"ito$x#>$%+ɋ_lُ֤tH#E)H]Jͤw"-ĝo_L0ү_d4LdX*k9:̩J2'M%MtMd$q7dr&sU2ȚMԉdoIʙ^]gd'5r#ǹm2S-ɽrq]K\";؈m?kC#7rn$ٿFmяlډ,d $t0W^XUK I?EtRD'ƒt %)rbU}ۜhlr;Ӄ[~uyshǷp$aׇ:NJ!D%O~Ʉx\#WBܞPEH! ɿG4Dw??z֐{kG  !ßgH%|t7xAu&k[ḅgmB֏yӉ|Ldl.[\~vIċD!A)HF]K"OD9*ƬGDGDX%OExDG­F? _nJ1%mw{Gx$4£7DmFİD@ĎD,#b DyE]"\%" 5D <-t%↟(ANĝDK$vl@Tsq^܋: <9Dw@%%XM5\]%lF<#Z!6*O'q/E/6&> T$!q|5%IZ<$I|)H[/0ԉ IaA-17mH[J%M!mXsѤu'y iI3WI8"}RMHY"uIƀ'Hn_H&t\ Kl&N$OO'L"źS2R&?&)z؁- HlM IHƉ'7y6[*GoR9oDGny]tOwm`jk ku~KP>?)ЅbŃQ;E(:~ )j+k(|,EGgR4(?&LCC|6R$[Dѷoҧxuy`RBÝ f* R3(6f  |Ik#aY=Ov [lN0Pka 45tK*&" yٙىx VMļ1o+&ad9l0g{̹#9Asz 1/h}Üsps|a#I\]ps=,0,OļI1byWa^y̫y<̓0jJ`'c fkomÜ]%ì/r?1psZ17pM¼c1a<~;1rmfc c#$ F1\'k?31CŒ5b3d`F1xv3W#-nEZPnjlxHC`)Pc0昱q?)cvpw\&̫̯cg/Ҙ*5s  ?b#Xrي|?ނڢX6v2 !5d`C ߥ ݆Xzp)`'y,^Q{a5sԜǚ9o/֬˖c&xj&6 Uf6;䭃zJ" [O7#a[{iˎƎ y"ۅG_ QA|9~`s3J᧔A} ~2oc{Mv78щ_L˳o(ﮏ^QLos<+_-+ïSg}?ǦMؕT] x'Gs|wD-/C~;zb)`ۦ"99 C.J.Xz5\4qGfp/Nqju\S\TG20.rE 5h{@?Qř褿0$LU|X8\+Tr`y~, KgBsȏ aYX\V rɠ*ȁPs%)k=,}6 9,_R ˭QL2,=, KE߃BO?ro,+aQ3XZ?ſ@ya BnPز C@^g+Y 'rG ?'| ( E`۰_ %C MA>5ky;= 5 Wr '4{Q?,+_|M0ϮޅF`w0G|/~=@l (Y02l?2@̷̲'`<fN93j`w6Lf3y f5*ڂW 2'Af=1YaL,]aU)̒0S7R%0)L+a*yUfmYafhd6̰}  K^]AV-^'C1 xoeȦ}ٟ@L;B [ ?΂f`'Ila^m+_? y`Ẋ A.px5 ca ;1dv,p~& 0v6H5(Ց F*v`0Fr$$@bg{sn/MwSln#w+=@s ]9އ;7zg @O_`=[e`4 0>.]`"zL_i0 {VyXx"iOd 0x" K{w`z$X)OJO|־ւ9 6GldU_u(].Z@, 6` Y/ze d}9Oe'b o\yX8EuSHp^n.:\O׾xp]JL\[x>O?gܙm< cxhI ^^~0xOGUs"xZFU ^ s|,[1|o1e9)sߥQ,*pF 1/%!p`>ڗ57  prd 7.FM~ vA ; p A@k큀0W#? ^{_ _+/B@*BE 8sA5 J0:xo}?b|?awGcI=nZ xfwe=ޯρwm~(N3>cx3|Ou7-޹JwxT xM6$qm"N3[o *[g[~>xi^/_-^?s^̷Nxt/늇Ƈ)?>}e:x?opIK=c32韾㷀όW3Jo>1!x[J}ɕGx(%x׸j\z>:?H1>'ƃϖ.3x?Ykt1avl7N3Z|3>t=< >N'|_9||G{ Ũzӏ?_uǿZ,w9ׯ~\ V߇G2Vj/=x_a?/f}!B. `>|?7g* _2C%Ŭ̿? TF%oL/zcW5]Yeo@(}b=0#WoEs,&7d1 FkÁC zEs- o,V++xߨ79l?r)^වɶ}/\z&mcv;t1gm~90_W&VfS*_Nr vYFl3y6arl~f ~{#]w?ڒvX.ֱ|{e(j`X!(7 Cp/!Kl< %x8^,f'Ŝ?1ؔnpx <;x NG3vJBzB!~x„ l61zANz@S?! 19\"&ZOe ZeD3]b&@ևs l%CLI,x B{} bBl.~ e[Ykd[xM ^^ /@xYq ^+_BtC"8`S7 -yxU+ q=+!^i?xO?~ >A4 {$N ,Hh>x1+/BNHS yH> ɏB HwB.H iP 2 '$_:R1Rg)@6HԩHRK{ 1H- Rw@bHR!w6)e)rR֗AH) Ŝ8)i|-u>nR'C꒭@\s^BʟHH{c!a3d@bH, ɐ˃NHgwьŐ2hq9y@i@LJ3GBƃq|2kNg !CK,y!MR Hy+ )Gͪ![H bH yO0$km%<&$oՀW YnĠWT >U F^fZ bC >1bD!fCmD b@Y+!:> =BMc 1^sj!D@~>yWL/녗 n~WxV9_[| B| @B5H\/AK$> G kc Hd{!f@7H m' 6! Ҏ]$y+2'M5B$d^L0<BMHNtv~J. 5 }"H?o\tnҽ m ]{/ckg!]҇o9i A~j'I TnB=>d}RZ t~=&, sY2@֖u d, Ȫl -;' ECvsȮ:C== +V2u`-d~,* YFue~ dCx= { !Baq dsQ[!cf d\Y 4Xր u:d?ք8ȑ9#R !>rA%;_4B[*VA,|."!o7\< |7(hZ cGAa]RP}yP,hC(bV/HCWP1B0[# E/Rq$9(Zxx [~AQr7Pb(jKP+ׄP1 .Ca)( YGB<](\oC#(J"3P0#?{<bu( 󏰱PT?P$ k1ޝPxw7n{& c6.P0_:05A=🭁P.ʴNlRb %5P*ʺ@q=TAP*T>.~H@_ T(PJ-ǡ@0;o^CNbdiAzd _}$!jdׁG mbHzB" / ! [lB$X8BDHXI!qnHLLa9@R2H:],qHm' 9ۇjCwӁUnL9<yZ 2L+i̴e"d~w̿ K|dq4o+̼!+1 s q1d. ),͐P Ҵ w E8$H+ !m*$=I!ۭz05`\Q&H98#0I_fq %㻽 `/n.fGz`s`̎+i90UY&`?]a ]g0~ I~!hɀ}`p0 VIN00.M8i0 ƯL&-0RɁBxVzNn2&+lZM`cxlƽk0V;B+X <G`9gXnw*?`7{ йw898)>FA)6=[$ֵ`-V/hif:Lb60ySM۰{gcpՙNހAp+#p=l|68RWؚlQ ko`*`o`쥏]#+B;`PvD mple`'z lZ7-ۤu&c<[`>[`ǞSC6_l)6jmk8v">wԙMttm.)J`l%u uXn[`Vy;It.!eR VFeNέ`ya$XF,E `qh&X(S&AxOa!X u[r/XjS-`m2XEwXu`9,r7Xǿ <0 #ܦ̧lR;lA0[f˂LAu0)`:q>|_&%4I IB0)&q`W&# 7 j8UہQ0JF)2`8HHѩD0:.K:%0ZXF hW0Z| 2qS4˃]`G㑺`ȱ%YN` 7qL3w0|L3&7L谼X ߪIrX<,x `,.E5X=,lxl 3\mV `t  9lS C9\ g`]lOB,v|a}֊X{~pX:>+2)3WC!CH=) yfHu _![1UDa^]u%D&BV7 "OBu!D]d;   i$(BW-@j2Cx q)Hػ](F5Da!tO@ A_fC"cر|})੮ M\]nN#s\64%)cQ`` I]+t. Ah^ 1T8,7"aQXضo;g`St6;jX_Ab<(O{LO⌖Zr{ ¹ʹ#]7-!zKϸ󻣸//pD/-z9ݜ_wD]1nK 7u,p7+i'7*7NjX)ۢGS^,U՞UuU7:ʛ""4PUVy'Tgϟ*+2NU#UgxNuSue I ;U':Tul8GU%Wh:B:шg"rPK;?Dxud^1:+ޢq~#'MczE^=W+N#ԩ(Cws:uzo-yxu~EQZU6<4l.o+.x}xo-7tAFka7y͝AQwN?Ӈ5xuL^5 xMZZ$YxԱ3O(qiެY ^3KA4 r@ ]inB&he;fw4/ sBV@턞AEyzJX^tF9|gߒ//d{V c'0DaP. ~ CF;bs'>0ڗ1dgbEW Eu|>>_ C?#WYD|}mgOaȗD AMV(a`zbZ D{w^ߢ+X?zB֗O;vәyr}7:Ţx;ڧBhcm{a0D3, /sbEB{BQզU\t TNk@po}`xqa=}>rŽwX& 1uzwwq?zミx:Cch6^J?>' ͍OC4#җN4/CC>ij7ϢN4&/_I\X&Ǣɇj4YĢM'v#3s43Mۦ+K'ơy4ͮBJ|2 ' h͓uh"%4M2@ӣht'&hہ ?r?_~o]nnyو }q[v wL݉[psW w܃;UpGeeq_\W}9xpUQC ?}x@Oz<(GtᡝxDœ̮r< >O ëxE6^/-bMq^ cҎx9o$^C/d4ފw^K`|4[~43 .a&4.DC542 FƠ{4@4:6+AS>z?B 4nnEh3V ѵ]ZMV݌[+BHDaQ݂O>c>]p.}OޫcUwӈ$.p[YOnƛPG[wCP:;Eat@{|4  Q }@ih?,/'u(O]B|<ya5:6tNfl?:Y y5t\.imtE72tuYOoAr!z:]:EfK%|z".*Y^.9r=Ԧ̎T^;}#;3Y-9[`y0X5M8y:!/.GaoF;c4ct<#;1JNXĸ0z$&v`ۘ8  b-$#1L Ǥs17LǤ{K12Fa17]0im:&7Ƥs1X&6`RLWw#k`5& &atF|Iaq϶cr6LqWcO&aT;21 _/w˭Q)QƘ[;Sc;`t&`Adafr +au1 1l x_|/\I|yVǰcn >׏P /O09M '1} F\oi sZWco] ϣi1 s0 . gy.ߋD1* c5 ݃aGOba + 0)_C V/Cu98 ]D͙hs9hNj|^g9BN3}T雋>Wޠ|!z-qg>z{A=2RcLt1z| ѣ=ږGC z<2CwGkto+xA_z=ư7\=ueKiz9Go|CC# zޏmt^BC:zY6mGI}Y%ى^Vׄm(z^[Ƀ>V3Ysat= so=TZНwt{,d6Yr=Bϭ:z&rp=71?e!~{{\мeq=V'n-E ]R4Zi.PkZ&0GBko qVڌ1]h8zwⓎh)y@WhkՎG`DА \$3Ty24kFn4)A{Njآ{j9{i<5倇OA~#4ݸ3? w qלDW6*][ k&5S}znN-پn;.<˶bl=^8 ?n=4mX3֨N9ίnS^8>ͷB׮,G \zmFwt9k)t6ع ױ~j&0t-O dW Dq4校$9[q,Π/\dQ*؍~ /zkΠW%>{ѻ!dE 욂΄LkϹ!-6c))xE01f 0F?tƨu{;FJ (| #bc1m Q&omgua?ځa~^|#oM1<˿"d~ >׹?0 C/`4 uPO|ah.|?3gaHu YV!,B7b2n`|ae+ 1Xa1^"vԷa N} WA<\ԭDIM>6Fhot,,FϣrwGcA? @Pj w$@/),V,: Cy}vu~I2sFattFkt>w]cXGs5kt7A>PvIlGdF}>4vF 蟖c1p 4 T@QXt $z?w,C'; yF(,,bujx g6svAcCmA;v'4CljzK}<gmzlơ;ʢ$t >iz@O ʌ[F[VG;{vt,Z].zX/=}29/sЋsDOW#zA1t1zs~zI#辐]+5Q"#2kV`N A tkzG p CO;0Ā}*~L>W>=Fւ пK=`D;c) nV zs &ÃcĚa#wby-{abvUc-V_70}=F]{cFbTS3SST1 &aLh 91GM4\LzЌ1Xwa>Lz?n'bbaTL .Dn;&0Nل *0q+cߋ&ıQKz'c|F SaoLbYX nF301&>͘x_:0y|?&5brXL)0%cƔ0UZSLÄҘaiN~ ; Ô)|i~c1\RmHR֘3Wai$YifbQ30n4$16_9zy=Z/SwbjfjÜwm Ϳ1Ws/cvf `t f?ĜQ0QqOfs`n^3ZyưD,k5aZSL!FL<蚆4Ҫh`ީaVr̺3R`敵j0~l;ғJ$K)$۾HlQfdnŒ'H 0s9fƬW1$1g~-ǜlHw]lԊ'1$\1s7f. 1dzY'=&K0'sOWb];9F]0;UcaQ27s{|1Gvsfۇ9+cN2̝#1Mc/aV<=mc3&`'vօ|gΘv"`z/L51E=?ƌ03z&f=oŬn~: sɘS]FcUi:wd1(J90w82柭9޾3?YK/"L0t:(|B!, X^ m7ayW,Z< 0Oy>0o'J-ҕwc9S&9cb-L0Z= L3+#3u0bOP~?Va͏}J.c$bٓ愹߱J;cQH) "2{ȯ9%XK`'n,j,LqXxjebX|9/U_X>cySVX|Qꃂ7J: V+#lVYa={ꊂ$6/Uٿy{ہ(-:(+obEm%VpX~Y˭ͱBʕV^QJ=X܅Xq. 楢`{+ DO `6cE,҈v,>˖aS], XZrKϫ#d,.Kk5~/V C~<˟yMו) X𒇅[aJ,Lw&)XT ވ`C15n"f5cց̡쏙[vbm lU;vi Soᣦ`|MMF v:x/3 C ||FHZH@L_mEנ3֠W4oY X!?KFcA4V`3-Lڑ koGo˹#~;^?ͼg[8~77,>{7)إ׆c2OQK7ҽYj)V⻖8Qj, Kf< 0 {? ^找'u'oE4Ы瘼N,dx2W#wb;'`Q2,G~X=ł0_ ƠD7nA tƧ_]7 ؙ[aPK0_,೻[1X=*Mu [0;qru7sq*,c34>Zv&c8,>OںyX `eZL3&X_7?U)?٣o2֍}&_-&⟫&K#qp|4-܇oPK_b)~{'GbWŮY,~a}vƸ=P *0# uTec&cyD Os%> v#U,׃jU0sx 8j?bY] ,@Ir705!C>~2(:ڡ*w,%Z%kg^^_{+̜ zERGmƭ=2YzIL_~~y+aa?`oE)?_ğ Vo2w  x!Qgvyt=OalOQ_#!{^GgaB1`gW&4( `o5oغ0'ӣGt7̮AsF0 1 |6 #c;1ʒgy)|mn4sHku A0 zlQJ3ᶫH7al0Kl8ƾè 7Vc9vUEycT|7S ;xn6 {P8#6z_NL~a}'v 7yBdcWJѡz4ж:ć}cߣ>>u909;~bև݅hㅎr|>}]&>~&yP7yۡ=R{y*ijFWFJ㍼'1ۉ'e|'0R%_`h|%SnS`;nF_F?Rœ'\'n7b{&OL-OG'ї'^7bMވHVsIFZF$9Duxc/D,቞btkD 牚|ZD/^^ho\-oӹxb?ybW_?+y|I24 ]=x'O$'6<'OxkP!5_ } yBn3yBV} I ׊y"#yL≉ Bl O{rsyc7$y=9Ϛ7rbO'x'oD(ވ$Cfo't'>'R3H_."=}'zC'xBߙw-p),-o'[ ')E84o)׭T7LQq@  o}]kþn ށ}W}e6o/W}}b_os>t^Rހ^?qؓ=DZgD }o7=g&uሟbXZ ^ÿ36_a''vo ] ˄'oa^byZ /l;U-vǺ=%lo~5 zjO&ۉ*櫯5~Ư9 +/oFV??o'Gz~y||_%VǧGE~T݅]aהт]?^Gaazr?52?|n?/|7/;T3 ;ۻ:|7& Ix`g-)c3s$Wq9vOΕS;̰W 6ŷss?|`9??lķyS1I|:ۣe#z,v{X#mpʁ7RZg(RqF71YLW_ ۙt4eߍ?;&îna_e~]Zֶ8D{߆#8^z 3DbN nNS1 _1r0c`0k-<ش_܏gáڂ"5FnĈ-Z\;}tw_7؂^C>ٯDYqaz8wg/z?7@ =o+6sŀk_1p SC¤X4#apcf;4Ƭg1[&gkV7֜[0w{毚 `A6]ļw0?v~;b>39&i\09LScj[fHc̻wsb2]X8R w }kYg912fRwqMu|.f<#1V:f{?lXeK) o,&>yw KڗbY as N)<b* (Yծj(eZXK~VXq "T<’X*ϱ IJ4 rFX֍͝X6VJIX˕cXzXa5rW`ZM'\=,C+v}5&7@X{PQ05PSDԝ*(ljXE*Cm*eXo"EJ.)iLSlӉ4%͙'Bsԍi4;fih4xflZ8ɖ~=d BIVd#-fiR㸈fb4w-ݾKoӂOig%ZhF ³hay:-̴Ew#i1ySi[$7ޏ4tHL? y'!K{V|R.)lj&RP@ p_xRO H)̡%$=iD+ѲGh_ZaO˦ЊkrZՓF+FѪB^W/ZmcR:<L ki>Mchp;ƧntOi,I\Qt 4^ψ'Faek MeBZ_Ci)o"xڬ[Jj>0O't 9FGJL_4yI-&itfpsWUxyIݧK%atFNM]bH{SZOI!ٿ.iݥtz8/{rJqҚu#͹ܬA:]VD'.I_ӾJ:~jcw9Jiw=/:]S tf:KT_`H׽:}| iOz3Z%^hr!]]D.n"#ܼtuE]vE2HnwˑΜ({7Lx>I_ɐЭJ;EB{؟Fw[d>.?av{GI!Nz{8w2h={JՐtC$ɤ{?z  _QH:`: "t9:}LW[He ]>?&չtcY:?q#F75lҡ/DžIЃBo2~p#CCd*z,d4I zr*ttfuI'җE; -'wHiM/~:;NE :9:i:•tw]Ê7=:S[A:r-zѡotxj%rOl 9_Yth ޣKGb.1]:%1=Jǔ7Q::8>f4]@Gӱp!:Iqm?MOco0t5:>M;tb8|F;iO?C~g+:}:{s2i]{Kgݢs3}x>i1;qBjtN;]Ir— :iӅHEW2N7&!J:W2utm4i)хB:?s:i-'BEդN׋rW59{g:QT@Ӟ|zms#;e mmL;ڼݎB =t.> 3#.ҕ;N=-_niΣvWk.&ЙH[8eim|b*K`:5NE!tlf+T ttG,AgF*=t-]N:S:S@ڻ=y es4iWaZ<% rBZ8NB+.U ^eΣvVcBI/byю.$GO?:\ܲy8 W}r An2<1y<#K ) sHägGR7ΐ^S TaOՒ9TqJ+­X@NɔR_tϔ3oSo̎JӣT!CՎ(S%2}#r8JxjOoDIC.T\N% gPZgʿaEc)V3JijEuYT!FTEu|54u&{&$?>-O.RW/u 3Gӥ+}H]ͶBFKѻeGzHkQ[z?S7vpz[,Do|Iר] Xj U7b z;6`jzڄORwwj3ߖTCoPj:G5?Bo[ͩOo'*ӛSjO޸:D\5:P{[jF:yÜ:V9QuYJ;P>lϦά5n{u^Ѻ:Nl>c󦷕۩Mښuv:5jΡfjzNR[ j N-姨/FQ^F 11Ǒ^)wȀ ӫy jYGƏًԸϋR"jx^Ue75QÎԐG T.O :5*jXkE]bTu~Oz%N5ATӽjՅnT;Pݴ?TPO/Rm}J+w8ՊwSM]=:jv-J5T+H5eTM55TUYh URv.O*}OU.HU VIJCT\%A] O%A MIk! ~@T%1ua$p&c$8 z*R>ʿI =V$mbϬeUT`O @SIsIgI"b<𓪔vR2GULU}T1}Wdcۨ ͩj61$xx$"|Y4DV>TQH+L\@r=U8LJaTy*J;qz*5R\<*Lʙ"*U8 +TQ*t;UT3ϊT U_ Tq*QJvSٜ*7TR-~*}zTmEsTCe+,[N?Si/*J${7_ћJVawߨ?}5DrbgKk+Rď`+;+&6KQɏ**ZN%ʕ~_BJڴ>&9ė#F _;@(dkĘ\7OǨ;LoNc-x/rOTm R1KJޮa= U&C 9G׵TD%똍SI%42[SIU 0Ʀ0Ge?"{ jljow^C&ւ̧=ot֔=%~1{įf|uDt;T暳wewIϟ+L'v1*2;2y3ode> 6vvtWqɣOcc|KXn"~>ms0?1{1jA ӣmu sx9іl;4{zWD"r)ot˼rpLF!FfzfXg?FtƗɔ|';WIgz2o\g*@ctY*uK!TjOԟQ*MYe޿[ٙ ґLnk^c"Q{JyT"OO:-[!*[ lCۅlcXXb- T6&:ʆQHogdQV*ʖ܋ʥRS,QzRT M zB>_< <|HSyB*@%+72^E,r#*gS^O嵬tv5U,fX*Q*T!ǣT•IQSX_)cuh?Uϣ;br.ULwlx=r*f{T1&G4*[bdmGRQs/Ds/TrTOK=)SR;5TG%5&G?g{/Ub [gkژγfm Uj)#`lf!y2bE:&B6&Zʃ:f6OfqkYݞ3{R>yz9UB*:nZMG?P +fgjQeU/'nh0aU$xL  AO_H; . ǥ3$HdX.Ia'Y]W !vO= Ϡ*kTOURո7T5ـ Sut*|U*T[Q kISy2b8OPՠ霤ZD=j}]T%5Tقj-VjWRT:Z y JQ"ErT+N0rZ'֚~]RhLZT{ʑ]N'Q^g>j7194R1f{Op G;n\ MHuZGl"f9~13T…QT0Ֆ3:Tj &E`2 Gu˯STGu k2Ty-r:>i:/T խL-T7[?TI'S:?KW.SBIۑ?2ZTkjRmZ>fb:VcLzRG$Qx2\5+؜L׆9s@u Th$[gDuLKTG?t&յ~Todjz TK>AkS[ gFuUT׶WQ?T/vgSݛgTV ks|wyPa>5d=jԡMϨ>B)R} C{~/?d8oD;R=o36T1dEvQ5kP UGM~{saob*q:d68fE`H[6Q~f}~-+Meϩ~yTd_e{bgOF_-}a6x 8{GuTk]l>{afͧrtf,ַB2Η+O[o^Twsl~-]e>ꮥS.܋(=,3?:{T7ob-;; =۽vJ1b.,/R, aQU_{MQmTfj=YJMUeTuL $0C[d V9` PU?QeG>AS A PUQ obx\ d8n;RN6p4[7u5}=6sj `8aé8WDR~t$iI`2oOPX)VSՌ:`*S1|Q;R4[X`EUɿ*vQUZIUQ dS^VY`$*.02Vz6Չ gy\jo/!T|5Y^{IuT;W?T}ӫ*5Bza]^j|h5,@j#NWؚ^oW}z 5韢&RjI}7?5R{ϟl#F͇S:+jj)2z5w̢}ٺkQs 5H-"p$QK5zS/jnQYjѣֵ+p*Qk*M{Z:H RԦZm>Qۜjm΢֏avt{U큧4$3y !8ɦIFP""1"ET^H@G D@ @̜dR(Qi^୵>Oa>kf$/4gZXhAkqZV&@lN-'{[-2׮ЪTmBh[@^ZZ"Z&XhMhCSyhC[VZI ٵZМ-+@kZE-o`\_v]bCiЎA }xڌM6W'$H'ZNh_ch߮xm\hBMvտK1i@rZ ֝|JtPCkrr/rDnFQM9;~rmGn ww_ <'}.dޅx&֍$m Iס۴"/m胋;z_?zSN #3D}8Qz5W__fu;Bo2W<!5B['ґ_w:MAxkxWx4w x{~7͌J]N;xgI(7zAlxwe; xxVxnv/ o؏&]}vPp EAoZF8EUP{B!(\+ a9(p{ ?JDQHkn鈢P*(XŽ@ё`DW n +=ǐuM~.zíTwMuZ?ʋ.YjNwO#54=8-58vtj+vB~eT0:ُ|Y% *.W@ˉAs{3TB̈TDo F{DGyMAY#="^!>?ͳ^Ghij=ڃq}G8gtF4#Z<Y64B̒҈:1+ tDQF @hG#6up!^Txt#YƍG qIuB>l%>a1@R߳~8D/7Qs!m0#NȋF}DtڈjFv1QL9Z>k ¾ۅ9[saE;6"p޻y@g' Z\T\{iS[Sՙ{\K=(e+e/2pq*ד|z^K#dXLǽ7ٛF2Ϲl1yHۥV9$٦n3@쐲F{IrJ8vjFj1ZU/U.1RC$NGŋ(P|<˫Il d>}1QqfzSe/ rr|: H3cj@Lͤ]RΫ^gI~W6*'~_ueYſW&+yJz(_,"^jlQx5$pw~sնq|=")[ᙆyq|WRWx.3۔o L/lW}6]g~akDD[E5DUo뎨W=P1_a>'*d^OGJƝyHa8+*ϔ By–Hw[?E0 ?^WXvsx8'V*:K8蓯|gJP!yڇkExW=½(o=m}̣iy[ez^E3JK)3 J~ɫA{-'jo{%|Re KӈWV 2M9^Ѵ'sbĻyxne ?3e?ǎs ^L^\LIL߰,1= 7:c%ZsWzmtxfW|zT+:)'_"`Ec|:ߔxxUu`}Z_ }J'L˼,WU7b˻/W|:=iM֣DAa2ؔF[stբ̿LAe}^TV{T)YY}`c>S:NK+ ռT=`s9z s%GլM7css?XgCf/z2{'C^Ջ/Vsg!$DFv%bl潾{|,S4م(|Ǟ$|"Ͻ:}ps=sϹ}_ڣȮ"&9"Z| =Mw( ?']Ӛ>S5;01d;}9q{$I>::>€@9 j'+bjq|- o>/ r6x8pX4 <~6?_t^vq#HSj8#˵ͮ,ěqh:*(CϗՑYpiH>JYN~WIǁƐc\gˁ>Z^h?+]?pYAտ/d#~>l~\{ _|nZ#P6wZ_">HײɎӮP4ڸ9H/.}#kGOOm6rxw)xp8w_ҡ3X~ud4K-Hr'睯k7-Vop|Øw _ؐ޵Egx$KLGCw+ٯrrs9,C]} K5kH@ާŽ OO֒b SOcWg{U .>-Ӵǜs?)b.bG߶ Y"JM4Hwj#_#ـl4$Dk)%3 B9ƶY鼻||:Kڹ{rIt6sn':rOyO>oYRyߝo>/0#SN]$pt^ɝw:yxaROPND9&IQƭ\!xyM#ǧJy%GA+Q|P<k*M[C:]$<[Xrמp2}.;RmN!<_ElGItL|<['?ǩF(Gק9~Q?F{|(QHIRl! O)BCߠxHD6r܇8h7jܿ {}lӊۤ{^Mo{^q8Ct_Lw>N<1ڸX,8wV}}7+s N\O|w h}:}D'}GBwM#4/;c K/T} HZm/>xN3qPOs)C}7/?ƞw'ػ?AOخS& (v-1cIAw?׬'SLqR_v#;6i61/r:|3?!ZBv 3Z\.WgPpO̝2Ymd :c=}McxK;<Q+b9=/?ԐZ#toZ1.:ž9%2ē}oЛ߬ow/n/p']˿UHռQWP_ȿμ .7GODG}<+<<<<<<<<<<<૿)=nGF#jNC-дވ[ &o@p@D=iM9 htHGqi6vBU#T2G}y[p5m!VX# Y2hYD] )BEpQm/7C\E`L|) }Z Ԗ}YJ]z\!!_?4z G>k GE/2.wB ݸPm{ m`w_G`VWA3bMO"-hn H\^õsE{|+DϮRyμȕ;d.CmDT@wwDjBqD.@EDCxeoFPA9,FdDBGW {T#\s7"K24G:޲ Bc PBCtJ4`2 \1ৡNoc| 0<+y7Ad5 ZZֵdGM+jA]v7E.k FBV< }z5h.C$Pclʰ(υn!@#ۡ<5OG@f;;A9+{Cyگz!j Pt^02>8'Aؾy C9a'6b,~C~^0轷@&Pτ=jd$?=x}}]0=CPvԆR%jBilB[O'Ai8KخFw6ևrS@-.j P}%D `sl V qzzhiD ~|ڵw/ "lZ|Y^z2wCʓ9P7v*lWd\YآU6̜:i5gZ5cRKɃֹal sRk#N)dS჈1֖lXTU ''= O0Zit P1[Z / CӞ@"f&Fzqo\krC#x@hͿz0Z<GG!_ k0u&^VX!~%av}kg`-h s0rƷv,(ҫJm ] /1 C|}k?g\F%0"_lD9<saMWa=00b-Jj̀ZV)0Gke@{,(lS `U`zE|Sh]J'%e97󡵨7׃8d>_Ʊ^俵6>eʯЪK`6y@Yg7 ?&K^TBlmIX{z?bjXYr>:`> $7f"wXaxRޮ ҟvl;0WYrwX= s]iLygazRS+:NG! ~+EpĮV5S#F##Alװ&=+ϲbM̦>K[C_FgO LiT?1&F+[z5A'zXg_(0jg,YEз hs[5Δgq vuJH- #tw+k؋U`]ab*Ɗ0G-UՀ7=EXu-3!F0{'U75ZCP_"nsY+\na}ߎ6{2 ORC7ܺ\{lok[x:NԄu!.X7LBp1[8Pƍz>S0/-FW!>"շ!u7b #*bM!q!oS},U>5vuoeNg1uja%F;vIe75橏 ێA+0_DOAd< G{zXmxQSWs[q:.d c⼣@".a|_cXl(20.M>oBU-i,ʥJP? 'ѧ; gנ8ԅ[3ڴٙu=+޿7ko19Xe2s'<g5BFb}/0睃 ΃{8#r~7}c8{9[ @tD'" 1$XЄ 1b}9碟鮮.}F%=A_oK^wJ|I1>閈1 ς_Ky(s\<>g7!^SwIb n^E=xUx/h$=~+ցGLXAB+_ύ$'_M2)mు|zy)׺:q6xQb 85 zmkc{!{~#xġjSxݘcA{=}Ygz?|W!v |֓O(lSU%P#\w)GV-xX^G. ^S6x< ~M [D'Lxqn/ E8&)UfHxL}C0T{ ^qP6|Rd>8I.o ;,18 8D!-D.䵯rQ>h#gV F;w3ۃ=6X=xפ}] [da;E @s6Sr" >]ǁϕP0{|ay,Pﰿy3%$k.<CAQϕj{nseޅv,+xVLlܿ{{w+j: :Ă& s@5>>{i|඄R4k^Xɫ Lo.'g Vo~G_?3═_J\zlLqՆu'|WL}j(zo5\ּji6 a;x*-e=yH3{:-z]eD/ꀡHܩU >$ϻC`hId0|g/%m <ޙ$)f"d2 <~?%ӽxܲW1[O@!<:L2=o"@ Vv൓|J"]M`?XUQ f3<Pԑx#[SWx.n^=K>5%3wWD!%ZxMzN趰H>nlWd{4 0r1~1oœpA艷KxQQXS[^C_幊g"?lEÄF|C3qVKG 1oD = [m=D;i'*6`K~`nCPռ6#b ΏctHFn딃nS>?(xlq1,Z~Qs+ .ܯ,;D ˕?E^-| puBw"oϷEL}|WމE!O vM CJ- ٿokUw%~'%p&G_KۗS\Ģv@Ϩ:E;]Z<'7ϵ}E7 _#< D-QҷsVbĎkzཧnEق [Qůu*F{z}B0}F)#\y0*Wj"GH% m:%Q,n-(f,痁gYŞ~\gc)I> NEp 'x2}c#qO:~xˋs}5H\g@q% [;6ޫl#WUeWf;w_<5aH'| cI-jǚGKJm][xp.Yr%}'q#z xdw"\  zWzߜW7i_">g[&@p!zMCȓy,p ^7}xtUZK->'e``0Tc%@ Zk^Enygc^yVsϾA9o QD1y=lܺ>}*9XGk3nW4";9g ?[| zgPv*xu|^qSQG:ev;zlk;|ެgu6p{GJ.:<>MG1Z_=xM&MȔMC}Xǀ|yy\USE0pK1/\ˀOH *ۙ-\Om >)2~NWC>N1lx ^(P|͏o`eudק|0 Gwsyyqe8w>vzp \.C MǷ%Y_KT m0uF;\VD-HC׶L'ك_ӓ0s- WCZW qR>ED\\< SY3r *rYϡ9݉m,+^OiJ̓C=gDοx{$&/@AsDYUz}%>w,jǃ.?V9 `2HĵR#?C%-xWSÛdeݧ$&ooNSn~}QS<ݯש~Uq QcڼKZ^{З~!bKmc~ %~?H{6'x$( "KZx@R}^&`kzTׁBQj^{Ps7bϞ ^.jB_zȚ"*9)^vL^*)uVϕD1"8&d7} <&}QgOĶص-f~LĠ |k+j`ԠRW .g؍QJG}8HmW~:$O!QߙEgNcڨ<~N|.WpSj&tVQ[q^!=1g1xk*oL9yn(|u%<"JobB?yDCY}tpm7Z`hoC73e1L=$E۟'EL/my-תlpM̢:.b0W>o¿- ?/r^ {w$i1E }'#_x`H6k5Fy*97o3OƋzlkv͉?=8/ϗWjz+]]w%ؐCOw3kaS *597K0~f ~l"^=~*'b[!>s7R^3츽!~r*JDbnM{|_*~sk#?vރ \ӬrnQ{'^1M x &EuזDl(SrkCXzI &aQ%G_OrH_&P[8rƿaxs$BnaK#=g(vЦo x-GQ>.  W~+Sܐ6ڭSEuS~B s<Òҧ!#:ה}Pd%K9Owy;A-]n CN 3$OPϕ%|?|5cޏJ)Fy]b)5Cgg՘+Lsq阨X&zLjlzU?2`\z}/k/?˳Q\QNS5|ŷQςsA_t3x٩öKzR;m-~/ƿ Z}Џo<]x4~ʼn}DG|'5x~,PDqIe⻉wU7s %~ɵ)sfVrA-~,j#sLzpmv YT<6t(ǿpL;zӹǰw/~6q;}MQy.x=׊S7oo]|wP^uLpoTQo_@{`p;Q ۫>=0ACJ} Ux'(onj^WmA; jH{V- `U:6+{y uArj@Ѭ^]ng`ew݇R`5XtK!5.,X͠}7@wؔ 9D۵`5t߀ tkO=pkj'A׮!X) ViKsJrˡ+7t'k.7:}/z n5Y{F5`e~ƂF{N^ @p9lJA(s6؜:a Xh#|πUAi`QdXlB$4"9l:P3ky~- `yXh ֋XļM*1n6,'?jO+;kv[/:7>t[q#`X=BB46o blX]~`Ro6})wBV eXDƁu:`?U7fc]0_:~`eK{GDYG=$z .}?d3Xܽٛ','ꆀA`}5xCf#`,ڔ`zb#0lkxE`\>Y>eXYW.3ٯ2dۀR;v VۆuX-Bo x2t ;+1 lʿK2t>[X X~'ڗ]P;Bf_wm0/ 6+~lBH}_J*m-X-jJ4كҹn`3.l}h@Zr)X,kSX~%3MUjH2Xl=K~X'{G\1,~XT|+|5vWA3} 9eSzW,X7{fro^.1 ;+̺{5eoj 3ѝL()P`>lBUWZ~`ӺvcVK:*8TqFu߾`XAX6 ,K.Og.zR0nK}vuN"x.M* :"`Xme![uK:)wIN{b낻x_(`I&X턮d=qB-VeZbgzLPD)[RGP?tKmk*J|&l#I^kеo6ujCiVY&l+spfJ:u ܿqc?2$X|( =s`q%j!+A7YS߂7Y/7u.,GUQ˖熁u! V[{ m5旰+F۷#貺 y&h4[i'ln9W(6ӶF;m-sNT9?|<`= ك&l _PpdKz{=NK§X$4CELAwh5lź[eggO&,o/Tb_ǂō`|֌`@]@Nq/Cݲ!`:Jɞ[-.JQyh1Xd%V݄U-~6Uu!魟"7V |$ݛ}Oڿ[SsP7+٤PpK0?CESxFacC{ +)5[,@GBͳk~E^%+c-k'W(Q?["&vF7l1R˺C:t|-t/d9 ݶLPsEl[wM9L͂'מu`o$qo&e  5 Kh:Mq᣹=(OO: sZ>6=EBmE\MCW%,0"z!^I_"bK:x)χ=jŝ"_*X'X2c˩E ows~ ֛ VAk }(ɂF`S3X~fןY`)(_o Yrƀ̀B3A[AA2\s?qFfn ٲݠH=Mo;)罡`ݐ/t5/C?#ԃͬ[ws6 /tXOrb┢?[GyuQhW \#b|{ɖֶENaQZ|.#z(MZ rfފ;̫m~)y=_(w8+׀Hm P;ϕ ?c6λ"~b_VWUMtXy,{V`VX lN?~Pr]E[$$:ܟR>d5`l#Jfaìȏ&_yld݅ɢVt`=t^Ľ|q#uiʧquqXvMaSwZO;|Nj^Agw ?cf6<9J} Di"j"/ωXV"#DQuY_܄"ka(~vͺ^Ď<aM˓kQL|Q)EEG*tq;\rkQJg\0<7k*ruID<~+YOgx= BODw(M^szL2+ tuqsĽ+UdgZjYݕDnU戨q'bRfsy@ YH'rH!sj*y$qeJF^4X$_D=ǯuJ]C9puCEa3EHqU++*2=tيQ\7֍v*|:l7~礿kEƯrEm|+W(y<XSզu &Y7J:,lM*P^ }8#<煵M#opy)P, l&6Sr⟕3 [֡zrDHl6TRxRwDV֓:[Ut 'XW'=%jE&um 0&I*3[w9_yJh.VmK?AR!rwø =ߧKɀ@Pzs(%,jAMEFU)xJ{z6_(+2,_`*,^B~ˏi/5ro/:OO- Pp{ {5?\= YD{zǓ==.bfAm&?ݯ>{r[WݓKYa,k:ժ:${ҞݝNNvZgvVkv'q39Ӧ9Sbd}zm\n{ef>`y[gF[[3[}[dvvE&yv"nzͮj͂Xxy)e_dK,3reZgXfAJ۳P݈n,jn|n n%ɋ(]ҝ]y]]X]_]ǮOî̮YŮjή7>Ʈa׾kkk;kk+3صٵ5욇?H0صFv_aWFS/ͭդjFvu~v+]Ϯ2ovUUϮbWbW,dWLdWٕnʢJPvm2,ٕٕؕf7ٕ3,[qxe*2f9,sco ,õ'˘XetejY},}>h2K܄ga߰Yz"ҧyһa#Y, h%K<ҫXz1rxv[vVAv$v|vSUv5 ||6"|;’br`v92].ڳz?v<<<ƼVucgџ];]q]nz];.dkSy_f \j \higߗ?ج|t}89i99s}7;qC^~|{k8n 9|N?[,r;,BE:J,9^ѯ.,ͥw}Udi z7eXچJ)K;ݘ}e,]UnG:ubɳ5>+{LvyةD!ײ崥=]~QؿtJ,aޚ$޳ҺS@ KO],}xoKOvgFa]J]YFM` XFB,c ѯp2b,cuq?cמ;_+7+ժ+ +=++.vʔg,P]Y6]Iг+β+G+]u.gZj59GV|3wNgWYOW*1|j{[vvM^ʮgkص)صZG~k/γ%ڳvAW!gJ ]?]ϴQ|FS v n$FPvuvdv7q)4nMee.}Xf{,sB%IZ2wFS2?bO`vBf2oa7[Wd77泛O+q?J`*ezs[ݚVP_cLAn)];]r]o)m8ݶn+nznGb aAY=}1 NݹNNc~vg"vWovk3;>݉ew2;;6;_F5Cϱc ]%nDv7; k\cwWewbw,kƲ:`Y=ڰ~,5ˊs̲|gYCXG,koeŲd,{N=^6޳Wvoevgv#sd{5h-kWnv߿|?DzEI~oxoQoߏb*d.SzAb:v*sS˱?xaa;v_hFn`78cЭ,|(u }[QحXӏq0.l9\cfˆaLr<{|6-7g$L Cn0}+& Ne>~3a [Ԇk` A`df=~;ߪ@+L#K0dQ>l?aһ0xzڟIP*Sқ” bh6퇰0$H@&-˻´yaw`8|~Rf=`Ѓ2 ~փߗY5Yk_co4Aˁ}cX2^]v€ 0.]#:°x$D'jAl)Ės@h!*D6XU`=~4;A:&i Cc`G&; &¬f0k:W vĔ> C' i,`a@|`Q_ {`^07%̽|8`I0/K쁰?!dGi^,nؔo!dޜArUzTf.n A䡑y$D3_”5!n5C0p }7BO)'8L#9bN#HKD{aLy4<~kr=D 3s < XN2B0#BZyC$Bp0ٻw Q53`'Ĥ5O }8L_+D'\ |>SGBз7b .K/; P 30 T#o>fHhcX, 8y+]j,k iwIf@e$W<-a`vâC6 QB蘗[9ĭ >` o|}`b.VL3ˆ':f0|-#gAa0QG̊!Z?t fw80Vs=h6a,$CJ밶o;P1k5aCX,%0W-0\6,hI{9p9j<:A`f sm*%`U:W } 7Chm :aA0oX|6 s;uzUb,cs??0wv6,pO6CbLX94VvY+`_d2w! pH7] :D871f2!4U&@ϞPr=;tu(Ԩuz@}h [B؆P4h4~4O MʳJA!UPw~T 5RAEn@ pN*cQRc6TP=0ǟӚAGܗq TV Ah9wv1YL$mt$3gcRۘ&;ouM0f LD .}~c|vLއdƟ1ä1>2{r?Oe1! 83htI2&l$g>cB(ߘJtx'je=j&MwGc86,1i8L\hΑULg.@cD4f"qhG|mB19lX;S0%#h\u] bhJ$[eIb$K1q59&zRtcLXO2E&1!{ ͝Ķi&&wÄ1aPLp N`Bn^WĄ5 GLKr\H҈0-&~!;lV}U-~` 8&6yEtVđ_1bL: 0i ;VLXB{-#Z ynab/$bٓ0D~s?LI.T%90`B|<&„Y1>&LcBLY 3y6Lgn#|D|VВ*F'>D&|\:ґ2tHgT&{D}I|ۧlG[017Fadt8 'TxI^'\$j20qK7U{Ll}>pdgZo|[I6fϤGmV^#%I?󼠵BbCx.īt&{KXə;&FWģXe0y;1=d*D?Ec<= M!UĻ#1q_LXA>DwBh\nlO0d&}Ach{d)&?Ƃic`z$C_ tƍ? yO]L1VhM:'ل|AM4܂Ɵ6 1"0):Ť/C8Ikb}/ҵtFUd[yľtu0qoᘘNt!b)w0io}Läۣ1iWCH~ɳИMrw|s)zIB0)&&/Ibr@Lʡ/&-lVMy̘b4N}L6OĤGhJv`L>C'brHLpś`zLn]~br 9C \h &w}0/L,MR,פGxδ;f;&%۞E8ʞK1'߉l@ܡ%EaO$]lic1+ńIU0eLHkfc2ݲ1yC\ސxd)^`Gd7b1ٲ:/n EV ![SÔ~LiDz>&9I^7&&M*RwdcÔ]1l*4Σ =W?0%ؕǍ[p׸x.\:.{iEq]%qf.\21ĕ%+קpq=.4  ZuEb?pQ6.WqM0.6 }pC}e2 \:^p8fSpsο q\-Cqa;s %p^u72͡>ry༒qXs69Wpn ;/ιTD]9C8#Ιsڌ9M=pNBq^cPq1T0( sJZAFz1nBމq#Obܸ6Tø1P}qa\gqGQ8{Ws*5qvWݩ'ΞH[ ΞTg ه8eu6K qs8&,Yn8vRmqcwOX?cc]Fcݮa;c%1t0vz _0f+YI1f) cFn"F_+bLvF?n08#FgK1j-FȜU2FU fa"F.wGS#|Hy0#fc-#{T61u,670b`Hۀ0b|%#0"aoFuF,V#fLj4_gV8a{ '^L>'/19 { ÛܤM)Ǧbxc`Y; N'RW`(;cx?F'1; :?04m?.6jeCsFaX/N.K/`hp -C( 92CNMv1G' y!a6=ۇ!m`HDLpǐc0L1Y >g㌹=1X,wu`vK⌽E0;1h 0/Qo9ΰ3VMmAAϿv0ȼ&V15r^A5a/ &`J |/(obʀi?dѿwoutk3 (=\ɟEc1u> 8D3xLE^À1`dw (`@V0ǜ@OF:Yck l䋁.adD 10;`4p5?A114Q3[H8c|\yA?c68:@fp4 :0pG \Xg<؂3V 1ȳ .Ae`Pxjnۈ#0 =65U0ʏK/d 4b'ڇcJdjbp\e6H3*pƸKtUA;cОAA9t0^ *DOPx2dg5ZaP5X3Ӈ` |쇁c1hXE \n`P>jAaxg0^臁˄<쾍Ĭa 1#:oZ%11 +Gb`0\]1T= ~݇A~_``j+ h0b~ [/Vc@m迭| aI6;c@O1cMo 83GM^1Y8}+@oѿ'$w0['zmOHB5e1!$KYezӾ[I&``wpl1x燴ֈ]0 /c`|]•7]@ ߸ͬF4`@)|~5bHQ7 CF0x ޾ f͙1xYxbpDy g|(绡4%PLCm!}#0dc+s&!0CkcWR0 ߍ!Vbm ؈!K`#쟂!faH8:U#l?bH/'[t<l M3;_b%?˖_ ٟx1mI*a+ҙ*1xzt 59a@lcR = [ƀg1E XMV /z| pڵ8k5NoW n2y=qڶ8m N{vq4m8)65i6qjG bN+RiSmFqʴԪd8li`&}l/}߉E8.!N D?ڡ_7Ckj~W {qk{}<|Iv }B.؈{7^E__DO74<(EhȘIh }-Cзr ? 濁aIAÈ-h8 ?4Nc<Fch8}nCi e'#̗ R}VWDuvz9盢OStD_'B^>^aVBÞF2PFEC1Z;o*נO)pT>ѧJރw=1z_}>^D(@}k3zCizFGѻ':Fz-.^ޠwGPw^Q>=nFΨ/Qm71-P3=~[X3WsG \? Ƃ%fGI8z/֡Ǵqp(zl@ УvOxB_ УzyBckWK_c[E =F} =N ~xSוK6w z$F1=ڵ@Ut{ @mit_3b{wOMCwG^7nY-5Kѽ(@wk47\FyOAct쁮cmZ,F@յ5g[Pt[ E*m]t7?nJۉ.܈]mktY] ͦ\nWҞ^ csto5λݤ%6<R@D%M-%JBׯ4W=ԡ[}tsY^ݶN'zLts Cm[tk\jRpOs|-WYtO݉ni8t=]]BWOt-]K2e݀.[nK][t ] G2@?5etCᩇ.We]Otձ/ˣ?BWwt AO{d~EM'f'~(˻[ Ds"^GieV LFuѥt.;e!tɦ}GW:h ht]Ky4]Re tJE tƆc=:?.mbL36Bu8t9o.K:㤗pE!EcybtCmq@t.tˣ+|ystt;cSڢB\ ]ˀ]ZRx..mХat){]½e\tٳ]t.%:W-Dsr2:(γaqt)x2ৠRz.3Z˧bOyzctq4#y.NRt.ס䨢/:gECy|SwOggU/t)_G(Wi+xX ,uk?t>y$d :mQ7pRBt'^Gct7s`&N3'EI#p8>t[qTNY'96IpҒ\yBйtt]Axt] .ω"Zsڣ[#3 ?Evк#}}[6ٿ]ނnk$]kb3ݷC[/ǽly/@6z5zx2zLfѽwW1끞m*zHF6 A­{KF6{{޹>c2g YBC^hX_ 3~aP4DS}[D wS GЯ_a|S'72*m,'vNyi8kqS}r-:q!Nڭĩ8h={6mq>>N{ ,kdc(o^:@Wǜ`p [1pv_ʩ~Q:{%Аb@cMX g3&Q>PXHy@(o!uC0 Ϊ!a҆򉀥22C8 [Cw`ȴ)Lt !`&;4Cm17LЅ1i ]Cϔ71 k 1'ðs1XmaIv Zaٵ0̻1-a30ܼ&axnv8S^! .0ܿo/`x-ۃ1| tpfb83_AgT|8sV(άFQ94NqpA83B?g>3glpQ#FtǙ1z0|Sƈ0bU`DdaDR FDĈ}Z#a4w#ˆ0bacb1Fƈi}#1DF?120#bdZ9vFÿad`l{#%W `y+FƄc;UFUQ FQOu#FO1Z~z6ƨ=1.1zhoʩQwcTv&]F>Q&cTO ĨSW0J:61^["0*n0=hKdby FWѽcTH!:at3Saݞh`tuF S_Q/`ٝ]$`t=й3;Fk`tlom"FumQ1i< 1r4E1rF6.',1rA8{1bQ9~8F,qWb8#җcĞLEq#ycD/L9 "%<%'y,_Si=IK74ҡq{4G㓷dc;1iZ7;O`ҕe1yNL7#^b)5<0Ů; h)I1T9LI)?cJb\^./݊˷+{вb+=?y+npeո2W^m+߭U㪦q\5k聫nե$Zƕc2 _~c9WLY+B0eLY4W #0e/8S*0%q.]`gA0&7pe LWInw1)Z)?cʳNr*ل)j-0eL9 S/͙rS֜Ɣėg1LI8)'ap: SRL٭SvŔ#1L9FcJaʞDL9MYw.SNtvSV9` +)SÔݘj̭;D}7Û]uRR;<ÔƘEw)wY3f {]iwTcqjg^8\ǔ7;#d ]Cr1eWڞs]kyh RCO];h̶4ۢm-`[mѩ9E>}]̫=+?=+h|ps/txs[yMim :mmL-pbmؕGW"厮]Uw]`y/I0F=|N*.`qqx>iO*|&*MM[.ѼʸG|xGKIysTXUo*qOe»{qxG4 i"!9=c| iὀ[Uphx']6E]g{[Ay8)=k35W䕿t8ˇ>P9z׾H{R^|x|c|_gsY4Z;cmwuTZ(t *^w^?*UPpBg.yi2q3 gN]=+_q"ʼ&Cr9 Z4k2ɵF#oN9,;58iz8+J9+~w:?7Ю;_9>M68-'.>>Rq ~B!5=3 LQyMﵻs뵽59>Kql{N:y8~_O =V <=͵EM㹶'??wCqN7燦7|v6{Wfg8xB_}ͲU5~_my<<@qj2-l_<4^sMmEx|OAytpߧNWhq4k:G)p|_ N͜ڹ?cgw>!ww]1 v?*2~ܯkwɓ6Ѣ ⽩?D;_*N6J#aTw^f4:[٪U4B\/5l8Q <_铰F+#|hg_j~{sZdrxeO\5<9Iiti1;r|BYhw{&Ek5r7m3Csפ̋]?ζxi|a:b\nܗ{h9Mr-v4ij{i4w^%BëUmo-71Cíźs{&϶jjN{qÿxsamH9ߛ!I8Z Οyf_3YO~"65r!o?w h&|=͔& cjpZ#FRѻ9 Qk8!rB׼Ֆ7yNBr;$/yNe/ɛy4,~yqNӭq0+o_G̛Ϲ4_ݳ12m^4YSB}WaxYOA97=v_u9rqSi3-yN]/x1K˝ߢYP߳j8sw˟y.`(WK[tlQQ^54M8=OzNܽq \\qmL[}Mϑ;ti>֚MN֔͹_Zm^p Ty 7z'[ݔF'`O7y&H1m <[S=+sb^q`:\3?UyY5ه!h1+)mMΨ;{. 4Y?4>܄?v6>ңܤ1dҏ1=r[ye1y|ͽs)ٔy>\2,,#lNí+i6&o8zV?G)5s'oZq8mp=5:S< SátߵҩF/&^~m ES&C!)=wu Y;Λލ&;|_G6]GꞫ^Fqh1M;/e'Vi4klXw^#hkkJ{f!{Lқ+pލk`^;[b<מs!S^ڰRG>WVTN4z5>o{jc/rmm_Zx[O<vyܚS&ϵ&{ꩪkQ?g3c_4(i~`j5lv7n/h4'09:ܸ擉?PMͣS;6ھZNvS~s#7;F+[&aK5"?kMjx5>;~\ÛL>ij91b946 eF52#5w`?"70ы\;7Psܻ&wT) ?㿱u^20.x~ja.Mʜ5ʹx4R<ɽ2F91$-V3ߗ{3ѥk6&&{9q. rX۫95Լ|6Nߴϴ`CIn;*D=&g0ͥM[h§1y`kLhؑcnw\<}ǧw}䫭U[nmK5_bV[#StSZn-lku +19퀛c$fm<=}^qSEp9:&`3ꊖ;xz64g6˶163Vhݍs{ѺUG(89,8~uF.^MGӘ:Nϟ(V|é.Φ)`f_˟M[.VpmABS?gv^\pڈn .&m&{SL=Z,&hiCA}i/N}: ũ}5'qjԶQK桎ym#ߦ8:pAVMpmS U)*Z# >g8m~*|8+[MU>ؘQiÑd<\UP܎ ٩mI3V[Ko6Aƛ=RLU{;y ]*>9Z:\#ܣj}ZsjՔgFPkH:Ok;Q5cQXR 5ޅNtмd2?;ھ=n?g:hBvvy{ x T}i4ᅝrS> >R=&mTWzwK8c&|\cMF9{ۙ-9G>c>_>3HߦQI}Pjɦvp>,>o0#H}Pqqj@g+y>OÙaƛcy0|6 >WeksgT\]@%LgMo2Mj>YD죍* 1j}>j +븯{QnuA%n>^D]Lc3w4⓪Fnx-[?k[hCFc3ET|9&thk* ڳC4LΩZD-Й^k1*M Mz7u}Խ%kw*ȑv'Uuϵ^j+"ƗV)3WUέѡkNis49&c_d Ľ]29OP]T,nsy4V}.bgC{U\TPuǮԻF껶G3/ˋD{l\SگYu.S‡cBq긏:بlO3͒ /\ Z<דMmIIV6뮮yno6H]Y+(6H][>gbMyP|+Fqc#OQ)mO(WhK1m[R!ӆb6#Fx$Nj!tT;`[gWP[uC;<8ZP7٨ T4XSZZrPY=6>Yg6EOV玛d%nmIکϥ^wznFKqP[ҙYɸ?k'Yy)m:N2nY6yu-曣j\[wQP1aW7<$\FIOrкZݶ&hGmdAEOnMif9[Uw0 uju:B}ך&dU5w9&)\Md“Kyr(*w}\ycԱwyX*Nñ:U^mI3H We:Fth=JSķ j N}{ [Gx~; 3:ڍQ~gF;&kV}mQbNs=7T*49[:BoCšWz^=qcy:^Au/ u^/TBXt y|CFqÈ3s/;ߣ΍PΗΪ2rV3Nf3LJWMgrECnTmAmfo9͆LSAܻꗶK+ ٚcjjG7{d%v;[QܣDGrzw5=J= MΑܗ2vN_JNfN>Ns.NβS{zTԔfhnMZXRMmXsV66UKۙ{#)Jv ^&;ܯNDNibciBvQ[v+;@q^GvBv4SvYMvLv$;+;"\[ȎAdaEeNdG'׶ا+eǎdٲcQoKYkVppp,<>^vm.;xUVQd4!\v0e*ÔaNvNS~vKv_ԕV7 }7!gdZYCXMdmC ve~e;&Nv0Tc~ОmdSAHvleG|$L6Em[_h'.{.;N N=N k՗;'.Xh+;-+&;&(!]==zR?Dyv,Cר5*;uRhZ]-dyI}9;9Z3}־;h#ؠkm2[|)wro>wQ;~3@m#gxo* M'uM:V}Gq- ^K]~xӵy}o]JyPsi'{iT~ksWMgMR9YQGm[U4dH'~͋=pWM&iK&x/ɹ"? ^QC.Ԏ5>p=즴Uihs_hZg6uoޚ԰ }uEhṰUUpSÓ{Qqk罫9viwwOrmX9hrpPγqosk4Xm?h9cﻦ㚎h2M0IZ3aoZ~}h#*ds-zd+)v|k-=Ѿqk0}An4Vxu[-]`޻ߐk}4i~;3S~޵]:n7dRcʘ?f#C~oMzyN;wwu^.hjٶ~ZYf*TTu664S[.鰰/LlXgVYcY&Fï٪&vP1uO~s&#*/Lxj.іƇ>SarmK5[ټ &i>V_#WVmoN3?Rgᶯ_ѥcR;~9㏀ֵ5k_DiY[ m;+fG>[[b]^󋱕6=ְ\_o۩3׭&mmǾsǛ{l;8 |o8۶uŶMr۶o]]b=u7l%W37'(I|o]4`lm0o(gl_c!X{WA`8"}[zTI!OFZ1˶%-JoM~M `-4̐~|+SF30IxdҷgUirPwJ(}sGt&]̑~^rN>!}[J֔MgW>& xmysW|RvZg9{ G+Aүuפ_%I ו- }q&l(}ߔ%p[@*D^eToIbҗ{/å/!/>olو~{JrRNTc-;6~ffHśI_gcrΰ|FK߾|~'}kF$Zm=i+}Ul-eTpz* ؏>)'}qVGwYi@yG'2,Hf^!嫞!nT|çgһ=߄|iQVC[Cիһ;ϑ3-X]U"7ӺHo]ެ,.,i3VzU2&k]m7ARI[қƇ+<$rDrq94Cz"ߖ,=WY+-B>k*}p'{NzG+{|[zIi!Cnd4W%ގ>]n$}~!}vZ(}LzK9-}2!:+Lzugx[[[҇Wv'?Y_E6cihu^ =%H!rS}?wKN>%}:+d^mI]qm3p?GHٷnH$3E:˺Xk*Rv' YrS=E"Vҗ+k".rK;rm͠p{R~)Mگ3~|ZZRyvb zZHfof|qPnN@×S:,h8I[|w^رJ)da{O>$}E}2'r{=g=ZFҤWma;lLLO%'aOl+X a[b<\>gK|eWI\d^H߇ttMȠ`W Ƿec|q&zX,ߣ̼ 3Olm˗VY3K8f>"o8 c3YTk_.I,_y?߫#ӗUV_V뤿iKXIYR]Y>blbp:3WLM)]fvu3?)lu?Xf,ܶ0~d70+,̼neEsfYfVүZn]*l'J&HSę-2!F'f3OH-? ~Aa]v*.}(FSwcoqB!ܯ|z!K_Pd+;V< _<:_ӄҏ[5cH9_)S_+2+# <% 7%DϡYtRBRQV)++w;:xۂԳ|훬m+(+5#+x)+64aޏ5}5؞5ܳ555^D`4տ7)j.jbu SZ8*Ғ5fƚzeMűz:α:GjJGXaƥ~g a ְhd>'cM ZZxcoF}FƝ3X#1%j|br[&EveN]aC2)c>1)ew'7}:}(OdfQr k3(Zj::mX!X~}}}Jk&k=ZyD&kլ ksks}"kk5.~KVršƬ1f ]-Z[ưY_Ź84.Go6Z板džƯuIָk?5nݖر ]ʮH#K{+ JKD# e#h,KЈJ%_k41bo޻}x>{ܹs9̙CEQYӢOcj;協ca{])H>+)" (j;ר(ٞTIUT)B(Dʫ'& 4SkV=oKaR)n3 +IjDAzY&]qGG)bIsB$SR-9$ɫ%RjQU5nG!)44-,_I_荟IG*u4ͦP ReaRjf I!^(8ىgPH($~)t|b3?ΐ2T=RRI[&~嵤@ Rک) _@cC(葂Ձ4DžoR`0򗷢O7㮒/ɿG-oΡ9|ch&W+I)sk0{#e'yj$ޑZD ŧCGI$XR\mA)=I4QO's']ue%EӾ$/)Yu<'y(?[<ܿ=K|i)H"s;2y9J>ߓϰ'my.%ό 䩸M^nȫBIOTr?On"l+&.ɵjā\{sv29Wz&:ԓnrsnG-k?M.ZKlI%e49jGJAwr,jOԝSӊrxuN }"ǘ\j].erIqrHk0ڧ${.d3U5d?xTڗf$;jֲŬ0Y|YkQhoVxcj>YTβOWH<:ԛU%8pu'ZǤX,jl>5YYݕXGr+b,q&- p/V/|}ZfS:TM*Iv55t:)=_g XFN:QrNu\Pwr {g½^:ǽeGߵܓbk/ͷc6CaGq-m)jR]ssߎ9lʑ| D敱9U^dN%)x}3?㠩sas6mcnw\&cα+Y%3sw6 D`{X2Y8"dȁ)\ts֭8Edg^e=^,hF(Y+$c1gkk8֒g+؄,nLoǾ;Mms%Ɲe &bQL+G(W[(yYWr(a/t}`dK+@}<W!,~zBco~ao1&ø嘲/Ɣb$W0gM$,\rX# 7FO^L,wc7}hj 7 D,kC .`^R,ŒIX܀|,: }+Ӱhrv ?Cfz;ku!U 39@ڜX RڳMcr,PI[jdnJjm2jm ir*G@+oB>-u!6dWbUTNqXzf"Hۛ~Ho+`Cւg̙/!U-VΏYAYX3j R޳Λ͎k4QEfD.}04à*A Z([{5C_lh[A/y}al:'Q П@;96(hrY! E a !akB*-="! ;B8cwx p ν19gAtǠ= k@E[~:KҘ1>΄nWZU &Ø z?N̲sȏ?d,[`j &u[z讝} 03n0 (DS_4usދ|gȻ%w`n]~#{G &ĵv p?Ne$ >F`z 1w`t|{8L <U#o۽iF }^ȳ| P0*އ/qs?lC-Ża2T ,\r{C{|U n¹]^}Lu( LFq0y;vh ĸ!Yg hzt 8nxh2i6.a*X<翁=rJҐTh'|hʻ@h,+hvA; hB3Rm&b:oHy+2MwBkdM\o}Ro薨 W4e42 a8w^ vХE?߀/҃;f`"`czA0ga|,_ !Bz{w06w3C~w" 4׋" +"SkaX=Y3C9tA 6xÌGm߷&IwɩLjSgQ{mP8Dܣr u'ƦS!x L Y0rr6'/g5LӛBv|':;{qvb~)F\~9 ;X Y|CE´xB褃[<˞tB(кb56աpϾcǺߢ:]c,1XQ4FE=kDX" n(" JY`QDX (F;j޹yܙ3s3s,ǽIGNuF[BŔȎ^coj0^7(BjPoBAgt ȨPwG@UBw@|p?f(f9iӁ)o(+nZc=DŽ~ ?}. TQ.Xw oAoETo{@X ռnDTlWD yDyeCQAe-E"G4C'l(@LUCYe}eDǐ矀24'(>^`]"l(jGQOG駇v5D[Bn9t/:_ނi TBx b[FM(jq:Bɑ=pVC.kL)-k3avjHBXuq•&a >:Y81'#l[3B׶rⓣ4B.!~>Dž aZ4Qv"|b* )gH2hCnMMe!XtH:YRFShHkGDW Mᖨ0[Jc.__rTu@7)E#:G% (*_EaF}ү!'g9v*Akш+pŬ/Q9ʗ%(3bp, W[Q1 ˹ _i3кRVmqevBG4?níO<К탖hgoٌVh^NhGn~?痡|et\N][hA0EU 汨? KoԫkѠMtP[錺P7 !&;aXW C= /]QWS?zB]`CJ 3Q,AVnChԬ}h?sjKP~@} %KА=P{w8jj~꒗p䋦)P{˩J4[yTsxhNAjo/hjܐ͑RRTk{9MhFGI@X DroH>)\gR!Y$-zuٹ!$}[ӛ| a?"Q$l)AH wQ;Ӳqy/!;3"^L%qjSy脑'BCDF@dg>@dz 繐ٸU'9 |HBAN/ _񲛐pSy&wGAlMLl7[4+@j;lT-iڸ43Aj YӐߋ|a0gCV| 2\zs֜)Ro"m;#߀ /k0=!sE fP,JO7(\)QP~} *PZB)nj4!P9s|D5}Nk:!T璡ZʙK}uPNփ4@a AQ1V`zP%Av~!q,nܼe1|=9 y(w6S#4نr* ޥCz'S)!@6$RHR!id@&LHK0gp`(NL;$3jg&&RW˓|d@U{@zK]{P|ki0`X= %O}3!;Νr7;AطCޅ\+ؗ-}@.T@(*!+ԊޫX݇TAZ@*H=:i=IIvY ihȾ ٰ쓹 )Gy<$={qw5qR6GkՑUy Hv@\)Y =?S!7o$}HfBM$f>ę_B:^[M0L0L0L0L0L0 t̏!#ŠxYzYeY&ޛӈ.!^@VDտN&o'kOֽIu Fljˈ'dӚsdds@I@C7!9Lv=D%٥&j_I=ϊ8$:x%}Vw$BȾdNӸ4ccEӡKwf/!G%G>$ӳɱsȱOcɱ$$0Ò̩$0&ZKNxnFw-w" ̙K~sF2Z(F1Kxcx=olx=N++4#I!$A6$0{M6qד/H, ?<ӛ!AtL r+x7c)o8 =ȷpu'گکDD䴝ׅv6^L#NMFD)EWh`xKy%B}=`;4o%ʝX]CTww~kW%/C׈(m_Msyׂ~oPx]n=t%"ze=_SB{5`":dɿ[({_NsOs=k?,?SJu59g{`@>>gsQFDmF^٘l;/u--v~QZF&"/VEwE\ɐd$@.g\tqZ49zzum>qx~fB.elQ,s8fזqcw` YxeXq]ror2K][ǤЎ簿KWm\e^RJ~)UJ[1i[mi?.N:,EX̹=ooJlN- GJY2/2,O68CUwR_09G`R!v` 4nj\&n#$C~yo;uLLZwr^2{Na=/1o'6:j^]v#6nW,5_zTqzvzyrN'1bܷR#Kl] fU2jZ"_N3yJ ޞ-!82jy("< 3gkO!W\gmפrX`œzTk* t-&-%Ou}`vsؗkRCtザ~'R^#,coǺ54_^+L7z?ITۯk+K$]`Cy,\+1'VkV 2niqPB\V=ōr.W7ֹn7[ZJqAityiROëzQ19^n̶NYU3ggJ1Xpn(n]DVݨع9L/.vFfueP1kW49Rm\ҕ-4]ԷǴ\o'>ڜP8f/͘?|!se8Ye}dԜ['n cUӮ3I_KXkK+t3VH_3ZDuVO=;[eVS|N+rj5wgV貫囟m7'epr>\Y_eO:k_?9յ7Z,uZ>y/r尭s꪿.1y6x{9 3^5_I5iO>ix<\*c~KC}SK?V{&y9/$\c.s}.~ ;ǫ=uw"Z. Kc;gqB9xIM]yHX\S=~1j[>ҭrp]j䞧] /~' eT{nǜRgGk5}7D' _$q۽QY/.~'~uH-Ƨ"BѱPw׿ջUhk<]6J]]Sxw=#5=59]0_ m6/kN^oL/Et>2Շ{.Br]LyD'l<{-?BtF3/YϪ|(bQ$;љc{ūik8M/ƹp[u=H`x'޹(W=oYnz7xEЙgoѭ Eޘe5:.mʵ+0ުm]%Rxk~$_R{ZD_/~zC鱘jŮ N\jc|Wk}x?%s`XQ[+8Fݡk=ï\Su3o\9j99w2Q9b}cx7cExެ]KZ?~W{{+d3UV} NDޖ?sp'mM⇝\p;Y3tBŵӤ8Pġ_'{eG\R?`1> 죹ᚻ wkzo"b.]{ n~;nL>{">ykXhy  6zW]yAJiBV 6M.t`Ӈ2w|9>x ÅA_)Ɨ^n`㗾6޻U|hU\GowL_s{Le߻XDqo~ғqp]YSq]&Oq\٢+PX=]ّ85+˓^>sg+鱜s(;'=?{W\xd= װ<.ܦfMxɸׂ'ؕ>7{r>+qiik,tOO'x'x'x'x'x'x'x'x'x'x'x'7J%<O<O<O<O<O<O<O<O<O<O<OPeSגPT x'(B"EWN@h,чkogs_P$U OG 1{p/q3B5c9d>v=275h.@WBdYsc(Yȸ2J̊ @M9-d9H?Q^O ܂6!rdL@r?4 E3=~iBZH{Gi #iH}=^[!xmtNGO~y$07HIGCrܫH=GBo>$+'u ! {K$}69"B$݀@Hz%R"KހoҤ)r5=3 )"^&#t[c4V#x7#Zށ蛆 \L HZLC 82b;air-]+N"OX=]H^C`twڽE>LAHF45I~;6#ih$G#VH2ct5mI$!Y6q$6܁oG BVU?#s'?IV¿b(G𷨀?yklv{@^^CiHxkJUU>Z+!K>: ۣ{|ͩ&'R5ju)YBT/?u$jd7jY VQuFu ٹT%4v$ɧ{sޙ*QEE}-M6vݙ4+aO:&=;1>gs>gO' LOc])8|ZC{M=!#čr}_xz=5'=Qru'缱mZ{ꯁ"^Kn"\dQ㗋ڿq 3?Qm/Fx7N!4oo FW=j^VAB 0%$L wOAŒHx"Hxz$ؑuH8fc'< hׯh7 hqQ>O80@>:hݥC@l,,kHX( bw͠" `+-v۟}}wggyfv@p8_*8"擩J [SuK**$*ڨ Qܠj{*['@s-[dF|rT0{7ܲTUTЋT~ nW̩xdwR}2* LeQb*pRF+@oe5Cj$]yFFVPA^jR|*5vI^k ) SAͿQq/Ox"XN*R?AxU 5^Gxnj՘[_Ϗqjb &kZɂZj2բ j}$N&sdsjxJMը 5 S֟CYVJMPSϨz?VP3Osj6ŞYfճ 5ejYOKj{鏢fnRӨi jџNMVS㌍Ըv8hW#Mk`Z\=K&*5~BN:Z::Fǣrhq\^8jݢfT;ۛjQ3EJChzjϥӨV3j{ͨ?V IZeBQYztTz.Zkw_^S:~"e=^# w( :Ɋ#:q*iw#{7O/S8:­WMptޝèFZE5PTs`ijrFոYJ5R'H?jR -SaxLGR#zY(UG UIe^S?TZ)jVrT-r:Us_A>ea&ft؊TuU3ӣ ОTsU3Cӡ,U9-to:vUEU_*iZTG†oœrM#UnYTy1\E<@|7C!t::DOج!z%tpK6צ ]t=:]-꧃: u:h:K0w[āt:p"C:-]с~ tY5:3 *;7SI)` ɖRz*s% ;Genݡ2t}*JPMT:JW>.[5RmTzRTjQ=JRɟ%V$ߢe>^G~n&._=*-U"?;F~+ ȏ;{G}}dq '|o3׮jkz//tW _U||nM>}H>{y_g1u| #:GL&~YCwKȻE=Ý䃸|(xE;hw{c{Nb@} J){JzIO-{/nLz'OIo}LL 㤷#=Mw?靱|CzHOճMd-t+'ݯ_[k}"IYDVptABuRt5$eHgt(&H0-H:6=3Ig;kHǮP9،t"4HG~i!E:Bäzi/]D: 61!KC;|B:ªͤSEt؏ޞM}ai?K:"JIǀb! &#Μ3mQҝt'ݏFi]/5<9Hz9 sĂȐ^E1?x '=0#/23_cHSU3| 'q)^CzeHO"P.j˒N;'9w.ג88%7HiһH#靺*:0Ygt;+v"Ƒ$fuғ6',+ɵk9N#f !'鶽Fzj鵔cg1HOĿv_N'fW+y XO/&CKJ#]RQҵf;>98Kw']q9+~9Tҩ@:HGb=D:2 kIr>-ӊ5v;q##t OKH3SXx:q~Ǜt%C+tҾ•t\'y)}nE:HGstSg17Ř&fU%XٓlLhk2"Kթ+.tcx^AXE,VkLj}n.Ŋ2#] /O."]ǵ7 Hq#eYL-&]Qlɿ<%Jl97tOO3ސξ3 +5c<[16.śwx23逷cQ̟֤vk3HUEg"{%y4ر"L>G.G5p "y`O|I}Q:A4l%U H՝~bR>i4lMI~RH~%ݤԝ~L'ڒ3N6JjF&ՅHU]R==T?HjbHdR}T$#tI0[RuyH~&g&٤T&vwIՃ^RTl U6IeD*w%&sIRY5ʧIVKRYTm{M*+rYRel{ TJ*_k3IִH՞R%$UI R}|1D;W#΋g5vR*-Rf@5I{fk Ej%5Fɺd-LR=i>v;Br ͬ?@(jJkHV]5+CȾ]rdzvTe8}&UKH#sّGjTR54T5(1;IոSr $FWRG^`Ա Tf%1<1RT=K*zmI8C*4IųrrᑊW&TIŜϤb{R!cJ*ċIy=Ri3I(CR)0a{0O2\sH啃*TC;tRT2,].7kHԸƐ4RcޗB_~RfypjNj&0E1HMR+CjN|RdCjm`R+Z8Ԏ&^N!IOjHͽJ8qN`2-I^RsNq?OߤHjj3~zTų%Zd0꺶<~ƇT;ؚf6n'U?7TU+֕gkfj? GPGg_ /c6h }T &5EgMdX7Ounu5#,abYcjg\]0>zZP_ol;^=eU,w4ljcR:qs&a<mbf@RTzTO`1_.I'zjGMNf:&1ݪ39,N2>%?Ob|O6_,20W2{gX>Xe~!~r{6N?f0z:dB,v=yƋL?1kk^T+ev\ur"g7Ter#wrHU9qΑF#L|`GGbSBVv?l̆y^Ur[sp9!3,mE}RS^8VGj6!57ګ͘I:GWR7I]&AꏵV1wU!OegD V 'iX4xƨq ! 9|il" ֓xҔHf% ISVfk \O#'#-I,r=iv鐖D;ҪIZ'y?HkM&Hvi_Fl#m[ɃoÑrР<"F&.y<:<<F(&Oy>: OIynymD|9D>s _rW` jD&˯o5wt-Oo|OJ~ 'E&qٜp%d_҇=Cүp8FlȯZ o1A%RgWaD@l"XQOR<* z@4QiTZ-J_&_*0ofcg).IT: ^J;*#Jע2\ L2Wo*cs\Τ2T-)/25*Oȣ}(OMSFePET|3RM?(Q7'y)5RٝT͕U 2[wn*SDyoPMGJe5**8ʺKTvu1ʄQ{NUPrT`*!;Nlݩ܍o9e8P9-T6B} TμѝTApON>5݁OJ/T~OIꂩ\*_;/u- @凾k<5l#@ggcfld*ӯxwPKyjo_eߝT~Zx伣'1*5ES9*aJe˨Om*|W2n{:yͤrcOGce*ތyܳElGy&(oqQZ]{C2:y^!]3=eiS)o`Ps}Ay(yxEy[Pޒ18\G =Cy9c)i%+N\fCP 0{7[ޛ&P |*:XLdc-2`{2i7F9Oދεk)O,3|=f{ bxNy7h-*?ok')5򒖱NyeL*=}ƶQ*?l&Gep ]Me;g|r >T#{A٘f1v*[@_QbK :sRnJw*mOwS'TPXt=3*REiUϱYTɻ*'QaTiO4*JK-=>T%ӧ*UQ2':@3V7*tWt" :PIJ@t|:|0x)tn,:66.fAa`;:xx:k=2L~0YxYHC"$tw3lG5PeT9;8-_ͨsT&U©b5PCCQU5U&CU:U}N@Umkf4-av>tؒCڨ-&0tXZKU5 tc5K@UW7谊TM8URa9Tm03jڍCT](Qi U_BATUߚN՟7RTC,U0j15T >n_EG YK;OG<#H$:𿿩jHёQ (tg5բTKT;#}sJuTյPr>&oLzj$s=sT_Lnj}SjfJ h#5FQ;ܵNs0j"50yKMeTɂjjjGͬX/fjCWOԂ]RZ.F-uP˓e7zZֳRljcy\BZx ="(*@E+Q6n/SBmSۖ~GP5Q{I:4;SǔL]թ9NQZ't:^A]ԨECiG"N]f[Q1.o1uɖ?S*Ch5*OJ~vQ:hy~4V1u~G]멫u2u-hum@]XcudNBP ٔAP)MY6Ӓ͹FWQekN].SWGR{)KP+͌:MIVT:WJ6UCO)P-^JP:#u Τґ<נ\Xʣ!CRk]JSzs+tպOi _PhYjZ:~BhSN[ v+`@mc5m:j7G ʢ@ :OmJs(m|bELL4M$&i =K3Nܳk^s\b鳏X~ 8bq'X zM1]Y@L}59,^ `3>φh &* z"}(sϡbsRCO[Q;fNM#_@|9cNU7~Q~Z½yu3{\;W{/ҙMܱ WA".3=Klv(rq)DEdĒDt%FNġ5DfHsX>!VQ i>, H̏O"BbZeAL.3nbz"YÉ*"T!s݈ 31)Di//AtdDіCԛ v#ədP UI$rN|yQ#ٽYaK"sj6t,A$W ȐcψtBTe5Лܬ%r^D6>12͈d72p;2H?JM$S&"-r ʽ^M[3O?uQlzN'vQ|g$qz٠7 *Z4%3/2qQO8.mgwY~FjIo"($-:P"+=0R2ru=xw6Ү}MN\NF[ mV)5uE oQ\/i"N'\%'庸oDz{ f2'?Os 7\i}ܜ\L" fۃ3N,R] x5N~M8V=(鵅IaG]Μ[r !DnV|q'cyD34хAb~Wݝ!P[*rX/)h't0j߷[)yEU$*J|%y^.dELY2mͅ [4A͡KdOcIrMBZy"c%!*ƳӊJ嬊Le|*Vnn41vho~hbK1.±Eٍ%y% sdgp-Lw v>U$W2RIQϊ:Œ7s$yK,>+;Q T,\Vmx^"~J,H-)ג_+ )ҐpvJ1'T9_%o?IrIt;Zrq[fnQw$;6J&*I~J..X'^-,v9|zxAQkR 9!9 I^vq|gr.xUvEFE8f5M̚Wbal.g7 9(NjNVQIO /}ȍIig\%>rX,7gਯ\/:6Tzvbp8u8y8IxskKIymxCś'WT嫴?m-޵“[1gWxj9\Z~n׬ܔ[EW4a$zDcIBUɶ|iɓ %&iqvE,jSj%K]lWLskD"y*z%4pot8I+ݴjǤi\Ot S\/}g},0a?xuuE+oŽQ6{9K1 JVJfqG w#W ?)\#RW\}dX6>ƽlZIl||94.%3T@ 7\Ʒh6 .iV|׻I(%Eyܶ\bO'pjz܊ /w )OĉDG1( D&OF?Ftd(b/O C"&CJbN+lpb޲X!.gx"֣mkKF:͙½k"%IgC>xM%ZKf!WwĻxFl5klB[%GJoqH JqA7fO''w1 nShbTD"NW~O%̸$I4Gzh5aO[$GAe0.'*pPwb?wd/c p:8mH!_`:C(pZ߉wvMY8&\|Վțs⠠D~hׅ<_nQ_~k(Π˨0Gi5qMEm-{ܴ_4h?g4zf7;Hv+:쿌~qR5ǯm C8e2NI߁ 8)|͂0MNÀXڙ81*uY_<ڇbNa0F@)흋SW?~'"4U^z6zˠg4:m!)̡}y-F{~w}DZӿw~\qj'D<DZj8k8j'gX)_DL; Ǯw>1E_ fqkƱ%,zTf:q ϡG*MEwN BZ= eE͸n/~;:_E5(y]:Ub9ΏD" :xtPN褳6BtWt@gI;:%$t|q]Uh:Ġ] @D?vh " W6%.NCs}hr*L"AkP )3Q( k8_6wM>ZmC9*̊@@4' ڱM@١hmV3bZLJ@Khj Zl@%O|[9͟y 4kD4 LlE34[z͖@3OS4fb48͎yQh6ACѴ|FS4MU4toX&XM=94d~t<ekt4=M<k?4f̞kf]h6 BYf{nٱh*Y94f5lj4/fhgs4k\Vyb4ێƠhFhم[ 4~o4{ߏd&c2FӛhLMɍd4i0D!hrb\&/dh4E~}WM&hrMI49&vkkjDhXwWvuD`(pE7 AT4eW: &d υa`4\SG/hxKϡaV=c'{4T'5 e ~$c꫿@u[umZP&|<:=|O@A;]u#퓨7E9^C݅1u'n$E{G u/2kE /ހPC}?1kʠV;H)tDA7&ȣg/}{+@-h注_DCh6 N\4(Yi.4grcP_tکzLPcjCݽ^٨s")AQGu&e3m?|΀R{|[׬F@ ˚ _f _]|u75͕A+-D~_ߊvO#Q?ٶu!۰s, _$"^S80ھȯun@$gqOJ8{#4hI "?c6#S<- Ecq'  fAn k:7|C@Ӑrk>;俙pWEm˧eu櫢Nԉ;:3PgW ј:#*:sOcsu%Αy[:LPg'Δtub'娓ƞ{Pg{u̅tu,RPgP 49uXi0<>v3\u4`Qd6E?`~^dA~W1 ft-'#;~pw3|d]Ceu ak0_2]n2U0N5@[_4{}26꾴g/`: O~B?q"R?q;< hƝ3 cu1>A]ޯ$dԍP:YǑ3 ^vӁٞqͰt8Έow9: Pw2N}-n,O%|ra=]:Q޺ݨPWr]mX7'n`K8ӵuk -wm@t+zYi#G~.k<ԟmѨt7=E4lUFhP_A|fye4xh(FYo0NG%p,]Ahxd 5쌑E/(4Ѽh4(BF( (i-GoѮ _Aht B[a4:3*_Q>nCp4‡ht#@5lw4zG?QԊa(te5 P兂93QZ(_CPν (ُP;P- ~`)[/Pp {(όC() J(Hi(8žY_KL $yV"mDU 3έE56;WW:'MGD!߈@'켗z&hr'M4I6E>V|f~"V',w(_Y-S>dH4g54I\w D)|%/ 9hDGJV yn/fD4LDhq-D /P@?h^{ٷh+-ZZFK!hi6-jrt0AKa4Zr1hI߱yqh9-Cr-'ǣ83\ꋖvhy/NI־zew1ZVX3huhy4-K2-Y -.Ac'غr>V7>U9dњŮM=Z@>RID_)h%_ J ڠҘVRVht=-E˟gjRւj>{VjRV@+v^[ 0gr8l~w!Z]sc:EhU"Vlo6A.CVWlNDpˎpA2 40?B((Be(š(\CaVkFan9 gD}>Eηhs;ڜy6tѦm.}]6LC&[( 3bP8v\@A_zKkš\v? bmZ Z[GhX6?FPNh}J֛h=τɋAkYlF^h{b@&"ZA̿MfLew%KY6X\"6Σ͚h׍66 CѓhwmY-(l̸4:(g,Bm7#Qt EP Qb9nvPoX[=P 2}P4C;Dw1NEgP4QEa`"Aޣ(ҕPw0Ew(?lDwE#P/7Pxm Xlݸ˰Ca] X_bpCDngQEa+.gbtVˑ6(fBa 3qlV whqY (tD ,߱Y#4 ͂4u&hӃ& ф~A}4k]Nh| /V +] ~.BwODM M렩b!HV=hZM~{hzMEhv Bhnf6hv fhv/]~fhvɍG,Aͬ. 43| |p\ߢZG֠UZkЎ+y켾VjK.SPުF:6FhxuU֢2N|\ij }+Ks JPܙ7(ԀQx-n]c(v_܈OH֛ DRp>scK EjJe$ߚGza<X=MjDtއt9Ҟz#N/t3 : at?܌ B=Vo z93cFsz:~DO9 =yRCa1zxG;z{Gs z@O\'DOQ=US)zJΞ֡<|(@/V/x f߶gה5=oA]| =wAJ = Bτ9?^/EϨtzy]DI8 zD7,p@1̎K~zډ^KMTѳ6}azWn2Kgz^FG=_D9{ zE;s8<;=E2lI7zv ='t|}h=k-س&ף{t'cOCLtoFwd#z0|W {>ˣy?=51s+#gt =lF{~y|.zaJY&l6a)p>l=?<=/c3|BO zk9GKɺ5w=WA^kЋVlz}E^<&{Jzv777CyN7;|T؉Ҏ>gL5[ޢwFN,C-#hC+} d>o7zXϨuJ^w in @}|>F= L)-Z^ێ C$Zڄ.bzmD; /JЇr~ â@? / AБ}oDXr{6LA}}T DL }'e/-F} mE  (izBLzw1p'~)l裫>7+e5WynD߻Sw5ιз7TNȡ_.~þaN@C%BC/TOϢ5ݐ}7=}S]7}' Dk s%}.[O7f=}ט軒q,y;?åѧ.{^>m>vRƍ!RϰؼTc-;qag5A3 b@d#]ŀmw1`k@ Xf8U_/1 8Mލ<0p+IqB{ <4q8֢pI t1ǀpf_Q#-q8~#YA1V ݣ8 2hč/p/xK'T`ЄR!N2 UUۂp\"킓`ӄJnD2b‡$#*6b'1 ;嗉Q2&٘m0&uvDjZdq( pk"&[DXIW ·k᪣2y:#Efbj ܹ?J> ~{:oV%$.uk v"pB>"l:H,{uuIB}! O. y| ,t$܇.tO'ߐ .4qL|?F2y Iϧ kIe t"~?p_2+& %fDc>qL&[yNpPWB葅 Kkַ͞b צ3qm':{?TWwyful0l *`N|m` 9~0;X̌%0U sϛܩ[!(_ (ٍ@a+, w*#7`K޾"2 zyXOw`ّO3b/߃Ұl 1OA0Sz ź0K^< @錆yWR^B22KO CQ~] KN$Bd,ag`~Ko̩0t+9>0fÉo`ZN6'@>0?w@r2N#,qx+IS ~dIuhI*.L%cA~uoW =0b ʀ 0JG@ir嚂qK#.S! ZӲ4+{u4h4g|\{'? פ!h-BDr0ɮS$M4K2g}$$㳭䜂Drgu{IGpEI(ɻC}* OA}P odrFg?~ P OVYE7vS`L/9`<z`:,+΃M0W `C 5J`8`,jklFw+ `4,J X js _`oP+X a@>| :psq}9p<^{ xX #aSu0nHߝ0-D1)gݷBp.}Ki8QISΡ% V 4rq97u:8-M{pvYR@֟7nSv/6<>x{S=Fc8?MMXˀAhjDcx><ۺn˂:2^W7#p }Epmy.;px GNwp; @72|JI68̈a)(pZ F`g axx,p~Q޼ \6ܣtj0f{ 7Y oU2͝ r_w5 =fԈ`r$lTE; 0& <y8j OxDžEc^Ag] al G΃RLd.Q+X>G7|N ^% *GG|Sc CsV {x xĀ3 ^v%@/h3-mӗ#vf(|}rT &D\z (u\ @\b(y.;t-WA,plL$'Att%?z*C}8UNb.A2 t6,R_:;|F7- ~ՃT h8ȫ\xN9\a8gm$-VAfx z7,7\) .L:p& 9@΁@s@#_?cIx~̚5дk3</Pl7 x 3.Aan3Kc*4@V{T"xL2} .7/X7P^cE[M5SN?sD~3n/nW )bp|<ms'3@]ʞ=? */>dz; 7 1 mux_?kU c%=:mq|79@#;/NR4F18m8[#N@L]ip1N_cYP`]yy03n01A80~ F'3A)&‹` uXC`u7 @4I AxD_b14Qu+]+K@jP(\m(Jp NtՏeej=N.9ZK/8?v@9j_]02'3 xUpƑ༴kf~St$;`ǁ];?{?.b M"e 7@#<@flt 4qs?;_A\3\ր.Wq8_6psGI&,-=C[N l!؏e1P l,펁0^c`z)l' \tgP؊d)ؼx6G,'5 rk`$l'M|1 v+X+`کc uZDpnspR_ N`{Vh1/ʰ5 6/3$ K ,;nWm n/lsl)`!`"_B+Vmlzg]S#ƀ{#ٝs=x?cpS@:c)Xy͈y1>9EIyu^O?=,7Y b`wqI~E8j2r7,W}+7@[}3Á /a (哢70\> n M.p?lnM#؝`=8 ⤗Vf_mcvN,VVʁӼ>2ne 6"n+pUGYpJ`_Kc_!,yzx}{V>.8ٖ0qP&R>70s-L윛;<,7 ._  J{6x/9Q+n`L}R._2<#.Cм04s`9{W1?'0n{ z`a:1?adzM D ʼnn+f$RCg\y# -_!(, µ2!ffX`^(; |=fMaZ?f@RiX,FA>!-f D%B4bsG 05oCaA|hMHm0[ ZX_B`żOKX sX$V"H׃=Uy#^HaӨ|x67*Vkma{5$VB"z@o[xH J I0{!9v|quCuMg m| |H9H[ [>H)=!̓ Re e/l{>&dKH ;&|=odO5lhgCJ$o*x 6Ni,-M@Jl] i3 E۶6 +ҕoA S|CJy2lnaK@H/iIS@la26̆m0H TB^|v~; {^v32`g=\fH;R_߀?ap`in {>̙%Wa[$H(4YuvܼgawdZÎ2K*v_2k,ؓ3w+쯋 Hd@bmv6ޙ);{ }SoΞWEHV .k!p4VS{!m?Î ݆_á+v/k>Y '`N;4F_{̄͛ GCް48T Gy¡SpZw@n8 Í>z2GvAa@:\}}@a]L$pn(f5ޝ8'z*3^*=@-*&CuT/?DPLB'y\@]qPïBCE ۰}w6+Ҡ~J5ꎵC5Pfpx5zE^լsj+_*fP5*dCy|#@Z)T 5ٗrl.7(Ay#xAMQ$/:B?LPt *[*;~( Pz  NBy'npKʃu>;aN(Mlx˴@Y\ݮ*PYJ@8|s\Y 0bCy#E?PX(v\AunU2sށIP:XA͙xk N%pw6h U.-P|:HhF@8x,ܾ:p-P)uS8*MzP{MʮC ṡ28(k EPoq5&*Pp23́PnGJ T)ʨmPYpzAM 7gwA8h*=-o96i(XC x- ÓGɚ xҭ O93<=Y:x<-Hs{sAt94$)<^ɇgFbx<~$,^@{fZ2=ܼH5]n5pE\[mW7m UC ߺÝKo֍pQT'vp@(| W~܆p.)z>8BW+Zz; WUU8Ό {7å7pQc\ _pqMK-yWfF-t39JoP'6ۯكpZ |}/vP8T**Weۭcn 0sfgx3qϠ ;N0j?at-ܗ mZKڎPs Bc^0jj<ځh)P0qi"Tݎ硦)r6V@duπ /qhqɇ[fAcO?_*By%όy7*πrV{;G@Ԯ=OXxr<3i; yKW'_W}WTZbp>5%3vAVJSۅa~7|VY7sDFi(̜pJ~'@p~?ʠ 4?B)dP{׃%?y6^S+u?Q "$8v(%:R(=(}9JLBitm7}&*Cf]C)(>v"ruv؅(qQ&~gOE^7l_U{?eQgJ1L֠kR@(˗c E*s2D 3]QNelF(PMLDr(FFCQS;(,GPdte:0^BYFUCu-e;I5Gi([ROw Rwb+ ?^ބMs۔={{ _Sztu4|\ w߇2jx+?:* ^Cxi)C'3CF!t%B`tاAGn3'̂ɋEz<ϐgcDxcO#5p=# 4=QД4 @(Oh0D*: V{ ړz|:nUփyP c=n#P;.GPO=EͅPt1B,Ԇz@P}wwfPeӠ#ܡ'T/dP5@:3yufyNxjVV mZe=ݕK^6<Հ[χ{|WvJ@)w,ʂ&@i;]np'pܮeٽA8`[邢PfCbu+nZM=pL n 7VõGp'\-ք+vpd*\ڮ t.9 y'p2?p>pZ:Njɽpr389 yڝpl^z±8k  G8CphsfCmm5~C 7itC6QapuANn{o.Ks; d=%f=p3,g&d^ϚA:rN@Nȹwr&C45,sr,[%FHsm7@ʌ+|RB ~~ vr!eeHUv@@9Hs`fH1^Xl-A9 Fx o`(Tk,Ϳ!wC¯-PT[!N–Ij [ OZf3z K¼A`[[6J)+ay7,GZBX zTX?v$mڰ) ( .X>>:yIHR&R2aT+d `0|;.܅}9pn GviB K;p= R7w8r|Gl684Sk'ȿz'85<Nޯ|n(.7&ӿ p"qm+8v?8"B@8,;|5^)C!h?ٙ 2 [Cˁp#{8kB pz \A͐}턫Fb8Z ǧ?p. {ޯAb8.}θ݃su Nqg, ّY©!QG/ Yp8}=qY fYpBk[D' '\NBB$_t >cp'B8 y-@.)Y 9BYQ ٗj#]k QmِrtX{ʐ]<r 9ȹ8嶫{䖝CНp]䝨˻wÉ}5J'yGa7=ysp '@ު#pnBigݮ9 Gk@TdB!>_)k,gFA,$vvBޅU,fy5rHjփ!,$x $Bd4$sG[!y$ΐ8 $$|!QAbD6$@~_H|vhؑH!!y`:lэ ydzP>m@:2 @r7H7BdHB lkT @-cޖXOIn I 6:ϣix C6́0guXxZ+G^~w`'a4_6m+vobz+-e`m?+/UNTJ,q9 3z1!/|USVvpH?R+!mqp: XL:An|{rOCf ;{!sc}ky{BBfO/ۃd>:vA恝92A"ع04Y iA~&Cd gBFwH<[RaG!X5~ Z}ad-XQ?V nBf mX+, ׮Џ\3_4=w-`&/W޿, s%6.y ԂFQV>X։w,nj0 7OŠk Qm0N?h+_ՃA㿹9TWXɷ1/%( /7$D/OVDqge0v 8C?"A HO0k j*+~bp8SpYxėKl=xY:xeǭ,xZZ6Iд*ȸÓ0PgՂՙV|Yr =x಩ 9s/`lթp؛W;(ܤb2جl `V?ō(ӁO`<kA拱O1~| 77a+# r0~x];>aCnFbyiL6Ƅ1aF&a&S1+&)Ťag0rn `&^īK1aԾ 7C7b[fû8AIKe1bLIq˴ӇI[0q-&);crLa{o_0).Z\0u/^ [[qsܴnzҎ&sָz%&4;[d{ g-p"ⴆ%\$ep‹8}gsh8N?8=jt F^؏"y\2n}6SKO'i}G pJ=9+\QӍ+*j>qG<:W'J\S| -:kU\ p~6w5w \&W\n`Tp Fqƅ?8u)LG,Eg,tJ]Gt|jEB# ';qR7N,J2]Đ+^8Ð&m=q 3sD pL= 7\%>0/:.I0\4uϫ0bHFV_H9c3O_u1931|'_{ckv`,.K Na]i80|Ko}0\`YL°︄6b}3F<[QFy#{12*FŨYmeKg(7FwQm0*Ybѷpnqןb-,e;RSU ]0E?c0fNֿec0ZL0jFT`Dፑ0Z=FFfc$#db k1*'c2"0na4 q>\cu0*.1='`&c~c˾u1Sw`iža+U0I3LjYV% SÕ1?pSb^+.; ctB0a܆8ћ0lk\1#'nƥcpHYcKp#>bXb\F-%1́嗊~ҌY0B܁ve0 û]0qT_Wp./ǹ%p:- \3FTEK+`VY84g*06.ڨ&]8O CKpոHxcmYcQn_qC#zB0t+9*n5,/8; ò2p.]d187h qN\\ Erz17yo< 7CwQUmE*EA*"ґ"JRHNz$HI#M@@TP UE7~~:k}vk3+Srq rRM.+Fɵ~9M&h:rGxA΍\.9'.rI&3~K<r<{7SCԱ5K>{R}7~[3R|χ| ~"=pz:F(hdK]}м ͽtDA)>])ok+ gUm ` xp+`xG-]~͚yX_RИS jIA)Y6ȿ_ x} 8/-}G&D t *3>$n=Ε_b' RK^|ԗשmy-̼<\9mjyݺ'"Ly$>&}\FyT~b8?CkU~Uȿm|\nwx]NM?t 4kW3qʿC|w# 81Q C&6pd/NN]%6ȳ4)3߾#Iw;_Xlmy?e^ |TU;wk<Ԝj3W]2K^k^hy~&S(BܧhTQ>Ӝc~$ךrypA2.Y.!N|+_"9/Ohx9 kArYw)#V^mWW7q 9PgXyç<ɻNy_dbA]`n˖r$Sr],rWgs jsz*$嵵'|+،A=^/_+ <Čp\oaM_i/Gol ^Κ}l KAs&guy~2U^+mg[+^m`O.&|1Yǚ#y/*pCSMO& 5H&5oSgSV5'{\sM LUp\PQ`;rv>_ hV`掙KsI/h~"$Ӿ&^O̓A>} ]^CK*Emjj1S'V~c./H{y՛+柘>4B[L &r(uěG~ܮy5qZfVoThZfe噘厂Y <׬$Um0P >\5[`fa>S< QsoY/+%ۜh6ͻ_G7VșZdB+ }0ZJmf)"7{QVxr"}6o+𖖖ТQ |La tB*Wء Ü>l"&S_(|xmV:&Rnj)-Z0s Yꮰ|PC/+s">կ""7To0GaiI!E$ۊl B3<YVdEWT z¿O/UiؑbbWlEmGkŖy)b~WE Pl|ؽ5y\u(|hwǟ)zBگV(>bwW\~R QJHu0W +nJ5ix宅A/)zQlW\7;%\I R܃ilW%_1"ygVlOYR{[cFJpߥĈzJH+J8SKq}mWfWBSJLە'M߮⼺*}%ԫ0rSңWə[Z%N.+>⏭TJ^aJ0Tɵ*}Jn0J5Sw/>Rl%DH =rJ!Md__鲧Wy]]yo^Pޘmr?"x7R1dFvM{IōXSʽr(ߒh>E#Q)9r|KvK'뙶YUhpcwG~:* {Ư#*r\NԆ%Wvs^~Uޭf{rZv5)6Pmh4Qwj}_DunGf5Yc3Lr{%v+'1vU9rڢ{^C]3qo9bʬsCML5km.{g9Mͺ[}| 姛~S3m!r X- h'=Vwkݔho{J.9*pҺy Tkً!w6wza&ۈ2&$Oyƫd=oP~-#r (euպ5R[~Z:\yKĂYL.hroӚn6y</1;!Z:WkeiM^ʞôrV8ەۺ2dw19e67Y60kl?D|"ۉ˦Vvl& >FR?TO5:ǔobc 3kRK埭u~V^A}Fy5UAe_;Wq;L"{;fF YfuE{e-j&w5⤹O)/SQ̟M/[_nry+=Sl0ȫmMĎPƙ䬉rcڳ,ELZdu!kI{g璵asmm^EU(mh{K]цZ_Qfr$m2UϟՖϴeZʴ|V͇[im=-rt}tJۂk[smXEjSmY70֖uXKmDc^TiTZW%Ki{ T[۫F:ⵋTN%#T7TGݳTt;Qq^*3CE RѽI*ΜkU|c JUR1Wg8JoUI*9JRɨ* |Q%MUCUrJNlFJ{5Vّ)*7JU*J;^WYbO.SiaJ [zvJ Lӯvd^3k%u=9רyJ;]R閃*_ T!*4Z۫/JS =W*?_"9?JêFʗUUeGUQ̹WT]ϪH]U\UuT9d*\WE*qFe<|*ReToFrr}USٹ}Ne*߼MSonUxM6SETQ\UqʟVWE(UR#*iyZ}U[eI馏ͱT WŠm**6_6yxS哿Q ~lQY*wB"Tz?J Q}*󚤲\U`{QЧ*8c>m'I۩|[eoT1[SWU~miS3M,WiOzA<*>ʾU*?_;S3ӿ៫NtTi[*M T?E*}JJ%Tݹ*.PIyol2Uq$KS^TEglHތKyU,죊V妿ϪKʷ/z/TzάoTRy|-mڥiڜIEhcxNPUXY}Lx MU fm!Pֺų>iҺ>uO7׺_YT'D^R7>11fW0;n6wٗw#q.)MVuLr`M:1.ʛٛ}rXL%ir6{= +o9gw M3IRL}11E/ɱuEGan=W(og&{9x˱G.;e/7{fGfSs5{gWo~0jzY/5n[gfؑK۳L}WKAL;Dd YNTΚrr6>TN^Z;[5jM.P~Oٷ==W+{`+ڻ_jgcUhUhzV^cjLbV{zR%)eR)}%9SJ#xoU)Jeާ/RwJO\)Sҽ8W({(矔<+Q)iC% VoWҒ %?Uw>TR7J~}~6%oĀJJyEuv*&CE+@m*zub&RߕP{+mE%TW/EIљ_(}^1U>OQqG9"d*c"Vxͺ OHRkU- ТZUおȚ9'DQۮ'YZA*L&)M5E Rs _ph-5sGs=JQZYW7>Jr*G)e4%zE+m%%5U¸%uP/(~DM6?+qu%ZW7O?T\V;kؓ8~6WJ5JuJ*mEtWW['cvTґIJlZRRjm^eJC'=eS#VjFoCm>7Zv_T˪e(ckMNӴl2kSfMe&+skK-k)kY;-e]12.g\TzwF)32) p-[F)}o}eT;gV륌AJo4S_eAJ?pZi }lmX3K)1(@ 2^(:-o2NTJksJS[ueY4Qփ]ZV:BF(J?bRe)mqئya2hYZ{C3q/ôVʰ55颌qԴ{etsҟPmN.SJMTjJ8) 0\ɇVJYT))y%n̵.JI1q}~䫭|R|*cR*Z<خԡ6J-f>x(!=!J=;G*5;O/RKJٯ4^_+-6W)5R9{+SJYG7sD))R˯(Y%OPR=JPJlSB$%|b^]5YSW/;x^1_+f~kżUEQ(_Eˊe"UT0EVTii#5*9sB=u}Ut力J41uf[E ok7d^մHэLTQWMWKEQbU}Wї(zD{EarW^x{-]7MQQPE S+DQG+~74|E v(d#-xZ!kaDhC+\ ? ]TMc QP*L^Xlc[c%J$jPd ٕs_g<&K,MM4PcxY^s~8 .yN8 #;J#۫nҦ3KcjkdE43fZknneF_.7mmy踶2!i1\0>DZq^ڠ]j/+h>@|ẌҤ]f~!Z_z.ۄ6_WEK-.qeG?JN^ z//nGE[zGV͍&*ؖ:xqJB9D/bvXZ-j'趝 j4eK֢@V+/g?@7.,tm'c˶T>$w)> ՅrНj.}L)iU4--Yֈ3ƋH͉\׿S擻jדE7~_vCtv+@kɗ|ci1},8M,oJ=Cg_(G昊96Qe}Ag|#Rʫt /]'ȡ7"䵍\T'/=%?/V[aA7?-GM=;~Үn8$΄ʨǏğGOa z6~xξnG )"^=.UxzGzN|#L_n{~w^ae"d}]%n!YUHAFeB؎ՔӉ!کP 1Ta\~A_g٘]+ݶLs"_.rJvXDě~wgwiWZK?o#iGb.jݠônȐ/Q0-pb<_˞.'Fz`K^sh` t: ă;]3},PR"*s#>owfjdRgr KٔLsjX=Ey羑_>LSitj;[29Mm/Gx.ҏzòD>XQヶʔJG$v΢]&Ɗ_ R/@,L Eh6 X#o 8ޯ,K\|6y>~=Kc+?UY#k_)3%~*]6(M&)ΓsX1P֏Kzƚf&D\fW[VI|m7P!]:iK:Y&揓N*t:mREJGMr0ǘRN__\U3(uf) ̠!Chni=1ןhoYG۪k_ ṓjGҵßvEQAw{ aZ`[G懟QN]^d znB>IDF C ^"ipa&/؈1C7SkkrQOG}m#'=x0/N|陛kL^4A<6IIWVK̷dr嵘 L;\4~WRޗ ve,#FJ뜵q|gΐw.v9^kkkrf~;Vмv=i֯oO"^ ->Jnvر̜I7[:-ۗ]"fck%LH9,x0m!F̈́e+P%jX$ :V-U^~-Wrr i:F\J2euĹYEĎrP<1&n4:dJk,oVOn>Go%~xS {WUGبn{N1W0N #߳rsNEIvokۃ2'QK(. Pu뻛ZQm`|Zo5T9-/9TN[>AT~ :QJbב7uCsO ؤ8ʘyKD{0=^vd>уHF)*(E`lnޱckb{bWDQE,""V"Yw?w}<3YI6'9y02%x njw gWgs4dڤq_[qαl!lj4ۢV*؋=1Lr;#{m1vJ;k|9.]ohϔ0k2SS+*xk?uQxkiFbϊZi☸dqEez8 Ֆ;Ux9|(=zc%i;E`3SFij!0yY!l34|И9YC,|tt_vǶwgν[)QC ^"vk*o0EXζy+o%v-]/v{!~liǺ1qICE DR Y*a2ZkO]jb2&kW qמ1ʿu]~,b|v 3a*s^ E[MjȚm27!IL5~|F9[[CNʝ-60ݍue/1+k҉5퀷}ЪSd^ ۺ13ʛ,g6ie>a/a%€%OׄrCeOȲk`"k|*q#zWWVC35󉙷`́+/i GM * |&1:>G3ƶ^gpgcNHۮa^0OSƯ, ,;KHMc&~gG}~բGیH0CY(1qMx{Oh~Y4jv{.p# '}D|#w[nxcBv={Jqx >qX!uJ`Xb0B=T魭Ml,*Obgln:x ͷnn&|Yljfx2L(Blu^/3^@xweQp8Ja)ZF+̼RPR]9ذ绱;~w;ךm0kF%?wyB;Qumyv;:uQcBvQpquO?W#_͂Xq|cg6Hbbl끰u.ݖ) ꤍu dcLT-FA4/A42ہ9oty#_uIfw} Bu[wV.!_.~тumjx,-mͺq,M>Ч||J:3 7RtWS$"d # u֍ qgXdmW򅚓DZQzep%eY2t"[nfMD_;&vCqsؾQX=EFN?ΎhΦ7Ɓjcl%p󿬐7rtSVcN~Y /wdfNyo<7k랬㱺-<-*zq{W9(y,ϯ5_zwO6Dc<XNMn? ]Ziㅿgb5Ac[kv7ѵ~b{T: |6+HYaOnLlkRֲ|>X@.,_n 9x/S7lh;7͕ aG>SVe$DE>ny&j%VO]CZGx5} W$ԑ?)+/>8U[K>b_uV ru-e.\{򤪷r!Ds 3[b\ЮDAov.0~.o#!|,4\a<DzZذyI{{mk"a]ϻ)1 ?* ۟uF.pU0aR~',_{fE!u>/|9S4 -& ]-:ky[9~KOGEޢ8]^M}mMR2_~$7F](<~\x``ԭoQu7>O5T>x[~'+ $7gDu:|jUOv,8r"c 07q55_ԋbv1K,5 *ec>:6~(ֻ] 8s :%|eAcec~kp39V?*pp6ѿBܪ'8[\ksqhwc+F-#Z_PV8(;uvO(PpkZF]33eV ox˻>oƽfi7Bx`7 {d̬bwJC9]f%u;,-e:Wkoa֢i!{fu4m[b!}w2晆{ 1 EۆLXOgJ[KjyZ FnNa;IsDݵɂ0p4Cwdwo~FnGw8CWLfT^򭙼7~;2t֐U&ʗ|GʇZ.YvּHwnHamPa^p7{5N7C| ^u<&-'Y0Npaݞ#g !sN`!o:Eumx^7%'y*G]-[G >ےygc샆YF̍fR6^~Q&xM7lj)oqQ\ݯs$1 ;g[ʓ-nUE&G K,6Tx%dKO QSniܼҘ ~2k 4W^rݐȿW +xY*Lpy((n%DN_)l"ͱ(58GI s8š&ȼȯ!} Wa]~;f=Y@>K.ԕץ /衸'}%BGZN?"(^yCye!fZ4^\%۠5]'^,]7ߧq}gr{8.-ٷo X;<9}/9NcnՂ̾p4>au{Sl\/kd5߆ 8yOj57ϋΒpss^Ï<+wCt%UUs{CtU`>lUVvkev}Ϥ#c듒t]bTʓ7ue_Ʉ& Q˜~f->'Y?T˄9O Ƽ;akaɏu%21c*nײq|]^ g}g._f&S/kE+s 0nrPѲlx)Q<֮{%U"2ERSlJ\xEXAΝ9N;&/)o$?ɛҞ&6 5t@yܤElu=m͘GY޳I+ښ<̤[o㭜s"Qd}ilN]6KGyHX,45%.2k_nj茸C?I>7j[.5''|)\=gƼ>Ŭ/߼yx/2I6Zm:VrkH{X$,V7-5l|R[C0p0݉m*)ӊՈ&LdjXͿ1<]rwq~Ǚ]F:}}m?Rd:mq-ZEB,}y-o؞^HJ)5c7u-Y m X+,6A]VuفMƋgdMrD}QJ$z650'Qzx\\]'WchBxkO e1P0<# MEuD 1d9|kV>s1^gcl{ǷlK5+ŮnS7#WXˉSd>?#\3t>%`ƅ7)VUߨ0I!v?c8u]ʹ9-:Zav `%ז3c)[)]a+.a%on6 w5]\4 )ۣTE5*7,y]qc/qlDZc\##zN!mt¦jP!KK+DǩE˻&"?rW!j+T綻(h M> b٥Ymvys׾'[]m0wn#$4R 1>W? L:Oc8Rݒu˧l});܊._FX ƸW uR!TN8d]-jPL7i~I^f̉MRwGha\5'4֖MOl2JgC3.VOqH(Oܽ!|:e? k5P%{\MmB15Iyɝ-)B /kBeY8lSa^+}7syvVCZ76-?~qx?4/8l&ᓰ\y>ޔbm_`*Ӆ6%MZ1Z4]|?IS)ﮥ73a~Psrtuˁr/ E"oV,όItoOyI!GMyȪvr xa*JuB9φֱ..e[u+9¾+3J?15s1l^e%maౡ bx2ϟⓐUw  \ˣ~5Tb{V)<٭6N 1̎53gig๰>j}jp}}je}jǵ԰s!j}ēԩKSS7էJR]}jʎSr%|Kz> }'g n7>o14}ڈ{Ek7%Iz>A}ng7m3Lj33zmpzs N/7;3oUl>X9>sS>s\V6 K7t4b}jQ^k}WSg!>`#-ϵ՟sUp>`P~Km\>c3}Qj/%9!)76+JK>%^KB%]y5IVjz}kkT+i3RҘsZi_,׹ҘҊ;DևUJoK[I"J;v+)+,^$S:xR:ut;K^\-DlAzi?_ҁR|Nҡm## FHG=:KZj3ZH'D),N:\Y:}tA9׍R|S+Ro)!tqX[ҥҥYRb')qtytt\J o)%ΔJwR|)x`N2d"6. J.-$C~aq`#=s$:+RJat Rz/[tt_)zI+\QK)jހ;JV>J%HOIe gӤK\zUk~L=(}>N>#}{@_&hHz\5Ue!ZLw tc0:L#N`:?t6`YԁjR ղRy,MfEPs~:{`krKu8ռ{`uXr VmjV- X>΁`,N]X*em|^.چ`q.,r X_ˡ`9#Xn2_g 6$U:sz1O` ؤAa nA|lۂM^n6OMK`e3؄fe39~ln:͋pPX["d(&xAd1DP 9OA AsVb}vt [+:#` _ pXgZp4 Iء)8Neq'8nx]vp^ѷ0Y55/lؿK%Pw88Z`+?}nWO ۫~93:` ^/b>{]Q2=vZv `W:7;} _'`. '`fviGnTEOs,hMMPP}? 9W@A5(EKPǁbgPoMwq_`1X K*:< î1X[9 f՘`[ ǂxK`'X6\ޞ_1o`yXQՐ`eֵ>TΜ6ufMvMa:8i)(:nH C9(5ILTJA5'< T@Ucj]U`,΂j PM󧧃jUPM(T&>Z Tj Pm҃jk PvTg*%TAL*3P+߁ڵ}A4@-,u,P>uPPwOS/zT5PPz{P/` ^QA&7=ԇl<uaYEPu7W<}.h껀&6hNMhhzf\o,͆Ϡ M|@S6yuzv`l;Fm`'lZvJ] A`;v|}s?fm` x z5nw#L O|__Ƞy4y@4l+߷gIY+y1LMLGuͼa |'&堉0ͨ14A5hǃ7?zo3Poc>ǔ~[ڲ➂QPnPlKl}x[֫ y~mڱX[Lkӏ`m>kzG6l 8( JhP5.(RA(~EB Pvgl|X{\+r3q`7A%PV0[x j/Y{X0ixCs-_1MqDnRO:^ic'GwHoG4 ^׸!2M^/Uc|n^J/5^^,[%XzQ/UT#Un U*REt>Jzk"-0m-=?VzޮvRy]\IzTzP*@*-'=*;JZIJfI~ wJI> jRܕR)dS3DٴOʾ .X)%Bdk"SҮ4w,S*XVN,ê}ZtO`#D=kWOuMº~[ؠFl|()9lޱa5غi ێy `k- ;v#e/= {%[;Ն@`K8Ѻ'jPP\8ܲ5GÑSpcxmw8=N'~ɑdVq1sBL8Nm>܆ÙGGpn[ 582 6π: X NI \8[ v@_hBDwHw.k"ARzH5ځA+3@A R{\)WNkp=A޴kCZ i9ps~Kx]I)ք̊p;d̅U=T _;B:?\y[CcK %Ap`0tu~pxݛ<-qAQxP1(yJN!P)uӡAxϛ\wŜ PᡂDx92T:WsY3x;i܉6nIx<F?=2S|v3ˠrj _Ox7^o?RF6P~~>>UŸw4DdM4AhM'Vka9aXfs;YR)Czd VFsD4oWTujEjh1-@zTA6h9Ze8rV]ʩhuu1Z|h=Z=ߣFD}*̜61Ц*.쉊AP:T^xOjT5~TG*ُjPTn@u5GuXT8n7̗je697k:cK% Ua~jU6r*!T݋w|P GT5F偷x'rbTGe$TWOTƠң *;*~uDϯTCE~TdDEfT\ * h Pq7*GEL*Nϧv"^wg"aֻj4[m{P"*PQe@˫xQQ@@HT*B}TZFeT|PiJ[TyQiaJgևx5/|**JxP锂JTǤuQ6 [Piv;W?T@%[TC.7Tۘ2*BEW*:_*Q1*fEڻ8r)!x[&2*{LAܙkT>FUj*HEUFT-Z}k#o/OP]o/E›V֡|{T'/FuJ]^Q-[:}?6iTm/7ՅPo4N7}PawT+F5W'jZ"j5Gs3P~5&fNԬꅚ]9u5PsjnCM7^|{W&?7QǗ?EPY y}ʯϫ9/uUy_ףoQm} **Uޣj/;6sUǿt[T?e Pu'UE43T+ߡTkDgTG~B˼|m6?n[ Rf?yNGh뜆AhC%fGۿЮUo[DhTh}1:۠u:܍;^N5] ;|t5{ocͲxkEZvnX{`}+]F)jtIub9X-Ǣ"t}گD4tb(Fߟ.Wc!w =uúNX;$֍uqWgk]Fzks;n~QX?b_뿪dѳp=#sazn^G4L@w,T |Ыy'q+ SK-z@ +:׷ۥz6 zw_w&z{ucI `6o yW/bwaذCl8.68 +>CKg@Y}NMAf ܱQ\lo6Z=2чXl윃xfly6צLתzC_oEߥwH? }Gwg~#Я3BNGo@)+AYoz[7 D=k/zqDcw~g._]~Uwojz~ϧw >wϻ6sR k4AWvwN=|~%^GgWΡD{^ WGƿ?X  LŀSw`ǀ=Upq}1b# wc@3a.P1-&w3lҒalsl6It&c{a_30_냬1׀Af`дu %Ơ UhC i31x- >6wPk#PMQ;p9jF]VF%u:apy,ga.'}nC08@t zC0 Z> F`P`A51o7 L xSˋ00F{\1pt.y8?%c`d^1Y0𿛼ϝ!и' \1۸ wo`` ,뽘?a}W j 4t-qo 2TàCap 7aɖ1Y{ ޡV} 5}0jO/cj].jȗm\0o: N?08 c9:GUܹ ]`mw`pk}IAq/?7/jMکkP;~|7Q;! |D>x8ϣ-v\ߧμMeF@0^APۿB0vLD-Emb6_Zm8jo j}''އP[5N.;^ZQ[O]~F֍/ޘO^oW{l fx;uTc`h5Y5jc֖35F]m޾>wqooǃzx;^jjω7mi{|ݠ>|ȏ?&b^\pcbbކzv5m?6[bP4 rg 持c"[`H>vbW>bnɯ ۑ~Bѯ}{w w ?OaӰq t36hGol4l6j>'.f~@@56|'bS߱0l Vc߱Ao2zɯ#6z%>CkKi^qֻ$`1XXvOx/պx9=:{Tt?Aw&݆^B7e[tM܈a&ֹu:y ]fAoΟ( zxNP+x?,z5D`ͦй#:GGgm7u%g%:2:h1(:vEaM=th 30v_)L7ڎh~[3hgcu=:fr,V8b5)4MU43Gh%Mv>OBCdUmJ=~j ݱ|_3{.|QōG4c>M~@x1Wx P›!zM .W>@eAe[gxy'^t!|^K^\ UJxd b;TL^>BEBgzI7EQ3xukw,-<e@P1PLᛠk@d(M6AY7(;ffx{/4>P>k/OP^rPnqC/(3f2r(s~OOi*x0< O]^ (}R PGzCNg(]?JW^JWMqPYsGB$Ҟm RUҎPڻS6ɷŷY [CfPz`7 BPze-,S(]gNa> &PZvJ_zAk+T\_yJK"rO<{4/o 魡[^Ƕ|!|ٖ|]g\f6FA)TAɽP+c{ĭ3ϡx2? e(*􆢅o3:O&xe YH+3XuaQ[/wY0; 4Dc0m{?9&.ADa ƄԀQÈ|? ͅ!a0P ,gAZЧՅ@Vs5tu:dC=3N  !yVв_24{ۛA*sos4c =^&av\5i8 rݨ1_lrh /,}&qFJ_j+J*IeRy&=t$DOr[_n?Nn+R]Rr%JY%ZJ҉ґ6h iσҎҖZҚcaҊAȁ=ŵVH~8~̭/uJ,pZ/|=r%rs5%B!4WzK$3 {OOw't_Z?X>Z9HmFn15 W /I_xV?+O&={ԏ+^^C?!Bܷ~ںksF&Z_S_{u},}*}s,OO}|>zGVVnߍ}n5{ym[/wy>Υ;39/svK賗g7z5W@!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!bBl˶uAH",C"M9X=DEI CH>0{LN*6ep^y:Rr|-%KB=$XP-!QP!|0F>ƌ1>d9c[op8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8r8p8pu}x9tgsvC8\--[{j%-ʑ㫸~!]Z6ߜMZl]Hual%w{seE{=@clylY r2zN'&9ڙdnSNUb{RPG6S8s {]}zBSWm1kkN׶{p2l<1胫;ָ${_]}>[Vz;ݲaՅ߮.0g[!%㶜! |o͹~]}yq5ž3͹ǹwzXf"nݺs˽a6Xxse/q16OK{P[W5/i9lK]2w'ֳ7뵹]taY[w>Oa{_l޶1[uu77t|jo;7_ז1< je3nCw ҥan^ ;[uΝb#eR?'Y{,s(J+M:SX؁;c'6N{}MNk,Q6]˱/8q0q\)v*Gn˸bö{Oy8{*k>c#lDֶ#_u;ΡQzmwvu܁vmhspJyYb{?|u me=a]'SFL%ׇz`$w;_sCo;n$z+\uǷ1gwAl}oV3p{-6ObnVIjXnXͷ^+be誺%1&ri ک>>[\Ǒ[lcg-OY'Ȟ$7y\Zٔ2[au߀|³_k [;{հj9W]sR޺{ptz|DZ6~m߲:zm6ni5˳a?N-6q s}x'phܞl=s7?+)07沾!lmŽ^ܹxz|mPly=16❰}D 3p}ػLCj zmMc=alvCc\Ov}{5>=K2>ϣ\sr{]=>IwaG<5 yNsIvHZ얨l->_k\u.6] !v#2n|Mjs׏Sۨ؇{;ֳ5ہϖkmS9a[nq/k{DuS/1XOl>r g1v[&{lPr2w/؞sc]mߺ^LvKӹsk~1]:#~9d;Cj9Tc?Y[oؖzלͽH^k%qn#o_1aC]sT~ 7v⎶Csݔ;.cƸmaks}u<.;®spc#y=Ѐ<[e-ͮ`Q q؉{yj,g;(aXn{z Z1v\'vÎ{XOXĘ2w2Lز)A}ϣ†\GU~Ѯwou]0M߄;(k ~M-P=5S'smdXTmY]b]qx쵉s\]bqYoԺA[ ZK<-n_;g au"}7[/xw +vKZ޶C3wxwpVďr7kܹݸC7Nak)wZ󟻭xQʠiNm؈c+/vbݔn=Z #[6-n=+j_LnIe|vji.<œ{^Nk˽,a6>׭{r9>2V{*_w3S˩N˹oYřh=U%[Ycm;JqWI~tW/߅s,=S)"3[X/k={žDKr{ofA\ b<=$n=k'2q%kA푷8#-fAxöԻ>4`Gi=_8wY{k=va_YrǺ`~mj|6~ܱ\sj3 Rm+vKa8^-mq4w얧9my}oPnX'g>\_9vVon+uj:>>m8=F6PѼw<^uq2C_BmXv|kNƘ΍݄nY Mt=pWcW7el ڛU}{lFd\o}ꝶenq/ؗ~wSba;N͡a ?'lGs}qչ{f7^7e.AMXu.)v 5DnT%oyi;χ|P7CoōuKlmRx<[Vf} N݌.r^WN-'ř eCͻ~"δEos_(a]9w6ɵ({[%nil@l&_>/vjֵA6ږ:9>_Z,0ܝZM-ߛq/6loi|K!s5ɀCؐ?c1wPX؆iźޛA5V_"["Y/Fmma\|Kecc6Kk' wjǹ-AU)lۣu$FqQ|P,b.k;6c,l}2wmiĵs6YfnYif?tĦkރsZܡQ<1`JƍiOO7 Vϣ{XV#u UwjiMT! x-Qc5ɰq 4/jn iņ{4㶶b߄ pa氬WW~'-y3w/qczu[gAu58pquGqť'3p8axp8p8lp81Zc+9T}u88R-|?pz +p8qpp8p8[PVpYs8p8pX\ or~npc\p8co_p8Sf>/p _v8;Nu88ǘ>p8p8pyoq8p8p8p8p|J79׼p9'K>7LJ;u?P {p8gg^Ϲbukns]':W~蹎subc?u=Zuݷ?W'εaG=vs+k阽si&Nw,8g vyl{ |皷'W~k= =d|{.5okcXދ߱-vcp5ε)~v.>s=q1=ǷzLK;G_on}zos[\}s;wm{{B/V<'>* ^󕷽p={[+jl)?w| c,<#Bs[^7K-{4w3}nr܄-cpsDz>y sg 8ϸ{?-C=`ñjmN_ĹC.k5$_[\hEV&cP{m{`o_%\1zߓ{O|,WǠ\\"~ _p6f.cAyK8v؃c[‘ZǽsG6S~yT9>oQ׽{o}sǞ;~>w.W3 {]{D{qs1ñ -n ש1L{#ozp>Qh[\>y>qv܀ym5vt깵8O9?W\gnsK:G(sGCs=O˹-~8Wq^8Џ1>ͽ?\нe%[sHXz&"4׭s))4Վ<w[{Ozn\}u9ǀss:sjsB(=sSeZyosmsk; v,`1ׄs;#_Sϝ}sñ5߱=\εu?ў8Xñ}5qp9w\Tp8~p8Wl;p8sop8v8׹8xpw8Cc{l{S>Ի{Խ59¹KlF{%>[q fScD롻k;L߼O>s?vճrNu"+s;ܚ}dS~Ͷky攀e OCkĹcy \O__>~_o.q_ P`{(<ׅ{e8spxYͷ徱w?/k*ms_cW-J<5e-^&SiᎥiC)TƯ^]rۛ%g$8>}]}˸(}P9Ss=e,?}r(W8oWۛ=F\o ) EgdYO˯CA_^(_z=6m_8?)iy4;z5gJ~.\37?(:P/S2|%Lmκg(~yWҟ]nۯ st*ؿYdEި}.s&<(uK;Tsh'^Կ#XT?||W?*ן>_Οdd1j_mz}Uϳ7"n&@lCHދu-c;6G鏮3يE}3oQi[e2#Yͽ%둋Rϋ~q֕+ϡ\lvJqE֊FK~OK{_~)-H6jRmSgR?xw'gE&ǿTWcu}?(>(c߉N:&/u@ѹ7@ s:?םbF1/:7GQƿx׏G7||~>7$_x|=?~~o_}|}쉿O7~Gט? Y##_7Gk*F?؆__7Q?/#?xGwYȁRI;?z;8r}9&#?x~1-z|Wfa|o=&z|(O_suWǾ72Nz~|X8虬k{Gb/\ٿ?e_E?wyNnIgN'満`R? zO?>oӏ\:Ϳ#k5/=r9|&==śOYO}yǏ٤?Oz/!xCY܀cvAkˏj VRbk⩡3B٥z^%qTۊOCSKfB>moJp_PdO5o˲K<{LzkypC|븇<kSWp>sxCݧ"K!%kנߧX+ΰ|s %>kXev Il8 ֍p]ABe蔬zu^K8p*݅}_/qC@S-x."&Jq)2JL,misyQ9>6Y}Uʠl^?+Xp_sJdXCV%X]^*sC|y;w^!T"N78o9fSR E8Cڷ2)ox* w_o)`aN뢼OlMy3M{gOjː96'enOӧKTl|O$Aq%^{1{7- Eu/œmr= KGp\w[u퍸)}΢Ҡ=8wFӵ+ܗbW.HrN,x[1%SeH"{fRᄡ܂ϔ>K Z ڭrey/zaiГUܖγ@+HGo5 xVu<ְ-uJ-T&qz ɷ/s7iߨ1DsHckzHF5eΤq[!~Օ)u@s;б5Xu[/!ip H8Wp'miީ.s?N(Nߛ;i7Tmtei˛Ës?9;P?vostm.__<pG7y,]@r ۜtj֔͜d `?"XpwZ+S2ރmt xJ|}3dn4ZEkd/Q_`M257x/- cuҾNCܷ;1)׵,5B| emwj>Q Fc„d-$_Ch\*Y 2wV{.w8>;Bɵv&$a;?GOKv{%o _..A?n/E5@u (;X#/z|8J~A_Ir wI5Fτ ryolO6B7g9.fߪzur~ם1#ps^T眇bC nkUPf/5V~ثoSi̎R'\폼׫, kPxQBϔ@bmEοvܵXd,8yI&q %òHzتQi%Z>t wYޠߕv vr0Ql: AqS0͙\ɝ }l;ᰧSvm/͕T_wJևW'rk.|,6 i$Ŏ,iרⴜE1Aok%}ݶy/#6-5Kf_^r|7DpCxNxK7AE* 󁃚Kp][W5\x_'t:"?+cC N6wbx~?R0Χx.Uv\7D3TtO=>|dokxyʐ)lTGHmiS/"-I_Qۈ~STF>w2h'*աd|Mk(_s"siM㭴 W˸ԛ\ѺE8:sQF|0\=l#d^^@΋ $uA] {},<^BrK]oL\Â>4bĘk]u[ 3W7}!i92\/6 $փR"s‡tnc28<al^W(HE_d22s)C}_Y;pjA7kF,'uNᅦ< L󷶍2K-c5!{\>+^ʥ1Z!Py\u%xɭ~͝mP^7?o>;}ѷc۱p[O\y^ϥv[b%k_wכp'<מN},=?!clh4SLY$v>v?cYݒԵ؃,u A|Jce٧xWtJ00RȺػ2nuQZN_$Az;vQu9%.}W=$ߪÄp*7-zѹ|6P k9O./C]NOE~Jw%B፪{ /E|9sGn^)dm)fA q?YCgwSs_ )>p_GwFT7qU +Tޗ. ?r[CkPg8ՄCtN={ɩ)2?e/r+{zr߿̝]q|7?nos*^"o.s:\]$f<<px9ϲݡ=y$?by߳n{~!u<煗S͹KPEPǸ:BC>JdmhC!I 乼GαS}4ayܽW=ɻ8_ϊ *}[r>!Oq] -ʛ2OR|#R˸X6ٌV%p5weߨ#n %~ʺ+t 1)f"kP^N|O}䛿[_B`n[|WyXP2T}tNӠpʸ5~`:޽$G͌4YT9@b-1F'pWgEQKsH?-:UC^EWyDy=@+^?K[C{QIIBks =-OI׎sh;%f8}m䷐\_+}yAn_RO+c=W%YUa e} ~f8ų`'8V jl+ݞZ8+%k+9?8-NYAƲDߕ,?ž?7B7DG~I=Kt+c%< HC8T˘[KexMb#~Y /<S_Uv  x,zsQ֩N6ϧ걘RN.<Ʈ-mq󴜿kz"iPO1oU9_{ 9-ɘOg]P*/ 8kTnJ|m8<!D8d6C2F"䌉oҙVCcbT?jrs@kf%rR?z ~I_^V9&=d}y [ !7<9HC[ )>5<݋~5EGf}!h=e|h_s+h,c+9T6sG3á94BΗ"&ܿ-%8si^Mk[P>w)cܗe-*:|[p l8]4'wMBy7k/p'm>:.b=E>?e*BqۗURPX糹/w/O2{hvWhoqwm6 S)uNoC;Y{.}B!gk _ kw&C9ylK֩_Bb蟨n H띲 imPK߇cLNt?$ߟr#sc]`.O2qq+rNvJ8~kK{jlGprNk\g9/]~;!Mgb]*]Zs.1Oӵ/E%$2Fr+>c #dCWMSO)Fq}Zd,5C_cx!qIu];%睑N5|!q 9D5d+ޥpfQIWJ=ޒ>PKo@FARAbŎs=A SwX.<989%7j^>f+{"'z!QoJun:YikHwPLאʅ>}W 9jP:-Z@g:2.J&b4o`e}:RXb?|_K症؟A;~{=~a0&V%̽z=G"gzed}+ f+G9$7ؑnjC}X{OcC^ LE&=_ǃOk?Y+!gMܔIig`?ńҖylI|kFe=q|俗1p7?'3y߳@>r9:V*(c+۬шy䬍Y? 1̹[5 O|M=t7يоoR9-k}7W)G5P˅xf:}֜Gpk EoU]*GgЏl'74q~1J%.d]@*³:|ڷGuF4z`{~?,v2PywvRV+}YsK-r["DK^ >s>!v}j8 yik GKzնSI2rյ;T_@l[HNQkT}ᗨ^roεճh}dMބy_ݫMcCdnÕ{IIۘ-=ϴx sWRǟ 'Aasy|>6brGH>I5Jv1Zk(rN~QR6}nKExdfD2+> =@G#n%zd\* XpJn -NYGф[J=pR%bY`;z,C+Z_o@qAX P/R0i}ѩXSǙx|=Kv疧O:Ⱥ׃ Ѱ97!Y>:t.PKp%}s%3^;lq ?U}of+^KRNwD51\K5bZUj7!"d#rOVsM(' r pU>o^:ϧ8GT aL?k⁇z}+Lmo!ƒgY+4{ArU?!|pk,A< {A3ҕw J5~gMvKĪ؋l;Ev.i>>"K珐5߫$k\" qd\Z9b۽4.Ͻ[6r[pOagoʅi;^:km>}mHdĢu\pNpDO5*WBob\b>@b#$AYW{4nKuR?ׯp 7w<\>en.5if}yWܟ6m{_KH܁8; *<(Y'SwȐTDRNY#W:%Qel+|ɑ$[uDc8+IW\{TT"9 9NwFA[U{փp*o3y?5O%%nZskмv[ J_3G[7JW"ׁr4⦹ 2dY9,Qn5$dnz| &Stܛ_p6Ԩ])+H,)*]>2MQrkt T{OvNJxm ~Kz#ہU#7 (lNdw;8NzMMQ\>AG }VRs!f3k7Jo;ᙝ0SJ;e[ʆ@wIJ p5Ȇ]NU[0kzcUy.Qrc_{vߐsf|p#Ƚy o+[6{F-6 ^ [Uo@bw1l#곱,o ~mCi|Gaf!>wVd#D\ds;GTS&sYT}{yoYJlO^NEܝ87s_^uA1:W7 &no<>E f9}s*Wר Q|[=C$*}==}<9D`ǥrP|Nd2wwamveҝv.s0{D|>S;g:x g x$@Q]=]ȖOᬸEgp>GnV:3AԸ2Ɇ0`n㷐z n.T<<`w-@r-نT޳or ;;kiϫK=Io$kABވ;6D9|1f}SQ^g͊;{ދgY$Ts o*H4M6 {Ari==*Y 9ahx#l/QBU̡Sy~cl;ޫ6)7N5@GX^آ6VT[?* n!!krv՚\_٬ޚs5^j. Tu^CϹ7ls:k@^1OTlj䚔2j9 ܤ؅сxS^s\ E@lQwm,ؗ3eNu{W+faA ZͭLڿZFܭЉUp ീ^6v { 8O b;?H:de ux2yS8Ij[kP wgαOUhe)ܝԙm&Hk@5ZwYgߛd|4psgz':`S!klU6;Ck73xQyU>j"]L r;SO=׀EܟHJ}c:g/1Ck_~W{U!Pd-7$eDyDϙp_.eYQM<>!z%s,v?τ8ׅ!s^WݒittZ|}c\ OtY6 T_*}<`'H\_ҫ7+S|崭4qB>!Cbhݤc{U#bNq`„k?tաdV@Ę5A# E{qHGCY1=ȣ7uگg _C:Ḭ$G!~ k᫸/LSKKn wC}#$v'c=f+c,OV%*qE^B>*?myspU \m$lC:HdT'ZP^%dmؒ:̄F||z#B3[^ Nk_ccm;U9݉}-bCvNJ,ڵwe?`fXп ;HjN!;6H[ϕ|(.L' rNwB}{R[݃cy.1\^TϣV6EY:o8bsHf /A$.7c? sֽ*aq)Bn~ה%75;1g3.??^]]|/2&c|nPr9z8 vK!y|.^7|wZ^d|Ho8=dȺ륚O5P^V:l;;٬&oQ尼 ż2H]>gq+}ʹ\QR6 =mZYj:7JݻGלloz[ȽOm*5'C9^Ρ;yynݞZ3R3,3njLU)^- Fk%$}Ϡ[/Ѷ8V'{0&)rۏ7GRo %4wGvj;r{ȾNw,!},/-k?>o7Eb-G;*;R/UJ;cW3\JL}w` qۛ^ߖ=pѐA,רNu!I{Y\*Ouwm*5 t,zu:X.9Koyt,c =\nO&@AQTxc4 iQ^jX=0:ܿSlf:ۄ'9w9[n9w ߿„WyܡC 7S:U|&ܿ%kz s(j/ @w}5.|TkH$Iz©?oDγ>PN!<4*zS>[|tu|y 9%w;U=y# [ ߢ}Sioi3&sK~C5*y#!k$nPVp  ArF~yt"d fg%s2oѭ&uYDQO'~ɟ5^N&i|Y|CW#ĄWy~t]9Kp>o]#d}}ZsCJ}aE~ kålԩ&; α헼-s0^R穭+qͤ"~Z>Lr5vS(W{wN>6ӍԍSA9ND'g_unM@.iMqPG.~h>ݫd9Nt| Tx(uN%y.HdGٕׅ\I+/!kw?ϑ7by\=}v[@/}f'ΙОm}WxI[3,R|ԸL#U7y[+^ ͽ1=>$9}$Oa*ód3H\39xP)|RQYOb#g{׌3S{Ha@m'/9Qbs9+4tCsXԷ)\ߡ"iIN=dbP*w/ -'q2rCx _>Y^ܶ?BrM!f{)'s}PwYCP^Irw~+%vjg$kVXOE&eۃMV=&_$?!{ 8D(u}x?;}κtD} {nWþ{En3z7>q։n[Bx)E"8{ގ"aSNQȾX;.x5JΧSlKjz.rB;zy\^7H5өKcexJ^V64PΗ[^{ ү~W dGOJItoz[(-sy3q?>B(x줾/qwg^A_?~%.ۉ?Y`?9z#ch{!zK*/Kߖ{ {qm!yw==$!Kp9O$'Q=(]ZPʵXgcEu_yqd_5uPx"ג=q[TϟAgJ`;=Xp1<-^d,_h󚲰޺9i,q_.v 9?z.pjM8QZ͠")ruh&Y9lz-0ϊPgdY^C|~I}7ףν7-UmN U~_Bg}CrK}n!P 䜃RK9(AzVڛ>=%x_YqG>FyޕyLKk9?)+ۃ1.^ Γs[/y|4)9!vm%m=E7K.yMuQ5ko!Aց#xt{KgrgysY~\V:5ϲ/!P^9DŽ|?7ujn7Ld೑HiyB8x Z /y[tKNS}Y3z/_8Bx^t/O:^w`1l~XY_ -'qBlz}-Y $7Dߢ~[Dm?|@>hSP|μSuةu| Yԏ%Yflg uopqGHN}Z(+̸B&@4(^82Yl&H5wi(>^us.23ʸr~a՜syikfׅsP kV<.dCK?đ} y]J:C}>(| KU_rv~8jdor}N~~_ .> YS}*c4Aӿ1!d*C,qq")q- MR n5(9_lgKX|vK9x ܔ1o 'S,e>P?[Wx)w%~'>"q=\Kv q]@։o{ ?=0^|j^c4_Zv}jlU.YxW [#d͙|;!k*kːo)ג58rĻ2돐ڵ yOO(P!g32.J݁y*]퉼|~o ܓ>xSGi <'"n`Wi6CY,ϭkTu&nC_BK>Q>'ľ;"-1CyD?s8g/ w^5CA^Xɾ6%\-211^|gOy:*Y#9 k5ܔ>%Ȝ TENЋlSNaY|Z} pRǸGu9 rS3POD4I$b=l]})2_?kڕ#dlr<{Qo䬇*m𸾫?R V1d]"Ip_GDܡ:JtjwdDNSs'*u}{}9U;p!کI'#(̸͜r-n'hM畲^%[-l|8rߠt+| &gjZM~UbKfvKX[yT:=|2ZqwچNq~|skd,ʘi '˾;*9sVny(m>s>EU 981'suum@\߃ ;xsiT6xxނ!U':lzO>`~5Nj o^xoT{d"# c;|of1Z_nxx}&UX+ 2ޠ~Cד5ΣұAʒyaqcUyTCnۈ7R>MM}Sȟޔ{@|2FEi6C;sI/G#X8yo~!13GFp(p=lӛ~A =~Y+<Tb{@WDWir^ XB\TQNu:*Ԝ 5ny'>h:Yg^un s=f2w/:%_k(|Qt%HyA_4Yr"sWt)j;Z4N|^v\-_uJCyτǢS[+kufY#?4ߌM۟cH{Ls_!֤)wl>v1KܣO574.}#J#*ZnK7q^ T/ cl?bMg;2CmDQ%AU^" ge (mm\Q' zmjgkCXJ#*;3}թqNM 9]E%Y'ȿ7❐e}mA) -!4 g^}zO kdPc;(Y#i /XSAq\GI8/:qeþy|stLߌ;XI?Tg?s]6s ]1ki[c@˃KC$g.um??ZRw4"knEor{Gk&^Pz=NT+L;%J?ZI2ʼmQ٨+T}zG%V jKe;EuP:)K"ofIKkY~]UNk72$p8WY줿Y&3|kd S5c%9D`;}A|:@[VgȧAg}Ne?1So WPr>Aڇ>[qsl*D\پz'Uy!k5VzR.KǜeI\7ѐ}Չ3P(}S~XDxtl 0g's 7j'{b{jDT~QAP}!tFRn!AL*Ҧ:zPoN3bS wj ɖyL. Ndc< 1TSnBQ>sÊ62},voQ^T/V9P%P}YNh|~zZL0?rsgnC{WH֭ok]uA^e(ц9㮝,þP}>ճE7fqy.@k_u2j5Q2gR5^TxuY-;g k[`syU{;cߏpՕ{2:Vxx(4HPLm|Bg k337~i'swu.Y|m,q M|,X|zYskxB3jͭcl9PیjoA9|zRK |W%6eYh RָPa~b=|h݁Y.xpzXB-򰉣T{ }=;{Qt{sow`C3l{lSl;Ay ~2-c}v&ʐb|rXC=_ѫ0-QXsYq2WBkœ, 7T:(vbmZ_k|h7aI/z_(`?5G-cpfT˕I__O~9MUnIܗjwz2$ܡn|ęꗎAo ϗr}ϯ2g4biśzi+֛?*Ati5)KRy(7 T~8ϵVܝE3y[bo%ޤ:)}<u=9=m șI ' W]]?>c#AiluS/O'qw—?_/@5V4e;-ʶTB9%\nO>\PϨ:r-S\3ºsi{|.K}MZ3p27kSa2߃]^;J왕]1q?BMXyܼFݗX7\^okN%Ni9NkM>ʭCVLs3L y|-Q]ƐO`y.eMu. /C5WG \] k}pkpE;}Pru >IGt qZ3/mz|6]rLo>uɚ("3Nӊ_SʒoT9x'TaRר~kM<{Pv2[Asϕ'#㫵f7 7궦@ϺT\ruVOO(ߑ~q+~.6n^gC6D>Fj{)P s|}R3nsN+ݞksI:n[7?c3֯ weU9}7:?u)OݧJdNBu9͚o:ez<{kUdT.+u]~o6_Mfũ ݞ^侬PSCzM428wDS%0':o-@֍w՜{hҌo6l #ZlRs.+分:`y)?-Aڄ>q7,K[•oArxv_eZ൧͸YJJtV(o:$Զ 8=tϚw?xT26hn\*4}\wUIwLLc-Üc\V|Q>ӔZ>K;gz.2\-9z XZM _z[?eXqkזz z{ pOd>-ykL+7wx^SsO?ۋ^^'/6mkR˳&fvKTk@5k^Z KokǏΈINmck!sGCk?[+L3[cƝjx3w|]*1wwB%{Xu9ZΥwyW]Sa4 \[c_~G7Weh~*(1Fk';~i+[ߊ u[l5L*_.'8> w shP_=Qq'?eO*^]9g*`kKkQU|XqO%+ފ[ݻO’y0)KiKk|yDZCq)`6[;סrm~ĩ.gɩ[w~Lj{ʢcɳv<6Q%K^^krN}[S\Y͸l_͘.O<qQՈq&Rx֮NMM=c=fGQ9jܱXħe (yT{,6rg2H9Q~VQd-hlm t>0PYrաֿ[z ޴Q{^O\X?cj̧u۳?k[CUN׊@;>hI;XoeCs5jYs(}^g8Tnۖe禦Õi5Q͗|5d&Tm٣d7Rs?ݗlykqWuyX}Z$PNX`XYeM rz Tg@0!̟WܛcIv1ÀuZ7=golZgkn1NZxܖ9,tXhَU<>3}]3(Z}mUOt<֨||WYCεϼ]|`X|\o*31׫֖nZho%5GY%Ss$ٖDc+oKrR%~s(C}]S\CåV߱iaV\+uw61`Uy}߲:&A5ף΢^Kg nn@Rxe>*X?Gژ&ՙ^kZ KSa]ہ.lE.~Qͣ:іҩs[zU@3nu3 1ߘ^yQZrU/qYwgdK<`=!Xq2:p,es[cl lqy4s'։ ?ݻ8kxNMjdHNoi%#b>uii>̿:;_Ƕ5/nnL~}p4UT: *sr_g*cUqu?&C?hn ,;U+,UVa?e>}AA[>C^,W :%XQMm&uOzƟ֫%Y/ȟDm)ߣLAeom;ǒi}^&':趨8㶆ȸ~ߎA3;}ü8aSְә#@,iok]w+ҮWQ̸/U?r/d 7\~N5s%| s\$REhΠPV4_v͜)(7oEo_ϼn2rQ˳FA@`]s}$v<:E:9, O)KK(~aNWB0Su,etA/dlM7b+m"UPk'q uq%jBm/atN 5;1[,֭0w_#=\˜Ns' _}ߧ{n#Xx}y=we5 T1P~'ܩ9#)N5@{T9dW&iܱ*-yN0"k/>zv}Mܙ^!rg?%V:uW_Swk'`˝j.;&@ɚ57yxd]җYlo{xW W}2-ϼ}cC^&ܣcQʝ*T[A|n>@/zcmVwب89t.kr՚;-uY3ᶧu OW{˹%۩IKlSPg$L]{_$a1b m#_uk}*Aڛkb፵~ur.'QdUi*(xc.@Fp>kZ0K~~(3]lCN ĭ^f Hyʟ:aeZS^rZ6?/+_~X+9SkU^ZpQ͟QϛGŝힿ*Yrdf5|LqmpIr~d{KЫfnmwZK3v/}z5cp-tjDcQ\m,o.Q k4 s-CC4zo­XBCT y^mBF me}Q[qJ7zZ,j vk R&JG[8zZG8Y,pi?13C#%DŽ4V"Xϫy_[rtL59s?4Bטּ.1ס(9^yԈWKz/$0s8n%围n`U[j,o8;y,s9nr1Vq>ޓw"s=R=}mNˠׂ uέ6y5@Feq,7ϘsjPcNMu[>x ,@q%T~xR^S޳ewsFܖ9Tsߠژ7?*}JYT;Ί[PuMYsZm,aN9sSGMsؓ'@5dDJܷk+,;\z[ACUI}RKn͙ҫ~M|>/ƜѾfzg[i\IgX@r? ۨթj>u%1((㼊g2wYI~`jM2*y 5Bܙc?=s&es^Ojd)u(c=՞yw|#w-N-l{D5ٚE2T}C[{qBH&3<.52p2wy| 6omsuL=D6|'a?(H'Zk's3Swז?q%t$AN4I鍄zd~'Z>c3sy۟7jujssGn_Ae0.qc\28lDܓZ(`WMcl,rN+nA^U_ܫ>oح3w~͟ 85α?O7}SGuusoOLAVCgzX{>[OZ9Ux g,о^ 0 ̌;=\A̸~ASk}_殾{<\`;]_قwj锽 ~=ɖ ۘަPm>OXq_>M|*ߊ[ߡ֯ӊ7sXm}(P!1 JJ1ץ ?ߪ6МiGHdd[rղ) [:7b=͹K_>,-q4v/ 7ZPezl[}~n >Ak7j[ ܡ j+3`*] Nmީ61g^,! s{5rח6]G{'2U;w:ۢ }Ӣ)qu^^T˹徆^}5ױrG'UzC7\qPuCb=Yw"w uhl;iɾ }^;pZ;~P>r /j[P\ ȺlS^OJZ9̪ |M 4vZdn+ުG{ȿ͖sC c~ڠ5, c j2ETD|hM螴v6r+ -o>ke&RUި^ձn c -c}pvu}kP6P ߀l;> N~J3ҕzS2Pd;e6ͼQ5;l*O5:nH wTNRϬk;ϱ[_ǹN{[NRWc*Őwr-:ԲfM 8:sXKkQSc v"ߢb-oJnwмs4"}yNѺEn}xx.*@͡Ɉ;}Zh<qA1@珍jE]kJoGkρߡ'q|M1̓4s&`.VASYRW=o;cgc ;aXg@2l;㼬cWsf*C g"<Ǘtܖ3?ˊ;t_32 VMavkoUi-V}.}mߟI=tL㆜=_ns4C=v=oeMU8{3n.H72 seHuNUw3T?6nMLШ v NSn:%k0ֱoh;9I}\͸~` ,3+̍+QVe8K|6j̣/k;։X}WZ7߫Zb-AZ s8iqEP.9?52g}z}19?a5Wl7.b1muyiIƶ.4)uj|Z\ő#>\4_NQKߞy }NASO>CsjXgl37DsKY5r2 :56/1dv\-@XNI Sb7z># *&7 pwK3g9Bw=Ta(kEѱQt JZr:pNs hD TgCen5WU+Aڜs\Pi`[nO1O-Y {,Jyf2g=>;9*"ќfܟ*yھ7Qy?[fNte+tCX/c]FM 7,T;HLOVZKmX^dn9e;Q^'{w|;տlvil[ڊc9s`_o6U6o澗f{/<+jr95-6w =)YGNCa {8@2uƗfg32>Cn3YFܽsY-Gx/EӾJ9\6i8MAȱ:ֳ٪}gE`8Q{uz7PyTƖT :^{6ˍq̞q`v筴Y9,˚4egЏ7g6ݠzFOn(Mҩb}ST6kDm㜯-K>-mrsIİ;}le{{?ͣz"bcD#r=WAڜ8-wWuʹl͖ySԊl _fܷb^{?jX3y g30i[y.syo~ 9/5|(2P;L@'JxiS錤[o Zu~k&y<rJ? C $g\d+9wjFA |nl(erd=~oɟYcչ'sNǼ;/Y /ʱ'Vfn __+- 0,(U<΢ |&uPu!BlT똓!}ѫJu۟ :k=yjOМNESA}ѧ*H7m~ >K2PV^I(b4k3(wn yܡ1E0/kG%exuPt>ha:&5w_lG vs7KPzV擋1yd>leXtُ`lgM|^7ᾑ26{c%oy"@/*˥ij8Cs?i&!vE{T1-g;ϺZYBhAeo2֤ȁ^q KxJ(Be kD:n!v_+y cӵ7lzhmt=(sf LY@s-y>P6\ i(cjlh:"ArbC;ch[AޤCg 2 g,P>ḊۣNq_-s-s[Q$ԹAt/H (jKm?< sd6Gq 5Fl7>=7:Ծ ;c_[S=DӒ!`UPm7w,KjL%}XfnCGic;=v2s]y/)d#ҦWҝnPmד̈́21[o:WjxyKQ]DZM%׃)9깃]=_pn 꾠/:Kѫ>b25R{5_'5蓊peOl=*y|Qt|W(u:zX븿C׹T9^/$RM!̾^!m`GWs(]PUyfzLI_uJ"k}.#Q٪A0c'?66lݭ}3SCs9p˕x3g~%_k^+~^suY\ۊM;+JEsS^b|޴gnH~թT0Al 26gVܡi(}Xg>l35[j}FHԝcwZ*Wvre~s͡BR{'շC-{khdY[mPr|>pP<|Y?gznc[BqҾW|֝:ɲZq_v9j.+Mu)Ϋf=Ju]뼚͟?.{mb :ۑvRJf xϛI[v~օ{k8]+;&.m3˦WN$N3_Қ`'M|A35fXo6+'w_ߍ#*:._IθӇv}Šg{,hí`U*2ގqXNq-撀:6*j56PT~%AֲoW]_ʯ0K}:ނuTۧ>XUUӊ_5ykF\3nϐy7r +clE]ekp߀Z֬9 4ZIC-^ܝ\gA|P!ZX'kP W]}3߬įPe(wV=#?Fk _vϒ%'s?K*κpFV`HsՁGyN(v :mu W,gkzIRסW'fA\|ֺMTA*A q=ܡ58 ճ+а./qOX52:@?k p! uq՗{GT65wcn ;]sToZcq<z-VirNSS+NB?DWKPP99_V6rQK0KZ:|\ Wܩ9 K_+mܒT5vW7[Z:'2@5p5_ uWv.-뵤C; w2,UZhtg^{굠8ÜS6ᎍ.eޞ>/ZQƏLpϱ`-cTkq9?q-?@WZluN ci%ΚTjX?DfkBCwRu,Q xWl;}C.g~%a ckjFyoZ\hܡi %wXG~Ss VeкEߓ[qc/^/母%5\* cPW]?;845SItj{A}K賺`fTlD勵rlgܩ_{އZY\ֱ'5m_gn<>Hg{rާC?yx*$Q=#hIkߡՊ;_ks=k(Km [ҋ's:eVX=\GSt,åU =Os{_uꚚva߃o}U| |ۺy*Cǒ[}^;y!Nϯ9=o󙖝3Z`ě\98^5,&>Zl_Jv(#>n*P$Ǣ{@ðAq'%TzUܥ,kvZ˺Y{=dr'yӋJl1mY# kVϬ;Ǟ,+Wzno ̭3~)]6iȄWs\Zl-|f*=OR'svP>(mAS[%WI-Pf}#Dm,k݄JsSvBն `\MF鿣Erw2sȹOϝϳjZkc}{π>k įcZ͸l3J*kC{ྫ9:9,\™(m19_ʐëq oUF5Nܱ#B-׎ps θÕ:|qz3krz͹?o;4:{=}ѩѫI>OMɈSvie+ +sTmtΌ{TmKoPm/layd;3[u6YCqzr'߷pNMs˄㊾’{ho*Fz-R&jskm E<6bMЯh}Ws|<14k V{@3fξ_24c;>)ڏu[d5AmO͹rĭ|C9tLkұoӌXbYGXfZ2z_e&#'{_9sPlH6W\X)I9Z yI]٥Kx6ܱ/~>8rN^=@_4(]1D#swD1mEَ{* mݷSĝ_=$w5j퇡ix%?kPckZksNe}ҫϊԘX#hpFS$W+Tu_gȝxm.4}knr~}c{ѐ;)9 >qC o>Y5C-Z)wP i%ͶX9&%ݩqXwd[_zo["V&Z؀^[#7JOO }#籩s2$kCPшo|$ς?FE[p:[twz/5[Bx.P|E sA^Vx۾ж|"rr}N342y|VIύ8;j-quVsW'Pϣ7}5uirݸսynlꑫN'k׆ZUle8 EICنо;m'fj)N~+ܽGXt7gUb{N꾭lɹjlv^7XOgeKt/!̝V~k얡ֳU "V·z7SsF毤=qvmT& {WW .ŧy-y.IJFљQݜ'{տQCі^j^޲ 4dG#nZ|OhmNqJݫzJЌor²4}&w/[1w@e^6~PvjP6T_шbj]Ig]-3ORuwlMTc==Q'3s'f Φ&JșSnd̳`;T啞-dnuFR)̢zݟ_Iqdn˳3-hT^Mʣ x3ߨEz-Ĺ|qGT~pMk+}'r!u~gc|^!5Y"bAͩϒ7s;^XM\' > \o>oRsxSPkߛ׈gfXS&83s 6k0o1ozy9+;sqm};'^`ޙe2+P$@#sF{{σJ;4M4^Kni/aOCCݷճ j̨\,cg]0iC}>J;3gZA/Tg fBj2WuKT]IZB㌨WXo Ϗ%I\N#;>&_.OۜQ=[jn+\˙O>7DJjǒjj՟'PwWdA뚶 'sߖ{ZeudLs4sc]e.yy5Ap?ߙr;3Aw2oӳfR|(W+~ 3:(_,5/ܽwB<q2wTujӼ,g(P@ٍfҩZƨ/e=p9>1FWc`(ױ qt{. CP2QuPo㉊?'۹:e`瓸c5!T5{O|ldjM7UXſt>J.+XTMq5Ap:f{zk's͘=7s h?Jzt1zPCfIt^#-$5 D{7tu<극,ѰU]lv+"_4eb?$5ƂaJH ijAڙ01MA6u93:ke p#z-bo3e?YrNb+P`C}Sั^~kζh:7m;- zEP3w0n銎 bӲy|C<_C|"w*Rp2wTq95(R~GgoUݓm]+7^LJZ#RN$ֶJŭrV;'k7b.| E+VYB=g[a{pGl۹nI^d>[>]SנtJ'teΨ4#1_7[Fu_snl]x2oϣpT>8Dp_w,?] 776W<Մ$#+(3︬͸!k:q^Wxj)0mܩ) m ;b:$덱jBc]C }bdzjIyY} ^&/9*OƊ!^h}藾RqqZlc[m|ⶡm$c;sDkZ ՆR+|zTth;ؕ jXPT'V^S#~;է j<3wOvGsy875WhռMN^YZA,eÅK[ ^ee^e+<1ghϓr+mzթ1d?*P-,vK];fwH^ϸAx*mǹ=PD֙[?gfKA`W2w_s Na̯(s=5SЮ9[t[s%SUZL?|ɘ;*B-K,ؠ]eI,2;HXyz[ફY-o澩LAVLbFߪsm*j> W~XCCPւ#xZk}{1ɋ8McwE5LK_ WR:#;}P[` 9 A s>Oku"W]k1L(}z|p/7oĆ\t;~>;sMoeq&jN3[C;1P8jf55 gܚG%6~Yτp(}_[Ps^ߕk.C4.k绯m^7[T:#uŹY(9<ܵ O(Ο%шidTbTsh`7"a`t.0y5az>Zϟ/^ s͸)JsM*w=HLm&OE@|ց=&Tfěj^2a8LWyS:؀b;>Gш+0x|g\G]uJDŕ )\k~l^&ܱn߉;?ڒ+E1>V6_>s(bfWAP{sb7rNWq%\tv'ʽ7Wrj}Yy'e'{ϥ >grTfۨc?Ym{?E=u`9_0Bhś;w&JӠti*|Q+^yW 5m>6FĨu6wd)5N}?avD|X˚u뼊@e L L{._ngUwx%ww_*}Ki\KI^ںjc[vEC} 6$]l%xhIwҮ]uN>~`XЦgi=zd@q;ֲ>]d)=" ZB)yנt( gsɮUBWsx4֩IY*SЯd}[C3Ǎ} t t|&8݄VL1?6X0y_s'5oOȍpg%}np>;&kr)OۊZ-v+۩ XSxs'}|r؇E{sJft*qFeC@vucl@}NRRcS䍍Fcϊ2}z.vUz&I,ϓ7sXyҢOTx2D A?ܩzcCkaWcN%QɈN7ȅS':ޛl'㘸BuHkt؆^Nu<W9ي;9#"o\vK->k粢rP=qʼ#:֤sQ,3Uo[{֩)cw\jCgK%۝KSc=dz1*y 2*!w,|8ׄ"7qߪ Z[l,[#dM1(f}gCBy=B׻;n:H~ AAކ;7~i֯Qo|nlNq˯ 7Hn v ,_r] YSἯuRv~îz|}E:q2z oAeUWTNHO憴'ұ^٬A~{[^Y{j[Wq|oB79sCY-؃zA n(塹l@e?PLC \{81cu; P[="$@0% &!ĄDI0 %_B ͡D7݀J`c:iݽ3?uziWєgFm$},[p-{dq3_ 1f,ee]-E\낤6kivd"TXvn&ky|ӳd>wQk ՄZٹD\8W~E.NX Hx[fC$^ _+;Je }_>.\-E-QW~P%ezZ[+I"tFe`G_m9W֪RV!+HXؒ&8NEdZg,eO+qU~QyMŷj!YqݙGY:ŃO Wv 29nZ j! oF싵[g ZA4R9qU{(qފ8giZ%3!ᣄu'D!n1տyLע'K~+fi}FҖI'CKsdÒؕ4+n*wkT+XOD<~ilԮm0⾆\#$é ('kyOkl-zؖGIU,H]K~n3poep?_9A2O&>$ioJlտ%˭2[^|_jVHISѿ*[TqVS-w/Z:W\5b"}_ZJ"M}Z>"mdHTٶ6lަ/!RY/lPnÎˎ{.vgITwg|2Q2%? Z-#U^_s&77=_- nwϖ̓zYǦ%c/B-[![9HWc'ᒰpw8/&ڱVʴ4jrid2"ÿMMj;ܺyyNқ*jtr2!7&l*ZʿMU &Α\9 UBN㢴e2  Ԅ*yەqVuwUb w!n͕)rSmq.>s-*jeZ}q.]srj0~A_q²4f2m͒eTzS>KJkqKeq%snoDU[}&,%~wʫxl/eOLg.4Yރ0Z[fQP!.%[EgհlY[E2=ׄ]VV0\3?E-4ATOS"ޛjqQ$=toE;;EVk:$UAg#[hjN?qSkW_O쯗y(;,L%ü{{dU_Kg2m*- Qs$Oe9 [D .OVZMkȼʒWe|ҙwa:_$wLӤ]9HI۲߅d˵v $s}%wNx-[=EדyJil-Қs~S2K_U ~h 6j+܏mZ5Op@5)|bzDmNƵ*S LoÖ$SeZx\o9AcRr>75Vi[BS|g}LgQy絚~7Yt0Qml HJK/QWf.hLZ[[8`bDWsV*MP~.Z=2-cseaρxCƹjNL2, 3be*r;J9YoCX(ô6q^= ]LU삄ףJ,q9)8 7rZ[6lUcH[DZW#C@Ѫk]ͷ|>){vO6Td KX5zbTePKƻj }5aߪe> q BԷ$̭]?𙔟 q]ڿ4m"Qux7O)rMJ_Mׄ=&ζy,"D>jf,yy!Q5Ust\{wD:q. ςԥ g[h}܃~hmx Z$.Hԫ?j"j8ɞqhl9# },6x.U.JA[g iZO虺կ4e,=WcCqhn|ƠE{-b"7IUBd{I$*"=OnxN}V U&&"Du/q 2u$Ჰ ,/"T\ϗ+C}+>DO:d[VBa^ԇ~WZPEKu(V蒲 E}6ˢ0gB<=kef_)$/ln >lC)9.#aTNTH΃/,x1GqUj%o|+oBҿU~[gtυ>lEVا*\-O'v`wk|z)`l ~|RWRQm`+e^?_ O TB8`,v g/—^ Jq?}QXX M95-HVS:B6<M9%Z@'}ymUw.pqBYwckqH}5` =AMW }D};Jb/ +;女Ai̙$/v+'sfC4M`-A yZ*V l:JmJ\^V; _/`KplzpO>oT*oWr aP |5|IY>NyqMxNp-K=?ןALڃѳzJ9;bdkTv1>'l~Ĝ=,{.؂[s!b΃Ctj ӕX HΣK! y3 33~EnO2|AX׳JR2M/UoMkR-Sdo(_}#|KsTE5)7UƬ8ՒΕĞse{^] 3Ѹ5뻟_SmW:hŸ3dTᒰCbh x2c߻K9.1yǿ?>M=ZV.zM7A<u>cYKv$|4A{*2Bո\hnZ_Ekܫ{n\GEVs&C|ZHףd=5*l)hV+\=*}5^%7XRDZS(fA< hxm ۥJ9E<'í"ku7-iI%L*;hͽYh^OpmќYq,|5&=p׊ύeZRug[ fϟm :'7|ZI7Uj`H(i<]R~\9w|d80Do!z.DZg_pgC=2{v/l,2fe&4mCt~ WZ|ELGcBLt8G$OՎ#0ԡYNE4JewPt)We?P< ?xUkpJ:W8Gj'\LxkC)!*[ >҆Z᳏/$U1ٙ+/QG ݝ|t.`dwٔT~&7QvAb<[Ec?'du6%c%=$]Z~\+q٠Cu'xͤd^ lvkJ}LJ-X\w?ל>MhHo 57T4fR_"sܱ9ޏmHH$/洶`\ScUѼ&7$`wI +o6ttfTݤe~[ۿ+cJLDﹱv YTy> r=8ܬlm#CG}l;'1cjaޗ!Uwq\.4UᚲE;ן8zDsu~Jk~{I #L W!Ņ&$*b6I ae~j($+=oҔ:s\Sa~M?wN[({1λA 6Ⱥ8ӊ;0;W`6/}'S>r.Bx,?ƤڠQ_ci>K!o4\+Gl1͂ļ-SC([d\wJsHƃisRo`6E}Em~*0"DcTq:7͏[ӹI~bjϦ45>`+S 39D9jn[CsD}`ЩֽF(kgVri8$S2%ؾ֗qzl $ؠICKk{b/EE<ޙxW:"]4cހ]ͯQsy3Czw=}n .@$רτ Z{ S)_Z7lqgjm2yYh5.)"O| s]3*dg- ͝1&vgN/>z m!8ʾ" 6ja"r| BO6Z@lRvz_Sxƨ]')^ݤC}([OŨm"#ļ܂&DvhY s#v1ekk2MלɶiYfKkѿ#$Kr Fm`L~NJV,\_x_A u3WD)Hrd=+$}PPX40]8om$s1ǿgH$ ~FqIh^rXOuz6Uۋ79ѝ9''4M1(Sg2ʞ!j P6δxE4f9Ycy8KkM`#%V$1{EJcɵfO]]Iњj["d&vC?xr,t2/y8w]֡jè<&PN4.Vk*=g"Xg>-Տ)b*E>k%ؓK9G4b˗:L̈ 17z ڻB*kѾ`Sis ;#@pG~/.r~OCfAk!n l3!Q̄xNWu ޘB8˼}KogLcTEO܃z1ۇx=U+S1~&mX3'Z1!C{-9ևh-Z(RF=7^kPg|㶰` LkbO4P"ؠ9]hʎϯW  "O: %tuzoޟ,2tlI2] aL?&mTw,,LIqr?i)_MeQ}s,W1Xk\59z9zr^"f*>w5TrxҚ8&xDyƌs]ad1Q\E&4ևJeH<&mq>Z L͏y<>rzNi jTל%S)b@˃sL*oc*EC%>Gl/?.g'm`slo@"r߂]Uu}LZzc0@%g`{Z{(u8!Mchqg==׃Tc5i% b6Pkyi.2=ݏǹ{\IdlKr9Ycc^1u8 ^סgrE [kcP%l`OUZ7({@I g؊P{<|i_619uCQ*$6p9@x΁X,SswWJ"q<_Zl{=R5L19gKq3؜x Bb7>KF\ kj1HM٢|sLM;nM lpM*KyUj<2R*BűssI<t}O lڝς+lr}mA=0 꿏aTE!E`Z^c|9JaG*ǹj뗱}KL~jAk !< .{ylWPFb}1>SS|\l>_w^_4ۃ>5dRr~(oAX G(v2ݳ^Wec?^+Υ`L6Ҙ`%_Q}FF~Q?n(}lx39=,rIA٘AzoBzZ3ɩS&j;TᙲA;L*Hw%岱s3{"T9`hM )H1cЙW2%?{|cLM'xX%.C}\Jol`Pc}Va-{uC!F91v}6丠o_gR6pew\"Eiv@nݥ^> !T58zY*>Rӹjb+_2Kk}f}h/WMJb|DP;oR~% j_4w(&l +BCl12al|vuh=\8: \Fbb$ld<~< ɼƵ漾'&\.IǷ5HqynZ3L,=GG\=a:ٓRq`Lo*9!16L%53,Pk~96D幗}FE- q!tI;/ vkj@+Z))-Z:1u9E^<-3ŽVcfKq:3VsqLudVl`rC\rE풢] A,\0E?ˀ\_Q}8 D^?3u=+;,[ `e=\?U S{#l?9@l!Ŋ|Td,s~-sT}`*$ۗs-忱̣8Ŗ-V4/+ZgZ+gŽ?z!%b=OTkҖ VH]jotLѳ7goZ& Jy *T?U1qpd`_:ϥ2%<-}\;4=/]ccv.OU86|xUAWSw:<&cyOn*`6sX+֗cST~uLJ=̜`sԖ8ۋSyb&ݤ-)2KOX~\tyܴ9Eo;sq\mP*_w!1͡Dד{d s9͢vSls9ԩ*ov6ƨ8٘!ZhTA"? ޙ+y$K"ɺK=nH1 qX6H5c`+jj !5󖩂/%6CsBH<T9FI?2?Uhi?oJwzҼunoS}=>sۏ}&=d\));8My\.@ŵk8g}6agiS{Y_;Kzق[o i_5iGzw\YZӎ{6/@<*z>_עy<Ƶ=HZH yd$5(]]1/!āA<7-}2ŵo;su5+FRxnΫ_k 0έ1[o AͥC䧪g[ 6[gBHMgAP"\Aۛhg1W<|C=&EH琥<#K9=,8Ơ5ݙ_yncZ)W$\#WRg.H5,;aCyjZ!CCCz̤ ezH?˥h K9!([潋ϠMl%xgB+i-,0ǠT.d–h9/9$s_ wcF3XelsPؠ;>'|VGo66@Y?0[05|s񃦤 ԗ6A'7W`Cyj^;&`bWx&l0T!&B`,r.'|ey f}D}1ol/ݤ|FcN\ ?6rR;h!ޠb*1vEY4ވ{GG>FVi. -^=hZѼ\H 8/b;My6BcJ~PgrƊgV!#`c*l_+9E״DH6.h},;<|~3l\A^GŇWlq80;4ƴV;Nje=K֟|/K#g%ۂ~Äj`j$#6sL iA_RjD|[1Qkztf=WqAb\W \Xe؇h=Ey-3!T` j3!yuT73u'9;5-sCb<ؤ\H'MOB\q}OkC\rEZ,ySy2>^=WQ}3Ŵ6Q.V+>>u/s!Ǥ6AnE?mPsτ`M4YI}dAw'B;8Cuf:Ӓ%bo#яO S:sPytZHp&:y_"'&L&م_c w[3|G@b!Q^ASl}Vl4 ՙg5Ƹ+[GULI4eΜk)<՗ g*R;c8yD}3rY"!~7Ϗ3׳jV4o!1`Rּd= BoS<]E/YΘ 4׼X\hhAxx/1\UO}Ϊ);:s3%xT9 o|G/yb&|6o ^/p x|4naz5Ugҹ*8M݆Frs +z䅶MH|D#ͷEꛐczςJ깵%Ikjj\>.n巤nZ9CKjxI.8ӣL ^y9 ZY.>dF:sL=g֏y z{Lm|Lx_բlQώz̴te9ܹ\lI}WұoP LiK;`b=7l5!?LsmfFW$3/Бmp5_<;̶Et<i+[mSmx1Ȧg6XlBm+]6u)~x]9OÀyCPj'n$XjVc>ߜ\} 35}~;DW߉c?c˹M {nb>@ 1n50ey(ύs2λ}:݄d5 y1 *hO=;**.A]s,ϗL>[}iZ?lTyޙKOUxI˖ff JǁNd8d3uItgzy\A;\_]i~U_gpF.BԿx'C3T,BN&yacx<.xm\-fZ<kq4{VwPL\Y>6|7A&L_/XXIvȬ\(U2KcU`#! A6Hg6"y{ qf= T1*wDfM׶?sF='"حG ᚋ3ubU5,=on!d%lY\6+g-ٶg%ӓlm Z6L}ƊgՐU盖>F}>^}_cΩK+rI0}^fX,sly= ׳ Yࣳq:/ܧ}e~I!iw׃19L9==bgQàbփ솽6Y s(m%ܳ;7Sj.mWod\jz6 JY}og#ԇ^i`=;p !ݔws[5;aC3V< wU6&Q vVh]yl)hPCBX߶ ]ڧsڐ%\zQ{)ƁC!TwUhFFf6ԐimR^Ϋ紁ՓlOvj!pƺ9 d.>u 6 B@}4T{m" 3 `fo[hۀXaж h(SBԁse+a/\[J;4BXnL m@C,BX.1ӲvC_hۀ m!m.m@C^hۀ2<"BdDж Ș0|zs m`IhKBԁ]qchfپA= PB4.(ұ(J^;/(&;BdL86AV[քpgQ{mKhۀ mPC hȊPmqHcX~Z}ք hEhۀ 눝̒4|&lu^ajoӆ mPCrY*۳ֆ)m&%z6d_6ʎ";+M_ZY֐ͫaϜ\o-0{]/7@4ж j5Ոqy $m%3ZF@}yc}IB>z6Q1maYжu*m!ӶYBM 3η!\I!m@Fם(ܲ͢жP6Tdm@CBdXy(m@Cƅ֨ͳ8Y6 B0 {P텶 m@ mжBmjBhiBf^4*)46^/m@F hHmPC L0^ˊ]7ڤ 6жuȯt mАm, {) mPC6 B4&\Ihۀ mPA~+m@C6 cB4062 m@ƄV2Β { ci `6!6ٜwF۰ m`Aڲ.%z6zPl#7{PfUmbB~ۨK3zC+5ۦlӶ>ũWvzVָ"Lm { 'Uѐfp099U[źT`]r^w|rݟ%IBL>6a*MH'x >t!-!sV20oȼW1=&PkkUY'mWiBLжLRm1ķՅ6^aVppmEnDz$ȴNۙ:[\|ُl Ն\:`rۀ ٦Q-Kxo[)MmdgboHې^s>;vS{lUc6Oqz6WD|o&9ՔeFXNnCv `Ϲ#`37F.#B[l'yMVȬmRB ,Vί6o*]v 'ˊV韹6|c0gab9i̖lC|/:;̶`q\γN mJuhC5UmGU!$˖zwE>.[|^">Y뀛Vbsov5e-٪C!i4o`?޹`WlUg! 9{8Rli.N N8|;Vxd~+!' ũ粎{jB4'T =}l'K7 U*Ǹhȋ!TUMl*O7-fSu-m nS,[l=Wb}FcU60IiNClȃ[ m4qRrJN2f%h7U9ni\ŕ).^-i~V߷l%Eڲ(mZq3,m`Avr0G笍0tMmlwuno[-du}߸`qJu v=mO3JW0S6q)ZNX3'׆0ߖ21l7SY 6L6N{^[fc;;^&lVɶ!ٔs0YؕYjmm=`kw mPAt=b[Ҵ/񘀚;&m{v[ZKzyeV1M/LӟɍU 7ӦP׋ϖn]g֓mS=2`3)l׈s.!Gr^6[zuU&d#ަM^>k~* S,~nKX6fogPzY]W -0ws ZvKQv-q<"Uc7TVOl=۲ֿv,/]h BdTgE|Ɇz02-ͷm@CV hMhۀ:6z깏m B4Ԑ!sj:7lQO65m h!fmը{ж eNhfmB4PC 5PC= mPC .j'8!a6Մ̼ukЮzݖuPŕǑWb7/m@CVreOGf^V٦жW|[jg5"6lh&m@3ϒq_89ͺNz Dzvm@CjW[g<0z6^-7-mߟ`C:-q֙ ![1 feHkŒLN8YIsi%e)X|>7+9QYd|v=S{]wtkKX1czoݜc #?WҚYMoAv%.WZ:[h6]jfAEFXB2h +Bۿղ5ktmX圆j{jjZ/j'|jĵm,(׃Nb5l[Y'kG0BLn>7l;Na\+9KBRZ-[qv -lqo[i>c5}7TiFV熪w=̡k({BF4no SI{ m['=X ƽӜА)nT3Kڂm`QGVg?oȎж YQԡh!d#$meaݫ=|zWzж`ڀdrϏnȢĘm#=|vn5%n6[gڨOH &X{gU(clȊж)!d=m>ۃvu!͸ކG'[s2T[۝жU̡6V̡JqPõmC@F0ZRVZ}!}6׳%m@ȃ+r+kXhۀX}VlYY*n!IܪѶ Ȯ|]6gm,;6dczP׋-6WKw. Ӛ6ՎRz >ʷPhۀ+ks~E÷-}(+}!vzz6AӪGL iN.j,.fzBlc eKh4Kyܴ껑mgln^5m [=76cc6BC>aiv:as#`6 u/|ǃ >'KWm,A=L9jK`=Ԟ[ so6mIY6!6!]o .ӳz6,Nbڔ>aF١`f[I1~E}lfB}-zZ"L4k[5k&L}TUmB[YZb *9%J JzX46yz=2+nwNX:ٜz$Wjma*|+|ƲvZzvuʧ_ &mA/[Mr{8Z_pI{uw>CbY`g=cU>Z"<#dNMJYuxdwۗ"_6MQyմinM9Hw<&6jۗ Llwn 4LihͱgHasLX,g4 vu8s]H96vSe.KZRg}o'\܈:Ms{'sb|,m)Kl1.jc?cjXvd=޲-DuTlJa w"q`Os޲sfߙ8Zk}56I}X-_%Wd;=O)[D.j đׄ(ZSqّn! D/tv٘[!Gc;Ǫ2GkSe}x/,+DB ѧF.r]c ťk .T=։q9pw?)'"0cPߍ%|wA~(̠O8بI0>Udm/.υq4ΥҼ$Aw𴶐o ݎz%v 2܅ ;Am3%TL_Kgye"X3P>z!/YVxy\לϝC0Ljt|UH!3MKkawV_k*gڿ,b=aWώu"d`l}iEۋqؠZ=R6Rm!ug`l8dqK: @]߰皱A1b|EZo=[K[I\Sdz|kiS-1nd-$\YeJq i6yP&TˡD"3h5UnT\+ lh&ءq*dZO8 2+:us|ݗJ/W89D >\Ӡlͣ^~7Tȴ}gN.l_/J`7pmIg]1y׳ S[= mPc9˿}ޯ;=wn>ջ,z؁cq`oN]?Nj"EqxvOw:h'{\_!kvy?zG;MW?/2jqW 3|P7O4EoFO/~<_Ԧ/ޑ_8G;_ >?`ë >ᰋF>-_;ŏ;󋧟di >v/D3+?tbk]1a;tZͳ{]w}/jB>1rPEudWk8}Cg[pǝyYKr\yÏt^Eg;#/tg_r&=xnq]p?~Ӎ;ݮyp|=͆899ח8ޭsҜU?ο9W_y8笯8\ˮp.ts_8߾<Ź8cKKwf\7asý3s/?{˹uGyuνΜ].s<{3Μ+={_u>Νb?*_]rqs=s|3>P}sΜKw\{7Nq)ΣO3q|7y;NvO4yv_8m?yUs/<z -:/L΋{㼲+۞2<s^=g#?~Λnru~kwݭK,f?#vogwF|&9o5ZŴߣ~]SK_NIvXD+u xֿhЪI~ڣPeg󴦻) jt"u>ԼǶusr:suzI:jg:Qjx,,ڍZ^A-4nJ_g&Mx4 4 iEЄK֡ Cĉ;=lD<&xM4Ҹи ozOѸg8.4n^4n$xx# :=荃scqZq%qm:O_x4nh^qwNkHv ?n4 i4;hRǧOS_FcEc|ƮtLcN?:FUXFm<\t844>q4bC(F]z5~r)4i#?L [iu?M?}u {v4iXh%ПECs{A{н{q4lhsh֤F?D#ֺF\%<+HlBE44꒯hݓi;9=4zGhјҘN1vQP`jvyk&|sT4fghiL4fijgҘU4‹4'i{Ogg?l#4Á4ì1yپ34Sicu^Ak~ش`j?}skFy{jjz6 <9j/WA9j_rjBl4fш>mjL;lFԾ)/j}~! pSP_[}#~~KpGQkP3hhh[\Lc;4viT^#4)^ %8~[ث7 >7Dcٍ3sx0W-ծ}WES?yEj=ǙAg.AԾ}lA=UԾԾV؜^!܏)Y4vjڿ2wԾԾ}g[ hiИј#ϣ1ls6}CF؟Fx:c5a N#F }rg~MiO+iv7N߿rL/Ҁ~M+/y0yuZki#'D>Nw.{z귰/d_Aԯ­ө=Q+GS_K3pצ:h ΣME} ľW̥ZߤΛIE% ⽝#熾>4k[Z4`inH<^Ga=ۿҀ 9tK~30i 4,ZIJ_׾GۛV|^Z:wˍ~GH+8;yZ~~urvQsԧV=F0vpvrnΗO| ';_l})W;]}OWd흝Ňt>΢OwyYϜ?yo8:ouΛyػO~yW>y倉uoӜ輰~筎w7}`Gu>/Nzi݃m&մV~$h^&AM'K)֨o-ۨNCmPD#?F:F#({7s4h°5hCw&-=oN|:m5i+:inMq }f-~myCxy}`Or I[{VG?8mm} {~F?"?ҶJۭmοx8Y4iюL;giӴmhV~~rC?mC?}b6lN;|s]v_ǸhK]#E|[:\Bt؟o/B<?V:騝=B:fOۦq/xS?VہNs:svoZ@ص|:e\rxM-\Nd-NiN+H7~?+:U'3Й[|^qڛtVtVaWGgo}B:S)t}?{2`5?Nw+]fptQ#t⋗72G=c/[ J l%'%Bs'!t/ҥExlt٭{?zvtM]>b >;no"%}W;?8ӯ5{Oѽ' u}'}L}?4'͹聋~N =ǝ?rEq4=φȫңS_x{;@x7zbKO,ގ<)wӛ̊3OO/ro'ܛzӋ[ q}*_7^L/mw+rxe,z厭^W қ'Gom Mz;]+5>w!}PZpӇk.ϦEC|Z4oWL~>wtyYiϏ2}6 zig&fC˹.]>c.qq>r-.wgr_>.Oq?3w{}rA pW8xOw9~3~G{0wő/+y#+Gs?8JG48w@Kw>nq|r~[w+?8r;W]o*qW9rw;.sW]~O6t~]ڇMq6]3mz9w1vY뺫߳=5& rowU.tfs5xԿYApjvGk8]k4wq;r>m[Wܖv[~ma?}֍&o&縭\Q[׹\wF\n;xbwpwЇM/w:w+֋ww[Nt[p: u 囋ܖwq[?myd/ݖ-W_\:m`_ݖ?>m9lkKݖt[v #e'ܖ ے6n|ynuWmmtM&sg6_s[OcއF0HWO|0wv?u;Oݶ_s:q۾msq~Pp۶mܶOv鶍m[{m98Âe} o=m88m|p{ܶ- ۶͛nϸm;|۶nAmlXmgcs7ܶn;nmY>wjC}Yo]wCv!9NwqC}!?#w!#rmn3>w!n[nm۶G?;W hNwunǸ>^ﶞ:umu/mG'ۺ nǧ[GE}a*vww#sfQV @a2QqV;?-ֳfs콙ŚA7;Ѡu,(EI[ʢP(  E1DvT4Ё3bk;+^& hph_Na=b)p  |"X;N 'ܟk Y;U8l$6N{6 c tupzG);DiEq!x}Dոg#܏}~.wn3R8΁sx[yEcpc#/· 5 !ϼΗl*i/1SX. z2EF[,\Nv.o EݦB8B(v"-K(mduYHs4ஐ¦ i0!6ҝBUOPLANj(hZֺ WKy{.Yuz*u`,aO|ւ3 ^SE܅[ˋm !Hl!].ۅCH:!e!u"jV( 08"]( B^(tBEB%bwKB~M(6lP*C:%W B~µ_T᳐jMR'B'$MBr(~AHs' iSU!_ҳ*~ TA? J.hu}*z9`౛o`/xH ޷L& _(JT/y5z#8#Cpl&8(T{$ nbA : gZ/E/."R8J}>:nᴯ4jC;dJ8~%,cp8^Q8# IբwxM*Ir>^SSEeEχEea|cWQ?WOp|nt m|)/%ńn5ͽBaB ΫAk_壝f~/:=uP:٭oDνD+ECSѡ|^^oa/ڝ&.|h8[*چmk+ED,h]_XUZ4RB2h3JX)Zt,; {ˢYRѬV45MMKM6MNƫw}1K`VXs0#5z_ ݢ$QVQ?3h?̮/ߋz[?ug#Έ:ENim|Q+y2QԜd+j5|5ɢFy>^Y+ՂjuDU*HTmNT -ׄU a({v(ktee ω2K^2N2ueQU#J΍DiBQGQj(]j*97Zo,N ̓'ԒN3^%:>[vKWN5]?g7X?w͓ R+o&;xP,k*-*o!ݽ["Yj =O}Z˻K/;Qwg9Dܯ\rerW8X.]^JPxqz?cQ!r!\Pj>aw_|wF;o߮],uʑ\Lo rіcr~ɯ[u_%բ+(|_^~/Ց_$)/6_k/Ԓ_ܑ__, Kg=gQYkSgy/qA~RįdBE> glgVV -?_%y \G~+k6{'EXNKxcD^.9xZV!-3LҵE+3ZD Fcz_%_uKq !򗈑As>ȟO瀛n7_咴:rv\2\b_E.G.~\.>pF.^!/ŭȟ~M?=(\_tCdi&2??kqo}SrqrqY_^?q~$W-7#w/50D.uM.^G.S.{&_;rK9C.)7G.W.i>K6w[|KξrIrI>rIrIb+ĺ\#M.~}E.K.TY.>I.U.޴O.^}C.^B.;W.Nk|k5&@.ނ;ŻziOܒ7OǪȟ";ʟ:od?֎?t?̾$h'?:N~R~WrT~7wu@v40͆+Q7EE3zȯdȯWʯ嗷{/G/?E/BW.?ɓ~_ ?쒟|#?5T~bU~@щfUN=䇯Cc6W$^+ 3\b\\\d >[˅GɅkgȅih"w 77 sfʅyW3}+, 㵰D.|׻rrravU0\{e9/c{{b|u|w~Gn;[&_NmIūIMAq9Va/|&_"_ ?$_}_:|媫||9|A|i|\\|!$J>@+=J>{|]?L4tDTK3m'7}j,,[rȖz[壪:Z',uM;ɦs伅joHFUÊC,\ C#ɇFNMȖȇ&ɇvCXPS>wW>F>T| `o@a{|97!A㑼?d"yryC_yϑ?7ɻr΋rNFyÇ.Γs]N;'EoCrЏrЛgXc٫<:qvJJ=J-;V4J|RiWVijc"*CiQiz*UZT+[Ye^rC**˅TKrU[OYfܯA.)_,,2,w% .sUVFYA怜™ )+XKiZQSi=Di=:hzuxzjbOʊʊ3l%*+]um[>ӫx<ׁ 8 Ub`.LFn+  s^{w`60ڙ-6f2w:bj)0h{iiis`2|p֔l ~89pg$c7'|aㄻ'A/șx.ЉYhF@M6Bf'alTdX {w`^8&!h5*#eџ#`ᗀlơK8kgQlltdc6Fe\SN (.N{fcO=O7ءk'6vBtvСu[};m, j rK]Q߹gÀHl7xƆAel8x0p C`!y1l=0) >džlIlFW6 _g7t gׯ6@aCbeR BaZ)6Le:4laoHbc# -ه sg!Ydʍ7{mh†Mm|p`[ bb-.@K5-&6<\x,6 gÇ`~dcVl,W-} sy;WpGllhca $7xdjpн58c(x$܂5cUaoX|~3l5xMZpŰ33qlZfc w }'lL?%b虜xS87 @I Z=?>pf/vw8Tgq,dD}ѿzQyl4?{5[36D@(ZrE}Qp'v_u6W 5/gQP:l(A|3{B@}Cݰ݆BMn`]n:n]]^ ݫ~U\zX}E)p/fl| kE×ȱGpq\yyrk!9< Q!a(x"}Gc_8|0 0$ yw$};=PlClVxqu6G-yj*x 6LeO`ן/*ֿsd}Q9ֿX([^+8Xf=O`}{[ZY?=Y8s;N~;Y5NϨu~eu/_~!9ۅs Y$'>!SXؽ^1+Gw`}^~6d!;LR#Rˀ/GÞ8'g,Y.Ή87kpF2C>FȾwX1 ^xf)/?Cg-W mYvvYYk7~s2ق;~dݍ:~lka7X8aq7)OA3?GᲂW[x掞`ºpq'>%} ?=d[;?\cRmށfB-+} eQˡ5kqkUуUC\@-y Ul\M?Ρ/^"8+ū:p2B/{~1{Cz's/vĆY[=8#.d_cÏJƂo[,SsU8_@=B%y*fꨩ5Qk)Xjvݛ7s #5lBcz [˘Sч`l邞 ;F?>>om]0w2o8-['l GG,=\3=m U%r,;QNf\p^.٘)bƿ'JBKo-RIȫ8<3jzfPpDA  <^ 3K43\h\v׷N#͑[O5V 8" j4Ԏ#gPWP0ߢƾB}hfڅsu`ϢF[:CЏGYu5jL[!Q3FmZ&571 7b/-5j]zХY E?3uz yY.ʳޥQg{>]Q;c}CoyMћ4BޡV0JW6bݟǺ/yuh^i5=dݽͬ{ׇT` ;yuYg^ɺ#Yw u{_.LJuٷXu 6a]ްnu+ni9n%֥.pF|:2iSd :un5֡AXuCͺa}?O_2dOlYUf]"ֵKe]k[5MYנuuYW -`]Z0uVYWjk~`7_֖cG־`ʬ}b۬}@*4^ ֞ړX{l&kMY{ؓ'Ykwe6>k$6kOeǬ]= X/kv^o&bmBlb춬5gk#Yש<'άq=Xy p9d0k@.񬕟;kXۻ:kWֶ kdmGgֶ=V#YkoIamF 9*A֖ȑsqGqg6#_=9M|0#[đpe;#϶ȓiߐ#ͩyĊ#9ro!GlZ#7Fp֛#W/dG.Α*rdr Gƛ92 Gr2i{rz G})c8r! nƑQ9)Gzs]ш#p7D>GB>:S#{Hi] CG(G,p~VYԱzRđar85Ykeͧy?5E7Y/kQsOfe͕Ӭhǚs+Xsk)ufAkve<k6iXy5Yf)kVfp,Y3gk,mʚXk<]kDDfLm̚I)x?kʰǝ5ީ}5uY3ԃ5 kEYְ3k\ԬqƚXcW56x5Mn+kZAاq'̚a+c}){#|∟9kC("wxOB8AG܍戛9j#rĩ#̏8{{pĮlv '݋#L:X s܍#G5#t%)8bj[@?,8$G/1*#y49oG>胳{7{;:#Ƌ9~:GrDSQg}?X4fuq{VX]ZV?YV}[Y}m/-dk>ӌ'BYm9jSSVb77X݃՛:k3zիX|tac7ɟY=cmY=3XjnVp޴Mg~zj<ì.bٗÊY=x=`ΐXjYm{]籺+[YM볺V׋cumgVW*X]q<.eNꏑU?mY~Q,fGUoY]bdÍ?UzVQ]|ϪKXuƁU'n꘎U:UjKVDjGCVmM7ҧjm)V\ȪeYSq/ YUѳY5 ڳJ}UDzj'VMJaՄ 8*`Vfg60۩fՐͬeX%vՇUsUzV~! uV VaUˇjvUװAXU+UYU<]˪Ry_9$? 8M(:/p?Xr ~_/s8O?O|Hny8[?9<*{sλc!go[iRᛟr7@99|Cg|8|e2e`]FЃ?1GZ` @GX>[p&fbSJxfc_~k p==LFħ&|Y ڪCIC9}_?c݂="8 9iϚGc鬹y5yց5]yKp,\W+9Zy5#E+8y6Gˑ pdw#{nH'ފkˑ[38r<Yϙ#F==sxGjƀ{`nHTpdjL~,G,k_F Gfߊ9b܃s0'ȣy %З_pc?7qS/u5G~Ğя`+{XkՁ֫1L.fFs=cmqm;f"3k{bṛ/RS0Se֎9yk6$d'XL95kcXZԟߊ]t0m>۫v 33Hy'{/'c|ysko)3Ҭ}%fԢ}=?av,fs+U1bٽnՏb]#l\ss+ֵ˺]0?/f]׬L=uv{la]/w(1s3q'b`Ck`?ĺx?r^cX{|7η7 |ɬ&b2 gTRX71ϑU:o439uuQĺmºDb]X%cݜNKIe\3d¦[ͺoY2/{̺a[Wn$֥ٳ.:a躩&8nTeFyl+ͺE;ԓuG^ ݏiYwb8N;- z2q ޹κV{F/=YWtuCX }YúeֱHWuGa7y٬oe}]=of=zv}\jb{eX?n&."Cβ>X.\BY?ϳ>{ _Җ/~5JkYq:6`}vsYϚ ϑ7`}~ObY Xv'gC?X_ԙ?C ul«T6T~ȆPk5`CC`Clh= 0aRLgCXW6?cCj6h!7flb!l~φlHlÆlC8cQ6,ɆlX] kؐv v aK%6lX6φ軷4cÁl8Ԕ Gjgs!,3rn 6P3/Y6\MaAlY .dDm1V`4<|^–qF66`ûl `l< Ao-~c6RgXƑmj,6VxƊX*X5ՊX?kgcl3uX=Hll8Ig66596hƖllum곱m0就6vtecD6v>ƮUhŲb}6bcd6:OXNg,ge-(]f#=c#QY2`mlW7|o\wl 3ocel:&q6FQƑ8*l3}g>[9!߫*)tAl;~A?k-`]/g| #j!|oߍ૦o >";×6ȫ x7b >r} q\Q7{b1g G@6țQ衆`k@6m$bC~d?CL5E_HH9|}5_ҷ.PgX̳Cap`a$0^1Ϟ&j H2}9 bj@,n1G[i@:pb b쁉ܱc;v pb s*g:ŜPZ̉UȘyxtbN `d<1\S#g [X [,옺b^P~ BP@Exż X l\c1/| 2ż!Z+ż#0Vuj_ WYcXW ú[sLӠW59 FvNc1g od 3` 7vʀ}2%g6x /-> , WpdKǾt" JKzCLŽ@wWW-5m3Z]V+}aKc9l_`*0  X*O B.`F)9SrtNm 7q #i o#/bZ!hh ,,΀^<9d ~-Pbs-Ώ >5]d1N Ϩp7'f1A04}S,d}r< 3b[OC!u, /݃/q| t|396>(o1K 5dF z^ 9 y h1z!G}Qșӑ~1=<ry =7y9kF# {l3X}G#_G @ly =??: #qm8Mh<5aLy¯ <\ o> f_7<Nu_q?u@T @|[O0xl}B;!D9>a7|F!C+>FdE\FAw=xBn2S Y#oDx|'ͼ=gFW(Hԡ5 b-<y|! ASo{dD34.i +~LB{'y-F-/-3211nȁ P31N_? ?!4:p:Ⱦn&X\3OkckeIܵ \ y \xZ\[^Ya_î˛Wۗ!⌥)z%%ș% ͅm!rt!b~rvtK= Dyȱyw.X |u>'IXH-`ԞxԞx!vc(Y8o/fÇ`Yxf&d 9g?FČ߀ZO.ENk[#GJ"vT#T)P8z鈃pxjZ85t*O7"BaȃI$k"8s" AM' '~D^"cċ?b6Cg}>xhQ}'N5'1a1;wC77z {#` ;pew{ػxA^ 绂3˺`.ػ3r3b;Cѻ^maǶږۀ`ְ_kpb+͖7Zo[ F[`>ky#MQgOhݚЩ1u^C[C_aM|}Բȋzz.|_Y< ?F] D|Ԁj תP5UwUQsU#USe2P*|Eyn˺\6*˃'ʡg, U]Yص lR/8- ߔYTӟ_@Pbhe1YL?0b~c1}ZL__,/ŀ(e1}*[L% Si+=?bϏd1}8 _YL[vPbz3k1a@/UbzY@Ig,ӓ]8n" bzHjYLm@!b{j1ݹn,[0f n 9l{m1bW6],ː2t3..a,Kh] b: n1 -FәLb: @SrO$ ,Yt?=@yɲd1= Ffg=32[Ly[u~:ݎ@Xxt`_|d)->Ƚ{+c1 {4Ŵvr>amN>;aÝӎg;Oal q ]oY`>l"Ʒn[{ZL[-xŴ2nƙ{m v6O<F`1 쁪S( dA,M2 jT6t  쳡PbʄX@fBL<8˄m332\@5@&l eB=r.g^'Doh 6 ~7@ al8Yoº,,+@\_@ 1ࡋpE%l~ 5r{u@<_yus._K?q2n o7Zx z ^]ȃ۰θ| !'YP37aQGBi! [w Cdy=''ȇ'S)dy: q }/#wC+0P_6^#EǢ78 b-d wwwp1>"V?">!>AObحR ./J?!g3  l> }ߠϷ{?+QO???/w ? />/e0XsFYzeяE_k ޗrx_k}yg+ {ZcFZDEsWB/V sNCWFX!z>U0WS=uUDU_?_ }g5e`$kp5DW3h-ۋbf9N@Z}}]dugU@_p@}bo !7 fFiaj޲1?cl4MBfӚ'o޹9zQ -0@sjKo 6ؿ-ۢm۴CoO{̡Sss!KGpyN:c <܁ d+= ziz7G7,0o.ww׮ a~={Gخ|3N=1ڞ1{bzanyވ*_o9y3|:bty'ĕ+' XO[9s >`r ̻ lKĬ , ;xr=W,FFy)C9 Y'"/|9~釹6w/ܰb?fKwFss:ΘqBցȭAȕAy .bn88y|8r~+HP#1BŒ7 19 ێA'fA/g^ o~9weybptC^Ĵ ;bf>~0c` yAc0NXj14೉ȋ-IIm9"\Snier3 M^g87qR;0jIr:k"^}"W D"t8C@;s ěv7Z u|5g"7gzbzwV%8m=bm. ƳhM4<1sb0ƨ}x"c87"bXd܎_qָ'q?{a|>6JO$"q?,?&!4NB'I*1 HF'd NOF%#Ɉߋ N[G-s?$ȟOB%Ix> :$!~um"-1wĿs{' x}8D9 K,b195/1'F^G!P Cx3 z̾ 6gCYp,=1 <3s`w3nf018#uKZ\n+X: {j` vwE$8K S7խ_BLf'V}?2!Oa}ҴX3 @6P%)&?$aˉ!9kC/ b:1 9>D '{Sq#Wj?wX ǾwUk|k>|A |o>l}prç|~E]}_x }[~NC,AW?l^7< 7+9!lv : s`$M0po8{/:;L&bIIPK''&addɈP}( -CuS) }_71= SCLEL說Wsضbs:rpV.*D|Vîjp#;ȯAA?܊jt誃p{oF w u_>\ց9r |pg™'qxdCXȃL 38 ߛ3fpQQԛx(d=| ,K ,W ?Ǡ1} 1G]dz|(a|O>jA>z|5#wGR>d=X>^`k>b.2g|p_>@>||pE~h>zcǐ{c1gAggY^ȴ9 `.؃zܲzFl Wr9ȇ]uxW }vF;;?u3nG}nG܎>jzm ms[U[[P7^no7#v7O/6fmBmœ{nDɂo}hC ʄ3z<q~ؿ tftpyJлAu[kkCEAVC՚_`zUJp%lߠ;*_˰f/,ųKR%%. !""0 Qs c,ץRuq>xo><1C8{E dxn8gl;\8HF|$/IF"Jl _<815"yA4b4 Bpp,,LLc3= yV:ď.9H ^BH9Y77ip-"p-Ԉ5pMk6MÖo;aBLLC.OsyqFMA8 EvNΓQ''CI&"g&a\ AOBO03]t D5o~YL_:~yy480e,X~ܛM扼׍c`1QFFB^Fv#y210}dž#!~VCOpgu0`\zxij@u o ܑrQ#GWز?lݐ/n8r`7<]ܐn7 {!7nkGw;;b1 @\n{wG;0 # V`ء C^ _ G=G#Ǔb h3um e m^l ?zGcXp8ԘqqV >/l}?pC=/9z@@f )1>?y_ÎA&` oC!Cr}""d9z/'](b(4S T䩈iaðttt8; ,B-PA'bOZ ?D4U@HHr$8H:Ek!o#8_PC ۈ~Ԉ<7"6f Vg 'g g3ۿ ffa#> ף&|\b c lwrS,l8Cl!{87(swd"x'y:&$IIK!5%$ǒd _&#%8?| >Js> 8~^r#H.v;]5tyr*#NUΫ\>nf.ޕWu<z/˫z1SJ@foMFAGT|{/:s,$K[SA<:vэyaL]e2 p9t:ۘkp:.^l9&ҏޣ[:owHEGS =;RDOk(=fg3K1Kztn\_AWRB}N.A(Wڿ@M%ɔv*Ei?zӊδ䡞(XMRʢDZ&@G@krV:ZsJ+RhdoZ]EMB.P*%REY]cF) M4%ߛͱtY֕WRS8ŴjZBcCin3^S̊3P tt\+ʋFс|Ȋr߇֛Ъ7ii"Qj8JWٛRQkOM<]]1IcfZKhdV މ4@KJ0Vhڴb?28Ӛd*G 'Cgޔl)%@ײtTv5FRTw0)P^SmԺbj(HO V |Wqdُ4u(8-@5 -P`4٨&}i޴Pu!i6jhFu巛f ԉjI=dM!|j^ŖjĽsiȗ"9 y~jFcK^Rȟp43(Tn_L3.ԣixF->oK t/}(;hjmp4{g/j'i} ͪ՚"Ɛ~ h ƭBC;ޡҠ4CK<ؓ~9O4;M!ZR4*:R_H}vGm09Mr&QlHN Ҝy4koL.\(k;Q3v>_)HNI/ Xj F9Q_V5&T9NSOZf}NQY&ҬkWifxqEP.TyO caȽ-=D?h)4WQ.\;ids:Ij^dH?F՗KS91F=^KJV"BCԴSImkr=S߁p\gN#"hd=n$%ǓK4y"vztD=^(M36!\ZGʕҊFhLZ8ȍ^$liKBϦ䫼L{罻4Ti:ƖN;ҸhӔ7;I-jzfuyD:ݴ sV&:ĹQ`W4ctissX'ٱ cVӱkҏKoO_IAS윴h(zQisRMiNNG8q_,6*HQ )>)mi#_)"N:d~J{͐H'8(M+Kiߴ^Q$2LJe J#QyI԰OjSjQϙBM]f~PEZj,niT@UN 6'ۗkS켁&4MUJ })WnX?Fz9le(H>Az]"R(-MX$o8љ|$[i,[' ˓U<95^CNC-uZX@K^-".(]jPY*I5vyQS>ImQsy58kݖ@O&$g"vFvmې\|nW:}v5;׏]6KRג6ؕlt6Pm]"U+jTj}jCvك3j=}>O.VTw >׭5 & m5d[e9u{A?SYCUϐߨ@ ٤ЗhډZ~lΛ1izH Ҋ}x%9I gjrMhc[ڶJMESkdYܙ.-A/6t6BOMW!vT4O~F}=u3T˚Nmf:cGѓթD;آ>8_WŇCK%Ò7z6tߟGKz/):Pq~ i=-?\tٔ8폐QctjJ:Ҧ9*7@9)iׇ>:t tkzw=}U@7;ҝt#ݩQLӛѽ{l:r ^AJtz *8Ε酃X;M}Em tE(u2yv e:ycj ]E$*֎ uwtFdOkW麲Drb # O^1ܙv@דcjv3*.uAn[7҃7i+=kVT]OW+7tb]QLגRh:,n3F>6tw lҊʤ{c-Ate6*B0Gt-ftigCҺ]n ߧ:йjto:NQ(ő=@j]` t.:v%wδFgSth8A~֧2Ït.7O1#еJtẹۺNtdM7st5;]No2-t՝k j /Qz[KoS~l7zӨ8[E{ҳɋzq9E/zզ- lE =2^DEGѻg cަzާ7cp;>,kjix>K>7Td]ޕ-ON8*gRIW ljjzsw5Pvwz_*>[@B>Jq*گ׊*r1ћm^z;ޟлTdێ^W.ڹSG+gsI?ӷupCRH_kvkSIz}ֹ@oSzנdO*iOZCkcG/T2Jfn/*6T'}XqKwݝ_2}]>nH"'};}Rmѻ#z52^B/O{ya=aE/>7wm¿4OJQV<*Jһ&H ~ѫZW5r*R-W-a|;>]B% Vzdotcb0]p "˧2t!=aKQ~-VТ&iIJ}h>SM?׋HJ4 rLU-hyZzgyOc_!%(~5M|C!ȯ`M[ ~<#4Qg e)) v[k E/ 7)#H"& ȲȈ^"{?TGQ3-WD #>RBxJPR’+%֧sRs S9JRҺdkG Q(")0◞au(I[mEq#R*ہblm(v?>Gq'C/\O}iMz@ 4qMKMӊ,-8~ݭLڽjWOZ1z(EJ^tVGkoCsix4ʺ:yiޒ4!P ݕ nL}/J %;6Ҫ(e]{Kۺ =iq e>@]n FZymk7ˢeh4[Sy$/ֻ$%^H-F{m*GY7SڬG|;J]Q')je=\QhM!)deMTPP҆F`2ָGH+"Hs"P;M}OhJ-UEfC1/3)\JX>QK>~L3>&iHOѸ)4$!ȭf.&!yd[ƉںYjهUK:RޫSԤm]j^.5kOռtTzϟAU3gQ]-{T^wiI5\ܨNT{뷖~o=)lۅ* oF e -5uDM*3x:m@ݻ]S 2ؓmTeّ:U)*Q5QEԻzS{șg)8r#+Ixթq#P8E#K$=MʳKI&e:y qY{0$ vJcņZP [~dFݮ}nܩGIrOn ؐQyYJß!_SbXCf4}JCSIW AڭHmCߒ_4~< Me(!JNM \ϺRbmviR.rpO ݀ztw-#?Ӂoh_mߍ67Y(C}%6ցzKht :ՊNys+^ %Ogߥ OztWЧ֡U4*.@'W-`zKztn?tۣtNI_O٘2t3Y*+D._ o)NiC邏It|NU:x ,u(gNq#vΧ]i_j]}Xhϱqh p압h'mO[VV pv;<ڹ:ӂvehu9o7w!t4)`O:|'MYh: rGj)CNi_ѺNjFi3߆6^Rt\NJg/ wJt}t6ݼBЍvtHx:]: c3W=[t{NC5B!ݛЍ t pd*|RL.w{鑏TT?=6UycƊ.tu6=8 V>'< Q taVK,3_ҙ0:K'Yѱ (A]Bn1PNXrk)Ş1Ch6=`}0?Ga DzMA_v4vm>4fш|+xl[~QH( ”(W2֐Ak:O(}26P?u(] in'Z4o2+{ܮSʔpd%4ѼI`b+ZpmxKiQS'Zs-C E6h|JiZ:ǯ(s%P%licCڴ} mz56ͪ^xEM>QVDgDJ?KkdҪUJZx6-8/F ym);R=͚G Ox~!c> oLC+t!pMSAhZuWn/ͺubP-8UOZS}"NXӼmh^l%T- Fp(0qIOP|hJ0YM(!0ZRŇb֥Xj9zQsEp"cb|wT=u"fH6iz &m~JAE@oCf_:S!wĝ|] g^D{wyH~VτA4=Zu5'~Ϥ]O UQ ܀/%wi#4n ;m(y=)OWҘiԈ^4yՎFpӈwn4gt AC&oUe"y_C9h3(&4^}(M 4zrY@ v}y)EwS4|W#eN֛y6׊4Qc Q5H8I{<≴z~Vʉ'd4L*X%N6F/J.Ikn-JJ IZR7$5fh晚RNR$'9"\UbǷyI_IV(*^(w^sbMzk\SJeRq%ƛ%sIKH/K2saI\0I;\.|FHmK5{U~80^qA%Z*f* u,)+[)2(+^,4J[ݒ*7I%uv{$qԯԷ#IDKu!{RcHHc3J%bI-#NSJTrN&HFNWj)hSܣ4R2GQ2lA֊\J_\41IWj5u/K5>W_'O///%t="Y~Y-(mX4Kkϑ=k^J{μFebQkNr^:[6iwJ/i֍k"wLA{')5$,]ȭ9״ 4ˋ,GcPɹHݷ&C~ Hr眧9eJvUaҦ%+H,Mc/P4uܚlGR췝ݚh&Q,˿RMԢYV:ZBFSzviC#RE%h~Z{5e䝠MתPnd~Z8e#xԉ,yӑLp޼FҞUZ0UӇ' /]TLO?;3mi3}ZpOl쳗7ݽMl]Nrɞ6bF|Gff#{VE;i˔ڢŇ^Y~WҡTuVDgc& oFр+hf'?t 7,ޑk;^$F^4j'2tWb>Qϲ[R8~|~6!߫)$#帒9iє+(1Ni8>zzA 2ک)~+~Ӕf]K:[[Ҿ3[R۽#+S#=T<$&* 軖M4Bp&KRhb/ lYʁ] G ?AާU4< HɫR8V/1< hj O4iELkK]dߑfnJS|5ZD2gHI~K?L)׷'¤_KgϕE*$zid4x`tRpr֖YI 1>}Jibz=[iv<\0ys=;Suޙ(6jٙx.\wy ]~ttɶ3e͐9T|i# +KIWJ#[5|ҔyR\a)t$t&Żݤ3KGH &I;HW|H׊b;KXz=F*\zyVzG*r:HϞO5|+~2HHJZ^Sݷ#wұG3IKn7 ?tIY%iY3.GJ-xMrR~o+I,ǵ_5YJN PE˻fqKV.>pfE)E=gvZPS2̥vN1W9\|)mGsE2/n_yדU_ϭ 2a~'`f8s~19m{2i2|$čsZ4_*c:Ua||%\o1]͹ Wzlügy0󱥿'0_|c^Գk*ώ2[s5oɯf^ۼmK3oN_ٜyh9GsZv2o.n̖ylt|v{Q\fU[cGy9mf+͙:7mjc&kf5/l^p9=CQ/1jMv1<|s;42wmng^b.envEycLg9G%L ##:sZokAȡ-"i.V"DZ57yy7 8U4Ӻioqi/_8S^!5Lq/SǕnoj2bz/]pm<5:uwGL*wB-:q!7ͫV$KbC犲w>SeEŊ؂ öXŚڊu)vz*ҿ+V8zV}oE6u-)HW+QU)RWMXEg+推ql"NŴM6.A! ӕ5+ W+yEy~Rs.+>FR|R*{T3rvT3ަAR{`nnuJFC`y_)Z#i`ҸogRҴ׳)+%լRdF$FTp{҄Ϥ1K^kϤϤYKޮ+^,8fbÉRRi+%ۡ9R~R۳%Zy;K .?Uj*%5=1H^|޾+ _W}$"")!{YLs5#yԥf2FwMH(%"c>?kskz"/TsɸܮHCn?nmRr)8%nj.ߌ Yy%˸KjNei]wfܰ+J#+hsTr]*"‰jG! B|yl~]uѧ@UBДZP;fauO;aaRب4 sV^&L"tnR{V 4Yٮ P͛ 5Q*!puT!*@>TJWſI;AT?{!-:͹:IN}sNcn:k :eeBajWZA]֜ *mFtgO⹒9n>n@Gѽ/}zR^9~ƨ<' yiCÝШj%DҰk 0]K#>҈hĉ4rH#c F r4uI3hy4hJ, z=@æP] ٤ACtz̕ QoZح@V/\+SɻnSٞkܠ<57!6nV<Պ k[qYv*;N{ݪfUїTD- eNupJH4R B]ZĆQMC+UI]J)iFj~w =8>K}b|7 99OoӐi< wF#罥)4zT3=FԶn4c ~MzI#rKiaG4(4] K>SZcL螁K=={>-]SL?V;xѾB'v-G͜[oNwth=wi\OD}͗-ְtt%wmGݵ6ttMtn#]Kw^2-I/!T9<=;z~P }zPߓ.{7EQ-Ю{k5 C/ު.4'[cSӆV×7jMUOi.RyZ maN뵧7~]jy67VF6 #DБ-nIcu1eG?CFQ:~:֐tt.Nx@s H"#Q:_,ZFSKtL_@u\K-)p%5k5|cTm,ոaFeuĿۉD_|]Yyg-?RV߷!bTCS](ȣ1bkn_X|JIV['#U >O^fx'>_k^G;&V*5,bHBTԊF qo8eZ4X(v4} dE*A7G%>l%&ȄEBFCah7\I%/y.|0ʄNDf'/飰 4TCYq>K̩ljܗfĠ3KFJXM'RH1dp}2hiX%rL&5#õI ːfE;c\ P+(=Pq> -QOKX}l7닕.wj;spw*H(+N;AF tHNkqTF D2P!J2ᢒl%c E2NNL.ג^nT7/u'&H Y5WpՎwJ6zVNkշCib6$[g[ȂVdQGM2s WJu!#1ꔂ &Cn4f\p͓(JdU<-v9˸ݸ\x%UCVXT$679W}R9َRo]8Ki%~ɦmdDy-%[3ȂM,jn$wc!l '*HiFtudF2 2uLqT{$HE}'lmO]HSRoio%) ƕVܧ_*i>2t0?;.肚Tqv\u']w*2:XjҹԆȎqOk \Tw bGfq=¹PZN P> Eʊ-NYqk//z'SՒ)WpD3n:QUBfi%d˾V8(4_=x ZǷ;akG=kY|yɴ-μ~`~żey%o5?b~di)麞5 #ķw m{; ͞tW}7+yè| -^R{z&o>}zGM][7%Ǜgƃ⧓V?KvC.]U|o|?{7 kcViݗ|R[C*4+$'ɼ(Znۋ|o$otݒ?6ooyqow˝׏yww;emHi| Ms*SGPǗT&hI$]uwwR$_'zAA>Gm1ϓ:O> n5!̍ൢ=֧c<_OO}IKviۣM ŵ6&j/Z*r#GxW2)kI H_Rb#  'ɐҒڒL8#IzBs'S#e$qOIZHkH9wre95懐i ?xryiYbLoeu "uRy}#Aj9[r]kɲB9bRfFϫ !\ȗm&y`,yb!)zki)'<-($~cR@ cgDIldÔK$rzwR5GF'?y rƧ$YYm$_E-6'!_[? Gw }}1pQ>!{ JoB+WFq׿\_>;0N4,,GkJ4 #m UIڭ "E2!MM&4V;UF"ׄbOɘ7dl tG8]ZhE* zhAz z ;u!s~:k{;Qƽqjyw^p_+p~8pW9up=i7CCf.o+|s;Vܚ@+n2C)rkC.VE[qq;_)CT\pNɍ;y;Ȏ.rDpl3 (rTfyjhMEQx]BtafarR.KeE$\9*Y%立 TIa2ijG ׭C>7;U,rm\P˝&:܉jJ.}Cs_ùnBgYqTɟYfʮ*:*nC;.[Qh=s ܥV\ { |޻sj9jn^7gUu=)k/㌄|*BEѲDuњɪBjt|Mm*yL>W&j?Pir.Jx_-O{Z׫l#b 6 ܭݗ {JB9D!?3S^T\pN)A!DeR;bb$hV_%I{Fs]6_m^teBn͂ojF/ޏQE)jnu;FN6PrSO8yݎ[!6K6;(BsIҹSitn\Y]~e~PpI9j57LB^#A;nU^OQpƒ-?q츞Cw{\|_.xT#ۭ?o72puLf&\6Nrt܄9i.'U!l '݅MR1݅ vM)w'JÅpa'!\$_o'y(R5UEROR4obJN0Qf Bg͂LwsJV<|yG}U7{Ifߨ8#Z\3r %_fcZ>鿬2#Suns7!=H&oF7ta =]C"OȥJMFoJ6 W+ 6$l ȕ6RSNO'nD!ysYE>/%_jtHk&w|amSM%Ӆ|RKMTfդG&6ۑ24vM|pc^yӜQ{37 .UY\2?΃7aǛxӤ-Yk9?ōq?!ovۀ75Mۻdא?l) 63?NJt\k.fwo:|*%Od2M}RfM6MzRCrz_IʆxxS}{;bZ@Vϲ"uKIXx˒$n'qG%wG 5_oH,Bbɠ]6F*˄ `x#1 =fc8񓊫 0s;NL ;21 $‰0(}{>,ޮ'DI;fD{{vG1y3w~m) ')=훅:b"*2 _(iǽki F"ެ(=h;ϤS),]#jӥ=Ӡ|G š5tʭtyYt×tHk xǙtI_jjӑ'(v9t_hV #.?U SʭR S5U So5efK yץR^<\e\PYGQb%y#sD\+ZQfkm Z!^-ķo2!!Y8.k&DmuʄUcj.:_P.uHUa(+"WͬROU\R^.2U;/#d$/H!)aB}h>w|6GQ#Ժƅjn3>ѕntyF8ѩѩP~%hE-g̡c/tLf+6AJ:P4ݗҎ/J_nl淿bxRXW,Fhn67OIߊĖ+hGs9նSRF]mK r_@'J (AC A^PlEg>OglIF:~*:l>;vDZ|mX<7[0]L+&Wa[/W lDthR7;VvN!7)hT=ډg j_݄{Cy3a\pB,dظ gV‘Lp"̄~npCp-/ɄJT U[LPPy ~wu!BZ~\!x.lv ;CG!^5VEzC$?wᵼ񝙌)Co坒FCy,qjӧ;S3Bxϳg=a~o|Ar$Γ_ԛ_W4_= m60~MWZ2l-S#=nw*JKYSuO6ɒVo鼾I>eZ^a>iA^k"/O3njF&i$Tk"(߷⪏ȈV72FX\$f-tTe?}ǒԏ̓TJαnIr6Z䌆59ug>ɔ0 $8YYOfض)mȸpb~N$f]L0$'1$XN鄛cAi&VH( fw8Վa\SsS9+6=j2̃d fdPCbB,:둉qv3!rm2y bh$#ؐ*b}p:GXq[4ɸ-dk+Z~QFK0"_܉dt7>ٕK6HVŽ=F[ۈMW324OFy5ѻUJO%yfɓ\˒b/o5K^;o`7NۚY#{k1OþcN6y,g~r.o9WmLJu]7z5 jɻjr\ӄmr9`I"g&6=U' KɭV{τ^J[I.DgHAdC1 2]8w.[fj(?=K%/Qpik]?v\*b,VITxhJ4Ih2o. \O;> lt],ąZzN61PwP ebg!45xUe7Q]gȱ@-o q#܆a c+np`3wReը7Fɸ)mq*I+l*nF #ra\K+/2-\DwnRV?Tpy霍JK&'j2Ya?Ŕy2y~<\%?1_%g jn+jDvVgmW)]j.b3Wdq*.*A4rIC fܚ|k4saynRKh_:\Іt.MEw|?)`w*Y;#0CeiO?`%9ƧA$}?c~bx#v J4e0}8q}0~w+݌qT~ĸ'; ,¸QĸuK1n cC48uĸ1nīrq7X 1ΟI{21nƍ(8ib cCbGbç,°0& ah Cb`lQ}0XN 0  V` \1p a`5Pf0$b\Za mFG]_'TO7׈~)fwvR_n 幠_l w+--C+#зd >@!GqfJ61O5qn@[K:*h<Gkɸ>Z7=: ݯhNy*n-Ѹy37z pU1#\~ugdK9]&8uDסٻ:>DUh7$g3iF+啩h{ N;D{ǿqC-вt -2;Ȯp0?4k!>"AߡvArSg聆zhpꅽwޅ/=v+Z:/`&="RQd8vXT? ?דY9n<|o9ëuU[BCb{0 HORP^ ,a1zsB(t oÕu1p\ȅ|38w=8@·|xY!Sv2vρ!}LjG,C溡:2bAFd9d0̀oYhY=Ac dyBNȚdq}!렕2́L+>gi g/#&pv8%YT HBle2Zl58NSf@㮐N(S }.SUT/8Ur N5éԺUv6_٧ !m_H3 ~pu,Zo);}X<⿨ vD !l[*}X@$<\{ŽWpwX'+Ɩ!d=L_;`U 0l/0x^?V@ @C6N-u| n|qu9E|rS0ە|߼2w0/E{:_~tIR]PepKx^sߋdM̋uw1w^"fv¬ i f]<{$g蟘y 30M?Onي'N啘ZS c1%S䃹x<Q%P<<3 c3 X㨅ѾfUy'`08:ë+1 rC1C +Q96 #y>ۋ-%L"yG5|(gPy>$}_w Q _%~o~}TFܞLiʫC\+MʁP0*?gTQ+w8dJc]^^u zFew^7Ї6<4=öw-xp`Aq/{.-ݞGpByΠѸcs -.yHn 7%5^Ybk~:ڸrT\-lK8 ?„/`+%etNCQ Kn8 3n|Y8͡7Na !9vD*Nphcu' K otk7Z]݉cgeO%GD86_qXK UF3K3b}z⠮=h Ͻќh+ #a7KV&^9ΨWU=+ǧ#8{hwQ7&Wa;#Qu4=إvI .vv;Zӹ5aG;zɰء7jY_v۞- smsy~Oojhu: ̃c6hNW je+43,x*? kACu F6[A-Dqs+Ǡ8΀P XFCz.KpqF9vܮ Cd '?8}=S3&SÉK 5k*;pR}^KYP4 ym86Nu3 m9 H4 |׀P.B:@гM |!q /z[| +O|"n1mSx|3|VGcx^ ʃ!o' |G/x?w]P6e4$]|Iqg \ޢx_ @{ |,\g_\>89 |MN>O|og<Fɣ; I q|xM& /I}0x.ocgI{dϥ oq |.!(~2=(悷t}Vd (eAaxP0wiݙ@9(u+VvCáp xuN^ς3y!<Ap0w7sBr ܍9|7l}Om82[ 51V:gtN+ ZEp`"؛vV݆Y{$ԇ]?`Zؽ;t(aYy#A`=x 4wa ^NAc xJw=@1|O>ZJQݖqxx{ G?/&B@+h!'j\ytzG܃Y-X\mc !W!C)g0NzR",HPtPQ^8"" ȠDuȽ!r^( qo!Y BBȻ2ni!RS BY>aO!ȹO? 時xyۦBn;Ղ(gj)DQ7B̂ qyvÑo 9.MT(8~$ Nm'탴_? hr ,6 cOr5} {/Dȭ̈́ @| 4e@p} A;htG`$(%Pv& n.PTU{qpC ܡfcxAVO4ϊ'O|x^F&Thʚ/[9)􂷅E{%| C둟5|ߚG;GS9ڦހߓ@ϺaG/¿}R8n'P e{be^_A}PY8v"[;Y/;ժQ+;[ga~ jo]>.ǰSv uGYugNuv5H7vO±{uGUocn (==3:vD? {-`Q߱{NAA_ d?# fGwV[ BА!5~9J4ȱP[q 0 Qep0m}:Mk>3,}2+ ُ\J{n89,?I:{9 pm4Hr8r9牖 2LZcj؃)h5Z=:vq|1߄y)8aN;'~*&&'5`\LS *ʇ! /ܺ|TIAQ!ԙ85p;N}bG%83řڽqO=ֺᬇqS5n؆sp8E@ihwo&~%_Ǯ ` E6n BGY5:Ԣ4th :ϻUŰ]|!t3FB?tٝ.Vr ]bE2]K9.˺Zt]zGVRy[t^ΫVt^J:kSCtz9StZn?K]I:Bt~O: ]t-. t.DfR{]&<.pt])j3 ?t=]?~v ]6,nwBW7;t]g묗ҳDu.Eѵ2tp]5U{t{tV:':Q"Gߟwl.>eDt~sat :D[T>SA#:])FХ%:.A@g.%{MZ.GgVCI&I'jt'٧U 9#Y/ߖ47ӿg:tE.))uo>SM>:IDo&:VsRt^}$GLgltN3Ugt>ND%]tZI):It :yJ4qi_$rC—RLDxd~lF1sйoɞйW:}⼇@Z7>J#tz*ӫRC:#sAQoH~qPtS)% yIHstvKC? :u)ćKN)BG:,JsPYKti߈.k˝:=H<ݏ ?q*.Lѭft[؆nK.tDѓm' nѭwuxqr\4 "px1Ņ \ȦŠ _q0.7oカf8w5ϗpi'!yp ڛU/?w$_r )u)c?#:KK=Q t$?Ll^N ^b7GpthMG!:lv50B}?ga.@= ]w='ho)퍂оkvޣ}e)+ճgt!?Datѱ!:nz>M?t* W4_]1(Չ$S)\EϳeFtIFt}E;qpi\Y-t܄n=W\|}:..%WRpĥwpJ>oG\q5+J)'rjB\#[kjqmf3*vuo-7D{mKqVl77-Yiի9j9=θ*썻>U'nW> z@o<# =i*T-F/;>*b'o-Z~4Пߋa# :b@ ъ1h EVbp{ _1dk01Tцa<0:X~#*/`Yuw0*5Fcc[0h+F8͹q1K & wax$cb)&܊Ic 2*ۨxG'Qƣ1)&Y ɘ2g\ cC2XW<|w\'z>x Óf2;<5OE`]L_ۀRfJ̎r)t#kT9f!czs{\js^nF~mk1Ggk5 9c%ƜoYH1go9fcNu*vs0`w̽z d1ofUc^nUcޗxn3MNr=3y3ց|G)獎|XI<1Zwnwwۡï8o+|D|N9p)$;Ɵ:3g}u(ڃ^\0*o.+%/LZr}"2o0fK!^'[z?h[9?LNPO L] {u-Arᠫtzd^T54z}[UW7noJ``?Loa`v{4{8H`́0g?0&Ft>#<Fa8Ӈ#È_A`~\F#Lm 0r F~`Ԝ 0*!:=FQ)%0*+F݉Q-0UAWq,J~Xˌ4̲L\ F{ QRaDt an8@v7O>b =g=tmyBX?2_H៭kwoJ\:Io'ICQ% x~G)~>eqy<;6׬0'\6'3KНW'׏!ù[# u??1 ?a~|S*x+y"sṋBz{ǘ6ta9sCNc"sOŜۘsv.欌ÜZR^;a阽 G1/fǬ)}Yc̚ƬIhY\3fK8Sʫì+"fTaV7 YJ0kz9(ffaf`< 3l0Sa <搇3)i30pxnaG%fC!f4{cƷ0J{1s+F,w ?w]BTmÛCOGm:O\\\r_2s}2|(>`>.a$9n2/\K2_wo㛗?[Y_OvB#i}t]=z=h>C_`x]+8 __`4 T;`Dk3|,^Qg¨3`ю`|,mj7o7596`m&0)l>N)=@;MD pp 0nfVìs0{c.tmߜC% cIpFpU .?*;}N`v;ae.[ Nì0=i'9p+a8CJ7l*,4 n_R4,og+vaeXզ5QAsnqB3l TzIaU>llh[aKk/ؖ5v8îΰǦ ?anv^-n~0`{rlW·aME n;=:}Pu2nEqpWO^`i|ꦍ'C}! `P U0!3g}AS"6<-&x!<^(Asޘ/UC%4o4M3CSOx>-t!7O(04Jxpg)>wA[CPk[cc(,BI(6 ꃰ)UKA Bmg6Esvp\ E/J{}@H6M |*qY@tZ t=gW.@f0?m&\K GpNLk)"gA$Cx=>9 ʞacUVddWXMa:k0Ə bzQEez0h Y7] ܂ |̷t/>C;~޼k 7|( tr|x~vy1jVJ'2k8: 3\L?HUx2F>xMLǢ1eIL޸#\n 60Ll6ĉpL)&|: 1$_jwbf]1&m9W`t辋0ʛèv2# dP:`xn ߸ .`X# uCcƑ_99aH4 iI0$7Cb$ *` X /7ct$peI40p7 HuN[ 0:'aP xy|0 n-! EX~?/_ik};}9% }{v@_OD߼x􍿄ϻ:>e}JwEzoޚ |YJCvW:zq{Hw|g2I8ޞ]Ӏ>O JzZW'wYl~c>ݶfe)$藹}6A}>_ޓ֖^AT>X! K{=?a=zk%лd.O{Pz/Zi;%{ A]8jk?! d~ޡp3 ^׫: !P`"x-zJꄢȔ,c#Yhʂhr1-[mWӹ,;lXc=s2E=F8,%zEfhҕEbѫ,Xo>EWY 1tLb3Y)Kۋňba1,S.9cbﰘYXHݦf7%kX4/Ug¢Xd,)!"ʙEgYTn- YXk2  Yū,$ǀ}zo9b^տG){2E/?,/0/lZ])mf5 މy_tG09!qOʴ RӴntӾ5!'E =dvrP[|]/vG=Oۡq35{]RŃ|cQ!y?A@[ڡ'D歂)!12$.~0}νi+'wPԹ?} <T=@e:,V]/W G$,WLtIPsnn< -:P*~.QoqP7-#P?<ON%Ó_P?)7B}H?{8Wwaphp s?4WK+AiP;u_@MP;+up.0QϘ3lWx<_\ oAxhrM۠!=^|s=epxYOA%=χ+ex+Ljr@x9x,Y?A<5<6뜁gӭq3hx:=<}?@_{n8gÍqӁz0Sgvsڻ +3 XJt PHh3![һ>5 ð4{@X'؝X{ld z9Zw2Gd$?g4?:i=4v ^+'7l#/_őϹ넡}NP jeuゞeԧ1==Ɗ5w/M_џ3ӘɬoB5߱q{(ȚWngcDKrQ y2;>y?"X9W\΢]\YEx;ǎF,];kͲe,c;wu*+T=]] ;7"W0؋zVy+yXn$c+}`e{rͻ#+mnUJvq49#Ӊ$vsv 4U*EKVUIa\v/eu;ͽfo"5S3@6d>Tvjv~n&9ԓ2<9SfLkUvc]B"S:3mLv-:tXŵb%Vac*zh/=tM)7"vs+vgV^sZXY7V+/4br c, YoYt]v]h8]=ؙ]X.VؕfkŲ6̎t>^N>cǗ?a)9ؑt{!wϢCYҷ,]+:)[}]l?&|~5>̔Mɬf01i(9%o`]-=6_5ԩhL)O 55 ~PxRw3WfQu"v}owrm|3||&vZ-wf^ͷ_rz#apK1cZ)={9{0o ٞ>jxX߾6Ža7epA(mx1i? *Y}_-DYB7׏/p9$ݯ#_!Z˨\BQ̉^!> V@^r$[·7o(G th:loWBٻIP"f҉p7ɥP]j\_ #x7f$ cPR %J(Jf%vPJ-j(2{P4JZ{/(ypUZsJBvR >rl$5A3ġ x>EPp2_P< n}p|~\  ׽9pm\\ۿm\׬b#iAp5\ Wj>o.p.ՁK3|Xp\7t.X罂GW,+fUpun.\=0mPNkcZ3}\wс碠Ф O"P9F6FG@, tG2!{5CC%顒 k%AiJMʜ%7ʖʡOPv+ >(%O (2)&$XJcBfNq78g7: Ost-ܰos$AP}%A:(p>a"us@qk( ų@`{tXi‘ =,Xk`v`QG}| h?Kyn9@e݀ tv %07>AidW(3*; e|WEp-ſT cubp+fZ܌FnτC&ܴ 7FMP޼ϗCnP4EAQP_-/ nl%z 9Ѓ) >W8?AEj(}Zx(x W.O mB%\ .{s> O] L!GldQ8Ӳ NNt8H;=NNpu*{, !pj4~-!1 M C!K*[YBC..bc gBd]X[@Xi !!hR &C Y }ޛg;z g΢eh5>͹sAcMͺRԈ{łq|⃼;l=u)ٝ5˟?5,?R{o {ko͹ï̻]OO25wjE9 eaT4ЋlB5N=*lL*k;[=j}@%"yvDcеQgPՎtnҀ**MFSՑ47XI5Rz=3GkWi͹"5ރi.c]뙮 =U {eg&k!GƳalcltqf5h#f6&2&γi)̧\ansSg Og[vi [)؆{&sCml%l}Nl0ۣa&gc'-١Liwy̧0߅I(mfX%,` 츉NX% 6MǂBG,XKcwo! NÂϞeE,j ќB&nb!{X,G .BYJJWA,l4LY [o֌caeY,,9,fD7Xؓ, V'5J~*fC Y;رE1cxE"jHZ٫Ed۳!Xd,RۈE`G3("gMEL`zX,1C;Y,|ܽdž7 ,:ݜ„,j ;ba),l^ ,|N$:`b$aAX8!nf˘FN3߼v{]9|b0zLyk+S70G|yG1^3DB|1^1JWe5/3 'X_bW0}wId߇0'0 w1>+.w;]-d~ߏlob_Y2Hv(oN`k0i,6dX,  bAq,M,ÂֳxҩLa!XHX>,Q6 )d',@ lEf!,d22FY %Y7YC YBVzYZi= gz,xl<7 z,l- (t1cAF,(,|9 zʂ~Y?ɀwʂd_$NyBYtYc,= {*0͗uϰЛkX]:= iBZRXȿ,t D-,|ɧųK, <\¶D},h f BXo;~]nb"gW"R?,"#,b}cYX?1HEtx.a׳[,d5CYDLp܍Ebᙺ,;žٲ$#I]YcYh_ }®ijp),°Ev.eQYr]bYʒJxɎRcxv});;ŋNOc'?Y*Xj0vcn VQ>8Y_L1iX+mVh];4]~ˮa ,Gvn#=QŲ6̯X;3KXڒv,n#K2;g,v)EbaY',p5nqg0ыylO3lǼ699[WVY͖ihf5s{3 ٴ&/`֦.3:1L]Dog1٧qc%Ҧ5:V5vwvUFѻYwh/ܙ>JkGu^khݱnV=^BkrhmOq18v3}<͏>zDhMtZ=*mgҲUXיF̧щޡgI[7z6߷FX=Q3ɖny.=MOaS}9TcXmDމbE Ӌ: znqH&+ϒ+6;xϛS˯VyO#FΞ反{͟΍ƖWN M5v?u䛒}_6CTY.}{p57A}i `pC7=,`̜q0^z)%l Su|`zI,9 ؏0WG?Y;²^}a|XVLA?`}M,l^ < @>ߊO4AO)+ hzt@pNL!/@hf3 Zy!lv ̓8gP q ~&gރNCB}0y'l[p$υ- D"$C4HlkIZ\[!KQ}!@|;-MNy—V@țA/|/vOw\a-хeƃ`~QpfNX'oQ )ܯ`46-"q)X'??s6>:6mW^OmwH"$[61k"vmPi!.U'CPh~rC:Nt3ΦtY=JC34zI1={y='M,wB}Z@=(V:}1}v~9ukڇong:fXn=YaL|3躕}4\esXF8OgK٠u 3]1ӝWi6f|ϙ%mf>2m{Rclܑz@66G1&Ʀ3`3`U)1=t9cl: 6b6mVv*M{ŦPi'giSTU &Mgc>1~z7>UꏯGlli?Vgc]sӘly &Z;,j7Syٱ#s6OYOį$vj/v/ee9\7'π]dyvE6dCX}9-?ؽ^dl+!n`e;tMVѰQ^;ٝvw!v |3{x͕=~fdF3{}y${9ĿgJcx7yQEc"pZαYue/*UN+7##þ:ȾeߞwG G}|}~d?n\tLc?k/!L dMw/>ӅnjcGejsx*|_55[XA'b9 5za1&,0܌0cή؆YJ(y˿*qXFEEPDsv.,"QAiDDF|rkv'zjg=I'Faa-hMz&~đNHْ5Ā\$aIj̾3iqDެgĪ;Ų9|sK1=VLIc.I:/8'z}%ĵĹE^Rt$v9@4Dqv>SJncVxZd vna|M9Xdf}RC>W|kk0}`G(oj o;k Õ:Œe#&^Z>kßܽoޗҟ{ؕ/Um|gǗV ht"C8;X5 KR4z]}ll{0$F<^c`D00!DU0wXj-apjt\Nɰ'a?Ec> ^ze<88;8R|`wQu'( vΆmakB[ҲlZy6N/ݰAXu6|+ ǰbrX1Vx-V+SOW`q{XS;nw:ɰ! 6suG`kxؾvV+apTnq>h'83R8>/=vk>pph<<JS6<y9xo x:QYt i<_Ctx5s*x9? ˽.M/9x^#|ZƀM> J8c7P]6^uQ~~>8Cx ] pO‘VpdX89 oGıt1-p4+nkw(N4'Cͩ'w& %;@Q n6!ႎ9{Q qs!ZN肋MOjػvsvB;r:z9~9{C" yٷ >D5$7V3L N"wO%t粍D\w KHY+mCNm!Z-!'DP?GB^'!/A_Í8w"!N/H9 QkFN|JN#!FKHH1$8ZKȉGĬrp'999RH9G;#Ǎe؝#MX;9v29fRGoI8L#G#G$~؉@$#ɑ^$ <n,!?I@QMIoUgև'Ỉo)rs%9aAy%Ր7߭__ 9?&O:8 Cǘ>$p988Դ SI`@o-'/{ {Me?҈94WﴯO䰉79䳟w uB$ڒ{X0S@v A\-V-k06 ֖,72$i7ɜ)dƙQd>L&O&c7K+,݃"& B>HVu&uVQO3;#bF1x:N:Z3!Y\e=J>8Q^,Dnޯ.DjZ-Nl~@*(Z$w(*O  v[E]nӵ#b+bbf&U}EKEF6t[M#WT^,Qո۸N-;>araEfb'O'}!hbYEc\,wibRu1C񂼷t#FLULTO<*xsB|+1Y%~;6ĐVqЮli7꾃8K'+Ƞ 蕛ɔ͟ܥwɲ=:U/OV&woq@N.=HĚW$vHG M2K kFm Y$/ʧemR4=JJ7&KIٝIz~)wN*ԋIbRJrIҌ'cWCZ3)M%%ߐeXrye>)0%/Q$&$Iݍ] 1_~HXd, 1H'GDooՈվd'2p8YǑԆoHۑS}5s('7Is7u{@R~WQqr7x䇭'8 =[;ҭ)פw&̻viZ^~T 4bW KxyC P1Ul9{:{yMߗrph'=+;K.k/4h?fdqW8'}!S8{Tmzˌ^RpϬo{$/@4 i ytC^pyȖ'eFf>| y JqPSCQ?f5pm=(ys-\ _ g_{BENTw}PxByO l1kZ Pjſ@Ql( v|9#tz(Cci4fpao89Ľ-tukBŸA!|Ip˽az K`d\ׂ5Y1A/h\j(_׽VOx;{_~|;u1jr5Z8i -rhh-:+^uDr]\?Bܕ9A'zg=ĠⱜbUİAİ =1wc14x|<<-L<'O K<6m爑OųxbbBK1񶹘px~_1y%D<{W!j1Y-ĸk)b|)X?q{,bL:cN::'}ĸSĸŸ ĸĸsٶbP1cBG+1I1%QCLKw3f~3Z,ӏX?ċ Ŭ17DEot(/_eXD$sbX0bXcx+|ѱHtls֨4 I4=^L%m!6G2|֓EdtJ8?Rؒ/ߓMɺ)f?ɮ?'?s-%r$Zc?~$?M̏h/^|?R{0I<=Gܺm8gѹS k g7Ώ}>b'ޗۮjU4` y;JW+yc|5y>Bu_Y9c{pa?g+x W[zOIp:x̅~zw觯4 qǖC_cp2lncc3тv} łY5pc;{t`;B"sp}ꚂCyp!δe)8<^MO@/c2zzf@;uzmq8}Sӕt9~'8 &ǃZp NFsr1jp?@oj8>Fe '|iv`a:YZ%vqsQi zn[ ̓OC7sG&9 zn=kgu_gC t[=Ց`K`ۢ|]҃K٥ؼ6C t|:nEq9t[ ϾN&?I6ڱ.tJi  潠`=e$X`qĸn A`m.{h>Ġ9 4f<МBhz-@.(9B+աsRLgԠ̗t7jU`+Y7*_78"’n:YFϚOO_϶5H?msZ?ZiߛW=]W@_w{N?_k=yf9qŌdY?.?:-,_sÈq?%W+0u???]?|l0~w8]Grv$7̓{\n0m<7#9G. =Hlk34&W;B2—D|$b;"=$sD4IJ;ψP<!DdD0e7Vf "~LpwD/@BQNxw(~Q}"D߇qD62@$p䬹Ir'9IN%Er|Pt%9'$qk;Fr"7\q/}G ,I$Uwwܿ3D.?M>&)ȕNYRЮIZFH RՂ5s"E]HoM$E[HS9)GVH_;)JuBꑲq夬ʇ\_\֎GoֈTLkO*|IrxL*-fJTΤoE5\MayR9&т]$4NTF*-؛T"fҹIɬ~tA HArer`B'p6>$abp=#\ʈ" ?̽\jF.ϐ7Hk)ɰ*&Ź$C>-I7hDn&iGoiHeI}DR/# H*oDRd$e_k2ܝ<$ozr|I~2$@}I'$9Ό$m!gdd#$됤$I:MBN~$$IH#ٌ$v3d4%u7Hʀ4#))-ORI^:z>$HZr6ZC^tdA҃RH$oK2Lұ&\?dj%\]N2$[ydv%gOI4dUE(rQ;dN2 tP޲y%i&Ijz)IT+T~Hh3$9dP;_I.h "}3IK[Ql?5Ī I ڝ $aɀ$T/'5`2rhrģ xcIn$A ɡ;ӈ;enMՐ}Gpg6ܚ켷lH6׈f'":,Vy&K)m*xdAs2ɎD:8jW&-a81yڈnIzD}/H%Konw/MŤ33zyG誥/R\hx}1W9xSm,rA4=u^#ck2?T_bҋw`'>6 rZbo'_%/Ӯӹ n]^͎A?{  r?KalL; 3\OܓN(,?O-ذ l];.#t o:.+/ CZ9ѝ Gc5D[=#©~vg6螛!0 (,>US !%$~р$퐼m ef2 ]b .%e}uB3(>" @ d>yr-!_p. .ρ|z02b\Y W B%,?pO)\ @a~w(ZIPvJ,RPMтkzAYT\uɄrPP9z6TVs7p BOvq/\!G*5nws;pg۪Xt[~oS(T ?Ӻgܗ}{ {Ipw#J1;pGn­!pk`y xn@OG#g(lΏlSc&`Q D(I~ %-BPEm+*\WǶ,3(-+K%n\>.wy.AQ7r/@n. ȳ@d -'8 M@q d_ m[QY2d0Һ@* y+$E B( 7M{Ms/Nqp wA| s81:qvBmbLX]rbB|w!] t\1s XAIĘ@Ln3"bV!f&YbFM ~o5Dy߃i1_Ck}Dg߁HO C;Ml}#Dӂs:b@l3; ΞWy$j$sGH?@aw\@vP^>g9fC^z\ G^Pj6PY7'm1jVhc*O.};³_PS]E^ W=ݓzaxjo՚mzm }{AxjOvs&P{a;ԞP jBmPk޾osvbx%޼s7sͮ;_Mzugxn ^W++txs ^4Oe;rExY&dëV8>oi=͵xkT oWEڧ/u VA>AKy*|ݢ2xZ»3}]{xW=?6}=:g.cj)xt=K6)07x>jPyjDBPކÛVxu^ȆPg5</xt\ {ˠ*n'2$O.CnPoBaVy_@N :} ( ˸d>m!H )2_H* 셄ܟpw [CW7j}"uw@D|k Nv!η؋fpt@&} ~ Sи% ygnؖ4?ŏ܏0r /mcˆbyKFlpAt'^&G$ۯh4;)50tyجΫͥ?4tLAG#ueo훗BЮc* 0Fe=jw,.g` 0L`21V`t;Л>wkXGAuZ1: }mن#0XnG kzl'9,Z+~~%}XpFtߋn?8g0{,+YԔwe79Hapwl|/p.RW@zܠ ]Ay~,' weȻ4՟P` ~qYqPx&xH(R샢OPl3GbkP:8w%WD_ kۜnP«P8m\}t 򃂼(`WvfBG/뷠=py8lY y5Őh=t5Wydc!Tuz@9}!N@E8oB&)Zc Wĭ @4 g;.p1d,}%k#$'5 e{ Q!_wU NbAԬH8mi;=1S;}Q=BJ#p\ NApt~M #;H"t]c ;ow7 !R >9^^ߛ@r9{u{;p {N]+`;ؖ}L7/XK΃f0'&LqS!_To#:ϧCT  O (p/ҀG|J L ;dK AVݝ mC-CoF8=h}n6G7O.8th =t18 X]mkd:tZ,u,'[3]`=Li 0:Lk0^ kn~? ֈǠށ 9Af7hEmV#A/вςu hu|-պ@,:4 Mz>PSCV+[ϕzywfVS6ſh _E=Ol>f5[_Q!؁^?9C5?6ߚ{׍[Û񍆯AEObwj'eJ*6[k_)"@44!mġy .^s/i'hx(^ q`\Xxs^b⋂Tݦuĺ r4/'#ڥotb4>19bC̆%ɑ6/H[,n=~Ca J#vtP#_&ifW>.kE7iq.Od{"/B ;q^3GԬ"' Yts3"]N'Bn|v~Ds_5i^К{_L|0x}\1OH4PY^,yF +X䉇7}Έ^G/^qukr5~ayB<(MNՊŋꉞDc]jk[[;Z ME]Ġ{c!+'nL _#W\cȚ:D#/Z:g͇gˢBӬQh5`}a(tU s{=8cR ~i0?y9,k'_-.eGo}}14Ps (FUvw'CIBVɦpRo>P_+'=c@pd?8j]GV`7`P.lY֞̓BSXY3'g0e2 ^{WS^;w`C=J:9ںX3hƞ7oCӧc{.Enl|ꃅKhd|M7 ŏ%#2Ik<{,moyy|˻Z|̧UGf^[b.-؃.lEQ5tx"5DڢQY9\Wi $;{oK: <'-N",&g g {o ױ[xϘ܆r{9XX5'S6bCbab˝7D $\ :*~>.t ֋D C bbb;G5ѾsطGQ>ȯa|AoR/vNm( ]X="qaGq1q۝ .͗K?R ŵ&;DK\FWEĥ qa]~ʼn{3:󗗉w ƍgJT'u],N+NMqWq֋?G,Z&0K3EMN]StStPuuVhcݿؽEعh&׈&IIKlm~@le8'Ϡ~#0o]'ccOvy|f4t Ϙe-v!+>gO([aN$N!b*VW-w­ >bGXO7o.~د>,>~G |-.<"y5B(vRP%$];E =!ZCY|:Dg(SNX9X5*Z+=ORVFy$i2B幖nʤ왭PV9,-,z]yk2g2w>eeeGʳ%ʄOёS :'e,ٞ?Mm)[)SlWBGeF}tC;?Vnws%DB[FE?1\1:QާקJ+8|`]"+Z%w*m[wOd5 k.Y|_AQ>?Qivv+D~iͽ]܍Z@z"5vb2Z)C]w'QmZΣ=W#i)ȯ^ =^ 3rS4g74& 8x8;u˸#y;Lo_hd=4r hM IFVqO1W!8= 5:8{|wan.9Trj'ɗrW}Pkt'=w|Y+w/r6՞SMs'NxrZrOCzF^j쏶B=æ" v|t{C톯Emm_]m??P.E)~}!A^w"sS!A"!lD0jJ6/w6$~Xivicσ>UVѫz\̊\;81ËfpqrfpE?pZ4J.z @._r}=+>; 9FuBs孂B|7a~'Lڡ|'_ʙv}ƍ-Z};[͕*:7̟Z<(C]UqvQ<r{˜6;eG C#GEH(Px; 5~[筛13/jc}/Qy*.S;[Kzq!g9̀ln=5W1{7˯=W/{̋,M 7 z *V=V?-3Bqeя5ʎG>g*{)vz.׼CJh1^>r|Xڻ7naNCIu[\Bel UYoN+<<4Hab*oCh2y#n';UyńR/퓲ڸE^7YyQ{<rx^_MQozoyȭW*0y;Ug%LTGǦIW{ 5K;!H!z\sLւw(gR!,=H]8t)g(_fUn9} F-nvB' NH:=Hs}NԽy8s$-c-*V:1oe/:uTgSQscEjʶ*^ }FT O;r^9XPxi I{ ٝ ;#%83ǜ.Cq؉·BQZp8%Qxh5<[Myջ@#![$dW? <?L#5G˄{]u4z;;VJA5l?p >CX1صϾӅQSo}ÅșDJ?Z +A=]|;)5<< u~~cr݋3D3"߽Q:i]N9B'o۠Psp33 M>hh(-4/=Z7-X--< G;AWv h:kiD.G^FQIATq<<]ߟ E-#N*xf aPtp>J?y AIKP+t Ew΢wJtt^Ktg+ED Q(eP Jy}kQZ)e،!>{z#uxeS~-rʘをO(1-Jn7]G t.oRW(eC wiFĉZ( ~!(aK(ASG/ Q螳(4O١,)~F㑿k)Cޯ=/@=E(q4x>J@ţsg8!5~L=E\hd2mE*3ЩϛgPНhZCG^/CAc_QoZstxlPdH_86)Q=b|'KnlIºŠma~ ]v)iUx /vK|\ qZȟ]?(XMkMr\5a!bGF(I(L8b8`/\ny_3eM ^D#ۚ?d zLRw"mcN HSD6s΃ϞǑs4E:R}ݗҶ w̞;67KY̕{&)qBnG3A=2Fyi|rCe3˜ɍеܽsÞ3^$oi>k:_~~y%]S\"'CvIknR#wXqK yuhm5L~ieuZ.7`,w*.&`*^ĥLBqs{+ʻ;*;9+/%tDu;YH)T:R.#5!k !&!-{ 5jb9ʦ«7W *˄ w' W .Q2ՅFjIPg/Rػ/^\S) ?<6& -l($(n5/=F^vuNeveU".wȒũ,4Ys>qqjsv\3{q]}-OUWqcLYɃFq#F,O䆷-:ߕ\Ǎ_R ZlµQywUˮ :XMV&oS5S>\<,W+?+grq[?6q%[rNQۓK:s]ݙ{vӉT15:x5OiCŬ&Bc2f!K.r}&q\ ԡ)4y4o@}y g(;K Mjt=B㗡\H>Uc8  y9JLҢ 6VNʪhhz#:7݇6LgkYbwsQڬ(LDGٍg!/({:Bhbv~D>}z=w.E/վoB=4>#s:Ԫq9j~i "[ud692|4mr/uxwƹw.͞Km%s L.h…Ysɦ.0dGsAor7w+&f~<Ԧ b 곫WehT]K4r4I(](=q >4{ -~H}r냚E/s)gi|곐fK͟pk-KNfneY]ƥCȅu>=cXah$_<spS5)f1SYux5Z[J*`X2 74ODxn[.Bț}O:°hqgsAT,'jkr{Jn5קE:ikyʌ)rsy\N\*u#g0| 8k/;̭4ʝΥL.WnW;p/p5N'MG-V/Bg&toOq/qqܹ=)9QBoy3e$W~x'UJ#ʬr+A_#[WxAH^'(l~ᅛ_5B_ԱM'h,{܈,nu6jyp^:V~[[ԛ[=ʏs췑;t n9zy 7G37d$9-{׎ ;pj8[uQlΨM-shőȃu.r[r%=7]\V%oC>֢Vn{-5gT1U/>I2'By)KS*zɮf*m.PΜZVgrR%>R Q>R:D,-mۄ;+|ӱ)_ }&#g.mZU2`ƊU.N?]ʮ+Gؤ<`礌{OYP=XMyF|b{x/=dt~s vc>#M+#-l^^s=3{jiMwzxI^{o 5s>w1pf?OtOd~S-.Eq ڇqjB710g.Yܑ8+!Xs'B|5>g\Ƨ?}qR|I;o1%k;N:/s񅮀& hy'ۂqbm`Qۆssty$|~N,Ikpct?' 44N3?`'Sq87c.Sq ._z φ)q1;-qN_">]m>Eq8zc>Gijplf/qGcc*|= +Ĺ Շqׇ<\Εp9.X> bb? 8;gVgE_8C  GqxxWqK 'aqx#8^^qyG187'.SvR:NqG">UlsWbVД;돃Xк>8>ꂏ=~ eq-#d<3Xz K>xx'C)n0_MSGa0N=pcL+bT !͏ {V Ws c!FA%4I4 -cۄX úxԫxL[} יCX3bwa褞<,"Vg 33lu3BPܪ1Ac7vs#3KwUSNxxj:TǃnW8lY~E‡wGl&Vt6۝lMƃ_ã*(gxР+Xvt1WVS?bq ]q˭uXӯƝjb;M[p?RrUC8ҵwr.!Ӗ)Cj YHP1 &&$53pg_pV7ng mb>x`Fxt<0<6b>m:QspoTx/T,&uVL=k=6K9>zھ7@2hS4yL,`Uzި>jo{ع&r/܃.[Otmu2v9<\DgT3NUwT]. ;.&w6?Bo"<Еc(qtp0V 0~်X,Qb`18Bq Nl˝^UTv< ~UXaGaBHVp!*pRNV>Z نWBiByÄk',kB7_jaeN8=`pԗ|aKv'{ n]: v~(otXLTOd N^`<7;B_7 f}Q_6kdN F>wDsԏpZʿ?| W)Pr>yYW ylӍ] '-Y]Q̥)J*)V)rԔ}WMQn_XC%}SQST6ֻHYHyrU¤% ;/7u¦+: ;R"atp Aٯp7~R [Np;Rla)n'Bxww+>;ڂjx6xx*>W>i7OU{L\֤澚l l&ٵeh md ;gr{\ōwb乸g쨭ak5)q<mOp|Tg'N8`e: !Py|Ԭ[CCs58N}sO\dWv؋lٞUIKL}{5.[X7ŦΎB x+e(weio>s]/J&wF*v?-uQ3V—Xw܎L?<<Ѹh#۳p'S{moux_x^xu9 `9K o|TxCj3ߚḗcpG>?Փͺb#bb }Y$j_#j^!j5nx}6/NQQʹO\B{+ %fpIF_׵ү{mfCDŖWa1֖? m;p3s9o힍 6h)~[owQT*0L!y& @Mb ĮA .6b';MXh?ߋ&uD)D!_Eyk:ΫرءKmtltmhqht{@!$ OD=p!ڧض$^l*V-M,zn`h0:N4* ZlQ?W5vr6bTR4}(GK։lj:ED3Svم`u2]lRj?4OWzg7ͩ;y5E.oe8m GlQ\7L[5{e_㱟w'luUxR{]y7/_y~Fy5%s䰬〣_ZVڮR7k LũjCĹINoEaMcPIލ_,P2D;&{_AgOu6-CdeyMɞI,+'r"^VT+M,r*-u7I\f,fyg12߼Yƻò{>~#wY*֮)6nΔ])s]6Ɏ,ٕȂ?ɒd8l岘!2;edez܅ò-d}wn ˜*U3?????? QQXHabr(SpM ̰ M(PIad}]CS (SXN^QA3+ӥ4`@)О~}!mg(B (TRtS64G}a 8T(MFS)0pLi4f0գr0 @3@a!{aR; )БI VSO(Q$WP Y TFIjtg0R7u1*W: Gl)P7ySޚ͘nlIgLkLa,#O#*#)px Tƣ)Ppx&(67>( Fe4դ@ubD>D _s  SvcOx!g0*/L # vc*3rVJ}RSS9K@mϘڬIs.TQPL1IS  )@ufҝ֎7fT^&T&T&*CO O&,ӄgBi6cdyL"X~ b ʻMʃ)ɔ͔ڀ *o*gwSjԦMm:Rgϓ)l@7t4UgY))ՙ)הڂ)Ri(\NCy04-FcQ]R@y67:1vkBKfFkFi3tQh>Ց)=Vǹ3jfTfTfOͨ(f.3*3j_fڟٌƌ-LLy2nF~U}vd}Ih2R1~afyhS݌ځ_fw TfSYDFD3C̨L͆ӠSBnFcR/*{&|ј`1Z%nL|YC7 +cd&@ܞ52ͩϘItIc|LegIi ڷF?Aќڸk&Nz>)'sʛysڕյ99M̩)4F h,0gNue>ճY}IGBi3gFY_\/sY!, 볜09IxU2\hkL70R0\)CߌYKҿKv ٧7?A}ٌ>3XL)!ɮ2paz{2a=lЖ6V&(q//ߒ@f7RyJx թ{̨.Tvop:|G3=0: #X*o04`Sǃ`20&v7V|k&hLFԇ?qßR][&9g|yҺ?qӗ͒nl_~ s0#cW cEesy c$UŌz0m*LeRt,Q٢Ddԩbʇ ۫?ֲ2Xc9R{vkIpÖ=KиoImr_mz=KM֟Kyڒ% Kg,3Y3YjkY 3<63˛7d. K_Rw,i|tee,e}dYdpfϞ9A":ZR[c!__ ocOg<2[][X0F ,oXR;gP6js듎VU}7<1ъڝ[QnehfƬ9klٳ!y};UR_J[Q~cE֊ڑ +VYڐϱTOsVY &:SY=;Net3e Fr G?.D_ ѸQ~juh]X]/Vمo`3=ߡy>otbRg#Vٳ>=ӅMgmVϚf2ܶ^w&U6Sv-QكOGfl+o(a+a?uTб˪1+kGg[N/5btLYS YxW/U3xL. X}ֿr |dytPˠŊW,}d{UxQ鶦J Z25T;>`yN)K1RRlcnrV&t_ƍ: cPxX45m8'CuƾyT.4.5y2# s 'J4o7קK)#- y*6GXW]昑l{^ݟy4W3Ro6l0Ha?KsL&X>_ӗ'EkCgixN?5/^ѝhau Y6Vd/?b:nzt]t0/?lKlK}},I>Za [SKeko 7yFdmK81X?ONs˚4UDZe*U0m7sBӝcuކNi-2lN2Mfu:$Қa(K~9뷡 1l(k#Y=Yd c`hpdills,07ɨ;}ݟuTOW }cx;2=6eSg/HuYڞ[_/>:2|tkI:Wuf NCcrCܯX_Jb#J{|IYg1)ᩪ_7rc)2Y\*D֏!І)`y,:MBm[GT&H{A^XNהtN@+y V2.=K?{Þ¿p7[Xgg9s_w3'vwUMSM3*rbe eT,NmҢ-'Q[VIҾ33?ɪu`͍[*~?L aG \n2㩁,OtMQRiEi}7NAO rlѴ_hլr#ѶvKqm6>!fi80FKBÜAa?E_"GKwN]2Y7GǴA٘uY|yU#UI$& T1A⣌՗b=Su#WͩV0k1=+ݖq=~)>bO~ݟ 1zڽg#IJ7og}bbO,rɧ$c%ڃ]X*ҠL֗__KuH4IqKgX^CRgDfgQ۬Mt*+@;%݌d}II1Г;o;YjF-;?cQ1֟9HN:wP5I@|Yɋv 3Ig3)-%=ޛ^ubW߇.89t&$#6Ʋ?IZg>];Y]}& 693dywM/oXtn3ټSSgtskvژ1߭?~6]kl1ю)oP%`vW32F0q.]嬎4JI󀙬/1w_}IV~2xge,hOR|YW2Ơ!Ffz^lQ`>'w3yʬY?i޳¹T6dmW2</_Ri_D_Iy?I;ƳKQҼH$1~v wɞXnuKY{ii(gcziw2Z<ɨa׋g}JtmceL Iq@姆uE_rm䷅/ɧ1͚xTRz|S:em ކyy?ά|* άf5مlNyyVKOߺ?sq;Fo=~lYKۺ?cG:HqFݟ &񩱌^7@~KUׅgЋy~'J ,fYcV{n;$ZPy=fY561ZY=ֿdW-jXlb䧒=YF7W y>֯ԧiݟS6hp1gub5Wҷ`ww7;wR컧[|`ߩoʨ,UcZfߧwN?]M};ʗ_6:֙ج)7\]:ڒDi=>0#L)~Mʙ $|L\MoϨm`)]KY;jϦԆL\Ɣϔڈ)ե&^kGoJy6ua:f8SݛlJmٔEe껦 ԲkM oF j&J J %j&~jk&VM60T^&4P>L.LQ}.-f\GU?sCenžɧ<K}׃q"RNm8ީwR{ cJ14S6ɀch6r7ch2OUw46Q(Ʀ:׈ Fwv߃jDeoDa}P=eեv`4S3JcwCf3Y:w,{r7)t<62eyw\&X=[vWڙR[Euˈǐ!CO R )NCڇ!#C& (}y]y8,o@qlb{>W*W*C+J (4~S9SSzi}}c7էOѧOѧӧrѧLLڐCGԧQ=Q{ѥIu/Qz4Qzg=OzՅ.MS.tӥvK ]꿺TTtLҥ;]ږK+rԥ6KԥCHU]'cPС4FV]j:tΪCeCmXڎ_tt_P:X*m:ӦkSu hXMuMuMӦiڔwmYcm*W-CEuMeݺ]cz}ձ1Kiբ2Т1N -ʓc-JV˓PjQ9kRԢtiRzMkQ޴5/jRYhRk>4}iImOWڜE M*s-O{Mʃ&KR*&aM?MY&M44}iR?դ2ԤjfOڛ&ի>KOַѠ&Յ`Gy֠ AuAӠ(TTT jǚv4^YGTڰf5(?4ZF/-MI>n448Jx$6ew,6=SȯS?LGB jthxA}Tڐ '՗/㙎q '-4dI8x5ue`V3 %3ySmco3z09^wj]c6 [MzTzg:c/I_4%{~3mQlLpK6T6y9{\쓎ԟ4N4):I xI]T&_f{P?Z~-jZt^#Z/iѢ1ORCr}k>JEeEEҒ͖Acrf5YY+Im(oZTZ?X\mj iQڴ^iTNڔm*cmjc&)T66h'MmVҪ}GmAU4]*=ʿ/V&Tzv>~(N=ʓR'Q>6|o6>~)mzh=ib=oj{~lf?IZ]:ڗ~3[ο=SO}jk<>mԷ)-ܢ\5g>`@6a)MTSX69γ+;Q 2=lDc!՟!Ӑ˰e}42rwUs6Cڷ!gR~ . ).l^', }Y0#i'q=Uw9rK6vdMT{ɫ}bi>洣f7v'9mxaTӘaܑ_؜6Vg{LoGv'x4[SP7R4}GB&RF0:5ae&[lj~TזS6z7Qsy}̿|ϒҙqN֋]:A}NuꎦS՝<+1\:)U6Fui켌Ү\_f꧱Lܖ1Jg9Tf}%9P!#bgn39=l_}^_>vPfHegH1,c`X -NgniMucHebH60cLJ`Ԇ %ׯ ~πl@}ݠ+ HpMO@77:0gTV>m1{6h]o6};:ow*}J~)kJ>Cnl_E:}S[T)}*',Oڟteo=1^}73ѭWէңI9=*#=*l)H)^k2='z.lj kul};+΍xg\f]jOzGu>oˌy$a. Ș@^H'/`i}gTwwŘ9u6k"{=nc}ޢϷؾ2onϋbh<0->[ϸ~ }7v]^^|wc:qtY}[X[~[{NSߔY☛qdY=y;kL%𯸶S~quU_{I}>?O婳)̷oo'4p]/627HAIs>?|m QtO7d0!;n Zg&LV:#i<iHg%u&Rm;GR8lr>y[?9'}EXƱӺtoΏs-l{>OS&ƹZ Ѹ^}nuc`MޅZ/NrNy:70fֹ9ocXPK4k5iP_X}V-9: Ugֹz Y琫:UgjkJ.u.^익mS s&3@|tsL:7T8-tt}*XnKmL-C{ݷ cw1 k*ݬ`Cln93HPx}5 ?NV),W-wqq@^ijoe_ů&Zw>TuDۦwPNAۙ>=鱨}ilC5_?_0_}@RkiIԲ&expi}֡جCZϊ MjɕcX*=Ƨo~YO-X&qhǼo݃ڦ{l>Wtmj[Ѿ╡ǵ|PT~7suǡѯV_CnӾpDxR{+犢/cSyj,vmW};jb|ַnǩ?ɶ9f˵f O_r?+vV]om&9XXd9t:ѱEH]@ݷ@e,rwUU WwԺ 撵=a~>˪u_1ݦƧut)me֨5T*|Att߿kz4>jm'.XoR븚gjPfu}]ڔߐXkY_CJZ?iޠyPY*@}O@=4Teݳb.ShuPU![ z_x yF|y};aq3?պF>surʹo ѻ~j7^xا:U_46 _꼖uk[ oG5iPXݩsknN25?>zո*qCu%k\G=JMiP}kRܞ&u@g=k7 O7U JBܷ˷z/ tN*}UKxU}^}!;}l?U7M }N߃QžzVwMd;1N&@LMw\;4Aֺ2 -}OFք8&F$ܫj\,awk}^WOtLX'7|3^NC7}^|WL#yÿ{M6jnҨ_UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU+: >_e␵:du@=&خT*}4RYv|3}鸦oڿ,>=Ɨ8zAի:,o*LvUxT٪[^&Pxc`[YDz}EŽ<;k^lupUuՕM= 8p=V]OOZ:G=сoU+8ށ?۬ϼiPxMR:WթwCSgchF9etp4 O±Pwxs4Xw8h=S諺ʧ+\y:;<~]=FPW;j[?lp ԟz|GE/߱3ئZ]erjxvqwGaUڭ ѶSCעτWzwIKSochx^A6TY!~<n1V[©Y^`A ,4}T+ZVyC%U_cV^;p"q:iQp3/FA\vioG:W ˂u& ԽBN[gN(lqλ8fhYx =\͂z <:g_ΖgH=1uKQ̙U9[6~H:" g:B\(d%DcRջQOfmapM-}jY#e6vlWZ:6m.zB}WW[JfnWΣ#odήڜsaбgν\5so:{j;OOij˧^M3g6f_V5L{4Oc3\~;x ;O u;^d167DxGy;;lG3v[Fggn]W~O^gYShSOf}5t}ޛX6vVBn&c5xuڝݮ&_Եn`vlpݕ.="׋ivY϶ީ9ZoߦLx*I~OnpZs C0'CB=&r{BޞX|+:⵮2_ ;B~v0L^j1kdh=&GGѦ΅Ds{爯@Txfw}j3xffjo];t8Ǿ 큓*ilf=0ߊc|cD|CG{Tnp |?PogWf .oՙ7'o3R.훓)߇37xoJF7=7;GvDdz- 31pg7F7Ԉ#ڿ+V~=v߯gfG~'72Mqkѹ;esʳsV:X]y޺TC3߿ן ϥO=Ȳ{o雲uނMeǪӠ۫;{}Ȼi盶{iW ruڣYjhg>'n 7Ok?R7{ g\!FJiZU>&W9z7xo*szsۿO`v;DѾ7s#:GDTt&7>䪡|S+$vwxir@{Ll[d>x.xrHyY/3xQy(mwY]ws|^ㄕwBsv>BE -{㢭atc]Oד'j={(24uBwgpcJvٍnC3F>3g~h~g{EC73L̹лmi>Jh"rcDxr\M uVsYyÙ{rWd.c͍ə~e141 lyL^i=35}CW5vumVo~c7wL=7߈YGO;roP#ϴ爬(ھޙ7O9{Uzh_y/юke6<7ESi7wL٢?OE-:Gܹ6˴}/[woK]L_&f䷜@pѹMSG'B#!Fi]wF$״g  )wFEEcx>U|ۋ /I}}_RQP(G}=Q_*6h$_S(ZXt* b ^,#].SV@X ۀ р~ k@{h-qQO]'/G'x!_U Wᵞ-u)& -Bk෍C{dNR1[+>/)wx^t:ӑ+ҡnu'hf|2ɤO&dbi/~gbL|(S/ x[OG.-3(gОU'|2t ˀv:e CT[u[`;)T?Nȧ6UONw&NȚt@? Ų<,y?-ٕT{e( ^};4t_5FlOCvimo6j ʟG4@xl Okk TI_=_:->g+xy|VI[% 4X>)蓖ޞ~G{unGT"Ӡ^yGtpe ;;`E:>9:@[ O~kt-Eߎ};«ji(Ґ#~acP}`]GliAoKEWuY= , A@cI9 -iMiȒ\i?hblҕϚD:[0_IvthY cAz]揎i= Ӡgɦdo\R*TA]d@+jwh.m Gc"O!sϪ8/m_3_dkÚ?}Z3i5nhGvtV~*TrjջⲚۊ@C y*LEVC+z-hk\hOFZKB$x&B)MhDȟ?#:y'taр%wu֧>GzbC{ vAdE 2(ƠK bۺT:@uhj^YkSWŏ-?YCwwc.LJÿ>ѱ>2Z ~ ҨsC] 4TS;kcZت ~ W:|[հZx8~%:Ev9 _`׎G"w| RAPIUκk:ǮvTx:S.ܠx@K庛*'~'f:*w1.SQAgLFCcƥ)}Qyc3I 5WR6j佽*·;:_]n3ү'2v6|9{.y̧\^n!4C"_K\2~]N]]a0D+̉ju #: `s<|=>L(wNo Y?_pN)wN$p'C&Sh,!=9VO*ϩ-r:Qᜆmc 瓴?6#(mCs>.rL/wΤ3x6|:]/Y䜕S}_޳?/  WU_]p.?39?1 } Ƕ|Y@ -DMMoϷc66|q{Awkd9߅h14c>tY|Cp.`d)c> e1}OS>ecx2u`NDߕn% gcEAwBjkW8@ȗ ^X\k[~x} 7ʝb}mی|qͭ6oh;roGwN|c6͜͸Aq82{y'h3t!aA#r8/8N Iv _<_:e:(tUXvQa+* =W^XmVl./QX5ちY5QXZ[ kT֦:guf֥\wFEa]c.vPsEy +@z+s[(_GEw: ciuKVa>x0fEaw}]^0 2 x3᛬†YQz g\(lD]#diXya^hOth^^dT4=MYM0:$~UT(L=0#90dLdLG2z'/(Lv-&8Q->i6:%x`$&Պ$ .~ %u-/LjcOnVTV^x@Tɞ/Y!qOq5/='BC"6OPx%2&Q&fމ(藈Sb  el&2v%%b<ߨʋ=-x<3[ZʪNSfi?c aQw%Ւ)-@m{()C]?9MWhMݔo[jRo`NZ՛&1葴H'|+qJ~JdOVa )0^)2)Ȑ,)yV>O2RQ 2Z)󡉍Sk g ɢ\)W)W3jE͘7͘n-/l6'4Cf/fifSħ̧Uszff m84ͮ[6Ϛ%V#+(t-KR0zɌA2"'#[2r&@+Ɍict 8I1IylX&1w>$9=T ;*8D|KFWE?Yɂ$#{ro;/Ɍc2/Hg- 5+gaC2t3tKaQƆ֓hzOJW+|>ؑ S)+xblFf{3B3R3|:5#ws7'n4g\3=[ -FܒԒ5%>Պm~]*f\[c6޷ -_[lЖ81yۣ{hgOЁޑH#x ?yEa:N+ ;!c'֭ S/O|l>2f3I|D ج3};cά{vf]YjwA.g@Wb~W?2F]ѳ+q+6uů"WuEU7b|7l anĴn _w u߻1~ݐd!kkls6 ,b\㐅}蛅YPFW[g!O9 YCwѫ;sO@̡օх߅5Bb΅й}z[=ѣ'EODة'6E<\> _̽ߛ>̎)/fd3dzY7df69&d3ɑlEG=z&6dcO㘍/d#S6vffc>zZġlM7w(Pual0}>DntX}{}>sֺla=N9ȞB/t}C}w_Ʃ/e}`_|/#}G_|/q/~e}ns~֏|a\ʅ~.1!1E\i.1yb<]WOG[-0f xO>yJ>~O,0V_גA>xX0RcK>5ז_iY/j|֐|ֵ|O?'xC#ߒ[󡕏M|6e>yCgZ 1/`M -yx[4!9ql<ǒq'X< UQ(Yp }E3,{>kV>>gl,˜W#X3=U_eS?8O|WkƬym,dP_ZbS| (3|yAR4^fVcKo3ecSV<ƈ8OOQ)+(%g旰Wy̓\#w̯~ЏyON|/ş9ʁ>}mټg޽QoIor[/xq'zdz"oO\Ș_Hyރxۃݑ;x֚݉Manĥ1X#V~B34;3:{/@  2?]ϧ|>cw>rf@';aNNt0[g4֐4reGbVGrkbm'.gOG§-m 66FkkdM'R Z1Х%>][0O[g-՞=5Qn ʃU.d&XoS5_Ftn4΍~oCDb]1$O98';4> T,K %6Ƕѿ>ztނn^b!_\_a,jGYokᗵZÚx$Ǫ| jcWFuxV'Vg>T'[5pS5u₃v q8~"O;%_;9Op h ]Γ3x(w߉ 9Ѧ8<v~ a '1sQl}GGTv;(YCad:܅w:·qzw]o㳖AЂJPczMt?:ad8}Z~~wo0{'U_Cuad>8f<c/Kt𘋇 /1Sx?7m. A| 2󃵋z` ~?ˏ# [3O[ ge?|y&|B!Q~>kw-\t54#{|o8 $0l^W8%0[\ @!$p^I4G%m$0p K$pQӷy J ?Ky$}=f dcظgg /, ^8:1i5%~0fC$9RDޛ wC ]*Z$P)SMϳN}_[FC_3Q%u˫Y/V@ok _l'|O=Xys?&C;F+7#ѥ/M3?s_\ٯ5ŏ@@?~!w.M_t˙'>-lp{?C2*}{ Nz#K`=o`ܗr_(K˃o^ l+Ȓ 836/@C]/Z=x^sh {1y^?\>6DARy슽c}sg(.ayX, ,jG`k,Y7 M-s0F>Nw"=V%ぷ/_1Z+Cp"<<8/)bcu^mycgIi^ spZOg^K\%nt!Vema. ŃćKCWۆ/& F1Gko$^B|u]{.bC)40|>wAA?E vK~l#NzzPbX&n~<~ؤxVLރF+ueXpM}_ْ{^xEˑ{~/i>:\r/Kc닀+d.-eaۇ5 }{³𧮬#5=ۑlE||L @~x88r?knd1.bm Y X7nb]Ϛq mÙC?Xq bb8 վ ݈ Cq#19ւ5/ߐGG,K<^fTߑyo/ķfm ]Mk.//ډoUO}6D|+''[rB|gݱ{k߂yY|x_|E{' =ߧ{*_|4M=%'kHM>(I::wBM=|H|r+߃}0F|c]{<?f=,7 F`V灖: uΆ~?`n#r-D>V /x5zOhab'4. 7Ӊ-6b 6J|)l+15k>Y|o α[c>~Kk8Sl~+__xF}c֏첑>oݝnbvA>M~FCrd9i;'yPTyP5kQ]]mqSאy٘yՄ:/͙-V̫̟e'Gi͝X#Lr.μ'y@ox!y\z+̗暓Пyu1sq2O1.e\ܿ<1 c?"ks=F;H uy% f v)%pC5_?y}%B1˜GÚ'o"Oxt < q 1oi,{^Dٻieb+K)F<^C BE[bd}<ܥ.njͧ-G3*{UWf@5%ح~_|M7`ȱ n&GJmvb"Fȃb}Z? t~0rD<BNC9&ك`IQK]֩ze c?5GK?MYw@kk2] kW3r=-XZ#F!h vY:H4ֲtwb-O糷dx2tfB֕uACYƱF" lZ:ڗ\oȕ~dZ󢕬:y |\Ju|\J5JмU{5vо\CNFODBZkõo"a#k$4G"HrkFo|W_\W!pWc*OC .6|i /P:[!E~?sM> {DeQ:3^?M'-r&OkE>҂<%aӦmL8GAZMu܁ߏG?'@ ۍ`n#Fn72_a}_G!V}D%_!,b- Fހ? ĕg3OwuO4!~w|z8bWL\y;yǭۛmK1&ˉ{БړO/ă.e"{:q=s59OKRH ^T_Wq;J3~֭Xvm#-m_IN9kS:1kRYa }u6L0Zϳf$*g+ 7yt 8xñ1#uϽ]|ŬwzYDs9w 9pYL0p."wa/e=3U|=/ ڝA^ƺݎ559Awc ⋭-Z\mxOS=-ޟ<>!:YmL#Y⭘"0.}_tVMk;N'y=3A3\Nh=JX>x cgr3Xwe-'ޛwT=\%ޫy(`^PСxᙻH9.oܝ4ѥ5tZo g76U1ϊvxO_c.e?HvRk}PʶKRv9 eKgKيt)LwK;l@)[h{\Jًc9h-elP)Z!e;lt&dKC llW)33WJ2w>zeIٍ~Rv2) ^W|.eCg&)C'e>)˫)e9;Qzh)wg)qx^[!͡Cy~xf.gJ3ix oxsq#7\s(\Lg{F=q?9ZDSڈ{qO ==v?Oܞivm=Rܷ}/ʞy/](?E#sqWwhuAg; w,q)nB}nyμrWϔRLJJᛥSx)=UJϒ-tR~~VJ.:(+KqRQK)fKR`+WJiR t@J/ҩKct)}hQOJKK=IwJқ'KR:r^W ԔD) )cv Hi&gJi{oMR^J 7pHy\JgHɩRr|!%?-%?Nݳd2)ٲKJk$%KR)Y3OJV핒ϲdRl|AJ/%oSH)ys)7HJ^R2k<7ZJ>"%dzL](%Iۥd8)FJ.?CJʞRx &Kuki_ wk.q1F\S5w^zNq=׌z-~KqMY\׸z%._!d/Gyq]5@\W z|ѳr"|qeCgsqe!ogW';oEJEȗBlq5WU]k W")uX(ǶKT)y-?KRo'[RX)~0)Y*şCguR\OWK h}N?Β⏆H))~o/!LJxF)~Y^?!gHkx^M)R_)ů9KK˥x'8Hg!,dz/|>yd{A9=w'0sy _lw~vd( ^]0_C׫KHϢ_)~]SП~z+&` Kkkސ(L)޺BCcW)޳1B>l(c-3dq9U;O\1{KWlq纚W2~k ;0wL >Ŝ9?[)~АwU#K;96Fq]yD\#໙⺡_к%d^X|yqy)3M͟z if1W^w_Xq-}͏Vd01̅Ȱۑsbq~yx)qaW}&wJJKHI3b]")iKHX@,?k%NJv)Xv+ĴRrqb-MܻsTZ!%-RrulmhX(1R\`&yf#I sOsT4/u ȿ~[;ཇ80)zU.kTr)ϗF45\K֢6SXCӧV~uyGJӧ)3BJmo_ `[Ⱥ"CYgD)OX#V־u'k/mB{7y>ZeR5{6W7LҷYaGS.|!GK&eFt mtnH)ipq;%91]yq-wÕ.[ĝtB݊p4ML.m{wq琿k@L"72N2}Fq$U$ɻ؜܋|b@Qo y"#.qOBɫ5S4#o#9@ktq{a@mo(a#}{d,vg);}OF샒أ5g_=ta c_Bzþ+}9`z &eWWzb7M?:CRx^va\Ə?({'[MߚH3"eK?K޼=cwB>ȳ}gc&|='4ֻ۵Rmc}?.efoQp;~ڍ{'e݈~MZ)f[omK{mwbɾS]Kś5=~goAx7CxB8ٟ_VQ?N<{l^>zh'ssxo֭mW{[W~Nw/{߻D|tv/{~\ډrx.>\㖉w|g>ox_o"7&wxFe)'V q]_k|Vyv3>? }1ƍ#M7)MUE'(ͩ-W}kLO|oR>Iߊ,ot\F|@;d܂t]"3DM:^5ꉿ8ǜ_/ğ8S))֓n;F/*~|}{B]"e/S9. _WS֊/[>5Wݟ;Vqԏ_$ ЙA,~OTxrڟ,M%%Vst/ſBwj]{o?X#~⋟xx˩rĿ ϗ ?qǿo 6Ŀm9X߃{#xO9ÌQ8cDDS T%K_Ԛ%: 7XIAs /2а@cM2 4@3h5' "%@hK{H Z,·+$Х@;%Ek$paM g W$ys_r3$/&%Pp(DE/WFKI`P \, \RaA \ACW鮀0p` ~W!( \N V#Gjh? E|#R=D'p/,%*]:HHH!@{RN7'=*(((v۵7zι8>=mƘ]k5sk4'YCm~lf|x勉O~녾o}.=.zJ~;;[-&co6nq}ց:MT"ꋾq&2}.ѻjRֹù =: Ϯ659~m;(P~Sdjݢ#56LLJ_Ӎ=lgpߛ}DQ $`4Bs©ja=&GDGk K.q&~@Tut&:YoBMЫR iHԡ9j Ե=>tNI1LGө npN#=Fp1rmk=yT8K%Tj.RB'G28'SIĒĺw"1$P aDG\urqh).g4 Q_c`ILr 'pk(ғCAz ` BA D .hO|取}|냾|ޥ"g/zV݌I\{;1q;7*7wŏ+WѮhɅ.\ra z 8 9g48/ř}Ιܝęuhљ=B^:mst੓.tԥy:U}UG:~#fG9~п`? >Fa %`r̂b?Kmt1˰jWɜ cfdN^">96cO-$sj/5ROI.X,Zz|3c7$[g:yWHds_y1̋X'Fd>0X> J%9.*}y1>c1>ELYĔMLd%ط9,R;rf%令3XV8!\|堟lfݬ5X0ߌ; 7 F .3n>>37<q⩩lbKHLh0X%&NTtJ?K40Փ~.mFs=|nyfh`.yͣnmV|Ļ,kc-Exb,fSc;98 h*y#<^ºKn YJ-eR4Om+ ګx :{.Bz@!Xe!uPHWD."jf>PQI,_j𳜜wcuU)""8*"i 駅|.eeIJ ી\ ȣ9:e_5ĽK4ޒGy/\ukOc#X; *b[L^"i!X6 0n>6n3:$yp152f.f /,x50msХu.+?BI&dDIHΉ`@]%Rkh*/ 5˜XtÜFOQr_$̢gL@8cFl el7k9/@Vğ?:C_~n|o>ԋf zCρJ w|ЎX+\ :s&?=JG:L;5TJSwG|Ơ qC{ ڡQ;pOiб>ף{45;^3: &##jv8l[7gg||Op >?@lΆ4]6>&paG9. Y4>D??>_>~/RE鷃dL|IŒ%OX+x A2XL?lKGfldz$gkdz-!~ D2}k')ºI{1|ݕjQ2}UX4@2I^LΒVdI7m% ޘ*u?t{,k,U֭+St06Q2]yIZbKzd^L.<# tςp83F2&<\$TO<ƈ9g$ӱXt܎vLGʱ^V }$Ӂ/ɴlcK ~A|B2;<}V2Y߂*T?gf4`A*@%ޏG.vroVO2 `m;oĘ LVxr#-6v ~7ǸoHn=\'}:\WRi-E_k0|5mz#6ʙ_r+o/V*Ƭň{PʸW:ePxd] N+Yo%d jr>V0J~K]:`QJuJT 90J઄5KȽJ>^&]VxFlh-R˟Se<]lQq1yVB%}1RBݗ#]*R] olJM)+ 4ͮرJjl%i%N[>eWF-*|Up1r0.'r[MY乚Pk5u֒c* >up똷 m`xوf6F6MĻ mfom-- o[r+yn#m o`rmNIE=BGnws]u%ו\کu˵f=\Z¿*j,`!Ķ%}ļ9S_OGKztAwC0ގQx?J? ;1j8?qtsOONjjOrTbifi| :;C>KlgYg)#<=<VX kk 9EHɿk.Kx ^h2BNuRG,uR6WUs \cƯub'7ޠ.odϺI"[S=6xF.×_Krxӯk/߅{q}cooɷh[4s|= h;ܾ#S߃C~H{(#G|#H>?cj18='rz ~.WWzqN))s>ϙ>ciKOsk ~g~g,e|C!~Fisly1g8=ǹym<|/p}Apl™ כڔ3h31qnQsskYg[p{3_ϡK_x&ky%g֖g8L2a/ gW83H+κ8k⺵|e *ׯr݆6pvm9-ζqo8g5Yuz`q<''7Mxٵ#v乥#xYg70 N9w9-r}6f҅XAb ]ۍy3;$ݹγMw9g{gO8I=9g NAoz1y79>߇yǺO_S?<,>OU>!\|?ϓY?b@@k@r>xij A?y<2 a ؠ!Cu>!O k|JR =., Ce|k0ao fpF7y$#QfyM1ha ZK,c?xje<ہ\kpp@NN&oka2\Oſ#>wbuӡgj,\˅gwWG7f&<>qߟ @;  W0\CB# CapNh)zpɼ7{iF{HpdnDy mE7bJ 2&^c8kXQOG=ufy'0> pvY7J^{Gtv$;dl2&9KF|)h,E~σSU =)ݤo zJR!ZL7o1I^~. vCN\O]Кħ'=Czxփ31> l7@# n+NX c}6Qְ%cEwR;o}樼Sz0I4KW"4pH֪U*RY#g3}1R&[wga$rIDH%b'|=s+31pOω'x0cl=!bY+ڊ) b=bګw{t Qh L$9D,⚕I^Ah$ 3/, r !`j& @|K?\S~Qhȗ}Ǭ?x3֛^>J!ӣwy'=Т<ߝ:sPoܨ57'Э8Uxt#:s ]9u+K~tण/:7: Dm:Ee)ﴜI'i:򽮮WPGuJխWIog4I|Ls!~A;3s#:%wWrPgG£}M&vG3h'';%{ bW^0|}(BJ0#p46`z̉{YsxD?#9Gg}${ǢXw3'zMߝQ%"y%Q}2{Er~ i`+=> h k!V#O*=f]%h{I.o h>.`B/d^Bk1Zςl8FK9h%梗<4%྄|)ȗ˱eXHʿ诼g[No/fb꫄Jl``wYNɡVj0^Nky-}+izYSsznD^ 6𷅽e oeݭ݆mĻ-lİvNzN]仛5v3o7*_i"ܚ ffnj=`o|!{Z'D>uTfU*US>PE.Um? 5`!N >-ԓ\-6u XЩyb>b-hB-X{^|}V=3 x[An~c! #,hArYЀf!*tTEϨڬު $$|H̕Є{yX&Pf7MѨLm"oTQ%yWv%nMEλ Bg;Sg.vr؎~Q8 o{_VJl-l6 6&n#Zو6ۀ6p=YG֡ j5*s-_Kk>X VVWr,gUhq2.2.#|\WR;+^A*RjRʸx*!b,b8Xsu;B|SœG6Xw>koi۩\}Mynyo-ms:lΒk,/Y\O} / (BbX@ 1 q>}l>O.pV2qg͕ͣoNN1f{:9i:yρ99i'#]ks1kك|FTrOe~*LœdtL\Io I>F}. mgx|ǣ8#oߑ} Ű^#E(Lw~{3s/{ ; ^(B½`k09XY`5L?]|`9{w/ό:,6eC>x7<ܝkO سx指qq7ӱchTߵQE/I? V#W#?\G+pz{ַ [te fcle:vF~b>0/]~Κ0b[jV~ǏmpNON~#Xg uhx :Fo41`1F(3KNDz8qn'v`nooVt p8'IDmL"5^Խ#kOAsSΧL#i-s66I ^z&'vbwA.#]Jh͍X;뻣Ꙛ<_33:"goz+Y| g95?Oo )]Kz FZ :~7R  gJNz}8,fLzL48Xg,p{.3*ZFC`}C=#M ϼ Nq`''-óܬ9gsvHyH/\IIdK&d?^B)Ē"vO*5JM#@i#ns/7Ģ\g]=Mw)5k`-|VW j |z5܌ew#G)5g#:0F04<5``V|{pz4L34L34L34L34L34L34L34L34L34L34L34Lf\34L{?4L3Ѵ>f}+}>jZֿfl?ώE34gWL3]RU?>Sidi۟]fifh^3kn ~ӱsM|NMÖtv"6e}T4}ڱ6ZOkG&D){{Gk)Ż3Dsb`,a~vp)t{E` ⾈zqF$o"R] }ozSHUmW*u@dv;(._(69$#$E9oE/)1V)Nbb`)IdM ,Ld=҉"{Q>0@d@:Z~FЉ]"gi?Lɽ!"竮"@䚞yM[rVXͫ`hXv(ZŅEjQִB#,b!b7MCs_XA bƋb׶bwrOT|P6洷Ğ)O i؇h|$~6gϋ/w8PZ8*ѽıiö8y Nm'N_gn qIqy@'b7OEqisN\kM|ĵ̾"q=G\?+n+nZHU8BQ 'nJĭV- }QG&a2.\xʜY?4Z%=a.WlFu܁9\|X}5HrG*,o#GXɑq5c=űa1w,d˺ء<Ǵ]#ubv B? )mmW^\q4k߲jPON&,=1/ʭ}Ϛ9rxdb̳l/6_?ǫy| c s1o^d\e{Sgd|?X/d&>'Nj+̢yZ u#ד) k~ZKjLI3rmS+MD[ =NkoZ -t7gIϖ{ܣ}}JޣOEQw2F\m0ڇ=A3Ӯ~)U\wk!oq)=pq1U-A(k2kqWB 1bwOCpvJ}{ι?^=e,=ݟgS<y&:ž }uDEΡ WvVj=gP[1R@MO02?[)'E#"}+: A*Hac^Լ{:E`퉗s}LM+ͣx5x^Ͱ+xu r՛x]^wآƨ$ޡזw(3]*X˧ԲߋIx~G'WkAټo)WY<o\Q,KH!b:scDLU֭,pkVVj[) .zev:j7( S?Jڔjw'Z?'{JDY,*/k_&Ow}yQ¢D9Tb'/!(cz"/%61D 0E}R|j)N=aPD(>Izam.}']7Rl#w9MCB' =d77VLK1BW CiW˱{MԱjo"~xB3^@>qaKT8b)( >|Y~NTg=IY1C W'!$gu@=MTqF _w(V7sWQuySB߱տ!_ }^"cbbec/C|(131w<(Ṱ?c1"f*EZ?{38aP7!b7XXQbșBZvS( A>9Vjޢ"w+xa^u߿݋]7ۛ+PF~0K]+X ,^B??{9aJJe~)enͳ,V&,GS-wA2C.® I)~_(b@ S@E3|~KMb/bCwۏ̟?}Y)U]Rp {q`9V}?ǞģŇz_)1cSb~wJ8z^›Kq+$u›()j4<Ǜ xs!,nCSi$5 ge1Wk)ʩ; 8Sbxy8/'ˆ:n=n/SG%Tq|:cQenVZ=uFY<1xyyE>:/xq&qҎuP{yLJU.AGi@E mE<`r=/·HEYSY. }Ŝ:RtJlgL.kMz [Z\;(>kKiD9:Vچ[ oBο 7lqv|c*>9C[/ek7|y_Pg$JP4f#x:kw]~?~ďU.?i絏2ڮƯQu7~egϿe_7 hTmϫ+_GcDbB󢾌W2jQK>USd >1\E2n1~1M3q3ܬ=C|P݂H< tUxpJVd3T~/w">ZuŇ3>oMVQ;*EQlzW;oV߉+^Y8b/' ن+/}$6++ӿ2-⢲3?KC=Rח,R|R8g駫/[?Y|%`_qXa">( l8/CiϘKGqr>+ >t3\1^ (gqF%Pv^%_.ڗqƴʜ =>b8oTvB[n?w#ҽLjXl[,63>|"A ~ŹWc#B2X e2cs.~ss"֏o(;ϫceog>|Jه=ɿXiUoS|Tw} U:Yr)0̒Bg[oī"6SbQ[yWȚʽ?!yD'y?_um]'~Ĺ8*bž݉)Yqźksuٔ8,/P~E|^v^U bD--'cW-K ,P6&aŘ}'12Nqß|eyq,t!K}Dz߸Lo1;(K]J {BqG*Ο9W:}8^}*}j=Ai8~WBq^-uKϫ}Vjqx"^}~?y9UYo?XRğ"boVYRXRđeLJ"8eCu,ȱv>ޚ SDžodu|XJ\WW|Ϊđ_k1?[fTw(b ()QČ"2Q_"aXG#*MGVWruuSnzNSuٝ)_\Nu4]GsR75:G!WAN:*e)N%u8NOZ:jWCMԉA2NP#C()  eees#)At4hZ^)hѼVGٴ?ˢ^ N.#r| bOB}/SUEBk5fFQVO@sCi[ź蓦̋6\)~g81FGcr>4J/|^bM+;J.WBI'_<(߄6>~>|/ߗ7/{F { †]9r"XoF%ocg"8xBn\R ?/Ź8UŽz8Uw#>+.G\{G&wE\T5ކw5>]!kbFVPDg;q}Wor f2l 'Mԕ8u 1p5.(o}䘭w- z1TC[&w }B.H3gh#iZV2lїW*#tcE Ut'9XE0t 2 1f)Y"œ4V0B7!V77OW Du[\<~!iesGlLiS'V[p:\N}8\Pg)onWZ0ߤ߀`-)obNl~71!Cy?6v8ߐ p['z4Ɖdٵpd觼3g]T%\_Y^_㤆C@KP#)뷬Oϵ"]yj[̳p6 n}*mJۑ&psީ]Fp8rNvI#?}ܩ8uw:NhӿF̱8۶'z|{(ܹ8]YMg2)kgno|v_X m%AKŅT;ҐC>pb\9WGl/q-`#B&"U\mqe.^zzC|̯r>6)oC.Ro.ז.TySJO\Yg+/\%\﹂/6 ?cpSq՜wuǵqPURrSq-DxuTG_ƝUPmao6C¶X4TC6yC=J("GOT= Q수ka?!B=8&.[bpk Q~w|хO}g۔0sμeYIMag5!'s#sr4AYekk\1ߩjp{Gq*V}Oh\84 aZuoS} ~:"`\znF+kZo -`EOݯ~R!O?R~U:^=̳csE7:V-]o(|lpK!쉰+⭬ȗN9ab霙~s+Ux{⑓4 gտjPቍ}7Х3=~X1uݔP>[!_GфM;~3[`mT_) ~󱜏漊y"Ms 烙vA^r ?~\㶾*`<׏e?G"Gmsg6ZVF=ൠs{ ^&t.: dvƟc_J<-ƛX'ys٦Y?Y)?\v~\ǕplSO 'n<c4{ng:2͆uoʚV\X ngrX)16&ccGu&n#S μչ}5᫘ViUViY~%y*r} Veir̫v`Xil>11-ӄo{ŴL Ӌ6\w!-y̟üY OT'3=tqPq}$#yB!\wW2]~L".g~#8u'sY. pNrލ\K} wbg͂ÞޖaC.r! f4a0`ӄ9cg[}3NJ`{"_q3ӾƩs?8Q}a9jOVriEK9|b?XސUYVUi59>58ɩߵb:>jEPpڀXF\nT?4涍քiM/ľ)Ӛq}3oy41 Z0_Kk|b?܊Z1_kG|kgzm}a~num9N-WKđNKp׍1'׍ằ\7iX"6e>7LL$N'1dOt S8tN4.Ogd˙gn3g&bY\7f3m3}p8o2p,Gs<8/b3|[v,`2"~qz고3i"05_-O/ѧ[  9:+O7^EϝK|;LW~Ss\@o.W~+Ӕ!u:/yBXCeq+2 A7G@&t,YHş &P&߲-ϵW2oq WQ.Kz+s(~Y])YQc^qˋX"./fy9^,\'.D.YbO.m˿b/;2pN\-vB\^~p }mb/Hmu.bbJ(Yf| ww4,py/~nse6!s=qƧW}9MYJCr:1`u X!\#ӈۉWc3̈́i&:&,˔e,33cY,KWǢeZLKnoɼV,ۊs_ޛhkpcm츍6zsc/8|Gu侏sǹ8q>vi'viLsf \4W2͍廱n,$p٧vivigvigv۞;"ϱs遬[ 2]1\` >,A\"q_K,̲yn]Z .Mhrk'r.)AJJWWཁ1Lo\ZXmL?t}.sj4{g㽱t>w2AL JI4F&s'].v\^q^SރJ9}"Uyj7wF/D-r]|7: SSkf,9[p[qڊ6-k<홧=;0ijp}UG};1Йy0 <]G)i 6BfR]Bwqւyx1ҹT9eO DF)L-'9t5Lc#SϟTנ{N׈x}i_KWw:oO~L;51 7|;;ߒo&@ `" (vwߚ?Y֏~}L?,ۗC_aoe̫|DN.O,<ܧ\澽^d^wpO=ԆNgv=STj48mN Xrt^7j!|qyXse~WqeW{ uzgE$gۙ'O+eN§orupd9\}8p3=9orcYvolVQr*k+xXGO{ep6 p;V,ÆeZ,FbX<§\,ۚuf X'܏˚R})X7DY=UVqԁˎbDzg]Xc8ڙ0]>r zRL;cgZZ Vߑ{09Sz҇V.&C|{?|=yW f++r,v";# \s/lS0;<*)s}xW =e{S}vHml/I]J}cq)1؞J ^?*_~TCc^Jl뫰g +I/>P ;'|_/ %|I۝+91?0ms~(Ӈ1}ۏQ\s\7n<'r~'s~ Lt3}:ҷ%~*S&Ma2yW2x_Y\6pCK˙{pl-F=V.o2O`=py/c?[Og4 rsv=f,wJ*ww]}r$q{X2ݒ{"Y1M+r_e;_qk_fxٝ ;\ܥޣNCPv"9o⾄*S=I<#ܑ0-M܍sY4Gܑ0y>Cܣde=1sYܛwhO ?(L{ʴ*"-(܎Od+w-oŽN5+}Y*Cr Xƭ1特Rz\'$.'q>e>o 1\ 7< h#dZ|gR:/r*Eq*~s N;:cfpl͉5e]zi\z{&M.DG؟~t[6cTTd[)쥰Ylc86[b'pSE>N-gĮ?O{,P>Jyǜe?vxlW[c sV'}p?b?2_3=vM.cD" UiL~O'D\y+nk3Xe)oX<^>Mmc{<,G)o8si+ox~\#o^[Eҷozot׷xzgjj}GV2]uK,}(ڥnA;lmu*7^ot Ocon!or)tK߷95J!NN=_{Hj)2Lj{bUb<}rdj#y)-cGzcJ=UNMtG~c,ikF[S`m<5ӧ67SHͷPYMc|hZ[nOs ŃbhE@,Uwm݂oN_/Io7ҏG VqD2UHfjy8H&˸rdE)&u:Vܗ]iBv]ԅ<瑝m="dBd_1@g~%Mߑ}%*GɡA$9@ Ê0m29tJv!d*!;˻dW: #wɦnnCVYO}:2nٰdL'<%{d|.%#taMKkD_!_aQZP<ɤy4-ΗhִO4fUW:^F$UX,-?[#km=_-NUMa+wUT-0-2$"[VGBI i[ EpHʾ ;GNt}140,1:r'a0q0.p g*ցG0 nZ~> {91yT嫁x!GT/$'9 1_̵ݑer E$8f5"nYVZwq{nq9R~n},n; pgank%w3΢? vGAps<ƽrpE?_? ƽpoBk~EPr&D9UP0| NC7LŽwXlcWp+(,ŚJJ'SWHJw歟i?uXyQjbUģr^`-'yyG}efWdg!rhrf}Tթ4UIA4d\HU铦d+i}cyjJh+2O1mv&rBL.ix-"?).L]t ~L ^q+EuL1DRՇbWwD -PɾՓ-RbBJJϾSbf%-3(1>%޳)iTJu\B(\8%]JIz\n %Od>RPq3J9I)(%'RR:P3J)՘R3)%z+<@)ϝ)Zvԥ3)sK()JۜRG:PJTJY܏ S2J2(irUJUļ軖]UcyJW>s)ᙊSBI6-Qb,x⟟72%TBSWt⟾lxv{)>'-(09Q\nkb^kS_G)ZE=эheɛj|2"w,E}SȬtux]dBA=(z;ւG^":?NNnw[)[ud~/4CSޕ AZnU7Ӣci>\#U, XzlFRcTcHU"v#?<@w1.){%; }WW.KCͷĪ#[| ;wh_T턻*_H|SK;괓̷xHi $*)D)yEMҫ-oQvjh Ѳo :쯋+ L);cä1}3.B{k,}r %>`:}W@\.0uF'aZ:̧'#LtW8.}5f NZEo9,shx%|kl{x A"Xpl8a;!khD>yHj>FHk6‘YmȭVyzAp?9NP0%X{_3 mx0Nƒ.6iF-P" +/vx +pB%:=C<_ߗѨx$rxE_,TƣWhw2[q#.&*2}ScO;T#y 0 XHgƲH0Bsj\Ɠjz{Ǫa} ӎQ'"h g["y#azL7jBl+b v` ļC厘2b6A  1sb<#^|ڎwmѽ*R߂6Ռ '}6 2D[^N!"1"Dj7D\Cx37"<½ |wX ;a;am T\Zqm!\ 쇫;Rq3\V+7{ʻ(!ChD%BOFp}\zbvyPs}a7#.WnuSQY舨6fP}|.hDw`mB}0Q"~ Kc[q 3+#@$ Zoo".yk/bM=e-bDLbv$#K/5:_A6Z'i8bj@bDoE.D/@0D+*eV# %@3 wT?!7 y:Ȟ:ގ-CAG"zc}/sAB/x$uCb}$ilGRH@?}!$>0@}H<l9H<Hͧ!t$d"aszBw6 qAס;bv#ՂtD<({ rP6FԷZcD'D6GĴwwtYkXpmG[\u^+}qh\o`nܛRxh( w0.N";]5e2wHw^-x- 87)ř=8ɳc!\pppvSk[n. 6aun%w4&'9xߡzpg]]%:wkU`Y'X\;bl3̸}ӪLئ.ƭPa6H| Flİv|  zD58hrgEZu4}i5:vDtQhmeh+APu RK^cǕ?Kw=7u҅缏ҙGm%pɱ-zhH/K:S򰆴(i>RW)]jf\NRpCIl>frF{_޺Z ˉ}oET TWlV8]\T)TV|%e!w2o!]Ȝbܷ XNEǽd1z Y@GKvۭ4_'(\IMedQr,^"dnkekj@V 8sNIdw"MDmCZ׃ 5Ⱥq'd޷dYOV5Y !&1d YNc2t'KOƒ' ( "lDךYdYJ$dNj, |j52+9DfWY2u%Ӷdo ߫@ɈFlɐN2/& 2iHбѱ&_nHwQt3 F2mʠ5I_=I/ڍm{d ޼$ùpa5ND2jMFd9EFJJf2 %go D&d&hC.w2 8EPe$ Rʵz5AFxN@&$2$TL5"v7u$\2+If^%o4%N!gLfٮ02shEf禓٥d&s L%ȴK2L&!dZ]Sc2Q9;#d2L>!|2L}lLf~2yK~v^dc7Y|u~ Y7AאEd!~Vd^=H;T2 <t!zdѶYH7"5BEBYƬT#XvW>o Bs΋2^^d@z+ɪ|KjQtLd5@ d屑&ɺ%2P춚jXOǹd?S=i4-6M}eє4h &'hY*MDSԢ)z4U+5GnvZh ͮAs6_yKv|]pZ-xNv$ZDVNsKHwݐC늚ӆZy3ںi@O}:>CGst#۬h>2't,}z ןlZ݃!u9&nhr.r ׾Mk=궝N?3{R\cgM^O+{:oG~:_|/ ibtL-\m]YڞkB ]T;)B6EֈHkQw qt8%ԜJ ?(g%w_)K7Jk8һܠF](1eMY)]YBS{Ckӝ\(_s=/[J=)k?1}!_B7[эt#?x{nE7 эntJ.غn nJk)e;;r q+)g6e[NY+)(2vޥ::R"-J\C(mYPc RQTЖ|RhԛJ<.L S`y#r43̾6"\Z"䘚Oƹdە}|^12ٔ ⎑Yt-T жR@i/ l3͞=xmy؍j7hn4(v6"vm4Vn|{*/7[kN7Lopoזo:o8Z9O䌠Ir꧕rUk9:@x[UiCSu>/{zȎ=beβHoH-V)ˣϓ+7+*rhQ&lTmj5$*pipZ{ jWIK֞5 .UNjvB73=%]}֒DɪyɩiԦdTrk$漗2.J& ? .}X8J4BKQ.jwٍF1Z,C^w#EMзAo ك!obx:arTZ~3?-${? ͓xo2neagK+>53t .c,xc/őϠ #'7<v7a\Ɵ' &ԼLo,يW0 枳`a6s=_zO"lM~.lhM*+-pE 7m[UrB Z=0"yc_*7up& SӊpvN' 'fĪq8k&{^:q'6i'dx:p(Y{-9?ay%G$ r/#IG;;>&q Kzcޘuf2bZz=:D`"T t> yur=mIJ.Փl&7V(y uO}vNx*jxxKQ1Ts Ug ߪm?&׸-M#yHXy쀅Jzs]3c7Ȧwv峺 rԩsrܜrj[K9XN"{b]'/GgҜ*^ *R` M10j[~{L-ʿZS빳PjڽQ>p/L:iPGt/6K+R,+_@Ѐ}h@JVW4^QoI\9ҾGRBl,{4E2`̋4&Zw(=yptǓN[}s1KRhhqM{ϼLsɴu>јKtn9:, N%_Cpo6|JvF[H ض\mJrON3w+m؊wQ`~ WC$UE]_әBg)bJ!$[%.QB6PbCzRl/PݔBW(P+]Bzt uSe|&%|W1р^Φ!MD4{%]Wkzwo:޻D҇rHCw}4>I~_>b,}1>oSq}%<}WsyO,[kbזVu3}ٝ^Su_/PI˭jt.~ͨd *YVJֺRɴMT2DˎJR 3*2J?0(iM%RdW>?OccXzme,ڈ_xAOg7OCӿUty}UCYnF-) (LmCr|K(V(]y<#N3OEgێt2٥'- YhDզuW.iW4aN.IR>D=Q֓aԼ jj߯M՛RzrrqAH+Ws+_ΪYN$G-_:zɧʎjǚ;[ՒWv,O_`!K^kUɝwv. xUʭ U.O P-i1IZf;ՂŻ7䬖3un1I{ &~ϕ׎yJWHU̪KGHH]wEIR9EFڠ! J[7N%JJYwJJJbV ^#|и < sᲥ04>À0, Q'-7d 0V&a:)Lm ՝v`Z ӎ`+ &|kp4.98-7`o]rbǽ;ؾv>݊-aO4'6 N>֟#~o&ņ6!6:t [Cc(vXĮFw;n]~J88JFH=hC8t6v8[w8 ° z?ю8w㛑0Yf0~ 6,MK]90]8GmWaR7u`֤!̪Y4΀Yrvy0 ؽyP? a8a ˖Q[aյ l#`'Wul|Evl Q؍K~@#~&%N[~Ikbc$bCp|*gKSp) '?'rgY8=}]zm25ù3p.3<;cE&<ܬAkBxVOp<lx|{ϪQ2Mvóxqw<y <{*<3&3^ «qwx c[-6;{xwt'xJlx́^gy:<\A;?8; 88SN ǙqfT)pv~U {;p;57ex\ >]z| / gS. ~ |ų^q(u34&nudkr?\۱_kMKr2P kRG.9h'F.+sTrvBzs\{x1hJK'Os)9J_G19j7#FzX9"m0m'9tL+doڐ' d7͆lvN6>nd3YI1zJ(Ys݅Cd%T$*dkBd;O1l'd;\ɺEjR,7璅.2O}Ifkȴ;NFd&Kt'x I;A;dV qZ{3ByZh浾I.[ciŠk4r AysYy꼳yӘ.̤MaGtU~|E9a[9"t|RlfU6M_+V^i<y>zG%rCrorv実ɝ+;o"-^!Cn3Rn+Hn)M\4F]gufVkyߒkV'Wl&WF\^կrɫ׼d6!ƞ:_ST?fHu5#R(AknNگ񜪥Gڪy?vz:G[e5%c* UhQ*p;UZ?3Uƥ;5dS}QO\Mvjrrmw-M7+]'˽e\̩{(#܍ҿV.6q-oޔ+C)l*o6אoIW=Oӥ#^-H>TCqO[-8H)qd./K|i[ߩfZ2ĔfmoG?Ө+4uM[N*P.MUrr̂H9m:l'6HsOIseK󺞖fkIM\JsUf֋[%MlSHӆ<۵9~7e#.I+hv,%NIܚHQ3qKGͤ/Gҙs7]N忡o3+tM#-8e t/V'nx-,#[ġ ٛpncxwrleE!G#4W7#7*<#!!IK!>.84xG"Yd~heȾ!?ܺUs#3V8kkuk*e#sb2l'"ݡґZ<!1Ko!V=DԀoVXazj}: #Ag (-+ZRIal*=-z')E6!ygl9HZM*uܪv#mDIrS˛ک?}R}3In<8~<5Kӭ7l$ɲE|Y>=CvNvPI>ݦD>+4@>X>e }{-d9]e1,;Yx'{鿕-?5DA(Ω!_x#5%ް~O~iedO2so ٯPٿo 0Ay[Y^Y7P1&ϿOMS>O=d_~?Ɂz !K_'N!=!:Zko!irHںD;Tt#FQy2%l9fߕrJx 9o9?\p~&A~}Kpqc**ΣjPՉza/OAhhc\yHsߡ~ m:^tL6GF|!iȮ~9$rsӯt|E>/hRBU)|EZGQ{C+;RФ(ɾ1%dJR$J;ٍWw(#22(vZ񕲢Rvъi({]GWke[̀9&eC)}T;J[R׌|!#)%xbUaŴ>~-$Mux'EOۖRM*;S~tg+tk }te .Y*}´>uk[·UyL I1t..->HgfѩCWr5B ts2Nѽtgڳms ~ZN f̉hR7FѠT3ZO=CMޤ:3_Q>\AC}i]9TA\&fߑ >VN>UEoSzST~~k=jRmfڗ}oqCIhi}WcſA:t|d6V/|$U:(Fl+E!%L#e 0THi%t<$}:f/, \\zCиv 7AN оestZr]ΡG2~v3E zD衿=6F6[39z-ڭwT6~ ?t/8`P.>1ĐZ~? he!cHS~\Rc";joz5Zxo?M}7@aKпI?y] -i~jiDz<q.J , ^R|i<>Wt>a`h= nmпT}v{1}MoJs~!Wѯ{wO^0A9ĐjImo#+cS}+xvP"+=ȓTS EM'wkIOҕ*=@*tGƋ´9ҽ`pW[8 ]*,vQPPit;AE]Gn"'ݵ ޮOӔX _NRѣCӥIjhIEqRCEO]ҽ󥂐R=}}{(ޣR'])kG)iq)&R[Gtv zIϧHZkYS?Hmkyڟ?~׎]mA[S'fUuYUM'F,z.rV~F#PJnD|"w':!rĝҳc(cP6cA)^4eDSk:f(Gلw{S#|rP:-rl܋ )guݥ])f,/|ISRʟS~T;Ey.Ix5@o(7%JSnʔ PpF({0(eQVԇ2gSƻ֔1ԧ(fJ[Cqu(uVCJ9A)PTlP⻕8x%Pǚ?&9oQpbG):2{%W{#!1!"Rvp _[B.]1z]]2GW&ej쿏5%Tc/R1G]XszP``% <m)3 NEtaK>5׫袏]Ԏ.}F&&k=]m1kJ#_IKR胥FAq„"7S+E=[H* $B4G4cD^D'>XMygH>G$~B+ݦ*G}HIQcXG VfEHÿ(r6EVMoS[Wޒ"ף5)j9 1jF5ZP疜FPX% 0+W wV[S0C x-{( -ZJ3(4| Ik'S謱:JBr] @a) kvRyq=G>tE$U)rQuD9f)΋Rޜ[('DAn&󶇂fjT8 'vVQΖjJ9c{QNŔbK9Qq: Rd綬M6<^=u{) 容CҔq猨Ja3)*:T2S/JIi;K(ukJiEI(;J)G)6b}\2E8R+ۈ :3RG>L]Sȓ r?H׮h]k0v;ꌙtc\LW:ѕl/[+H[2].k̠h >8fSpܰ/]zm9]zvtqGt=.]Jӥ9o9t/]|`CyEٕ.ԡ#bbm3ХGRMtijdIdLE;P0fR7T5+#.VurSl4=,l;O3`2k+BaYm.WGp|rxoTtU 1;^-}y3Ϲߓ_x6V]El\xåqK&J3\k!z%mTa|) #QDޭo Yо11 NOuG%@Cğ^g>HHNyHxw%HZIw6#y.?-E HCH|tH182sj#k[DU;LBΓkrCȯKp=nMjx Vd^NGsxDŝqwD]:>(X' EL{#q ܫ(xɕP3GtQ7wmL]w^9__qEn/h[qkD9ܼh{O9Wr#[crf ;+6Fܕ<O"CsV i*!բ"R k eb!3$G_H\gH8q* 6' &=1b]4Z!# s pQ/! D3BxI}B|kaqu~E\Y1 #xE\Rq1-  0 +OFo_w~Cu_q[kg Su} ˜ow/xϞ=? wSkxxF"mMXk{box7=W C{ExiFYJx]jc:^vN{)>Ͷk",o"Ņp '5ŕ#{pO\ɛc*jLD o+1mvkB x۴&( GP< یǛ7&>x];_|W}vFقoxxT  ںN q7*j id2GfS U~H~=SD̂l㎨ma t+ (E@ ÀO"78LgQ qrwk.:p|rCSlkf&a(]9=ؿv,MA7-ϟk 3o 1E;1M=U<#'( mЅ. SщƣSvtjAxO_n}ݝhYAj1 Z]hQi= GsUEӯд'4iM;q 4ZEQmg4؁FdK.}{}A]ǚ" [NǴ(0,v?ڹX ߍ y ;, /]*D\S0]mTxU߮;T=| g.I&)ۑB.H>/o> z R!>FjqҺi#NU܈TaH<)H37_!y$=[.w`t o ]Z".SFܖ=롉/k ?8qbBl`^vG\.Ɉq^, mŶtQniLDfVy5WDk4=r 1 *Wj Qǭ߆U~ac!<k~5qqx\,  EPwqo&rk%<¹-g-pf1<[d*=M[pph8p4<sphU["ad ڇv\\Ѕ }Xݬ+rH s0[&`3`ȱob.Z3݅{qpu+h=; ÖiuA%`WXl?u0`4f?L &b`c mæJ!9%cԄ:#Oţ11"R#b\0K_0li z!1 򨌁1Q>Ţ{U=kdtY: th7ڜFhY!-Z٭hֹ3ZDS7hMNEMh.P1upG[P{jY˒-O6ye5VG6j;ơT Q):*. ӎ|;hFw5(73K?/hK߯Jhc3I҇ˤ.K-gK/lJOCH J Z9H_nחr|&RFR#RʦR()w&[ Ib.tt$6)l[m?)P;ttzL!2D2mYگVz,M<'; Z*։ʎmu6.0nA޸QֳG-UqR먪jۼTU/LQUr(U|Zԋ:m{Fi1"*(5'+b5Q<9s-6^ U@Mjk'\o}(a}i&ޒ咵 TR) _J*,ܶRzbE$\JQ۪9u=~itob#)kpucqW>8d6ۮ37ܮ>jDT~6Nk Po5 mpc${-:%U}$ZCBuOPtWo4U5EڢHۗ4HF<HknP;PUֳ1d>2&uԿE.z#M&2~\S.i%2x s6 #Wegګ&Ai:Y CgvoFI.kw y%w>7!qX7fc]K7U;q>n{[p^6036x;qW{n٩IcO' Bafe<{%]^@ A%D[ʜs 19gT%PDPH 9AEA;͜Ν{쵞]]]]T; VCPv'w<(J5P{:(LM"SPo=~2P<IWiPsJʡd>(E/~ $,g9PefqJSOB(30~Pϔh.(VBb(2 B^A-lFBW >nG݇APp/j݀P(qP|>⟖PLJ^: {( eAٝ(9 <$TClQPpT]9砲t@T5PUPq3TB+T sUO jS+# *B .|/G@(W e!lS(J%n'M5á/kUPr(g@_ VȻS$W }Oȹr&my,@^#pW kAC 2.O%[!$d>jH/ti/j+\HhAz,PJ!*dơPZ cd̜l @ƪad\  #?dz!Ӽ29u(rFzuܤ}S Q2^6@wq$AYNwH{j ig p̀Gza?_^ 2El*5R| |@"3xIV 2$j4@¹>>qR6|3hՒ">[C0˻ qFC.3BM-o}=1 K Dv25?ۆM6']Ro-7ۡVvt) f(Px[]osS(-7uBT#D|@K w2Zα^o;#FQg=~jv?v!~@4: tCI Z `*q0>[ϑ~-W!voqoMP\1yw}2va ?oSwbc &0LH+!jD!c+Deu.n=!ꐄ{ƕ6~!zYޜ(W1!FmE7b&a<xXmTwvwvm'W02=l!p<79Ĥ"?<= qe"0;C`+asQG#i= z dHs6BbrH0&!AWH{歐.\ t0$5Ca^:){8$A3y]nV,]%1ùG}H}R/TvMUecìBܰ(̼& @J7?)RRxU;*Iy0K!H4!${h4ꎐƙI˄x_یʴ!fq:I*g$׀!2xuX'yiH/:䳱ПO>s}ryMR!ՁUow9[1/RB*c|:!5f Bj!"!}<k~Mat2-n/} 3dAŐyds{q}8%Yy?(,y8pueŐ9CE۸=^7p{-XY!kmp0dgJ+Wd)|Re@^P0q\\;wś+(p2@uP9TvPm ꓫ:utTPjީAM]+(AAM:ItPsj&BK;յ{:#T'=)ՏJ>T'`8y'TU{j$TY*YmP T0islقCP S#eFM@Mh(My̎ÅRh,QF}fm_g;× ~D9R7@m1?WjxcT/ |ؘs0+l.ρdAQ$(2?QaYi5乮 I-olG@斛RR}3}P )q!e*$WyCN<'}s[C i HbL!I!$ƭDϐpև?;IrQ8[,y HD'(HyWwp]:$fM$}yyb݃9I Ԡ,p_o¯2!yyH>c$!q 3?-7 R8׮72¹쇻|K;c>rE\"!砉/ ᷽8 ՄD%9;m;|+$EH'l} o8W%CrRVNϛڧRw@HMYiGfCH6tXHң 1@F~`L̯ K[8nY+m+l.af6(݂/ğ+16w?CB/-8Á+o !hH[Ҕ7z8ޗ)2yn>,{GfJ 1ݐ0?#X7>>#YرQ9YY!>=!u3$6~f\pMp3P%x$HCѐҎBzyvM3!dl r Btgi/} /E71?s=yCބZ/ȓ ߚwN)W!7moȝ re2aN +B_pVչd܁u1 ',̋w2 42~͝+vBvyg9W,zw,"Y9 (ȉ9 Wo&-ތޛ}u5Bξ'㸛?1/潐A;@%kL~!p??>zCur[ՂM3_CO~0Lx7Y_wn =%'ek$~=Nç »Vr|0sUxWz ]}>A~eȤCI>fϩOwP(s {As(| {_ѱPrb {(vP Ȝĝ_ ǂ4:K :+Xʏ3syΝ_rOP9*@eT)4]a.ⅳ|Q3ܪP;j/τ:P7x0 {ϡ.7Z}* ɂs>u |ϱ+E@}P߿GA, O ,7eаk'4je|,5/~s |jG1e|?d?χo@R=hoAsKy͍H-%.Z6pK}R kE=Fu#QHE1+4cɐd>Fu(#ȈlbDKN0]Όr# `DY ҖFJ#6}LfDQF@FdʈQWd2#{|H>xH޺w߸3# Fi#꾈Ǖ0Xˈ'9#j϶cgdDoĂ 8[pv3Y 6F2~*#y=\t.H3ivA*Ch Mr!AӜ7c7K.i&| G1obc3Z@e#T eq$G{Ah( BA{fNV.ϛ!Ňߓ2&FwiRª!C4Zmr!a|a»5;K/=}#D(66Ό9$<onv7'F5x$ţ:6޳^.!rG*(= !IQ"=+]"v)g E=D<2 Od!@0B_!4~ A^9'1<7OF%p\ ^x{Q=VWpc!a\kp\%.. /Lg\ס"۱iqcg54\}u&_ n㿁Un nۚB{᢭$\<.fmK^pi}\ }|pAT}Hp$š3HpG7#>u dʯw<2_eO uYmMU_Χ@>pˬ;}nlWa\ i#\]< Yn^kAy .,e^Yps%e>\=ޣqp*? yc4|v%p;Aw%_$Yp/T\ic? M#ߩKpۻ|spG8g.%|jOpn=WI p#0ܘ^oGb~MzoW?<w|xe/<-{GW_c]vY_]ah N+$҂Kpiۙ ?Ub{݋=sGܜփZQ >]Apm\ }b=p.LV)pwΦZ[p1굂 p3pY glyx8+^ԅs༊.3Å={p}\=vꚰ//a01ːWS \7 耋']级Y98~8Y)mC8qDw Gw`V8&ž3'l} 6uaTpK_߅E'aK1̞/IAalzn O_Owl0z:W$'t&78+]$y- %~i!~M|sQ۫;ⓛƊX ^]Z<3xĮbK{E@',%}5q)OY{q/^ċN N-vwE;}X;{XsJzXdۊJۗ]Ayb9Սvm2o拥njK}K#E޴HCE<>cXMzFl9cߙ.Όsa:3Lcn1eCy7LP#ѬAì 4eV-7MwY;-wK!a\WfE1./c..c'62U3UÙyDrSW0ߙ ̏.k LD2_`U}-1 (\ Qa_8 BQBwJ=MP&T0-/qFϱsN`dT? UUa \ƣa5eQ k `5C}\xV=5v$lOԤ|!Kj2*l0E#IG{opv1*xbkziJT]sՊTx=T3_nCT)j3>$TP79U2o_z3*BM;TQ*VQ; Au.|!Zh5]l飱۰Fo\QGu^[hb .<< %4c7ob4EC-}+4m]ICjڢNԖgP5Soԋ®dp=Ia[k41]}wh^ŨW:u/jUN\vzPhja0i)`? `UZfL6O.H {{,@XZO ju&=:Pn0~ r%v"h2#[QǛ?r*P6)osBy[ @.|[isoTJE%ss]RQ:]D9(;mڟXr^ rmu큲b*Pu7P,N@Ɂ(1j^/QP[2OE?PEN]h;X-F (.J_(a1ؾ3bmVFQ=( Bt^/}/+PK4?~AbGCQZ4 2GޞҕsxX-ANBX}XHy>̩*Abf5Ӻ3;cQnw?)iE矰1kc2tp;Eg,^gzN?79ɭR 7gK9ҩ%~kw6#ԛ]+8Jb~NukoȏOJdZd2ߜݤ"26 s\gÎ#ڐ7kGjͷR2'{׍WXmI>tDh&&h; MKd> e4nqa2P>31+cOF#Sh4=֠9>5 -kk_88?&_7y] w|II=922ǚė[y[w=7ߍC0z=7ߜ6ּ.oQ_a f~;yQPs xˋXf^^ jܹ? Wڅ T>:No6mܾ-/SP~]ޗGĮ(;/S>7yfp oWaEŬف2oRyPĚZ'C(k2a; xd#9_X>cR3:Kv*Q/r tu"8ĮWܿ%Y(ѻ3烘o`~p~i^i4M;|_ܛi)bd>:|n4MgdzXsLE ST`&Z1ߋQLYLa Sl6)t)ș^|;䝿,gLe֬a2.0'2_uyc &W{&^_&I|Igr'0I1EW#?D?rp>E"B25I]I+d3Y-pgLє\T SӮS(i.gRL~E(^|h7PsxgJ Õ8ڏf=E%靯Kh*ϣ *ml=wj4]6~Qp-'ن8=A6͖Gh'/P gLTDs#1 8ltnG Ǒ qI8z4/186:;qqNx'vIrpRx<NkVpJI:e6N}ЂV38Qm~g-Cqnv/Ut e}qQ>j;. fⲥ} :0qkt,*A.%nPSq\3Vntw"k8},@y[`K k0p io0|08>CZ`h`شR 4'LV/|&>5O/ >p!{_g]%o~/T@|k/Z@%|#=#;cd4o716R OĨg0pF;o1fQmwK໘~~|R0?ƅt\gPy&48 Lz<bLSǴfLwŒS0Safmì}mk0!Z.ܦw?OW0ǂM-Xʰhy,Vd,K`مX>d(VtNJXyWZq7k]a:X'9Yaj#s㑍F)~ꊍ71d/~?:=l|͖ܠ?c˲plsH2$N_"Ju$\IDʩ$ZDIZGTi9I+$v ɨO&ųI&\Rm]HjoЅo$ߒd wHq$EUF=o@ol )LF ~IBoF?R8TLR OJ㉍ϩNPGlLD:R RVt qOI+)jz0LF*I%NOv}H*i n%틾cI{,vH#qH܊ HzAZH\ZeOZS҄GI{f@Z:H],DI'>tH;:;ؒtG)*EzvtO*龺Ka9t.hSg4m5:'- ݄atz =hGs R:S_(SH4w!cHH~VX'^{fI";%0pk2bcge49 miaLz"Y!+yƤ=iWK38؏vOT ґ#\`CoSB:AV 7_f s ܸsc͍gHUK&;u5鮨.C)Y:+RƉRGIOvm"yDzv}skJ]OSKS"LQd 'CrȠbuRM3u[8 U w2(IF6 dm%cB2f,x{ 1/$;ORg{9P ESRzag%5ȚzEJRI"RIw3v>dj2La4tl𕆮΢DCy? mL*8YA}:ԉ_#KdG dمl%Mdrd3eͪzqP$8&7;l<"-lMXټ BU@+v =ulrȶ`%!d7&f%dIv/sɮ2u6g#}d ٿM9:UGx*oI&W"q<&'X` )!q"^xd['AsFwAo7i׼>]p/vGןnm-Yb-M#;!Bn#tFT ϗXTy~s dw^."%0K^@vɮ4\yw,&~#OB ?q&FKƐ؈3 ]#y<#0Y*=rNonglZ-y)z!= 0 Sof"x p/AvA6UlEg ҳHxquziXsH*sv~,:p)WW/}{ίr=r}qm?drm\.re )7+U n+ؒ́kϵٙ+=qy v~~q _HUsm͵ ~ُِ{`CnL9;r6.52B?/ >ua9>Nk6m} q ѕ!hM>A#u;iHCojHV =Iԯ!4d]( e?YGd0Y!d׃,M& G4LHG`Q1 zCܤA}&WM4+c PQHͦҡ?ڃU|x,2l@fLlvQ@}']{7Liv>X4}-.@}riS 6˄e)q)6M;M1( [_+Mj}l+ƀ FC; noj_bV㗱.968Xu֛ϱ},{rXw*z8N ƚFUUĚ1+:VjcʧV\MKUX)+aқX^ѮXhzX4,S)ar(z&ױdc,~ŐE+go`Ř0w ̹[aJ f)b&`aڒ,FKLa/n oltO_Lifb ]0t&c&L)o`divN”/R<St&` ]Lʝ[)1Ez\bu1+fĬ{1=suC0ϧ+~}?vÂ'X$b4,ypQ8k݋n`EB>VUzdAOy#t06ð2O=Fzalh'VUʠ^X#+Ŋ'ۅqcW>ɖ鍕I VzŠwj|",r>cWc}[9`ɝ,h|>Dz?`9|`?Ǐ7c|4Xc118}n㇕0nƊ2˜ӹsv`t:F1K>FIf: _/*>_fk4$>U'!Na8>CfYa: JRǠ En`=ǎg|\PXo u1ҏ;q ֬׭a@x /C[kS`;9'KU'X$vF{}Ln vlsW/el߿rQ^vW/1W"]1+q6W_++^9?6'_w٨MN[rڮW?mrzk?W%[y G_mcwOC!^cτfLןmJrڮxE69ٲWnW\WZmJ_%g  mhCІ6 mhCІ6 mhCІ6 mhCІ6 mú6 mhCІ6 m_,$-]XOY\Ȋ ‰iy,N޳X vZEgӒF(vẐm1ޢ,z, vZR3NXXskY;NbB45ki&+g&+g+gFtO4Vƴb7X:MaOfu2;DV l?dzki,hbQKN#Fm0; gc+m0b'`ˊYYXN6C#NVb'xibs.?RMQ+Dnj!&nja2l6 Üwlcana sXEEQVJE(Eqy=y;?{; ՎϞ/Okx~/>mO >8ß#<=kqY$;U(m,wH]gY.q{2q&*A QRĽ9^.{-ٷ4A܋{>ۋ;>Y?̺qs$xytGwDqP 㼁| ~qD)ּY/E qwC+2!c;ggt >:;0@#s:^I(tU肌] /@{2x3 ܂`x=%%KǑUr;2 :hD=+@&}Ytt_W9UlY!;嬾wPPt 98g`t9Cy(!~ Eht03s ,exΘ}fόmDOf{n}Gg!zY™JdAuj#>I7wq>>{qhDϧseSbYߣu+$#$j!% Qɏ>wȘHEn3A^9|$9R_FG+,f&GЍ 3Jw*:W5grQ_BgLDO{Qͨj1AF}(P^]Qk8>s0tj:"tCKx|}7~_]^ر' z.4?kzcw]>vN|{>o kkQYt 4ش?oՃQ2ՆVCgUϷzpX>\b\)cCr bqs#E>ⴐ~Cc 9h%1م| YUL9283Fb9W9IYzns#|܁m|M7 *eo :$qU!*6mMI,rqN_+l_a2/v<- _" L?%4M5'ٹJW{3}kf<] 8u\ q٠B5gq><$6HtR]:/  8waq`%2.ױGvGXl=ހ\yx3ڭFot=vW!=o|@obC|f4֕@mǮvxH\ il>q9>FL|zrbלwqf{rU\?Uй? F7w.W_k|+5Zy.1q8u t}6`mCb)b u)q453}hߚXlClz߉ jnY־_ZʌZ!% e"cCXNAd{,|EW kckGN"MA5Z _fhYeg.hy5 ٟL>S*Ck}|t ,.fRh-g fCkkWv e-(Xܳs7#C>9h2AN؉ݍ {>`m9b3{j輤ꧏ޻v3CW=irGq?F2)]s/+7Y /^Q ~"]= ž_L;uAuURKQn7&775>M|H9z՜3ZP[RC6j6kc;hᲪ T= 6wnݡj^_^S;'G<՛bգ@/G?@AFƺe0dr(<]' 簤9iC9CŐL"-oPuŇϽ4_io̡|/2ce7 _AZ5?mzk/4g]@US6N1Y5O ?FpNH/W>xB%n㫿ۿnע^?Hrx O}qF@~=[>P>o V}[jV==UaћC6UBn}5;3 -!^3tij'3WW9l Cу)$P)t,)/@-4ZA9t&cCb9꬯v7Mj5jя'a_u7>ԣc|w:=IQPW 9Omʣ䆪#^aP\NzFZmԭ8o,5- #~E\a%>jijmWhtwxSO>foLOP3?wUq8q^ ΟnJKq^煽⬸,/bi8Cֿ+y,[G-gq8Έs_8wqn+`qn,gn8s8oe{q./h,Bq'=W8 4_g|Mm#✐%ΘpqFugd8Gv8 嬰: g_h^M2t\Kێ}m"ӑl\&Ά[8g]Q8kX:/^^ǝXqܪHq\+Ǐ8.|8Gy-ql5qN{wCoі^qqTsı8-GNqdgcyuq,NB?qdxđzKs,H*|9 _3k|M_Qy\#{cOCc`8Bqn#|qNjݙ=ӎ=mӒ=ϲ{Ic8@6tbz\mou"_ b.["~Lb/?%OC~NgZb7]Ǫhؽw^{ K+b'mľ%JŞ!3bφb_L =#Si>p×,_S1 1c1 #TaZ -'O=wFhB=4s)b9A14F=hUXouzXX~-oUX{zXOb}X߮&V-Hz0Pٿ;ź-LSĺaXײUXWu-. &B~;NOd (G3b ~h}wX#֠8戵}XU5#%|#c\b滛71/=\XG|X̛ZڋyuCż߇,Ǧ"D|vMJ6{5'(O]gc.59d /"|~M3|ެ._`SWZ9v3s>OO͈bܚmY!P̝bSL1Yu27+b>rX-8{X<N㻷.>|H| ߟkx'?P~'j5J0Qr\=rUCrN3Q*&#tx 5|QOQ?BYSS+<_Ty?@O0/GgIpU0Jl鳚[ Vw6Il/ [PغeW{^QG(wM'soMHo7~UU_lĖ 9TBw{wӯ7;M/}^ q8 u=yh\:-/mk>Smg[÷OL؃{@R|}yi>oV;2 ;Yw 3Pl ؓl4&<s9-jN8Ҙ2ߖ1#f3_唈#*89 լXļU wG Ͼ٧]VvM ̬z u5f#ռ[83<7`nݘٽtstsf[gll}Jp^WߍG38s0>&-c^g=9psO|>>D1K&/*EqfAw tĹ"EJd\U,Μq):n68ęM~ B}+C|8[G{ۼw˓A,*9|7M56?z{qs,jUj%N5qW=ƉG\Uqb}Xqup_#Eqo#T^qWD"+b 5:S5_\i%_JOz\\7fٖ%A?࿨D\j780O\S}bE.DR!ru~S$(߽A;˚~$X܏q78)Իgݢ[q/WwY;*]~wD'Jw{!|>GWin;沸'{R#=g%OC"gsn {rŝL-JR]eA++n{{[ | ][Q?S݇[&nTwI8˚UqӫOG!ƻ~ga꾇{ yWt.#wuo?@V? dq~:wB_߹TIx#ux_#hx;#ǻ{$ޓXdxqSi/uC/|7?<[<͡⪺kҊZWTw^{C=u@w?w!{+H<'Ge?ރPw}8^D+G}΄~E1츺艰QH֍F1Ꞇ~_CřѬP,W7oݸ ū=%@0gx]qףq#ʸǞ=\aVt|Ȟ+ϸqoX3-{1f{GO'|V}=2ջ:\Nf9tP#& w m51t Sf/rػN>HLU*9*~S wz\ab{ ;=.-GǡNS515y+1_(QޅGb}(|xF.N~Yl2<>~sSCء0*77OYⵥzG|uTTt_wS_ PX\Q~~Ovu) |FݫX9)'<{>5\m%#~\"Nc_y ΜLb,r".,x˂b|o1p[ Ⱥ38{|rE þZB3oD*4xdXdZ|Ɛ7\`qXeĮ?378wy'sӱS:qnLůR9s.dnue;InB;xOwؑ/6g+j Xfd3#1M5{͈P-Oӑo~3 ӧ"Txc%7{ug\G_wyq y N͗'" Lf^A @8p`< m͗^BrKmlK{4_`y[eyhp@ͯ R͗8Go |voQ^y!ͷYLȷ\K?|^oy/V ohבM͗jO8V5yqͷW=4A5_3i}a.r{974z>YUm vސnoNK>; {~4Rߣn׏Usqn!+]z[YiΙ.zh*|t%dfb3N'|| PM L|oLE\曈&V|}~ sA 'r^Ag:aFl<*yG>ا7腟^=UO|]ل͂//sK%lԃunnw7jً"ͺb@P: ]uBGr 9#:@=@yyӞXkԶUms5zoZV9Hײ|-{ 9g5m3 gwsn쿻vBSBhD;VwzqG#ͻ + yA1 7g[u ^"V> [<'%u06r`-| n>fw ૛𺹊=M mMۄ]6kӦnd/{o?kOg|ao1h&) شlMmK )Ӆo!~[;l/1 z&N֏-w۰6׶%Tv,jZm _3aEbs' q/];@oy`~ /{?—}='~r} @}I>}3LJCbwH0}Ͻdg#4b(GuX+! g VJJmbmt| Y!1y=nww?%/.>p=]Bpmߒ}~@`%)r)|441pׁȧ<G>g3r9ushC)'}A|>{z?=V+o?~E}ע@z|}x/r77䐋䓋Elx ]Ke佼 [d|2~ߑ?ju{y ?/~8PCj՟}zFkw 森3~3~r?"?s<~\rq{? ~-5L6PG~#;96OWww<]׻?Q'==3V0T׬ v1\{5g.~x~ 3OV?N}CUW}u f5}d=ϵ/{F033?μ8̭OtOз%w_pnk՚ jڠ&s[@ݖ~۪݃fA{=^~ Ca:2v|.٫6, LЙ3:ccv [t_b~"{|%`xq31vc^`;w_fM=KM/A𗗙4?9I&xs'>z3)6$t탿J@W8BRy5%CyՌ_9 0 `<o B303ƮCkv7i( g8> } 9ysjϩߩ_טWGQ/7{Ϣ1a,{QAThfq8CNXtKO]~|It'$w*T5}Md:3t|#?Ig3M&| _ﲜa(@ڑN\9_b٩3'gB7~E_oK3k&ϳY,lX`D?'ID%!C21 d k/=g6 W yJg_R2pGbϹc}7{J~L%_|0mRLiK;ʴ=+tr]:ȘN#<C摏-Q2.w>cs~rg b9}d,9(6߀.2.|u{g7bO5> >X3ҏ>͔>[:H#Q*_K%Sۢ[\tdBYCؽljomΏo'0W#'b8u`YwoМI z{pSw 715K>z/@oli'Gٱ}ذ- VcEVlnA?I*Ľ|oBmQ18zO2 T@ާ4ahSSSrdbz2=I!*o-DhL/kBGn<1KOK %"CY(XǡqƸ8#ahb,M\EC?>G} QzDQ"7D+ƀPտ0cMg~F5{MGSW߂ɗѬFVE88j8byd!'1b7 Klӈl6q;aĺg_q=8zIIuZLF&&Ǧt0M=@I 'PofKHP|yĈݚљZ+4|F=vrZ mqbS'qd č|nĩ9x'=E"5s\9=&ƻ=lǹ4iiԻ{Xϩ{~OO~DL= g!B""C,F%/,# |n:z=JXENX] pFNO.J/~~}a.:XOXlil$m7yW6 ^\@Nގ?@o;عxڅntmͷދ]a~tvX"I&A| y~:8΋ū4[g09K˽:[>l#԰hĊ:> GGӣQx?%%>JJ_(A%7)@)qTJ(ERd-)%WRVʞRx.%J_ϸ:-rbiW)u#`(KQ|䆣Gq?Gh="n5lt=G}߇Oz ًo{a-} ݼ/#C1_Ob=D8|uzs y7˛EeQ=E?}KKAw{Vz]Ƚ z( ;)I.؉$v? vzi=>AOuo l V1z**`--V6C{&&tyFzvƻp:6_~Sw1u\rqnܣbZ|5ٜ_0՛ûmlܐs~^ua~3WPwCk9d78t;.E%rt-&_deQAgFuN[H-3#K&u~>lu"sPw1ҙtvTHogR\zStSs|q~4fȽzjY>=f/x4uDSDl*US|$Á>{[vxghuŊM ͷ f:10qO3Bܖ@4ΞF=xJ.cpl$IIqI35cw&P[&oo2{C1vjfYќQP͹c1c9R#Yy缶x~̸GԤ?6 ÏџS{kuy6] 0b6 ᷃@s r^w 'BC(B?9?:O]~P?h#_~<܏ٗڗ\՗/{YKjugc{#sff|֟ Pj_(sZ(0,<'y!#y1l Scg9UﲅCox_w`'? FBs䪿M;l8uӸvxg18cGD9fq^bUfޤꞏ;J2$dg9]a&קh%7uFRSTtJJ'IGIC4jvS]96_Go;o n}~KHRj= Gԙ9||g>v>!We/q盞'ȊF/O$dbLs&͸˙e~TX.pڪ.-h(~~ E J ****.W2\dUӯZ%CJZ u*+W24dhZPвM%CJJJ +B*B+*+"*"+*b+*+*ۿ**+*r+|  WPi%CJJ0?bl.JHPI(!3̘o5ugC&D!MhhB^rډE]zxߝ}]kfz~sᢔRJ)RJ)RJ)RJ)BCCCCCCC?-ehhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\ QZlWJ>Ǡ_Z| J)HHRJ)RJ)RJ)RJ)RJ)RϕRJ)RJ)RJ)RJ)/oVJ)RJHU0UJ| J)㵫` J)RJ)RJ)RJ)o퇔RJ[ ƠR{Ue[_?iQJ)RJ)RJ)RJ)v>#>O{֏xD AL `am/;E"u_8. ! 5L$b!=>hOȼ'6`F!T#[N *A`x-{r'!pd"B ~&Xu=1boM`yW_u G-'̬n^Wx3fC1M1ys8?I؋ &mOx; 0.7ܾrmZ'eܔ]d'"w`lqM3f[xGx'bMt+n#n=ۇ0KW x0N8Vi7iLq(3 '{ܸ ӇZcϺy͸/ū2 7v XFE:-Z>;Ek020s pLy!wgcMu,w\3NqL7cuNc.[==qFqw%a^n;c>u_iSqe8Sd-ahon+8)^7$pn}~2q_I9*㬁SN%W2ڸ_4~Ǵ(vX5b})3/n4Yx 盏pɔ{qL=5fCx07`߀I-D;`zsd6p^;AqSf7RD#y8fw`g/T>7 kKpdz=|汎u&Jx-ܷq6lyܪiO+t9R7礎Mr2p_~S]̢b1%/~;nfX6bu|ky5yRM1]ZIcƭIp~}q)%9eζp5w`3Eƽ7*y~#ޞxoT|xnYa=7BL;qXM=7 R7H|"ujYnz௘e=U^{8b758?y\aλߍL8%*l;h R]>jMosrf//8瞐ȸv_-ƙ~7%"L-0Vbǭ%^Ni ܎0c>O]r`]>T>Mw˟-fH~If\qژJ^OtLzn`9RcXR1VXc*y4R{Lƿ1O9L%P3kp&퓹  :ഔǻ]q:s%S^,f޹AE鍟J/Y.5|o`OoSp{GNկpwaժRe}y̐јNdMG`9췫a4v>kqyτ tK`~#wbv~mV^Y . dlq/^cR}~Hz6Sqe?sP}"<&~H@T姊%ȾWw, :m~P 1?O/S>L~\$k`ZEKܢ$ٻO.>n's x4yk3w(}2b鍿^>ԭi/hB# +%}B&6%0]Hm/vf<#xE ~Hѐ`ۆ XO0چUxV{xqܙce_-=VLi%}f;c=yS+܎@xH6wg#<ϏmzP[ WN|Bl&8w>wY+5G΂k4;,sfyq .$aU¿EbG'A(y[9+VKRum=>69ZbɞXtrM3[|QGB]rfY2u'X;c=L`>Nu5Guvs[}5pe=%V\cw&JlLy7F]=TG3Xn_yUr˓y4{aH1v^X$tY5d^AƊ_2 .djFo% (dʹ:3YȚ<&͚=,awGqfZO|`G΄=fJg{vaw6o){dz&y#dܳN);gO7yw,]oF^U״ v=]ZK 'v?pO sJyy;fv`%Tidv,Aak}vX|Z3]Ĵt^rsv";el:l+M> -=Xߎؓ%X$6#cKTYQKNd)+`Im+eĒXRǙ:_eٮ^gvN{1){G]lj8tyE]maF]/.bolog}V;bc[ȖiUl}-פ%GZlϖselyo[zXEl1e[,Fl~[曝k~}{6/f=ŋ9q۱7mSj]6-4>q/k~? u.r6Z7t`Li.Je̦Yw fmS6 bSX6I8̦ $/M>lZoneT'p{ailrȒM`=g56MŦtF6xM2;=& th< }&n\6qqbĢ+g@CP6RalrM.gS36oϦ 669D둀kǦ=av $|&ؤe6q:l,NfiGBC6{ZeS;6bxCyŦٝ=Kl֠Φ yW 6M/.l#q6kΦݥlMe]4_uc̟h6Mwb}lVˆMn]fӂS{S,-p96`}oΦ^Al"٬Ys6~Ct^$%2fDZi6]:M1&9l+A\ʋM;?d|W6iӞM a㓿ؤezl'ML&ɥyl| bkR=66g;lUXq1`lx&Ű6#tc"glԨ, l8` al! 맰lP՗ZLbe)6d>l8-^d;9v g#`6rˆ 0rXAx685 A6} aYlPăc nSgZQl; Wa%l՛ CaY? |'8 VAc ^bCl`՞ fe X\84Y'pgl&bCl`֌ ^x @p .͆#lئ 3X>lSaCl0b6#2`Cg6\"7_mAV6xҊ Ğr}6|'%~Ć:b2nX? gXA"†alpBj 6`; ! YbЧdeklZGmd}6e4WL/blԋ+݇O!h䱁$'w{zYq_z[~77Ҁm`ͣX|e~J֛bFH؉ղKV߅BUYV{h%-f [Y-TfՋX-qU =ֳ(`V}VNmȪ'm :UU-oZԄU\V=U[`UTV=Ǫ>rFa[Y̪YeAVoʪKYYmV|ǪYj"+gxOV)b ViUF`+XVc*oX9'+y*jWY#Vl*'ʀwҵUe!B̭^CVЈU|YUX*zjZwVyULVmo*۱ڷ*k'FCVa+{F5BmYaVYҟU64cv2m 69ʪl?Vy<^ dYevf⌎*cbsU7!OƬRͪfYenVѼ*I)Jk_%he0k$W +*z +8Jw>A*+%cXl+ya_ XI>YiCV=;!alp/ wp.+gWYX)7;if+q}YNvDRҜ|çBB/akmV54Y+hJe Y+i[wa]tXȫT)M~; :ԭJG/njV;_JYi8s -~|6t~ !(bV$VzxEئ1+cncYikV%Mp{8n6n-lVm'}a۰t-8ymk]El7~w{:aN=alƲ71۾`Iܾk:#-V"vWlٮE9}wl=9E_Xr}#}9#;K6cIKfIt<ќqqcg+&wKx^=vdg{4ԋp1CCKg3YrϝWȒEwz(t;X-LK1=@bT %bGOɹ9seL=;b1Z-gF7 ɌXr7h&hsH-Z{?lK2obtIv0|);x f2d3a$ gɰ,4qГ.=%sY$e!IL{Y2ˈҜ%lӗwb:,!oL}0 y?T!e&mKg1:_bSUFg!WLk3bZo4ec8ɴP}r{O&c<;Mm=ر,7yi<ӟw%ة1vZ{fy0y;'䞍͹gVNvsObf/6gv{f!ٹv~]*[mvٓ񇸗cjړ#'ˈy I8^Y+({]k^9{.T{bl>nŜwMd~?Y>Oח㿄}jo7l+^qL/Ľ< ܇{_'p7M>{+Wr{s}z>+&pBs g|f]~y/y,' qH;=ߖ0;dN-z'5IG yǷ$U⁙9pE]Srrj-ŒSyy`ShOC 6oAIl,_AѷP EqdzdA X(>E( (%uOm-\~(O(n%{ Gv)Jm  Fqn*{PPQrv->,@I(iEQsD=pA @QSCk:vAqPCYA~0rE z d[C^ dٍ쇧;2?#r EV7rGIdzF:^>m!۬;"}9dwDWX"d22[ BF>Șl1H9Ț1 7##rj!c2 A@8dG=dHq2~)'Z!=y#ՆTcfRg#w RG6"E2c()A[R Edx-z*2I6R&#& )χ ! w# R=}4 ɱ]roF"m>ArӖHi+ 9ۺ =K o u3]<W!w?$_XS)G }t!> y.ULB.$.CzHd_Vv_{"=^i1HGOf!c~ikW#yK?"RB30C/폔@e$+tAZL3G@i"M# i<-3Hv+rs5RvB9H(SZCH䐉H!ezڿ8)} < i"k&*!<߄/dHtMHi)H?5@Jk'wk)ʑv>OaȘ%t(|zH9f#%J{2ZBHk H5Y_R!5F[~i-|RDZOw#u9 BfǻH-tDꛙԢH|=Krq"RS&"ÿ!RǝBE-oz "F(!U%ӑi3~#ΌCz>d5AZ7c̋.H[Rd^k4Ua.җvB&6qs&ȼi/"dMFz+@ H'br d71*AFХ^_2v.lBڥȊ܎R\DM Iyǿ k&i;"T[:THjLOȚ H덑ޭ/Қyp(2IqdηGH.rJNdXFȴ1~ف%Z,섬:NM:>2^5BƄBE>, 2\Q{ R[f#тmd.Cf_Ud32Is;>̉ei5,k/ IBcH#RGU[&"d2#;, Cl#y'㓐Hvy. YV^*hUoH/z.Y#iUR~HKw~ia/Erd4a"WB)edy,CF/j"d5RAznsd_Eg;7 d#sT-V kK_FV?NeǐkxoTHdE!]Ԣ{PdCY}l dt|GXA^ڹD1Z.$!MCԳHo 鍵U'S68[,+ 6C}\x-"-3r)z֌.jG1l+(:O!kAd؅tau=]ΔȞ9q>B2W5[wFs? CN#Eֵq]o roàaimy罐]Ȼ69zAב.l$9O99 &횇9 +CD/.71r{ K3 n< Eя-M EUcZ/ZaФt 9 G 1jBWTAw0 5AoGQ >yU^_yz!w]Aџ{z (Š[kh߭Ġ)-xU\kr_GV}G)f 4C\CޮOQƐv]1@Yo??C (Šo; d:[^cȨ( !?1 a 50>Aկ(pР(PkWQ<!*P-aH(؉B 9;0 9B(CN;EvzETw΢j (`n[wuqx!n7E_-+ŬO?) JWP.(XI}1 'o|yb6 ϊ[ A^P7Eȫ}bCs棑7[#{do>CB]d><*ٍ6—#)dEf~)"X)|;'z "0yMX!["د#!ctMGZ(d^YRUԢHSHH9tBA JtӛHOL}iF͈:q⶘yعHX'so=s,x1]o!["漀Gc8_zֈcqQň=`%*ދغ sIGt ĜLCሬZ7⏈ӈz7/gy#"#LC!s+.CqK TD{E CЭ a*aЇsa#,# 6#t6";BnO@? DD$`#0B@g[#d1B.F'_o9= {0 A]-B xk C""AуjAЏгF n__^<]s>Fsoޣ;.|o"@;]g/s&s{v v]KrT^(9Obx5>~ Tw18wq\Wۇzw< z\&uopKUppsIK&ռn/27Nív$zE6Kzp f^Ki0z7"=-q^pJ/p=Y_pxU Ǫ*8+1s pzA/b N-p:{<'ԣ?8(67df=mln<|6W ]0P;`l_Y ;tG<[nSm3w~'8N5ܘSnN$KaW%ZF} ]a l U a;)=c|^}IsU=9z Xn`h(ܫ 1/f=lܠ X[w6Volv,[3(73Xii'_5&zP 6nª?zlbaj nL`S Vac3"ZeկaV Ѕ~l6]{X?`5 "a~all~պmG\XK.ԇU g `6l̔ޭZ}0 RO`Vؘr*XI+kͅDXv=`sIؚgòK\ X `*hv%w. XW[X]l 0⅛X bX4+iX|h >1Uȶa `OX׭W0/zB,݇d&\ocsXR/>òUcXh -X B`y E/ga fRS2v>,ζtrՁUvXսo"Ssc/tyũN0W+FTůa&,^,V=X̪EZVn)|5փ`1>  E s}t{˾"4]{)tAO`q ߟΰ=́h s`1z3?AC0Z`>Wl'lũ[§.R/ݏ% [|e@Kt6tJ!>֭ ߹VQ'Xnw: ˯b]wRŝەZP7 %A}m~ghOְۭ 6'Ё3tkn`~B*t1*?ˀ[ݵK4tm+pzCavn0=wDיa'[0KX.gC;M:]^5KLti&Çl~%:VtvLk̂dWj ԅҠ&0fKdEV0ɳaZF+^L^(/:Uhl80jF`e fW`4;L>xjj!0yg#t¤\`8 &a Ǚäy ማ0z |ѫX0 7`a4f( Ɵѥ0^5g 0:묠;:PεasrE28hcU áw0Tu?A> N*0lzKB^ ]ނ#L8="T6^xNLڍ?)toApӃ-̀Ξoз}t_?9t[nz^Ngm=оNtΓm&z3{K$Cm诿Gau ͣ;t$CHgByCt\V ޅnб(`;oξJkA)ts :-BkZ{B Ay{|3=:נ :o@;0Ag hY?Nvh}I62!Z1^埡Uw4MtA= tdCˠ:nQB}^A31E@WKhR]Wӹt-@?vkum_k?^ =̀h:;( t{}vй ! 8 e۠W9taw $|S:C>v+܃^ߴvqtO-|x:RNVwо AV@'{'4ss@7n ;@;4[CY'hJ=tNwVh4vX_%tsw# mծžb2/ԡ3ZZZtx/1i1ZO?@ihh@K}t,VQ h?'NvTt~Z׷f(h~IZAsV$ڻCg|hp,{v4,.9߅Bh B'jЎwy-O'h{8hN_@R~@3$w)Z-dŞв{7C*Wu9ނ/ߠs gMg 4}ҡu9:#jCB'h^#lZuѹ=N 2tFݡd4?A+mtvc+tmObV _]k {BFҡ$F*hqf}Wؒ $A+ehЇVfh;1]R JЧ5<$bbXA~*4-2z5 {5b!tn{NQpjpnplr8]'_xb T8 Ǻ#=އShurCl U1 . ᴡ1.Y<[eokAOlXC6¹s#kSSk\nI'8O{LWwn=Y8m W}p ]+=ue} 3.7mۈ^gqNMm\WSoȇL> ٔ}%xkA$JS5<^\uRZap^K~x8S BM>z텧N4|[jύ7cyޏ3! |Fl΀J<_o+G9 9|J_O^b}Tx (Sy: ;+xyb{Ob7xYmφhY_Q.+NjM^<3A8^Br~k!oEgxu租| vz_G53͑~"?VYI[Z 3""O=A@6Cp) /F-A(i"hAZE1EpYuO,(G gKGXZBZF0mEذwg+< ςj9Y?!#L>rH D WCTp7G?>Ѫ+9aATD x+D+@و=(È9ȧΈrHFHDڊ-[UP77=z bGBQ ͉HxS+>!~ZmnJ)BbH}٠aKw&7:$[Hp@ :R!lfA{$m@.H2HG$S_!m$O4GH?j]4.=@ddFvBgdd@ܹ}.srμ@vZy z àz1!rRaGGNDs V-ƐiT6!_aPx7ڇߘ!NPCG̯((( OlQ ŮbhCQ(-.B#a?"q(%P3J\C0/a]gaJ®`X` 8%ư.Q6}/J]0A VaSbGYB ×CQC{]1bMzAi:譄S~(>#~ƈ(1 ň0e0V_\;eVcį9eVaD&}e{aDi;Q@#?A ( #t0ҫ1|V _ewPZa1(]0K. G>G!%@i~#^t#6c!FX  mPs#Tb-8ewadF"4DhʞlGٖB7(EY0r-FXFlL>F$cDmFސVU~b$b&F\կ#V|G&>*z!bTȾcw3} ~>VP%p2G$B/`1֋sŸTUB5b\kgżI̋\&Ub,21LK5O2ռ(!Z|Ge΅qĈH#]j9e'F gIAe;D]ͫL2X9/e#PfCoٙ?p=O1ּeg]ee29~h6U&W6By`77YzF\'/>|ddp~U5ռ)[]Ϫۿ Wnz\L2A2;!u5LU51&d(9T{DA @\?`/22v?#ⲷfr[T\7a2Z~9DF'Lv.O(R{(&Hv_FZ5z0P[&g8YΨ[-C >Dfj(mB#UFu^Ȫ)׫l?ew.# 9-y<~'<*\K>.9O  U㉑+PF'JTkxUM}Ƕ<'sS \Ȫ/k2yu'Lv.P/J^ &ʾ#ҮY5׿f2hYD?/U_̆rQY:C?Z#NƯ}bjog"d>#Oߵżeez^}B,D΄K"]ed5Pnhq mZ3-9BV#g x(ZlDV=ds w2Cez(' +;#Q?)YrY_|?Ed#?/I^_y&A/`7PA}e0}eed>2dtt[}L6V8_F3^+m_[F +K=_!W_߂?r'Ɵ&E$xj2dCnZ\~~l'󯄂?#ZvYyFl%#zM6p+SP3r$Q5LZ_?_G2XlU5#K~O?^&ϟQ#oZUd_džѲ} 2}jrn?H}c J#QF~Ǟq2|1 |'*-]""=IWWD )o Sd02> jl%#_.kb jrC,d'J- Ua q&j>?DV"j9O %KNGbM=9Ԇ8 ׈?y {`'[;A g>rNr"IHUMiSopjM \jU㊔=+/$oE75=\A <( +QPC |TKB(髠=KO jǏklp:UT{Sy c忺QЃ<|ٞ;XA5gBφ~lطTA(޽L&EQ# j(' 8<Q>H~.\N| $y2FS![R#d%ExoXPCOۢ` jpj_YWG-QU5>/  xQЗ"*EuUo/HYG)m_zQ5>#u&֠?_vAUC^N>`鿳" EFWrP /g̿Ӌ*/{.7QZ׿-GVq])ga/՜9?D)/a'TսӊV+G{{b^WD*QX;Լ+ybΕjqg--QryNy\  9믝jSmQGgy $'-wwPU~}~n/ոArӧGe|VSoI<~R/{|¨>މ=,orc j{wtU]$@Krzq&7\5g j_~dzZQ%NEy'jl.%?pV~NO͘ɇf\տ}LȪh}y-ב"L31 4~LY2>gV7._ kŷп`GW_p(Ʋ"=,GP)B__%9>9p=VJPU3 h+CM/R&י UU*[o>#jsٓn,ov uK{z|ⷎ jb[W,7yI&%q(;>5qB<ɾ 2έ@_h?yO[R =G~yOVUkj㔯'#55=o$3OW}_BE)r#dp>=Pn߻BxAGoXP=O)߻BH/W~>m}ªj3"e1&-)_SOn9[PSǗƿ3QX%y+{y*ޣ>,Axo=U/D{Tަμr{Z\"XW.϶./>X>wwol8|Sww(EyimY+mJhJ9m+WPݫ)*+-h#'QhyZgO[&m|.U<9]it:Z˜B/wAf]r)7n>8 rzc X~җ2_mGΦ7{չ;t6]8N_HOtwӥͪtщ_ENGfy ]Cu3 ’}iMj=MOm4p3v&T!Ro={oin?Z8%w hO,=gy2*ͣ}etr(KgqT<4Җɑr/GkG3*hBK&Kh43MJшX>?|NEPQ2 kzJQ\k*n.R{B[uwi nר9h'&[Hş7/4-:zJaic?&lCvi*9E.M+zVVѴaե5uZʜHZ -ڵX“shAZdђFid7ͼGsoy[ha6-qFwU_КaƴrRZ X2&ڞhRʱkLSW=O4z m'K%} HJ:R}/h4^jN~fҔ#hx4rS 4v@yo% ~6_khdM=Hb>Њi=̙ȥ/ Chie?ן['GGdū_L<,^mw1F0)9zL!]рpy<vO}Y;S1Fb%RuTF=գ5m*_֔+e/[D3Q.J|QI  (kY?N6%p̀zB#ǓŒ9~!S_ɠd/D:4&yʪӄh46֔Jⷽ(ʆҋgQʛ/Bܣջe@y)[=*iאFK.а)3:ۦqdo$y|\l4oB>90kz0kOg[ y:Geq*ʝ(A󠰂w~:!( ŇԡDGKJ#YCw@ѻRlݫKF')rNhvb覑yk EOI[?1}؜)SD jR|C($*?JށEMXOWN~M\O)*)e[ʼLi;PrGt PIEHnLJ7Q_m,E8=M(wg8z)` zLT(!e@~fԐ >)%w4ݺ?%9Pu =HuPA33J-YH:UYQL45\ ]c;܋",=7c^?۠dwmQԳz,"3M"Ӌlk'݃e$܀>&WH̛\*q(-EM!؉ą,l.mzhGa r]!lnэdSoY[MJ1b7&:"ӹ_9I=F-ZRzxJ4HQƆ4WHKZ3V &I1iWądVCcHr2y_Egkh /E߉\%rJҞ4PC ʮN({]J*O 7E#QF[#Hn]=ca̮ª'vӪ8 .ǝspo}-^'%Vlvĸq(8cq31oI!R8^T_Κ [`؜p[Nǰx5Ŏ&7l+TƖ83<`I2sySoyc༆ p&37Q-?4ܻrcej?g黑]DJQޅyzgSǩ%H z'n9EHhM<ڒRټ42~'Qkʺy.];)"rWD}dd3ropB(B2ͨCYR@D?)yKlnNdTB&ȴ+2: @76nsP-񛩞-^xPԡ5F-©h]jSdL;_n2RDZaYJZMsyrZ~EJI-2ٙOZ+Q˨*K7:ŦTg Sj2:GEj4jsԤ,5ʡơڤ.g]%Bg3*nHI{N_AZbH&ԣNr5JWR}8ŽH>߀Yb(s48t'Gc4i!r%c'iմyfC;`4[NOVЕ^tf~oF _z s^-B/vMtnζJ5:tp]}B˾;olGOѫޫ'z&/x@73u zq)=ZNGcSNM-:У%܎ΦZtu ] 'Ut'1gUA;^.`]c>N˥1/C:U=ͷi쑴:a{;4Z݄̥҂ 5QhHզ1L| M&CwӜi݉0Nb2kBDmf.Iktec,m8HbVޠ&tewM7vUK _ t1Ԃ.EntѠ)]J2gtx:pXH7TهmREM{P>;/!մs8`J;V'hWO:x 3>Sp:JtSUt ާC; tJN|Ct# b:N%!tՖ]@'ƜuFљt7:3q:*s۟ҥDj߆n.8Mwt;~t{l{;]^Ig?3Чsoٵ)WoDg=SgmHz>4Nsg9/ti%]y5;@WЕKDWΡiS=Nj)t#RoSep:FŚtR=EGp}t:4MNRtI4]ЙJ':Q֙kұt8#MϡCtOK:`ONwʩWM1οEΡ ĝnQKq :%΄/ޅt!:^ؖNtS<{XQt쩐P:=TN3'TN\9B3Vt=qu1ϱ'KV"}j>6B <\ˊ>O8<֖ޫ7Ry"={M,7]^A/=XFF~{W}5z0=ݖҽts =\qLB̥O[Wz/z9!^"zyދ^B/Ыaumz11=}۝X=KBz2޸7wћ;~b==(z2d=5-y,n=^@M Y+z^Mi;, =oK/NzQ~A]Om-Wl>?B_:ЧC裶9}O7N\z{vx>iF,JQs6cz8^oA/3˒aB/z>Ow_-Wђ^,&eNJ3ճr,8IoY"=Y+cAvu=FY=y^ӫuAOs>R'lHo:ѰI+z9CIkkM/W%ҫMm.zm|ht9Ut\*gGێ́h]Z20Ց}ΤIuiwg<>aSVd8E:/S$׽ 4ON'-+כG]?P%+>~Axd!-t{F򚹊|r:-D]ПN(D$!)![I;S|KJhBЀWVrS'B4x*NEÖPQeS*ڴ.^jTJ9Ѱ]Գ aL2QiTRǟJ5Tt% gSᔵT(b(I ZSᤉ4~ ]I_.4: Y2\S.)v"j )j 1 Ma[7gRtwEL,8CsF^hTj*eFkQə-w\HjD zF^k+3<''luR aўꯠ hjL8vF Ui݆4ڴ~9- [D˦bxZ&zҜo{hicDsWмhSsZ6^Тi 2lD(ZT(WрEao)r |G1k)yGK?(ɦ/ hJ);heMq*?рJN>K1~Ǖ-?(sT" I^ѰèhJyb,)$5m@_ZP<G}4Ɣd%卺@t# rXeC@Qі,[ʾeފfRZy/j.P_4j(9hSvPji79DϜ:Kk$T%Pu5O͌0QâԴ~jуZ~GKA!.ʤ)YW2 mJ˷Q>g-NfκOd8 (&H_2\u /'#֠.E}8A>dٻ?Ym";/ А$m3^$zdlY}|GV}+hY^U&ˬ$qmKem>i%5/j >KHTH+΁cYjfKk :B*ȫĝ#^$z3E⋎S_+?ƀRB(GS|ҢoPʪ]4%EϖP tBassd"r\1y.chw ɯG7mnюq[Vmmh[KE|h+ oiEwZny΢KМ 4sx%- C˜D,iuMҶ1#%;Mt@ߕNG}_DWOwҝ]tzi`a(ݝbO7%dϕt>6_qΛ33D_2VsbGym3;0Ӿhζ_PO{J{i\O7-hÂ2Z߉V^CJ&ҺGhI%O|ߠnf&N.ƅbZϴ\]rqg]6JլB5+h퓅ImA;= hs)ھ 6Dk%hggZq-GhӼ}էYK/ӌj6֋i uZa-YJ]k}-:pP=J5tv:.|Ws_VT9)Nԧ^7:1$֦t5 >{謸W_=GIt ]7AO4MG/-=n&4 Iuo5tkC4IK%:oQNqҥ-%tE?:d܉fޤk}@N @u72Zmٕ6Χ LkjC%ZD/Ҳ<}Z|-^Ai~H-_O n}EђY/hٻa29Lu^ZCgZW6Xж>%UՁ>M":=HGҡmj{chE_iіyimt69+Іz>DUc*$Zyt$PB~<[Қ?҆]&yF;43q*FtC&}:MO''L:w9Sб(:]A'c2RnQ T9ÃNmA'IFt߅tDMhH)5ɤʴrIvVi);uŔvU8Ҏ=ixZMC:s *eM>j#m h؀^<*F&wߓ3ʘ|S@1_Ia)CmN);SƠ4kIJ)%x7h*4B3}<&N14> JJ*kIM9oh@'?"NqӸmiSi&9NzҴhfop]G biLZLҒ hwZ:\v#Z{h 4w eN3cI4M;M3!9ƪOoQi*ԅsJF )f' f$yE}+f 9^I};45,>:P_^P`eA%.TÞF]G#dC=:1IC iԠ74*g Z3Fјc4tm܏FA#JV SӢw$f|*+^lDCn![Њ"*nIcb 1rySF:J.G.85 lHIQ?+IK85Pp#t >Pt YbRox <*Po{$S)kL3)bpibG @AGSp2 [E!SD M!e\ǔz_Oل[罅CnuD'\瓋4,9.&D$IcDjn1yWVS,t$ij UQA#rȭc T'g:K?Vt w?/r[wn""܍6#_eurD.wQOXJɿ?9W!G,֕dl69dlq$Mruu wF^9ZC]ɯ<ɦ9x;z]G~'6|ƐϛO>wɻ0<3r+N1.%x 9M p%*Dzm0#2Gb[d9QDC`s GX; [5U5/@Pp?}vy9W{I+AHn[)^5B 5)i;0Ag9؛`$y?؛uJ8l\-0^+⸤/֣$O7v;Td?HIwEQק5F훢Y|J+4qi@<m}oh ; ۉ_A?|;m |\:͋vB\ t;=.~C$wh{L=Zӷz< p֥ҐJZ4$'h<)ESZL'8 4*C(UrEfKÎ\&t+D=c6IѮ$lK֓j_)ַ#q%~Hn䱨YHnd>|DWj q5E=wϰcԻ0 Dc(2%4Ӡ~р!)k %&U\ߦO LE>A^S˔="aъ +TU@ Ǜ#*|Ux]>ZuD řMG(2|gEeʇ^na|Թr];#{gc?sIJS&N4!8ɻ$=43ĮΖJ$+$|1&IdKVRϹ\s>_u~}y7'洕{oY[Ɋkkp׹&mGrwuڴ;[_:Z[칳u9s֗.h}nZns}kmݙ{λ&wm5 yuwO]y 's?x2wďW6giB؊e,='t]ZIH]rgLmpy4ov͆pN_NQ9'g u'i8 7X֩ߧ*g6r TOéԀp_o.4ޏ)?¦GNig@ )i_N4u } ?N'{_,'NSgEݗy7f Uc g]t^[|,{Jj>~P1"EFK_M7]LplnQmDnQ-Lqq:A*"1J!0J-OT=fd}>.^Q>}8U,ANERG\vE\v6zi뵈[^UDȋ8uڿOmzkݸ /r ;&+a[MոO.\_i%IM/@׶!NM2.ڮz/q'eqz"} t@ڛrN.DwtM2=*]|,Vb-ݏ zME$d#&[sd>Kcԍ̧r]g4o®Lw'IsiB'ٳrM?HG)39q$~6/腝;K!~)WE 1Ƒ$9$3'5$I;&ݽ^goN~ k|*:DN~^{?/"tu]G%aF:%$u̽z.0WܺIdZ6w}Y%ye<q{͝xXIzsɐ^tɩ 9=a纾Orw\mzT _PS sR^t>-<".Ex-b)[+l+t<¶<ōy7߲AC.b9I|yG̗4mOt-+q6:t6Vۑo7|8_i>!_[BX] x ?ym#۲:}-E,Ǚĕ&tkڼeH?׹&вOҸ }6q ?ĸ%~'4Nė69uww.':Αv|G.{]>''G%p YqZBVx!qꞐÄܹ*aK-ܥ絿#N}0a{sQS8ZۑSx wpN5SĹ'boD+#f/2,|/_F&6CK'}hZ}-J@<5ϰϰd9\> ;u1]9t\)<ۄz\eA֮ %ײy$˃v$}Nָ yIJy}^;ryq5ϰӟR~|L{}<>:]cLB$|l:rVŨr弯ΤOv'I${xw ]ŇtU~6T8e:jPo^N擈enxZ>C+bw> m}渏~ZW&%aῈp{W:OB9)Wi|'lwG|E}1%y8ޭ.=w+w<؉#x8rF_Z_OgE.2%[ˈ369%i-ab۠c{WߝOv<w 'e\/늸.sd\%W9pZ.a/q[Itw~r[I4:nw+] kmRd:'$6&;7,lZ3xO 燝Wm{/#CT 7zWk>WD?xŽ =,W%qGIsW tep|Użd%ݯS*^i="vL8:!1Gm!m |Ζ9Y{3OgLpYӾ{qŕWdoM=uτ^yWu9'z-'3hS?Gsx;Kʱ>#q E7w}WI2f2NeǷ>':eyȊS5g>U]azLNc:CƄjO['we˙^ob家|x ?h2O+5 jg^96Wal]FbfF 539<8 Z&D}ſ#eţ>Cy-C뙌 ^9h4i^C>L4u8>x?;{D x]qPpq<sVuàbq)Ǩ%G*gLQʷ-;ߨC<>/ϊxU+AȊ~*H?ϩ:e׏R-V\+홯)Z]V׶SV,g_zUچa0WLSMX=ޞqy܊}-V< wK8Ng`Lޗ,I9W YLFQ|JgwǸ,[%ƙĠYⱈAԙT?u;Lݦh5V=}'j]zm)ϯcF`-,G!]VS'k5Zo {xG5j0F![4gXv}_*2{]+ּ8tO*o(u]KͶ\yEG&ǚ X4rƪ|wnUv\+~{G2z˸ۋ6Jgs2}7 Z\^oz4d,'>a-XmOsk?7aY-Y{ֿ)lduym%}ƩBzls,;_ZtL96g= qs9o68v<ߞi[&~{跎m{-~7墩g94:&5wMeǾe[n-~l?kŸ^ߕGzNmk,;&^Nc#~+3)po4gاVy5`UyϓQs}y0|;PUZQ%nw ,i "xޟUw?-~kZC?URGY0<2d&ZοLo~oӍtP&Y7f2LeL`hL`|d^i)zw=DzrK,fU3N~è׊,mxMեyoZGV:jy V˷7~k-Vo%-{;ײ,yw{-y[;~[A,@!ۣߏ !~A =W~lCeue,]ޗT'ĿUeȰ osZzX' ٞb~'I[4u;^sro +--'5FI^&lޚx}c>+xs컖~otxn7ϫn0j?f-i:=K>!k[yMf^Lle^퓣[뽋u;v[y}/KN8ۯ -G佈u9{źh_E?/Ty&TP-kTyPYcLTxLv2TNJSk#WHP㡚STxPC5"O/nНS8żV T[yF <3<ҽ须Ӗۖ2[tyt`2LK4+QmS&/6UK93Ucuc}5mScsqht 2Y ^s٢J<6経Qмҙc=ոC:ۡ>侖km(_S~f PB[>GTߥ`<5[ʃ)t=?uzfh4fOTVW)lVR6/v)=(Lg~ &Z̰6ô㹥sBy)e$>Bn2.[tRl0M^OisÙW(S:0N>C6C>5bP2sW4{>Vnijm?&A1mo,O؜LnӢt1C'bV+p{~"=xZoN[r苩&XGЎWm 'kFA$hHPe,?at(9--Wm@y*r ؼ7mD?^C8|P(By>(#ÈCm0?bg1baLLj-q}S8g0ëᓃ>8.}{pߢ o\GW(°"zlabXk0q.ǽýq^} e=({ah(>?]0t9:/ah,0GgVmFh[RZCh< {&B{E@B;! B"j  ;*nP/'/AJ#}|*je. y!8)'}>##"+@vk]"x o![V"x|̤DA.g+#xAoG=380Ml/z!5S!0f$&u- P??}_U6?]z6~ w}OEoF&ROg:|uK7V{[PJ.CCPZE=?4Ai(m< 4a4Div }ҫo@iӽջcM(f^ 5r`ga` `.x&kN[a~ /fJ,&n`'BZz>ڏ0 `!s/| 0|`VpV^s704 izwl-30&|_7=aG;My;]{ +7l ̦ `8K`G4` fc!m'ø`$=5m60~F0rķ }-qzLV.q]DF0J撿߂1~'?> 0'ma|ڿ030Lذ` _kyPv8uzb/0s.9ttV9yADZ0HZI;O9?7|L#c)lAqbxLǵM w`|)%0 ;ԮYc!"_x5 kD0֒o!߼G w?0>Op9==,!϶MAh-)&kk7| }CcWISa,<|`:`{`̡_X@{Bp~>Nj'yUK:XLtz%e*0*)< cb /$8y£b̤E?l~En'byy6t '[΃1ķ& %_(cpMCvC䃁A Nz#:YğD`"[́1n?#_=MdT'WxMt'.&; t&{|k˜Dyh"3JgTH>|;+jO?c9U{bU|jo~O1DzH (W85-`^xrWs)1[eoaf/`|NNg.lw-y:-W#$K#c#.vq"w\|3a8A|h>n[ 5K̻/*>`ޛ@qoz5JϭFl.}Jc\Iw ~W| {S_|c7r-|/Eme>|'w=__J@ ;῱ڙ@\!6Dsӥ_TK_1zm !gwZ:o+;'9WLvw;&u_f-!EmxwM {0|s͡7{cos o ucTx!߷dS:z}oj?X]w_~-Tg1ٳr7.S=@] _.@F[^Fyނ@M G`a^?"q=;GL}g<f a?,`" T_Rv ~}~CpWsAX6BgAί.^PËjеT^"O!,~ PA1BWS=}i%8 {ܼݚD*kIG-zޝk>f"Gs?-W/\7S s(.7oP*7 (AQV%W -JS#讪ZPC2)_RsM0.M_Q2 <)J:| qϑTܳ5y}){9=7=gAӅ(^ţWxL97D_nm n |~CV!k11l(A CnC!Đ Pt$E;˕oghnuE/ފDzPt (*E]sw(s$hM0+0x`; c'_]g?Abк 4{aP3j=`k1pb6Yw~ €9]1`r ( z .gv@/rl~13£Q~/D<(,+Lяm:~C?1~w`n8Ft8};}oދB#oϖ'r9x}HGx?퀂{Q*TQP JCmse=/]ޡTz?z7ݍڣϏ'כ&zMk^9n^DwBϬyɳz=x1=F߇w};AsJtق֡Rt|5ע@ۮB=u ݊F[v tt=]?U&]vBקDWPtS]o;5F7?}O<{!!?k k._.}.BbD?ѥqt7t:1::WAiAgW@7ӎ&Bt3& N7!o-{y /:"/kR9]^Kpw[a:{cu9:>ct~>u}Ɨ""#%ɕMC'N" JH7]QQfEk;Ky~3gΜ9s9`ؾ{= ^elO@ H>@bv,"ޝa};֕3 V3v kzA˄Շ_ P1^m#^$FB33om@Y?ėEG|{ M/!\ĝ_{}3EܸJЁ?Cq%ne vRKf6@lqĶً؇o[g~h>1E4 DL-XFLD.9A x #z\_DDt+n1;ۈb _B Q."ʞ+QFT0_} Sga>`^a.sW s 0K鯩0] G´/ 5Ca I`/y y0=`<c`+ZdXTƼLa90ja `vOՆ0vz]w^cbW;q-ׁ%+o2a@C9x? aςYޅq'tcɏ0jW`\<3)sI0>;Ik`9cG}Gl##sgd7Ѧ2gT1-F[ks+`6v?AR˨/a. ?,a)\`xR&{7e5 hO90=/ 8w {Q"b/0@߻xx8VB!C"W }O. o)vD{cAk"hOZjAЂ4=7!:Ƭ@Pa8;4@P4.Lk؍Ri/! ?ڑWKGP$݃?u}׆#x!nG׉< ׆M7'F`. (F`4g#lB`-cQ.>8 3l?,F306 oA@ݳhcE@]Bn1@6׽}I W~~Eۡ!}}d{.>e;O29ۂ~ },Ɉ}9ne;}=X}ZXlJ7E+n8gv-w::6n Ǐ>o_}-t-t[^? ݫSt+jA|t/wō-ݢ ˾Kyٜ&igSmD6;v{d7'&@m#˽+h6zJG[{j(me%ns=ǖ5(\lmԺm,IW DL]q\՗p9/*іBlSXRU^cldΒyתLpjNC)6_g:euɳi,?$4rbL!|ݍ}R .>w\+po-R/g:mic[2OO<%%y]#".y&Vpmphn9F!"}Hߏ7{Z) j'\'3Iؙ|Snm{-,{yFr4BFuY6!l =9/4l5үPDڽkA1ㇱ^ ^Ю!޲r\~ C$hz+A3M(g4G7m~"$Oϑف#d{9B!-lPI JA/~л‚BX?aK3aMFحop%'#<׉¿Z"isDoEDDGK'D|}Ֆ#KeD<‘\]>ㄡ0tC1H>C+q,0:2/s03t䷘F)͌0~yK0ocaQ-DTt.5G_c+D?7=r8׾A>;w?AL/Q1}n!fm,du,1Nu#.%@r({;xk a>6ZMY؂y] #x ^털18! 6!nR^|qoEf;oDܝ_o1;=q3 #Cf_@G?nK UW#?G#AWnAq_"!/$ ܍.$ Є)k0' /#վH~!$|K~: ׾BI)X^K}],,!` s¢KP,YDwO,#a XfͰaeX 7}` ނ֮_3hkưWaq5uXͻtֻX+ kO$ #qH!H|iHX '`X I"~3$5EғאHFUGҌ&Hz$M'- $W 'vD]H|$HFR2$"}$5*?T3}`;6Wl3[r–Ϻl@$R%m5%r3a6 sRXzܫ; `9 K簼7 2:,pFK6tlXf’W˘L a?mq)27XJXte8~N5,^Y `Ua}l6 j2 G Y.&65 kZ &G{kOaNa{X kTM_/53OOX k뙰X"+Zv٠-ASv]6\˯eԧކv'~璇<',Q(ۅځ$]GtI a}k'c7r{H9S%\OoX(rQ{y:y8v*X+n5s]N#QcEbבWHN8<-3lďgsx_clOa [ ~h]a{ve&l)}U[uԠڽ-H*0 I+DҺH1IF/[\yێfܢ>uHx Qml'~)?܉䌹H䡿!9+GXW<$׫Y_$xV#r'wۊW<`#\G!)H^ɫ8;/$oKѭ.t 8ncm1tlCm*t)Hie@Jd :RvAʷ)H'ݛ&{Y gET5z<9 =z@OkUeOzLCO[*z5m%zz =nCjfGWH=ԫ1HiMÐuҢ"H-F!miϾ#)M~iOFڤ62 ͱi'FZїiSw"m i; E釴?^{:;VFzL83Z"}ԣH &!}I?t>j0‡W;5nz͊GFbށʗXW'лRz?Y 3H6}"S}.훡o ,}?@G/"FF7~G?.:/0E H؂a'ǀE^a-٩ 2}{ ~Ơ0it-[_ /ϾÐz11$_!ƐSZc;/c輦zp5U)'1lb ; w`@'gF oƈsbdD!FoaȊq"k Ye`>),֞Av\do웋9㐳\ܰ<o&-]!QZ 9(H fEs(|t* (|z ?a FMxUJ1m7NKf`qc1C0& ؋;N߀W=q3g`g0o)+1~7a0]Lh a̕4L8E^FQQ1Q9Pl8 ãhQ,߁#78G@[8`Sކcb!5Ap5V8B.4 p5cy8F]#rKpǸp~np<Ypǜ)[YQt7O;N?Jεp8.rRDC8I',_`[%>"C7g~ ]"xꘌp| ˾bGlK&vMy]$s9 ym^[5ሤN#;GqtaoL]}Gk}$M#eFs8RE]FE(:E?NGQ㴋( Qt(EeKPާͼ3E;(zV@M(z&>4q?=FG~$rO(v9b( (jEaO1P& „ЮGcˆ`ى ]b#10ߴg\g0?ĸoN`eWq1'9ƮX@0Q9wcۏ1 GbLcm1`0S'؊Ѻ H#:FQ'`Ԙ} ؆Q Pxօ(9/$'d@a&F((\ dp/)?p[ ( /FaPX (BŪ(4G`՟( Q0R: "砠A4[ݜ?s';#?pAq#׵C_EKOO @dxN&?o\D>''|, x>콋`v{I'="Of9Y74Vdf}XG֧ǹlߍ>[NE֗7d}HysƐFdYݮK\.r.&? kҾp3`wv@[-^ lϋq/AO`/FB mYEv.ϟhyȮF'5 <vo dُ}l%;;ub?s3M29?اҌͤMNmrmIӋsDn1a7Ԇ=g؃g fR3n=sb !DکmrCFY<<VuQw\G46. [ɋzn7 `H]낽3q1켯m֎2`{+w uxVFvA+d3fܗzgd;W^~ȩ|9M"k:rwa z0n99sx\i? ]@.R&O̩lKbf> rsͽN@d..!w$fB.m)\߅-2r߿7k2 /2K^!oG惩ACnX6? 7t1Kך2̥?}:qgXR6-erE7FC.@nȵGqͣS;rfC[J}x1"X5X'!/h o| yקszc7ߎe6 yoG2m 8]Dޕc'kmA>z%yA>uOϘ>Euo`}/0~+W cKƞ7t:(Q6 z{p0((jM(`]x`mU7n9ޛ||P{#(x$ W LzۡOC&ơÐߔ:ignm P."z`2m=3rBXNcΦ束R(cg!kg mZlŲؘ,FYe5<_ȷN`$sF0IF|e1xF=G݋ˇ3^2ß`x: -  8163L? c\1lwu {m?-0`nXV(Eİ0p:`X@ CCj'ahA ;r_z5=h#z6{\zf=c'c\c'XǤ-葕ΠG`z4ct?LBws?Bq3Н;;kwXݙBLۍ#%$RڌE?CKYVBw- k8=H #$3JMr.GeL~Io;[ȘHgt\oa<ÔlI{N5q wg͸:ø17\7s7|#o`|E=s4US^αe l|i'_#c<㲺gX930P7%d~o<;`ܼ-q}՞n\c)snN/l 9snFqqtOo-]5 aSƿ^0^B W\y͐ZνICҀ[B8q)u\Xi ̫ 0>j0 ԣ{j /ôo0<c~v8+tӉK20\ ÌyD y,}a s a00v5\!2 #m050킁9A 橆wah CF0'z0 (W5P&ah=\kۀ>00_7R~0rr0F0̭mŰުö0R6ڪ<~íC0ܙ#scs<܃[ ro- &.ؚG;oAn>G>Mży1vcG<0055̄᷑0L9/}Bхr*6>YEYgeu6oXs ڿ000^ ÊN0 fxfbBS9aCh}b~`rI@#(B$}tY "?_HȽɼ5r]"_z"iH2̃#MM X*.xGD,+F</!HC8+ܲ!"U5?ra~@ع;-5"aC'",1/ c.z},B;#^(о,rBxBv[!S!dX$lES ^>sG|;v!xh. ]8d[!| @pv~t@еAߜ@ |Ak&1o ZsA/"h]=oA!hnj QALAԝ<qA"Yg~.D}.)_,GȘ,pdv3vX @3Ń8&'#K޽z[_C`#wp5  9kK]Oﲀl I' 4 Pz^_@O}og=m~U 3CO;B>c1WBOӗyCl.^qo2e O١]}gr5H~={;(b}ʈз g;֟%̬2:nu*=eozưz ?q z&| COcL:~+Н] m\wdt={t@jt<:C݌񩎱.o;tmjpr ݀t:ӥN.ЙY е ϓn4tO#۴g.Bhߪ -yUSZڸvd]hiS.@˻CqZ=@"k+ z#?k :y?u;ۿEwf=>'aoo|hy'hZ#-vS~ ڡ}-h-?{%CkaޥݰMۡ}oƽ`/Nhdg^8Ds26оBh\+څ8w!3?[; evUh6}=A1um&V*ßq+uGз^˄yV\2gIo =8CF?>ߥ\_u&q/3 mh ںo-*us em+ _~O7ßy?O]~7T;oߠ< .g|-|/΀?c%#῀r:\&̭n8[^'5~1mg7DoᏔ7Le}~)Nl7%"5.[{=!=sFҼs:XO|]=.Y~!<|b޹GGYfzQR^"_m{.晻3:}ж?bM]f|O9[z&zy70'fANG@8ޯY'COCdx+w[ ";t :fqA}Y}.1/ 11 np%5CpN'fB0}nH.a b@HM+#X9W6^аe:>KLݺE\V8tG=aF {k!ŽF/# /E'm?n:"Z#"&ǐ;2c<$2/"_G0D\~$pL73/ `ż ac\90r]&G|F` ޭӗl3Ass01~o]ׅx#o"z ѯAtY=DY'!p1qC̊u1,D߅`8cGl;،X7/!&*oF\ o&ډ)#|(3w2ĻÝ$^;oi㙇6$ ҽϑEg9: 9GB?`Zn0Hz ܯW#|6A¾x$/9LS$\!|x%0N,{,Ú jf݁ul3ui"º82Vڢ]Mx<3s!q$FJ{ny*̫-MX²,F2m,cv2XZ B=[h?ƕ K&kQɰL< Ϛe>x&-{,>XY8iMXNWĆH䝓اʐ8i$ҏ%26Isc'7G$^soɳg1} OT>Iٍynmt*-CGVt9R?R">☌ݙ3ug=eНJwE =F={0A_уٹ zҧ@O=Eѓ{ʳڦ>R?T3GjI~C)H}i#-LcX!)䶺߆3ּ:ǥ^O yHi1HiK7!mT*B9~.Mg3>Kz#_}K/s~XR~7O?Gc0v @GV ݘ2{LާD"Fu} Ġ G1 n[[`p~? ~E >}C4 Cv 8Cy_Ce~=ΰ[0P 7-1|i s#;c<hFH#?k&E}YI(+fN {*du 936!֫)Ōyey/a> |cVƘM1gulۯ:ߋa\ǘn31&0xw1{2r>&0v@=NmM'|EhE P4 E[}u*5pw9u)apaGw;GV8zr\r8# 8cpGm9c%8x~]{ 8 طԀ}p#*2L{8s}#c6"0p=G>"ץxvژ8Bu0\2q7ꋺ7N܋ϊ5Q_SZ.JԕoK)}_ ](FOPO]{Nij>_M]w <^Q~2ļ /e- 2(Ү%9oe.ܾP]=|GV5/Q ZueM r% &|3?dz:JRWگ,DxUnuQؑeuU~X+ꂗVvM/ :Qgj&boy(>b>}M[>KhmL'J㿔۔oA@)u1&z~cOoѧRЉuNYVLЈo _'r(q@1'PCQ}Y.ɐUDPE?i>tњhL#xqY}w\g)D/hDJ|~?]%WBw/dd(>l ]c2CүT*IhtTJB@ШI1JCˈ@cZpGvW|+uQoAPEHܧ+4_E .ɢԯׯzwힺ2vUK2]zGOnꩋFGz (<JFmj1ozhsR,vOҦH|E2?ʷUQk_ mӞ5(}B?zrNWz2$?y۪?[)Y(ZC/ 歿^S! ?V/mPSߠ5 virs :ӲxA2jo:^So8\Yjd()jy*JौW rЉRM\>& n6D e>A׬A9T<2It<9{JeOܑ-3=hWxW/"x,|KmeVZ:=_Љo *Yxui2᫆\ iӳF5%H}9mn]8U2.8 *}Z}ӯɋNnMAr=h$-W9V>gzUؓy1W=rʥŽΫ窷 ?-t=v&Is=){+X&ղyj}ʾ)v,Ϳݛ*߹$o_}{^ͽ}~TSNu+tt n(~ν<>w~^'ʽ;>_qn;j~}Y\o{Vt= JT]ߺ}}7/xo }Tѝ@Ϛ|ul->@CxG^)P{ #,P~s-ݽSbF%NV*wnձzm"TRWųĪXXz1zuO;>v/dķ":W)Z^(kW3!J)XSxQn1[O9(ᛧۏl'gpI5Nȫw|srEu.Թ>Czr;w8IPJK/Է.sIuųyhs4]w|Y=7Wx;;yPM[{Ρq(y+0˥כJvy <{ Tt ģwrykKM~7ڿփ[-9Vyt*r^zx*|T~@÷ʞUIu[[*{_\;dk{^[i*${쁲nL/6w_=-wbKSVa^:ZwJg*(}IsS+^X%<5)Qч/{yG;/?5_E6uЫק^=k?y߫ޱ7ӉC7ue,&M,(EtTƊ>O=»m^u{;k|xxxxxxxx24P?&E?C+4L.˘]5Weٿcf_8BF[/kj)k4@S֪CMY\MYRMYߝ2,2LS6l)i^]))+Kє)jgxg .4NCP3V899vsaLsuٹqgsn6;=hv^QZ{3Ϛ].R3]?mٵXZ5kL1)r)dE׌) J\Cu[uu_ )qolvU[]gv~WP<޻Y]꤮8:g6+u?Zmi>qR'};oה5^SY[7hʨ߲>є{YW~,sGcin-._؏ .J@GeO=Vッ+Bo|}6CI>VOZЁQV &Mnus!鴨l*iȫl;c5e7Ӕ}הqj*v>I];wg@a3Q3musįo;g-uҦk;e?eqrO;7I5evUsE+q<\Q4gt{V*?\욷nJ]/]ϺB\j\Mwdj]\tRjNځ󍷊_-u>lvN +uҞ)K]Qe?kʨ{Ig,s_ʸ?(s[FlvIabĞ&[o|U_{T|r|QBUy##w.(>$#&)+ذ]-M#yHաXYfYfZ?bv^ljvUj~n{%&]=^0K8Ex^YS${=fuў\!X{Zb8C=qԹkO%{,|Wwieg'+ϫ6]\vkv$c=;D#@j{(Hʝ%F쫯w߶Tu8{?>)[7\(:qVqcE>LG?κZ,#|=8\e Vu^_i]Q]\=.q V8^GOTi%.7׳ \ \o.;=fvѿj_/{Gio=8cEQأŝTQ@>N'o أb1=(bq=2G#)k|.*T·'1u.\ig91sERi~ucXRCϺWW]]2]%.ƠAf׸~^M{/ayE]]]I\κzDR)F=9nJ3c^5'圾9nɵK1J12)Ő"v1"ЏE )7TGwR &= R*rWdb= )QŽ#+kq]_CE9 Ii=ǽU4I ^7;W5(r]ΏƗ:9kȜ\zf8rkT%?MW]ٿ=w%ŝ6f-q.*qu˴5ZV.q=|)\Db羉f;+Jkn:ߜԛX=q /'RN#Σ'D"ΩgĹWcEI|{GH+>Rأrg}Qۤ({Y@m?*q({kVGw-أ]^o9}uF_}qxKs3Xd򅗳73KN]0UY)hձYW3?]-W#5oU(AO|u]%I?WZ hjsp5NyyY_3[k:Υs\f''Ž\X(#|I9 Po9wwGKV٣7{TǑ}-ߴ5ϊ|F?||7[}we{$?8C{;CGړds.쑾f%{)ԥU~{Y ]u]ˊ]ſsbׯʶأ(mړk*ifWVY+=E{r*uQjTK?~N\:w8ߋ3;וos;yɹ<ΐf'er8k_#,Ő=wۣ{:TbHۊQȊQ읲ՊlԷ~wZmok%VQ׾(μG݋==(ab "Q)yH{,%}R1fwvj|uh{g]}J>Yd [[Ux7mWeC[PݧqkK\K̮+l^<$a_gqtvo Q1#(tأ:1::wo 5&Ş7QvLo<[iSd7*Gq(Q"(Ga"fAYE-|Gq {w3>$݉nd,,Aܝw.w[qVc-u6>ѣTzxw/#uқ}+Pc7ʴ_^+uީrl r~^=o>b's" [N 9Б..GoN#|oT'S|c|F|r_+%CXʛxPNo>ۊśg\2Hkbdzg꺖DJBJ<9(hORC{rDYȑDUuY@}HNα{gx39;НxRrC lq΅T|-R@ɵJNs|}/j%lQ}OcG7 {PۣM Q} 7#|)~o9xaś;b1xaN$~ϓ ~\*ޗ|TZE޾QU_|)q%m6"_!}7dR,~uv-I T,owQTq QWЮ)^L!7>_h S*rz)tMד!>q/fGB{'Aԥ2S/Gr!ƋER?SURALS_2D]A4BVoxD*u넨߃Wot)Lgݾwvy]1 ##:y9눌/wCFc2v5u:`Q<1֍_zKpܺ]PEuڟ.'=mQ*}oRB#$,u S W<ڞ+[ŒÞR ಩هJfc2*vMu[K@Q&5XܲyףNߵ[/ȒEՈ+hu R}ow]7$Pu_Yt|m@Wbuz٨~U` {فM؇~G{뿕_}Ϛ}m~|l7WEk_ڧҧj/XP=}QTįڿ=Pl^kHezRC}y{OܭʝY}u+@yWtYRҦ|+muu"b kDSH@DĘ?)Pb*O=aӼ>qXZVD;OV#y|s߼SתrCy׻H;vº(TK9`.шzۍGye;-H%IRW5.ޡAEU TY-5*|W0$O9|*CԮ`ݗjuKP@wB~?FK Y1T | %Ϻ%(㔱|y$]nmmʻ]Ru^n)o;ꌪ Ϯ;RW>4^khlE*Y*˷MY=rEۦ]gF-U;yEriJ>+zWkOu&* ~÷S|=P|Pξt06-#'҃'$F4v}醹.y&/4E=:ƃdku#. }t]1/WPwY.VW{dו~uZCnE=fF7c3ABlr)vM{g.S/݈]B~#!!7t1Y ułd^H9ܔu6mgZ:_qb)yw;m|\)-RF]7=-7z4%c>\BzZ>**!^BB^42;;$d]`ʸ=FWxh?=|FW}I#JIw雒\R}ftLmi%RVuSzpIF{PH/uH{@5=@3xxxx05T.QSH4%E$1ﻐD2GB6 Q 2$EkT$:pR*_}~nϥ9{γ|Z{|/֬R(E)JQ&`l 9βxO'q {X'FϋcS-9ڻ>!>Fmpی\Om0јy8`sv̞XbOhsL]p}'x>y1cYc&>Qus-`q mҼk3-j#tj~n$6ħwyWfP?\/h7*)Ɵ48>GQcס_6SrdYi椾Qǂ^;i<7>sXA>pdy %BodsKGPn=>LL59d Z?Ha|\ɘx![ͱs ̯m.-p:̶|Zw2S-_ǐc=( i) }s2AE۞LdYm44c&+,n}t_x1>ǚݎ9/tC:BSہx-cl/m[mڧOG1~4qZ/<{4duƙɭc`\[CqVV$'SEݏ=/u<ķ)֮W>}ZN-&ٟ$<2&'w+ijO}b~|PgX+TzZsd5ΝC?qZc(G4K#8dwjR;Ic=9R9O5j5~s$l$-cOoy/זM6XƱGÜԧ34uX!=xzG_MHc3pD[ >jNxE;4_\0cTd>:. aFpETM|LV<\ zKcmI$G<؆(ҺFq5|iR pn#똰,z~_c,#<1C3]={m/ݱ _ >?;O}vbbaМ5֙+nj_<aU0K_WNh< uL:_Ì8Y¾0tq(}m4 ׆q\8 џ1&d>A6`,k=R\>Ygٷk̘94c}r"WzAwO<.XPlk|l8Ngk9*W]CN_{Cq\edt\ tV(q֯>6֙Syq[#xmeKDַ`i;?g3>?VrnƍC#K9%B־z]Qt~1񡵎`cku5_.C~ZdkȤb@NkT]߬Mim#_ bB5Jq4 j@\^C{qjkto4>3kl[IU:z\能oKl6ByA_U}N6a<xEkG5OY͟Sߢq?= k7?$^åׯ9_zNWNkz|Ǽd7^kxLAMqN}x^>z?ObI%Be}k]ɸLdh}IɌڿԸM UNOdjUO|{Sao)G+^zBwgy[Z\C߰OJͽ}2mwAޑurj|vbA&~\75_u<+t{:>X'H ˏKl!8oߏ\/c?ck7vu\в}H}JZv,ÌZZ'>f{4>uc c||?~bt577b ƙ<ٓÌEhCh8X?E-/޹amҽsz =6ȓc8‡H~Ƙķɼ^ɯF8业$^ACKoHum$gП&9sƛr@d)[@},K OO1YħfJEDx4uJF { Su*ǜGϣ|{c~*<:yo  ^pEz|MtHmcz|"_qtT58N?64#.A\'Y6Zφ ؤԠ|߉~<-+"!ʡe'yHۭcЇϗ3>w.9MGc~e dF5lK6q.3Lh]R[(/~;1iZΟ#>mgߏ}ԿƲ1 !.'ńЙc' 7F}ΈZ7c߁pXYk=/-uKˡӜl_sdK1:v3f&.mcNǸL+Hee0d1|9t0Qd?}=kn5_dhWvfL7koZ/O<̷=!:3IH/|s7y7J<.n5.1߄8^L[X1e!:ʋ Š?W:3X:0}VHc#807k{ _v2SA gO}p[~_3h5=?3L4A'834|_~˒Bx?dxn߬| c|znk&u~ f_ }1Fc͸nX1#Ԉyf<6}?v)֫ĹC|RnS!>nkx,.́y|G#OsS3O[F<;?Fć$> 7DGFy>>C" N"c#/ȋ7ð۞qkcFn ig`\#Ccu\}Ռ~u0ׇ]o'Hf;^Ci756'F;#l]ޝNC݌yz,)t `14\10_91!TVrz}z̉L Ci1.}'#sMyCᯁy}A2CfI{OWDzC_j}pOLM=jkASq&du+ۑ&^ިoWEmc/mk!*NL&}7?mGBYKȾg-֣`*d?+>&鹵,>Oqn{]:.ć|Hܫ3}ՌF6qB">Ob{I;'&$.k?0"9ExyX_}1i髚g!1a2j #{:Flrt[3|9y ྘h-35_ ]{d%Z7!o |yx}oI8!7NkN+sz?rY!!ϿN }^yӲAn s2ع`=slc< S5|Ԃv #GQ?]|cK4,ٓsCZx<Ewy6Q׿i>c=ijsRĺh2?k ÿЖr[km[&)OWls\`km?͗o_M ӏN6b9  2JrlL*y(E)JQR(E)JQR(olޯH$ϗ-9 բmqrߓ?|9z𾢆%d;{uMRﶜQzGSBvhfWrwݣv5Յ[)OƾXfWr{s[wׯg8^BG'C+8';?rz{no\!!Vt7vW~xxG>zK_߇\=Rջ G;~;y4}zO'x1Gӓ߇~o^޹q0dw>0Yo̓wkֻ`ΐ?{Sj}%e?ǥwm [zlz&xMS\E=Y7GQvO1<@x>4mS_IЙ'/y^gex@ovIw覗ק.hw^[k㭃7kwd_xG w/lilx ϻa/x{wvƹo!xBĻs+yz}8W~& B^F=~ IbL|Ỉ]ZO^ewٻ]aSw#N[[ b 9~'L;n XKNW/ݚ⍇Yj[Q]h/XF=w閧Ip7l#f Ocw{fƸ )kĺ{c(V=C7߼sXAw!P }C9^!u y;zߝl/uD\ NU_phƈ3xpK#e$l{9g F B\.==e:}tO~Bl ]Oxݛ.θ}V`L+(?்8KC~,`DI B.3`<}g`yr b't QlC! 7YWz{X\I_d# ${cLȊwS"GZ{mkP3װf*m 0l&{S+lۍL$ p,O= 0^?bE*c m[d[PW!tx\"_C)U߻Qai ~G񊏬Ҝ;9/Psw6j15" >l rb,|؃O;u%.FqܘuD;ǻQQyqMf[Y(q}Wu4r?XW x!& 3>|ƹ>S8Op 9k{֫gK!3dM 58z-B G``)|rEO0]wE,]xm;x<{t5*pm \i~C?| osU Ja@&>0IocrA+?g-ȵ|zOu=lA0l ^ͱ^υ `݁y3;P?u_*t= ]FisՑk0 x`:f#Ԕ?Rxz bms_3| ހGxxP{Aޮ\cw,R>mEbNٶ5 Y! މC/P7gu:qvA> zsmk j.t>rIkV-1bNkoz, {$ 3ۡ 9~\b`L0 +8~z8C^AɱĘ.s~8ާy}{uD <ƞ@y lg0^P@T7ۑ/}y}5wQutߋ[M9t{zX:s$쀼YX ߨ ~x9:`D{#ȝ-9 wgR)~r=>{r̀/!n>=(s cpNDsps^+}nrm\#5뵟D޼'0y/b`# vv.qkbؐ;7y77罔~tmW9WaξG8ؒkӶ? #rE7n6ֲcnCl9^T}^ڰ=^;Oy>j@zO>5œ<%;l  _Db)|XoӃx?voi2Y ?cos·@x4qOc8n}Kj7gZE>'q}B ߽?{*: ^?|@~sc) zX@{kyUnPGcɜ'SpZίKΨA=cX'ru1NoNPf -yZ#t~{ڑw؟tO% uix")_'xMP9S͋\۞%ný->o;!i9zOp}"?tz~آjG?s֍&xhz!/=W\ yO?Tuީ_xck/DL[=kvOޝ8^ l Q+e+׫Ϩ;r#Z_Z4b[6Z~K+a{ GOMiʌR(E)JQR(E)JQ6>uOC}|Oq>#ឲ~`8 s+I9x݇Uqj G@[9޼՗Wއ|{ك޷ѱW6{2oCxR?Bo ?T?^߆=:{^ tk/KqL=3=t"x?r߫ȶ?8*b>舞a~~r Al;B=y/|'aѝ`VۍSY)ݛy8|B/ =+2Ysyh}~VrvL~PCU` rr'?S2ς@=9Gtgz=#[tx%?٣bso [G} ֋c Ơz9'}n)/HFXAoXT7LqQno$8Pf}J)o aЙ~ku>1`{Q:⨟ o~` ڭWK{V8gH1(GRK0&+s}8%^9W:C ϟݗ;*%sNDL¹Yߣz<kՋs+1sue"RY'ň&}9a߅ xm Y*ʍ9t] CWin;kS>dOOp\0?b[?Ot;4&u=ݛdk^_j] p0ۺ|7?'S?2kx~'c0Fm'p]wȩ7I4' ;=65uz:G@V'y^2CG 7a;#rk_z:f$_`C4czsnye|>Ju't϶cybo0;^W7^i<=%)f$lr\ p?'d'5ޜ[zQ볟b+?Kٓ~՟6# p3/s"nދL=oɸu#Z[ܥht1<q5^ d g|4׶׷5is<y}_a_?ܓRGTGǖg5+*c&dny3+0^^;mN ? t>6X| L]:S8 b9W y^+ d<{67p (ܨ0.0_ɹE?o l3kp8ڧ1sZdT~ۇc5Gؓ?׺:NwUpȵοa,}8t ur`׆)ה}X>s wr\i~9 {A\BnϘrƛItӃH=~BlO7$oy=Y鸬Ǡt|zMѕc`WC1Kte_BV|#CaMs?tK5юj=~3 #9wQIo:pJa_Q~nY cr yhEp~=>.s^Q5 z0C߁Gr/Ӹ5H =R~bG3cp.(MlB/8}@/ϼ'6bzU9\o`^Kkk=fN&ە 5`W4t>{0!ھhy}K;FГu= g`T'o _`q}sL@z{@o0|pOﹱ}e{ɜKowz-0Re/ix6J:CY =a~Ry> tl ~w+,'Myk}~qn$c=od-БؑVϼu=7{!} Z j`=;c|}scw!n @~=}%JQR(E)JQR(E)Jd|goZAM4>+3tӿqusHD: S}:;A¹ﺽeNySHLuV>獤HGO$}"5^x-M\dl^G?"(\H?j|~}yMp^qI>||xk^|c"G=V$9"m/SG9Sx #\vfpc䳠z<:Xīߑ|V$lΣm>L]Zp5OxH}y+L&N :f03LFoQXG=a~eĜ[V$"exlӱ\&5zZ%9ct?ͼ)DL?5uaͥṪl^4OH5kH9.)> ]p8ŭYtYTC U=17~x1KնU$~#W0=PC(i[ӑc.Oxpis "&e p[6 j.օng;^udeʢn/sLfI㘺s}y7dgݧ.Ox )VʼnccE1̡&>j[y6|ݩۚy7<כuɏyݤ1y0Hf]fg5s ~y1RPP, ǂm^sv\:Wngx΍T_7L>Gp511ou쉔wĂf#=_53c_=o>g~ӼG:!]y<&6Gܑa=\pA0]I)CinSڄyymo֩fAo $sLMcx.xM4| kyߑ--hH:4^$*OAj;h[Wx;vzl|A̶Eڇ)h sNeˤp\g3?ǂH1-z*N- ߛ2W77'xefXTGMˤe/d9ϊVֿhћ -{W )<p*ϼj3裸r'= ל"TsND(SAE__WA ;ZAG iޢlRΊ3gAm&K GQglW._ | ݿSqZŽĂ0XPn#ka|پa8v*̞ʼnœo űca oqڅ 18~ZEg3;ǟmQ:**Ƅ*F~V\Y)nӟUEY~ġgU3{>v?A?kF^ȂPP*3O++.=}ƂRA\ {1)~'~'~'~'E-̒+ǖs1rj8ҒO˗YuͣbdwmqK.ʗGK:YTI{lw\/7+;z}-C{{|^_:-}{c-y6{| )p\28F./Chw[xOɒVN; `>&==Awysdy]zͳ1І0{sa^8xlYꍻ$]W6)@ã+/H׌͠'- ` h\;)΋?Q8GE}3=dmU:E;rj|_2k4ֳRm!ځL5O6.V ,-+ػ)=`^1OZ#,w #xLq~|һN6@bJ?>p\VG`7ד<>nkB_8@Vol³2o<d]_SXt#&`4ŏ%*nA Yj,x2QHcž/tIel,kS ,SE~@%cv iL!>oq={+GȺ2XXAB<} >»ߋ<^Z5ǂ<-\5A9fyQ⹡*F!anm3L}`o7.b4o?ʩ<+rYJ{z*p3r#t9) y\|a϶Q̙Ƙ(Zr"^!C^S 9(FnVy?G ST^Ev!b"t(3jxW%\P }y6TKW1.o?pA,%]~ӇP}|\!R.9+6dU>x(sM0a?QX(V+=>لj$%;|{}U"P]^a~J',9;cl*Y{`jdKapYGT#uQy`eЎ\QR 8BLȗ?fԥkr#r6WU"K/zb_WsBocj}ǨΫHZ9 ׉GԱ熓*Giw{@W|9nc#kٷG*tAq7t-Ơ#bVeWZ"[v/(j'x9?`/ZQ$SE^Ʃڃb$?~6)_[X꨸=cFSAG1A.~i}[!NR9'FuxE1.dx!e9sZnU6uLk-5-K*YkT%/^k`NweliGWPn170Ko؇xlZ>Oߩ\dF^ zmob;U >DsU\'7`<^r1B{7UC""`I({y:s-r5l =Rt;[U;SKGi&#DvTOe* @/mЗ|kπvX?a\SSWu'br+V3UAݎhMrR>p_KU9i](gTupK5JZq ~ uR1=ae#ut'V^pR?pޗp"wQys+?׆}x]qԚ2Ɔ#N5')Qq)x8X9lO`u-@`'HiF[MA$`.'i|e8Nk[rjuA?g/gڮ0qN全lس~3y96oRm~@3<}` Ws= ~TOnԁ+*ڰR=aO>Ea?9o-KqXEYg{aw[=|PuH"iDC.k[*zj V(nzX{޼:$~'~'~'~'qrzVR]Mjək靫뵩K8#Uܣ1rZ|9-Ӓx^k3#oY-ۣiy1jjmƒ&Xn퍹;W_1;vɗS+x+ ^h>lw">g.y?2sGJ靔.3x/qKlV^~ߺ|hN9W+g&kbH4AS[Tei'-s{֯gc?d\͉S?Q>c`iޡs-?q5q/렟"}- Wm>iN4_݀wҗV00 La`[2 T{4p:7Xz<+ܻOSkyQ6|SǨгL~=fieƲ7z'TV&}-S%}xy|β5&xv¸יּHA?}lgH!Y=Lݤ y龎3 a|Ss|)?:1ψgV-W' /fM-)Բ|NUPv#_SJ_9_ac/}T):."6fNxLO6=ɺSLixƘKĀ)T>#4ŋuo k 5i_V*(m|cI%+(6yǽ>HιC)(N+pcxX. 76)SLrc\x =e(Cws> =ٷA nɶ˞(NV9tqri'Uv(P,S<Ow 0N-s7&b\0A7鈛0F˯eɦ*F0F5>4&e+C~WGC˜W'{{jſ<"˂8HϨGcY[sRQ%:Z_vWk)M*+7?AuIՏIIqJS8RpO8 nY3U~3/wH9r3_ 6䭮|vh1AbT|R\Ƥ|\ 6!Vp]ɖEɄ>:R]9r+5kLŧ:AqIׅ\ӗ/^UsP\.p (n4:j:תgT[Zo/axi۫|D ^3CljnGw_'Q<:HLHOicS˂gO+ZڗT~1)CM]sR S8CަpIkP]qW%ܺu;(L#jYQ:@#l =Y\-[wS80PZi㣤Z[}ymAr:Gf+(ΗTgxbZVJV8q^ cήuw]RU|a7 yMUٚ)P\T:%^tL5Uk^6zϴ`mNI=o8FdqiDarzY$CC^ #LI`&YZhZ*gO2vYu̓qƩcW|ORY10r8I:Syhz'38"!кb<^w*{#RIM1}NG/YⱎC)g|U+CGi#Ǹ>&s=Tk S<|p*\rk[++~Xi͖~/n\[xߚj<ޛ%bMz@x>G'l;=r~\O\H{kHiz~@m ^)5z9eG&zfLpz ud71^i>sYQn5o͸ӵ b'_Lqj?cd?GlMukc}Xg=prm㸎_UG]J|=Ž؛=֑\oϖ y/_\{D8^qLmflFy%ѱM{, 18ż\,Q{1٧Q7e7 '&n5pdP8G2Ma+\|rRi,^+GuRs G+Yt^5xΨ>Cq5gilϋkk1xϟXXoǷ[Alc=Eyr_KaJEܑf{:5t1;j$ d>gnj?vZtmy_iN ݣihSm~Suc81RQT7O%z4eXpc0A80Q|<y}B|!+?z8~'~'~'~'~'~'~'~'~'~'~'~#?Su]Mdt m(Q#x_N7s}?ſ;{mo2ƖƸ̗]>\Z<m͋1c9Q8Ɯtj7I,n̙2xuTy <ة,gMNx%ios%鸞\ƉmC Oi\1兵%sa9I'LvN ˪l$'=,ÿ|N?~+ğul,YAz7iیCˏ%arw+(0IǪtc/NpӮo +,.ZѼ.<`2H"ψ5 \H23u\&#+]̹Υ _c_M eν8[2dҺ ×4xpBC@G̘jJ7E_1J&o>l1[4ƕ)KzP~16L7=J?Si]hV5l10G ޥ3incqlknL]:Vͺrd&2G̵֓!v60 9c>&qt]uu-UG%Ƹ|1j<6}ozVut ǽ|~5utc쌠N{1sy$axi\>oyZm~|n5׎< 7ײtNXZLOˑ73?T4! =l0w!WHMyX>" c!7h YwI>2YVh4_ {ƹk#B95ɗϓ4 ˯yBǵ®!ð>& ü~޴I\$ژ} #տc5_Y/\H~ }24m"Ř_1?=OQ2'pQ5U,`X\Ιㅏm֛m,VVf=?];#髸 _sMa|G%|~1os_ AZc{bBieķٯ뚇(c[HV7y-Hniu&F?|DZGNHv6G ; 2&8}0pX0m/hHcFj\OG65y. [8K}WP /}#p~ ߑ+H<էϟ[_oW,(7;o~UrK~sHÿG~[Xۢb7SPn(,d_i_?hWT1Gп(^^+e1*6)JDzkSGT>Ҙ' k#mLPnSկ8 3|: ?^+//|peszL χ Oϡ)}+Ce8 +3Y+ >C[gW1nq<|66α8ܮ+\n?˨Q4kP>|yg">ǚ4y9a09Y6жlc?$YgYV6MLcOҸf/BV[ϊmyF)YbD y[s*)r_*WDW"pqpvD !Vfo'Enc7x秉꽽1ĶIŶ%kD`:inb[ubl7kϝ*̚&xibbىf _%:!ZT$ߞ-Fo2C53ER'"cY1Uyl1ida1i`1.)f_WL , S%ۘx`Fqy,x#=xY6bߤmbOX~9bwv\DȮI9tq`Eµb%Vg'79o%~M:/;78dGuޘ8DJ77Sr{jro;&ܱefʶWνIBn܎6۾5a&oJH|"f_CNn7J,ܯ.I̐xUwYw|ޚk~q.u/,y|igMݛ?m2m۲ic婶nqw,嶚ZѽII޲uUn^5{p۽8%<&ӒInvu>3pWmMwXܴWtGnaN|N{y;(7'݇Z>>eFsvL>t;ܯs'^;yLq-Y>txl;Coug;<8>ܝ|wx7cnF6)GwgXƝ}Q;؅C݆M}ם}nqnpgnÝpwfw >~Swp3wg,qgޝU&՝tgsg9;# p;yqwܯc>鎺bv@7pYw݁MwS[noFt[M8^٭f[ymno>~^m f8wudT}S=/w|42;f5-;'t(fMX4!S3f "cGxl_o̻UŀO%~RI6Yv4aٹ'TuҾM ;-p@xtbr.ȹi'v鯁c+ّ[&fYMʔ..,j^TSTuo&'ibOci 0!w{@2P9BZ@ݏ ̘{'ÁCcbCunw\½kTrzz)u,wb~)7ӟŝjq}yg>rU܅1G.ߝ+-9cܹ>!7g;^vgf|wnlw9ԅ)RܩiSmz;?s#ϫ㦞?͇x won8MQw&n_=}v'wlي7?w;iG[4vԻnnZ)icZv(4?wtZS>MoLwҢݩָs'$掭֝N.SϝZ;͟)獵v'|U;v{#w%Inzy:ٝ~rwz wbMܑWM{Zwcbs֊wǭ8N[~;ݮ{`FW݉=M5;m{Un 6;9:T3%wmï)ϿXt`N`\k&Ob%qu5sG~13XZz ۞^6C>-{uwnVor*]䴹`z΂sgUpVRYΫ5prW|o{n,tomnk]q6MnǶ].tf۬DM ];6۲MzRn͙=puM;ONn뺹vvipqn)v r;1y=ݿܽYnV%6xmsSZ$Ml-u、ۑn^p۲&]%{vs0]Btm?۬NSC;涻vr]׸-qpѕMrnjۮ6j׽ݸ 6eWu~ٻ9"ԻK/8?%~s{I;j;_-<|>g_n-C흼@ ]wۜ:LuV/s^RܘKwܒ9dž||C}F;g|<7V;G6';Gwr54gǀΫ :;;LrZu^Q+׍{u[g@7!~[GEҽfލK4vUzq[,fZnW&uo&Z{znW ng<:ݭ@+ߪn[;nnr^{8֯ KݺIx{K -|b[];ֽ>J]b׹%ʷsM?札W9V'童MOLrstx}?8gwUpះguKėr~{sPp ;|𸳯8 }= Ýwztsvo۶΁*wN9[7sV;,әUwntIέ-9*aӟr3[m;%2RU6kO=Rncr[x8P{t2فm&>RgOW <^@ڋrͶ$9i_crħ?'˘%dUٺK3J޲BVQ-o;L珲ҞYƿPLU^8U86D/YZ#1?%nquU^o>Q٬e'J}eNR]LS>P|&MS<:ɢ^K,*UF6ύ^lVdWHO}ꋿkj-_GT',߽ ʼněO7-g?Nc8|yqW\%QuqK%TO>9+V(W,xccG_'4褍M;ĵ 7J|y59x&զ](+>=-ϳF LzA!v:iMb^-bWM?xY[9I^2{YY@y53䥗Ky-]U mwnn$׺H6'y[$$yk߃?ʫj}ܓonX8ϾN|,5}ݡ^?~%K;^! dEdn)[+>"kࡡ77z]]GԎާgO<&O^*=_59Y;d/3s[~﯋l/ܳ[,j#9\U\:%V?n*+c?l*ڍ7O޾꠬!V/K6FݰAdIT_?+[LK۞"oxT%qD:|Yk6L ĜzC)?{cYҾj)ڝg_HcWHt։y;e2i_}YOvzoؔo'>eKԮn*vlvwon!OL=YL0SLx'1>Ⱈ7m^Fg,W//TV&^nEF|]jTJbP_G4Oj$]wM7NrAM1j-b;wrp,ļ 7GI,\IO*fX#z5D+ET$m߽ M}›/*%pύDD%o1Xe'$=iM'MH|fMMHI6cQ+횉_^UF 牥/ŢqGde_$oy/ʱ]m։(/zk\#n=ۼ@G \| 'mWNInJbEŢNԟEbx<1ubwb^bb~Kd%Jl9O:6Q,*V}x]&b+{kg*6 J~Wkg +Uw0ptrqɞT-CD7Gf=",ZN a1Kxvgx%p(^nXObg*b.%Jܾ&-1JUz'$޺-I%Vnwr=;Dz+7*x굟DDRΊn$vnM+,{˓ՒY/?U>6k]#7=*<0:KDa`Udx袗M ̮710sU` yJf=]95rvoy?*WvXn{j|O[ɥɃ?k)`'GV+X^sL^%Oyf5_~([R~mUl[1%cKKپ`d]vA+ hg_ٮbOܻؾft=gտ>bj}Økwvkh]tsvMvk iߐ{ؾὡv~S]yCw|uv:#uc~b]~oM톝ډﱛ>c7-n'Yd7ynrlvx/ Ԯ?c2˱^#훾m2ɾ9f;Ůj}Mu#߲8g}̶{nD7m9[\1}kۇ&챛oXfevgO->b7O-g7)n5n^ynmoifSvͭ&?cq*n~aݶ4oYVώk]K캭;m>8b'\Nv}/#[M`[}˝'[ƥq~bt[Oi7߷3[ujkz]v+^KmӎKݮZ+Ck-JtL`_S;mˮ:b;p;ל:b_k-\jl߾K\gx]tF[ˮy^f_^g_Y;.=f(wgdMSk_rkR7˷:ߔFbvbm}}ؚW^4^SIxJKKeϓWW}K^j dR+ʋol"޵E^-}^ȎĴUFu?[zA>+:%n;rĚr#\~ս^ d[F%.>n.S}~7R>K.svK>i=] c^aQ5ؾ5/sfڗ} KN/c/oeh_<[K`1.};u2We8m:.{,2fڥ&ڥ.K.S_.tn.]_a[ɳ?}|2򛘭͝]Kʜ%UdಛW;ΆrKˆdF2rjۦ+Ϟ/K.K.Jy%Ǻȷ~ܞ|k`QKmj|ҟE(~CjtlۯW^-g$s\y\.f$\ph9}rfJgek7 dk.HW?\򬌛=O++~s,?1V^)qFyݫį=%xa] yDYeͬ:˲=$K4_~K8{c,W[[puzI^nOfdO~;3չ|Ϋ^~WG)l66(nT-nZұd!Q!·1ʷСtZ:I> ?#[H0'ٶLF"u@[W⺮DlzMT.+Ueej/t}5{"BT֋Q !cJ,O#"$K Hx+f]d}>Aי=[65LdAߊcÛdo gf&+٘ll]=Ua?0aYx)3YX1-l0 }Ú47"?dΥEZgBolWқiuЎSQa3Yt^<_B},ˆ\w<-C2p Gg"QJfcV5TFKw/yG#i&mIu'J:i:/w'󾘒Idoӝ,YH.ī ʎX?NGZ~k7{tv yoqxӅ(lmډhg㩗<|w`8/6.WT 1xtE.Vx=Ɗ$[#f'5 2stG^[0ZOhxLM >a^RuW-šW3"<xk?xAgWhOwփĵfAG</B[E -EV k3g B~k8<-r;!gpGֽwJ N:-BM_8Q %2pNЖ OW}4ߗ׬ ;p!խ}lV1p?}/{-,x$>[ac+–iY8S:CkůtSa{ o:X35k4j4)Pߝgz`W |>o+,S9#UC@?;EV;2{ppuZp i0xDI0̳Y/`k(l+!Z'b ض+7[WQ,\Agn ~~* ~" A맣~;ЅTS Zk&4!3/[Է^"D8`b 4moQIV|#a s~IL ; 6 jVAqz g™WMhA'(Kd(4;}4gZpC `F58YMѐ:R +灸6Fz0=iP?*{Њj@gF1hnMЈZBa7 7`[^<׬A JFwg  `E#p<ϨE.-W| y)$;ΫVTf7d>Ȅְ 쀅 ` 2ܼuKas=3-lkt@ozæf{ecczcx+^Q]Ax[eb+bFJA4v㑶l%=}ww>/m>{v ,ݘ :.!G98+E OSBS(O>Dnk曟96ܞ 'x ,0]1UaԒZAHiDqNT}DŽBeVnAt]kSbw8^vAH3ar0" J[ VJi&oRg:jS^SMҀI t3]aKYu.̨3?t>Wgmzy-􇈵L&٫[Ⅸ¤[©P!<v j{B=#ݑ|SEbi;XjjT65)bfm,M1B6cbYkK))SgmHve;Ty?f4,W#u;}3M1b;=kXrۮ=%nb$:%\? Y-˪a9G=W+{+Ǝlc\ mβfe**gl,URYߏ^2~c6Y.2c>O3ؾ~,;tf CXl:Xve|v9b;k:ٶ4bTCjlAld}< `nN+3zi]@3:E;|h{ ̰><޼ח2ZI/N*&J5mi -N'RHzN^AɋFpԔ6^MMLji}˼/,|N[Y fNg}WR3ϩ<כ;䩫Lɢ:M[iH}x=~YF$ vWu'@α 4RFL2ɜBEd6q6^{ʿJ-եt*|> @xˈ5VQ HT?]$T2#u_}])TSӣPW<:5d::1 P״P+JxHf%JeբOi%:n_k )-4_.wʜ;YWJWƿzNϘws܍99f~]a݁q</4> 8w +J+J+J+J+J+J+J+J+J+J+J+rQVT,y,*qq DELN2牨Xn5!Q=e^xk yu'~2˫+ok6.NTdmBQ@Txš%*7y" EEQPTSxbت把ޢ"煨(=-*E"]b[a/*[[ oYbX8Ƿs$KTD)x| QQ9BT3F 9cߏ>nM?VW%w+YҬFO}k9U+<s283.˧pZRNJͤ|g궿I[r­K? ws8Q.Gmt>s`Yw.=fNKca^1nWOeOw9]:v3ٮC>lbbsl}W\c,6RKgd]CYnc_5>`eܶ> Gݲxߩ“|?Sh=ƭy+pdvxKP:JF,ള54Kcp(@U-d7(DfTd8!HRtBrgH>I*O$R#yi$?FHNTIW#yjK$nHٷ ) y-v,DjH 6sB\?n?THAc\b$nv͐'@ҟ]H~&!'!?7$#6&!^'OĻ,C|Yě#F=aH )H𮃄c BNHX#F|WD|o]83|0">B 0|-\ʆw<|i%][ [FP5v>uG[J^+]cќBn Bnc)fLnqc.l0 l:Z,:$4ښ:mo Kg7Jb7SHGt4;[)頏Үil4㌞4OI{HiEFBJ>dnSf;ҫ =JakNtՍnј.׃y dVts|M+h7i/7$STןHM9$@w9mW&T>H-m*oZO#rON 9ԧg*8}27G>z(O}lOn v-~ un&Խ6Cd('/͏Y6ToXS2V`?Oy ۺP EP^Z UP >USP7*h Tcnb KPgGnpS؅}Qv_xa?}gIvarv7a1ou}=î0va{>歅['@{Ժ^PPUXz]j'TjAeiPN(@-T6P}u]B%P׼ u0u6]#5áV jcPѲîqm /3e9z:KS>:jPUAPM26 'Ae$k_CCmTʡjmP~"-Jۡs3(ǏmA؊D(uCYVw#($u%(܅P۹Ka`;% Z&ѾO[f bb+ُwl ^͆96 _5nCVY?S/_ͱ,خ0mNΐE?}; cHl~[b۾^ë]cǐFةHĮ ^N@f-l?žS,v Y`Ee|jR(>\ β%jlӇ/=un(<OW__5}d8' pҿapgpvZo\u:h\^mpkV~ʀ[pcv}xO_xm6)xmiwrlzkE4^EZ^:?y|<=\kp%vk8 ޽+\>8=׆Cp;ӯ<·E\v}x|U^c{7I&H)ri6Rk P3dK3&+; yu‰}8udݴPPQ } 3ևpl>qip!p%\\zqG wɸYe1{qm{Ux01 a;Q*ϡ2K<ǏϛLf^-y7M]4|U(jf5>kZ,h𧻓z;~tWz?W >IbݭYW]ּveX{e־yu)YgWy9uc_> W462 ]0*~Vm6FOxP6g?#٤67M6`6lDMBLMfs*v`Al^>-,'E^W켍-}VG\+Ml6Om"m ֩vfGoa{E aٺp;aǂ$,L?iٟߺL~BçhxɎ9.4 XDýi2hXMiX$ \&Ѱ3zԢ߲z4Bmhd!l06>Q`'-ч4nؐ?иBc 4^ՖkNxColBcOԥqJ~Dcl4~UE4O!a4Biҩ/M}Ҹ†wd!(Abwgqd/o%8ph|ZHC\ /D/i\?ƭvѸ]wEgh䱏F'0u< 7tY{.49h8 4l[Rih, {e0β_`_kyRK{{*zQ ٦=e{ֻ) /Q4IB;gd{O|ICB:6Q424аlO4 ~ [wihSnd_Iц4:ОFi14m`I5+iMniwNeS{Ҹ\ý4hN4>9ƗG 4>/Wx!OtR4,M4&t ~ ݉g4F3@ iԹ> o̠)4T.0F:4x'vCȽ4[U_FL ~C#hӨMlfOh L;h[i! nѰn> ѰF kʾPZ~" Ggp% {?awfѐGed[aAs|u>GO{,w4̗r>% 巰4% 4hh/q4tp[#COHϗd>g~OQM"Fr&|}ʴiڅN+~FQ4Ѱ̷!-i8Kֹ_~72~\G_8wQ+ H4{hpÇr\3TDP)GZ4iÝFhT)y9hOh9G3]h>DZle@Z|{vWp7\p<ŅۦpQl.^O1emjp\&sOjV^r'W`k\,Cy6|67vfdžb/'6g{nߜ;FqgB܀s> :˽L('i^T-zUJn]ZӮ iőFthp!u1niO:==Hg~t. t9ړ#z5n[==F# =3 ^ugkGcz!ΊkI/_7Tt/P 恣Я6x ц3l5#3AN :V0 C1$Clb -0E{%~`x 3#eD#02ȟQ %F0~FK7݋?&3F7c2elJ0n`R1-Y}0 22 &Z1]&np 3y&ߪbx0ELfjmȴ bӾfzLӈiO3hӒ62-ЉiA"ω]fխL;߇ig2 *5HW+:}>OLQߙSea>L&:fmͬٛpٍU^3s/s&2g{s`%.kQt/>a@IŪ GO?E1EtEἾ/b:!ZߤqRqCIö&Ԝ'MYUV()-7QZU&myU{y/9 %$Rw;)Os)YMNp/[ҍҩ[Β%m~/.]~'ݨN*pFسXzPh'YKn^;"Fz]ea[1 5jGY3PCrC.k!jv8[&ރ:J@Ӻh -AީheZCѮHL@~.;uUt LKcL Ըry[cL]vlZϝ)2%Z)cSVfʲLhŔY ̔q2OfJ'ǘ|5W3#&߿Lg&3S&?:/?SzNdJNLi) -e>RË 21$&FL6(cҫLaRLgqLXg<=q0qz1h cve̝ѓ1Qh8Q5{4#?~doF6gHFD2bo_FX0bx9#1>W>n%b +2aXD5/dX -Ϊ\{ YĐ Jb\=? Ycxt'kWxp})~/d|L豂W[$/U~~;ե_Q}oI>}7a5}}w*.s}C߾mkK:{>/М>7?J:Gy|}5}>^ϹE91>|s|} zȘ!uY/ϥȠOV,}2w'}R'(>6ٶ>!ek軳)_B.N;׈63G>T򠲀 h *ܰJbо) c [a o1lrF)d h5i}10Gq0~?ńŎL8;#ĸLZIg2YgJLY)L)곙 6(v``ۍ6K;mͰcCX aۏx.ֶ[$~X`lҍƦu{))6- u1{bgvUE۱{iʩƮ=au}u~O 6}a۩J(g?jL8GN/{ \8p<N:6 p pySz"\kQ^[1BOw(AoOCȂDuέn% 1H9 iѻY"]Լ_?gTМq6N3fqAoo7Cɝ??:4RKqe zŵd\ ek\T4ݖ?pw>TDh\s |r$4½pOịQ/#m wgg2|;7'-9'nl <_w0!PZ2m5f *"È?ȰȐ i`? Jn38| g 0w6@XzHE?r=3~b! Ӳ!wW9zktSz>F-xџУiV}G7)t}Gרt Kt=׀/:.ItjM].1;JtEĞΓҹ<:]GG:ëtL%vcY}:Zͣt<Eǟ=&{ѡԌmi^;})ܥݧNf Er~+9vy1Qˈv/IٽvmՒ67z mSם*TSuCg.Uѻ*oCTݤAKۙT/e,U#y˂JQTEez*4TޯJ* cT.u:קJ~ZRmMuڟT~DTC]+1snB#eԤj*?ʼR(ydģ#Uw.RԔ*gp*LRW>GR5ƈкT˲M\DeUg-fP#ӖIT$Uu*KYéU2DsmNYho.6D Yo+[CL͠(_Lu+٫QT^*_<&jdz(*E)QȢZ խ_9H==>pH`ӀWI=ޑkmg;DdYq]jy HΞk Ƕ_vusDl9"L8G%pq|.|x#g91c4؊{[Ъ,.*rA׉CNp$ :>y!UVRBչT9v@ dHUTZM}XK{w*{Qi,ߣITھʧ洵N[!6픴2mD6Bim^MC~Co)q ݴ{5KW;~ODnb:/7tu=Z;qK[ZipEh {ͥpIsC.rɅ pΫ}gٚ4C3zl8Q.gM)猠ќ;qP߹Ug8yN/srԛ qxZ}6CF? pً'cه5ػ{waЫ^ vVa]`7Ұl}[M}l1M=m٤E,SDf^kgX#Y?]Ʒyh:fkx}&^dmxt? x^(lPokZNl…8_67:8x v7Ʃ8c6-pS~#G}d|a?; #)[~9/ѳ 'c?|6}AH~q)V"eR‘" R;"u2.ԅH5V#uh"uI|DJT"R!cs$#yBW3$߄ēHy HXCb3s_Y1ϗ!b6E?HN$ a9!a`$=H> Z__>[1 Vzq ξ>bc0Qee V*80|w7x9d }¾ء¦?Xsr' fcax\I/anf|^][ð5hmPgbǮ:һϤ yݤS;KۤUȼҁ끤\_Zg 4RnRO?^P\qR$T)Tt_׳VNN fohǬ#30`7tc+E_`\ǔݙb?.Lxћ C0~ye/bΌ1;}j<>l`@0ru#M|,{/cؒ Q?3xB220'?DJ,>>5>hѯK}OtzBeј~q=jmtlG$s19.DU6`<'ӭEk'5G4:y= b~q'[÷l8} Wp]C8~yi=\ag]8%ax8>'va<vczC9Pz;uUPu'y)wZ>z?A=g2a2 v*#`0y {A#gag {9gl|v?#a kM}3컘¾gy+{'þ5`_/> ؕ.b...n`F^;*oa76jA}Jo.Ԗ<$뵁 ʾ; 6e<Tt+\$y!<}ڰם ٲ~#,!+clP_ PYP*e,C?wòpx.8իN#8]pafp)p<Gd,ܚym΁pSQ%U 9Up(ͅ?W=x)m9s~5~zO^F ÿ} l/Q Y~?X<1! m}P 5<f@ #]??M=&K&ޅ5}}~ ~ry-'ÿ(Y;~_9ޭp8F Ëx^kwX]&zx<p=UKFcTg>kek|3nw@Kk+0_WXUdQ2߰W#vZƳ윸#nFob]2/kjԓ]u; ~n[!vZ{'cOxӀ=Ʊ{~S3u¾ϐvgχ}/&w`<ǁKOq [єN<`._r琕ZӑCC]9lxis#刂dD<QW9^csv<.>˱;p\ ǹ\[8~X [pBENܸGrNPWuQ1͚;;ɮɘ2ԖStԵu9{NIt]232&sμNs {8sFqNq E<3I};1s3ѠnѰ~LJ-nBN4`D؋43&fhD42)h+Mo]uq4;N6h-ߡE7bCMZd<Z6E˱hLeZ'-ӵhF#ZҮ!-w+-MR!zL˺h-_"b;-TX6IZ nE{hQ6c1o7zf+~'\6%gSkjӢa -=EZJEٞ\K]hjF ZrZIAxoӢ,GZ6NYzΥekKˁh9 -rB=ZːԚ#_rH-mteDҲܾewZvE6iٺr?7{6he=-iӲ3)e \hq,s-6b Z Dh~͓U4WGr0͇Vͪ~f/YpYb=َ4j)/:զ֫4GӨ4ͽ@Sљg[ӴM6uNYO4G42f#hf ﳨ-͖4[ 3ͬv\/y.V~4Nپtv45;lk0V C4Y4Eӫ hӄ~4G%ijNSrZ647KO4s#4]䱍jnBS|4 bh?izeM_ϖ\>=Ji(eY*&FL[ Ckdj M4>M} =_J|SyL+ǫ{h:M?˾Q7fm6Ҭ*h4G!w`V^nwN麃4]%9M ^Ԥ MW%Q>G%M+Ci}!z< ]hXN*0Z¦j.l [Vqa\X:urA#.]-`R.1kb.h iqA;\P37AοpQ+Ώ<_2ǝ&9šb9o{hB˷?h}B_K5hYRmr\$-̴iYd U-˱쵅od_D#ՖR$;VُI}l3 WѤ!~qwѦT M iԙF۝i4CШ`A4̩OCJnGyOi8 apjD3i{# r߉MZѰsE ̎F Q}H1{i;O M-r.I+4mM}L:r,9l֧KYWBh]-5y=99's\B.,wᢕ \vpK!2.\6'gry}.p+|s|^DV\5Wwշù&4k>[yOZ CqT97ՎKg']uAĭfՇ Hŝk¸k`)w}yؑ{S?Kfcr Q㨒ʱ)U^w{޴ۜvi2ѡv66f:?BtO&t9~$]Z ]j$]+J>99=NJcRAOa5^ z>ދg/}f'Gx/fVӯiѿQOW<`Q0Ȕc}.,Ay_61h }< 8, aȹ& Р `\SW3| }bDXW1ruF_dUZΨS:nh{1f3^1;1c/3f\Kkd&1) t0gbl`_LC_1o ?dʌ"ÔOL܋FL)fjDS?fjAS5z,":26zbG}L152I.Lz$Լr`^Lw5Ĵfhȴ]-iW3OfLӓ}3chfD3-fv܋.̔svĵruc:b`fƜZo͜WyvfJ]oS4@1neŲEw+ӯ*2[* U]nxf`rqdWZt#R+)ff.>K+6,g>s }Zok}O.G!RA7 ~M7}%>s z'D-==j.Ϡ-h/d jG05m)i:GҩvqD[tm jIet􉭔^M˨Bg|6\yIf/"FqStk4h"$nRT7MXqrC"ZrbT3V]̏te~l쵲ka֝+̊fF[f-f/,|L4Lff7('ߝdf̌K~ӏd:g_fz0=ôLXi#*S>eyL]0i{<ƔIL̔-FL1|ƔQL̔za+\|G29 ˘~Ɏ7 uam2*$X1DCeo.b  Mw `P oSNNg5} O'ϞY*gϘR OyA]MD#Dv@oU zoF?= '\G_\2|X27-X>ݣ̓AvW 1Il9К_0a/2t 7gD+'Fzȕբ ~s1m0&{=ca0qf w3P%;?a]4۔IULf;g-2VL!3@h3mC9vd*y8l 3dʗ8<?B9YL|fjb݃YÊ3u>c!y891gMs2ɜ_Q4э8VE w VQ:pT+P_QnjKţozR G6=$ѮӥiIKI;3K6F:0PHa[RڡiRޯ~RqoRnͤGv)ҋ?u/"֠ƕ٨*]ڝ uDh~jZhgou֡,tyGAo5gsn_W]_1PcȢ -°TG #'¨S?cka܋n`OQ s0`ZH8fԺqug)f{9?7@MCzᅹ%0`%[c=ҡUsb҃34saΌƘzݒ {{$ h%4= k`0?F /`q,XylVkg-Xuy=>#6,7ņ_QMu v'6wǖ1&>mQ;nݩ v=nSƞSM',,}=cf!v߃Sb{Fb:ׯ%])W`qlkPZ߁TAFPu=؝k`{m?W>SEpJ# Qp][ zcu }6cGWóxF:אZ ^}i |~foB-/DĀFLa==ľ옄zp8rG,ñmyk( ghtߌs.fX\6uR;v޸5w46qA&v%@2^HDۻx</xROǜ -<}gFUx1BL3ϛ5sx7 mx>{Lh?/ E%^u.ĻIax?GC>)l_{xg o4›7 xW!xL<[m3Q 7ގPǝm(31MN*W<XvE$3,ƹ,_쁒??Qr.%Q(y(%VQ(~% i}'WPv-?G(5%}dkEɋ(sG\N ùv}PvvݍӃ!?o.NKAV8d)Jo &"r#Y/^pStm|S[asX* ˲U0}vNox ~{ ݈G%h' z,=WHW:6|RKHKtf%ʑjv_}ROhYQك3k3NknLU~{ƎI'0MN/1Fet@Fu^}> q{3D*0(2n-yz0J_?F7o8}}̤Ok9LZD[Ċ^3φO!@^_FCՒnw6t/S>:mӰ :iMc@:~YAǗxS/YtLNGMqБ!tlOu0j ^jNCJ;P̥ݦ[ږv&C#ڍYK6aKө~/Oux#Su{$ϷuǼʩ3]TF%'Q{Ֆ%TF T%Sy(USbww.S)Uv1=TYRߏTi*9EU<U(ivR+*TeSZS͐A\{zn&T\OUX UTEZQuUOéT-{ATyeè'ˋiTje2)Jՠ_Ti$꾙.eٯː"9mU Se)cU2?yl?ڴ*JzU=uoF¥K]T6@kQqכ&[i>orj[*WZR$1yT6>*9Sٶl9IKTWS)d=hCՄTMDbZMdĞ6u_)9B/Vޞey ~:hxf~|DSەњ㚤E5G iζ\?Tּ{h(ZiNSDcEWbb;/HLv?+;ǝ 1XrҲ=;Z.{F JS3F?^"_V cµkpA]q3Bx Olc;M<%| ]gH[7|S?8/_#oĉ>L-*_ty_75CRaV_m+O7\J'"G7^OTᱬpqFnSU?Dd Q9=Q8U?߅sa7}P5n/5;/vg :ao!zĘCcŐ65AK}vhvr 5Լ_saWM)MbYʾkj:(Du|MQ$%Ջy'.[{N8AMm GYz1`j6{&zfNA S? u:Ua=6^ ᬙG#ID,EI $Cj>49;qǾɻKl A4-8Gp9.Q\3 *q# 7+fLދ7pC(z'{Rʋ½(ϪLG֨ Fwøפ5|{q\M{rz?ۆy݌~ྶ{p+ vu67Iqh7{W-p*3*<}w(:\%8@ +p) Wvŵ~#7-oVQ9nh;< 7y$Xpds<ߍh<|r?R{*]}<+c*WEe%u#k)o) 8x.w5ţxtrh}M->#Q/JTkDC&v |?(*߈UrMgsb>uYÿg™8 Ga3 (iB ڡ0?5Aa~ uCEpOIQ8<iG_\_MY; ~,@E~݉ yqt:*pjCNi;p$Hi^f8'DqgȺw'Dm KVd+ Ͷ;M\!n,(/̡9?'Mdo(ri (zbLo~ S)#P}̋8SA8m,3]PlE mX5i \;v;Ng8}:N/ۄӓtGٞ@yƍ,])\ԯ&"4(iMhz}F%e8foqFgnlY4&ߛU@ɸ(98%pa_w$9%>(q]!(~ % .dx@I(zrNP*rr-MxdAZt%g ׁ&{`q& ߸%=|sQ!N~Z86R+pt%çP.v 9qi)5:?::9n02 u@4$;@R$$lAF#nȢHFc¶5@rD,H^8猀&80G Vg|zgux2=H s|m3?{,x!o uoCm ep{݅ءk3[l۰zLbyb1Ni#f]9Vr1aJ1^ yc~s?F| AB< }Z׈n ]NY^_,=zPtt}3JRґgREw58C XR|Vr$OxFZ7_2^}4Wi@l;ΒVfQ$ͰP8/RwVRPn@ +&5`{GVpIyK;sME1>}4Cr5Qt9[?@h`͆AfC4F4]J5_Zjz?.Ҥsȭ MC4n^{^pu*Kɚc/E.B!,Lv  o1S1daK1~m8V{q_L:PHE]y5ČgbEbnehx0]]X&[;E}ŊvjauJiRh%֗Gυu-1Ld"4ƭ6]rzO궽raq{O+~)rc8qp݅SeifᔼD8]-[LK^ jpM̯)\ K¥rpyN%\k ݅qvZ^n ʅmp '܎n­p]OLK\ wƎG7:h ZxmsYTCgA_xkؤkcOz?#}xm(<8&<~8Ax #c91hsʚ }]p&"pF.Z grpr# k|tF8ԍ-⬰ *ݖBP[ UPո/.BPn/T=`PvӅraw倰7-O 7FpʄOGiȿ7=[.@؟?#snJ8 "V hPtX8<8G:+8 WpJ8%dpX+ve@pVOTMSIặpMs[u­6p۠sK-pu!\C{gҝpROnQCEpѾ-\b?.Fɲ} ?YeuN_ e6Ax4.܋ w;P*nYVmAc6TM#&3^_KݭTJp?9E]'<M=qeca~nj> HN|w˄g#CϐCwJ[pY?kEPoO\+Zqځ"jn+ok\;%{%k#׺p9N9T BZ#M.;bcbʓbEt;+10}T/3ML$>}A3DwDж~&7/ZML>Z5?jjԼ@Z+5eknt]bUse%S47(DS6@sL)0xTswaH+M MEǯSD?Myj͝EC5}Us&i\9__z&~ZFsPWYIgQCm1n92 >/? S{Z 7~vs{_e/ǁp Q[B" -A)84E` #pkP D`o%#e>peߨ-si\܂R8n5P_헹s}>ƆuXy/F{P?Accqѫ m6h퟊FK+_R{Rtɷ#h(M'8XCq3"@몢ט'?-/jqrY] ,*>ZL]nfKKU-43W8i,4h֔j̏ijlDkghGk@S]h2y"4%5+l!:.cEUGwSF,ze׃nwc$~CƈĨ9Fbbl 1^1[HVYɡ7nqPDe )F 6]0鷘"A1~bڌ$1Z1WLo~YL=FLs"W7)٥o\+(]3 9Y I M bۙb_Xk etp^q@sL!N"|`Wy-ۈZS'g*QU-4}E8[+^%%KSEizqq[qLq%F\˱7ĭwŝDA<$*o(qYBxYSVo~FGmۉ7E( 1!C|j@|[|J^tG- -s89s|%H|V|-ln"D_XmWR-ķ&ķ՟ŷtV!7Eu>Q[T$EFTH1BTQ%:!E˿|oķ~^*>wϊ7uīYg'_ӽ9*xw\ڢl*E\y]".Fř+KD_8QpA\\k#2bo?E"c+Y ]GMvaL췴f6-wѽh1`bbb1wECgܼh5ZPsEmPk-G ~5_k?ߠ91^氫Z2m&j\s=5K6kKK5;ii̼i;iT~ y钚i́ nY)ȯ ~s_yZhHݔ7KwsZS.PsQ\gŵ69ږRO>Rås%dV.Y=)٬8#9IAZRAt|I4 ]ڴXUz;SzZ϶h[cw V%c~~@q"N߅Qw)a0`Pۿtwt~3b1[E`I3Grx[ug.bTlMͰehCXmءU7v{_O{؄oO4TCJ@dL΄} p%/ӢYpzPg6p7^p.s5h/鯮WXKL<G'Ê຾\#Q&|r[DiWw..'exJxviO@x> UޓZ>7Ǿ@s;|}vv>F6]?ӓ;'@h)(*%ql}7"3wF2Fذuow W#%D:mGT:|} :hb"f ČC̃<"~bz* . Nͼؼ3= +qC"7;B#L{x>/tGBH6  a@HolS$LCIH>m㫈 Cƈ遘vx(|# ň ["-}58NFtYto=bE{ |9R$9|"9eR2iKt駖!cd<ڈLjjϘ"gC8Képdymvo[!Qؑ8޷I8hN8ĉoqr SWy6"8 jİ4^ ДCw/Z<6q}]o#M g6H6"jFHMy_n;\*bBWz/ (Xќ("*͂b޻HDtD@齷sf& "bî`o}ݽw޽o|?3dL<$ُMKbYo\K>;bt>O_{G;7낺q߃$u 3YkԃMkF {w/g,7CqP. |YHW׈!HPgRjQiplxmJv}%K2;Hzrx<} #gəQIXa4I<C_vv:k>IZI{u$G>|IM{3Ng%y$=IE; ygHM~G#$(XMAM ?䬝ID>TmH҈rxn>I\_B=ILWDD$q(I>$"T-ޯI[+Iq! :IB30I8C$a$މ"0?BD~*$[āy(E$VL'1sV=3+9D?HI$QD6ukzCHÃk_!Ms+H;.=]-&aNtbrZ>;ԯ$4e*9=6+WL%!%$"rkH5$jH1rC]dA{HdLL"K4D'Iu"Q$@=D,>G65$lMr]9'CN[KB3ɩHHGt'  9BN$- ;1ș&rp2-ٵo&L6#TXBVM9L<&n_%Y&Yx̛>Xl$%_} d_dҝO8щU%*Dp;>+jwk3צ1\P.qB 8ߚܦn<9~ f{)Iv~:gRU΍ O8;nNGEpsjSuFFHGqrƜ[N'5.g7j2'q'i K=Xg%hioUXo!H ]_ﳿ~?Z_qt"vћyC3銞̍ 7?oX vR9Y7Ƌݖ_\žz7#5lZ [kw׳َ \,INnBn$)TrWrFNg ɺ9C92O9Z0YFqv:\%ܜܼݜbnqU3t$sFqSc%Rn 7n&Rnk&nh|o#pwrN.d.t?vJE,梺5\ vCHAr)ɳsB.mǝOp2Csy#Pg2Ww^̝{c7Ao3J;R"CY.߽M>,M<Q<,OGN"Ww6fr9\3%~rQՅ'*{qM4Ri+wq$/i3zF.ɐsJKI WUZ5";;r;o<%idbgE4R^lPe}Ow/k:p+ڹa\pX$iP\>[47yzv:WBScхPDb@f`$(((Q.w /@괿`Z@~.)?Ի 0{߳:З4$ V y F 7U=Ly#W`αRChHө]kˏL^_s%xlÄ.Cms,ػS觧٥C*ʹUyO=7 v.t y3 ꤒW. +`xA){aH|11›y56kQ#l7Fx'S;r|D+\2ԋK4;2Bl>ΝETqyj\A+WWԼ+h[msrpvr<\dM.A.1ktyk(޷rY1ﯹ".'/˹ܺT\`=WP=8ŕʦrnsU~\W-~ef*q"ٽc8nC'Gr\`F w7{ݖ=={z{ӼdF&RcD9ݣm _דP&VonR׈P:щ{M! ԈO'{#zN$T. ^ANϾH"~3\lۤ3\ZA.$֑ [)HʅͤJX"uȚgM±~E՗\<46$\rf2iEj#m%359~r=0%7SHhҾߖLI#=IrDrw#rw0\&m3ɕz+*H{{NمP$ {HKp0ry*.z)0]t!®^%GjZI5+R%SyÎT<0%l#)NJWHaR`L>x܄ $g"EB~9y%?0;$)& V$~Y}DipI$tw y w)I8GvI6+!k-![Wn&p z5ߵ#Y΁ztr_s/JZr7Ꚗr0j;c85s#tpU썆"6ɿ]l+r~L']ƾApuul~hF L&,׏,&'RVAѾA${,>/}YpQj #W$o/G6z$GXJ%X=먏ţѰx+ZM3Ex1xڷx4U>{1| g~}gǖbY/|?e) S/`1vc_sضx,_`*!R,w۰elO^n-n{dחxF!3r?z:$O`s618)ӱ)xz6MlZTx|d פǭ?Ml /Exl Fⱱ۰'Z9K$Oy|I4v] -2Z9B9d|2cx~PYzz;]7?>hmĻE\t*_qLV4 G2ɚK ٞy6K|_&'H4LN#=v)A"w!QͯI$fDOn$ _1$"}q]nKRoY$--z@.A2uHuJ,&y~I=)S$ 4)%e,T=I*HӤC7n'5ǍIˤjs4!upC"ND'M ]M@š>'luV!yI3j i;x\l!M"{<psrɄ%K ɥeZtH˼Ѥ%X\A.Q"1iaHZ#J &K·bU!&$/"ךLȵZmrr̎\*XfAnȍSH%MҞuw|1t*NDY2tM'grs}8iMnMj+r &t1{On)fCnZ0;>tדM)0tJ:N[~G'bEnL$)k۾:HӃmror>r ry5i9uK\IҼM?ƒ&xr1&&FhIv!-N~L !:{p3ajB^"RAD8&sHjsդI }T]2#U dR:TQ&OHQ,wud0R`@VƟp9R8$!kH'?R0Tl_fmIA=)TJ SvX3?&IYDjHSRJj>&5Ix TEj ΑoIg qp!5%go p=!7ϒzݩv&դn44CKEC`C.'M5_4AO'_HPSB, DpwX•8Xk*a$la'u4&(aVI:l`}N0=cM՝9f%~!a'왓^J+FvGᵄps"|h7D!ŷ C{o=~-_ϓH#Ҡ_IVő:$|Mm\w4tTܙG:>,v0uسH>鈉ucLsiBI{]۱U|A#49>0cBn&s;\1=NZevVkr)iv$m"~SH},!)q>¸/&"SS"'I-6Џ_ _BV:O* QzE*ߒRLʗXrٵARVDʶ$e3{I&R RҫDJ.Ѥ$)IjcINR2'(&oI17&ūWEd^R<<-痒[kIɰnRbԐҡ!R=.?EJR&C& e瓲svm)7 'e뛭v:E*}JvH&RST UjR@ >Z?IOlNrkl?$2zItM$arn9{eI_$$aq D$vi%ȍD$l %!ϑH`{O&~)rl\9HչmVU-38F:ޢedx2I,=yN'Dk#/'2X)Ʉ|fOb ”\L=d nB/neT9T7]~l5b:xěwS[PB@]_0UM`pVh nA+hj80jf!XJѼ]u/a,颊oh[/^'E|';zMYZogWtMI]{?yAP?tDmsG3< ^?o$?\-q;fK|߳]u=|ӈ{*pGܡzonk^e|Նm*M_Ys֟íYr [-ۆKwz%]nZ"q n gKL:0Ya PߌYc̘W`׽Ƶ1fW[+#qőwUklqV\7 ̜;Bׁ.K:e]ao,;m͒X|[!n7-~U`,ՃeU'G5$ qT/?ƯZ?  ~ 3{US >euŽ(KܛG^N{G >?ڈ{=6^{T/~h^g~؊[Y?ⷹ9)~  1of$5sb~my z1ů gfu~;'~ St¦wo{q9}#yM}C>A-[pߜi }q߅'m ?݈?چ?%}q_2;6>S-ܧh{r7{=0.Qu"v3~_/eU񳅊=kX.t#|G35whv7M6?ol,:5WpY!.Up?Ty?Wܨ8GV8h8> v-gO<_NJ7qď|ivfcۋ={x뚙x{W^0^6xEAa6y.mL~`AuLz2U?1ta5Q-b <5r2}T06>bS"<['T{FSq'q:UD_7(;Gc*c['7c6<-< ^Vbl]7[^u]:X4>z`.Xh1ւ2X:kN5d֟C=?x> D1?Y;b4"`F?_cS >戏ԝu8xj1y+p<;Nd;ٜlZ{g^o9Y6kِ7W7Mu`FszeዖOqn×J~jI­rpMN)94W[6jӝF6 qg+n;ыpmpUrsJ ~`-b=xv|iDN,M.4nڀ/Y 1g%M_n72p3π8?* y~ewnZYR]ݘ lyff 9K<Ԧ5'p[W݃]\z+.ƅ@s ù2Js|q~|>kNori7ԇ'8(lg8yN'> +:psCpT!@G:8  ώa.iu:z7!e8hI??,'S5>z:>l}k{1xg0޶ojxz<+D#b#is ^ ۛ^vmAcځxޛegjZKr`Ha Ž|ZbbSxAlmxtmƣ^b%Xo^ ֵ=/uL[7k7UamukM+XzVa7X.V(G~{G#w#OXaVx+;aMa aҍVaOX6hY1KVb) ,9۰æ8;!aMXWv_+ ~Č||y" >; ^.x6JPIpffc{ iZp-1N,hQ%h>HФRp⾠qcatY Qzr+YiE쁌;ljq\л~˹WvMOpD]8mnfpֹR=QýtWr+7aV/#D~HaQo&hŭ#:3! mdiÐHq#1y9yq9D֓5ۉ1wb󐌃d\-2p,eXB,)iBu"JHh2@!)dǟds2徐-M&qȘdDzqODV) sϽ+=1puaMjRsq/\r/w*q! \5.sn\H ~ 6;͝L22hE.(p8wfwR/YŘ2r;s:Fm"ֻrQchܙ=\l.~-ąʘ 2*g\l,;,Ll#hJ1jJE 6&$e ʗ\<[#Y~ˢ%XE׌]5̢sX:~;r)=sa{ 3I6!0iCv18|u%86%8Apo'mI\qiWC'ZXc[E7q8:OO;m!8msOahvK.˱ÔTxӹ5ʻ}`'3kmEL9&X.-8;z:[[ W$6QH\MvʥVVc3T\bYd!L!ļ/R/?*5;X͛Q3kn+LVqtUraJ܀/#SC#dz1eWj*N˱L7cY^gJNaڃý5gUկY"m ![6S}+ٯq!q %;ll \Y^7<,5ۀ2𫃔Sa]2rqw(X2 ԤNLGZD?DGung-"=aODFEpbh-cWDY=/hSƷ~SyQgge&2v91ӿVRW6}d_􆈐I44\ٍf" UȡrY-RAw5@ҏ}"-hx3翖nTK\H,ܥݢdcj3iWU>%M,BIz4:jPQnT~(uTʌr2*4}*֊R~ݤ?B/K oү#E5;4:QE"V4.@zn:ZYm!x9 qDQ(4CGlB;5FO"6hbS4k( E6Gk&#ј.d%&@f AD# 1fD3 Wu$ RUDzGg7f:Fw4)'X4fԲ^fm櫻D LG [K۽>اdäi/L̅L{&ov.gIݶ oӠk4!M3D>FR3Oگg ^JWUsҡU?ө[ckϼl>K+*ӧ'ͲǑ %tL/ZE î0"膙LiLK3faM(4ub9Zt 66;ܤsWљitm#J^6[Lϯt2ZS*->KfRG=oףV;2n8fLBDx>{AEtlɝ :.){gbϔ2OobZ2D1 q̅UZ>凱cWų'Yb]e-fy1s 6ɕY;9RaLOT3Y>1z3StDS6CTzJԢ(x{,J~ăYyYcjRl05~1%y#K0z_7S͎&ZB$[^9l)Cxݞw˴9zE/SDkOM^HA{jRtEt5jWMY)U+*M "J֧E f5^Vp+/:+5˛(~`(L4I#­YdD#3 ݅Zm G/Rn#~}LR,-,4J-F.HotPU#Z0&/o0֝f"6f<*_&*}SHː3̬MLTt#3,.g*2}5rfsR 00Pd' 5_C-Snʢi' ix:LlĆӱtRM;򼙎;KSQ<0ctlP*w3})dod`.c?|c޲悗T3O$2JcW1_$2ڬ@v̕,XwIb-R_qr/Xܯ L5;$u'GXϠR;gC-۸<՜ʽJ%#ֳ술"vX`2+1/ǟcJ}ffȻYL.MQtP8meI'S#R W:>*Vc̱ULZ^)SqX`΋F0"ҳLfcicM4dzx}PB_ImX 0w$B&ϣ?Ӧ):ǣ_Q&u6"bPR-V}-6V}& n{ :0n]a'c̈́2{&7`$ɔ>bEXk-2;BdX0)+U]9L nj59Rx~QgvxOÿR)Ka*.}cd}b0oy3nf61lr+ّUEX3!yV]f;;H+1ِzʴMdϼdZyRKVt ;n4{rS9݊ Xʤ˜ӼÄz2M㘓̙ss*)QeLͭ$u Ya̎G2߅KD-0Q& jhGٱj#Kѧ|uY Uhձ89#:V ~KDk3QŏTn kF0v EqD ݨ$1 ,@iPs;'((UupQn] G5;P{VM9%Զ&$iꃷ#V"]SFk!f joD_M9DKTyy#*zPNRGPQ5߁(  DViu6!h6[pSvCG1Ctd3[P(mxt(V%F\i(~i+:ٌ8s}o ּ* (g9J}EE9й\:ʘI"QjA%(;TE5[P악(EqY(joG>mJ_"FywPKTѸ ՠϨF P TFQ6:kG* !:dh!h.F̐T5t/2m8vY5@G6ˠAhoLtE@xq9$Id҉ljHPҳ@Кz$tL7vBc%Q:{0 {Q(vB:S7 T)c"i<9mF ZbKkW ZyǢSi$q칀^F]hﻩt`JW-A!aqj݀ڌѥjHFMe⾯mUDP= Ի.>B)o(껸Q(jtkP+D)(=k?V:b5AŁ-TO˞2Te/oJ+X#T^*x71Pf'eф2 CP~S*DFH.f1(W ,C Π7?Po1|t^i9ʰ@n2(ID|Qp 2|'Ǡ=с#?Rgތ'.wȷ,ZЃdJpY}.s7YPA(( OB fMAΓF#V G]ƭh`NpAKO__"h^y'GJr\콑wO-ڱ:D_A'V\D''C}VOE=XI_[NڴomBzbE0{`Elѧnz+3ZZg0jS4gb$K^^2v~6`f ^Eo7\!=.^T \K4ZyF?+HSKxl{~q0?qQ[8j.*Ҟ\4ϢL9#rryltgU/GEPJ}1jiC~|#Y57N;,X,Ch伵=To,VxHO(`xу2ȘA3F3㶼qfLf2m[EƫXKutڐt4)D,MQ̅ۡB#WƠ㷋al 14#r;d`"F0.FL9LbZf{_Rϣ,GE?@WH?UA.H2HDjV!Ey4|<ܻ||:o<Һ1iHk)oH?|8:25a+w}<ɥӽNt}Κ'oNѽ1Z8)˦.s}>yZ\A;r&m8-L+8SS[mIT8υ4}M>vNxHצч4;T3ux*mT5O3X^k*6-=hh|Ԩ1'15^3wz'0W05{ 6)jla2\,B2øyͼ`꣣-ӢFZS~҆)|Z5Ҫ,hGkK<ڷi+9ۅ`hQ>|jǣ&KIg-g9͚=[N -s"XZ$\EwLʌѿ~#ӐHaRI}@$;*H_CW҅ϗӍӾ bDRѶy(NDiQ]TvU/ @£J BSQmv Z::mNT?G{>~Cނ䲒B v4B>|.A~;J7Pܾ(eVt~U?ઈ҆C)8r(kiT(ӀkV2SCU[QYr** A|'E+K^wKz࣭]њZa#O9%}Ǥvhqv«%̫o]ݓLsZJJd1gRdLF>Qe4e=-?(ymVŀ6( =>Qz*w1%~jB>恨&gMe^HS̎Ql7JO5+Ou)V hut@c*pB.K3_薅&??]GoO4ԅ71Y񗘀v̌{kDWvj귩?)>Ϗa&t:T}р0J^>=nћ>ӫi˧h]I2nU~\S=oGQ2QS]RW>wPoc-ԡjtS7ݐY"I)j+ǭ71?*(& P,J#:EKH@*m{]x|hQ{sM .,$ɵuC]{'&0V\J <ޝڪ1N:)8A~A9[PzRFۆ05u\[a"Yo"?"{#"蝢ʢtZĖ= rz[(\ש-ڼA+|hԛ[" D3#EN/ ?+1 )5g֠\@H- ߲E_6_8m"QxozRQ]Qz9Q"OQZwHc)N:AttH'p>TcAqRwFnOjfQ}dߨ E ?zaN%&5-VyX3.u_,^?Jɏ,gOc%G Mح ZϏa0vQ+vͭ vW{f;=i uc_1bJؠl`B?{K26+gkeʲ{{#vWU)= s%8ʮ5]yu{ƺ~.*Va MenvMx)ab}ncO4DAgFk׳Qw&K٨wl̵Sl.6{a&1?]- ]=ÖMbK冱lΤllrn X26ͺclb>bY8gK1rlN6 6 {a8>F6:^ƞ_MzȦMgSk6u*/Ǧ3' cp6~a^fgsurBl'![eֽ `,6Ne\ً&,3"[y-֟lN6㼐MT!lR;İظd;66Vs'uHMMӗb3z<GEغg,s%_ cr9XG9[;I29͖%K"׏l*6[q>eS bvICLl|>"6g77ċ]ƪO`c_gc ؝l*&dK[ؔ+ s l>Xlјl^L63=?t/ȞOacoKER :?gΞˆdlT6n yז XPN>.g X#Kإ6cYFW}c~v|K{8_brU3.=kY X=&(&r<&b o_VL\j& ,Se\]y=͍Uy:57cg܊`g^/bFc^fF:.Y#+ b6߳Џ?LfMc'}gՌO2 ڥWw7.6_$jk/4;dB ׅhJ:YbDHw8]Eѯf1#'%OB+т!x#̶[A0GUܡ`p4iH d,D[mnD17^֮e&*#L0u= flLv3!L\"dFLt&b&Cfͯg ɇ18<(8'T29oQϙY:~ f6gX1uW R*?FwLkܠzjR1V(_KMBXiYneDɼDeLYE=|J˪'OmM'mᷲ0[*gBjz{,wr&5{K5$G#Ck%b}{,7mo =?T؈\%_.V}#(卻(>/߷qX/RYدGۉoOMM<]~l*?]>cT\1|17aȩv/Vn{a @Ճy1usH,%Nqd`-iE 3LA k?1}Vf# ̚XRĵě3Xu8~vnUZ WdkmY/߫1 챋ݫn zMu`?̺nay!qua^̔`^3߮6?v1/ݙ*G<_=HxXi#?UxjCUCj/|~[ܑB /mqukRnE:uwI|JvD4C\7똠w1IvWv|!k^[]Yu6x3]{t {V6ʦ5ԲI3lQHW7{($ibf6LJMl;͞ofFh"K~f[Cכe쭲V}~ {ɏc3322zfV4dk(6 mlB {fC8=).l)p0vnmt<+鷙ix3Zr o@LJ{JEj2sI&C#!y6̃L_"VkXZJHoOTXBqa#VaU`w_m/ؕuٜ.x]v,nYݺ8ʆaÞwL٤SlJA{Ar<[6]vzb[{UNzˆ,.ddքsR'dOdvm↿䆌~žuKjjز|KZyo&SF.o~싋ٷ ye-䤛,n(D8n 9ɞlgi-s%M:6{x.<\mN`;g.d}̾dUsCip`'w"7"%qJmjM{gTV]F {iq*pjQӍ /q_9ȤEFN۔'-,rڧ8CFV{7rS9St(n社s2p#F \xӚznVs_9;ޜ;mNNN*e͍ƍ(JdÓߏ37fle;_r9zN1r,7"p߭8)W$kbX#7n9x2}i ZsF2{o{}p}7cDOw{ KelQ6fc׮4sn0v[KfXs8s⺏@U f#\0iHd(;ҭKLe6ŌSnjoȌ0,cF·0OQkokD|Ew+vwYRcQZ"*w*Wa2;szoG\i qzXL&ڧB[{HWnӬ\Br-mMKޞ1=Co#mItdB:b^}2؈}{睤}=OҎߍ鹇Vi /tyZTֈS?%|Q;=ݻې">T *}:C_g/!Sz:guM|.oƑ q>-zcXϨZi' %$#o?ĊmNWXyNu?bWfsoB<~uEӏB#jZ+ =?L eFC .tu]h- 2N;NԄkW[mƵépJx8a7<%4fa۠Wly'v@Ӫ&h*'ÉwDI 8aS N M&ҡ%kCcQ 4±_}!plov>$ǔH1hxq m}0Y gC%)>4 ? ӻ! C[<4xZ  4()f4q yCQXCCG8: ({p,2P@V ކG@ϑPo/> )PO')B?ݦ/݀;_CmgP{-%\@-6Ԋd[5jAPԴ 5A6Q0 j\q{Jh /jm<~Ӡ%Ts8UU;B2 TxA6PoϜʵrl T*>wC:Kހ*y,T9|tb8hEA UvC9{ʱ+L9v TQ1ZůP9 *^)N!T.oP.T <2To1PY*=2JE8*]Tr Jrۡ4*] 7JGn#B5|,(K9(YBo.eCW@T(ۼʶV@P*2AP61ʶ$n^K(!~/%>] e?r5PA9t({k'(244΀сP2&J %#(J1H (y@Jz%Pj8Jm& 2^_JzwAiÃko]exaPfG(VԵtByu亮@?mP.@=BǡP>bXO0#! pUUT: 'ΚPgY~js:GC9P]1vP{1jO:Va3sj-{2_B/+PmBw/׍ij=a©t ǝ˖BwvBԾ'^WgX:zΈPrq~<u@].kuus VW<Ԋ>=FUP``ޤB7yuj/U@P[bԪ[RBdS(% Rb5Nj = 5[A]P;[\PKMj6GBⲛ=jG Юkg0PPg\,;L\FPc14:r9P51 GہpvLDCs8>]U).S@]Y5;d:Թ_uGB݃IDCUaPGl8˒P3Lf1qu u)@2hC3PW&YjASuEt5BZP/#7@P_΃]G(Pb,g@;P?꧈eA w͆C PC /Z [[ό*7O ׭/ÄOk`ԟjA}W<UAmԝ|'Ⲽ uKC@[u/92eIԫz"y uJAA\\Uuj8#>Mi/hg6'@PlKB];i \^Nz.P/~@ j R O{rxˊŌڰ kI롁^mph oFOn1:e4 {(A%4>,EӠ.h4IǍ5jช p|8`3pN4'&ǼW?4] n(ዡi98iq8~343VfhZ &@ px]8f7h4LKv>@گ_P{PCW;@|TPj.`?yOrʄP۰=?`@;w-Y޷x_\>u>}]띸MKze{!=S=>_{PY2@ךռ)3(^*ލwyIڮ)GZg.5c^Ö<.(jD;e˫5Wo++U+g˞2yfg䥲wyޱԥsGxxQ0^L *ymٳxygy78wJm!e%y;x73x#Z\Yۚ;*;찑wQ3o(_Uwk2oo73XO?=6J>>[$ƕ*Ts srs984죌x+xvxsn}>U<)=g7d X!3̝3q7ڻO?%<]<: T4@b((keAA ( T@>Au ?_y kbA 剬92"8$Im@wHt$gu@rc7H -^pY$5 aؕT@ .5~A$b|i nbAn3111Ψ@4 "_?҆ b;p 'A8/J4 @E^ wAZ?nA.AP9d' ' '*CA]# -7GpdN أ# v }/qXtl>ws `y|6#Beob`~-Xs M֞듺"U`tco{V^7X9{3p? NG6Xd,p{ d^?y pz0NGU/<`z. ` d9`ت9v*^J0gm3ضYE$ XjR@=7{;"{kC\'/ ̛ݿv =E<0{$=( @p;,@PٍV!{iFb /VpV1>R_= L׸wFb,0++~Dϗsꁸ>v^V,X]1x*[N%eH8½`Ar/5`^ҁ6io>w `QIp#*5{6p>ܳphx:ہSX v'jM`jɓ`fw`8`vsgy`p(r!/jGgE?s6dX|J,_q,Ks8%fA`R_,], ˺wXjXqZwN|0Ȃ }Z Xps%=`ɥn^d,$TEubSt|,{KOo^`ph~N`?i)+V>{/p0i`yk~  sӛFb .j;J7<_gp0c3Jȃyk۲``?Dw;!GkW0E0@<N]wfv6b0,7 . Z `nZ^\D`h ߛ *fz=5qϋ[ %!0f3̻K-C<3l~`̿"nPdwBl,Z%n}gڬSU)`xp.X, i~`a н, bZx pr5!Xt'qh,1`` @X,ꀫE;X|gXZ o0Fb,r޿M, `uMũ/^:x~U<_SƷ` 6&fM.i`,PlUۗ{ź خ!`o*8t8nAm냓y@lZ34 += "f() Ju-4* R19wӯ8L f#bA$1;@쬛 +Hh/{A!:ā2vp ]$ )3$c|Y$lۆDr$<  q2H1$ ɻxNgǮD =Arj?$Dxk9${D ^?bCpfg @l2Og>q'o8 LqyA ~E H<$X!HI_ %)g_*H)ww,KiK _R@y9 2oYq g,3(wr r[W>U@^7K8<1?jv Tj ADPd!& ܫ 2\@(P jAPPg^vξj}ugL@C5݋#@10 8_>Efc 2k(^{-D%N@|E>`DFht[s g!a@8F7}pK 7Z>_P:xk "ͪJPi TƂZ)PNUAŞeT|}mAIw( 0O(ej{@*Pݠ\q.(pT\_ MU+Au!U?A;P5lr@6P7(Y_c%(y J[b@ȁ2wWq;=JW8/AIaP2y@{hxPJJDg@IPzw$(uuf-2\:rAer(|TѮ^Teڗny*cA͐*h)-珠f\ ^@ j! i n/ sn2RQ>zP/v3^ul}-HY [1>1tuMpwP8T(P]T:@U8@X5TPTvJ][P5y,b]VR}(| tAQW(cP ׃:?& k3.ٟ$Aβ\MRAl}+Ȇd2ZЅ|a2cĂ ۃ@:'AWH[rVs:t5 w#Hs.ȃ ׁi нdƈel Xn&@0qz s bt\p2 @fّAyo<5y߀ }= }o+A P`\ Un aw\}K;k y_AנB ;P '%9`6(%jt}(@ɛ/E% ^(nǍBP ܵZMP!=XP@=q;hXF4&e,P:[dKv\b&۳ywhr|Ax|RZ:@Њ2Z;ւibxrpXikk2u$p}h :N#p0Zz*wBR^SХܿq{ ?R+ GSH|Dçh8= 'uilD4=cQX) A(4V^,4 <܉ǿ@^hX5؆Ff4>QguEc;}4J.4&ߡih:w7Nf}ЬW%4 *T]%iyM t#MFJHE4#BE?sq74LEh MKAΉr}3}6NFD[4vyƣhf5߲ChBa#4|pl醆_F , .baӒh ԗʠ1 ~BnPSla'=/Xp3`XԷc^@VgxrX,gnEґLXz C,G$˾ɲ߱OF'YNlG,qn~ 6ZCFYve?Jβײok=@`_>8Dܘ0a_Fd_^,^|e\2|_ wփ}ߕ}kXe<ףKٗs,}>K7Ғ74b֋}RJXϯ"YS[,,{vcIڲ&YRJMŮuX[: {s?{[].'{{{{͕=1d =KD|PuCl {^ϛ3{0{zcȞΞ}=^8]fvg/5e/^%gw,i0{`F{Z,i^>{粗35X7icٻSX+ vQ]k6K6`{^c G),d@jReYjc,v21H2ELz,ά-v`Cd=K Rei끥 qؗ,sf5[N,k[>ӆ}g߂^f'ưEwY,e.< KÒk|,ҕ%1Rbا,e]td)WƲ؇Ծsh{ IDKmҤ*,m'K鱞}Zҁ}a\O%6\7eK}X},} ̒W?e)YjK?}чư} ;)ȼJV}52gMf_{n`,,F닰΋YM,۾ ьQop9˹z<@VX$, [`Coʰl-Z }Z3 }J Ab0< ^艅BbЍXhc,tm_bMKXf-~1 mc5;GáCШN4iF/04IGfSףَX [to%m̰#X#KNX6˭9ma ʼ V1V֏*arXgc 4J%atol\t6٠ȶƠEO@C6hm:%UuhnvX]y}B08PVpvq}gea`Vӹ'NHo^I0<}%JiO?aĄt}}7 ؾ%xƥFʘ¸nT7wĽsx"</.xf\:.>$ xW|d 1r×7 }x7L~TSF07jU ,%|0羕Od =-+\)Qfh{Zf[]fj'3Y[v%2dEȊV$ YFe7ej>uEVfLAY4OYdekm@VoyYdoVU69'RV㑙VfI ?j]X!uV#YGe-S&󹤬nNޫdu?4OVoqY޲|5"kX}ղF5v?/k=ǭŇCaݻxb9&6jCLx`>8o&xuM^eV3[ᩉĤx|d 4k"{だ<`R^} w̩ƭe>ymXᩊ F%qM3WW•kl'\ 1B'\rENX.v`%e۸V8U;*!FC0:m FĨ;0+\Ȥ#ZY#.cn6#U1#l=K#zQ%zcTY5`b.(6n둒Q0jk+Q50s59q>NGwv8Gy)ΜZgngV܀"05HuCpF8rYYN8m5VnS;)ax8]Ey|e潦:^z rwA +Х!> Br5(gtnΦ/qpg&`=KjBNxt^;fn6but=JtcObO=aGfmZOMŞt}KǶ##rأ_hwn4@na)NͲvk(ֱz mw,Eu7v5] T\D36hm ®$]*m7~v݀ rn]"=ŇY{?vO*=&cn+bxC Gaa k_sӮy`Dî8 >MAg_%Х dDk \XG;NC78R#+CWošqҟeG{0W:K>2".:m羛u "\Fג;ѕ!OІ8kܖ(St.nmL~C5Ş/zFя8b"CYܿȯ-ow\7~$^}J,DZ}Ӟ䄡V{oO82r<؟€|r,mQC̫-Γ׊غTgg^%ЮN w!049Nǰ1l= {=NuO.{>S%ǰiV)D|ze|}CTkNƉNl3p,_g (_Knz)(7#Ml'Ǚ±{p,clp̆k8\a[%ȟ}G' '׫\gP&rF%Siޗ(b/gOƳrz%.*4JξNgG lUlg2lkldU/OgilqllN, 6`BY'}YX Y.L|)q | _] 2'Ԑ9ix.]yn\ 76ÍWK!~n \_pݴ+w 7FYrn6Ã1Lxv4HnC8H3Y ol䎉>{?/gg *gV{29p\)Btpj0oq}r?CNOwfPÖEiy{6WTMc`câ2Xl :V 2`o`f 97c0rWyU{u iQ0xP* Nޣ|Gݬ1WwOSJ߳1 ^q}~9 `{th b,MhkZ֑UCD9k0tr dBt Nq/CھVgC KS!P8Xz׺l\۰0r]8n݆cLp? +cT(8<8@gPp='/{߷0~Z`ٿuu4 @_{}TY4h`{f@cPWP}Rb% viP(MS>5Kztg1\Ү2ҔR;$9%OKzj$>i׭yTRNꙻ>m=yz fn9f"yw1I*g a`˸;߉\,K]n7l_Ηz-Zڥ(4'վE2.&0?-5m(=HŸJK-KIƷ:JwH>f*œHsVN"mҖ҆~Һ&'eJO .i#5;-?HؾuiiIe)vP ҡׂ#ͥ0+xpd!өzO<r'9%Z{V軔6)OŠ ңۏä o/(R:!%~'%,)]yE cIeAw{ IH^wj-=[)%}j,!et,e8I?v~Ǥ L)g2 łQ`2$YFiۡPDk(d ^nh"}lrIztr-sMoRGGI aI kKkQr *{CAvy6_H- =% `Rb;";jd~ɩcMO/>c~aikz!E=Rt[ze$ٔ.,$]64pRx/)lo:p44f$9-m\7)xi$iiIiV8QOWt̲t"{7)qwj_0E^݆RMCP7T^83.4}X-@~ayty]7l{:kyJ0|[_:N#!0#9 !̠GW0Xn(#?Vɰl5XTbD}lkYŬl apM8d'L8.\_  õyF8 Sg&@{3$t|Ug8'pZ8N7b 3pP38_n3v_ D8#:.173}ޗ*6H8!\) c]wyY}"w>o: wEGw_2̟DA5kR QdrJ55!uno||^rމ otgX a2!! >l wp |D<yoMoUxzfr91]X3Ñ]k$鿦uaoχWU4˾<{8 :}P^4W=Kcx+Ƕ*>^Yʳ n$ wǛMV2[YT+x:?'N%l$xTt<5Ɂ›b~ )G!MHn"Rd_ғ `yH{f6~G2BCꃂL=Lߧ|׍o![gڜM=@@OO~/-ӯҐ|ٛl <0 k}HmWAFG:2 +Mnsc +09%|_w/^csҲ*=wٟ`ւv6,IY)Xܻ_T> \&Le Sr`K}&D (xhiJ5:wA-Ը* /lv8sG"=r_MJ&%X*1҉ێRlD݊ҩsJ>HW ^J,g+ݜ&uQl"f)=]0lj  .F.9(j{ᯝA5pT,4<'h Fà4y, h_~niuWcut*A-CP2T3旃P`}(ᅠvPl%00Մ^@ϡqs( >9+'{r[&APyv jaP&jMB,@d+#X \(6ɣa0l]pJxYC+1W`ҧ0xB6*#NJ"1Lש:&5 a a0yWQkfo`.=Q8<8fzG@Tk\jr-M݄ȐG0^QWb'̿ E߶-%+²`%akJš3ga5:C5M`3csX|/`Sa XV ekkaXtd',̎5߿ms\9Em r_6̶Em0l3 ky #!yozmE߉s;GeYpb~3$`X9\.Wxy̡B0D{Rc!bȚn3wƶ0eY{+&L4}! =OѺF( cDBة[05VΥ0 xA 귶>(l^0tW v> {Áe ;ě׆Sypq%HV( bm W^q%_L[Q|>HpnG8bp@Wh#Kvp!]Lӧ\xA|~89Y}#>lؽ5v ^Ւ񰈳vU ;ÎYw`0k q`Nس]ְǥ<moWhO]oSV'UXQ ,5oaD}vd s@U |PF@T,JI!jGE?zeC3`E-Xd-X#eܬV/k7+`^%ز z"/`͂ ,+v Â:E}Tv?sΆÞ =fH `J0( &d¤ANP6Z%+ ᗦVGڞ1*-D̺i-k>U# 6'!~589>.g8t&\8 .WׁCvp{5'Aqx9tf>ͅGBqfx <- φCU9 фzu&gw:p5$; nK¥ª$8ICéćeŝd8vw{{FM\lbW&1 WAMX]1\pXĊJg˯u /Xt#挜QK? OL;Znt)!B*\Zjm!cqwE@@Ž$Qz`[w:CæJsaCF8l)a-̃%gwQyIU}2zt#}􄻫d4?X4\&Q6H2d?gqe-;XŬTG\Wj크ƣNJ͚kM_0ސh(:`f>cݿU4_ϜSF0_=lԵ/,tp9^.M,~QFkI0k7}M1-1ɖWek^`&}W9ԈUFæuًbV,a[z q<wa},ja+3?6^!eNS^ahw7v&/þaq@L釮{0)n膞Zȿ\+oTQZF7OIM``kj۔)p8:{-Nk}}ۏ3.JcWpLșU1Gαs']y|K\qag8M1b\K+~ťmKoe-G)|bA\݇+Klƕ~uqՐr]Ֆkq+_\4'20ƓW NXW*mÇO02n1JV[VtLY˵e5/rs''ag26%Zo)k}⼬ Pbi1s܁ QS,-YZ8f^wbmiQzd[ZHiQ].--*̵eV /,cUWS9yhex˸5QA3>4h6=9JCi/M2\ۜh]DX9ྮ5ާǚ0#O-5 vBk3cdqgvjZ B>ms?z}h~oc\FܗmC[J=c> 8lz|-˵{ls>Mh&{sll?5͉b7.ͦp=W獏DJQGWҦФG8զ&tV/m~jk^?m?4}Xx_{r~nE\5QSHVT'5lCv4ʸUSJAhi56^Mؽ{k1P "jN4z:k)礞Y봣Moicjsk*Ԇ;ϟN MieM[O[>x;A2uВP52'J4ХC8Nr4kxu<eup2qAsyҔoCiwMh ^6MJ{C҆6;imNꢃwp[鲖JCsWM[WMy>N|iS5G.&=x9EJ9Mwi֒re?sMm(T7h.y\ij{.Kc9M.Qsd\N\FS|%nVS "tR>9\M92m9ɼ^uh+W4 U2;x8G3֔;%-<MF]Yjˣ*\Ӽq[hʯ*srdr-)sriUA=MkFErJʼܧ i9h7>|N9mԴV=B}?<ɦE=]ʵ.m9m]i-˰D6D3+E}C[9CX4 }AS?ִ7&MsSJV矼\*=Mg@CUzW\~[֚?U@e^Q<.Vؼ*Mw*^-KNI/N|\ U]F۝->KF[-Mm>Hr"7w(srھ3<+eV]5OV-~4}ǿ}!uB T}ߪ;W$VV>ѤǒR+y;ƢI.1jjۛR#;u.Sӷ|ǴߡPoE7\>KMyM](iywצ.bmy0o 3To~뢩m1mr]~;Ԕ_yC];i=ֺsh˟%?6Y< x8noFwN~zp}Ǚ+kfXutO~>|:u|C&:InܚqxŃ햺Ń¿G5tŃکYC{on@.ƼArYhׅ#ku 6>.Hg +gtQ}.kt]g /ݟ쇺qM}[6PG_ܳt'2g%~;>9U&|*+EĽ#{xޝQq^sugjŽѓuë=m^n?tm7oۺs q_"[~NkB)]֦r?Ͼ2pnz兟!?m7'm~ϸbSst_λwIt_~־rcS3{zf}4.RmqO`j{ens?X!?)?Ϗ_|T7ZܽdGYx\]uWn~Oķۼg]k"ǟBu]Y]1&Mc}.Սw+ҍb-gq'z;h!:邮cT+yk~|OC3utαźŝwѝ,ϣ.'?6,t>GB}%?:s.+|58Dz̍]KkC<.1.9-{҅|ĸ?M?y5_Ƀ7k(|] oJ}t*?ooG[o=xeN>||7\sm};7a/NT&q'F.6[Ƽ@\X 6y pKs,wsC &9\>8ʒTpNd-[~mm ,(B><(&?ڟMџŏ|@!%B?AI@~Oz[)Z]]Ѧ߼o^NDQ}?jKRsﻟuמߨ&[O[n3nZIsSVy+CG޶}։~1=q|O>DkȇR˗6}iܾԦxO}Pˇk=7KkD:4?!+!{/͵/[_UBux>g\?QKUљօ?8y-QJȏ|HgOSNv㢺|^1h=Q;+ˊ9K/?ǏuhCcO~F)b |ܾ||tu\'mu޾RSǽkD1oZКTAK6U+KsRyC͇o [,pԉ-^*{PBS'P*}Z ՟uО"uZ4*RK=5>wi}wl'Tq6&+VcLR;EMT>|Ϊtg3sZ5nnq !kU2gzhx,`ړD@u~%+≧yb'Ubr"*@@ڃDb.轈eCɨUwԇ.P-nyQxPf^=Sq"Hvv:)6溒ox5xL/OHv>;7y"S̕/^^ԗY)m+WA׍su\*lU]b?TsEg(t+EsK牏9C"|{/ߋrUjWJPWMe$'dѺ=q=IƓeOד9ԯ'YOImzPEox*P'A}y{P?BeHۃ yndTw Tw4tAS{$N;5tNNN1\OuuFM Qn$;FFkr7+ Pz? WMm%{yg=PCH!B++JTו]iOw~iԗŅd\s.ԯ BNȮA *s&ygՙtrr7IgÙ@@@g Hm :kHv5 TOO2Nd 'PN\@fякG#~$W?חܗ%پTIu'އ| U@vCmwmp9j7Ko?&oxzs9#:R$H2͍@zO"^g/^_OuOzߓ'ٵ'AmW@vwۃ Cw$۝NrɗSyw*ɆԎ=S4V;zoQձ#[t#thݨn[3ڳWlcKul+EW3{nW+ ;Xm P ƆTxl.$Ӆ| tPY3cg*И:SygIg*L:ޝ݉:QG*Hu;RlՑdztW@mu G.Hƚ֓5X֡j {[Sճz7SړOړ Zyn;v$ߎjGrmVR@##{s}_.ٞDy'͉6Y$;yk5/uW7ofMu G\>Z{6뛿N<.ʾ*|!/[;Vy|_:P/kŚ,6ՊتJc6}\ewMeck>gyOQal& ڿž/ߣտQ'I'3z_:tW9Q ʻ'sh}ܶ4*{ sa45Dk=kOgKUӻv{$kGjGRݶm}[v[*kKeVXQm+*mnmhmCuл6˭I5ߚ5Y+VTɴ3RKzג޵w-^KkAcnA[И[P*4-K:,I^kIuT,o,XZ [X?A =BW_5y }UԿ #Y͑de$+#dcU4HI^\`4WUrOu0˟F ȟ@E@{,?Ax=R/мKT,ٖ?U%/$ގ:%?(ˣ&KrDc0ۖ4aSS)JU*%z?W^ȟT6Fz?_<1%Ұh//k['~]Y|?{/'_t$7?핿(U:V+;^H窪>߿S;:啡*=9Jܢ)lHus q.Ҟ:ܒlٿE"2gc{(. L+ǐl+ې gc iM֤[k*kM6ZSmP"vRbhonCkYד]ԗ /Q~.Hd5Ph)-[Ђ,-[ 쁲$eӨ,"eQU"I2=P̙}̙iiҜ(AsOm/7D슶4% (RX>BmHiR@j hK " BV0=!B6 qDN{(oh+ QkAa%;Bf_rӜJ5yKٝx.RT')=\4ORU(aO*VFFNK64K8U9loms.Blv6GdzDR[FRzQ.!I؋P8v(2G :foy,Cq$[h헔ztG:~QXjXz>c)^FhO2Ǒ_gDkfw:'P'P *MVS9$0Dy$_25P BRds߻Tn(QVMM[od?NH:fP6o)AiIz N,QYL)6:uto0WyL:i(C{A$ͅ*LM,ip)in$6p`ޖNut06p94T@SI!ꓨQV9YPl, %-9Ac%34b?P 5E2HJ1ND?QFuJlk[nSZkIT 7{jvC/Tl6w kfWYfFidLsWtp_v=[ӢQa}FK.#m\J3Wچve4?rQ(l˧OT=Ӣ:YX'/au3S s%C[QG? lZtMF.S.UImam"Y,^vFnm[e>TV4rmjG\6ŽNt]au֏|L\:X :?:nmo{i=DC3w!g4yH[kJ3ֹz+^Π,*cֶoIyKg(l@id_AJ{4Ϣ+>gPtO/gӭN2=1*t@gf\\Nݧeg(3;g@HSJuJyRF0BR46ɔ<K癀$*kja~'Pt/)QǮ&ʖ@,'@$6⩜' /833T8/ xnzvR: /폙9 lл)Pb6)L4ESTNIIwn_O+8T}H'(Ac)C: B#~; bd~ZyF-(c(*-l`5yCϝ l -s4Q~,!#;@߃˙ӳ*i?DAD_A-iѳng޷`_zolkپ5qVPK6/g8~fs5)AeNi[0Ty3CpCl}AElb4F%[fGs02[7YB`(\_0q+w~SsY_&[9%>=O h6F~&mN꫙͎(4jfv1.AcaPth!%Aph1όIh]3S^FƒmSjTD5Z]V7jIo`]'{ &la6b#UoYs? 61٪˙[o;.i~V >d:ACd7tjݦEZ`zrq Q-p 1PN $(N ØXxI;b#CVMs"PLϢssL NazQiZ/ !Res3kk _aFvO4V[Hu6ڮfg񜅨uQbvvrZ52S8)NqS8)NqS8)NqS8)NqS8)NqS8)NqS8)NqS8)NqS8)NqS8)NqS8)NqS8Ǣ;⅋~t=IU;D#Kɯ wR^vRZ)~O,JeW%4j]-T}m*u5jQwLy g@NG^Kíڣi{wfNw,,R^7%(:T.pwRJl"]=&֋k]ߍEEMX狿So=4otfR5XFv=;潛7 bYni]i~&߇i/zI7 7Ov"vAm ̥QԜ[lOs^VI}PT|{aWrakWֺ|SJJR*pX^vo4*xm#~ŮiJQDӆ7A?L+7 \Ow5HFڻ \~{~\<*K~•Kr5|X?Wȵ^•aݪ>աUnWBfxq}nrl kp"Tp?qσ-E|/]/wX{цhMdV9I|8JUr&sl'%b? j˂qq#JVS~̮`^MyVO\3鵼*XIkaM*5,5W)݋wsK|ήyx00ޅN)LL wFф.GwRV\!C +P|:z}M!Y+zc [iYu ζ}?QgC"q̮ބQ3Zrfz;_9JuGەPu+[oN_p7ӧ :Ы%TW܀o;?ɹ*>뾯ކ-5ߊYG??a?ݿrbLo>;~{wg6e}˅Y{ sЯ5i+6oM ĪkEoa݉Vw Ż;p_鼰_0̓՝XäqcbY俱)~ 0lѭґqRHi@w';3H=QoA{UtZYFk_JL Ptϳ}#n6,Gi?Z`'`<cq̏a'%x}bx%l;:n'<όExqC,%51͞{ /v̦(vE/nBz b0>C^0aF(G/:{H;);^_HdH/Zوz"^?aok{ M ox=zN., ]2 !#0Gu`@p)Zz/ ϣߨO ֜ GW$|XZ # < BK"61@_Hyd-Rf CJHHI0B֬_.~S1Bܷ ?M_# sh"B8CgZ1۷~f"1>D ;І=0k |Fa`qs5xF@Fת&}ozAz ?ݧ@Z(Kغ?k!"v!zgкK-< o#иS:CGksx=BDxh[OknP/VCs2!~䍠bއ(w=^{<,F8.>y=#zBb k#,:[^3 I`oR;#V_G6cxA(?/ 0h*2#EҔD<#k7Eask6 %#sY俒\Hy}/hIog#fXo<1tk71# #p3"1؆`xTSw(K(cF„QL 1x#\AGF{10dG #&YDȳ(TC؉1q(D`QW=`C_"*9x &_Z4OG?CvYE#&DMFVx(CK1vE$ȇO"t=B5fBw]:`k+m n %#_V HjuHv[#.j=Ÿ/'RB|wap |^ !wAu#j$S͐|/3+ zd co/KU}%H5Og1=sZ^Dă U j-ň[;7w*>FW<NWo;G1$FA;;^@u; kRA"udX?"Ɠ~WH,i-#H$؈VO"u[H)~IƭHs;RW!udȲwi[6 cn$P!k?<Ck!PvS{bv7 0|tk4'BD∺#"_9qdiH10˟ty&`H||]Gq E$BSva}zf3քohSZ0h}TaPzGUK np}}fdnAD-CcheI;f!xiz 9N OZB=4p[> ~s_|s.SF(8-F寧{^OC߸\{ uǡ0}O; {ІEOh;jԳ{<^>Ct4w1p&GZpdsH 4{zۏ3M =%v-tn.ڬ8g~s&3/~83hw*Z=VCsuCj+t :lѩaogSZ hzy'>8o <ֵD÷&_Go :g_ے>3 ݖDNשg =0#t[.z͘wo>Au؆DC.] &Pz (W]퇨lx<`MWD 1_B!-b0ˢFĩHr ~ Oi^z¿I"D;[~jiH#hn!S '#\>_ l=Dd% 򞖈7Zj#$la4!Q#BtEi}B=GرQ*=; y$1nT1#ዘF]i.|&Zcnx1bNEy>@Ħ#"þD k0G>\{(RuBƤ{ǑU "@o61zF {#7FfZ$gvAHfDƯ? ] 2K92ׄ#sſQ9o7 3J$nXϦ.^=;b\>!M" bDBןpug$zY`:$> AAЭ9LSHHnݞ#[3"-iM~fXqߴC:y6 鯧A\z0k<rg##LM@d }#ą\Bba FaL֛HO Is9 CS}rزl$ a0+VB|t ]}#&Cb!Ʋ ˌL0tcȩ;Fz"p'~8Ҿ]y9aZ'LEd1" Ӥ"=OC"Yd̄.f5ҖB_bFzg Eވ5Ӑ6ַ_#ogލ4zGu-#l/v}ޗ!1 M90Ĵ IEHswo^f"0j,FgGb:u>F~3!ϟFFe?Bvc5c‘9HNvڟFQv ^>'1>'~r_'P7y#އNV#c( !w}L9A/ kv Hz'],cy }'Űo#F3nLh1FO¿1E'Lm 21=회I]zb(XzC`x D  &<=ŭxPS[11!*Pܼ#Œm1CV@1LTϣh&-jns,Qc3#c;l6}P me(r';);Ph (<&fw?`ԋ(~=5ìZ0󝵘q꿎)90'a}0#Ղ&bjtl zf<vcAQcw3}.av˞9QO`y{;av'0Yf-16WYa^c3Y=Ņli{=E>06+1/XDK̞LĂ`17~_lÒwc:o0xXt $`'m?o4,j ێ" cW?`I/2xVŊ_ZdM%ƒYcYf0LMb频XV~^-T,9}Xbr/gauJ^5OJI X<%ʋ(*ִ.k,򛎒b{'7iSX]8iXvV7?UcpMĽS5b'X( "v^tw*i"Rw`a7!vw?w~߿μ3gs3:t2z yGekgSy8*,ȤyCt4Wd1*爐gC_1bx[@q25sC/($>OEQ(f}QC(vW%.d/uJCqRB:͋D&L\kDQG!h ;&d3lBQsXXã(2EIQ7+(f)z"R58F%Jah۔ڭiHSD[ E<Ey> ]o+Q~u}OM^>P;J|M)1BBS: &UBAj(տm2(tf {8v h2ڳvֻR6 Ӓs)| vOs?Ey /i3yhFVOʢ^deZF6 #͇H{&ZzE 5i>MT|!շ[Af i{iNFڭ4׼fazحz3uus!IsFF %MZOѼɤq$f= 4;o ?EjKH=Јf}ٻ2I$TN"?KI%"TFq4;(5ln:HcM$xDZ=4-ˡfn:zJ;i +,bqa},oi( ߤp%}$Ks'hNV,YKWq*XBG+-υіN:YC:vS2TxITrw: ;ұTpЖ ( JQ*GǷImT06 Voc+q*j~* j:bIGo蠧u.IާÁtԈ(mt8\Kf.4s&TPMFSTd$NG6sMEk-I.Χ"9Y,oo?jS=*vϤRV_|VSBǟ671壉=xNA *TFI*$N m.SR XE$PO5F  G⫖Pڏ ,z @ѵ~RC%/6:1T&$6Id@$bu^tv9 '?.fBDTjdR rYͫ KStd |LsrA*MSuT2  *-uβ"^iZ)cAUwPw*9KY<2iu+7ޢSXCbt|:/]|-Aj&et+QFʼIY],eSͦtzJI&SJ~JEW)a'(Nb/SɔRҮdJ]G]s(e=E=:EFQLr+.xKE1/S4%7ZP~>LzG)V:b>xaza ŗzQIq,/=8tſ)śŝSl%Aq3).bc=a;N!5?;)nL1L|}ՒvH&)w@Q"(V )}nЁ-C?%"nQtE I{YE;F7PX#ѷR -K%rf>DYF_L($@XFaQB7m='WI wK;oͣi{i<<@!>P۴z)(8BSi+yzͣ:fIwɟcHFm4ڬH?O[M"MWK_ЦwW;[ o%䭵8{i7K4mp>EccrOɵv?G.r>3\'"E.CաzOZ-L:?LR EV q~<&/cGtGsl5iMTYzI>Iki5OkGʑfy2HhMd9tOWllJZ5Vt.L%t'ϴ1'C2VD5K|#tx2,OƬ3I{3&8Iҿ;nDj{Y #Sod8L7$㢗/>(aAVNV|38F'ss}@s>BVqdӣE}d1(l w3y^9EmBgMȡMR6"Җ_ɿu&P:m@khfpbRBLZ_(-.VS8%;SBIE)wԆ|r%Sǔ5@?(yHӡ|_::LܣCtC w\T\s qv:2X1SNePe\tae&L+r/)eAX:=B)+?wIP9J9)6JBoxB*=IGl(o?^Gi?(~ oң(D@)ODJz݌(w >e^JYMIsGQ\J$YJ:r)R?JH+oL/I^y}27RzgJI8I>)D2G3e({%uSJ)}%e Pl<-b1/* OPNXȜEi9 7JsBH&fMrͧ)%HruޒH~@ji)ue1p mINt{%%LDegJbR?EJ-/iU,E>L"Z)zfܧѧ(n" 8N{Fюu&jC;Q'?{]|{;mLnݴBDa'>XIYpvRp{y<`͒6e%6g0oޡviNP<үI=iKU?? IE:µPxc 8FN_b7\VM-]-ڭ1H(`_ mYN[ާm9W(mvHAM/B,[V\\)"c,%غ1ZJr(?"a@|?ͦC?)H<$d%6[#LAv2EfѯU(7riyX2x=,$ʷ 凉iϏ:iDzkkC:q )ī[Hp)n*œ =It~M,oI.weҔ3h^/A͜__h;X69站ݺIϝE42 E#ֆmy#~F 4 G+i57h$&uhI$=V&OcF!h T/c-yA-xl?&.'~M*~Yyvsifwν8ONpywg2ɜDzbGw 9ӏsΗr:~ irop*վ)2>IjsrG$I9 k98Y8N^ 7 bPcn? Vsq m9 8m9=Sfq^r:F~sθtTqn7܊\yUyWvӰdC4jXK zǪ-4XRy@oa䐦I6b| (e|v̥kGA.Qj^HklX  m"ׇq- H۶[Ngs79%A6NHȓYE&TSk9QH! r=Er6E+b9^r Y{?'׾t[%z멇9b9Rs*j?GOl8'b\'g:N\ѧ9}F98#Nq~ws>刺8sR58'JpDN+N sm;sIz|R 95✍>/[>|9n -+ΝKΜ#8?էpn<<~Is.ʺsr*/(rn}é=)?995=9Wsbq!Μ#89s9ק8^ao8{gqvy|Ԟ1vVϜl$RZRp\ƚ|UdYK&Uݴ=ͦGJr (שfIλt]*M<0@1PNiT{R'E?#IuJؿ645.S?mszΏDϻX^IVŠm;z7 zE-CoiI7zѻSz.Al. B0E=sg?zGꢧC٦JFyn[R. 5]o|tz=ƸRKpGv;]&};\(Hkq\ (tnCYd'\: 9 hqQ|C?c$LFWAg-tTG=蘳'h F18ЉsGW✇.?f3tbkLFHs,:FXq8'9spNWg?8; qJgL?o8}C-&TsJ)=_*QԓhՆ6sh6M]A?MmgѶ-ڌfٍ6r&\E ?[|nVK3N;bh6+eZdQ|4zhzMt.|oi4~+hlڊL94F+19fhFg/4߇Ri4Cu4<^}B)@"a!X]!"%֣=#o7`xO ސFS T|&%nAm!p9vpԎ ySp!xA=[quEgTDA7P)=WD;ZԌA6=U[&}n{^{b4 s \>p-rJ5@jBKP}-/ gp$ bvt]^ǝ ko02-,?Dh^?x4" K ue"j CMjFf+I\J Ǡ4砺E2vFuS8Avlb1{Uj@xpG.A j@확lkCu-xӭ[aSQ[]k=Pn,f@zNVـzo/8܍O`W~${c>߼Cފπ`v1; aHXBgm -aO ^qxu k = ¾/Sw!Biθ?nG*!о zqg!L9=w:$N69]gx&-sbgdgl?{8'XK{?A l M-nUp3m؞ze< K^?@?DᨙgQ{MY:' _ { ۦOpxeqӃ\7YpUڨѨ)+b5A\j$j>MA-@@<ʞ,?/vs'܎}Mq1j{Xˌ^Wnpb+!>}~Z Ѭ7: QD'nK*νEp$kCt[u#nDA]T(rMQWx˪^q,PoT| 4kG$4UAӇ>4ŮFc af/?n@hP?*h 癮B1[ 4TE[,V@s&]Gx=! ҾX QBgqp.DKU+2BdꚘŴw-5A(c|jvnwTpkQ3rv=T`0>lי>S=N6 .b0>gL3۬d!B]Mz!8,/ aq<2vVgX\Vș̿=xzeLkjy\bÁoJca8SԪ?EoWmAyLXʇbZ>3Q-}UWPu ՉP}ㆳvjc@UG,9]8'ʱ '8'2d%N(G/[P1Ũʼn^Tـ82X'B OFQW:C^+P9C@Kd~U Y1Ȓ^ I ;38qZGˑ齋=iV M6REבj|KHy䆔>D#E/]FP$ IJ?ujHh=*o3@|z$Gi$@F3$/'g$ AHҫBbs$vJ"C?tI*HLA#E"O!q<$MElQFo5:B>-BH8IgЙ;*GB![L0g?6/N} Ł=|4l_Ma>s ^{6xs55^f,8fށǺ8x ,3o7=\{t}eʂ~Oĺ n3݆-p pQ sp.eVe{;#b԰Nzp {7>͂Oؾ}ۄi6:Oa}6;`[++؎_ljfvl-a)+6d`Sfa+{6@ka{ln6My6fm~o 'aGaW;{$ [3聝+s^ \n l\`kfvtlV<a;Ո=wv]!{vf{gv#ؖ6mdvZlއMln9\m; ` [".lmw E")~ԇ2l1ka[uapa] ےӰ3a9^(Z6Mfag16:`ݫk8ڢ )~6uFhlfD/΅^Xo] ٰ7g.l2&j-'lƹ 6aQl}lڟ ca3r*a&+u[X2cQ>EUXmX} = >9U"*r`kLD0I Lw 0S?I-`d`zf`0f`1, G3޽ օq6 `+VX,dXJX;MƛN X}ʁ*js6嫋|4Xnmоw`~*̝zaҍ0qf%#` 擦|_%Kvٶ ;aw v2?qj.Aeyόs'H،uXI9҄.ݍ=?UX `B6Gaq^asa~ M͜ pՅ߰J}+3UX"!̏0nP/$o J09~&;( ${_z?gˀ_cKiPKpʿ|k`z3tBS&/,oj-<6 +`[,we'&cٰT,M%xEbXكE'p"Xpc,Svh澆U3uaޘ#hJ;ͷ24[aN渕c\#h<:g~ s+hACur^s @=e79r 6nY>P"4] 5)f?a͘WlxڇYEu7`?PU.6d8iD9 3n`F=faFB f`0C!f:1U2czuL ?b阖/Zo'LiYf*isc1uSSajE*ƿ-Pi@] _ Ő Ղ?- {z>dk+ {qo {]3!t/CV8d 2v@ dj y2AOLȼ\ ً!kYI.dBB2VQ!}{2B{@FLĮY82:R1ͅzHW̆3H=TtHYeC_($ބd"$Cr"H-oHTB$Br$ [!sR!-7RHCw$'E|=HǾv-nM'H\ { T R! RYlNH;2^ ᐾa!#2o@Z {ٛ\EsCY~5!*f.n?v!Z  H1_j{XlAHu Bl򐅔Hwdq$Y^ 评De2$wCbd?oxsE/A"!nq] (]\93" g@1/1T#oB3= s7tan4:1c-)h7>g,^`Q", wb = Xy#EcDC# VOuVX'::vN78A @I躮I-m=``5}x0'Ĵrz0po~p^r+Cy7;% _c ɂa0Xao8j5a4 `A" Sa ɿ`xj atƾ_G.|#X2 Va<<O͏uc:M٬f=y?,f=t rS ?ln1pa:XUKBk΃|7q f܀ߏ7=k<[mƖ~ځG*m`۩vޜCp5B|Ay~^acN , abV/-sTn^48_ŞQ;=İײ{S/L>D@ĽۈSGUD&F lu\ȿ "Z J28W*@T:  iD.Dz TDEmDr1 ycl%1WKs9b"vtb=.b#O#6abE񈍚ئ㈽8Ɲ80ęF\,lCܣGW+C2ğ*Ea vH8lf%htwH<Ԑ4! IH $ y$>Gr%L~ H܎HۇTHu=ԌoHcca+d:4 y iUV4^6Ҋ -2i) HHH-A/ғ ڐa⌌q 2#l 2TGׅt  Y:휂l'32U=u?.#+ $,ȒيwO2@f#2#2M"s^:2~^CF dĩ"c0?Hـ#H᧑rgRV$fvGB\;5`P( *1gy$FHڃh$ڌHBN}BBB‹`$d!Ap {^#ž˙w tfK{$2 ՟"Ѡ hCg 7 /$acܱFedҐov$q*HG$ׯB~ eR\C^B"=#~L Oev2N!Sk12͕i lgֳFֱ}j{^A.#;d w!f6K%=/!}dUBV)Ɲs췽^lfٙd9B֊?2BBdnGU2K"98 Y\dU, d 8s-և댷ؾ- Cu2[+r֪!9[ZSܥMMOy˖!o}aȯ..8phqJšO8?Cqس Grp$iN78.5@ bס`8Zc=pצo7}iCnd԰y%(3sQ`#R8>6 zfjZ(tgmA y+Q((Vjy Pu fv s7%P X_u5~i(.j@E[Q\W(vSP,DJ*4Q8J]Q6R +QMlmDeKQA(Fht)T~LX(%P|3+oCN̵AɆ^#e(sGyQFš8w`>*EPہh/v/D14J::lG"PyeQ6 %t]^D8JʖʍQʳ|yQYo8f*G@eH(ttqb*:~ᤆ'NǢ*s+[Z .jf-P345QsP5$_+ G @WB4({ǃ u}ro@Ru Z B󅨟d4Mhvhٿ*rhu)OC;3nY͚qC 7^i tTmE8ykB4\jå#qIK&ѕ]c?=_+(KJ\QlǕkZOndEb>n!)mp&.íOq"mqx &?C'+_>-~xL=ۆ컓[/OsE@4oXԎB/C\d ǀ> q/0rO 5_w׼^ZWϴj1\NzWE;HS]V`qs$:|e*apgpy5\ޗCϪoPF!ޏ/WގGe2dt~C,!I@!WtoF%Yt 4нTnv:=]r z]ڟWke]]uXTqI..h%ǫ_pQ#."Ͽp}:3]~ t?Zl;iXN1-; p@ 7u\T Å;pa,A7ct|\tl tdUA{{G=89m87{Ζ,Y5y 3qF,N_J8Nt^t N 3!N}8=NOPŹ8m>ٍS'ԏV5*TfN)©I85nm#іn6h[5ߧZк%ZZ;Z[Ž-KEZs.ZA&n%4?KFsz#gW]Ѽw;Ѽ*5l}k~y84=hj3CӁh /_Dc4q4?GC[4xڡaVEM)>G}^ԫH.RuɻQ D !Z# D(("B1n@A8[!Ell+7_gW+ aWPy BuQWSяi&~$'w꾇at4@CDUws~D݄B bw Z3h`;>=XzɨVaMTZ@pvBgzA8¯!TN+D<:%?!:MI,D_@t.cs!4MpRB%ɶ3 : 9C:Usu 3^ aDL֝h:IہzLBb[Խ@|6kNq W;uNm?Qo4*֡x]E@.4j<jXl^4ndkg\ |)ѰYL [A vBiQ6?L\"}?2,1ɳ9,DOY1eg S]i;ǓhX:%A ?/埑!~@`rɤqߝKc1M)aʆay0 S*!x >H@qEM|!,OA(pB t1pRÄ&G,F_w@EQnCѸS@Tœ,!\Ÿ5<c\ez$'C3Ya`Q_ CZ1HkJFaIT@0 &CFp8u!:ø`: w!#7FXVCPјRvv@xj56 ^iS! %_ x6?7f-xk5 >a9! BԹ0nv@yo=x\6߄FdYqY~̾!3 gAtĒnk!zC۟x6U?]| p_3A;xTWJ e{Clv`|qBdֈ:CM n176k  py`4NGÿ,4Fh2MVہLC GS{Q|r٘9wA b5/%ngn|%dNu3Z5,A}HԿaXmiA}H4YB c&}~=[CQp7oаըEuNV?XL7ӱ|LGsY4GeZMahN5Ѹ -hp=oE띨BC4jCkZBӴ`Zu›heֳ6q>N2-hf~T&f 88{9DѴ8+oS'NyأyZDh -&[>]C w~cZZhQt\4eif9x,2k 7nù࿚ף^u7;?HB[9 e3$O? easXf|-L304 c~XU-gQsP;|B*Ѡzqނq J#sv,G&OT fB%K;mO1;2g x+v j8EHÉz?>vS=μhv)p ۉple~U9Il(8}S6 TWNؓ|-8d| [Jpz g)58K*!.NgTsNW©ĆUux͵ˇ#pv1+~CoжG68|醣q4uh30\8$6Ѣp G}81pSc;71;GuoQ{ ]ؽMk <K`{> '{)l&mO}ք?,݁eCXynvX˟)rjx',OOXhrVca aR8I¡s)73p}a/< o ˜m puÕ<o``4 M`' ~-oðM[y l`Ȯ` a?6k9lo؎ەv-? `#س ~#eCPj8y?_.1|}ӫpV ާp1Wp ΃˶p:unX .[[.ժei̟ p.ffgvٓ ^pºIgr.V9N{nٿλ༟%St/~1/r ýepxw\W \Kw$z~۳_a*Apv^pgx>$s-8 Ǚ[Q+pe坧pV+<8:ѷ7Wg`03#Yۏa;| l(zmVa5jsv` B.Cmg2VΆcP~5o$K}b fHlfb:T4@Uw Ĭ0K!B̆WPUH{\:0sl#+04fl?*>3m1=M´g0-i/k0pF7aLPM!PQ@?T^C *ٰW 8݀c:TCP:=NBy0(eP[.Pѝ Ru*Pi;6*J3/Ow!TnLJ~ NTRL}Sԏ0Mn8^ic1mL=;S9P*Ҟ QP~-PnPveP^+<<ǟ~(ﶁ.?(ς66ހ.Kn>R?N@iXBA)p#<BҠ4I xL EIPtbv {CiV(͹%8(lbM(Ub*>AA ePPU9PZ Q{I'(*CG(jC!s|!wrڐ UA$dB6&dBo\nKB~gȟK|ȷu`ﲠj B!i PXc!D @AZ0,% Ba~(B,G(J1_@1%{,NP{ WP҇qy(qx?(rByC;{Q wp n@qOeךiIȟc>B^q(%]ρ\ X&B v܂lCzDBV(dnAf2I"B7d8_!#r̞XK\oB\ w ;[!{e:< wr@JŲ b((Aal(؛A@!b| YlX6߹B ; (!Q  ˡ;ܳ2)\xSiPX&l{R?ŧr\șBe'I'.B1 X9;N t@ҕt=B ufBW+M|}pg!mQ윭@-(f\ $JÍT P4PA]2rKW@Κm3 Z 7{)/@~*M(\~mC}P*%s2 M'7 1(N ŕpu2t` 惂)YA aW An,d.L8n<1]82IZNd$!C2!c 2 +3OC~{GXz)' ӽ2o! dXo#ckfwCƺ2d2!`lHӁ7Ȭ=}>"d?,CV1}p r>vS  2;p't@ ʣzl *焩{X>c1鵽z3+0sfU~>Yu0"jP{ʁF%8Cs sySU1Kh b~}]t,E a+ǒE˰K/X1+¼B0+;>asW3 kCRk3,T4(};hC0Ҋ_`" &4`v<2a`O F W`&N07&6wY6LTlLT LcazL =`ZGv<̣'|]X=rn0 03ٮ0 4K+lDnثu3 pz48 Ӈ08 g3]8=< gW:w8rXHTbfnmؠ~Nc%tyCdЍMgglل͏k-Yt>϶ckI!f~Ӗ uӍA؄!#i.v4MXoy*c{Nw $a8_+""]ň:HuC}hRD_܊^ ˈy؅ 1x1W t^C ؔb8='~q+wl璈S?r=?EJ_90 H F $,CH@B3$A*$J#HlEiHZIHj.S$ϛYHfE&$5CX#eg3R ZNTAAsIC&ҎEYHe ^bdD^'2vi#j>2?"S ̐&D2g>Aʲ(LHՊHn,B $& $*D=| yI$/,FHvKdnHfʝH:H^ݍd0$+V#yr71LCҀGEr<\ԇb$w $^BrND $;m@r$f%lFEH~)HY}ٷ2|r)ڧ!elH)L)?t5?:46<imBv?F!]cҋH{C}dCT8LV 3=d$2+m%Yg2#.vQNG%rtŐsB]vV"ƗZnF^@ _#o; !rBnyb~GP@_.Br ۗ=C9a#܍wÐ r#7M c!2~ێܻ3[ 6"!r?/E WM;.پ_h|x'OY18 O㐬5"zpDG\78_hz^8-C{칈#g&;Ȕ"rj ?BQB!w7 Qx=?,5à(<wƃ؇AC<(9RN< O'-7xh1Ãp ۳k1`# >l*£ b:?2G13)oxànήB?w,߸c@L4%Ө!+93 |_q-k9? x?%VH\pH*?l-՟ hJ":QO-u j@8cnhA(# I;Ϟ ?| " i^$"bgB~*a*9'?dr_ēZ r;:d9l}z59rL񆓡_-KB#cZs3-]8'uig'‹t("QTiunN]%P@ ;BM$̉I]tr}:Σ.tr#~1>rn*RJi(` EOSt=tb)BR"wRp=Qh}mѽLR k-GZ5JYy} &dLMfO]OUQ"3dFҧhMl:-y *nU9w>lKn5gxN Ώ٤s }$ݗ|]9KN%4"k8^'ML Id!!˦dyΆ"9Um-K~RB~\mZN9ӓ6K--AïϴLc yXǓǘ*!٧TM i>6dH~2yNcɦJMc-&9."~wr*!dU!3y"jy2T6ő\5ylJ >,7 -I%hQ ѬdnD1#iC>i|!uã4{?i3#˱Ge6tÙ~%%iYp2vJI4-J#H/\=!i^SrZ1m~(Ғl-K{ٯ$;79$QNd|`5?B*.zf|#KO䦣Ff#;e2"=\1H%y/e+$wTXM>oli*NrOFJwhRX%_Me(?muM>-vz?\I~XJigN ]Nw&&m"-س(E%Ke m(~/즽d)ƄK1te !+JqO)HWD[]0$:0}>3 };)$ELVNiՔk%uh񢨛!hD}WM5%>T)P̉GyIS 9R\;:;)_@ahP m~1Gn#d&%zzZEn㯑WS*I˟o^ | mXYIR cvr F.h VB7?<">`DnOim }g0y{)aBOun#.czׅ&v{hcxH6X^? F>iom|t3FV}OPp)m "m IPTӦoh 'h+Ӷg2"ER5$vK;M>BSOE _7]W/9A9S$N-iW&QmWeH vV p_jQĝ~ -_@Nim1h&AVʴ*R@Q($e_m`;`icuZS+9ۑ="{Y#Ӿsdca5x Y#k?UNcȨ!,m%d;GadK+"/ZJϤ/bxh͏.e1Ĺ~V-OzLH?3l_ FZ{EN^Z,nOF3NuY }A|s CDjHz/I&㷒q62>Yԛ)Fz?ɤ`9v7l-T qhd6 ' 5dW_hҐ/Ӓd> nuLȦduVW.F!?tт+iɨ5MZ`MFsVޠYOJN(i]y?h$ˇ i8n'i#ZT;Hy2I3Ҭ YR-2ivlŲkiWS#I_3ɎF2M/H|} U0mɶ7cR^O3fia;ZVBZ[hQ1ҹO:}d84l8C:Q1f=@kSH)W5#-GF_oIMj2Kr &ݹÔmÂ^́/uMǑnubm0m4{Aȇ,iDIT WkFq9,& |266jWNt!dl5er{Gwrw$'<&>ț\G"N rfr3q.%5'A㗓Lߞ"'5ṞS`IZ_iGkN!u4Tr5J+u>VDKCג{mPS&u.=񤹯׫hZ5imGAS+hEx2m~FܥQ6q-VC6M$ lhS>R}X̻oZcN[K;yͦW)`̷wR`% kBKKڡ-ȻrZߑ|*[OZ:3EL'Q3=9VՊ1؄sOЦ}okܤmiG3-{8-4!OrB)hlՆvQWt|mҶ)p'P_3?J!Rb ~筣EmMsRܔRh- “oQPeMA{4o|B?Ρ=%6x3[R{ ޛB3S)H9N)m7 ~*SH=/M!So߾/=Д4|(i9KQ7(G;I!VS(ʣRf7 mIak)0B5u E \Nk(l&ŭ@)fQX>(a*JKS(;J>2J R‰aUHѷR^O;&P'2bzQJq)ACFkzߔbC-)Vg|NQ7JC⸔2%zG(QB)mS:;mrשR.tf<8vuhG{oeh o3(ha:h&iO}6}ӾQ)þ+)1n:-h/yܖӢTO{Jӑ=)'J-':`[Jc/xQzNܚD9NSmٍҧܢe3(sS2)M3hM9M)geYGRsx|2L&MJkߒ )V2>H(ˤ NSVT8F >17LE?){b_ lOiq>5Mƅ:Х%ev;NijLY)kʲMs?e]@Y,) eF Ӌ))ӈn8FXShEWPJ:E[(y=Jjy#(!2Rz \?Bo-hg +OAm}(؍BZ I<}(BS 7WmΡۯҎChs˵1ֶΠ w/&4u%x&1hEӆzpX_'/ڳ"=mP'%/o|_a txB'z, @1IRnKm- P ֻo`1<(p!pz K֓_KL]'=AŸ;N@j jIb(f: 각,K)(+U(𦄂& KR@UHoSP" 86'Rؘ¬P/z-ŮfPKa%Zڅ#wx–"I}6^m]?BDk>h/)- F~sDK7 ޿DE >M+І=*?&@}5ZD5֯-h6Z{]|棧h䛴=(rdwv,Z~g&y#/1QH'  h,?ͦI9L~Zh0uO? XNMk_,-M w;A3hAiZbCgk2sVHkhNX\xVvK!h4?']iXZt؂j% -i=r;YNhN*ShΖ&Q#ܢ)ͳi|;zA.Nzee6͸IO=hjSv\.oK?Pߩ2`O;7A54\PJeXSCwsC2iG6d8D+P!i,ym#a2JƫQewsXKt&?#I7t|'i7pUeS_fzo Lg4482 #-$y5jn40-]Xǖ&+47 z8dr aCMm&i1+Z4wM޹̳Vi/o2Ef h4M,& MdYyL!ׇ>D.@dn:GkxКgiIZUVA^;ve!r^\4Z`ڻ}[^b}9RfP۠E) (ś)nR_QWRMլ EȀ>qјB7Qy ~څBQض9ƒ\( T휤C;G!??T 1Ӡk<y: 5~@ՙ89I(W =}@!3(H#($k1B!W)X DB^Ϧ)XQPi :c@EA߉5Q J45l)(qsv(a0~#oAs%.HۯJi+sgX뿡yx%#97v~G661miC#xg>d&i*-MyyAZ mFycߎ6]H>vк~;~cӚȫ0h'&=M|N@dF^iM%yHǴuZr?BC hjZ҈<|fXSHˢi?*&/iɻ 䞠J7 ]}P-~NhAG1v'_4X\}d 9.9\L΍)t?jS 9'g rC.[ȹlrtSg95!i)Z\Zl7rCN3ڐC=9Fn;8M.&I΃^Ka.N.ѫ&Ѿ9y9-#d׬liМ/dwߐu49޶"'DQkdwu״'d. Fw9^ds#lhU|f-Xf]1Yj4,ׁ8}"Mslli4 z9L9A{f}96 d_D4آ%T!iJ3*:w1*QbNkLfɼ&e͈ Ɋ$!w h"q)i82;Cf-hZ,[hLm6kQ4zWmE}fҰ4< ah]2IA8 O;`4tf La Nng@Cid]6 YM#ȑ[hTp;ƝJ9$TKK|iҒH20*&f!pMƯ/?hL4TƧ{D'$f|&wD^ ?̜Єv4!VƎI}" D4,@[*2{rPޗȺ=~:fa->DҸ4dvR(΍C%h*i{dNVE#j)YF!у¤YtQb}7]7n[ES9 49Mى&]Iiy* gv!48M%-*dymbI6GhDN6js<}YǓ]zfXGVgJz#rYUhD h4`.MLS%Д4UOSޠ~4eZRuMK dE4RYLtӔb 5|M~> 1" K B3ͥ٥5dBӌ3iV da hzKܭQԪMԐ4̒f/lCݡwipxVT,8Ư=ٜ5%';dp%-PJ&ާMʜ8r(9ɯȭ9{|˖pgZJ $d46+@nҪ/QcH^%1y@Eq=yRPD ):8ǹQnDCP~:kQrw*A(<(>{+)=%9- )e ڝ5S}EhwPM).Q]Q%Z7:|`Jԡز[tbd~f-xŔ6%;|sK3v쥔)>ś6wjkWQ5yәЁܡOm(y?OpnוBL"uDJ!"(´)Juc\ߑ%Q ϵ( {LHДcjF{wRM Bs(ȗӮs75,OO1KS\6ŵa>EyF)x \9(v{igM^(^5Ŕ;QbH;C)zĀP?$ЀFoR FPWc7锾%~F{HYg]iUsM?m>}wPJI'XShQȺCPّ=EAq7(¯.DaDDOdЎ "֑XCҚhm ns;#hkw!myGhqwZ}=-]6eihA5\9mDzЦ+%ؖD~2Ϛ$&Z'Z/z<猦uir7Z{+?VOkѪhZ9y/_NQɧpynF>iC}?-kMZ6y-->C+\-gr{$iL&ަ5h'#ZphͤpZcmK";m.ƶP[75xNi#iZGZC"Q4v(E3O% yM>J$+iʪ$>E1i?#K~ 4sZj=Uv4>Y^%ӂ4|.v 8؜hQ??w2~0X%RiiSH5mi_C:I"ϸB[o}~+uΤoCH-7Q׍bIIӹŒfJ[Z zGw*-z.b]ΥtjyZS kͲJ45̔vS/Qwj#:HRKń jNm|/R;r<}j׃lAm[S[s},uٜ:8&P|4[J%_fK>)9m.9Qri|yWJҖEXͩ$'J}$m/9vEudߠ+t Uɞ$1%$ImJ®DIbC'JviJ/gKJs%I ĝl)Yo$YKU_ҠGrrx^s/I|tMl>WŒc-HJK+ \1Urxɫ ÔߒwJ|\0Gsj2ڒN򲻍侫ޒoUk;Py@W dݟ,USVw,wϢm?;$Qॵ$G^NR}j(͟`C/ۑb%˟Bi<}؃Fk5vJ-]S;9^]FV/ qAoZD/ѲVH#7UWiuA[H U]^ikaJjn್hi&G^Jlx?:M,]6۳ :_ lX%%<=$Z6ϕ$Nt'̔=ҕ?J&~:Ir:=$Q%)Ji\|vN"o<#QD.OH*_MTΜ!̓Hn֮[>In)9qĭi0Y+#9Mrد$)UofInv(0*l Ԩ䔪Dद7̻%OLԬ*9PhɅ)dH*-$_$N'I4J2K.̒ے#9.TrzZ#ɕQ%W;y)1̼J=Ow S <씔ДY\MvZm;G-INu&?K$]KL|@"Z"=j&)XRz$9e+{d_:d7]MCɥOH妓d c%GTH.:fH"lER|%3KR[IN={-'v4~͈+ d{ @Q$f%֦Rcy,Yw1ԮM { %'T"V'=ӧcP*u?A-vvmMYWϩ_3L!wÙq4tn=4 B4X hX/J/툆sޡ! {!1rАА⊆=ɢDCCnh쉆аj7c0 A |34p&V_i8'YdI812DzXm85 G48jS#&Y#BPEW|P|c8JB$?JEɭ2Fl@YQ?HS 5頾ް, r^ @(@Qō[A!EF.l4MPfAk Av[0'('E.](ڊMrQ jAJ6jz&]^zzo @}~隷?opx)m?/AoWߵAywwQWe81 uuQp=ꆥnTnv6F]8v<.B u/Q"D57ꀺf;*w@8q q8- n␔p L_1QVe,j&8jţfT2TPE/Eu C ]vh+Ju7T xʺ{ꐏ*j>QkV ʗPi4P2UfžLFeTNAe=Tx5Tl{Z@oB(5Pd_(.b6( @1䇺A.s0(&bl#]!߻ >=ټ 0]Ț];zCz2W%H')!T7Qv !uzH  PxsE\(ϊdBP޸ٹPʺP~|87|* 6 7(|~7Aճ(}Pʴ,`!k [Ͽo=YG<9(˳F\m(]|&%<DJg+%8pcQ|JGJ9z(؝82ʬ^,>ʜ5 m %(;P̾zߖfBqf%!ϓ@!P+h+6"nE5'qUP+BCRO">7BlWEP~}0I { ʀP㶘&KQ*tG=9oQUu3wPkꫨ*Y9*iT9"ƀ{PZCLi0f Tw@PN8yڐq;BOgѯ uҟo z 2GH6!KX-A~: Gq/_(q5v@(go'Av*l >3.6Va3֢6)^hd7!!ƝgiYbl l1_]CDcٕ/K! v❪{Bn.eoy+D䊱fkBr$C-4bPG(F-bp3DŒPXѐgu{e:LtdU! K!3Yڢ {.ۈ1c)JYo+wQRh7mP&qb<{'o!v^* f(;B966|L1r d?!"]Ρb6b e0dN k1g-ev(=?e]7e-Jӆ,yJY~jKdxv"!=C[ў wSb7(Nzv%S!;xN Ǻ7AP\K%|!_+#un? Um;<i֫t ;DI%d! `.W4! !dU u] EXQG/A>b|/tD[.FU(Ŀ"5Q9eQEM։RHSBb}Tq"f@1@<Gr:T6끊W5D-UgQUNZoJ ŵP8vDe1Yr(:OaOBQg(uD苹2-GT [T~"'S?\S|U NPQ(Lϡ|/b8&]U(χro(vro;Ai'rv(/.DUT(͠\лP=EXoY=b4( mMQc|\PawKb1(5Mh|J2;z|TQn)&OuGI0mJP>Nsf\9Q1%*֏G "W&~Be(TPAe(o5D'r2FpTMGUVڲ=kP$ro|}CphjEmըXjDTkYp9ŧ״sE CM-D'fLQ-5P]5e1δyZT/݅-Puexҽ̬D/* CP1< G(/-އ*jDF(ElS-36*#E]ƨ-jm=pHC&⨨IT|ȑ?,FUqU"A_!o2HOYZpxW~A'J8CP{L5Q-oQ[$ʛo ˗~EIT냊P ߗ+3r5(Ě*F)ENk/d!Qs! yoG]y"? 2CӐw"UWBK1e!oB}m)#[4r DΡq@ky;9g G[bi_(ǐY<s"s0doB~]gHK^jHszp`p"}Ɓ.;'H]`W r`ߝwN{,ǞES7{z6aw'ŮZ]#*1)H1َ2$ad>r"i $뇤>HJ$*$NFs$.DHx &!JDZ+=epq/Z"Vb3ї!zlш'+l "@ I*DLĜ]l#lk"g;"X11jBÈGx]bHǏ$D|?0B= u'#xy}QP?DȌ#8 A"A@YtDH,/m] E%bw1 io@+cQ>q"vLu}})l7lm&2l-Y5#{- g&llj3>yihbC7XPM֜Ú"}is^«#{\ԯ68/8ҀG8ep. g"8el0o8MphԅpJX籇,~Qnpp ..;uxOW%d{Ms%pj9f׾N88s n8mSe9Îz̀My \_ۉΰ66`ۮ'l}+1gnةynfM38LЅ8E8u g%pfp^p'SxK'>

    8 D8=GZ8<ׅC)9cاvw.λv`rsvopQÜ9_0L~s`N\uQ_= g~?Ta/~#M/≨8}yx<9.SNijW; e":".s\>~ .1p·b7 ί3\ D\nP} .E\ qV+ڳ*fpjb1>xJqwN4,O11qHZ86Z.u36k߫p5Z)뚇]*ed 6qH8.k+ޅhWð% 8Ǒ#-hx8SvpnV sp8UMp ҆8~,%papNñ 8 X|fr?`֮(YO a},37oX7X4E fcz}Z`@_F0y0 &`R8 &*0qU0{&&0q 3`<&ab&6w%ME{`)uqWo{oc0u#[%e3ȭ_0ZF8Bѷ(z8m}Oy>^ޭa(֠O5ax7 0@*AQ aР#`p< 2`>5 OAk]tka9`fa8 p am]>0xp{L;lzǗwhz}0kìaΎ0 0آOK8mW ㏡_mO~7%OH~t9;@ߧ#Lͻ?!C'^UK蝨ޙлEl^z =s|3t-/͠Bh虽]ޮ +ۣkG󠻭tg@w=EA NՇbnH!t{BwY:t~Ξ X:h[B{k(mA-hЊy/5 Zc7Ck|T+r6 ӡ]u?- tAgX*t@'=t WA :SNgOlǎK,^.CG7:FA;*{wRzMáweB.tʠk<:~B:~~:CYovsA{ڪcmzF=, ڳB{Qgh϶z-lh>[ͽ;9-4 24^Fwh6 N 4~OB+ODmMۧ-~k?uPz+1t.407ݡr8쬡uڒZh/uMvxϠ:WAh7@xOV@{ho4hodh>v kAWZkώBsKc4[Bs8h~= !޷f ǡYh6B+KS  mZ0Z3dO:fwЅ5t | f}M}Z h]>qVܩ3Ԡy?QPWf8]A}1] i 9PK RR^9mE|ʡYZKU̓6x>kQ cgou"7'&5@r,ξ j'FBjKjF0A5P]qQPujŵw1Y.Avh4Fhj@Ph5vv&,? 11}o`7 n5AY->~3}S|1-0>ab3 &mŀ0녁OaІ-[-9wŚW8tV Nor5}&\eCOppL&#ش%Xr=l+lls`? |R૨ >~ o{-Iv;q) E C\ဠm Fk'!e#:`W=;䉐V5!Ct|BF dfBuDP} !~$H‘ [` c)b kv S Rpl+'ʐDHԑx{!$~<$HJxH0 Ƀ#Y+#eQ.R %xRf@H;iH HY $!8?#~"y`_$|JqCː$#HGt$ ?'WXQVHtZqHH"a"{'!}%bGo@L%D+#e+D{(@Du؋+:"{@oGD#bkD; KatzՈs1fаGDYuMCRqbDxtAD)DT_FK "{AD.%|/ g:_FTň2G*D%G!D)7#D #" Q*SEԆ)Z(J?(3q-xDooADMCQK@XDnȝoiHhJFd4H>H3gDڎF3D:#rwD]ADFvAdL ij E@G3$ﺅܫH>ZIqHѳE+;$7 TC#LFH. 0lɭݐtIU凤H/m5NGd=$YDџ"i$wQ.;"Y#I_}zBH.BH\}D}8~9R.Roؽ +cOKسcvu^*= 4fa_Be~?f5MHu|hٙHsFA"=mE,d C"˗ ]=8vE*A8]ZjHq"22ŵBfTdGf2#2ô;2K$@m8^Yc1YUIctWlm?o= f ;CvPd[}2] 9F{35r#ͰD 4n#o;&Be䝞oר +89\gu|s~9s}rAΠPnANjr!.!b3ŧ#_?Pz qd (l6 J5E~ 3uuEs{ΌDn߉X8X!W,6Gz]<'䵊Fnro-ꋼض{|7IAWE~.^Pv N^&VBQ׳(**@Q85cP:ǧ;4n̬ J7'B:td!QE +bP=uCu5PxgCݨOCT 4Eej- Q%ꣾWt@m8_Ȕ8r/ǖ8~&'C8^JgRqV9@󸎳_pR\xu إ (g\Q)!Y]q6jޱ wLp_6xڎDchF6n܏ƠuxevٟѸ{AO<Ep_vpF܉x;+nc=Xx/ԧUxuf—nٹ-曷ۼ]`yG=wٙdUټy7Ywvnwtμ{zugyw/1ocy?>-Gj7MƟ>2rVKW|ħˇ1d"ޗxWT U^{Rgݺ ['x9.{ 3|pA+\c 5ŸP%SgŶ6. ?f=zE|qz .:.ŭq1`1.Zip(.ۏ x%kn|(xHYXnqmpqQ+\(bf..v p%8^lwm=Ոso.\" +vgC.8k _qnp( AgO⌴FFü98S g$z DC:4hÙI8j"Li™8s~?3:qzXqjN5éM8u]S'8| N,7Wq)״DZߛp|Aoiy8nNMiSWc2ڀwo([V [ħ8'TKpj\Tm[9ڨ}UVjTMy_cP,ZG&TBe%*wnDl?Q* 90~r[/>bLuʫ=J6(uzA-P yJ12'rM!vSlpH?^z>C*sH e_lCٳ(/CxlߐilHB " wePr0(G(G(0 ;r\ E"(N|tգ\ą@W(?@J.P)jH[vEi.J΄>(xҪŐ}٢InٗϟO|^Z6lH [#PrJJ4tPJ&EvQ Eb\M̝'PveL!5ewF< e mmK!m+]Ro-H{VRz=6{OB.,/ k b`"dw:H_wtNvCn8!orb*[N?2-ul2 P8(˅t]IP/KDN0%8TM+QtJƗ.(9(Wv(eP%osP*لQ`_P.C y@Yh ld͐fv0菲 ]i8&FNk,F$d!OoSXu /O/{&C>=>A1{ ]c su/ }ScE<&ޅ"lFBf52'7τ\(Ca -(;tľP !;ošP1O;wF(APŞb@ӡp±$wD7bEKBe"TAե"Td⺸W9T,׼~W&(])]|?TrH @$ϟVc9d,X䓗CNrU8Gzi5šla>rS(DY^}|5;Pe-P^|Hw1+#~B.#r'(1 eo7j!m[wHTs#&_X$I(e/[=uӊ1#,br /D12o[gH?tls3!V GAvEw 5w(d sYlx$FWI!됻'B޾Hm!{-OA6NaTLҧO͇D=A+N?bm2ʜx H'~Ci(ӊK򜸷dGEE|#!SWܲ"6Et󖈕VڊP~ (ʃQ/?P QW s6_wC4Gz5TĜrt(D1;/ %7>A .Ƴ/PŚoX('qɭ|گe5Pr"Ʈu^(>=bY(ns=CxFh(޼AP1GL-P.1C(DXlۊZ)*Q1O >P MYb'[O,[k /5ϒ'ZA-v9#-m?C -Ϋ\ 1}ʠ"Ǡܻ嚫D/J9BV rv_9ͅ찘fyckuA&Qy(941/sG(5?RMo.q%J:*ǻ}b#ڧ"17qN:cQ%{ELQԵŢ=@(]`b]{"#(ifQI%Qpm EY(4ȫj")O}Yز o#f22]9~2^@Kd݇ d;H#Sq`AGd-~죋39RZOEܻVd}ـߑRȊE&27tC26GFpgV6 }>#-k8fBpFp`OG"ռo`, _΅wۍ+k""ME(D WNW *El !+".FJDMc}iw*Ǻ~1kcaCx[Ob[?UXi퍕$tہqXcw +Z£gbYtn,qwp7|E/xQ,EuQXxc ^[(3LcXPm1?{]|xZp[ n*1Qm඾nIqp3y7e9ai&\våNOl tm8 #28Ucpx> г'5s up}Z_,8F,ߙp|bv|gӋb(\I-탓 N'te$4NZi28Ӯp8u᤼{_1"{| pG:XǍ.=_Q [1DB73d8m8܅Cd*vC8C&"D0W\&~nn9i9K0r y=} '6vK'|˂Mcv5?f{ X{Y`ֺ5Db\ f5?|/X7*Xt,em >)g؛f>쏏mGb[vo d `? ??\c`Űvaagva7xQŜ376Sw8lf&6`{7?C6vqgqsj_Ϳ p c6'sNXys`7v7E]'ޫEaßvI =^d8yg#p.Y շR _lg?pۚù#U'\G{V!?iQOx{{σ`WdQTþnxw` EpGM1ql.dppewp@/#ؿ^"f:5Ns7l2ظ%[FXލYbX˛ay`8,.kA1t(ouǴ6n)7 1e:&_ɓ#1%&Mׇy 4TA^ĢLhE0a ?؈-$Y~,F`kmvbԆmVȋZ9$#VW`ygIvby7c# Cfc0x- y u  0pf }B0а+L.T~{4L=6 60S;LuCg P<ŀ~sDoGѿIn0w`Er][>G`\Y;9΂ FI&0ڹ Fa)FcHw?=;~i?j,|>ѧ1z/GC~}F_B />v;. gDðzDVv0?`ئ/ a\u{`s.ЏzA/ MӃn@%t絀M3Nք΍p,񆎦?Q{ P[h +q@7h|hoj m9c:]'t /@ltjA tޮλ,|$ :FB :W:BL]-{t>@O9t/Am:݀ЕLЩ hyAǪ t[ChvFhmo6!=fE|hx1[ly9=@{( @\|?uK݇JV?DwJL:T7T$_b*3s5*[_@wTNCoؾ P *VPEPe[>hhP4,3a}ag ])-3[{B(-B~-o{˂}kd6C%Cj446FP{ 5PA5WAP44\O@s߭P߹QOz@Ԟqrw4OA3e4A(ހSc(+P aPZPi/OEMzPwVA}Z4{%b>4^\f+@˵VЬ<д М9C킧xk6r fw{ P/LOBH9zqX#owCD_= D[f{ 'Ż аx sShzT^56 6P9 *qEL4@v=Py-J+TLC2T6ʢ:XlJ:yі1MZSWlڙPky"zBaT#O"6*Zub%TfWA%Iԧ*vPYi-Y';3 P,jO?CUԖ΁] зPk̻-,mܡc]5Gn@kmHpbDYw@Q\C02wS 7RKd7sm€0@%Iam %:# a%_0|`6 #8`>ƴ)˜ #킱>b5&<4YA?LdQ$lGt&7T|L3ô1?f|c`91CL7Sav-Lk`tC13w 8wT,&=EK={o``1u>,2~ªXEU@GX 䋘rf'-=X˙m`+waywSa=c֣Z>6o0g| 5|8C8NǸb ƷpN$֕NlQpy lmHh+ [ēiH=I=drIc5H ׎"!#f ec@UU9%"VF;{w.!z3r'eN ك"{ b3DP "F#h"|@WoGwڀ 78Vj.uAZF\Dh"bDOq(D$LGr("DE<2BJ6"5C]Dz"2@HD 2 @s 9; 0-sAEDܻDHDʙ蓆v8DD쟀v&!tlB-\ 0߀̓%"#bDhuD䂈;ȘQW@UDL7@DDtFx5 /W!RwXȾA<{o ]w!r!DlVDNR r^D}g h<"!VD}GTD}pBt DGLDӬ5b-@LduB̽y{"vmQ81B+OZ![?Jш)àcH(Av '[#Ѽ%H놤H;9|G$,ɫW ye.FwoȐtb9MHq%w$}XHS#Is>@[H-H|  IWILGRIyun /$Zi$;u}S_ː2t RC]}kk%vy`l6^݋aسv dN! `_ }a_[{z]F!U=RNp"nQ9Hw H`)iMo? i%[V=Hc>}%(n-AH;͐\!g2 #k2*#s\d|PAǥLEd̠v"Hd~FȶȲۆ,7doC(7L!M[dFVcF +{.{[#{!wBCȢRd"K}![y ; u8rvCn5{'N"wY-<u@rF#w:4 ',9̐WyQ3x0 Atd'Z!d'A 9#j:rڊ|WB~X,C(_C2_.A%]9 %䚮@T{CyDTK5W wdWDgBkJ.ۇܓȋ" 2?u uF#Y{^A~1ȯL@8X0>CQBQ(x鍂Q7 B!d.Cic J~O@A(-KDMgoWgK(O|r(d='$m_<Q{Cߨ(6GxU3P5QE8 .r4wۃ{p}#lc-pbn98N,DS-;D{nqg\.lPή݀wqVk6-g pI\Nƥpys7\+fj \ č3qc[/-U|X[rq 25ŝmn?fU]ĝ7-qx6uƃxAK4]hl 1` <z~=nƋb@=ƁP_v%yh3q 4θ,q{k< q=ăSx0AOxp~Gћ1xwߝO dߝ967Ì^N ebtYɝ^;-L{}2̮m =ܰ+jLQ+jEFnFoerrHjdUW۩t㣽Ezh~w^^xeX76ZikX}g4;֤@jSp*ѯ bg٨| wӬTϭ+R(m?J-V^yx 0=}luחKnZ-h{߲}s-nګʚ(0Qm:s`oN{*:^ӕw:+^YZ8s9^NЁVG{%~]ӡ^ZYݬي]CC'Vb -noZnY?9` Kl9ذrWӓm2iEnHq W=L4gFGziΜ -n.%͔Jݔ[CG4TҢd+*d~]:L}l=z!֩yn=C7[qt%Y&:ư9=J+*n޻Ve_]ԕ>ZuWkV -[ N>Pg|E5VieNG.jly$bGޕK\}R GG7 eBlȯYL^vtP;/DS})9`KG;ZvRjt~݇u\no]UnqZaiY <U3錒zmQDŸ\6S4~v3}D?] /]өMV):b!gW顽)Qo9%7*0ר'JbΌLҚ6Z)Fakju_-v{&0:F`sJOϓW{I^c|a%=y}g]띧c7ZWzgyPf7+^ٌn3|{~wUOSh 6I;_㍆ֺQ'kw¾.{o]92B>lX)O_E~*eYQ@I bd7bǀb<f0YdYAEEQ }p8z}5{!LyLwZ@&Es]uthpؓa~eT/̈{sƠ%gΨ͡uf4џQUӛgosV14Ԛk1J#1>#6->GKbgʵfiF-Fn}q#Og4i#_~W8I_ԧFcN*2/{ ;} Z"ve }܅~+Oь6+t#Y>4$02*t)]"zǏXihx59}{͈VQqGal 2#=kf̈V/# #}ϞQg2=#[2=|t.-k'3:"Fk.>3.јM=flc yicS9ctԷp8:ҋ1#ii`,O4t]a)=WeLgnƹ>=3bcWL/ghUz c*c"謺 ޑ/ U`/yLF]ubsF͒( g5~-uiu63\)Ǹywn)ToO̢!+h%}jgZxv2cyBytNDža2k~5Ϥ- TUf)5!bg @Bh>KAP#e rފ+6vE%0UQ)O;9ϣ {#o=5RpTeIm)Uo[`?K USIlO/E~X>!НCr]k_ePڡg *o{Ơ#04ן5TF)O:lw(! tx1sc)s%XSB# sqh:  nCV6Μfm)7'پ`dZ`$~E׻hj_/{PW~gId- אRN?gah~ވ.Gbv/ͶɿL<\Gm-./6Hc͖X;,e%5k馮|+ᓟ,C= $ʖuKť^@5D9;RV?6C-}=gl]B&^ kWπO{ / E?{ W&χu!dh7H#$nމ:<1%FArKF]At{I_9߯1|X 5S9k4tBrw#V< >Lsr*Hȶ׵e1|/Q,}-Z [Wp23pV[9q~ c5]"gjqx |KbP|IB6V9 qԹ+Gc7o?kc&h˕ AC6iPFВ? JkywzuySm=@E*BrQ[vPyw-5–#݇jnD+4A_k#6)s[Fkk I|Z! 6846R ٜ xl;D[ E41  ^ ^+XtƏM, e[Cy}L5b  ZzD.@dFc v[1dp[h<6zq.=1?0wwpHdέ=iaa A,׵y]@h= dǗ"Ol{]:ǮQstAOړmbjRD,̂whJ@\5T<:#d@V#[6;Sp}=\wUs%_m ds-z~Bhe!ZH+\>P3qn̪hf8N b!sE>FFCr0U qgS4u4fQ~# /ޞ۶1]Y7bv_űnh*Ʋ5VՀncc[W[Z<&цd;D}$ ZȻxQ,<7fVeN. 2/ƃ5@t=: Oa>GWФ bwo $6 }P;"r{BvA? hf!nK:U!t쾇~_ H7rb&Wߚئ`U:Wa븥ŦA70> RR,P;H^ c^L\spgoM%7y=.Ȕ{<+̂ q~3l=Ld)-ߎٽ5{MM+QtYt X9:{bb_!9AR9>%G?@ď?Q+rq'2,}2<]!>VbVb\8=$3<QPfnc4BbA̻E&쫚F 4E9q+vˣ6{3,˹ Ura+TPͰsT_T|T\=UH) wpD#7D@kpgNDh [!5n6}:BxU ^G6C+Awޱv:A>^rvE?>ްcXr3}ؑYQw!]j/n ulW}w{bn>9Ԯ}(el t(Ng |sC%ɿ[[N}a|1MJA]Շخ|o8(gZ8zE=B:Hdʗ"GB9/@xA;mld "VO"s"L%N@d6O>QWGYk4 i?S>u1!#iKRoz&2Bf>d({E0WԬV ^%ٞ*ʂX2;^ 9i8 1{g^  7o\Pl$1+qb a8dB%/#Z&:'*UssL33p26BKh'7gv<%U2qKhBԭh;Q]epvإ.A9JOG(9 n=ȌA ^3\tb=?8^}/SpR:壳9R9pd l1u%p)= 7\4:n7/8o~ MAޫ T#EA=h)p8̏ 症w.S93Z]F hwkΛK1t&UХ)w=0H! 杤i0uj'EQZ]_z<˶WR۵R/ĉӇh T\E 2hL=hP kJa=1cV;[1距&LWe)"H]OJ3nR4sY_N]XOj-P@ uviFv{zC~ ݳQMӃýt9Ve Rق:# 58TμsAU}\Y2E)tcL7RYi$c.2V͵&+'HoRpDCcgrx}K=jZr; xCN݃5` ܋aꓐw@-K^'w&%C\I =uY}ј@tJa`X=ث/'d1ofmq 6M%߫c>@ZoHy ad̴]0aL~4 aa ;CGAfUCAoHՉ!o~;- \a(PN^C7rj;j c @!V-|AYLC+r%3x#a<y|;| SK+pY/ڃb!DR;@7M$g}m䍗9+[nJNLMnaׅsuYёL%͠Yb{6$#GWFIB:,Hk =tșQI!ȍ ":3$d)#{Ĥ̱P]<&RDԹ2{H=Ȝ`~ALڗ$yV+w7h\) ( n H+ |s6ӷ-GBy\?}O7|n-qiV'TL&U: &9hdv#zd=: b'U02ƫ!U 4h|%&•}M >H$ϗ|Mv/#gDOkI[ H)HFjȜrY60r Uat ;E$u)bZeE^~5ۜ8!&EsX׈Gn0M|(\Kξ wrb-\!yO*$AtFtmIN$H~I%IÜG/I^H}~%>$))}JIE8^kdil@V #Kgh@נ<؟@݉G/t/!}W#AOߒ(#Ei2,HVHIADo y6X[6M^B{&FI|k,Me+k7ݟIģb4 lo S+)H"WIy'z/N'^IjD/$NRtsD,Y6!Imz ʓkNڇDq I1q")ɛaɛCqDbyw0w`Q](RHk4 Fg,5`bATlԭ.JbGQ)`ADchԿ}oy"woΝ33g=9 .:pѩ uNuA0 4™X;V!h>GN?\:~?>\^CYsi9X>f͡U% əWG14k kO1Tswx{)XLv7zlc43\k /BvhK2{-EdN$pLxJ H kFgV~O&74TfN5o*6K5bڐp:.FpP:{*ci1|QKTJ[g9Rll;"T::$H@Rv]D}<q4NGn&e6NHmcԪ hKx7Z4{ q%ݧn]kF™AeJE/7[k}j)zVLq=޴xiߘb .XR+t촴/pBaTtů>BeӾ>QԗT>˱5.I'mb*YIxC.fQB_$ޞP;PFhƓ(A?J̚ F@S Q' @֥4{g;<=3Yş A4/c0|{E :Dqɴ 5Y`FZ`< kz*ޯbĚs ɜhKTt[$ @RLHn1O- yu]y~liMzmіd[#2={w?.r^h=NԬskY|Ck+BwLEȆI_W GhS^?mer>Ɨ'OiS@~K6zWv3>xZ6!俢-+wZ gl"u?=sCM bvkI'9Bk(iV̟1AP cϨq k]ߠiI83qUh Fn3Ls}^ .h9!hf/{p:*n._@XE |Pi#͟cC0xעZ:1@|CAc&W d3bcA9GPͼf Gz?b;^,}HիG[]&  7 c@zU3ZO7h1t 1uWc8Oe4 ;~ vbޙFN5;Gz,K9R}N5۸Z8y~b pi!:d%~9!ȹu$+T)HCB@d ,A\}> _؍D {ۻp'yw6$ޱ +dk?ɓ||ɮm<=ǧEhY^e9[?\.ZVTT=he_UZ |O |ROb#57ǵ]kȶwlsP ~n۵SZbi&MY~Cg?]+ O`dzMSǖ39W2Pׯ )Aʧ>^t])B!Ť R RjEO,u^ڈ=ҊoTy,_ƒ{> 4,AH1y )t(K{̅ͻ`8 9lvScbwؽggfBR ymE VC0 a㝄/E74md&9z$i܇||Lؕ x# P}.f]^s.wwsÃ\2ˁ7b^i޺Y 0{zGBܓQדVo&{_͕hl>#@lj1%f}2ﵱ13Wv6o ٘giޔRy}U .θ~Wx[ ~"?>u?G [u% V/*?F㫔,:!VۓC!ݙdԊS[V6_=&E*t9ZQJ y[$ۺao=a6ohg /=Y?K_!<++xgߧ(r$_*qȫ Zg{P>FcZM۳d KCLf6˵o)YF?(M|UC:g/:7iiZ>Rh iQbxEh>o|vk\Rg8rؑ!7g .s5lO{~׺|ogZ{+Vȧ  l] 9? RM O9"AjE}+^.\}䶒kXf@pax+řp(|KpX-eo~FL E&vPWc G@W-/aيX2;nS`0R0%6yL)tZ9ZyଞzAUηm_y'8W4gO m 7AMPsEPž_>pe%=ds$ <;O5/\FH#T_=q 7¥cꜘe| HE{>^|G]QV{%"Mx#8BJ_?K;%[PV/XC4̕t Ήp+S;p*z|݈G'?hPgi[!یڧ uθHܐ|]Hz EcW.QY>>,}nPG.xF0nx/_Q5\J P }C<k|lBkF>Se$]I.X.MΎ[iY`\]޳­yEw=Wsk9q|p3p\Yŭyӏ[_[UOpPIDQ33څb &bݝ-!  awyp{3;sWl )ރj ]av啼x- xOLJ~ƿr:;:98``k3y=xR <@w.Wu xqE7Mɾ=aC/t 푞нzc|Лx6Ro__tKG'*]ݯ=z~Зnzb6ӽ'ؠ2K7nY=ma/"t?Y tX:[*_u>)}u 3LkxB\^rx'.#W?Kh=YWhjN]Qkn{Fw.]tg֕]ş<z>ݎ:QT!5GTDԠDmꨧ+is Υh9 _D?Jh6jˢgA3ixBJ+yS oU!ot8Ik9zjLxtFLQi3uRoT5]zH:pZm㨣$vу>n݄@jIGuLijtGoQ=|8Z5KquJLfKzDj 8zw2TN>EVmy{=JFP+MBl걸LOU8z+P&?Ե?^yL/bNLGw{P}z;Ji@~ &L_ yQzQOM{݋w҃#v-Z|_S;i͡N QoW =QsM*۲ZE8C/VKO*NwM+y $JڛYZ&=*Q zA]J/=_@-Qi_R}**M1* RvgW?P7V2q*>dIxz䩩'̓)׺r;)NX JJCs2ͷS3 !}70bFQ҈&%PG/%@Iߙ҇OQbʩ5(qD?RgqJToC)))x2ݞH!G),B^Q n$*<&Kɧ[[c yOr!^O^9 ^A]hE^em?Ӑ|6֒7Qe "|;%@(Xd.=OÒ䑯2 ߮&E们w7<[0u%Ar_(D%Jb(`qti:g. OQ)n%H6,wCJ~0ىQĥeBqr)JdS( q "L ( m_'|@ G(v@bPd} A *QjvJ_D1i#"HѻL=CS:yXGaH1(wŹxQߗJ "A:a IQJϓ):=")5-5"ZM Fw(q?{Aj}>uſgR<E;iS)RP"zQ-(ZEQG} B(My~)E_46A1azPBk),%]gJpXFSΗG ci>%KP MX<͏Jo_E2~&M)֗)IٓR?niQJJ쿖dZ(^QМH t)C6Py}FQʟ\DӏQ%Q@>Sjʐ.+-;3 mEROjPxGQW(%'Q^"ϏqdJ\J[(lKQ9)ũܦ(zEQ4(K(k E6?<RϴKq)j7ŨV I?N7Ȑٺ"ng %VSr%nK>)>'9d5KmK%\2Y %΀hKnɴ<-]qNe=+I. a.6f s}IQD[֔&.Iu6ˍ"aǬoF"Kob5\Ho#oD88O{Ak/O\-$t4%L~GPy V &H<~lZ3V/Ӳ4#IӬ;Ɩ4,i=kY;fVќw[ia0ʒTRaFj}ie-' &%^ )|$Eg6јD^EryxGT!T{$?I^a3d%q\ݻdsh90Zܣ1itoUs>Ы $Fm'ON4hL6_Ce=i?UoaI}qzS|>߹£8Z q78pE\>=g[Kv[Moy .]W]F':cĶY0XK]CfMay;޹ gccrcxmXVcO=VcY6,1sâX\ُŘo˜Incrt1q9`JQ6&ʘ 11FgM NbÏ{`T_'$nhcBadArs0B| F.A1Cã1x8J=(tcr aPQ0] zym4TYo1XmO3?0So|,}ۏbXUw4ÂSXw)IŒgxa<-5V-Vcil܀?aO|uM}{o)9w _ #wiW/ۈ/`O>Ѓ} %fyplŽoq!eԶb_xi#Mbx|m'>XyxOd`c1,?ℕaX~BWsiv)EhUׂ&'x"[x ģs_)yx)I^x~AahijR7ڼ݋.^+m'w4Ch5"xk vJ G׮%]ƠGY,^/ }GrHߧA#tXy1(Cc`t:x s =U* [ax1b*&oy9FԎ1Nw &bF4bemv E {x}^6([~7cut C6]$#t;.Eh}Jߠw٫vhސ{hٌ7TաhnDx*nCj-i#kf[?.?5bh<zkw WQt~]D9ktzwBC+zĽFϛgFz(g$tAW\p@Kz]@c)]D;9zl+D t>Wrѣ<g*NZ#Z.3Yal1A;~tCt(Șճx]g?^{ 2bI@h -b_|k=|>nU)M<7Mihv^8oh3~4ϧ;x ?˃*hRMU7A ux=$W<V\-c!^u\WMkAtY/{w<M ڲ4LËh~wMğϲIC!,39'J{>~|J;/<)^'i}ؠI*HQVXꮙz+$o~0r)E6SJ*D^R\)טR(%ɐR5)!$R%YeK UePz9fPqZ{?QIj??LErcz2zcq> r4bgޡ~yOzE k<ފz8 RoY'={J/9Z E}Qg URTHuZ*zvz'o)zQcBݩNX'(^<-W4TL^illG\ӷMgI}ODyBSfFm0~5Yџ<ۖC&а;3B]zfP$z^ <zy9AbJ_ G?4 9;DӠ4qnqM4*F&ߢwK#0}hp}D?/)4'h( EC4B#C&z4| қnno48O#y4གsƠKhk:lWOSFDIQdutuLԥD]jN =}ؗv>VыD3S&f?LqNG;RKYO5u)_y)Sg4ԗ4^(N B^9+iճѡ3B'c~xuNw|_^ZQ. j״7'7{zb PW,=@} WB=ׇ6gꞽR'RƳ2K7Rp n/ ; t鐧WrpU'hr!2r&S!;^?90o[A6: V|LJRC0.vY@!t[=$CN_<:KdBdtY&kH?X":= 7?iom!K>Z=⽏)uq.,N12&Vz&"w!{bI4jhN1=F' ˇzd懯ncUt#ͳu<ж5བSXS1*1UVmjjشnޯ/m v]Ď{D%`&>4`6>ه-9Gơ(7kbIl99틅F|url+Tp~7<+m;dKV?Jǚ{˰gy?|Q6x&^Kc`+wjZ -*kƎZ+S)ªgXq^ˣaa,IJ Xfe3z oRw-,W+ҷױD`s!V/چUX.ފum!4\Q5儭l<GF/4|]9:> vՍ8x~?ǡ) 5JnpRn$Dif %oO4*Eclג|NIB$-B4~xw ;^bwie4n{ha4m뿁MY@b7dXIhJ~#4P$.!}7ESUMHYFǒ$9K< $ف$'*I7z](@/H.A䓂I6E*RESSIZ^%Q$NR@1$TU/#FdڒˤK#6$6&yPRzJHI}"IL%)<>G k$D A$Mc†ZRHv#7Iqi ),xDSݬI6g*=N&ϧHa H2:q*yK̒01񥩅 i5YJ2Uu-Ib.r*2$W5a6TO$gpds=HoMrjHA֊\$ e!dudǘ$}I*4.5nmB9$4$<$IkI!iSg]x-IO2-Hh1IKʓ̅$}&),-bE2Y$chLTH: h&i]$cd~ftII]HQ@RI$_HRKHe9E~7Ii4eIg0F!HنӽIfos:IV4e$5d_$_}GH֗wH;Mu_$$nGSIhzHlɮ!YU"JI6N\A$"dm&_$m$Ad lIրHI+4#8Ar$З?E$s^$SnO_9I~LҪ>nRv-⯣ZI"Y^ArJIMm>doݼG"$[g4 RPv e5IߢKKxEI)4O I!;7%_2_&$Ȗ b󗤲)_BH*RDb᤺=TnL!Y?H-z>JdѴҬQ"6j`O+ZIø5jURFj7?﷤8BJ*HĂTz"H OʪHeDSiy~^|QR8_$HxJ~C~"R6y"/+Hr"M#(R+?Ij_V Rn&9Rj!ˤb ~FjKHҨ~⤵{H3h?gM HM~:ǿfHP>4Ai+IL8xVzfJiF ͜0fYMZhv,ҾI7VV ь14=ŸѕԾi>3OJӷw΁zeIj(MSԤΐƬ=4m zF3Hm6ɪA_L7|f4kA2SvlD"@ZͮA51&4k;\h U}Ḅ߾4[kZVF-6Nu,}"M!LvM=1I,LCZ:NtQRfHg&U:p\'Ub?&OS9Zƅ'DNQ[Y+oQr\KHNb+&}mr5K"9sD͋<#1#?7yMH%Lu&j"y>L! QLI/ť,CqEq) _F!O(zϖoT}f#e|9@Q.PԈE )a\Jp2ፉΛup3oO[7nn Oۺ\!oA ǼYMN_ffy+O ׈wV+'`eoew(~>UDuď;\kt?S9+9[/r(Ϸzr7~o~To:|PvKﺒa|`G^#ۄ4F~n?lo_mH? bFIbʃ4eMHd5Zs9ju҄f[R~݅I_ E(V'Kt*,|ً._0\L nňj yc.Aᘞ2s }0[y1ET<%-̜섞y0>`V 3m0/Ouu}k[4]Āԙ[Tcf8:+1e Z O7dqLE+%1Z.9^u+ݽK;aT;PE#,0a &@%eh0+~v觹s`\ɝ`zot\_)ˏ[3]nT7b\Ĩ*)Q[>G_%M}. hiU6âJ);fyЊ.1$WȑC!^߄.[v}a"*c@nLzB1lI8iڟ{q?1vTo) m.IwF yo%|߀YCޝ 9I\}{40 /Ř.%cm]z}G/B'4!F7Jb}m=COGs 18h| V/_Z=B.X vDg,JXuw[^D^ϯUv`d߿=lcHŀd^)iol+:(ӫ[ wO/Yz ]Wa1 #NC*ct򟀑+vZL;z O;?[X߹M h"z~~?0:b5! L]̅!y6zEcޚv5oV^$ma'&L_ä3 ['kY=[0^ mY>o0Z A&m:"܍=.c>}1$> ]_ۿ~Qe0'ύC 3COd o(%"Ɛy8nVbZw)mڊя1qt5c?眓amv 8cɹu^/ mϮCXQ byw 8pR3!=xK m@yP1\вN m5d2zGaʹ=Ӂ*)ÖjywƗ`@BzDVָV^2踢D2tECЍ.a  ~%TUaFgݭhcɏ +T{; }nW9G_e~ oȢD_X7fӮY#Tbf$FG.DAt:k1/ѻ/:0AK~-pnaru{Z 1 ϯ7#`ʌ 1etUWBoJ p/Ed{t܎0$i4F=q-{^I/]rT1'UthQD7h"0y jchdYb# 4Ewr0~x & Lx&Y'o2sg}0f\Xi0yk6=xOfL= ʙxm 4}Xf)bW c"L~×X{~d0b07?.v1<1zEap{J3zHhSΣi z`؆ZYփ^o:Eoб#z@_b썖I|Fs>SuK :<݉ Ɠ2Z]LjzI#&}aФ_CI#.F9LkKыkfl<}C'=34 yѲ1zA%^{*j"Fۏ[bĄ8LYzC/F ȍcOLNct vAs=\߃/`@ ܀Qkgah=d컋W>⡺uU ܌_Ʀz.>~a 4P\L^"P2.틓E.Wn_ʩqUocpV ND6x}r%N?'sj-jB p\J #'5CgFE|If(b%;z6 ߑU^2WEZxq/['/0wa8V26@ԃ& ?r8zoN6fX|b?;L{p1HwI /5[X,8O[-$`ϻ1^DCΉ 9nȔ3pNͱn` 3>mj@;AsL| hXP1-P jN0e,ԯz߬`n96a#>Qs`ܠGX(㯕XVZTKr7t/"`*u|37>ܧ 6*zw% WlSe,}溯pO6ʀתJicTd W1{0ϕzEG~P5vr9q \l.Șk(Š+ƿf7## 3=Aa 0~>k4/XUX ~빯ZK@S_{w.9RaBٚ[hԻz<-v\im`A=@Dހ9qfRCX[E@5@kU5}1[. ?4pۢt.Xc0W^ZƁ}Tl48ff7,ۑ°cZptq{#nl> s+qSA`k}"ؙ7*ge r.@dyTV: 㚚`" +CA%1 꺟`XOa[{`jSwyGEF\A3 lZv:r*p@cs 7q[NlEg3Ly%=`j aצ\V&m|[6 '{@6n- `NiLnnr_܃+.u P{`bť71eׅ}\G.|skj\˙kV-~j,̹ iidkj^Ad})p'W2! Xz¤-\(<&igf \10Z\7ȃ| _yq,`Uל $}憍:At)@#gȕܛ˒Vի <#܋Ik/ |n(\)e! `}oI;$wKPY ׵Oi \ˆu kr{d'^0j{ B?roJԸ0!) tOq8Bt1 6aJ5kU]̅VpᯋF.ow)xy/\HnεՆ=]õݙp\j/q:`JGRÙJ9Y,כs6*2+_+=JH*z38 9׫<.gjUpSu9n1Wr{̹/k&B_>w ֺ5Vz=bWqU.m^L.bՒ ;׶p\˹\4=Xƽ\Ž>7Z~!Z|G.,3cSWɽHM宭BC<ý?y5;*R^;b\.c:u>7gל]}32SgssV3y,g=_ν|phw|\rA.Iٮ&:kqm \EN %\Luw.3%%|=kL;-lO抜UH$rg6w lK V.צM\z];>qiG^ @ZK;qO'è\_{vq?~kuL7sݛ/0~%\X5WAT^̽υOI&qa5q7j L ⾙?pY %` w'8S}Bp 0v;o-0g7x; MzxMpqoy0\ >-`%OjPm^(1Tyzw@4JxfI|,<] 9Y_n-h)i ]&CZdTȪڐ;FͦrGRAL= F4NCtdv(b6W_ 4kyB%Hr{ j?hXy&v-8pYGUBahhï`dW$-s MH\;q{·!"kwBْ9H xWA~׀a?MRJ&CQedU|_"]alՅx/Sӵ] {!f01[Z4 G롭rD!}8L9H2:G! tVLdA;>R=,j\ _6= 8Z?hAE8ԢInTn;O]WCdz4tZ@\;pӿ 7Cj1n>Dpg?:t0vM Pej nIAq8?VngBE(6eAmGk .xօgo pO^ e_=\+2j6-;cE NtKkCg}KF#S E\@fVԔ :p bobhlR9lMs뵇vC**A'c!"r|CX#ePQ5]ZboCah SJ7U @jcoխ4AAa3;{= YЙrEy5מk3Bc_t*VC;W}js&/ CqhqI><9`1 <6{ür4 FD< 8 1JmU @P-3|$g<ҎSc{py~uZ| … 4WBt7x^%r:r[OK!L @,9S TksAoC`%~_yܤ+wxɇp8,o)` VȘ5ZV-#mVpUs􋡰6(k!4/t$_b`׼K&`[IP&Ν+&}m^/ Om[6Am Ph +Ӹ᫹O>h7 o~-% l5nɁkP8(pO\Lj8Wf=z S]5u$?Px… >; CV 0k ґ%Lnkf;)j[0rKYʥs59Ex;[2w{6gaEܛOOpAq\y~6WS}&Zj#9fA;E0OWHsOkx?^y}rms=Kss aN7ؽ˒ybq~0l`:/}7BW{r֥p[uBXvQLO!MH,/C GƁ,r^fx̟EAz0_sƿe/eG4þkj8]upVi3)() g.}Hqcs a]08,6bT&Ǟ"Zz"@uJgP; +!yR?!jDX%!+ ,'4a~. λWB?6 RJx& _ %`cv;߃  N7m}h"q6^,&Ru~ld8Ehp8>1!l }n H/rP)P 9'+נtRj ݽkomPX %`%T!cn |kF"pP Cv78 v`˗gY+<'FIrp 8M9/`+uɟ l ߯%cd1탔r.@E SSpW(Yb? }k$@:]_ WoBT5j5pXrB~ƪp,` A~>lAX ׀`;?U .>`) Swwkp=HR0>\y:΃X3œ@-YV:p o̾spSΕ.ɰfc~Wƃ{v8L5`M/cE|`D8w\aVc(䧿۝zN $ ހ^a!z|Ԇ, 1M9Vփ;kvi=ps9p: +Vs0{ t8/&E"A,KAʖ:pvu Tc|`1|ZB\w¹UPk wm {S8 vBv0c}<5tJ[PH&plah}0p`$N^`;6iE`1 ~6s Eհ68xB"v.@N!lm-> [*8e0 :g|kؿ5Y詳a"AuL `<|{j%'||NmS|KTf; eCD5W {УR AQ\z !$󾀯K5. րI1=OOåLj=w MJp3|"4y<Ajgw8 Qv.h Y ھB┛`4@jp`^4\mW+U{=8y X~@Lj?_˅\q)d_Ц?=P|g>5HGEP)F@fCswhKJ}(~^?QP}iTUPct'MمឯfnTtn( h5.jώtPCK1F q?W.EW=:MW@|{t1iz3}GcvWŌ=#b% V׬FՇ8 {]_ Lu/Ĩ?o-ꌘ.YX|v>" 4dWlĿgI$;$a?4QD3hA6]#$PL4ZeiO;mIEu ]yI3gL) 8I H7̧$̄ޖ&:$r4`蒬V-#Wh1I 7X‚&+"st%i\k.$aSB/y!4)6h;>^J%HxՋtxU!A$yDw.:~/>X[{Yal-$xTbį8y*Պ7kELXnւ70pV: A:M̐͹(^W귅u{5I"rn8vL7ln[v*9kw%HW7{:uV*JZλD)i8|ӊ;uQz `rlɽ_Gm=\H}l͓}|[/cj[llpE^WaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawPRieA\4P޷1`$I@AeEdrwO ]s@QP"(( !uusgzV![=O{/ொB!B!B!BNCoރnvgƭmzU4?NmD_>yitmFIs۽s T|m"vO۴YnQ.AwOتx~@lwqCc mt뾵f۝޸baww'ϭ?7?_xZCoAMg8k:\t[ջ~o[_k<;{ܯnݔSsjYw1flaӋ>pNu3o+^O>[}{uFWHLN/}7ts %?wR?ڌ׸h{jtt=e&Nچ^x YǎF0m.v7뎍V ^\,+{2f76nldwʛ1ֻ^(o֨py[eŖx]vDy}\yW}w6]W}{OhYx5Y^NѾןF_s,YͷykF)aFFI5[ϖmuzWOkcmw\nh%n:E&ۛʫ-<6uCGj)kh;ʲ;2KlݤƭN/ڥqqf ^}̮3 4xx_f;Q;{|ֻL_RcOdI>/6Mu%f~HY޽`I70lF,ݨmUz;k"Ofnʮc5F[ Լ}uਹW]G˯Uviw_|ac̼c~vȋ4쩰?]:hȃ-}D;{$k{h ?,ighwp=፱Qmc[ݮgeǯw1~wM` F[-smw9Db[۽&ro?w{VП;33gIڷR%F_,̾z=5Az!M.n{J=xzcoіG/FkWh3׍2s1Q2{ikdu(hhQ@"ehX>; 4or.]UezM}^kH1N6̚7-rEDFoMvW{S4e:^s^M3u~xQO}W§k;h!Z-hR^6uv {˕mwu֤X ω&8&jPvf3n|Al]ErOM""ǯݭ/v7n;WXIwM]yXnᧁ9]?԰wՆw,7δpq'32Z;-Y}yz6{N/̇;k9_VkV61Fgqw?քs;W>JVgckX}Ú\D"߽4YƯIc~ZC3J6z̽*P=1%+?wxI'oO~F2B?{&o=4Mx2A"cl?Gt?>gO ~;<>~]~ryQM+}g@52ݺj4kه{TV|>mgWkz:i7xoteh|\,ү ?ydS$'fwfVϺal$\+>4i@?7B#'?^hd헒d3? }Lrzn6y7[s#6a5e1jϚڶ&4$XPFgqq zfgqwrQĒpVӇ]pʎxA4]eC}j-mօjҨs$4:Tr^z[Ѓ MzʵSC tStyN>P7p?{Q4G1oM.:6; .Yo*DDS>kb3[07]_ܴMjwwuR]uŚX8|6U,h[׽)HFk)w)w^_lGB6lt)n5Ku' |N$KhsM$t#nzkGՏIކtHXwrgh͟5iW_Zawn&ڤLtAښ{:KiL6 o'\\[Y;1aƚ[36%7x6:㣉MγENrѫMV+J+c)f+[mRfg܋R]Hn$yZwޔhH^ctM_a5`1:蘇h[@?mwGf ylJ#t9fk̖Gv/9hůcݒZ֏EZnϏYϖe}q6o^kNFjF}>y%kjOw72P%{H9#}cQyL"cIwܿCShCS?J8&U2_~V@./k4(?iŠӴwǁ#sݽmk"?̭v>n&,[3'pde|XyAC2YNFSkWɼQMQ3W;404|ìy Mi}fF\"hwŐ̑OO-}nal$%h[3oH7LҌ{j{g^l>ݽr6jB?XD{3{dkKdm"5W/1C얌 ̽5+VWoF}`F mF{8H22nɘS$ߋZaﴢVZcOvga7=m욝6C_+ן1Zo=|IҎ,.* 8]eػ)`GcoцHV m}W4ӝkƲ~G37{9ydwproY;gx6J0c[{DXnr}g?^f,?ҝ׏ǭ^˲7t.ކmz^;GaDB ݚ|SqѿHc_?T+.ߎuzK79%2ZN>JN3Sf|#u]΋_ٿ6sO.OZVXO?aϷsOvZ_`s?>[\6)o:l~f䏭)ckF_}'ܯh= ɏTy5RH=1?>CSG_ZMAaӋYGϬ{?|N(u^I3~_wnڽ ݚ26.񑂊AʌjA]WIɆA$8ɽ%XͭvGoM Ҽnlvw]Mc$27=@;$+.]$X%xmIf/צ\?Dxs#;zmDz_FYN<> p;.~w$T[MRih[Z%jew ^a7֝&~mF: ]xa;q?$c[olh7dv/u߸;^Iϕsh/>Z(f[sclNz޳~)}%4vGk]H奆7٭IcCy!smwK.F5ݚaMܭmJ}oz\|I(F{_죉_ǎV$xޚc7=pf߽YM\hwďz>̰Y}lFm3֤ciӋqѯ_9^E4ņշH0[ .8Tjl4G=j}dXN*vWvo}.MMY=b&ή/F.5Hț<6{uhekɎc)G$t):~޼=)*tm^/UzrI\$7{lw:pkKM{$EޟI 7{]лkһѰ^ðY}JM>N8pzJCba;9MΌ:a{REs;XMp]g7n iդ/2lH[ 'gyt_2C/QvNwٚZ}Dz5yl] kD̉mE3"וdg$qh҃HO*W땕ױC5i+?7\v&EWƏv{v_8I/dF&jE[ޔL$[rwt[AZ-w[Hxْ͚֔?cG&GIp {D)1kvWlwtqѯC׿Zz?'eW9']ѭI5$Z}cH>%@MČ5劫uX ݒjCS]m;߰Gaꍏ&?n 2/#/~D-~T؝6]ߓl>UǞ4I^?=kwaώwZڌn_~XTgܫ'DsmMbB3{c%gC69f_|sHY$7=.o$JΌfjx^/3$ڸBɩЌM$#hϥ;_Ь+[g*9շ:ɺrrsmɊ-Yjak~f"V_ՄMoI榷X1kw$?;vȟ';}\d>8W{EnJ2u4lwK}^cd_e|n>[5m?G=6fd3+mU${k ߖRۣ~6~?ə}iu`9Lm|ؙ%{9LJ&Wxltt%朽FOg=O[褿o6jjZŒ5r69m8Uˌ59vH 7?f%vWۮ m7zƏ=W4arq~v,fmvk$#33dg$bo6kFANϤ?{᤻Awu30lvKFY6k~wvL%|x^_p }k+ʴkdʴǕ;ghF?{*gW;-Szed"SKSVf`Lm0x/qs/JKoeE.2#SA}nǬ=eX=pX3U{=ֻlZnZlF:C%2Z>NYv}2{'KgOã״Ʋs"S6v8L}c[/}M{uHPzkX!S>ðO =KHT7PՏwC`еߣ䳬^{]'hs*іdrxw?]|uN#Zwkojպ3'gDM]v!8[t7515_2䏍>fg62嵷C>J?ѱ5S#lƺ I1*YF?wOO$wI~,C5-u9#Z摁Ci7u6N"̚}nXV B֒Wv?8R?Z6\=!ַzgm4,}X}Z?~1?и i7H#Om>@R|ݠo9C L~+սaJ@s$捾w/x!'*o$Fgq/hWQN卾whatC'Q`;7tK ~D4^t%woPHVӁWx~I?Q=;pr 3j8oiޚKvwX&kKc%s4}P#%.Ҥ7¡r[־I}N кQE^pqR_:L8t4; AzPϿckgO|HiU[CΒŷoE&ԡ'X9_4оhC'}N䓎kz7ir&zV.O6z]?\̽uM, NѤ-1s[C7kzO@ Zc!IdX.aћN7o;O:Fgq5\_X[dn;iR $ȱAj9H[Gn?KI"sJ_H,ꮃ(w1 z5 x'j-쩸ܦv?tw5ܦD֬to.ndH4w^M>qmgDMO\kּpDuc ^4<0&qs?ݺ~!l`$[g_qW']?G" /+w>"*=&徆TwNNIok?{Ǻ[ݰn9pȺ݁m\7m{wrtjV=zw2֣3$qrkyw/ziMԗhcRؗpQݏ*=4<@nԭX؇ \퇁M/=$h59"ku͚7@rt9Dĺ\w n^ݵ'fjuGV^.PKCGE[IGY~Io55ԢDvomL5QC 7*7_E? =_"ꩰ;iŁ}bƝ}v؟I2 Sq$4';doǾtWXMHõhuM0'~]qt/>ݺ M_{8woY^ԐykZH ˟4OK5/2G$N?HxMpVX?JugE%Y)WfthK53Jdew򢵁[[hxZڝ5!pzZP_?U"s;{Eiʤ4?"23Fv>/ "~MZЭzlv8PGtl"+4>^v }w] k:T"Rfnin3 q5}ek]8<31- OL_i}.JNїgcFN/GOIaݺ;;ޕ?wҏ 4-a𦹁i75lF_N٤#xȐGҌWjwavHd[_jn7֝ƐǾu?qm O(XJ6l-8h>l?{*4Rx~s[+Mʣ5'EEg^">^Zu_:|h6=_Kh)E?{ il9F{9݁:kՔFw* yǶyݭ[WIֻj+Kf5Kdn{iƙ:yEkVZUC' m-ӛQ6{M tWWdzW~[[Zg)79KG;vQvm"~bfďU%2HIÓIftѯ'43})k ox(O#ht߭?\jeeݾg>u}}ww̰8.Ou ֩_5E|SL$8~K$8߳NzР+]TH8Xpҝ#"ϗ\ڞMx=z בK;ރHAκ C 'Eu+|yg}_=3RAMn.z5k1X;gYHډgR >]o~ Mv޴UU[ɯW|~. kn.zHt/Npȷzwa Io.zw װ~~OqwI+;J'(\_P4%GB0\v$?=$Y~(1;6q .pb?jP]uGZlE Gz"_]WB~o1=a !#EfTHa'i{v/:'B!/R{!X*}wۑ}y^}mB!B!dO:'!Bٽ#3گqR5"3Z=zBڑ_[e?!{zd+]Ed椞nzO7\tW;!~Efl8zKdֿ/2k"75\B!B=B!B:GTwR5"E!B!B3"YsǸCUdo{ v"{qO&B!/x!Fלz'DrOsB!BHՎ5]zB{CUdg+]VHVT{ dOd!)nB!}$ޮ@Ȟ rBlD2zB!Bٳ"_\F&zB!B!B!B!-cB;r~\Bn7[_ȞuzpK!ʏLNl72ۮ`#2[]B#/\awdHa}mꑼ[>u<1eUhn;xasw [.#Nw)^vF+=Ip;3)z=鑂#q{w3єU6!;_;I,wѫCZOTHޒ]#AK+ ۽U9R`=vմ®"RpBe~o=|>"Ez#Z=r~{ {ރȌn[[ꬻ*Gfu챑Yi \zfunn^墷Gfmz."zU1rO5}w"2+U793m]aDz"EKwNv):6'~])۝Cp|K>lG ,u)XqQh+[]KeйJ^U >eHU)+]uKu]un[)hFZ;tN%k$'̉?]W '݅Gt[?^MW| KxO' :RP}~iMmwt07/2\tWrb{N^/r)(zM \sz]*):zc]AS۟`HNDhPIXnUOǏU!Rx]zfwn\DN;[S"EwkIѵUϞ=5MnwƏU)RB%ޝEUqX$W0M,%2-= kɢ(f).i٧€傈kni!j.|. iiwHsK{9{;8:w}hQic+ ^5ǡu`=377Vi 8= ^UvIK_wTd{ND_ N#uYh`c՜9V66\ ߡh yaQS `іt?`=X]3KO02 |5eTe]8#7l\ňLRӃkKD][mrdaAԁV{UтMMJp3v/AӋxt)vD/s=kmD= cZ'/SGUCvm(LҕI("No(`sGˮg3/` uB{s{n0˝=0=UYՙ{C'QK^oi^1W1 0wF NDY)Hɧ}k~b Y`}]s|}̎xAm^CgWyG0rR 0›='YFEN=,niN|݃(na+* ܨ0r0Ǽ#GԔ?a#^xcn-_<7BY yG[D! «9\H f4vAض,d0۲PWqtYxecaK8v8vfQ+_-2 7U{+_邓[[31ͼ^cc@!Jji׭ SxpTlBl +MVz<^({'8T]|6w!qTg:=w_>becvB;RP>B!r Bl|{!i敍CqTB!?0})`1zߛB!B!Ahhl[F'2 ea@J6UUg~g?vBy8vB):^>vB!v4,ـ!0kR!9!/c@!^bD6)!c@!<*,v}r 820r !DoECHB?,,{54IHK~XRBB!<D/C^SbrvYB!BJpSk¡&Ͱ{5pZk  j:6r({DE@Ex㰲I {{ kF=7HHނ݃jߡNn&=Qc@ԁ}vvP %8 ac,>#vA|$8G{nfݣ8G:GW#vA`@ԃ;`@Ԁ=#6ʶE{,>! ."vb 7v{ 6Xlx [-{/dd/Z|f vX`S{ j+!`c{ L73{ %lY,vB { *!ĺ`e\CL :b ˃h|OeG?3+&7Jy 3m=BA-Lr|l[Bૡ_Gzꕰ{xT>%w if#aG3Eٶu읿plb[`xCu#vZ`k>b+Xٰ?^T=<.[sUA|=d텞m;,\Ek Y%kkǢ|" #:$Z^'qt/.p$_(?-WǺ{QWrTg$v}U߾#$T-끓sS{PE悖ݫJYX:!+GZ럻,0'HS~Z8Xufh? E/7e:+[b> Y6iiM׋5g.IHsw}+jkUg{p꯹ PSPslQ @Jw`GGQu6a:GYpMo︲:E@JlѦ2һ#Gͧy=;]s˗2~ ?I'Qyv/OY<;%9ŸYm=@¶uN-*ӌEG^d :v̗5S܌3er}R?ۈv"iQEJvfhYl2 {Ӕ;{@_5ׯ\tk .KyvłĬk[`њs8,zo+G٬@ Rk~);~)JKp -Rb ׇ2l٨=}]~+6湲lO[+>{v-p%*r,f?* +Cmgd9Ys..V>{h+^0';~sZJҒ=o_vբkeҡYw:)؊RRG=/U]wrF\ohe{k%GlAa9RL3/{=GM=uEyf(6:gOLB!B!B! O8Pϛ&|J EuMBXSeQ}h\vi[qIMmPhaӸ5I~>F{i ͼ-J ט ÍuC|ƭ{wqN9GZf9m~p0t^'u Ef; wGev%/xw}jo^D+ܡrKy1c:u osyAe Oaqx&pO_$*u"jmcOWoć$U3ec1<4kqD=E֞u{9rU Q?9Pu-S~ϸ#"_΍E!y_MGx m^vL%};|x7J6bC]ӡ=Ou)5l8n\.ǷpYeqrMF ں5y\hQfj.v:S4Kv)uEY9p?n갨VM\qo5G>!I,w.]ifΝ"TniE.A,`gD_^~Oc̱֚s3 DpvA7\Goyy2&lˋ09XX3II.ۢG^ n֩^퓧ce{L3slCs C//ShM;LM*ݓΥcd˟(CFWH,5ɏxw2lߔ.fx( Ġ7ar^qsjݦҮ-0ħȩd5YM۵ +\lY QD{ NC=1L=b8tV$N(о| )*?/W 踟jp*?dmHZnMJ0"ęsѫ}Saȁqf9 "{ԋJ7=*bSml/nC8,\+ZK=LIS}(Z7Um ZL&W>qGHsj_EBػn,,1׹#W>DM:Z0ܘu*5-pzBC>x6j 8k&Q6Mҹ`Pph)GFНѫ`@O2.r-'&pЉν$+7fi|fDZEi5:'Iu~͇:~>νM1vzt 'vaRͪZ37I皬aAU͕lU>]>tlj@}_s疞xK@6/;OW|kb]amm٦QVs8*J)K?t'|Cl0/wڲO=aYN2bНXV^m2lN3)oK=LeUG9W-ϥgX@l\=Xr~[ҸQB13sS ~wؙ`i1 3רSMc٨o0*Ͽ27b=e"?5Cq##NLP5[a낹xY/k\~gΔgbeL4&Mbط"l"Ej6DoBq[y"5MЍ=^gbc=}a O?"vRsf=XQv)tesf{e:X/OOWK !Xa*l+> =׳`6l֬ u[o|:ͭ/+_tQ` Y칳lޡXWpnV^ QV[E `y, ]ַY_;}i;Kz`-{l#lװ lU|#4$gđm!s|.gtnGY6|l=3Z`Łnu*KsԒga!.lÍe Y ;՞ke^FI$u4Y b31j4Sg{QtP3zYq6Q P6!sFoGaQS){Ǻ lcFKO U䱭Y7[9zoS~CaS'w_>CaY K\;Û->&i\A?1ã]{g3?;-f|ݛmb6c-~%~0 # gU Aja;E4`,y %{9laXGW ,Σ[zROyb/bM"xP.B-ä/E7`f 5`1J>Ğ+E{m֨2 E/ (7;Iǫ1 ʏ vI?|ӎIMTJZS~朗?Os o[3M8A—׼_&tgF!\t7_kҹ~AϴpD909=R޼:PLoPmqFїbSIbߵ (rXakBʯeN|! i-7mo91LCKa;y]ky zՑ Fx +: <|SK1z\M.(QuuJٺUyxjb׺ra$@uWɓ63DZ}}biT2{ۋ/G$pPou1d.?NwrV1Tslf.b; >3`8t9A{Ή 9T GfZeh7?n7q^xF){f#<>mQ,qXlKoU5Y:8^-َ}``5J3ӊ^`Ľ0yNtZ bUKt̻Wy/.ڌB8{f;Ai+]Ԓm11{¹ TmX3:V2҆AY3u)Js~z(M~ߎ hkؗpnI>VQ/yfO=*'K[a_=k~v$/ѭ[x?攎2;>5*Cs>BuZ)H)}qwX3$F:X׭yCA4aa)|,ԮT9{DvmDckE( zW()ߡE/q÷e{د{~XgyX}HHiKg`Hq+ӗ±inaYްY r偾ۅff/hTwk}}a94@t\X~c?/TQ# I׎\'J; ^3UB!?lƒ)#fR5;+4ƒr=A%_y* b{C,dٹpX,EkO8/:r쨌X?]z_ה@UJzq木-d{ MўC"x.pY )$W[Sj:9 EHNJ''[īڲ*HPM+ /}%e_zA K|8?WϏ?&)/ɫk|a6s4ftk\_}xLZֻ$/%Nhw9<Ѣ7Ւ?-^&MR\XE)ݲ4~dܺG y%hlٯ'}, :eE򚃔<(d) 4tѻʉ5t)i/0{ŧf;ң r]~ et?tރLmvPQ][TTcM,}l 5oQDF`%R-XBSQ1~)6b"Vޫc˼^眽}ۋk ͜Ƭa`9Wƅ4A{;b֣Yc.!c\ٸ~Z+iOuGQ8_x+3/CZ~"6Đ`uwj9lX q*cLSsn%xE_ZO=%w qtz"s"SZI0L@/+'ppDy#`# {є:y)C=b>޳*Gp# RYGiCigZbѳ*'KgpZ5X pUN7:FfjD.Ԫ#ߞ >:ʳǮGy^#܃l][`%(_GO_1(§=fdZR6s Ŧ>ޏyjJ̧VvLl Å݇P?χ -B dq~vAlD2js sNDMǧx43~tQS~ϛd#}9Hcf#i͡7ø6mZ4KbKp ߋUU[؝UJ#3 HW|E_a9Tnl^*I Ԧ+)b ǦMC}jmBR;mv bL~Ic/~l<>^bE`oijgGN@sP/+%ի޿>H01+%*u s1wYbڛٹCOw=u cE< eZDN^*\4紸cfsdu8~ _vBIRF{9(( )gBIfF"MDjT+W0@M895ʑnḨPn|nF#*޳CE+u󩝽1GY ĮkHӨRpogQl23ž~gu,En?<n@kG2]LfvD`CbRVɑ&NקqPLu\5wggkQ}Ԛ4OGx4f.ExJ͟J_BrXqs[)9һ<Å%LQ*j3&]A\h]ia7=M?p_^d*~c-C/CQ&`@)ә&*Kjfr'<}ZhPMf38:tsSW,ٮ}.6G4s28`MfGv6;Rq(^T6w&][EG/~rR*xxX/˾+@yҀWt&#U _,̅%U0]DSx>Pa Ǚ_LT|c"[ٿ!"Tp7P!rAg.\cuVu. '{ !f_?ʀ)iz:g拚6vVg.FsNW('ލoIlGe+ D.[Fdz>QƐ+|?J71|-'!,'pҭۓoun{I}rA:65 ½]ysPn٠4 c66;bCS\꺡)Y]G.@j -~L 'kBIkRUkx)t0,|E3lsaڅWY ǘ`D: Hais=Ons<*jׂ̆Cu+; [LX3ܧξ7gz#ECTXpZ נMcYN#6o+*77a l6& /û%U~gWɮO=^Z:_F~ϸFS>iXKNJo︿<DԵ?%֝q %ﱹm|&"O{O"UD.ӦN6 pl\(| LՌUI˒@2*+n^ c/Ґ1E89#*wXoFAjO+z* 90e#<$ܻ?KME 98+=PcpB%Sɠ"A!JCTpBdsV&^z wy?nxp5ܼptDhiB7vZ*/!3MkKX@_vW\bC 7/{ >c`א8&mNNh5Cέg%sk糬oW@rΡ ?Lv2I9J~:W!$Vpޅ4Q~>g2cuÏC*c,!j̠ϙ,2m_ uV8wBf,70f혒s  ͌VE&&(d}a"63d-xD!luBfx_p)=뚗Kv^HoU4v 2 Л|Xgmڦ]yvh N'X]xYkme#'w"#Mto%0:ly|?i4>;CK{Ӑ˭BaW9݅2Ϊ[ >ԋk6χQk-zu%U|4qn v/T>Cʹ3m5~N`u$&~YsFSA%$*prkK/ȐBjmizQܫ&39GGܤ5H 7IßY=yғXjݳ aG`5~5Ka[CWZN+]I.#\&2a'G"$ӱz^\H3t<2^{T~eGz84^נSk^.u^^|LC[h\3}H u*L׸QcL W䑞RN^JDҁiޖxTߒԣ%we8TWg{dq-$ gȩ}.G#:dXO&6|GOb~KξE=qbL~k2f]%9A="6 #q3/5G3f ̚F=Dܐ5<( Zv筑LB\7q 4Aݨ /%%hi% F\qtFrx^_9YFq_Ng3|zB;ڎF"h'mX'Uϩ(bV||F.Y!fU%VŅ[Ȼ}7ɼ2O}Ӎl j>l=;TdBwGS&#smw}KD3⾝@z|n4UXTC/`)c1^g 6uwBOh5GXj5l6= e-ՔNv頱+/D[[5lauVi8;L+Ϡxu#}p"{V29cEs%?O?!2\ &XhDFꮤ_Fb-T:PvRs]kv;}!VȘՄ:"[Wa-ph-|wQ?TB@ęg''ɂLZ˖F!Cؗڨ"D\NŞq\}W1=UjJ}wlwDuQ҂ڢzxS٢ԻDnr;*3Ϡe+.=5&!Io7.IUOߧZv<$zZA^m@ýhr@-nFzӧ"}Cg㾨u\4_폛T{dj[eYd^ekчTs{\HMKP>K.N9nhj폏F<|ϲuEo+6XLLם k' -a9WFMHxl޳!Q)L4ހH w AM :j8.BZ*֩#SJ;8rmZe{ T,sVOnWΒk#Rx λtV(Ir M?:y Łg=GȵǏF"e4f=Pasál\A܇~TM5|ګh͢^m&,ziy4 ޓ #7 +v`p]+~Yg̣7Q e?6d{;|!|3N@e1t. X#p'Z3t<~P0#u&# vm÷c?,˲K9AeiH5 BO. U|}mYdO) ~]1u!s>-7{b5>{fN@#|9)EH>9Z}NI(Ky2amL#P{yV"ill5,jD%gںWV=&vqVT[!12WH iZMd BRGx02u^+m{~\Plօ}oo\CR!FϿEJ+A;Ȥ|f/,~Y+|ݶ5T㠁Yg3cv 8}㵖H2Ώ&ŵjgLǗE srNԳO ]9{2'j-;>nÙ:˲uH]n="YU Uu. }xlls qM0i4' ﳘ+s)d)@|NqV$[9c7:VԈMnwv)1 A*eg>{ٍ:Y=-22l+ W)(e7Z rMf\ed1ISawTVK-@M,)qxy}yS3g$?vwE;$zߝAAjrc}cs/eXVkdf/\.n%={h0\sഛ`nIOre|pǿĈp]:W=r=2e9 ri˟lLef*bQbE*GhLK(}(TϋBȆ'[5}V{%wșFGa|r=[EjWtAıKgU+'[OWr)Ql6#~gFm\V7M&<>D*ź,8m[P5zOʊ(+3! ЮĚ%2yfFzj$==iFmwD R#e6>+ sqp]?YZksEj}]n@ kOpX,lHN(:$10fsp=d&[n X2H# AIjX/cn{t<5xL4wK͆Φ3^\=Ž|jDE)0DC'o }"Yk =yu'Dly+V61s2i?KIc:;C3hK03K?u/Z݆4rʰP$r]9?-Bho_AX!ź|!ב}fwC k^Whaj<=><܉D\&0ksc} |% r*}@&Pr /6W{`u$N8QaN0_/4sYڠ&~xւZ |Ȟk&e+֝E&%]ڰ(bY^V ,a*֝6-eu!4pM6eZ÷9[i9b@դZIlM<y](j3Qt3BFA~L=$V)Y08M3 Y? ٘>>vNʂ%=.B,;$:)Kf\wߗ9?h  "{ZxUi?~$ؒ"sԱ˭Pqӯuo>GjP +yKػXνeMP.qYL?ڍzy|MCSw^giOGip ܂c~ļS=CiMTS$7U3T$9VqUbg.[흰R1tq."Py#jYpfƭٞXn].at|i| D`ep>ߟi sK>yB7f"d!f夺w; Κ7 '()fkgg1Yy;)5( Б )5do" 5*_w`9%zE)U#Q>H-7Fy&KNMG̰,FA69v1.P%8h?,pIJ;_y݅;"tNwF^%>G?&2^2H_]9j99W)NzqU \?aV;f<`qu&qs8 /?~GTf־Ih>=mr!$#r𿀪H=ׄ&j9MJWŞx I|*Q0 ?)}mbu/%eU4qj'getܗ>&Ջgː</CN1>#@R Pg~g9'y,Xu+Fm}޶B9zo[źs @fe"{Xq>Ł|}bቢ68e;gr)q2U0Mc߉Tö(.@rז(hElfZ-2u"`4QpZ2 e1E>#'X=L! ƚwae{9Vk'}A9dK6S{[9Dfk0_$X[ dI Jtwwx g*+?ql>YN' !ת`mAzMU\}d?ԁ;pF1bfm< ^ 㨛f_S7d 5zg`?N;Y 9Zz'x=DfӒ<,GvHSKlh8G2ˎ#6ʟɍUegS\GXoϲL];#{Wүupg?>Eȶ2n|V;RGbIvs g?d'ߛYtQf#sz?I("|ÐL^l5-"ݱ1[|5N D7aigd˻|fpߔnٚ/#%|qqz?z݅sБpOa7I3MflCwޗ{5{\؉H8wzQ̓t2O_XzL8ڒpr$L+x2 Qi? i"nJ pP _֙gF4}VbYWSW,teV8'9T!2+m ُf/ 4RLK,7/=<'UȺ E6gBbA~(Her}l~u^s4b|8s@AԚ; 1(B*3 u[9&!=: G#CD=c+} XMNzgli;3v9AlH3s^X݉]cjnjvd-!nRyh=%vCC΅C2ȫs_$Ğ 㫙ZU]f^ocaE |N . :!8o,F+|d/TO vH n}GmQy)uS#'^"@`~%0OxW;HAvm=t9MGH_U)=Ld Et0Gö%]ΚyIʽ},w[Z"٥1j ?_hL~5+Lv? G϶&Gx}NgKE#mļz^0CM]MԝuO3f+ywew_a;*|Z‘%}I^jq6`9(o;ݖ!PИ(LjRȋRR ܳ<"WfNid 1 kٍ]_w#ٺ $+U ygݰ] E(< F\ӟo v57*M96qvj8?jF98fע)麨]^p݋}2~?a?,‰%Gxu s}{FF^7 {pu9GBCDZN(f?$,Y +(|\}(Z-JgG*cfTw:vΥ*qbJhiGoNj:⣛ޟͲ?@$<Ӟ n&j.de`*|\km%L?K^ז7s#W 3υYNr,;h$σ ^A>#D-30Wtl=Vܕm~ΤDžSȐd=50ձq ]13SЯPԃ5{5r91U+ WxOmi(:/|4oV_3{1CV+?:RG[`z}5l?E,Gm@D!;0Β 9|Vأɺ_^&S+;s}UZdoWJ,`axQE ÈؕnHHnQH^5׳ia GJr(l}a؝F,;R {e|M>hډ^XROIXwYGsRw[Q05ew/1A6q/4O^U 6jAg{8ۀ2ji+HtD1m\0J1M7@^Bʁ4w*m_G%M56O#hbA|aY^\BXN 0ѵɰJ>kkLtl+!4Ik4zZž ff5+6 ~SSkPwpl޳us ZlPD<M05PjP#ȝCQoa=~Ͳ#ZpO y;Qjؖ]0g0zͲqvz?B7"k%8&}&ZI$&Ռ Hgs\xeΟ죆YI=Wsؽ4@aSwH>/G6dv&M.~DΒShD{t~!hd:{]M/iǏV#}(٢l TQU-.>f]fĦ6ӄ8발kHas){^la|b-kpTNW`x}#U,W>Sݐ.ϳ P>H2F$Wr(UF)qTb+Yކ rǷUHa3yfٺ";˵L ?.1=$*+tlr|Vj5;Hqo#e5ݹ'vZ6'.luGR|-J:m}عG2jYuF4l9 bg9&o&_=/, A7%#˱Y#4'Hc-`Y PF@6?]W@8yW2埞~ÜnDcx- V wGYɯ͔P;/2ۺngAqJ[<̓YͲuj2pW/m% 3!ڏU7Eϕ[caD^~АH1;%A\ *^BIKGD@UB RVIOկ)?"$4)|d63;0 Fyho7}f2*E}VO }YP$f9r;'!>}#(yPgh<9ǬMf݋ cDQ 4M$6]~|#)_@rfW|;nd jzAV_b4V>ig׼vΎ͂Fy5J o j s^Tu}c? {:xCcʶ|ҬGfhX޷6L:)yΫ+;'[4Q@d1n1k-Y1%iCYOs**hd/׈`(3y|n?V]l޽ߒo ԔiΧ(>ztڀːM'zйfcǯ%v1&8 #g79f9[~ cPXhcKęg;^gRjd,EƇe8?Ni~g?#vi+Rߓ^oVT0ᭆ_q[wND$5@!r߼l_=HG>m8aVnUa/mLKUf錝gTu@C=mp>zy#jY"v .J̳85֮pz^ Rڶ͏r> C46mD o_E^#^3s9;韩PStVgE@t9}R1;pfYuuӣ{*lmʀK4٫F'PՂĭRgϊL[,Xםcp&wgA( ڸM0~ v qz|:1NJMNxpj\;;0$?!}l(Q`"(ԛj%#2[ Z&[i!m، 2v,N BD&pt6~ε\p̈́~ A\W֡f4cڸ eΨDP>%;իaFH1jԝz_D {8flXWءyW֝2{0{ޏĒiQt2KLK<a;S0'rid ]$sc}{6RN80%):Ң#2) $0RGKYϜi0xaspn4"3Od8g5ݺw3>%IGz* l'_|enq;pp$6P31 ,r93r4YVbZmJ0٧ޡ鮁(b/ܥ1m8;MGqF}opǐ {WSĕԳ^?Gv=N}hj˖pF;\{%Syv6w 2TVpixZ(8.g{y728(njV󢫨yB PK&C8(7H^ in Ϡ;!=QМt@a9?@7$ַE}oT#!,lSah׼/^163IlG t3Z!ãzvʅy8-5}?\XL4YcGG( %<9 ϡ %@;Rh>l! F6,{CK Qۃ28H]Aq^MLN/plNW6ɖwf6|]8hਡԾ!1zϚ|TjƲe:gTDHWIOL;ҤCh_9Z(9#iBd.\ޗ\CǵzFKU 2Or>SƨᨭC, pEblٹ6l'{?I=Dhuqg\0_O!$c\qcBi;d-rl8fLS}ٙ&N@y5y*ȅZ!ؙ Lϋ\c";$^Dp*Sӆl-̀][lTH}fn\;$<AX8 7.bTYj`>Q*kyb%;sT+yc`GS#1~K]=kڮ 6nq#SC~O ?:GSp} >ge׿ݶAvq+>o.5^،,U1 tQt L Z}:hE(첄GM=ҥ+ ͦ*V˒z s`VRZ!zu \i%@yV1~rtvPu B mGsrCXh^Vp)8%4rYdߜsK6y/EtAT6qAb&[k5٠ c90 9X3 ْo??П!Bx Ϳok& .%KԜ/nzg+BQPTvs[,|vBjYuQcWb g7΃'#ls ^b^O9z"B‹|>gqЫ9K@-|lFU\pwe{]䯘sX!eyg8=҅\386k ~$MJRRۜe֔y"WҗC! g)I-*Qpzỉ0D<ӛUͳ\]C4FZ&#*v5bX9E*[jm칚FCNP3,uo~8?Xsg;Ð%(_ZE n]c9V[G[Syb/ߠWEQ*̿#@MhVU{٢gc'tUkƝ_ӋΉBF3q|8#5[[)0x8R Ƚ%]t=EU]롕%zb2"y}y;>мq lC\m^"wp+<x \{%"lZxsȖc4-OqW棜?',:}~ԑPpi";Z 곋^mL܋)caϴ]-_섍0촆o48ޟ΢® էtw r9$V˗Y4wfGS(5ٲ /"HsK=uut*#'[b6G |V<]-}?uzW؆(lw;$oסZ/]?\ᨎt ?V܏J5fJ0OjgY5?6 xgQKIBsl'|os`),jx+[MwtByJ'k$۟M\`` ۫AP0" (!(!k{`yelc"[Mk9[bgls ϮZLD0&-,űAlCjKȩk`II0/\- V'.&[vFfOϮGoMk;? 7DӞ>eg&Zǵ<'fj 4S41Xsj>_z0;U+hpu muw99fAѲ>!y7KrhֆԓPXE+cuTAf#xMļ}m G~HDoa|i:JayĒKUE'/GVu,\J=ZaC?Q: n>iꓟ'c9ŌGcG: Ƈ>>NoխPR~|F~KHZQRad^E=/@;:Zn#,GW7T?WkTyg9(z.ڒZ)ɹ{~ ݏ٦|ŢB[ZVyw49,}vF|4wA?W:릙sӶ@@ޞC9P.:BYkׇxMهOᵸH7UDҨmp-B Vy]Va>?B< o?g~.XG5(h)>[_M wD-mgg$ug|;UkN#VAdGo#'>|S 0/ߴ8lj䶹 Cu٦а_)ƎES(|g2=JUY~ǡY&2?#ѰV}Qk^dkPػq#Wd!ANPp*5Ns W#<:cy&d#9I KfD Pw9TxYvE|pL'~ ۝O 7b¤/q{ImoS?gOem.KV9!.ﺈY>zyשb}*;~qiuw8sBxr7I bN| ϼ.WPp 2SɞGg|Eۯ8K4*J`iP'4bj;t0yp oA7bÝ޽rYd6̓] \n*qɤdְy[YIk%hi*lҶO9Lf%:8Yww"\s_n'3u(Y\`'2u(hHoO'>"r'Py+<#1gRƯO;=k\l }ݿ # #/ w+KI_<^xcIcN"l|L&]An@TFQ6)_sAbƊ ;y &?"ymS,p%2&_MwXxl@>0A.9 "c@YIzڀM+X!c~`=bcS˵^-졃`"6'bq?RG!t22\Zjskr^xIkbIuQM˷BJ>@H6RTv$ٳ,WAwZ/D%yNNؘ7mu,x&fAsUc}`y7ªㄆ[r߮hb]GpHP%wwg}۞6\A8 162K ʢa>[;6^G#U(}K=uRCө\6"Y yG^;]=/oWBÖF/i/s vf32GkP$z=}.b~=cqz|9_ sԾCs *KPr 0ϵl3y/{>'_ʓTbGM,*"2E[k Zt=6m_명XxW.iۅDo&l)wo#==ӛf16^=y5{lܰT#8a83Qͅ|s~eTok*;{sЅY.DwRra)SpSS^ts:հϸC(פW(M%&2̳|/P);y+ڇ 7=sc)B,b(\f5ˆ$؃B2g;}3|Bnwz{WR9GK-@| gKOG_D.9Å:=<7G<ƊН 6QW݈2nS0 9"KS^J%)E梠B~}^9]w826~@C]`@̀^ul s.˞?H އia s;?쭋`>OL_犧D|:lN7>p;3^&AEl[;\´'qjN̝GQZ9A;Q[+zSB :&D?1LzN`=;TS*6!u?m3a)|qI9*uҁpՔrIxBwd|D5΁Mc2) _ ^̃P۶Ag{AZ%3V틑kh_EqEX'4(Pl5D;;!d'u(KD== fhTzxwZo4 `wfX|f \ZH:{2=Eh-sƝqMq'DQ:i[t !Ts7'ڛ H!M@opm<RsBNH:o$*wawc7Q\dW" Gs8VWH &xZwBØ d:cb?NN]{dj-`utdK6)xB6ޥQҞtρ/:rG"lW92#MFqbIYT::cDts{ZFd6B]H=5Pv0{G1Ņ!fDW 0[@] ,lp(ImTn{{[#&–]TP4kɎYd>>XqRw+jVQg6#`Rx{ۚ=]N-}~&+jF?GJIRZ{mWc-#UDǵ B9шd=nGWpu|rz^kf{EWV_YM"tA= %]sݖuYUO:pʒEZY"gk\Qj̺\`oAD+ EaJ̉Ӱq?,'Nc\}cfplh%1&}CsS~7^{yqzf1Pio͎WrChҺ, EKk_`=C~=X*;oDf(}:HwĨ)AkX;"#ݏ ޚ(9댒[yjR@ gDd3CP6K([A4o^&&|l=~ϳ×͵P%GD1BO`BJ]¿zDmO!9T R;vVrgRgSlx<}@t6-_ыAdu c5}^R%QErWg3c=03%X+ry7!/10 'B茜$:3^mY%١'Hu.bv/W##mY 7s- VUݿރ4>nqE $8tnT,:fqb 1VXBdm JO!Z K,I;άnVO~!c2 Dj*S?p{A=u7g^ww£ZԿ5;JQ|&5-DfX9"$`!,ńǶОyQK7~o!b2|"8 䰓cr&Çz|`o;U=a}[L6}Jҧ0KHP88{bb`^;ѝklBeX` 嵸6#Y<ѣR:`/ۏɫGgՈ%l)0@yI?(,5uIvR$sހFΰ?vŒ)XAqr͐zΎS _BA7 ,u"Nps2t@5йT3(N2Q7Cvw1&LdQuGJz1G~ bjk8RWt$l ".w߃Xu, D̫<[RS˜ ] ܳ%4+zX6l^^U˄ڪw찚;':e OCd Q9:q4H5$u/r}55 _E,;;bM'~ %֦]g"d Jš|o=*=Rx-(Xmz"K1aL3t*;Q1[D_+3܎FYc22S5t Q)x`e#y%Q]Jtpiv 6,p%o/h5篑B35_6[j.D+%pP|sl͑u׫9 ?$z@4Ϗ\n>žPc]-5[ do"QM E8oĝt^K!PaXy3p-l.8>GbV@}[G@N Dy(8??B/b+#k}8|< }|˷-$x,!zQngYX zT?uԥo0'?IF7VRz{`]7O{_wCg6l>{MDa{{l)l['5 A#oʾkyC-CQkTKOrɼ[Q $OB'%3T6+jބ{Ov=Qt{KZ釴ѓ3aPpz2^ QyUCKujjn̍܂f=D/V5Xv㈻6 ACf^oqBkufCMR^پW<q~زqwo=n<խ CϙH!4s(fxl,!k,4< 5F< qTV~~E!o6lN"cz z D0_+i;{qEw|hN ̭V AOqaSeBlG%56kuYapOx#6q}JsE0FIk7yCl[ i --|88QT.u*L=^+܁\5{ۼ M5V贎d|6+|6RvnB8ֈT#fQY ߆؜f խ67s/xz~iDkq⻲oGZ,yq9Ԝ jg,j#TC^l "mnBE&*׊6D^'IǵΎN8=ׁOۊ.Hq7<4[Y=0nf+gەpdx9oWǽpQ ΑGqɹ YfkB¹RH;<޾Lj1Cm4c.F%L|GνHY$G7?T&9`8d?Gx?o7Qv#[{s _rN[kЌ[Yk IDwBT]K)y~ WAq~ _m~ظ>'IxڊϋgtmJ[&g'!%c@f_b\|[!*{6xg{JξyQ;q)$+]LKݬU՘cUz|1[z<)ךyR 8,XM~b!$jy:q m5?V4FFd#ۜXr}PU_#f MKz:"`V?:^ <˚`{c\8O:rIuk^M_3a,I!\. ;`qV:G{tXS粪j_aNZ[i=*a5}&߾HDN;䢊|L@#a~^q upM6oGj2gJV+xOB̒gl8r$ "-"T3'&9VH]:#|6(T`?ض%v"/j/ a 9abeM&0yqB&Cz(V/tÒ7gIop#£ s├>|`1\ʯAZ΃}kZl(>bKe?%!xC!lg t+'?͂wa:9q{ű7"SOa>=WwaKzmR"qi_ۦ̯/ll؜^"at )lsc IK֝Tѵζ8n!FK3nq`7N)@|n/InM: խvNKhHx(H3`&<iBMVhf{%s̈7] QKC fK pBJbiQ,&ɾ򬀜%>}Lv0DHc=|F'`ĒW$ƯM%[.:tl 3kLؿ+,Mݛޝ3+3 ?tBks /3P{E6\pآ:<6Ur$qַi;BGK; 6mJ9ѫ0,1y{fUݢG& L 9W VċaaUL5fč=g!x 23XtWηK z2L0d}ǵ/%*/%u~\!{f3-lVG$nLވQ>H?v'9cnQ3j9$iwRp>cOU/44L4>Yޣ2ʙUuCBլ8kF[?dngrA;u;|1'YF}{H"0UAS(p^ebߘw] $s9c F%1H3QAe+9578&`R])3p[o { `z(<Q2nђ}QmQ;tD_tF^./yK軪Ѽ:U8y`qhڌ =FvGTxs (gxCvZ56o!?dr0^F~NLŁ \}) D]S&Jւ=*r d} }_9c 3!;I_T]q'~e69K^TfV i ;BsX3{93٫ݵk?䵟_P98lZìc&ՂeB[D l]qN~c`yNm|RbA̻©yUu`<{V-C<}#XŁ'["¡zi(N"M{Awu; k(V~=ߖ_;88u5H)?#&t"p>4 vm yGP-j=.Y"c0j5{c_U7 V̸Ulq$os͹즙n{f=`,H>325KL!p@ . i,ғ}?%g̴ {Uq0hM<$̓<'ͻAJpCH?2|Wgo.FmWxXv<L0B铇nkCojՎL!d 셞ڋ #pzYw;GEDIвg{)PyS:/3KǦ5'oI>^Tu}@̿$s%giD85݃g a*NnsTQ yA H3T~(:ǿ-y_&^C{5|;ءkh[QoM뼐 9;":C߈@rN!j:SGuA)lQd=u g=ӯU`}B\}fEK93r\wʺ ǯՎ:JpUR}yto֙lp].صc&z ({9#s)=eݶ\=Zaϕ9eyOLTkP-,-e 0اYo<'^=rx!C/# E漩ni-51yG/8 =I1XC~kA}Sm{ #I0/MMrL謬Rc_:y Rss֜j[׾3/~}Q<C)҂vx`%ufh:[2=g-wZIE])^: fyȧEU1AqkH7}`+ i} `ԦaΚ'X}DUpECÙp. ҇ )QTuCjEv9b(/K(t;:meᛡRWO`Q_Ap;Aӕ-e-˘1aQe8rĜ+N{`O( e]iF^conBY#it39'IG5M,j8[o}BϘ (.N_&/QQ A35K ^|S%(g-NGD?Ʒ;c5͕u7xwnq{JƝld17#\  :Mt` { Ҽt_U7j/UŌ!CLԶQwe,-@B c|t?XA0vUvz `. 8 9IÙȧv;,v A@?ֲg5};mK,߻wBXA\hi^egcwE~tvtF =FHy>O$\C'pX beW^~$g{b_c\vrnGZP\XL9A6d,Aq6m'Q47M2:e>[};%>Cb=z>r;4cĢcu?k"?V<\Gz= ]u?'R_P~pv?ܓ("~t }t)."p(ܼ8X`}$l`Ϲi {UuEP:Z(zg3(W+\ 1 E.M6ߩ{fxGeH6ŒnC~ ΁W<ǝ+!'/=}a3fXgy|Ξ<z .]SmWnj` h%l? F'Ё ® =yGv묬S#RamxKݛGȿ'_sOؔyK4n}wo7$ofH+s=xߩ+ 3؟ɹę`3gf^>poۛB)Pdǡb3ל ʻ}x&lr/m}{Hz@ZwAZe; z =c /(A6SYѢAkЙ-+O?%F( 3kq|P3{HK\\6=ae>9LpNZu/͐z1} kȌz4kP *rF,wu_'zF1tv= DGnԀJVʳ# Nt;%5˹tχ:vKZǢ~yFSǏg:^w73+ֹS&-%a0DAD ! GD=TDD;%A ! *R$!a-a'RD 97ȟo}Tr{r+0ZUкDdc܄Yd,9ftgg|ˤ j\/3fE^yK#G*foY]/3֮nFPjV3s20y7MY&2͹:צuF^ {@oeS5tuc Ĩro_18kʕEg?;\]B,~bpxaaͯ6_; ú zVbE̞7='Ϭ۵+HZ] ~bơx`ML% BSsN,;<22j+ [7uyA+'n$M{ں]oMtoES]հuGI FYy^ +G7@{؛:1{H#L+/k{[5Xׁ}=Bz$ Vaˆ+P娟_u @s=S̰\S_q[\g@܈μ&7߃Ͼ&с 3#X2m ^8. 殶v?: `zέ=m݅ >Ǩq|. Kfe?4y-E[㧧K#h;YzخlRzuQ>`Fb…C&qYޝ?qk{dQtEtZ8~ka7M?e-sbE;{l(#kx0Y|~{{סt{~%Abv Lbhvoܷ@Gfo٩|i\cpr?mjgL灍?Vad@8Θ9gػպG?{I].b 䙥ux\pv~=K_<iw_>72 a^ ='kW19߇HwipKS5cT!gņfq:*}{I̺Иf\k{51PQ+fWxa) ÿ3432iw7Wׇ `ezΙwz$xn䲡[ o8YAOP2og?m-QA}z QSl{2Xp;?TXs?uZ>d;Pf{#l ,&ƵnsFW*ȅ 2#\3f&r\q~oM7P: bd><\Yg_θ.>3yX/X 3[`{= `uc8!"`33m%Ki ʰݗg:;nH\+wd,T *>#Hl s![^a3!hfyO VҭU15si<9U=.zM5 uuNx.z7ރ*x =?uթtMoT`d65e"+>zR />lS?zbD1OVתd#/lz-!gn͢Ύg2B}JO陣,s{Mz=WAʂ&7B괞okoebi}&v@YG%@y#YKd` ǣ%z6=9&c w +b)b}΃m`!L8㵢+N\mU{l (B iao%HܛV= >oL aL>:›v@E:mځfaS; PbجN!\CgAkp\'cC_(_3_k_\5T5}732ދZC76ǏSǃ8zJM-{nΥr?YfDj|d5_|BɘٓUUA )Sr1SשYsۋ^%{H#}sN| .D'l-p46ld@3;A 13`n8Hρ !T0%H3d{^v0xu/2W4ʙyd`; @l.;*IP?N}4F5 HC+fإ\W7d+apXѶvlO^oQ9ԅ^)b<*1&nv<Ù3Hos6ajWz`kJ(%jv]tnCJ_81w&uN݃Hw> "_=sC&*eG\gW9۷Gm\t+dW]7U5vÐ,lCvX;8*{l0qx/n!2@/l=,3ciS}m+;{^#Otl͆"!fF>+bE^Z05v{ޞ5̨6WoX_j 6fm-ڻO [bѣ0f(؆C׹аDᯏ_m'أLWzcό>1]&of{`L *I1Q>H{Gޏd3Kꆳo JǾRy04{!l%W9^Hqk%@=y[v-QEI#xUPHQE*$hAy]jE)ZE$sN@HBnQRZLX1?SqQP0P>?r5G&Ojs,=Te3/'ۘTIK~ύ 1D=|$_ɢygǪmK@]yW^='_jzbz_3u@Ճ7A!z>_,:x^ CM=jO|-j*@:19۝iLة_G޷'fB=$&DrX]WêW}+SbmٱAҼ!}R,1 bߘY`L yuf.F){oZYمͅ*DQF. ji~ X `+yGRhՕ*W5q\ֺ -:kHlY)XWJǙآlzYf'BZwA!+JD?%anӮ@J"q[\%7>dbL^'&S^XGYP$X#;]y皏=+innUܒjU6:jy.rsdեP nmH;UBdOЙ ?>>ϣea۞Īsx/|NKT!|^.0OZwZSj{p{᾵ݹTP_͜W+E*&t_zӝ+="}4>*FO͢[?̫vQsv^&;zk *{W #t{:swA'9,qelq޻,0_ KyYAf ]]OAuάb.%OtsQ9 }]]g4лQ? X5=d.H\Hιa/|Cr֖[zVޠP ){4PcOڽ^ΨNM*0o_ k.!$Em/@ O!g;;(s=;}]!=|ҺYA H>Y*8d) <8μ4~v>1/GnaO@_+{]0s(fƒoEx*0<1ЄÙkN> |+]'BxG{nΥw.}Q7 EA|`WG࿝2z#$~<ȹ>kɮ`!sh89o&M\*< L >lYLSә N DzH]=<ڲ=$N%0WL>}+^OFH^  (gH׶'GQv? V9 st[g^G1b@6|$} *|M8ٍ%s,=Ƭ~ 5/g_fy3RSlJZz\{~kr҉CMμg?L/$_!\{9=&ȌB.!vLg=/+,كHɂg?5̭m-l㞐{5&?-JYLI'6@"{c^v 5vq Ah5MVB'1|dWwZċ:-"~G<֒m~&q>[F:}ھb!u (b]`X!2W{5WZw[܇!*-9 io{n/@bx$SG.(~ sXN {͘:yCfs{ 8r P&ؖϐA9#Wx̓ P%X#ɶv w D+ R E&BZGs`*+ܠٗb&3qZocx!'|$XiBHpLԗ/{+IFgUlO=%oWs"0g?>csѕ+{Cp/=s-1!YlYj7O!-x;;Pɵl,>U+7??LԎDZ)h 3w7xSZk6 Η}vwEsNז]-RHX=5lܦ=u3œ s*Þl슑pd2nA=:ر{Z|@9j!Hھ|덧"FOBZj˵?JzS<٫yuώ5n"׍/Fv6!uv}ms Gwko~__3ue; () rV3WdN%~sFgF]F(sE{.1.zh5玳ļw-Cr\evo8 2q·$kٞFd:7p[=S,ql ľ8ĵw=8pWPx[}/> ЀNu{u:Byy-!}͂}Z k-Iܖ w]rve7g>P^F?f9?}dp:ʹeZܿ3 nm_Bx~/ Y|U)}H}3=l`}@doKz9њ]TWPܪҿwlk0+-Jj=Qo\duhxsa{op`I m)}}XhiYWA'@u~fa]P4@~@,zm~;k/R~^Ӗ]4|O{F+?;W}^~( ׂUBVg{GU!z[Qw6{X>"5g 8Npְ$~;lGb2Wd[.Ay9ZSsޙg^0k޹!<;ue.z(T_-]; # 69>loe+x?Ll.-; ջرyڳ{<tזk |/iT=Ssv|@'oB;m;sk:Z= XL@poul^} {< ^֟^dE}9w}՚)a/\qE<^hd9z +5$yHkF:C0·G޵5]5P}x3+'6;''&Q#aK=s׺s̷?ry^d+֏U(ED%: "sY cSDžM"U "" h`P| ( ($!yxl>IdsfwP}|IwknFife6Kvj%ٞ?>e3c:+6wQn=$op{*6i"|g;Qkt_v-.}{)Nu*u׶gq)?G_og,ieڧ]laf}@_sБmi'VU&%:9N6aAhCjd{>j#@;Fpt8Ulϙ~,xFcRTHG`M>=<ۼ`}uwXyJ3clCBԤ=K+^9ŭQm^]tqx<kѳ819 &mS rAGܵlzY ]r ݋KqyWrh0&J>kf?(d/^園H#@m"[99eYA&j v/~Vef3@GIΩ/_ #ȹ9W+ U@[{-L׶/J Yəx%όKJZX9+B#Wzʲ=Zꞥ\}myߓpiiHV;4ŭm{%_̌i!j ՉeFrszD!8jjoBo#Zl#1F'u̓l$,[{jsu3곗M%m.9]xƲjqg*s{zٰQgq {WD,jqxkS4 d"NT{{z<;Z5v3cxNڪYP2Hs/jYŌ{z`ʇ`ow &sH]̵ >{F,]aע:Kuke] :hܧϙ52Ulm/=/T,>%P cD2SWU|a";.]y~Rx瓃Av$[{33E)P0/QyUb{k xc{2SlW JjkY T(;V|࿠Ϗ_5x,=g `jBڮOsr|]ou1oVw|NrfyUe58;#v9Hg1D6?,3|7BghUmz`DnOXݬm f$ fv>aG]|fJMQٞqSmCP7z@?N,ݳ wHJCuz43%A\m,0 :᤹X\$x&H\A <JDv$$U=d}uOKTF9mX}ѷ_OBjۣ,\YkX3o!=e闎 _:rĽs'(5A Op.`DY)x?. @ UfjuX-^XZI1,!@gvߪGZeeK7ky+aeuEF$4rݠ#}ωM g<] }(6_nSOk*AfTdڋZgBf<4-[}8cq^M6f^ ndvM=&*3:pH@,jUY 6;o&gPz_Fѧ}{fo2k >lZf[l<\3Bok(=yWCS 07*c౮ .~lѣ9/q}8O *5] B? sCe6.@Qq'gum b΢x<2s>`?#%=G&qLBA}Ԫ2l *.樉D.^L9rq_' 5[ I0b?|U,fޒ  _u!5j{έU-0tL@c`6پo{ 7fޡJXn%q(C5CߞS]N4ԟkd0N5@}-V]mZCP*oq8wB4T<{a/d~Hf'2N?E:"̞!ke:fV'ب탒: z'V^\%aS@Avaa-<[y2'UNvg*cF[?3:{L=&BPyls5z 5s5{ƮiNiN*w>婁7x CM5= eW}",_;9 CdN>lG^O"ӬlmM+(8kZ=I?. ;V+w{`|^>T>Z?!,!4Azel5Η̴fZYsxb2֝/Ƚ,Rxo2VY{?a=yޏ! Yٻ>g׮_Ӱ4u.@!A5Be6-}:^@u~jU-0%A T S6քµ `s3yV@홐[<U O邢@*wySw4"-@PVUxyPAn>@Ϸ# l;UϹ*I;@ȓ,(Nv/?C74Y˓q]%4!WXIvx90YJ g9uԩbХ/\ZYvh 2!|JG=B̼w{Bnְ?S|upvhؽN9__ț gzf'r m0)N50˩:ֺP}pi%q߉<9Wj hzAPک?dvϓO.Fi;D{=μKtS+ rj!3iAWlXwXoӧ_OdG};[ y@ 4{U<t?_xx2B#=A6+nE,`XCaU,E6ʲ<~#oyl:r?_tl{5qh 5qf *Svڕ5{s(>K0֤A5zҪrEz߯;S-d!̥ųMHOB[=:1TgC4uE_@ 12-Fɓ{NA`:z^b0 |i]Bi->mȓrd4'Ūvfg!|@>3d`8tDp{Og֜ުߋѩ hT*k P06njl5/xAAZT xf|s4Zџ\B-3}Ak,櫟}硸9'x/݀J~/gesr#m*/#B> w{UJ!x܁ɭt$/U'dN.i1z$ya .csPS=B4gT(^wb0g-drh E16 zC2M]>7fF2w#4nܖA}[g\ DŽnxjU|l8dο ͆_0}){14^I? fma?nJ3~oAQ/5Ŋ%4pQQO1k{\nf̐>쩧,yl߅w dY\cnG }(q3kes~0{$/Sr,!OJ_܂].8O^BػZDe6nHCwDk 1^^օ*v ոSwnѳTY ji3߀;Nb®r(z#=C&TeC`osLv].#Ռ̂k͇rc>~sǘk9nr@Ɇ1ݢOuu} ղo438yhrOfL TmF~*ծw!c6cq}?;Ԉǹ}OT@w!}(w5~=s,)U 1-}$vػͺɷ@GtI?Wfa橝ڣFVwEvWOM:W? P>7W0_㾪Q-jv;f IK0y6@p T= [N@u̹ a/2ӜTʴ7jG˞/kx7o?&JqG©q dAdm5jowHS;Y\CzYj*0[: zeپ>y~.HG5YCxl):heogAx~/#}D;?rڐ=┦ ڇ91[!gԗ=^Z`k[c=%P {>gio"g*LXkPaԲkЦݕ][Sq~TJ~V>Lڌ|t%pM(͎<]V,=K+c3k=]Kr8iMj'O!n聋Oq/MU\#yXpxA*xVgJkn >X5تZZȮv.x]?oqGW)Qfo|_ZYr٣fQܗLSU|I%-wR{l\r9=yh1k6]?6< Uu>5 =_`34XΞ2q b/HzsQw{_Wq0)n6eln yz=@pmGgobz`o5BvMUi"Ϭ2C 3ʲYa1tglGn*7فEK0fcVw[Tڨoz$7/y @`_# wxʕ۳WkLHn;1^U6~U:!8҉-עJ.yUU>,arL5;;d)F\> dTUt6"cfR}!0|O n+˵BP|KP ,rOjhw>*3i:Ί悏VOtPOvnv;dfLiGz 6¬UmZG@`}-f dǪ5V[}hDLt-5yIm]U٘͂ :y פ/Rv]2z7O䥇 4 x!o#,o3ٮ@d[{ wlHϳ0s&zsMj͸,ۖt"0 f]^^zWc3P훑(h3YX ogU{$؇ Fك܏TI8ql&A>ekna9#~oY!̹L@mmojQ*h.{ չ|A*נ1RE͞l &BOe +=NFSE U]c5 ZU.#xwIo5FO=㬙Q2sW@ ]k2E\{sWX^Yt,gaY@5X=KfWu \>قn=<3{*s%;߁b~X Ϫ*}mG ؃~Y=j9@O`S@r%#3~ڃ?r T=Q{5k6GjsHF}|{!5 6 ց e?q#8/ ;cF\v͞l :*Z?iJ'zO׃E¬nz^u?k}(\gT_5J/l ϊcp/}U:8w!|do1"ޞF e; YwE x| hʌf 0MH@i} D Ϋr~/L9J9R0?Xkپܷ!j15y2{&J#mS8q}T3ēFwϨWꯓUUeCFȾ]#+:# >~"e_Pp.n+9G_4=BU6:ζsNvb/WqZrMU}б$'(;9e`$߬K㤩>cE R:ISUt%.+gc]Qsw䦪<P@ZANS 's݂J:7L>R˰N}1cd=@Ibdj'Kv2n_KHJggтOCy ڲM=(sL^Ud;:flDZg>X R kY"C5:BsׇY ocY ͺ@!P+gARdxc9Q>mttn}SreϜ[ҹϺ Ȋy-{pO C1vVcPm&R>ۏ-&TmkgUͽ9 ȢlU Ki[Al,2( GZAh!U7ڴ$lEY""Ҥ(ڴ҈8{–c_ꭜÑ+и`("g’~n#w0\\ǁ{EKXq2sM=oۀCQtg qPrQ)^AΊg)*beTh3QT~C)9N"R^#)'WuQΛTn}H Lx}1&w٧&3 V70<+Sh̃3Nz^ǁn. +ޅPVT2{4Q؆ܧڠn0df%W𜺯vhi|&P|u3]vwU>9YS 2g:g\I;ZZ0 BeM{@қ::iO6-5oꒄuuӹm>XUQ̙iXms&U!WuȀ^rl.{ں#(rد{0M!>Ρ}ec~ ڏFA0NF'w\tʁ5I00KA9٫3: |d8橂Ͻv#>C/FngҜYiۭĊSŸ&4ʬRXx~rE/oušCg:V(jU]bEm=/.}PPu;pf-2`(rDUc^ONW^펜Y0xfOrWnEƠ)Y)싒QE$::ݥoe#a'oBT2b!MQeS#^9(P, r&tЭ(j]QX+v?}56҈y$ l/{{U!Ɖ#dZYczh.X%e#pٛwW\g2+<깸Zઙ(k=\fbOqdFu'~otXj~_FXV짿vTfzwsϳnQ%>}@zYC9d5Xvۿ߇K"M'~g#ϷyZzF-aV&^rQ#k@@WR앆0tHfFW.39=mtqF#Y=OQmV>~(`v2<{ZW5Fo2P5|dO!<9=珅9,9S˰kkWNƒKSM_r/a( ~!V#s琛 ɾ_rI)$ r_ yL(.,(vg7ի}Kunbڹ}r7{:xc]Cq8'׫^="OJʀ*.9@g^N.ޮu5)z(.KyG ߫^qCCSo FS= Z (`{tţTtx5ݢv*}( P󼣻9'Rmċx$QU-;/(UdW+x(ޝuU.&,_ޮW=^xu sdG0$}J^QX=J{4KN{خr{_%Y[=%UB|Uμ;A`Tl(9;S:ί ~E1#;]w*]/G]!YśtbY(~zMkiIBQj} 0Gm3>z{LvW>>eRݬ3I|A VWէϓv>QrEB9.ijPzK  Qٍj?WǧfzDY(m'gUfxj=xiB of^qAh KSYQk)zY AsԚ{Dl'K٩3Rۚ &R$YNQ+wq*gX6~+վ̪+BwUZ] Zvf^'G'X#5>ɔr&x{ڻ7 څ T~WߗLpydR_ڝ[H6# S{Akw0?EzA<7jЍ^{@{= T=s_/AWd= S]aY2[;:.! Phu]b}ɹz몮s=Vxr⌢=HT]*-8LϜ$#n G3>\3Σ8 zSdG4NWϽEZs)Eg/%^Q!xa\f-(O9sg K'(ϩd8Z>$FU3#dV=<۷m G)EU'+̿c\Н޼@boܒT2sz/WW&g̕Zsb]0'>( H>OܧdLʡGLzsݰ /ҝ=ԑզoߏ !r2u'Ļޝ2~+eadL&8BeZjZapQ~- 4Ci>)ѤNN6%LEXu3>SܽS>]0nL!&2q"gdrgd}`  k ;8vŧ.U[6#{DfM98z̙b8=]9]2卲^i,5eZ~*݇1)/{٣/ av5> 2=>P#8#7q12gaO__bSc՛uN#k|e> P*X yUYmoPaW|E^ ;߂u2$#wW=^)6mQxd^wuZ݉ET&45f!Zf@( s)/[ik1`)E7m>{Vg?w~~Ñ32,(3|#l_ibYPnb(&L zuN00!1 +3yb0k3ݺKn $[/ ocA@ȇi^VqW܂0`|Kyp,q{0nLz.F Yrv2kZb x1I+vMs3sσw áCײzEwbwx;Omf ~Ҕq.vht/34iz4֝| y?<ki,:Ktֽ**}&mǭh4kq+(3C*}&9 EsM`[M?Sk}MNmֺo7v>GP>S'*fL L-iunWwm9 E1qq}-3aR2!{93fo<< ve;eH{|+0uD`$7Fn_+< sdvcܤP5}cic3:.vw#C!E<2u_ 2ftH3xCݲts>ƍfa}{"P,]s se},jwƧ; 4Nj Zil>d^_^p`7Сi1#^g&-sep@% 2O.҂=9ifiܸwaRXPYxr7YP1?/CsARO&0Dȴ|s7bD*LrkiݮT{ԁ2z8~=gbNy.鹌ືMC=߼ᅮ_SwDs81K;Nbub\ #A܀8jIu:E!PSv bkŤω /`$=M'!M2O2qBu9眀ucUN30k,;k^ ,ä4@i77XsᗘpCh\3!gTجCײ1%#0n:۪MӀ:#{2dYoA!Ҫ&00G#<{4s ȷsm{0neΌCGI᳻y('6i,+iYPv VӆT㴠t#=eu+"@[1u!r֮o8MWc*<|-Йw Ƅ@}~濄O"^4(sf譈v$toŬ yz`h ]= YƁ t]\<B`+^Y|pRz>3ub #}u:^P4*C_c%"C%u Vk9zfcaQHHZZN^bư@d^Pu~{Կm;0j5(1T1e?|"* NhxL ⌼ YRVJ&a\vn8YCCPN숸_nkρz,8;0+vhY{4#-H3NEk0 }O=F<vJ3P. ϠW!ϼuB'3 sK1c4龜O$`;ⅳO"se1 )v O iIS~l27ߋYXtjP_^*dL+܏.|+KUsys&u嘧Gu z"M:~ B H4ݮϿNwu ,.}8UyW\{ͯ z-Ŵ5Tk }¥s=m+DKG'-Z/I{Z#׃Ig4b i:[ӊרx]8J*N{2JJsYP>ʊ?DqFĬ(S @9kY|0c)#q7aacxbP` yXq'+vHmTW/)}@[x 8?oHu s ه9ϬJx_Ό^B3EzJh#7P \2cȈh.q .R¨c ?UpI[l.B~*z1>:I`yEgeu3 6E+!!!=8\vv5uBJ3Ic~ǡ sXzroЯE7 onFŃ1}9sLNRؾ?G0 ݕuy\q%`,!wT{i7pt#?|c>8s0 kiݽ3u11 K@oPT;``\T F܎PSGp5w,xz>sLH7x(3}u'xOuh :K^Ђv+v(Yq'ځ P8)W XiFKr@#!x8 \ YOŨOx{p_QWcǰlF3f ]3թeAײ]7Gp<;γILҜ|mI=Y9'!$TrpݩgUg`љvu==WqZL zX {z^3iכkXfnAp(\އ=\1.xM_I6q p6$,:9r׫ Tn W]{<'HXa'Ap:"c&v_ʷe*=YXn v Һ[Λg`HȑZx3ͼrF{zEi df' ikґWYҺB]`9_;I(s;UR10ӊ% m= y{fݪc qP#{b(/Z9dWL#&.} ]?ۉviL~{u]+1}`cRD 'KJJ; ;H|R40 &cՙf*AZiz8pmX xw RB݁s*sy^:3,^P^)̜ 0D/kERmUj*Qc0m6fM?\QhF,3W]0YP׿>fO!LC}mea8 fVbs-ʷΦ" pIiO`4ZI{|Lr/6yAmأC–J{Gu C 4&M#>'56of1cwK;2Pˌ9k}. [obXlc]YgYhg?:XkQcKvoX fT02XV/{b2ֳs1Ls~yqHqt1xNc#ȷC]}ʮ5v)-ߍ_{^؃Z إy1#`wA0{Y o٧3_.ǖD8,rb1cvlvM^T dΌGt/iȉ{i 9h CCUYCjX4:cbsgIʋpa89A왴ݮ#ɠq+@=/ {-~HnWEz˸''`-~cwlQvﻌ|7V0=<Ҁp.?? *w |6|H38WLfTon 8*(M9sU[/dҎ@ckl׶dP9+g¯)NiGN;}WDbUyAIO&PeaǠjTgxG xE$;%ϾJ|5u/IW5r"P7GOYJm~\-cϖO=m[I~uWU./y~*=I,{nm%yk+^|Z8R˯!ҩuZ g;kژ W!U({Ǟ$'Iy8 X|5G](ϮutDEa8^yFoEi{BW]2ھgbΜUZl޻NDk' m*8' deG_)c/*?kXƟJ9yF&CMO@u1q8 $#PL4?5wX#%`}k5ڂokgW"1{:뽠]\>~rfl \Ɓ(#%3FO=V}Ȥ7J$fbCPH yfrQ3L2^ ȁ _8; wuVm/-5X?^\ Rꭸr_IKNg%鲷w:kۭ@D\WK έ^+N|S S&SoFoN'PtGCijl~O0zf2N@poGk TA}:xC$=2P$P Qc!\·y$ΣuGwJ~cޯ-u#LЫCjH=m)!*~cI=" %}+ľz}ys&hUfJM!§ߊ0H~+ւ~]_*} ̾nʜ VFg@*^pp P1b eBuD=ͅ_cWY\ynb!} Bғ&~gYgC|ϭl]ް wd6@?ޅq,'j9yNM0$˘'w*'sEYC%@5@%q͗L㏮%(͵DqxLeVo~ ']_v繽~4ۗ&By~䄖if T.P3sr& iW{Mwpxj=:WI%@]Z7"PӎYuAU+_=75<`ٰWH7I> }$'<~aU5>d23淆;rM~xG.v#.l+.PU4Jxǃ{JgG\*."^WGZx@F0JCG#7h{ gEB{^ l75 _U.g'Bx{-c'm\>~y|ssK4rFAսPQvpܘYYyvpgG?A~LX^i}IUgI`|\Inph?EfW~?Uَf%hiL79Bo!~ojnyVy@ssdg1K(l+:<:Pe -mP^DL,5`טD$eo#Gcg6ZbWif'l2Ցmw{@Mcs϶_ٵD1#ԙ{VV~WyY3cnkrco=al}OґL(pe_i5f}rYh8?C$G6jƾl(LўSb?MHMfxX'mʲwC(\Hf g+e%Hۖ]޲Y0dPؓo=!*(Hcv^24$mgt1፳roN,c|} 0zpƚ `w?|iW]0(>wM>*kJH-sskXYvxλ"#]⫀>gLϦ@|azO>.Ʈ׎j'̓Ջ'p]#efze{{`ğb. 4Ҫrؙ Q>zlECed~}A/>iK4}fB(ȌI]j战sǢg+l sy= ̹* ͸|ju5;cOiC!w(#Qv 4ueם܏19KӲ gc_Uz"?Xl37rO reSþD:rނe&#W>'5UِY= O<^YvF i9._Cxy/ ikŷHC i{Z:wk4y=YeAf1d\?pnq<#&Ѡ2[v{3{dc ȿm {yk lC߶ fׂǛvew ]d׽Gd| =1==#)~R?y "Δ6NA䬸%gƜ\.3 eQm5;qH/Vv\xwè=eװyj; i"gȼ^h(?uYYwc+8cWz=ggo2,{#lݷtM{y{^E!S`R,zVFEù_$rPg-OH39OɑLjarcne%CțI,yV.;vvWC6^gUe[ʰ!q9stյ4yzQK%[Mp F-k-˖KMw pΆЎd guF^Yv]ɐ~WwId$ys+,9=\ rHsjyԂ=âbp䐭׳XibX5c XfM-=dЖIXiW87y&#iځP7]AO;HgY* *ˆ_8_-C'Ş=grUe9j@>uj]{8/ -p,7FsP65Rjb=y#}- / Ha[۽ z v7({vO9GbL E0 `*Av2lIi84Ll k!{ 2C~!PCXԂ+g[H229spC%CVXvN5z?-!mz0z{ ݢ}0J '/8yhvָ#e/^$s׎E0kϑ{cY=R*j$?,!7{oF]UrޙFNsԵuWiv]ˡ34zivXNm5/MӴ^Uk!dFXi i !_m |%Q!k9uԁ< ۨ}n͢/,=L5^84>&*T!(h!!$(;&"Uf 2K'T$7M` U"S e漳o}xG>I|G_aPf=/1+R Mװm%/2oG+|T >cx;;rVj{ʩ>͏h>(ۚ ;VlƤ8͓CyyP{<4+^zXSġݗŤ[NKz=‡֝*5]/v;Ӟ OM[\sPJJ|m\o+lݷva YyRii5m (ko{[hz[m;Hj:13u ̚FVM }n0r3ނ)ӯ=C5;@0?+|r&I?mH,Y k?&;ej9Q;j~|3ػܢv#*E|{1}7D¬}nVf'ۺ>m@=*;^~@K _3z@oPy`+&Lvޡ`ı-RRB9;_??~اHB';6aPZy I McӐRKqiD{ |'^4ƥ⣅Co`IkkaǬlVBJOK\wGd-#٢*zXwÓj[yCx-5} H@;c߱Ƕ{Q'C)_ՊR&J Bt} ^ܓDG{ͽսj9+zI x1+M_3XJt9Yfi5~9Y!>lkȼ 3Mu ^*fH?j<>dl yCB;B&{`́:]6J'߄}m߸͛{;oP牻n0zOXwÄ![ >fόMϣrVdہfUg=|rY!4ҭԁqiȪW{:kuo!n#]s3egYӌ}BLlqbj́x e6>(~F4w|,l嬲\;aΐ3MvSw1h('y.;&x>G Iw&2A)\n̟ъ^wb滝 na?̕c)fg۪nD8nufѺewMuWD - 'hww@`T) gXP[Q {VMv}d?Oe29g/QkibfLD%<{Y ߛp&oڍzhFqPDt{cXRp3g<;m^.aA }Wy< *c=Fųѽ*.#;Z *iU~ /6njaﲇZ*wzs;/:'p߀ 5W?8x3VE Wj;cepC&L˙'wSv>BF agakfxWcoμP/KLjUF*A !".QuC.g+[*,br^v.n5-b0 ҌcsszXwzj/+W$#{2P캬XwϨeQsѿrhb򑖘Ɯko-yeB& Cā;q.8wxXs$teoe+RJFO0'’ua PO3BRSB i=O>d7qWC3/38vIۧ->H#jT7^!3C"tg0|a+Թ,ϓv7Ls>m^QAkS@݆访 }\ `۞d7? uuq sYix&LuC͉7tL; n3 <(3]}nV_3͒zJM=mG?5TDᗬc۵Jhm7,Ldž~i98mmBߓWkN 搦Wܧ=21_ǒ޶4'"g /3t10}v[CQ뵙f՘P1;g~S.0+Wvp^*XXi _y]5GbLaC30t-5ٍ5j(eP@ܱw(2#ݮS!ֵS1tѽ(ݱ׳)cp^ pDz !{'^sVΘMc?A tv 9yT/yRaI| K3d=`G THAG(LFfn7q X uVn}lvтe*;Zt;bi {Lne|h7P=f ,Ły.ƺC K}dMFeoO`_5`Ե{TNKMtXUmꝱ!wFkA?V!!:JfS|fD#-E'Ld/tLBG펩m\|38{~*'Hwhz TfQN BU Y"2LM^S³v(21pXC#_ ܅?@|s*3 k0Xbl);>.9^$]q i}Ec;4.p%+^g~w%s^ypkP\t[gp7LU= q/1~tx(={{?e8pT,`*뎱+GNA*}m {b4{fo]:7}C]Pݹ@^1z1# ] 8ͽwi,m=:Lf.4BZMJ~9f$ۄcA.,*7}SPջ?ȞfLv _IVdJrxOhBᶘտRRS#|Fq*}Z4*ojV,[ı@v&QY꽲mn,,ٰQvi%UBJ* (Ӏ R AdH#*6m(hj*ݬnHVl=^eqN(wwoRIBp/s7ٸԃ pHԗC<7y&=Uva1cV;>ڽldT|!C2\4csvUTA }PJ3pg*]˲7~FԪq+ >OjL5P| rϤK@*9}LYn >?9VM7lv4UY^p=!.S qBH =թiWU6 oR7ut8w}zL|R7V+PLQN}N٭TYv>7>ީ\K^X #`*swCߡ}TsXX <X(ϮXLה2.ZwJ k uc@[S(صd:P|7#1{O,d'P{TzRPZ[ ]g? <#*|3]1N{Ve/ h\ClԍzVaeG~mU+tĊ&Ho:;}sCw<Üщ|8vTKX5|z`=ٓedn\w]?:Ppz#91m@O\'qKR$^П_\˽ROߗ1o!{ZT'uiכ}y΁ῂN$`0` kJWl@Kqd)LYs}7A"9S2krH`TeC - ̺\Uf2_~=D]'!ںQs+]Trx]6`GuuldVeCl{1W/{> Wv'2ڂhwDozGe/0ʕkA?<gQf+g4ULs BR%{vvQ"yj%ٮOt :xb"D3x5y* z-}ŢIa{Q/{ h?9;8[vm~W:]p f02sR|  jDc1uVg~;bP[Z1~+w`5 #~gM=)LUav sAIwRrxw*W!Pֹ>^<>~ 5*s5qz&HԷkO[=^{u7/Z{nɉ1Өo\>>gx+WV߳Bs$zO*s!q/DV7դPC=9ɽت~o1@ꛖ٣!>- hGo]ש2I5s`ҏ}3)S BUf2(,nV~yfU KDy_bP*k!@Gby<;x ^i*>?D;w+s 1v,;V= j>LT;'YTS/;'u#_I~`߽[`0HzÜQ+١&&TkvMi*˭&P#m V@A*e6;.#F=I3m:PO|=W%BRDR3.\>: 'OTcfy+$_V%՗z0o_ 1/0-?4oN u/6+оl([s3Ƭ573}yylk}O6 c Y=T墾O#>)|ZߥC<#p6wEN/_ʶ<躯{ r[Nȃ Tk|@¿߯j[C݂J3A|xGlG}?1+"T]~m^-w,>y12xDr-ʲ!dp]G'䞽*#c\|ȗf@$.~^Rj0m왳l|t,͊/\k56w)Y?{C*\ g_U6.ߣawa}Wr z:X?Ja{-խ0 ٗ:H!֔?&c0Sit_4XPR8V}U٘>=j _;,#o_ 7^u3wo*Wx0C0Mf%e{w}akڗ×F5]{OYvAxj*IRop.I1TYvF6E l%P-3ﳕFmHmϔdUogxY0x{,;-mS xqԩdkkG({vf/6$ڴP H+.uB]U/zKxrd]^7O{ɯEoʕlkg 5IbSqQu fZ<{9J}s1{> sYyƵn+vgNDyz,psmϕe<0ҁBC#]2䙖|m;0AԬ:u[ٖ߼Vq0_kZ וCg@ēyL>yn/w}n̪5F=a{z=aOU6f^G4Anp0m(R'y>CM\+!Le]{ZNckhw?J'0n>h֠Pf? &A=TEVC=͊B &ZAA?V ɘhq8Vj2Jg6[`AIBǭ\k@Y"`HxU}U i P{m` Hq̸o^tf`#~S -!JqP)%nA{r`sE}om];Js]2`tT*XJR1 0+ ;ɵ54o- L"{1 I\U6D9~ ,&rPG^9ʾO$<Uc0jǗc RUywVB]|!c֪Bj5-)^ q W.~_F}zw:=] tTeNUAXA%;4 !"^!ЂATP@pAPTCQVEUUBXN bYpJ6{{E%jOkηܛsTj[){.EkaW7]jͅvEnU A#%Hef27YLq_O W"&]`DhN@Vh}fLь} !/!"Sҝuqt/e"Ak&+= f]MǃO6q m'S:Ǟ!1,-'gwΡb)HnVw;8f,ߌEH}8yxcׇV Ah_ ,瞯E+vB,`7cfVvFm¸W0 x!OAǨMyan󽫐KH~_ji}cyN,nx%!@;8m+,IœٷI_/+܊'چ7;K /̠uִ?g|yJ{,6m%uwD(3^|~J&-b!8-#_g{G.9{KS]7[A[F{vq (<^lE D3g\'޵ﺠ]Wos]fxgntoL н%c{|TO^>u Oס{LŜ\I;UӟZf(=k6nd y2K0~?{2Vn_'u3f.dt{yeS+yys`NB}3<'3mkFy, \(vTgs.s)}?OS&lkH/ZI@Ls۽-?u?nwW/XRcVfLG?O738͏͔=vG+P#$:<U 730e\^p5YiN=] ;]g1(kK3ݨMPq|ֺgZ=4%V//!m:f1eod{95sn[$4}xD!cڇ-XhWU7aƤ2'5oj`tRV!r0wA)ӝ kON^<3`jk3?@33#lz%ײy=0MG' *X5ȘrkK;t79ml 0k8u<#|0w؝:2'r?3:ßw=gC#w]4ـ<Wz7MƤX 34٣\J+3'A.f}BR+u4 vWjL͹ueʺ=]P1L'AeA^h&rJ?&nԧe X1`k\wBvqKpp:LˎּwE-exRfD<1sfU]_glt Leyu;G`̈́;NwW< r K1|) <]4AE^ 惏aNI1ϤUA3>t G̺azUb(+nŔ9[1srP3sG?3n Bs5 림3`$Đ+.̝KKY}9k /ۙS^01^̝fD^#WLigH +Ug=6 t贎!0؉+Z^v'gGKZ^ԛ+Xc9 yexnAUܶv@+DW͜wtUCd@x0b}:1|n/^38(0p= ?ŌvA o\Q=IΓ aJDX{ϳ.wWR}ЃdXvh7y=4؏a58~dpL]tw/:q`GhbkSUvp߽V 93Ut64ܛ٢G&֘C[s+Wqˈg[yʺOu1<9:̜s3l+e`-78rb֜3~6?_ρecoφs@^;- me`:`?zOdFF꯻[Z߆/Q++wGZ98r}4W+ݎ{cwì#Ϥnz|OH5{t\>3;*j г`pQ:@U7lI{f¸H 3_ɓe^=ǰW7UL]^yzG}UݘtZjz;bYw53#V o7m# @z최1khS9Pq5L]Ոۯ 3ӕ?ǃfOYIvl9Zn=)&uݻs VyWx'YĔ>o癗`75܋>nv%1F;a8n9HͦgPk.ϔu{h''.ݘ!Hy(뮸 9Ԇ~a"d.;:1hÕmyjуEtej5s%+:᤿Mb1ځ-,},̽|< ^V]3Dy@g_yލJ.O53&'b1{7bSnۑu0`7?}"bս|0tD9DwB iZf6H3fݶx?k]̌ayMķ^r-!I XZE׬[ 5k<&^,s-m uw{ھ9=΀Aʺ.\w]όCm0~f3)펾.Bͪ1a_XK Yʺ˗+~>r:m{V @Sӕ޳3ˮm爺EȚF~_Ѥ7?8Ee2 08=in;{|`[<&|>-럇ճ4˚rUh͵P7fL>H34UҽzB [C?ڇ3\n0 fm~Xw܃>eZf/Ⱥz44@S5pu|ӆ@edbBypj=lykѦ-N]+>ћn=n(P5'Vl$n´c@MasbiGU7䵮zhI-x-(}im6Mܚ%{=:+IDŽG(Lg_KނQ{a|z gs/xG/CUK u{-H2Cq8;pRLCRp[,r?wxUAԪ>+Gpp+{&6u=}xʛɅxݢpɅpSK#@:.s0P=H2<>hd2Fg;w$BTlAʢ ߑt/oGx/R+~K^KFx7F&, "tclx*v ҋ @#n2^:/Vx?5GG"D\g0gf-6re5)Ǡ+ 1&L8Ksai% dDo~.xù2}Y~$2Dvb*muPV ƀ窺1ᛯ zu5VWc[qu'ECѸm˻H !3ut``?P[ Caڷ .k9h&|9k35'`4ggKZI>6/oav@U'@G#0i^Yw lY{KCXd`.ZU/zi*W3%0xư2Ҝ)>-nEXOUl)~z2SӪЕVG$;.&{,tRR([M/kWVc&-JfeBR<CW*A#Nͮ6,)^#Kv1"3 "F)}Sg뺯~y[|:zrecɱLD3]i o}уX2 ,am> o5Xܐ%қA8@qwle>۶+`UڶP%ʟlG,_TEڠ |0[qj6'_ k؛䫌/&YʡN=XDȀkю3\˖e?$iq qkFfawm@.`kK93zre,"kPGæH \MV[ c#d DCD>#f@reǟ^Ŝ(7{s}|Vsu{xgzv v7l㬅ϑc؎rovO?$l|=c.l*f쨃;d=c:[BY8EOfs<0 wm}6{,#~c-jդ,owyZ6{x=^xY>K9dB$j;kXHbUo}p NoD5GI{KHgc̡` {>ΜPܑZz2X0扚jmvjU->7(ͳc9t\۾B?h^FH8dɎ T7΀[SNwg ~@ܪc{wX ~ד-{Ss `t,NylONz٨)6yKTl΢vv=,ձO.٭ I5 [-ղd= IX$$pdSv[ɑzMcW9x>$W:3m$Gƛis4J{{?avBE8:${ܷ=[ :vR)!dCR2} x-8mbeɶ3!tiꑰsI(te}7b9Ke^}2tᙞ\l t܏ 4 LEk+_JeHb9`9} ߾Єce{-Fk8-B7vZG=G}} h>#-;|c? ,T(.B\ތH0be+P ydǝ>ݨY_oY?Y K@Y+Wr!qx(t WZ|")}ki;Gb߄$z^SsәV*eߘъtya#5]PGYG6V E^!jQo#Ȗ-M/ MP<u+4z,f:|^dܶwOu9Q]N=Q1QnwqD=bvg{@Zx? BQTMgfKE~-88jZj'`0~GU#74'[vw_Co*ɫ@Թ4 v-Ȁú12Lz- f!QB(|e7s^sHE4Hn^_rdCos:֎W }0X\3y 25/Xw&UYGx~f?:;d%Q D4v$칯Ͻj5!h4_܏\@Z\8X 6n{/Õk$^m\+ՔV+0vz{p:jx 90$2T/{<{8 h bk Q'%=%ZQg?7go f jَܶPc{v]mќ؟J{)y´pfQV $Cݺ0CfIvi1#Nbh^w\hG<$H$Ms=e>܀K34#64SA3BÆ[ٌjٲGE׃`E1t梆/A8Wg"=eN-1[C":`=h8Q녧q3U!AlVm{ 5A~]Q{hCʃbk+(K =6-Ŏ=8i) F'BnjSA*1)ݐI.(<~50f8I'eύs!?<0sCzM$MH^{OukuJ(9xu}!q{UbahHvͷ8>l^W祚el*4̂ [^ZZ'=CcVwܽj^"04g&`ꖏ;F#/,k9 eh2znϒ^wL ugƈL঱9$Y1!BՇ^}xFdל .Ab![T [g!-8iVO;5} NiddM.[vNjB|Cf&7 ѯJ!/+lu{ l4}8H597B~"۽pǨ'xIlV~'f'}1eP@JP&\xk,u`/'jҍWאȗ%7 Yᡜ%u2;pO7+=SK' |<.1JТۢ][Fp >Ï+ ;C\E^V@;\NE :>duHulV׌3}*8Η}=p'8rXL| ОO?=<41]`h8pW>GL6v^wV)`nQ0~LP߰х4q@{t'l(FgS~ЩGlcT3j۔Ak97z..Ftw:XRP.'ܱkoCie2 $0j,n6/n,XDZᢩȑ+Z#zOqjѩg\,B~ Rq,l'{MhqqEo/AP5^폶f=F˱pÖq` \^|qjJt diV?gQEC|P}aq[vo F,5"p4yR,o чQj}z_z@eh^^+ ޅݲ݇;T-qcyNޟ,S}ŌL,_' l =HZܠc1UmKAUgkyXȨ=y TYy1-bI9f6e| RV}nq{^#? ɭ?/gn\+}lN.輺Z~#0e~4=0z?|i:j2VgmA8o7hYzC+N`Cj1wTB{=ǃPlmGrhIirx\ZřV6O1V?~yF K zt kyNsVp6]OPeaLLЩ9jF~ghKIۃu %,]&~ Uj<7!]Q0\k7QM7C}^خ(9rE3]t%p. ZPfhe;-L^x-[Fo}W_(0M譣  Yz}\ g{dUN@cW]Lt}ѩW*sBVpm TԕZ\6:Z;1F\p(ß\E5Hp+R>ǙhClǥݰ7c]c^%|J߭E{SG,v3dE5*EU)eNFմupm!ԦG`a=RU>kVSS!QJ)4]3MJ+~$jQhjP4(QFѓWw?/c~k>_s=>\L-u86v/BynhmU+|idh:ډq[E7E?S^ȍ~"1u(1XlC';vRe!<9(=LwEEfFx8A۲CY߲9{#uP,2w<0M>&΄Ka=x3WfI[:FBY8 e]^o .ۂ+L{P@֢JrVZq #}ͰW9eRVԄA;$g(2~+kNޘs CEa8o 5|Q(rex3 nai8Sz?4.yb#kMϋC9@ʠ8!9Cq8tp"\y+`U~8C۠u j} `q<.^Gwq  OSow`x#zCj|󋀨p^#n Oap`KwD}{ _̓b\P= QAq<-FH *!6[绠#:P41-ⲉh\t?_14.@w6^w0Isz5Wi0 ׬gʟ=7 Ghz"P gu68b>Ocx~=4u^CiN 9]]aA}C) Zͷt\&'67Q}2s:cQ@& CwG"4 msvW+WU\F%^-TwQn q];#6@} 1x_(pn_֕ɐYJ먏AkmEz\ivI_Ra+_t s-/hLnyR K*=(`/P<$*PF-D@1xsKQD KR -K8)Y.)XﯞϟW|"W(8b! SGWN 5F N}w>KEGf3Yy&khiRNe(]I9S@)FN=5h`Xϡ⛮)-Ze*[\mV*ԞVIen{< 0Qm*uF͂XȍτK]0dT V-`2QQ8Du FپQjr.bnm@ۯQߝ=EsWB.;G똪b_BkQ,#rCet=(}j75v"ji8t;UzsH4FjKf?XH'e-,,QD|.N40pk>̓$+}i=6S w<YЮZ~x i`PvH)[RPsM?ȵH4~m޿c-x}HDP QSx,Fu=5"1].4&8 DCIW4s,IW+B@H-%4fr Yo|6<%cz]6B94'Ĕ<o)(;LyF5F8W Шg&$` VA, ڧ6c5`a,9N4F3WReݚ5$`j^tEV**̟(e7EEG%=t1Io/` TKGgYD8D<2|is 23vQZn:4c5-1-;y;`-ovŹ.evED&c$7 =][[{ !G s\DUr+%ZjMbǗu/q!QjӃMȮ;f r/ 1D<,i [$) 1Ra_j;=eJHڌ'7ZCgxG/NʐN&9 ɷ=BXmi&sl K<=^|1䰯82hINڝ@[̿ESYbV4I"O7+S.pw9mRN\L鲖 3bfoH{raQכ05nɍHʃ[H0_^e7E<>.AXΏnd[%äO6^2R[:k="ZL^;3Lj{V(66SZS =JlNWpm9\:c9ɼYLt%:Dn>ݹLLN} f~ʠSYvS2{ntr2ÖRHtWWdXn,~a4Niϖ?Cg@|ft8(uN i-emgу,SW g٢n0ISXLZsM{EWk5XG#"*u2dg6_L&_ђLN6_&rS!T뿰^vYۜ0g+ UZj|So'UlG C!S_ M}YdsɺIV 1:Ī©+s-jz/-T͝MViȽeq$nĿпIeb+p*"KwBv9{?划Z4j5(N $ ^"3Β-:mˆ?aghbmLsD<^3uIm~]8A0QbKUcɬ_j,{K2`<}p{L8 #^8{\*2**r("KV˒Vќ5fSXTZN!E1_QD9 Kw]ݯ o_x=^?UByvTsGa?\9<꟞nO~r\:c.7іdL{!jGbrRh+jcXk-֤&E@F j9jLlJ\,RSo-i8g՜P)[56eWs[\sy|ڎ~FlIQԀm3(Muwb"h㳷IUJBv?g]H|rf yp=:6@-j#F&s'I*9XsHci8uA!v3fʩqx>$``35`SWIy45pqwH$m\3&swlމ~Fd%}ofI?B, O:өGR$p+mcot>uiMʥb-Y~s[>o<7+E[$Og܉tT:jt3/IT~ 9/)I`ԋZ*:p66Z1k$0\oPnO H*m͈et)ԤpORYJD;$s+[݈^%Q#n3oE.ެUPșgI7ėmTT_f ;\&5)O+L"T^]F{bu<?S%̬d7ǿwF'e5w$xIYlb}}ASR CuNgP6 Tsrm932t'SUl:OOe&Q;)qtA|޻4}:ŽzZjZjZjZjZjZjZjmq甖"O;eEfqK0Ce瑼]lp@xv]- \͸͍kaBJ{`D*9!]`ɬ gtq3:#VT G'/Mjla!`u V-C0Ч$ui-5 x18}"y3q]]Wd,z{?#Ēϔ)[; n=m:FxңPᅕbS`z:b F= Bm=+ l;WAaÀ:絃Z~} jx^e /? ̰B͵P2urGn透]\  Vݫf A%vkb4?WɽVpb1EGYdq~SX鱕lU&S)ow)@f|{ls<s/ygNlZ<6=+гn>^\ON)G FG ^o/!t%zxPO6a }l_͜յ{ Ӟ`j*=DƞkǙ]õʙ`߭*Ě-nA@zMoRu^.[sĝf^96v'lHzl`=#*o[W5iON s{4渘huۣׯ[]-ǟ!#w5~1cS\9 =n\9~` v˽o>X6W-/i7 %єZ`'cyR^=VѤjt=$7> .|i;>8v ]]9S+gGψ.7ʏ(bTm\|\ YZ{nTId`) 'K\M Y aJ7 ra5ِܲ>RWT;|)lxt X0=|.3}+n.n.Dw9 "B.G}ǣ!غ}?ŭK ^Uի7lm_q,Ʌ9yא筜^ׅ}ATXstqnW' '}fX"wI E㼻bKase k90TGk *n^!"'QWV9Sif ٧;A@b)7~DAEMaa鉘alNgfcipb;t<5ڵMK(:Bǎeq^%({6TVYyYE\ ̮k Wɵ#C i:Կv5MWEZ(NǼ遯{e^KzgV4XqnOOk.dz?c@Iπ's3ҎB8:\$Q3Ž7wߚbx5ULͫa.x@['][#'z_m 4wn#Tis/oJحGπ$[!fN ĢT\Sֵg*e'kqzfJVXeE(Hq=XWe G`5q>xm ˵vTG[|X8Lzv(*SG1na 6{+ #GaV+LYhq} uNsbְC.k&n}MT5NfTcfB2',lvkmjJ؜̂V];l N^BO>,h[7߷`_8\kOV7cʶaC Z[Ţ5ֈbD̰=b:Vei}-%qx gE+R*{kz8ttX-˅s)26WΊ(S3&-(쎘3e-S0/?\U0GdZ6W+t;0O׈P;S;r4UX5W_'ܯ" 7!S<:afznDbR_ bwDe^(ܲ5c1t>lOb6+jծamfUet/t]efMFqm`)^a>6  FN~C0Yfy-7af)>k?TV4#Z@"ѭkɬ"ٚD%ت`&-Aaqw)q/ cWPS$@obn$1}Y}1;2bu2:gROGc}ِQicZ*>?@FY ӊ . JxŎ5EE>Ixy6;wY1|OlB(sPLVazgb͇`VLa㶀~m}{OV dƞ>AޣDd(ڍ4@ۉBP0J$2bu!t]G]{B^+lfsj, wRwyETPJQO7ooy5MEfj~K"os挀_lwƙaΦc&&~^33F]J+A5E7IWYcv9Ĝ?Lu=/~e(03.#ɡ|"x{SUolsLq6X/_BF>H5I[RoΜf!l}aͲ♳L:dz0s5f;ijѹDr DMnA? KAzՅ;IfSBlP;-w 2bvl7*ibϙ-TQ>)х!0v}W9KiBRqCbSy%k|&yɝʗw>d1jrSzQ%\[*F_Pʼ@g.y/0v_aܩjr[*_5*z[gE$wS qg^PM e?vJ[[a_/-Rn]qal{+:xLdEN-i}mV15>&i6" >I;6Dw&L;'Ya}E U<*&ya=sஓ%l$O)j}%梙j!4Q;7:@~W(-Q%Y/¢{)L`ٮ?Ujm}PZBhr./h^>&4 =FKUԝ SO_[GlfҳzspvB e!1YTQJZ%&Ѭ:-d!VD ^)˰SoMYFUzSOa2!/ڡ g20]iQe~$?'.GU酳o} 4 g<\.KműmpxXL֛v8FbM'LJ/ LXYGzSNvMyIooBwx`uph22bY$tW%m8w$;B1v$i 'kO}N$kcYW(8R-٢γ /0Qq4YE0ՒlIaoKW* zHZXVҎKf5W$&)3Em8O?aOrp^4:Եcu-QmybkB>&:IMsh&&抹X7O^>c?hQgf%uxIv@WWIx @Md8 gz) }qL;5=ws!쩣ah~b%U"XḾoH7.[?왌. MXL;$]_aIxIֹ3gt1MH -.49sYr'o\8ZԺ<;]pޝ!lڇCZ8*AQf?Af1qA@2 ߔZNrõ}Zv]321FʶG2#O58gߵ<|;lw._)+N6EX[ x+D)~dW?SL,S E1WKVB v+(673a7bT^ @ZCoA\b8N ClL*{>p`2Eo@=BhC>Do]!`-"J-^u]{+n*^ipEcxG, GkXhB=yo"|<}_y˽wX)vՙUf֝^X,yuހcPg,|Z(;ZZffa'lĄY/s E4E T= 9`8|A!_g'N_ѧl"eg52^eb9a*%&LU]{QL{^^%7dv⢋Gb`n]GN\nP~F!MgB3)5z#fBvwY~C̦ŋ#Wp\E~ " \ƭ1)XUpW\8ۣ8{Ùh6wD#{L{u. q}4ULf^㳳K)EᬫITGs~hZ} AEV7p# >6PU,,齴(\ǯ/(נW;;Q ~퉘a!XW\;o3,#: ZijEryIV OP3 ]BX03P$mQe+, .vTeh6BX?,YfhZgV̘\lɺ^|Z.0lx ;SOviIg>e?c [\"61yo ~K >gC1 got̤; +vfً͕:A rUfzv_,Y8_Ԟ ݕL.+Mmd:zZdE^~ǿ`c?I4to+~Q3RW{lAsY; oʵ0c=dn( &P?nt9>z: Mv#( NEa[fwL¾[p#owޓW&g(=`gOSڋ`Chqǣg#(2XRu.yntMCr/ pyhE2Me~,%ĜUL|"tL'\7ң+Z>NZmr\ XT#w'|*2d ϬH^LzfsrM( e6յ}˽\`͆$LdՅwtދ9y3&}36 ?K⊹߻fmA6lMʵ4vE;=vۙUU{<Ҳj $FsL|XICMp`8dtS !Sp85K:{JR٠p|߷ly~]~bג~>M Ri=GV)R?\a͐xO,<zq\OREZu8+=څ_ ]GP1W11se9U6ƸeL UۼŴ;q} €gaH \i3W1޿|Z)}GC}r8O@ܧ7^S@8%e wvd,Y ,?t2R1g6i2]5s䂻H}Ku+OB]"c7!lYNף({ Zؗ /u2d wR;o&V jZriG򹹖(ً%sU d:͢r O9`ecScӵ韅ូ>~ fQvY\eAKl7&"S v\K?7Sf%>4!t;YK{ eAD=|&(~=lmD[3i3ڡqgG~KCH30VsU\ޛ,ӭA^n&b_c ك)ˋg׺ɉIWsm2݈fLz<;zzuA}(,ܕE7UϳkxO!sk/Tɨ6,b@1pK_Ezv^IJ nF/C nQ|t+}&oSǩ ǙsbkRiob3rYKṡ=aX =1 |R=@qgMM,^f]Uy.O8R,+~ϓ,?sY-/ Y:#|nnFҡ/y aɞC-{t-'v=ilRWl8Futt?ĒXީڢ_%)zө 3n-KE(3،X!=Xgv@ J^Hv$4#ex; Yw8EtϾW\ Nh^Ǔk vs7zOhFkJDŽ8۝`aM'v=$_EڱY Il-kw8la1zr̤#Ya[E}Ȟؒfx]3-v^7-ץ#:QwgҮtv^Kq-衆 Mxadk9'͔O$(.Xyy)+z W>!sqgIo o$R>sŗ;x qXOJ{^H2YH5goĎQNyB*ξugv\K꼆I,/Ac8dC9/E`9*![9z?&WCzY̓R& ű.)>">jf;EE`ICa{]P:CzuuI,MIS=mm)Ox"¿¸V#\ù͞KC66)՝l{*CIֲ­Qtsst?Eر5+9r+7eU{~TY>z5*d{,)k  o9s2 /x^!I?qU(w!‡%+!KDs˿'5g eqIUocb<"^K$Hi) Už #R5_מկ`9rEaW T_{sFyU=Yn5Nʉur4 qo@%%Rckŭ3KEǞ\ߎu}yC_"yX݃ q{ܻC|5֐ ~\q$C/&tq}|f帓磊a0![݅`}C.Hw\XnZW/,&q(h%徸uAߛ=O9} U[F V(RW݀;iŸfd>l#eJ""[:{;Um_!¶SEj+ՠJ\F>?s&Ogv1LK|X!;R{xܜ:^m2y7lG9Y9>)ͽtxgܤUf ">+M=q9Rݞg'g'@%9QNJ? %?]o~nKN`B5| &BbyduI[7uMn RBR[XXu.sWmq39Xfmט9ݖ@mJk=KɥQd; =<®:wZ,7Hc_?Di.])~\v۱9/H&)vaMERdl&$޳Oa~(ѷZ3g"սŚ*9?eg3mw}'eLg{w%P;bqe6v9ؼ D01kdٷ ʬ|k_EE%csD)O2|讃><ʻi.{FLw,UNקϵa_hYNHɢdAsm蟼 tǯȐuDK HZ{,$cdD2*X* *7UK2(dusϼyi/Z̈Tcrw۰7vBh/(w>E?{Ng163Vgqd8aT[JJe-Et!sCɇ}SԪ/^t:Ru8pE@SBPBޥ8xћ}*| .F1݊_O@\9'z #%mr} wcIh`N _%w䓬 %iE<ž5U,pV 2>`>'^Лc~LVPkJ$p~&5~m\1wavO٠˘Ct7F5.tvJĊ 7>4 fmTDuFO)I4z,i=bm3௘ ֞8;{i6"eܢ=眆KA[㕇$N,AssWHǴWc~BK QzhdJ2#z=XIYteG67vK",exDR^V?X7hM$EI8WghI-n攽ueßfGI)aתEyTlX(zJC+qGz:X0wQ (5[#gF܍ay7ڝ`)নUzTFDGԞGjz$fvK"8WN뎓{0ܕ\^S [ukWIMZ #EJfT{wb^1y3\5ƻa`ƁѣhŴxAT\#pRd]cyj{*}=uX7|w7N@Vf y{p:*i/^3*|ܞJSDO8ƚ6wWF+>ZgI0%33X }b1'*{RvY+@^ ,("rL)|9L}?^k]8fī"n%C調Y֔=RULBjR3),)P|Z4-ԗhG?GT "$DzjMqm%_?3Dngqyv _܀Rw]J{@~po2Z"/x)w$Kosv%wm _"IPOɹuNά"a{XW]q0eծD䗣ӗ-{s A+Su-<[y si:d:^k5wH/>#sK1PQ3pIi Oà?L$T7´o KahT:OMMo2;5 з\kOF7%ϗ[?5Qd 8bv(9 C۱6C5iQ2\Lfi2LהzUӆ1Dܝ?Ƀ&y4x_#Ϸy_#׼n?>䯿K)~Ⳋ3Qw4:toC;XhM n̑ Kٹb;݁'];26 %-J7 w!77߭{uw8 x >̩ĝoׁT]* &Zmj7-Ӽ@=V #Bĝ mHo -kޫrr drt}rY$TdQaSw2Ο'q~XT禲 L.Ǎ"ǐq9&#[Rہ|wiS;V aA\W&0b0ڊb+uԓ+8nxC:yMz[.2z b`$3 _Vc16xeE{iǿfz2m7o85IjEFT}hF+*7qq(JgtFx7$CzCDrU.yщΪ(^G >~WwN]lY/:KF!ӂ}ҩU82Vm5ic2]p.'1Z3Ur_=[cPU$qkۻo6K`i"o#Ur䗸yKfDV?v3{\ۗT1|IxTàbFk\ >E#gI{26u7p=[LieN TxaYںD\wuGu$H+Gu[{v"?\ ľU/ YcF$ݜbQz~]~E] Xe=uUzb/Mft6'84͙~]k#odz0eq{!osyGe:]uwk?!Es@ܕaM`a.[;p~46l[{%1'uYٶIQwX}cT2 }S tTEG>q0* H,,n*j! "("M@I a".ʄAQTDQ#:/ywR;[u_N~LzPv42y6[hk7[0TBܶ;S>szhsw(w߱ѥ]tX(9D;룎QgAQzöf#zb/̡'JnN2B ģP$'Ŏsd^F%;{;fuhuH[p-|CU-#cbtׄ3cϘ5cZObUwF|H믟fdَka~%kKr;Y{׺َC~cnaoY={6Skڍ#}{žo>Jf}"06]9qwzGhǸY&eJ]o> !-:_uޠ;i`wH5B[}2ɹ:oA_sX7ʀ)Tzu'%EYUߟ+ fsM7o ^/)MB+6nCclݾѝDh@Bjp{ a }dM[;8Cx \anEVy|5w)߉;E/< s 6}#e^粙L ʴ^\IldmЛ(mZ>\}IA:_ ]ԸӇިSžp!dg n5fTD邵FM+/yN]'RN,2cK6d Z5 Yٽ$Qޯcdn{ePB1#ets:Vr9|0)xU1&zfm;h)H5en﷯iz@N/2DZ-dȱjgXI;1GFy̍O7q%j]3{f=kC5.}یmUwG铔='<˿˿S3Zc 7^܇U-V-]@؞jT*?װ*p)+ik2gjD i!TuIr,3$oCX1) ƒ:Ϙ Z;F/q({7W1B'?#~{-y֫LR_MsɎAy.S }V~hŝ {$R6dpE}JQe ]Lcd(>5Cꐟ(ыjp1c~H f9c]t r ȖJX\7Kjɍ=@aImy͝tg?e~<؇ ?< =X^r=(9+\Z]QOqOoyljj`\ݷ_aU* Z({\nJ8gk;[w ,7[xXoi^nPХ]qٞmaArp`aQA{'a9wrx#i 4](uu=bsel֨vv\ɭn[8 iZM3#ʠtFvk8l^ˡN:7lpƪ4@M3ݦ缝ZB%E^͵:Zݜ-Hc%.[hKeD=+{ ֣\=p ۹5(5xB=p g ~_xo:[?|#bݕ/ HxS(W-րDS#c>\_7ppS՚Jg'=D :tn^ہќ9g\݂3,~^ N>>B*s2T{+]*G3EQ͚Hghe&shjgaX>"!պxۜ)3??xg5Iܷ0rX_3}.ҘhW {T{b DžiD pljj߬NWܞȝe%dTY:qŻdtDwԌ x;3gZ 79#9(+wQ962N |WT"+s/ٞ k?rhj;$Ҙ d ӘQdk]B岨&NMr3{ic2Un=ܙu>jK͜k;hK_SKV2d>]F6};+j0ٺ uՍ|n!V=Cߴ͙y?+1>{xs#+qz]^Qѹ,zBw*csd4;Iio2琾` 8g0 tHH&IMY"d1( ;pCIUSvw=W1RUoPѱl]55|M.9|SͷvϩxUA~YRo9>/Aӏy!͜-xX뺩!廆K1waC*9 8m;u5PwF5t79|(L&#_< grIo_L2!]Ǻ~ m9ZbVwL f"!;W_H/Xp,aosp -t*޼Ko뵍x u` h;#1&w4y~{$;|ն@nr8]P/,Er#>_]$z(kB_;ˍs7ZBZYSzqdw]X(ǵmm_ jV rh4ޓ,g8秡^yg@npx 8Us+ȽD~fs)k \D7"א7y^N7C\` {W:Ӷj!o0lX39LG;/ t_(`ٹ&{Zy/lfk&;^_n#^9D|?9#M"߻^l6K6Ұn 빽^;@1܋KnkBك_CnKCQ27*mfM{L kԺ;Ae'XFzBZUGуIχ3<"N; M_$Ⱦ 5k۞9@v߇Fx'SxsoDn__O>[F&O랁k<|x(+.ѫL)[Mz{ǩYmSw9u_z!k}'ATu/NT.O0廃BSȡx_=;aݽu>JYÔc|:Ŕ!鷞)/Nq.o5>;۵5m͸j7'{ޠr}dL;~23>[De?,}"ճ=d 9-Z)AF6pw%}oF(AٙldK`!u׈r0N1jYiYAZlBҚFiy6sn A4HW^G&qFl#l c#PL%NѕDijddn}D+#3ΓCxק}$Au w F=q2zsXֽd;?XwгM*d_kH;mqMGinw  ApPۗp`Bl~0̕~"J|8 cz:wOPFFr#"5r#s#rpj:E c7j$}7߹s;wĴNGFVgB&9Ƚymߥv ;Ķ %?3ӓ2g0Ū _E<ÑClu? Pۜ0j̶ߛQyYmsPbjvWݑALT.׽Ҹk!a{ÚgpKX91.\1Xɼc{P ɚ6_՝mM9}\nNP'mL>"]l m8ZŒ;MkӸOv9xܝ;rx];pADzrk1''hcNFj?)}/"# _k3>HݖgEl{K RCa#jB5G]Mr9O({b =s1RW_^7wTcU텙P_3N9GqxMB}ݎwauë̻_I-U%R;jHk(+ ܻA5sg?:ʄA>DŽ$ װ{ w ]Jr vQb}J\w[ke5|jTK~߷˼εCwIF9(\^V,szEɥ1]ԶRﱀKl_߈CBKKU`wU={^VC'p9{n^W*_ϲJzuz9{gt4>7>Udz_ʥ; U.PڦDzd:9;wG׶E &HQWKZ8-vݣHGGORCBy۫6@/6 CJ0\;bfZx*\!vܳ/_s4h IRu5)N}p(׶E!=#q<ʳspO}-y ^{YЪfz@R'~-wHC:Y9.yyj_E" 2L>[9Q#{3qtihz,iga]s1ܑ33]gTU׶>1(h4Xo5&h;PcDE)5*XgbbQ쨑Dci;׆@/o>Ɯk\k}{3 bf#h'bxu6bM<_2 >&Vy=g`kVv=Dm@w]ɱ`nwv>|5jDjԔ)@q~0"9Q :Olq\)P$l[׮,T* 3'3Si]>L bXu6{ L >"fXZ)f3Gڹsc>-rm%@J[Mgy$kb؅1eߟK^Qv%}* @KMC=Ƣ`Խm`Òn%}gckz 6`f=hKRϋLT}Jh>Gۂz8Bi_=JU_6%˅?w|g"rV(qIg8OYJ /Jglg $Yhdq.|Δ>Kߴ!go;NaC(a8Vl[%!87GxjTLB.O>%+cD?.ڔܣoo.P@j KS]/ڔg%z1x2%r _Z mFVB4N5r;S|%B&;cv)ߝX{1%CڴUR?.bߝRsrcž#t)elNw a$36t>F'"гFI--9ߕtMەG0AVyHއP]nQi][-_r!V˷WZ(PR7?™X־}ESm@%ľ=^WDK*pZCOk-ѿuX}/:^1☠2c^v15AiUWEݘ-ǔҴn?QEgJkQyһ/H.S OVZ[ֿFj~z?hԟA%ui}|/rʥtǦLpZy>>n܇b֔,-vc߮vURb*SRJY>*u=zIQtǣ+)k_g3Jt71e -x Cf :B4pJ.}AŔԮ4qQ%($zpE=ai<$(v.v!<}f B:R ;֥3PL15K}zvamMgAF\d$A Z]ih91ig dM(,LrRl/&)8ZånSg|τU6yd/g* $^WA Lݶy*WHY՝MW<+}kO]aKyvڵq.J/X: z cmC>kBziNh{[JmGZnU[u3ؖ}^HToׄ_jmčJ-<-~"|xAY"[҇VeۯMשg8<􉴬ȢZ偳e%Қ,bЖ!ݬ̛Etݸ').kv}Io-y_^SY=>* NfJK27glL/_)8 Qѕ2C(7}Gh{0$)o^ʮz (ҋa{Κ@i_9J1ro9om&vzǛuۼt[RUTj77&#Z O`>])76NC =H`ܒ˹< E Vezxl  \+ۨa2#AS~QJ`>u0@c -ev=ضF8cZV`>Ο~E_ Xn3*~ Ɠ_B;%js'Νs ?X 3U87!0.|zcoF,JۄTpY ]T qLNYG߃@ hXV{m}~<^@w[v*q֭01,DV8o^>z25Ś{TMk` Ui|f̾}O7LG;B;rt|ު0Yxn#,| șT9 jο̜'é0|Q0uy ![b=|^rZ.\"ѳZ\A;y8-N5FCt7y@7XcCi4ִʇcp>Spa!!=o33FMY=lϡ[aWZm7yYXIQd6z@ nw8! 6;g{ N&kDy,a t_h.h. 6Bc\oT޵i:NuIQp7zvW hT12}DD}G.@n7Uu S\(,7GR\8.-ar-un1|1yX<`B#>9 s^N)}SQh.=~, c'Ox B9W|Mc5&k3nKr40h][56eҋd9V= m yPe QW( K¡ګ'`=//Ozu\wԗkQ~H㚶)6i\A7=vors6 Wu1yCsogCjmB'S3C+[C)!!rdkzW/AO~ I8/\K"_S(';u Ƈ_+_w"(_ҳ~FpkZu.j!w\GE^x~j8yD ,5uln'ᩭ^#_9d3TNtM'C5v| yU z Ca=^ ȶhY=!Vk3_(X^"HAajFm+s kPGy ,wg)9aLf\TwNY0E`;_c86qLo ?ּ)އmOuf/y.Z=ol4,՟JYsaZq??0x8_Ma9:EV}P;%΁eY}h8|?\5k=t`x@_>=ɂ@9sr@_y< y:l<֢jué~r89pLFl:5;峺\pPt5/%n$LfZ=0 (ES| fbJ*q?j>sRQREKuRGͬFs{ĦU*X>;}\p-b 릸vdUvG혜퐭J&bGú;ZBxMRadڭ Wss툱]$mǬ'կe]xؔɘ3ֽt[w0wU-N93ՎEi^|l^;!vܥQό +QO)cho}7zu.ж!+onrYkE;r5vӨ7ݦ1Ɖ]:;n"!&9|gGPedžl4ϧnZ5p\nG.9jGnqEdɮav+C%G\vv,jӳ+SCM֎"&-,GNf7jIvIl'̳6X1'{nn] u_[ Cm7ˑ`߰Z=8cn>#ȥRc^=9yլv{g!>K q Y|eOF iǹt'Ut_/Q/Zw m.>D-(~]k^Mxz_ߟSIUKrpXz];~0|@N_gOG밁%p ss_qrjЯ CƞW֍_'([ZtKi Zk_=kRHw^MXNc]#9_gbI>M܇42\}\Q}c{|9&oG-`R|=|>5qlU^dyˠeڛ!u:)JȒx_|>s%7VE3HVƽ"U 7Ɉ7=H/o=Zp5eZ|C){7U|rwMolwy^z->YYdڲj/"7!ZūJjrlS%&xĞ 6hPٶi7}zM}TmTY7z}dK"(PG.X%:{/U~{϶p/meе3/:g`WŃ+Z܏ZeM3R!br$81 >*8z۩=Ɋװ؆R{=]لG`gy"4%->?җgć#} ~gĶT_ ;r#^P|9s G٦_r~v:JwOtaYB+('LE [BP.챊KU,h<+*'tf=u@g~Y6OF0 'vrkgض5b C>oj<_=(nǏFj_ޚj~? u\ n.tjP3rO|Vo,ke)xS7xj6aҡY9=[` skGOc@an\7ͳx_5q\s;rRc.^:"dǵ/ݚױ.=2:ű3["vx5O|V^˕T]ux}'M_ٹInYx~έ}9Íf.wvqԘ}R&B~̱P>{4yP< ; rYҝ nʩ*@9zW'm5{39}^(Rks3cmN|Bn~.,.5rl`S"UoLCTT)CצӖ}uS'ʈ,#5G&9۴sI)=+)uιX'~z{5}^<-njy9C64ض9a:|͟AN (x0W`/yLt%JC^{F [s/Y_۬cudʃ!jd>z4#Y? G?|de%t_8#+!_ߕz?ggc̤Mvdιf_:=TO(4jqOe(rۨN]>y;=G55s5Pl'k߭\!𦞭Ŀ>DbZ ـ52=U٠ZNVXϩl!yg!/ـ[Jʭ~oq]kôqA~#K{[TE RJ1DoG+3u6vJoP7yKN(@4)6)l+6}*GǭwңGE?<б |' 0h4ޙ(g| k>8?awpil\K/þqo-9%r,*zΞQd<6m K<>xFӊoQ1S<όT|U.cnbVzy8 t <82LSS _@@yyFдSi!TRG|cmK6F|6zMWCs" etwfK+WPi\ۧԶeA|;7謮=ȳz\s:]g[c;>7XrXC y*+3z9~1TcxL?re,3v/G/O:&17x z-$m3 dF)! |&_&8)X,5@->R]x=Wr6he1r'r!ߖ{mk=^?X7멶LyNޟ*~]~1 x6ko3Z8d zl'/ ݵgY+y_57#1~ Hm?+[1Ej|Eۍ'3SN󲺗y oslܗBw^WdS9ۑ+)]f`ma#|tɼIo[m>!za<Е7Տ3[GbΌN9Ɲ\8*\Bl؋%yLC`OP9Nbҵ.za&-V}ll7Vq~ 6~vU.4*lW`ǒ{! 9T1Ήl/;Qz;u=}8c~OEI-X dT8\h\.|0\%@WɈ~2;ySٷ nѽS= [f& 2 )SHff"W~*4؏ZgvV5}/#}e.jW` u:|y%ʞX,7eV}Ro:B-0d N;{ǽY9,+88)Zo;ȱm_'\Z8q]TZ0z%D*u/*q%{`]Qr WyeRetm,y47artw"ZEКI4ԢYtAZLCSiMwP[R4V4N~΋D=цnx|֣[:;x*vBw>BR-SG\E`KNx\vCle.g~xX<:tʟ 2}6ؚ &"Oy:ϑv+&gKKӤCs9]iW󑇼ٓiCe< aBZKa$aFI@쫅; ;l`s9r#wOyډZi%#ǃ ZLn*DK.X):,e__}*^,{1x.E^^b^}ۢB4ʹMÞ@ ͂,~vҌw7Pf>K_ko"MY7ZRKmb;!G޸8WA ^m{8FJ,+w!s}y!RO3|'t[nKׅrMt~ǃzN;QÔkU=k)s f\ѤwOm]<;h2RUWoSl~Qs zLcINc䢦mm:G_\c,c k?J*]fYS1*9xSӥJjo*l%eӖ+S'1όԹr2P}Y>YWO3zJ< ZafU;èi݆W5i脮q:Pgɯy`u6{.ӱLGx+G:TtD㷧kyv8[>vd_[5o&ߕ kkury'}65*Wu'-?Nl4 _g<vmYͦ|ZV;x:4>cV_:~<1]s;??gbbH<y.VVx~ΰ`G%^6f)uR:r ˎ/Wwv.QaIIҦ;jt5+ߗˇps1vCGxM`sV*x7h<:Phç00[Ic+&FVޝ{>O_u{gx} SK9LQShU<]F׵*;NPTѵIAJSԚ(|:nCQ2quGZ5tJ0mϋv;x߸#k Q5Ct ]AҵI岣:UM)Ov8JTtnڅŬPЦh5D(k(:uQ؊w>j5-u#}'s~ UNc)r,) O;ʫ;|aXgS)=FN"=ze2B/Xn&'{ v)^l›Sw< êX,cBl9#b_l Me.8gOB19w )#FÉiP Yh ƙHHwǨ qb$1DoC._ѻ|Ͳ #;$BzP#;vm6\ƒ}XQ҃3AȲZ4Za1vH&!~ hV? ljD 1q_'Ģ*6ۢ-vAt8DKS(\9 v]{UuS!|J =(΃xnZL!|-j*<&3%P[1EPx%N8{9pM((A[ijWՀU} s |\jE(Z(;R cG qn=|w"݈H7F]Uj1Ab8q8WE tp4M,_ U(57G Ge gNZ;a_#x{4Drf\ |T-#? % _JvsH9H);4? &HzIP1|GQV1 C0d סlqDeԅR|lZT(R$Cjj7"cWe/PxU w%ms2%nHu_: \_ɘ2һ p c5>#7WҨ#_D]P;u=6ȴ QTJ+EBpGf(pH;gو- 7J 3C كH5D6pK,̞!rf=rF/AޯH1Flw9(ǣe q!=)ærZ|Dd9 6s1$AH{"ca$#K Q(K@H8luS1r@H-h _ȱ㑷"e!m?Ϫiʛ0a8;P!/A^`"3{Og!<2 D3q_fD$ݺ#P1N!E{ԟYߣt<*d_ ~Ѵn@ b򸘘mfz oƒΨ)B¾ޙl0}{NTNw"rUkoo>8C7C0 +A`Aܢ;d,Dm%dY4<cAOmNC:\Tw{o:!k'C<1)#hl#jW"5ŏ k݈3H]b}n6E~TGEZ:^F}75O؇1*3B7>>@ aQun;V ]FB Β!k}?d\?.C8o$B䔌GnRl GQ]2!w32E >@P -E*Q|jE#P6/>Bn w@P^+!^6 ś|a:2&V gTO$N= YF-B֝CJO~ܐI>JQR8'/!.O,.=x(lijľ@b29KސԢp7H=v%"+n'KEd $ q~:+bBQ4 t r^C6u S) hGFT62w9 P 5N{/n%DzkFC)H#~vV:!.ڈ"Pk;E#bti!gBĸ վTH!b/R(q*FI ΑȦ Pq7<MdCl3zP'q2㽈buC"|\!x)1~߄opH75+ {nbj># I{Qg;X Qx#HM샼 co΂ 2 O=L,؇aPsiVqhg&zH3 y[Co~hv:GE\!!s뎧I(dDRQQ׫NUB"{{qm^..mi禴^hJ{y>T'w𴗏'K/h#wS873S 5_!vѲ5p]2W+D\x x.VÃB w @ ֮ G}@p'*|nIn?WOktLu9y*'A%4/4cq28p-_ IC!_vZCbaTx^pA x:w,q@4d1:n J7\mB_8һvr x-v&|rz/^(ןl}Sy 5PptUmgV`~LЅ!ap+(  Z۠pTvU(Շa }'f@]U_8<l;[ADYr!.|y=iCG8u-ApbowhJ>w-݃io GՆH.-i!W=g`:ĎΕa<{U?AF.0CM>!9̛{O2H{GBT7O87@||Gηg!& V!$  pW$\ ™p(S9>_Aكp|".òae0( @Xx|k?ݕ/O͐uI 9sD@ F~(q9 G/_@۫b ԵOcv:OG 2nփ!j?xo?o_Y 3)X' C@ˁ:}`rYw@ ӭ6 m-S@|!O۟QH|b~n\0ܔېjF!qs`_`h<'"Ab.ރb&Bݻ٠:=i$<:; Ը.a-, YMؠ+Viy }8- ]0US1 W` '=H \} ,&b_k.)Ks|Ά{ ;Vdr=؆22`=sLwCz s82Ӄ*2?JȺn tB<37@Ip3T\K [ !.d `G9GnIp6$;êui jkt uJXY7ym(;YL4U@1r10 <}I)m'm}:J2a`+Aޓ`aAk;L: e2.XyOI=y)s; f9;~BmPPߡ~`# `+)_[aC# y\) c@ܔί-f2e3j+ue@ U9fC 4TAp7wCA<%l0CD"dONXuKz ?f9`ff=@ o < kx3Bx 䰬_[/H| +`m86">>sMD[~]( p:oLoW9X9e`B$ a/?qj5xZ+b_t']H5\1B)ps9h^>Z=!9n#W' bԾ:_;Є?8_; Â@7?p:tE~p 6J\ns΃uJUJy1AaܰSPB6#̹kn\f78o^w@n|zzyG~!̙?bZ[X%^k ΍}GAUP5B͂]Fiu6l`sTB4!) { ӆ?zF=#H>>Y+GwgnM{s ,΂:7+*<pr9L{-b7 5 @0<} )Am8Jp>&Bޝ~XoekLW~s%xaPzEO#rq_u~n׋HZ8x?@^MXssa<Q n~st{,_(@eHl\~<\:fx zC]uQ0 5g }ZrVͷ`x+Z`bqw~%L!O)Wsnq^x8$zǴSO vpM #B5ht>W@=2>y/!1 BS_W y}5l`7hv[ U鄭ߗA 5$\#GA{_vOjS!6ws;4u*n/ f1S) ?o!CbaYsr#@dznҁ*pPz B>y*6% oʄOie2ROจPwhO? =7^IptsZbzB'kڋ;a0n`DއSLO͂K l˚;BQ8p-|Op6k($A_diZ[]A "aH[|caeT! ĴK1H;}!t,1'ζwS n#A' H PTI dPat&/6/WB4pDز5r aGP.l*^  Nȃ-P1:&B[2®["H |Bl9 |0 ;ay >[r{-^90'" @+Ux ^Z[KVԄ'W;jy #.waWwI/߅ k u|-4Oa?xR>9Ϳ`PT/`0@($8dzC a|4az q==! +S!dXX1[/N1JF\YPPfrIa ̑ނq%!%}@Y~&`;@_(_e}9ܷ:$Ď`H UMT–~W@K -NonAWb FPn}Bؿ/L2bX8 ğ 93;A:GHVDNP> ~VUZP aH>j8 'a.ܓR ;K\^O_Ma-=pvcrC6_)aSZCZ;0n^ OcBPt)96sa4Pѐ)ׇ ' 4@p '^@w,@܌}0NUewz\\_tnOJ ^8][&KX Nnf`67䃧IS!7Ν Xwjs äCCbE!\^|+ykAxB7c~? /{ORXx}%n ^MvDg>?@k1%6Clp z cM'pŸtA#oŸv8YT~\<kr t[8̶ĸC+M܄֢@~? g8Q$ȲpY%f 80+`G_G܈mP6Zw뚷YDUõGg8N[` 'k@ -Si W\n>ik"$+\?pt!4,=;VS(ul a^ͅW:Z3\`uo @~ ~`a}#̎IS W{<: r3kF^׀{: pI>P j`'- /èG_!c1D@XO2M(Dnտ( 4…e:s_ݐ؟|\Mte/ '(~<80? J A}4ރN;c7d^9= ˁ5uaC>u  l{+pDOWߐ 5ͅ v1b BI5=+>'fh/5MoMp-o8=75pd.EH\>4=5AA~Soa $YAs=/:uȜ, ߅ï$.OȻCc5= pkFuvV솽QKAL A5Ok;Oa8(pB)_pK1aǗ_wA'|:v9Cr4ظ^ Rqv? Zp0 7.H\…_x3 :BrK ;g΂ek?$ -dg߆ى3!]с+Ӡx:8aa뱩 #Pbi(q. wX8!]x΄6@I6}&'#p!2oqqs~K3Wgֺ2w'CqNˡ#dn¨]XrSg |*> Aɨ6ݦ~pRwrx@2zs!yT;l-BJKuՀ 34Cx>TEhjd9\zm d[`U0We#X^I {pqX-h0lj]7Ѭ`?xVYA5Ⱦ--=`0=r9"RԶ3f:l,z?q'v/(+7H(6c_.AsX\ֻ* Ǫ@FHAɣKk5piPVu'@ xZvdupx3 //(zd?kx5Y9JaX.KgArano]Ap) B mGI 6gOJ YP?xlZUoTB8Տ^wPsj?v@9;!|BΦ"a+| H@#  FS3?*>y_rj+H Tljw۸9o!7X 2ԟb 8Mc9 ')u~ȹV<щPv[=ǃ܂!,CTná^Upbsxg=w@2u8n;Hr;^{4T{ÜP3Jk!w%ſGespj>$FB.o(\= nBX8h"/[ $'}J| AV L ՆǂTwUvD:HjEaV88/Ws9.Ck!k}'ǯs~N( 4nlj`k\/$UC݌ BPrP28F?K; 9YU!@|>0gf(M )8,q+34deC\,2zAyh . 9e;"v,p;k@޶3aBܗp`~L2cp{#DŽCd>[yȸyg32! 5@É'p_ȵp#!Z ‘Q#/{[r~hU x;niwUr}uxΆ;pd ||Mp?g ݷul&t.Mapy=)lRCfC'pc4g)Kζyt]x~݅+f2%Qp/V=ҡ51/Gjۛ-!W̅ж/XOË0PU,\Qp*: Osoz<w*?㯕pczxb$&go8l0 tXj|n\S~Ό<;x&?y}iI TH s2Ď /ڿz^IvJ˨$'|ŚTc"]*xM$Q.%qTb@-=If,;S %${6R.]JfN$5@w&o'`u ^$]DRHH"=$@~EB -GEeTx: ӿQAt*DnT4IV;*//튦5SH˨"~TYsC{";֒1ym$ L<*:2ƛ* ILVSE6*BIBd巨be-稼"wrQyS?mV|*3*UޥGT&0򉟹9H6m6ɼHw5늨@PusrZ*GIT1yIa;MCT6eWMM@y=NPϝroEQyTPKy.qFyv}' ʺ ?yL=ͣg|*Ԯ싋),RB?1֙ SfNy&SxS^G_ByVڔ7I)O@|(r (r[WR^LsEycSn+n@W/}r짼ZS׃r>bK ]I\ wʙJYӉ/(GQ g."a/OH8efQ)eP^6 lt)g tvTHeR.,,e* eoN/eMeէ)(Š)O8CY[kSnj/SJ*K$ns Io*D#~>2;݈23{@:(Eߟ(K$ޥ~;?H۔2w'IJ@_!2rRDs=I)ce)).~f(o^ʳM_+L[aOG(;yMYс} );z7e@ǗR]u$(;G9I:gp S.vPbՃG(e/_@YI$!a0XH/Pո.|(DATՓ j a(?]rw%SmMʹA;(e&Sf /=ڧrGRnC?+کHRBQ EHtk/n%q-TgPF*2MNRQwʽcFy3v*XQ@!NI#ʂ;doW-X*B|BݿTIt [*EY]fa5^ҦTtrK -9|B!7G/*][ӵIqΖJ? !TrNcFTZE4u'AeSETj:Ja*9{J7=C-j$-_@$]oF%*J{tv_*I%S9)@8LҌ.|RRϓn `H<.h]&6Sܗ[G&TI/ .R.L+]dӿPɎ]ؾ+I6wܠU;.S]=d+"jPھT=֒hRPqsz`KUoR=U O_jg?J.+8Od#;EsVl rA ;(>ԝhskٿVqb%T]?LQdvieR-[z< ǟؚxoMם ֖L-u[24I8?:<&]TJu +dR\|PVcݰ7e~).vT ^ذǪż^adfq@1"Fx\nV,AkFvdFvAl-&\la=bfXaZ+;#Vq{bl0q?o\J7*'7XJv%lb6;܁n;FGcmb}`[쫪x] ٙ y5; HQz&e~\c\ ;re|>2VL@cw‰Fp:DINY6g&Z\h6 {fOt}K;LqӸxd".Ҋ+{"׎nxܷ'Wעf\w ,Upk qzރqpEMxEO4s.|7^o00CapT Mwv#f<7|_ 7/z>Cbt0n^7<1\kKpۧ,يMΡɓ軯 +=sPq}>Wo鋸cx=x9u>m3` z߂+#9_L\' =UqTe"K%7Dv~uǡ22~1|n߆ ed[.ap|_ V-[6c2n"pPC~] dWn`mbܾ;n=q"cWaPgc ~K۟}0%-aR&̾_>`B`r=ńE>&aJ1LĤg/Iƌq"OĬ9ʟWk1-ya(v3OLs;c(  7`XaJ GI7,^ E/bA( ݍvטxZT&`A-LJBn(c^t>i:Lu0oU:6 ?s#f?(샟\Z9̪\MQ3oGuٙ7xT1'$Ŭ1?҉LX>ì}B^9 SQ$s0#h7fZb:3ӧ4bjQp ȟQƍǬ13b^ ? CJp?2ya>s%XyKf`ɷ2,:7=6a鰟X,Dz\Uk l XRͱ8-<%XKPK.u)}"RXRegJ6b)XۄX2ܱn,xsEv ֢xB,"Dw, E6Xw( KbXfu.yhP2r lҥDb9oC1uw3(B E8^`ɀ]HԖEXK'r{]"qt,?wӫ3.X`\=w鉘4 gbXpmYa+thW_FJCq5qc+X`ލX,7Afca%̽=b.S̫rļm?07!wŽPwȧ]럜nC,1?EW_9(jŴe\o\ބ;P9 SaFu/4C~. c0bL=_ôEn_$`r=LS mb]IT1-|n>u0iuL]IF0e &0a&30Aaq^0K&>9 "3cd11+aLE%܉ӳ1Fg*&|xwLØ)7]|\1nƌ9_r+X~ vOF_u1f Fي/`O>Ʃ4c"wn0^]r{aFݜqKws6;vw:}cn-jӥ_#F0F:}^cԼR cSƝ31 _akNq7`c/ ן٥C ULŠ{RS.\q)|=BDzz)Mk\sժp~ \0%joǥӖpϫѽ}..PWp_RW5sXq.WQt]/̸+p`Zsùp1 : YC8φnpZm٭TsL܉gp{ty-9qtXoGW sYCמ5msy8jn8*ۇӫtձ !8{=[8n-䩣mڅ~M9/p7 RYt8'7DqKgupҘN"^U8It)fpJS/f~ 'nSLpFht]ӗE78mN$N7yӋyE)NE&.ߕ]FhഒfOC⤂]H=eH8S\^BGtoljZ8iQ:08a8Zv‘8F==8~LZ2y):GzwH{*G<F8jCԟ#[/Z @{  f~C{[/Y5ZVpT 8jfU{'!B> 1'UGqbY NL fteװs6:;t-t|3_ErsR-FGw!m\u̽ǍO1j> 4±Yh)Zű/s3A8N2-Fz(qZ[a]>CZhDG5h>cZX2N_טŠ18zgS+G&y8Gc6;)<GD+'O\m}YZ俱ŗXnF}pR%lc*1 :8"^GقAhH!"MZeUiőFp N~>u}0MhcYspR3-5 9.nD]0yFczaW=p4mƁIhda&6A48 Cl͝4x5N&j/}P[p 5G>*j~6ޢk@zqiB!mv\6#if7Gs2ud4 xw&)Sp8g>\p C&~f%jFNújAM8s0 MV^scD{0a_!] ZAƨ8 b7/Q /simvo7X {6dB ؝J;jM)8 p&ꅛ^9_32ր_,T/TB سOF5T8CF8>a59k? p kpm~eՄ_s1., 4YF/`a|iw$%W 8t<4٣834+FwfϹyhA-hUMfPGR0Z<->őa4t\uG.1ᐐ$Zд?-k8&'Wy8oy<.Ozsz{w3./[۹} WCw9oIB$eܨ!kU0l?M}QY,pۚ ].i&}ɖo5jƴq,uagx~}Ll9)[9=%-()GNa\EnLYbnθ8^k5?9_?i%UCùK1<&k 0*FcHY ~ӌ!Nؠ >z&nL>nqc[ n ĕW z/>5Kp[Bfh55JBLJ.~WF1X; ׹C~wIt7s:bЅmUOG;ơm '\ &q0 g pZorFn0|gLuW[(|{0sSQHjי}V3O2ә CˆLɪFz0SSt<1%yLt=b,3u54k}f*60)3LdYɄc5m20~'3L-b/cqmVfdf֞LɌ*ä̠7.[:-yz'?=΋H'<ț([3 ܠTǝN6g`1޾IGx:yOV$^\]?eT;'wbvYpSeڼxkyB'=>x?ĩzʛF(8 ?zHNo68o': W=xöe8z  ƅ6\Xv3x&*!p\x1i2aŴ% lg¤A4Mq!q">6.R}9U[;B!(Q:.$&Jlxc9s{ng'?g}Գw/*T6hq6(͆5lfeq&lz&b[frf?mXllD;67V`ɖL?V俀M9&%_dl vK+vuK6,65]4$NuX? d,?)<6Y&?Ǻ)9 ackـ-}.nMJ6*2g;v[,c J'{-sۼt{8Z8AJ엑})]fWzpyβ JUvsR7O3}nTٱOߙUx~8P¶U.W- W|؍P%Bǫj}.~ ׏l۔w쏤JgK'zT:&*u|*ZoWAKSBJskJJukc^+*N+1J˧+cQd)mgP:+\r qYv.+mT:jURrsC9@7ϞaSY$6|y!;Uor{tov`/;+;;vb>QKV~83/)Mn^9dQ p#/NJ[p,aj̳o=Cc[? 8L!g,u_EkE 5<=A:a94p wx=Mi4'Wٲd]iLY4Ww-;?B&oA?[bNݿ). NiC8PA 8VQeK_*&q/3"ZMFQ NU(gM?*LN{$D}3埶xA*p"٧+TwIVS]"i]c1*T-_7T:t΁KD$ѹEŚݺ/IBI#v} -9$㩸O_*3]JC*oשBd\ U֕R,uOyQT4^6u+g-* ٣TqJI]\;.9GLFS m'Y56O%dI }C#Q!?oIbX* $;|;*}L5$L'Ya+.%vk/ҠQ ^5Jg]qio$܌dl>xl'*xJ)r9%$;*.#ٹ=:Fl|_Ic¼7U,PN*?ۍ̿/dXd}ܶ AkItɌ{c8_o#qk6hJ+˿o>ITý]&ѽI$Dk?ZcW Ifo$=2D~Ho6J(*ZN"\ԟ$/c zLDoD%$/rH[:IڇJPi? IӒJ{%a$UP$L{m {ATrmL"T1G5\*\*yyHrd+!4|FF$9oQ']f *I')$7I,_gTd1s2D_n Ix0E I4/,RTBөn*CEK00J\L |>.O.o$Ar !XoHU]EU,URTy%UiT-ΧczT%T]CkQ(ѢvNMՉT}$O껏=A5S͂T3§M?fʡTcƭu<WnXEյT]FڭT>SUEZeHU}2Ul7J"yC$h7ɓOsGOoNr%J;e5G*R(Wn:L5T1+ru\?*QeTў<%Uܩa\ET19Q'H6oIVqM\<4LqnPٯT;}z*}YjTV@*}5ʧ,T^YPcTDe%T6ߨ|#*wprT>'^R49LқVTz:⩨Ay=<ԥʿNM?$Q^} GX+vK!͔ݳD?Sƒ TԐN9Ž)" J (DRZH82Ρ'W %у*I}h& )ۻ?CEwcn:EWR I2HbkSJ9jRiU*l҉wI+Oa$19Pi/xwtDy)i>ee) '!Pvmv؋r)w|rP; W}e)a`6񍊉ٙ.[Q~gL8GTJ]R'Zц=c@>bRen$adekMƔ3䑴{82JvSH8?eĴJM#(͇2Ei$`0:MiW)y$JuCcQ1PiJnVRJ4RxjC)S)鋒Rœ(mMw /v.F HB3/Ii)_ }0 >u'%mp6UJrۑRFOJ_^Cɺ)58Q<]#onu"e|GɷFR\r)|eSt#~NAJV֧ޣ(FDBĔDS GJO<=r~ \Ӕii@i.ϴ7\}E(go!e6;q9)&aPۜ~)G%MdkB9JN6CoSm奭|׃{>;P>O9<8P~Cy}('kW?r(0E< rS/[r}'RhM\=ܓrONܤTr7=+) ) E)9 FSւ%$a|!!o1kQ/eOBh({e)ˠ7RfK;eYnpZ׀2cD`^N q$02ͮPf*e&y&=) mo62,Q75J%zyŢ|1iM:I9$NTATTO/g;HdDNBY2NYu)A#A+JI^3)f$澤y9R?2(CND{{PZ{Ord)3 (Ms w)sl)e[OšP*N9$trU8]PE8"G82LS<C/R&Π){U*e.Lk)}DJFBʺwSFl/NٔlJ՛)cdpOVzB\ӓ)"*L}Hs?M_(;ʋzYJʝV_kN\?Lٗ:|2\OF.CzpY8M8)w~}\suATh7$g+*s V#*l?Gy[)wvuէ >Q+WJI2t 8S)Q$GESD߰ WQTd! QT0.ELaTxcqIy$@AG/t&S# Tr$RG*YL%9jXFq$J%Gܩdp؟pkoL%RɥWT"Τ+ޕJTQ&\t{+؊`'f8J^I$>[KH: 4*#IvI.6RT|˘瞒&8s9885ɜJ*TygsdG7֍$uk"P*03$P**o$]Iw~_Tp%J= T8|QuP*q׍OgIw׳T~X/gQٽAN$[d 9\Ia$05TO&T$*TyfUNO$%i,בE*؇a/8e IGU9KUPՈ!Ty>g_ yp's*U.MT2/jFn<_9.!y<яՓj{L y9L@UTڃ*}vRMߜBPEWEP}$Q OY{eJbU}V5R`?-Znl'4V7ye' ZȜ>\s?Ц)*mx@ _ao}RfR~7=uТ\;9nGQ8-־4W_S+><{kuFR5@3|_Gċ'49iDh<_enX#3f4J^hQ''TÞXPw#<~^-W /gnRSnR١\uma/QϝLV*(WU l+3(3v/T (+# V(^5VF:)gׅ*G\LP,{gfq=X%S|Qeofln5vǔ\sub{:g6~uy]:uAfzd`'}cm[ ֮*fx-")m|EPʞY?_vtfkMEl _}fk#8`7 S>Q+Q]9[iPvs݇}G+U7b/YcwOQ;?͕RjLRѪT-ege>TjoOdؘӊ)J4 *e~d<;^<1O(n^cG={<4\8¸(9[)L3x6-Fh0ƍ8Ld,Xx-d3lg b~bb*f2ט%̹ۘj~.7ȯ̑= E5|7_fg/sUώQiM;Qk>t;|-f}Eԑ>~~2_~]o:o*JI^`Ŀs}w QԪ3E]/4t-zSaeס<#7u[p`1.g>sȓ#O%C?atQcP:>G-~ _SĩC}qƥ86g8s t: Nk2mv-x.qM3ViI8&N)3)Epʨ=8Nv/k?0K4IKBބa!FPF" Fy/8ΠSVtw㤣*tq,ttI^?Ю# j+.`ڦmΌFѮ7Ю;t̺n8=nNLũ/m?g'̴M8[QႤgp6. oqBs=LYJs~͝7B[, 6U=]&ԕ^艫{4ObzMF/^q5s=N ÕkѳZ@\>)5[>q Rqsܨ[*-p6n}mO0|wn/;bu|m}u.G~i C N~v?ފ1}\Li1u&vƤ?1iƙ-3L-)s1e$LN /1ioLJ2ċ͘0/1F;Ta=~#cԠ% i9wކ1{bc è0| Tbx>|CC1n!Mml [W1gwܤӌV-a6 No!]M^҈q;1f0&M6ä:5J>a< |W1xLˢ` lQ:\ zaօFRDM* D=(±u,fZYc9f`f̎ zp!f3Ŭ(Y1;Y?P8 ;Q*{Y; ׌Fae- Ba;dfk-R 3W`fE/95g9@_C( ߠ@#7LC~kȟ|PLolD>'c)##_Lo-(}^i =61ܼ1`* 7azO`z%b{ƘEL0=e1]˧WLo@qB~yW5!*_G'gX#? ]A~qc6 f/DU 2g2=9 MQqk=4 bHOd{`e ZX̘\7Q(ۂ}KfEN`p52C2>`[[X#.Ӛ0mLde%Tc?LDw7SbmBMv OBh F~Gw_i-[1X&a/;LgbjL Lh؆ _aB&`±^w 㯜O1aL2 reĄꉘ|*&Z9uM1t`Ba^LP?ῂ14Yal 땁pn];C1m , 0t +F_Lͦ84  i h*?=p#W~Sp>n|^y  7, f:B{!9}ֿG3zA=>o'cxGtG#wDSkj>Ǘ;4C-9>7O[ "-fKec!Feڈ޺]>םޕl9czwAoB7EoǛd z}WGs;}Ao!z۟Dok'7zw}z@UgRWz'`ZsF3~ZBh`։+~ǹGCѺrj;-G BgbU5ZxUխp8t4L@OPwVꌐuD;t C]a0IF]⮯գAQ[> 'G=nwZVh1:Va]4x< ;?a.< Kp >;C펁/Av* -h*@3؂fq,`))L2M:f8U9m(B3\Zh&qȕM8xm4r jF#8TpF 8|D\M4gqX>Ja6"&E8!]AA8p8h\qԗKP E}mހ/P7b}cw5g}& 1j4b_?=W~sa5y7@&G'QBfuS?lPgeͰر,?+݌/Dbh!z/y5;Qse\:5c֬un9jF1ajw uڗأwʽhz3j\}5މPt:roY;Tij c>BT$L#(:|ݦDaw{g3[2&0kT)>mo\-jKPUu\=FJCBҼy3:h5py10y4sˑS":T @ jjka=j?AEP9ootg51Ɖrhsi]oVms?P{p'fjϷXgD1<ە_ϦK̋Yc3kI:r}x^[a6y83>YǙy簜y3x ykk||tva>f>3N!̻'BETiTa0 ·gs~4k;0+˜73m=e˻L뵥L$[-64w<4,yd<ļXQȼtc:Lg<>y>Uisy`wMw|F뙗O210oO3̛09n})̛aY6+&CJ]|٫|sf~f~b~71?.0TRv̯;/ } OQZ.saRbUYcjTuU.Þeַ^6[&ZFuhT?Pg&j䨡rX 5 O`B58~&NC=ЉsytALr)Cqڥ)8c:.Ez pY 6 /M\uz*q^cWϊLMqSo ]\0|n+G`mb[qsFQ+bT5ƨDctV5F{F`tT9F1fSGga [KGclu;MNĸ "Ox_Pø\ʤS1oaLZF1A q]{'8=r wAstwڇ}pu?\y$=ą3\\VZ.8sdιsp?3[typ^6[~pNopKtdhwj|mqMu4C䎽We"X46%n?FrbPQڼCxˆ_tDDArޚ_y7j;L}=oӘ*߸sDuÝWl4ܠȃЈƓƃo=H7˻o bv4j6Ӻy 9<=X v&vN fZƮzɮy]k.zv]5 {ucz%?Kv kvj~v~gx~'<}2 /`6w~)P[MΦٲyZقm{+Ibli[|g+OٳZsي,[Q3- z ܝY6cE-_$`f%Ȧmᱩg٤*6^Msd3l`6q'ƍTJ`-S&G7l otM{f [ٸll"e!d{^gt +n1[=c+߷=]Laox> }mξZv}Ԋm~~]M-wg)U-)qfYRZzr`R~[%EJ 6Ի]eBCٷyrUNQZ%SZ*ͫەt(GTUP4S9V=˔fO*m3Q(] QT.YS%JrLZr|+,R}$){j[]:Sn*ȸĚ<˴5*b=3~Q̂ELOV=4؈#/=!;6AX/:xc;į֡t i+$:Mꗹz mi42Fÿ}r;Lqk~ ~?vd7ևSȉCOD!#wFZwxM\Җ#zP!%)2z"]?ʕ$є^I"OT*Q{ yd6*?Ce4Ǐ#*sIM[:c IC^R'T*T}i#Q UkCU<$YEU5TBזPUxnU_OUK7+I>zQŞT*n$n_ZIҍ=r$T~A@2SuFnOջSޑj'PMoڹ̑v*:hɦE$?C/jTUNխD-jŽPTu<ʜfSGZ5JI*Iv :-2*QڿT1AdbVO<U蒬4ljT,U$#aM@OI6Ads&TEȻ$sdsSEw*?@};C2"*mRTVDefPʃ욜dQEp Ud4P>:lC u+(9O h UnGHvʔd߳ӭ$CIJۨr:>!YdRs"'I$bD|$$80=I HlCגxjMHDOITxD IDe%Vm&*H"˱$ҹO"$2G"zBdk*Iͭ}$t&}xdp*6r5wC T٘+!T.N%8GozWK $ՅI~_x*5$&tA4ʨ&*zٹ$– *JS'TDźIt5D$$\"7JIYD]v]FQ$ۃg$zlNKQ]0DmZ%멠sRN, %ɷk$QM !y \吜{S'k>ţ& XTi?vQMO($T_M]\m ͥ-%H~UﳤIɕuT=іjʎQT5[AjBϝvlGUMTuMjVVTEHUET}71UT?j~%P$/SUpv&yH,U1kSe,o$T7OSj,;|VHU^[HwUS4©**'d+W &Sc4OʊT5GӹZGf!WHVoLUA$L.UĤQF}3IA2yTLXu{C}*QyeU\Q^ӣ28[L|:ekghͬoĠa7C+O+%^am-W2DdhԠUjbH->H]=xģ6~Ң3^#3 3C{f2bEb7imO)}1A_W3s3dc_o4e6eb_?3{mɐגk3#zg+J\a*o>Jg'Fܼ(yX1B1&0MGF22d)# gdZFteėLȻcD:3jPc +Fe ҸBcu?QT"QbmݘhknތyPħ1nj>\9 kcfc2:L¼_3vxƔ1 k4c{aJ^1w(i+q{F=kkٰ- {z\ڇք6]UiK!{w;QGw2xrx/YqBdvONٍ?;$a_˾O^9Ž!E>_u;=Eϴbbb'#&>]bf+fxoLSsxLUEtsԋUjnub? 1l1 Kٱ*/K5칎bRGR8@hq*J>BA|mBH&*z>tt/ K# V=?qWe\{} ղ j Wףbz.|+$dx#],Xc|^ۡ1P>H]dp}C!-+7n.Gw^%e?Ll#|qi6$cTV7>]4a5Sd T.D(9Z5CA @:s08m,0]͖ǂ)07b~' jm)~[mVbC2c[R0m+1+`X=1 XPkVaItuoFnuG*VO˼bRkIŪX38eXuxV߿ZlbMQͱvic+>C3Y;cW9flm'z`kl)?-־ش.`Í|^a5$y+6p4D9*e\k!`yJV0*X1M)XyaŴFX+ͱ{, ,3ZbL,Kt;^XX{$N :|wKaLlS-r96 }sv;c:IhHdD{۴ u5 {xcwR߀c6AX lQ8dC8k#'R'V`64τ0 # '9ė%8RM|%:?㎭p}4q紂}>5^8, :w89ùT8gP\Y 9_~N ۜeR {_so&m<> Ywx= Gv~F! =këCLw2xcU9ܮV?>#n#u&\"p碦R K/\,۴8 I28YX `Ώ픶pN`o { NЅO؍q2XV ƿ3t<^Rrv ǨpHOJ䖡WViqۼ| OLC B ů 8!H 2:x" !|.b &#@?_9WIWSi|Owq8V}>e5m kwE_>w|VRI~o ~3Noy37cq_cSM| cF*egXwNW5W)]md30|+6+[Ɋũ$ux+o ellSZ5^qލj=z:\Ykx}qk=pJWtkx 5c [ Cik 6ҝ 7+51^'k^;j4@r]y׹fmer>\ J selx,_Y }1{ i~c\eT%_y|YO|^E#G>|kpD?7_*J߷KU寯~_wJ /Τq~1m_L_?O'ߘ:H}([g}K{gcx\p/kǟJwq{yUo =r_?̨[??cynM[^݀{&j_oCKک%\ude34>v&p?wF&>` K`C~,֖j^9orX$,;E&X W |"jVQ04'w݁iAc 8d-/*q8P<Tp}.8ئ ~gmoW8()P8`:Cq@'*cR{\+ػ&Jp ʽӄ[ޝo!_MxLbʱfW`8{/`߹iR}f[ooܤ⎽^IRIOI؛gёڔtnu7LL&q{^T{(mPl^b-mc}æX. y5' ia|,usaW45W?1ӳf^fW16fog0/j`jBL]}SoJ])ObZ6 ԉNmrL.UǤ]VخYL0:<ƿRad5 Iuw<=/0M[E0.Ŭ0v4>fb-e-=T`|iQ50*\l9FǨuTD_IXD?~`ܢ*=: c@s> aie{G|}U7;cX%F[JFnȑ/òcD /1PbcF69w)nj}0ygx'b2/1O7+J~?د샬`X 5CYoB颁]ʭgբm_hv> `PP >{:C#$ 3ZwCkh1Z.zo͗ڎv#p:z?5Ρ0H/_gƥrḶf Mіx-z턾K@{)^@߲]=.D.aîo[cVWKDヒ{$I/ۢw5^Bѳ6x+v.눞sTtBEeT$:~cOJѡ/9Vn0=0l#hiw-?V+3]g£뿾 [Fˇh]_4R/j3| /+(}oڕrkֿ@^ڤ0y7hm%ɥ>-*k)-N54jE7~V4V'EhG-~P^~;:lKF>3jv]1Ÿۡ47&GAGO@u]6T2j{w@hOz/@{%f)oEXOr T UrW‡ZKuP;POܭyKr]4ZEM )__ Es_/.$lE/˅_=˄k!\֚&:@cKht .&l}4 ofʵ\4| eh~k=Z6$brn2ջ~V2oZ7O] Rn3mro3 F ldnr33t1۸)?, ^NJ X:k'b' +i6ߦ^[v WAs$Wbgdoaj%ap8U|wqW][30qɵKX/n4Qb X,hEZXO0sR>}HpĎmǰE[(ݬ5KbN%.ދ`e+EBg,GaƷg ӻǴ֘{f_ZY%f0Dm,WyC,y1O [p/ &]<5g alT@i5Fn:C>@v_=M&8* rg75)_K뻙PJ\[(3b2 -^@7t|@=·= {!F^-Cx? of7 }Յ!IZNU`aB񵬢YKUQa¬Bja2gaxUnWkTaDN KNԵoɾO&^+{6Ee/`ZaY 2ǥB6|3^ָc}?c9K=ڔ}Q#۹_ϓ'0۸I'ҥg||^u;tJwi(D^oN$wiymU_37.)Ao_:[lu rfʤNK-f/Ls[&ߪ.H.^fͪ|6GO|[S;!;-:]c'_l"{WyQ7]jT/v(/O~|ةP;&6ja-{Y%v^)qHlr_7!Vlf^y_l]J߮P NL8T#S}zxx#qWX80BMj77Guo!.\&h$o-TvJtx8wءWJGq8%OV&ӍEyŞ+sDWGV˻}u#.;w,jh?*.'hn*j>7/^{&R89J_q96?27;DʃʬQ~Eybe+EEⒹyŃ2%rBqWitdODJ1DqGa]bg1g&f۬&ϛwShZ(n*ԗW?WHxKEs EΊ.) >)ZSS>Ph E.ZR}7Eax8@"?E#}ZU4zWaVER=M.{.3`Ϡ1slncuΎnso M.g=ǐ^ ./^vme ƈKe0awrMʻ}3Х,74V0t\r7wn.$<7h"ca :1+˄M'0:ڼw vew Uufs}+z/m6` Y̰_rѶ_+g|7&^IeBƌj?!w3H2(vxèi\Ð=A1~nx _yտ2lo[1!3.x:3Qxb믔wö0, a9 0t彟v ;qa2]ry bع ߚaڭz CZ*rd@.v`@ d@|+ _={g4\۶E:n &}OyWF?z~:o(]hLf5yC@5 _Aro!OCA{]1?Ȁ Ȟ@ /cp#CeH*"Ȇ=sCFV(ۃ=2D3C.2;?+7ah)381DŽ)}+ =Hqɀʁ0 촕35y4s7W_Ȑn *0%m<[2`14Y:*usӧ3{Fߢ95>S;Cy?*`h0,af _?Xȣqvb7<;0z\Fw>ØQь|YĘÌڛ1aAwS،1>*c/0cƵ:e񓱦'>ucQ3i¸TsǸE_sW0n-c3:a\.}xm鹩 c?X2f}LO>%soX)SL;Ё1=Z˨sc&X3 F>hMiZ %^u1m:6K+1'1\u61fF-̨kݺQ1T0%#LېZȾKp+ Ͻp ?;5 s0 U]o(츓s^ҷ:_}8ҷY__L>Ktj@#:.Ti]5oiOoxlކMl})9{eC߳<섔2v=o-9Ik9FnWaj"gv30{=Cb?0}O!zYG=:Φ0zO37z,H7t]AwszYF&N҅{y=OW΢GzLFCIso:z\A]\Ƌ.Vv~-XA~<'fUh>e4m0NG:Bz<֫Kt{ؕ>:-')e)i~mYCϛ=O=|-ݵK5Q'neM{E+% >t'ܲq`r{/ hTuYCהtUF+X6i<к7:Ѳ<9gOM VT&$mow(GE(]+h1Ti{>Sh߿3-,NG!zo領\Ь\NZ^Ck]<==q1[nZgUuGiZë?tӯKy":ilڜPU~z\?H }:e?zփ#hmT)4 }hk+=sgz&Ыmz<\#cj)]n 1ΈA*sJx&-[s~\`hF?˟L@n%|z06C7)!К pw 8C.v`h\SL0v_}a^2"v/?a.ԏd Ő f% +63dv#f$ d賏 0d q6Sⓠcp2"2*CFLdPBLw޼gh2C%Q֦Z9Ɲ>7}bӆ{͈)_H}7}e`z1Z/y2fȁ&0a[ ovUȘ7YTz6֌27#fL`FhuFi0jK#eDy Z3j#2|FI~FsѥcҀc2RS[3xdҹJß_e]#g錍!UƅYؑ{6_9&*ȘୌMObL*XĘ?cgtƘ2F~1ٽl8cv$cqƌ癌:j.}MǬtzCGvtFD_@˵cx6^⦦^=ܤ\sVn\[y` 7';\-2X ~([=ٿv;ٚmԽuQ]x[r__V'KVGx8j,I*޴ʒl‘ZP{|Ló2\ẙሏȞhm< 8W=ýN;jb\&b։s`6oI^MO8c?B8ԫSw,|UZSo7,-Гbr]XbXhlU1f{Ŝ]d(&tב%(ҏ(4Oo.>mC *Tϟ bQqIŢP'qǺ{wOi/q.w#ss)У|4ƇNqsͯ'%>K7hP==SEĵM"D7RqsR[h5zsX&h](^z8WQCjƒ,km W | ^%e GPMI ha 2lz*VjBJ4<aƎ1>bL&.X;,%7aXvêEX4bfWl[`C3۱yB 6-*ۡh*c}^ ۫Hc2.L [6ofg\ߗpB%z8: z:bO:2q|#;*S@Al MqK+܍{w|VV`ص {OLɍZG>bͩC vc2\o߄1C4\솝(8> {9o9{%܎%?.kܷPmxh ځST!#VzA) e B;pUIGizMHUG$K) I}7 !Z"b<@H]F<R$#'^/fw9 >ȍE=65|OR_=?+sBZ Vo7Tz&#XWb~G?3+窴Ame۔6mTߧ?@G#pN|(5J]B(}ퟒUpb)&`)nW)h v~'2C#rU?0Yү_j-Ee_B'h |eh=)=tj9 GzT)e=3y2|Lʕqt2Fyo]#r ,#?}[#(HiG_w^O(}2 ߲|k3bxZ;-Woz%Qwa6v*lv!Z6BXbqlXuE[0{fai|CX|%NEF`^4ZLWX._S8u)L{f*,\նS`~\*qbE,.q7,q'5Xnj!N-Z]KV8驍'``4,&I:48z=,{z58f)3O|c8ѳ݁UχI893N ɽb걘1+Ŵ0eeYsL1k=ńyjjb<0I }W(O:h88 c}ApfdBV cqF7톱0Fh9ѿ=z71Cza8gnx'zBDj{}=Gл~5@W[1K-F+2F߄asWbo{i1Ed~Ru}̌QE10e Y9|Yu0Z Fc"`nem|I:lSmLUsHYj1~,+sOdfm9vc\w80ʑ޿aĘ>c4^C:`Cw }ەg^wJ~0$p"ބ>wQsMUkAIooaɎ &ۦn.Q cnG}kAƣD,x};bt1UHc6o ɗo.4[A(e]G_m _^Qi>[ZǂvWӬ1:/DR CR)m #3X4r[:j,Swo Bw%,rβ+.TtAG_#t\#z6G̃{ n0iz=h?m.}COctzt&J O߄(lfK?CY 9@Кzo^BKД]BS>>RϿglѽ|>nЮ$-=mmV~ɸ@-N@;h}p4ZD(tQCuNJY΃>ڍHrA{ h 24jQ]@{{1Z%7f h4*OEn54vYVMwP%0Z{A3\2^.~|*|xR6 Zw ?V (][o >B~u-zFK h;Tߡ4Nޙhu+kDc4n>E[fW莙vBDhA2 Z-AO?{Gkaot^%`^l0ۅ#2THN%]`?qFgRl0:;b7 ~VڲC,-]:pB:un?G .gߌnճA-:M*偷ҼX= }n#f8=)Y>,`y1>R~'9? qh 'zQw5tL <1Jlc^y/ET;U0F3:\1ۭ w*uȶh>d|&BeFyv5=Z [5OZ)odE̓e9y:KeN^fd'#2םq$w˖c͸aوYsnu9nlh 5\;6~+5l 7n/}4Hמ_Ue5.9x&2X|]nF K^7wp7w~S+U5o< 6oN9K>KJyyOy@s3{DO ~fɭs֦o?uI7'*d"i%~NT΋/6Ζ,,X#7L~vF癐Zߓg<$v"Q yMUks.̔̐ok!^P,{4Y..*x'5Ml%F|"w+o]F,[]~,NYc*-Cүwlhc'qbE{E1R%$ +LEٙsY{bӭE'1ⲵ9W'D΢8rӺvbbq+%bEb5_ QcSqca';{w#<.Nxf)n]):?&کֈ EEwwG1v1YtU sSۋ~MED#1=Ϳo;"n˽/ZFn}66Ѷh%B[).-$s)m4g7JOJ3Xc,;!Z>+_#:D2zq6di%^,qkv5₦gu [{VL{gϐUeqէoJzV)m;Q0'3~xqsip! -~~jfmsKDm ]b*Էm^UXC}\Kjhi٠-t?P?hn$*+.X5w*Z.ZtL\EPŗZ7ŚmbJlbQEϴKVT-*tVغTa8BaVyeQ1lb1*E_R X>(sbaD lU̚60Ұ/#[>e%;͟) qh)8{HT0b_KW;ޗԐaQo~h=!z35ί1170v{FO`er?+G{ƈ>z4s #{0ri W1`;u`F Lᅲi׭t,`D'U,90&KhfN ]-xTgfm )\a ,yAZ=2'E1r23RdL۶i#~ykb/4gF$K93eFjv":0c Ӟ70%Ӻ=fEC7aV;s/05̌.35dr*cꙧ<%gn2e]SND3#ae)?$gNz\܂^i'7d^P_c0sY(,fm܆#JX2k5X°,21fmMH?eQ,깎ŷXt '$]+ ye ^^Q^+cyY*/O^X:_a,)˧Y` TeQ`0eQhmbA CG~ckY{`ި=,ф:GX: V2,\`Wd~6 %[<[J2?Zw0?X1718~`'¼әwyor /;P1_j(CQOf)<`5-z3s7e4fn^l4a^ʧSlbI6];9lcyYCbW]Qܵ>iĬfnցy=h_cR U~3.J -9)aL\ֿ"nvd\hr]:,#1X鲁q0C&} ɗO =%eVR~~Ik71ASf{ċ~IQLl&ɰݎg6br1I_L 3>cJ660i O 2[ގYdu 9-^|*^1M90J^ӕi1ƝϸK{ϊSs1O#f .Z˘`pF#]`HCg\w OgicK=w@=!qO=ŕQk=?^  ?(^ &}eL3V1`b2p/a4F^{46N tcJLcП~8ڔ+1}Cʖ20 ݡz]jO3'=7K|[7M2[3F[ _[z^H c,ZԒ$ϊә4G{1 &^UgL:DŽLس ,gP&\#R.iDŽ'0ޞN7:x糒/Z2XuΌIdSIO2,FglgGyϨ˘}C>1j&b 7%T(;KXKatj5[g>TwU3*ה (` a1nx/gWfF7躍7zܔInyы?ܶ9<]g+%<vԑzĒ=cf6Zf.G2f Ǭ{r`v'flLߓ0>a{M2gR`)=^<ޟ31s ҫ8q1/f.dyRLcڻx1ɘMeI̸>ׯdZ^Hgg̊  '0}V/zbfuo sI8g.sN9G)ߧ5i:^Zd8EyohƼqxiU<j2^wi]יyoQq"B.oB@KoڄϙRX$ G6/p&<StҢc5nېlȰ@8i+>;q X" tCa(w88np>I˯|+dFƃ`BBȧ8Jm;qAp>e)lL$gL*x#=4ˑrg;Z"m-]62.\8s; OO$5H)#"u  wpN .EAd.Ǜ nLnKpg{Oܝ'Ýp4(7Sgx? m- U|w8>MFm>~a +g)>Ĝć'PoYT7%wjv>eDe-jgh|]uCcHs3~5M/4jH_y|>]C!4@C/_7w׍EA?EW)nįTh=U.QR%OJhoDT9KՉU5Uݗ2e6UʊsTy*OT9Ufoğ" GQ %s7P˗*9TO]r_jRU=PcU7T߈JKͩd1~,ZHowoCTmGeӨZQ}{j=GCZw5U^ST?:apa#Q j-u֤6Q35'MjwZjEn!L5Cn WE7:u+'Q_Kz;G=GR_&ݢ^O]4:PSuVn7ԋ;GӨgyPǼfIe>u6_ԉYBM#oB̩N8IZPFjE_}֔ZVRT/yF[cڥ6zJzjGԊ}[j 6 Q۸ vVwjצoAwְ.귒&Rj}ϥ܉ڳOH28P[k %S)K\\B}truP_Π?zبyB|m6B}N~ԯF&{$oQ~si9Q?9/UѨ'uیzWS?UْP7'븒zPT uTSϣ~Ŷs;M[T}l4?,$YnJvRf-P6DP__2꽕0G.P/ZzEP/L:8z7JqzWrWH)_"݊o.٢=lzTK$!VQ{m5[$}FRVؕMf#;.Om^%ZQ/Bz\]J]q~Kԩ7,u-ΎhF'RR$_,NW|(zU1ԛ!hOSFK/n|0{ uIdjUPO&g0G(%ٯH{l,p/"a}5(rgc9N~N̩b3uc6:#'P ~ԝ,I]g/$Su-uHtsӓ:r8bLlN/O<#Vx #S}|6ƥT#qT+L6o՗lzKiq[#gR]Êj6RT @~4o:յP:vڂ|;!T&qͨ>jsFSSqZTk*ѾJ$iMoc[p ծ,7ȣT[ETQFUscITk9EϥqTiBTQeH,UWi"agc M0g)U?G~cө{ XKxO~ 3Ot0ۂrf's c o.0|;â_A[|Hx6deI-|ԣmq|[ru^QCF |o!iG]j|o* Jv._ofG񹮵?_e 샺d;|*ǷON Խy"׶2|t_K8KXS|i؎og*ԎyjQ{jD]le|ڈ/Biho|qO0x6Xu`G]m| Z/" >0@݊1be/ܬ;Pw~| _Rm>ڌڃ)|8S/|:Oc+nZ?QeU{PA>T6TrBq%sч9UY>䀪PUQ3a!|4Xnv#Am8Ty.kQuTUmjN|@ݨ'b|^8_:ŧ@|\O}p I68ףPۭ k|Rqiez< >ޒK)ɶ j'DS4gl=j_?Aŗ5KEj| 'G͖)̑ƛgM}a U/Qud:TEMlT/yCWT}Q+7\QSGcoTTjLW/~DUTo@U|TlD TGÉ8TjP9[MƇ|նSamݓK/'zJT?G/$[z~] Uǣj ]$F&:XsTt݈>p֡ZҜi@TGpCYVoTICg7}*RPY %wP֡)Y'kՀ(:%7oJD9tqʻ1JT-Qk+4eBQe+GL޵ŻgP[P+ A&/ |&+@E(? }^BoQ~}@)x 4,T0?Q{*F^A999bXTߋ#WP˨<_HkFrqTAeY)Pc *EUCJu3TENEg*QB6N@?x5SơM&>h|ꂟjO݋[Q~A?PX@}9|9~?5TԎ*6PsSDst.p@ 7I|FScW 5Ro FxUP,J?A~9~hIFىQhh1 Nаj I{~[?sN"~A%hx2?a[~mmv4għ|>P戏ŋ_z܌Dg/?7mjy^i7QY2fR\4|]W7N ot߰x/<a~wVHa iEq$nƵp;nZ[>ֽ#T7nՒGz'FO+:l=.߿7PW@(+:@q.CQ(JǕ^.(.CE(7HuG (\4E(4?FQl5 Ewz.W6TpySH&Hm (LNAэg(jDX\+:h4 峨Y_d3VP/SD@k {j`ݣyOGq-:gǍF9'wZ5}}vAνwvے ^9?c]hmfnS+.w337cTWRuQ%n.bH_-aP ;F4el&1mlfPoxLy(tyx^ҟ9Tߘ9z7PӃُG1S^ɋ%ϻEv(\5#洌G(˼#KHE`8Ĝ-k`\gP~>[l[Z_L' bA9ļtC^ݧfʫxIW` KB)ODr**Pesݣh+HETLצxӂr|w1u)D/L\[(QcnI<17}5s60vf4b?x#sKzdQ~Őb3(~#庭)3b)T${(5;Q)1ak*6T$`n^4{Qԅ9k'Q#$,.Kur!Au`AHh/$($Z B5w!A!H!w!0+GH|A[Qҳi0D0G]H syBt!]W%ɦ-#$, U'%B֑0M!ac${D0󬐠!ɹkQ{r`R)$n/-L { dj"$ I< ]J$̅C% C$7 ^;cBB-B[+n w+BvBBN!^o.~Bb6BP!!u88ꍐx뺐ig#$n&$^_($; $&$늄(S!a!1eFH>]Hi%՛B%lS"G!Ez64TkEB4!yx!ipVHRZ9I; ɧN Wl$ީB S!9#AH.JBJ!!9U <*.\HQ%$-R )w gtv )%֏37 )Bʥ`!%NH.RnHϝ3$g™}mBJ.ጮ$!Upf$ħ"o,dtuT[R7@w EL-u"U[wRw/uww}~[?:3̞CV|[o(e)O2_,hrnO6P֎u ^ϱe[~+e>IY(k&MYS(Ϧ3)/eՂ(K O>R2r")ew3(;eA~e]HGCS<2 Õ aS=ꥤ얘%Pv|P4Ҏ,S-ʊHP)z-adS`P~/=˕(.7>;eO 7ew+H fC=F*%])k3z]~ÞGFY ZS\Al2aQvʪLYS.Q$ZwrPNx0윪uOUSSkksSv=> FY4]RVu:qx_}|pqzXєݮ r ?oLٵ(+e[7gʲNN.\MYߐkυy nN^sCu.xĢ+{k#)k ,J>5k x@g@ ̩&(#,@nmk)fKY;MIYӞo\CYw,`\lǯ)"7Uˎz#OVQE .[\(k~ rGlMe>(c9?ևϣPw s|Wn;\" ʮxbot:l`l~DY ބn8#FyF'6ߣl'Ŀg_ ƵE> _Q{ջP~ N)kr68 Vu`|8e~{V-F=Du1|0C`9D8ak;ȍL-; f@Ry >1We+p9u >{{ZF}R[з9-t vG/SN1Δu<"#'\x ^_L#81DّeyC[]'(k2 샜ێ2gqͫ΂&,v=8ʼ:3ae_Q@kZ\cz;(,tr'㬮2lOrN'v6m(s`EkP* zny?~f(z (ʼ˂Suѿ=C/5!,c_KM~=lk )!GA NX-e7;/12-QS :ž2JQ:42hz,enMqAwl*A Ր2A$^aʜЎU:")sf,H#7e)j/wݬ'2mboM</?G\Sp̹P'giGRY#Eԏ<$xu!evAG~wAȝwZ^bzO( j<W:"|"6\;e7lC )eEeoѧ-B?8SAƑ?؏f4Η:m' #;_.}/N)_{RK0_/^(ǫԁo)' uB~lr.zQwտ(V:e?]H9zR={ԁr(gP"]ەVWRޞyWeoNy%)o]|e ա͔{w;(OK?)OP^wo;?w'Cf߽)tϠ(ߺ=Dn(?GRލ׆0p>K(5KΔ=}(.ldh&{.e-)?2=OS (a=PB5(`_;Q~\$"CzO$CY#ZQJdPB1N\b/? UUЏ?g }wЁ&C1dDRVd9 #C/ Va;2?#ˍ 0FEkXZC^d8!H.w"dNן , !ƟdxI?hA]Xw>AdK'cdAd,w2N%52F吱?T`ӎcDW]Ș^ux:'5%Rd̎%[d _"87ZX?2iKCdlBU QAWi tT@s 7ψOi} T-w7[]]{ B!+u,F>M>uElm %0TMWΩ?N%=ܣ!ˡs!`CAVo*MTRAT{AY? VaX;CC.T0q^dcnmT*Tp/YT`,~b( /L>B{ JЭENcm2P4xwLn@OOQב;ʡ~t;  lSgdjxϥ̮q^ b|/[ ]iT0ð[7MwXJ޳_2'3`;pV׳[tkP##+Vɿ)ԃ-a/u3TחLN[`fmVdExX̆-OCC*8:"T1+^5 <ߑr*`{cI#`H O/ J6THʁ{TXms 24 ?|v!o_:p{o]W2E_gpxgTpG2<]w@8Ov~,2xAd P_×.?]nal^Ld;nd[ssN5eG2Ek/L `%ntdK&|M"S2b |N&ӈ:s&UG̶V5:ލ]eZ^`,j H19-CE/ ߇YZ@;y,Q1Žd]뱮ctXxk@kȴr3Ngd] ;%S]}iAy2 LÉ?ɔj>YⴍLgwt F!|c'p6ɀTF[Lƒd:,A.3 ֝L/`-Mԭ1pcb/p_B)B2_OdJoMdziK2j4i߉Ly#{k3k\92Ad:3dj8M%݃13q^dجɞLM׀?zhS֎D{;8/S}]7gq* on6r?gQo2݄Sa<\[lɴ: !+}.8{ Ui2MAnWl:N}pw#R>Y"AO={`.VWp{L]nh?{@LQCBsU! ȽMбe^*|^8?>&a r_e4x1kY݄z<qFyj+j.]ZLClC\>W"΃qjF 3Iߠ/▂m.:45(2vEO;#7F,@-?|^e%ni, qA9D3Ըv*'k96κ( v5Pn-ᨽM j=Rq膺3H@vALZ!/TȇxԠ'P ؠ|''Z _N#8߁3h\ {4r;9 ۯVn/sG| ygIȏGZ L™5gxy~!.6K~n1ѨyJ&;`vNK{=~ jI/Ӄo?/bV'E{9a QG9^0 D~軑cx؋~kzc'`;{avY{1mA>߰ˆPo,[`z* %kvio`QЋ^w lU=tOW4DBxp Ԁ݊d;F S퇭=~}s2C+2~b2Nd<kqG>76!c͆dUr%2jΣ۷(:pjJD2lYI-d/z`q%! ) Ca/v'ч i ~ۛ !,xDz%n{fu_RWׂey {R8)XG|?ɐF8uMGdhy ʿw a0I/,FgK]̃KR*8`%=p \%Q p5ŽQvdF p !CDO2X}ڱdX_".'" '8+OQjr+@̫Cc  ع Oݿ9i/gout<Q鲔 mE?b)jG!OL-3mkG~P~IX#~Q~ =ɦ̢S?o3h\'򿐙M]S>G(0v?ޔ/kEkX`g?(}a5{d7Rg߰ t=ѰcVu/[-_*Oy!q:CnoO.\IXDyERLZw{ӛ(m=;T>a#nʻbMRqs1==ûu'ɔ,ʫ}y(`U|IsĞ -7(^0dϤ`S2Sނ;縄nަ(o#sԥ(CymNPg[JP;C<ʝ߈rP.zW)7lϡ9w)rʍZo(wn mrNԥܖ)guuN)gt(gʹ>rΔURN1Pxo}r*Qʩ8o()ǷeJ;>RÔ=T/(; ePv[_'\)š?SvJY>R֯Xʶϔɇ./ (k6:ҘroQoReEY=2)tD_ڞ֕27(]>evr,Y)e!ʬr2~ޔUAQke՜vlB;hǺicj 覠htڑKܦhϴ_ 7/h{4>w,mO>E'm_4nQڮIDžҶ&6DmKp߷4m sh ڶ!msmK.5i뗒ms&WiuRZx~ZցIuy?)Mz5.mC[]_VOVЖŻhea̛\/O[t-|lB[vp3h6ЖcFrn+Җh˩ִ%mYmnm I[.i[ m:s6ߟE[|*[9km>6>O[J4͇>h<몥%yzY\hs6k0W̵ͺ<~#mߎ6SKȯU tT*XW}UwU!*baVsu5,sW O<*3#ִ\gNB); q==p .cUv o@M w0w>|qc{O lyOq}}9佀/ޗ{k^bK/l{o ־Ǿ 󟱧2w ~)²PJDJ )uPJRHٲ RJ!񮂅To!!w%HRTjBj`o <[mL  6dXcN 9`! l {mlkl lfų-{Ru&H=YߣPt4 ]cn=1:A#m wfHC7؎[!~__c5>xz`!ljFf=fsCcȵ{t>v}06:BcW q.wm}Xk8#>v;B# 뜱\p }]a+lpnbQvՇt54灙f9l d0cx߀N e:At:N r{:zK-v^g `. ^?wX?r\_<{8b||ogp|p.xku\s.?^!6fa_q~+)~,W*7x}W^\ĦXG] 6ynf9f̾}2ϙ.͵oA~= 2lg":i ٵİ:QTvUG ],e%쯄5C쫀KZ6_ yy daSy-r]]YPeakY̕y-=b_V澣r~K[GKa ?sa^ }ţſ2*R9 ~nя}ޣ{{s2^|=3|'X2{L컏>3.;_oz s71w=g }5a߀]컉m2nIq>_17@K ƥYpws TB\*#NUjiu q^k1v97̹il>;hr=to<ý?}!C'WBτឱ\=dAf8G榘hA.9`g:9yIJr1<:K9:P_a~F:Sۘml`MqAـ69+zO%\ȵfl.Wc0?C\A>ڂ/I\m0'|C]C.ف;v.xWvu׺L].? :b Kq& _`7'UI7B\ư߾{b}u>9 :GpD:Bppy;#θw:|-w~׺zW n ;;ly&/ ^/~{7FovO`|>Nu5|Q?}#_鋺 }#_B/P|~i~\F<??.*lUU@*^@G ت{Z|oZ{ آ@ G|?r mN7MCM( 9@"a{ p FAA P `p56C0C_0R!C<A 'nR{ A BPCB!BP?C!f9aOjC,kp!6hpElgԡn1އ"m(b N"wCC(ΰP1ȽPp9:PS#%rSD ] U\xBRo>C/T TK*S#*pD~I R7|S#ԈqvW <vj!FqՀҀw\c 0bia~k![i3-bvZC`tq:R:J:pExhas ]ZE^h}րf஁o>BM!'p>nE8Oc.ҡF`됳:_U1с:,xC!-Z-K 9Z-5hy`Rl9."_q3 \_ԡ2t8m:td选|!:ئCKY6G-f>>Fg <:CXx:ĭXtgbWjM@߽yyyyY_zk',5XKw,8Cb_tq|6gC)~?<{͘:Y\!!g{kk6#ź2q30^}>ee2cf y\bj/QqPgu31S5[ Zg= O j\; |U*pT ]J*m(T\QWCQB79;g߂;kP[PG {'1@ @7Am6A5Ql̛{?뇺 { >dq{oF.yz&/ ='@<`;Oŀn u UCSqNU+WFmVJ-" ECVˣ>Wr!eeqޖ/ˀepVKC_iĻ4zRȗRRz쒐Q:KƖD>'KXS>bm{, -=Ʊ,C}tuJ?  Q(_d6͐_kXsglE #B~,ic1Qw0X;}g̕Rȷ-B.0*dH\ )ɐ/E-3lw`@jF|4.>x^c!tmX7 |]/) {_mLW _BKx /aK#|9|xg =o!O16=&OBy ]1v<ZCa:=+x#zzː'! v/YE+v 5߁w3Q;(ߕ7 >~߀7fW~_s1R"Tgm! l[/kx-d|S}ALqM_/,6E sa_"ߐ{[Ut5_!xכîŸ"\8!EWWC.3*C̋3/E7b\~'plߘ*o~a~~@ ÿ֚:—-topk^ÿk z_WK^[qπSSO { ~=c#`q{!>=p= .=5{z8<N(~6;~>>a}Ⱦa=].]`rۨu7 ~\G^ *]]!2쿄5֝sȷsYZgiu 6DNB =\a1Q<#߈a}{PC~3}{/l؋ers19{;{=ƞ |B=ظs vþ]л u'MG[S#5x9~!yЕri6Y;0C6`c lw6Ÿ 9\];WC*غ2V)2R6-Eel\,@~/gydE o웉ߦϩSd: OD>L-㑻`W:֎EF#FX 9ɸPf??zaWw1jX)צq8C)D`@a/zcwzƙS87܆<[G5M W3̿( =u!.o72Ƃߙja8#p2 _LTe|&~RAXrAB}&mYsW23xB07iINA6t|[73 >s>sXgg4kjX[{n!] ſƺjxWkC+yſ6ߛe?ͺ`g߃d6زNWՃ[:خts\̵.qz vȴ2kk[i^M~y4o76pͯ/V;6zɵډ{ڒ:!׾߂Xq-\u#huMl㽔mfۈl7uvs!Dnƍ[ognv|i.O[DOp9Ş/}c_i~ zbH+~bdkngL94rJ᠕8X3C4Z6ӭX92UeQ0 Y=#,YU5gڰ6^1oȢ*%8vvr #"/QY $ti1%r;7Ǖ>-9nT{wKpw؂らT7=ǭYqW8-ǵq~I{>Ǧ=ծG=Qv9~BKs<\]#kix[d.18Sss+Su#7`̇ e-]Y;,Je-}b{w| Y\y{9L9v^Mr 7=M{L`qa96_8lB82v߹io7nx*:sD+fpxE~1GVȁ?8j .Q8zwG/9:%Gw8v_CZ1_slJcslq[1wj_8vT&&:{ўh e>+ws{69Tܞq|'qs=8/Ǐ|ͪf) 8_WnSCBhPq\:DŽ'sxQojpt YC8\ሧ8HcUw8RƲ~VzOY#%+`i }Y3k Y%Z^ez-)V1[Xmv'ڢzьui]ZsYgmh,<,jY;r 3Ia͜^cъLdzH|V& k^e]L}kznVWY-$0ŖbJ(bkiӎɐ丕5y |T7֜ gfLư=>L-bvr{z VWêXa9;Ug+Y)֌ƚkX3a2k/7d]%'Ktgf>ToY~+9,׋Æy>ԇO>#\sow{G<]8|7 e}PwO}qSiwro,7ӆ#{87Bjqyr8Í#9[.K8f(,0C,x9l ;V%㷳 dV"rڷ$wc.VKr" gY?}9lNYlUZPonao/#V9YֿF-agXkSY db?l[ۘɰ)bn,Yvx;y,˃,IY,';8~g~,/볬r*MwsXP> ׽̰C+$b[S˞^,3XfNd gaXs̯g! ~y~d|t#6!8]a3qM]pj܈(݇#8b8"7&)_Ȓl#˩qme9}ΕEXw^kG1 ǜz7smw9TcnD6䘟{9n`=cds\ḇɨEƁc5Pk^B,t71pjܬenf{8nqǭ!N8`cC8I~c G')8: úqάh3G{6Ȃ&w GNyӦ7 Mj9R}đru˂t8{i1cp[ǖαs{oUqǝ=js(fJnf2ps-{p Ug/n5[9VVecեZa˭߹?Yϭ7V>r[yxrkAܦt9mvve'romܶVn/q]:s+n[ܽDr>Q(7s:7f 7Y2l-[uqN=帮̱sa%G{QϜ9jX0GMyǑmܴRk'=K)r8beL6䰧=y^Ӗ s'' ,zȉF ֱmY5ÔIo Q'6E}3sإz =Za7Qmȅ2Ѓ4ߨ9Z:2'`l$zְiwELY05,5,ua8vp yD Cm~'r }i0#^s-hp_qؓavjd)/ .Ucg沋Xy%>c 뚏`m5գ;jzYk4ocVU9Xϰnk J:G֔݉5mXs-ӡLsOaBVƴ}n b0Xb+ÙWX˂UˬRUY9+|:X5d+!=D5l=zUg35OxX%d&&yʮ8zYm9x\394 Пyê8tdqB)*HVj&V[eYun$}{W^g-Lzi$'uҘ>@rmKz Ku9>H/:u/լkaц酊@9X66fUOf걬T<WYfz+蟂X nVY5)Zz+K4b{X뼞5 3)_2u9T:kaZ/m~&0{Ŵ/ߪ`4OXS:5o2Mx 3};dV*`~Vd.LY1kUfJžYX   ow+auVuJ6XQ5ߘ}.`M84ptbl48FrgwC5вw<s`ܬāe䠏Sa;p堲80?W$a}Z @ >؍C&qhR߱^QW͵9d90492(8s·6g8po oُ9MoA?r8i As`p8XqܤC7io5fgߣ,Yq˚Xe?0-:~mدF"3+>NbEmVzW}fR?%wa1x,hƊ?Y1y8/J`)_PȊF\~ɱf(k~ob8F=ܘ}Uʱ"q> +LgB^ai쭸.9]-E>E8{`/v}:p;G5"{7fG۩;{OW.{͞{Y9{*gŭ <=d7 ǘW_1z2{^̷>I#"{=Og~?7\`7 b{:@{[˞v?3{=c dݛžeO{{|ƞ 3?{͞_ث0Ձ!{qUi{y^\ϞXה=`+l%{meO-ٻ,c*m}G5fs(+:Ua87&sOt}́rТl#~ѓCerhܘPGj*V7`-V{dAν%ʰzgVWGV|**񓕓CX"ӼYY8+aCIVJM[͡ˑ84՝CWrGQCѥ8zǡ38H/8TphIC3Vq#VZ9¡crFy;CXsH|]P8EuPgsH\F/4Z!86իa|nnq0:l]8Wg'jArp@~{r5|v߼:u8\J9AuϢr瀟?[qdԔ<ȏCp^Z67m+?aU%_V9 ~yUz*7+OYM94})ZϡeP#O]Z0C!q` !R9$ ;$ 9">_wnp\=΂^qC}j"V٬l>r:V*!<:jng ᬾɯ4Ӥt&t6JgMߝ~Y;)2 oYun.ɏuk|\ߓ枖tf5she;-fKz|fYׁy?oy .&ߝ8""G∾9En(G8vjRq]+{rt}1%rLY1c؜ cq޻9}ǩrʟ=qܟ_qwp0o؅Nx~oԏûwǝm[ْ7&Nj?{s|J)Wqyǭ÷㉊[U]Mfɓ9k/_9~[?+8~ 욆oi}sy3X7p߼:ljv_ǽ][Fp\F`L|qk.r\pv"Oڔco394c=X3 :ٻn}{d,U;gaC^Wqڬb/g83*yCϞGBs}<==`/7#{g//'/^57x=vf'lx^ ϰW? crk:ږc7m4pugo.^l^GBfa#kt@/0>\f$5{KQ\OUd@k{}6Y>zO4iͯ/fZ/`v>d)QU1=Wb6+{lb!q b5RGvp'gOvkva7Ze?2v]:]{maW>o.6K=v~0켸;84ힳTvzއ~d2;=hN7ӹ|v[S+Џai_Dev).6.ir6esusv]8]w1`u- nۉ^2{]b>}uOG 쑻=n`z3*{`ymG {^]ƞ_x?ry ~ bcH jsc**a}3_<|:{@,Zd.5أ[{s=%?ɞ%/{UĞOA)z9ʗ=fPޛ=% e);=ԵأYv/7F~o#߳nJv3f6&%g7d7wvsbn.1ָf*!Vc8Uu2U9`>,e5&Wqw?CO,^w3|Gm;m엝 DVtӝ u&7r@ڔq cɁrPX™;݋Vt*2>rPOz'86$|(ͱͷq,b{D?ű2|8k6L\1nsqҐcOG;Qc߽F+q1 qJqUGpG=bͱ߆cNc9fjrcp̹$c;r~6ݩ1[l1ݟrLn_1=arLYS>/'x?Vz'9_2d! 9fl1 s]Y8z;UKsGQw9y]8)zn9HZQYuN঱9bX6W08"r-/Xܮ;WKf^=t+SXk&HV:Zg0UXU5ssp 4̏÷|9t3׹G7w4eYX}X1v6+ƴ`|Xqp1+ +vf<\ÊEȸ̊1'Vh~? )Qza[VlŊ!Ka67&+pɸ4n277YWMLi$zݞ|Fq?MFL&-[p{IP79uB9|cqOÁ+;^A qL-AqЗQpH=>W 9ظГ1.æ9n2%AOd݈fr[~_{&}]ϐ[q ڰWkb/iaϼdq\vSdmױĵZӃf/[5\!rp47W=X+ઞ\e*2͊,Un*% JW\UVuUJp\V,W YjN\mۍ=^~wzog>tWkp5Ǹ6 ,5cl5KVCy5ZqM'g} ٪h[5~fm\s״5Ǧq#l(k>5;Tsؑlu[XV?2xVkUz#{#cY[ 5^}b2l(e尯<[[ĺy f9ا5GYsSc\s#lk 9NrM{#[}Ǿi\s\؞ qy׹&T͞uv =/^N v_}Al}[wa)\gLm6oۚTlt ۝ẇ۲/l(u#rSչ~ _"w'5`|n3.ƍܹqٻ77v-^r籣ovj>K-egtŒrpv],ʰKUv.V7٥=v9f׆5>]w7ev?]+uc3v)qM9b;NGӓtq;G/ovka)0f;tپEwx̍onnk.o_ga܎mcGm,;8Ȏײc# ;+b'7;'`dvf< ^}>v_o cDWȞa/ie]^w&"OTqɾVw5gԷҞ>\dcٿmM*7&qܤ`ԫܤ(?s}tfYq+x"/+z"˟Ƶ_ +>:b?_dkc =~W]7f9yvJfGvGV˜Ɩg`y_#'8S׏p.\oK[X3 vVzl+m[v˶l3=c.c׍K㺋rM_\wX .ކ`mh \ǶoVՉmTcg[6OmlӶ|:Wχ\)|qk"nVFx12kL-z ԰\8 n_j{qGڋr\mghUL*᧸ѧ\ybWŕs2WZ4-Kq\ Wx?+|J܃+ SkqB#\+_Ur@5W}ЙVV9-׸pv\y/[|˖rj_ɖ/lR)qX׉u+9z'R_M:H98Cj[L;Aΐw|4|5[짯S{8Ti& q\=V.b4~Y?\'_x98,YšK8 ǀ+c 8yZ\۹Vwm=wcqSҦMx*ħCj'/ =Y1I|DE0 .EF/z{%^<&ZK Td5Y.$R#AwI$A DB|$dM XB:D0EBƋdTD٩HTA-DUT"Eu1A */T1_hxQ=x-HQ-d7Q]="KcEJU>Zs[]WTETԍ: ؋ʶ]գ{zV{E5Pn=&G$J m?nCBjQ+orR(Glڕ% w#DrWB$VT?jQv'ʷgD]&HTj*Q9"ꦭDݻZ&4gP=P ʹN$:s8y";Ny9RR릨/6&)(2V>M4n,hzq@w5l󅢹>J4w)Z}hfmj;%:Ef$vtpZw u#Kh^~M(V~M?*.] Oi,|nPAq Nl)\kVdaD)} !OnLjItDQEW6tхyV֯-e:sWtDF]o[%MBK Y?R/ %=EiE(l-tsvc jG`99Hh:t.ڋmnUֈ0Q9!Զh=MB3EmX4'D \_c/+x_8nu,Q5WmՅˢ/٢>\)*ʜz^-5EYuV JBzGQiP]7Q= /ܒ u&I$Tw_BM$Y\T+.yQUM.%TT #.jY < -!B)䙧(ˉRl>DWc%݂+#rEsUT6D}骨v< V"'.jwȩ(ʄ/nBB_0G4ۏ;jEhǃ֢nW$/#_E*PTe.*:#TP4x(H!~i)J\vm셼h#SnU Y(4>YT-ۋQ|@ "t(W',7| }B{Q3-|.GQ;*TAO -4_J9[4 P37к`\P~qkvXԚ=&ꉟ ulжn[u "ƨ%*j8AmE}Rԧ7qBe^ nMAm{Ee,qo$t"d?V;6b?RK[m8o_GZZ1jkѨ :Z\/hNfF &.D q9Q4qRG?tѼ| ie<3OP4UKv6r+]J)x+t^⹾kCYDLDh;mj?i'UEWn"Ѯ#GG gG=E=|]t?'v\+rZ%wRX&YtMxm]gQ7ԛEKw#WBmm<_ [l]p  Z!8. Defi< YmwnY ECnhvy(&׷^.3KnEj WG-O]Nq 1WtSt\OwM+U['&&v7܄mkϻ% M)kԢ{q:KXm A!XHۧ"8$'p^I&>Y]>$}WEphCyepeh|q~?Vf_E^*dEuUb%Ԅz<:JB OJgQ%8_+E(-* {Hh)q.XE&SvAKQV*]QQ/+C=Ś]DyJ!Vy-u[rZ4E9PBG(OQBǴ$4/'K(e` ȗJA5P~6SJBfKW (!gDBq(JHɫ'A? N' nDB%x,!K;JȌt[6l4T4>M'V;$9 ڋ%AwKpTQK\ IxN (GKRBG r@$7o.!&ʈ2ZBãq#~okhf$÷]%طn(Iݣ]Үoe QnJȍ g6ΐ]#ꙫh֡ge-D] Q B&E=( YgH/~D3YԕF7Dܭh;&Pbn c]_trEq}7~nGpPFuUI~}4 sD-ݯ(7;yR G'{E*zp"r?H"_ GNiAĦHm/SD>Rzl1_Dkǻ$L$[yS[nHx]_o)%- w-M=%|5()9$"DzSBbFg4|Bw?4k_&OufJU6]3H?i4+:9bP4+-4ߥyii8[Z*-)}z\TIZ)-7JEDi1glMZ/VKrW򆳴&-Vv$-?o͞IK{?ՋU&냴VSKۻUj*ieL6n@(甖gH^~璴 mK ֳJ7oiz&m{6Hv&i;s_چ6]kiNkI?}O+ ^y^: &CV:YäO3pwA:L#biomGIͅigBNfWZ:pcIǖSkttnY:8+3+J:淒;J3Gt: ]*.&JyCF4.ҥq? KD.oC)j!]f)%KT2t;P~astXW~$ݪn.],_xt%] 5ME?/==t$};[ ]gՒn")?^"K;>MJ1UgcC99t+%=/,=mI/N6B,Kj ףkLm+=ϑzIga- %aee~1USҧ2X9!;ϕJRp}$7IomgK->g}?Y+;YE$Ȉ2E- 6Ƞr7dК2+)o2غ *A2h`\ _Zʠ 7!re 2xJ{ RFu?( +dz MƅMdМ)20d ,J2P-kȀ@!3/#kH%)L|SRJr]BR=$MQzI] Hw5 )ǛIJix^%)["$P71OR8H *i $J#IQSҴ.2btI;IF*HZ2C^$UyRF>3ed Wt\JK]CI{FFXMoK$%䠤l)R$:)eļ$I[MR-Iʘ˒vry]%9 o,io%-ᗤ+#so%m%񭇤,#ޖ %jIdġ&VXyYasK$LjIGlr #ߎ퓤$I%{IY'I*H$J$|$+ɝ~6JNd.2c$.}dxQIJ(I7JҝQxQcwoM$- KbEn[ROJf4I< I=d2|SIj WHC訿Tz$Ice$'Ic$Q$}%I#2liIUN? [oK]EI\&haH[I#F>`  aNJⴿ ;[I*$jAX-ϗw%iF חq2l d*IEe*X77FzH(p!2 *I+$YDW%_ݓFHF|$_Z!)33%CçV8Hdp!Jʲ'蓤ǒbKFT)}JjOԧ2qN\.#5$%vٍ;o8 HjMybVX*)2QRnƠ6!wtԼè\KRNE:G.{kKZ dIk]R %%e I}QLI())iIޒryJʕE顤A"#ӫHGiWRհh2\3T/cotDI#cT1~U!T12Vy[ҫܐ#H+d습2dKel72{6~Kz'$cSV2vR%I/!O?A2 I7zJy2vF9Vғ$t/pQ,ccK@NX2 ow^[#c13>,(!x7u#c]`c?W+c3ؗ?KJPGuI)6I= m#twIIuWʸme\2ξ/?Cm$[q}%-ʸ2z{bc>ViI 3yi<)UJ(i{TxrV5uGJ;*ilH$]B v}J]B sMJ[m~lioXO/&K]N_<'H-#aT0꧴S?oH2i߼THåBt|v(̓H'CO/#wKօ0i&LCi\[Ǿv>訴!GntXzE:T ]:8=}k{ptX,ޯFafi'A:'ݥ !;yHUҡz[i]:)JyF=a;ﬠ_ê>FksMK'&yaר+oO?et˗ò8p}}'V}Io[K:FP jB;]9r^sv=-宐`svR<.wz*wdIsh ΅s;rGgޜ9"'m^mc6-9n#u ug r۞rG?[}z.MRnu.}vr1 +7׫#.7֢cr9rurӵrsrӵrDn6:#7x)7#7\+7n Qr٩rrCJ+M2LpujȵV[]rmNu]{fS:L"n"ׄɕL\!W*ryRO8L@n/W4r+N5+t 4\\.[*M&.(˞KORE\z\6k\z\.ջ/KK˥%kZI-isi\mKKJij /Mi')e\d\2P.m`&K@i4%IPkif%͒;%-U|X+pK~_fZ忤UKmi64H(fJӈtiZ4La\29E.iUu[+MKL*>rI?G!HKzoK{֑K{ f'~JFx\4KHflnޱ矗fٓriT.YLH4l4 35xX^.M& rrArS9<9u9;3j4N>*ɃoczHv?i4- `9@ g$gUϒFЩJ6[$g6N}]^K0'RNn. ߵ.g+Ji8ImR%ozH3ԯri&Hfi84QΚa gh.g-J3J_,Bi\}ș/șokY>䬼 i84j, UriC=' ?ICҨQբ4<(gݎ0:S(OKz6.gFQ1hZ&~wJ#ӉxdiP1[m 9<9SU" Γ!嬹 iY;ήҤ9}W{46'M2ܤҤQ gLU&lI9Yit?\n9C~e.g'K㶜o'g/.M99nr<9`4&#J$4&ZIIh@,s~-X&KqI>3rVe{i8l4'}"r.w_o/,Ο-{|,{}fN.^e_ruuzeA&{/X'{.{YȞ/ʞg$٫SQ {ݝRe/)ded}#e_![v^v]n.~.}.M4sQXM+;o!;{Ndeee:CFqaR١iٱ\a(eÝiCu!\vjKvZ5eQ)\)ۿm)-!ݴvmB^uY,l.~ Dz6 9/ fli$[)[u-zdMyalQ,.sNi>l>lvlj[&8&YKe3eײѮ|pfHlL6J{!VF:KR߸_2Bo0K;UkQ}G֛,k:"k.kU5ddee&Rbf-e5R=I7%.>* /^ƟZ w;(04αpol0&a|H2CۀR4I TUL)9>%k)} )AH5޼Ro6ԛqHꭿ)ܒzJw`۞/KTk`ԋ ‚r7m zRϻLz{/z;q'w3³H={~QQyK@UITp;#m֍P6?ck,?7e ~lq ~ ۂgi90*{GXT&?įCQY]o=]H.ǟZk~GZʄxn!Pb*CJT˝Py!(Q ~+>~}M׿5w /ISO;v8|0jwxg[Z[hOG?m5߃th ǡ%݂mOnkV, tu|-m%%P-muháQFmڞЎsvh7hW@7ˡs]7hqPeʝP~vʓgݼͿAS;fGmO? t$46AmՌRelM7Ջv_F*JP:xJ.'wD]@qlٮEaL8 CM=CQ^(GQ EZeYx[*P98WQ21JVEɭ0џNtkmλJ@!/zBɳ-}< t/JC9ʪ;GʖwEeO0[@3c4;25c-B*8h&46Ov\߱&c+;PvMGgye$#h? bh=eМ{Phu&t{Aiu{oB7:,n>n#Zso] N>CA&&D|3ʍz|@t\P ]:OU$W/Ю!vJ"1lhá_/-_9|t;kq{.ӆA m~_BˇNt ]'s:#Akڲ A[h*ylB M"D N[&D Q33ba!{%Ѝ`^S}-gܓb"+\M>W@t tsB7=qp(t;51tmbVԏz.]Kl#>$NEYCGPebYXľc;cgN:_Q2/NG@S8o mcoЎ%1GsS 7m_BsyP:k)]" P+ba}žpe]qy1Vmd!.jPv?hQĉ,b7MicQIY⃲&('~lǾO Tn;P^}$ '"Lfg~ωЮ0vhkdn1BA'̱Vˡ}uA(?<姆xo}PْTLg%@Nݷ Y%@W-|.Ж~}Ú,`kYK5mr %?3'NX@;hoh8USpoh&A MthLJ#XG+4 5MWY}? J +Q?1&}+؊zssh2](e oQ6eS?MZ(+ğY5q6VcCumǓ] \C~12\`4V Xw[\o3mJΐ^-ycj nhEiĊ?ٓ`]skąMgpD#(EJ{sVTΘ +Bdžؖ\SE.jxwPP< E w@Ѯ( f(fb܃Q(&(h1  6Bls}QPi©>(X =P`; *t^(ª(~EgXQU(P3D(܀Bkq@V((E&u^kzxc^Wե3xPWG_xW;jqB'"o.Ds_;_f_ݢ_g !;yg"ܒP޹\>x+9󐓑kK> '!9ev9%?s79{99h̺YN޿k!{z#dutҹ"1dyuFGF2S<#ӥIYFu3ك ۱ O"[[ .{t;KSӼ&-)Av31AJd8Y kd8'#32ODfD5d=i:F 3d6.@*2N :2l|'2f#cnd xVgh7v@[H@_H j!F/EzHH@?"=6H?!CzE (FaH飴H=m\R-ifi/!u@QH}א9ں!Aug"{FEڄ%Hi}2is]g ^8@iԻK`R3lZaHtiCoi]"v[mא7RKw_8 i!mNBWHG#H[i"miîSHk؎ήHxP neSmއ4=OQ'7Bү ='ߥ"g d(SAȈ)(y/]Yy1c sn=dnܾ?P6!se2T s-dκIi G996FȜr2YdJE&{qP sL 2'BL_|5Nsyh2L6~ -<7s2"hd&FE[dGp; Gz/Q縶ȼרύ|Pd}L/tYe,F k)z"kd͢fѧK kQdA#.R9M=k3רKS7r:V"GTG9e~[)ꀜm w\r>#BC9{)r/Bn/Eo_|B+(+rgB?Rag*rC!K3E9!-9w}n3rSD3OM@N}){}9OirFTܮ9^#rް眿9S3|8rzJdW!# #cVdoˑ]q U>+1O#N 덜NOSc~(,/ ۟=gA{k>T/ÏjNL* ~"sM]7{Rm2zN@=QMwnQtC+d_6i g#-Ҏ&.g#M@Z3oS^3D)Gla^H)B9HUH~ɧ푼&C"~*^~R{/K 2E.x6/v'͑|6@HޒuvH^N"yv%'EH$w6\:k/m^~Vxj1^f7g,/cfߌ{nH;ϡ/,BrIH'f"yI(w!BL$vH)&"eO>0MDʺ9HVAHٷ)"h3H\W"5R[E!̼])})YӐ5Rt[Hq#\{R$!Ŧ)bA>:1FJDJZ> o:R" B+\끔 *L@J&Ks/RKw6HIKĵXc'wi;-)/->) =_ r#R EHJjs8HYJ͡QH\7m(s߂;noCGH{!RtR& uy*K8}~CZt߂H6 i!m!9ߪÔ3䂭;%\n lfi' Ϳ?.Cs[i"yqHo ;#]~\Le!5B"ۍ4Ffr5 v&yw6Q~M{'94D&]r yhmC[~ {GK>Lc HWHRE\fH]F=>ї u=/!$xFԘ|/:}G7iA΂ÕH'7W"mY4HE^<EpZg{{7R3ޟ6דyʞCWCߛ,d_yAcz&RNv(}fsPG9 a1 #s+ֈL6̃y&yvlDqt9wҶ:"͔L=v0W)wr^Gg,RB6=VHu/Bu4%HձUCj1c׸-YI]?#͠6 8T @jyof3Ϛ"9 s^Ro.|Q}d:R#!5̫#ypaތq?1#NH ː09J/<9s1+k2f96ǑVm.k6_9}oZ5s֠s_#ƶ ׎u:3/p?lXNC.憯Ғ{!һD:y*|eȨUW!2@FncugrwOdnڊL9#3#_ Dd5ߧmur^a%N!?Bv&_ǐE [E^찗Ⱦ 9#gerȉ@γ)ۏZܱu+Cw#wވ^BSyC"Ϭ y yÐw>r"Aw݇|`+!ߧ#?eUe!\둿@޳4{x%B~u7y;yv" nj,F޵sEs /3yV eE^A,u3MS)"zj! C+Bx~3^)ǫ=9xկxp ^{|WZ~;WxUu_n3^0z'yb~4qA܂kQpk JSm©Ql ۢ6{a. 6@Q("9(0E(rAхr夢XOQG@d^m_Qlŧ-燡z(iv%KqJP5%gi&JQZs*JtfZŢ@mnRK(RYb^5kQ0StXJnDo(+tJ:g,<(9H} %1PRy%K.8%)Q2GIG3NoģE4JZ B.FG_L@5;ǔ88C(>:=A)Pxgm-d+J̖d!J;QrD6Ei/(]P:̇-Pz3JP`0{l]*NeS?9 ۟ mK^ Bh/Q A7е]|5nlzhk{@7tcӠB.߀t)I=s@.P޺Ǖ|IwRQF(_s_P7\Q;ʇ ݩ͟C 6w*= ch;Ck A6~͏6dCs41@ُ:(؄z(`Q1pGs(b"Z"(NQ5 ߢ3 /$zFs(Ba<j^r5EQy(LE-yUOWGQ- ޣ;b (^Q(bg8#mDqVcP\2odHі(TQҔ[]AwR s8mw>!a-(;Q9QQ3Ǣxܻ7@zaSVf80ޑ5pN|OP(~%uFuZj(Q %ͰJmA((9ڒ5FL)DIdMBu#ʻ_H@y\Ay3(_,tY]0qls11 /fw0Cχckrڧо86n;tf-tj0R}K3-!CWG]#ͽao]~P>ޡ|Y{o"~VCyH AyBC-(>OCQ1 e(Olr6(_FybOнO Mmj8xb?ś~xE7exs4<7xU7ex3?@]|-}>:x tkSsQ»|!uf.)ʛs] ?$Ә u>/>RƛM&o*v>3w=wuCpN)~m?wjޣgƇyV|덏+u>&\:i"|r§4>MO93|>*3g|- 2Bi X ~o'Kn}~h~n2O~n'T@4T'!TƯ}; MB[o f㑄I/7ChT_3錿w"?!O:je;eefe_ֲnJYOSAW?H}Ҡ@dAH@lP6XZ68W68gal`]<. \^JiS,?, ֔K=륁4 >Id4Xm4XWL(#Kϥ~zk/# FQqR߽2X֏- o ` V[.'##pT٠@68.̼'z+ ~ߐ jU@PH 2@KVH)&ҠZI[.?I;~j-*V'ߒʑT o"a$|E $2JG$.DH7'mC\$;89lE؁H3&w&"q!$LAW#&)Xb;g?QH: ~:^AREHQIH:I6 !~|,g"~U6!)"> ¥i3p.ťx-. (qɻ.yK:d G؆x;}ox3 +kTb!.&qc\\剋p^\l}( sƅcpe\( _q! \_ pI\g.(x ¦!".l m\\ >/=1cC5Ώq5[cslwe=2޵Eܞ㈫YX7غsy3b@̾툙71 fdbF#eĴW =YО븾i25Cb:z!fWĜZmeXk/z e&KZ8هS)[USN],D[uu"QW"(DMA" zpDuQrD XH DFCUDƝBj2>UYd>F|Qz5- DԬZDmXzRV:WQb\.# ET\. ETTWD%ry95I?JeU,i3m-"7?"{Ro!# Dm@PD|3Y Dܯ~ЫpFN@_ ì{"w_gp 7yf } "UF{G]BtFtDE@Բ3jSy#">DԚF@dwD-Wic{i9,#3\؞ȓ<^̽<2Fޯ|.F_("mF`DzYZBq?>1"!D0f5ѧg!}5'!Dg!$#KrҘNoӻ+XfCb/"|C!M Y{1ΧbnGLZ7E_b &i(b.nC̋y21A&WsGG1"tꛁiWc!v^Ğ;GnOEd]!(~bnB\OkM>8+ vA =9xaS)tcw1jbEl%C'bR{)k4q nGV$"{YOSҝ ?< 1eS|zg5Z؝ikęElLlOpvN88;&wgl% ۇ㬋g}dժqN'ε]s5q:2^pn\876¹q}n8qsO7rC\]F쩙5FQq̙[s{"vtbvBkMC\wkʘǺz< UA1ӆyuiY;mzf=3#C}D7em"z?Ft`N?D]^Bls&#DXv+XKnĕ /_ 1\7'!ڕ"RUN)uEBؔ[1v Fk.hyKika1krf_{bV-h E'3>&}}/c1n5C%rDפ #.=#rb荘ȃ:#[M=.C5r'J9_XiG]r_};o ADZps\͗ݔ&m-"+ܗ!QD8^ExG?.#*"vMB-_8V]AhuU!kba=: ! ;}ws\.u l3^J)^#NuDL OzK"BP\kJ# =7C7A=O pPC7sAG Ao#4AXAz"=tGR>,@?0{B.G ulV?E܏K0_5۶ mQנ;To-3և _<~coPyVr~w'}9HWA𷲇6&L5}F E"꼆e$Eo߬?߂} >y ߧ}hߗ%_P8ޫ[ owo va-'c||tq<}|_yw:|>Ovm k9,>'>s|g'q@iLO lSg}3Ltvom5x; I-ѩ9 k}OJ=ܻ||)9K$&ç`)|^ >>>M/h!|Vgb1V=q&gLLkxUכ10^𺯄WOx׾z ^ᵢ6 kR]x5>^}U+oxxjs kvn4܎=R-7[՘ײ1p}6v5l\CsxAz\Tu*|!\Lޞpkn&Ko8 G!ܚ[ [pk˿3VkOSpM; pI:Ɓ:멵pUQp]xVp5W6 T9)b \Gu\ZQ=ϛׅ4uIZ6m0\! \]Gh 8TgR\՛zӸ{᪊݇A&|Znq!#ຕ>XWSbeMS#p>3swMXvC-pk]6Z%\ky6׮]:16וhSΣ ພ>]wcC"!m =pK ݀Zp{.6e6KK֟ O\炓ph {YpNsE8 LJ۴Ϋn97+༛[Ey=쥂sH#5p)\uK|LzCb.h N׆˘Sm\98;|3Sw]T gs8yK8s͛pNYkN t"NpZNR)q6VY86Ӿpr)0N̸n9jW8 ~yX _auIkw>79`'~|k~p>{W9?9;^ p޻湊Ip^KvpnrNTS'8P¹Z58Y:o:MS"8]ST8\w# p2%ɿNii};6pF{ӵp*]pnP ƿwpLOpX oNnC4ҷY4" NO>-4Qiv91;z16qN;9.,S8}g ,83fi~pzNy釕pzC{i1|)pj<>T3NEVe8e~J!tvfpdr|%p<GpNNpS8=}_\ k:νkya#džù'ks(aM΃s?8wĊ\. 5ےЅZԂ9۹%k~u޳ iX }3Q m{ʜ܀SGf5]C|:CY7pz69ېv.0n"O8݁±p'tNoӯUpjNcsᴂqXNprfM^gpq pBV?\p>B\t{A78{0s"}j8]'bD͘wӗp gXm߇gpg !1N}DSot1_KplHޡpi.mhϏxq w`|mἀh.{p8pY>.a|þpW pf߹.%ً :r=\-ȣ?w_ קpM5d~4%ޑ]6~,ܖMU nN|)ܞ%}:5Op7hs1{'˾>΋?^rb^0]汧\b{= X s!#m95 p#W\֒xߵlOX<'i\o%UFp[7rbr$?e p{I; œ{5wp Ӳ~smAe"wј n|5p7pk͝ɕͺ\} yB=NWwm7skv3g3>;mpK=^ss+[_{poϙ8-V2w b1;8olǻ931āț[^WS eތy23;~1iv(z26p.napc1Ĩ'!þ/<ػ<8]le+1<3 ^^(mu|,kdx׋z%Ut^aVZ^u*xzaxFgI1y9>r|[|^IM|wOoQ*|wk|No-g/)wߪ+ÿm7EKF` C,>,A[A\ۙ xtwEp@gG n DX;j=q8B!t8F軮[1aS0"C< aG `", aIg@>b)G%#7 FxaoaF=Cs:"o9B>Gh##=:#l* pC~B 4(mF $*BFƧ3|ioMDHGCR!jqF Bd錠7 A!h/m|\t;ܚw7Es^^M|"+WO noe\?z B kBM,펐za"(;CD*D4DD3+۞7=ga*&B|jecjZAq+~/2'ls&jY0D#n4"@D?3DCĄ{`XXs0=kqz+hU]p=ƹ1nE0?~Œ(c!Gº298V:B[Fȃh8uBXbݻF!GЍvC A[<A%O\s.[GgOi|X%f\j4By!dx:B9#dQSA `UGH9EN:3z t-Bͺ!tB|F0 B;[&"taBO=mH76B~C] Ħ!+3s2 Bz.FHIj\}?OӎBU+lH H{["3!z]5e7CЩE2 h  ?'C5xx83/#B..r ON w5F.4@H^p;5ErC+"`U "Qc&hړhYmdz?_;~[V<~=~w/u~~Bm <\?׏;[ ᷦ 7 F_|·_]z~m|?u|o=s5WOK|~O\| }/3f|j;>=}1{|.^ )>a 韛~/n» o^û?߆Oi1 >;g |f?I3,A1cϚ Z~|Wz >9)\w)᭹Yܓ}Bo~w%~-_:&}=.~́dϋOK_#w3n_[V335/TD@_̛>̡i-`̾9|sjچSG(c@bUL%62tC|F@_9τ 0"EEOGN}sB^ h:+<=k ~#p}#?X@7~{:A?Ept=y A7K^WjUAuT[{J! r{Sư҆Be]bO-J BZ"DH5Bt%G1e!|`;,N}e"^?@NtYb5{Tނ>c 1V^ kĒŞاkqF5wr)>8 g98WM/.l_ p'.F#~Y `0.]ƥ\˭Sqy.Rg>,m+p&\]P$LE.HX n򝸖FHLjs4|!)p=z!~T'9@qs# qspܬ37Gtiyj2nnsq-ndl;p3uÍ]1+7f'Ƃ6Wm13!$x8$]Zh$=߷M@ҙfH:I"i\8#-3"^,W"!ZY#i $uaHZwI1TדOf_6M[7Lnq{n>ͦsqÿ)n~U;p} \sp}^*/H%q]zAu\?cw&>f4ͦK{Qq=/^ xEy9YJ%CDQ")pJ%B Q)ŗC񦜡xQ<)?#n'2tJcMN[n)ePoIP-ܻePoCIPfB=7ͧ *ePz].ŜRGҮz l^]HMU')mz%rP+޵z-'K_Pf[BmF?qA^5Ë́z.^USy)zzͦmyPQ 66d|g};zc5L _B-i WB-yB=P]cSGѶg]TAB݇dt+]Ŀۯ6̏BP7) u}֤տjB+L~LBiPKBU TEBPXJ-ۅꮫPݼ"T\wPwsY"*PʷPy*ww*~BuPz+T+j_Pw PY*s;ڹ@jk ժB5'Dl_fA,N|+&ՈĄİzPojK&&Nj%ר?,jBmOlp 6<,ԇkQ7P#(((h[ =rB,?L,=L?A!$v$:Xl=S};bbT$*h9uol؛( j*_,eBXK);3w꽝vl#m}D[=ύ6k5Wb*b3׬>e('L#י7;0>m!/`=}.1}nGp<{{}bLdS 0iSGmc2E^@N6 #̙owCB=pPO=wϘ\ӆԪP7d2cڔBC'T߉_ G⧎Vz("6fU!m#{=3G{ă[Buؐ0Y.vϟX US ՙUBAs!v;F*xugC`عW{x-qx?3͉}g O\I,=հ]B5P& u9!Tk U[Vuq{2`E\G( BsP~# ;BI(u녲lPsMPBAId|M(|A(ByP& eBP^x+<_!g elKJʈB6H( e`P?J߻BM]BT(=K(]~Fԋv|X,N i-5E({>ym3B(p %PGI4+qNoK&P^YIPޢwXN( !cqxoOlƸP0y+/X#E[1V" Ƨ\(߷g0v/u"D[f^Y 1;^(1O07kx1k]ͼ*}}!k1s {j3kmn}9߮͞X:~;n;k'{Y/>'AB5k(0rX7cɭr,ՓOa-J;uqY#F&#XW-`/bO5m,Tf<{)y9n*޹k5zD]ivI\4g$&!Q"FP5{^s8f#TɫӖ#=ǖ ՉBu\8}!3M '-!o8J~J.tg(Mʟ<4v$ %nMp 1'ct>P./ɏ/WC Ħ7zC }r䣏)}LMJ\"Ta&ypyRZb.1.5)`QbTJ^WFRzC^<}g&~~!~~0?Ɂ*7y_Ʀ}Eo 9B/&㰗fۗ3J}}r'尧/7elfs<}״zLgw 9ҨY3y0O3 rԵ>;Κ=*Or.̍N=r6-ɫ3fM97 C}SE$n%.fə9E{ykr7Og}W>{;k&Z"x}BNu{~qm,gBE '& &νQ8+p8E ;NnrŁuSL!SrN(W 5`P1/km Z4$ io}aBY=[(BcPTOzBN Pf EQwxe%9"PEP<+^-S("X(. c\B=B("dP BY(< k8uE(N#|wY( \P `,nBH(b1Xm"+ ]$ !BaC(f% }B!' B1P%zŰ,̻pmޓtk#. EBњvX/M EBQz.5ʄBoTVBRؾ)ZCa[rA{mv͘.lS틖~a୰X޼'l ۫R#a{~$l۰ aÅgu*l[fIamk lWj'l |ߜl7:[uB.o"lN E<=53 [y_؊vBV؎|/l 5mGaۧ&lo v&¶UmE6)lWma[ l6?ooB|-l>L6ov)9'l { |aJd6u ;a䏰yh-l~66a0]\:/l.6q{MT &8T6>kMaN8i as踰 }\ 6Մja뮰Sl>*lֿ6kf Rx=skffa3Y؈f6a36O،26h!¦?ulz8 MGiYشZ'le 3AO6?FX0].o" "~{HXYu~GX?[+=Na}m|YX_l-*ut(Cu?a\X{% k6ZX; ھDX'.V+ 'vkn uRcawOs kzzWa=NX8#u!º*aݕgv$ UºYga݈:/u,ucª_X ~VFX.tUi3aUEXVU aHX=[' {-Ga#F auV:aSXVWOa>BXq^:9_X]#V=J(;j{\,Vk +bՒjϛ.L̄լmj&&F ׅa5TX xo6ª[aij{[VVF[BX9,j ˪a;^Xx ,+ a eZXG W2LY ,{ 0ay瘰Q.,+7ePay.FXge(atGXw9XX:DzaKaTX , `!,- ˝rAa\.,+{ ˥t\{ Ka K#,OXV MrWXhgCa١l ,[xv#j*,xF¢jVX|&,_ B7ZX Sa[,, !"9KX Jka~_3// so),=섅XaUX^XGÀo$!a:MX\.,CYW!,/ T::-~ ,47 +w/ bRmJ²a֪l7NXvK,,{ ~ħAW bnVե*A|&1Vja=NaCX5V{"Ro5gor#}u º!S ,rKc%~[IIXʩ/p¦ aSiD칰i=Rش6]Ȼ{l%M6 Ja3LL*ldKa3Ü{6 ɫ2ɳo6҅Vr na9E%>I2Zxx 3 ݃ rOas&I(67? ld}a6敩)> g7#g#/)ۄka[kǙ(a۔VNs܄mz¶;߄;Cv$׎+l'q6g--vap%gvha&3X}b;ak9sg%u=Y\-lz ۓ8q]g [n6 @ΌQ9r>LxL&pN3o{#~!l_@a3w<,l5da:~V__zvm9w>-\€q#Mr%> E谄3/z\(zE9*-9S B1P,66U(' DB1l.S9O°P  Ӊ3<ϘrݢKBa:_(8/uWD Ū ZSXW"8o&BWAQW(vBaN- m.{B](Tܧ. b=80L(¡PT!}P(^㭅,SR(h t)nBA=Og !>goPBD(¨T(b܄">:?Y(.^ˣ H~P<LJ~xg*}qK(E>-` B3S(=SP|$?X2-ʆIPH6tH(g e@U(Մr3) %*\(MrF\wf%OeBM(32^"\E(uDŽ]xI(+ 4 J#TuMJP5#TM{j#PunPQ U`tOՈB5Po T ԆB5P)TZ"T7^Bef#TnBP&TՖ BP*BeIlJo{z վBek ao:WN\SP **osMB T!B" U4us`MWյBuϤBugޢ? ݻBuY.݅zvV^XUHJi!~/Tٿ* BUQ"dP*ҩM?z)TiBX* 7P~_BPBUU&u;B]sP:#uj u]B]/GP uCkZ_ꦍ:n~I[}+o$m> u;o"JqZ {#D{ u?[$B="CB=lP_JM|?w?/ ]uBZe{A魄z3 BmJ 6O+F1%E+ mBgq[R)י>jKJ dIMJ3JS]EɣSRi,e,H噎<1XH/=yϚC]Sԑ67?mOhJ;F1>z2>NCKiQƧPT1fiac9Q;rm{n}Z{}̏m`f}b. uRU!z̿*桛PaU%kvTޟyUb@ gzEB!R9Zzw҂5:z:-? ^xgk^ְnnSX#{YG1BUκ"~ U! P"vBº%T9{(.%AqDSxo.wR<Q̳@]\G;Ю˴v}귬Үkw=5vv` ( 4bX# -!v9c|w~Xs89c ^ԪXM+mkyl1uK.e=u`:s1O\{u`~X{x9|weߓky4u=o*C-H"ɳzXK~oצirv)q| ZoUuGq5amq/H\-6q&m!;rҞvΞBh;8-ŵ+r؇8"կ9k&:@n kb b/'o0cBB4(z]\wRvj{d^\wq]]#bDwvQovxVuI ɘd;Y;Y#;Om'sю{SB E0V7('~ VRSO 60̩mc}_|uWƎz3dz3^̉WA<c5h.I9+FB0'` @MT`@\$-IK|VL$#CEb?QHFWEm ST0 (RyEp HD"5~#+Rwn&N!Hݏ%{FD"5t:AC+RAEj*A_#:׈/D"5jO)REj2p)"u"u_3u2qVkEysrLzhaB\"+Rô0suAh"51%ӸMh h#XmO0q%QA0q5n'XNО#{> |07<"g͠`1ѧDo<_X0ӾvS b],Af| 6d[, /7oa1kPrw;sົ}ɑP a|`; WDp-ycƒG#7Ov1S{n̅w%\ uf8[*Rɱ ߵ@ U16v s`Zf#+k5[jI?-pH`bEu~o(RMv(Ri13b<)R !f RWT=WE.kHaMPsmI[ ֶ&DuA.iPCVpOu^Uc{^ʹk3}61֛M= ڸQ҆4"P!Q̛*kT|T%OUY̵*Q!U-5B-RaUX*P[T7H2A?T7֝j7Xs<0b }#HHmdlb61^[+qU/j l~,<ՠmФOבbj;Z{35õt.s1z>N2MP' C<4^c 3a=PL]rŒ6Q̹9yƼogmg,gӒZ撃B9 6I,ylK?vV@N ֕ʼn;$>~%Y++օ`mw̝:z&/WI}K].Q֥k}Լ g=YGAAɾ:qŜ5{O2gØ0NMEjM0H}zŘEўhh6yacX۱Xk/r/c#1O~uss9HM:HC!aj>LnG#|U}-~GMc}Ƒ'q԰8bQut{hR4s݂yb. "YבH\Dppԁ0ƽ¨itM_wQwiˡ|'=2 9p6 ֐֟9g^X3~_^}\˛z1>^ӓq {F>2 ą8#}'w;Y֘=cO[{mlC-UkۊZ2_6rhٜ17gMQwZ7&̗1kט1>F+L7` ~WYzY=֬.kV5Úa>} j9hr`n4ȷ-k B-aE ?7s3?7XY |Qz\W뫰'#eq=_O_ǹtuk-}\K=[øέfo^xbJn ԑe2ήKٷ%p%br}XD2 F#!O@g?yԮy\\ll=s,~&יfpN]mȟ65ۚ1jMN3GKS-ɋI r9A3/͘f(R~'+R_$f(RK)_  ]EO튔/ g"Q)Hȵ>*)R>"&*R's))ewMCEʟ[Eʛ^))/\EZتHyP|A06YwgG+Rμ%3|Zv~F0Ӵ4ky{⻧STOEI>{6IɁcu=A0!h rDEqx!A'Ӈf:NAñDANK&#<DxN :>fJ1@N Ƕ7:ѱs ~#oяq$>IN"NkvbA>'rc~et!ɓܩ,;ENQNS+NsӴtXap3L s7V=D1\k;G~'3. LH+8]'~oe24~3 ԫ7x>^a ľH\?;5-_׹u 䍳!M{'gsL$3Fɬ[m>0)\'rT5ߡf^wX? `.sx%Xi3ؤ jEAma|Q&NYEu>{:Ad'9(]L0C 9LcO>}O?  rA+DlChK1.fxy@ {ST|ϗ2ƣl#wi9yR'\0:R;|@'*j汚{T35{C~>=PjXC5|1u$sX+uccZ3{ml`ո8@5!S _t0aEed_{z}N=g {d]doEyżb^3GePPЎ?1﷬}Ǻ5h:>GGԳOgF|7or$n|e\:;|}[.^g3.?x?x^kƳe3Wqm9g慜x݂[ Ւϴ ؒS+Ί ^uk^u^uٖϷmf;ӎkמZ{e9u\݁՜;rĹ.Yg:|ܙ3{n]x+t]뾼׿W^u?^KsWξyn3}r3y~-9qXcyz(s0qnƹ|8gcy+uD xYsrt!XsḆ5ſbs<\¸,K 2esO<+eXA>L|"oW쵚;|z-sgu} ڲgn=kNy9AUQgG՝<דhrq::ĚݼT+uNoYu E>kSV=3-> wtV ]K4=5R}n0<F2RoB>NMisbFimƳv-̟E%ױ$'f.%E-a5sa8o->k'>cv& wv_/u֗ZkMg_/99{?ʏ1#9~ ȟgpj?5?`LQ#K= d}m'@coO- r2я0 "/\5> _P ?A= FͿ "#Go|I0cu+uH] 6vr)‡`e'G?sZ}}}qg^M7yb&Ojfz%ߝY{ װd,qnng}ng3ۨ6Osj99dVGY_m0a_2a1#>kD< ]Q^ G}rX1guAkq}]jQԥfDM}f̴mڮMYoڬmZѢiq>"W-BZkB"q_bֻZf=i*m66BkiSoٓ:?/LuhM~갮uXs:̧Pu˚LNV=ڭ`&h{>'/>u^տ5 _ Ȑgu 9CшmD9#j{1saL^v}ydmx|Ƅ4e2e6̸,`2'O٧̙sj66~gm6mkl۹װ5ΒDӖV́5ۚj}6z9`Kmm%;Ž\`OK@֐%ˉv:]g|u\P\+F^q>pl9oP8;{xøE^ekُOb g@`sr*Zڰڲ9mH(<< \+~Eп%D.hh1[ yK5}}ԥ瘧?ys\;Yc e.XKǨ' ΄'$gS)iw<,m:Kgg/]vt%eˬx)"59OW{"rsUkr=:׽}&9q\Lx%dTɜoq[͸Zr&+U*TJ{p;CAW)8 (8ee'zw9ww㻬4ڟqHcHc'Q3Өiȇ4,iC:cκMg;c_:9N>O?t?ڟΙ7k#Qȣ4ii-1Mc m'i4e%ReE>`, pyC C[*gT5wRO mX޷9"_n1wXȏd%c2"yLb̒X7ɡM b7)7o.\^kykUr*{U1{&2+Ϯp¾@K`JSSx2ںD\Ew5q^F_`_SӮyrs~clRSR?rV; :óo<͘ȺMx=EOr͓Iz9=A}>AM=sqt~gcϿSGqԈ8+qaÛ!j!j!q y~ڿq˞eM:cL 1]էhA4׌￧"#o$m=-v^8c؇qV oc(Pr}}cV>inj.]Ο {!qLmy$+jf?L2V>OʛMys>/^<{$Ojރ;ѝ:N1nו:J\W j3}wߥ89#s ͅi=9o9ʎ{زm [І}h͹̚iK%o:sf;vvgmԀmߜks?3`F^1)ބ 9kB 1f}2b܍!gxCֻm@~ }.+=tS]~kvd[VVrGs&g2 rHlmawu659TL>m&o661W  UZ VYJ|WfTf\3YKx^Yg̳>YFPp5k8&VӏU*roZ:X޹qZA[s,출,#ϖqnY~=|22rxsZw'˸228,'7˙|9s[`^AV+JjJ~~"VїUc3j `-kn-mYK [Ǻ\GYXgMgPfPf/WOn\Q#Gc֝1ń0&S̔Ϛ1f׌vs]sj9{6m6~ ),1 ֝%T?lE+*uῙeC~7m [dGCt8ъ=+.Nh mݶh_-Ew{-Vh%-hsKXV2]+vx^&^OM({A|$~o'+d0 [vZ9!> M|\#x=_!>qxw/^ڋyc~d-⽻Fp2C<{qZ<D?Wj⥴B*/N»\S ^ ^\+},ūx]/A<_L<_F}/]";?2I<>տI?%{Ͳ7KLmYoquy(.^(.8*Fq(\ý[iqsO>Lܝ/4V<{bA-Ĺq/Kz\c1V CEw{1ذIL^b8xhQ-b`CtVAD}_mkXPmY^\OcD}Ckph+-?yZ#fͿ-1y;A8\%Ū|+md{r[q:3]GvKͺ8}"Z`wL,ĥpD1:_ Ջob\L D/hREiKİ|/w}EcFFv,oa.uͽJCt[(Dh]!\%.{hvdQbYCN(j&dlQx\Vo+ ye֯PtƝ}7esڟF}NtigDQKTl+GrъtkEͪV6Id5Q!wkZ_Y~,^OV$kdՑ8YDI겲kV.DR]d"ʽ~dEqgQ +廓~kQ }ɲ̅kY,W3LYy늨TU{Mٲ}(0YgkY_ +&CTF0Qn/-EU-mWYfwBE,+=da'-심n>AVT^;" e|YpV%S1A]rDc1]#iEA4>닑%b?]@y$헋yD?1Q}'گ֊ѻMb]7ќl1ؔ*\oxl1^L%FJ]#_5j1X:C7<1ZP/FyݓkZ'N}pu;1-Pa@rĉz1P WVу1bv&FE? [Y83,-rѪ9%:'bE@{U9*d?dV":)sExl'Z^D{YW*Y)Z4ޟ!Z+ψDX%j \uJ2:~kh,ZaDhhi%^.10}<^&JDQV"?ڂEm;ŮsXؚm=r$Ft|6'ftDlf~[= rI-m#GtOf<:_h9[=&*7ȚE%wl':9=DC64Mv&rQ5LtǏ-#ihwσD41Kf;D!FM1+Ӽhs+/D7h2R6Vթ-'G3ECuly0[6+*MEqwSDs@P;(:*w0W d;)ʖ%SC:0OEchYb|eX32?B} b]>Gb]X,މGjh;/+҇Xљ]_fS0M3b:?K,v3btl31"Vx1w9/۞V6$1V&ǍĤX&ۋYS1 sII<gbU: #buT}¥\/J&1!f7T1&mbBK6F^?dbOՕ퍴 q#ͺٷbr\%&=w,1/i.ڋ1gH*obzxD7)hw!m q{d*.{CĥpOĵ],z9tϗGxz۩Xq (:IS]ħ ޠ!&}sxgO ov|X}5_לM<@lOHٺL6tOh['&E/[&uVdGK.B'Ʉv?d\@F&Q-P{\&G2&Ff;" ɲ䏊2kcZW.:ΒFJnW^ѡhKx~7mڏRE8qcv<(>%W.jIos@ {s! CVPx,Eo^"Gn/2Ox a_*.ƙ=gN/őhK? eF{ݾ={^z/2a0˞ SڟvP5xwlhXlNa|[KXl0*t<85ϥc~|#4gL x/n\nVQJx<ܺgtp7bUDcOuh}4l}*G4JG]!^BhFh|PXKѤ~ q1hZ?Mg/.)dB9 O=[hz |Ǔ^x2xǥq maC~1fE4mfΠѧNh9Uho5hto_k}kqيm|o W&@hW4.ƣi;4xuEShtD_и29ƷB,e?hr{h8ᄦhhƅhxIh'M^hXɃWh䞬,BC+q})@|WQ F(lk24ޫDd4 &?4M hc|{h G4LPN4Geh2GYh>Qx2Lhc>9 v`;MEzG:MjhjccB÷j4>t{4D}|n5^F Pg(Cu+~:Lԟ$WagCKԿn@Cxtx/e?1o6x5֡.(jcQ[yvr/˵OEmNu5,DF-ԺY^j P{u㗠fj;P>xdCF"crdCͧ8ԮG732Fݸu{ǝQz5sfMGxTyjPLS.t,jC͞v;.Դ%kіP.srhԽa[?5Ḱ}tQߕ=O}Z%j/^fXߍZ_폺څ]Zs٨l"_u~r0տ~@oOB~B{..آj'Bu~ kj56 kA3wY=ՓTQ ?:N˜{G~/k!jm&ޙ}ڢ )ѲF'EEJ*ʒQʘ|5Pz*E$T*BeCW4`T~ ᄄUV(ߠQ~ eP1 ׿Pm|Pʎ,@~֠lʍG\' Q6|9\w<:1(_RrW(w &#Q6;V]/Q%P厫Pq1JC %ob(_;enk]iFi*MT\]Pk9*FE_{Q\;<P |`z|dseۣ[yl`G6ɞV%<YZJpJ-Dyn([c(;eMPncg(?l&޼t(_ P3%?h_'9E~Q-9z_w0x2g0=E&(z Ŗ(E},PPb/&F(-PJ&4Ex3>?DɩK({b@-@iP5漹%u@I'Au(Eټuxp0\'c7tl/D J\Cxh'(%-ZK9HJBS>Q(W8x5Jm`hcP<&Px h[Ϗ(S"_rϼE1{aQ(j(EPTbbo? qWQY cS;iGѢ(wE(Z2'6O(hㆂQPG 뎂M܉n1 ڠ m *P!gQ y)g'6&#.څYs#?@]@aZ@Co̸GH nBQ(rajȹU< X?rCt}x.rv# g'B6goJ(!;Q}닢&SWyw(6u"#>qrd} ǽy/jO@YȿO!Z~Ct O]w|g]kqyS'd?A+m%rD&?-C~t5('rg /u|4}m9CƣXT{v?Gޘ)kóM"' rf,D;!K#ndl[?ܛiY9ǜr;BF*!w:5zY+ u0Y-#cUy "':0Oq\bPdGEVcr=DΚ]="Q%?睉"dDz4~~EJܿ +#hrCڜE3a^Q@ d_ۉ, ȶc# ާpLqd\"͢T܀H4[N`e6 gN,Gqq q(޷%AtGi(yB4~>o3zTvC+( mQy'gZ}2ӨjRTztQeP}?.3UߠVzXɃx#Q+**ϼ@ TڡljP>OŭD@`GX +~G((m@A$Qya?=r#!839|| *eYOU.#yi-f1R  >­Z;͑z&pD\~KR@\Nچ-\m={خ9O\3[bB.=@B??$W%8' qe8_.߯qR85-'J8q}Bn8T'؁a GO{8j2qttF2 mp ލ# 8GOG܅v8iFapH [>7@bINX 7pbϘao[$U v7؊3@D'{m"T bwCt|tE#.Ӱ77K<1{!z/r1#7#1ulh<#Q;L녨ٱ 1ohܘĮ{ OkG;">Gd=D6!.b\@L.DԣJ:Dcv>4Q~EgՈq'Wy㿚vEˈ%1뇽[ *'!fb!ji2bzk#-6ƾ؛6czu~}yW.GcK3܉Cd`g1=*;bwLe\&aoػa;b?ߧ f-ډ'A5UsAQ[0ο_~Zsػcs!F6"cElqV\DR##*Y QTs bO!Z5bF!zRT<vBNOD[y`§!DGDo9[ex/@x("͎"#lX5 |tDuD2  n-lCxDWAIroWDLr eV7{l~Mk@n{B4!MOr%"=Ap_DAt 0(C㶈̽iQc!›MGX@ QmF S~rB)myW{vî}= OĞ!t]'3' y=`<=klcw#v݁tb=BUI+.e\]ngvByvnNع9vi_+iT AIToqwGpR2@`މ g"@~o_?5~Z14M׫@1x AK^1kة7^?A{roq5Դ7:a#Bz6!FNXskgLT*-AED\{ !vC".=m"Z 1(|gop~^7x-x̺p3]G-U8g印;p<2#ò,7GNjav vaq(:kp\뵇`E EN-t:2x nal8G)a,a{ŪUlfU ٶ? &jT?q'vr_C|KlY%sm6"6_nX-徑bXTmg)VJ y$9:XGfbi s"l=!rNJ5,-mzYO!#lŦ^Rb]`"6fn#6XiqXUo'nb+gu%OV3 b=`X,$V^E-D_!z_EBt/Egki+z3&^ѽQ{n2Bt?ϋLDYNΆݹPvщ]t컉VnVY+:a^։΄ݢ3/ptå_$QY ~EMw޿1!F brz(&_Isb* /}1`#FwG f..Esm"zDw|;!:?DWa$z}{i!:\t]۫;h>"_cĶa]=Cna{^"q_+/8.^77Wz-^i냩xտ7jɟwn$ޣO Ex5w-wĻ4,?GĻkU|Bssz!⽗C+"m'^&^GW-X%^:5x~7ūE;|7X<뗋I5KׇK[qI5]M2'S\|gsE7G~G6@]\!2*ab>2ML_a3;zfb6VLBc1x#FthCSEKl_CLŬA="01mc(]˺Nd-QAtA6 Z2۽d޵b[1[Lv=֜Ab0m;'F·bo'GZf)O _/͕⤚&6X7v Oƨ8husNbU m!԰㥕bxL5ˢFm%#a618-jdUћ_u-/vѩ3![LfNꗲl 6=eŲalԚ*ϕkt4i(/,2.Z&~*k?ٺhE6n,cb蝤$23ͨE@/hR6+:ĠbQ_'ۋ֛Y;l?P?2_ Qk(*:Do"0zM6De2H_MN'd󅲶,uk!L~ڡdʼnv$Qޔ */ʊ#dC%;Y>_GljY&\-jKe'7QΩ]ey Y,5eF>]$dyY<,TdidFgSd,"ѸS**gdzŰ^n!vjX)bylo%[ۭ;JT5vf(x(klvʧעY׵FV_ёu&R E#{h 'ɆR?[6 dS P-gQ,[Fhx*-ŴrƋrѿ$n1ծDD>Dt}MWԣlv+DǴlC.O]Od_2ZMAL\ `X9ޞsf)j-f2j rhڈj5odMX5l 1^-C^"t*sѩ(M~YWJQ71"ZE߷þbA44^#&Mr11 C-:l)犹뉾)gؽlX} z[NEdq\e, 1<>S wb<7O̎b2zvl\1Xnbloz/Y"~d؆\b?皯cľ{+ʜ.V8뻈sb?;KԊm7?&yY~Q,b?Zlvss怣<s;i%vGUXO'6ĢKgqb^S&6E/eضbBjMzY7<c[,k.ȶsX!{[0OlbK/Fj7U̞tž"SlK*U1壘ӧ0h]; cd3q6VLlѴbq\pCZ-'ria8GGqB\kvP<ƋIX q9?YW>L\ ^I\-SqpBܴ[]qߡ#E<׊՛mg1&8?#R?^l~q=ųxfp&=T4mkNx-#97Scx?(^8q?*ɮi)+x8OZ}3&_<\3+@½cp,Up*!:@*$8ŽU)wFxn.Vpd#O CTe ٪7\,CԼS?ba-N~ 1ݱ=m R-&,s8| K5X*<IErXuԄ彇0u ͡HX}/a+s:"nTCnOGG3X6;Xí)W|6p:;v{5"VU!NLSߔgxv3F7vێL{=*HC|QFYla&"b"<f feݰo1 s-b}40baa.Mp58}@Rj7z`8TrGqJ篅#yq[ѿ4v5)81g|q&f6NMiw88U>8 WY8c gUsJq2frn3\|Kgrqyx0lJJķ &P0;#L7\jl\ݯ Oqb\ W?;Wj \͛k]wj\&iuF4nh)psF.Asf$, i:$$QH쇤'H'I_+͐tIsIɼN/ERE+$=|6HC#EI H9^Hޤe|f*$/ފlɳːc^ ' 9t2r[Bά9{"g7:#w/#O#]^vPV E/(߄}Qxi EŘvxpm?J&z4ʧEPy/&ơjJ ^AbT^ʣcQyq  Q^Q tK[TBEcTơpK PvS|E9z<Q! ^4GEJַqx{O"Y"N^Bպ!*)Q+/xFի:'&չo<<zY0C)-\G}_Ѡxԭ ѼAxlMC\#xk,1]QqU3Qw^$^TوjLsgP.v7::QO WAվ:T%~!kq/|q4 "Tdz1PUU%_P7G ;TFUl'j?UNӖ8 U)+Q_@[|~Gb'UިD;Q5{0q9z*+`sT ;*%Dk@ez,u2REv*~ۣ4Khڿ3~|v3.GwTA'V˼wK_a~?*wMDw*FwA!_T? wEy(KGŻ6|I*QŰqmQK19mCA/^P5>"Q uyf[ɗkC(?ZkN%3Q9ߝ-HFœ7xPٖ=}PZӚ(@y=n@YD@ٴ/(s-E`#uR׷@ه([ eP|P8'PQm>OQ+VGlsʌM_]AYf ;"lkEٔ(;eae(,;ʪx{ƣ|Pd2Gyr{uFtFye CEiθLFB*odb *Qy*@EBTD*sQدC&{c*t.k*Q TTCŹHT⾨TFE.p mQQ|y#Tv3D6d*rTμJ Or*TYImCe.*|QYE]JͷP ;Ʃ,KΠL P(ZW}\y^c=oLE(^ś#~M(NޅP{!P^hiG(N⬳(2UP܋m.v;;b(˜(:Q"ech Q@P+^pr?Q(tCh: G[/ypFnC!Cڄp(@"hEgI(X(tB`λBc\Qh9(ܰp#gl>Al@7^?C's чCP8c$ 9#wP,j(\p{n5h gܛ>lB; SQxќ 2&ƴ(}MQsW };{ ׿u_QCy&|wuca>r!~+@N_<9"!w}ʹ}ܐ lDyڼErc#7u#Z!O?j?"m]C{y/rmr#wr®!Dzrg#/qk^:ܷKp_7lhsE^/C;~ހ܌H@掾Jm,EȸLR1BѸwd FV2 "K]yq/ wEFHFzH{څHsi'Ð(n HkG֜T9; GȮ@~]|?ܙ<iG!G2;g!7d^Ȉ_P\ن)p"2΍AZŽh߮E7h#Y½{^3;oDZ*f! y"m5z;VH?17&2CƊ6l Tdz7q '{pnd쀻-pgcw6A*i C-;Wli!= )yH1*ב~ 2t3C>t߁H/"}8!?<:"?H{=}%H\G"}3V:H􅏑6׹:B@grZ$^ B iYHI@ȭH^kVO"|)xB _mSFyybV7inߋڍŚdsu྇"SAzk]<\3i.o$#mɯuϑ6iӁ76 iEHi] qZp$w3'n\$+wo1 dkM@Ωȝ}դNϳBβ[; y[{<8peoD Ba*{(T$hRͼJ(=QlN</ۢtFBYN(kwe{s&4G_yn7E.(=:g(R(+PJy% \+(?Pڡ;JҙPگ;J^D^x^,Qsmk9="g"iyvD$D Rq<3wBX"Gh;¾Bkm,b lrj@xꌰk=8{.bjx`χ #Gd+i=سW9BGcs7YBQ^ULn1a B_aM2]v:†E%~~Gav. ֹ=zCa"l2<2gأ]>[!#,6b_I}%v#5;v.Į|e`ghj]FK}vŮOi Bӱm !<J6O\p nJUa_ܤwzΊ 5i 0S!1<}cxű?lߺ}^mu+~w5~G~;?t(k.#,o0ƻ!a<""yeߘ޿b!('|&!ٟ3oq B^/ϯ=y{ 4[&>4_1ܷr1\nKNp9NpV8؏{wΰs ;5z*ajs6._j6ݺpXhU}55$n0/vpZx)iZp ս`7wX'> ,_UA[Xb{+] ܅ql%LddS+0SYS 0sЅqLA [f76z a0<zo_zX6h /] ^CsD^𱋅Um<9{#=&j{8öpB1Xo=q]s6zc(nr1nۏ.u;c_U1x 5Z:\ZvGVKs@ 3LzAzv-CO}t-8-g̖'ȴKe^;?PFsdm2uS_:-/e͂v en]aR4&"Y=t0r}qn_|+2-n{qT,9L-E_h ^l?o$ݔQx^bq(s*]cw{,Mst'XyK Wx #}Lq|Gĵwi-~'nBUg8?'B+̦TL-ڋe9q_#NsEkb}}(ͮdA{RgUSOb"6"VfmtU%jbs}XO]%~%buAazl/bWX~GlFx%EމeqS׋b^V&bmR-ɇbXlϿ.]YX 63;bs6:͏bfX͘bT#֍b,_4 mu{z@X{G:%yk$7LERHn}M<%3$ڵ/$^rIn(-yggB|lm[^/yL;h-wHy%g^q n@(K"W$jA]k-yx݌> (HXs ɟ0EXKA.uO[K :ʟ$'\ו$$}"zIVՕdus.=k*cwu2eNvOaSto݂|]YWG )度 pOWwcT$f=ryמ1ϟ5DO,wmx/koG_5?QMx`OKơ[$41va9w̤eP˃v`ΦIcϭVge Pv$PB&^$]f'rzp5ye>mgԡ]SBm|{#\kj@q5$a62?y~vjx8?QxJ{^M+יKvռú3I\f$Z3_-͚{F>%Y_%o}wɑԷug)?KeU樓;UY.v2~-S%GYh91<½Ԃ#yiQگN/3gb5G9y flɗ *{C"|?]zl{6!zN^! 5\/|@oR9$& :89koyԋѴz}-4Nue-1ϹcZŘr 5R=q<~~|e6'1WFj|&^~2?Gh~ r5D>9o~*N.d*}QeΟ {=^Gnmm]A2h/竫sۓ~0W_ef4AL<:W\aod7"73nRnC9,~'yߔi ׃m+mdB;jOu3mF0i#gk%sV}x!E}*׏|c RFFľo m$F5x!SֈpgG35Ӿ5х\=3~i%uo-9~:rO}m-uUˍfEkWz/I;&{5Α4h^~GP#Ng͚J}.wr х#mqu~nܤ߬b^.RӘ$^p I{ΥGIiΟ8snR FpNTs>\ʹq$cIqlY$5 jc-Μʒ|~ߩ;djCQΓɜWs m4`ro7W:f cN+K)JR)$ŋs)qƹ9_&Pw07R?^;PשI2]Qsax:ùz8Oj~sI ד7R˔29sy&}9uq߱ Ͻg8m'_v;ԣ=YT\DN)Xׂd 5]fnn<P%wO[~=8^}qE!;:姾P{{SqE̦8kwͩa% {karY|Z.ϾPN\'~8c3ϺrBsvOP󿴐3].8]tco^_sϴ%E|ZΕwr1^pv?Q,ǩǭr|;9T$'wr춲=,"1GZq ^o!Gar"kUL㉼GG_ȉr:SrR5^NhɉurRINX YOW/cȱ3r{'q67YI-#[GftÜZ Ô(o9}g?c?$V{¼^ʎ6k`UD0bٞb݆Yzl+)~^0#݃LŴ;0eS S >?EM;&LZL`Äp/Ɨ(c$~`:;>c\[==`!c{1;FQluݎ F4hw^ s V|>a]/c*C14̋!8~߅O0 tcH3ҽIv qo'\A/؆1h){q|iqO! W$H;_~|a;g36-ui{Sw4\qg+?P9-i~izďƈ/ɋǸv MPfO񼉴>("ރjg)O羡n&~M~m@0#*ꑲ?@ݧ%E=ǻzpϷ]/ y^;sr^{6ݿmч%ߌ_o.Ͻ̷([|u{IӅ͠N b cEkƳmµUsΘFyx_9Pi+ |N=P95ۇ9BhClAAb? ]^%KC\4َNz/:n<:$zѡr 0;|+p._.x9={mm;tJ=Z3nmZ&[8ZգzZ Ňlj3^F4;Av4QgBh|єqɟ4 УQ=# >ke̋X/ sO㗄Ӆ̇h|Ɨhֆ㽈zqkAWAt5u_FeCD4 Dw!2mK/"gԎ63T֋p~˃Q. o^I[}fcoy  ,7aJx`DwRK yJ}=g%aKx'.om Ɠva =fyV,"'4mKK<!͖ۆ3 BBsOZ-w BhK3ޅMCy^7Ҽ}3By΃0Ԇ<7A((a3\c 9p @c]ؔFvgw!WBCڄ|^BY)d ]/5d-lemژ24zC6D1RU1=1(psI8(0ǂ Ɨ)}6?e#~Akx*c@ cLN([w@3^3{`B=3yF ? Ml?H>YO1}>_\Y\Ӆ*}EdROn:RP5?Oz@#ޕgT'ˈ/9"p%;Y+"Fє×HR2ݧ̬CVR 5[pky=>`(u@vrsgpR~a>h`xC!pNG^R2N Fj}~$=m)pCWP&@ gM߰f1~ ~O:/k`ֱ^| Ǡŷŏ:AA;h7'ٶ#RyG/s&ydCL}l!iCrÂy9(wW;; p{1ߔ} X>1]oWo}y^w1NEYSƪ KrGA(1;y4``^7"A(QAAm~OԛB^>'hc7#5hc~1&p̦!Mz+`{:6eg}̽~o?0?ּ~yG9ۍ䣷~Y\c,lOlhP)h<G3 睾1XL&/{_gKH)5N/z* c5ہ?z5 >(2ƒ! M#aX%0n ?"Gp<Fնc5Fc1uXر qa<&.L`ׅmLLfȚP/>7}lʘ?-ʋ3v` =c ;gVf'8-fM8}C>^łN1X? >w"iI Jt# {X86ILX^33aq,j_Eʱ豊8LI/b''aX XW%X̄%1XR׊%UtXRӍ%``i-'<&V,bi"3HޙN$2!y v"y~q˒uXfzE1Hg>,۝:%H)%H5Y‰T N -ފN!:һ^% H郌$d*юKX6,XL2CȤ2 f921BEV 8FV?+Dv &dHD(W]K}OTdG됝Ϲ<Ү@NSr$,*G97rY&&W CC<݊/wy^'n`W,s`-&" +ZbE-+VtJBRvyDͩ@^(>-]ȝܜfX{h9Rx1V4LGcE@xV(Qo61iz|U3')HR)CMHiƲ z+q עUt%s~ ^.뻭ܫ"mÏ|FćIHnnR'H}Hڕ"m&iu*>Tslt"z cOL/9uHs(oՠp~>=E:])Rz?cuQ:a9Ro67L HyЖb:ȥ|Ϥ L'y_'ע+yv3(m(-<,"Tqk_D29ۛ{ү뢟}iycg˘]:'s|LŠoJr+OcU +V1UJ:QXCZ<kʝX;#k]{zb}Q)6l6$8:|ζuJ76 #-eЁ;:lۤ /+, Nbg8K\–dVlܙ>Xu9Wanlll:l|Th:z/>((`q |@aDN`k_WR(:/&ik9PR^I(AQ2TIDQ,ǞR}Cq,Iؔn&(^B W8Q:nxx_Dl;VN 69[~@W`s#(FM(ʞ)ç9w)f\g&h"YAY4عҊ/밧 _'v])6wK} T|{:cqW{c;Z=Z:|Uj&á%8D|^;pd|q}oYRP rt$Np4k 8SPs0O9ӧ.\*Ņ%'J{3^|" ߥ8\ sU/ 'K5樫Ǔp>tq*+['(K-_ܸ3 ;p] "d' ݝߔ,#wZQ^=* Uϊ;̑pnRqDܾĝ ~C=B[;yQ0q~&ב:.?S|>FfݯVo7/=nJih7~a?PŽz __xAڊ[?~H17n58g;ۄ۵bPޔE8Qwˇz(ŽVnSwmI1*U*QJTD%*QJTD%*QJTD%*QJTD%*QJTD%*QJTd:DoS!Ձ֭ԾÊso%+ՙuCq]bԡ't Iݯss~[ie{5ԙmչ;SWQ]2N]վp:)5v噚z(CMw^W37,Un ީNSݯw/k/Q7zLݺ_n@XA K=PxcGȷkP=m6uz<`YP?_uY=P=>8_=U3\=z2$N=/J=;nzـ^3JGӋngVVgfguԳ#3ǿV?Y= zhLzlHKhRꍰyjHZSGPsY}>3MPV wqkf?Tk=ESQnGimZܼڐ|mD6g?mҽڴhs~٧-SR[M;2vtڱc4˷igShgC;iM7iC&knXn߫}&A~}R|]1ڕ^=+֮]됭]{H~vcԟ}ڭ3ۓjjwRkekeI+{VV٢hwJkwhw[&lyl~yoXh}=򬄗*$bXKDXFH!Y1D'+K?["m$"/bD[- %bTohdQ\/ Hx4uG6B,[b)!O~5by;M,#egb9zM, .{%\]'N~O,e9iebєkIJXR3Ų bXڔ~XmE3E=?7QN?(cr~(ZX|r$0X2||J,L ,"m 9YyGsbPL؅k5y&م찄<^"!KȔ!<%%[NTa1ı_ެ&wC0|$A/~}% =B"GHf$ .J`^P$I@#0vlY(Oמ3ZKPee1<,jHc8J$4v($Xg ͭ'aHXh&fb@^Sd~ϔqZCg'1ϋa#aO_9 %l +R%Xcm!12ǟ1ߨ+ƨbٖbz}1ᙘ";USk4i6@1#69b|%#H[Ljbz_[RĸK=b?!w|?[,KgŸO㳅b dNjitƱfxgS?iWLS+C ([FQzW!}{+4L|y/51b~_̛hG\(Mu2J6eFCsPvX/ Pnn;wE+Qa*jEIPaTxUqDup#* ^YTE ֎ESQY8.Q}r#vKƓi<܄2Y(eJ]zb~r.\9ǵ;rsmև3#\gZԘ5͜5JVqG6˸i\Ly8Վ=L\O.E|K}} adr [WW0{S3{5\{{ʽx{w{={n=/>r\١Gȹܣ\ t%Wz*Wʕȕzs+NL+aWhgDo-t1f-ŕX?k[6pfs_Z4rS:\1ck?gu(cAcϤh,Fb8`U(㠫騱E5?yhԥ? Шl.q|!#SCqL) qn2NǩXhr#q/h~MÙmh>/Z$e"ZU Dx1%hc7m7@.UcÐvgmWM8gP%;8_f/Ϛ =Džqa\4u'. _tyd.. $\zeJq\qx~5VK\ws/v<ڷ :NB' Ct2]F[Gto{2{U*@?GMj ՎvcP_tQ#1cb$Ej"x)kbP($&,LĄcx~&q2|P0=Lu4nމpIiܲ4nĭ~pZn?np{';"qGꄻN]%~ 3hfd1s|6f>{BVo{ڎ&@6ㅘaxQi^y/)cOF|l^Q+FUx`^13sv\yk0/WcLX gx],exݻ¸X5/Q7w<oO[ex{-޿LwǻӰH2E¢xo/;Mx޿%0KS{|+/.,Ҕ |$||w> 2 Xv//g&\>/vMJ|b;_re|;V0*μws|!VICb}nÏۇ'UU Cc5XkƎĚ~ůu[aa8-c;i4hqcwo7 qz6 ܊MyylQ8-%mC_ aqsvs 6bL쑎ǞwN5v$)J%,;IVHz<~d 'G<\H#$6dO\$v eJB7H~2L L {kI)Fb93WR>?[RKJosHyrd?R~ iO_wۘ~Re 0l A.Ӏ4p:GchVdK*f^"2%<#qGI*)4q"E }, ؏РohP9ToRK""{v:"IQ>4Ae@^nE:oIg1}M:JwHg.N&ʤ]JڙgH;i{L"lx ikI[ iEZHr*&GҺ0_$SI+=iŗV0&qNZU2LZMٹ4Ҭ>JI$4 9fY4Nfs6i6=-?l^6ORY4_d箑[F*ҼEHH{?47a4 ׵!w;a cD74H[?m&ͽL3loHsN=iޤCRqiʱ)iҜ4ĒOi343HYyF uI+1NփUחeJH{S^B⻤}#i`:=t/&N:Q]thҹ@:I@:uL~jNs鴲egzO#"^yM:o^i}!e]t*j; ٤k|tg!9Rt7^"'H7ύt,"k1V joL agfg:+?Oz!H/,+XO'=ᄂgHLzӻHoa[F [CH{g{#Feڻ;&/tF1I{G:t=@:HGg,:i?Ht1p8YZm$m#ַ"m!ߒfl[֐(iO(&)=sO$mˤM=[W$iG#I;8} ig ]Gگ[I,z>ʐH lᙜ2G:at^?"ln5餚"A:gn #yB:_fN=HEnʤEMOҭ5 =e)Hz S~h+ "fc>_4%{cI<L&ɠ@ V GHە"mȨ 6=ip= ]OCNP)} 3Vma4l/w /Czoixh ?ڟ̢hD F# 4E Qϕi4:ғFϤ17i. 38Cc/q6{hο4N7Lُh|M`2ME. U4QMVO=hbnx&>v94I]DIkhRdM&]g4Ε&dA4<&/490&o~Fɗcir7M~s&6)RiJ4e2UMY8-)ҔD͕)4Y$MnFSzTvn4j.ij@Njtm4<{雥iz %MѣZiLGO3RhƩ+4aK&F2[C&IS${9,%t2Lf2LiLhibH3cifluf꥙̢DM if7 s2Jf㦓j2F~,"ٸ,[vd6{5qd6z^2[HfKd]cũd6ׁ[Kv_V}un"B2 &dOfg,^דM2_|n ۧ2w ,fL#b p" d1,BGi#Cdc:YNNq{,="w'ɢ-,URDo#KQ/YGȲY)$ d&YEUV/Y! c&9rWMz`7YJsZ^#k:Åϐ d]>!y9J6'͜dl:͂.ž/dYL?}ڽp5% <$O0}i"OVFdUKVy7Yh!+ ƒZ+!ϥ3ޣxVHVsjGfg?UJYmO'tv6s/Y_FV zBVow|G0`vy oAd:Y̰vI0#YO~J팮dmcDֶʬo$Ֆd'$LΗgda7޳!+f&b}q o&{dZF6&3ٜO ;Gޒyl0FSe,|%d@}#[{lVM#iB6dð:îy ;O6TȦ.l[lqdS[ǾJֳOd0w: g1tT"fI&[d+涰~}Mio`4=nևdmټgKf-{{Oͫp)seLɆ٦]cKy:gMvɟ6oNdi|f{k fc GV Ӌ O1;~?O"M dsr&yl1^=g,b3~^Kw+lϯ 1 k&e3ۗᰑu&6^{ò%ld|::8d\`% hf 3]"FL'CzK'OO!fɲYm%K|v,j[b+ȢO?Ed>͟492s%4r=<⑳9G,3=]Tۚ2Ơd2sfB3\rhp{-+i:VrtӴa,>? m%d^&ݏjSN: ac,Q$SƤ8)'A0;| _䚪IAs8ArH3_GӺH#/IFiI癑h I/&i zFRgHjrm7#ƞ#cGo$v_]^ϰ[z(v+&cU:c>uZ;O`3lvyOS;ދmX2~KoJt NaۯyvN6}lֲzv$nAغ[M(ly$-e!lc;ؼ 6mƦ[Q0Eð6>ĆϥU'-/b=Y\Z>O9,?_X)_nXWuX:WpfZ/5s ~]{ 5Ư#ֶ8b9-am ;5b$As_.7"ӊ՗b5?WS=N~=?&ǀ&Uc]xܱjPZr6`թX(g)"?UO;.Iya~?wYXzsj_r3KQ?5bVc֦¯/ub}-z_cEհѴ I7p$6<V[fĖe= [6cK|rl[allne|6nqU FbS96O_@laclSYq lӂ Oal8 J ^ذ`n`Nlpaz7bC|!5 cV lU YlaCub816Nq]lFhK݇*6?ٸO3dq|lS 18}]y6.d͘ٹal]26`clF重jclNl?u^lh!g`Âؠ> Gt[r?+ s4h?Nr=} ~[=X{ZG%K.Nu9~˹\Uۀ^z~ k kֳk~a1?aٻ.Ox~vcUXu:ĮXECJ?<Ccr,~֋XA+Ga7|.{4+@lޏaV܉F?h{F~л~d a@;{+beiLfw-;?~<|QﲋJSxmW oަX=_?Mm )*E|~[MSXes[Ir|, hp.|MÒ_x {bx/rgݺxwUmsxu'\t o0}1@@!~/*uT#ĝC+Xc~Ȁ|`w%j拧`,ek0¼bލyR꘻d$\z9 UZE^sqj^q+m<^1 /o˪G΃xi^:/N =T> c l&v<_gGi-m?ƕo(?=?{H=óUc--ܵk ~Dn\.ҒH9VֹqK|-KŴܴ'!o.pCpzS9a쪳l[~ YdmeqVۛf^0ѻgVٞJ_e{r{%Wl8l=[Ivf3͑n^nacnޢW|GwnY=f3<ƭN쪼5Ne9 9ϜHOνjy7碞GU\m+۲%;r;46wX.w/;;8r;';e.&-⎨/>ᎩrsGp'⎟ϝHs\? NsMNLx(s's'N/NE~.[w;l;i.e|rs_nܝ\DT2)fnנ&ew#~ˡֶ@ԯC*8E46R_v~ù%q1%~ދEvzE:M tFatCX]L:)pa nqmqTܩ>e&~iҸR:U{RpA fnq̑2wafH{⾕_d5~xxG1ǯIx+3Wl <o߂٠=Bs^;/ K/x+-IxuW ^Ü;ܮØ)a^ ey^wrbރc=7k\ى{gP(79s?ӃExMt|>ykO'h=|i_+mV VX??RŪqmӈ OMڐPz4P?nm{ 6ӱQ"6n:Qؔ?awll* Ǧd:Ƹa^'6Mcslh-b=jm Vc"v 7.##cS]OR{L@R_kIj{:IN&HJ {'Şˏ6;ݾuح]4+4v.\] |bS1v}+b]{%kn$49ZERIzjsäy2)~c4} #G~LgHRQ>Ie)6\&ŷ#sR,Ob*[db R5WbQR%Ef).'EZRL#7/)NO<Rte{-R!{0Sl>)L`-xׂ} I(R%ueB!y$6d;rE2IfI i/֡nn S")C-HJ3=/yk{rbI7'a= n`aZ1;`g($iA$ƂdT&L>9J2$twwdW&cHnw L'S$WbEr\CgH "9j3#akHn;Ir9$7<}$9$H9F${UdM#{>~$9$}?U'$7ژm')$ݽo+{31h#6 K#Nl!~H['y+)!IɽP 6{>[@֒\fyFd+8Nrͪ$k(5^d%9ag]axTP/>J+GD7yLs4IJ$8M!yn_|z!yg5_w7|6 &kIo8iiRP)! M 28f")tBhE%8' ̖I0:uHz7π1.B EIMRثA {2ǒBӽH'v²3_f)ǐ@ #uv`Ru{RXp擂|')LF }IHaxRT&q$ߙN[IU)_$,/e2\e#9$J2''1_;ku_H3o1$kIt"$m3I'$0RIztCw9ev'lyO$;=Ɇ1}>i Ӂ$+g/%.;BrG?vb0i&$g. IЕFbωݼ:x,Sa M[X/'l<= T6"O]=s>֯Low:+k'/yL~~? i:cj~Xb+> Y}|t7cy?~IFXKBl!'6`yu,ˇ-E~˕{ l/WKyY|q__%2-|)_^bX>x<џoG +ҫ|,{'[|ohWbX)zX)/#r7|x?[%;k%wNbX1x;M7WM,y㫣ge/ϵ~ƒ<rdR'>QGL+}}Uy|0KrbUX9`7]G o[w旡xS/oʠ0 ǯ늻0u0OG`ΪF;+xv!^/x|?cvx=#c\@gmE,7̼"<}Owxd'J?i<)'J2DxO|<o$Zz<_Ϝ؂g| xa^| /ū^ᵂ3gAx]a ⭙N@g^=/.\WcX?a i1kůnXC `lY&6'd I%P+䜧1Ybw 9~;H&:O%b?RLtH=$i}B@ZޛHq%nC;đ~2XM2TɷhS4tRYL.Dш/4r:5xZ^B^h4&'4i4nt7UEOq-i4~q|o4ɤ&JSh[2.EXU>2=M3WdП,R&d{y7\(⭽iV ~Es^y4Zt;Eub#d-ʢӲN-ZV1-%QHk*/Һ9h=,!8XLGq(rrCΛȥr6'^<B:/ {*Ў|?S6ѠYPMk#)h2g*.0 u"P)c* ÙLq.?xS=S_wd|̋]5tպW [s)Cϗ2L 6{f}%v0̥g)slj=Ρ=yi0U_޴oa;K/~Wh`:`WI>TYt=t : 3FY;H$:x䌣hHǬ2X:B_GtBNğtrp:YBѩ?t3;:w Et1WLp<.-]ȠKѺty \v+uj]D׶dQՔSXF&ʽ~򦌥iHR"*G}z6* UNtdRL7C-Ucunt'f%]DwsRѸ!T CJT|:wo}!-*J?WУ;ͥ'$/XRv_AO-g.u5]"^2e.b9ޫ ^; սT;BMF 50T!?*Z;!<9ޗP@"tJ(U!]41]<>gmT}"}xdYQTIJ6l,좯k WmQ}S]VիS}^IߝvPԢwZfRˣj@'$Ԧp|oR[tY߄P8jw^8+=:ާSǟ)u΁ב(hu~OKcꐞCX{.jwZLfMn4em]f*)/*{u~IӲo`jw^;zKmo\ ]ԖڜRۚIԆ66&@mRkVvRk1QZj=Z5۞Ze朢cz2^CvQZIdZ|j6>6%ڦQuXJmߩ-t?E{Q[*j?NmmO,1AmGؾ\0k=jKsR9s6?ڌF^6=~Jj|f0Zd/jJmfmAs5tP[a3bI +Ƴ\jA#ԪCjIr3PS9Q-~^jS>Am FjkΤsm?ՎקSK^:WSG~|:ls"uڧRg 꼿:JKu)SלF]QKLԵ5D]4SW\9uP uB]̦֭.uޢt񚺎+QWI=u}B]|uU2jn=a0u3?}$xPw.m9˩g O=sriCr˨WJvj0\D=}' qAuBԽm9u{?i{}ԕh=I-uf@=\~:GXS_ Աuu|0 f==ړR{gjN~ڃ"=e>~JB.'c}u+XQ jP`G0l cu,XCNǨ#b#u#uJҒ ^x T7W+xG|_VC%l";+__'_3Z6";o|/QŋamBU~W~c6 @Ox~ޙ/R?*2yacxͼ׼:e^%yr,rΈWU|U*?Kx#^ ^(WΫ^ULUWNڼ"3WMʫZīiUUoݥY^АWɫ^^me^m~^ͳW jUZS^m&WۖīhՎ<.jyk6WSmi󃦪VbeAAMAtyu m^}c^1WO2Oh.4x^ƨz^k/yF\^Y&;T5GL5gnwyd5OM5_5Z5yqY]^ˮ /rZZkyN_^1=B6kϺk/WھvvD^;kkkڗڹ&-?oڷw'}}@~kg߽ⵟ䵟kظ~y~ƱyM6Ns~l9?>^vƉ~+x쎶w ^G"Oq uxxSkxt^GNZ^wi^!uټDݴXnuyx3]n[p׽;-u_yݯfn.77\׳-z gyCM ^^k'w7?ϟu y!"o/o  r%yA"Py&o׏7ZxKNapo:7!o\=`ߑ9axC*9 zAYop!7,( y9S^xWoλ~^__/>eyżk^О׽z+=_y}d^_͑DP^b^/OWNy}ټ~^?z1xz)5+F ^4^ShhJy.7p "ysg7y-o8| op &Nc p ,ox}_dsgg󆇟Iax0ohǰk7L>O&Arޠ)o78D^nF#opi0!ݕ민AK.7_ pP~b4~~q 3a6{7{UW(;ddStdXd;{Sc 0p90oF6O93.?yL/6}c|7T ^ |yx9g̖{]uyS>u6ּc^g6qMiYE^;v\^:y uf,Ŷ]T^ 4k5{dx q*ë:ayYU~Э\~P?h'WW ̫Mcï^V^u2:7l ˫X~]J*X/U'm[lh4F~8ݶ;ǝ++_=+o++sJKUx%yC L8+~WU n yU|/urWr+x9ͱ-g^ψU[,e\2jxۙP^Z׋*B~R#ԩWHQ sQw4cS:_!u.@ן|܃گ$Sa7^:YiZPIݏ_PQA8l5ҟor9~_,g5~lGuտoqTw3L[.6y}NCGRAddPM%s*}O)sT;>}OU}+MUwnRe*u'Bw3VSŹT36#́֜ ZB^Fҫ[ozY@/7$ ɇ^yzn5&гlezZ쥧Z@e,a.RٶgTHeRtzt@OR~ГM >z2UWwx,=;mKVSTJeQڿT:d*=8f?F _t1=A҃&uzȜF6уiw\{G%Dݿo6*Ѝ 'F{a@7y𧈄;HMȖhK6$a 8 H_O*\u 6t}nrR[ 4Pєφ|w9 <ͻ{4ܠKk)w̤q)ɔ}rkRXu󈡼/I+(5 &eeQz*(늦t5]̤_/T8' sWE70uʖn_w;wN݋:T}5[OźT|ΝOԤnbHfPɈ:*qK%2t `Kz`,Ԥv{[`m9=D&@ ԟҋTrJX=_̎J&itv7/T[龯5ݷ)F6TܳGRV*Γcש8WPV*gd!ͧbcOC/k_JCڜX{]t{2˖S/ߜUQ~4kRT<6OAŋP*̠❇8s;?O'QqaOMom w}?ޑT;nwsݮ7t_6ۯQq$*nMſ Ҕ_ofwPօGOhP(*eGś훘lbVSqNŇp*f}e >]zOv(=nSBE7QQP19"Cw?tw1S?Ewt;+fW˚V:n%?[n5ME죛cuFStCf XRa*\MKgt}X/}T02]֣|7nJyPn34ܧ(w4]SුӳrtdCYk7d:$vC`+T*A洿~)_U> i^mړM{$QfK<2C2(sʜ(OQf?[컁2RuO&(sf(e~֖o;=v6G6>$*M<.Uyܒv7,xv/'ioc'ɞL.KhZM[іǣhڜ6ЦJJO]ꔺ\RR(%SJhQH2g*;KD(N6@/ESDd5?G!ooQY8{$ F&O<!']߆\*e(rڽ'"H{ZqҚ7xM iQZOЂ47}[Hs-2?&8Qٔ*+XE72D&ïãXP)Ф iBDc,ilԁ)ѐɈ $Ha4ؑz!R#F#*{2L>iZpu(E!Iv%9^*-X7%kFA_"+W~3E-|l Ţx{+  ŋWU\mǿ ¬]x'ntRܱ9\z%G֢#_?K? :cc\sty;"h Ng8^m} ;7xܶ^k}= ˽+=U=XqfW˃;5YV۵&Lj\nͥx'q!gEz~ē>z\U.1xb\-p\"ZybnE\\HSnG:.IBG Ha!X [U g7(v#z ^@@m0vn.B[x-A\ 3kѸ) tg<Η2=qӓ GeA$D*!>y`=8|ĩ/A\Doh MS!N_jT3E-r !~f? ~D\z@X H_%U6D{}A"0l~d_R`~2nj-EY īMBA q,0 pZbϽ 7AL&d&H fqV܀$HA|=ӁN Y g6Ae9%+fwV}3HB|)Ӟo@H Lt яlPHr CpJG3ݲN6H^O2ׁFV+0l$u@S IcHb~2ɗ-K a yB]tIc8H!֘si9-2px+_e ?ޱ\wG!5@`ULd"$i&W}H\#Ɛ(cb!2;mS! ݿ·BR2k“KY|9 P!$@tt$ڱאw&Bb7O2GBUH|jic!Hlt-O!$gj$ysƐĭdI<96Cɐ#CtHz{!wn)ӛ )>;[)1Tj.DV+@j$$ BH6/$jVw|2VktD57H?~ |+',Hc1ōlQY]PPGW԰\~Ŗ,3 n,v_u |ZbF ̂ 6; Zy "ߋ,8Y;Y j&S5,̘q{C̉ev@\n q ,a:j=g|9b~XVٮ)? j7@Y q'z w{!fc@GD7:^2y#!fK1".}7" !JN"<ȁѥ c%ĶCLQDdJA9if- '!4GJ;쬂!f=D;"]S L$D(SXc Q_@a:WA8_ a!*5DzKٙVQ;@D+\ A6A} f"D ̻dD+@FAP # l&ác$ dw teP7 DJ "CWDL ˋ dqaa ,솰 dvCa:<ZBX7j gjaA`AX'YAbvyfr=*!t71Bt3BA8W݂$ذ#d@Ё4 c?ApMCQ lH(eo5fgGm8 /Ʉ 'ٷZlú&@?lz@ꥰ,ؘh I_q2}`ío #akBiUhy~##8+]3i/l|, ߓ/oB!> |K`.Wx>n Y~+7ۋ`C>Voǀ*xto@幁כ\~^wE,x&w|_Ϻny O|BNK{1tϕr?Γ|_Vmzay} FU2 |# o/!w> |^`M4M/a^džW.4x/S #g(u_~~e lߜ?|;8ަ~t%x]UZ}-- ~l =_- ._~y 6f5ׁC๶|F rz>iwfxՍ<}  ߏS7ޮߟ{&|ߑ9=6h# }^^޲u|3>Ka|Ϗkg&o!&r- 63gOd-x&#\R~&.Nk$~goixzȾ>#Gg_1xd0Z7q.x3omm!y><كϘAٺܻ4y<3;=b<'xOvO> O{Y>'c8x2=\"9xfkx!a:p yMnrUޭ9} sop{ S"p/p \?ewp;^3g׎#^<& &j8 nO U8`r '_V-Bpvb<5i?SpD>8%|Ǽrf88xjE6ays{p;l0 YQ3s7O5pʱU2PpfZ\C'2\^p>: 8'q䗂#}3pMra8 'e=8ܪpp1 F4|)w8FHpY zk'\gϣik'VGJ.OwspX.Rxp2.=#W"3c8G1rq)pʫεg~%cp3a7"s`}\ph[ vZ.zgqv=s|i38|N"ol*8|0R'/+5 2 6m{^`}38ez}p~zK\XAtjN7) pY έ [<9p(8Tr~cLe1~ceow184br^xpTaL:q[NjC8LҘQ/=&9^|c8|əѴ*t5=er4,yJ 8c4Ł&ӹL4ЊOE p /tsOسd dk6Siglp8|K=`&<Ǥ`7o8d9spV<îݸHup(3>Us -$700 {3ݙ uyt 8}C {qi8 <`}Rge`wv]NS=RDSm98};pX|4Jj`}zp| 7x8 ^;bO;vAyx~5;9v3WøZ/bv>j8ڂZ9p3@L?NVCE,/U;ǃ0[VvoMVW΁cNÆ qWAyS{2I7OS35`Al`}AI\# fl҄_@7l!|lıK ow@ #~ %eWa (B#. ?i| l< ToHCW% Ɗ'ڷK!t:O ilC8k }'A# 4*!HNi* !!Ax] !AH"Cذ: lM.ѫ C"vЧ!ħ" l^a yCW^: M ~T tv,w=yK60 }:Z1 jk܄%y.vl D)ClSo!@ȅ9$;sF@D=5%EFA؇r¾@AQİ!o ri D7@XU/D};* yD=aR r(a5D,~!r6f;Azp4DCd Bx]"DEpjfc~@BM&sSYZ4"s^Ah?E[!|l /&I0H5YM!|?x3쀠uR1 s6VQ="6xۯ!b#A"86 D] Re }!6+ D69 1ϯhM x сA4a$)W` ] vdo΀!Ga3b@tw711@DL vO5=AqxV߮_7@lKJ/^@|h9J\@cqi5A2>  @]|$Mr >X $v@$6LȸV$ ׵!*H 2 L6)@B$DX Hxw,A .I p*=ͫ!VH|3$<$설)'!_H贄CW5ɐd$fCrP*$m s -w|$Qt @U<$_w _ 7ٞVH w!%yHr, )j*3@J.H]e ż~5jRTHUAZI.U Qi#`ՐRe Rߝ}/¦7!-6/g+QY6i]aRlA>Tw܅4հi-fׅ~ 6e :}X[ u7O4RRπO Dm͐9Np`!5 i=+!e>{i *z aK H mMOv@d6k@Z'ii!9`,ldw_n!!\!q - tHɆ!-6¦ m6[H?jfiǼSof,Odoٵ4 \32}_Mɋ7iٵ $-j-׬`_=PsKVnչ[simۿomۿomۿomۿ?.OxOѼHioŽ=kOƪ \Wx> }e/wWjXnYaq藅?f /U :;% [an0caǂz/4sfng< 03^`rD+h' '~sN Yq!1A.]P8M]J(UƽHf/~$y |&M(]NL7 WX:B0^) -])  a[X$L^rAj2I. [`" m8*K$^H{0zUϜ-}0nF0Mlc6.J0=wO\MZ0 F(L#'}.ލfe P,~&V ,="̑v k;o C 7;~W}HD]v&=UE[ BܓB ařa5-,0Ft,KP4 턭e槓ªUߋ%A K I]Bp o*x kG kۄB`-x=6%D.+R n¬&)AT&DaB'BeBtY%D~" ) ˄HXR%x< ;Zʂ{o=6G7 VD􄤟ABWna\Ul $Uo0f5o l"$ 6ءMc#ݜ)l,^*3u}F vz#a9 #/Za83; N [&𘙙)d2ıtfff*̹z~ֳ#e+OgڑTAf2)ĐCۏd{!Cn.II֍MjY굨νaR麒|c՟F& IEc ȭ*/2 '!dk<9/C}S%Kv_IXB6'a8UD#sop?rh]3DF/P$%KLkd$.QN} HܟjFlnM uIɬٟ$i|T_Ú~ƒ*^$N$_EKȡt I~~kуOɧJmr첑lN#69; BVͤP7}ɳU~zP']7ɡb8H^]\kFŏvLyS`A8 "NQxm߂>o; O{>d|B^߂Ðȭ\&m"נ%V}3KNt2$ }) `=I%c-KiOCeE^SD/LC}R^O;RFȊns)xGur '5}MoT#Ua\:T'qd^!YvNvO뗑A NQWql>[xt$Q{IdINVoxޓW1)Wo#iԶ;9b@DR'€v1НJ=O_& ]v̚櫚UU3~x-uNm]s j&ר)L, :Hhk.ܹ C@RdԘzdqԌ}$(CFQEdd;AfIH RέCH O~s) drl5<{jmZSKEjI-B{䰻P'df# Գ3#>Kj9:R}ӑԵ<|N:95lK 7L^SWu4ڽ}N漏TLMzzԢYj1i&FS~vTAjX5z<{U}޸5]jL5FP$[ Uo>NUMRuJT5o7UAU'SWT2j~APlc8#+iIl)FN/Qmy!C+N@W]v*}(]jtjX{}5)V=QɤZ[}?ڵO&c+2jM Ժs5^ە䏩ψ 7r0巡΃ӏ)iy5ї:S ,@)kHrukDwfjj{LmlQ'da5uq é jNRw%m:lnS o'2{ YAojru>u^:TA] Rߨ.AFoz55~:Ofadwo r57)ͨoC-/GrueGmSiCI9d;uUJ|R~Թr ѻАg1lBP ө{E) $ǐd\:9Nr>.xeOj#Qw,KonS#FLw~Wq5BvWbh -ȡi,)crH^Q)$ 2ިI}XJk۔/C&S;T|E-SD CxΐhGSow5WGM6.ZYԣJYQnM9wk=&.Ժ`m"b7 Rꔱ,N6$8QT",R4JFs֦שd8:ZQ>R47&K4 33MmW G&{Q՟E Ɍn]rIv&qy5<8LIц:~B;:^LQߨ Ie dzoPpj1Lߐu"!oaw|>$Z-]Nņ䢰 +s ! grN.QRC>)F-д)m2Z#+5F}23JKqؔK¥;Tkk$>7&yj3zq!;H2ېF6SӣHE^wwdb 4I#K5trGoR8'adۗV1'JiHHV\Ho~V$S!~d~g$ɍ#rD&S|U2/!K$>>PjxW-t$"g$MQb s;YUIi:ݻE=cylL$JۂIv%mE6y(EjHsP- uGsZ oXE^ǐ) 9 Gr;2e_#.ߒ|ͤjگ%ol oNg-9JQ3ɩm=R)( C;Ӑ [(nI/~[:).E>lOZ` Q\1iRJ'(1o Ŷ7I(q}Yvu`7vS_5=T&Cγʇ4Z~m{P^=ԙ֢䟖;gY<(V!-FVSjHc][1iTEx")lEꗘDYRQ֧F:-ʑ (6 iP;=j0L%Uhx5 AQƾ[4`zSЏlm 8x7 uٔeLܪC(biV(DKh41Oitrn o1ThJ*}"T$J;YQ|~Q卿O#/hx[~vQ}/Sьq4[SFD;  #h94 DYh,]o1GIIg,MM :ӘF/B+T4Sgҕ[QeE{Rxx2eW܃%V{҇HĐ4р&&idRS03RXwSb]*5Qh9S 9ܮ{w hr< [[) Ğ|C^fڥ>t !ߧ )dn X{ = N!NQpLFqRw o*>\FIKmbR)bX[O Q̬qfE =LCNRoCɔߊ4# I6ċ߈Tn8p?F_⷏x}wJ.AI;M(aN^C)aR:̦~{]_\iG/JM äQ:Q68ԧϣU^RЕ)MJliP`T|#qJFߌ).ٙ`kJɭS>KPRb:EU\w.=PNgG%Q]崙IFSƤQvΔ*תAv0?MXؑoO ͗lJ/)n* =؁3u(r\X@)I+H-I)SXJXH^R1 J~0.MmA^'ו"7$m"IMST{J6wMo( §VpWWhLo:Qו^@P ]BͷST"ٿɭJ-Jλ{]܁RWRDz:4'/ɹ2̟/ SO.랓_)&dޮ7DN] 80쓷+rpM6s-%W>tݟ<~l"jd{ވlj#o>f?9|GSvR"d꾅Tr{_UKȑA d5ʍLdE7t=_&g$]c)d4j6{Yv;QߠwGeM#cȬa}HCI8DBK$@%!ԳO1 b2.PW:7z R&A׶"3!Hc#z`8B7IH OQZsL2sK!2%J~/YĄd1~dC6%;Ȁ^Ikp>^Jk'*"dzifHSuL>Y>[{8ٷ!۲өf{dBd=:ɪuIt#ruwWI90.i'B!u )CEΥ(fQWk 6k),xSJkJU'(uZ:7^Dj);J3IO)sJVoS줬h4d3άJCpy]<߷4~pS'gPiTzڟJSTwRDGF,A4 XƸ6j4vu! vx*:ڌӧQэ 4[40bW{]廉 $b /]@E~QQQ4srg*o $.QsSF]SӰϨ 4|}s/ʯJ#p>Gш}MW8&p3q@8=JFSI*STJ2~sj'RF4zeex*ʡ(*@%QɫTg#~s>J{и;i_4v7iJMleHI>є4iII3}:cX9MF6k4n^ Bє4~g8MCS7=h}Mo5fHV4 MR u)~ДEiz4=$Mi4ŝfG3.L4f)8׮DSL3x+WEnh|T{Tz-`KfRՎ&7^M>Фiw?3yJ#*TʎиZr&6 T~uAe;7PF**wJ8(Lc"hR*2In/ho+OQ2*qL:@̣"*N=#*woG'и,[bAoghr|)M7&M㴣*jOiS c&ͧkTr ?|Dhe4i>7TDD%SOTp-'M}JWD̗ŕҶwI+dSjDJ6էKg(9Xm$G}FRmKJR( JnNI.߂ęƔd.%qN+)n >bn6V(Ⰼͣw()s]E3vžyEf(ewiLNͧԧ[)e<%T 3(qHcJi>;R Vdg*O&[(E7]GSr~yBΤt  dSTQ{4E-zd "\oRf|+Ε=\wN|5UCaO)E׼OuP\ @(AݞLAE)f7Χ ߪ28@+wec єPh z\QТi΋|^#Wȯ9 PR@Sǖ"#ȯI*y 'ߥS(psZFA)u(YF|FbJ;wD򙨤)t-#u!VޙSȴmIR_HQc)ՅjdHQS ;BﬧƎ؉=SRJ {Bn( YGQXRwr|iGɯE\љד9=<}'L{.ԒO{3䞚Gq?wSc#-#!oMl"oCϨP챀E{pwYK^ X0뺐s|&9^%["e=0cNʑIi6oCndF KRl^M2O$x~!aH s) _({ մYd۾))5VK^9yxA^Eoז/#ܾ>.yȿwrxۋ'! yO{r\DΕ_9LNcSG>Ktr#|9[ 䰦29OZL.ȱ [@6'lNMBڀ{=ft>@ rN Yh~b[RnLuKRV kET-'aCd7>v"'RH]Vd./uQ؀6nI.#=ԷȲh5M^?gQ`w;E./2JSlX}FM&WIэ|ߙ,$=HqR%ű'NZS'/R4) '}7Ŝ9CiMqp`9&L &ِ{Rcs|rvޓAWrF^ T:P~F_||mGCRjRʬ2W %弢= ne(Ǥ8 =Њn 7!iZSԒVQymJ )a7PAt|f=7rʛH$CNalB!)~'JOmΦ~TVKHUȦr\ž1YH2mdZk1IEr2RZ^V# XR?AgVo07Pd2CE2udT$}N,X!nMKJIɨH} jHޫ/VS65;N)Ԩ R*jujm0kS+׽T}!j}DMS_oj~;?5kwL-5R:WN*BuPUqjvI4uΚD-QO7šZͣZQKdx~JM;!7woDR곩ji ~8QvTKz~ 2_clGM&F-Pə̔,Zi}Ėo/q֟>Zx~8V7Cї^٥~ѫC6'VS:-wtOMwbAU!k-US9Q=1G^&Z.zUtY/ZvdPˉƔRqg5Vߋd8^Qg5+JmϸRۏۺ+ԎsJF~Q^Xn8nuكB-kYҺlzZjmL'rޞ9ozyV9M\̶]ҌjhƻUNʻ|*`ꡣFX V]`jc5[ݭN: *x|+[Vڶ-d٥`l+wͬ\eաnPf[ yb5gU7VƧYeվnp%'2k$G^[my%j85ZՅgYLih5$^~el4.n]\BOr{tw.a}{1:qMY6ҜGΎE+#V+Rֶ͓ },V*X%̮/&#5fU 7%\\UD(.+SwYѶ擢Ƀ.@{ѣ{q(RZ\>^K&O_)iVs^DJcs)ᄕn{Xpppxg ѼwErhVf$z\+亟1oc0qL"iU:OĻK3a~0K<=aphHe\BgaCf뛟Z^ W S>bbiNApavL:xP&T8sXy٢bzR6/Ok%s y0 ^_ӂeeFyOv ¥ߓK_8ۧ&xb+\\^O1V9XФ4_?]Q@XkKCڄb s:겓bCN'$L@~h4׼Doi=wa뮹Œ"dm+pUV㲴{EqUh]F8Q2Z-zLL9F}Pyùbb3b=a◳!bb+ oF<ǏRA@13}gX?(\h_/W|j $)\eH_S/Fj.^.Kt8C>@6&o8tB=_qy{dck-Xer)cWaxbKqu\E8z1T-|e5km*S(z}V(8M@a^Yv\xM+Yj].oi,nF, ZKZsJ1G}U%<&59$!)/+:X۽YqMZFN?'4u ,M ±)WD1Rh7S_u+!G6:'b|`{i\gncHϭu̺]n))t֋UVWK׃Ob ->7s$9Q_^xanX:[\uDZ|bpX O^t;v8)aiQ*b/a@`6esug]Ce9CgY쇵1ƢX)A':RC$_ܓĊ/Cu/\&T/y{qga yH,) zXZVuEpYѰ"+,x3S\pkr"RyF*:?IZg{TQh.yuB8N gⓙ;5smr;?FmƈOww6 n6v o *غWj+ZN^(MypSr`ºZoCRxá-hYTZ9]z&KxXUiwRm.ݐ:N ~YR䍑p wLQm^;E:4%=lT$?IzN$!c՗OHѶvRѷWfJͱTzW7]m@eRxCWj/+Kzg _{靗-įf^6դۥwsJ zJEIZJUws%,'MW[~tݻ'U]I>;Fq{ź}ij*=IcqҭBEcoH;2¤HJH,'bN1A]Kr1]:6拢EbXŪyҷQuWL4?,Y:PZrb[R1u$EPE|F1 F~b\*n7n8SՓ[*Hͫɖz"&^ Ɨm-QȔ'S.-+YOZb9n EHPy,B"W8Y`hyUm5 ,8I&I_Qvx.0-&K'^KKg/Ƽ)li?u-ZYs0SojU46<# 5?n骮ĚE_(D[ufVV&8U1ǿEIgBc+hO,h/,x/hT20Lf)_l,PUYA߹}ř)-(+' ѷUX#ua|wc'o?o)+VXk+  ;N#4}.4a(37],\w9بy-R_9/ʛEM?ee7S*_!++m/M '4{mU!,+ _}%߅]ts4 U? CSs?Y*7ϛQ+f [©Ef}FMi)XP]˅3] '5Ƌ+W0U?6AhLEu+vx?'K^Q_׺fd%Neݽ!ܙoEٻ+x/m+q\E)9ipOu|(\۶FF lnL˷vNse׬҅+|Y{x%RX.tuKt,TYwdv-yd-yﵼX]Kr|ϓdw {ETuR;)EV_]Sn_~7xcȟI g^=*[0.lBvLzaږl\nˆ+ 5Ke+tx$aϞ]?}o U*?PpϿG4?,~Y1鋃B6dD%rMlhţԊ\Sw ng#H e>n# , .I6۟߰OEy/$ z%ˏy(yYC~!滥쫶(lt1'iBsm[Q Q1*U?TeYayjYNQ)}rEK)_onWH{Zu '?}ֿ?WަP#\R:&vᑰif}VT׮&?wpnDIL_)kT3n5!π7bՂ?;=Wg4G gs5m|?JɨΓnEW}WӿE߹Z?|ȯn덅-WJ[|YakY?oW–:9S}ȼl=R6l+ m:. LY@[hwU}3_aA]loVc*Lh=v~7e+kQto߷ne؊lO휹BWNj$w=}O݌Unhbz5oJ:IDŽ_09͓ i5~_ m;LMUG?ĕlӿoB=g'3nj%;^itƚWl\6 * e^Pi*< C*-_eO]PGa{ |@hY7iHDOM1Wx/VRK:9Ұc^lOBbJ+ztdӧ{[ BWxٖuĹ ɥB7Y  ҭBlo`Tn_q=Sډ dKcs!q=ϹzbOFe4FkĜ$Ź_]Ƙ>*, .)},$?TNl6Oܕ5^T<#4>(}?on`}Nmk&(~J]r):I 7_o#`@O' Sd%5_J+N 'E v=fIowIt75pUk'sIDeGh]0Q8_]z񺑨J~o|iJɥ.KRkBWFI~ Qd{{ESRq_V9w4c<)^xV]()UZ u1۲K*{M1q|CSܸ}1bxKyB=ZTIR|4ud4eD]ҡf|,LjfNROAe_0F+1f2n2O!a/3}W^]ȳP"ʕѓqQ<bu_썼.7i,:@^i} ^-<cl$r#f3^m\?1G$ܝM?ː,3lo0"?hR| vȗ^#y2E~0䷯Ñ߀|@~å?f"%gC޲$^Cy·gvtu.FW..Cnr#` 5.UEO1`s9/ ;9 9>Q ENMB?-{nEdg*#;%E֣dvDUJ,>]y32CnBM62Dfͺx:g:#C dC\)`| 3Cƅȸtqx|Id[A*d$!,22߄G2NnP5njA= ]T3輫Bg :#+ 7@r;tn%#83p D_~%ҏ#}CuH??g~1GH][!}xtG:^ ݴ2[.FH{i if m/%EDrCZ> znЎȃV3 7hmOBsM 'RDGH;]:'RAjj uDm}Ԏ^HmyӾ ͕!\tZ+h/v059ܸmqSx| 4'>Cs14[͠Yy?}14Eà&a(47qa]h:?ϫWP/+A7O1ʵ6?hF͇Ƽ4*!\';h\@K}ƍشƣ3%Aceq4MBS*T:vPyw܆z$Cԋ g頞~1 m j PuuxH9)7")LDʭHyeC| PW%Ek) ]R^r_iwn\wɼ%\OcEʛL{HU20W9Ե? ~Bݠ ԵOAݨwc{/Y>x )"dC>kP?O,~uꏳ؇/qv47!C 식c=T ZˠQg wFpgQ h쿥-`~uֱ.P?gk9ݑuZ_ oӡ utgq:{&34>a`0L P,􀺈}ԥlPq}8;^fZޣ1l?Q|z@1߿+?@ :iށ:F@@p/ICY P:yp\E|5x.n|+pی.&1ϡ#`~Au\/O}z@jo7q̮ڮ&\*eP[M6Amξ1۠g/m݇u u{>Wpٕ3ۿ5k]궬!ۣ3kю{^wg17e{Yb6j˜uHm-,m6oX79x}։%Ձ94jw{ϩ9ݝZCs1:vžm|ӹ<={8>j *Lx |>'ױ̈́Gloٯ97hjE@S%,g ԟi׉Ps>űy|veX6kI%C+:;]|3Unl/wN(]; mfDh&mf90=\4Mz'H ؎Tm-rBHԣz# j m3;;@+@ h M6ڒN"h׬v*hwՀvShA{|"^K=9s^ W޿hh܅#v wTFZHk2i"jw h_5F;gr]Xt=JXzL6CNhSVV +"# fZsC[yKB;ՕЮgZ5?FH3\4"Hʹe~EpoCڤ|MODz> i"K]f}ی}.rՒJ3#>u9q53s`_FwHkWЙO#t5/B2e@7!i^J-#[;}ݝ 3B: &pp.Bݜ%}bYof]6_nP9 =tSYϜ.DH6ޝxi -6H>zqQmO9<ԩHg?>Ϲ{#Ќ,sþ~=8ov9yCH{ )sc4{ma'$#9]D $});;A)#/<CMkI?t?I'#i L@R7${$HI") BUH\%N8>u͑_iH >D$Cb$Kpq;6B$ k4,L@7 !~,^Gpv7s4dy=b@(#6&b!M=ļ{31~1>1OFLD3'FوMAѭo"nD{^*:D9CTg_DUo]%'oC`nOmA)q.Wp%C^0'rX7i/lx¿x q9M W-~+G[?˝3L_@~E4 }>hߪ1|<ϢL `<|Z?}>usloy62w2x5i 4 ޳U5<gbxG.5x>1:s]]o΅~:'{j{7{pnZmr-B7v˾p= ZWX ]9\sˎphy\6p0ۢ΀sA8vpnNZ,op' IAp0WI#tcL.mv'|'8Ɇü8 !j)7C{8Ty<<IVn@-vj`OF#O7}A6S>}M;¾E~͇" `7#vN[j5Jy}*uh%?6e l}V=Um +lf*fa ΀MZ EؘÇa6LWMezvAqxb'|Y6\^'9ыe@u `;C6޽;m}]>u5>OMm6 {¦q$lZ@l>#KM5Lg.X>?ڄ.uMpTy}ҰDVsnUPʁ(NR(鍠 劏P.\(gfB9˅PqP.X<(ɠ\^;P.m 4Pc9^<7yA9ӚB9}xC(BYʑݠ< w(;@~2KPF^2Pօҍ}a*+(%((}BiP3 %<1s2y8:q]pu`Iymx=w5;.S|vykʻ\~qMlWkCyAyϢC7]l=a|NMbB9kw_BV~m B@ eϰ煰a'7{z^K:c~V 'a]u9<ծX̆;XJf}`>Vr[%X QEԦ2,`g,[}eNxbkeXqwHT}¢A$k0 0msL(ήbB1PօPTE{HW.C:r7~4m2k9@Rυ w$G{HِAtR9 @KA|pϭxĝ n3=L8Kq2XT  fBLQ1C\ oC̈́(g)z,Mm;@ b+mu>.^=| ' <΅ȃ˾np+F:C8m l=a5s!/0Bf,eBp\ yd|^=<n,ȏm|ȷ΃|Yȧd S] 7y۱Y ٯF}=svlsd|VlY ;!n ܛe,ud)ΐ%,d1!`pPCB! YP3B2߁d~},߿k&d3 zMWz=jyY#dW!s02~ٰLkB))Bf:iY{՛Y5%̾zI=7ο0;3 Օ`xja6fS'l'0+~ 1oa6FY&  \ 0y0,BṅMa*fXaf5a- C`0] 3t#4wLaa#aj 0 ô46S0&?8,Ӆ0y.1+j_7xL[<Լ'2a_aӔfL@ tt~M.ӵauO_.g +aqbz\Tar=i<fOGg^'`鶞&vLWe<=LՅ0 (4?um=0 @] S0ncaځ`ڼL뱽+'0b<<[3`r.L0L 0v]&t\VeDdn{ #ar&Carub'~$ôۤ%a;Lκ~=ryd~va1LɃ0&׮߹b=?b 5YO00ٮs0 uaLe0Y2|mɂ+ & 7040.00Yy&0Yӄ&k->`]Wwdd5Ɋ/ ]Kügqɺ/S1ٌO w~볆ir}ceL`dj2d+6u;e>__'Dzm+ƼX>ox`{*\'dp^dx )ƞ0לq&_Y߮hg<2ϲy6|;e?^ۙrzrKcRFc"˕r쿼?ڰb_ ckG`:٧WELo9f:W3YeeNYi}糸+̞M*׭>s=dQ|d'AV T>78Bv%i yuZ仮'X yxGu =9-!4 y?l/߯!m1߿qv0|w'CxVB􍁘/݅xF cH B;{1dJ;nnC/, EV&B-m8*y0;枕`5yY= 'GaQ =&©s5%,F>ؿ,aYΛa e7X%i gQ + 7V2`2mc upNZ*8OQp^ ?o 6b8_ußp~Z 7]% .U¥^\Kp1lpQpqGpW%*\ B2\e#r9\GN?<pUWsV} Wgpm =UWp p.됖puS \܁3p} nM$zLXnp  sp Vj{;ܶw۱R]KKcWJA3wpʶpwEpOp/6-p_[}t|KO _z:xz &Vhc PxC  1<Ư|;<NjM /u<<;\և[Om?k zz7|c9|^p]pd- n:S-2΂[^F_>n֟}+yf[VXFܴ=7ܒ>uj-3'y_f=bs -fn6e[,`}͚u*bddlܷ_22k7g^zxD,!9A>p d\at: n~6bEeyn !pkmEL(N9*{'ps) >,ccjgSp?pV8. ¾1>Wqf x<*lUO{3 <%x2x.离qs>J{ AKUʘ.z\ WQmnZΰwk<}'O1< G7>೶>|ϳ5_y|w%o_}6e^ {GWg ßfuB@[P4FW[ `f,}/!jA`+F}*W ЙKf@ F`*Ƥ!PY8t!pn>Sq| Ȭ*<JB؄ 'tAw *OFi-{E:/B!J_CHIWw!W6@C5!tmWfi;no{g¿>B!B-C(DhȎe':Q"jq.!nD[g!:3G"ZĴ|Č^}s {+b",qM7vDùoF w!^$tG ^ I$R 1'oFu$u[#HZlGϸe4@\C\ RRB2qR.:C<K^&Fͦ|T1A*Mphj@[ڃHriH+ q>oCg4m1k2,###25CƓ{fCd|EV|dIAvwd0FP ^Yk[x9u; 3<9:"Q 0c1` 8ґk1M;drK{g7"o乺!/=7E|@Cw7|+މAAȟ ( d^?g#Z9TFgC ߉1q!1c`ݱ\0Z``56 c~ 읆q7q&@^N䍜Gțu<r^r r{!b#Sx Km&ѿ>d?C=9א>ݿ RUd]i5 5z Sud\ \]>LMFwOBf^ρ!'H22@8:!f2LA+;d|셌r&2^2nEƩd욌k12 ##y%2!Cݞ!~tCw{)t'@t kB7)1 ]:@?:Mٍ :c26kEHjt~c?k;|] ~^H?鷫#]AQ>pHϑ`:'@ȕH@z=ҝ#Hiϖ"54GڸnH@7Hkvڏ -]Qвiu=h@AmIHkz&Rx!u%TΏS+!THmh*סנy ~ܚ ͽcOh^·Lh^v {KhM9͠Yu 9);MDFA/i㵪CSmԿz@S Sд M7'%|a? Gxt+Єh|[33mvLF4\ok1@SY P߿QP Lτz 7Tzid sez+߭6@q!>C}2c5GP<5C9Pe S@PDAjPi@ݷj;nlus[;)rRo`EyH9)mr)s鍔r!R! RMD=>bD X/|<)g R1R"ao w#^T[n u}3mZdC]όI~ߒqyzO᱃o}#d[4[cnǶ46w)w}'aʼdl,k bR;f]N3Pם:a[nBm-l^w淄i0lSPGmWG΃zq 淴PPa`7P?q&GُBӐc:\|M M1b5h-džAڊ;Ch"8kCS}l1gj<J"oXǟz s~WP٣޲P/cf-pޯ'FPg2PB=‰le1a\g-Xb'zfv"'qLp.t}xQ1[9d,ۭ8ԃYN>b^`:sӞ@]+\v:&ޤArܡ2vLze+j ulvtP2f8Fq,ta_kh~bȴ̏R}W>njf ӆm`j\29.NN,ۙsXqRњG|&y_p ;>sxܕ7Psl:|f$`<`;W==.?{(ޏռ] ޏ+ |w"" 2AYl,s}>kv.? e{dnf=Xn><X޷̃s41n^h\ M&u#9ާG= ͮph;>WEjH5ڃT%H AG: N>2wݑUf@4vrn ! ~`5c@;yK] |o 펟lv=.BSɥ= YC{bGx]h/98oVyҪAߏqٟK3h_.X ̇|uyF)"#6Z)6ߎ}VxhY0hr8A;ȟB]&v67+&C17] !D,iO]iC<__H[ouyHi_DIHwi""܀fӐ޹M2n7ېYn˜9 }S-yn"-U&CI=:@¬qBW#9%{yws莖Bw~t7{ܙ};݇}nG2t_\ߛn<3V.BtЍn ]*(W9]cV]#J6!?qHk6 z)Vq!:^lԢ#Hwl1} 4,y:(k| 7 ev"R|Nq$[<lFUl`~/y784Fc8@H:eKT.!i@#$F5Բ5j;#. ܬ«F;a CXB;YAXnXGI+:Bo!4j!#f臐B#D~~B)>Dpv!Xf 3^mDйj: ۏ~Y FhjsxE+!p!hy"~{VG[p O!`q/FgE@t.E!OC@6Oxqw oy c2ߡo[ q__?l}7Ww ﴥ _m,E 3AqN{ x.w Mo@Gm^Së2OGx Yگ˄ u;<.cxx(!£^?>w{h(ܥr7qR76*ܢf[pP6u)& p65&{\f ːAp \Zg'8_[<05sX8s{8W{p:NK|1$882NK 3F1 ±!KppC18Yߚx|86 X8F; 0t#؟Ey Ga {հ7ֳa*Pm[`7vѰ .u]SOxǣ`{zlW݀ɰ~  [;#΀m66FrMRfu#ĹM#ظFFV6-aST/Pծ*P լ)P,*T -o6T}BgTFPuUg2x 7;Be *y̙jC>PBՐP,W9w ׅj TkPm,jsھU:b EnBu T@TBvT̠QJo`S=65xuOA4J4Y`lZMHشm_lx5w6͖3m82l 6aS5XD N>wzް-^A\׬TOʡzxu սP%.rk5.e<~iA&#볙>b9{>֩zZ:jȡrISv/̧ؖ9WzCZjafCy3o@SG죠@- j$CWfP>^Aya/@yj'*Ayf( 9׍x5-"ϹK2˪P<Ҡ<C{uJ}7(BC fլDzPιPr@([APe :ej(}(J;?(mP:A:Jb(C:A~L{xeP&*R^V^5D#|rʏMUFGjkvʱ*ko CPyk98\Ұf?[cU.G^.c+T82ytPwg\2%ӠⷑJ}^A@,#-ǩ7Ic=-N׋t~U;PU˼|T̀WS((s_ =z{m#@y{)J(e`̃rg(r!T..Am(xxoL~@ixʦˡtORX)W` ksuX7ՙZUXr ޛ`U ,FXnG`9b,Ӧ28ٰSgX֩ ~/XOXaLj _ 5?Z|a`f@q# [XpQ7PGa γhҏq>te8Ó!mihHB*iP-HBGrɶ< ROKH 5.T*# ~=QB1egB<2D!iqy- ΜqD_ k!|qHļB!AbO!zo@([ OݛC44f>́0Dz>\ jM? |n!<\ 8gC8a!L at $ σ8BO%!poL{k@+jB>; }\ uG΀3\6a k@Qo ]dBUY^L :m_fFm ̞fsav wx -`fkl-?`h00;`6y+Ʃ`V^ f;a6TY9`fac 3.0: a̚s_mg~ӗS`zo5L/;4趒 333$3I6Cb$ɲe֕pLqfYuUp>PDH7}tRHg'C:1n@ji A fp?!]!m53!!VpzEHY@ZV t=*A*R8HxH3;Bj薐N>\HW,tKS旐^ }Vҷm!!;!*=4RiCV}d5BV$AVv9nC2@?ᐾ|/7Hv{HoH!ҳk =C~@ BŐNwt\$E[0R=aSp0tҞR;Uڏ>ZC$kBu5)/8{[H~/GTOu !mi{-RF.+Z~_)SҔ&S /ޗg)w++y\|H_Է;;hjHkͥ -K?S)H~u*HA3$/" yɃʤܺPSH U#mJsH.>lUHr(mr$G*Br $Brf#$osϟ 9ɽ'q- sVH&$]䂌#Ο @^!?$ϝM.s$CHD{c1噱<$mFJ=C@6MMnLexHCr79^ҍ9i-x}ve9OMRs9k$BY;o<$ I5sy?}vҎW+cG=3VӋIHI${'9.|uW 2~e6ܜ<}5nm pouB>f77Vx{__xã$G>)3!y{|3m;+c_m~ UbC({mcTxϥf*x)ᕘ f=.D3LńXB$n<v oc{Ux MJJ6cx0*0wp͈ N|[ @k ԟP렎 uPΧmBe uS"WS<1 \{9/9eK(CCxʸPF2PW^e@(y>=YT{d'A9}TA+>!=$ VGpJCUSm> ӌ mE؈I[a";«?Ex&)Dx)S>.WD T##¿m%@O=@77g!O4"j\GD!_oD :ɓ"=fFV; sz&Aӈܰ"acDY:Qʽ}4]iz#:c|AL2!fd\p@ʗ& >Zش]وkE\F-@܁ݗ fw"ėA&GyHpߌH :/G_y fDE{?5֢4~ۻ#[@&H\-GHIHJy$$;@t?p#I$"y[W$YH)Gʁ!HTA3H=iU!b-wDڭHoW񟑾?m[s2Bې 蝧@_t``5aFWEFniq7Ʃ٫Y1F!˭)됵6L/ I`jߑCґXg}r"#gAߎZ+ᇐ{7Yu[\y\2}?"D) |ˢ@7'|KVBJ#cPzl0 Mae0ϲ¼"7!V/Tu x`ħ#!~KoXjZ`i`,s, Rf,U! K٭@aėo >: "Av ` sLax1eZDQsʯ4GBg<փevXssu X8;,פ}kXGʽZ}m|؆+a| aak66᰾ `T` (۶~ܳx6lBaޛmSXoU VXn )V\,3Òj鏿^| [yfN76m%oaۗr?[`C9 &64lrV 6M kӕr 1<=5 l?ڕ܆}3 kAX\zXԂu;V7mWzXO{úvD}$ Vkٰ. |2NU(uh[Ҟ`;EVm+ls¶lzY߰NO`VW#,yi~˽=GwX{Ns2XGҞ7:Kg!lh qW\|w >G:-uy$'Ѱ!m,+XZ#y SԙU` 8 k$ڃ5a2X8(YG7B<B1Ou!滛/Od4QK97.𾼦- fM{|)gua &c><<}D=П̙dz?ށ5 sYڱa>Pr©XY, ά*)sF}۬ '¼oPQ4f-.֎2t+ѝ9dυ~~k08 ;\\??a> M'`~I]۳ff&[a&2q",Y-*,HjZa'1B}ZLX+Nu;X_0u`:f ɱ|24wX&G㘿N"߾y_Zza!D/*W /w_`ֽo=s&ւy0oi d=MbߔbG_ĨXR~6E8ln'aVc{ 7繶9V[V Fm: Dbװ-g9փIMw>l%̱SYw*ئ1,dw26G%nl(Υm> ./N0]myc{wIvL:ޞO.ƚ9w2}mO˛̏G؟.1o]qb^d;v{R߽#wLF#iɋ搎tp yx"#)W,wؙ<Ԥlh=GخrneuCyzl' gG`;G'ϰF^nv_w>Mݴ\D%רz?ȣsȃ4I{i ߍJׯwGޠ=o>kգj=flO9O<{:/ֹu+m@_^ #&|lgi.y vO@{Sk};')m}@n"?NSNާl/X'\Lx;D=жjM̬W{^_؃ܙC];9˵vԏwry@>w)mb͚y$&6nϒ);2Ww{]y\+fop{Ksž|2Ư0n.{;ȷZ)F1f2Nnw j.xr)V2v~.Wl_~!~6<Ø88XY|kd/n$66þ:6=gćSsg#][r:üqہkFf:g{H='rcaʴ)s c >꾋x=BpybFϳvs?M]nsbrK>vxzʞ!ҿx$^w~+qvweLe=O/3nssҧ߇v9Yc4|96;wϳ'pu;@&6aLc߼;Tӌc(ۑ}&C>wX:YE ,Vx|5 63WRl>5Π-2bNJ,}Ŵbbnueޚo+ָEY|0FKioG7HSDړbKM='SӘ'Sk&.G04qwhq}3YW9n23ɔvx˜WBOi4f:>yug?0u*4OFs&{&R׉̙#O0C!1bbbg&c5=q̩97Ȅve̎16G1888,rfR|r-K&3W'ч)U-siB fNb-P>ġsg }soI/:p#kC /s? /<:V04ߙͷgMu\ԡ ֯|7Ga}֗8we|֑sVXrwJmu Ww=I-Vu._z-q=ڥTymZ9c*F=hۺ{Mb:{Qj~4\ *1RdNA5[XŻ6Ub sTmՈr"m]8Wc劔d8|R8K\e^u:z&(KmyYF|%n2?7eoXliՎ5+X۞x˚Q̕ ֑xD[dͨĸo1[ś#{ZMȣ&!_ ;:n;gO݂os׌c܉QzӜ9%kPKڬ!}R8m@sBٶ[;2_t`oMY;>bkN6ǩI=+gEb]}mrDNOUVRb4qJ V9=#}@fq$(`D|ï|/8CE>'pM |^'Cאg9. 3a# y-^{O/(3?!g`}njW=y&~}ߌ)m9jF??&Q*Qa -i=wc_ڼ8÷SWn=̵~ОVϼnܟ##|by/Lc o^'?tM3};RXouzud9U7iS; RYXia}{c.^"ٕ +ΰ޾^Sge|o2yOQ~o} h{4mo'~ț$<{ڨtU!;8wzˏ)'cC[ާQԇI^bʸA_.w`]N^qww9ɹM!ԉJfc7s/mw8߿#Ub+C<$ݠHEqxs铔PIYO%֡J n;y QFIrE?S:Bߟe~9 0=`=@V(!Q⃼(kA}g37}9DKg I`=ލ69N |b7q;3V-efX֥լs򮣼{ }RMj"U2xUcXsn#qc+񽞲o u:nbZ71X=F; S׵rsghUG"uboѥL䷒}#cjq;XB3x8M]F3bZt~,sbg`֮A}s0f8cc8eC>Dz$m_8LS/q_7p!27,cY|5n 1391:L#y|-_[=6\WX(嵘i9isʽ.Gb=ZDbc-C1`=>ru4k /dZ\ȸ]Hͣ?0o,`\H~ b-~$VYPO#Ɩ6ʺgpLzq\yQI(}=6x&cm2m4vWʕl<4gS%L⶘q:6-!n${"11y8B%^GΤ:5c}G-x nf3~rxw~B77Ϧ(6q]m\y3rڨy}yv8c0m`~S?͔u0cm?9J{`-º0;( bD\`J &^$;X0-Lg-!NRT樱<;uj$ƣ(8c,=7dևqb1f"5~Dҏ iٌsisFrq5|\Ӊ̑KG ӕBʰ_ a0ym!^y9x>JLXqJLO`~O{N$^ЯC鳑?%_X&.a yNa^` ׋:1埾gg.X_/&2?`^[^}񲞸[q1v2fL`޻E{r [όϴwh?Dze.z:{i[oEr-=_$D| ໨ UUoF#[p=j[R n޾cߋ|Wvo$gI¦y [(-a,lHka;6o l}/߭q[?SÖf ߖ)3)Oݟf{6<ʑyf<7oN:;4I$mk=w.lY.l&o&jO Om÷rx#ϐfl0c&Y̷B؊wׅmS6 lcDMW7M?6o^3ڠo!oK)ɷ(B68ow3٬O͟Geڑ6fLf|=;5eb R \i;YW25|{~6Xn`99aax KuXCW|82πa.,˺O DƧaQc!hkq#b,ĬLq!pbg[+G`s0vYfX0hsC&/I`{ sB0z9I%'W8'C`)XX,e XQ~W'e', IEXf2,CWR,BY^q/N?0X܀e;feJ#XMqy̆ō5R#g ^xv6r 00 ^0߱{׃cX8 b>ɗ6b0E>ɧ=`>Ki0o|!̷|?0?= {IEc>x< ڤ Xz(`Ft ~taI"ڧ.zY,oiCiϵ|m,RX}$bgG!=|`q!1>G²~X`yx^3~EL3.J(M 0߆x3uGb]J^^Xxw,ڳlXaIK=b5,&eS[ܑxQ|'$O֞Z>"a`' 8Eٛ{UͰf_uA<1sdGY]':-K`7\Fξy,O\f:EU [u|?ɾr%|OL`1>{BWsGJ:\&Ӈ25,XްT3 6ѻa[^Gy z[0uȺ5i\=NYWPeP6i|7|yX\GL+JdЕjw11g.q zLK9 oּ8}j7+ڰY`_@T(`~̃(=41K qQ"B/sla)e:u:݃5RQ-Ǒe!&wxi?u{/g/Xk|:͚{kc{҂5Ǎ~g-]N +c>,rkAڶ.m\-QQ#U7 qBĉ!sko#!nM]_7SFשj8̡GRLc*i2DYo+9:"iV{Fǣ fM#ڳu4AbaVX;u؏w]-927 ƌ!697! 3ٝ{-݂j]o[)ꬭyoE/zNc.ckz i8v#}0?Xw:_?s0>mAd0w!q(| Pxa6 WOGᐺ(CaJ(Qm( e 7 |P~3_ ) ?^@~d܇CK# 놼rEAȝr(b r[(rΔCSȱy!'TS"BȞ>eYn#azp`Z}0i L´kL'tm*LOӧ\ޮ{:4L$)#L Of}cd}EkNɎڝMVE֢ȚYcUY푕YiYRF,wuߏ,ȒAV7dZvjY\;=׸1Ȫ]Y5ȯgdn̷3D;/y.;Ȝd9E3d6 O0ƥ^0cit0vZc'%2VA$~["#u2j#*dڌ`ë0\ Á?0̖0 ^C `P 'kN&:л= 9w.0H_ts`h Cp Ni*7^A? _k݆ }D3ZC͡[Y.>Vw}~@K~xg.~r ǯ~XpFYhWO暄à^s }gxAϻf@}=A]B/m }з }AЗY};Ac~C_v^oM_t;CztkCw(tg6B 86܅nA7g tw`]2C5DNAG~ICg z w. =8 ]ͩU ]({!_"O]uFqHoǝЕ]?OD1۫P ˡ:[׆:C^2N:iC1r&uλ>kZڿs&t9:|s-ЅBxT7/~g[|A5B (Ձkt{"=rz]zeM>]2 t%=uáqsQݺMسԟ-Bv{rQl} ڥ0=K1)+3'ZR녳5Aϝs㡏B@3ĝCAtW3YR̟:ɑx?K[yg btk'Hs폠[A_/nPLAЈgqϏ%oqY&bc-eZIܮ+uzʺatkE-"]--Xǜ[@\-"S鋡CjJ|n*ezk~3@7E,f ]!搟L6m'VC] Х<(7Aҿ=yn̵N|ȟyBdX@7X ݘs }V/''MK9qdlOD5ԁ11s,mn }$s1JV$+ss84Vdv1<+?˻@31D9<'FC{t0f@_Fk_2Ϭ?z }}%sՠWnޗ=BށюZ!_m{̗Vh=qX~#0eɁ^ۨ<{N^GCm0x:0 \Z5kn AFh ?"2‘12ƴBt52VTF&ȸ@Pd|'8cU# _؂@r0ʆF5wN;` ϸQFPQ^ q1O' U`c1cj[ i3 oXϸG؇$#Hdyא"2~DƲq92?ٸ+opޡT |銌c{rԩ6eȞ#s1T ^ KiM0K#}d̲ȬVR"Lg2W"32c 3v2u=9j72g sGdny2d6 kd&Fe>pfd{u%.u!adSjփY}:{ԃo30ςka57RLu0ua?b yCzYn߭e5vZʀjwY 3;2{0WM``m۹X!&!EdtL,F<f `(+2ݒB*k`cG>'v0 c6i]a?"}}tKwI@ڗH$G-H icH?*ϐM@Ha{:ŒHuy.Z:R>mFHS)G!;RrI)B+Ȏ";/Z!y$|ŞHօH6Fk=@r9k I7? 'C Eңl$;%4#b"wFH>#1Ðֈ~o:[~v_#yBfЯ }{%;w8S}E]H} F#a;$ *D$;OR!#^~5uf#]oĝͨ8TjĹ@\C%bE앉 g"Vp:[[_>_ϥƈ>E1Aa44_%bVA1EL1'i蟣}{!_hץnUd[Q;59Q6DXț!"{ rX>"D"e!ioD|[[?q "VC"!"j1"9׭f"i?_!ɅpY0a?nOA:=Ž@ؖ Ml6Ga"u* |CϟB o[|k M-\C2oBA!Bb~ BEH7o 8o[9`^Ap|Az"H#-MAЄzA3jF p8NOT% -;hW5vThs8mЖ[ͽh~khFqFêPzjk#AOP;PKj6VJ4:݅O ?B94$CeםP3怀~(z#O &q{~o^-2y?k 3h|}[=Hg- c3|lӷ|/^Ttd`< @~8GI+=_|.% <8 a7k LBx(ZPYuu >׊./SxҾWXx5Wc|7dox. iU9NϬj<2 <As/j@qzXQP؞@ѿ3pE#UU .ͅ|ח|I!7WD䡃!w/D %{ Q NEwo7{@+^K 3 W %!|-{gB7P\"WFC~;ȟB:u. EkZ{z{h͡h3z:(oeT8A DZP@J4B£&H͸' φ )tR^w(ԃ+χ=ݲ6ɯeM@@K(gx(W8.0(*+(e@Qpn"sHԣ]'<Өc9&u+յn^"t')Fh^6R ;b\ =qϡHkE X3PpQs i1oYs&<ǑF?fO<TOx0y0<' E N=?;ýB ܀^ 淃۰FpKnOpk n (\/(.\gUYp͞p Wd<|cWLx.`8 p] ΅G.pnN=tNir8 ZN=^ԇ'8> x [8gr>uW Gm{;ckg8> p,{ߋjnt8{ p`v́Ö\8oUWp1fô8? 07M rg N8$=CQ8uYpp38n+БZphz8oHIP<`?:?q5o؟ljد9}kF>>t2=um ؗwaYpd! !od.E489=xnp]JN/4͚6KS iJ4;*qEVr,wRLמrAb+uNwݩϥ.KAG~"GR9^-o:?6QO ZP ʡ"{sF';!,,1~q_{w] {=߃BYgM%ph$87qPkp89}G>+|cQv,qP8Ʉ6_?©"89 MaF-p:9N/8ngE!j?ENKpqXp)(˴p&p2 *{W#\3uB2\ހͥpz nZu3" pn,,Vp7}J{Q <:?Z~&*  PBލoUҾytwmV;ߘ>w{Ai?< |{y~=gu \w][m|9wpߓH_KWo2_>b~CoU᷻66߳{{~߳_aKM˳᯼O #׵I ?&࿨>~ */G@c0R8}@aj"! nz" ~ȏC8# `zD)8 wb1(ˮ^סN"2 Pf/rI(AEr/(OAyg?CT5UBj3TJJU4JCTOAud(T׸@e@]P}z P׺uP{uVGԁ'CQTsC=äPOy A}&O+AS.͡iMиC &%4U=ZC3*4Y Ph&tf.hr̈́&D th읡M,u9@}~GPEPuFYmu&ZB%T PQVՔPQ'uV֡P쇒>U֣~G 쿂-IX぀y2KI$"@OF@HM@ʼnĄ"=wB ;{Neh܂&ˠq*DE[C[ =ZP8 DZP}#͆'ԮcW@K z*qq$Y/uiPIloƜxȆfv7hրfG14o#򡭻摤жmo)nkݠx m+; m+CЦ6ɑZM<~O6LWHUʡ7@k,] m hG@K6k 9 v4h  4 -v!$UyL>jίst!,FP[DPs ,A AwW@p3-+#oY|3 !eo#P~BȐVYR!ק#ChsJuBO@d\0W5BCW[waZ" {E ᑷxf^S>.C$mV~ε!b7E#|Z |N-O>EXCDaRޮj6D{#]Ȫ`0"] ň%9<3ED{(o7DC6i]6 "/ǽD4TG1By6}:5G'3}!j:b݌n_ U7)n2)Hh {0vGu?FG)]wC~q'ߺ!QC% S x! C!)StmGs/n!|!9{2/"R#e!yAoH}in& ڊuq2ҽ#}释>ǡ+i݃% ZbR|aX=XƦabsø/Տ ӷ%2Djjf@YT}L2`VGvٓ#lr:" r@α|*F"7 Ƚ3yv{Cް;re["߷*G@s}P4Ct(XgQX [ۡ9 GAᶡ(6 3a0/s{aaGjoX ;qD~ؼ f yKѮB&@x~C,1пݔCtH^b#ȃ8fπbj.A<Y3cQ2c#,UA8w|k}sΔәr9' #5h}2 q"ʒߧJIzKߟMb=a<q8y[iBiKm}IiU9woDݞ Ҷ)wzOl4Ca1bvVGO9݉P} -mQ#Aa(`\ wC~G#obgm|BW>Vn+CG}1ξrw3d ?fߞ$"=Ⱦ7碑o*WG.ډlEdwzZq0}] 0}ӎ0- ӔpFj ` j L\`ajnk*F֏zY#d]+iȺlDxd]쉬u!N{"\dh&&WBְ GV_od}d ]j92y s]#dNL.d!> 67¸1K^X2Fb͘hQF0 ckgMAdܺ#.ӯ!c d@F2ЬDFhE폌ra7`x4MQ+R v6 lݘk`xr00üO030'@^ݗ?rJE* ;?ȯb P ^0إ<34`!r5 1\Cp_!{)K!|Z9i ݈:Vu0C _Пȁl߁~S藋/#QΙס_voΩП mXik Лw Ї z2ۛ'VA6t7Cwzt:Cw 3ctG@wtz@w.C,>O $Aw& "g@w't@2g>5˯6KdFBߔ2} 2.Cp C_?29'&A}MQ{rnGڢR;kϡoI[.3اtυ'R)yn]x_dٸU)y}ɔ=&j܅&M[6mhnw5ٴ9y#@?:.#m/At/#>x]#/|gn'~OG?`h1#FY61WnCbTښXteS8X0AL?JŘ鹋|W eOٟ5/GZ3~e +h+g/ }n]s #]$1>% 71; i%@?1I;[ З⾞<8CXqG %6gɅ} s<MdBAd5G$R.E] 7Elors;Co{x>zmc.Ч>>iq:lǕ}_}r!􉷡G1}({m'D1I;k N}])GoUF=(O'H'BbuL|v-[wr}(#qл7$QNO@Xi8F2~8N~۟va2$#/@"# ZẒ-h!Qofr> )HOh2 }<)c-uG7m]3U~M9 _ӎ;Eb4wn\\KϢKΔbo푳r|ڵF (9GQGr2Pa\U93ً 8c-ǐ"vt{̠rȌLdN|ggD\od "2wuF"d>̏s *oBVjYld YeUr=TA֡o=Mo0: |LÔ g0 (PY`ZȞs2R7d1Lwt'ٿV >_[]|Cp>*Y8>!!^nJL;M`}A^0IaE'_e(Y#e52OLgꝄ"mƍ)ǭ M+ dD, c d@4 ?`8q)Y^ 3XK1l g'b η2t7"Eҷ#}Bҍ=#ioҐvrFZQ=%BZA9%!~;zDːZºHڏ@:WBjfH e"m>RG kfʆ'HY鋔R)H)؋=H )o".HWc/!Y:HvH.@.迪OFGלDY_?.C*H*jH 5I"^w"q-$#1`TCb~+Я/K/-~5ޠG}E)'7MA-}R$Hp?$ HhT7"'onًo)[wG|gyw"q[F#n^ĥA\ĵ߄ľۅ;bBlZ#;y}v@9m'τ>-4Jk,1Y81c!FGLlKĸ-GL=yg"zUG8!:Ɉnu%Q_"jSDe!*pt*#fD^ڈ=9߄HCDEd"+C8ۦ"b"CDD#":DDV(Sg~]='$"`&c#{@xoa/'"ts  aQvam#uc?6Jj#4/B ԭB@huo|r`BV"dr DHh#wcs@8 x|ހSdCPA;igWi}ڳ]y_@u, ͕(h6f_hLӠ vMP9P_u 11P;@]P> բP UTI珁S3ug|"%K9P/',[.: Dx[:B{ӓ@Z¬mFj!d}Nh=5xך;3^C^1%Wlx5 Cv8C_ WBB1gAd5yP=7A·hE+PATPnkS(/CBʵP׃"v)ϡLœ P b\n@1%w,(Vb'Pl.bk.gPőP `(@>OA.Ba_eP2Y1wsq&W-n=mF3/QF /Jxz2߄U(Ḟcu-v\?ʽxU3yOMQJYe1eC8)\=_~3@(;wr!<ϤpóxJ=|nH{S xjg7e %FWA3NP,SB16D܁h(B@C!hF<&*Cmoewo,_ϔ}VO8݃ko WyȯU }@!ܞ<2!?uc wݝ Ӓ!e|+m Zʱ2A>!`rq39?<[yBNAWm!B! )r$ȕ6C@!O{C M&!r긝:ɔ q /!g令 (ZюuǠ22J( i(R!L|fv(,d!+~0EAՙk1 Pms.-pB2NkY(¡(+w纑O'P$Yh<:ש 1Py|6hH!~ \cGw[?_ȟ-rb5^m _wtη {N<> DH~C VB^6<^Ԁǵ.81 cAyx9|x\[x4gkB%5}oݷZ *f5p˜h>níZ8 uiJ#lkrkpS.7e̕2.}Z#\/Ϟp ߁~ gWpn?ε8| Ct|*vTӪpNVNpJ^'>Np*}&MꍁSp*7?I8>y;x]Njxb8nɃp\8{ Lcw81q{8,8 y)1mc  GpY±q8֝:p)#kc`vp+h8|px O8\8 )pK0m>FD!.RLpZppr84i3gi "VV~ 1#nlag>y ;}q F}繰 K;`wb$ݮC[v|[-LݼvjnlYر~vE`g{;s%-]fe-$ #E.l!8̈́^L(0)qnN]m 6=v9W]~hd?s{?di>΀O*-W>W m{.ï`uNw%"oy< ۷ w-JXMz '-/Q??P+ZL@@5 3?Ħ!@=FLCXZ{ dy\Z{gAY9꿡l wlwNiRJuPՆ2 ӡ}P.h&~V zCUTzAS|T^PTJW¡P P-yڋPCuTwC<~3ބZ j#;BTi6ԣPO PoX_senshnh_MNд MUBe hb^AcM?4#A3W ʮY4[A 4@[5mA+ы56?ځq h'|v=hC;mx h}|]m uܦg@sЬ3Ќ tʷ^` 4Bi7@]P7|ڶ/TnP̀Q(?%By5Ӡ< ʵGP2?J}0{ e1( !}P& 2ӳswDlqr(g"~"LrG(Wm(o\A?(_7cdNP~PU񁪖O4-ZG Us_PH&ZlI T WS7P58N>#toߠx][bd(_v#(%>u~`!9h$Es++O$ԍ1r߯,O:w3־(/m!Tepn?(څʽQd3N ʏz߁TPjmy#TGv@u)G&>eA]4]t> _cQ[.Pod:P? $hjgC 4hTII\zA:+jh^?YZJ+= h#A#G2F~A;b 4ΊvErYjh Z` 砽k޼ OR ;7fA{{.ᾗО}Ž]yО{N:hOYKV,FrGzvU #v5.# Ly E'?<YCXkft_d4ꆌ_ȘVz.}c`J[ 5 skܚ"˼Y;kT2L!`Ȯ١]=$ً%~9 '9r&Dȭ~z#y] Owm/#?."A, tP0} ηDa,QXD(<27+0Y,+̻.|#bJKQ7 A|ZI o@|?jTaiqBX:,,eR5ﮰ if@|o-xċ&,2o݁~,^ KA d;R|܂ewXd`qJ `qsŴ\2|/,єJglwQcK 1R W!.Yʵq,\5Ӽ!NAiԱMs)# >; @]&y|1c3[ؗcYt'͖X]~ M[!ъ=)ڎhӼBWbbbS1U :i;kB;X枃ydϽxnDʫ%^uj9W d#I^{.|WgѫO+mFxM\5m yy-k^[1k8C[=ulOU^fS e^9gv^~/*~u i`/5](Pkf;P!YPV_tSCP^%xljo!z&iBsD{_.@~P?` pe_Q:~xPiYBBMBC?_ ̈́JB BB{Z:alzdA sA9$![nfmB !z!p!!&Y"VG}1ZHHQ}7Un!uGHr#$ߪ(+W%o?.!.2[Q]0!gadP)K'ul[-A{BQ2Bыo !j CL4F%QS0w0taYƏJz Rn&eYbޑdoIhJb]zl L<[[!ƽa>| B*:?B6yM_wO,UU x;cgP\Ϛ#W)ILMJ^R٥^B~%kl7)W_)+M >EƔ@n4eA1([H(rj3%E?( Eq>䷷07E.S IȃxD<&!!N`ro |Ncᅫ\1y1&݁5䇒QDq@te}?ߏFoo@m3QF.h E?/V]/}LE9yAʗȻ!EQfkdb>#old]߈9%Eˏ"kbl=wYD6H̵S}Pf4EiI픆LtBJn~@Ho6|,_Il{9(`TsQAxIG*TԌ$UhzSu UN5稶S^E F^ЩTH uW3PNR\)8q(կPuV7P3G&͹Q>61 Ўr4Lw&5mJPo@FIȡjmcPIՏR>TEpŻTRl! Per?eեe,{ʋ>RGpc*8Q{ʽ⇪TzmPMv<խ "j&RBjqkA#j{MvcjkG1yk&bYjj@ݜft0nJƬHOn_fuz̸T;uv>uucݘ&3_Y1isƞcۥ9w3{f=k¬[']t[J,x-ۄ(oERkSFR$_O0#r 'ȿϤp{Bi+s(5dL)QGQ֍n'/P<ȇ*ra %(~TB O5MQ4?iMW7D^|EOwCȯ@xÑOE|Gxf_> P;b6 G(V8/ 7%yD-Ł)h021+(6x.Ő#*0`3%mP˂>7&߯|ϑ~>F̖$7*yE"r? ΊM{Oᇥ+!{M8% sӐ>dlEV#=2 ]+{Jo4 !u7=ېI%W&=b6'pHxN$3[>^YI_N G:GrI:WJQdUu#Мq)~|whe_B#HC‡$fO.Eg#v7.!ێ=JJnDTW&=J# F$TZAIg2''a^Z,[$`? wE (CQgG^*'/H_N[zNGž5IׇD/#bڑlyk$ܛ5m+-#?dI~(z f#/_B’NL ŝߖDoGVHdAi z@jȌDfdؑ5Qgd=-#jI9݉4f'K35 H7Dz>ImOTwHF Ih=cHύ%2ikIɛGzӯ4%yg qp'`"v$g/ĝ$|C[=6>;KI{aN_i$B>M\ADqE]~Kt+G"' 濈4L䘟DvJD: "ےp6!,י%d?aa AP@  ~=.&uAE5~(A} v:D5_¼IHXݑ[Y8=`t/"^&Q1OMHv%vBwF<܉ Gфp"WA+#Cm#hEbۿ 1 8sF60Pە5@XSOo[Q(-mߞ7~? ex N1md>q7bxTkasz o\tk:Gh ͞.^+Z)ų˷ul >q<~ wF2%hZpew$̤;p2S+qbK87Ӧa8up:8>p& z{q}Gq$wsn1'5] rBgTaN`a{۪6f؆-hl zlF?fcSW`x/6X=6j.GTbo0V{S7+`lկXbݺ5V ]5u,ci8 nmu߉ؚM%CD"%JDID oE鄯#ovV.5 l+]Va~mCؿo?H$jmaKDXf!5Uol #h8b 8ֆcnG'{eND_G ώLsHדľ$!Yk7)D Mӝlj/!jvnA*?"$r0"~%rDO1֛݉0&˭O%\h˰3fm!|Xb]"z#1K:q#$|7IZqdΤn!fkI mxLHϜJdIVHC;cr$+4qnG[rF{J"gSi&98@$ǒ/9LI[ –R#kNzodiL_0 leO$%OQگ+g)T֬e?eT4ʣB~&aT L<%ORAnZkտ Pǧޙ:5]q?L0j jQ13Df;fI͆^f!%hA+åhƎE<}4z⛗NEMEFD̷hZ+NB34asQ/@cG4;WSԿh~rͼ@s>}1οe~_ {2иDJv5s7OiJM  -MԎ"&cBg}%x_" ~IYLW/x%Ͽ1 &y}ĥ:⼢ q\x [pؐ\pv8D`,=}]%c[Fpvl=a;h-X'2;fb9 îaga9K_a[b\صݾ={ݗط؀u:73lG`1 8le?>#DrSa+v>a{>pu /qYcdgs۟8ġO8do*Ω'pn68 qq 8 KǾ/¶ilbKՅX^,s` RIaU#16kaamfb6z`:&b2, W2$Leq.eܺg1μ1c]fl4qe)oflcݦ3vC0NfZ1?u;qca\ƭ^-4f#&\|# M%*Cc>q2);1H'PƘca>1"0>ٛJ>-g1ffi^!}")Y`6vݜ}wKqgW&Ne'r-ƭ&x|Wx}g|'|?G Ah3BgtE.t ´;pЙ[1'$avH' pyFn&v߼;- L@CMCи5NH` (ɜ0%B/׊DITCɉyn8dN\񺫉xF|\#W 4!n([&D^߇;3M칋ND虫J#5;K+ 61wS$4%bܒxˇOؙH\n:X\"n]x/kSH@L j[R:]%9 I>$ 0eGHGa'u%H令 =hWl2ѳdD6y!ȗp[EmJRDhKϔt]ec)aN٦;PLe;/}wST8 BBcjR6T>4'U= 4*VMվ7Zޏ:#U~G\@.4yw PFP}0GTNI~%T<To[4$|zUgT۟Pm)[еQA]kiԯ Q}E}~,]Qv'Dr[Q{JjTB3W;[JE&^ŠZU.x*w YVk7&TF Yj O*Tjx~?E,* QiӋBBЛT&]j5:T̠[}G81 T|Kc*u/Rj ||ƯO00< p{WeЩY`|᫟oáQu*~g_1g F9'߿G܁J72rb!L> ۨ s{"'b" DtS~5>vzs -rTzߞY:Fs|>VxwopmS]qsy/P:񍱼cb&ؼd's=)d':Ou,=i]<-`M=@&sxzs_9q9vl:Ш aѰ _iN3:[)k@wtKz>z6Ы.FA2mog/]]ߠm?IE17`f4lOiz8&Zbx #hd!uu2 7Ĩ$hdF54NbtrFfElbk`<_`X} a8;M?0c77gGi2MW&Mt.AM0t\:`31 mg b4ZM\1zہfշhv*͢lN%ͺYZ4v qu;$hвjZ5U3C8` 8Z V6cȑ ; {ݙ'w0Y&#W1Z'FhȌ3z1zt .D/+0<!v:X~r>co:ؖ q V?X7qO\}.m{m6pW߬(|G%1 dL:qAx 7G38Nx[G]&ePM8,v`#9bEd=Ӽ06~ 0[04!}O1EO~|ZkszN*)} ^Gov;szf2] ֛N5t\~.:tZ2.5vtI}v%n@tcؑ.߯mH#9:y";CGf:̫OtBt^BǓthOǁi:JeA[KiyͿG-E0x ] ix.;4BAd5+~ةHN Q0_DGj hD_~|-_;McN~jMHS׀O4v@Z3tdoShZѠkoꯘ@q۰WQe%hEÙ4QGL2mtLy%b|K9vg Оm᭴P{t@^4]H&Oo!Tݐ|(} ~f=h[5Ho -$3-sV4Ezt)IP^t HiϞҖI:_OiCif_{ize4NT}T([/HEHvH=H 'H~WTicX44'_R#߼_.4?g`,sƝ惶48biTMXw0 7[ 4:q㜮f_*6llv",^ϑf {uisŬqY̺Tl|y3=j&ۙ^ƬŖf9 12k8c`ӦE.2=6)fA_MLym骴ۦ^tѢOeۙ7e|eJVZimͻ:olꎉf[B]n$J7~rKU|6_bIÁwB.Nw! I(`/Y!|(KKR>%g%%RFۖOT?im3iE6zmv8DH{J=zHg,IΒnU~4'=˕=&m$?IT;V:x}n;ǵ@שRү I~?C+%ԯEcNL8;tThޗ"=.r8&=1&+2-U0܀a irh@14-"яV~66ћO^n`[[o_hc&b} qK#\}q+I߷~B7i$3Be=aO!|N b;{f$q]H0NbRd$#uқVQDdKܐ؎^^k,V(ֽgPf7%B ,{TFaT]*v}2'GzꍭP?7꛽9ua1lP3A5nL\PԊiT?:>*TIH *:lisǣle3?Sɏ(.)[zX7+ttΓwcyG;3 ܝB-'r֍%5y/oԈݑ~|y_ 7l&%'RZUBiՔ7BYZ%6S|>k9(Q^)>Ţ@JgyPeC(1+%}&R%(6+iDIJ)="|C*Frj*g *m*!ʾT6 2՞3^y~~TF^|:3S-jAAbf^Oݮyrn)t6 3hfD3c5˻1N?45H84VylOdAR1ugwT-7P)sx%P:Abn5\he5bg].PZKB/b~Ț>`_6y+7y+&C׋]M'?'3 'u}2]$sR$֚l2&z%IS"6 [}IhH[dIV>r"g 2Jȭf[Nrd}"q(5"89@\-81Py@,GɛȢLJ@Ycd2~FI J@&_Ja*?Q:;2{/JM9xП{)mY9țY#w{y#dϑ;O. תE6=Ļ.G+._d͑ N,}mlI %ȚUR4E#yOQ'3O?t+SPш\L^搿)7`ȭe{&S8d*vӑٔ ~Y4 e:pM6wSTP*'~E(wAEjSؐbG%W)ER?RVQ\,S(Cy'o_(=P.r[SyJsPهٽ2J+V*XHU_Te ^Cw럡: SQ}կcP[ #^:0 X?04=|hzo5?\` eP5Ψ@6+gMU*ޤrfߨXE5lUs(ۓ.)2rw-2&X؃u x%|$UQ%ηnJ jDx'U3f30#>gcZ5S!Pgzh†֖__䆡`fƱagl@e4J#SP|R-(3\IlK/ۡLZORJP<5b- 2 =!5Df ǭhdۍXRJqqѾk-4C1D(6{ ;N$qݔbm]{(j_P$%}g:!Oy y1g ܑ?Սn: |9 _|1rEMC#6*zPh \\\)pio XfIqA0ŻP]E(6 L=Fd>Z: v[ܯD66(]$/y[Gr[琫%gz yqϨ'4r$wo3)Ba| 8,6ϛYO2 =Hz@#:H_F.'}=]Hu7t>G^2ź."P$zHCқ$!v@"qHlMDDlEGrjS4a 9Yޑ3{9_Or R78Y%[&=kyĶMlDl*q/ s4n4 HT>!!.HqmwRwB2^!E'hGqwk(pEq PKhPx n1:"uNNB!2ѧR-gI3$$t%6$O wI[?%>)e$'ѵIkNҲ$wBX3[Jzb]m)&`בv)Ad5Amr<܈mfPh*Row6l?}L2##HADLR'R]Hr#]2=z,3I[9AHC^͏t?#p?=oN.cHLXNbFCLL$ %f6W}ҕhheDFdl"猸IPK" vy  ى~ )EHYBC)j,ޯDXD%n"$\aaσ) m3$*~1;Q, J.V$sh5vGD"e a7f] au-N2}+BNDX'Bgg" KO","}zzҺ5>n9i= k£E<%Q._2|૫w+>[cT :my/[xa<1.[Bk<8zTv7q]ڄI+p=U(g'?\åx&E"E8ڇht gLl~$.yLg۽8M~o pcl*NXPu% Ob}ZIئE9vvSkf,96'a卍)K~ WImsqlFbVazUic5^ }v;bwr`1+b4۶ ۫g]f(v {IػaW8s-7am9cط'暃8lcZ-qI'Cp ;񸟉Wq4V2  G!e.% 0Ė#|ړx$}I&SR-"6RԑՌ4϶=U)G?9*+!i6lt>I5p֑0p ?ߟ^LĻ;8% c?_9k=~uK^"q|,MF_@ᵭN~ц_mK^NalC{"?MZs&)]L,3hJFwtei'(څ9y[P~/g HUͿQ5 T7iHu0PMGq 56P &O|@}Mcf=Md4ofa8i{@c`4~y͞%+݁>|ѨX۠C%M4"hƣY <hD1ckDڔ v(jRk@mߍԎc>Eϩմ6-}4'Tf˨9F͂fԬOY5;10 mQG S[)j/Sĵ =P8Qu1UROiQϢ\ ) #Ju)Gk(R!yf5[(3|kEGBƑJ)]#Gׯ\TI㗐8$P~ 8JD&1FhB'7o4mcV t/n_q[09MqsW8)NprnSo͕8Vj8di!8>#cS] 6c߳ +?8 ^r{[žo{;f&FC pܳ8N8>S8 ^S_qp[pu q蘀Sq dzpӋ8s@Gw=N&3weE(.nLh*C!8՟ýد!+\fkGcU8YO8 {eX_7#y}DGw}̬b?S͘1aY gqϷ0NƵa"Ɲø͢I6ŵ3`mw)wmو1S&̪DŽ<{L̞¼I0^ 30ND1iU 3,b|1X>?U|:~Ib;3v9٭n}vυNػau&[.- n r hl.cUyXO~ kX8cuؓiXcS뫱 ۬ml cg;tWb7;.Yؼ7f]l̎af6֦OzgUPvae +'Xr,Ƣf_A`3 @\[/~*%H.HSl@Tt)R4qs ZE $;ܑ`FKo,3쵅[Op>$>IeqQkx,P7ރ~y_U%~҇[?"!i> I&mB !yv SFx1"B܍?&"/ e$ Mbu GjHĵ?HL3o8Y}r"Sc@nb.ys[U[E~;۴'k}[SOEt0]'RZ ȿ@Q$Q9C(وv=Ϻ#bF _|{XEOf sC>eSP4bkSgƢOĜ7Ek?E(n(5Ga o]"߸ĸ Z'k|G듑s~2ۑ7oB_)dDJ}gPҽ(Me}~EydžFi eD}Ppv˷SBo:QYڗʗ}%TUPu~U"GUV/PUGuUT\Tނ:u6%ƣ~YBMq_A$.wQ7ۃ#@=pY&vnPmꭅD}?ԛ>t /DM̤Fk(5 {~C WP7Au4[cT&scN1:K;TW:U^gTIv|BUq*geT}>F-xSg3Q?E@}*#8_zПӨ nO5R֌J_T r_*-3}B倃TvPqؘ'hET6l)R۟j*\b?*e#?L({I(AJc (ME\o;EN ^geF)_@Ổ~$R~~/J]W=QFpGmr3*:|EfPJ UQT)'QB"Uo6-rh*=R>Ug)k&9R2oxg.Q~nGbg|Ludͥ~:N g$0%6Z=R8gwkF\uփZMӑI9${L"j'z1!=b -YHpoCۃp='4c xXI`/Kb3 1Uh<y~As]t߃5ˉ" b=o]MPm,!z_[,<H:B^m&a:x DunC"%KFdv"&"~-VBS,%l|*m&~/c-/x-p7G=Z^gҡLIb5fn}ԇ f^fA0z Rs/'Q4zAniP z-i[I;Hm_J?үg#?3̤sѺ։hz1sN,hUhGX"ڋiBh8n#Fg8tĠ v;u%W8eK@3tVzE墷3}轨FH=S<#ܓ/HVsAo_z[WѽݭQuENC':u#t >;x)Sн syuѵZՠ;1zG7]z4=M:4xYhd}9]rb&zE0y{`V60TNQ#Ӣ ZMvvhwq[Gw;iӊ6 i{Lut{Mu4BNݏ.ke`Fw{H2>d'00+O3xC?G24xC1s`uF2k3"#MվO x9F`T3#nvdÒ1tzgИ 5?S3t-wbDFSNѧ#}Q@}Ma`cP_]f NЬ mɈF7øpc&23b7f;Gab҇:$vXI&[G4E.ਛc.ũF+&}kV6]]/W;LJ6%jn3.&V0e&%z).LI- pnejO6x5) ;Evaa 0a a מZA=vދnVu|N]?Qt[KP:ދl">2m7_6~_hxvE[i~qE*Ҿ 폭Cݴ/(WGڼݴReZ%:q"BZmJ)w4ۣW42̦AUW/F#yMyz~nS`[ykkYҗUå'K_Rρݳ҇+c|b<&ls/ktg B)ݯ/*tB5tXt[vtsIҫ åm>ӭ7ҥks7HOߖ()wJHK[JHOR׊ggWH ow IJ/Kå'+CWHOHI>픞fʓm ]ܖ_&X =nO*?#['1L^_#=M,*|"%Oz~Cxrҳͤ{-;vn|l!]n)l&푻H;J$Jkΐ_*Ϳ#͜Wj@^wCDސdIYJ1-II%ˑcKfQYqn ⳷:)S)l~ǩPz+mUj<1R6k~tsM0ss.fG-72Oc6F?tie\bV%7lf~ϬiŦ5LN7-ԥjEieN |j:lWSiNwۍ1mS:0f8I7&L;aApNsSo[ng"l=\nrDd*զ&k5Y]d&eL:0d+liaɎgLo`rn cL>7 2 yFf'7- 6wf;Ѵ YMt7k2LoYv]Z]ndf٤f-6S7l[b ӗ;^nмg;s.JجeySͧwb_w$ɇ/ow{ٻKҿXj-e4X4ᕾd.ܾJRƂRTw4yti {iAҊgvNפ#NJ'm..#]3$݋'=Pz~sv#ҧ+Ǥ/WB!yE[WZ~_ CE7hԦ^t_4|IL i @ δ01 -9lZOkhg>miފig(uоJ5;t\Ջ.]c-z?@ :aw2Jͦbs]ycƞ3IGqo@5z_g "m ?O{BO_%bo,Q}91ą'Cx;k.ڲ3Mf#{ۛMQC&rxS[JOdhJWEHETHvOMYS՝ jF:'J_j@}4GԌLM5{FW0 >ռ"Gx}T®1J;{iMP^4M6u\?"!9()q y]0/uxd7&F#r7zvV}F> E>@=bź$MtoSC%e)V#]ؙ(S&;N.7KӿӈHʎZS@tgJQbߊӋ( (]Arp*6Pҝ%TRXEUKT|UU2tC= Ց=nA"l Q=Q G'TQ}[MP;:~:$ٍP[E>O*\\Fj[=%NԴ/Fcfy'j1?SؓsP:{iKTTͨU f۩zG?Z|m),MU)+8aš!^~Y7 R4ɫ%o;~C^U p&'6ܑf#ϡ+ydJ$9smA9ӳɚKOlK)#j5;!?e\lE/Fv*PC8gz(L_ ,][ t EȓQBM繎 5  1.C1A~V| 'A^9y7#d>RTY+ȍ![YkdNuhe6#{s6deE6tx7/Hd wPD(7(JY;Odb-ؙZJ>PdDO:6eiCH ,ƍ'ґMe7c*eTK 1)(F:ԥ\[eb /Cx!c코WTCQ%E_DmgHMaFRv$ֳ6$ڠer\ Tu8nTg?ceu7P:X*7b5f<Ό/3B]efS`uEbƵ"fm9Im>90cfml-5/3;%R'gi 1әL}]Jmhe]ќKmX*_~Q;ن#:f@.5-_pFu*/T˩@BF)p2*)IYU)ߡ+t3J .$Ql!\2OA)thY=d>Y# %eFn"rW8B;\ŖC(٘L_GB/88 %D.QҽWSEw +C^L"P/hP{wE#0rGGPbgQDJ(tf}GQ%!b|SQxi!(VS!-'Sgm Hr"e/%Wq+K'YrۗL\'?#_nCŽ$T%M&؁uQuYԬ'ZSLzFf[S7#c{<v8i{I"4RkIs =w{6diH|O$Nr $#%]1H-΍Gl<Z9YO %>IWوأ}H NBHkҙed ER}8?"- sND.#2Q-QfߋMTHrUI/D8$|&;a~~ | 8=MPU- lNXRc!gMo ~Ae 5ѾKE5 <\ bz5v$o=!vo$ B֧BJ"8`&hʧ t,p 'd BK5OG( ʶ[);=ކOB];xLnWXIap3 W p> p-#l^}W>/x<_Gxz+n^# tr( nw pdx ܋wp{7 \3?_&yq1ZʤqqrŸ&r%2p4Ʃ+nhS=8Sώ8 Ǚ8ó%_~1iq> 8$Qv mOc,uXџevWblr ۥZNl a1XYuh^X)LN'b",e?TVc]e[eOX,$`A}N^F>p1¬GX'aaXoXUi ,-rX)3= 3lovmlClw[c96aSX_[@l&/vPԋ0.8}? Ù9mU])_s-]MN&y2&9u9ўm\Ld9 H!i74JʵNCJ$# /$-+r OqeKܘĚ1{^3p1D_h@LmBuD߱%fDL17юgK1^N / %яg6Q鏈LzDDj;᳼@D/'"9 "<Qʈ>uO9Hŭ${4 :}H!Q$ ŧ/ u%ZxhD!MG"?"J`KKQI͉VNDa$Kf+4Q/}N1S·$aMa [%C;1/QUGD/#&gsl .$HjגI~,;RjH!˶kxGzA{2F;>L&ۖAȱGκՑ;2{ׇ{H~ z~{ytF[䯗2̦%s' Rq#snl-d{ ūp%Qj5)}KYKʍZQlRT8RNcʷWDOBΠUKߨ;DNu[}Pg#jRO5_4M7j6^hҏqD[25'SŠ L|& O[4A%,BMYKf?jҾQ M4}Fy*47C3? M/M4Y\G_9̢I}ډx4P!.S+<Ѓ&h(N:@L1QG~f*jlP ݎט.ꄺe/ԾCP[uDmԅGmjBP5;%TlOv'*du(}R>eYc)3H3T+)o(ǐw!{ Y^E䟟"4n&9nkB൤]+Bh$sÚI.j-;QشSzY+ g5 495dRe\nnd8sR8 V/ߋ# c_fymx]9؞vh6gaAd&f;6 7`mul+a[kߍ<5ͱhla۟kiv& ;/Ǿi>/ñӱ?D?[a \}do\kuChd'Sq(8sS#"m_tn1Ne&8 NRpà؛G0>pŸ2ƚ{Vax!0vk:+X5`Hcϸx>L0ʄ{L`ɹRcꕍF9H̭eEj)P9`QbieXy ῄه?WllW3"vV+Xl؆wOc BW =5Vwb57x>{a,h ,NeQXvc0ރ8C+b'TXm(=̱r:SBGzT{zkG+X<9`* 5XX;bQ#a3 pDw09s]:Yf}:vx0ꈙ1?1}ӗD}ӻiju٘Vb9 sO}88eX l=6dP/8m<;4=&pmc[wOQRg]OnϹ|@O} 0! k~%%߆&{W=G?I@c,zG`N>o+A~1 ]I?0 QnKLHb-&as7kBqď/$h;,#I/⎟".{=qzMCo ]@\[mb7&v]bXߔ+1~[~8wȉYёcbxf#qn'>|&q v~%/{y2f>#~h#-{_rǝIZ)-Њ$}Lr$gU>jLyAKŌ%e+C{~IKƈZ26"z'Hr)5@n\2)-L N^m<$o7ғӃz}}A~ NSr)츏˜T!k5"/E{L9U هaȞV 6yGvAޥ9vK>|;rȣ#A'ڤ]G^"獵CzLGPnP]jTjjT{:QQ:j:cPC*?QbQPuUrRZP G5Y&ATPgj,H*U6B26Qz6QiRNe*SYr TEP2BO4hVo\Ie.TI *oS&ޥcnQj$eN.:FJ)jKizJ"ʺlt'Q3唳rp'vPvR4J(5T(AыATGyϟPr7-OQnUI({Ϣ#6"TxPO}Y8i6RU ;/D^cT-!T>}OU8T?Q*۝TݦA%PEnTrc:'ףt[3J à ;) ?"[`Fѱ{t{J%ےH;!Uӗԉ$=J&$ %1`# nׄ%?ALCD>lG!. %8>: %Gp*līM6.x £=3}c<zk<֋6K?/p= Cp|3܍v/rY+6튇&<7 qݑ7O| ko6ſE# y)FLol{oo897>czK j خ"Z4 'g%hAG NKHn B* bL̟0#b[?W ;OxA aB-R_"1|v>xJk<+\;]aR\5`bᑿGv~ '= O'kv,ZgL;$h7 ރ9h 4TGô#4,/aKݡ@NHhtfў4QO]i Zpz#fԡ}~~cDG7Bc4Y!D hZn}0t9cso c"jcFbWQ3 OmhcMhFsax~=?B uhzk;#0#4}4mN4̈́iކ >4o1viZu:ah-b\ L31.mMFÃhDE&4sY\ʖad4}f>1<=#34.aF'iپ;ѪZZZקM}hm Юd5 tͣKh \:I tmw+],x+z|E陰^GҫNo3w} ϠAt.C v3$$!0̠׽fķPFx27x%b|;1_0n.1nsE />?o`֘ ´#Lɍq3n5㒽gv3?10ν'׵[ƨkĈ=] G3{R3Tw1C2|9A^ ԛ73eCZ1tUw^ƈ+پϒ;#v`ԟ+X>;qm0¬bὶA_n<:oXwĺ ۰؎8eéc"-nrqαŵQCk6^vuU [>_UZ2o*-k+<~> 49l5]%RA׻nu'>|wk7t[Fp:^NC5Nt8Et:э;:E}Itv[h+-م}K gcAC4.ݏ z5*t2@Qc9tAOz ={h}, []FٟZZI}FkgZP㤛B{ˆwT@PW3 ~]j@bYw$_o/8^h-.M=Qǻ74љw5R o$Z3oO/޶=SV_*ڴxxx ViRLyIx{`zΛ[go8O=yoX?>@uq}nz) ﶻw]Z'\E&f 'v}a{>v\UHjnc7]nf;"cYRvfk7m3413;- ;&iS+a',Ȏוּ훌svBAWD,D^i;YU1;+m~ȷ!5)Ue/Ug5ӯsMKa4aϯU}eAڎXTLa쁙K'bΤ~,p{9Ն ;CG?TF`wx uG㒌8`^HzL);&%HoL.d bs6{'M= ރQ=E k9P~Jێڂ2ߜzU娮@M_&Kuӗ~v8?A2%Ay1ՆQ/z.A4*~{R89Ԛ&Bע6 PIEůNT?F(@e')("t5LCQ?P\3q/(w$f_@CE~;=:"Cr _r@ރ* UmB# ݁(ިOE( ?2[Zj: _8%W9+\ C-ʏE PeiE(iGX2JOd-%PjΜ˨C\ՆkT章jwu~}BTmڑp~@0FnEPڤ6 NS:3 Cm;nԻqg, P[Q j@]i *O~C4<[Fih]AhdMߠ4Ԣ40Ϯ72gԯF]j5QZT١*, *-BAnmoQwbB95Cv)7p[ 9c=ȭE7!hW`<3՜/,&dlGB}{\g) Eh쿢_\](k@a1ypq +QtOſ9ZU(si(Η(}ʽBSYg…sQ"vFiJJ^9P12( lFٵ|wڢ,{+*5P! ?g)(o@FDH[TR(A4SXE (t栨pJ :P-E=%r=oAaWnCQQڋb' pc=^A](>P9(vDѵ(h EOP`bMnndPD-8}B̓Pm!lB~(DQ8ol ~Ȣp p1Lo\vJjp_kD c PxE SPز E|Pq(an4ՠ* E$P(ӁQptP;uQ$ G]G~YnP(s-y烐\QGQiF^K$ [5U.wrό$prk]>98|u$sV(z{ǡ(;(ʾJ nGɤ{k(){}a:ۧD([T`<5è0{w7P1ҨcLDejTAKTp%ƨ5GսTpm5TyC5ӋP71>g4jQI+Q%LB]=?k^"mF]2=*d;Eq~6xg { dݪhc}U\\*&'sJ:j|@ jBɨ E5Zkճxz|PU_kQ퉊3Qq?2to \^ U+"Q5mB\>]^"n{P{s|Q Px𣑋Í-(ƅQhrBCW4Ek!d|іkdfmjzȵu`M6$Gh};<9-ց^šuhuv:&cL(y,OX;3,&CD"fտ`hڤ& 4ꅡI ^M~d^_4w:eBuSTUq9緣%lN f Q%<(ဋ(~(A'GQIJPX7 ٵ(X揂 (\Xts!%GX[‘VN1@6JAIE;FBJ7D(E|?JK&ss?EiSJ]CCjFn硨c5Ԣx"G(:CO(VSG,ڪ([gQŨ v99_QNv0oj8(n3Bq/6ۡ43%J\r%( _P"X(|X%\srq kZ;\_? _!Oվa#Ot4G佔D+a_ RQP ȟ|?9FzdF79ܓc"ȎUVӐU&L5HsUo $r ??]ǪHCbdYH;ʐ})1> ,"x$pxq42oc@rC82~#- b3҆}1aΈ%慸$}2EH 1E sFZ+dX!)Zg>2ې!7M@Z2ґU'ӑm2?^ªdKd!WO[9m(p.g*ߐ{b<8?;׸{EyBnT;r_sxf 7#;>ZsYHuȜ݄U |RCʳHۊ%wl:iiH{|B[ 2GzG/"9p VpN#pW94pMur4dܙk\ȹYϰj$JQ-:Uӑ]vAnjBvy[i2a*~d-FFi#ӸyMr6V`յȒUS怬Uϑa=RH?T{qgJ}njܴg>aZ!#&HBgk_#~}?8 #/MXcHt@BY$Glğ*E#W7Y kA_@t[4b 6"$Q#HmMDنHNQKU'yq"jcD5obw#p1b#6D=D.G+!E$&") ~ق|D"&z:>"2"Dq .BwU? Eo,NDd[!ݴю=rѭmHH<3.BxI!:r,"%؃( Oao +4a.|Aa)Lz`_oXv>!;,&c%]d(bBl =F~$B"J:/W6Iaa1*AF,3ތeSa%,IZ܆%}X%X O’b,ɼ /U9R{~࿞+W F >G'>S?> sIs xo=GgÔ+q cWύfcL ,x<ljg1O6x(C <·Y/ܒc w}Ix܏=pp{dwΨM\,`W6\3&Xܶs.<gK<7Ǘ(.ܕ;ܚ³1<#hg셷x' xg{k9<=iO1;~a/hnʷϭ {f!bI,tF6IBb VoGxqDZF A8RFbc$\HՌB*?kꀔ{HKH^?Hy1IoN"uHwEJe,LE\jD$".ɓw0|bw=Br^Aw$r16 0u Cr#A[> } P .!n=Es.@RӑRF\.sqLQӛ)s[ J>9 gKIךr֢H/)ACK{d\Z;i8|p)% I[G#t&O )x.e` _`z= vHD?/C+w'QyeM\A< k9 Gr%Rr9e҂#]+#cdf4#LdE"(V>qAbVCw-CnoF?&sRmFD}7yFېo(zӽo1G>NDOY<NC 꾣KZqW k8~|5_PPt[=QZ;Pf3΢Bw-*RnU{Q:VBu4-CQ+f5_}"=>>m3AP >ݨ_:Fhq? }7QkFmGݨg o9u_G8'"PAk wڍq?+ 8! ;^!2 h8a4EÛa4@ 7/n-7Ps nEz99]d.&uQ{YjEA(:[jnGTETȠ/TF>]GY@$_LC7Pnp4+\hK!îyހ^&F2nLEz#)# sF:[a?jA+.KYXF&R#>"dX̓o.o\|vg,g|g^U G1^ k3q?,/6/6 ^;+E^et߼5^kg? aXh'|v6|[_S~U×ӟO|/G*]9o ~x׹ln}޲>]ܸM{d~3 r=-Xv!(?X U[g{xS[lǭP7W>­6n3W%ܴ u/KKx0u=Ea%87*.bxۅon؊UwWQr'm ¼_pSx7>OG x nswܤ0~YצpUfXq5zr.{f%8\L;|2sy&.8*s#7i¹P1 8K .Ƣ/pb,~%$~ W~m/wed_WR?2SƲtI"8~a};bm3#¨s) e>I"qbDFFl=bv=G݈n<*!vb9[]WjY[ Ĝ@ψw5[8[?VAlj&b-:dbMÈ̾DqYSHGODB2lD)7@x·7#~~_߉'w>G1ދ\N"͢r u#kc8L;#! "yz7R R !x415h22!mTRoAj~RS!.׏!H{\CJ,NjkŨHakHͳɧ'#y Gf 'kTfüjiH=ᆔ[!o/Ҭ"}d51Y</T9k 2l%vY#Jê9XUP-VlȮx}}dW {dJEΨș99+ u GIt9 "/1y\A^>p2}yy84ty./҃(FitQx8 gWp Dc(HP$E(_"^&lVw.B"Qf9r(2F{QT9(r9L o* ?Cᓯ("(0wqma^tqE(䇢W(:ba3]+g26hP4"pQ>E (2VB(.G{|:ҹu xnۊœ(8Y=šs(*@q ZPe.U%+ob^* P(*AgT2T-2EՂlT8'z=8Օ~85SK8쩇gmiDm7j_B0,u IUPl/抠vj|CmMΜZ3@%Cm17]cPMPawUDM$Ԫq0 A ]A19)kZwDmQB\[8Q5P߅?Nwu7j-5Wĸ~o>PS{5K^FD ՛ ;V<vNFڟʸ&T0>LBUPkCDT-B2TEpRQS%իF#9LjK8dqg@8=~C18}q|J|:*cQu$*{Paᄲ_([y (t% ("#rx ŇPGG|ߎ G9[l<+?G d!2>G2Ip5:8N݅$<5.rLDD̆)*5Ed#2Bإi?V#O b\m%u!Y9ۆk7DH"DȞSGH;_:"8 t+6clEp5'\DHwDH#h1¾bŗ_}+:sqV\ 0iCx0"DQv1Q #G|3Nbͪ@o,<E'"q "9Qۜ59g #1^ *|G?N"^M2qFaH(;i8E!؈X9~x#'&X~&e} es"hDaYX#VݩOWp0%j@3&nvv{5 pχu?y0Fg#Tv]k]( (~P2WEHtȿ҆pCqC?ŷxOɴTʷgP9]4BUd5T0;Ɣ9aL-$n!u;0 ;Vd@U 5n^K1VJ1r4(h_ Q9P?Rˍ_Wy?)7qB<jƭP kYgeCԳn{j|_1fkAhAv+Bc\3qckal!ՆS1vn ƚ4s4uwP%3MP[a 5XhF 1Z'Vc\",}ny?%0=x9>h8Akt0aQOM0o0?*3aPZ &_@̅ѕ0V kLqRɮU00A-VY`Qk wqߔa\ۖ!n=>N`4`w xhB t)`f܀_f`7fw7]o gs``7Y WSav3a\ [͆X匝3v¢}3sj~%d\u``iV'O/ w[[MmClY1'=Dz0oz8^ Ǧ,Ыv,ltRxR#\uzv"ܮ%cd.{o=z=dqo ~9X5&Ua&`ћ`$#0X7סwj&5n^̄~gAwqES׺湘0㎸@\%(.7:~pl֧B{;!-H) C&dv`Llӆ8>!`F?I 9b#> B3e LeM |: !ZOƨ-!P ?0J[g[  !=3{ g·ȯ!Ohe|!o"h|$Ͼ5XC*S D U !q * ;Q hb]HS3DL <GA9$t!); _C)d!L t!QbK!t V!y"4'jB0k!K l ~~I2xY m> "H\ɡ"H }   uߢ ੐zt M2rF̀h XAzL&)Ƽ_Wx׽x1ޅ8Cީx-vn+uI~kd̫Uū/ū++Z^~y"Y[Xƛ2jOLRh%fm1SQUN:N:N:N:N:N:N:N:N:N:N:N:wOVn7mwAIz|yvb[|g\忾V02f}6!6m65mί)P-YcMuXQc[4Զ=omqC҃_K<-o3/nkc_~vc[۲e 3H,&S3Bۺ)*bm(r'ZQfI+z)ңS:žBB;(jb$ER{q_DDCgRc?b g.KFoF.ik9]fnCz4Swqw v:[{DBǕWMQ%W&a$mFq$bnCJO;l=R&FZ-5d;̖#t`_exU.,/שTѡs;67r6[VM͊jɯvZ+`숁*jɮng+㕗ٽIQ{p}?"Kz2$"qDד;@"wH<($K[H ц᤼x'\$}s!٤KO 2f|'CdrON4 Zao2O?F_y4=*H]R|4iH3V&M,#c2s!d`+j G$|$/j2EyKI.R{4L /gOoH=rl3"Bjb[IU_%ϑ$? AZ_ϒA_ZјU$MIsh$UnO$Yd>J_EJȸƖl'%Ҵ0}=(#dѠF[i(M{aGf+^Q} Au1<#Ud2$x?ZH4-ΊlM[Mao d}6]"޷=dSVfvWd0x^=S&'I-4C4/Ú8^#;^?EZi40L3(dB&bijGR?IZ7'U;:2[@v i -MsߑH*(!SHّ_d4{~DSVne?=eٰbv/ԕHL %'~_6Yξ~Þ>' +:fK%:өS2@NgdIb#iGؗvD]~]dW3-6<+]lN(U ~zgw[ȝźڤb. 39 gíj$7?N}d7泡ɠ5l9E6ve9;|ـ\NfgEٕiѿEm-{mľtB!$PJBײl []ɲk\?1 DkI8 Ϯ[`wth9,Ic{v#wڟّ$1T|2دohB|#U$qTag 8HiyO;6v!hEjWHQ*I1# $ZA:Ҥ}u}"'A$wg)8ᑢh+1ݎ"ԖZ^YdI?ZAJId#7m84~pSXJ[iM$Y4ZNѳ38xܥHJ˅ĜR@RY'In6&$G@ v&cϴ7DT؟8|vz.I?2!lV#$d@o}HhK^8IlS$IFt07#q nL9?P{9mE I^$ d2>$%J"s?#)f?g{oSRCI:Ҋ>MJYH},%TU#z=r&JW9Gc*=i\ɥ#|-RO㧱k_wBjzHwpwH"]14yGPt.Dx.6n?фA.pv"E{hlKIY}B敫h!ҹpfȝ#+^Qǭ!zyG.!E  S{4L.m {E䠛An=NbhvRY)ͣ'(2^EI/&OS>%d>HՊ4y6Lדɏ4)2MHF*d_NS~ NTL_5294&KL'];-|I"FMFqĄl>g i.CwF5YtO-%SdBftϧlVJ3M?Y:Őyv.WмsghA(68c2wVTF~jv6\:ȅ$=䦖En.q4s لgCqr+y4['jߤe[_Q0_-{iOKk 8s4\ "2h/YooJ ҏdqY\%c3w";LoirMnGVfY444vNGhZYm2o aIvR%=ӸBJrٚ@~ä#IcHa-R̖!4f= !HjCPMrh=MsO#ƇDn&M$u/4Gq:I5iœR[S\OmޤVt4=1MHo&p>yLH))e%a4OEZ8)J\eRڦJFHۆE5I6L%ѤpTd7_񑡤8e%IM(|"SHz4)j&ERt%ˤBe[Ә3.E2I$UX~؟<:@2?U'$]N$*/yv:bHط$<$O $ %g[/#$ɟ$ CN)iTu/|:]JRE$Rbq7C H.Mx .wq;^M"uώ ٯ$;}\oa?-~&v]-7g .и3vt&$7dG1Cjg=ȎI'f|ήl.{k4;I І%œқǑP v۽j璬UIݭ$XyKbHVW /u:82kٳ_{Ije#5 > kɶvE4uGRh?EO)q۱dHBep%k=Quĕ7%싱 >8b_ƝF$RSFcer׎lغ 9^vTIHkTcԘ$3NȐ$ēp)cI=}veY&yDohqGz+D}y#$x$sřDmH1R&aG\ފְ/sH9} u6tg="YgO/;_@V Nu$5~!WlHSޱAcħ}d/&[v&=:y7n^Ufo.N>OfJT}P6|8;S_97< vZQc/[esXnkSŹm[;<􄝨rgo%)wؑοZr0;-{g*0ݽ9Ȟaw`3Vgِ vzG);t;'V]Uٯc9,zi [`r{XჹDc2¢|lgSf0o,n [fVe,*Ka~ɝ,HʁMYϦ43y̑ >EI1"Ɯ1t2#[lB6.'c {nsbcljx _*eWle362 籔6!K0c1َLKq8  3S [d4c: .cU__*?iS2c i0-LR4٣lÎ\ f9VdjBefeƽδ3BlL*4^L+61$ce&-+cU%YY~p;5{da?oo/#?}$=g:k}{9~9{gFȑX(=L`d7ϋ_^la:c0 M`W 6mZQ~,nl̆-ѥuv]l0d·Ndg^KG؅;{q=kv6vzBvS<1rÊ]|y].%0:7{UTdvXz |9;ʮ:t;vyRQƺI쯞`ZT٥FAAvK(-~w6v'>/ew6ř즎&p{}ob$pr{5=nc~ ؋5٫WUf_ 362fbnk#{ʓ`#Wd3\I w'$[ǒ"kP}/^nyF&boO;ϙ؟k/o9Lw1qjQ "8^<:>I$$''\!(wMXgKƊy[\I)',!!Y8{?;{xr' HK;̦Ic$:X'=XwwF: W pC2C?lR#Ө|vfX%fJVdn5,L4_~9ڻݭ!G2z`ma ל_򽿦0?iZsd>|>ҦhöR^g9VjUz_:t{wIXWճom5aՃCJVmXWw}iac}/U5/9>^߾-=Sޜ}%le-Ew^6ű@}$4??If -_~W˳>U67s(3%+m&cUĎO3dcw09L03I 1L%̊fKNq&BL }&T8ɭc 㘒#$6C2W.LgS*eLz!?)ogLx#"mv\˞-{\ f5L`j[|z7S>D>s_/_:pA[;1|#G9'{?hU^ 7(9M8۸  /5t~f;7Ǚ#)eHk,* \Ȗ<\"FeI. R֎idk볖Y2$Del7y.1~vfuؑvX]XÎ2V(Wa|XIvn';k4{r=y#k&ى>v:G]rSeWCص7N*dWM8\t]qfE.NdȰRv\ف fǫi씶9;d ;uݗGSw(~vN]9]\\.gg3v>+xt]͝?u?A;F)t(dH$خD"AI\e4%?$UcGq$fAbL2*$@2oCIn\[N7| ɛ I16rRٻIFԔzRNc&Z(53vhY1Rj%Տ滚\ImW;/ " ҅SH}r+!*61떐6UBjH))WNމ$#AjH$RQ%1&4T4tit4xCS&XNtwӸ4iTeg,/r#uY^i꧱ϮfL$GӏJ*0&mw4~0n$&D&,t*4!Q'Gɤ3Vww.ҩ,!]&]A{Rei[~ƒVT57xCsq.r9 ?ɪ֊P Wڤ3 i>Jv7k^N,w ˳z2fizd~! 45˧sۍd=qYԝ#.ΟF3\.EY&|nq;fv!f愑C*5j)9\Msh4_3L-B#4]%+Iܝ4*Ь`3xe@މO>"vrX%YdL!L$?'m44NVߐU-*{J3eY^RI n6:4c2oOm ,Ef|3\ȃM4Jם$7dȢP,d>ʓf ۥ%d'!IV8dO־b}'MۮE#[dxR' Ƞ)MLz>5/7 2 ?hF2Iّ4hkQ Sq4l汝fKYc.>%~2-LFf4/7g(IҤ 4:^GڪmҚGFF[t>4n:I#\׽F ~wq %X='1ɤ*9FF3t2M)HkȤql('{Ȩ L%=`}tvФ.4 z҄2%2ȸ@wL hs^|DfrȸMt~!] 4v L'݃hiM6BzsHm9\F|q#i߹Iٯ۷٧ϿItRy4N'cc$9vHn-vE HT>vp! %$74>.fߎWϰ^|llMF%kg= hVvY ۛ~5u/Ye4Vm~r1uc׏WV krdO_y \Ă#Y,UM%nfyCQ8˴0;6?Ed5bYǀkXr5I[ڃ؆gXo̚TYi>+[f`GY[m{ùlGvpw-Ռm_j9ŁRd(+9V/6ble?F f'_0:mkg7f-WUͧl..eH֧tKd~#lj+[5c7+ \Z_gElZ1Eìkd=#XE*7l9`'hf+qVa ~0QNc:l֮e]1HiNqm9_hI@!Jghor_l 'hQ'e{U,dˑ#dDn-Z2Ncr ضfl/lGq1Wqkwَ9ַmjb;V{]ll!̅Ώa>gg('kkه[دEك6Й !t{7f{FLO ؏[Mwd 'GBrD]h>j29/Q4! {.6}?wdBc&MA\"%r7hI|jx}E<{ !AGm:t.ǾfToH\{t4{b-s<#{I|J$hI$ZBiT47z}\;=w >Y$w"<^wq8eG ,"KyFxQ: H2ž4$}f< %ɟIZ,thґ$E!diLu_#K6]Ie4(?j$s%jEhN/u!go'^M@7y"|=ia ۩N)bR7o_N~;S%VƔ?_(6%ۘQZ3J ,NK+?S|Jr\K4#7_Ч$"(U%FSBr*,A-B])>w;)x?ŋP_5S4"2k(-7~GsPP-l* nԙTⱗ (.&PNx$Vņ9e*? z^@vVmOm48Z3 0 h(j^K:Az/v(sj>uϻEͧԩTw)SK^^2* KƦTѸS*0И.ER-')o\*HٯPJ.xGM)[@2֭oѯIA-I7Ѩyٽ:S-bE8SO~v{(3#qu$dsiʻ\UDMHndد쏑'JMg%tٝiWi)~&aҾTD6)|MH{ U&$ -H@7~\̞o+!٠I\ٺܢ2xeet:(ضtwXBkگԳd4mw.*4RqӦRq}ӭTw(S͂(ʙEմϗRBR ߩJ3nҊ|b*C%O-4Jr3 C:)S=F7SIIg6Qr4$?ʥT_Tq=&pr&ʘTye"*_1")5>e?) iE'NL[TdS*ءEoKЊQL Elǐf@Tx -԰S AJAIk+G:G#$ݵPmf&)`yhe_".~iBQk. { I#XFޓ(mGB"~Do o+#%UWrS(D(G޽GYc@i=Jנ·壝Q>AQ\/P4zV%Qg~B|xGqUjL=r>_D*᧨Y(Gc@U(^24>qdFO74B3Ij]hFl`?֜PAh3k}m.hؐ>:ϷbM6n &ؔ3\4bӣ\t ]C9t%_DW$tyWWe_{t9[Iu^݂_isn@{N]zǍ㹣[,'pWn9uD/ =c}7=JY|k 艶DOz6COS_C,LX\X^zچt=6,ޱdwEONzѣI:X^t:{:eݨU#Cw-dOAϗY]|?= UE/ zCTue譝 {yl-7 Ukޞm+{[|6/l?9cWlgun?(Nɹֳk /uvg#e<5۰Vu6ZNuY,B+C g>֨iXgd3P6XQh؄X=zId3{zubu b]NZf-F)ڡ3s$}}QVI;gaax6[Ķrb"wl]ΛXm 6bCX>8Voثh9,?2k$6!kSQq-+o nF;8e5BG/iu 66@cz=m!QSQ\N6Hq@}uUzҽ*/oDG`ş9DEQ{# cZ+cMh=j؁O_cbt7XG] kb]ԥEcunZ Pw՝k$)\ %Qz- mNnFM\,mGadɣG碡cQ~*|Q'J>+v#$œQ\e/*GՁ /D5 v* <IdFz;TrP">.Jr[ch:_QQվoE(Acl+Gn22E/pr.*PM6GѲgZN @]#*l±I8ku}gkh/jEtg$]Qk;q j20]%X=T& Ll#z`)=vM4KCK#7{*F/h =hB$?Ҁ:~>uwy[v ҅NSBT'kF94/@M1{G^b چ[A<6fI^ޥQXlm,e VLCS4OE3 oP44%P2fu+1Agjtu+~g7< mGjΡ1ޜ>Q*xQ)o"F1w4 \Lz-_ru{P[{ŸCh؇h9 -M&p$*SFHֿ~uߺ^чΟVb|fA܏WhiFST+.hLzXz>ƚ >X+v( ),_a!_4@k+dВ='tm]s􇳝UizfoƮ4l4&ޞz+d vErt9<9+Й*u~e?s:<6 bc8`56)&'tp{/{Xw]\ o&bЩ:ѩ}~R?ulаѧW9,Ye+Ǧ1RBW\8AsX=q)On/gK%Cbz_bSO8~F{z0N)F<W[a6/ {,]ָ,2 *'~<[s*6tQEO,ziw,zĸ=l/8a"7r6*~ Z?X=+p\g#fآesa>a0OމF+ A׼rtMmPaNqŠcǡo<޴]UN<-c.8wbP)8o–Jl[[lOaLJΠ>~j#$PVqX#8Sua]?t=\aR7u*Zt3YX4;\2-9 ˻=&?mmKƻVwjGސm! nދy)@v(,⏧yҶ]Syw$gv.>BțoA?q%!@*?0~Cϭoq>Qx; ޝf+މʼmxHKFV**g2ov2Zx [e%V]/8( bxky&f^ ^+y_xk>wU}JUon6kkױ<)wשUqoB6Wyx[ޖsμu]Ox;y;v|w^:o" Ν U/VxF6ޭnS_xwZ]x7tn>wgFK{u=f;yϖyiཛྷ{G|6HikW Wyoཫq!21zFާZw8;[eޯc߁?T]~/ʂ"k\!8t0*GaԽ^Bs =[>B"GCLp$R i|t N8  g[g~C.rVB^䯟‚=P5曡X4V@f*Ae\,J@T"+zXe#)|Pۡ2=*Ʒb6ʃ=PфQ(-4bs:ƺ@.C^.nZ39W: Gac'cS{ag-qк&-y)h"<2UyW]UЭo} 70QXb` &Iqz> O+a6wax'L 1~'lDL&!i1m=yka0)X,Zr>}7bOak+`7v{ayޡp)ppI obsv.Jzp~$ g?X'gpVxEXt΢(κ[2,*݌EHN}pz4˛t.%-Scq}= ί̴ࢢ ܼpypM{l\ÿSr1<0<=e|ׂ57/^w[K ;c] x+D܆>Ux 3 G3}އ}>o>umo$x_iz`o:xR讂k|Nu);G>wFǥ>u?Uo)7|kȁ+op1ǭ>7٭iӸ _SIσ5z%~_ ÿo" ?a3,G.x][XAs"Hdhү K@0"Ad;K:ƒRXK\ ~Kb3|dVjb |>+s|S}X s|3[u_饙ܾW{|睅o3—;aO[[qw?_?YM0_Lf/.8|΄dp _>'3NxW%xτgYxn̂zxvMOcxs;jxY- OYKx %\xgD6<} u><~߅g5<\^n_ c / =x͒GB޵_UnKZӀ[ ­nBf.p)MKLeg&pob8XJ v_.0'x\,ܾc n~xL_ o9]Xmn@xߚI<|—/k78}.Z m;ovFK}% %"Bp,G8l]hƲ>H/BHZ؋0{ra ?¥r~"&OFi G~9+-G8#l""/#Jd"9ဨme6>+:͇JĎkD,6!Qq u&!D p  (4$V#T#qW׽Gb\,U+(}7F\$VDCH2r$ޏ?XmJHF H~0)V]H :H|T^.{ԐTK )RG~ -; iaHCv[-@L ?⮦H;[z7n21y|,Dּ d2K޼ :H! ¦"e|_H+d8$kDjRRgY EɖFH:9k>rH )Hq !CRq~H4|mBj q{<3 iz/s*YHF(ҦD#5{ kI5=yda3I#7 /r9P$ou"v{#IBH_*HG%.C¢H2IK.y"yw$ۀD$@H^s % "!g;8 gxHBB.g[aHsS y~!3"=)6HAtH]V#k' eM8Ab+g}Dº9IğAet!n*M8=q'79;w ؖ==킸Q\߉3QElfT!fG bJ V b G1k5w+J jݶDZss @LoSC\Q+-u4b!n\E8q׎!Be}(cń=Xެ#ӱAby],YWkG5?Q+ Quurf0bVB3DLGt F2Q=-X~BN B /<( MXe BŊ׋!HFr"m I?x\{Y|U(sR&=D A9N[w"X9O{"R1"m"ͷ"Rnn{!ܻ +:OayJ"-VEm5 $d=kyò/l,+2} ٥X6N@3\A@g1w=o%97>W|p4ʾix& |xȝ67NXWpy΃,Z`(,/ 0L 1?<q*+܊ݘ`7* p|?1+v&.. 8~ޅsc,KBXd[¥c\ ruOMC3%0Ep#CJI]ᾏýౠoAqg~]kc|xg>y+/xNp3nҟ܀ŷı}, px1Ο-pObwinppۢY,b,3 +kH'guؘLCXx`F,,|Nv 7c_WKdcZ̄87r ̸4iY[ _ \#*âcwwww3vw!Ұ.K7tݠRvww_s̹rjn'm_Y}nsɭֳ hneK*:s t[:hsܲtU&Oc+EoM1(N?M[r2}H_K[|*}?>KNz<̣OG}lAj;>DKCJzwzJ׸һNjL..MWkLz"z*w4;ӳeY]z>t)=/Π9 z^EϷo#Pz=AO/S_ zыTң2zPvŞezp~H+҃Zt?._REEуRx(A.et)=8ZJèkhx*=FOn:zѓw/i't~(=Iw u=XK/tKfzџ޾M7?ci}ZgF_?af>}}ϐѷ*\5$y]HҷuN5)})jA_{җ,1?aB_6}9uM_vg賎6>vϦe|RtU>Cg)ii&}\G%~Gzo֊>vG APчك}/?]Ncͨ>fbzӨML7=fX5No/@?zW0毤 6?cwҫGU&^{MաQS7+r~mzu^HojGn7> 7zw>m;6:^'L7'rzvJk#X9m.-. ӫ cw7wл8^mMӛ 鵦>ښ^4W(zf =3޴ȧW?cs"zzGk3A z|=xlssaCtwG'{w^|;@nۅt[[Э nSH׽Oӵkt!]ӗKt,򘮶֥+9tf&]NEh~5kU!5Ӥ-|j(RjPI Ԡé&j{z͡WNT_8R}a|wj~F +PQT҇Pis?+q.yQð@zA歩 ZaDjxiPCUT[FХ}3BE1 9vMG5T;*PlMG<*QŬnT{*w}EePٸTłn=RuCm(k ף(ٕzEHLC}:Qӌҝ>RڗM˥/1*RPJ3%kO)SQ%GuJ]J~(k-%@)-(e!,uɔtvN))eHPeJMIP¹/E5ץ⤺=Q̗{t:?"\l@F_$8.Cgљt=<$RCc)u8ORt&0"4 tb ECqK)amJRmeEݢ)Y#}4|G֏TO#(guRKHeMTk?]>.?<@ Z}ҍo'n%w9sj֏r1<,*O8Sgb쨶%]l%ve .['|n3iᘗ%7#vclC>G\\A.C8!Z=(C}H#v8bW#&pxkقC ,8WoߝCKu9t캜<9wv`.kKr6h6+^jz4KKK٣4<4eJrֻ3ɲQǮm3vo2FpvƎYk;ҳY*;ɎY-IMɎNÅlpM-n{jq?ۼ6XM\ WfLvbl'Vsz K_;Oanil֓}R7[Zwdelw+m$MYKB:6nXmgˁi|i?ƹlJl[ݨe'lKپ! a+IefZ~|Vc]lol/ivΰ=[9(]4c vf#Ա:F%ח,9܎!Br!J&׍dcI7>eIfw$IL5I|Hc.I24HRG$Y$Zd}!I"#I&$mgIHe,ٽGqҎtdd4I^"I\*I>)a){#RrE\N:siN"i$[:;!:Z)sX-!v<=4d󖜛)كx9^4 GBq9YJ rHap09.J:bt?LNAG춎; $urLڒCTr0# roAGөd3엕%;N0+uэ\} LzI>j&I|dIُIۿ<ԒBEbR.}EJmxқZ"-6SRvBHjGJhr)?z)H)F^%+Hy qޑ}<{wk="K'y]=K^W\ C'W]#y!ſPR&e RV2 )IeziF'G/Hq")# RXig[R$$譤CI!pbRkRL'?b )F ^b9RZBS(ޅ<~ ~&Ҟ< "|軗6mM299ۨ>^I$U$cHaKIɔd|T$ɯ7^ %+H^:%$/'QIrD uY}X/ '74rdGˊ lzF6'JNf-[n+5d%=klEj俎t2[MXKSדdL:5G&J:CgV"O%d%9~AQrA6]C>5%ɕdlI6@8ُr#$;I#diN}7$WOݦ >Bf~~7SRFW]'CGr:lx;YLHL%7Is gڟ65]<鐺u:487::,'^E:Rt:;L4$tǝ_Hk?i_CrBӎ2w,#5't|:7NA%}k&t7}oEGVޢCBRNVG>cnhoM;&9ڢ;L6<#˔d:/' 2 IߤxO'|ry"#TdjL˜;D6˄?5ɺcKdWkߴ# od=Ykm ]ρd-.I;٦]?uM%d~YN VUdMadDֱb~d,[EfL2s.J=:6ȸ*2y[E 4&QOs:$wɴ5dt,'dtHFWD5NMQzt|Fh[4[<( +<2 2י̮'^dHZj#HSu*!^w#h oÓGdAvګM.Z:r9?&$QX<':N܍%= 2 YJn{I[Lk+EBkv7;RטKwv2y Y&8]8~-IA`y\{$K-)+IHҪ Iv.do%[I.L'ϛE6XD.FUY&bz\;b%xM:œdΑ!Y${Y}m:&޻FҲ#\/. r\KrmJ]ڒKM Lȵd%[L?Ļ"mI}>9[BN)_1~@N|Cr>\ DNVE-+#ڞ\CI \. j$26#[}? "&rXIuQΑ=Cn 2rY;mv.FrG.ޒ[}۽&yCr#}ә'K=.rNy le^" Zʤ8SM^%u!HR8mR~H^;ns R|xIAGHy`(yl$ᡤTf7]& zȫ) OR"e)LOI/L`!dR#ρ9=XJvǾI7KA:N2 }JvK֑/G޹i} Raci㛴-ˢyi43h=MxKSyY:ڛ6+ Q4,:MD4il{[M[R2/~§xsߤ- vӪxOěgb1mC-;O>[7<o qK<gp۵ ¥=P2]5DVy5 `!ãsg"<A_ MfR^'pXeX/8So`[&iu7ΚSfK`kC#`Ἧ63aGU[Ϋ5BZ0N2^WS=D!G]x*'#6<{eAoסs Kp?^8H <u p [pYҚ6p7O3؏ȀW@e z{8 ]o5N@j ǀHvMn lf<ĺ?n6p=57>x,{Q; 4&ܶ!`."d17A4~{zH8}" g#YRU*FوvgAts.G_+~CTi1gǙ z숨qIs#z[ u7q>sQSXEl-? (؃xmonT t$>$E!-52!]"RZ/6j=Fjf݁4]H_2嗐2BVY 铑rvB'r!7 rք#rL(4z< W6 ?<>!_'yƠ?j^F W1(X~yI(}P nFq׭(\QTuQdEf(Q oh15D(0E=/0v/pYGh.ۃ=]P9{paP}5q s7 ;"?zc #W&&uBȷC؂6JOj9'#?^"`*Dx=F]^K(x/ dx%J[GXm;ʶCJvGIgG6C#(Q&@?Jg/Bɫ *ը@a(uF:/.I( ݇(2(; a  :TBLTlU\ U#ߡjZ$Xu3BͳfFlEVԅAIWGȥsu3pEm娭>3P&.مKplwƧ=M;h5hPozh4-4-44@}n\qi6Գ P~q-.iEY?GŸ"ڣnV\*?`¥aq /EW=\f#Q7M{z=q@. +P.juN>yBߑu鸸(jSNɞ3u+QsjPV.PDgNPX ݜQףu?1[ cvⲖo&R.:-G"4^l4l=VhxjѼh3z}Cnh0EF44ofR\ެ@խhMOܡߡa.6y3׋hG ьp4ـYhw?/xq:4)8 OBh4sF19nѤ%GS[4FS"4e`42nCsL4MTƚd4_Cx4 hѴ Xoho&z4ZwGog4}AS!h%t(xh 郦{sC)<)M|Y⻴|t"LXqh:ͺpyM\nBڎhtZFh7ј9;7 u]АV^4C}'?CqhܴTFhkB͏/[稟|=硡* 7qE4t#rc١ l;)w4U`VPu4> hP-DOb ŅhB4o'8FoѸ;;qR4lqPX^qw=FK4M@;G0?B94>G+4~8*OBShr+FcoqR4E4D*]4mf\4&|FGg"и ϣ11K4/O1 M5D ј]Wi9hva]$8M\BԖ5?Dىu&⮐በ_閌gи*D$b\2KpIqqQ6.eB}OԠ \lkK]u5.o8\5 Q-sԯE-zzgzev@\0?C]{݄]:roG,XZ(-XԣԾnڳQբVJlQ! Ԝzn#Pl!Co;7'Ps'E 5'Q6U?jVV#ޕ Dr"~oFAdToEUjzT۠zwTG*z!*?=G]($AU5:ՖoPe>_oG\E:S'cvkP)Uwf8Uc=!(TPͨjר2t]Q9RCز U#Z+ƨ:QތLT5BeTT4[^TUIP#C7DgCy.wP|x ʺEW([ cdJWFIQ$Qs adZdy>Y1Fn4&BB~S! Boyo|M7 2>>o oXn{!G "/@{ #jK qG~C^HI휊K(h<'IPCdA^S ~f BE ]!Wx!Y[-3DyyOGׄLQwDn=T" ل؎LY៩2M~#L#2? ?mZkdjlAf[-d+jXd%]2n 3TyPGIPm!S$UF}/2Ef5!92@O2*C+ot߇HO_ sHiv"h]]tcNEr"AH^ )'7Ig,)Gn,"u;$vGJP1f2ZYT2ˑ&t DͭH=BӇri iU$EjwDA굥Hi. 5+%G~ -V Yg Mw_! ;@rY5 <EˑvAdU{fE!}d z kԧyH>IS2@|CďO@ Hxe9ZHBH$zHB|@uH])_" R:FA RVE"1i:T"UHz6DvJxx wOY#9Fi}#YIAH1DR$;#}%Rcb3){!EOaHyٌTqHGj$F/$|#?#RS 9 ,/i+H^TH݀THy=i wCH]HW|DjoY#ZĽ~M^4=Md^-@F:dz.Azw)'s2ʫ> n")#%ҫ"x21;2 ut9j  Ej$dy[순oL-!/ڋw-nu- >F R8k=JAO^GIOABsQ`Pq~uIktr(wr/݌R(1jgQe#$(=oPl9NG^ P5yN<?RQhu(<]>(E{xo'#R[fFcG(\mȫؖ9WBěHMyUf$T d؛ cGY"ƍ yn?^FLSBTf?Gb2:Dbw8Q{W#fnIF9Blq?>f+"qzv45"rm2"o!j)NEy~a]q:gf#7 ̨a#t~~BX?/+t"["(3 !n!|AVC@x9ֶBϧ߳+ Z:?໹~_7~)(}?wI>q=|#C|gd'8W7h| ~cױr(́O?)|^j÷e+ I,|+ c oIW< e]7i?n|[xy,|')|-ᛘu6S7=#>Zo/~eߝ}s5}^b3Q=9|^Nπn_їf 0UII^v#žAL%r= ޭ^t_oa8aIŚZ |;sg50'v`xߊGiրw|Mx텲E'(KBs.|Nht1|ϑsrQ{@ x.P ;*:́RЀgoPW1ZPdogR<_g£p56iTxܫ7B!꽧cO <] /{6«(Wx\oV NJFWiť[ ̞P8 $wAk6Cy :uxGMcPp}a7Ba# ~ipq7qN\g  >pwm̄˛p*섬kd}C n^!7 f -!nŗf9ΐGAn @fyk cV^l,Ȳe}!O ig8_ cT p1'٥ҕmT~.ap]ip =H pteiA:\) iL(\^z/d&p?!wp1H>}٘ǐ iT8Npy 7%t 9pq|Q; [ahv 8G[<y~J0f:$ݺC7al6c4,,`Tvaf\ 3 >0y]*.LlX:aQ -p*,ɰ9}&0=61Y+!- I`x, ` a,0$IY/IZaG{+=>8vck,5^gw82ǧ-?p!4pVW$t'a3!4*/mAwM:kd!{2F`+Cv0 #$~!=7&IG5PYt ϢfO\;{ir|mKE%-u-KmzvV}QTj֒:[F݊P{i]eE'mU-=7Jʢш'i4y }|ʠ_цSh{5[ÛjnMΗqw:9.KRrI@ H&}OcZBVXII$ۚM!ΚK$[dFO%פ_$ Mj䔺\ SQ&}YJoHf6&$wdoIx)#y;SI!ɮ!W}wg#A{B_H6떐5{;^ t/ H2dk?Nn̮S=4j/I?tggrI#Ի$0dIu*=|$׌$sD2zBY$M?Hyd>I\ES>#sW-'7IۗdkސK %cpq9"rHZAeOȡK:ٷG|>9FCG5ه$O\C$Oޓ}>$Q_IK${E}H5>N dy1I|d:m"I$nd?Aۓ/'&)9DWH:*9LR|n!5s "zoTrH/sy%9&|*9%i0rzvȩ]9ڬ Pr> #tDg_9hcr4tϑs:IE9|ur\Mq rhDV'v9

    dב$doJԚCcH~#ɝn 1Er{-rN/x[$d{',?W٘KdE?Zmz/ 21mSF uҵ~@/aՏ Hrdx/TL3Yƈ؋KZyIӼG&H^=@ƽ;j9O &;v 2;M:~cp>NVZs .rxl~DN#c:|drNj0\Cr23#g9 "t#rDROQgg YNz 3rYy$2N^FMdAf+tt>O"˦dy&ΕЩ@ ̦S]5p). C_2]mI'-'#UdВҾhݫCi!ZvJ'ք]t8;N?e%nqH?:'J&^@9tr#K&xtj;:EFot}8o@ړh)d:=i!V]Od/|S(_~Iv֔{$tpORϊ=~#iӴ_OIuw6ן - "'K=,e2x4Im6iT=m>"⧤?g!ݱH{d4iKfѾڥonmvK6# hv:rG!%HM.ѧ]s37֪.7#5ƃ@/N&3{QF'|1mP%Gj#ImYHeڣ> H+:tb;d!sd{/:G.БہdiCv>$Ȭ"dܑlN%+2kIV9IFjr8"~{k,7U,^:9ld-ƻlޑuY?-#Շ]6Y N% t채,23,rYYLdS+NU2! Ed^?̿WńX^̵ọ̑6y=d 2kAdr[O%:?N7!ѷY.O&{Qt~:1P2 TAxO;dG'w$]It2ix{һt˾ӱޤ_L[Ȱj7'$7%\ΛɈ $= y4$~9n9/lђoH~'9|H7O^ygX)FN'RLFvQV`mQh=<=cyL՝ŋͧ5|p2ARf}˟z<:k;ząs6j>OF稻"J4<|JPm3I<q&r' 2 KCa8|-|;:Bg#cج_صLi0lRMQؾ%v~kbܓc3qd @=]S=b p2glxL]p\ n)֊2-I sp9t4b7u&\Yµ!\t}=,_~%CaWUN Jh8 gɰ\?`t'VXwY0;;;j-`fL` 7ؙMü08'NIY큝;LaS&B?W!nCzG3 ɻ>[Në+> x##q"'z"s,E܍GuG)? <AnAO#sB vB"|)D.G4/@5/@Dm7pk񞂨՗3Qg'bME47q9q9 6ֈ?Of ^_}<bY#}|'Yؿ boG\px O0R 2Iul ɗC%ifY!k.2w@Fh} #cQ42t+WK!=b+^#}k ҟGFd.CMAv£PN*ETP^TBQT{C5, W!3ݐ)=א "s]=2g"sd:ÐMy 2|2 dXzpEPmC\d!h?dC2,CFtdz ;kdAlQdCFg~D.{ot:a>!7"uCK[ }d ; n0@V dօ|) ;.c됽<.c|@BrAN13.rֶCHk츅m;y[װyi9m_pWlB3Q x+W(AAy ;0F=Qҭ%9(yTg,vBa(]P%%֣t:As ?2FK}@ŃmQu59犚P3`?k_Դ4E> B[TmFST6_@ T Q6GT+B9ToD6<#AŇ(ThD٫c(_ySP{8e[,-esQ{e,M,P~/<`ZբeP?@9(HFyS~i}Q6J]P:%(1BScyu(p%;PP J7(MrXu(B~T_[Pq.َڥ75Cfj ՟5Q+CM;1@dQ:EFue'Qwu纣u$Ӭ@݆3n:Ϩ;u 6)w5o@ԄWŠfKơv^Cm敢NB'jK6 ufN8N k@]}ucP?u/:Ǡr!VE|4EEUNEDނZ+CԖ>ępG]ۨ1uU=Q ZZnW\haBa#Qwo%. ゚.̌~0L( 6\&uoNW<~"V(P7GV3jyjgmEmǨy5ojE}  "b_5&P##X;{PT5ơ@j#Pယ<[B'qG 5j<5ڠfejv&Fj,QcV!55{Psh-j,S3jLK9+gR&)5)b@T4GMJq;j権ķD_&jt~aig\ " 71jQs5O_Qc/x#t!A#}Et /I#b7j̣ Fo`ZD+|Ќ7ʅv/D*TFVT5ʡU.0[ZR[Si/p5$.bi)|y5/^c^5LiWP%7@ՈHTڏAc srp*癠WT\A٨= kPQwQŇPJ[?TEMԙP~"uQD(O]}P eKQ=zDzRLu/Qڻ%Pz#J.CɃ(ix!JSQ"G-JD~%v'Qgbwm.PY(޽'iC{8>bsFqy8|2ݦ8 P|_̯@/ םA(~ܷ(]QJ_C(4fNKQxgQ\tYe(g.^AqzWEq1(d ;M!u,řQϓ}BA3ŷK#?Fb5톒Q9J:?AIh~ {I@ɼ(Y%B :(;%s(:E* G0C>(p2#FA8ȟ'r5~&rC,r|9S999scN܎59X}EPE!nrKsN)h OېeY;N"ks#۰Yf"k d,39*Kէ2d)շYO#|d PC֠X / E?Ή>Ps}jF*@`_UPVB3T7 ar P ՓP4ӱPej2!Yd ,xHg% c dtrA5"TsA{23>A: *xuTy*KƋ=ƫZ ~jsvD PzUB5LiLGdXvZ[dNw#2C@wdT4#cc׏XҚ^"xBʙDd8KQM`}iHI?o6Rn!^Hѻ+EHyo"UH6 ?sL"ZAHԌHݬS~&R#KEW]W`xdDR^_.ҿ^EFW[v=C[i#-nM}i=6#MiَH@i-k.H?T&p!җҗT#}P=nы\G)ݑijO|.H5US@k#RAjEHmKrR.FJZ){$R6z#g2F}F?H6dHGrK7""tHG]5$_H%b}URn!ew]RE/f9)f!e>.HY)HY(ڤp$HVK/x")Sɽ ynnD s$=+@t$&uFbP$6"u)Gf$o34Mk qX$X$y!&#qgC|;7xh^#Ήs3zout$>?B2c$#Qu 7dHX2MȳI!I^HH!CĆ"o{%b]>IMMgG<IH^H΋ArE;"9%RV) 7HCG!oW$ }Z fZDAcA*kxqHC|)noBBrW$")$ zv1CfOĖ i!Ob# buED"F>񵖈oV F b#qNoG_į8E 683',At%bm q]".qS6qTňsS!. qlT!nn+qZW#F+V[w qf=o Gܙ}IFt"LLDL]߄ߎ"YS#j9񳄭d#~"ozJ >y [.zGvHhg7Ю#k {#߄-BWcaG3%A`$c$،GB\{$ԿCD$EB1$2CbcH5mg TH-bOe \X3իl/x+CҬH 1H4Iz i%IS|r Nm@Pνkvb>".jWdCލ~YI շQUQ]Q(?PhE}+Pl(b%OQeQVteWZg-ܬ Cޠ|WovcCRۏcP~T쉻_(xr=*DŶ{pvŨai(?,؍a(3b*J Fa 5EA%X#W^B"ok\h-\?ґ=o9G"B793! I`uǑcB 9.FXEwc9wȚBo udhzH +ēmx^iCO X% i)z;8;g@ "qpĄE.Ķ?3; BOQepS8/J"?BHB'C&G#B!O!B-Bȉ:A3$FSBxa K(r,bog,n{aW ^VI;6ޫ.^B6 .N^LPR,{5xVBJ((׋b4CʧZP}:& BoxyՁ2 ?Z کRxm-2x-Z7M\3n_ eP( "P<"!!='̡ԶPHWoa2x-#/^t^h+.d!R)ow#[x/qOۡ97>m#=3|g΀rxɇ nhx>P?r%(.RĶr(GxC9r'C eT[(|R!:^=Ay%o/El'P턲. h(\((|-'h0r~=1 8Ux,-<>apúz -5.[Q;pO:pSNww ȫ*!6nn wp)[T_ߟ}9܊G³?q'm;x\; Os/ gA^nv{.Ap_6 S}2GY x PxVSCcxY13Mxo</&] yi _26>|\7sAeA!rߐYgfȶ˿p-kM-duYXKb t{(u[\9@)p} A67>-_B R4H[&pvm\'HE=p~3γùT889HWl"Ο9bZ8RHB"8;Y8vb(\Bun:8HG}te9epEpYvΣziްO$i&Zl֢Xu#0a1fq0;ĩ0{09f-bv8 Lؽ_4/ xOy+?3XdmXuFOLө 惼`5'F LXtM)L;8Hs?O];9K~f?hc53`й-nű;qT}#rQPṅ8zXۥ;qǺ(xLWdؔz ( !e {0\[MK5ۻ+>N P֌gqN@yK$ċUgQ\}y]-xn77n<ڮkvjԦZ 6jOSKu8O}W4ވFRѐgT꯺Cn#hq Z#ҬScizWZUBk i]ڭ{=!>ɴ7m0xKǻҞh7S&ݣ'rȩ&zn%9IkI~̵upr\NXI3ȩ"ΐ䳊Id+3$'i$dOq<Ɠby?KoHϟ< ;џǒWr+-ގS/=;ڲ얳ݮfcX}evnm?v[ӛ-4YWE6=eE]ĊYyʊy7cx:{aX<=ˁ$~cY=F%_n:X˗a7?Yɀ>qFeWvp?〓908έVW9Փ'pD^~Oȑg%|[7>g|n>k:^sO|nF> GO[ ?8/Gѩ38zkX;%,1G9x6csLc҉[q̲قc =8lǙ؅8Vׅ3rt \lϱۣ86(csi{ǘc7r`-0=8/|ḹ9v6plu Ǎ-x^w}/9V%hq 8'-'{}=Ux8a[qlqlDžp\^7Fp8WϱS8nVO3q9ǽq89^֙s;8wO {sK>'})ܞ4I9' ]8wSunpe&Ler(S͜t ǖU8i )| W*}ʦ!wOs9;GyŹn֝-`e6[gq8Y9G.1cK8'eNvg p-|:##{+qXd䄄؂qq=>=GRrrLV5᜻9n<'Yqb$La68Skk8 8ˑV9]!9H!sȈru,簣B}8;s@y=F߲xyCVpHcʗo{I`_`v}[u˝4X9^^'#Q.):쮺>;3[sK|YbRXv}?Oa''iनt1ϔ p9#8,9Hоدr.pF?>mRgqXa̾8DC`1b ^bɡ8tE/~ǡQ39ɑ/|旨&uy9n5gV )8/-#"39ُ5rĆ'a78|98|oÚ_s]8N1MKar-+=G<m8蟊p-=YOq}Tr1.E2'rp]9@:}E 3rF'}Wfcou\fN?wZ%Usw+̬[9M0)f{Rj=֟a][}a+l=Z8~j>z#n⨹!؃Sztߟ8Ap ܋}teO=_ڙ-?X<Ǧ2:{Ÿ35})m*lW_58$GLQ9a]Ƒ93msDm;#-ޑs5M!8}I+oapWư'ފC/(}Ӣ*.q`A EwfMءkw;;c1=6r9g;9ɗ7:Ρ>qؚQ-p9du=GJ ]`0+! 9e87刁9z6yϏLȭśL^)GVRgv| G,8>|5GỚ9^>r_^ũ9qNŕbCC2sa9􁨻Gĺ88&9rF`E196.O >q;#GOYa(K`ݳw8:A=GkpԆm|rGXytc2|>U1sK8ڿ|uՌ:*qv9$9ay9 ϦmcsϦn稌|Kʁ%9*u{fGO_1^|~SG9 #ĩ{˓Cs<.ޯ#|"6犪9r/x }sc/l Ǚ DVp| N>8a±/qq.ǿTrB{aλ8SgOn+> \ 8ΡO!yT#[/䳭7rhx<}ȑ r-m'n '}.'pFN8?h7ǍN1Pg\w㾼儸wS9ar']ljNsE'6_>*$NZp򼗜:_縞s8 [Þ";ܥ%{L1 KbˢO 0WZd9Z|[/Z;OOcN.|x`>q@i4; cOl2n Fqe(ZŸnk3 yj'Ђ#> ydnX܃z̽;ysy4n][NC}gǿY+~M\uCz10~8ҕgbJ'|ҌV)颔K(:,EC)LB^|OU%yY" 2rݷJ ;rc_!?I2t Q;@AZ(;b^QWJReR}*%.v>?(%Aʲf'ۻ(Mw]u}-),ŏMy8}-vQbI Ei/)K+%SWOJKu%:tm?|ܒo(Ey)9o/s)aJҷkQN2RJiR҉RF7RZQ^D>Tt̛@ fPC*s 8. .tNwEJ+v]Xut+v ?v ۢ"Q] 5NJ*\ANzs =nctEu$=]TMLC z)G/k.a1d|[ z)o)sJ?j~5=ϹSJImo|'n-uܶ͟FZnpY$qǽ3]rCɳ;O䎛ӕMܩa w5,ŝGqůTq=;s[g{soƽepoj!>hSL>xIy<^1wdPV7Cfu Z|ɀ'IduS\m͓xRq Oɓۈ?*+OSi>y[~O/M)a<54gX3LxU_sfGj< gzsjZl|j=I| /`HOsX(gtm]ϟyoK[} y|ޤ]si= qyODxϕvwo{\u^;}KC[:myXXɻYʻ5hSwŻyoJE$mA)zw>j^ɇ6i8a E;V6`gYzf4dU0kN15gF2qok1d X ca3kʚ֬=5ZJP"Xr׎ƌ yPϓX'kZfykYS&ej=;f5>ձdk̇y"s0̚#Y#ބ5`+/X55+c }Gn\c͟|ߜaͯXn2ZXkwa&6|r<]:k|q=a)|4yNº򑗯I~Ϻ5zG⣻;`!y.k|ei~տbY="cMެf6k|"4нB绬'>]dVKY]Y%:5u`MD>"@5}`M٬uE2~~>k'Yk\PߏY{ >7u3 :YɚN*֜*q)kijXpV>}YmnV{\'`)|>8| :<3 |>ՆKެG>)͏ƬueX-B>I>p*pCՆcY-T+Djdzw~>kZ߬n{K kt]#YMÅ*u"xu0 { Cy_ geʅ_~aXS kLga?"fKᯏE<ÛY#mkmf%G߿ L*ccx82‡nzO{|pK=9tf53Vz,Xm5*F|ć>;־W|xY=yϞ|Yk֞ˇ+}].W|4h;:;DZ_KYo;m\ ~d|rX%\ڊ *bo&l`&q6-xO ٸ>M 6A`|J,mbN| r6f j۳u'6]Vhu=j[a#l#cA nmVr;YV?Ԋ>dVle[?fl}1˶F;}vb^خ}/ bONq%c7dG-KncW_vYYRy%nl7=?vO}wD`{l_PjرD#o[Y1Z{/2>ɑ%a|/`:mvp dDžl/j1+e~:’,IQdK૓vOl dlʊmr۲H6C-n[?Vb7[^c i6f7l7ӛMcF6Mlw.&^DOcI'Kdl7n7K 沤ȶ]͟lz9$Xm&eM%,1cYjO[džl؀mDkr8mwa2,g͚@?E1Q[D, ؋;AT D% 0P^ātw]3a5>{btYWn$gN9a3}l66ޏP&Sr Zao[ hœp_7v8k ކuQRlHGa-S-R8ms&:t*>Lmp N)p|/ Tp?:1b<~ [O(8&Lyg8t{pm9 ž{Ͱocr1J0(Ko~V4l?ݍZ 9W`y` lU؎=h}X/k]? S`C8EUlfѮ\2{ƜlЉ*?l.mWMsݯ@X lXb-!V`T[٘`?W{!3ݏCq8 {6Va{6"#>װ1փ`K6 l{u;ㇰ`w'|۳U/ Dv8#va>dla6>ɰ۫kؙa`2 .<׏Ou:t;_;פ d]w9Hq>lS9/]S;؍dNNlwmH&Mݖ֙ްֻ LN,Q0lWk;XY X3VvXz:*d̗`2lUE\`YE`1Vw/2=9 {aA歙L@v`lgF,iN;L|9߅..MEܼ`z 5mqu:I`yf6ܫ =0{fVUЂs0Eaisa>,nY` L{ M_=8 8e0;&Nl98U| gfV`e6F`.~ X\8 q"]dx/>t0ugވ`2gg~ęeq#m>V]qn9--_p6}LKaZgG8͟8Z3MaYJ} pNv"]7>x"q.,j`1,6laq/NNU)+N?̂IQwe:vC c8gcsZq ,t \ ;¹g?a6>,mâY_8a iٰ8 n0_3p1gg]E8sNLqz:Y7Lg0ǩ+K`8v&N|ccqToȻ<w 1fy˲>]g<=8wW!E!_,o=?g>}}c]s$ve9ir+?;;c3v1z6?2Q-bS%lLWaCflHHQXo䉵Ƕcmio}`1XkcXو+>,lfjlOaf,`l퉍%X? nǖ l}h-y&wFvywaGtN[VM{ aGslOӣ0e1߾nK}aoUq-v/'<Ž^~~5'6טb6[y9c%<$H`>h 'ؔxpbX5 V`yבXVeFX(ޝt#^#GXp3@Vs^X0+E0 B`6OybmZ9#6c+8Ü?= cV(:>RB?(Yl䌃*U;`Ůa‡U/L # Wb[Q; 1xa >"1, 4#V0d ŭV6JĀe`@hTW;z{pDe 譾=o@# F{T4^c'zkG-:ItڊnTt]]Mkt~NK4QlNuѹ 5vyQ9:yUƿZC[_񿳳_s?c{Q'V"|~||`k5f=v}T77M}&t|S|s,ߐi?~ooR׏t#5Colz[qV(V+;Ti$_q%"?V򏯙U׍LWݚWXUŏ|Y_e_+O._8tf#|yS_ӡ/_xx/<"W?oK >E| _>//+>૦<㫍*Y|ՠ"_W6UYq|E#_e$Ԣf|s>#&n"ߖ7o->n1_?[m#v||d,>=b_Y"|K%kq="9՝ >o{2o?֫|&` v #/zi$:츋o9љolP7H o<7-?o까oo7aW+<}W Z a^|||9_w _/5믷 #w |m$_vkn־LMCf3ӷG濟lm:ڜ|po~gMOu_%o{[7 M"9<-)|K)_SW/9L+ZJe|z.x\W嫃UR9_ٛ/ʗrz|N_lΗEN.(JGI">m}$_lg_nf'K7CLW{=BLΈ{ſGɇ x<^}'y IVbc^8W;+7x9&yl^j/N޼^:6;/m>DKxdO^6›Wjeټ_}u='-|Zs6/R] /Hg^ցYZldXϋU>YO=‹{RbqC/X܋O-}['Q}$x'I?.h?X?ݾ|n?Ǿiߤo=f+O*܋Q93Yci+4q$4?[uGt#+/K1|T-{>Ws o g~J>>j? G]?C<#gס|KqaG>hs_>dv>xaп\uo僇vMn9??4[ە k{_F+=fM/E >V|ɗ|sA|PS۹|chl>c3R5,W/; y9 ^&Ku!j>_Q7?V=\o ~+fCi.F8zLOk\~ >Y7|Ŋن%FؚaeoaOaQp-E :Cn}qrE8B6w=p!ŵ/8 gl=`#ոe'._+kqz[szB vZ5H!c^Zp܅[n~<1y?&CDWxyX/6:ٲ q [q;\&uqn\2apq\WY|o\Ožr\1?Ņ8npYKWR 8ᢁ&\\$.x=p a8N` [ z=zl}6lBV\Þ<|!puS]O= O` V\pZkaw~-8vOmŮx8ԫ$caذ6IaR>rd^}#X޹(^[v)7h~ŏ-6pHG8=vGm҆C'8][qpzfk?ݔp*d8L]NJp)s5\?|FTHG2t4;`8n߁Ml[t枋;#.NBQwbp6ohBhW?нt>I.xJ^~]ERYr^X"VQå3~Fyq/%G~';"i.70ۇȧˈ1^QIf~"v$Ҕ|K҆HHrۚLfs/f\N$ |aj{ 7 j/#ym(ePju/]ljm+zgq\0IR.*3 )O/ixA$Ϟ(ԿSI5Ծ}4O t?E{h kiIGoѳgtmiIkQ hAnXD}yKk ĺttfލKt5c_:,ƤBﴷa:qy=PGG?l/DnC_ql.qth:y5:sg:b%:q-||tp^4!~?Nh)G'F҅tkUh+΋hwž,D'сQCzC5VAX3DL'\[C9[:Y:>_PT꩐0IyJtj Z#MF#  +[v _MM1mG5\F~[r4 o}\1ˍ*#? Krn*yCιLqwX &0՘ڇv7C[]z 5.i0jR^M3|%^~st:AS("j}MxhF'f˅5nz^A~$D1&vCP_=-e=/<Ԋm~twy:t} rvI' C?17k^dߦԢԘjЌ֙GўL jMwi25A&t>gF ^Ch_eYtϢ C,Z9.9aܠd!itH!f6'H XtP,p*{.:c-]t%o hư'¢y gN56 BD3}R<%~oWG\b(.]x$>G_ "I׸\ML!dkq/\9Q%[ݘ)le\u.[xȃhxKnGrbf ʘƒ s;[XF&o5btgtB٥Eµ΢2:\iwhj5 :PgуWx`ZOܷG!e2wt6[=_t(:/AA'Z _|lfr;v݅hZs7 )P Z8e+8knZrgnE|Ѣw~BP_-pa„颦BЋFq/=^˜߃pjz3ۆNXI&~VEjGW!7M? 't!]GK{ 4]XI u=5_r6:8̓s*፳3pOo5;}NY_'p1X ZC?GJ KڻS'li (G颴vzx4:BhWj$$|}F;RtF՛XF;s 9Li5g ?f; 0~=n\]M:NSOў!t[/=d½u*CE#]8&mQʍ!•AC M y02L~/ DkPYXbׇqŪX'T­·Tg o>'HNw G ܦFMm#-+?qT}dh:ҧ]9<74!23{?Xո>@ό?J#H5+&^-9)%J RUtt:7/tPX + ;~JƏw2vU]})'9t7druOkq~4GHۅ+O{2W`+t9 mF} ʤO!YvBtaUqJ#(h jD1BAg?f(XG}6/dg DI3waf_넫'?uAHP(S*4t!IMy/_DS}+ވ{ jc?u4YxzR ^\(rC91\k;Ξ?} +9?ø)zܖԁuN> EsnUeJk&FsM ܱ]KTg+IᇸRA3 qfq9=Iwc/3s(t9~1*9PuI%E .xw5d͖D.kѭLQg2tpyx_#WՓt7+h>.x!FJFߏ%B1F:Xyl9IsN&{!s&ځ ڶ h>fr]\crҫ ~h+ .'s^/N|~"w$҉$t*|$bHT*DGB^;$a{[~'D;$$f]rq_^A&O5C=dH)ܽeN.d[drV;~&Ϗw]3/ & ӵnܪyySMwjVK^edA1"jn3_#Doe5 " >-#;5{.fD=,31E:Ǎї;ThL.F1⦔˚?_9{w9Kd̉\ѫ\QiX=VaE/!DU%=Ss'q7r#;ƿ:2:jnc~5-&4wu^t9n$o5%.%ؕt:1[r/rAb Ek511ir⾕ 't"ë3+%]ɫߧTbF=rߊ3zt9M涤ic^NmķrH~Dr/+ ޔBn$qc=DʕۙK-'6@ss1m.2b4|Cn_+'2<~)ZEvOvk~v]2͸ט~nji2t'qjHŒD$Z)Ht8|ʼnݜG&C4# )}K|&R3򫐬Cɡ+~djg= -&^|,yLCƼp"'}"KByLOǑ2I1ཝ SG?Af {ٓ Ed;K^6Ġa!ѭ:Aِ)3 ]GOHO'=AdzKN !+H8w}>GI#b>,Gz7t$os_s9{c[f59Az4qr{e.ɩOsBfҫBpۼku Ho')yteTLPpp 4# <.8R$6 ǽ{\ٓNmLT#\S]*t 9 t1.W%?ia*:ܟ.BWBۖ8k@]jfG:}MEw,C]^Bk#zp ]Դr[fR_ĕchs^I\?{m+t(OͶ}yѧ_Sc)翇:NO<[to; 9BeFQ}"Fjӄ~ %߅˄g5]>edЧOxsLxj*݇ =t~ٗsZ/ /M?-2lt%&TpgL{o@ɇ |[/ Mw޿x T~Åg"ᆚ\x4_$Z,4IH3'~~!nPm]!Sg:,3kЁEBއWۺB}'Dx+U '6W 6 #\n8,L_԰R8\ػP0YI& x.q6Ξzu pzmܪܢAK_}(UgA\kr~m8/3nӎn%w4.M q3W~ׂ\S.~rON\y}ě{e,Nc=WAs3\E\tu8ɚω~qr9w-Ia\G3ns9Bo2zx2ʎks]_ΕK ng1jI^/Z%v yK斄 DDe=Idsqms~.su链t:k{ԉk $}n9~fOcbe@vQ?rQ3KAf꓅"L9{ %~,#M.~~ ?MsRȚޚd$YI EzmϪBġK.JrDRp>پm 958V'W&-Jr79qI5&jȍ%b=2q!ֳc?ry qE\)2+bv 9ID<}zo'gq='}s'9s ىGĨьlYF,.gkOOcdۼdۦd2rܴse@bsD cuX6$d/9}-l'%R̓sS`r92ىr6 &!.GyNVD=% 9S[H!&&Ѹ<*lЕ곟SM7/d@N}#|6n?٠:@L_$jO/r9dC91Q+%gL V9ɞM%do[r rNIv"%]dS'?Y9RLVt$;#֑sz1Ji\#_&| B; V29xd1lM,jg_Cry?bl Y1ϔ,Dv_+SrR|pv~.zܶbuk7˚5y\>7'Ɂd~2W:O 3Cop2`=3\t ]vB'%=s#26\L4,'idxo=1M-봇g}! &s5۸g|93IIM%'czy~{7-hF!|H焓_HᤓW1XI&9LO8K&J Gq;qf3dL6h;GN dUM2̑!H-,2 FtJj$Zeݹ[|3;qgNr~ܺɅV»-vsS,bg: nBc7iubc:+DDf0<$aԒ“BcڭmU0밷 VFC[tFtstB5s[p[ㄕk o o䯳xl,Gz[mzwti'EvV.;[m+u1*!x+M8TWx>d{L;NgDz\xO:K&rTr?щF?7 0nF}Νk#ߓv"^qlEo?Ch%ч!/x.u}nAO_c& C~j4U2;MZF3ϤgRɕK1uoס v;džҧeaҔF>4niE<=;:B_tKRtʍCuP*ihc;<9<,7zGR"^D!\B#](gMQ4c Dwu 7͠KStѤVDz򾈚zKM+iߥd1jf<=㢢ӛ#(u$u֮#ԞeԺMzm6uñ@1;̕x.@g$ۂэ7{)lPzM ]3 I9Rn}&]ّ:HOuK'^#5tߖ7]z@͌wГtX@O==E[Uީ1X$\_B Qb[>,<=֜kb OgQz']VIBP~]2ͦk襓v;ٱn].l,M4$Ӣo[>ѝ{Q͓Z[o ]VA//K]Ɩ2,M}Nի鶁{zm]7RFsꤱwP۷{~:N8XNw0:sըڲ0:ff|!0О:E9R#n,aR(sGBBPoͽt4k&ӕY6Bu>ѱECu|[dž7HTNքy^7zC[Yo?=)Mf1:? C+ȗ][ISzk2:Yz# ^cNRT$`)] &Q$qW^%7d\=é,3R D0q(#=%V^Zhk oO"#I$„2ry.wWd. "> f7qO$WKo#}$:ym9-%W%QC5z:2;9?t,5Y7F.&-z?Q?fWɄ<٦Bn+C b˸Ӛ(㡯̍k ^CvFs1A]ȰugHDJtҽ nq86,N d^1y"2(!]P=3^ר>ՆK+j2nuz 1WJRD3 _g,Xp-Z&pO~+os(= ^~=@%dϹlӤѾT^IE&U-F>N\ 0jѢ~FߝI y]ݳ#dwZ9PpV7рhP1(H5 BmZ CBdb[m]mPWCeht딣b]aRio/\7I:'N -׹w_ۻqkZnmVNfO'}zɽ*Q X-+ w w{O61jP;Νv0ZnBJ,AQXA1m;kY- jTcOݸ)Gzu3>e͓>hl4Q95Nѳ :'4~zK_] ]<Ӆ4; _xd{G%zWSOV'5w1q.}F맧Sɸb6 y>6&RܞJ#^gЩVҕ*rMMǜ+c=o/y\'|?=rZM}>&k= WhG/[ڟ?@ɦj#4DҋWo鶑[J&/+}P݁^SZB8E_($MEw탅/ ʨV!Fhᰍܝgf67n[Fu'x(Xn~FӰR'Mxys!N{ GJ4.Zt5M(3{Ğ y׏%ޭLtRH/TD,D7V֘SeN`v͸?HOlAm fO_|ǒq{7]ɺzc|o{}@ צގVI7RIᆲ^db(v>O Aw޿,}{`b;ց'Wx9y]b2 Yig&г:M|Mܗ"=z!"k ABG<']?˴Z +H\/&ΑrՄH$x#xk%xPp?@ki c&ӝɒs/ѩ\\t'>M\f߽ahqr B%HqP1s]'86qȎkjO\!mv?k#5__FЉ^>RBLlaM=GwcL0c zNIGRpq+\?;:W_M5W_M5W_M5W_M5W_M5W_M5W_M5W_M5W_M5W_M5W_M5W_MI⬂S)N810~Sr ƁS?9fNq:c9@Nqa#e)\qf!5쾊S[9e⮘S4>2Jnl=Jy-Ʀ74~8rq׼.͏nǞ0姄k7mEVeN{x0˕58ԉ4y]?Cbt/ـS0= :1cS,8C׏F@sH| Npa@.t=KWJ݀^gqRܚ|qR:8W ܮn;SΓ< Oz_V'{m͚c7>;+z]ކW`r < 2?!_h."o-9xqp>bJz-ޮûVxqut]+|0:xJ Q|9/;$pABNvx|߬@Y5!_; .-# { u:C5 T p*H?шӑ6"W*. O'#]JbWYHo yYo^Ԙw}u3E1dGƩH 8^3w#{7r09NGr#F#>!9y] ѷ > h&pOnȟݮ!36 ?E1C| nE(ԙaZ([Q`ǡH' wyh3hq 2Q8N9QVFW&FQA,ށW((ls!O@2>!d[)5g78 fAֺXwCes!WC]Ed !rjn|}ZC|*d +~y"gΐ?,q+d[*![UZ@jikrVOb(ط˙\tth@A~HB I܄HAE)3-i2gCHuۄTZH]iW CR׌x{H]%} Y wDC9o;@:{v4iƱH2 !5 mH% ~zWH! AdK (I(<| ~2T>( ]n0钳PFz~Gq 'Gftda6 Py}Brd eH:"à 5%! dpD8vP}OGn2@ƻkphG?\Y~2@&~%Y)H ՏVC7.3:B PYTWC zCusPEP6@%*G&2L&y|PyA P=΃*Tڡz *4T>P`l'Ce\kPug5^Biz拃sKFA0vvq=(Bg (zd.'CyqCƞ (ڮgM(oy'۪w((b𛐯L< :(;W;Av!r oPȓC.g6'B|P.)H?]'}RO O&S&SmP~D:a!ҫH_>fȘL\˘G˃ Y㵑e{Y{t=/[<}t# d{Evq"hBo䄺#Vި'KEM3Ef'Xy7MF<' ?B `} ^AAH 9(ُg(-̧Y%( A"?+Qk(P{S37[ހ\7=iܽ '̐r/#bd؎,$"˕]#Ʊ/ANPEƣZ@ylyO~QPb/ %( EP %ZP2>(BYewlhNP e-}r#}墴5eN;Q)&@G, AyTPC^|ġ-*zJSC0@ɺ(6)FQaMB 9/sQ8 #Px nl܋|6&q9OXܭ;CIC$dvu2 ÐD}?o͆T j/cmP. `i吿0fcPNNtb>q0oCq`t|Adr?C#DHՆ1{)Por^eP|b6'5(5?zfOCq=YEb ϣJ5w(30۳[ 7d]fklgfqCPY?r*("Be!On0l|Pؾc>PLa-zAѥVB~53 ilJ1S ]Z) ,N]mj$ bH>!+ ,DҊ#-<̜寐|iHAH_AqH H#CېNoDSW)H{4C{#!>A b;R"Dlw8$ %Ǒ)+eҫ/.v,CXWqg'_B2F oO U;XtɽT0YSsCfqARcvcA=_ЮH[̘a_x(arlߐ^P, !g 2'2g=Tk~^1}_dq;T`BlXaߘf@ ؞GBz@Y0H·o)$oW@a CiŘRHuaH_ d.Đmf4'P1nUN @t P\bf/HQ+[d1TwJ!Lo/CMtq='tG\rS(Y< }!Wn͸p4(\=XLdsQ&MA /L'~By4íLƌk#md1r?PJPޅy%ww=LC b7}ʄ03? YX3H%C0 z߃DF#B> iEH9 vwHY<9ѐ4ن^f>qO6`l1,7d>d!_3q=Ȼ2ذ|@rYIŐ b{iIcr {"VGR\8,)rW֯3~T 6 \_Vk"iHS$"m`.`$ ]OOD+# bHB s?J֍o $rAڡT! g Nzi;H\ qeRgq_@JqB<9!>Vk1?r" Cܓˑh& )Qq ?≡Hy. )H)ko %XH5fyHMj"m郴' ϐvz Q-O̭ >ߠX.SBGAHg"#g",dELrFNyrHw>1F,g P?QXE#_7o7#ߴg I3#o1[#o3IDnm=r"7V Ðy=#wAle&rg@% ^7 G&rg"-rro O)2@W]r 2lXƭ#u("2ۏlȞ =F#Y 6`}#KYĞ9!62}z#GdWYG3څ.VXȚdz!sA52!s'Gg97sՐݖ |#?{s俞ZӐ yCu$rvDNE"1[ rG#N΍f~ysk!rfCvC)rFΊQODv5 6"0 ؚٟ1<CXB1rJ{g6 /&GCRVjG?P VWQo, wiM?vAS^1L@(1Gq9J&$f;JuQjҫP>?mƭC` (+^r\(?ތP Pnw{P`xT\ GWTOrPT._QQ8eٸ5+i@MjQ9ug~L+$ah8oYh֢ M3ǷJ5|?|M#iplESDX|h]汯ЬE͏+Eh8ͯl/ =4GC44o}#mh.Zv4ןAs44x4ΡZ4D16٦;$K-jМʕhQh1-Fhٯ@*bhyt -ŋcFah9}-&hَ0 |q3Z^@G ZDe-ü/Ϳ~앉c|7_y&h= M:DS;uФhjFS?=V[f-Ƹ]h<Σ .’DznEM|Qm Uҗ4Ga +T]mLG#(8j(eԪ %E(YSb(*_";(C(q<r/ \w!t $I[  -ecƵ!1;L]!a_F@6ddX6@ZxV'jBvbȢX\5C>@>ŗZ̓͡1c#3ƌ^zU, ć!9 Yf;C7Y<{lB冓@qh'hYqS^B(/Jʙ8E!3XP ÒE0ΟX2$ߙᛐ8g|Ƙ* i%Fi{"j>RFkHqI={!>|Ha&%R Y.EcF-$gFX- yfW19Dim9r$`wF!y+c)MH6:H~ێ#e #H 3aʄ"j@]Yn覇wHM^YH[rЛ%l?Mlsr!9 I-HC:> R;ƶEz@vf dX ~K!ˑ@~1W, TuR,|H-keC dJƨX^td_Y_6n)uW !?t?K!g޽!S7e/,s% vCrHo $匑 y{ rm6#ekG$\;WMdpK{ f}f!$ÎBJL@nAc,r* c>2<_LlUCKg"tOFN`g䎞\O7ۇ.{].,.KAb Q0CT#lP}q+ 5IPpK# NDaw(Q4 vP8>KX}LQHPm y ꪡPM Qp w''y OfbVտa܊<G^">yǑ‼ Ƌ:쐿M|_CƔl=Pp r?p>zލ(z  PHB)uT#.(mP624Q5_P*Ci@iEY߯'QQ<tRJ+PQ1Pz%(=s3Jǿ@WE(;veZ(Qھe1~ɩCـJ苲"9|*g ?P1"'w*.T^J+v&*?C 鋪SwP&PTݨCU)TZw(:s-jNx&kjGm~mAmv#Pk;jלB&Oڀ+}Xߌ4 u;;Խ݊y:s[~@BX4Ark4܈G,4xE=s|4끆w%A] 4>4߁I+_\4FZ{ Gа{$@4KihŞ[ Ѱ]ײgVl|Q(g0NۧFB4f8qC 4.TG%r!R!5Mh!7[{4x-a{AQ4?6eǾ{?-Z{uHNSJFN@B6}Cơ+;B{h}K >uW~Fh ywkv~9ږlDx}Ah:hmDk+&{VTNA:ġmC0@ۓX](B }ih֌hu9k,ÏI37?˲c'*E˹@\Ib濌%vXlN4w&aOMy<ͳ6rk@Sq".뢩{Ov&;=0{|o$zƣXۉ·>~hlƠ4:1b4괢qX8d5GPЈ+)h0|ԯ:s6AmjlB)E$]ԌzX3Qs[f5ojPSԲx]{7/օ5̶o3{߇1v̞g6*sQ[m_Q I0ZyނZMz*jwKlǨyu:%izh8GQo9O22EݙhzKGUԪ߂$fM:%ꦔ6{j>|BA~<5}P3aj~02Tw1A\G~Rk,'Ot8[8{(| XSg-)I> lr'rxٻd5#d^ #*lR+J(=B/mqF?4:CLd:$D a.K ei U0&kȸn Ҷ hڣ:#a&/'3q3cug!%XNP i|82KA#޼ t :4f2~Xj%j@ƏK +Ʉ~?5_?ōOPxgCSoo(7~aTӻA5ʊPk%Pn 2 ;ǡbyc-d:C[Ibc6%RCS=+!>5HBr8$w#i6|ėlĀZE#nE)b#}Qe-?,ó5'"܎!|Zx*3Sux2 3{x<&!r9Bn45jQ[GfW>B!1"JDHa$x<.x2xVkFxq4DÓqx:HӪ ]p5 ./C6=vAa)atV@Yvz=žBX{"D7E·C1a9>8a?"",f>a_ ,$W Y ¦>BF(¶ q?{iMBr>@h,OCh.B+G x. "4=cP akx+,zCS!|J=¯g"<-p(F# xVpEzё3G[D@j5Y(Y!R zETDLoo=<O9^V#zhWČ4A곈^3l-;^Y,+y^ko_<^?[%x[fw$r~"7;O:Ӝ@4|Zύ3>g ~_{6|">!H |f h?8oUZl !M\\ĝGܔш0{}w݁|^W=*qۺ l1D ꉸBCo>LB<]A]OYلtN+/WK_W C>H2Cbc$#y $2B$$zZ=%[R8i!rˑeHCwĩK!~C< R#Ր$AM63r)Z_ImIy/z"A'Z{᣽1G  54Sxg5W5xSV" Gx7^jxQ/ 2=o*@x)낗Ub)QEcY{>'#2U=ATeagct9gx0Q+UQ%\X@KO"b\{"#m{ ,yBi:ݯ/~MR-xg ]l:/LϽqW _~%|whwf*|Jc>/.6/,f3dO^yg+ࣻ+}V1gb6 >>gGOgx<~ p'^φ~^څ'GT0n/{m𨎅\܌;t S3E UR, Yw<[4/|mw.w}fr^a% ^wLwlWNܹb pS{qpu3̳kpɔ X(GXԆ8!Zc_vM`ëdy>> +qXr?|7̶ ST1FZ0y,kWMtm:ѳ 7}~έoy?s>r+ﶻw_[z/Ԍ:3x~^w~X ~x)qΏA:|.| c8l}o>hӿ0NZr^+/ mal2k|mg_k3>iE1ޒxw!|q62fQc-60~]Y~;k|cgcimi5 }Í'V~1N+{:!g!L~#?F>Km)xJ)ϣӋIf|(>:ϊVv@,yM!wS1^`Ln{Y1opp=,az.a^؇8DsqbP{`yg\h q[\*pw -n·:7U;E0;9i,X,] f yp]\_8io1??xPzJ_H pJgƹ Pfa<u(m7##rG!_r+ $EM?(  JP`77!ޠ`+ @(X"FV4BYm乏@nD-rB -=2d[d!?w" dF!h;TPˠlղPtqP̆*=~P/S!7yrdB ˇAV!+yv.|5B>kҗ&"}OgbdNE=d#˺?哣 #"2jغޮ_ݐWX}YCA5ˑ<ϐ٥!&V"Ǥ#rB;!Q!6ODdy5w} 7@(C('(0MDGPtQ؏}E7C. ;P8 g=DatFuۜE(>Q?F>(vB^;&J ojPt4 LnCQX? ȏCp@y4 cd]2G-SdDΙ(XB3&f/dsD_!ҽ;\ U/az≌=Puw Px.m˙C6%{slP,lS(i!lsȯ*6@jRfK+Y>ҖÐCR2i-HK| ɘgHlԟHR!)/C*WH /B:'$,vT H'lCH'T 'BA^p uɤG PGh-ZfHcS衐u1%dC! ڎ3loh}P>kM9dw=: +|Ꝑ!3AƕچL2m0؂~l1T:B!c82LCF`>#*Z/_4xQp% "c {~ Y 3W9 h>@὾(QEZ̗N0@->S(r E3(uQ%Vg;&H¾ӂ"ʗs< 1L؀gb7#*|!oLG]`thvD?r.G$6}+c39W wH/u=Z,9R|_5d!?$#*Q@F`wi(sEO]QX(Pbsw@g(WdDFTﻃ/[Q; (]eXQq0JZ(7*zMh@ej^U}s*nF(⃲IPz JQ&EaK֢b NccY\[Qn"-(tꉂ,>N\|xfɑpBxIduA֐<-⃑3;| g  ?| *P K(o@%B%U fzt kz@Uj m{{#iW/"}e?n#.Oxl'՝ PwjpfW͇J?= ס :=(P݂K,PJ}s*=[2)l\ͩ,g~%P b5ߣ~5үކh'ojтM4T"yNއ},9i* ]FA $K n/Ri!h y;$o+ $OFfGCRBiWT~5A}X@۳d}2EAZ8{1YaNBedmlk^(Ay:TG(2W!cse5 ctYPh™~#:1fry0d3 Ԁ4qLS@a~!sNK F2|ݡc&|z@x ;t\Nys80HWߠh9 65?@U WlGH?!, `(TZ3Dx|j.P N{B5~B Kٸmj9;Pԅ@n%߬^(J{XB9O~kKq̍q6fWl; (߰Y,IμbW1;d9 0Bq?diaשi&2f&H!MWH+/Eڷl~ɺELdl I&ƩӇlH`z HXZ4BeNC8%!#LΤBt?ds!Ki-HHLzHg! EȯhC>L^B>|dC M`6~V{ lXiG2'j ")C5C 9;Hg"W%f#GSHsC6ɣ!9}l ;$sܐt^'$IƐn`6\ i?9\ECѓhoqH 5H]D"5zRg As)&o|q3HmOd{Ƀx {!>}bwDʯHqlA)G/S!^|JA B< Fv4@Jx=Rw"e R!Mij_{"")k!9+6H%KiHHVE $ۊV$MD/$wuCs$`'EB-$7B_W|lHbK*ERI}")7"y` >EJ[FB)/m/Rn}HqDxO5LLV ޟ R2߿%FH,XC7H]bI!n|=nzԒ:m#$#&B$x!{'7C(5P&]*ODS 2"?˭X쐄 OS&Ř" 5g(0@Ɛ#:p!kWZQモ(:5(\DZGlJB~";=BȟyZ31$3䭜MLkbZL7tu0ӧxeSL=0yƴUMt9ebzLId S-LɇEYQɴSR[T yc2;Yu-2'dj$kL~Oi3LGa*ء `Zfd1VbΊ!CP -Jlg<ӌMSW&E%;᫩Y<˶?t)_Ƴ"-E6ҀoqOl? Gg"Muh6ۡх-hWnנ ebNʊ9-OwO bUX tㅾ zLBN>,a"H[E\%5Wv+bEKD_k2ģzqgE?_~EmsA7e:iGW"m ΏhowF+A3h[4D{ cBtE,.`Mh*@D$ʣh?7E{4)QUPyOQڊޝEof4ihg=>~j#P8η 췄@A}>=@%v]bG6#_ b[$b teb3YFCb^ybD E՗r('Ċ9|z]Q'ĹQ SOIO%pE!nQ&ZILF#d, 1iߎ _5%$2$iGy^t+yЍ7 Gly}>^I֨QdL'+l#/ Ů^͋+xUË5xa(aӁ@V@.Fǧd&K7,fdi˃d%k/:x,YuȊ@C7.]&+x9/ZxQ=&܁,d !k=Y <9Ld޿LdNIw-ɴ$3@^lTӬ:z0-cb#0)ق U"-*qBOW2~K>~2oy^W!}F=Z^1i;V(:/RǑw;z3R/j3I/=: o ݞ%bIa[c\~ch}.$Oq&)$CHHH=e$"!H,CbG$Dx;CϑxĆD{[w&4jyT@"I߾4Im'ɭ3IkIBoh2IcV(u],%M$~Mq+&yl$b=t&Ui%58FRD*3'ΕdFҤ$IH!U$7;B$q!bYEğ 1H,gE™$?ϳ Ip.³1goܒ {@\<<'JcA̭qdyܕbx%ι߈P#aqޫ VN#BBNIPB*9F6oJG~s|; _wԏ躏DvPF4_R4ݏi&Y%D.Feo2 44} ES4 K2^ruK=v:b*긭MP 'M#5r€6ژ,}R]—})ЋG<;ѽtKEJU3$]h~vhM݅(m? b_et}Pis-י>썯wbi]p!O}gݵhDVm$ l\iԣ'>lV{(%ᵷ<^o@-ǝpm \}}v#8x+ǫ8>uǗoN>EDӻ0p[NN6Sh iy2Nqo8Wɡ;N;q +ӵ0ƹ$O<7Y O(Os]sc].Fk.OR).cs|Z^\)׎zm\7&n{SelۥLNmmZmqUf n][;Ւe wrG>Nw܏9,ۥMqcX/y):ssFnY-M/nȉ۶&4Ɲei-W,M˓ܿ>y\w^x+ʣxh)^ ZOc0^.q{>nc<ϫށς|>s zxƫ^#jHmx쁗r+="n?w꙯'^q;sa4V{{¹y. } 9? ύQ-\՗8g5pb!.|8}E:R Ew2" ep ןzx'\pץ؎k(r;N-é/|IJOs7 3g q8C8;?a=GFpH6Ь>m pĺ qq[N@X19pOγjCxoYa}teg> {{Qۙ ؎,ݵs5b] V>8èk؀سp'.nEX~{"-a3Aos~8ԫߗm`'ݱWo. iؗـݕ_+MNlqBcW탋"{{;}Ni`wp/lWcw-Fc vv˶s΍Yҝݵ^#ydvUǦ7.f l~XϞaXbﮋB.mp-l^lQ`׾5`-^]l8Mvs`';gUgyln:}nY5Xi+zd< fLw60z[u&ԝas_TzJۂѾ],.M&eQb>UxU__սa~*=U~g\Wڕj>).)8ZSaնkΪv"UrUWS,P5wOhlUWUytÃUJQvMըUcT.W_U*]8t̏}(\Z\rơ*q\rբh'*(5V9gur7c?*\r2G*W/ʹ_Vr w̞+W0Rro-Q*5n)e(~>|TRU9E;GNQZtUUb*ת:>Km9UU#ɪiih8ݴce+~O7Jp_nUt߻ }ي6:!'"yP;_¿_{L~{L$0AkT?E '; H_?'.A=!7n@M9AZ^&Gx'A= ;?&Ѝ}Daa EXYwV:Y&?Jzu'"6 $%Bʼnh h[a+`#Y0CݳDh+]mdD-\Dde UQv{P;&z?cUıgѩѹ@۩7:Nˣ] ",IhF)4%E_})>ϕچw]h>N<56F M\nh&|vA14ʡjM-x6@}#Z Ϋ8$>F)Wcϟ"$@k t_ځnvit׷ת4 Fw 0N80~1Y$ )vEZ5 p?AMԦ.;7xCI`UN##"px-AH d\!rSc io^tߥ+ߝN rH ˚PGPR]OC_$kG]ؕ'w&=Wa&~K@?{*/?2>B&jh)/G)_3Im*ـuMݍ_9 *`j&w1~_-)ց'~㆟i*~;VQ6-$zoK*,U\w𛗁_g) _j~ §.!Eя蕓E _?өB_rl-}؋KA|CG#d~o36p%`oX9f'BG%$~G9V!(\Gp 1`gk2VMH}!a>=!A dB"5SB ,EKKL'v"|—?NC"~DdO#b$"%p"na>Jy0{iD~HUk"=g~D02jqDyԍ7̲#e"%o)}~ sJ؆ׄ>@اe JXބ8AhՎ\&߆u ߊ[/ ~\cęr2 pTиM>m>,яŹ狁Ȍ&$29j oU;Fw'C8@VN>:ēEدӈ'ng(by2Of$6΃V=+r Eb_MIDO1, `ǰNyqX~P#~0!<5A uMJki=v'υ+w)~]Nqi!*:-~=wߖoo P4l|ƥsg⯼lO?鏿؃o~&~m7\skkߔ!l7ߍ+޸X'|) |O¯{׿~Xd ZvgDYvmo I} xŞ+i؏ {J111-n|.Ak4,1 ]hLGuc Esj-_~&ˠ9zM?4k[JrK]ǡh~@Կ||>ϊvT FP-(>a[~W1L-'DS5Ϝ/\oqx nx-b]~J[;eU綡n/Ф}4^Sx/=q.޶#2˺9gs;J_c4 ?"w}~D|Bs MAhG?,n񛒉߂zq{r@xM+8sOKj?HzYGW &Ş_}>T?tfvML"EvĢ?sEmM'h=cs]MpMhBc}3\>Qq6;h;ᓗ, }IEzC|OWcy}>XӂgNhoq1 ;uѹD Wt?f gsݲYoDf-֋Zj&y(3hF; Ի ?34ŲwG}k_~jwT%75G[{=%_i>ud 46@,|/hy@lWhUvGNC7Oy&*7w4XM'F|62?k"bK— sG_vQ9Nz(wVA]SWuc#Qgi~֮ǻ'^%^'m%^r<>mT4тVjۡk |;s~:>=CΊ5~^Hź*ۨ1,x$~fCBPӡ.VxOOcx]Z߇wR#} ـ5f=l*^m^'g5^Ix,d'ڄcIx3ڟU^߉=&2}y }ʊqG } ^#OOj$h4ǻT*4K>\)w &xiH;OxGx{X3!>_S|ޱbo?^7>qQw݁tWɣBAߠku}bmw˿>"1_ڧ&xMB>AHxQB?"직wBKDl@D6FqCb_l1\!u?4us&bA"!bP5/'"rÄw#?a ON h9臽NX Aw&n>a jXKX/ aK:?: $l97E_."TБ Y 1腏>箄xM^B6 aILJLHh$deBR:@ >vG ~3WP%88i !2 !?>"!Y'DdCТ"mKq "l47%t-BuzAx?(ڛCB"^$>"qjK #5EhDB$t1Bݮf՟DOB:1о~ޟ UN"OB,%DXFq B%d.Zt3=Qb.p5uKѥ[7BD ' aBTDf@Z2sy>SZ ?^7{b2bkEDl3NM)ľlēZFœ_dk"Omȁ0M$Ø6dVB8;Lmt0ә<0”6koLk1=FL >4]iS+ED2\o0ADjG`2XIzJ12ڴ"IG2&8h^ZH_^MIk HcBu[H9@y=ɍT$99;O$hlg'Mzox':gq><1 ߯eCE}\m!XC3C NE.tB7>a7ŽL@&rea[WsXuB֫o,H[1D{w>X8uCO+T<)fмFMf+%Ρm){aޠ%|laoǽОBJts v-⮛D-ѽE_tI§Xn5эbݯ݆]2 h?LvhEeD7Ѵ=/4ZκJB}'C}&ZTD{=?TRt'D_*"(i  $o)QNgy½KO^£7nDaD+GAk|;T$H\C˚$ nM˓t IIDBH^F$ eZRH9]H#R_R;8)'# )֑bIkRGpW(R2W'Ik>mHY7eIq(Fʁ0R6< PGR&eMyRV Y2_{gc0Nq0katكq~Cfcl0`cUd,$TTrDg(Bğ%vCRN""%Hc?)@L &>\cыړ:i y$^ .[/*-2u0,%% c0i B2 s]8xO@wx>y~J k,^|9]Kbj"/VŘX6 #YrJ֘:&kiIsC2U-FM'$AOIhZ$kE$lkI´$BB-X0*ă=zL$cH<>$[H⭲$z _8#Ie*T[Cw$>We(p/O>$i4 Hl- f) D\(HcmHibo&w$BJk_"٣ Ɍ"y$ӓIԅĸHDm&#):I"YmgG }$0 <ۻ>#xEq⌷^/PoڡE:vhvEJ;CBCu=!§ O/?}KD@ }_]ѵBڑ6~U&h Оt\E76 7t{o/߸ѻ9[j0K&ˇu NwId8NnuMw'ޫ9gфC(|JP=φj7diZ^g=<8{6Oư%\j᝹X9br]\gG.Sܫ?N713ǍnRc~_rc%rtKGǑ9p#N&#%1#?r$993O8[9Y%sPo]o,hq Ǜ x 6WNs^w?k̉p9| 'wd6eGShNq3'O;/pr|.~sQ8?s8%icx>sD+}s-8mqr~>A{yq V8]S%N.Iʜ8>m8*'gNB9Wus2x3NŽq_Qd_|p!ǹ[9mq]8!ʩ8=ӛ8Ets|!Nqz+pnRz9]<r~+.G1 8:u)pm{r ͹ 8BΗ |n\3&p~)7 \[Y \<҄KrKkkWʏZ|)JZM?q\ܸ;3r,m?nmV,p xk~b+q|C[;;cmۍ}܅>m'wnV4[OrÅϸ˟b[n :ɍ땣v c͹,}zE\:rc~n}ywЎ~nF-^aG=$ȝJxrYމ^ܻ҂¹hLxY7qx_}x3Jgh:UJڥcD]'*QߛG!ܯmݸܙz7mw7ݹ)V%K-z\݆˯U\2i\6^.ɹZu[ɹRsn)>u6p~EQΥ'r3™-9{wp͜N>qt@1\tmpi|:l)\qu6\eZ/.oZp.J<8_ۗ8GЕ82Zo\(':qN?8⼔/#9dsC=r، q@y8nc8Fāmh#NX_ b-֎`_b޺ݢrӰɨݰh͈gwf 5>`OAa# ⷰ OǾ6쬣?c{Yl0r MBkl\C82a߶2vv-쪟&3!0l(m6c[m1v_n3~2me{ֲ#*;6I=v:شqa{Z8Ž351Jgb%Fbd1 Ov?&u?v禳g7s==#v%yglǶZ뱙-Ciѝۍ~~ؙüUl5;GUMnioٙuK_t~}~U ,OZYΆ[fҞ|7,S7gR^-8eM:CE<38b |Ny}i7MSu$wP%/z5*|V\Sgo&}Byk U>Qmj[ATݫR ՘SU6R XS|RUU_:6wQ_V}E+UWT{tQ,HauU6TVGjnQU3Ʃ*}0U@U7᪒=TOSU8i*|uv2J{ /{ /{ /{ /{ /{ /{ /{ /{ /{ /{ /{ /~ڦPPMRH5E(6ZRVT-¨Htʉ-~lv(h굥Fķ2eΖIVlyT'sNO%=HFV5rdʠr LlzI|$ Oī۶=ƨ;#͒?OumF)̯[rhV2I5"{P[!6`G=9J4FIm$y$lRKklL]ϮG+HK)ew#x9$ѫ)aKiD³I֒MYK+OuV[LwqyvllkD^&o-fuIcҺ yJϙ<;#Gڷ8ѥ({MZIW֘"O>̰RWD)ѡQꓕ9te1Lv`^-L+z죑4mlqKrD_Z:q>{cޓrpdMңYZ#9QJVR+\['<4ϥ?u TI2fӪ$3LR4VkFiFICwNϖ}LƷ9v]I~v%ٯR9MyU9ͼo%s&pSԔ 2Pv/o0˛,iҹygnqE3R6o|96X[wrϞGoL7)w4դyrAB) J]62۪$=l|sXS&V3ۇٖ&Jpsm je~jKpWd]W_% (5T)ې'N!E^ѯylZ9wJ4EsF92iy{VJpZmwu;l_Kmcg+E޾Yݚ}tK\!gqbƞ \ukW[9gZWZ;G$dF> f2V#i|1vd"V𿓞}Αy+9y>xT`WKV/92e(=mhd&ƞMc fdپu޺ͷ7W5*i)JE+Jki4Y8"{TUJgx|{.!ԟݮz M7]( y*v-nΚ3lFvW[h[L? mGSݟ)q%|>wtbW|NRVW-9wZ^p|އxO{p,>9|AWDOryu| %=u{eE{_\~>|t }],eoreZ֦=VN2o y{>"|-ǩ4R~#9c".N.bf^fwgnMk ^<*߳"\,xe1H2mx$׵JNJ/~ՁyQ#w qd1 9|\2a1JnօYOfqT, N^U<9xr=+k2yΫ ^c2mr),Z_>Lo?Vs(q?ҕɭcI|>2o,>~1ml{ r(ʹ?\[.Ѱ)o3ϱelcN|rm1k/QYyd_!g)=|e y_؍"n}=,pu$Wfu"?wduWKJ w>fX<[_{~Az_{x]֔d3s_/͒%h7!r8]Zfgۮ|+ߥm+u~R*/u\Yv+{hӳ3PzV՞Ov}\7wW*UNs gwסeiI,/H\>cQ*ޝ+3oK?R>=3Fw)Kcny*HV*mUZ*jȷ9d*>< ҹ\u+ ka>yer*y7dWJ֊`yUNQŖ'0?+S?n;oNHVaK\9n'0T Sa*L0T Sa*L0T Sa*L0T ?o}U-RZ|cT(:7dώg$CoOٷA;0ܻ͸1ȾarT2߷ME=r-䰒I9uMz6g7Cy:.h$TEn(ӥ;!ywa?<4ϗ[|TXW>;ێ"[9󷻹P䳽y Q(d< ̳YNHc6 &?|.DYy2[ʡЍ5(\uߌ̳qs9hr=OYanP[SffJ r;*Y&coY6Q9(,5_es;bw)wr~y6z2-#}]q底B'B׬7 |/X$1^*!"Oo朏LqJt},שL,2):RZd c4AP`dtߙ|f 2|Z2[W]/֛\>= Lr9|n-ddA_; "o(YήQ}힟[dcͬ|ca.d>O1 ڷɞ'9z2qd˦7\ftWJ}%~ >䰖fZ)~BZs?Wxd|PHuVI珚ߏoHs)%IzRm ̘esW^fYs}ljzNkQ{i5阷̸$wxƌ'%ߏ޹Bgy-_)N 9LJErZOֿRl)%`gI \slaJVsT}'izS zNU;|~gg> *e H7+#ytOߑ;0w|%~A盼_DCȯ_^>}|c ˱;OOxW\?WɒG,>Jrܟ;NJw<)ID ;`9ɠ|w<[.Cd9 օ%߬lגΒ%9mKͿOd)ee= wy毠dԗJ)W Krez,_c)| 9ue8JŻ ޖ\`pd6N7$Y} e'dws䀈пOcCew wOOe ^_>~;W~'0Oη :[=;]{?Ip)O15,;ߕZ,/-'5(ÿ/;red)cE.C]z<'vǂy(-8*GxvWo(ɓ%\EY>w <y I0+nAkԑY7例k1\Ye·]^M)e. v +RzUV(zȉ"'Rd'{fJ&Q/%?EYZ(bz/V*!r%K'2~ WFঋ3-BD Q-z%>֊3((t)mgT>j%(zZI[iu]ѻmP l813tywP"/y[%~vRyI"Y# Ec7]Fvo,sJqI.I]xvY-vx.x^-dd_WUq֨ƊkXQE5hԨ;!Ɗk)b+J.}$ @W !#"EjF ҮDlѲjyZ;;G3?͜o9^\Nݠ V/ QpcA}!긙V14$>\Dz>SaE_%_E"{}qUGtDZdr8%({پDrFiM(.YO<ĆTޏ 'AI8ns\;h%9/e{{"zY*ڃe;)Ε=7P~+}7Yu|{95w:͏RJb2g7k)_CY Ա/sZ/se_&oR]HOS&O~Y]L{[/P~, _[V\{i孥]I9a0tsU+Fus>9 ncӤnp}2v}!V ~yAsʘF)cY &rO{6N=T֠.H|Z&Ӗ B0ZBeMZg(Nx"F6!Ę}r 6b8:9̖m7 ?N}5扽u8W,A,Kg:hȐvʾfo]?Zl{H T~Ϟ vI&G%N"Iʑ{Gd.Ljđ^\'\ K ʉP7%1z,`Ⱥ4 3 th 4t-gb^qs:4%[@I8%wFG|= )8R]5C'y PI9C}cA#O>G܏qLĹ)3gvRuI`D<$Id Hc0CI}Ȟpg$d:=!%Y_#N8G'?$ti"uR^%mhgI{,笣vydmchS3K|ȫmKG EP5h]J)Kd9rEyr ;,! wb1/ )w21N:}cBp^ 8$8sD?\goE߫ u}''~|)fP2Yz~T;G!QCݒ%w $Ale=_1 "~'sB h~Ϩ:s찏C.:(ږtTŘ@lSR1<"P>Υe1_ fA+pS R%cs Q1|=O1&6%TO&Ud\ l*ñƴpn^,UŜ^`ь! qDӐؾ0CC9'_9>@yx+j?&/h87CN^tEakaUvkouqsNf'Buu?:*WGϦ*?*P_#n雧r3*(b9|O{Ce)X,:\ӱxL+}Hq{+}a<^qNmg~()sQzPRcUۻ Ƣ;8FR泿cU5wiZh^Xd MF6({.vUwSS1Tn}﵅z)=Y#mFpV\gw_t1ח獦 *kȘosz2jdoMEbp/t\31+.s;_hK[[J# Nxs^ͱo.U`=Xp\=mR l&I_gRl&L.?x|%}eʟ3Z)'_K[Kp\sdAy"Gm:"URwvkװtVYsXusk&uԩU>L NG>;] n꒥[)[zlKEA^ /9ʞ?FaK[# f;-7.C8ì}Ξnc|XJ,Ob)+ʯ,uNW ʟ;b:WG܎VʯcAxMk?{8'*{ll/s:&N,{קNV-8ʺzWI[Z_u2%ٌCmH}>EvpO8GxK\U`[aҎ7)OG6x$S'>Fŗ=u:hjKu)%WS$ɃecOodw]ǐj8^ՙG\"3Rg[%-Ħb/V[Hb89_ˉ\n6? rRw@|>2c;`Ύa4s<Ӻ)rgWmd[;юT>v"啊g wveL%Ŀc>pvf;++9Ab(X(_Y5%R{knl}񶔱\[__bj(_~1p[g}Al#?7\}_)uWʾk9>.ߨQ~C[s]&VY/U>gq9Qsl\ GR ή W>/ ^9oW9ɬd_:fEV;?#vy5墽+ξ{uѮ|,t}ڦܝbx(G5_ҭjS&q4I|='/֨9ucփ 1ΧοNG7Xr1DY"s<ſo|tbW6w/ K)V3\?5*+{wRʟ ])p 'w8 b[CLQK%.8JFY#}EgFhIQ:b_H}\|jT>mKG|kh_Q@] ?o&kZ}mH)Dq.Wm?/T3ywk$"()rcݭOg[RV>owSg]ʟu\8HH Σn5vk֐&ql-y7)V?.׶Y5a]VD^pL-,?~C|{~ΡUœM{=X}F9,X_ö}6yDa.D>i w߱ޣ%{tWP~G (GP T{G^tEy*.Aly|tй|Ϲ &8*|r}ΗweN"+sN wܓT>='@D1U~l6A>cwWwGԧh|JAoH<1|\b=|]?r}fSkn5-~?MmmLنTw6@{s m} ϘOmn C&t!mjskmҦm߯?@?Ɣ&6Gb5"@ƍWj)'h3v67mC\~65ڜ{.@[@jϵ9 6vt6ߨ؋9m6'.mNG9K# +fy %Oqh8]զ ]g_j طݥn8m:`*Xu٭ͦ<6}i,tv6;fmd i(*ԁnyy6/ w c^!^| _|CݘWa E{`6c@aOh+g1 L_"^A= CoկWZƽ bz |˽31?]}uxF竈1v^^}ݯ`ڼCYm 9oh7ji{՟G|Km:zw^D}ÞGiI6ki6A\mO(mm/( wt8J+R̻Em/VۣiY uklu6C#i{9K2ʠU m\=qGߵ6_YС!mKVmk{S/[f׎6Kac^W <VAE6g0f?-nvοjhm[v'pnvnmwL6/6bc<|d_ ]/N مs=alٛmX+ak>zl\1yni߁8U×rHςj{e4?2l{:!.&Yqp{p #d#$Xp)n!;J߇|o~g."\bDljwfېK<ܟu %Zծ &^QC/u|=@ń[ԝ&ćME976 Ð9x0s_t&u;=DH<wFȪI}iؖ<#G =/LdǾBOH*iy?SSeg%+8݁`o!5eݳ0؁dp5ۇbo| lvGN/B|![WzZ:CEYz^ !kjB'=xPp ٝ+c}-YgDkKVO8j.z7/aWГX˅Get+OnVCk ꏒ?з%oʝю ~Oݜ@L&>tFӌF\BCrG%᝟|(d5G w/{ ki01;?G~Ln߬Ԫ|-j[]noyB4\#wk:ܕeDzD@HP=cU=G̞ǿ(+{?>,]w":Н LW]#e==N"}#zw{O=8G<2_<䷍> |rdz8J_駾+S~jsfgY줂ȢKgy˞bWMn>;]ɿ{M>ͳw\zEΜnJ_Iv$oc?Bot9az;~zUFa=g|E 3N}N%s%7ջrp5f7yӄeӝ!~ݼe"+qx^ } zpz[ۅwPzd.`t^xOӣщ06<@WǮ̓sȃqYg:bz{,>93ԧ fjjеgjZOU&56+Ʈ5:XզFE'17fj8]wYjxAM{QcjPIoKũAʨp0|TUc[jYJ4rϫz5֟.]_kCvѫYvê, Ը7obbjtuxUc| 5SjBMrzhVSjUMǨ) TSJj*CM窩u55mVfmrUSָznj6q^m:5 YdȨ&T5mޢcytཚg3d=ZMsi1G45Uӂd5@3jz#8˺q;55ERӾjx%'viae5yC?ixUUS@5 BjZ@M{#zUSp²_Mj:DMfQӻkj:VM οț<\ܲeTjnVjZEJ5w^MܱRsi `57;\3jnuyUsD57Y7n?5 Vsj1Tuޱf?(I|Հu~ԬE Mnţ[͵s_5W Þ̝cFNN tQ¯Su\ާܹ{g75M̓yCͣy \vyl!5O|WfP~gW]jR@͋y:5Fy=wKz5_~KLQh5'}eZ2wwZNT˟RZ* RK/j)lKʫc25TlT#UI .2UK{SK}j Z5R/oZMZ-r꥖=20ZURːUj]-7Z.TtfW$Ȣ2cZ!cRhZ0>06_rW2'=>jYY-evujYS-;y 4e}lVˆYjYS-۰E-WN-~BN|P˶Xm jYV׊(߫śyW+3.c\U`rxxێ_WA6˦9^7~"cLHZP79c;ϣeFdncmpbf6s^`V q9t[2.EBs1Z7Y+\17o9`rF FfU,rzF\oE%1E-K4wi\7xZn}Oٹ~.mobEעWL C {VU. kFr r~˝x=X?A:_-gE`ԇ5tylj WȺęK`"zǾs|o0x4—;Q|GE\Rcrt kw8J#/U-AظpȍC|wuי(p}>g1| Oۧ 'Su.?Ö}Wl N8w 1ˢxjA>x_7/ '~ꬖ`s|_gy eQkzjZsUk}jTk^BnMSkk3 ١V̙G@#]_Q&Z 4Ukp TkA_PkUjzK GF|ChPkSh*]QkjmUPkBY_쏇l]^-_ZPk}Qk{|Z;\dD^$c4c_qj6P9Ξd<Lj6tx)k 6 w2{|s ljF8b;e'h2. bC~Lj햢jxqZC#hï^:Z=NuaN7R:uF_Yֹ5-P6.עj]LP2zVԺRۭK2 j] Guq#Qy37=7qYmynպvĩgZwކ T p= Zj߷ZodCLx,g22z@`DZX{C. 8FcW41AF:<7c\a{4n`^"2[l(:w 𝈬$;I|'c)jMi%]i2 3>!͏sY[ jT*9(1rsn9ǣ?= |IG5y6! b.>'CԵOPS>^D@}xK/!}g) 9X3F"<63wCsԖm:|S;nsw>+w/fWw.rO]nB\r2]\'F]NݠFD-j-z:}2c#2nq7ޡ?C~OF>宍>}z .~Mq n⛛-ƻ'; Q!|W;I.=wgVp DjhzQ=߫ 5}@+߀X:ْ/bQ Ne^?>2w]z˼&9=~ayxEwޅ|ӫN?\;oCc'e.ۼ'x*^w*x-睵wڼy[~yyPD0GThD-y3 enP?{n o _c#j>K Їw~^7oг1@-›lŽA[z{){oѶ+ҞoEWKbygƖweGH ی=yզ\c[7DF.8׈wBcMِDmROM%y3VuyUƦERw|.j.UYUKKT7h+ywVƹj@ KYY9[7Ti7y%uIܣRR[Kej)J{It- J,Zi0RRiե9WXbSR9=WU V?TDn%x{]T n3=60g?co%ޟZieqY+SKʃ+įc 0UERmVdij)λojT zj[m|Qě- 5%ĵo #qژwoS ͆MAbўmgtk?L~ o}o7>o^{=}'gn׹Z:Q`wv{tlG]hGnQY mo`KS 1щ_.67Mw3rE&Fp-vQwZgс7<)t7[}ŧq{x!5v ܰ8~Y& ȧ_*1qjzȬKķ0_g9ϵv6n4or## ^İi'-Ko΁&Ժȭא Wg|n 6[a~0 kִԕij:\mLb[=C#Nusj56Amr1ߺnmpS k:C̓'u9_ ݪ/5¯΃szvePݯ WjW<1ȷ* 0\ ?I_bA;.Pw`sL.:I-1o6K35{D͟[F5`,Qd$[tC<Ԩ?\ؕw9AܲgbS;P2SDzo6|gT5 SƢ>l0e"sI j'/:P5#3Q\$5_?rjN0F#5mCԼ']u U6oM[ռަռs97?L͞<M5jf}5k.5ȭQ3 T͋|8j>Hط2?WG65A{ܯ!jZ'$^͍jI-߫?ߪ1[ͭFM5r\?5UBMojUo5ŕUӥj:}t&45j%iԳ:>PSj"M fC3԰ھVSӬTSWjBM9[bx)UjVllZMswuv<ε{S[_ß!uV"ٟ[sEC;%Wq:GFiN>؇O.Nj&hizNy$Wgn>XvNRױ.[@]/suս-YYQݯiDfDkD1W#<ш}5bLX#Ո=5b X@#11F'jDhiq;5bh)F컬~2›0"_xDwekD >hգ:A#R4aVH,ӈ xA#.Ԉ_5qFdb̎U1FqgFl4,y`O::,24b#pc-a70a ш75b=z̙_k\Ƴ6FU1F4LԈ5whL#҈5v Ȅ]0ejiD4"cuI?>UjN\4<{vЈ5£FsQF٧jDJƦCԈ8ge0zfnN:+VR|*M]]V+|bkVյUW|G/9]Gãz@ UP;Q:D.U%PgZ%u3zQ]s{RClMۧx3ԝ }.um٩[|5ѽ9\P]N6q_w񮊨FǞ/KFnB]k5JSWD7'Xu~Efi*Z]ժ=u+[ wy|WW "/qzuWgQu)5x.Vs<|D^w[ԡOmհ:Wu.=OS9CmΞ+H @-Ckc Sejg6|x>N4fu暧4U+Ұ-8 v÷k+ 8a_5G /:Xs+wܮi?5<ȉ]Xoi&͝4?D_ގa;kWiö ԕe5`z9]'j{:7'R1ubij2Upu%d'0O])wluwm.%5L]K|tfuRuFoQו0u]+INbr\V>D]?s1_fu>A=y[@]Ꚇ sU(O+]]KZ?,kQɓ{E<]5v!+e0j4SnQ'8w~Ïؐ/}LO%896gF=ө:=Sg4<'%2jBu {?}թy,XĻ uܪ#O+=˟A]G{3uSWcPEݞ]q_^o y m] &NȑJ!uVXC#(`=GolWԹojJ4u—^#,C]lKLXB<gJh:/&yduDk99 'W{oNnz|=cXR=3k2G0RZY:w5RWE7ץ.oG-ziͩ܁٩1E]Vjۜ ~fen0* ;{^BAtB]Kk5{INuEZ%Ww..GNL˪՝=zV%Q5ďQOSgSl>A#EؿJ]oVrľ S//)w~yiVwb4 dn;O w]U^} ;W{Fwuw/Uq"z4S tܙ9NZ_ݫ{UP~FňYX|Fսe&>nr=ns:黲=B~ku)>~㾙v-=rSWY08ŔWluϱ!>;@]ݴ*6v^yWQ7!/2K벩kyu٣uMɧk=FGj!,2GkDhD^4su[/%5zmu'&m}{e-CF[ozmF i>kkug@u{!=99ƱF@ g}XHگFgEGݫWjD=*έ!/zkF8%76zS8Ak~[˽8$z5.%|Ѱ\CnӐ:i<{zAj.ޤYݕEg 8E~.V5=wfeeH@4`+_׀|7ejEi{̴h@u+MlcտK.T)~WZok]B}QahЫ4 JA/ipNlW\~hp: RYeѱ9ZhP/ {4xI-ӡ6Lh~kK9lz'FjO|c_:g|_֩#wy ~q_#5u,(Bv\9Xu1A%&BuVZ:$ڝ1r:fW6]Scg1ulD:wSTu\>7ugT0NSǣIHإ'LFνq:Nī#;/o:ʨG[8sq$I']>3S#F=I% ? 𭥎e'nӾciIuxcm:yVirQ/]ms/_WllXM+|]ύk%"ú5Bw >ۦ]ðý=`ڋ^|t Z9`(pr<~w>u͡[qe 6Q'4$Sd$ߪkH,R0ZC Ԑ2_}4i )q!nԐ hH6jkϏ@֝{s?d Fwh4$Kye\q~F缬_ְ/?ַMXGL^l_K5D% )yMC*OZ>Ԑ:ȫjHy@Cj\Аu iMhH̿>hH:Rժ!]9|~4Ibhg 錯Z<֐{ۢuӐNX!xc>xk!mj羆 BeА4dgam4B~\# =٥ҧ |R4d :o!ґ̐읇inF- >iyZ!M+8ZΉMߺ7C>1-Ӑ bQ։ߨ9mՐ^4d@s_zLCvX iUslqWt뉯ۅ؍5U}G56>Ml|d/iᇆDY")~j?C_Ԑ*¿_ |8n D c_Uw<_🁏x#(þTӠO|5r&DfĶ1CLB.2;"w8oVЍz<jH}b=#.|9ب. RV?1I!^ݲ'VWX'Aw'85pА`eMNx?O$.Db3 |t=au Mu\!GS`u\^Ӏp5>|93i56f[}6-̠dž%s\Kрmc`|ݟ6ߢD 6>W!x%oyׇߓəݘGmxE-/zp__a394>F![ɇ)ԏ!ԕ2\(# v4GS8?=َ e #^&,Z԰A`vcw|RzԚ<[f'o2 ? E2cfC&tDgu5[ѧu }cW-a{Wm+fƁ7!Se֐5ԏ/t9ۏ{wr*K6]lUG׎ԙ:Q{v)MFGJ1"ySQӗ}]wr5%kRzIJ f'$=#z#xv܅Nޓyw񖊣Lz/,ze7=8 wwxޠwzD_z;_'2~-;oBry&}'==zȢ?{{_xC'FyE^nUwx|fC]~Aߢ{y#HE|w|'O'^M;o.׎ݚ }ztzɯ'?8?¦xL@xzO'~A.!6>F^ >?ߎwFsҏox[Vt~׊>+:6Mp1z˩coqf[͋wu{<́My'ӫ^L-xrȻy zLW4+oL5\ ~[DO C QwLMŠ4xI. :N51<`?jpnkpŽܸtj4`MI\u4hp9w؈5 IkЭ't|Ԡ۟4BР)mAjy-̫AME߼a~=Ahg-A2k5^Ojwkqh`G \Ni8uȣ/5pi \T=Nj G kvv~oizj Fgf4AV j`[3VTK쨁T" D?֩$?~T?UjԾ;LrhGTj?Q6yC{MS;=vGwq4|H\ S4ᛘ`Vpgytօ+<>tuX$c?%mM|q9bz&U k{o?cX@q"fs'}cq`fU}7q11juY2}ڽ'Y>3N=}b Uf,&k!`)9jT }l4:9gyt O0`5$[עnxY+#rpi|ު}>ƶcT04q3F_ 9{[)O3gk#0w_uӾޘ|oϻVaS{;#KgX|I)18lAi{-#C-v[_|yR7SڣJrތy]eW GR#5/wk\IG$B-S.Ms]RǟE}G/g̠]G`2ߝwm~_7I,d_wm׹ ~mbno~G߭w*ElQ;3qS꿤/=}?i@ 6i,L6_6Դo50 }ҏ]jIѰ:jެW4E^.п i6[ B5줟ʠZO)LwݰcR4b7u%M]3|:֪kkGuϤZX]]r&LPwcFdNӈar/ʡ{>sKewru?;6uuTRͯndWwͬ.gV%J]7aV`P4u[սݶrnw"ly*h{Fn[[\&u?ٛoTUb4^ݷ}?\Rwtuωޛn[uS^/1{!:Y辣c{8nS_!S^ W-uNV'/퉺^ݧw~Ո"߂y ԝxZ:4"u?Fas5k^S +uVWW~a15Vo5l/-հ!ֱoGF5>hC`.K*j;J!'(}@ a![ jjp7ju}|gg!5%԰3Э6w}ldMpǞfjP 0X aoYl)6p 1??gSmԘ?5X Tn+UcjWukV4OG0VRcY|gTc›11y Zg56do;16.diS8Ӂ o>@j[PVc$hߔLPcPb!ZoWc]UcKx:k9jL]bl;g:AK i U_-lb=Y'c+Ԣ>Rv$=?ee֙2k =Uc}Fv;~tg{Э\·@ƾjd}a`QH7ެ{8WwA5.C"j9Zոl-FBj 8=Ը%e"כ~}qXӜjm l E] +1X0QF0gSb>[CrqdFj܏aokҽ7q1 ~zLŇO0'~E9s:,΢5w=Nq>Xe썞RԸ {́hP|؎_V75 `j85nxƣvq;@H_¦\F#6<_6Osre 3' 7K7y&V^>\!w+~چgKaVOov_4 3{쏂ѓf`m`o)􇏍8q/uޯ; ?`GQ!:;䅿/N/T$6AL}H||a~aهCw8:n|2 = .C}uSLo88`~~ _\j _F|j<Ξd",#,Xߊ\qdJ^RE͑?lF7#v&VB.z-Ć%ӝGoFq.!fZFZ#wiuqy]A>.>s.6n_搹~5XÞuo-Z:jκHFھzlB ϖF|G.PK أ$w}un5F/H26 LӇzg&GW~;zzr{tg?b;Ќ>>٭ؽ ,P(v[0ʼn5{'2g"0ڷ1'RGG |ul!yE _s 5cɉ=_52|S;ҾOxfSw6rl?7c:t[ U `w95m)zN&WgYdA0x5 ls2nC?|{l!3>pc&ԎA9GrQ_bB??z K0>go/|̦EUaV~l5c-5r:z,/1y#mx>`y W߃.o[E}&ƃ3=ԕ afϸ\3erọ,gKo K‡zEu+K벯Σ]wqX^تA+{+PrWZX8VjQ_ "}d"Ľ_W&W'(Km@}/I?P:R1~"֝7UJ׮ıq>+bij4. zpXzVEK[VO|Y[ܕ%gq{)bQK~E/jB pQ9njEyLel;~ܵdC=5z# k-9u;ė<9~3y' +}jv~=KMeQjj=@Mu[5U)u%^$~" WeF{ByC;5֗_ .ց+߁ ;s\>@< f{ 9x;4Z}\!nV){5饦\_ԔoSST5 VoՔ淿JSS1TCM5T:KԍJM3iNjZSMMi`|4UMsWi^Lƻj ('I{ԴΥմkdf~h5鮦eoXy5jڗzj⩦\t Du)5o ubt;wbjo IVsmjMMk)?UԜw1e\O5UM/p#_Tӫ} joljz ijsN5l"K\ilQ+j]RuUw[bOE51jȦj>T]k=Lͻm%5Ϋ+|ϱBOPujÞ潓6]Q~񋸫pf7"v}_Eu@!jfT MyB>jX-=RGqxqݎדKY#0ϡ gR-ĵRs<6URs :>Ps|}^?tN͟2M`D r?SKvZZJjiv_-re@ZnfeDIM2ZlSj9K-jPKhK{j\Z".1wE-=7kQTS%yH-{=r`6rdvY쯩c OFx88Sj9sM-/cZ.>W˝6j;N-6n'.ZSQjyhowLe՚-QٍԚc<ԚwZ]VkT<e}Zʷ7vFs*쟮֢+Z|Zjj-}jֺj:ZZQkVZ.kٓMzE=UkPUWrjW]T6i־W:8׿~)W]]1zt:-!O7mc_g#Ξg6u6aO3x4 mRk r> a~kOXWkExa{ŷW!.J0,|1|%DvnFĢz7z̕a|TZwBgbjtli[k݌i"28Ӥ'a2a"*[Z=,c(Ȩ *o`e%t`\s%)t/Q诶z~oI~l-˿zyOT ^ճC?ϪeƆ5s_wUjZw#/]QP /rcچw!c}Z{y ug9Orh1sȇvrW{&1׌N͹:>Sm2LO@΍'gQ>22vyov=͠!|&Ǔ#= c%.gl|^"8;@|+ d| Ǔ(tDg1]Cas1 7#(=>$x/O`o& cF6 %S'RX_*Iþ68xL\qQP~Q[++eꬶ]ԖmrN1cC9ՖkV[j y_&vQJ Ji}jiu|}z j}e쩶>gcW?_w7tzecn#܀6Fm$rI?u<~ T۬jYDme.., _{Sj[Qm mlCԶn ukA]{!b7oaFlmAO3W~VLj^ ߖK뗪m ]K,j?Am< Op8;6"MmZm"&S|18Wb~0v|5[fӋ\LEwEV{=3N=?<3 GWrl[[mbt^<Cs7qPr|흑P>'>ȱc8&+!2Ws/.0KCas~#wsغV;kOI77`uk|\|{v  f@5 E7ԶHja f'oǰh9G`#qw;{`ߟ -s_m/u /:&Ϣo-<'3]{ wN]p ]~I qPA1WA|퇯{%~Mčm~]5j/sػlOamD,flވ-aԩMesUp.:jFb!]WSSWUؽح` y5Wkn SS#cFNy`$M;w R ԊѬ =Y#wc1`rMK=ǙԜIɜ`s*wm1LݙJjF.9>ۯAN3cn:5x~ӹ9O~N>O>D<&W?;pxqsfi`nB7Bveʊ"y[[J+,ȵԕK}'}CO^}=z̛=AOvwoez[L[f4=g˛=@zlC7  a V}zӃuz¿s?+F]7@AIW`֯TzJQ|S-s 4J-O] Q˻jy/f9neH,Fv`N]aw0N|sO]p7{v~A<>\^-^~6߭3Plc|0݂]3-@UïfX 'fD]2~'  gcu.Bv\9B 83q`g߯.fr!bp<^j}U-rb?]C6p|b$Nunt-alrԍn!"؞؆ #qYX+c7UK( ǧW_;sc~o+XppF|B}p1Ž`PlowxQEv޾=d\'7:F;0oYlnκ5K\vSW"G89$G-Cɇ @oto/6gL>]?֊,a9>^KL-ԁ|ɯmx}z};#HmV=7CxlJΐ>??l[y0aZVQW%d͡.˨ym>qA ,Jj9 |9&Ɓ#nf4)mafmTh?3 ~{2ߓoF=<ȧ|##Wϸ]j]k uh,>ׅx:}3-C}$FRsBԙiCf_+UrSGQG57,ZQwF5W͗kAj0BW6E͗]ۥo|Ca|0}9{Yͱ9ԜPר9)Rs^5ǜTj>#ZAݏԼúy5o Ȥ4اk#ռ}Q_mWj_<>@ðE58j\ Qs8Qb'5WӮ|jrUmvP!?_MQj 1)hBwFM7w۩w5]MT^PSj=I]MUo`M5~ƴjMԘR^O[V jLj|P@@yxS#2ƨRj>U]/xxoƨ8'iOΟR='1{kȝOl9 /y^%ʙsJdMhF-.–V~Q{|ЃO75^ib~\DeQcP_~wo`U 5>"ww~㌣g6A'~D5ut3zHh9=8DW$ѥJ4Kk%bAgy$izLe\rnN1ܘhrcD+SNnɍ[Ɲ}r#ȍr#*7sȍGIr q#WEncnw6x43[ȍJtarY%-YZV\+rJ}"ѝH0]n" F] SFp]yrJܬTn.,˭%rCE};E,Kw{/˽srqw0vJF<؇`*^$qjJ܊ķF-.q}* nIBOT^}S%]WI8zI/l[$ai$*$!?/%N $nw'EK%%iIK;$}/]%~_HTexIxDU=%()˝|WRzV䧓$y!.HJ=Hjs&)+J~ITRV}#$5yݘ.i$3$}$yطWR"Jj\"l$D.I/j/,IOKb5cIZDl g$Ih]G쑄R I3B7aoGm(R+.q_;K|r_8z@ ~bğuNh# yI¨tIXV%KBP1Rw qTqIhsP$4I0$LBvOrait$d% & H6DI$6%HbI8-Y$a/_6Ap;1|( fbn$V'#KbX$$ +Jbr0IܖGsJRu#B^ K%1*7$!<Jӛ{J|&=%iUI0lߩ-$vrwM{/1 <J&Wc|CνRAŦowI$d-񆯒vJ'lȗ]_$9$mOMHDCR[I U%C{/6I+IfIE^TC.@nI*LTfJ?#KbVĦ9H3$4BԖy&ILR~ޒ@RHr<󍤜%m}w)iZ騤-iP'JZlRܠ6,rKtya1w]?I_?V  %b%es1I^3`| )Km,OI^1OR2ةw$kI+ý$3I/Iňum)߸og\$ ;%yIX!$iSSz$*׋I轮;'J*:ؼ6'?|/O'O', @yw!飆+"O^naT'?'$yAj6Iw̖?{^y= IH9<,:]ҿ~IzI#"'J5贛7⟱w 9$]I}LFHrkATެ[un7=$[8=JyX.-)iu[FK/ry8"w8ķ+Jg%)p+J/~ؠ,x<(1KK̺Hyȯ7){+R-%aN%b$Į"){kJAFےZ>}QI;#)OJr{j#CjG$+!I=%I }KoAM*sZ;KrjtdA_iׇﲸk$d*?2&Dbi-|k#$&`<.%>}x}*^pČ%13"j7).I@[[H"˓"Wxh$13]~2|6u {rR=7qr|vS};-bKȱ{s؏r<>In+Ǧ֖c^)"G?D9-Lj QHTP Gr-CƯrx?9lSOLqˁme wuS"$rK{DpȾ"(Ւ `r0b90"YϹ/%.Uˁ_r`9o#ʁ_dÏX5&ꮕHw/;r?Wv*{[ wdי$Z"Zbq)nOEuq'ΥęG-^gI: +þHȗEr5푐6$L+ M+G5b'H 3TG%Hsn)AHP+7AbK]jI&%pwK^$~|wFۉؖ[bIl5ʊF]~^by]{5tXb/ćb^UL_1.ƧgT!"b|YLzFYn1Ímb$01l-M0rtK1(Ƣ3?*@ v.;^'gUgBZ)>ħaiC|fV-3TEv:扡&1 êbcUbKb7}+3_b~M,͆eXXLGXkXo MbUɓVJX>nk,SŲXn,ʅb@,Ƌ%*1]$żfC 1b]m~A 촉xFyP̭= Gb=ꘘ31=*b:KLst/tXVLSĔm*1_, mTL>%4cAU2c!1V_.X^\cb̲Pe3gocdF1ST1%+ļ_1ѣb)WR,Udo,<|&WT[ۊqKĸk-cbxL qEpԓ3gGeby]U|ROiU'!>Qdg}#;kWd b(F LJ[16/54Kb^Y,%XAŚY#KZX`*[Ome'&[b}X?[HUgزLkbmUZLkֿZb03YO;ub{Y|߹&V)Kpd] .߇cgqt&ı8bcO%8}9(K**vCMđ8Lı:Xwđ:z;JpT; 's{Jp 8_ΦH>O{H_Dߖco!qD7ZBZKȅixUQE<,MI|wb-%zt-,A$rk$hU =I:Ε%x$̕\%A~$h_˹#Ԩz%;I~"% ,ۛⷷBUElibGSފr{1Y>1N%BsoeGcvϢS);S˶e[Qurl)I6/ M1ʆlQY?>[_ֆgȚU5èvTkY}aCV-gee)ZYq~RV.exwAuxO+Y~,:H?&3eqdƒhYV,V,˪eeɲ\4),=QFm+Kt],Y:Kei ,@Y#Kl% ɒЗdI)Y2[t.K%şe񰑲HYd)5EuG—0,N daHfYD. GGeQ9,Q59#2ݑ'BnY\@&/_zKfNz#3 e&}jdڒOfōٓge2{&:Y! TY=eQY\.O?ek,޿,[o'L& Ekeх(Y/ E?ˢPYRQU"EȢd/Y6]% keaf`GYho u.ʒ^e1Y,tב eq,A&הeFFYrB7_%cdɊt}kY2\ ewKdY ,W_玒eD.laA,oT,˿)'|=&ޓOwJݯx~C ŻTKH_z$m~QDY, M?-˓Oīxx-#Mex/= [Áb"OV ߙCVh"+o£ZVVX;kRdEa_YwPų]"ޗ^Fo?mSH"ūx8/^MNJW,7y,3S?Yzxu"MȄ^y#_Y/yf|g75W|W !^]-,^E]Ux,^ח< }q<,T+^7wv} zY/FVɊ~EYiSV>("sjeqRZt 5e-ueDY;CRd}YlG^6^6z MG'dX?zٲ2P$}ekXzl+EM(܏e۷K پnlZɎӠ_$>wIACe[b0wfO16{wS[b:W^̽^K28^,U;b]{T)=֮vM۷w =+~~_}$~W3&|M <Λ`fQ9*~C|u ķ]E8#>)o~.k*(~}ߜ(k7S|_y_״5x(Vb{HlH5i-j1w@F}YVZ`Zn &<}=_jbFr=bؽ;= 8  K$a%~t+T$ASR%(r}"I-Eˉ+!r6//I3k$u 7XfggR3q $]ĵ- =~S$D'xf]BexSٺJ\y"{ey=H"se}˖ʾ]oߨzF;-8@X9-WV.[<./ʡM䐹X.B5оrSDh%Q$*DM^!Qɡ[Pr[9x球^ rT9XhN,//dh}V;'OdUA[Wy(c,s}˾U$tܗM"CKADn(cz]eew\;-I6+{{af{D~I"ȍ$@WkyUM%e_1_S#kn7~Cr9-U&&Ցkȁo5m4C9ȡYP\Ej.QuD=k&}Y,GO#r$9o#/{ˑ]5rv{9#G-#ˑQAr$CN'G cU˱[_C9Q τ9X9Q('Ndxq9yKN79 3ӹEN}&>ɩԏ!rjq9uAN\+';lrmY9YI{c_rʱ9}ChrM p@z&W+)doU%ٵK"J^< ᯚIxOVBH3LBƯGR8gG/okoԮx&Ip^aw 0]N%h& :[F6潟m{O.$v82|G☺KkMp<GJO zFB>%7IZGBՔe%tZ \LBw%4 S_ kQ\Ki{#kJzG2Irު-$P 9/6KhZ(!J%!kHp PB*wjo }PB$w ܼ1Lggdy+!Ih;,KWf-5OH?O$tn% =PT PB7א^[M냄['OKb}},(aφJxGb%)qf,)&qN.Έ*Z^\#Ίgq/*n_Dj&cI8ٕzMv5:^ ^^ٽKv?"{r=3ʞɲQ [wگ\{^"7;u0ӒTt,+\yrpr7XyKT5nD;#KÃarx 9ܫC;pr*9l"CHԷQQ3sC YPhq9<'7!w\}J 9=W{N98m[PrY}9d+QY$jJ?j1 }'pQr8(W/&GwcgؾrU<ˆ`"((HAPĄJQ1b@%%H **t$*Q3 }ܭ9;==>]{ ۼsنs;66:ɱ}Nlly=Qmm)ef[]<ٶUlle>m]޽m5fۮdٶYlJqACvmg{ma?`Ƴ|e_c dOmg{ٞ_/G)cO[R'GپIl_#|U`dd3qMv$ͬѷ\i:v#~";~Rh`Dž`_me_;`}ɾ}}b¾~d #>-d~f'qG;aNE&e?1ݶ;6}W}_}þS`__ f`ʙ/z/ O~WW Wqgٗ*W%ٗKmWGKd f5b]bN^>fgGcv;d+áIh_`ءi^%vd)/X]%ɎyS NgGCMvX;Z%pvvhvVˎgG]ّ(v`/v`cvvȬfف&v0Uf쀆.Ԍ?kMMPlm2a-GL~xaBphwqسSZBt=/PP8A/cp:N:v  1$ :!aڹR-C}w$ W!ZK=V۫rJ\q8e6qu%c>? 4W\y~QܶƂB8ۃa m:"`In7WR-mTȀ6YR u;}~-_A[a "Ě_BBf+AH#D4CR}|[{3Y|_6Ct38%7@Zb`k_=l~=tp&쩌.%XX ҂uga[a$ PݻW6![tDž[x9xs^`+Nځ* ,AJ0hu3d"K>ށPŔ) L,~{0(Qp Z-I >uq&X7%hF9/2%As,7Y:8-yvdN01a~iMnO8:\hoo X-ܶvJNCRqKWm2rŧћ b!@@y7>Ahavi ^J(I5{b#xT/.ޒ{';9N&v4IsmHӄLv;?s2CZ9$ @r[oBϭPp3ȷB% \ / BeBпHp3%@&dD*٭m+jx2%`!S ohJسw Jzx{w"xe \? <ޗ{P;8·V`l6`!aF>k!±P8,85E=JYv8w4pKB 3`UR0yaf#M p.i\V YU?t@*ַgAx!` E`x8-`oa#BT@i3 GyD!, 33a~"@ϻK[&[>0ʩmS \+YYpq+8Gӧe; :RAe({C3MgVq04]`¤/e: xi'| ]IM7!Il6fNa4y kOek PM%ՠ~TgB=X{Tf\fZ>1X4 ._w.E[ /N%f`QnّϰtւGUUaegYTzgR0%LG+l= 7ɑ0I' 39otSf4){ U}q.WAf׫̮_)53?j< uƭmb<&v3-9rZɗdv-eBU̗җUhoΜryĬ.8,>p|y]qe$+&k8cLJ%I]]aN ^n|Ȭ?]ҙg ÜoZL4J?3߀Y{fG)jj?i =p^\T' V(gFWG=?~hT q/:/6C V~,Ǹ*7CCJ'0w31f^>|2+1Fa,#zSyƇ73caϒv|d{K:J_ME=^z :aM9DõؒWUX(|ERXo˨M~A,zVx+ "1p7ڈ`2j}b{;ڋ\-IOhodh1yӾdޗ d*3?J{U$yt <9X[V%L7:CF#+p*h#oɹҜ ,vc MLǶC^M6yݛI>.w9:IZH^ ;yɭ.'o??FĀ.3ǜ蜖1t\:dJ'gЩ䖡I'[\rТ3-N,[B ԕitV{:E'̡#CS:!KF\lT~rFN Nޒ.5v}[h7WvXΣwhgd7i"ڒHP_6!gwi<^#wsH/\C_~-GLiaI#iZʐfN{S@<`SqEƤ)BA9]N[݈cVITbfa LAh#DsbW%LZդ†g;GHg$ɣKZބm ں rebSH{E޼t3Ho&wRd{Ƞe%72ٸLV=2 Ed2ŋzA&dr:m[NF86 IOliZ⭟8J05o%MW\Hs5h91:1aĮbmGltnG:tBH~#9ޜF=<^%MH"u3H֝4ty_>mId`t l>0UݒtH7HtzMIgv~tހ4ndL2xId@d\$+Hg1iwu.SEz[Ht?ݦfd4%ddYKKVz 2ȳ#_I499dQHYt ~|2/~}p 2 |,-pZ>LR*a̾G/gp)>ƱN;.Ov O-!kp8Œ` oUkD?wƮKmxO| v»ل-~:-˿]m8 6*&XkN@ѹuh@yfXo3~aex7,ebٵ&9 `s'^5ī;=v>ZcE>)XbŢqM,~ۏa,8Ea;q9kgHE _'1+b~]Kcf^}K| ,݌~yXp hWcQ ?{7c)%6X ̱p=̫13<0Lm`Z L홂J1Cq.fLjq?"◰ z.`a[,"-7ˋp|abVJ^%~GcS0= /`p| |rK>p,y#q#=qf2Ӄ/Y80V=qFb*ʼn%: l__@nД8KSO#!$ɟD؏$jKy$Ms_e{io4$Lb{iVDI$HDuH#ӬWh,"[Db9$ DY}K3x}댫=DIDKB.4ub .+i+HgrIr%ɶh;iރ4!.&Q5{['ؼZ#$fZ}ݤkh%-MTohZI_ZWڏi ?ef5^ci$;[7?FY}ҎZ$ڰ$JՑZvL''ᤡ(@iHb7a9O[^O53'{qZ4v=r2Y+&<YF"Y&߲dA,Ce8?@1{+9wM#S|&\2:td'9"r(@Oӑm2'#,$3v!S6$Bo]i]>BB[b 6$;Eßh|y>3?G,pLoq!|~_fD;cRG4ػ8ֻ_58J qpi|Rwh}pb pԜ'y|pC?ϥ3'>jUv~ߍJ)? ~Kw=o6,<7&gI8uN9.J|i/ppTWݍcUq(ۊEek|xoԣO>뺩I{'4+%vW>/77^^OKj|wF}:c!O/|9'C /q_>Á B-wvb.qxF.mxo/lS/v[EX|V VzaBĶX7kNjk6#6pri6:;[Yuea>%daYΐc>lS[yW8`{$l;mǎ,l9+clS; ;E7Wr|p5^GU;WW`ۗ=x_,{?/kl!h`Ol[ͪ"ؚC<܍ vt:`k,/`&Wl*gaЄ]Na{~"vuV+<3lLJOA}#\߆h"G =,u_`'vvǃXQ9`uM^E>:bp">X<]`GkJ!n&p>QANM8r p@1n7pt(+ovW5Z@6Çصb%6J`]ָM;&X҇|![o`x_Q\-Ez,Olƈcء[cC,KkGRlbZXO%s' ͗RL[`~{ oIի*?`O]Gx,ݘ2PIߧbUch B5}X`Z7r[`ՅtnYxg*x=^?5y%a=EbdiZkwߏ ,N~ǒwVO a>cc&luWݟ[eaÒ?qafe|xN'B+%%y30U3d~3l.χ''O?z+W(w\Cl#dQQ\+~V3bj0 A׿pFANr<7Nwa6UY\u!FӹG6冧fpqE7lZ͛z$2啜4ݪ~cd̼iʬXE o{&*I-aJ`\0!7"?}i< tb&`ҫ2crOaشN.#:,dDe^3erq x,(|sLSQ' 43 ta>b6bՙܕLsIn6Ƅ0 9*'`<+=څK)BQyoP r]D(E鏡w\W*Vu,{ʃAq(y>_\2{য>\c͡E,=<~%3X DG!mH,`업9[d>xsBH߷ 2+T;%VpJg0܆Q=pX >KL  88 -o=7aKw XpeaiS "uHQp[ e  4|Nn{`.h ^-b0w)O u1oSAk8||>CxIH>r!|x3.l̟5d 6}r1$X¡3O_+> C?6[Q#))DBpWnyݠ&8xM[Aa;\KNyB׭`|p(x݁L9[njsH(' > 8sE"B0ӳt!}r L<6AX?m}tx(sNi6 `MNd~7~Y8{ GL0{a1)0˂]s6{Q>0ER0_ Ns6,H|KSa,g@e$,?+ f\r9;jU^d|m`޼ X ̗`Δ0y"li8jx^UOGvr>HW Aa`\'̉R3igp8a | ڏUQ8o+ +ؚ(oC6aH& .6oAz8,u^4Ls..*0b+$Vf;l9p{8Dŷ`S`۬pzn>ɰw/u7b 88j%M @I;hEkGb H,C`V-`f:]`t=l҆.6gܴ;-=Kp"nఓ%Kr< vXBA$v31q@X'I}  Nu70l45}c2IކyA-gwB2es5ٺ/΋˱I[ #>aϻ\ q>B0P˂8>!k s6\ t~@nx=3BZb XG ͒ d$"#?AtmYS !i 3Zea0Cn\6ŚE|92 "'xz;wpa>r 턀"t7{ ;!v%N^ ދGc\υikx6#Ƿpi_ gx.c a3D-x d7 3o+b Hq.M E#!R& !)vO=ޢ]^xҤax S-A$Ta}piW(kh=o`9 edc jG<\-`; w2p* >)W_?ʃrxCp81pXFdi`pP7kFF EXb |>ڬӠ=k^y1{Så`Z @g藾=ue8v.=7)ƃߡS{*\ . zijK 48y^\So!Z8,gN+.žX>8x ˢ`.pt8:r 0|*'q3Gyj /p0nW00-)TKkķR%'p`:0?烣 Wo[~03pg)/w䁞X$kÌk3oRɀAQtmljA]Syu+/aT?W޴F+VUFhG7E2?zfעX{܅?j&(iS]trW‡\6gܵF7k~>nJURz=7{7JrԲK۸yan \wAn@jŐ܋\o4.ZnVn袲 9m(zM;J[B/3Qzb.:cȸ;,ٟ8}8/Aӯ8{գA#*?GR8 mQw"^21fF6b:Feb0fG9a֑}Xv#~ci e԰fbq,.B8= it:YcwB lɵڋbσXχ2XM6cmF6JĚS-8Zt@[lVMJjyqBX+z9fl2ͷXa BO0/Wwb ,ux3^k&&R,ŎJ]ݯrh2{s-&ˑC[H6OSJHd*_JM"GiƳ;$hOWIdOTMi4fukI֔<-SѪ=ImENϢ Ji#e㿤\V=@_kH0-E:Gm%Lfd2jG;?޴+Ӯx9G{^ +\?6,֑իdgEV$i~Y";y$Hާ!t0&iQ::Y\qgt/uÙEtJ:I9]C rc|{rB]k$q1u.ZMۦa\BwȓϚ)!ރ;O!ByT$(y馑=y.$S{yVy<81~:c2-V' tzlr3$WvZ޽$ ):gxJg8KϤSRtV |E'ӑwy<ϠRl6U 9="'%1r4Kdӟ=wЎFmOl6mPO[n#cO]i2a#ҟa@zO`r2\’=WQ"M)iz%2GK{ČIGg i}EOHsY<ER ^LB{0ivjgy'yAS8_=~?C ieɒֱ :9%oV;ID:g<"SHXi[IZV]%Vv!zGvQ#MCzNH( A*<$#Đ )m$so'j{=., w[~-r5K&3yc?NzB sgK}PNHUҌM&N/b;O@'s&t3%-$ҋ!3H!#Ķ-"-؍={qHgQE:S֔"mÅDz^W͋ɠm <=Gd Hw*餽&C ^FF.dh nj Ji2$%))MKhZZ%m2DH))٨B#RJ ti!ZwHIaZZD"oAkZۿ E(,%V#RG*'/>RwoM_HƘԥ\iޟ[;JcIʌT&VZl&F-!UlR $H->M yi9@̟ꪣ<HuKRN|7HmB؛r-TEƤChc Rդwo,eR{DʪhmXEJ<'In%uے5Z)GHBR+HzMVOk;H>q>"a{Z7}OInIkM#yf/ɝ8G2IIohE^-SEiY$k[H*8$r~A"B$z% so26ې4&]IV64$|/Ռcw,|{Gsuľ+x?~]=q',>aUycORkXO]qT8;Hd 8g?_.;pp^fbߧq|y{,{ϛ;X jX- +c85xx4KJEt,؈EX4g+aw]?0j{'y.ЅVX,c~Ƽ/SH)8aQt?<%e̹Յ1oV^b=X؇ 4y'a~l ;^=Ç0)R]0YaQLj3¤sL4ĤgL޿19Vwk4LW e-_lpS*^})N"~d1S0o볦l^ZWt/czfǬ٘#91+Z3 1#XSu6b:r<1*LzI=/0Qs'&5ɋ1~c$^lxa#'L\ M+L(]QL8yg9I:<}04L”ӊ\U0}SVts?W%C0=x 03x"(顮>,fXoNcv~̮Sn椴bṟUyX,uyXێy01g~[2yg`|=KX?1{=f<~L;7bMK["J:L*MW!w!v:r!WkWS~[^άXd%2^UñVwac*]UQ=<z~ɋik 6!ºhEDDKcY`br-֋\S:فw7beU3rygW0 9 2c&{%^men6}_:۱2 [|d`֦eb6lнMjql ŶD(NR߃WcǂIEe>vxM|-{e {w-<̰-;]w{χ{3>Y/'dusG<Q<:Ӥn|Qt_6۬q^ ~ ]:i4A5i"_񔦙"m$VMidlK玒`9* '$4&E"$zʍD?ǐXnpUVN"Ghz 6%Q4g%ID9H<N:LcHh܍nPXM=gf[~rH۟;ΦVa"O3~.'Q=7ь#$CR94/Ro[ilZt!͋ŧhyWZ:VKssHn5huJ$}JIieI" M4iUp>}@ }iCvڨG*Ju1&z4YrXAOI5b"YM&͟H#\4f~,h .ٌOVᐭ/ǡH/2#kpXoLġpdC5aS;ǡ8YOzp=-š8bGΟơ{~cA?q=}|l}7pX> wMp _fk"Ɨk$U}9/ʼn% ?ϑ6I|I|xV¡7~ Fұϻk;=mѳ]iO,CJf+RtgKm=vkml~eLl:<Ӱn}#6[Y+!/kBZNjy ol#qoh୮*wb,'|w•zrg6OK%u^kc*u6ۅxwp;6}hŎ?@2[i{Ofl6ͧqlބy%/==il<4k?6oa?Ǻ-l<;JcGrv>Vl 4n ۲#İ-[x>t86cVcU8aX+OF"Wl#,c X V cVa .D!` [NbÒ lڰE<bՏ'XugV/IJm[l"u=Vp K1v` cO-",=ȵĒ /iۈwafVbC>MĺCX#;-RŲ'?L5Iߝ*Ij7h)=寚~Yu+v\ Jwc ,0'#9xb*rJb}©kl];acpyzb4[px.vcޟ~ :3e>:z{ת`I؝鄏~cw|bbl_[U_5ƚ9X]7=x=܋/X7ƪMX# CA?6 +u06V}; xs:ދoUs;VoH?ƽX}MElĪ/Hϱ=8:p$Xsec^tNj8R>)Rw XG^/.1mCC`5F*#ξƼwx>KİL/ IxA3,K5bች[y}x{UFrL&/0v¬CgS1߿}#, +u jul2߿=d'cG->p[.0G {q_+k1>M^>lYvY@nV66NصXlÖ?/b[>❋,6hlv;őy~oJxn^wJxvz5a̦.| x^*[s?cTOr"^=q#.&uY؀RqZJF#'}%;pwf W(zW"g'o븹E\\ܭbgpx^oōf=îfHŅhH!/&McooanJgkr*-7ݿ,o fmeY?˙y[27f0EyLeo ӊvXMgLybSNYLLk LkTgNfm`J\$̕ !Zϒ1zaaj:B{8ϨPzs $ZΌIdjL*sjX\#|f\nf0">a=yzR:3By) F=sO&z+S˹\Mɬǹn߹ Q ?T.DĕU|ݨ u,,Ð9 z0M@SX4s7n -Nɡ=4ۿn~qČ˟o[aX6zmyh`&uHK`aR^}bnZK0_3۫_EL&8C=qq(y[Õ Z45BQ4[OxAà,a^c6#`Ҟ u\g>b,I^a_|#c7Gaԥ.+y^މMX>1`+^-ZЊv?սV;> T>%q;@ nwAE(3:t}B~w"܇yuWEC+M gA-Z\j \@k΂[Gh=f&ڕ o5HbDd]|4f?sKdtxߔQg3m0Ss[9S'TT3T1EǙ*nKwI[VSto8LA1(eKr`|v@PHj{ߕ-.G-: J%V)BlH: @jdZ)!K ֤CkATs38zQfp" N^aw?te^-  Ak!4r)wGC63A0<jM0Wv`]= |/8,m%3{z%~ N a&s:DT<+p:u.5~_o;BA[} D!G& @U\ON:xUñ@ #GaSd/8˖v\_y]$å/N0Xk"H9[ A bǾ&6$)_eʾ1-[GK̦IaL zig}83 F/=F~&|1qn\,9vt `,Q˙λ̉qYx1ߤ2>G'1xd=420M_Fc8;T5ct=}o?sWvLқ͌mf Ν|lqHͪ5ܥ{ Ur5ܓ|yKB\6 ՞\uqo(qd^3WWU~X4ksTpo?`O~UVbOm)HmX!Y<' k :AbP?@` PGS,*VqtI^C)\N"qW'ڠڙȮCҕe:DBTCŹFJ+_NEPgIp8}Mξ4ghN9S6zĽ]픞m:@k9 ըdm㸂y}5KkMPs7-&!#<-R W=ֿBH,[̄i42цL)9Ioa̓B`c?&j1&DŽe 00mƴ)F0CČ]Rf]4_c(E0̇yO3=L/=|; 3 Ga~HYa=^Vm 2> S@i ,yb ~&϶W f nXK.Ê)B2_^JgR?b {QO ,'{i~'誌–y`v^8nG5x|sr/s;4 >p\.xo.˚!8bv 3"k`~8. E޹vԇ} iۂyp6]1`+ .ʰ3h.,Zp|) NCcpzU82>,y5uhY߰k6:.nm`l?X>Q 5>qA {o y|˼~|g~\ށtm"`pvipp8e6؝`YhlV߀ RWAdXgԺO/a$ ŠqB%fq%Hma0 aFzY% `Id¦][LAS(܇9J 6Wg/A3,*1̷L iR aV&1Ú`Zȟ3LSn:oqi0)a)XãM=(HYkma;_#n܊F8n*z9 ^0 p Hk&fs'z\Ǩژ0^}vvbx81_Cw'|4aဌ$?f_OWp(P + Ƒk# 0V?n'/BN]w?Zc'>^r[ܐ4s k k}joX%%5ضh>>4¾yjMc3gL.2HL „c^w]>p/ul^x 7m\yh.]Hŷa\m ~ 7bbnǚK55y5+׎kzp r'g1t9xüP"Ӊ=\anF0M!+Z4_|ܲPow&f]Ƥ`=cjyzI>̄I{1^;_龳O23?7`A ݎD' 7LpfZO0C߅v!/2_̮O< WWH@ ]siз{-tyBG/hcZnbؿLp7,d]hװU]Bn_HHp?e<_ɨC OlM 0{C#0P 0ڎRCj97r  9x*amхgd ? ~>|#$Ave[N6YN9#Nd㰓gM\[vbyt?~m3JNڳ|,r:0S #Wxb_h4'kud3|cOkrƓ.Ë3\;Ӆg\^i0$FpC/ 3Зi O:A.G]md$<ą޳Wa=:>o)xCIhOV 3A1sk=q[:Ǡv{nی\ Ǽ^U* a q?z! m耥+w "}AG|U Ǎ!ćԛyD܀xѝ#CX T;—gAPW7@@4H]K{!fI܃O]/lX `-) !Wr!>-9>=(/솸!. Rm< jAR=A]9.OՐ2OC$o yjo!.կ wC6CL\0RGBdHo}Y!rVxJsgq Qz!B^u= q/ڛ! D@ | !0mBfKua\ aS>E)Rd0&=GHaʕ 36 STt17N0RO#療L+;P SDf. 2Rgk9A؃9_-aҜ'G#9&99r9$dt2ƨ4$ts[̜=vqWgBfhbB`kk +00EW߄E9㳧 C&0$ Rc2622y_™T*ysS>3LѱKL|[i|fc߬c:Gn3BL_v3:{ £yՙ6y ^_M tDׂds-,a) k60/_A/to{6/C_ >[d?0L<+[ \s~^A99$@&Ѕo!J"BoTqcpy[HINpeF+dQO /2C< Ft\Wd-Ձ2$ @Φxȉ7[rBvdB^^>耼|>ȳ3 Iȷx!;4wBf2SּPWZ1Hٛ )} 0m8궀#^A!"nfK/S 1@\>z"/B,Wܑƅq໶|^kS+Sϗb=~ñEYp6F؛񄭸LPБ.@iڞu|.,+2avJso=OVĐym62`% w=Y'_wY$#19Xč/w}9g} "A;ڛSw'+n!r78-2q?:mS_9s_=JCG!aWf^E8_.#h`—]@*N:Z1N8Njc2Y氺U74'h~vJqվtW ꨈ=(^_W3ycg ig; 5 [8&ϕ/)_r%E~pwcw߁ѱ;\?ܠoܠDn+gnYCZyi܈ՃܨnNf +Q7."E,ZPO'ߎ\'p|^gHL@Qc;|ĕ ͸zn8 G xV"QeG/< sc0I[0,-CcJw ȓY1fJ a3 ;>#10WatM oXB1vQ>[ ̪ '&/`vL:Nb-ٱ0[<3'uLS`IMT`Jb\0o5h#XKǵ"_`]2ءa_/>nW ^Rgag=-{l`~O8w)z?ܾ DZm3Ѿ~S~ y />s/¿;c'FL]Je\bf}fQ+tI\eY)Y)YzU%F؉ِ\lY)Ye`־Ǭs8Mf1rlW˨ |fǶ2V ؼ3SƨQ191Ksd;3EUycrc@1VOaK7(i1Pkc5F/j3;Ld]o-Le1ZkGo2#Ӌ1F."hc8F2W꘭̺̪ǟe!̂ /Lsp8S(m{<7+-/a $yaB)LQ&`:!Cw}T7 & @pEu<8?};vu Jq,*cogW&{v(/~<ه?}02 ǎ/%a|r |Y ۦbpPfkCkq6QҶ8?N I"+p9ic|a]q]8z*~|?@}7~>_ŇK7e5- wl=;WʥOo~?KxJc<&|3) tnm'}SD8qp!!/+ ׈@Mol]&|𿡅oG5W&|~DH 1khr]NT  <ģz:|4 wQqaoL?EEo zV;+i#"ßc?l? On#|[]<+~z?=o߬ځ{ ~as?.mq.oB&7v?re^j8x 8@Eǣ&ЁC&WPJ0;؂}}$i!Y]7`\>>b>6]`{,+ <C_elyoIm8q1NO8o>;÷iN/,jŏCpս/07]ۛpE~CtQ"bE=uȂCddY}̗(M%*KȦ=Dl&ٶ*nH} $FV ~l^*D6FMQmO6!/r(H?6_ՈR5Yy,J3dY*A;RM6Lt&ɆRs,/!K'\yNĽw7d_ <@9W1hBqܙ7/ݸE'lĮqf>(%zُcrY-@xp#42htg ~;+V ]g!ԏq6aZm\/M6CF) 4g35+^x *܄bP4գ"^u /-k9 M7åOn.3!JUp1nԶO'p㓟`CnاP:(L[;?IVεF`%p z w'_V}/e]6\֊bu>Zqy&XSb+C5U]>x P0ZM:mgSҀl4wMl {Ñ7q%%}\]{|rOOX1tk6 T,~yجd$-wԇ%x֫x/'շG.<&6v8 X_"׫ƙ~nRiMk=i\߱-7ٛx7)k kp '0i`>s6>LX J <z *( ky(Q?Vs..-Hk,TjEspɟd^(G.@C0=>t6ÓwtQ la|0m C;`zK1&W`f)o}0<2</51 .^okAS~@v$}: 5p' =kz5+ᥛp|K5# FJ _CIg-k'{ẍ́ZW^Sq׎CU]φ:aHK2g#J5PL6 E?`3 fB37a]y!z iT~<lĖ+?*[EP>8\4 _KW]?u~ .>k p42q(&|4'+#+qbZU A@=]xx8X[:p ٹE 5~Q Xpܵז(\arn[ϕ][7}L#ecMrXՕL/v1ulz?[lzu] R-b|,oėK[ײ CҰ/aSWo8 x7߷tȝ[pq>#Ry ~twqy= zȯgph Nđ8 6C/Ntه؋M8bE >5㈩8;ȝ&q^4oAOq܅}+.a_vo!ZC>6G40gC"ys |q@A +GSWet8>ЎWJ_S"Eu$:㜆}1XT6r \X9+RQqxJc,쪍T_biX~E4V\չҙS))}ߌa;&k :/lx6g(+`UŗԳMN275lɸbQI⚚YqߤpL8koP wpp{$h{ .`n^GB^\}%āGk@˳{1d"H^x# GLiw:AdI.T%29%l\ ApÓ-< Ě^g7Y@>1^sGnnk @u<z PDoTjhk^b^rPp]v@˨nhu84o }c^e -﯀poxı D$<l[ ?c+hsMPWOj΀Ǯ'x:o=.j<n wB5hUvB4w~g3x<? 1x3/ &݀2p3pzhv*^ą^)VeBÖ3P\o5@έ|]D\hh rtsS>z>ߡV}4]uK6/ݚ 7JÍ+#\Y¥v;f<ܫjx}k <~r:ML-p-( t+lR'@B>ؿ$0R1+e@Х? EB3pQJWᆻFp|>j~ {gD]qܺ] nkQǽ\*<N#'}. xFAТW &!Qmhn 7̇~ɻ Q+Ԉ*"uE]G6Ah?4k9qxJ:Us<׼OBԟ'Q<Q8Yv}珛a;8Kmg-w܃kD={}<Ēr𖢟>`k.@ƚXŇb\,/m;sE;DzWXl6-={ng;gf5_⽄%IXmӍ[1Xq],hv?zykހ=;T˲:SX!3˺x?}dմ,`ȈG@2^ro2 a釵ǕifƧʽ"8(:s>:E8'$ޟGK޺=I)m?;ތ6}}w}4RH!i?jK"qٓ>L8k~;9+zxM^%w/27K`d+ǯS51J65ׇ])lxd8 :nNXpb(k8y`Z#I9 A5#/C`p`8f͉߫^w;āf^۠aP#4: Ѽ N#|~6Cw3yPrI} _lkȟlO|}$~A\'\+ -?ݸfBh8k$U pӡ)=U{@%Knx e?,*õYJP2pi3S(}3eAkinchF[1Ƈv6 ~z+G7AIs0rpLioѮp]c8> gP>_mP*Y .Ro 7]j;5ʡw? x8cK?A:MaxּoKD P0l Sρ6WjFTo|a:S 1|e~kp*~ ~wTڟO;rNߧE+p2|x 6˄U`)`Kl[Da`!Xz/P`C_miElVa!lW)R`:lQM|;Z4`k"Zb`^̂.Ygo$ {a.jr|;M=9o `wqr,Rtcnғ+8y/ JӅ?\߻[tRe)03>f1|/&Fv #b6'33< ;pS~ n zn=\'#14᭫a|CkMRf%V|g) : _&ެ7J{5fž.1$ n|yvt|z>= vKփڰM v~>GW-rx>9 fi9}7Lu80v^X?|.Pov~߆y[8^'{M}6e7IQ8*x L88ǁCppNFy:*W{Ww+v v/aOS|_`{4ln [7ŽRyOM`c,Ά5*n Y[X>|ܳ>w>K.'.cxnSfI`|?1Wfgal6 6gZ0blږ pc!#FBzϯ vݬCc3y# \#\l`~80v3j61aL$T3kގZ`ҔL&Zj`BQDxwg:`azZ Rhd4Cx{-&WIxs#0I)ffŒZ;w:+`Z=H΁w`vjfL( J|y&WxN>oW˜~sFpY0L8 D°04;g,^gCdI +ڂ 0{&9/Q`zE .m7~)i(n E5K1 rC2!m6Ae <"YAR7P; ݈%A4W;opy \~\^t _h#nx] #|pځ\ D]U A?@NrsQ{A\Us@PuȢaī4$UnS%I{/US+wϚ K,4OAD4h} [@űyw?(o oQ௕ X5 v&Yg}_\MlQ/\x ;$ !' '?> Z==\ 'C+dk/#kI$tWhYn3C&Aͣ5e?\à900 ;C&`ȕ0Yj aJ7vcW¸OmSM`UL]` LIs`*{tv>&9II`5YS]&`ޘQ L1:S4a:_!L ZOôs0o 2`L?aH)0FO|`t*amߥ0 g@(y vBg~;6ME`У0ح@:9n?ߞe;xՑ /n:*n£-*/@3x@y&CK- r䥠U^JRAx>DBᬋO;幀BQЫ :NO 4{F䂤> f;'>MLVZ*ҲXrzty>gr"9vQ9GfXl8ks΍sU{5kfQ~M| G ,ь[a\ϱ:;-$?x.Ut8zs@G]fFfTrf_7*r ъ-ܰl9 |EK\^kQύÍlV'r+.rz ܁ӬNvx6Z5}5ɞx=uZcWyI2l#eYbfUcs7w0{wq6o[{d([Za*َ.>ϵ3t"?b,S,96bXIKmv?6>ϾgcOQn?>+vgKn+䊝ӱ%V{'Nۊ}C^C-C~犽 cϏ؋i(ǭIv8U!8D eWHoe1pf+ a5oq8Y)Q8a qDGc8/>;g}_C7ᬣE8KFTNc|;1985^)V/U8w7sq;p=勣>Ƒqf|+ǡ'SpxS)8(=Y]G$v8|*;;-\ʰaK;po5 3KlTف@A);>|X C1*}kvE?(дĪõ;Ӡ΁pj|4h9MLW>ж[:.A$~xuje9z2`06|i_{e ?>0O&&x, &7x=0]fGD;zn,X;'Ix'frp^5&oz0"F? xukƛ0Ƈ!0,FGCaYC&KdS0ՎflX 3K`Ϊ*'ɋ?ɰ^*l\-5N\XyMgW8 Jac^߂^ u/᫪8ϫDp>owp;|3… ./?@=̜2KP"(~Q\Y|Y*Y,m`Vx2JEG%)7f,fsjujff"j~f%21k1V02+%J2׼gtct0{0Dfe&c05d1g:@Œٻ^̞)̞aF[eh1L`,;8w3L$z0S H`4(c@^㺊AČpdh~c`y 2A16FYoD pw 3l#`9}qU^ .e c`ӭM{%l?YA ,S tao NV1x6.rK 9sr_>,< elJ-nc N![#`>Cxz#3!d֩DtrN R"D4t\n s"IDdE" j=Dn"2aLG!yDdn" D,SC"%rNDYrHܾN$INdY8"'̍%s3ɼ}dl2obL8̙N|!2.fDY+gA# Sd<23P6s["Dܔ"#>n6 ?/e`|%4v?>x,-8?-߈_dZ< OtD~`U۹>oI_7#0;5S5{|x\kP|^q  s}ZxU!=/ާa[$|*`"޺c&|@q޷&kG-k*>Q|&_`"AR"q0V/_7k,jǫXGh [AAuqvq Vkc7\ IxV>o >;v uÁ}8|#N8Sǭۂ޾ɧnl%gEQ9|& 7ⴕq89I8]?N,tiqmi648{f\L wngxS~Q8P;a pԇV|7ߞƱ^"T_KqL~)NW]pEU _Upu hfIQW"E$Wٟ=D!+F֓U,Y7BTňjZE$V9SeOQ{OTB)ۀdi٨H6\G6}@6d{p ,DJ#K7?%K%Ȫ5p9tl~BTb5+g ˖yi2ӽ<!G>)]w྽!yO*&bz.YzĮ1-xgcO|澍nzٯ*)a!O u[@mIAgS +pGB>2+Z]r'V*{U֐Ol+1M*歝:9~2˫K%#ӗielچbGIcE8Yl~${ۇ}q /M3F}+hnTTꫳؼ 옷qT7}&6=8T3ٽH">F`Z; _ϱيx̯M9Ϻ?b6zVq? %}:_&eu&;iUZ,6"pe?c^mA`b%] pe7 i3GuOXV`X?_}ǪTkiLݪ{ *}W>HwXJIj hJ=!w֑lEj_ 4mAD=4.vvQNjwgzk_A=G6Qv>_AEiУo48!hhwYA?ṙ4&O|64|ą7hxb i{x'CO7ib0GwvE4"ފF ӈM<ȹ>4r,iQ4re)Fw҈|* R@uhX ⧡~4h >NN.7Ѐ4D~Էd ޣIkO1اMdoi\nR;GB9΢,սkI:륫ܠ(/0#rq?{[]m>C(-sa5f{Ksr t×ɸ<<ŴEohw[$-D+(R DƁHk-d2 B'GN 1(Z|FAVY( FgPܨ&J65CWQJzЌ+:PyJ޳DU5Z TSPsw61lzڇ^t/ިk" lP+95f:^F=' tA樧d1aPO%^Fѫ>ԻKC}ƨ/l%꫗G}# OQN?d+Qks/و磾EPMw. Š>tgQPK ԿG/&4 T@ ;F+14f h8~ F#TЈw&?Fo@hm4ZWu)4P4:dhq(hh"=Fzϡ[oш>Fs&ѐ48~*eZ_!F=.es ޢg'+x'j_jۡ*ctJTRٝEAGנ (ՊE e+PĭD̍C~cg/t6Arh!2 H#Om)F#$͘|#ļ2JdcM60)rLLW/NVfK*L p/8~x&BV% G2TI鞃o2px! ijQ)V*WCg J5jIqL.s%[ E_:A.4LIFyؼ&^iOhl(̡y a$-tΡjcZfuVp);CeLjhY)Х5󸴆{Һ޴o!QL/*vmߏߴP9 m iCNm ІhK5!'{t6tnKqH6mMhSNm*LyӦ3DbӦA2mjɢMfh,6A_̀6gf6l6}[E.,i mZHцhöߴA ֿU Z_3y+]iRZB,hk{=Lk3hm0O.Gk: Z';Z'Ek7کZgw}:HZVUDkṿhJ ⽳JV^;Li%t+iC+jiV}r&-}fJ?ž ͷw*ӻS,Ji"MI_D6z)F_b45-^2g]+u1z)^ 9~DcLm{Q-h&ⵘϹFWEL* 9'ҝ4ґ$G$GQ=OV{I>v9"X,bVct[G2>o0ujoE>fZg%zP@UQR"ںUBUŨj^TU~E=PTy+ryT9 a)D :툆H yfH|Dl"Yym[Dҫ][h`owS!J"UpQ6DPM];զ֨du)P}, 5C f<yB KT˙y>GCaPT3 _gWS %tK*CrlDձ<׋PeQDj#"~ĎF mJ(*/^>BeГcרa !Ts =DE=PRzt +3z8Cb1tSTP.Oh~Dٽ(Pڲ({%? FIDQN3'b:F;EkT((3¯(tB¿=yoV{ȯSA>* ȫ84~Clkst#c ]ق.݌.}Ggvm# t|q}ڌ,+M?2I"W#h'zq@KbaRGƲЖS{fqyR>V{ b[d_`@2h{6JOQyD6jwj cMnzT܁}Oų!zJjMHQ~j@W#j#7G+R#jؚG új&KXKn2S+hK{cnRCMjɁM-&NT݀I\9AFy˻Jj!ќ'{Ԯ뿢U򋞾_H i-nϡnԃsz>ϣ<{ٵQ4P/ 4 #n4B;Q%4f9kw~BGvu h.&K3ؿ47Hһ{iޓDA>T^H h!>i[yX1>9=Р?Q3e9Mo>Z 1iwgZ'JiyQb9mnͳyK*mj} vT]Oߝy}}J;%lh~ڙ#Kf]0vMDhW?)]_y]hW19I֞AiG_Vra1}I.Y=MʴEڐ6ܠ p=Z;Kkt AIJe(gJ+hYo'}2MKC^7h}fH>ϥ35mhQCsrhV,A4PżXljP穋gJ:)%g]}n=6Zf+Wں)[Nm"ctӳ.]ɚ.Nb|"*EG"+QdR^|=s;EMWGν{Ӥ]0i}AZ";LH ASh92D^$GS;t-I1t/>J&IWkL%(d7 U]9FJH&rwHYE#CZ$s|!'yAmb=9Hͺ , _8ʗuBv)V~䦽3 Uh 5~n?ßzc?{2cNx,d L֥maϖ"9LK.|2 cƆ3ߏI3Sb%$|PAehD R->F+$#^֝@#xf Ґ@˫iGvvHoE8| ڿAǑeV&:;-=/d; /sGea taF*>MwϑkwVEh)cԑ!)CG7"ߑos7\7? Aנ5(h &(i_BcQ\Ovp' {EapS~lg(v(B"HPE=DL.C(Pk(<#LQЂ Q@*G1(8]7b؇](a oC텐t{1 fɣX}9Sb>C{QyPc(to?lPP'yD{r9\^5ZdnEr8"NYJA-^#-$mB3_{7n_Lu h0hDxTb=j:RFp/WIp 4Xw 'р}3+,D&%Dk/1@`ȅ--M[ $V%I2|i3RyC~q?i;-|gI#]h,^L6OhٷB'rsD)V Z5KVxsiݧ3! m+is m St>?v޲/dўڧp::HGSdr:vz~G?P&~{Nܹ@:w{l:.HwMt1tN҉utBGNߧN"om^WJ4ПϬN=L]I^(v@ߕtRTN*jtdRcN^]ÆG,:$}::NNN'wl/=%x9E^D?= 4UCo連:ρȜ)}VP7ڂFn$J1e2[kZrK]ܡ4^#4K3]ZD#h I='Bt=XSK˓DYdPdHwR5֊n0HWqKRCʰ:;pKEWQ2ڒ|)'o'ÔFgpw4[_;ߊ2wq C~>!3<#,W~~"_ON"1~(Yu( QG.FoQAQf ~䤎U:@6叓`$DA W:JΡs%ttZ0eԨ5[z17K[zA9z>~WiK 7hz[CgU h/?qOVи+4 ?/S捋qwi\cg /dqzۨޞkCo hؖ4Fc il<ƚҘ)ONmݺFWQhKdih?|,I#óh%phC#ʺiD"aQK#+posa4 un\iH IICV$`4/r4 !q2a}i4 _۞!4GFlOF|s6 XOomfiPnMnaK0<vwN,Sh.̈́>!94Dnl[I|iP$ Ԧ ԿS(V>L=݃{ZџP8p2- Aչt. ҄eEs@Cp:x6xx}P;jV;AȫR ?| oC7 D( CVk"{aa_ A{ F=\W^:M3ƾ`12C/:򟀹RV.t/81/i~/9<{u9jXGHvEK|ݹg_WQ6k7f5skt.ȵܜʻoJ6vqgeefXsa۬/J6(ȏU]; ʗ\w8wgmS%i mW {|¯'b;wa;!闵 J9L9n8[9h 4Vjf$HPs_{cKMN@3u!K>}?ᜣ'Ymܕ̥,o uDܲN?9 VI6JsNr r'5s5B_s'Bw3{r>Gi.8%Gu/>U~ oZhXpE)9Vgj%P苕uu 81y-D 1 X 掂#[AVH* n'`%@Oj5Pȴ W6c2}׉ٿaP-xm`ͣP}j R%AD+6tso87?h~2d'P O-`]!v`/LNj^v'gEA[cW􏛃as"A#9m% :A2$84U@˶Ph&B@}!x :AEP>|\<CVn'ȟ ~0?$0> /7+AWrvdP6 (.`]vpW(K@RPY>}qvp8Yj Z+|>tY 9H }]*U7;?v o?(PsN%r HbAL~ As:x&mK <4ȗ!, lgEG(?&,|)kW`{-a! 8ǁ:A  RBοd 5 ׻Lq&g4 t؟$Ds]4ipJ?sJܼ8OsVj> TzꭹٔԁӨӢqn&gkfQsZ;4T"5ۿk٪Sݓ2S9ڟ8\ANP  s7SS>yxE8puϫqNqg (sΨs^B]s׭q&빂5'L8svp5fQV"0YvpH}poV$Mq7YQ+qp= m& '5>IsrfO?[sL$WWr׭]XnwVgh9__f^2Mbs_r[ip_FÍ]a*G8WZMpBs񬊦M۹4k*o}.\-]8s٤b3Sn͹ō--3c7h/cs.c5o;.3]=]]Ú(e-YycG;x!'JՙU~ê} .Nr?rdO^c؍i ix:Sl{~!QdC[ٽ4؋|za=b O.ps¸iXVꊤ3>܄S=.H.2Nي­.9[v_Sƭ {=8WmQ'9:739Q݌'r;̹W9 9Ҹ-c>65Kr͙Zw /gah>آx[àbIMnnZ˷I>\; KT|Q)5WpF9ƴ'z!'gړӰ#0n/; Vx5-$?;i<9;\s6Mg%o35NU<}]qW/gD#*ۻ,6 D@_Dm6Qf9>VjrDs.8c{"99ng?`ʌsY9y1,C [d)eqa/8pװöd_~?xIѣ@n+{ _֬$8Xs0p&2U@ֲ (*K&Vɼ eG@D'/T~$#8"7p< jMa*P7 @q8K~& "-J(ަ5 ^-Y R7ټ|Uee_} 3~K8l,sz>o9=6s\o(wsy?zE9ѳK:unlf}z&+lcJ?I/|,dC٪֕l^cWb럄cӁ_U!J\T{'\сLH$~{p4~tO/E [+ofQhBEY_<ۻcDOǟY>D!1 3s4G䗶ECdNr$zeȬD1{mQD%)Y?-YfCV_3&rQdQ/tH {,mt Óo{f:Iv E8Ul=N[wB)+f'K[q(kӸCBh+8Z .fikpux;ď{{n.lj(̔9|MZ~#f{ /hh]~DTn#Ǽ2.߾qL";Qu+b ٿv OK V+绉0J"GGȒKZ띳y->D׉ur}+^_AnY%r.I؆)sp41t`ѵW(P譩%{NmJblX= #7>D[w6%6d'Iv* ȖdóL< Y#Nܬ UY:NVƜ"ʊdYIO%d[NK.W"7~b }IޝL0NN^ {=ً:~5FVb&D(}DO̪"{CCbs R cbȆl4%Jbj- "$MDB$aD#ѽ4n Fy[311K'F"nRĠ1Y>NL[BIJȇX)%A6bLxf=enD>yM^ֺ^Gdqz>YHh.O$DO"3K  v ɌфO;&"@k-~WAB.Ob<݁heMN;P2g\tǃ<įƯqRW MCE 2R\|A+A,wVpzS +Qvp؀,ߧndwY}+`UG^|s^Z5_Wbc|q>>[ծ6W#_W|HF=ĺXY}0*x3>I`KI `|,{W+}),fFtIxEw,9%z`w۳3[\~ ΎffՖlQ+4 hʡ?5buLnTܤ{\8 +Th-&hqӹ!R .+·+Jr-dTbץ@`kŚ^-b=Ɠlhi6TG z9l`D8l?.^3g#)i1wǍ`=˦Wp2,~#vgVucK%j[%W=v evށyz}[V 4?a07m]>>>8{/>V=xBʹ߆L6m{{)u%'كg8;3XgYJ{Be}]:\啲ұܩ;܎\i){ 'ϒ;eu*5) Vb`7c7. c7fWpr'7 dm? "CV{}32 -bKbKŢl Xލfi*٠Gl\X!Dfk7urYel|>'=c6Q:w/lf h['֕ϻ6-rf6v3F Kϲ!SX1|!kB؋*X{ZVv*Vԁth'˹[Ūu鳋K%-;rV6;0#m~9;[%-qACo{^4ppʋgTJwș1%8۫m8r#*@`)X#+g׶ Z ތg{3Ro R@|iwZl ?~wļr(4^s5@\jNd<m H p|A9^w!\7as@yȀܙ= uI;yܾ be#+|/M叀۫7X /4p5pα\~v0e`os p DŽ#6|eN[p90 T.< f>/A`࿕|THQQT%gTP1!fD%dIt I,, YjjS9}sӁwT B@~Y2D-=. H 7<h L4hZe CiPߏM. зxZX`d,<#])+~^}NaCVEV$M e'M fgfK` Y9v}6:_Y#INVY˖5Xj N:'X[?XY\_pb>knj`wrvi'4`XWX3#k7Z;Ϛx/)g7v[{Y9avJv^VϛN;shfÊ"u𧭜e#+Ɋ{J+ұ܌3l V\1+6+hyUggsj'pPzY`lWYS <>::APs %AFz*]5JRP Ay?P׮{/EΠqbj=P# c"(_ _Oʳ@ZA!h(82ogՂ}gz +PESAPb[:?ZO xap8HGNR`W-77l݀k<]؞* 3~N1w8s}u2)#'9ML(;=ďcB.`n /e~2ьsMa?D]m]3L+؂ZߪX[=e>b>佗NbV䡃֓ L 낸 Ls "m\UOq?zYM˞M)_N)!~.kEbs?vq#[jhS +(GY mwA;Hew(2jyD_XM۶yveh_utoAv)?Ъha69rLBN@GAqZ(l sG(4;E܂"N}CQx!W.^#WGjF"Ǟhw,!:a?ں m1GCuЍ(3 @ =9tsY F0F-Fup#N}GGr;<6>@;=w Mh)hZZwEVXd|12ݎLꑕk2[]Br]%]gUS[F=coΈ2zFw5fAܵcЇQbS&ӷ󴓼 >9u4s&׌Yd1ti{g)0o?i3s* $ ]mXbq~ V=G^)^}T [/&JzJ"pZyPh0'X>.EugUȣ ?2+/+%;9{UU,dY ^qAx'N+UǕpMӹIm%Ђ4\vDn h14\wEA wa~nYm5wU};ԑ(M\\(} *yR"3L@Wпxb_~+NYwqĘ{; 5J;Nq=Ky˻Yf{$'vQ+[ m8dIG8A'DO鯼pU6G±q8"c Kq7})VQA Ļׂ8=}yػ:{Nاd GGu쳪_ߍoi-ʋW{|m_=EL{sR1|Y`SrBA|}Uzj|?I ?k_¡Ǥq@"wTpȜ:|Gk7Eq= w q?_׽op`>TU Z8d.#zp% N)/qʪ8)ɧp7d8(a8Z}v=8lOBⰙqx(Tmqĉa|% ]a2},!S )[u8 ^|Ǖ)߾ԏq6N:L8$8;; U4l\|b .\xUq%E/bp 8]UhUy5ߑBWAɿ_|,qOž񵩋,|}9olnþ5z=|CVYtn|熙89gJϒQ!ve8bNphpKp䑗8*iP}$B#q=5n{W)?8?NRę p}D=ۍKNT"C 2pIE\W F Ts|pQ.(syq63\ 9` /.~qV憭qM2d\D\xq2\Y3t my'de<Opf 풇q=E8o8<|?n\*[KƄ2.K8b)jER6\rxs+GN)Zt4kUq=n؄هk}#]#. pݯ8\]1=:kG۸Y7n0=ge3sT>A \Oc {-7<|E#C%nj+ *j~G~ _2xo"~g9g M~}t>~ƦwG^ǟW[w, 'gs'<,;CDzKgD _ *+VM܋=_ԪUD7/نu [z."yH\_F]FDz'2q)JdWwjDԅLB)."3yJxJd d"yc#My"Gȼjd}E]Fg͊/D=# +Ug/rk)QhOT .HT$[r&f3~i"dq1\DL͉ijb}'掟Ȱ3ĠS$:Qddh?&=+D!\W2+Ff(iLȤ\ "wtwm%}Wɼ;.Y\,q\M#nM`sh'wȼV,v';a LL3+e ỉ)n1u!DF>k#F,Oi2:"gLSH5|2*<ÿWwԌ,/8"1SdU }Dyahh֦L_w p~ ,M -F+O>d+0oDc' <^fzLq{q왼;kq5VnT6Fj|$pͻUJ /4j=v'ː*&x r!9k͘NaU.`ngnj)36WFEL\[=s5 |3zguK0+=a6YIZgMle\?@&yYTq`7;%ݫۺÏ|D Sxyt~)g s9پߟ/ d~g|fm ju̸#"y"} '̻(s>D1m84gv)g`_b 8vX}nƵupJ1,! 4d2?HIn ;V mjL@kozp435 <޶4e>}[P d-1 t'H2yM .{{c Dp`]A) Qqv" ?WAbA Dpv="`,#F1K l/5zY?L Ålc孒8%~򅵘êW RQ%Z^yqHju6j&ub/d*r};9,''˭6="xO| w[i >`<Oз}h^d1"XZ81;1P2y]U`&ye zt{RJkp~j<6YQ l}:#fvJ9+{$+7G̯-B kh:+XIK{39SLreҕy{0,g,d6*|VtT=tgafWl>y*}]ʽMk2{JaK[L\*X{8]z`ũ"TW<23μ=ʨ|֊ $V1YVWᅂ!cSڌۖ5ܱ'yk/O&CRa̓\[\BzN?ܹݜGKvA@3 I1{;3D˹x3/D`OzwU&.;:6ƻOc&2k Xw\}?zy TCV׹ݙ]FǹVmc_aޡB럎-<$H:w.:@WN_ 4 \Ɲq#DDʸ+͢"as'Ygr/(C[/-ҹuh~tv ZW?/@[7r!5k@;V&=m16E'O#4?A] C Nh*t$2#=1d5ro"osAg*F@ -̍q| 'Xs]坵@fsfܶ~J$b攫?s+cy~v᪮nq/o\j}cayv>7s{.a (#;e̥`}5 }X?Α$Hfox( qY:\V Ir Os#7 9(kb}@w?~/#@ÉYe0 Q;䲉y3y?\o}dƶ`y<^?&d87SQ7fnwoK@+5/ 3J -!`!q]jbw0Tik?Gp:3yRfU4^2f R M@&݌I*`?dZqqEQV %`8K w cE炐opXe:w2#` c4LXNf[w, !v(^Qr_L=7o#bq[@Ƭ 3qKDO1zAVH @']私{kAq{5QJ.C AȖ;8 Ta[͸0j9Lt Z9Kʈ%bCE0!W CSt IDx( jDegZm+|=_>OzEY[SPQVʷ QVD2&*B¿2q#6L #Rvv"I&TId®? ]<^+̉[E&$g:xl>%߉g2~o߾{?\7:aFxSV+vc"x&怷 -^'laa6 ZEýY;; k.}l;Nفo9Xm:0WxZ^X2|‚Cºs=z=@B(w%F7"|#?9;4O W~괙m~ s4#\~gp}gڹٷ?I\\sp_pڈ$5RC"$KBRY)hǛtrr^~Vap# XnWG\|]= y|Fgf(#?I/ttL@Ъmu!KufABaܴѰ|/~3~_{>kPGg\&MuOF5WgPR z1@9obPϯE7$~TέA7tSP<{m\44B7):1(Edt":|0Za_ߨ eP˭F\ S2%V!HЋmy}IGFߧ!hCgv07ni$}¹gȄFn&ҏVCvYf= u.FqeBP>@ f('9ɸ2'b(4}Vn"@\n;(qLt[f-A)}(Z"*}_F}QT!z:z"b.fy\ EGN;Q6s48 *{.ڷS ,Fwd!ہh&P{[!5^EZa"ZX$NFV陸?H{a}{{1ȥsI3pM9=;$NWѲ׷Iͫjli|63?f[ҟn)υ\T}>(M o I ~;Wi Fu%; >ם`i1>ٻ LFi a_p7LGT΁{y0v. x*zl+0'㪃%8j1 SK}`[YXuJ <=Ioksp>$pXugAXvo[h QY0{2ۧp0=x )32 p|Lp,y8>;Q*8V .U?mR Wۛpkm߁U/Dp"ϑzB}偰f$'$-3 /@Ws]y*> <60U:?&ʪEb*dէıX#壬-߉5zĚ"ٍ4.k2u52}\VW5(c {Yj& V^UN#™2Vk+hJ=ʤog ~>ƛ5w+z ;Q+~` s|oN;/tXQtAgct O-^{ OF@"ںp/F]SM ";S#zWϹ|p82*8WP s N#SߎyZ;'&]plE:snRRDpϚ;Ϭ>Xn=r}^IurcGIe\gWwr1ӹ^Lnx$'$$&ߓH4= hi7C)%hIhNC˽:2k[\!.{nK?͵iqo$_0MA2w74wo8GCyg&Rf޻=k#ULhDWSk1|Ln\V6Wq<ɥpϝ4O4'72V@),؇$!Ld:#SYnmFO!&"{3h=gv܊A#9)m6|AWK ȿ]q SJh3D;ccjtTNAFQR,߃\f"hصmk݋"M"RdկA|Ca:;xy EL?T&qeK{1(z'5nHBx](=QiPhq62 %aQ3\ꧣC/tG8nG orGTߝ*NE+^~!݌2؄J+D P) T3E -PJ+_T1j-=o ʙ Qpf(b'ӅR (mR=J1CwlCdӃnAPS]= -*̷+!`;{H{$Zi9g^o+`,|.'qXkx}2CkssI8' nݛ_ʢ>6g&\mUk҃y-g}%rhbf?-Lg|+L|mo5>& |53n}L;\Ձk)8ƀCe YI . n䪯3M4<+#=i"غVVNz ;m);C-;=wU:2N٣NN ak RNVk;E՛e Y#^eV]u;G9;+> +XY윘:V" 4l--*JAUஎ\G7\Mpzx-^l9yyuTz$+wrսg]f2&38UޖhwV L\r gh1edwwPC>5r@{#Ǔb{AUu58{''߸{'kΞ\H R*Ej hn;ҬAClO|{~8ڢ=bD_yoeJ;'|t; IA(EEaې;=ZK@ yehi ڋe_!NMDa|to6ۧ$W\ЯxR^<5!܃ӯ`B 6!cDià3 ;px]#B_[|u=>Z_2|D(>NON[Cr|s8PS¥qZZ NOӂt'N?82zJ'8yITHsL%qa.(? /L',Y%pv*x4ejqN\ z8Os=Nkys2.Aou'DD8 ~ 'A{.8Tpr5zNǷq84}ُ㻵8ߋokE>vhVa3b3IpƑP0qĄ8#Վ˿8FǜZc!pl[%SDqt;iK8)rw븂c pԔ8> m9̺A'Nk:3?=8!wəbC~).Xt4Ņr. ^83LߌS<:p\&NspJg>Iq/8I'*C8{NDZqp|:oqN{ep 4+?ipG|X wE|pfηŢsٸFUy1ُm}VA|Ms1>XPs  rWJ=w\$g)Y40r$N؁߭ñ 81\lTa۳8lz0^.8$ :0DLq +mwjN98S IB[;!W%xGA ­)Vqпr8'ȆvEh~'|ϋqww.N齁8%NT5}pƉ8NkåxE#gbh\u\|-VS\ Ɯ/?`b.M)Se+}9|,pp阋.H5KU4qfGW^̹5 qVoKq-ξP)5pk8uӯԜ8#7N7)8~=fݗ0Z#m\c4_ s80s/\P\|.F0g.|9[1U٠OvY|Ȕu'Sq"}UH#3d1O\ǿ> wV[㾜7y 8My ǾoX\/_Î+8Y=F>l2,/we,C F]^,E(BcdQk3mPڅtsHVD_"Ղz=%T|u !^|.ɬt b) &?|]hqWa"l4Ln0vw͒~X|e@]Q{[A{ڰdx* f5[zIwt)0fUp;:ǜ vxŒj R4ذlc ں0xo mA୳+898o9MV? m)j<"[ 6ydT0<_{5@m; VW{WNT|,msEI#eџT? 4}J//χWةhi2 e8^-OZĖpM4~:1``/seBbKRФ Onc J`}kAjc a)e){wg{j7ki6vr+&m7);Qv1ºvb H^ 'ce~'{T|\=P}qW}% (nK&&2UE&3λD|:Qp&g<@'KfqKbgIbݖ, v{+ުg]Y}o=qrEZWV_/:H6FȞw3+)7r+ ȕ2UL|/&o>Dc2Q.D;KsH̙$V?jNB\'qq$>v=I}H77$?)0"'j2yG|Q"Z}TGM ϣ҇ujDj2:N/jR "S1HciB=C[҇hmwjdJOv"A=i m K {i2wڔ@JcR" ъTZjD w<,z?n*MGh$D&4&t-uԯ\zg+˜!tǁ ]7e_ST' UL뺨:2q5OD=B6/ D 61!b6Yb s:aS.to-׳RK*I])/TS &HlOZƟ"cŸ//XɗZ3l`V]aGS-d6;,{y/?Z_^jq._{_l8|G,S29<+_\w}<_'e_25_Y_q'Kŋ+';}oc4gV!|w3{ ? ?̚_uPR8?f ; AjWh Շ[DB>?o?=υm-0hHax既I2o`jU=\f +V(<>.aאk~qIH΃5aݡ qԻ mp` l;ΰ˦vUݚ`2KؽUv/ Z`W' ;;6N]C.l? J$Öpؚ[g¦NبNwa,X$: ,, K`bo/엣)3_Ni;`C/cad }YGǡxy Z-Kک5N d gaGyPxC'?gmx;@u7'|F[\V2k11*:'-,ݣCϓ'ӳc%ȣ75h]Mìzid^/QKhc4nMD6Ӝi^kZhL=ii,Z1a9x STKzQ2An.s jHmJCіbcz}KMmh& Lvlע5)S&vڙ.tJ;yNh.v;E@(mm?i[%mnOzhcp>tnh&\_GoPjDɽ.QrITPQIie(H?Ds>Ѳ4NEhA=oCs#if1f]6Z!4̜єm4G?MMTh7i:-F_I4lE# 7 4`[3fMk*줧H1=:o1;R3tw1`Ce%|j>уZKڼ0tNJevSѯ6k?y\v4 $U]HM$Nŝ~ W:Τ~D"QK>v臺qKv YxG63Y×|ͷ⯩,M_X8l +7OKï_U6XQeAPeOisB1l{= V,i x@*h4{-E4 -G@ʛ`:}װ2WAs"_7 a\:Irpy1hg 햪C;_a\WvMnw<\Sꝅ6T! n@k6;h %Ф>k@jhp gݠBdgd uCN̓:N/(C] u/B]'%nX[.>u.~. o= A#)4+&EӠ h64{ \7y4ou|B4͍C384.ƻOA_6h&OAb=4r8kWB=AUha&4ܼ>FɩCÔ0/'a 4̔;BF*CH54ZtA'X3MCSGl hBµF@-7fv2B|M_YhRMWBSU^ j/ADhp PD$dhi 4\b Arhp0nǫEokzPO͞BYPop/wB}8 BChhG9VW8;x *YppFS߯SLG89lZ'pk#|\N6K '/փi_᤺PcH @pPᄊIg G_?O}VMR'u8ׁ߼YkbH&zU0eKR"3R'H҄4A&Д 4ug:Mriqz_ߝV܆-O iѓWˎԾ3iYR3-8N+pœ/Z%>VBsé exkMh3^R|鉔(PבVkӚr>Yu}δZ?hN(`!m iڐaIzFPh7JoϡMiә[m>,M;i.myPA[ӇR= 61iۭAږm+mˣ|v L)j-4h)H;3mhڵz|vM=nA%y=g9J{Оj>QHGK{^Ҟ-(Y\F{$hwG=Nn~>Np'ir!̩hߴr5SM;Dh{Tm7yC̡m+Їy1ڊehoڒLw&6IhCڠ@xN}^ݟ֝ =V dZ}_VO/%t%*,nPIw{%IUr8 }\w3-eiP'iCZ@6p!-Z=Wi)7Cx14gj}߉XCt 'P Ib;?NnY$=M^%zdfS07Ȉ;xM z6YhBOdu‹Ya2Ӄժ//V|ͷ (-_ ,s;j2ǝ:j?E Ț-p"9+Pi -j^C:YzZhB }ڼWkf@]pǣp#xAt}~![x-\}zB_ oÀ͏aP< CWp^Y ˜ & 1L0>.fYS=a6 s~oy6a*,뇅-Z7aɺk,˯' ~Xyu&rܞ`VlUH U `M `];다L"| `?!66 `ccl H&l* ?->mV_aGt]aWؽbv=.`ϻ>u`M8R`ؿFw'$?t[ç 3YP8| > ;lwOCXцNϷ%Y6,v|fOό'7'W.aV<|~{섏`Ϗg9w].6;vgV ‡;YZt *n-nư `S\ƽ2 ذ>@Mo+au'º奰m1ݳ#y ;!{ E;]!n] ;fXeV|!mr?, LU V 4w!;aUm9 \z2:~v0MBgS?ib0mRp20EL.\h)Չ0"^7sal,ȳo*4qUcpxَ>Xq6ޑCsvuӵ> C8kR.|k" )w_.pa5>&1 ?~Z~zPG&8G HC8,*/#?Wp$#‘mpD5 ~z% t~2dc)q]84{}úᇄ,~P~7j/^-7\%-718s8?tj.K8GхGQH8- j 'dpG[Zhf8z솣pi8:?b,"?  Bv.{}/[pW8ώpToN G^#pcq6]k?mQ0wy$-\S 7MU:U =sUa&!7v-c)1X;|Vw$J(X +VAX ,Yk>ہ`2yBTPga/i| fHdIr1&{a0ax7FrO0%*ua|f! v =5< \wV-+ Ov t+9%ͣ gͅ .zA[?fON@S;и4J '@(%.Vuτ B=P{ZZ&mǠ5Ld \T{CP! z- N9ep3TU5*sݒP9T^ăJ*܁7ޛpR8T8sI8sv8Tf@CPi@Q_ @,#d4NVqpE<\[d᡽yC <^=xC*`XC5_c. %`R0L;`Fnx}w |/.y  ͅta>3a΍n lk;`t lj/`K6lU``/l[N^i6lY-2l [ assl ^8> ? `þ>3`stu"6'O^kaLX{Xn&cV5~`X Vo)r~솴ǐz݇#C\9H@j aezXq|{`+Xܒy+a`%VY0s6Lvi^|_ SacGx0Lro0nk5ƬPwO/0Yf J3gaqޙlC_6=qt)F8 /\}č@. +:^nyoн1d;t 1+۝1e\U_ }h`m&́pQ d{ }62?!8ym ϶Z-}ZeA+C\ Ԡe}h)?-y\h4и ٧C03WW:ųv<\(4738TTUDԡv4x*1AP6*{u?/,pf&TXvNwX h)Bpb("euBˡS( 'ktɡ^p PC(*.X e堌5^ p/ ( IB 8U8AlN⏇}s" cP?go俋m?8~wI%q'~Ow+k#aqeuN~~%Ŋ_#_3_#{_m;ȧ+;(ӌ_/ϱETX?gY O?{nZ{|%~8|u$c Y^gaѿe1-" 9 Γ*bMby$m%omK*$=ԿGZ'΅9yVF^:3'Oa*"0Rs쪿t*ϜNoEgIͥJslTe E~jR|:Q]`JW{S |QkK5eOPB5.l)]F~Pwt^8JR^FJ\N`eҴskjY@W:S[M:&ta UH˥窨|ؗ U4O&)J4Đ=$KP$% xEߔ[crkr-) [P=BnWwXrєܬs'ȭ#'__H,k*ս$DO#$T#B>˧Gd~{:D.S`kxC!5FS^[w{E7c/C|zjU\xꗍAu_ ?X'AGmpx9

    ar`USf~w'`~9Ss3wބѺS`x)(f0# .KaFx+V=>¸zxsrIXx~gk G :J@,@O .:PMjA'p8N?R~kL\_y_v_s?y2?5?^[qu&?Hً1RuJAa7BSN|n|')R=o]u+[g˖ݽaQ*%l ,]g.+gZ2^ Fڣ# %^gw/3.j7x.ˍW>1ߙ&O^Κ/Hҙ["']W?8d)w3\wX5YO.sJy\*RqDFSE?ږ1n."ruk/ؒ$f7\n0$||b_d3/</~`ެ5̸LYdsgmRdob=*OnŒVZ:rp^Z {o952& ((⾇XEl\VwAku۳+ꏰpsKٓ7NJsɢ {Fժdoe^ocCl\ƭfc.wn KDlX6%FͼΦٱ-Z6=6s6-MI3ټGl26_MbFIlƓg}.6>ϦJq,+6/+ƈa";vXccw{=М]=qaάbW~`W&}am~=k]ְvyY,{v~9vј!,ߝ2&) X)e0=h @$i Cp67Xہ2>vרּ?rmVrA}ui9\De4+O jė@& >ܟrdUm^} [b857i7ZvFfЅ(a}ڝPM\<[f ~:x n"gq?hEG2v%1Mt$-a$FAU\|eoc*{yOqmWsi}/f+\4yȕ㚖7 848jnUFuZՃ 9*'H**<?C!4hvz"%@ϣ6Xc r ~ǒS"nj;qoz/j{OFnnRezwˇ^FexQ(U҅`/Xy34^B́x ~ K4ªX|Slk)X/wQ|X]oz 'p )@o@8A7|%(VzET3|gN|s_{q#F#;`m( ΘTHby{oG$6z ֗+]Oc^jl#c)X+]^byXy54c_X@/W2wŖA۱X|& Šw $ƕUae'~>sCP®|8 -[Fr7ݙbb"ЍV=:q`. ׹ ? K?EY r"<IV Vq-x#~MA.b"~%j@f܏\N?R"f(?]4Fh%=)7/ZYy..8 \T17Jܖrq;mA4wyDqq ٚJGj@`P:T8K[+M&(" >rk9)e c\2ƷIƼӘ۶3EC@a%q >,~B4pJpJ0"n_='n~nUWa7 k~b]ff;yg&.|v>Kg{RԆ=)z{Mc/e?̺Y^ Ϛ76q&\`nM`#{&-؄-lh{.$MwebQf[9Ȇe>iX_horViv k:jerL>;2uOς]M6vͳ7{˲؃:_!f7Țd>#,clZ>l`<;bMO؍_홡Xʗ4/a XmL:lcE/$Q=촳\0jALѐ!Mv%`hE "1 S:TA{so}Į"D4g(nAp8X ʘ5e^9q=7λ {zry$3ً.@Wej"eU֭BI0GjN71Uy(i. 9}Oе`MJLBMB9(W-?ކGO (儗I(?/(ῳ`8ވnj^GsP\ yUPծjj /Ha&*yqVbP>Uz$n@n  y j ]w WE1 (yoD4PQz>^+Pgm;{=LE>D P(wL!(<=Qhf2JӞ&@v\4iz!aQnd7 @6E/qhOH-\ s[RDwq ᯢ` Zk G}[#r G"͉fhrg!7&+,0O- 6${נ_Єyd.MYsytENg]_$M*A,3P$Osvs(M\cN.|'7柒D773gn9\ji3us,rM8unE"Rh-2h2rգ(xyZrCEǶ:e[?OEJSߛH59z\EOG=]Z g\4,76`Bc̤c }/)‰p\A˔ٞ53h7=X1?qM#p[r^8]UpFyWU\:ME\9t6p?gfn>mqG9.KRpѼ U pʏ(A* ZYw87Z wo<.NnKF^]*.=b+6:-MÕG4׶kf15v'nY[v931 n8M}xP_N} M݃,xf}2fy蜣xy<7]56^ϡ ˾>OנO^ +?u1xƀMRو!aب C3]0RC1\3~Ǩ+o}s<1NÄ_ʘ O|“Bۄ:{T~ &xg ڮ 1ƌX51j4F%ae t?cs$F-(%wLjٛQT1 I| eaNS0lk 1 #NZúaTV FoK0cƨ!1fo<cb 萏cUb=P\cƜ1+#`WW +I1T3Ɛ1dn 18.c>r|7zۆGIc<*pT:KtY.ƒO#>~#yKO{LƝIpǐ>ܵPM{'Wנ^ ]ڂbRfuh㧌(d~0Zh8YaNSE3hj C=hs ϡ5hs`=FXh nEQ[qj)g jE6o Z575<85.G7@M=jԆ&MKQY<_e>fef'PkYZSPsjZڲ'Q?֟Ũ#3uBb QgMFi/A?h[&e43FSf4Ѡ ,Pu/{ܾ Ρіhm:PoKԫn_@Q|{ uwس(Zb[z( 5m~|omIPCKZ?CNԝvu{3Cs~[R9ԟz7GۨӿxON} u':^Zu P'WE=|: Qw/>CB!jo@8+DQU}axr3*%?FxwT[Npb* ba*UF U#kH5T;jH4>3G*1jiCԊ8+k::[QwfXѺh<2KaCC{tO OƣщV4ʛh'h*3Mwi4i57hbuM'ɬhT ?Eh䥉&ݶhS᎑hxp7.m@ 5h8K ϙ4ڍFYhrD?nDs ^ƻbzzż!(E}٣AK49+PG;/{qګvJ%`(w G@bl~z1騝5}-QkP-ZΡjKTZ*us8VP+y!jT1xf:jZbn֍PIuzPU$Ceo'm?u1kpt"#pQ3'в(yU hA~w@&WzQǾij R0g>e 99{s=u'[[쩕*{#=32g}痕>J{#˞a/{u.u]4~v}p>> ω[f9&}lfLaԣهٻ<ӄ}9>Ȳw?̞/4cOb]=k-묑awec{v7ne-nJ=)ݼ}ݘˮd7DyCv5v%u+׃xmî[we=v2jv?]o.a n=;_0h̪]aU>+W,J~ırs?V)JaɻXgeY':bjVwZ҇ꬴ~+_',+{NYbefoY+MV*/~q_kdD/cjOmŝ.2 h,QUuGzG>AV]Yk[P㒛*pͳ8y\8aOsWK7\"r_=ag W'adY_S]2xzL%Q^$b)Gf'ļ5 +!nn$ێl%7_-*Yz29ٚM$A ިB;ɱ^r6D cW$ڒN&#IV4?!yH6[E,J"ztd"9#I' \&gZ35$G*?#9Sb{dbS vz->d[%yԋQH\YGr5IvS J2 H6OR7BR*IBRԓI9DN/|FkɩPBNeN#\ΑSaIR%$7L-$I[I@6IZLN~k"9jEN-#'Vl$'I{w&D^6$0IXI I1$n$3#DG"S2HJWVn0"^$ 'F#GGFAC)\L79oZ=h6 t Aaį;?-쩜DMY K^*9gB"=ɺ7ɪCÜ{dcy)~#{ߐ9+ZG۩mr&4m*%;m @\"JɦAKmN٢`Gɓm}dv/>&{8rlw=MvOT#{N~%adMZ^ERI.9d8[$䞢w I' H'ҵߊt&){ȽFyOD_OHgl7$_Iimwt{|"IR!]3v΢פ-m$]pt-s!I_L"]J Iw}hyy\N!^O!Y ;jO>"(Mȷw!W>y4$.p|!Z[ M=|U$߭.C"u8KM$e>򹤄|nAnI}~C~4C2 ("_}_Gg6+~#C>:t7ZHҗbG^@޷蒾 M%|EfAK@tyg\JN6 <&rggGImfi=7iIo#q؟45&MbXD '=䙬N(n#|!/52?kM %fC#ȯxw]c 3#o'/?gd7}qw;34H.JYE"SH56=9Aj*GR1T|F*~'sH}!)ͼ@J$HaG VHؓkH RY+Cjt?sRdRlB2 lO(J&&HLR9gOVcry 4iI-$=eFL\qLDyԚMxYGxKx.YV)̞$,& ?wMkZᡸOeÅCU^'=$?d8R3?  )S ڽv %Vi 4+ 8ZO#T@Z8v & >)?4SXG(L.. /R(\x@`p̙e}DŽw '\sl.,.( ḓoinpe38n})j7:.)ˋ6= ےE#D]ӫEMFzKy6Y{F_n5O7oW[9>ܞ/Yp>?m&H6%|;Q k{| 7}QCg/>໧n=< ذ!0lLLq7l ;F.g[Yx+[bT2yx:3r? QW3Ls*3<f:F)cg0CSΔ.7u)lOzc4me+X iv`.;"\ΰ+YDVƪh5;!;=83vj Y]dk"t {3ڕQgc`-֟5k|6N}(7e_LK Ja([W(GG-Dw)8r-Sj!U18lUG1_+[Q5;'|EŁ7P"s8.:NtFU8g!N݃JMPM8̿PujTԅJ;~ ]Gem9T/]f68 AP kPqRv;rCpW[rhu8o {23qdf#Ԉ23$m?نW謗(Tc$(vBocpX%N[x2qHTԗDş֨Cv 0Ǭ9.±(:U2m$4qIRg|N-I!htQ]&Gh=hQݽ(ۢR9PB]~ƥy9{7ÛKbJ0vd;wv)+rcIzY䩳:۽[pi:" gINƼzuN*Yaj Km& ?JbIB֐NpXv5#ɳ!p;؊xэNN}pg|7gg! [qrK gr€<@˃MXY^;[rK|F8כ8~ NWm[șrUFmirZ9~rczqJrCR9?ȣrqQ3:DN%U&$nu9)Ii$Nmrb9A3 #qSg \-oDz\=ᕴzaha~% Ѹ!}'UhZxLna(mXkj>\zӗI D_c>^/iYo]i?̏[-Ͽ8Xl|fܭ]xVc|l^b+CDɍ|lc>Ad0RF'h_b/lY*J߼^/NR$)E(S[]Yyc>|cܾkn^{1V~۵ote|:m׼O?l]4b Zی*y"~NkѦ K)h8/<պl_P]O9/yWU4ۼ/N yiՉ-`HO51L[NU:7pEիDW7&+4N/%뜝+0\,Msu3M/M(h:Y KY'L7| Fr 櫃g/s Wr}G Jܬ$T& [%ؖ d ԖVn*Z* UTA\᭞Oc넿D~L9Bf.ALW$3W G. kw-%IS7➮D/- YK IT'R,& $y99SINS#CHW$Vd)=$Gqw)*s"#3I$oE{|=ɓ>NrNiA$w )xOʿۑbYRk():CUcH$Rg)3i%ș$u:ɸDҋw4s S yGqnW@B2Hh;bE&ɒ}3Væud'| Ý+ 縟XON AD{ԐIaNl9{AFzA$&1>H-8x_􋋰ᖰr艬0OTSpTxzAۗB3[U^Oo BܴWYT++j,k*z:q1]tp ?vfQƺ^_辶4 /5z|[2o9wh}K>/蹵?1?yڐ4>3n{;7n;reپ%6]̫_+z&AtvV3[Lsoy}o(ld%z;)Y.7aM5L Zf5csG s^[m!;r7;҇6}% #YS)gi]d;21m3! ͶXR X*vjc!sxX8cs-k[y,eAyHlĵlψ5l6f[3잝lIQ'N9,CҘw xȬ3M_<4Y=XĠ΁e9aD9iC؄ďLP?S:.53ɄdO aA?PI,v/OE6E./'Rq)Ѵk-m UhQA46h?\t̬mco>gpu|X+΂cj{Oϫ=EYlV;#`;M$wؐaș:aKNSX!2r-52ES?D,ZETl~XkLV=dyr Yzsu'Ne@:Uڶxaؾs7n >$^jK. ~*$H$<"Y޳IN]8JN"Ie${>񒜪@o%O4 I$5Rd6 'H4 !ħ8q4'Bƫ80I̍ ܉Hs#6 d#|u*}(F;1s'N~Ygɴ*ZBfW%ý&6b+$DvVaD_>~ 'N ?^6Oɨ\|""}LX߱\py0y0a/r$)>4M]aK 5^²6BrlFͫnJh|wvڌuLZ4a+aG)aEQ'<|bpi1E}kwZwtUsEYÀI9$ԛ_̏|/?ͫS-GWDIV1DёuַxE_Q;Owex.w&+{\yۉ?{?˖]>Wٳ_ĭ @vD>/''|W)/tי^9Qw-z;;U?;h+~>">z \:Ο͇o~?%|Cf9_y*|3_װ:ş3+X%C]|d>riSXp~ς|z/3_?&޻G{kxf6Y`4Eϋ[|IN>v&?ޣM{E!D/]UoGȋD)n5sƈJ5W~-1ā3sd2HGZZ^,-glEWEOh]V|QwUG/P뽭޵w y]/ `~ў7P'h-~->HuE(Xh'޺d/Cw"#ٽZ6[v:'\t͏tGw?B<@1GYv,৉ݩagw<cب뫙|~u&a_i2LA" tfsTyC26|bgT){~lgN1lXv n6_c'kYj;;ObXM#ֱR|8\99%=Z Nkk ZW+qȫVS7<*PFra_Q<PT_'jP)xG#Ik!ZZ(fZ3Y74%Lb5~GXra)ǎbq2}$ ƢE,b ;H@]lGcXiDy:XNed'έfg瘳5 O=eLe]|V^gIىGm,82=mcЛ8jE-ATEy}Єzs>I{4z Z:p@ hxN*sʯaKΫV5 !m|e걸2\IK}MZqF=rᾫx8# ]s+H3WZAIkti};~rji E~5T^{Bq{"9EBJPtn@6@0zӊsLFpJ8G!4W4.JBHݲ;\]p:{!tqg,7_'⽍!qϐ5y~z<S9t)M[ԇzVÖ@LEOi܈+j+1zm~50ƀZ08_+0T)>&Pڄ!jf2W1r[O`)Za_'y͞`/e⽚cx ^u0p Rǐ# !f-CT1h w2 Ȕǀ{u:~@wmSg<쟄}/q`%:KK1],>ϸٽΆ͸ä w_ǭoqӬRtq]Xt\yW'XUvpqk/. ux Czm*AsKy3q78-'Nd"fCT-)E=LBѠ s4( C?^cj*CzJZ*=Ru&_Uԙ ӟ֬t,^dQs>jXf2j2FG99ujދj -Pktjġ} *PT5;}hM&B/h< MNEx 7#ph4|'hb4]:4|%#Р `g4puDwh8ACw;44Dh:M:G-4X&ߒH2[PurowLľG44=&!-FO6g6C [JssKG m_&@Sd( Qj,AunT P9 P*OG5 _^PkԜנJϲQr jG- ;%P:T&?$+PCqL8QY8"EeF!l 6S~?&;اbuW;Pw/޸ cFWٳ)Hq$cA{b=5uhGv/s3=ze:g2 m?+RwKpQcdzΔ}`apa {V-bޱ73X8`&{˝6lg/7GY[]4n%JY[v[9eMֳ&Fe}`WVvc&jkSUSf%x-+ѸdE_(3Vh6b 'xB2L!ߓ,9$i 3C$rI|ENH$WMI΅{$o>rFۃI 3$*B2CcHtg3I;ORkH7II I~8LNo.'GIz|a,pAl'ISɉJrB'$jr|b!9nx:7SHBl*?A⭯$ƾĬ|Nbؐq^#񇇒n$~O6;PJb$lHf<3e KnH$חP $[!aj3Hv ]P$duܩ ǯ[ɱAxhٗHZD> VJ Sf ׎dsY8Ye|8V#ɾ! /MvsɊ1޽8H:dkvq,HnؓaO̓,͞!dq YdYzIz! s&6E"pob[Ol#Nt!2/ß[wBs;EvYiH #KG~p$KF%{~dHb7֝[ r ѱ8n|OV6%ddf)q!npx?J&Iк$pOn~$qO&Xp#Zޒ}w6~/qӸT&gN !%r$R3c,;Oj5̈́|G.E>Ao}'&J$% ͇%t|gȧ˅! k/-L%tVSׁ|Co*yI'B~%oWw۷M/.IXI^E{d珔[M9u|~@2&_f'ߑŤoMrZ-ykFːG'I|7rt\n"m=sIޒt %NI]?rz0B:*Uv8%8k:y>}ygkA>'?$sɊdZnH*N0L͕ɏdw򩦜_x_ #4'6Y=`#ȥޙE>MՓ Rt¿"Ն"\zUn8Gj""G!]H}fFDNw "fɑݗ;^a iظ:E7 (d7ED+։k-s+wrf,@΢`7R*g\3t3~W bOrj?,8 e ST8 3naN~`5|)7^ςec8]YYP)ܐ>nB'IqAcɯ@>E&}{GVv,yӢCJ#y<yYBzM^qL]FzWo}+i;q|EnQ&WdnIsm0|aj|\-HHӨry 410& 9?mR=ɮ3$iIf~ZG2H8#H೗ħwL VmdoD~ qV [ҕȪWNu7YA% '6t"fV$wteqd~`o/[/Β»w f8 GSUS"8.?c+,Z+4$ S&tfa$\jD(=V'THDQ6K}[P7zu߁#"%2[C~|Q$ /',e=/:GUz₃-N*|7NLn}`Jbj^PW.(3]*8@P%F#=Lp8/ɑ+o  ' .85 nd&Hߔm-|E;Z鐨pF(k4QW=cSogSdV0dtf G3N6yl6cӽY/3g3 f dF{3lY}CؔXʕizرܻ,|c)b` ,2h+,?V~}V=𕥞Ų糲i2L[.G앒3}`.Gge !tjb6}k^Uؿ1 eoP^5? F[-84Q?.ne(wሚ8jx$Qpx JYj]8Ne1vCGPyNT9'F?Ipy* 7֢dTn@UzH}GT_Dٖ8BކrE(ueuȀ2s}|OWQ x;(w 8tW88m*urI*-V q<Ex{&L#=Ȧ+$ 9)K=- }^!MzVωW35na*NN87G73A[pV:<5q~ysllc8YǑ8,nrg*7"gΙs ~v[%{6g,αpC9NPNS#ɍnk̤]}34[%)ڤ6ʎ!YILB >Y4; ;E6$*_ C OX2$(!-o X ) j ʾ ߰Q(=GP|HM7xI",j/V6yޢ|ޞs3͟[|V%cw/ [ *Y*N+6}%tic^}HuGcq_Nq|~>Gl^g(M">zho FՆSϚfgDaF|Zi >y~P>8y=pg,Ϙ m-|o9_?ׯq-{5~G-9oMf ~1SdzdƢϴ~-hY]$R|R+:UНe/6= Z{z~]Z9r'xrx\ 87.߆pL44H32 q1ԻOKk ~:X" H [աT0Ԭ|!)UAݿP<oJ2\4WKOsN|(< 'Be;"_x B{:Ҋn4z59FD|L haK񔆜GCih FiL}6X@E/xy zvGӀ4{ 2M 4AhPJ GCL 4$9GCڿАgf4Dm A`"z{}z4dQ|LA<_|B#&m 48s. UA4x>|\vC n͠40%5hд@NwSNӀ4Pb <On5QԿҕoK&ǺQ?!. q+Ϛg~=z~)=m>zmN=EukzXPm꩜Odԩo+&Sgp5/4~ULmIx=42+7^V1[oG8 CxR X (4Z}i[ԧ z$En]C=5VRi{m,u@/ZQ}OdKCn;#zxWPo)z]Y>sz>#φ)zp{u AyZ/ƊzOxG-{TuD=矢;Xeꯕ([,LC݆>jg,9C}"nPo%e@V(PO+i齊r]!oh1aR4s!ٯiR# s7_\NCnh` 4Ѡy4$Ӓhj&p=:I+FAJ҈4[KWp4>iK/ 5bzV_H˻h V7Lћ%[VW] FKZ9Vӆ 8ja :ZV%5q~ִ,wG5U5\͍ܭsnd,KyPߌ#uqGq%>ק8{m57:-&sos/WsB=Sgܵ3FܥE+q7+Gp7_nqoqPڳ\['Ic-Ͻuul=?k=kQ=¨A^Fn=N RԆm ;$~.w$qҚ`u!CaHO]0h #61 w0[>o-)%`Z*wTL߬Sϻ`FmV ^r0=1&at,RaVL0*_KVk`0b LT6S:Ku絰Hc,v K7̅%' B\N`óA6o `[?p apwp GH%p.osh/p}<7_^~]plfC@wx.HB0 A@U!NB[B\9@hl>~{/^{ b f~v|b,!@ڵL z'"_ɻ!7hPvH<NV!/$(d(87DHqn!c@l$TBʳ&)gn} ARE4z)G0EH9!4YO +c2d ,>2@ )Iw\f>_3m< Ew<|(meɾPp*kP9*MRq8AGrTfAEa7O"(wo7PVeAϡ|yY&P2 ξVYP 6@@/EBzE@QxOM P= ŸPoӠi(j)Pb Cy;ܗBnM~ g>BV y!'stAd|{rs! = yB8태g `_,|B5;g~|ߡd<5C$(No'mZc(Ů=WPy2}%PejPv_lP Pq ʿC,(w*5_,1Ҏ;PWe7FBy(^9נ4s()4ݗ@yZP,6iAI@ mbPtx*J GÙPp*I]PC-Px!ur VBSPnˡ(52y(RMP2MKpfo8st9_"v(2EAuPEWG@ZjbP2JB?A^UePjeˡlo-ƍQt[Fנ>e3á,MlWbJ(?-%T.TJP"ASP?鬄sp.E=sP{.@ s@y9u.vz-j@;FL/t:10A`/a؃]J{AT"6.>FxuSL'& ?4> ^y@3;yLF2'j"mp[4NwAyp1? .6n\0w  G@ç>h< Ax J9@5 @AyB2hp~ AE  u…kߠ..'nАx,~x9@467?{~n96o . s lK\l~ J(a"- |b_d[q!w _lN>7;<7 .Ygp5*.C0&pJnxXQp#gܤВZ[3 9Zf-Vݦ mvp7<;w1 lLi) =2r7<ŌG'A?dxއGxxz}'k;ܭ[ 3A{27- a1 l-] zOv!FN;{nݳбr;?ŮpE<ON$9cT{=>3ߎ<(A[X7n旟fsK}$\טMn\&p[&\*lpbi1&qyDA DS6BWpO3sP{PӪmԯ) _@O5:Opes3^9P0νjPc5 Z3C zCG*C͔'P!T~UǛjc6T'P*m;vP9AS/[ %BeOSrX3 [~9gB`8JC;PYUuC Trj]޸wCCP'>?z:*3e4+yʛCŔA(uRpz(yjYg9#[C'C/(㠼P*<<*sbZ*]WsPP%AePa:|d:G?B}(:{mgDCPE C胒8BQ( :p|(\ 3Pe6]0R gB~5qӀA( _1r̅k M![׳Cx,z bh!C| -Pw2Mσ$uZ  0E MBi (`Pz :?AJ߹ HÙ~B^qnb}cg~p`,~kENUT|T,懫R%TBJ(e'۠TJ{m- rPjQ ?Y7PpP?:}猪UE vA$g(sPڊ}a %PRng5bTWPEPٕ&ֿSFԬ9 UPP .@fA|Nm(kźX5Xv %aP\%b%v?x9wNPFYD(m{ĺK ?BbM% *P ?7d!Eh_hj(4AAKePpO ,rŐ"P<k@9Rm87N\/,G d0IV̑s3%k!2ȩy֐˯*=r@4ȶ_ !}[(ϾO sM0d3odx܆!ckȼk ٧;!gbBN 10r}[!OFܮ@rq@fARqrley^UAY BruP^ZI,za m~Cȿ AAؖ7BP\ bKP& ʞBlp BoՙPc ~B"/#n;h cV5B87O醺Z& ,>XcAxQP CĺJ<߬(wr X8Sҵ5pd=\)Mk.\/pm|\ 2?epb\cfn^-Y ua/6vsm Z.-1o߹$Vhwi.ڻU#C :"r)UЩAX_h;@΅]= CwXCWGCϟ;z-CF=}@& XC=AgTx y ܖrz"Įp 0)~ykAӉjv\Mڭio\pw7A1pP%tZCzt<\{>_RoHK}uS@ݣ{pA6.sOT'P.*r2Tg;ll ǡ嗸GB 4 ]'\J V@գxPU *#^CPqj1TBNq-(濖*( )O6PcI([x]̷#t6 ί<:堪TI߄PGJBoPxo:4@PqBϗ<Ƚ\ Ȳt 0 hHҢ R/.M!Eu!=9D̆Iڙ.YɤNGp\-~@%iћBJR7q j9'fBb*!fl2DB܀6!\ r&OOB^7 $!7?#fBXWs!,-/?h*׃W'cVMy>q ," 4 q `{`wÒ~YXTO@X?y~@V2,~ Acaa+u`qp+L#` XڮQ0g;G"#X\ Lu TA{A,H3Kc0xگ@ P㻼A(U;;=}5m^`h:cu+`19SgŒu0mN>LR)` )qA`yL},L zg0mҠwиԸ,P 3*`bZ eaBnPٔJ'@qQPͪq֠ td0 ;;P0NžؼY]0A?F9*\g{' e r0jb0o0zIL{7<@B^e޾P̽z˽x]=ڱh:q}\k\:هrm${DG\/y38Do ^p=ݮܝ-ܝ\[Pk^mnFp\o+|'7ಎi R|ޟ e%ԍ1(~];Kc`߽ 0~ H(4q긯!߹7\+HGԸc>Dg0%L saPuVV.0`( A$`rmL2,7tY ^58)\s21z2j 1 ʛq._Bx k.:B̈z8-ί?+t؞ R{!iC (~ -s"O@x;W&o;KMmDJVAkr8 6S"%a޺/[Ivb. |=.{\)tI0x,]Anato$.+KWϤ*4RsWk2_ @|Q@!ttg GNvUl]ݸ;kB;G jesmUT_Mg(*4źɏk!YWN7vQ?h{[ow9Ҡ?z}o;Q{秱tΗMD=6+]r D5H};H*z5753j2= WeX qK(\R)!}( 4 ̃I89uOAⅡDʠm\$!wXׅgfk<-[=Ҍ!W_8z"(*{ 7zBdH>I.u=@rԬ (R>uӡx N8e߆AyqTP;[\;6g>\Bu{nLzzڢΛG7 0Zq}FH#Owuipu#i!;P}4y1 O,f@%{h@_l8 tvЀg'h{, BҠ%h+4x?HiȘ"bCkА$YK܍!Onu n^41FZ`5|IgǨz5i FiP]ip\6 Nhr%x4 ~/>4i& tnGM4^ @Ҁ45Jm1'E5PI% nPyei΢!ԫ/MCL0e?zR?zJc_Q7tna#uI=vP[K>N})AGuQ[[q{u+̧'ׯg` BigDĜ_G\?7mb%Wi4؞b[h4b |NghqC^$GC/a4,F(Nq=4ID{iK#pgyA>Ѱq?FwӐѓh*CO,Ccѓmnix7<ѐ=io{H4r jNCgahxg7=Fi4i1!h4t6[Z?g4O htp ,A *B;(tDþI44NK3Јi#42)FݼGCq FefWb 1OLy5&|+=}FuӨiuWd߮~E4npZ2~v՛hX# C=e_LwAog8c40ZdlzHN;Rߜ_z/:N}`$GS ԡ>=bt^r=z uNC]4h.za'^ӨC"YKcgM =d=cSxzݟMuYB>KLyL7ҽ HC~Ot* 9'kP-u{@kRX?zH=촠.'o0M^Pi3 .u#|ޅY~xnp:oYAܤ.K1+z`ҽ?ȸKBsq WRS'ݏH|fVHi MHs"$eED>djG!Mͣ!ާȬJLɜ{{k_{z_fw'^؝R=aj쎒:v ɰ~gSmFؽY2MN]qpvz*3_S`d-`f`y{_g=X*`<߲{f=Qf߮azCE7fca_ X?8#ـޭl}6‡9=|U=a9c' l"6Pw%I#!X IbfǰA ؠ(o6_&Ul`'$t. ZT)gu'68!ڇ]dkYl Vwb48ʆmb#,b#Kah6"ggKғ d~; eوT sŚl Yφ=Mra"/V>b^ÆW) ss`#6WG5ә dcαᦶl)lld ʆ5gD*lXq6sM\8 {48ub#-b#*ȇl,9I7f1|8Mp] xL[\zFG6ĚMLeV{/8%76>y2{ fƙ1.le6∸V7ب)Zl3G6j!3;kYF7D1Nl6vs0` -8G6&۰6^:M6FU F{.e#沑lq}6G6q!yx|ؐ6ޒŊגxNb+UF6?FF$am$iE[l.4uoY86xͬxet٠+b6˒ }d$H 6b7qQC^(FXQS'Eb`g~*}iaC7%b-eb06b%qab ll #ֿHfS.NI v` b#5~[؀#X?ˬߊֿq"4 1 |?e } 8 .ִ}ـ'3Y,dzΰW]b-a}U^>K؀%l{6PXGsـMFwd73ݷ?; " R^Ud][ׇٽGY_։ݟeob6sg7Y`3v4{Pi!C_*_y@upeͺ5 X-l`}&$1 + el`{G٠}K$Ǟ`O˦;s٤ش {6%2clěؔ歝8<9%|$~)F"/Iy<6@щg)yq<%يPzJ_@'^HR=:̐R_MT+cB'ԣVC'W[RiJ[G'1JRjJ dLJUH/R4mEʔ|NRf:eQe ?(sʔv\9C+)O? 柦Sn [S TnHCP_U*a-UmHU϶PRES+Ol*uTq*;TkB#ng;"QTl&MD-ӨeTLETtr S 3*Lsx_̠TŘD;R#HO`A\G|w:5ƎK1~5K_#ђAj J;HE:.$:JW/!潤p08-Tu)5p#$:5 6RCD TfY߉ #g č&.T#^p)/iTt Rmx-;B/R}}?OuK.fɎ:T/G{>yD&~*5 !!qn-n߅զgz_{Dgkr@J\M$ &HjI"]՟UϹ@L+_:$rQ!xF&E'*Rjo@Mӯ҅jf?.Ko5?tu9]}xzk@76Vɿt>]w1 ;ZҭWƌҭ7j(t_j*uo2k2D?Mǩ;uIGz<6G*Iꉋ D=D=S3"XO]M{F0?ϣ@Aݕɉ'9u}E[z͛FQt^ N u>у*8Ez0=PLKF=tl[Hwѝ{ AeԙK] =XDwWe~QkglkVNjH[=m,-ڎGQt{L}/,j:dmw9j6o9Z0U"Om˗S{!Cmt{m2S[|<ΌQz:@8?S+Ԗ$n__?#nM-j ˦GdQvj~.OJCruj4kCjj#E:q$Q{Lu B:RNt.9stέCg좳FtEr6i:7ڕY:)rHUGQ]Tr*=UʉW_a3:k1U)өT'K;|?*MT>m,2F*;HeRkW*-OT"8*+Cbl8ҝJTFT= O^"CTx¾SqSyjbV:DmG/U8C*ַP9gALv/ 3TbL%ҩRP E*Ѡ’:U&SP4mTmFEgsU[TpT"! dkN>ҧ ]O#({;Fm#M6rRbʑfq_MxI9f"e%se>9NKZ)?N9ĈkNt ޭ{'RюzhQU*vlTi/EQc1D)? 27ҩ#p]* ͡S&`VTd|x?9TZ ⶝Th$yBnS;d8MbPZk*,5dP\*'A=*ʞT:TZJVRq1坜Jy}ZGO*ZBy(Wʎ4DPF:yw);Ślʑ9M3sGvҔwGMt2c(eYA;(ǫr({ J-g1$<֠xєhRϹQr ޺Gf(iMS򖡔ӋR(2{ZFRvEQ>JRZKJ5t"0S:QB?ӉNd%St":NQR~%5PCJ5YFC(5Ru^˙R35z(JrJy/DӲ LK)P=J*=@9+Z?QRq/VNM)%ΥBlEK(e_@Rv#՗T%EpC5TR`AFTq*?QU ՘_tF{ UM:T6?FT+^__QwU~ET"L78}4kF0ji6y?jҙ*g:>νWsWS}InP}M'qb.q/5h_K^C wID-tAΔJ2]GW6st#].U5ݓtf](EW+ѵDkvtsk&nVVj%G-b)OmBjpv^nv@j{xN6GwS e@w?{ zAEiy:{ԩ3(НVBm}S-欛:ļ2[}w]+r<+eWŊotP`1]S,S.P2jڷ.}Cj[NU(jEl%)pUЙRxD`|#<ړ^B +KԳydh&:TN5FjEOv}J:MiOu̓A;M#Yhϐ tH'|즃;$io }|}'c 0'QO{&KCf}X&}2mU!Bim:e=MM/iYiZFKvp'7iZQF?ob>Z(Av-HRGZf=15~oh.ćVCh<-~"Gմh{rK5_h[}Wu' Z#A n&SorP%GxZf$6Z}\LҺ}Z){PM9 r=`MD%ie.=H+#I#_䬫G+&D4uoZk9<8N/&uY'%']x9LK>%0w;ٻ' -jHn ?Gs/ҼYD˻V̓暮#%uiTZ:켦I898[Ғ@rILnZϷk:9~!iGeJr޶z ȹt-4H:Z.ZhEZ^#drl3'4a%D'vU [dh4%;d,ov -jŕ&AMhS_xW"dNZd{0Y'o4 5Vݩ%d#54Ln##SiL2# p2Mߦ93uQ0 +w71&T!ړȺl~Z0ى"}4k8q4;LswOK4' N&;_HQfLk (u%MZM%4y鑳,.q 6Lg>s+ia;0:&JW҄g4&BJ$lAoIIѠI:;8n{OѨ k7iɤ=749yt.%d|?ƿi&}Cb3xFF -M<&f&`2LbRE44MhjIs=.V^JJK uHa%%JK> >6F54n uDܶh5 I#ZmRy܄HלǒJR1 Ѱ4L{If ImCruHVInTQLJ$c{$<_op@z}[va/S>^xJZx+Dx}էN›W[tV66]^ ^fۆ  ~vT [RV_ײO o-ސ޺wZ~g𺖋k+„>^!UpUMY7aG'兯 ?`ky ~&G%H{2=ō zl_ؗo5_۾ "!»$=Ď<h2y5|'I0%im-/ ?>&FiF: ɨ64e=c)1%'yiwd1w举fK'$bD[}wS9zM>ŴLE*_(؉6g!sR9Em:Al7U/EwQ]mhp$0'%2q8ϪDySЬRZc{~Rbz?~El;l+6n3Pe+-?Y,$fg`CudXҙcY:PB64,g&q,mGVIkXY$.ݹĂuqĮn31duo^ G>dOaW,ꑬe8V*Pؗo\aw9}cv\7ِ q ; RZb7GƳ{vg:;|;f%|Ԟ:^nf;OgfhNQ>TVQoGEFz'ekn[WяIe5PKD>7eUPrxh pſͤ Љ_2TE-ut:4ośt-ʸ?#Zk-bZWDIoXOg[gXl6 6omY[6kAw5mm3zr9y(Y/z:Z9kބZֺO|'%kX)Yk=|a=΋hCCѮZ4Pb}KA;\v877'hVgYg C{TxhB'jգ#p' qJ<\*pތ*ܹj՘Ю{N0Z:mq*uZN'r8飏n[[ݧ&u=qi_JAOİ85{1KKGh֠ɜh .}Dj@#^z×Q(6'pYTYV0'}O d]EU^YT ^{Eٺve5 =qr*Nځr_WqTWJzt:=@qe(4V|Q GƭGn3xQ_zru&|k Bm8 NЂ֣]϶o_c"'2 څ_A8aYxi6Te*|0fk1osR LM*< -v(1nBLHmk(Z"L3>FvH/z2#·oQ>Fˆ3f.~˂ƕ#`}gt\,qB;n۪v\AP &qs fS04973CP;IۀV%eex/qs7pR ZtfHGL΁aXY<׋TD2RE"KϹ-KJ8x!p(.AY \Y(W͢ /0ڻ!w>px|ue縛s_|J1pfR4í8G? ^`Zǥ)|7'˘[\zTۈ =350 \N*/ 꿩>]lц Xz0>KWecU/GPh0e=sck, v4,zA\d7o}3 gV˯r'ۘKa-lCmCnN!HVtL~M .Ϙ?=kwM aP{EK?޺Lzk+tSUPhUxB?NI"0*Fux;? aúXOK61z>.kxvfR}1 >9[pĶz `4!k0Wo|YvGnr_4%r[s`:8%/'G2;5P˕yC`'K<ڬer:=/ #0Whf61&qg oݰ$cD")`&o5e6ӄkCI 3 f&q,"K8e"zYG jvV)'`L}9ŝ螞ǔ$xդp"h4B!hRiF P8 BZ<: o`ɹ+E%8jQv5l(I^{ 'C`n]ւ~q{JlR#81LO;\yJ{'4u_ z"!A|(<)b:=1{, Z맼^L6N|'u7!3[J/[=N=oq_f\ &- ?O[ 0ppĝz[K94{%i|cU6')s?rqGb(8,fÖl.Ǎoxr =*nA JMua]18[ b-|d$mOj6,{fr3U@1Qst&}UC>/F0 U+,H|͙ uWQ,+Qz e.nmLZ]+A wrKǯG| Ce@\/݂`svhuH֠-Ŕ^4;⦁؜P^­>ɗ`\4G(I<) 8i/J[Eߦ$C.{w5JTVr%*+̀)a ?ƥj"Q3^AaHRGw훬TA'mGo>fB@}=֠e|;ic~U@gm8 SfrQeWϸ|I䨑C9tV *Z 7(φz0W 6j%"Ns(<'JF")^\XkT^y"[>ێ;*#_Zv-s|.JgJcDܭ"h@9X4A^ac,|GÜ[WԷEDz~DCQdT3HIr^UHj3cDzWы0yojEmkkIqY?BuC9<*,^YV4szn Lˁ NK7̼T|S-2oAuMŅu*x'ݳqSxw¥{`fd-D9*j`a,f6[ clhpfނw016aT&m;<˻/|-l+f}+?pԐ"0ZT*2LsneW]dK3 ˺@H} bG{É8j>([3nH;P`gY%L+|5b~ G'l WJu ណZ/Q T0%ݷOglHAQ~8xWȭGЁ]jfm9Na21pGt~yhlHM}EGEl*Z}#QVI|nτP#h FBψ8} (MF))iQ/L;V}h{::C%!g?q<< GŽ"p|4hf]ep6j=wIK6\=aM/DK.6Ìpcz'&F _ddd>V-8?ǧ8m% et|k/]q^R\7}>6|@ Vp~6.z??[p%T!ƨ ]9ehG]]K#iL@ٴ(GL=}*[wQq; hp;\ kV(3w[ ~TIr,s2ɓy^,_e:\|aw>󗷼31O7\vܴ96yaV(d *ged>ͷ]nV ,yv_2z2ټDjMpٳ~AuGPl`^ [Z} * כw5X#{AR,B$t/GeAjrg-= ӧfgTx ]G')ipf#pe Lkk!j,xsO}0|Qp> LMO?83V> E͛!` Q J7§WpbYJQq gh]+9T pR['7 -yvxg'1hK(Yh@UǎBCT}rGMrhm)×g0<? gWTZS#jEt$. bt6lAg_D= ʿC[@L\ a50$`zmua @u*T<=\^ ÏhĮ84 >n5:(jh1wvnLZ 6d`t~ -Ń1>L0Yn"d ^g rbtЙvyt?BBg885HY ax;AU&w^3guGOkks; mP9S(ʇp;N-KP^[̈́F*P-ԧjAK!0|lXR{@r^HXN.A^ {7[۠]) '7}YCL/.k̟2fWeoqOܯ^̬ҽp,8?60me _|L-; <;)om_kK-abHa;!Oҟә/%b~lɔ|&نLb×] C:[ݲ|F#w7܆e-{) H9p_>>Fnј?Qc2swfHuGFL?0. ۏ`~5$ߦ ^( Q`ijO!U/}Lp`M3 u$(6W5Aa]e@}DD/ $F&# X+0*a~l ˟= Ftґ+[HK\pqB.|+6& 8I| dP07*Fe8T)^!9ndd3=| I! B 2y7KW}<8,ϟ%: ;z`/WI _ }5۲5a{r/J@(M ..V|l})na g[@,_~ ~nM[J9k 621kɂN0CA{ Ѷd,1AKW711LQLtHW5#c&ѳ# \@u'-bJw *s5րA\L,f%#/a|0?R7w^T bd E]-: uEp֢R5Bkwn;{puMΈA#]) /O&§ohxx"6@_'QgZw<A᝘~SK.{:/psI0FyHjeEb9d< _1f* dF2GacN4 }nkm/}ߵ̸Lrf bnp;n+LlQeݣ>b+<h&>M_np$q^: YԀDԬTd[aC0l^`  u}it3<\ġb43><1uҸܴgvb h-Gqڞh&=89}7Nx׆︣щhbZOڬg/*ʠm#勚Qq6j2H̀c޶o]\A<hضJ]@$ c4gO$.1C@Ki #sBa:­($y/ 4AV} d W !hW@ C̈́pN׆=Sl= 2#;fOe5,0wǀ̙B"id>N697nѠysXӽ"s$ |&(֯$`mBpPNog ЪCn_8 k~p"*+C-~2.t[pM$W`_ zr[.wUl:JG@}Y6R'~ )6Ҩt FZN܀St,-j> EͽO;d6E({T bB"X ۡg /p5uڪ"du29crwBUT"cS\4g7yYu22ziH}&)fV'p%͸ߪx/6Qj0mL~+nb1ZhSFb[ł_f` g<?竘1p]:Y `U1܏SiCG%FH |QVg)Xuy se7bt3qjK]+U'g7涌Hˎ *`l j`< -pB!b6iy ~Jp=*yeV]CAqkkũqچ2Go2Oƭy|;x2֟ w|+zpɅJpjn8l &ŧhnAnk?6Y?gyЭ|z<9љwƯKW:1GYkmgGˠj2,ca;)s(-X c^FJySY|=>F9_˃xWlgVHrc y=n?Fi y<16irwfSVpʏðЄa6wf[O*Χ(L~o%}K9AɞU|YcGj^|9/(8yxWI_ v+k̀ 74J; MĄK1 05|8y/?,yalwd ^|~R"I<]Sny+Wq+ԸggpoI`Elqxh]Ձ9\y 陌 ]ppnBA5{ȬrfMN*UtWw%h!Wy/ _a|z>Y<V >m^61~z;N9hJCޚ Q{*ֆ8 ç+ߵ\haO<#ib *'[wbK턬4kU'SayW*胍Ç@ X'_zr [MA7dبiGHY Wm-p.L%Ni!^#yRrkA)pd|Z*pxCȈu-ȏk٨Cv SK LbdyO0ko+gLafq:xB}JLQ{">#Pv-\/5)!p' CڂR8>,ONd5rD8 "S\O(=* ypBxxQpAm?Ӱh1e*| #;;L) :aymu- 3iF,D"F8}0gЄq[M|CQ;:Ξ]x=PT):c g=lgl%Nd .&)..EWDp#.>Wrpc~\^Q.ًh iɉvP_jN5@TmJ?uk^#9PS7N\/؁>mzp'.B\؎^Yوk縩nᦳml;_|0{mTWvѨ ._ƳL-Ǭt<)*3DN41G|\-Ρ<`#f&y& ^.Q8yj! \]zuuCa Z(0F!ŨW/[.8]s zwW mmА&V++uAU1A̺-ft| =`8u`NỈe( g闢ͮts} `06&"%wA4=ڊ=JG4PAOTV VTK;p~W:Yk|N9j$n7w]>~m(nKy/.X>[(AaH_`̱x  ?~)za#|d& pFZ8)b Ei݊[& m:fN |A8mWSC#V5>0ƞBAxI *Gg@xg|U~FQP[8v?Q.{B:ٜE3QܟRn$llqlWމBw8|M  ࢘7e#5 g_믡6HWx@xe)n}hJÊx6o>`Ђ^/dp>{OF#5X7t mg#;.4|AI+;7^ oE1GD5X" ڌΓn D=R, 7MiR=U6rtCeHZaaCc̩DsژQ8e[K}|ѓpzlY럢~;\ݘA^֒](yZ;m*f~hW^O1q ^Ե{ؿ`N݄(h3]P7jn0xp(?uE۱2L0y/D tr=vIO?(\(R:>nd~?VUGEV*+͇݇^8w}U·[*4x ~~wnƛNxkkU=k6~zLC^Xčg^iCPϽ._t3vw)I o=mZ7, e3tkl"NYLjsdY8o ܗuc=_rw 9 Or_<˶KymNpcw@ 8 h ^3[whc9J [814Ymj _l`.e>fX-@:BΔ8}j) Cb-v, Nԕxy2j5 BՉpΡIQ_F3JPJ]^'~ups`DG|7K_RA#lI-cf]NpI8z.nW+w=cS2bХg18fn ]jp\U<W0X__cN D^[~?,ߋs2Q{* * 9wK8lZsoP R]~,mkCz\tNy>dހ#E<=ᒍ[WÓR螬 /ov&a6^ ;S,?s3|G..W!uLb5u~tܽ3%A3y9s9"AR@vxuj|:mq?\Gɲ(Fpc8J_8n'gRQ$ߞ?Ҍ-pLBcHl( ͇{J뙜67(ǡd1U5Q~N$S7aK(*Ʊ5U)YLg8fS0*τdYFg&_j  0zt*?vwpa|Jr0d] 7L Ĭޝ{ jtR<_9 F ܼU$Xs vEӅ˷ b]Mm(d9uQ<<%"ŒP¥~H3'51/EUr1BKEP :Sa]C5EUY&~-\d+i͆tAGՄ9y> *1̀E<=f qQ<5Aӌ( "` ˝o-=~P :jox8go_ Y\jv|~6$eyȷYf~]ܡk lyκJ&fs=;%+ pZzRNϺ2X+Tw/@ zF$ 6? 7Wo }$:qhv j9Qz)_t<Ę~pw]у 1+l$:ahdh+Brb e,D+lzNOw q%h$/,Ӂ6sQf~P(Vuܞ$kk ױ7GD$,Io%=Ev|w A R s ?!1r"(/ʆrILAQ= cox[4^nZ'D~^˄mb2kj|Nz9sF=̗(H΀Aƿ.Z nC_'c6u!I5M)+["?,Gh2ǟ4'3|{ ۷U+<ho\Ѫrh>'Iq=(=φ‡pN86Zã&Cu\Qã]!|QWt.$p_-'q7.sLo ~7am4VYj\a!t<Į]*y9ǿV̱٫3_-XOuop^K+g/^qUӠbNop 5̏EsmYLcd-['c18:*9r3Xjh@AI 6'|Bch^ 9l9&5ޣ0neEi9 ?nĩQ_u\:"&Pg3yْH4Ck0譎~sk=ڻ Ih:NEԋ%3 uoZ!(= ՋUs56rAqLDgB˸c _)::QoE1|`q?JϿ;Psl3t3`&0=5C}{ "D጗7["r ]A9_0k>(1F?Dky%G:GkKn=\,yg;5]|I>!ce o=N|YRr7]PT+P4f1-98W\dk~߭L~͓}\[iA֣hZ&}{pNN\jMްgl5F8qETxeUqZ9BgAπ]P j>4P lʨ_JuxM 3oC7T;/.Aj!FCo`0tV%L}be{19g͇Xzp;dBQr9\ ߢ)khh mky( ʽ '!jWwRG<5Ap=&R A{vh:7WQu/SB-8ydVr<\m/D/ +.Ӿ"WjJT76DZ/Qyk|, (+J{ Ox9P*GAa"Oac!:-C̭8Uk` ZUqFnga?s^Kd!|~"I~N(`^9/?yr?)^k5?.r']4rV6->ݱJ;}=Op8D= .P>b\=p}YAg7B>n3/alp|4G[H~fÖysf!$ob.Qj1.|]CW&|sMh4*}?[Jfy _Ș8|șȨ1`k>v㊿ovOWszSyG÷7GyoW1дTZ-TG\ٔF=@;R o3.أPڵZXUmsZG5+(̶sۘ1,K}.`N$+aPytfT &;+/<,PWy;s{ h)` K'5݄ewB &!~񌥊8{fjt j Ճ`6> ?g1> sr@mJcNix2F\6.{O{=U1}~tq9.wޏ{w|*?#ȆEˑb7%: #ΪV;>X~N?~3GTNZX'L"&

    0/E2cM`d}?[3&0g19u L`y1)[2+]_]i]i~ V1 F NU|ݰ=q) j  Ĺ6`4n񁝇Ciͅ73 UJ.߇x)\9^+PrS`άC gQk$i$6Dr(7+9E];Hr$PpĂlT2?T-hK6I: 3[pY( eqo{ XCg:,X[@>auq Oyj鮅ܣق/1"_m0/6hgL5y\"Ƶ9O;b uLK6BNLȵ+@is)\^sYo'& xQP<O(w { /V2" ڏ:EN!* h·ni&i@x]ȷ ;bA\/. NwP8BEĉUG4yqPc뷠-߃͛PEb%*'TB p(SSCE M#ED^h{'깈'!>)Qe;Eg,pJqLl1xci7?Zo˛Cɑ5-zP6:*gï+:%AWz< LF:&h ,#ueh8jJ5mϠ"޺j(.=KtZ(돆e82*kW|jw(48@h 78BI\z$ggC!Gn| Mvtx'4հ}<,jyP|Pr|P!t8/mFSkb]AI{< 1JIa%,цkl7 vfC>[>e0kH̛{rB01o;J77A +N֯Zf  ~:u@/ JPm~]@+!!o"X{G:Y8:wEvo#|^=K{Q}] w#sb`7$o649AB4 wVCQe,\~5uBCt-DQ9n.hQ]p&(YuPx W?~xZ+}!?QPV3k9+q-ۧ7SY% +!)ȻTl㗝G]g@=6@*|OSaga4Rh*1F8 vH6[ .p;}fY0`q 7#yU!K#T8mѱBm/#nU'qcn8/³3 \c8 _f0 wɷpOģ3}_fMr0F0Vc 6aه.Y !#swcdWES?vmtjMǵOzХc,:qqo *8[ ts8cN8:;g{fH[%~(9j:x K[]:7z (8wTNA^x"8?@{pJE8dP /O88Zxwh3({=-Cq#5I0ysc?hŎCwqFx*aZin0A> '?>*uJӫ(sSr0f#LCިON#=>tAXhGp{m"[aȂ~?(㏣+n*J}jエNкE8tjZ@}h4P1ܲ%U)G\~fGqUqoEx\:1IC0u Lr?qrajF<;I9k1uu!n>BmV҇;mgΩfT\!#jt_hP fw) R=7;+ V2}28͑ /e1$;fobX)e6cmcbќx o'|GnOU}k<Q:+=vݴō<ჿNac^u f1x,V8Y5N3nMitlyiMDDĊRL VxmJFϓZS4ie+Ʃ`wX|F>6>aݹkXnYbY]Icm/m2Ibmt#o ZK,Oi4wa bmd(Ɵ)IXCr>c]O6ėW`f'.;RV OnG7b35 ZƵ#y離kIDEbVD$ {V$EĄ,D%ADDĜ3cVfΞսbElݩB${=$ǢE\Xx_0w˳S 3XD_![a#SƩh2FW/-Ny紑cGNHK{8l| mMyrhg|}eA0mxa_8TzyJ;0\"1*Fb s&ߩ#pvR/p]X ge6Xs 'A&PfEQɟX:;4܏jƬAcgVɳ庬}*-dA/ϐlH/x8ۖy~fZ8[桎SṚ5 LaWa珘uI6C=9Gc@*`<Km3K1_-m#rNG+=D<κdh@XTs+&~ ϤpǗ?a О\Xӄõ4`-,œ>) [1V0+Hfͱ,!sܝԸw DD1Z)T.fp}v;RͪyV bL r?,pАhȽP\(]+-nz(*POwϊϏ=}SJGJn7\-=bN\"6^=@wMx6%<`y]Y)V3eOdb7o;+6,i9vea<{$kb`:2\ꇳ!?5yxg|>*o1{g&FD (peV񬜱hJ➟`ǣV3kkωd?Űø)݅Of!lؽdȽl7y=LDŽ.VQzm,1?[zqlp6oepۼZHgÃ([Ь䣜rQ'^s.SǧίKhg>LÇN/z[y3xѷ|E~{~ .kĬ%p<)eũz.U\5n o\xLIQHdW=ѣ|\+>H~;jۈgrD[.l>os_µg {˙g;sl8b[b"o\#d(€avE`]'X~C$e|l>U.zRˢ ŢɏVko~I^64 OU' m/ N"U_}>"brSUDrUX{'%t,b;ٻ%kHcož;؅xq{G_e.}͋䲸еX@I)+]p/;{G~m:?ҼK=^Z#KdHݔk:WܺOaFgRڊ*:E_YgL-=21e$g|7Kۚ3ąYs=\ߩ q*4^ 4` V?w{ol$w@ڙoXQe$zf ®|h9:gUҌɔcWC)r 3m_կn}O+Mo\[vS(ɵNtr|+;z[PE(L}6O wnk-jy[d֯m0zǝKN37ӃH4纵,Y;'w;01R+n`[pȶN$]d*EZ[C]&~*z`(9Qu^5iLjmTMxӖs*^yrOpj0H&م0#iܔb >=(oGKT9h r)ӏ8^.r׹}㇛8Mڍ/!x:N G3hzm3]xp:lp_a?ƒqg8\1 Wpb7.ۢE6.ǝed GÅ[8.qڵzZnȧ(RPc n]Y-`%v|խYaks(-9=-c_bW1϶`GLڹ2&`_Pf>c?B>c7gnϧ20B`QX1'ec!:RlDk@A]D6 whC!]Rao =3q*{S7j Qux5zT@oH-3F,ĬC/HL|dӑJdZ#9nRb o-TxBIepG YM. GvyWmC^UBX#Zf"F#@G\|#Tm$*$#$ yD(ulF١2TYDF-h|!O?-GVzZ 2U!)_> (`yo-\, ?hSA蘴}t1FEy\b Cք*$I /Fvۃ8<j>>Vv씊?xv6g;!OVmŞX{N a1&t,=WYSl mYVOWKg!G "uro!+ĉXddllA8W7K\@؃AoX擈ņhIJ3w*i5ol3\M/" hWLF.K}qL% a:.m0JN h[wͺcP؀ZCEpPFIu}iui_pP' L3sE Pc*ߠ68VDzp<M9h]of%47UeD?5ިZSᨲB8~',qsI4!3T4wJWQ5U6zU**C 'd-.\pJH؂iFi ? mOԉmj'U&Qr2i7CIg  {P*#0IHLdHu祈 cDxC;O}SGG v"2\!>qT[Gd fs*a_&7·7P^;_N{!;csuX1\`A<-UUpz-"G{YuX_ 6f!F:" D1D9~Q 5,O͞r{#ܝ:-^T-^HS |Mm2bQ?t9:e^^)W _kݴx}|\]^ćW Ώ=k-懯G O֒yi}uCDž_uc Ҋ__e|)G~s9):$6wjOFb͖Vn=];h=k]x43ǽLi-5[-B%e9l5no#.kVQ$cn,LYtq߬[[О,S= I5Gw9.4?!?Kc_~vXV,eiv46R+͌l׿ wM_L~K|B~>QWߘb zz5=dT6Ay2ԫ0ZL; W`w'Fn V(L?n ^Ofy.{ˌ=Qf_*ADC0/Ti&2b20`(i7/S~֏Wp, ǴE_*:eET1v[֗4;cv4˃<;\ )~Z}"ϵ9 \Rβ usWoeu?X#bﳥ1a53#=l3%jgէG.wTeM8.rZ~%J}wCVx-+5?^||}[>S"___|\̿:]֐y{M,߽+oŗ}˗OlO;vzus^{f?[?t*a*:h\gqI\.[}g1øj`3 e{Uضj'\MJh"RZ.!lUu̯dFV:5`=*٣QO'^w^_P{#G@՟P^ _9GW'ή@Wf+?#0j[2M.gD̘|NGɁ0'PW~18emc5 PR^,=o$ہȄ|ĆUXYEU"asT8CT!%wm$P|f e#rA^J%P'T.!E83'HXJjtqօϚ ?e/77nC6<1WAzD(bhl o~az[LZֻ%LH.> ewMu vŔΝXzβ -첒>4%͚e5WY.vx4,b4Gm\/VMd>1L\okeA{}:}`fWX=,S8[⾎;ȵ&pYq;9Yk]Z\˂{)w)~A+R1ntt d*u:U'b .^a{B9NbߎfoK5q6{A(c8^+{p0bK#4IacܺrlPc?L٭WcōIvKaaK?rl{*.v2.g]fl#;rk*m4qToYg>[ ڻ5Dʶ9휏r;ƥMŭi2όo|@[&IE;dTEyeuӢRu.ٛKsma.0"Ifiz}[YmV]njdϺl}HgzUG/S5ZŢh̢ڋMZφY0%WjZ .<F?n[-ΙKU ]>eæ4]cΑ6lI,Ϙuz>$<àI5da,Mw:P R uPvrՠ8Ay0p^w{ɮzX;u,ulPegz;Y.z}[5dg"YJ);`M5^f&w{_p?Q¿+ (d % NYn7&.?֛?7$>IX/|;#?:q7 goxqCE߿>_!{VaCiHm7n5 zlT(s%js^sUԱYXͣ:6+\ezs7?2=aÑ_旬"y,+Vޖra]ߋ. iݐy1 .BV5AEC{=ݘ$]ņ_ewLoXOk3.f\M#Q_߼N~՛ >-jaqP^ew|nE{G^nf|e GI.&=/,\f69lh~2 ,E%fv''X7g^ŢdA+i*3f˱Z>ƶ3Dك2_ɓZ6bSZ_frB4wI} WKp]w\h.B˫͝l~J53m.ۺwb2;[n' pc*rҦ͛"yqk 5ce%/9/W)j}&T4knŢ">+\ԜQ$&6ʊme/C$Pґeޒq39}".3VsF#83mn_~˨۫[Wߚڡp@ԟZ m}VO$aX=h.a" {oZsM[芢~wj S l벰:@a [AXj%xo&욼ABJRG BKpHS88pP=X88B8KH/$mEBB8vE -D9!D-Df ۄBBz2|O5TؕK6HSWSS֫{ >AzÅQBB!jQ yS?9ȪT(*±CiByB_XR m}BkxYֶ^ ɬDB~oW(P c⭭Bi@P~aP5PIo&oԅ B'ԭVjG 5 ڥRBkV\~;C7M,Tg6 5ڿ_7BcGppURG8vThX)6z ْ™7BϹ\%lpudEpm+FpcUj_baprжB_ Z34AwU',JWBh ᨹp4QT.M& u.Bcu92S~NXgPp+ẘCn-:˅띄KfPp$CxQhjZ' 'w; ; cRZBh~PC(˴JOeBM;TaPrP2>C(~*'͂pPr;OP1U[!+Z"4) NImX%4ӪF&WBG څB++!齔:pxf]{[? GdBT!н.%^J}z_'l8!6%k/LF_OLC|+S 0o7|[ݡnFw%oAC b ,* ;څǣ;i |uR~c!];Lf|Z#sl= ?opAKHKY K6 +KO*a@,W[im¬#nd?ap}vzTj7|-H%4 o +zm. LPh`|J_#L) qX/<5GEP)U?PSJ/'ї@֞6U_Noyn|>Z?? l_Z3D |MamނJV4zTP[&gW vٴyqQ?JI2]. *"^'RҼC+U'Qʚݘ؁O` oo0qXgݍEމ}usAάQE%ZR6:L4*5 +Iɬ +W-<E~0rqv1#?sX>Q,\ީf/ֶrZsx>E5wd_>ە/ǟ8i[OoWC3ھUW>f*ހgցQ~|ߛ4WQOW^L{ir l.&5pc۹S6Wvdp}5AmPm׎5Zl~2q8's?~>y!U!dA]T*H +V r?RO5]PS<ױ%vG VW^M|Q|fr鰔5i/>79}/[[PZ5rThhJ_k%JBqAFܬ7<[5PThʖᢖn~6~.7^JAua0L0O0ywW0]/3B`|-Ap_uP2BBW ZFR{FVB\!2!DG&7 n # Z‰S? o7*ۅZNpapoЩThOP:F8prPe,dx+$d2 BX~@!{&ĔfaB0EQ0|uoeO:/k q[,}lpμDOT/3'Tk/'HF,"Ҷ\6H7/[!q`P%YNHM#Rvm݄ BBtk!٘ YKՄ5BfDPPJ81=]8#m)܊0ޏo~ԇ69m9mJjmCT4T渵)7k)hi!mH𑶡nmCnjM6m6U _4 ."t}"t-lZ /# OjuDI.x&3K /6%mK)[iSH|&Km@أ6K¿}%sw[g Oy O}wO$: o _?K}6h(lS 6$m؋65mgƨiӔjӸ6A5mi6_nmRmnX6m6-;6;ƴk9LFKK۸&^6{_۔Qۤ7mb&ѦMC5mdQEWmCrۆoawM}F짶QsƵM,n6TVݶ1gԞuܦ8MWM}'sv!m %6_U_^mR:2wL6J1m  FJ 5=&GW&uM!&mPelᗭXxz9- _Kw?sL4?yd7?r~^C$V-;#9Êc+_~˝U*x\_x^{g?JɃ4?P/vobu>!mG~;ᣢZ*4ϼW/kySmڳ+Zt6YylV)cN;V,b.u6h6!"O ?fτc(e cyʙZ rK(+lv*;~ě;fMY"V:!+ ?X t4 0{٬ÚnKnaWLؕ G[_^*]1YE.\:~+ Ks62١CY~ ^1] (*Dk`B@.h;85ކO8'Ŋ3,ҸNCsg2F4$fz=2pp-j(+^Zlg *cQvo,j˟NE6ʍPe q|4\;g%?Fݐkh8jDh|O'N~_`s8_J[B8~]ukRPs$*#( I9g0P{5r2@z@Xm6c}[XUX^=mKG, 1͈ۺ`< ZQȿg0QXm< Nmkeamd]@)9!lVDOĦ/,;e"TGv=H6oېT#a[<ļpecDD{D-8s==K10! ñ?i| '1+y\ۋux9z`j)}$|-5ڀA׬7XӇAszI={=Wп͠T eBjzk`wa1X5ӡs3FBrG8g}DŽV i1?ǰ6 uM1L/Qգ&G؝x Ᏺ<GjR$"c >1^M)uQx/ʸ\$e/RWoŊXI!zEbSB& xW"36d_?J>`yʆ`nfխ_x>p75xp$E DSƎQCxVDz%aTh&}:y,Z}Ll&g2>y?6=)"[pKOx:"=CD 9m9bH"n^!Ԭ]C<1SM{;m^T; O{ P!Bύ8,'q2BL ;ւeSbٮO_`.Oĺ)~z1{&`ɗX݀%cA#x!`KB56sX5 kf1اah?"#Siu8;} {|I.(-,u3L6amPmF-U u0Z=5MкWq6c ^Q wfߋ # lK9B7H"<_Co@GS\-3F"hT+a1 -"F,$1W5x"':a԰ueWNbm:U_b,ڈYk=걶 ؘ KVc ̻X]x[S5{7a*MrZ[Xn*Y${ay5]Fx3N5?5vވNnt>-XXP|? CvB~$(_W̎%+yB:9+( Z:X|aT? 3;m|6fuz `cUX Yn&@g k!;&Jyg:fkb-+0Y0d)EY 60Cž2M"$F91q;Ɗ1ߤu ٥IKe{= Nb:Oz=#ٟUVF~2&\̜;Fuaz"a &2m50ak"w~Ձb 0y vn,JK4o\GqכXx%V[bU`ٵvLKmpN8pj XaaSؽͰ =];qy*|^uVs4kGa͙Q𵜄<6`IO q4s16-G34k*x /(\^U7H7=sDf̣"r!7&rZgkJɴȖushob8ny-wj{ӛBTEfzBQ ͢,ɢswiowx|$E03rhHZe<Ӫ N -'ӂEufr~gSc4Z?JL,qWl^2>'3dv, :j-ܡ4'6>yh`Z3<?ilZE/Rg2vB*ЪpZ=C3?|h::{F4>"-h#*BߑSv9޼@N;=hrI-6@lGz uU͗0<02B28~'qn# 2o]IS|Xr<ԉws 'A权^=|D'D=ad1cYŗ.o.Yf#w?JV4*Y^&r;QK7%IŸCDkkU\Yu&V̜.취T99r0Ds'[quMNtm8č!7i>;rjJw}h:in$9|M{#Y(™dΒ8I~Fܑ&b!Du?aJ쉞'  &FH0r%Ѷ6sDEz +&}NV/%"wdzY+МyiNtK!F$?d7!l"QOVTG z YFV9d՜l>́6uSd֐8F (o9DV.edY8[)OVKMzv$;r&Cp!9z呣D=I+Xyē]A6;֓4gcjJs[Y{琵 9#?z"Yƒk*Y~P%?ůwB!‹dÄfO8I&[tY < dd_H+HGw%:7%S'}v{!/9dLH/ET{ۃfЌHWt֘/sv-N%xCҵ@si9rt֓ЧIY\wǑqxlhb2L%ΒY~v2r,'CdMDG2]TB#Ӆ2M'H25HOT2w&ٙhd:d딒h2MF ?ѪdҤM&dNdlei$Jiٚ1odD&_4\#86Ư$k#2-2{BU YzU2vEwHP v$CidT(+b0='Cd[fm!G@I%݋H M?@9WVu4&5/ɣ|H;:͐Pʆ4sgqfND4}Gx<tfTHS.bOGTiܱy5FӨ#IR381: r+&Ha+6"$PF2h2=4ZLi~;9J<>ITmIպ' _wdG$~z=Ǐq)Gr|/de(4Ⳋ>ƇGƦ ܳ~#D؍w.Y>p \PED\z@Of߻8秩ܻ|=z-85gB׺Y8}n"c!eZWCKM4'q 41?h<Q7#jnBueYacA:>OhLcΤUJ*Q(B"4c9pC^kǒAy j׼Qx 'f> P(mF~XF~(H:"(EC"(( CAi!U. Bk%rDmrT#oxc(D^ OEa\M>e(Q☾w%F_Q+fT J2Qvh lCz-U, P8Q)BT$@e Tjw|C}MNS]jKTiF͸ԤZf@u}6*ZPg2=1ƒGv&j-i^JR(qqFBjD;1TA!4G"T@-=Z'b<'~4=u@͏ex>uh47Fc]4Gi(b96GNqQvah|uy#N-/ƙw 5tݹ^8q$ѕ܈SQ3й m dG{,:-_t7|бgzq. g,.Bgt \@OX. I¹DEי y>Os# jlrEcS zruq z[mq5+q_Ϗt4spqzί9:[ qqZ.=jUo~uƵYkpR7>0#7>Dn7|pG/ ] Ñxx?-÷]{ӍxG^5v 'g <{2 ϯ?=x-U|< ԼM&~*6$1&w!AIB1I/6#ٚK$Ѡ?Hi4hZJJ:Nj钊0R@Cl hH Рai&Cn^q}ICϩа @#6^R[cEjcWڦPR{K#2iļ Ej*rCMh'4X*H<%tRo#E0gKCMOI> ѐڣbNZz5)^E[`; \]Hr2)o_Oi7!OФXڦICc#_w= ӘN#1Iyu\4;&w>nCӌ3^4ぞVu#H7M=9^m)g#h1M0T^S7Siȃ&1dRCD2s's;͞E=k k"~Duh]1AbXq}TJ+θޏdFsUim 2"ZgZ6y&JIW[њ5qL3wܹE.i U&4/dO!{ Kf&5̉xZlmR oІs Hu_]IZ.{d۽"ƛw|̠uhMEy;i񼃴_V;N+F{rCC*|Ei>Z1v~d{ "ǯ4+;`Js"Jdu(^GuӜKÉ8HLܿ BE2S #q=L _U L_DSwTӤH[n5M;&M{4]&HRwr kInҪ%tR3GIn6FǑ[Rq%irR)oi!ii`v,Jr[H%I_AZHI!9$"֥6HKj%HZfIO2HV/ gH*$'Y$sZhHxo0I_'?$dv!4|II2IWIZA3' q> $$E g$ȑ$)%et%)RHyrR'ſiP,!4()dCHvzяdG^#I AR{i`^ג̠`dd)$o>"ZGR`'HimRQi9)&O i5sV?=&!Rw'4O ݳ4d/YՇI4}>)I&)9dFh8LCX$O![:_.$ii|+RÇ? s]| ue ><&)_FoIi[|/}-q9jo, *{,X O~ i$qy!I_Hے HGҀs h2d ɤ%IZ5$-Jh$JR$]c@OPKGէ$8dV'CH,{kL[$Iv1"٧$ȗ @$)d2Hi*+ۋ1sE4j/ lL =1@U4p6J罩_n\Nߋm$!dD]EfuO3{ #ɺ4Q?$a2Ի\ݒ$}?I*I𺖤$$kF2_|CG !xyc uVdϮk:RJ; I#)OzIđ{17㲳GߡAIl8PАM4`&01G!Rf4ќ^'=]@J&Ӱ)[iHs`w Q^Mix9DF( yH4-籛J#?Hce}Ʈ\Nc?x5Ҋ_@nN4F>4hl?Oc?Ҹ?4AZ&O ؋HϞFtmCsho;d0M)Ӥ0'%dH&y%C{aW4C)YR9ѿ9dCUcr=,4{r'DGӲIbGQ"%)<|ɴX ēK4p iNGɯhBeΚ@%A6f4~ot&کfTy:I?>ܛxv+Op;Y o2r|,v|wd9"FJĊXP5K/#d}#vƢQQz6ofklƁ/Hֲ|SLa,*;NX=c9\f%'؁^,ѵU(~`ڙa |'sod<8[Ҝend [IL 'a]Lcyn5&Lyn"S~ Haݟ^[& !5)B?.Wg+x) ph.RTpdFR\¥/C̓[UEd3X;H@#.82 ^CF.aECҒmb`+" "`nf'hl HVb=M3#3A!dc1K8Y(6V`cr@K=םS]oBxYa_X73 N`ֺXv}1Ci&yH1t+1S:`w5p8%;7Nw0A #bϬq1l¤&79vZb 5x{݆R\{>q6c$!/0\ǓG:γdhiۓ#gV0Mf 1I-4d8T~RWp:PXSz%#tcchVh Ph 2ha$+rZ{e\,K7d,"K'>62)|k}7UplJ |_ƦţuPšo,.Ԁ{a3h|`oV0vi`WLGt 6soP,g F,t#0͡ +Yʼn,"zِ[`=Y 01F0L#o202l0w OeQ W |﷑[H4 'xl.no eWB~j.j`>_߂OV*%g(ԺLhOSL8]&=IoQMH7јi [OII[m&Hk7Ɠǫp.4Ԛ?(y#s2Qzuq2OVCH{ brgq"|RODYO8m:>y_rpѸ] q$$2g'dq'EivY]r#2 Ck=JyeiS7^BŴH&V/ekȵʁ.x'r/O "ŦMRkw{I l C!STWANSڵ0:PHz52|mYSD+N-.} QcJ^w6ru"<}&ǽoKs݉@/&-giv[/d;L޽ dSD.'v92ΚlĐEDS>"WI ^(a6%dt0 ;FNCz;pv e[VJWCvᔬ;P\=|Mq)nޘC1{Qz',I);>O%RdH]I-(zEK(lOQZXE(bRLJqA'([ݳ(.}!ŏo)~%%OGqU0?h^pҍZP7w={)>=St1E=k)*En@w >m q(] ߝ,~-%)ףGЮA"ǝ}WS~m^%;7V״^*%#:Fk/-br!Z9JR4f"9&@9*"ljwɁo"=d;$VY? DdfEKW!qCH'&}MdA̗ky,[Zj2MԕBx|k1 b'*AtG,beWD&dIKɲ/,>#p;JK kd,L—M ]W{(lY=KdsIl"t}{nN֒ÚܜVrFܯӾHO^"ƓW|рQ g4:A_QOkObdMZElW@}bf'Տ̿<"S dLȯ,Lϑ_}|&y#I#dtg7?Ӭ&2R%ïp XJ= ՑnVt5izϗ#i)|?$471}AvHa͐KKiҾEi߈!)4Us)z4e9܆߿DV~=< )3iDR˹C#|ZHU/)W~$K $?,Kpm'e$%dŶޜJQ4`ncy|RdC<ݍ78-qx Yynm&f>xW7( 'Z|zi7?T|=_G7)U|7?}će {n)ˋxs(}5~/N n|M7j'\ ՚SW8$@?؈tEס{$g^3_mq:n@v@-K\< O5`X0E5;P=5Q3V}֨X_GpTUS?)SPuz%*mjukx*e)T DETȠ`.SAu)jNifYPAU^jPPTzQ[PUzƨ\aʽ(2'_Zcs{~ yrȉ.\P9"QXEPpJ2P8A .({Y4CM@a25nE1x whEFad "p: &;@7 6rWFz!rB΢~!;eYf99+6⋼?P4-F7(hGގ_ |{P!(19O" {`$*`DCS=(п(\P?=Pk{P[[PxS,AME܅usgՑ9x#$9b[#r{`F'mF"T/pEB݆ YUQ+QY"dpg*IoPw 8zv *.ɠ|*>*;\=q(&drωeȖ@VTdEpd\?# '4yb$ WUa5{pVL-F^9 Ԑ#LqdX#82Yሯǎȹ1ٹp$l2\AFC +aG"rQr9% 9>Ȗv g!alwF"W8P6ܒ;t$rN^DοȉbC3iJ@(lA[.>,7uEFDCI$<c DߵW 826?$Y_U? SpxM:Wz3 WN EHqr$^8YGwq12dNn@?Kd,8Lkqd<#}<u8r)uL"3#rF @ i ߽ P`Zy(W+,@(eP:v dPKŢlmDeqTI##gܳ{ޢb1B?(GU({ %"Q K:_HGޞ([urX+<)>K 2lePWՃ~%8!hnWAyGEL%laTt>iQ;8^ǻ8<W\ZqcPܸD؆[rpkT܇Jpguܽ{uq'wvS55{\]PyhhqG4MT&3&D5M[&΢J4q-Ϳ|oo-\--D֢٥kfga^X,&-f]Xl$l76r3r|pU-5k{qGp)}pN^),Mo ن=Ҭp-\ $T_$Fm!Bvsέ BC 4.^rq!&Qb«~bBg"{1I1>GL=$7. I"o1ii&TL~\L$&k Ąbr"_!& BĘ#:1!1X;1$n-"1@-A_2V Ҋs&oLj!ފjD?(vGp(Rt|+D\+ڔ?K"vU5v&s)hi"x]Cxu.C>c#BV; 2rb}vYwu;vayS(RO ̈́y۵&YKX =e4]m"_^+ 562D;Bf[Bva?Dw 6BП#i KӄBz^w?o}C41z m"( lHWM }l?D ( ]BwS?@M`N,t}ۗ }BZljgyhh-BY[D }ѼT4;F vp,- M#wf8MϢgBa6N/:3Ng(tYsS{"e) &IE W|Qhy!ZcL7E4Z N,k7*_ m!T/ yO0^NW 1$ Kڊ&ƮBUۿT8 ͕=vOB;P7I6}-}o4jp 1rS0.8ߢI>z1z pd O_&^8+v Cwp l2˅;apܔkѲCh/ [2]UPx#1:v-Э)%h=vu rfZ :4r-M>SbjGAאcjcfCÞd7LW&)ՅKSMދ;U9ާ)7O>Z:yþ^U˵&ƷQ:jIPi5\'JcD=U4| z):򹉦L?5~ ejOFR_DHM*OR$W;~ +Hu1Tcޔz0S<ި$OH 'I?^v}#HJ,&U=RI$ KCgRk]JpYTQ_Ip6vdfQ诩:LU(IN!+7P n\KP_' ):E!.)?(phJ ^I!~)ΙJaZSh~N|nD /)E 6B,0->B(T=QHr3\F)) 1Ѣ(o Fӳ(* A7(ض%+)h ?ON8O_L>Y$&>[F~3 -SŹ0}D% 0Ч)R@x 7Ri PW9L*qR@ WK(~&l@(G($2ur*T(. Nys5) ي|)PPЊ4 slm) v)ynnJGR` IA M \7@ ,yJ(pb5\@ R\yK }z1? )`: )!=|ױ仏| #-ȷ̃eg,\z)'v̛ և$_ۇzޤ<ޜ|f2Ջ?G2;HbEi&,XKֵ5R#傥l|6-!eǤse3bl&<|lɽhRf zA>Y6?CZa@Us267x=%ec)J3H9i)ۉ̴ƂH8|#VB 3RI4w<95|&9)}ASmnO6)'Odxwe=LmN[gIGcE>)]FJ-=e{1rIٍuGm'1|rBy͟OͭHI֬X"_UJJݿ,oRbzS36L;MfH9)2|&#r:ӟʘٔ|swa0ۚ~0~l1Y;IX..))KO2l9:1RXkW')?3mo[Q#g~8o:A>KR'RKʂ1~6OuvH)2N@]iJRf>浻<>)7+)csK ;Мh #ߖ<!\<){ϩXGuWtRJ2/U'VjQk_ۤ箂|1NXMYsIž}8=ώa,>~<:yONCo$_S_R !e`|oOcOJ 0@-3,[Dž |*=k ݝe#%XGNvSs| =͛}1قz֓|.?"ϑOK/|[I>bɧc;<$>?KRI>L ]3|ϓ qb)i*9ζkN>n@RgcC>sϑͮ33'ԑOHiͱc|p lg4=a}qT._ϱ:_"XǓıck7}?]cn1& jw )s8}b;:J>W?lvlǁ?sc4R_x+w-(GLY/:t`bhgA>CRFd߬仒m?e{:}wש,eGޞ|;&1kϾ.~|]cW,o#%ߩ'ݺt__7K򓛐o'f9S=5|9;;nw-]I!2i{9TEw=$;Kw#]x]g7٧WsD+o%ęoa9 N~FLG's>B~9"_(-f\/_30&?x # ~.\H5[7i^. MicB~;9?Bo,-Z:@~pJ~֑L dr9܁R;9wmozY2ZqyP0rc 8K}"[/!_俗e)hM(߱7?)W=WG#Fs)mu/c `̙Fe hGLCfS@]bW`z]3OD~8w|/tt|{&S#dLb_;oJȧ|֐ssٿ[p@JDy~+U1j.VOUaju/y]H٧՘ԪdjG >l|4$Kck=yo*'+2#"CL &$c.<7Yy# D,i4;A;:J6gB\kN^.yϞ<"Ϲ~&yG7p>􂦐gGHӆGo_\^2<4OavG}]OɄ w4r׊܊v;N۷VKn)nv IᾘvCrxOGKrد er8oCR49 $4r4% ~uٿ${d%{=kXwAv ɮ֙.'{[cw ̹dMɮ*x]u -BvZ]d7g.پ" .Кlڒm;d{>lOd6l)d{ݣOd[lL#QdlWm/d; Č%d]rlna+:~ͮP9l=~VB6;&Y%x[yLC־g.q3Ⱥϝ%k?dYId;,ΒEmY.$Kd9,!>dM'wŗd1"MBL'dѹ,l Gɼ,'%d>;'|e2Bf7"2!Ȭ#YT2{@ɬb9ݽBZdUAg.y9gY82o>L i2Ifs,i,2Lېi+DK>YVL/ndZҚz[ȴ%okNEvd T'Lk f%Ӷ{t9YdC)EB2}tLCɧdza1"yd!h$ dߞN\"3͎?$5lC O~Hv|@2Mjd>E=Y_2{<2׽Kˆ̇Xḋ2sr2O4mD=+Ls Y(d~}Y|JzdǑ,$E7]0:I{2/s E;;8M)kcl2<,b4Ȣwcn[Y\yBd1g+Y,&3oida<,2FfE#cq0dד,N`~EJtE\?iG#RK̃.YvCK; p 25q|emJ2[D?E&Y0K[2"r/PKÿ́̏o#d{0B懮1ݎd^̣N "}da{CA6daM9L<'ϻJMd düfٝI}#̎EIf eC8#MG9e2?C |n51!Lɺ1V:Es'd2{}clK;;1d8}zrƘxeycgdc_YYpXϲo8M75YVE^X d^"Yl"Y9G="KH$^dQYKAddYƐEe;k=݂|Ydtb}en~ǑŦ{LcyY\>Є,JW3'8. ϼ+YB,' O||=EϬ>^wr<1A̦dqǼ",#cF2:|/CCIeߧET}F7Id cH#Ixב,g8gN ySs׋ I4'y| Ir$|Lβt% V9noxk'7ې|pgLY,G{uT8O]"w#1=5F"$O2Sd7E=&^"p1ei$bKH-d,Ɏ'7ӃRzQDFd^AFaddNna )hlv'ÃȰ75!t?2\я &~-H%G2VJpw+2'#g2 OL? 529 >&GN21dx =pY2ٍ ՒaJ$V'.df ɴQXHF[FwdT¿FW\&]fdd{[>KF-VL2GFZEFud8! Ʋv8tht$E"dg9 d,%,%#Wd$ hz2rHg]Vdd ='KdԚ^,!#dO02r%Fd~25ǽd!A,G_2ɶ~ڐA^'>J2xy'sd{ĒdTĒL>d-XdTx{S7H9d̕YdI z"Y$:B/y.'ԋ$E2 $[>WJr$%&ysv}>16dk|f_^~6r"G/!Y!ů*=¾ݙd\7+IW"m$a nNgO#}>W~YϾz'ɪH؎dg&nɪHdZ0][k fڐlRIve?>L}]$ $Ar>q„dV${d/ܠ~. Y)@G$6ט5SH KG[rkr;دצ'${4oH>$W"ٱ$oru+`x[xdBg$;f{}±%Q#Q$Kr/ϣ,]'e/9:caF O0 H>c?+7$w˜1#;> wc9$SwJIǼ-0/M:`A+<&3fYլۣInŘ:?-d^ujyC$[f`Oud Ll $ofq$_~ύF$?XOrS'3j`|oeufbI8U2we$~CyOf.O5x2}9o9C&&.-&{]xʣ%db$dq ,J&͖vid:L%d@6 2YOJ7L(?H>q:s L6$376*,sSgZTY!ΉӸ$#QdV=3c8\)Foi,Yrwsl=pyYϜ+sޛ^Izr/ɲCЄ,e:Ԝ ߐh,F7բd$Yk?$Ajm)Y=@V՗dU #4K*m8Y;gUa=Y!z'ud_'ۗRkq8K6xko1 d3+ %u+K6fA)َN6%d+{J6~S#l8C?vj$Fqd'5?JvfdMv֧n]HgEv'7_sk&{dנInO IdџCz}BϜO+ J$Iduߌ#۽pp9L!3*r ^IEa3rXkC>Xvp"ʼnS{_ǒb0R(5H.)b:r#e[r\BƼ.rԼNXsq[r@Q)cCx˜Iqm)Ӝ'^&'g{9>rLNI-v'=gFr2!_4f{r 'Zϐ/r,g)hJj+n9F/Ǔ[xv9VofF8<m]IC=cx)9F%ܕa9T )Oo^KIp#96_0=z#9ί'Gy/r\fMg~qSxYbjR_Gw6PIctmEۃ1-N¨) Vr'9MYrzy.r iºYOND%9dLf!Ǖi.rՓȩ9-%ɩrzoAN9 [r]9GNɌx1ܺۙ.4MNNS86]]\')aL} 1rb$IJl 9rxZcw!k)6]'eR ŐE@b֗zN˙i[JHq )6"kNXw'٤ڤrc?b=]`xRzqüg{Iqf.9Vd?~3Fi7 9c?܅cl09b,ג'rbON&4prFN:ލqu7DrvU#gOOՒsM |F.ȹ<\f#[ɥ"\m#?UܛL^E<&wxIɅׄ@􇼆{רq+y'y}G^mXE^nW.UzY7vc8q'/z6'ȫMӋ%ϟKyy} y=/#u5yw&|pNj `D^UYC!G=ǑI[6gn0~J/w ՗U|d)FJq|.)#A#弟Hۆ|'!edw|"W;2t~~@ 7:PPaw * p zIA)a ֕PИ8KAx\MmAm)xm  yhd 1֡=fΙBRhq i,PRPhN N! <WPXNFaF(,7ׄQn@cZQM^Dq Q(cA A CHRDR,tfۑjqRK#ZTJRU{mJd6T^T'iLtOF 6W[}IeI$|CI;N˜T#qBfa8Շ"4N(bn EzHLb9ﳡ9H\Nt?ċyܙv&E)RÑ"7.#Œ"*"PdaELH(28.(REG)}EEQ٧Ƃ"[4?歞"v?q|Ey+Fg,A߃&S~5lE&ɰ;2[FA AmG>P_oq^Da>]$ڋ(Wz+"CR-Nhe"=fz՗§&i)n݁ZSd .Z-֍S)rE<'z$@ :ͣ\ >L!#)/cH ֚_v6S@q $\ X5R`5QBC'ߞ/ҋPhA[_)/ C?명J i8&D_N΋!ZC_vI:h]Ksvw!ЪB4DEbr0Ĭw5C[tZ6$.@H-BΌs6>/B;oi~G^}lz<.`'a-Ϛyu)k}|6Ou;OX찻yV}SXEذOe2spƒ/Dwt> w)$|o 2kxƗ ,˳T>2Y6W`4hCg?ti`*kne9J(-([*#_.t5z[x U "."W-tbn}>ۜD=)[ ۡow_ WcEd:T`[0#qF}`t(2 Qݧ`,Lɓ]1=#fXr#,h. /`s:eNI`O{_u]8raz~G^؃<|Ɖ8e5ٽ8+ =W˸x>.+=zĝkYHۃ|SԢHUmFnz5rGW^Bw%_RyJ_ef-Q-ʭQ:)(reEP5QZ (n(wv%nqk\FɦrԵQ2"(/"|!r#{-!a3rbGUeދCKԶMQp?ݕǽqhړP*Q5r*j^ atGY_STtK)r> 7Zc:d72 PP۠$oo aAFd_k2 "+Y#9|62gAFtg@fg3lS udL܁,sGfYWr>M1CtH ~#XTӏȊ}Ԯ8YiHK߉Hg"JG$G*c?\ꇔnHhD-$NAN#i@RnĿA$w$wHb/;#q"aw!3jU"U$BbHp*FHȈBB)GOGFؖHԨHIz!H?:yHȏYCX[Yvy !i C) | 'Eј2+Q2]N8ms9YyPv/."'?Y7p/\ %(.Q7&-CiVq0QPt#EOh8~gȻR6y;Q 䟑 :!{)!D~\\:Ȼ틼mțys '(/ߊOو}|(!oRmMzB~ot$|< yґW;CˎC^țcGLލJ-wBηȽ*!7'ӕcd_3>r#wD䜰A+WD3 _ KQyh2dg!<@n{y9"'3#{O# s{daY 3d􉗐7lF nzV3z۟w(CٙD(o\=P9+-ףq&jDgjA ܝ59jS7޵exp 6n/Ǔ0<1E]ڏQn'iX<'Ix|w/ tsܥU ^>GvH>؂Um?qyǽ[_9@AȫdȾDvy!CԐt^ەAn?cY"kIvSd[!+%+"G/ ٥cO`dGx$z#_'d߈l]*ً8~9{푣>Ⱦx Yof WȖ j= .GƊt?Hkz){"etZ&Hd|$~؊ɑ-9}$$}#LB7H;i![+$Y5"=g+h9 k !9EbSHܐ0 Z"Fr;$Dk$둬1;jň]4qQJ^Կ7.8q5v..m+.#X& 1 )kFˑqa)nuF҆H~䋸a}yةWDq^q-l\1iwȑ0w*p5WAʘ9W q-ןCRu a>Gr)!9Α"gF,.Hmsr71d(} tP~ np^;;W Q3yuG#(n#+PnLrdnyA:9";2~Cj˗HiSH1 GjiH̡jȹ;3f>؆C9}8Ea6PT[®P y-8?h-s Ef dx8 2nD>552Dd;W d.BFHTH[yiwN" 3 u!?HHy~!f!Rszsݐ:kҼ y ҞGڢ6H>)f!yr:!u1>HcYH1Iw qE5:!yu9>ER $tCr瑔{">6 5H~u$|uت=N qHo$oBB Gb_bSuABHlY pkd[FBO3FBK o$]?Hَky}܉xΈTC\3uG\ķꋸ>'1-qR li'!nĹ#n,oBe?qwWWjZ=Wz[\={#w&7!qm$d'$vDbHύ8ϱ[uG$.=1!Vh!*hs]ڕ \Y"e.>T+@rR?$ބHelEMFmS"p[~_]! )9\\+GqcMJkpksnQ^ʩMQw j-q6켅{0{jG<+½/}Y_Pg'PCf ,jpm$F:A= UOƣzP4*(Tgwz@T7'~Pyz j&:|S=]PЎ̵EEsT -AEaP15N(FF;'ŢBw&ZEy_(lٷQf w9榸s3e(;iY|ʚtBY({ru3kF>wFyoΫu2nP ܼ57 qZJ=nKq61ʋRtBިCMo@mxnyh[Ž1{3sO b6EU5q'*Q[{;㾋67RXA\&i>)iYdH=%-E!uLSJ MKV*IiI-IMI{=i!U?.i}ub$ݒ^ !i1ŒII[KZo%I;=n*i*i_$iߺ(iܑ9JڏVLIh}푤CҙFҩ )鴪tl]%NLIgIgQ~>t3v)I;s}6Tn,i)iİ[I{ rPJ&i͕ 6JZ1%=7%ђVZIkRIk'IR[4!iLГ4zIJ%b#=z/5AMKǎ+hꃯWu<)|<>x?+^ CWo?#~WxB6 'C|LX̹Ȕ Kr圧6)C>H9Brj-mtZsNIn%HD7$[y nnD8$*![&׷#5L;!0N"qIHZ~ ͓4vKi6)\mGZ4~w#} o\3gfr.Cn!9Qg$ ԻqL2ARKF7ANp% = ㍐My\8r&9!gFc.rj!4rw[!#kP["/& QfMДpBbeC@^(8uKFy8;!y]"O-Vf\# R!I#{&dW F^}&<@ȊuGfOd@֪ Z:#k_:d-E֖Ⱥ5Sd-Fvy*r_ oCg@(2|=p-w:>)ni&L~woJ aNM"jZ4⮱ j"PmW~g-9q|ytg :y=/xo o>{M_Իaͷ1xV7=xx^o7c_^uQ-<͡#_v+so/@χm+p ow݇pwzⓝ=>ބ:`|t54>sM)>?w/[1=םz-L?vB2|/1ÏD_B+b=~4R=?qoи 1os,~?õJOWHjͫ%w$51$my ['JfH.$$$As$>%%K7ɽ偒zTI=a~dKziI=MRo4ԯYJ>J $Kn>GORvGR?o]%6$%y|4H B%5+%k$ W IѾ@00'IRR>cz^~YR)gj%M%5K%e-ԣ]%{z&IXR o߳~9~%2#$'2I9@Ҏ i/U9I:nlIwL;샤Mk)酬^KzY$k꒾?쌤?/X?l$&"J*O&IR凤&KnHMIM&۔R+C&%$$cQAOuB2)H$odp%E2h$}% Y t~\IdOudr$=2I2I"^;Gҽl)h&鶷t5%k$ˬCIfK:_ttwKY% vSI{I{"ɑ=f̗5HZ[$=$m-I+KZWHZCH?,9?WH3K%M}CIcpIDIṤʝs+TI顤UR[0WR[xORARⲤ&?2%5|m6[~h_k]%~e:_+'Z _7#vǷn)s#04C=|߉gn.S3]ڋݜ}|Oﵩhx=>o 1wi],A'IDk޻O uv?Hg!)TH)FʷP$ ֋pAH!}xdd}C$dzE#Jq 2?r^CY'8'2Z>MuH9 ӑ>}}V^_/װlR,Y3ƚc@ [7s:_).]96Skaʘ yl19&~{I.brטr46`Q[L-i1m]2]b*ظ3:`IfYΘ>S;1nǼMwoXP2 +F`Q7-Gџ4]+}}5M⎻%=&K ѳTX2QbJ+,i |3,ֈ%=̰$ќ .nBtQDG2m,DaѝXjoh/>(,xmpG,|X\;>R_,RE3c1uFt mmKL>cYXjvK#V`I>,u%dT,qw=Bv’3mK r=%`$,o7A |EwrVŠWUwc3Vź;v&kqI045f†sج O˰x&aK [/ֽj؞+ÎS=v쾦=U H0]LB-үχpp{3+q(vp$lÉp5GOZ]c;89gN8|CM8hAR[۱obľ؎V+ݶ{~62{c 咂]cywށU5Eط=v"v}w3q;8P'+p-y{G8{+J5\?ZzW{Ǖoq,\< 8 ' 1>yES9Xؽ ;+bGp-][16a}f->5:)Xkfyk:#݀Ӱ"V?egV鄘-eGl bZbٳ2Č}_ fq,+ aX1V+Ocg0@y]l>,i=Ct0DaIB,I*FtE,ڸnaAXy=9l$p$<1FݛQU0f`t f6`$ _1hl Ί`r ~OyC=b,lt7.M htnmDw=f&Ρ]v5ڴ|#]DQ5:t@GO/Us8z9:v[ڍMP.bڮLn tS@S1mX6M3"F*͋Fۑo۠6r9v!:" #\a~@[HY*Z]ވv>- gNA/@YwMD|to U@uvm%t|,2ЮW:碍qS\/qd"aLD UmT@yDB5{#q=B|ARcơ՝p[k{7=S7p;nE l0P73O5 a~W9ᇔOoY!|Mrr+s ƶG>dY Rhaɫ–*ۇׇZuЖNQa)SƆ/ \anjcZbeBg1jwC7n03t?1^kB}yU'˂a+C' N=4tU{B> 6l Y:")mEPfC |4UH^Bp ___________߶'~kst-2.0.3/old_tests/sessions/README.txt000644 001750 001750 00000000733 11544160210 020232 0ustar00synthsynth000000 000000 lotsofstuff.kst is a Kst session which instantiates many of the data objects available in Kst. Some of the features used: DataSource w/ metadata - netCDF, HealPIX Vector Matrix Curve Image Label Equation Event Power Spectrum Cumulative Spectral Decay Histogram Filters Fits It depends on two data sources (which have relative paths): ./GOTEX.C130_N130AR.LRT.RF06.PNI.nc (this must be un-gzipped before loading the .kst file) ../healpix/healpix_example_sm.fits kst-2.0.3/old_tests/sessions/lotsofstuff.kst000644 001750 001750 00000230702 11544160210 021636 0ustar00synthsynth000000 000000 1400 980 DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc GOTEX.C130_N130AR.LRT.RF06.PNI.nc netCDF DS-healpix_example_sm.fits ../healpix/healpix_example_sm.fits HEALPIX 4 4 0.02 0.02 0.1 0.1 12 12 DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc GOTEX.C130_N130AR.LRT.RF06.PNI.nc INDEX 0 -1 DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/ADIFR DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc GOTEX.C130_N130AR.LRT.RF06.PNI.nc ADIFR 0 -1 DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/BDIFR DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc GOTEX.C130_N130AR.LRT.RF06.PNI.nc BDIFR 0 -1 DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/CROLL DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc GOTEX.C130_N130AR.LRT.RF06.PNI.nc CROLL 0 -1 DS-healpix_example_sm.fits/1 - TEMPERATURE (Kelvin) DS-healpix_example_sm.fits healpix_example_sm.fits 1 - TEMPERATURE (Kelvin) 0 0 -1 -1 0 0 1 ADIFR DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/ADIFR #858500 0 0 1048594 0 0 ADIFR-ADIFR_... [DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/ADIFR]-[DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/ADIFR/Mean] DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX ADIFR-ADIFR_...-C ADIFR-ADIFR_.../xsv ADIFR-ADIFR_.../sv #009999 0 0 0 0 1 ADIFR-H DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/ADIFR 60 0 -18.2222 1.27623 NUMBER ADIFR-H-C ADIFR-H/bins ADIFR-H/sv #0000aa 0 0 0 0 1 ADIFR-P DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/ADIFR 100 1 10 1 0 1 0 0.01 V Hz 0 ADIFR-P-C ADIFR-P/freq ADIFR-P/sv #990099 0 0 0 0 1 Convolution DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/ADIFR DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/BDIFR Convolved Convolved DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX Convolution/Convolved #c8c800 0 0 0 0 1 E1-[ADIFR]<-5 [ADIFR]<-5 1 2 0 0 E1-[ADIFR]<-5-C E1-[ADIFR]<-5/x E1-[ADIFR]<-5/y #00ff00 0 0 0 0 1 ADIFR-S3 DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/ADIFR 100 1 10 1 1 0 500 V Hz 0 ADIFR-S3-I ADIFR-S3/csd 1 Kst Spectrum 1021 2.7091113352766e-05 6.5488658091627 0 1 0 #ff0000 1 1 - TEMPERATURE (Kelvin)-I DS-healpix_example_sm.fits/1 - TEMPERATURE (Kelvin) 1 Kst Spectrum 1021 -312.92321777344 305.1423034668 1 1 0 #000000 1 BDIFR DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/BDIFR #858500 0 0 0 0 1 BDIFR-filter_lowpass-C DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX BDIFR-filter_lowpass/Filtered #aa0000 0 0 0 0 1 BDIFR-filter_lowpass filter_lowpass DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/BDIFR 0.1 4 Filtered BDIFR-filter_highpass-C DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX BDIFR-filter_highpass/Filtered #26ff00 0 0 0 0 1 BDIFR-filter_highpass filter_highpass DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/BDIFR 0.02 4 Filtered BDIFR-filter-combined [BDIFR-filter_highpass/Filtered]+[BDIFR-filter_lowpass/Filtered] DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX BDIFR-filter-combined-C BDIFR-filter-combined/xsv BDIFR-filter-combined/sv #0000aa 0 0 0 0 1 CROLL DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/CROLL #00ff00 0 0 1310738 0 0 CROLL-H DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/CROLL 60 0 -10 10 NUMBER CROLL-H-C CROLL-H/bins CROLL-H/sv #00e6e6 0 0 0 0 1 CROLL-P DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/CROLL 100 1 10 1 0 1 0 0.01 V Hz 0 CROLL-P-C CROLL-P/freq CROLL-P/sv #0000ff 0 0 0 0 1 CROLL-kstfit_polynomial_unweighted-C DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX CROLL-kstfit_polynomial_unweighted/Y Fitted #e600e6 0 0 0 0 1 CROLL-kstfit_polynomial_unweighted kstfit_polynomial_unweighted DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/INDEX DS-GOTEX.C130_N130AR.LRT.RF06.PNI.nc/CROLL 12 Covariance Parameters Residuals Y Fitted chi^2_nu x^0 x^1 x^10 x^11 x^12 x^2 x^3 x^4 x^5 x^6 x^7 x^8 x^9 CROLL-H-C-kstfit_gaussian-C CROLL-H/bins CROLL-H-C-kstfit_gaussian/Y Fitted #e600e6 0 0 0 0 1 CROLL-H-C-kstfit_gaussian kstfit_gaussian CROLL-H/bins CROLL-H/sv Covariance Parameters Residuals Y Fitted Mean SD Scale chi^2_nu CROLL-P-C-kstfit_exponential-C CROLL-P/freq CROLL-P-C-kstfit_exponential/Y Fitted #e600e6 0 0 0 0 1 CROLL-P-C-kstfit_exponential kstfit_exponential CROLL-P/freq CROLL-P/sv Covariance Parameters Residuals Y Fitted Lambda Offset Scale chi^2_nu P1 P1 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3060 -18.706219238043 1.7602789819241 0 0 0 1 Arial 2 INDEX 0 Arial 2 ADIFR 270 Arial 2 3000 0 Arial 2 0 0 Arial 2 0 Arial 2 10 10 ADIFR E1-[ADIFR]<-5-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P3 P3 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3060 -10.818526495477 9.6479717244896 0 0 0 1 Arial 1 0 Arial 1 270 Arial 1 3000 0 Arial 1 5 0 Arial 1 0 Arial 1 10 10 ADIFR-ADIFR_...-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P4 P4 #000000 0 #000000 #ffffff 0 0 0 5 0 5 -18.2222 1.27623 -1.525 104.525 0 0 0 1 Arial 1 0 Arial 1 270 Arial 1 0 0 Arial 1 100 0 Arial 1 0 Arial 1 10 10 ADIFR-H-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P5 P5 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 50 -0.17172081938406 7.5619709065307 0 0 0 1 Arial 1 Frequency \[Hz\] 0 Arial 1 ASD \[V/Hz^{1/2} \] 270 Arial 1 50 0 Arial 1 6 0 Arial 1 0 Arial 1 10 10 ADIFR-P-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P7 P7 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3060 -27956.913391137 15952.563989994 0 0 0 1 Arial 1 INDEX 0 Arial 1 270 Arial 1 3000 0 Arial 1 10000 0 Arial 1 0 Arial 1 10 10 Convolved 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P11 P11 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3000 -1.252446183953 51.350293542074 0 0 ASD [V/Hz^{1/2}] 0 1 Arial 1 ADIFR [V] 0 Arial 1 Frequency [Hz] 270 Arial 1 3000 0 Arial 1 50 0 Arial 1 0 Arial 1 10 10 ADIFR-S3-I 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P12 P12 #000000 0 #000000 #ffffff 0 0 0 0 0 0 0 359.296875 -89.269029291574 89.269029291574 0 0 1 - TEMPERATURE (Kelvin) 0 0 Arial 1 0 Arial 1 270 Arial 1 350 0 Arial 1 50 0 Arial 1 0 Arial 1 10 10 1 - TEMPERATURE (Kelvin)-I 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P2 P2 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3060 -10.463578698915 9.0154766750265 0 0 0 1 Arial 1 0 Arial 1 270 Arial 1 3000 0 Arial 1 5 0 Arial 1 0 Arial 1 10 10 BDIFR-filter_lowpass-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P6 P6 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3060 -11.479896235466 12.588251757622 0 0 0 1 Arial 1 INDEX 0 Arial 1 BDIFR 270 Arial 1 3000 0 Arial 1 10 0 Arial 1 0 Arial 1 10 10 BDIFR 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P8 P8 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3060 -10.569537444665 7.7339252444129 0 0 0 1 Arial 1 0 Arial 1 270 Arial 1 3000 0 Arial 1 5 0 Arial 1 0 Arial 1 10 10 BDIFR-filter_highpass-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P14 P14 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3060 -14.489474626954 15.384623298776 0 0 0 1 Arial 1 0 Arial 1 270 Arial 1 3000 0 Arial 1 15 0 Arial 1 0 Arial 1 10 10 BDIFR-filter-combined-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P18 P18 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 3060 -21.277038955688 17.031010055542 0 0 0 0 Arial 0 INDEX 0 Arial 0 CROLL 270 Arial 0 3000 0 Arial 0 10 0 Arial 0 0 Arial 0 10 10 CROLL CROLL-kstfit_polynomial_unweighted-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P19 P19 #000000 0 #000000 #ffffff 0 0 0 5 0 5 -10 10 -3.8499976845953 157.84999994353 0 0 0 1 Arial 1 0 Arial 1 270 Arial 1 5 0 Arial 1 140 0 Arial 1 0 Arial 1 10 10 CROLL-H-C CROLL-H-C-kstfit_gaussian-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 P20 P20 #000000 0 #000000 #ffffff 0 0 0 5 0 5 0 50 -0.2932162193032 12.440471224987 0 0 0 1 Arial 1 Frequency \[Hz\] 0 Arial 1 ASD \[V/Hz^{1/2} \] 270 Arial 1 50 0 Arial 1 12 0 Arial 1 0 Arial 1 10 10 CROLL-P-C CROLL-P-C-kstfit_exponential-C 0 0 0 0 #808080 #808080 1 1 1 1 1 -1 -1 5 5 1 0 1 0 0 0 0 0 0 0 0 1 4 0 1 4 0 0 0 0 #000000 1 W1 P1 Object 370 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true ADIFR E1-[ADIFR]<-5-C P3 Object 368 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true ADIFR-ADIFR_...-C P4 Object 369 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true ADIFR-H-C P5 Object 367 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true ADIFR-P-C P7 Object 366 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true Convolved P11 Object 371 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true ADIFR-S3-I Image (Healpix) P12 Filters P2 Object 324 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true BDIFR-filter_lowpass-C P6 Object 323 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true BDIFR P8 Object 325 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true BDIFR-filter_highpass-C P14 Object 383 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true BDIFR-filter-combined-C Fits P18 Object 468 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true CROLL CROLL-kstfit_polynomial_unweighted-C P19 Object 567 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true CROLL-H-C CROLL-H-C-kstfit_gaussian-C P20 Object 601 unnamed #000000 2 #000000 #ffffff 0 0 Arial 0 false true 5 true CROLL-P-C CROLL-P-C-kstfit_exponential-C kst-2.0.3/old_tests/ksttestcase.h000644 001750 001750 00000000752 11544160210 017375 0ustar00synthsynth000000 000000 /* * Copyright 2004, The University of Toronto * Licensed under GPL. */ #ifndef KSTTESTCASE_H #define KSTTESTCASE_H #include #include #include #include #include #include #ifdef NAN double NOPOINT = NAN; #else double NOPOINT = 0.0/0.0; // NaN #endif #ifndef INF double INF = 1.0/0.0; #endif #define KstTestSuccess 0 #define KstTestFailure -1 #define KstTestFailed() rc-- #endif // vim: ts=2 sw=2 et kst-2.0.3/old_tests/comparison/latexlabels.tex000644 001750 001750 00000000435 11544160210 022061 0ustar00synthsynth000000 000000 \documentclass[10pt,a4paper]{article} \usepackage[latin1]{inputenc} \usepackage{amsmath} \usepackage{amsfonts} \usepackage{amssymb} \begin{document} $2^x$ $2_x$ $2^x_y$ $2_x^y$ $2^{x^y_z}$ $2^{w_x^y}$ ${3+5}^x$ $x^100+y^32$ ${x+y}{x-y}$ ${{x}}^2$ ${x^y}^z$ ${x^{y^z}}$ \end{document} kst-2.0.3/kst.pro000644 001750 001750 00000000430 11544160210 014203 0ustar00synthsynth000000 000000 TEMPLATE = subdirs CONFIG += ordered qt thread SUBDIRS += \ src/libkst \ src/libkstmath \ src/datasources \ src/widgets \ src/libkstapp \ src/kst !macx:SUBDIRS += \ src/d2asc \ src/plugins \ tests !win32-msvc*:SUBDIRS += tests/dirfile_maker

    ndZ$!ԥ4֫1SMdgF}^usÀV07Ը/!3ez(3ffõKMҧM?!DBWK1,+"Ӂ4E֬u_BYH-0TxhEB.)ȿ=U뾄B s3 ! lb y"i$= F״!t1IH!v !PY;!^"jtnz}a;ٺi@LdONq\H!H/B /;4:0H!Bd|S뎄B7ٲ:8Zw"B!PπH!tIDyB!gdz2w^@OvsKO!4,0 ^ \nҹB#ۃ_~8} !.RYǹ=>jB/2/~He 6S-:B!.4jݟ6DXhބB$ jf_ֺ?!ԛ! WxfcjџPIs5O40rw𭙽[ӎz=3!PA !&Qsc3w]IzBIJڹ_HZ[$/$iIָk!8c'I׺/!2* !z uG MO0ls8Elܥρ5S OltA $zIHZ4!^T<6RVe*yՁ jݑB4071/JaYHCu?zpBf0?!pEaa:Y_¼lf IZ/ `Z`}]JG)=/M:==!`]I:RIo|Q`I_*$ :³.?M{=YkG9x3Э~B !*II2IԺ/@! l.,5Q>p4y2x 8x8JzTfk$=#i@IC$\^Kg$](IgKZ0@Ityz9D*N۬"i7IHU4_nMI,NI.'闒j%2y q{ jEGRG1 R 265Ϲ:9A7j~R뎄B(Y!;!^%2w:p#cZ+ϔ4X X>HAƴfx`Ik+S//YKZpqElKIiS$,+)<X:-$iNMx% 2OSI<܁ K\z aittZ*i  #igTXYx8=KV3)0gz'}Y88̾7Tfk3^cAIӛHf afYێv‡v2u3lefgC~yo;<`D?) I 62U[S׼:i ?ShL`g 4$0|*;p^g/<x@ᆲMLYa;uiEQx7j t>Dp-`=`eIٷS٧P#f6*ۑ[`3t+B Ȣ !6 #iIGHzOuG?f^`k|&еW`:*3;̎NnMw%pqqJqvOGcf̶0l;Tw%|8ǜ˒io`Q<3(InFf6|yBSPϒhJ0"iI/T Jd}|R>KEJCf' h?tC,@x؃@ `w ܜPyM32 C{ {B%u{ t_q"*?.BtoqbHVj̝?OćNdRVHY&?!]@ҜB’6oӬNwGH|91a )~}97kC 3HZ~OmXV{Bv_5%K5xN32$pJlpr$[ *%hu$=S)-_&-+ *fJL?Ge>~;s\|!iW5`gixܾ6 2=?LIg'3ی^ӇffY~6il-> TxFǥBS5?~Ni|fv]܀y%%!i:ai<t5w|(I?vK5m6N(/ bYڱ9^]3qN3^ƃ)A`rI* ½ IDAT }% @ fYq$ ^nNOX/40IgCI-* _:{ǥ֋ag,DILCيj⼕'pm{ ^h)<X8H>+i'Am&3ViBv/`~jsSÇ.&i!z!A̝B}dpT|P&/ `fT4+B "dzY&X3։f?n뙄z/ćz>RT 9[ee f:Rq)B:u niBF" iS|Ax'L8eK !4}Z#o&i$DIOǥGe!}g4ƇgnWhsǁ?\ V*LPC!2f6v26 :x8wBRV|&B Rap>Qd4ٵمB.׼x*~E?!ꗤÁV]U^W! ̖YW.BkάGOZ7.aZ^M*&Ϙ)[פ"cZFI9|R#'Z&HEJY˩IJaf-mWgUڄ_i*qۯӶցj>+[) xެôcf-J}_:^j XSć€ZOۮQ}Fj틿Zg֢}ȬJ΀ZMۮY>:%n=0̬e:6g^~Ƙ:/LYu9A)&:RjU%n; ZM-qπҾ΍ϘWZZ_(YGY>B3{_L | aB5T',Gx'g6 aĴ ɟ)$`4p)r2~px\ QIfnx`ױ> ;M`S|_+s+⨥dn7q<H:X|,|ZrjcRY⿟ہr܆4m@=r}n/s{Bﳔ?bAт_;۔ݗ`2}ɯĖ)?-,v,tYwKR6ٷ.Sꕤ- fEB]Swr}xc8̶/'`KObf`ۻ *|/0a<[\RQjY0zS#@MXY_KW=/*j#|=VR=,__ݤN2] k,~E 8 U+& T#}m\t_'gばr}mN`;}-+-`o#o^%6 mG| nzoێ3>`Ҷ+Vکc\g]0I%[g驁Bgf68(;!ުQj`f 4S@3{M5f-OJAR3Z&| mOuhVïT:CfRxF[O K0nLJ,b"pY˻Rp`CJ6 άTg-J׏R͝O0sf-Ja֒1Nև!V GoҾCCR͝LRER)!҇nHuhVZJ_mIC3KWZZR4pY˫R-R3Ʀ~jkGÆFRZ򔾯ܓ7=/$^k7|3~|#_:Fj]X/Derg0B-,I}-IK |bfgv+^5k)l!:']mvSN}qi /J,𕙝^VM !İzUϙ;WJ 25kww,B#̮ $͈ڃKbB!Bέf6Qxdï$mDeaC!$73[3]Aϩw!B^tv7>[I>dҰJBЖMOW>J&=߄k߾hYs>?4J:΢㳈B!P5u)/>̳مe%N"@iŔCrMx1mIg-@ \_ߏmO6qJp0YNB!BPw>2QSAfV4Ow3PBKY6  us`mz#gI TcFǙlhg_$B!F \<<I_B?Tm0Jh`t g{BU֖F_3_Nn0a&X`Oi:l0p_/}}ff&?NK'#i h́Sn$ίV!Pet"93,=F^y !ԇ\NS6[r /J<=VX}H{\4[!RTsJ73t24~934=)pi% &T 4=p2*<'3{;=ϒ[x8 c;?73{=h\̮MY-N4ڍKx# ö$X|`ff( `ngrgJ>=F{> m cffbG3FR!lf{Î?Iۚ͒bϒ.L#!P3 x?}@BTxYjک}|^t+^=q| \.왡?<@ߙN[G>~\B~)X1 Mt pCex&>߀ÏLJD~zxmQ3QD]zМN:J)v3fǧOBEǛ0ٛrx2$}Rv1g6wB pMH@n4Jm<*ie`_<𠤵 /~<}dfWh@,iL fgZaS`|ƴc9l0Iw٫L%Uϝ$O- efvgffINJCۤ^ afo2xw;8xJf;>4o><呴ϟMeBa"l nfJ}/-[X,8x |ܜGHm?Gҩf6J/ }?d$07ARH*UfO~O4e֙UQVE7df#R&xa/ddiӾ#f6,e6%>> 5_ho')6Aq2ixV}5~(lfIzt~4e@Om3c RMAf1FmxfI{p3f51exebbH:N+] i(s"BF 4㟋-A!9?SS^ă8`s|F&vq))2Y t7>ÌE!/{Cg?aIIz<26dRfɏYVxHX7i;i4=SxO*D}!g;=-0tXP9 E~鹙C[ ͣ ?LQ8'f/e/5s4v<8R (D}g8̏L>Bcy~< pvAgKWHwnΕt ^s1IƇjSӞV[.8#V3[}|.s{9 k-?YD>~x&B!C>??INNO<#ɮ3(4ѩÁgA-7GJ?!XJҪxas?CsJ}GlPCŽIk7ç?  Ҏ]!fMAC`O 5>gL6+aY72u~3ُLbIE# Wkf%:pK)U2'ϑ4 ٧l¬cE>&e-_h)~c45 ]6V_~ "cf7f3&ſ !mLǝTë;.jkV<֯sf| lg\hnu73^ |yfX*'0 ت8&e[m^L] 7 ̦xЍ|f6*O5/l4#^<7 X$?D[.K3b.|!| XQ!e7sit{V!)gzIk۝Ә8fCW77TP;Ǘ]mOJ_O O˿Hp8pN3BaR`pZ#JU`EL%ofOװ_!-[/v8}|~T=M^ kEN!BznY=>B\n^o@3>Jg}\\ԜB{w5ݲKGwS_B!B/Q#me`t-Еrds\ iC' I٨f !B ;/7 9 R@r&`/H`N6ڀ|թT |lf_w)qB!JU3 :B-'^3No?tB+|Xߔq-B!NhVă1wW!B<d IDAT!i}Y/Brppz89Pz%K*/6pY˛Rk_`sW^{<*+ef-owQ{[ɢڴ~!6[7LlzNbY AjmLZveBrKvӫHљEWlSt!zEl~ZVBS_ 'n:=/˭Un`^B^ڻ@;ͬe*^7DO3,&:sG,|flGSЭri4wUc!TZ%LԺ AuN륽E{jL8fΡ:'^;vioWh) V6#i`e/7{`w/>ʲ;B([[.S|\֜GlVj hܩVWq@S{ OU7NyU^r{*Pukj8) !Jwiw 7WA{2~Dp'.ՖMς7J۟֜Gh1R3 i;%n`W~\:J] ׌xfb5; Sm`:hWlaA0h*7lo(=@=R{  %gۚ;.3 o 0(=|լe;B\nx-rŇ9 Ժp>pYT/tk_LaeȪuJΏI[ <ÀlvUz%բdx%S{~I8v O. zѬexWRh4ϛ3ykٷrB囔3s,ӜY0I8R0 H92#m)]lg᰻z+3{Zn{[H:ERqC!*k `t.p勖 u@j]%RؽF كx͒S%-#w5V!4F l=s!i3Vs>ҜϏzBZvFtoWB',β!13{̾ǒJZ] !ү '%m|,i)r5YX[. p7Y!ԋ6`mo5$-LKB= iQ3Q?YҦfv[B!2w[`5k` p }V˾[rP^`{`|zffK3+'[!Ԋf _Rm=E sc5JijCkݏr?ӗk]ӫ} V~BOcf/H'l[!g<~8B;IH&N!-;7F`'4IH:=tejݯBavIt\;>ds|VÀMj۝!;=xbJje_;rJd"7% 0I qڜx:zNS(òef;dJ:g,ça!LE[.p&m^P3d3fI: cMzB=uZ};%ofqB/E$p"^?/Q"}Y~TA{v_! m!ٔRvB5/}\jBx3{ xBlXxu$4V-,4عQ?)hN(cwK!tYX̢4s= qOL>7B3X 8H VqBŘދJTò$&hA+IOéV>/q5r;ǕMV.Rղ; 5k9 $~+X)i8+=n!43 i ``(z K/3)zfդw!4\elr9cs>?B5Vj}¬Yx K%BhPf6Df?mw1jݷBI9p} ~BT5reYJl;ػ9vIJjZxsfp}qۚE;WxBHFոS!k+8%Bj.R`'#|PEmܼxf܌%nr|s>WvB?f(e#3lJ8.՝ I@F6uBbiµQnsB=E=gLFy+G1yaBrμ%nrxs>|v)KLL:..Ԫ_Kſ6NO &im`#3= љK4,WBOy3;>ɬ*$!NjX˖Q g Cj>5Z(Mgl:I[KafOuOwCmI+_ٴU㮅B"_ffS`[ iΧZ!5΄m ̖aqi]` `Bm>gd35=<X^k,"%BUf6)^gw)jQ;1i$MkӥG[./TWt{uawBI*L 'u¬cLP pY3_, ܂ϐ)>| IJZ BafjݧBF 6N4'p0Z:B#hN,q'b&;. ^UBE3k M3ef/YV4 BafJgAS!t_IsxM[?eBgm `@ lҜߵ . "Y<(pwcb*z3Ժ@),ܗ XZz!ҙDI,f( ! 1 %-<`Pu{B: X~՜ .~v ~vj@j]IJ3޾#4rIk$wwv@LB"S,X?028X /EaCԖf n_.Pqi_`AIWٿjݧPEYTO3f4q¿cfILY Fmܴ g~6L&f+n 2llRi'٩A[.7'pAٜ?ҕ A4;uGBdf  2>1&Df&p0Pb)'tB[.74` Mږˍ0rp gf%[6c {Bi6cfc%T1BCh_Iկh/j!ԕh0UURʎK13;N띐܄JSH]|A@AAXA@PH K B.lܙ;;s>ٰws5>"KKZNs9TI?1 67Y$5=%nf/,'ΩJ`BZ6S7V<Ɨt_α݋Ђ:JgI%"5},M O !ٵ6kfVI8reiê|d]zլ"c /CWҢ6?!$+tG)Mc@hU Aҧm:B13ίxi=gscV<ܓMeoVbD|E5|lq aP ^.%f1A&!$#2> ?>;] (`OI"/+31 %}̦_̞ÓH: K^԰$s=G`F 7lͽ00pMЫX ^>F]CρUrl_BaΑxb/z?/]`C[2wʃMB蛤 ╔YUΆ5F졎>bNhbC=s'b0(2rl 't(2vߨx٧bYvh! ! \9I6z]BR-byaɖ* ,af/w`oI.+2U \|5(21dXj5 0Nƫ]?7cDD'mPs$i]HhHЦI2ޯ!otlBHWPafOJ*4 8=Xph!43$iw`z֓ga3{_$s_v4Tuo=<~M?$sGE[d*D &!4L$wBh_'KR^`BlNXIOU|/Wlp{ <(i`W'&_/%}nu%t9<'i6ɛ7KiˋKi:zί&wnM?{sG߬%hNܢc d h^~pBhٴ/E&T &0k$<%i]I-Bx2`PeƙeB2詝A\I2'"= ,=1P5sai>4}!$mOeho$w=~=4aj0$-_ؽ%\64REfvk)'b~T_QoɛyUk'!l|ze#gj8/_QZsZ)Mot0!-24b/J{nnY efWH̦J:Mlo!go rɆU\kM7 Ki:dC=#f6S5f 3;642 (} d`>j{Sm i^ $-OYo|=o7Γ񩂳ߍ̬e"=ٲfVˍZ=.i IKnilnxRgA RMxBL(OVl$ye_3;!f+k8?!4rȱt`( ml <;Y)+j+TIҦ5/ c$jf,8 gfKp19IKu]dq{ ƹO'7I'=+'!! MHZQx|ЬNcj_:KiFB2.uO>~9Ks;68N1qti|fxks 7oal}݁[̬Q! 3lrf6VB,p~x >fRTHZo*h6qA'Ġ@C6O32-RN]y 80 < soo:/Fz$i353 $R3 G\xsԣqFwHZ83C )1njq0lEE4CZ1fP fK *XxBh:$ pjMR )z 9[ ]wYϝ <`yI}w-kj0=gXVS|M^-kd$+וQBh'$8namzO\XJGBc \/˾Ch9՗qQ%TNOR>BhzR(bfѣfvoy2I~+ 21B~08~5Xh}C6cfsl6?^"_ YPs?plc B(V9Ivě'ŗcMwBnYΟK2yEӎl^u!in3蘆"3@R (-QaZN9Io CKuN-u>vhӀ*jom%$fhàf` 'i"P6`5`Sh4 m$ι4}n$u^?']P`hm2#MwXtNIIq0P$$ƗH}&vҴ!*|"ڍ|ff6+#)~BC P6!B<$ \ ̕c66Fqf7I;1 p pm.Id7czluYbl K̢3 9Yow..u>v {Of%+~f,?i13}Ŋ *ߟ7Ji:Ў*KO཯“q^j)̘H2ot/cfS%m6O~Yph!VN*ui`ͮ#^JuP+Cr'3̎7gԀCD$wʒ^ǫt.t~WBD$fMFBۺ Œ؝Rhd-NxzH `fӀ$}o:@\l94ŕ7K>x5ˎ:ufǚY$vZݞ$uh1S;3K}$N5VnUb9!4rlWRA }|n^4 ,;u`f/k: +d QG:`O`CLx6Iߑ\5FOW$`CCJfvEӿeH闲?x%j IDAT _xYi_O/>j=/.iv"NGׁk f6@H-IÀyB ('ɧ{o?gT1)>Wh@ xCKX8@Z|0xf2ɝH8|T*_$OsX!U*zn݋4 iOxx/}\,,i3[%iE3.X`IٳEW9Iv/XÍo\JӉ=m`fJ'Kmfk]18`uv%#Ь6ιcrC3 h֟-! 7}AC{2, -kF=BݵJΪf6]oʁ9*Y +'@)g4o'aUɕ/Jz gV2G^4?^{PXYnfHBMI28JiUs^I_'шgf_3@L5zk&P6W٪BrlO]=擀m&%Я5l%YB=&~/{╼wS39si<YbG"x߉)U Z$Y`8.A?x/sHZEc3Bk;KE3$?c@w76Bnsq^!N̚~"sX1!˂Ǘ")GQK">QNxo~$f&HZ^.80pJzI Uh -1u(>B]9I'kصSU!/3{nU!c-}73FǫafiaQى77$ |`f'W(V9IVۗҴx:X^M5fl;}`fHxo,z%vF;fUءM3Z;6qb3(isIc)|{[:^o'3.ތ[fgb(jqKɒKbgīq3ј6 r NbKNhCﲑU$j~ٻ+_^񄂙٤ΜlfִI>uhvqFPdKxBŗT]MCzײ?k!Th)yf6 񰙕>"/N/U0CY9I. ˀKiqc ! Rf6x6ˉQBlfi`-i`Z=PK2 YOMvQL$Y oJ[Kb5`!5{%}_a-lWlY3%Km?!*ol֒4;] wwCs4\ UNEIo_bˁ"BCLy1㼔Qr@I5ސ%I{go & ̼;4)3X $$7}Ju3z)MoTJ*7~\t<4VN:{#iyIJMҲMFV=JrFx $I+7ѭrN[U<. <zVNU `HfS.U {X L,i9 .O;:VfC3_dp]Bsհo-Jiv}t'B|'?o 8oڠ8CZNvelwCj8d,u!C9I%sXEb'6~pYɵ̶v^{qYm -Cғ˯ٕFj`53{Rf^A('^*w|?M;P<N1/4DOʽ5y_X̦H9E3{A0V̞3ifvKt%ͦ$ Yw5BWtJkznwPǫt 2#i!I^@d3Sj@c1('>>u$v NvIs/4TK%wBhv2}m*_)MZJSkLd!.Rlx6 } 'fjc}hSN'37^ݐHZBI5Ox_jl^JUy`3;X >StLOӺ=˲BCIJ]9I7>Ъo\BhR1sr!I-{s+'<@=d6iNI§n"Kd6`-SBFaD$&45Movk)M'; Z/>A҂ ,TVf𹳈@B߲-|I;IZI_rkXy- ~>b!2ɝ%;uϚYf/`B# m$wg UsF4=&&b.0^dfW XϬMdf$xn/.З`bZ)'0<}Tϊv`f]͒,:BhνF4B+'"$+^.V 8Xwaa~^:,[*ɝ07:-83;X^GI[S`*yخSP;z硢 !4Hcj3%} oV^'2$I9I×`Ucs)M*u0P3{ X?/N ^hvkF5,PWf 6PCadS)AoSުD-e}KT-@EZ[KM0%- iR㡮O[WN_xǗtz !44BWtE-˾a0$|A9I.WbD:wٳ>gfS;ey6mt,LrGFxsiٸ#lB;o 0a CS9I6a(* Si-&XY,3haE>)*P=fN;e ϧ&{WJTtLmh1|ȓ9z> :"~DrGҧsf/$jKAWxr 8Շ2!`Ϭcy` j!i^ \ҵM("*MN5?׀N%0p5%4%CyW)Mz7HyXK{x`%;(#$}/yp<8r:%p( RJ7ZatSalRfvv祐Më>M(.6efoH1ٔ!I+r>;GVA4=<3{R0I1狎|-fwnZz<2FNCxuL$!̢$% ,s~)MNCUxމkؿҼZKge/_)[Effg=YAI[S+Ji٠ZxTm`<;I`CmVsU*w /i2^-H(CU9IVa 9ý !#u+=\Va~+#\O /x.tM-, $%iGu}vnfF5 -HfY XYpM_;HZo\n 8H[7B<\H5=('`W<V9E)M߯B^Zޑ"pT*nftM6)nGdQ`l`f n3xÀj*v/vzI.&9q~'Rf}%N7++ןn`!Fr ~9`UOS10T*'HwD}-R>QZPq^=]pXfnIs05sj##>RNM.0"=|E2uOT}<>mf"i !~DrG҆IfvjRN=]1u:t|ίc\g;IӲ~  ONItn6>lMl/?tI2>>;ǖl lJP9|/pi[sIZm a&-b/;K9I ,_C 4ʰBoN~<Z^̦Xh.f69{#`w|ܼWUl3,3?pբNY*i>(|B -U; f!f}wZ\om`+<3-(!p;Pqq^ V?$i#j`v|ђ~mf\hjH郁ImfW:XN1$F7MҰv_*15sdfw\hiMܑ4^yR1 4cz8E5 `k5ꤜ$9[f_n.(! 4Q?Qy)d|Yj͒2 /433;A /H8PN%n:-DB4IJfhII{ < XBkkpިvx^֎A/YX<M(p.p~ I\ғZK6NzM_ҟ%wzwM֧g齢i2UqyLg,%xi8qx&πC|#ifikncU+4#i>|T˟̦K:x/; 鮚O*V9IeUk18˫zs{)M:'iR/7eL$zzzԁ',x${` gá5uDS6efH"iKC3kdq95ۥ4xBm*Of[{$- t NqUooe ɳ,L$ECѕ;gFNـM$ff] cqݷtT}B I(38V<^◲M^\]J '0\?|b]ˊ%M~y)rP+l6nؼ X3{ԹYGgkSYbg4g,3K9IS.Fd`Q3{ZҼy4 Klx\xUFݤ>6+HOhS%w{KwЮ3G>[x)T$s≛MW2{RhO%s]'+?rUt1yKdWI\;&JۚM*wf3)V7vwo⽁W&u$`/Ikٛ=møx~26Ϗ+J;S̬*_97` IDATsC m䎙}!@ ;fWǒ8{d>vmK$Kb>>>&hV9DBH !U&w$-Sy^:7 VdU+sW=0~v_זSha3*c$m[ސTNMͪ凥4ճ,1?YvI:wz@X I[Ux*8(zYV~;_;c|8> c9zӒI2oRWfaЈ^̢:'0_؜xߝ5o :^0 ߙ7 a|I_*hX$no.FK˦_?0'ڡ!KvLoAm~Bȭْ;=!c,+3EI3Df>xǟ~71>BBKWU(i`bBjKK^5#%}HyBj&iv;&k} H /*sBCSpT34S;;=+)|FZ(\QAj-K $4ρu&7nqOy;ƗƦf`]"<_x~YGK>gfOfCfϮm/tpbb ;&i^`n//|K:l.^Bx5x^*94}ؐB~7u{y1`s_X#FOkKWn@udfI&KZc3VtlUNu$B;Iݺ'o SӱkTP2M5rl i[lT 1O4[r|iQU<s<~B2upNj"~ɜJijFB [絊nRݓ=f= fvoVcf]?v«lG5U;E5w4{%l)}$mW,O?O{qMlc7ћ 'yHWIz w8OR /<8дɝjf:ɝMG?}< , ϋJxErav{3{Dҗpb6 mGg67z `Jeb'9 8 z 3{b?viܷP7;dWN:5&},i)`M{!<B4crgL O蕤y~ɝ*38KiZUBhq>"K XOv1%{l l 63CKʖ< ik!%ک鱥4MOY"yIIZ̞=GJ=AjZ-=_1xlBqŗf/ !1SKB$3;SkCԉ8?s~-2鋏ѕ6 6xQrOu~M_L~>apY5R7wG/_#xR:3o_R2x9s;ȬAs#|M9b^}fǿ%r7ͬRsI`o!{::^g?;|:xѽs7ӬR<9 \jqԹ6^\d=t "3x6ŗ Q t'K >.f+OEY|߆v;[Y_-6V" =QqÛoFuCJ3%w[Krǀg}]akR;6'㘛67㙋6\Sfc_E05+]?Q[5';VԙeU]2jY.u8a9TΝ5or˞R節S`cy}]:w.$¢RxbZK3~,O_&3 žRA{K?!5>>w*;POrHVҞ\Uʻf{;/AdfHZ֝jM~"i~>/[Cᢶ$5ySJӖz7IS~f{@[ؑ^FI0 ͔Hγ-]0%-%OS0I6I$==ϽmZqaf~:ΨMgMj~}]lD-|-V+wj`W'UJ  Ը5'{<R}ҡx%a-Amw0TV߯ݨx:ZOdf/H:ʹo.".4 ɝ0XfM='?Gm04@fvmOfSWLA$4)IwBCJrgE`]Tڣ~<OX}&w 1aLg'jÙm>~{اlp3Ib%Ldf3zl/DFm3i}_?ޏ/n<\ 5~Go'I>7z{17CuUKp~WT8.T׺?JumweN_b_;0k WDg߹˹ëCԝxuH|C^Ӏ?GS]%؇>5!775RSX o t^98OP܈W:>1ji|iB5kWҀ *_ ܊WYT&x_*cABdH]b~at%kf,:.$ٔa 钮6%-af/U|n-[t7.̚g}w P-0g$ 0Y!P3{jRxuOerc63;a[c{@M܊WRU.c@хB@ر4dg;$mjfwV|fX?}m jnk"i|̲lɫBmDx$F"W~~=Ifdch fvm_lͬY[xUWuVU3f=&IS9IsA\Xx ۉ56 F,}5crg^IU<;~.8zs/""IP%KR٢;BBHv})e߲>3sfsr=y3|\39>o4.iXkL)4Hڒ5p.9:>.iSI#@6%&N"c}viCL: zWF=Jvɪ7^)}xRJCPLLOSxXC훀͉)Ҡ4;p0Qyr>~ ,k{#?#zڽaejÀ )5E~HڶqtV*O\4@LѪ;G:nRպ$}W҇[lJPKt] z uh)RJ)5r/ .ZMJu?Xv{~ȩ;i*D8`6F(ۯ~h[Iݧ }h|La}oF߲}I;OY$%ТSцZO˿#X5%`7JX qRJco3_OO;>~pBʉǛ'"un*zG5Kg87F9ۯ6]`TۯHxJ=q_f}}C@Jd)lSJi+,7_MY(p"cNJCSC}~JeR/ǵ04< 8(IʩH;1mk[1oTlO|m$}ʔmD$wHӭ,_(]ܳ}x40+1uf,romV4uߩ1MӼ%@Ӓ6϶#B4,Mw۾lKAkAxO۶+b9ImI;UnO⸪tT(4L~xTA6bMO$vzW@9^Q㟮t{hY)1;] EɃa1>i{%H,}vÙ l8 zL\Z?=5xH}PA Q/p#V~/K "iaIGI=l <'i[IW߫~J 0QݓZfe5`VǒҴ(ɜuw$}Oʠ'vT9 O _V}.%I\88Vkk?֪)ڼRpٖs-q%t6I7߮?49cImwN}PA2f~>/%Od_Y3em]҄9ěZ$-hI&kϚLNFfz|qRyqY2&d>R1JÌOv-O$S>;)9ݿgzת^OOO([|Iԍ$G>ijzq ^ NyOÀ~:[w:gڮM|x{SDGg^O99npR& h`gIkپnZRة'=,Sl+` I~>Iҝ)nG [t{om݀KK.OQyTǛ4!ܱhCD$Ŏ)}}m_8J4x5$iCrr`1Ҕn;b/yWܟ&ؾ[ =Y &Qh5ɝR͵{BJG)H#W[3}D!rP{@ ~GfCu޲kI]RK{ϝU4.mOVscjJ]/$Kώ%[wb֡,[,S>v\13ՊiH%wh<3c?}rO;ak W"3?p Q1m6n;hyv=rz$ d !{blm7۾|وo$N3A_y-`2 0yoI2qq۷J𛚇|#&&wR6 _}IZ]T͔.[Oվ}TfqRCl(i r!4y8<p+k@4pD_˂RjyƓ;GaF\7Xj1eÒ#N7'DA}d|,xm*UNb&ncJz!^1 %P#D V򮳀$NT[IWrFWR^`>Is~Òސ,"K㻒HZ<ܙ8TI,R눫UbٜK$=HCuUҌU97$N‘4=QUumx>J$~|37mo[OI[vRS>Mr*c?,lO\%ڕH`|'5QY;5wt$ O60ޗhKWbH>Jӌڑ[VJׁ N\mGL&W\m{X/Uݫyyձm&wnpI:7$^sTk;Ӱ4Ez&'w^޺re￉J]-B$|j(˲h,}7˿?A#*Mѭö[$d{ǚm<c4%DB OҧoK299HL,k*w$C$.%s3e2v pWItЂ$]"a6;T8{KBuB,m[y_MERiI"N&a =U\][ɽsl,/D_ckVjowjV?k_}iY*5-9-LهgMپK}d= 7gR!z:ęуn*2 IDAT纖WT8WszIm * C5hlI |>s6]*c"h+iۏIHt%~ l)יzY ĺ߮+2eL b3Dwе@eMs(U0"V5zI,sN&'uq׋-o}%η:QQ13~T}?R)zO.oh:_vgҹ<ߏ߯1$v>H\XoG,'nE/%OJNұ1UW F}8/mPL|4k+g{6(,EJb,d- >AѨ\I/ߵByI'qbjO%@ D6/}n',ڒ[lb{,):TJtwc,(-J1`a%E3Q2diFk{^.uO,^uόDYDE %61oDcTj`g zzn{7۾kR9t_D*k:;?瀅%MWs^x&g<% i("siM@=KCxMwt IØJ\47{ۧRC hT#Rcz,$Ylw_Ro۷w&wԜ@۾S1iif eL}u,H6%wۉmw*~oD3o!>ATH\XG"aq"/iD3ǀ|#)ZX^=E9iIN$}WbcRIDHv]I,z XK׉j%$]JTS'$ET}9Q 0*\/S+dA1UeJRy>6a"IU0W`/II &ExRV*V>RF"%s5Ր4+є;Ҩ׉ߵ_~A1F%Ikmjʾ]Pq2]OtV*Սʪ}q I,\G'G+>JC9hߝbNoUo:iR壷d.]K^%t^+GiKjZ}!M 5e_K:l]"Yz])ލp8FKRw{=܉LM2i`{R8ݓ;x΍nx퉒:$䈮J.K&_~d{R8qa ) X&wҨTA̧Ԩ% \N,ۜT'%i=9 ,j+biDOHiJe &v?#M8X; {f BMi% {˫Yݍ8᥄$!i{&;ޢ L%brm&wRJCDl_ސF7IIϗ'^܄&i(u/H }K,\ =>O]Yz'؋؈;;?&4IkR4thZa(&wr'4پqvwDΊrsmw=F!I3_!uYƫ7odI )Ccr+%{qokK ʀoPy$(޳*eRl0bJɝRJJMe!b#z:F݈W>S#;KVaʫcM/VxhQ;׎jE1ML~~^x%aʋ )5]&wRJ) >HH4E8>6ױl lUET,R綥XJbyI:nܒo] 3aTk{:=҆(2;_4LR$-M,P!H8- yWK fk!ѥ̶S>;~dK*G=ؾWjm3m8{ xSҬ_v߸z;,u;I3Ի}^qRjX㵘R>3?:maFbcI˲F~ 88OiTV5;NIؖ)}Ul7RF1۷PI펩k6lo;ض/HHzv8QTT+5yE6FwW7Og/4 JLXyi(u?` 0y5 cۓ;XҊ7GVѫ G,wɝ2Iz=;XX>>gJi@ܲ,YCRJGX?sq<XPJWMl_^{M}kIQ0q*$B,!?p-)H\g 7~461zH'o&p mgs+wKZk>d펩KM^;=}"Ȕ ,@)FWK׈/foc\iĸx~}XnX)6.0GWCylDR=wJYH$]uTGH%V!r[>fw5#Oi*%plj|XXUr>yNUuM.ndrgVbQ[eRJ#%Ӗg)5$Ô=w6(Q(PzY_g$-oiG#z h>x' ? &5E\%ib˶aӵʿ7CJNCj7be8Dså >J3Sك^Sj1D52K5k0qTRJi;38xS;3c+r9K[>+0Ua=Qg$D$`!-.i#/HIM% ʒn}ojGc SbGҬ!KmJ }7$})me=3؇跳\J1C8fi_/M)4HX=jmgliDD!fzXhfI;UWgK$z"'i۷7.q}]9!jB%->wMmX6loIg7%z0T/v]}z_[H)4`f,'#VN3Zo۾UOZ9X,#o4seyyn"VmV ihTLlmȻ[5=U+IΦRu /fX* /r8iNJ) bRmm 0&r/I:XBKrBIJS4WO۾H|mr?Mn}д>o::+Y#˵ߪVO-II>y:KLJDbr9=. ;m,iv3 9$+iGIV0T&wRJ)5%GA4\>h^R}X5Ogn4`b_baρ-T$#HڭϙPxةyeu+ j ,/4I+JZ]) DpqXD%xs妃W,2RJÆOt6#.MŖ6cmC6KbT>C$vlvtbU@GVU,ʲRUǑ{Փ&9mN(`۾b`AJSmIӗ,H,aܯM}H:SlC=3W[H)TW2b2ˀmm4Jbg.bcmۢ-9@jjelڤ%Qt YVUHӛCzVVNt 19Zw <}C;~x$U6O-1ԓ;YRJCHY/'ML8<t_7۾\I%҇zU.͞I'~Fk>e<m?Yl+ _6ejzwn'%vj{x?q֒ QI<7@+x6^tp:IlI+$JCNb5LҐ }~@4I>Xzm2Jm{SZ*l7-3[$-*iFeAIw *4|s컌S%=V>44}C:+#깽m`GKZGϦ-)I;{3%i*bbɒf#~ikTi(/ɝRj+IH:h| Q'$yzR*li+V0yGW'Lۛʯ-}sr' W*-t p7Q p#O^IMZR8]fvv`#KZ+X1/~PJڠQ%$}4#w~ڶZR3 eYɝRjI'8wg~!)_| 8x>b6bi| brQ݊:Ico<+$u~I4fhԡ~k`~OJZ=m(ےn*']!~'7!>}Cߒ < }%yaJ}ʝRJ@4I/ ^iIЍG ~nגGADN$dX"s'ZmtOmj( JeQV ?pzz"AsĎߣMr1J=l ,a>xRʆv&wRJiH'?ӯ i&BTtKT % i6,b\I{$}VMZݍ.IRxm׏vV\؃?U7u~퓻ݵ;5oFZ/OlLiTɝ%@RJi$4'' '/!^ERެ : CR1v}%cl ,{mVc3;/wJ:ZҬ=l7EqI3˟#4m'#7@RzꝧHJ)$IYؽJsJ#Bp$m oF7 cz>_'r襇~@StV*v.Oɓfز<Ē|رai|8qDL#;J C9l_[&eDR;f) PQ!c #NoG3?4;iڕhK~ כmV'i}DGzu3}Yur7/[3L1D`F(A/\w!1UnŚҐ^5j4;)O>J\!=p[[J%R!rQR' ig6x>,%iOg;=POR1Qw?hQ8O˳zdrIG'K-3`qIZ@$6_ކ?/3$Ʀ,+FIK:X~!2FQ j?+fk` H:DҪl{ -)Db `$v$'5RH5jߎjUW$uA"tL/= |%03gj;v6+/ .Mhn7"~ p j'lYRJØ刓կcis\hTݶ_i8q$,}?wپ*');3o=:+·__&)~,,TNbcגfDۭY˔ v8SN󖆉L0T~Xt`*d"J㗱W~͡5% "dq9l/aY`dGzr{`3ns=$$-M,{&=tV*#*fntTqEOvXGl7e'ޗRj~u`vRJAZ) %SҹVl ;Xۇun!׻)i,kGo9QRGN[U:էZUپ_6v>`'$Z~c$8Dr}AIMJárgfIHJ)%}EU I7}~40$zBT:EL&c9ئM[m_G۾tu:+ ͏)$4J#OF IDATg۽hb\mVԈr|tV*wTlrHCI8a8!)oĹˀ eۉ`1\ZjH'wNJM$tc$& }RzJ9|WI _Fҭ .0um_JeijeZ=! 5'smw it(;KZK5ɂG\ͩYa!I ZTf#&?سZ=!  &NSjggIAm?vzi`vQ<=``ĞR ldsRH"0=pngl)Nu f É퇀$}8Xz8U:+ŁVobHÂJZpcJ##&6޹Vd7$xڭRY<%vN [$Ke$n{NJ:m G儲kWuք%+O+uV*+c;eb_$hZ"y_Hm;bYRJsGxCK)NIo },g -l#iUI>15Sg2q5{L[Ӈ;haiIK~YD+57U$l&?Ś.S ʝʿI)G&G%^~,`;I)U|s7ˉf$^\q>=^mw Y|X5-'^Wdbg`Jbg-."S;`iy5"DP{[-x4 ۓ$ XRJ'iyWװ i-jRKbN(T>4a!{ӭ wx(MA? i<RY84>π;Ivp9vF&ۖ0ƗOUm?uqwsK ;Kr'QLҺ Hٍel&;):>GzJu~҄U؁H(-IkSms(Y|R3@ؙvߴ)pH1ކ&.4#0Wmb><Ѥ6p&p'=lr2%"0m`RJ!i>bscmRJÏ%@1f&Ҭk9Ձ; :+f-KZɒt2m;4rؾX@tݦ=,_90rIKU~iTpJ8xFIM#dj; DI KNs~HҲ4?p1R؛`0IOZ&=^jDq!0pp.pX]|}U m?%8b(п}' sNJ#uJ)][/K>!;)i%iblިF(p'1:-:+:+wV*K,v9DU23lX nwN $?RJ#mlRbUI?#drlM9q5īzJEDn`c`l!G;\R14Jݾ@҈St,trۮL^(p4b{|#&-lے}$g;'fNJ$} ؑRS}6K)i0x3r, FGM򛪳RQX1Ul<~XYt%eV#s|fK7{(04R/[rgFRjG~Fˁ$ |X?{YYq²tdi{/RE h*"hPX"ȂHS#ґ"JHG:q$7ܹg\e`KS{kR Q-_Bc`{ AS߳4}kukɒ^+b9Y$}H-<[ԨՒ;YW%4<@=6+ n}%̌Q:v0k^Gmk{Αz U7%L5bZDO,VIԖ?NJPiD# )T H Q?XimԾ6#p3pTw0jhDYtkc^j4p~ 8HҒvϪ4lOMbu'wl?l,i5Z% ϋJr4-;) f#|h4o*cK)%>\VZ,Sez:%iWV ǡM"ޫ~2-m848l <پ@eKiDr,O&Ii@'<|D2R*lNTl01mtwNc%[I}7QV% 1gIL GW۾]hTPjmSI56}cz9䔦iN IR#$f'V:H@pQ &eD Յ7<7V.Ka*z)͌Sk]XSV}7BYmQx)nNL});).!K\aqnN) $>@4}h|>$-bžInj7FZ XXYfYُ!L&|'Wmk&ۋcR <a$[D_ھLQ%w:2ab eeQY`)Թu l?\%&>v̇8L5j^טywc!w*i)0WE%C"}ÀBh/ܙWr hM0RYeS)ˣ/nǽ ?\\_zy¨Q#Ոv9gNGSN.֖UCɒ֗bIJ=t3`tHy>#i7Lo^)k0`WJ)Ic{ͿZʒ?jDENɝ`9:8{ܐ 2aԨفehY_ͪ <ɪIYDVӕRffʿ>޳'\JՒ;}wZi4bISDJKSJU5&rZmD2M{¨Qs f_ UZGN.6xbllIKJ-UǔZS{äţ([dg{1:Jɝ\2$i=ζDUDlR+;6 _Vjiz'v >7؛gbmcg CƤ֖3IxW&`U`U`0}ϩ}4M+%w+wRJ= I%$oRJ6ۯw[1֒M-zӄQ/=3_EaΌdE͹U.% 7;l-nKΚ'K3zJ3*;) F_$[@,{p;-z헺ϫ )FS1Q,qSO0IϪcJkO]}g7Ez,;) b|= p$p-ݷL5F.=a$VϚ' *kZ3Y Nކ+hk+ک7-E,E7j9t[pI`1U/TRJhI$-A*0;,pRJݰ[?ư7SҌ{kapn'RitiPO7VKjU\O~(9\9';) "!|M4I\4fg3psם[}IzXX>^eJIKI:]UǔZ66~Sq@)u*;)$yKb嫏'4.RJ&grgF[vcUi~7$j{jǚLCaaEG *Lr;CJ,I,b۫- Tu T1jZ2gl[c=$v.~+QؾMR4;UǔZ<߀VՀ_dҀ2ɝr' qvD`;Lnۉ9qS$v)i}ۏTSj>Q`֊4{* )NZre2(Iv~,RJMܙC,-:c?"N&4[wks9ǁKbkW}}SR707\u1oV4{ppfofUǒmSÀWKJ)͔VKzYrG*1۾n Cx8 0+@Z؅3Ici`Ka ~6> PĐRJ0H}"> pMz|ML?}$M\L{Ҡ;)URJ3kX̠ pf;؞bY൲irc(U<"u+Wg <|I)r vLӧl_h{>g5yxm`N{H}|M)4JjTך(S{ْM-I=vtXAi`CۏTHJ)T܁nIJ:%m3Ut; iPwѓr$I4pܫIHD{Xt#p*wD)/o `;`QU ovf#dK7lO{BZ4꩒x 1kb*Dz)@EKvbG`=I̕Ro IHZ8l~RҘ(a0#;&"$o|h1G<%$\I\żHK4$jj6>QWu}H@mK{ۂ4t-B$u6#ZflQm8)u;/ެٍs p&'91q]M˚ʝ15>P =,T[1=˅yKt1N^Jqi]? >@$pF[}? $q43ɴڱF:?Ro?djK$m<&2Skihۋjä0:ՊɝZrW;V"V;Ul`{K^( ع%z2S-A$I1'=fO"զ uTT\LcA[%ǖjiy~xC4ŬUԦf{vcݙWۧ cm \R?4F/G^r[^~ƔIKyJ:xR6m"3i'wk0QWo*79f&RnM)<C[S[Fo-`qtTqΎip>͓?G{&"ٴU'wffZVGΖQO)4$Oρǀ}퀵m_Tip>LK{Y%4^So l-iT49ߣHlrGpIsӭNh?画;J̴/ ^Unh{+KZ~gI':/)0mn(ӽSM_V-RJi`o"g^ I5ID"`{IK[uY>\ ibn%/inSK> \$iWII $mF{) ֪>P;#'x]lhܕ.b.zD1uW">(n&"R۾G1&k~{񈤳Օ| *s]  &`bxnVӮA4cH:d%vm.)`R5p ŀh5AIho,=K)nJ)4;Qq/^[\<6?iw)Do5ޑ)4` Lk6X};= g/۷$t6gđ4xw* .nj eI,GTgn>z'Wخm8DI_hW} eIe#l.i;"95Q48H=N|vV&e)f@M{ą˿OkR%psԛl/i/UKJ)u;m>7x^n-_3y |RZ.S I+DmC,.'>h~RJ) F_!VM\ xzBYar0]? jBI)W}?Uq8ix>V\- aH~)[޴a5RJRFH p"0詳ab{ DsreX'%4@>!2IUOJ)5Ӫ;5RJI|Xq=߬2~r0Q {\6li}]1Un9`c5ǒRJѪW6^aTRJ?4{ @`Iۇma WOꄤ݀JZP;`qۙI) Hܙ,RJ)^bF[9YO!_2$_Xnbe4p=!ůG,e`J#Ki`"rwJRJi1IRi l`rVJi68U =[I$)uC&wObgR/!4DH[ҜUǑR$}X?ueld,ҠPz<*iI헀v:.>Um8)uU;/ܙV#U{"@0R $ 8XS,%VZ@Ҡ7`YIWHSÌVML厤hXIImPOܑ6p(6b~ /6s{ζ} !Dc私ٞҰr _la6ۯk~a9ve9l9#q*R$}8ؒx98ÕR$LJ7I|.N^W,&%i@jʝIUFίquՒ; ,}x:Ɓ%m Xq"pSK%'Jn_Ið?""iIOɧ%KI%]TOuԠN’Γg%%in>]$$xI?4L7$)*I?+ɸfǮ.[t/Hd%}^6*VGY旴H;ϥIi [͉+4TYtMzS'\u,OmpE`*I;Z5:qr'wlOڧeFپnZrg+oxj+DBeR2նo,@It_~n{7G؛H4'"IE%Qw=6x"_k?!~$b9wJ Ģ0}D >eXI7c#b9AvnA$~.-DBm?">9$)i1IHzh+ۧKI_bXSntsG R듴?՗VyT]Jx |klN|iWV>Ni@hN)}Hԩ8t4娖ܹu۟ dIm0ivnĵdkN'/ 6lc{jmCB{bNMN$~nNO%,/>=eڍe9y6ղ]=Qۗ>XuQ{>eq ELaw!J3&H^w_*wW> ,d{53e*Dl ۛv *j)= JTt|蛱pQÇ_ D7UjI+J:X6SzJ-l.wNiHZx AձnY&#+l۷]y~c))~lILG[3Z_NTA$iY(w~Hg b)DhO5>mnɒ$A7+ Tl6&i h.`/iid"A5%i^>?Iܴ'F뉫&\?@Z5@CB^TjL~$Z`I>Y5ڰGc]%SJ-LZ=y+˒r{}Mg=U'wf4n@ʝfɟM*E5P,>~Ogʒgpmع>S5ϭUǚxvwujfrS屟+bVtQTAMzq{,5사IiА(kDBZ"sM:FHp& )*"hцEˀӅZôn(uDp޻ e;rOvCKilK4UKdu{gI<,s7\Y8Hڨ,O4s,РVs_ݴzA}bIRr{logڞ`j8=w$;)8I I0mf7Nmir]W;]oRl)Z9JmN*J}mOcڗ:Hq*IL&iWI~8X$hF+C,n5hF8m"r&"AkIBU~Xk9I,iVbI lO u+[I*l%QCDr z?Usm]IH{l/eԢ$- i<ދXkKھ膔yך~Xu ipRRJjiY:ɝ !HJ@$Q#~& j%*g.#Px%EѿfLse(p:DgOחs*iGb9ڈ2ǖvlZVH9j.'&Vv5aKwW%arr̟Kk}'FW; T)Jbu%}u%]>A]D:N\Y[δzcpLGI*t+]oNbK)UD|J$ʷ_e/ ^|i_= n4~vDo=wU7'h6ՍwHxjvi^|}>ޓiuB\ T{o5xsՍ 9^77+1bKi`QbH-E?}ATLI%- ,M$˞,ˡ77hd yHKTݨ,j٧rp")5+aF_o=gc`yy׶_Ys=Doeʆc'S KDv۟t8S%wl˺DD6ε?$}K4zpki7m]9|H ,WJHMLHbP:XP+Jw`^j*z^6ƛB4?;ؠ IV$.x=t@oq1{9[O;Xu*M$>۞iO/o@PzniDEWmZu<5HH\ceH`VotrDen>ۏjwMdilEągJô62П@Uqw9LLa=6#hPRްeNǫ >MT=v@OTQ3/Qulٰw`y x W xWӎ{kJLww%Qc%z#ՎwQ[]Bw)1!2D{ "LJR6TNC%RJiI]~Dsןe_VL <7gv(J}Ux''XN]L ћLL{wjD|NV+Oz1D{TO$]E̡6+ ,4IMTGT<PR9-sو 6d}xU4ޣ'ƛ 9obgIPo"p=nȬ@ӲZS+'wS_d{I)&Wf" 8L 02RJ)%Njٞ;J9-+S|~ !,'[-RJ) >-)^!;)I#/s'V:y+RJ)YF IDAT RJ) m_~ , o{f=RJ)ԩY fTk3TBWVUJ)U^w"z,K/8̮RJ)RR4@za``/;~J)#p7p0?pC3RJ)`H[i3TGMbܔRJ+I;f?!:?zRJ)!i$wZr;(RJ)uI%CWel)RJih =w>L$}[~ U6lO>` 1ۏuq.~lNJ) p~aJK)RJҕ;^Nn"z+<^TQtrI4}^^tўiY)4HKUlRJ)4zrriYlf7ڎi{i_j;[ן@-%rvPoV!飒$V7\m?_mt) n~!IH| i?IX$雒Z㌐E$./:RJ3Փ;3s5#n;"mcj6>l_ _oްѶ-dr'*&i#I,k{/V]JCmoe{+"gs8{=w+.I'IPҟ%6' IWIw"n᷒>HZWZV% oJ) C:c{$--irufO`"djo 5l.ܰ+s畻9-+*"i=I>L$.!i80v+F(iqIJZ@52߲'!:^|}"QGۻ- fv94A56'dD"?N4L{:FHUzk̔RP=wf|⹶܎(_#VK<ݰLy1H&c=Snr'Fɟ$^'~RJ#K+nH%pdF)oD1"DŶp Gg8OI^'؏jiI;;O Y.f2;]RJ}+w^LϧeI?O7~ٻ kW&mCaNfjfNJ)R6` JgYbuJ$7>bp#^*-I_k;  !`$,S>T?D4af%ɘRJ_plO:=OlQnc{T)M˛|\?mp̘J)$ L88ERjbQI8 ( ulC$g>(i2yA`Kb۵s3H7q* jSl@[a?^-i9bM]m?*駴WO$6}?p9t/ls#}s$R}Z&"Iٮ=ϼ#kاϯ;7>A"޵p`$M}~yB|ROv3y%-@]&IۉJ Q!iKJb*ڃ8"QÉXY9Lѐj{ߖ4xXR-)^ɝ ?Vng*SO%+/j3RJ}D ?':wVXJ##m_ n2꒲zeD˃ l#8YJch16 *x>%i=6/tpWujmP#ۓ%H$~o؆?drrbK~Aҥ*fr\DZfӲn_>U~Y4? 񣉩kΕ`?53Dna/7Kښ(]$mB0=uMD[K/!$=*i%CG~ImD%Um14p)0~"1-priA.OJ)uէeA$wqe.-;K4eKSRJ)$IH:hx9ڶNJZTPn'cGC _ٮĴ\DG4|טhRKrQ^_>S}A'9$ѓ!z2I{x$іf0뵧Zn$8Ah6-;IY]F$>cG~nDU Ds$/@+68LX[@b|xLZYyMIOH9'Z$Uپa;\?H"}lN77s>ZmJ)S+;W?۷W]JJSl ir(`%oΣ%Fj_iCoO7յP[ iS7$Db'^lmvۻw>]u'K}R13PiZ[ށiL w^+f%G_ \ET&KjʟKZQbn9&Iچ(ܜX_Dy͈RJ)@!t$o4R^5#%]dm.x?t$Vμ gD%md?/."Ipt9hf+K-i[D]K%}X]u +pj~+a"A$p7`IH,Br\(0<Ɉw[H]\fi4TOT,KY&&SmD$"m.D3|ړ#1f21 Drj; hZZɈE`˪];S~+=O)N + T'[fHiXöf Ww1Tb>8R?r~@15 Ҁc<6E/޸K˛)T{#>Vr=Z6NTL%VAL zxygIq!ouo%צ|q!ٿKiD+C?._S|)@$nqA."=" 6;h>mbՁU%]I$5jMG~Mҙ̒DBI!</K诳PLxSI'*GɒBpê͒rAI\zp_Sm%6 Ct3EI 0[y%D҆D`S’`kܟ\2R)>z$? DD Թ ƞ>IIz 틻y4H,VȚ\wuɈcjri5 3D-bVDBOםgN"ɵ qA۷֝<77ĸk>><6Qa4=| nbj9I ɦeKG۞SpΖD"PۗHpѸym/Ne-Y#dWm,~r.0aK%]CrĒjRJMĊ* V[HZ\&w`%i4RĴI%i ȥig۫ Iar+w$,D{g$p`ZOΔ*ɝ4XeAϛ*Rj#V3܋{;ԹSJCZ>٪Sjג&h;U9 m勺퓉G4lw~/ǜR2RJi@40؛XFN@4RJC/mk>ڐRJ2RJi@4wUU!ɭ>8RK}%:ܙ(RJ) Is%gRJ)RʝRjaeoi{JRJ)4er'R$JT,<^=4L)RJ)u;'IzMH Lj#J)!i+}`a)`wTۓ-RJ)V2z+ 䎤a)S \|BFRJOHIӮ-}R&vRJ)R16>`g9 It3%M4&i'գK>JL)RJE`rdrgP4 CHYkVo~&h%CJB)A@A("4 )ݍ 1xמg:3g笵Z{\~xy-ISW~㟶o:_!~Cl"&aq[ :'mI$I$IK;KP]qgj06L{W;ݛ'vءDX\".)g~0Fa=܆?= ȯ3RI$I$IC_"ADʟIJ8`Iw߳D7'l[_> >mƸu{4pf$Ĭ;u=6_w)OsL`tGLJ^aW+t5% 6! g[7 .<l,J?o#NG k=:ٟ@xMG_ftp['&p+pOʘɁoѰr$-CU>{mʸ4ccIՕوwt(ی CĝwS6%r}@3:0I$I$I1yLpN:grj4|MةM۽MH2I*QZJ5ar޴GϵVI<{%y/~_oؘg'`u;6 hwNByXնo+%̆ҾI?گ*< lQ _EX؜^WmlDu^S"Dx'D3 l%B DߧiO&Y&#QPB ؆.&:o!B<{ag*($#}IoKzMҢe OQKC}{xmK I˟K[ҝnnL;Bܑ$]#nzUMHZG!6kv$I$IdWĝ7˹WIJzRң(ֆtWyGyZRVB eý\ ųz`)IIc$7ھ]%m.iwIk!֪>jWIcrn0Q47pٲU})05p注k iۉ.'+ޒީO-mHڌs5% K|pmUl mXK_AtUSY˽jX$I$IL¤3}/NtsHWz۝%kϒ}$mj2sUVCmCF{%5 W{VO)3]ʹGh$iZj|/@5+%j( ^PZ/+6*a'4u#V[sтRi*)mW~iIK"DD5-WN+V}آB9EZOxfE_U]F"*$ʍ񓵰 JS TLs>U$.<3gS<0H!Ja;H=""&Q%$"B%Ry5ݾ]Ty' ~=BQI0B n^5,I$I$I;S"%PN>0"DIKr&gJ)yzޒ4j2*\>u;ޮ Q}ѧI?GI+i_JZׂJE|H)әSKl}3l)k\әPwOkA :Dgʹ)ڍDWZC(BE YDURMykӴdf-7iM;]ϝVVa-.iIYȧSI$I$I >!𑏘pŝ<+KZH9Ц&'B%AGh7JJ؝8K$.p"ݰk`cSz}%̑4;WiW;!?!cM%#IU.}}UB?5_/E(VB-QV/X4/*B5Ig fx5/ʹ3 :Dr9*`!eo"6"I%JOj^"fiuA =k߇ʻ8:ᔭDىIKJL$^e[wm?I$I$I}B)aB0/Q{r`cÈpAxLI|.N|ОF|X.KŽ^+ִݬPՊP$]$顲DŠ=W%FT!yIHZKMWKْ4@wJ X^ IDAT!}IGJrv"*(".-bFMDMJ)J\beח2TvCh 0}ML9L"=Z-Fwv7JZrtGEI{@If\?$ծ ۼ-iZؒ"Nw9ۏ~{euBFRP״z͕5A#iQIpk]$I$I$Wr@|0O;j;h&;w1s0I3o6@!OsYJcP2)1/MrX"pF'ep:6"qZVƞwt'QQZF'IL|C;ՄskL0$I$ 3² 2RI$aDU K$I$I$I}ZLI$Ift4;RI$I$IE_I$$)9~JTu+{հ$I$I$I)$I$@TCnvzհ$I$I$I9}QܙWH$H!Q&~BԹW K$I$Idŝ#?pWJۚ.rcw.0_f. ع jq$I&$MK:?oU>I$I$IK&Ts6.Pk{|\%mktJ:I ISKx8 xXy)$I$I$ɤG_w,- Z5~?KZ5a]Mn#;'7 H(izIƙ%8^9?JmKHDE̒f-$M)ioB5!ho,f,{$I$I$Iz>#,~/o]5E'BMѸfb`[m"m$l_]RsnlXx'KG}׀A["81p u\1c"$iaWM!i/mN$I$I$})CZҌz`0x p!m6`2~(00ȇKwiѹfb``9i?>Dmm?6&*ol<}os+!<8"NWt,Lk /WCe-RƚSctq/{wN٘؞$I$I$Iߤ/; w5NmV Eܱ}kyl$Uq5+p:p`"lK5IW7~|SZEؘdwy&–[ '* |$v໶_l3=IG%Bܫ{lWaZuQk~h`2ť.m1ބ(2rjcYo.}!UC7m_S_G]jA"9w~۟ZyE_WلJ"r`j`Ʊ8eOũu; K<뽀;y/d\3bi6"I$I$霾($`KD~HZxX.[av"Θe|VZ}RnD[ۮM"-B8xl!o7l_RMb{oIޠ6߁o۾2ppA9Ozx[懲?m7Bg!pmWi8!XP!T,W7tYzY?B8{}E;!>D_tpeO|DsK4 xH{:!Ax|\W۝&r4 Fk~1"'>ZZp?YgB@\smXsGTĽRwl/:wW)ߟ Yw}Bs*Kr$I$I$0}&r-``-IW .Mjm[[+6jљPӮoL9j.KbH9P;%mod{eB<<ȡSq-!FY *Ax|0හnx5p_OS)"TtHst;!-B.PpQM.!5_U %=!aIja,.$$*iSIKFU]D⎤$YCy窊oHPy^ۿKa'I$I$IfE cNcp.,o +䄗Eĝ²FsF{w=O#iWII:OyDl̵k]3W6+z[y}J}j~JBNci6k(Si"=ӅmOiv%]W<Wm!D mӀE-moR B(lDH"rB|?%E q%﮲} OaxS?0'6ߟ%j`Ͱu-!5?]H$I$IdR/eAibbu?ά]ggfʳ!]W?t ^Bʶm_"*Ѥ>yJ˒6#Ym#6UҺtxI$I$I$&T!H=ͻuB|(*`CIKaHQwXVӻ]ҜDLOpZw"$A!TT^Ngt++E_@넇Her~ iP-s;VI(ZkIT+}e;-%d 2nJy!HVb{FNlhcyr>qG."w~5D kf$ >m#$I$ +qG_w;VU"hw+R]JV_*?um)i0ᥴMt5>|hKgtsǒO;@5UZ^ cCUY?z#`'"wOՏZ [R#{XU{1JjWent i[D #B4ؼ1;_P'xc#D>$I$Id"cwJegmZ뾄[ 8]> i׎KFe3Io%b%ss csG;:!1=loRљA+JcU||̈́ծZ]3:$I$I$I. {Uή720ҬӉ_/IkJ8$*D>uKd 45' IZ ,V'3r%M-ik9ToV!*Gȇۏ0dQ;v>Sx沧JzV;aouϚӉ𛗐HNNyFn:<5wjtUZ2:MXϫ ;DhL9ʨTIvXVgk1|_ 3u2oj_KȰ$I$I$I)&>n-`Fy5^#D"LDfrw!Bof03pv" oBtz(}NpQ{~ByNq2~$UyJkePpذsG)ʾ*J+*cI+U*З9IHڍjR r?&Ŝ,iZs"qDigUJU>} Q`߲Ncg}g3q)U"wƫwW ;I$I$I-)$I}~'  *M ګ%I$I$ItA_w&/\$I6Dյk%l݋%I$I$ItI_̹;" \_m{$޶#I$I$I mUŝNJ~y\V Jd!$I$I$I&6ӎEj8bBљy: FtQ~yl$I$I$I$K_͹;ﱽ 4t [.0;!mDS旴voۑ$I$I$I$},؍Ұ]+1W5IZ I$I$I$IF_wS}ŝ<00yŀ_ iO-,ѾOZ=yX ؃DŭEI:3'"%]K+Ӏ%[ĞᒆJLO%g7oo!IWHzx^ N4Sc(_$-"" =IH\gtI:$-,iIqo+J*iIJVҷ$m&i%m)闒~$M)iiIK'vMTb_gMƭZeÐqF$I$I$8/ev0aXCJXenC=\  `+Is!'?=\cogXK/Iڈ`*Kt|0 l lhvS%=fv2jcc۟KfZXEt /i5-\KE {>~<A^K]OI'BҿUcl;`n`SBXXYz/$8x/wml[Ƭܿkg Qpsۯmmh9`\ ؑ3?#ˁ+!$Bΰݭ86cgo OG%z{vP%mz$I$I$I_${%Ym?0A(pJtczsLW>T-mwm=5嚵S}ŵko}b-~Ul aKv``Ml]ڧ=\f/K6jqݍ`6xn.c~^nJલeKeO Ϫj\Tٱֶ8[߫oϝV*?KQWk,in'$<ǮlԞk-EmB8|Î?o7fB\8zLGyGyGy1Is7刏ĵ×*g<Ћl'i0!NL|x,V<{֎KmlIJvPæ m zIEKZ eS!ڰ^I6'yԵ;C7=rT^_t*i [PWLYnIڛm\g~s}XҏUl-`]Mޒ#mS2CJ'wc0V %njMl2;Q<~)f7vlfB;U IDAT`DI v`ʷ&O˸O {DR瓀Ng'I$I$ILh;=dA\DDό='m0B%|fjTr63!,,@CSk$lWyv4Dǒޗ%1𰙽[i1W%t&t+B9sT0WnE0@l.ג$I$I$I&4&uq7FDr+ls@3JY1Lilf{g߳=Ĩҋ 5U)ʹU]N%pIk/zjVV)#oieIHY5QT|!*|sm]DmRkۊ 7nArB||RIV$ۏ~6nrn%yUxPҺU-<ĦkU=z -*סּRB|Ȼs%EbԐw$I$I$$IW@+ѡ)j,JTjį P5SU rTR`dF'NӣšQIS{"t'EcjG u<Ug# Ϥ+ o3ϖ?gm1 j'6u*j6s &#BkfCKw8 s"g"BZv] ָ㺍!V+޲J3( :*c[ΓӉ,M;!%',BT9mۗ~B|(B$= '9Nj %i#I Kډ(Q5o'I{?_*}5˿^I;JY7h]ɑe{K 5׼zjRVj_3efXui:'~ 9ʍԊY[q# %My*㺹nuBxlIڪs1oLB*s'I$I$IIz,N- I(|{ZFrte t!ԔJ?j5gBSwIDc{kvco+^;̏bBTyhcOHZ3B8!l /sA|\曺}'peq*k'ʶlnܛW%LxS%Q«*(B ?V-J҇sK;eůt<ᥳ6#ҚD \%¡уOqqZX=%r~@xExW^o;%^oEIvN\~x_m'I$I$IL}$Ia7g^174 "!ī'V5v!G-Jo2`{" ҄GԄt"pd3Jv097!K3Gڭ m W / n?“7/cۇgt.9>x60! %`b׊ gbA[ ͓$I$I$I&XRIz׉B'6گ#El+ƍJէ-lE7m5Q"i:c-cnU;k#JOR#KDK?3ԿvaڜkI'#J_@Hs 1n'B@x^$I$I$I& RIzP oi o"gyca`zv7pz˾$I$I$I$Iq'@T[ȳ'/[%4fr"Dnm~,L$I$I$I&uRI.(9tV!ʋ #D}$5]Jmg'^Wc%=%鱒kf3Io%])eBN|Nl]P$]'IGKZGҷ%m-Ŧ9ksHZ㚹%-+K4y ZҖo/!UU;Ϭ;MIՋ1I$I$IIf 1ו1 7(ڦ">?r ]K፱aPce)}%Zucd~0}c5ox޵e@N\P\ ,m"< lKi?>7!\{~ N~uSV6~YN <6~[{د}V ;Yދvc+W_'r^?o9diX8bo #­){4Ym n"$Ɯ+6O Bk .<#<#m_|m "QDΝP8B%W7/c&}s3=$KgG"gOcsQ)>IiZX5ҽ+u$-gβm\:e9? MqY9?ލ}Di [DJH@x*{Q=oZ+Sd//ђ#'=[(;Dx"Yv{z^dxD L?B"eU3螐06skiۊfW$n%IS1Gw?"ta#JmvnG\K_&ƻ%I$I$ILLN%̌*H/~4x#@>|%ۻ8+㟇bo]1Qco`I$nY[$45^b^@." (* ;;;le̙3gf.y89ӠR݀;YymEL]*gsK$Nem='Fgs[ku挺*>䗕gw/M[tݎ4{"/09n'FF=F`fV9 g4e4Y0k1.NM} rmGw/`["#z#qo$5]j jJL!96lk3XIVfgfRԳ<2seѐsJ 15ʁ]lNwbNCJ{I4NXhvbRsg3=앫S!I ݿ"VwI:):1" Sl\߸9Dpk5,=yݷ!V 1Jhg9IȖ_hۍH<8HLDRCRimb]ee/˾97+l4}Y"zN,2afb]f6!?i(lY 3:SbfksOZWbai$./7-.(qIVe;Y$9i"1x>s})9MV)<JqJmU8^@(#"""""igf]=MτEALy;%ԧĒH*Zxx迳}\XMi9`pbfSú]եN1ոn)FZT"+K)^L[֧.Dk{"@s?xUbTnz>@&K>L4ZbCDn]`=bf 9XaZXlʎ k'F89qr僁l~݁59JLUX=It{C>CyogV̾^v }9V﹋7wډmnf;4-YXZIʯOm=)}vfKyuvV&*OmҞ V:TWb )fv 7*91lB9 FS?%<_P9WX6:A,;86y/qM":!Vڝ h DTw1D,?,Gvbfljr%uL;F7b'i\~[{IlSJW|6l `#b'Ϋ_%QWf0`WWbtli'fv/1i1mw%:jY"""""""";"""""""";"""""""";"""""""";u0y3dfl(SE>iB?3kU;4ͬW{EDDDDDD3Sp>>NE߶k[N{-/`vH֭;dV=v b]άSwl` p?WkvJGY` ,0xA>:epXX8&5;6pޛwl(pxXXv s.6H72R{Ӏ˲D@kbS'D`[>#̀qUI݀mՀw(3[5ӷG>ISJ &Ϲ{,3V!0&"""""""92玻Mpo#AfMaiYf6x,۹{3uOGSt{*>fa"PqO/383˞?ÀlBN !F]nfFg]^N(vV.>6ff/3{̺Yf&=ff߫rMDDDDDDD::rUw4+t)fv,pp pS>G>9Wd`h3rWͬGκGYf8Xǥ~ ̙l禲f:8tqS`~jj+p B:*7 {)b2ZI*e~t"$g`ڕau-՜Q?"""""""Id'J=80w6-+?rg1`00ݟ7N,UI;-Yu+gf``ﴼ3<<쒍1D=/P@:GqۙDN_e߈FcbzW`׹NDh1bPp'4sBA IDAT,^O>(3(pwR%$Ljݧ@/"3jffbOT`#1> TU޵硒} /g ϧERyZV3={>NYp'Sl%&aYit-"4D~s,GVLoVh,Еm/:sp';ln"1x#,jzq%dZV}Ic}:VZa{ *GBEȠ ]4תY"""""""hZl"mowi%/#R1J\Y[w*<^NSl^3$%fX"`]չʎUvZ1%mU;;"""""""(0%=(_a&wMp9<_̶V.L3ٔRni)MwO5%U.#.C$-ب<byUxGLZ*g`kch, ܁|f6̞^ r sf6a? . A2l_3;ppHدyo0խY3kfR2f6,~8("3[!?D,y5G|LK3F7k{dCJ- 4:-afWٮ%t*uw>f;p1p!O\ݹU`Co-dlN`\ e.M'm? f#}h6gHswf83ؼNvÚq; t[pli#f68 ORo p~[wPRovn2w?s./O5/ 0'(:҆mN_t`B>=3~N=kݯ2 G5W`!``%wX?Z7lzعީJ )pՒ6R;+}זkswTGÁ~R;Lo"""""tiYC݀rՁ}s 7F4 kK38XXJC@)3oKںX,H*24g:w?q m~J\OوMq@1}`)H>0x lXC~g>7m7!nROkc1ۧ|WMJT_k }#`gf;Fـ̝><lGq-ܾ4Gg d/` O=6cfk#H"?Rhw9?kN0ĨqF`x]}kkfv c6/^ vVop[q~Wt8q?o!kqlg3;{8wBSgS-^lͰ_+hW!<3d8Ȯ٢T`ϸiԜ љ;ҹ8iVEOx#fwڲUO/f>Iosi4ԟr+}" 1%lZ0eo/_Кi@-ۻ-Ϲm{?#Rg{`WJik}WEDDDDBgI|p|3"-"ɍrxT&FWp' ~*~-0x JL O":"FA"׀R[l`t.}wKzysQeD}}H]{31q[=j̶$ &=O~qSJ# v6rmE|o&WTʩ@LBܻ5L$í4DPmp؋#g FOPwpLoD̳t9mKLGT/3 X7}\#w?>r+AgwZV#KyK`E\ 0ۣ>N`'wl >g#m>pKЍps>jfsSfx|]w> X=-}Z/P DRDDDDdzW)3jf{ gfG{ro(ub_#sC$ kb"x烹X醴FMait{m=2, Ai,[3)iĔ.!@3;OK~EUT(?)T(?:w/(l[͇ʳRImX5ۦdt{qM^z饗^z饗^^ʹSAjpn>?'7s~R^ngx(gsGقUݯJ9/Or#lsX7h'H !$bDJq$]I`#7*/RZ; uNmCiN;ȾGh<1Ve{Q!ey8-TTm!jlF@4Z41 f;C+݋lKʲ%LN))ߒuFɶ& g;qXzUM-+ʮeͽE  1bjis TV_*~5j绉|3e*M|SlwrSH\jM)ֿZԣ6ffsD/ⵁY(ޢajkл^z3Cᵒlw{To+a4s;1cܩkJV*݋95F k$MMdwXwojyE{;5gz/ҷ'}Nf=p?Fܩ*S>cXgߐ/H+P'5fq\Nu5sXuJYrsSʗ#ܙ0I|A<4 auj8T؞3egf{,BLKk#u)0iԗ?阻{ o'"gh3M \̬{@3ꬪ~ln`>w}Ţǽ~MMdfi'Wv$#R|U`nw/~EDDDDڄ*Wr?Gi?@}.#qX~8s?o̶q'1 #AΘ-N,u{*K);D>IPl+"0t;v^)o~Ī>)lou#rJm7JB7%n/llVwyzߺ!(e#qq∦'Ou?8(g~?l^Fe׵OJb{0]ʁt';]X30%/Ϸ3ηVbtb&FʕmO:+qb5 $Á=[w:]pz*4}`V)ao FzB4OU$WoPmDq>VN ɶCW. b:KYQ$@k#tmo>A,^#&ooG_2 }3C~{dɶ.0-4f^#^z:x~?S`GDDDDfe#"̺V'CJ}W#cgτ>{("""";u2y X.W4?nɬ#M/<'WD:֚D^وOψ|T"""""5 ԐrA\D$} X7oA[7smjޝKOΈbfk7,?+IysVo9%vQk?}6 F)`("""""҉(NikdW!nlv`_b݈o;R;}X{S}ޫ#["}m;`^byӾ""""""quk-| Pk4{Vp}HKqJL/_̆ܮ5W~ gZ^JK1lfÀʖXw1fpA}>x^bj`_u Mt;iԶJ,wKz{KY >1fMln`k`mbEBy8S1ɱGժS?}zOvDiD>Nly"jj"1Dk+[[3uNm߂n7_-I)lܾkܖ"=wQ/Xhf]=-nrJ[ Xx x189w"mސ}ligwךq"""""":3[ 8g?3bzT40}Fh2:r-ZRp51ftgQɝ5&JmHs^J=f.NDꭁy{6fT_Sg7݉(%G QG;\$ͲfvT>fvp%0X)پ1Ma"`fv d:eS"0|`dy\3?.iT|OSDDDDDDڌw`C``a,oOhMu`T8#PS ;IDATASbE\t7-&Vؾ +1@aR_oS{YVS\ٺ즒v>ȕP'Bͼ/.,v%pzIω]ʾDȁ ȃB "u~K/K/K/jWg#1Fo:u$rw5pc*Tw4sG3bh{ Dݿ F? WasR}#F,DV[J?0o)l΂>bfVYw4=;q>"yWzuaz l.bԅ{H#u=lܦkv&(lٙH8>>HL{|$212f4֨>_Mjr̀' uV_z_5bGْ45-g$;+0DB㑹z+灮{rmp!Fu2ypFNb8˒kqF~o*bٶm;?""""""2tI23/bEBOOlR3ծ٤BwKOlk uڅi  _ˀ,K0#lTUWh{hI-\>GdIv,g@C>\=٨lErH;LlP {OgB_+w 5]SԽgzܚNU*lwc0bjMOo5ھb"з-of+++.?[ϧ>5+MZG}659 """"""n:SpHqCZ}Ab:3Suz17;-af fe/lUNZѧFl:V/ W;-w^o.ԩImNmW 6NL뼎esj}o>-l,D޹=YՃiJ,3w |M|!Hk}j+K>V7[}3ڢ:n5۶PhxIt`^btf6GI+ Iq`S"%>DAfDIۧ9d[KeS~ Fden5HG\A&r-b5Ͽ&h4O"""""":Mp_ gfe)IIJG{0[JBۣeqeyZ %<.zniGar!86?p&xξϯgGefũTK:HU8zf6,wnGkpWZV fJE|1_lEVfd:4EZ 7Y̺p`_,(K ߟ~n 2OL Rc |5H:g`N5ܚ3D%.WDDDDDDf"ܭKxJo:])ZEO:11+1&~7fo"8'+`0pOկBn>Pot=AË#\:`{bըsو=W{Tfu@mD,'ye"^JoT_p#V[Luz0z+o-wsʎ7"tdStRR(1L7e˘B"Ύm'#wqs>"""""":]p?/I,9ydEw AWz{mv]$4}-Y'Y߱j)@4T{-GټDvY0g HW ȬSwd)wڻ?"""""""u&玈w;&l3l3cDDDDDDD:X!IENDB`PKH:{.ʫqq-Pictures/10000201000004560000045AAD14F665.pngPNG  IHDRVZfsBIT|d pHYsgRtEXtSoftwarewww.inkscape.org< IDATxw$U<9#%)*YQ ԭ{:;UkVW:]Il*=_?\ȼvO0?X7Ltf6 xzs/r8KR |xpwybڨ30*f,`G &G63XX?;XX3Mw-{'y酙 |0f#˳w5 v^&3[3M+>s<(=ǼxEGl{"{QgRPJ^ 6TpEDk`̖gbJmE~Oicf/#J^kzҜ JlCQ{#pp̶p󇔏͈ŝTHy"^_<\@%V! ,;4%oFQȋ5dSk p33p:pre:+"xp|N# B&L,4Q3?DP1YZbV3;8 8QJCDdZq?ك]`Pۙ[قľX{ّ ^/j`ꈳӘüXYbZCͅLZ} SQjl`Jfi*3R#ͧ݀Ɩ5#}bfS3|x()982)-Q+eyo}Qŀ-DD?D2}vDU%o6Q#jjk`ÑHFDUL rGѹhY6{=lךWOU||&p,p)p 8#!Qm?"?ӈꙏ7t%jьmw 8Q.\h9`uʬȐٞJ; /2u~3t&`zٷf>r#4q&Gcf+3yznۯk dw?ݯt=W"$o :ݫ%Ն(?5l)3^>te\ l6`ϥU\DVMDqÉN!KfPjr٭y?1|Ȅ2_{f(23J~|0OQPED0zYl b ̬s2ƹx˨`f"j!\6D\Ȥ3"Y~ݷro=&m M&3hR]3!m^wPPED1J!Ss˛+y.pxIK~&]_=1>m.}twկmc.ƊRZ~W?2gau> Lg 3#""saVO9{Q^U3{5!^l `z;@H_+f+"#afÉ >,oyMsm>{xh9 3u"toϊLfȇ4Sᑋxldwxaɨ|ce&H9Bz6)ΉS.Lm٪fǭǯ9G+ǻC@k@XK56iL~@K&KpX[76[Dd4+ɯ|6xQ4O=x/{0o_M*"CefC/0ȼ^|dA,/2<27?^C\9|Lv5rS'Dbf[O|1Ǻ?) ׁMG wqӪ[އKl2{Fg*|DDdVC%Q3 _F`{%51w5+24fqoH}Z3꼈ffӁf~*+; 4S""s25wfQ=AՐ#N[Mwz~af$f?Lr,O #}p F9l{ Qk1?~eDGO5] k*Ow6tnr'CM.y;q,c71iOWUV!:\/5Xv fX|L!^n_'j1> ,,`ywzyYaYc;  Qw{kU_Ӱύ= Smfr9b`;J۝GL'Zw] <'>}fbf+5PL'%Q+o=3r w{mhMJzXh7dO?ڽJ?; ~Z/$:=1d6 _FfkgnC~^Hu/'oRbJ949Պ2Gu:f$뻈kUn]B*Ncf+mw$jW<OܽЙfp8{v2m'0SJF})3!Z;} _0PRĵ׍b D7 /Fֿh@ #k Qrm~l{2h]O:^EqK"SZ|O_{y_suy̮ԇke3b\*L~ A4;5hZeXa%ΤB 3Ŷ6@ܻ,rhv|z_zs'*ԫPgf_k3s.s ,z]o qN8[]/S o}g?YͨCw֯H5]#M+}Aqiߥ4#JUrۛ lmlw96}XYT.g^'pU)'SU>xNm8q/yaf-N}q%rmxF:X.Bth\~[7wHwO4Ml:-ZJs +#G==5}ns/c}zaZ|af8xj|}Ft^GufUE+T,rKN۹ XYxQi)"Ru.,{(X"<:ߩ{>:(ޘxږx}bM@i DfNhءLZok 6o" <yt[e&_,,w-m~4y%c^fvs"^QQh:Z=7|}þk[0Gi5vTZ"`rCatX~:XѤiOP+D%U7SH/īX%jjT~TuQV\;|,:?ө Rhӌ>1A-"i:" _N(VJoV}-N';~ƗLu[IQ`V!ϫyUIiפ Pu<Q+noƥR\O)cKw۾:ݫ{4^Z/4^Y̚Dm+۩ypd"Pp(9㑃8.l.;^ρMi_"^,jni׆zn%_$os;X99'ܬ5Q!EmVܟ/dlѴ<ۮD|zq̀6}ya'"FԀ܍xVh< |5י@+4MixC`hqW_!sgiWu4Lf[vΨ+_osL.V>]~S ]%fmۑKK}|P?Xs5p!QQaQ20_TgaƖ}}}ŶCДL:[VS"v^a߼L+1PkfB: :| zι4:V ־㖫>+/Yߨm1"ش.E iyk12^5t}fݓj~]xKw{1+VV' 8U.Iծ%I嫚>4γV tcpx6"Ӏ *wM*輿|T;V5UO ]lw](I$+D;v2?TZeˊ|D }`S}Zxxe:"bIt2||>i>WZ쬕;"#Z5ȕ*>E<Ժ.R>xxXJr|vWPє7TlK`%.FsA6knUUjxMwp|e8u 4Q[\7,cV,^#57si{X\^'ؤS;Xzs24߻W_]T":}Qg }c!oty֩Sr?T:n*?^cT"m~bb`}CU: J[5XѤiOaF~aC%F3ۊnqsV'~4&%|V5l/$^%:;x7TwY{vS1Mf@3[谴t1oǐ|p`drCS?HP]V3%eO΍DMC0$~תc.Ensr+5~_&CemGk将i4q4+B4M$ӿv?].? "yu/w2V/͟]2SuWwd-Vs]ߟ @wOr_ÙEaƏ"?_OSBiSvc3 X[>`f+%Wc9%E6gsҟ%:U//Kϕum1+3}4LjNvw'i5LGgf 7LsVsC[DIJÈ& ;2oOv {7W_I#9!T=T<t3nvw yKXoo.T l5Pf#pu' 6Nsnsl _gU(}!7)ҟǺ{%;\~uyk+3m,Z{uWN/C>Xg|Nf^Yޜ9@z7UW=vcQ۰[U۬&mݺ3aho5W=hX6HO]f6 TK4 N^ŋ^.~ѭna"2L}D>IM"f>aV]~m$&f-pKțjh`F,v7Ty[&/c 3[5+Zmm6 0C5xv3rqj73Sf 0t붊F!WޏGU>e:{?*-P] ,Iױ bv_DU̼Y QM3`F״] \'FdfѴ)ԭ{&)ZKK/njv`Y)==ls_Um"pѼxf˽8Ygt\$ ODdkm>GK(!Ʀ_ BoeS."_zZ~Im뺛HrMWu3?6|^ |sM)GI6Dmݽn5*vZͦUMQmͬ&Is4♲{҄ 2̹=H4!/t tTwI-pΉV)}|/dj~:~UrzؾL!Ҫ~5&2r/ݸK2HʪC%TV9)׌zH_r/U=bfڬۯnBT=TOfgA~φ^ J!DB~>C4dº?Nr'#lft-٪DG9/3uR$j[B4JSfv ;ۛNQ'R!Et׷{e?o͡R \C{ydpkiVvNiECso7?3ٷ7DG&D`e2I7r$횢qi%RU'vdfTtTO\wvM{ # L =Hrһw cU@WY؉~CyUC]3:\}}FimO2^'UK"Ei3F U޴ @'e'ⅲ7 Pه9ٮEt//e+aVjafԊ.BǚL۵ƛl`J~1x>;ጇ".:7+Z 3Pk#X^Տ}?^j]L6ivfrN$W6F1rFy4769(˽H6LL2b|7f#F_f:}wvmjL M QgkeN?o"}DԼxm*T;&_}9k:ن nw=N!j~cߡp.[16x4a3K,,]D&VWT,^sC1N4gl 3ƈM:7j6壌6Wd+3l/5ju ޹<ݯumΘfVg ̖H# 9?N/~sifvjqN c_sz&:yߠj΅V,u3{ +w_LByZh9AR`{Uч|UNvS.Lv@l/U#)ں1ϣ^X 4V3'XM`ŕ65ggVgG:5Zq'HǼ5*쀷;0f4sC*Mt2;N?!RGG<}-0IHU2іa\ˆ:=s ?YKٗr)uMuӜ^;2j>*7lXC$OJiH2̞W^OW~0WZ+;w!xs# 8Ww~kPS}w~:hrDYEwxojy; dONd# 'uDR\@5^ 70ooɽܛF0Wn^;>ރ3Q(ו*o@D-ƪg*AԞa< `ӨMfHrtOLJ~w?h3\9S{l '%ӹO,U 3w?"U/"BdG+gmoQ/fʶz͍3̾V>NMkr:\MlNK~1瞙cfNUzGD3UKRlQ3sT}͐rչ>&]˯,j,ӓɜkKMAܳܩe͒niwU܏_`f3 sefٟf.+"}6 zU`:Fuú \ >\w}CE:{7%}^n^K&2O,?GRf- _SۙD@igݽ\z~6gal=vUr~$D]ACT?O!:̾:[6~wMtC5^ȫ&4)ǥ;l_rV";JUW/wd?Dd-˝wZf$63{/rFϻ\a}5튀@;;,_u_NrA!^*DപEUe4bU%#b3{ݝh: &nfP4Ժ/fEM6j=/ ~ߜB>ՠʁ@kT]+i$JOtٌl kU0Η nfS7>sOD^1]9gW+e':|8"WW.A1c~i{gSw8JiuXgϊOe&'۬m;҅eh:e@y Qggt?OUTŽ}i0*klӈZUۘEve @y2`>{A^cit_"wֻA^XͻLkWcmJWud}aipjsQw4i4;܄73*rbL#(~Gc":On]voo":Hm}>0e{W6H ]1R.L:]ni]<΁]n{%ᱧ듨sOE:tD3\:o>SA\֭+xU45vDxi/cW:0[;N4=y"`+ҩuyYX2{|ˁ'_ƺ\8EWm֛N>ٚF ~[aEiY5A淇ht]:KẨJi.lmHO"fN`L`f ɜ;|}~ l_#zG4K^]t:Xq١mQxQa'-:c^VפIS4?~wC$̾2K[ӭN7WޚCJgy}]k?tHˈ&щ긵J \ ~uXw?`_1Lʼn0x0s i\-NܧHTuK=T{L)n:tX;DYݢwjOsT!^^Xv6G,Xc=ݽN`6뿢1saǒOl泈m2zsA߯5=M4mrϸ6F\G3cnf%kUDj݅R^H25{GTqekRMY^D^H|C:_M!y^V#}ءwoIOM,ngi7yyq"}~}}#%uJfu+L߯jۿ˦;颖h_D; ,t8f?^ѧ|nJN_M4b/}IS䛛ؠ6&;_IWt6ORnJybi_F4](?lUMOPdl'cʺr 40+5f_p_!#:<>L\?ZlXܚHsXa;isb_Ag/BG7=@ F1d3;h&3(Fݨݏ3#gVꎞ;i>I-:»8'- 83dazmI{w=:N&jmHCܽ<,D`y" sFRԉw>^@m_VDD~gX&` w۠3#""""27Q`EDd>`fgu!X"'-e+}r&""""2)""""""""Ґ4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC 4HC+uԙqz=΄7 8vԙq6XHDDDDDDD!VDDDDDDDDR`EDDDDDDDij.DDDm[u&DDDD{5RȐBX隙MpG ~52i~R7Of0@ Xtw3 <t`YݟC̖w:9f8?ևu0EGG칟;'l:! }45 ̖5}l IDAT)3[fe _fv-p/0#/[}l3X:,p3p€s4o3[M5ۀ7 (rf9b?}n^n2n cf!mq]o 3[mfg:?ef"3;' if9s}G0[if \YXn3*o`6kf#7 4+"""2!/wZˤ 'rovnGB=d3i n*08.T"P'O<\KKUPz5  my5=q0&3jf?WYeJ{>%q/Szz_\8}GJ˿xݟ!툗ˉN;&KTJW͛tm,\JmFaۉ&dNϪ{Szε`Ox{ıs_ ˤkuwmvĽKHCS1oӈ pjŽ}^Ht0]nVH}q6g%T:M-XX➿FZi=XO53gk Yxq=o3[ X=ߑ+;ݽX*Wnc6N5 ayD KTcEDDD&eۧW)/:pLq8'3;l7K'iVMMR~HxpVmcefyfvli{'[3-+}h?O_Nvg*OS df{[BRDG/~w3Qޔ޵ip ,j4]1gىċ;ӼUO٫g!ػǧK0ZM1? :ݘط-MnE3?pU ȴ^_~2ıdq*?D]ı-7p Dl~~)o{,:F=xYq q=7#3=x|gL#1ϐ0m&gJet"X #忎>+OR3[}珤|]lfN9pY|i_K6{XK_%,}qċIlt}Do1]k@3kQsň{J)o/--03DgLV,:=qzmu77Ľ4GH ´HyY8[hzYoxJ,J'm `BSS>WL(;]8*miDˀ|x93>-;acy~!1xyrw4iҤI&MÙ~f~_4|j"FMqL-!Er/T3 Q+ ^AtƷLaiCK9¼Հs!D1f{eݰٗ]x1IJKD&˕),d¼wyˤKTXf3"`xaKt,,+Z"ot8K˝R7l[Ҽ mS{RL_L-jy^;-snB{n?lF,)35Ӽeq8ܾi/J̫Ӽ+seN鳏?@O%j_f=7f%o;EoZ)ץu0o`5s)ÈZHR^_b q^Air?5Sv,, qyna^)ϧ`}u'jF~^gJx`4]iN{DB[Xn4of:7&tZyK0DV ˭Y\qWXstM""""sw(uݿ @T,/T)w?=SvUUKՏо?7 joGi5_OS ީ@Ī._&Oy]K< 1_NhzвWo|DE}>/yO/`7ҼG͕ 5^jf{efr!ڞ]ZnM"ط`oE-yrVa^)@;)g B:3[r[>Y[y\qNIy~rjit Z~!}KR"]x햾oQyJJJ_tFwߍx|Y~`ak#iߴα݉fT5!qkyDgxhq8[jmz/sӼ`Pk٦s:0ou2"@}^t[i^<Ӕ,JwΧf"@:nثλW߯5<"¼ҼSͲV Uyߦ}ۢDDw[6[&+E'MxH//"]>ۄ'"8F3.mfyQUM{ ;HoK4)JoһHJ N@8?Νd޲;|}}ܹsfݹ2U~ 튙b܆+f=k893os.A`5I3L zHW W2/xP^7fd`k7I$27LgN0O ns2}ϔ&ŀ+M)fv@r%w˞zK ~ʸÓ fv[IFߛ$[Uҳ#nsO*UxjxNxUpbBV:*+R.2El{^ƹ1y<@8ٙ06NdCrӭ$}+l_+.I4'|_odKu+ ߋў>c82  &j{EF5_bd}KeO VIV!@%3ۗ_qF:=W)]:|43۟\6R:-31՛u,Yl,OWntVnEFUνj4y­jxܗ$]l` rpĸײBEHc=[E!?-iȘFK1wc?Yq ri\QZãژ22e=S ]8g^Q~w'Wvq:x&izI7} 1 dny_ϲpsshů{۸j'WF9oTgTic +AALʨB A_V\hݻWef[A>s(qce i{IHX^VRV J:w%^+n7*^q,s_rՙMʴWsi`ﳒ3lw`mY L2onU \݇+.L+W9~_??Yeul8ʓ[d.Y?ʼOTQMhFqk7Hں@6攍3,7 7wٯ,e6+(uǧ>6pWpwj헞 ߚguXlse lZ\hORq  z̵_N=KtӠwR\ ̗&y! b;mj/n[j)C<5n5'P_O:„8|YrtxZLS2!_(' (s[N\}qןg`IG:wDٖr)^x;JZZ3l+V*.V{VQd}QNJ&R;3&py6&)JWCu6q1U/1%e[b&onTEj=kNήgv9'_2vA\[Ńqvu+4&yӛow8-SW((}NKu~eRcɗV'bqi{=YKRyKǫz >Tvs#_cfnnq{ TvaW?ȘY+25yeq^A(V  m,̨3lkl2MOn6\ULͩM9x̏GI;:GHVzn!H</'khWucfF{K%#D1Hh}񴣤l_|O)F#''w㓤?ůIgE3[F#ZSʹzj 3+ fn Jڰ. GKJ% a_=V V }+8.|t:L ]y?'y+U{`5p.Yyl̃nɸx#y^Kf+~`#,k,V+t/4ϙʖ'#pL!3_OI:x xIfMEqvD[|l+0Ǥ}<ɾ%{.!߯p˴Lbv֕vf+1L2㞤*i4ʾtbץ$l;sOUsqLX[LmƇCұ+Kuo-oXyXL]9q!n+fI$m!g$=2h~.$[MGqEfmd()nv%܈.e-Vfs ' &&F1*Z% s<$/m8ng)i>I:.u$)']~2W6z4y&G675*OE~u6NNW+MY~קgjR'-AA0ӬfN.uzJROIS2S4IRtN֔z>YLQ 9~i eTA  & R wNH#i+I)m?x_"%ۦt"UIdW봹?o?YtI񵯤gAII?n8m CI?otQ#>r)$x*nIӎg} & BA—wi1`xKl`[``҃Jka@ oQg(ۤD?)`mo>',G_5!.0(Z|}ߗ&q4[ JAf@(Ƙ٣ ֿON, l JS̵0w7f|6MM_ 3{Wjfk0w[{'`/bf"&7BA+߲7%mN>_ T7i)Xj[` u[f#( ^FKfvolz}9B;pǀͬ-} @X>Nۧ(f4:% 9nf6SՁ셒5.ԙşF xߘw!z̾mYwn6k*}T-h@< |2=py{ 3M8ǃұ[,Ɍd `{g-vYq IDAT[I6.T#x?O%ES〣O 3v!5 8%=+^v}<6G 6HVǯk`: g6S`;:HIs̩;x!)mj (Zmt/I/JzNҿ$-~<PIߛE ΖtpΏ;st?~k"ia\a6 {0*) *pgF|ގHJ|{ߧ`z2Gx'mV3qEhvVt;Q\bǸcK`T㕛-W3>1W~fKeۦܞ}RrTM,O$G~'OҭW\ })>ɛ nѓ::$Ε xPΒ+ Uv'ՐOgʮLΐ+R8WTOH}=PNv޹pcse-Po*[?,ʖHe]xp;Ћ߫ʔ _[eJm+ޠTvp*2Wo'ܢ%~\GGsI\ 7WTo\ҩ\p%, | ̚+!]yנּ{ C"pTvDj*ǽSn}qh#>O~@>/HXA翖3w2fs=*$㙒:nHW\+WO'wCȥ6o%ݍOn^uƇK̓+L[+ W0I(!xK%~#i.3{ʾgff~OqNGKz"մq0%][ndA暓at^:ߑRW!О-懸ESmU_+/`kwMy7}_kfS>-2^)1xƝqK{̃f܍+q'pswgkw煱ng'W'}h@pkV4𢤙qe s m*//r3|O<wy'W?naf}$R~|+"<ٽ=;7 OA7nAsId"B<IWzzƬN7~Bdn,J1{bBy+#7D={LOZDZwy]K) ʵ_+kW ^&c.-jN`91*L%(>y+[[T Izǻ8o$P6\yof e1XC8cI[|ܢi+3o/3**Ig+t%Abn';ot'GUE\ {?; (ٵy6.Lyw)0ǐ41C IkՒ!CXT9kf')x`SӞ/ ee9J}ONOS:g&,Ʋgor32W PTc';$e+8$Z?>NT&tyYw&)8V!i!}=CahAweI)TO6'\ЮXx>knO1C6SގE^_8 ƕ+q $VȬ MߋNfO3411:[=ǜ> J[_],Ve֬tb3FԸp3pn[Hj{]SF#%}ϠtsK:lf$~M㷬t,_#dڂB_,߫Hz l\cfY^4V_JzXŻRsnR eJeӶ8?'d}"; `fK: sڃfeW c\ƭ~2˔M_Y}vڃ+o 93}I`~IJ_JZ$)peNIv8^p`SIoʍʞ?Y_M$Y% )%A7kT  ,yݛ&kG)~ f6a0]n^:ڀ5}dQ"nEs=<ѝxRI4Ge%M'@\A2E1q Cf3<`K>|*ഊnYp; d<5g%]+tcfï\ltNQfB'́!Gt>Iߤ`e23{W-.BO⊦xt͎rnoqeb&=]/T"g\Mjk*kIqiĭ攴*~/Ej1 +}P*eIJZc2X8Y}x-IS'ˏ𴿳axܯ-2㔜 +sn+QŞƟMp7y~+F.0Cq]OesK)wK<M27Rtm!Y+Nc[<Tyhmh{ܒuzf6v=yx̞K\+RY3,ކ+VcL i`tm6CIGK35^ 0M||o 4$feff/|:1f<^4,J FXAA5I. 3!Rf]-䆙 APX    "X    "X    "X    "X    "X    "X    "X    "-@0ibf5[I32L*^^͖cRn&  `2',V    H(V    H(V    HX z54` }St[K[AA$O(V  Fk20'00>;M튖π:,4AAAPA]RWdwih7ct1Ǵ+Z.iik;  &BBAZdzҤKG-M%  b% RW,>K)DG   h.X hT`\% ͔k"&+AA9X iTJX#A  ɜPALBV*J3KSAA%+A)CiWL&Cbe"Ffne)CT@_39mwOҬf6Q'4}V(+7f4zmߛ.p /0lYƇͤaIfSY{B4[ qZ+%[+}[+k'm J3@RIwc{3IjM{?>./IKx<%͟~t"pzު ,\e%] O$&8`4pD/$|(if˒!k%m@>,XIvzP5ZYY=7!CPX $pɶ<͕)@§ A(Vz$]`fwC{CvC{ͷx0Wtq%擄x~=>Hfp@%}j~o^1'4/~MK\i9xI"1 \Qno \L{BfjV,zܮ#of=,id34N(V zJ_`M|+`Jyz-mm"BK[W@}[++Yzښ`D"*Βf^7u>o 3#4z}#Ih4=pae}& 1^>e-J'?nղGO+Uȳ f62LTH(V DkXWl nD| <8/+V>EUWT_@E2IrL8 0>$pe(3{1 įV|&? 5[TgZto{iuBqלscFVg [3%ia㞢bz7-6ßZ;Ol {ưB1cXfvO+l`;\o36r9A3$mcO/~&jfvi e/d}8P2΂e|0ܘrȳ67n, j;h>kDEkzkrp+lÀE[~ֶKK[Zچ=T z41Z!E'=(#exRܶx=-\Iأ߿?v́q7Gi9mGiŃKA_OOغ ~+ &HZ_%6'\ylLؿIVuԊ+Kʀ QJm85ta.x\H7J<;wI?*7n-".NrdlkB6ǃU ^ާOt֒t޷Hy)smW~r}yhÞ*F>턏a˧kWnK۳1ltMǯJu%ϱS$ X{7\XG%NUß{hwt(p0Wjg6Iac⊎rgkXKU9~ ] ܖuƔ!x=7Ƽ,)xy W]]BeXcfLc͖'>Ϥd.0`K xɟ/0`%d/0`f_(e?n`T㕛}^/G~ߕj \pA\|er{zE\1ߋɬE_WvHN<>(n*W͟8ǩpı|[+V㊉qe 횎ْ+;7{-:Opu\qKJi ˷ϖeAnh=ݸPw8ʴ\S9BީRuQw0{*:풫w n>!Y5WK*ۣp~S#qeud_ϗ͐$f*-]- ʮ\e~ȕn­Ef5ÕyR׶p}{1ܚg\<ݚ+[;; X0.\w pTrelAgs1_l ǰ8e$M)a>1Y cHYS=0_}|y+ [V}rs=\JCQ2-O߿M,+kMegSR*j֏Sѩ~vOXAL@Z+EZ+3󀥚 $-mmZچQ-mmlL`$FG/hb>`aIGHcf?lof7$egl~4g\, f2%Md5I{%lR H=uq1+|߹gp˂f6 _1^ O3`<u ӣs7-l[Kd;wɛ_86YN`n"c][Adf4 _Ȏ,YAT:f.YrYH>u+p~3%u.]v#H1Rr}pk\y͒矛q+玛ޠFGoY=[OD,35q!+O-ws1wKX_RfJKڛKҪ#B,":cب<3t^ưsc/ cǸ2ineܒCt>E}y;}\'| eFUtcO9;W5MtSfH IDATk6<} na+o{G'd @X fR-.gWN[^j A0lYH_t4 1 ܁ >!;̮l3{wa+'}2@QA@w;kwpB'O]4A3mOX3W㫼Y8' %fv[=dV] X V̆}#Q|y!̞tnp=q_t7"tv]A6qEO1!baq-vݕN #$N B_þb"S%St2|@Gp Ṳ2uu,(Me%+S 5hWQvoĕez60Mxl{$] gv| ;Nnp W.ưYp+r&?FdbS;8 M Ooxc1|3l0LO+ioܕiLT—3=l'VҀ$E+2,PwV-Ê"xm/',V JeJX|EjzNRH-mmR%8W>d7?y૜WHL<c(atp9?f7J>_q@6j"aB$ UJN~tyLҏ"+~Pdۢ#pws1ca]I|rYPL4 Ms=&ߥ S;oOFe9ﳙh1U`w,>7i,IgD~WָAxJFP0q#~Ⱦil ;^þx.h[(VVr|Y|+R>/[!?uLY}lj{KIi#Lv6&{ p*\i\i::4Kk4<%'tֵX'Z}'owb13E2=L(V :Ikfk2Y_e#ܔt3`pK[ێ-mmjik) q$[Z:G=Pj83AEAjOk;"גv~=q.˜ti)b^$-&0Y ՞>kI[SfcwL=>gp>`?gʘ8,gA8&ۂJ:WgMx:=ؑ|\1sl "':7$ Wx 2׈,5@ҠNх![o?oP,?xΟK?>k#3(lWDU%ݑxfZ C$Lf<>'vܐ5]JRgJ9JQ9%o\1{K^ҙnH{jlj,^Ixݙt+&ߧzJڰA$+A ZZ܎5}7fiik۹톖^wJlxJ*Z*R| 32MIm t% ,=N'/L#K+J= Aw'7__'aJh>Ejc|r895]e" 9놧pW3 W'‘I+#V6a3'5x*M661#MWfU +=5dɎu?>9(W VY@Ҏx6xfdTWJ 1ر"L&&6N+Gi$RvKx06x\"gW)Z>~/BY9O6p?li;cR|$Mo x0XUE*?3Kv@M9{gS ٿ$+iFJ*(]ۀ%]3<3ZҾ JE[X\c'Kレ ]#|Ƹc؁fvUÎ| lP2-F~_gR2]8ݽN=_gCd9R5a/qָw}_)_ \JNBҞr£q,@ 涃 `@ҏJ>W%b%ɞJE+f:iik ɒLfA'+ALִV*KVW7yQK[ۻn%Hn 1IrNnv^Y&@*)SN3 8eJUo mz@R?`(+ +&T_ `tALV*SV*Ҟ;PAt4P"E}x^Ss%M3HHZdxW:ْbu+{ʎ7}Y(`fi5P-`0ݸ(ip3)i-8E5Y$ǁF*w}&e _wyxJ `RR ?Gpnr^(U[x W6>7GW'D]N?Tز*ٗf]`1X7z ('l%~ ^7R1ڡ;Lpc7c4=&=[6Z3;zBȒ'wvL/)̶5?wǀ':+G=CXA0Z_OWǗӀ[:Am\ Q' ㋙]*iĈb`HI+KCZIkU|w/$]V>4fdQ%-FGeԫU~}14|//ğm%9>-5]U(ޯG}-nu{ɮ!Y̶8ytnt}V}ufWoVoH3ku>A4FA0Z<+U>WRkiku(U`'6C;Ippo?J%홶 O| I7KZ(98OKy1wŬJ&HZWn|ǿ% u0pQF>xp?ӤvVt EM+ENȉ pOZ1we<~,J|K)R@4 l(/RiKRs$6*+s!kKj:IuzO~V-U$ S෸K]fL PW92H7+H:W S[wï{Iƭ14g¯pqӒqfEηJ*QIvft1 p` %.H جR"]`[Retm_ v/|5 0+>/&_YKa0O> 0%ɀ \2`fS|z[͝*rϫ2m`p\`q%6:/mp_&-`'?_s7x.R8 W'ýu߿Om-+ xŴO&)d\%߃q˃Fw+X<=5nE4nICse/[4W~*[.w1%"\:;0ɊfeYl8Nݒ` D h%XІqܹ3cy[nU;NIs3`\SyBL?(MxX0ϻkҚRڍ)mɔ ]J;G7]Ie>,Ʀ?k~W5\Υ8l.W)<|~σk\F{Q܁p^:{Ų^.)V/ &}\,K5wD.mvU.mT= 8.K.TK; ۾BZ^ 7 =/t+ALV4J /һvh*i*{,@5 _vUAhitL[ϓ j) ^3C.iw`7|5R1~]y GmÅg—Mͬ*GN(iE`fZ+28%i_5s}i>ىz2S\T),x3{>1p#Z+IasR{7ƵKfYef/Y)ffv O21ʗq%S83{|nfS`EEW43{JR?} #WQ~(w7gOߛfmkL07wzpZj\G_sCHWG}7SBޤ8?Åp5CMˣv7M;t.d;|21\e33 2c%ɆRi|A1|T.~A<$EFŏ$: ->4;Jw6C e•"cq3 fqG;1$G=Zw!VS2\sۀ %I u$8Z{rM5:N\go\adz ͏kA܎ 2VLUhIGY _ᴇp3%qӍ>6NٶMȥeRɯy״ZqxrpAgR{.VLǵ5&afըBv;ͅ/ iuN_tV[ni>,.ʫ0I[}AtX `\*h..{B{%߄P%f0IswpZ%HZ7mxv"r#R2(~>訌S;ÒHk?т/9쐴`]/ fNiv͹*_e'mfPϖj4D&VisW}V Dz/ImIPͧ*QQ$cBbߎ}Tm/NcX }#܃ sA-©c4R} !o 4ͥB(`'`r2A;HR fv9{L'Yq墰ԃy-C|JK$ӚHKÅ=Y\fm.R\N-k, .Sr IZ̮u1Lm wR y7kv7M>NipÕƳj<ȇgcnNtG'ڹ t7Ie}xVZsIVGJˮgt\ajY0< dI踯: IDATnB9t]#i5/g}20̞Qs$-ϏD6<%탏oMIl|,ts)UfyIIKz7ti~Uw;=i6kIiS݇٩9=5ՙRq9AOsuGVҹN[IMju:PA8!X `@\*M\M:X\.: 1}t%/ < !ivIB-VwmC_;|7/zx0KҸ3ӹx(4-noTGte'\ԆhÁ3\H?L pqizԆ1rUOyШ+])ZI.IVGINv+ 9yu|,)~2Y<)w{0c^IM4_Hv6J}C\C詈Q)Q >64_j_ ?IG(&u|HB零WC0I$iF95pTq~]\sfq hZtώGyxG%ͳLT̞M|l.M6J3N"o+9l,dmo ƅEo㑀V5YJŸ &f;ck:/+]փ{}tsI?Os9=.}ƵffOHvT\^ ,lXtQm6`q t! LsΜAښ,ك hd$p=EwZ=G/iE3۬/W>I̬^pp$҆BvH2APR{؎V`rƵ*ޢ,lK;z^_=>h z(7|}%T)֛GBoaL)PRi1\ͼB!T E%]!id68Տ)͒69$-/M   HV W4JG5WMe nRAAAUBAT8 ب\M   IV 4J;wԷuܤ    J}Ns)pNN}X\~M   A\*\BG+P%  $+Aͥ t>rƷ*  ~BA\*-S~VAAAtA\* 4VAAAtX Wi.fnf7;P%  DV 5Kp=0G'Oآ\VAAAtAЛ ,s6l*=О   n zRi`N nSi4)  ۄ`%TZ8fSa4)  !`%T \LщVo*VAAA4Ac4JC$݉T.3   h=&X4r驺 q'T.C   h( HG-gCK[23Gs:pD'OYSPO'  'h`EHN`Tcfv "iFAT =c.j*&AAAX = 9 = 'iD\*:qn=Ӣ HRT}ݎz3c_?"i8Bj=z iկH!ip_#&C\$IE`AX?6n*A0@`]Z7f7Mܹ?O[=zDҴθ^`>mP?BrXn<Ѓu&ie3ꩣS?ů{4@<8ZRiLWHmf41ZlB7]oۆ/t}AE-X;-I~~CKs(m}+uMM=Ԥ f*w`(0̞t0X6('Ic9/2 Eޮ"i}ްVƻ[PW$ ٗ..9z.`0/$lpA-{9;pakAڅۀ}EH%sMl¡~wf]yZ7124 34Tbf6U /_? (ͥQ8_M=Ԥ 67% DP`9E 6I+K^REڒ&IM!i+II,iI$(5In.iIhER$-)itS%i IM%iTB J1}Kc$m^X撆$iwT_:gR[||C$)ikISW(g46{HZVҰi4[otl-$ZoCIsqX6͓Ne%Tb1uye=&#RڒN3p|g3҆JX΁4SGm6yip\0 ISw7E,=% qcKZAT+ٻf1 LT|7{!3;0 ` |815iSlOc?ʏ\,ܲpeU*,LL "%qI{Jg ˻&8H r5p%M OKZ0 Q:ct ՝$s/_}<k& AO+<[!]󣒎αxLǎĵ#)tVI}1j,ߤ_kY>4K9]帏$m cQ|]xDR54>`juI/ϱU.M\ yC. } P8$> `ZI^ǵfJi;`Vig}Jj^3+<IsgG$|dBQ1]Oo?s`L*g>IWqv)W`A9`WB3."izAP3}d_'>Æm1~0ns|o+?^tԟva1)}x2Me ̑Ji{\=_`LNJ睗K;8k6;wN;)]QpaT!KV\c|yr"\]P|P.)7 0aBoeiSᩜұ#ӱsҮÝ 3sB1ps(|~ (g. Y"}* }h.)4+t>ρQ#q.mJq\k4Ǟơ[{)S\Fi{|? XR~J%$]&EҶnCCs4 Npt5'ɋ n:;՗;(<3{=P%wd.;L^>ZMHsvp-ٹ+摎̛eZU_Pޙ%DkAsGJ#>TK\#ߟœ q֩fn \ a\9kըwn`?IKk('3˴;5w&\$#3Kɛdlf_fRJ{d^27||>JfUwtHwܼ)ɳ\N̕SOgfvu.3vp:oB҄Jdc54p!V8צ97|ʟ X6ia.7CSAt Vp֓*5jI-3vt4lO iz˼q팗p p :ٞnvX>[S+0~;}w9[}kpgCVcj!=*,OmNKN#잪 5vM6t&WCrYfVt.D˓jl|A1;L(0]7$$T`t(oUBƹ]UWwެ$]X)*][?6"] l[ҏ=lfgIZ$e_C ^5k0Vb7:MÒ֫cNAtބd?"鷹cR;e3XYB=Ԗ zRiU*ۿW㜦rAL"5npy(Gt)^UHia 6*|>N{bG; [+=M!= U !T[퐴n~1'YЮ*MB*U;ͽXNyz_^9/I\OLYc UivÅ;ErD{uun6U{qV5 m)iP-YI*83 h HZs~#>'n;:ZC1Ai.꘰}Aԍ=Rcl)iCI?Liۥd@s<.x^Ri6ό9<~K}$m& ܬ$gw&*jAk;<6fL]܉JΗtÒC٢)Wl i{ZCbDuV;̹7{JU5ʝ~ɏYVV]%>hfm|y_d%dV~==Y]pI5~;gkx /fAtF Vޣ?-iu3 Vf%=\J~\ a.c|W+K$mT^_B㒐`A|ւxq/. w[&-֒VN&B{$3%̒t==g3{51;n2 I%P!ɺ +9shJ0gRF/삛Q t.jxOq婌uqGwyY`>%q%m|?շqfu 3g| /fJLy9ygbfVVjW u<:,He= ~k:)6'HO> {I$"&?wW2wӵm;I[:֮e"i?~}X_ IҺݙ"=ȳfV]CҰ*>̾iVRC&Ap3;uDpmZ3;56# 3qz z[I}\U AY cI=5=~C nQI&Pɕ㋯]Xk4'?G2S73і=MI=MC+f;IvC;kI+;zjw7NkUnZP\9g8`rT/:8\ ge_6$1x%qSuA=HC+ɞq ܑ-q㪱-ɦ+|{ުI@uAcT.ٓ $G;%sL&?_⛈1[}AAh}&'y*f68u |IhwRije^~Sm ({Nwu@W՗_A0h#MM)rEzib9(sچŭM}g HZ!0f0bII:ՐzfȜ 2I:1#ihOO"gd!ޭyQsZL.HH3%q.;ww+2L.0!C.Fs4-mQwoz-A=pq #Szup_)"i xW:1$- <,`3;X3ᡐ{ISᡟ f{<) ߭#\> 06=38 vKH9%c^.I!3uz-]6)-㓯˙ϧoᎡ3SO)YbCoy),sqp^r! 4Kxp|0nRХ(@.A+T.?ғ !>3K5Jw~"iD-, L0 `\0K; 29axwY=_Z.)[׼I(\s~Q&hd%I|nu\/s᳎21p!ܙ'x'fvoQ`3&w|EC\aɅE6 󶡘ٿ$ MWG<%k|~ hf3Ai`ewo 9n^&O. ظ ͥh`:V=`afoH_ IDATP! I?hP=oIsoIÁu-:migcfOJza#3I@ffVO&v3;K~S]=-)_OLNafwQCA* ž%p1070 N;Tz-B}[5_W$$ #=-i gr&7lٞ=Վ4Zr+~M\چ>IcK/lR3{Z>Iw7%A0&rlLAi']O}]-m[`[Yq֢u̍E_P8料]5H|X7*$(>; >y32pU- ٫6kԙ"pRAf5ͥHV ~I__7#~xmS^,J'ia3%W+3zHJgGyρ_O lGK|4*=K[lf*f唀?臨7mz}7{7K׸"(nr{y5E9|sOnW|mf/k7}ifP$͗E|&u=H& :f |[7x9JHIҺY%3L\C璟Ol\U\{Lgf91pwq$- ,]q.]7MZ8ϭ=Y逕p-'v}#.F8 1NҮ@3p)F,ΩgfU:0m}-33\Y\pyfRor`&CS9#ϴgz'A>069Bg2s\9pfxr}Vi3+CRX?xήL:$_ 30g*Z3"8ܴM ϼeݓUgc-鹳*n2u[S7 .x̞Z; pHH6 !{)?Kz@ L Q;%Mrl Nr>1p#pP0|1>>r\?^8;*gN~a|r8hZGšp ӹ?ǵEf%= E2B2XCүӁ;\5MI(.gǝ_OM3qÁg$-X^$ 96PAR"<ע-vI]Vm؆ZZ$ Ks `'w;/I ${pwZy%2w! p1p2-ɸ>'y-:!Jm:iC^_KoIcu 4V8rlcTG(Ni.]ϭ'$p|]`<0I91DѴ͠tίx> H:ܠNp7G;:7URs௒S۞/g \smd*gy}?Hy4zۗ+giVZ\@s p*.xA.&>mދsϔÀ$mT8&>f#.IZ+I挻8k"ps+ŸhqW1qϞywI7IPo|<ŅwJzY ʙI3~ذa?lfau/[:{ `uMNAE36kJuܓRq;xk8ssSriZ&[Ҧ__w ~ X:sZ]'\Z0~X!͉^Ay3s+Ow\ ]=_3F *&3~ l~5[Y?յP=C}Y.)e\hqGgN nR*0,ש};+qCq-upZ.opǠ\Rri3Jsi&`!\8UR3A3m.T3$v[746*P)}ڳ_ʷ`!T.@jR0[!C\In_(4?)vd*泹B;.J]ޅk:g7ӆ)}o;rɔ8RJ 7;0kQIiK|W|+vۧ+%.IGI:V _D|rKHqKؼx cG\=\T.#A7_N32YXGa޼%XcvdN;U;1;'Rx,LB^#;v$*Sӟ&l {Ұ$w[W*E>kfW_h#Ѽ |1x 3{13{.HK\۷>Ju,-yqefك$iP|q79|dq C+Z*~K펹 qyS [_i;\#cF\(4kϞse_|.m72Zfs$3lfD/Zޝ&i4*nt:GyBsᡷ7He0u]MYl< gf]/32n셏馹q¥ɺ2M"uCf.:(MlNjf;.T̛dL칝$ "i^\Lw ?( iE _+APRiRZA9wjfٯSp B⚿f$݃;!:W>9LgT:̾Q-np:ǴҪEy OߙjXdnG$0G% -mvP$~3{ٟFX Tuvom Mdk<nz}>t;.ę_(13@Uh1IӘه)4oMz{*oZָI6JB₋<M]f>\1!}7*5/&'&¬Rd΋>]\ ^fU1ߧrV…|&sпҳ$I3i[3p͞G%ȕ(.)Iza9_0ݠ3_Jq?Nq %-a; Ξ[mf kR 7o7/X_~!\mB.m.E  ޡogg{fb2:pȓ+ U 6e\ əi+M (~pao3 |#Fonr1E!={a~|kF<^kVgZO9^̮k ^PS;JPiMip޴ѯ7c"S\ :m 3Z76GWWm,}ҒN o|W{u̞&AUƩmzH[`*utU$ 4c3\I3%xKkdUhw;?]׌Y_!Pe K)IcwA]NP|/6H컋}qcכ>Vr'uvC` nnXO9h4Z4pmbf'9\f)c$9dGs3KWT6 z3TTN*&Ե+Tެq^?!={Qjn2GRωx ^K[HZ)PBjfG- ~<-0N+l3?^K[U(wayTbbDWoΡJu a0(YQUjOqւ??kIڊ8k<ٟ5/hs9s({}UW_afk>fdf/L̜YxFJ;8T;κi6oZ!&=ؿ/$I fBI#$-- kB# ɘΨ`Jq;%m"ܙ>xLa=S,ޗm?Ҏx+s9PO9q!M]7!IikJZ'}#<[xfϏLp4>EwƟ9ܜK;?MU~Ew;4Ous$= "\uK@YH7iQ_>y X tp Ϋ>)j#i퉏o$݁ yJ<#i3y(tl=Y*\v}ίq36<{g\C%[` Ls͜s3{6;W}!=B\LN}5gx\2>QM m´=wX~tx2}zv^EVq݇k(i[7KZy,.|h`\΃k-BIJ:R˝w ţ u{-X Fgv}|}J7F- y#G?G0C A]TZV'`S|Wق 37O_\;c|dp\u;|qnI¤]Q) u`~IJ1ջtf?.inL}ϳ;&j^%~ _flkS₁2#+ayjz9 H8Oy5rZ_>?@x$:^9qoҵI?ވC/ ϔi=SRQU+i|,cT$t(ВʽR*ʒ\(<]{ښ G;G؃q]hIL8p\ Z?5?C_ L[ 3*8rl6.!]ef㬧iq)ִ:!1T;7WƱ Sf) 4JAS|cO'.5ŭfVkM,AQ]~\Ka 3~k܉|@WY=_Y.3C ~QZKZ}"j<x|_.ͥ2i=\Ճ pHZ7Rx:ATr3<x$}pK⎍G江] {^X0{cq`pG7u|l_:8uuOŊLg"T.phA$9;%} n2L${w^ KT+ޱ{/_^Ҿ ɉRi< E=\ԃ 3$jG 1wX7igmxQ d=4W!}g06:T):2<hH%lfo7$Sv~5y }!x V~ ,a{g-|xi AAk*ht8%v**<,)mtr"ӆyI  Zo+I 湻[^_ i!~x+9vDҌ~o Vմ4c𰬻Ǒ?')mJjh@;T Gۤ<zQW}ݞ o }+.1TC^JjHHY Tؼ&|A 3%Sl.:U 4BM` ۘ_gH C0 Rԋ&03m7.//zsipA\tmȋ+s0⽘@w5ڇM ~K1Jg4a𫊙mfIz` Kܓw=T.֋VAoq%f l 1g(O=3+|m?B{YgUjS†`fwmМ.af15\Z~2wQޫ= ohif/53{{!"|vٸTWq4۳S6d췙=M`r;;+%+X9XVI?𜤻% [𝥹Th3=؜ ^GҬ 'YZڄGߵϪb_`_6.HYk\SJZO/RZ{1=U~ḇBZ l)Kc&F,$iA`9\f~.@bIkPA]W<\lAIѪ0FybIc5A&M5,?E8QM3C I^L1+ VM^n/j+H*˦<7fHQ!V5JUmISZÁZf{ +3d6ŁqCO:f͋|Q IDATfjZϗ I+ߚY^ҘեyT'i`1`_kǙ:)3-KGo/V4?7T)̱js޾BwuW~65ؘb01`z BB@ =HB !^D {ok0 }?YkMҕ%>}4;;3;3w)s^74OX`3|R``+_fF/J/'?IGߚql8][:[+i(]-iʌE:ogms$/¯\>>[SIZX6/(_+ർgI#޿S8A`35Zx>1שּVM׹ǵڝHtFcŀ$.BIgK:Gҹ΋.IW!Dc5V'MNf?{3{hh`IRi6`:}%B|q.<@ɸIC7$;;gå9K3pX %]; aK6Ip׸fZt1nᜟyWM%7Kx lY-KI h\>)zi?ܙ׸iIe`RYgոx7Wjp&~k3ݵ'HZ]ҿpz!\K\Uܝ[Q{4XVұZ.v5GI,-(:e`{IMUQIŜ/\2`ɥ݉k߽W0"z;}.ҮxF.mH۸PޛfK>;k?/tw\ 9K9Y~~ϡ>W};o)˜}}}Z!~.0m„ijJKb,b? >?myX~7 1w:o;5GNU>fioIl|3qqNWafEfvddvNç>' lK"ѣi.wꡅ2NDbr%TyS<ΥeƧk^bǬ k|[ KK=v۳g].p8?WX|cQgfX…P8xښB\*>X ,%iI߯Ze~u~iDOJ#ɬx+4fv2!kl{Y+PZ~nxp-J$/Y:жr Ƶϐ恏|<ʤ}|k LG#W}UH^#>Ojǹu̻fv9+Ӈ3Ņ33ӳLcl0.H뗛׾x/y"WϣZ<}i nrv[}k[ βHP8.̖\$t=Qh)~3̬ERힳqf"1%p,G僮lL"H0'ג^4>u*3{IRyEpqg)_^t~(0Է9f]&|Xn,`Z` \((}݆?Ӂ&IGY5S Eۚa^55  .ty{ە܈k dBq-syT:\rחL[G{J%iSe8ܐpfps%]6nIR?I;㾚S5=riW6vom%d N Vp 3{Uҝatn<- ?rls=T;[΅kOq|O2aCg4Vs/^LhDI*,7/X)gbTZ1-}"HLId ^;$ \+ 3ۃ}I71x's9Hx@?Vɓ=rj>s?ŵn mFﺿD_pSeNB3Txu|DHZ1-'u;3JG҆kf;.Ȩ[09!}}%pkŀ%]#dl>HSoVnk̂[A-iSMw'. .RW,CIc=1I VQ+xanowO⪬sϔtkIrmmvɘڑ46ĔFp/x сAVsح7! 4-Ϗ]+Q'ҪΞ7)af77ݺZC#\l!iN`0:XXO, doC6Hw#K4.H<.+h4q2 J#a,ds=o֓֜@􊄦f/!,nz7&tv|^-3+slNx4CxY=?u"{ ytD"Xzدq;]p'i'_ЃBr4nP+K$&kKhQoq|D"19NK{_lZƏ<)Fz ⋶Ori6h}/+.D}lcj/>=X($YtM4Bk1nr>lk60b8 ãfNH9G\7 X^[p߁Z-xʜwJϷ^ğƛH)u_'P͕ZX*+իFJ?rg&+XH9#p͛JÖ́cޱxe|&!dT'YFHJ5;9pwCp5Ko[ =$-i^IZLў r_Q_hfOdל}HǢI­s2/;K !m|/4"sk/.r/gC,3ke!iyy.f +J,N,V'C[9Ͱ2.6gǫ l2ђ6tg͎:}W3G0ޯx?ΗmOq$i;\8J:N,IB-Q1ձdxسch Ӧb>G2Gw=#$eEZ^FvExnGs3ǹǹkp{$]'W/n%!ܧY]R f~L!9S*k\}ゖ+%=(we@7ŧV"1YVjf{w{-S4qAˢfvoi"1iwSg2H$_@Af8@DX_ ¥pzg\b$.`ذFW p핝7oR%0g%͊5J:(-8+1]1c=/_ V1>]| ظ_݂'Cm‘fܿS6S#$u?|֎k>vGIZ%*w07'l?xhME_Vfvg'Y _~"P3tqͩg,ӛ1H ąɷq$uffpb [:pgoI+=)1]7[/7rɌ,ѵyI\{ .9,2FҾD?鿕ha#9$mX77\wN|yTq5_b C7qYwv%{)4}axwA3Fs}V`ӺIdi !{ߞou=cM*E>IL$+|C4j]g6J lWR/жuO 꽎jBG>VOop} ap}Tx#8'!1i1YhHF҉ܡ$[nkHLMBH$+SKu"cG$<.J]uTYD/|6 UD} *a({bU4ІĤTLup#I\t)3ۭىdHs4 vrXSKKxD"HCfn4]\.'Y%'ĉ)Ik>a$ X4%%--i\ʒn;49/.T[n̾q{Uo"1 p>GJ$DHZVH+%eftw#=J$&Wm ~'\א ۠:~-n{"1\*;ԫCZZҏl"H$:=ff;l̾vM$sDт>yH;q80- ^6mP_j*]jPDT P/#ZZn$ĤY$H'5E)R-2UG˝RIjT c4<A OLH+i9;N֢Ye>k04i'HKWX$>Ҡ:̾^Z#a%IR~lQ~ӭ* i]_7˺{:C?g$̀x6n7ݖ#6Fl)wi?-,.<3;eWg:f_˜ 'p'=Icvy21 3艜B/=_Ҫ͕H$S,<mffkvK%f6&U#`fjn B@!۲Ik&e#-c>jt]z9I 6p#ߘ̞튲{2aqX35+4*]u5Tbf/gpH[94PR/DG?P0F՗HDKqʟZZ>$$HrZ 1RP+3IpN"|Xl33Ot=~K1f@W9X 8Ӯ(Ń|tSvn8NE\781³ˁ*E$D W%Mof_r9tv)W;I'~ɊR/sX4.jN"HXBsvyܴ~3;<.?pP YK%M l| ܝ X x x &K{&=-ia`rZ2jܫoÒ>4 j`m4pg[XHAf6BQ%/L~׃id/h[fVN+ kG? t~%`^}&-x&ٛq|f`]\bߍ 6HZXe]Xx4b~0Xte\Ib`I+>*Zh$Ԣ]6\ Lc_ϘI*+ K/~5 877lg[Ӈ=up_F,I+\)i.ؼ0VSss~*}$>މ"xxcfwUSsસ_qF?[ܚI=,iD)|{˥zWoE= ͸0`H(͖Wnu S:q!hOƟ n IDATĵqf廧LpA카qîo|aneH_'NqF#m(&wFޡQ(+Å|Ey~sm=\ pܯsisݞKp\Su'qzέQ7"vi!8㾛v̥ގ&Iٴ5ղ9Ҏ6 iGDҹpz#\#3Cpro\Ha̹|+.doƫZK^5TQƙCiFAJ.yv>e⼱O:lg.7vp]!߹'W*+1pSb{39sԸ̙1 w*|d%;?\03U.ȷS.mYm~lɥEyŎA3kJHǥ}p=:Y:U0IIyU7S)O"1\*EOS)?(D"1 W[?ߕ>w9ֲ f ,&@IM2Kk5˜m 5ڴuh^5,zsD{0GҺz3;=fh;R#ѹ$dk4\j<'"VVfvo%4#<߼lN ^h5|cJkkf M Sr<.v.Vs_q#3P@I;l"RNfVTeW]\=ӑ̟p_rpSKKmD'#i_B3EqG3b8g{KoaY8-ͥM&?hMff&B;_OLͽ}%|ÄRߐ+\cYn2$dfM1?3Ʉz(ڒEY|+~`B2 N3+kjG+Wgem! `$]>ة[ kSQ\.RMɮaX1}/._XcU\Sا:8cU~r6Þgjowq?-ąTE߂Iv6+]T(އpa]UF᧮wOq׬3)!$̆Ќv[%ی3{Sg,_9,_ |3z&IU4wM02ܵnXђ^VnkԚ wzMzD+KY&ڱLW޵k"wB{Bp5$-af˝z j8iK$&%KpJfI$&'Kp?c=ZZz ^"H43T|@"f9Ẉ Ž*VއH{5,r[,Vw4_-gPsIjU1{Q'1 pGKP\0yE';Dȓ(^ϛHv?BY=7O Gɓ-xM%|ZJ}*+k$'J5 eώ.3L`fν$ff;U=f?{wb߿.ӦB!\4Je毼0h|Evo|l u4+5wkܕ#ow绲zh`ߴmqufa3{Ô퀇]׌Y.5M$&3Nwu̦jgK$ɒÞ{e. ySʔ3A35l3۲{*V̏a}34&"ۍee/̾GGړ 6 %m/v"L6l#}=p%MEMtU|?)5A\F|{tntVycNZ<{w~ydhd U͜>LhwEmVH7uyޑLl ,0(|ȷ){R Kq+ß۸pgaC;-iFwŴUp?Fj}5? 2b.-7>#Ǜ;7wC`+3{|5^q4wk^3v+V%pe8.$J(#]pIyfnlg>|,om}{X+Ls_NkU܏Jlz {0;3U3W3{G߬_(i2GHטY{Uq3RFʇ~,O6I%2ͥҦ5<_"HLvIWC kf Zq2'Į-LwbY(vt%/6(gjricYoBVt%-i_vn|o)ÚR gēڇ%*&܉U*i[񘂹f.`pZV+oA]}&v6M_HnfEO{6Jri³~ iUQD/30>+)sf9>6n3#ø%-]b#Iqww9@DxH𓲾QJ;LOXl/F. @W#Oō;.l1-Ԩ080Au03fPZen[lw80 pUΑt?+|p[$݌oᒲ Vnr_5cޝS>;=q{$]3 %99kMHNVFKq'{JCxv\2GnsAQ|4%5]@`S$Ź+7G6w(zgļ46Ol[ gDyKߚV07K7~ΪC(\Tiv/UN^ݚˁ:b)-\x8̱̬JѺ+-6&]Is4aWs BSKKq'H4IӺ֯}n+$I7!e˟pfHf胇G= p%w2#np+z:_䬅=o,O6="it<eRym ]fã"\cA;S}Q G`3+:߷zoz7 Cp'7a}1 ߝ?֨ Я4;ٙ 3/"_Ȱ77vhw!F2ğ}x`~?l({82w}/|݀p2mJr@EikGMz>Xks}pxd٢Qoswj Bg~Of8ΘM~ #fZEyBO{w&ka틛~fC,\X./Գ&.|@kqlג?88wOw5>7.syK̅{DM;|ǣ63>1%rOq5,'xqm|rdK|z8ھ9>ws~ \i J .88%e帾ߌ|4 L`cfV1ҙ<wv67#/v:z?7{߻Ӭ?Fil|k];(~wCV%f(ge\ 45Fřqgg{oS|N[U V,-f^L1r=H: XfvI`%ѣi.n%kji9vD"`eBPhT>afCH{Y?> mי:lGRo{'hoc*'ۜ`L:rn53w %շr+jhL)^6_EYA $W;FQ0S}kH{ ww[IRi/'Ty #$Oz<Zww?*{fĻٕnabG;|GA.mv]mwEIG˫wo;Ӧ=֕ut{K1ah%vZA.6_|WϮIWVW㎭F/ y)>puH$Hs4nC]_}ZZK$Ds4`GTxtD}!im\C/qM DbR$vV$`ĤU;q#(m\fN5-h< SK}%6¥Tգ~"1I\*C ki74\5-J$D0wyj|q'DN<ә؆IU|4Db>VVwד)πM:PpGYT7}+!PlD"Ib r_`3o*u7ѵsNpެuH$JMCRe\}>$]Is[/$٩DbC/_KVQ1pc ܱf;C \XUfvzsCb.jN$D"Qтq۹;-qO?.HTTZ_]ўD"ԑ'S3MYFМOiixdl#+pL$]*r$McfNo}%?uD"HT>VI:5I5DbrT\KcD"HH"}"iU`h `\'ݒT>|ERN"0pHz wzH$D Zvӣv"1I\* #e`v'ĔفPfrJ>^b._ђ-EZMD"HL64(p_5pG6DbRT;g^l߮iU"HLHZ X*,iq+33XS6 eL 7i^̾RJOπ*:kzV'?&<ٱp?.ǚ eey>η5|l;x7V ~f|cfc$0H$O+F*o#.i]`E H9ȞM--)s"HTfc`x+U`EqIf]%8\;=8\.Mg;RҶfvE.J̸o p6 N}w˥WVǹ:.ĝ.;>~_J>CN\vfve#YL3I҇F3.$Z%|]-3:D_mfE 7%gf+ >a\;g"H$=VvU\wA3H^ڋV*] TRM$Rdr;~ur.hN"HLĂpd.,f=pI?Ƶ_F5Z8d !8)8|of8.`[X 3Zr}e]#n\\ a D"H$N+f 6ffW:^p3O'M$NstTɫuSKKD"ц%IPOB??j?;I!7x4woˣ|g=ɼwBf@?dAI(H$MÝ9|/H3.XkXCi9:P_"e4J'!0×M--_̙H$j,ӗ96 X'Ie73!^oHȷ\ݻuU"{j`U%D"1IQ Uœ( X腾V@Di.NkP%x% %*uZZjt{Db 3K{Pl"Xz4A6\dfƄ2zI+rLBazESj8wlwė+*^^$D"4Zce|oofVݭ<+&Fst<rfۓH$SsY(l~;`|Ϗ;C$݀G# /4.3QG0w[3Gҥv5$ 1sهʕUO =H3.g6&o?!m/\[8eܹ9 YBh8O%D"ѣi`e, |&} |X!i3[&F٣O$rHۓH$S旴pp%=|l $Ȍ$ WJ`sY&n=BsFJkinfTg{M௒if7$Gq<\f?0ãt.g(w#Ix4w]H@OkХ?.tɄH͕% $jf)c"H$z$M:v)i~`=3;J?x)io>7Ac ى5988}oTS.ͥR?BEԲo IDAT^Db"#b| pߞo+$IH$D"]>TD4;Lg71$%絉Js4IH$D"H$= V̬WG%`U=W1-`ۑm"!Kǁe:pM--5ID"H$D"h0 H@@[~lP%\H Lp[gpnD\*mkoȈ}ܤD"H$D"Htv^;p4Χq6TLL$\* ou6ED"H$D"J-XDy>6FTff%Op@4Kip'?`{6ӺJ$D'pƣͬ<+i@H<ʞ>TnFҴuODt!IR \(D"N(]f}4hftw[&6ݎBWVX+Np.'pW@=ەBh.n:I`$TI$AҴ;-@S+kK8ήQf`+`w`~`F^$-( XxHZxNҟN5 '2k3әvcܗ/X7LKtЯFWў"l53;fe| nC`&ˉPQ_Wz4+K| lyVVuM-p4-ڷp쩮oRтv#in`z3{r3INCsp5> }$D-p?0AkI+f+G7gJni[=`.lw| "3֪'x:[t p/<0JҼf6i{K mGipˉO⛟?ܗ,!\Ji `I@pJﮬ$7-*V m o='i4'`Hk&T<#C:hO^F"A+anIS[2ہ;SF"Q/asCU&C rICH$ EqXI TY׈6HzVG݂"I\Ӣl/'wx]}'.৸-M M߷HBϭܽ]ffN5!ԻvquZ@610%}B}| U0g$ I3!Q 6:i 3{W}]Y)76b-lKݍDp˒6u|'Ϸ#~|_PҮNI:o"PKUU>LBD",afߙZtB{"ݾa2T/ lx?Wɷۓ0LIEUO 线}dbYanm!}MNlJ<6wZ; ng:.{ᑋ?i:Zi8;&U})i73kTLh C*&M--6aD"Ef|'pŁ2\ aES=&7#.@h>"n?0 vskvV4U ɚqcqgsǵcfw{j8 ǃľ,~'聤UpŎri~I{=_i`-Ikĵװgv µ $͋:d/ֆ\Y ͹9P#l\,nf7 X̮Rݼ\,% ^4UO_ } l_)jÕG+9|D=4]gc♮?;ͬsL$Mk\Mɭ'/y7vH|Y%'ѯV^ $r&QײOrs]!t=:A{tWeϯ}q˔ ~;6=sz dy7>-k̏57 p%̎ z֪\07#}649c;axx (Yȼ1l \ ̆"@5pߒ / L~{?{gWq7&.E[(4-P"击fN ($8q޼M6>};v;ssM2W<7]HZVH`}Ik'$TRZJV6ީRwքoFf|u" xm@Iy$] ~yΛrNl$ŵ@."inIFLp6k5X2\X]ҵBl.^6 Lj$4X ;/Z'H:7½[!~xpoOJcCѸp|\xz;;MNQG~k\ {%>$*iw/<(iRG9+}w!H͉ oݟ`j('PI#XsepأKqI}$Dp-$-#܃rqӞkpyE<VR"cw-d I mٳx_lZID^[q="|@O+iO\x{9.)_pAI'|\< X qޡq=JҚ~0=l(i|/JmG*5I/Gox1[׃/33β|8¬Y%:QLXJpz퐯4Ц65};:ytЦ&u+_ u40 \SӅpy)w@"[pE؍X)~5WMm@~T$Nl>!藄K6%ߊzQߢ$JWHwz)蓌MVI I~ϊg;}agz-uw>јu$5(Win0\#m`Sw1\Y=/3~L߉I0\'oz][슏u"GIi8OF':g'akDڭEoG%oP0.X4*S ႎ@3*6?3J{ŌZhin9>XK5:${6_?Ds3J ?/ ?v~N4TDQM+`A`C$g_dViu\Sf$Nsbfٕ]`ImТJwt|if]ܤiyUBqb9^k%463Zw\Ej6|WV2176Xe66 \fmIop\10l3{4vMw6HqV9~UX?Nq<.$(4EKN^#3; 6QX:W<̾Egafff8Ϳx$ ~n<Ƹv>p">WD[€xpUq F(p| ԅccI <1̎1Lƽ&nwZ?Ÿ}D'}%_1p;Ż*Lk@*\$y͘٥o IG Y%' ÞS$3΋1*맸9o1mfwGx.Af{0S^+/daQX$.m{NQQ- m4n32222:0|}ifJ;SlrX)޵T-멲?qUE%,/NxHY0é_m%mfQWln2;~8k֜`gXuJ<L7~ cfD];x0/:?NDqaI0\n9sDSF_^CManZ)ވR<^.mo$}΄U G` K2Q'O|^i=\嶫΢~0(K\;i/(\ҜPfp(x; gv:7I#piP0$M+7)>?Wre.BY =ttox)*zI䄽 F]֚Ƣ®*}PyX6 o5|EtHzHoas=pj_)N9.R/֢6:#"Z{C}26^ݘ]!B8FYPφTaهUݫa(_{B*9aAUv $khfoJ*k W{B0^eZ> 7]_RaQs=­K#$y~R ǵ{vtd*}B<+.۳^}O hVE]<LLH)PEq!MOjb3(4 l1w|S.k|K>7Nv(n´.PXSҮfv^ysefɹ(3O%=k\M8؁֒ ʵI/^4Ѵz$`Bmf:\l uIHMCv1.&A%m\+I|TfEXjAe|ܬ 8J+JddddL>t[?d(`J6m }5]-7fU?ID&+;Hs4NުQs%M8?ߜ4Bhx7:¨~`py|pI?AyHHҒϒ~{y6SrBWv! jTFH|ʉۡyPW;V{NiHŽ{ڹ> ӕpmpp.'8رw)iAsiesPYc7cn(6tʹLIJr s7b+E3"+jQtfG\eҵNu |O︴\z-]WRCAzZ1P+.UBkV7-|b qHC~/IXX/>9pņ8NmMk3{ %zH 07a'W"V/Q3ͿһiDD}=n{ qI2T^E&@k*ԩڽW+RWe_KܖJ-ưyJxzs US񱴽Uv;m+sRCx+^W^P/N+=W9Yn9]l[pxE,50.Jkz?]z#IWz < vz8ntV?RG"+-# &LWG\6LCR\)L=蜣6 n_فPe`YT~R~6o>zJ%lM3̶7 5<)A4`+x†ra+8 WE_-F[*I22hin8ٵ'M)f7bKũa;IõnO ^ 97=%ܤ1Iww= 4 !8Ez?O|Ξ_(i0Y!~Y~-in k1d1IBHTB+@|wfi-7IVB]8>˚.9K~8oKi E%I[UG*%sp#$=ff7xgl$@fJ>[&~o$.KM B+wý7yIwBi:$}OԽIZRENREv9!ϩ8.>9og_M+J8F -%mz\ Inx9ίY% kޟ]!iVk#Uo%7ڤv ̕׿ܶVt>mfGV+0 -igsJ pKpKz?J HZ;sn^~V0[R}WNC#t qS8Qnowŵpwާ18mfvQ9p2p^8wu뱸cUI[ _f|Bbcpz|.(v͔>.2k"Faq\< '( o3drCB!&BVF|ٙ9^|,iN\`O|W4_1>\a4 M 727/qHBЂ v(L3)ho1Qܫm(;i+r_Ax?Z"C-"QLqM](wh5bj IDATG2Ղ\5qAQN?m$π:`e*FKsqFTAR`%h:\hf;wdv׳ft]u`i4NЙ&xJBAkfKqAlՉ-gRKx!i$pldQJ`$pf63f|wܼ2.Qޜ۱VCR4:Bw7FLwh94F)SOcPe`!TU-M>1PUk#RPjܽ}s0a]Tt¸_O\I2r47굍719Q+###c UqowsU2s;{;n25#n!Iw] >+)ymVWᾨk3:q2݁hCGp𻬥19 i)INE1%ax .y88oWKRAW V><t=P ARάgt/NLs^8Q]QfƔqұwx8tpkIwFFFFFFE8gݞ] U2A%w\ uwL $I+ ,]q&v3 7yFrS Znin>g?< l0Y\Ԗ;9ڻrT_ƤEnz\i?21}G.EnƉȯGwyJ/cC VCH+iiInz.Ůb wkV=$ReLz47ܼKKs#c ]\+ nm G)ip)\o^I{oQI'op%m+>+cCRdL4x} 1$iCIf;gI^ݩw)b\]{;,N>j;>%!IܝΩ#'S3&W>o|oU+K=V`!Sm˒>^ B'&GKs󼸋 Axxw~.N`8B!^zkz'à M(t3JS Z  %M5q@,& 5xUC|n|… DF3^50S.@?\8A"8f֥̾tpk3k+p#Ү,;cҠY8qdp,pN22222#sՒKz X1 CR"IQ^7.Y*|Ddu2[*cJto)<:8cfJzkkڮ~݋f f'|O]TJFHkm|/8Y=X/FΩt/2cfꢲ.-qM6I?wIy]qA/pɟM22222|`Xi_gJڈD1բڸlhJNd}|O&vZW'](m&[+S=&`6^ GR?te9]i3Y.N%파)R24l$ E{q*\=WJa0>πE 0'RTU%- =bfϕ 2KBLr>4U8b%`I]32?;]"i`= -{| x>=^JڦX?ofcz`A`dO'~S_^רTOqftr9HFHZ_zLfo*y8/ǙX[}\aঢ{[xF/ ifÃc=Z.y7)K>Lgf&6S fVFxkP*qꚘHZX2^Q ̊{hx X*@?3;c(gɐ7%́ #Ksqg3p}:C+*ZI/[h 𴙍ԓ1$0M2ƌI T!!eJҎ1gt3Zkin^yHKsc=hR U pk,TȘx|3|~lż;$<܁oN7À $cNLa7/OIKܛMҙ'\]8| EI/H7A҅>\+Rq;Ko )؜NnD)i 7CxMT!0Ix+onQ:b`t.^ 'b}HRAI[EHk.7Ձ%;hƅxN\S{EoR7{x_ck}cDzxWP.y$m5q!ChE$$7kz}@O$I ;O͉V8O$LgyG%X/qQ.qX>KEp>Ḫ<-)I{IT3GOJ^{{EK%q a')?|wlPay,π ԷEEo%aϕz(}/= Nyy܎oOf$Wuj)lR]Oί䷢ GsGvG7vS kuJ~y\}p$p69,0bY}\pfiޙ>1pl687}ic$l@PJ{6 p3-׏}p!]I Ii&uʽ H$l{sZIiz.s_p+gGx^9HyskϚѷi;G)||,  |Uwʁu@kM$RcAQN̮U ~<+~R\f݅aյ[[։1i<>ޓFn-i33U= v0-k|Q-.8\z5k'K\$y৒5#\ppIǀ̀%QI3*+S>MiIZ%KImn3Iz7=X.o7+s<.l8>2vMm 8 >5H3,#8xߜ(YI[HU0 UjV\(*.@+HO2\ƛg8&|#s$p7{9Bx[1y9)7OpAQGFJ}fvJ|8kNƅ,o7F/"ln f3TiAIJ=kq \Lyfv}&'MyOBe-A%"3+2Z T!Ӗ .,=:E9pڤw 3K˒3[Ch{`W\8x`g\[le/+_fv 1c+r{ShN\&'fjA0Jl^/R3J37@(jfc$S3NJQ+D~vqfU.vnt30;8<.bh3\s iM`#ohb D{q\fX6 s>DO5wR`A| B:?̈́uB.nTF#ո`eQ\cf1$MpWi]%0+Kh*砣88[fFX 7'CJ7b#W18 LS=4Ҟ5Tl)^gڽQ IkH;sVJٓrq!Z5%1jBfvkJ#;9;oicj>ΗrGI)ݯ9J w]-*Hky[ɊġI#\ߚٕg|70E=,%>WGv3p[PYx6@Ks ORdjJy{jpk"gdddd|afN7DKZ 21OTz"ܓzeZ 6:Z13{Zү `H5 7a%1 #1n‰[$YzE~䩧%ۅ!itfQS@+18p(`mI316~Mu͒Fz>U\VҢ)5{ {e}PN#nBt3`LWKB`3eB0b" fLR47iin^y˖C[/jin]\I\X.p\uJj8>[[<,Th\fpO%C+VGHupe8~zk0֣T5q3`8lꥶ]r{ۚٯ%W;H;-3(s}knvD]*yRg"P]`R$iąnlO3ۼPR(Po wN:3j=, Daz$LjIdUI[7%M4>|оU½z2F&䓨k|+~ 8BWƻ\|fv n.3 mnXid|UzFDP+ZKu:_Tֺ(SοҳSo;s]upwHz-%,51*ύ7څ۴{ wc>?׸i"N8IB='.*+c G5VV鞙}- 03`LG NQL׉4S$ZU촩r~!Nv#p؀fdddddFS0^kN\[m.;=kw:(6GkK,(dNfNM71Νpl2f3NM$@펟 _o04| yYo)ηw3̾tn~udhjMTl^]%{wI]. ̪62Sh΃y)iO3;SR3E}JTIhIG=v ӄJ_0[U(H禶ӆ7q3r *i} 6?Z&9w'H_L9e~\!w=&=@q%m4B'yvV!=IҤ/kJ-48%f6"ߏS% ~ogT:FN! 9` JJ uphOWҦOqGIUy'bjZ6`?9ύ>s3I̾ycvԋRp̐5δ+)~5{}%7xab7\h|b섛,́^Oㇰsͬ;q/N{'s{95A2!!T9d=sopq}C@4| {k#Θ11@3M`Bj-٤ezࢴNv477$\>3%>"ɁpA C[[zF,[pO)I%{,-ic3NҾ \wT̞*}J[UsI/$- {X׶ٿ\פνp5_$o7'3Z0(Id'ho.n?m~6bc ɍh/BhkU+?ĆV7Kuuϣ{vo8.^a)33o_]ߜwsԟ$=smlf27g,ڣt&¦[3o7\2_Tx.z8OҧN\pV<\a-u3ʜ-t縗Q67؄/̈́0{x!ԹP.`8psZ idžDޒ~wtc=~̛ 2_ү9fIҞ.|>_މ w>|apͽ`k9p\C!?Y\Wު#TxGҭ^_ CۜzffgI Υj^^i\ O@W ЬY=6(%ׂ$}_٥?MʣT~6>P#cqI#Sf^Ks"pVXFe|1apk\C9v3[#oF0!ftJEp,ȯI^%6릇RZ1jթt]4|߽>f^>-svzoJnϮ,ﴸ&YfgWS/I<]]rTM+mƔX):*5R rm:w56"x|>;32222'$<m^Vx(JZq=*'0sF+7ͫF`޲+u\uؓ='ʩO~wzBz+i3,L`e15+|a.PtU,󂕱Q~ ̉M Q2JO' ټ'#####;f9?s8icefCh47x__.B5&|șU(H|sLʅfGJst7پ(FܮhM{!ʣ[[$######cJ+ऴOCldwoO8V5_wS I+{{j$Ȩ 5~FSw#Xij]8QXgҙDfVuYc=Ľ3=9=ؙt(X1T![[;l=>z4 I3])r7w>jH2i|ֳ;S@]4wS*F,IžKVSZ“Wf5ˌ8$-tMv1p՚" iiu6cۺF -]*`t0])k43,6k;lm2x^繞6qMld.o,4=+|,}qH 8SҪfvRޫF{MU[1ni;ѝȂ]X“$MWxO 33QҩþEn$}P\L#Z8X'%Xx2O?=o7'Q]g|%bЌ{aNНxO) zu&q@m|tm5'`qLI+Ƈ5SR3222222&$?< ջRcp*0kh (axERk| :$uX- ff4|̞@4X& FVpd55gddddddLI I0nԔ)z('N[&< fvss$-kf_G:hr U2*ݕL#F)zn,Xi T ښɪ222222kì[π_& ia#e,ljuqnCނ0ۑ420/Wʻ6 *0>{gOWJ%=\ʳ73`1\ɴgEg4leÏ,Qy6mR4*tKZ$afVwQ`j$ gfFxߺJ6u M ^3#~eqoN`$'f6*ڿSrD<׎z<SěLi>pD6R3;O҆.1Qu <N(47$́hV`3H@G5!y- N`%i^|l:XN cp:~3{B-4QNC: R0Sq4;0gnfJj54$i1!*UB:5}/>}T7s݂ʗ}cjs)_W5_mM=Bw?vG7⚢'7, z܌2O/1H:~"oz&|vX2Xs$iZ70R7 Owp~ַ?mݗFިS["ޟi뿏F%:}4>Jm_+N8Tkq?;ֈv;F'a >G68pρ" ƀF-V*og|n[>u_EI+1r6>~Wkz9N ,_8PV [&2|#eg\hʥ|_U XN!mbn{Қ^c󮾲` ʂ|+_W/`epNI>HNs~vhS〫߳Ǣ$믱X ?%'q;]^+IdU:+\\6'f~o|}'%<N,e,e /]!ٽpqH;O4KS$cwМRwK,$n4^=o{D$i;] ʭ8嬸 k|[‘EFJ;uɱ60ڷ^V$!>s%lS]zl>µA:+.P4`PLYJyń 31KB Q?Ĺ@xF'aB-P-a;GX3p{3{F-~OLҮa?IyދB?&a;EwE;֊yc $]x_Q?`R_=Ș*G_'ON87k3  (cVw!0dSڻ,TO6/\s=&0[]+>z~^v-_!l_`3]|5Kio6#(u?4)~!E= &IsH*a@ ~Zzw)v{Y|s|W)q$l np9wĽ[-17C6-phfف\&|%&"JZ&kO4.7 ֣8*#M$㠨8m₇qhG/\{@a"3~-;&474V \kN*IU~+k39 x3 3v4wXwOx?,ƚJۘs| N1̨dzEX{pchٓQSxKM‹ k3C<xk߾Ƶg%i7I{43q]T $i>6Wsí:DEWOq(0c Qˆ풰"NE@]ۓx3{1pMyIu7\X7-c%######ch{%WSIB+&Ļ9c9fv})^%y)|qeX6 ߬}y K WQkeJmkQ%-xjE*eeY' `f.*6UUIK' KaJBO TrPlPʇc~hJ5#6[>`f_&>fN֡(x_x7/"<\?8ufD#2"&3sĭޥxI:9*p7._ .3p[qmu--by*WJ7) xO՜w|ȄccqLCh`pqrE-IXq? І%ajFM{TZTqQ#ppuqAGMw%a2f$efZJ}Gf4#!Σ.uIwzCY1`Zb(m=/qh`Vv|)|gOgI7ncw2wJg17)ؔLTD}&TF֢A\{i_`"m+eix|KӄntRߊ}*3 n^] %?)/~ /.i[3|T ́.ºщBgpnr&˽)/޷OǗ7v0׌Uiր;^3%q鯀$s>}[+=qSmɭp~|Wm>,Hdfo)E*2swKGYMjλ 5w!b\?0m稆 >E|'poR7m84y_gw!eddddddL0L]UHx :7$#IS(`6RNi|=A_?i&9¬ EY1W25hM[Cͩ6p.@&STH׃S=ȶ$ ޓX04RT{gOgGɍQ]%ݻFC3 ̆d?… oO kH$+븠}bfq/8kI4z8P辁kxTso͇ &&+$Xaiڸ 9+Yb~zB, w]>B>*Kyq nhzF~D[W4cqͶ%sqkv1ҹS\`M4P,( V2222222v<Ưn+S Ռ kt ae< o#i }㵝M*-0,Η4s~K$ܫBÊka+ʩ G-KuY8]M(cRFDVl yRRW-I;qUnµ() }mxmTS>U)n{q)̑.x+ۧza>L - Z(`HS(kf8EKjm>tkwI֩¸&_msp@}Tj]. q5U'Mݕsur)$9MLWjj[総 V]i;>,WٺfRgsbO9>6>er||p!31? , i M|iVD"Bt1)t8N( 4R!i1i?ƥ5 '-Si?Y1U#6 {㧹 OI'ٓYuSiN({Cҕ. AOLSKq%].As?cIIH?F%mo2=y8 \ENNpWYIn&sk 2FE;NOI%m*|ڞsc4hyUNF$paA `hB'\s'k-M{[/0Яt:]3v:[ bZf@dx;I[Eqo9B4lafgƳ=o~Gu\HiBVTnl nt.>FmD#M?J֨6fI Sw|1_}Дoe}2$%i`!<,wX$,,-/x`qKР]s:3wr'3ysVWuUO#ZW`I31`U.tKګu8>{/J7pO~2)h4u]k).i77>'@<_JLҼsHHwgo2ThKH#"wE@h٘ylݮ/psrro0ﻸ`qJ@$J"H$v?(j6f}p%-o~w9#O:.M7!GD{ÀSYƕpG7!o3ñm0̏/k 整Q9 H !馨 3mwd; UҎtp6\X.\3golJUK< ďfUsyefTO&2WZu~}£O)i |5 r#=}$U035. KK|_KavIZ7:6 `hߢqxuӪ*iO +q]nQA\{1 XI q תY3f4pq y7uyrR\FG^|Mds \0uC`;\3ܿ.֠(\>/p7qw$5b{: }}u. ^Û4Ce#qnC@B;6_ yC\[[|Lae똫GBB)p*wsp(k\vL0Jx&\s#.\h@ƺGIC.0ڷ\;3~{D&5c.(>/Ekc}Ʌqa,xy(q鹴?q5Fo7O{&z4gy<0`UIUiʕ5^!N,7 bR_\|1 VACJϬk\5I' ̬k'H$`Mr-pU_j&$scB5l~MmokzFIon6_CG&;ޅ^a=3ۤpl ik A}:[R͝OeeJԘ]Ke$D"H$ 6uƃ0.UKu,9!*0͗8! MkpMpc\"TWIRWcZBM{HD"H$DU4GafN$Z.sS$M|=Y&>۵^$XI$D"H$qs[z;Haf䡒Z})92DK+D"H$D*i3X0Wh{HLD"H$I3v:B^3 )?0XWs~mݽq;%𖙍F͌k,r>0#31HՏ~|;苿9K,{6<5q(yvI3ǫ5턏\yF4gq`Ra`]X#d4[I1?k:4( IDAT1k/d=d8o߀oz`fWƆ0M.9<' *@8bfwH=l='ɀے27[o݁Ŝ&]S?h).|̞,_71zWͬT;)Zў;l0,hYqY x x26ٱ݀#c|ofoV(ўu*}sVҧUqACfrYY!iK\hf*̖b,=BS%#ϡq}u11^ ۱>>ގ3k~|>>4O$m x+kccd|=^fjz?hI@16V?ΙnΥ2&n.`_NFT1pӝ8qkdF]L7+>˥O >/ٳnh5"iA3{ mHXI$D"n4p[$v7[HZ#I-[ϒZDes\ | ^ttKeY*Ccv5;֋ / ߜaRpsϢ-J: e('X;~ZKq3mIűy$݈l!is`(p0\W c Hzx0_  ~+!f͵a~H 7XEKˁ "O|86a{ᒶo#MXF~Z;xTҎqоwfnWOb`#|%N|^<'cʜbN 1{EҶlcK:'(Uq!u[ttپpx*\U z 7?pȟ2J{쒺wD3/~2)cIJz)}rzsBiݫu9{2.\ I厉2^kXl=ef[_7Z4E.<*6okꨣ3^Iu7I$]HZxp?9(g"5blRqkq_P*%stR!$q!y!\"|ގXԄpaZ/ &pi0|=m_k{aXcftp xۓ>>>ߌe?!0ݯ\^&{IqdvX\ۙP7Յm դ})oȷP!h+yx3g@T [x{?зqG\ߢ yϊ))sȷJ?ryy^֋ F8Ν=~ϕ?(U;=%n̕1u1-5h {`\o`(g\wS^qTe6iSocn~t]'w?r7e!ãt"`H7x Wܑ)`)\ |3D'ڍܵre\0I_?@·o w41Һ5/뛰5ˊY5V\ڳӅ+O-ؗɭH[3+wmVsv9sS7RQԅ}Jf8W6N>E.OZOÊf\ڲQyis\q wgܡ|%2ʺ0ǜ:&kB^5Di1ka ۝N j_ݫ#4 q-|yvNөB=D5'i$D"hU17(w{yx8of 5?㛖qC;7ț\oӾgTw!~HsѸĐHxƣM}7~)'S[^4B9HssAfrL ;M#B3efCl(20m6Gw_§33;;y vY;427VM_N@17y b &Dwwc";GnmhFY[zDʯf}of'Bn&`_ZokKfz|gdZcٻ1675wJz?Ks:Vk%7#wG 3yq}-'`\k-iY'3ߣʵVʜfXwO9rS5p!bs ǘ!4|LEAs0#bnVS!7|=nfE}wfTs9Ak|@t\]+ 9{^Ӧ9$+D"H$3ot-ptq UY swSl;t3M3y_!_%Mff?CzH iʼp?JzX3M&5pbhKN*(.XM7frT eә~Di+kcbPb(?8p͚qMCص9MKX&x Hx!PW,̷K惥+^q9w?\Kfh.PX|3oGSf2fjf_K6ꋛ1+|!U5+aV|. 陆nk/mX놙}#"lv2fZdTVi}$z\0J%S7p\+j1|s0%"BTGyss{h.kwcƠ=3Ồ㵒k<.94L@e}; ie#iqO?~ OM.g&J"H$̩zh3;P{X7D1~ ΦAs"S ;^s:BV4C!?LEeI>u+|3%J}{7XCRQkeN|C'{c9)oH!XmLH>nc|ˇ4nVʮIq>)ַ:>^yl4at'~F3{J?467' PứWc%gE6f-%ӥZA= M^ߛ̉;riQycbF`!|{<.Q<:~I_0 ͬh>Q6an(}r w6Z1rPSlCF>0 N 8W<:WZ1z.!1Ʀ13ղSZ-yjcKq\ؙ w5.QfodJk(IH$D=36{߈e&{ $=&rvCK=Am㥙@yP0 u/U;*3 gmsFI{8`SL3?uxwgGuJHm/icLLN!4n4i)f<4C&4l*9?{ ?I$Y%0e=Ƶ+~8O4(|?dwAZ{~J1g*O&Dϵl1yp'2xXuд}m \]L[fHZX2=yz#>v4 M52>߳J;n(n%Qxc=={؜+xIe66{C&Ds]%M}q'HzJeisըtx}05;kHe;6<# E?F.wN=v/FC&; 0'$Һ⾾l}7f>0X5ƹxΐD?bf_RxѥewYcƗDfGnnBm;ݱRHD"H$7ˏȝڭG .;O;29~͆SJ:84-29Xҳpj2<z3kOxd?!Ib0p$qq~W|S <^]b1*iwIC5k#i!߂]"maUg|^.fvuԱ.P"iQIKq9v4E̟?7J!̸&tgφfv[֗xC$uk瀁fGԹG9(JI\fQsN.i/I`u!0^Q S% cf{BjI<"TWM]l*yƩ+_le9=s2A!0{Ƿ͍뫵F[n[-~H vh4s#$D"H$&_[{l.0 O񩻎 ׾ƺNBijnf U_6WWk_ܶZhk4n2G=KD!iUIwø%IXe'D"h?HTғ7Y34%JɜNU5$L4c v6t# 57 3 N!`%ђ̌wy.OFW|,C#DIC&I+XnmI$sx3Z9?eܷ ! ֩fw@>&`E`p 𲙝J$rgYcLS5%D{a*x-a5trnH"Htd"2O#asV|$qϯ!(܉1kS&D=1πX#Ic%H$DF1Q# T i:5强TۚԃsJC$CQK"Hԝ$XI$D"C^£d$ |L> V&|݈m:Bn-Q:a1Ց0RݖARgII'T9uޒÝނM|B໛7jHԍ4D"HtMnf =mooH~g]g]ylC05v^}ԃ?hCWqy̿f?dY9 7mIOhC먹LB{q%$J"H$@_37-F8<%Иk4F̾5Z "^-PW͘5󃙍ުSޤ/>3UnKs43#&=,A5>fٻn"f3E&&K3{1f}3%$J"H$vYJUHtqJZب&TVP6ІDe1ckfŌV+$܂mo"*ݎ:QXKO?D"H$#/p 'T0ѹ|MmQ,gj`9`P:GWJ|!R., t5$́cYNj䡝L r_m[.f3}ZR @lƼ)^R,7~_* ,gfWfV5ˣk3.5:2ר;Pa|:Gsh}(i*\z1n"~O- ,iܤs\7deh"$i8.P%xX\]zxB!\pqvqBc>޾NEjkBw31sGsǥk;E}pb'k(sJ\8Yif2?Ι`buG|?mfxfp f<#37 3}on2s_)rq)]! DFMf=lf/Ug}|@h¬#\kK qlnu5 afDq>IZ) q$.cdfウe3u3{2z_ypv61{E(G 0?+6C mY ;3bfDW}5e2oわ>įZ| ff92.,+R;ri/6a|kNy2\8`$+D"HLDm߰?Hs/ZZbx18 WӯEpUwfWE%2qd>.37LafHǒS?d5|z!_G Ѐ8TW$}>McO% ,(iZr~&l) z銘0f oHkS4MߜHdf*ͮe\ރkd,Y;">G3ؖͷ /pA¹uKpS{%efT8Wpn23_XFi҆VG\V+7*k]Q%痭LSB~VÀo¼j \H=jq{a!6gRpb۠4сHD"H$&N7 2al'vdM@?~@x=%M{>{?!5\쎇..nf˘+nf6Z:Yyk#46γ3zŵµj6 !V뀭Y4G?J 4ebfȝ,_;4^Kf d£WlCKG^zsWDT'}<Ҭ^;?O`IxL:^DN?[!mcaw)`:b'|@8h&W@-a[%Z=3ìÀ[D=NCovn&C4t3U6 WeCcfӴPJK!Zfvc eeq^œ7mЭe>UZ4#(p;unnn:{f50&s<\P%_fqafeo[4y NZ腛;7[*GG|=OЍ4!*iY޸p1",ټ䜊H SmqH}P~({q#N2s&u-&c`IGQŦ5Zk]\86} rUv }fvkSef_Il&锼UmMDh_Tޮ釻  P/2o~^d^irG[f=UkG#<jc\zsHwؓ :>P~.|~L<Wbۇ$mg a(,)`qIk~FT,uZ~K+[X2 w||$M.,JLr=Sfx#}0P5/y#p_snmIO}#s9^v`%<PF5/ơ87zSdAg~x j²Sc4 !iq1^#a^O">ϋL]54wciŦ<:ӭ <Ӷ{ˇ\-.9w$ c%kfoI w;()306=sɀC;>7~bI+O ywBHxne՝塪ģ6A3 2Uޤ.3yMIFNI⑲ cY`eZg=⻢%>ןr$|mdz~Fv~rٗE}=3wN]oEߘpœ rbcs!!:71`B>h=Gy[Y yfVy"_&a`LCEH-L&\ofM:Ec9e-wg\ _7WϮY̱$moN/2%moN3n]_Ӌ[ҶP8Tw(3GIx4>syǯu.͹KT#rO6Eb\{=NpHٽqy=Mfw0 Q…GxLotGW3žϸ`k.z|Gy-wv]ܛqQ3YO+1m6\^|Ysyh%3/iNޗP\~=sKz”sl< e_Qp3k8oGkq6 (Fό~?n?q:w@|BM&x| /sfsM`_`\}C%peZM$XɑLO4pEyv~ @g_y.V`\Xhx]Oʺ^V0`j[3>UMP9C3DŽzKXle`̬[_BjiOSlKcTZsjGҥ ?$nu.}z|g{'6R?R[ȷO Dǥ)PѾC5K#ݵI[_c+c7>XkfxwuD38}6;7_f2Z۬Ҵq ,o"߀=Zc3Jo3\ҭvik5!j3^&}|m&d=k)-=7lSlKcTZsZOh l_7q 7Ƨ21^2R?R[ȷoB U&:.+1] \!Rr^;%6WB5k\-{pct=cc*Hbfv{ZxcMr-n?_ԺfKZRԺ!YdVݟG"*HJy 7}鍛nf׷^ Db&D"1* ܱf4mpp_pϏ@D"!HD"H$6};k<ےHT#L .O"HtX:5%H$D inCb'ͣD"X$J"H M%]/i$/k[- Β6t?<,III3ϑD"Ht)P"H6V!lx[ZiFF@OVmTbB"lw &3֪F7 "]<#U`(IO0} ^3{ut2fVcBnF/o:+fFك':0dH$z|X +kr\;ݡSbK@W3_R^}!7Ҿ77se,|mf/ZGUQN>ty;>3pq>75S8z|~| H}s^&Ag%Sz-8ppJ\<m;9Wyml N5$=< ,!bq|_i.o*4 x@Rp{n9 r:=9?~g>(¸l c0C\3 yB9p@JcH$v-϶v{& fnAsn"ЄkT8>'-#kYZ-8[-uTz%gĝo]?r!0=&le(AHo{^ |S8TBQ檹#s.mOp͒j x.oQ:#f\). sx\#YU\ ~w+a(cyr7|S˯i"%+ɷp{ צ2{*ܔnq}X:^x!wJsiD{]ϟsyD'Z{OOτD"Q3; X*ЛٛfvGM$&i&TafKo?1lo3[-o2JzS/|ILC.3+3; 7ݙ7)%_8t2.i,rT_` I8Z*Yri#3̮1'<K yWoJ9 o* }dc}bf_qqzUkL [{%3{̮4)7kZ}qHO\lISF9Ahv`>IKdfq!V~ն:&cfv_vyXLD"h$+D"Q3{~7IۼZ|/?ffcXޟ7FmKy2Vc_Gz!1ٵ~=n7Ws^'ه>5IGZG3@EgpBT?8OvQfvgvV 4ukY._ϢF~K+K:ɮ=IfvCypM0&V䗒D"Hc`%ђDXDe6̾@R?,+IcfNM4‡f=?KBp*%=<L`ߕ"РQ.>%,ۄlc3xGZ!m3rҸ,qO\s#T% r1cLSec(1E C3[__H%shFӻϕKRQos 2I]X6G&X7皀|L.PZDRoI=$Mkfp?4Fـ_l\U w-n 5W80.n"Ht `%Ht(pxk/fv_lo#O |%vI{KދL&bfcfvm`f3so;pxy=\'Iga͢G|L{. $#'6}q/pY*ܩ;䡁dl=w |q nsr^x(}KZ%9 ת#O{\SᅻW6_SS%_\pʖ6ʵ.5sd#3x:ק]I\SP` o=٣q-ҙqZEyD"HS`%H$Z3̮0p!K@}%< K>tM‡K`fo #wĥkG=yIIJRVk`BP3k Lmá޸y?NqD 3wW~Ʊ2/q!hfO7cqα3\GfviI7I19'p?!G_Eֈ&x_p 2m8"ɳy#2aD#o'ZIJH'gcA()qx8(M#0m.4 vM9](iKI„7'e:I #%O"H$%J"H!/s9)6xYVC8o4.`x|!$Z ,$};͜>cfF8CFQc3lą!62IKz7yآb\:w0?Ti`:wÕ,wL҃ } q@PF0^ңa`Un)xh3k|d9]D"HP$J"H x "id\|,ih17j#q3\ i^JJqU2AS,Z6ܝ<-Z4"iKXCx3Wz[ꞒK$D'+D"1bfcIEGlgD2kHJBQrC,HXUZMlE#`3hLt-f_w;D"H$J"H;J䡒6drp,JzRQ5njNdWy0$-E렸}(jy,\fX$.jf`bUy+)IYNlfZjH/zH-8;)LҠBD"ID"DX4%%z |$^\r[ y3{ x (Y4O4\P\3{s $- ՛Լ)O"ўS4:$D!<r_#]~4V)4 +. kyH:̎6;sK維< 33dN$=XI$f""xbpl?\ YJن)oSGi5̊{P,Hz\`tXK՚Up󀹉 ,+Rf.>]ɰ8T!i}ՉLoOKን<ÁSt~؟*Xh`I[*?;qLGmD/LCDb#)VD" 3?c$ ݆66IP LDNL'eXΆAAqwd))[5OlO쾬@xܫreQf6V҃eTW9!K-0%M5p9rIwMK,:1O8aMc_OIG)U < |"HL&)VD"Q'$+Y6]6(̊o3 $y,/IkPj~V]٫AW7U1%Knxtf_,ۉM, wչuPRm"gfv?$ L0rm|X 4+6IS'"]6@ pG'Gnf9<W=[<:z+fvEx6'1۶nlK۾ Wư}zge3fJq_ Ǝqoq6dOfv. :GI_q}-AfFOeݮ2^PRH}$Y[ 2 ZwR­8篇u{qD:oKeXOςߧ}Bցfx&ҧ$Dbf_]fv|Sqh>YmD/&(3;v1='g $=$iL;I: g9I+T88 W<'* .$rU(GE8o-qOr7WlW^lOO~+M6gl3y=:(\(d{7{<=w~.}񌤕 ӂ[t\6_ydqy$a|Ql`<0zANOIbzEdrڙx ,zL $-f~ ׋m[Jսxj=n3 X :xmI=-#Z<&^NS#X'}[+>Bw: 2+l▔g$H0]q\xSp!is\)y7~#ǒr c$-_h`k\yr_Z;'` p:7Z˓%-=y|W'yox<9k-k'es #Q7+.tp;>!۲0z> eFz[⩧>+~?|BHLrx0_9BπamW8;;kŶ&;UrQܱ*WvX!0X釗re D+{ [} }r .ƃ. e~ 4Jre}[ro-7 (*f` `Hex(Wgfdj߯x|>xV B17+ǸW,ȟs 8'W78 reG`([&\p+c`Sڒ5-iIKm H$. $pjOmhX&JI)c=2$&ə}w"0=/ |;ͰӼn0f6ADž2Ji\[$֐4U];w^I:%B3sy`փ{-\9Io=WV/d~wyyZ=+,πGm;B|,[Qa,c1f?n4Q@3¾]Qc \g:̋'Kz܍R\ UzR|y/p+ zdc&IzXSRspE? WMf,mQ.WVv y_:.;`l&w}(;IO]+D7&)VD"1]|E()Y6'8JRK̸RnbGt('⦳h'se8K>an|VMI}ŗV%lg9@6"j.ȹ,>i.p8+H(Q7Se>]OKj' : ¸ED>r&{}(fqW)bȼ^(Ք$ 8(;c\m,LL^&fϳJw;)WNM&vΥ|D[^e.L ͬ\˔\1C~ߘ7`Y+NM <Ӓ.ŭUMDb:+D" NWǕ,HzRlʠDP`BTL O1*bսڏ],nCA=6kƬqE2 Yi$O3Wh\3u5ʂV2Ak LҷlIO㊲?S3{>;2䏸+$TA)0'#iGܲb?3PҽҮ-vutQP K2kS6[H BO*;jcfIzIf6MiD]lD"ы1phfks~'%= 8I[D373j z 5Ρ%mU.#Ǹ.*x`uig3{Ě)*MЫ!4xWL9v-֬pESfvU &ia`wq?M??0mqWUڳ'2!, PY-^./$Ez M$D>1Wf(`<)IZ^D{采sJRLۆ󌂢Oh*Ql ٬X'`I2e8~PP;QFIZc%{0#ߧ'_Y3%ת%53; ?!RK'nHR$Dcfu<%[t-h"1197VP-^ۯW$nX|Bt8rIY>gQ>x`¦)d ,ʣQx|%|`f~ļy&'_S<_ KQp5zIJZ)bH,'iGIF9s&< x|e9yz#Ix$ QfV.ig_ iM+0ܡvNΖnrIp-)Y</~If*2~+ECֿ}zMD_t5g/tHZJD00>+M$DH+D"EDF<qKMYwpK{l|m$N$ӛqAE7H$)HD"HJzT,gȳR|=c$)\r7MԉD1ZD"H +P"H$}if١f 0Kz<ɱxևntWi2Ñ4h*Tt5IvJ]ҼefS)Et"H$z)b%H$2ٛ?Hꃧ܆ӹ"u Ytc"nOYt0gIk<:x=UOg$g3.Η=J``<I+}>nȉD"$D"H$&cfv0p`?4TҚB| OJ3RM{8x?ЯS~| |* I3I_(~zi`Booe}GҀZːH$݅XI$Dgfvof76N':IJZ& if6pEUF pmhfo fs;Łqן{I>4w)Cs{^BbS`0p5G%Uc#2 cfN<0h(,RO2+Iʘftsʵ4V\fvn4b|@vاnE40p0?wP&1%zB]o#C\)-۾6>Jlln Oٗs cpIi0149pyIH$dH$Dbffvcf 'ϫovk'nL_̕t*p> 9-6L\g*;t0>FnN^LCWCeB3HVRFJO/C-@S(Q}"p#_ĢcߗzBk*珤_rc3ƶ9% .i[Jw2,<)6l>.<}:u +0H'd XZ%dǻ~~+Hw!D`L(c]+F׿ w˶o +IJ|`Ux߭}H$=tOۀk-OZҒg,e;;_`*a3?Yj}3Lq-Vϕ (\OreV q];dʎy!0{5DQ6wrnMʱ>'.Wg3"wl.m[werh˭\fŕCseʕ]k~[oV1Y+B |\)QvEBOm\ףɼbpLQo([*mlۮ̵{Ϗi0o|W&͓~rW룀ڝܐoZiIKZ] H$D0`-қ|௬9w3A~%2ɶ pM.YA{B ܽ ] \f5TQdx=:"o3jC剰h pă4+>v)p)15ٻ^,xDbF%)VD"&́_X8'Eu gJzW^C[y1./̎++&cf+4%h;*VEv}W05}$!iS?g++Q8x.\ON3)T8$=>yپ @epצṲT"ܝh'Yb|v]☺W,+V*]ek8\9w+StpY(^g~<9W:p7D"HT XI$D]sGg9p1"/}IOI:]|+?28 ʶ>8>,VH ?2/P IDATtj!"ɝfv Q% B@3qӒhCpH`ڑ)``XfyNfv d 8,* Ɵٿ߅e\nr[ژYiD"ћI+3(usoofjǒ )nJYsCKMK"H$f>i@2 m˗w%C껰ܚLtkfyk{]:ڷH>}V*<Oq5{#8 rZ 8̮9\}-CRٳqmSfV4\ocq~q˓M'Kӳ~}N6v}3{fvCGN$H$ID}c@<ِ,~ևPO hx?q憖Z=$ ML/. U()Z6'U0 lq?U=I/'f2pWc$=ef׷! ʕo|IĘ#!Zѷʱ1IZ8 sޥ8L@`_I+(,6ĭ)3wr1b*5w{ґxJ\ i3 yJ.5+jl"O2嶵xZbb?Ÿ4VwHO}oGM?$m)$fɟG9W,AFwD"kInH}cxdpYk(C\ƺ-%)^Dbډ8OIid,2I-#θH2ϼo.WK w9W' ;YD~h􎙍"Z&\Y{rujFqכ%O,YؓΝYƚQXo3T?(>O %Δ[\3L\Ѳ MQeحr\Iaep>sIcfkI6 AxD"$J oXz2"frs72Q -H$1ρ[bAҢe`t;nUn_&`I~ss$~vO x UX}L38$i},\.m(J¯O0$XWڞ"jv(y]&DF7 TY_g$6(uKq/N \q-OʖwH$5Be=b4WvYs SXj\^#,g} KSk%iO\)c3{`Zik_>I$d҅DL peL_mH,euJZsCKz0H$v?24lHmhX+|•-#V4)9tk5{n}H$=Xd떣HYoNtͿ Q>ܬwTsCKzO$vA,%)Yí,O#.Cm譲 &"sjS'D+H}c *eXG?o7 Ǖ,ÚZzMD" %D"y$TRXn*S`(1'>@}cݻY577D"N[ˡ|+!JنNUk9D"ѵ$J) j,N}̏GUB2%D"'$@mh܂tCI3{6Ot4!V*EZ>HS!K0>hGs^݁XHhI/kRIEzDד+nE`?|r>[i/)eB;n69K+`b ] Q-K$=<IxmhX4R)ՁhO{M*J$Nhm[ _v I)sYr>!3;TBR=7o#t\%i3i:ct)ό%$ nI}4L$H7BE7#Xqee>?l9uihY$E`ݙx& d_M%K$F((2W $Oeh#X M0 g IKfIזQҀ\\w>]}.m0i Z8i} <_lGz+&tE]Ma Pʗ+ˑ}qkH$HG :߲V-0zLn eƛ憖obiƺ”-RN5}()YnLBD"q]2ರ!%EDqIPRkf]6rf8w*X?xؖgy(Iu^贴!ie`MN[cfKhs= N.>bDwOFhX1Cl n 2pYEqW}Xf!Dom_}qwVxmgl+M~B)#٘nC:`kJhوXWbt/ ڒ [>+)`zq%>F&ڙ eN>:fvU;xY-MlnbLNnnh٩ެTFsC -67вmsC¸f&AuF`D"HLf]lf;k'V[/Iz]Қ|brXʽ|Z[e : nݡ&kIxT` 'i!IX&i~ 0L1X 30%%S2L GQB*`M^IXx&u +&% ʅQz1I{J^g>a{%|YDž0R9m;Ŷ[}$p~ <+vy^[g!lW2n -^'!*x+Yl[A-55۾!.~ƹs+~.<)]EmyAaKUOIZ@<.c¯q7b%)AtqvUirGwpw :D{cn0߼a|.6E6ޯa뺈CH$$Nx{!%7:xJ[- >(Sm`33Vҹ!, fv)x7%OB l4PPMV6ף, {.-<;}8RC`pi[8 X̾ !OUKv.m`fIGqfaԹ ~m;w,wʛepߘ#k"Qkb%5Pz#9\H+n/FuvFĔ47|?t]PX%%ڱSXw)pQFJ$!&78%&2o^'xc%-/i> $dS%l>_$}ك*|QT6_`GI+}o"L(UgfO}Xfc J}p%Ƹ +nk x`OIr.?J?V'܌G,KUP=[ R~+\ qKSs3n,oT`1`}I{٥f#+@y7u wdmʜ=uX3$}J(@r}8?UR, y3{ WǙ Zzí\\;qfbN3h*M({MIO3kqviT [lj~['SRIfvrnq|4n&|}Marl>fvQlk4y̬]3Zҭ+gw;6~[*947>M-sEF5pv4;K:7nھH<&ƺ47?D"Zs.kAt1Vp=ޤ{< &Af2V㓺3m@[ .2K\Ʋ9'>gjO}@*J,fp/{q_ =vŭ~+Q*W y|0w.`vV 39]lx4ntZH\9תi8WIz W[nic,FEw(72X-COxuZh;Ų9~zqOy(0sC>IshnhDsC˩ -fO봲v}cݿAD"IYӍqkq"D5=Qr3Y5=pү)'ǥ3ned2;P+EZÍ* nQs*,T-.5Z!W'1ئ̘;W^Vjܢf2yW<`\|G*秔Htb%63mc:.ý`憖eZҕ&t@sC憖3ZVŕ,Go]EAzt}cuIH$5!1PNя)݈ʑMP bZn=[f/6~D>0fígvy9ĭ5%vb&;٢Xr\BϠS\ ]b/(!2E_"ŕV -IYns̔EgL9b<Ǎ=xUSR3dncw%Sf)_[zJL8BR j,Jn&$J8D᩿x杌}rJ5cPvx|+dn/S{/H\ 8Jog3#3{w}bc;0hЈ cZdqWZ`$??V_0qY(Gܓ:xqqnԇuq+N-ާW23>edJyr6)/]E;WlIYzK Xx5Sro:Sl7J1 -O^ޡ0ěQ>y={^6xDmnQoqZfA3?H៓ўHt& -,Go;`I$< ljp-xf1,iJm!p<hHI+I ?3; *`}a\֤|uH6&3m4J1>B1AI/~`f_1f'׵%PMhBVyg<͸Ífxp˟i $+s߳3.Jg ǖ>i•QI[osN4GU_s$]?{nj-jQ< uP/li IDATg%]ˍq_7ƕW['9E7F,~$6 ƴ(XҺ1os4P҉󒎗=I?V~!+c#&n.,hkn&\(O7w:rC}c~x.d -tAD tpm֑o?*وr3;x~I}(nE~b C{Z=I[VYtS{kq{1^j%8-m*ckHn2B@#݋t"47k t~dH$`tIW*U)X0k6͆^nc{ѓO:fw?K*n|]T{mЭ+qt%]#~Dinhz:n"ܙ~ ;D"H\f Q$ t4Vt{Ȟ rHCXKSAiWt\6t{m//'XKx"ѥt;Ŋ}ifWQt`f0=l`{IH憖Z-XN>f^oU}c]D!iLM:{gv]D?`W"i[`W3;Xk9&I}%e*O=C`9,uHݞ9^ij ȴ<,*>F7~>Ѿ)޿OtmKd]NOx(;`?IMoa憖ˉ'l=px}c]16C"H$IKef6 xvM5tUfc~OO|VHۀ'V>15Ji`NG`fyUV% Kҋzw4)( M*UE@ t.jUPu@7{s3}fy;o9e{)ORAa`fffJ/ }Xw:0_=#Rq7-l*durxSt3/l[3KO)i6-y OPl /j*;XY^-:GR+Xg,664WA0ݐ ~ MhF7-`O`#Yh|%~ ^{v.CI ,>HZyvY٩@1vI=q {}ɬ%ۓ=p3倫;%\tRKC֦o,~vtp|aAЯI O 𞙽I.+bz˹0ʅ~f6̬C.Zffa*XV:~wbkfoF|VGU#fnX,~,f%?cR>^Kurܽw+3$beLJ`3{(U쁒qLz=ۢxZe3$&n,dfwՐ p쿹lƙ٫>ew5<&ݧ#ٵU3(L9KHQ3{C@f}(i.`TV27 M I`>s˥=EtD ͎_VPrcgXC3{-ɳT*H{OwJR^j.3&w{ < mn7١fvp}6x'l~LQ|3=&U4;݁ګ6U:`?c^RE>u;lCqOuJqmW1TK _-\L,5~i|SpMڗcp;>߳[pXz\+Hvn˥O -p%xt~,6Luz>G?,p9~_"i*[qж~+7<)*9:yw'_l4rnǟU^_XCso%\sIwHs <W^~7qxiIKN~ĩ uسP{u{5m A\ :*kZTt5K;?ϛns|n;$]Y+kw{ǁm p/$ݏ?25hSX,a˜sԣ>GC [:clIھ[?NR;s'1͕݂%#//Tok X lڎ%<&ͬ'S?;B|vl8@B1rG1/OWZ9@imsesM> WxS-gp˝x|̆[,+Iv\3yPWj} |,{t;_l2)W6:Iǩl\VH}0D9%TeshT02;V"⇅ȀsaWq|q• ̟+?4m+)+kJe _?Km\"f\1P\Ԓ3 x1Y>O͕͞Ρ u}8qLf2 ̖ʎJek1\ټ96?..(y М~ʾw2ӿ+b+p unxJ[&Y0RKFt?ׁ[mnm* '35_@p\1DhIqˌ9eU-lUTQ8x=-U#{~>2뭆 0~o|Q9..*'ro9qա6+z$~dq2KzH&Y{3{19y>/OAO򺙝ƚ<̟>, ߶62w,;gVq 8_=:cfQy.}-s/Qo3$׬Ql9?7fك+.̕=S(`m\1Hcs,Ls4c1} 3*rgWjw2;;7s{WUy eܵa`x qppKk]>ω/҆cru>εojylyI2̬, Rd)Jmϗ'nnlL ۲\闑o1nr$_c+ϊ]R)Oc}:[0v\SiMg8w{T ט8+'˶ΤBێN =)Ig XM{{+T_33Ip"Sd,[݅[eIbRbEjgW+UtA6*l՞AKSź2/@ݶ"LAYA>:j2A_fDŽH܃+~'*bI9#e*I4++4*=p:@sj*Z># Z)9f6W&^[&tVDIg :ihUib;n[˼ifwiܪW_.E\5Ue4*Õ{$%YVUwc´A{twCy;*%[0F|7xsnA0=Qj)]j)t0֦j Ƨi,$}WlLJITko;xإL$iIUkEJok}U'gU\)+?f|4ϣRE/ |Xvd~ %͓==%$]AҎh_ ֛-+VQx^{I%ף/8̺u>Y|N ʅ6of2f.-j/3Ak6u13{?ÏSk5%M#[x}V:V'4b%~>kff7 FRK^qWxr5 LSRBRVQNHҸ R]+2&KJC|lbn.,D~C}F3䙉VeBAIk mO3pSHg<[\\F{RlEbfh?J[|I<ݹL9UDvN IrϩjY36}\f"y65;0v5x|^aLgqˍ-, \st쑔<(휂-ׁ<pC$ʳW% ̸UX4}*}TRX䙐>WUz=OfǸJVyd=_;}ʾdȹ [g0/Ex"s>TTb:жd&Onqq$<+~TT+&?Hp<}I 3RKL4`skSR4AcL l~#8 ٻx*91nt5j+)gY~P:^~cwIb 9w;7)𬤋%gx2Ucp_#=7n}p5;xe)|3פÀ쏩lz\\CxJZ"7wxP óM [p~+Vnhg_/DP "*i~ŷX,}6]L̥)O O +$c_ځw4{ڗtgK: ҘC_f NICf.'%'dJ2cx{sh"j:g67Sf>m%"ox\mJ3ӵ~'8OIi/, ~&id:v]80@.|C?/~ôRy<〳SpɒK򟊧:"Tx)ne)0"-nk4pV\ܾg:/Is1O;W]fen <[I\)?`<QO{k4DV \[\%)`f W>s xY?__oϧ>oH.Ve{AgcϱK))볁fv<~~ 0glSܚ+==_Gu۴)ϸ%FKAɊ{ZBR=pX`_IkOe+&2x0I$˟#RIK3)վ[!iζH[ŕf$eOR’v0kpkG9^w+l*iS!7jofOGÀWہ'%eO-Y2 n_dZxW<#`M^q:'\-HMp//G_ğr>=WЋ4b.323%wa IDAT%0 if7-ͬ+AҨ@<$]+Z ]ͭMd46mVj)AP I[,gA:SX&3k Ѝ7 C!m&A2EFt4k3SpO!pT_HyXC5 *2KoT!+4rfZ66t֍`m֦oZ_tATBBxUqӢ'ۗ/9&эԧllP 1Uz=)Hs3{1@3sfe* ifMo1rRT ߆@J(#{q`L< VM Yqj v.IsMF3$Y/@1%pc6.ȕ lfJqo-o1Sk$3f6I zsQ}dw>`k3(W5`tfM}Lns_T9*X¸^P'l\ݘoy35Cz9 dfc>'Oy}&6#?ʃd3$]7 web%}3Nb㒼+VɕMV90sK+JήELTIÈ$ۊAӹb3{B?X' o? mfL`u3{8#is2ݜϛd=k>5`\bftٟ }Iʻ3 g^N۞c_p}++_&w X w)jnmiRKJ=Cz}w-ZJ얶UmbUU[kLjun0ߑtks*NI73H :%`T>/A}w%Bң9"aYmaT*59I' C[Rby^Xxx+) T%Js)\4_KJR,W>, ݝ<28L҆f\bEոqQ*9`/I+p8p[aixы8'Oc ŏ=}6gJ곒3cj[810p7Msʈ$g54p' "x\y8TҮfvEkr"Se֪+y =98~NR{@+~̏׿HV]nv>E&)6J_@?K믒7Smsiq\aQU>/ "|=+~|.iK3{3Y?gÕF BG- _Ȟk}ʆv/;9q;}[6dߗK_!pha>.k?W}e/ȟ믩B eNHwȕL-)Y*pO}\QWr߇fΕڎʕm[-+[+ջ0WTv;t*<]c|?}$pZ"seCrߛy60_*[1 ջ4QGΓl?u6`寋'reK*80k .b3J[F ^.VtN{q0SqN]0󑟳Łm$kW+꧸Q>s],]\t9_J&\FK:_pό5Hn1cuq>W?Ǐ6fM޳.HWhIq*5Gb~+ʶ-*[ƕJߗDFt޵h] [!=m6i?2KݭP<^RfoYC3~8}.,>G%-J( į_'w*bàoi8ŊY$%CIIX'>/pӾ^=D|"`lܔC[ 7> Ẅ._`(d1orrXIktG3Y Z@l%U }/47Rk+Q}I%'(ܺg2cϕ&ZY[2$-$Xbڸfy%.<܂( \Հ IqI:oHEVLUYܔuseϝ+qK$ݝ\n.loEI;[..pkfٷUa$_wZ>u[l\10J[,+IIq{b6\h2t Ga?kuJmaJR[d<&2; w8MǘY^;WԍmGsV 'q f? Wh+3_e̞A0Qj)߁Od[v }jfO[D҂$ %mǢD2ZM3U#(e*-*O/*%ؽvIl5e?Lq;2*e"UQ<wI+*_eL2YYکQ׻ ;/L}W~:,yq&eBƃXIN3}7XI.l33vJǨ~NLʆKqw2ײc(i}ef''iښq]-n]ҏҟcR?|5Iu&ڎaj<9*~nLz)zSs0݁/Y]ok]. X)p){X|hA)/;vk[j *#}hsz{EJPp|a,;-r6]o!ďݹL9=ff\!T~SfJG Ɯ٧V7KjLT]IYX _-O^߯邹2Ÿ+G]eKs\-ؽrsuwWvٽ/&yW(6kFIZ?*/)e* ~ ntP;ڎ\4c&XII:WHz]WYØI%~Z9i-[ck2Uz 46 ZHApH7ug_/3YwٸJgDқR z'i@aqCO|h$R`/3+gÃo_uQ沑9>+ oRzTAU~Y +W465j -2} ۟*зs=y gQqJV.o5Rg.铆WfJeI3[ ^dM| i  6ӄ;A&mLAGY IJg%N!W|gFi^)xg-HArXF^~APg^kV;+y)??ɦg46m "A0b <AHfv S6eGfA ef\*iz 3x7;lpeskSG!ATb-n+ZHhfʛ !)FB2SVă mf[n;s*:iev3bz:# 1v*[TE?VJi?AAѨ+yvNvvJ4W:֦zA /FJjU*nU)>Yh>۱5qvxB1X.#q%+iM%=njD yM ہ끋soڏ̝SI퀻847WH5 XiIgWH;}oȹW\+2ҥ=(YI+88^`Xm_`|cз v3~NmJjM <'iZsA?+wٕ?AV'R/CoDMx0zG 6*Z.tI fvЂq̞v&2kćkfvrzY*x̖& ph38-ypD p, qՁp%.LfZ%Pfq-3;.n~.ivi-`W3|ؙif7J]p\Q2;<>-}98x̎Nco, 177rf׬sVr3~if.gթIfv=OA$-<+P R~#ؙksn< #UD /)HM|5qk2&cOwf6&[-pe\^ X W>afd{h23̙H!?ƻL˱fViw 6݂+twf\{ VfmfJ:infI%ƕMJBM8Qi>NHpnuT6\; %_c +fv0PHw2*XPj)͆465լF_n-]+e:w9@LqKϪ3}11fv%+x`xղϴhf\ڮ;M^5jdT[sǸ['}flR@ʗMc mk_ԁ^x|RJ 3]+wx c.A5hx =nfq RK"#ͮ IDAT3l \/IA \+i6`A)6fWXӎ|f3]'$ܸ MIn6sȔ-̓>4*ldSJeAO-8uspE,@ƞTen "&Wܕ !puZS-}~-$ 40ϖtp%t9̮#PAKRxPY,JU( nnm:v w$͇rVe~*a M,afqbȞTsՎ)>JX]>*UX^I;qwSX'C Z٢P|ASmZ2)>> 8@ҦS:1q[.OkU_>͕Ϝ܉^0e.~WA,AwtwuRI+qxskO{A rq(WTw;%]:,x'9 2R"iU hxJ- xbZ{ R gwbfOJgpwKx*o;fwʈ򅒖HWҜ<b< ~?w!iIGqTwSIIZWqXWp < </*fO3{9:4jvMcq$ړH:09x*੟oKU>O{$ 8#? 2MaTI'-k4iϻ~_qnUBA AFUiYDL3 c3{=63ѧl?fT[0;l"0Rw #~zmݙK〵 4K$=of=VrR6J61CzjzD-{sA!-Vך*Uh\ك (Pj)ؓe\ڴA͚ALWX+Mk"s;JYd5UAPKܯ:gAA}f3Q%- ,ЇAMJ-46746mTj)?KAx@n|bq܋|\efb  ? iaf7)jRKt<(dgi^)ƤvxŁR  ѐ _J-#;l~֦b OFD{3+fvl_AC(V kj֚%p˕5kAoIe0}9^AR"gzA('i5t*ͭMPA4 kwn@AAݢ!JZO\m[ x^2A=J-rskreN4iǤ `AAtTՕ S qJ-叚[DӑͭM{Zʑ3/F_[  Ш@03[-n,c=@.0MNq fS-?bf_[  А3FπR_ASj) Ӄ[y +V[  Ґ@>b,\^2AгZ46}܉46_j)_KAwD|   il l Z,+V (v&v[v [FKAAX~nfVQ0`hAQj)ڴ'p1n56Y|uIA/3x"ZAX)*U$ E%-U mJ-u@֦oHA2PATt0v90=(RKtN6˔+;HA.Y|\AA+P38xBAZʇwY\ "A{l>b% ~EPXx2ifg&YvFK \4جOٝvjew}$߯$-ifovO |ļ,} $-*P!i5Gxgjug^^{I+3π TgV@x0&3{e|X?޻;8iKzm>* |AЀtrͭMzV :`z h%YU(|qyQ\mɀ)` 4;TCHTӫ)_ %@{1: ݢ`bzTSLPE8g^+Y$#̙ٹ;gyz/Ɲ.=⑔I| ; E|y76)s{K-w;|Զ8vgf6WMs s3Jvƕ׷R% ~*w|{kU +(VJ<; Z-psm}ʹA.P@ڃ_f6i38#̾1WP6=[<Ic}K`g3lvmhf_WyKfF^m3;i2$ kL'}_fUۢ3 Wr _Cm}0lK3{;"0cf/M tt Gª xHƵl@!QfWdC@N!Zo'n=syj eiskfn鶒6H.1k;D!{>ɓ 9= 0zL̥uvKt[gfw'r8pVuv"t]獮RfzHtf xz-}U`Lm} ut |iOz&Jz&2ܷp͟$hfW&y?tsI7fǕO6,|<VfvՀ]'*`~ 3ml+#pq ؼ26>jfoGz-]gf/JZf][\>-Qf~3Ϣ;xK|# <>yu1  Ӎqׅq[UPp 4W4 7"'@B@5 i_.87xM<]]_}E.O]y_XnʞMa]/1Mߵ{qO$obYn1ru, ,mf#UzI}q׵ٺ$[||'l x9&$g7ƚ K(oyTM!1&7Ȟqm1&xwˢ~RYYK _o?2*#V}wnx >˕gr0 8/Lo>Wm ]fLt{ wzވߘ{$\]=KwݝΟ+ʉ)fP/ー͙ (@C]JyK5T $qn qzI#c1I\T~o+0] +^_\/i8V I$ _>/O60ȔoBIQ^Y\/HpI9G|nxyn~ W>sx!3kOܥ{x.'(%g ¡{8 gʟ+܎~,EI/HZ.6Oዠ1Ѧ3)$] pp!8Aqcj)T޿na5I{\rφ2/s. >Vekt6@( >< l:V \ <%ibNIՃ$ Cs2.+S$ccB( |6D_ ! ;7cRIJk 3߄8P=p~#$-s("\q۾8S58a9RGү$1)e@`x}U8]"kߑ{<+q$~%iI[ኡQ2{/4gG^^r^s}+g\yroʸO* q| #qeqo#g$i臁8!~ז盅qem=>nf]]#Y q C;5ntG88;W{]wx/k~V6G8?Ɩ=^}WӠnĨ'V"mA"m3 ^J{;D9jqz2nAf%>Y+[)nQ;,q|yG\!ۢISZ!}һ/)7/v%{$m|G9c;.m Jg|<π+!?(lr^#[a4-Ҵ8p$m͐o-x.{yn7e87 Nf-sʚ'6I59 iNS#ese. ;Ҷt#W+&i"R\Q3naI="V`@mi&.!| %~*.QC1$MSƘ=w< Wn>mwvKU`Fh[ǵe]A t '65NBh̍mb(P:Ěf6ќtMeDo0xxTB/BҩrpGʲoȰM"qmZxG!_szG6Ky7?g"ƸQ߼r*pJsx2xX0,u$ EXT[SFp:i;9R˧fv9pB @{s'G/٤jfcB=.o "c_|{Z d09\~!N/\Y޻:v29/nٓG3̝;7~{ț!kPFly1/L=R*j}`dJSSQP<.iYp^|~kvl\Y@ڝEiѷY%*Gd}iN>J2[Yrݍ[0=y=Y4Rs,UoN,6iaB2[FVs$eχg\,pRs+oIAW(P@[n `W| hVVY)w0S:pp.Ғ#m(Yrg487>vɣyT*cW~=[! I-$4݀[>\ϩto 37!fPESs0EA; Ih=rfv<(Weo+rI R̖ S"-Vzݟ-/g}AG*ۺfGWmfC={ZL|{vtMP^.\Ž+AJ=ipbIygǕj+ʋ+uRxy8f\FWpEqPe]]^3c-q6ܤ6݃Fȉ?l[P`N9x--.缣%Ƿ4Klo3 t.(+ Px=nؚkהd(P@+ίBR\ZwSK3@0$hܺ"L|K"ܝn4IG ܌D|$m3 )ooV5>5pb+U bRk ΋uA n%.QٖI钶w~6l3 YWƉ- 7p{v)u2K\+hݭ[\w ΄hV IDATU‹aa\~/m e%y pKJϹԳTE6? ??s˿+Ӝ =)F%Rr R.xHR吽 %LlHnGJRVmCXe(u̹@z=1?,mI|M,||ܝ]+?A'x0,:C^uq J,7'1cݗ)Β/]*ϕTP(P`CC]m8k筸}1`lm}͠@ ZZf >7%yf)&2R/>S/iKy8_ GkKz _ d_Yqn8)x.C%m/RgĉV ~"NbJMrWl#)+?#TLBnGWќ#ۊٱb L@_HҫEn65zK:J.6VCϝ?<']'p~" %f&*v#}]ܕ vT-#ı*0\Q?ƭ(vyj->yl!,bh?Kk&9! 8?C΋c6af pہ݁l\S`9|.!9w-y_%}!xI Mه$qKp#?xxrwYJsf'ȿ)X; sʬ\L}㊇y1+ }|5>7n%gP˓ 8^#ڿem_$iD`G$-$ZI'P9/xԗpMѲQnX ElА!S<[}+݉4^yY㭉\f8`sI9g.8\QүV5cpr!r׾L' /#ec\AX,[G+ʉI‡ʨ* KN(:=N{o{5YMKQmR]ߍq^ۙh8LT6r5Yt!1xY2۸417۲ t>̋/S)oPxlT "> wنd7u{ƶx rLtq+[a ,h5AV .ldkKbʄrJ{,wwEbxy,nr𛜒@<8-ł(K00;D&zny{nhr˳qǹ>#IZ-Vp[prZ*P@Ihk|պES[_sMm}MO@1ĵ-9~̝w L*RNy hZ &_-I*Z?V#[[ʟclTj묔r'}WNɉH+*Bafo2P|NdNKwȌ3eg]>dft[ Y+r%pgq썎@?O45/=K9n PS X@Ǵ$-P`(A3* `f_$'#t+ Cn -ډ*gg3=\vUV7?l-](P@Uhkgk gb&@Ӕ_@熤JBvtTT+W?OG] $mfJI[ඕ,}Zso>vvBg1ƧZtzmxm!S]} (j45>_[_0eo)ٶXD(X#dG R i~|l7biXlxՕpnmPfkh cI; xl>x+ɳ<>;3D0 ]b I#L}*U~hkR2ඓ@ I=p%ŎtnxĔi;.i^yso`<cx-8˔*fv50+TgUpގV0MJ΄i`flK 6qV1ו|0)fXY76:V LOhkƣ:܍5G MIV@ [(V t"eU<kˊc`C<Ё~\8+]K ܓDxRBBjЦYָ48j5#](crf=ն+p\ 2ah tyXE,٧񲶕@NՁG: s[<}˳*n>bx̞)ST}Xx\x \ x$ORk ߀K =یYK ٭ݭLJA03&eFY8x('JH: 8"}yYf5$\\.ies3o1?s{n3/g<6^5$- , efoW~{l(3 ]n< ߀_ȯÒ| ;naő^]}) \ wz8gm1',ou뀟b03]{Գ$^\n po3T9/D$,_g~MfsfM'ޟGik]#3pE^3{D5>.-W̸r5> 2I$.Ya?m `rn iVI?{b t>45> ,OhKm'Yp>07oV:BIkIzxW,\w)ny% 2|tpeluI˕K[6׏;pkj$+4>;J%:xTanWJɕs,`yIG|9έrg<3IP1ʵ8 _<$br3<'.s,-6KqޕzX􀖔$->X8WG wcǕ0yY{لP|L>;w?q+4|Hnƹv*HË. p-s<2OBѺF%s2@0,?nU{`vk(>itG88:wx}Ὤ{}ڤQS\`-$-{rG g`͙Pd$mA|G$mՐC|r#Óq4߹o* NҮず\F|tO{'&m{'<GEޭ5I^OIq,%򝐤φ_tk2|`?}{yOZx,I҆GYIMI8iEڡd7]+W2/E]z/s4SSM+q@H|ok+0}+(V48 (PCP0nnzO`WuF::RK-2@EG$~kqbl<\| d\ {;\.Y 7oF鍪Lɔ)uHZ݈W,[99۲n/0:9O4ז1-p7ף7H?*#mݷb9rmϳp3IH:8(Lnx= _Sa4¡%^N,IZmf?<^\w,x=A6gyMv.yL7W•md?$d418!0J-|TQ,\+ƑܽV#HB#&);Q~.|j5:\7#R@)k%xy}9pdX (hkf}|fpHC]4(P1x_EzђGZ kr)NzsqjSNvIaq N{G”Ϧ!] yV;/d4L-2˛x_ Y-V^'['ZךfR@킆Ɖ uG ׬f(ЁGOY]Ϸ%͘}OM#oš6ES;XT7&^YPIOpɗ'p Vq488}[/3 m(-Hвߍ!KK֮C..=JK!,^03ˆJѼ.%&&7}/e0npp!?fրG[ 9o6?y,ĿMGH#\uY\G8Aj.y.iD޾8 !OѶeI!par7ps(q=ři{qIKzx,8KWҁD83l eJ|5lUIX9>JzRR=L0( %m7enK1$k[}|l@\)s]W.fȔxޢB:{w@_O$VtŊ%%II)ضe+P@rhkllkZ`m}s(:ɡ`#6gw )XGISҡ,+'Wr$ERM%Zų< W,ff7Vh7]ƅ,0E6|Q'49f$&Ghb>ɝNmTP 3_ofK7@Am}8fV u#^m IW;lfOL`ƖUכYiIJގojњIV":Kk, ,w55t9~=7'Ui%Ow,!9%e\ LO+03{̞)I@:=?hk7jkuHW@b5|CU@G-.F[ӾrJ(UK֠3sPqS*U,.F-7ZSgz +KYXvdA (PS `)ܼxjdm}kk3bS&-P@r?y h{%4D- 7e*P@Vm`3p֠;]m}ͱ u?V@iq*e,P@m7윎@]bZ3[f6ϴzÏ(P@AC]08aԠ/S-Xmyԍ倇[@ tUso]be`.Epv¸(P@CC]5kHN#kKwP6@Jxx  i3kMy:@I3ٗ-Grc(\DD 6SQC}6oZX@:xڱi]og@{]be1`<}vlhljV@SFkk<+`jkN +P 4eO#bGr3K֐t\c$fڟ|gJ+H!Jx?ywI[Kx)7[DҙCi IzftMI4We[Hڠ;pU<ރ=Z Is'cQJ eӢ΄?΢珮X hf;gWSI}5کPȥi5t"iI[v\ (.hkP׸.>׽E Y[_s\m}M+403]g!% ZprC(.6í,^r$^3g2;Ui۩ iq`,f;{̞4JԷ =5ET_fSҊz3bXɟOfv{(`%-\R_>tzZ3{YҞY& 3+ (FC]kkni3vPXDh;_E@}8v뽁p5y[l2fXM~cf?%f-q Ձ3I}#m~3{ Wv`C`_蓸6p!0NҸkq}m3{4WfOw1 Tȳ 0.򰙥nrגM0LlI٣%-G rf6B //j}"i7bIK%p!i-|hۑ^K65$ y,3cZ36)S| }|x>,#I`\Z}_6u,EY-|Q=fF6̍,mx|$i|x-Ϳ'HK%-u ]/KޑG/rI3Ք/,bf.f6cUVXl[=}?OJԵ4n>_in>]WLJfNwiq!?1i ?/1߭Ϗf6g7~x?_1C RF4_Zq$PxX9e`| JgO湫/6z)b2ùI[:ڐ\_Wb>ϱu83[8+7A(P u uEW,:}kk.e(bp ;='Òoha{vw,+=pwKp}uQ 7C|h??xp%Pknu%= 2዁ˁbU%ƟzF.%-\Qg&þi<#Qݸ{Ez ZY|!rqW?K: ʸ%DێwWTAg gG.@Uђny3K$.wÕJO JX_X J9x}^Nz,?%C/0+>vpr]X瓴8; Q܄\;$m?pecr߲H|A׈'{KWv3i}'K\6➅|8_S|d>^Rttp6L,2$dhўKД0pb=>^IKH[Msm=~ qJaY=p9dpcr\q"W~(EI/H:$vŸ'k&eGs| >5 |fGykQkKz]/{pW6iuۛQK*w}=~ft]($e$}M̥WOH7-wC IH~ ;M8&zJ)s*>'fUBoرq:я1,5w/e3C]CE;8((;}z^ֆ};n_W=+ߏ[zH[xnTLJX@$O|J΋"HۨB;\2$QPt\ 0;WȻ{3q~jrϯ"mlE_q yoǁU#?yT>br$\`N[_v_?K{I<ǣI.c`lWX x5ko8'˗3J\/7GҦĘW2H /=X-9we.m{ly|V3㊷/cP{yܻ~3  \{G/H 8%[Ef%È9BiZq‘6(M[vϹ*՝WU ߃>q۸bg|s,I;5҆'cH&ɷk㖊}hkNÎ#߷$%U]\ڒ1HmIZ&s*vuHe. Gj&׏>Jڳ;>V\3\ prj)R fnfݿ_lg\90X?78OҞ'˘I]> Yy}?4Zfi1PҪmjfX뉁3룮ow<#['ͽͽ?G-\wu, u}6Y&>Nskɗge=bfOGoc 9 sR~~'o3{4:= ΍?&,\u::IdnMLב`sYl~a\3.s)rb|%I⊺%.p fܕj" - pK턛pfB[L"|Ak]3F9&du Y"8r䮎V{Sp4qρm-{RDC_WRT;g yiZCfYh&W@o716v֖t&p>Vv-V݄6LΝD4:I[6U\dwF)Hg(n1uW'RudJHS*K&͊ˡ\pR\,oN w3w%a)4>oIU0=%=/Nu^ `ܐxgwчߟ D9  &cI>&d0` "1Yd8ޞt}}vww] PI!*[@5j}bfcQOZҖVcߌ4-%IA;hwr3YN ݲI͆G}AS #[^iٲ`OWq^cSM 765A}g ffhf*ޥix~&5ٰC4E,<_ndfot^\UesdLd5# 9.IwOd=?w7;;slz.jhI#k٦lbh[3<.i_L:c<86sE=w8L5$͞L@-神^q=Zz^rUX9]o,ZlQes@RI@H̞ǭ8$7RJ[Rh7nmqa9ȳj`f'7=9"IN}lI]Exܜ60pˇRYy1~.yih7eO|ĕ '5ҡ+<$zcNBe_؎Kc9y3 -=o#Z}F}RmtIl Lj/ Rs*@ߦ=YFά:RЂӧMq,k3)VtX37"iy%}m7da'ׂlfq<,ġij:oJ%IRR6/.nI\]Ԛ|@Bv_2Ei;]*~?YU]Ѻ$|plt: hLȖh}r4:beƦ[mljXH2*U1Pg5pW` xƞ1|*md%^S60= IDATR4r~; !}1xïg$-撴FIV-OYs`H-|>#; ۱MP| -][,\ _T> <~ʲ0rG%%@+i#ckUbb]@kYo>ӈ%W?IVa&ZڢI1ɒnJ},)bڻl\s/V%cpi^c$-mmyJr=wܢiE%4 E`IK{7Ile +WEZD&)|HJq9/x霆IY?uUjcg\i6޵\qwڶPR t0h~||/ʙ |e`=/mAԋƦ9'⦧/hcpʇGL.N]tmfuho&IOuf5ZRw {#'Wi7z}oDR2DŔ6n)""y l[_ܪe%3;pLxzSwS- 2cb\(T At-cS4I `Z`~\2xydKKc{JOF*)OD t<.q3OIKVۓ%֛Dkn=:ߧzS+$+pك'yA=-565+WڙN޳_765<+ZiA7i&倥h=.uu yAS_'dܥ3UsS`_ XJRq?S6 yd˧NZG%FT>kd>c"_/o4l}]KcSD& DG|na6<xf&<M O珁<\,<;Hk0c=Oz ꤼvS$R%ނ݌gBRC.St=U0W}kG 6yA0<]Ʀp+m8 fw0}zQndƦܣԀgP\4[o9z jMEye TBL.zde3R%ofN 6G<<@`N<@i {tWҖnǃOg逃  @OX z#[77565 -YFn6S;gW 5bǴi.)5N7]E ^AX z&#[<-<šZ8+*ނL f=KNNʽI}f"$  j"+AD<-6lY_=!Z-V҂|)w}HZع en,l외 `J \ Iyd8" R^Rs@w $]z R I_V~^/hy%i``p}۷p5gf)IϚٷIf0@u!xJЇ.Fʏ љLY wU Ŋ6JYo@cg:Oތc}/ x̞/?]*i&`<.f] [R&Ld}1fjGrAAX 2tcȖG4 *.z/i-HU$m,Q`

    xRe884کAEԧAAydgEcS }du<"ª'ǧ_={=LMfvc|%q7T~[u8JIn67$ԁwggmp4THwY4Y[M,\hyˏCk$?`.R(>T$%s_F}بPO3]XpeUf~*w+^ɂ_ +J vb% 4lW`<[*=+0>-H Oqeʛ{#[&ĕ#i~`6zR,nWW⊕*>~^oLc$7o+߄&)YC,\*bfHZs2_1b"u>N3'9gKe2Z}YKr9xAiIfx I$m_@?I2>X>SOAH(V OȖx:*t+=6J +)E2$J~0Gex֬$lf*54o0W1Ϭeˋ9Cbf݋g^kfJWmfJ8 8s0!Af eLܙ0#IY H `b+=6#P+YCzX0Gfpɾx%LkҼf6c4'Kf%s+NVuNW]mf7wf֌[me"iծn3 r JA^spp|V3Wl\G/ɕ2] NeGI .Ã͂giG غmgS { WrW$ ,ȟZ,QXzXG^6/eLORf oZf\Q_)R<[QJ*  hC(V  4{v9ɾ/pX!c\Hyk퓎}8)k<PpiǸĘ2]z^h3COQ)xK?7O"GOK:\Ҝ~$ս%H:@R3{ X8We4i?" *kK~mb)-{N5fVAy$]gpmfu W.o Tr`a3{TBOpm2.N,SK]Ao; JAT)cR:6ڜV A(V  wd.G  & X HӣH3}E6' )~  ^Ljޣ+Mx|p  JAeUs<{M̾ AAL+PA5#i~3_oy  M(V  n@AAB(V  %JAA  :[z AAJA5!IxGzAAJA`& ( `X V*U  D(V     b% Z9($$uC[AЫ JS+;gy2S.YccfWwG[̾0ӁIV13;w%tӛMvOFWط@7*FO^5o `]d3U SSi[fJ̇s̏3e4@wY ,˃cBAA%_E,gN 30>~̞1S3kv~%i4O lv4^3n֊AЛJA?PGvn֯VX҂ϳJB4w.$Q 19J-@Ҍ]LfK;jyJ[U+i /ZIZ@<!TigsNiN4_rTf$M; *J>$ ")5, ̗U,i*dH J\9 Uؽ'p=]M\SlՊ$ .>asMBiA J}eu48{}q*iT6~jgi$-]hAP/BAA;҂f13N2cG+WLr$*QII.= 7]`N ܱKJ -p%,)6p$#lIwPrtqVOۖtUvb켒Ɵ/5܍M'NT..FR K!-u tIڣ]Q`dIH4*)'*Ս򠨋IZEX`B~=8H;vBҘκHNKۖt!R?TwҾA$p9%=TnTTnrUdhǁ K:x+2'KxCN.I_7t}"J`8Ioe<_-Uҵ{yį6pKHxtw%8Y)i,t~vLvҶҼ&g0t_n(u`dZWҙxtMOe9.w+۹J`PKs?͕_,(mTnm͚ ݊6>8B=XSf6ÃT.*i{x Wtұ'3t0fK}Q\ٰpnۡilN_U< n!n1s=fs޹!\1I3 {Tns~߁\OCso,\;tn7Sfl,14Ɩg5W L紝g--ٷ3$y[f+^+AAWgڽff_O 3^lf"kZZ3hL'Ȼ7 )uS3{8||zZmǦ޿3's3|qC2mk[5_']of'KኀCiEhK"qjbY3kp_aJZ[eӘ`foQO7fooKj.aXZ>df7afvdɱ$߇+'83{ _טoiMxe fm'^o ]˗c**} [ISqf&f31\3{8: hQp%.Ǖvy)IZV?\tOݗeH)fų-Ꭶ7Xy%4]?3Ǐ$ sR}?l 3{^ 70NCLE?K+n1+AFBAA#V]+O@/<ǛȲ H I%GTL .!Nn6ާ`vPw*Sp㒶4px4̒K.7|ٿ)X>=Ol3=?5+2ĕy7qˍ|0dk}hzw _4p1/5Wd)zdT?I#2S1A]O]iF[[ m7`?S't=rE u?p^=EҲUuϊ56N-ƭNs3 W༆?z 3;u.p<$+d" b% "Y|(V܅eh3{xX^*Qvɍ%*K}Z9/'٪"o`O9<VR@&_.sɻϜ~.Tehyw:Tkt*.Ȕ?c,tI u5g7@nMfYTΎ+I߫k 81w6qS΃!_8R&64S}h|ɱZRx kaG\Y^mHq{ KT!q|'RJdzaf7\q**W湎KM ]P6݆Cu&[$3pģ~'O|p_.> @BJghuYB ;c\:ugr.W(iA܅ kvd[:=?Ée~Iy-pK|mS̞H}q++s;\A k,;{|'Xym>L?"8}^7ŝ8,yފkI? Zn-y>2&03PPnU4cqi$--i|vf+̳Ŷ])҇ PIw5XwJJc\'Z}Jgny4CW,,,~ID ` q9i a IeY5Y X0kyi"cmKu#p ׻QIlfwl/@-BFK:o'H^8hKZڛb vIfn3b/ަu`S3{nK5IϘ&pݕcf/K:7L9^x $[\+*'[vOS'%]na'P|'gG?FI:Oú_ڶwnJ+cPl4ؗkW3;K'If\oIs#:܂a[Ho`I+ճnap>nY>F %c_$YGQ(wQ*(VnVNJ/FNqωwfvYͥ%=YW\%+|7)v98ʋͳ i3~+[3[ m[d8Ij2j8*ENxs`G\ާ<}+I%KgfwnOpEg9kNH9i%n}T@i/P_w+m;"Yl);:3Pwv_.gө8S~~vO;zKϭv;>ρ3Kyp*fgAC`2r6I| ֆ炉\s.|7c<:d*C߯A>u/]~%udq9`tWpZ1H:0,F0Uӈ[lƃWSVg2] A#Yl!ifKLXlr2H:7x̖<I;uW#iF 9f{GʤMJ0`MfV?U27옾6:su]f71{ īIk5b  J+AAL}5E^Jibe.=?,B:Fx JZ$͊]>̮Rn`<&fV7။; J-iwG{f̜5_ GN.CnhBA+鸙c fvMPH{tq> SC/%MfffvĚ,Ed\w|pPl :}qmy+>~]5n]hf\R diR3=D+"9 =S(?<];jfvMvŊ7xH6f>L"Z$-'iI8쳙PAA: v}˧ ut3{rKՋH ڡ;1A Oؕ^`_B)̤bf%eHZ̺=y'}Ec'?\Jbfݪ[1S/1ԖJpW<=r,  U:bID’J ϙ&uI ?}}%͗>(ipIy$SE9%-\G.p켒W7aUi,Aj5V_C-Iꓮ I#}}m_v}%-\2/+7GYS@;fIm/Tq~IE%R7տpq4NiiUHzޤ,`TIoɣ .8|8\R^>>͗$Oxs;VPz, {9cgTf+x Iz/~]+?wO*- Qi܍SRH ?tObfMK2oR]J*GqC hI1r\$|*yn4fv_\qd.+.Kޖ_QimwVwJzXI/駒F"ޔtH?SqJA(bhd: Wt'k*tՉg GLrz_/Ϯ,rXe/܀-K_x-1kB+T8> HdOg߳߫ӀqYR~>IO/(S:q=gcgƃ;ρ N!7/ ~2TC~~<{cx207~?\+W۶ ~v]|WO=/HwMcfuNԘ+?ӎLx\ KgCig`wٸ:Wx3:s$ӳ1Pñ}qs($L9O/ % m s+ͬp]hf[R8X(]Y||a{_z/uɝԠw{mʋSұ S̓JKk_SVJ}SEn w $͒~3'N4̃#_/XJnɵ1_\/cf Mqc`[pHyIӾ~>6}3E\I8ef7ٖIC5CVws::6׈Uz8]8[훞lgrN6''d//_6cM3_θ0?Ǽ%k;$^yi0qf%:}+Pk2#C3{߼7 :>NOfv2_HU٪kTvNo㊚\ɺ]qr%u/0rrfv]_ָbq#3$Wm\)Sd-WgU3i阵_,,Opx>}; ~~`8 {mf;56ï᛹HeGVy`%4?ŭKu΅+zf6]čfv}2 5r^]žD$- l-E>Yqy)g3/iG|4Xb-q녥%`f"_jEw* X,) 1ӹ^+1pfEY?윮Ǖݮ~ 8yU2~_F۱sJḪrpHk|mx kt͒*(v#n#ʘ?mp+@%˙١|f!s{tmV5 zFqErq|wW¾0;Iwg/mwzd&9=y(V  @7eJ3%H5_yqE@G-%ٞ4Og[J#~9v mB9dd }6wG'CY}ٶx Y]iI5R͖K#p( SO‹r"iFB1w-S:͍y'?nfU`/IW9<+ep%<NKSق\wÕ;Yg[ܶ"%h;LԽcfKZ40RoGBnȳ7*֩43{N_FLQdUv H#>w.[,gfI:WoHݵ0S<оJ`5afc_}8թ{&>"0<;n5sE3a<':obk"\  dfe鍧$)7]ƻL*)ILJk%pge;I^ g͖ lLS!LQɤ -zZz%ܤ~c|[3 7;`Md\R FkvyJYw9grW*z3p%kQfv$n n9rUvj*SL#Z90JH3l[ oM'v )9.%|`f{*e-NŕPeˎ\~ϹKwBv*\[-[q+ƒ(_+_ogPǙ>warU| :2^I`Ώ.JQtЛtP A R^. 񞛽{33;%gf={9}Kr4޿- %{TR!(rnS͐,zPAt<=B/7lW uy}q>#صdV,UI 'm$}H}%<_nD1ɞfsL;pW>E sPw9ho IDATT <!Y-߮><-nUQqe(dH4r<[t"i \SIo̳]߀ .%1ӈIT<ʑ7cr3zZfkyx` 24Abhӈ|1OE믓+G~\6ĩtn7w n~+ֺ){s76=1*{9YvPAM>󜏽LNoIW~̫'-'w;Oȕ˔K?|]p^%m%O{)Yp-~%igy%<${[ Mik]2֓VH.Ǖ6sҞ䧼 Lqɔ1IaI-@M<)I%!G}gGqM$I7>V4wIu5Eqo"t=p=9e x;k5!)^ȍrzCbu?</2@YE v6qXe(riekat-[ ^WP܅34=&8_92Y dv<4@R e{`q= OSIN ZF8"`YR0d}43ǟ:,w|XHwAyjـ9=c)[9?&~IHMu -Df7qJAʗW,\TF9 cc݊ 9IJ_Iorxƪ"Gn.wK:^.Jm3n{ƟP/=JmxK6c_Uxq/q˓yx/I)Jkc $i<8!SsSh{n?#W x痀%RE(qg&p8'9l/ T\cuQ?ᩌW+m;WL3Iix"Y* *[X~ĭ2ƳIX:ohOii&l4y$\xNóV,g{*_MƒZ\tp[*X Ǻ_s[,]G ϲEJƟg}r5dIќ5Eܞu~Y:.Vů&WI}ͬ53X_ ܂g[4c] ȳU:׏t|oF\IُpIR9*R_˧eZW6[Y/s"RZƱj4ghmw'^xI1;p^\8X#=g ~Ǖ{-۶9)=|l~<*[ZL?3:Ã~!\}[ߠ C ugx&ѹky;9Oq~'2l6n4Wdst4R٧">פ~oMe9گ]r~fno'J3+ `jl/y27fVwAI4:^fU$=ifuZ#*}C,Gx֊!֞F3޲*g1&[dO߷Y <6eVfd 96j?U/kM4M Άg`;_D,.fhQdHc4?lJ7^G;l͎Gʥ%S*d뿓~cqsˮ%|aܚfkzIvYА( J(V `d <ׂO]3{N}^I} |?2ru^'?SQ̬c8 %Klfzwi==$5 !X  I'Y[_SY&[fnD҂ٶ2 8dϦfMSԐg|Uz}FJEz% :X ?7 GG),JfmXW$]RҼ5bH!i*uʒNi]W~, 24ᒖ4{mhRU+)iHZkAf@r Y^Q+ 2&?5rf,kx@>HO?Hc?'ef}+Y$|Yc}3DK= O7{~$I"\uL,RnfZ H(V (+VECCM7=zLv@ d'IqR34xThO(*;=?2ww$+.NgRko&c̊g!Zn-iv0?6=.I \I5{Wd.bp'$-kfWD3;?=*|W N((1% 3 ALWʕreRrX\W*W.+oVWV?V|,ÁА{|EY݄n/`a7-By)ualAy­Oj."S8c:8W|5x i)˝]0OZYϮwUl+V>óEOIY֬ydf/&UN+PPűAG0 TJ7Kʱr=5hܽdM\Qu4À=M\eM.)y R'9{f9%lRk7 Gk%).]jZ$3fA,#~)黵ɍanI;J-$V|n3ۜ%_vln_I%تZktx\e84ٿ'p䟫=\(lPJ v$v\uY~WӀg܊+l7 ׻I z.pth=IkKZHPII:A}̀#AR*WʕJrV<(!tjOhUt$$P܊eNII*KN I+ BzJ^tw)II /-2_˅' ۗ]mQҸ){mg4+DX:c&ڕK:I0IT->t)vHZ8>z:ǑnMS5;8]⒖#H<{$[ mfg}O:-pbf\I{qeveO:vaқ>Ń-$YfǕvߩ k Ĭ N#fB_A4N\Y_PoL5&~pٝ<6}6Wuҽj56ˤ{Yld1_/jfooUѸ}bڗ]$f֚>Gݾu)) rW ,7p3{[6/K OV+&z, 3Gkԛ%b+iHjql!|AD `R*WƟSN}ʛA`f_j-N߫ +UR6ky  5BALUJʶibz;-0p  BALJYz=eym-P"c{  BA:re7 B7$ `Z$+AAQ*WF&>ǷM/7Z  iPAB\YwY]']'$- \ײAALb% QJ twZwND  ^"+AAQ*W.v'=Z[mo"pmAA/3  JwGRSePcվ$ `Z%,V nS*WN{ {3RMHXe  JAeJl`nt O[k˵=#UX+G|  ^$+AA(+W=ן?|#By"pmAT +AAӔʕ%Ex*(2x̞kA  e"xmAre=^TyX)*l@AAN(V )+7vk<ףEn@AANA Q*Wb7Z[nAD  D(V N)+'?bۀZ[A>ׂ4$hfvo~ 9WtY4̮Sl lfm; ffAHdHZGs6}-OIu 6q]Iُ{TX{E`63ʶBfL~~efgf7n94{ZFt.0~zPA5)+b੔9z?w@;3wwKL//_ok0Ǥ26ΐt}`ܪTض<0c/4I״(^}_!i2*ɚ56 rK$--;}-G=l<IZXR(fb8ImY&\࿳ Y5:۷.0+%eq=,_f6 ]%- `fϛٱIx`%+Aʕ!g.4ب7=+U c@r=Y%3x~{ jN22uZaZ0MQ7GZH:us?PjKz"M9&uWBR_qn%Z(Lr<ػ7,%% gefv]Pn gC >νtxJAЁR2 3Y^ijg `- <%@K&O~+iI[KZ1oI3JZ[V͕`5W*)iSI%[ ۆEIkI5d+IZ9%m$m/i I3gOrsˍ[<t_ i%-j],+F6Po9 ۇc$M_ZfOg(T~(щ̳ԩ;eO:#Ra`ZuAӢZZ\uRgQI#)a.U}Xw3KZ4}1@e]IB5Tk0?6gťjó̞ x)8i' -[ZeB݅;+#\),,h7E IDATkN٠o JʕJ*reRRrR\E\٥Tl\*WV-+ ʕ!refF`.4XSkwH Y?s: DlZU?'!syIOYIʔqxWpRJ-p1nq 𦤼p\_w׍3Ő-<*Bi KZ"3KoI:+;'U[Xm>tZ. T*ǩ$%Wt_`4)X|}xAߔ i~Pl%=\/ivIsI7zz̑[ЯLO B\i> xI1,S2 ]ӱ;F R]PңV*l%O)|ڻq $PIFH:xUI=y$+{L M+̌X xxqk =̡=1tCG_:zء +^Wg8t_W =c~?lk*ǫwAe '1c{u]eҶ'ݜ맔fŃΞʞğގJɵ:MT&6[d6W204]wx7}LNeNe}880$U &HZ 'Li#j$z99J*=JpsKwSKʶq S 9p8Ӿĕj3p yҒ;20zRBT<霾(WZ`}엾9;$}F\p+se17+dB~qpnqIO+1`\?Nߣ\pN^ij \񬸫7=PA{;j8~M},>KoorM\}*ۆ~_Z#m] rey+'~@K_ůyXn ݯjs+\#w[t/ غϯҾv]sfY<^ aϲ9CFj)&~1LaZ[\ O{r/rǥreM >re($e.4خ%==JSȳ=|?}<&y']xKeo5@/qaf!~z7&fqϘ7|t_|a?dA"Lo5%[HwݜZfJHOw'x0tSsתl𠙵o f3{ޒV+E2Vz0ow1}r׀9rVcseWRN^Tٛ>ŭm'I/_&VV}ͤ^Mã1]ApepaI4!(.YگUcXA/秲e4X.m6-r>@{sZq|Pv椤x>'__3+֒]E`fŘK7ki.@y#]o(c5|>͕}ϕb$M+c~[˥2=צ5/3bMτb%Ǥ|)X-7J-ͱ( /(+BcZ[a1n5 1,n"T㞑m }>J窔afoH&Zp`Y2Bi RXU˔hY`F@ 2skԇA^kQe͏(ՓmN,C 3Y҉3O Yz4lqRpyu WR|8?Yet'gx뫴97I]:Ѳ#]q\N^1%]W fՕ/f iPΏwL]#ic\v*~=l,p&W6+k`d0Yy!\rX3ۄ:s|p>Q*Wׂ g5s҃Bҿh.܀/>fA`ߪT~2^W_մ_Rx섍qJ,Rs-P 0>/RM34_`f:f|b3˿#R.M^%H|{p@7 o&S i٩,Kً8loJJ:g_bfgn;g7>m ,31v=6;yKp;g㱝fJlOΝe:h.5}ٱ_ڼҔ E}-`E^y͕t=\+&w5unU;ƒjFoJI] TX*W )Jʉ9i3Lvokm9D Ǵ_E5> +ir'>gv^.GL{_ S$ 2:T"fƏ~9y2I=klc)mcfb#雹V`m;SBWfv'> pS\[q_/SIiuEL9]FK&lVEˉ9kt#K+^:n28j*Ɲs CISwRRgdqPQ gl]I_b>ڏ9nx̬c]sǙWd܊_GO 7$-b?Vh >pvO4* bȤ})PkE"ErvZbf6]~/d79ц/e<`=)|~g'ϕE4PLyb=T[I%y_҆ft5%e <<5ϫITt(2B VH?}`b$m-+qJ:Toݴv=+)4 #I%Eę1Hgq%il]c8LaeliisIyn<~Nb$+oo tϥ:-3n}Qfx%WbSbG\yGRjIKϑ,eCRIC ~G㙹n A/tg9?+˳d q+:_?Lsf4gߐpᱣ4#pk%#>TIҮ*cpI`Y5\ZMUkʜ{$7SDҖӶNSty9 ސt*TY1otB1(w;Lm&z8 WGtZw;JҬqx"Iԓ[xpo݁)][%&f=a:tAWgٛ5 ҨaAMJ&}ź\;R |$]L{Λͬ KIIw?'3WfIJqU^j)Kf1_Ӛ~o%!=OcBAǻسI [qYqWE!fNzG!rx̝gs$^ce$ƕ a,Ǫ)/>KGt_Sb70Ul-a)[Ox':u<>J\J._XAH_#Oˀ!)[3ԙ W_b#=qJYͅN X w zqH+H?ЄLL6p P+h(C=kZ\x|k_LWrhZZ[A0Q*WvZrF/4+1-4ʳo͵okm!,+#qoWO-wʕ_j =JܸI}JCB2 V7V4gAR% bΠW9fpZ[>ğ^6kvAg0N\ٱntD\ 7QmZ[g *`ܬ<Io >-YnK  #ڞݍm\[k>p?0xTMA@S?3Z[~=)zX#Z[>jkm9X] \_*WY `:%eOۆvP_ HZ9pc-lD[)-p-.}?ث_m<!.tS1"x#`xz_u8|^,&``"zJu#iY`S<},f|cs\5:*٦*V#׊x:>zzv hBǴ<2NT,SrA0p)+s|wZ[u8f]5/Z>bAs濭VQF3fve/5̾kfr`O36E ZhWofYlS 3 8zi*3 !L_"5ۏ=[L+/kbf:ԕ!=ajf'{b_=L{rLKbr9W'W\I H sI MYlYD|MZ_%-)i*s޵ƹ:, X5J±lT9:X/.t}QLiMevtRg%Xm0SwVI 1U&Ih7XbQsNI.iٔYmP6VI#$ZNY\$JrS.MjʓtV|p5CH/<_tGu27\iP3Z[&YY[Jʚ=+YRrg:ސ'*kAz *B+E*%]#VPq RE -&).l/K88xOnHEex̌?Jw&vO>I#%d92m21pc'`IoI@yI'yZ%m$<^Sn`3{ P-폀sӾgX+I: %AY_#i$/)X}4)r|_pI^Ύ}n.RK:~J{ΜŃž$lN&į|{HZ[sz:_gsnt\Hu:ETI⊵ E:H89Sҡ 96^ż:_gXQ!π :;Ω|~ki^tn3I7kra߁%)\IHBҷӽe` IGn/sZ.muH*ssIO4Md꧴[*WVăO~#KwZ[ɧAt$e:f75$I?Q 8̮JeK0m$?.է'm|ѷZ8]7y;3Jw<0E,;KZ'vLM$-pEؒfN*&,V1m-ÿB󙁛J=+Undڮ$fZs:ruV`fY}TÕjfGf\2} n,KuwrS?!GK7y`0̎/uuPwe)pp}np eS3GP\_ -iq&XY6clߩ^[Ro/i$=9-uuMcqHRa\5Ν8\LFv2nفf73_(4cc`aܒ$kۧN{3gJɸ&sI9ϼ3ylfʖ]b--4Sfv%? o!-`Isn>OAt’Ə7qeW޺xFΧs8)@Gd3̶27uPܮM1< n )mUNdu:<W<.wfBO\(i^ v*Jp뱱|}̶[hH4sk.YFjAX8=,EX-DP%QD@ Ab$AQA" Y$X* J dQI%vǭa{{'tT>t׭{f{v<|r [b`t/S»Iӣ_b 6PlSX5ҾBo2ӎW~ df+VBU?#P*wifVAZTxN=ٞdZ_+$g77~of[+IzR{¥ݒ|f*\֛NU;X'6pxoE/"7#laxksWgbf/oAqH[Fϒ> |adF6 >v?[W6ٞw_m܇ہi]]m˘%ը:Y: M.0ڎ9>E|BV~vیv1}KYg!x}Nm3:S+T"$Zu)ҳ`\}ۻKYTlIYP :8Ƶo}e=:ظjoaZqEEͣ碟6@Oz1QqF>#Ԋi5kv'Z/-q%܌?[Vv*S s~.{o_Bͬuxa>~ ZdPbeʳd a%6 V<X̶koN7}^"¶1-3g3с $\^ofG[h"N+h5Bו֯Yp1I e΄co}r `-H&.V3j/,V]N-rRq_Oߏzf} PtG3[؝K9Q՛I= 1-&g.R{ 3;]Jof~- 1?{[>kF6 {Pİڴ KX?3;v1o(~?Lxɍw') AD *u1{}칿ڞD;?efvIMw6E>w}̾hkۓE W&$lmE q3n6~(&Vly3ۦel~,y^ u`(N˶p.ũ/:б-AFZԏICJoi kf0ݿV#\lEXj 3M0}qf؈Bb[`wwbxwL̖_#t[92Ӌ?SCX*ݽIZ'efٿl a Å =+&F-BX&+a„ֶ \[ķr1}}-}a509넺1Ŷ+.%t9Oo\mNS^hv j1_F޿7c-^ؾїɺQt*V@|ÄzH(mP|f:^ I# iN{i73=l3;PDxQ3;&V|.2=+Vpo|ffeBB BBbC`{ !y 9 B{lPu3;̖h~\CHxNh}a .--ߘн_LioF8Bª;-l:i3ۯH^l' 1yF=g?fvaf[dfͬg%{ _!-_v_#$[c dx^ m^*Rdb"?k 1|{k5L +w|7tq tl7-,D)Q~BCVWfXT|zZf71cljW6>G"b|ۅ`78@Jo 9{+xZUӊ3=RibZi?Wr=!:H._ՕX!+ ?E[P`Cn#1b% lgG%"utuB}q[x XOj7g } ֓Xq%N;[8 $YYwT8DIQi-Κ"ŠFXrMl}Bu[DuXYxw*McJ2Ï0"ϒɕۭⴷ"=Τfh]FsZ郙nf"-`f nL1Cf vՑXB(ԣJO>Y4%.\i*"248()`aE;WfEWߡ:.ϒڍʨ߆; jIc%~lFt62mdp,yXS48`J&GWuXpMpAw3y<|5W $"tS`C^ɳ䭆B6 $VE-1wք+/SǼ2"iB2NtEq: 8䰽,yx;X#-*:("""=Z1`0%G mR3;TcY!Rac_DqfDq:8Xİ,9{L m@""""]@ ff3ۯŀMwq~G%wl,eJDzq8ht~myµ""""]|jc%\?|-PS 2%$[z <6Y}Aɳ(଒V.(?H~L.q,9`{EP}SNJy9ZBkOfoQY^%l @,"(N?Qbㄕ2XĊHtbq3[9m |xX2'-3GH<9,2mlG`ʳd*5CT*[&$;1 1ϒ5t!Rtせ I&l:P``3[ݟUeB3[8،/HnrYA%Fq&`COy{+2xPwt%l(^kތՒXq_|* of~]qӀ́xNn+ |p2,5t&8CP8eP̖#XyDDDD7utzz5;_˼.=ƚ83. UW,9HK;-՛Gdt.mz-ϒ2d3` O*aJlf 3[j+""""WV `7SO,i>l ẃۄD9(^=(׆ #2 ,S,y`;}B] nDDDDdf~!ty'$9ZC#~`ks@ B5f8,#ϒ78ݜ\3YFlE%\G"U rJDDDDzSrW_:+g>W3[89gydQnE󤧘m"b 9͚f]/{m+?EDDDN- lCHbA؎36xӓ/u;u9ɳ(N\g8G%4u}γ\D›""""e*wAf棘sOsgsj,99Uw(Nɳ䖦I8] دĐ4?=[V/tZ׺ǽ2w>~D72'ۀ+'?fvdQ0WoO%W1[Bsϝ} m`[x8kH+h}<[x.Y3fk]K~p;0;pb5 B%o.1f1-qykf+/DNrl-&Owku'3˳(NW\+S8'ϒ KdXcv @m?|9zspmq>`8]%ϒ' KdDq'YrwCለk+Pl}3%f`sׇcYIbQ1[%88vl, 2Xiט٭g ~Ps`;w j2˖Ҡ:qE5lU3m~_% UbG lEFc;5}{w_rKo0[=[!T݊rl~LD"NXQՉEDDDDD@ʍ~OLq?ɎwOUc{o|alq#1+_J?paGF(N'BuआĊI"4p 3;J4;J,y J [PvfQ8`g+k.|痢] if f3ffl>[Ю}[SC%OٖiA'D$#] niyP8"""""2BՕX`2p"-wt9f3m X 'Q9Yw`öM##WіL)""""""3+2phQ@iKX`=f=ywefcl^3%pvϙj^{'">yqqLl"]/YRSUWbſіX!,dW8J2^wW&?l{5LǟQ.P<2DqsSYۦjwVvN-'vSZt 54 _\qb[ pis7Qu8E`"Ċ,< jf)a%@D{rX)cS#u}1fF9Y?`s̪ [dֵ7Pw7,y`DDDDDdk y˄Z*[;j_qHw:P?c_Fqf%6t(N6-1znH' taB&k< x x=L#$r2BGg1mwgTBGJ 2ӉD%"K r[DDDDDdVgWk2OW<_q}bq['{K/,byu%V.2즶۝;*vű?8NFUbgS=H%HJ'Vq3[S>df괼BōV_vN,y+-+GYBN!$:uP1JDDDDDdjKt`MB*=hfߩ0by\l\bQQgɉ &%ImK aH-J[cff3=hfٓf2p$O).n8؊d˳ `#BA2~IJtQBҵS/Gt (`YB'wKV, /[+{rwSz{4 ls3Ml|1_, (~ ,TYhSȬTӄJNf4 Ǹ5͉m<\ l lf*6*ʳogBJ (Nw"$:uy%4̺JݯtWMwXe2 ef4f<`E;]*cIfo]sgE*2 8]8ĐݠDDDDDDjWKb/k~[2Eqikcfs8By_a+C(9 m;w%iU׊~elNHc0'*Sre X ,$+"""""RI-lw`=Br6d.w9 Uzޅa+PBŧu)X%鎄Ŗ%0SԊ9Q XbS #"""""ԔXV N[bXk`p_(gQn[|JKb%6H+(nn{e1wpKlK3h{E\I)H#Jt(N!$Jg/1ak_Y&D]-N:1`%L2jStre1(N7+U uU tlKcHDDDDD3u%Vv6Sl3la3 b\m>;u- l>¼")V#w+mQngꍮ{Eq:?p50,DDDDDDJ-o_9_3s_Vxۍ>>WaKyU$Wf/9|(N[\8] xɡYBĊmBh){_ofsu ԧk%b1 r71H)y< X+9|,pN֭AQ. \Tr蟀HDDDDDZך3-U`)wH¶chɜf*sTU] *b(Nw/PTI;,yDDDDDDkS3±@HǞ]ew~_D84!Q4lEWRiJ%DqarN1?p^[j,y9ӛ)_`A(NȳCl\ UrFyDDDDDDQ׊{ySn>4j}1wp.p\ܶ&$]tQ&.ϒ i6qEW(N~Iʛ*H}J|3X1́_]ZcXt`߶c~^|"gmQVYӸ(N'Wb-+,tZ+;;SR9fv'CuWxP''1fe17jWZ[Fn֫05`.d\]VefSw,p~IPSKyLͳ `cAnik(NtAXQ8 i x ϒkLDDDDD9%V*w_Ѝgw+uu*$\} !?rW.yx3nij"p$htّ(Ng`^BQ*˳oE&"""""ҼFV; أy#m 3[0'w-g NQjAr Mw]g]E !~-}vɳ䕚'"""""2*'Vl0'pfoi*:5_3끓lwśy6?SBr,T3XSC,9fUf.B2`{{l>JH 6hKp}{ByEgɋy|x/sHuyHI-J'Vz-z總[ہOmy73"ϒG,Xp3HWYrp""""""R*+VV~ Lt Ylm38D~=!$0+R *[f,ض.Qx+]aNN7OꦴOs+2 ȳ$R t"׆ Op`yfh#^%3yRN,&.o5)"&{}o;ߒRf.- `ifsHͶ ^>̼|Nmy2"rf~$IbƊ&(BRʈs1WGREħ{sA1vX?X9@byfO\ \GفLs)n8ΈuD<ť灷qO);_ED45sS"SS_7FћMI$I1(=̼.3EUtd.m`vfQf.YG?|j>P/5t,%`3[m{,?̻3 a 9E"J|te i%Ag3ifE~ `]y> pum ($I$I#&݄߫:; 83|(3Bɰ)"vd\,j̵zyb]V4EmCd>P5g7nDY^pf>OrvfYBsyc=;"xz>$I$iXcE~~35"KD'ydqVcvn0%vkf^q)Eonغ4:5[6w4ǽg{SjЬ,v#p)<͝~5`,-#I$I&\GADlMr8- =c.9)~ ]X]rtGDAsIDܕe NOsN05"\y(37)3_)?hMfu~$I$i$HZDLߥdHDdic5omf>=H t%{ds`i01 촑>x ؂+Oӛ!uz>H%I${V4DĤx}=ߚ `Jݑ/$׶'M̩2aŞ˭<lziη~_S,]D\@Y̼qz>zE~ub$I$i0t^\y}?ꘇ3׵y1ϸu ̼8O|?f W%3VP2Sv>N 읙 8N}}t^1gK$IҨ3nJ ԝwZ(cw}N@e;V6"b9'3h6M`j{FD,؈X* ".23?fiyFj dO)Kۄ $I$ ;+^8lʮWoխ3"b FGĔ8fw]On̫;홹XZ/VF1/"_c QJf̬db'P>1E,"Ԉ89"݀?ˀE!ODƺĈX/k%",+˨՝ Yߝ$I$i$XѸ{6#biD\GW#ʖ{77_VF(uA)m^WS2*3#bcnJ&̩=z%09rppmI- {Dcmc,1?"ǁ `ED,3%L>NfssA)j#`UDoͥH6 f5%[e58ܨ(:YDLAdI$IҰ[Z#2Mט=Ҏ.9H%psf.fw/i7S#?οױGD,xy[W2A'eR"3W]cNb`ǢEz%e_`ppIfnetḐ~@>٦̤|S/;d暈 .ZKpV2~ga&JR2ΤӸ^9Kղ>]Q$I4XWD̥dkM̼a4'MV$I^\ $|K Z($I$i0")U;.Tkl;Z$IbXO@Ҹu `WqvPZD$I+z̧#--ONk^G |432$Ijs#S3yff* fm)ndgqܖ]wGϻ[vmXUWaEP*62H܊^nz kYV겯tiV(t\q2faּX?mtgh{Q5˴sF,#D ;c e=q[6vq$&|xuE;PEZJU WnqN[I˨A\e@Ca,)M' QfU?G Y<Xo;5J{h+q3iNC@V[CH_L nú-HKA7UŬ`l}&+ց4֧\6O 1Dܾ]!3Lr VDdl5S&䦽VQdҰ죚}3y͕xQ/<DO#x$0Q&WNcTkd|- {ƒH[``y{ܯC#4‰! |:Ů -Q4(\rnKyUI;iӣޭ̌~""qw'iOh6❂6p_Ta#V-c*tHis!U1~]@ 1"@|DiF^ٙi2 J3UɹTe11Zb:׀)BVoRQO ςF#ݾp%_c /rr V}/8Ͼf'ڦR7 ^Q$7ad^ Կ(Zg1  .=}xO3>h?&_ sg ӫFydد7oWg=d x: &&,%4[?.?` I2eI]b*C!bitɐ bIQR&KVaꄖ>RoeVٗQVYfSvc/߰7,LXY!IP<~Y2vtw5eW/["d6x9v/qUI5L3JP w>]Gǽ;ɾDb''T$Y4#VA7_;ftmSLP | : yLl5 q@cC=ِ@kas/9&pdhS`|)SD&MnU6GdyԺwKKz&%N3N_Wc^`?d6f<\*)UԿy㐳r3_0B2,su]PncC;t@s-r!d%poψIDIa:Z[3)Hy̱gz՜dTRěd\ I6{H'v+W\rL/PShP%$UOt#HvClUQ%, :P_W1+JR xr'L9T^5T4)(Kf9оC9&#f|=rw-23S,p%榵3W.~BkVas/IPr\"8*wvT"?`iL}|>YwA׫ [O,!0ﰿ<ʜ,Ju(fo|d.glglT^ #Gӻ>k8F!RC2ԩ@8"|¢m>8v*=0;9zL-5{mc.fe|<wh~fl{D JpX-.,&T UEp*?d*R Rh |$eºLXח 2a^&˄LX +︺$,e ftC{B7I74odMJ'2曡O*}h3PK͏H"PKH:ccmeta.xml OpenOffice.org/3.0$Linux OpenOffice.org_project/300m21$Build-9319Unknown2007-07-19T15:04:032009-06-08T19:10:165PT00H02M32SBarth NetterfieldPKH:Thumbnails/thumbnail.pngzS@w;|xWitիׯP~y&08ON Le&#~2*|cPƈr&96|G~s-55ԑҖO9㢷+k+o'n/7]]~ߊ⿓HLqB^S'זD~zc+._$>@|A>|q!1"za A3 &o`YUy%7#tPiv_"Q6^.w.hI )KNL2;xk/2oSH {VX} ;~.Ξ'/r +M~PQeLʃ+wFa .E-7O |.2]r ϱw׃% f#xbB\n^F$E:I(Hof;8;:8!79 ?h$IkYq%%,=:nD,uNky3k7n 1# am\2<pץLx*q Aj Ӻl+5"nݎВvWI/n_|zJ]S6`+ 6#Jv5C◩t;s kU lfxak[<4YO#}@!$aN]A|nʖk wṞg8増].mH̒3EiA1G\(W8&V$VHq)탔J?9vzHaGq?]u>4++D,NLXڞRc=0!³ԬhvXxS>WJ9'/@Y5-1'Z˾Xw*O>EЙncprtsLq}GcGۈ/b"#,Na3ۏ̷4ʌ01VCλ;.Ɵ^>2 )K=[?Q ^N'M] spuM>{vzWJ87X*Z̰e8/B4 os)A#%\E6eSnyg*vT/Z5nGYWW U r\DV_W} scI7SN&ҡ),t!}=Q΂/7ps[ǠǀUv cox:F2[I4aRZ;" b-BݗCZo( 5״oh,1a),wE\D/;S %|r&՟ ^ΪGy/\P0͉p]V1X<5vg!=fjE!%0qK*=x:zSZR\xk/6ma&D!J3& 1gk A: ]QKGر)swɧ!6]@ Vܰ|<.Rmcq'¯l8/OE "?.dtXˠ|"n롮oDț-Xˇ頀Kq~O=覢H&/g)I/uQCgTǴj!U:|滫N}UsOAX&/^s wC={[hBoΕuE `6[])+V[?k|/jaɲNNڿ?H ]D͎w<|y5p?Q^-ߊ8gN*=P^b_jQF{dߏ v跐v ƂϾg[xMuDmwĦ5_~[*lÛ#}dcΫ&QO]vUŦDf,Js\.h"+0IkJ %j{$4s/&_dֽ[EOAu6!IVf 1dABٜi_ 6$̻V+-"C<%!MB#'JuŬLb'+A)(R[CzvaG :#qgUʹ7 =FJ9[@k'gv;=DŽCfO <2@'SPX:lDǢj)cp3~i&[脅D2'L=Ķ}3 kMz(g$Lp;31xE2CVG~V R3im-S=\IYZVBM60\&qK5-([ |&ωt`R&҅fYDZ.[k 7#x˧]HC;vt\ vXbS^`4R.YkE"\a/nETx);9Emq_=3޵+@0t:i8׀KOuPw`@}>N^5& aU0x|f"\?lr\DT_rY4kE|ԞsZkMm~xn8FBͦ_DZwơ]skO #VAl媰} pdr?ge=$V*ϑmV<+Eu؛Ѭ{J,,E?_Ԓs)uϽbN#э K_H~GW|*s'OW'AUF C Cm U / 17{9Onsm~ fNMZ~?9]B"[\AjEƕ~{T4}Ob;#~J\kcA8/*9_XчOGd0{m߳C%>OG[sDlH;u>)g>e6mYp0 #(H%GpʝRE'8d Uf h1kELAr+jHw'e3}q<睛i8mr,g}x1o8X;OcXϜ ٗ>Čt~|o'SVX]h0{A Q5A1y-Yp3bDk;p]bӪ >6dIUQ6)e8av@=x0g4Tie ؆JY1 Cl uXoJ.x2h3."'-$LXd1b:͸/"bl-/_QZ:͌s g&ť\T Qܘyo2Q۽6(!@[]h4T5y}C 2. ;wʨyxQRgbnʒ3hLa8Q?-M2 )h8',<; $i*OJ'obd啠p4+k)- mk$a#ϯg.HŮGXؙ)((_ F6Tp8"vݜ*<ث ŝUfwv4exz'#0J:4m+Ah<kC%XBGY., gs̨Ew:3J(KAblFK|E'{UIE?վ٠\ 蓥X_.`5C5xwr˵,p(~SS^ibmE%pMy &&?rhi]a`cT}j88>E0" M|Y $ -7 ; m ,Ɵ@vm|{u ?﬒ .{4;H. B $ilb?FƵ5ODElǼNT;qkpֶ3 ɶJ,v,xEׁ>߇U0$ꗯ/CqE[l@%jC -ol~l;u D|dqrޏ "gꑘ)')[bvΎ)ЇtQ7,Ud~0bEGda!&pa–s̈T(cj"tbgy愺Ƙ&/pyb#W.kp}wW?CgC9{՞(Is}'={ z}Jo%{%jL+懳֨%Ym}uT–c/{lm?c}@]=B4OMkD@Vuii T]iSì05jg zi7`GcC|$Z .)xEY|r(+ӺQ|}[VQi3F&ܯd ϛſ9KY.1pvaR8E+em[^(ye멡ﹱ[醼8\mZ}uwZjFn(n.+waLl|T i LC;΢Lv,1;T|rY ]e6K=i0i*>N޽ntWx$ ?үAV%_e-2RC'FL2đ4q >~"#ݜyY50[hSM/u ذhV%@P{7#z[%5E &*IC BBo^a sbL$vp?bn)!_>/axyK1nMA̦7h<^K2fEɪ} s Å uar3l#aVc.Dmh++0Kt^ vG4A6TaW[ /qSGcQk?˧F;orOkbl^vdr5i54*dr,z嗌U8?^:Ћ7#/zl,X~ƤiѪOl.e(BZ"ΒǴ^쵥U3g=*CsP'TrSwo ؖ^t>/+T Jo0Uï.ᩜ];,?_[qRgc -Lʵ??eC{QR-XPy e4E0DF)S;c.`݂.! cI)C,%PT(b\H^?|8)qo̷~L :{A7duo~T':3/6۰i^`^bdQd=;Deݮ(9z98}cYW3ADq⫬t`s274;m@\PƲXp{'wVBASs(G.lۖYd w]w ,B}eeҔ<]RUT:6עK70옥mg9?tSҮe..Ϡ㮉IϜ3!e9?||g&8FBm{<*+Ty|wpSL)A:v:f{,Jm|ݲz a^H 'OpjD%SBGQO*b)<&ܐFwI%2$3-`^H^Vu#h5bf5h0%+ EO{ _|W'o:\ 뻒WzeX%f[oىVrU{S1!ʌ]K, lBYjIU,߱H|{J;{gJ0m 2jvc@-) 3rU_w48J\"o`{Io0YfwWkNg'(j Ը~ɑkF&Ȋh0vvfXiJ$K@p>˗FeY"J~聾huIe N`A2S) E^Cj'e؟6$&$ +T#|C뙺1a)躍](*KfgrcD2 Cs!'D^l*0vDO{jB# {5Pyr#FdF2:~^O5 (j`?2mn M!?f4 /)zi>pBɬ o=u[/ko뽙SԀVs(S"hFT!tsP#uР?t0IgHS+L2ZV|EYi&'oaZiߚ!#X scOǸ컴ЙgVÔoY~+x܁LqePR\3$lajP!W6:g,eBIFHGAX 5QNHwd:e#wW3]P I{o˨H4 PKruA(]+PKH: settings.xmlY[s:~?"i`:40@9}:Iﻒ!I)H|޾v}qgP c.gq:SA3(K@S #^߾ 2%4MM51yS_Y .n1iV[,gwgfFQsw7F(|vתE}!?SvQ_!_"hm1uVr=m@*/^ |1 6w*;\ոn\v.SS$^N#ͼHr>~ո:Nh!ĔcЙ39`(ɠ5eBqJe[BW KOa 񮳊3̽CV>:67hd.}CS)GD@l'xHl;s͍#s'b2&Q6GUzl]UIo#>UVջ~Ƞ*>y ]E8zxx?/dX80ƌyʎ{ *%%c@hl`) lCu]GDekzD13EMr%)Ij%=˕6dSKs/}"l$U-KDFd/8AwuHRAWgŀlVa CtJpWKF 0q^EYbe(ޡL2W$%`:@Rs|t:~5!~Tꊕk>ɔ0٤hGhkxI ]Ή aŁb\yf74Lbݗ*xPl\jݻe)!Ԟ5!n KHKr+Հ&/_y#nEk=6)1u 4#CzIԏM$@5-4FY&Gsj*ꔈ/-Q-%p:h0~?4'L| L>]ٲя̿21V=;<Vr)6 ~k-|'̞*(2{2}*iAEO3ܻM:uwKsLndKK~B0*ޭk;k>~PKr PKH:META-INF/manifest.xmlr @ w ɍ%Gc9490^ ``D_&z:5{ Z^&`Ъ!E[<=^],{D J)l W+փڀj{PXڿMn4tCrV aH8f{W6Ud/H'M^^05zR )ߵjE>67za6qBS[ʽFwER3Hp7!3|$՝KG2\Go̸ٿo#ΫɼTo1(߇LG2yxf/VT"_e9+o2_z^77w,P`p/٠=0:G!Cs߹ hz~[l1wa1ܤޗvIH~PKDa PKH:^2 ''mimetypePKH:MConfigurations2/statusbar/PKH:'Configurations2/accelerator/current.xmlPKH:Configurations2/floater/PKH:Configurations2/popupmenu/PKH:JConfigurations2/progressbar/PKH:Configurations2/menubar/PKH:Configurations2/toolbar/PKH:Configurations2/images/Bitmaps/PKH:]--Pictures/1000020100000481000004573171E9D8.pngPKH: =X)X)-Pictures/1000020100000477000004626EB760F8.pngPKH:{.ʫqq-Pictures/10000201000004560000045AAD14F665.pngPKH:0(b,? > layout-cachePKH:*("gO" > content.xmlPKH:͏H" G styles.xmlPKH:ccO meta.xmlPKH:ruA(]+S Thumbnails/thumbnail.pngPKH:r | settings.xmlPKH:Da  META-INF/manifest.xmlPK9 kst-2.0.3/devel-docs/Kst2Specs/src/PlotResize.svg000644 001750 001750 00000036667 11544160206 022170 0ustar00synthsynth000000 000000 image/svg+xml ViewObject points inside the plotrect are placedrelative to theplot rect. Plot Rect Outer Box Bottom Axis Label region Some projectionsmay put axis lines and labels inside the Plot Rect -10.0 10.0 0.0 Top Axis Label region Right Axis Label region Left Axis Label region Plot Resize Behavior kst-2.0.3/devel-docs/Kst2Specs/src/Fonts.odt000644 001750 001750 00000057331 11544160206 021137 0ustar00synthsynth000000 000000 PKl4<^2 ''mimetypeapplication/vnd.oasis.opendocument.textPKl4< content.xmlr۸_v6(w7VfLf3fb7Dbeз/9I֍*MI=q&)ͥ8^0ʈy篗o΋8!;dL/oBNę3ASLx&3&J:V&-p۰at؞cGN"#,˶7:b VO3j-)n.;cc3ߟL&~Wv8\%* }0d%l m+Ey:dis^ףq=ZbpLUذMGݻqSjK|r⿇MY,-/m*TQ0UW4 +t.cU!+`-%.1K Іe:abT2Lܾ`(]KCD˫N*8Kʰ,)4Ay-2;a7JoڑC(M֍Az\jZy1 0у箄T]$_x:5(S*/@A(SL;u5_Ai:ҵ5d. UK6אyɍ6є|b CTEҤID 5U{:!_/SN.Ke|e{IOa6B]ұ4'N-wYR47гtl?~*^Uth6.7`gH{UQ/"NIB2(Lt&)/`&3ÙqGjJX:0A?3 Ue8$F Z?ʵ 1AQW͆yH@g֦J%ھZ,@wVށy~n|kzvr< :4BĺCmFrZay+,ʄ58;wHD6b9?wheJUjk+EN>_[ N]s}nJk,p=~v͒0Ofu{\%ӥptD;?+׸׼exodb]? r%tHb׼篲Կg;c;=}3߯Mtti~Bm:z tr[M'v'oϹPcκvѽwntvڍ}7FhwC^Q)"Si ;agf%S/bD i{͂Eg,SO&yOK:{M\Eٲ@| b;*D^DgN^hl>?wo ^K6\?[rPxwXhG4s z[CXID4dH&Ʒ2I1#Q$2T2R )@ TLɄNlGS{tȅ $Ұ%]Ϻ-VNbFdB^/nƌ÷xtdprxth upoB34Ak lo=fq/}rd#QFb#c8nxaB5Kw#K8*jV{73&@/?G$j Ө\@K>3k'uS5K,Zÿla%1 %$tv?͍ SG* Eel@*F5*|-n6#Yu:;٠gQ܀'Y]B(K||2- Vlmq4AaB5)ۤtC➫ Gg7뱒9Z詩\ 1ʺ- DŽ;y*1"IpMK.1 3KgS <3q+m1Zhu۪-S S5c*Z2E4fRO^Ʉ|ȇ s+dZ[@TӯRPJw$slb!׺0p,+Z5ֻ;zG .ܬ;@T&9;-j{b-rE4BP \YA3AjjU;3Xtͼ5:EX+NL1J e}yih{ŠSkؓGUj-]YBɉ"+DjR ~N+['w;=9 o:7گ2*g]=jg7?*1:ϑGLoPKS_ LPKl4< styles.xml\͎6S f=Ȗ?' !3ғ\Zmf$Q v;/}}IQlVD9$1Ub#ۮw>f'4(=4!jxиp..)|sd"N,G3hs#4gj*=W̶mɢE-0+,y!~iAL ccJs-D17hs5l5XQk㚯(YxS,'h okMlY V?zgê#4޹{_ޫĖ͐Xwտ>%y[)zmyJimT; ÷cd0"01J:4s 1pAfNc DmȲLY%N>R)5NKo|*tVqM%]RK q߿;giHEɽir#z7;#vsUS^oM-5N5ayb{ȲesךD +$!jqDİk#3{;Q;mx.lRL6-8;ŨOh ~9̩ >TոF+/QVhLZ1TIsP0L<$5J&q(ݧV8kJ5w&vB1wץ P lXo VZ _ T@idP)$jVz e`7X\c-5wyJVܝ{Yn!oke[o5OQ"Q)F=Q@e.?(Kj?  #CXr$4Dm#a?,Ci2F sc(vvVzMr."r6UjcJ; &BX1gQsJ*?KZ} >sw%4$_LV{LE;,M)?P*r*Ѳ!%,XZF`}imѠ8[~iR+!*T_-WĴۏؼoPE <58f>KxMّ%j3=!z;7^Y]NlUT}Q׊]Bs2 x\/$3[mC5cO[&OE UP }ƫm:o]Ug8m=F f]Nn^YӬiuMmpL8f$kYO aϼviOjXD 6=,걜:Ë|Y IweѤʧ3 |3oLtIO6bܜיr{^_._䒞LɅK<7E~.ۉ#&/#er` c0zNq5 iŀ/|1]!𧑯8 /ŀ,d1 gD_=]h4] b@ŀ.t2.\a+ ͳ(GMR؝>h=|0> K"b/ɪdWŲnH1G5CW l;EڿlG jf jXƭIULnL n2fCnbHqckEtu 6!ᩴ4aF*cs5e3It2u[ZPdM:[L;?W*]F~Hf:v:YAeArS&1v-4Ӓvݺ[$:jSD,Χ37c)ڴ8.:6$È^_z5ebv:%=\+hYc$[LcFkp_QkU2klՠJݟ6[IiW?PK)F [PKl4 OpenOffice.org/3.1$Unix OpenOffice.org_project/310m21$Build-9319Barth Netterfield2007-07-31T10:14:462010-01-19T22:59:25en-US7PT00H37M17SBarth NetterfieldUniversity of TorontoPKl4<Thumbnails/thumbnail.pngeP\6Cpwwww w KpwwwM[Sw/鵞~V2```r_AM```p0 500>39IoY7CW||ArhR!_(xȎ!:%Ĝa \7>Rׄ87mNҗ|Ե_56n^_^h`x 5CVZUaqe./JJ QcV{?7m {(|]h_H9݋1$t,]ߎ)q^/x1 >Kaw<~,)r2۶G]6XoTW~]BAdt,z& i/ΰogx kdxP ;Nc'o&M Qt^IEFs8Xu:ۚYM'?7hj\]sC~"5p8bl}a ìW;$#ts<&*ӝ7);Q@=LGdo5//+Fphl?k&p[wQN?,h ^zT+ \4>9{E,hUt-h2 sڷMsgh me$ghT"d ͈!N `P$E䬲oe:Ms FlgY8F q|*h3vsj_QEX9g$MZ$4)g|6$}M|b[U! B sb]7&v>`߈,8ldҀ¦ nn]Yd1v=Fo{A][c}0ªA!*ҷu}K$V{[lOzAPT퀂Y<#=|ŽizDtt 6H?[~~= =*߱  hZAM˻}"#v鋠`ۮrxÇtJ/ސ3܁E. R՛Xz^gU-B,i~O@taDK-;Q62e(C74(j5oqÉFxBd H_,uE*7VE?컞y5?Aa@P˅_+qzt9o{ ˪n6"‰{u=Cx"rN B}q^U(۸&[\M5>U.*muy~ ,h b#5uwdRcZS@I[I<|2ȉJSu';(~! m֕7M6y^l=E>7SWoQ=l 30ġs*"DСW?O\kB>PʜP|"%&?1]lW(kt6K%yFK3f~G{'WQȖ<󰣦i/7Rp.¨,G<|W;/Y4@/:72Zko0MўeSC H>y}pDvPN{Ámٷxho5yj)Fe40 v7~dlwi~1@_,|5cXwn3G1ʙx"IB};xx$/@Z4ҕp#H+x)Ε'haDƒڽmp  U_g O:( QF.;Ǘz~jܾHZ7&Lp}k7ȉ  n=J`> % 5 wqI,"vH&}+"%W4є tS@Vgߚ Wꢞmnsz߾# ߳6nNmeF\;-"}PħpqؓZw>>G 02 [uK[&?7Wu$F+6Nj?QBѾcQw& ['u9(:x)~ECHd:-W),Xxw{37L<쮇lO.4_jމϿUZ02 ja@2d Dg"x^C"k!fv]Lٞ阝Gз$:( 'Ō~:Ħtڀ=$méW^v8x x8 Tp|2sc$ F(x!ͼ1B%\GnWīKR\$tD qGm+t >,н䢶pPaaBL2χ:qjt?I)$g6kC ƈ=6rh22|  &Tć\r$ք!@EYn0 ǔ+ =?{+p& x}'~nJsL78;vuhЖhpC5С9k׮x+b[LAoZrҊho*ޑ qj >RgmpBAGRG#bs^%{|ՠsSj=@w;<XXխ>0  ,VBtIWʹyNԐiQe*p_&_OI8IuMP.򕒦HByB̢7(/aJ9KY4B~n v쮖l\~_][&NFjDD~܊|uGJ4û'ֶAf2u{N~>pZ2_" =RVǓ  |qaHjyE !pcX?'|>Yo dz 5^zj.qS~A &AYd&%)kǢTڡdnfeC 5 V/pс^aH\FF?bfn\>7dgiV+ 7Wv$2䦴[.EbaF8Q0mGN C>׎kI7h&|$t_b2^*:#GV0?)~4e$߈xp11}]ϏW1Oi!kf}Y)o,.4b]@S -xC=ڈw˫} u-K-Cq&z?Bf;.Ϡn,ߢzkH7t^w^e6jjԩhJkBp9FAB(i<RCi;.y0&/gV⦸5 ؈@Tdyà$ 2gC ;D`?Y OU(%1 ptt nQF@&A鏑D?܉td(Jُu4ejlQz{P9|Mf= &rnEuZ nlt}T-Y M]Z29͖@E8[~j,ՀvH %BFZPW Cumtk$RBo[S$mv9d4/>y$I*^M/ cض g(/ᗕΕcrcrA*%,EG#,-Sz5Eo vg-܈):'\ᑫ˶)v*CE xJ*+OqS4'30)Vj!y hp6/$8OaUNB3Qjv$VjF6<ԧdXeaAd^PZ#"ބt A*"e?L>D}D=T8pB#aF:FV3c_9lTѶ*7$yE<@_͋,|.?'"pЌ1s i|j2-DCacAI5dHH.Aڄm $r׻?#%}ɷr2 ()VzʽV@wH7 ?Ǵitg2qةܶuYFD85eS9NH<x=lM4s8h Q̲tO32$DB!m@+"):窘dvf:0`["0&fXm BPiCMN'/n륧P8{W~܎Y8J$V1074:o^!jrLIJ%*&38~aY-CМb>nsGw) "SlwBJru|9 x0=waJ_]$V@Z#˜C`7a ?ҁ<ϲ)e+#w*C?0ƕt1߰3ney4l h"^U)%7/ SFeƹ5g2ٝɚ?J$%{n`ΔI7}I?lSo"(uL2%YeNT ޟM97 +QROདྷͷK߫|GlTnK8ft^Qڴ#0"&.nT.PM2.<)*^F;\& & oРyO )XwD\?{[ qpXpRFIh>"%ݬm7{d6ZKX2V (0h% `"+Wɖћ/j}O@-L B'tvYn>\X(s6o^YnSZqMŏ:byޮ"|(9ݳq {-l5ƷI[S*xMr!/hJ5Z8rP5+q 64fHL`~)A`?[Dإ]N)s){/6}(\Eٳ/Ls6erWp*y`% 8 ֒-W1GM`~$*ڤ*]u_mpWN潟W7HųЈYJnX[DH0lP| FD3#!{l P Yz{@.W|=Zj&Ө. pyI& ȥ fD !ɿN,5Gs|sW;HxZSnjGCde֚Nx<3\|ߝ[ixΉggho Rz+b~&̝}*⫢Seu 7YaabG 1#V8}e9ܷ" Hړ6gw@yd5Fˌ }ƍMw#7E¦{NєbbD5D32n,SPtW*hbK!K&n?z`kQ]O2ScFVr-~;Uuʣ2[bj<VRw NAFTQ$H~? 6͘-teZZo%EÔaj@*5?0h =GN;>Ɲ|?0,Ш|dyY`B+Y <ݖ4ԘԧU/Tij)k;Noۛ;l-4(>_.^ST=חEenmv@.,(Sv)@~kU![DRH/Ƿ@bp63!Sb-_OKbrOJйi*oBdB%g~ $*u )B;=c@>Yt.wtl7{>\laݶS(dHm%Wə9h(3V)h. ӹ:9Uڠ.gc>/>p1g/<$m x?]kƒ^w] r{D Q.Ozpߪ}Zbb}5)@j&tH@%!ƂF "rr`{AfeG`u4픫v=?-}ci`˼ͲD1DmDÚ4۝i?#ǂ*>u5ιk<>7)pEHks~q'(X{x¾q`AU|\;_I }&@Bo[C=~ijBt}D&(/Ÿj~ &S#.V=$n

    #" k!RUssΚJY<#^-uGYF)XOl$? @8DXؒKLUMWAYr[@!ͻGk$aNNl8D-2/e2NAļ阋GKkMʳ, ܈[*V:@7,LMo3UrXRS'=MiRě@đFs& 5ls5 ĺa;"{p5bnI7v5%^hG LBh"xz6*#~{8\Moź%F(@6M)?~d1P1GK"@YE3rXd/:Nk4,{uG/+)dǏؘXզ|A͑ DߪWlK!졎|B13fc߫btTW"Wu׸b6M2G􍍺ac@is=b>|J09 @$sp$n{6K,+\O8raC ;w9ֳ!o$Ȯ>1& 48$v0D K:GZY}O5"`2/Z`ܱ1gCU67DBVцÍSK֢g(=(JlqXI1`>uS'RfR L@NYC?v^+*JvBncbiU@E|Gh9\/qL42pc7K;_sD(IE~GnMMSyko1Ts+Y7}#*qﵡ/'%>MK}$hԿ-Y_Ӝ'xSG¸)2}g<Qw?NOϗLѺѥu?78X^E_DX0ӱneD;&wBp @LP4^ꇟ |iyƠ*|K#2޲, ͻq]3Dc~;Zͪ@  :1bߧY98kv-Q~-n6IWUFkߊ}=[ `zuV8tk<\ϩ]t4Zn}?QCpgvڛ0AkYp hV$jO ~m %P)I|մˊ~HV?]Uw'Xⅽ)/*q,5EͥyyiYʟ.j}\%s-NS]gX87hc4Q n-'/qӋE{׬`ξfdw\&5w-A?Bqânee68̷ݏf~޼Ѱ/ Fk['!y5kP>xGSO2<)0FWƤgu& EVgQj U]ȀPO}|Þ{q&iD>2eKdFtnƊ<&(6)x7N*0ړDaW{϶| KWF}t/;3QE/3CvP8Jșhd@܈o??˧5)2s^]%>}ng;&>~7!nd4~DܭɌͼE@K8d٠ESM8(Yˠmj{h UHgU-TA\?0:)E ,K˴8HՓ]m/Ol("5 c_'dIinH7co>OQ|PERZk'ﮟB5 bdyH%{kB'>LcO RkRơ0`s ΰh鷖czs1-n|3C6P죾nXj >z=b&](>a @^ }䤔%ōPK9ٗ`79PKl4<'Configurations2/accelerator/current.xmlPKPKl4<Configurations2/progressbar/PKl4<Configurations2/floater/PKl4<Configurations2/popupmenu/PKl4<Configurations2/menubar/PKl4<Configurations2/toolbar/PKl4<Configurations2/images/Bitmaps/PKl4<Configurations2/statusbar/PKl4< settings.xmlYr8}߯Hp̄J2d̈́ Ȥvބ݀7%\~ZfdYc=QRw/O7_7!XT[~Ys.@xbqZ)g o]_)&b8%Q)Dςb{PvYһ_(m Z&%=(`zsuZ MXd#1=bȾp:/2Bk9f$04b--s!o?e*VGMGVe> ^L]mR!TY\`rTO@ @ ˙xUR{1O V| #Tڜ K{3H8Pg") A0$(3zM~$5a`u aD`)[yt)&n\H׷ E0>:#C, l,M7Ycog:EfSڍ5Ie9 [ԮL<3 ?D2H rD#kT6966SKIq7UbJN0Ax-\01c[]BM4F#TGj;(1l0lt8rMxpڨ,Z{1,\ʝ! w"Kl=P[yV r B,q%*Q3*|Fs\UDVpK!wSpVXgL /&bWrm{LxW hs.Wki4ch~J z 򑉘jA>`FL1mJtna6,泖5%u&F䱱DChȄ3iYj 6u]μWVP&x $`3G1pݥ,$\i7 {azCmow?bRwQj6#V2C:,^WZW}PKQ PKl4<META-INF/manifest.xmln @{5I(qR$0%f[kn fzpC$Փ(o |/uX9<(uHi#R+2Tr@5_;c㱸ʠ5cFъ<䪦zs-]#w0 䰑44ƀ9G 4;a]r[Tƒ 3}DK GS]Y!>Vet+\P)~$g;fz fةYĊ#wߧcqVTz_6f`Kk^? PK`3fEaPKl4<^2 ''mimetypePKl4 image/svg+xml ViewObject Selected View Object(Resize Mode) Handles are centeredon boundries of objectTheir width is 0.4% of (W+H) of the screen.The handles areForegroundColor and!ForegroundColor.Alternatively, iconscould be used. Selection region is shown with dashed line outside of handles. A right clickanywhere inside theselection region brings upthe RMB menu.A left click-drag inside theselection region, exept ina handle, moves the object.A left click inside theselection region changesto rotation mode. kst-2.0.3/devel-docs/Kst2Specs/src/selected_handles_rotated.svg000644 001750 001750 00000026614 11544160206 025067 0ustar00synthsynth000000 000000 image/svg+xml ViewObject Selected Rotated Object(Resize Mode) The handles andselection region of a view object rotate with the view object. kst-2.0.3/devel-docs/Kst2Specs/src/Data source changes.odt000644 001750 001750 00000035754 11544160206 023576 0ustar00synthsynth000000 000000 PKO8^2 ''mimetypeapplication/vnd.oasis.opendocument.textPKO8JjNeS content.xmlr۸}CHŗ$:n܉XN݁HHBM\t }Kz@RD˴#v:-sP/_]E!dRq6^AX싀jb4>O#/b  U>m2 4bHX껳,;1MƹZduWzͮt8h@i8X.O$S0jùz۸kʠlA J PYfz$dTw1u*_vvig쮎hdmQM6&Z'v{:zMOq1<4_t J%{\5ls+~6fpu:Bb^L6 ][̽ y|q U^7$7I#DY+`~ yi ]%XuJt7C><s`KLEJNqpH9SŹ4p+ʖZ;p6To;hFk}#aAw ܯ2V35 ߸-m(۫|﬒%Hg` Y'LETy »^Y}/e_|YD7⧷, Vm{8e|<؇" nkK&`s ۂ* u@o M (Reum;}9]އ6w/h6vFǚ<54u`<0u2O)x]<4oܪ Flj!W%:ob % 3z 0d؇8nrx>jar+r}nSȎr8'`(ǻ 9ګ XحTTOP3>8X]9yB:1k$ڳklce0eOP9$8 ! 0BKUfi߽oˤt&\}dtIr$MX#]?19z؅'zB>&ɥ"1"y$khr6&Qꓣ/C?vI$ \Cͧmis()} O_qހYHH@@2qk$%}* r)pJԆ#op*BZB@& uwPp$ B &;ji2ЏIgm Njt28zNqTPߑhjc\(N%3V*"htNEu:l\n& Aآf .rQŚ,WBGd >'"5WG!t"ŰE0 fO qP("S @Ceb?W֔H?7ѝ 9sUeU9V8R9dhǧ  hq;5TƨPEn%SgnX*T2i\Fn$$өA'=>#Lx!\VX3-cHI6rG0Bww g,Yu,xX}I KBSKjpdVBɳ?t{\`5\5+sSiy?Ҧ0EFx:hrߐL/)}yLC#jѮRMVۣ8[CbZn?(P\QJ `Y;k_z%fs}|(iVct; t Y܏p0ވ)+ ՚;85WMoʍ2g$lhW`*f"UĺMr~=K^9mO=Ȑ=!ͪGWt=݆Hp-:r6pk.yJDS 2ƨܟCQU#Rد!شeS VlXAK}K%7=n~O۰Mܶ)Er;/urI7oWA[WANy.3 f^ݖȫجP#|yc֦1'4bZW\Ѭ+o|\ۖ13G2PGf2LCHVOh>i4k{w`e~pn]M{pc [wuc-Lq!xNøxwhb:]7-tc}&ض!O9߰0XI |Ge墬Iz>|HUEb@ ׳V5'a+w A|aB7+XabxRm,,bBX] h31Sɰ_jkI11p R[ ힸy€Λk0W-j,N/-Sb;UB[>~:e\s^εo#sPKO8BrC( styles.xmlZr6)8E,Kc'LɡNrHBD}>IA? EJ x4\.v?K,^'ع#J'l@zW4P! r!w0[=x=R@B[{Ҕ `+%m5)/཰y`V̦tV8+b rZ8;5LӔEho"l,0k)Q 缦,J ܑ"*w aq4ՈsW'A8!- |HJn.on-%nz~7~r^;2I@wtt`5_yQ.>/ +B IaI9M HBWMV&<["!<,t5߬WT{3hLnpRP{t@9f4#L4L"\6.3csȈx/l&ň;*;,&HVѢJjZ~¹X)H( Ҝʯұ{iw~M<ҡPf eD0 [Bm 4IoD!;j !CT̡^@ ĒI߃rikrGxzHYXBA%Ft$.r < >dJC2N×P +HF3gmaya^Ա'If)<=r9Z.6nfW 'l #e|(.i&2ax܈Й}1rdX.Kb9x2,rq,ϋdXFWY :7-PO/F{+N` Y}]u1cxN/YR^գr[ûhwk}:0Y&(0sd2nLqiU5ޡrU{liMl \luZ禧}έ[NQjjd(QPbJ\XWdnR_hS#t=1i<m|}6 Y0Qr@<=h/P,,˞ P,=X.?,Xk la[V?Nuܼv=/}%9#[#':eN6`YEn }ӥ\+Z%T@z2>lq7EEuj*nRbXUo>CUEq)do6$ahgZJٹrNP}Irmm:%A 0n1TN0eamM>mu~W{wɪ]iPF|zC66n8Rp)C7X)eꏗr q~kz1la2 _j͖*U*ּd18X2dQPs(hQ6qPKO8;KG- settings.xmlVn0}+"R}تJv?8%CJJ93K|8r@i* @S]O=GKY@KRq&`҅Κ$TgsЙ!,AμXc`p(a\"EA8PxÂ>;W%;>T-_07}0i4`U zp]HCjh,ݠ|s /٢P r٭Θ2Kt,6Iybs!-4&mWPGBposLfI_Õb89H)Zv'ȚynUEgun9OoJPZ9֤КerMѼaw6*!); {PB*xV)VmS]2|&hmToʺ8`ɵjXnpKLAM6+#62mS 0'wq:{M}>Iz_G>^o2@vh^8,-e֙޹֣PKO8hN - QsJ%OM{: #%?LܻV4}a)H(>44D&QCQ%k{A,nݚ$3|Jb`j{>=3 F_gIqP(x<`"XCKꌨKٓ}f?mb5(8柖jjw@+=W pP/]/T>b4 4xYI5κ첣]I5ͳ|u5\ 0%sb! MTMq][M+7mlXB.qŜ"'o$h\޼` ժ\uKWՀ-hPRROOO:v&[eZ zO{.KL xLLa&<$?Ii78 ֏,<q5 >3k=8@伆Md XS z(6\ ~y:9_sU1憴:(EQ *y&qgvш̡_zoc箰O{患eZLKb:MTbJٺ[dTi) I#ii\\}ȌNzqA\C'-2X$$M>WT{?0f/z74PPu㜂d^rpT&xc>zxw9at2;K͒;:ۛ7^c3q^p4nS%*T4E0'Rh'7?G~581SxM'&%đy$G1 9_gM&ư3}(ו:[AJf>w[պ ~OzcìFmރָ[w Y]D::9euxyxiSO "+XT͒q cyȜLe !w7kVo0 f;u,hLƬ g˰ȇ AGC.yM>H|?/#D˓>-,#C]77hڢp I? ^2I3ތ/>~s̮ D]ɓ<:#R(  Vs5`mDئr?S W)NRI] 쬖2s\i~+ V=MGT9hO:S0\w1ȈD}9f+(! 7~3MdП~/$N45}<+^b*{҄ytՏa%3*1Mhм"!-W?|0Н+ g|P q/2 &P 77깹9@wvX-pN$ x֪{) vP/ $8 F(9gϺU2\WI%-u-R5S-ę?HŠ2tQtѪ8c_qm닃y5_m.6DwO= x45߿6G9]iXphS_mrmA !{0dˊ hdy=O;m*;9 vPO3jW™M,Ж#18t%)c-ê21&(2G X1"]+8|OUmam:Oƒpn,lxEɒF҆\nKq/喓_]Zc}xl駰X`{g","( _/~;e v߬5ᮩ/H錱` 璭W]pޚu?*pushpwgh^G*S.fhcNIS]k d o=tYK GwNtKKdŚv0f'v밦T=wGlmojB gHO /6:3.lEdv.S4`"t$>@҄5mumj!] !ơ,l&|CXZq1V 56ׁEiRRYhY zE #,mAWÇ㢄'I^ -.,988qf띀PF 59-il\lVXë{@GPVMͺ܊c8baHKo;:(kcMwQEwúxh *ŽWRaJ2UcrÌF~zqf+Q{;,0Ė$'@ߜ@Yd 8+!U2s-rUMb*dd؞;<ִjVc\Wjqd?(4雚3.gy^ ]""cvHDlqrT_T'횷[1I]x:r wͥuT|HF -c'uM2'II6Y{; =DB؆F58"`cܗ,LE&+/_*6S(@$QWirK,Q[j,mGGjdD7J6Bج {25=D H~b(O>|' dP[&i@-V?CbŁYtk \oOŒe۷ -,, SN;<|4B)dSXA ar!ؤԞ[cK}ÓK`iյ>fV{ "}S`$;|.jQ@[~}J8H*\g,&2 >ˁ()02cGY>:4pvvFKAfjR֭\; G:>>>(4xؽ); nz4?5Y>UZ,K>c | - iAʼEQQJ*jkaP{MG9Lx՜0Y$SM`J**~JoȳQ%a-KkwLSc(8 c$~ZN45 CQΥJ֒죩R T`[6iKۛ/Ta_Y0V Afы !qr)@sM9{8R@L}^6c% 1(.ckm \J77}7$$)db])ꠑp)f2|h64iZp4c)eF:|nL:ӑ _ͬ>ߝpV,"hL[$;Ld1+-}ۄU0QD\uVTU޷|#eISURVh4މS"UOTxGG>pA3 sk~oV@JdtB.K#nxn{Kg-zμt+Y&OY*4̭ sx7)@m’x1ߟ;fS,{G_u@./,UݓPo\&GiSv/A PR({Ε6pG姿DӜqoPIж{(spY}aआʰGYr4s>Jx][.vۦv&WZr Y,+ *[JT9pÌ(U.'@1QɳG)0@<Mo`^߲ugIƾKf@1Z5% 'Dk(bbq- x\fGtdtݞ}DvyK !f]OvDL>B ?einaH||=?m݌._(%O}I5-tQJGoH+(tf֡GmZ2?x eS@5V`{5{YPTqw?- FSʼ56Qkh12X`VCFI/uZ~㐼k%inqN y19 DJb vgQ/NfZ,M 4?-ڎD#Þ21E錗=9 9kDsSq g3zSI3[ʾLMJQ˿$Ux^kj*vMTB@]M袌Uݨ醙B?۠ R{/6υotpd<{@5i&GkjhAUlez)Z[iK/!Lƕx`TĽ]0S!NQ܎=.C38.6Dsq\ZeOKoSvsMJ0li\Rl"2=K~X^G_)v%)qZPg{F_olų"~oa$Ҽ[6Rc!Zwa4l'_t|YVE)ttmz̲*G@gj>ds]JrkA#a}a(@psr׋3\ b/,~A R,E m{3~{,jܣ{$ΈUW"ԁF>{ӠmFC+Toc_TU@ Fg6I ;Ec^Ts‚ng^◇0(Gx] \JΑ Ū xH /-H&Ydd}bv393aѤGrT__筡2l2|Jf|pyNprVJ]QL˦橗 a㖠>cz]G.ĞOP.U*JQS*XXCZPu2gځb; L~3@: N9ܣ1cvݚVOV/%CB##\vρFĭRGۈdD*XC (MOQvH,2R{h][L 82p|TU@ETk5m6?S-;Ӄ/zjEc*Tbڿ8vD@ҧpǰ$&RLc/H`|Ҵ*>&?IU"џJjbJ "W"Ei ߔ|fm@a<(Nf/^_b/#ug~A@J'2e4 _nwAQq%)pXs9?m1i9dF$p | wuD Ld~^Yy[r*Bg"xd&ܤrxQfqĚ! g'wDbas'{K$^am!WW` ĦӴ 歹G}]Ñ3ou0W1P W3Ţ$< $iIӨ"] Y傲 l(pFxw6àӜBvb}q"""Gcv#/PZ.*xwXLVGjwѸ/ǮNBEbDR/^:]}}Lɤ)C6{U-V"[ I~13ЂtQJ&_f$Ľe͚z?y(EKw?PKO8^2 '' mimetypeUT1GPKO8JjNeS Mcontent.xmlUT1GPKO8BrC( Nstyles.xmlUT1GPKO8;KG- settings.xmlUT1GPKO8h image/svg+xml Resizing a parent with anon-fixed aspect ratio child If the parent is resized, the child is rescaled accordingto the new dimensions of the parent. kst-2.0.3/devel-docs/Kst2Specs/src/Grids and Layout.odt000644 001750 001750 00000051662 11544160206 023100 0ustar00synthsynth000000 000000 PK| 8^2 ''mimetypeapplication/vnd.oasis.opendocument.textPK| 8Configurations2/statusbar/PK| 8'Configurations2/accelerator/current.xmlPKPK| 8Configurations2/floater/PK| 8Configurations2/popupmenu/PK| 8Configurations2/progressbar/PK| 8Configurations2/menubar/PK| 8Configurations2/toolbar/PK| 8Configurations2/images/Bitmaps/PK| 8 content.xml\KsWtJ,z{kTyW6e)rHUro_nыcd'ӏ)fG-\[DBJ쵥zXa V+pkf4&[\%EK*R{$@iCV$n[9mN3$S*u*Ourp 'X?KTUҋݻ(NS Yܿ_z^ ti2;ERrÅR;d o*Mvge֦∔16c|2@B磢$p؞;GVZ:}2OhedAq=OkX z :x֮f]ztp*C,JoDlb[+Yun],ݻ: dK@, bC[,bnH.e"Ck ,x:o˿,eoا'NZƋLIkLl;_%f 1fҰaxpę˶cК߈Ηt##ݑu'R_s4|@ Hߠs{@sx:uNz/ پ︳ǩ\g7#}37# HfoFfoFT37#}3u4#}37# HfoFfoFT37#}3?H]MlayK_1~JH%H)>D!3|"znFa?L.<|ѣr:oԺfz< %Wﰃ>;% W,YGCC %6d{ɓ@[^͔iqTd̈T d\o$\wd!TܠV!V"ChsƟY`]1}&A{UvI94?R\ieq~5d0<@g"k4 Mi}8̹m1g]@H#7ٵD ?gO'prS%Kc^( tI̱sUI `ćv#w;Oxew<< X0vz8A1vG}e.0 #{nDx7Q/ PKƋ6 TUPK| 8 styles.xmlZ_6OaɲMq PtD[l$RGRk;fHJlVI Q^x E4<9㻇яoZl,\dME>T`3WkK|ׂ(֜TTu5Ͻ6G#lvnF^~awnF^Щ}+n>2ފ8UM4;Aq(Z$\]VP;YW74\yВa*IiVTׇějCdMάv=i7 royoňMw@4{UeՓiB*nj.i*="{FʬӸBJ4>F3BiMӖd4iV7ou3uEhfTm4Oj*VI->]b5j#ʀPxE{RrmOL+-)fPI2n;8j3p'"fk 췷ǂ_({lg C@ҴzJkpf矞E[E-iJ$uuZBAEq } !Zo2 OH:GcU k\>tR""Y!gNzR=LmXTk"ѐKB4Z,².:`h Y[ fdV2֛0S,iAKZmEA jD)UвbiY+ 5dKL4\KpVwKCy$X0O+~:Z;pB(|"v4#W [gCc]PqItf ~źLn=u8gI˻֠>d>ÿ<˅t?ǂL+"bzvRpޮVvۇdX9j`s~ w@GwGLv_?|A3#-QԔaNmvu~һzO4ՅJ3=uީ撀i0ƬX+-]d}X]T17 NQ^Sb6@}*q-_({Bqz_( ŕ.=!G˅ J߲]#3bWl;ATnݨZ(͇!30v'J(47| lţFzcF%;7ժZ(V;4{1'& TXnWq;X vr䓂pdИU]A ͓Yen!flW|u;\wNB2P"q^&$PKXL'ߚˤ`[%a\'TۉPb׬l0vJ?_ց % Jh9& ?ǰ1l`;Ev^PVu 4?y_t6w$Y4K˛RSj$=LtsL%JvqV'.PK LPK| 8Thumbnails/thumbnail.pngݺUT[C)).݊Cq n=@^@qZ36yYw%>?9Ĩ*``J~```a߿|ᢒ=5D/ ^GBPYT|1q.x&|x4x5TR&]l_>PFI!bsLnj9;:[Y{ݾ]w7g[!gkI|w؃C; W]گVfSQ亏s>=eґ\mi_Vl\ë"jݭ:+6tZLNر_~8v֜ijBr>Loh^o^Yl|=~^5xnfP"2˺b(R}VS,cr,|E`sS/^{*xH+a`m>g-OďoOV.HjJ.fhrݻK-PXfzB ~Gec{A͒ҋN]͞{3xgҦ!V.NMΰ3vWЖ )I_i" fU1 xx`t C,"a7}mU ظ꭯Z1tHƦ}ZJYeYbRLw6l&9coNc̉ff}Y.e)i@m&[1? 2C!6xL +"Q.5tkVؑk*e(|d:* =t\7o;oGB/!z#X(@OKJf?}11V:/2ig}=GDf}XyF\%6m47^PQy9R9wXCcM0J|xK.['hQTx㱽tk^IS|*&KdLu7;U04wȽN՜hjOj~EX[Y@KUf vUsY2|eÔ&_Tp9:b1MdHhs)⻇jU{wPżWS_NCèu|FC̿@Ij;?Z]5K3^(rdtj5&6% O h]\c!Y"܅/C0`0L=cd/ IE"h4X'Q5eL2w2 @_T8W*|8`<#5 ᠀wD.'cbBV'ǒ8k$RXO ZA`]{ D27h?=[y!$a8>q'\LdH>젵FN`E!E$ppMkޛ_(/'+K/|q~1BmpկQ+Q O]^ ueYm;0kvFYX30U,l02hyF,5],NE\#޻&2i6J$IxZjowS0,5~qF9?;iWع}jl!w3K Dl˴8U)u5-ȪGSF9_}"~+ν(\66B=7;2>o>.nZ+$<Rc} V#(ޚIIus;!lW#YBڝ2 F:}ǔ _tR"od^LtOuɐ9,! B>t^3*ZNd @{uCalhޥ V6J\) uWeW=,ҧ$A >ڶ%Q _5 N"pslB/,H!)ʍ >y&,*o)YSǚBKPp8*,ѕ?8w!Щ'QXv,w܎SPّisy0lW hb 4.G jfk2l!M2_}/k\DF"r/Q)d1n ^S_렼/9ά$sj+U)iTLV:MɆbTSn8-sM/N'ڙ]ÛËh>_Cԝ1`-wUx=ێ /1@qcTY׸||.pnwIt XJc3&~g)Z_AXC/|y fqPI`b_a'T ;QGE[5;C6o3ԭZ4o-B#vƿAO'?I=ĕcs"D}-%Rq~*ױfn`V}%b~ As3J{nQgS&`8opwknUmJ&hqL}wc ֠lK˞(L' ͮYm;ӻH)VD`2a?GoT HB)N52R& ֺbƾ}3 1BF(cKMZBa Zؖ9]'Ġ!ۚk֚GDW,0uhvj+c"{KpoDWo6`j+8BJT1B! { v)|ljݷ=SɁ#hFI)A&D.~@]KP놯.*&U8 J >5F:fS#(dN^{(500R $t*`s5ȡ[ rK4mTkw2 @P\~S ]W]J<O)JP~~d9fŻ:&V98W,%|hؿ"ͨRulmcSci>mLQP7#3pO1;w  |?by?k^+{y荰(cP'neg >H6"TB )Џlq2[)H᧾qoF"jsF)bGQB,U;Z:2N$z֚AϴgO$?$+ԗeŷDt2l ȋQw9t]-~@16z`3 u~fA{3-qzjqz]f 679#ZO$ʃT`VM:yh_SINw2G '.f.ve͌)i꜍Av\{- QYԌ!_<%Zvתg@PIxg|g_ L"oFBFz޹` A%"9nIJ_<a^8v#0IV*8[riAZ!IKb槁ң? ʕn'&Ƕ&|a<b誂gM<_+]ʧx;G9V[XT6Jӷe(=֭=/u]2*djK8g|!TyrQ /^S1"OR &^#s+*9YZdq~etr#;9AX'L"o fH&-O%\bovB pΥ}9#[l'HƒnS-#& ƶodz5[aJ`eGv h?exIZN2C C$ewIl`{]*cQP1=[罬ZJIJ-K$E(O^)c<2Le#49X y"\% .ُ>CnO;D5bIIP/Ғ! )EjgZyFjYj„%H\`*/cҷiSSlOӎIT荓{ڴP+gRH^m-V+55;!,\e>T P&ݾ|'vO=R`+7lG7Vsr+vixȸ7TcYGW 5G9?ZHw=IF1q%vKz?X mֵCr }3VĿט ,P֮ Dz-ҠR#nQdv)V3b 7{M&eUVɏZN1@sZ|M)/28uo:W^8\=_>@}/n_:v$*B wt]P}ww쉻=}T{.?6oyBn$n c{Q>U ;3͖WQYoy  .I տf#Mk"֔tSVuE(s\}K5\6m^R\ ZԖ1`pb&H|)`b4@|̰l4 kg8pDYoڇMIڟʗRNqpqelrg5lKk2{pJM,<.3l2y+)W(Pk87ы|~:" l7Yڣ dikS|q,F_l A; [Ϥ֔OHDy1,\]9/'-ľ!{g=%H!sRxt'}  624Q)Bnq*z1p5#O7H FȡjTR <ʬIJ=cY.P]6 Xiל=oLװ{z*=ygj ~<lHIU5 ?& ߰&ZY+Y*B6pWČU: GHMv3z\.]1dM" ]{M;f]% 3v/1@mdzJeRkY~wVf2l{ 9$"GU/Lw!b&Y"t| q(JR,k xQczP*X*^m3c'Mc[x547c,sniO\@mJHăԒxUֽ7;ʕF.Gosڴ*moQV D|LZr?jh|_ { q}`ExpA_P*K)9k"K<7z}ݷz<^SgƆƆE4|,E3 ?cDaÐ_j"}! yOKs(MV# Ii5CP(fY *0C :eN;7wciO}T:hZjd/3|צEX (Fq?ki}Rw'?X~H {YXx6fmAFGXTTbVbX{Mm,i5G}jF8Xbl3h 82(8H(>¥*W!Ho3o^rAfJ\en {ox-Y9 Tg4.ȡ \o1 uBuݷl; ?QKM°{ "+@Ұ NjbBCß#{٦BqM6SF'yaǒQ+~q ~LU 4"n Q v*lJP$ꁏ>^кyӲ<䙁2.%^ w;6U7L(nB|?TZ@|fs3W1|yPu8?MSE5 5*i9A2[AB1ژ6Ǯ 5Gr'"؋߫d|Z5ÞޯOScζ@p6IP[oňLN4mdyRL)gT#3I'Ou+ `qiwƳ7Dsej!씦*=f^ UhF1\/|<N/XIE!Rv&CGn%pX؋ј>I;ˠ0u0(/^HG6 AHl7=b8PS1ѕ%S8QveQ~lҪ纉܋+Ҙ x)ņ~i1%Et-&z9J)ΏjF ݮ:|rd'wMH0-$0TPi U߼_ M6>c#΄~:3Z͚!D1DD~nХ,˽ ͢՗%},n{Ǧw!{&OmG!67WIٽ^P9Ű &!.M֎L Z~@pZס&i4YÕ%=q.t`UTl 4\rD;՜VjL{e:씂,OEGbfP"KEsaJr^Ƨx֜.=vH˪E.~2h6Q+oV:$Et9fU.$2?JӪ+'&1cI)^YۺuhD3Ccpm70qˌ-Ku}mF {RFAl;QSpG Z;-uOϢLդ h5` DXxOӌ6׶VvF+rt8 su=^0CeBMhyhbp LsJiOut 떣q6Hnk|" 84k'Ё s o1TWk["SQZ`HSY-e&_>A. %D>T-qAee:I;օE@i>A spc2f\y %2QR0YSpU+Ȧlۄ_@oc{=g .! {#YMYsc&ؔL5M OBm޹in;(P:r!KP%[1YVVtԢpcJ<~OmѼdžjQ`/BYb[=-<μ@:cf߲;n6`"h-^q9u7r6nu' эj bW#3wfEYUfa1o9 Bgg&q$ 8 \1A(m=HءU`'hnn}.t;DRʳjޅ~lh~0B#kK8HK<-uvϳ^K-`d3YxH޺k=zlMC)[?aSQE~MFꣻn-#T ŏR`,Ediz6'IӈVZŞp^nclwepaj56k*vB]ZfHTmVœaZpW!ўx-RnQ~\O MQ{L_^{quLl4-Ԍ筡<%em6~";%?BH/e:UdOD .].`Q2|szVv> 23R"wȤhowN&a̴ONnD:6 u~y\(ܹĽO'-PM.Ls' Um<ådfT1^r#s"_8x*9,j#8IWpӮm} AtzU)S(iB-t.g0R#gZxBPIeyG]c<Ӻ[3FV,p|` o]{ZQ|n*9@;Q}(hZO遂L?iIZh M>-\ME9bx$"w 3wrH:j1lSZY?|W00K_΃N&͵.<{̢)oَvP\" 9ތpi)b:pKmN^C_^㒱"@;ׅ.u͗.41N,ZO@d%7XU-C 7K%jZq< ]Ӕs4bNjs*b|J08E*0Ì歸_'0#1<+p]SHPŲtlO4u*Uom2^c;(=^N\ެHnΥDæFBze5O٣IHEzaEԍmn'n TNTs# oE+#WʯY6\ xp@mwwPXU0JXa,A^/Co1 #^oc^Lۄ*ڸmNqU ~0:߉+:}^@7i dIPK˪53\4PK| 8 settings.xmlY]s:}"wIKK$7a/Y+d0)ĖήVg?|mP a-]zߚ\l}h!HS` -g]FƋl \7$ A7f[F",}\>x cF\.ϗsTrꪜ,QPQ귢Uݐ*T,Si;l߼?%n 9[n<x|GZR&y7f.׬VWW]Ñ03yХ/_*Őx`yŰ>_]^ǁA@ns[Fpl+\jϘ×B `},CѡևYl"֝ >߫U*PJHxOEt'}QrQ֊Fc0žժaF 'n T||*Z9 7t=8"s}p_@|>3>ZA0dM8bXƌ&_ئ= 6$AA>>8Li}*_JPK| 8^2 ''mimetypePK| 8MConfigurations2/statusbar/PK| 8'Configurations2/accelerator/current.xmlPK| 8Configurations2/floater/PK| 8Configurations2/popupmenu/PK| 8JConfigurations2/progressbar/PK| 8Configurations2/menubar/PK| 8Configurations2/toolbar/PK| 8Configurations2/images/Bitmaps/PK| 8Ƌ6 TU -content.xmlPK| 8sg%  styles.xmlPK| 8 Lmeta.xmlPK| 8˪53\4Thumbnails/thumbnail.pngPK| 81% Isettings.xmlPK| 85b9>J-NMETA-INF/manifest.xmlPKOkst-2.0.3/devel-docs/Kst2Specs/src/UpdateConsiderations.odt000644 001750 001750 00000053306 11544160206 024173 0ustar00synthsynth000000 000000 PK.V8^2 ''mimetypeapplication/vnd.oasis.opendocument.textPK.V8Configurations2/statusbar/PK.V8'Configurations2/accelerator/current.xmlPKPK.V8Configurations2/floater/PK.V8Configurations2/popupmenu/PK.V8Configurations2/progressbar/PK.V8Configurations2/menubar/PK.V8Configurations2/toolbar/PK.V8Configurations2/images/Bitmaps/PK.V8 content.xmlZMoܸWs(ly{{d֨HԈ EjI=P/F=3ƅn$~>)ۯn A6\h= L&*rz2"OV'T$ x4@kL&a' I2YA|=qĥT"2uI4=&n2hQF,Ofg D%<Hb~<=-Cȯ b/-՗bB[k\\t 6JCΕTk= #)䜙qc:% TeoXβB.eN/+I>JԺX87xM5i?D:K+B&kNXE'ԔcŨ,SM˼ހ<㸇(xwt>a"*545m93$S޾1OqoDТ\L@η|Yc_X tF}0LXr@߬Y;>TO,UvG 4ņoU) ^<ܨQaZ.-M:FX#0qYN܍SA^h׽7NesսAWkƢupnA $I%o:4l?:2l,:$ ^`00z^ --rW5P=< Qt\3m`x@j牑HA~}Z_+H/jkow8z Rowx8z@y:|n|oF F_}g^N3l%y@֗]F-L%/a,®W_&/_*uQ7eJ-#gJ% OmyPPW}5)5/02X >%Zy~%d$*!))Ռʔ,c׌TTCOrI'B@@T A&4ɆhQ^8xZm]J\{kHⴗ` A*.߰Qi(\U"EZrKӕ$};8QA|//+낊j P5=bN~٤JKϡ-P⾴4:JiYל``_L#$ 2̗TAsRtel0N2ǵTb%8~h=Nh)Dc`-2:O[QȺĉC,/ 6UU-N%)@-XBC9֗SzQL*#dDQkb" p "RY'&f>/eD LZ!in$Tq%_0Y< cD04h%fÇ>*U/m%hRp9t zý7]:"Pd\ZQYB=IA5 i J Zp!rݤcxBeUfLiֈ`d}5hL_"TԞ OQ V IfNH9Ӻ7v/w.ȟ*>h,0N)gSr`l;s{ڐw/rpx5Cۛ>Xn-$4-VAyapwp]] *P:l4 VS׻ t@5n]s 9aR_c5G7b—ϲz\bau:,.vELahO ZD f%iVplI}gssm'̟pN&b>l~`h?cq<@@u F1 g"%\*r,^8cS`PyM^U *}̖ۗBtPQMPw>]'o{{}+cβg:*d4Ki4%lp5j->IFfz񼍭nyFEfrO%[G$WrHj~ڕ(9^yV (Լ!HR.;k:F{Ɂr7j˔:ਙ lGK~g}A7|At!1J*H|*lįz0>d(uzʜISi6"kǵܗ̀p m .M2 =:FcU zj\>tR",NYPziR9Lq;I<Dc!>- ch{@u9XIJ`P\0bD⥌ )v8#L=iQ+a;>9M(W(Z6W֢EG@kmJ7 f! }w|z;%ꌡ'Mǩwԏ#ٍ PGIwҎPьެy5&:?Dg LWrK`31+֝`d t*6|p90]@9I:ߤ}n Sy.f~.WPog>EC؏0qIZc]OFG,VBb:`A)I0?wXr(c-6TxaĻa7m<}%Q AuOJr/BpLW ,ޭDT*"̀jlsl/Їӹ%&M&ե2^\sS@5}B|;b&(uI&>s.>}18%|d |DO~A1%$3q(Iͳ\hdfQ5C1{S}ĝF߮(L;0eZYj@8q۠-F_0ᅠwƗ(l' 嘤Qf1A4ژ8ˤ(қLR)KDوxVʑò}Hw F~~mJN {et#ߙ.whřqU0lؠxgs :Eh 0#fbm rn_ Fg(VT +6m{hOuDq>O4!@ԣEzm'3yX,G̐u %]kKc<3< ^߃[:Uμ[dyk`*\lj'!,VWit 0Wʖ-}Noi ;ΟM׃v[[a> Kl WY eh=w(-A? qWDMonz>lV-O4@`s1'۩|z ۳0P bi*հ@ws[L Χ,b 3ȓYw 7Ju22=?.SP;q'OPv쳵#I?PK*jԤ&PK.V8meta.xmlOo0 i CJRsسmۗ? Zh{5\ I,Nlua[aOyNR9Ńri\Hpfhx8K{{|pl[ 5s.?xxϟWQ j mSYzQWhяarJnF^>)ڟU^Uwl_fie;_S(sҷsys|5 |Oqjh4u6y͵* tuМʝ|™PZqtw&pzn'H}]$Sԯ;Åw~=em)Qn+XK$ RqyEFs +w 5%A>rkI ~-)\ < XY,xq"/\e(8#҇;yfG8Λ a ᠿ]|.gf Md!zw YZ'=ëQ5LcCYJ414Y]u+TXr9ۚߠifgAa7U૿:;啕ŽŝњrFzH\EϏ(v>h;XBs"<݅^L,ě}\X n)<9ٖY!_ X+ŠGI+U^6,`.~Tڕq3ݒib-$WB.?s΢m> H!~+_uJH~7>ALUsPdu^RچSެiuZ^H%ڃA#'Jջ۪0ۯځ?AϬHR"DgK<ErT^, "sBvΥ1a\` Aװ!{-^ayMIA!2BQ p?!#>!vx+ 65dON{tUwW/>[*)y{". vC9qr~Mp@Nq7W>Vn ̽'nڷd]}Yƽ=>N&`߼O%í^픮 ڙ] /I3Ê6CO_E-Q\=0Ri^K` F^^Ia-s7{qb3֏#i)O@LQ )Y0km!ipWJC9nF=,]4T[ YtvOo.pcspQ* a8H`L}^˖`Ru~0k ߥ/:m-;U5->D mT&2A4kz}vKx'`.iOvǑ֊6wA/\H*;qsvδ񙆺QE`(d+}zcuBOp|s؞8IO]nf}y;gG0 '7[F^ݠ"rr: W񶂼Y{zAD*Up޾mq^rQC BTWlt| J=DJMTz>Lu2Gx4Cd7陖x +J]1uGMG<\T8{bAҳN4( ]6MF M 9w:Ƨs6:Z9#."?`r$ a6c}cڎLbs~P:C>ޑxWXq~@ßHKU 9Ҥ=<p+fcWxce37N4hi#nl|MΫ('~^"W0CQ!ZRemϮ&ݏCkdOA;Y 6hx2fOj8@}K8d5e|'srҶ}k0,>W91.1!CE貋yr2:%wV}SoX}.邢+l嵤a⨑gQHI8eO(rfZXsxY_//- f[SK},">uR[8$GMv.*&~,ta/u1pa5Zlu ")D^d/,XQřQhe*R=U-z0?@8G=]n FKhX1Rlҽ 5{-#WoTmvAz*. rXoo.B >6ϯd鹧(ڈuk>-{1?96|xqE)~{S lS5 {ɻ洨7|c'."Ao`Qqj o<_n3`kBW|bAnPZgA8˥5Tfuzyw8#3RMy?W)|*biDI(}ҭRbhW3c`MrL9 :Bye.рzV%ߦ{#R U(s& E7@'ո,fF;Q3bz&'Md+۷ٵڢڕ;MOŮh* 󄂲kh[؀AkU^1s& /T:f_Vhl]<-:: ץ"*ټ>,t="縻ْ'G| S]M^/4¶`sŮ tuF/Xbۡ쫪R Q7e"U$yx`_E%JU'o+~TcYz(۞t\v pEn0' 26Zۧ|M?^ S{$imc=86,je)2jγ 譤y'uXH.tKWXq;Ċ{a]WR[wG||dO[~jd*r); fQrz~V#9D경-S_}G1=JF-mzMr8'b+\+g4Vb4]5K7 n"6cMf'R{C0A, 2 v!4sɮWYaH8xxe)_P61F{HBV؈KL/<%v-@3\  r?ZP0==gj*r\HbJ9]uT@#ҷi ub.[:j\C@r(R f 1& 'B龲3?$еiAY5I.ɺ5hV$ۧ^[skj!2>Kd?u- Z p3Km|uC[CؼcbVs[-sX_Vi)O*{o3JUkqP<'mn&t6LH]Ի&m` dM9 7H<׊Nv;~'eO5mܑ9n: wO֤d~ǣyDs"\.%Sj6YN\0. <<\n5O2Gk>qcל\\ue~ `Fl.+{K Fcwtf 1H ue*Bf#5sDEP̹ ;╬5)ˤwPR,5(0R>w^ybӺuҐfSQɭg<;kI__T)&X4:MTEsMP 9]Lڸ@Pwtnb}K6jT1)^.[/ysըy`r5wbL]ZZZw}|dU}UO+2ZOwTհ{h%8=aA2ٯ r٢KҴVI4gK̵vI&;siiCSX=3wC6>#n[񤌋auN~քL4x{/GXlYf-XJAMe0іpxfp" [ Sg lF/˹N=>= ٽNcivV" 咧^Y hOb.0Ymk{q7quwy dXa+43 w:ںs$̬ }G3BE2:#UU߾u%I| Yљ}{EAVXVz _.F5K5:;hԷND#-c^^&p9E_뎷^]T_7nUYf#^{7V/r-4r zMsMY.yA%wsz rΝ`2lcm9qtHߠD$B{1@/~1SQKϫ:s7OAhDZ"ُuY&Cli|gi،s~nq[P'Y܏jJiF?~E+a!H<+A4ڡbϕ^tbA_ |c{9ƽhТ-̽0ݒT|%zڹp%N?`bS޸Jކcl,AFxEL< BNbцUxc'h* _3նv|:$8^&{ 6\W^7SH <.~:y[=쵧3K=2e:`rژ@% *뾂JG\Fk|$tLɥ/JQC71`^%,͙41l άymڜQ ۵R8Zӣ 0z3pm0&KEB -/iFxWxxsi [rMexRc*kʛ3˰cs5 fy߽o8>&_oCZv|w`Ei[4Z#2y:8q 3 `k'a]@mkq،uwbo[k=s<_7 ڔ)Cs# VXdn"4Ù[:D1 2[aW6x#BK< '-D)m˖L,(ΰW~wx4Ry>R1~k ? 07Ǽ] mvA,ZMZՓQ2%G'B>{Q]E P=G֊&JDZuʨS_%s\P}=XA@bdx zԗ: 6f iq"Z8Ґ3:wTV/XmF <5K93O)ظdɹUnno|N+;~g3N_:/k ɯ`Dž  D6"Y\AREL}T Cs rY\:1ab_>bMݚ?`{,WYB/n}oFN N*c{2ꭌ~@讗< h攑uhA2xwGR3KؖW\H~AKdrlZ!%I!YZi ,_}Z2^8L5Uj'oݍ}5swrmcu.q/&hu=33 I_3ܭV㯏uA#YLp ɟ_58ƥ@WǩZ|<;h^y9" %!0C~wm{,u؝3Pzc{4֘f6+ۍl1™ Q!> -lw#[Y_P3?~fU)"yd4_)$h/ש]_VK)[/kXDn‘;SE+ ctEYZ`l>0T>՚hݭn72&دd}j:g4 4r{|VBw IFQY}ڱ$z=DɌ./K8,&1&84+5;2Mv# Ytme}X;Zݻ,~*5C/X?$`~ ;St0ȨwS-ݝv[Kk>mY蝺="+SI:kT;%FG/F駢O2miV)jMt1-h@;Kး47@m#D_mvl#1Dq)h`tnvcF[h/KО3Mzjxu䞹C2r]'XE!EC@H<< ïs!` F_'{5:ܘa+,2d)L^.Ы *rlWP64YfN=;IݞMf=r;W٘ 3-u[fU?G=I}W9r=j>lNDJcOw4Op=MO^kLR¶Y7wUYQ[VHH{FAChfNCh`{d  UyBc檡EaxlCDL_+d)mh%]fdo2ɼ)5ᫎ|oSwUgw泒[n6^85Г VaEl6QN(3P320|Ri ]JJ=|pߒQ-TP[apO45d]™#E9+E!+<^a߻)a3fح43oˉPv}MmeT|V~)Imh%4&POoR4ImF8px '}?43mtHAK߲dAKb|A?ߛ3('6^ $V,ڸ|2;ȵ{S&$~&a`P<3HMǤ\^R?57A <+5Ь&668eԁN (>h0;xдBs/q~Tt݅Pſǽt!:_Cx.:/TcpwE/iuj ak,NHmn:Y9=Vݟ]C-z\oR9h^goN/=XYNPzu48(\#)1~lSAvn.~!Yrp>9ίH30}]ѵ|:.ɓ`.7Ttf k~+֫[VRA{g ͹v-尲DΠ դ&Tf悺VA1Iq`?nd~bՎ 7gߤ#n`gF|E9՗% fIY6^PAQa1 ~B{M9ɿ_H,xNX}rzEj=5m}dD*0[9:K n"Ӫ~ZljwCh4BKVfu (E([&(%FaKv⸧N){RdDSky6B)JPnmtth9Μ_yYFí5E:I>Q~,^|?'5p7GC.4 UX#Z;ΩO,8Z-csB"=F5xe{4T:YHcӃM%vv;n@z^х%^q43_9lQF&пM~+}_5;=>p=tgT5I[o#6YUͳ~h7FP LZ]d诀*ܷv‡30Ah- 2!7$̯4]eC"GeUKO 414QғϹZ$e03SRゝu?mK`Xuw|ܑo9WseK.0?wžҸ<=l;KW҃hCshɛ jN7ptQ>S1sgTS?G؀KbKFY )i<|t@l f{!d7T+7p|*2CO O>(n\d7:yH_B*\Su$Yptu%PdxH}G6DcPR%ˠkn~ϴ}\Z. 7%}w`fAA T'dRW3 ::#rKW{T--1.gI!1|eYf#|`Z'^/_{ρ%Pܤ䗸l6Jzd cG̜#-Gp!nA!12W RǟMI иx+-Qa[yAf?3G *td}NzE!I4kb*H-7LH~rvb "(9q{,k"[͕7x:7CmsJ$Oܞ7bzYTi8[ڷdaBȧ>f"iyZx %~rIYb sX2GrpUJ\ δ*ށ7s&$yr h/2%'ǐ얛\iBq3m@K\b$%r6YmE687_DJ{5mu Q$kMl~yOP~BUes.p/ ݲqYɥL!WZ+{2g XjkV<#jIM\b+ YLFroJ؃u"cyJ02uqІ`*8ߚFΚ9WG kٰ,~QMMRtBkhAG_t9|*'wEw^MЎ5zK(p }_)ok ɺ.qnasqmɲZV6- %1vŒ%ͺp~%O;AVL`ݭ/6;^bqFi܂jy8O;bf>v2-!* gR<)O<ܟq^ 5 ؝hxj}2O4(? tkuh M{%TGg^I6)rqG!GIm*t8z,CY[VG{i"泑/FUfX* <EiFi.f͏. ::Gy>93G Teh?y5 ۢJc#z5A3VX-7$@{O)$١MX5\m 0֫yiw[V4 z<]m(}8A/2|bxo=OP*vڔDQPQl*⏧$pQ S?zi0,Kzjmv 5( A z*BБwKSQ[Iׯ<ܩ0GulQ7e}z%C0hv-dN&" Mym+CΕt(yvg|'VYbh;7ް8d8\ mw3hj@g_IV3 74E[p%7shR:UWi ҃M7h[M?+ 4DtZXtMWo[H%f)%cףv+'.(-dy>>THe*jKD҈̛7Ϲ{r.H$`m$ t8]v:w?^9߿.-\/Ym|AzN}e\Tc}c"9Mlnmmʱ0;b*>s[l3D>u(~b, :LMqhPo.xZ7_ս1澈7Ldkm`#w7CpӂLT~chABV!;7dY6P s#״u^>; {[/j.&(n~u{˦ǍxF@*kjkd1#&F\/^+.k[ >g\m*c9.}gJK6pn?CػJX=+FU8HİN eIU5wPk sm7mF dinKōQ曭 &$=(9Y u9^d3I6eIyb@}#1;(Hi' 6E,)kAv1$(S憂D mO \m'ޓDlF'#4~&]=9N(D6bè%gH&&)dPPX 6RCg;ZgK l%jfJDv"e/H?4m;ꉦA{h=%$1\)e졕J *ٖRWDLx-h{):diUgr?cƤz 򞉘l3M2"noKT@l.涗K"<6k*6[KtWn_95Hrkiäv{6eEŚpoH:O$'7սoC_qPKVPK.V8META-INF/manifest.xmlKj0@=VU1q-&fW6X; F#h[S0Oͣ)k7vc^aaӠHѵHS"Z^%ۯɴ|.Ax.25| h;7GWsh,.dLB%Mync Y'@,`(Uq:bbqW`<0RO G?Fr7=^ ޛbpmaD-*긓_PrS4I7ZOHNzbK|0Hc-2xd7!ɧa87|"sϩ]PK5b9>JPK.V8^2 ''mimetypePK.V8MConfigurations2/statusbar/PK.V8'Configurations2/accelerator/current.xmlPK.V8Configurations2/floater/PK.V8Configurations2/popupmenu/PK.V8JConfigurations2/progressbar/PK.V8Configurations2/menubar/PK.V8Configurations2/toolbar/PK.V8Configurations2/images/Bitmaps/PK.V8褢 T- -content.xmlPK.V8*jԤ& styles.xmlPK.V8,)meta.xmlPK.V8й(@6S7Thumbnails/thumbnail.pngPK.V8V +Lsettings.xmlPK.V85b9>JAQMETA-INF/manifest.xmlPKRkst-2.0.3/devel-docs/Kst2Specs/src/Zoom Modes.odt000644 001750 001750 00000073647 11544160206 022032 0ustar00synthsynth000000 000000 PK[p<^2 ''mimetypeapplication/vnd.oasis.opendocument.textPK[p< content.xml]sƒ_VRFH)&+Is,%sI !91A0({V^_30$iR gwO{zk ƃFհhpϗ?6XL\qgcqxNFq"kC&F1 !T묰p6}ͅ3>f兛,1 攉 kgzrѐGqFQu ܲ^ɺHĊ| Ǹ2?gƨu6H? iİ"sM_,<jXTk9b49kd7G85GġM:xR!cK}Ǒ7Fk38 "-3oww0?ފVr/KI˒f.Ʉ >0F-T~bG/4" |E{_oUPoV3t2! %B;]G솺ێtጇJ\t7>̓;9<,\I {%4[;\*ܟI/dޏש$$1t*)t0/=ȐDdpfQDn#m8 A(fTX#.oxl ա4ӪhQ)F'r䕵s 戲ID_YFPƶxlJxV[2n]#hΎ{*%VWGLћYY&w$Q\h u8]s;H?uk-h A'_t*xMQDM_Uoӧ-L\h7g "YBԍ~u63_3jyhl:Tb̗3篹3v~74 >'{O)bƧG}O)S[e]!ztb7&!OlZ>Ѳ1/+S"[ Z:VHnѩ)Hnѭ H[ltjx bku`0[jݗ+4-4V.NjxrqKZ.\h.#һ w)f^.!/qA;wWPêqy:y1L뙰eA7=㖬60)UV5T7ᛡ/mllXֆ}pLxqK;:.cRHe!|;() (0ݲ:Jjg-tjf9 n،Ѷ͠urɓiWwA(Qא{r|܁}8),dhjH'ڏA7k?{k1/;לtF-{r@w5tS k^C?D:н5tީ{ kTCнN5t{ wk^C?h:н5tCS k^C{'5t{ 4j^C!ҩ5t@нN5t{ kTC^{ e?MMEq0E_yOxU Et{R9ASP%&Fs 4a!YBfY Dcd=i?+p}}ČrwڷUm#>I{vkQOVۅ{mhwkC>bgjwl>bgɾK&ۉ~6Qۨ}Wن6ʾ[Xc|FޏZgs C$ObД~1,AfH~D'qވ6#xuq'Oa͚.@\͑є?\xbC5(#&Ob/;%q=/qD{0h 54i>`jZFx55fx!c }=CC ue}q2>yJ=mBIҬ9~~93UBĺq*A}|!'-84MtiA KcMʛI  0a3LkƣԱ[ >x|̓JSMTOQP0ɚ!0MDk[a9pHyeZBvMb9`:%b昅2,;H*یjbsڋD]) ,}~]Inf"T2qԠQl ֊o%;"PQ nji۫2ȁisSNjܞ?$KeV{p% o'nT̗ꅈJ=$u`Ua/WgDD|GDxKart pD@&PfR$͢lP{E%רYk+Dh.Z5u5ŁW>}Y~E-LmS<ܮ\ y $5#&ݽ!3pD;<T218TKKgGa<gpZr,{poS5o1Tcs9AkR:L|2k=l&t\&= *QTvd3oi뛿Oz:q5 򕥔Z;IєT}8'&l7#.Rjn2,p#K^1 a~ؚr" "BN:䟦O_Cm 7?VW.8B%J6L^+* KSA3|fS_E?_)ᕘ\t+q>7BI:s)kbRkc3!"DMnѧNy=Ί#%S1ȠQ3+ >#35F^f~Օ_7w>.U.]Dg9}fᾹxGN/01=*Tmr܂-kzw(Y߫v/Vj.'+ؽI^u$rGZ6l@ˁEf*Lܙ} M-*;N҈|l8ʡ5_Ts.DK)\ޝjUuwm^1 ICVb$Z借vSRˆP%yl4HŻgjVw+-Mq3MBp /fGReaޟ 3L)&S9"KpCɖ2!27Q8Zs&LAȤ ']V0‘367Ӕ\,RY$0v̑8{IO$Y@IXS&E:ylE>R~paCs*oK|Z8wN{9ws?~~ʳ!ż\\<\H#V:wSe /CxCG1.ʍȸm)fGpH 8?LӃ,jD,!'-!Txd[~ݮ.Inw۝ \dic5L+MUn$,,9]!/02Β2Yl<q! WX2O!Y nؽnEoj4XE^ш&(&M&;(}IG)ߗ{S{bg'WUYZ ^ȉ5 $L(O,Eτ!}P gGI{89*a0t+]!WqpP&+UN9<>>XT"A=IS /`#4hbhX|Õ<kmaeFP`ӫ3j,H{Lѡ R. VXSq瞍8dAٔ ỊYy>U5-tY^'JCPis#^t.P;,4d } Sw|M44VVz;,j+W?pqOx1v州{j3:(㉘k<5+pl)н3pm)!`_JG( | S`Xi&(s,{Adam\(^s1ϵڨ.bMIEQfIz\>͂nZ(J]w /(F:kNZgvg%AP/8.E\<;dD%%nEGJeBWJ0 W:3s3Q(xlBل8Ix(}Sy0hPdX:pO 2]ebDxNWFܢA?`3˷ǹ ]ۦ&PKd5PK[p< layout-cachecd`d(```e`P2@Nh4PK'!,PK[p< styles.xmlZ[8~_Qi:302 +1BZ.M֐ؑ¯s8uۤ >\||۲\(O̸XECn/~{.lɴ.0D];]T+1Ts=dznҹB{nMle ۚ{ K-[P:St3Ty!x. ouArIRYV#ۂ/wʘjǛfKl[j 8mZ+KcV04dĞdŇ!$Q zU^'4銪a{ OUʖԬzrrwf_ j yB*^ vqR* jN'7g7,{J,|I L=B{5ĊURH>AAt,cjq'($5.h魯.Ӕ~vy~#λ5+F#(vTbJwr!-w^5t%Ktp%m/Fh9B 8j4:0dSJ_o7)4oYHPi&.b.~#32:A} 3Xۘb xd +㾖ԬYϣXN뢙Rj6II*ab9hWPz53d{MIrpH^}wJ6cL6芦0WT+8@ ǝ\^#Z`']ZΆqjN dXr$'6@9IJjզXIOqJxY cr.+eG'ԚA&Oe!aN4"_i2]+Xt KL؅T(Z|aJXNa%$pnS<'㛪W_[Oj yC)NzGJ[jږfzÆl6قЭvՊ  2E %o=XwU-RS; äC./(qءL׳~tn rw0ECCϗ\p[c-߰%XI xu7=aj:byް,,w_H[ 7LA+EPD͑qX9ڔ_KfVxiMwphEFUjpҩ@4|ZlEaVݑ=($͈t Q]jb%Ua bm&fm!;dNXWu8a=}=NXqJ&!)+aNe~H3[R݅;irEE/I%57ZE@ƍv9h8B&>W#2;07o)+<} EW}l#նS ~[B{pWeu0],e3~;7b|B'^w%b_8t6X| o^PKM%PK[p OpenOffice.org/3.1$Unix OpenOffice.org_project/310m21$Build-93192007-08-31T09:24:202010-03-31T10:02:5510PT68H19M47SBarth NetterfieldPK[p<Thumbnails/thumbnail.pngUTA-ww .%@N ,{q{߇{ڪjZ2k:JUYC^NJ: }w"#]#/%}\r>d0{(D`h_D ` &Y ibyނ<6Nrs'O܋ i[/rrđx~y\\ZDlqPFRt44((8rr(2*U-~;0 &2[dS^ E{9|mr ]e}Y?qgf!dt~˦12 \\p Rdrb:7y^Fp/q3Yq; `yoO"պU]޷y~.FNtA6!za=fl> RI ˀ7ُ/llݏ'ϻ{^{_o{U B)'K׃k&+ǥj*×;r7w3Mc-`8{{HY(jw+7Cc-xM'tE1CM] E=kcwcsA%7{f56L$SI.Rr>I}=)+-ELIFħ8Y ԺG|mU ԧ[/˄Hrp7|z).x ~xzidꟖM^kibluUח{{o2bߖ^o .S5Md _xhq@هB2fؿTNx̂>C<ӯ "E3cF79%ڪ4޻ ?vIԀ4EzD$:*َjgx:~8KB s ;@>/CHBNzDDߞoneQSJre?3BAɚ+ B|By_pٕfܾ1D^ o:DKfx,xMffr~@UDd{#G,!y W~A!._(P0ZRFA|-v yvGgS5=y}v'׿Z1mc^dq4ns'u/$#'W-ON LMm;J͔lӚJ8~쎐sITmHB㭒MN3sGU|(i]KRh<%o Lt{'7nKX|knW;r/e"iK^ؘ7'AjZ74:gKndNNge !\*]u;Mv^38Dũ+Yq&܁YQpR+֟z<9RaBIB&fA|?/L|ָzOq M7w,~`Qnݤ*ˤ}0ϒPN."p:T#~vsXXEP4\wH"jϵc:Nc9)DӋS$>f?n,tzt_,~J ,;@JPfx*_^ KB,p£buߜRޤ>l1iCdU @_mʐ}2X 6Q oݧ9lTkAIxmWTT(2 lU.~}8ETїaCUUtI[]o?eMShkjngJEj^[k2X|YjKB?TI QYx0Otp*.*-?"]Dֆh,*0 G%oK猸;^Rc]E?>|ál >;-f.FhT7]z7ijkSz!CSxʐBB8w)!+P~HAT!dJ63FKYl>^2D"~ 6"ɞM]ʛNT {nnӎe?4/˿;cU~1sp!\yg4Nј*ςgi5nF DbShUIG|1qmcDH)&x !kfar3-~[Sz)$\߽+*J3)>AGP!"R.: ;L; <%h^7[nX!.iN̎6e0꫰*oC\Ҭʹ-ŗhgʭ1z9Ƕׁ8ycIQ Uik1=B45R7i+&IZaP-1d+1'*QMZ5t9֋/`TH 8ҝ) @ҭ@1na\K@ j]%M/2{hSE[ JI}1:GL6:ey{䷚YmtWw./VfV)۴ EZCDNrIzDĪTܼб~0m9*cxq)2֣]%n+fYz%|k x<ߕ$k+z8xa} 6:IuىAx$JvB5F/RuY+" F_P0؋Q-qyb8v( ADg9Z“6FS%I)#N@8}r!5M9?p p-wOIc/@VS1NF2g 锢BLGmS?J!,`_`T|1m 2rڲVWGHrk.pF OVÞz4#u~h'm蠃h/(0=Hd+N!0,Ǩhm'FC-pժ.'Jգ p}q _k?H#9 /(}*V)C-ϑM;1 hq~u!`7qR(>,8Yԓ*Eްs{w@y0`sv7.#+p$&.l@c .;wS!<ǔG^->B,MKt;at_/~$%Ψ@)=`Г?zv|&咪(4),t3]F\; *D9ߴ __NV]c q0l* ;J q&5ΚH]",ir5%l"Bec:G,Ka=L\\@E/tl~fw1_ 8A?D:Z3Ǿ麁Mky]^㳽oayCRHv΃ZHnG8\6JDrk5Wi2 ݓWe@$;F`swz!B+^R[EI ÿ鎥f쐓lH/XTLf{dBcƄ7X6w VcDeEH Hȋcd8_0ܸbMe8?+ 7̭0!8a*b* /Vy˵ s{e?[PEA 8i<$ `X[^¢ cQsHƊ0 I;g>kYg C*iIKJkOc"`-^lrYow`841bA1xhH@Z1~wPBZ}WdcG:0D .7-n^$mt- y@V(IQ/m1 rK ro֯yP{˧/`T0rD<:tz(n 0x6<6>.ıw^IPiSwwHswŪ '_&ѾTԴn 0ɲV0" `t֨ƴ 1"U-X 9g ,x %eJF Kc+F=!r" V7M#?]>$MJ68Z~ؾeHR&OҳVf4aKĠ"|se[jh7HLׯIdP$:C5TGYFK| y; dUgYVv4 @n /'+%ʭ yetuZ7TӫD׫%2-6=\2&&`4 ,;;]$TZ%c2(r rN'\K.6wij+6s-؊X{^+Yf'ni ʠ}ҕ9qd1n#S+q#;rBnXekRӕiA1D֞Amk%KVMΘ+62CNtIC(w0a!{vhT~nu2hl>-OdoYmR:1,XA {z2͵NϼJЏ|aelEM.^27ۤ2[JӏNeօ?ǙJglf p3ǼrŘ}zݬ :y(鈤`,QTZ5# ccyNE 1w, a(xZ٪2W6RO3CZ;%#n`ŗ^~i:grj6ٱK{ǯ>{TĜPdybWA< d-׃ V:4ӓivPRN_XHvL3+6V / &Půz-BΉkBfLXtǃ[EVx5( ,3qEPP`(o;+@ݰȉs^P&~b̀)\N&3Qr:B'?2NKms]B~h9TŤdYS9pDP߹S/pTGKsTrrkL!"(=iBz`0#D0kp[hAg-|PS5_-eyw? vgWˆ놪%ĨϿUmsFCԝN=2;&4Rsxحm Z%(lƞPsnYe="V"St&eL 2Ze!,q C6އPPn Uen pZ ?f#0Y@%2σ(uAa818ߌS'qYd (JB7xۉOާ)le?B'#Q߃L?'6ႊ$h^OvRR1px>E&+lG(!i3ym<+-iUa7R4/D$sCgc>Y &8' .cVz=w7䢣ׅY"@jF2ÎKc8l9*iFa݊&bb3az*R)S,z|'_^ Ssm37V;QV5/'d AQ=?dp8:ANd唅]cK+k~iV-S|*ރeh>H"S';k<VX:7`> e<+z yX K:iz ɫBiЈ0+EGiiG٩g`P͒Rշ Ċ<$ҟaN`٘C%OSBp56"[rMt<7Bl踎L[+^VDm ԎT~i#uepiVę{Fdpb n*oh<yop= 2#rV\+X o8~HX"7BO\8LPRtCNd^x<(η]ME܄_m~:N=G[=Yv7UPP Kb}5mFWPEW:ͿPhixb' V&t͹4l5{xgE /-Ij2 XUr;C#K8w)~2EƳPZn3&0xQ%mSʗ/fBIƏ,h VKrpu_ h,~ Y3s1qQM U/]j*tNDNW]0iU19qIp@#_7㗬rRy03 ΏOʾ%Xp-LPĈS隽E_= 1$*{!ʇ+}?<+"8d|SQAl*5tY<.N.?#⌾ :ks74+^;0צ_IRH7TjrZc/7x?vd-vI(>ܐ9; |%)M &wn G!xZXb_OX0VDAԗB@g~JSUvc"u*iR0g2kmz د6vnF% 4<$RdKY /*;wCu,H3,*./,h)a،{T3ÎJ;P j'QG9~a>7Jظç ^?yQǟ \RMr?d ((J@D2tmE'0$Ř6̿ ˟K0꿤ne smgG574S J1in-}f}>;ݴWR3}*ldc^ v7Q4݄#EZJeo'e-=}".lE"7i*sL -+GBa00hFI.D5 +|$s7(TMjSud8M:k:6+Zgr&i2OrjT0MLvTAg:mLOO}mM$.Ԉ)*Cf`shc"2`n'^I ?qk\sĔI!*A^i6x}k46)Ag yR{#r8#Ĥ*.BĞ}NCu;jYd哱2$ L98tL4YHdt~DԬ97~#n<'|) )^9U '` &%xr:?lgF c=/CFFNJGA SF:"%@^恙#00fh.&m\zCL"k;j% ߏ:ZCLc3,447ڲuBWx 7,˜=+Mj_/%$"9B3pʀv +< x(9 4W39kh8d l١SfVNZ{9PaBtJೝH^މ -5W`<]m{ 2XLܥplDJHu\vC\1/)0eͿaA͕|q{_J:/Ov9m^sB|(K%yXzs3"o8_{JؽƯJ@:1Ej{x:g<ggK7TCIȧ28#~Croީ2?F=?lpx}w$?=ͧCS@_</WD7{/sg==J3C:%pF\-Tr-Jl!|FiIߓjv@.S)E^aJ{6W27ukQLB ̞dOF2,MK9HyJ &?{Ҁ9AL <29`h5ǽDZ3gћѧc߽~UDBm#W,q h F# 6}G'ԘT{樇w}pAkzz$=xnͮKx4q&Bc{DSgT`AunoȊ+h)Z`>cD}MAH :JC_Da׸|̝ԍh&U~XmNJtBjKTםeБ04zMW*˱5cN_/E}p.Y*NᡮQSpUKr6} ɚ {y=~A }fibQmaOX= C}1!meg)wХE{ \W2aiB,޺k7E5%HRK89mR;B8 NjB*„q[1Kt  ['F c4:Zur3'3Ь\I$tb6jqy.I.;|"+Ϳ *&, .E (^Q[bKN> } CFOwK~hIi~cD RtD!P MDl5c*5 fl(͜\{rmR(Oj\חW]@ (zhB3as{̥3z3bs:I/*y#)dck4+u {mt𵂯t~XNvbhpP GNV@yקYAt \& 6(*O8"Q@;po))Kzw\lmu q[K 2'$Sqqi+n|N::K龠 ]ܚQp$Uh@ETs=D:yB`c1?/փ=T(\ )Gywal88FSWT ঳Ow ַ(`2%_R-R_w6_2@$68뀥D^PU'>]Eۦeipkү˺GB:r uڤx$'#Rd`9pv.pu(u%F/><'8s*S|[^v1dň_ nVYJ9\7"}0܈*3^I&C k{^}RHl=X:T8swr[lqN3!S1nn2%|@k[ǖ{vo*e2]46Vsx1G,m1 B՞5kjZ|{ɗ,"?LQeÔR@c|+l ɷX_.Y>* }a-XV1ةd[}-cF{4T>wzB,𺠡B1#BMi6akN2a;CCF & Z)jq| Ʈ;Id,PzD5!Wt>&P]!ߜ5zRcp(sv}<6ܿ%9Vrkēt1h'ON2gd5Y"8-!Udfi›o.),$-Iɩ/ԯDSj8wzgyK<L~|[ya%#~d0ԧIk\)r=KOPvSu+a v]M|k}:ϨUfU`9.7 x.dodp) 2V{f bVJsT>Nv6U;+;޼N '>nsVçD/ 7RϾ!ܑ@0vcBqZ1xyψjʽYv"cw2iq@\Qo*"OfoAO7/u/${\LP#0,tm\UG-s;~BhOΝ"w%on^G.%\F>q<ʱ9!WwG&r8~oT2Fv L6I|'b,0ߋMyVG,GZƬvzz/K WWy },Z;RX2a8~uյYJ.|Cج6ym N?#ۤ"mdSuet,*L"Q(}\,~ -gxJۿenYoaSe&CE!w>V)NQrXc2I4}60Qa1rdy5\?k~LwwZ;Gίnw9~d~-[\\gu"eBT.N ~VT{Ι\>OJ&/*ny1ע{j7}?Hrٙ 63`*qe ~?9W-x풿m_i5 Jw~t9ƒ{!>L +3O]}LƧhއV+|nAoGe=Edۏ I?X>a{bKWw[A[2/9x35<^x/}6Eޯ0M?'S77zlyN{Se \,2ZWʶ7l?k>wp?qdxc+Q[N?xrVS+_%TDmٱ յ.)M{PR5Ve?Q[IW m{l_m{x}%s= 1,_!+:坎D{ޔ8MU[MsMP 0*'|*׵N*xsJhPKao%DEPK[p<'Configurations2/accelerator/current.xmlPKPK[p<Configurations2/progressbar/PK[p<Configurations2/floater/PK[p<Configurations2/popupmenu/PK[p<Configurations2/menubar/PK[p<Configurations2/toolbar/PK[p<Configurations2/images/Bitmaps/PK[p<Configurations2/statusbar/PK[p< settings.xmlYr8}߯H@H*)CYfHLjM h#]eC6 f5-ur|y%(Q>xW5d!eҭy[lh$HS` -]fKl"\7%@7Mn[f,{\=x cfZ.WחիFQM(g|~lGUnȌIkj߻5u D7ִT6V^{Z+`@9ZwꡘEafreΓC\t}{}?f_կM/p5 : &4L0鵌Jl+\ixI1O_X\25Otڜ^g6[g|ܻ-.X4?ͧ/TN%։d=ݨńD&$j?YgLLE.Kz>KUW®LyaނVjA&` Y 0I alFm*ghHaiȜtT, ^PFx4]T`U}b/qL^K^ U WALMK6^ KT@Ծ ۂ7M["D0]͗(6G˕64=,iz9RDS΃`+v(!|é Hj2ES$d1 ,L!E/k d,MN[Ģ͙DZؼhP̰-%Ȧ.lK,ܜ)ۛ :/%G(=Q)#Ǿ~(_d-ؤ<DžߺD2:Rw[%'}Oi;9D&q}璠ol0SSA)pIN χ3.'g8ms>ptM9hxg4Dbo= @mPXWr+PWnOL&L7*9;j.aYp4Tv& hcb?jYZ^3_P]WhbDXJA4FL9(Vf`rN],x!5eB?A! 1{ m:\a"^Fa/LrQ|(-G.A6*"Z 1v_vѫ7걯_PKLv5  PK[p<META-INF/manifest.xmlMn0">q˪H $XrƖ=FMPEUAζ{㟙ؙ>hKx.Dl=bA6pV"z*-JCɪ*vH\~/G"m0}]Ű֐s x)T'b*Q0Y\wOZNhLBaC"i6ƀv 6r@qV{c;dxznGM|ڹ,5ta)A)48L*z;_+ 4c*E7ԋ? [ku-|i$a<ʟ%D?gu1oaF_JJOPK!c[PK[p<^2 ''mimetypePK[p image/svg+xml Plot Geometry with shared Axis. Requires Large Label Region Requires small Label Region Requires Large Label Region Label Region If plots are placed inside a shard axis box, then their axis will beshared if the plots are aligned and adjacent.A shared axis box will have the options 'share X axis' and'share Y axis' settable from the object dialog.When plots are sharing their X axis: -all plots in the shared box will tie their X axis, so the X range for all tied plots will be, in all situations, the same. -changing the X-zoom mode for 1 plot, changes the X-zoom mode for all of them -if the plots are in Maximize Zoom 'm' mode, then the X axis range will be large enough to encompass all the linked plots. -on creation of a zoom box, the X axis zoom range/mode will be set to that of an arbitrary member plot (eg, the first one in the list). -the top and bottom label regions of the intermediate plots are suppressed. -The intermediate plots share axis lines -Tick marks are still present -If the plot view objects are the same size, then the outer boxes of the plots are adjusted within the column to maintain a constant Plot Region size. This is dynamic on resize. -'Share X axis' being set does nothing to Y axis sharing, range, or zoom mode. So X can be shared/tied, but not Y. -on creation, 'share X axis' will be set if the X ranges for the member plots are the same.Analogous behaviour applies for Y axis sharing.If, on creation, neither 'share X axis' nor 'share Y axis' were set, then'share X axis' will be set.Tolerances: Alignment needs to be within 1% of the size of the Top Level View to be considered aligned. kst-2.0.3/devel-docs/Kst2Specs/src/resize_window_box.svg000644 001750 001750 00000013054 11544160206 023611 0ustar00synthsynth000000 000000 image/svg+xml Resizing a windowwith a rotated box If the window is resized, the box is resized, but remains arectangle. The rotation of the box may need to change tokeep the same relative extents, and to remain a rectangle. kst-2.0.3/devel-docs/Kst2Specs/src/SinglePlotGeometry.svg000644 001750 001750 00000053706 11544160206 023655 0ustar00synthsynth000000 000000 image/svg+xml ViewObject points inside the plotrect are placedrelative to theplot rect. Multiple Plots can share the same Outer Box. -The PlotRects must all adjust to be the same size. -The first plot in the list that has use for it gets the Left and Bottom label regions. -The second gets the right and top label regions. -All subsequent plots don't get Label regions. -All plots may put axis lines and labels inside the Plot Region. -The axis lines and labels for all plots get printed on the bottom layer; the lines and matrixes get plotted abovethem (in order) and the child ViewObjects get plotted on top. -normally, zoom rects get interpreted by each plot separately. However, a UI must be provided to allow zooming of only one of the plots.Potential Simplification:Allow at most 2 plots to share the same outer box: -Would this be easier (including UI)? -Is there a use case to argue against it? Plot Rect ViewObject points outside the plotrect are placedrelative to theOuter Box. Outer Box Bottom Axis Label region Some projectionsmay put axis lines and labels inside the Plot Rect -10.0 10.0 0.0 Top Axis Label region Right Axis Label region Left Axis Label region Font sizes and line widths are caculated based on the width and height of the Plot Region, not the Outer Box. The sizes are calculated in double precision, allowing for the desired sizes to be determined without regenerating the labels. All dimensions saved in a plot are unitless and double precision. No reference may be made to the number of pixels. Single Plot Geometry kst-2.0.3/devel-docs/Kst2Specs/src/Layout mode.odt000644 001750 001750 00002423063 11544160206 022231 0ustar00synthsynth000000 000000 PK 8^2 ''mimetypeapplication/vnd.oasis.opendocument.textPK 8Configurations2/statusbar/PK 8'Configurations2/accelerator/current.xmlPKPK 8Configurations2/floater/PK 8Configurations2/popupmenu/PK 8Configurations2/progressbar/PK 8Configurations2/menubar/PK 8Configurations2/toolbar/PK 8Configurations2/images/Bitmaps/PK 8&&-Pictures/10000201000003790000016B51FA9215.pngPNG  IHDRyklq@lsBIT|d pHYs.#.#x?vtEXtSoftwarewww.inkscape.org< IDATxy]'HUKWPS5h_[j jRR!(%}wv/E"DΝs;=wf}=s>߹g1wGRfv/A_YDD33 X嗝-?"""9h+f X  NkD`Rxx;wfQXP^53[ں?"""t7f=*տbfOc[<:efDAjkV̖.IM4꓈HL"3_-<ѿɱ?=A+cgo,Z㾈wSX㾴*摯92*ff.2.~aLDD$N̬p<O~<07wvF׸;"횻?>}8 ^rwVVI-sׄѷoy ; r@%yRl JNv/jZ#m>ZkBegfK%3Ny8ݧVqv[I6kVE2=m'e}N·ʹW^<3Mvw2pLK$r388)"u,M5ߣB::[늈H1u gt4uZݧv8<43#ix.H/3z(""Mi[5Ml0 /if8p7pT.֌-Ax"Ծs3{9śp3lHwC oL7Ow&?> X/m- ǡִhf Z'cʻ} \O֪Ҙ-U嗽Tx>FV~Nt3{S>ʸoI]9 3{:oA%DD$Ń0Z9ںW3^Oз91+ r-xXm.`o@To1{׊f#00 {Qע&#>//|mۂ*J ?o5V&$B^F`< x>[C=УG=m:aZKafi:u77]h݆9kٍf Yo3;jV^nKE3wMٖK/٣fzKf+>^R}4 a@\by>3c%#Fƪ(n3̎r1ےQ{)XLtf60}1\ fVîn~qdv~z @?`Q´@5lswEH^qWQIB5SH,.fG\bfFݲF |LXWޭlB̲^K3Ni}>n>I_K6[0ޫ}.`{tlf6a68=3I3N5 a}F;}Sn+`wv)P$yN !G$5N:ݳF0/N680 ѽ}q13kZfaJӒ)Ӏ<{QS'GCWH7Z. \dsM y!ٛ64wW&})oU^V LܛifG)q)p&R%o7wDŽ8B4?!یI3xNw?Iivw:&i!1?""|>|Ce^#}*0)z_#)Z-^ۚUЊ5fy.Iٚ 7Sk؂>NϸL/|so/X0JKk[ .]X #Y֚=ON+^sSs?Pɿ_~tɸGH ﹁2?عɓ%gA=У^&w0Pk4l73[U\ s?ExS b_Wɨ5Z> 珈5aӪd 3۞G o>abǫIgp}%U͛6XݟB>$'tlvXwYi'{/`]h_B5N'{:~U5skfF{'3DD$J#O֮] |jfwٰdd0]3os[r]w00͖fgK[# 'y~_K. NfO3ۢk@ vºw d+m}0M;͞7U14`[wf4ͥ[RNH{_Y~mf-^|@nj\ݟNhސ0 DDD"$x_ލEGfkfkdDl:+CCZv̖!qhiޔ9MnNu/Zpm1wL"faG{1mtI#llfd{$llى{.tZ:bG\Tuߒ^<(ިjV.yךkH]8^J>(#UZ؟ (:y~tt.<;NnNޒ X5!L .0!;u%!rQPYlUw9=Irj(һ1U 5ykypUq,UkÚrڲeJf) m|& ;Ű 'fuKd}<!d?C̬ES~"=댕z_?9mۚY֨lɖyD^uUG;+m>J Gw/tNcY-zN[pYgdMY_֊GDDNg>PxGX'HR56i{vKvq{> bi" }Us k l7rj]0975`pLwOrk}H1Kr9QQZf"^K:V^'d,fΓ4hkTDD*ԩIݡ}/f#?%v+/8LVVzTO&yyoVs&3O1ٻBIN[%1/Ѱ^|=8b,}q|j.bf9רTS&y}teC ө4g߅/ &{-K1#ǫFsX3 ͬ;u$|Ӗۗd erNi)ʘHS3W7}0;BߵyE㉈tZEuS 5~ ؄0RWC!wڢBʹa_7JyυG7(JvkM o>ky:9mEǼ$)Яk^st,YKU+5 3kf.YVn}1ࣈDD:-%y9..1;>Mafw'Upj&BsaH?o̚o|ߜ$of6kz\Kx/S -eR.5 y-5aTO׬Op v {GR"T?֖l;s\_;fX}l.ɋU~ד#VCGzHU)ٴ:B]+*+tso2k-vAGct1$O=hoQ%y""hf l9(5m0=ӁH"oّ&iyJsjt:xe*l c5%y'`K.jf?p7{1=sTα{TՖu&io"_O%ust0J>%,\cD֣ˆ5eK֍4lb_O%p3+JxJvlm^qzӑZz֑>hn$/vJՑ^""RJ3iflF+x-5:ӂ\DӜS֪/Ps} 4oYڃ*UGօާ;D-& VRf|U%βB:RGrږY/ڟ 1YL)cgN0fv~Gmݯ>9ݼFED:[ 6,SVGO^9eZB 2zJ9tN 3Y*{w~FEDB5<lfV]w*cf*;RD*4̬I"" IfVvffsNKB(HE,+ӶrPʱk}j_NF۪fQzԾ)JֿUcRfK$#Qc'Kw|I[ǫ[إEJYW`Dk!RӀmY`^'tf8aOs۬S""%:C78NQ qpdOq[VIi:&cp[5F3ہ9LN>82甿kR4]0˪UI=S}u?@moi}|.産ZAhigiGňcfk>2nT,7̴{ΐ(f8#yp@ /=x+֮0+idz]{ Y̬Ue2Odl_d<`\ՌJ{u;A#a-+ ^mlULْkw5afCZsd4jnv$S2^,I9fvIZ2pM48_h}20-'poKA%S,kOX ߮$SG<k tGGv1[1mt`c=[xEͬpiy5qɿ"MUr(kzGw)e v0SY$x2gEZH֤39ZEz_ZrZ0fdf`3 KYv5TVDڡz/P mtz\̺?'L]Y#k[QV$4OeI!fπ f;$onFw?Yꑑ\OO9r;0v 6~ ,T4?wmN6ty +)pV%-I#*7<^hۖutR KOxmL lDHj2j~ p(Cx!{\YO{]stdz^Q]kԨLoa_Jdes}X{/\?ZLwڹy6wv\vmm\,[4 ع#5afeFW+2d1c*p𸙭^?ܽnOʽw7[v\@//o]NԱ^ t=mN$#+SKd|"ጯ >W}$ sLX_0O ^/ORpU V}ۈ~>9*ҵxc]*dq?3~=ᵜS>ß}Y?yޯmE=輏6@o&1> 7YO V%\&o/U<Ye_U%<]+xA[ !{DֹS#o%XS_!;){]]%7(+$/QU^P_kO"zx?k*}^{gqwoW>X=Уs>jM?? ]DR/ ~y5Z_$=<ބ)1vq B]-?HB, u;-qwa`OtL_WY7> gE+urgҍPjEҧlYbw}ON]rg"r MHܲ"Z0#&kL`4ocbfaff]G()1 +k={*S -_-"*m݇™2FdUI#\7Y$xZgܽ:}G8P-^ L(A&LyܔƨC؅u0UmU8BJï[{ ׼HJXx[vWمݽ#fByIX%tLlgBYMvx'~L Ks>df Ü 3޽;-:|,LT[o{zDu$\R}e#~"|G0=:X3MHV l8s"ׯߔaÆ0jԨ멈Ht$ODDD:3KXfQ={ӿ>SZj)LIkVcmeʔ)Sz a#5y""""f KgE-q}83f{{ә-^{-/"mfFϞ=vl7#"R%䉈H0e PS`OycfwJ5O>|?A1}t1N;t IDATD׮sJ;wuFG(k[Eh$ODDDꂙmOwBa}_2kO8s9g_|q.Ǝˮ(9r$C̎{i 䉈H]0 Z5Pafߟ={aάɆ3>o o*aD&iH禑<pvuE%vy ^2cǎ-Cڊ^<TM,HtfaM 6rJ&*vV ,Ùo+/oU߸{J%"RJDDDKjJHJ[wݻ7#FJCrM~o̶2WZiF ޗ_~ɡ=z_o-؂Wv""4'"""m̖^-kݯ* v\KXx9s93o23d|~+`aw֒AD$<iSfCO'Č5!KIxm|O YXqko,"R)M0l_3m8〟:1<3v^Ao0X ؙƛ:g.]8òN(/0qDD<)uNaÀ)\V:m.4Θ1cXk1c >hh88x8pϬFDDDh1'">0} IՅ4M"ԫ[/HYw*͛`_(YS^$;+|cfsx1S.]&͚5w ۿ""(V1k_`>`Qp> SF}SNy8K5urlpaЏ+"ZJDDDŒOX\I9 Buw+K؜_J8´}-NhL%w"ҖjHB}#"$wƈߚ߁K,LsYɹovis]SDDD*bfY&7@w9fv:aT4Mwc%x%6jNI2wl6wPD|AwGC(N>ہ}sw,VR> ;еD0w""5y""")AN/r= 4a}.@fnF )9p$ppO[D$%y""");)]@#i );<_/*H䉈tRfpNE94{dw_W%H< ݧŎ-"R+]SDD -E3^` M %Y= |ifW5%uVI˺EJDHH'efo$K(}ل0raJdB-q"5pW쵅""6^ct_Ox{FnNFbޒܭ<88td.qp<gSf$J/oӀ_6TY=/3jQkn!l,swqEDڒ<:dfÁe'+Gk1>vlz$ODDIMlwoa{rb/G#a ^8""<v^&L9bh!rܥ5~t/kvVBr\̸)%vvۋ+"(!3K5`%MK]05r'= 8!);v?]8|¦2J?DVR'""RCfv a ZGM}zV Z<pbl=h`3Bɇ>5vlLuDDDj4pAV~EÆ>\rcMbn~VrxU`0`w/vlQ'""R3ۄ0}B򆩈Á׀/kq$$wۤ4O%L=?4NK""R0%y"""Iΐo$)]05r)EŎ IHhg H$ODD$3[5fEn1!8[8`eӀ+Q^̸IU J?ǎ%""FDD0M!>6K}jCS.NvŌ[phy'""FDD3 #z g)+zc3L"l(0 \{RDD:>䉈Hff'꾕nf]}fA1FH6Hi88 ] l \O+LFDD 䉈HffKz?W@!)_ĝ_Ek G$gU\DDU#H0f-k | <l3fpM/ ߒ~L/q4p9s<eKDDFDDM%v&D1[t"f&ҷ'[9唆Zs䘱SrYɡ?KE5y""flQQBͷ+ ^mG:280v93xݟ.iv|~$}yq xdBw"""-<i̶n*;ge``^LVZ'"ɘَ5e].0bfJ`40 s;%Nnj#""h$ODΙټmɡg/~q~{Fwj)'׋̺F+7*kZ4v,F#y""u̺?qsJ{qv<X!Ow1ccdc7JDDꌙmNؙ%_rX1F,r8B!c7yc=uD̸"""핒<:bfeM{8 X*(uC9*""Ҟ)3f 0 _1.r[>#f$PZ'ܽOX"""6^递Q~fI``G,rk ?}fe.q78x"""FDD:dzp$9, ?4CW3 \ oWDD#P'"ҁٹe_,++5o aS[ g¨n ;r&xnƎ-""ґ)@`ӀˀqF&.O$q7 8 ^Ҵ?;Hњ<v)Yg`)pfڶySNy=3n{{ x"""uCIH;bf 9'7@̓r=䮼xf7i*b.""R%y""턙-<*kR`%5vzra^o:p4L 'Ď-""Rϔ䉈8rb2A@f']! p B"1p<@i㊈tJDD@2շl#[% cEHF v5 ƌ[Yh'"")!3[Pn'AAqW!۞?gjͽYDK8GXwyqEDD: %y""5bfg^m354 ” 9,pON? K(pO[DD3S<HJ"Svx^@F#e.Nv$l+B5C㈈Hvl̬o١un{KNlC3P<06+(;#%ǎ#"""4'"KڷՁ}.k%cޔ0r~Jsic-Cw[/xءJI$OD$dro ;ܭ5p&0ݿcw^rl`o.Ō+"""S'"= );|W@ã)|IYD ԗ LC]t3d1)"w L?BrR)d2b%5P'""Ҷ䉈T%yG`'=w0rܮK9e

    Ŏ,rH^'rJ`Sp\LItjIlYӴcKHFˍ!ljrGOb/F(Vbt+Bi+رEDD64]SD:53[PTbߑb- ̗r#~̸Ikv%wMc<4l)`5R`szTwq]0t/g)Gb-?anw'"""mK#y"RGB;]}! 0G)wBk%I$|5pa]aREDDm(ffÀ h\2 IDATw_`́ZveBXs\WwK  l&#"""uHI53 (Mvv ,apGNo7_. O[LĮ'"""퟊H0~ffeoJ9pDV466)MfW+o J<lCH $ǎ%"""FD3̀>5rՀm\5\EXvFSOJwWDDD'Hef>QB*0N.Ro}% LQT=རe;83u3yt*"26 pVe]Yw,w:`wYLE/UEʎڰ `zS2qǙq%qN!(w Oj:"bX(#=V` Tbk(S88S7n8N\lW2 =+o,~)"`^nU88δ9%K,Cq`NMfdy8  BU\,qq >8N=!jv8p`#3<OI!I{3t%qqR \Rt 0,(yŢqq+3y3""}1T)X84\{~Ky pY6 $6qqWg*BDffTD6V}*%͞M9yh E+p+p~T\qq.+y3 "yd`e;#k 2Gl^Xȇ+"T/0brqq:9.T+xW-HDGsfdy8rB0 ~)sgEtqN8S仰vs' ;3kt֌,'<=ȟ x 79ԳhY88W!"bEpU=@U_ŀ>Eǚ 3gdy 8QU(RnVg,qq! "G`KzGw&5!sN4@_F0d/, ],` C;Tqqljp%q" #Jl olp`,wc]Edi`g|EqqǙZqsM"X}>YNJ? +!qqgjg !"bUտDf6Q H'+9\5w>]ܤ o| NU,K88Ԇ+yabہ9_fpY8ؕ*'1Xs"2~6>N.Ro8835ӣqq:khQF&"ˉu+T+xaS +"wcE"2RMUTtWqq9N V>\Rt9Y8؆j*Ϫ:HA)jM%W+ lѲqq%\q:x@U'8tW)w[d)7i.I` UT\qqi W?kG%88TUvv_ \ 88N㔌lFK"s#L[/#+}pU4 4MQqqÕ<)թV^Rg$"cZgdp@0Mh88N59NAt֘C1Ë”_gEMڰ!p=D 88N}\sv=?3J8X!#˧i<j!8U}d88N+yD_`%  btFh $]g”TpVx` ,Euqq5` LU,;{`,.U 9O3$ߨ?+R88~|&qrfVWGXr{{607HA~/-nqqx|&q "Coשϓ<3-(Gfdy57T Dd(I[T:88mÕ<ǩCqw ?J3(/g7ڷW$."c3v#T(Tl6U":88JAD>ډ$ UYÁ3<š@"2T RՅ88t &q8UU?.Z881LI75T/0}Fr+Br1H`SU};:(0v Yw\88] j'[ٞi_LL8hEGDEa1"6#Dz@`4Qe+:0|;F;-݊`6_U88MP+[;)W򜩞0u(=p )w HY8؍Ϛ7'sEM8(ȏysm}/l'7W^Ԟs"Dd+|`@U6u5DdK6| |yp_|ǙDl %TؚYU.LONXs"#pC+pIw5 6'asc^Q^"/%7.L^"2LY銈V*>R`8ݷTgJhgDDLb>*QغiQ*+LB0^1O#T U1 UL&x#/-G1aqF*NJR>ZUl9k=]O`czc!`[o- '"۩?Ki8S*9S+ Qཏ{hA": `H@kg#+;~uWΤES`gUVfU8UD.<{ [+ M*h"r,^vf͛%fj \ ՝]%"E&8N7Gg7qڋl*" bJl΢E}"rg x<`1Uݿ$o ~fPreu6yMz ^LXk=p; UXHUwLJXqJm-EI91UG UHU E,Xf3ETU}((0K2Ybdk,x醄gTn ]㬼8Nƕ<[""bV(Y" |lHU-l퟈E<FUG?m,%DjZVL^IF889ݎ-5!z֡SlfV 3=ceVUoXz]ԁ|o ñ+Iߩ%_F:"fEd&p4g~\9`SOW',PU&y]C230g_Dfz""qe5 )'ޮ&U=WQկ;CVU[,\s4" X xNUP "r1I,`;L[)#l߹%>gNҾEvJ#FUNhVpx9Y S&ԭC~v̅" ;2 0G= |^ǔj+YDf KFȐDF6OU,]ͱ>![EZU+I=;Pm9s> 6j|q޶wK&^]Ddlm3,q rGשc{`Q)aHD8ǞcQ"2 tK ΋xݏK9;7)"2=s^^)9dbU}yCj]1E}2IDFbίՑ?KwK`U_H Mֻ#f] >gp+?0F "fqmš] ^-"2P]YG$6o >F,U'"sbqQ~~u@֨{9O{C]c@O-G*~!\}-hGobN6z^E#+ UWBMzu`@_|8_*||Crmz]KҾNFkwy69^ksزask 6;Ӿ&ͨ9I1 Zu\='Ty^1%L+kXN~)9ρ7yɸHS2eun $}<ѝyEֻkcjC\:8->3bqTj:g9֨QQ֑se?Q?Q!mE,U^ m: M IXSyŔZm<9 Qs!̆`sOl$-|83`'{`#ߥia5p8u>)1@,TE1rV21%sR\`1Վ!I]g(wQz4J PF_| ,Σ̤j=OMup -cV&y,yiwVRn49#l6}dVbZ_K2x9lZ+ vMʜo~ kd/}P81yW(wTλb3 yƔS8>5y *Wq2U8K8_bj4M~ I7 \1w`z埀Y,\Muzzmͪm_SB+2>SDJ ɹL`+by~+c^XF23ȷKTWee<eSrAi).Mʞb=bQ9jԹt$uo\{ *R@-7ߚ2LQʐP50 {zi {йc:7?D`emȸFE0(nL oJÔǣPG@#yrW#TR'Qm-fNΥK_0CsiŤMb $>-X;ߦiy ?5clѐoX 5V֏tŃ&upPi=xj9F?71 D d:yWz@QϬJ> ڱ{Ҏ-r%* ~`J$JV/Hs:zS=.%/;2XAE ֠t zn o gɳ?9:y7LdܞM lvi_~ߚm,[o5af<%Ș5OGA+ۛIqQZx1:oZ31J3`hY%/}Y5F(c㯩1{^̯Fy'NFe$9d\٥ATɛ5fH*X;T)qv9*գc0J~"Dr.).s*#؆ZQ`o7+*y ۠,T[LAHW)P2dKc8#ks(yG>LMBk%|a(J^: }BqAM>$sP4+y0Ex:w`˵Ĺ35JOIuNu_FQoMe ͷ-۞H,Y13:0>xv$$r'gt7l].դerh2YJUV&Rg56q~ybXy+38W[m< ,odv{w?sa!9 IDATRf & ZɛLpSߚeVoY6.]2gF>IVK#sbƆFoغ[娷'fn͵~Yʶw(yG%yٞ~I5=ICE*J^:pirR Lfh=+_W1<#scs2pkf@&S%/)?QAr95)wUFTKΙkl-V\z'nL5T2X~J^Iy08x NO's[NgT`! r%U6Q&V/}2}5ޟih5Ӟ̓;J9w tU[P^(l!u0nEUA $"y;"15 c){EɝP᪺>|%y-V&&|9nF&k,׈ R}rbƥnm`aD28yuysܴ-:$c;VUwUյnz5z6F2o?9J8^݇uqP>ϽYTn*dpFu /h~xhgPD"sw RmW5C\2`<8KU:|mzgs=P<ڍs:j.Dd6,`Z[uQHqy^"OUǔ!{ZBU_fXv?%;p=DdN8>(ou_MflnM㏱DpbX?I?8IQ^<}@fNBU?5`oe**Nc٥װi<"Ĕo16#5[{uޘGJ"IƊL4O{G,Z"~ a̜i|κ ́ͪ,mit_moQ|y[epqqyYϴ<-c 0,Tj1l."3j8~2jiw|FK۳*}]l[Σݸ甂,='j!Y^[3NrL~Ev'ܕZD֢zld:灓Dd1,؇j,9̕!"ytpj""}h*"Y j 'az|w) m$I?rkSLBWR`/Z9{$fhŴzϙ+BU'.s^y.*[USpD/VHl]j4X|)v41Ӗω9c 3\sCD~ ޥJ\yΫPՑ"7\m\'l6Umf`ٶ܄XQDS)W"#$Eɛ pST'},D|rۇ߾"]f̴֤u+yNN샠0 cNvsrft~ŝKSj^Z1ovl/DOZ0("ꄤh:2kB飪߷|V{\yd =h|ҼY"ݩaTd""&KֽYVwDX< c7c.Dd&t(S#xҾYtƤ5+&d|)cۥs-d*"[_zC::؆ mU0X8JĖ `!0lg[k1%l=6q@afƴe=,o~np)h79!"3`3u$*QG޴F܁)w {]XkT]Y橰M3̓EulAⴶOg*el9i @Z3]ȺV͜OYtpO̳KQZlr+ #g23p1Su4EX7j|T9tinzM7tTxC.;vBs晷ѢMƾ֚hfTU`Ͳv.d녭6 k^f| ;PUMYitvK>Z3X)skig-ifY9EwZ_gaV EDł3[wt>SiY1vJla 7T[J}ej:TuyHϷ]< Lk3-w-Mu}&Dz 3?jYN«13k(o{k^wI܏MzeFXrfi{p7g=,_Ef_j" l-IiQak oML5S.Ezx56!"+a:):XPUXȎ,%"C1PMfkVTmPaNT]GNȺ"<*"R,&]#ڑ[> OƕaƢfm5"Q~(tp7#S/^]4

    Uu<Ճz3zK<CUEUL5o"gt WQc&+s2%7Ui {|/{kDD.CccUsP6-\,04I,"|2fa&EEdћ=8% _#b[欻+"Ec,d<‹|$9D,hJ[&Qd LaT;Zrbe- HMRwؔTeXquhR=4xZџ'DŽFҍX !"CE>I"8:9;I.eq7NPI)rՍq%iw)"kȿmS_\U-!ޖal2{Ϫ/UvzNtƞKv4&3#_;u1jډew?ߌFzո9$} =gQrؠF|bf.b樯Fymco{kiPfzmRԶr2{^⃂'㓀C.גߋ:*izR x>Yo'6OV׀MrnofV;` $rygs7uh_.ZsT`3?Yg|Z;r^Ԑ*yk`% !<{f&&y.R8Xz,\X! JϰYݰu?-j|G[?, 3=+}?-Dy'G}W3]\gޯ9m(xRf, ѵ&ҟIoj%ߎr Jz D2G&"gw2#c  ˾|fvQ6b -36P;KFٽ:[3{[uLq9ZCbHxlT(u JvC6mGk!k{}ΘT8KrֻfTXJs^/݉/q٦!GIZwol-cu~ jПT9~Hܢ،G؈x;͍:gFnQԱ2fz؈OTuM-FGa(#|Xò965/,Cl5:U:g%1sɡ`N".4b>@n/Li3CUk97oĻV(3шU5K啓6: fj-ͰgsNU}fVl^-Y9+ "c}ВXȉ =X0&[ {LP[ֻ7k\רܟnsnL1sqf;ǩ>m(-66;6f@;EkF#mo_6YtbL~ST iƣUPߒdP5UMck d>5v߼͖ܤXHg4Gi,Z֥/U)!DdMjGC83~^5YaDr]xw•itiÌ~z{t|~̔-]^=?`i)aYj.؈o`2:8N)yTǙzp"6p>6B>f>U}H/F[}0ET"--"i̇hv'z3WqqZk`t5$Ȟ~kR "\4MMDNPT0]?[3&88ӝihmAzSBDd9- ;%To%(x;bէ`3z`ꧠ?88LLTDpkŠ_*[Ub]I1}kmC_lf2vqqiw2c1`T5uedySnn7&&m"YUG/88Gx+\[a( ɶZDIb\^.*˟8+yS"r# ̱Hx+ðYYN=w({جժzTtl&,Crq"aR.S}(cU,J~Td q:7ל:X(p%pl ^td,c݈"3`1e}oElU Vlq)a<9=squ#=U?Q:јcU΍;r/[ܤ # Vqeu7"2'1iGqq f |§jD7H?LkKx|& "c&B U} UGaU~,pѲ3!+< W 8ƱӀv`[""egř:9|P.dpCXxƱw5J^GDVDJS̅azgdS,A((Pǘ%UѲA 3wVC"";g3iz\g龈25 "2FUfM |Kn:o'L;/Ӱ]9UYK`fPf$U}ك͢Tʢe9& mlrLADzbO+#^L;e/$l7JIU*DZվLCBr"B|?lh`<YVDZ-; Gգ14""1a@Ֆ%,2ID΍"TuvuDdp0YxxND~Y9eTuRYYID?~\,+E`%쭪(Q}!{84.R7;UN749lIo:KLv],q20Pt@X'`U};x{eo B<XRU'-qiU\̬^i,,Su.S}8 a"v{ӌKA V B"Z)q)Us8& ^8%J^""}R/sה|L wEq5f3oIqqg[KFDzȎ" rLU?UաE*x" @U+XO3 Š`=17*iap*)46NDla7~"YyrBl Ƌ0D'kzv<.HsE+)_E1OY|&(& U,T`y_tfp];3R} ߪ||OwkU9rU}7̖:5ʜ'Xsx a =E ,HNyz>lc,"שꤼ`G9Xq:.s*"c5R㤉@`o'@>} \֩Odǎy\UoINU:r -ssHz];TUթ^Pտ|eR [ IDAT$ܙBgѹzSs% g^&'tAE$WU/h}mEDvmeUFTO5́=GAUPؽ0 "cW0'8'4G%n lU=3,X?C:6eRb~x+TwMugc=û`X;esaKV *7~fؠ=k/|kbwx k$,[I_.N)I;`[L>/Avo`pS)p_F9:mؚvc%N a^k-_ (NUl +`PTg_r`&ۺz&`iw ԩ:m[F3Y*Go`<|_-:uC0'Z>ƽv0g }HDikYk]_3-Ѡ̕5-4vuÒu yq;æu꼯Fr\t{{y#GnQvFRɷ||K5ό2$y~ \Ҡ K'L&zظN]noy'-V~M^1/q=cA6 {WTm0gel#،E g;a 2YFc7j E,m|Qz"2FAc4q2=56j7; u`a``/KDI'RDC(7;Uc} l)RzD޶7 /̎!"?n^/`=E̜Uw1/bc Y$g/#f 7`kWLu xTD6W2m۰Q;0ŵb6"0sxN82s6u"6 76j^QuzLU3gcR]"AZ}4Q, 9L6NƔ،r_4j`(nYL-/XID63a5w}o0Y艌/ e'B4&\Õe? oT6OؑYҊGK-5 r fiPf8-3]ojcA"T{,[l_*Y|N˵S&c@iq6 ?_ 3}t,9BvZػa֐4 OQկêX"^GUfTptgM Q.Y@ u= Dn9\HKG?xMU'Ȣ_ X13Y}pl h$w| 3-p:lcjݰ!Cd<$S{4P`?Q]|6ER>mCt&*c9`$oI3gr}g2Q{tVBثkV$xX<t@&TT~Aʨܱ3=3@:!ϜK9C( >{X|R=0K3a 㱸E?%ץLճ;(*Ҩu(V@'77De eFkX`=5gJrwFGa>1@ImL^W:ˑ/>oA9\9.佷At& h=Ire~gßF)erH cj&/`댼;`**qB΃]/qG7J?;%yg^ &vѝ7(+,76ZV"7t5;[U;wm(^ɛ:Ú&i`&2ybd@͗0k{+9u^3Qd u?*9g5?qGm {3G1%Laotzf*e*iF;/wy7$m,G2doB!*Z(SsM7mPg??GVu?+y+Jc)= xޟl//'aJeQwrQ4V榥TV&vD _w]9ڔATɛY$!5ۈj? [uo 'YFb4EZ"PD)"F,[Eu遅Nxu"󦔰(ml&jb23S9AQ.&j&:GIbߩuT*,٠ b Qsz`JYĎ7ʬc1zX#ڿVU_mP(lYE$VGuL u8.oxa}1{ÜU,ђ؇fyp(UQЇ%-Hj#zmu >i3Qmj9yBC|}Zf䚡p- E<:Ed#̔?Ӣ #l-ZizG[x<'5T~'31 (8V{aq+ymgn"E\׾ ,iEm 6*x<6 6w58NKQG=J篓w|/ri/3VH^oSՏ +"c&}>n=%mA:R"B2[bt8dY!(GnFU;,ͬ3>ڨw boS^b\~WU}F_ӲF~zU諸'En 56lM$ؚ>>GB jX}'ԏg|hQi{yUU_+|RT+g>L-+."'z<5YՕl"r'ձbNF$x;SNzlqNX|aZІ1q܍0s"cd?dI|V1TIfˋkU}At/ zT>ӄAb vW_SUTUGY*¨IrY~ZOG_4Qu52,% ?"N3ﱠƎ#3dB8lv/#?G:J9Θ0NcTu4氨VcPDf|3+H٣W3F~<8[/In}Z+|MY4{W("b 5OF껪 ]4)w䞂-yг̽"3OYM3bM9N7$KWB)3[#I~vȓS&VL/fҼ H2sSa>6y! 6ۮ yQh},+"}_gRm~&%"I$'c d:rjEXE8gf[`=*ljT؜*mfEdaKdd4؃jk ݏ/M#<XDDfhyeiӺ<z&amS!s6. aԙ/v^s";Ȩ|]fsB.33$i׊HAîa{c擮S&Ι7cvw.:UU !6TXO?w3ituUW[E"RˠA)jH0ڬ;RX?~E&L#0MDE1{:鵬K.`Y?UMA1q $ WI3R.ұC?ןPs1wc~A;2%&=9j?*s^2ϴpYPwd3 2ig`T iJKg0nD=ۍNtN8Nefw\dg鰤ת2/&8@8XDN\&KDB('CmS*zl4,Ǟ:,d )"QՊNj5XVJݘdavh W2H= rN,N慲0Qbl.B6"YblƖj֛9ҾJ='xڒp f&WR;s'"+mǦJ5/J.<0L+9NT tFu9e]\JzRReh>)uȳ'JË0/5= "4OU?U}8 8ID,GTRD>WՖj*bZa^7 U&"7aXhgKXm8VJV;݀yqwckS ) y]IIQ2Ϩj{X;^`NxWM{sM@ n܈N Uuz x"x{FRqt#e%Os3xw&k8(&TuXڎZ,\)NUGDUGј u8-G.#d9/jµxX~RG4{&D) x<Z7XAypv1.!"YKtLuBt6ڈV[xvPm&puUs?1'2WNSյU1q*d#":2^ YBwYZ޳cUA_7TQ35] Z9u'`>aԞRF$Bq9]U=Sz<}q@Ha6 dsU}*-vW;RSspun!Ol^QyC.&ۛ-("YɘfKQVq*3s0 _?g?3EdY-oXuV;k@>Ci,JYs6ٸnGD ץdw=fI&w"$6[\B-AsNcP4g8L^˅iֶJiP9W'ٮ1̓_XHmS]]AkGgYOiS YDže9&P}{铕QDN%CjU_]iY72ۘ=gJUMv-exgOCgxA$L^M$7hB 9 k6;Mo.XC-S߁Bz @o?"暀h?^5gQ^0 揢y`?o<gSjr~BNS3(u7lMqBmd4ȕl4|FwrϏU4@j+Xׁ%@XWtdҘ_4y*͔ p` ::P)9c60xND6 BDl fkeqJv9eMK;Ed uǴS5`Ddp"9 U}`LG967U.i8U}z/ K02Eb@0ZՎJOÔlCqL[O]NU!Kcww(4A^[DrBA܏kߧ4m=fk2 xOӲNQ)\, Mz5 [3ҷ" :>9h{Ԩ GHo,$İes(Ӱ2j{ jghkIOcWg'l>.wPN21sqբQ?_v#*OLѱ=2FOIS;akP &<ކ}@ yzݱ]9%ӌf^otM7F̔su`{ WQgy6q;p Ov3HIt졤ܗIQ&jK`Ẻ廬A_kgp@%}iA{w'uzey{<-L?wń{p7uULtE.yU#+˱I~m7Gۀc1XǶw P:hPC~Ak_0 zԞQPW(ߩB8=*N2V4hfB޺<2,sDT&˥*u%,l:>5 1-a 9bB^us NbJUꝉ͎WE9냤FC>ؚ̆}0:O&5mm G u5aOr}m&'J˶5b:Är>,Sv$.zޒvOyL0TζNy}GeY &LQ?!Fu/BQJc2rC)~ו-+| 2Pי9rH "cTUmB`n3lo,1S˵ L$Dd^4]iH/lhZ0QޅjLP3*7sZ1mG_4TGVB' rd#C%BSCYɳxFo;bڕE0-uz[:*/^Lk1 -7o=`pm[(w>08l4 ߫º/TJCy)zކrK/h5϶(ZJĬܶ֓N>/h+W0F=?FcqI\ϹFk=Iv[@i-^2:'"[`x}t`3UwkTC0uk%^,h+.Pݵv[qq>M̴HUBǙ#\=KbJ?[ nX~O3 fmKg/fp=o=fqqTd{\փIDATsڥ&/„+4Tq%NTש:;wds}t܂>-ԍUӁUF883'!"]Q (_`}UmIp+M<ʜ˃-d hh@]'c Rbqkni~PpvqqEy*=w[88̝&ODƩ2mnoL;X #Hଶ5'"_b1>Zom888s'm&},(GDL2ho, h?0,H^o%Ivg1eM$|_euY^i88NkhK!o$E/GU[0{F'1_ooKL`QUm9Ӿa168TUoj8e۲?8&ODz%)k U:8 87#CYf]Go s6ũؒvqqjȪ"r%ZogKz x"c=})o5Mq :PU{j/`'?:p>88-.Bt[WB;Ȓ|:ZUGEfm` %:]>_vzbϰ0 K lq!"Ȕ(u^q:"rWl<8z웈E@DV{\P oֳ&UUPPC#B08SN8NBqA5㙭iX݂PjDd x sl:p3WoOD:G`YFq>U888<JDY+: p/&lR0[uE%ӀU`U}5mU`v̻Ԟ888NDdyx,"Kh,&\2U)"9XD\,Z믑70y`^VQ/ܮ888Nn y"(0X/޿;l0hР"r8mԛSvJD'mÓKeTU0o9mEy\D,Sױ@+MCvvDh@Ho " HVz-"tm"2_-TH׶"]Di>P&uy*`-#~qik?9CUǔ "aNM68-p%pI#ƘJ[ !C]c9Y8 O4$"_c1-M v,~Ŷ`| < VknEdE ``yd|M]" yk=!"cCUuZF3Ed:WU"`K'WU}-y&u/11?xU}zAy {CUGTgy2G!BW}@7@E3lT c=w zWȷ0Z;w0UZnV TI0w3J=f<..")֒~;U%Y:aL,`:l0-0uT]b%zC<_ӁӲJ ⋌OhT,aLN U˓m,g`?"^Cs⤮0aO+I+cqʜ8 ߃k:V!)F}sh.T= ks(m *ز3lO,~D"tGu.$69|7/$hQr 0f3xi;6i_-sٗ҉÷5 Kx1L`9L)l 8ω'O<$aU֚w'w%6Fb 8n X଼O`G_6ZkСC7n3]v٥p}̆YU\U'iF^D>8oDOY* \W%G]E3904YolzEUQ/X V&_̥`^7YDḏL+U_aJe4v5kh sޒDUgb_Ĝԛ&Ϫu%qABA)?^x^zqG6˷ꪫr=/;гgOoﰙTUӨJ<} sq7k,̆2?Ot`Y[Xv<\xBU'T+\GDBl_Sj^5m]U<ZGDVz`}~kPWDGѮ/)BU`zoqQ6UսU4٘9i̒C4GZU}[XqӤy p LPp t VXoW^yv+?lwiY@f.51 dutP)Dv"M *N:$z|v",O?ͩ <]'n@tTu5B\D9G?U_E%E$pєlU9˗#Ss]"N5bҾaQtzI-&T"[#=?yҏjhiɄ:rk8ӡ\fYwλˀ6 x?c-"]jpHR4%b#5;i[PDzQ:!UNI. ZHJzk8ΜMJ?lbRٓ!C0vX L{>89y'BTp""g`Sċ.9\WU,q~/"&%-5''SZ7`=0.ٮ'jֲGK=~yg;:i~~'8,!y?xƎ˙g9J3p@ύ7߬ly1HD;SS)u5=]ފǙQՙz/fPWIiPE&GM"2oH2K$HO%uU ciywλSF\BK5~$=ZGhVkȴ:y˭u4򂳂 K.K/>}9Yn>}:\p3f3r)y댏g>KKy+vc#""RTw~_g*Xg)k2 =4ެObB嘝V,"ϊFD*M֗kHE幌z>Ҹx7 QocZ]ٙH=6yK󦿑n>q[6`%?s D+6c̘1~7xc6d}9$"v +``Q +sgdML:gt퍌<$۵8^,_SCsѮuEd&_Dv ZbqWէu>}F9SXfeK<9udf{'ju<\#2UURǙ[9)0x1͠OR:s!"{͗U?9X 'O'hWЩcZKOe`]ZD:cCM򞍙8!}>#j纬u٪9D3$+k?k Qf0)8usܹo'V*h Wx⤫9DŽX("b>8zTjr{GcZkeO^x?\S!ج{!e4@_Ul\5{@n;$ǹ^&oWLS{cO~^&'GyZ͒~.:vlFv!sbvL)[K7sFý}/=`vF=()GoEelyTijM9KrQ梤e4_'L=9G'e6J*:o'>xiKZ})E0y qbYgf3'RUp.p6k8\< Ħc˱x6@??U5֎u/ oop`6^BŬ۫iv)5 uUݟ Dd0)h^ y[c*fRXy?&=P?͓7椤;8⺴Z%䂈ǪJmEDvh.&?`\{ CjkPvH;0::U4vb'RԊ=CűaX%EM[wF\@q,.j`gJ%WsrSWlRM|M\Maekɢ4qT؇'FVU3fwܡ=z &~4nד'O/aB +̄+SQO,>Uꝁ WPrqd>m1X.5\.`xbƼYﺔjFU:VLڪi@λ&HTw6HxBW;1ᾙ2kќϠb{ gODeYfTwTsY.TY̨{;lb\c NFT{xF'O<&/*MyL6tS;0N?t~{ jqr#"kb30K?,NV-:l% 4>1dlHCU*uDXlߨ*u %4u\k}B93&DG&iyG+9Y w }ZHzVĴ<:+aa&b15?|?,^[zݱ{2xxLU'U a&ճ'hӰ%YOU_ eT[Um6i8&&??u/iWĞo{.4_no;qy?S{ T:888DTu"t_.9884Wn ӱE̕xnfgUn:888y+ޓR/e&`Nm888:r y2tQi"2KrY98885Q-Iz:94s-~"888l#,^13ΕTujqqqRf"TuF888㴂)X-IENDB`PK 87Q%Q%-Pictures/100002010000045500000332A5C6A400.pngPNG  IHDRU25sBIT|d pHYs.#.#x?vtEXtSoftwarewww.inkscape.org< IDATxwU'!B'#7J E" ,RD"ҕ"DQz ]K-B$3K6woyI޽3g{=ETqqq'<sUV8N癡 8NOED^T/:OYKYqq!"%NAdqۦ))A<I$"$W`DUSj9"2p# $pNr8 Dp(p40SwTN8S^oT6*".Ww;@DF <8MD)Ѭ$u~  qu 8 DdU*yl۬8=9UDdsNQ"0^y'T6Dd*kqqއ  rF*CDdZcQ9=^OFf"]U 9Sn?"p_ti'Xp8vD?XmU}8XAQv@8USF8NӃQP@#V X*0 fQv^Uϸ4B-Zf^SqrڨSV7 ;TJ7$ 6GH,fsUM.ɿIfUvN l\ \!"=9崎mmoPw;7c1itq,cP[ۨ8N%UV%61p͜&ܞ{yi zpjZplF86Tu<֟9Ǎ*-FUGaoEV8=91Tu2V- n,ꪚfl5ΘUqq^%x M4🞀CK#""dkGU'$t^\i=q齨];8NJ x=>Ftqqqq$nTi&m]qqq)UCMo888ƍ*& E qqqqJF~D[4qqqq^|a_.J9|-q+uh fOdyMUzNـ%űa 6RK0&-y 77TN)DD9,vDdF\-&0 x)y_GŮaJ7] vΞnVʿ"2n}w'aﰱ7w\lq,,KUGvR/ ȼ5뗏FjEW#"3`<)}LƌQQqF2su>lŎEd`3``K`&? ܔ,Ыn[aƥ'JJ!|9U}YU̱r*>T;szWUɲupoLD.MDj.gwJt G">p p>>#0,?P;snRDdv`c``U``&+UjYY X>fOK),MLUɹ\ȬFu\ 5}yW 27𵜛Ț9Y6*;x,YN(b$MV+"a<ܪZ8 3o4ppޘsaZO#("ʱoc+H+ufwm`!O?IDfp SDd#/rCR!|i3F6Y2ސc$}ñy"|]#ZO+Q/}y\ZOɍN pI[h֎OOZϙɾc@py a !㾇9oUfo@ Ⱥ'1W@ 2.*p_< 8`b|&py&|xc;A od ,U1 .r_/*kQW r9ulX`]Abu5#v`O(y6[ibt^!=8*EМ^PL"aȾ sg{M|$"stYNb .٪rŀ Я*fD\* ~>}m{Ed)r~{<"MoC'E$Ī>b/];DN "r&0҆0(@Kwr{P?9N*S{ء݊8$D`y{zLYDDnČ̿V@`olL 9N%xO{YI{%.}IGd*1X^YIzpyV^QRǣ_?B9^`JNYEpmWK8 NLy%[)7\'"꽕(f QA<sU[T/p|kU4_HǓunX8XWD.5{/f3 H =f޿Z{4iVL7AXhz :?/lo3Iޔh3&"f 4,žaUR8+ 9HUjH 7$L sjZQ8o'">rD wȊڂP2b㟑X_a,nM58SD9S8NոQl֤;H/¼?Ҹ WS.O\y,ܪzFA'ݠ2Dr/%:FDx8:+ZSVdO'ca i|H&}+c!c,yz *`hl076_6 EdUCnc!$,bƏ,ut , v/ #F:@sXN5"2'euEd3[F#!Y{7 *_`ˁR0o}OD&! /a3Gpһ0հ*7ZY| 3["yQFgf^콴&2#"aߢ4ac&^gc99GD] L lHDL1-||fg O{j9ͱnY&2b7`µegɤ0#}Ydaƿw:o%سZq2,Fu q<@vS7Lֿ%p3%fnOt=MލjXbuvRr '?Bs`X @ sed56@ V@E0FYP Ix>_ ͩrhEM_9U"1=0 "oul#v@%$ Q,u~„dSRG3M,N:MUߢsh:j? QX}_ = R@f6MwTKD%VhNGrghY3`^!y]3~3 ݟ;T?j9]J^ɵcIZM )J@'f1@j?P] :}OG+ K4۫xN6 "vN.`HGױيTIyqɿfOU}lF=ĦI z/x(z}cI3"X[Q'.!kz6rf,qYed3fෘ7e#s!@NqJ 5uE8p|E:w5Tu8yvNnfae,.F!p>鳣(u)k؇iUk΄ɽ*C(x9>yE)n<} =1:ɯ I<bȷ%S]os#blɿϐ?}@VaX4WմN&A %݄1Оy hL!2*Zd:U(G2pm"qdcvlh/,<;Ypn`D>^#$Ch"@)RUqJFHJ7%"A"2K֕ct$Ld(Vm,8Eh$){ί;\Uv j?"mE=Uv!\b"Sfu cIzkd7(+ÌBQ ZʖgFTu ġEJaIgf%^*1Mk4*iXUsA`<<e.ȶ?%}/';g+!-W,5<qڎW dX%{i/_˅4"mt7l38w2|\ӼTħM@ WSڥO([d6I3TP"mL"e 3m|YP_.ĥ\U TDmWk } Ӊ;3w͔ueWU[p_oݤO,o-ʼ}JTEy2LDr@QYҽOJ]j4r8Wbn|foL%.P2=g*?ȓP/fTy1,r#Hޕ`3l:sTX^>:Μ,ͮclt.®eyl&ľjhcɛl] }U=55@ZEỲ Հ~z.M'@?% <U|{TOoLhō*NGpJ dyXDòdi&Y/P X*J0kc%cy=CDI?[r!"KO$Ք)TZ)(=WUUޭX^5xe,t- < yfn{U9oPv5JU;va~[e3TTUEd,鹢ea@Mjd;BK`9x!tY T0*42Xi,%9rڌêXX.Ҳw*ГWnT3z*Cj N&=h{"F KU[b[./b%-,{4z[ XvSnTi%Mcn%v ES[Ed9pl0omAr: YA63=3{^zY3 #P4ه-KD| Q9MH+H!c.S%tyRo=d:{GUOD|KIT>~ԭ7N{]_kF6766JXj5U 3ǧO 6 q"񂼘A%`WUwrFôUe]4$~^YPv[I*ܒ$j͐lE>K?h`I^U Q`PՇڨO7P5nNV+U&ۨ]yx{狪zvqzWnT3zLcTaZ/XkmۓbTaJTQz PUlVZ<`9x)dEhfT UѨg:\Uk(v=;LZzsqVUQB-$1ΈHI.ɍ>L8"R%شOWGH}CB$j-WӵQ}N<ࠤF^b Tu +b~rq$?Uv)LC,"ҬJ9u`( :'͝ HM8Y},O"`'TŌC! Q< V7`;= 7 U8% u'!&""ȃ mEl!"2n*7ëh? "O7UqZO,j? rZM,TYT'0_Udz*dױ8!^Zyw(")fKN%D'JN?poMWVN*TI1ޱ2E Xay'Cw-[T~Jܳ X"[**k:V )c9)2RZ6;'U/U$Q=|x+3XUnh7wk`.J9 i!@۶UМ$cEdy6={Ҭ2iUߘǥ7U8- `2''DV9f$!JiyJ|t-N=OEުp?~XbeM4۪^>=ؽ41MWVP8GTVTU)+&"R!.*ŤTهi+Yn( +žPRI 'a!P ~!<0GɌedt'"m_/+\DvQv'" {FVsƁv:n\6jk*p]yf+\ZGlR]k̳~Cz$Չ9-"(yPU(,`W.FO od}MRtUڌΈ2'4 Hi:!մ ~Wr~:4ŪznqI_Y%gm럑|Ae5=/*pY%2 R>~/ 6)S&1n׺~:4Ox;@yHo֦Ox"wU$mȰZZ~!^I r҉Mn"y/<1ܨN&xD"zZ7DY2~>ИlqpvA ".s%@K*> &u|D8>x1"""Sf'ԭLĢ&ٔ g{kRD$ʁ NyUKFD֧XBU h8ʇ1mΥT6ddoרu4 U}nxtcOgWSz҃7)7p-H8eqJPձ  SlpC,iN%rSgPٲiUUBh"'>2c$x?T ݩU}C 2W1DmUxD$[yoL _8IDϳlM<ϿT5{zYxldȒPk0yGU$t_Uuf"X43 UB*z19"2x 3)=o$ƣ("OD~ Ô6'=Lv*DD0j/3d4LH}J3Abj!\G{C誾ݍEOE]Dfs;t+qcX@=vSߓ1Fog<6s/s=xo%F={|u1 WICE?"e߿~Kzk4.W^{LD~j~F+"r,L&"'W0sLj^1ƪ+Ԃŀ#ۏW l?֡ K&{tz5Yg5_@ƜX*I>Vto˳oM*'EVf$93D˿P`~,.$NCcL\LN3 汵( 극T9Y4A:=} gne~XChﭘp ,)"ط䅆K{gOrb˰\}~%Wۆ&[d9N߯|jgrL;c4\CHwF=#rޞ@\!Ǔ>[c(}폽?JY)|ҖW%[7q.6I:3ê۰ϰyS~}KhlʂXݼUsc&d} lf_C?,x'r㱎jm?zmhQ7-,nT /*~`Ǖ/҉ܮ3$z Qkr-{v|d1'hQYDU}WU7E<̳e`Ul1`9Ut3$@8XX\zXⰐ{jǓ:U{[Qp`m]> BrvS=4[9EU?Wc yZNOb¡ cV;jcZTu#΀yy,A4~Q݊^J<@,Nz_F} sF$aiFUG`UCN,2=|SUtT*1&+Obôhqz{C0Wڻ[ 7r+#9 ^/"퀹1K y>c>c|%96K  t}aWyo^@zi߭z檖_(93wBa XxyzKC[,KN`Vmf$A7wz~\俾`FU;0#w1cs3>fOUKX>;Țu܁f_`'u"uL<@YU=*M&"_î0]:nVբFS{2TQ*#nθXyU+:IDN±CO'񭲔s,!gkFcĈ5bW 49xz&¯mx>Ks*8 ]mq*B,װA2!Vb,Dx1Y.`exxKf^Jlt3,jAyz3rݠJYr[̂ym *͎`IG7j%y l3v? bv>B_Faʶd8s`kUlW I!vmk0'|f<;{=,oS-Ìy%c} 7"8jM;6! > GN9= "bcb`ߗ1XX֍jUFq"VN@+KUqqs8t"m!{qqqznTq,+~Ln8878tU?ސqqqPq0"=UQg;]9qqq&Qq'κε?DClh^>qqi8~UqqqZUqmXVlh]Y8878cp~*zsQَ8878gtwC ;)`988&DU;8NED.v 4 c#2c6 :0TU_.bD{)M;UTsqq:Wq)o_ȫa l=0Vw;U֪T `,,Z^qqQq'E؀xC@L<|8VU'qqqFqI؛Ed1;XZ%ĎNPk888N'*89zwRb x]`"0xRU'Ymqqq*ƍ*8$uZqqqZUqqqq Ч 8888t#nTqqqq)Uqqqq FqqqqQqqqqnTqqqq)Uqqqq FqqqqQqqqqnTqqqq)Uqqqq FqqqqQqqqqnTqqqq)Uqqqq FqqqqQqqqq3tZǩ  ()𞪎nNFDd>*}qqDd~`HFcJ97{OUo>y97{WU_l>NyDU;FD6f p/p%|HIeU]U88ȁsnv }z "*hnTa'"86.õ}+q*NW""Kۑ`f̚C`i=3 ׀/*"pBTm8~Rb88?gd$9JUZY 3ԸGDvTշ;ƍ*NWT$cvY9`< =M3r C^etwz4g3-huqq=k/yMU/ZN{x H ~u) \52DU'g5u=7089UADļJ*1Dd ϩ҃qOUu|hCU}, yXm&_p8tFb_;|~N}""ۓ>yWUnf|NЬ *NWx *5T%*`Bl8Nds̰+3Kˡ> TnTQՉ"2 X((78]DȻmq*$cqz~~\CCX<}488㴂X咶i8h{Rq78G8pwVAUoc쮞qqp4pcl.SU} VPUk8#"}ucR7#EXT L9~x._)USz!"0eП) ߪE4ND?ZXs[sADHmƩ1?|WkAD \Юll lup RU(97;GUm~f\ :1DdiJӠfȚwqP$"{TU[AD6)UًaXQ{(%"fd JU.؀6G"r%p>rڌ YE~MSrUٰ߭s>sȂt6Xr=ƉMXyNZN!"aadnLb[UhGDdՏoԑ㐜y͞QsȆ{q{FEX+納ɀX^UU(l(Ŭ+4ʫz:e+_p<0G =(a 2^, Vؒרҷn_[ pRz^'cWTOJ\ՁJ$-fy.`}Ks$[lFgg"px ux"}Gd1n{~Y{X ?hwKNx ި}Ɩ;N(oA6%IM[l[98y; ú)=+gfe6Y "?H/W!𨈬Wb@DNP ftIUg-+aI7 0tІ{V7u]Wՙ1#,rFf\MVzvFb7~'"GWL.0uTud1s1/FcB # 4þ_@U=1V1pbFuj&f .)"ߩP IDATH^Obܽpu;oN}?BB!&a],[!o0cżt&46`z^r5ZOMo心a / ?`gbpUȐuچ`ic4k:XDN}7n!fXmF<1e[#HAD\}Ӭ?R3Y{`B jXHpb`-` jVɘz>;AXXG"GrZ2GL$Vڴ2on"_U\2Hq>CUbDD R/k#"czbPG]5CҿUEum""6vRj:qUuWq {s/aFwCl]16 Wwbޘi\Ĵ}fUuX}<^jmиcl}Xؗ)N`LI7j^ebV xW1kL f[x, ,W6 0! XNy3`U&0Q',OUďcNح<9U^#>|`anOfNy3`Zc?AHdȡP'oqX 0 flF_ Hs t =W%=BfWtݨF=lf*wn,7Iis+L6J[/ 󔈼3K޳_fd? * sd4~:`:R`&6 L9UA_ѐg ̌yh`ۣ}<^zʩMd_K~ f ?<?6( f d;3 lD^,C}Qܲ'?G%s[3nնS+EUj46Ȝx"ߗ:KJVA04MJ3Z+>9ƒux]mTIdn@XxN( oA3F!'dbwQeL y}1pY dnWBf?,zVUj$ f➈W"z{bABԡo{hv.X9P9ED,)-`ࢼUhK cᚮ9GKS+{֑jdą5"fp^CnڽqpO1wR ~= e:.*6 ݲ楚yIxSfr̘OD;pQ cg*7`Ԋ{U}jhOr9 <, §AU~h4~,H͐> Zh ƌ#͏n`E 苕؞= :|+GB?Ӄ(bT2KU/,X.EIUr I@sY都|t32!e1w,bUDk&$uLO( M7rhMbuDV6)h•V:P'?7ƵeLu#}XK2X͘'­&n,tNw(1@U"u! C|pe1̲yk9yyaa2 ] 4B8rCs%IxojI!"N\ˣRQxpU}\0CGEV41BU/:]J2'#6H$_FB?lUKDZiI' sGOc>X$YeLy<lK U|F2WJǼz)cJ-Jt^SlS^BX(9lP~UoyfI[/Ӑ#F,^Y.,"u|NTsr ^L4P;WxŪxLYjr?S7rUϹ.HN3+IP 1Ocz?lEzR]0c=+)> w` ms bِKzH,4S5gݱ)G9oNz5g3uGKH۟+V'Eg>Sz#` @KxtX eEUYA9@, \Y +%,p'#o^ YbY7b$P(WD$Tk*Ddcn_Ps\+5= P՛UuHZ)* wֆe }I3V`@P~ #"Up;\VtCU%NciI&֛MWY+*Id]JQJY#m74vgy1bK HZM2<^vLب2sPZ~e&OcFdY8a+)4X(JӸěe*uzH<޺zlj.ERTBBL$=2ϙdck_g5^?kR'5PD7_xBj{>2n \ƠZ*q*ZJWRFpm3]FV5o;mĚylgͼe"MU2\?ڴ %7HRNYlviӨl&-5߰ ̽_yMk7fkWD73ϟS3o爸~t؉hm2uߥy8T.{} ?Uv},3Z{g)Y3$ɶۣ0]Msdp+&тIKiReI+k *5ȝzyIDڽhw6Z" Mt 3όwx˓"⫔ S_XnTu'm.w}J2eXRx3򈸈2LM)Cnjh=s6k{9g?`8R m\'Ucyn;>K5v1q[~!TDlN 7ژ᭭wgR~;\A}W&렜t!"n Pi'skӬwyE51]IRQ -_('kԼ]u/w0J?}?\+Ǵ |󚷴U~ΰQ@V5Zww1Ix$nS ׺ ~!xLnH7q4p\fպM)yOݱʥѱ%nO}ReXQʶU3 EQjݝj{?,;_60||W'ːӸOjㆩEݹg7TJ[} 6ha9.ESº}Ra<" ,hd!細O΢sw^61l}}XDuU]2O@AT;{$&""3gP"[/y%ʈ 0oPwO|1 Q<+"a\%UA\0jGł$"x rhBv a]ֹZbM kg*`4dE[͸5\  m|m}F?F(u''RiFm2m}bUMNi1&?pjn&kr33+(:*a5<0Ik],g+H ~^Ii2qbf^gNZa'6u{¦RPmێ,Q F,ARh@`J-&E <"^ Ke1nݟxXrX*dp+ĕQ9PqWLQr+Tr?VOK˙d*u}׎Dz2Dĉ Nl 6v7I-~02g rD?ȇPx|f~z$3<%"^sǚyg,iEӁLP\`gd%%5ob?e$"Nқ̻rgf (>R [k]c6 YJÎKqdg][$WvxMmmm,!s϶׍ohLf!C+/ם,"nL}ymP7ynfED#[nM oiCvpM(ŁA]+ɘUWA{EDonQ3~v눱,aɶ[MAN~2(pm`?|Z{-ނU*-^Khԝ{nU/\@l*Րu'55ly&U >p,Wdf9"3 |f1GDM/Ƣ`c:,f-:m5Ef -ZPD\ؾ-MlKҕvMf-TξeϚ'S:cgVʻTu ;u5i7A@r9f޽hm_ͼ 2?K}dq=uC&oKif_-bwoj޲OkZ\Rl3ZwCzT ɺfmv}zu#u "˚XX-N]אEĝ"yT#KuEهu[(`Ԩ]&]KܮEuc>Gj)T,sOʑ ={뙴xtfm{fg]5%3 |-Kq߯ϴ3s!'wذaL=l[&FݝaP:w^WymwhJq, yK]{hi_x{Dܟ}|a뒓r.5NӶϚoִ ZVܻ|o[vGۍ:w1?C-ÿPcU7HeifD*њD-26>G-"?3OZ؃#ދ-5!"nܧϬ$ِ.I{,v9cǚy;hG dvVuTmk?91C L6Bi66 OV7|z!?1`Z'˨0`D%"^6qc%ur|u'YF\*e~qۈؽϩ;?n gj-~\}GLj>P3v[ q_f-L$U*u'lޫjjU[faI}dk\[a-'eUW޿uDNum#bv U !lF\^+3yKyD׻Zϸ|yZ,J)}fb% 5_W,f4]4a8x1ˏ[QNԑy)Z"3Wa3I#b~"ddq׍wؑE\3`Nbϴef =}vfש}KYx? d`U}mWdZlt~:`ރ[hB}pfv9j2rʺZ,¹\2p&Tb5oyhD,E;/ձIT^ /FwC;xkNL^3)'U$3ϧRbξ&U-E0{g=M;j-ql̬ky̛k&bݱ(&ˮ̽Q`yb[&DĞ Yvs #≣ruu猞l0h .?ƚ 6XS<a[Ou%-dqͼmZ^A3jٚ<&"uðZ.bV)/.2_h 6"bp"g';fpˎYL}IV@Gm/3{J|hm/~k,Գ)I.4*$Ԧ-k2EUy!80_foU74"__Y=#/̱ .s]DD]ad}%o2`\3/B۟-WZ`I'g̓3պ2"N)دP Fm}^x,P> rB9%otрuU̿Fċp[XoZ=U%K8w?|?j,ԓG3~UC) &71t(-I^O9rw x.z]qfwsW aZIo[PA;iy 2MS#Q0̛#pvN|j^yk?WDЯfPU"bGw9Mk~1K%EBrc+NJWA]nx *u g ix*墻9c#~-s-V{_{` PeMպVfwDlEΊgwS/I9+Ow&AfZ?š/G;WWnZ`>Rf~JZU_mAjo~ Ț6=V |b˸΀zϲ :Θ _7-|ޕЫ(IS.F^Byj}k_TS(rLsE~ϲ#?D1hyRSjOֳ~չ%ǹ/rܼ{=e9ܻ>n8jq}/y˾e׼eT^侔6ÖKG)ʾEB`j1kV|$0I곷lr_/ۤJcRew3֤JkQ.矬.qpם)ͱ/]z;uI*?)Jm;(rg׫s8XT޳.b~Ңf)ևgRh8ĺ3%!V+)Ji)U,"ѷ'9UàY>O9~ݵTYR닋\ܟ)r4at݅mrLҚ~_jIPV²ϭY?%3T#CɭgB O?g=zwÇF+бXD }(BRCg2K*U-Qb݇mRZ vt؏K9"EԖj܌5s.Խ_*1mQaN\,߉uRc?q?J6 r`_67 7r|pRIe>twqQut |0'jyΞQܖ}Mfg[QZbQU?1>ne}ؒUFHX8 8o.=;ק$/>=]֥$wev4XD|ӦJV܁R#=>1j;Q.Goͭ?̺JBF|q]J2sX̼ǩJܒUuS1jbQ-*=ؿ5e0wyQ6No&U$I$I"I$ITLH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$I:] IR"bc7FĦ}33i'2I$M̮c$3q phK˒$I҄$I$IR&U$I$I$i;e]r$I4"I$IԀ$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$IX]MCer\u Ҭ݀uEQeoB%2$"n<x4cH <;3u , m;GeޔgvfT$U"bk:EIQ\u ,g:i1aZj *$M':iT]~^u2plJD xTqH<-CAH@a*@$a^AH3 @Z:͆iHlu$i :I.Mʒ$I2'ĮV=Bͤ$I4~1%6 $I$I&,TY \u$̀@$iRR|RAH4"b+$Iv$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$IԀII$ILH$I$5`RE$I$*$I$I T$I$Ij$I$IR&U$I$I0"I$I:] I$ivEz+3seHRLS%uXfsi -IԭTϷ++ߩg{>'iژTђM]*i2تz>nED\ znEyU %Iyߋ7yzW?_ߥ$X>/Q*jMDl Y=n =_ضz R,~AJ$͒Xx Ͳ9TϗTR/wm [=_|4IʤY=S Yd LGDEIIIĖ-$IE77&] |43[b_-k;^U_E2*ID<x B\\\=W|:utc힟ץfc+6&=VDX՚LL$i/^^|xSf2BB.T;-OVTPUGPir!p2ysi9wЌ*15k&[vVٮfPj _;Pl< xlDxGf^JR&U4PDl |^f^6ZUu9zn 'Zn˪*w[E.C*HiRZ[MzSfr\_ur@JݕOGI 2q#IsL">sdؘUIӫUޛܛҢeuUWWTC%YNoJ$c/gUB|GAT砯#w/˻MdREsC! xLޗg\jq@Dl ܇`*ڐR~",I&ZDk*2`psGģ3G]'iXȨ(aLJ K77sBe̼832s;Jgݔ"x$IZXS࿺huy `'q`XIe*"6Q۴gA66+ϺUf~(3 lIFb@SFU%xlD"IԅSF\ Ww2|;eu_: N3 En̛uo]r8)"a!I"b{M(_]4)]W#bN4sL,2J9 ;3/&*d湙܍R`>o]'p8%?"$I3( _8F27=7U |?"nYPfIe "^M1j?35GUmyg`;E;,9ONs#⠈bJTuyJ̜25"O9pjDܥ$ *3."C1J࡙Beo21R%Oޔ+?GĆS$Mn}X!WQF[X9ĊQT=s3+:G?e2sJ{-#D"bq)I&])V8CV/Ů@F`ReD{LzOfQ8 yJf>z@֬rCH$IZ^̿uɘean>kI aReFDkz&fk{fR1{G"bq(I:3T?d{W/X1"Ipʅf"3?wR_ۍ9DIԾngwz#: G҄22"z#2̫2ܕ}m[2"m$Ij]1iU/C: G22Je' D+3n|X3{]yئ%IҢl_=T'3ԗxmD"2IgRez]t4<+34޼ٷ_[?:I-*J񵀏G#iLLIv@f{~=oވ$i1y5%fg-\+-&UWoR n \3kyX$IZ&*Wt߳pF$i\LLޤ]42|#>`EMw?u$Iˀ-UZ^P|dDe<ä20o#䈸$iTiIf~H-fIeRE3)38s="vI4TO;  u%dRezTL;〟G#b.$iREyp KҴ22Lhe< 9_zfo ED<$IkW+;bdEQnۈ$-*ӫb໤C(ɕ3{kS񥈸iI4Y=oi3&3O^Y|fDe-[f?ID,"wl$M]jm FRLLޤ֝E!u 3{.陵!f{'I4}*4 <"k0iAO/*Z2X%hPDlIp$M˫g[,̼x\e/Vu 4LL޻[uԱ̼,3 qϬ$8I-UXf~ 8zڈ[HjIReAgH 3OZy)ptD|#"v$8I&I882#z#&U^H^f̷N7>ڈXI4,T;y5(n#*ˤ4@f^>ppVDܫ$I@s5Ul2󫗏t3222ʞI&Uy2x{=vNF'I䰥eGOU/GTn$ wN7 BOt$MkӁ (vMI֛Tٮ()U͜|rDܸ$I_g[oIf x,n#ԔIv^& f-͛_$-C7:d^w2I͘TnyWe&3~3kS˟֊$izF]  |$"6I22z*kaki$yf$"sQI4vMgQ,Cy%pmWtQTb3ҞI{v4BO.陵9p|Dv$IK/3`U]*c?^2"ne3^WHMf|gzaوش$IZ-U&/M*螟<@(3݁ w&2Id "bN#ѿeJ@wi@VcRedX5HDfž'GK$IPVV?ZeT-b־5"62IT=kJԍ@.qN$i̼U7謫2y^F9ƎcT12{z**i̿fCzw})݁Md$ @*Z3"]#02c2i=$u,3݁H4AhN{RL̦*m:Dy*;L^x pBDܰ$IZI V}h흁v$*X`EZ"Ruz(bV@JwL 4h훭&uˤ [~g#b⑴|7pA'F+#}$+?fU.Q)EkoXeuX7U ֔Q}g/8r$ @gW/ML̼UEk2i9322z&$"*Ik2s?Ehy7ISg*CkulTmoy[1]"i<;t Ԉػ$IH&U&Xf^VDܯxʤl /u5i2e;陼)edJL%Un;tjeeύnUC6‘4DUd=ע$t$i9{U&߁!o 3y}#qhDMd7Tص@`oHc *{>@$&3 <x ݜ_w$ifeEw.cd_7V/MxTY&2RȞIudz?{f8-"v&2I krN(Xe`Eڔ&Hf~+;DCJ4~P=;̫(EkDL,#=("s(w O왼1وxuDD7IfqfLjضH4O?~~{HˁIլuP/铙gr>u$i\V|.efV/}Gu&U̼xsϤ݁vE|=I)`{n"$͂\ |ziRedw/V/XYgReyzpaDF]#iq2H^qN$͊g*]Ie(3^3^K2}J۟LADܪ$I3`6Sh$#C/- *Tf~ ^Ϥ"b⑴x[`Oߍޝ:}C24%IiP$(e(ҨTO9*3DI"JI Bt}ggw{uy^uZ=/{}u]sʤ$uo[Ǜ V!,K7e"2v7+DĶeRI>z_CWHRee1}퀃K'Gʤ$uX\M}SIP}$H#REbY @f i_\z窬 xT.?CuT liX_GҥH< wczG̈XL*IRxk_"RIdT\< x_8Af<19pADR&$Cz[ꝭkREdׁ4#22O~O(JוJQ;*RIM{3KGEbH̼XYcT3ʤ$ +zҒY4%k.E *؟lLmۀR?1=8/"(Jg׭PkypJ=[TdW4v4z2?ˀ6Nˤ$ 'Gģ&TO}] 2i,U4̼UO HQ9+3HU,|#"-K4~R?xGgU[24 ,U_2R$ܟL$|n=\nD}}vDl\4q*9mZTI+3`XY 8."v,J4zlM2zji ,U4Gy/z$<ؕRߵ\*IҐ9Xxa,j#b͢IT\eϙ}S} ő4y$"r$I"3.nӀ?R}w,RgYh~~6 iez*C"br$ICwxKT=1"V)G*KS h$<xG{ E$ ޹*+ );j; g:REUoS@+iei+{ӟ$Iy +a{Dr%H]d?om@3 E$ jP? ^89*Z stRD,S,sFA"I*E&єd激xGu#,U&ڳSDTI/՘~GD$idf'Kfeu~_Jf^ ֘>U/noLpŊ$v$Xؼp3,U2oT, ˖K%iP2R^$I* 3\[]qy%zY.TQ+yZLp%ieTJsWH2z[ژzpx8 Sݘ8zIഈxFT*kDS&єe)%H]`~981~uDQ*#w5{Imw-@w`I!gӟ ET@f~HcjEXP$I`VX̼ZEKMf*,Iuʃ˥4h/ppcjB$IӯW<."6,D[]Dl4I5K Df^ 1KDS(B2f`;=P$IRe/_C'zYac;nvscxyH ܘz,pZD,Y($zU&QU_J*38."6(JR){k |PIR,h8 },аTe̾lpjH n1PH>[n y'z f"2D#TXP$IniL*I?-@Eģ&QnkM" K_oLmI$̼jiTGGʥ$T\8|+$,UT끟6_(GRc`B$IS38tW?8LzM%K/cL|1^8!"~%Ieڷ̢^P y"WH \ژhD>R}}ADY4҈Xd4K 5"ƒͤ1wS)5[$I<=Ձo)Gq2p'8aزTP̋WS|5"Z#y>S*J4ם=+@Nە"f;Pj(pbDlV.A{4f'Eb"I;(_رp1h K &;KR^RI<811pP82z=_bHcREC+31,pVDW(2~+"^Z*$ށE&Eh2>z},RI*jfNJ9B$ XfC_z*#1RIVf^_V0iDjewXTQ'dfg4Ύ劄T/ئTI̙apwW]M"`Ψ o^\ }pP*3{B$I p~hnzo KuJ}`gߏʤ4Hy DH7FḌ?f=.@;*̼x1pecz#RT)3Oa7>U($i^xI g{ƍ:)3o1Co&whW #IZpy)ն̢ ]wXhi@,U4R2n`kໍGQ+kI%i24#եH׀[VXxv,@XhK_ޘ^'I%i@&o:8"V.F4zXdoT IDAT3qgNi,Xh$e}+S*V\&V͍!HTP8REcRE#+3goL?8/"Z&閙bm@FvH.ſẒ)ZyM58TH? 81xfT`Nۀh iYhle--#b2$Mww׏>S0$iZ&C,jȈXhiYhe%3?77~I%2o6^/-G4oy%Z~V?vF^f^EU\ژ~;ycX*+E WO,D&*RCf], |%"+KRKnL%IC$3DUU:'3P=WE#RE؝ꓑ#J-3$ 3;΢ 4Ki.2`?7Eăʤ'0-?[0$i2CV^FSKߡZxkcz+x\T*3 |1yDlU*$izUKX+UV\24,U̟Qr%2F>\[,Kpk\8Zy-pM=\Kiԇm \ؘޒU_hL PIG-T8e"-̼ 81ň8<"(L\("-F4wy=zXd-""JREZyf x p݀DeIj;S3p$ O7PnY}]Xd,U2P`sf?#)eRIj#3/b4wLSf _wu т ~Q RYH-eӏ.ʤ TI|' gW>d,U)̿ј^8)">Q2{卩F#%ieL}eJ`v@6 p:k//D4oy:z~ ReXh,U>Gބxjkx\d)ՍBIPxZ;΢*K "G&nL?ʤ 2s𿍩 #H-3/NḲy̛CidXH}WP}81pvDY&tpScB9$I }c~*Va"Mb"+td%3>טz~Di$ ̼8~0"V*Ga9*4Y7SF$4w4ƞ"I eh>z:l$RXH,36nlL\/Jd激/7K$[fX̣y0}S gRE̼ؐv`kqM4t> Q0$i~, -Sf\Q^2/*ҀduNzj';T$3onLmK#I̜ n R.WE *eNe?OMh2$As KK$_f^W?+̣S4'*Rm)ō饁Dın_2DuH{(>kFGyO,6> dQh"$5x∘Q,$i2F`zGDlP2W, ̺!?õKfRE݁6>ہv~O*LRs 3"bbI$I dҡEJ%Y,U!2O=j;eIc&)JRW}ՇVR?"6.D0&Zpe}]>"^44E" | 3*Wnl<80"/N/gh]"I0ڧ{ f֏NT: 3<~cz1%n`ҘSGbH\}h'"1%2~zV,TYH7[o<>v}\*Mg "IZhQ8*WWK.uo} ؈jpǁ"b"S9HNfxS=<"v-G>h i,Uˁ Y6.ED 'z_ō)KI?(G\W_NT:*3SSe/ߏG 'my)Iv&`y˅JKuqy1չ*xj37K\҈xޱ@:%3ocn@[Ews+RE#REkGF2餑Sf?(-@1MzyF*W,3&RE!`=IOm 6"^5P56)E4%onV)e\]xju4b2|=UrS㩇'G RtHhJI̼ث/3z u42 `]&jʖO%* $MAf|~)"R2Ϙ\u42Á3#xptRg]BHkC/2,Uy*V5݀+]*-W6$I7輻KCsUβTDf^[3`UV-N$MYf|΁\44*Ҙ#4yʋ+"I\j~yp"v)Mb7L?H IR}0?>"V,gs:REy)7[GEIIU$Uf@fQe<,U$̜tꤧKuG#bGfJI'`zmDV2ψ}/u:RE2s[_O-A,"d"I#"bqFYo\Isߡ:SΎGo&5,U$i\ ,K3j<^X i ,U$Sf'36~2+#bX|餢,U$ie濨W |lJ*$KI $3<xp{WD6%IXH҈̋^u<#RsUI*XV"IwO+$itpW4GXHZhysfx>IO?yD<48+6X IҴ<x0pZD_?!Su̿gNF8?">W"IT딍i?33sV$RK*Ef^6"3j\"Ic(3g:v:RU*,KI*3O;"bꌈX=*4F2Te {giegՁ/3OD7x?#&T1[U*<߼H̼-3ΘqTʫ-W46il"Ic(3C<;SREÌ̭_Mzz-D7a֐zZK$NT%[RER1yv4u_G+-W4d6n<"3],$WKFē˦3HSb"| 3vuS#+RRHBfAu_2?+"S6U'V_-AKIC!3ge1T'IeAz"T+z,U$Id ۀgGJeS 3HSb"id<Xx#Mv}ഈEDt$RET/:'Xz޿jV\S44*R]|x;rڦ oG#bˁ8۾ϙbI$IC'3/^  M5|"be`zxm(ҔXHjyfAUmK6ΌER\!ur,ᕙZa˚Z}M33,U$uBfޗS2Q ˈ1"xH6' "In-o3V7f%HSa"SrreOI/Y86"q76!3U,$ieyڒ!TIyof <x;pä | [D|)"tFx2]z+E)o]?XD|d!d4KId zK!"N8F{)D9x%pz=?Eg JfREHO6΢:'1sW"b5fa2i$I]N>*'׏/C2KI#'3-uLzT[7EĊΨ(л}g f$uP]lD1>vzMfN)*FVf.3w2%:wX}?CmLו#IFzط`Rz۱γT42x4aqen8-"^X՘e/7ny$ibe{zꀈد`S-Uyi46CmΛEߣD<1'3o.F47#u0R?>`/,U$OGWG9}D,9*'"ј1=$MY}WWSNʥ׿f%H`"ie噹j&d }."> 8,"HU>1xSf$I Q@p^D3l =e;??D>ꀣBlYwI$I7y& pxmTQoiڶZ2O*4gÁO>=".wDģU۸٘5]fN&IҴˀ"^OF,Rt$ Tf+3̧R9`I/ Rވxj{/јifV&$ieߨ~~=/xDTշ޽~-3-G'KIjsОT[Etw_Fć"b9N.wtGT$Afl |Kj-aH}e"ISd扙(`/GT?8L>wqEDO`\DD|8X"$Ij'm33# dt &"V pXf^S.*GϥZf\`^aOEĆ;"T=OS*w>$IsgO`OgVT A_} gREIfޔ_́U]5?"☈9"5#-"Vk663ߝs*$I*.3o^H_DxA=.4,U$i2Zfn 3 ^rhD2"f ,􈈈5#ξi9*TPf;3OWQ,[_/ n|GD\D&@X!" 8jtLz1t$IC/3̝zo;+"++"Iu`)!3o/EKIywfou \;_8,`_ඈqD|)"vER_JTQ-5~ܤ꠼'eΙysJ42"`CM #bAfR]v7<{A+^J>fVL WϬpy+3oӧ)T=jܖ:_|O$I^yyxD @Yq%£؈8l;2IRE:"3:`=& 2!MRݾyF^\Mim,Xx:%TѼ |[|$I"3 =">lM=8RfmBS[d/$uP]zlzcO:wIǬZm9ip{IqZjӜS~䬘Srpf^9l$uU]8"֦Z`#Tg23g-#"Vڪ;VNTP_@u;_ʖ8Uy恈Y|^<XdN.ڻ}!̼?KSȰgDؑ`YjsQ,:ggP}^;CƤ!b"I#|DD+[V3/0ePn*O.jIF]f88>ը/q/8W*4fpϪeGQun Tێ..t)$IS?ZBD< ؤ~ɒ7?~ \Ok`iYH(" 4¤W4nn[$-p|EDfPJY.EBQe"IZ y/K$̼ tKK$I$I4$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *: IDAT$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR *$I$I-XH$I$`"I$IԂ$I$IR GKG*CHq-@$+FTٮ$I$Ivn$I$IjaVH$IqcR-Q:F$I4V:$i#I$IBJ_ IߥH#. K}h4tT9 tI43RE̼8ti T:FЗ*ypv$ tiR:4f~(B+CuHFH$>.ByZDl؊|)uÁJnlገE݁+#IҸja$IAgJXT*IF-9tIaҹRE$I$i_S$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjRE$I$KI$I,U$I$IZT$I$IjaD{WQ$$wJ# H RDT(* JHĊHUINy==sMI9gvwΞ-32XX  WU'uo<>WUoK~"r2`UվS%_<~^UؗL =JAUޗd借<v-JwOQ}Oa%i"=`'O*"8e*Y8XmOU/iPvokɳTIH, 3K 5=ہ?r{akL_ÁRM\( rAy>t\"" U+zRXۀ+UDd_TTTld$agK]HBDβ7p[)@bq PTq_Fs4(0>.?!aZ`OYDU?O!"KcWGs7vG^:1C0gB#{g,LDf~Q|DX{!L58k0Y `}`n0}-2g]36%$g׹Y\l XC| 8J1Su0G*ʌi(T~Gx^\"/^\FUo,RHJi"w\U} ݚؐ.V&t_g|[^-"33*βhsօZUU DYEYBP;; ߮*UuQl/"CBKaX.+U_ػ^D !w`*Ty" IjPADRYlZQDW'LDD})vgFz#݃| pBHo4x8ZJB4c]S& l8λW1JJ4<]XwzC'JBBB;1 CQ[jW~QU_(;3lHHH><퀟3? 5PDd3`OlwQBBBTulTU?lଚ$ `fNSUg~n)U.Isʖ2KBBTU|$4|$$$TÙJ||$$$$$4L R#w~C*Y39" oyrрBLRImSVűLM ],Nzm]8s&"C+|LP)Zڎ!KͪPe,~cNM_ +"OcGbN_a>֔0mc`^Xno$" +y,2,ǬU:s!7a%}Bc뻤X(Bt_v1X Sv'UuT,̊QxIUG Ys vNU}7v ANms>xiwvΈE$[g〧TvOK` F`a᧟vʝ(ge`l yv(_puy, X_yZ+#bGv::^C9kI̹X7xk#uc &OMrþчm2=sG1(S;i86w1Ty΅w\92&W>Nݻٻ:3"M19`l?<=b&lܧOwAXdu6?~jk>0yQL\6|Ώͭc1_׫yܺ"6 "^Нu<.!&4UcZ`sCEdl{SBVTEXf]*hwhc~ǖW*iY $oK7590 7U9:(eh6&2D7+Úw ݊|u4[`H WJ}|V "{mȊH0v_,r_(bG38xvb Sk6{,t5 !f< ث.yAXm|-ɱ,p ;lQTw߷=;ul _}T[F]cyj[8,00K7 1ٖ>pR7q` .ls s~>;Y cӍRQ4"9t lǧiǽbϱ|pq5uz\IL6O){5<b-~0$uSnݍ$-o,]]QST;AZb%?+1,Xˮ(Re0 WKSS ~>~hUuaN`".St?@! ?` xeϱ`*fZ8K76Ho kMy~=\{2c3_}w0!jKl&yaEB{_ݖ 4Y@7(h+"K1+®@E}qDnlKü ,U`{\A y^d߃3#y\Lw%/of.WouxM=S&-Y(uJ (Qo+v(Lwv.#Nkۻ{R? ڨK*US/pFnu V(9-JM˔Js(Q JC 62츢:wm=k eU̪|G3ZiT|?|$ V)Ee@{bE_?Yć^WRg֭+4'akY=pL.Ҕ)U1A1 LaveɔAyjt2óp;y¢*iG{tGw>T<>FƧ+/i8? ~PDlHE;K3+ c=;ޑqLObBK9<6Ԛr //}Cbѿ2(#\xUv-YTGwoDއyV[< 'Qi[&'l--&R3cJF"+3y^m؎AU@~P;T +$(UJfx4v 8"MRS>owtLKPNR15 =Ǽ;T _/IlAT(Oc!-1M}#23W(*뇘%nFwQ;֣/T` {=Uk]2Nr5֊/ (K5Uͣ \C[Odh7!` ,U>,Tn y;\53VI,yuR_*UEx\sG?-x:!Ebn2ra*TiW *U4_ <~f]׮1Ej2 ]EӫRE7 5V7?K65K/NbmB~9% }? |L*UMvZn %o>f^PR _T(hU*JztG==E*J ӟ?f0_t} /d腞]=jh;T, n[#oN8(ܹ*'4HLJ|Wч;n:j^"a&4M*JI?Gj^}~AD_$C Қ6Ȼ/* YAG+UBy|爲 :P*Svw~ꥩSdWdh f"_@څ#{D_t[JTlzC[_CZɓ){DXnU)WD8wW@-"N{pn1E؆Q!&ql~Y\]D3Xù1 e19rQ?Icczu8+/ӗ+7tF:pÔCB: o-;_:i.FD3Rwe.ŕuD]&2:/a~ !"`>|$yj9B ʭ1?->j|, y,K Rz\_X# *Tiŭv KuPH> vIKBP1'|vchU{4>ęnoʉVU?PѪw{,춅T$ A-F{o("{%PCTuO 1|D4U~pcZ c5>;^bc]}5W-%UU|DLi$f'U G1- U[{D)S0 sJ)8ȔGaU>9ê::Dd!G-/8/RX Ҽ}7_F{@~,ǵJKr~Y{F5NPս\ʫW<[~Lt6-*I'W(tJ3&"#1 ˪32U1ﭪz>XO oLݧ0 Sqnlsl %D[s/]w<`7ZND^AӘ Lk4 a۰q(׀ ;~>܎F`;O3"w :"fusE<_.uNFBg#9>`3j9;Z9Ay]I޲.R.vF5ØHXo|*UtZd(y 2A%_\5ADuSD[U((C>DW^:a}13uӰcVס|X_]q=l!r\X"m\M,F_hlp=/\2J~G0Ec^p>̂mO%8[گ虈̎)'6S+ IDATʕ0sMa^UhGn cK>oX9>)UZBFY=$8&"-zFm&Jp'n*b'9gA;fM20~fˋHǛ(U̧J6- 03dP^+1f6҄$z@U?c3l~DOM5GɺwDJw"vzߠW pL5O0kJ1(36-} *|"! P\(o;h*@kA\c/ѣ <_(X~d썆[lmBGѷ c ,gwZEBAwP~/CSy/\77#̑X7c~ 'KǍybA`QDDfL7SHޛf(*|\ bћ~D$Tulg<^;] 8[U#)>+vNr5|o>9℩a jV붃d%̿ЄvjF1ݯtb .@Lg_a+:JDŽ<^'1.Z^үT-W_"XMskRv̇=܆|X{ $N|1T Aј7lZ!x4ۨ Ѫ@/B>i`4&v. |cʀjW%cK]{T.f'7Ehr"ά]B92ي8GeDdrV!osW{WE,[ 9K}΢#3vd /"bf{]fm7܊EhgW #߿&t;qv:6 q%>8 |'!?S}I=55;SNQ6lJ~fep39 mvƖTDmpMY*cdOFIK1y9'[Ѷ:Q>d]{T.B,@C3* N~uB@U1Ù-"a.VuDd5 a^;@!VO`NȖ 6lgx  aUC4 ziGӀ+nqg"(kWZ ÔpocxWJgɥ77C]WH ƔD Tub;<~ʀN7;_Wh7V W'fsQ07壮]J]觠 )eYufF qtU}WUcu]ੀl!>gGPՏTN\Q@@6'psQpŗKUXӑo8y_AϴJiRz}8VzS>g+[cULUSZ`YfɘUM"6j\ߓ;:P5 ލ{RZ#t]z*ׇI]u ehQ ;mx:B&BMGB%}ʟb~ Vdy.e'Un&BC_BBǚ3;?_ y}9U}\U CBXC1U(BYEۤ=BD_ЌRp 3yl~ܺ҆W: yno~D:o՘_gy*#j%J)h=K6CDD1dX=' Kyx`)ر^' n ~otL7,%:"qFU'zVg,w "s8\}UZl򡍡 wa !"Dd'xyv6^Q@ropVl hzpspFl}5{ˌ nԀa"r3wVE$ve@ɍEisp*_"oi8H%n*gk:EU(~HY 6:q`:\;LD<#ʕN1m2V ޷)cѵ|N"lCU"2׆v9EE3qH]CgsMmFf[N,v ԘTZʈ?-(U|GY- 9e8?>o)"afKvm@^񔪆G,4#yX%Ӹ zlBYCqE}b~iƥ؄Hqqc~ݚؾAamPk2^ձ"=8`䕛Xۀ6a}VoEJ"R+@lF[*"2_6 GyNgD$ 9Z]:4ۋp-ps6]5W5ޭADԓ[(8K,,zZy&0Uqcn֯_ f"N.q@>w,}yvmPP)tfH&ޭE$ mжTf;EWm#+I'p.ӻ9k:|e]Wp;bgx'W3#9[3nWz\P'C;5m,86U?)k|?8m ed#ñCFU_-gDK[X<\oPgId&EoD> xڻQ܎ Mnx?)HoDߢ WjX@8,{{j-4wqJR8 J+iM2 v}_]J Wbo3&_CN2CwEg'VD:i>"RP,W),_7L`X䭥cm>@99|_\d=QzΎEUmlelg?<8mջ$pISDVwJ vK!"zn.KmXzU Ddyz䳷w~Dul*/Umku2oe% Pl 3{ U}|$5D䰪4] Ȏ\!_""a ?[ݾ h,"TOhگp[("_,wl._sJӯ`Vi`sn,Koj|K,TyY W|-pwV 0hh'{fvc\ \8WU\_^3~7cH;!x>CEڱ^g;#aQ|>͆S|rnwwgxV?4Hsl >?J < n#ՉOs^ҬcA[Al |<͍Tm9{ ̻ Ͱfv4>{^e=>|?y϶9P _[gc;g C[g6w~=S@Q )[03 GN޳%4t/`Y8riTAЭ|Aw8Ɗ 1`&b}d1Yl][mw(fO`|<1ywgxioQߝi&?f Y:]oC䌧 LX͖M^f/꥙߻\Z^ aI'6GZd ̢頜QUbj׀lmuBP޳Oyin֬ho`lm%= 9%2TAb Y^c3t3`Y;XbL7%&fݚ>^0l`Gq`VLK|o$ؑ(+~e<ݠ#k7v}.-]SfvFy35_K7*hB7uq\:%u,&G/dTUXD,TvPYRU?g*rkxk[oc \m("+VT~ȹ76AOhma*wc5Xn?8̚U}+2wJakMﵾG6S82tSn}}0+ X>ֈes & --sVL]2U׫S/Ddn=͇Y^m* 8],~cBKT %>+^*kDO} H/8 aޯ`Vȍw(vtmAh\2%VQ|XߞkceKaln1n0vgnUmZKBB~ .6 s>I"o;Jx>,n= < 9+ =A~N=XyHHHHHHHH8Z*"2wU}Xe4$xX?DO?ooh66. XmݤwEMƏ>|Հű `:^U =Ez 1PDfriWb$6rs'V7#ü^S]ö?b+)bm/lj[FU)a5yWw$K=cCQ^OkO*EXܥ0!f^}IòScm X Ás(ꞝRE8y+%tڃKS0acKG{VE>9{L^aEڏ1'ۋzgE:|_SƦyƖKK뿟a i@ p&ܞwv@*",ڂrvWa U_(گF|rݠـSc\9V%(RJT9B)UEsw+LɄ0ˡ~Sߏp5#[,j- 8S<V_R%^*+K78 [T)[n(+\L~y:@%Вj*u9.to`ʿp<;ceFcb\]_U4T?"|X`!c1oCҾzT`$e I8啷Ef21{\T`VEuK@YJ]{;S.!_j*ދe$J__}l'oN '䃼geb񁅅ێ/ ы{NSE~9 l*v"l=H#1,h G`:nf$\o轀EY[xm~Qތ}^ 8E {}lDzLBegYC'/oa`C>E̪c MRe64eJa{XPf["P1!yfu4St|3[#` \e=j )v'^իK0+ؑiUUP Sک݈b4sx|RTv}KJh׿(VxJPҌgz76n/)bUHD{4-EުNߠ ?V 6w\Y90wǻcV)(1eʘ-jwvs@k,ꄯՃ;&J ABJ䂶g`y1E\F1p8ٱ$o*c4_?0? =g1y+>o|MR{)U|$35,.}ˍw1ccdh @; =N+UNޣ~cl<Qσ2;exyJ1nLŊ90RF?X&gN6) |%Kth'(z ۫WT?v}и1 y}1Sdýs1ʣʍl!+;(> T ~~7:9=̻5 3.މ)2l/"u.`fZdO-pl7j)pTF)2 ުrӰXs[UN`~*laa皼Xp.N6U[C ZRU96F`5g{bUsI~` >WUs#֣ `'~Z`K`oO,zLb0L\Oy? sEdp53HDlPخZԍƗOu.>(DdYCT^n,2|QD4o-5xaV(UpV8gvώn-Px/1 ^Îs[U*קϻ,]o/yǒGbG@3HʠXO, NO~Lݴa !:R䣡\X$ ck8_U߯x~fҚa2B'f%Td9v"@]^x/u/@vQp}|!U71guFbsE{sZl.=ZE)C)BDF 9:JTW; оmDM~Y7YޭW8_>.zG) K!/·"1 UuPhY.N'.y7uץSDĬ2!bG,3SNȰy{1"0ld:͎BMؑq"2/a,pͰLg(2^'[ELHHHHH(Ep1rYdBm*h}e%t,$o% m:r] b+Z}/`yQXM׼gY!FwI[ 1 Qj,X9^UTj̏TAU9uM%n̩*WT}pq;/iS| PTΩ*vUX{ [}һv[PZ ΌmUGUGE1`to{I^U]SUYmYf_LŽeN¯`O -REDvO|) ᄝu"h^^n|<\W-Tc&EXSe]c#|T^ %+[fGTW*xhPH ߷ w&(;!T C-Aae|~wEB=|*=cGYv!" -Om]n^+*FNN:X k)oK`(f O#9B}D 9d36eS W+Ubbhg""1=BlF? L1:WGNeU~ Bˀ2;M7#¶0X|WD"o%e\not&(f/d S):T Ϫ0}H_y}Cs"@@c'z_UԖ?a;"*E'`2 R?wUEjjaݼ[HUzV_)Mo Qy~ʬ^"rX 诱+VU'"B>|yp+-"{*>͋GS+X4ZzXO "_!}U,b%Α| 7 vnؖ%^I7=Ώ ]F'*?_!}1"|KT~oU7 RE̲`Nrрu|$"W[Rh&@BX_ϪHB,"b ]i]|xHD>eO2>q"r79.<{oћWD?`r5ܡbc5 W"hLb HA&}+tvm[l?@*0|ZtR ?-A(lK~&:}ޡߓ/)G!,5s υ14°zBmi~g4MAUUP %L[us!g nsÀNRտY13 z]N n,Z:.$霺74 s쑴a"aU`W-uoV[ QT =ɷN`Bf z$_&rU}?2m bin4|> M p$p$o݄ |ap;̀EA;VA+AVG8PS;S"ROt&m&vI؂0׽y`pNKuaa3t*duW;LCh7EGќO;q)!Q") ~<{9Ӭ(3\V@Y&rZu۰֯n:Y<36uBBBBThŤhplE~'_܅{2pBD&y_c,yO_1DdY,0mhG>Nv`3("P-NS,`!T|_ǃ1KUutd) ppؙZp6WHxe)ѿ D҅$d8aߺnޭ7ouSuy&y|!~:0:]ќz-6}vpʧ_yG&AS; _"콿d xaD;DtߦRy+, 4nd@U yWGn^3|("ȕ"rtaBBBBBP$h#o]X/3T,'d,Ud99#Upo E;V;=vj/L)"gU S_t.AU_nNt&Ʌp9~~XF7FpVS閕J<_DJ+"u,TcI[a˻trcHk]_DN9{wkEig6 ! -&up$g׌qG?&#Uȷ95''ȌXI<'d;"qUY8])q)eAD6" Z/4Xu|ID7Dd"[wO}Hn^CS>|6 S ZLUUEZzBn'"g±Ge? ݅=YDq~Wp̎ x/ U/"s&y'~xX=b>_sNti6tuXAXH-PDVM<"%VǙ^[Rd gE$Tq.jw<2l)"s/>:@`9frgϻ[걍^Д!N Oq|U}CDE')sݽݽհa aG2l)"̚-ڳEppCU}ХgT=fK1e‚{gcGU߁B(Vp" h1!nVJ!FTSFQ1J`XJ Ԡl-nRc8q윙t=K&ٝ7;{=ܹ~M6.k E~dp,vGa9|a`I9OrGUI2382NyIUX+[EdVLJ"҅[CdR;K`by}LDGj/WtY귗慈H9.U:fw\I仿i̺̒_/ Ƥ"u~!>i2-gr1"=ӀoUi4:("K10ާ]\ d/W`6TAUSo!w|bk/&/ `.n)̷4 oS՘Qw5NfkIu[M77H R 6`o/_ks^;dn)&~)~[sD:`;On #0LSu"@9/G\~([M ev)7|~2og-> _~Ե3O7ݜ/.Ix'fbIDATLg̲2-_vcZwW!xΕ+~WCVU}DDN>v%.mMZ X4^`*'c|D^o!v~iQL-:}Fk(7j75;/ȍXޝDqi1 8~_5eJ Kȵ:]DU_2/J]'dP:%.wҹe&>Hz<ơ&ix_5ev4AUo0M]c(jTusxL5e 'RޏRSNIo;y9>fv[U:u9=mm$׹XyК>D^$9N U#bm>l_e&3Lfam[;7KR&_lpaօ-= <iړLP`uߞ>Dzވ,l\T-"-S!-VlôMIER:8;L`|`z~kM'&3rwNm@VVF3h_3B25<+]oNM \T  NE  ^}9f2    (*AAAA U    &A?AAHa?S  h6 wjH  9aAAAA0 ^"JIENDB`PK 8?J11-Pictures/10000201000004B0000005DC7D79E82A.pngPNG  IHDR2`wZsBIT|d pHYs.#.#x?vtEXtSoftwarewww.inkscape.org< IDATxw$Eaw K($$9`@QT^IJ H AA%JeaT_U=3sy~`t:eHS0(%""""""""4X""""""""h `H)%""""""""4X""""""""h `H)%""""""""4X""""""""h `H)%""""""""4X""""""""h `H)%""""""""4X""""""""h `H)%""""""""4X""""""""h `H)%""""""""6~ f0q6U{D?^GD.fV`*۸=j "f6&/jHٗ#+nӋxwҋP,Sl~`u` `5`A`.`lyx~rHl ``&zw瀛$'\,,, 8p uf6smT =3  X& '^2[?g˟_]7RDdX`{\S]WCbmw# FBM5cܽ}tfv"XϛEB}lL;f?1fHE `2ـ#kvZo2rJw\ӾMeInRfRg.Q/ |/ٿ]O43[<(0_ U-wq 0w+ո0yۊ6NwDD3ʁ%C̶~H$S]~R3;@Nr`1̀+"ˁef>USu"5Յ|*Vs꼕0D+d)df3L:5p26e,XHqcs`YүHK|7n5ef_ov)<\;Fg{Qh{mFCZZIIaXԞWs^{Kbo29poZ03[ 8X9 wWYx.E8oHl45)c zJ9En4X2Ts<|ݟM/F/ф DaHS~8pxkf6xM=nw﴿nfr7*Y#ґɄ"3=R+p(pH*?G8Ngf,*c~JŘpA#}iu +n0efߊ?bz`#BN-J#"cQڇіvf(E˿Pi]N"?x"A~A*xO=~BHn"p\1,B <fw! 3awǃ{a("2PPluŴ(+la(yu,|fv'q[G*w6# EsƂgڊU"" !a7ot{ܙlf^&q.9b گ6Nzۙ;nNswZه"{^Uf!X;c*^Ǚ9PO e""RX2,va6^"aDD ćgCFط!ԞX.w?$['lcB<ӣwv' K#3ݯUE6[+Hci4CM,!{I^-" N3[_at׿Rl>Bp7/pawpsE'ƉSK{ } ?\XS2&m/wJ~,)/c[bǶX2 bOxx""V$aw,j#^#i3{cx >6wLH}!3[_d,(1%zvC'f1`>ׅpn0qw֯%!9y#NDDa0wl>I- .JEDz_SOge5<Ϟ&n3wB'=ww׉Uif="""u,2 K;j(3p#`L$ |x 7pXf# {17އgefoVhYx3||YRޢwoP'ʷ3#e=Wϙ\:qZ{x >FJRWCrAȇq>33` `qo"'Wn5% } s F76=r,1 0p^X2 (qg֚nvl lƴy`b1+K3pS3[^lGr=ffB( 3؆SVS>"rwOk BUGfX'kv%1y3 o9fPhf~Nνef7FVmf[SJl.`늻<3qo@,3{0dC 38v9VeȦ,Tl}:>]vWyl3[w2m?Uv6yx~s&,X}G~yy\N\>#@ȑ-4_^2?~f&uքsׄ=LﯰkfhmD]F/O,G ]}O¥΢A`OjnɑЃb"U.ߋ٭MxM[GW˳}B}w-v|{6 p#BϯN7 ة뿻d LJ ;{ߝ3X_ۧ1+Yr9bN[Tl;l9]?+mܳzs\zow^,aw`_ߑWF!,=>VOr'p00_}Ǯ/\VQ-.ʁ%ͬɅkgfo''TQ]726mC;5g| p]af6.X5d9؜03;쮥gf[># 71e>W^ml=l cf_ }p!(Ӄ׺~jgfe:|:p]mmv!}sA}iEZQՎaؗ_\3ְ>0j\W^*(8 6y٧ C?IǕ]h7fv]+ED5V.e s#V2>Pfp%\NTlŁ}B΄U["U\ofk1r{n{Bތ}&Bo-P3En `fKE Cv'Ywv`#˩aB 5jw?پڽJH?5 =Ts4qY[>Ng89wd°+6/_8Pp9՚l{:+fv pC^^ 5݊Kfl0k"Uo \o=w̾ccNH_1ʣތ@woҋ܄; ?#xp#AFfwZ;3[#*5~!Dúe |5u6{*~ӶkY %A bf" H]lHә"_{ܤGo|\P{GL˶4/f4]1<7T#u ESG.P/!?@3pCz۳6v#o:o~&ZW'#sFGN{9;)uzw±tzJnf3 ɴA} +"U>0wzLvOw0oT n.Kg_wx]w Lv,DA`Ӣh9pc#>@H2ﻙM$|c7s+ꚋR?csgaE u3$V#<;>%?81b8!DxVwaXI}(Ndb~RSk%U,B)VT! K{-RMژ:?G]b!9K-muPg*-KN*]2"Dbw+kzR 2{X:ȣ A<;/?~~hECe(c-eyCf]3[?{"9PPR(wɤ*uz荲ǽOl%B<vtW#\DYFЕ>G}Wa C )pSivLwл027L w߿l{uw?Ă0c {J-lCF6gT?ٺď=,t3IUoU6OU;ws=R_R+!|2e7t[oM4x:av[{^fț]{pR֋23ۋxeJ4BvSKQY0:B0fe6l_7_C"glȦ|?~Nu4<)4Rտ3$!Wݽf?t$lfw1Nv3#Y'9\~J|̈́+q̥H)'Y{;` e+nX?};q!]]}39ݯ# 3ƘJ<Wirs~Z {9/ v#9~JEY^Aq2E|!⹼Ft\9n'ozwtZqHDYىv>?쨗-I9i9)/a -u 0~w r|xgygn~NJcf6oF{{zH]HnAHڍY O~r晇phO?;}<" hǮ f&LR-)~dU0H(%C_vǦ O{of4l;0[ xGEŒ0u8=QMґIpZuP59j.!~Dۑ?S#)+uL tx&֛`ևeumo $ݴdπ yL%k,a_몯R]h:W5)2+1YkBbforӇ]]k:wA}aْi]B60¬tkNg+еߍ&/(ڦܽ_ꜼvvOakGڹ}70?YXvoD,H-:<u8/JfAum(-G&v3X}uƓN[ʭsCR 4~·=GkٰԅsjJ<\@a큒VwU'K=LA2JۚYWRJ{ *qVb:]aKu~M}RgOs^iG*Poy }%hmAyk? 2I;L{Y"R+dLȦ?7!>E%RǴטal,IUӪ;eoy_UAz wuKT T w?nY"  ~1 ܦ/8wr+( dosR#=R2)޼llHv-/\妌ݤ.N'>>-%~^]4TޛyiX{͘ `eN (1L{1tHҬc>,X#R3Nnʺۏ`AxX `L;,laSճ mx:s ~ |==uֳo_So<y}gmƴ].K:+[?.4lqG$HvaB#+ mBʀ?Tinfn]<ӏdRIu#"cX"q"b7ɭRHgr+j.fh{Qtڴ:5s,V'KMPs`jj11>pXz_A8Xްc>lH{`K%W?8.W"E/Lpd[EVHH>݊z]TPމԥ(2\E{/f&DQ[֛ZDDdӺfǚ+ZQ$u1AREM~tLO*(;Uw}M˂=,خLy8V0^௑lAYҫ2 샭~SP~_ZVԆ^ Ѭ7\:VѵAϒ*N1"2`fنf vrDITlBbzo("i\)uL7?Ǻs5Y.D{8ja:w/&2ۄiA_ECRizsb-/=K0#߳M# :;ʝ^ww?:7_84,wwR `ɰT:BյX.e9ĞvXd[Ƃ[eYAe*AX:j1`+(oO*ޭ9kQ󆙵&ו-蜁ޭM:w-ܷV#`j IsH>qhN rMH?\~[- {)u.x~AIwz! Tk uƆS(z,I3`A*P\@E jHlf}kU[B-n}e.unfK%]ry\u`K6YZ#6|peՐ%ʞN~k; +k_U'i5]ܵټ"26)%M}Oɬ{v?A:֓3`f3-63꽘"uט`N:T>Lwe'c(k՚kw#JZ> 9ڳlaGDy?:n8cgdڞQn&5UQ/^W[1y)N8^f%ۏMjL~UY:|5ā lLHC$+uv8ՉԵ'ďSͺo؜3܇LaQB=?Jmif&6 xnPYN2:Q+%%?Rf67DYp1B5^-uEcgtRWKl{r|NfKN!#iy3[|X^QE- KKw {x,x: 5Bxa7jX_J~4UD_>㞏\5Օ:'_i?:x2EY{]NQьdAT~Flô1sWW#CO" (׃[;&.*[I6O,`2SFОs\Y0lNyI _KRgnrG+ԑ f%_N6x4OP;MZDfkZ4~!$K`|<}<XF$?)g{wXɑ6Eߗx/3\s}Uc"dSjhx࡜X%2gKj jx{6LA>}h>D"X}[t~&[Z_ x}2߀ 5GoyzIꛏ04/Ek+qj?vwuPϕv/l۷-ZvQ,fGiOO?^DeS{(+_N'hc3gPkܽu,AFёW~=zbC[e縢=s_~ !Xϕ=RCwm=*Ի2Kl{C[]x4Rֻ&TNa8ܔ;aB6`sٿ-Z ZY(`9ؘ\8/4lZ߳c`u-BF|4pa2 !q\츜'wwv>2}Yg ey{Z} ~.@Q{R}BKn*x?[wk `F_ǿ@ hҜ3'=K[c͖q97~|Wgٖ< WUkyKI]Oe&#܄ ;2:? %3aw/e̶%<5 z0ńcy3=lM}2!!ke۔h|!>#" $~v^0n=l]ifk9й˜=Lρ ݚ$v*޻ Mo|[9 |8ߝa(#a ߹l36 M y$ĩ 8x ~csf4q_r 3F7@'؏4٬&<! kke9/L蝗7c] = EM2E<{,U# Jd +f'= ̾^5j< Jv|M|(gz=DZ؁KP_!c*BNx_W$\7輧ri4̠#hZY?n fsJ1G25uB^Jz;Ն;x/$|/^63!ru|Y}AiE=t9m=p޲B:S=bzq~Bي(u5kt 7RuѰ5юPROvQB}: =hgݩDe\ Mד5M=ղ9yc=3;]!#Ez(j1:Hiیm]F`AhR$2woN8W 'mu^>+7mۨ_vy;}4aӆ@׍6Bg:| ! Qw;pwNh0ew?ݽpB[o갊ת 7X1'-z]CTB=o&ڹ- =Joe#~PP5ˣ!e{ֽv$鴷쯀=5sld=8 vuByH ~$g\^'L_TC0g2-r)RG{D94P@NB?Sy=v޹޿{uބ0kk`M!Bdw3t7xٶL LKuf(GEqV!!$/z82!/ f6E& ۇ0 %Lך?0us\f,G8ﯣ-)KrXmO|(+^o86Ois_XqF1]r^¹yClfPeaBxqacNvx]AlVa|윸<>a]ه#C'>K02!{Z7QB@WSBIN& -YOmpw6_GjB[7'=ngS8+bvH8'?5BgKDA,s@by  N1PzrݿDR4?p5H#if}Z^~P뀽#e{IȹUx`NBm%m"ۼ܏lsO!7GV>]7Ց]KYB<fx>=5$EDeC .fl+Oq?!~szWe /E6pwE~Mlyc;0m @8ݿyC`-D3 x9:40ODzo@DDA4PDBH:W׹`sUٟVI fi$f6 W"}?m{y"p-;&H(%"C-=D0Vkw?J>61$Ip& 0lww?u` a0;aֵz_)4сcm ""2RKD[s^/~T)w@B1vPUZvV~EYo|QKD-St_7嫙n@_pzV1uAl%}WjH_er^}w{DDa]ׇ?\]41Qc093Xok"%'s0sUX"2ly`眢ssz麂 ƃ\}1sOS'̘)$g3:nft#"" Oy\3gdyf W?sC79q3sV|p3p1p4؍p/,L8~/)f67% "o'?WjO1+]s"?ѻQ6RňXgfEwqszrwߢm \XIw_}fݚpRNum3a5+7Y}}ݿVve3;ͤ1lfGngCn1(f-2/dw$dA3WFf2pG `fU{w \B8YsF1M yV3&>ThwR 0#0yu-} QN ""2i -e=q k ٪Q=x0/pY3ېГX:^A=5Sl3 9윙-hf?%L<ՃWnn2Sl:MU{_lY3;3r+ ~٫&Z BJ BO7ڵ73{ \Ov2c&¹ofvWg#nnz""2B6!!}kڑ oHD"Y"e`{3}{`w7p!jsob7e˛i(=s1axiW = y#^ л0Ds6֍'L:mw7-Q.=ܷ4X"24ĸe.ڤwu?| |]:cC>CI{88%6<, (}$xNfw0Eߓ^=FYw180;!6|>>6CNLll2Zfw]ا4kѢEP,DYNShe5kľSh| 9:*Ե#!M^] vоy =A}$@k%C*u@{taF^VQxѢE-ý( aj#[+ mvdjfk϶ˁ]y^%yztGWð:hXB~*uC,WǿMyyz܌N4٫B8fB.n:ﯡގV'K0o̬jV_){ ݿZ\!Fz.A~rZٚ'ݟ,[_OS7SDd3T{OiDd,(kCxs9nvxbi}jzSo*f LSU6ð$380)$=J:'nΙS< 1xxIBȱ䈂Y7;bfocڼS0SȟY`[/9#h+v j73pf'O3{;!S^iw=ۉ0h\A~RW=;ZaD$ oX"" DdifE.Mrw?% s?E_%$m3%n.!P{ ra#pxDHDwxrw?,RϠfpw+@b>]+mE}:3ߝV7&yȳ,1k+I֫5˷vY^nzzg T01lm3;7Bu .afyjv-6dm. se>:P_(;# VtJ,5,"WؖQlt[OSeyKr-0,'Q.#$ϳ?t&*KYζW{M =*zp])jyR=nPW >y>ɜIg_3Kv ī""M -@RIEgf8*a,{U~fvXV6 K 50ݽ)?NFĂ&t)Ӷ򍲙I1sd';}޷_~_Ҿwo^0M?;/i!SӒY!H:2Ɛk_+A+#S]SC-i"U_&RpL{(lIhh{|Sʽ*G @1j)`+pSvsexCURطM*`m)3D}O#g{GSD=v7M{)WW;F{uYs|.b:?%Mh`Q=9 P0P ֓ S~6V0hIgK2%a2E-EeLW̴A&HyDȽ~ևCD=v^sΗRDu WUwB#!T?Vﵦns$qE=nʱ.WԘ;qV_ޗO|}zofQ(+0 XPjq"~^uGjw?GZĘ'(*q,"OTRɗHEOG$)icff*unTԧci}S0n>:EΌ<3$s}Ϊl%E/tAИ[ِ."z]SydQϋ~~>cс`wFoW };[q2{e uz\1./5u8NBcT4Afv} U`}$-4Lżz.I>*0ǎ$Jꦎf !!+u!T/'pL^5N* /֏SִR $I -IZs4#(,,FuPJof{HzBWZQkД}?bu$m]d(ӭif)XVw/洝Wq?ۗk99_Qgޝ}m- -UxkL&YpJzBg~KBF\PB`($u`05.M`*aVv~0vkIA3;W0f/MPIgb?(驈 %y= PqtAH :DTU(Ǫhr<.`e\+)Kc 8'KV=%FA1ϒ6lm뒎Op9@򿹙}RҤJ辒*+LVX9P`?,B`ja~lf7NRyV;31OK:F4K8~+h3;ݣ Yq̬A_UABQq*$3>evI_tsfG ր?]()Ǘ:Ur*o%OW/Sr`XT X/`InЊkPUn*?R#fvtwm%fv?ptFEB %x!c3E:W)WRM9.tяq4]'G"eS ީ+ VE+LE/H{f*gdݗk .ojIV1ifvoF\$|B oPs$+"3PY-47SVjJpj~FǷf r $3#Zdp%%"Ӓ/qBu+iUIGK[I_+}qw3H#B^-."N*IuxBg4^sفtIWͯQ{}oYRE @fľ~ˢL,qB럌.q܊-~,i=IRBֺ*wn2anQ ֽJf٢?USD +z \ehY3=E?*1ayF_%9r }[TQ0 X׹.aي.nẃݧfn#CJBFve<~Դ|)3-*zV}%w/镈rAϧKw:\2h:$_\e점ml>>&鸐}(fYX?/R3.|! [ۯE0\u0 .C$}Rхl$yJnfI@hu_eyLtjba-bPI\|&qzD=G5acfI:>.Ige’un" $Q]3IKR)ΓeIaXRֽ xg_}.өR> ĬvrhEqMwjTlJj -Pw_VKFMźfoWхR 9Ms$|Jv(Vʡ__ľY~}@$qr<'W#io'I:B+>GLx%I7%* wG;!ԈP;"Bv4c9G䈐D׀2FI_̳[d{1bߜST?KZ;$[aޗp#iB_D+a:o+q*w+(fNVtW]oBQ_p])*vUݽCү#Bs4l3iA1I)ᴔ~`G>_MwyV|`qml>Vr{/N8}? :&œW27Jf4T3.c Kz+r;\,3dfr_`f41dw63c e̢Xbf{J8NE_$1VSH8G @6M}u_tODȮfM1*|ΪΈ3^3&)T_ .۟Nh>1^>IS:e*^s{1 dcu.g4*ϐtM:Y $s+v wIV`f;)8w_(!$%Ji]WeIZ " 4+[3~VhR%izȾ3lu)jJM#>#I25$W(tI{U*rwjffvO:cT>_ڊ]ISChf%/hnf$}%d$Y°_ܶfSQlߕrQp|28튞Z-BnoS*C x|S?`a0{ٖ1ǜ/mgU3;] yv}ݗ:_YԂ̬^ DZdvARؔIdIEpvŢv.u|3Up]H} $R:nQϗquL33R1lu {m[ܼY PIC;X0Q3 >(O1^|qrMdfGK/lVp3WD7(]9jiRUtT3(fI'^&*IVhIK:E|~3OjP4$gݽׇW3_ݒʱUusp搐G%]$Awo ^z@ߕo=$W9Y¯:Zҧrn{QA\gbfO*!:r7$I๓Cs7CwuUҡI,pofc%=$)HUV0w _[K:P/B)i;IoK [I^wb俗EՇ.RIpS3c_Qw%K#)I녽,@pf}#^ʕ3/(oM͒FF͒%VwEv7QMI:=MfEBIzAE >"iuIIVvpݽ״W3JU%I)J "E(xql%} ٳZӤ{Ρ1e C#6E0/KzCFR"J92E^Eґ~Qx+̋kʸmjD3+xn`|F)X8_N̮TP=w(*[] @P%x3i F7$C%cطy~W*(}] >VS҃\2 6L.1]2,?sl/!Ozq{wgf)i*z?IV w6QG+U-gIWjte9 lռV *YWyv4o;JtSY7xNɒ6CJ{)%@?C*? Iw<7tSnC攲<?ʌޖ)q3% g 3])亊t-`J Ag+$ޛFQ#wݬ5t9 ^?_􄻇-jdn :d1]P(`26=gusA惏UjwQ\fV[iQ29⦙Tbi?GZb*.iGw"̮Պ[$mRH sɗ{Ui,VÒʗmrv=+ Y*}$v[Mtyg0Ijx*T tcR/N\Y0PP55Esv~f6"]%VJX*fIzTAQ'z1%.i]K:+@6:Tw)igIٵso?X_WPPܽOt7D= wJ;@塀6t$| xIi'\`0QFs`3OH[P(`1*,T4 XhP(`Q@EVv$]uUߞ:u;0w 2lx2U֓^c׿rv> 'p/Kr|F 2es馛jҤIJzIvӒΐfV[Nv%}_YqS%--Ɋ@$}"+nz渋;f}2x;eŭ0+no3$mS}fVܚ6Ɋ%;9qe>7[i>U=Ȋ+ wZB̿w문y~o?zV8IK&+nђ'iv -Ľ7Rw%$27/t?_Dܹ\VpIJXم㈸SYqC%}[Yq-.pNjˊktZ%Ίkt}qwr_fˊ IK&Rw߹Yq.Yq.sۊo͊5IsIrr⎓t+F3I'fc9FK.mݦw3?U9c&HIMIXb4$sS[wEw=4+NwUN4<+>wߜ}%םENܞ)idVC~~qy9q*x.s{ʉYsxLVS"vɉAk̸{V6N4>+%5^ue}Vk*Yq(x[VDܩޙղy)xȊ\{Mn\:aqҬssΉLˌ7u}gg{;#!:߮O<@|ɪFmt_tS;@ܝ~Ry[<˵^555.ɟ+鱐=wAN!q;B~wKHe9q7_Nu!qs >'!q7.$o9q ''r~pN!qĝϜ=wzHK9q wJHk9q {;'k!q#Bω;,$CIYq_ -!+!q$ ͊;$nYq-̉XҸ !qKr kJV!qK%eH\6s.?ӊY]+$K&YqEmNn\-E}>+nL&|6+nDDYqC2Bqy=3|qe)x; +FA!>_!9qsB⾒1+$ȜCΉ{;$Ĝ7B⾕JHwrwFN !q?ȉ{6$.\ɐssąU_r = ;'-'.\':%lvtR϶n:~I5oNItWR9-ylaqaǛou &rr3=fwk,2A+>{d}77'.MS^erǫQ'7骹a b+=޻*}ΝJ;PSS^|E=#}fίcf\zGtIn+] jت?9q_gq(RC='JqFS?Ͼ̾.{uLq{d'KVWmpWwG((Em-.Ix֔Lܖ=eK@N*"3S&%)=S+]=X/!S ˊ{ oɞA&nxV܃ :`>`戬Q). vS זtRqkLIzB+WNqŞWp4.+I:74W\gO-(9[ ޻|IVꃕW^YO=]ӜiӦim̙3? ITY63t O~O>yݷ)(}E>e]$IO<&LPݶu.%3H:6L?Vϟ^,ג,$)H[Zw׉'ɓ'yI'/N%1@ytwVJ|."tAn;VIJz<`91,X@/V_tt`@8SWYgDG3>7 XH[k7ovuWM2emuuu>$ at`@e8uE+йסuY#R*sĉ/ArcR$,H߄ ?w߭o|)f(`Ln)w5k&Nzkm4qĄ$,HFmo]o{u衇+C$2dsŒz>@'NԻᄏ!C;Ԏ;@$сYuUuj̘1o:uge3}Mқ}򡀅0c } _Ќ36tP}M13@, XF{Gk>#^={v_?PB[{[_\P):ᆱ/| 6|p;dw`1G]Mnfmo[t/7Hmw_`F.Icۚ8q>巍6R;h$$`/?|m/az*Ŭx*3$|׵.hΜ97)z)C/WKK:;;u mWo}[!6Hr@fP̚$e?!ԩvܗThCFhmW:_R3 `K׸Q+y3_4d>6Ak ܭ.$]|MDƷחMq1vs9pT)`_m5sUԤiz>7hfKz/O{" k@Dں lH^5Dl-ׁ ^T{{3%b:сJ0IDIϸ{پPrU qt`!u>ox <3S%b:X]vtw. qt`"sPw_sP(`!uf3IY31 zXTY%%jBJbf뤝E iSFҘ]1@u(.iD3 |T' XH[wm>g{h*Yj*wtofsSLT!@M}FeY6*$, >-\Iz:7SL@ W{HQc4dT Xf6}@b !RgfHofO,*3I&i{I;ZizQB$gmJ+1$M3{@u(&^f^N6/ 5lO% UR\$.I$.Iwv2bN% U,unڹgHz.9][)Jс=$(ޚv2,T300|IBΖ33K;PY(`!UfV'Gj%Ms (v,NR}P3YL3;\T' XjK3ՉTdQBܽ]3%b:ե i}$=N@,]9ݩdсԹwo x}2I@(`jOIK[N@a !* }@ 3JZhf,*3݀H1Մ̚@IV"JcfKef D P23[UW2'@uym1g{D*Yj*wopfEҿSLT$.ioI;i' TPB}_o x}33%b:,@_`!O{K>L!DE0wH;lI7ERgf?H;Py(`!UfV+駒$ffRN @ lt9^zūJ@iZI어sP(`JffJ}2|T' XHPsGF rvIg6[%;t@K;@w'dҕݝJXHtմsϐbfCIo*Eܽ%dT XfVϒtmy^L!DTI쎴sRef.4LlB)(J;ՋV/!k{\Z(]%i]v.,@lIGK2I_1u@5ym)gG rvIe6$7t@K;@v2bfVсԹ wv.qٜ#/$R}IʹBL!DE0wm=0N;Ջ,NnN;Py(`!UfV+闒KmrJJ`fC@KjV"Jcf̮J;Չdf$J:I5!UT!9ۣS@UT{'2@ui'H:Rҗ$=o XsU q:wGEi >wnf*D WJS]8dT X>qi.O;ՋEܑ:33T XHJXI)f֐v,^RcP3T3sP(`Jff+K:Iǘ:&*QBڼ66$g{t*Yj*wofWSLT$!Ii' fU(; XHOtAy(tIHD|ISM@5b !dt}q)Bt`ߕtiy^:3)i o/:~΍ZW\ (`!UfV+7$M2KjyƵy Yf1VxcP3Db3,\T' XYHjtrJ/6/ Oa״~QeJrj> kNUnh *E rv3{F%-z)a0Vw[j\_(^`zI٭/ Qݘ/LHJ5_;4!P엒@ujM'Zh]VҷeZώk>fX̚%&iZ) QBr&UBh%^\}Mu.>gr+d LIV"W] `psvg$2 IDAT3{F%uIz=0 ۲^6W˝7grtZtV{V-C7zW):q-T#%&w-d05;L|{ALkȝgݧoS]|lVUL?`bVc !RoOi4TjF8q5_S@PmK"zwK@Yh0U]Ke 5Wj lt-}a)B G)w>:^ߪ8>o/sP(`!ufvofJ;@QB2öװː PB̬V%&83\)R|q9=֮ʐPiҩ%uľW| lxA%eW VK+ [I\=J龪i4] i*\T' XGzucc;e^8ڗIs__v`ef%}_pIٚ) B4}Z>^lo}m+V> r'5ƥE r6I/d6%b:@/~'!}UVݛʐ |*Γv2@a߅-Kյx`#\Q~G $!%u-V]Z2Sm,Snu `} @Np)~v@>Ӭ+u&uԪ8S\*ZحOuh3j{kڦ.SԮ7kG֨iZ5[i]jGQAnKj4-tT# Xav :-}}Y͙< XL9QM%6^W.uj5zρ1}qs{R-xMS: 1u-VjyS&Ii w;dMm}ټnͽii5!e()ZXGՏѸ+?a׈ʘݻlIIC h>f`a,z]mo-KS.-/wk>6(S:5ߐ.`uߵhujZni ZB`FШgawO]:j~q5Y}uboh 51!zR wUҫiz133cڹ?r6fOnM>2(viE4:sxǢ'>s򖳴kEMiNZ\ W **OV~wi,S&颀TY%#kft3V԰jFe5-%MO{]B۸CvXvT״/ԋ҇݉T-/vjʞsa9w<)T]j{(7!ԩa,^Rvji%DYY‡z\jSc66z坕s᥹׷ō>2*fO>ԷC;*fdf|3$\T' XP16~|ٓOOLAF4%I.i ~s>=*iY6[~qfölP'Pג+_Z6:I1~$ioٚ) Q"Xi>uUFҨ9simZ+囚]GZP{YM#&Pw6$}I T@ uk4KCbo5e\]s_?iʐﲍޭI<4^yYG+X2lz}(m*A!ws_&y8;r4^M1^?FMLKaZ7y>tsIkһ'%yʽւ d^=nq ,j$I'$df[PШj\' RM/W_T~Y}|u3tQ6jW[`u>tno4-Zx5kմ~ϑw%X>vLY}q]Ltu^`@ ikֱfZE3R-[<ŽN}kQ?MV۸f6}b|5\~󉻨xۼ詟?\]cqauTH>2 @u%h>zsə6'"͹Uv5oJ66Ϳ'~oSkGlmq;=֞x)43vE_tajʵnW|%i䎍Ew@JΖ4VlSP(`@ ׮-i=9OK?v&Սo.8+16iKF!ԍ׏ŜvaBc"Gڥד/z:^Mi EO[h{bpQ2}4fpN薥jy)jfq/04hFźGڵ֡Wa&Wؿb;ov i B] BW wjbN7*Q~)iwwO!e4KYaZ}p~@~I|jUtO!׆5Ov->*$NiԮA#whTMcqän(V7f^\@-CO-Rvsi2kCsu{kj>E;rnRYiH1"]f_"%x ']3ͯ'ך!VGM7M=IS3&iFRc $]Z@yѭKK`>8:MՋ9[KOnZ܈ +,ow$} ׍Ѱ>.Z;p?-^H܅G3}@p.IJ}^FoݠƟSt(e;6i+WEݚ{ci+;TMߕ5VYߗ\qvi6wu?\؂ȝ{[36'?\H%3>%\T' XHlfo(Es ϿM'8W+B.-|8ԬR˪f*w5f!ܟlw`ܫ]TVo!vg19%kT;4-ʔӂHj wde?\]@HFɃ .Ȃ q*.u]Ew]]* +(D"i0αr8?zaf[uyn>yKB)cyh޽eqFt'2 m[鸒rts LC| ,-`j[9 '}W@@/7ӆ ;:N{i˱lS-vߍl,4hr {'ϹMi|аD_Ed|v-DOMDTz,#x,Գf;ݙ?*0 ȭ7"fKlh>,H>\' 2 Uww+XD%" DDZ.| ZCdv˴yu~|IMG?xO7i=f%%v7X5 [LÜme^* rGKFtsL^aG7DDU4uǐ.[1"T5`ٔZ*!A\QצzbR1'̂`þm wuf]h)w9VΕ29~gZ[sLVv_Qn]Tk!rI\4^ߤP0%4fX {{ fMQN'0אz&f53`|"sw_( nDA~po7"-`u\U?] Q%{tһ'P僭'ƌv3fX̖j @"RVl-.#4ܕUZ>-1]c3͈fz/o:`Zȧj7Q>?̺xnɠ0XBý)d^.`>z^>X(}f6[Hf}c*@(, T޶Za鲯?rggw&Q,: *k#;3Mƃ"D-ZFU],""u?9by)r~2nunYE~doML(e_1S=Nu2-+rځ/8" SEIZ*ltaޅ2Bi~{]o0Zf7Y4u?ĊBtaSkȼhA;&dnVE^c8/`U"p-\""X.b;XFD/Ydט1|`Mjta/9Nc@n&@ *h:|0""Zh"4El7}WӅ夛+q`jcGj1YYJ䩯Snhըa 4\?ǖ2;_M#KMD."e۵?1""'Lץ+^8Vog2{ x'{wJx]= A V~'SQaZED4 n[1"T5)iR\DO6NUtNCJUDoday!O1tzQQHܹ]&@9ƃ9X ޣlC͗ )|)+ ⭜Gb>0,// ͗;ʬ`B£ѻʛeR/4s? ulAw0X~ yR鯼~WyAeI !R?qQ(e>vjh<м(1pJvAӮ1"LXg"#XDDU"A9 NX%?`/f!]Ll] WRZ1P-kΧc-GW(MiVnSȫT "nTA5𴅈,K.#,ot_2m0lqxVN:rsrV~^3jzKrpʤ^w٠9Y'"'"۵-_OHDDDhry[UK9 V~?w;pC A;` XSEg͖zҤ@Tkw]MDo0*{PkOD.E2۵?1""P[W͗v$ML]f`9gގBbٝp-K+/0=GvФ^-!K}D7,p̲\,"}yiv P&-o7`Yc=hl^#9(`9bU@d7;h9Q]}|jꊊXD:Xd[sS.UQ5.!:lƒkw>(V=iy`PGݟrltWDT6X–DDbEDdI)q{yAn1lw۲T<8ԃޕēlRY몱^#]R IDATj ο"ڢy}Gj咈ȇ`Y"YX+|T>o=rF[0%6}oųK1j+Aef;:%A|LuƈEURՏök!"G$NDȃ"rZfZU eh:yWc9Sh9&h;9PK*N(&a,o`ⱜgv&4%^K^jtlȶ&ëvJX'\zj`;}mlYޛ@!4-ƃHAd~HKȬ* \ H.!<ə[h9>^5CAP( UFfaDD3AD. ?SoٮegʧGPJ9bpMv{4) }Š]BJTɽ! 6 bP*4(JY/^Ѻ4uWs[3Zbt7DTD \\6k"" ,""˂tݰ̆x\|} VS8VBR1xz:늾 0?o #<;|Nղԝհ+*f*ٖr !ٮKYNȱ"r\f"ۺϫ{ &>߄Vƒ;(`e{0M.qvV4jJBVv4D|/gHC؁EVH01"{U}rYDִ+upphW.C/5}&!8:ό#ߧ1tsfy'?`3]Ch>*"h>:bo?^S3f\x2_iFꩼqk{~LMDNS՛wv1DD5Q$c&!lEJƷ%! :? b0 Ov*b ^YD>"רV,"WX"""ME)TJ+(PLPJ+J)&* $[wM B8򌈈,6?rqoVU{mDDqA|IXb"""c-S  ȶ,S.oUy,J']FTG-DDDDDDDD%d~u#3@iDDb99g)UrIDC""""""_vD_"DHKD.] y;* X>g,"""""""v`mQLW X 9 ""rZȟ؁EDDDDDDH+& EU\ ; s-BD>lX5&[7q !Y*"nSGlDDDDDDDDSջm"""""rdf-_K1U8AU`؁EDDDDDDQ;i"/v`u"r&"] y;*ֻ'ȭ岈C؁EE1^b-DDDDD䀈+"ۮXDDDDDD䘈br_DnT~U߰*ъ \a1b-DS ȶ,US.oUyU"O.p>b&"""""U N{ѻG5+f;+hz:1iu՚GZ78Z](9wBDK koE?1"D-"'v-DDDDDDD=NV@;w_Telb2Zȹ[v'"r,""""""rCDv!D? -1lADlX=r:ȣ`U.GÖK"""""""".dmADDDDDD^z{{{{nݺqUQ]pяKvY2m D .>-Q\DvH@䘎]ֶƴDDDDDá8j|ۯjw@Dud)~gr]sOZ:WˆT3<5kܨg>ȟ؁E9HDDDD46c=(uljGTպ"_/t.%`"`m1"۸,""""""rS`8UU7.AU"ȟB r ##.\jooq8#D^ ᰣ`f/wHDDDDDDDUnG}7wqFоպy""""c(?{ svmUvXdU{{{{5o@UvRsWA+H3aLXܢCK$".XdG>oxbyyrW߶׬Y/MGiNDDDDTExm8`xfOV=cK..iNDDDDDDT_8vU !"bEDDDDDDj ཪrIDCDDDDDDDQ:ȿ؁EDDDDDDDDl1"۸Ɖ"rm"'DDDDDD䘈4 Gm:l,"v`Q%:ڹeBOlPry3NHtApA97qQcEVELpojig1陨j[ @+'nE-ǔS՛d"m˾ X?JU7 "bE։^>nUv=D61@g1@ɧN'ýR`a$"h<$#h>2#!Y%"^> "v"ynLaU40sqHh=!s8 vg0"ۢ `Q%3;27MU2-`B8| v """#"'g7!"aED4JoX1$mW:ŤKFlEDDD&"Mn&aKEvU\ ,"4|[?;s gO )֓bXVėW՗ߙ@jy˺g]܈ƃS]k;',\ų-`[.Xj%K.,߯s/i9#˫~j81n;EVj '<K[Oa^k2ڪQlc2ODDDDD-XdޤoUh/l+B~Oy<}D?z] yG^d*u [ij `&l:)V]0?>-خlS \U]o$"!""rYrYϽs ŪO%HO @ &(J(% EncV7g!DDDLU ׶ "bE։zz*\dz0PkFz| #pOp)]_D&a,Ϣq/k+ND!U,{p5@T&6|(a""""0:Bȿ`9'Fm_ێ_k7:>~ MXy&1Wuv+""?bEDdh nt,v+:Vjh&O ?PDDD}zWۮY'"DL۵MGW.v4nEI]M3M:аO~at+,\:YhYp7[-.WT}`:4wu .WEDDDDDY%"1\ 8b9D;99:6,U;1o6h*_ X-FDDDADDt۵?l@DT+zDvy5a_gbΧ043>~%E <+ ( PUJ(e-p{%!4FlIq7UEd_."JFRJ!1A0!$bC.![.]pRJ]S@vMٵE6QP'J(%"Zl: aDLj4@"rr_gDDR6|cѡAlY "*6R1 oI#D/aAaC)1$`i^1@f1PPq@l@+Tcg1&#|0{iNQ+^!4A QdzhFtb2&,WV邨B"-#Cs 1MWM ?Pc^:/aZO{K]f^TJ+Nb&ya;2#5agsa#:yil8Ogse LAB@qt_@1HpUP{- ߑJ:h꧷w.!wtlO6?򱪅WS6ԡ}H=3i^[x|&|ȌWo.b%xb͓o "I;""r_)h޼%9jttģ9~81<>V|ԡ} j,߇՗"o3&[ʳ)me,:/0rWwnc:>DT9UM8&WS|TUY.|4~lZGk{Ў4EÛ Tٻ#t0}yxJiŪ CЙoyS{[TZU}v-DO :Y,"lBh ;;<˟W[urjӼSww8IP X3Gcv>۶| +NǦYg~k67#"">p̷] T#wfua_oq9Xϡ0l9׶^`÷z/\%N0 ^%cA}[v)e"ʧGKy{X~P/uEDDD؇d7Yq 8C#iu_C/;\{,^:v6=ޛ45ok ;yqDdFD_ȻlBD]9 ZN\7ͻ]FȢ}F+ƌ wxP=C!, Ea/`JÀR/7W|[~3P+1{}b @3p{1E|o "R+ tǭQDqF7 _+qkb% `B0TB~P ^ITD$.LA\vJȮ5? 4::nqo,*+V}ΦP[=$qfE2f2{:ߦr MEzR}H,wV^[h9&棣h9&~ԋѻ25?e.K!{4@‚ַGvr GFpY늘{n9'k;%pwpH=[RʞJ yg B 42{1"rto52',MG 8hzyԊ45R.o7"`Vs &h=)֓bȮ)berE^0nN( *]Ĝ4 cQ~jơE'IҘ.bRioyZʼTs,$. aguvBΟADnRF1r{Ici¬ƃ"AN !m`Ci興~*U-ڭ5' 0n9YWR- 44ќ"uJ5QNu'p 0sMն v]yǎ{XuPEuB xAW:{E/q٘FW# Nv,̻Q@YU/V\KJ0< wp0Ɗ« cu8c2$X""_d^TݞAU^>1 ;[Φif}['"M;|T= 4 IDATx - A3m'0zWѱmİ=:R^``W6_{fjͥHpZzx~KTV &h?-=o w_DQpU8 X{솽X=`Ģh+6o&޷wxg!ώ/~޼KI¯`[:jGQ{n;^Hub,6}o.Z53XnO|0ve;X9 =$ "OQ 7S5K""bEDN1*Gvw.^ڄ9T 4̋l~ Uyߪ GPLw`t`M3:aP7=f!V<~RU>2:lR՟a۵?1"Dd|GDN] VJ3!iYv]UQ;bXՖ@\MX6|kFb'}p ve{ú+LqU!%׷ODDD_c7"2v1D,\Ϋ+:V[+nhߎE!Vrz]:^r󥃳>ֈ9-~ά/,ѿ? Tr|+nhEef,JDbopr^u{mU}߹ExmۆEW"egyVeղ?h 2\<_i1^.c:jw"syZȟLhzN+2]r8WCt`Ei5fK=Ǝ3`w/Vgv0_4 6P:zdH>:P:"r,"(8;a wjd0y%\ivlz>l ܐB5ޒ]]_f_GQvy'g啩U b>kG"yo VoDT.LfX|Dȶ)mB4U)lrr>Vo'!_oP93%oFI 0;%4xxX?1j'@DDDD}igj %^ڭhRb ^g[n:n;s}bCh=,Lˮ. 1 ^Z3tI]4 (53rG(-C0swyJDDD6XdRUTϨzm3+JX0Rt`IDuvUs2z{]:^ZGvټ33J"#_X,PݗEq, .Lረ& WU`mӥm`rV1Q0ѻUƾ9 On-ǚxl|ii>qP5K""G"ЬaS$ Ow5Pr[||0᠃t+79TD~&"'ڮɣۉ 8l<i8tsK|v ~KB` 2q%mVgnNS570"Hi\,"pT1\agwrVl7XӬzWYW6[gv 5<)nk!"'-`@ˣk!zUY+aeybo]WIUK<iN $oSv[kެstTY1[h<Qy;ERLq K"D8[_Pfw̶˴f.102 ^JYEɧC`iXdOmA4U X-$]T`3Zp!/oxAD3 Zȧ5"0i6f; Py}~H8ZsUv9,2?4<%2Qv+""?bvĸ!Ba򄻎R+w7|V.q@%̼Oa+>NG6{T~h"::"9"59v-DSE,"A;R KpFOҝtt9k,|DdbJvt@V9J\ӑV)ЇXps`U"h(ث8;x"r%ޖ\0rF2u,7":{YQD"v۵?yoTT3/y,cͺ\wN"iV! }Q'3>Zdx"O"ҀUQg|UMZ.|G98)AC(h†}Bt 2,'Q~?~6=@bk:<8Gfьdxmv䎄DDaE ryb-D ZufbtvYKs\`o B]M_.UK/FD]NBsꂪ\`=c3Z, cJiiG9}\ݖIz~>M{m`3 qA,zADDD?rfUu~TUk5y^;-,ة%G%,"$h9ӎzotǑ :*u vuiѬ$6^N9:(-]` ʼbV_dnJ]d=Ω1p IU\Y_PW,DD>3"" 6tyM; xjE.tV 闼`_0 /-2J`=fύ"y@Uߤ_] ,NDEK"rZ㴸~DqŸ- #wdwtJaV|fj=u{^'s#a y,\Ve7z$`~5hUk:< Y& zrYj8(w:X8{k Զā杤cq$"""`EVH[.Fb9DTg6}wf lŞ'\2ޢ񜩙2 > 1^FeGHD7U"rZȟ`m~Y'=; ^2/cgJ^󣎆;g6_P槦/{z-]B;ܖ1^`Kx9f/X咈ȇ`[N&4xAdV9 w,W.ű6qnxofaB)Uc-6_x.wv w}TN UWڮY'"""rZ:vΒYaV"^jnL!-68 f9A4W[IXsyMy͈ +,MW.2,4ͼZj㬂/"mr,`fGWjlW:JKvTRylM? M̾+ pKf}Nqͥ4V˼X0^LDDDaEVH[.fX|Z^:o{ W<{|v5]ŪfFɼ% Af'&qMSB̿bREI0RQ g UQ|OmKYՔh>"m9v-DO ȶm{ 1J0W)_Fa\]WijK0pca`̫ͶuWa&]+H.3h#B|ōf86 ȼRKqu_ú/U'PuQ#"s_"=vJ̞oCgEGDbi咈ȇS/olP&^L,{_Qu5*~dvhu<]/^_-n䱋sǸE?8:3^4ٙw":UIF1z:7?+;wyE?%/ja7f@e{EL#Z_~rkMyN3eh zf2eOZvZ;?SW墕#,<Ο .Y9M->3 րiKEܵVefu<#_[>,}}A(a;9Vнt$MY;g؋MZqH}Xqg't>92oV9d2N&8uKu-a5m<#z7{5si^2v+N{dhwӞRgǿZB炡4L v<<`z~gns3*v벁#b&2G2I ,;6TV`oEs0-x$mu S~#ӽUb=]%h+->/м5 c^>/J')Әu`+ ZÂo--~ŧgc7XP,Mu@+& E=ev>X4ߏyjD^̺:Nf.̓d+n`,׵{l`=6>Q`ٳXp " 7>MyN3;r.;d!]3YzS;Ko58A&+=ebK[u o^ դ#3[NXr};Koqj0sILݣ53iFg A{qmt.eX댑}d68mb_:Xm-l{ź}A5֦kqO^'/+-߼^#hu&7led{Ӟd;t.n:nVHsBKwvNzRӞMLڲi\fWҵQnV1CZc^*)7qE!~R"b6_MysH5efv<9j!K~1giU;34lp4}Pk!uHQOhk Դ=ZμXY/keW.;fяk26zth9&j/J$I\]f1bдn;\7 ^eZ/|k6Vhfluщn>ƹlT?ⳳl'ޛ]$I ,*"&ە7[X46,4_oο]ʈjluyMLM;z^ );51sIE2mp40ږ_ul?(M@]D|4",I#|Uwf>8~7L 6L۱Xk^<οont<&mjjZ6ldǟe$2Tme"Dlw}}}5ኈV+#br%IC6$i 4j`Î?]kAү(5vk=6K`K&sdgΌj@~Ʋ[Y~['mfLSvhb.Lݽ{O*(v! IDATN*tеh@09MMOΈp "N.^Y&*Xwl`i.hhUunz'+{YLZ)Ag[4:֭JIgG@O[NVd߻^C{YIԠqz4֭C3Svlfsnm~hO_ j] {XqG'_ݴ?MǿYO%4HAԠynMsi͚hݼI[4Ѻe^Uww]ქaneJӂi 4L f6:73y&Z7kF4 %ImYW݉u2wE#՚hԀKv-ih Rӗ1 Wv3MQӴnC.5|ZPZ^$iݐjif., ID$IFUDy0ػr$Ir-5I"b8?"Wt-3Tw;1 lKT>){`ƈ<3 .KRHS$Uc݃7B&)5-Iu#MXZB$I=8V\+$i I#M*3%V$IZA܂h• $I4:l`pq`vfT;dk[X4A-+UeK5!3{A_0eQDT2s1!1cV$yT$=Cݬgp3 ,I2CRr 3#xnѵHJ^jPM4B$IX7;+#b\XtA4u/O>o٠3EFI$X*XDLԼ]`9XL݃zZG Ix[E"bkTE?ے1ҳ*y-x╃z\Ô`l`IDU>)};089"6F ,I&wҕ|b7)4L$M`Sj^l Y\9 ,Xʚ?x+ Ec_XN>ϮkIҽǻY9{ i#S$i I qp63ƂK,{gV Ĝ0yQٷ$Ipq`vf4~4L 6=FAIR[ Wl//IjBfv]$ip6p&[8[&\ ,> _lEG$i3 Nu+IRIfG%IX*\DLFĮE"Iߺߜ]t$I@Zk`W`yDl.H{:7S`$IS~P1R `ˑ$u&vfoJLEDUF3Tg[TMliwTŗhI3ED `<3; .KR%I]3^>هLfK&9Jԟ (5V=pgqHG6T.`9VX$ե{н<ގAôqz-6ҲQ#ib4δc%I4l`P~TpITwzN%H$I)V.3? 2X$I\jEQH_6T2$I$ ^f..+"IK%I$IÒgg] ,."Eě#bk$I$IX7,M2sqI$I ,*"&Qj^L^\`9$I "6wG.E">9KEm$I8-:iyfv0I$I؀RjX:eKEWl,I$ICR}UE$ ,*3 6:b+$I$I Qr|@f(I$I\czI#jBfef]$IEǀeE}V$$I$ KfxbZhE8>"+I$IC=E ~5] x,"6%#I$Ij3TDy0اr$I$ ADlgFE">9KEm$I89[#b,,Iuf$I$i86ԼpgKEVTl*I$ICR}UE$ ,*3OuMV$I$Ij ,.3fd$IjRrͫE"~RMUE!I$ip2)S2poIG6$I$IÒfd=1-i4R"5"^[]$I̞kT.@DĦ$I$IRp -W3} ,G$IDqZDl]t-3T&jc!UH$Ih2$g`I$IcCJ+M ERu*ۊ*D$IҐD?ے4l6T V$I$Ij ,.3 eE#I$iPRbU}%il`&d)I$IOځo[zdK$I4,v`FfiI -qtDlYt-$I&3;ARj* 97$"6̥E$I$Ij3ThԼ S`9$I "F1Z$'g`hMB$I4$ Xx("̮~&I ,I$IplHy)cHS6T.`Uv[QH$Ig[ UZ ؊$I$IRe滁yz$I$ 2JWV$ ,Մ\E!I$ip2s!p |؊$#X$IaӁY)I -ؤZ$I$ Mf,I$43\$I$I!R"R `%U#I$i("bND)"6/IX*Zu*$I$ ID46[{&I#X$I؈R ` `kTl`h]@[v{QH$I} ]~\lE$I$R2 `wf.-I$I\󪭯$ ,Մ|҅%I'3B]V$$I$ KfGgfOH?6ThWD%I$բ\Yt WSHuKEif./ I$IT;BED :K$I'"bvD] ,XH$I$";MDޠIHs$I$i86ԼرZ$)X*ZV^T!$I$})i¢Bef ,G$I$ X*\f;3]$IAYTyWPjBf>E!I$ip2I@}V$$I$ Kf #3z$X*\D4Eġ^ѵH$I\Rt ,ՂW)E#I$Ij ,*"Z7+I$IC"QѵHOME Ϥ$I4DD#G`sྈu$4g`I$Ic#J+ŕ"^RѺ펾$IjRBTl`P |y;pKH$IdKSd$I4(+5ڋ*DRgcI$IG2sp1UߋHR=%I$I|#0;3_E#R"1"^E$IиdK_#bJH$IbKu ,G$IDČxMDlXt-SSh«n3)I$#lffO?Aq$I$i86ԼX`- ,+(I$&Ul, Iu ʛwX$I$IA6ToJS_w%IqgPU{QH_6T2$I4d/Iu$I$iX2 <$3GREDCD4"f]$I)ĒQaKu1b$I$IRmBED pHys._H$IGEļkT.@^u*$I$ ID42IҠ8Ku6g>h-I$^mDy-cHSRѺN̼4"{P{S&OG_>{%9/#V ZIP6 6C-Mԇf~қڏcZ8'BefgD|8?u/yɍ|o0k,paV,IW+ͭ\~̟?w\zi $y.L\qwq䡇?oCPKUg0$iyDZp%dw~Hz+{l7Q ,I-gu3J8#ַEc7 Tl`P ^m}P&z+{/vV*%I ,I=gy&ԧzuQ\r%nbEԈxeD֎$#7_TF`ȧg͚5\k'x8'|r$$ WHRm:3hllN{zc?~W/4DeFD5nw鱕+Wr!X$ $v~\tEƎ;8zϒ!hRE:/f}]n>hn,O43\Kj˩ʗ^c<_]Ւ4l`P |@w׼)W_=rIXT2O>}kO_җF:IP8Kj_f7/&>fW@ 'IRM̻r~8{]r%$IC ,Izzzxȥ^k-oy geϯ>rJRG7sOozts'X$im%IGOO'p]vYSO=O}SGf l,3FJI ,Մx>06pUW؟'O>=śthBkonn/xE?g~ &3XIUFh^555~W󪣣?|(+Ir ,I:;;9ꨣ{uY{k{HQjK6T/pA=p W*(IҀ$oUkzO:9쳫sYsy_ƣIx]J>lN:^c~w3VuIX4sGpu?s9묳*_]kY҈Bef'+ 'ɟ>6IXTx+_^93 JDѤjn1/W^y啜vi&Ig`IRXjv3 x;Tw]u& X*\q9GSӚǿo8cq&_Tۜ%Ieʕr!x㍽/B.]~3Iu)]b><ܘʭS*%pKflo3~T妗ss*r̫J^E̼*7۠"wWf^1_2{UVJ?WU ߝ 17 x-i}ys͔~/Gf^k*s&eE_{\#pmEr#9*s (mG˹!r3c~uʹC+r (s XgmDr3c%k9&1 =#dp\wu/e1QfsG!3s@>袋r뭷Nܧ(XW|*waT>GcU}*>r_ʽܗrGrfU>rߩʽwr'AU>rWU#w]UU}~Y{ErhȽor/#wXۧ@SEE}Z*rϣ:wWUn>rLmOQ{*m3*r[RjT̬mG`vEn#J ܣU -Uffgͤ-6M@-6M%ؼ"Gn0"R~ `\SJo+vȽuNxx=~cϫGn֒^TKr\K Pi-U]ܱU_A7VGUܥ}N}U/;*>rTjXSUs h:չZ?9\N_DTzL4c'?>G9iҤ<#ˈHu?FX[A'+7m7j߆=x@sۮ55ͪy3r>WkQz36=+^n,J}<_I7#QVT͖UoGn-YlY3 J?gkYKܔ&%7RjͬmRզfF^&%7*Qy`]zyUҬY_]Kl_ss5?˹Y:(ςZ-F*^#bʳ6M6^KEY<տ }XK.*_yzzM΍kj^?Fv}X%3z#"GnrU\qEI4l`iLE\V5vJoU *w:7\Ue-4K:cw%6ʝ[;ҁEeg% BXKlJ:mI7ItۖޗMg{?BRrRvc>TDEnuQ_֒ Kv-(] (Lz)rڣ"g} {mׁ̊=Ͻ:!v r:W.K ^\[By[>_6T>mCÈEni9"4jsˁRiD| 8`-E(]zRf>U!".tV:"wcD3/ZV\^Go;"}.5\k4 ܟ"ݔζnxuP.JpUHK!/z:@DAi@u?"tJV7躀)Z{$"Nt:ܿ#JV7亁+[*r "⿁չ_W Q!Cs~D IDATK"DL4z("2"Nz^"*"@uzu0?us[KUSzZ"S֒u)JeW~A{_r'Rj*Ψ\\{Yr3+nQ/JչVN> S1+UO%ܛϲN(ΝRέ[lUcTq-S/J_JXgYU|*Xg\|qI:=&@u T{g(B?&cIQkF[叶<$I$I8 ,GRZry%I$I%X1)_Eˢ*nL$I$I , KDlNajJѬG$I$X؊53C\4Y$I$i l`i@"bk̴mq$I$I4XSDlKa*J.X$i\euE!IDgKDi$Iʳ? oL#IPdf5`kfZ0JO\l:Ǹ$Is| Qzڼ$IE"c+ITl`iaJw]{$I*DD̍/S̋G$ ,nm`I1qp/_x+IҸr=Cf^ <>B%ILD0r$Ipw)"n)-12UI$]Dl |8h$"$XSf>@p0v'W$i4ËYW#ڼ$IT":0yAI4*"800r$I(r֪|@x)veK$x1; ~W$=X˧#+l|`%IFTD\Vt-$il!".z33//j9033{FPI4!E:Ȱ$Isz』V = y_^gwۼ$I#-3e[]]$I}6OJ>˸8$3f揁 e^>(IFMfޕ NiƸ$IS6@D |h.uGgozLf؋?EJ$Ef^ $9`z[2[BJWs$IٞЫ$IuT _>2 `~V{*3"%I(37n-I42l`M`1 ضbk+3W}J$ QfFiG .G$ Sd:z"F Jw\+2{>h g?$I#!"gQZ#k'p33OITt*ݼppWyNDL?)I42seDWH4n9kU 왙 *I$iD~XzX <;Kyjݼz8$IG15ǽ(۹&c IXHDT]ppw $I(J ~w[>#3̞]> tP$I XDD\ΚuϺWgJ$iT 8bbe 3d;(F$ "bKV`^3 *I$iTO 욙yV$IsV+p-Wy%IUnȗy_ 3CiVyI46l`ձ\MimվIzp0b̼e̮_JP_$Iy aFWGdfw1UI$x=pq/ffOA%I`NEW*nU$I4"b`|$IH:wPW$^E$J^n^%p+I :'T = *I$i,\V̼b$I:We>⪒$I]cU +3; *I$0Xu""Oi)NYqUI$X< -3/*I4ҼDլi^%p+IT"5+ؼ$"b=Z`NYyIA%I$Vl#3UP-$iy 8Ӏ_W >3O-"I{S:Z=$IҨ5NED_^1}ՙSLU$I/"fwځdU%IF__w&6$I54iJfkW 8,3 *I$iLD)++U$I^B8D[* 03*$I1;ZCf⪒$Ic8`̹2OU%I4"b `P7_f$IXq""͚Yp+I4A|5+l^I4q8k퀛塤`wJ$ilDk_S}]PI$iqp+Y;3‚J$I3%G`Fyh!u.*I4ּE 'n^}$I"̫oy%IcFؾZ1]b*$IsW̼b$IRqEDxyfS$I؉QxB$ML6jPD| xg]2sqA%I$X0<=3)*IT$/!1qWڼ$IALyçڼ$ibUC"U*Sj^P$I(^ZFAH%5""^ \L*SZ⪒$I;|&UPI$C@{eߊJ$ilEĦ:⪒$IKHD5ͫ60W$i"FJ'֩>$Iz66@D \ z(m⪒$I*Ĺ^_+ K$[ +OT$IR!3үgIԻe⪒$I Q7;T 43SPI$I99 #3Z\U$iQUn^]ULE$Iňhm^I5 "wπ)o$iypP$I㏗,pj}2sYA%I$""vnalv%%Ig`xWټ$IMDL.cM 8$I,X#("^|bh!p@f>VPI$IE0b$I㗗x)c< ?3o-*IbD)-ܾ\T$ 7CyUqUI$#"L+=tI4T^B8L94Ny%I&hUy%I0Dĺe *I$hvؾ03ZT1$>x Ed +/3XPI$ICU 앙$I !FaefW1UI$'"6--vJ$ /!ӻy{6$ID i^$I)6)"b~\QPI$IE{/o3j$IuK!"|bhgfWPI$I_塻3seaEIck"@*</3W\U$Iʼn&6⪒$IK ".gM 8$I:*$I GDl̫>)3VPI$I5%"^]$IO6ED̥Լ_1<$I$I&X}/V %3TPI$I?{/GU=Iz/7қTMPOA"`GE A:Rwj q޷3;W󹟷3s33w=q"2 2Z} NV8888Oޘ37^ݏ%mw8888N/9;Z<~!qqqq5B!"aWoRqqqqgl\ >6T;8888!\Bx9qqqq:Ϡ7`R o?;88881 X"2p0gz^Trqqqqm, btU=C*98888 ,,Z`'UqqqqF ¿Po͍W8888}Ag〽Uۨ88880BE h՛ڪJTrqqqq0h X"0GTi88884cPDd]f`xX5RUoV88 ̌}' }ˠ X?g>zKo8c=s6g>bXh7",p5t88X-,"ocہ[h= l7OIzAUr"3`&Ddf\m \ S:U2{Sg1=Dd~`|PU!qqڎWd3ij1ޮ,"Q{ Z83ڼ^ݛDrP 0XTU_JN?!j1`"IqC?ˁF88NW TEUT%U)KVw@_X88NcTz`c,W889噺1ƵX۱88g 2yuqqEJW2&m؝<M̳:U};cwSiŁת=.`K,|,Xׁ>FjԌsEȆ9}WUĪH6 U}±L0XgytGTYX0g ُ!_\ 8pINjP`SUHvѠ2رL=\wgvlNlU ( FU_1cT 7Ŭb>PGؼms:n3Q+B0;ϰvCSգ+9j}o%Ɵd<P8KtXe`g_g 28h9&XPnH^cTa߈t6"?vǼ3FDbkqc*` 6'3#z VadP5 t=6g5C&">Lq98(Z54xX 3dF_vK7%kvom{\3.=ir{nE}~SXx ߆Gb_5O&P-=Ϛɳ*C-ڴO[|`ϗ3߁O䦣CdK b|$&0g=/kL ءX1S7sdg^{m:mt(fd䆅46Ͻ7[0끅d3aFLW-hܛirMc a^lZ.?mkH_ Ǟ@ ؿ~.-%xl qy͛7o޼aF/q{8yX3 Ɲ,ڤϾ. *3O_^r/JoL0*Bo 3Oj{]0G~6ÛޢX>wO`[JWi1nd$.yjdR& v~QQ~8' 4>3ȯs'쫬kH3r G=JVy!WSԀVLax f4/ci\~d's4zM>ȍj">/5ߊ.ɿOa`Wqqg0u |#=ND.Djj]_3ɩ hD=&ZE»EѪԪ_7EzpRXGmhS `^^}̋(cl!؋ae|UD? 1Z"9 B2#UbyrQO1c_,X8qf Jw!T}U ,Q V5"b0 p3X ̇ 饹6*< !$O lڹDG0 pbVU\$v,qqZ^5<<ΊF/Edd|i \ v"*5 ,azYe {?Wws:Xeƚ"V|ޣ7d9a950ǩ꼪h:Ή> _**햬>zzttN,,oU"2gpsg;Bf&V:jEA_T;@\7'Exo̵\cj(J~`jXX~*LyшN=3;qq %}.b^,a3"w`Hdr3T IDATrVRC%5cdTY{UZ^B^LH^Cyyoz"['5jLzXE>|t "iEՓ*רұT!,Qj"r1YDED lVeרZ7 -g.`C,hynu7|o+Us888&pR!ܨ6* 3!"(F 괫lP+iTt%X*i[eB2 sya9D)[L:'><[{'[zXvja/1}䢪w0{8Vb_y7ut0GV?~mx!p~е{iZyzs]MwOdvSE y<w5~?nF X88:wp, ˍs\ $ddy n2؍Њ<OV񀹒&p'O*jӈ|lS+*&gts.ʋ{BJ=[@?Dy/r1wYyI{3"p<6r ڧ"rpzȧVV^^k:!v6dF>84_DDVS4d9N܀883 Oڻ ,p%82}w?RS X:~$zF񤲃}"=wSz0^aW\UR?l vJ YazFuxADŠf1^"rpp z{fFmq X`[I0(88N)~ hݒt5`7UmԫdM.TVUcKw䜫y.XDz= 7Ϥ--R/4̵4V+I{CU-PU5po쎅F"2 :<&"cyU9XRD6PUm%v ۙ` [ÀT5>xkkϏDdu,4x&O883@%E"rC~ݾ-YH4/N=XZSzst!sU V mH=a='רUr~VX>#Hr6aުae/࿉ڥCzuF""Y%,ptGZ\DVNTS7`98 ª Xc,/Uw'}Nf?;N`%,7UU_HT"23"rL'+Tnr3R!yrXBܭUlN;PuF}fT |AR&=WeH`AN[c+ϗ/"bφϨ7)B˖UuL\GL}2)1 6z֡oȡuZòX̣:ޞkWS_!tg`n`r7ݕwbJ)Iޞ\]80ͪEFd:+tut鯬E3 XNa n[=G,A["rt|}xBU*_oªj_e ,WZ̈FXޤwEKPQU'd+Ddj=6`58Wð<7 (T_"/jߋ$"jZŲ88/GDj,?ߥU= QD"fGFǴAʺ"2~Dnd0+|OduIJthf R\dM̀frZH'r`MZd>OdJ3%;i=3ŪU%\)Uuj&>i-"(*N7Pۢ]wW/qlQFPDŒR)5"U*lX8V-4x-""Œ6dx׈coyРW4sc%=W?Ed_q9-УN|,'Rs\DB΍V-""7`Kk} -gk UGR 5qC{ѪBch78GDzxFK"dPޞkWap;ɺVᴐ^Rwe9Z<̨dE"Rսtt_N-:8E/XkscIߗ>gGUP;|,m"+|_˩Ӱ_;LD>-r=- *0o CέG!JOCGRWaQwWU_!XnC1%" vltq3KX|CU'BXXp6]X,TU_su0 pIȕzf$yl0~F!"kb>c62ݥq,A5f("Wʃ!t#9bgXt2 %#-Л32+"?Tσaw#,hOZh KQ 7\x@D.&X#aMש- ;)FU q3XH>X$LrtڞGbùw>ۆK&}-"ۅרjrnCUqsbγPvwp@}85ϝ\|VcpqA<ۗԣPD֦CodEdvU"YZ5â^ol\CU[)048O qx6lti}SVHwuZ'oފwwjhbb<~ @x ɺ灯ucI]-c:76Y7 +0W]gY*`~736fS9J)%pO˄X`Xx{Ԩϖ%\ŒQ`ъc/KVcό"5@Y~q)y.-mn,Ԥχaǽ_c=NF}~PϏ{0w֩0wVm|=m~`DEµ~>ꍼkW<1m>\krR%lٷvznhU4B883@PBh̻b=`E#֙?_OOC'2TJV{kY{!2fԚ3<>͹?kqtʗ1Ϸ͍!VL^+ڈ:UD<6ǪL` 7m#' SMsg <^+7y|>w Z 6?m:͍[-V]szÂ\0zNAʝϖHކ6̵"eKi侞ydgJo`]C%CM= v_UU%=CU58=#T_S$YoiqZAȳ2#𙪦y>Z!0F& a=j vϑN͍.GDNVr$Mw|BCQo1\y| .qqgǽ>ch1.C[}wzЮ{Q3'AgZwj+!TYs%<n>gJ.lxs{'_BBu1Ԏ!daI]gÒŎz>1`qυ<ceCsh$v?hĒD~X=KwXBٖny͎1ׁ>kbVgBnV1=׾n_Kcua,,k5_'0 y /x"^ !i'~X1oŀEdG-Hrx 1`/գaP`E{63xN͡/[tX܁%};gkaJ_F(`D퀋d`ǻBZ?4v܇MYsbU2џc9JwY)"ǩOyce 5u>5\,-X9)p]}31aվGc cXb1#jW|XB=EdK 4.S<3,r4)88"r'rz897<`W:=`!X%_<3솽/bIΒDZkD́wyZ}⁅y}dSE͝jE$ 0ka{&{yq;`v}2v _9cPQdܡI3܉w(-.ԗ9̱jOGO;+fd6j 7 +&_9}Hקbbc!z+c螵>$64w,o޼yk-zR X{[+[j NE2VU%hj M^ aR]B_i~6h2ԿXO 3Ap$ W9rPoZ9zzs dcƚF>٫~s4-~`D>DEQTb}MgKsdǂcKh~F}x~@}̈́ 9$h>~g12 dP}cmdwDipX~=}F˛7o޼Z<5ic§c^/`?gߤIJo޼y돭 t5`U5`mZRhgsmۛavLm2_K笥,,4)~y~d}&5[5ѣGI>^VoΡxKH XXhTd }ŌYqͮaswCr\۔yV54`[&1..f}m"c>'KЫ'[UOU,XĀytYB?|Cc2 X޼yXK /s07o޼6`,嶒qM38u!c`_Oi"sU`+!"kb>3nWJtC튻QU,~*67}iqSb_B~^?7XUƼq#dUYUQEKc'b6WUWڤ8N/&q? #^*7"2W6Sy ܍OH|>LU@DހjvI)dy+dEd[U7^Z͡4>M\ߓq~ɾE,_SJ3nnbexzVXΉ2~up$=4w5QU-!]%*ΗeMS;X˘;QD\[29^%H#qq)ɠ7`XB+c./"r4V{з3$˹9P5RR&iNT2K~ ]-`7ƈ>zCߏPz=>ZHYJU:BX:F[DzoP>\ "2]V=azzއu*F!^wW#&=ƾtqq$ހKDU~t.i* Ka;v$"k` wkD{VZ.?Pz=^n(~."O2wH6UݳEc&`xqT'Fv^/6}888NItZN""ÁmUctHzFP1 RTBXS[QTp,g(=B8^D@gs(E-{Ty4n_8^EUyHPZ7W88dPB{dP_dBEch/TUQUw֦ݴXaOOs( ߜ3:I|mnM8]RY9g888%;r IDAT!NibN@HhƢP@U'%|DMi_`ֱzb}0۪t];e+o搪-"OS܋O/"?/-P6,~F"*xƚ{+ +YID _Edn`TU8+Y]s"꽒&"7$"V,=KOG}9t"(""` BU KLyŻTbün2+A"pc~m&jtnj/g+Uu p~$7/[}(i7Q՛yHDV)<]OKfϿa=Ev|lUp,tZV!" { %iDd0;4qLs3 X!潔1;<`T0KUc/_ Ȏ؋v*=,es ^|N13,ԼWmO8iRc 6@BOb^Zˇ0\(jFߔ m7Gi`xY!Xp GHa݃a7qYAD*ܮw7S+UlqWV[3yDyLDmF`[gHdFUz 9ɂg*G9$"sI"0|wu^EDE"B)1G 㴉^!"c2VLD8']NXÀU'" %cGU_Od(U`Ka`9$xY3>nVVU~!]3,إzKDfƝ-lmUq> l] DdpH>P_U? H>pMKmg]``Lѧ-Eh2!Lx]y < "_br?}$C],G+0 ܇}j8*cz}<ig I"r3\>7r#{NcΗ3`PlA}aWS?n!,+Ȭ G%Czm ȿ.<ɶR0Vd]=މONlüR`:H3Xxanp~?^. >X`+u*΅pt.x׳m {!YH¼v޼ n>cn(z&6#.qvCaNӦcA2ONt?I{6gL9\N+omXڈ6SYwamϐd?vZxk:gԇ\5mS*vz,yIWYC{?JU yCC>ߏ4crzG05yHd!G0,NdȤد:`/Dbǩ꿋vx[b/+PRb~1URc)M*bjs:/뱗1CrH}UȉcUJ} inrqqqq4B88ӏ9K(ϝ, ̜3h]mT$wMar5$Vc3][b]f!*߂}̍Y˛8+y'pNbZGbyGG`i^r3XJ~ z,L}^Rջz0Xu97;7obՏn^֠XXہKT.Dd6j S>PGYX}VVkdz"h~"43L=^nk4Ecr75gZ+6؜H*سd%Y2 VfUUsey͛7o޼u;R_ ?/vNq=3֒X2ϝ{{/X0HCV櫆xnL=qq7b =>'&}fp@n8pM${fqwKt*ŒQkO3dM=0i6OMh˞98'qwq8>ω_Wevjgke%3`̳iU=[ǃb9tb/=Edt;F'`o,knvOU}+o^2e f,cy5BUౠ{m /LD lpDj+og[/^@e7mmUQ~9U}T{=߷CDv:YUj$`ªy!oVKف `dzӕ{y[Dd`hqyjy[`jh˱sc3f6'99#ȺUt X88 7}EfhN}2\B*l% x8I 0/*(y-̳ 5ojp`n0#Z*MەPs!ŒCbF,N M_6\`4U}FU ˘ %8VġUe ' 7WD1U} z@ zYp4~F-UI_c^`Wܧ,qq UvB%ŰF 473~À5S"WO/Y6Ƀ D4WR/KhU^<͛ cɶ*O(U}3oc0LjvHOk(UI{N̍yfLNo"sK\tlcKqN|@>M U`_]_⡀B?1K=*g_JE?AhՇXfy Q,qqElX̓j꿈 ^Y૪@O%ƨMd% Xɤk({&<‡rQ;U\UKğǝ%dk6oH݅r3,U҄7IuŸRWV E!*ݖrCl(\]DFW`M,D;ɼ\,o}:3"R½Ere v f?DDϒ!{p*,qqE0l(RS k%d0U )ٽEEDVmE;"r"n*}q-'EtV%^!b|3Ox!Ynt'e-qZ}ߥױQ4CzͺCX座 =ԧSI}C"rl拨rjB7:F_+qq "S QDQHcF"OR"2OXDfB}g1K'ŒZgT,=wK`:vEdFUȧW1dD+aJT%eHuٖSEd,[m"ld|X~wE\ Uo U{04G+ X88Qil=rM9A\N!wz=FD~z 8LUo,% X`yDdY`S@,7tϱ}jm$=S>?N#Ro^F﫿>x +V=8_l칰0c"6}{0ϵL=ePӯoqq+<V턽< "`>EF`jCSU Y">H៧bW[ZU_ΛDdfkow{~-" ֣$⛪ߓ[: _O&5R?'4h^CU遭0i"ao0C[޺kt["<88$64-,"Y̓ZUXg(}>&pw9R!"2_Fס%vRTuMUMWϘc:: 'JV1d$MJUIU."R_ͮxyTBf"EU'hU<x/;XDVm{p ܃~8%q88dTUjvd x`5>N֕}Md׽STݴ,Ϧ6m}/%U XU`ױ*>UF{߯ᮌ{"!wCFzʣSF*`_!%Dr6_7>Nr^ٛ8GDJ.L8{G˞y~7q}3"$\X\=>kZ" >-B{(g`J+W襸 mDd`%UHVU_SkjU ,V,"ea'+TD$}TD4K/"Cf+U{bHw;̦e,Z=18{W(!DdxɆP=~."(%` KtPj2/sgȾԊBUoo' X:l{%}V!:KDbUI) 6 TdF8-,Ypp] XSK~%AE`5 p&+mŭ>iT.)y9z>K;>JPƲ;{b2s LJ_{S `o-%M؎>Տ88Z7DHUmZPDVƾyx~("P3H }_|wawW !Xpm{q()PPE Nqw/ 4H A%rλw&{ywݝ{wҲ Y[seluYD6,ƨMnasr"21WDyuE566߳Yr?2"7{cYζk1#OnE,S)sc fzCD&;4/z`dY?͛e/ۛ:+<(~A-Ʊy]\Dd!`[>ʨx*Z ӈՓ 0/Q-?'S<z\B?`S}XDR`cE;]QyoEؼ6o,'"8*+hܼp)𙷽,%Xq mUS^y^TF ꩪz*Gz ?>l/XH Aޮ IDATUu'U=_UoPAjyyG_%c؍-85'DdW9ԕݟHDU_s> 澔Z>82^ ^ .]6 B,"k;` 0o{/Y.Q￴{a/H,/ڂ^wn89:Gz"S퍀K|no XxyD8 ͐Wښl6o#}^&9aQ29)\AmOnY̖%wuin_G`NKċZ|UUE䌬{ pe`At!Dz.RG(&b /PD!F&UnŮ={s{D]ZK1r=+o R ^TD|+c6MnP~#"s'_׸cKEd+z|CUrufbZˬy U-wtyZ1!& QN9~-"c $;ŵ%[x-ujС>y @D`/oŠF8 tw*gE"4\$"k؅>e{/=yonL`6yl-W fb?E$y.n\Ug[oomTuSPc F{u^R ]梢 2WgVֹ9bEw "r}=b*mtLRUHDf\oӁ'\LXr]G]ʿg*pZ."av|rOS}/Ϲ]%XX @ S2ƾNUBk>Zm/l_A>T5|RoK}<-.o wʑ[X}޹|l|϶?Ģ`JUjuf+Is kXy_F{`2܏M='Jՙ`g|/oy XɏΑ3~LAlxn i|X!:Qչ`-rJ<6徼 Ľ[(EosdNcX:)0^:38g.*_L}Pgz܈)6ƞYk6SH4 @T5 pDdN(2LVY򝎈\DUgkgz:O.1(D"H$#qD"rLlǷH$D"H$d:ʅeZ 3F> < LLb}mȢX9|uc?b1 ^8`a} ÖiwN ?f!f>{snw&w~XE,9ջs$"X`Iع~vaV̌|x$0^_`.bvÀ{m< <{`֣w *:ؘ3 7t10\ySU?ɩD"H$DMp9ՁG6 b5U^icY'K 1nZq^f(AjoA̗?-fRNfiGr꿝SoTFǘ%XK:5sq~{nNPw,tֹdYcYSgWh발6ʎ >͓A]cVfuQq2L~XL*l:] u

    uAiJ+@w_7O-%3ժzE*.Š} 6VURq8\dU}'qI$0gN)rH=tgA5o25{eܢ3n/ߝccȣ'6DBUnh?g2wY6%_D, رvSSUP偧pJ$薇 &ʗ:'Ԯ .н&Tu@#CS¨NǞ)HAiJ{>Syk_O;T,c S}p<g } i NAH_U=$5o~=g~wpXEiq_ͥYv;uU5Kj~Ff`a:)Ю 7g@Zi?EUV࢖C]D-дU]k-qs3Psޘed.6|'Y8?8oԢf8*Yh98ς'EdS5bMe6]D:^ 瑑ܽfrV_@߅Dzk.Jy{уzB)VRq80Ma5?$/m! 1T7R in{9˩`HrU&ϸ{r)nU򴏥{7Q8#uUuzMqV-| W}"5NIÿo\\J{ 8+E~kcgͅJW>`[s7pjodƓ=~m˸ "lxH{TQ Y8pU}-K{I[?-+fߓ^(g]cU'd/T(3<{a7F@UkɉE2%"H+7{Op#pi%svϵ@]|IZag |;BITV9s): 4EOlmEdC2V pTuge9]Ű[MBCT^ɦsxHњ16bϹ"' Yr[,y 2 <<~'. I y .ri*`@ {ܻ8oA6h_7 |^ջNO$Ӎ.UaܠkyS2]LFDZA+\ձ/g SU-]+Xu*W=dkD]Ut _˹?T$p B}R>@0(U\L+%ɡ1UPmHG[b-R%H-,0 l,[>aRKpSlq#K:R6.H}$撎My6 [~Y[.K8{pw*V8o1dkl*ǹpۖ82Jy$֜#TD[1Ɯ .z|S j@jIsgeY.i?珪%O?qrސi(ܤs2.9wV #Arpd%Ou+0 #.$E}SQ BetKбp Qϕ k9Rބe:+<ᱡnJz\T\jMTk[Tp蚠1os`nQ"2trSɦvƭ"YL,Ž8e-*NX^\0 p `=Qgq6m*9 B%)ax9/>kYx6N#K_/",+A2J O6fF*"OS{, GΉ4E):FCt<7cE"/6H_w/j4Fc{@D̹ ߧYġW#GgV ϟJPu瀿6 U*G5dܽ{- qbD&Arv)mnŤ4 qq_"]Kf [$ab܋*<*qlp}yyV/#`м-D$2qȞa2-G4IQ?Wp"YD" Sj݁#v?&T~X9O&"^};qspGU2TQ#+7t+"9=^ԽkʣU5PL gkpCPU/6\[$-݅Y E=,=1 #H6r}A>Y@y?wZ}` URTկqQSaucR ?1[GpAp}|b".mj bd@U']QE]E$"9$ E_.8pkuUl }E$lAFX|"M9]@ٌ~`QU|U)X/"gHBD]Qc 97A }5 p|"8\ |(_&"um8L):|?7S< "Υd.<2="t/𠏃Q,b[mjlF|r|ODVVՌ^> M7U͚YUG}|#A+'OCczkni%|Ecq{[CEd pf288cT5W?xT|^>T5_$0>pC {_hϘ"Rmh"('o!`"64.1ōc-fe skL~r&GErQ.ܩ}RWo)qsne\D$iU]ď2p:m7U hrzN{ȕŴpn}p[<ƹb<@U `xQ*w^cgi,8sCyH;2=XDV 4-u?ű3[UU_qϘ9DUZ9EnРL~f "+b+2c^ucpS="!pm+HDླྀ6tŖyZ= ,XW[K=ͧSU5'Ͻ|n%yQU w {Pi/BhP%t)(U.H tAtD:HG R(!!s';;[y;9;3;;1 H.pgpx+x{8PHq IDATA"RD~@̽=r^S"sLѼD6^VO㱲Ba/`;R8'7t𹪦&D ÁcS0/"YGjRP}<)K gjÄ{aAXk+"bM~r_"3>rŎky V1 {j2`O]INK&"ScǯUQ],XU=5܋b1q%x2gu,b*5cZ]쐲{ :NQDd|X7)nܗlʪ:2e17b͓ kSQDjj1K'Tu0fAs$yUUgED6BV >`ρjѢRjET?xOU )k)"c3%vrp,-}yؾt"HjkQՍZ\*uqϖ%u:,e= ^v6Ş-ɘܩXk+Vy ˪zp37]k;L `W칗|Ǽ0i/"=ZX,9H.<%NPDDNchNoѪzfswұIgpUys`ZGe.Yc|S,Ks{ಽ,P1SQB~C<뒘{~^79 N=e(¹ZXS> N;uKcq  νB;cݸx= TVQ'}}?$!`q90Twq Lab"}3eBn}}`TE8t- s0 XDy|A"6Pb:@U-8U韄cMY~BT.ﰈN:YDuo\qa9*IVs~w"":"xHVHv{?g'Q8NẼ {`W* ;;NJ}6Ô?7cxrq.D, ܝ(%coq>,L3,i,ω8݀+X7KGL;3^vqG(*Vb1bFcDyqX q6(gN"Xiϫ8N6 Ѫpb9Wqg ";QikU=y;X<㴅JsyՈXݠnVpdó;8@U=(lY':8 {R* ʼn8N^88 YofƍT/1E8NKZ}A"2#NR q\qq:*43oX_M)8fW(8MvqqB%+ q| +Q""ꊂ 88X kD-`Sr'w)뮰;NvqqP_cc 2g(Vke.q21[(˅%"? 8-8LCD~e?FU_(jN:(jNqثD9LXc\Uop4+84DD>43O'[(8pOrkJU.N,qZŕvqq""W{ρK{cl`Btͧ*%$"/3׀U˂s5 DdI#Tq(Dd3VUkb \ l%"۪y'+Qx[$ TϫvOqqzݪ2πׁTubwi:5 Uݢ8NEDf\ϷP+R-dI@Yk;if6t\Ӣ3DMZ*B qEd}*g.VՃN&Dd#asNcU6f`h,K7Eqމ 6Km8Xc_}l__xX[U՘N:۷: >6z֘!6UZdFw*ƚ>TNnD``0cSU/8p>㮹w=%OoCD5=O?ѻ%tvp']g+s{VBFTu\MD, <%"{ȼs(ICs3yĐ 0*^$qtu U|8Uw DnL2#q4=,?SUu\w靨ꇪzK8mŋzkΐ|#˃n‘)pؼTUq _Ԙ{ΓALȬxs6x8FU8oj7YSdx 8DU3eOkCU јғbUU731B@-FnP's쏝,o71ٜٷU!"2BƁE0vw,yuD}Gԑu'eMUMf l Pg)"S ,]o"=X#E-0NvL9UfwUM1g4PmDd7j(ߢ;)2Ee`f{;_A9No%M Dd_`GvUPi+,b/c0zw[D/6d"1v"rpOZYEdo@Gh0z5 TDSզJZ,{E$Umە,}H1 xY066Ses&%cLY] ~ RDUHXe;'QhR?1%bΪ"r;~ٺu{D܄e/<2[ȎUe@Dcnƚžo`nbߧn%cϿ`"27XWDTS*JD0U D%ʼn8/}UTqBdD/Y@AaYtƉ:!XŁkiǸ0 s("GgPM/l^(={y?N*ax!h,QqAY.:r U}1o)tXLU=IK LuMUsy 0klڥ~rf6iki'$6lȌ%Aֈߨjv?R"N5kؾu17Զ2ԓcMˇ<.N\S/b iB K{}OkTRd8ףcI7ذ 7g\8S(bs=ME:v+"C1yrK }om,670컝F~&U)=F;mZη`=W_6ꘔ+b 3\+Ed3(=;@)`O\{=̃eWNt~#iir}ƾ#sc5OжEN31JUieN:fers>%]ީLcK؋dNѾSbcw }BQ߄< 8$ZwTlX=9盘,AZϛfߐj|1 \.BaS"`dIQ"])aꈸҤCH¦ؘ߅Lb!*į_C} p]UR}'u_")/`]p;SHU9?oM)SUuRUՋT_/S rl{4=p)Ջ%^&O2„:秖`G)#Śv}~QQMSqb~#~ k;&ge<> BD;8}iUCuH5"2嵙Z.jG<`%XS5;1 MD` `VFcjX}UU)\\ܤ1HU_scؙjX(=j鑒Q Us ,y)\>l ߈TzRk0+kġ"7>=}LKjvleX˰kq\s$s 4k4&RoޟqY&M 8'N-$nl/" Oܔ(?\H=ۙ-^D <[A6qdɷdRDk ӷZ3YlQ;;s<w!GDn S6ZlLP5)^`[iAd zVmDV>U}'""]2@#'c ,b7OW7$EBo/"8a^pIjĪŰ9^8iG{<"iIFpg^|%kZ !,'>k37[b۳V4AD,埉9(%_(}lUpBMy;EXUqZJiW˘bS l>(kJ^'8gVi& 5cFG$ZBҮR*CĢY tg3u\gR<Hޜ?/,vTFrNaxU=Il:JU_< BuBv%,ymO4pLYY^F߳ϲWK;z3xDdݣg=XhEnoŀQ1ia6 OlwrZe3xzlZ!,(Q~ X s+S`.DdG-W#8};3Rdsd2X{sե> `n{q=yb/qu.[c/('v/w`Bkn~>,DrwNb_PգQ&j S]emP="%xfg.,"K"2${nũ8٢ +b ~Y ŗFϿsk+9,/% rƲ*7%_(-7 rd-gߣ0q0i 5Xo|9kz>K@=ȶ&-&"jJc,PY"7?BU-T`;$EI+M_u9NCwdBY0(yL˦G򞘜HvqyMM>ɼ2+` uڂᯅdM3q,<M/("skqFYw΍weTs V6o&јk|Ͽv^>dmá:ʕT|gW;X Yqȉ%/7-O}r$tEiW+v_hZK &RF% ̕^jWμ̃YҸ-3]ZcyLuĔvk|s&(Qi dS?lecEdYN[|RyRڒY +乆T+ 2(S %A-EϲBvU""ECU˱n%̛(bWl=W>bI+ziUE6Y;`%WK$N:F`i x+YQEd~`JqG-K(`{}~׏ԔZ-2Kb{V/Y김ߎEVVڣ[c1ac}IҢjHOS{Ed/1kYC~3Gs%?lU3yC4I~LX%|fQp#%OX<mAEiLA:/h_|ɉ>q=r-Gǩ"ޞG섕[UJoDtb<| UQq?T<@.dRы^VviqPODA`CEU;cc .Q%D;e/a_EMTբK.-؁P IDAT.lˑ̔`2!"sۃhv}jޑ#x)mBi6"z5?֜,߯jwvsZr3FS]bq7H>Jӱv_jtv\d&{K, vR5,w[9UI-fa9Zàk=qRQՏV|8=YT'ZDVFmʤK> SDU,Z`Ór~f(7ۉnț5:|sԸ~gپdgW*9eFUy'勸7U7^~_gHkv~r~m/%ƭhED6',|T47u Hk*E_dq=yra2zfޞ`cPO#$}rzU}\U xyGDnf嗀ucd.{(71JޠqTWgdq/Nf{@X8Tu 2PKXz,K&MMyPo3TqwjJe90LDADZQ)OĚq"{[~"FJ*uϩo,/~i};6GoRm ԏ T'$ՓèF)՞Bg8X=}#sNzt:l/%@dO.$` ϵ_K1vND;I7%ʧk.R@ljqVH9к~rEih&k9 TDm7Hrz#XCQ8ˋHdHl~B i/Ϲd{/"d+Y[X'4} Sx&^ 0%ʯGbmS#iѸOiutDN5 "ìHU^c}0c`ac7{7QT3Rd\nr 5R^R̉Z!Ś'cv 쮪՘"*BczbhS8U,("PQJONs-";S;8UGc]Rvߌ]k17}݁&že/o b$waG-^4 / NQTa}vVYVU,DC<8,%b@p4R#ØE1ϑFKKBx&=_U oItXS^9N^*Q>* 9{= Qմ于32)">n7re0v&Nȼ^JW-5[ɕH=6`1lx;;Xĥ8)XQ—'XėĮ(L>+"Kb4JU;v~_j r}V-"‡?˚$x,]0y8q({}<E:Xa9( miaEfq}Riw"IuaŲ88c3`-jC^bL_xAa1z$DK4N8N"K":i'\q(ē\."D,(kE4N\8UGP]WgJVD,"c$}=F2Sq\%C`f',Q~ qfu4^:sIPjtJn~ lv;8NNRݰĶcCE*i4]b(Or@~Uɸأ0xLVDdV+`xyPTJ|Y;8N 6ƨ?c킽#5]R}skǹDq+N[)O`a}V՟t8SADfJpn<o53W'[&yXD6 <\iwJaS$Sc:~3:8=,ĕ/_5;IytMظDײYy `$lh|[U_+Z8q;8@DfnRo \VA"쭪/73W'v.H<)(O;PD걯<҃\iwqɁ܃ 5;g'ahQ<٢Df@YU''8}Wqqr "++$vͬ_6;o's ӳDyߞqt=-88N_BU_xMS8\*)7Et%;EuZ(쁸ɮ;S,a DIlUuۖ2{:ErbbMgTm8cMEqi8))0i%73XDfF'r]v[ 8WU'Td4`tg?{H$"PǚQ#>No@D6Iyq@DSYӀV`[zZq?i?m_8=~-"b5[>:p'J=%H7p0wNvq4|T98VU3O!t XpaZ 8݅g0_887=+Yڔ(?ZN=>ļr!"+"򉈬駸PUwz')qTu^j;;B^Ie1)J,Q> Xok: yy Z,T{:ŕvqqnFU/Vk% YbkMM; X#tA83pqqPb_S%ʓJF1X^,/AQu3#" KSWWT<zDU'M>7[}BUj,|>70 <^<\X`#;pwߣTF"\X̿6}xxxEpTd ܩU{]d'kb Q{_?M[Jo}Vfrg`#JNcS5S'M)2%U2oުA!DdAd'TB%\HCD~\D:)a wM1e$`/LU,XZ+/^س=Ed{U͇,oknaJ"~5c:lq'*楲$G`lEY+ L$f_[! "awGlvpXޭ8qhD,yدUIv%VRphlpU="[PyQU%-dX%4M6TՖȜ a"0EU?J;f^UwA2)߁)s瀵B bk,k/"R"P`9U}=ø0w"p-+,yDUCGXoT]_FU-jBnU=s'&oq6Qkˋ\Hum=UqXTNU58F\iCkÉXxHfkCWoC垮ȁű#XxvSU}ż6ƔcbҞc*wiq#"$p)0;~꼝t ’EǸDyDd`(xHtGGv`ѽ64K V3(`JlյO~y$ = ͸]R* 7Tg,킪!ִlZx,!bPVhI ̍5@Ŋ2"* vUjWCLxV/Ջ_ >m2|kXvۈ#5=](` 5vU@qcy{+" \(O)Q> c|iɅ,-qJ`mZEd `X˪zgz*.Ƭe0E$-4=_RoDds`X-A)oD+iW[F{Bx,3K;:qX|yv ծ4T uDb{xFrgBvԸy {)Q~ [H?hقUrM4ٟ$G8;,H>MelOu`m;ִ\P[&XXzYRդB >qKXs=۰laTgr-t),A i}Sss,gqUb(7f?Jvehy B(qK%9$[E7%ʧc1O(c_+w0p7BUM 8PGe(LVύhHbخa5{. ZdHb; ދ5}%T-k$l%J{s15oq^r@\1cۓjrS^3ϸU*Ϛ!_!w*H<8S$چ҂'a+@ 4F/Vq%[QUJD[ I<"nfN5DU"r7:"zp{N3?+=VAZ*ѼD̊2]#ňYab~LulP, amQ,kMbҊXwǬqr"`ek6ęL%A`,Gb8 -XUyîɵG5Dy*pN'wbnYG(7|+`/j8NtҞZ.JlC$ir).$_]<7S{&Λګ+8FRihEiO~xKHJ8N77"E[Z'`]O(_RTbDrgJ{$3?Cz,J.{Ԫ˽&V,5>-cTǪZ;TYh|KU#w @)FDnr\5l֟5{fWqMhHW<|n:8-R]%9Sqg`u?= nos`V&uYs8d/*ǶܝT 8-4 ""+#j")L;*J,e$%>8s5吤Hfk.h$K޷&ǫ78㴏s%_y')Q~xɾp8DDd5`zgPPuQ`X?ҞG-RHDd%."%#,8 8TJñwܽsS'~w2eꗹ<ړ| -> ъ 8HSړ eUb{=Gp"blHIW!"R Պ;-zgȏ#ȷ W{VUM5&'s:pQv9X6t㰌WZ 508-MX$F%i pWD~K::2>k""7'T,wkuǟIiV]L ^&wc {Wq|MMV~Vd4 7(| b~&QcK_of`y(n%q^H8ՉEvI?.6NlB}E!V6>fc~0bTlXjңPjvҽ,u0:7[$v;?}yFl2l"r| 6_~%sm9K֍^ߢri速Pm > 87Ɗ_2uU/lOcŁZE Ly)l59oű]B xqf3(<{_Lgwh MݨxPUO0fcs|vۣ퀴Ja3yfřZuo~{ckL'xVs+aܬX4cOU'yט5H?1k̇=waz_'`3c(۪{>8AD6Ojaot̏$PԜ~osuYL?t,q,_"8G("rVfU=QqHUڧxЅ0f&̚n˕X1Ef*&owfDȜ007fyo{cWUp>P+)E JI-`ZTIT AJ1 `| DBPh!N| EYj]ƘBQnri.*ҿG8q]8+^i,a̙ I51">x|+󙶈"Aqtig ŋs]p 3:}wYx_GCE#|Ed{O^c.i芈td?&X$ Ҏ˚gfU3m2vwPe}/dΣw}7\pnGN߸?p<:*:X:YO> p$ nfKJ5kXQMct> ,O,\:6e*V37Ӻ5kYc䍋> l}'%?3`⨛$5?qz7]kr~' $\fNHa pfƭQ$侍ng#hoogܵfb}VW?ᢈw%施~ 3~IvihG'r{IY̦HFQeIhxs3wz߲uKyFͬYzfMQM=ח|Tu4NQnMlgwoנs x."FI/ A9nwTS.Noʚ^+G6 &@v^>v=-w6rH;v,/sݭ_47ef[D.A4ELPzo+3$Iq1p+P^ }]fޟq3m˙7~{ǎL0֪c),* 3v@I{!*3o_Ǖ+":;uU@OVX3h3f 3gdժU>P>v0I(i$IR2oV.%"m~<׾7]o~՟%i K$_2%3o+Dx4" y 0Neߠ_Ao&ಶK2jb.IZ"%跖u+">|/ܼ󺂲o6P_ovLA$Ije] sD[ZZxWw^Ϟ=#*x{qfn).ήtIvI$Df (/~4pb7 R3ʷȏ?:̇:.2\- "Id.IJMoQ/""Nίt~$\z۲/Iɠ]$I5k2s*'3s'wU3A{گ<#{/I:$I+2눘 ,Y͘VQ}\i ^>̽$ 9K$iLءʠs!ǡާ(v^YۓZ% %I4X^C{[%o8q"3f[ŕaW%yYUjJèˈEd, 0?0n=0 xxoO۩u`淢Д"1r tM(babu1~2(00 030oO]Ro407HjDdf`.U}׺#!"V@XEYn֦0 ȗ{^UH"7c  r7|BDQke݀mJ p-/\U\A,塪zbo53A-cCD6l HQB~&1r`^~`T a v^̸H*C"Y%b?XvYZDTջjg6Xe.a#G98JUo ""׊f STuMU]snoQ^f[K#tYc""6%Xe$nfTDO%XUW.MG9 v~!"΀2QzeCDVsFv{g܁> n~V`aG|n0  0ΰZ9`03Ȯ3L٧NPV8DD>߁wU8 4p^CՌ.Qԍj磘 ENaU}[Dm_ uj ".n;Y1Q|%Q0r۩ \:f \ " 8blp¾v5URUWa f\vsUi\b+Dd\0xV*p'jR/*V΍0,Eܨ$γpˢa_Q.vC ؽ'׍3]/Sw #OHWaGF:"\a`_weYbNR߆QYBYUVuP1Td 03XPDBuRi\Ot_(h_F?T.⻄kJ̋dC"ƼS)*\ѨVzaF⃩Eh83t9o0zv!J'4H"2[1~H6Egƒp9ۻSm&\Uu\u"2)b:y^RXή#"mm  ԛغ:zW6WyUn'N0Lx\ mS_RշzQ"m/cHgfem״iÿ[ezxxa[[Ɏbʻ`U|u.j}F2eKW؈ 7 7k"2bU}+Jv Y w.& &"/een[X|ƖȺLc^YChc<NDV6rvy3,]26٦1dY+")G\W 41 ui 6f\4i5˔qL(AwD^8fOs-u ǀ+y㯑"ryí\;cd\%@6t.ݸUD\ypf+VU__ |X`o3oYF4| ꟡2}t/!o16}O&8Gw댾V/x boG*D%)c\Qo956pKOǛk2ínl,{j߳;ı=56eq̩/ԡƧ2.@364zusrs G܋SalG {I q+]U8wflQ"[ڟ DDvRWo@ " Cq'qu8 snɼM{mn(uqb./f npmpnVYAf>*"ke]fvIO8WEu-q3YUD6Tлxpc˭L{[nVqL"HׯGu55+?_TSKTLe1n7p pwO=݃~*|U/:TaW\A,LZ؅pY ޿.x09 p\ƏV|B},=x~ X,ņ~ U)eH"r8;U ~ Gb,p'?~a_|qKWD>F qGg4 |8.,[!<}`p{UILDfo܌dE s[IJicz&\a,X+JlY7C?\ǥq.pf \$";j@rqC-\l `p.b}f}[GHwx||=ܹ/ʕN!72+zvDDd 8`/sg"߂q M$$p@Z">SDn0ө; vp-zZv{E>yƪ ŻԆ8˩He'{3 ]"i~w79"8Z*X0U =_9pc[NDPGk*.ួ+ڿ} ŽK~]FNMwrHg[½ .,Cq缢 `;j{R@vm7*` \,KwXwM]WD +)sa\xHF%/? |#"n. Xq6c-d]pW=fDr7_ˍ 1rM W3n991u<:"sÚ9j_@kȎ#zcZ(&CfЍ bߺfpn# = 0CnTIgr6+)og܊zG馇 YJʛ7 :~*tn2l L_p+9lPQA:[ h ,[Qn }=#/J꺱y| ]~/¿BT 1/&팩8Y7 /󺁶U˸,%(#Oq, ;38b4>=fe\Pm?t %dÓӪ`%؇ߧ8㽢| g`e ~jSW}20P4 U`>Gf<$"ȯ}q&@hlIz/n6( El& &$p΀bwUp9EU+8)nO ߄'>%"YIBHk꫌XGF?{2(0up>{ MdRWSp.Y'?pVNJ.L-|XQ9H\ yX0"\U*Su+wqy%Y,Ygx%w)c@]Up]eRȍ"!"%!>sԞf%]؀ |p7pjgFO4πR%ܽ0 YtBD&0Bq&8ϜWdjh $O@D!XO֐4;T^S?@Wy!MǵY3ƯFg{7"2ONc&f0u mo={>={лx R-L&@zz1Iat˾G1!)EgQ.}FDMh2l;O] v|:Kq'+mϩdlP{Uu\I."'H[Q]YSv;f2;W%'V`3nYu;Z<5]gpgkKn-#m)X,JJ=%uDU_%'L䭺~k8#}V}KDd1)#m{w2tZuH)ӅꟉVSPSQGW)1ccⓀ *U'Dy$6 PK%L=y9J$UaU<0v.q > 3 W%T؀w&x8n/FQbb{.9xibbu*P5 .Ҿ n}W i{~ {ϗh$9lVKȪےe<; ̓CEdmG<`qc#7;P% |Yb2XJMll t?\8ӘUQT1UnPJ/S@4Qȧ(t.F%y4R2{N6Rjc#E~tV(XӅ<̡{;Sg{֪C]Kؕ~#$6 mbjօ w1׺.1-|#q/svK[ncb/6d 1H$9(?sv@;.T>Y ֣3?)}۟e)f6ϩ 0\ni_+Z "sEvyju8,Ӡ/f: co?*["rœoGXͼ ت`'vn'ntC:D\"9;OWNOMJ]Dd/WU("]qYQUhۂ]r.ʾ*"_ϐ1B՞Ugo"p-L6Ec.UR l^%:E^f~ 6NDZ]ǼUtf{3.Ubn ~us5^Ed잏q6YFvYFK4.@ݐ@U>U}PDb"236.K_ng*Jll08ky.Cf7nT]f"R2;2~*m=A9qi :c2ZnJw{=rqӸRH+Eȅ -~ŅE"/5lJURO@Õ4ϛ4߫NU,1Ȍ% vCOYG@2~8 g(@DS;]Pէҩ8g/4 "vm3~F.Ui 4wV GDg,To~=5@xp+5='L/Cg&_Y;%^jzq)"ϊ"2QDV̓yF^^6sU]XNGySg/o__(/Tn:"8q>NYػI7P&kTU>\RkH^% 6&^ ԳKDzYaiR IDAT.oL7:V|ȌcJ;LMl+;[Y:ع(NqTY.tK>$vg^`Og:.X^?Acjq]Qk"m¥,>4. ՎmmPp̭EuӘ[5~i[LD&*͹/&{,]5u!"8 hXqE|}#r &ns{H)zx^ޭ.u ,l.kَ}:=t?[Wy67MUU[=1"2Sgu|8O~ph}n)Ҏ7vrd$[\]RnwGvo@ݵDy"4FFR-\^,!'v*!"'ȍMUU}ss]Cc"HҠ89FD6MG T-.Mݧ8.ɸc ~Sm5>߇&9~rfǹE: zh枟ED˸S': ."Ӆ_/Ev/4#KdִU,ҦvecMƻH8fzE䠌q)nڶ +rl ز/%l3Xq3ϝ}]AI߭sqp~& 8v6&s@˖rDׯ'>F~>-p ]#~[wQM"VAEw'f܆sY~z^B0x :S =qAuYW{"6 8'"ᄿH?W im5hm_^S?J3}YRĀWՕ9*[#m.v. $nivS,-'"+T5UMe%k1U}"m2DdFYc Ν h[IDRf]kT5wQ]敘K'*k551_Ae:ogVo BDRWκԠPwWíLB PɏR 'z@ojnpv"yu5n:߫ N+" Dv}NHc*ȴ_x_Dڒc_Pe eU:1+r:W6>5l,j"0[Iy Ȫl"; u_6)~>vfSkǏF,bہ[P})"E`rlxy1H}ܙ1%s ^"=ޏW}3{hYƆIu13]_ApKY;$kSqYfQ,%:GgQRί#zɐ;uqBqD1Y|^BHL:_S?GdflCx;k;5al,NM`D_!l3#F|6".k=pY# omO'}_yd`ZCvRcZfF{e~X=#^@ŀ3d;zU,wv266JqA;;m<gy5dзOv\3ה /*ȚbadBJ/+{ g0pxq_9fȳr0Sy:TJŸܪeie|;ͺ[rcˍ}ϧo$}3&k,uk{9F7> ?}i/K%3dl {V906 "X.NS9ּ/ʐYi[@g Cq'8dl^T_$4=5tDTAr"{F*.;z'telxߏ˩r:1C` 2G|.;=BEc %(KqD^ԸG2u\KЊsO:qu%\켼]27 YD`46 Kֈeދg[qMYEWPVl^@~6'%mX^\9j ac%v 9pߊػ ^6 (& w!'F8 l\Qo2M |+r9Q㘱ڮzo {վj(yIy^ː*8Ck-d  ~hq"6J,U6dRq6#{Hq}2ܐ!g"VJbA옆{ 9tDž?:~'pF8?z}b- q܏qܝKٺ^oZ=s>u:l{ֹ ť%~L^=GVQ)wΌkJDRͿ^GqFI+]:3K^jC>9Cڷ\F /[ )i 7 m|M]W .-n4pF@kTZ};rrLQ"Fk{Pܬʊ"pA ܍[=񛾘qRڷ qŰ2_|d-UV-ѯ7> dwf8~-UgɸX(u[^;afER l_S_Eu:®J:9/p]YqT@]S :|Co2Έwֱ7>1c#-纷Ez%r?{"}0XjNgG~% 5]-qJ_sMU[>XlTן~O}\xd®%ZL-y7nbPlX@!IcƆ'D \32L>d'QܸcDbaܸ( ^ib}q5pBFwyghw:1kWJN-fRߵ]b^MffJ鑱g|7_,w"^&>q/&oŠΥ^+}'kv> 2nOV>}=G@:n Ɔa~8e mj X-GI5Շ}/Mq>5Qٛ6Ck3cMqbEb0=8 #}NS՗Sꕅ < ?(:.kt[z-᫸Ο*,suwfF. ݪj2ej "|5岟W=ίuf"_)bN͢ܮ{( " ]AqqnUw^pF M,"^yqHf= SM董pźՙp!_MD, _A@zʆaaQұ 20?0:*XkC36 0 0 hs2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 FZch "3껽0 %{DUjB~FZc#" /wza1t}K^ׄ> oZcpanTF#Ȭ"a``xU2 0 #E<_dd$GD*y2M(5- ^^nnVWaU o+?]0BwlqžJ5b\ LR&]֥ՀDdOUwj0 "#?\yQUo+ c9ԫÓ:׊15"ra o4Uǯj,]QxU=JC 4pjylN)8#dǪzxo2aFDDG&bAQо3Tू} F1r-pN,xܠCDvfhz^U>l̗^eu~g ̔s( ఄ:Uew I@1QDXdXDFj?[0j#"ƹ#saƌ "2#. \:nFQSߑ8;%ԣwVQ߆ 8ɆQ36Ўȩbu]>ng#ja)O[,"3wKjMvahڀU؍!FiDdEM'5(panmE%]Z7㻬a8x"GHV=Ø36*LcH\ӾeW0 #%?b+t)\=ԶuTu2eGhc`ƆQ _x/k`ᦜ|J0~2B`EDؾ}FID I`(ט6(t\E[i *5 c`S1Yux҅~ pqFL~]VaFD 4g2cd3 QՇGvؿIDd ОBӈFID CVP쇛5.(f8?3lH\ƚpAMo"Gpãqf<.8!6U}Wz "2$^2:>zxYU%?v'{P9^UkUT/PJ wsMoDdF!UL7"LyFg;OgjM26E]Fv 6 FJzC}/˽?X粕w T5ߋYFD~^ꄒzX !.»"r ~ %"IFRCFU8G'J[ 8]7>W~FUqX؇ZHm.}TGDFq"wDJ;lU}A?ħ*6"1YD.N  ;[S5u6>%"]~0bmnYI8ע]SxI#v%z =Y"ۼuY x~ .jq {h_ O#뺎~h?( j7ogvu > hs `.=Sx6p70 HX>e%AD+Vp3|ȩ"Z{DqxC 87Dd'"2JDNŹ;_3)'T⳱{SD6 "eUd\ŵ{f]7"2/ĹTa^2F:͊!" X\-I޹!Y?~9~021c(hl~jNDd:9? zT,HKqf]= /-Mا6\Mqf\yqC.eH5\[~{j\:b,Ƚ"J#rڿ݊Rqf=]CDnU>۸f^(`ܽv!ٕ Uu8=52d7bc:}pW"ҵt>`._ŹƝ9qM"d(plTi #CI0^2".7R sT5iZX5zF>F>Yb Q  7 Ț@xJ]"z}L[g>ʴ9>"r15])ґ5 Z|l&s)g%UW[TP7YýXF;8#͉pWrv9Ń\~\C쫪'&g#c SU:mT@*]~ |wBD!~n=e_J8#}t nPj@zz]rk2UeIk8X87:F^lE:~A@l ,K:t-f7S} ^ 2 `=NM{sg00GY#q,$@4q|iyؤYp3{sǦ~KhoѺϻglu%f7nKʛxjӜt80pFup!ٵb6pټވeK[(̿s5!Яm̍(ґLX )gC~o28I$ IDATdq])@U/ƹe8pRY}8`[MJ,d!|j=τcZ>cS%lk.NjȠ1EvYسN"SL¹N@}`'U}Lui? ~v4~.?Ujw⼸Sg*}">XF>lw2 Br,flEX&6h  ]5 4*[U%}G #ߗ f:I W o=WUϪ"W]:/"9<{5 udOUՐ1 #UPoAvp -w=pK)bN*ꁶ#U*BU1\ ~+Es덍!Fb/dzn9A~_]S#mH9uUM#IyiDd&zqgQseyG?(Pq.p!>YEg>|@WpgQPd 9ŭ4gM WK| "K&8xW\%Cc ˜aW6ȲEdmJD""g⪲: ^MU-^5oh~ S U(}U  ,4n9E.QէH'V7/"UY^HodA%'K 0BّpWk}\R眃3@U%>\صL2U۟&S62"ߐ އKE Yyz/2VFD ZzrbYx%ҶX36"Ă8nC` U]JU JZ ɎMW}}5VB/>.@U[$):ܡQӐD~~sU:qG ؗpgT5]Gڊ~66s(V {Ryn{m+H,{b1Mm36"i{kZ48ѯ+Rj'^TskfmήiQPQ0Tu\¾nW. "sY":SagH[jWd FnP7Jꔉ^RǞdǫľČ 1WTn?uxW*][֏ʬ˽~wHM,|XeJ)(IC6H^!q_un]\8[UﯨSm`V*jb_,N/c.7[lU0c(M(a+oEw޿u4,\'"iT&\+b++hU@] ,Ri{cCDf>%uq, t9[OQ+DzƒUqi3+۷qYB<OVmH}"ȻoRɻRgB YW!\PDR />/1o~ĝa N/@96{T,YpqqEfmIkKl/+>k]{iLWBG9xFⲾu^m] "y. Ue˻oԮ{I=yUh웟$s10c( RcK`KNۊ֪zQ>C}>Hಶ,m(oo]2f 2"r 5EdKU_U3u?j@;t:1mcツ-+>z=d 0nŀ_6UՉ"rBx?J^&ӔU|񱫁Xzc}2oh ߝQXZn2*6WNM;haw{@U_( #1Ig""sF>X;q_-bgTEd8 'Ak`Ɔ|Pn wLm)"+)u.۔CLdN=eXh*&C(J1'`nj@?go1VЀp^;-m#mEťb8U)´q7u9p&%D$T"2#EFS,msY"pcHQR&a B$ _%<6M#q_53L0 6Wk,3z(H)cKUh8#ý"-`@z| ts[J"r6_:ʱ%#ȉAnw{םLTc}uʒ0o;XD*Bh &j^eY#B.n>D`URz'@GDjS T5h~wU #F }́Ll@'M8!"?4?PF^Ϥ>P?!'[ #"k\$t[5@ۏE$ED> D88ٺ_哸N/ǛE8 wT5BDU#Be9FDbu=>gk;s4'P$0١l2{)3t&-V 8C?Ev1~5TCD` X'mT53̄ eKUm&\<l''oP>G;йB-pٯg;jQ!"Q8gtDVwpsmU5V[52Ri r~nX\gLV.T9qF_q&U " a?Aӄ T5*ju@N| ro~'DWbr­H.8cO3B܏[>6g۪xH@a7 eRGi/-ݽN.-U(e -F $o˟GJŊ9|$|<|lsu? !q7r: -F@~7ǁǺ8 ?+Ʋcc?{N[[p2YzoJ=wAxX<7±1NzLj>Ϧ o$"c}+f6Xǿ{P|fX(Pyx߅xM񮢯:PcxEn8U>k.Z܈7vd S}z;󟃷eu[7:t:ŭx#xOÛָ2/;{<5}G 裼>FAo8@M]ņK}u.^!R[-HI>T|ο'a>='ıTw(񊇟a| ݇7{P{f)[lw U.o|͸ߢǙW0Z?H=|CZ!Y'\lxW]&%33i%ź_syw7ۛ',׮W0!X3[W'cqkx>q dඐ> zbfCfv>ޚ CB 3;Ц6S-61} onK35䲘Ywp`}wBr3;oT=0^3SQ 2_L{1ِR7ʑ3>m!||ef{'̿wدw,P_ LyG,CQQہm枧 |u7zWif7Moֺ[8VdـG3gR/'<7o^/?sn u Gr=)qG9#cw63ι9!]ZT~oQZ =˱RC8u7òvysmO<}YCj-x.do,ǚBI\z^śV9XǗAņ;d$ifk% (t{9mJy+!rl[^ixs<>Sȓ[9ͩ8E,?MGhc9zx=P9l;}mlЃ=kf"SsnCO ^1~WDZlh{|wu3[]K5ۊuŤ;xbm;VN6`3{hbCBsڝہ&PDDD 9ޔߚ %)SZ!k޺)C_vЋIņfmιGx2u32bCbfm=_Wι#HIDDDBr} ˽_$eNņ̮Ҝ))8'{f>dfOFL*6 b};Ώ&+s9w ۙ.2;L&F% 47EsR(ވ{L&ِ2 %6 _Q*4TlHr3;Q#""" lof1ᨓ!u2yٽι݁Q#"""cz=u"2h͆QHQP!"""""EbCDDDDDBņ ) """""R*6DDDDD(TlHQ8 lW5f|u35g|y%d\ 8 4oٍ>6ƈ;l8<[F{qʈ[F}]ofɬҒ;>K ?ST@ȸ2,3<#f2+nW`/uzBOhf]7=p`F܊. 784#72nK>&3kk=w-'y8qཷRnȸ{qmfvȸx/ ٛ>0Yqq57Ɖ#n&qNȊ^ ךN}i^  |I}) kf/^̊|͈{̞הzi5/7 2|:7>\lߏg1=7.%7P?N63u9Nˊ&GܙYqhVe9ɊmOeg%9>qˊY/e0GW⾟#Yqo~VWr(+K>.ϸ_gŝ#wYV9Ȋ;3G5YqSV>wKVܱyݙwdw/2@V܁9q{<+nOq^̊&G@mFx'q̊,Gܿgm#M)#n&^QvV\[q 挸x^v"%#)Gb`z`q̌q쌸jq˲rus2*Rl3nyF\,f[d9qc#6+nqYq7qCYqϏ7 ϊϸ'LjɊ{|$ϸ#n84+qGfm8ʊ3GqYq7;!+.׹qv\Ƨ9 t<.k^δEr횺ʞeEuFSv,Me!o--N=G2m7/Gܖxoi rcMOu%WYlꑅLeϸmX=in[4X=i rYǥm+=O;Oے# fissĭ+=ucĵ5xXqxPڦ"i: ׏׈Wxmui yMϊk#gֺQ ƈ&JsjeqUxE:5(Uq3Tq `Jqxlq2fufpl5F\ #α,r7VcC!quoxX=Bm:Eһ.ɯd|5,fe]:ޕuU7J}- lUw5-3/Yq{*^fd\I6Fܭ9^̸;Yʎ> IDATŻjw]Vܼqgm<w/sV>6Ɋ-+nq՜9>f]Ɍ{+dLlfc}5gqgŵ'3I־3n:k*3}YqûZwxV47̸X*߸:̸զq-Yq/'fUn̊{JU7K]/.>*k񮈽wVV\ 2+5c]#fŽ#xqMMǽ?Fܯ}r/s-㬸71>F܅;qo#>++cIJ3x#AqYq_̊[wvƈȊ +]"2FRqtg &+S9j>Iǽ 1qgfLj0#dF63f3xQqW1;gx#38M Uq }Nciun\*o~|ǮfLtx/UU8[oݷ~?̙s Ȕs{mI69Waf&xW`B9s7<<|%KZ?JDDDDdR;G}s9~ t],w}w^(cn}ojG9ac[naM)fͺ(j^DDDDdJOH~s'nÛp/v+ k-s5+qW022gA2<pΝbk"""""SsٳgnŸo*o+@% ~39U=\͓$jbŊ#8^TTTp׳>sx$7U<>N.~򓟬}կ~5;loǢCDDDDd2rMS &ގxwRhHX_ʚUi7GW^yڋu|b߶|)lwcV瑩W_}ۏ0nfjQlA---,x ===AʀRlw nUFoo/GuB`œ%p:SN! wޙ[n2*" X,ƕW^Td2I'3<DDDDD&1{hnuӟH$j7Wskm  ?O8W?mVDDDDD& n_z|s[uιuz+Aw|~vu_׿.#N?;Ϊۧz*?!KB xq;.hk/ˡvPljG;7FqQp.pWsUWCqg:Q8r35gwy\qnk_ .rNԋ ffji>w\nfjjj?ɱ`l>|y^Smنzi`_3 ~$\8}O>Uw^ޅKP!""""SS P%-]C=7|:fϞ&p\f+&._{wtt~\|y=KlfnڅJDDDDJ˩{p\r%|cxxxW3[pXBǚ[cbf8f:2mXc+fD:/0H:~kfs{Hh1ИC-fv.FqThdi9^]Nӡո܍GG%FJ}Ӏ9wK5oKqBMۭϛF멵LE#]2{Iۓ,}oxusp/M7\3_ t8إ~~#˽WݦiVp`v <<'9>Ό/5JcUM؛ K$hfiQ3 0)yf;8}dR!""""R)੨s9wAɈntmfGL1B#m^@)=su:u> CDDDD 4pUE**6DDDDD[v/g^U""""""2$O#"""""d7. 3{x0DDDDDD$'x̺#g5)cf;uB+;Z :H 4u)#Y?u>ODDDDE}%ADL. Sy}f#"""""At{{NDDDDDDBQq)TCÁ:L*6DDDDDʜ= <ubιs78Ώ:<xsݣ"""""R .""""RƜs osKs:Lj'""""Rv>Vq)A\DDDDD&t5?lDDDDD$(ux X Lu/ j'""""RlspPͬtF6N@DDDDDcfDGsn;ܟs:<x7"IDDDDD&^"EDDDDDJu9PEDDDDvf"""""R@%AQ%""""""K|>A\DDDDܔt;vSĵfCDDDD2࿁A\DDDDD :l16ιs:<{PEDDDDA\DDDD9ι;.JZ .""""Rv6.tUF**6DDDDD[cM@mTdSq)t/"""""R .""""Rޞz:`m:i͆H3Nh ."""""cfEGsnKUιFL .=yOq=bfFL1B;F  .""""";p0u* 2nwFL. 3*DDDDD<%PA\DDDDD /A ."""""cfDGsnssgGL hCLܣ .""""""""""e9s9sQI EDDDDn?Tq)@EDDDDdu .""""""""""9ځhYMk6DDDDDʘ-~A|4VQq2gfwwFGsnSsGLs:?ifEL1B#ѥ""""""A:9:H!|u*og^U""""""2Ā'FL 3!DDDDDD$uKu?WEDDDD`Ȗpx̮6ʊLJxKݾbo51#)w >~9:LM#KGy`w|EfaȺHKusy܇'.M]o9*"g-]h:z}gx -L:rs.j*RF"""R"fd|]岆^RA\&N Fk7:*gŋW m~"qX_lDDDDQqzg?h:XzCvVWDDD@bfvaf_2*6>B,B*R3%EDD瀁KQqmgV<6TJO] l@[Q#);':ؐȵY .qSet:GˉEFDDDJlf+Q)望㜻9jNƃymH(QP oQss#G0 œݣ,1x9c *- R6I}v0f_C)&Ta  >R$""")AιA\d jG5gw/.}/ FDDD֮](*6d=i:. ;ŒĠ#B%""2ŌA$iURm}/:>fHYEÒqaӡTYv 6dMNw '\| x/tdk;7/ t#<gBם /[Vmg9%s!DDDD&v2ϚYK"zz-"PSJX%ǘqlu/"""R:5ƌy]}Q20~`SkUieTcfPqH0yr踺 ^8U""""C)w휻9wBɈ4QM_69v }PA%˝l\R \ZйA*}lS."""( u٠=$pWh9-.T"""R޲:u>fCJR͖ |\L׉۰yU]f]ME^"""S.H0a<{M-mG."""Is答P0|b-[_Z=7C No,"""2b灟Fji_>5j}zF-.]@gI&~Jfr0kkNDd,mg 6Xz}?m)EWa $B\r!V>9# zot?TMPYmYE.ĪHQDD" ^MuODȺ4[E 5踎z˪h UޕlQ$]w]񀪂=~1>;L5}t=@X%Zk\~~%-'rb-ycYP%ߺ*۩deafs.**6䵝U_tL ,z}v(t Ym5PSp(K.YIǕ}XˆypflzI-_*xc}R1v[Ly(\f" 3 )<0, n3s4X>#7iGlSB# Ko=y5F@&B1F.Qz^ŠpKY-EDR*gi:,2aCFE%>Mk2og\¢Yh_t?yqrF&n$`'ߔ f3QP7""YA\B^o}iXv#KШFܼ%,p6T"幭6(gb_ o_DPι's'GO&]0աjɯz j%/u;|sbK58Kw+X{W?`]ʷX(|,.x?Wq\Wҝexq;_verD'`EԩF`gXp^WQ'VJcw Æ-RU8](d|ކ:fdOP[ƼS$/A];?_~(թT+*HRͷ~JC *p1 .%v v>*~Yi!j:SeлI^ܿ'xgY`[9t*Os^"T*%c <4#T-+ u<էP  Q4PEޕTNP%F5F19Q$\A:ȲvZx jÅk%9xbJ+UB  P t%3ǸtξD|h97?`wUpazk$fĘqftxμ *i4T5nZA 7$xlΫXXtr7KPga84PŲ5KM~d~Ɗ ֢׹H9ٻιӁ?5 ^v4:`t^rivlrV<*]>^zša*6d:;43#xӿN_V~ A{Ċ T[ob6E4ٟL3GԹd9w9#LtW=7TBt\nM8>6wthal`P[3{VmY^WR7h3E$\i6">4\MFIT aXAN%e|'[_ wBxH;<^ѷ$m<mz%|%+)vVPH wonŁJij'"[ 2ya."Ġ#/bZ ]TxCJzk+3[f=(wS|M2辷8#KG|Hu;N "R:RĿ{9wRdҚ )KmgB)ңFuJR}׎JGiSƲC5>\3 gZh (S3ͰAY+Pj=@3x8M.j*BBTg.naG7#(V.+3S7MPe.^)k Q|ţC 0=Ee|>;IL .m~>9\rT`'sĪKy5X!˼<%|RÝxp]A G|Is%1F|LD{W=ZQOJ TZNeg0:ht^On-Ue}{%$c8fNN>:n!hSC?nM-j 8~$!AU,q87MSDTٕQ-ku}9W=7BzZ-r^1*rfE(6Tha;t\l]o[f+vp@b}W[sFH;;TO raw8O)T-8> vk^=i=P|1vz  b6^"R UQ=7  wGNX%`T`#%0*`}o%s-7M(f5sSw)qιp;.\2eO92ypFg7?o\Q# ,Uxb囦bCDJXIw_q'DD rvCf LJ1$f/LbMZ랂ɹTvԞ("F *6A\& ŗ<Ȳp=_ ,-̂%4s"%H;(ȔF;LUΊSR1""X~.DD m1ވAXG;BTΎt/6⍓xD z}38=yzSՕ:ՏbCDJZx .21k!rL(6FAQS) wn@,+l5k;F}~x~훱qW_˅7MD:8A)uiLjaR|fkꭑxmb`dKJ]}b>Î4X/V!,AFVDJ]afǛQ)kv}9whɈZݎW4a*7eDkkËí HN.A)4 oPܮ2踲H(n [lmwzNk ۜjF zĆswJRvT(**ߴ& EDdm .^iĪMneNH:mk|C*62U >M`ē 45Vssɤ2%fĘqL>{f|b-:2%fĈ7ocjR߇Yo:[ӑ}73Ѭ"Rڜs;~",T0ܹWYzkJ6W<Ou99t* Wlj{\giڅJDzBE&VӡT6MdžΫ׽ kHPfnw K6hط WtmC$W=]o=*O4T|Mkp;/BeAG&k%5mNA bo6z\D݆~|/x1G~gff2iUxUR߇`hQ>.ghax.a&|Rx|>#jiVO+JDū@zqi͆Ls挷_6FK@r2Am<8лjFE]wy=4G:иq|_CDʅ 8ŧbC0 ;[ke,9@`S͌j`+{a՛&]lݰ_p#~dw2t=u.bιι;:bk` =7:FY~ۚ')WaCzk$c8Z;یLj'QzJce^Y.w2_(hT 97+|D*Vh9)\F鵁vj`SF%3=^_ ~ S *;&_HU*'\D&D3M{ag7.T>9ۃ/%ZT>u~?TŨrWwk ǝsHf`m:F7Œj\A?ᚬ>ZG:Qr༮"e4ym_AE{ FZsi<(YA]}("#AQqhUEGӨF -1ZN >ݭ~_T8iѽBX~AOD̔tΌ+JDd"}5,UөU9ZC8Ou~XMK >MLuAs=~:pWmzs/ B8HAĀxE&q|; |̌ckH bPUs!c;YJAK -fI #] o$o!74M)3,2EsqҨFXTOM+P&ZKüvRDӃzn"`~{u-2"fh+KrvCu4xcfҒ/彟 4fBtmW-s,Ɖ{G*_T-u"":x:Whpqn}N<5Rj: o^Kuw%y+ynb^~_'oH+ڊ σJ4Ǩ۱ 5JDʕifEKs9ιNFd])NNS e50mݜ,3-:%Y^^:g/ 5'[ mVSb-hxsٻѦ$2qjUPG%+(b}4@\c[[xavwnIGJe4Tzgtd5ž'{FY= z>\2R13N6aXlM\Ż?*FjAxmg]rh1NR?ͼn аO{URs%UP5;NvE"#G^d$}/ pJAU+6&ja*\ÆjbfʋLYqfרI˾쪝ei9w1_zGk v, /XXu߿f_xc:G΁>cH4F:F,ኀb/U:b#V߳ﭢ]D\9v~sn3f?,!S^!F 5t\Y[N%^ڽv`Zy΢-Nv.<4_{SQ?P4\bCD3>"e .B:dToR- [bFmie44F[0Xk1N۽x}~#)v$ޠ}ED MEԶQ _k`ۇڨٲ+WEowL}bm 5"B%"e5 = u)=hzzkLL6] z]ߙI΅mPFޕĪÏ4_HSS[NV""`f "%jx šr}mNcg4ϡbfc=ίdX4U{V>#~""~efYI-9s_pu2"Q˷G/^vyk&[\==K$v^P϶ۻ/ܴ,TQMGݶ"V>ĪJ!"2 ${]A3[qN"ql ~!\8|bl`j?/)?*-rJ-$YvS?nA&bpzUQoTQqi\rRM&y;鏄9?ib?܆}^CDXkVlfvߛ '_7+FY+aN24x_ TmzVPC;Th,U˞~s~kf+^ZL)ZGޕ>c$IFmUp WpoWI4p3`!""T婛H:jL""2%MٓWDDDDD[  ."""""0Ks1#EDDDD$jqJ TĵRDDDD̙ٯ_EGs9wsn~ɈEEDDDDbx@Hι;su.A\DDDD9guݜsJX H^6|^e*\b.FL13lfǚF6DDDDDK8@ .""""" >u1#:HQ${:olfK"IDDDDD&^^KEDDDDDp}9wssɤ"""""e9p] ."""""2+9Lv1 VA\DDDDD $ff?f .""""Rv^M(J%ePDDDDD3ׁu8UA\DDDD̙OFGs9ι]NFDDDDD&p70Huo8'bx@5PREDDDDd| .""""""""""R,%A+v_TNh"ff?f"DDDDD$ ^2]EDDDDĿT/'ҹ:93(<ŜsιO8v:<DEDDDDbxHYr眻9oԹdRq2望ܐsn 3]1EEDDDDFJ$:HQĀ ~.A\DDDDD $ff?fSqoRS bf_NQq)3>sU;>6dDDDDDdHR;#IDDDDD&^P a."""""sh9:Lk6ODDDD:ߜy:HtQ%""""""K 0=\EDDDD bfv!lf= """""%EEDDDDRĿ <"""""R0fGGs9wFj,Hwu"""""e9wsι=%:1Vwm"""""Rs -PqbaAA\DDDDD $afs7d HyZ 8*bFϒXbxczNED:;`6W)?f mGl(VQq= ,H2N\1J5#^9uشFgwlI%MT"`"xU\z(^AQ(H%BB*f{٩°$~wv;|Oy3HNČDDDD\^\XnI֮-tD g{0NϽqz["1 g/DeSF!!LX pp,0`k,pD "1Ŏ?!S Bb[Ķ4w} Gi` i"""R:^Ik#2=v\e5QJdVML8=nԟR Ln_DDDxcN>Z z72%:2li?-?'㋀M2qK1:YdVJvVn %Av\5)%Օ'yÅu)֝Ŗo1j?Yrzx2ӴU9A`?/"(>M7Xn`o< T.L_MY6='@xgA{#27X,B#W =M_!H.gLzhk/[Dk}bfSXupBwGDDDc8A| ާq))^^:@i^LmtZPwO)A\,/-tW&L'ËK{~ZZB%WN֮+tD#ݛa=>Pi>}B| Ն@SngHYR[^J{)%<βd`7zIvdXpQ]WDDD$O߅ĥMDJN(0&dv>P0*;!t:Ȏyhi?&`ڼT7Ox4]A/`T`ӗ{ZHٓK,up&YRTv!i< 3әqr ~ZDz M>hӰt\dGP?k\xF=Dd?ԭ͔/ y~d{5c=)̱~hR ugw>U,fڨ'LMD!a1t7zC)[rnax6UΈն1)N3ϫb_vRa:{{}DIW"""o/(A\dץ- /gO2,[eI˺OveIHI^`]b}cƘӍ1 xߺ=/~[V4evhFe7r|EDDDr[cWtvhZap"ڣ1/w6snW/"ϏWu-ʦT OMiD"""s1Ƙ ݗ\Ju }{xFgz_8J IDAT~nj"PU\:cקHdHY *@|qr4|ɶ M)}LԒZlb N!Pn6:D T:l [S$Z2d,%`0@SmT5?N&;p+EƖoz7AjN ?>[$ٞa/ $T XM)ï}gu'D?T Gɲ KSIHؚWRjv(_0o SsDx\*1E# I0d)Ү0la^4HŲBT"PY/"-@?P5g%/? oXM1JZ~O9Gڶ^:/Uzp]qCīIA6}ϩdƹf=Ɍ^Z?ʏ}r ; l@<{#hH V3Z6qcΛb$zxs&,DOA;"[F~鎫}Î N}5[vXsmoq < `ŴL?Eze&"aDmvOM[e%Z<1er٣x*q}lŽ5!CG+³St4<:Ja]dۏiKt-p M`UWҴ\OHulkfٕ4QiEq' 68>ݐ呱44ƬnϹ/aݎ?&c)4D&[&jicl;13U%UhԟbYc[/+~l8Uq$iO-ΖozJ>?`ͩ믂#9ͳz ])~bwv\Ac<ךor6C3vj7{|)#Af" %Ցcw}GlmlMDx %}ɥq;=y[bTTvJ2;~[x:^lmgtxm1aC 95'b =קoMmOv=cEr{m':d4`c`!cIIvdvx@= ǵf J$&fT Pip* 6-RR=_w1{zƘJEz2!HOڷy*6g ?E+pz'FX V{[iSTAMX^z^2!Tj,eSF`6dϔ!WyP5v뾔DSGQw\9_ρ*CO0G2ʖozN OueXNGS&MK_a`):#Ƽ <3ʙvZ9X{,r$d6xzW /d87S90r?^A݊Nߤ&FPcC^X==J<='ƾswk9R"~?';ypoa#򺁧+p3-vYOȩ -%n!<<3XvWmrOWrK3jgyG)nKM|v%9zΟ FHroh$ϱD__ |qKo`ک TVDXty=dm4UIV'8 P׫W如C}^|iF]>U2i@ajYvkK|u{;u* ~5zʗ5oxz:3~uOڱ-{.ʗ&]12ڄ3~W[dk 5J]˦Veޮe)ծ4ew6NX0c݊Ӵu컒lώD ?'GXd3UOE\\Ǽ׺^lϰyaIi {  ˆՆ_3Y:³Il] "c02`¯jp/ԟa0Q<IJ7ru:sK=g77f7}O_f+.8~?0?#}La1{\XkvSnU o (cگZk^VRRz {|[EALxj:uDdU0T3Vb?lVo;s?^i!_vߙߎkc=o԰7kܣ1aC\nț9ͼ ^[‘=֬@dx?&d ti73Փb>%2~b:4Fs[:[fU 9)uo˧So%/y͜zWLxbcWLxZ" ~mt1x:I 1Wdu$n4&{.߹MuD0{.`9Ƙ ݗ\oܷ1. /ygLmH^NTm`-u'°rHuuHu>nhޓ[.v_*Mv[&*"ccY<| _!m*lOl:O9ߨ[6W'G>Rt\j1JgY}Xixg\ߘp"Xߪl&"c%1 aSh'x9ƴ}ߙ<_(<'@'v$uD|3k8E]MT夝>5" '{`rw{j.WDy*6lrv`Ǘ."R@ 3Õ .~uu]Y00 =,݉)bkmhnO*p\>*Iud} ~B4b_[DJޫ9o'oSҠ:1U 0Q}h]mr=[ltʾ oPOg1R?>\M"2*ksOMd}45y^F5E ?lԿݠo2/ N/beQsd* G} }^c5}G~"k[k5A=ƘkZL|)7Dk)" sx( *oYl$[}^_|,`|+ oq7HNlOldv};mۼ<LTE¸B|IPE$_;"Y^a`o,moO6F{"v&)Mԛ|Tu:ggCDdkBwH&[Jo7^f6BL''[ _e-=b#ّq,'oSҠb#>5*~ P+awB.g[B{Uhb#btl % hӸ e M``]n7߳i A}4NemK&ꋃL|a1P]!<+t?Fr11xčBwFd @hp#Cmj]Sb`b?2H7xXPDDe8AN`O*u]bߊ} ;?r0=&bR^^G/j""~q=%;ʃ 揨ݳlS5$3\'1Pc̷1K ݗ\#2hp5lxMIdl+t*{>yّ7$JeD c X J3=Ml'˗ &f7ܚS%/KJi=R}DPQ!<۴%Qi"b`xി1ZS SVd :TibkS/.Zo8vVcX/Cο}ײ̆A/V37BmWF͇\:ty .~be}`;Owz>뎍'=mDʔԞb#ॠNN )M|`>J;۠/ Μ04^;[oP-6B%.-7-@q]phZrn'a&ko:%2렸8m=6ĚCI'oQe%Vlq4[;5"1Iv+Kh_JQdA"{/2ҮXB0T+QzR0S:zXD\vB%c343";SnoXAo9Կ?wذ)\nf#%([rf6Q?xMCE| xSUIY{)EmQ>O+_†xֿWc@*)_TyMX#Uy {D?xzEd*QyA6r?KnOޖMmD_HF>a^QuY*^~,͋%"211cnYR ^zR{lne*&dhd{AweŮ5H| ͞{X ">1 OnF)IxݞNm/##}&K*=|XҸ^H&s@6]ݍTWFnM L.M2Uo6}>a\G7{8A]Z1L;v\R6gꯣq"2e:A//"586}r!FjԭjcxS u/ ׾$oe¸T՟dc:Kdjr;?{Nokg=mȮfoLKgx= 7-ͺszn&fTl Jb0+nt9HEuguvuՇsVc؎Hk=b ׏ra27F~ױ~|L`}fnvEJPNJ(0ޯobwѝ t{$j†y?]JY]TB&-~qMq?,6ϭte~VW?iD ;A=PaJ|Cq/kg ڋ ݗ\ Gc3"c1j*vJM;ҟǭ~Z~}6kT,+M6wi'zK/&Ns}n ړSH=U K MwwzC,{uJb`iˋ'qz5@l8+ 1@3LInO׏~N%&\K<)tz'-6Kω3:HOeBZ"~q)a3,ٖcvo4AXxYe/(]: wvraySMaapd,b>СөT,!c|SgNױ|؋I⛵J&cƘ4,*t_r)A\P6SVӉb_azurּ~S/b<+r³]ky?ʼn/b*rA21gVٞy郝E:GAׯS-:Fc< EÄ Kk`/=ugu+m?qA9WJ,)Օa)$wLru˧LHP6/(/tu5sGv&fDdQ:vtO}>IC C.\Of?$Y ~E$4#\2R<&X&n>VJ7ĢYI^x/1^Hjί"ơ"75gκW!m?Ι [u`=³ԛfT{{֦xmmlROaӱ-ggxbv ?5'g9â+aw`7{=o_ty}ɇ&0˦yvfӰ}<`;Kb m8Ó Zxz`apՇ]}^oeUQOXEW'^ZAsC͑evɹ-> heE&P>W.졟V+X.8 Sw|F7nrGgӽrUɼ^ 59sO|DK'fSnXzK#/kǘڇghd/.v\50Vuޟ[>Pi8Ͷ/{8ԝԟTN9?[ 3qIz@{ 9Y>EoȖG[4;ڟL\Q!%֟5W3D Owp'bHG- KbkKό MF*+Ar^ãYN}e†cʨ;1B[B/ 5)zu`^Tb83Q /`7pbYʃBTl^Ьj %dT{4iD_L["r 5YņMZVh- 68QF[D)[ <#SiTl*{ YR <$gMdl2? *hdJqUlUsZ"|V%eĝhhIh)Z}N?8/: KAW>Cl†`D >K/-Xzkdk1!xy*82nH&dXrs#kN_ysΛ(PTB SDc x>eHćj^'SupqfMf+ަ/4nm$8$3$ITHzO_˞Ӂ̾Or!z*jʗ~WDq3n7+ *`U>:n|~W_c%M,SamTAhf{Ko_89Ò~Ne;Na- c̾Ƙ/1Aw7Q6O"ğ~E&_Qet|'R\YKKnl Z)ףow63<0b9v,Ҵ\Oo Kj(rN[G{2l~YN [Ia}>Q:n[3q[dc>=zkmtcb˃TlH)i'Ύt\#;Mb" TwKhŽ//V _-.-bcXz2J#\s=wSbķdl*dNPsTN {=R ")Ez`/ dn'HWH̠8g<9@] 8T-LQe >s{k5F1( Ns[aƧ+93#b+ђAnhT" T2j.ryt\AKUu'QBcʊvz&nIufHwgijmb]휐I6A ?^bCd72'^L1.MiSf" - R(HdaBT_BIK O[":)RT"T, QOwQ} kW })_K=cB[DdJ ;qml^pHiگ!"2-#[hPݕ b_w""2UI6eIXR==x;syꩈ)&(A\D$}K+v.[F[9\DD[k[ #""RxNXk˺.PDD?qB%ȸS""31!km}5 sED@A!Ԁ '""'~+4 ~ بq}WlQ""RC ."SNİDž5,4""FƘ1f]R"{jPP|8=z>DD@aO- 39CDDvk_ NTH90e4gPwCT&ԤR""2fN8lC퍈H :WgEDD&|ķ?"""""EDDDD$o = ."""""yc}1&lM/ .""""RVh@6A7 CDDDDD!{(A\DDDD(c4| ꈈ7T`<TMRDDDDD۾d J/dgr9dqql8 ."""""y2 ~8pEDDDDNg4/TGFNZ9zskc1AcLmK """""E < 4+ ۣ&CDDDDD<9lp1ɥq6r!P^DnxJ<N/pEDDDDNm_&d\ΈkEDDDD$/x1fv{k8Ay"""""_~+4 -`1Ycf:DDDDD$/+dG """""26Ƙ&cƘB%W34;oqv 0}EDDDD$o| ~EDDDDDJ|xGDDDDDuxkBwFDDDDD\{xdeJJ1fvsk8AVh@6A@1%H8C%cL1$cLeK """""Eng c^6e c_A³g<0 륈ʁ+1ھBvhXljpč1oN^7>IC{"4UI;F>Q=ë\d2aݾL MN# ~p1fOi`1p72Ao߂B Nwoz*""""R"bkR: v[h{pm]žO6A/fRh0,ooo稣b͚5F5!""""HOn';w.w;Ybkm1fvc;. 3fXVʕ+_&cݧ>󈈈I^8vBc}ݯ׾V f['w>~';٥Osaʕ477 db bH,k>A&jGo<Œ3Yp!tI<浳y_O?{b{wy'"=;+""""R6~S?/^ @,=y<@nclq}q駓Je_8[oq=^DDDDX 7m4l28}{{vuh9;[o嬳bxGu]G(=;A2qSF"""""a]NjձrJ/_@2wuT|sIj8W_yڟWXW^>UzwcEDDDDY-WWWswpAJ836&A_^r%k>3/ wFMDDDD^LlM}ee%~;vt}c\ ]|;\tEs{/6YDDDD <=rqGd8ӟK?Ww81/pW~|_vRݾEDDDD&XHnXk9sKNs5O}o~p9bfo=DDDDDUgC0]wwkwy\ve^o6J;@Xi/ 'tk\r%^d[8j8z*w}7rpUW˝w9Ο诈HQ1ef.p.p5pꩧv\=.XkzL7E(w= ̴"""""S1f6upW.Bon=ifM cƍ[oeBCDDDDk#cPh|o0OOwlwqf|qwhѢ5Ok+ocK9묳^ˋ. . _g1*Oyaݺup tww0}tV\ٳG6E)jW3/ӟkq%p}3ϣn`ժU|DQϟʕ+ihhnK&""""R;cg?]vw^:6NOd2tR~Av{my뱈Hްt{.y֜2#'XZqc̉-@';>5\8%O"""""K/=ZH4=ꫯ&[nOѷ;1 .Z 9ww?'vm桏"""""%S8cO5|Z{1{Yk׎ydcϹ 8uagމ^[rȜzzlw p4ٍ1Zr9-i70Ԯc#4rNEwnP;'M'崋7[k[<[ G 4vOXk.2Ԯ!<+#ji9V[kWzlj7+k흣c;i^`(Cȹ{ohw 0/ ڛ?{:7Ue텮@=2&RY mXO*lRRW ϻ~yt1 t%lIDATLuf!fݤ%umݸ~C31kQKx0!iWa #gnujGIƓsPaTG!\QHCyPqTGc: ._a VK0Hs=.o(wRa:wGYrtK ٲIFEE7ڑ É@e kԥ}éuk-A4"mf!Ddm3½8O71G=?_!n\Rmt}ywW[87VfF.+=Yn9O#ݘ]JvMt!*Vtsth钺#N~Ȓ% c݈݃ᄑT_<=LQaFX7WK??&Vt>k czrFL{a;G~XRwv^Ii [9SstCm]NѝTRwBkvH;>=ْh;&08nX;:SD3u/eA>02^>#҉&tNmn?o'],-ۋ0.VJt((oTh/YR+anDstK&FQcݵnĺq%u[uK4({?a. 6Dϙɲ V`Danb[ln>+[LtkԭAx6uӁm99Y%tw%9#rnRg^?wˑA\!B!J2!B!3r6B!mAΆB!-B!B9B!B gC!Bl!B!B 3J-B!@/ 3 2!B! fp!s> !B!0٘Dp4V~ef˵$!B!`igO.0-J!B1/FI}7G!B1X蕳o{Eq-J!B1izxMc5YQ~e_ B!B llٖoYB`Gw7ӄB!>gw{2kB!BK w8&ZwV/B!xpSQH\!B![Zld?LmN!B!bBK($Qfv|+#B!~*v+Z~2!B!DWg̶6$N>-'B!Bt޳.~/?(A0B!B,p_3$W!BO[ w? 8/ZB!bvg#KQEtn!B!Dh'2[8/!D`f*x{O+(п:!u`fc !qWp 0oQ5`eRde.vs;kQafg4[>1.lM%f6Xu}n_ x@/JBVѯmN;*zر[Bmu0p_ޢDjlwwʞnhRx leMԄ~Pbfs6R;`최 !]>%\gf[cmO^N[ƀՀq6Yef٨HwC> U/46Iy[@F-PpgT'J~QwϢ#:XqwXB6L5B!:F;~}8-Zwkw6Upk+l4~Vf6 &at}ziZ+>O!lH}K6B~ }lf#u6ntG}ueB!ࣿQOFUB(h2 p[Giq"38XݟIB!-s62Dr1xB->/t:mB!LGlçlu c&u!B!:Ag6pW=GǛ2S}+ shʼĎG8`Xr13z. 6NqUhar Ts/i @m#`w6y g+ =$G yBnC ^<,oP% `fN̪*%Dm1F"w=sT*p/; 7|i6mf60AV:=>vzk=;ExB 0:z( `Dp0=G2ǖhOn:LsN͑Ik3-;f΄%ľU{ų g6950@{RD90Ww&|wL&}`~M6#j A{amH"=g9.M=G|x+:Ax)ߜ _ f6(/Iyr-Bѕ˨bܽ_"9wOZif6# .v(w::Ll4fq"kS͇եE֌^/Cw^f O3OФzw3[gr_JXMzȜMRsTzI3S~-KGe8eHg43벿B!w6]hfUBglfw%Y3)MC 5GilB+ʒ>0vy~?2(p.YV%gOBDhzRG:&yjfoC;MoYʞ€3}J!bl?Z.c٤܌,a@xF\KǞ$(ad5.K<.!d]l0O/,U'c>!I6TcWJʎQ3F;lv-u!)lw U"Vm8.F6:-nl࿣9:m&нFyV^`f'D~UpQQ/3;9&=IzڍRIB!=6eV]|6, un_%W-G5xQ}V.><̋Ԯ/} -Pu4 piHg'Vnƒ^ޓ6O!aЯ ʀo6hooEm+/{^d2Q3{/!?M=oK kL!FNJzuw&fG%%if-}r *-ƽ.̈́ !6QQ| :"nv3VfV6Ӈref7uJc=/ *u6'YYff1<KWafwMDB!EF{Ig70YV8{J {lSӽ.f3tT7Ym#uza2>d)Ӏx)ئfK聙- |*z,4}_eljCt[v3sI3D[Qe !XlFDUCc49ڐ_,q=]qMi19Ӏ5r k`ۡ4 //kdCXaIyK3̶6iI͓HG0FcnI1E叛ٸ"q3{<6&b#g|;)lf Nj~?bfgeK-z`fSr>Շ"҄r$}.Gu6"^>Í~RƾlfA^__IZ`3;HofDU'd_Feb=Ȣ]DwaD̬G?3nf;hQ\%Cl6ޓj2CB]Qc8#ݯFcV sOQxw9ΦvJB{ KvRؽL(3,̎fpdw8!Ju'p*a9̋lфoeBX?Fp*_˳6s?gvuspt]EBH5} 6a$}g3Xѹ{$˂UʼnLX𰻟Y꾞IKus%FT9< ;* MC=p*<{&p3Or)ގPr(.ҟC 4=9gF ˛^\D,?ન,f6=şep##l8~H Rz̖v bW7]:y1 a+dvvw{p` PqFNpBR蠺Q1DZNC 7mCHj`&>NK3,mw"dunt]$ټfs| Xe-$ZBOJ_H׽Ls/iϯ6J]M\/MkA?+c.Q>fr%mZlvC >ZMٍ_FpܿZGsvJM\|_ݴͫRqC:~=фaiw̾BO #+f}, d \M-pfaDzKъ\zAVpw5I8x!$6A%{TdZ)2z3ۄ0idӄШ'o&l^{FO6 |wlFBGg^I^?[MԬY+y >M5'Ì$3ۛ00nG¨F6Rz^پ ,UݢJw̶0K>z \79+:tLll`{3 ؁0(0]>@~.q-BGhE~AIENDB`PK 8 layout-cachecd`d(8& $@`(~1H2BAZ A^ t9& 20010h" y@b R@Ea'І" ap) itK?::8X h PKPK 8 content.xml]KH L cQgwyc{ưg6H))$ˤJ%=,{/وCϢJK%"2HJOwgH0\Zvf. fW_nՇ?t:viׂށWE9LS11i[\ꊈW^qwL⢝Z_2)>lFdY3Pݧh;էPC )<|87^vlhԐwS]zy2b1r͝9)k5Eޢ@= u;m,ܽC9I֘߸.m͏L\4 Sp)qhݥ'^?lī_?YI`,00ϼUrvSu8@-*I&1O9-qطua9u9NMk~lsi!CYDyr. mo.Z2pکFਢQK] =O2Slw:1\+ix 1\gN}71yNFDs@\[R6C~# ;ìWr{wuwNu^uo!Cwq=k\5Ѵ{禋 ]HݓϞ >ÓtrT8-nR c3X`­z1` f^)$t&@>5Ov݊ '] :GEUTg0*[QZgPJVTU EJ8gEQTɊ`U*=|I^mM[ܷjNf2m}Jn}ZO ~zU"jD3=:Zvw4rZFlR],pA}Q ߟY_%@CȽFY(QVz2zZFYRVU UFY(he-/ [F crEqyC-Rgv.̺>+ŁE߻E*q7V2^K]&g?/8HKFߏGeT\ԨLmT^n Iua<0o?P{={z&ػo?".BۆJo(0)C 7PFPzC TJ1PzC韀IJo(ҟ7RJo(RJLPzC 72PzC 7P'`RJo(獔Jo(?2PzC ?o 7PGC 7 Jo(y#e(?*Jo(O 7PzC)C 7Q)PzC &e(JHJo(J/ 72pz ?o 7pc 7pz 7pz ?3 ?ӛ5pz 7pz 7̐2HNo~Apz 7pz 7p3Cp#9 Y 7pz 7pz )8}:&$f!^oLJ`w%BкS`/G ZK[Â}aΌY@)a.l}vCV[@t]P.GVu=кV{uϞq` G vC&9^<ț,Y0ˬ`54&Fɫ,"9"HyTW!D_FeB#ۉv:h~n{m'1\l2}w^|`e<9"j^?ޛ׃7aDZ`~:Ĝ/jV& MbhɃ pmĵsne(jdv9Dv! mXh;oߨ׃7ֻ~CdA 3CkZ dDlhd[j:f#ىl4dvg!;[6;{&9l#9Hm{wFVd%68|OVí㴓th1a]0ν xc0 =ޯ:?0ӈZs %| -Ɩ,W}%G5*b%,Y!>qRh@ߕ5GǥKYc",k,rD{y, ]ف %˿/g%pR':FtGzTB5 b[ЛvZ_.aϮ8 l oWWΈ4dI=Cl7(bts.vH@nIX sgA`?Sw!!lKK" a{{pꙴ0=pV`.sxmIǿ&o D\*omB^˂Ka${ye &49_0bL{DΎ^`R 24sfpL ,uP(M[zXV=.uxV*1 kɈv*&QMN-.Њ䍒 \yrq_v)&.!I/w%1-%F.WS^(6%PPj 2d\3/bX{+1l{f9)r:.F|vi;Df(=Qa4j?u!(~ !?VXt\/ӭ!>Wg5ٱYmJ3]ٙ3SY<)^UDg9He?(ۆYM]K?B/z@Z ]5d΄P!1>fF@#dq8)D UGC+laJBg<[ä-ɖ2.&h}LSQeROМw3E@1Yhs_`%8MTsIVst&[yte<۠jHE)ie\Mq +ʫbN`/>> /t<-MX+Io*Y=%4B#dB CYBK>Nd r?x;_~lEu:#F,2/`运鬬 :Ѯ8i'GgpSLlPsn[0gWisB#ThF~T#M7g9y1X5bd Y^bpNf k)$(8&4CrZ~| 7!. :+y%׵DUp0i~c{x/fē7 ĻUfLwL4Ӗk䠀) Dd疙ro۶/U% VNGUN®j`H忭Ode=*E塓g=4 [d>G :8Mn]%h U+!u'dbA^[SWE`f 1W٦.ZG)ZzcI$Ul=pu[,!̮T.&-D9^-(Yຒٝ:doRg͎zج,I.xB kZuCH!?衎dT^ԑtZO6Cga^Yp t Bza/#<\؉]>ـIX†ssA]"Xe,xox5dR- zgX:n V )Sou*zUq.(,HEUu# ~r%7*)}{Q.<`r.tZR&9$RIio@eD>S,\d-k9"dr$P? v@r|%FW܃V=[c8ݨ;l?G50zҺ!u,htu(бq\+QӴܼ,`IؽS!|8%skɑIjo{,`M>BD+q˾ϔ{ )-eQj>: jAZ3+X4/dO-"yR(M{{kz80O$8*ߒJ6GPҏ3 rߜF[1'9KM$փsb,G >/wCɻd:>J _?PKwTWTPK 8 styles.xmlZK6W*-ɻil7A^I-TIʏI=(K4pAypt^9l'RQ7A<H)6eb Y" 5RĈ0WkGkUk :YFhsVn**n}iMz-/J|*lxNL>*v%(g(/ ׺\pBfaZBKm'-_YIf$$T-S^-M5xU.&ɱ޻t{R_:e'_ł,ex{J$-'qBp]D}=UH=ʞ`Řр/ `V^zhrN@~ᄠ$L=v.ܷ&xGmf;G & B2duAx}G 6#>-JKG"HuF;mbPF809[:@cIM{ 3X1Wy<R0Ҥx8si =tuW)e\C$.s oJ Yj m)nkTWD&w !Έp 4BE*qeBү3úX^eɐrTY@u\e幻[q$ÎpbD8VʼE 50MtC1@+D L"E)1gY63EZB2arvnp{ىu"cdf"P+ k ,8k CnT.FLPkjcLKƖ:ْ@kgroZ.8ʊ'FGpt2TK8iR WMjEX|" <TƈQٸ,d7ma$9DĿތrsVȔH\Hj`4~Hr+_)ѹ L?aI4x2~Y%\ ydnC(iW ֶBkӼ6Q®[h:\)Mw''&kT愻kpjhChpSOm8ڨGToq%,E}X GK[hakFsqfi,7qIp9Xvkv,Gj;7D/f//F2XO`IiO红`V"] Ѩ;ԁti<~+Qˆr>~TK*InhTV*?cb鉄bO蓛3B+>!mv&1?K 2in$". 8^FqMAdTLﮍcBo_ѠvSIFc~ߧ^*rMKz G>ن$)j)?uDdvt~WE9 HSŢ dm/3񁥭YD{{ȞZ]d`Яբ>(L[tM V n]}"ō⺻Q\7FqQ\ŵQ\qI>Z.4QvhVIZG|2a ؆.6koKK{2Кk~0'@:Qo,!OӾ^,ƬS+`&Fy"O]&'1xvi^yE2ISgmi88)b aEh6O/N(]©TJVcn/أ SJ&; `,Ä;q;D4[..=$I%8U1U^CWќNEo\!~_w} (9e\znZ.xS^ymzymOϪ^#XuvOe5`{es4i Vq;}|:h{E&fXeX{\%rF,bʏoj mrɿ_PKjkPK 8Thumbnails/thumbnail.pngUTMЮ7!wk 5nܝKp׍wg\LwLwUOMu 'OUNVR W<+oG֩/R[mODPJ~yxb՘;JSI:"SSPH:K pEDHhn ‚_qc4]]&oƎϳ[K[[+Z=eb{AvDr4aGDY>4rgN"'}Kݢi!­$~^_5yM; sCrAq-M4-tp/KrJ\E Gf C]ҬWRX&Gr ,`"[*8Ao~jYXYx۲uO RF mƫrRLO(qyrŮMic's$ Yk=G4:zEfiWFvN4~ ` gn!,v/a'4 !ʸq}o]5g]ojPNB?,BN]K8ϱHNaVOh/OKݲueQˡ?=~I݌?>oV>q^гݯ{SYJ+ϖLm;U䐜Iä¶Bn|R4:?9d %c'p4+d,q$d^]tNkg獧&wFN ߢpYb9$7֚ICX:;k:fx\f)ʝwe'ع N|}A9_*Ca𺭟bKBCث?RޣU)Hƽzy+eHl-Ʊ.I<\g rZwqW4Fn5Rjit z%$&~F=8P22DBX w͔3&ɽEN!9Xh8Sc ;q2,.5"1˔(~=y62_D QXL=89|<p9E?[D{ƹVӁ:-SgraXs" C0& MebP`Z/cR#EFzP)`F_ ֋<1WG-`ـT˥ƙyܢ$%AX{(?`r- DOK2Pvv9 )HQi-P_vC_9{hj=W}Y& h| QcB8`u]~BxO70#:b*Lvrne{ X*Ps}x!4@gm{i\`+8[ǂb+-ʎװm)Ɗ;G)i=ZN7湵U1 vȆa{2`UQ!I=q6l5z M>{E>gU^PEVkɥdK B>,u( MB,Vy/mb;ĘԜ>U&}P|ySTBvQ`YGfm(&&m2.wB(ѫgBM|*u6QUK}D 1M hf}(yt/+.%n&NzJ#t?ac!r14e2 )l(X"!#45,y+">x􌡬!5$ؖL2Yݐ J:$t09#Imn [&H'^3U V>d4l_2c򓸙Vho/f)$?4~7ĵL[)U& Q>LxA>45 \CF#$8pq}=m':X0xh%ZWBW\VuILen_Σ;lQ;VUK -2IaR-/LWٜ dɧ1cka"\h,)OmxwpA*s+z_bRV80T*oп{gPh**.)Mx!Y)ћ5=ߧR9>1;U܊]LiH>nSl믹b\嶩ʙ.| A UvQ$EjϴH)1qh=%rrE#eُ\V\^.7`zXR]c0 Uh1tD!U}C x` г*]m*~ |]->uMks-xE/p22hss`ΞL\f>l:Ĩذ_n^خr :yE o o%XrMrTnkΨ>Wsk46I6Q^ѷ,{9g|ojU,+O vzޫa_\ +hlSx*3ױ`}L0*6ĄB]`W{zD(Wt7m,*e~*1&n9zdP_uIK~UE(M>/U ?9p4"TyCyFidX,zrvՙuR8^?dv)?p7X\Rį9IªCOV_goZv(6K2AuhWQbٱ'ZL'MA V 4*L2 $a'ANS/3mӚ[V^|e*{\ 8}YӅ2?2&-[D=r* wեW$'79-i*X[ٟؕ1ȵSzv O66,Rɗm$C= !VeO}GSϧMGŸVqṫ;|4J7LxG[FMA Mq 3ꖔ93|7r5WalIbڀYзo gmrQrYo7RԘAH\4A>N\?ҺYQX vWTqсR1ӎ[¬~z#PSoEC@ v1oQbu]8^O^Oh =& 9+[͖Ζv3GTiMe+=o7\c><^ 2 8[P@=ꔦlR}ʁ`I\ Y.b$Qϩc@ɖDAuĒv"-J|tC 8'5eO͏R*WR2^0VrqVY+,9@p=P(_ZM٣)8%~#ڕ*s[H7u7N^7bvw?♽fuFFͤO!Q\I{,I_?4U(7)OSxh$Y%N !8꣓ 0犍*{Iv*ika%2!p~PM"S 57#dV3{2vMUVaʘZ[|; N.?}rٻQbe;yhNdCfD[ꗲp3ԁ_~N K'Ѩ0+cLX~AqVC TVټ*xDqZnaCfs_=11#uvO 0Z}Yn5xv |7.7  >i)1>l oo1I`)J`jfQ9T(rMp`<56GL,7M]zъ=ٙÅ~ ݑUp$*$6!jp","Y b/P7 { 8/2"!}L|mnS_?8.:qKc*P>#0IIܚԖ$^|{9>5b\:({lFYJz\|q^l"{] R@ AezBx b֩odа]0sEںh?U`El-yU(HKX{B8(z, _Gq5}TW=/N]+5jdw[s1z9&5 |o=k-E)JYrv__\csyKΖX7{UXChFR 3m9!x=BxieB K"}3,#A@XRP򤭴"w!-ݓMTqӪBdh9gNH5heaxcsUrt%u׸8ا6# \ybn[Yq[I7foflDXݧD=o1]b/&9rr6I|GAFhAZR)a4&[VL1-s6N;1<,1Srd)$ҍr/&E5rS4rʏ*AF ]OQLIK?/:sJJ\@+ɚ8ӶJVTiGR\횷°V~Zo5]w>r_uDsm qgQw@x-pyИ!w5J / Mb}Y;T V qrXqH7W[;;76H<^P`F(FzYovNHWv [CNmtmx -נA|tHɴ}fSG.M:/ GiF-̐-t#3kn>7ѷ8M '+Dmc\pg";kS>#3Uwu6.*a9'JMОC@ Ƈ~I>v#̪D?}5WGFGuu{]AÆoU>GL l"pc2_eV@.db΃,( 2qCnfrϔap&Q f>S?s}ҸQǡQp"f{:ir%VQ:ÁP)auj B ?rZp8Iq/59\# 5enKKXEm>}rUZ!?ϙ:GYmNZ'b K?aֲp$2+qؾ涢D0a2O5@ ͐{[ZLG =VcT6ahOy)i7*ޯ,Y.3rI*‘$U9dTͰao/|&=*!ṁz P+wy)gʗvo`LQ#ZD B#J&V= 5tY8Of3c. g9φo0[ .}4Q͜"lKՓ.\ކ"?9f 76% 9q>ɐwQG,TV6/c@~2pNJ460TBcU`d0ž4_ (آ,FĢ| ` )]%k^yzǪ\3_;YQ8N^ /"*YdrQ%Xk9(rQuQS>&k`QBPD%GObC9JtmAaJXkNPbƄU޷s(ط7R7:aF^kBlll63uRm \VLTO/& AiA)DgJYi*hFXQ9A~?`S5SC tg~ *rc2{ xsDC[4@C8$Bax0T+P'eL9+ql} 3rs[0p1% 6IE%cYֶoDl`M|xntO&M%] asB C2gbyZ:\9$UrqXaBCTľ*'I$9Ĺ'+1Iwii}grc0@wbyp1ۇ1= ЦewمWn% ,Q=#{ e3!\DѠS[`!zzvJ?~lګĄPlٍ ~MQu8Z:4ƚyy\杘D^"T ʫ(/0p^:XBBS<{@? L +8I%UJ-b4-=y|umNu.Q?!Ƣ*fʵ NwB n|l)?H[LH5/og`<bP+LJp[/ f@D ro/PA);Z~4" 7r>hf 3;RJ!LQ'iH,Zd!z.Ds2GJ`aoJ2T pF$kvRD@L~2S*oѯx&','#<7Ĝ4Oa8_a6kdKc#|IUkAǢq.9XBCooR|Ԯ紌E/4dJ&ʱlGtvP-M%?ԩxTPA 1p_~31h7,PV%I΄=9}틡SY*$ig;Б{q?s3]OZ͒Rs9fcSHMHya֛Bs9e{{% _ Vv10,M`P.0I-NQݑSbP5#WPNHES gnWZ:sN^ E5[la^3KEK'Je `Gpu c}jv =h3o0'_;jcr?^dwqhze'WBڬ,~4A H_(5?ƈ]dt׆zýg7D1\;˴?cyb2d2}abQ0LmAa\C5.=aIWdܶkͳ!rZ{[ߥ,{rI+S^~/ *iTo`1e@Ϛ"V񣐍t]ĨzfG{i sY'ߚ.0fQ:(ڰEU3;m?hگy;ɤW K Q #0hb뾸Ў($ɋ%DZ!ԇr~̱:9[~!\naQS6 |uwR~}؉J Wf(kKM&҇n3&pI9.jcRw?i?\NoAB˓f.]@bmnD'p?i;f~GTZ37` IY2GJX«|<;aa,Oj/ zpe*.י[kO%2m5PȀˆ˲NTJ+F\Jt'|tU:Y'f{n/uˎZw"?u)\Gs#&=VM`њ垎_mwbv ܕoK[4c؉qsH /jW[ĐDKtTl|Ww,U|HVf,ġ=,1C]l>LCDZ>`b]/s +T CG3O/ڡQ:O5܃l-õΈ|'H3 TYHQy!lpg/jymQ-cL-K< XΞAT؏s CB:6 e!/mp_P^3}Jj?yet FOCS--n.珂*hRS&wcԔ ɨzvIV ֩@7u`o~a=3m72A\j&=:J(?U'wz1vf;ۼ\^TTd"PtMfHx]v .C2Ư`8$ʢr$j{߹[tG!whf: ]5n' \D)4*ob= N#D>m2XChɋ*[Wm/7eqgA1#buYHIC*0eyOhg{cbcN0p-#i"^z$rmiS)[S氚#xrob(/%+3?(A{%+1bE;hTMyݚlONz,{e)G>msVzwjlQ!˅; }ΟW9TUuJ JղsY,\~/{wxǮfW/Qz$᳿zGgËZ$%ύCr*kfjُflYaf9rL`(>5FUX>&\K"G(e7˫ŗWY*9()LXVB,&^nkp)mQdW<>_lR3cǯм)q̔ʤ)w˰؎SWc $eʝ`42Kl)1Mu)$Vo |ղ瓏 A%։:*kRMֆ"p~ Mةes5 R@%ӈ4&k(=8YxϝލS3X:!Juf2[f(x;|1=ĢiW=񿠻:uGDgl30SrGCrRfݍLTCP,a2+ŢB,IG4;_Owtא!^)->wHש.!zBpI};'Oq.~*q3RAaFNpI^;gJ,Mdr.]ye"[Fz6uR~?= ܳ[o\3NWz窅eHm e5Oh.Ԩs' 5xiY؟kR(8?) J~pLCE>iD&r\sZxNQ34su!dpןEd vP]"1vn{tLm2Q|^ >ܔ-6:[fA쌫B}R DU*?QӶhNcm=j(h_i2 Ulwfz] QҝfDMDH gֿ/LU z++X\C=N9Š祆4⫵a P!w;UJ Z`cH/[ :Ksit['OCf,4Qpw ig_>6gD7AD[BM.iMT}Q;d7tq1a>il0hH>Qz*WpMݳ2|AxްP m_la 4mb3ȷ꫒ ]19 Z rFgH,7^__q j#+gjނ+>܆ـҢ!׽{]年;5zt&?quFL+k%%WSjz@GqSsd>~kx|Ca93?Pv.1/Zv0>ϧu$%Dlj:OGmgbF'Be6gNq5N zez%QKWs͞^470P?}3!S;C2+$=c!2Cɰ_.%YHW Z\ev0/$,+YXf"xo1e>(4}{oIJZ]O^QPYaނ:syfg ؋Ga6# NYِ7Ol [QʦG2eYڿHGM*hj͢(ϱѾ6V'Y5XiJQ@݌nCx*dd1,#h/0TĎ4H%lzN@l>9)ejqPK ߋ88PK 8 settings.xmlYW:~,*GSpˊ\ݷk$xl(1 _ˤ X e &{6h% xKc2\Ν)ݦ8ڨ1  c5 B9R!bIG.1ЉlM/3^ZQ=ݟR R5(gVO긓yvkKÝ1eԊ6#`|o "^яЯuA s wQE.WA6zsq-̪b.,1*fS/bͺg6Np&'zbx gSplC?-r2^`5VK7nЧ'PK K PK 8^2 ''mimetypePK 8MConfigurations2/statusbar/PK 8'Configurations2/accelerator/current.xmlPK 8Configurations2/floater/PK 8Configurations2/popupmenu/PK 8JConfigurations2/progressbar/PK 8Configurations2/menubar/PK 8Configurations2/toolbar/PK 8Configurations2/images/Bitmaps/PK 8&&--Pictures/10000201000003790000016B51FA9215.pngPK 87Q%Q%-#Pictures/100002010000045500000332A5C6A400.pngPK 8?J11-Pictures/10000201000004B0000005DC7D79E82A.pngPK 82-Pictures/10000201000004950000037264BEEAFD.pngPK 8a -GPictures/10000201000003ED000003BBB7D11F66.pngPK 8Zե__-jPictures/100002010000031B000002F3018B2D7E.pngPK 8  layout-cachePK 8wTWT ݿ content.xmlPK 8d  j styles.xmlPK 8jk meta.xmlPK 8 ߋ88 Thumbnails/thumbnail.pngPK 8z!  settings.xmlPK 8 K  META-INF/manifest.xmlPKJ kst-2.0.3/devel-docs/Kst2Specs/UpdateConsiderations.pdf000644 001750 001750 00000075754 11544160206 023402 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream x[I3 9J0 ևh L sߏDjy*wg|OۮRQ|\Iy>}N9)^տ8~N4Ev:]\렷xFz5ֿL\wng_Uzn>QQ5!OUB0Rmшnō*nZ NB>XcNIA8gk^36ePb'/<}[mIhnTp;\~GU^@U˼lS~8WB 񸐅?:EEs&.5DON$GEaAf$CORA\WBO%YprMV 4J^a l.F+! >#[V`ĎͰ؁9L 9EuF8@)4὆?wU |bh@k MdRaѢwaKԎ`VJ;@+P0 pŤSjQrޚ/RC߳4ER]ͨ(|ÆtKtL(cB˭kf \ 03^l@0@W1)]'D[GUdmDFc|D ppr q~?sffU3 f(cO#6r_vS۽R@9ݬ.0ѕeGQV~y# w&QLFA 份/Co\Pa;58VJy ϝU$RTvt-C&Shh̻ Zo"ZH3u1)xA`wSAR8?\5TS<i| "Ĝ.3K4lP ]|Z%}CR>K)fZ+crcS5дo~T Lҭt# 0j5Z}*FR.w^Fn,Hk6UfkZ1|T3!ni\d^U(^[ȕ^1Y3w$ Ը.BR:#pXes"HeTJ!jW}hݨz j}lk=WEM]P%c|CMUme.~ѰC1由2Lېq5ć mHj A po^s )`Gfkn +z+0_B^)VGU!k;"%)BDY,LVY`y܈m&o-v9[" XeSj;Y@wHK w swt t%bI*)OT~5 es7lS@#Zp` i&WuFӓ2c<5rG@Ov&N]|tXŧQ&aˍ wjMfPk y?S39Sbxϭ: ֋'_Ϋ9x ʲ +aMlg!6i҂gK2 sS_% ,>a>U6pY+691S;EFU|fHS/a^ὺR}ƭ?=9Cr. qakȲPxva:;NWcqW#?U -< 5 hm}2niG\0}<#p-e_YX'jRtHLl96 ]h'ZE@;!8Yu{gx_IE:sD;JGh"2kJ3TJO_ln\ AA}AR"]E]Vit?lK_#g#A%˛7NxOՎr{q2q>~n!L( I+3 pK;h{jPeK]5*-`|-?g`**ߛ5ZpTבAGUU)+bkyHkD{p:^ub4bjlx$LGICT.X&{1eޤ!g<Ahks|Lq-@+W^SK_l;Ј^>kDUNO0Gny|j3Z<"D63O۬JJ }Z?!GT]Bk52R#q[LZ!;vEɺ ^|wD59~.Ij&wU,vyey U95phԸ#ɨON[DƁNHnDI 3@'t>E㖐/;]P/Rwr[4۴3È5-4Xm{vҷVPu?yG,UᱷuGgcH5ߕ$n`v\H n:Ӵ!@t胧TVwœ)8F۫;}x:"`^W5E~u:4itq,:̚ow3p>g{>BTdF|<8յN 1MAhz Y΋gыaj}A\߹UAeTq mr^[3N v~8JE9{5U!8Ü7gZʟA5N'zGoL|aFcGw9Oivx8'tDμy@!k@'lF8D_;Mf endstream endobj 3 0 obj 3031 endobj 5 0 obj <> stream xSKkQI >6aUۅ1"t!BZh0"d:yf:BP|AzjkqۿsTw> endobj 8 0 obj <> stream x]Ak0s=,Q7eC? & I1k[!Mt=u~`{L0zrKX" 8yRetD%Z7] Nm/_c)Arϳ/fFKix"Buyb%lhBUE($;a%YJzht~ڀ]I=WCܩm endstream endobj 9 0 obj <> endobj 10 0 obj <> stream x{ |TչZ{={fk3Ʉ7 C!&!$DE;L|EDcF h[XiX'R hwf^[}k ! ځ 4vw?u[agcDVh~7u7w;;Nv8o  ?D1:j.sjKgd\\Ͽ7'" !wP+BIUPw!@H0\M}/DI2[6poLl/~FD%)9%5-=cVflo;%ԋ8tA-nta o/б?C'q&s N|xo#LfcmnqZlt,yf݄^BOѶ6:{p-+}|:EK%`IxxiC »#[ ܰR2P?L\EH^r)zw6 v348nEos_2 Cx?n~Qt8R\i` a3$: ۃ*{ r O8<¥G7Si}5,*#r:zr/f4`U:e͒bjI]1U&}n/)CԤ",6 8匞΍I$GR{IG1d"%_8D ܌A3κdĉFFf gFq5gl1>lhC۬f0L%{SxYt~,&ܘ0e1yO6>KX||MٱfYYY6cӰ mI&<7IOH?ƥs{Ͼ}{v?t9:ã}6:y\웿~ۏ7?|Y}ssPoo\ x3?=H6\F!!!d 4fX8Q0ŋyï; 2DeA^9FP bXpM OͺgU\#%MPGT~/YP}^ynМF>StM#Դ n6:CdFT!&l!b-.ߑS;V1x3/ ƙym3&{cYN99+Ƅ-9K~> u. :E(R|.+o $CҒbfA&S&n$#pjXsS\Z2˟dsoLrKceN+.]Sb>%yy&庁u\\WcΉɉ}GzN;gL0Sz 0a>mw}1;Rj5Wێu}mm\ړt[kQuS!?KB큜$s{ȸו@ʞ{w\$[>;0 doV|i " YHUsz?(8 YᬭfCY2ʏ QϨw4lٸ>+uӹTV.& 3}.Bb\=sp{"{NUtq}=NysW|?n]Ylpg_}Zo3 La0,~CvYLmvhGbsX0pbë ݇8Ƿi57d9yl(B햘9 I;Ab1 jjJlgE 1z܊b^{L!Ӑ%e3lty ZCZj-8QYghon'!b4ml}r?c`PsfϘ?=T Oxaw@ 4j(\Tϑ_I~ymeD+_P_ 9aXNS,7:d?F ~3,9>ljs6G~r!4|(d}w, G⹉hha%Mq#= )ܻx3cO?cx^n W~WWPqL~(%KMZl1Lfy٢$^-tD؛,lIJ0#$,3<;*b1s~"'<*41Sh(HP223R6H,7(6$KٕKٕ+yWʁʁR%S%K>}g=zy6ٸ33331gb tcCl<pGOno"57.l1'͑e7g~{~-SܩQ<䌞!d|Tk݋ιR7hP<ٳfl[d"SI$lO w;;w#ISˣ7<$2ADv'?rA{;gwemώ|uߨK?8$mŠk1lL4勹'pTix2q#e#>Q.\qǥ?…8Oo3g-tыҐmd6x 4rǑ _Zt>iAs>VwgN ,vbPĴӼ 4u![q7v鑑lR!nUŖ}?2/Q9žc#o9l2z{&l7&朞Ųl/ٽ^jH8(aK[{ȉ@L"^@'b'$FgΘB=g*p"4q&e.)i lo&1k}tc=;^-Ya5bo66ۛ-1{/cy(f"X 6d3؍.[:M.evY\VMyXOwi4˜n˴ϑYn'ӛ?2:V(uzė-b[ki|Qu,Mf[,; [մUj::]C]~@~~+Ǡg^tP}u߱6!6nloW ??Ff[ :Z 1{ݰ2pu~=ʁ8YDܷ4܃:4RWe(buxQ0zD1]L7mw8N't;SNz؍+rwvR}ʦn޷k?1_N@݁lȐp(i#xH-#M~ʰ.>Cs3P+ w]zpA:x 9Gdxd5.-s_(jXdȱ*n tt笤C?wP!W1eB0d£!QHBz aoKK+mGZ]5s32|8o&c#+3hnO,f͡jՋ۲/TnBrlt-Enb 7F'b+M]|ֳꜻ=ݨgF }~ 8׀>ӽYVsvi;-5@wa_}TCk/b'Ժr?ko/MW~-ZuD#"+jHt5 v KWj`^0o` У1{Îݤ.6Cn!+"[mV3(@j4 :B6' {G .K4li\9ն[dk+7q_3:Akd͢h3P<>græ6gKG8K'|563h)2\-%|y9lcW6xw ȯ3lmo7;6;767{Piᛅ&cYj67Y֐&9Z}\/}P,66ǠdY qGէԧpyoOgOThko9 Gu!"ovYZILݞblx|.Q4{b 91HӱΝA琝.U߼N .[~^'_ y=Փ?XEše$eö)lǦ 洚RaNsh獐;>gA7Ӄl~"{| CV?SN^ 61ٷ>z6W~]uW?44oq+f1Ĺia ۹o T]NuTwO_ҎȵDb|]`12n"7FX ]s9!d۾K}ІلhkT3C7ՌIٌ n6B s&"hE;5Ӝo,/7`͵VZV~b˧4=-B:~ x<hyv}Qap6t8p[ Yq "}^%\v 198BMΘ_hEZ3of:.=G̓m-GeݸE\o[iBMb3hD6q&b>C83Y|V=..牟24se5ÖnOqBn WHGJ7z Zozkj}mk#bŽⷢmm6àuG#w{ݖ{˷+~#=wM=6k7=r5ދݣ~W=w}j.ܽ8]P bUAϦ6pPϳ)\NqHE\!;O|3KgnYML~ vOlȘS2n4~&G?u٧nfevݳwdU#nY,eiudipd&e&7J , ™ ( 秔Ie敖22,,yjmai'v(Iɭ)Ұy2l '+IɃ)Gf'xN?>㓒O ?~,]jls?⏿^?䞻;" ^ ϿT'X}A7Xm&!6 3ZyuEܘ51;bǰbe2Ӟ U?R˪Y \B~[51#Ɇ s = s],s$6ɒdZ(la.'n.ųc)lF'Jǟ.aYc)Րu+i4⃸ AEݧ>D^)@v, q`vr[R%_-+9dȇ4ψWE?Hܐz g}K@ZO\M /-/fY8;WnoC pOqi}џQ}wsDGOO#A8zN5a|m$qw?@B3ۋVJ5zY@|<_矢&Sx>-@ 6_ Q>_jGGo»B$QЀN:beWxm}$mBq AFO hPІ c08+^yw.S;dt*'d9?NH3x"q´tZ2H-onsu2by6mv=h?''=ǝ='R3n{>fyԵ<Q, ֡mOb]h۬Gz@Xo9zیгzjzmF),RtaX&x:-=15m̓z@zz[szۀ7%hm+ݲPoPKbt-&F:1e斈21SWHOӯu5f+EJիTzC=`TjS[껚CJ}OHiR:Z`+::ڴ4n<]m w)y7jS4`t/ B_vo1iew"l2!27RBl:[&'gFyBWҜ]5+J>iWMRPOgk/Sn `H(Wz@xJ$w *ݠpn]ͰJ#0MGFZBÝ0uPRT ĂJ}oo 6u"OSkx&(<9q CLkm苄&J}A@k%f:[M@SqJgI⟲QzC` _4evSEGtձZ_@ `X ޾Pch:5TT!&E ' G Z/Jhޖz!k '&g G +5BSvR`kS+u4h}0$TG㫾a C]^:zh}#3^qAMaS\CDe"1Nsu'D"KT6 ߅4=^%y"J2 d6N3 !&J@N0Q껻!:B&?P0-(N+ɚ_eplf:jz"Kt`w}c{}3ޱ-,:(S+J55JҚ[JjjMmYqI\T ~喲k(0fT)X*(+%*J5UJ+XVbUQVњ5lN[]Rl<--+/YWJj*(R ZTUՔ-[[^TT\S]4lEYEiRBT*[jӯT.Z6$JI-\\YZVS]SURY^f5ڊ⢚5hiyl_).Z]zr:LgRt򒊒rR]Y6@eU%jH=hlMEukE(aKEo㌉_R:5kj&XįUUSJԞ0ʸIWKmD0,.)*Ք/*Pփ[G~j . WcMg,y4 .:Rlo?(K#LdE:ΰz;`151 N9=  FL>iSqr-=nTlC㤵 ʭN]tȂ(FfF<CQH_Y Fmnсښ-r ԊQ B(y(|h5-1 =(Q'Co*Bp)jV/{ =soFJZm@F[THڔTo7i0NaXN5[5aڿײV/l<T8mQibs4#~" WPa\= Uag)B-]h8lmV?l뭬ZSy_Ih᢫w=)sEg6dZm0X/B%d:Ihw!]fJ ކ&V,yfvݺk+jDp+ MF]QtQCuQ tƻI!=8y$3ѹAve|5œz]>+;{O:t?5 4)銓:=7 1>' 2 "m+XjM'ZXGttELJ>Cv'g֓ _"B; ŃFUtQivOxthZ! M 3t CSV t ?SMFFO3Տ;tZd.`YϪa 6E"t FceRcS1`<\[aiCCgE}'O_cHV.Q4M}\ ;YX"=֣qJub^_tM_}@͋JdR{uMF3Ҵ}=S0y5O_i*yX=8jNw^ǣ_{ޣ#P9nw3qsm xf&UON^Lt|4&O6-vʯ3 ,Sx!j~xzV.=ҲX=CČxiaH{cyԗ&0ckzZUhn ֘eٓQ(ZAtL =GfbZ^bX_.U#=/6Mhj*aADYO5'ػ2S7T .E }̢hSkZFKQ)Ci+>@-A%@bWCo9Kqt2Y ϴjT[fհء(/5?t؊QVS_-e4E|1Qʔ2ਜ=޵pqLELf &C)d)ah8ZJXX|0.J5H?SUW^5i{JKډp)La)QQY(L"5l"gȪ)VYEF9/f+1T_W(ֹwDWX+a*gA%0lG2&2]M5(eLFjٛaݧKER EeSt6i ݺ&lyr 6ٺzB ,~W뜯aQ;sg踿;4Zѵ[Sa62] J 5NdgdU:OکkMj=z+Kj7Z}hح퍦VAVk`DUDe2Ntm7FLu5zV-zͯPYV`^P]q5d,I=i֓:ݟMj@;G-@֡TS8N|-~sAVe*W-Eu~Nr;yC%kkAZM%?W_^ W2M6򲙜2^t /dGU}Ws#˅.Y<|O%Owu,w3<AI<$:`Fl#i*LM3S8{L.<&GڄGAwFG`#n_]Ci}VAy$LoH>+w@ |,7M{> endobj 13 0 obj <> stream x]n0E -E q;uD;bIs!93<"9;ÒSwtKz޻tKO2%s㶸axOwuIӤ;:_[{uf=<,/1TtlMm|;^\&]Md}>i`\+d "5Y1/![+u~Kރw F~[69`W5_r} k+pטo1>ҿco7`B_//u|_.%M/[8 -G܋пPu/S/i_l|?8SQFko]Jm|x?mvwCKhj/ y endstream endobj 14 0 obj <> endobj 15 0 obj <> stream xz |Tչڳ{2d${&2$aBD" y@$$! h& af|-j-Ո *}ETzV96rUZ{d;{ko}`i y`BmsPy~w"kn!ֈPdBYaR p̞Fi;޾Po~]<Ѳ~\E({&{ ޫrC U&H |% B01p-4]YNPNo0̖4k-#>#ˑ;]19cDPNx tݍ[f \G(sBlAP+Zt7ٛnvt2;+2΅ "mNf**@ݨ wxe;Luw?#g ^̀Q%R8~ üx8}v|2?;^b19MyNExƥO] _@^Dx%5xgjLJ7X hz؎9}l73\.*/?{yyqi!xU3쌓3Xf [暌饞2/#Þ3?{2Is7V|*=pX3YEsXXՂ(2P1+{WO5k̙m2uW=ƍ< ֶh&=fO]mZpuWe̫{6]XӈegyDLBYMVgYunFw3_/? slYG?G[[V _uve,'\< ttzo^BGPTэL@/-Z%{"w8\ z&E/Luov0 {¿&𞹠 짟eg I>ge si$78P>;/{1YLΘ~,2f2cʰ\6&+6^ki<Ƌ!NI yB7TB7/wΜ kEz""squ86 9sإYz*5e=eʒ6a{v #O<īfQ ww[71?We]\g'~~_ #cм˟'Ȇn:lj2cmia`QabT37Ϟ~"rsI FM+ !"3hDf )"_j̼%s8䖕BR;NAO-|..}WsguKիoطeˉXc_)P x]rF4*mѴhB U AY"KF#{83ItR~RqRyRuR}QQQQk3 JB\nQvn"o(~' 0EQ2vY?:#/{0;_ {Q0kרxd<_6kY̕FxWo ṷw3ó=/g~y 0J׎ ':uI*c-fbC붧)t6qգ3žqt%kPf1jYTfe$jFC=GA9 A7 idD9~%n$"">0WϿ{-5zwqY|-?{gx\V5SBny3)`L*NfЮt*LY;9-dә6td}ytvxq**+EFLG#2xP;=@ tΏwhn-,_aM:Jh4ZN5ޑ OU@ֺurkrUvM]׮oi۝uuuuuuu9uuuU5۵u{T{{4{{t{{===Tԇ4tCCC Jq,N$slHYkVz-}Ѻ_m#}!o. uSaZo=`Oq j\ؚWȎL//` +ƛci1=Z.וiC2xyKBhrlŶNQǬPairQF+Cƕa!(\P:0!1q Ԣh7* L:՘F=_ ^7VFm2āNbkip?S]^aobLДLe~>'j--~|C*)I~쭶d+ sRB>jV`)hQ!Y ֦4lV*ߔ4eL M{H.$9zrE%Lad_vs4Y]ي s5b [\[iVy%'m|baј)CF.*bKO]S@%CIV!v<r7 ׁ6^j *$aɂ? ٦Q +a6B3Q[\S߂J6?sq}*UdY#Z4k"3E8MN^P:d)|uEHBgTy%V:2eRoHf&tdeҭAiWrdW&@!v pA(He \ytW1P.tJ= NCif6bLZy2KY"ۢEf,ʪͨlXmH.[2E FC }ȆK۸t=l7 0ts;ӭfV\+-$!Z#׆l۰δM%'RrZ,.tLP!l u/Yy-f>cv0l=[n3/=b4@;g;?وgۣ6tHfIՃxm.j!']֬/Pitλ q$ FДʔ%Ja8rOlݶM˶n#!<1q_Z0K1%zݖ9Ex)EBFa4!T0^\t4N /1|sکuѪ|HUtk1L?<:s8uC}t˶Թ/[,Hc^W{3!}TT j@l ^qK. NdMFY!È/۷~8uL`d P6L S~ja0VC s3GΑ98%ΕۭMLu:6UfFJuLJ3ęR:RR~C9TH6{+_9|3ߕ[.הkurY*mSiڴm6}[Nls{5^]7uzskk;W9wwϭ()l*Wx +ə'&g;~y{cG>>3Q=8C:&%2C ~_-w5 o!~1OdGFeJ!u EHWvD]uH-`흩gd^R@]vr9 U?zX~TKn:z_>rlFu iIdBG q%på7OOfľ3T*:@,W|"'g)U/&?SjAL=H3RpIټ[LNn|bD9Qh4klTL4V&vVf83(rtƁ<-y<[ rZ?*hf L- ))]c-}u˿@nT \1jϡy F>Fj=TnAmX 9WLYA. |N΢hr)Dx=fbweE BCߘj-Y.^7W;\:Ɛ-HNqY`MO%}ikNie.&~o Di!7 !3%iiፑfWjcdB!B{Djs@Ԗ*Jm%<-5'NtNj|6"zLj~VdXP?' KmRj4Km zJm95R[\Z֠rmYfi{|[jQFRۄ*Gk{b|~W)));`,|nn UoDH]X[=w/|x/C@% v/ S+vD)PcsSC H ~,#]Pdmh dD,ZR%>?𝁾І"PH xstVF槭X"|{:)F ' Zk#X#}q> V (X tЄ2, z;)0I\PW1_tm $@8v( vT)८A?dC00Ai!BM l@Oq5oǝY p6L LG,!>rum!I DhZ CPj F !*'#@=>P3 Y Ā M34qCcp BM ?$AA~h:_5Ѕhpcm_<%HIHq~`ӘHLr|pJJ/@4Ę7 @D6"(J梋]$u]lz)g:M (1 & lApR ycz|1v&#%]Sq%jMBfSG> / °׷\%)Khn"ԲoimkᛚWUTxwZ5j偢o+u nolV4@_]CU꺆׭ktĪ0[Q\ ^+׵ں³VMͭuU+UM-5656*5+j@ `T\tY&BomYQټM$lyJRRf5ܲ_R\S,mh\Al_RT.eU+VKkZ&!d: 44Wֻ:;5TRJ=X[Rrt]b pȲ(P dTPimlnMr}]Klk!"67ğ0 I K|D@EfK VT"Wh!j6v1RrHTO7Z @} Ew&ln ~ |@tn$¯((%P"`!`H>X f%/}}0-sjB%6p$S6D17VU DðS}"Jr_R+V2Po׊7{AEpKHT{QZԃbG ӃJ*&YjԆv?gדÝԳO9 JVo:a9Qp2cӢnR  l覘9 iHYOd 7}bI8P2.J$-*EIbѤ@!:6+Kŀy<'y3ۉX!"{ />'E 4}'iT4R4$f_rш1 QRbSS.UD{ O%%HZ#H} c7tDNa>+I͒L]o]$[{THO%ww)@+싮gĮJ61w34C)J`H< et.qQd $g_3"=OQIQ+a8TS-|%)K?Q%MY(RA%k4c*0^<&ԶZuJ9N#j7N#롞lcuC= #z_*wlڄc#ZEyMo"tvkO`5zI–56_j`_XܩdUZS6Qx)F7+⳸gMyRk+\SXOVCnlZi.ւdU"deNiRt]QAit^b}Y-zk~5ڎI oP%N;G-Gҙ*H-L"o%g6!nOdnhzJl6ErqKYS}ڻ~~Z*< }S+ʿK)t+3~w9~GoO-~~.C.S'r6K||3~M U7b/V,?e}3gYÇLa>d‡F'A;7Or'bB<c}vqtxcܨ}d 1GG=&no6SޭŻK ?>~|N wީ;qN;ܽC;{6s|̸g3ߝ<;,ܝcÂGu܈ux xm9fߖ7z$[k[[G<.ǽ> endobj 18 0 obj <> stream x]n0E|"W"!E*Rb,C}=3:ϵ\a_ְ~Нyn.ۊwz+OYono^*vnƒobQn]ߍ"/E;1>U綇eݻ_j@(ZKVifӴ`}/ \de{{ađk~6ֵJq;Vi'r,czuʦĊ@>rO|z rgR# ٱ JO.yO?> endobj 20 0 obj <> endobj 21 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 22 0 obj <> endobj 23 0 obj < /Producer /CreationDate(D:20080222114944-05'00')>> endobj xref 0 24 0000000000 65535 f 0000030527 00000 n 0000000019 00000 n 0000003121 00000 n 0000030670 00000 n 0000003142 00000 n 0000003801 00000 n 0000003821 00000 n 0000004010 00000 n 0000004301 00000 n 0000004459 00000 n 0000018230 00000 n 0000018253 00000 n 0000018447 00000 n 0000018980 00000 n 0000019360 00000 n 0000029451 00000 n 0000029474 00000 n 0000029673 00000 n 0000030118 00000 n 0000030420 00000 n 0000030472 00000 n 0000030769 00000 n 0000030853 00000 n trailer < ] /DocChecksum /0DADA992A1575803CFD639589D0682FB >> startxref 31040 %%EOF kst-2.0.3/devel-docs/Kst2Specs/object names.pdf000644 001750 001750 00000250324 11544160206 021571 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream xZK6 ϯ@RQ/[@``2z[`z(нW",N-f[)G8_N_ZsvӏM/׏cd>~zU]j=ɋ+\K>3e㇗/]9,C /9Az ' y͏t߫cSt#<0GMlĢl./5 eZ,Am$|'$Ofk@xOjLA :zVx5u uR@'R E謎w 'Dž;q$ҥ oe)ͻr_aVGQA`p&PYC1Ij"y)dCqd eKA43WpIIB8ſ Cp4@h`wXu[nb U" !& ƙ3 ]FcS;D$[QYuOܰgx)>> T-BiuTY26x )\Ō32gȠmx;c+G4_\Q 5 gcyֺ ⺐mѡ f$LnJLЄN(ڗZPVF+c%xCg$!@_*p=W,ePc4 E0W_91 )HeF]"(]CHFxl^%,LQ9:A/١-S-ڧάe暊yd  f].U.5&#{S0|jJAOI0*[s#6D hOe#7w1Hd ̓uN%) ܽ4Z}۸pen H_b((O%'elfpR 1W2ef=R]lHzB<PMtd#elUUInH^@ݦbz':Je;I{/a镫SL³hi*b%Om .DAJ$i3.- QWBn'*k,t٨:zOW,T2t8ێwiəJa mfQBa-R^Pv-^hM_)(9Lj!F,lߔQTOi}S I7cTy8 @HU(lqu?Cs0(BK}PILp$\9 s1[Řn#'ףK/7s EJY^*;easWGDthʖ[Z仰߀g 9"11@cNׯOU@!{*:I䬸ݯH] quYZ`%H^[|ƗDm $ ^y7܉Z1=gqi79Pͮ=ޓ e%zk(NJ]ifdۇX%mNC="\Ն'Ge |~?z> stream xYˊ6W:{zz݅,Bv d#U,k^cIGuqJ8I. պpO_/\֓ڿ<P.oQ)/j=:Z$Yۅ.,=5 8ż+}&Lv'mܯqWY =CM`$ގ `eU4N ]^,CFVGf;D 34ؽXΜ"pq !dXh`}.Hw#0(w8<SIޞf)!:Zff12h C`&$?CϘs$SXeG}`ys0J}\RL" =[li$a!Ǹ8h4q~t"g2 nFi*3\˻6f vu_þe%r'K+g8;fX/ި~Ƨ= }kacZYR6]EW?/z0>|gdm~"Hҹ#1[( 3(%O1Z'^NLe T]{6y:i1Y{Q a'KSkqל.D*OhWR܀̒,XL-1wuSKG+$0xM2/2Ӛ endstream endobj 6 0 obj 1658 endobj 8 0 obj <> stream xXK6 ޟ_ua1d.tBM~%=s.ʁ!Iw#}cyZ[;_F&}:Qy FQq>W{.YpPOϏ/GZoЁcaBZe "i˯.B[qTYb$i!!̘9Jqư.QWU%*I/;>0+^H&IIHsFRZ}DV.K2Yݤ: p'ϥގPRL]8$V"`X %Vc<.ϏcA. 1X$-n&HGIU-w2_ e}, |Jf##'e`}L'E:Y 2!X&bmD Vt"3]Lu4c};9T̹$J lSjuO4@1QpRY(E fPx>AW@92[ v$5.c% -u5 Q8ӥt5 גN{ԟ271DK%㶳hwW% N-VKK/ uhv,|@&$<4_ՓOG|t*H9m{TsCd&|%WTM/âWeK/uT endstream endobj 9 0 obj 1435 endobj 11 0 obj <> stream xYI6_@wT%Y1{96 [&K~J%'ۋTW韏OtVtk<_}=/X??&{O - OYv9Ui/gB<_ms9B^XRmFߘ6-uIVqY&&R3qLHH _@n]Ubi!8Q">ݱ[w.SBV 2=`'zY\ڱxUxgKʠNhсGfe^dՃ_iHVsDZ𶳾!dc̠*.b",Jqu2ױ5$)`2NdgM\iLޔ|w$%(@lwH1w+ s L_ d, `L1w<_]PpBA$*P?FDo;\"Xx"9g+`PpK1l>bƐҖ].t#ӠxP7Vj - )&g:"90َVb<4r4Gz&SVo]I䙘0* <ظm1_qy_5F mbzޡlUr))LFj&<YNCm5e R ̮'\@Rfbʅ[Xv5q䬐LUck=qDwн1}Y&Oo<d'Pめ_(Ёgo(5Rrkn@r9oJ_͕9V,fAi7 ij0!gnIL )HN#&.F ZwINεM1;T`+9N}z U h2V5 muθS}J?tPʦx7!|}{8<m1Cߗ o76*] l2٫])XjyԴwPv94u$1m0 )MJjSd TSZWU9b}~;߳r3WJRLW;dMN~ 8>oDY}pY39Wݦjl*jE{<ǎ ,1Sg! {!_<= fu<4{d#^b3@)x$F%>{s׳p%وW 8fL8oOAdy~''C)w>6GAj:!+]8kf`#9ۃ#VHH18r(4C^Z;鴗 2 :؛@6Ad=F 6I!qcIwZи1pHZvR p%څw@ Am&]F0!U2zZN+7dY]q{6Q?OV!=b=Ҍ/Im|EIwjHP:瑈4uZ> stream xRMk0 W> stream xԽy`E7^Us_====sI&I&wCDPA.# DvuA cl%x~ՠ]]3pt2Q?!d 3yyrxt!]nB7=3HƓ ȋZ4*ڇ8ŏ YwK9#U߂C.h` '|߈oc 5ѐ}:nޘ+PdI0p9n#IR`ܛO/ͿEPacDKhz }l<"#T|q%"_, ^&ɼNdݒs6][#Ё ":D?ohqu$ {'\> 'WHianf^e%ɹ;s-i4Mk_|= #]-v'$<ŋb܉/×U[.KX%NSE"K09t21- c*v ;T4VԿvuta޻z_U]KܧyS~g3EUpp݈x9 wTǭ{ D<ρx>^7s/U #`L s"I~$?3qajVf:U̼O˹ikct)Pg$Ha.DbOad4ϟ֓ y6cۊq4y>8L#kk A7RZt+ =A[ I@3@QjP t"Ny:t.{/z m 5q&7͇AC]pzE%32H.$ЇCeF v): E)\V߆_+E^i}ڡkm;B4756d3ښTeEy$E#a9 }^vN9b6 zV2C]]l<2rdGf@Ì ӻB4bpt[hpOz9R\5WGB]S&AaɡV퓖g58WJ&(aL[zn2/ AC〶3&7Ln̈́JײS&!4ӻ ).2ys=H#[T{٥qc.,ó G}ʔI+i;zZxXhxIDzδ2VeY:=pڂC## d,'uѳijL7 =Jn㧬\itlH+GDB#VN_9;lf$EVn_xo5bdxLFl꺱y jXZ`Q“ C<m{#I?2wdp擹#cfLU] * !up0c_6j`", a#-ۡGvT܍݌SC Qdlb&w]MmW)ģWq$R 1@OCawA\_[-TW;Rm$`V&>z1%I$'%ȍˍs@ acS OM7zݮp(K n|,B²@f6<®!F{c2sxd2xkܑ xG'q\w74p-|CʍB*aGwmy}6;2Uͦ؞ oRVLFخIdDx&]ds١ ZG: kX[SǒA'⭟%uw~q,t9x_dEG_Yk߁ˀ)fX!Gg8I JN%҇qh|e4FyO \]»ʻƷ&vݷſ{5տhBc_vXn24Ex1pQ7LqCMi ;7}+HrcSCjis=UI0߷x`t#c'HT_d;-eҨ┊:gssU?^~n6NYz˭6nj&bOam\y@כ}L7 \'$0} {,X9^ǻ⻭ q У韆&VԴNz}icJv^v~ӥ+VdW46 )di$^4=nU47tMUY͌1v@;p|f ĕeԤ L , 0ψRtSDԦL^TK:F7ʦ33|V'az0q=\O$T`/+64 U(|s\ j6q}~(T6wܭ- z ؃%0ݚ N+G~K6\o0RB=p}&PP6bmM$Y誸9' &H$&[^(C;=9hyVJdE:.@Y.1ʎt"Uum swh.Un6c/Tn+fуkO95u'],9D!i.#`x$gea'RK)> *9#J9^v~ ?_:UBu&a11 ؔ||i^lr4rC8yNlNGHSʕ1Jnuu76Ib譒euvTgj}rI?ym|.HrA+6C8ŃAJ]7 89(\衢ွu|vZ9ّ`\0^Ǥhx̋tPK xGg>]xewl⣢٠=aWx`q˞zf^ލ*.\_p+;:t0UX+`0 Ɗbn&cؒ%%h8i ]Y1kBIYnF<HEmqe#k#"ڈT{ &: h` 1t.S:pѹ[ 7tqU M˭*>U wN쬫+*>rA.>Fȃ }0ZTNRw!sp4efmlC9"Isi\< TQ ]eR,,HttD=f& Bآ5&i4anw:>Eҍo{ҧ|+VՄc,HS06ry3qr|RL|P}PQ/1eU1F+TR~IâӦWY"vvҔ;ݻ{kO*7:.rcn-o=o4do{+*G*_xɃƭo5Zn}]֥:* X|ԳNƜ`p̥hFuM#YLu`3<zC(.|/[Xq7ڎVA8 6>ܠd5e z*clp<ЊgZ[x;~E%c / m swֻ)33)z:qfm"my H6D;QDW()z12L!sl!5,CζE6@GFӂ,%ea,'-60Q( 20՞AZ {ms}rQR ;8BAp8Je^4 HЍ+&iJ};ؠXWPǰ Za$k#G5R5۵-H?w` W=0i!GpqǷs>]^M4crBO@t$+a$3/RD=#/lZ^d&*&k)oy)u+*%%%rȪ]tN2~GP뮤~O4@a/?%WEȑbx4 OzC`\hz/qE\elc˧/*|_SI4"MC~ *mjSGkX^ذ^(i mw:l7 wt㆘% zojnPdq++*yKu NULGudX]swpVvzZA-mN#pf!UQߩZ__O,%ba9\:Օbl(U>_W2c2Ȩ+_\Δ6%= 66y$Yhl$KfOUgA'T~sjLT[f% 0"~y"z3/q{JED )_*Ъ5W U6_[dMYhX؀`SQ3m պ|Ar5u*{n:`\㒛7zЪ}\ _S._Ah܂Cb TriNn)zT}/F u aM 7M%8*aMbL.JO)x**)-^i Dp$ٰ<RAT7`}9'P(P/VJ'"KʌNb3L6V%b%uOr!glJ`$U7tYYUYձߗu@\SW^_@x cK]sUfUU:Sro/~Rv1\Ôt@V;Onݯ=heeIFYY"n؁a$oG͖=AdžA&?MML$z#$:ةϛt*A]cCh4sp&$qr75Է>4p9ܷCg>qE(YZԯbHDTxK4ZЯF#Yа6Eync4,]a9|YU@H?3i(~_??=`4G>+W){I0S03W<ӂKdM`n}L$1iS^8A FvV&L_@e\)K`7^4{"Ѹ'B&1qoG<ΰְǰpȠ1dJTUnܪTG >Ku͞f0|`R :jC_(:ij2w8 Ӣ~,ۅҎ|OO |tw!\.X7䂪O+嘼-FOS|Ki0J`(Zv>l$ӮNJc+dO1O;*O0+[9#{_?n; J7zsa jk0n#\8,< s\#`\C8mq#x(oxSu&&+H̨H.l-LwokfoiݦIi4c54gxM<[sKOfҰ8*gAHcs)RFs nWITӃjua(P?=Nj8UPƅ@g#rM5xp 9p&_l:OM/aW i6ͮq҄s& i¹Aׇܭŋdd|=80+t5&8~鵹uGUju":3iIn!2YgsC e% h:gx! s0zO̪qN~S &/\;=' ʒpHmnJN`YOk~n`:ӝD(r .%R\f&n ˲l"`=>fT\$rNst2No΃Ѱ_DgsGuPA nDtU?6}oduuD= 7yKXnpmu+׺q+li6; |5Nq_?ܸ{?)6 ^;e dw+r?kڢ^:+l'u}SHcЛ%" W"o(FtݎF!Q /ԥ7G}_#lMc|V0$^b匾 Vkz" V MI iXDbd$m8a`T" cPLfǝR?8afo:~{om<~a<0מ% SFeC{}[#>7PŸij'&l E{^W eRUq?AwmPx\Kp,2UPS[WSLez 7ez17., -~oeIa 9.Id$_|~40֯x0qL|>o0θTuTd2YOd@__H(MLLK,JlHLhJ4P-qSbObuO?ar~`}>LKbX u:e `Gz> Վdv)ނDY+?T%?iaahR Kz`h# xF1:+C.- Riqh  _+. \,F.j. d@Ssfu kV4}!'|ᣫ Izd}=5bx՝oqۏw[݀M3jN }3o޽"} pz"#G^gn3Ȃ @7a :|0x{%e|;]Z_=H|ɢ4ɢO\hFP ۢmQAyR8`#9먯ER׺oŒds`r1wzf㎇fu5S}ri*xjFk<=36w<0ѫr%k+N*8ƟvqYQC㨯ЌJvUIqmX9<"z|z!Cѧ6͉H5ǼEF/4CO_+Od,DZ4 " L5F S .VWk #'ѓe]|i82LlƯleLhoRxXٻOhpQA3^d$]D5)&N.d3g.h|6l w?W206D 5RDWŸ)NOY<+|[x]SheC)KO eJY-U57st<_\'kPՕND"S΂M$YY$\؎PqTǓx,/1 ̯~힅bP;Bno]V$RM59MNÍ~^ r{O~ \GTUzmHRNɭI̜ ]zTϤ%%gnȬ+{;CT|WSЫ%#2 ۿE2L1$ %em<DuqInRJ N*).ԻK#2zN.EdbA 6Cq[H|kmAa<.6'|(̆fW8q r@uG GfKHQHS\ p C4dZVC3bt;UQ'e)%OjՄB]sϔe7(r?~vS$së7L=j_(x33X<,i_?>s}IbKݍ:G}m7כFW՗Yfa32 *iEBL'm_1=.Xة~: U4tfȹOywHV&E&~. ;n&ԟ;hnDajڜ! @BW/6>sBsf.nbwb+$0-%A6_ nױsOD^&0Q Ϣ[;gvvńo ֭{[2'kdl6_Ha`O ^FkDxثA,S7y<^%IP,l̠jI7N>6;U DLjiv\;--<4p1/k_GlKJL1,\mzyyKޤѥ̯p\ؐD$B`5XQ<ђ0u~TYp7^P9yT7߮XRNŹع:kVǫ;f*{6MFa&ݫQ|A+T;xoF3Co8BRXݽ궗Onhy-{ExJ_K t=^yZ0|i_u%=yj'Di ԛD)ǻa7!s`CNRl~{oeno4wSALff+f#U$%"Ыٜқ}Vtn\tiEqtD(CmBHnB  lzCg 2c rtJ9{HכK`ըxSD]Si;X&`AkN–ZGq>`'Od'lQő_+),ܓ__SgeONtXkjOhqDR9'ҺCJ9%It}M eCHt{CL~٦ݧ%ZOYd<2Pj FJnJ+D`sL(q܀ץEM?߀LUJN/UHx])t.n^cWzVM58Ot:L2eK+ۃτD6мٮn0mQa3|ksģ᭷~Ho]C/;6r~svGw+Ӗ'ZCrMᒇcIzBRQUF7vDNOtTV;!=~jNOgݔRpȓ*}oR819iNK+J2%me 'FOH>quZQww͕W[J_UGG諫ohdӵULy< v}( 8M90V(&Ƒ&V*e"r~ M@L*Fʫזk/R`>nRqwu_=p@ >gݮczwbFD%06fd $ IӤNrmi_B:A@   TA3ϙF<=>N2PQXyO4Yn8ӤӤӤ]4PkI y[9bޝߵK@! L40} q/)d"d-2.sr;ԍ#=u>Y؋( s7DKѧҐ{Q,wza͢drWW@8T c7/҅gΪryigeRtm試VǠ ajwsvX]-IMD!35t΍5L3l0iE zH& |seAF݋Zߏ(!._~yo䕻Tm3KUN,rt}k `h;"RG.^҇J*aRfF1cΖ@RHJ"fDß-_=^-I}T1FJ > Ȅ-[ Ӎ"5hL@{Kl,Bo" Tk¥j9\>FsL_0ʻX( rD vQH b|d}_SD[I`)HhuHKQI:G%]͸ so/ӡ.;dCWtuFWlqfWS,GP&6JnMEIJ-U#nA颵 PD/p_FbHe(stQ נR`+<;*bv HU?cTҡ4V]=пiTVWWw)ŭ @,dt;8ץ]ť꾍}F^:꺖9sOVnæ=C^$ K%?S&V/o||8IEђ~R8;d1ښ1zbtT={.ήܑ]y(ͱݵ۱[xorSvzV z)YbgR0n˥nrS&VcCp,@wJ {/_Xms/# vh f XXLf;:(ۉ 17b 8\c/*m.~g<Hw]>rn'^r$[g3m?xͧՕSϼ9-\\I˄wG2zK H@>zIY$3]g!Y>0! >0FXPބQ#"N\ذzD9N΅y3U1 Re?n4#:R\)PVVk7P|h;#أ\kp=m5lD![`G_ؿ1?I@Jnf  2GŝSM^fOဃ.?JK6a78!N+7g}tU'wq0mKre]p]<*sum@ ,o7ϊĜ_Kțѳzu;KH)[Ll9N&9'IJsعγ]gKg\^SY>\Jv.SS%/>&+&IRLKKw/i^>_~"?owN9AG1J9DKk{(hʚh4QKYKO(fXj ;`iGFc0h5a yԭ~J=R8$o'+ԝ8Y&$hX6S(A(["08vA3!=D8~?*BE1fƳDi 9,& Y,f"7v aLՒRdZRb HH$$6{ZjR0]z%N JuC~# gOngŢ Mwb ZhUm6jPQsj‹Fqfjn 3ST:=&G::!w0c:<\/J\oS8x =܃c^5UOj6/L@_Fu!XXgc:I0ǭ:qmusu}17i>){xo"~C:>|oO7ٞ1z+C P.h@?3'}VUo%\dQZ9RY0P'4p*-^xZ@du*Ut׍Q*ՈL}ZA-N!\-$QrJ~oD$^/Zh6fYea{TA!6 6Ml#A7+@B`'y%w Yj:&.08!`X(  QIP2A)$3%BF~L #$"-IFqA&`1rVMu,1N3\}1p%CNZ[g/}ר+m.(20ǷI% 'ܰ=.ij-hO.oȷ~rӗ^zKD?7ZRݰ{HH1MzIh֦7FP~T1Wh:H@|{:kmҷ)zm frbVH:ڝ߫)ƃz u,eYV/>eFhT|%Dw8F?4}mqF i-ɳCgɗȗZ\9]ƃf~؉!tDKܖ0Z1S܈R R]LZ-j`u[+ZP`I,O-tc-{jCO[*UY|XTj>v8RuQ/&c!up61Zd!rL!G?8Q$-CcRS`GL8fI(TPag,X_I<|2[> t압n{g۪־s[[Җr;߿v)qko]7aĻBn[O޳aՏVʮP緀5\Khsj$X@NKt)Naa#es}¢,VbZĊE 1c-\Z@fl3.22F$v,2c`ـ@;Y) AۤPE(B du܃cU4$v>sWT fdUgA/")mto&ϟG /|rI9~!Ϝ堯a[7(&d?_DŔ&bClAq\`!1=x$! a,,hi`af<0Fٵ8^;%keycgR,9IyH !嵶֑ejkrJNv7vٕJn r;|{s=s=$Mvȁ"&\/X߷;8Gy\19բW #Ǖp`yY>OZZgk3ﱶںM9nWfTJyBᴁ*{ FSqnPZr}qU}C!=9y{E/)=V0q3Wp\**ϷVVA8 d46r Uvy6kBer;Y'&b2v  +|Vj$Fc }3e䈱q1G?]iQl75tS8>3kkw|hBOK ^j,}Tn3}{.DIs|WGYn.=7 ,:Fu T6`&~Sy#哅L(4i%˂@Ҹg7u1w% AaxV} %5-I}8!e&cͲ|;\f!)Җpy`&pGK[FLIM1fdh2R/s ?q>/ㄓ{Fs? S;XcZm2a>+m[p_L}>2_:y6 i$4}1@}$,42D$Sy ׉JJ18 '3ؐ|1c0GR 6Dkg@lFk$f08bN0XGn0X4_0TzSɖ7efA; N'v ZO[p#Ɉ E a;S`QVFYn e`Q e}`Q 6ʎ҃`QnF3l O#BeVۦұZ(^\p:eEk6س ls߇p \4lI?p ҟEWљ!t(?վ~N4!X>!}d * 7D H})DI¨D xRC{;@͈w/99bjd9+aZ:T/Fena`# h<?XLAH~/^zP ⌒?I(_rKP5D0$#2ʮ,YFe2?ʫFa//PyGO8Z6G7{Ti81c4nJd2<8=zJ+%I`,]=_템RDn+IDg[Yx5.0J|ōۛqXG/ΡIjO:≄X2mU?ʣҫGh !nH1Ϡ>z ([k&x$1>{0BMъ++ĈaǢQՖ:c),vJidGoK6!eF{F|a"f Cwo{Q Ҙ;|ҁai'+RX򊾀Šd{!88vF'Fa!)_ 7Ko$ݲ)i$"z8ۛZŨ K7ġI 5 b< GQADEC!o'_!$̋dp'K^)yG’Da٨{BCԥ CH%0 ^_ \`%8"!I(aиALjQwb5QgpC~[%%]KQ$qrH;\-_`ۺ^ 0+EQПT(o̧tdյ!QR=A~0Uh*.>ڇs&%9H,^>)>|,) t1XЁ(qӁ+Ec <1(#{m`_K*ĺz[j~_ kj6onSXvkVC-fݗNF`< ^bSBz0s/~~h]/% ޞ' W WoL[FVoL[z3mfʹ՛i7Vo'~]+'k 55Mf[@ct✡G(7=+n2̞"W[*\ݷy mX\H/8ETM.p t B~ab3«dUHBˀ ˀ F̖J6~.HpB8J,V8P>c  H>=惘wa~k D8p# #!7cAsG腩lvc- Pv>-;v, mX|.@grЊ O6u\ 7 S3(bC: B~5HRrB3l`s .hNqApNa';cP5@O i4(ԒjHNHݐAJ>VhgЃUe#YP4GI!Bӥ/nH MgL,H]!tyH:Ҩ8SFQ xwŅXnڢ֫eZ WX5UӐDF̐xp2r5H@ /e2`eо SH p2࿘& [!9Pl9`aڔm9`?qHWX]:s:g*i7"Y(ŏr2\u.HPmI쀚FFqyHIlV[lDB!Xq؎m؎lGY竮T#kOמR}wv?L!99MF]+אb~YØ;1_005`xzs:`p .qCεU_T22l2V6U* .#G70o|#E5ktx|́ wX?əhm44nmm^!;rߺ~7R`a}hW80[Z:ZK[z(>e?NGD7 -K :J*]!.aiiX4;fb4#H3hƒ@N,Hc^_FSx4VIЦԴ‹?n~cfPqщ!Q#h8--]+w73/>Lw7ϐ-}f;- mʳhw3)JW6YYW Bԑ]jyOM>T`o Don}ಆpϓԪi$Zes\ fJt}p2<_p,+ȴY/5BJ1G!=1Z~E]I'B849yk?|  sJ`C*? endstream endobj 18 0 obj 23734 endobj 19 0 obj <> endobj 20 0 obj <> stream x]ˎ@E|b] 3ec%/P< m)n]HYl{vʾ}}Sznf>1=K%NҦ͞l=>nSsZ%mӦOS}8%}=0Miis̲sʿSwGom8V%&<_~Į[!L9894uY Vr{R\rJr~3-sxGށf1{cAM_/7ǾL{?XMx:+u^l/{C^9 } G?P_/ /C}8п-/qvYoup^ 8+Q+΢WDﱯҿ:WD/pV+u?.Gt?> endobj 22 0 obj <> stream xy\ǵ7><v"0#"@6[fq06 1d# ؎Yv&ikڴहqoKۼMm{妮^'m z3zmę9̙sfΜ9sf$`dhg(ҳ{P)B~Fלg'~W!Iem߳k OH3ݽw޲Lc67-mGJ #t߼Ahs>{}8,:ujuW!B<<;H;7MKBAz|z m'%(zr?eQvH7qG^1Cj ^_&cMd |C_{Bk䟨bo-In&{btm Z%N-LnꋱH[Ƀ4zt@S@E$D.%/GOe`26V0H-8;ȿi=}Ekc/~Etd)EE46Gt_dh}) $BCxD_$RI/?|U/5:2u4VFo'j!N@O/#}A\>_=|2&B/'G4fRѥU;ӯ*a+WߊmwHiJi!1 شK?ͳO~m)a`3eŖ{3\.WaM]Cj1S/_\y6h.ӕRz=4}t m/C?'+ z|EZxXxNxA, }ֈaZfA?Kf)EKtMrJnM{v9FAv`'b?o&?IXx_O: waIߢ (A{"K_Hn/!"6ZBo!!ezqt9.)KH%[/"z 'BzFۭJw )EOAi79D `o%qaBZ =+m*AK6!H!EaUX`:E IFo_y+(yNS{B).5t(%߉} ݌u5oߒ3R*vR!&Lm&oVcYŷE6ȯh/5u7mdV7tokkeZJӫYiij4Ʃh )-e_/`HQ|u61"Cb l2[>~#!(z؏c_ƖR>za걩TϾu>@?|S`81֛#ؒ~G&~m;<"\Dd|DNBC(y6t6҂ce~Q0|Cx1Wv!hbɥDNC7uq/Sy$^fS3]J'Bڇ O׵]eՊ%5-_^V,). }vetf:R6l2&:FJ]rދ.*fnt*(jK86r|ؾǭdsW=*vw0Gӯz'cu7Ϯ5dq߾k=,|]!vŌ :ºφTJ.Iem.„d5{Gha! ]&}\ʟ+v ǽVGZѬ:{ܮ DhV5frL,ufy:v9VRq:x&ڊM^Y,<5qh/ZkT- f8 >&S/jEmO9m6.>kN_/?Di\]Ylo]{TanT՗86hK?XW'l D?6-..#^܅e۷(źW |2][jrAD6b+ٷ+7=앭}G41m`CWbǞ-+x{r.FVbmXG+.44iӢ(d&Ӕ8WgVYԬYefuj&kzl %9+* c%ttI!E(2:- ņ$R Si$%Q]Ji\اXuYg F%Q~4bd ¿I]<9ى.93'kީWUQ{zZR#@ix7'{d-8ZYS.\4u`^QN I4S4q؄ƆG!mWdY*1Sk;-[ `jP u &峹Y1$W`)I@d%O@,%Փ9^>2c%!3*%dI"9ސ1%ƅ P]RN4, LźZ'1y+:M\yfkNc>(+ۣdxv&yf$7[݄4zԶG& R8=T95ǫ8P6]vR"eł)~o6Ց6|ۤVnޥlٻ"Z~tНw|KcU%U4G/SYY{kvqfufr!Mr}a>x:GYiG_噗x*t~}lFLNuQ=&Hau3bT^8GM{R+]ʒ-WX]Tq.J%QQ<@U 9c 'bq8BONX]Bٝ pyͭ8L3)Gt )R5stVN If*1<KqzBl G|GMs;abevQ"^Ul!wx1䌜0O&}a|Ҍmgv>-V ~7ik_RzY2GuQ<_M{ jibŽ7lhNE" ?P*J=rKMw_D %%jxݤ? T%../h s-3$bzBhě_l .잲oIIAcizØvfګoLɿ߭m_NKs%F\OY*ȥ,1^WT^]igvAU9=Һ=ׯh#筗ijJr]e)KyZr%)3F4GiiYs7m8 ZZwmPeAekKhӕ+A H/K~,ku`;<;BX߱eUTgGSzŔ2$%Yls͜~1-moႄ b.P|ЗW(N(Y}?%>>u4uw[V,ͰGJ+o˴\ZX䒞5uLL 薧eJv4ˬ4XWXǭ"$Š$+FŤqffveONqvBFG1K"1I:]MFn6v9fd=9WsO9 Xbvdy(cGMK6@ZbR̂`#9Gazl~,ai|, NMl+aI1;MD!w!ϗQw5ZynV'ݻ4;nWpi7.y/ݎSJU : n>mI#Q6Vn[ ZᄣDx"Pu!s33>dl5vv$n3@v"F *,$jķ-I!{XmI2R#hDԃR *})fIܼ RvX-"hes@=p$V>Pb\(W>sFuw^*Gnj#)"Krx PaLlT&,Aُ=}l엊v`OqGJw/9>X2(1'MN2W,b)@+HE傅/yN88[$V\k]=瀧$>IvCk0ѮI|]RL4~ ZVϩkc&Q*\ŅT,c(H eʊ /7c{2=M)LcW)ꊟMJI]iii${8=\ԍ97?g1W9?旺pA6~p#%h:Vc]oSC'X|zyebeIbRbhr`5x-6$tV,vօKˎ@#tQaatc'v `ۖݧIb@?;mH.c 5JG4F$Pi1OU  ބ<3y>/+ɕM]z39=f3 Sf6A2?*x+~b4rF$Gؗ$}ibVCc:~$FcWI,o3~Ό`-usgU?haUC/S.]B7'WQ7LasKqWTTX*`0(Iaۈ$}?9NYSL4I7q`Hi"F'. dLm Q?xy:7\(&{f.:M|^DEK'5+"yf'ʇr2K?d,l ,YuF](+e4 ɠ+oY',/Z|G.M wguȋ ʖ2Ke89eIZ*-{^˝"?h`hຂ"W!X>$i eYS\^c^diԻ t%$ 'FS`jR졔#ڒзZ-lR696> V&l|*<3Ҵ ~Jl6XYbl:<{!.ILiVKaNgdhg`cC+j1So-.~`;\lĔ)PtDOOKӣ7~gGKbͶN]B@r! LqP5{ol1{\穽;µH qvy8ٹcy3d;3 ?`KxY5u}Iv#n˫jC6; X[ $s7;DVSBQ$N8L OxdOEIS 7PIW,JT|_IΜ(kslg ;ceם~6$U {۳z&z YXWPw39gEb r18},YG:>)+m[( I&ќl6%Ӿk]כq4%=]E6\aޛuxLUHba yV.{ڭ/EQdC'5KH`%cBD`WG1\JU/NM~mS˻g'ws[nڞc;z}m ߇2ov#}A"oVޞjP IvG&> ؟*'[cd ~2;EʾΙJ$ل-rrI/Ә4gtOW$]lM^mj1γur )"*{ sl D?ttaa)giInHz<pUq ɠT\Kt\uA_Aœ<;*n\‹*LwTHhZUܤ}B󔊛ɥ˧uSljPqHVIM%b5ݤb4ݭZbZӓ*')f'9K b.Pdh7[T$n|Sͤ zB%usJKğR:U\"9)[9E6V+e?ul^R☋'9G1*.ܔr<ͯCTQ'թTg*M}@1ϩ87w*MU1i87%f|_::Uq̯ḁJ~Iš+M'ߕc*.BF6bG=u73D=2>T3C瞷8`|ONSQ Drr}NDwro8Yr~ⰁfZTr;_A]\fM*^B~~py*.%p=4{8+ Í>׭(-8ܵ*!$Ln҃\&6$2QdRCk(2JѾX=/)83EM?9M3&qye RRb弴-AoCd^އxe2Y|7>{N/@/O| #1֛EHe~}j[r\~s[BSųz6ʓiۑ\"3%^z9{4+M q{H< $ޫa\񹏀+8YfЍsNlT|&GT=>.fQГ"udm> z9u7/kխӲfK`QtʄFd5wFͭy +@72Ok45AoՋ-/WZFԞt̖vr#\5ZN8aޗ8#&;u O3UZmG瑰>Z&^%~]2KGޖnA#\0٤Zp:8K[J6ϝ9aÜwb43۳`S{AW~w,?Yf?/&ZݥK;wڊ`ČuJ[z;s%1fivqu,(&,\D*BĜ22<#jvR\*NY2TB2Z- 0{{?3&ꂟ~ضg0',?"m +#uPH_d@)GQ1FwaiʪJȵ򚾭F5Юpo]dP_xH^޽,ߛ\=\fջCLLyɢr9e_Pd8eӄgѩuj][ٷEߑۆ{ۻ#[־PW{C#,}dP=EvwᑑP}xow2#=2Ȑܴlen ޡ=rmP_8ne p#C#\˸t[mr/_$og 0v<pfb _d'<8fa$" xdޓ052\$toNߑp϶ޙHӒm##ݻK+ln>HOp𦞸:»KXgl;܏0oe(_Tװjm\|MCʆUm&жoOa CAf^>>X0=eOd]mfLȻL%rm#I1m oQXِ7 #ol&a$5Ivr]/voF7PpSiUL7cƺg~t{x8<2un?<<G1F-{: - lm{{]No(bC\7Nm[&c67-n03ss6&޽GF1U{f44WGӖuw s1| #R͉EvbUCb6pf21F7=Ft F{Ff []n9`|H5#XV.U,,-*.(-MJZ׌Ҳ /.2.bdOA{|+V6 ]̥!; B.|!%$~q!*^E|N<C%痀_~~ %痀_~~ %痀_~~ %٫3T#[n`s)so2|F?FPv\D/eI\ϱ k/^n?[^v.U3_{.|̡RiT'-IDj.m>C7umfe E^7F;ȿ^Xh[tbd;/&^GcďTה\?"ih"K2vgƪk #5d~lZx>zMօ*_h 3 +?-R4vȫ+jKoR|@ͷz5_K|רyOs\Vs78v P\HgD/4%sxN!@p X]UH) E{^}  J Ey 9 P ^+~ԯ`f? &n~s0c1*xy ^h*Zy<1=.X~pԖu`_À7eP1'lgj2P,Ð\ ?Z뱍xfyX*5_$*!'G,RXa):n𔇧<\<墛Hs2|px$c)Nnǧ"%ωaYIJkvm#Te~PlzkEaFؑvd2#ݮ ?˝ce {A)pP:% SpP8%k nmHIjܺn.ۯӄ"s K;Ca^Dx6@r_W5W5_ _ ՜5W5Ws_ _-DKյ1j\@  ! ! ArAB@|A??OOp??OO??^a+ Qc0Bl]nf^r R@'2^l%kmu|귒!'D '9ȉp9ȉ@Nr"\Nr"D 'D '9ȉp9 gYlza^ l%.t.%F^VC$@R $Z Z KjHj.Z ZHjHjZ #j.'9Ր!€-n K.\ \K6d- VRe!#ArABF2\F2  d!#e!#Ar+.c2& c2& Ș Ș2& c2& c˘ Ș .c2& c2& p5*X585rkkfVr:Rb"<VEVDjq [s x'^7CA}߀.GO+F?<ۇ堗V*N0(iR!r@ r2 ii6R.,}ye<]j%\i_)jjh55[M)r(S3uL^gZqiuLUי\g i ӻyzK'f׹]z0~x[ivwi#քáa1 1Y-g-LV?d(-\VC[}dYGݥlwey:Y%ؓq]3@G]5XUqmq-gUf/>Ԫ{UVۼ9 BI# }9O`LՂam*Z.v> endobj 25 0 obj <> stream x]n0E /EMKBH)I$}@!Te_'m.@gw4ͱ&d~T-=L+dεQ:Dzm)~,K=^e/^7u `>ys7@TFDz 2Jg> endobj 27 0 obj <> stream xSKkQI >6aUۅ1"t!BZh0"d:yf:BP|AzjkqۿsTw> endobj 30 0 obj <> stream x]Ak0s=,Q7eC? & I1k[!Mt=u~`{L0zrKX" 8yRetD%Z7] Nm/_c)Arϳ/fFKix"Buyb%lhBUE($;a%YJzht~ڀ]I=WCܩm endstream endobj 31 0 obj <> endobj 32 0 obj <> stream x{ xTչZ{=gk;&0$1GaI I@1w2!DPE|*T)mhQ,F{hiUғҞsk=y ~LkXk # چ 6vw B qcTVh>{;FDa̽Mv1wUK>,_[j紖Un HcMzofY _o23#5+LW{%(w^oBXiQ4IffN$NMRSR32eM{]^fϙ[0o?XBC'zZe m@wmf/"}}Y00:p'0 y]7~đ*hU 2ɛڇ9mMUZ Зt]jJĒ.҆wg 2k5a6%~HYԑ& (SdnGm|\*bi4pfX_}3S]MmL =Chq -n&1C"C[H-@] 7z (GMX<3pգ"u@9qJ*>AX}TrG37VR-.ҡA_*h'⢙TNM>I8A Sd)ur 3r$;ғM<% #/ǐ0:cdFTsн_ 1XL=卜 sFy#nG=~W΀z u̙u&ǀ,~05KK^h1OMflQy/6:(~sп۹3nb$'ąv1Sʹšw ˌٞ=_pu!FGh)ǔ ̤L%393%3uƼƲƺ&i&yMʪI;;RvKڧKޗ/papé[gq;}s{w:tmZ7gVTYgl< IƔgno5mws~_6h;xxg?oEuKV^73wML}szMg*Fi"<~SyohsgAnЩ$&[--[ :ЉdHoѬQ~22BʑϞx|y1a][9$-G|u_?9jr& :  r82$ JQ&e`PM .M7njzfֶ6!Fס|IѬ=M[r6$u ?r #0dr$Xd ]TYFT|1Qvz?=x葇Nj:$+\;}駿eF7~PK0'!ٺ AjweLr dyCghꐣ `|CA⮜a|z z1Ø!o ^ZJ;=Ɏ r̘'xQ__l1wxߞG^jGYbӭ6tnRq)2B`o ǕH<ץ3)Ǎ?wÏ0Y/CMCmZ'mݐPOmQ2ZLO ـmuNg<<>Pw." c Pu;5`A1uzO&>2C_|1Շq;wٳkG;C՟]]:܆Μ׿Nkz%1׋RQMpF#H+A;:r{ .f%ӨށX\<g ș? NUÌj ^ԺT̺ȯ[ G1-3-a5NfDjdHūQBt3G9W>+#Xd!i`NB9<ە|_ꮩ3v <3QYxgXLI@܅s?eQ@L<=2}Ӵ3ig ⇄!Ðg;;w&Jά1&4YS9c,f:$w+ڻ! ۟ c][pŇ#߇_%/C ee}b>6"mՆ~f7V%bcrBn9K⥣iQϒy/5ep^|#;pw_| H&N<`Y FF a!ƨ܈,@ G6I4xLv3g g`S8S-3}_h`3hh4hJcHh:?]n.ME2Ժv3ZekF-F߰Id$mNt?S&Ɨԁ|)<8wYsQ$#d84Pp$7%xoBA0F|aQ4]Evp΅V%a": y,]Nj1KZ˜̛|'꼔OW^Ji+ ruMWJ(du5 #9+h4$Y..Zj>QeSr,^˝,Sj.Ow2|[DEEy|S42:9U.AŸX,6H%R22ycs}U\⫄*CJ2UKUΕw:.DB|Pg3։u)dnr5}hඐ-0`0FiϲѺѶ/;QW& 4SД{XcУ%T_>};!½Mu90ݘIRxs[ YwFn=Y36~SІ`ы wo-nqd3lD]vr=)e#bġ @5 DD4,[4`-$bZK=B6Z7<ѣG_ђ+6칻}q7Bb1v9`$bl"o7D8XsndREuPMM[%FDX22G#Ϝsvtv( L3XwVK7 ٛmN=xml߃ xWD$vPaIt9g, mvS6ĹeNb51S\.hi!9,p v?ֱy/sSoO_n>b=;^--o7fo_˻Ǜ`56z&2,.&<wf&M3gز3Owp|t0$|QGW]5m;rr WL$ݖ0v,q6MXB>K0pƅDGh47J<6!;L$RW6(RKf fHsAWvmS5ڨl@&9K2@cδe3U[!T + UJi8,Cƍon%Q!j0ml}FFƄSo9!Vmb;);4}P`ΒW%JkoY+^4j;koarJqAޗ r]L֐\vaߕd f@A Q-HvFXp YLV!:),NfL=\oLĩ ! Gˊ_nK}.`*zײ5HEٚ75A& `XtҺX N5Tow3=} ?U~8 I>lvȜAaB .ia( @2m!F'%,c3"^{iGC CJvy(,NM~=PԱ ×+L&U?909#A 6(lKQ)T7WVyP x{mn 81Y v!^I9z~O4\-Ӭ p^,fB+ 2TJKj Zo__І۸6ll1XZXHiJ؄np[ ~[{g/ߗmiizN;;51 ƏR?e;?=j.Vn_e ݋OQh[XN!$l X RJ׬NPY^z؝w>v/ԗmnkkT3LgO_l* g8٬ɖø($tezzB.gaّ1%f!;wølGI0N4άȝQ5{ƶu`N"W*Mgit4=v&e,Y֬,%+9+e.ԇ,) R榖JR벤R44eڼڲںZY:!u;,##5uټٲ)s8:'{䓽GCqW8y Ͽ#v勝>wn9A+p-~]wvD/|i wݶ}p~r_idžC+n1Ļia عo-bӜ8Mpd V ڦ񤄺O6O8H7:dZP84O>9yq eGᩄ)^#͌:QjK&͙LO5/>>%r0$ҠXXAw@Y 9HjȲ\/]+ݝ #b|4*Mx9ߤQSWÉ JF=w-`]IA>x8'w IŶcBs -gny97\+ œ 82v%#nɢ&k__l$[DG q0.aFVvxgxRY0漍ޜmLsRڑrY&L3LN3MA|Ϳdc\zat{oݹȽ~9Mhe 2 $^9lLVdI2cQ2pA6Lve$>ўyk)̧y(Kf`R F6;d]\pabt6ʼaҳ2Eos&99sY,\"g]j\t.w-w2rwqq[goL2uDݮ cp6拳\%bU^aWj!cH QcuO@_sFr=`.6:Y8 ~䧧GOR.i˨x[ېk gN 66mfi 8fl -m()9dzHw~QyNmZNݿT7پm&HH*4{ nӭ.䶤I~C败y% ʼnߔ~GfӤϩMJbwӉ1&3ԙ_H\bl#SrRfr,GK(b|Rd; Iԥi^0?uh=Bt/(zimd!}KX|h/~azwO?#g΍f{B«+dM]n51D$dOYKOXYr_р*. @Ak dO-9}]UUl/֩s7Ϩzv3w.}r]7_>][!wMug3Oe_=.'Ehd (¡ \0}`Co=C`?O?<8 Z|F8pV6!7rBVBnl1LN/&"DcAnz,fIԾhw.7ڎֱVGxrY$.췥sY4"ny\b[}\k4l6!vh2F! +/xYm(gp$Offqד-sPCsI _l^j).Ek*f_Zzzycsk{ q YhLRm-6zFO3mu~|c&"@CSSԁ\x}OgO]^Lg/Qr gΔi2v^.1d IhpdJ3:dsn_$۹d7cgگ_>(~CAj<4#Tz=<<¸Ǻkb~>t,Jg9;0Rt9&>BbyGkn2If(r&IfX NAeOo9ds9PsC#熠a9-v!j`:x y"bK=T!ұ}X%U Rq4IH$MXoEN7Ns9"seȺn9%RJjZZk+(R#:FFqfQauuwVwr3}{.u6. !e40N sXJCw%26cȣ)1ߑx D+6^ ^ B< --M8cFӊm`PbY0PUPIWdI6Y 4ݒW_۷GAp˿񇣃8X}ĵZ-nsq{6c}Q;ZB4&wC{gZ{hdHS!vN1T4f r$^;\@YL|;|/1|i}@VItbH=,5XD'ME>iCs aaVC=.9T*|%#E p5Vd#t:V'1N]F;Xߞ`bOO"" %YѾB Nc%5Z7^q'WP?o`zǟ5wZ){HMKS/)W_y+ "W<`ōVBjw $;͉!j1g>aߴ r]LeHCF Fv < /~ylSgQ"}#7m=TW>PN<=?u_,MyZQno6ik DnLCGXA:! rTXn~qIW7["ؾU9T˭`څ#zbDK ˠayڗT,νV>2Tͣ 4ɹw(.YnA7Y^*!-/ՓRzuR}ٔmo.iI^jOҋ`bsԟ~v|DR2<eZVnTTpy鴮AI"W%)tG_7) Tja_Zo&n7Z.d˿Q_&>ç _c>mۯ\2t+a2W,_g9{i)Tg؍zc]W.gX|m0\BP! H2"]9o0;gsP6paP jC@?r%_sBpφ ïU7 }s0Z i:[m_{z]^շҷ÷Q\@Bt蛦u<7Auxᘼ֏^P&<7mwm6=Yx\of8zۆbk":/1oSғz8sho<5"J1Vo< VWe޶Z2Ku 1%斨21KWŭhO3v5f+J5իT{=ál(VOilj*=aKkhmTBؘ֮pOkH}pOokK'itQ%힗}ٽpS9aJ ʴpXiwDlI +1^I3G\UZPT=pg}Oi$U{:[{`tK' k5wEá4 Pk@ÄHCnjUi:29^t@]ƒ,R{{#p3R|Z;(D6A4E)Y pwO$f`B@XkC_4p4!Rj QL[-( ٪/Dh}0P:Ìj&ޖ5t͜H9V@U')r2:-*.X0&"Jo$5Gq$%1jtΓZxUfhZSHЫRtkNm: PItF@/zHOd+сpS=,!5mg 6REAևBruԾ{P(hn饓7^:#O+iV1U@y1\!]J$UzX̤H. *)cB׎PR0tti5Q} JHbMQL#L_hRUZ{bk2_`q )}]!~%E$頖DGUtP]^ -vE߮X(;(RˊʊZbF\YZT\sJ@vYZFTVԮV*KŠʍExUUuqMRYWC_iŒEK0V)+-/l+/^  ֮(%f -T kK(+VVTWU"[QZQR hIeҥj0:JmuaQqyaa%\!ـ%PW5 ʔť5Ņt,ҊrʣEb pqY<.-_g,T/) ciuZ6x(c.)it el ~0@.S[Y];ͥ5PR] Ry J '^/v(:[' P44xSc;Ju[7n=2WZ /X,EÍ R Hsaԕ}D3oea3ǽX fYzМlP S{ZL>iCqr5=nT03Ik[:}y1UIY"}mޚ >jSvwKw(H׻A(R4ԈrʇVPbEAaT:QzKQφV!KAczSa`V>cJ3@WJ1 )0?ֳwWéa&4WW [;LUPʃ(P0o0.*0FLGL._}Gyf "Ru6kZq^IhEW8ͭ:ɸq" ٿ dƵOޅu*]LB N{[MMWawQ]­L+4ZuN`FuF52 ֡ &W Z$Gؽsu4ldPM?Mx+P˦G4=+t&(2]kQ6Wm0cP43ha69&R3I+5lC۝L1Yo/|1:sQd4ح:W'K멎qNö{LWi8E 1khb>K0YЦ+ KQ )Ca+>+[V5Z Y`Co܋qtYϴlT[f2ۡ(.?dJي1/R`1֌q|W1ĵFVD=1{J'柁 vb&yllU{5Ŭgbw~9 Y }3ʿψ[tܶ~]䵡4y-W䕗3WBLrf9d&'‹y79G~UJ~c*yRKRrD%l!?T6,) ~^|w*9G|"$<'Bl·Mp0<.oewMO$Gl£<}6/?N]W%>L' 'p0h/ {d  ;E}wYA 򻠵kyIaJgpIr6Ӆ{֑{݀;]S]' ^t\rܾf&B!aJvxrpkb#l f;GdD7*B%oQ!}SH&E^dCUؠn+-sN:v!m|6Xim9)yrl㛛҅u970 _"iԫn}P*YoHn!kTR*YyPIMTMy.Tm!vRQ\LdyB>,,%EJxR%%ea,.4 eR4 f4 c hYn$ K7YKd^SuN2AXl̺-R.z7ϓ|ɻ$I$Ou&'lGrS%!C3M!a>7@ 7C$kZUHbrI&2U1[u$-)ՐT$A>E$J(IA#> KrmTL d$|!5>ĩT╉> endobj 35 0 obj <> stream x]M0 xl®!eC?l'EjrȿyV!<0; sn>¥2+%^)㶄a8un0On7ӗr=|~y<#>S0kKvmj07%d뢨z0t[#scEz# 씥{ʁKƔy x~!odoo;g/mAF~+0+_ LJ/_._sҿT[ ),#K?j =1ē7I/5?KPZqZ_Wt/u賣 gGC]G1艣%1?e> endobj 37 0 obj <> stream xZ{p[Uz?wȏر ؎xNJd[D$Aɒk+K+tֻUfii@X`N LwtL98&Cٝo{9=ϹF<⎥&BشI$SD0Dj6?"DG[")/6-l%DN l}u|$O|nN1Y)/{Z9}OɨЌN Bj- LmL?`مϧ+ ^VN RCΑS$NxaA/aJmmiklkiKSB]G%yk4n#!{n\}:Gֵްgu[bԢ{k1GsޘTFɚ ߾l9pCLa/Jkj9m[{\m-i:qݞ?mG\oXs}*q/ĨNO= l='ٽp ^nfv:B[]pa鵭}a ܶ;5u-/ڈn+:ّ6oX:жf1ټjHY*0!uƊVIkUKfg g8iZV g'٭稡a:PKT3p(6m qE3 =}) C<ˠB3:5t'5Zd3S̠Qn2Ok+8Rdt`X,*rXkH(hԸ&00ɕ*; EԜjq,PիieOj2dLL=PEUX})9ĕO)9HՌDy6a0&J X8rD+b)KD,MV:1ӲbS, N sAKth;+v6N@̸Ĥ1̈i=Y3jb))-X%I(&M(J2~Au Wi> }ݲpzU6 BS` JlJ@ð3z\ybU¦TP0J#AOG:{}^sGCcQaO0z'xN;4E"4р߇s@`~ 4GQh4Y(/„N:Aꡣp?0Xx4 / a(h 4z8:)N {Ox! aI\ePD>e FƂ^O ~,lh@qRg3䋔02aNa='l~}QNGO8܁P0} '2*ȸA4ɉI=aA .'r0П,xAň]HŸ^'# %]c1-kmGJYk5L 5LJXY|:\ؖ헵n܍Nk J>tLftӺ %ʐDOC b6D\fB<8'0-K4#;UrZKͺ63$VZ3=Ԥ\E+׺gS$cl"-GI2@t|W%9$$ALBv#]x!8RP|?O⺁шBĉ~Az<$ŷ,?ixאgU/&QG*(eSR3d;4(7tuԫr"\K[<_7psl=hMz̻s q.)צVecT[0:ES/BWωq|*źYhiUV}}dRF_u+ͪ}f׽^5/i\M.1~Έeb Z2+&;=wC`xF]>_,l5ϩ=Wi*cEkݳgXQ*ArZbg~OYbvc]ުqQ#%O "A|bzB%<k~x |⬗Wz;ƃ8fCd˲d>3L6i?QC\E8e}q >aQK_vb!|Yk5*?XD6Oa?,V=(1N)6p #&@Df>tOB6 e#"a!(fC+Q0MQA2{ig-d!e6.Kq _Z84G(?3Q/-0Rʣ1n!55E@2\/75yG"ZRV岣a pчҌ~n%{+'6ގZ}"+G?(;Pug٥^9kǩ<<֑ycVP YuTa*ꮎS@ r}-wR߮޹+OSiYk+OV%tY?[{V U|Koanݨsu4JkK'Zӭ4|3^˲X*:_Z 1m2\iZeMq2a-g[qn[Šh?TIavt 9R|?+yu+$cs(DrUD~_O7Ǩ򓟋³8W}_% ?s5_»lU]a#6mo7|=C~^sZ{|wqH'8Q??+6+gWp^V7K= b^P; Mw:1| $?_o>,s#< mOw³Hl<떞Ag̼ n:ԃSxVNxdT+iO6s6KO7'9}-[:}ocGأcG1(zyE~dZ\)¡,0V a5@@=ܦ}_fyׂ.6wUN@< z<ղܫJ;[G`-y~f|nqK7ۡ例rpc m gCSݽnV~c+>ׯ]]^vCk]v׼s*\;ЈᖾпB]r#`޶`kt6;t [ZpKێ"@ߔ6-y^dMnic\l%_ (u.X_Q9)p8Rk+ERf5Ŀfp(q=4C)#}VE^债{9O I;R9 ێ?FB endstream endobj 38 0 obj 5176 endobj 39 0 obj <> endobj 40 0 obj <> stream x]Pn -/ 싒B:]bEvb@k\H)@3ڙK9+yc:C4€uXzV%ܹ7 oiDp6~_ Y7'ޯ!|.`R1> endobj 42 0 obj <> stream x{ |U:U~TΣ $$$!"1$HHB0Qt $& &(*cḚ Qa|p]qg]yɰ3cMSI'3Mש$ȀFFP !Bc(.;vh~tE7= snMty;B'u֓_ N5 ﳺ[[;C{#!?>C#"!_AⷠW^Aƣ=[{7B01! TwsJ,X6JKwgdfe{D?+g?6 3F@QuL;}h=9s:t#=y0wlvfᓇP%C'c(AݰOaTx1] 8ED X;Q@eg?V[>fFbzvgTvsf$l;[!(7K. 8z0]?M::ZLLztTYhۅ<TpeRe1[W_xu2m9E`/" /{xwٳ<ĜHS,gϏ$O҈miS _?Uّx!OhcaԄV%f.T+㗈|?="z>Iϴ^Wp:*o6SL]]ԯ2w<('yu$_ &$ARO[KpȚ VjE8Woyw>wgw;+C*vHSÚ•cϏ b ՞piҘ%ŵx>W-~ M5nz^ zޤBm'2Į5iTƐdh]461fr s̴o658P[e 1ZzO#IkdfL&b~r+u~]"13}K|4}ԙ,U=oDv=ݡG=[F}8 Yhۯ{$GF(0 hT#x-Ị\t_pAl&~65~J|Ҷ;-3hsb[m_pylq T,-;ʝsu"gk0l6 =wا'fI) *41_S2Y>+wlm=Z=W7vO%v57<*߱O}?7rm3r|Ѽ,B|(ǛfѼc~t+ t 9.]VY%+PPWf$Q`dGNeIٴIQ( DĤ/Lol{xy/IK5C#|fߜ)mk; Ā6 K;g#Q{})`*1>Re (`l\Fr )"O+ 1txqd}O-}=G%_I U<@{^98p7{M;2]r7j 'A,IW(~2?'xa[ᇼ=f-[uq$}uǖ-ĨRVwXe_~[K>AmY ix!dP9ҬfHkk1e}nD串кr4dD3F2@JXƴgq㟘҇.ѻQrJodN<෾G}Of\:AF9fܨ=&-00w.'%6! hHCiJQ~{p:n]89طX{18ϑ>,( .a}GMKko9cW?!`V,iYN *5uF s#풚gLyFjZa%S,NK?^N'ǙyB~SWC!ޗgy%-& 5E5Ke6a= _S8W%;Aބw K_|=0OR1߾o״Z@>W7J0]=}x--foll^3v۴px9f{ړVc,I4~* x`3$ŴDvAF&5%OE ]̓/,f3{ҚRr6[:bwmb߶ ) 3,Hp^sX8μS0L5D(3=uDΝ':k]fu9.;FӭYi.f2k!Kܚbے\QI&\l~y)oԘ 0dDҸtQ v̱Kl%2WYZYz,,::d_6=lw8!xZђiQꃍ>l]/[Vѐ+H blx1vg̪wp%P<LZw6B,aI?u{-Vgf^v~E褺t@ +僙].WW^! r]'jD,bqz6D3Io Jץ7Sly#R'Iy+t=f"JH)pNIkj߀hs0?KfSo< 2bT& sEx5+yE,4KA,AS3|8RWNx'5ټd(oG&+zFTuV$.?y ?rVΪG*VD.5^__[W(%r-[[q}}͈vD7׷J&a7.3(b. cu ,ǠYGo'w9;m>Ҹ֊46ǂYY6d/'_J'+ȉ]2'`^Uʣr\c)ד+zs}R]Pj,5zJRoߢkѷZ-Om767676y6|'t'' ''L'<'t_3f|55kЗogMCYx;SFw7q`8e= Ǒdegո"l,^6?A?0鏥̹ġ҇$ǁtfG"`m-89$V;U7AOr3Gè]s#cV%Td WC-;I)pk \Ȣp! e%5_;_OY H[_-G5+V0zN>zЯ>Z3Zjc;v'^?G~pνE'ͫ[^бHÕ ee x@5{c*m|o)m<̿UHԏ)m  J[J JhmV&y@i (Ҷ hZ&z6t܎<10~؞cp@(+z{F2+&6cၡpg21vPo@X=bg/ӟZL}ٱ6<@J%NGVǹMc>hJ?0+en RC}ԞI[Oo V|rѼ#Rr<ȴ{NKԜmtң3nJ-T}h9_0c'&{ Q|rN*Y2iw'GᴔFg*#43L 5Mi˙ǕhM)u"9X}2o'}MֆC_c1b>- y֭"Q4M}Z$}4zh,'3=d=G3^_dY_@%D%%ꤜ{hc#t+})94DG32i6_fZ<(vz&((LF7d̬"a%߅Y` ].&垹OV]_ɱS;δӸ:CC0s V~%XfT<}tL/gL1L=EZ9Y5|-)K6fc IQ( z'1Ȁb:(MA\ng뫥jWb$ŮIM@UtzTodzxkF7lc5'kV .th4 mBdMhB-w- =ZHiZxV)ȊeгI{9"hTޯV5!/2?tjIV[#_VJ_@5Eu|V+VPʄ2ਖ5lyMTTf:*C5˲TQdK-gMf,)dfefSIד]W^zʤ=EPѥɝLmStRX5Gk|TtthvrfcUQ}+NT#Mה$ImuSj&c̯ʺLѭLS{'jSH,vR|nr-P|/Kٔ.u=/kfUtVuӤiR8_aI;Q~MQr_;dZɽ[SaӤ6<]9wUA]dޞ^S*Mş)6 Yx97cT5uIpת\So}ȹ[>Ne,D%rL"-tt˧>:#ʒ *+fҒe[ 5^e mdBT;ff 9P{G3U0 Of'sx֋Y'[|܂pOce$|,WV|,xSS>O'N$m#oÏZDzc/_=| =GtЃC~xk}Av|߷W{uxO}v~n{Nxwe]]6<2lG$> endobj 45 0 obj <> stream x]n0E|"W#!<,P~IT 2d m.gxqw>Ѥ.mդtmmjzW_wt'EqrwX75Z{UɯOa줢,UCS5> endobj 47 0 obj <> endobj 48 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <>/Contents 5 0 R>> endobj 7 0 obj <>/Contents 8 0 R>> endobj 10 0 obj <>/Contents 11 0 R>> endobj 13 0 obj <>/Contents 14 0 R>> endobj 16 0 obj <> endobj 49 0 obj <> endobj 50 0 obj < /Producer /CreationDate(D:20081215111145-05'00')>> endobj xref 0 51 0000000000 65535 f 0000083869 00000 n 0000000019 00000 n 0000002017 00000 n 0000084013 00000 n 0000002038 00000 n 0000003767 00000 n 0000084157 00000 n 0000003788 00000 n 0000005294 00000 n 0000084301 00000 n 0000005315 00000 n 0000007104 00000 n 0000084447 00000 n 0000007126 00000 n 0000007561 00000 n 0000084593 00000 n 0000007582 00000 n 0000031403 00000 n 0000031426 00000 n 0000031621 00000 n 0000032189 00000 n 0000032599 00000 n 0000047706 00000 n 0000047729 00000 n 0000047929 00000 n 0000048302 00000 n 0000048541 00000 n 0000049202 00000 n 0000049223 00000 n 0000049414 00000 n 0000049706 00000 n 0000049867 00000 n 0000064288 00000 n 0000064311 00000 n 0000064505 00000 n 0000065065 00000 n 0000065470 00000 n 0000070733 00000 n 0000070755 00000 n 0000070959 00000 n 0000071264 00000 n 0000071441 00000 n 0000082718 00000 n 0000082741 00000 n 0000082940 00000 n 0000083408 00000 n 0000083731 00000 n 0000083814 00000 n 0000084719 00000 n 0000084817 00000 n trailer < <8F045A6BAB361C4C171EBF99AAE8AECB> ] /DocChecksum /91350C4023DA5A616AF5292B79205F27 >> startxref 85004 %%EOF kst-2.0.3/devel-docs/Kst2Specs/Zoom Modes.pdf000644 001750 001750 00000355322 11544160206 021217 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream xZM# y 0 خ!a!@$T*wx."rpO# }NK?~:/?!|L o=x/g<;>ݟ]p=^pn/ׯ}~~?8ǘff_x)}KywzS /zAoq񻻺/L2}Q.@핑q౽>؋'ސY<8,*x'ZܝW5$Ȩ!h {8w2xe|f}f,4cՍpc85o=I+Zٲ*D)0 C w3]ܣ~^kqMք쀴rLmuSSyY5@Ji'OqGM"*ƠN ٤u m_y9lg.VcC' zG|%(sC0UP!lV@k68meIRIL6Eh#%ɜ8LGf|lq1 UXg-]#Rϕg(^i$ f g Y dg-8*)9j4XiLiK&o2oAHW8d |ϒ"L??u$Cf=HMHIzh$F2rNOf/gv>I ZIj<%!8H8, +$e^cFTV*Ҕ)ta*1KYҭzCU0j [ҭS'9&WvB*_[b:9K+{D)HSAt?&fuCKY CUeC"RQQgV)!Pt= 44]o䲤 ҜEo XCj  FEoڒÕkn0R7Do=,D#4-QqaGdZJhz@M*d3iY%NW8F؋;Id'> r݉% ,u_Wkݘpkڑ[׉WllD*(r%.G҃KyQͅ5 ٴFN>j" s-Wd-2^ZrԼbbi&̴muI~B>=BŴ'k|O-0 gpeqK>iˁ%p{aq0fT2o5㒪PtHUC3# 5b3I&bJh孨@+υފfReDCrJ5A|V`EX6nhTƣr٦{"sSֽ2~ӏʺC5DvSdmoZ9 =Tj;*=ef6;vwR%^jaVmVu6u 7|VpV uI3*qrCdB)Sw%9rB.9έny\ˑcX~B!jf1 G{ΰZ$'Cza9d}=u=Ӣ7oP;˥-jt2t܉&)A>c9̾u^==#+(ۚR7&j =_/gۼJv'd{G{mes 'ĩ]YG9E<7[ }M%pz>6;gƹ`B;'YyZvĠ(YC׃oxX%oʻ꾧7H(!k>5䇙P4V}%`? %,ϩ.f[%w>R>4,˦EzsDB:>6z-)dRt驴$=Qðz:tY8jajrZFk{m _Iz<ˤ 9uϻ2q+Q7WXw^y8=w?J=ՙD-=_;w?JzT Or">{ZTz  -߮)Uj=H`Q쓥,s1_rlQꢑ!?107%,EA`7k:0G.l{ɦʥԠoqx<mwq7dpS9mO`M]ؾf8x{R6\E2c1wXDl &_ZviCư)f*5U#z* Ч~g&*$fӵ{NFyi)t|ɞKwG9ٞ}i/ncOp֍ endstream endobj 3 0 obj 2634 endobj 5 0 obj <> stream x[K$RHTBPσo > {}Gޯ̬Y0f,=E ?~?ӻ|z?vIf{Ac"U}> -)~鶾36Z8vwi܁ -ﮣ·j}s$4JSH3U-v]H&Vv}[؉&]~DZPY |eQ(jN78^0@Q Ɣj.aP88h,1#pS^=IMJyc!%}C-i4jSY'- WY;3O޺nYL;zLE|LIW~}TbUgXNM&SşA>Duبj0H-H zgt”Z3߱ݣ@Fɏ#ZGv' حHvqBQϋv:#޲<()Œ*䋶dπ곘+y]#&6?0zx[ UK+>cO[E5$ ˈmzU*&7\ZFBhMA\k>NVRAxB}QINގX%ugLGnFMJa gˁw&,{x`5a;HPZxh"\9C%&, qB.\}G药Y>#q{mm@F.i3E7~()ޮ?dM1 ;d=}-T`y;> n=4 1QFCu;n1}ϰ \=r|Dy >ʿ:%Z<;]g=T`EN+ Z>-(?YLlş㷘[͙ޘ׍O(¯ iB~P4pi>XNAcTc1u5&(L*3!L2b< f&E:Lf~&doA!L /Af |xJf5dCeč\SL]goܱ{v} R Hv N,m!} SUBz>u wQ$<|M(N9Y$5?V 鸪҄#f*8TCL?+<ѷ 6b.{ez b@5\D.!e1^$!ـ .lp^8˺ ٲGAT8\:gLSKU#5hA;-3qC ]yaëZ営fMwiqaw$I6G((SȎc0؂4'%b5%UpIpK=f GaJe_N>z>2RjZpw2H8C)&2- 7;C; +In:󎏳9aST3O'! ^>LQf=* (y^G?DOOYՇY3rCQ v~zS]/ax9#m/݃*K,Ԓ-r;NFuEԸ}SY8+.U ]̆jfrN9%WdUTێ`5x&/RHQMҫVd-+,8<R%vx'qv4_EnqXXɫ(;$uP,Է'-h+iS|y'ے.3%WOL.ҥɦ%n@CQ=dP`aL>l]ŗ*C=m;-iF:ְem"A?i0/]ԶTlPF(׸F :t_A}VS3ΛuH ث [LFAvw#Ԗ;ʫ /]Q3 dC.C_ *3zn`c ӎ%(*ݲ,GJ IѶe'8Wd'{+E8-UH&=an1DEMsM8ziG2"cOpeXT3UG-.'"zgpYFvݨxt%k5`@0!:{w C4{u:xY:|^OidddtkJZ^JM=>p5]U(^^598*a.eε-]ڂۈڥIA$ ;Xvov"L&.vM^BljDQzK]6ݐn`(Tؗj4YM 5]l7d)9QZel Dl(y^,ԉpo=L9 ~߶V1[`NZ)@U9 #!J [EDoKr.Jُ*r9zį~ > stream x[K$ϯ =MBwe ދ# )2gJGD|_Tnϛ|9şJ?폿#~H~۷ff0Ϸ?m}뛁߿}~a70of^7[o̼5qwg#fivoV,U^pk,8z{r4;{va{Y7k6Ȅ=|nAI>-n{mGpMki; Z&=NOt\ ןxst2|G ҢzZp/?p"xgYFrfҽ{Q"|,D8tɭ>,P4!4'=%4]4-(1ƃ.d? h:"C# l3(#vU`_rpCf.my(f>^BV( mbDaH̞-lcPl@z|Yu0{| q u-Z=u9j.K` 7f&g|#nt%4K8嵂 % %g<mt sA&Q0[ p=ˬ)L&&D< !aKsyR@" 0~ I c3/gqv+0_ꍂƔ/&P@\Btceʈn#ʬ9fKfİ8#{\Pvp;,)yQbe++łR+&˞52iHɮ$hqh1nŘcq'7Q*ee:KQT W;6.9XVtl83-̢Gکv|pSx<DeFtKTXEUTX\׭by$7c8)yЅN^;Vu~2M$ͥ*K e`Y~(xiҷ+]+!Q&۱F4:;4s`r> HZgMݑ\];z^m'1_sF4!F@wNJ: C;1^ʆCK!fJD|TZ\hR.گ+  Sԑ.™{"~0zZ4 fRt#'2TP1rze"P5zwwUcG;;*ҹMqLJ_M`uIQTIPU}r{wed ϒ24Ipb$ p KWK~`F z?SgGB! wIxKdL$WjR"U*:mlId5x cмC,p3Fe0LP)7 v~(`ίV.j:PdUZI,i=~De3T"(2 }Y.UEo{v34|sQ|5ybr|H@rmiaJ8]jz֤;AUD>w9$Hvk>ƱJowi&xI*X\pD\˯B^SI\"YyWx@*Ec3f;E' @S8TBB/S,NgPr*I+Z%|ЋfmQs-i\A6g!G]~ܹ1,\3[HqaV;y*![ u+Q'XOjl0 ( 掛t +lvmpy jmtayugb,@6R471!CAr:Q`4s:5j `'M 5йj;L^i\-ZMBFg^ )`ع@sa%qgdׯpS=Ϝ{(OKqwgI1mc-`dm"p%\XV=>+ :_̔/ c׮9%M;yܸ]3OW.KY/ѭvRR *0FEZ{7!߮:a7}K^i\7j컨@תQ4]Vh;TUWk( ȗNan;N*˒u.UFX3xN ڕk5mkwx++U:oʢ}9K=^ .fN%&wi;8\ȍgoZ:L6!\ڢQ-u륊# *6lf9+:z(Wq {gqzq @4iά9XG9Hc.4 6qu( }5ДJs;aqԧ|pM)?Պ$VP/0-['kAFCYBj_T[kJ'B*sR/qoKDD^SYʢZZz?;*Hz)h~->mW'"Ie{xUF\$1bPT7K/R^(u!MT ~)vVA%xO5*:o99.{PZhqIb=rBEۦQ. \TgllsS1ZwlF:{*jx銕]kNmX阝2J^!Ս&d y" w'9H0dɱХzQpVu.H;^vi7܊V@T ]y&| F:iϵ0}ɣtGp%qG0aTRsSi:_b:3Mr|Lp<|oYoU/O;P\j Kmm$Y_prNckR<[H r knMN1 j۶YUT@vRq"#(* R9^t*$E.˽̛urHU*T/Uxzi?vAz1ͧL$V$HȩŗlH bV {=K 2^_o^_6T4w{88~!C%*9'F߄=i3Rٗ|{\nL endstream endobj 9 0 obj 3511 endobj 11 0 obj <> stream xWK0 ϯ\i$BځCoFJK~;j$ğ5Pc lеr;ѧPƑk*4`o:xMcҀ ;s֤-1vR!,5mЁϡ+\FyHJ_ѥ"O`$6٘%@WyNչhCeyҗQr+"›iK`xA0)p^f.L8{ _ҩk/-[ ]VV:9 v2Ҋg3fϨ&6lTd%ABơ41B&݄7C z0lPuC* œ/m`uO/@osg?;(䜑Ck5%9!|o(e!y$Q,%<lx@n0o wWrG~!5!?b)p\ldZXFbm˲L3B~*ڥg'՗\&-9Qsr|W;.:fQ鵉[܈2̡j :+R|n9LaiR'I\aXɰ'I +hѡ'.# -J*[6mu\lPL>A.NJ Rl(5|fw]ފx;Ԛebmq.`Jט\耴8|f\^9L@>Qǝ|$[#&|L#Fv+ 7(CH.<]zw+U JAnv宲UHMc1mLlzɨ9,Yiqz/jtnz8X -$i,k>t_P7jCIɿ* ưo6Rܳ |HsjbX=ϳ?z:0䨕/> stream xԼy|չ7~,35,ݒ%ْlqq$!Y 6k(iLJ\8e+YNR)ҖtBo[M)\pZnb} 4y2˙s<9@z4h$fMˆsB?Ap[fHB;qekmEHmk7lze=N6^fU=  [9A>nj6i Ӻy˺5p!57?!lf5\Th ݈ :Q8M{oh.^ t6 K5x o{xߥTߠTt-ɎZ6|z^xߧ؆ømSj۷7;=y©Gsӻ\6z腿`;!Pi#-:G7Kn.>5g ,v}[SRm y@F]@YT s%pо~-V r/ڇ~ BC 6o_\^~?%U [F@>$6!2ain)\ϭUTT **>ƾreT>PT\'7_y)՛ZDIxZJo^ EoBނS/RW4~ucKq~B7R*E1 DRCvQ-~}9Szz.ڍ,{m~ {u.{NPPoZ ݉*1Pz2=׃oIq|JaHKm; ;U ?߆n̬ eHL3H>a[z (W!ruj5Ul"J'eh$ J[qDnMo4uZS MahIc1&?k`%}c|1O9M2y?)ϔ/Օ'4Ӧ4W.WؤnW#Ji.1'5ܰqWs_NhB[@:H 59XIPRQc@Sh"-Ck֏u.jnr1ܸ.v qԨ~1zM7y)ms|ynnnMjvnHv׮ailKk B-}ZwC-YԎ1( T|+ͤ*iLظ>׮1tVAK>:} ]Kzw{Ml!Q/֔'b03 디r:I]v_1iQ`ØNtjk] n W4i%B@cCB@ L~Œ53% "I% /2 \#(qϕ'nuB߮MAdxwh-dƆwZ>T{#5jlHЅ+ֈmL vK1lT_Qo[h[Kj7ӷmK+\IbtZֻle)?6h7qEbrʭW_3tɽJX)R˘7xO!W)fi6/<.̄+w~ծ]-eW߮5Ckuv7]cc-wwKlĵذe̡>N}p#Gt84r$b19cb#*~8~^"cu+>: o__'G3S &s08&?FZF=g Mʪ)aw3?5hF‘p [H=ߗuB!inA+%SKNH5\W\RSm):ZC UH7ӛ۽Q{<}>JG<*]ryȆל(yW2Ik+l;ݚn'W_jԇ_d^Bs:33>=!ͺ >ILό0cX/CSFocҍxXtI|/"= 鉚Ʈ!] \e+?>t_&QddEq\K!c yڐ*lKv ,An6CB" 8pVNgdxT/R1:0:,-29"K$KC'@b,[{N^ޤޣB)w uc~nr3iO0^S=uS&やSnX`0&1! @Uq0aAVVUU?DzKG!G]൛W0[8sCG_Ȇ |pF(il$tks>׫JCDϐYO00J dC+1lk~@@At5rAb01/5.Ô 3a)6-`A@/cy_{}s T\.q{ݴCStϘ"ʵ[!ZV,"Q LndJ)"Z jF5|ZneߣV۔w\0 G/|p5\^RxFKgC5@KH78a5>Hk0W1gЛe/:L/M:#ԃ,*Eǭ(a@qZQV5wÞ³=ƪT\ۻyRu`Ǿ}?^KQ%{M{ŗl/Dnt}Wk 38i)hLV>L8vL9uߴg VOn,'$TX U0f6h! F2f,}gw%$#zh4$T (|6Hp 2.)2v&c]e_c^.esbѵ2먍~+/[Ne9mMl>ćjFj5t\;kjI\%35Ӽl*-y#ژWh c8m\$ِ暰B$ppd31-QZF;N(ʑ?w3C#r|d9SWvf:nHAJ>iVgg (0.Va+z0vq% ([;GYQfΌ!zT oaQbԦ\}M銫ZmB\{ܼ|VHNO0 pI_0h,gcK\Zk =jEsGC}ַiV)/8D/&DZK69n‚KrQ.R)h'fs0`1|D!%Se`8WD9NV{2먟16?}|??8ňKLXHd(BKtҁ }r€Sզji IEB= " O D*m0tVA7lLƍۄN$||vg,̳ŴT'IIL~V^⢬+|'4E֜>>52=xBqRaÈm5-}00Z'@4]* N<|$tļ&*汬S|" .jI(J(&zD`BPEH@X x/s^< 0\sFy8ӂc 78# Ӥ_S} :P攍"TL{.MqNR#[K{x6T k+1^}PơG:Rܢj*9 =ˆcqA;o*gea}UˎNG1'rk-1*F Ɇ"4gnCʎq#}3zV~[31/ύg0ʗB}}e9]Q6kX^S #zi4[P9NE)hټyix2ۗ &RJQ(e/ŗKp|Kj>4CvgSb*%0/jL6.o! ?b݂ x]B8#s: c3pr! %}5=h!U^]%iJRĨ~8`k/9]q6u3IUݺTWͫ6>yq=0|~ks?f'1*V!:zOÆ ,70w̓jnk#mG)>v!v?K9z~ÈØF Ґ04pu9C_tq>XIQQu\Xvi$:uzr>/aQ[yz""?D gޏ>xYK:Wv>:SfĖ5U\.J}z??{Pm-JOOE~[yV&IU+kK]U"-$=˕ٱƖVW@S$s)V֚ΜXjU/4i&꽚ov>V?Mb>=|A<:(}S9W*4^QXUh$R@L eѓKoAxgonewjjYm֙wtty8^ rK^d֚;%JNQLkVFv5uUF bԃT.Q%Wm#_iY6YAV4؍$欆[,Q!/sH34#B)*-EޒZUr/quM:,: C,"fN%X4KDqRZn @5AӧshZK^-]q X",XG8T 1H4YkS8+G}JPX *PSbP1y[fRFMB>ěg5YWo,٤}}ѰfviVWX4A*s=ϼQQIҵν1qzvx:MڝC!̓UxIIG=D|DA=oA=;FG4҃.(Y("9X]A*()ܹ\1ۆ{ mBeߡeܑ幫RP0cܒr0ҥ.O8z>\enX.}CY՟suBe MAY\.VVAe~,hBJѿH#}3AV v)B*HE)TN3浴b^sk$I/-#*#T,fYioъV !D8͎8q9#}3Ny0p 8Vl`z&0ꗬ3.Y±Yf}Eh(46&JGC*fSGx I,/s06'92ҹ\_?7c,+!ȍTc9j,`"G1/_tb`k:5Jb@Z)kH{+<(P\ sZ=ȍ~M5&F;) b>p=hbTLq~teii*'0Y݃m n{޶͒ݨ[e3ZtF2 -,|my-+|a;n+KKR@t0:~|a5זgQ faKy,K%R67ChCt Tyxs72c18ߦO{S:*ռ¼۷[ p& " vT) X?䧐_KN?OOO +K1#;E%Z5|Iħ=zJPɨ4&)!ε]T kehcA%*YŪKR_+.j O L P|<^?991Zq:'q9bɳd y !? S]Xg֬k D,zG?w+&] 0gŏ\:W?zlNm7kV"LO;a+ljEٕKYMmh[N[;*1kzFY.T5Kͥ k%jPܦ][kn]0{nn:~v;ﭧKʳIpM^v~mNw)}zZR zF_$;-N:_ Xyt\G%r<K ]rPƠgx؂!x՘G!_h(4bЙ5¡T# ×LulK\'7p\Ƌ$d\ W$d٩=\4&-yEJXKuMU ҨjJ/J)UNAf 3xpi`uV¹@9¡VU!|C@b xYYqI ɲNcz3&&"A+Ւ 9bWKF‡rJtysZ(ZZF=!j%^g/2h53ހy_ V7+ԇT*J޼hǬuVeE-~0Ѵfטۮjhiyp略de|H77恦:1їKfm0 f|`xoʅU e7,P*lWwR}}f{ܮ97i~νQmN:*Keʷ}JZUFvFbqŪQC*X:Bth?&C~lD|S g)VJ"&ZIPk[j8Ω6qB֋ڔ;!_~THC:Ҫ8q1^Hߧ "p̣v:-;4ޒޓM\>I-KC(v8\=QNDOFҪ*y>v9îgW<Ђ[*$;7_z\_;iƈh1e =WқV:oŤ=Fm8ʴ<-AㆬW'kSpv4Ld<;C "y2ug:.v\7m<%'fáʊLEV5;PYxyh{fy=-.^Bz,oK%le|EINwB +Z%֚F t΃{Вb 5;=8??\eEnU~xGYWfMk7'?s<TEąe9mQ&0lUŸ ªKs-]}7*7֜xi^O{6gU{yGΔz|&_"9RZvfeUg-v:Eyl6Vqb8fr!{ʄM9dThK`{ J&bL'α,9. Ys3zk& HHդ䲰SK\u%REjl2/`ARh-vlO0D,9r8&ψ ) b8U2P^]^KTQ=\xO|`,:S.ɒ,DV®OИ}$ct:MzDP-CS uƺaP BNOp@PJ]{ @J nAm^7>4@zHp [wR*[z *%r(OvIImk1-_Ivx<vrS7Bq_XxV~f<윥(H|6QJ'ʾ:7ta\UXBghzSyy᭠;r⻭g<gPq:$OƷVp8P k-qjNY><򘑿E< yaJibLYYmULW%Uo5mMܡ~PƐՕn2,Rј"ż❥@Gċ(s哰ᴝOKvx=o%2WwqB3|)"1ET$"?"e[2 hXudQY*.Sש"E&zʩc[å/.7W-,29\䚇QvJkE'?U+/RXtɤӄ,i^]6bP\]}xxt'4:l̈́w,Df[ f@J6+טՌeF gqu`zCEU';mq-e{IC BKr%zu4ciQ F)#b6mЫ^iLidD 5GN89 Ivp  r;:C)x+h?{zi l6F]=cb-~ !p [*X8}RրpP>2@I.hӿbV|5Ir98m$$y%|MLz۰պP}_FSE?21PZU !m #f $~09MZt}NN_\L3 Ǘ[[#;#*UJ8[TJwYDmGrH0J-XN/]JoW3}Ze!<#:T6-/}䭒SiijҘs R_XrP4F>(q{a "b(ΰ#( ;YRYyNR֧͆ Д#JHSJEB ⮩:s&8ܚ03 KDT󸃁,,8 zp "g} !y4@*`eUZ]j%؀ 5UJ}rp,15^j&oc6vcm]IU0\fj6_Y(qU2 6˓H0>yK=9{D$S("%{4CFGTON8h)edl}U(!h%D8^xZVG:B-P Dڣ!a]ѻbCɇɡKBE =!MЄ&B[,SG˹S+tWx(M7Qh4jPH ł+X‹xDHm %5pXEa(BZcU5NS!V ih[-NZaDr2e- 'I"%0U(2`T'u@W$&S"'7DZ7rc B+Z>:9ATo0lǰ疵pit" 1)&b1.W~˘I/&N"@kR8KK%(zaU,Cw//-[Y,.k&s`דpb⩶_w\B9ȇ}.2rV2/dC9ΈﵪOlE )cz|s"vmo\d!æQ ^"Č^kWʒޫ%W{)iI7GoQ- qjBhp`y]'ڏ4NE_PkJv_ܫj}^{";5qHZC,` A#Yi|VMA5WdTuusl (_;IsTy, K_r;RS/h +K^xhټAhFރY4)Ju݈a#}CZm^̻z^SoŴ;飆4__?>'M1ԯH~P{=NQe©| 8 _&,>W4hC:4vW5Ssy[ .} 5TKe[XjZjQ|I׷bS&">WLƼHx䳮H*jyP ,|V S((,!'D(^+N-XqB':V/N.SgOUjcԉ._$ R()$ǒɓI3#I*W7/ !~Mar0Hza^}n>(bA$,Ve+@=@$kƪD G0YT,0^g|7Vž(@=Kd(uĝ2qD!"_6)D3\Y(O:篡;>lիa|e4|tPSh ?B%`Fe+3a|[MfZBIn_`, P8]I/s_1`al2sZ\Fhb[;4G&fHYYc~˝ܐ Kh7Xyp K*ҁXZ .j-FP| -V0 4b¨QRzK*% Ee?(x~n",1U'?iPJ.b`*" |])1Tbhg/,,ڼ&c {؅TϪ {C۩ɡ?0,{5VȢ&_5h3QcҘjq|NWuU5Z:u7~_?S}n0l?<̆!kȕdJ%NQ|XyfC3i1MٹeKu +Q/Z\*.uuWάήέZYmuEtRXvl-F^oˌLXUO!VЁUC=eoic_Bzτ%~{&4N { $~)tNrrM()% Yp Y&"N Sbz%U]UU0Ya]BA1>A 4d P1V22HReV/| ޲4hu+ uq jBjuׁǤ|⺧oBf\^BLa)㥊p0|il*lw|mެ. \]oH__x6oqZB|xɴm?Z++LxpKeN\L 8_nqȻJ,e5p׽{GуtX6:. LNk!o@0Oʫx-ů9*G| r\}.Yn6x?'F7ZWx2nDEb rJA+xRcb)\,vyM!%kup<ʷ n~彊 l 1]0l]Go?^+w>+̛mn煹PnpVLV&//<&j7aa$Z)+y~<| W w==\ygku鬵eDq w=K>\~owD|)`eޙ:Cw-fC!&Ob-Я+=C1G]X%8|u?h詒ƧKUd%'㴋y oI4e[9;S7 3z3% DY17BB1g$Z:XDh"󷟍O ='HgfBs9ȗ<σF7 V S %AK?Fuu񲺺ܦ5~gyT,^W_鹁@[Z5إVT+0=e4Qڇ4&`gC֥+594ȇ H8s-^1(ˏ5Jx^=-˒eKӺz˖mɖ| 0ybٖXF &!v'$)Iȫ$ Đ4vۦi!Me4l3slClw9wsΙ3g<*ygEWr|?{x:uy|2) gB%@QA%7wab\ >:e9d+9^{HhMγ~;L6,q$N.\Y:3#fOmV-3w@:` ,w%VstR^5ӊܶ;cE./ظr䁻>%OsrQ_Śk@(=9r?WL]Y,ŝz+9*;~T{sht3)X1+Œ]%i%i%.ys|*_傏+aF-O2 G@\9zۇ0 /.S{9z+Lg!#i]'xxoSz`2t..: 4/L 9v6** pj+[aNAm\X3ksg zcLtR;kdWca:\.nݭ.#CM65ߵ$dt!gI1]z' v/ "w(nx_}{{Oq\]g^Xxs%ߝXh1L0O/ qڬ1Ӳ}⌾B/-|P2&-oM4f́ߤf f'u~s;?8b8l>f}*pBǁ7\ s O¿7끬da"#/W[\;2VrYł @1݇6N{[7;'LejS\?0Hک81Hgtr9^\ec)t+hxXF<蹧 V nX.g˧K*m/pOpwڼe:k=w={R׆ǣUU{aYSAt㺚s\z!o@^̈[F1w73ww!7|}3`z%?\Pqͯ^I'Nh 0(˔[Z»`Yl݋=Ϳ?w~#G]e29;6zxio?ExzzP24#V+7sDư9M;s|usuIdmА,aNXroVsG|#cU[Dv#VRv7̫,ENYҐ10E~#`iTQg!qF'jJĢ%f+N YZI^YPLe:^rH ΃3KsN@U'ȁ"t *h mM;bw\h d*>; %GPOsRY,uXn,Lu{O7T9(/cW7̖0qHZF3rKز0m%`$p<Gm3!9 QwJ_GvHDg=K"o;5^ɱVu?pԍU_wKg;N 6Xgr^[ZO+(nF.G bGw4}E"% 0/ͯ_PYT۵kY+eߡ}0!,?L0fm\0ߙ29rEp8LvF1 40iu.uR]=d-UsQ7XH97ԒdI,RDs5z'ۛf=XL:l2K!# 6m _jNڲ\z,r)Jx`%87;ǿ3=ˑu1p$ؾg~[Mx|`9›2<]dUr]1*]eB,N\ ʲred + ( TtߜgeURbyjEAAњ!}yCW)S{,[C!ِ|(m;,;m{w .!սY2?hœ'UOXZ=O(M4?~#G˶=hxRRiˍ %QyTѣd+AIe},oVlT9JcU*!oͳ˫TJժP*ӬV-7Wd؂^YLΗ+-UW&,4nJ)\Jh\eZy{X)P0; rb cqWUJKS(ydˊE0T*-W6o.n+/+SVZe9eVe8d*r^t6y mC1i1j>֟+q9,CRq(v͹]̨!KrA `cz \bq!d9>wBxZ\\X'>]e sӷ4cyCcYeVfuɔhݕX;_-uz97$]7瀖 9]7Oə;_(fu xG7r NcW1B9hI4=M]tx$'jx=+K؃0s*Œ9pջs:ȕ` u ˎ tMe- ƈ3"'äk4\7cǸ58l|? {}Zmi9В[n,-5 24PFld4!l2;ό91Pɔ( B!_,r¬pq/%,Nx^L_yf6USYF3}E:e(EN,AK[e4fnHa$ܯʩ +'( ڝ) y1w d94'0zE.f7p"&Kgī%.ҹ Oo?wM_|nę=qݛdU-WOٛڷH##2C%_0^ Ҥ%M1~FkԚ/o+ߡ0v33Lk,/27-yJr\ޮ:W.S-?;uvwW)@mN%~f>5)$dڴf/x^Pֹ'wP#ϬR)k/ϗ;G<ٵ@Z!Rr'+*OFmK(_ pl&]pqdnKk}WZ-:zR!\-/LOݱmG﮳׭fԦU_yh]?Z>ʲ@C ?4}~UzK=[# /}w1O"l2k зxTceAcҒ(*6>>72O[Vy|^@h{yF뿘~i0{-. ED@:"w@|.d mZWq|yB!fhy,57*/*|Xsn'` Sqhop՗lfUߕdvf7^2o/'sMI@JvX7/,Yc< -ü6鰻I<Sz8ZH),>DzWN=^ɶOuem=,%8=8j/x*I@;4-훣h"CǮ Jr~T%H4C6\%|^L Aߑ9z:u[iKn=x|zK[ȴ݃E_ydn/ T:}LaVe֎7+<ԁ^i8,ѝ]Dwvta:gN|CTbbV,y ݚLNZV{^r-0ci<#iGDF =-*(.!.pՋm/:.ע*]Zی6bN#(~ud0 )r#&`#Al{ciS!t]Ճ1yCЦʮb lSoM?׵3n|f׉e q}ϛ?6OⲜHחvK_} KIDAwXIѴZv<,),ReJc )cC,J8s62kJNhv%lQWjbP-k fo7#=Yg2HҦ K꯼3S 7t#~jAy Xo9{ӷſ/~ԫ`ރkWN6qdg&_N" A<#ȯ˺ۭ /S3 #lTWWt-6c.##î(,r`WFc E6}:@fyj) Z2"V$gCE  $3,M kY\6Pv-CZ}|GNd6yML}i/E^AKMm ·U'`p0™6]]DUٙUg(C8?+y<kW&ZP~(rD%zUwX]麍.`qO`})-z pЈNFdD~tTmyd2;%; Hj~u&mV`h49y5x3aDRQ '뻼NeF|>?/7 k$ܚeʒgf?-ryʩwo| JOmNl^`(u6kez^ҎӼتڑ3,4|ZU7a,\UUG}Woz _Ú2npwxMcOv/05mo- >౏ɥ$%h>j5odX8C3ɖ,1,["Fz)|A4B|6k[^[It@Ir\z:%[PRgMW32$^;X,PP|YA`AVRY bO=S*'^]U#W*4꽲ooȄ=k7Փ>D(~ =7d>`g쓸,lFL{M>/4L!݄, >+Auk[+Wj? N.&P_ܘ(^YZ`v |6<,fOx}*'VA7K"Y^O\Ǐ_3zl籭vmŠ]urdX!o7غp}Ƿv1gvk_ӳr79_mK{j}qxxG|"_>'ٓH\8<.8t%KU67ٓ*ޞU,/ maw:X?XLn h|VXRmWdWjY|k?WÞ䅷5*P}?L^'pbmޗ]/ ' =*,Epo72 {rwppxKuxzy}]oߐ܇|y @>M4lP0%Q.K ϺKls1GrQqӲ3r䟐? }DOOaCګIJFҍ9͎W.U/fꥼkdRQ*/A R,OW~+GFn#@RlA֢P-\}|A.r9 ( z)uP 9䔄]܇Ly)6d  {!=o֏/꥜M?K9x&Pc6!c Ϻ+zmf%6 WF4 xI*"|tVU_͜t(u;orL2OY޴3-iM /VV8zfW7f]RGY.lfVW,d2` i[tu~+ڍ!ɼ~~voEaRЏgmKi]ҽ*i|nz~{]Ua$'O *gP6jNb r L0* 5K4<m"|$>@xY`Ԓ uet@0E`’[5]$ZF ]%Y19٣-eXyCyWޥo|un4_.AP0M7^@}EtRRU9U#hd~QV :#o-!ڿ.+N(9x5?XQppqQR.Yt]-}l9a&(Fڕ%Bt/!֒/p(MtPXOQ@G(lifqRNSvߡp>_p! SX(N´-F 4PuCG D1&)"xLA"ScNqh 8 kW(U_P }ஆ4P$MK!;^qhiE 탧'ZP_I_ђ3-%5 }%v@h c@$/[̦ͦhLiJ5BNJH`JMҚsL$\B 9'I!/-o%MPv+!I\=bnER'bP.wIV3=b֡|Evx|ݮ9֡&ym#)A1.˸94̑BRMi;}-pGIA(gOP/ͣcNh?OIŰ~3~D Rlj(v^O5D#oMaU!*}fu\,;>C-39¤{Ȃ3egi+RY୔*xhV0Wʦ#sư gGh-tL8yXCoһWrfR:vq%}w +兞%r˧+&`,z$MO)J83]ܱ%՘ƒOr'K(P=|VKq"JҧMV#1etN(Hl(Es"/xr褘caϙ'ĎY1GF52}6x7dl4AqL{z/?fSh}hZ,Bh%D8̴O0Ԩ2'P<6t;DP%Th #U %:N`.E/çP [Ic$%ԡ\8`tv$!`lH+8rur0'@Z-ۑD:#$d&&>7ubPa(r0!I{,%A+5M\BHCLXǠD9җhȰ9'{I[zɁ`pE[ED{[[$!c"w&#HjjiXҰi״[Ѱ~՚znZi4wf: {(c̟eizɀ-~ñA#6DE$V"\ G(AX z"@X{2]U"ɶC墽"uZfNƺΤ"$"5TSsXT$8 EH$EZSS60%"l9X$̞d; {= +/|>_X|aV>_X|aV>_X|aV\X,?-kDz/"hޟg9ϒ\IQT2쪫J 2o岊"{1M~Qt#u9|:<]q@;sD}} ? n0n|}9<7Xhȯ.J/,y.5#5&M5/*Xތ4#;:+ }c-9" Ԕ$:2>,!;{=%,Au 9_sE0c@#`9F4`4{ 8vL ^0> [ao@NH{7wR1p~ s&<$a!x6>p3qA.)x][ Pw!0ؘ%ܭ 5pQ1B)&!N!{Ĺ qn GւUH>5+"Ovcj7{øL=Qŗ>vykd+;L#njH( N(Ӊotl\.@7aP6n0`, mU >>Œ#$^dKPKBTkpEr@9d1W6+1v˲}-nf䐘:L-UTTcsdeeRfYl@6*';$S3mըժ8UHūURm'Gւp9`656*HI 5σ+' @< jWCMBCe3!4$EK",'5.d+^\ #+ ro<*CS&sIn>s`" v0A0`b` >O&0H!SDĀmÈAF \B㏏WV >il:A>O?eJGF*6B7܈jl33Kћ` w`#a7zv=gXoG LNˤ/j?HԮXpۗ}0~>j;xU:uS:N R3zjˈߧ*jGpPos;H:+a5Mm~j/W߳vuP:ZH\j[f)B!'<^gdu:pk35^sk??th߱AB,1p/ aT=>6^%QH0< 9$7Q3Mw7Po>^>2^0 > hk} 0^o͐ÐK\9TH\?^@R-&LEbp|cj]6YXVڂ<Zy5rRW1"{5ϑ`Cc!Z0=z{+T@ >e? H >m?QmECwA(`MFCxyR Z[ W/Lbk ijW^ޕa☽=It ^ $K4Rј\y\ AL37t543M:YID)('+<ᤧ vy"-ǃ[i9 q 87хx"ΎU6vPqlNvpcد\cHǧwkIQ߲d]<#։#*kLYF>%"RO n$IYFRa0-qBؼ-l]tN04mGBv`ƛ-g%-Uu,ݵpL ֑ $(5byY|D ҂wk! c}D"$fp0vrHikǖ\qXXM߶l6k^ab5#5{k֜ENf3qutpHN5tM8 ŴAp<&䇠``ц:'^#E `$( ŤVz%-TN5~ԕ i@,?߃-aKh׶&P"v$$&uad"@ 6]  O\xP"QI6H[' endstream endobj 15 0 obj 31797 endobj 16 0 obj <> endobj 17 0 obj <> stream x]͎0=Or}Hd"e5 H ByR1; R|n}nC~ ~Ȍͻ]ҕfʊ-zj2?M7§:waKc{4 0,yyqB{=x_ϱ˿r׆vmj07%d\~aӹ̱Ҳt~ȢN-+͢5۵[W7B޲FwgόqL _"w{ml 2F/I~> endobj 19 0 obj <> stream xܼy|T?~=w;L2d&$CrYّaU! "(UAbhEK ,nj?mkm_V?T)Ek+|sg~2,޹g{?y\~2EA5ztO¦%^1AV!dV޼)dBά\x֟M7 aqWiB;r5>^dp/ ^u4h^fYsz-#U[~s {W/[xsCڷ!> }>rf++*F87[6r{> (‘h,HәںlO ;B JɮBBi8yoe+ѳh֠[ բ'ћ*MCP}& ڄHDCȊZ{mM82oS4b&W -A#9zסj.5ߠz-RYKh". .d]؆߀" סWISzwL4@Y % wv>9SEP E Eͨ݊Gxa#btk#|:|xѽyz L&Mɞ+}h-W7}ơI[}vϠ$>oO?jn*u/: DWmhQ>@_c+0=6w(Fh]vs_1zfnd3] S@|"h:Pu+PN {*?/YUx7>3fE9od_ ?2|i`(2YF@~]8o;q/ރ{Wmr/yeWv>OS,.[zpގߴ.^<0!t w ox:߀ow{DfYG0Dm}_E)u W#7jfx9Y]g72P71@g 6 boO}gcLs揤C"4ZtȺ}*%ߥBC }PҖ,hiFKs43/>)I*E 9h2ZEFwx~t9>'@Ϥwwc4 [ϷïM k!|_3&gL3La3Ke:fs?4s9+Lmd"& `D6y|DaFV`lPqZ*[%5U~[OrEL1Q1Ub$?gqOI_!v. Mw.-:93Pn!+=?@Fs6t9P]-J{]7>7!d~GX9~Ogp%ǏQy-#1lg䙹$nF]3D/{q?Ɵ1k03DdVc+cH4!g +#9iy?~!I"sόÝqx_]c8fxnV3tF7|TImƆ&kdsZ*iAe*FXo-: qAO70ӐwtMf8Vg\ئVd$AEo3KάV aDAME55)Q[[F l]mM&]]J&h$qj1&#gJX`j/Ea*C:kI/=S3˙bLP*o}5Nis~87(;\oËm}]۶h|Az0v*5P@&;m-X0 R¸>0>A -^7uڜq@*Շ.C˜>CR:n'ۧn㿒 ?:{{CW,Jj KϟGw{pq}- Mr9;/>"m+ۻش9 }W|\˄/= BJ mg*J#]C79;sku ]ǹQHU g,AR.,;LIZÉ }%~x9H#-kDK4pUR Õ}z&O9% _ڳ#s_"ZqH/K$(_(![v*umCÇ΁˺0Fism?udW99r2>r`Ò`SF8+߶[;f.mKZUj}9TjHG?6h0%N^ZT(-XwWIŅ*ה|Ix`6t̜۫xP;Eۯ{ ^_ﺶE#-{JTEm,C\@7 z_Ef#5Aj5F\5CxR껿' C˸Ρj:wv51`  #:''ω2o~$€ZxlS]wn|b)яF6j`֪Z)qJ+=*>e0,6yxBZYi@2ACjFiLS@ӟ6T72ᓇT8sw4eiyDk2,E\=yU:vwM쪿mmdY~KƦ];<3eRGřHפu&:5FbHav8|9Ϩ|-p/fLw;"L xlqH:qQ[}ѵM@n*2D4BYtkqT5V[^l>y"Cw8v*T9IE?\$5f"%5E[:]~iw̌ۚmLu{2eR>00x`7דLv@AA8~I,Zk"ʝҞӊ*P"{c*<*ܗsK2gٵl(O!oу-9\بX`?/T&7I}|/-f4R#r lzFbe'ВBNҌ◿ussMcl{ڔf!\vkms#B:>֐H^7n+^:|]UdWiԾ74ښ)%\s1MKo >56#d£jyCOnϙ+.=:66~6WYm4+)`0~ʬmzSPLpq_Y~Gua{vxzHăe`祵XfIE=1}!{=^3J:]f.JyM<[Y s\NS񓇝1?ݓ&}Ȝ~6cN| &(7>Q*_|!-E#|ZgsjՅsC g2{sF[~ \]p8\6RcG ښdr>{a̿I܍y0-S(7X jt5H$Jxܱ4"]cԇ>m~4ZZ 8(LS&2;.P.[{Ɏd \AvʹWQE8\-hW͊ΔAiԌ >bsahՈ6X_ȪNcK\R{yeeeV{`S>moU3w/~itG<9L#-v8UMϗ.%sD!wlH_ *S.Eob$VIw |&j̄G()M||󑺐_/țI*9k(#9kjz,XQM{ whF?E`x3r.xH e]c9Zl Եϔlg`+ʚI`LR~7ioeSѲ۽NATேZn(#%KvjE]ҝdPK;ۨҙS)oM;&+/\Qh -皔tfL5`Xٞo.M:"2>ݼxY:*SVeФiU* )U?uJuq]!BhMXQP,eIcS["|>=;"e$ P9uДO P 0*H5A?< ZQݪ Z-}歛/R dFK~Vq܉l)b=u}͵<ō/n1yɨox-}İJSce3;;$:V2lQyvëTJ\ `e,* 6TJ=b\#S +#iC&UJ2B :aJ | %U1;-v{ ;a{&3h̏hxnq$$-'y bREw V6A F4ut\xTWx&Z&ir 79% S}/D8]wj꽛(gA9hWp܂oII_BѤ&*ڴ'O0I~Ft`,PiM-Q{^ "D,Z5l%U^0`)be}bÿZToNNcE,W X 㩭,9"osЋZEri-B4TA/.tv;@rlxFIbw]mחE/1i9( [ljNb"S P+Zx|VVju`VWOܾ{6,58qq5!ө8-<5xԎj6ڇ)NZ.*9nhdƓ{=TkM9;F9f3'c웎7vWJak2̓:kFFy1KvV\ofz jƔ5}FnQ۶lTv[m#pkÔ HQ~\Cq eyk9SCla5wH Bch; ֡[ gڶ[IFV1{ 'zl-HV3lߐ#EжI֊f KtR j4r}s4J.ݝGG:%)䆆EՍ1zp}d䛧9F┷JߕEE,ha<2N52}-&GcLYXelb}#OjVU*aZH=*X@,gp>[˼\(*u$ژoduFU\~O* H)?*wxNݫZD*ȋcshwdyђS>^ƃ7,j.W{Mhj@S?.fKLeRtl%rxT#KKLAklB;( ntUw oEHv6` >Xo5yKŻm-(^u`F>⤖ "Z/ 0 :1>;eFC]4:j1uߨ$&:ftlAa :a p`2V۶6GRBqץOk:¹.ѻzMC2]zÏߣ]> y8=]4䟔aѓY^&!O'l3^7`VP Nk9XDV)>l:1#0dPz'0F *'Xk7j ḑ4(,3ZfR 9v |O*\DI*^zY)H:@.B#11>8F3{.{S֡C F`^iH֯eFZe[@jcD'*"F3$l~|QZ"lKo8 T61] ddRc tb9[0ܘ##5>KZꈆM8Zo:fD:@}1"6wd[DOe_'б:ZDŽ"6bt7` PgO°Rfuh@ځCPqo(\%E8 lZJ膷^Lh0岢|˞s$*i^Q0K#vOYih=w,к!yx|,`O!^˧h&Myɮl6-9uu w8wvo)>[$ӵZ8^ek8۸ȹƿG3!UˬH8$FmW76LIєKWKl-07;hHZELk >o\o"r^ uD[E"W+j9+T*𘽢_n5eM7aR):/ꤲ:NsX.rSHE῞"WuR,/o yZ=b@T#HdO˶V𛉦xu33XM¸ZYǷ>MfmJě㉦҆a[9!W'v[ݚ(іAAzF6p]B[¤!E|!kDM5tدZv:AHnEM.DyfۜRkm- 5Y⭷nJ3 t tkk kmmU۫=PBY"ջ;;>[,zQ{@TsU׸^k4T ݼil3ONOntլ")-g a^z|ފﯲ& S3-M"? Z}QNt񖉉YebǕ/Ǐ'pzA٠օjjzբ7g,B`FD!`18wz$}n$U'v\N.u4:ԌTN!rSXTLUS<8)NfHK4{6vXpygsڜu"i:8 ++-nK8L7HQ˗a+a)ˆQJzJ OQ/5n,=LՖTѡ!^revkV:}=+Ri2@c86n#g]^EtԴ~Ki`?Auxx6hD!h֨vC;j|S4Zsmm+8f35bFcQc y}:>Ӳ[Xmv_(b"ň-Zcl4Fq4bfQC4LZœx<1w3$ΙQ@hJҠ8@1pCW9KMjRH)wd6))syjW@OQk' +3N0E2fP^@ҟ{$/q 4h]PT/BA<2)c.+ ѤRQw[mh6 k$l]+Ɠݲ`9_d8HF:<'Xuy߻qŁ'Ax&&04% ~fE1"Fe*yQ]ǩfJm22 V|1A0R3h4T>UZMuJnϫ(9Z˩H4XnՇ/LјWc7T6O}o<}\=S`QQZvPQ^f U i)2f/Ry(/_dZU AilJAjoUU-^ǧ| tS}V\P扌XgRי2ZJ?;0Vz3]up̓CA'DA')0xU)<̛[i+r14;M1]5;Ϳ__t DD3Ϗ\\\?R~jwj|vbZnuLGt'Æ1H&ooe;RUPCB(꓾T9J%v<g4VUІ%}>xC7^% :"%M`Se?UQ R 5U) :3)r4l)s׃g/(zAo\4A b8Lwr)>6vFG_sd01]GZlww${ۏZf A."f-mOȨazJTwm;'1eSd]"R6g3'x^ *R,dP. "eaZAk0Mr? Vv{j5[&.lQa%8wkN c_; {-|D͇%h;܌6ˌ-0YR8]F~s@"Ͱ}QM:Z&uFm?ԉ18a a+bNԱ˨DTQ`Dcȡ[U~1; X+!؂d#o;j TO&pz!yA:tKA_)&N)ab(#g4 ZUZ}iuH^e B1ބq4i%'Nn )Ty}\ԋW<g:[xHLTZ$GxC~dE٬vfbx*hTX>2ƃ VcΥ=-vKW< *\Oy0"Tlr T*5".kF Pݪ)GP5 *pă^yq*/HN@1#8 ;ys:ksҖ*}Ayj$,l[m^VQ@P9JW&4αnrZ$[wm-=Dg'i>L K?6i (ͬ)qyjvlaF5I69ﺵtiov& w/ijJ-^^ v y8l9Ct&"ʼn> :CA# @X&NJn sLtwg2ggYzxYVW巸ojOaÖ%|ZOS][M&+( *pyLS`G0=DFAg390Bg0se2y9d@(AG,T0Nr*σ@eqFUX j8P餔#m`ca(wVT$/ t=$$NT3cE/^ -bfir?ltWҰL=#,w5tWt45R@gu{+Z= *?q}tƌϯbIKz7xx(MLpǗO 9ԏ4{CriJʡ]LEF'Qs36ٱ։1F)VZP nD[b3'CG|!·uȜQ_L~koF '$IU*D;cbtc=!"L\\+|8J4 :GT}F.kM-ԱO蜉 MP|||.L'?)G.;e?GZxRdu>ɽ]=4*0z9/!'KuX/R); @q|=5#/nHyO_op1-`ܻo\:A»@xK`l2n-"D^aEXGXo0 EJ[(]N/y Qb0{,l4`=tu0c(=ɟC QQDFLDL"KDy݃=4VQ3f9wQ G'^=+-EMtG4҈i92}> 5taɧmD_ԳSRIY; gZǁ̃nSk䎘a}]3gd-^Ѵce'm. QcK+ք1 =fI3l k`(gFi4 Mj1MO}qB5Kj*nUfnsǃ/tȍee$%`{ERw(f#үׅR`2'2iVԷN1BjeM%5*mVG7izRG=1DbY.߉η&K9>OAn$%*JY|tA1%+oGJIIH,VcIl4NT $JȦE9KX^Ir,MzhUjٺ͟qO䓮|MxcQUgĞ{-+(~η:V7[VS0VEu6/%P26޲=zL;hZ5c-;ZУx "u\$ƣ2#tr( 2C[oE4w,RA* d\#&Y;Bkksm6;lz.FWr`4#1b}fظBU |@P]!7.qML)hE_Ʃk{~Zuhph|JZ ymevyNɸS[^]Pao+#̭`ݵWguIhnE9UAo\LVE%nt _]p \8)giH5Ozb!_ԩ9Zk\IϘRG~#OV^PW-K|<561]]UB&JB4KH/КCc %x^*#x#7ӸefU>b+sg8T10 Qk+nXA MMcAw(za܈c®zJtTp7jX'cdNxON-h)-8T[,Cv=?WJ~}] 1('#aI<(el7,S8WU HUK0t##岕ȅ 'ͬ`e!dJlf`qcn4Z 1zCh;#΀ R84g# |9NT\HTпDb0NF3`CDE Їmح>F1% ~@˂\AR9E^Wu CC΄%H٠d+ٷ$%-b4Hp 1mhw ʄBv񲜵?Q>Ii_j]j{* kl7z^]GOX>n=?}d"^!:::s2Ld9=؊FJJz:-%=U$z[P(Fy1aNm?k(Lց9+Mۚ:抣:WW|M9>X҇(g+WVcޏ5k4 H02EfV=ަz | b#Pa՟ `e)*a-$WX:!9!X[? fca|_52h-p$=.TC~f=cc5Z+MȍEUX+5E~4VcC ;"9 29}'WLyiWR$U#Kpj7@ F&W QP7>ݹ}Soen:U:gN_e)7ݼMwqNƻ>(~\t3ȞDUǑ{ΘO'/wmnIufG-ȃ]n3[j]3::f1sdpS~P`4NuSj!mM36SZ2Ւki(Š [ejVl5l5+lN~^ƈkwzA!gMaKʢ l*K NiAcգ6w~dYz?`19[9Y4|c/}G/Phb.n&"T]W-v|1bɮBAw7 vPՂ<Z)BapGxPxI+F P&P̘̄3G)WڝQn|S &sH@GjƣwǣJmqy܂" Ie ϫxnZ$Ac "!`1XS$#-:ٯiZd1 M Vyl9h"#5e 8`#BOd*OD%&ɳݕe2XžO`CU =WPRPg )YGV5`)Pt&X ݩ6:4jtCoڞ-hJk5z֑MxoY7/ ƮoSsҀ̭d{G^}Uϸz=b:>V^ֽlhw:ѕg#[Z.l0 l8H4$MxUg^M{G@[l/©pғB5 SL`[GjC9X~%Ҫc YwWQZ쾪3UL3< ϡ8jfÒ Dj-6BPdv%)We򺍭J^bCչ!~={i)Sdr ݝ_G=z$e#_.8T#I t%|$$%0=-IuM7~Ywx7.sLݹN̰yQF>dnI%RӬ_IͤvI6 WrjZM}pVt+3!p[;O)U j) +.a{</֬0_zOۚe78nlo`i- B?EiZ6gˮ5R ]Z^qҪĤ\ ]66W+qkתO+UEH:Vê=FaOefX^` 8vƫ:V ePWy yW咷CIsp]ͻ,%Ԛ)X /-|%qЏmӾ<]]Cp<)Ԫx_KGr2M.TxČ3;9)_y\6RaECK 1Wd{nyW~a1^O|pd]#־[)̕OmHMJ`ӛHju{҆oUY{r*>NQ#LL5z 60Jmg4;e;oJ.SoT3xSosdX%A2h:-#\c5jZYRj5VП Z#D!p4juLXyL#/1aaJ Q !LV$#*j1 %hu:࿗H4Fi8MW8@jT-\Iv(MҀJi`Prv 'nKH|\n+YU&H.sP^};Y]* diiڸ|3#! aȒH`?iA,BRfF$m4={ۦMNj,Ǯ=ݭlm߻4:iOntm$$LO1w}7ҌF?5a[Sn!Wlw߻akL:'KVKgoj6.KJv]Q/n{[ZT/ DB =Ol(yл ;0TY唯$*6rX"):m:Rk&?8 "rI%?J8\b?"}+|åd®/px%9Vf2iȪIQ1K|6Kvx?pIVW9\LvWsD$PMʪ~7vaFYϫ"@_ 5zi|70ķ@_}!qx/s⻱ߍnT9 ao!5s!g9 ݼm.>9 >qW~o63.KHWmdM˨ W#l\C}? "/r#(/qrAj00 a?0 TNa`~ۆ!S8~Z rؖLF 3)[9 Mc\r85iFFJ"*iH $IYJ!UH&~@I9=qј -Ws(NC{xFA <6L> cdq 9$$hGh"W~ ^Q͜T6+d+Ȧ4_ I/ 2>}kM(QAG5~qVAtB;h\84zU@kʯ{m:~G0TCʧTuqi%tbqN)zO* sMVqu>cVQ 9G=@h0f1b~zY%(Yi0_zOA[hȏYl#%Г&TQp&Q\ 1*ʊL:Gqe/8 3zcu@q0E04+ۑD ǹcq 8yMyuzEm"o &2KDJ4sa 2"y3b'l\|3%V4VCW܍.њ@:G BެWYM`U km"4˹ 3u2?Kg9N4CYTx5*| ),&ZY8|\;jO-qYi6(,ֺx.q^GavS4Z&i{b(- /V3#<6|}Eq)z2c\W!Q؎# ͔ZAsI(W Y*d(/1* m6\-oF}jgdWF鍰PIP6u>52ݎ8ąQ,YpCჀgVL?Y-k?b~ ºs jA{y*Wo]Σr+[0_cR' lV60gˬ,hW.6{y&{6W\:_Lٲ.1fEy%1pscG&\z%Wfŕ#|*9RT\'4KKMlM",N焬Q =*r=1Wx.fh޸vDl=f!Gmy=Ǫ/ 륉pVy Iegi8q^%٬JX9t5c/~ek!;3a+MXc$Sx.k =`Puzu1+82o1 ,/5Sz䆴]#D0?H+kOV}I;ް_U` G~x܂DI?1:Lz9e6CO [=D+r ݨ[ʘk\z80FԈ< 4e2NZz2⑀ҭZ50?OSM_ΝM~Jg<GcL͘Тf*IPr\MԸo_ԫ#a!u1frĪ_<)|EO)UcLI\fFu - Jj)^e`rpd$Mm2d$VrPS|tꤞ:Ư[j"Mn& =b% ejD.b PḦXٸi)j*\GJN[j3lܗLD6iԔf4(#0dLR&USj>Т<cM4RHr\S ʣL񨩌'A3h9jJЇ&HizB+QfLqND5cBE0S} 4A!#A\nKKFj4$U\4OH 6AcsxKD RMu_ y8x.DDiriFJ*J_\MX:YgnRbZSHL5Ti14USTTF-!GnMT&u+&Kr| Mjȴd83QquT='4e 24XI$f*N1dtB3,YVqrr20iYq2w9dA>tFhu2Njqr={ww=x@9GٷwwρC=={ J\%8wr1x y)V`2xT2M9# ,,e80URɦ)ꨡiaeb*+9la^2MU43<iܲxJj,Iids|!E@4gg^s`\cXU&xKjPÌ2lPU̔!E\/E^5 ȦطZwn*yYwHz8 d^B1<:N._o!Xd7G+=!fk-]|QiEJ/*-_TZ|QiEJ/*-_T=kݍ|SHK!}#xUw[ke׶9ztU~QIUӮ)YOkZ@m`m :mm8 h{oSB#)c+#IA꘸R'']̻<5oMPr;;tn'6>:6xwΑa;۫@9"&JSp&̺jtuq`Gf,țҜtj#_Ƅ/?%w Ry6miI:'=gFچP~K_OeC9ĥ[na&k7*f܌*yp lҦzg۽OiwXv<z5pH_?Z,},["ǚ<.>D`d*(i`9 Uz,x[EmRnf?T ~s[ݳzmvҳ>汝/qpJw )VbVF/"Zuq!*gC9%u:5i:S¦:e:SP k4; zB%?'O=De?۱'XK`!$%lpGZh fS>&Tm 뼡6/ ^| %HE`X@n:SK⫢qdK#$KRtP:!C{Y-G r { z)A{!H)#^ @JxC@ )D$(w;Wn8r pߊ#-Ob-@-Wg K{m}ooP\?W\+)KU\C[qu681ۅ&нs"/ 9K: ]Kdqm"ωk2hsrgXDja; m/fZpگe9Y֜2; O/ hJNfl_ɸet 7 ofC,`LH)B>&6ZS;ȿ 9ē9^/eKp^!Ήッȯxl@B3~͋B$?|'3mFO3OW˟Kr D݆|'u58> ! ^-<*w7"SnF޹ƱndV Ɓ&7Cx6_8v#^G;k2Jgt9mNIk_ CѦF6DeE)R5si~ |vPy9Bzw %~tf*zI@W%ψ9ar)teI9iK1ҼGc/#o 2n=l $͛)@pzsvߺf;b'X kQ]BoN5kוn<(~/ %+|3%.Qtp(6U~ESR@xI iJ@]&)Ur8y93cиIe 1/NETT}{Sw[Wlp̄4})b8$%>3R"&$q}Bg.=p"DӢ I0QFfo endstream endobj 20 0 obj 23795 endobj 21 0 obj <> endobj 22 0 obj <> stream x]͎0y /Qk'a$Ab0$ a瞴}5u=}7?9ٜmOM0pĊif^F\1IcqП:IƵ<=ӦNK~0u<xp lLqTm\s,x-U nT2JB;G=Ũ,7UdQ.`Gށd\|bf ~o+Y[#o^ftv`p+ҿ,:ORcq?^_=韫y{8_/gY5C_iw.wSpF .92ncOGy;ѿXis.]6;OSl}}l8oY endstream endobj 23 0 obj <> endobj 24 0 obj <> stream xܼy7|ﭮ꽫z߻zgߊeaATfPA@*\*>aM5HbGaC]wW~_xҫl?0 K/[Qx3?8+_A2BwƒV Nze4>0|M a9No0^`H GR,HVҙ,ގDv 0w#?B_o~fOkTZ]>abm(>DыGԍsh`"[L, 7bU! Dȉfa3ڏjǸ]hElBhV]DZh-aBmh[{ X*#\觨{}0J?:]^>ErMG{Ѓ[hߌij@uX8jf?W~| p0IFSC .nz^BЯ70SZEt T=[َx?c)? Oӄ-#]&d+@+0Z\V*zա +mC7o̽ W1#x:~F~ S _BluPP1ѥi2νl _![C̯4U?˯ ѓ\?@z>S {Sy3o؆AGgzl l3>MD" m寢J3WЍ0za3p?*މ_%o33Y[eiʾ\a:VM0#}3؏C0R#-+5x~GOCn#wkmr 2if*&s`ҟr\_U .4k mh:'@w+Q)jE|o;]a:5ŧ "&o4d1f Lbf0?b)9SnT׽uz{%Tف h2 Xhzh@9tqk:疿CR?߈~h>Q[X5%$_=:<]M 83t)E7KS+)2 ӭH9T d(@Qw_Ntq8J0`fU2t gE/KB[h AU ',FOows:g&:V (HAزP؂ɕp=*gw=+Hr_ո O[FyЈ3|(a6ʼ~b]'> mXPUf%̷ jh<ws#'JP ح}DΎ֖榆B}]mM>ΤSUD<&E#a1 }^tmVMF^X C0zÉaMBҾ6,=kp6|rXGp9RVp;jVJhhu0<<.mv$'=@{gSag)Ҕl5z`ZniJ[!HgISTzL{ #aHuw[ E¥S8Ўs6ad>c+ Ɗ3r8m!}0؋dr8!Uc:E\x2O&3dQ5.Ym-<J'WL` Bv/lU o o֠".3 ƑƦz&B]ӠOt$y yUg\w<c/=TrDkz*KfFy9̼p[dw|8i¶u#;AYCRȉL`OMf6(4R-Z˱Lt\"H6YYz@"om&7b#=UjևL1>lhS%.g šu95a_m͔T$.!9N;Ḅ? x ǛmIx`hIl5Y8XBnpPu'"I3,kp F;m1m[VuѰE;hxvj;=:\Dšx\`h9)J 6wUKh-$ \Vl;]?m1没ّWzM)Nv,'g!]+Cf4m6Q6t&oLt=*hȎ褘.Eh$9119B=,m)&A[NKcb$iƈkBu+5Fzna {隟Pc^ ϋ<>3o{ٻKE\ve]og93K!Il"MɓȾ`00$oc<'1zGȹ#SXRb"ȋJ]lW+. c- Hv\TH*fIl.9m a9Յ a,g>hM a](ɊH#:-lAp UlD/L1S$afd7ONC}hBGP/+LAō~aRk Lm5ۡVQBGY܉9;#9oSw0ұ3oTXBФuSE9@yNb  {*Q[:g]qU;?+f@W"i=ℳ%$,=Di3qk$|&@)(:>LAzi09{{GG]OUloڬ<<7ҥ<'bJNL4TIb-$스=rS=eKWM[spռUϭMo}ƚ'/dU feHX{~뿵O o+HtCgLwTA#:Q7 8LGѱֱʹ³ѡ#7?$?d5+waGe0Yɬn`Do`n|lЩO.3 :FWd.{\#Y®eGpɨWlL#KF Keb0dh-{ ȗvEDD):b )uȦ։B5& Ubl < r*zc'Tn#F`R($d MM !!?N(Y\.(KX@Z+tN8^/^~Qstk?y?Niß)^?ΏzjVpS1]8dF{]DFk %lFYPDFRl/),)-l)/pA`pڊRUPY孧-5naFNJ!`taХtڝ8tU§Q) ý0BB8A@a ah}HU  ٥ȋ^( ]oj Gwdˆ@6GC?6$1C/e+/y(Ya (zxn @j YޑЈg]HA"A=z$) g!PYe]RjkXWi]bꩥ@ _cu*_h R0Ng>`qEh=5NWgM[m.RW5wn?{wXmkKL[|βKydɓ52b99#<"'h5 ДU0L6ddEqL@ENP 6e>/3y0ʱRW_RQTgq*)m:cǁj6R&J;0|67d jL[MLL2 yIk5y7r/̐j CC0@8905ӋJv -]ccԄ&9(=-+%U>VMStBJQX40A Ie}z'~?7wݼaFGӘw0Iv0.ęX kf[.:9;1Xyiؿ"fZ]r,0&A? گ-zACf^Pj9p mܕ!FZ`vĠRvn*Qb6$)&!%C/ڻx9_2R\(hp/A.q -fQوR[twZ  J+찹 Ǣx0QT/ҳϣ^"]SS  WyAQkRM&hշK@ƺƶѺv1q#︿7p.}[!X%n֛oM-DHj! V]d,z$oV ؄GpZ,2=o ?ƨ?USEc֖fms7>SH̦;k'.Cq(KaNSs~Ht`*a9`թsR!.؄cOVzϖv-~?Yo—w>X]ˮ)G^s#J?w6&y/>S }q{5NNZ4aNnZ.ҙ ZWfn?}=ngw> +u_C{!^vޫ/{uw.s tsvǏOtt+ۘ^qڜ^Uw˟p]Nf2LuM}G}__U76.[J!6,&-t\7A9!f`|[/ۃ<ȩL%<=/z{9a<"<]՚ꩩ)|\]-0T=яeAI΁N;ʠ2Ih"Mu, kOYRl?;jXoGyko<@Ne^*iq_;SEeka?5,Ƭ6ZUR "A8#P۳5 FǃHܘhIX40! E-Dq MT<*xP)X-xC@WцKEuHZ9:2W\5) $uof?Tfj"ƶdě۱9kM3Uݳ{oSSf~ Lؔ y忒ݚqEȖƝ&FC`hiy\Xcq~Hl Y%lrnt82QvB0ZۏُG tͨ-.-R 1x akS:3EH0;y=>!Lj =pհ+L֌\6|pزni)OK/eWh[ D`;&eVEyybby G}~s2¦gUpILY4sax7[ : Jmw+x#Zn14iNh q@Nh5U(PSjc ΢ g6E\I.EM)i;CdRe,_Pj/kN{Bj4M 3Ds-zg34lbe8qr la~oA-BD_upD~RF11"E 1"I!R2&f$)]I ^r8K`4`X gXv:rdRCh8xArC[ZEM-,*(q! ZA/f$ِ̒UAQZhJ c)s>x$RK&n'%'`SkAJ-냱B[=[0ehʺ/Ø lL 1(۳ ÅlƮr!@,<-J Wn /")F+,umQ6oһmW;dg)lɆR@8{ڊ-Aiex%%/9Ja2aזQȁtVΞhB6Qd/eVp-OFN~V-k+^Zs%5rm`fl5&o:5ykf)2&dLGŽ͔CkCk+֞u(ĢPS.|iD'gD2^I%q"EڗM@MQK`i[<[B[[5W:xH-I{<=x"dㅘm+[WqBSqWhR@Fkz|sm?^7iER%!po{%9{?l2Yv'2 ; ĮaEDV;3+R(U8@%k@HeQ "մ%FӈQ0fѶ6lc.N1 k 'Z VETSV􄈆Xyψa捋_=>ͼ ˍ /ܟf/pӑ4fz}[U}'UWۿx~ҥڳ"Z3/+]Hm]D/ h&'XJaA.$=i>,hw IEA,ƠFDԻΠ (Bⅰz$Z*HD* Xx aGqIh[⣱*GY@e^ǻ(I8'Ka&1ؚD pBNÖ]ve0ACB7QfW vkK%#؍--ZU=Q|5$yZh38Zu*lإv&%df^)W:_؍gd9aG{_mr/q㲽.!d'StG5c(O7'kAGTʅkj(;x\#* a~uWb$[W?5# Xx87e!r$G ƨWDI~L hFaѦL6"<&q.Q\<"qۤ,΃˄'QIm(Kՙꛪ.<CE" u!Bn ZUN |i=s.O- oVP!ds~ffξd\esXqo-WĿ<.qQ ̧̭^E:Ay|L5bM\X* } Y.1^Z{ ?->>"~ـiY0rI* jib jV!w-%?4֟[G0<;ҝS.{p :NOKYG|O8S^<0xz~}j/9c"Fy+[_a0?˿+|(8zVec$ 1!W#@" \s\9Fkqc#UF5Kp-j@@E  y , %/].s41"ݼ 2&legc,)JLÄǷ1lSP/% !~"BxU!Ѕޓœ1e)|- U[l'*u ћ ћ%ͪbGR9i`DM,9jn?0C鵖;zܐmuͥ7'7H>} H ]<^O|XxIV~\fnv~_POAE--aȄ"INBmp [v+b?,{צ:J:͖WͪmDEvvR6[-]2.Fu_ +0d^A5sPwu|]4GRr>j0-<=>%6m{eb{c#G@L6L&%j ٺ:e[KH:)tNOmBMvtLN0%qZg3uَќU]W/Wt9U+#-q2kۖu.ۖQ[#{u7;88?[ņsgLZC.*ᜀs/MfÿU@јGz]& 4´TZ \eAncv?y3T|w-L!$ְmgߛf'Kڬpyٶ|yngͯG^AC0cFzH,1Gl6M 8ReA}9C6Z Cz\eL2J­hA2`.TFd-%櫔Dnȍ3+ pɡL߸7?m58C6m\>˃0P8F`bq9Qs$K|#n7km8Wŷ}F_&XZPLJ>O3msŌC8t55&r:'w*:}!w@恉߁?4Ncvdsblҫb+Ԋp/ 85c+V,VCÜg)ť7d6{(#](y-f:yM̲Ǚ]!>qDZjO~Z(gP w ƮfSp ͛ b~aV"}QP)iCO;.Q bK FDtІzMȭ,򿙸D[ +*)n5RI9ڪ}v\g+jW{B]:W5&s_$I =mjَggN[2u<%a4ӻiT2SAQϕy[NI5&b )y֌⨬Rj_m~@Ӥ&%S}aڔWoj'ވ9&X[ؿJ@_K^ +CSCSg?$P/1X OhI4yC@tHb9B]($t%@vcݨ'[4[ [-hl/$J٠~"mOlzY[FL=fOmLNv7jWhkI|mz'~JW3sXM eryu{NH3}ӢKˢZb_Yz=x^wǾx>~c:ɳAm4А[#?+E"* hdQ8P;Jx?#%P?ln"(`pdބBs0Dvb8$dM~36_8Ho%y20>V'o>6^̡un)P"=W$>gܛW;yAqe8IEtK lwhjL-J =2zcJ3JXK"aJHk]v_{dt^i–[w̹AjM=yEbaKdd5w7{7gG%C$g8GCפw7Dkjv/_,ׯ7 ?m1B:Jގ[vc G'P@px=ZQy dp% X]~V>< g'qxi+PUp 3Zo5w7N1džv%82He%ّrXQq%7JCҤ>bwxOϹbM0oz\^w.j:{y[?ertvZt&K|,jGPfD"d2 },Cl|[h%o0/A)6w4JZ$+XQ*p0"ܘ;D8"+L=#:Vۥf3kUq#ZkM89T\G_SN g@jbRٮU=6P&]h«X% T3 |Zl o܁v»"Ϣg#fMXIkƨ=@_pգ֠Hp`A؅Q ):sJᄬyiJl@ ʴ [b*xd-i/RUr|]E׬d>=Lmʴ5Js>ߣCWE2ߊ5F G;ƋYLjvIbƘ/*Ǥ(bŅ`|k|_#T`w½M$$Cɓl; zR)MIa7[ 66ge]ӦxO=w`]JEݷŢ> a%zxox hZ,}r_TpA*g >byݪ,p$!FE/G>ȣCRRsTTBp.1+vcӴ:o,ښff_ [SL8}mBEïJge*!D"n5xHQ%jJRdb˅ŖRFV;$}#vz^3B"Ӵ|P$Zd`[&JHIӏi/9ju3ʋʍV +w?;_q"lLZ0yniISy ><o)*_U!+b1:DctA;򮼻rqqq/`.cWWָָVMk]׸m _ܙ'.!qgό,W'8g,jBr?7cLl6ݎ Q4xB^ѣIdJL9wpgvXL# /Qu8S]##=D.C i= \DXmж h! #j ??p&)fb[5 6T'AU3s4RUv8=^_!G=A UaqgA+>(ozF/ޛ͍ ;2>/3{ XTg_F($tPMld`-%^ 31pj0P wC3T>A]JTUkKhqON2Dh}^Gs[߭of~s(j_ ;s?GÀ(6ye)G]3K48p͸Z9Op1RT/]1qKjfq[l[F_K7@cvqqCmw8v8q8m*MiĞc7_/aРzGCe[ߠ:hQxlC17D*t␯ACB[hx/'t9>hU,;^Tp)p)iL`$.x#,Q<Q$}Y"dyKCϐ46OFVEUVȐ"h#oQm8@_Pd"1>t{;oZ{qV"wlח~+M=gl}J?x/v8ןO(}vSkv Z6WIiDL/`=ԆuuM*5OʱTА(9|꿓<}PD<C+J;0 cH$^|&s޵mn +K7 Qg=!{yTF>FofFc9LB0$ 0ǸҰp)+9 h>0bO %3M̭!Ud0밎l:F\B)XT 9fċq A[D tP(:U1RLfsa qT.ҚPE-O*1Lz7| *dY_j U0 抄HO.Z7$I'$`L:e4w^6~KKKw=T|6?wmU{_1q$[v'N_q'$֕-"Kd)#}ZJ%]!PXAZCHmקKڧtIZ::JnS֒{d918==ysHbxQ|a_^-ϥ}՛M9C8'$'rnI3Il!{4k[faĜ{rζ**6q;;lV^0^,o#tB^H2yoq:^@ x%k7*%͖OSzeeu윜ۀ[C|zEEG%Zޅ[Kʶ}Tŏ|񺿳=>pzS+yae]yp?_& icbmjʕ \aA{[XtTYLx6Vi3xXy#[ڥ EsE ?&[ t .%VTA2l֔ |DYlA1g%%_x <+\Nyt'Jx[xyV.NfUn]2gx"Yx +narY=^[Xm?-po }A+ v bߊ.CgńߊVFJ#KS #_8[SG~&<~Nׄ^ /sq8w ^+q-ŤǼ~rq7 {_  V՛Hx9_8L[n8jaܟ 4!F 5Q $\(piư[Rx.?'Kr8S}.0OӿG8KӘyz}dž0 bKeq!ItԘLe;0d4w X\DmDv ‡Im>@c>a(AB;]{rjZ"kzzvܻhUV!WN˛ӲcCƜ$eƇ1NqOjHVc4ל'&*<*%{[aOr9 Zu}HhsYKa>E;\0%vb4PMȇ (c"QZ.]e[(~jP*|y^Lg8(~@3^kj!?s[# c"FI?"^){u =GŔf/ m>_r26GRlSyuy #IFfE:ŮHވ6F;_l6W?Fg3-kq2`aot[Ag.F]!j|s&E ""cN\DJ~cT)|#wls= ga^Z fev/yљjV=_#b; N.;E&u6*N\{`.o$f줩5{=I_d&}),*kTEt?>}sB}iv<;i)cW{Bs'Gl@"WsUbj̰EͨwTve{ySMi0x;8EJ+.i\UQӻzMfK杝1.AxOk ӽO%|&)}y:\L2fY>:Ne{Y(_ia@ܿL4qp4Om|RX3[hWW N-80#ތ$; \{;15xYaXD{4+jߐz¡p $#X R#y`j`Stusr+֭kj@rm=08횮EG4__`XmTA_J{ec*l٥Eun\RDz8T Qu7B1vo(?T>S>rviC>(oD֫~X :UCϩc(z_CpLÚi\h8pM D5mLm0U9{]EaA|Z(Qm?vyLLQJCCȋ}0Ij<"0w! Gx&(|BxRd ڽ:bKB 9:pb`\WFXKb9`9NU=6 y^B[,0q3?^75 -F@l F!u0Fe—%ӐȸnI8|@'CUհb )rfoP/G1Ѣs(46:E (ơpq8qXC=FtՂIgkM;6oQnRlѥݸgͷI/Q uy%K `ʈ/pKGh+0KAiy w0i<`NuĆHV?E=m WTf#I~e/D;"M! h%pSΌNaCUG8m)^]bNu'V$VXj Q^Uhȕ3WE^$|cG\(Ŗ˜ ҉K=fɼ!np$?RS2i?=9 df@ obևq,֨6ks>dR:k` U>c>1?Zr9-0_K)o3цCnj MvvشbŪUhW6kV[Κ]#j:?ifk?䎱d99lDvbsr >cIoK2D? @4hD? @4h { zD)čsJ6Wtݙɟc|GZK争v23{ŝ@Pv. dfm,Z۲mY7wڿMsn\L— J\>\8 sc {Eʭ$(\i;܄DѺX\E>ߘҍ"٪>f@$׶N(=4Vml2Hps0r N']㲡[hJ+ť(q"]l?8  .H;O"e 洆](Hv m< 2MQ .F9;SCMh 9v(Ïz*Eee[tX>:\|$׽z8ySy^$o< yj̿-e%xivʟx~yˣ6>#j[@ab\QT )9r칳*5\hPܞWs,6Q(m,rXOؔFe#j R0^-P hDT邬DTzgGdzfζ4lqg[.u/"&2G{bB{~v%m= |mTc ڣY~]#ר52.HkȉyE>C^g3Ǡ):EǠWNZVk[㒻{ h"Fž"uy"hlE>+z] %KpNRۤ5] ޵-Jj!j[-rT[Wmjֶ|fVEj_wakX>\c=!Ī0}mU~x****'V.u_ZZZZZZoqxZԮ*mrn3X YncV%߰&gYu9rKss sfZr\E3󋲋ymᭅbc7B[ўhvtO\ڞXN޶{B>GNL ~5ƎI)ۭv)Qͺ?6)ݓ%.qOE1$so7s=lƲ%6umWg93*ѽcw= G.UN,ߡ|Z>=`vN:m=Vؘw`V 6iΉVi4hӭ&SG& :OӃA;A7dv2h [g&-gpՂaEۦᯚ_Ó4=ՒZ<×GI #]Zu. ?񉑡xNFPj ޫ%FDSذ{|xCuշ{b[467tU{;${=8ӶEl-sp|:mz=d{{ݻ{"o>)cX}IqeewU%͇ A.Cew_V*ʺBu݌u9st8bb'p:Qxŧ_tG ,Y;0 : 61k_B7KV=;)ǝuTʔ{2p|,> endobj 27 0 obj <> stream x]n0 }&$P%C?ְJ#B96iǶXnڮ0;ԡ]p -={i҉S3fy]0,YSe76_BGGu2_t"?"k!yjD9WmxO׻X~I>kQicRhEQjߝuR?M:[֑ sτ`l c/%ǂ+agfKR }8g%9(9x#Y- ,3EEO-tqওX-|WxN\+e}ߢIc?|;484$$݈[[Јq;ӈ-yyҖ`?Kq5c6~qQſofAԭ endstream endobj 28 0 obj <> endobj 29 0 obj <> stream x| x[̽Wnɒlɶ+&n%^q8-"Hr  (%6BI)-KI@Zm-X Ҿ}{Μ;s̙͙+%V"wg8/#G7|!A{ &/c9B!x_@&Jy+<. E3ࣆg\6!P !Ϡ鶇^g)S m uw8a̰$F*+*uFH bd~%#}3p5(zN9&/f|N QP ڏ}e( ƈW"%:}Jo8jFf܎rQ8P@h #Щ &h1}=^A?.2#h}×G=nFf⚀^GQ98~Mjf 9N u菌K&tܳџD*T 7(O0v>zm; ghHu!t@/Sӆ1!f [XS)Z+ZhcD?DatC'0KqnajIQ" 9 p:xHc'PREې i ]v'C7Gjr c?`._f8݂xFpڊ֢~4[5^KzM`)4\/ŧً{ٽW$O,SABP;u5w O_ſǧi3ZXL&z1m-̽#O'2^c`¼jJ}5;߹4EIrI?cbDbޒH6C_Kt!Nu>;>ۘqMp݉pNZlFV1f w01 .<Le 9:^b/}=nh/1Ǻ0.0RY^'џ3͸#\9&t7Dň_^ҁZ Duџ? v\Q ģy^h/&ĩcR4:2+Mr?vjk*+J rs]YiTGY-D1!ޠi5jR!Ic$`hia.ͱpayvx33CS\0In[tOcb-_sF>#xvolpnn ahoøo 7m(z"'P(T6:`c-cl<  '9ÉAu6zzm59a\ #EQP=&SixY >uuT=0YCs a3G o>7hq|e{\hXԹ єREyR>,wwT3ǓGQR#seKv4c|ܞ8Ab5"R}jY>-NL8r4n8iwBI-G; >k0 |ay}Nm%kĩu;?@v_xĖD@bSp geփ"Z\)¼PP[; [S2ۉVwEܨ [ Ea"J9sSda.iYvNŜ&;;w69;=.u<cnh$خp k`2nD  >5(I8pyE )(Q#9 bqcɥ|ը`9( q8'2s<{[>A͝9ؾ_qls%˰ѽ)թU-@e8 *WjVZ q֥Ֆ-=wIOSQ]-ŷ>l}_9uD(TJqK4tNg=pd-K #l[Qg[ԕg8!O8zt+.,r'yٺ|3~ߌ͎rQWpOlFp#=qЪ3G'%BT\5.@q%MqQU6aVk'&΀VNÎ UT*pXA4ulĬT@5PfqHHWVZT`,9R1j)' l<ީp,766_mDf#>'w~Mi*^z*'eOȿ[R,+^9eE0Wq7# ;$7HMvMEfRi3<kRT l͸MviҤPi]⺤,xY?k 1!vK▤+mۘm쵚]v3$w$=O<L)SRI!RdK&ɶiػbv[R\x8_ \^]cಸ0绵X7f3ҽ:kԧڭ?f|iW .!KdNv$(Lڬ}˔` PVl'1DERY;JK˘%m8ګ)t5Zaycf>qQeÍ%ˢ+nMFOEI6b3wS.Q)ӓlOI[ i>ѥ#'Ned\ls$Krb1#q)#dsb 2:fഏ1鴡 Υ*"-a%x vZj`4o"ѿ5حq9VmEFTF^A: DW %eNs9ߨ]xiV#S(rC6֩Jw^cFYǟ-L\\b})tL>lc0Rmw׫L LXsIŬɖrNYy-ˏeR8Ev%fDaZrMLPt5E=T.&HZSRZO2H*QK7tvD@P帥:w{,+6g/o{l/k+ |oX#]ESt2Kb/N3*Χ>pIQ.:h+o1yjزjilP_PleJ[-Efg-hk(2'qJV''&pr,gjyJ9 k-[*oԖXb:SMF^&e@Htƶ!3 ̦7zu `TÍ~fĶw b16B`F+32 z͔gZjbMZQ&0#LX|p^B]6!Yzɨ7e)"LQSvbHJvI&:pBw\`5$l2Q"Bh - 19gKA .NIiӦ&0ߩzS?6UϯS F3sym Ť[̵8;ꗪ$ϭgsg8ssɝe綔9 kXwrNk !}bn{tlM+Dʋ)mdJkss$hi*{W=JF鰓.+UVvPgCWOQ|s">'ssdtdd8TkZ+ſKJMtk櫗3y=#[dcզOppfC3\٨o4dV+TJp2# :g]Vk!Z>=ꬫ];ޝuS!]Yw}8+:RU; CjHU(c\=aVǺBNA$tNF(&-'GQAnثVjqq.2$/N~NrYfY%uj39fCI)8mң xV"Ap072'.s@qGmZy\$Ƈ%Yi~K߶`qzMTkl7On\xc KPjK]Zs[pʓ+gRՔݓؖ/AwxfqWW.x9S%p!sȋdEEFu2TAE8⫝̸n=ĽOJ);%wJ) 8.b5ѓڭ?Lt\J=jc[\b0$>x!9cEOxEs$M*:&H"*ȇt#fu]Āҧ76 km{\Ul{:l!<:/emê]݇ՐmL*NdWJQ)*ԑm\-kƺQەYU=+.CF&!Q~7lSrxj7! 4Yii!Fr;n=3OvJ"v wr']j̰kl4gNFBO<3蹘=9 ,:1s?kW^j8"...嶇25jBauMjrO+0Qsё3HnZ3r#FJyVU9)JT+55:"/04Ǐ_iۇ=1Y D)BTpk VT:b.EX)䐑&NӍF]) B |bFf^ED!k)3%.I䙓N0kk3bx) 43kQKBͯJd}݂KL86!\4D;zպwe/(t.gXh53dBeAi(4喫 Bpl 3ҳLi k5ݤIȰMh4eRQ5kәtbt2cAɨiU85m-,F1{bǰ1IF@H6cXc\Gy+5Wggު ֩=:ช #QGsBR`DH}:.#J[HT$pYV*TvLõ TR)&4\Øz=N \9q͎\ҵ _qzӮz2K{ia_rr,?bIÜ{~o62?̇X^/7xISBY\/]X_ߢߎ5!؇3vk3TBZgkIJʣ$o)9oY +\jԢ2x+D&\&hP9p-8UxEQREnI1g$e8Ceqeh{<(b1h(V8ޚnN>tvN{6k3 鄖:S %ՙe;3 8OWoFk4 ꇔ64CK8:O-ӗLfdTm[wI#UV[ ꪵ[KZ7B^9ߞKdG_Dž+U8I]Q銇=Iuj+E#/[SQLn)#1%BSXTn.- hk2|~}A~~~|ɓ3/TrLc,RZgf*]Μtg*bSplXxxsAɵ'Jc= ̭ދ2r,xۜ%u>mpSѤ2#y/RK4eڎ7[  œ#I퓍dtOb*YtPShS\%q@UjBAF8p[%N` gaaWpgLs̫_ɮ_SD?Uj?Ң<4jO@n3% L!k'Jfff\(v~(dop *LPa9ad5{H( W ʯau#3"k;-+gE#M\PZYTws(99 UܟD8*R4S uc",GDXӽ JTyWEEXͮoEnsD!Pm @{Rs"̡3vCU9TTHa)KR..IaaUJhO^-jLaY{" k~±=G'ОMa-0젰$99䜦͹ "̡\A!~rM" 瞥p"7Pa޼N&|*g^by0@$mn/a/0Ҝ<("LF DeT0_t]׉0i*MBj'*Zuh #/E 5{%p+!C")0)=< \hR4gFV4ݟYIP?N%ZM9 Np^%V ܽ0.ߜf&Кϙ6w+S@i Fxh}0kK8STWK-R~C-9Dy1Q*B5ZVSmb*?"!&bETwt )){POs7ՄOBz=)ߝqA)=$@CJz5R^$tCCiP?(DC-ﻨ6$aʮ y)_Cb=F)Ċ AM!j7L^x%5zwEަ$"hC}-XOC*5/B(!=#(ۉl 29n#1gL^+^t!MOCAFB0;%U6(i'܁i mO cS?Ϳ``{JX4B.Fi!h̊+mV7ǚ9F9"ut@~G8o@wduA9C%7#Zn5< .(wcGh(Ҟ~J3E A^aLxEny$D$fC,ev .!?'P)P S PN5f !#d@\5f[du( Pσ2D#<%uB| L#8J51gfY^ zȌZ4Ae$wZ;z#\u%R#g0Sb(v]D- 5ƨNIViVV0;N#=CA!r{`a׈$.}%yFoV OB"ΉS>zH?21D;/JJK>k'(,~&K}K҅&_%ž2]z C9Qmq*͚Ď*ia?vSF4v`%_,5|3 `*`WȠG |ͶA1J jXh:׆hE3LYMBfaZ e>?zĽ e*|O|+s)zգ -a!q/Oi)YKH3t[4#`@OpRɀ3b1*S'e<|D++`Cop!RT' r^S}y~rl+|&4^_ =^#A'5ѮpXbPh; {|/0}!~{A_ߐ' z7c|?C)=A~ G`ex @0K yaA~oRH|o7UDاe ^0p4D^xe!Pз 4VAD&zG0:@HnJ_4A~Bd < znHwFdd70 x xB>гO3XO:v{ B 5"&C~{Yw`,xl7 #4 }~?X&/xA#AN AРϳ7 V/Xh{DX"A  =5?  "o0xI1@<2t~ŁbtȒ+l^_/no\`ycck㒕jZA}gaOTcU` -b~c2ۿd  0{^/X.{@Y$ ڛ p฼G-P0yPR/e/vhvz(!i`SY,2^2-{MR<74{t. <MzOE_$xk`x<"׽&KY ;E* ª`S(/. sU-И_PP\ eYQ_VZRQRV|}3<=}ļoD|7ONG_~GVгlF_ f2jDy&yp˿@那Sq( ==/#oooooooolm )wQj7?f*4% : ~e?dz6aˠ%W}ȩل8/D3?SX-!3 ѽT"軼m3y ;̛1?W1:=e9WUq\)Wι@<-nn~DAx#W~ȦCB H?Ο _JƵ T֐cݳh}aqM#OGO_{$jG?ES p7=8X@ʥxFf1V8{yrx4<1L{?_J`VN=q 訃G'ŻcvK#ѭ3EAsQv^2 0,@nHwSoIU_ץR)dP3z,)Ohy/-/s[ZoZկYտGakU/2.LI:Lm)SGG4 $?ģ \=jEVTeYcL!je@Lf<9l .WCELvhclx[QGYƋyP%slV+T[o֓c0>`BBq{6t?n/q{T/)F%t-dcx Rʛ6gCM7k¾ԽNۻQ&xUu%*EL=f/BvJpj<`ҫ1QqܾP[ǠJ2^ [nvmeŶӰ[#~GmJQz^=nMN֣Wvi{QL=YTeIQ :*# `۽{J"v7,v %g D8*{J2mKb6ՙtqM (:51|L.K֖-k…ZִWۏ0;0INev4.'8a S4< {օ \EhE_L@^)%*ErP)+F8,LF *+)4vItRA:PU(EU倮 ThwL]nhwLw!tw@;+6V-mdhB@͵ɏdҵ&p+Q]ɥy-aJ;ˉU8Pp*Uvɏq?HY-v˙GkHW,.UvAK q0 'jlF"EAW=BI1\.ɰr5˲ endstream endobj 30 0 obj 13316 endobj 31 0 obj <> endobj 32 0 obj <> stream x]n0 yCE]%A8F41]xNI;$9>+[}&ف6<ݜ~6,͸#[o SQ=f:,yu 6Ww7k``e so_r[/` <8_\o !J^4Mt-A~.H ".E='xAE yy5kC4T)|@#WȧX'Cnb}ԧ"!`rys.FsÉi;Eoj endstream endobj 33 0 obj <> endobj 34 0 obj <> stream xoUϛq iA>'%I8-i*AU$jc*lO3_GH Y-ک*tn*@b ز@ $r~q?{ޙ7wf< 5ລ},`{#74ĊfAߧϒyܣxD7JP%+XzuZYC9oi E Y/8Kv?'@b9G =ڞ&G塠B= t{R=ϧzR 6/uQ=:VcuR|t$yr*%qnX7;p{}v /o{ṿTrtdx(O`_]_[Z_ZyJ(WԟEthtS'Kŋ붕ɼ8͹g;;ݧS͆٠U E&h^"Cv4*xpr}/1<'l=O۞mFoڠdԘd/J,㔟k1 X̰K`E$Zj?鿔IVыMVhHWɤg]~*zxUW$3tdZ,Y3judd4_SgXlŧn a*ӒcįI 9N18Ce?+wKئ|ñyz<Ξ1M-Nܒi'QlvcYdL;σR!넁ytM?< _/ EK5n*τE_>xFn:WҕL3U͆A 8ɷT[p6$(lKxWC"..,!lk+L5ы} &)y8j(/EGT1N/K9f'K) +GEѹ䞦}/-wIWh endstream endobj 35 0 obj 988 endobj 36 0 obj <> endobj 37 0 obj <> stream x]PMk +{XL\z@öiIVhT9w4zP>x3;g^`D\5€u`NwT~=8ymI8wnR2NܒG<2 F&8|=~ gt *4`p /jF^\mv"˟c z%(Q 0twèo*&xhI++Oy>d9-#5,7)r)l*rX endstream endobj 38 0 obj <> endobj 39 0 obj <> stream xz{|E=W&;Mؐ@t qƐrA@"D2ȸ hQ]F:{]|8QtTu{w|_թ:|ϩ_޺*FonY~@lV{KVcK[J( ʉFIdN9BQ()Xfsh_gsX/_7sS|WԯmN7R(,{WD˯tX.PM+Ch 07F쟋k#e#2+SAdE F٢Ymv3NMH ?&HN1vmKCoN =9P|kY V-7!o(whdkЏ`WR2xt`fk1=oǧ}{ _oVXLX|DQVCm'&N?.p1٣F3}ތ#Oflߝކ6}D1YŞw R+U{b0*6}Cb8|mM- )q|#q@oz뻯hXhhSl~&Nvͪ6eqpXo@Ҁj>L*'Nʊ[SDd<+㮂=Kc:$xHb7t SEbrYLzct{;H C}U1y< BVEtNl .eR- "2[hicwa^bS{ w:}Tc)ڍwUq5bi)W|6.\аGץ*?$PgPqb;wjbi9{@qGϯ+/FBX/`* |el?|O ?e.\1\_^Jvφj_BgU=]^K`Ep#.2cBD kQ!?+_5Q3IYu d>>Y#giʺJohBWw>`KݞX#1.JnEY3$T'PC3PQѸ4!fDx+v0']ٷcc8 慵~ %EBq>js> {TcH1kz;DAYu kk&N 5P[?i?S";CAUv={DG͢H|/1a^kxB] ",DP,.KE0=Rz,ңny,XA{tvŎa$d {@^?.( ͙E^#%W?̳9"yt_C{RGO& ^&}} UH^*A'kH Ff*8D#N v0I'u͢u(^%,KV za~0Hg ^"[:PQ"6BB#m[t & q"+2Q| n 0Ld2#%=X`5xZjb V cœ ][̰8:^;ѩ\4fPBez5>_«^#ھ=xD E~Lbxx:KO+hn.|x 6n~5( /TU zP($ d71QG)1  = zS9DQJ*^'. lJXM'DY4Ez;\ExFx6|\Ex 3Ot`Zz==1LO#bF,I[| Mҟo#Qj|.QŻЎ2`݋0rhZHIbIsEǻb+]Y44pj AI+U{hRMaE= k&kHf[L&>Z~1ⷊ'N!fh:NQ""2Uψ~cD"Z⼼( ii a:5>ۏs!ǿxx/1ׁ5z\MPCntm/()=TNT+hz,=iKrX{\aTd'6Uuc*UԨP:ŒܑvrrMjxLjf׀zD2ÀV|I%빌b 0GW3:?!ɴk Gv:D '}vWn;:ecaضKX}OΜGAxg<_ϨQJ.-d2! DUp TŤ׻i.lFtP (/7ȋ؜5Mz?|GO</xOCD! 1DJ8)m+ sgB5j̔3/1Si=C'*) ҃`zD>jI5DFEX4Y}buDG@`sHE %U$),z+-!hUUՈ*"Ulq8S46:h@9̲^I恰f7 J^vf*?(9Zв D PQG/OF("WdE, Vj=6%AK..pY",XmWʁ%#\>a?Dʗ"R]%@vaMڑddE76*F#* eèwmFw[/^^[c|U>eܾiX|6̄W15m{h׮|qK֐;՛o>{dÕ,|gpQ V+URKQWOӪ4JUr#^;[IN$E@Q0jk֢dHarcgf0LMsȑ)>/mГ;g!;m_]tݾmx{!icч2NEs1]/bF jgXxҸkih_)'ŃIK gE_E^"/O4M+ 9,NQ=/W༎,W!߇uӭ<@P lS|1y|;KH&x|1݇G|t7¤DD`3|EtT%q";EEE\Ո$)N@=UI2P;,B0z2kbYٙN>\ WH >ӶW" @L -9 9oe=%SzzTO臮+.*(tK` T54zCR1eJ?F%%UOoOI d05kV;^jTj=وـXh#H)V .ssLA3 c\-GA POBIV"x48I?%=sG\ j:;lZO~>9sebkӺgҡV~xu/=ѓI2s?x4澭?lxUA Nnwճ[ZR3q325>Fh[?6/eX.ҺnomDeqٷc,8mHGz={n،=с% rxPuT AoxˢD$Rpɭ;%!* )xD'ºd {=KOU+% ! v6(aRPEW.*DMʲ7T_Co^#7{(x  'p󇈧MC/쀇*؊>G(Nro$1CBoI=?MdU~ߠ'|)ZZ!=*]kg?V&)#:U?R vq2 5.5mHXcXs{/X"Q %i쨟 Z>'i БeMw$i ED8-1N2'N+>* 8ÙI@ s$-hLxu%i $-6&iNIZBE(aYra[6@U6BTpzqƿ%^q_qڎM崃i'G^_T>6ﳆO'38ӣx'9=?ay~'mLӌΕ7.ilo?mo.ZټqI;lwbQQp<&9шwʦ#޲+[W6x,_#ڼHHCΔ"KV-oUs#m87/g„D5MPmzo{k}CdE}2ʍwMqQԻ~waYiŽ56yEZ1_qߖwJhPˑZzlhǼ UDž«($< ЈFԈр"Q^X35:zE cЄb>I`3p62S3OjGLA.c~}6^`|5*%vfai roWkKr4&}oebF3;v컂 V"lƋ7"L|u/#Z~تE/Q^n}l9Z3^qu\"\M,s.\Jlo>6sp)E^<+qb^ێGp+w \5+syI.b紉pM-?YFMr3ܖF&گ71p#̹,'1(ӢV`m܍jn {i*.guw )gb)Lδޙ3gΟ3W\-;l_͘,_ɲ;MM>ij`پee,kК爿\Ť}&KbHϏNK߉Fl碟D74GGGv_[Bn(w2J^FN)b;ص[ ${b=@ra&dI$&'9ᑹGel؂OwG^Ffw?ًbnxo{t{ǭmPСH:&|6vOr:INKis&: N! 91ٖ[qK6~UHOMxӋc~?XжXV=c{978o2),`¿2 endstream endobj 40 0 obj 7915 endobj 41 0 obj <> endobj 42 0 obj <> stream x]n0 ֮W?3̢0 7o@\ڹH%vfmfP{^ڵCG[؛fxow*V9Ϸq,dTB<5sCLUچn^֡/}A$Vb BKY%\ZB0o5q!o)3#q"wĚr'>0SkļGT_'_> B ہ_w3tP쟖9(O|oݟr_kq$xg~F-0fX4_lÈU|n endstream endobj 43 0 obj <> endobj 44 0 obj <> endobj 45 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <>/Contents 5 0 R>> endobj 7 0 obj <>/Contents 8 0 R>> endobj 10 0 obj <>/Contents 11 0 R>> endobj 13 0 obj <> endobj 46 0 obj <> endobj 47 0 obj < /Producer /CreationDate(D:20100331100512-04'00')>> endobj xref 0 48 0000000000 65535 f 0000119407 00000 n 0000000019 00000 n 0000002724 00000 n 0000119551 00000 n 0000002745 00000 n 0000005762 00000 n 0000119695 00000 n 0000005783 00000 n 0000009365 00000 n 0000119839 00000 n 0000009386 00000 n 0000010450 00000 n 0000119985 00000 n 0000010471 00000 n 0000042355 00000 n 0000042378 00000 n 0000042578 00000 n 0000043167 00000 n 0000043604 00000 n 0000067486 00000 n 0000067509 00000 n 0000067719 00000 n 0000068246 00000 n 0000068630 00000 n 0000093274 00000 n 0000093297 00000 n 0000093502 00000 n 0000093994 00000 n 0000094344 00000 n 0000107747 00000 n 0000107770 00000 n 0000107984 00000 n 0000108351 00000 n 0000108591 00000 n 0000109665 00000 n 0000109686 00000 n 0000109877 00000 n 0000110181 00000 n 0000110350 00000 n 0000118352 00000 n 0000118374 00000 n 0000118561 00000 n 0000118991 00000 n 0000119269 00000 n 0000119352 00000 n 0000120104 00000 n 0000120202 00000 n trailer < <2BB85BC05F1163FC23E079C11EBF3C1C> ] /DocChecksum /316B24F469E56525942ABD7A0824AA9C >> startxref 120389 %%EOF kst-2.0.3/devel-docs/Kst2Specs/DialogDefaults.pdf000644 001750 001750 00000123700 11544160206 022123 0ustar00synthsynth000000 000000 %PDF-1.4 %äüöß 2 0 obj <> stream x[KϯstE 0{sd88@|O*,v<%])]]e~寿>|].-p3<λ࢛\r/|K5Bx40]S(~#^\S`el[sԟga->o݉?%k^x"oVd @XW{;ݱ=WC,ls/le,&z~i-!˱_n&uU:~zNUH$)ֳ͓\tD4~oZ\4:LKLh/PZ5d !uUN}V1(5 D}Iɢ#[,s[Y"k;Ѐ$+ ~%ZNGs% b[<@q62V#)sC ˪fW78.U>'smw$ bU{OWSXPʼni :Mb-P^1UXcoR\"x)i $|yz1Q |@/hIW<<% )j}VDM[B4);8Y`#:nCU7;ضy$>=w"'1@E_E8I,/Ѯ m5@D \S4TOL#iȜ̚[iV'F2)HW6Xi*afU1σ2_rr1sV 8Z 'Pec4ԎWB@&SL`aʴt\B{[L`oB}[l*VX, YdVY=YmVgk2R(VX YX*kD47kc&¶ϬG"lhP&El4.Cڮea ;k#f%–W#"5v!&y 7v$FZi(ajǦQ|OQr>[y>ows?QY*T{™=h1:b7[t vķ3NXmn6pOvGM;&ߎ]nZ{ӑMZ|ߩ F[CЩh3t*5_`(ChHb0J5^/oc3k}c. 7xaJGZ{+.P_K\2*/Qp@65ŐѺ;3_toe;hnIM+w_zs6N1&B5O}߿r<9׵3 e}EHu.UO=\ /DfBF8nbх5$q^qұ#%rxw];qwԗ0+!H w4y>5]]r Fr䖋Pi}3ŏbFssz)*-^H/A1]?> stream xZۊ$7 }@:Uӳ3yd ? l`ߏl$*@wYhǖeYG5ÿO_3|k.vϸ~~fa)N@f3??Ǔm/C5&aR%2Hd-xZ&XJ\BFWb"&&ΈшDdɊxD(1 "ΈшDdɊ،L ?3i6 Z xap56JҲ4^&ΈшDdɊxLD(1 I111Y1IFI1ΓHよx5"6JERhD"2JLdEg&|W#و-Wc!a+-[HHDFi\(1`j,Dlx%f+bӸ &F#Qb"&+b111Y qAD %^ي."NHDFb ⌘HDFXgzEvI@sA JX~waU#D. = މ,$Kd=T%IR8DVYd<=/^Ve:YL#W d=\,3%-rT~SJ*,N6D.=ݟ~.7q|f aխJ@^<jpCJq[[m8ݿN[.*Į6]x>শ; Ua;ڏGUQoA5Wt`PE V{z%T'Y7"6V7-%pdGn*|pS[-AHy91;3ؖi.%TeY=ʩk0+$|JD*YwW_ )žLBȦY 2Q7Bq#î{Q^rIBH4-ڑҴ]eqfk ռkiݶ`Rˡ['c]WBmL#6wC][`j[f=EB^VΖ?>tYhKssm(teMm_`A݀Au.7#푁JUOo \QQV`nF6=얥i)t)qЉ{.B/ZD| mTUƟih}jl]ۆq?s sYa>GB7vnݾG2E/.y9.n@'v[hyrk:؝n s5nA[ރ_ۀ^noܾKmvB_®Gs)>p>6wllݾy6^+tg_`hN__Q}D/Jt[bsGh v~ 2S_ {?e] endstream endobj 6 0 obj 2127 endobj 8 0 obj <> stream xZn6 }W@ٲEɭt[}(Kw&s#c'f`uwwd0E lOw.2Z Vt*(+) Njrw1լl'j5~":ַj+[+7M+w>+/ww! i/VDRX+UNzRTXsw< |Ve/wcr;: / ?<჻,&>8y{7?u#PO-[jSu0u ㎇X a<\sit8'd |2@}o6(2Rr$)f~fs-$\,YRǃ iN4'gVSJKʓdԦE7mr*Ls<{X~섉̳]3:NׂՈoJ!N4HT0EIT?.+ XΨ i 9 < AHpK›wO[" ۧØ {('tzHwË')Um_{9Z cJ E * +zfYj73~Ӣ>~)ȵ> aA"xg: cr@ $ >]&e#|X6 j7~)0h=cMx֦|XO iEOx#F͝WZOZ/דaf] nz*[sWkL]LW*\=<;aڸ}UD})kDA~JU>}*٧^J HqXexh H0S] M8ΩjGGlG0S>OXBtt#r^gI]+LYSSսWZ_ZGƄﺾ2~u׼sx GŤq{ȧz:Isl=a߼rrCb:{%{J sH[1߃ÿޡ endstream endobj 9 0 obj 1933 endobj 11 0 obj <> stream xuJ0Fs-XfjPvo|}'mc$9%} nQ0[cЗ(Z.ɉ!ҙT(+&ȡ3EKk|]< lw87>υ拷ӺпKA!<3)QIcлn3cM2ofO%8UL-J",5Jtyg endstream endobj 12 0 obj 244 endobj 14 0 obj <> stream xݼ xTչ0^{Ϟ'Bv$& L &!&!re&L. D DTFJ=(F=VW+9`޵\O=lyk_!3څ v7z쑗B?G;Z) G9n-B$skl[RHB<^:Bu{*{+="/Sz Ǻ? Q S+~{w޷ [pPɺ#pgvFcS> b9pߋp3a?3:z^ЉzdXmt=ބD_Ҭ)rjZzFfVs)(hEŋ?a#G:~כUڂBG~ y=`}904: x 0 y]׹m#ղGI[3tz=IautաZW;tvZJF-%Z&3o\S|Uq#M 9$;Qo+]?5~M\}'u@oPZ?|3(Vufwx:L cdԄvPc{Q ~vA.N _FHu?OVDyՎX哗/׮㓄#¬3__NyTZT cw0 eڔ|p"|3*ҽ&GyƮAҹscN{=3՞ƣ~4rP~?t9c EГuDQ b VŐTtq|1{1\+k<ޔY(#RqQ=(U×xS+NiVUx\FԩlUQb@j`IxʀCCyȊ7g;m~{>Pt`L?}}Y{M@ (iφM/37G8 Z((8/];.W.|g@bGq~ C}ٹМ,w¨n=M8xg.Oa2aNZtm<Ӌa}tc{OU^wvisӏywP .ȷ3vNoXBK@u8tC-<e/Uhᛦ ȄoK~ѧ&>|D"B 4F@&ENϬcnJ >wgw1B 91ȁ,PxPѵ]8d:*ν`cʕrw䂳`;٠aGZ[qa_8a&O<ã^;Gsy0CG? n /] 6u*{^;n^]( fsz?*3'C_B7}( g\HޙL@o77o$ 6SUzRf4uZ%8~-?TǞ?̝{of玧G@3ZgTX_zQo W|<;dH8]6sR Cܒ3]zႷ`-6/egH fgåljnOnj^ov;w>Bŏz~W"d*K#@׈$>$!wՔ Jv7偭/IQI@tZ( (P峌΀[[t,}^}@o=՝j=sxr} yVtWw&{&>}578lCv$xX CC&$Cm[UyFiP 8+vqEID%ArK+%(\Px@d˜nӔR̺⺙Ty3"\&^ZZV>GxM #i8i<^9@ `F2iv ,/3M&{7a_#>LMse95YN^fg36T6cjsq{:d@^v\q3.;%[NNN````ِAސ!m]iL;~,|,Xڱv=~鄧ϸθxx$InBjQeE,zݚ\<y?7?z=ÿqض w=}t'۶nZ_x|W y#E~KhX*˿en. )hq{.X>m w!2dC M<{cx/e|DK)g+](P rM\\i{bgH7ɍqTN_j>souO)>̷͌>{|eHΉ ?M@.<&(%hrnACbe% h87\q3v~l|LKf,K;GYէQO^NR4-}##SY)v2"cSˉ|v$ (}N ,Ire&L8K{ (iΜP!{Kvk4:?70PjcK/)т F )[iTy[=>zL4Eo;OY[u%3o 4ߥB4Ez| ꘝ`0 LJ9l&|f59aͪ?,V̠tp>qC|t2_OVA/B$Y:7J/uZ뀡{ڟ~?G^^9$uvBRҝh`46]d-p FX\N,92\4b[hIr:$D#= V7h)u)V#&esf`q_g,vJƛA610!FXY@^4茢hֹt':uKz0L fBsp!˘n+͵g:\[N˅bCqyecUpPn,7U+,RQ,w݀jq-WKjZVW+k u:GUi/l$0$6 -Ơj xAv nPR [[L歖֭m66G̹uYv_vKMX5b'&oc?÷mUFU.)6/`/qoR[@̶e4&=텘df-HŪCF;0qpg :'cw?؍8n(;o*GZEd* У}}=):C.nnǹqm΢qM'%񲕶4|rGhKCw|n߇?yIt_Ǟ]eg?0ڶXMvVcqVE v.Џuc?Dy%o7UEZlu%}{g2E',:ҹG7;a_TZt5i64]IT/vHbUšUjj-{Vo!$-EFze8 X9?>zF..*KG h!jBb(dZ!z<҇sF:TSɾ~~.liL͞ʪB7R9,+g"qrOL}Z**ء}@pԟ&GT AtO )?8idq83Y=E2 a">T$@;vvY!c d,4qNB"|,q'em<4%CNƤDdB`ivw뷣jrMjTgi<2Z( IҺ UBZQ\o]nCmb=ht߉ O>GMfmKLL$ӔicɶfAіeIe's˹bTJZn[֓:ruӘkL!bailmI-rnвŤ=H $F{L{Xe˵۽;qowFZ8|ҤIв;}ѽ{>}Wڋ3߁vv*۔^Ӑ2sPD3{ؠv{ zaɦ7譇 9$f[fQ{lzY PF$$ZQr ,{DA)f ~#mgo֛QSS;TeB:6?&M[M* 6G}6'Kc,{Fv}ݦs>7,`YUg;M.08N8mKr%999,km>˹y.;ǓZ,9˓ RK̹ްθtIfncJn͎giJbiHnruϾsϛNz@9w v<]Xr'Ə㳏wUFG'.>q:h.W4.]^{(H-y$sCCί$ ,e[#zyFi#?'7ɽ򴳉)pw۟M3`M%y+CUܱln㍓K(Cn9z*57MoIY9ٶ,D.Z8jIf8f(asгHEz`eT:i7~BfӧW'aexX}is◊"U߇X+yd$ԁNz=;A_#5-tpS[}OcŎOl?ǿuk_/W7[yKmsh~|9-U@w.)T$f)&A:t|g%i[ՋUWWU/**^T Eܨ6DcO-(H2& 3qh¨]C?j h< ŒJ BW\TXYԂ&GMq+:II8[t70_ MUK"6I(qԊ #C2e6 dR]ڷW^(~*GIZ׸{ݻ܇(_4΃,kx'Ϝר}uv^שcV`kAگY6 +$PFGP̷-&`LS/E 7d%fYfYps-s&iM Ӹ ?O~?߾?q᫜,D>CMG@H| I*'eVT. Jj!Hz# U S$^-p CpPʾ8<PO1"*{ ..0+Jk?m> as$ G#ǙZX(.Rpqvv96;687b#;îmNGNS.h }4 B}U.Km\+6:\A1:[]1q@sveLzjl9!gWL< :L>SS\rdi0B7`zHVͰU_pa,'@6Vu~jG7/D4pnl\G2k&e8p`GUv*rzHIjJ}CCt4vDB)g3ih_oǕ?Ox6=#gzAN:SP;Pa2Y/ZϣY5ݑ[M'&'lAU'$5%e2Zڥy,h}]5HӃl ᩃd3S'UγЀmÛGAQ׏~01~w딲ͽ7LP˙ǞwwbQhQ ׃täifJF^!s6mصYJ~B )%B5iQAמZkЮ]8Byƒ{rok'˷ͽ8 (y埔?^+@BЍ  l$A/ 栺̶X-XZ-o Bi ZL 8$|i3!j7-hGf6+>6n ?pQOdtKMǥp)&51eXsKME*Suwm Zo5Ŭ=M zA4UoKD}z%њpEr K,0]k^h>[A2*(+FlAѺٶYliC!Bomvcw~UL1ˠNFA_ģʓʓG\x!nxoO=ğtOI 4VQ={Q]`.tM3*[uJ[MymBE+۱10qVB;t82 %5ӂ@Ǿ#-UÏ~YvГZֻ١R;w$'hU l7X6C L_ՔlV=9KY)4L0ջ&ge9_^zF2DGD* BJ_Q$;ןVR~?{OP9@|j"|[ěx3nZTymy4vzr'WAJ<<=,zS/iKL=8+j7hkwxYҹZcd)(g.*q9b5˽Z.k[A ="a(& &zzy0=XmnmOGClecͱeJ _^/ZيbBw9ZWqHrUT&E'z}\ohѽ޳>),u!CN[et 9N'Eը7r 6HH"$[e0wX3>T U? .UtT.:h%!; 16]2xשvs~T`/tot}k#}^DT+|. CFCaC^&Tʅ8spDx뿺UF;P"Z _^"E[a}8z_Dck`ZEw5t( x9Bu`>}&qoB'p>⣜>$CpφKM'G,euzԪ$Zzuv:M\ R(yśm~{)ᦄ]LK5}SIID7͓zuf `^j0 ߥ:p4vk %5bx\Zc|/ v0J0~S12Oi0d7<`Y4X5XD74 4h0A)R am f`(M_`yLT_'55`z`q y-,BnN`0_n HoNA2 ܨ tj0>n[vN7 kSڢ=s za|@nt5kbl2Ƀ=`}rw/tU`o6Uymajh]10=is08WEGjcCFF{`oG?]D-qzI*i@2H3LX ѿ+gs)OIuw]He`[//Mb;@Nک|%D([IBc5rso/XsKW>PW(9&w4PLvSzi3Ji?E=*Y%>_NƏ߰flA H uQ*55 rKznMceiYVRi~ʆ5kdQWRӰ^^S.Ԭ)ej5ureumUeU֬Z[ZYJ^j4UՕ a [,ȪVVmɊʪʆ~,%rmI]CʵU%urں5eT֔.ee Zv}]媊?,jAPWRZV]RwRXٔ\petq}EIUΥYUhmMiICyERL XYYURYKKKVOmBiL.XUVSVWRkVVRXYWك$+ԗݰ`^| PHE(V25.Ӱa+rI]e=%n K +(kATy5TGtjҲ*@XO\m͹B?j &Wc 3x8tiE6KGֹFqU54ڕo\tzuiO֤(LL0~-Za>w{jg0 2㺞~X>|汸#3̪?ÚTgjKNwҢcWXGۘ<bfahڎAgTsq%je{a;Ù1"ÔǢ) |6 3}eJbcu2YTd܎ۚ* 57>,ȚT{t{Yj8ʝ!/ZKe28I70xDǴR|E`ifT_=Ӥ(7Xߴ̬GWʧKy3,j|1%3R.Wѯ齋 AT"P=o|2~se i.4CWA>*y1m+W6Tߩ"ϴ0Nu@&U$Bۙ{4Kb,&WL׿J{L2h 1|{QZ OجTigY){ &k>mL̢;w15/0^YXU#1-/MJ}֠t#ԓuY%PF+R>Ocx#Rqo{=P2wEזul2Vf10Ze^ 3 z2WۇٔLӭ+>e}bteJe>qio1ywO1*\V̊S *Nr|U!8ˣAr ?^^ M򂉜2s \d'<) 9gFV \"# yjBo%{,|E4ɷgOo* ALrdQ8I_Osɡg $k1Cn?Hn3]K!;$ag"uU찒[m-N2l#Cɠl7m[ea%u`U&H f~)dKEآ^ {IN%]|tlDB:7 H.-ShD|[& % V7iQHB6 M ٜKnV&t=ٸlPRN!7*Y s HP Re"2M/T$dUNR eQ(K$+Bi'YBV:ɊB"%Pb" P9e|aY5nKztQX"K#Y\o"ŋB,@!E׺"\[uP$#)Ps%$/-%|l&0 s <`b sA3'_)!s9$>dZM$#!dԓtX >MOR!uS삜@| lb')F2;'Y6A|$|/lUG"nKpw)\NyS+Di Ϭ KxBLpc ,$FcA AED; n`P@x@'3\OBIs/6_/{T endstream endobj 15 0 obj 14901 endobj 16 0 obj <> endobj 17 0 obj <> stream x]n0E .E %9!c>P K# Y^;m.,3Co/ylaQ~ps)\!Fu}|k3ey=>nK^gϸv[zt)|s~_caXTյ9Lߚk%~y<ǔ)(#cMvmj07%d뢨z0tSNcE\/`K`Gނ=y.6xy~!7•J6-قw_8/uG.;0+8kx__ ӿN7RgCgWpD6w1J +a;k%`pvC{3p3wW 7+C:6#&,'Դx?6K|䏳[W;`> endobj 19 0 obj <> stream xZ t\yo{5ڥ4, #YmfI`yof,`H 0 !j7T,!vICKSB)ImЖ}wph{sggYU#?.B?DΈ|3 [{o ~ 3s0#$B< 9H7Gۗ!T&ĚLܩ]_ /xi(sp'a1KeJ`Ÿ'wzPf\H )t\w7"TR\=!N )ɴx)ؿ8xO%dlPR:X^QYpF"BP(v#@9䁙7Z@  At|>i2a#h _K^A1ti4|<]2t}=ƽۑJqFu%F{tL"%&8Oy8m 78h|z >E WZ!6N#hO@ǿ@`3@x]VzYIWR`u,B;~ n7 2J8dk& .yvVm+,3bM8'+ũg &y$[ KVq:w:`λH2iw:V< > <vj}mcmscmcG&JVRLg Mk1m\Iߝ_ho۷fӖ۹of;SD@QWZ3FhUxՠ~31on3,[ 5\wp\6t'M'0_ u5.?"Drm^/Dͤ4XfmgIiHT]:ZSi5W5KR›/y8>049^y~th/[ٹޜhm~0c J+~']jҁ|FJ@HgL\8DϾ 5k2|;"Ļe_)a Zєxw+U/)dCZ\}߾شێ򎇂w^6flh|J}6*o޾i)wS jo;Dfn^f}bZZx-Z}ߒ@Jh/|_<4,ٲnx0Biڐ!8/ցy0MqIu)U<Iϙթc&.;{W[7ծZrb$~!dq} H&eu+†:@o3}w5M]ε+kwﴗmg,ErWqGmvOkоMim| Iʴ<)rZ:u~i߷OZj7p;j8j[>ꎜ$Mp*-ڊwŘ͎4p"5MڣUיIItP{o͎6+]3ߏm^ξ~ c=&\d::}PpJ?>Ė-`_@Gs@6NDvYBqT,[[a<\ZKi6i'Do$9m] r|jv[}+\{tv.y\nomsT=r\Χ'ԐƭF s }iw5j5F_w-^lݸ"%0T)2CҌ"?qFAyFC5+A*ʸ5$kQN|㋌PMF~h?b+]*/`t)+_Fi/_h_>h_-)e43Z@0Ք?R4\Pcˌ&h<(c.A3T4FshN 8Tͣ TYqϊ{ 8TVq5Re\N/Q6tpYMtR8l\#v8<:AԺ]Xq:!P=4Y@;vOx8!{Db/AB}`n!G= 1@r{L@B`3%z|C_ޕ+\^E{\^Bg% Ifs4 B/q^.ʐf[oBVoP½ ظ%agѓGpEd k}@ui_y]P%G4Jw:$;T)@*RwstD 4Ql:ivT͌XZQSpRw+q+yF= 'gS T å*{_k GmaQ{P5YO%V =G2Ypr ԉ8S3 z'|Jtm/F4$v\gBWT'Jj|Azy C 76xdƿwPlf iˡ#k$3 Ͱ>&\d8eC bϭF#bOQ᳣]9PDsFa.IkȆ8VF]w), &S=֫BJRT>*^0 =?C:3C^pi­W*`sQi戬L*2OA?TejЕ>b},X ;9X̤3 Vς72 CkmV3t5g-X^gYEd@ C&N#OOJ,RBi>s._-%g;"լ]w:=:m*_љUWhTr!@{fEY'aoD8TS\1%sS28<@wII1I;C!Ž iR@ˉ4fej4߷swrMͥzDGݜSqUDs4d棅=Fiց_|܌ܾy()20Fysќ{ϝjsfdYr YSs<)&Ϊ%|^oЊzѣ,嚎lEYvܙ]uEn$$kLъgeL?ۙQ=ab TrR;C #bgF>t'=ts"<Fuм Y7xDt$!阌 m6K9=T D7̌нFu{nѽC/>/XZy6#cvy?{vLtvGtDfG= |^Ƭ{1zgB`p_>c!A~:{6IJL+R%oKG`Gsc9u4BS.FP$x9=EYxԒ"5ٙ:rzi|NNwgztXN(BH2{9XuSG! =v]Y!n|ht/:)ڛGAHQ8s(t|s(iz+g{z<W]N8N&߷ŷ­i)7 R ¬ޟ37ɕ CwۯL]PJ#™S{*Ge3uK5u4wBnev3!e/;[qzƷOA.O?Mbߩar2i~V u+>##6PAse\Kio}6Lo~Vz O$]g߃ߣJ4ϔh-^K6{K_U"|W/wx9>I8ց7- ?oj ?&{>/5~ E>zB8jG*w'dGek~T_ڌci_/[n^,|IZlU?o'v^ swpO3Jz|gwiwMq4;OCח w;l@ݾvp޺]8x> endobj 22 0 obj <> stream x]n0E /E#4BJ!H,PI?TêN[ Й{GuTu;tJXp=R$Br{OLym0jDnXE=<0RtQuV`eiLʒ ܞg_w[n{g6 4ugf S#"KZ4MI@$ ~8iqs~F>>"g+c 9ȧo=Rs@5r\k'"0(_q1`2RY_. endstream endobj 23 0 obj <> endobj 24 0 obj <> stream xz tו~Uꯤ$ZB! $PqDxlm@pM83p'q>glNC<3*Wխ؛=sl]u{Vx4!!#CȦۗCշ+.>x+|OG/peu Z-| d'4 D|@1 a"0s8t\oO#n :!_PzC]0DX$oC_GIJo]J#B(1p-k0iuz/MfՖchځ>bh%fXp`an;ݎCt 30cNgzC!%Ycz ̬fT&`#XOc ϽȔAу,1fM?E1HQD( ޣaGI=m#kiC>F03NbE<jF@$`$^M=`QoG!wgk]6ܛhTkfju`+-B57B9e-b ֽqVOisPij))rzVvs{ϲeT;wnӬRhLüE|N@EСB=԰¥Ezid]V^j+gѵsCj+h!12wQ.[[e2,De#zuҤm9|IIWK/0]Y6ame "YQC8^#33ʛpq2kS$ARG>-p6 m|!k"8aF뵦5`kQ.]&&1YJjv=w6cg/^Rʵhz{"kpsc1y70k" I"x*B W܋kϔL?}2{<qfB1c\i-PWˬyzlbˢ+dungI劜չV.X^Q9ZWkskFQedT-uۙ팍hbf@Knc/shue ze``ɭw-aږ3g^ԫ{džb#w=1}}C:&{;_x;/ϖKSzoX$W/ h;K;cфi@VnyZapVH8lY:Lre{T`_jw67jdz#x6*+"*&W^ v`ZbWS"5g"62r#߄2U27o3#L%S!Lc=z R([fa*Nd"q\ǖ(8^tfvP+nZhU\W5qUDIGiԹ|~!2Uo5^4 ԧ9lcbiџs"EVZ_nЮsk /xgJt۱xyt^{^w^p.j/./.F0UJkٲ/qC]м?U本~'O?gjg 5[?ڭY ̥g?!!^&u(У'cP@rL=2UҀFf @]X{uť$ Yn>7/BEXf[:CΔ0TR{- _G=A;S+;~oho/;^ 9q] P]kc8x_w0>6vw?ӧ~UT޷RX^qϝ.)C5KV?ҷ4K$= DŖ=Q 0u[?yPS(_ܭ߯9I>%do&HE{XmbU[u &*O98Uk@:c^{:UXW)Zk߸6L+k%hqȢ_yJK^y j]nWK AѮ2JKpіq&G]u71{D.ɳ~37ny]R=ö; !}]m)ҖXJ1.٘]fdXZhn`8rԷ"P+KO55RE#2mj#c':.W7_T:hnOVJm3^可_'㯿`^[p B:#ԏ+9 6 m Us s1PGr&զj3<6k&,,:%s&HaΙKo۔qmg t'_`^0xFq>*elҶ0g)/aעLnb[w-cv5S&@H9 1__kp]0u-֥96MArM+ϻftнzckb^(1 , J PMwP {ɯ ZָJm{!AB)l̢m D7m׾wL浇G/rӹ;A2KF^Br硼ql qdXrVi]sgS]v*_{24B)tWe-f1m"bBk̴ܹf>#滲Ro8scm O>.G6!,6&Ä/Cem[ p^e P!Յwb6lͩ&4o}wҚNgg-۲/DO${s/ _`^(;f/xy;_G󨅫E^܌k s#h5ST_Dh*zM[v?f7ANM+چW_#/9 zmS/i.5=;uiO贺zT<jmY;U(bI΍iN@[5S1 0qTȗb׷7A.k+(Z 4OZ[:ڽbwGwKcGl;:66{EGc7NqKw]&]Ell׷7;E.Ow%nlk\k{SۦZ7znUIz u0l\q-vB6]֦Mm]b禮Ύnh-]ųJΞֵNIjllhZ$v]"E)L6wklk״z] Xgm{bM͍֎vqTi\QdU[78 k=Lδ9ȆvOWcS4iRL=Xٸ &/CYJFou oG7-ʖnSlj&"tuğ I׮K|Dn"U=m@q.DgOV[)*IV)kC!!ɣT"GS-|@ti_. `ȏ0)&1p  3ؕƂzm3*u Fز;C1} GqT=fk@̖?*"pRvIJATU닯Hи8@AqhjDZ@mjԞ`V-[H&y04AhZ$_<T|rzR) i.b*ljks7@ XHR$n @ Xz"P"/epN"x1%I)X ,n86N8Pjb6&b{%X % nKviC١ךhhFDh/U@jSX1x`"c.bL%HkQ[qnngkRb/9Tk  Si803CmҰ/d6Zr*z&P J( 4HD Q U[%87$CAV0\"JӊёO 삻0y P،>2@1E }^<ͦMP?HO\06ӹ̆<.`Z N qv+Yf^RC ]T(0?OW47J49\a*apո E>)q*VJ=E`++$|L`GF8^?}ƨ\}ǧ`DeRӕ}VxaZi$ۉq% i%A圖O5X8]MdN5@d7Aq2A:Q~tFT*& !p3n'LYKH)+V[k"m$YQ7njgʆ~Z3CRG?NLп0@x'3*PTIW|@1L+ô2kѴn!ʕieր}"٧z7]SXC[3LQ}>gE4s˧jT3RKlLhDZERbS3.u~.@G4SIB<͠:ͨ>=Jx̶OSuʬq>d&vNt_U=V A75KGf*of"ZM޳wԩȈ6%wf34&|Hybnb1 vK9|JWdu J/gLQhwNVkofU1r>[s6I*RE:tUw̤ǔs1Dm;Q>Y^5G؟:|:P;y'Z+̉uf5l3K#]![&;&JKwBfmh=-׃RM1( 0OGv4&x-"ݨ¯vyi}DER/Os)U+嘒l:uhRzD~'r6RʄfHFGdv<;ڳHNuhuE@"Q<;7X ryWtR >t?ẞ*u^&4ՖӜmpT/xo~n*vR qHA9kĊĞmi̮ 4Q{ɛ)Fjj6;7T?T;z5=c+յIBS{%&2Du$\=jL5RB"{Sͦ߮z)e7Ze EjN[UM&5>;Ғʹo*Rxv(RgzS*awNW]8N<]gܙtW:3jmf'T78 ozVʙ5ΓJ%+=t>ڭev~ڧ+`,ݕ(G8ݙ즫g6{1W,MK/}[ b7Noz+\vS8v&DKz+z4t4G#;UZ5*(JMۄX@u+8G@Pb Ǖ_OZj2iWC(?WHVs[oSos_(^ߑ<?>tc|0)7ί؇ϯůï _ ~ߵ;nor.g_( O\)>KϞqϺi>=~:V̝odq'7g3"*<s eT!~҄?q;.'=q?1>rq7ur|쨍;Vr u 1#n"|X_3G exȏAt_}}5?`_9s_qC<>XǿaǗ/ b|\/fs#xlčxԄG 2n?_{G{۹16KnI7^w];qqdQX pkpHA[xǃ2/>엱;d|W..X2 l-z"Ņ7 ]yBU7vrquxt s}xC0opm\"׻0>jܺ}x-[<&Ņ=Fc%Fܴ&k:Fk܇K یc+*xڎoWs+m+<" /n>v/c^fs *8Ua\2^duF+Ƶ*ڥjqUNa2zWp]-<^fq9(?er*p> endobj 27 0 obj <> stream x]n0 F#q[oO7G3y5 No}?Gooу^2>gLݼk  ~ endstream endobj 28 0 obj <> endobj 29 0 obj <> endobj 30 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <>/Contents 5 0 R>> endobj 7 0 obj <>/Contents 8 0 R>> endobj 10 0 obj <>/Contents 11 0 R>> endobj 13 0 obj <> endobj 31 0 obj <> endobj 32 0 obj < /Producer /CreationDate(D:20071112091704-05'00')>> endobj xref 0 33 0000000000 65535 f 0000041158 00000 n 0000000019 00000 n 0000002815 00000 n 0000041302 00000 n 0000002836 00000 n 0000005034 00000 n 0000041446 00000 n 0000005055 00000 n 0000007059 00000 n 0000041590 00000 n 0000007080 00000 n 0000007397 00000 n 0000041736 00000 n 0000007418 00000 n 0000022406 00000 n 0000022429 00000 n 0000022623 00000 n 0000023167 00000 n 0000023560 00000 n 0000030206 00000 n 0000030228 00000 n 0000030433 00000 n 0000030790 00000 n 0000031013 00000 n 0000040181 00000 n 0000040203 00000 n 0000040402 00000 n 0000040797 00000 n 0000041050 00000 n 0000041103 00000 n 0000041855 00000 n 0000041940 00000 n trailer < <28027FDD67B8EE519D78ED0E6C15E8F3> ] >> startxref 42127 %%EOF kst-2.0.3/kst.pri000644 001750 001750 00000003050 11544160206 014203 0ustar00synthsynth000000 000000 TOPOUTDIR=$$OUT_PWD/$$TOPOUT_REL OUTPUT_DIR=$$TOPOUTDIR/build INSTALL_PREFIX = $$(INSTALL_PREFIX) unix { !mac { isEmpty(INSTALL_PREFIX):INSTALL_PREFIX=/usr } } INSTALL_LIBDIR = $$(INSTALL_LIBDIR) unix { !mac { isEmpty(INSTALL_LIBDIR):INSTALL_LIBDIR=lib } } INSTALL_PREFIX=$$(DESTDIR)$$INSTALL_PREFIX !win32-msvc2010:DEFINES += INSTALL_LIBDIR=\\\"$$INSTALL_LIBDIR\\\" win32-msvc2010:DEFINES += INSTALL_LIBDIR=\"$$INSTALL_LIBDIR\" win32-msvc*:DEFINES += _USE_MATH_DEFINES QT += core xml CONFIG += warn_on !win32:CONFIG += silent DEBUG_MODE = $$(KST_DEBUG_MODE) contains(DEBUG_MODE, 1) { !win32:CONFIG += debug QMAKE_RPATHDIR += $$OUTPUT_DIR/lib $$OUTPUT_DIR/plugin } !win32:OBJECTS_DIR = tmp !win32:MOC_DIR = tmp TOPLEVELDIR = $$PWD INCLUDEPATH += $$TOPLEVELDIR LIBS += -L$$OUTPUT_DIR/lib -L$$OUTPUT_DIR/plugin #If VERSION is set qmake appends '2' to each dll, but we don't need this numbering. #VERSION = 2.0.0 # use precompiled headers PRECOMPILED_HEADER = $$TOPLEVELDIR/pch.h CONFIG += precompile_header # similar to qtLibraryTarget from mkspecs\features\qt_functions.p defineReplace(kstlib) { unset(LIBRARY_NAME) LIBRARY_NAME = $$1 mac:!static:contains(QT_CONFIG, qt_framework) { QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME export(QMAKE_FRAMEWORK_BUNDLE_NAME) } CONFIG(debug, debug|release) { !debug_and_release|build_pass { mac:RET = $$member(LIBRARY_NAME, 0)_debug else:win32-msvc*:RET = $$member(LIBRARY_NAME, 0)d } } isEmpty(RET):RET = $$LIBRARY_NAME return($$RET) } kst-2.0.3/run-kst000755 001750 001750 00000000234 11544160206 014220 0ustar00synthsynth000000 000000 #!/bin/sh cd `dirname $0` export SCRIPTDIR=$PWD export BUILDDIR=$PWD/build export LD_LIBRARY_PATH=$BUILDDIR/lib:$LD_LIBRARY_PATH $BUILDDIR/bin/kst2 "$@" kst-2.0.3/config.pri000644 001750 001750 00000003760 11544160206 014657 0ustar00synthsynth000000 000000 # Define if you have cfitsio - not used on unix HAVE_CFITSIO = 0 # Set to 1 to disable usage of cfitsio - only for unix DISABLE_CFITSIO = 0 #Define if you have dirfile getdata library version 0.4.2 or greater required. - not used on unix HAVE_DIRFILE = 0 # Set to 1 to disable usage of dirfile - only for unix DISABLE_DIRFILE = 0 #Define if you have the gsl library installed - not used on unix HAVE_GSL = 0 # Set to 1 to disable usage of gsl - only for unix DISABLE_GSL = 0 defineTest(LibExists) { lib = $$ARGS unix { !mac { contains(lib, gsl) { contains(DISABLE_GSL, 1) { # Overridden, do not check. return(false) } } contains(lib, cfitsio) { contains(DISABLE_CFITSIO, 1) { # Overridden, do not check. return(false) } } contains(lib, getdata) { contains(DISABLE_DIRFILE, 1) { # Overridden, do not check. return(false) } } PKGCONFIGRESULT = $$system(pkg-config --libs $$lib) !contains(PKGCONFIGRESULT, -l$$lib) { message(Could not find $$lib disabling associated features) return(false) } message(Found $$lib at $$PKGCONFIGRESULT) return(true) } } contains(lib, gsl) { GSLDIR = $$(GSLDIR) win32:!isEmpty(GSLDIR) { return(true) } !win32:contains(HAVE_GSL, 1) { return(true) } return(false) } contains(lib, cfitsio) { contains(HAVE_CFITSIO, 1) { return(true) } return(false) } contains(lib, getdata) { !win32:contains(HAVE_DIRFILE, 1) { return(true) } GETDATADIR = $$(GETDATADIR) win32:!isEmpty(GETDATADIR) { return(true) } macx:!isEmpty(GETDATADIR) { return(true) } return(false) } contains(lib, netcdf) { NETCDFDIR = $$(NETCDFDIR) win32:!isEmpty(NETCDFDIR) { return(true) } !win32:contains(HAVE_NETCDFDIR, 1) { return(true) } return(false) } } defineReplace(pkginclude) { PKGCONFIG_INCLUDE_DIR = $$system(pkg-config --variable includedir $$1) message(Using $$1 headers in $$PKGCONFIG_INCLUDE_DIR) return($$PKGCONFIG_INCLUDE_DIR) } kst-2.0.3/build-kst000755 001750 001750 00000001004 11544160206 014507 0ustar00synthsynth000000 000000 #!/bin/sh cd `dirname $0` export SCRIPTDIR=$PWD export BUILDDIR=$PWD/build echo "Building Kst from $SCRIPTDIR into $BUILDDIR" if [ "$1" = "release" ] then echo "Building in Release mode" export KST_DEBUG_MODE=0 else echo "Building in Debug mode" export KST_DEBUG_MODE=1 fi if [ "$2" ] then echo "Output directory of $2 has been requested" export OUTPUT_DIR=$2 fi mkdir -p $BUILDDIR cd $BUILDDIR qmake -r $SCRIPTDIR/kst.pro #qmake-qt4 $SCRIPTDIR/kst.pro -r -spec linux-g++ make -j3 #make -j 3 -w kst-2.0.3/dataobjectplugin.pri000644 001750 001750 00000001365 11544160206 016730 0ustar00synthsynth000000 000000 include(config.pri) QT += xml TEMPLATE = lib CONFIG += plugin warn_on CONFIG -= precompile_header !win32:OBJECTS_DIR = tmp !win32:MOC_DIR = tmp DESTDIR = $$OUTPUT_DIR/plugin !isEmpty(INSTALL_PREFIX) { target.path = $$INSTALL_PREFIX/$$INSTALL_LIBDIR/kst INSTALLS += target } INCLUDEPATH += \ tmp \ $$TOPLEVELDIR/src/libkst \ $$TOPLEVELDIR/src/libkstmath \ $$TOPLEVELDIR/src/widgets \ $$TOPOUTDIR/src/widgets LIBS += \ -L$$OUTPUT_DIR/lib \ -L$$OUTPUT_DIR/plugin \ -l$$kstlib(kst2widgets) \ -l$$kstlib(kst2math) \ -l$$kstlib(kst2lib) LibExists(gsl) { win32 { INCLUDEPATH += $$(GSLDIR)/include LIBS += -L$$(GSLDIR)/lib } else { CONFIG += link_pkgconfig PKGCONFIG += gsl INCLUDEPATH += $$pkginclude(gsl) } } kst-2.0.3/INSTALL.qmake000644 001750 001750 00000016403 11544160206 015022 0ustar00synthsynth000000 000000 Installation Notes for Kst 2.0.0 beta 3 ********************************************* Linux ********************************************* Preliminaries: 1. Download or otherwise install Qt 4.5 or greater. 2. Make sure your QTDIR is set to that Qt installation. 3. Optionally update your ./config.pri (you probably don't need to do this). Globally installed build/install: Follow Linux build steps 1-3 (Preliminaries) 4. ./install-kst [release|debug [INSTALL_PREFIX [INSTALL_LIBDIR]]] 5. kst2 Locally installed debug build: Follow Linux build steps 1-3 (Preliminaries) 4. ./build-kst 5. ./run-kst kst2 will be installed into ./build Create a package staged in /tmp/package/ for later installation in /usr: Follow Linux build steps 1-3 (Preliminaries) 4. ./install-kst release /tmp/package/usr Command line options for install-kst (all optional) INSTALL_PREFIX - Installation location - Defaults to '/usr' INSTALL_LIBDIR - Library Installation Directory name - Defaults to 'lib' release - optimized build (eg, -O2) for release (default) debug - debug build (eg, -g, no optimizations) Note: It is recommended that all installable builds be "release", since release mode does not set the RPATH directories. Setting RPATH can result in a security hole. The default for ./install-kst is release Note: build-kst and install-kst both build in ./build, so ./build should be [re-]moved before running ./install-kst if a debug build from ./build-kst already exists. Note: installation likely requires root privilidges. You can separate the build and install steps (only if you really want to) by, eg: ./build-kst release sudo ./install-kst release Examples: Build and run debug version. 1. Follow Linux build steps 1 - 3. 2. ./build-kst 3. ./run-kst Build and install to /usr/bin /usr/lib 1. Follow Linux build steps 1 - 3. 2. ./install-kst Build and install to specific location (/usr/local/bin /usr/local/libXX) 1. Follow Linux build steps 1 - 3. 2. ./install-kst release /usr/local libXX ********************************************* Mac OS ********************************************* Building without Xcode (out-of-source): qmake ../kst/kst.pro -spec macx-g++ -config release make Fixing the link pathes (installs kst frameworks to /Library/Frameworks) ../kst/misc/macdeploykst Starting Kst from command line: ./build/bin/kst2.app/Contents/MacOS/kst2 Creating a dmg in /build/bin: ../kst/misc/macdeploykst -dmg ********************************************* Windows ********************************************* Using Qt Creator Bundle (Prefered method) 1. Download or otherwise install the Qt Creator bundle including mingw 2. Open Kst.pro 3. Verify build settings 4. Click Build ------------------------------------------------------------- The following methods are not being activly tested, but might work. Windows using mingw Note: This process must be done using the windows shell directly. It cannot be done within cygwin or msys and neither can be included in the path. 1. Download or otherwise install Qt 4.5 or greater. 2. Update environment variables for build. a. This can be done using the Qt command line as installed in the Qt Creator bundle. b. This can be done using qtvars.bat generated by Qt and included below. c. This can be done manually following these steps. i. Make sure your QTDIR is set to that Qt installation. ii. Update your path to include ..\mingw\bin and %QTDIR%\bin iii. set QMAKESPEC environmental variable to %QTDIR%\mkspecs\win32-g++ 3. mkdir build && cd build 4. qmake -r ../kst.pro 5. mingw32-make Notes: Be careful to ensure there's nothing else in path that might interfere. Cygwin, msys and various other things all have individual make and sh executables that are slightly incompatible. qtvars.bat - mingw - Update directories to match machine configuration. @echo off rem rem This file is generated rem echo Setting up a MinGW/Qt only environment... echo -- QTDIR set to C:\Qt\4.5.1 echo -- PATH set to C:\Qt\4.5.1\bin echo -- Adding C:\Qt\MinGW\bin to PATH echo -- Adding %SystemRoot%\System32 to PATH echo -- QMAKESPEC set to win32-g++ set QTDIR=C:\Qt\4.5.1 set PATH=C:\Qt\4.5.1\bin set PATH=%PATH%;C:\Qt\MinGW\bin set PATH=%PATH%;%SystemRoot%\System32 set QMAKESPEC=win32-g++ ------------------------------------------------------------- Windows using Visual Studio Use a Qt build with Visual Studio. - open a Visual Studio console command promt - add path to qmake.exe to the PATH environment variable: set PATH=;%PATH% - to build Visual Studio project files call in kst: qmake -tp vc -recursive - open kst.sln from this console (e.g. vcexpress kst.sln) - build, run, and debug kst in Visual Studio ------------------------------------------------------------- Windows using Visual Studio & Cygwin Note: This has only been build using Visual Studio & Cygwin. The following steps are used on the current Windows build machine used for testing, but may vary. 1. Download or otherwise install Qt 4.5 or greater. 2. Make sure your QTDIR is set to that Qt installation. 3. Make sure your ./config.pri has the appropriate settings for you machine. 4. Start up Cygwin's bash shell - Required due to command line length limit in cmd.exe. 4a.Setup environment variables in Cygwin to link against Visual Studio - See qtvars.bat at end of file. It can be run as qtvars.bat vsbash to setup variables and start the shell. 5. mkdir build && cd build 6. qmake -r ../kst.pro 7. nmake 7a.If an error occurs, you may need to update Makefile.debug and replace "CXX = @echo compiling $< && cl" with "CXX=cl" 7b. If libkstapp fails to build the following steps should circumvent the error. 1) run nmake >makelog 2) locate the cl.exe command line including application.cpp and copy it 3) Replace all \ with \\ in the command 4) Starting in the build directory, cd src\libkstapp, paste the command line, return to the build directory 5) rerun nmake. 8. ../run-kst qtvars.bat - Visual Studio - Update directories to match machine configuration. @echo off rem rem This file is generated rem echo Setting up a Qt environment... echo -- QTDIR set to C:\Qt\4.5.0 echo -- Added C:\Qt\4.5.0\bin to PATH echo -- QMAKESPEC set to win32-msvc2005 set QTDIR=C:\Qt\4.5.0 set PATH=C:\Qt\4.5.0\bin;%PATH% set QMAKESPEC=win32-msvc2005 if not "%1"=="vsvars" goto END call "C:\Program Files\Microsoft Visual Studio 8\\Common7\Tools\vsvars32.bat" :END if not "%1"=="vsstart" goto ENDSTARTVS call "C:\Program Files\Microsoft Visual Studio 8\\Common7\Tools\vsvars32.bat" devenv /useenv :ENDSTARTVS if not "%1"=="vsbash" goto ENDBASH call "C:\Program Files\Microsoft Visual Studio 8\\Common7\Tools\vsvars32.bat" rem Don't launch batch with --login so it doesn't prepend /usr/bin to the path; this stops cygwin's bin/link for overriding Visual Studio's link.exe call "C:\cygwin\Cygwin.bat" -i :ENDBASH ------------------------------------------------------------- Windows Installation No installer exists for windows currently. To distribute / move locations. 1. Use the build directory with kst/bin and kst/plugin only 2. Copy mingwm10.dll libgcc_s_dw2-1 QtCore4.dll QtGui4.dll QtOpenGL4.dll QtSvg4.dll QtXml4.dll into kst/bin 4. Package the build directory or use from this location. kst-2.0.3/README000644 001750 001750 00000000256 11544160206 013553 0ustar00synthsynth000000 000000 This application is used to display scientific data. More to come later. Please see INSTALL for installation details. Please direct questions or concerns to kst@kde.org. kst-2.0.3/docbook/kst/Screenshot-kst-datawizard2.png000644 001750 001750 00000034204 11544160206 022750 0ustar00synthsynth000000 000000 PNG  IHDR=sHPLTE    (3' % /F 9H&M4S9"I9)951112&-6#8!@ Q b'j8Y![)>[(Cc'Ip,Ms!Is Ir HtGsCzA#R-]3e;mHrJmUhvbee]e[TVTSYRRTRUTP\Lz6v9z5.IDATx}liG-*2aZpאmѼtlr-]Nѝv733Rk9i`GjwgO,\DhvSA$HA%(a(" VGY${Ď]v~]O=qO}^ /|W?U>|ozo 2^BPe]yƚu7ٴ$lnĩJu9ˡgD#7 y_DNtgT*]҉SCL繦S%i3T:}lPH){WۻޓJ4T }sה/wyJ=S//~"V~Om)OTՏ>ɰ  oxy{o>Y /oxaD/XRףH^o{sJ6ЭYU|ėr#<\M6Ln8y>ʋ5{U5VKyv 54VHFsGͪ3(M!UFy߽SnCML˴G/hUuw/;Lj-S]g<γy/\S׬"(Ͽ"۫ߤ{~eo ixWڷ/>+Jnk92<'oM<煚k;u7:ayɯI# xI)<|oW8ʎvS_ Lݽ}͛7oz6ްljjhjvB+ ퟷ I |3Q|vQ+ 9 sNYWݍ{FIͬ_755]8_ j?B%5JR;)KDksr($xG>;ggY gX;(E⁷wNdD{L&9ųODFŴ߃JesʦoTOL7=8WSB/;k.xkpN?6wtsVEJllyM1oPtyh/tyFԮxJ:?o?^j%^zm+4ϳcyy6nkIz5ϒa+XbpnegˑC-9IAg>HۣƄKf']DvxgMckp!6<?C34ԛ>Fy-PYh3ee3{k%7O͊C\flY-!w'<C×R,?%Z9MJw6 &Kxd>y Bdӏ>(4]0XXyijgqcuyM3xPl<+M&ߓs!h-בpQ3ޡ Da|81q!Q#q +,eJȳ=(2y?`+JPyr K33lpqPx Wrs2Yqe9z=IyNOCZz7JFL g6C>ar(<!uspHL+g?ΝTr,T2AA+ ENjyaL~&ykn0nr(<5#Ni,Ől&,}wyOn\sWT"υ>\Uq=| x. 1Ĺҍd*ad9ҲpT'0JoxE=m$·8Wq[)Y{gGMxRT¨*RvgZg?I|I9{*R7 hyM;|gA_4&,MɛC]ZY2Nug+<3Qnhr4sJ" V[xѭHY2)eu}&#S 3e:jNٓ7eqow/S1S %TA2F-鶍"z,, bwViGr)i3x8J9_\G\o6.y{I}ɕgN͋<ݏ;uyI~UJ,ϺT<>-ΙS[)=Ӌ7,lN`qIi%0ymEƗZ?i.j);Ϧ39+bETMNq"_1ty^S~UʚG}R wT_=VIG|/ >l%46φ5XפR$MʃH Y%WN)ᘈN^Sh,vތYe<u Y wuLilAyޯrt8uyVI ӭܼ0yUY!F ɰM!= B|oHUQ^a,yc4tlJ_ϪnBV gs9MU}%=}ab1y&+ k0B2Ҿ43Yĕp7yZG"]Q!Om*CjXW9o2"mK2( &$I]Zꦎamxsziu/_W}=žʘlu2<[I!&`~v}V'Mo"ƺX6E(vrKο|vY\@NZz|\΢<ޯ Uv/TWx3\e3e3GU;a@+JZRt38:`iRxdgiEQ{3kh_ṭ\UKs~U_)lub<7Mΰ 3\es Io`&ȳdPNHyM]7ztiop}>{H~GٗR,:z2{*%:aub<^JTo(zjQI|3? <%?+igI_AM2T ,ƺC<I Btu?%j~}+Oj0 IU-jvVy\V׻:r{àk׻l w?w Ѿ^|P]yӮo}|K*%KR2}>{͍gnQ8ɿ9w|"r0^z5 Ww;N^Ŏ˸ ֺtylq 7Ww^yWk[K>>r8Ww^oyEݶebs9my)<|"q S=#[U0?eI<5;As 7wb~7x|su<͋+ܾrq}! !3x3xxv&.{od;U\E՝y&@C-PKn3TZ?CYS!]9xi<'k;٩qlĹs *񭮍os Ɵ-m6γyXT*{}luVZ 3ySobYBs_gY>oG /VV+Kd>]@go>촶oLi٥H ӭdԮxTjwmT W[y>UU*}ZQVGsyY5|'+/D-nq+*ggkf?JRj>3Y#P@%Q?/V&z\QdA&-ǤK,E+FVӶGJ4x^ U Ɩ0;+ᕯD( \~c$$<9Z-ܮ1xvmtL3_MoxMgM&&s>%EHҥ^ZJL9Cj)8uyj5N5I;'W#l{3fs>Neоk.qĔsKx$ȣvX$+y3h!׎PDEPj(-*EPCYiTOq9 H Z>i{2f&cTKOmZ9~dgKڻg#n8uxYPgٙADT<5N$"1Z%4q(󩟼IAP"(jzTQsHbDue7BPӴs! W>M "*X!MI16v&cʒ] CgyٶnhZr3 ɿp \dy!@LDÀ,`VIQp. Ef0gFg49 T:PXYM,7~3%vF'?h0e.3S:;(X9f Iyy.̦TQS5Չ0E9Ϟ噵9 FMX<)S a-g!a 0/~CGӡ,x) a@$;LX<d3?da`gYg?U0) Cp%\~3wfU4Me.3ow3>=f;au{js6ێ#FpbgLGsx `y+TbJ5<{:ү8]Ts|-Pލ7Н`>o,Py g 3x.w}}槀rC\V}b2_܀L$ղ){eiy>}Z ɇKIK9!`~>@,T/dff^dѡ},DNsx΂gG.nž2݋}f-sH-i9%gl~s/aiJ0 T iy06ŃlxΦ}v 4-W6[;.FNH-D\ ʳV+!u'3?mô T&_*<;p 4/.5lY츄62w-n%l39 /1]wlrE,i9›-ֻvV,xv2`Yl6[f;.r+}#s]mde {tD<<ϳ]y1} fl%Wnr/ g5JK$E߰] ϋ%.e2q ?0q# OY\ ~&^.ljy3ʳU3,fb}#s^dC_Xa7׈|V%>,6"goLІ47j|VJyqYmv\LqܨT%W`Y UILF_pF\OY>\^(#wzKwPKn7nը<Ӹ )spt(Ƴ%AX_сs xΒáCs̳WźZ,mtv*O%-<@,= T̨" hEG1At \:ptYB ռ$@ϸ 7ߛHwrRV23g! A3gx A3!3*8x^.1*XIxD:>q-jܨg%=5͟DʩH92DrتdEfg^7ْ(x^.<2]F(f): n[Hx)5KD$:RMsHbO^<Ϲ๲y|n-s5 :CGRH"Iw͕ϕs$Գ~Mtc*JY̱yyTg/`q e<%Dž$xhuy>~>r?(˅$xt1U! Kst"> ]> The &kst; Handbook Rick Chern

    kst@kde.org
    Philip Rodrigues
    phil@kde.org
    2004 The University of British Columbia 2005 The University of Toronto &FDLNotice; 2005-04-14 1.2.0 &kst; is a data plotting and manipulation program with powerful plugin support. KDE kdeextragear kdeextragear-2 Kst plotting plot &intro-chapter; &tutorial; &commontasks-chapter; &data-chapter; &plotsandwindows-chapter; &saving-chapter; &eventmonitoring-chapter; &plugins-chapter; &miscfeatures-chapter; &license-chapter; &commandline-chapter; &creatingplugins-chapter; &additionalformats-chapter; &dcop-chapter; &debuglog-chapter; &install-chapter; kst-2.0.3/docbook/kst/Screenshot-kst-plotdialoglimits.png000644 001750 001750 00000026603 11544160206 024120 0ustar00synthsynth000000 000000 PNG  IHDR8\FMPLTEĂcvdi]tXU`SVVSVSSVS:]2O(: 3P##a44Q66=662121/11/10.1+-1'2%4=a=a!>a"Bg!Go!Kx!Kz!Lz K{!K{!L{#L{#M|)U/\3`DgIhKeUMVMzVSfVWZSVSitÓĺŽ¾Ʊĝ_PIGF}?s7o6s5{4~8<:99=@AABDIJKKMRRSSVYZ[[_acht艼-tRNSԶkB* IDATxOY~cj}nĘ}X$#;$}-N:\0T63ӭn[09Ao,FPP"A@##OD~ReFDx/ދ|jꭷFzP-}xOG> :0?#TS=*etﮪ{C@ 8x4[-wWܽ:.;2vF?; k\9w 8̱MN5pؼ/ӟ|b}zow/ :V|:8 c].sY_"xL_w?/h/FKfG>M?6{Y!.?3nr|ȝy;I3cp~vv}}w`gF]0 nc/%\J4Ƚ* 8ɡn(NF7~3L^ͷ Ώ/K)%^LԥѧI9CE@ Bn'|oNNa< ?Lޝt:_l8?$M΅<ȅ4 ?dvr|w>9J߽;f_jgT9_ }?ޒݤ -ȥ4t_cNO'@ɭ* t~ bE_}1bGr0HEŃKtp Mp`S΃ФܞD/q2nss='8ESd8a;u:/;\ܙ|9ى+Cmq02ߘ-AAK`Bm!G.컸'.}DK\}}p10 2t1 B,&\rr3>՟~%˗lt(>z:d|||e{C@)sj pPcp_PM AB8-g/Jʳ7>}/)#YI]) קi/uL;E5t`L~QH<丹/Wwv.Q @dE}9>쥢jL8Rv}6Ӳ>KyK22s#&8P,x2XIQ;z-sk-)N{ +a87 dLkr'յi{׸ sVqc'9Φc؊Աm/o>8V8DNQ/ #9ǀANs}e胅ଌY,C 'o~ `g9i 88a,"n'Lfryu98ѥ]^#%-N' s]7솖{܆ּ18U[28 U7 ۙϹȱ^NZ 34MNLNW4]+8)!ٝ p Nց5F8]svcxٵ6pF},ㄕygׯQnxTV]見[tg,kzVy39NO}z{U[N8maZTe p ՑÜcAp App䇢{z 8wgvXqԚK+0ylVvXqlmyqf-3]mU|LIG5UR i Nۣ}rįtrΒɝ1 Dk}Q'~{ȣ&h>KQ.X£je!mua[4 AAuMvki8ecvJdfvO5grprʚx viܚ%L:$H D)8sRnf&\*8%}S9819MG*8e ,jq I 8px;4v kqDzi$^ҿt=LU+~Gr<8qG pT[uQmTѭwQɓHqc$ݚ[&*%,Q8y8FU3\歏\->9nA"pΟ> 3r'rsO֧ͪF'45}W,}t<ӞӾUg~pfc9vVJp*Gۿp=UyTsg n5qj3xp53p0p 8p YjtѤEXbUHSrVTH/}|tj"Fz*Rv{WH/VVS?Ez4t~PN=TxspNWΫՁҸEfKp.Bqzb7ԍ[uQZo8OWk=כ8|ٜoMe_Iz Wat{LzSⵏ+Wm#0gVR㪑:s]AѶڱWndr3c/8ꪴ)BLZF_W>yqjH~ -%R|\Ad23g*A)Brkj; Z;j]?z] ihMK˱", F}s}\{f;:/b=P8+)B<ί_`K._ u!,ծ1 3ou-jq|fsǨJ]sp•Њ}5TSbw԰b*8VylfBF2OwW8k'3BF*|Css<9h8p A8p ACl377V*7uAp A!A(5B[h&8MQ֨8hgƷf ?.2$@8Np_5pD[,Uc2,lq\ V-\oUs %è ps8p8pLb U'#㇁tHlo=p+9#NQ?|p UhQLjl/BWZ'g.q!DiTSMm=߂QUw<('zǨ"5{4T;^ϨʊG㔎 EXf& ո'.AkԊu?9/y]Du|_(XH3Y+8V8A8p Ap ALv{ l77{^3dpvovpg3UΰMl5KʒNqJfpӷ}mpVlD;ʊ2q\D5'=;g_˷Np&7ڶ+ⶫ5$m9N p6XV^7\max8r9d}8R7-i*mn ps 8**Y8MlrxkqB%MWK/Fq&:6p)pz3Ml ,SW稪 @LZ}TeUeTŭjC,9NsMgrx*i& ppguz!fn998p8pk/X66]銛eh\Wӑ< 64]Y (8`q;a sp ˮS..,LWbpZ37~ܹ릗rК7-롑nv.368979]iSkUcNgNW4]38-JgoXQQ9;K1ZqZVUܧ>Y9 +[@GU_ǣ*x*jͻ *nUxӝ )+r?9NO^vB;ߪguY\ Mp#9ǀ A A=goEp2. gvg{YzhcT>uΫzMK_JpVN4+Z7y>s3 p<[bNѰp8 "/̣s涫rM1ݹ3)3Rj{8]rc{tóoUNnq skspB-ʰ[ܒ^98OoK-'~g[Vpg]žp͢>NG|qkY>q\Y837fhm;5oyQDTmg0Z8KxR-~?p, Ro#~4p pp A A:&4Us󲱌S;%g{\zNN ^6Q05;G Zp}y1Nfjp7bpRnc ūU/N"N{~_ד\eʿ E5 K!*+d)$npN}~)8qNNs#hW Ȳ! }w1ϻN~Lϕ(g^2^ԗY'鮪ɹʾ1Ͽ(gBrpb7sMSrD([Kڳ[XB*6t0bF9Qp:8JZMkĮb7qNp  uhS CRhY9mQ$9J_x3 Ε; +_[3]98 eLU<~4 { NnM[R֊}pp $GɹG)7~3pLɹno8R)[`!8'Vc=^pNm1p:SܡℾnX#8'O#I8arX)>\՞>NfjVuTUiatbTu$Rܘ?IV6?"񾮇ɹ~ 8 U8ϓLUpMp>rDF^k C㦊1xqƍD#rɾy9Yo@rgړ~76l?ߪV aSEh#8q.l8{2NxƓcf88pHpn@6ss189hkrS8p8w77m>PEC8([]X Gqm,L#ekޠXAk!iिe=ުy /qC=T8QZ٭ pMNc04FUɭZsQ 8p 8plE[8[{8m-#pbⴃ8pp*sF)Y/8t'縹pێ(~3LWuC5BNqg؁#BBp^^qkJs8_<Nj7iV`Z4UNjVFFV8M<p A88p A8-87 gR B8;prCqGC-' փD\#wH)["*P3HpD]OH7Ĵ=T-88Gb66( 1{'uu%Z;pK{p_;{"#'8Y&'Ε[Uv_{x1GoNc,[զ|kFwu\[8JN#}T-.~bT5Xp*Hp꜋: <&rp8p 8p AS I9j,N^ '#;O `YP=QT|¥j=8N֧wYR|LW;wWy-VrF99U՟YH/ESo6$nb08Ӯ*zZp⤝nц$M8S Kwlizh RRײ0DD)dk&/Uy:|pNu-5y#K=p*]IUDK(sI n/>6cJH#+,IX :<J#VKbBp$j],JjQ~!8ee%&eC\oS%cQbckG +Zv%}0VC 82`pi5h͈򳎴7I8JcLIurrO@ِ#Z08'>p[vDJf NvJ@cRl8b5 u謞Uڑ$eR/JdǬːy)nwk%ٖxWyFSĖDRNN%JJ77W,Nm= J#Ҩ0771 ԌeOTI'UW3'iDE|c;&ɕjl8']ɶmHr$ The Toolbar and Keyboard Shortcuts This chapter describes miscellaneous time-saving and convenience features available in &kst;. The Toolbar The toolbar provides one-click access to commonly used menu functions in &kst;. To toggle the toolbar, select Show Toolbar from the Settings menu. The Toolbar Menu The toolbar menu, accessible by right-clicking anywhere on the toolbar, contains functions for modifying the layout, appearance, and behaviour of the toolbar. The three submenus available are described below. Orientation The Orientation submenu contains layout options for the toolbar. Top, Left, Right, and Bottom Docks the toolbar at the corresponding edge of the &kst; window. Flat Hides the toolbar and turns it into a slim bar at the top of &kst; window. To unhide the toolbar, click on the gripper that is still visible. You can also move the toolbar by dragging the gripper on the edge of the toolbar. Dragging the toolbar close to an edge of the &kst; window docks it. Dragging the toolbar anywhere else turns it into a floating toolbar. Text Position The Text Position submenu specifies if and how text and icons should be displayed on the toolbar. Icons Only Does not display any text labels and only displays icons. However, the text for each icon is still available as a tooltip associated with the icon (viewable by momentarily holding the cursor of the icon). Text Only Does not display any icons on the toolbar, but displays all text labels. Text Alongside Icons Displays all icons. Text labels are displayed to the right of the icons. Text Under Icons Displays all icons. Text labels are displayed underneath the icons. Icon Size The Icon Size submenu specifies the size of the icons on the toolbar. Select a size from the submenu, or select Default to use the default size (usually the same as Medium). The options in this menu do not have any effect if Text Only is selected for Text Position. Custom Shortcut Keys You can create custom shortcut keys to make working in &kst; more efficient. To modify the shortcut keys, select Configure Shortcuts... from the Settings menu. The following dialog will be displayed. Configure Shortcuts Window Configure Shortcuts Window A list of available actions and their associated shortcuts are shown in the dialog. Each action is allowed two shortcuts—a primary shortcut and an alternate shortcut. Either shortcut can be used at any time. To define or change a shortcut for an action, simply highlight the appropriate row in the shortcut list. Under Shortcut for Selected Action, there are three choices: None Select this option to disable any shortcut keys for the selected action. Default Select this option to use the default shortcut key(s) for the selected action. Note that not all actions have default shortcuts defined. Custom Select this option to define a custom shortcut for the selected action. If you select the Custom option, the Define Shortcut dialog will appear (alternatively, you can also click on the key-shaped button to open the dialog). Define Shortcut Window Define Shortcut Window By default, the Auto-close option is checked, so once a key combination is entered, the key combination will be automatically saved and the dialog closed. You can uncheck this option if you wish to experiment with the dialog. To define a key combination, select Primary or Alternate. If you wish to define a key sequence, check the Multi-key option. Now enter the key combination or sequence to be used for this action. Click OK when you are done. When using shortcuts defined with the multi-key option, a small menu is displayed after the first key of the shortcut is pressed, showing the possible shortcut key completions. Pressing additional keys of the shortcut further filters the list. This list can be a useful reminder of the defined shortcuts. The action associated with a multi-key shortcut is performed as soon as only one action matches the keys pressed so far. For example, if a multi-key shortcut of ABC is defined, and no other multi-key shortcuts are defined, the action associated with the shortcut will be performed as soon as A is pressed. kst-2.0.3/docbook/kst/Widget-kst-minimize.png000644 001750 001750 00000000456 11544160206 021465 0ustar00synthsynth000000 000000 PNG  IHDRЭIDAT(ϝS@ow  v~-&XXlAWlasT.*pYUu_OTDofW@p > ]i 3JR@eLuBT8Mԙc4L293̀鲉0vͱt`IC! π/e.}`2Ӥ!Әޘ MGgI飽3_Ǭ*FB-aI8|9?r}N\zbea|?SX|IENDB`kst-2.0.3/docbook/kst/Formula-kst-autocorrelation2.png000644 001750 001750 00000003116 11544160206 023316 0ustar00synthsynth000000 000000 PNG  IHDR}hIDATx?h"O]p !E46& \"ja 6WAlB @@ $H)"p]ufw_v !9~^gCDUUUU-#RǗ\X.TɡnzN*`VA<ƈFv\ J  f\n{snA[KGy` DsʹYְ'D|[6k=*` cyJ:V1U hzeU~f{_^Yܫi)Hsg 7.pTOl[ S@{7uX2C8=ӏ{ܶy*3U)^GZ;  Νpq &f]}$")䨈K+1n>;RU8r0bܛaB8}Xu[T݄t/#_X!?qn 'izƑ/߬@Zzc݆,~ #; m1Q+C_X>6d#Oqjw8IwwLk~>_Xt"]]{C֦^3QDk>xېU9gVŋ&蕣 ]SiU- Y oK+`cQz_XTŚn6dz "O`2rHGfbM7xڐU94@]c3ʑmJ9dӆ̦f} Hm"-6 !j-KRHtW# |EQ$(ՌE0x%-~.˽Bh8B%D<ВPߍ-$%Pi5&珐}+il\ՠ mW|ՠVmpU2aW ʐۆ_5Bn\ՠ mpU2B=`m @$ XL`52f_'h\N27k׈eƁĵWdƁĵZ)2d^ձ]ث|dˌ}c gP6cnB,u,QI/V u,( R"3"e2c_X*QZq-( +ؗ:pCfG\KG8` )3.5a`ʌkMjXGl(e^ŵ5l1bldŵ`+3( {q@qmD8ȌkQfP\ .2P$hPM(e+@7ٮ#ڛxrvj?@aٮ#M(er%(H H_ՋyyIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-datamanager.png000644 001750 001750 00000036317 11544160206 023007 0ustar00synthsynth000000 000000 PNG  IHDRs.PLTEIV K @6 />*5(1)<1D)Q g U G6. "   , $-?H{C5 $ %!3k%>\"Fm GrHt#It4OrTXeZZZ[[NWG5]@(_7s# 0?AS"j-y<>ؗB&/bۥ͝ӌyc߰{ױ~ϬΨeɟg×gh\rquowqn~e%;^1b-e(h4u;sIxZIGSci]S,6@@@@?@EIJJJJQQQRTTSVYYZ^cccfru{ۀ쌿ٚʜş߹hhtRNS| 9xIDATxylWˀlbt Ǽx,j ]iļ B6(7Q"Mn换0 N{q, B,꒑R,K@G B֮ꮵ]O>t_e(3C@9C엻˟/(e{I54 (4:r@#LN`Yђ=xOǟAp]&'Z=={TCB]&' eZB>߷gw?^.4JalIᆱM>}bѣN/Lt]GÏ;rDwdyg?&:c|W[5S^gͫ+Y %m~,[@KyU fw0j!'n'd?77.vxCIMo.=xwsW0%͏?#hѴ`_wnӁo ؄v^;lNI;=[KrJ8or#a&}wFzԎ `lBZSڼԩGE+d- 6]b(lsI;=&;K0.z^;Py{ibRY~>,۫_=hg8BlI@AUC;Ӈ|I1?rL68c     A A [{@9 =@+FeT&\ NN=..Z`J [q_-'`7O`__/8? }6qfxR%]-g/:R[ ㍇؍C[7y-)t$CŽX4BY׿Q5^HAW xe3-z$DTK(8wtPP/n jq-J=iElґ4Ţ4м ՚{{|YV{\K7JBST#BCt9 jW'ԳtJ5ҿRˌ Bm`ׂ},w׾>el+Dh$ZIZl]P3::@>fYxxF 6E;??W}@r{ SJODgFȢ̬DR(Jdf&)~^ШW7+"v:r^ 1zR*v3:FvKRCseb5ni" MlW}@2-mpp`5J=?VCJ <+ uYRֽ#zX ;;27筞(W;6+/HҬ-URa e~G~ڗ1")WK zvbyalvY+ʩ%ӼBŽ l;KJ-"i/}]&[W>E| /i*I[/& ce+#yCuD n_`qh*-eJJ=bVnJrbE7T1Lߑ\Rjp~(&7RbJvp\'`oM,dcdAOrGR:c*VSK>W vád$;b4+"m]%˝J;,&jPq``Ւ_&H КZ9z4Tޣ)Dg'V/uHm%Q9Dys %jX1wDԔX 4ؗυPg2,P/lh[8 'غjp|=y.'~/9iGaz/9vjllu&j9{/9vNhV&ZN&\NMCX?n~\Sˢ݇,8׿tNA/n)xGk~e';>^Qz솷jXO1= eɎCJ;n(,;؜e+-OKC/ xGu@kg|ΐKk;DF(H2.-C1o2݃_UXzsNz{Y5tQ{v7d[$x oW~bgWk.xw u>ޔKBg\3jM2;- 2&=@_> MO};o&0B,NF7H(U+xRY_\V|Y~ן׾~)zڿI2cgk_L]{[kׯu580Yl+1+X)?|^[;g\9."\>MsőrF^& 'uМl4B\ȶ_ }MWkulgn Y4/%I>Nb'po7_|)' !v{,C-RwXr]|}f5YnMյwo:\KCRtD!~}7>a~ zl9_OLyOY;NWuun~Ed;2cpcg Lr 3EMSzo;B @^ÉP]c[X1 7W+߆c\}6k!=lAR8u?6|Ry,q$b7S S/w9c쯃c32wx,-T#{/P3!~쨂ʏM-윫%gk}-;؁`~:2 ʢǶeU3_;ӏc 2Qv o|7xM/Zƻ"ycGmUضiOh?UU=ǦEy-ͪu`G׏-{Uo;uYtDLm@=vcg7]Uu6}mץl9Wmz@Ώۄ~l{ҥlĿHĆcb^;T.ڥKؗê3zlm3d۟wc:ik.m` θcg;U[~lfwXT;t~lvht{l B`kwErΏ\y ؙ,Ď&vc6KycmllX^cY i=vڹ laUP  2h@vV{llBʧs cşwS=ϢNm1ޤN?Kcz1;{llBÚY󾁝E?&[ʗ]>5vƏ9lͿ ʳ{S(mXU97|;p?cyc~Mc9cv~c۱#676Wc;W?*Uc9cv~+YmXӑA zُM{lL?gΏp% ?- ::Ziy@ij[q<̠Q\6-ĵG ڏvw?Q73f[ kxi!:{{ k?\73fH>oU WK?vX?6W/_Ud•@c;͠Dla~y1p%9\ 91|eqp*9\̏ `gWšp%G`>9\)X= ;בDg}CE"a/#Q3R t,6 |ͼ!{ T/&guܑɎBOCp~lSsx"ZS6Ը%Gdg5 4`H;ĎR$6< ;؆l*wV޴5T^d ACCc`%)?RR>d=V- > H!;Z+O+痟߼|z ״-ڼ,m3hО=qNWzl5R>4lKzU?j!;BgmAlfѠ-!SAn2hct- qka"Mk rK-S_lI sE?NAcǦLɝE\n.o@rh-^!/Zde[,*co2{,-nfy/45:M S`PV fLQi60SpCQV rN;ي8lP:~̮۪91]*`9;-mRjhXMuUFtns*HA[csu\kI- 5Ejukk_-~lL;MEjA-'+?/cDf)Ua5ji?DAyqKc| oz݋d|dd!/ZesӶv~mݫe׏mќ`=}s/0i."X&YJtF-9 9swu7^fЖ -ބ+%#C y /kΦ۴9;݂8PDZʴYJr-i}vWo,gh͏{ ȠAxrBMt-e z;YRjX-fDԒ| W +k\`/i),DMY\~ZҀm/a} `` uPc8RKIJ3+ u2[JJ+eЀrnp%cؙÕPѹ uP |c6WB-9)- |9]+~[yTo m?:3>[ ?v-#疙(`cce9g|!/؁`G+\ɾ+S0;9 %};4N̾l>0?v-`c+S0:srnI?f?:3>!A`GsU~l̾cݒ#cp )9 %l1`qA=`GŏPK 象crh+A ~\ W x>!׿{2`G7\Ic+ä́F_ 6,@}&p+@k+4V^NtaNry7!WZ 36?ze35-u~l orؗVZp%TflVb͋n:Mٱ\SЇ+ٰ-fl&:{^}/0 ZjmZ[ W@[ |``۱\v4Õ[ |fv{(@f~lv,~pTqf6lWeξ u`۱\v•R{lnwΆm6c j ة~lv, |Uա|qw$;~lkf(/l`CAh~l'H=؊ycay}l?6LU4|uK4-~l8~ecx{z?6m3tY_ܿXs1[A>~cc#Ig ˾ m?vto鮠~2id;J`Wu3?Km?vtÕL7K?U13cqZvIc)Ǿ 3?6nΏm[{>FJ caX0. 6oP <~H 鿟]? |q?1=[csv獅z;ŏm6n.Ds: ~lŏV $M?p)Jc c{Wp @ Y҄kf[yFh'J ;sҨP*4K^8v~l;s$•jo)N$/iv/,4JtN5+|c:),xI}`m:@f~l7)-ب~Mϱs?T|6+m=CE v吜BUs2_5% GM۸??WJ_߈o"`;fP93ت{SJiq9 o`;,~l$Zܼg-g]̏]qjT?6~Jn 6 ~l /3(ЪuP$HH]褆jl+7U ~lĆ}o_6+8_؊A>~KZ*ɇӷ[EtRsltw&CY3.52뱃c_ V?7`_xIv^B"IJ"i*[wş MjB(K`p%$•4X>d,=qΜADo"egy/8.5͔+crH@m 5󪇔x%Ďp%PV•0[paiRCsntPj=}1\ Y^lJT I%v 3]1,%ʴ5% rݷ09'c^-(E*e) Zҝ `]c_ջ" c > ص˫X<{g-ؚ}+l W8L6&[J? kI6JLҦА}•@ W$XDYDŽ 5-h%,Wi&S!J ;S*ҕp E&V6 < I&^FzlB˼+! mdHK l{B•@Y<a~ldU]y;Wԇ۠C]yTolP>D6(`C(  `"6+rlm` 6A6ApnrlW$M!\ ` M<>•@'_G•@[+_ WElct^t;ؐA>\iԥJS]@?yҨWڷov|D@%/DC,"\IGN*m-b1J4? Ii `+J z<'!i`qmJ#@%IfƢ 6rtRJRbi&tMؤ_([Tұ+خ{lȠyK&tOp"%Pi~ojcf;F6y[*Vc8ص۪2(Awy{04 `pAE0|}a  EET{6(`C A2h@6 IaUPn cl`  >!\ `C(7PL`Eoe6(`vm.jp%Y*z;^GvZJ-•ގNl•@[3?vx J d( f4 `p%$•k= mJxkD/v2Zl]P#+INq2V=  [ W<`=^*r v#;ʕ|@Cs 2p/Mfz)CJS9$%$AY[W'u\zd`K_5_A6*_u{E+.H>$hAd( 6WBdg` 60# <疙ElWؐAlPDp%PN rl` 66A6 lP>5+1-jA`` 6} A A 7`_@uʗq7v]i߈اvX@\q1NxUe>$?ӟ7b PP.Gy`8qk=N.脟olv2WNfr]_G !4=SgL{30G汲uGj\9a]P_RH_jWN-+cCvvjz m$:R_q>` sv1Rx:}G8u.<ZS .\ fJj;uf^(ީ9eE[U+Ekfʗc&[\T⇯31b/glZ"}JԿOZPo$ )-%lpPj$G#M:HWOQSuA>my>.>-t#u[Xl9;q>]aljC;\źҿk7J+D8E26>#اg-Gc豿O?T\վ)yՀtϘ3}%g}Ħ[ش `H%뱇"Q+<IvJI&=lmt)C l yrT Z_ԇi%}׉4W~cxԿO[fjJ&Zҿ7`7JLJ&cxG"3E;#_t81ӗă+gcuZ2{ĝD[;9[UAKӽ4`ÝNԔW Ԕ>6?ҵ$j:H-,.lGL\r$jPqHᑎ6.a>w|+q_bLW%6-lCvNCs:tmƘKFOvnKT]w/{g,FtXS Xٺ-;`ocV}le% m$~=fg/>YWjDڂl< 9r _vy12ÒGd.loT= `G v,+?ӟ7b `G l)W; bl2c63A킩y&7n~=W6~l     A A A _`1~_ ?qDIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-datawizard1.png000644 001750 001750 00000021257 11544160206 022753 0ustar00synthsynth000000 000000 PNG  IHDRe PLTEĪ~ί}ԳٷݻྉŽƒ̖Рөٸۿپٽٱܩީާݦܠң~|zvuspnkjp}hvp}Džǀ|yvsrpmliged~a|_{^y^y_w[vYvXuWtXsXqUqSpQnNmNlLkJjJiIhIgGfEeEdEcKfOhThLbF_A\?X>V>T8N6Jy1Es+>iSWa\\\]]\_^\ZZZUTRLLLCCC<<=38D'3L124''' $7VtRNS5[IDATxSTWǭ"9U HE@Ry >kkg*SIv&٬'֮3kԘdf2D1 A$d7͛ D| "hysݷMH~R~{ϒ% aDہwqI{`{OⶱtϴCn`0#uuG4%e=姚'F`Q.4z좄WF(e *֨qG%xh%|kT4L0q.NKW^fS55iWż]EAǶglT⦦S=²fl˿Z[ZZ\%-'N8iE4gD5JdJmFr**e|ɢJ.]aK_Q͢FEu2Y48ˣ^-hqE)<_wM) 5쨵$-芺6qEmcTD*6eT%o_ۆWF7slT]^~mzU:PDIE2XF%+UQ\GJ<4zQ4SQM2:x4D 6AhSmKi S3NW] 4\!D%5YTj/4ks_78)w/~^MmR[~ -sU wt\/D%JQ*Gr2*Uej5*jYɸfD=*h\>ƕiʖfKUt8ǢN ߹Kۭ _>^E鬚`zykU*Wuv+evkPdJ&ˌ-emmm%׋Ν;'%2xZLF9 *2hxTaQKGzlYD%.&y],tu5]ձ[=vjךw1Q'W&֪du9]imrOȦ7_N#e IJe|ˋ/-?d.7F(1LE <*Qej.5*jYQE\֤┊f-jxp={ 4KΟ7zF:Nvuv+:~<.Jڄę'ίAqUmz5dT>b*j7ڣPFV5tEaDvg.REG,[d?+2g{{{_׋,kZbLE9 4y8YTYZE W:,h6hF3kǢKNJ'~͎}tɿ(v ;8xs۫c,j\,g:+jW/TF 3_MjW`jPf,oԾ e6*,{eu\N$}Ⴛd;wd֞VŽ~Ys`wƻݙ[z;xwkWkeұk׮VE_q|[ce.MkWk8v wvX{2̮'vb'kd~,zzDtwӧ2vKJe.nY>vZg~/ |{7EՃ10LOM6i]k칽3Rk'y#.g bKDtb<۽8+-q A.ׁ :bk7TE%YTdaؒ/U5Ek,T˥Ӡ&d\K-lݭ4Ϋ`wKo,1xc-3;qZ'ǖko[/8:NKy+,ϔYRU%TRYԸ2L e4jPZ҂S̲E` s~?|\~`x <[[T/gE 豮_;v]iUg%t؃ZGǪ_c(k_| `ԚI*6p~xVJE;J2ݲN5ZN҂l8XAY)5G%#*-qɢƗ~Q4:xhDkFgFja?}&k }.}ا&mk9M-;cyE,kcQƹS;j0.)+¯rZXn]SZUb jT .UL%j(ms]z"m[$H\^K#Tq2X88]:N ؘ/c}c{zĢ7b~]{:0-GzX TXfڵ{晱-]E3 幃D-?XgJjjjTu>NբGq8Sb()Q΢&*Ω*j-Qmƺ3SyF6/~*fJ*)`U<) ҴA<ԜqSZ?ApWUU)r:WOTVV>X 3< (%Ru,j(Qcj4*XK*<*ja^rz!uϔl-h1BR<<)$]h|V ݚ!dgr<u fam-^C"ߐFb =q|԰̳1fd8aY*Y;JLo@["[wLH39Z"Y+˲HܽTvVD*߲uZ9-[GYdITeY:IբcSÔQ`e?g(+}YyҾ,$ P`E$Z-+@K!wTG&s, &eU$1 fLfхܑ rr={n<لܜn-[9Xg&̥h)"ڧY|>Mb܉nlMo9ۉE4u1Y?ט_DyM-y6cY0!Rc!rlױ[a5UrhzޝC˼YZ"9 ͯ/;2Er-䕋+;˝D[hO.Yd²;w&QQQLSX蓥r~rJ+sDHlޚm&CʻO~x ˿)i&̖e#$HRzewr0lj%sS^b܉C{ւ6B1CDE̍bŲ8@,Ee_et?az9&isLҦHYлG'(-}PO~Z%O=,qdetbk3]]Ъۉ|QL#\\<3fYXNQ()PLkRdQUƩW2nxKEcS&T!9dd.)]~'%ӛgO"%7Vu\_2[&Rzeouby_fb}g}'ybEfa-g;GF1Mb]cOV}_xGnW}:Kf"s~"}VG݃z^z/~V F$尢22tUܣ YMmXf*-L b \2v ѓSQ" Fq;;gM_l,er1?Řźt>Y [a̯B&xި"{LM'G۬ԑlޛ6x|̊'i{>Ejp|2cxtL^te'-RY7W.X,vOx<,2s3R0NXIz`x86N <2,+C7210='8GaY5{?(`ቦg11mcp_$#x{L?p9ѴLOy@"}i >rO0C548P,MIM|y;A_Bl:NTh:S8CbHg1LGòL_,+<c@Xfܓ_EqPcҊISܲL(>8NTh:x8CbHdbSij:ͷe;},Ku@<}"'},18P_:t7FZ!U7h'^4Qiy";l2tfLi?ѰlĘ;},2@<}e8B3 Kyؤ(Wh'_j:S8Ck3oNSi8Ϳeb̝>/] v#,EgX1hˡq݋Ugcgh~m?}1pLu?5Jͻe;F{2cgy >f23Xz`.,nn.:ljex8Ck3b|OݘJc?y  1Nwsڻ2@<}u!XF>}iDo#Fh'^6Ow3346;Oc*|ca,1wˢQl^mʊIFGղys;56з ` 2`e, X` 2e, X`e2eX, 2`e2,X` 2`e,X` 2e, X`e2eX, X`e2,X, 2`e,X` 2e, X` 2oeFZ/eOŰ̾>9\2X˾m?NMe`,Kv2x8 ,{ߡlr<`e瞺$,,YOoe ԖQɞϞ> @-ϚVP^щ=#? Ԗ n{ 4g#`s។mc`>!l3.M زuG 4 V2b˖?cǎme Ė=9ww]|qcm`eoGX`e2,X, 2`e,X` 2e, X` 2eX, X`e2,X, 2`e2,X` 2`e, X` 2eX, X`e2eX, 2`e2,X` 2`e, X` 2e, X`e2eX, 2`e2,X, 2`e,X` 2e, X`e2eX, X`e2,X, 2`e,X` 2`e, X` 2eX, X`e2,X, 2`e20:XЁ;&se2#nbPƲ!my*ϲP~\IJ63ť$7N^'!-[4sʍ׭[Gv̰7j1I)_@?ʟeqҸyqx}ai dF}VW/M_Nֲ̝+6E KMZaYL]~yp =>ZVB[FGI*laSsٲã2"VgA##W1k=P#Ӣwd,#$#[>;ByY-7LMLHVO#nB_1wVebiqևG&flLQSXHͨČ lUZ8IHa[#g#6zkٱk ߵw/}߷ x2gX:MVҞC봤^e Il~-S]gMt߲@eeBZ=X_!e aÛ@0 |,C_/o2enIJ6<f7_c,+yX, :63~2}4}7|:;<;:77789999::AAAAAAAAAAAAAABFJJJJJJJJJJJKNPSUSRRRRRRRRUYYZZ[\[\\[ZZZZZ[_bbbbbbcdhijkqrsssstv闪攢ֈσecbbbbaWM{Cp=h5`.^-[#O~!M| L{!L{!L{"L{$L{$L{"Ht!Bi >a%?_/CY4@N59@/27%.9*:#/ W-mHpIqKrLqtRNS`M{IDATxMh׽v]9? ټM YHnVޘ$o)9Ik>Jr;iH73_|ݦNK W#HӮ777O{9kZ@Eq9hj:dho >N7>63ͭ{83~4xg݁(vڙ3i|t|~%[?l]:*)HPQ'3C`qqyO799p6l urrb":t6L;019DEp~)x9x~6jY% w.5TR+A~Xֽͅt]&>@] wWiI[6M Ѐj{qXq\%54ǣEփ ]4wlUm <> ea@CAPwriSU-PI*躯= 2޼uUt4záA_`<)كaNapщ!7~=j ]AojW/o^l.߻_( H1G2U| )u|j*JpͻiVI4aJ<>i?ZXhz^/a5t P:'mᇃ/*c5WIa`zbi\X2ɅRi`gߝ \02Mխh ˡW&î$GPL3l35KÑ#Q?y4؝}9<4?4Hp^x~u%9.^ Go ^[ܾ}{"ۍ{z}n:ġ=윞=rM-4L'o2 c־.hFnN$3#Zbyj@dؾ۳7#hAkOۙ>[3uݔchQfh=; j]Khv@;hCKsHWG񳶪hjo'J=YhENKJݹ^JQ,؞YX'P.c ]vs3/8[9LJRk6זkΙɗ];hv@;h]>__%@<{ڧ{uM{w=tuǫ_)qHԘŚ٨'[qC{]ng^.{fd\odlUmQN2)ih΍;L\dcbH˂]Wx*Q=y,/G>8ОJdF+kwiJ $5 HvwKt\4qiO`iOӍ(.[M[X 묖%(lusdwT7dSLeu.2n+2c6TK;ב;.f9H'vg;L^X:[&<,!k6Wi\WfEUZKWSҽS_/;[ '{.tuy=(1hG;ގvZ ֆ-鰜+IV~1̭B]5s{=l^<)qH4x+.5׳QO"ɱph^A׫^; Ub:ɤ 97 ܇3%wCZ,P5h펧Փ 쪌;황Dftv&vgj]D ۽]wَH{RK{nly.T[W({:vi9 []G~'ժoɦjG.D]ll]`lwj7HmkM5fwٙXf/4Gsdfy4+iގB.]A/ڣ;vޓ=yhڡ+B~2 r?-^eˮj,2˹~k/2 ~h^yY;yN,,SDzwV´2 <v@;JZ,oDiw"oF9eby^~:2 i:j`7^,Uf,e7%fzn[}Pbַ*юvv@;hCKhwlA]G=lVd)P%S)P== ­=]=Ir|m[*;k͟NF3xj䫢hv@;hAs6B_3X _;>?7kb2޷}o>g6Ƴ +hoS^phpQpk+@ Q[5X$[Kз?={hewk>|g׵{:\ÇW޻~myjWKWw՞$OIYqQyzњY.Z1WjF|aF%F?o=|G}RtIIDsngV%wCZLz>lo=ҵvSa^^}ph=3Ȍ.V>=A!H2|~?C"RmvEړ"Xtc+"r{~Wﻶ򤗭+^=rRqxϴ7Ouzy'}6ўXMՎ2]ԉ n+2c6TK;ב;J07G+V_l>fMxI9;k쥳h"X6osue֜_1YeOGϿO^ ;%Tч_=o컶TZ"ogc+}ui/o=z/wE;pz _x:h_YwS8p`}6R}n}>$v,kEU_g*(\B \0 zhvx^Es-ޡr]ڡv@;hC;BfBd̏9TyHAo߿sW?~?Wh#wYꓺ釽Hƙ$HzN!j%v{Dhg]G;uN׭ƹ`o}k]']>6ox򨟛t{}ښ~sǯ.p2unf={hv@;h}~W&rUY`ޓT^\alU'pVZ^\alUCڻо3=T^{*юvj}{;zͺi7kp *9"giG{o$_DӾ\q:H֔Ua9}UIKS_xUDT^{NճՎQ&먰̧j@$Ob]OIv>=[{Zjմe=TK|uRm[ی?ORg۫vHP %~8V KNOڋBIG sld.%_7 k=[J,(7δ'jz_f4T8zim?G{^TT.Mˈ>F[aZ(qdaڭmF'Y$Qa9SA־<> Supporting Additional File Formats This section describes how to create additional readers for unsupported file formats. If you are not already familiar with data source concepts, please read Data Source Concepts Creating Datasource Readers If you wish to use a file format other than those currently supported, you might choose to write custom datasource readers. All &kst; datasource readers are regular &kde; plugins. Like all &kde; plugins, each datasource reader must have a shared object file and a *.desktop file. Before writing the reader, the library name of the plugin must be decided. This name must be a valid variable name in C, as it will be used in the function names of the shared object. For example, the library name of the reader for ASCII files is ascii. &kde; plugins are not the same as the &kst; plugins used to manipulate data. All references to plugins in this section are to &kde; plugins. The Shared Object A datasource reader should be a subclass of the abstract KstDataSource class. Ensure that you include the header file for KstDataSource in the source code for your datasource reader: #include <kstdatasource.h> There are certain requirements that a datasource reader must meet. One requirement concerns the presence of exported C functions. Other requirements are consequences of the fact that datasource readers inherit from KstDataSource. Both sets of requirements, along with suggestions and general explanations, are provided in the following sections. Exported C Functions The exported C functions are listed below. In the following examples, all instances of <libname> should be replaced with the actual library name of the plugin. KstDataSource *create_<libname>(const QString& filename, const QString& type) This function should create a new datasource reader of type <libname>, where <libname> is the library name of the plugin. A pointer of type KstDataSource to the new reader should be returned. bool understands_<libname>(const QString& filename) This function should return true if the file specified by filename is of a valid type supported by this reader, and false otherwise. The function should check the contents of the file for validity, and not rely on any filename extensions. QStringList provides_<libname>() This function should return a QStringList of the file types supported by this reader. The strings returned are arbitrary, but should be descriptive of and appropriate for the actual file types. Protected Member Variables KstDataSource contains various protected member variables that the custom datasource reader can use. These variables are described below. bool _valid This variable should be true if the custom datasource reader is valid. Most likely the reader will be valid, unless there is an error condition (such as the data file being unreadable by the reader). This variable is used by the isValid() function of KstDataSource, which is usually not reimplemented in subclasses. QStringList _fieldList This variable should hold a list of the field names in the data source. QString _filename This variable should hold the name of the data file this datasource reader is associated with. QString _source This variable should hold the type name of the source. Virtual Functions The KstDataSource class contains many virtual functions that should be redefined in the custom datasource reader. These functions are in the template files template.h and template.cpp, listed in the Example Templates section. Descriptions of the functions follow. TemplateSource(const QString&amp; filename, const QString&amp; type) The constructor for the datasource reader. filename is the name of the file to read data from, and type is the type of data the file contains. This constructor should most likely invoke the KstDataSource constructor in the constructor initializer list, and probably call the update function listed below to initialize member variables. In particular, the bool _valid variable should be set appropriately. virtual ~TemplateSource() The destructor for the datasource reader. Any dynamically allocated memory should be freed. virtual KstObject::UpdateType update(int = -1) This function should read any new data entered in the data file since the last time update was called, and update the member variables appropriately. The function should return KstObject::UPDATE if the file contained changes, or KstObject::NO_CHANGE otherwise. virtual int readField(double *v, const QString &field, int s, int n) This function should read n frames of data, starting at frame s from the field specified by the field name field, and return the contents in the array v. If n is less than 0, the function should instead read 1 sample from the start of frame s. The number of samples that were read should be returned. virtual bool isValidField(const QString &field) const This function should return true of the field specified by the field name field is a valid field in the current data source, or false if the field is not a valid field. virtual int samplesPerFrame(const QString& field) This function should return the ratio of samples per frame for the field specified by the field name field. For data sources that do not make use of this concept, the number of samples per frame can be set to 1. virtual int frameCount() const This function should return the total number of frames in the data source, as of the last time update was called. virtual QString fileType() const This function should return the file type of the data file currently being used, usually the same as the type parameter that was passed to the constructor. Alternatively, it can contain an error message (to indicate, for example, that the file is not valid). virtual void save(QTextStream &ts) This function should save the file description information to ts. In most cases the implementation provided by KstDataSource should be sufficient. Example Templates In general, the following two template files can be used to create new shared object files. Simply modify the function bodies as appropriate for your particular data source. /*************************************************************************** template.h - data source plugin template ------------------- begin : Fri Oct 17 2003 copyright : (C) 2003 The University of Toronto email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TEMPLATE_H #define TEMPLATE_H #include &lt;kstdatasource.h&gt; class TemplateSource : public KstDataSource { public: TemplateSource(const QString& filename, const QString& type); virtual ~TemplateSource(); virtual KstObject::UpdateType update(int = -1); virtual int readField(double *v, const QString &field, int s, int n); virtual bool isValidField(const QString &field) const; virtual int samplesPerFrame(const QString &field); virtual int frameCount() const; virtual QString fileType() const; virtual void save(QTextStream &ts); }; #endif /*************************************************************************** template.cpp - data source template ------------------- begin : Fri Oct 17 2003 copyright : (C) 2003 The University of Toronto email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "template.h" TemplateSource::TemplateSource(const QString& filename, const QString& type) : KstDataSource(filename, type) { } TemplateSource::~TemplateSource() { } KstObject::UpdateType TemplateSource::update(int u) { Q_UNUSED(u) return KstObject::NO_CHANGE; } int TemplateSource::readField(double *v, const QString& field, int s, int n) { Q_UNUSED(v) Q_UNUSED(field) Q_UNUSED(s) Q_UNUSED(n) return -1; } bool TemplateSource::isValidField(const QString& field) const { Q_UNUSED(field) return false; } int TemplateSource::samplesPerFrame(const QString &field) { Q_UNUSED(field) return 0; } int TemplateSource::frameCount() const { return 0; } QString TemplateSource::fileType() const { return QString::null; } void TemplateSource::save(QTextStream &ts) { KstDataSource::save(ts); } extern "C" { KstDataSource *create_template(const QString& filename, const QString& type) { return new TemplateSource(filename, type); } QStringList provides_template() { QStringList rc; // create the stringlist return rc; } bool understands_template(const QString& filename) { // determine if it is an X file Q_UNUSED(filename) return false; } } The <filename>.desktop</filename> File The following is an example of a .desktop file for the template plugin: [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Source X-KDE-ModuleType=Plugin X-Kst-Plugin-Library=template X-Kst-Plugin-Author=The University of Toronto Name=File Reader Template Comment=Long description of the file reader template. You should add translations in additional languages for the Name and Comment fields by adding additional Name and Comment fields with [xx] appended to the end of the field names, where xx is the two-letter language code. For example, to add Spanish translations, the following lines would need to be added: Name[es]=Plantilla de lectura de ficheros Comment[es]=Plantilla de código para hacer un complemento de lectura de ficheros. The field X-Kst-Plugin-Library should be exactly the same as the decided library name for the plugin. Compiling and Copying To compile and install the new custom datasource reader, create a new directory under kst/datasources of the source package. Place the source files for the object, along with the .desktop file in the new directory. Then, edit kst/datasources/Makefile.am so that SUBDIRS contains the name of the new subdirectory. For example, if the new subdirectory is called template, SUBDIRS might be changed to the following: SUBDIRS=ascii dirfile frame indirect template $(PIOLIB_SUBDIR) $(FITSIO_SUBDIR) After the required files are in the newly created subdirectory, a Makefile.am needs to be created in there as well. Use the following sample as a template, replacing all instances of template with your custom library name in kde_module_LTLIBRARIES, kstdata_template_la_SOURCES and services_DATA. INCLUDES=-I$(srcdir)/../.. $(all_includes) kde_module_LTLIBRARIES=kstdata_template.la kstdata_template_la_LDFLAGS=$(all_libraries) -module -avoid-version kstdata_template_la_SOURCES=template.cpp METASOURCES=AUTO services_DATA=kstdata_template.desktop servicesdir=$(kde_servicesdir)/kst Once this is done, you can compile and re-install &kst; from the modified source package, or alternatively, only install the new libraries, like follows (using the template subdirectory as an example). First change to the root directory of the &kst; source package. Then, ./configure --prefix=`kde-config --prefix` cd ./kst/datasources/template make make install Restart &kst; and the new datasource reader should be loaded. kst-2.0.3/docbook/kst/Screenshot-kst-eventmonitor-serversettings.png000644 001750 001750 00000013455 11544160206 026357 0ustar00synthsynth000000 000000 PNG  IHDR 0(GPLTEtqldcba\[ZZZZSSRRQMJJJJJIEBAAAAAA@:999:;?HPRQOLGB;4~6{7x7u7o6n8n;oBsLx_t}thhbRPQQORTQSUSSVSLYb2^.^.[$N}#M{!L{!Kz Kz Cl>a!8T*.4 %+)#(  DtRNS&m8IDATxMkImz_a: k(E0E4ri`҇=hۨQ uitw#U[cffGDddeVUV)y䪈,/ǛqS~._t´ӿ߅_wQ)Mfξȱ2]ʻcwXg"B}VN=o{|||-4gȱзj߅_|s:Zss/5ִqOl1֊R} 4BsOyv?J{FE%GqIbaa{v_;뇍޽=< L=Poz~ygކ`AwgwGa,F%GG>LΗs{|6ov>;NO߼ $̛,ȪFva$ oZMy72TEZ(P}Fk&w_ {5+N7NTeT ߐ7I.Q$Azpxh,uTӁο/1V-:gǝW{;sQn j£zvV ;i@(LƋI:=h8~2OUљ:SEjt^?޽6wOv_}H'vhMu2*xS̢lvk_#OUљ:SEB?<~=M]Elӎ'W}wc3=DY2>L?4Ӏi4`0 L1=v{{nz)^-`seFjgޚp >.A|\Z\5J*"wi:7WŐFͦMVQ*ŏEz]״dEI0ʒ%mv~ga9@ņXmm$fѧ Lt|Mb@.摹`v_P7 Qӵ>Mt|XTWctt5o^MMUinq]`Z3amM VP:[\Ocg{ض8Vq^ \ي+6 w8߀9L%7OC ](_]}e(WVjs~jLojMx{[0 z>'#~d@/`4`0 44ro؋R.z؛o@Όѹ2XWc/]| Ǭ<'ꧦ\Әjik וL/8HW1q^1-hq&Λd믤Ɋ|/t"xtItLP-/JW L/9"k$ sEijNɧc0=nӋSIE{6L7Դ8sAMaL[rVYb\qkUO\<6/tE6;í18ح<45\B%mzy cz lzeH+4^gk ~d[}ǧ0F0i4`0 hxY1Ѐ8`Ә1?8HSaiVӢEԻi/h9O6q붆mHUJd3b<8Lkc3hI+Mg56=tɘ:ҍwG۴ݦo۴xniզ9UtsM8Ɓڕc8Y({O0=.56#1=X#McӀiX{$E4eя  L0]"Z ixY M qӣ2` LOi}*38BuJ&`:zxJlycq h:}w}N:&m\|1:&Ɍl^L`YhW4Q;>oz熦ՓgĎ;i@|_Lnf+ѦGeT~wi-GD3mF_f {dUV#ƪzz$7sJ6 {d7=ȒQ02sl #[:#Ӏi4LiցAcӘ-> 12F&φ4m cv 4 '۴55d6׺ oFA4Nߋ[P N *pwbDҴ"]%mft℞ =NKylڨt39sxޛIȒh#V l9i+Xas{ ]` cMȀi4`0 e,uh7`eE{41=M2w"􄙶v*0LӾk,6)b/RL7,7dNv8#iKH2Fc=wN$=ʟTkܛ{d<i4`0 5MΘDC?2o(`0 Lt*h Z tc8ӘF.1wJֵM5]%ZGȮkq< 0G⋻?'`+Z'􄞑DKbz{G#ZG|Q`ksreFjgޚpXK0:W~FQ2 { ѹE14`Wl6]nZhShmk>ئ52LceKm)(r,LjSgN6TjMMj'%Vkj:ӴI^  ^aW2eDPčbU}BYmf4^j1t bNW?NKI[T:q,70ߦbzh+J,>NKaz-@WKTjC[b>'ďwC{/>%I5#]؊+6|߀6otXlz+Մޘ _Y+0ބp˪[ x-V}CӀi4`0 L1W|C"hLfg|GAY2ccqD zCybL|2iԴ ghsjO/yjh='iIs}c2Y7Cq4׎Jc粍86K0BfD@uc}}c ==s/oϰLWav1r~Qd5?t qjh#!`z>X3|z_m[;LHKj:SBmtWfCC:){ULO6Bӹ6YBͱ\ Ϋ@i25m:=N_/ZeZJE{{)3]9*>N_ٴOP d%,m{ #֘ȽϽst0dA4"cxӽ8b|s*rS}4 LӀi4`0 4`0 LӀi4`Ӏi4`0 LӀiLӀi4`0 L1 LӀi4`0iLc0 LӀi4`Ә4`0 LӀi4Ӏi4`0 LӘLӀi4`0 Lc0 LӀi4`0i4`0 LӀi4Ӏi4`0 LӘLӀi4`0 Lc0 LӀi4`0i4`0 LӀi4Ӏi4`0 LӘLӀi4`0 Lc0 LӀi4`9{٣f}ƟF-*Lu>T_4/éMw, jӁ+Caz@:Tp̍t#40X]iͲ|yM/rGziQ=8L/`zӡ ~l%++i{ ګrӮmhC-p*{6Ej̒tͤ~LK[$eٯŴ?4Qer%WZ7L>Ӌح%o+8L/6б2vF9sc17XiJ+ַ4h۩*~5妵oO[CM7t`_Ӑ]$'I:'ct eFI6JD,mc:0!{#*#qh UdY#᠊iKYMLۦM^V8L%6Mlhո!d6c"3]bÃdkt21<[LVy735:p^t]"30⧛9Џ~d5:o(U7o(L'4`0 LӀi41i6L?8,o 8IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-tiedzoom.png000644 001750 001750 00000011452 11544160206 022366 0ustar00synthsynth000000 000000 PNG  IHDR.QddPLTEȾvvvppplllhhhccc\\\QQQLLLHHHDDD>>>999444///***&&&###  2'ZyIDATx]˯]U^hQ4 ;!`82P&0qB8`)ҸH?B ZJ 4R9sco/!ַ~k^-T..TLcw]]t@t@@.0= wx`C5OF@[Oiu?@8[@ڣD5ӳKO|I{ i5gNtћ+.̡'&CZ]2DmteQ@*KΑHôRq ]ڕ[y LeMK1U[-e+]Lc.+yFըFduzP0cǽ⋁sq\*dSk;RSjLls1YQ[kXX 677LnF"ڜ` }0YnĬAٖfv8^wz)m{xЖ wȩ M4ғ.su&^gzFtvmȠϽt+.t K\ˠXk3C!m b]%)jKֳ慾Dl5FVwD*HԜ[/9qF~EkWTx5fc5{SE$c1Zh6םWڽʫMƱ(hljƪP+v_#ޥNP"о]d%e[!]1RNmTp2SzmfMڤmdH㵘w ;=0PIQB{d >fZneVj"'y%. KizS.|ٰ3޴rs5tYml[x$L`0 :v0]J9[ʁ/y%X_00x|+W JeHaD) B4Ԙ4xA˺wƸn8d%{K_rZXk.xI.EI+"-.c.:}oc<%k,5/c+͹Cx!v2w`(9\YsU=цra`"ZSR w#x5%ʒd(sONb?-^RVr'talц⯞EAPuN^\uK&y(., ֬,!i{.if2pBC {!u]xc$"Sv]xdž`t 'yM耲2DUܥK$//4Xҥȴ3J#V.BDI%>B`t81l&ݙ"w%{ᕺop»E/M]FZ.UM`0ޅqZ1WSQӥ%zk]P.K&tq(w@8dzV|鷝6۽eKm\ F.8x[DDtQU=Nȿy˳цR?gyᱣDOё#.ӫMH?-~ ;G!N}+ozUޒҖ;H?%~廿~tDD?@D ݧ 7Ə}ؿ! ŏ|gwٗ˻vEvHP}7}zeS%9OEΕ$=tg7Ϝav."AwD/<ħG[GQ+]8Jt]=]C|LGљl-GI(5}3Dt.C/^VqϽ"@#^;)'ŏ|WYZ>ѫD<}?w{RGrKNl-F)c(.@L16Gx[g\{}/.?7/-ky΋G߅ M>_%[a pozkO]soc5=r~؛9}S_{OAHuw҅я~vݯ:2n;@ ]+gN\&nts+?PD/Uh ꝷ +O:w ZA(e9;߻{VO/?U"o߶6']t@t@t@]|؆54A# .혻+# q=` >7>d\E.U\5^4&3l+}(c%뇦.z}6Klgm;_en-~4Z.6*8@w Y4m4cmqRoo E v6ް]빧3GuCS5^u0j l+^,lsv\Xfijur,- iu'l= יFuֈ gL } ; 1NnޥkJ,bq,J)MOnaIgJ0PZ2r-}0ˎjm)~ lK{h_oNdr:͙pP /!l/K%>9]KbHQ ƷcPb&IۥSTV  2[IlQ9 qXj+[ چ X kbs%wʍ mT* =l@جG t Bd)+9^ަEyqtn6@[RI\ʨޱ޵ͬʺUt)ǭggN*YUV*Eӥl(3} wVL 2Uk{l>PnOM%kjt,/gYХT DFZ!t/"lڻX\Pě\pK3O]N0=*l+Y٦ db%@p J Zvq"<:+m*XR45RUMUũ)1Z޸K&;_HiI7 Y̓m+Ɲ_٬I%PP( C 6QDlrU6hso1M#-+DZSĶbc!ͨ2L7|Q1.$TB![EjU2⠝(m,ɂ.^FyߥyUw;vvoD .\3l\ 30M|f,*b6Y-:TmysM`3#"}ܲ&jG*+FUf8Dz}@t F Ҭl>/5ZjxY=٭'-sوV0B}+ǭ s$FGW~cr^W]b+%u-ń*o0PyIĭyک\U:}0"Xn>"=vN bIENDB`kst-2.0.3/docbook/kst/Widget-kst-defaultcolours.png000644 001750 001750 00000000227 11544160206 022673 0ustar00synthsynth000000 000000 PNG  IHDR s; pHYs  ~tIMESbKGD̿(IDATchg@r@?: F?P&TIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-mditabpage.png000644 001750 001750 00000020460 11544160206 022630 0ustar00synthsynth000000 000000 PNG  IHDRGPLTEq ~wusridcbbaZYYYZZZ[^_YTRRRRQQOJIJJJJJJEAAAA@@@:88:u;z7{BJViӎƮ˶̼˹Ϫđ魒נu}}}|s~9u adZMYXY]\\cehK_}/_!jS}M|"L|!L|!J|%6);j&=c9[B9C5<=533210()0 4?2tRNS;IDATx lE'@ :X2B!2 mZk'CfGAnVVVZYhHq#~@L;68؄2"3KWկ$d_?~\\QՖWVZ;.ըƫk5J,•bD$sT:Kc򟸸RLuIT%˃1ŕJ5YMI(:75ZmtD.PɐPBָ-wsDTN#N5<`:cZ~q I+5fVɹ>9'O "t$\ tBs]$^b$ FRQʅ5J#"9sʗ9#ߜP|-N'3=W̯WBd#H F\(Q#KgfsY-sbQrt*l"Lo< Xg1!W):=RBIc:kV3əS9oNhe4:  (1&B苓Jɚ7ި!&8҉ "KmY$e tR׉ x H6_t@s9<̬IH: y$g2a˱`Ps0kLd3‘Fȡu\pFmגTDd&Wue?IZȋ)Y-B%"ZeJRZ ysۉ\Zu:sy M:AZ2:^,Ȍ9NTM6I)(d"ʼnEr1i*rҍdcDS{+ȂėKz}ҙ+qǞ݄rmQ "VoR,ȉ+,O'Z[hƝ˜tch*,KK;Mm&^= }qNJoOևlwNٱNNL9v変W/'OM7O'sΕمDg2ߖ5ˌNviN4d%-ԸwWBS󇝳#?ٙ:OV q`md@͊XdW¤Ra9:=tɷJoNyٻ7E2˝r &r%X|Ǫ弓trq:8\NBi.&N\_[N[NQGk)Wzew2?~m=gw΀ft>.~F;v{v,z']Nr7B}WASCC[dp;S׹햘T1CFON0=!PK9>oq5-kβ𜢣pB ޸>iA' EXF컢ߪ;יN),]dx[Ԏq|,5{ܽmtwwNK(كl${މP/nSu_ U*--ij 0΁OesmLM :/𜢣qFD8[^k>;Z Bh}WPz;r\>Sǎ);>/9c>@fbFh]I{=tѱQEFxrދ3x,Ikm*)yr+B9PE@BqN #G D'j7E'N/LG)Qθש̲YWgǓ>Q p$wǂK13-dEakTdu"Sntv}ɤhx'?/^̳SA PY~ܝ;w旆BG뵣~8qtNZS_WizXf٨;w]μNt/.y SX0-dEªsF+_;t)xvz}{ߏFOi>fS"=tNi;Lz;N#B~tV4`T_jw[9sk>]^@8a iӧ8Xl'w:Y6{~A]ˆ~d\c @gp o?j {YQnRנoCyu76Am6:{$9s=;{&cNyg}rog'TUTTDEɾb0񢺺wE9#nz+WÄÉcf {tIׂ9;Y*/<^ͷ^8u#q6t~K'lھ]gswwIE/}ᇗt U|u`tvss6 g NGl>wʲDw.Vli"*J&,jB:&Ɲ">Ҿ)$Ϊr fFg:]L: .z(g*0a&QUAfJ䝶&j4Tس$K.='/*{9r@Ez^9I'V:wœ c:s`"5xZSqϯ''/E0{woSz.utxZƝ$Hzvr\xά+Q 'dU0u:f:ugE"QM9\_r+%>p{v.{n0:RWU_}=NRhBp(sDDgwGwtO`eYi$6ܤ;Qv!;7d]Nkk1n$5:< ;˸aWIM'Ѹe;]qMp>۸S/&zPF}1{Ji}5yV:8\Q-s5?_x ɯu 0Lj~<8wWkc8A̱6CCCmm3i:#ݑOh;msl1gww<9:ww {*1\* uW毠92\ҳ+H0~:YӢgǾW؄oqԫ=гSeW^K{W':pGƸC^/;H [3o=g9:ް*%.  f:j6F8kf4wQxʏOoxoݼ0Nk3 ]mpRNXtmPQ6wn!#SQ4Nٓ~zlos 3ccݝCC##i:9#wvw:'`kF'9Ee*C-u'u-= : |,<;帨W{/&c?AXfh}WtE]s~NC^(t8xgO:=ߩD}N's7l|!Fѣ; {$;E_b]_a/9|.CpNeN]<5OaNAY!pr:҄OEaҪҁ )s=фŠ9\) KReӥ%9?6e۰·dNJM2eQʋ!Ŕ fq:o}:i3%U~i^i-MfR6otsݸ`l=M,|ޓXL'fSכ$L;:?T O3d6T(әt.Lx_^XIk0.tiH4)dkS"Ng:)H H]NAs:sds81tr*:׾?0^Jq:93tނt'vH$ AiM'2VaX2ebPKQnG` Ej%PM 1tjR XV`i@0 z 9'7m.ֳ-Xz0X6HZ7l / +n)G~ _ !? $jL)JHJE1-zCI)uJ#WrE؈Q戾 jm赔Pw@ock戱u#]73Bե6:3tl@lA7mi`c5SÏLd5SYOqD };ʘJK%+;O?:z*: t>dW֓\){ =|{7x힇7x  {/w8P>= QHB2`OZ$J߅[W`WTFדOmO<ѕWJ|~Rѡў_)()E; {h>.%Ld>,pkY6W[㏿8WJ| j@_IuQ'jH|}!F >?@iC~qI}ȋz}B2{@TcYqD·>t/uCv0j?K__L]A}gAGB'dAl,Hkgȋ`G z:ǩO|1BCYqD·^ @2+'I*p^ܫ$*řY$y/,*ޯZ vR>\;m2qD7wZ5ق2Rmv:NZVBzm|AR"g:tCc`7`qE/oy+%rH#V2tj 8^~¨+hV֮-Y~eetФjLBUzHVQ_m4SENo V_il Z]7Z__Ff8Dj%P?@m*֪/ffz7grDgAyPRMSg9~Wg˖6oJCækҿeKN+;~q}\)a>rg_wߎlWΖ͛wܳ+%r>G6lHxvlޜ|=pFgc[6#}x309תtrqq:8\\N.Q4IENDB`kst-2.0.3/docbook/kst/Equation-kst-correctedpitch.png000644 001750 001750 00000001444 11544160206 023206 0ustar00synthsynth000000 000000 PNG  IHDRJOrIDATX?hp@@9 Appqppnppqrpps:t蔡 R28dp)tqsrq)(tD(ţXh 5 8 $uބ|cw/rD+ޠާ8ǀ':|"3;@>6S9TNhI{QWiZVAԥ  rfrg)&H P77Z'05{)dxL'MM͕݆zea4S$Ͽ-_UW޲Tpߗ1pb>:wt';bȹ睮1>fPMpUy<.=7:6h:rUۺ aQ޽G]r/֜3hbDmHiFz4S 뤚ҝ7A܄d@-?7~{.oA-i߱JreZ6>|e?YÞ}6IENDB`kst-2.0.3/docbook/kst/Symbol-kst-theta.png000644 001750 001750 00000000373 11544160206 020771 0ustar00synthsynth000000 000000 PNG  IHDR >֢0 pHYs  ~tIME3"bKGD̿IDATc_kgb?'"=3 U`:fsL_ 4r C2Sȹ سA,aG\dbq[ dx*96W$p~$I~{4IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-equationwindow.png000644 001750 001750 00000014654 11544160206 023620 0ustar00synthsynth000000 000000 PNG  IHDRE|PLTEQTRJLK99:9p8x7~@KPOC>2*68::@AAABFJJJJJMQRRRSYZZZZ^abchns~郷燺fcbaT}KkIiFg5a+Y!M|!L{$Kz!Dm=a7X 3 ,+,RURSVSb^\vpnwwtuxvvxv|\w}žHKtRNS$(#(`IDATx_hG{dK`Ļ^ge/k|c '#A7ՆMc^L2}wA/~‘}Aտ͌gtuUWG]]uU9E{T**NQ\zr?@e~3>U[Z 1˚ާM[RlIy*t4|k4sB}Ui%Ŗ ӌ՛{Q:Ws.imcnS9kjvnë3Tk:Q`mkwn4?rEHV S'Չi{9a¾p;LU;\=[ekED&AJr^SU._ +NM\U4%-m;{1'64NqIo_tj弧Ǽ?o4/q>^V)+ 1^5A o8;~H,^)>27e yG}cUe1>$Alj4 r·h_%XW#EkE"sCP2 h^/h8 jB;W(^WP2I6T^ͯ|5x=rz |Er,i6?bJϼr] /zbזH!66;a=EyYꁗ|x`x~q4֨aAZ2ii`bDͮ-P葀Inz o}.ʔ*:PzZ$ٵz e>܁Eyi.tCFT%(_/m(_TV# T˰({6/ hx9EWU`_v~" (2d3,.XiLxx!WTmK@0C 5֮ץ/W4Ra2V_ETD[#j3zH^lӯxPWPA=rW?^*C{-Ɏ_xezD~Z/bLAqx~DbRuZAu~M7+"ZvPe0#q(Kw!U]ST+ T{H^wRaTWwa/&5ʮEJ c+˘a/VsPaW?Y7ܱFn> QxA^xAnBOT뵚mW0lPjxs!O$IU&DоX35lۯU7 ׯӞ ^/|^EоvBr+ *zP!77 !xxANj5Q*~߀`^^xx^^#:9z/ rG:./axAxAh". t9Ğ$K۾P+E뮯X"KF9 ў9+m:bsM͒K+8ނWj;x&cټۜ-%t^V3͵9´MQyGk%mSKz,= r"Q61"'iv5KoSk~0H=Zh}FHra?L ^;͂ / / / / Y!x9k*+c,OVµڹ/qmC`u1Ҷu+ټ5Nשmn<JËb5^켞0j^Eq̊y^jc yiW ֚!.omVץdkm sH^a=^ONjS#n%/U^x 2yQ\Va^*x9ˋ$^/ޢ[X_<>7h^$vB_/WDԌ7|xYhҟ]錓o'Fںz?N#L؝F}|_PQ]K^cYyջ>fnϖ+<BG`m>մ7nkgׯAL>rP-sx /$&jTAY^3~/ !$RA͸KչIe0 0k4x+2T,ubeduU%?^kS`t5g/ˆHR|5H3"4,,<0[lOn#||<05&hGC/jϫg5~(Sx-p7/WGy}f}ǟ*v%q)^o[i|_S\UJbDk2-̈u7._km׎J5ZEyE$CzeGb/^5:YqG9bkتʋs\] '(=8G~Q`iܗr\%+XQu wA7ESy5^wT-yV,6^~eCu9 ټCm]*/fP^JK;$KNQb}8+c6/6?,fKb<K0wy>?lNtҏ=v|:/{B9|tXJ;>^^K`.ckK 7~o͔`f ^ 1 ^.8jVl_ Pxua=N}+|X8/^Ƌė B yua=Fv<] ڕxƣ kë3R}~ϫ, %8~O78w8('Uu+ Gku^%8_y_T]#G=U_g DX $<=%/;y0+/ \nPvN|T^d8Ƈ!Rʡ^2Q>3:xʧE⚊?-^ϙ_BF^ewȇRrjTf^|EBeʢ/("U"^?ſCe? *(w_<ڤp)r3pMK~dT&ʝmn8)aMsGB9ʹیm꟢#ꕐj)QkGUnS`KmFd߭b3MM-z-(/Mo/.] XVM>/E7ZXrAJuU7qv-4P^J}M7߿D"ݏVlqPZt&Oõ ۯ߇Ou`S^ߣZ_%J9FaIPE"K^rϺ',.^ ύVG}lPMit,E:'`z"VG*AտP[ !~UgТn|![.t/;_j)*rJ:/*?|GUrI:?T^BC=/ʪZ/+~u=^UZo+w_S[w+- B(IENDB`kst-2.0.3/docbook/kst/saving-chapter.docbook000644 001750 001750 00000014306 11544160206 021372 0ustar00synthsynth000000 000000 Saving and Printing &kst; provides various methods of saving and exporting data and plots. These methods are described below. Saving Plot Definitions A plot definition is essentially a capture of a &kst; session. It contains all the plots, data objects, and plot layouts that are present at the time of saving. To save a plot definition, simply select Save or Save As... (depending on whether or not you wish to save to a new file) from the File menu. Browse to the location you wish to save the plot definition, enter a filename, and click Save. The plot definition will be saved as a *.kst file. Exporting Vectors and Plots Vectors and plots in &kst; can be exported to files. This can be useful, for example, in capturing plots of live data or using generated vectors in a different application. Exporting Vectors To export or save a vector to a file, select Save Vectors to Disk... from the File menu. The vector will be saved as an ASCII data file. The single column of the file will contain the elements of the selected vector. See below for an example of an exported vector. 3776 5380 5245 2942 1861 2424 2520 1868 1736 1736 1174 499 Exporting Plots To export a &kst; plot to a graphics file, select Export to Graphics File... from the File menu. The following dialog box will appear. Export to Graphics File Export to Graphics File The following settings and options are available when saving: Save location The path to the graphics file. Enter a location manually, or click the button to right of the text box to browse to a location. File Format The format to use for the saved graphics file. PNG is suggested if you are not sure which format to use. Size Select the dimensions, in pixels, of the graphic. Check the Square option if you wish for the length and width of the graphic to be equal. Windows Select whether to export only the plots in the current window, or all plots. If All is selected, one graphics file will be created for each window, each with filename file_n.fmt, where file is the filename specified in Save location, n is an index number assigned to each window, and fmt is an extension representing the selected file format. Autosave Check this option if you want &kst; to automatically save the plot to the specified file on a specified time interval. Save interval The time interval used to perform autosave, in seconds. Click Save Once to immediately perform a save with the specified options and settings. Click Close to close the dialog box (autosave will still be performed at the specified intervals, if selected). Printing To print all the plots in the current window, select Print... from the File menu. A standard &kde; print dialog will be displayed. Some &kst;-specific options can be set by clicking on the Options >> button, and selecting the Kst Options tab. The options are: Append plot information to each page If selected, a footer showing page number, plot name and the date and time is printed on each page. Maintain aspect ratio If selected, the aspect ratio of the plots in the &kst; window is retained in the print output. If unselected, the plots are resized to fill the printed page in both directions. Print in monochrome If selected, the plot is printed in monochrome (black-and-white). If not, the colors of the on-screen plot are used. Curve width adjustment Adjusts the width of all curves in the printed output by this number of pixels relative to the width of the curve in the plot window. You can set a negative value to reduce the width of the curves in the print output. kst-2.0.3/docbook/kst/Screenshot-kst-tutorial-datawizard-done.png000644 001750 001750 00000054641 11544160206 025461 0ustar00synthsynth000000 000000 PNG  IHDRC:[PLTE ~Ӧuϡ`ۢC) lW(O#M"U1h:yE{Unyq}tydTH=yAgFmCmIgJ_8\.Y(X L,  J][_m "9=9z=wBwH}D@@@A@??@ABEJJJJJJJJJKR[Z_TSRRRRSTWYZZZZYZ^bfdcbbbbciiowytx헼댽튿ꇾIJŎ{u۫ƽľǢƛĚ͎ȝbrn[WYAMd!GrItExZy=m$:\7S>A19120E5*"!3 @?+     *2Dr+ezȠo tRNSm]VDIDATx{l׽J>IpP"N$$9WW&p*U<$PhZ Ib&!?#`BDffϬ5ff{{7kg~|!J|AL /w..5AIt;!J~4 դX oѕ hA5'pڒ'11i jRK|Ŝ%RL4@z@T{ !)! !QDȒ'KϿߞ|obo#d)X4_|D?79ߦ4 C!KKB*}tc9@{!%KC7y4Մi6BdhK+ !/?v&v3!ۥێg?|`m62Bk'bCo.\YY߰ Q#*C0b}b]z ?~cE-[BZR0o[\}oב:~N "d9P)ds|asap|H+dO>BR_bK?oߛצ:tCпX,=ڿ@e_,h.5oTWlmtYㄜ\-C`^, 59-6d=D:`_xdͦ;j9!F]7/ij Piz;p[\z%~3d:իmPiɮ5ǹ_y+ț{9ybI˞ o}vL8*Co8&oli1):7iJ'!޻0[cGto~nquU8Fiqt\{|Z, ݐ2Thu,;{%TK/nnnjJ׹ؼ\qM5-1g$e"o:J Ʀ?_x:',^쾭36._%K,^nCW64_u?7CejUx@пBnuZ _ AJ3Z. APr AP`!C"Q';P"4*JsV>[SuoU5Vּ(;gvV_s*|eN7_fjG|oӐCScwCaI}e;v5_rMVJ Cv{u\~Bk^z.zk hz9Iگ.:;׭_ohW^ɢZ7+7/c:.L[$%{#m`}ԩ]˹á 9J9ūȖӆY;r14W ܼ1)7s\Ͻ7kÿ3Cf>`}O/Cr֊YyV>{bEMw4wn`},ïx 46-<24i~ +Mvތe4ayo=^|sÏ]n6ёkz3B%g׭1=8D3g;:(g'u죚QޭM~Zfc#wr!QC-{Ojz4\1o1n7Cm! i+ZS X${o{GwmxGh:U9(M& 杶=!L5q*O Osz]?t>m}̑0?d0bw[$ie­8ֽ}~a*4+?E߀EMzː:QܯCNe֔y?4ʶ^f1:VPMk%s 9T+R6{o:vUknrQz9k-Jr>߀EM߼N!{o7X虸[k"]@fרE( U;C}AURdVXoyArR[ }`~A`!CI3AI2 s4Bez!@tj "^d HZ>5X :K}:˱bS)U6*CH=&,[O?WXSgOI[--qΖ; DrjM=.sR{>w[?v#caE8kԋTя\yx\:{w.;v$wr d3tPc} S?6sJ]PWݐ!v_a"γKP.7=C?Xzz[{fK\`g 4m-} 6z4!󯷐2Cl2#j5k5/wjda Yeg@^;s 6|qCL$Cp@Bl5GuT`p ;'b?d-=rT5An#.C3ZxO?eO?S-qS]"γK5={=C=]u֒gfi]A { =D.8w[?|ܔ%]uC=D?3@X tg^ 9Km{KMf/a=!'K(CL:$hl_p_xaт-;wvH!A8z`  l\ CǏ CGs炞莶7[W3; M\fbژٰ̦= yR!_f|`$D=eˢX.tإֹwlٲcOo?~?UWC]ua~̟zh=c董ӡu7,zs{,/tЌ?wsu7lP:͘@!Ʊc9s/gDc[^yũ-oN"!sMOd ;P?DhD(C@tb C_N ,sœ{?A1dz!{>3! rNbDCzիV2Dɱt냟eg,cop-{n^dz9;;<^|-|>`Cй}8h㕞cP#Gf {::֟ڇ6j} 3["Ƕ̖;;3tʔm쳇˙ m7o~vsϮk Y^Ϙ1ヷ}m?h99C=rP?w"G8/C[?.?C;{- tPJ C6Dmm8b"?;.Ҵ=0?5Av0Ksc\.X ?RB/m'cի5!m5'Q4==dCrkMI{C*]=sK /HyZC)!P呂 /E!{Xv ްD^Q՚R?i| Yܙs7h f$q)zw;~m톇}\Tͨj]޲G?)ь~h<Xb!;M rO~+mN)HO};319os0`Bg\:pe'|7"&pN(5!x 6o¢uO-]ڸ8fQ5RZwC;,0Z~Ǯۑ-}Cz~XI<c3إ:j2D~@!;3u<#ꃛG>ȣF7XGFVA=s-LzM땇)ݥb?t)"2÷=$嬌u2R:wGV֕%Z%Sz':D }%!_,g-α!`,WV\/Vr{؎V K5,h8˖Vޅ ]nuV45.S/[G\2tÓǴg S}Z[vl}n/uCGgwC?`z\ZwhuV#]:GΣV*v<ڍz˷}yȈIr_yPOtg4õm ,CuC/9^$P*A Yнo/Ksr ~ .C/w|ɀYZ7ZC/l['CnG1C$=guRМzD۳ǐ,\аCgxཋ]tP惊rk9m7o~Z.p j[VZOc9O9sM uY 4Эo7ߒo+BO?q'04I(Ӝ>٣Z6C=\7XpKT˭oi-/>ڵ=vCi }ryLР韮~썭?wP4*P?wDes'nȆH1}{kjJ;fΩC{ּs+[7ʖg[uXX/7b~dfٽGxzM>ӎVzOܶ2|nsk@u~(jss/~4+Cxl N9Zx4BXYۚJ>kqJPx?Դ̖8cC}+Vh/\hn^ѴbrmC8ٽmP.lpA2 nv#u aB,CrM+)B~ȴ,iڭoԭ Cm2uD/9la+bhޤ| E}@uYK] 3p/Ͻ>dɏSr{':D Y6hT3䷐gZZ`_SR|VW1CVy1/\4a]!:HGQ Ѳ=4e(c2{)CTji9li{ܩ_gN ]`: a[G^ξ>ʅ!~na<=V7 hwHPG]~3>>ujfVP{j#Fz|}DZ:;>DFZ. ǩvrKz9~Z~iĹ;oذvU!!X.8 1~U?_C-~!ǏzeAEн7|C܃k֮]f5Ox`Ҝ:nw`T뇎CF+vl|MmSk:1!C"?$d;xՕloS8b̧#%So?CvAVСXɺOwWwG ٵs_p?D{X(Otw Ga'RaB-/YٟfֹuZ^e_.\<) C">a*̧˕J_TP Y:|*amrO7C&jH*8P>C 9tN"0*9ob4Xa_R62WcASC)N7Ve$/S&g{|lAM20CDQV₡*dHKA&gQk\WCr $TdTAHCftK`M"3D=ZvWj[0Tɤ*G,J,W?ĦY40TKD*IErF[k&OM%R\LUjUgrŰ֤*v,(CJ1TثaM~2!Y4ڶB !B(f,1H1TX..2F j4R!|2d" e|5sPI֮-b| "YːiLSt6g!D0Dʃ <*)`NwmY@Re|"Wy`q>0gHT&װC/n\PM.Y,VB!C lזɕj*uPn"1G/ <*["C#ʝZs^*v#ŨPќQbǬvb6Cη]:՗!h eo@pr(. }K4dTCkMLQm} ai8,sgAVSW֞0Ϭ!4r UZ{|tW[)i,W`I%mH}'f%1$UWC%0EO:cULx&v4 Rl[} e4ahekķkX.%HǮ'Sr+[PCtS%U9]eʃ!ɵiCEN|"ŽG1WDi5^L1ln-s&]h%49_}>[\JP+žjbί8MVV+Y~LiM>$CKR01/-CsɚjEdH ؛%yפT!a5 $ɐ;cq^:aZE'Uᨲ aKLs$1WHTe(/6X|L)8C!cY;Yjt+JbyƐo+L|x/rJXv[-&d(!BD34C7rnda $#x\-9CXD?ArT3*C!*;C7ɼMwkז1ȤaLkr9]-ÊPFLK;q4IIæl6q]br;~zeMfi$ݸ:֘IfjںV4ys=#_&Fed0ZInn?1I&51ÊiHxjI{& (33H A  A 0-Ʉݿ&3W YRRݮϏ#Y̐Xk~|CۆTCP?4~ Aj Ey A  AN'C$ǐ C!mHB %b$CN ,BPј!B!34YM0`XA:RLH̐5$j; H1w xDVCbP+YcYO/W_-^J]%C` M7 ~ ~¹_/a(KKOk_sZ4Cz ]2}VNyKIz I.]ށD0ĶZ~m>k_=1{c6lm]W^77uL-TA0'aHWNiI|)1zҍ ytNk" PKPgIzN?qr HRJֹ1&ait 0H2(]vz[]eHOPݥx.!ҫ! e!Gs.ս+[ؑBZoIag4C+lOts]WeHaH399C^~nr *Rtz:x?OjaHOɐ^.[UPi7^|%&xxZ:SҹcV: TmaC~u0Rgo28u"W:Q+s Cz`hHagY5!IF+0Yj),-:b)c5? ̐^^b1D;C$)Ubf()PQғ0D0<]!2 cHO1}c 'D(C@zңJWx2ۊKor!ѕRbHzxRdH%S0L ~m:SuN7 Jb0DdcS1LcŮF8 i~gH2P͐.ϐ.ϐɐZ͐,CDq u_9W(Q=FHb. ab">S$S$abVck+E/*ңU"YG^!Q%].!=_ֈV} 7 _`ȟκhSn9dYe6VCsG71nsf;$a*[,C\c"8/q d &O/ C"r IzlB l!^ J [!Z CަXwM5K3# ! {{QE՗Me(|х.-)Cz u Q\HI8!OB F v " 8mhWqrkcrIΦ 7W̐W|dF21=!梉f&jч%<2 vtJ:>du$ ycZM$E _덫c̜$a 1ek11a(].3KxlCȈ͐_gHgC }2*Hq=Ҷ~bkcٌ (!qA0@J +NC7O!",^J126C$ *Z2$ `H*JkE/!( 2CZt" 2ϖ  r 颠J!L CoVa(t v$W'BHC1 aQ3;FrB˦.PJruS2DR0DPYJH"0D”rDNPc=Sy'Z_/Nb!Cf5OfdUǴvm+!0THbЮ)Vk۾>Zn??W/_ڛxN}C`3|{/(R&GۦN P(>+얭*cRCZVSZ +7CfUCӇr!٫kդa:R,S~ _`l0A50A 0AUPM2o|dUr0:.#чeҰ]c͙4>*.[l!ؿ[FedӰ&I& Fi}T\ +V,㗬_L 2i,dҰW3i}T\ +C9LBHxjIhS@& X& ˘aEcht q4gҰk2i}T\ +C!C  A/kkh-/}2!xH00d_ruH0)3d7֚ж!U͇CCsQC C ӰI1$  APU1y8 )Z 2ak%aȞ~&x[YCk )VD iHPyv0+<z&,Mb FC&!uja!>CJ0drFn-Ȑ#sWcȐx5# CwbR>['CFr hO-I$(SUC^+}b Qhc-5CCiR;`\jcOQCNsaE YEB|XD^a=L0IJDX:ⲣkGJ0ffcv7$a2}=+w\22Ð10dp ӟb* al-. T:2 E^!@< q0FK1_KĸBPa0$2a/ ņ̻*C`coZ 2j! ` (}78!A7+]\].p 1 14q5u|r>C8Ac1dė:o|t뇔2X0dd!  SdHǐ!#}F~Dd KU C#Dtb({LxgVCbCI:ӲFuf :S~VX6XX$CR D)1!ȐQQ0!#!ː ^]y~3'CԸlop8&ϐ{hDe3x8`B&EfKHFCЃ_-5\G-oMTÉ!D#!O CDk9J愗y 1h"gC~h}f;cXxmR c?B&㦄 6!2 of29ZHLXFHpSbb.^r $$0" a] a1i{ >G}ԏ""H"͐܇z}seCXJ`H.""ƒOR$bϘ uT7[!WoꛄV]\BH4$0n2$!M(.k)J&djuۻ}}kC2DP"UIcƾF2d,x„㚂3=p߈CLKBH>ef>M*(L?w2r~SDmIP`s!"fjaw$ˆ}ISoD͙b0>i1Ba=81TbpՌ %`0D+@ +&IU.}U2GK|H(C2f!Sc nwTz *J"bh?T} 0$yT̉r~=ѥe2! "%/n d+C4LD #WER&&C,C !RYB,VC.CL?eyTFKS2ȔO?: /]2 C%MYLqm1D*C`H^v]4#V` $ "1DW@wR,D Z\ۇqZ(` Ms;bLKV53jvc*oc}&E& d01]-ÊPFs_-w ϤȦaoMLF{?fҰoeR+KV9/ۆgRdӰYɤac& i2fX"ayDS3)2im Ȥac& 8h +CG^ؿL$<5>"LF{?fҰyf6c!!C򗵵E>{d $ TZJ:q$ k͏ohې*`J!H(!C!CTi$1 9 o" ZgHI!g8a$P"Ce0PTks4&e~C<["̫FR'XjRՎaIw`Jǐ)0jϰT!HQl1Ua`3/0'4% .TSY AP A`H%˃!\*? !0Ad;D_wۮ XN!{}"`dHs53Zg;d~)CPEr c9{}=>~c( T; o P A(Ņ T%"i '$ #hQL|y0M{~wbd,P A˝xo`x"a )0S" B -L|(CviC$!# |eC`MX*"5p AӅ!m}G1"(_A A'3ן_ys8 !q\y#o!#.n0=u?DwGرq[!_|DK <ꞝ>Ycǖ }un"SQx&K$ L} qik)vwow=iXtu,s4fE.vw/aR%׷K=^-W3wv߉癌}̙K}H[r=^]جNd>ʞ>Vr7 kiHq ^pmk4( <!$&TќC %C{߿$ ]ix y~)O!JP=S~XN 3d{RC Юo< ^$D[BrBC a<\;A9S`huCMژؖMvGr3̖G3jخd6rfKPkj׉3z4tfKP ɪŽ:=cl! )h"9,-¥T+Zåe 0A`!jMb !cKݟZhvulSزNCfU!0 'ál !Hb1tcn~X2zC.014w|F5~9sڲvb90x3W:0A` :l~9!`AUeFC ir3B9GcR95qcYV%eȷʐ`JʐU`X*SC$2[ aUoBa`*P~ *!0MW<~bL0AedX2~HC2C!<,q,ڌCy ?Đ:OK j!{j=nCPEr c9{}u?I0])\c(|0!XN&`HCP3xpwIZC' "hz1sb9]! A˝xo`xғ1P Vǐ![AӇ僃gHW`HCP-rE#D 麰z@/(ң+ *B^,`aU|"hrs;OҘ,Dq"Ju4GCd}I^.:+9 vD:Wy3Ow|'P=ݭ)=z 8ֵWW]:O?L[_RQP`kT|+2p))ӉI-r{":|nU}QMGM`}RAP<$H4]KCck[@I~(~7AP-Fs ^C}`3t5r"k!JSP? (1CL!rb9 P !9! 35W0!:G! $< ? P,C7뛬E!BrB)r76"3 ~(!┇k' h:Gs 5~C7s5 SC4A*0A`2A]L RA  A 0A5P9(ŵa:I6u& ! ! A` A` :! 4{ձ r9끮ܮڕ7OmW߬` EۅB{\/V`+o/noy}` 2Vcsх}w?sWso<1_}N7a]wg`:5ޫOzddj{n[^770{g&Cf>#WoMzgPdhb߭M{g[lt9nk\Q\0TKf~g7\ۧ[ <{Zu-wE!&k󩭹]9<N2afy|9_P p7jΪIo^}aiWپ CUЛr{~u7JW7m{XfI&ڇSp.VȲ`hiˁ! ! ! A` A` a%̍ DC -Zp;߽APr}5U MIENDB`kst-2.0.3/docbook/kst/Diagram-kst-matrix.png000644 001750 001750 00000014205 11544160206 021266 0ustar00synthsynth000000 000000 PNG  IHDR38PLTE˭Ǭ}}}}}}zzvvrrrrvssoooiiibbbYYYSSSIII@@@:::000,,,((($$$  ,x@IDATxkO{/6/@#D@DnG(%[h:픹()ӮJٮYg WM4l՟(j~~4fC:-HLoՓh$^_|q44_7[S솺׸z6U 4X(ʮ;ҫdR2D{4r\1)>V~^vRhOthY*:wVbj.vq2_oOΨ4`ŽʳKQXkR8_k,Of T w 7'Jz51FhJ'9r~eO-@ETnN+oȕkUVR7Sqyݠ4Dp@;D@M4&h)&4 MhBЄ&4 MhBMM4!`qBThBЄ&4 MhBЄ&4S@h"&4D@q5)%44i5ьEdơ-4#1I @32{%4#1G?C32 dUhF&&A324#Dנk45dЌLk d\ͤm: d,uhF&Zh:ރfd2V 4#A321hF&cA32#4#q~fd2fd2ZQֳ) d\dЌLdyhF&5MB32'hF&c~ft2RtءSЌL{tX¡^ctɘaivs*42D5: B4EMcMtnIe,Vk4xOژ,U;]9VOJң%x N3^17VPL3hv1zK1Sޒw+* N /6&gcrxmʔO+͹uoeɝl=Ir\LUs|M֌:43h7&l=5C5hf LS]s$WSlt.t&oƳzD׼+ת;+%nV˧7ɛ.E=xfM]] jˀPƕL&ޮrtF٫Ĵ>HBS yZmJIxK^l4ORgZ!5+w"e+gbg|O.jQ5g5͓`q&w{NurE%JdoL抅f茪\4cqfoɮRNswLU5vZ@ˌyR3V}Jި_Q3V^!Xsѵi9b)4ISs%?%g`>j52kk^ݜ޶|b꣖1i>]LXwO.ۄ&g(MIW5TZ*̶sdzqI5493/'2 ˄2ZTe^8]L mYOwMΌE74^UO4 kIv;O5c+jUNc4A< Nv:^˘4McjѣV['X+0L3+41S3`f0f341kb3aFfY6ƌU&fc}&f_Y$ }h]v;Mnӟ6a+O0(hbU~dlgP+6>K:V:_q=BuoUihK 43Ϛ 436b 43L)6[T3H4Zhi&hBIMzͮNOVP49 j۝f'ASM ` a `Tci?0hqHQM%bGX4;iUMivЪ@S1z@MVJL8 QSU- `M%ӝj*Tk*T9^k *T핸AoUMYUο &gM%̗MVJAjUD._UkvJӽUt& 4زZ/n 4ؤBܪ@S}MV SM%>:8MV!P\[hjGCiת@SP roU;Yi٪@Siժ@So*T] VJ,/VJ<©֪@SժlB5c~ &ypOZSF"W4ŠC:dIhF&cfd2VC3dNC3ltɸO?C32NS@3dyA3l_5hF&ch-cz\h-c\h-CͰe\uf2Rtl?;4CFE٠tHcЌLƁz _G h/2 _}kQx&3dӻЌLƚ43 a]fd2&7hF'^fd2m gH4>t.ДdK%~CS63SHT8Cϟwkt(C{M hΐh~P^" ]OZ Dx5ս 9ߢ 4t?~كeSgV !寧LlcS:Q)RIHHAqX:-HLR)W 1n_N:zPF3GȭM,KȿϘ返Ko~w{YG~n^ϯt\v;ͪFvWَ19VJڭ?iڠ?͝NiUr!0v6# <~p؂g,|-3Չs"w{:Y;  99J'&/f,#)P>K'&'f?-)P>]K'&f-_>J'&f-[>J'&f-Y>]J'&,Υ]kO%)M ;KQ>J C|:NgMgLo-/{/^[^Mi_:40L.Ӷt:h:`ay4]ʧ]״i:Oiit*6N?KP>K Qӡ|ZNkMkL-/}*~[^VMiU:406ӢtZhZ`kڔϋE`X^jMyt^мKiU>/vvX^zM^:40d MV:͚f`YBӪ|KIӄ4KhZOsll %4-˧th`峵t65f[|kNzQsxg.i+_?0n@3JMh"&D@M4t ӒZ-±4f ô4٫#4%%<>iC-KJ(K5> RR~Ҿ*h.)hΞ|^'S:<@*mߒyo,)!Y|HUs|>DP2<>!#잾 ӒJ̚'kRc\)jfPp)yI 2W}ܶD}]"7n۪T"; NU/Y+|cbLo你9M4Є&h", }dc4t_s[*pKCSaB>>1Ue'זi[Jd/[{sݑ,4SeQz9)jgB+78wjWf}L!L=Zj)X1ęvR7/uM)v0r~ZjX1'u}3R:kMSԗne q|KC(,hs룖69FCIN̻=4=,#gLڨe*c!j􆾙{{hzS{HS"=4=d'ɠڃX$fA3JMh"cQIENDB`kst-2.0.3/docbook/kst/Formula-kst-exponentialfitequation.png000644 001750 001750 00000001114 11544160206 024615 0ustar00synthsynth000000 000000 PNG  IHDRm%IDATHOd#qb !!,9\氇!=!s*01U#žrqRRr!CeR!*¨wj~v'6}m!Nz41ƶqd'yG?M4Mt8Fd;l6۰b@?އ{4M#aˬ^?Hҷ3aby?G4ۓr! \h_osM&iw3Ŋӧ95 CNwpOgiP6z^4?Yfyu'4T YdMiw%ot#.=ݶeL߀cc1  ͢@8P"Et5D85u;}xO ;`jݮ !O[$hf`X02K6Yopɴa4A?t#TZc^wWڛ܎|9O«J۹b͒ҟΙ_40k/%ie ߢl3IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-mditoplevel.png000644 001750 001750 00000020573 11544160206 023064 0ustar00synthsynth000000 000000 PNG  IHDRGPLTEѱ̲þ¼Ŀߠ}rkecaaba][[[[[[[YSSSRRRMKKJJJKMDBBBAAAA@@C:98997- Z  6L[e`[$[1g7m?sA{?}8>|LQZfxҋԖśĠãƧȭ˯Ƭ~rzftfn^]d[Z[YXYYXYSVVNTa>[3^-`itdF*"9!J#K!L!L!L~!L{!L{$Ix*Ak$ - u@Wo ܑ | tRNSI&IDATxlG+:pN>E%%/J WT۸8b8*:SAS/*B=Y4͉ V\BJ'T MH-ATBz\BIsUwfCzYwf<~; ˖ݾ#DHʲe/,ݽ7;~#H9,{v=B䠴~NwAcyWIi"t ;%!I:}XY?~ܨEeLS֏}'LN;^ns.;?aL""I7nu:ї:Hm:mG~]'gHI*ZNݯÌ@MB'8T :"Itva3: h~<Jj+;N=ڵ{N]3 X&PZjC `Om¥y,ؔ`W7nRGXcbomLj+r#1F=i`g'ɹK&LOJN5Uv vMIf'E67aݸya; ; cr,;I#Xy*oIəkZή7u*edvw ')EW&O{߂u8Fe[cGgƩi⼃#+"7ѩ)wvO$.]r+\jv9 ] y`Oފ$ݽCL6vXlLJ:=-;ڈu&C[h=ڵaW;`L ZI (5N>o[Rmz!DZOaIc' ԗ6l['Uj.`81r6ɰs_?Оf' ̭_H=NN8iSke59I9X1IWF92;"Ty71>޹s|m6׈3S\J'ѡ*;@ٕ{̍I].zCC ދ=| wt5nޱwv'h:aKMVp>juvv؝Q$~:!B+ jڏsvV;A@)DHǂB;YS`!Ow"<9,Y3)er+zme(J e}}JjuYLz'dD% 2A B9\sҔԾ -;<紹p2蝐w"G>f"i<sJb\º-훠E-,WAt%H^BM^!,ة2^/$KD*k;)%2i)m3D%>t}rȒL"B*;oR|Ep8][:^giICe8Xlͩ)ku,:;К -e2tDdK#d"md/N-^ilERc'مKs]T 4Υuq؞B1>*uU,(b|+z. 7wGoȑAaU.MA4:PLFʄqv!N!B;;"DB6;j6Dʩ+lBS;y-\;K\f˭2?}[B{;%[)ᴝjSo){pz~2ynOY! Mj$ӚiQk9Vn!ǠtB=2amɖ{mq2+X^TAT+S2VJ31V)Gq*MybXFcڳLTЕR'-3Z6_U[0ZHMT:Osk-0YH>))ـd-^?Sξ ƊJ&u;2~`ws 8%?yx9T)I,w:,;E #XCRDy]UJ=Ejʕ+,;}.Ԗخة q[HMTN}}e΀$Ζ((I---g=J] P2xA=y+k?LZ0ʠr8;\ >WQyhAg402쳺>;}~kvE/&-ٹyc{Y^Pbg+mp,^g&%ϭVr4$)1ɓ'v%NU$˶pEY-cVzΔ˪̂4NXEAгԊl$|K>²{27:(}C64jL}ڂ~N^vZrϹ itTο0RK~'\ty￷ٖ%²gYPݖwvjjjVǘo=IkW|ld2\e>;5Ӳ̂Zu NXeeE[_,{uQUS6Ζht:1uBѿE`L,w217EN9*lk6[FϟW;2az1"σl+ OwuJ^?.;{+++= ʊPg{y֓)eǏ `` $ZT_Y]fn}sbv >'f'f|QF=\hԬIݤ/2h;e|*q^xYԣi.zۋ ձsLNЮK|>N{AؽNltЃ2#;ñZաxZ>;=0)L=&|zpt3i-)$kQB^ ,Tq[iҒm&gS;M)~'̭NL?_ @0Mr qkR7ts_be|LP.Ί}[{zz4s޺ N2yyy_PPTTQu^5g೓i⏳1;l7f5R#7k64>>-/[UNbfͶb*5vO^7ܓ9e(+l!2A#G1{|y͛{OwKvCr<1TĠr ے(W;h>%!F&b0DmWع Y޻߹͖la-xEO(h R:Yޏg?^U }p#{k< w5]r8A炧lwmet=ڼd`;l*5y_'L `_y'I^j-){@SR#;%efu@_TbJfGjۮ-:q: oEx\a[a/bb6ef [;?HNhә:ih@l^)ߩ+(i%F}zAaTʭtN-rf[Lh@G'?;M.ѓPIp<-/f4ϓܖk1;g 0-` DRmmTةl;[G'8 Q@^ pcdYDSqt~=;q+C;pB9bu}^]P{Xj;iW Wvv)=D҃Fvk6TFh;fN}GN 굱k+…QJ)J&WI\~'1?{>[x̝ђmoyIvqrw#DAy)+&/#?FWu]v③ZqSUH)j 9ًM˗e9/4ݿu}lU?͙Y>+llMu)f9uS n=ʮ WS7񍠤upbj|hRvpw5ݠ4]q-ʱ;ГN;sG`3Qx.nص:PC솗1<)9 1k0rQk(TL]Ïz: Աmutgu.ɽߩ/cd'mΈ2;eSONTG}ٱm i֖FBʂ8w;g<ɎD ;{8/Lܛtx^Տr3OYO\;Yfﴁy𜍟 / q_ap髤ģ7DΏ5NC,q֬U 4Zim]f g=hK3J"h:ЏOL\ꫯ @=Bg9|wQ?Oeb'cƑ$d|D[j]_6ͶS;o3s;ճJyQRbX,v:k!,/ 6mލn޺֝0dryw=%k7" ҈XbY;ӱ3eML7lp139;V,oMPg7?C$-WS~nK?+s8YSmܰիWMI)5Ɲ2h?Mdzȶ]c:[33~o/Wo2__y#*e9q%jyN8Kmz<;K=y%y˼xwjp(˲ ؜6 3mnʲ\ٶuHYeh;nܸ1vpeYV v;);61R3teſ"˲`gTڬ&`,`gMj,/β/vg_29YN.!,!cZμ?wJ6F=# 3;ىHBQc^w;~F=IOJ8~}5;!j!!MjvZ'ؙO~sI694$Ejd",z;Wc#I?!$:ҷFZS[2PM-zɟ5N je]\}  vIbM5:Z*sT#/%ZZX?tFvTiIȮQhk`;1f7iTi)ZTb"BW$A/ӄNg1`j:ױS;^Vo~g>@>ُ4Ғ;dwV?!uԏQ9Z ؙFv,bvP&-\vCe;1fPaCV,58^qC5j,ߙ1˘vYMw__>V3kuCWJe~g5Y'suɹF3?Wm(ό֊@e74~6KN+"$Eeؗc_3IGIx::!~k_d3i5G%7l|e秅?w?|Z$%O.%y!}%G'cƥCG}bd `gZv{Gz2 ^;ӳspcCehّΏ;;3d`-]T_p!uT'عtiG(GeD'\,; Ji*NűH[ rS!l)t&#[l1S}!%!Br>H"\²wIL3MTIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-plotdialogtop.png000644 001750 001750 00000010146 11544160206 023414 0ustar00synthsynth000000 000000 PNG  IHDR8nPLTEzszecf`_`bZbb>>;;;666://#3/F9W=_=a >c Ag!Kw!Kz"L{!L{!M|"N},Y0]5a7g9l8n:pEvE{C~<7CNJ@=<:99:@AAAAACIIJJJJJJKQRRRRRRRRSYZZZZZZZZZZ[abbccgkortxȶxdztRNS1u IDATx]h\UԉE1PLӉ CՆlB;8B %/Eֲ1ۮ6"AMt[uhLt*QxaӀsd7k2w{94ld@ilw(ΖM1(Z<-JVqM ;dl8M>~;ϟn*8(M!ahFk<To.vU6AI4amA#{ 'f{qik4VPyA q846>Hh5i%8/ jfi4J O{#{&eP+x8hmXHD!\+R]=8抃aXi5 -Te4T8[I.GNiaWW®p/UHhG1qj%ffOYq%qc3:;N:"}5*!a:L=V=KKя*tE҉g9/|iUr.Vq",u &zsV5J 5DfRE-Db'ڈc>r89ԩJV(ӾV&-q1!m5~>q0u ?i" iv8S9`We9Ji G]I4s}d4 GzpE3. " 1;7$ *G8G5wIO4=Ѷ6TUK4!=ǕiqӮ&1YcjQʱ-nqz;_쵫 3'εvW8A9%,$fqq@@@XMx+XOek]38˼JSPx?Se[iK_ B浛@_I۶B8id ,X}K) 9n4 ;O'P~LhFNHf\G/C0,3Ź)ta҄D &?O"=.VKk@ȺgqFGGC7.mx$Bš91eek-~G-ݤ Qyqy B/dsMCq6;MBuO׉sN-NTVY_տTa=8g~qfU`q1^̀8gq.bB956q,CIK¯#//T.K], PNyM,;wa$fo?*_7PKYj"Oce⌖BOZ,8%ބwEQt8, oqy\Yj)[`cL׺Y@e)ą8oKℬJx<̛ƚ#+۵~Vǫ_A?@@qc'sD 6"كL&K; p?HClMOӷXfkcG$n)8j&lI|\yՋD0֤V+_Zq^wPϓoKLtՑS֊:@UꊠH=xq2MqnִS44YVNwPg&::ix?88xx.(gi`;LJD/oJ,6HjX)(XqPW \v;$A>e"窌wjL|(&'%qjQK?Y) lTT ?Ɉ|tys1tkԻؐkڙ3:(o,$Ι]ᕻJq G:KJq֋FbN9{3R3n̍rw5?nq `CtwҪ81$Ί+ܪŜtwB/+5&|nb^;yf-{] IEy|_J:eU ];Y]Y'_}8/1o+=,9ƠsLV;e,W3<|2<4euY\%ET51 kƠICvaEce< @ IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-exportgraphics.png000644 001750 001750 00000013350 11544160206 023575 0ustar00synthsynth000000 000000 PNG  IHDR }PLTE"*")/-.10/2002012/4:%3C2I6P;Y=`=a =b!>b#?c =j8336=E K| Kz Kz Kz!L{!L{%L{"M|#O~*Z+\/^2^2_3j5l8n;o@sEnIjJjKhKfOauUbpjnpɱʡvZSNHFI~E}?z:x8w5x4|8|=?;788::@AAABBIJJJJJKQRRRSVZZZ[]acdlr{섴牺 tRNSGIDATxk7#;Lz o gM9\AB/J`|\_NĽ$^ "4D IIllB^E"5腂/ aݙݙ_VڕD;gf:|xʖ>txr!%-O>4zʖNM\-Kϑ)R冬Kcĩ|D(*7jFE1[FT4nX< ԳnxZ:/7HTNXL.씋fL O3Abgb0UB,*ɑiC oQ_(SǎZrqIIfpJ;SXsEce'>:ujbpju\ߏ>2*:,ʚ?N֚)a3ݸo~zvzǽ,Ӗinu ɨ6ry`9kLN_qdrfy|Ch{LW7 599===M(wׄL6mfߔu՟dTrl1ŌL"etC'^,,;7*Gg3ͳ96͝I+㏘T*#+,tbff-< ') K}Are~*&Kep 0 vҲSu6\=V0582j$a-;G-s^LSa<2r{{Ǹ78FO^X_\N23qjvYŔ9R0gsm^|^1_v̈l^i]ZbQb}*z^̈`ѝ;]rg8kW<&]{WSSj ʬyԘ"Һf<2U*\KTTq aDVH3f˲~yanϜSfFYu!3k _@e:erGEԲJNT Z*SBb陁K leWַ]X.2,f?ū.v8x%}*몮4FJkXgmcVjdvvuPX]-XR`cyVWf +Uosڕ- );I-ȡV-rp%?З:/Qʨdħx:kja3t22{;\ + ۉʉoU+?Г+:/ѽ{2{ΜdyHzyaSTUKc2Dr1bU{iCĨ܇%P*m([ * @ @*P͗4e*3EALM٠Bܥq(*҃?Xn-.[|¨ԣPHQi#%*VecѿoLPaEDAsrڎqP[8CB<[هHd-?Y;c8N:T働_bP/]n6R_JUI;éDY"rNlLQ?9YTSuCӐV?NչK$پ&~`aR &4*)q5v-S?U}{7'2(FJ+/TyN=ԑΉL*Q=Q2_zy~Hhs{(= @* *P$>*OBåBhJlPifqӮp̝er 15Tƨ,~+V,PC$h55TD<LJgTG9ܧb.1؊)D?3YDAb"}35T5sN\bTXvʎk`l\GK9$ijl+ytd0.ӆio7SCDr45TTH9<8*SCe]QV҉CJcTB(vs&&X">A~NjNshŦr>d9|k% %'0Ks:ٷEY*oT#}u**r3TrN%7sA%*T򩈩,iN>5=ƸT@PP@T P(Tyi>w2@eT$2LT63ĺˁMl+㸟K/%"bn-e*H,TH,:`^w5I[7cb@3> !eO(&m'J;9$ $QLE.,j+4Tw}sFY]PSIXRHIs:L裢dVG8'PoAE&F MU.^ ͚~*J*3*NR_V8%QbVV60Bhkv*j*Ej5/QPFqڕ *J*1*x \VhCקîe+0*AY>/zۼٱо}T%ab{ǥڱ #ƜJyV8PiÁ&6Thby2_Qv"X}&@* * @**"9`M,РBQ.PT@P@y^> #lP!ϒ;YxViWv޿>!KoTk0EPP@T PT@T@P@T P@T\ds6^s[*Ҷa*z*RAר'*qrm#mrPCb-b bVZ7(^B|`l*׶KTL[ %aQMqP UIetql ?8$,A]AM*]Py*z%le *]+ +D`KA!q ?[uU ˖]m%KxJxI[Yz۳|/9E׎$ ** @* * @ @* * * @g*s2(Q+HAYZA @T PT@(JQ,=*c I+;D͝3'MS(tySyѸO5vE?ozBxP_{rAUo"(*v ½3v7}yFRA OWζ5T?}X *Ħ+<5XߩT@PP@T PqEPe.]W$c K7~'APK; kMa>X썊fmDÑUĚ%KT4k '-5Sr)]*Ţ;* Gjw7)|c9V|}r)e*wGEpÑCE9V|)xcF(+O_T4&EJR;pWBUfT,pvP!6 o*/+^uG%`mDÑh?W?GI%lӹ]-{8Rv%lv9 -8;XkJs ̱J:Kއ,~d-E%tct6^k %ti}ݵ} q1_=,"ATtYdL,xn @* * @** * @* ** @2TePVűW4| @*Jڱ̗|1hA*;YL]̗t);+(R1 SzK5Jk$|c'T^L5J (Jk4͆: JK1U- 3`FPFJSIU.}_Q<*R` !#~2.$&u4a84q* Ydo( gi;ɩԉC:?ƋJ'J0jzsO(*ͦDݱB^*;8uqYYöCӄT:T>*^r@]WD#[T'4@űvûghRiTsǕDښ8NȪ.icLIDC@|9Fq@mPQȹ磲U !FJsW˥.Kvr :T1hɥҪu)J1 F\*\*]jk FvLT=SiJijg1>s.>Yc\* @*@* *B?O$50WcMIENDB`kst-2.0.3/docbook/kst/Formula-kst-linefitequation.png000644 001750 001750 00000000736 11544160206 023227 0ustar00synthsynth000000 000000 PNG  IHDR^upIDATH!lp]_TaX,␕X¡JtA,mYmSw?ȯH0/9c$lk2ืn#9Й}8@hbK蕚A͗|dajUp egy9 Dq8kH |{bƪf ?aRORި?Zҁf8.F y_n/E[@)(R)DK>|Ao$rwȤ.vcQ9֟C,G,[w9*f<5ghZ& 2;{a Ơs YCy |[nqϟrCggm58ݖ/weg15 3;WIENDB`kst-2.0.3/docbook/kst/Widget-kst-maximize.png000644 001750 001750 00000000447 11544160206 021467 0ustar00synthsynth000000 000000 PNG  IHDRЭIDAT(ϝS [`B7?M:: opx = XH+Ie8q/T0?n  ЫއKC*awk7rϪ!LXe2] gŨ|? ^ S 2=`0ex1y?cʐ~0! 2h@T|j1?qj ٲ~p2[@~\6x19 v*]#f x4IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-histogramwindow.png000644 001750 001750 00000012503 11544160206 023757 0ustar00synthsynth000000 000000 PNG  IHDR $$PLTE^saC  #$-%*0-.1//2+/5!1C4N9X<` =a=c?f Jy L{ L{ L{!L{$M{'Mz)O|,V/\.]2_6d7j6n9n=pArDqFmIjJiJiJiJiKhQVTRURRURRURRURSVSdfdŢzcccbbaZRQMFFID~;{5|3~588/ $s!T)h5999:@AAAAABIJJKKNSSSWYZ[^accekpt}ꃷ焷犽M!htRNS:IDATxOh_|j0 EY;ڪ)9 Dr6vRZ -!UECO0!Pp7NlcQCP6 8Ly쿙Wڙ7y}}x۶6oCwǽ7Pylε|\ײ300 Qj1_vĸNpա[#qG+`9Đ#A!NI|+;ƺD?t,dLȠ$Ν>d N#>XiN&=`ѴCLc- rF2NL(ɶXX~ccXC 8k* S\Js yFu4^?Pž' vE1bv;1ݻG@BXSFY;j(*_)ĩ<#Z^j#1Q'JZ,rDT_,,/4: 4HG yi^\lkiaG+jebx0K{B.d~\f2 J[ԓepug,+*|G1u !']+w*0+G?ut㊲0 D8_V10.b( kĀP1Èb8t֡ 1:-š0bA Gz' MbC{q b@Ȭ<"#1. 7CڂNCf+B "D[t@2=h ĠZ[,q@G*f& 1L b=B;Fh9[|Gr}CroFj M )9{C3FSУp `7XAeB xהb xw>A7]{(4A (ĀP1pb0µ{վ wbb7Ɏ 8Q7e0D2KꞞG \`ݡ5 VRkĠ Z F֝ho Df{(\R oq[904xq81#$v0 f7Q}R-Q 葒R21)O#| Cs_Cʳd17b@!ĀB \Ϝ!l)qhFP Щ*F("! i.?Bgop޽ _bUBpD,@?p6"eᎁA cX!1\x]*Z26(0ܶ/ϋa̞*I 4C!ĀB FC5:IfZwE!)u1T.gRBtQjĀC)'bYoo!$z +@fn> Π# ?^> ; qn>b ; /f'86lsPC Co@ Ԩ7 ߹( @cr:oS7x1)!ĀaV2Ox/zDE@1b@!ĐjwNs ơ61}+{ve0tt9r)wZC* •&٪3o!0j1v#hM'7_jc !=(voPt /E%p=]lt{@ 08|~|CK (ĀP1 Āb@ 1b@ {UjJCR VQ^&l1ZGU9J)kNU)`RjC9(q"􆃕 ػsνA?Ŷkbe?o/F$݁^uHNR۠Z%v?-bo[-3Uk 㦬:$°kCwbgO9G`P }u0k]g`z-mmp04CYbh(90`ZCHh9(A1B 577``8X_}TeD˳]pzS6~ [mխmˉk_]2iz=Lurݷ a;⌒Ue^Qo{^JկP*l]!װ]2k //~-kT [ul *[-N1|#ty7, ~q[ohy#F K3-6#S3k3)K;[zrT^P AO#b`/*o]~?T޺v;Tފ+ll1f}3*;]qax6#SmrjkPaxl6?^G{ͽM2$Ė61dޤA666iױ)!SU x1DᅕjbENM雲¢M9 *]|ۛWEM_[wkFZjFҍ\ԺI0lml~lRmm͒h!div,Y"xFi6wjU׻ֵ)5v@UDF+ ucV{ k:3ݾlpcW]h3 ( ~ g2 YD5VSAtFުۡx7N3c+m 8`GݽQ8eyn> L:ae|R+BpJ+8]m[R=G\{`V^[:gY`bdq* mV"@ 3퉟N`^rHunPqM(mߣ@U.y&2`]x7R;i.ۄ6ޛVɰ)-󫘝X)ShN3Zt&bٴ)g~PCV9:Os*Ѣ6!eŊ,S~>~}o+?Ե.=a% .K ;,ƷRB†FWiȲ,r-T,-6,vgPHW+_eIENDB`kst-2.0.3/docbook/kst/Icon-kst-datawizard.png000644 001750 001750 00000001111 11544160206 021430 0ustar00synthsynth000000 000000 PNG  IHDRĴl; pHYsnd tIME$͊!IDAT8˭KQgC'GQ2#Y>zBD E}B60֮]kٺ EA=7gMǙǽ3ss{. $Hp|%4sh$^8֊;jBXXjjZҹ]iACmZGk1ήo9LT$ YJ0:B7#4T2ܐo館Eu Di|ŲG RU^^9s5z{0I0[\VN̶1qFs궂.\fI3[aqvd@rՍ[AUV^>]B꛵2<~/FdsG2(}My]3[*M^d#EW`VH95I@o]a8H}?i+[jQKCO˖׊B Zsv+8~4)ESe#7IENDB`kst-2.0.3/docbook/kst/alternatehtml/alternate-index.html000644 001750 001750 00001165501 11544160206 023740 0ustar00synthsynth000000 000000 The Kst Handbook kst-2.0.3/docbook/kst/Screenshot-kst-datawizard3.png000644 001750 001750 00000022007 11544160206 022747 0ustar00synthsynth000000 000000 PNG  IHDR/2PLTEſſýŽƽƽż}~}||yy|rpniidgg`ce]_gZT`YLUWMSUSQUSRURRURRTRSPNNGEIAAH<>J7:8352121120/10/0**,   ,!:*K8Z=a >`"?c!Dj"Ky#L{!K{!L{!L{!M|#N}+X.\4]كos/}ЪDy<X J)fxjkŵ[kIr%:w97vǟɍ5y~^8(y)yo|S|%k~)?!>O9{c͌Ywvf4<_ 9g/޺v,>xgVNUz'/L$ۻYUT?XػU97J}4/?OQ2x޾mP?"yJq8r3ˮuͧp~?]x~X2x~,+f<?^v׶+f;">}]HyF<7L[/EQ^r/۾JL/$k׮]яύ<'yod\hNmAy1GRos3ca(PI,կWo\}޾ 흝'Ovӷ;;ћ{`@Nٓ* C5Tv~svw+/Υs7~&Si'zɃGe{xPVRRF@?Q|қ柋t*Z=BEJu hSEJ C?H3g!xF<#ug+{ԁM zuWL˳geH]VUX*cy( U;>iYlWD?zBxFYQyDDhΘ5ByZ. 5ag!xF<#u!OyN73B<#3B<#g!xF<#3BdҜܥo[U {P֫ )|+0u<zM_,OJg:K|ngW1IDZ.qM9׿Z;zcsWnZexNooo?:_z6sB=Zk=BWٚ6'I wfJ`2ߜ<)ЇY(y9`_o\!>^-Uh᭪߫-paNŘ ^Պ>3W[լZk0zh^wskyVs烃l#>O,T|^#>^-UϢʡCѫ~<9 W~5Q|k j7K\QV wwFJTW}tv~2HЭ-T(f'y9TلewX)Ssإz~zdl/pY-+!ơgzOx\z`k<׵ {ьz*xE{Uб\|"y~yf2xWW3Z3<3gxF TxgxF Ϩ9"4 l[ <8>2^2DLaD3룄\aLGa:Hs_Z9r]9ϧ[CȚ2aь(aY '( -u7"p1z(ϥao&'YNqpyH(i[-\' M<)ߘgJvJP|x 7~2Eo؇7F4cȟ(aʺg>ϑlX~;ϭ%1{p;<7G -2p7o37sSCe\`[A{5c*},") iy8-𼽝|>}= lf6˦Su 琟L<`lvIU1fY4ςYGjR8ܒ1̐yPπ>Wl׎ooȹo<~ XxN9xjX9Ak1򼱵 9xhܛNgxg3<3<3<#xg^gxF \WH<$a <gdyX?xxdl?xϾbϧ<'}߰d,gdy0<'<$<3gxg <3<#xgxgxg h<3 sOF nuγ'#Mx^(>TQxS|dJq\'ZE;s^NLCot}9/ϵ~2B\p -p^O6EfW#Zc .2 <goxF ψgxFSURS>>^\ڸ,e|6te4m)z$ql_/Ԩ`wyy׏ K[]45:onStgͪkЩRXg8_ijt/4ԏ%/sb,kn;5^?,^󜱴ѹ,MF-? Mų&<-&LKsFl4*v  ;lJFHg-#E*)xF-\%Ow_I3<5x)}9xnh8<S3<#xgxF ᙮Wy<3wy>tS'DSl ! Va*\hM7f8@-r.jK[ó%YZӦ !yvfmׂOujsgy2_=m*'qntUSofuي x>s`L bZe`.Y bsC1Yijl,hΟY%ղ!o*7lY81^>b?p(4JsqsKwfxNFA2!y.cYgxĢ^CBS E0>=f>Ҳǟr+B~l|<'_˔QZ8y2xOf(< ~2 y:sA[lS4ۅn*xF<#3gn!4 ΉwN?a:MhIENDB`kst-2.0.3/docbook/kst/plugins-chapter.docbook000644 001750 001750 00000144724 11544160206 021574 0ustar00synthsynth000000 000000 Plugins, Fits, and Filters Plugins provide added functionality to &kst;. By default, &kst; comes packaged with an extensive selection of built-in plugins. In addition, a simple and consistent interface allows for easy creation of 3rd-party plugins. Fits and Filters are simply subsets of the set of plugins, and thus behave identically to plugins, with the exception of additional convenience dialog functionality accessible from the plot context menu. Adding and Removing Plugins By default, the built-in plugins are stored in /usr/lib/kde3/kstplugins/ (this directory may vary, depending on where you installed &kst;). The Plugin Manager can be used to add and remove plugins. It can be acccessed by selecting Plugins... from the Settings menu. A list of the currently installed plugins is displayed in the Plugin Manager. To add a plugin, click the Install... button. Browse to the directory containing both the plugin specification file (*.xml) and the object file (*.o). Click OK, and the plugin should be installed. To remove a plugin, simply highlight the plugin in the Plugin Manager and click Remove. You will be prompted for confirmation. To quickly refresh the list of plugins displayed in the Plugin Manager, click Rescan. Doing so will remove any plugins no longer present in their specified paths, and add any new plugins in the default plugins directory. Built-in Plugins To date, there are more than 25 built-in plugins available in &kst; that perform functions from taking cross correlations of two vectors to producing periodograms of a data set. The settings window for every plugin consists of two main sections—an input section and an output section. Each section is composed of a set of scalars and/or vectors. The following screenshot shows the settings window for a typical plugin. The only difference between the different plugins is the set of inputs and outputs, and the mechanism for deriving the outputs from the inputs. Plugins Window Plugins Windowpluginswindow The following sections describe the purpose, key algorithms or formulas used to perform calculations, and inputs and outputs for each plugin. Note that fitting and filtering plugins are included in the following sections. Autocorrelation The autocorrelation plugin calculates correlation values between a series (vector) and a lagged version of itself, using lag values from floor(-(N-1)/2) to floor((N-1)/2), where N is the number of points in the data set. The time vector is not an input as it is assumed that the data is sampled at equal time intervals. The correlation value r at lag k is: Autocorrelation formula Inputs X Array (vector) The array x of values to calculate correlation values for. Outputs Step Number (vector) The array of step, or lag values. Correlation Value (vector) The array of correlation values calculated using the corresponding step number in the Step Number vector. Bin The bin plugin bins elements of a single data vector into bins of a specified size. The value of each bin is the mean of the elements belonging to the bin. For example, if the bin size is 3, and the input vector is [9,2,7,3,4,74,5,322,444,2,1], then the outputted bins would be [6,27,257]. Note that any elements remaining at the end of the input vector that do not form a complete bin (in this case, elements 2 and 1), are simply discarded. Inputs Input Vector (vector) The vector to bin. Bin Size (scalar) The size to use for each bin. Outputs Bins (vector) The array of means for each bin. Butterworth band-pass The Butterworth band-pass plugin filters a set of data by calculating the Fourier transform of the data and recalculating the the frequency responses using the following formula Autocorrelation formula where f is the frequency, fc is the low frequency cutoff, b is the bandwidth of the band to pass, and n is the order of the Butterworth filter. The inverse Fourier transform is then calculated using the new filtered frequency responses. Inputs X Array (vector) The array of values to filter. Order (scalar) The order of the Butterworth filter to use. Low cutoff frequency (scalar) The low cutoff frequency of the Butterworth band pass filter. Band width (scalar) The width of the band to pass. This should be the difference between the desired high cutoff frequency and the low cutoff frequency. Outputs X Filtered (vector) The array of filtered data values. Butterworth band-stop The Butterworth band-stop plugin filters a set of data by calculating the Fourier transform of the data and recalculating the the frequency responses using the following formula Autocorrelation formula where f is the frequency, fc is the low frequency cutoff, b is the bandwidth of the band to stop, and n is the order of the Butterworth filter. The inverse Fourier transform is then calculated using the new filtered frequency responses. Inputs X Array (vector) The array of values to filter. Order (scalar) The order of the Butterworth filter to use. Low cutoff frequency (scalar) The low cutoff frequency of the Butterworth band stop filter. Band width (scalar) The width of the band to stop. This should be the difference between the desired high cutoff frequency and the low cutoff frequency. Outputs X Filtered (vector) The array of filtered data values. Butterworth high-pass The Butterworth high-pass plugin filters a set of data by calculating the Fourier transform of the data and recalculating the the frequency responses using the following formula Autocorrelation formula where f is the frequency, fc is the high frequency cutoff, and n is the order of the Butterworth filter. The inverse Fourier transform is then calculated using the new filtered frequency responses. Inputs X Array (vector) The array of values to filter. Order (scalar) The order of the Butterworth filter to use. Cutoff frequency (scalar) The cutoff frequency of the Butterworth high pass filter. Outputs X Filtered (vector) The array of filtered data values. Butterworth low-pass The Butterworth low-pass plugin filters a set of data by calculating the Fourier transform of the data and recalculating the the frequency responses using the following formula Autocorrelation formula where f is the frequency, fc is the low frequency cutoff, and n is the order of the Butterworth filter. The inverse Fourier transform is then calculated using the new filtered frequency responses. Inputs X Array (vector) The array of values to filter. Order (scalar) The order of the Butterworth filter to use. Cutoff frequency (scalar) The cutoff frequency of the Butterworth low pass filter. Outputs X Filtered (vector) The array of filtered data values. Chop The chop plugin takes an input vector and divides it into two vectors. Every second element in the input vector is placed in one output vector, while all other elements from the input vector are placed in another output vector. Inputs Array (vector) The array of values to perform the chop on. Outputs Odd Array (vector) The array containing the odd part of the input array (i.e. it contains the first element of the input array). Even Array (vector) The array containing the even part of the input array (i.e. it does not contain the first element of the input array). Difference Array (vector) The array containing the elements of the odd array minus the respective elements of the even array. Index Array (vector) An index array the same length as the other three output arrays. Convolution The convolution plugin generates the convolution of one vector with another. The convolution of two functions f and g is given by: The order of the vectors does not matter, since f*g=g*f. In addition, the vectors do not need to be of the same size, as the plugin will automatically extrapolate the smaller vector. Inputs Array One (vector) One of the pair of arrays to take the convolution of. Array Two (vector) One of the pair of arrays to take the convolution of. Outputs Convolved (vector) The convolution of the two input vectors. Crosscorrelation The crosscorrelation plugin calculates correlation values between two series (vectors) x and y, using lag values from floor(-(N-1)/2) to floor((N-1)/2), where N is the number of elements in the longer vector. The shorter vector is padded to the length of the longer vector using 0s. The time vector is not an input as it is assumed that the data is sampled at equal time intervals. The correlation value r at lag k is: crosscorrelation formula Inputs X Array (vector) The array x used in the cross-correlation formula. Y Array (vector) The array y used in the cross-correlation formula. Outputs Step Number (vector) The array of step, or lag values. Correlation Value (vector) The array of correlation values calculated using the corresponding step number in the Step Number vector. Deconvolution The deconvolution plugin generates the deconvolution of one vector with another. Deconvolution is the inverse of convolution. Given the convolved vector h and another vector g, the deconvolution f is given by: The vectors do not need to be of the same size, as the plugin will automatically extrapolate the shorter vector. The shorter vector is assumed to be the response function g. Inputs Array One (vector) One of the pair of arrays to take the deconvolution of. Array Two (vector) One of the pair of arrays to take the deconvolution of. Outputs Deconvolved (vector) The deconvolution of the two input vectors. Fit exponential weighted The Fit exponential weighted plugin performs a weighted non-linear least-squares fit to an exponential model: An initial estimate of a=1.0, =0, and b=0 is used. The plugin subsequently iterates to the solution until a precision of 1.0e-4 is reached or 500 iterations have been performed. Inputs X Array (vector) The array of x values for the data points to be fitted. Y Array (vector) The array of y values for the data points to be fitted. Weights (vector) The array of weights to use for the fit. Outputs Y Fitted (vector) The array of fitted y values. Residuals (vector) The array of residuals. Parameters (vector) The best fit parameters a, , and b. Covariance (vector) The covariance matrix of the model parameters, returned row after row in the vector. chi^2/nu (scalar) The weighted sum of squares of the residuals, divided by the degrees of freedom. Fit exponential The Fit exponential plugin is identical in function to the Fit exponential weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist. Fit gaussian weighted The Fit gaussian weighted plugin performs a weighted non-linear least-squares fit to a Gaussian model: An initial estimate of a=(maximum of the y values), =(mean of the x values), and =(the midpoint of the x values) is used. The plugin subsequently iterates to the solution until a precision of 1.0e-4 is reached or 500 iterations have been performed. Inputs X Array (vector) The array of x values for the data points to be fitted. Y Array (vector) The array of y values for the data points to be fitted. Weights (vector) The array of weights to use for the fit. Outputs Y Fitted (vector) The array of fitted y values. Residuals (vector) The array of residuals. Parameters (vector) The best fit parameters , , and a. Covariance (vector) The covariance matrix of the model parameters, returned row after row in the vector. chi^2/nu (scalar) The weighted sum of squares of the residuals, divided by the degrees of freedom. Fit gaussian The Fit gaussian plugin is identical in function to the Fit gaussian weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist. Fit gradient weighted The gradient weighted plugin performs a weighted least-squares fit to a straight line model without a constant term: The best-fit is found by minimizing the weighted sum of squared residuals: for b, where wi is the weight at index i. Inputs X Array (vector) The array of x values for the data points to be fitted. Y Array (vector) The array of y values for the data points to be fitted. Weights (vector) The array containing weights to be used for the fit. Outputs Y Fitted (vector) The array of y values for the points representing the best-fit line. Residuals (vector) The array of residuals, or differences between the y values of the best-fit line and the y values of the data points. Parameters (vector) The parameter b of the best-fit. Covariance (vector) The estimated covariance matrix, returned row after row, starting with row 0. Y Lo (vector) The corresponding value in Y Fitted minus the standard deviation of the best-fit function at the corresponding x value. Y Hi (vector) The corresponding value in Y Fitted plus the standard deviation of the best-fit function at the corresponding x value. chi^2/nu (scalar) The value of the sum of squares of the residuals, divided by the degrees of freedom. Fit gradient The Fit linear plugin is identical in function to the Fit gradient weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist. Fit linear weighted The Fit linear weighted plugin performs a weighted least-squares fit to a straight line model: The best-fit is found by minimizing the weighted sum of squared residuals: for a and b, where wi is the weight at index i. Inputs X Array (vector) The array of x values for the data points to be fitted. Y Array (vector) The array of y values for the data points to be fitted. Weights (vector) The array containing weights to be used for the fit. Outputs Y Fitted (vector) The array of y values for the points representing the best-fit line. Residuals (vector) The array of residuals, or differences between the y values of the best-fit line and the y values of the data points. Parameters (vector) The parameters a and b of the best-fit. Covariance (vector) The estimated covariance matrix, returned row after row, starting with row 0. Y Lo (vector) The corresponding value in Y Fitted minus the standard deviation of the best-fit function at the corresponding x value. Y Hi (vector) The corresponding value in Y Fitted plus the standard deviation of the best-fit function at the corresponding x value. chi^2/nu (scalar) The value of the sum of squares of the residuals, divided by the degrees of freedom. Fit linear The Fit linear plugin is identical in function to the Fit linear weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist. Fit lorentzian weighted The Fit lorentzian weighted plugin performs a weighted non-linear least-squares fit to a Lorentzian model: An initial estimate of a=(maximum of the y values), x0=(mean of the x values), and =(the midpoint of the x values) is used. The plugin subsequently iterates to the solution until a precision of 1.0e-4 is reached or 500 iterations have been performed. Inputs X Array (vector) The array of x values for the data points to be fitted. Y Array (vector) The array of y values for the data points to be fitted. Weights (vector) The array of weights to use for the fit. Outputs Y Fitted (vector) The array of fitted y values. Residuals (vector) The array of residuals. Parameters (vector) The best fit parameters x0, , and a. Covariance (vector) The covariance matrix of the model parameters, returned row after row in the vector. chi^2/nu (scalar) The weighted sum of squares of the residuals, divided by the degrees of freedom. Fit lorentzian The Fit lorentzian plugin is identical in function to the Fit lorentzian weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist. Fit polynomial weighted The Fit polynomial weighted plugin performs a weighted least-squares fit to a polynomial model: where n is the degree of the polynomial model. Inputs X Array (vector) The array of x values for the data points to be fitted. Y Array (vector) The array of y values for the data points to be fitted. Weights (vector) The array of weights to use for the fit. Order (scalar) The order, or degree, of the polynomial model to use. Outputs Y Fitted (vector) The array of fitted y values. Residuals (vector) The array of residuals. Parameters (vector) The best fit parameters c0, c1,..., cn. Covariance (vector) The covariance matrix of the model parameters, returned row after row in the vector. chi^2/nu (scalar) The weighted sum of squares of the residuals, divided by the degrees of freedom. Fit polynomial The Fit polynomial plugin is identical in function to the Fit polynomial weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist. Fit sinusoid weighted The Fit sinusoid weighted plugin performs a least-squares fit to a sinusoid model: where T is the specified period, and n=2+2H, where H is the specified number of harmonics. Inputs X Array (vector) The array of x values for the data points to be fitted. Y Array (vector) The array of y values for the data points to be fitted. Weights (vector) The array of weights to use for the fit. Harmonics (scalar) The number of harmonics of the sinusoid to fit. Period (scalar) The period of the sinusoid to fit. Outputs Y Fitted (vector) The array of fitted y values. Residuals (vector) The array of residuals. Parameters (vector) The best fit parameters c0, c1,..., cn. Covariance (vector) The covariance matrix of the model parameters, returned row after row in the vector. chi^2/nu (scalar) The weighted sum of squares of the residuals, divided by the degrees of freedom. Fit sinusoid The Fit sinusoid plugin is identical in function to the Fit sinusoid weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist. Interpolation Akima spline The Interpolation Akima spline plugin generates a non-rounded Akima spline interpolation for the supplied data set, using natural boundary conditions. Inputs X Array (vector) The array of x values of the data points to generate the interpolation for. Y Array (vector) The array of y values of the data points to generate the interpolation for. X' Array (vector) The array of x values for which interpolated y values are desired. Outputs Y Interpolated (vector) The interpolated y values. Interpolation Akima spline periodic The kstinterp akima periodic plugin generates a non-rounded Akima spline interpolation for the supplied data set, using periodic boundary conditions. Inputs X Array (vector) The array of x values of the data points to generate the interpolation for. Y Array (vector) The array of y values of the data points to generate the interpolation for. X' Array (vector) The array of x values for which interpolated y values are desired. Outputs Y Interpolated (vector) The interpolated y values. Interpolation cubic spline The Interpolation cubic spline plugin generates a cubic spline interpolation for the supplied data set, using natural boundary conditions. Inputs X Array (vector) The array of x values of the data points to generate the interpolation for. Y Array (vector) The array of y values of the data points to generate the interpolation for. X' Array (vector) The array of x values for which interpolated y values are desired. Outputs Y Interpolated (vector) The interpolated y values. Interpolation cubic spline periodic The Interpolation cubic spline periodic plugin generates a cubic spline interpolation for the supplied data set, using periodic boundary conditions. Inputs X Array (vector) The array of x values of the data points to generate the interpolation for. Y Array (vector) The array of y values of the data points to generate the interpolation for. X' Array (vector) The array of x values for which interpolated y values are desired. Outputs Y Interpolated (vector) The interpolated y values. Interpolation linear The Interpolation linear plugin generates a linear interpolation for the supplied data set. Inputs X Array (vector) The array of x values of the data points to generate the interpolation for. Y Array (vector) The array of y values of the data points to generate the interpolation for. X' Array (vector) The array of x values for which interpolated y values are desired. Outputs Y Interpolated (vector) The interpolated y values. Interpolation polynomial The Interpolation polynomial plugin generates a polynomial interpolation for the supplied data set. The number of terms in the polynomial used is equal to the number of points in the supplied data set. Inputs X Array (vector) The array of x values of the data points to generate the interpolation for. Y Array (vector) The array of y values of the data points to generate the interpolation for. X' Array (vector) The array of x values for which interpolated y values are desired. Outputs Y Interpolated (vector) The interpolated y values. Noise Addition The Noise addition plugin adds a Gaussian random variable to each element of the input vector. The Gaussian distribution used has a mean of 0 and the specified standard deviation. The probability density function of a Gaussian random variable is: Inputs Array (vector) The array of elements to which random noise is to be added. Sigma (scalar) The standard deviation to use for the Gaussian distribution. Outputs Output Array (vector) The array of elements with Gaussian noise added. Periodogram The periodogram plugin produces the periodogram of a given data set. One of two algorithms is used depending on the size of the data set—a fast algorithm is used if there are greater than 100 data points, while a slower algorithm is used if there are less than or equal to 100 data points. Inputs Time Array (vector) The array of time values of the data points to generate the interpolation for. Data Array (vector) The array of data values, dependent on the time values, of the data points to generate the interpolation for. Oversampling factor (scalar) The factor to oversample by. Average Nyquist frequency factor (scalar) The average Nyquist frequency factor. Outputs Frequency (vector) The frequency vector. Periodogram (vector) The frequency response vector for the periodogram. Statistics The statistics plugin calculates statistics for a given data set. Most of the output scalars are named such that the values they represent should be apparent. Standard formulas are used to calculate the statistical values. Inputs Data Array (vector) The array of data values to calculate statistics for. Outputs Mean (scalar) The mean of the data values. Minimum (scalar) The minimum value found in the data array. Maximum (scalar) The maximum value found in the data array. Variance (scalar) The variance of the data set. Standard deviation (scalar) The standard deviation of the data set. Median (scalar) The median of the data set. Absolute deviation (scalar) The absolute deviation of the data set. Skewness (scalar) The skewness of the data set. Kurtosis (scalar) The kurtosis of the data set. kst-2.0.3/docbook/kst/Formula-kst-generallinearmodel.png000644 001750 001750 00000000560 11544160206 023653 0ustar00synthsynth000000 000000 PNG  IHDR8{!7IDAT8cO&`F20X1i61Lo֐Խ pXD*3\݈ŏoj_6n`浚m6nc8$t,~i|̚hX_q<0=)|ɏ/:CEY+#p1CSs W63o2YvF2m'2] C?{N ޣģ="!>UDјٍUK#2f~N27SG!+w|JF IEjixe(Wl/=RIENDB`kst-2.0.3/docbook/kst/Formula-kst-autocorrelation.png000644 001750 001750 00000002215 11544160206 023233 0ustar00synthsynth000000 000000 PNG  IHDR;͐@TIDAThZ?h\A:N...\?pprCS,N.. BA(C_b{sn-ϼW=yӮ].u- -BgfxU7gO d2Į~{={t]i%M&ݥj w v ]/ !pYT6c}PyFV0pYT1PjY171F?W!)]EE#_9VpJ6D(csyy&h]{>;Շʂ8 Y`dS},0tZb{SLc',0|&*ܮpI,OyZ8%|Ee9^Skqc[98^OγG;)ǥa$#nRQ0u)59aܸ^kACp49U {}S}݆qIEUv-2#5 Vڶ}vVsQ^|MM* .-+{ٮw!0C'a3Јpj&Cn86!cށJECotIRPgPȧ w{ɁM* WfI;%t&?I=};#~KKrbCW%G!61l{ƷR__@3s ƹ*2-Ψ,8gts$!%fz8nq;!w`H4-dGpbe?8RH gTtP-g&@`éC^ dS~gÿ[,QQF^WmB\pu8V^ᔊ1o)p.v{Xl:ǰ/ Tnpfu&d@&0l)??~pp}7ѕt⢋CJ6.:tBLt9J_UF#]66uhݰft9JϸK6&1Dc[7ߨ\/:<xL@hIENDB`kst-2.0.3/docbook/kst/Formula-kst-bandpass.png000644 001750 001750 00000002302 11544160206 021611 0ustar00synthsynth000000 000000 PNG  IHDR]qIDATh!L/% BP'( Up(TAA:C$$\BBr%$!.zwm|`ٝ]D;f Event Monitoring An event monitor data object essentially keeps track of one or more vectors or scalars, and performs a specified action when a specified condition involving the vectors or scalars is true. Event monitors are usually used in conjunction with live, or streaming data. For example, an event monitor could be created to monitor whether or not elements of a data vector representing temperature exceed a predefined value. Event Monitor Dialog The following is a screenshot of the window displayed when creating or editing events. Explanations of the settings are listed below. Event Monitor Window Event Monitor Window Expression The condition to monitor for, along with other event properties, can be modified in this section. Operators A list of available operators. Choosing an operator from the list inserts the operator at the current insertion point in the Expression text box. Vectors A list of the current vector objects in &kst;. Choosing a vector from the list inserts the vector at the current insertion point in the Expression text box. Scalars A list of the available scalar values. This list is composed of both the scalar values in the current &kst; session as well as some built-in constants. Choosing a scalar from the list inserts the scalar at the current insertion point in the Expression text box. Expression The expression to monitor. You may type directly in this textbox, or select items to insert using the above drop-down lists. Ensure that the expression entered in this textbox is a boolean expression (i.e. it evaluates to either true or false). This usually entails using an equality or inequality in the expression. Note that vectors entered in the textbox will be monitored according to their individual elements. Whenever this expression is true, the event will be triggered. The action taken upon an event trigger depends on the settings specified in the next two sections. Description This textbox is used to store a short description of the event. The description is primarily available as a method for keeping track of multiple events. You can enter any text you wish in this textbox. Kst Debug Log This section specifies settings for entries added to the &kst; debug log when events are triggered. Log as: Enable this checkbox to have entries added to the &kst; debug log when this event is triggered. There are three types of entries in the debug log—notices, warnings, and errors. Select the desired type of entry using the corresponding radio button. E-Mail Notification In this section, settings for sending e-mail notifications of event triggers can be specified. Notify Enable this checkbox to have &kst; send e-mail notifications to the specified address when this event is triggered. Also enter in the email address you would like to appear in the From field of the email in the Sender textbox. ELOG &kst; supports adding entries to an ELOG logbook upon event triggers. This can be useful for remotely monitoring live data, or for obtaining summaries of event activity. Notify Selecting this checkbox enables ELOG logging functionality for this event monitor. Click Configure... to specify server and logging settings. The ELOG Extension The ELOG extension allows event monitors to create logbook entries on a server running the Electronic Logbook (ELOG) application. The created logbook entries can be used, for example, to remotely monitor &kst; events or to produce periodical reports on data. For information on configuring and maintaining an ELOG server, please see the official ELOG Homepage. To enable the ELOG extension in &kst;, select Extensions... from the Settings menu and ensure that ELOG Extension is checked. Server and Logging Settings Server and logging settings should be configured if ELOG functionality is enabled for an event monitor object. To configure logging settings, click the Configure... button in the ELOG section of the Event Monitor dialog. The ELOG Event Entry dialog should be displayed: Event Monitor Logging Settings Event Monitor Logging Settings Use the three checkboxes at the bottom to select the type of information to be logged. Include Kst capture specifies that a screen capture of the currently active window should be included in the entry. Include Kst configuration file specifies that *.kst save file should be attached to the entry. Finally, if Include Kst debugging information is checked, a copy of the debug log will be attached to the entry as well. Additional fields will appear in this dialog once ELOG server settings are configured. To customize ELOG server settings, click the Configuration... button. The following dialog should be displayed: Event Monitor Server Settings Event Monitor Server Settings Descriptions of the settings in this dialog follow. Configuration, Save, and Load The Configuration drop down list contains a list of saved ELOG server configurations. To load a set of configuration settings, select an item from the list and click the Load button. To save the current configuration settings in this dialog into a slot, select the desired slot and click the Save button. Saving settings into a slot overwrites any existing settings in that slot. IP address and Port number Enter the IP address of the machine running the ELOG server application. The port number that the ELOG server listens on is configurable through the server, but by default it is 8080, so if you are unsure, enter 8080 as the port number. Logbook Each ELOG server can contain one or more logbooks, so the name of the logbook to write entries to must be specified. Ensure that the spelling of the logbook is correct. User name, User password, and Write password Depending on the how the ELOG server application is configured, these settings may or may not be necessary. If they are, enter the correct login credentials in the appropriate textboxes. Capture size Use this list box to select the size, in pixels, of the &kst; screen capture to attach (if specified). Submit as HTML text If this checkbox is selected, HTML tags may be used in the logbook entry. Suppress e-mail notification If the logbook is configured to send e-mail notifications of new entries, selecting this checkbox will disable the notifications. Note that this option is not related to &kst;'s own e-mail notification setting for event monitors. Click the Apply button to apply the entered settings. Click Update to update the ELOG Event Entry dialog (the previous dialog). Additional fields should appear in the ELOG Event Entry dialog. These fields are unique to the selected logbook. Once you are satisfied with the settings, the Test button can be used to send a test logbook entry. Click Close to exit the dialog. kst-2.0.3/docbook/kst/Widget-kst-swapcolour.png000644 001750 001750 00000000235 11544160206 022035 0ustar00synthsynth000000 000000 PNG  IHDR s; pHYs  ~tIME%mbKGD̿.IDAT#BQT UU@UT]q%AIIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-pluginswindow.png000644 001750 001750 00000013563 11544160206 023452 0ustar00synthsynth000000 000000 PNG  IHDR} 8PLTEtv     & +#+#*)$).$),%*&*1(0:)5C#6I!:Q=X>_=a=b!>c#@c#El"Is!Ky$L{&L{$L{!L{ L{ L{ L{!N}&S,Z.]1^5`:`@]}HZkQVWRURRTQQSQRURRURRURRURSVSVWV`XWocf~Y~Dt;p7n7q5x3|2~7>DIMOPJ=7+899:@AAAAADIJJJMQRSXYZ[^acdkpt0qtRNS) IDATxMkm&|$l, xdܜwV![,Nb.#92DBBa梋a.}g_kzOuuSݗ._ހ_^tyc?P=q3.m\xO.Q(k硪!׾uZ_CjV=uZNg<=4NBs0)uB.Q3Dtz j6wjs'~>scS[ xy}tӵu:o+"ǀ|iG=BzڋWK/E<5K⋇|W֔4>i<^{bg_N_Nf Zwen4^=z^y?_t)xJvRx}^wՖZ- ~"xHBrykFlG +k{=F۟VȾz['쉸׃YxԵ3DzuƳVU}Wz{Kĉ4^z~67m{K/\_1UyěsْsqZz[P aRy={v_ܛBebe!!^gyj<^/T^^^^N.Gw_AydK]/Z /RxՁWiEܹ2JATFɋ"H,yk$% ݙEK~x$22}H`SVTlj ? Iy^$C[R+X v[*Rx9V^R WsRhE( 4;RA$_F4+T2H"}9V21 `BԪ3ٗZI/_FjP9e䵄/=)>6ڇyAx^q+:Z2WKfA-WcuHEbp{ %_'^.J>/^ / /+ӧ;z?y>R7(-4^~dx"2{i~sls!3|_xV؋쎋Piw=iK&}(^wJ?߿k6ym UXw:(W +p<<ۇ>i5Be bj`_xA^xA^x5DY;agwT`xfgꩮDNgQ7skԝ뢈U5=H^g(7_B3T3aՠ"2;DI)27f&y~aN^lOʃŒ`(ce5)snun/A^^ ir!dbjψ%^lfENLP̔)mODYHƚ7+b]vb輔(EDFmLAf%#K&2[R fJK<$X8:e%1HNɜZ̴A|\$7kcRѡ( WaX)3Nrz(/xxXy0/%υ/(%7g##tdjO-sM/m_S@Xk[Zal.}}}^^ki.rx I3(|@-S>zFnDڒ};}k?`Scu-!H^ʿ~#t;JM(ȏ|ɒ/^-OJni{XTkhp kL?#{8<9Y9iEg2^^ɢirHHQǤrO'B%/ǬCVEk|..3P^^ッ0^^8::y+ī݇ )7gP B^xA^^x`JJ|JE٠* / / / /+&ZZ^bR/O!J)sCE;o ?*"BT範oZثj +5z=wWz^d/̋yQE+zdoC/|zWcU÷-5/ / / y.)]$%%JNJK}Xj)y9d)% .s{D`ٲJC=rg\DغXQP%_Q7]P#y9^V w ܅sUKWJú4Kwj:;A"o_WDYCӾؒ&B_ھo+aƶiƟv~ևdAPqGXf1_>f͋Aqa }8WR}9c$}H+F)/[| UڱF9Sj.Ik4W외.5r+xՁnW5yQ nڇU} 2 pN.Vu講oTΎw岴yRz4(Wa^@[m3JߊWLRC]FDk7l,#p(GK)'iXѣ;Dž_V %?"S D n_mSؗ=.S/!󐭋$WDСO2^:5s|(+}ǥK/Z[1^xA^xA<^+x> / /*~ת>xUVY5WQZ]IwVMuVH]tv^F;FݩԼu61<&:3x1XN_MKށ*H| L50 $s·x%<.u\Ƽ_ 1a)4\y^ ?o^4` &$LAY͐W1,#:Xx3xej s48WFrJ/}iƞdv!!=A d2ڇ q,W3V}x!xxW= ( /hyx}X3\ //O%pq2n^xߛ/\^} |J Ϋ,^c 2|sSȿ?}|+ - oQ/ڇe%6G_*ۿ׿Rʾ%WxFC/z/ÿ߀^xA^h}8\ //O ҝFk&GdG[{)pE D';ΫɌ"οe^[~;W^Y+54^(i+}91=þ}+}X2> ^3utcۇi+E/2xxտ߀( /B/oxxy*ۿ71W{Rz/D^}wP <t^*vK+_r }V|+ F{/xe/'}9E|{CY)D >JwCÂOrgs U+^x<xx5߀( / / /B1^x^x^x^x^x^x^x-[PUKq / / / / / / / / /:ϠCUWJ\} `J ׻bVw5W^&5'yMV2lxuU^ț]SA4/U3~^x5@s k^%"90Iklj["[LmWN^#U$$% ,H2ȃW9&QBRҍ4W,}^#V_ 0 >xk_">yMF[LU3DʇOErTxc\.XTJ54Ķs8Jh^u^xOԉM/4IAW x5Ju뤰+ xkA{ZA2x-Hy7 9? ./ / / /8^Em\G?a"yIENDB`kst-2.0.3/docbook/kst/Formula-kst-sinusoidfitequation.png000644 001750 001750 00000004532 11544160206 024133 0ustar00synthsynth000000 000000 PNG  IHDR5;1 !IDATxMH[ElCn.B •  ! ..AAp PDD(HZ| (y 9od3YXL=q\jk+w]}x}⎻V;N+̲Gxn$9rGN7hO9"DÏ^Kq{f? O}y30Gyf2e+}py/%5dqqoq?a(s4' 9b|cAlD$W!}w=cAHtGh94E!='a Vr132}Ĝ($\:'Vnh*TIEqx<y<'d89wB{Og-_7hRltAjO<"'^}rv?SYAH8uEO@Wm{Ƹ?zGBL*z e=_-#HNb(uq5-T[F~ڕ㮂c~'fIn$~ˀwZjwddpL?SKrqSL'*)bx6²" {RgTbהI3 xk|s$Q>СH[ƍ1% yhFF}K*մ7i!J zSJ &DE?M'Cu($o8kps$Q׮ ps-~`0/sؠ3IB$: (%NjZ2wLβ"3'ÚI>_7GʵWF6͋uz(|^waS?+MŇTմ[r1m?LeTnC,T4mQDRIbP2S_}#$u҈ґH{Dwo ?[i?@).qilTxd"*J]ڕpFk6 2g:6ErTTX{Ej5) tJ &0PHpFm4I(.w·uF7@>uƽtp@0'E@ T\QEM'ҋ&Mzw&3QH8ƽgap(P>y{?a`N[#Rc@'|t03`-|l055:!RvY֩%%0F2X%m4kJ˲3#V5ʯ}l3]^l 񖀼IhxoiSz%I9|C)~##V KLCV-yЮ$8 Ӌ6%X>*}7NDW*ݑbcĪBɿmzn{efl̵3 OB 9v0#b9"鍘Pα;]qaLo$ 癄[`%nZEOBq۝NggELBqܝN~:QLo$wY,GQ21f9wS+F3`9"鍙(η;]% (ޘI2ө/b"`9"鍚fj"wWqwwWqwwWqwqQ@(cIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-plotdialoglegend.png000644 001750 001750 00000016613 11544160206 024055 0ustar00synthsynth000000 000000 PNG  IHDR8\FMPLTEĺ=a"?a,C`=L]PU[UWZXYZYZZXZY        (#"#(!$) $) $)#*",#0'6(,30/2404B8;VBB\OMTTQSURRUTSVSVXV=a>a!>`!@d Iu Kz Kz L{ K{ K{ K{ L{!Lz!Mz#My(My(My)O}+V-[.\0^2^6^@ZOMZ@_4f:qByK~Vgx|Q{Dt9p7n9rA{FC:5?KQJ>:99:@AAAABIJJJKMQRSUZZ[]cpoU%tRNSѥ\+IDATxkWN9 ;,,$YY=ihM g.:m25&,X!Bb!u CaE7|0C&[U~UuUWT?_իzѫzWWjꫯV[WVo~ PWV@M睷)bm$G"%Χ)\^), ۟O]>43;ru8 /\zg|b]|Hg8|/RSMP #nlɤdF0-%0"ͥKוI/EM\$|^X<]`xN2o77)7Ɍ$I^Kq-%&S ~-N8_;x+W*_tͨ ;nFF{#$_D~u7.GR"c-(0Zl׭pT/~aK*[a'}70%}SvdԻRlF:+Non⼝'0G79q_ϣ*gyk53T&YSnvX7/oQ⼑ˈW?a ս/`TV<Šs838O{S_ GX4G[g2jW\)YL]+┈n8R',NESԘq$רK N$NҼ]^=I;/8].@2K_6\GyJ6&DC,w:IC/˱kGs#m Q=/8QRI8=SckŹ{g8zH^Qq-GĨj8=8FrTj='8*J \6_U_*ΡC;Gm۰88O-$m#.4 T :2T qq%֢vl(qN.G-hZf89-'9-9?~KvqFd4u5L4t&k"^xPqOvz8i>!(q6M}qD$Cm jb'.Mx,P/fUQi'oؖ7t߸*Q4m4ƛi Θ!o qv8g!hfc1ruU4~޷-r5 S:hyq6|GŌ88888888888i[ϻ:&7H,MJ3+4NF^]v#̱8BWT N=^)q:"ήɔX+e4J)!x%Ẅq$#ši8'ǃ)sWսTi1@c>_9@q"Th^fq8̛9AVs X82W wqFc28PXa8.qL8 %x8S) Gq'Q qǾq;U "U q88*Yhqp5q8qqq`Q985 AA8qA(GqVkPWk98 Wqqqq%┴'&Ĉr,I]G@qLBdtK9XIqfEYb gDҔLnos 9z#8 5|!Zrh8b_d)hg0т@_G(:tBPjL&MANU K㋳q|T5߱l9g0̩'Άu:,ANU\̩9ǾfwU"y⮪T@Y |L      TۈF ϔny;p)s#/{+X‚P VQ%GfyIPj986dKc#s]x .ŋڶCfk Yo=cFoGY'=hԾ~ 9 9Kr!3R`2?$R!#s{KG\[u3-8ggggQ9_r--lOٹЂAf[68Mp[`~;_qovSxtDF8Y,γg_a>˨$8L{Y|l3JvOnFW#qwW99+oU=~U=~U+qW8!Y8WZLn{?WոO yq/8qx73ۻqT~A-|_gkly5-8|Wh8        ,8Kތ߲z.]Zqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq`őjJq&'^4EoLɉ<~%}" N8=@_ڈ1c,g,m8jqaN=q6]\tӜIwUwU_l8"gqqqqqq-A@@@@@A@@@@AAA@@@@AAA@@@@A@@@@@A@@@@AAA@@@@AAA@@@@ę2,SE]58C'\4]#%_}Kx˓Qٿ f~ B.n z>S*3Y b0Ie_ڝ~Ӭ 防…E]zNrߑ!Ux- 2'T*PHyb8TZAʟR1Q 趎E [De =׫ @KtP}_U\z梚=9P6eY'2TcF3W9q@{S'YţeeVf]e8ӧU݌2l R [J3ГXšfAٙEN?_N@tgi 릳9 L{)*FU}}E<-ݡv,Q2=Sf8֊q㘯T7O>:(yF7 muBjUnCEy4(;Ƨę~X)ڗCzb{ͳ7&[f`?_+`5]>yCecZߙxs`*%9tvC6LJ+v+l@zjruGq7n7t3{>GOG;99:=AAAAEIJJKOQSXYY^cft燼튿읯oKhPR{#J|!K|K|FZ8;KΗ?셢+;F)e' ٽ{6\Zp=]>=p̟x'O|ۻ7 po)Cɹr'sp> sF8iO1։Ox/DLJ#;[[C%s&VhW!G9:yr>he<흹NKܾmى{k]vC <}RmB4`HQέ87ppv9d"k·wu8xg.$sy \:h'Z51-`Ktdn-[zv]=pnF}pksf+s}nz;s;{Acԋ7w;E^ j2jX?|}p5J`ӳe3&7]=pH{\jn[9z· pHe8R2!!!!!!n+U<[-[ֱg͌1ɒ).\89Y#"YER<, 2?/o{/E!9ȬtOiS^y ?9MJg>SKKK Ӟp)sO  qSpS.1iE7ŃO,|+]eY_L< K#g-qs yfÇڏ6^f,D˳N FRтJ7͏ ZYgُes& g?Q,D˳up6_yg}5N< Rp g)[*N:x*%-8+Azl3}VG7?>#O?਋'MYԉg bNy6>gpΜ8xGG?Oy52S8񩁄[!ݍ5tY'Yp2Mq$n$<lyYcS8w _Sfw=NO/xf885SzۯU_׶>Qq:K6GZ:NSK 96!Vl!!!!!Θ𘍖#mѵg׻7W'e52D8qupcqϘMU-[717IHbTϙxmI|C3Ϫ],B1xۆd9~Ko*bpJ6ec8.ɹ[r5EpwҶ)y{3c 8CmLJG{ȊkWeS+NYWq!eӸ5PI_R/oWU7ۑN3DNhNIUGI 2lFڜ7ǽV* Ƈ3q "Z!WѯyCښ(:iJ|8I MYcmMV,iL5+k CCCCCppHHjYh R-IkaID֬ G]Blk3`*<Qp%T4,lq?鹟@j>cϨuIC7YmsᯆN 819;*yVϪzUY pppppcjU+I&'9k2hr 'N|G&b83~ q ɹ2!p=[#%*77FCK4&cTI/ڛ6D~_d pƓkĄSidH򓼈5K8;Ky"COrߏ?SnpF.-C)8cӳ+])3t7p-x3pk[c3p9 7SP#<ʇc>2}-8 <Ƒq}SN~g2*g)Z FyqV7%^ 팛s,U9.<8^8:^GrI8Ǒ"|89Nyo gZJd8 N0?oc|q^1x&w s1pppppi8W@2L㕫!)  q>k *WN8P pVO+՚Q i=df+~tHpB KF/=e> 02*W[W(1*nJ\oXvƒh3cћU8TN5$oZpM 5ghpz]o-N*BK8)-⨐qQ*اc֮*9*uVU `u8gJqB9f8* 8}fc2p*W? ]5\sLB8'T&T 0r( **C`TL 0i>IT&=ƙl`܃IV&-L 0i1$v{`҆q&P47uS8k}S=kTN8T F)vC`B`BUpylKUG3Vmb4 h&6Xۿܸͨob4 pJQ DepU&e%ŨGj)t]Reb,v/F-NZ-&Wwź}Uҹ);Q^LS?iDTq_sT=N&9-/FcGgmrY ]܌6U%ŨX!0pqU{vcEDKO+8& Jy^MN%Gi3yƥdJj!wɫjo4(Md ,Z5nVzCb8AgnC&xEeñk Vj ;H.ir G{VOza'],AS)əhE993- Q*B%Frlޯ'}"Sg)=G?j]Hc)fR=&<ijUՂU-u-$q!D%iK"ኚl}ZHXB'l525LzQ]Li~g9;U9k鬓ćc|8 Ҁ5Vluϒ&XOkP888888!!S'Qy=)lUT5+w87}j ?L8ZK#}X?5#b<*H׮~ޠ5Jꘓ]Jʨ$c?/YGz+NN,y(%G;?a3f8֓yG#ǣX,z*c=38hPXOs?oh!qڧkƮ*iM\u8-NoC_8Ra3ʵ#eS-rp#KתI;=1O,y qhW1N}9CcUe*Wޮ|ޠuV~:=*Ϊ& g`_Te2 p*|́C VZO4͝){T^Xiˢ 5gytȠX}/֍LќΫ݇z޽{o?P6duS?$}q&KZFB+,ucyt7wϪ2sO`$*c}4ٵա=5f-qըբq½( ]m,+Q{=wk IDH =sgvՊ-~p~gs~8/y~p#J*pF=3pB|zW;+dW~2Q1Nʨ|[q19O> Ϫ>D9\;gU$I_bqnҳϪ*0 ǨEX#Y'.nY5D7͝i8,?Wd ; pϝEY(8fC᧥΢Fg8#Nߧtv$]Oz3p1 OI Y@ȁ1pYN^G[5%#8dYVX}3p"p$19YQ#k ^æ-ו}YVg +i;(gmNtCCg9pqPˁTCpppppipȰDO˖^SD; H)m"Uib88i[k*E)Uq{nUpxȶG8ƙ9À$rYpxppppf.p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p8p3ppSMT8(/_8ヿM[~{_y⫨G:;.lq ׏sxdJmqy:yO S/׏?(Z%^S/߽5po^Gͽ0_-148Gl8l[PSau|zͅX\8.lUIC{WB4x>K<ѧE=l%+NmP҅Tg'} 3'/ܿK?04Λ/Г㸌8ya {Xi)2Ecip~sՆζ P=2"o#[=sA>\8GK~:\9X$W%qjq*hp.|dIgzd{*uEPu;=.cDKdD>*"{ ;N4g"=t_hESr v)zu|  j:xG?>Vn{W'ݴv?8Y3]p tdWswU߅1ηU9¹( =Dݴu? '&qJߵΛK+328wvo:WT=FqJ|-Nc'pG?m ǎeyj\BV,Sw?;7Uˆ7=&&x\jPgU.{c5pw]Rq繭A~t{ϼl^cigU: ΪBDH8p^w_o4xX=l-M{AG"uJ=Ε"8o EH)9nr?qLN D pVgQRj=")gRur2(т d?}:p:Z$}ԦEOVsLeӈƕ2MQz=t4˓X^0#TjMC&#֤6J[US4dɤ 7VPЮ2e ұ>sE8X>pJ^"kX&-iA#JZ$rDPLTEf]\cajhwuÿŽtrldca[[[[[ZYSSSSRQKKKIIDBAA@;99:<@HQNI?6~8{9r7m:oEuyWYWSVSSUSQTQQTQORONSTHXf<]3^1^.]*\*Z(S'N|'Mz%Lz!Lz L{ L{ Kz Iu#?e!=a=a;]"3K-3@')3 "+   !` tRNSǤ7~IDATxKis{^I( =lw z{=,nYA"HAEc]J-BYRXcwߟwfޙi367f}y3LtLj 4`85*+˴R?k׍ҷ&ǰY 7AiTt&&ðukeUV;_ՙ4N 3 `*[{u @!zp?>@Wqb@DƖj}t~hk+B8{v>sja蔮tOZ u$޿GM 4I$) OiYhy˝zݣRu~i֖_D-a{Ui$ðN"J;>f[GYV4٩MA!WE^X&dbwS5Eݯة3JҴ˕OuaYcM̉ qOB.GNl.ENmd?MYc )y ,)(4Ƣb>Mgg˫ (1't:]ňesiK~~# _+ uLWe^sjswN3{l-,!6eI$# VV2 Ҙ٢Ub]+Y%b+ 5Lgg}ʴ˧ĜEI:7a^/@dj wj ) u2Jl1hxUv\, C# o.we3QrB6J>O.1 chtGrP矔6:_bhessY$uj(9˖\#e[{\1D@[̇.љ4NCUVBVIeAdVxA ߠ}-feh!=Vx, uc*(ɰΤq*kNw'N'_*{{5QUػ" vp 5vEf@d{mM%P|b9+eI㴲bXY9}_yp>h[X^RU.L'7>o-UEI, +a4``c4` 0` @I0 rM\w)FCtG?$9 (bA4{$0DN DW 8`0zOݓS)dg!7`]g) O2Rv؅a{0')dg1( p=p(N!5`7p XnnU   ߽aAiOJ&(I |VBK;nC-zQf cccަ& }   .M~j-^ccwG.uuQ `݈Oz Creating Additional Plugins &kst; has a simple and standardized interface that facilitates easy creation of additional plugins. In addition to detailing basic requirements for plugins, the following sections describe how to make use of pre-written header files to create certain types of plugins. Creating a Basic Plugin A &kst; plugin consists of two files—an XML file and a shared object file. The XML File The XML file provide information about the plugin and describes its inputs and outputs. The following is an example of an XML file for a &kst; plugin: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Module SYSTEM "file:/Repository/Level2/Soft/ProC/moduledef.dtd"> <module> <intro> <modulename name="testplugin"/> <!-- The name of the module --> <author name="Rick Chern"/> <!-- The name of the author --> <description text="A test plugin for me"/> <!-- A description of the module --> <version minor="1" major="0"/> <!-- The version number of the module --> <state devstate="release"/> <!-- The development state of the module (optional)--> </intro> <interface> <!--inputs here--> <input> <table type="float" name="Input Vector 1" descr="The first input vector" /> </input> <input> <float name="Input Scalar 1" descr="The first input scalar" /> </input> <!--outputs here--> <output> <table type="float" name="Output Vector 1" descr="The first output vector" /> </output> <output> <float name="Output Scalar 1" descr="The first output scalar" /> </output> </interface> </module> Generally, you can use the example above as a template and modify sections to fit your needs. As can be seen from the example, the XML file consists of one module node. The module node has an intro node and an interface node. You should modify the intro node appropriately using the comments in the above XML file as guides. It is important that modulename has the name attribute set to the same name that your shared object file will use. The interface node describes the actual inputs and outputs of the plugin. Each input is described by an input node, and each output is described by an output node. Each input or output should have either a table or a float node as a child. The type attribute of a table must be set to "float". Note that the order of the inputs and outputs matters—the order is used to determine the index values for each input and output array of the object file, and is the same order used to display the input and output fields in the &kst; plugin interface. Once you have completed the XML file, save it as [modulename].xml, where [modulename] is the value of the name attribute of the modulename node. The Shared Object File The shared object file contains the actual functionality of the plugin. In other words, it determines how to derive the outputs from the given inputs. The following are the requirements for the shared object file: The object must export the following C linkage symbol: int symbol(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]) where symbol must be the value of the name attribute of the modulename node in the XML file. This is the only function that will be called by &kst; (although you may have other functions). The following describes each argument of this function: const double *const inArrays[] The array of input arrays. Each input array corresponds to an input vector. The arrays are in the same order as the vectors are listed in the XML file, so inArrays[0] is the array representing the first input vector, inArrays[1] is the array representing the second input vector, and so on. const int inArraysLens[] The array containing array lengths for each input array. The lengths are stored in the same order as the arrays in inArrays[] (e.g. inArrayLens[0] is the length of inArrays[0]). const double inScalars[] The array of input scalars. The scalars are stored in the same order as they are listed in the XML file. double *outArrays[] The array of output arrays. Each output array corresponds to an output vector, and the arrays should be in the same order as the output vectors are listed in the XML file. int outArrayLens[] The array that should contain lengths of the output arrays. The lengths should be stored in the same order as the arrays in outArrays[]. double outScalars[] The array of output scalars. The scalars should be in the same order they are listed in the XML file. The function must return 0 if it executed succesfully, and -1 otherwise. The code for the object file must handle unexpected inputs, such as empty input arrays (in most cases a return value of -1 would be sufficient when such situations are encountered). The number and type of outputs must be exactly as specified by the XML file. You will probably need to resize the arrays in outArrays[]. To do so, use the realloc() function. E.g., outArrays[0]=(double*)realloc(outArrays[0], 5*sizeof(double)); will allocate space for 5 doubles for outArrays[0]. Do not use any memory allocator other than realloc(). The input arguments must remain constant. Do not cast them to non-constant types. The following is an example of the shared object file source code for a simple plugin: #include <stdlib.h> extern "C" int testplugin(const double *const inArrays[], const int inArrayLens[], const double is[], double *outArrays[], int outArrayLens[], double outScalars[]); int testplugin(const double *const inArrays[], const int inArrayLens[], const double is[], double *outArrays[], int outArrayLens[], double outScalars[]) //Accept 1 vector and 1 scalar. Multiply all elements of the vector by the //scalar, and output the resulting vector. Also output the original scalar. { //Set the outputs outArrayLens[0]=inArrayLens[0]; //resize the output arrays outArrays[0]=(double*)realloc(outArrays[0], inArrayLens[0]*sizeof(double)); //multiply each element of the input vector //by the scalar for (int i=0; i<inArrayLens[0]; i++) { outArrays[0][i]=inArrays[0][i] * is[0]; } //now set the output scalar outScalars[0]=is[0]; return 0; } Compiling the Plugin If you are using &gcc; to compile your plugin, simply compile the object file: cc -Wall -c -o myplugin.o myplugin.c -fPIC -DPIC and then create the shared library: ld -o myplugin.so -shared myplugin.o The resulting *.so file and *.xml file must be put in the same directory. When you use &kst;'s Plugin Manager to load the XML file, it will automatically look for the shared object file in the same directory. Creating Linear Fit Plugins To create a linear fit plugin, you could implement your own fitting algorithms and output the appropriate vectors. However, &kst; already comes with header files that make it easy for you to implement linear least-squares fit plugins by just providing a few functions. This section will describe how to take advantage of these files. Header Files Two header files are provided for performing linear fits, linear.h (for unweighted linear fits) and linear_weighted.h (for weighted linear fits). They are both located under kst/plugins/fits/ in the &kst; source tarball. To use these files, include only one of them in the source code for your plugin: #include <../linear.h> or #include <../linear_weighted.h> (by convention, we will place the source code for the plugin one directory below where the header files are). Implementing Required Functions Given a general linear model: where y is a vector of n observations, X is an n by p matrix of predictor variables, and c is the vector of p best-fit parameters that are to be estimated, the header files provide functions for estimating c for a given y and X. To provide X, the following function needs to be implemented in the source code for the plugin: double calculate_matrix_entry( double dX, int iPos ) This function should return the value of the entry in column iPos of the matrix of predictor variables, using x value dX. This function will be called by linear.h or linear_weighted.h. The implementation of this function depends on the model you wish to use for the fit, and is unique to each linear fit plugin. For example, to fit to a polynomial model, calculate_matrix_entry could be implemented as follows: double calculate_matrix_entry( double dX, int iPos ) { double dY; dY = pow( dX, (double)iPos ); return dY; } Calling the Fitting Functions Once the appropriate header file has been included and calculate_matrix_entry has been implemented, call the appropriate fitting function included from the header file: kstfit_linear_unweighted( inArrays, inArrayLens, outArrays, outArrayLens, outScalars, iNumParams ); or kstfit_linear_weighted( inArrays, inArrayLens, outArrays, outArrayLens, outScalars, iNumParams ); Each function will return 0 on success, or -1 on error, so it is a good idea to set the return value of the exported C function to be equal to the return value of the fitting function. To maintain simplicity, the code for the plugin can simply pass the arguments given to the exported C function to the fitting function. Note, however, that inArrays must be structured as follows: inArrays[0] must contain the array of x coordinates of the data points inArrays[1] must contain the array of y coordinates of the data points inArrays[2] only exists if kstfit_linear_weighted is being called, and must contain the array of weights to use for the fit. The easiest way to ensure that inArrays is structured correctly is to specify the correct order of input vectors in the XML file for the plugin. iNumParams is the number of parameters in the fitting model used, which should be equal to the number of columns in the matrix X of predictor variables. iNumParams must be set correctly before the fitting function is called. After kstfit_linear_unweighted or kstfit_linear_weighted is called, outArrays and outScalars will be set as follows: outArrays[0] will contain the array of fitted y values. outArrays[1] will contain the array of residuals. outArrays[2] will contain the array of best-fit parameters that were estimated. outArrays[3] will contain the covariance matrix, returned row after row in an array. outScalars[0] will contain chi^2/nu, where chi^2 is the weighted sum of squares of the residuals, and nu is the degrees of freedom. outArrayLens will be correctly set to indicate the length of each output array. Ensure that the specified outputs in the XML file match those that the exported C function returns (which in most cases will simply be the outputs returned by the fitting function). Example The following is an example of the source code for a linear fit plugin. /* * Polynomial fitting plugin for KST. * Copyright 2004, The University of British Columbia * Released under the terms of the GPL. */ #include "../linear.h" double calculate_matrix_entry( double dX, int iPos ) { double dY; dY = pow( dX, (double)iPos ); return dY; } extern "C" int kstfit_polynomial_unweighted( const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]); int kstfit_polynomial_unweighted( const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]) { int iRetVal = -1; int iNumParams; iNumParams = 1 + (int)floor( inScalars[0] ); if( iNumParams > 0 ) { iRetVal = kstfit_linear_unweighted( inArrays, inArrayLens, outArrays, outArrayLens, outScalars, iNumParams ); } return iRetVal; } Creating Non-linear Fit Plugins &kst; provides header files designed to simplify the creation of non-linear least-squares fit plugins. The following sections detail the use of the header files. Header Files and Definitions The non-linear fit header files are located in kst/plugins/fits_nonlinear of the &kst; source tarball. The files are named non_linear.h and non_linear_weighted.h for unweighted and weighted fits, respectively. To use these files, include only one of them in the source code for your plugin: #include <../non_linear.h> or #include <../non_linear_weighted.h> (by convention, we will place the source code for the plugin one directory below where the header files are). As non-linear fitting is an iterative process, you must also define the maximum number of iterations that should be performed. The non-linear fitting algorithm will stop when at least one of the following conditions is true: The maximum number of iterations has been reached. A precision of 10-4 has been reached. In addition, you need to define the number of parameters in the model, as it is not passed to the fitting function explicitly. To define these two values, include the following at the top of your source code: #define NUM_PARAMS [num1] #define MAX_NUM_ITERATIONS [num2] replacing [num1] with the number of parameters in the model, and [num2] with the maximum number of iterations to perform. Implementing Required Functions To use the header files for non-linear fits, you must provide the function to use as the model, the partial derivatives of the function with respect to each parameter, and initial estimates of the best-fit parameters. To do this, three functions must be implemented. These functions are described below. double function_calculate( double dX, double* pdParameters ) This function calculates the y value of the fitting model for a given x value dX, using the supplied array of parameters pdParameters. The order of parameters in pdParameters is arbitrary, but should be consistent with the other two implemented functions. For example, for an exponential model, function_calculate could be implemented as follows: double function_calculate( double dX, double* pdParameters ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dOffset = pdParameters[2]; double dY; dY = ( dScale * exp( -dLambda * dX ) ) + dOffset; return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) This function calculates the partial derivatives of the model function for a give value of x dX. The partial derivatives should be returned in pdDerivatives. The order of the partial derivatives in the array pdDerivatives should correspond to the order of the parameters in pdParameters (i.e. if pdParameters[0] contains the parameter lambda for an exponential model, pdDerivatives[0] should contain the derivative of the model with respect to lambda). void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) This function provides an initial estimate of the best-fit parameters to the fitting function. The array of x values and y values of the data points are provided in pdX and pdY respectively, and the number of data points is provided by iLength. You can use any or none of these parameters at your discretion to calculate the initial estimate. The function should put the calculated initial estimates in pdParameterEstimates, with the order of the estimates corresponding to the order of the parameters in pdParameters of function_calculate and function_derivative. Keep in mind that the initial estimate is important in determining whether or not the fitting function converges to a solution. Calling the Fitting Functions Once all the required functions have been implemented, the fitting function from the included header file can be called: kstfit_nonlinear( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); or kstfit_nonlinear_weighted( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); depending on whether you are implementing a non-weighted fit or a weighted fit. The function will return 0 on success, or -1 on error, so it is simplest to set the return value of the exported C function to be equal to the return value of the fitting function. To maintain simplicity, the code for the plugin can simply pass the arguments given to the exported C function to the fitting function. Note, however, that inArrays must be structured as follows: inArrays[0] must contain the array of x coordinates of the data points inArrays[1] must contain the array of y coordinates of the data points inArrays[2] only exists if kstfit_linear_weighted is being called, and must contain the array of weights to use for the fit. The easiest way to ensure that inArrays is structured correctly is to specify the correct order of input vectors in the XML file for the plugin. After kstfit_linear_unweighted or kstfit_linear_weighted is called, outArrays and outScalars will be set as follows: outArrays[0] will contain the array of fitted y values. outArrays[1] will contain the array of residuals. outArrays[2] will contain the array of best-fit parameters that were estimated. outArrays[3] will contain the covariance matrix, returned row after row in an array. outScalars[0] will contain chi^2/nu, where chi^2 is the weighted sum of squares of the residuals, and nu is the degrees of freedom. outArrayLens will be correctly set to indicate the length of each output array. Ensure that the specified outputs in the XML file match those that the exported C function returns (which in most cases will simply be the outputs returned by the fitting function). Example The following is an example of a non-linear fit plugin that performs a fit to an exponential model. /* * Exponential fit plugin for KST. * Copyright 2004, The University of British Columbia * Released under the terms of the GPL. */ #define NUM_PARAMS 3 #define MAX_NUM_ITERATIONS 500 #include "../non_linear.h" void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) { KST_UNUSED( pdX ) KST_UNUSED( pdY ) KST_UNUSED( iLength ) pdParameterEstimates[0] = 1.0; pdParameterEstimates[1] = 0.0; pdParameterEstimates[2] = 0.0; } double function_calculate( double dX, double* pdParameters ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dOffset = pdParameters[2]; double dY; dY = ( dScale * exp( -dLambda * dX ) ) + dOffset; return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dExp; double ddScale; double ddLambda; double ddOffset; dExp = exp( -dLambda * dX ); ddScale = dExp; ddLambda = -dX * dScale * dExp; ddOffset = 1.0; pdDerivatives[0] = ddScale; pdDerivatives[1] = ddLambda; pdDerivatives[2] = ddOffset; } extern "C" int kstfit_exponential(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]); int kstfit_exponential(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]) { return kstfit_nonlinear( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); } Creating Pass Filter Plugins &kst; provides header files to simplify the implementation of pass filter plugins. The use of these header files is described below. Header Files The pass filter header file is located in kst/plugins/pass_filters of the &kst; source tarball. The file is named filters.h To use this file, include it in the source code for your plugin: #include <../filters.h> (by convention, we will place the source code for the plugin one directory below where the header files are). Required Functions The filters.h header file contains a single function that calculates the Fourier transform of a supplied function, applies the supplied filter to the Fourier transform, and then calculates the inverse Fourier transform of the filtered Fourier transform. To supply the filter, the following function needs to be implemented in the source code for your plugin: double filter_calculate( double dFreqValue, const double inScalars[] ) This function should calculate the filtered amplitude for the frequency dFreqValue. inScalars[] will contain the unaltered input scalars for the plugin, specified in the XML file. Most likely inScalars[] will contain cutoff frequencies or other properties of the filter. For example, to implement a Butterworth high-pass filter, filter_calculate could be implemented as follows: double filter_calculate( double dFreqValue, const double inScalars[] ) { double dValue; if( dFreqValue > 0.0 ) { dValue = 1.0 / ( 1.0 + pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) ); } else { dValue = 0.0; } return dValue; } Calling the Filter Function Once the required filter_calculate has been implemented, the filter function from the header file can be called: kst_pass_filter( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); The arguments supplied to the exported C function can usually be passed to kst_pass_filter without modification. However, there are a few restrictions on the arguments: inArrays[0] must contain the array of data to filter. inScalars should contain the filter-specific parameters to be used by the filter_calculate function. After the function call, outArrays[0] will contain the filtered array of data, and outArrayLens will be set appropriately. The kst_pass_filter function does not use outScalars. Example The following is an example of a pass filter plugin that implements the Butterworth high-pass filter. /* * Butterworth low pass filter plugin for KST. * Copyright 2004, The University of British Columbia * Released under the terms of the GPL. */ #include <stdlib.h> #include <math.h> #include "../filters.h" extern "C" int butterworth_highpass(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]); int butterworth_highpass(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]) { int iReturn; iReturn = kst_pass_filter( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); return iReturn; } double filter_calculate( double dFreqValue, const double inScalars[] ) { double dValue; if( dFreqValue > 0.0 ) { dValue = 1.0 / ( 1.0 + pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) ); } else { dValue = 0.0; } return dValue; } kst-2.0.3/docbook/kst/Screenshot-kst-plotdialogmarkers.png000644 001750 001750 00000020255 11544160206 024260 0ustar00synthsynth000000 000000 PNG  IHDR8\FMPLTEþ6U8U:V%?X1F[>L[GOYKPVHKPCEI??B779324212"- BV "b)*h./V23@461-3 '1%1'0+-10/11011025T8[;`73}7zDj\Ac/_/}\8rXGcVRYUVVWXXY[^Y_gaelkkq~ux~~rXPPPHA@::99:@AAAAABIJJJJNQRSXYY[^bfrϝ tRNS߻rZUIDATxϋf,])X1XK3gݎ7]Xg;']fq 1l M`hܸ⃜`[JRu]U*$HUGz ~kmKHq}R3?R3bW,e35^"8_pݾKv?Ӷ?zYΗQ>m]s޾%C>3\> 6O~X%i/aS[/@ ի'wnpKz&/A˛\\ ~U?/;^K'kfswd.G~^~w]>z}p9 \ i0f灟kkk?;w*҃NuYwuLpnGn&Ry=|H/DUz:z<yG3j+Ǐ]WLsی׽ue\\>k돢ǿ~ zv9m*u͵ozj]ם_ll^ _.&xn(pF.+p}B4 #w݅yNVjpyG}m+s=1l F5ﶺZD?2A7i6B. ݆宭e(ۣNƕ+7Mؼy?< ^q@r&l,=|‰JҚ_֥Knw 7nO6ZqI,꾑r?x.ot{{^F7o=Qi ]:{m,pH9oyhe8dpR3!s?88888YpN'2,a\g1w2){/B8Vșϓٺ}ܺuK${\p&3pwOњ(p&i΋VfԞ8^Z[Y 5g1rޅS8[[fkK"Ac2cy9Ih%pNpNnY~|#G?Hk\,3N%4 |o\}jp2TxfymǬ^,i[f4G,:_ s=8Y(g N?{Vk`\L*wBZTGf|dY d~rpMppn#$$?u/RnUubE_NFw|bSUNz6&Tg*5zIuu9Lbk(R}x,el9yE9NgS8KȕNtXGbTcb'nq]UofxVal:=NG<'%|#>ÉQOU݁S/sBCCCC8[i8{;C9o9 J:Yu8LKjjyj55PP̷jqqqqq5ơơcj~"8P5?6U}or3ǁ\W'> 8kS8ppp8|s 888pҏ/8} N9R_ǁs~;pæ 8E8pCC8 g3rp:#p3׏pq7pCCC8!|HÁ\i@p; pS ([.pqS'\]N#=p8pppp8_ pj\ZJy@.~ܿ|pu89q98o8pCCC8!!p8pppp8888p8p8pCCC8!!p8pppp8888p8ɲ8ɲN<9Y pr^pp}ԅ5 '*ihnK88pѲ1]C+2U8p"pβ2N ˊ&8~90 pUe+XLi{c@!ppppښC SƘwUpfy}99pÙgipnyی8٠iۚdKWU)B:yyGg?#jkW7>oJp$("6ey=$GԶ,QryvW6PܰE<+) >jz`nlԏLEG!wFCJ'hKq|94'w gq^QbT`f! ,^Y8@frfYt_.?ؾ4 f}H:㨝Jws|ypB9O,p/Ōg4I*?V8f66*WuYG2햳|:;9k3α(Tyf2 +o|&5N~:Yi;cm63rl[}Tfv35E[rjkW/SY 'S)Hi$50ٟR]j +hf!h᧪C?r(>-y%~vjkW/{3_R,hx{i8JutˍL UrtAo11uƘw'p1i*!!!!r3t^q qh7YNAgk+%2 9 g~Rx,SƙS#݃.ܒ2>UUkTeT]A~y5 9pW\E;3v.ooU! pppppCCCCC>8{鳛rHo :8ƙr/TnAGVNIfBqN_*N%p*EP_t8T;݂?DzbV6Cc9gY71SO"ެmw 8m:LXOcf:\9Ʀ*ϯ-u<;脍j,lqV( cwR *vg4 TdXqs|h|" 8u%{888888!!!!!g )]y+ǿԒ꥖j\>>?rg ~C-DZTPgi7cX0pm #t|}c;=ۺ2\ܾĥ&y᜞pNOgaf+_+^0Y;>iszhJlҥl4])T/nocX;Sٙl;-Β$#z&7Qg/*kWc(Ms,s `/4V}q)7/:;<ᷪ_ ppppCCCCC8{鳛Ϭ\ˁp-.H ppppp!5 E5_Qɢ_) g[o~̅NpFZz7 .Id ZN|/x2Ғ+cԁ.NcS{M?pjg)\fPs*I/{X5邶N0P6SSy+ p E'"5S@<_,ق~~Yzq8|W8 ŒYzqci@+!!!!!!88";Bjo:!8 NfSIENDB`kst-2.0.3/docbook/kst/Icon-kst-layoutmode.png000644 001750 001750 00000000436 11544160206 021471 0ustar00synthsynth000000 000000 PNG  IHDR/8 pHYsnd tIME +IDAT8˭[ C$ҲyXt1!@'% $I)%= NQ32P=T ?pdTf)߲eVXi~ l35O\IݠARSbՂW 8k(×L+4CM (shOEj8GPm?v0=|<c\ ^IENDB`kst-2.0.3/docbook/kst/Icon-kst-tiedzoom.png000644 001750 001750 00000000430 11544160206 021133 0ustar00synthsynth000000 000000 PNG  IHDRĴl; pHYsnd tIME"'ݟ\IDAT8˵ !DLˡ4ڠ #Ő8@oKef' 9c; 3ևṣ9gL@hlZgLp_*J<):KϦV̦dokx䈼cVE^U"B1yYۊ#')D֔IENDB`kst-2.0.3/docbook/kst/Formula-kst-gradientequation.png000644 001750 001750 00000000574 11544160206 023372 0ustar00synthsynth000000 000000 PNG  IHDR? 8CIDAT8ԯ@{.(4r=X$v%]_N i~Oܯ\y󺎚LٝI.O?Rֳԁwp ɴ81_Y" L~{sZPTN>9jn?*6YQkZ/̓YCJKx`?QkŪv^tvnkGW8)`xkj`T0\Qxz~O0?[ipA=\ ;omL'2foh}f(YF=>;KfCIENDB`kst-2.0.3/docbook/kst/Symbol-kst-sigma.png000644 001750 001750 00000000317 11544160206 020762 0ustar00synthsynth000000 000000 PNG  IHDR j pHYs  ~tIME9PεbKGD̿`IDATcs͞>\L ;D=@Z>@F Ԩ w 5ovoE'ymӤ)IENDB`kst-2.0.3/docbook/kst/scripttutorial/callsubs.js000644 001750 001750 00000000336 11544160206 022351 0ustar00synthsynth000000 000000 // callsubs.js // demonstrate calling subroutines loadScript('subroutines.js'); file = new DataSource("demodata.dat"); var p = plotField("1", 0, -1, file); addField(p, "2", 0, -1, file); addField(p, "3", 0, -1, file); kst-2.0.3/docbook/kst/scripttutorial/Screenshot-kst-scripttutorial-simple.png000644 001750 001750 00000104645 11544160206 030212 0ustar00synthsynth000000 000000 PNG  IHDR`B^9 IDATxw|EW{(wHEV,Ww,`W,DDAz %z~;?.w%w] s<3>73'Mr^z)^!i1` 1Ztttttttttw8ëOK*6I3F_+QQbh6y$bҏH90l6:::::::_<+k6۶b[\~JͦTGGGGGGbп_fٿ__m߉)&G_aOu&ޘ%ܖ5A:OxetOΗI7@B cXدul:::::::G Hgj;DltXf ,iEQFă?Zf_Hwrp^^F3&P"Wtwnþ@|B21'BVxX[LN᳴n]۶P~AP[Fߞmn~n^z =<\KtMB"5MGGGG/\\:zbeaWCY߱|$at{0Ci<eso&ꚫk8vŌh?ϊKiі#5lGlHhÑ" H|9S𤥐[RwY5㬇zgw%6'rLr2)䖖 d`mR-4h ?ӿٻ#iK^syV쪈Ckxx\UT:&peH!{=X1M09,#juPg!SRHyE|^/“Y[CC@~~a>v8u@qV/w,<0i$]Ϻh#+G 4I󖂐~aÿ]Cyږh,rV.dvn7!.#0nyYgTcHH*x5\xYwcn&ЎUqS\TK͹oߢE FLĵGm7=9h0|AhccL\%*XɟyoUsзo_~GF#,( M|CBB$U<'ey$1|2+'|&K=DzU]K~Y S}FrT[p ynr+p5fY%;pCl>X?/_1p#eVA-GlӨbBTU4~,Ӊ!:f[r c3 Y+$y]?ɿ/ׂK@6i9ަU:iY\L6(Ql.$=m h}c2(Q$xD:p _Y{4es/̩V6$_BQ rK+A}vg}8;OgжU,KZvv+mvutttt$HIjX7(iX~c7Ʈ]޺q/zl}4I;w4;$eΞ,]f!^B}GR\e&Jm8U<%W],(,BB Zji4xe*ơ@h%6< 0%UL^՟>DiUQ{8!};k~ݏl}BRo "<͔98s׳1w=00:8F]/ oq):] {놑o>Kr$`0Ȝ>IϞ9EN^9ӎ$%6j* Kh»Sz N$zT0F$,%IF2ۘMvQ߸j$BhBC6% [1Fǐh©T%XUe ZuNXvwݻ)CqXdݖ|G0ΧpysuUT-o!k?BDž [r UGGGG0fVood5gmC{놑\z6wQL56g]ԋ;0 fHj 5KK!}c:4.@ԓQs1UazWE-+b6pTa.MCܚ' k߁䠪juEGp<9\g zM&qKH(L5l߻.#f֌~&$ޜsR/}淐rý 1[.Ț-;^ohh 7x(-?Bbq0X>N9RFEs G>z K2Rn'$dFR@{Tq;D2!N% ;r;?\p3#Z%/{ yv% R0.uII"NuM xbZq|/_ǰ3cz^ښ%7ctHOڨ>?/8׻ ,$J',v0c&.A0-?Bw:6dc(F}}׶|H>;o^?A1 ӫW/>t#{wFŅjh4CEUӖ"CvŘ^xE~r_!. G|sGh.oVO0t{+"r=+Xۗh6aYƺѷROH|^*=*|_JQe%?bJ=tRVj,,ٯL? ˺7CչA*f"x$acgqw5G.7<νط 2s d³Gw0Gmk=:::::GzK[G6Ơ&H ӞmJ@[#Grb7pxwEKs  T|g'C Fw`Db0%vO]RAMAoM[Ǣ|Tlg/ȑ5P[*'N;!,uRPY־@/Uf!_|b29DRRvoKSlvNI| ߒRgcLjGR~rʹ]m; F*Do{nԭ2w?l Jp+QU3zo Ɵ; `wCr%C~KAin%9{\ݶc'1iZ\~M{E) lwNY+n lGxěeL2 .E`wYUvͻ5Cu)49doi[dĘ6y[trCIAeu҆l;.I2mhP<*.ЪPQaǡ dLώ ƚ5hBEԔZrs.±ֱ]!F:e$95 ըjN{ 1Y0I( ,6'nbB.[BA=Y::::: Hb:H9 P=hi ly0UUͮIQ;)(I 9N.Q)8ۤ$W`FG!pUQΏLre6VMABӼeTUby_h&eQkȍ,ăA0ۑMJ<e6*X\nx 3k<@tcqzlcttttӒAM5An#v$TB['SuUIbo%hBB܉dehɯN.#hFQșzxr!~%[O}d8o 'ta$'dsF< "--hk܈gcOe]ͺ,mNH#寰]k0 dƥ嶴K:::::::L1 [r?ӜR>T"m30I9sUUlp;+q[1 Ჳ7BR,_8|\%d=*v-RDLӸ;gIB[(Z¿BQ:"7VN$ [x"1ɸ*dM<!8q,3m4v'CG,n =_~ 'sg6hñ ,Roz(zͷĚ_oo̧,yQ5tw1*LޑruH7K |~}>Tzr9x! 9edOu e[߹l{ O;+4Аm.[?zl;o}J@qpı8^G%5<ԗ^s;B}@o˧qݹ*Y#_4K=m(ed4P>[3=>W: ,?2w7%~i" W>,T>!w-]bu쨝w8}?%RSiHDbawd ۧ1a]_=΂t̵[( umTf aOy{dr o.YJ4/@⾹wP"^)#ḳx⡛H7MvzM(w߾:eVG/̿f!]i؆SfQN0m f]:DVjs \ޓ^5e(\:?%NkE)ч8}\6Frc;4֣el,U+>;y<77W[,!۞㶩sd[MGmC<+4מZ -W_I1S<7N֗ĺIt. Is϶$q0Ɖc&qi݄1lXB !pYzk1~8f;OOouilЇ[ooxL9x~>ݵ{/}z>f }!5MꌇӞqS2Y)Æx3~:;mlıy絛6mTVp|_{=I~z; K 9ޓ.х"!̭&: 0ʫB^ih+bЩ?>3Et'1m^V>yzSy<V>x IkP!SySS?ז2jJ9fj5:vO~6qFgw,/eeLy5Nɺo㨪irM-Plw_; fmt64!# =p|ןXIc;1~$zhb>gVCoYk1\6y^O:ӓ@gz;wNf%kٹz\tқiv}g*Ԑvzz3봓-OT<̹t1f2l(Ǝ9T_ꩉ!9!τZßT:-"n.0c< ڌky):4,^ɭ䚌8ybBê586?˖}qsoi}K[p=[/fԥyʬ&?25GkI}~o~0sN|и*N֌C6><6N> .uBU̴8Նu7}w"7@M?zJkK1Ֆ T߀XuߕL23fp}g]ƚ)הY?,Np<,Dl̫FyiMnB< usNȌ1/f1cwcwsN}>Jf^;nnK[(A@B%Ir!F&kV# EkxvhL%617NN_g >T_7gq(ZS3̫Fa|]ˇ[&_߇u+xk8LMaŇPy,X9KfD1VU8ېHtJ楷B"=(8x`{)Bv|אe˖lٲ:גpe5>_\U!#9Q4~ul,KݟB]n04/Tm Ks۶3OdԶ;Xݚr9_݅>1L8o}nyO g }momKfޅD3ۗk쌸ig~ ݪ۶ 0QI5hY VQAf$uk9 Mah)DLdeLq;0]}[7@vjxZrF}מkOgߠk?NQӇ}BxMnvB9h^#;h7ygfeC:Ͼ_ճz=Ά/ă~ qT.8egֱm/4Z.ĵWW_zb4=M_CnugS G\LK34{)ehծr8<+#2AT;EKu򂥔xTuKzԴ7Y(zԬ1{Ll$eGC9SwsUȨc>l||``!E湫?݉,(sw^]anlէ!W]-U}71x<~;Sλlnyv*tc vki1I nMnv0%fzz,k|9:dGceV>UKQԳzճ8Nh=eg|6JLsO̾y9'ZVZP`VlLt 7%u톎v>3&KzΨ*ʀQUA|l8J3IJɟ|&G6u䯿nݺiBRUUU);wrMyP߀sss(8Ol/ `rjEdb=ʫ_u]!}מcېF_ 5v5- IDATt8e ]孻nݺqtڕʉjՇuM?oԧ>$PO |kϟI\1>`C TWaUUQgnv;StrN7&3ԟïg8=gQ]<^D4Z$*t\6`BLm_ ?ĥzeXVM# F߿?hf /ՙ[JsPx:Qi R@D;#Ǻ)\v[4~o<@Ze,u3?[lgDgn4Ka^<zynH,_ǯkP_1sMcyś'9~9ثG֌mw6ngxbHΠ>6MLP}}n6s"6u4{5;w]|Ui׹ _n8g E]>Bxshx9-Vu#/<_n@}z<2zƻ3jgL^:fW,{|xXemwG; y/ϯh NG ?SφSw笇[6./.͝{Gm:XCQ/oÐӿOc__T@|zMx~?ᄏs`YYY::rNZlFi29!( jƥec!3t ܰ_q= Pez Kў={oe;XpmcnG~!3 d{gAڠw^0>J=|spQ 97ך+֒D6 !D a +7lM6ñesΝ6bb{L/iV;X0)w"kZB$&B4M$m"~࿳/' [oAcu_͌fmuuʇA*,_S'M?0L~HGGGGGGGG3`::::::::G=9QN6k֬7 .]Wء$V%HEs&y~Ғ͓ϰaM#%ߴi+'ljv6JJgHSS9ɯ s**;\ ۮl *%FHM0'c2-nCԑp'\H⺎&.mFT ZqeeeA󦤤`6҄u|.XZ0nwH]pY|RRRMޯFkh&>}:IW5&B@iiyj~ECQ4l6,Xb%gqrw)/1{^ʄ Ú]'$IM4U Up=GQ). )vj}yn,*VI2ښKUe0U19WSVyCFoۆ+ SdK*?q&n_GiyWR'\!PC|GDEE322d2?lr f3߿ql6rҢq:iixP֬YÈ# }rYի>ɸZiue>zC|O>$7pCD6*d+9d~3`iiil߾~h0*, W\ؑhCÅPTTI^~b4TZUdр݊wDQxT<C9ŴoE7J TMBxF1??~QRRl !q W_̤I魍j^ⰳ; \9߽4Őғs"N姞B;HAd!@nغ+DlCv䕪|ʏ$C4R-ĘTJ9XfOn:%:ń5F"ьϕE0%&:~涩xH*̒ذW h s' Ct.[-IG.d-o!i }2"O: XEl=hA4 EQv7U_H+;ѣXT?~d־}^fAؾkAnlUsy}|ܼxӸ< EJKM5f vv0L2| o HtjʽO~JAbB N7u>^xkϫ?o(TU \#R5$ǣ4-'IUUٴi?W3qFFZHq^*ٟ yGȯ?aԁX&ɘj%q(˖նPP2cct._֍^;rgVXX(stN6`=(T؟ߚ7:Y?+ Np@38@"'=i `f˧43"W@$y%9E:o]07ѥw2H2)))ٳQXU'Du  H.+'oYp8ztm< |YQnT׎WV_Wcդ7w.5V_K^ )yGI? )1H3WHvW_}]MU{C/RU5_ <=$x, k~)G-+.q󿟊ط-W_Md1cپ#v{;HIzzŎ8'b@@\;RTAx髪ʄ 'cX}&9[)0,[:Cy.b3mݛ޷ gM9  V|BTiDپ'=[5y*}eawaf&1yIJ7B woGQtH7ү̲UJG N;J"ds`L@TW,`0":/!45VlBΆb7hTL`￳m6MP"pUv.a `KBCq{_qqѴNK`|>b arVne1 ؑF,g^sb+YԜ q2u ky:${[ڣGr4s1uXM'8G`o3k`RUկ#~%,X' eDǿ7"Kx&`dž^ƔSZiVhvU[n͆?-K7/I &noS tELLdKnS*5)ҾmÛn +.{|N,R5 MxfZ'\l *,T[DH!/CQnt:KdKE^G۝Ȳ,˜p6miLCEs{758Nɳ=2lذ3|'[ '(1Q'Nb1f̘$I #!>8fh̴m9Xߓ4ܕ\ԥ Y( =z~Yۮo`ff]лwjcMy..κ]~ܟC;73Wбo8f) 9z\/*XW#mDxT `xkEfVDVGVLV_ocaN|??%Iw2k_qߏ?'[%Gko/"W3rܾY|qyp/w`>CIN$~%!w'w8P^ŲdV6SPC&Qp{TP(9 J+'PVVIaA)v3%͛7o>HLLuK|TEA Ȳڵ((l62l0DU}4|Ƹqmkh4-P Mq!J%!o$wK xˍ@ ˒-kUz)ͨFYezw \4SE&蝡u_w9Db|Lw<%7 ?Alr%L#Ar8 ?ɑCN{gԘMYWk Hs6Ğ{.}8x9tMzBa:Dm2tl:et!wrzeh{i]ڴiݻw'11={ؠ_dwaj*'c/G"OU988]vvF:+L;) AENBEa).pRafc6#O*><O]gў}؋/˯Y1X0yZ~) ƦPaןXjNzsaJ?߷LkÖ6lNoc~9>5k߾|[!Ml6Sx1~N#1"  QD$ꎇQZYxo;諊[7cz9L3f]).NRhr?f T:EU[hwذEz.V^CQTSNmxY8iT.~SOv_ >A;?4iPX2BֻN>wW(j:+eն®!> eAdrU$hHhY(Pp82[,Ih.PS(xfӽxd hϟ;= ZN#CFmW?_=T=]6Wu'4ĥfo"v ?~L2O?4e i vP*!ێ>rrrHc{F&Q U>ẈhWPZVΑ2v0yx|k_hmX5k9Ν͛q|.Sޚ6<7GV۟-6O*L\aSPU@CNd,9-!R< Lяْ׼ym7Tm9~ 1te \:tFGCݷXs,ǚ`ixVTi[/o<n3f( >5 y/#cdžݯn}` 1ev@yG9))7[f _O<.3I u:՜ݲ[94ܦq]{8mt;uGӠKﶸ\*2ļRv+=N7R{<ۣ(8]N7Vv'.˃tZkV쳧|3-,[Te&3F(Ӡ),hG Ѧ(Ύ;ӧOzKUh4.\) )" `Q vӿz3>!e=x^öP΄ 1c7|3;w0n<9aP@:mPb5ṛ1GqAJ}}Ƙ5OH&@Ӽ/Eb++I1RxUwEwn3c vڅ`0Pvxv%~B6tΕW^ /FB'/]኉:P$|$KUp?W;_f{/,ٛimf׷Ę`iCw[sկ'9y@n,ѧ3}>Bwo9r3Z#W_o{ WS3txmm$FNz5z9s(ع~]ǧ_ioEtJu>cMUcwTH|[$F%e'** FnigHONQlg);[P]/Yq;{6m_׬B92htt4/]vG܇lu KMG*0֗odd>Yk٫oBhYI Ϸ+=ylؑ"ԼڕnK69ɜ4/~fNЦU҃ԕӗKWMٗ ?.=[1X8`w  fjdd~o%PrAp,03cZQ IDAT(gi8n.Y~BQ֩SgF`}26ءw+' hԮ՛nO.E$=ך){Ss^k;%U(+sp81|j2ArڦxIqeB%V GOv>[& *1e~?KԷYnf/ .DlqTad>L^ذa#F 999lY>Bxy!:]38q`U&ՉAws,jF<3C%Dk`:4h0.FJJBHԿ]J:R$-,60wl+%QU^&Lv$J~vI0(-5N?>326‘2T%I}RH78.8~ _z56ށ;f?9F擕=*֭CQި?:ۓ|eOOfh 2$H7j }ot{;Rc\[54[*]u/L\=?FޚpS>?f^U>j( &Mb|۶\=DBǎa$Imʲ05ly) Vc`ޥ4UShՅYڟBIiFx(J82(vAq!X^f)DU夁àyށЍǣ 1ۍAt0(ڻ(ٖzI@HS84^lق",x AOg. *)t! &lMvfgv?+/dgyf<&iNzɸ&輽%'^vםKj`"]QRXIQ.U^}տ; ,.f;™X-e[YNzxU ǣct KVQnm NU`!IδF e 4t-jSH`4Q^^xfBNN,KGSIr3h , cbw8qv79 ݺv xSOy|[keu'#lqVҧPwjwEii)&M #{Ꮳs#ġjƆS8W+F˞Nác( 7Il2_yPxuH rrPYY/}݇^{Y *x3y.-܁N|q>>?gsfv=`9djΝSѱc* DlN[!))58z(--k5u!$7$_6K2.! ]#[s Dq5`ܹX k`6A.2:xo/x 9$8@ I'נƊ#@GD RUإlظ]ǣo7_e_X.Cnj/*k *1pP L&L&8 06mYgcȑ!=W$wwށadëV + YJ Y|K<>gt~ [CWԩڥ L&sc~D3}@u `?2!%ص1y\zl@اqR]T5U0$ wEO$<蕖YVW_}3LA#`q 3}3q˞p`ս# <>Ggo2n!x#0v!>~B)ϗpm@!޶1\(}˅ZM7okg 'ND^0ydw\Ç!Iuv pVBq"$H$+Lj_ 4.#`Q I'IZ]B? >Xi9D2:7!9x|0 /eU.9+V <\%T[x+j@q9?r*H[u6ňޝt+hںNUԤ[ b`ڴiXh =pTV0,\3H7m60;n o/± hwutehӶЮ]+kk.rvRo0ICpҊ"z[>|8>3'C t[N`.+:uq bbLPZun#..F ''|c$9gQuv=iI'\K4:uM; ?*q ߻`KIojy.>/^Lr8 Gիѽ{wv`XΝ1}t Ϝ#t]pg4+~f6xsaZqtL=/A꓾μ :Z"<݁*`o߼r8V(p@X2+0A/YPV?]PmXQYU ͆Z:Ur=bu=h.A7 ܹ |*˹FVx&g}n]:`0>!x{mw26]$m6GpGq$k´c}y:]0I`z.>c 00x`\ a#SIUwй-бCO7bݮr HM1j@4# h!*vtlGQ  ը`"q`ضmcAxO!l6/:I` _ "$] qyQ3z=A9hu_zB *++pxLGU;ŮD ke%f3jjjqT'2!<'Ok~=?;={!o9 8zCx}ҭ& 55$aw[^NN,8~}+tZRup`lA׸]gWp9gW M' ?+p|M 욢,srk}K.Xm HnVy.6}(CǷ~(;4t6 ;w?޽{cʕ1b1b <HMMj켼n^YOn~Gܰ^pV5eKƓ{[WNҹPO ufk @x l@Y6ZYkfA6z8f8Ͱlގ3zudK6|>}O>7nDbb ƌ9PQQf -sN/Ks0.I1__|uuH6-O@`կ&[.(vNw0070qH2W >`?I=my2ڥ" nZ[nFtmg^ I+!]ۙ!36T*EfdvqM=B1zh;B\\\POgp]VnX8Zv\;Ͼ#xJ}Ʀ>BbR2:v=3899ؽ{76#99Ǐjŵ:uwŴ R j+ֿƵ~K/zmkR e}݇>Rp] TLG h6u_|l6&NE>vBmi)=QyC*{ϐ7y^/g\ EyoTaTl8BU ,+D88'i gvBtHBX˻gYMҒgYu偡[s>X+ܳnV`CbkCɄj=t:8yǪU` .D6mosAbb"͆Z[n>> G饥8a{Ϝ%@vhqa֬/ƽ!%"9\_[+``6`6a`P[kj@mm,#,x}O|Rc69Iy7P9o^ ᜤ$޽{BHNNAm ƣm(w ;x:9u]HbD5 ?vpZ2&kbz`o3 q'Jhs3LohNK Fc3&0w̌?!IV( D*kAbbrP7^zaǎС6n܈#G p_ Y믻?Rtx6xr`!m6O1ieHnrMAA32We2sN@uIM؈m+ކܿZ:t={thWy Bj6T<+ KƒJpS尗ĭh׮;L&UVuQH;z\ino*Ͻ㪰*J{B9$`[*$݇BϾ[1g9ue8s8˪+?y.} y t[8|`3˝ pqw>u;fC^͆'No$Ia9ұ#s;v:RvhkYm1̄W-چ*p9t9b0k^&Îyer\[mFթ 6TVts2jw/SUQsuts_1zyh: GO@NN[ر3~}?Zץݿ&L@owI+)j,3и^hS 8+`9'_1Z]|9Uʷ5eCCs8VlʐlUj %%aSUU`q< /v1\!$ $I(--ū.ǬYuVcڴi8pvlߎ/߭]rVO` ={'Κ[n+G"99yyy^I=) S ӡDcqcGtqQwޕ_<>GشiS Jg(}5}KtAy'O_|12*մKڡ7~?qa Vaִ&ŊZ3jjlFmVf {vWcAo}?lC·֍oQ';e+vY$IBFFwZ>, te90߿?%z C N׼9`udu+cƓa]C2cFʫ^*lf`  :|'%cB6е-!/Z`T 6I@D ufPpO9@Ze'Xmo)C4ڧ&Bdi5P|=[06ӌN - HCխ[7Xz/#Fd}b_~9uι%Inȑ#q$''OGqq1$^x!1idvƾ"#ʟx z!{HO_|zzL&:ԥvpt:K%{{v,Ἧp}%3S! .לոW.I`^ӟ䱾3fx#2 : )[ y!ܗVgmm6Îj !]o1"#FO0)355FJdff\|6۷ڶMDN.מ]]TƴVk\'/nQh,8o'Κ-z 4|yK^uicqȆMy@`28oe2H6 tMc ;lw'm!pA1c.\#F555~GzNQ ]#y3RRRp9B[׮ rܗ#Cb=yi Λ! e׮]HKS())AΝ`4`2a4r}bAJl!z!C4YnĉN*j)%9P3 oyޖ 6}(C_Z?Ɩ2OWRUu.Ž;ZH4ٷwDm;V+֬Y /'k6oHˆ CZ~ žG^\TVQXRΙ'5I|Ďh ArQVVI&!...`}t:t:u:W9~.aos8-;lvF̛7˗// zϺt_U = k՘m(@x#F# Tly.+Wl:ꪫB-W]w׷oޢ.^SR[T݉5kiADDDDZ4p@߷m)X>h,9`DDDDj֭oݺU(9`DDDDl˖-䍇`gQx5 VXzEy1XDDDDQE`DDDD2ګ剐L(9ٚs$0""""/ < 0""""?r4A+GHa HaODDDGK'{0""""ibIΈB3D֐À I${*/ZRh-K,ˋֲ.eip%G@4)ف(v419`()Y^hnh6%Ek;FsTʒ0""""1oB$/ }BhN'j `DDDD cFDDD0`DDDD L0W^N$""pw41""""90+Q `FDDD0`DDIEFZLo=iC9bXᆧ/-)i}䏅M񳐢tH$%bQ-:sh$I¸ז]?Y /JΪEغNҷeNB˯Ì['xO$)CyVE0D!k 8_\$Y5#""pWDE;ߚyӑ>Ay'7A!.]"b5A]q4"9FDDD1 =^{vK"77{shU""""8#"R3OJms¹ 6`DDDD cFDDD0`DDDD L`DN pPh"^G$NFDDDrhcDE0""""jpOhԘKu"R`DDDD cFDD1*`DDDD cFDQOQi-47ZB3y\y9)51""b0+Q `FD-Y IDATFr9QPͩT4lCi )Fy غyHa =jY;u^SkwjΫIC<`DDD$Ɂyb0"UYDh\n6'_֣%Z3E'`DDDD cFD Q$0#"""R0hO 4J+6 w="]jiO"4yH0!/"j66c(gh&#""" (q4DMu<`_WϘԢXmU`DDDD cFDDaӜDHLo=iC9( (Y O_Z R Zg!EM赜;v,Ǝߢ(ZE:-,W{Բ,Z(Z#d LkcX4m{$a\FJ1&y H;iG()}ۡ]$0o EXV?ro$I"h#YsxJ`ߋQ\7|g#!96@$QtZ3Dw5F#}ԃ{NoroҥKQTSWWvKFzxt?&ܲt"0lXʶ?ιᬿj,ςL:'f{즗Enng>OQ"":Q0yɟm@>)4eFDDD0` !"& PTSǬm r]DS69洅rbFDDD0Y&i(%-7ңjQpsh<H^>OJ `7Xh|Zpj3kĴ]jV5<~ %(ى Ϥ% (hvha{~g G(D} DQS]HKrDF@eRSo5QӾ> %C >#"5R#`H4BK;J^` B!qJZ p /iwi'VHḴ'֣}xiI;.%ǹ\u.\\=4E;5/D0" haQ u$e(9<"0#"""RXL`r<-a(Phn&9lXg]vw¶(]G掆s.b2#"vyyI`95]HB8C. $IH"XOG!IQL`o*#I9R*'eVNᜏuӜ\xM[| w2{ P`9<_E@,d*#wГۋf\Wӷ`9[D)v+5j[E* W$F'1Ҧs i A#kZ?91S %XADD-w6l0Zyl}P۩<`~|[R볮87&tj*)$g{5c0m61WPR`{3Ga:1E宧ۡ9ucFzߢyZmS/0 B5<^Z&f0FDD‰ɻ edD ĝ;rPC*IGu Z(痚?" !Ͳ0 mCO6mGZDB ""p0 LuׂHXᆧ/-)i}䏅`,=OCDR55G^j7jVxj>ؒ1w~_;-xO$Hq.@ױ3嬒E:' pXQM sx\D$>ƕ|UK:<+q nX7n~/cǎxϕ eL"j"" ]9UKǕ|U}X|k.NG[إKX Ic3ZOhiӦY5"UoDy\YQp' p4Hg7Ş=s57`OY5""X_5։(Xԁ|m_lws#\\Ǣ=I0JVf,f0"rRIDz նA亳1tj9-00аOObOj޼U9F \9:C+Sh۞HQ۳ÑHy` u*zj.ګqHpώNDjkў^m px0N.jB-ҢFͣ>1"E#> ZH\9:Cd=7(-|k-a_$hrQödꪏZ>R˶p,%- Gt5O*{WOsDCߏVJ+0 hF%lDۄ(2SÅd.֗bm{I~S꧙̕C-gLi:y] 䪛"׼X 2.mu̺T3cHr NEMbrnC |10R o*8:s^u_iC8b%h$>Q18k`!|[ ˏԁJDj.2ZҖ#-ߪx&euU<ُkcѴ%M7?ZR7nHAl>O2h\2Cs}Qk-غNXUawPsYN#'>]xϕlID(⊆"coA Jvq./I$IĤdT<`r_yyB5OW\~hlhܦX[ek+DE;ߚyӑ>Ay'uM_~e׿_6 u &/o5_8qM~"))僳1.EDk{5~-lX(8Q{X$I³^r={p5A$ )8Uʓ_U-SO2>lIகmؤ*DzHI1!6DDDD9YSV;vke2esFK)Z=B Hϣ'M`Pb) ga #A"$ Qh`L& 2r97R9)S}1VS_FE"VCVoosJDjcD+ԢHf0""""bfZ# A4>Lk+`TEΗ67ET`䛿[-ۥļ#(EӉ8(Z8;g\&qt(X Ż=\1qAZHD]Z-c#"R泰aThjIjkC"Ւ̚ԃiZ^rm&"`OZ:X_DD-MQqNZ ݡ%V!'j0""""`A&|l;""R`UVhi݉(xHĪLѢd~B345Յ?gKtJ&}LFDDD-NbMs7I툈<1#Ґ`;Dkx"%0\"jH0R9IDD,`D T""r1DrPP}|QDQ͌)GMBDD1Q `FDDD0`u|]eA""R`,{ ҆Fx"ZPG" kj  O_Z R .0~RwCSк3>\""""8%Scؿv>M[Ϲ/U-R~{$"X%[lg\Aݦw^]>uI?=f5'hcۄb]ø"1lcoA Jvq./'݇#c?\`LٔS6:5+*؝ożH ޼B:&/2j_C-LkgÕnZDDDD'ۣ҆F=%sss={e\""""<]nJڞԍEH}DDT0JEFL`xm"""6 NE]$ce""҆H$b- Ei%+iKC L3#`DDDDт/QbF F 0""""1#"""R0^R#"X4BI_. x(0# Ո(*0!"XHa HaIC<`DywDDN/ZHMDD,#""" HQtcFb ADD0""""1#"""R0""""1#"""Rf1+ɁX`EDDDr`"V"""Ha ea@PBkEDDDLp藖x¦ 5"""(#[d|]ǢiK?6=wI0.#EDD+d tՙmü$CDDD Hp -(ҷ870""" _q\Q";!or/5B`ҥ()«+VU-"""m,mlڳ^r?77{{(0))LI-(("cT3/"""CCy;`DDDD cFDDD0`DDDD cFDDD0`DDDD cFDDD0c"V"""DDDDD1)俁"wvP #4`DDDD L&I"PdyZҢy۔QIg+c(Y#""<`DDDD1@3#`ZT[yZEkYJe)]^ty,K{i2&0^~$""hKDDDD cFDDD0`DY FXᆧ/-)i}䏅k9#0vX; CѤĨ񳐢wN _ĘÅ'Id|]K Kp"]%0c@:20~G#I?9obи Ҹ\ n\uϿQ_9dԑ&-]E5Exuj\?c|~~[9?O(q3nUT`ݢ"]'"""c,^SR[T݉} (1#"""R0""""1#"""R0""""1#"""R0""""1#"""R0""""1#"""RgAرCz ،3QXBzEy<~0""""1#"""R0""""1#"""R4d~YI^l6'`͚5())X&''SLA.]Z\"j>_DEr@uu5{1ݻPUSJuzOm|l߾ve0V[[*k*hGzr`5bɒ%ضmR&""JS~鰮 !8et::x?"G;!;.)B[w ?X~駟:J|'8^z0B/Pe_clWԫI*;;Lg~R4$ Z5,l9u#Ɯ;3;O8<& ! _u~] 'uΆAN%ZR((؎L|p[|t:% _>lӾEA77o$Ig{볺ujN3)[twj58QzA%7nDD- speZOQ,z]]c8y[=\xf, {^ : >*}io XI2a0Wvy/Ìţ=[:mwwZlhab/jVTWᨋ]I]iO7yd{2>~ǯe8 q(,d0}bo_'g|^mx?;;}㦱l3?+"@=^8~髸2-~zĥ [ǹ_k3緉O > TZ45;-88y)kA8j }RQG\iM.<윬@E7ąsqZ|w r6`#^ X %"g7Bol~]cYLgl/؊q`Qmeغ} ~ټ<_È+=wG1,1de=_~7/|a׿cضY+[F տ^W->wwoB|qM^coUSQxTlwz K,}䜠"l#μg?R}_̹ڸS'b{]̺*?]=v(U3 >.Vg߭ "pu Om$gG#+/-dff_:EdggohwEi7vJ]I3|ߛ} s]JI['y{gS%²kB$ĵ>ܤ~=O쥸c~z':tdyo..{K>b cntrwY:ߌV'w2c83y'e᱾m(? r_ [ly j_ :爗k&-my]c{,WwHm mpOdۘoSnE^A;cٗF-~b11+I}oY0o* <RI,,x_( =?g}|a=khßߊ"So]^.:{zSݜ=紻xץKvmXd AYPRQ.bD*=!C`VGDD1Dҷ `ѽKi' 8A3XBWwuaZN'e7Runz 菻Bmz8tdWj3n|}0mߗY+=ფ;0u\a ߇Y8EO̼:C<(/˻'ƛ_D9j_g"xcjKKN`quqBV[r3tTwsEO_Q,cODD1+Oк%pnLDJ7ɇQ`$᷃'C[$^$"""R)-F䭊T])M.A6^Uz W?J"""" V"I?XIENDB`kst-2.0.3/docbook/kst/scripttutorial/simple.js000644 001750 001750 00000001010 11544160206 022020 0ustar00synthsynth000000 000000 // A very simple KstScript demo: plot column 1 of a file vs line number // open the file "demodata.dat" file = new DataSource("demodata.dat"); // grab the window var w = Kst.windows[0]; // add a plot to the window var p = new Plot(w); // create the X vector which is the line number of the file var x = new DataVector(file,"INDEX"); // create the Y vector, which is column 1 var y = new DataVector(file,"1"); // create a curve from x and y var c = new Curve(x,y); // put the curve in the plot p.curves.append(c); kst-2.0.3/docbook/kst/scripttutorial/scripttutorial.docbook000644 001750 001750 00000020004 11544160206 024627 0ustar00synthsynth000000 000000 KST"> KstScript"> ]> The &kjs; Tutorial Barth Netterfield
    kst@kde.org
    2006 Barth Netterfield 2006-03-19 1.2.0 &kjs; is a JavaScript binding for &kst;. It offers full control over all aspects of &kst; KDE kdeextragear Kst plotting plot JavaScript
    Running a KstScript &kjs; is a JavaScript binding to &kst;. There are three ways to to run a &kjs; from the command line when starting &kst;: kst -E js:"loadScript('myscript.js')" using kstcmd kstcmd Attached to Kst session kst-17704 kst> loadScript(myscript.js) from the menu once &kst; is loaded: File->LoadJavaScript Note that with the first two methods, any KstScript command, or collection of KstScript commands can be substituted for the loadscript command. A simple KstScript Here we have the 'hello world' of KstScripts: plot a curve from a file. // simple.js: A very simple KstScript demo: plot column 1 of a file vs line number // open the file "demodata.dat" file = new DataSource("demodata.dat"); // grab the window var w = Kst.windows[0]; // add a plot to the window var p = new Plot(w); // create the X vector which is the line number of the file var x = new DataVector(file,"INDEX"); // create the Y vector, which is column 1 var y = new DataVector(file,"1"); // create a curve from x and y var c = new Curve(x,y); // put the curve in the plot p.curves.append(c); This script plots column 1 of the file 'demodata.dat' vs line number. It can be run by any of the three methods from . For example, kst -E js:"loadScript('simple.js')" Simple Output Tagnames and Variable names In the simple script from , we refered to all of the objects we created by their KstScript names. This, however, is not how they are refered to from the Kst UI. In the UI, objects are refered to by their Tag Name (or "Unique Name"). The script above did not define the tag names of any of the objects we created (plots, vectors and curves), so if you try to look things up in the data manager, you will get cryptic names like "anonymous vector 1", or, for the curve, "". If you ever plan to use the UI to work with objects you have created with a KstScript, you will want to set their tag name: x.tagName = "xv" Once you have set the tagName, you can use it to refer to the object as a parameter in the built in KstScript function calls. The following script does the same thing as the script in , except that it sets and refers to objects by their tagName. // very simple KstScript demo: plot a vector collumn from a file file = new DataSource("demodata.dat") var w = new Window; var p = new Plot(w); var x = new DataVector(file,"INDEX"); x.tagName = "xv" var y = new DataVector(file,"1"); y.tagName = "yv" var c = new Curve("xv","yv"); c.tagName = "c" p.curves.append("c"); Writing, Including, and Calling Subroutines As with any JavaScript environment, you can write and call functions with KstScript. Additionally, KstScript posseses a means for a KstScript to load functions from disk. Consider the following example: // subroutines.js // plot a field from a datasource in a previously created plot function addField(plot, field, f0, n, datasource) { var x1 = new DataVector(datasource, "INDEX", f0, n); x1.tagName = "INDEX" var y1 = new DataVector(datasource, field, f0, n); y1.tagName=field var c1 = new Curve(x1, y1); c1.tagName = field plot.curves.append(c1) plot.topLabel = plot.topLabel + field + " " } // create a plot and add a field curve to it. function plotField(field, f0, n, datasource) { var p1 = new Plot(Kst.windows[0]); p1.topLabel = "File: " + datasource.fileName + " Fields: " addField(p1,field, f0, n, datasource); p1.xAxis.label = "Index" return p1 } This example contains two functions: addField() reads data from a datasource, makes a curve from it, and plots the curve in an exisiting plot. Additionally, it appends the field name to the top label. plotField() creates a new plot, plots a curve in it, and sets the X axis label, and top label. The following script loads subroutines.js, and then uses plotField() and addField() to plot 3 columns of data from demodata.dat. Notice that subroutines.js is loaded using loadScript(), the same call that we used from the command line in . // callsubs.js // demonstrate calling subroutines loadScript('subroutines.js'); file = new DataSource("demodata.dat"); var p = plotField("1", 0, -1, file); addField(p, "2", 0, -1, file); addField(p, "3", 0, -1, file); CallSubs Output
    kst-2.0.3/docbook/kst/scripttutorial/demodata.dat000644 001750 001750 00000351056 11544160206 022463 0ustar00synthsynth000000 000000 0.1371469069999982 -0.09102273199999882 -0.2417358600000009 0.1419084719999982 -0.09671080399999882 -0.2388918240000009 0.1428607849999982 -0.09197074399999881 -0.2332037520000009 0.1390515329999982 -0.0900747199999988 -0.2341517640000009 0.1409561589999982 -0.09481477999999881 -0.2388918240000009 0.1419084719999982 -0.09386676799999881 -0.2426838720000009 0.1419084719999982 -0.09386676799999881 -0.2388918240000009 0.1285760899999982 -0.09481477999999881 -0.2436318840000009 0.1323853419999982 -0.0900747199999988 -0.2578520640000009 0.1361945939999982 -0.08723068399999881 -0.2559560400000009 0.1304807159999982 -0.09386676799999881 -0.2474239320000009 0.1380992199999982 -0.0900747199999988 -0.2531120040000009 0.1380992199999982 -0.08723068399999881 -0.2654361600000009 0.1380992199999982 -0.09576279199999881 -0.2588000760000009 0.1476223499999982 -0.09576279199999881 -0.2455279080000009 0.1504792889999982 -0.09481477999999881 -0.2436318840000009 0.1390515329999982 -0.09102273199999882 -0.2417358600000009 0.1276237769999982 -0.09197074399999881 -0.2379438120000009 0.1380992199999982 -0.09386676799999881 -0.2407878480000009 0.1419084719999982 -0.08628267199999881 -0.2436318840000009 0.1447654109999982 -0.07869857599999881 -0.2379438120000009 0.1476223499999982 -0.08628267199999881 -0.2350997760000009 0.1390515329999982 -0.09386676799999881 -0.2398398360000009 0.1361945939999982 -0.09671080399999882 -0.2474239320000009 0.1419084719999982 -0.09765881599999882 -0.2559560400000009 0.1352422809999982 -0.09291875599999881 -0.2483719440000009 0.1276237769999982 -0.08154261199999881 -0.2407878480000009 0.1323853419999982 -0.08249062399999881 -0.2445798960000009 0.1323853419999982 -0.09197074399999881 -0.2455279080000009 0.1266714639999982 -0.08628267199999881 -0.2502679680000009 0.1295284029999982 -0.08723068399999881 -0.2521639920000009 0.1333376549999982 -0.09386676799999881 -0.2445798960000009 0.1247668379999982 -0.09481477999999881 -0.2464759200000009 0.1276237769999982 -0.09481477999999881 -0.2502679680000009 0.1371469069999982 -0.09860682799999881 -0.2369958000000009 0.1371469069999982 -0.08817869599999881 -0.2294117040000009 0.1352422809999982 -0.08154261199999881 -0.2369958000000009 0.1342899679999982 -0.08343863599999882 -0.2369958000000009 0.1333376549999982 -0.07869857599999881 -0.2398398360000009 0.1285760899999982 -0.08059459999999881 -0.2464759200000009 0.1314330289999982 -0.08817869599999881 -0.2455279080000009 0.1428607849999982 -0.09481477999999881 -0.2455279080000009 0.1361945939999982 -0.09386676799999881 -0.2474239320000009 0.1371469069999982 -0.09197074399999881 -0.2493199560000009 0.1380992199999982 -0.08533465999999881 -0.2559560400000009 0.1371469069999982 -0.08817869599999881 -0.2493199560000009 0.1380992199999982 -0.09671080399999882 -0.2417358600000009 0.1314330289999982 -0.09102273199999882 -0.2474239320000009 0.1342899679999982 -0.08154261199999881 -0.2502679680000009 0.1323853419999982 -0.07964658799999881 -0.2464759200000009 0.1285760899999982 -0.08343863599999882 -0.2445798960000009 0.1352422809999982 -0.09102273199999882 -0.2455279080000009 0.1342899679999982 -0.0900747199999988 -0.2436318840000009 0.1390515329999982 -0.08533465999999881 -0.2341517640000009 0.1466700369999982 -0.08154261199999881 -0.2341517640000009 0.1371469069999982 -0.08154261199999881 -0.2464759200000009 0.1400038459999982 -0.08249062399999881 -0.2455279080000009 0.1419084719999982 -0.0900747199999988 -0.2436318840000009 0.1380992199999982 -0.1023988759999988 -0.2464759200000009 0.1380992199999982 -0.09860682799999881 -0.2436318840000009 0.1352422809999982 -0.09576279199999881 -0.2417358600000009 0.1380992199999982 -0.1005028519999988 -0.2483719440000009 0.1323853419999982 -0.09386676799999881 -0.2569040520000009 0.1247668379999982 -0.08533465999999881 -0.2483719440000009 0.1238145249999982 -0.09481477999999881 -0.2426838720000009 0.1342899679999982 -0.09765881599999882 -0.2502679680000009 0.1419084719999982 -0.09102273199999882 -0.2474239320000009 0.1371469069999982 -0.09102273199999882 -0.2445798960000009 0.1333376549999982 -0.09481477999999881 -0.2474239320000009 0.1304807159999982 -0.09197074399999881 -0.2502679680000009 0.1380992199999982 -0.08723068399999881 -0.2426838720000009 0.1352422809999982 -0.08154261199999881 -0.2388918240000009 0.1314330289999982 -0.08249062399999881 -0.2417358600000009 0.1342899679999982 -0.08154261199999881 -0.2350997760000009 0.1361945939999982 -0.07869857599999881 -0.2360477880000009 0.1447654109999982 -0.0900747199999988 -0.2455279080000009 0.1447654109999982 -0.09102273199999882 -0.2417358600000009 0.1438130979999982 -0.08912670799999881 -0.2464759200000009 0.1447654109999982 -0.09765881599999882 -0.2531120040000009 0.1380992199999982 -0.09765881599999882 -0.2531120040000009 0.1266714639999982 -0.08628267199999881 -0.2531120040000009 0.1181006469999982 -0.09481477999999881 -0.2531120040000009 0.1228622119999982 -0.09671080399999882 -0.2540600160000009 0.1323853419999982 -0.08817869599999881 -0.2483719440000009 0.1304807159999982 -0.09291875599999881 -0.2455279080000009 0.1333376549999982 -0.09386676799999881 -0.2464759200000009 0.1419084719999982 -0.09291875599999881 -0.2398398360000009 0.1380992199999982 -0.09386676799999881 -0.2369958000000009 0.1352422809999982 -0.0900747199999988 -0.2464759200000009 0.1285760899999982 -0.0900747199999988 -0.2426838720000009 0.1181006469999982 -0.09386676799999881 -0.2369958000000009 0.1228622119999982 -0.08249062399999881 -0.2303597160000009 0.1257191509999982 -0.07775056399999881 -0.2275156800000009 0.1342899679999982 -0.08628267199999881 -0.2388918240000009 0.1485746629999982 -0.09576279199999881 -0.2398398360000009 0.1409561589999982 -0.09671080399999882 -0.2398398360000009 0.1314330289999982 -0.09765881599999882 -0.2493199560000009 0.1304807159999982 -0.1071389359999988 -0.2569040520000009 0.1361945939999982 -0.1033468879999988 -0.2559560400000009 0.1390515329999982 -0.09860682799999881 -0.2531120040000009 0.1361945939999982 -0.09197074399999881 -0.2550080280000009 0.1352422809999982 -0.08438664799999882 -0.2521639920000009 0.1400038459999982 -0.08723068399999881 -0.2464759200000009 0.1380992199999982 -0.08817869599999881 -0.2474239320000009 0.1314330289999982 -0.08533465999999881 -0.2464759200000009 0.1285760899999982 -0.08438664799999882 -0.2322557400000009 0.1247668379999982 -0.08723068399999881 -0.2303597160000009 0.1323853419999982 -0.09860682799999881 -0.2398398360000009 0.1438130979999982 -0.1052429119999988 -0.2350997760000009 0.1390515329999982 -0.09291875599999881 -0.2322557400000009 0.1371469069999982 -0.08817869599999881 -0.2369958000000009 0.1361945939999982 -0.08912670799999881 -0.2388918240000009 0.1323853419999982 -0.0900747199999988 -0.2417358600000009 0.1400038459999982 -0.09481477999999881 -0.2445798960000009 0.1380992199999982 -0.09481477999999881 -0.2445798960000009 0.1314330289999982 -0.09765881599999882 -0.2474239320000009 0.1342899679999982 -0.09576279199999881 -0.2483719440000009 0.1323853419999982 -0.1014508639999988 -0.2493199560000009 0.1380992199999982 -0.1023988759999988 -0.2483719440000009 0.1419084719999982 -0.09291875599999881 -0.2388918240000009 0.1371469069999982 -0.08249062399999881 -0.2360477880000009 0.1257191509999982 -0.08343863599999882 -0.2455279080000009 0.1295284029999982 -0.09291875599999881 -0.2455279080000009 0.1390515329999982 -0.08912670799999881 -0.2341517640000009 0.1400038459999982 -0.0900747199999988 -0.2322557400000009 0.1390515329999982 -0.09671080399999882 -0.2322557400000009 0.1304807159999982 -0.09860682799999881 -0.2388918240000009 0.1333376549999982 -0.09576279199999881 -0.2445798960000009 0.1352422809999982 -0.08723068399999881 -0.2398398360000009 0.1333376549999982 -0.08249062399999881 -0.2322557400000009 0.1361945939999982 -0.08912670799999881 -0.2341517640000009 0.1371469069999982 -0.1005028519999988 -0.2445798960000009 0.1323853419999982 -0.08912670799999881 -0.2502679680000009 0.1285760899999982 -0.08438664799999882 -0.2455279080000009 0.1342899679999982 -0.09481477999999881 -0.2502679680000009 0.1361945939999982 -0.09386676799999881 -0.2550080280000009 0.1342899679999982 -0.09576279199999881 -0.2483719440000009 0.1333376549999982 -0.09765881599999882 -0.2559560400000009 0.1333376549999982 -0.09386676799999881 -0.2578520640000009 0.1352422809999982 -0.09291875599999881 -0.2531120040000009 0.1371469069999982 -0.09576279199999881 -0.2559560400000009 0.1371469069999982 -0.09765881599999882 -0.2464759200000009 0.1438130979999982 -0.1014508639999988 -0.2436318840000009 0.1457177239999982 -0.09481477999999881 -0.2407878480000009 0.1380992199999982 -0.08628267199999881 -0.2313077280000009 0.1352422809999982 -0.08817869599999881 -0.2379438120000009 0.1371469069999982 -0.09291875599999881 -0.2417358600000009 0.1333376549999982 -0.09291875599999881 -0.2379438120000009 0.1333376549999982 -0.08817869599999881 -0.2426838720000009 0.1352422809999982 -0.09197074399999881 -0.2436318840000009 0.1314330289999982 -0.1005028519999988 -0.2445798960000009 0.1342899679999982 -0.09671080399999882 -0.2464759200000009 0.1380992199999982 -0.08628267199999881 -0.2512159800000009 0.1295284029999982 -0.07964658799999881 -0.2550080280000009 0.1219098989999982 -0.08343863599999882 -0.2540600160000009 0.1247668379999982 -0.0900747199999988 -0.2540600160000009 0.1295284029999982 -0.08059459999999881 -0.2559560400000009 0.1361945939999982 -0.08343863599999882 -0.2493199560000009 0.1304807159999982 -0.09860682799999881 -0.2388918240000009 0.1295284029999982 -0.0900747199999988 -0.2332037520000009 0.1314330289999982 -0.08154261199999881 -0.2284636920000009 0.1361945939999982 -0.08628267199999881 -0.2388918240000009 0.1466700369999982 -0.08533465999999881 -0.2455279080000009 0.1371469069999982 -0.0758545399999988 -0.2407878480000009 0.1238145249999982 -0.07775056399999881 -0.2379438120000009 0.1219098989999982 -0.08628267199999881 -0.2398398360000009 0.1200052729999982 -0.08628267199999881 -0.2493199560000009 0.1295284029999982 -0.09102273199999882 -0.2531120040000009 0.1323853419999982 -0.09955483999999881 -0.2493199560000009 0.1333376549999982 -0.09860682799999881 -0.2464759200000009 0.1314330289999982 -0.08817869599999881 -0.2550080280000009 0.1371469069999982 -0.08723068399999881 -0.2588000760000009 0.1400038459999982 -0.0900747199999988 -0.2512159800000009 0.1380992199999982 -0.09197074399999881 -0.2455279080000009 0.1390515329999982 -0.0900747199999988 -0.2455279080000009 0.1285760899999982 -0.08533465999999881 -0.2398398360000009 0.1314330289999982 -0.08723068399999881 -0.2369958000000009 0.1390515329999982 -0.08533465999999881 -0.2407878480000009 0.1409561589999982 -0.08249062399999881 -0.2474239320000009 0.1428607849999982 -0.0900747199999988 -0.2474239320000009 0.1409561589999982 -0.08628267199999881 -0.2350997760000009 0.1342899679999982 -0.08817869599999881 -0.2303597160000009 0.1333376549999982 -0.09860682799999881 -0.2332037520000009 0.1276237769999982 -0.09671080399999882 -0.2398398360000009 0.1276237769999982 -0.08912670799999881 -0.2502679680000009 0.1304807159999982 -0.09197074399999881 -0.2540600160000009 0.1342899679999982 -0.09481477999999881 -0.2512159800000009 0.1361945939999982 -0.08533465999999881 -0.2512159800000009 0.1333376549999982 -0.08249062399999881 -0.2521639920000009 0.1295284029999982 -0.08249062399999881 -0.2512159800000009 0.1266714639999982 -0.08438664799999882 -0.2455279080000009 0.1342899679999982 -0.08343863599999882 -0.2436318840000009 0.1304807159999982 -0.08912670799999881 -0.2483719440000009 0.1333376549999982 -0.09955483999999881 -0.2388918240000009 0.1400038459999982 -0.0900747199999988 -0.2284636920000009 0.1304807159999982 -0.08533465999999881 -0.2417358600000009 0.1295284029999982 -0.08723068399999881 -0.2474239320000009 0.1361945939999982 -0.08154261199999881 -0.2407878480000009 0.1371469069999982 -0.08533465999999881 -0.2426838720000009 0.1295284029999982 -0.09576279199999881 -0.2483719440000009 0.1314330289999982 -0.1005028519999988 -0.2493199560000009 0.1428607849999982 -0.09671080399999882 -0.2455279080000009 0.1361945939999982 -0.09102273199999882 -0.2445798960000009 0.1333376549999982 -0.09386676799999881 -0.2540600160000009 0.1304807159999982 -0.09386676799999881 -0.2616441120000009 0.1257191509999982 -0.08438664799999882 -0.2550080280000009 0.1257191509999982 -0.08059459999999881 -0.2483719440000009 0.1352422809999982 -0.08343863599999882 -0.2550080280000009 0.1390515329999982 -0.08628267199999881 -0.2569040520000009 0.1371469069999982 -0.08059459999999881 -0.2540600160000009 0.1419084719999982 -0.07490652799999881 -0.2436318840000009 0.1428607849999982 -0.07964658799999881 -0.2322557400000009 0.1428607849999982 -0.08723068399999881 -0.2379438120000009 0.1428607849999982 -0.08438664799999882 -0.2426838720000009 0.1428607849999982 -0.08628267199999881 -0.2407878480000009 0.1380992199999982 -0.08059459999999881 -0.2407878480000009 0.1323853419999982 -0.08249062399999881 -0.2398398360000009 0.1295284029999982 -0.09481477999999881 -0.2483719440000009 0.1352422809999982 -0.09197074399999881 -0.2540600160000009 0.1342899679999982 -0.08912670799999881 -0.2521639920000009 0.1285760899999982 -0.08817869599999881 -0.2483719440000009 0.1361945939999982 -0.08533465999999881 -0.2540600160000009 0.1390515329999982 -0.09860682799999881 -0.2635401360000009 0.1371469069999982 -0.09386676799999881 -0.2578520640000009 0.1438130979999982 -0.08912670799999881 -0.2483719440000009 0.1295284029999982 -0.09197074399999881 -0.2436318840000009 0.1247668379999982 -0.08533465999999881 -0.2483719440000009 0.1323853419999982 -0.0900747199999988 -0.2512159800000009 0.1276237769999982 -0.08723068399999881 -0.2455279080000009 0.1342899679999982 -0.08059459999999881 -0.2417358600000009 0.1333376549999982 -0.07869857599999881 -0.2398398360000009 0.1238145249999982 -0.0758545399999988 -0.2398398360000009 0.1266714639999982 -0.08249062399999881 -0.2388918240000009 0.1352422809999982 -0.08817869599999881 -0.2417358600000009 0.1333376549999982 -0.08438664799999882 -0.2417358600000009 0.1285760899999982 -0.09291875599999881 -0.2417358600000009 0.1314330289999982 -0.09386676799999881 -0.2426838720000009 0.1285760899999982 -0.09481477999999881 -0.2436318840000009 0.1380992199999982 -0.1005028519999988 -0.2474239320000009 0.1428607849999982 -0.09291875599999881 -0.2474239320000009 0.1314330289999982 -0.09197074399999881 -0.2550080280000009 0.1190529599999982 -0.09481477999999881 -0.2550080280000009 0.1200052729999982 -0.09291875599999881 -0.2464759200000009 0.1266714639999982 -0.09291875599999881 -0.2502679680000009 0.1257191509999982 -0.09197074399999881 -0.2502679680000009 0.1295284029999982 -0.08723068399999881 -0.2398398360000009 0.1342899679999982 -0.08628267199999881 -0.2417358600000009 0.1257191509999982 -0.09102273199999882 -0.2445798960000009 0.1247668379999982 -0.08154261199999881 -0.2407878480000009 0.1323853419999982 -0.08343863599999882 -0.2436318840000009 0.1333376549999982 -0.08912670799999881 -0.2483719440000009 0.1314330289999982 -0.08533465999999881 -0.2417358600000009 0.1333376549999982 -0.09197074399999881 -0.2388918240000009 0.1390515329999982 -0.08723068399999881 -0.2426838720000009 0.1476223499999982 -0.09197074399999881 -0.2350997760000009 0.1419084719999982 -0.09671080399999882 -0.2407878480000009 0.1371469069999982 -0.09291875599999881 -0.2512159800000009 0.1333376549999982 -0.09481477999999881 -0.2502679680000009 0.1323853419999982 -0.09481477999999881 -0.2474239320000009 0.1419084719999982 -0.09481477999999881 -0.2455279080000009 0.1400038459999982 -0.08628267199999881 -0.2521639920000009 0.1380992199999982 -0.07775056399999881 -0.2606961000000009 0.1400038459999982 -0.08059459999999881 -0.2606961000000009 0.1409561589999982 -0.08343863599999882 -0.2540600160000009 0.1400038459999982 -0.08912670799999881 -0.2474239320000009 0.1380992199999982 -0.09102273199999882 -0.2445798960000009 0.1361945939999982 -0.08628267199999881 -0.2398398360000009 0.1371469069999982 -0.0900747199999988 -0.2379438120000009 0.1371469069999982 -0.09386676799999881 -0.2417358600000009 0.1276237769999982 -0.09102273199999882 -0.2436318840000009 0.1200052729999982 -0.08723068399999881 -0.2398398360000009 0.1266714639999982 -0.08059459999999881 -0.2426838720000009 0.1333376549999982 -0.08059459999999881 -0.2398398360000009 0.1323853419999982 -0.09197074399999881 -0.2341517640000009 0.1285760899999982 -0.1005028519999988 -0.2455279080000009 0.1181006469999982 -0.0900747199999988 -0.2540600160000009 0.1228622119999982 -0.08723068399999881 -0.2540600160000009 0.1390515329999982 -0.09291875599999881 -0.2493199560000009 0.1409561589999982 -0.08912670799999881 -0.2521639920000009 0.1409561589999982 -0.08912670799999881 -0.2569040520000009 0.1333376549999982 -0.09102273199999882 -0.2531120040000009 0.1247668379999982 -0.08817869599999881 -0.2474239320000009 0.1342899679999982 -0.09291875599999881 -0.2407878480000009 0.1400038459999982 -0.09197074399999881 -0.2407878480000009 0.1333376549999982 -0.08154261199999881 -0.2493199560000009 0.1314330289999982 -0.08723068399999881 -0.2493199560000009 0.1333376549999982 -0.09102273199999882 -0.2407878480000009 0.1409561589999982 -0.0768025519999988 -0.2369958000000009 0.1466700369999982 -0.0758545399999988 -0.2474239320000009 0.1447654109999982 -0.08533465999999881 -0.2474239320000009 0.1295284029999982 -0.08249062399999881 -0.2445798960000009 0.1238145249999982 -0.07964658799999881 -0.2502679680000009 0.1342899679999982 -0.08912670799999881 -0.2521639920000009 0.1333376549999982 -0.09102273199999882 -0.2502679680000009 0.1304807159999982 -0.09481477999999881 -0.2550080280000009 0.1333376549999982 -0.0900747199999988 -0.2654361600000009 0.1380992199999982 -0.08343863599999882 -0.2578520640000009 0.1371469069999982 -0.09291875599999881 -0.2483719440000009 0.1323853419999982 -0.09481477999999881 -0.2464759200000009 0.1323853419999982 -0.08817869599999881 -0.2474239320000009 0.1333376549999982 -0.08438664799999882 -0.2512159800000009 0.1314330289999982 -0.08533465999999881 -0.2455279080000009 0.1314330289999982 -0.08817869599999881 -0.2379438120000009 0.1371469069999982 -0.09386676799999881 -0.2398398360000009 0.1390515329999982 -0.08817869599999881 -0.2483719440000009 0.1333376549999982 -0.08154261199999881 -0.2445798960000009 0.1266714639999982 -0.08438664799999882 -0.2360477880000009 0.1304807159999982 -0.08817869599999881 -0.2436318840000009 0.1400038459999982 -0.09481477999999881 -0.2436318840000009 0.1409561589999982 -0.1014508639999988 -0.2464759200000009 0.1438130979999982 -0.09671080399999882 -0.2521639920000009 0.1390515329999982 -0.08817869599999881 -0.2531120040000009 0.1247668379999982 -0.09291875599999881 -0.2540600160000009 0.1285760899999982 -0.09197074399999881 -0.2569040520000009 0.1333376549999982 -0.08817869599999881 -0.2483719440000009 0.1285760899999982 -0.09197074399999881 -0.2417358600000009 0.1371469069999982 -0.08533465999999881 -0.2483719440000009 0.1428607849999982 -0.08533465999999881 -0.2474239320000009 0.1314330289999982 -0.08343863599999882 -0.2436318840000009 0.1314330289999982 -0.08343863599999882 -0.2379438120000009 0.1333376549999982 -0.09197074399999881 -0.2341517640000009 0.1333376549999982 -0.08628267199999881 -0.2379438120000009 0.1323853419999982 -0.08154261199999881 -0.2445798960000009 0.1333376549999982 -0.08343863599999882 -0.2426838720000009 0.1390515329999982 -0.09386676799999881 -0.2426838720000009 0.1371469069999982 -0.09860682799999881 -0.2436318840000009 0.1304807159999982 -0.09481477999999881 -0.2445798960000009 0.1295284029999982 -0.09576279199999881 -0.2502679680000009 0.1342899679999982 -0.09291875599999881 -0.2512159800000009 0.1333376549999982 -0.09386676799999881 -0.2512159800000009 0.1323853419999982 -0.08723068399999881 -0.2521639920000009 0.1333376549999982 -0.07490652799999881 -0.2483719440000009 0.1266714639999982 -0.07490652799999881 -0.2474239320000009 0.1295284029999982 -0.08438664799999882 -0.2493199560000009 0.1361945939999982 -0.08723068399999881 -0.2531120040000009 0.1295284029999982 -0.0758545399999988 -0.2407878480000009 0.1295284029999982 -0.07964658799999881 -0.2341517640000009 0.1352422809999982 -0.07775056399999881 -0.2379438120000009 0.1428607849999982 -0.07775056399999881 -0.2369958000000009 0.1409561589999982 -0.08723068399999881 -0.2379438120000009 0.1333376549999982 -0.08154261199999881 -0.2388918240000009 0.1323853419999982 -0.08059459999999881 -0.2483719440000009 0.1352422809999982 -0.08912670799999881 -0.2521639920000009 0.1295284029999982 -0.09291875599999881 -0.2531120040000009 0.1333376549999982 -0.08628267199999881 -0.2550080280000009 0.1380992199999982 -0.08249062399999881 -0.2521639920000009 0.1333376549999982 -0.08723068399999881 -0.2502679680000009 0.1285760899999982 -0.08723068399999881 -0.2569040520000009 0.1304807159999982 -0.08249062399999881 -0.2663841720000009 0.1323853419999982 -0.08343863599999882 -0.2588000760000009 0.1276237769999982 -0.08438664799999882 -0.2455279080000009 0.1352422809999982 -0.08249062399999881 -0.2436318840000009 0.1333376549999982 -0.0768025519999988 -0.2464759200000009 0.1304807159999982 -0.08154261199999881 -0.2436318840000009 0.1342899679999982 -0.08438664799999882 -0.2436318840000009 0.1276237769999982 -0.07964658799999881 -0.2445798960000009 0.1333376549999982 -0.07490652799999881 -0.2445798960000009 0.1323853419999982 -0.07775056399999881 -0.2540600160000009 0.1295284029999982 -0.08628267199999881 -0.2559560400000009 0.1390515329999982 -0.08343863599999882 -0.2455279080000009 0.1400038459999982 -0.08249062399999881 -0.2455279080000009 0.1361945939999982 -0.08912670799999881 -0.2493199560000009 0.1352422809999982 -0.08533465999999881 -0.2531120040000009 0.1400038459999982 -0.08249062399999881 -0.2588000760000009 0.1390515329999982 -0.08628267199999881 -0.2578520640000009 0.1323853419999982 -0.08059459999999881 -0.2521639920000009 0.1304807159999982 -0.08059459999999881 -0.2578520640000009 0.1342899679999982 -0.07964658799999881 -0.2597480880000009 0.1352422809999982 -0.08438664799999882 -0.2578520640000009 0.1428607849999982 -0.0900747199999988 -0.2616441120000009 0.1371469069999982 -0.08059459999999881 -0.2550080280000009 0.1285760899999982 -0.08343863599999882 -0.2474239320000009 0.1266714639999982 -0.08723068399999881 -0.2483719440000009 0.1342899679999982 -0.08249062399999881 -0.2521639920000009 0.1371469069999982 -0.0758545399999988 -0.2455279080000009 0.1304807159999982 -0.07206249199999881 -0.2445798960000009 0.1314330289999982 -0.07395851599999881 -0.2521639920000009 0.1323853419999982 -0.08154261199999881 -0.2550080280000009 0.1333376549999982 -0.08817869599999881 -0.2625921240000009 0.1285760899999982 -0.08628267199999881 -0.2625921240000009 0.1238145249999982 -0.07775056399999881 -0.2512159800000009 0.1257191509999982 -0.08249062399999881 -0.2588000760000009 0.1238145249999982 -0.09955483999999881 -0.2692282080000009 0.1266714639999982 -0.08628267199999881 -0.2625921240000009 0.1342899679999982 -0.07490652799999881 -0.2625921240000009 0.1323853419999982 -0.08059459999999881 -0.2625921240000009 0.1342899679999982 -0.08343863599999882 -0.2521639920000009 0.1390515329999982 -0.08343863599999882 -0.2483719440000009 0.1419084719999982 -0.08343863599999882 -0.2483719440000009 0.1428607849999982 -0.08817869599999881 -0.2512159800000009 0.1390515329999982 -0.0900747199999988 -0.2417358600000009 0.1323853419999982 -0.08912670799999881 -0.2398398360000009 0.1295284029999982 -0.08438664799999882 -0.2455279080000009 0.1352422809999982 -0.07775056399999881 -0.2436318840000009 0.1400038459999982 -0.08059459999999881 -0.2464759200000009 0.1352422809999982 -0.08723068399999881 -0.2625921240000009 0.1323853419999982 -0.0900747199999988 -0.2578520640000009 0.1333376549999982 -0.08723068399999881 -0.2578520640000009 0.1361945939999982 -0.09197074399999881 -0.2483719440000009 0.1304807159999982 -0.09197074399999881 -0.2455279080000009 0.1266714639999982 -0.08154261199999881 -0.2512159800000009 0.1333376549999982 -0.07869857599999881 -0.2417358600000009 0.1238145249999982 -0.07869857599999881 -0.2398398360000009 0.1190529599999982 -0.07111447999999881 -0.2417358600000009 0.1228622119999982 -0.0635303839999988 -0.2398398360000009 0.1200052729999982 -0.0635303839999988 -0.2417358600000009 0.1152437079999982 -0.07016646799999882 -0.2436318840000009 0.1238145249999982 -0.07301050399999881 -0.2369958000000009 0.1219098989999982 -0.07301050399999881 -0.2398398360000009 0.1047682649999982 -0.0768025519999988 -0.2464759200000009 0.1066728909999982 -0.07111447999999881 -0.2388918240000009 0.1133390819999982 -0.06447839599999881 -0.2303597160000009 0.1142913949999982 -0.06447839599999881 -0.2284636920000009 0.1133390819999982 -0.06068634799999881 -0.2350997760000009 0.1171483339999982 -0.05784231199999881 -0.2360477880000009 0.1181006469999982 -0.0625823719999988 -0.2322557400000009 0.1219098989999982 -0.0635303839999988 -0.2275156800000009 0.1276237769999982 -0.0625823719999988 -0.2294117040000009 0.1228622119999982 -0.05499827599999881 -0.2275156800000009 0.1276237769999982 -0.0483621919999988 -0.2227756200000009 0.1361945939999982 -0.05689429999999881 -0.2199315840000009 0.1295284029999982 -0.06163435999999881 -0.2227756200000009 0.1314330289999982 -0.05784231199999881 -0.2256196560000009 0.1295284029999982 -0.05784231199999881 -0.2161395360000009 0.1238145249999982 -0.06163435999999881 -0.2208795960000009 0.1266714639999982 -0.06732243199999881 -0.2227756200000009 0.1285760899999982 -0.05973833599999881 -0.2123474880000009 0.1190529599999982 -0.04741417999999881 -0.2161395360000009 0.1161960209999982 -0.05025821599999881 -0.2132955000000009 0.1266714639999982 -0.05784231199999881 -0.2132955000000009 0.1219098989999982 -0.05594628799999881 -0.2189835720000009 0.1209575859999982 -0.04741417999999881 -0.2189835720000009 0.1276237769999982 -0.04077809599999881 -0.2151915240000009 0.1295284029999982 -0.04267411999999881 -0.2057114040000009 0.1333376549999982 -0.04172610799999881 -0.2019193560000009 0.1295284029999982 -0.03793405999999881 -0.1962312840000009 0.1276237769999982 -0.03414201199999881 -0.1990753200000009 0.1285760899999982 -0.02655791599999881 -0.2019193560000009 0.1314330289999982 -0.02750592799999881 -0.2019193560000009 0.1285760899999982 -0.03414201199999881 -0.2085554400000009 0.1295284029999982 -0.03888207199999881 -0.2085554400000009 0.1295284029999982 -0.04172610799999881 -0.2019193560000009 0.1285760899999982 -0.03793405999999881 -0.1971792960000009 0.1276237769999982 -0.03888207199999881 -0.2038153800000009 0.1200052729999982 -0.04172610799999881 -0.2057114040000009 0.1104821429999982 -0.04362213199999881 -0.2047633920000009 0.1152437079999982 -0.04457014399999881 -0.2066594160000009 0.1304807159999982 -0.04362213199999881 -0.2038153800000009 0.1333376549999982 -0.04551815599999881 -0.2057114040000009 0.1276237769999982 -0.05025821599999881 -0.2104514640000009 0.1200052729999982 -0.04741417999999881 -0.2076074280000009 0.1209575859999982 -0.04931020399999881 -0.1981273080000009 0.1200052729999982 -0.05405026399999881 -0.1905432120000009 0.1190529599999982 -0.03888207199999881 -0.1924392360000009 0.1171483339999982 -0.03698604799999881 -0.1867511640000009 0.1181006469999982 -0.04457014399999881 -0.1820111040000009 0.1266714639999982 -0.04362213199999881 -0.1867511640000009 0.1295284029999982 -0.03414201199999881 -0.1848551400000009 0.1190529599999982 -0.01992183199999881 -0.1839071280000009 0.1181006469999982 -0.02845393999999881 -0.1829591160000009 0.1238145249999982 -0.04457014399999881 -0.1858031520000009 0.1171483339999982 -0.04457014399999881 -0.1952832720000009 0.1228622119999982 -0.04551815599999881 -0.2000233320000009 0.1304807159999982 -0.03793405999999881 -0.1971792960000009 0.1285760899999982 -0.03793405999999881 -0.1943352600000009 0.1266714639999982 -0.04172610799999881 -0.1848551400000009 0.1266714639999982 -0.02845393999999881 -0.1839071280000009 0.1266714639999982 -0.02750592799999881 -0.1886471880000009 0.1295284029999982 -0.03224598799999881 -0.1829591160000009 0.1266714639999982 -0.02940195199999881 -0.1848551400000009 0.1257191509999982 -0.02655791599999881 -0.1829591160000009 0.1352422809999982 -0.01612978399999881 -0.1772710440000009 0.1314330289999982 -0.008545687999998807 -0.1725309840000009 0.1247668379999982 -0.01802580799999881 -0.1677909240000009 0.1266714639999982 -0.01328574799999881 -0.1639988760000009 0.1323853419999982 -0.008545687999998807 -0.1658949000000009 0.1342899679999982 -0.01423375999999881 -0.1696869480000009 0.1285760899999982 -0.02371387999999881 -0.1744270080000009 0.1266714639999982 -0.03319399999999881 -0.1763230320000009 0.1209575859999982 -0.02276586799999881 -0.1677909240000009 0.1200052729999982 -0.02371387999999881 -0.1725309840000009 0.1238145249999982 -0.03224598799999881 -0.1801150800000009 0.1181006469999982 -0.02371387999999881 -0.1810630920000009 0.1219098989999982 -0.02560990399999881 -0.1829591160000009 0.1276237769999982 -0.03129797599999881 -0.1753750200000009 0.1247668379999982 -0.02560990399999881 -0.1630508640000009 0.1219098989999982 -0.01802580799999881 -0.1564147800000009 0.1190529599999982 -0.01707779599999881 -0.1535707440000009 0.1200052729999982 -0.02181785599999881 -0.1564147800000009 0.1304807159999982 -0.01518177199999881 -0.1649468880000009 0.1333376549999982 -0.007597675999998808 -0.1592588160000009 0.1295284029999982 -0.01233773599999881 -0.1516747200000009 0.1266714639999982 -0.01423375999999881 -0.1602068280000009 0.1228622119999982 -0.01138972399999881 -0.1621028520000009 0.1209575859999982 -0.007597675999998808 -0.1545187560000009 0.1200052729999982 -0.01138972399999881 -0.1535707440000009 0.1219098989999982 -0.01612978399999881 -0.1573627920000009 0.1219098989999982 -0.01707779599999881 -0.1602068280000009 0.1276237769999982 -0.02086984399999881 -0.1554667680000009 0.1295284029999982 -0.02181785599999881 -0.1535707440000009 0.1295284029999982 -0.01044171199999881 -0.1526227320000009 0.1285760899999982 -1.357999999880739e-05 -0.1564147800000009 0.1219098989999982 -0.003805627999998808 -0.1592588160000009 0.1190529599999982 -0.006649663999998808 -0.1507267080000009 0.1247668379999982 -0.005701651999998808 -0.1469346600000009 0.1266714639999982 -0.003805627999998808 -0.1431426120000009 0.1285760899999982 -0.009493699999998807 -0.1365065280000009 0.1371469069999982 -0.01044171199999881 -0.1450386360000009 0.1361945939999982 -0.002857615999998807 -0.1488306840000009 0.1361945939999982 -1.357999999880739e-05 -0.1374545400000009 0.1390515329999982 0.007570516000001193 -0.1346105040000009 0.1314330289999982 0.01136256400000119 -0.1374545400000009 0.1209575859999982 -0.004753639999998808 -0.1412465880000009 0.1228622119999982 -0.01423375999999881 -0.1526227320000009 0.1266714639999982 -0.005701651999998808 -0.1535707440000009 0.1352422809999982 -0.009493699999998807 -0.1431426120000009 0.1409561589999982 -0.01707779599999881 -0.1478826720000009 0.1285760899999982 -0.005701651999998808 -0.1535707440000009 0.1266714639999982 -0.003805627999998808 -0.1516747200000009 0.1314330289999982 -0.01044171199999881 -0.1583108040000009 0.1323853419999982 -0.01044171199999881 -0.1573627920000009 0.1304807159999982 -0.01138972399999881 -0.1564147800000009 0.1266714639999982 -0.002857615999998807 -0.1469346600000009 0.1371469069999982 0.002830456000001192 -0.1355585160000009 0.1371469069999982 0.005674492000001193 -0.1279744200000009 0.1304807159999982 0.009466540000001192 -0.1232343600000009 0.1209575859999982 0.005674492000001193 -0.1270264080000009 0.1200052729999982 0.008518528000001193 -0.1346105040000009 0.1238145249999982 0.01515461200000119 -0.1327144800000009 0.1181006469999982 0.01894666000000119 -0.1260783960000009 0.1238145249999982 0.01041455200000119 -0.1289224320000009 0.1352422809999982 -0.003805627999998808 -0.1317664680000009 0.1352422809999982 0.005674492000001193 -0.1317664680000009 0.1276237769999982 0.006622504000001193 -0.1346105040000009 0.1209575859999982 -0.007597675999998808 -0.1355585160000009 0.1228622119999982 -0.0009615919999988072 -0.1393505640000009 0.1285760899999982 0.002830456000001192 -0.1478826720000009 0.1276237769999982 0.003778468000001192 -0.1393505640000009 0.1266714639999982 0.005674492000001193 -0.1289224320000009 0.1247668379999982 0.002830456000001192 -0.1270264080000009 0.1238145249999982 0.005674492000001193 -0.1260783960000009 0.1342899679999982 0.01799864800000119 -0.1184943000000009 0.1419084719999982 0.02084268400000119 -0.1023780960000009 0.1380992199999982 0.02179069600000119 -0.0976380360000009 0.1285760899999982 0.02937479200000119 -0.1128062280000009 0.1285760899999982 0.03411485200000119 -0.1194423120000009 0.1333376549999982 0.02558274400000119 -0.1099621920000009 0.1266714639999982 0.02368672000000119 -0.1109102040000009 0.1266714639999982 0.02937479200000119 -0.1128062280000009 0.1285760899999982 0.0303228040000012 -0.1156502640000009 0.1228622119999982 0.02179069600000119 -0.1203903240000009 0.1247668379999982 0.007570516000001193 -0.1175462880000009 0.1295284029999982 0.006622504000001193 -0.1156502640000009 0.1314330289999982 0.01420660000000119 -0.1156502640000009 0.1295284029999982 0.02653075600000119 -0.1147022520000009 0.1323853419999982 0.0303228040000012 -0.1080661680000009 0.1314330289999982 0.02558274400000119 -0.1099621920000009 0.1285760899999982 0.02653075600000119 -0.1156502640000009 0.1295284029999982 0.02368672000000119 -0.1071181560000009 0.1390515329999982 0.01894666000000119 -0.1004820720000009 0.1380992199999982 0.03221882800000119 -0.1014300840000009 0.1228622119999982 0.04075093600000119 -0.1023780960000009 0.1295284029999982 0.02842678000000119 -0.1014300840000009 0.1361945939999982 0.02273870800000119 -0.1071181560000009 0.1304807159999982 0.02842678000000119 -0.1109102040000009 0.1276237769999982 0.0303228040000012 -0.1061701440000009 0.1276237769999982 0.02463473200000119 -0.1052221320000009 0.1304807159999982 0.02747876800000119 -0.1090141800000009 0.1219098989999982 0.02842678000000119 -0.1156502640000009 0.1238145249999982 0.03411485200000119 -0.1118582160000009 0.1361945939999982 0.02937479200000119 -0.1118582160000009 0.1400038459999982 0.03221882800000119 -0.1165982760000009 0.1400038459999982 0.0473870200000012 -0.1099621920000009 0.1295284029999982 0.04454298400000119 -0.1071181560000009 0.1238145249999982 0.03601087600000119 -0.09953406000000091 0.1323853419999982 0.02179069600000119 -0.0900539400000009 0.1400038459999982 0.02653075600000119 -0.08720990400000091 0.1361945939999982 0.04169894800000119 -0.0957420120000009 0.1304807159999982 0.04169894800000119 -0.09479400000000091 0.1304807159999982 0.05023105600000119 -0.0881579160000009 0.1390515329999982 0.0473870200000012 -0.09384598800000091 0.1352422809999982 0.03885491200000119 -0.09194996400000091 0.1276237769999982 0.05023105600000119 -0.0834178560000009 0.1304807159999982 0.04549099600000119 -0.08720990400000091 0.1219098989999982 0.0369588880000012 -0.0976380360000009 0.1152437079999982 0.03411485200000119 -0.09858604800000091 0.1200052729999982 0.0303228040000012 -0.0976380360000009 0.1285760899999982 0.03601087600000119 -0.09194996400000091 0.1266714639999982 0.04169894800000119 -0.09100195200000091 0.1190529599999982 0.04549099600000119 -0.09100195200000091 0.1209575859999982 0.04075093600000119 -0.0843658680000009 0.1228622119999982 0.0464390080000012 -0.08626189200000091 0.1238145249999982 0.06255521200000119 -0.08057382000000091 0.1304807159999982 0.05876316400000119 -0.07204171200000091 0.1314330289999982 0.05212708000000119 -0.0710937000000009 0.1285760899999982 0.05117906800000119 -0.0767817720000009 0.1266714639999982 0.05117906800000119 -0.07962580800000091 0.1323853419999982 0.05876316400000119 -0.07393773600000091 0.1380992199999982 0.06160720000000119 -0.07772978400000091 0.1342899679999982 0.0578151520000012 -0.0834178560000009 0.1380992199999982 0.0530750920000012 -0.0834178560000009 0.1447654109999982 0.0464390080000012 -0.07962580800000091 0.1352422809999982 0.04928304400000119 -0.07867779600000091 0.1314330289999982 0.05497111600000119 -0.0824698440000009 0.1304807159999982 0.06160720000000119 -0.0891059280000009 0.1247668379999982 0.0578151520000012 -0.0891059280000009 0.1257191509999982 0.0540231040000012 -0.0843658680000009 0.1304807159999982 0.0597111760000012 -0.07962580800000091 0.1295284029999982 0.0606591880000012 -0.0691976760000009 0.1295284029999982 0.0597111760000012 -0.06635364000000091 0.1295284029999982 0.05686714000000119 -0.0701456880000009 0.1361945939999982 0.0672952720000012 -0.0635096040000009 0.1361945939999982 0.0748793680000012 -0.06540562800000091 0.1352422809999982 0.0663472600000012 -0.07204171200000091 0.1409561589999982 0.06445123600000119 -0.0701456880000009 0.1400038459999982 0.06539924800000119 -0.06730165200000091 0.1428607849999982 0.06919129600000119 -0.0682496640000009 0.1342899679999982 0.0672952720000012 -0.0691976760000009 0.1295284029999982 0.06255521200000119 -0.06540562800000091 0.1371469069999982 0.06919129600000119 -0.06445761600000091 0.1371469069999982 0.06919129600000119 -0.05971755600000091 0.1304807159999982 0.07108732000000119 -0.0635096040000009 0.1314330289999982 0.07677539200000119 -0.06635364000000091 0.1276237769999982 0.08341147600000119 -0.06066556800000091 0.1314330289999982 0.0739313560000012 -0.06540562800000091 0.1390515329999982 0.06350322400000119 -0.0710937000000009 0.1333376549999982 0.0663472600000012 -0.06540562800000091 0.1342899679999982 0.0672952720000012 -0.06066556800000091 0.1361945939999982 0.07108732000000119 -0.05308147200000091 0.1390515329999982 0.07013930800000119 -0.04644538800000091 0.1390515329999982 0.0663472600000012 -0.0473934000000009 0.1314330289999982 0.0739313560000012 -0.05213346000000091 0.1352422809999982 0.0872035240000012 -0.05308147200000091 0.1390515329999982 0.09004756000000119 -0.05213346000000091 0.1257191509999982 0.09099557200000119 -0.0511854480000009 0.1181006469999982 0.08435948800000119 -0.0549774960000009 0.1181006469999982 0.07867141600000119 -0.05687352000000091 0.1304807159999982 0.0729833440000012 -0.0559255080000009 0.1409561589999982 0.07772340400000119 -0.06540562800000091 0.1390515329999982 0.0872035240000012 -0.06445761600000091 0.1352422809999982 0.0881515360000012 -0.05876954400000091 0.1342899679999982 0.0815154520000012 -0.05971755600000091 0.1352422809999982 0.07772340400000119 -0.0691976760000009 0.1361945939999982 0.07772340400000119 -0.0682496640000009 0.1361945939999982 0.0805674400000012 -0.05876954400000091 0.1314330289999982 0.0947876200000012 -0.05876954400000091 0.1314330289999982 0.0947876200000012 -0.05023743600000091 0.1285760899999982 0.0872035240000012 -0.03601725600000091 0.1219098989999982 0.08246346400000119 -0.04265334000000091 0.1209575859999982 0.07582738000000119 -0.05023743600000091 0.1238145249999982 0.0796194280000012 -0.0436013520000009 0.1238145249999982 0.0881515360000012 -0.0379132800000009 0.1295284029999982 0.0881515360000012 -0.0379132800000009 0.1304807159999982 0.09099557200000119 -0.04265334000000091 0.1257191509999982 0.0928915960000012 -0.0379132800000009 0.1371469069999982 0.09004756000000119 -0.03317322000000091 0.1419084719999982 0.0928915960000012 -0.03980930400000091 0.1276237769999982 0.09573563200000119 -0.03886129200000091 0.1276237769999982 0.0938396080000012 -0.03980930400000091 0.1276237769999982 0.0796194280000012 -0.03980930400000091 0.1314330289999982 0.0815154520000012 -0.0369652680000009 0.1409561589999982 0.09763165600000119 -0.0369652680000009 0.1419084719999982 0.0947876200000012 -0.0303291840000009 0.1409561589999982 0.1004756920000012 -0.0284331600000009 0.1419084719999982 0.1052157520000012 -0.03601725600000091 0.1447654109999982 0.09668364400000119 -0.02938117200000091 0.1476223499999982 0.09668364400000119 -0.0236931000000009 0.1380992199999982 0.09194358400000119 -0.0284331600000009 0.1323853419999982 0.09004756000000119 -0.02274508800000091 0.1304807159999982 0.1033197280000012 -0.0217970760000009 0.1266714639999982 0.1061637640000012 -0.0284331600000009 0.1380992199999982 0.09194358400000119 -0.0255891240000009 0.1409561589999982 0.0928915960000012 -0.0199010520000009 0.1285760899999982 0.1014237040000012 -0.0255891240000009 0.1219098989999982 0.0995276800000012 -0.0312771960000009 0.1285760899999982 0.09763165600000119 -0.0341212320000009 0.1266714639999982 0.1023717160000012 -0.0379132800000009 0.1247668379999982 0.1004756920000012 -0.0284331600000009 0.1314330289999982 0.0995276800000012 -0.0236931000000009 0.1371469069999982 0.1137478600000012 -0.0255891240000009 0.1457177239999982 0.1222799680000012 -0.0180050280000009 0.1380992199999982 0.1127998480000012 -0.0151609920000009 0.1380992199999982 0.1071117760000012 -0.008524908000000903 0.1504792889999982 0.1071117760000012 7.199999999096818e-06 0.1428607849999982 0.1175399080000012 -0.005680872000000904 0.1295284029999982 0.1298640640000012 -0.006628884000000904 0.1295284029999982 0.1222799680000012 -0.0104209320000009 0.1361945939999982 0.1127998480000012 -0.0142129800000009 0.1400038459999982 0.1052157520000012 -0.01610900400000091 0.1352422809999982 0.1090078000000012 -0.0151609920000009 0.1209575859999982 0.1175399080000012 -0.0113689440000009 0.1133390819999982 0.1146958720000012 -0.0104209320000009 0.1257191509999982 0.1023717160000012 -0.008524908000000903 0.1361945939999982 0.1061637640000012 -0.0123169560000009 0.1352422809999982 0.1184879200000012 -0.0170570160000009 0.1295284029999982 0.1203839440000012 -0.0189530400000009 0.1257191509999982 0.1137478600000012 -0.0189530400000009 0.1276237769999982 0.1080597880000012 -0.0208490640000009 0.1295284029999982 0.1109038240000012 -0.01610900400000091 0.1257191509999982 0.1184879200000012 -0.008524908000000903 0.1314330289999982 0.1194359320000012 -0.003784848000000902 0.1428607849999982 0.1137478600000012 -0.006628884000000904 0.1428607849999982 0.1127998480000012 -0.009472920000000903 0.1409561589999982 0.1071117760000012 -0.003784848000000902 0.1428607849999982 0.1080597880000012 -0.002836836000000903 0.1438130979999982 0.1109038240000012 -0.0113689440000009 0.1419084719999982 0.1052157520000012 -0.01610900400000091 0.1247668379999982 0.1023717160000012 -0.0151609920000009 0.1171483339999982 0.1033197280000012 -0.0170570160000009 0.1323853419999982 0.1071117760000012 -0.0170570160000009 0.1419084719999982 0.1156438840000012 -0.0142129800000009 0.1409561589999982 0.1090078000000012 -0.0142129800000009 0.1266714639999982 0.1099558120000012 -0.0132649680000009 0.1228622119999982 0.1156438840000012 -0.009472920000000903 0.1342899679999982 0.1109038240000012 -0.0123169560000009 0.1428607849999982 0.1118518360000012 -0.0132649680000009 0.1447654109999982 0.1090078000000012 -0.0113689440000009 0.1409561589999982 0.1127998480000012 -0.005680872000000904 0.1438130979999982 0.1203839440000012 0.003799247999999096 0.1400038459999982 0.1203839440000012 -0.001888824000000903 0.1380992199999982 0.1184879200000012 -0.01610900400000091 0.1457177239999982 0.1137478600000012 -0.0199010520000009 0.1380992199999982 0.1004756920000012 -0.0151609920000009 0.1323853419999982 0.1014237040000012 -0.01610900400000091 0.1304807159999982 0.0985796680000012 -0.0265371360000009 0.1285760899999982 0.0928915960000012 -0.02938117200000091 0.1352422809999982 0.1090078000000012 -0.0217970760000009 0.1380992199999982 0.1109038240000012 -0.0217970760000009 0.1323853419999982 0.0995276800000012 -0.0265371360000009 0.1266714639999982 0.1080597880000012 -0.01610900400000091 0.1257191509999982 0.1137478600000012 -0.0113689440000009 0.1276237769999982 0.1061637640000012 -0.0113689440000009 0.1371469069999982 0.1023717160000012 -0.007576896000000903 0.1361945939999982 0.09668364400000119 -0.0123169560000009 0.1276237769999982 0.1033197280000012 -0.0180050280000009 0.1295284029999982 0.1165918960000012 -0.0208490640000009 0.1390515329999982 0.1184879200000012 -0.0151609920000009 0.1400038459999982 0.1213319560000012 -0.005680872000000904 0.1409561589999982 0.1137478600000012 -0.0151609920000009 0.1438130979999982 0.1061637640000012 -0.0274851480000009 0.1352422809999982 0.1099558120000012 -0.03317322000000091 0.1285760899999982 0.1033197280000012 -0.0255891240000009 0.1352422809999982 0.1052157520000012 -0.0180050280000009 0.1380992199999982 0.1146958720000012 -0.0189530400000009 0.1409561589999982 0.1099558120000012 -0.0189530400000009 0.1342899679999982 0.1099558120000012 -0.02274508800000091 0.1228622119999982 0.1090078000000012 -0.0284331600000009 0.1342899679999982 0.1061637640000012 -0.0236931000000009 0.1400038459999982 0.1080597880000012 -0.0132649680000009 0.1400038459999982 0.1090078000000012 -0.0151609920000009 0.1447654109999982 0.1071117760000012 -0.0132649680000009 0.1409561589999982 0.1118518360000012 -0.0113689440000009 0.1419084719999982 0.1109038240000012 -0.0151609920000009 0.1457177239999982 0.1118518360000012 -0.0189530400000009 0.1485746629999982 0.1175399080000012 -0.01610900400000091 0.1390515329999982 0.1156438840000012 -0.0113689440000009 0.1323853419999982 0.1109038240000012 -0.009472920000000903 0.1342899679999982 0.1061637640000012 -0.0132649680000009 0.1295284029999982 0.1099558120000012 -0.0180050280000009 0.1304807159999982 0.1109038240000012 -0.0142129800000009 0.1285760899999982 0.1061637640000012 -0.0170570160000009 0.1276237769999982 0.1099558120000012 -0.01610900400000091 0.1323853419999982 0.1080597880000012 -0.0189530400000009 0.1276237769999982 0.1061637640000012 -0.0274851480000009 0.1323853419999982 0.1090078000000012 -0.0284331600000009 0.1428607849999982 0.1080597880000012 -0.03222520800000091 0.1400038459999982 0.1109038240000012 -0.02938117200000091 0.1380992199999982 0.1099558120000012 -0.0236931000000009 0.1371469069999982 0.1127998480000012 -0.0199010520000009 0.1333376549999982 0.1165918960000012 -0.0189530400000009 0.1409561589999982 0.1127998480000012 -0.0170570160000009 0.1485746629999982 0.1165918960000012 -0.0132649680000009 0.1523839149999982 0.1194359320000012 -0.0151609920000009 0.1495269759999982 0.1099558120000012 -0.0170570160000009 0.1333376549999982 0.1118518360000012 -0.0180050280000009 0.1361945939999982 0.1175399080000012 -0.01610900400000091 0.1476223499999982 0.1080597880000012 -0.0199010520000009 0.1428607849999982 0.1052157520000012 -0.0199010520000009 0.1323853419999982 0.1080597880000012 -0.0208490640000009 0.1247668379999982 0.1061637640000012 -0.02274508800000091 0.1200052729999982 0.1042677400000012 -0.02274508800000091 0.1295284029999982 0.09763165600000119 -0.0303291840000009 0.1371469069999982 0.0995276800000012 -0.0312771960000009 0.1266714639999982 0.1090078000000012 -0.0303291840000009 0.1161960209999982 0.1090078000000012 -0.03222520800000091 0.1142913949999982 0.1090078000000012 -0.0303291840000009 0.1228622119999982 0.1071117760000012 -0.02938117200000091 0.1314330289999982 0.0985796680000012 -0.0189530400000009 0.1380992199999982 0.0995276800000012 -0.005680872000000904 0.1380992199999982 0.1080597880000012 -0.0104209320000009 0.1342899679999982 0.1194359320000012 -0.01610900400000091 0.1276237769999982 0.1194359320000012 -0.0170570160000009 0.1304807159999982 0.1127998480000012 -0.0208490640000009 0.1447654109999982 0.1099558120000012 -0.0104209320000009 0.1476223499999982 0.1099558120000012 -0.005680872000000904 0.1342899679999982 0.1137478600000012 -0.0113689440000009 0.1380992199999982 0.1033197280000012 -0.0180050280000009 0.1504792889999982 0.09763165600000119 -0.0274851480000009 0.1428607849999982 0.1061637640000012 -0.0236931000000009 0.1438130979999982 0.1052157520000012 -0.0208490640000009 0.1409561589999982 0.1033197280000012 -0.0246411120000009 0.1342899679999982 0.1146958720000012 -0.0274851480000009 0.1438130979999982 0.1165918960000012 -0.02274508800000091 0.1504792889999982 0.1080597880000012 -0.0170570160000009 0.1476223499999982 0.1127998480000012 -0.0132649680000009 0.1476223499999982 0.1146958720000012 -0.0189530400000009 0.1447654109999982 0.1052157520000012 -0.0180050280000009 0.1342899679999982 0.1090078000000012 -0.008524908000000903 0.1285760899999982 0.1184879200000012 -0.0132649680000009 0.1352422809999982 0.1194359320000012 -0.0142129800000009 0.1485746629999982 0.1127998480000012 -0.0113689440000009 0.1390515329999982 0.1099558120000012 -0.0151609920000009 0.1333376549999982 0.1052157520000012 -0.02274508800000091 0.1333376549999982 0.1052157520000012 -0.0199010520000009 0.1361945939999982 0.1090078000000012 -0.0189530400000009 0.1371469069999982 0.1052157520000012 -0.0255891240000009 0.1295284029999982 0.1118518360000012 -0.0284331600000009 0.1361945939999982 0.1023717160000012 -0.0274851480000009 0.1457177239999982 0.09668364400000119 -0.0217970760000009 0.1485746629999982 0.1071117760000012 -0.0189530400000009 0.1352422809999982 0.1109038240000012 -0.0217970760000009 0.1257191509999982 0.1127998480000012 -0.0303291840000009 0.1285760899999982 0.1099558120000012 -0.02938117200000091 0.1371469069999982 0.1080597880000012 -0.0236931000000009 0.1400038459999982 0.1156438840000012 -0.0142129800000009 0.1333376549999982 0.1251240040000012 -0.009472920000000903 0.1428607849999982 0.1241759920000012 -0.009472920000000903 0.1466700369999982 0.1127998480000012 -0.009472920000000903 0.1342899679999982 0.1175399080000012 -0.0151609920000009 0.1314330289999982 0.1184879200000012 -0.0142129800000009 0.1333376549999982 0.1080597880000012 -0.0142129800000009 0.1361945939999982 0.0995276800000012 -0.0180050280000009 0.1409561589999982 0.0947876200000012 -0.0199010520000009 0.1380992199999982 0.1033197280000012 -0.0217970760000009 0.1419084719999982 0.1042677400000012 -0.0208490640000009 0.1495269759999982 0.1023717160000012 -0.0236931000000009 0.1447654109999982 0.1061637640000012 -0.0217970760000009 0.1380992199999982 0.1109038240000012 -0.0180050280000009 0.1295284029999982 0.1109038240000012 -0.0199010520000009 0.1304807159999982 0.1099558120000012 -0.0180050280000009 0.1409561589999982 0.1118518360000012 -0.0151609920000009 0.1447654109999982 0.1080597880000012 -0.0113689440000009 0.1400038459999982 0.1071117760000012 -0.009472920000000903 0.1390515329999982 0.1118518360000012 -0.0170570160000009 0.1438130979999982 0.1090078000000012 -0.0189530400000009 0.1390515329999982 0.1090078000000012 -0.0170570160000009 0.1323853419999982 0.1099558120000012 -0.0170570160000009 0.1390515329999982 0.1023717160000012 -0.0151609920000009 0.1485746629999982 0.1004756920000012 -0.0123169560000009 0.1419084719999982 0.1033197280000012 -0.0113689440000009 0.1304807159999982 0.1080597880000012 -0.0274851480000009 0.1314330289999982 0.1023717160000012 -0.0312771960000009 0.1304807159999982 0.1014237040000012 -0.0274851480000009 0.1352422809999982 0.1099558120000012 -0.0265371360000009 0.1447654109999982 0.1052157520000012 -0.0189530400000009 0.1390515329999982 0.1014237040000012 -0.02274508800000091 0.1390515329999982 0.1052157520000012 -0.01610900400000091 0.1428607849999982 0.1127998480000012 -0.003784848000000902 0.1419084719999982 0.1118518360000012 -0.008524908000000903 0.1409561589999982 0.1090078000000012 -0.008524908000000903 0.1428607849999982 0.1137478600000012 0.003799247999999096 0.1409561589999982 0.1109038240000012 -0.003784848000000902 0.1285760899999982 0.1146958720000012 -0.0170570160000009 0.1276237769999982 0.1099558120000012 -0.0180050280000009 0.1419084719999982 0.09668364400000119 -0.0151609920000009 0.1380992199999982 0.0928915960000012 -0.0199010520000009 0.1314330289999982 0.0881515360000012 -0.0189530400000009 0.1314330289999982 0.09573563200000119 -0.01610900400000091 0.1333376549999982 0.1109038240000012 -0.0274851480000009 0.1371469069999982 0.1033197280000012 -0.0303291840000009 0.1390515329999982 0.1014237040000012 -0.0208490640000009 0.1380992199999982 0.1080597880000012 -0.0123169560000009 0.1352422809999982 0.1023717160000012 -0.0123169560000009 0.1457177239999982 0.1014237040000012 -0.0123169560000009 0.1523839149999982 0.1033197280000012 -0.0104209320000009 0.1457177239999982 0.1033197280000012 -0.0142129800000009 0.1476223499999982 0.1061637640000012 -0.0113689440000009 0.1419084719999982 0.1090078000000012 -0.008524908000000903 0.1438130979999982 0.1156438840000012 -0.006628884000000904 0.1533362279999982 0.1156438840000012 -0.004732860000000904 0.1447654109999982 0.1099558120000012 -0.009472920000000903 0.1390515329999982 0.1004756920000012 -0.0151609920000009 0.1371469069999982 0.09763165600000119 -0.0170570160000009 0.1276237769999982 0.1023717160000012 -0.0180050280000009 0.1190529599999982 0.1004756920000012 -0.0189530400000009 0.1219098989999982 0.1052157520000012 -0.01610900400000091 0.1295284029999982 0.1023717160000012 -0.0180050280000009 0.1438130979999982 0.1080597880000012 -0.0199010520000009 0.1457177239999982 0.1137478600000012 -0.02274508800000091 0.1409561589999982 0.1023717160000012 -0.0199010520000009 0.1400038459999982 0.0995276800000012 -0.0170570160000009 0.1361945939999982 0.1080597880000012 -0.0189530400000009 0.1400038459999982 0.1099558120000012 -0.0142129800000009 0.1380992199999982 0.1061637640000012 -0.009472920000000903 0.1352422809999982 0.1071117760000012 -0.008524908000000903 0.1380992199999982 0.1146958720000012 -0.0151609920000009 0.1333376549999982 0.1194359320000012 -0.0142129800000009 0.1295284029999982 0.1175399080000012 -0.0104209320000009 0.1352422809999982 0.1080597880000012 -0.0170570160000009 0.1419084719999982 0.09573563200000119 -0.02274508800000091 0.1380992199999982 0.0947876200000012 -0.0255891240000009 0.1400038459999982 0.1014237040000012 -0.0180050280000009 0.1380992199999982 0.1014237040000012 -0.0151609920000009 0.1361945939999982 0.1109038240000012 -0.0284331600000009 0.1447654109999982 0.1137478600000012 -0.0274851480000009 0.1485746629999982 0.1137478600000012 -0.0236931000000009 0.1457177239999982 0.1175399080000012 -0.0236931000000009 0.1476223499999982 0.1175399080000012 -0.0142129800000009 0.1457177239999982 0.1061637640000012 -0.009472920000000903 0.1380992199999982 0.0995276800000012 -0.0123169560000009 0.1428607849999982 0.1146958720000012 -0.006628884000000904 0.1466700369999982 0.1203839440000012 -0.005680872000000904 0.1419084719999982 0.1090078000000012 -0.008524908000000903 0.1295284029999982 0.1052157520000012 -0.0104209320000009 0.1323853419999982 0.1080597880000012 -0.0132649680000009 0.1457177239999982 0.1052157520000012 -0.0142129800000009 0.1342899679999982 0.1061637640000012 -0.0208490640000009 0.1352422809999982 0.1080597880000012 -0.0284331600000009 0.1457177239999982 0.1061637640000012 -0.0246411120000009 0.1409561589999982 0.1033197280000012 -0.0246411120000009 0.1485746629999982 0.1033197280000012 -0.02938117200000091 0.1571454799999982 0.1090078000000012 -0.0341212320000009 0.1466700369999982 0.1127998480000012 -0.03317322000000091 0.1419084719999982 0.1090078000000012 -0.0265371360000009 0.1447654109999982 0.1071117760000012 -0.0199010520000009 0.1485746629999982 0.1014237040000012 -0.0113689440000009 0.1457177239999982 0.1061637640000012 -0.002836836000000903 0.1380992199999982 0.1184879200000012 -0.001888824000000903 0.1352422809999982 0.1080597880000012 -0.0132649680000009 0.1352422809999982 0.0995276800000012 -0.0199010520000009 0.1457177239999982 0.1175399080000012 -0.0189530400000009 0.1409561589999982 0.1194359320000012 -0.0170570160000009 0.1295284029999982 0.1014237040000012 -0.0142129800000009 0.1285760899999982 0.1080597880000012 -0.0123169560000009 0.1333376549999982 0.1165918960000012 -0.0151609920000009 0.1371469069999982 0.1127998480000012 -0.0217970760000009 0.1323853419999982 0.1052157520000012 -0.0208490640000009 0.1247668379999982 0.1004756920000012 -0.0217970760000009 0.1247668379999982 0.1033197280000012 -0.0284331600000009 0.1342899679999982 0.1023717160000012 -0.0255891240000009 0.1380992199999982 0.1042677400000012 -0.02274508800000091 0.1428607849999982 0.1033197280000012 -0.0246411120000009 0.1428607849999982 0.1004756920000012 -0.0255891240000009 0.1428607849999982 0.1014237040000012 -0.0208490640000009 0.1495269759999982 0.1033197280000012 -0.0199010520000009 0.1476223499999982 0.1127998480000012 -0.0246411120000009 0.1400038459999982 0.1203839440000012 -0.0255891240000009 0.1409561589999982 0.1175399080000012 -0.0151609920000009 0.1495269759999982 0.1061637640000012 -0.008524908000000903 0.1476223499999982 0.1042677400000012 -0.009472920000000903 0.1447654109999982 0.1052157520000012 -0.0142129800000009 0.1504792889999982 0.1014237040000012 -0.0142129800000009 0.1485746629999982 0.1023717160000012 -0.01610900400000091 0.1390515329999982 0.1052157520000012 -0.0236931000000009 0.1390515329999982 0.1080597880000012 -0.0312771960000009 0.1447654109999982 0.1109038240000012 -0.0255891240000009 0.1400038459999982 0.1137478600000012 -0.0246411120000009 0.1466700369999982 0.1146958720000012 -0.03222520800000091 0.1466700369999982 0.1241759920000012 -0.0236931000000009 0.1361945939999982 0.1165918960000012 -0.01610900400000091 0.1409561589999982 0.1061637640000012 -0.0123169560000009 0.1438130979999982 0.1109038240000012 -0.0170570160000009 0.1485746629999982 0.1156438840000012 -0.0199010520000009 0.1447654109999982 0.1194359320000012 -0.009472920000000903 0.1371469069999982 0.1175399080000012 -0.0113689440000009 0.1466700369999982 0.1222799680000012 -0.0180050280000009 0.1466700369999982 0.1203839440000012 -0.0199010520000009 0.1323853419999982 0.1109038240000012 -0.0113689440000009 0.1295284029999982 0.1118518360000012 -0.0142129800000009 0.1380992199999982 0.1146958720000012 -0.0246411120000009 0.1361945939999982 0.1023717160000012 -0.02274508800000091 0.1390515329999982 0.1004756920000012 -0.0265371360000009 0.1523839149999982 0.1061637640000012 -0.0303291840000009 0.1438130979999982 0.1052157520000012 -0.0303291840000009 0.1333376549999982 0.1080597880000012 -0.03601725600000091 0.1390515329999982 0.1137478600000012 -0.0265371360000009 0.1323853419999982 0.1071117760000012 -0.0132649680000009 0.1400038459999982 0.1080597880000012 -0.0142129800000009 0.1476223499999982 0.1127998480000012 -0.008524908000000903 0.1447654109999982 0.1090078000000012 -0.007576896000000903 0.1447654109999982 0.1127998480000012 -0.0123169560000009 0.1438130979999982 0.1175399080000012 -0.0180050280000009 0.1476223499999982 0.1175399080000012 -0.0199010520000009 0.1466700369999982 0.1080597880000012 -0.0170570160000009 0.1447654109999982 0.09763165600000119 -0.0189530400000009 0.1409561589999982 0.1099558120000012 -0.0236931000000009 0.1400038459999982 0.1146958720000012 -0.0208490640000009 0.1419084719999982 0.1052157520000012 -0.0151609920000009 0.1361945939999982 0.1061637640000012 -0.0180050280000009 0.1380992199999982 0.1137478600000012 -0.02274508800000091 0.1457177239999982 0.1127998480000012 -0.0255891240000009 0.1438130979999982 0.1052157520000012 -0.0341212320000009 0.1371469069999982 0.1099558120000012 -0.0341212320000009 0.1333376549999982 0.1156438840000012 -0.0246411120000009 0.1400038459999982 0.1071117760000012 -0.0217970760000009 0.1419084719999982 0.1052157520000012 -0.0170570160000009 0.1466700369999982 0.1137478600000012 -0.0151609920000009 0.1533362279999982 0.1213319560000012 -0.0142129800000009 0.1476223499999982 0.1213319560000012 -0.0123169560000009 0.1523839149999982 0.1146958720000012 -0.0151609920000009 0.1561931669999982 0.1146958720000012 -0.0236931000000009 0.1476223499999982 0.1099558120000012 -0.0189530400000009 0.1428607849999982 0.1042677400000012 -0.0170570160000009 0.1371469069999982 0.1099558120000012 -0.02274508800000091 0.1333376549999982 0.1184879200000012 -0.0265371360000009 0.1304807159999982 0.1118518360000012 -0.02274508800000091 0.1276237769999982 0.1061637640000012 -0.01610900400000091 0.1266714639999982 0.1033197280000012 -0.0246411120000009 0.1314330289999982 0.1004756920000012 -0.02274508800000091 0.1400038459999982 0.0995276800000012 -0.0255891240000009 0.1438130979999982 0.0985796680000012 -0.0274851480000009 0.1447654109999982 0.1080597880000012 -0.0265371360000009 0.1514316019999982 0.1118518360000012 -0.02274508800000091 0.1447654109999982 0.1090078000000012 -0.0217970760000009 0.1380992199999982 0.1146958720000012 -0.0151609920000009 0.1457177239999982 0.1175399080000012 -0.0132649680000009 0.1485746629999982 0.1146958720000012 -0.0142129800000009 0.1580977929999982 0.1146958720000012 -0.0132649680000009 0.1552408539999982 0.1165918960000012 -0.0189530400000009 0.1428607849999982 0.1175399080000012 -0.0123169560000009 0.1342899679999982 0.1137478600000012 -0.0132649680000009 0.1361945939999982 0.1099558120000012 -0.0217970760000009 0.1400038459999982 0.1137478600000012 -0.0189530400000009 0.1457177239999982 0.1071117760000012 -0.0199010520000009 0.1457177239999982 0.1042677400000012 -0.0246411120000009 0.1380992199999982 0.1090078000000012 -0.0312771960000009 0.1476223499999982 0.1099558120000012 -0.0369652680000009 0.1580977929999982 0.1109038240000012 -0.0246411120000009 0.1485746629999982 0.1118518360000012 -0.0142129800000009 0.1323853419999982 0.1080597880000012 -0.02274508800000091 0.1390515329999982 0.1052157520000012 -0.0208490640000009 0.1466700369999982 0.1052157520000012 -0.0123169560000009 0.1476223499999982 0.1052157520000012 -0.0217970760000009 0.1428607849999982 0.1127998480000012 -0.0180050280000009 0.1409561589999982 0.1127998480000012 -0.0104209320000009 0.1466700369999982 0.1080597880000012 -0.0142129800000009 0.1466700369999982 0.1137478600000012 -0.008524908000000903 0.1476223499999982 0.1118518360000012 -0.0113689440000009 0.1438130979999982 0.1080597880000012 -0.0123169560000009 0.1380992199999982 0.1118518360000012 -0.0170570160000009 0.1390515329999982 0.1014237040000012 -0.0217970760000009 0.1380992199999982 0.09763165600000119 -0.0217970760000009 0.1409561589999982 0.1052157520000012 -0.0151609920000009 0.1457177239999982 0.1090078000000012 -0.01610900400000091 0.1485746629999982 0.1052157520000012 -0.0199010520000009 0.1495269759999982 0.1023717160000012 -0.0104209320000009 0.1485746629999982 0.0995276800000012 -0.0104209320000009 0.1361945939999982 0.1042677400000012 -0.009472920000000903 0.1419084719999982 0.1118518360000012 -0.009472920000000903 0.1466700369999982 0.1061637640000012 -0.001888824000000903 0.1409561589999982 0.1127998480000012 0.002851235999999096 0.1428607849999982 0.1194359320000012 -0.005680872000000904 0.1438130979999982 0.1137478600000012 -0.0170570160000009 0.1495269759999982 0.1099558120000012 -0.0217970760000009 0.1542885409999982 0.1033197280000012 -0.0170570160000009 0.1390515329999982 0.0985796680000012 -0.0132649680000009 0.1323853419999982 0.1004756920000012 -0.0123169560000009 0.1419084719999982 0.1014237040000012 -0.0208490640000009 0.1466700369999982 0.1014237040000012 -0.0274851480000009 0.1466700369999982 0.0985796680000012 -0.0255891240000009 0.1438130979999982 0.1033197280000012 -0.0208490640000009 0.1419084719999982 0.1071117760000012 -0.0132649680000009 0.1400038459999982 0.1071117760000012 -0.0113689440000009 0.1419084719999982 0.1080597880000012 -0.0113689440000009 0.1447654109999982 0.1052157520000012 -0.006628884000000904 0.1352422809999982 0.1052157520000012 -0.004732860000000904 0.1314330289999982 0.1127998480000012 -0.009472920000000903 0.1400038459999982 0.1033197280000012 -0.009472920000000903 0.1400038459999982 0.09668364400000119 -0.009472920000000903 0.1419084719999982 0.1127998480000012 -0.0123169560000009 0.1495269759999982 0.1156438840000012 -0.0151609920000009 0.1466700369999982 0.1071117760000012 -0.0189530400000009 0.1419084719999982 0.0938396080000012 -0.0142129800000009 0.1438130979999982 0.0985796680000012 -0.01610900400000091 0.1438130979999982 0.1080597880000012 -0.0217970760000009 0.1466700369999982 0.1004756920000012 -0.0208490640000009 0.1504792889999982 0.0985796680000012 -0.0265371360000009 0.1447654109999982 0.1052157520000012 -0.0265371360000009 0.1371469069999982 0.1052157520000012 -0.0265371360000009 0.1419084719999982 0.1033197280000012 -0.0284331600000009 0.1438130979999982 0.1090078000000012 -0.02274508800000091 0.1428607849999982 0.1118518360000012 -0.0142129800000009 0.1504792889999982 0.1052157520000012 -0.0151609920000009 0.1447654109999982 0.09668364400000119 -0.0151609920000009 0.1419084719999982 0.09573563200000119 -0.003784848000000902 0.1457177239999982 0.1071117760000012 -0.001888824000000903 0.1466700369999982 0.1137478600000012 -0.0104209320000009 0.1523839149999982 0.1071117760000012 -0.009472920000000903 0.1476223499999982 0.09668364400000119 -0.009472920000000903 0.1390515329999982 0.08909954800000119 -0.009472920000000903 0.1380992199999982 0.09099557200000119 -0.000940812000000903 0.1409561589999982 0.0947876200000012 -0.005680872000000904 0.1447654109999982 0.1014237040000012 -0.0208490640000009 0.1400038459999982 0.1099558120000012 -0.03222520800000091 0.1361945939999982 0.1090078000000012 -0.0284331600000009 0.1466700369999982 0.1033197280000012 -0.0236931000000009 0.1561931669999982 0.1061637640000012 -0.0199010520000009 0.1542885409999982 0.0995276800000012 -0.0142129800000009 0.1457177239999982 0.0928915960000012 -0.005680872000000904 0.1380992199999982 0.0928915960000012 -0.002836836000000903 0.1361945939999982 0.0938396080000012 -0.009472920000000903 0.1419084719999982 0.1014237040000012 -0.009472920000000903 0.1485746629999982 0.1109038240000012 -0.007576896000000903 0.1485746629999982 0.1080597880000012 -0.006628884000000904 0.1438130979999982 0.1014237040000012 -0.006628884000000904 0.1361945939999982 0.1071117760000012 -0.0151609920000009 0.1323853419999982 0.1052157520000012 -0.0170570160000009 0.1390515329999982 0.0985796680000012 -0.0123169560000009 0.1476223499999982 0.09573563200000119 -0.0151609920000009 0.1400038459999982 0.0985796680000012 -0.0123169560000009 0.1285760899999982 0.1004756920000012 -0.0208490640000009 0.1380992199999982 0.09573563200000119 -0.0284331600000009 0.1523839149999982 0.0985796680000012 -0.02274508800000091 0.1485746629999982 0.1118518360000012 -0.0217970760000009 0.1476223499999982 0.1156438840000012 -0.0180050280000009 0.1523839149999982 0.1109038240000012 -0.0113689440000009 0.1447654109999982 0.1023717160000012 -0.008524908000000903 0.1419084719999982 0.09668364400000119 -0.0151609920000009 0.1438130979999982 0.1052157520000012 -0.009472920000000903 0.1457177239999982 0.1099558120000012 -0.006628884000000904 0.1438130979999982 0.1090078000000012 -0.008524908000000903 0.1419084719999982 0.1137478600000012 -0.008524908000000903 0.1447654109999982 0.1146958720000012 -0.008524908000000903 0.1504792889999982 0.1118518360000012 -0.008524908000000903 0.1542885409999982 0.1071117760000012 -0.0180050280000009 0.1466700369999982 0.1023717160000012 -0.01610900400000091 0.1457177239999982 0.1080597880000012 -0.0189530400000009 0.1447654109999982 0.09668364400000119 -0.0246411120000009 0.1409561589999982 0.08909954800000119 -0.0208490640000009 0.1438130979999982 0.1071117760000012 -0.02274508800000091 0.1476223499999982 0.1109038240000012 -0.0255891240000009 0.1466700369999982 0.1080597880000012 -0.0208490640000009 0.1390515329999982 0.1099558120000012 -0.0236931000000009 0.1400038459999982 0.1052157520000012 -0.0255891240000009 0.1428607849999982 0.1033197280000012 -0.0170570160000009 0.1438130979999982 0.1004756920000012 -0.01610900400000091 0.1438130979999982 0.1042677400000012 -0.0142129800000009 0.1428607849999982 0.1071117760000012 -0.0104209320000009 0.1457177239999982 0.0985796680000012 -0.009472920000000903 0.1447654109999982 0.1042677400000012 -0.000940812000000903 0.1428607849999982 0.1203839440000012 -0.001888824000000903 0.1447654109999982 0.1146958720000012 -0.0113689440000009 0.1409561589999982 0.1090078000000012 -0.0113689440000009 0.1380992199999982 0.1118518360000012 -0.0123169560000009 0.1371469069999982 0.1052157520000012 -0.0142129800000009 0.1419084719999982 0.1014237040000012 -0.0180050280000009 0.1504792889999982 0.1042677400000012 -0.0217970760000009 0.1523839149999982 0.1014237040000012 -0.0217970760000009 0.1447654109999982 0.0995276800000012 -0.0236931000000009 0.1380992199999982 0.1023717160000012 -0.0303291840000009 0.1409561589999982 0.09668364400000119 -0.03222520800000091 0.1514316019999982 0.1014237040000012 -0.0265371360000009 0.1485746629999982 0.1109038240000012 -0.0189530400000009 0.1457177239999982 0.1099558120000012 -0.0113689440000009 0.1457177239999982 0.1080597880000012 -0.006628884000000904 0.1533362279999982 0.1071117760000012 -0.0123169560000009 0.1571454799999982 0.1052157520000012 -0.0170570160000009 0.1590501059999982 0.1099558120000012 -0.0123169560000009 0.1580977929999982 0.1090078000000012 -0.0132649680000009 0.1485746629999982 0.1061637640000012 -0.0151609920000009 0.1438130979999982 0.1071117760000012 -0.0113689440000009 0.1333376549999982 0.1042677400000012 -0.0113689440000009 0.1342899679999982 0.1023717160000012 -0.0274851480000009 0.1371469069999982 0.09763165600000119 -0.0350692440000009 0.1352422809999982 0.0995276800000012 -0.0208490640000009 0.1285760899999982 0.1061637640000012 -0.0142129800000009 0.1314330289999982 0.1023717160000012 -0.0180050280000009 0.1419084719999982 0.1014237040000012 -0.01610900400000091 0.1409561589999982 0.1033197280000012 -0.0170570160000009 0.1352422809999982 0.1109038240000012 -0.0208490640000009 0.1457177239999982 0.1080597880000012 -0.0142129800000009 0.1590501059999982 0.1004756920000012 -0.0104209320000009 0.1466700369999982 0.1071117760000012 -0.0151609920000009 0.1428607849999982 0.1127998480000012 -0.008524908000000903 0.1533362279999982 0.1146958720000012 0.0009552119999990966 0.1466700369999982 0.1080597880000012 -0.004732860000000904 0.1380992199999982 0.1109038240000012 -0.003784848000000902 0.1304807159999982 0.1194359320000012 -0.003784848000000902 0.1409561589999982 0.1156438840000012 -0.0104209320000009 0.1533362279999982 0.1099558120000012 -0.0132649680000009 0.1542885409999982 0.1090078000000012 -0.0217970760000009 0.1561931669999982 0.1061637640000012 -0.0246411120000009 0.1514316019999982 0.1090078000000012 -0.0199010520000009 0.1409561589999982 0.1090078000000012 -0.0189530400000009 0.1428607849999982 0.1071117760000012 -0.0284331600000009 0.1504792889999982 0.1090078000000012 -0.0312771960000009 0.1409561589999982 0.1023717160000012 -0.0217970760000009 0.1361945939999982 0.0985796680000012 -0.0208490640000009 0.1419084719999982 0.1042677400000012 -0.02274508800000091 0.1428607849999982 0.1090078000000012 -0.0265371360000009 0.1438130979999982 0.1109038240000012 -0.02274508800000091 0.1419084719999982 0.1052157520000012 -0.0132649680000009 0.1400038459999982 0.09194358400000119 -0.0151609920000009 0.1380992199999982 0.0928915960000012 -0.0123169560000009 0.1476223499999982 0.1033197280000012 -0.009472920000000903 0.1485746629999982 0.1127998480000012 0.003799247999999096 0.1457177239999982 0.1118518360000012 0.003799247999999096 0.1514316019999982 0.1033197280000012 -0.003784848000000902 0.1523839149999982 0.1071117760000012 -0.006628884000000904 0.1571454799999982 0.09573563200000119 -0.0132649680000009 0.1476223499999982 0.0862555120000012 -0.01610900400000091 0.1390515329999982 0.09763165600000119 -0.0236931000000009 0.1476223499999982 0.1014237040000012 -0.008524908000000903 0.1466700369999982 0.1109038240000012 -0.006628884000000904 0.1447654109999982 0.1241759920000012 -0.009472920000000903 0.1466700369999982 0.1175399080000012 -0.008524908000000903 0.1466700369999982 0.1127998480000012 -0.002836836000000903 0.1447654109999982 0.1156438840000012 -0.0104209320000009 0.1361945939999982 0.1090078000000012 -0.0217970760000009 0.1342899679999982 0.09763165600000119 -0.0199010520000009 0.1438130979999982 0.09668364400000119 -0.0104209320000009 0.1390515329999982 0.0938396080000012 -0.004732860000000904 0.1390515329999982 0.0985796680000012 -0.0180050280000009 0.1438130979999982 0.1109038240000012 -0.0236931000000009 0.1466700369999982 0.1127998480000012 -0.0199010520000009 0.1390515329999982 0.1109038240000012 -0.0199010520000009 0.1342899679999982 0.1127998480000012 -0.02274508800000091 0.1409561589999982 0.1118518360000012 -0.0255891240000009 0.1523839149999982 0.1090078000000012 -0.0199010520000009 0.1590501059999982 0.1033197280000012 -0.0199010520000009 0.1504792889999982 0.0995276800000012 -0.0170570160000009 0.1447654109999982 0.1090078000000012 -0.0104209320000009 0.1523839149999982 0.1061637640000012 -0.009472920000000903 0.1542885409999982 0.09668364400000119 -0.002836836000000903 0.1476223499999982 0.09668364400000119 0.001903223999999096 0.1514316019999982 0.1061637640000012 0.0009552119999990966 0.1533362279999982 0.1090078000000012 -0.007576896000000903 0.1457177239999982 0.1014237040000012 -0.0151609920000009 0.1438130979999982 0.09668364400000119 -0.0180050280000009 0.1438130979999982 0.0985796680000012 -0.0151609920000009 0.1428607849999982 0.1014237040000012 -0.0142129800000009 0.1447654109999982 0.0995276800000012 -0.0217970760000009 0.1361945939999982 0.1080597880000012 -0.0255891240000009 0.1438130979999982 0.1080597880000012 -0.02938117200000091 0.1485746629999982 0.09763165600000119 -0.0284331600000009 0.1380992199999982 0.0985796680000012 -0.0236931000000009 0.1380992199999982 0.1071117760000012 -0.0170570160000009 0.1476223499999982 0.1033197280000012 -0.008524908000000903 0.1561931669999982 0.1014237040000012 -0.0104209320000009 0.1561931669999982 0.1033197280000012 -0.002836836000000903 0.1552408539999982 0.1023717160000012 -0.002836836000000903 0.1533362279999982 0.09668364400000119 -0.006628884000000904 0.1457177239999982 0.1023717160000012 -0.007576896000000903 0.1438130979999982 0.1080597880000012 -0.0113689440000009 0.1476223499999982 0.0947876200000012 -0.0151609920000009 0.1438130979999982 0.09194358400000119 -0.0180050280000009 0.1476223499999982 0.09763165600000119 -0.0132649680000009 0.1533362279999982 0.0995276800000012 -0.0104209320000009 0.1504792889999982 0.0947876200000012 -0.0113689440000009 0.1400038459999982 0.0985796680000012 -0.0113689440000009 0.1333376549999982 0.0995276800000012 -0.01610900400000091 0.1352422809999982 0.0985796680000012 -0.0265371360000009 0.1352422809999982 0.1042677400000012 -0.01610900400000091 0.1438130979999982 0.1014237040000012 -0.006628884000000904 0.1428607849999982 0.0938396080000012 -0.0151609920000009 0.1419084719999982 0.1014237040000012 -0.0123169560000009 0.1533362279999982 0.1071117760000012 0.002851235999999096 0.1476223499999982 0.1052157520000012 0.002851235999999096 0.1390515329999982 0.1090078000000012 -0.003784848000000902 0.1438130979999982 0.1080597880000012 -0.006628884000000904 0.1457177239999982 0.1090078000000012 -0.007576896000000903 0.1419084719999982 0.1071117760000012 -0.0123169560000009 0.1419084719999982 0.1033197280000012 -0.0142129800000009 0.1457177239999982 0.1004756920000012 -0.006628884000000904 0.1552408539999982 0.09573563200000119 -0.0170570160000009 0.1514316019999982 0.1004756920000012 -0.0246411120000009 0.1428607849999982 0.1061637640000012 -0.01610900400000091 0.1438130979999982 0.1052157520000012 -0.0170570160000009 0.1466700369999982 0.0985796680000012 -0.0199010520000009 0.1523839149999982 0.09668364400000119 -0.0274851480000009 0.1514316019999982 0.1061637640000012 -0.0265371360000009 0.1504792889999982 0.1033197280000012 -0.0113689440000009 0.1457177239999982 0.1004756920000012 -0.0123169560000009 0.1485746629999982 0.1004756920000012 -0.006628884000000904 0.1571454799999982 0.1023717160000012 -0.001888824000000903 0.1447654109999982 0.1061637640000012 -0.008524908000000903 0.1438130979999982 0.1071117760000012 -0.005680872000000904 0.1514316019999982 0.1137478600000012 -0.007576896000000903 0.1476223499999982 0.1061637640000012 -0.0170570160000009 0.1447654109999982 0.0947876200000012 -0.0142129800000009 0.1380992199999982 0.0928915960000012 -0.008524908000000903 0.1409561589999982 0.09573563200000119 -0.0123169560000009 0.1504792889999982 0.09004756000000119 -0.0104209320000009 0.1485746629999982 0.09194358400000119 -0.0104209320000009 0.1390515329999982 0.1014237040000012 -0.0199010520000009 0.1371469069999982 0.09763165600000119 -0.0236931000000009 0.1419084719999982 0.1014237040000012 -0.0217970760000009 0.1552408539999982 0.1033197280000012 -0.0189530400000009 0.1600024189999982 0.1071117760000012 -0.0208490640000009 0.1447654109999982 0.1109038240000012 -0.0208490640000009 0.1371469069999982 0.1071117760000012 -0.01610900400000091 0.1533362279999982 0.1042677400000012 -0.01610900400000091 0.1523839149999982 0.1061637640000012 -0.0123169560000009 0.1371469069999982 0.1090078000000012 -0.0132649680000009 0.1419084719999982 0.1042677400000012 -0.01610900400000091 0.1476223499999982 0.1090078000000012 -0.0189530400000009 0.1514316019999982 0.1156438840000012 -0.0208490640000009 0.1466700369999982 0.1099558120000012 -0.0123169560000009 0.1380992199999982 0.1033197280000012 -0.0142129800000009 0.1409561589999982 0.1033197280000012 -0.0180050280000009 0.1485746629999982 0.1080597880000012 -0.0123169560000009 0.1457177239999982 0.1146958720000012 -0.0170570160000009 0.1380992199999982 0.1137478600000012 -0.0265371360000009 0.1390515329999982 0.1014237040000012 -0.0246411120000009 0.1428607849999982 0.0995276800000012 -0.0189530400000009 0.1438130979999982 0.1033197280000012 -0.0123169560000009 0.1390515329999982 0.1061637640000012 -0.0123169560000009 0.1428607849999982 0.1109038240000012 -0.0123169560000009 0.1533362279999982 0.1127998480000012 -0.008524908000000903 0.1628593579999982 0.1156438840000012 -0.0123169560000009 0.1600024189999982 0.1118518360000012 -0.0142129800000009 0.1447654109999982 0.1099558120000012 -0.01610900400000091 0.1419084719999982 0.1090078000000012 -0.0113689440000009 0.1533362279999982 0.0985796680000012 -0.0113689440000009 0.1485746629999982 0.0995276800000012 -0.0180050280000009 0.1333376549999982 0.1052157520000012 -0.01610900400000091 0.1438130979999982 0.1071117760000012 -0.0217970760000009 0.1457177239999982 0.1118518360000012 -0.0132649680000009 0.1514316019999982 0.1023717160000012 -0.002836836000000903 0.1466700369999982 0.0995276800000012 -0.003784848000000902 0.1438130979999982 0.1118518360000012 -0.0113689440000009 0.1390515329999982 0.1165918960000012 -0.0180050280000009 0.1428607849999982 0.1175399080000012 -0.0151609920000009 0.1457177239999982 0.1033197280000012 -0.0170570160000009 0.1438130979999982 0.0928915960000012 -0.0236931000000009 0.1409561589999982 0.1042677400000012 -0.0170570160000009 0.1438130979999982 0.1061637640000012 -0.0113689440000009 0.1476223499999982 0.1014237040000012 -0.0189530400000009 0.1390515329999982 0.09763165600000119 -0.02938117200000091 0.1361945939999982 0.1014237040000012 -0.0246411120000009 0.1457177239999982 0.1071117760000012 -0.01610900400000091 0.1485746629999982 0.1118518360000012 -0.0151609920000009 0.1457177239999982 0.1127998480000012 -0.007576896000000903 0.1495269759999982 0.1042677400000012 -0.009472920000000903 0.1495269759999982 0.1052157520000012 -0.0142129800000009 0.1523839149999982 0.1156438840000012 -0.01610900400000091 0.1533362279999982 0.1118518360000012 -0.0113689440000009 0.1571454799999982 0.1080597880000012 -0.006628884000000904 0.1523839149999982 0.1156438840000012 -0.0132649680000009 0.1438130979999982 0.1194359320000012 -0.0217970760000009 0.1438130979999982 0.1194359320000012 -0.0208490640000009 0.1457177239999982 0.1203839440000012 -0.009472920000000903 0.1438130979999982 0.1080597880000012 -0.0170570160000009 0.1457177239999982 0.1080597880000012 -0.0199010520000009 0.1523839149999982 0.0985796680000012 -0.0217970760000009 0.1495269759999982 0.0985796680000012 -0.0265371360000009 0.1476223499999982 0.1033197280000012 -0.0208490640000009 0.1419084719999982 0.1052157520000012 -0.0170570160000009 0.1523839149999982 0.1042677400000012 -0.007576896000000903 0.1590501059999982 0.1052157520000012 -0.009472920000000903 0.1580977929999982 0.1052157520000012 -0.01610900400000091 0.1447654109999982 0.1004756920000012 -0.0217970760000009 0.1342899679999982 0.1118518360000012 -0.0265371360000009 0.1428607849999982 0.1222799680000012 -0.0208490640000009 0.1438130979999982 0.1109038240000012 -0.02274508800000091 0.1466700369999982 0.09573563200000119 -0.0274851480000009 0.1476223499999982 0.09668364400000119 -0.0199010520000009 0.1352422809999982 0.1071117760000012 -0.0123169560000009 0.1361945939999982 0.1099558120000012 -0.0170570160000009 0.1476223499999982 0.1071117760000012 -0.0180050280000009 0.1542885409999982 0.1118518360000012 -0.005680872000000904 0.1514316019999982 0.1146958720000012 -0.006628884000000904 0.1428607849999982 0.1099558120000012 -0.0170570160000009 0.1371469069999982 0.1118518360000012 -0.0132649680000009 0.1400038459999982 0.1137478600000012 -0.006628884000000904 0.1523839149999982 0.1109038240000012 -0.0151609920000009 0.1542885409999982 0.1061637640000012 -0.0142129800000009 0.1466700369999982 0.1004756920000012 -0.0113689440000009 0.1428607849999982 0.1023717160000012 -0.0132649680000009 0.1419084719999982 0.09763165600000119 -0.0132649680000009 0.1419084719999982 0.1042677400000012 -0.0217970760000009 0.1457177239999982 0.1090078000000012 -0.02938117200000091 0.1466700369999982 0.1052157520000012 -0.02938117200000091 0.1552408539999982 0.1127998480000012 -0.0303291840000009 0.1600024189999982 0.1109038240000012 -0.0255891240000009 0.1495269759999982 0.0985796680000012 -0.0189530400000009 0.1428607849999982 0.0947876200000012 -0.0170570160000009 0.1485746629999982 0.1004756920000012 -0.0132649680000009 0.1476223499999982 0.1023717160000012 -0.0132649680000009 0.1400038459999982 0.1033197280000012 -0.0151609920000009 0.1400038459999982 0.1061637640000012 -0.01610900400000091 0.1447654109999982 0.1071117760000012 -0.008524908000000903 0.1552408539999982 0.1080597880000012 -0.002836836000000903 0.1523839149999982 0.1033197280000012 -0.0104209320000009 0.1419084719999982 0.0995276800000012 -0.0151609920000009 0.1333376549999982 0.1014237040000012 -0.0265371360000009 0.1390515329999982 0.0947876200000012 -0.0246411120000009 0.1438130979999982 0.0928915960000012 -0.0180050280000009 0.1409561589999982 0.1023717160000012 -0.0284331600000009 0.1380992199999982 0.1080597880000012 -0.03222520800000091 0.1285760899999982 0.1118518360000012 -0.0303291840000009 0.1314330289999982 0.1118518360000012 -0.0217970760000009 0.1447654109999982 0.0985796680000012 -0.0180050280000009 0.1495269759999982 0.1042677400000012 -0.0189530400000009 0.1514316019999982 0.1137478600000012 -0.01610900400000091 0.1542885409999982 0.1071117760000012 -0.0104209320000009 0.1552408539999982 0.1014237040000012 -0.008524908000000903 0.1504792889999982 0.1080597880000012 -0.008524908000000903 0.1552408539999982 0.1127998480000012 -0.006628884000000904 0.1590501059999982 0.1061637640000012 -0.009472920000000903 0.1523839149999982 0.1052157520000012 -0.006628884000000904 0.1552408539999982 0.1071117760000012 -0.005680872000000904 0.1561931669999982 0.1090078000000012 -0.0170570160000009 0.1457177239999982 0.1004756920000012 -0.0189530400000009 0.1409561589999982 0.09099557200000119 -0.01610900400000091 0.1409561589999982 0.09573563200000119 -0.0236931000000009 0.1428607849999982 0.1080597880000012 -0.0246411120000009 0.1419084719999982 0.1118518360000012 -0.0180050280000009 0.1352422809999982 0.1156438840000012 -0.0180050280000009 0.1419084719999982 0.1175399080000012 -0.0236931000000009 0.1561931669999982 0.1071117760000012 -0.02274508800000091 0.1580977929999982 0.09099557200000119 -0.0180050280000009 0.1533362279999982 0.0928915960000012 -0.007576896000000903 0.1476223499999982 0.1090078000000012 -0.001888824000000903 0.1457177239999982 0.1146958720000012 -0.000940812000000903 0.1438130979999982 0.1165918960000012 -0.0113689440000009 0.1400038459999982 0.1137478600000012 -0.01610900400000091 0.1371469069999982 0.1137478600000012 -0.0113689440000009 0.1390515329999982 0.1137478600000012 -0.0104209320000009 0.1495269759999982 0.1061637640000012 -0.009472920000000903 0.1561931669999982 0.1004756920000012 -0.0142129800000009 0.1590501059999982 0.1052157520000012 -0.0189530400000009 0.1514316019999982 0.1118518360000012 -0.0199010520000009 0.1371469069999982 0.1052157520000012 -0.0199010520000009 0.1419084719999982 0.1052157520000012 -0.0255891240000009 0.1457177239999982 0.1080597880000012 -0.0246411120000009 0.1419084719999982 0.1023717160000012 -0.0180050280000009 0.1419084719999982 0.0995276800000012 -0.0132649680000009 0.1371469069999982 0.09573563200000119 -0.0113689440000009 0.1352422809999982 0.0985796680000012 -0.0132649680000009 0.1438130979999982 0.1071117760000012 -0.0104209320000009 0.1571454799999982 0.1090078000000012 -0.0142129800000009 0.1609547319999982 0.1090078000000012 -0.01610900400000091 0.1523839149999982 0.1118518360000012 -0.0113689440000009 0.1409561589999982 0.1042677400000012 -0.0132649680000009 0.1333376549999982 0.0928915960000012 -0.0170570160000009 0.1371469069999982 0.1004756920000012 -0.0189530400000009 0.1476223499999982 0.1042677400000012 -0.0142129800000009 0.1409561589999982 0.1014237040000012 -0.0142129800000009 0.1352422809999982 0.1061637640000012 -0.0199010520000009 0.1476223499999982 0.1061637640000012 -0.0180050280000009 0.1514316019999982 0.1004756920000012 -0.0180050280000009 0.1428607849999982 0.0947876200000012 -0.0189530400000009 0.1457177239999982 0.1014237040000012 -0.0180050280000009 0.1495269759999982 0.1080597880000012 -0.01610900400000091 0.1504792889999982 0.1080597880000012 -0.003784848000000902 0.1504792889999982 0.1071117760000012 0.001903223999999096 0.1514316019999982 0.1090078000000012 -0.000940812000000903 0.1514316019999982 0.1184879200000012 -0.004732860000000904 0.1514316019999982 0.1232279800000012 -0.0123169560000009 0.1542885409999982 0.1099558120000012 -0.01610900400000091 0.1447654109999982 0.0985796680000012 -0.0199010520000009 0.1476223499999982 0.1004756920000012 -0.0132649680000009 0.1523839149999982 0.1023717160000012 -0.0132649680000009 0.1504792889999982 0.0995276800000012 -0.0217970760000009 0.1466700369999982 0.1033197280000012 -0.0208490640000009 0.1361945939999982 0.0995276800000012 -0.0255891240000009 0.1390515329999982 0.0938396080000012 -0.0303291840000009 0.1438130979999982 0.1014237040000012 -0.0284331600000009 0.1428607849999982 0.1080597880000012 -0.02274508800000091 0.1390515329999982 0.1184879200000012 -0.01610900400000091 0.1409561589999982 0.1052157520000012 -0.01610900400000091 0.1457177239999982 0.1004756920000012 -0.0199010520000009 0.1409561589999982 0.1156438840000012 -0.0170570160000009 0.1409561589999982 0.1203839440000012 -0.0113689440000009 0.1466700369999982 0.1175399080000012 -0.007576896000000903 0.1466700369999982 0.1175399080000012 -0.005680872000000904 0.1466700369999982 0.1175399080000012 -0.008524908000000903 0.1542885409999982 0.1099558120000012 -0.007576896000000903 0.1523839149999982 0.1014237040000012 -0.0113689440000009 0.1447654109999982 0.09668364400000119 -0.0199010520000009 0.1390515329999982 0.0995276800000012 -0.01610900400000091 0.1380992199999982 0.1099558120000012 -0.01610900400000091 0.1495269759999982 0.1127998480000012 -0.0189530400000009 0.1542885409999982 0.0995276800000012 -0.0217970760000009 0.1390515329999982 0.09668364400000119 -0.0246411120000009 0.1438130979999982 0.09763165600000119 -0.0246411120000009 0.1533362279999982 0.09763165600000119 -0.0180050280000009 0.1485746629999982 0.1023717160000012 -0.008524908000000903 0.1495269759999982 0.1071117760000012 -0.0180050280000009 0.1457177239999982 0.1004756920000012 -0.0217970760000009 0.1428607849999982 0.0995276800000012 -0.0104209320000009 0.1457177239999982 0.1156438840000012 -0.002836836000000903 0.1447654109999982 0.1071117760000012 -0.004732860000000904 0.1476223499999982 0.1052157520000012 -0.0142129800000009 0.1457177239999982 0.1080597880000012 -0.0151609920000009 0.1400038459999982 0.0985796680000012 -0.0104209320000009 0.1419084719999982 0.1071117760000012 -0.0123169560000009 0.1457177239999982 0.1099558120000012 -0.0142129800000009 0.1485746629999982 0.0938396080000012 -0.0132649680000009 0.1447654109999982 0.0853075000000012 -0.0123169560000009 0.1466700369999982 0.09573563200000119 -0.0151609920000009 0.1466700369999982 0.09099557200000119 -0.0274851480000009 0.1504792889999982 0.09763165600000119 -0.0246411120000009 0.1590501059999982 0.1052157520000012 -0.0180050280000009 0.1495269759999982 0.0947876200000012 -0.0246411120000009 0.1276237769999982 0.1004756920000012 -0.0284331600000009 0.1304807159999982 0.1033197280000012 -0.0255891240000009 0.1428607849999982 0.0995276800000012 -0.0189530400000009 0.1438130979999982 0.0995276800000012 -0.0170570160000009 0.1333376549999982 0.0985796680000012 -0.0199010520000009 0.1228622119999982 0.0995276800000012 -0.0142129800000009 0.1285760899999982 0.1090078000000012 -0.01610900400000091 0.1314330289999982 0.1042677400000012 -0.0151609920000009 0.1323853419999982 0.0947876200000012 -0.0142129800000009 0.1361945939999982 0.09763165600000119 -0.0208490640000009 0.1257191509999982 0.09668364400000119 -0.0189530400000009 0.1276237769999982 0.0928915960000012 -0.0142129800000009 0.1371469069999982 0.0947876200000012 -0.01610900400000091 0.1457177239999982 0.09573563200000119 -0.02274508800000091 0.1457177239999982 0.08341147600000119 -0.0246411120000009 0.1238145249999982 0.08246346400000119 -0.02938117200000091 0.1228622119999982 0.09194358400000119 -0.0379132800000009 0.1342899679999982 0.0928915960000012 -0.0350692440000009 0.1352422809999982 0.0872035240000012 -0.0274851480000009 0.1380992199999982 0.08435948800000119 -0.0208490640000009 0.1428607849999982 0.08909954800000119 -0.0274851480000009 0.1333376549999982 0.0938396080000012 -0.03222520800000091 0.1285760899999982 0.0938396080000012 -0.03317322000000091 0.1380992199999982 0.0947876200000012 -0.0379132800000009 0.1438130979999982 0.09763165600000119 -0.03601725600000091 0.1419084719999982 0.08341147600000119 -0.03222520800000091 0.1323853419999982 0.0815154520000012 -0.0274851480000009 0.1323853419999982 0.0862555120000012 -0.0265371360000009 0.1438130979999982 0.08246346400000119 -0.03222520800000091 0.1428607849999982 0.07677539200000119 -0.0436013520000009 0.1400038459999982 0.0748793680000012 -0.05023743600000091 0.1400038459999982 0.07867141600000119 -0.05308147200000091 0.1352422809999982 0.07772340400000119 -0.0540294840000009 0.1371469069999982 0.0853075000000012 -0.0492894240000009 0.1400038459999982 0.0872035240000012 -0.04265334000000091 0.1285760899999982 0.0796194280000012 -0.04265334000000091 0.1276237769999982 0.0748793680000012 -0.0417053280000009 0.1361945939999982 0.07582738000000119 -0.0417053280000009 0.1361945939999982 0.09194358400000119 -0.0445493640000009 0.1352422809999982 0.1061637640000012 -0.05308147200000091 0.1333376549999982 0.1004756920000012 -0.0578215320000009 0.1419084719999982 0.09194358400000119 -0.05308147200000091 0.1380992199999982 0.08435948800000119 -0.0473934000000009 0.1371469069999982 0.07677539200000119 -0.05023743600000091 0.1457177239999982 0.06919129600000119 -0.05971755600000091 0.1361945939999982 0.06255521200000119 -0.0578215320000009 0.1371469069999982 0.05876316400000119 -0.05213346000000091 0.1485746629999982 0.06255521200000119 -0.06066556800000091 0.1457177239999982 0.07013930800000119 -0.0701456880000009 0.1380992199999982 0.0672952720000012 -0.06635364000000091 0.1304807159999982 0.06445123600000119 -0.0701456880000009 0.1371469069999982 0.06824328400000119 -0.07298972400000091 0.1333376549999982 0.06824328400000119 -0.06730165200000091 0.1209575859999982 0.05686714000000119 -0.06635364000000091 0.1323853419999982 0.05591912800000119 -0.0682496640000009 0.1380992199999982 0.06539924800000119 -0.06445761600000091 0.1352422809999982 0.07013930800000119 -0.05876954400000091 0.1323853419999982 0.0748793680000012 -0.0549774960000009 0.1333376549999982 0.0720353320000012 -0.0511854480000009 0.1352422809999982 0.06255521200000119 -0.05687352000000091 0.1342899679999982 0.0578151520000012 -0.0691976760000009 0.1428607849999982 0.05686714000000119 -0.0701456880000009 0.1438130979999982 0.06539924800000119 -0.06730165200000091 0.1400038459999982 0.06824328400000119 -0.06635364000000091 0.1390515329999982 0.05876316400000119 -0.0691976760000009 0.1371469069999982 0.04833503200000119 -0.0758337600000009 0.1361945939999982 0.05117906800000119 -0.0824698440000009 0.1352422809999982 0.0530750920000012 -0.08626189200000091 0.1380992199999982 0.05212708000000119 -0.0843658680000009 0.1371469069999982 0.05212708000000119 -0.0834178560000009 0.1352422809999982 0.04928304400000119 -0.07962580800000091 0.1371469069999982 0.0530750920000012 -0.0710937000000009 0.1419084719999982 0.0597111760000012 -0.06540562800000091 0.1476223499999982 0.05876316400000119 -0.07204171200000091 0.1495269759999982 0.05591912800000119 -0.0748857480000009 0.1466700369999982 0.0530750920000012 -0.06635364000000091 0.1371469069999982 0.05686714000000119 -0.0682496640000009 0.1361945939999982 0.0578151520000012 -0.0748857480000009 0.1457177239999982 0.03790690000000119 -0.08057382000000091 0.1419084719999982 0.02747876800000119 -0.07867779600000091 0.1400038459999982 0.03790690000000119 -0.0881579160000009 0.1352422809999982 0.0464390080000012 -0.0976380360000009 0.1295284029999982 0.04549099600000119 -0.09194996400000091 0.1380992199999982 0.03790690000000119 -0.08720990400000091 0.1457177239999982 0.03885491200000119 -0.09100195200000091 0.1438130979999982 0.0435949720000012 -0.09384598800000091 0.1352422809999982 0.0398029240000012 -0.08626189200000091 0.1238145249999982 0.04549099600000119 -0.0881579160000009 0.1276237769999982 0.05117906800000119 -0.0843658680000009 0.1380992199999982 0.0473870200000012 -0.07772978400000091 0.1361945939999982 0.0464390080000012 -0.0834178560000009 0.1257191509999982 0.04264696000000119 -0.08531388000000091 0.1342899679999982 0.04075093600000119 -0.0834178560000009 0.1380992199999982 0.04549099600000119 -0.0843658680000009 0.1400038459999982 0.04075093600000119 -0.08720990400000091 0.1400038459999982 0.0398029240000012 -0.08531388000000091 0.1380992199999982 0.04454298400000119 -0.09100195200000091 0.1466700369999982 0.03411485200000119 -0.0957420120000009 0.1380992199999982 0.03127081600000119 -0.0900539400000009 0.1352422809999982 0.03411485200000119 -0.09289797600000091 0.1371469069999982 0.03601087600000119 -0.09479400000000091 0.1419084719999982 0.0398029240000012 -0.09194996400000091 0.1466700369999982 0.04264696000000119 -0.09289797600000091 0.1400038459999982 0.03411485200000119 -0.1042741200000009 0.1371469069999982 0.02747876800000119 -0.1042741200000009 0.1371469069999982 0.0331668400000012 -0.1033261080000009 0.1476223499999982 0.03127081600000119 -0.1033261080000009 0.1552408539999982 0.02842678000000119 -0.0957420120000009 0.1476223499999982 0.02842678000000119 -0.0900539400000009 0.1390515329999982 0.03221882800000119 -0.09194996400000091 0.1390515329999982 0.02747876800000119 -0.0957420120000009 0.1419084719999982 0.01989467200000119 -0.09479400000000091 0.1419084719999982 0.03221882800000119 -0.0976380360000009 0.1390515329999982 0.03601087600000119 -0.1042741200000009 0.1304807159999982 0.02937479200000119 -0.1099621920000009 0.1361945939999982 0.02558274400000119 -0.1090141800000009 0.1419084719999982 0.01799864800000119 -0.1099621920000009 0.1333376549999982 0.02273870800000119 -0.1147022520000009 0.1314330289999982 0.02368672000000119 -0.1232343600000009 0.1333376549999982 0.01515461200000119 -0.1222863480000009 0.1342899679999982 0.01799864800000119 -0.1118582160000009 0.1428607849999982 0.01799864800000119 -0.1118582160000009 0.1419084719999982 0.01136256400000119 -0.1090141800000009 0.1285760899999982 0.003778468000001192 -0.1090141800000009 0.1314330289999982 0.008518528000001193 -0.1147022520000009 0.1400038459999982 0.01420660000000119 -0.1014300840000009 0.1419084719999982 0.01799864800000119 -0.0891059280000009 0.1428607849999982 0.01894666000000119 -0.09479400000000091 0.1400038459999982 0.02179069600000119 -0.1118582160000009 0.1438130979999982 0.01989467200000119 -0.1213383360000009 0.1476223499999982 0.01041455200000119 -0.1194423120000009 0.1466700369999982 0.006622504000001193 -0.1165982760000009 0.1371469069999982 0.003778468000001192 -0.1184943000000009 0.1323853419999982 -0.0009615919999988072 -0.1241823720000009 0.1371469069999982 -0.005701651999998808 -0.1260783960000009 0.1380992199999982 0.001882444000001192 -0.1289224320000009 0.1400038459999982 0.007570516000001193 -0.1251303840000009 0.1457177239999982 0.003778468000001192 -0.1260783960000009 0.1476223499999982 0.008518528000001193 -0.1355585160000009 0.1504792889999982 0.01705063600000119 -0.1317664680000009 0.1495269759999982 0.01325858800000119 -0.1279744200000009 0.1409561589999982 0.006622504000001193 -0.1279744200000009 0.1457177239999982 0.003778468000001192 -0.1279744200000009 0.1428607849999982 -0.002857615999998807 -0.1308184560000009 0.1371469069999982 -0.002857615999998807 -0.1260783960000009 0.1409561589999982 0.006622504000001193 -0.1184943000000009 0.1333376549999982 0.007570516000001193 -0.1213383360000009 0.1323853419999982 0.004726480000001192 -0.1298704440000009 0.1380992199999982 -1.357999999880739e-05 -0.1308184560000009 0.1428607849999982 -0.004753639999998808 -0.1327144800000009 0.1380992199999982 -0.002857615999998807 -0.1365065280000009 0.1295284029999982 -0.005701651999998808 -0.1355585160000009 0.1247668379999982 -0.0009615919999988072 -0.1355585160000009 0.1304807159999982 -0.002857615999998807 -0.1402985760000009 0.1428607849999982 -0.009493699999998807 -0.1421946000000009 0.1428607849999982 -0.0009615919999988072 -0.1355585160000009 0.1428607849999982 0.0009344320000011924 -0.1336624920000009 0.1390515329999982 -0.0009615919999988072 -0.1393505640000009 0.1390515329999982 -0.001909603999998807 -0.1431426120000009 0.1457177239999982 -0.003805627999998808 -0.1355585160000009 0.1447654109999982 -0.001909603999998807 -0.1327144800000009 0.1428607849999982 -0.007597675999998808 -0.1393505640000009 0.1466700369999982 -0.01233773599999881 -0.1355585160000009 0.1495269759999982 0.002830456000001192 -0.1346105040000009 0.1476223499999982 0.003778468000001192 -0.1412465880000009 0.1438130979999982 -1.357999999880739e-05 -0.1374545400000009 0.1390515329999982 0.001882444000001192 -0.1365065280000009 0.1371469069999982 -0.006649663999998808 -0.1440906240000009 0.1390515329999982 -0.01138972399999881 -0.1469346600000009 0.1409561589999982 -0.01328574799999881 -0.1545187560000009 0.1390515329999982 -0.01518177199999881 -0.1583108040000009 0.1457177239999982 -0.01707779599999881 -0.1573627920000009 0.1438130979999982 -0.01707779599999881 -0.1573627920000009 0.1352422809999982 -0.01707779599999881 -0.1545187560000009 0.1285760899999982 -0.02466189199999881 -0.1611548400000009 0.1228622119999982 -0.03034996399999881 -0.1630508640000009 0.1352422809999982 -0.01802580799999881 -0.1602068280000009 0.1409561589999982 -0.01423375999999881 -0.1611548400000009 0.1371469069999982 -0.01707779599999881 -0.1573627920000009 0.1428607849999982 -0.01802580799999881 -0.1535707440000009 0.1457177239999982 -0.01423375999999881 -0.1554667680000009 0.1495269759999982 -0.01044171199999881 -0.1535707440000009 0.1447654109999982 -0.005701651999998808 -0.1564147800000009 0.1352422809999982 -0.004753639999998808 -0.1573627920000009 0.1400038459999982 -0.01328574799999881 -0.1592588160000009 0.1476223499999982 -0.01802580799999881 -0.1583108040000009 0.1447654109999982 -0.02655791599999881 -0.1554667680000009 0.1352422809999982 -0.03224598799999881 -0.1649468880000009 0.1361945939999982 -0.03034996399999881 -0.1668429120000009 0.1400038459999982 -0.01992183199999881 -0.1649468880000009 0.1390515329999982 -0.01328574799999881 -0.1725309840000009 0.1380992199999982 -0.01518177199999881 -0.1744270080000009 0.1352422809999982 -0.01897381999999881 -0.1687389360000009 0.1342899679999982 -0.02560990399999881 -0.1696869480000009 0.1390515329999982 -0.03224598799999881 -0.1687389360000009 0.1409561589999982 -0.03319399999999881 -0.1611548400000009 0.1428607849999982 -0.03034996399999881 -0.1583108040000009 0.1476223499999982 -0.01897381999999881 -0.1573627920000009 0.1514316019999982 -0.01707779599999881 -0.1658949000000009 0.1476223499999982 -0.02371387999999881 -0.1734789960000009 0.1409561589999982 -0.02181785599999881 -0.1687389360000009 0.1400038459999982 -0.02086984399999881 -0.1677909240000009 0.1361945939999982 -0.02750592799999881 -0.1706349600000009 0.1323853419999982 -0.04457014399999881 -0.1791670680000009 0.1419084719999982 -0.04931020399999881 -0.1810630920000009 0.1409561589999982 -0.04551815599999881 -0.1782190560000009 0.1361945939999982 -0.0483621919999988 -0.1810630920000009 0.1419084719999982 -0.04362213199999881 -0.1858031520000009 0.1438130979999982 -0.03793405999999881 -0.1895952000000009 0.1371469069999982 -0.03793405999999881 -0.1820111040000009 0.1333376549999982 -0.03698604799999881 -0.1725309840000009 0.1390515329999982 -0.03698604799999881 -0.1706349600000009 0.1447654109999982 -0.04077809599999881 -0.1696869480000009 0.1438130979999982 -0.04077809599999881 -0.1706349600000009 0.1400038459999982 -0.03888207199999881 -0.1696869480000009 0.1409561589999982 -0.03603803599999881 -0.1696869480000009 0.1428607849999982 -0.03319399999999881 -0.1744270080000009 0.1419084719999982 -0.03793405999999881 -0.1801150800000009 0.1352422809999982 -0.03793405999999881 -0.1971792960000009 0.1323853419999982 -0.03793405999999881 -0.2057114040000009 0.1342899679999982 -0.05025821599999881 -0.1962312840000009 0.1428607849999982 -0.05025821599999881 -0.1905432120000009 0.1438130979999982 -0.05025821599999881 -0.1895952000000009 0.1361945939999982 -0.05499827599999881 -0.1933872480000009 0.1390515329999982 -0.04646616799999881 -0.1990753200000009 0.1400038459999982 -0.03319399999999881 -0.1952832720000009 0.1390515329999982 -0.03414201199999881 -0.1905432120000009 0.1428607849999982 -0.04741417999999881 -0.1933872480000009 0.1419084719999982 -0.04551815599999881 -0.1848551400000009 0.1333376549999982 -0.04362213199999881 -0.1914912240000009 0.1352422809999982 -0.04172610799999881 -0.2028673680000009 0.1352422809999982 -0.03793405999999881 -0.1858031520000009 0.1361945939999982 -0.04457014399999881 -0.1791670680000009 0.1438130979999982 -0.04931020399999881 -0.1876991760000009 0.1333376549999982 -0.04931020399999881 -0.1962312840000009 0.1333376549999982 -0.05025821599999881 -0.1990753200000009 0.1409561589999982 -0.05025821599999881 -0.1962312840000009 0.1380992199999982 -0.05120622799999881 -0.1981273080000009 0.1419084719999982 -0.05784231199999881 -0.2038153800000009 0.1495269759999982 -0.05689429999999881 -0.2019193560000009 0.1457177239999982 -0.05405026399999881 -0.2000233320000009 0.1400038459999982 -0.06068634799999881 -0.2057114040000009 0.1457177239999982 -0.05689429999999881 -0.2180355600000009 0.1438130979999982 -0.05689429999999881 -0.2218276080000009 0.1342899679999982 -0.0635303839999988 -0.2151915240000009 0.1400038459999982 -0.0635303839999988 -0.2180355600000009 0.1466700369999982 -0.0692184559999988 -0.2246716440000009 0.1400038459999982 -0.07490652799999881 -0.2170875480000009 0.1304807159999982 -0.07016646799999882 -0.2095034520000009 0.1419084719999982 -0.07016646799999882 -0.2047633920000009 0.1495269759999982 -0.07206249199999881 -0.2028673680000009 0.1390515329999982 -0.06827044399999881 -0.2057114040000009 0.1390515329999982 -0.06637441999999881 -0.2000233320000009 0.1485746629999982 -0.05784231199999881 -0.2038153800000009 0.1466700369999982 -0.05784231199999881 -0.2104514640000009 0.1361945939999982 -0.05879032399999881 -0.2047633920000009 0.1390515329999982 -0.05499827599999881 -0.2085554400000009 0.1419084719999982 -0.0635303839999988 -0.2123474880000009 0.1314330289999982 -0.07395851599999881 -0.2085554400000009 0.1333376549999982 -0.0768025519999988 -0.2161395360000009 0.1390515329999982 -0.08059459999999881 -0.2237236320000009 0.1323853419999982 -0.08059459999999881 -0.2256196560000009 0.1295284029999982 -0.08817869599999881 -0.2294117040000009 0.1352422809999982 -0.08723068399999881 -0.2256196560000009 0.1352422809999982 -0.07869857599999881 -0.2256196560000009 0.1400038459999982 -0.08154261199999881 -0.2256196560000009 0.1457177239999982 -0.08059459999999881 -0.2284636920000009 0.1438130979999982 -0.07395851599999881 -0.2199315840000009 0.1428607849999982 -0.0768025519999988 -0.2113994760000009 0.1409561589999982 -0.0758545399999988 -0.2170875480000009 0.1304807159999982 -0.0692184559999988 -0.2180355600000009 0.1314330289999982 -0.06827044399999881 -0.2180355600000009 0.1400038459999982 -0.07395851599999881 -0.2208795960000009 0.1400038459999982 -0.0758545399999988 -0.2227756200000009 0.1390515329999982 -0.07206249199999881 -0.2189835720000009 0.1419084719999982 -0.08059459999999881 -0.2199315840000009 0.1400038459999982 -0.08438664799999882 -0.2294117040000009 0.1438130979999982 -0.07490652799999881 -0.2350997760000009 0.1466700369999982 -0.0768025519999988 -0.2341517640000009 0.1438130979999982 -0.0768025519999988 -0.2332037520000009 0.1371469069999982 -0.0768025519999988 -0.2350997760000009 0.1352422809999982 -0.08438664799999882 -0.2398398360000009 0.1419084719999982 -0.08249062399999881 -0.2436318840000009 0.1409561589999982 -0.08438664799999882 -0.2398398360000009 0.1428607849999982 -0.08817869599999881 -0.2284636920000009 0.1466700369999982 -0.0900747199999988 -0.2275156800000009 0.1457177239999982 -0.09481477999999881 -0.2350997760000009 0.1323853419999982 -0.08343863599999882 -0.2350997760000009 0.1266714639999982 -0.08059459999999881 -0.2322557400000009 0.1371469069999982 -0.09386676799999881 -0.2332037520000009 0.1409561589999982 -0.09291875599999881 -0.2407878480000009 0.1428607849999982 -0.09386676799999881 -0.2474239320000009 0.1447654109999982 -0.1014508639999988 -0.2417358600000009 0.1380992199999982 -0.1023988759999988 -0.2379438120000009 0.1371469069999982 -0.1023988759999988 -0.2474239320000009 0.1361945939999982 -0.09671080399999882 -0.2512159800000009 0.1352422809999982 -0.09386676799999881 -0.2455279080000009 0.1361945939999982 -0.09576279199999881 -0.2455279080000009 0.1400038459999982 -0.09386676799999881 -0.2531120040000009 0.1476223499999982 -0.09576279199999881 -0.2606961000000009 0.1476223499999982 -0.09860682799999881 -0.2578520640000009 0.1428607849999982 -0.09765881599999882 -0.2464759200000009 0.1390515329999982 -0.09197074399999881 -0.2360477880000009 0.1380992199999982 -0.09102273199999882 -0.2360477880000009 0.1390515329999982 -0.09291875599999881 -0.2407878480000009 0.1428607849999982 -0.09291875599999881 -0.2417358600000009 0.1438130979999982 -0.09197074399999881 -0.2369958000000009 0.1466700369999982 -0.09671080399999882 -0.2455279080000009 0.1476223499999982 -0.09102273199999882 -0.2474239320000009 0.1438130979999982 -0.09860682799999881 -0.2455279080000009 0.1314330289999982 -0.1099829719999988 -0.2483719440000009 0.1285760899999982 -0.1033468879999988 -0.2474239320000009 0.1304807159999982 -0.09671080399999882 -0.2493199560000009 0.1266714639999982 -0.1052429119999988 -0.2502679680000009 0.1361945939999982 -0.1061909239999988 -0.2474239320000009 0.1400038459999982 -0.1042948999999988 -0.2445798960000009 0.1352422809999982 -0.1033468879999988 -0.2407878480000009 0.1409561589999982 -0.1128270079999988 -0.2369958000000009 0.1495269759999982 -0.1061909239999988 -0.2322557400000009 0.1457177239999982 -0.08817869599999881 -0.2369958000000009 0.1342899679999982 -0.08912670799999881 -0.2445798960000009 0.1390515329999982 -0.08912670799999881 -0.2350997760000009 0.1438130979999982 -0.09102273199999882 -0.2294117040000009 0.1447654109999982 -0.09386676799999881 -0.2360477880000009 0.1504792889999982 -0.09671080399999882 -0.2407878480000009 0.1447654109999982 -0.1052429119999988 -0.2407878480000009 0.1361945939999982 -0.1090349599999988 -0.2417358600000009 0.1333376549999982 -0.1023988759999988 -0.2445798960000009 0.1333376549999982 -0.1042948999999988 -0.2426838720000009 0.1409561589999982 -0.1052429119999988 -0.2426838720000009 0.1361945939999982 -0.1109309839999988 -0.2493199560000009 0.1285760899999982 -0.1118789959999988 -0.2502679680000009 0.1380992199999982 -0.09576279199999881 -0.2445798960000009 0.1457177239999982 -0.09102273199999882 -0.2464759200000009 0.1438130979999982 -0.09860682799999881 -0.2407878480000009 0.1419084719999982 -0.09671080399999882 -0.2350997760000009 0.1447654109999982 -0.09671080399999882 -0.2379438120000009 0.1438130979999982 -0.09860682799999881 -0.2303597160000009 0.1333376549999982 -0.08912670799999881 -0.2275156800000009 0.1352422809999982 -0.09576279199999881 -0.2360477880000009 0.1428607849999982 -0.09481477999999881 -0.2350997760000009 0.1361945939999982 -0.09291875599999881 -0.2332037520000009 0.1304807159999982 -0.1033468879999988 -0.2322557400000009 0.1409561589999982 -0.1052429119999988 -0.2379438120000009 0.1409561589999982 -0.1014508639999988 -0.2483719440000009 0.1342899679999982 -0.09197074399999881 -0.2455279080000009 0.1390515329999982 -0.09197074399999881 -0.2455279080000009 0.1419084719999982 -0.1014508639999988 -0.2464759200000009 0.1428607849999982 -0.09955483999999881 -0.2369958000000009 0.1457177239999982 -0.09671080399999882 -0.2407878480000009 0.1419084719999982 -0.1005028519999988 -0.2502679680000009 0.1409561589999982 -0.09860682799999881 -0.2407878480000009 0.1485746629999982 -0.09860682799999881 -0.2294117040000009 0.1476223499999982 -0.09386676799999881 -0.2275156800000009 0.1419084719999982 -0.08817869599999881 -0.2256196560000009 0.1352422809999982 -0.08343863599999882 -0.2256196560000009 0.1371469069999982 -0.08723068399999881 -0.2294117040000009 0.1428607849999982 -0.09671080399999882 -0.2332037520000009 0.1361945939999982 -0.09671080399999882 -0.2322557400000009 0.1409561589999982 -0.09860682799999881 -0.2341517640000009 0.1400038459999982 -0.1042948999999988 -0.2388918240000009 0.1333376549999982 -0.1023988759999988 -0.2474239320000009 0.1380992199999982 -0.1014508639999988 -0.2464759200000009 0.1361945939999982 -0.09671080399999882 -0.2417358600000009 0.1323853419999982 -0.08912670799999881 -0.2512159800000009 0.1314330289999982 -0.09197074399999881 -0.2512159800000009 0.1342899679999982 -0.09765881599999882 -0.2474239320000009 0.1352422809999982 -0.1014508639999988 -0.2436318840000009 0.1419084719999982 -0.09386676799999881 -0.2388918240000009 0.1485746629999982 -0.0900747199999988 -0.2332037520000009 0.1428607849999982 -0.09481477999999881 -0.2360477880000009 0.1323853419999982 -0.09386676799999881 -0.2388918240000009 0.1371469069999982 -0.09386676799999881 -0.2388918240000009 0.1542885409999982 -0.0900747199999988 -0.2474239320000009 0.1504792889999982 -0.08438664799999882 -0.2417358600000009 0.1466700369999982 -0.0900747199999988 -0.2332037520000009 0.1504792889999982 -0.1023988759999988 -0.2417358600000009 0.1438130979999982 -0.09955483999999881 -0.2474239320000009 0.1485746629999982 -0.09102273199999882 -0.2464759200000009 0.1495269759999982 -0.09671080399999882 -0.2407878480000009 0.1352422809999982 -0.1061909239999988 -0.2445798960000009 0.1257191509999982 -0.09765881599999882 -0.2550080280000009 0.1295284029999982 -0.08912670799999881 -0.2493199560000009 0.1380992199999982 -0.08628267199999881 -0.2474239320000009 0.1419084719999982 -0.09102273199999882 -0.2502679680000009 0.1323853419999982 -0.09860682799999881 -0.2455279080000009 0.1304807159999982 -0.09765881599999882 -0.2407878480000009 0.1485746629999982 -0.09291875599999881 -0.2275156800000009 0.1495269759999982 -0.08438664799999882 -0.2256196560000009 0.1400038459999982 -0.08059459999999881 -0.2360477880000009 0.1342899679999982 -0.07775056399999881 -0.2341517640000009 0.1304807159999982 -0.08059459999999881 -0.2332037520000009 0.1276237769999982 -0.08817869599999881 -0.2379438120000009 0.1247668379999982 -0.09102273199999882 -0.2398398360000009 0.1314330289999982 -0.09291875599999881 -0.2502679680000009 0.1371469069999982 -0.1033468879999988 -0.2531120040000009 0.1295284029999982 -0.1090349599999988 -0.2512159800000009 0.1238145249999982 -0.09481477999999881 -0.2493199560000009 0.1361945939999982 -0.08533465999999881 -0.2388918240000009 0.1438130979999982 -0.08912670799999881 -0.2360477880000009 0.1380992199999982 -0.09386676799999881 -0.2417358600000009 0.1428607849999982 -0.09765881599999882 -0.2445798960000009 0.1400038459999982 -0.08628267199999881 -0.2474239320000009 0.1428607849999982 -0.08817869599999881 -0.2445798960000009 0.1552408539999982 -0.09765881599999882 -0.2379438120000009 0.1495269759999982 -0.08817869599999881 -0.2369958000000009 0.1390515329999982 -0.08249062399999881 -0.2360477880000009 0.1400038459999982 -0.08817869599999881 -0.2407878480000009 0.1495269759999982 -0.08628267199999881 -0.2417358600000009 0.1495269759999982 -0.07775056399999881 -0.2350997760000009 0.1476223499999982 -0.08059459999999881 -0.2369958000000009 0.1438130979999982 -0.08723068399999881 -0.2436318840000009 0.1304807159999982 -0.09481477999999881 -0.2474239320000009 0.1314330289999982 -0.09102273199999882 -0.2464759200000009 0.1361945939999982 -0.09197074399999881 -0.2445798960000009 0.1295284029999982 -0.09102273199999882 -0.2512159800000009 0.1304807159999982 -0.08154261199999881 -0.2540600160000009 0.1352422809999982 -0.08723068399999881 -0.2540600160000009 0.1361945939999982 -0.09481477999999881 -0.2559560400000009 0.1400038459999982 -0.09102273199999882 -0.2512159800000009 0.1447654109999982 -0.08438664799999882 -0.2512159800000009 0.1476223499999982 -0.08628267199999881 -0.2464759200000009 0.1495269759999982 -0.0900747199999988 -0.2341517640000009 0.1485746629999982 -0.0900747199999988 -0.2303597160000009 0.1438130979999982 -0.08343863599999882 -0.2294117040000009 0.1447654109999982 -0.0768025519999988 -0.2436318840000009 0.1504792889999982 -0.07964658799999881 -0.2493199560000009 0.1514316019999982 -0.07869857599999881 -0.2369958000000009 0.1466700369999982 -0.07395851599999881 -0.2369958000000009 0.1380992199999982 -0.08723068399999881 -0.2445798960000009 0.1333376549999982 -0.09576279199999881 -0.2531120040000009 0.1323853419999982 -0.09197074399999881 -0.2597480880000009 0.1304807159999982 -0.08628267199999881 -0.2436318840000009 0.1400038459999982 -0.08628267199999881 -0.2464759200000009 0.1409561589999982 -0.09197074399999881 -0.2597480880000009 0.1371469069999982 -0.08723068399999881 -0.2540600160000009 0.1409561589999982 -0.08438664799999882 -0.2426838720000009 0.1400038459999982 -0.0900747199999988 -0.2407878480000009 0.1333376549999982 -0.09102273199999882 -0.2322557400000009 0.1371469069999982 -0.09291875599999881 -0.2322557400000009 0.1371469069999982 -0.0900747199999988 -0.2417358600000009 0.1371469069999982 -0.08154261199999881 -0.2502679680000009 0.1438130979999982 -0.08723068399999881 -0.2464759200000009 0.1371469069999982 -0.09197074399999881 -0.2379438120000009 0.1352422809999982 -0.09291875599999881 -0.2436318840000009 0.1371469069999982 -0.09765881599999882 -0.2493199560000009 0.1314330289999982 -0.09576279199999881 -0.2521639920000009 0.1371469069999982 -0.09102273199999882 -0.2502679680000009 0.1457177239999982 -0.09576279199999881 -0.2426838720000009 0.1514316019999982 -0.09576279199999881 -0.2483719440000009 0.1466700369999982 -0.08438664799999882 -0.2550080280000009 0.1380992199999982 -0.08912670799999881 -0.2502679680000009 0.1333376549999982 -0.08817869599999881 -0.2398398360000009 0.1352422809999982 -0.08438664799999882 -0.2388918240000009 0.1390515329999982 -0.0900747199999988 -0.2464759200000009 0.1438130979999982 -0.09102273199999882 -0.2426838720000009 0.1457177239999982 -0.09197074399999881 -0.2313077280000009 0.1371469069999982 -0.08912670799999881 -0.2369958000000009 0.1352422809999982 -0.08154261199999881 -0.2426838720000009 0.1380992199999982 -0.08343863599999882 -0.2379438120000009 0.1438130979999982 -0.08817869599999881 -0.2417358600000009 0.1542885409999982 -0.09386676799999881 -0.2426838720000009 0.1476223499999982 -0.1005028519999988 -0.2436318840000009 0.1409561589999982 -0.09765881599999882 -0.2455279080000009 0.1419084719999982 -0.09765881599999882 -0.2502679680000009 0.1371469069999982 -0.09291875599999881 -0.2483719440000009 0.1352422809999982 -0.08817869599999881 -0.2426838720000009 0.1314330289999982 -0.09102273199999882 -0.2455279080000009 0.1228622119999982 -0.08817869599999881 -0.2550080280000009 0.1228622119999982 -0.08438664799999882 -0.2569040520000009 0.1304807159999982 -0.09102273199999882 -0.2550080280000009 0.1304807159999982 -0.09576279199999881 -0.2521639920000009 0.1304807159999982 -0.09481477999999881 -0.2464759200000009 0.1323853419999982 -0.09576279199999881 -0.2350997760000009 0.1276237769999982 -0.09955483999999881 -0.2360477880000009 0.1304807159999982 -0.1033468879999988 -0.2445798960000009 0.1400038459999982 -0.09765881599999882 -0.2388918240000009 0.1476223499999982 -0.08817869599999881 -0.2265676680000009 0.1485746629999982 -0.09386676799999881 -0.2246716440000009 0.1371469069999982 -0.09671080399999882 -0.2369958000000009 0.1409561589999982 -0.08249062399999881 -0.2436318840000009 0.1476223499999982 -0.08343863599999882 -0.2436318840000009 0.1428607849999982 -0.09765881599999882 -0.2445798960000009 0.1361945939999982 -0.09765881599999882 -0.2474239320000009 0.1295284029999982 -0.09576279199999881 -0.2436318840000009 kst-2.0.3/docbook/kst/scripttutorial/simpleTags.js000644 001750 001750 00000000510 11544160206 022643 0ustar00synthsynth000000 000000 // very simple KstScript demo: plot a vector collumn from a file file = new DataSource("demodata.dat") var w = Kst.windows[0]; var p = new Plot(w); var x = new DataVector(file,"INDEX"); x.tagName = "xv" var y = new DataVector(file,"1"); y.tagName = "yv" var c = new Curve("xv","yv"); c.tagName = "c" p.curves.append("c"); kst-2.0.3/docbook/kst/scripttutorial/subroutines.js000644 001750 001750 00000001255 11544160206 023124 0ustar00synthsynth000000 000000 // subroutines.js // plot a field from a datasource in a previously created plot function addField(plot, field, f0, n, datasource) { var x1 = new DataVector(datasource, "INDEX", f0, n); x1.tagName = "INDEX" var y1 = new DataVector(datasource, field, f0, n); y1.tagName=field var c1 = new Curve(x1, y1); c1.tagName = field plot.curves.append(c1) plot.topLabel = plot.topLabel + field + " " } // create a plot and add a field curve to it. function plotField(field, f0, n, datasource) { var p1 = new Plot(Kst.windows[0]); p1.topLabel = "File: " + datasource.fileName + " Fields: " addField(p1,field, f0, n, datasource); p1.xAxis.label = "Index" return p1 } kst-2.0.3/docbook/kst/scripttutorial/Screenshot-kst-scripttutorial-subroutines.png000644 001750 001750 00000113241 11544160206 031273 0ustar00synthsynth000000 000000 PNG  IHDR`B^9 IDATxww炻+S  8PBBM=|K0Me?tI:Nb 4;wg_̮_=X#~cqIaHz .m21111111FH8[ .Udbbbbbbbf=,_K |`&`&&&&&&&hjjٱl`LLLLLLLLz?~|ܰa.gWaO,$ϔ|}|L0OeN0 6v]~O{wˉDG tp5111113{N$ ֬YìY(ܵ,ee:>,.Gx999T!Dd^W]v$AX3Ba[T u v޾añ=;2N{PVn23Y8A$!]{ !l73{zLeǟ@He|5^BUۑzLN;ᡰ5L] >Yi&6 7bĈ[׺o%X}Y$B@ z;S\Qh#Gw=dxYmsH;l? "KYwWfbbbbrU&`UUۻ3b.ԮIm%KY(4_}]#0lyYlp|1x0lr1Sr-A!@H ou8hj؍7-Œ$7O4&n|]}.76"5 G :"% fx#`+WbڴiԮȑ۶UʞX.H%L ! )_[LnxM$IXfI(sC*$X8Tl!kIbs J9NSEe8 "[:$ I脂aTU !X؝IS`:Re>l !iBie%.$@U1ړ)IQ,ܮ-- rLLLLL<3e[MMMid3jHnDfkOFƍb 2( a ~~I'O$.- 58rrx rslhjOcR innmMs3cwnc𷶦اQFS P4!(p |\J㋬MCZsKwYj^XQ~tdE&1#d`-m~4Z<u:.Wǁ0vSoٲ5&+ڕѣGJk,nBt]@0.GGmSZ@״z)EafF-46dp,4MbtڮkZکQ0bmmO쁼2*|aHq[e¾Y`P 7@`&`E"bA,ȊҞ !yy8( ~-Me%(tҵ(}nIRLd{Od1cF[bߣ׌GHnشi3Mf;G.,E?e%7JTE.V ޶s#Ԁ0 Rڬ(rv nSvGP ( Ha lTz1(ndiB_F- :HGģ(JV!6P|B~B5[6Y"d$ 0Hr˵qv3GLLLL<l5`7𽨨cXnFEij5Ua~wn~rKD #.HhHi$8$Yjuf=9pׅZXZ (@Z|8$؟7Y6<6lťXJ}]*'ߍ %nQ:=6~B51111fȦMcb6o#=J$ ZnH|t'y^ &~A#k1VѮ4&Ih )$EdIN*oxRT_W?:e+I2B(@tJj#Ӣ.' fUUǏ?I\y9|Xd I |xeX'ى:ZZH+ώ:YobbbbbM?n]:%`FǍ;8VinME XԲtoc׮FA=jEBmv! 5H Y]Jw3DQ\}n0EP4t8P ;n"ӦF2,aR&)))faGSH%B")6 u+Jy Jm! B0֨.#`ٳg۝n=M~? 6C!2GW>cuP/1Ҏ$vP!΂<4kn!Aȗz'Er:GXe=|B!@yyiZYYBt)++J<7m $*邼'h!|;Z0~Tm jN?SeIq<$Q^^AnnN}X(I9%P_אP$6X,>!!@"!aZۀffbbbrU0axHUc(B~djQGN-[{mzÐ1 ]%7Dzѳ5UTOc@j4֣2J/yC+$Q[[ l eeB "WRJ(t[|F*KRsQېmcid;yzjsa h X8;jT X t\7.ilBDOvfI$**3no!Dʶ |亜䖖`@FFjoj/5'h斃|7Nf&=d|ƶ3^o}_WtO #kzV{F{JNq ޚ&~M X-VllK֮]wLI L8 ע` L4 ^K'y@*26W^!nw_~YRM1}&MDNqp=@-y baE zZ>!҄;7E'^4a[fML}}&MbQSDNaqây1|#00 P,VJ).Aڱ:,u@Xk"ŞKe/ (l`۱?GJ: x lnwNB理_EXe (pݝdVT`f*)r/!JɞG@oY`Qd%yn,}>rrr츥=G=`qawq9: Iȱ@nn! ElIa&`oIlwSdltD$*++SnK_i}dEA+($!;s)u&mIC_Е\WvoJ$ ;?mX Xs&`&&&&&&&_ lڴq̍7_$I.?[ {$+7̼-_=ffbbbbbb ۅå'ltJZ[[V611111111ɞS$X⿴r?ޯ|YhӧOKH,*z<ĤoH%Ia&`&&&&&&&& a0gd?O=c=TLM} R@۞8uجm-wwȱB 6yA*:_7)uobq歗1c')Bz ![ni ?ozy!u?q 3|6\6x6/9/?eࡇ~֡x|n]cǾ3%.<OA555]Լ2y6}ɑyXøjf̳QA]lK8,?\NgyXU?*$csލY( P0lG+R)|>3_q-eEq gڴ)BĶ !y֧;RC`ə{߽kO+/=!'qvY.<2b}G}m G; !(S<ݜpMv``/p0Na~kvBsYzӧM'X|fr1cm:ڨ%Rh{=|QXu}~wp7׀ !0ڣ|'V@BvߑL>Ua`F~;n>,3v>ze>G0|Ǔz + qݩ{7'߀?J&*?l13ۇb4,t];s+a&-~N틜>$l~N?V3GW8fat_kvwe9&Gʄ"[&[V >b=j?y@6>^,W͟S:d;Žͪ9罿'Nԫ?2~߮.ͱ7y7^AIMS&8R?ҥ_N~C?s !_nOb?dsCoc,޿8D& 7o?:)ϒ%/pȘi|'1 Ϳ{ ڻdr G^P[XDItKb؏=OΟU=+A{qߘYIyՍ_<4>,r#L_3}so^&3z&ѥL_P 8sb#Psե]fP"v"N=,,X͋jY_3ٯ7}克88|!x=.Qv,ᑑN0p8Zzn1"ic,7 8ۗ62^})_3<nE?Ǯ7~B>"’NUc ^`Ν̳Y &Ǟuewft=n+9-s%pءIҝOrz xd^"I1tciG5||,v ;,q#3+?vG;ŏd)*zv;V M!⑻9 qBd,YZU,Er6\q憛'R5|xTdǎ?Չ+:}}W^SLymnkZѝ}ѲoJL Llw*xCނ=oEq eS!]o_؟<+?<hC wշzg[}y66,o-4NpglGTNdazF::a%qvo#޻qv;}lLͱGI,h ~''M1Gǹ̮_l$w;PοPHx3XS&6ƹ,]eQc8Z/] Gpܻt.*2ҵ .|mZK.3?;~6k'q}<}Sy[Yӹy)d_O&չГkYekahy޸B -rlCK KCC3ؙbMAN̾:'ϱ%rT^b&H)SYo7ܾx;|h]L _ ]M'h``9㶋W@"guFF ]5AF|U}o&5x1nߎVd!]_ڍ) ˩^#NF$׉ߞ껽 ѿ'ekԝ+Y_muQ)\,:onx4?`lW]:-ۗ󳅧s)<躎-,Ēmo%ؙl#v~y !?x3?2{BN*sOE!osg4t]C{ɹ587 M]3|>[9Æ cYp㖉?]ٝ+n'CӖ?Q]?.jq7 aT/ZeF/] 뺎;pSs!Mٙ32\Ū1γg#۵NlF}4Wpۥs-31 O+\$^;O΅~&9RՏ~7/#2ޝu ?tG7㕊۾}{wЃUwm#cSֿ`ruZ>ww^5='L=ǝZ IDATUYG$:uWV8\7~lڧ@6#8{kwFI>yž'YW.@ics**EKŕwyiBtkwW]"CW?ag<|s|*jnk&,~k> UMY/:xX 1i6žOaxhzN(t>p^8!ݴXL쮟=:eDW=s#XsDyt~>NunΑ7!D1)'΃/|@i$۶ɶMU o"/"#_"¯dj3XvG*s ys@ <}wTG:1oQN!ưa? dss [md&B.?Hd=#EEy̜9tiKw:.BLWoC~FFH?6 Z(pX-r`s¹Ew]P(DyyyV(2I3lnnNY͖P&sR*ϦWXXg${;N!0@hjj?]?~D쳦hCe`"o!'|T%O(x̝;uH10uPXE TMɃ`}L7l~U NJir+ǻpV RTzl ;~9Cz$[H q{xl»aM-({JNEҳjjj vڅjMcN~8/ &l6P(p \.~?eail2f̘q@˖Ϧ.]ٳ9.lٝ˕N~ʬl8P+g U*ҎaƏ/TzTWM*?`RP_FuM+cQdڼ բi:%4TUGU#wi``e vHntC?BzDhH!%SL⭷ͼyқXzVV֍fwp_~b@s& Pݤ'^_!)ʊ>6Vv,R;[9xP+!Ό:l@ٰ⚧h ּ29뱕}ZI>\.WFD+H2Jp#2/ͺ?^̰$e'8j($1kK~rJh|Dجu:>DUKYÃ`^vV_rYx6a֬Y~~7{6mV]ݩ# msPz/p88J_\|>޼~55lz |_8X2/s#Y5=RYmB'@^ۯ>}x lkn:t]K|@AUYI(bRN:iVtԼc&IZ,1{{ԥ;c$|z$`ߧG{7w aYpڒ簗Ţn1x` 뿨eХ@moxX!s8yj. 92#65e K5s߫prP~xdË\r%kbq LV՚U<&'_ )ض6=!uyj)IO?QF(orǭ 5𥂔': ]IEyՎzAJZobeHupɝ/ڸ1򪪊ꉾxCd*3*I1Bp$Œr1iG+[=ĻGeunqMt]%D==z [v@Pq1}q\||> Ubqasd-3VDO>0υ%Ӎu YrrEDN ܹGxika Dٴ(ZXΝ!\n\ecSa,SgŢnRRacÖ}UڧvT78+9QV8jxaCTbw:^=Qu`=fuVW_Cg H?.3Zja[}ĭ)-92a:RZs:y˞ȾH֭^ͬ_&8c~k.aa(0zLGpmnXR, YKmM͜qtaT ;UOeC}ķG~p8P U4ȎәTdXQՎUEn /g`yaV/5oѠH|醁aT5a=Z]ѯȻ,|Pޛ|aaA#NcއvYE~H%=~]D#ݵ]iUkvqԿzbXʙ39P+VDu] b8VB־V0uU+w \cXf66lp+n\.dAxAnOd/HoVә1 +,ޓ樒 '7ׇ~HkV1-. .uo͐쳙e 'TUe>ndtԴ)_H jv} lj&4?Gdi/۫q$-g444nC?#q9r '@}=ZLwq{iJ;}7;f />H1T|CFGʪ2xNM^& M;=?/Yо/q}ovq.9\âӏIDӕ+emmW_j]-??O|im漊 6>d d#Κƶz+ae6=uϫ'#`CJva :50s3"T}3NY'`k'„U Y$'ΙHeY>E]FkSh6 U O0LX)ME"2,sih&[zDF2}#YxD8|ީΆ?HnKuXjrh~@7~u|nnF%t] K2S DoCM۸ !NeǦaQc\%Ba :p9X, aUCvB'AVWM 0eTd5DW@vD0 0!Pa׸~D3xs|Yc( ܌/ )N3wb(! ?}]ٳyp\ve^cccCwߌmZ3uhN;5yx3gNZ}$%t_&7AA-ua‡"3f9; J ] UeԦn㼡CھM9rd%[lY.O`V\Ša̘%c<9!=b-[ >;{v1/,mdpH:Pޗo Vĕn>Lzo"(*!5gqK&Z/\ateGr>s|3a~3g2>\j.Ƞ&$jU!4=~N?X A]4ۨmf5EfmF~~1yyǒ/-. UtMCdYOVQ[´ib}wdbW]B!.w㎛ޭlP;'3ypXi^?6 曫9Cݙk~F-EQ5`(@ Rd=:׺`?a#lAskae2c%Nsڬ,/žnTn?d%/٣P݇Px%Rp*R@ @ ̹;sC.xYTb0wpGL,&;p}6mo1'u%`Hت% ʾc֭LZ' kՌ1X;\8S$Ӎ]w?CfԂ7e!!3&;ȝ`UkDB 4MG#wC!g޼HwJv*귝d^[*>av jTrrK)ph4{#Dx:mܦ1 CF$j[5VΧ#rQ0܅=tK.,4 Tc.FlA|I#-a(4G |g炷~*o Ζ4ȁP-4`O7 -bàQtݱ ޽n38W^y%ͫ -^ M`iÑUUQUvg>n' u!O. t#\1U3hnhu`UyIxXhڦM4_s kW^cs_$`EbBa"lVK<*{t dMHD!8{v1{}/VחxC~u*L5:zKEt1~,=m&VF=PQQq~ȿ/O9ﻏ iF_5+sL ^3ٯq-#Baa [+w`a\_?0sjEWoY a1B:2?a5לWԥpX#j$"kTM'jF0 ik „B*p`0~G~_uM4OǜjdQjb |uu5X,9hBa3it6nرc۝].b^%mtwI >zJZe"iVmk8ĉ-ÑL7ޖ|;tt٢44z4=Ԃ"ZĢȴx5^`8O]K4Q^98l2}BWPbhEDe9|,(upmPv<)r1yd=yZ]yJY$u9;Yg2pO V 4Q2}>{Rh۶mpHױtM̝; puqAi0ꞻ } M\{lsPXU;F1fC`0KӡKc_W= :tZ4;kT~[kG~? ,`̈́aEP #[X5b]t?0:m<N QK<~/kiO2T~Sň&a¢ȑ/gu;9U"ʿHsY8jb>|13}QUt:KFE#^5Ki~=4 G<#+ݴ]+矏O=0;?gݶm丬}Wd3K$+5͑:FC/G#`eLj t =hhjvF:8֬nE%3&<)H0p9mgI@:qXd ,aUdB0B p$^:`uǾkT_.$d!5W14[6` xw3fLz;]% e6OtQOIkǺu25ѹNDv"m % s,} aHq̀OW)4z#6jV\V"(+jx|:B[+GSga`Y$P$†`Sq#=jx*cǾf~_s2av;%+f7f˔QK `S WۂR9|7//?>كݖ~pp5 /pv-28ia5[w=&6n NAA.vƀnE梦fPuP$@c!jAuC^[^_ba!{.o6,SZZlH^/J^رorΤIbz2σKl5%1EIN~Y@H8s>Y%h >Ub}ϓH~o[.6#9k}9\˟bez?̞(KU/+=]mƹ] LiQty ur}zxrU IDATG+m![/QaQ9QduJf$ އ||+̺"gJ|-ͷrIcƓ3NOWvDh~qFIQ4*r>z.r8%IcsEW-cĿCH D۩pe̛s_UoݥulY<:b FԷACo34ZtCToR`ʫs$G#`)G'`# Z,1 Ä*`0jA4B06F1J,ԉW^o;:/ŽFJOwwI"c$`ˆiDL]ݭخ⇫qAeDΪC a-y{z[C Ss6\$ς.Y+xοZ|aMA"J!wLW]!jpM7qeqa;uO&%@}Ğ=Lu! @5BI!4ݱ_XV;|;dz6lG1hn>2e w_B RWP( ehvAXڧUU;oLL-\- H+UUUk=usU qu7'XT@Q--#MH=L6d2y ՘8qz8o~Um?WYhnbރҧ ~[ _dp݇Psȃw}K,Amm-;{; WYpGOu]~Z*l7`^Z y9 KM ;} \_U3PsoXF-I= F/w*{/v^~9V :={O>xq뭷矇Dyy9\dzgziK҅#1hܫE+q P>^| >W\GD~ Xz4m dtأ l>=^4 \j"z9{ѿ];:^n=>x=^Q={jC t=Z%Q egnj ϧXOE7.]ЩS\.`\Ae!mFUZTWSE!t$5m$2 .x[HeH Q< v{C|* U=MdW9X^6EY7Lf_t(2# 7zk%V(о&koB݅ygqlܝ~A7jw 5)GD\iL~}Xv-9\'t peCصσnř 42* 6gN]1`92e ={sN|a#uL1@C"edd@ph(|?*l]_ Et=߳Ri=zw\L7]'z5x=ؾOjDQ֥u“O>'[5a\eeO>9t=浑- ~xv۞c'e|gw3PROD!QK}AJ+]^tZ#SQw?[?~@t 8=я<+=knnԩSqcpݱ%Q(p͟ >Yӈs~/">IX]rڟSa;Z%ڶk8o&A82@g 8A~sy<8;@$c>z~߭1oBWoWط^݅7Tbոplѹ3gχ,]n-t p\#Z\!\i{~p/__~8a}tzNlRE;?) |v_ CdeZ_d+[u%A?Gχ2\2"uӦM?wy'ٵ+n݊:JוKwǃ]^oPdE_/<# u}0'w _vTChjxgODWa:oGWfzQWׄB\p77{B7Z `_3t]-?ϵ-qǝزp_n}7Է$^@_Y+|A~Lp` u'{o2S| u :>)ktitjuk]Np|k-2|9(*Ȅ ^)q3%G>?N ;'ǖ ZNz:&2f^g.xvznt >bc7wvw>'@s?bx;EE ƌQ{-бcK}C^Wu}1( 3Xmcf/u/t Y> P׌{nο]ͯ/|]A]M/2v/(jpJZc ``SjCǎze|۷/-[QFF°aЫW/t\|>ᭋ!kd2t< Ϛϕ\|!R=u@ 6]\j%ߋ6&7o['n7 nx46xv{Q'܍ͨoVzԏkjFcc`xیP kr[ U9o $fڵSc((AY!-@0h W瓪cLly.bVKW۩ //ónuਰ zֿ 84{6aj ̌n A 0n姽رf/vCzЌ|U76 O>ظq#:v5kओNRu-0|b<8mqZ<02vI&ՆZo6oތz—Ė-[m\1*3~ <Ԅ{]n#T}9=Ѱs'<2N; }XN.tLɀKk}GqN"AˎR}r/=ͪmգMB!=mw"gm۳T}=;POKZ7ȉ"/̯Zٳg\}ա/^}9szo>\tE_:u/[ץ΅.iCr 0%7x}!9WZqhuqt pzE|Wzܨ?x>uu5o:c`|P- pb <`̘ߠ0cƜA2,S.شi; [.}Vv)x~KR}hoFV@t}^jS&pׂ;!+z π#o`6/Rw)r3FTlb@Bti/}\Qv ? gۄ^١M}}=rrr[-=t!n Em̻ xj|}cԒdtruLu,tt,JNs`}QxWatX]].@x}MLi@vw? 7ٙ_CzGi>uϣ]x+P_dO rt\3Á׋ʃMݡ%n`$jս{w,]}W_}QF!3Sb^̓%89o4,|>N:$QGJN=TTTT`I$]rg߷ ?tMkѳgKXh/|ܗY)=g jӳ}EoVoJgaMaƬw]DyӧOӦM0)cWU8~1C~>O`~^~?C}q9[G*QQCMEEE=DTUաѮ].:wN} 4ַ$Wc&sVTc=[󇅅׉^)"x;KoAntUvNbl! |#?SD"Q]| _AcOcԨQhjjBccl+XtBp8 Ђ>ز7##Fְ(ޭ[X cСH-c<~Eز^n݊N>*t.dff #XzlnnFAAlQѧOÇo5# TR_sIWZggn}S{{-W׺}%J2%Lpxy硶55552lܸJRɏ?J>_`Ŋ8ԱߺukT ZSCy"HʩE]{ pd OQLW;om^{ 5558q"pp@hp8"ZWx n9#p8z}Xz Ν_O?y ꫯt͏c=VxקV=jt{QuȇC^Ĉ9/'p\-/-[p>lͯIy 6*w1b8 CV^;( <8/w*iFDDD[21`DDDD믿`mjGZK&b>R}-?_""""Jqz,"ui/B""""J1Zɦ盒 `DDDD1 Vz/t]PtEQĖG^1Z2lj.OIzT?GKǛ6?DDDĖmۢ<n+^'߆>s7 .~ ݚDɑ3-s3Z(-ZzTq:x{! ^}(锏_/-[˗c@裏д #B78c>rz%P."~ϵ^) %_f>w6b]_beK Q1yWwu#ĉ= [^@[tP9y |䔈GH>xd W'b1cwZrDQwF1|VQS8mCuDDDĖ-`.OjC;6a蓱jyR\6:b+b̿\LT.|>nj[`mڄߞ: 6UT =e"ΏfBEw?c Zo+Q_قWo3.l{ǰq?x惈pي|u8knFQ+ѫ(]Kw:a„3;YCDDDM՗nƍX`FBڵ Wg Q*05#"""2*4N/]DDDDq塚l-y'oWW}KFDDDg `쇬mvBFDD~;Nd0""!@dm @7`L%z=ϙ((9;lDQdgzQ̫=9ʤ%lɝbU] `j$&_5Z1?F֣&e*ܘ!vj|XR2r/5ZjAMfI%riK=}ci'S"B-ͮ)0@TOR#it*-Yi9[ھWVt cZ z'6kԆ=-V=ZOnY9`_byպ~S5'Bj늦t") hfmEoGjj*taֺSsFvYRSh /Cm1Iuj731Z.+`|jٖWf<foOF4{>|c|ŪfDɊoiͷz{\o׬R4?rѯ3:M<Ϫ@|`+5ӪrE˲ழ=IKq5<Ę %T\Io\YZCInVnZG䓩n8#7џAe]De`E)*YuMkUkRF[Zhx~"jҵ|gzUSR@C.XѢe7Ռ3B ]i-Pz[f1 3--U]J-EVosZ-kXFf!Uz1&)уzCnS;H*Y-!h`Lv\V;%j2Vu]_zZ &h[O۲ $jnI{&gUgZzK <*z0Ryfي,fRn5zvLl3/8zcd%fz0o6^7zaVj[u<33P82Մ-#g}jU zBv> =ہ-Izv֣xGIXO ϯcqЌ} "cl3sCYi7v'k0s3w6Q xmxD:LMYZnTQ=ƒpz}O/V) `VHDu70‚A_"z-@rJ3Vס=hU-঎-F>DK*QXy+_ckͤ%E/DtƪCLMHSUU·C#A.딈( i \Dmuas `l+bbkjc$v!/}g|}N/(Y3kY׻ԼFfLOdK獝1y@{/^ŋOL=c̪[䂫PkTbKaƲ猔 9¦JTn^Y#56 DՐ;y,Vf=#y߶4ZFOF[۴̓mHЋ.VSr"1wLO}#,\;n""J{A%;@4Rl5>FF0Fz1 &D(ۑN_ `xHDDɄ"R(ø?K] `c)xlF$ŋ= ӕmoC~ԜʎFjo-u xZkKصH5Z.z|Q"uZ36NKZ=)Oj{̨ s>7`ݭ6D-zPi*Hܵ s :6KYgF.\[M.m!T9!1^ɺۃj^]k:V=J-J|3QmXwKwz]f=JQJ<r-8n0c|.{PޓDD\J?dm2VןHf&jetZl# J!Mu}02`GoV,[Զ#銎~LOYT/% %T bFk+]oZǠ%"i,coL^ `dKSQ;lz[:^g)ŒJ.2z_)?oYd/ `Drj1Sm&EFgcnl}+JFc#X2i:XU&XXN0X `QjJ<D%U?[ᭈRRV2x)I:QK新 錷"4NDd((ajEDD(n&ק9؞(%kK~5Y,%d aѸM<0"Ι"Id3&hq,nb0Q\񬋈(qi1儗8X/#{鰏0JT>c(#J~9f=0e?(~e[Q2#`|ԕjaq:1ފ( oE:ҩ+|眊;j"JM>8"M֭DDDj1eĉbڜEz `dX_Ă;Y/H0" %")<,!$ FV//6}@2cЊ0$>j.)k';f"j->FїInX1aL͖z GkӨTV2lfI+Y/[io `v݈̗]\ѡ-o9;Y"2G*%^QR01?vz FDKE2v?&]WN2hzɼk=Rx$u\w`mӻ"Զ6y7#ֆݔ1딛t3T"2[xkK!AKc4V4eNm7`<>ke*+,5R{ oę3L/Rנ/Yb/%E cu2hK*$(>Nؤ/ɴ vԺﱎORv9%,܉Dy*z"ݢMi0Ң4içjFiڈyhufYE{W݋((:hNma'1G 53ڲj%ZI˙%*7b }J-27؎SF<'*Tu#u640""yR_,FX2w.+ -//3=(Y+~3GBm[[,0"%Μ}W`Unl`Ȇ- cFS0:(!ȝFI;$"Jǥ0"""Rm-ODDDVJĭm"3-cᭈ  "JU [RwZD*?K- `DDDDqFI+ȳB""J6 `(1QRQhρDD (i_^.hER}"CXra#""J2da(ijb+%ފpgs ZDDѭalҎ Eę3c!"jQ^Daw:DD$5y0qgBDON Cvw%iNjQɪ1FDDh_ `dk<#"RFDD¯/Μbl!K^ "Jox+0 ^%xl[㭈(Z5DD }1Qv  a0J8DDDlaR(ػ^ ,.@Aވlx{! UA6r0FD?-27؎SF<סQ[Kr6( OtϒV^^ߞ27vѾd"zWƜvગn Jl""Jl"ҥE,j\QP%Μjxx1x J~(]1QBCOc#"""Y c͸).%"":-`p$"tFcy 1řmoCDDDd[6&m""}sﻃ#öRKxRF(ߢ(ȊnHeZ.ִ `ܗMDDnH#P=Mcv030Rq㑓nKDыnj`falVMU~$"JbF>&q7٤O (1Lxŋ5y\mjYyKO@DD>kK5~XFB9\TЉ8.I3+=nm `v Bj)FhQ1=ǜvYp:1Ql&\+85O;:0s2DDDzevŁ(Z[~ok6)f8IDATvԤ 5jݵ*7$QҲ7(a< f* `<Q 2m̠yN%6 f, `jBUAE͆k>v܅0'c"""(i*N( =V*/[<}K[o|ߒ>1Q=RR)˖qْ>.[reKRyf[ ((}N]|<.6Bd' `{W݋((؛!xlQ^^vBV 468qlVP6W(l5yyvVGWt{gl #w0lx?g¸5@V7gF/`h_r,9{\^zt/|lu0""393 Y(8p-OSOWVş.3 {"Jel#R^^MUIM36UmoOOɃq܅/s瘱x+,F@V^GLuƌ:W[AQ ^""JEl#|sj֖߷`[r-Y3DFDDDg-`7n|l"""3-]4ADDDoQFDDDg `DDDDqFDDDg `DDDDq&y 3 >߬$2?_Dg̠F+_v[oaŊ 'OF׮] 5"+(ފwy'~!pkz5pCQTTT`Æ 5kJKK-a"""d';)ꇯ_~B .5DDD1Ðp8y(u~xuE_{餴}s3p84ݟ p8t˦l{᫡o}T\QoVb㖍zxꩧ` JKK[~o8t,=:!DyCxeie6'xFzvF"WQ?UM剢S!27Jw*--OszQT☂% Áܾ-ڣ1/XC!"+.AETTT_}j.˨n:l[b`G؏la22gl޼ْ%""{ ?HUTT`ݺuX[l =$]7siLՆ;\x㏱r՗ؼ{e4.ytem_ [޾57y?~ G<8= 'u!@ .D/v`szMxਨ/TTTkle+N۶u=0L6UUU?~TYƚ9%""do<3t;ml^2NAĩ߆psAC()`uO'x1\Dч'SnL<~fOk?ǔ'@lƕ;zZ>A N^o `k-CRءCa8F(~ άy#"do8s< }zcܔwyQcqcP6=Ӯ?m*#:HK|ii)͆+C. d:YAV,@U2;dǟ@ˁ8_Dկ ;'=Yߵ Z~+O)--EӉ~\}_.1YZWɣOD1ԋF@mW t8-^bˏ?0͞fMQj3,( 1oǶoƆblsEhߖGO vjX~|xFM[Qށowb??֯Vgο|1?oZz˕/"_WzټuKAqռno (ğ-C/gdo22 G㿳F󡵘ȖnU]9@`=xuN=H5jޛ ؿ-\%]EdƯAUeS7?Ŗ1M/C1vlj)E^?""Xmu-DuDDZPZZ}0 l8n3Ev22ٿ p pQslm` Ur=▞֜^8ŒsCdgwi5=~/dqC| tV8T\w vŕg`GV=%gPڥحuYU9Wu9'eL>%ވ- EI.SX}o.\;4V =󛗣Jߣ,tw}y].FГq2G;ߍAޗ`Pg*ӵ%e0h"YTچm%qXzrٽl4}Ip|rFu<f<>:MX]P?6yȌlrf9s}O,1G2: q]j ;MkxjNN 8pʬ'1m-n5eWUs`p8cA]඗Coa]TGF{&M+҈ln/{w;|;2ׅnDEAAEzr# {uO #|͵1#p{`8{% * |w 7 Z=~jliBK`h/{Fs.+/?j]5ǀꫯFΝnF~f>j+kt L~w8(uyg:ߎx:a߳Eh^!tyl>F%GEޥ 9 ls߹wOq9@w£]!ܰíu#`XW;bK6p_+hp/EÊdS@^ `=?{.Kֲ 镶] <UW]O<CСC1yd}ݘ2e E~xOk% V\?W0 lݲuW_=f=菒;NDj8Pť#nihoއ_xvV")fA0{ٷqKoCq5j.OXATn^`Uއv1"x1Ӫ}oTo vC2"3X?HՓe9_1sׁ[E~3И1W*0LW^zIqѢbдiD3]%СC>9 СCšC~?|ݞgE!0XTG<|xDb<zuK)Kǝu8wP]oV6_d8[;SpDA##N[%\ObaS3bOriyo~iI|)̮Z$>~TQ't~w)m,ZP|' n'L8S&L8S\*A_(Di$Jv#Ly"M|!L{!L{K|?;E#Q'[-]2`6f:m>qHvNzPwPmNkNjOkQgxTYYTVTWVRVVQVUQTTQUVQRSFNLALC6P=,U;&\<&h;!{44>IT#c,x9ˢ8 3zΔĎ׷Э{̢uşk___gg${>yxy~~xurhgffe^WTSPKGD=8}:=>>;$1@@ACEFHJKMOPQSUUWXY[\^_`dkr~腷扺ژĚȾԿ_:XtRNSVN%IDATx{pǽ5U.!DV# SI66H(BTʥnu 5$΍Or9I||9"1.h`tЪX1z~Lh4] J;ӟٙ߯;Ǟŋ[ؓ{>Ň%xݤLÇ@3KSAYe$2(_c-;U}uŴɫ~mrּ܃o,fj!͂_W{.\[٥Gъ:z:3-OY_zho0j|h'ߧaPK?~V=KH;*'E8qa} #x)p\GS^L;WWC;تX:8$]ByeQ^b|>;r8+=xͧ/[f]`rJ %ƫ$~Cj)u؉Sq`\t_[X<'Gs,srmK\%娖’R-`'}sY8!y2+ cDz?[ ,{ \ҁe=3*$̊Ѥ:D`NTW_O}#iiP.}r!M1dz}r\mv1sc:@S2^KY KZN"˕#G(1×>bʳ=/1^9+n.zyr6r^٥:`bQ^LJYkpx3眏s[S+  Qqux^S_^b|7~l @ xFvv2c-@eU`ٖGϩf [*m풧T3D-_zCI5mcܢ"hy!F@o|$ Axx7>l  J`#ypKo|m >zڙ@_;/~r[<'>sxك^^ @ h"WuxU{ C3&=Px jm] Pxک5j^[3Y4axu«N-󭭩UDo{u뚡E+/~۸cȪ׆`צbGR  ,tEi'5%TA %p[6Ũ ':ʻòyvP.vbGɋv.bUO k0yVļ|Ԡ;mǢUafƆ#uvmQyJ+@ ][}:'5%4]`ԆK"6*EC;]WO!Z:\X&W;-`h DR0y]`V fPx5کq7v^Wb+t^!«Ď%Px1Sx/ ?jǠ1L1{ e{6x/@cg x׋;L ~/0efM~2X3Dm;b ,0/3sXg  BuƎ;tM!KoPiP^xVq)MQxWdeDP ;v(Es a!#^ǟ _h ;f٨Cע_yz0;~aCa{]Ѵ/84_)/A-HQh^"fJ&Ǖ?dGEu!~[WqK!#P=W%ŋ::_ qBbF/,y@j'y巶&w/ظ80[L7D- 5nPR+$H1R!Ѵ4)c'&L~^շtR }#[Wŕ?CnQ_o6.VRC#/RDjC<@|-uܘlkN@be&Tyx;[%ry؂#bv 5KxB_8r!f`>^*ގke.|6Rv\RV:=`#ac/ow2H㰱Jh2Y7ccu> @ x^J>׫bpW xxGԣ ɰ2^1eՅPPr?^t>qoL] M gq!,>9eI0ӑe]}B i5."-)g:h,7Z9K[&o$ ɿZ9ȝõ%rOh[ބ QI#|,T %#-(-|_:.dZo[6o=wfK*n]9ήg&nLywS~0g^Isn`7(­vgC0(bQ>Es~VU}[kJ(^v*xivXKfmW® m 'o-卹o9ɢZK5+P/1 \Kp_Lb_za,{8 gbRHزnhQSlqNmK9_jGT?:6H~e ce 9iCr|ozJ?=3Χ `X#yiMٖotMY7g{H!v?.x34jqBB–@Ա}Z~aV9VUɅi/Y묱cћ7ž=3Ǵ`OG5^~m;x޷|-HH5 -7zd9|%Ptxo}ږ3hI9=tdK95s ( y\DJSW[?/O#,4:yC#4z}Cd8JJyՃ Պm~ZֿC4tqjnпżv25}ج/%Mncg/m,z3^r 6& ".)/A G?7To&ߓKT%E'JU UPRpǣ>e+b `fҫHB4K@ yR|8%li\i[\!6e%jB,ڶ9%m%P*{rQխW"#-hÜ"=+4*z{63^tJyJ41V}ۋJot`[7 (C~zIg|@b|iÜb!ÇOm(e8z)"IdS^\V-iG^!/^þzڱM Uw_iߗ$`\&yIъ] gLa^/zԌ}(Rʬ `l{ћ6ڹNH@2c?Cj^}A:^J2R~dLi`^wyi $:N(ڴڣ7m6Iơ+#ғF&+`̸=crJٿng_{mћI%v/}5_j^L&/Mv%_0[jL{q3 $F^E͗jz E$Zd&xzX X/&WM[ y CNVr_F֕h,^7%/F}K&#ǾDi;4n>Ր#Ee49u~L^L/lKj ihSI]5$ k~)TvܕN(xi+xSc,^_npؓWIhh/nAzzwfH^ BG]2I}4/sx'H:olKN=}^}ݫ 5~!MF15l0ˆq1وˆfXUWyە1GLŒ׈1u1AE_(a ` ^tcXbfX&KɬǰF ` s]N{*F1ݖcv~I4 le\1vo/f[丽?F y%&o4$ɊFk$ˉfxNbcrnj3ֵFD7N,wc?nS`bjUc&Ŷl/YmQ^ Jb1_dӭZkfcF7K-ìPb*$f@Zf#xI6xAo D=:Skeu&f S`jm+V/Y$I$%Z+f뱸>et$T!k ZhrluD?_guta܏Q x/$Orl6%~ƫ3/^ @ xًV >T@v^ ^ joTWDG #+e]D_Dvo4^ꉤhJY"yjFSʺ.ꍦu]k\f:N%"KkΕu|^:usԪN#k[ 5{::^CmŽQ:~eGwR?я :wutf д.AR}Q7]R_m+!sn;`p}]xм.[:!֞V2׼] *֔# i7oJ5"ծSh~DA'qI2D?.N_(@`,ͬ.Nm@g:g^R/BpR}deXHWC/y# GD[~t9VfoK>/n/[=jEEXlnj4M nݨnxgܼfʌ̐ʌ23H3jfOC3&Z2#9O rcC$qDd|E>ssdTJwp||:k|huIa򙛣|P@]"y$ _<Ƴy~I&yʇ( N:"+OJWO$6Iq@?F U/ }#CeapIȡA_gvv|M q>O,h;7/N/c}޼~Z*\S3p8XTOzyޝH듐)$Hn*|K}aYҥϟ?{Nz7d|o yVd../>>xnx))6:>̋PKao]{M>ddbFS&3]83*32~ 5}ehGy>\D}eiO!L<&![{x?M:Dr}lkZ3OqZ0&Iļ M@eު(3jf,}:)qP)M|zU9C ADo=|c$3ͣoߒ+6TJ5ea"'\ I7~bd1og1OԦQfz ϰV>9p>TrS|>9tQ eǂ B zXW|3\h5>AxXb?01`o&~Z?06fxb4P?̓>47Of@'N}j-<T/7~ Mi2=ʁ퓏r6U^2 e nC|PJOF >P8X/ Z:C\Tl'>ӄRPK,~N.!ջ!.뜏)2鳸PU2[( mE ށe>&gH|B(b2DXIȐ|s Ilz^P$ljT¾3Ct4Ws ZQK=sA`/$/O@ }{q @ `k@8;}M-?]{f^؉/i ȅkL]FWGUPt{OC|s-٣woEXIE,nC*(G@T<쬩.!@Qg ̬t17$awRAG$^U#Zfdŝ&Vռ$awR%&fڱl;.GFz,/IXd\TSB)6-4+{v|$/IXd# [n^BStD?[Ș x251xI"svJo DT%K咟tJ'4eO gPj~)&iу:TA y+, $4Se.X/+ HW'p-ziv@HY:u:&@HΌ[ xof@0Љ[ O    H׀G\ @@:s䚉mohsKқWx jlp7Wgs@Tnھu x<Ozka)DaYQJ|S ÓWYH)-^ 3 nE?`tcKكer[PǺ']6MG'x<uq31#J=lWɀ㟯m&6cӌ 7FR1قu->t9F)AOu3uhLQ59H"IgهnQ$Q\rr{غaeOcޙ"PP$%@RdE'H ưL'm#svg\&6E`WGI$4^7t h\%w؃!.뜏Ga!}$ɴD%7  i8UӃB>jB6@ T(ws5JZ3#K{,&/+eFHf7>cKb70u[o P|UT~jr}-S"bbs1ç41n5h]7@ȹ4[aoZi,%)- c[ڹclikuM 3s!cC(Tޒu_ _#W[krKJn䖦z EqԥpժzTqsu[Z3fܳdݿփ R4Mja&xK;A{Ԃ-QuKUZzn*X׋Hjw>ѻ-wj)N.QtYTD I±\&f/J:XK=@M@գo@(- f|VV`% :yN|n1|y>yw/j6ꍖ6.1|}ᅮt/j'+jfТn- zu (fg";avPz͎cH ~ġD> X?jv@ccVA",;TnuZ+U[*8IPw|K' 1ޘA].gQI~)MYmQ??+Yp:R΢[p3aA[BY@>A4SiBv1zVss-P,rOݱfD+!Nҹ!.#Ybf̚P#.,{}be`[،̤j{gtJ3c0TGe1 MWxZZm/ >_Zo^Fiu0 tjKi3t @ 68U:-WQ[܀\7#Ƚe.Eߡ]$"mOv _ MzsP)\uAڃA2@&m:4xqMV"-EDn,uI$y_+nɱNΓ)K  ɀ|ᰏ9]VWx7ލ~!I!Q*&׬Hޕ@)@ӄ䪝6Eb{k4 @RQ>S9DAÂ.TODF3RN2rWޯjge{k ?7 @  @ @y:9:AH'@bW5S6 -/(S43HkRS@ :Uy-:`IGe {akk xwwnx4n@ZZbτ.R@5+r/)+х>7y"tH@&Ʒ\z 7Q+хfgMvP3fӪ*Ѯ5s.bbB7wX):jj _9*xEb M BxZ_Μ& y"P# !@mt䳸{[?-q7wIx:7B}&wrG5Igqb"tp:{:@40BhP# h=4T zTh5@'@ @ : R+9PJ2IG y'l(O#!OA#?򮌉0D ;X <IENDB`kst-2.0.3/docbook/kst/Screenshot-kst-eventmonitor-loggingsettings.png000644 001750 001750 00000006452 11544160206 026476 0ustar00synthsynth000000 000000 PNG  IHDRh'j;PLTEōvtsrnkihcbbba[ZZZZZZYVSRRRRRRRRQNKJJJJJIDBAAAAAAAA@:9999::=DIORRQNMJFCA=73~3|6z8z8w6r5n4m7n9o(-5"/':ltRNSdh IDATx?hU2R1.\P : 0#`V1΅" * 5nԨp H@ ba+#]aα nbnM޿yvx|{{g~4;NLN 皜lmrD%ȹZ/&W?JZ,NP^JNl=Y,NO O^Q|r'M;ʻc3Y<@/7)Z`f8i9;ovc=X'6-Ҙ=z@ Ƌ85'@>}(R1hFkoޑ9<$Bno%h5Gh]rBgͪlKӑ:&8;kN c3 TqWcbHu.x#7<x=Pع8̦*G47\o'~-Moֱ4 '>#pzX^b)aa\zš$gMZna`QGg5zK4[" +[>WݽMdqZZA/-9W׫<r^z]l& z%%u=,N#z%@/B9ur/hhh!hhhhhhhhhhhhhhhhhhhhhhhhB='uA} 4@C c c?c ɥc|2zitI^R62(}&Ji3Z}xpnW]2 $R)GL CqA_2(K:h$Z4H2Sr1}9gNK65c6vqp[F@E" Z:AK~UFk_$1EkFw\vLK햎q]Lftx֡YG!:0:uAIʘetz⍏ t:蛑JST:7h\pn$@f4@C @4@C @rE% h /Rj+݇jgP!idB3u< %xE@*Ral- h.tvS@(IާkS]۽ FpL\A6)wӿz5 #sMt۪AbYg4&]ѝAaF)I35Hp&tx99㼸_@[i¼6FpWhhh:zNsϹY5Kpڧ$;w娻NIϗvѹf(F!kCpbt{NA_e <% 'q}!.vBRvk8*4'hu@bnϤV)2gF#98:-Ll)%gGv "$7j_~|8 k1h{/كCd`# _L"ÞD dņuM4iG_{ЉP@_kF2jӇ\wSV9נ_}HTA\8%h nA_m6JB{K)bЅ(Đ>5VT+^'F"uȤ / UOR=R )Dv3⓻mXÉ(jHۥ`f4YA4ۋAJ='fiƜMSU8ד.&g}_jLܠ1 9J=wz:O_8}}_!81K;зsc7z}-Q 0gx{E o q< hhhhh%\d A7D/IENDB`kst-2.0.3/docbook/kst/creatingplugins-chapter-new.docbook000644 001750 001750 00000065235 11544160206 024077 0ustar00synthsynth000000 000000 Creating Additional Plugins &kst; has a simple and standardized interface that facilitates easy creation of additional plugins. In addition to detailing basic requirements for plugins, the following sections describe how to make use of pre-written header files to create certain types of plugins. Creating a Basic Plugin A &kst; plugin consists of two files—a KDE desktop service file and a shared object file. The KDE Desktop Service File The KDE desktop service file provides information about the plugin to the &kst; plugin loading infrastructure. The following is an example of a KDE desktop service file for a &kst; plugin: [Desktop Entry] Encoding=UTF-8 Type=Service ServiceTypes=Kst Data Object X-KDE-ModuleType=Plugin X-KDE-Library=kst_FOO_plugin X-Kst-Plugin-Author=FOO Name=FOO Plugin Comment=The FOO algorithm for Kst. Generally, you can use the example above as a template and modify the FOO entries to fit your plugin. As can be seen from the example, the desktop service file consists of a series of key value pairs. The ServiceTypes entry should be left as seen above. This key indicates that the plugin inherits the KstDataObject class. See the API documentation for the interfaces this class exposes. The X-KDE-Library key points to the shared object file that implements your plugin. Do not include the shared object's file extension. Once you have completed the desktop file, save it as [X-KDE-LIBRARY].desktop, where [X-KDE-LIBRARY] is the value of the key in the desktop file. The Shared Object File The shared object file contains the actual functionality of the plugin. The following are the requirements for the shared object file: The object must inherit the KstDataObject class: #ifndef FOOPLUGIN_H #define FOOPLUGIN_H #include <kstdataobject.h> class FooPlugin : public KstDataObject { Q_OBJECT public: FooPlugin(QObject *parent, const char *name, const QStringList &args); virtual ~FooPlugin(); virtual KstObject::UpdateType update(int); virtual QString propertyString() const; virtual KstDataObjectPtr makeDuplicate(KstDataObjectDataObjectMap&); protected slots: virtual void _showDialog(); }; #endif The following is an example of the shared object file source code for a simple plugin: Compiling the Plugin If you are using &gcc; to compile your plugin, simply compile the object file: cc -Wall -c -o myplugin.o myplugin.c -fPIC -DPIC and then create the shared library: ld -o myplugin.so -shared myplugin.o The resulting *.so file and *.xml file must be put in the same directory. When you use &kst;'s Plugin Manager to load the XML file, it will automatically look for the shared object file in the same directory. Creating Linear Fit Plugins To create a linear fit plugin, you could implement your own fitting algorithms and output the appropriate vectors. However, &kst; already comes with header files that make it easy for you to implement linear least-squares fit plugins by just providing a few functions. This section will describe how to take advantage of these files. Header Files Two header files are provided for performing linear fits, linear.h (for unweighted linear fits) and linear_weighted.h (for weighted linear fits). They are both located under kst/plugins/fits/ in the &kst; source tarball. To use these files, include only one of them in the source code for your plugin: #include <../linear.h> or #include <../linear_weighted.h> (by convention, we will place the source code for the plugin one directory below where the header files are). Implementing Required Functions Given a general linear model: where y is a vector of n observations, X is an n by p matrix of predictor variables, and c is the vector of p best-fit parameters that are to be estimated, the header files provide functions for estimating c for a given y and X. To provide X, the following function needs to be implemented in the source code for the plugin: double calculate_matrix_entry( double dX, int iPos ) This function should return the value of the entry in column iPos of the matrix of predictor variables, using x value dX. This function will be called by linear.h or linear_weighted.h. The implementation of this function depends on the model you wish to use for the fit, and is unique to each linear fit plugin. For example, to fit to a polynomial model, calculate_matrix_entry could be implemented as follows: double calculate_matrix_entry( double dX, int iPos ) { double dY; dY = pow( dX, (double)iPos ); return dY; } Calling the Fitting Functions Once the appropriate header file has been included and calculate_matrix_entry has been implemented, call the appropriate fitting function included from the header file: kstfit_linear_unweighted( inArrays, inArrayLens, outArrays, outArrayLens, outScalars, iNumParams ); or kstfit_linear_weighted( inArrays, inArrayLens, outArrays, outArrayLens, outScalars, iNumParams ); Each function will return 0 on success, or -1 on error, so it is a good idea to set the return value of the exported C function to be equal to the return value of the fitting function. To maintain simplicity, the code for the plugin can simply pass the arguments given to the exported C function to the fitting function. Note, however, that inArrays must be structured as follows: inArrays[0] must contain the array of x coordinates of the data points inArrays[1] must contain the array of y coordinates of the data points inArrays[2] only exists if kstfit_linear_weighted is being called, and must contain the array of weights to use for the fit. The easiest way to ensure that inArrays is structured correctly is to specify the correct order of input vectors in the XML file for the plugin. iNumParams is the number of parameters in the fitting model used, which should be equal to the number of columns in the matrix X of predictor variables. iNumParams must be set correctly before the fitting function is called. After kstfit_linear_unweighted or kstfit_linear_weighted is called, outArrays and outScalars will be set as follows: outArrays[0] will contain the array of fitted y values. outArrays[1] will contain the array of residuals. outArrays[2] will contain the array of best-fit parameters that were estimated. outArrays[3] will contain the covariance matrix, returned row after row in an array. outScalars[0] will contain chi^2/nu, where chi^2 is the weighted sum of squares of the residuals, and nu is the degrees of freedom. outArrayLens will be correctly set to indicate the length of each output array. Ensure that the specified outputs in the XML file match those that the exported C function returns (which in most cases will simply be the outputs returned by the fitting function). Example The following is an example of the source code for a linear fit plugin. /* * Polynomial fitting plugin for KST. * Copyright 2004, The University of British Columbia * Released under the terms of the GPL. */ #include "../linear.h" double calculate_matrix_entry( double dX, int iPos ) { double dY; dY = pow( dX, (double)iPos ); return dY; } extern "C" int kstfit_polynomial_unweighted( const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]); int kstfit_polynomial_unweighted( const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]) { int iRetVal = -1; int iNumParams; iNumParams = 1 + (int)floor( inScalars[0] ); if( iNumParams > 0 ) { iRetVal = kstfit_linear_unweighted( inArrays, inArrayLens, outArrays, outArrayLens, outScalars, iNumParams ); } return iRetVal; } Creating Non-linear Fit Plugins &kst; provides header files designed to simplify the creation of non-linear least-squares fit plugins. The following sections detail the use of the header files. Header Files and Definitions The non-linear fit header files are located in kst/plugins/fits_nonlinear of the &kst; source tarball. The files are named non_linear.h and non_linear_weighted.h for unweighted and weighted fits, respectively. To use these files, include only one of them in the source code for your plugin: #include <../non_linear.h> or #include <../non_linear_weighted.h> (by convention, we will place the source code for the plugin one directory below where the header files are). As non-linear fitting is an iterative process, you must also define the maximum number of iterations that should be performed. The non-linear fitting algorithm will stop when at least one of the following conditions is true: The maximum number of iterations has been reached. A precision of 10-4 has been reached. In addition, you need to define the number of parameters in the model, as it is not passed to the fitting function explicitly. To define these two values, include the following at the top of your source code: #define NUM_PARAMS [num1] #define MAX_NUM_ITERATIONS [num2] replacing [num1] with the number of parameters in the model, and [num2] with the maximum number of iterations to perform. Implementing Required Functions To use the header files for non-linear fits, you must provide the function to use as the model, the partial derivatives of the function with respect to each parameter, and initial estimates of the best-fit parameters. To do this, three functions must be implemented. These functions are described below. double function_calculate( double dX, double* pdParameters ) This function calculates the y value of the fitting model for a given x value dX, using the supplied array of parameters pdParameters. The order of parameters in pdParameters is arbitrary, but should be consistent with the other two implemented functions. For example, for an exponential model, function_calculate could be implemented as follows: double function_calculate( double dX, double* pdParameters ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dOffset = pdParameters[2]; double dY; dY = ( dScale * exp( -dLambda * dX ) ) + dOffset; return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) This function calculates the partial derivatives of the model function for a give value of x dX. The partial derivatives should be returned in pdDerivatives. The order of the partial derivatives in the array pdDerivatives should correspond to the order of the parameters in pdParameters (i.e. if pdParameters[0] contains the parameter lambda for an exponential model, pdDerivatives[0] should contain the derivative of the model with respect to lambda). void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) This function provides an initial estimate of the best-fit parameters to the fitting function. The array of x values and y values of the data points are provided in pdX and pdY respectively, and the number of data points is provided by iLength. You can use any or none of these parameters at your discretion to calculate the initial estimate. The function should put the calculated initial estimates in pdParameterEstimates, with the order of the estimates corresponding to the order of the parameters in pdParameters of function_calculate and function_derivative. Keep in mind that the initial estimate is important in determining whether or not the fitting function converges to a solution. Calling the Fitting Functions Once all the required functions have been implemented, the fitting function from the included header file can be called: kstfit_nonlinear( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); or kstfit_nonlinear_weighted( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); depending on whether you are implementing a non-weighted fit or a weighted fit. The function will return 0 on success, or -1 on error, so it is simplest to set the return value of the exported C function to be equal to the return value of the fitting function. To maintain simplicity, the code for the plugin can simply pass the arguments given to the exported C function to the fitting function. Note, however, that inArrays must be structured as follows: inArrays[0] must contain the array of x coordinates of the data points inArrays[1] must contain the array of y coordinates of the data points inArrays[2] only exists if kstfit_linear_weighted is being called, and must contain the array of weights to use for the fit. The easiest way to ensure that inArrays is structured correctly is to specify the correct order of input vectors in the XML file for the plugin. After kstfit_linear_unweighted or kstfit_linear_weighted is called, outArrays and outScalars will be set as follows: outArrays[0] will contain the array of fitted y values. outArrays[1] will contain the array of residuals. outArrays[2] will contain the array of best-fit parameters that were estimated. outArrays[3] will contain the covariance matrix, returned row after row in an array. outScalars[0] will contain chi^2/nu, where chi^2 is the weighted sum of squares of the residuals, and nu is the degrees of freedom. outArrayLens will be correctly set to indicate the length of each output array. Ensure that the specified outputs in the XML file match those that the exported C function returns (which in most cases will simply be the outputs returned by the fitting function). Example The following is an example of a non-linear fit plugin that performs a fit to an exponential model. /* * Exponential fit plugin for KST. * Copyright 2004, The University of British Columbia * Released under the terms of the GPL. */ #define NUM_PARAMS 3 #define MAX_NUM_ITERATIONS 500 #include "../non_linear.h" void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates ) { KST_UNUSED( pdX ) KST_UNUSED( pdY ) KST_UNUSED( iLength ) pdParameterEstimates[0] = 1.0; pdParameterEstimates[1] = 0.0; pdParameterEstimates[2] = 0.0; } double function_calculate( double dX, double* pdParameters ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dOffset = pdParameters[2]; double dY; dY = ( dScale * exp( -dLambda * dX ) ) + dOffset; return dY; } void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) { double dScale = pdParameters[0]; double dLambda = pdParameters[1]; double dExp; double ddScale; double ddLambda; double ddOffset; dExp = exp( -dLambda * dX ); ddScale = dExp; ddLambda = -dX * dScale * dExp; ddOffset = 1.0; pdDerivatives[0] = ddScale; pdDerivatives[1] = ddLambda; pdDerivatives[2] = ddOffset; } extern "C" int kstfit_exponential(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]); int kstfit_exponential(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]) { return kstfit_nonlinear( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); } Creating Pass Filter Plugins &kst; provides header files to simplify the implementation of pass filter plugins. The use of these header files is described below. Header Files The pass filter header file is located in kst/plugins/pass_filters of the &kst; source tarball. The file is named filters.h To use this file, include it in the source code for your plugin: #include <../filters.h> (by convention, we will place the source code for the plugin one directory below where the header files are). Required Functions The filters.h header file contains a single function that calculates the Fourier transform of a supplied function, applies the supplied filter to the Fourier transform, and then calculates the inverse Fourier transform of the filtered Fourier transform. To supply the filter, the following function needs to be implemented in the source code for your plugin: double filter_calculate( double dFreqValue, const double inScalars[] ) This function should calculate the filtered amplitude for the frequency dFreqValue. inScalars[] will contain the unaltered input scalars for the plugin, specified in the XML file. Most likely inScalars[] will contain cutoff frequencies or other properties of the filter. For example, to implement a Butterworth high-pass filter, filter_calculate could be implemented as follows: double filter_calculate( double dFreqValue, const double inScalars[] ) { double dValue; if( dFreqValue > 0.0 ) { dValue = 1.0 / ( 1.0 + pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) ); } else { dValue = 0.0; } return dValue; } Calling the Filter Function Once the required filter_calculate has been implemented, the filter function from the header file can be called: kst_pass_filter( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); The arguments supplied to the exported C function can usually be passed to kst_pass_filter without modification. However, there are a few restrictions on the arguments: inArrays[0] must contain the array of data to filter. inScalars should contain the filter-specific parameters to be used by the filter_calculate function. After the function call, outArrays[0] will contain the filtered array of data, and outArrayLens will be set appropriately. The kst_pass_filter function does not use outScalars. Example The following is an example of a pass filter plugin that implements the Butterworth high-pass filter. /* * Butterworth low pass filter plugin for KST. * Copyright 2004, The University of British Columbia * Released under the terms of the GPL. */ #include <stdlib.h> #include <math.h> #include "../filters.h" extern "C" int butterworth_highpass(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]); int butterworth_highpass(const double *const inArrays[], const int inArrayLens[], const double inScalars[], double *outArrays[], int outArrayLens[], double outScalars[]) { int iReturn; iReturn = kst_pass_filter( inArrays, inArrayLens, inScalars, outArrays, outArrayLens, outScalars ); return iReturn; } double filter_calculate( double dFreqValue, const double inScalars[] ) { double dValue; if( dFreqValue > 0.0 ) { dValue = 1.0 / ( 1.0 + pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) ); } else { dValue = 0.0; } return dValue; } kst-2.0.3/docbook/kst/tutorial.docbook000644 001750 001750 00000101514 11544160206 020320 0ustar00synthsynth000000 000000 Barth Netterfield
    kst@kde.org
    Rick Chern
    kst@kde.org
    2004 The University of British Columbia
    The &kst; Tutorial Welcome Welcome to &kst;! In a few minutes, you will be on your way to exploring the rich features of this plotting and data manipulation package. Here are just some of the tasks you can accomplish using &kst;: Quickly plot multiple graphs using only the command-line. Analyze data using an extensive set of tools including histograms, power spectra, and custom equations. Effortlessly zoom in and out of interesting areas of plots using either the mouse or keyboard Monitor live streaming data using &kst;'s real-time plotting capabilities. This tutorial covers the basics of installing, running, and working with &kst;. It is based on the &kst; Quick Tour by Barth Netterfield. You are invited to further investigate any features at any time. All features are documented in the rest of this Handbook. Starting &kst; from the Command-line A common use of &kst; is to quickly produce plots of data from the command-line. This method of producing plots requires almost no knowledge of &kst;'s graphical user interface, yet produces immediate, useful results. This tutorial uses a demo package of data files which are installed with &kst; in $KDEDIR/share/apps/kst/tutorial, where $KDEDIR is the location in which &kde; is installed on your system (you can find this using the command kde-config --prefix). If you have a version of &kst; older than 1.1.0, you can find the tutorial data online at http://omega.astro.utoronto.ca/kst/tutorial/kst_tutorialdata.tgz. Download and untar the package, and change to the resulting directory: tar -zxvf kst_tutorialdata.tgz cd kst_tutorialdata To obtain an overview of all available &kst; command-line options, type: kst --help A syntax description and list of commands similar to the following will be displayed: Usage: kst [Qt-options] [KDE-options] [options] [Files] Kst: a data viewing program. Generic options: --help Show help about options --help-qt Show Qt specific options --help-kde Show KDE specific options --help-all Show all options --author Show author information -v, --version Show version information --license Show license information -- End of options Options: -F <dataFile> Specify data file: used to override a kst file default [|] -y <Y> Field for Y axis (multiple allowed) --ye <equation> Equation for Y axis (multiple allowed) -e <E> Field for Y errors (multiple allowed) -x <X> Field or range for X axis [INDEX] --xe <X> X vector for equations x0:x1:n [INDEX] -p <Y> Field for power spectrum (multiple allowed) -h <Y> Field for histogram (multiple allowed) -r <f> Sample rate for power spectrum [60.0] --ru <U> Units for psd sample rate [Hz] --yu <U> Units for y vectors [V] -l <P> Length of FFTs is 2^P [10] -f <F0> First frame to read [-2] -n <NS> Number of frames to read [-2] -s <NS> Number of frames to skip each read [-1] -a Apply boxcar filter before skipping frames -m <NC> Separate plots arranged in <NC> columns -d Display as points rather than curves -g Provide a legend box --print <file> Print to file and exit [<none>] --png <file> Save as a png file and exit [<none>] Arguments: Files Data files (if -y given) or *.kst file &kst; specific options are listed under the Options: section. Where appropriate, default values are indicated with square brackets at the end of the option descriptions—these values will be used for any unspecified options. We will first take a look at the ASCII file gyrodata.dat, included in the demo package. ASCII files are one of the many file types &kst; is capable of reading. In ASCII files, data is arranged in columns, with each column corresponding to a field, and the column numbers (beginning with 1 from left to right) corresponding to field names. This particular ASCII file contains 3 columns, and thus has field names 1, 2, and 3. To produce a plot of the first column, simply type: kst -y 1 gyrodata.dat All the data in the first column will be plotted: Note that no field was specified for the X axis of the plot, so &kst; used the default INDEX vector, as expected. The INDEX vector is a special vector in &kst; that contains integers from 0 to N-1, where N is the number of data values in the corresponding Y axis vector. Close &kst; by selecting Quit from the File menu, or by typing CtrlQ. gyrodata.dat contains 20000 frames, so you may wish to only look at a portion of the data. To only plot 10000 frames starting from frame 7000, type: kst -y 1 -f 7000 -n 10000 gyrodata.dat One of &kst;'s strengths is its ability to plot real-time data. Imagine that new data was being continually added to the end of gyrodata.dat. In such a scenario, it would be useful to only plot the most recent portion of the data. To plot only the last 10000 frames of gyrodata.dat, enter the following: kst -y 1 -n 10000 gyrodata.dat If gyrodata.dat was being updated, the plot would continuously scroll to display only the last 10000 frames. Instead of directly reading an input file, &kst; can use ASCII data from stdin as a data source. To specify stdin as an input, simply enter stdin as one of the filenames. There are many uses of this capability, such as using &kst; as part of a sequence of pipes: cat gyrodata.dat | awk '{print $1 + 2}' | kst -y 1 stdin The above command uses awk to add 2 to column one of gyrodata.dat before piping the result to &kst;. Note that the description of the option states that multiple instances of the option are allowed. This allows quick plotting of more than one curve, or even more than one plot. To plot all three fields in gyrodata.dat in separate plots, enter the following: kst -y 1 -y 2 -y 3 -m 1 gyrodata.dat The option specifies that separate plots should be used instead of one single plot, as shown below: A Quick Tour of the Data Wizard While using &kst; from the command-line is fast and convenient, there may be situations in which it is easier to import data from the graphical user interface—for example, if you already have &kst; open with other data loaded. Or, you may simply prefer using the graphical user interface. Becoming familiar with both methods of importing data will allow you to make more efficient use of &kst;. The Data Wizard provides a quick and easy way of creating vectors, curves, and plots in &kst; from data files. To launch the wizard, select Data Wizard... from the Data menu or click the button on the toolbar. You will be prompted to select a data source. Browse to the gyrodata.dat file used in the command-line examples and click Next. The following window will be displayed: Data Wizard Screen 2 Data Wizard Screen 2 The fields available in gyrodata.dat are listed to the left. You may filter the list of highlighted fields by entering a string to match (wildcards such as * are supported) into the text box above the list. Check the boxes for the 1, 2 and 3 fields. The Data Range section is used to specify the range of data to read from the selected vectors in the input file. The following discussion assumes knowledge of frames. In brief, a frame is simply a number of data samples, and each data file is composed of a number of frames. For a detailed description of this concept, see . Start, Count from end, Range, and Read to end Using these four settings, the lower and upper boundaries of the data range can be set. As an example, select Count from end and enter 10,000 for Range to read only the last 10,000 frames. If gyrodata.dat was being updated in real-time, subsequent additions to the end of the file would be read. Read 1 sample per N frames and Boxcar filter first In addition to the lower and upper range boundaries, the samples to read from the selected range can be set. If Read 1 sample per N frames (where N is the value entered) is not selected, all samples in the selected range will be read. Alternatively, frames in the data file can be skipped by selecting Read 1 sample per N frames For now, deselect Read 1 sample per N frames. Power Spectrum and X axis settings can be specified within the Plot Types section. XY, Power Spectrum, and XY and Power Spectrum Select XY and Power Spectrum to produce plots of both the data itself and its power spectrum. For more information on the options available for power spectra, see . X Axis Vector The vector to be used as the independent vector for the plots. You may select a field from your data file, or the INDEX vector. Since gyrodata.dat does not contain an X axis vector, leave the selection as INDEX. The FFT Options subsection in the Plot Types section is available only if a power spectrum is to be plotted. This tutorial will not deal with the details of power spectra, so use the default settings for this subsection. Once you are satisfied with all the settings, click Next to advance to the next window. Data Wizard Screen 3 Data Wizard Screen 3 From here, you can change general plotting settings. Most of the settings are self-explanatory. Select 1 new plot per curve for Curve Placement and In new window for Plot Placement. This will place all six plots (three curves and three power spectra) in the same window. Once you are satisfied with all the settings, click Finish and the plots will be generated: The Generated Plots The Generated Plots Generating these plots took a bit of effort, so we should save the current &kst; session (it will be used in the next section of this tutorial). Select Save As... from the File menu, and save the session as mykstsession.kst: Saving a KST session Saving a KST session Saving a &kst; session saves all the plots, data objects (you will learn about these later), and layouts that exist at the time of saving. Once the file has been saved, you can exit &kst;. The Basics of Plot Manipulation Now that you are comfortable with creating plots in &kst;, we can explore some of the plot manipulation features available through the &kst; graphical user interface. Start &kst; from the command-line with the mykstsession.kst file you saved earlier: kst mykstsession.kst All the plots you created earlier should now be loaded in &kst;. Examine the plot with the y axis label of PSD [V/Hz^{1/2}]. To take a closer look at the plot, right click on it and select the Maximize menu item, as shown below: Maximizing a plot Maximizing a plot The plot is now maximized within the current window. Note that the high x end of this plot is almost completely flat, so it would be useful to view only the area of the plot that looks interesting. To do so, make sure you are in XY Mouse Zoom mode (select XY Mouse Zoom from the Plots menu, or click the toolbar button). Then, simply drag a rectangle around the interesting-looking area. Note that the coordinates of the mouse cursor are displayed in the lower right corner of the &kst; window (if they are not, ensure that Show Statusbar is checked in the Settings menu). The plot axes will change to zoom in on the selected area of the plot. You may notice that there is a peak at the left end of the power spectrum that extends beyond the new upper y axis limit. Suppose that you wish to view the top of this peak. Right-click on the plot and select Up from the Scroll submenu. The plot should scroll upwards. Of course, it is most likely easier to use the shortcut key associated with the menu item; this is true for most of the zooming and scrolling functions. In this case, the shortcut key is Up Arrow, so the quickest way to scroll upwards would be to hold down the Up Arrow key. To return to maximum zoom at any time, right-click on the plot and select Zoom Maximum from the Zoom submenu (or type M, the shortcut key associated with Zoom Maximum). Restore the size of the power spectrum plot by right-clicking the plot and unchecking Maximize. Now look at the plots with y axes labeled Column 2 and Column 3. These are plots of the pitch gyro and roll gyro, respectively, from the 1998 BOOMERANG flight. Since these two plots are related, it can be useful to zoom and scroll them simultaneously. Click on the squares located at the top right corners of the two plots. They should turn dark in color to indicate that the two plots are now tied together: Tied Zoom Tied Zoom Before we try zooming in, we should delete all plots other than the two we are working with. Select Layout Mode from the Plots menu or click the toolbar button. For each plot other than the two we want to keep, right-click on the plot and select Delete. Then, right-click anywhere inside the current window and select Cleanup Layout. Now the two plots should share maximal space inside the window. Return to XY Mouse Zoom mode when you are done. Now try zooming in on any portion of the upper plot. You will find that the lower plot will become blank. This is because the lower plot axes have changed to match the upper plot axes, and there is no data in that particular region of the lower plot. Type M while the mouse cursor is over either plot to return to maximum zoom on both plots. Now hold down Ctrl (this is equivalent to selecting X Mouse Zoom Mode from the Plots menu or clicking the toolbar button). The mouse cursor will change shape as visual feedback. While keeping Ctrl held down, drag a rectangle in the upper plot. Note that the height of the dotted rectangle is restricted so that only the x axis will be zoomed. Now both plots will display data when zoomed in, as the y axis for either plot was not changed. You can quickly tie or untie all the plots in the window by selecting Tied Zoom from the Plots menu or by clicking the toolbar button. When you are finished experimenting with the zooming features, you can close &kst;. There is no need to save the plots this time (unless you wish to). A Brief Overview of Data Objects There is more to &kst; than simple plotting and viewing of data. From the data wizard, you have already seen that &kst; has the ability to create power spectra of data. In fact, &kst; is also capable of creating other data objects such as histograms, equations, and plugins. A utility called the Data Manager can help you keep track of all the data objects you create. Start &kst; with the file demo.kst, included in the demo package: kst demo.kst Kst with demo.kst Kst with demo.kst This &kst; session contains vectors and other data objects created from data in gyrodata.dat. The top plot contains the azimuth data, the middle plot contains the pitch data in blue, and the bottom plot shows the power spectrum of the pitch data in blue. Let us first examine the plots more closely. Tie the top two plots together using the techniques you learned in the previous section. Then hold down Ctrl to enter X Mouse Zoom mode. Now zoom in on a small region of the top plot (say from 50000 to 53000), to cause both tied plots to zoom. You will notice that the the blue pitch curve is negatively correlated with the red azimuth curve. This is because the pitch gyro was slightly rotated relative to the azimuth axis (by -0.69 degrees). The true pitch p' is: where p is the original pitch, is the rotation of the pitch gyro relative to the azimuth axis, and a is the azimuth gyro. p' is plotted as the black curve in the middle plot. The power spectrum of p' is the black curve in the bottom plot. Now let us take a look at how the three plots were created. To display the Data Manager, select Data Manager... from the Data menu, or click the toolbar button: The Data Manager The Data Manager The Data Manager contains the definitive list of data objects in the current &kst; session. It also allows you edit or create new data objects. As you can see, there are six curves (each created from a pair of vectors), one equation, two power spectra, and four data vectors listed. Right-click on C2-GY_PITCH and select W1-P1 from the Remove From Plot submenu. This removes the curve from plot P1 in window W1. Also remove C-PSD2-V3-GY_PITCH from plot P3 in window W1 using the same procedure. Now only the corrected curves should be displayed in the plots: Corrected Curves Only Corrected Curves Only To see how the corrected pitch gyro was created, highlight C4-cleaned_pitch and click the Edit button. The Edit Equation dialog should be displayed: Edit Equation Edit Equation Note that the equation used to calculate p' was entered in the Equation text box (an approximation of 1 was used for cos(-0.69)). Feel free to experiment with the settings in this dialog. Click OK (to save any changes made) or Cancel when you are done. Note that all data objects have a number listed under the # Used column. This number indicates the number of times the data object is either used by other data objects or by plots. Since we removed a curve and a power spectrum, at least two data objects should have 0 listed under this column. Click Purge to permanently remove all unused data objects. Click Close to close the Data Manager. You can exit &kst; now if you wish. A Look at Plugins and Events We end our journey through &kst; by looking at two specific data types—plugins and event monitors. A plugin is a flexible data object whose behavior depends entirely on the specific plugin file selected. The plugin file can be one that is included with the standard &kst; distribution, or it can be a third-party plugin file. You can find instructions on how to write and compile custom plugin files in .. Plugins allow &kst; to perform arbitrary operations on a set of data, as the only requirements for a plugin file are that they receive a set of input vectors and scalars, and output a set of vectors and scalars. As an example, we will try fitting a simple line to a small set of data points. Start &kst; with a plot of the first field of the maxima.dat data file included in the demo package: kst -y 1 -d maxima.dat The option specifies that only points should be plotted, not lines. The plot of data points should now be displayed: Plot of Data Points Plot of Data Points Now, open the Data Manager. Click Plugin... in the New section to create a new plugin object. Under Plugin Selection, select the Fit linear plugin. This particular plugin requires two input vectors—one containing the x values and one containing the y values of the data points to be fitted. Select INDEX for Input Vector - X Array, and 1 for Input Vector - Y Array. Then, click OK. You will notice that the new plugin object has created slave vectors to store its outputs. Click on Curve... to create a new curve from the output vectors. Select V1-INDEX for X axis vector and P1-kstfit_linear_unweighted-Y Fitted for Y axis vector. We want to place the curve on top of the data points in the existing plot, so under Curve Placement, select Place in existing plot and deselect Place in new plot. Finally, click OK to create the curve. Close the data manager to view the fitted line: Fitted Line Fitted Line A procedure similar to the one you have just followed will allow you to create and plot the outputs of any type of plugin object. However, there is a shortcut for creating fit plugins. Right-clicking on a plot will display the context menu, which contains a Fit... submenu. Selecting a curve from the submenu will bring up the Fit Function dialog with the x and y vectors preselected. After the fit plugin is selected, a click of the OK button will create the plugin object, create the curve from the plugin outputs, and place the curve on the existing plot. Let us now take a look at events. Event objects usually monitor other vectors or scalars and perform specified actions when certain conditions involving those vectors or scalars are true. Click Event Monitor... in the New section of the Data Manager to create a new event: Event Monitor Event Monitor Suppose that the pitch gyro data was being updated in real time, and that we wanted to be notified whenever the corrected pitch gyro falls outside the range [-0.60, -0.40]. To set up the event in this manner, enter the following in the Expression textbox: [C4-cleaned_pitch-sv]>(-0.40) | [C4-cleaned_pitch-sv]<(-0.60) Note that anything entered as an expression must be a boolean expression. This particular expression will evaluate to true whenever either of the inequalities is true. Select both Log as and Notify, and enter in your email address to the right of the Notify checkbox. Click OK, and the event will be created. Now select Debug Kst... from the Help menu. Click the Log tab to view the debug log. If the event was set up correctly, you should see warnings indicating the x values for which the event was triggered. Check that the values roughly match those you would expect from looking at the plot: Debug Log Debug Log If the pitch gyro data was being updated in real-time, the event monitor would be triggered for any new data when appropriate as well. Once you are done, you can close &kst;. Conclusion This concludes the &kst; tutorial. Hopefully you have gained enough knowledge to become comfortable with &kst;. Keep in mind that this tutorial does not cover all the functionality of &kst;—there is still much to explore and experiment with. The rest of this Handbook is an in-depth guide to concepts ranging from window layout fundamentals to creation of custom plugins and data source readers. You are encouraged to use &kst; in interesting and innovative ways—you will most likely find that it not only meets, but exceeds your needs and requirements.
    kst-2.0.3/docbook/kst/Screenshot-kst-tutorial-gyro1.png000644 001750 001750 00000035354 11544160206 023445 0ustar00synthsynth000000 000000 PNG  IHDR8g PLTE2/2253=V3Gt@LvOQp[Spa  %+/6|>BFP Y([_my -=Pcsޫܱ֬ΕƇ~yХiɜ_ȘSRLrKscS\XXYWWYYYWa]1/22/1921O9(G.C"C7,&     '2A I$B 5@?@ =H;W'>Y&;^,o+3"=)Gy*Ho!Hr Hr ItJuh&e6`H\Scctq|{xbSJ@e-tm>7s~Ưm43J]nqpnfez ){<)8xHU6]N!rݺZޭKlStfeBtjnmU{psٙv6Mi[))8!]btG$Dq·4͖Z NSrnmdn_{y'jb]O>Q:<}IF6)S'նUMZk<@ph4/>)FIĩZ-jkjk[[wn_a-vKm6cԹYO%46nfMM&'³ f`rXnt4<ԔcS26OsKK)2DfC)?rZuEo *:*;GyѫIٷϾj>Noey]gyB 쑄} 2GUm~]BSU\Nص\f{*Zm8=-z{55 Ųo GG*}?6{KF wӵ?߼"Y[2ɺ;K6n8ǙkM#=.eڱԻշW^q{E8d 9}fcpxeYuuotΫSg2N̬X:i4HC,0,mI2 fGը3sP~v]}1ǩU[=:H|Ou5/d`+_֣0qԹ;NX4̦ۋ_Ko}[Hcҟz8Ѷp_mmV#}k !6|d"ql3V .|4٥C{$8sW'RѪv܏rÈyK FՔ;6I8+ΖMNm#sW*ͪ[Frt\q5QԇSS,keG߄v@+yaWH뇳߼קc󶜟? @ pA J7sO! vnzmd6 <y2fkj7GXjnr SnTT+qꕫ7lhttp%FGFy$QzfԲt㚝Jt9T1$ڎk;G Y/ғ@,5JƬpRk58:Xv-ݡa>upFGslWGÎQQ'8ХK扃߻7W;'LÙL޹z5,|D"133,lEISIt9v#9>~bZ=*0RQ[qaس)^Z *Rו,k֗^Vci楯ZSpN=Eenb{Do=vmM$ǼF8ji!lT"l8+#iTK/*?}XqK pɔq692YqR۵fy\KS] sO;|v~V+ q18!SE͡5l'*X`iTSݼ^V_=G"1Lp]ٻ'Jm=,wv}ظ}pNv kb8f981ΆUJu"}|͆ YDZǵT}=a9#S P*lവj?#J p#b8J M5wMg%mXckwW;ѵ;ʚSIusog4J/:3耚o޸ڢǟPO,&'񁨡HD 'Gî!kVoQj6 >\Q? 39K̥:8[y$H5p K[+C=4P+͛C7OtgzIUNNjc"se*%RیC׎N_TEkpRY~uy |c)MV蟻o9Hqحe}mmKScJ}8OB8/VˢR;u8SߧGX?[g2)IV8MǑqD#7;1*\^zyTm@3585.ÉS-y'Ǝ R7h+X~4վm6zIT2~[1n.\=w5Z^knEϰ1FՌu22 g o(R幟)1vs9fC'gx9+Y+? ލ1QKh6*2i2rNq7Svc :;xƹXg8ۛvl` }'xU >w4|xCZAޥW ܾenčU;>`;֌%'eY̌R%0;c?vq:~uErBT05~sf-Ris]rR6MTQ> 57$"ƒzZDGܲH$XT;~m)f=G3=qP^#aS-śզD& F*j]dpl8/K)C6Oqgw=o8qۨڹsg9~A_{r\`\ݶQŒ߷V;8e2Ff17?_ڨZ")gY:+1ُ<裏PcXx26.UV\^իw2sΚH>rȒt8Th=I9>ǸNjJmZWĺ~{Ǐ2뙗hӛ#V>Twcj)s;Xjeţjp ip6?i Ug;༳c; 44vklؿFՎwts3Ǐ=$XarW pv184}ᳮ Cl;p}>t?W#4Xi"!8ߝGs$:Gy ;RۂrƏk85W԰.Wǡ<\d ~e:P=bWfJE}J >ND?n;OoFWKC){f8G9SQDfÔq=TAKƩ٩-dۈΜIivLgn{yMƎwmq/j`ڱc8~le{77oj5L jM3ٳg2{X q&no9~9niUP]͆ժיj|{EEKެ~pUHT4mʆ sSSg4tج_-J~c랻Fwd2 H5XhS8qߧ1NfY~||é<;2&iHtJthOs.vMWCѵӹj>b7/=s;3v׏*G_gG_ݲ^olg{om` u -ipxVe"Z*8Iq ik叾dv͑ћ];bsժZjsap;&QYdzN?CQɩnʻm1ӹjji:3qsq*՞{&2]sD c1d3T8|sx_N2‘{hnvHYe%I.#pX:I2431uU0j/{;W&F{NiqDEӭxo$>`ܹÒPz?L e.0p,HҌsfϨzw/ϰ8Ɩ_sծ.Yjζk>?S-BgUg=I&8mg 4}8ypKGO;b7>N|~h41R:s_96 if[14iþ}˃Wkr۷ꐧsԆ9CC.q\T7woÑNBw.nNbl G]3d>a=!u Aq8Yƙ1CzEziƜ9V8r՞ Ztچ S_6j޷X"g1:G3q5"u)կSZl!vR箃sܜogFՄg(@魱kj"|G-G-)ksDp"NpxQ㰨;N.Q.~  ]ٶ?W޷訧s>8606|CBW6oTOۼuk"Dvg?Auyw$fG!8OYh&8#93VT-1*#vNZ=+1ٽs>^.[2N ϘqTͶT7f;ۯX58|o||±w88,8+?9ݧywNZklqֹ9x}D wѨ4/$DSn^rgG;망}>FNpDGJ~sYgܰ vٴCcMxǣMKDbˬ9U>yh6q#Oc=ulM.Dk8hVbl! /p)\KT\4_(?w0Mk ^]3#A  8 EGB +cDvӪDsuԺ.HZ_l8u7<}K~WfCpdpHN}TMW 4VKM.*vJ}1ޫp=ybjfj!R:5Xw˼f8z@ .ɩo%Zp8s cu^B1"/0'l+L8<=~?p,!b8NN $!V@8si $-` !΍.0!cmCCr?C8!yC ;Z{tሒuI!;zIpvR8%9!yCęxT?+nS~!!Nߘf%L0t|>khA؎rLp go86/'8gu1K8xI'+C8$plW×8Ǖ!pQ:!E?OVp8$pIQO PB 0Av&R8Hp*2 NE xCC #lg_bm5{SaC)"86 ฎXxYqO<1}  ,pHpHp| / 81/8$88'̭/8xDpw8$ ( 8$Kk3/o>*\bpqM ǹjOjJ/+dQ=rˑy\8A!6pc%4H.[3`/dCZ! DZ^;xR88h?-x.g8$pvRp \E)(p'N1| 88npH! x{aCg -8Sph!89I}To8ppCpppzbqpTCpw88eN !888's5,J N1!e_8C e88^Q-!SNp|;\8iNjpǩҧp'{8Np(pk4t±;88868S''QSp,_8p'>Nah8^w)V88^aB %Jp &j 8888Y= ',&8NbR8'$X pڑqrC ׋pp7RC Nxxg8883MpD/f!88#,^8e ѣB]#8!O838a'x8688Y vJpBNdIOccpppb8}/ ppp NZ> G|b.088%z=xZpgARCgOSppp r)8vppppN`pJ8xvNp<.88ǡ !8Cꀓ pJN/dA)m8NQZp qu8Z8c7ppp#w88+Һ/aϓ _ k~g]:ppb?+pppeT[_8Spld ']sO8!HyK Pil8ywq8p88S88>*4Npr3888888E ҁc N9# ?(do(X8^  j7N,k8nqo ǻzypb[Sp}prג3|%g~U GNUgp>~'p4|8pSpp)78U'pr<Gը۟ 58^8S8NvYtk3N,TCS24f)8 :f8YL}8isA=ܛ88jSpB'u0,Kg|Ua8vj8##9 ܲu %͗4Ѭg+7)g8?8?jx( pNt%@ĽE/8s_*> N  ҧONqڅC _SU689͓w86|WiU8&9U{[?Nh|=N Gs)8 #Egj93e p'pr(l,88cp'pK$js8y^inNp2jcZ.8Ip#3>4)18)@8688a8ppppJ 㱚kk)28upppKN~x8'dX pM5)78pppt; 8E8 pDzarCTᘟxCpppx_2yTpppp'8nZ/S8\8Ny¡'quD8>CrC)N)Q_" QSp\Npppp'k8lNBX8Sp"8%N "'08O8SZM512O pp4)68p NUp }U'78~vppppppp$mpx8k=picJ B6R pJhF)p'8u *Rph&opܫquCá#) 7:Mpw84Dp0c8zM09cuV87 Wx1A898'jӓ48# 8c.w8u4 4;8܎5Zzp(q78?@j.> SZ8 K"ġ%eN}q, Tph>U$ieg<j{Gpp~;Q:Q?Rz[68{8 hpg ?_؂88a bS.i 5m:}SKST3Z188G8t`8 G8 pzw}@ <Ů4&@x & @A pآ/Kq*z8_M+, pA p p)+3O'(3gY^=P#^ڊ1O$|3i枍:MJ/ZU9~ҥ[g*<h5$g:Zn߶n? = Hm?YTA~3k+!;ii Y߆ # C;g#k=ts~`e3 >Dvak=洷._Q Bci s=Ԝ]ݽ}e.փ^jz+rcKGw=1Gp)#T`9W쌯3W>!'wdw.URqM-S3Tݨx>3eEjweDF]5x&?LFAQͅ4G*U\H,ĜZ7rE=ʹk0}) Yzft_wC(h(Ahsaz6̉9Tew[^g'afoGIKchA)ch v)}'ZͰliZ\J:֡_(}PeK))ź=& EۗVH=cvlC7-ۧ+1ۤJ.⼬rS fflVڙr]^NhM?\bslBsq؜T~_8m%vz@Gԩ鬎k9U=014ߕm1g[쮙.Mm=z9M΍VGXz~׽9%ѧ h2 K}.m%$-N5Ni˴>}^.'UfmԖߡңc&fE2GQ>-g`N#Xgx/E2'7,ah\/&J*DѮN5 !67nPZUOW qAnx !#+2ޢ-Cd{dִd`LI(5M$s\19IU+^lgKC'\"d0u5sӡzcGشb8[W=isLy}いlt1G~JEDpp]#;[zp[[XеlǒC< U>pjƆ-mXMS-HDGdAׯ9?$κo >0s+baEg@b9f+w7 9J3Ga9HU>v-f#j+GX/t#tfC~[a?sf،ݤ٨x`|M΁wY# ɼ펉okh,srQ+u4);F"v=s+礜PP+ 3pqTsB[]].9bTΛUgi ̑03G~(A=N 5Fsd!.>Z( /Vdi wһ韣v;dp9 eNW(4oU%d`͡{s;0w_曣G~c4͛SZ[5m^ap["95tw[']zv,sTǘxS#+Q$b\jG^^^ 9P9Zr@ӿjIqll eNb,o]%dᐮszocxwo(Gʜ3'^չ%0:: "m9ky '~ylItq̸qArG4V9QYBk1%2G@i et9y#G YlM9'DCqKv10 U&)Msx"NB9}竬Q !g+66$&FYZϏ"ǏM6/k/I̡v: M:W9 _wrja"f4R7=!+s eJ¡]dfĉ5c輠;~bwwWgGB9N6298dЭ3oMPiP2gtu#}t#}r+9HvL#,0u sӂ<'M.'uyx$M7:=!ߝh1[2bcc8uMw&њ#Ofs|"M8D69%T>\;i L&9gޮs>71Om$7WƏsw# %Us$;Qu8"S'X$\'OɅ_N:Ɨx#Rs܉BTxrX=iiTo8^#p97299G}Yi9ӈc0Ǒ^)K֔Gyɜ0谽6>4Y6B=]ĜԜc{+lǑ#y0'QB-6GZ)^Md%R:DXCtUV渙0̡OOBs|sjH&;}ɋz%䑏G(,\0V?q] ,᝼΋,oB.a؁;sBh'qǗ}2U?$ȔW1rȑVTsJG&TQ)<"X9T{Tsa^cPIǯ/IS=RيYV<-%ZlS':GZfT%ՓV7*rN!U2lo Xb&=,ͭufBrOj-=^UFYXLfŢSo2'*1Q~h N'gz\429Q銂!Qzs}KEB.etmѱ?%! U8JQgBM_>LK~O?`u5I e %ި##6̒|sw!kC,jnG9|TCa"T9 9o-朇aNʹÜY^7x~`s4[M"r#f+bu\[lBu0Buڬ_3&gU0hNlr#(\aE#Kglovpʶ^8t[(:Ǹ3ww6rRۧS77؛Q0`N-' Fi䲏?>19α凟*K'LO6Ds8n7k6c2^.Z'S$M{$Lz!Lz!K{ KzJx=a.C[QTSSVTNPO;;;212+-2(5#*   єtRNSԷFN1 HIDATxMkH7u&!o}KX/:%Km0d2^;a:Ә,@`sXpbNfY'T*ՋZR륥nT*I%G;jssG;jsGOѹGj(+Y</m66U@ۯmK/>ŸfЄJ;彲,!|yf&Bj=#/ޮUoU/]{5pkӗWF㿿{,cR^=vxǯ7p5\[[?}!qЛsv!1ۼ_z1zx㾏5s!W֯=6 aco8tkK#hYBAX]g[*Ba@PG8\[뿭հ. ّ?:FCV?Y <1A#-xyEC=wk'+.;+q@Q;fܼC@NY~v ^Olkas3_{kk=4uŽ6|VqyᡠQ;8<`]MCX=!mw<_{&!|v }~M]uWC%5Fᎆp߇f߈pm :3ݱW\C!RuA(cc2n^kˍӧ׮{tÃ7>C>8؍V%祐0]wONOOOlkwjw2m^J[46f( F (4sqRQ3j DrJNMs3^甀 .y l(%(u Z\n2 Br3dqmOJ"Alfi H6ni Z FӾWr{B)к!f \Dh(a0R, "H.%aw1!T D/wUY]dUI$\Q/J r Q0J$)2}QlZbۃAa")2uL{VO3"厰7a( aQis!{zLҎ+"> ;;J!?ؠ#ZcڊF 5J`/+ RH%3`B@B@!B@!@!!P wB=ؾP|Ӏ QkbȾNBIp ~+|[J<#hЈfD7 "$> O@X2BzyL0@ %+y,b) Ls U%G)Em#EER@rte{}œWM>#ȗ(|oBaA3;8rT , af|yāB!ߌ<#H E 0‰9awg&!C>pb@99!C>|g 8!B@!B@!P~1&Br(- (Y=I΢{'ڳ3TQ:\Iֳ34q#]:aEy+8aXx;q&Dw?YFO((j<,e(ow*;X'לRe'CXp1=S<[X<9x,r142Ig(&^#+eϹ澊Ibb*{f| B9 #kz Cz@@T*h@njxE|M\68 uW,|o[ x^#l؛xB&gRB)T}xaÜ s"CPxkx s2i}ȞJ$[J@[ p#z s2'YXvS7ZNBW/&:- ÔD-G8}N4`(:"h Elc&5yzqԹg|,?vS`&-YDl=).yEM Installation The following sections contain detailed instructions for obtaining, compiling, and installing &kst; along with any optional libraries or packages. If you use a package management system, you may use it to install &kst; instead. Obtaining &kst; &kst; is part of the kdeextragear-2 module of &kde;. You can also download the latest version separately from the &kst; website . If you wish to download &kst; from CVS, it is available via anonymous CVS for &kde; or via the &kde; WebCVS repository. Installing &kst; from Source The following sections detail how to compile and install &kst; from source code. Requirements &kst; v1.2.0 requires the &kde; 3.1 libraries and &Qt; 3.1. Almost all major &Linux; distributions have packages for &kde; and &Qt;. Since &Qt; is a dependency of &kde;, having the required version of &kde; should be sufficient. It is recommended that you refer to your particular distribution's documentation for &kde; library installation. Note that the entire &kde; desktop environment is not required—in most cases, look for packages called kdebase-* and kdelibs-*. Alternatively, more information is available on the &kde; website. Optional Libraries and Packages The following libraries and packages are optional, but provide full plugin and data source functionality in &kst; if installed. The installation instructions assume you have root access on your system. You may already have some or all of these libraries and packages installed, in which case there is no need to reinstall them. Also, check first to see if pre-compiled binaries for the libraries and packages exist in your distribution's package management system, as it may be easier to install the binary packages. &GNU; Scientific Library (GSL) The &GNU; Scientific Library provides a variety of mathematical operations for the built-in &kst; plugins. Having GSL installed enables a variety of plugins such as linear and non-linear fitting, correlation, and interpolation plugins. The library can be found at ftp://ftp.gnu.org/gnu/gsl/. Alternatively, you can find GSL under /gnu/gsl on the mirrors listed at http://www.gnu.org/prep/ftp.html. Download gsl-version.tar.gz, where version is the greatest version number found in the directory. Then unzip and untar the file: tar -zxvf gsl-version.tar.gz replacing version with the version number of the downloaded file. Read the INSTALL file in the resultant directory for detailed installation instructions. For most systems, the following will work: cd gsl-version ./configure make make install CFITSIO The CFITSIO library provides support for reading and writing to the FITS (Flexible Image Transport System) data format. The libary can be found at ftp://heasarc.gsfc.nasa.gov/software/fitsio/c/. You only need to install the library if you anticipate reading or writing to the FITS file format. Download cfitsioversion.tar.gz, where version is the greatest version number found the directory. Then unzip and untar the file: tar -zxvf cfitsioversion.tar.gz replacing version with the version number of the downloaded file. Read the README file in the resultant directory for installation instructions. For most systems, the following will work: cd cfitsio ./configure --prefix=/usr make make install You may need to change the directory specified for the option, but the most common directory is /usr Compiling and Installing Once all of the prerequisites have been met on your system you can compile and install &kst;. It is assumed that you have already downloaded the &kst; source package. If not, please see Obtaining &kst;. The simplest way to install &kst; is: tar -zxvf kst-version.tar.gz cd kst-version ./configure --prefix=`kde-config --prefix` make make install replacing version with the version of &kst; you have. Note that kde-config --prefix is surrounded by backquotes. It is very important that the kde-config utility returns the correct path (most likely /usr), otherwise &kst; will not install properly. You can double-check by running it directly: kde-config --prefix Ensure that a non-null path is displayed. You can read through the messages displayed by the configure script—if it reports any missing libraries (such as GSL) that should not be missing, please go back and ensure that the libraries and header files have been correctly installed in the appropriate locations. kst-2.0.3/docbook/kst/Formula-kst-gradientsumofsquares.png000644 001750 001750 00000002010 11544160206 024265 0ustar00synthsynth000000 000000 PNG  IHDR6B5LGIDATh/Pg{c{D1LH$4"`LbzF0 l".8IνL%p \%p G*Xշ{xIyd c`N'a/=wb|ij<1j&aWgm"1H1ps=&Ipd2ֱۂ{VY=KaEQ;H@Z>TS1`m^dV:  x]'Hswu"^\2{V $ ,jK_Z?:E@BʄA&4rwD$ʰXꢌl G3吿Ř#.`plU)|=fYB*m|ԈX^2f(>.`T. /F4FrF Fk|R jt.bniM8QԶ&8%$6#RǵL2kwt*'XG|ݺT=&m I,q9(U>ک08ZYE^=J?M>1Z=H!_O~F[kd}_T4tgpqIi;̩ubOܨ8>+Z=t:-vx_껃fc0$U;^'Z94wz~S{SFc:'`(/㉵H>_=wwq/5tS՞N 3=祀  ZSYƥ<[;`c貛Vg5dci"Ğqy %ٻS7p݉廄pKZ!. 0ym`Y]k+ p*W.ż p.,%p \o pnPIENDB`kst-2.0.3/docbook/kst/Screenshot-kst-demo.png000644 001750 001750 00000035260 11544160206 021463 0ustar00synthsynth000000 000000 PNG  IHDR_n PLTE?BFIQVZ^eudsszحǓ~Ɍ߱덽xnd`_^][[YXUURQONMLIJIGECA@>>A>2|_RUZ6a;k@v:|AwGP]lȘų˻н¾q•\;N(?^#Kv!Lz M|M|Z#I!;% MPhY\WmUEWfړ X |k% Z4;2&/1.!$: E . UKxtRNS &7XIDATxsŵU)r?AcW`,- 'qʁ"$K #ږ*LWc#"C*vϳgvfvfwv˫tOOOgN>o}DBkċ$$yGjh$$GmIH1%A= .oF#{8MB#eXGX|#9"!QeD3Fbb;K,jGBTuoXtW\I`d4S԰_ߓ36T%ґ!}97\&LNQv=t=6DȂ#!Cb\p+/xW:, o|xf xx㏝}D897xgCc"haxw&Ć&E) {I~ۍWM!cT,,G '8Qk!,uɋQ1x. ;t>ȮGv!kD};C;}ppKϿC|:gx' ^b5.66<>|[q;-.6߻G|9/,Nj`SI#Y.*_< t5^/}lGa/'_q˝e5/ᾍx[^{6_:N ]hBymxpp#=?֑WxS!+?ʃi6؉uD˝1CtD+G_q#slx||܎e5+  l?x#\~JIu q I2.+1g_?%!G,~BB_$yuT6 IR*拄$!H/⋄"i8f#˻Ruכ/Y?FA'o6}?"Wuķ[[~]) d3'Pt!U`00%{9_Ҟ+q2zwKghqz'O9d7#nJϗ][-<{V4Oiq.J?2iŰ=+V<鉨ˋ3pos"E1Q+#=P|QNzľ+S{.߂ mT. [I]~&\6rgv2^^ՋNj=RZ:"`߰}եҕҕ3.]}W>%`}/HDrҬw%9J|+ !^XjN2:_E.3 [޽nkP&bY]0km;ړǵKv !{ǼxNM.[Eg];CAnrKFR"S7 _|J'7\eE_n?4}fyҽW&7Cel-nk}-oC;l%7p8sղdx4-#u0_u s WV &H|<:o.Q8 6,?W/ŌqXש|KW"!HH/⋄"!{$$ً-%$5WC"_$UBwHI$_MWi}9~ŊS/o^|gׅ^Gw^ ^Off*ЏvMڼAQB.z)GzOB;%8|T_X!YekUԺy\<:֯{f":<51ebjt-y`O;_z&P,=(_J2_fݔP-H )?"C#ݖᓯpw8_\iu 2_]MT Md>s.\8sgϞook݆Mذ}AI|:mzz&ީї_8q}j6-;$4(wGGTzį̗8C#ݖ3omz-`>_wN>-E_sPCOc0{w@^I篛xmt!m%_mֻ}SL_&GWz(/佁RtzoX_%%lx# _"=\z69)ˡj׃8C|Pw_=6NG}VEどM;ۧ`-ă6^#́|:S`>_GwSOرcT5;mmmwe!tg^"/]i~;er_q*nr._O<Į|ݱ:muėiƖy&oOtJvun۱cdz^h<|B/ χۺ{mش-Fx>tԾg|u:u6ʗ@hD/JƹB͊|9)Gǩj߻/ҽ|n3_w\Ӯ|e/? ;w8yhFWWTos3Nζ|zzzx):yi)ãݹ6l:|aL->n6}’آ*񥵀_=_1$eճzCg{x9_}SO $=111y3f.LO}Hށ.w.VO? |ulRc-9x!ϋěo4uN5g6on;Y6#BܬΗeB[p?|up|PB{h]8&9^7q~񜦿P..p#k8|>u^çe&9\$:Y}n|C?R_j=|C@HFeN._sB7oR:>>Q7ts> G HGϙG떂 IQ_`YRuZݖOxX/}<ǧO N/Ud|zS/^ԨׅikA6OO.MZ;z+؏ZtQ_|;:vr>ikڨ:>1dey_uL *]!/e'PB{zS랼s>ײlŘ>2/0c1w}9:> fo.("7ǻ;:_<~/nf0u wvח+| %rTÀ^h_R$_s|ͩ|Ͽ@53_7'F|s," 0}B'wĬ`nhH*0kUoYo՜ o8Bzy)ȡ޹Xhwlk?{N狇i&#?"t}~))Ο?0c[|-ymOF9=_}׺N|i/{^:zSƝJQhK++~2/KKWN/k:d 5;$F,+f{a2Lxl[H)|Ϙz;ľFϻ_|`kV_]f+_Ryr^||oz -;{@h ??3MnnH_Տ6/.}F_}7<'6X:dv;mx+4@v}qqQ ƒ~;m # 7 o PU{w o<~umGt/{p'A䮓/nݟm)q/u羯"%G~$,׺M{n]]mU}7rL7=km j(#xo#t3! 턖 (.]z(:W6!'$};G 8?h}y\wU6ڛ1^$\{1=YG%&ck{/9d_ E=/FGtŋEgX 5y(&{X1zɨ8 utdڛmDGag~}rdqT m#O=NL(|]櫯%.gOkoe#3xwҽ|z'>O\ot-uIK̾},N 8W!Хy8|EFܻ×uROG|Yy'b/? OWǜS/صsZ{k+ Gw{޾މѣܳO{%|,LS1 CcT/Wx+r?p{\?-uU0Ʃq2_q?=לerǬٰݽ~N݉ҭ[|?7R(_v?|KKb,/)QS㣓eKl@IғP}TqЈ{w⣏o?_c'-L8rz,sNG: oGYo.M4JmckP2HHk~3'F x2T-xރ%ILqNbޞ秧g>oIXFj翚{wpty=b}GTW ?"-#I#IzD6se mUE_d+}u $c9|}m !V"!HCi&${oB)!78{8ܫWIZ$t#WBjjj_U71EE% OTxB q/%i$$"q^zNMDn G.冤lI|&BW (&A!2/HWP*yD%_\V~@ZC7]AS _(yh_RHcOֳ? 3#S f"*֍$%ɯZdj!$$fɆ*C(ق2/8 aIoҥܦ*g`KRf0.҃@FU/I[+ҲGZWQ*Wg'[لJBr9\)*|)_ F)KAOKIePvO Uye*ʵ/-|ɜ3Koԣi |+ 2@a˧} +r<)*WW"`1uUf|%/%a ±˿}LW9BEI2Wr}mu嫜rjWZ2X|Au|oR+*׎r-*GUNWL_=frrzR@J ˹U'_|U_W[r}\iWU&VEW9pdUr|a g:.HsU/9*GR_Br~teΙr2_ŷ W:[3ʅW1}/դ_G(c*טZ=kiۯ=_L_o? _U5/z᫜#_ `[/H}5嫜J +g+-_j[/8U}_n& Ԑ*?e_U}ʗ/ _P2_I_%Z o[/ȒE+"B" Wy _5'},5%|ezT|Acv /h >|AWƵ/v|AܐP -_Pw& Z/` މ|nc -WB 8oKׂ:\#HEB|_$$9U#HSZ0qCK0Д_3M܎F|_P"3%;Zb QsF(UX5x,GK|&sL6 ;+Ws/i[ I9mt"j /H/H$̗vj8_~u,+}l&I5'$>:\W㨧iK|O}U݅Iӎt*4?DR4hQ:Z͊ ! #3D|&Up0/p|hCK>JiJ4Tڄ|aN 5Z8/_W|ɻ{_>_Elez |`~W%*_Wz/+Wd_d_M։*/ '_d_/8Ht_U_d_d߷ _dk"bfV+}(ub _"?2.{k/3%fRXtjpO,-*MvqMWd*,m0C} cr}fB eEVV|oomV*V%‚|񓋕Pd:#a|əLyf[֙>rpen#c~YdR12TMy=㕞W11;t[ ӎ754cB) Զe><so X'$e\D̫Ɣ\0&g;._tsߩ$R A"K͠7-յW |aH׫]jLJ㫞&p.$n*CU Z*dl3Inݫ:SIhAo0/' T5@ZirtE(FL|!lg(#/CF Jp9+_%.Uo |VƴD`!nuB|E&M9h>(B^9(عSaq/HE/1<|j :A ,fKmPj#|Ik#\ B`LN}MW8ND2@_^عJƗ>#Bڜ_/]xNB*׻~l۱ηB/׿8ckmAd Ǘ{/Hs W.d+"֙G/ u;?V݃eܿ)EM_;JT̃ϰl|;Pf>(ȔkńR9?;!`怨M Jjm)k9kuh Z)cʃJ>nqf1}UʛN>T/E{#IU|"0?++ 맿XQ Vd>v bpRpܕ5q{,ODTo<): G'.3w>ǟ;7Gg14;ar$1D,2M <4R\77bO;O4ˁ7!^{ͅ?$O2eў)-ۻŞV|4g)LM[↡p(qְ[|9$ #|1_=N2iQܓp#y]q.p] |? nNܵ;ykQCiP˕S{c[36ӏӇv yǸ|N:r|Pܿ. +P89|l U 9N]M_d';BлI^j[o/_\()j|yug)(hxN:_,k+&|yLʏD[`=-0#\;z8󏾫s`mzzk*\5{;k x^ 4ZuO%y$t }E>1]́[u+wbn]L\g&?X{KY-(d>_!M іvh!J:,PdZ 54Xi̸Ve|!nT+uD2 Y 8|8U\o[lB,t+4kR,c_C 2-3/ՍWU %Ziog6aJNAn VA+ P,+- I# WsZc Fyx/!_ʹt<8/+#G+UG"R_Dt_QQk/sߗ"_ђ4<[_X'!>9IcTHWMމX\11$W^_Wm?{5_G4z)"/ʡ. _ŰZ&Ȅ&UAMy+gPJ$$$ EB|_ur#G$0(@ydus>j˸95ΈVT|aʳ|yjʶT/y /jȾ/V6h|"!HH"_ƎA۴omgu 4K }ʼ޿]=+B|_༼ WB;T唈/̗ue*_3E|Ѐ/+}[}ﵠ().E|e;4RA|_$ jhkՈ/|*V1L\ bY+/L"@ vGo>:U Y,⫹GK| sBGm|WwwZ~W|ቯ&_Ҷz]r8n -7$i!œPo@w"i>BG`Bo!xj/j[`|B*~U1#{ɝO6ɾo&0I3U{zGlHr +6$UZ1"`yǘx__O1Q7\_S\ş/~+3_יWs~2W`XU4O]^ub]!ڿ.9 yKJ^]bRްh|XQ*}|Qƈ p0nr03:_F|ir; WX@r*&0BA#L:d8|af4_(__ K,1Uś̴' %+cnxz fG_Q=nΥ!/p]4T] _UmRR;%/0 Jte=cS,_ cW_Iɀ2̺h Z2ZiVҴU*`gP?>+=!Y+0_v+i|1J>l}00Gk _u/5̗iFS2LVsRβ:Z]2FgvvCIG|!H/{ܯC/LW2HW0D  &Kugh /VP*W$g :Ukm | c#( ,/&UoEdةQ*{ԣh`7  "I%%e#0;E@E%q@?E!C8fyNZFrNU$A6P`;{ƞ7&0_ңz[\t}AxM 9}cTFCha^iǴFq(/́őK53jє@<Ж%"x- F%d #F` `5݂娙앶R0R8,Ą`<0Pɗ`){ W 8!9ƶ.R08B凰+ lUn!QRQ0e|K, |mm;&up\}75u\yiS CIENDB`kst-2.0.3/docbook/kst/license-chapter.docbook000644 001750 001750 00000000740 11544160206 021522 0ustar00synthsynth000000 000000 Licensing &underFDL; kst-2.0.3/docbook/kst/Screenshot-kst-filesave.png000644 001750 001750 00000024754 11544160206 022343 0ustar00synthsynth000000 000000 PNG  IHDRpe\>%$PLTE &     .=T!I'7.-.7'E J%W6!j;7CU"AFf*;F֓KđQR}QyU}w`goa[YWTRONHFH@=;tEzJQI>=@AA@@@>AIJJJJJJKU]TSSSSSWYYZZYZ[cleccbccimttuzꃬ삵刻슽퍽ॸҟƜǝĆ~zrĢmͥkߡswp͓Խ NztRNSKY&IDATx L  5zMl_ooE47i6}bcM|6m&Ι橧^͐~8͈v{u?fH[=[ )?/4rvʕRUm&VN83G-K_"nWͯX)htTRĀ{W:Y /7ԲT*8ep,\:vW~!]9I ֑VVkI^C~,1Ge9pcJoՋ (Q% hs)W}--;;Ѕi5cg|g9k?IˡYf- ײJNk0UW&.Fet #k fnxz[nt圏dž;ޒ }:Im *,+r5ɀ#iTʀ{U,NL#`Vˌ4Ё^y |οj3 _UO;Q"TY "&jb"fkh7C"aik<}<ɸ=+{GY'BPmF4֮G9~x E+#wk_f;VZPdFv|g9GDEn-YҶmJ&*P| x1G6SXD8PЙqpَvz5(-#6hlklZ\6-|6Fɀ48SkGʵ3r(ѻ^Fl! efEQUF-B>l7Dq _44Ȑ-xx@gY3 f 6X닰MCvj_ߎ*2k3RVmF^f#h8ѵ;SeӬ?G%l#m,GzCqKIN9D"~Xm-B5ԍMe;0ZvZmFهf;txeY[W}\l,J] ^_-_ "[nfdQ4;{Z<ފs3 Nd*8'C.;##jb.,˅,,J[fmEJZZZr0hcdY9>+O}9޷`'i_v>6;kXaVN6p|jjMT S~,J OA ?KY*> !p @җp @ 8p @ 8X]*u4Nrϩsn76xv"56m@A\ܼú7r nzWD3Xk+ȲRu*ER l#3 [#'rnxS7kXmXso25}Ւnq}= kg$/JDףRF`lfFFRtf2_fq7&ʅ? ܓp'vuuZ;:KrYJu=hP^j8gaf 9[Οn%n bnfCvxC]#?4tCׁk1 v$yDnեT7:q-R^oEQ ťN Bv[67p ꗿ`_?kƘ>My* &8ǂQl S)RʵgUvgEf+nmaDn㕥.\2Bj&(FlbLi{Lѱ2q`׮]7m[8[gzϵ,\Un @+T9pv Tn2nRݛ'p]%xfh-IQQ#QO+USZpf14yyқ(ކc_g}cY{=VzJh]lc(tOo,#'96I4J-ЬUhaHd;,TV&lk:'YI=Ŷtu*F# N8܍ ,ק)һOgo~~aaaar*__FnRZ\\=yO]?O^i-V)FQ& FGTʶ98{O/f2>TRq/b\ݓ@ ܝF<Nh);Q+ˊu+{Q3`|bm96qdN\& #T+T@3I)vP7 [gNdﱚ_&^yQA7JhpW+~yYxoK-5"N֤hmDmٜ7LC`<`JnVKq_ShQ&>?QaoR\7<&p3LC@8p 8_vE=寧_`xk\eopz׏qg=n17%0ngqg Mkjjf88|W8p"nyr✁&5pW3֙,eW$TC8ea{TSzh"W \,0qϋM3N=4_vʕ+¬GqCu'qBҐf,z8g`! 8D Uw+W3879 9~B{6wꕚ/:b7+ 6qNy; e7f!/Nx gHA=s>==|øoݶ.[ͣzc:Ȫr'}N뭭uSϲrsLUi՝P/A 8U>1-n0nk۸{”ŕ P5d$"f7Ԗ[V pc8X]q=z ܽ 9ps~e./Z 9\~AG8,o+cK%xV-Yj{(~ߕgݻEARj pZH\ZinMA58.t`ںzJ {m󤡚9\'F널أB%q_g;o]hk?}HDžmOg?pt4Q*!F5kp\Rڮ''tk?UTߚ{ꮗprn/S[{ <_pG/WWۗŤt16uH8)jͲcȣ,- Iivp\R[gMؤKx!V&nUĶ$ oN"s>⟨/!px\A]eݥsuUՎ'ZCzag1u=Y_pC~2,bV+RX85TA6ki Iz[x+ e1oIy Eqo#嬂-g `kSbIQk69J\8c5<~8`ZJK}T  o#?K9eǁo0R| oM&' >Z  /KII]"f&݊G8Еi+W%vnXF}9CRg:Et?<~As:d6fԧs r?q{[HH}IK@qY$lo70ޤ85h64A9{Q ח/Z#W݆x1<]S[=S(18} 8CdYmonIjnϥnM!8(poL^/햔oL79 U51ݱ½% > `%k$cBS/P5Ik>7=~(pJiMo[兹ۯe6piig"o_8iMa<}8/?GM…^WߚÎSpm~xgimOP /(p_<~A f888ppp8@@8p@@p p p8p p 8ppp888ppp8@@8p@@p p p8p p 8ppȟo p8Kɛo <p 888pY8eYү@^E~7Eu!.0+O oT>D(L\՟-,e.g}sow_n'pLQ@NWq׉trx [Y+؀㼶p|ى7blvgUa(zfkG,Vw BMT1A !pGJY R Ɂ?*Sm \N37ȑ0Gk"̖!o5%p;͂U;DŽpspUW U ӜD2-E敥B͚Q$p%cdN5M\YFmn{ۜn-3_Jt }9|JNKӎ\>rYFKva`mA(#T7Ontǚj3e@S,"o$arwO!SJTH9sFsLyN 8cXWDq2d F7Bبوb1P+׆b9ccYi\"ƮI?p[)ùФj jt/_Vz0rI1<Å%ksGg\G~Jt%0R!CYY@ki: be`6qplh洲cc2Z*58MN<φs .os89ps~١˳!5q1B3s(1B`Ŵ[e`6W7pl]'q.+Mq1H#gX8I'%y^]1s`͑=`f u86:siwP9\ 4q0'V#¹y47S f \ܯ~gtNwwh) \L0R;p&V#K܃%ڿvX~FVȧ6d8. fs%pl]]_8 gÿ1)yqAskKd:]~FVȧ6,U^fPglif3m+z87éq漋cp#; ; l) [$pfC_`;ԃٔigx4M@~.p@@p p Mo3MPwj;^vrE Dݟjν9Vu.u2DU[Q{ bWn_ pt=dP4싺քf8A PS]T1N ,,0 DppG.MGyRpDdr&, YFsn R*HA6d$tK&iY=>nI](_ǣ7v2VEl[12tV"2Epok_ xR n.N'rAJ92&iox7Z'a79rpa*|(TҬ8Qi,e>2 T/X6(Smr+i ijTOlb~ a}↬n7{MF PɅp3 ,49:D44 pKp@@7q "@ @8@ @8Ќ uO=1=#8,IENDB`kst-2.0.3/docbook/kst/Formula-kst-lorentzianfitequation.png000644 001750 001750 00000002375 11544160206 024466 0ustar00synthsynth000000 000000 PNG  IHDRiMQIDATx?hPO! N2drsp"!K'ln2 "8t(AAPBlZͿ<3Yzo='$0#,"]̮@# 2Bb!Fb !Gz;ArogQK$.C`5=10o"tHdjk:=i#шq%?YB Kz-jTG24cKb*LF,#LԌa0% AXHMFS5.oF1ft@D2b9IP7M'I(l.L-mZD0޼dk>p |!h(r2A} uv~焢,Ol)6dYgG hʞ: +b˘gG3Ax닂 UgG'Hgט* Y 9 Aí daJ`Zy+7XT ;c7u9Ov:6moCK%aaZZ*&N^#yIhbUoe7r XގzLʨS4)ZX}EM#aT<"X'}̕f_ k!-R\r44j` {/P 42[VQm_~kNZb=ࢦ51Q gM%‡D/ыs]ch47lrrgh&-eW(Qf)Vkҗ:n E)~'IPђN3Wcxv0GpGVxtJiIK\\%D"14VX+~@%a-Tdss!,DZP`Tn9٣GXn6m-yp"|o.-j<%$glNE%ohrBТ9 {@%856X g wcʉOUe0XBRs-0u)WJndmLEKfX~y5O?D)IDV%/Z&hX3gzG'֠ӰR[E%XLnkjs69oQى>p+xK'+o0rƤ`ڎ qK2m2Z}}ު{],[)ӂQ6v+'ҙݣ2ĴkKݗJ[dvjzUݼw[-"g]S5}L-G~&YffO%-z7QR-:5MtjSS`-(:?c +6_le~9Y0IENDB`kst-2.0.3/docbook/kst/Widget-kst-undock.png000644 001750 001750 00000000453 11544160206 021124 0ustar00synthsynth000000 000000 PNG  IHDRЭIDAT(ϝS0[ aϘeb$ {mC-U4+%G^0U_m]ͽ>AԠRgɠ k }`Y3Vuu|V  6Uc"EaS쒉>E{$:A=((#ypw So[nm […lQ:3>=2; G63n&'H㲑7LJ{@ ϻ|VB U4IENDB`kst-2.0.3/docbook/kst/Formula-kst-gaussianfitequation.png000644 001750 001750 00000001706 11544160206 024110 0ustar00synthsynth000000 000000 PNG  IHDRDFIDATh홡\bD*D(FL4h2P(4l08|]uoEqs3ݣ%MX]ʳ:]@ֲ>T TA/XӚ "I]q#z3}}tL3q==g#g08#Z_fPϦugq%{˭ 'VB | Z9--78׭xk7ɺV}ɷi; ۝N1VV+uw \"4'E`;;9*+S E+ GQnZuH;D {Ei'P:@N8ZǼM^B9h7˝}|iԡ%=o|@%mWU`i2SXV8e)$?4m5(,]H bߩ|&ӶXl:Vv-RI7 ¡iimBƚ>2=|XN:z 4mN )օ ho<s0_+kk>+gcv%XJHu-Rq5!e/3NX[躮㛌ak-GFYϛ>fGդNqeFcܕ)o4q"乧OC2"g0{D|th_"Ԡ$r=޽x٬7|Ca9,ӑIy:R{>#=,GS'3#}YP"WfO;w| ci14+D;6dAi@U7cx4>#*F/*34c(C I Nw4fPo" CDc'.Ύx6'rl d !rA&É 3N?2,)r:QPDQ~rݻOdO쫿5 yGѼ9LI=CާpJlzT}b/;ET'7|YQ"S}01q~٧W=q:Phz YƍI>+3y^*e^CWC|{hGY͢48Fur&}hllݛ8nCd|tOQtp">VA./S,%:/"{z "G?!/H?e$201tl8q1HH&D" FK`t i,Dx@@r !I}$^߅ˆ ("OTaF bAⰥ,"D#kI>lbЍpDA}G(P"b?m"n}DrQ\<0"ȹyD^K飋~ 1L"zjC"NG7BB>HD"@";x [ =CA@DUG|2[ {c bct >oGʯ2[.wP D"~ 1,U_+¥KdAF͆G}$D1ݷ`?qB$ ^HÊ|۷ᦅ3@A$G#&D3N PMD@@ "@DPLSWHb@}9ID.Mx1a$(|ZH [0"< mOk˼Nם梨[b8m@!De7!d"2:u)%_knAFeԈl.Y}TD|G,sG 禳|9I ҂K,#_<)S"d=x;'s)4GW[](<2HQ8˭VÈHD...gk4v~u|Cd14|r(ij: WI@ "@4+Q@` fs3e3P"@D"D!4?%L("F<J]|  I(I^o0\'x"JEQRU.^k!y""5=~e@q)+s D@@ "@DH[Bf "5&>HƋQ9 D.j;_";&sb\WMȞ>N!WSϱNr(b BkBR# :(A"}4^N[D,' >өtg dI/}d#[GMkkj]2Bg-k quq\k!qe}e>:  Q/OD?\nk=lV~' s1 C#C_Hļgi~ ]h^d5Z׶ˆmD=;űؽL~#KE;oMؽLwpn3{5~˾vJ{-rNnYpMy~ $N${vڼL{vxx"@Dfz~w蛺HZo.xZ'"@>D=A7=S*ze2>Ռ1HlSgL$0ݨ撩O6{ZU楹s"v*0mB"sQǤm(!lWI>yLj"^È@~|a䮵\M}_xj0_򝳢V6Iɽ%zAes mPUs#K >j "ңVDPBgvy1' EaZ2adDjO~N_kOE﵀"@d[n.Sx^"@"9C`#~ԑK6]).-SV\5l%] wVֲ,7+REFƶh]vtF_!Dt}Q5Vc"/JE",&ђXl+)V'" 钵zXn*/)횛5̾fW)fES0L,+sDVqd4vUCrUZ%dUUՋ *AV,j@ZQkW1*[\5HT6(JUc)ʵDzeWgƌ`"xQ04vV)L;4"Z9Wѫ T3b4bhXmkzf##fئF}ӛ\Ճ1sz}y -@X1qBA7@߈]BAUģz \3_PFRW,[(N xW zc7Dm@Y`]LA#J yR\cn ͅ [a,.ֿJVغ<4j^[f1Z*+dbSŢ{fT7EVzVTԀQQ}Z5meja"LtwpI-45t%f"a*bӢ~v-,e5w<˲f0-˨ܲ A;gw6Aͣ~YZ^^"%),+4В%f%ˬWIJڄ)[ SUjHⒶ1E݆uC߶چXò{Ik%UdewR\5~-&H<(JO(K"= e.K/Y^X#%_\iE\\2W=[+m[Ԛj_S @3[ t]RMY:H|[LVj0[$2y:_RMT=W%F2߲'3Fi^浕E~^+-N趷JY%zCm:FDV^۔|`kvOQyvɇ /HLy#D +PDښYZK~/i0OМ-,|)]]0ͨV [Xτy1H`j S e+LCSSS?pٳgp}ѳgH@2ILR\éI\njUcOIœ܊YȵeM|-ZOB$MUFFEͤY&8lR }gkO9l^dy^~N7GWX˵EWr zl"""__ӸE2 dTp"|_,BsFE@ (K)+NLNz:gb9⛓7t߰4As"=Gs"53n8)K+W XFHYD\jseWfQ2s֍*6CM#<ڏ65Vo=Km妮5VE^˩l֏u,ZߚWwV?&#SjHԵY޻5o=nhn^KZ+RD" D@@DS 4̐IENDB`kst-2.0.3/docbook/kst/Formula-kst-bandstop.png000644 001750 001750 00000002267 11544160206 021642 0ustar00synthsynth000000 000000 PNG  IHDR[>~IDATh/@H6͊ `jPu DUUWAaLM S $&+H6 !pB NNhr| e:޼ EWYIfD2X{N"MOfH"k}u9F:w9ލFY󄜗Y$GjN$mmX ٟGLR~w#39L8i3W%L<x9ܐ(xCIf0*q|0}WSRcގ=v>yz0*'?1 } ʩKf8ZiWc =n H.3%:ZC%dR(N,(ji+RA(|N_hua*tQW$+$toB6#c |Ʃ*ꨅo V^j8_-b2"I^.(Bn@_?5tx >xtjKl@*nKɣfRsDp+LnTLNA B {č z|7sRpRX./SCυ/&BRES1S>:GTlDw ʹm{6$CN[FWLBĶճw) ; yއ@JBdK@ *P$%eߐ+n-2uEr{tЀ"u3)c-0RJå)C5P$SrDJJ.,3XK[(&%6Ay p Ld"e<tU@q)4!i׻y"2A`ADmĽQ ӥ# GN#ӯP$u ;(fgL; 0'ZQmn%ʩȚ-9@SD땋މR&^ߘv(9e7l&jk^޲LHCn-l&} =b$!ЊdrRѝ6=@1 7v4Y /S7qd_d{ukBWnSNdWPLʭ/&q4g/z=g׈ b)\lPV ۫,ź<-ԥʜ6>)# P?eE{C !1p *P+c\J5`I}IK_gyl)c-_!c$Ss^>ɐZ1rW&q# S6Z_Q ;Bi^̞xStR^3(A\8 t+(f F6#5ʶjӴG[W[]ngp\D3եkkxn-+{h1=vPYbKGD̿tIDATcx DrA`7xgrv0q0rZ~8 @Mi! %(0-yà,!%- 0e(utQ(IENDB`kst-2.0.3/docbook/kst/Widget-kst-colourchooser.png000644 001750 001750 00000000475 11544160206 022533 0ustar00synthsynth000000 000000 PNG  IHDRGja pHYs  tIME  %1qbKGDCIDATX!0 ឱN54iGn0̩UMJ-y uܮ3zXUN*EJRՙѓLfYUCŭJTO#\О*nUsԩ$<^E?T@*jT˱h GE{ TSܨ;UdӫUT~cļ9"IENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-datawizard2.png000644 001750 001750 00000034157 11544160206 024622 0ustar00synthsynth000000 000000 PNG  IHDR\AVPLTEĢ٢٫ԑԏч˂~{xrle`{\wXtYpPmHgEeEdDcG^LZKZK[>ZF\7O3I|8M{]g{sttlllddd]]]\\\WWWSSSSSSQQQMMMDDD9CY-An)ȲTjx1d33 $!`gg&;L&aL 2Ɨ|JrC]կ8|JZ? jUa 4yuƵx4 M{]!=C~Z!t,/?盝D乖X6yF&O&E\4)J֘<(HU6_&9{H<8{oF"9=*@$sFeDs@ Fi@?n7AuXa n7RDʒ?-t2rL2pI\F hA:џ+ȏu3S>ef~4T?nz/cP7IŀN&NFk ɤt2Iڕ'8Z3M5_~2?.Dv~)w|LF W8 9u IUʐ/_~Gi]'S|3kNO2?xF.^r@#諌Q96XFԱn|׫ɋxW^w?yPL?W?!+C93vFGaP2~\?))?(?#R?U6={{'4'<zp(y\G咇K咟MvjM$*Jӓ{Hꔰ}`x~XQFŠ_&ԁ~L%ٳG2;e)+G_.5ٟg}[/!97gj<-yHK^Y%O<(.JWJ~2Xrb-OigٳC܂#R@3_\?|*_ghs{yBH7>{/?c~$v?Usyɓy:3_oJ%M}>̚GtoEɶ<_s9%(2%4&a;Te, 2iSzx?g?o_fqꢼ=#2?zL븼0os6i5&OI%?4\rIc46UpqaFo)C<~j{Ճ흝muQ?vnOvXv=O;<| [x>CܳHD ([g7|.d2hY ^]wȯd(\O(]"U_TlnSե(-%zGTEj+<DhOXц͉{|xpjxOÀu,>JOfNF:Z+͈.N^6{]nDznAY :/芓oh{׎znjAHt^=d}֗{5]y:yOBxV]M6s5m>fU{F:j|-QֺdzGZ:?B?t}&66qN2ޝ"zwUBz9׸QuLJ%ltG9GhQw7D6uzb Dwή{adط AtG62腟l* ]pDhNS}cFDL)Zy]'ۘF̈́@4ѝAtѕNu7ѭn>ѩTV D7l[Ndk#tU1 N$:TGN>ȑ- 3!Z;j$ԃm%Z}^_!NU6F:X+.~=pe +ɬfE^Gil*0:r-l>.A?%`HX v ёQDQQ/݂?i*\_΍yΔj~:F>HÆз2f#=ˠrBoSYhA&3b{mhGrt~uPtQz֗s:3U30QfGnE~+ghŜ7͓i\AWrmGK;P"Y­XG_|΀VϨkӉVFab޹Z_LZ)L4QGi'b# emjLDOJɶlKnrE97rQk|2z.N˴s:S98.D+&GU#2UPMM{ѥq^SY3jM48D^DN%6DVgJ;ve*0;ҰJo U#2UϐfS6c2qt\ 8 ѼDkD[ʑA44c&:S2-7 È6FiXҷZ51!#vq }(haAZ2e7 Y}عhsjfzDu#F'ۖ3l,7''Mo/ѧ39+uv\F3nou&tF4x nNBoxTW Dh}nc| DW&cAtW h h ?D-9D[~A4rcbFN@t%_mv ҆DrUx*̪\yM%_U%z3ѕևDVx2RK֛L6%wmC>$RШoJOfŘ*+TטFEV$Zɰʕ;L '6! hԆ7jSXdVD+/ &*[Bv%DC"F}~4MfE*+jḳ"+-gdXKL64DJmt؄7*oJ>c̊2UW֘GEZg!ɰʗ`W~47OGYyTo秺4ʘ̊2UW֘GEZaB'NUތDӣ=}*QK o秺MfE*ʛ[֘GEZ]|!ga-m#hKSqP':J*b,26fLeբh֭W};9-$gzS+tݎPwt"j4.x:eCH2_:!uX0'a;cN Ltځv4_j,r63Jˆ`sْ:2辰DDLK|Qx "QQ҂8ZaIMJvJDWDb@L/9ShdƜB!y5x9ҟ{i41ye?nh&ZɌKjIYpFr`p*4.1o? /]>Gfb#D 9J6z6 \J86x_%b6&P-&2ƜLVg]ՎX0 FbYS>&,򇴎:x$o ~bKqtqK]Jd"gHCN2NJDt}R#1sGFy) ژBtZcvOzm)mt5;BӂX+m7"Hk'%d#һ',G.2!ٜtIc+ٻq.$kBDfnN/ƣ3QD&P,GBb[-|:*v¼KRY>FWC62<%e8%]m=~/J kpLᷔh_JF%騽DWP:Zo+ÊvWc#᮹5cbȵ+CGODž]Ւ83'˓@'1;E{">J! #!`hO s^DGӤ;hGr|ez5z9r=dZ^YY#ԨZ-)kcL.#ED^'vBR.ohoD#>9S^>룓WTD'tT:;BlyB.:sf;G[ȹ>«-}u0Fi+Eًsf+uN'Qu|0эguD7ٻZWvx x•a cA'E ğt|DFDc,x#.DC DCmF5 u U't):hLWy up]hï _h[DC]G4DC DCtehg=h3:h<{h h h ŧ Pưxk u,ѥcX^|=N:,ưA2oC,sd/&ڗIfק}|taџDG97$~v!X$9ݵDѱ(V ư<|?o/PuLm1+Â8 Ԩd ˳l):6.Whz:t,8VD?| ug  u.pD@4@tfZgC97v9t}w'ˑAt;<{\/Z&|6]XȬ5rv"մzɦy`9jŦD U2?Edmx/-f'R哾ּ7x g')gۯ?;y}hD7 n/W3HT:9ql;|{Nz)D[CQDқd.Kܙjmesa.QP*%쑻sۼ._|tϪf:aʿ%Q y%uͮ6I7[_hN@hQND;r'wD|چ([QfWLn?oe DђA}͹5y>N%rk!O7E"X! ]Mgc>)O@M)6.3Ϭ7Kti9Szofm GE" *$4g[]9hV¾q+].ߜOݔbh ubiZS.-%EiӸنhަs\]Ur@rͧo@tl&t3[Lt3 -JW+Rܫrǃ!5~qF ɭ }h}^3Yƶy$ͨ+L4߲Kز]"3nAt=5u'!d+$q6Goij2e3yV 5hnV^ ׁmu9?G!DfQrxEA.Fy3Yf->8Ti96mCNɰDW25#$$LuAkic}X 鳚YLDms^P[K; m> )*"qו+Õd>qhR:I:YiHmԉ|j-khk)@tYMoFb!S÷>tc$e,gw3.hwFgǣ+CWU6kFӌ񊔿Èܜ64Q6ɢIʴ86Ss=>2]^H_J[uԃhf$`֡Y`Wl6t2u3u4kLl v;Dʰ 5-?:3FjڹJt DhDhQ Dh A&Xn":5F EDCT* Dh ! ! ! A4 DC DC DC ^DKW")geӘXLJ D5r(KWdE N=D7юWRd6rDb3dYLF$$Bbb|'#}txD 2{x ӕ^4.1BJƫI6N_SpIlӤĻ.zٻ~qNƉeVqGkA}mC`DOH6ne^G#FQ5\ <ѵF"Rݲ8:NJr#Ҽ#>zѼ_#YZ\׾b\1b r--ƣM4?+CA\  ;_ 1]3^ϥأI|!+L>9҆PZ5[8l7ȣp Z=)/jEFY݋9G%zB&a"8ZmK̾(#赡=xd|];Q>.ܭ\¥}ΠU`~D߰:ҕJegXTUB‘+&BQO/M6h\֛hP7Ԍ9JEb(a(NrV_E3S(җ&.JCTbLG&>elDw"ъS4lՌC΋_hX轨z=Ymm ,k|Q DEc6њ,< +C&y"6pC@t݈Vn82BCBYQbCQ7H>[ qtx-$Z/|ljLGkX8NEGbQi4Ѹ D0^S*  }ףv u?N&s OGmۜR1~23]L4skx ڡ]hXdX8x=20wY0) DhtA _ օԉ}=v2M^D+%Dݶw.wbH3^T^cꦬbFz'yUm4%tB mB4MOג5Xӏ Dve8BCg/qt\hd.($Ht'hqՉO4/Dh s\ChI 3jĨYGE:B- ls0M{# =]=UƑ~9$=45lX1z<S%v7+%wi↑6vhtsf(T৙ wAt=AtW=4 GhUD(@tˏ DhX"j@4    Dh A4A4[J4ԙe&DC DC DC DC Dh h h F u 3K4n!w 3K4 DC DC DC DC ߘUzWB DHT@tmzQ I$ynoXlj cdg+%; bXlF{vyʳ$&%;],~2iq* Ds1Ja[/2m))mm4p).&>DOΏB4Pxq;YWaǤFc>1枉 idy @t(10jtީx)KKD/$Ph|$Ӌ `CsଃʋukK6g)ѾDH4!\.kCR^&(B,"EDGB& \4!:gWwI=G.+&: NYkň4. sA%<;ml}WJ6DsrX, Dww Ք' s&u_!?{DC]Mt7 'DC  A @4!DC  A !DC  hl1}:ԑ*K4A(Dh!DCZ)*O4_ ] + s.4Ht*$;w  Dh A4A4A4+Jh-+:D bdSk DPqz[~~}D'\ ]7SO;VU6&[[Bﳹ$mSM}vn% n .T 8q:}tD'3y S[ 8r2Cu":i{Z , $d%3Bp+u% . Sʔ(9}ѾLOJt31fWg͉s=f#ghf*uS0h`BBp[=⍞/i2Ec 'o U@PgD )h\@П"9QeG8QN]=pQ9^Vd>\#јfNBg7OMd:ɉ*Sv*u`"F2.W{|lV[ rhr V?$ ̕ap?umƅaD^?-yNT9^Mέ*4k,9H|f3y?ȱKd6w ф,q4иPhOK4٥;.@vs7S޻ Dw)u *EmA4>5yIQ(PD u|Ǐ_2W h A4A4A4Q Én \}]h89B04ъhj @4h!m-?#m:fW*1&O^IZ%PB_q/_h ~M7 Urǩ@LCPKf`%?IENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-datamanager.png000644 001750 001750 00000034267 11544160206 024654 0ustar00synthsynth000000 000000 PNG  IHDR&PLTEzZhѢٜהՏӎ˂|~xspd^y^t^lUlRkNmGgEeDcDcLZO\LZI\A[>U7M1Gy-An)=h9Hjtttkkkccc]]]]]]\\\ZZZTTTRRROOOIIIEEE@@@999111(((!!! 5 tRNSOb5cIDATxOX8 ^,ͪBwRѨRGvj5j5۟}a)"J) VIНe݁ >>v쐄[ر/r?Pa .Qf~JпM[Y"5zꜚ|yf3[@u+Bstr[[J? ?}󠻓!o^.hHDZD/WD{ !{Sr!\tSpX%:"pȫ/ӈ&]={LCR QC!JyJt8 w~Wѫ$9F4h45t\ѵ< S_Eu(UCw~{h~o/$N{.X_E&7_]&H/wKGW?}|ul믁SW~ݼy.0P%w [/'q4[}Ӏ.z6W_^YQ_EI+uytynﯡ+箽\E?`~.DߤH3^2Cd[o߾}?.x:[(!9ɥHߞt S޽zRsivKZ[9ɝ&H#Af5KX~ HiiҀ4ii1  7* ԈHn>֩w$@|6cY :5',J#Ž_?iWDRWhRqol6Z;ŽT9wWHuj>fYؽ2<}#ʐv"'7.d afRQAi~K DOs$]r=^;!IiN=8Twn1tky k!Vj(l[֒iGN:Q)b2H`ɝAZs'` e&:UI9Q]f{&HO':8`v̖Kx4/= =&F̰ިX!OQ;&>9i^:g-"K?:Rf1׏&Er[EG(ijM#{$džRwy#4+&ެFӑ>H|ϐ&KbB4񜴱-ܑuo=MMmE*{L"Z냆td'~[n$ghx{p)H6U߆/d5HlECZ u@;QeΌK:}@܆#O]ZMBZ냆]S;Gks$ǖi7RMK-ٍ#?~4!}4~c.NvϜ'l8roJ*s܊I5kACtd[D@%[Ol+4ymkhTbS0sd6(4r'ro^:_?G/d@BKnĝtZ1zK,J )dߴ>N?#˕֤}]|HMGB\c,hTbSufyit>z#՗bϯ[i~0{鱘ѩ+xڲmI&S#M/}Єv_ZDQZ+edwr 59_Y`~c3OfSvyDo)ŏu/5)D %^m,M3:GڇWrXyu^GҠ:G5ف44xiЉE44n"0gcClכP1fj$S+mjfKEAlzwt#Z"ݴQ-Smބ653֥ZJPr wYZ^)20Ϧƺtm3WQTK .hz"ݼQ-m%_J~Ղ.f-M㥍Q-%F`ˤUፚQ-P #nlZ-#0Z.vH9{ H[Ւ?j&ʟ֦^:GTKiTۧ#u3%ZjjR@UG(cSlZ-⥍ZJh .;>@J^U2eI² wHBIk=6j)1[ <<@Jޛ0&E0Tkn1i\㡅Oh9+3&>@JnbK6AӑթFb͠%n BY,/'Jh9CT&ˣZ 9Q-Fܪ[Fzf Ƴl篇b=x ]#/y-xPH [><<j(6G&3ge 4Mm;{fGeH?H&zRi҂?,ᔰ=cH {2u,VKix^ԜHZ/rN3 T^Yݬxےv16{G&i'?=ėv)Hg Nq]5"H{ՎhJJ7 OrZŚ|-vHQIvx?"u@SXc#ҧzDQ9iJEڋpє(5V%6sz{$wגi}G%%AgD{O+Ik癷h Cw{IP *yK& yIh QQψn’7([gLս蒞H2SrhJ>'/ MliIHx&/]q\QP E"0҃A%SMb |->o@::Pej lґ>>}AGU=aw;\rٚTC-!$ϖkɅ!d;pMU'G.n;t523fcquzzP7S֧4ĥaH%K9G7H*~Km2K<MyHIx.qoI--ג iCtK vȣ%J^|$ϖVkaH{#;*%َ[;WL ̱1[5, *iaÉ-I!ߍFKk\@V[ {UFtEHhDXI-גKk;*%iqaϢ+Gn^ƛyCj1S)z,;n_[hЀpkPr&b0Yp ߫Pu,] D4!vb$X%'lG%%qe:ܹ֝EԦHgޗ%ؗTřqb }Io@'eP2,MI$ na{%fF NKDSXHPJɐ$kɍ(_ٴtdH;Y?űC(3%7U ?qL$6'\<A4xiPC# @͆qL/ q.5бDBK tlFn-A#ԣ~0$)ڕĹh}("9*p/P[*O} 92''ۦ iFSOqIn?m{ 6EP#W>t%F.&6 ]TUVBj{q4tUv4TDq$϶m`"5 Orr-釺%0B74EP#Ww_pd4›4EF9~cB=,gtCG/2'c'(kLĒT/MtZTO?b H82G=o=;|giJl4Eڡgǰ܎|ʐv>s'h|Or ]ȦjLĒT/'itY9>$ ǹQ-JJ~.,;3luc36$|"M#5TInM"H}a]X4͈J\YJ|>v#=x$]y-q)"Xr%^\ZX|w:HG2GD`|]x޽4)b%LK Bя` ׮46 !5c_UW,TŜZZ˿2ϰ`v}Z|6M,6hy?Xⷵ?[X[_] % "[XmjkDzvm#ۿ.3ͯ 1Bk3Kgi^.>'RgVWWuاۋ_擜=gS#k$?TKUjDc)uY$bR<;]k^l,^Ofie _:׵qacoW]Q|W W c&ϵmt?ӚHm-^_/~3m>ɳmnf5IFZ$q=cVt ~An,;Sإ~Oi狜SSi0vBZON|Ƌɍų]kk_/lN:Vӫw~ zllu}Em pVNNvU<ۂ` X" m/V$7yl^ 4Q-K={uXű5@zDagq^dcF6 ֫Jv}zRWⵍS?)\]@] 3V}Yb#Mg6nWt`i yE׺:䠣MkaPҚ4NtqL)1#$]z.ɲtmՓ=K] mcDƺZI=[zj iuR5 +ٳmYdK16)2ϴvhAa,mM`bY<סB]H3/q}-ZƑuquzLWMA:' h'o(PMim Z)W_V[7(/ _5rϮ])(n@m,z3tRX|kc}rmc_ۋ1m5KـwtU4m@O_S+ImJW ɨy_{gee١ǘE\?<05dgT?[)J׹Lmϔ^kcmmjSH rs!0(]M#mSa[iК ]6(UZ8A ]?/]3-t>/ : PZuA@/ GץͪqȨuTFUVȝ1 z/iZQe63Qީ4#jGOɧ)۴ff2IϺw1]+D,-C鰽$bI!m2g% '143ymvO d~.=sŕXZ폧w Or,;R聰:#Ց]نFhMM;FiFЅh-Af"v&'QҎ<%i]͢&w\ːt Pkr-& ;xA=q ;Z'=!1 OB,Ylif/V]MѢv˘_KBβ˫K&,~SH[4i9zj6t<9 f]̑EM“1#J階ב+nI o$N|)Z~NZj4lcRfbӢ֠H=bY#}-iKk6dLhx/FO4HiKӌ`]Ae8m.j&59e%wђ!#JiYp+?*4ɱ.ϗuPK:UiXRfbjTElXuEO^KڒM6Sr =3 ;q#Mӌt"n6t$l,,KQ\\+eHIbS<$Ǧ{s-::U iRfbj6T{L.,Eґ'$/ҽ3&Km,1{~%bX:bLNg]“jZ8Odoz&mh CZŘFO,Yltf/= MѢvIR&Qd"i&/icJ9\fn#)HI$}YXrIZ?.<ɾmw!BZŘFO,Yltf/Vhaq#ZIYFY<^a%!KiFh:Jky!SK+`Ih6,,H,RzIPΫP OR'=!1_Rdfёfk,E vOBDgY^eiyiɊ֮N 4/z=鬭{iH%`R30iC,S] ^X5\`R30KdҭX ؝t%\29^dFz?zE;&<"HGzx~#GKi6P'H;Ol*,ir SOKK P*RYIP&kU4Tw[d^Zɟ#؎k1oTKmiCmgHA2 ]0xIj)ryQ@ShY^IJ%_ˀtZD0EC{?@vWS $%*j$hy+~=9'j8w9o ψ"SIH[2֪E PbA# 8HhdÚDD4|T zv=F_^Ӊ-6:yv.ATKGM$p*2FDrQ-QbrFBrDkk.K Z'G'$/ sA4xi ^XZK05TKzi=d7ޣO)O[~ 879j)\NZ42bBzwt#'Ιsʑ\-kT1ˉjZcժW4\-=@T ¶m1{K^ҐZLj? D`Yŏiӆ6QeHCj1;E (Ւ(n34jZ?%'(6e, Z cGިH?KM?iQ-G~jɍ4 %q@U!W jK! \-Af#]—@ji/ *'U)W(/"yKɹ<Bǀ稿ѽsd֟gu[A5EYڬGx )W4!ҤYǃ^(VWHrXͻeȴ^tHlU;O Oā$PgjG}4=ݎ t=xi1"-˲?fDa?uM~KY q_l#l0 KPE> fiF=1!ьq= )zlԑvhKןNN,K%?Ǯ?;{R{^؈4ϴU6ZTXdfhQ-s;2Q-"[IEO°v ٱV{j-CZj1~jr&g}-jD4O' Cd7mujޭL[i*b(2.*^bQFjbͯEnAb(ra4C( 7LC\-Z*ApR-Ίji1~j>OiKsT?jKO$e~ji .^;Ӑ8WK}lŽHTKd,mmTKƏj1"Q-Ϗ&S>cZD42,dx GĿAHJOuO*/mmTK,2Q-~ B !3jxj<@" Ҁ4A4Hi@H @ilHWiUHcK @Ҁ4i Hi@H:iPS!4)晶q@THL[YiP"d"H+TH,'<MҠCfґ~BJE:wa@PHL[:Ϗz4焎r3 Hd^ 2=!(4ΐ }ҠGz\QJm;GF3gҠ@ZKŞ^I3gҠ:F:u ,HKH iH?g<@M4ǖ@4 A @HҠC2j ix#i@H @A4 i Hj4j6w4*% Hi@H@4A4 i |o;hZ}4.:] I*WrޜH t.M^-s>wC=*E|,='SvYx9t$h FxJ-t0:Hi,-de%zx,0!> Pݍw{%fөsB:[6.AuLC3^mtOr_T0BiB@TgH?H&eanH3=;>l֐]i s'A3N=:h{H H= Q):aD:(ϥ/̕d itƺixi@H@4A4 iP퐆Z&C^j.e @Ҁ4i Hi@H @A' 2 :* 2  A4 i Hi@Hi@H @Ҁ4ҍ.յ2:ېHM_9Z<4&ioEJ=iAt igzH4nxYCډ @45iynDK+D4.Ҹ!nHi ^/ cG4ă;p_Ҁ4 LH瑫mںzG:$;n8P=/ 1J A @A @A'ZA<Ƥjak; FBE\f[wtZi@i@i@i@:Khx%@15%V%\B+njt2Zn"M_;{VQqtuHsc露?2 UW5|X>QaP'~Kv~>O;=W&!͌m*[:@)ܭiGJvT_vw}.&x"v!%-*o\J\$8#EZ36I'3+!pw];)HsvcVHLTFGeHܺsd$d,oJً)F`I1G*0JAH#͍ T ٟ"-t:/vL2u fEZ9*/=GuUFcgX(`eYKGO_PQ ]>ҺU]3wDOHۜ_N}vωԹ>[XZfRݦ Ҍ>yM  !ttĽ@GG"!!L^8р:Nj;!J]BTt?"_^RtWzvKWMWfIV|yHީ: VxAbYmQ(`*ciW=I]5]Al+ ѣ9agXҥ"=]43a^6zd,愩lHۏ}!iNGeHϦ}=:IsݶiQ(`jJ As| %]mYEC%$R~es.ia/{" iIRy;Zn CN'bs? 9dM>iNGa 'tFR2 fx"!xt,Pd --9Rw|BU#?0 ]:gz0U ruVnHGrHWdLp x4'|4 HҀFzyM2&H/Ҁt3 I^&4[} x6ۺjiHkD^hTyS4ii    ҠGZyfڨY iZF Pk!Cht` j"" HMh4Jo>^Y@ 56l[^IENDB`kst-2.0.3/docbook/kst/tutorial/Icon-kst-datamanager.png000644 001750 001750 00000000672 11544160206 023420 0ustar00synthsynth000000 000000 PNG  IHDRĴl; pHYsnd tIME$;ħ'YIDAT8˭1n@)srB|44).\d 9@Jvx +}ɻ,}ibV~eki? 閼J;NAxs({Z]{8}|Bqp,eGtwh0pT&Da .ʼn&ˍpp#~;zrr3Mq}'umk8AmE&\ęΓ87*W{K  GirtA8?,qV̪MR=3A[>>:::777666555333333111///...---,,,+++******)))((('''%%%### *d[ 4PPPPPP(bIDATxoG~HY2/@ "&+ i@%`l ҽ p$pm† ld,D6k#Ûzq=]O]U35OR2k?]=]_@BjaR" "! "! "! R%'Lqy>([bN_73ZFAjgǜNj*[~I/Vg'r%E2 VURlr$(VYϘ~eޚ 0\44`EYˑl[Nq5ꈥ%*U9QS 0h+!&J yO"/5ÛW@׉ӥ N_&F.ڷo6wFosz4/쓡/.VEbieGSk3g`0h{Lx%DIe[ Z0}^it)Hxf:ן!Z箥 ωba]} :YpnvTi߲s7$U^rlq|TkKͩ:(I,s3'n;W.}?LǞ/+FT7+!-ez~Ck Ha/s/kMQW-o=KQ>? Y{?f'j/3=ju/S9w] Hzӝ6N׵g}㇜XKD/ӛνB`9`i{B[xq^g ??{ oF7mFZ ~%.B=xu? h`4@@$s}K  P~Qfb0 NHHHEuW+J\-# Z<@@@@@ة0 WQ+'%": L`JLύ"8      6ɧ`1xUZ9{}:S<uz[ʼn 'V-<Λwjv(5ب_#Kctl(:z{]pQmm";`RQO~5`w NF}I0h`"6WWWeeit{/s >yПzrǵUs~Q<_Ypj_jz(s"L\TKrRmv3rPΞ jXRMF;^ :G0hW\1yZ/6uYjg   `\T 8 c F@@@l IUnPoCV1lBj9IQ=3KM˝>}Vr0`G,*7N{By]}[ZU;T d5Ь =AwoF˜@X4 `F@@R,@)yK&"v&#qRLFH : t7*֬a@ ͷ"qR6y[,*Bu'# Zk)!h`"Bj[ w<@D4 `oF@X͓&ې 7Qٖe{C|PkSpjZ={S_\2HʉHzeKI u,@@m 02 آi.O<e~ȳpͼܤe#1gD72g˹QH` ^.`$@b Hخ 0 | ʽ̳ л@`M  \5]cm (ٴZ̛[yS·Wf ;!Zf>0\6zԺ Y.w3'xn0})ɔ `WRHAS#K{;9L< E eM3 {7X`N4C2@ X{dH[65g|?P6;b's栥7&g#.5 `qyt޺i$;G'TN%N%9lFs]=XFJQ0VLw 0I`cZjYۑ 28@EH"@şfv@PT7i^H՝ fxR 5{ NxB#&T^}0; hA'#[<%I>@Υs)L\:_G?H;(jϗM`d:aK{B iϴ$cH* $=@c~&LgXݯmf`@+O9@}( `9}"  K4R @l F@Sp\qYj/`@wULJr#1RS0gsI9|9$'$,;IHR澐$3ٷV&Yy`4 `@+0 8:%w  FR8q nc*j@g3Y_zP yn7J7+ t671@HI Jz)#1HOHsS0``{_y# o @ޖ U@b:W\0_PȕuJ=2 fF>&^<@ s=\ul 0+X^}nTs72 ' e. N^ض&#==0 X8JOwӯ{ @kR{; t2? NDH? @IT♕iP`4LJ-+Wѯ 7Uj^6@^)8!u!zk03#w7zןy)Lz%ԃ- \dN&"7 hQ0`NHb@lPg7@" @^@@jT @2H4d2Z@hi0Ѷ &Gj닾Ao@VCRP0i*̘~Vd]uqX4قG@@@H!@@@h |Fː^hDsOm 7ab;pL;5;xF M&BSn, ZMg@kӡ)/_@Pr*`Y^T#`24ɯK @)'U@0܏f%!   :{3b@@$l@^8 X4 Rli$ FU0F6 BDбvz FB2KDB*$ ""^7Xl"+t jS3 Yӳ %Wj<|}ymzb{+R lBݭRe-|~\rY-^)nOM?<4f}N߫ )B~WhN;[Ec %*$/, ^!f˧9hs +x&.-s6zKT([p IuӟmvϬ|Tz/A{ӏ%PXot^;k;na=^)Œy?ho+%f/UhdbkV[%Wj?|_~cPXhfv so\a~WhNFB@$DB@$T9](W_t/ŅK['EX6'@_\/tnU|th:nyv<*!:ѱ>A44<ч@ +c? ҎW++`qzsz-iO? 3st" " " " " Rt&n<o-p1'/-O^YLKA 5cy3!:)/ ۙ$ZNHFުJYd`۝yjc:O[˂L(k9MoTw}Ezn'J?⮥x ~}൱ wGz/~pInҩ?#?ߟ?/Sn?;3br\ԖͩU%J%yj'D^'jNSxU;q:=VuNV y4?3䮥3Tyª~ͥߞ$ދ}fiJ~YyyNl>Q箅IڣߜZU _c}-7 kirx6jR{(A;] RNR+Nuv-W 9/ȥ7ϻk78<'!J|z%DI2[frxJ:QzOnܜ6=zׯskOg'{%eޓZCoh͓aW4:574VebNe3ڡmgi>X'!{F_Z]TE,;D/G+> FHQ\k)_ 2"*4ό l.1 Y3֧(zf.B6-cF@ G@D Lk2W%:*1 ګٽSޯp<kj?ͷE:^eYY` >@>l'zk|D}%)_Nt  xq^g ??Gow|N 1ص#{ okN~5tn)kvn`^}Rh`^][u܏evm=cif)aY~ oF@6(@ٸȬ_yEye;L>( NEO`liU0[U Sd>@ ?P +Sц7XKڿ @l)UYk2@ޙ@L42z',+~ĢYrUre%EVd\UN>@ П~Q5,z4h EEY-CwTh `">Nh`">şfv@f yO5 ˻@L\B.=bGZJxB#ZSz*q]JNdA,3/,\ PG1Ҭ)\AyN1/)F25,yf-~ 8xخ.}6> fYwt/iv;@7#  X"@>o+/+6Y @aTl4[1*UܩCP>_"3hS2t۔@@y hf2Y6@a@@@='l\==Kw} R|SU L1l@hz4b.KB2FdL/w@1 ) $Yd u2@T^-͚-Ƨ!K3s,0#k[aY779OG=M~`%h @lke^ bn P(v8@9*n2-@[*On8&њ\n`8Sh5e6:T[ߍZm ߽ {,2mKd PI_<9BTna=^@1R"@嚕C"-t|anM)@V0@ֽY[dr&{`{V,`n ;KcL ``~@u{)_lFH9 ]~'l}+#2l F@@Ⱥ @, kwA6@@liBѢ|#(w,L4Aϸ8 2՜rQFZY)筐RI#3"0Sxd0?>$e { @, (X*@W#`ehؕ-$窧pLۋ$7Oo6!!*%`lS(=S 3=s@+9F }5@HbHFg^ᱼZc v@K# o Ic 7 ){`4LןGz#t64͓ 0rk@ (/ #.K H$Dl:[g$*Hzқm4"]bzSp4J9E ~Ν %pp[`# u@i*8Hy Pyt G tOCKEԌ۹7p Gf'fM j+`:k#`@Rtr־ MX@޼m)#Ӳ1ԿJZdIyv> ˑvz?e5e 1N)cIN`[zB5fddx.!C?<A86S JzRf{#mȝ#JS$5@J$#P*1 φӫ` UQI  vE`G]Dg>I> 0_s{:&\̲;)RqEL_*%M:zD ^4 .i"bF@@9@  \N  tWh[G@{2~5Ey_4浘He{Iw~V{Izdn)Q}F0y[_lh@sД{f ZME:FR)ÏHL35Д Z( M9z{]pQ-.3)O~5 &U%r&=~3f7s]Iт)/˔`NfC0_spVۖfLL|IL<*5=Û5w3 N(HPoSIޙ=z c+j:ve-"F4![Ñb0՟Y uaZ@)t.Hٷ}u@"EVK:{?f_|,6t %Doju2iXU0; q @@l @JI5SD&CMAcRӛdQQ[ 9 S8@JTT`֏9#`">N8&h`2>`!@{^ EQ 5.(h4j>dewf1kx+gk# bX/ D|@@  6>HcR5| [1     ;*XiI { oP}Q h&G@$ @U0\bOo`LY-CwTh `"@Nh`"@şf ( PO4O9e P*/^-W̎j`:H=Ф,D@M݌=nF@;7  RMÔ)!v4 vut,gn fBB݃ AB2KDB*$ ""^+!Xl"?J+t j^ ==0ZrY-^&Ç7wߦwǏ~,"n, vslV(M§%WꞂnAVDcCsXǞf}x6{;W(o M~ig~,D ^!f"ބ-@:Z NNE`<;\lߐy@YlF@ZCO}i«@ ph8|=G4㇧ȟp}z   Iٕ˭'IENDB`kst-2.0.3/docbook/kst/tutorial/Equation-kst-correctedpitch.png000644 001750 001750 00000001444 11544160206 025051 0ustar00synthsynth000000 000000 PNG  IHDRJOrIDATX?hp@@9 Appqppnppqrpps:t蔡 R28dp)tqsrq)(tD(ţXh 5 8 $uބ|cw/rD+ޠާ8ǀ':|"3;@>6S9TNhI{QWiZVAԥ  rfrg)&H P77Z'05{)dxL'MM͕݆zea4S$Ͽ-_UW޲Tpߗ1pb>:wt';bȹ睮1>fPMpUy<.=7:6h:rUۺ aQ޽G]r/֜3hbDmHiFz4S 뤚ҝ7A܄d@-?7~{.oA-i߱JreZ6>|e?YÞ}6IENDB`kst-2.0.3/docbook/kst/tutorial/Symbol-kst-theta.png000644 001750 001750 00000000373 11544160206 022634 0ustar00synthsynth000000 000000 PNG  IHDR >֢0 pHYs  ~tIME3"bKGD̿IDATc_kgb?'"=3 U`:fsL_ 4r C2Sȹ سA,aG\dbq[ dx*96W$p~$I~{4IENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-tutorial-datawizard-done.png000644 001750 001750 00000045310 11544160206 027315 0ustar00synthsynth000000 000000 PNG  IHDRM+bPLTEu¶̯yzqsllleedjGCݘ#٬l|⺅Í̘Шݢڜiבԏъ͂|xrle~^yXsRmHhEcDd6^b;YCY/T1Fu* D{rh-Q >C7x_(##΂r:LD_i[QD@t}rħQͤ51NӸēR ,twiH,uUzoݠ_$sѨ;ТD-h~7n*f$B4i-h"kB-RU_hN]HjPWǨлH~ +jA]X|$=ǽ{h&؄Ψ/EYSNw4 +2whS]/v\{p_[Ϣ _o+{[~OcB Laѝ ,=>7"hёGwQEU`睡ߣ;Ms!ޑ}ݾw&yc DWE=Ti4Mei7m fH>dM;'3!*.: $PM=ߢ ]=~h{$uָ}Kz|/qp3gyœ2-,;7+;7u,#[-i4&4*i7mUR a#Kt,"M0&HSc{]'Z>~xu{n[/oѻ;4 u8: yq[2έM<unhupvX',)4NiuBQMkf]|!ݯ?A.wD}O>xGDK/]8H޻sVERFWh{ 4s9Ŝ̹<97Nu=8ڜwFpJQ4"WeO,aۿk'ww]X (no}l#wH"աwn|>xBCs99|qn9:sչWvU,)4)M)4-ber\tr!&V,ׇߢt|wԾGImFuҷBWnyc*rsztnJ8t熠s ,,,)4^ЈWhT|˜ǕC;'nr{n->u"@ I[C$۷$,ඨsu|/,SڞF _.5e{Qٹ .q,iHwv|v78U9JK%|%|)m{[',iHOdbi ħQw qHSac H H 4 HB{ W& }WbLMk\B֡~ H+'{34DacuPL!`MY⌱B\G3[k[)S Zz86z?ccWr@AV.PgL_H4egzޟ٘qxvE] *ɵok6301jC>h ۘ4l9HZ:]^Lȴto^Fnw'[3Jrht~#,mft\Eh$B/ŖN$.wAPC-CK.+=:ɵ^Pbc 7#&vқK˕6"mߖ0L&񹉬!zjSċK};Z"K;F v1u j2f8=0Fgf79[Z!M+^/Z~㏏˕6"mߞp0۽=l[=C<.NdxZQ=YI;"]MOk|hH[1c$"ڸPa|h0?^/Wچ=Nj%W|#CZ-QMZհH/&É9x M қ3!Dc -LE뱑յq[Kݱ +xE'ccriGTߚH&Z=zZ/֢fYx%#4#|$@cq YmlO,T=Bs!5DUӛS룶BH&Y[ną@ҬqR5kB"52Zһ0 V 1'ksA W DGAVA @s!ra̤r 5c- d~Z\msTF`=`ksLs\ل富Y?㫟 #LBzF_^6*UCg*`X9ku*ZBLzzϞ-]1rA~vvD[҄2ҙD9ΣmEGt.%?^>=^ܞ@{@s c{C?>8;U1"z`iN=ґ!}IP>:U5PRE -۪8(rɗ.Hyɷx J͚@XD~*$DH>|Ww_0)r̘r[wuwbE 49QЇ*L0.=YݚO.^"z:UW֖"\HSl߼yaDj8 嗱UN cY]HB˶R#Վ+WrNdfnFR2kIaK ɕ-іΘ>d+_VMHǧi%[?xH{s-R$q3gF8':k=*4/_;hf.^ϯryr1ji#V%nҵ:՛Ј͆ qV[vt7WXv. *߾䞷-BrJC؋4[:=S.e𻿔忘dFЭ*ѝH +r,CMke1=MX V2OF8?_oYdDlJ/; 5!,#*rMB~YΡGL8o4? ! i4Sd 45H4!dXB!=(S`E)*Ҥġ_ɤYK+L`>MH%e!|E̴-.|ϣe/IQ k_Ԉ&3 2?O92~)nAHĽxy(6^m,=ט)kEjx(ƴAK+L_$UHr GKB>ؚ+ћ90,j:dS LuҦ.HȪMHJKw{j;/{9H`EK}k1<ޚ31`xLN sϯ^e|)џn"M#VcͼL\#'D|hbSy@eXڨH2ғnHO!8qQ*W?_``y-M*0A̴-M޿D[O2ҟJrY./~͛obu]= eo[ -]Є6;]]4uϗeZ47< O/+߼ֵ4eZ /+bs`!@dP왋8?IhxL*QONӇBRDZWJ'y#]V$Z&h8,t,Ͷ4z޶h=l䤎4%Ltu+L"#H$bGz}Ϗ^GtqKl=5 5K~=m әO?2=??\crUK|!i\jқ={LKUL[ aLS+2i\ DI )W|9n4yRI>j5|!Rr JH VbH#/aEXJutdxәKf{~\O <5+ҤDLC G<45Q&KX/ȿf>cX -A?^`F6ptyybKS VG|Vj|C!ZSpj!vu*DZp; VeRev!ZG:rYXƥp"t0ƪ/jʐv0ǕW?ƥk/ʟsJ3Uc?\<5Lq`A.Cۜ#CCԖ>iG:'MʼnM]ۏ0ih8<Oy Zz-dxA;20I%6҇1t ^Z`jx!s1b^ KՀbuHY! fŎ5+eÃhڷ-MzVղ ,oxKk@#O=RFY{梇NoQ;:ҷz{ëCg?9I l#ikic|iɼWK_bҤ5e fQ aB]vN1bDM*`D[*GK[eЇL2k<*$qXV<-mb.U!ZEf=a!lxgYJyN2_:Dnff.O0.ܾ=vj5:tldudD"Q}Cj0BNڐ&[NCx?_oۘthƍH!~.4ff*GC&oL@'e#mbB-3*,se&{ dBZ i==vD3&[Pz02qJt?OD?Lri5ΫYGf2OI?ɥ#d+M3T,- 2aMZPx:aWas)eX!a҇ͼ@U!E &OY%ZE`!e$=0#:̗VCl4;AB+f[Z?hI?dMd")3D J2l],Sx,k{ ٓؓ%HbtM%zm=,ɆLҴ#Q'60mEڭr5-,LuJH0- V`Zw Whf{7< tXJf:Q[)P]qNp1)L;9bDZ_oh{ *P?xHx|Nl;PHqt2G8ZayС(O\ (Xrޓ4rZ- HliA@vޡiJwO$HӋYKf %NH?QA4s1XVi@'A4H~H(94NAZH94Ҁ4 `K- tS17dz4Hs3ֽ8z1:4H㭧q/4HmZ/\*L ;n}ܚ'#4['ÛnGQ@d'ҭ=x9IrϒYLffY $#D#+IȷM\I^8G04,3wn?Y/GXkqfhd%&QQwp*62SS$m6Fo*ktHhGShO!V=s45cIx`NVh`"t:sYc=/i h`Y IӃH? R ,2U" iNVcF_SQ#!]9Gp!9w.G:'wgPH7 \4 -fKK^`:/>t0AHbx/}j4hi}bi :Q|rNVpc Tos\AK}D:Fe_<Ɖ#i@:@ZC5扥1&w)m y@Z7!]or9Η9vz;3'Gv|!Fjz@Ziox䃄 -]s-]K5B:sHگ\|񊴥0Ҩnry4ҹ!G}\*'j&*;65F0TٹHb}6M.w.yg4{tT17] eõ0<8zR\޹D:aH7ƝQRT޹i˟G>3DW?Zr)r"䤆Vp5V>)sc>t@֫iҀ4 -hKU2:ӐWΕ@#RsKjx*ݩHWXU<ĐF4rBEȉ.dټF9i_KPiE#-=TyzŲ*O@VH+jyߑ*գTZZ\ڛOjG]F̓Ԉ{P[-6!KSgZ ir@:9m-Նα!v--0 i'N,݊mDU Èid̙U0ȎSr7"m^lGjt6a\>4"v,Ҟ&Vp7!GOGyrimzS䄑M&BfkcVD:g0HMrs6s9y9! IJfr iFv3i6#mƎ4 t}Rϝ6 H$ؐ%li" -U)c@6jiHiFC>I}-ijAdZ0ِΙ{Vpƈt 1Hx7T6MiWA#H7硎i[J ii@H6^ã|ZZHqIp .7[+ #͏ͱF{6Y!s^GK#mi]qWHkV7<|H3F͂t3M:/2Kě}pigC%HsI-ԒA>&@":oXǶ4,V4Bj\+n:G[Zr!&@sji3ƲɓiU v'՞xcɸ4=iig+Frxl8hiэdrrfj c$ҕ'bT5y-mgͦ i$I,rid ==tfXHi%<wnV7"tZB7&5+S6>Az@ZG˦>XI -nK>hU7+j ñZ E]䐖Ra߮o ]% @ZJKˏxZZüQD/KiH 5ٺ  iu)N&9H#)X[# "I^-QH#AãFiu)jiIQC!Fѵt!mlrHb.O0Ed"m15mQ .ue1gܹg1 ^6.x(HK#ߵH{*LآH/' ]?-]^1 ui7ɡutQs}X>v+\X6yCb*hXzlstQăQY7=<'6,H.ƏHH.8FGk+iW;m{.x SU>7 M3T/]b%b<'- XK{6bstb*h@`\A@vO2OR7O^BpAl8:eW€"4p"yu6s S@"4p#^DRs@"4p3#ݝU~SJOvEh&FMKOzW0A@iL=m`@&-9 i@ii2@D"r{a+q_Nj}9%ٟdzi,e%T&!6,kTǾ$Fci@E6\h(cxl88U" w0b1c$/~Nb;#֌!ь$7NņQfjjtD4 "\hMךvvF{ e-hOM-'h-dG1 k OgI~QDp Y n\T&aZ}ܕH?=LBils1: HHz!"ݓxfezo*qt>5bvnJڗ~ {#K У dRQ)@#+ٱo3]Gt,11mпױa#]UyǢq%i;Dk5{g7G- D&@^l^l!F?C [w=9jl< my0[:@[JH[! XKK i'@C$HlyF9!] i~)ԥogĘt tjhiMQR7ͪKPKWD!ua݀8tK NJu [BuNH#]BC╵ce 1<7#M' -jx]"@:`x,;]J;Lo 8;#]2dZ2$jgW.!]oɡC?kx"iMK#ۊmD*tZ4o}hp"m1C0 m&jm.9!]rAL͌Z#4rX/ Y钱F,пk>lńwKhl`mi[% H #m6<-#Hг#]r欹K%'KHwLcGs6Ҁ4 Hi0<{ؐRUוxD|I.9 mi"khqG%0<SKH 0<1=ldK<iq@޸C^ ޱ2N7[A͉]m/~ĕ[:X[Z\elxiٻRug!]+Ҷ!vh`ꪳw逑'=HxHf !ͻEi~F|wNwS2tTƿK.]@:HMK՞DZ`U:{X4'=AKW1-ퟖƼmɥjO7+Cl1Cɜq9r'U ;N*QܖxD P%Ki@ǣJr3KS*u%,P :>j iںBZZd:/ ] 0mHimyli? :KmKG!+$[GhP-L{Kn4boU@4oP5imU*\>^H#9 -xty6ٔ`x4qB1<6hi42Yl9p@;Tn 9lsxrǼeVa[N lfyzHi,HF Ӗj=)JVw8ͺSG6YD9M|-͗DA < qF1himi\㡯GG0<@KW /Es}tF< =e3a%]if1x0"Z2RFz{8-.4t}ҍ4Z7mic'ijF<Fȉ#H w #dv)ϻ{mi@7[ڸ#[Җ޴%}9:{tZڰţg-Ug: Larڳ m|(.TR(XA%6+d[iٻfA"m\~;ysym_4 ͷC\-]Nwk7Ҿ-EF:! F6(/Ug#6jHWZ$t-]QK;q^*!9.ii@ڱx fxN%:ãI @ziiTB%Ŷ[li@گ j-M'ioҁ"KBKK3T* ]Z[i}&Vl# HWnK<@[4o}hpu! w6ZZ:sO1SU>BI0нąd14d1Zȥ,N AVi*VKLw|'XKKgz.xXǶtb*Q@GICH\ Q-9Cb79MLw|'XIKgz.x,>IxGf];՝bXgi" jpvEq wxlݩl@6\Bhjjl֢i5@_RޟLÜ*4Bͣ]`zL۸ OOCQL-7hiTҵ)4D']L*1mJƌL, ĝ)Sǔ`u8A~8kkҁ70 H t6jҀ4 H 4 HҀ440i@[50 Hӭ Blsehڽ؂n,+qqeq;h`TѭiߑV6e.\tR4&ʀ4\HӭZZܗ$ȊK7Wֵ44\Cղ'wil ͕= \  45펴@wzmq-jBK 50 \? H{mq[7[ji-- ງt 6- O3 khKߖSQ`x4ᡯ=lA6i-0./C#i@l馷 HҍhxhkÈZZp9-W+$n:L:# L{ai4tEZƥJHUt=xAx\@[?[n AKZK^4꺇չRd}+:2<܄}3<Z"]aڒ2U-A}[O[Msjv{XQiߴL<@3ikZ1C H73ƵL<z34 HWW1{h|AZ_{ñ.@nvm -RH MA#-6Ybr) {(8MKN.=ji@H nMH{EZl;4t{;-7=#-=v- H4`ҀnEw![Xijhi,C@ڳj`34*=#itHK*XI,DJB#siaoǥ'wSwZQ|Mܵ,_LJs<n)(ϒi:MP !R{z,+# ""2wxnLWȪxGka pӲHxl`/]@W'HEr 4p;}~I=$aCw+E,WXrNT77Ny#_t!b6ErНJa{ˎoI 4҃lrXII˖B"+$<,{itX,,,Y ۋX= \Sޱ%`br({KK@{o`oH{Se=aCw;\!˱ԄdA{o`iA@Ti@AvU7 8@@y~~ pW6p -):fX22Nwe78,KkzD:>G&;EcLn1NNM;]1>ކ ]MMN"֢)5tW6pSiibG0no!A6gNţjwfzh]MtO267ÙTcھ㙕MYtW6ps2SO:y F=@G:aKnŴlf{$hbR ~"=#1|ʀb2x01[Xnă "jjyk4 )O tрtb0Y,Gv\fӝ*lf S4htij ұ Z; H$G.&iex$iee}-A@]H9Fixb˴3olK r"jH &Gi4Y[o1ҏ>ixu1!!Mi~a0uX`WIENDB`kst-2.0.3/docbook/kst/tutorial/Icon-kst-datawizard.png000644 001750 001750 00000001111 11544160206 023273 0ustar00synthsynth000000 000000 PNG  IHDRĴl; pHYsnd tIME$͊!IDAT8˭KQgC'GQ2#Y>zBD E}B60֮]kٺ EA=7gMǙǽ3ss{. $Hp|%4sh$^8֊;jBXXjjZҹ]iACmZGk1ήo9LT$ YJ0:B7#4T2ܐo館Eu Di|ŲG RU^^9s5z{0I0[\VN̶1qFs궂.\fI3[aqvd@rՍ[AUV^>]B꛵2<~/FdsG2(}My]3[*M^d#EW`VH95I@o]a8H}?i+[jQKCO˖׊B Zsv+8~4)ESe#7IENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-datawizard3.png000644 001750 001750 00000033126 11544160206 024616 0ustar00synthsynth000000 000000 PNG  IHDR\AVPLTEԢٜהՑԎѓƤ|xqld^yXsQnHiEeEdDcG^>ZMatttiii^^^[[[UUUSSSQQQNNNDDDAMgl!9jO~oi\k{#ڇGq~/W;x-]G/ݩнLhOeDK@QǰW@{ 4 /lܤieub:Q]z78Z[(0p .#zt.uN c路@eJoß?4릿/` iح12ЅɈ~ŁЅq.O_GH:{h`fF4 cw MpKi6Юq Υg!eÇWcMef@CN~8卋?B'lRl§k7qzOOܠ gG m mN;QܞۏɅ 9ғK-y^Ɩ(ymO~DyFCg+;OѳLhdTe6ONZHt%5ɏH2KF臻Wo.~}oO./Oš_Y)KhQVVX;xuoK~@rωFUCp ^~C$#~}\FQ}jA2r~\F\ݫ u\FA#^Ϻj%Z&tR_hDC  A  4`D4LD$ei|h%z7 R@T>#:EuBNr DPhB|R()JjΊaYGBmQF_JE!\bΕ+љ9PAKvJ.QF>?Ze0 KQ/#Cγz ulJnD?S? a ">:P]5W z"q 78ZݶfEPNJe"vE!$GZS䫕BgEQZzAE!_n]<" " @hF!DC@44jJ A(: !DC  A !DC  h!DC@4h&"9\Dc9D?~YP%v*[iP'MQ lXю|-j\ѥPAEV-p/ڃ0Ť/ı f A#j`U/;g^)VwCR&E!+դr^&OAlvt1K@wmG>)BWʪRf[V5&j|ʑjf{r[J hkm;eG>KZ^ ْyem;= qL['V5:?qSVwޯ h{Q1n'ֽq{ X%ržDۇ|y=Fo{aU*q4u%FN&mպ#{/iI/)ѻ|*`*} Y+;ȷX[J;Jy!L-WȰ)$SPʹoieY-"6c6K;6{ΫlC2\!þ_D!lwP_-q5qw$hB_q裇lh ! A4   DC Dh A4l,jFo9͂Jx 9\UMnT^k?>}={DTBҋv[ KA4\:8}%˹-+.,|՜TR|l?couJtv/ћW=n-((ńOK mX ܜQ{z|uѷ9V*Zi^d =:%:8=:z<#Zf)IüH1|s=<@TEA%ʁhna<=,6?@J/C/2}Yx]Y}!YD@\0$,D>-)<<@TcjJc&œ%gQ}HD0[[Aӣ}PS7xYbSr/@x>+=<@Ti+ݒ9GsO3gQAK[8Z_]|E!,DsmU >:Ch{k@bO"7! :( ΪbGDsmUu"[Y9GSOKDۣosr(2G؛LEKYDi {xfAiB0haw Ѷ@$u G7fJޣq Իj(ú:jD=4ww C({Nt0njҲ1gTD@t.a5VRk=Hh{Pk#vvU)KtC+->)._Un'NW9⮤f6_rVr%*n`f%7 ή36D70Zխ,U?x@t5[mq/O?Nj5#36}tEa5e1`+>zJ+*+nq_jl3tG0ݷ6GZQVS5D+qtZѺWc|<6_cIt#0=NtN݁WX D7jITuBuHka\guߢ7(]55n5~y鞹ch5r^awu Bt4r^a]SƷIhDhh h ! ! A4A4A4?@4nѾl Dv{1 zXvh'Dw%:Mܿ]e. \48+vթ] 5tu4&ň~%%E!$ / 37~oW!"KLʡX*@ 7ņDF͆W/o$Z5d:քhg:9e"@}̽G'Zs_lȉnMjoд3=괟{K0k;_`**Ҏ +hB:D7r ?+?/cUWM57ņn"$ExDxuV:]@QY7=Qǚ`X $ѫT|ĕtt^b%̴=L0W|nW_6a'HJbVCxuV:-X ض2uN4蠰QMxZ{_8S?XjLsX]}AtL/6}t]7t# hZY=q4_`iD:Ks6BQhGnF'YQG/ %QxNYv('E~0PЉܬnqt}7Qҽy7aYgm ݾtĪ9lv)+ŎqFLܸ{1nT=`jPʾN4w_l:꺉j>Hfwuo@nYG#dc.w_j_vj~x7A3k}GUQeu;)R\ѽex1; N~5]Ɉ+ʚ+6NoELt?ضeo&xCfm ZIŽb#"O{" n ok{-[[>﯏z@tS )_W@4ejx@44LD{ D}1*' DhDhDh h A4 уMt_ݢ]{۾7'dmSJ*VYt)37$u7{@4 ||C&65Ҍ&hV%cOdi,BDZ ≥F<3J*HG\Rւ5nܥutO$ϻ}V3µ8k)~,{@i%z4:"SZ456MQ'iCg5?"dvIrNM9fXâ:NiZRױ=n6\ئ|ӟ_بm ߽[K/(ˈNzI uhi{嘤C=]P@4 DhDhDA  Dh '_At{D,uW@4n~ڻh A4 D#W׼A] DMIWny !7) +r}cg1 6nMJ\ɤYD7tmbDCmYѺ=)ѬG`*澥­4 8j7DKzoRBIڕZ6I5%t'4%95MCW QNt$zoR|4}j!ڴ'DM/H,0!Λ>2Y6I0#8/ꞣi4*dX8ZD8Λԕ\'ߢIiOʬG5;j->d;Nt#с|2,p@:jIBLZњ=[jTRisbZKtQu@=$ޛ4d>]ao$ۓ֣SsebDC$ޛfeT;IuQlqf,sQii4DL z nuFjh1j+Ё(#5Q:'Vu`1 >$hDh A4'+ DI4<"zpb A4@4@4 Dh h h ! A4   DC Dh A4A4A4@4 DP%#iDP7*- A& h!DC DC hL7DSXv"h)yZ.|RZCk0hhe@tVs1op;'"fl6jQ:чerH*%ebFJ:v3,nEIͱJZLFhB|R  M]zZ-ᎪՄhDDt&BTzVzy mD(+Rm)buzJ1(\"FYe F>KDPyfp)Xnѷ}?w/#rޮdIiEY)2ζ)LR@y~ԪV>EmHe-/Iϖjm!ߏm^9G?fT{$q]+%gfuZiSr/ċokX65Y"j IȳQ=ߎtUSʹd*ř.Bl9T׺niU6Ye,53h{Gfv('vus9H"qp ([6:M>ƞz*nLL%v#3 Dہ}僃{竊E}_ JD*|7f [am͟Bm5DND +E{Jd+h+ʪ5maE{GP&?O,yK{o%Zcx2 \\IYDx0q|Cob-HWY`DD^uVK8baaF$YD7E[Ey qCNc(Q}=L(N236KFstz1-ͳIME Z#+;A4K%mf/`V?>wYG }>,Fl 'za2d],DM_Ypo$]VbQ(2ˈֲ$~YjK5_J+2eKj(= ,TK|>R#G'F}̂(cKڳ z'fA%FD9AW*9pWZV )/ʘӥ<f@4߿o#W:y;q않zWtoK8Z1h8ZC2C+]]Cyq?%HuɲhŸ<0Ey\ ̃h1] u֯j'SbTUׁAt3Kќ0uDXQ6&ѮDM+z':lIlkR%G:Cq٩phJt*(D7Br {+j)c:|XJ"@mGۉvJA"JcMTzӷ$NC5{RyģMD/I?눥ifדּwq4) or>{@Ȍ<^3Չy؂Vv/˳dQ6,MM/@4ist.~C5b1mh7DwQP )   DC Dh A4A4A4R:h} v [%j Dh!#vtRڣi\@m>Z,F2M:D[\|<+E=xj rdT3.a}7oRSkAڼmv#ItKo9\LI- Y m^D7!%lI+.a}7)w! ğp*JA͏tƂ;5%v]f}KX;DMNk.XؙN*WYx.,H' ~&Ճq%F4\!VoҀp!]IbJ'e'+jXIʸݶAi:2lJ4\o&]H0cfN'6AVҟfm8Za:GM3nlf}aJ)‰n۠ϟ K=x2KX/:n&.g.bD{|.'9 $Wqto&.!:n2T* ԚՂ4)O55(P7ݛ>~DsQ&Ω)a~ iCЦAi_dAtWױ6 Pw| E/L%#8& D ]@4 D{":ڏڮAtDS *7 DhDhD7ѷ= \š(3wkװ3HwpJ&`e`D$&`%5oh_:# hKA装N;'%he.F5śtnVCp҉qg7mj DG׻-ܿѣ ޤҝyؖ@t.a6G03X D3oWLiDw;wk^Շ7G O%RiX1|tHqW48ٓbϋ2m QT {i :8=:z{]lK~}H^كqb>TN(\"wp m}x_F7h~(&SiE۫R4ӣ>:e (JJ[g9ƉMUx42VWqt-$R#LU >:D"R^D{suDHdZ%a`A4x6$ZD:$椟DCouKh}D7&@ uO! ! A4A4A4@4@4~ֈbiO$E_#zSjA{uM=[m`_Mk-OGA64&+EL՛6XJ +hnÿRh~sz[m6s; ,%OJ9i])zd{D7Xh4+DߋK D7$Z̪[m6u'&jMzd9;I+bij7n{jEYm_,{JXO{-$џ6G_l[a8h}4_9uS+>|ɕ ד5bF^aJ[وT¯]I'5Dot6~Ľyp5UWsm`I?Ą_LL_luW3pVV"v6nwo`&DpA݄7=#Mw?3ٳyzelڝ5!Z!˖ Z;z{}h~SU̶hSw~(<ΐAmGD#g dN\GW<N,w·+j`3+QڵIhУL?Y&K ӗ x*JJ*HBT:(Pwmj?Mku06D=xJ"HakUUq)!z%<8G/rM1pvt egznsx="ÕwEomC/c$Di~&> {уLtJ0}H;ntM, ɤh sZIENkq%@눥iJyT3QO қ%^␶1^WGY?P}Ľ X D4S+OpCl,xlbe9✙џ1ckh9566 &kCd,=uo-iq %eY<'.nG/`'=D{0[jnDѽU`RRnڪ ~!<]2uA4@4FLA4  1 DCG DDo @4nB< Dh ! At[NhݗDK!NH\ݲ{4q5 hi)2!D?F%oh1х<$>Uu uDtf C(l-)F^VJ.2_F vVlV U3fN>,xEz)cc/h]YȾZ$/4/T2)WqmahF Vhd"@TVTԷf@K^9^)ў|VuhS/i*6K/O?~;'}u#ŀ=eX$-Cc'>fc3(`uH4ɫ)%6KJJ[A%n+9Nu#ŀ+~>5XEJCݓ'/y<BZ*;?ґY2GBJF  zkjB!ۯ#zPg+|Rah*>]g)}E[ܮTq[)[ *EPN[۷vIge9_`/hsI Rs"7"dX)[ *嫕BBu3|tIڕm\ٕ uFFtͨ)RDCN4fh h A4 D2X  CS A4A4A4@4 DhDhDh h A4  Dh ! ! A4A4h^ŴeeBP{ӖA@4h! ! A @4hDhDC  A 60H5%"^΂Qq4h! a'BZ'm7$ z! =i1 HD:ѽ'mhDh ! ! ! !X./њ+CAtJ Z שJj1A ]IvJI+{Dglx%Dh;`]y 4It)'j6S6jvJDѮ B!Kh┱lYUv] :$E:BTlKR(< PjDѮ>Rd!or Dkѣ$a.y _F!n)A5]ɂ zW .DVBfѣ9{K~;}t\?KIJ%89 y50;ԕys!}yA;zY GN5ay/?e(d8BH38K1 KîM%_*ѻ|*FPvآB̟!kAy2K\ :zyDvV]%d T9WHZ9,Uh/jyD фA/й@P4>#:RTRD)=DwU7th6-&iF(%裡?p|}L DC DC DC QNtaI #D݈h\hDC  A  VH[ AZjY@y:FhA]@F2 }! "-?~Wӟ$֘z)[IENDB`kst-2.0.3/docbook/kst/tutorial/Icon-kst-layoutmode.png000644 001750 001750 00000000436 11544160206 023334 0ustar00synthsynth000000 000000 PNG  IHDR/8 pHYsnd tIME +IDAT8˭[ C$ҲyXt1!@'% $I)%= NQ32P=T ?pdTf)߲eVXi~ l35O\IݠARSbՂW 8k(×L+4CM (shOEj8GPm?v0=|<c\ ^IENDB`kst-2.0.3/docbook/kst/tutorial/Icon-kst-tiedzoom.png000644 001750 001750 00000000430 11544160206 022776 0ustar00synthsynth000000 000000 PNG  IHDRĴl; pHYsnd tIME"'ݟ\IDAT8˵ !DLˡ4ڠ #Ő8@oKef' 9c; 3ևṣ9gL@hlZgLp_*J<):KϦV̦dokx䈼cVE^U"B1yYۊ#')D֔IENDB`kst-2.0.3/docbook/kst/tutorial/Icon-kst-xmousezoom.png000644 001750 001750 00000000414 11544160206 023373 0ustar00synthsynth000000 000000 PNG  IHDRʥ pHYsnd tIME!@"IDAT8˝a {cq?w%XQ*fEDۺd~'S9"X9C̰kE$`%=H 2@qfrl^[21X^S4}Y9$(ۖWȈJiRu $U* 5d&On0E6r_3IENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-editequation.png000644 001750 001750 00000037422 11544160206 025077 0ustar00synthsynth000000 000000 PNG  IHDR02PLTEwS;?Omc? Wآ٧Ѳyuy~7ʔՏӌЄ|xqjc~^yXuQmHgEeDdDcE\@\?UUcppqiii___]]][[[XXXSSSSSSQQQPPPLLLGGGBBB]U}_wTԏ*JŎ<tTedAe? <37Ǝ Bu$̆ P 0xܳ3驉qJlA]lU,ޓG;mMk╺Rszq?kzwSTڇ\<.?Uh56pJ ޴R :)CwJu8F7o[{r#nl:U M fYH%{gG[[/REެ $Vgwr~Dlp}I UdУ* Y5H)j5IݗC vFOP7" CJ0̣՞ 1G_ ޿UCPklȭ#|O.~tO?3_=K *vO *<\`X ~'͛7~QpNnvD}__"iEO__>t$&0x&Nkz䆞10L :3$&aFt?+F@~{5rI"?ӈwIPґioǏ?~:}ߒ?U,[kmŗ?O`'̆f{pVƎ3{R&m#}O>"ߓȭwwG$$NAy )⵶xE]8?kgAZGЦ+[J.P;zDNwoA!oߪdDo^H wY77$/[|`tJ]|li[lbco.~RZGU2fhJ1ױL^xG~OLׯI;g5\oAxF lPxMӽ""̿C@ՖKo?[,~GxH14(Д;sG*7cGo^xuM,#x =~Oӑ~|xw/.W,~oԽys MxppQ +Ew_^rׯ^joh$4/~zS9|JK_Ѽ^\cO?gŒG;E2⥾締:44%`x:j^:ő)nW ƎU|֑) +ŎdPo B!P)FL @@ gP'2@!`tY4K@@ :֗Da|AYS0^'RnljjVn׌.vY9Np$|E,'xZ%Rrr]6FH#ੜxtub}^ųp3b _Vcj̎cB#`VJ吒%AQJHd+N{]i֦+ 3Jr0+o!91r>ΊǺF8Dd%@5d[Yx)ZH:&!+QWvdӘ!}-h+Ԛw1_v HAKA<.č9J SJ޵,+5-{H64ZFn5`Lc"^J'SX/-Bq 0gy`|D#N/g{% O'1}t͆8QrjFUJAfzc8;"e/ Ě y(*vwՍgy`hjvrx <ػNO7=Ѧ`oGr8's~I'4kSfU ' ZEnX 7JWIb$`^`jp"NZ)Hn9L~Y>[R!-PT 7goW]2co'Lq~ OrD%Ld3<XHH= LKr~E,odUš)XKl(~CC_8qWG.wMu#V] >3 @@ Prwkuѷ3 Kb[(rXޤ!󢔛< z[2F,m4O'7.* [#`{4OCBmņ:?- ȁRfwP bsiC`z J?`Ӗ! 7 `*V:% (bMZx8@N@@ 9vq1q#Ura@eZ4   hTEs=Lpr1aM|2t/bDbDO"1cڀ1*HRjY0B'`r>nksxvަN"I}̘6`L\ Yf"f8`l%[ʯZpv|v~qa4wT'%[1cc9:'3K6,a̘ag}'T2 t5y>>$1À1(Ibֽ4G@+3@}M@n$P    O}#QCJWb}+vs OZ˭*WNMu@SƧV2҉$!͕J9TLs&$\͊팈c/Rm԰-QTהkI=emagiP.g@0/ClNu+hMJ\IyMw&锓./f4@]O-֋! iNJ=A[ _^+ 6Uy3pnjQ>/`=6Ex%Иa^Uא"sh\Fqg<|؎#i1F`E8qx># :i*$Q"/e)`?/ }j$mTВ^C:%`z!zlb_z-kVz(cE[Ku@=EVJIs]IF}(!1JqWt s:͉j¹}=b1AK(#RK\#5滮> BxL TԹu@m%V$b еJju@s$ŌG`@sUO?!kM9"p`$iL{7/ϊ@ҫvlZ S|'jۛ4(^+5Lb3dt[7Sl^@?ܕv=J ?'n4uLPǫr75OJ`=^NwPtc` S" t63JG~+ AX@u@@@puΝ)PG'O-  @th7,s5r%@ x\~cswTUAÛ:p7g_;֘Y!-eBNew.Ͳ/NO’nJff!{ H'8#9,oҐyQSbiN&;DQyHJ %ba7m4p|W76S9|]m F; j1"Rvx53ggn_u Pzg3yrSH|tzfމu!DŽN>"Z\F8 ~lv$ rANTM!hJz]В#F;bLYޝBXlx9W"*׽E%C|ِz2){9f~~B5xX¡`b/bP X'WEA6ͮ(*kDZ\^<Miג%@Q"hGB&v\RReٯlxFB@~)G:yooRn\*e3zq9"-S,5yO&o{][jJ:N4 k.kc}kZ֍^`tI;+1仮-|1}UL]ΩW3]L~St1;$8ރE\$bF܍Pvd6VIt< FV9sG w ^AؔA#O{ʼe0{v5J?Ќx/drkδٚV5"]J@u:zWrkĿ7C  a @}0 B F_Zj+@@@@ \l0HgP6$S`=%o=U%)(s>g(VY %d3x"*KGj'AR._ +b8A*Ҷ,@m.i{{@8%=VXVfMYx{_*eU)i lx0Ӆ$ݜi9D6}2 s,^ HB!.>V~%t@2m̢e2Q>NQu^!.N NVPq/EWWaeDq,0!*^(Vyl8M,7 ?=݌y"4T`A!"M@f XJг?%  Hnxm~3! U>\$>I'`{i[n j<{3j{[ ֧ãOZ*.ygɆL5UڬC_uYa +R~m?s$#³O_Eҙ.zMA=Y w&!S;iߏ|$Qp D"-⛑H[ B1@ T.#sJB=zь?8&Y5BR{3Bӡ10 8G&"؂yN^UBD~( #艟,<o wm lO<`|#"k@ !hG660 pDz4_  #v#gU0>8`Sy#NP> hwG"O8vuX!;PB#3 :Z?! ΁=A~O08#dI\Tu s>p/ N!`FiԃBf"V{,N%@ 4t 6&=Pn AC@kȩ  hsK#A:bz{Bh o^ @n ڠժN|u͘!PW  kw#&^d@,     "Æ&um@05#M&\oPW#L"HVlA%BvUxhT0R#@7P4cdB+rQsm0}h$dJ0pKIlHr{h½{J](5 qb. XJРRkl`U 8ܫ@@' B@ro7"I%Fl"biWJIKTL7KXLV,Kü n7fzZ!_[-qq2C ] ]n8]4WJ_}K(2%VŸSj!IdamkMG1#@ Vd-]wt@hu;X3+v:=$/E`R Vqk#Z9beDGfn^Y'HYh &#Z<#!Fɩupذ*i<]UC-, =@lXRDfB Iy\ fQ# "׾A sw"%TP\6O!6O lj坥5&sNaˏW=iQ-Td}#a#] lTw7sYŠ;c~q6{ 6"'TOO48@)o&Y>q[ۥB"[@iyZY;F65;46!ձꎃ76w!}NĐy!Bн*OGG|3]n`}7燘'iV8 9߈NĐ_8"}X'U "~z8SXә =*9b(8e7]? w#w"ȕQ?-)@_x*|nXܴqf N-~sCc;=j4w"XD 2m `*ĮnO.Cr%a`00?1C q/D;Tw"2[`}O>8G1Ȓ SHԕW!&;G7iw'GO|/0"4{~{}&ؕja8{N|}N:S%F0^@@K@7Ruw>+JTx@@p)_2MV3 Xo`5<=?&{z?HPhNcT ^;t 8 |?}LuP>x;x^76*Ɇ z?x&}Q?Gn0{_A8#z?}j?Go 0{_A-y#c~0Ѯ:@ -ɿO_`jE@`ß>&@jI@q=ӇalwmP:xx;wLb{ЃB؆ aOМ0@3=o;й   j C5    @@N6.HZRS8=I+ +wT$M7LgaSRa!{aO!&$:J' $F)yH~H%uu],"ޗJYd*axq1YEkǶY)CJt61VF)>:VcxFT#P$D(DRtud8kȇGO1%IVmuqxdh͎R7CBTFW@McKAcg\᠂V|yjn@>`CN$FIs(D2L;w?<d@*sP"vJ|8"r&$r1"by %YCxɾMvOǫ4~BVA6 u(p`˜+ӫ6c#* 'RևbTHd ,a轀^ hM ?@@gq@@v t%;~   h6@@7$   !   R_@@]D9 UA.#s hD@OuDVBR%*\ $WG@@aO<'`JW@@?Pu'yaƬ\o-ASNXyJkei!@@Qͦ9/JyORً ,JpRb3K9,oTARVdwTVi|h`-rʬm3v YDO 6%;D1Ĝ>B^+EZrmZ|F2wI?"#7'Y#gy+~6_ 'yTXa7',,[Sj Cٻu1iKqrU0/~Ve?`-{QlBE e%ժ_.tC_KEN<r ͌rʞ nynbnժM[lSh,2e @"-nMXCU),ܻy|U,a̧N*QO$1j}7Sp*/^4n f 2$!^{/`2B #O7RQfh0  V/{11C]G  `_$^TEkzFzan^$QBߡ /D -p[XDQlSyc uޛ#@-p qsi4VuQ^卣IvuAmD30#d/`bvQu(w2U-xuO]AXy0:ǃPAb ϡblz>r^7z0J `kk*,wa9D@yH, *qO!`P @mO[ 3. Q:<8X팜gz/дDS:. =z!iaLӱ#tbPK`[ &WjS[4`+#@؋إZ+~6_lFy\%X &Wj& \%U㼟P{AlGT8Ptcө"j , 0L zaӯĪq@,iu:!5YDi yh$TX?'Wx/F H,PnӖ&u^96ʢa@9~PM֦,0L,MOOiqX_[Di\崁 /O&@XLH^&K>tտ3?lvpo$}H@@@'zJ t1C=@S*P  腑@@w gnL^ z  Vo(rɆ{.)] \U~횙\ɸ Pr&<\rj8RTuF Gv{;` v|P9|h#?FRIJʀ(VQŨj t٥e,5 JpN.(I#jS8Qq#N4kP4\R،`)LH',ِN~>F(VZA?Q{׮^ :Kմj-*q+R~U'LH' LWZ :(>w~+ \5b#/;gPA r?9;qZZK`:=AJUH96]O-m/eN};[9j4݊z/ s/L.YEH!YtӞ(IbE7LHY_T t^~_EYSTptEJ)/AT1V?u[4 8jVNɢv D1PMKP7Q)4E9 b|@p5j~SFS7y$W[]:}=D@OV   3PmP&@@@@gV}_@78ϵT h_YZ*@@@p.! og'ʷ:pDsR.V2҉$]EpZXSޱ@|*]dYȫ32 YN#9w/ 'f\ ^`,aW(S{NM><`<`x,Y 8Y#{#k   QϵT |nJۏDp:P1!G" / ۏN@@ @@ }#`T {28?AX!',hzQV%q{acԇbvDIENDB`kst-2.0.3/docbook/kst/tutorial/tutorial.docbook000644 001750 001750 00000115400 11544160206 022162 0ustar00synthsynth000000 000000 KST"> ]> The &kst; Tutorial Barth Netterfield
    kst@kde.org
    Rick Chern
    kst@kde.org
    2004 The University of British Columbia &FDLNotice; 2004-06-23 0.98 &kst; is a data plotting and manipulation program with powerful plugin support. KDE kdeextragear kdeextragear-2 Kst plotting plot
    Welcome Welcome to &kst;! In a few minutes, you will be on your way to exploring the rich features of this plotting and data manipulation package. Here are just some of the tasks you can accomplish using &kst;: Quickly plot multiple graphs using only the command-line. Analyze data using an extensive set of tools including histograms, power spectra, and custom equations. Effortlessly zoom in and out of interesting areas of plots using either the mouse or keyboard Monitor live streaming data using &kst;'s real-time plotting capabilities. This tutorial covers the basics of installing, running, and working with &kst;. You are invited to further investigate any features at any time. All features are documented in the official Kst Handbook, available by selecting Kst Handbook from the Help menu of &kst;. Installation In most cases, performing a basic installation of &kst; is easy. The only prerequisites for &kst; are versions 3.1 or greater of &kde; and &Qt;. However, optional libraries such as the &GNU; Scientific Library enable &kst; to be compiled with additional plugin and file support functionality, and are highly recommended as they are required for certain portions of this tutorial. If you use a package management system, you may use it to install &kst; instead. However, be aware that the version available in the repository may not be the latest version. First, you should make sure that the required &kde; and &Qt; libraries have been installed on your system. &kst; v0.99 requires &kde; 3.1 and &Qt; 3.1. Almost all major &Linux; distributions have packages for &kde; and &Qt;, so it is recommended that you refer to your particular distribution's documentation for &kde; installation. More information is available on the &kde; website. The &GNU; Scientific Library provides a variety of mathematical operations for the built-in &kst; plugins. The library can be found at ftp://ftp.gnu.org/gnu/gsl/. Alternatively, you can find GSL under /gnu/gsl on the mirrors listed at http://www.gnu.org/prep/ftp.html. Download gsl-[ver].tar.gz, where [ver] is the greatest version number found in the directory. Then unzip and untar the file: tar -zxvf gsl-[ver].tar.gz replacing [ver] with the version number of the downloaded file. Read the INSTALL file in the resultant directory for detailed installation instructions. For most systems, the following will work: cd gsl-[ver] ./configure make make install The second optional (but highly recommended) library is the CFITSIO library. It provides support for reading and writing to the FITS (Flexible Image Transport System) data format. The libary can be found at ftp://heasarc.gsfc.nasa.gov/software/fitsio/c/. Download cfitsio[ver].tar.gz, where [ver] is the greatest version number found the directory. Then unzip and untar the file: tar -zxvf cfitsio[ver].tar.gz replacing [ver] with the version number of the downloaded file. Read the README file in the resultant directory for installation instructions. For most systems, the following will work: cd cfitsio ./configure --prefix=/usr make make install You may need to modify the option for your particular system, but for most systems, /usr will work. Once all of the prerequisites have been met on your system you can compile and install &kst;. Download the latest source package separately from the &kst; website . Then, type the following: tar -zxvf kst-[ver].tar.gz cd kst-[ver] ./configure --enable-final --prefix=`kde-config --prefix` make make install replacing [ver] with the version of &kst; you have. Note that kde-config --prefix is surrounded by backquotes. It is very important that the kde-config utility returns the correct path (most likely /usr), otherwise &kst; will not install properly. You can double-check by running it directly: kde-config --prefix Ensure that a non-null path is displayed. You can read through the messages displayed by the configure script—if it reports any missing libraries (such as GSL) that should not be missing, please go back and ensure that the libraries and header files have been correctly installed in the appropriate locations. If installation was successful, you can now go on to the next section of this tutorial. Starting &kst; from the Command-line A common use of &kst; is to quickly produce plots of data from the command-line. This method of producing plots requires almost no knowledge of &kst;'s graphical user interface, yet produces immediate, useful results. This tutorial uses a demo package of data files available here. Download and untar the package, and change to the resulting directory: tar -zxvf kst_tutorialdata.tgz cd kst_tutorialdata To obtain an overview of all available &kst; command-line options, type: kst --help A syntax description and list of commands similar to the following will be displayed: Usage: kst [Qt-options] [KDE-options] [options] [Files] Kst: a data viewing program. Generic options: --help Show help about options --help-qt Show Qt specific options --help-kde Show KDE specific options --help-all Show all options --author Show author information -v, --version Show version information --license Show license information -- End of options Options: -F <dataFile> Specify data file: used to override a kst file default [|] -y <Y> Field for Y axis (multiple allowed) --ye <equation> Equation for Y axis (multiple allowed) -e <E> Field for Y errors (multiple allowed) -x <X> Field or range for X axis [INDEX] --xe <X> X vector for equations x0:x1:n [INDEX] -p <Y> Field for power spectrum (multiple allowed) -h <Y> Field for histogram (multiple allowed) -r <f> Sample rate for power spectrum [60.0] --ru <U> Units for psd sample rate [Hz] --yu <U> Units for y vectors [V] -l <P> Length of FFTs is 2^P [10] -f <F0> First frame to read [-2] -n <NS> Number of frames to read [-2] -s <NS> Number of frames to skip each read [-1] -a Apply boxcar filter before skipping frames -m <NC> Separate plots arranged in <NC> columns -d Display as points rather than curves -g Provide a legend box --print <file> Print to file and exit [<none>] --png <file> Save as a png file and exit [<none>] Arguments: Files Data files (if -y given) or *.kst file &kst; specific options are listed under the Options: section. Where appropriate, default values are indicated with square brackets at the end of the option descriptions—these values will be used for any unspecified options. We will first take a look at the ASCII file gyrodata.dat, included in the demo package. ASCII files are one of the many file types &kst; is capable of reading. In ASCII files, data is arranged in columns, with each column corresponding to a field, and the column numbers (beginning with 1 from left to right) corresponding to field names. This particular ASCII file contains 3 columns, and thus has field names 1, 2, and 3. To produce a plot of the first column, simply type: kst -y 1 gyrodata.dat All the data in the first column will be plotted: Note that no field was specified for the X axis of the plot, so &kst; used the default INDEX vector, as expected. The INDEX vector is a special vector in &kst; that contains integers from 0 to N-1, where N is the number of data values in the corresponding Y axis vector. Close &kst; by selecting Quit from the File menu, or by typing CtrlQ. gyrodata.dat contains 20000 frames, so you may wish to only look at a portion of the data. To only plot 10000 frames starting from frame 7000, type: kst -y 1 -f 7000 -n 10000 gyrodata.dat One of &kst;'s strengths is its ability to plot real-time data. Imagine that new data was being continually added to the end of gyrodata.dat. In such a scenario, it would be useful to only plot the most recent portion of the data. To plot only the last 10000 frames of gyrodata.dat, enter the following: kst -y 1 -n 10000 gyrodata.dat If gyrodata.dat was being updated, the plot would continuously scroll to display only the last 10000 frames. Instead of directly reading an input file, &kst; can use ASCII data from stdin as a data source. To specify stdin as an input, simply enter stdin as one of the filenames. There are many uses of this capability, such as using &kst; as part of a sequence of pipes: cat gyrodata.dat | awk '{print $1 + 2}' | kst -y 1 stdin The above command uses awk to add 2 to column one of gyrodata.dat before piping the result to &kst;. Note that the description of the option states that multiple instances of the option are allowed. This allows quick plotting of more than one curve, or even more than one plot. To plot all three fields in gyrodata.dat in separate plots, enter the following: kst -y 1 -y 2 -y 3 -m 1 gyrodata.dat The option specifies that separate plots should be used instead of one single plot, as shown below: A Quick Tour of the Data Wizard While using &kst; from the command-line is fast and convenient, there may be situations in which it is easier to import data from the graphical user interface—for example, if you already have &kst; open with other data loaded. Or, you may simply prefer using the graphical user interface. Becoming familiar with both methods of importing data will allow you to make more efficient use of &kst;. The Data Wizard provides a quick and easy way of creating vectors, curves, and plots in &kst; from data files. To launch the wizard, select Data Wizard... from the Data menu or click the button on the toolbar. You will be prompted to select a data source. Browse to the gyrodata.dat file used in the command-line examples and click Next. The following window will be displayed. Data Wizard Screen 2 Data Wizard Screen 2 The fields available in gyrodata.dat are listed to the left. You may filter the list of highlighted fields by entering a string to match (wildcards such as * are supported) into the text box above the list. Enter * to match anything (i.e. highlight all the the available fields), and then click Check Selected to select all the highlighted fields (which in this case happens to be all the fields). The Data Range section is used to specify the range of data to read from the selected vectors in the input file. The following discussion assumes knowledge of frames. In brief, a frame is simply a number of data samples, and each data file is composed of a number of frames. For a detailed description of this concept, see the Kst Handbook. Starting frame, Count from end, Number of frames, and Read to end Using these four settings, the lower and upper boundaries of the data range can be set. As an example, select Count from end and enter 10000 for Number of frames to read only the last 10000 frames. If gyrodata.dat was being updated in real-time, subsequent additions to the end of the file would be read. Read 1 sample per N frames and Boxcar filter first In addition to the lower and upper range boundaries, the samples to read from the selected range can be set. If Read 1 sample per N frames (where N is the entered value) is not selected, all samples in the selected range will be read. Alternatively, frames in the data file can be skipped by selecting Read 1 sample per N frames For now, deselect Read 1 sample per N frames. Power Spectrum and X axis settings can be specified within the Plot Types section. XY, Power Spectrum, and XY and Power Spectrum Select XY and Power Spectrum to produce plots of both the data itself and its power spectrum. X Axis Vector The vector to be used as the independent vector for the plots. You may select a field from your data file, or the INDEX vector. Since gyrodata.dat does not contain an X axis vector, leave the selection as INDEX. The FFT Options subsection in the Plot Types section is available only if a power spectrum is to be plotted. This tutorial will not deal with the details of power spectra, so use the default settings for this subsection. Once you are satisfied with all the settings, click Next to advance to the next window. Data Wizard Screen 3 Data Wizard Screen 3 From here, you can change general plotting settings. Most of the settings are self-explanatory. Select 1 new plot per curve for Curve Placement and In new window for Plot Placement. This will place all six plots (three curves and three power spectra) in the same window. Once you are satisfied with all the settings, click Finish and the plots will be generated: The Generated Plots The Generated Plots Generating these plots took a bit of effort, so we should save the current &kst; session (it will be used in the next section of this tutorial). Select Save As... from the File menu, and save the session as mykstsession.kst: Saving a KST session Saving a KST session Saving a &kst; session saves all the plots, data objects (you will learn about these later), and layouts that exist at the time of saving. Once the file has been saved, you can exit &kst;. The Basics of Plot Manipulation Now that you are comfortable with creating plots in &kst;, we can explore some of the plot manipulation features available through the &kst; graphical user interface. Start &kst; from the command-line with the mykstsession.kst file you saved earlier: kst mykstsession.kst All the plots you created earlier should now be loaded in &kst;. Examine the plot with the y axis label of PSD of Column 2 (V/Hz^{1/2}). To take a closer look at the plot, right click on it and select the Maximize menu item, as shown below: Maximizing a plot Maximizing a plot The plot is now maximized within the current window. Note that anything beyond about 4 Hz does not look interesting in this plot, so it would be useful to view only the area of the plot that looks interesting. To do so, make sure you are in XY Mouse Zoom mode (select XY Mouse Zoom from the Plots menu, or click the toolbar button). Then, simply drag a rectangle from approximately (4, 0.025) to (0,0), as shown below. Note that the coordinates of the mouse cursor are displayed in the lower right corner of the &kst; window (if they are not, ensure that Show Statusbar is checked in the Settings menu). Zooming in on a plot Zooming in on a plot The plot axes will change to zoom in on the selected area of the plot. You may notice that there is a peak at the left end of the power spectrum that extends beyond the new upper y axis limit. Suppose that you wish to view the top of this peak. Right-click on the plot and select Up from the Scroll submenu. The plot should scroll upwards. Of course, it is most likely easier to use the shortcut key associated with the menu item; this is true for most of the zooming and scrolling functions. In this case, the shortcut key is Up Arrow, so the quickest way to scroll upwards would be to hold down the Up Arrow key. To return to maximum zoom at any time, right-click on the plot and select Zoom Maximum from the Zoom submenu (or type M, the shortcut key associated with Zoom Maximum). Restore the size of the power spectrum plot by right-clicking the plot and unchecking Maximize. Now look at the plots with y axes labelled Column 2 and Column 3. These are plots of the pitch gyro and roll gyro, respectively, from the 1998 BOOMERANG flight. Since these two plots are related, it can be useful to zoom and scroll them simultaneously. Click on the squares located at the top right corners of the two plots. They should turn dark in colour to indicate that the two plots are now tied together: Tied Zoom Tied Zoom Before we try zooming in, we should delete all plots other than the two we are working with. Select Layout Mode from the Plots menu or click the toolbar button. For each plot other than the two we want to keep, right-click on the plot and select Delete. Then, right-click anywhere inside the current window and select Cleanup Layout. Now the two plots should share maximal space inside the window. Return to XY Mouse Zoom mode when you are done. Now try zooming in on any portion of the upper plot. You will find that the lower plot will become blank. This is because the lower plot axes have changed to match the upper plot axes, and there is no data in that particular region of the lower plot. Type M while the mouse cursor is over either plot to return to maximum zoom on both plots. Now hold down Ctrl (this is equivalent to selecting X Mouse Zoom Mode from the Plots menu or clicking the toolbar button). The mouse cursor will change shape as visual feedback. While keeping Ctrl held down, drag a rectangle in the upper plot. Note that the height of the dotted rectangle is restricted so that only the x axis will be zoomed. Now both plots will display data when zoomed in, as the y axis for either plot was not changed. You can quickly tie or untie all the plots in the window by selecting Tied Zoom from the Plots menu or by clicking the toolbar button. When you are finished experimenting with the zooming features, you can close &kst;. There is no need to save the plots this time (unless you wish to). A Brief Overview of Data Objects There is more to &kst; than simple plotting and viewing of data. From the data wizard, you have already seen that &kst; has the ability to create power spectra of data. In fact, &kst; is also capable of creating other data objects such as histograms, equations, and plugins. A utility called the Data Manager can help you keep track of all the data objects you create. Start &kst; with the file demo.kst, included in the demo package: kst demo.kst Kst with demo.kst Kst with demo.kst This &kst; session contains vectors and other data objects created from data in gyrodata.dat. The top plot contains the azimuth data, the middle plot contains the pitch data in blue, and the bottom plot shows the power spectrum of the pitch data in blue. Let us first examine the plots more closely. Tie the top two plots together using the techniques you learned in the previous section. Then hold down Ctrl to enter X Mouse Zoom mode. Now zoom in on a small region of the top plot (say from 50000 to 53000), to cause both tied plots to zoom. You will notice that the the blue pitch curve is negatively correlated with the red azimuth curve. This is because the pitch gyro was slightly rotated relative to the azimuth axis (by -0.69 degrees). The true pitch p' is: where p is the original pitch, is the rotation of the pitch gyro relative to the azimuth axis, and a is the azimuth gyro. p' is plotted as the black curve in the middle plot. The power spectrum of p' is the black curve in the bottom plot. Now let us take a look at how the three plots were created. To display the Data Manager, select Data Manager... from the Data menu, or click the toolbar button: The Data Manager The Data Manager The Data Manager contains the definitive list of data objects in the current &kst; session. It also allows you edit or create new data objects. As you can see, there are three curves (each created from a pair of vectors), one equation, two power spectra, and four data vectors listed. Right-click on C2-GY_PITCH and select W1-P1 from the Remove From Plot submenu. This removes the curve from plot P1 in window W1. Also remove PSD2-V3-GY_PITCH from plot P3 in window W1 using the same procedure. Now only the corrected curves should be displayed in the plots: Corrected Curves Only Corrected Curves Only To see how the corrected pitch gyro was created, highlight C4-cleaned_pitch and click the Edit button. The Edit Equation dialog should be displayed: Edit Equation Edit Equation Note that the equation used to calculate p' was entered in the Equation text box (an approximation of 1 was used for cos(-0.69)). Feel free to experiment with the settings in this dialog. Click OK (to save any changes made) or Cancel when you are done. Note that all data objects have a number listed under the # Used column. This number indicates the number of times the data object is either used by other data objects or by plots. Since we removed a curve and a power spectrum, at least two data objects should have 0 listed under this column. Click Purge to permanently remove all unused data objects. Click Close to close the Data Manager. You can exit &kst; now if you wish. A Look at Plugins and Events We end our journey through &kst; by looking at two specific data types—plugins and event monitors. A plugin is a flexible data object whose behaviour depends entirely on the specific plugin file selected. The plugin file can be one that is included with the standard &kst; distribution, or it can be a third-party plugin file. In fact, the Kst Handbook includes instructions on how to write and compile custom plugin files. Plugins allow &kst; to perform arbitrary operations on a set of data, as the only requirements for a plugin file are that they receive a set of input vectors and scalars, and output a set of vectors and scalars. As an example, we will try fitting a simple line to a small set of data points. Start &kst; with a plot of the first field of the maxima.dat data file included in the demo package: kst -y 1 -d maxima.dat The option specifies that only points should be plotted, not lines. The plot of data points should now be displayed: Plot of Data Points Plot of Data Points Now, open the Data Manager. Click Plugin... in the New section to create a new plugin object. Under Plugin Selection, select the Fit linear plugin. This particular plugin requires two input vectors—one containing the x values and one containing the y values of the data points to be fitted. Select V1-INDEX for Input Vector - X Array, and V2-1 for Input Vector - Y Array. Then, click OK. You will notice that the new plugin object has created slave vectors to store its outputs. Click on Curve... to create a new curve from the output vectors. Select V1-INDEX for X axis vector and P1-kstfit_linear_unweighted-Y Fitted for Y axis vector. We want to place the curve on top of the data points in the existing plot, so under Curve Placement, select Place in existing plot and deselect Place in new plot. Finally, click OK to create the curve. Close the data manager to view the fitted line: Fitted Line Fitted Line A procedure similar to the one you have just followed will allow you to create and plot the outputs of any type of plugin object. However, there is a shortcut for creating fit plugins. Right-clicking on a plot will display the context menu, which contains a Fit... submenu. Selecting a curve from the submenu will bring up the Fit Function dialog with the x and y vectors preselected. After the fit plugin is selected, a click of the OK button will create the plugin object, create the curve from the plugin outputs, and place the curve on the existing plot. Let us now take a look at events. Event objects usually monitor other vectors or scalars and perform specified actions when certain conditions involving those vectors or scalars are true. Click EventMonitor... in the New section of the Data Manager to create a new event: Event Monitor Event Monitor Suppose that the pitch gyro data was being updated in real time, and that we wanted to be notified whenever the corrected pitch gyro falls outside the range [-0.60, -0.40]. To set up the event in this manner, enter the following in the Expression textbox: [C4-cleaned_pitch-sv]>(-0.40) | [C4-cleaned_pitch-sv]<(-0.60) Note that anything entered as an expression must be a boolean expression. This particular expression will evaluate to true whenever either of the inequalities is true. Select both Log as and Notify, and enter in your email address to the right of the Notify checkbox. Click OK, and the event will be created. Now select Debug Kst... from the Help menu. Click the Log tab to view the debug log. If the event was set up correctly, you should see warnings indicating the x values for which the event was triggered. Check that the values roughly match those you would expect from looking at the plot: Debug Log Debug Log If the pitch gyro data was being updated in real-time, the event monitor would be triggered for any new data when appropriate as well. Once you are done, you can close &kst;. Conclusion This concludes the &kst; tutorial. Hopefully you have gained enough knowledge to become comfortable with &kst;. Keep in mind that this tutorial does not cover all the functionality of &kst;—there is still much to explore and experiment with. The Kst Handbook, available through the Help menu of &kst;, can be your in-depth guide to concepts ranging from window layout fundamentals to creation of custom plugins and data source readers. You are encouraged to use &kst; in interesting and innovative ways—you will most likely find that it not only meets, but exceeds your needs and requirements. Credits and Licensing This tutorial is based on the original &kst; Quick Tour written by Barth Netterfield. &underFDL;
    kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-tutorial-gyro1.png000644 001750 001750 00000032154 11544160206 025303 0ustar00synthsynth000000 000000 PNG  IHDR ?PLTE  ᡵۣ٢٠ٛ՗ՕՔՓՑԑԐӏЎώюыi[_끝Ά˄ɁȀÀ~}|{zywtrqonpo~l~igddb~`{_z^y^y\w\wXuWtWsXsZr[oXlTjRkPlPnPnOmLkHiHhGgGgFeEeEdDdCeAeBdB`@^>[=Y??BCCEEEJJKOOOQQQRSRSSSZSNvVCZWVXXX[[[\\\]]]bbbknkyvuј0učݺԮ\MtRNS>ţ1IDATx pչ'pU ݛA  ` $,/I IQ7I0!UrzrsUumr!PEZdY6xAyaRXGF:u*{N{!SO飙ߜg4 1Wɠ5b>[ P ?%>7oy/b^ʨ)i :`éc'NM6܇@c@b]׵ss#-d2:24<<2N=HLNߧ{=Sw;Zznim6-4=(Yɼo7tKX6]jiyɒVK5ٴ\OW+9-Z˵K^jJMN56 yN7#=?kvHPH۶HE%/?~l!E:+R 't*ҳG0o=-< _,7,Wѫ]Erܛh9r.N]|>&*a&a_/yoNɤ2Q?9U̢o*@*aSR3լ?Femggv%kj-])I ѹ]飫?& 3˪w?|ߊhuM'L' ML_R]bz>i e9==\{/U&'bZ]tu-I*i,K:Nd ih2jj(FC1IjL WܯNt"*͢?eʢ\2>\u a!K&/>9&|a96;y{4GԘiJ5?~OfN^vYC$CEYD`2MDOȤ}h[ˢ' Lf?9L=x|qr k͝'|xКOS1=I~fwM\}ov zქ==|Pf]s2M)^yvmmqmQLz*t''cU2::2ךϒsr1wэ!=ӥI2N.Y["^sl}7&~"`6}SO7t~~Kʞ|”-7+izBNtjt+K"yNV{bŽ{ݠi4۵]Ƶ\u[PZ;1Em[ӓ.zH=~.Iݭ;G~ 'It{]#nKtƻ^:M]wZP6]jS*)-7^IϲiKWzZj^:Ԝuw6(uQY]se\kO1ҧFGEvTlr:ͷ\N>LLHʾ#{\-j[SW7ЯѯN͞wyM>>,m:淞GN^s_2e9mZVN+t%-+i6/-3+rsZJ2=}COb-=9;VHcQWڥhTjy|oHOZ*~:a~ٹ|nԬ3WeJnӓߖ9y >_EQҊՔ琏W"ÏzVV%-7YMN\rsZJ2sKt%}_TW[Aد+ƵULz.^?˖լbٺeWy暚u˖)_XvOYwjm]t+D7_᚟-5Oҥ!&}^㳁Z)ٹ؆sy |>2Q^6lC =65X$I_B *bi (iH# @4H#!񱀍8p*!!W[s'\!t={Hi~K&lPo8LڡǑ[5Zc[i/7=4iTAւ+iUJZFYvp_C; r|+iHִa@^3"鱡 6hGN ~ò5HWiuN7D`YC¶^q)ԧ*֍$Elmⶃ[gƎJHv0Mle߲4(Z:jښ[ aiCi} .tcT:А4G:K4$ I!)ڨ|.7=ڭ0,u1u,;W Iitpr5r-h2>ӡ*a@oݑF@OGcBӸak'Ԏkk>X:W<#+W\"166RB纐XEtre.0O]z̡ }Ҙ oЙ,'iiF4H# @x }(0Ƨ^">0Ƴ"x%PI'p/!r F'9 vY8i;wjF۞jc$ҭkg.t$6I7Z; Ywlt"k0.YIjAN'LCu!#htQ‘#)[6JB=IPbjo߭=:A.iǒ[#8mfdӠ?TN:$?!(4Nnq&5?hqÏ7E-hg8#vTi9p ?{#?ۖ4VEi% zN=qJOJ|gh3z>v-}^x)'}_>b"&izd2I I[Ma4P&cxFS-ԲLKHr#mĵ14}1|KHRҵY&҆#g b"mܓ\Umy6Ҳ,yݦM0 M{CF睭>5991FgyfQ.d"z}-R'iڤ~5dg<{ZHGM3lh m~WˋԸXXdt,FAD_n$8&?ѡe Ͳ L\#Mf#gjc:+ic{ظ޵v^ZKk;3ثEc(l$}znF}L:ƄfZ 4/i>\kieNӪcӴHZ葭=z:5V^&;h/勾E"d;Qxm߾?~ǣ7m}֢E-+1ew%j/:w'U\ē-;tw2ikm`3F8ɦ:RX[xBD&i"O~HKǪ0S6jQO=`>2zЭJlڵVz__/YANkW1}R}y֗~!%=V):K# z7m Tm Нbꋔi,}q:KŴaVLGII,i7rfi?5N 3 L,-lfpfi)H:KY :OǪ?ެ,][k)3wAM뫝iLIH&&ȗO~r87of0izTxȍj zYx7HjNzf&7ZFGZ'_5ZΒKh\u=1Uǚ cgW_ Guu~_^>CS߳vMfbHoo^xto쥦_xYcW#"G\x(ܧׯNfgifZk?TOƧ#H Ӵ *ұ)X;3_ǧc|qxwcsm3FZHX}|hژM:M4,HD>=N{zbo6$dzzH:tb| $\wܔYIΝ>-#$I>F?K<^ ^_5L҄.5[<Ζ-}YZ17ܧN굴mhigשu~z3Oe,]ʴH r2ɖN jl+L4 DXsKoS`2֗Z6+#O>Em+<=G.ҞkNEd$/{m[YlN̥ҳ33УϙH۸i߾tzd(JHI2A!دx(;zʛ%w+}ɤ_nt%2uuҲwxGgiz6ɯ-h{5̝德a궽;o"ڻ[7K hE맟~]1S/*hsިOYڼevitKrf`g"\xȯ)'y-;5O;#zJ\OʫVS+>XCfH-?&#ALF3J:7_ ==|W_+1'BFҴt~5-ffN`zmp1~ZFc>69Tm#i'mDڭ=&1 hܹN<!iMƌN<ηIji&=ٳC/w%~o|Ey6,b?=g(-w7N}N^%csֆP pgݢdz :* 5}g9L~:F(U1ͼF^Ua;k%+ \*i(3iJcF~4{4t&_Z:uDKBTBmrI2mwdS⭶ 9#isNRB~~5?=H{t]H IAVn3NH6\xlo®u{jajWt)E۠o PKJxsoxɦ_j:)sH:]gi8;hzF'{ %C-}hc9酞؝r8F.ژcp%j,yEXK#OTK#0K#I;BH#ʒtp? Ƌ"'o1p+#trH#AzHA@iDEV҈J!BZ{H#PK44Z@-@-/{ZG@QA}/!4\kdClS@iDsmT +<0҈r-soGNEzdsfFm-=&6O&:2U3H#ʶk w΅{&@Qܞ}sH#*MnI6 AQ4^=DTZ- ҈ AQa4H#PK#C- ҈#-~iD HcEyD< iF @iH# @4H#@iF @H# @4F @Xxo#ef(iDeH#@i!dAǤDIUGI W"eE9J"h'mΣw=]]Go$W&Gz9" )y_iJ")ɶd,ZR'"dIJ"W<[dg8mښS:5-y{N:1kZ[`3pwȝt/Ȟp(Bv-Ĵ ҞWlE8L|_O-Ke6Iۗ]HZXIJ>0r<~kg̢iO)5qzBڸ$Ң+iѩb {q>OZsG_YTb>%m_ԥXiz\y[n]4HΤQZt!-U/i1߃y/O=]M幞 ;XRNKq>iWm-#-EZ,>i@W%-z!-$EZNZXeb8;U.\y?,iY r!-X΃葴i1Ҝ㜙i ?#S1T=Ϥ!-XJҖ!ĝ'iOҢ0[tH @Z,/i1HI;NxQ-$7IbAE~EEsgi1b9 SҢG"o 5&M@[SH{eғ%"Mr&m,| >ink*iхtҤ~Xi1ŒpsAs,KDڲHiby7w"-Viq&"H4H4H[bn"H4H4H>ii bŒ@1K致ҕ@ %-4HH ]EiiiiIOZܿ蟴E -SAځPѤE,]\"H4H/^"H_a  NhOK%A՘*X~E.X -V2iA iLZ%-q%-XgnaHtH. ~I* GZ,Qq,#bI ҁ'-4Hҥ#-Vi4HtH ŢKNZii.SbH1 E#MDr"-:/4H -t@H+i@s.k|U iף b,]J&1isdH =E.KAz^HPA A$-i^줉 ?imW٤.ip YABH?eI:AzH' N:A"mxT1HY+i#AAAt]b H/(i~A@Zi, ]\ Ң׮ʒtn׋4A+i/c_A:)iv# =,%0wOb= %'꺘'D#!t:Gf;iO &,-4HHc^(qZK{0Kt@Hǎ'i˕tE\i 4H4H4HYWt. ]8i+O ҂ C4Hiw% \߀4H,sKAzAI;H4Hw ]y\+5tٓ|lA1K4Hs-Eҕ@ڶ ALz^  ;=iы;AHH.,Y9&6HnAH:x fi頒.`msQA:i, Zu%͹@KOz^{4 훴O@ ]YQ4H)i&`QzLJW@ ji E'cxAAAAꡖ@:/Ҧ.  +IAb#5+4QmX0xAA}RDIiV |?Hii$Hte K9Ht%c_lҹH=&H< E4^ޤA*tj{hIAu2'oiixAt. ]s ]i˪% Ht~fAI ҥ%҈YAA2Ii@zI ҁ$3H%i@AAA:ot~ H4H4H4iB &MHH{XҒ@zѓ&E<&"#uk4i\ ҥ'H4i^T H4H4Ht IA:AA H/*$("YzIHtAI~AJ04Ht!|&K4HWib%M@|Hv M@AAAAˁ4{AA4H4H4Ht. Iib&"Mʉt(Ht& Dfߤ“&&E%M@:ͥ#=k?HtzH?{z(4H/0iI$iH"-/iĹ1MrQ(C iIsd&B/i4\ɘ&W^RlHʛII;IRp}A<&v}i\IHW9RDD&M~oAs'^H(/$(IHEi=&bGH.iJ'Mn,4ɅTIH4>yƯwT>I9&9HH+4v, r%o8G'˃YE& Hx%MYHMgU|1܍M PvCAtVLLڜbӃCq@&IP4@[#4)6ijVڞ]H[ R3)gYYPKHYD4!n9x9+SM돴˃$@" %EB MZ p$FN:{\t^j1n7Kq%iB}c;iE|> e:qfO1OYi>w>HF?SւzdΤr0rwϾI/[&PKA] HWR&9D;4[4^͸9Ԋe1A{tژί]Z.f z%U@!YXXPO%|4NW1S 9AisܛM~=qoF E!@<@I{D0tv*hO 082Vg4t~ %JytMLg}CNƜ?d93,)P:4J!7hs[sdvk I'VFgI"`F)۵?tS`girA%4oM}Csߊkx0ki2֬ΒE7 R ܷ+;w蝡,)(KvQC Ʈq]QaF @J _ e޾nB#u@LI_Qv$Ffqt&-]Gqt>zJ!^eo_HN6 ]I_BzEw %=ݦҽ*Tn.Wd|cGxZzo0nF |B <,i (iH# @4QoW"^Bb%=_ ^o5- iF4H# kiC ȋZjY/!Vfn۷u'͎Ж ȓ7ܰ~͞]cz }Hii|"M}te[__M-Qx48^iIhлU7jkmH#EhbH6С]CouHƨt!)36GtT.n[x{DƤx8H# %͂N\f"R!H0qJ$qiLHTK { ݲ72ҙh4x} /_ZHZ/C,=TP-jջUiRm ("tartQc/ŨSZƤڴ["IzHHhii8%%Fzvu)='ܚPUMoMcM AQ#l6R]۶۫:jɨݪkl=c (<ķ%FT $҃Q UxH (}ГcBx4-Dic<; UQL_h9DžEF#m"2\F3ڵ khF3`-~@>l-fdrIENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-demo.png000644 001750 001750 00000057363 11544160206 023336 0ustar00synthsynth000000 000000 PNG  IHDRZڕ;PLTE  ٢آ٧ݮiUhؔՖԔՓՑԐԎӐώэϋ͇˅ʃɂȀ~}}{{zy|xtsqnmopo|k}ied`a|_z^y^y\x\wXuXtWsYs\r[oXlUkSkRmQnPoPnOmNmKkHiGhHgHgFeEeEdDdDdCcCbB`?]=Z=X?ZH_M`J]DXPXgWXXXXX[[[\\\]]]]d]ZYi^Oc=n- !~/-D`);f)=h*>j/Cp1Gx5K{,T{f+X7O7R/Xd[ K eGBLhkkkG  &! ###)))...///3349:: ;<A?&?>@@@DDDGGGKKKQQQRSRUVUfffjjjnnnts~tİ̪鿉svmtRNS<[6[IDATx}puKe(ǹdKtDl˶=vql9mRT}rlaLK.LJUʭc+K h| H%>KY#X\r uLt.!33{{ |H'2y,Z_%J"bLNJ&TS)ѩbfyeum}ckėQP*)&'`r*1.aL|yaaaqi)Cey9]YY5W_WuΟSkyߖu3uIy9"Dw>GG:^~Tgzw*vwLbsm$#_?O"!@FC:^z_9q3Vܗ1MRWmۣhH?#C>iO CBPjC^&?g1#/yYW6jiׁ?)i%AFPGR{/PCǤKY\2g4hF?_L_ܲGZ:VO\I@4'i_f{?H{r]U\#%5i&ktӗ!mLHH֮6"e˷򫦖OJ F'& j,M} ׿măF4p6iCj2˘ޚgiky"ݻN~R{CT\m<]ٻ[;nl>k7/ x,>&4ߡ*;wrG!:Vk'/|k/8 DS ~; rt͸ oZHoNxBFo~Ϟx➅r!ğ9mݝ"sn_JA=)%=y%7E3ė~?7iW62xo| =< 9c;uo#;w[G%;;K{A.:uO>ϟ0pv6ԙn ۟2.Զ흭}=pO)r#G܆74QG];Czsb P_z>d&s`9p>k9O+;P#r>,G;MO|C{ s~r>N8g$/ݲ1liz 'aGnև#xG|pc{qo>BiCO7?A|N^03yo}v#G t>w¹˹|^Ν|r>N·e#' -L M_nȾzъ30^u= +[͟gkMx@zP+;[;wn^g2߹G,%#|c4qd-4Ҁ?r8pG;c·e!|v~~=z)G}@]1ALtWHS6y~륓/}㾻??8=Kt/ѓ/}O{?J~%,{ M;io{c/w^r>ȝu;r>`9NQ{ 5!|kn!Pa];ֹ9w~9z36Nq 3ߟ<ʯЩG'8eL_pyN?PP*/'8eLdD Jir^((%tFAQPidFAAQ,WWk5W:+2'hh P> Lk룼DF<3;.dJT;FRM[H˙q)OZ39޴-ɱ/FU+My0=/ם̯.%FKCLؙdsF("lKryuq2%šټN+[Z st1mX"ƻt='Ѯبj:#4xm>#SLY mM&ZZv1Yǎw% Tcʱ9v_-7PUL9ǎRW 3i4+ƒpi,\j17j6wHWWfO[!;5M4\$2_z1{-˹%v+f;xSOEwJoc#mWMKx#s{s3fu3mh;3u={zdz)J%]t.7޼ ņ/VHB*8˜seJ7.,7Y-egf%xVw%VBL̝uML!yfc OdQ?6Eo%vtqN|^Ml!ǻWrb$2cYPje6(bOLs@ieXD蝐&SL3h^44W3s*i3}dp {mFm!ϱxe$ FAAQPidFAAQPiLϡԿHL㒘(/eR|Gm{L˄EOAQ]`;u4QGі7[.LJUjbcf`"듬oi8boL- hy`wxGLzrS D𜹓%|IwTP",,R( ̑y^&^ ;"e.k>Liߛ/va[1e6$ixn:Ѧ6rԷNZrS'=h\fTLވ6 {Wwx0=ş]:s NMT~sfQA}L$/ ֫plL tU\P:WE ̃+WnrŇ,;/2 }$@?UGwRƦ9cNX67ntwtiS߾ktʸ׮g:nqQ(@-5=:NzIQ~́7]Wh*=6ӌW_}Bd :-nU3n1GUc2qJǫ3}T\y{}4KvB;>eL;r&nբ9$[ܘ^Ot\&zkmq1$2áQVʝ}~]6$7PMd&5gϞ=塧>lwcozk?詈zZȑW,Dj\Ҷ6 ih&zFz֥}3aוPLHiO9l9ga cH!Bt.<ӂ=/o txǔ_OL(ѻ&eC:ʶSCݳL;R(^L^G#iy g&oE kn3Tc`TTʿh?u)hna(XP'w34}BPs Lyx1h8d*zbz+P6;Va{DLoo/wPvem{hyJg5Zr'|V9Md:;r,QP^מ7:ECZ#6ӷ߲ϑ^_bz!IFhֹ\bPz[*﬇Ι}E4c#oQ2n iС> Ӵ31OZ.{V | eUGY)LXH-UFxiG`s9 ި↚ibȤ|jNۃgY=i{dLg dZM37˶&LRG?-;Woe9cOpzڷHrsgLqY`O؋7QCEGǼ/~qȫ9sfLW9gih]QO;f)IC4EdތBU1=RR`^z 4m'd=mS#8iB3/e^쵙~(HXL.hڑ_z˯7&J*P}P$sӑ؋rqfR|tߘ0`>ϿwXLOz.wUG_^x/rJ Ax{Wou恨r x);GlBi{5X\M{0MԦq?~F+liZBcij_{h%)Ͼ;N}Gӏzv0o=LjZ >L_ -G*mLtw)_3 6X}t4ӻ s˙Btj4􆢮YgS.>}n_;楟_2~ӣ&gO㩳ߦϿmiVcǎ1nyfLӪ]z,MQ+䘞~#0_hgLs^L D] 0L3r7HL:{$u8Nq*KƩOMGf Ӿ=͉x.,`mob62c~ާ3OlY]yso/uSSS-Y ˩7=226wIz#2_H./ՃF~|÷_TO.n>-)o}lmD9mwi|B5jgkÉvkٸԶY>iV3it2-}$;l}h3oƧߞ([b0[zz|ctwv{qqa!N_XLO8`->KG3qSΎл_uwuE>.] T#J=)=Mk] nOϱ2^bzbs7njJכּCGQ8ykiG87jˁS7g݁ Vi9COy7n![.MYxpeCSHUŸ+>>tm6u.)0K{ rCS)ӽKLOeҩj E=`gD7‹˖x7m1=7)*?fBMX̴לip,0=W@zZgM屢f%nQ$[ߧߟ#ɴ1.O3$1YbZt[t.W8Ӓ=-a}:5d7sg~bO"=T&/?`]0.I">*YgGK@ X7ވw@٢x-n%e(gϞH`=)Ϻ:${ں<@/d| gZv 5DygPgUʰ%Cn{.JM5OOi#cO dz3-ɯFs-Y=gtvAM.;'$%k3SݮW|Ȼw{E15Ka"FJFtLJӬ5e̓SO P;+0E$9%0Pu [T!]y.~Jt )Z ~ӡ~QBD9wzگpe ,ruErkt#"1L=]]- -{L!Th y$TⓁo`•)4$5>VQPiɞFAi=iid;Rk4 (4 2L ((4 2L ((4 2L ((4 2L ((4 2L (4 2RLEfPP]iEdFAAQPidFAQPidFA)$V*DH󙔾1~}dùOt3y*IsupEkŃC7 2`zgX3C33mMi:sy0rL$1%m][c#oi wF!С3 DLnS˟EZᘦz&[fMn\84]Y>5nO/\hLǻiaBE(EiÔ#3g4۬wǒ(?q D֙$bSi$KIZcCi#=bΧM kvLƭ.4-7^l4=mz^73MvI: D֙LNw}y'wӱ4VGt6wPڕ@2GsYN<պ (i%TTT0M ?joQ񷞌iRZ@lߕ*(O'7z񢶧(BbQc?jBI)*7d`XD/obZ0(po\hЫBx\7eTug˫ejҢ8Lt w7D3q0O!U1-v7ڟ'z6 Euѓ̞&c:hPE )N)6\LG] Ͻ&3 *;Cqg:y*z^XGvl[@*07K^|0]Ly#tԓiPieByrROQf>9h٘tiЎdw?g?Y׾*P`{:!1>XwKG964x/Ӯi+<.C'y;ϸpmDbUh}3mn2?3!*u˃ȴ4:lB[oLG a:ZY3EZa#2]KLG1!&<2EC-QEg:Lݙ1mᙎ(2cap΅TioIBT/5M~a6`ax)7ӠFtus=")i/ |R\![y3auЗbPm|jIG8EO!W\邙+~7߃xqAr0E$~`Z\L[X8)) (E+R94q$UDɴ}I[;I!, N]h(*HqP9./X}]0 J$캦Ś5((5cO@#()L2HL=PPV@\Mdv;Eb hT^}y;C5tF(iKn~Eb hT^v[auʥTp~En Mk_A*XW $kؾU.L%4c b^&p,sSgYRn̴_Ѫ[B隭?} W,W{jM{:/rSeV[f bޡ6bnM1E.\M+ZuKh2]g.򊞻Eۚ#57r)7Un%KW PyE31>PSm vj./ZKhFo7Wy%cRSL ((􁕭R1W4iW9N6ȼoyƨ,N5evIǨ%޵GLt&=s8F$ `̘Lg`kiB>$bg1jIfNv.0[+x 20}c3 0g1 kхkXbz\4 %@Bװ\4fe03" uǺcGwhPet#!-]z.xv;_Qt0#sә feÙ}=* cNɮӃ _]#+ᑭTsb?!C#qB:Q*^d LPׂE=3| dF-ɶGpc6&40CbC# ,n2vh!؏҆M(th?gmWۗSKjQK;$5qMgfL,gV^چuz e` e-oѭ9 b{gz%6f+;;veHZfzg)`s ֨1׋.?:ǒ0u9jI`zF"3R]lӰ;xx}X5lo[W? KLWIvg9<<7ULWK4GQidFAAQPidFAQPidLk$G7+U-Di\ !gR^&<!|Z43ohtݏiP~Ytb >Lg,hIHLe]xiG"ӵ*oږMp`lŚ{6$}k.|~[:2B6?|f'qc#FCvy{mSW{.jibΤ4sYӊ0}3$wz2íp4$ș}$Ixͩ %oa|*:œ ic3#vjmYX"Y$.vN\^b^f,/g2a5+y3:Ioxfr L/1t{ꙦJuoz+d1}qShNڈvf|*YJۇ)C2}d;KwS=SS$%+g0 Cwvg.t?gzl0-6@i!k3,1m?K;XNGfD9L3tCd:E\d#>}f`fefz`f6fZLb/@Fb0b3͓xgr`A\d`%ݑ$ݱ|#,| e%1Κ'q5 ]!n{py‘Y3K3tڇaF+3 Vgx ۍBv U)16?LmsiYqgm%M-fW| #}fl+/,terڈ=im=4VKvýv_ZKsm-L7/ \&Qfjxs|=b<./oyĎb rdʹL*pGL+}[Qʧ鲩Nv],IT2xiRBv<"i~U0mַ͙D.49zV5D#2 W*HNiEQr^2XBW\y6_bZ/~ʻ]V|Lk R*t0"9U:NrrւT4ׇunW9\<.擵FL#VSDÈwrn bZS3gH4iYt|Lk6JgRBפi^V:M`h%ƃ^f8%Xlw~@8ēi\;\jsz.b#:V~fN&bmLo3m{vbeMf(bm`L^DluMŴQ} M. Xr~YR}[?ˉݎ.ɴP 4]ĦXe"d'iBY" 82jRQ8/>+(f_^3Me/XjTp%6shuUEzâGhvb?􆺩T82qDzj[֕w zWA0@tXuMRxCs֪pEUu彊fqLV.-\2YR~ƫ&g@)=աldO}8dO(t)a̠S6"g{2U/Cj2dZu{J: zҊP qy:Ԥב ߣI! X|&ՕT4w\I(\̑tB.k(!AL'q€+IS_/ı 3cw Sb+0DXL MY-Nn ͋i}Ҷ=`n1i6@5@cָ.C!9|,}c=<ۤq%AGtjUekf:q0GJ5FZh4wQ?zN4Xc8V܄AG- Gj !&fpk1ť[D}$^}^na T qӚU[0J#|x54a"` td0>1 an"F~0МI`->PfL$y3s8ŴI}|龐Fcޠ }Af<b͕!|j,1f+H49Z35Q7507]QslV033pDX59ѡ&u)bZsBϬ1/ )h\Hf }][ek]Ss} oi)D4 gA*KbZ9\>3Z@ MZDB[>ʃiiB&MO93ȹ&%ї0)H,>"\ TLAO,#3٢4]OLILOn,Ş4 Q֮۝iƳgRgLdtiMenL"kLCz$V2 ̬LO,LfL ٛɬH W WlylQ=7"Y ;4;Vosdp#6<,0FlMmkwip( tfiBA3l2hveflv0\Zo|ќXHԮ5%Gv.M=+d4=l#Zn1blQM[uk/E}y2k-=5Ʒ0ܗвnr43r,Gei"wKdn&boYL,xѦKlQ깍HjkR~P{ ޛ+GSkd(lL ޛ+G:9qa/Ji{87DXCr>^R2!‚H*I ‘"]x]+3PvV‚=L#ӕ̮=푿to=H+ӷϣL42L S2fAKtwgI*tKi=id`0[>腴QO#C1L׃1tFKgOE@Ocnx='D ,tۈdsϞ@lz)>@i{2W QCk^L0ٓ22m_Ud:t Ӟs#^ٙ>\G R/LGiؓ0sXHR(]r.-{2W kLG<*DtEQ\^46){D2A'{ՙиT[$Fdӑ ^raxƳm#`6YuzlLG*tN1Lz:3g|H1u%6wpe]#Ki,ӑR2]-e=a޴."%WYUa$ d:W/#ed:`/B5eKJnKP G折eX]`5UTø"zJe: uQLG&tUk=+QadRⱑ"3 7<c?7+v,~LGd:tt]Ane~m$tĈ1$W<".Tn&Go#u+7<}c:RLۑ]sjI%-_SPAoiCG1P>4tf3W+t}yƎk2@IT41Ml#"  fgi"P!f,Wpy9f:`:0*m{5"s*E;20M="ôD>hiG!|8u[JLf:iqTZ^XVk2@T_'71x4llBf=S 4i9ԢfZ^ RʹtMD"\/&TxN@uķL6?#bE۾6ӆ:Ls,DK`Vu#SG4HoKCNF. P9T"#D!3{jfXGMk@C j4 tDfnL-Lm⺇BVA.b&TkN@ڏĿDbL۝6ӆ{Lo''Ӭ=hpBHp:.ib2@TisĴH#px|s?b&a. f Ww(#Fc|LVwF")j^&Ugܺ&TuN@`4To,Ʀ48rdځza˜L;#18x<ԈX}*6J0ɹ)i8뚒 G7mlӼqbZ64v:\GbDAvVu|LuM]Lib1MӜP`ڴ$Ӥn.d4jbje/Lu$0ML)E,EI8 2 i]Sikʹ\4_L ŴLq]7`˄ |T'V5\&*yKRfhLZ4) PQNtyY 4ٍ>4&2dLGP{Qr&t9Od`+1{CŴՌE3 ܦp@D4A}.9bPy8v'Ӡ`j6\i;&@R>I}i{@僧L[a +"{YLiP2 n4)Pdc?}I@TLD|Cc3 2VI|=Lip0Mj@Ӿ,g,`E"˴1D46B\sQOi4bg3 :$bj i`Z.N)kpkx,#Um_cZnɴc?b3- |1Obڻn9 iAk/8LUw)fZe-]L{s97L/4Fc5C~Vl3~ 8L.-ڈ8'޽yLCLC^I"b Ӂie^9 t#fa&~L*i{n(](K3 L7ӤL`Ƒzf:DT`L[ޝKA.{=]P`3 Ŵ8X5cMQJ4D<=2؟gѭ/皟%s0M|r(45_{J`|5t3]7PO#Ӟ?dTLCLiP1m47"iLK3'MC%x+AeC49O/gl3fd:؜sh{ iB̯'枹gO )2ܔD=}.6 qA"k*fl `-yN@!d.`1 }ǙVoŐid:ʹO߄/(RR9&id:,i{h`I9t RNmDO{ %8dtsFc ӵ4POl=4ikRCLWhkU)d.ӡh0n\E4fw+&'x00 4f(ٕZx7;=2`v%.ܺa׬AACA_AQ Ӆ:uJ6"!T4J `q2+eb37f *crgYG>.W&qfN`37f *crgY:LKG0Vnrdcgae$˗;帄Ui#i჉Z!ˤ,=ۣLĕc\t LDT ;; s(%qX/$p ݋#B*g{钸r,՗ޏ^R,=ۣLĕcTzqVH3HN=Rt&b"54U*.1w4 _%A-3to(tm0ҔځkO`,i2sfd{o;{lWb̊^SdV޶.KbͽlÓǒj;ufzFbOa"5(< n]>d^>Gn9_NR1R`Eb:RL ((4 2R2WJ h^%X8T h^4J@9.4 2L 4J5~I*5t<2ROR eTtiq3Y;Կ\8,3)U8AQ e?$ca9 )P F$27.Mr=QՖtbOl ڧi1;Z̍|\u47CMTV@eTWWfOecIv׌VsS]WifBU$l Kf?{o^J|~-\~9wr{+~ZoЂҳ`:kK"::WF||<eر8pRSSq >}.\իWqMܽ{>̂F"l6fwCh1*hb`qZ ֦Ql.ژfu{2ݬl=\BYn3|nu+]Bu DGhENVYlB7.#u?):NEWmJnV'zfжz4gqYNmuDWm.$Z':'566V2n аalW?|n7 jUi5^lit禭#}=թsXUL#&thնQ*mh@7=.Ⱦ|a@wζ#?=?VV/D93}TvVEcW ,l Q1qJ&*W߿/G(fdZivݸqci/]́ܔ~wz+XR;[,E=½lVbߑ+'X jJ'<+a*A)L .q8|y"uʼ9ES@vK\,'Nߐ&9).O}U>^\A 2֞q OQΜlWBX y`!gq,f`avK-yhb\w#O:g4޳9we嫷 v3t: \BqH&gUUXe`w9CB$cиϜen=qlUl̖vBտƢhPt]uTJ[Gm*]KkUUOSJ_tM5T @WW* t5jUi}֡*mUUUwUTjUZSTJUJ*]I+5PJ,(Z9ؐ:VXmhEG=h%hdui`RMo*qgixM,_3h`aNK-hb\NOO 4iׯƍYTT/YխΡfni2D͐PŬtGh6ȿ< s2َv?dC*K?[V >%>S&!% 12 ^FQa)ZK3o-aYܥ۲ C173nf>2 Y?gLY(*h=,,o-&Cnhob33YNC?=Pn W'&2kݬnWv`⫒MCOdI0jw*cVGo ƺ~SvgMefuIxuv1hnV%kgvSYU~u,dmUj"3v˪rhig. X7dEV?k>bVʬ5U2u0WݬAW/Q].Wr<]JzݬdQ ͌Ef1qny",Yꫛ.[nW\0SwڍmLFաKn$[t3Gz%dvaef>t6cEX7hPfZ"ki'͊uqgiFN.SdƙǭLʟġ91n^ĸ:M3t,S+y6CG+ޒزü|vDw^-Z:)dUwFq?̌/rYm1Mv^2I+uX+-ve$G. lE#Y_"#l$vi*Ѵ?Sn~>̜r h˵v&kc8揖:mg&q:Y[PsPdBq~F8B0in6t!*6Sf >;k=dY@V'3xl<Ys0E l"-V7k)2Sـ0uφOPdE6Q7tQݠaZ^毗mH͌n [4 :Y5Qu"͚`Y{fM{z ~Fu)zY޷IɢI/Ud{LY7.l+n`﫛5.*& L7s"'$E欗5qqgc:ٴC+uno%;qhv,&7mTqu ͛rņm@S\=mb=&S.#4&SwP2$} 9K93HCmu_Lwf [Ix+<`}@ .!5Ng?<}uD|pyg$n;6&Xp^ v7-pN5:r5,JTZͮߺt{VcS2[xR.X{CYۣ 1n蟍w>qvX."⟙u6_,Z وpqluN9+0$fDN/#:^uNaxhUPdfLfٰ o%Y'fC Vfs%gʠl"oLfaE6XdStg>DE6Cf.M٠颲x)*Y"fmԲu3?_ѳY7/2ݬUi FMUhNGTU2-K/kK38{2oQޢx)x`CZRyL*Z d5Ձh' Jv!+{nDSS͇ӮLKW :^ &ݍoI`\p `}qtEX)8$n?,])YLj6uD\=uf7 wD/cװm9@U"[%+DUtY%8,'Nz&޽[vDDO턬#e&*dfVϏ]_%OenyX>r*1ILm].+yzY.l<>3-UͨrEYSA/zY/\lt^SdԮ-V&+QHMϬEg#P ʺ Ud*DT ɂeeY/RdZ-VfAYd $kgd)/`Y7j>OVd#J^6M72b^dEk@f6[Vfd38㌳]81PĸJ0nNMѴrA4M'hIuΓ$b6WrP r'!E?4ZX܏n%*bm͔oSV(8Y{JbbT71CiMw7J_M1;t|ئqna/(X h%0IQ6J nzVeVzXG8mO 9nCkY'AW^*h@&_o28myf62eeU3;Ef&$l"sQV Rɔ9-#Lᙽ!Z*z)e~,Zd[2GCq"7$[9)a2m͜rfCE6N/@CR1&gqgٽ-ġσqu ڵkpB&@ݴz! 3_ޠlKmVO.2?lNF X[e|egN 6ec 0 *,A= {6@ y<ղz e ˜Uyf(21M^@3kx8㌳2LZL3u8)X@c:Mw : W?[b2/l)eE6_d;K~BsefX,![|ɓr?L8?k1aq3br zf͚I3ji$ISR{4u}qҰ'ڻǡ˔y 0:t;#vy^@ۡcPY;|^kblذgϞEttS:kԨ!WXB͛7k.,\)9_ݽ{{ŋ₥KѣGbX,T7X@!.UrT'mz 郀rt?GxyOT8\&oz:fBtG]{*4s>uM3#@A d(*"~/{ģu0V⼱ 0#h<4… r<`tgX}Zž&Gif;pDp:RRRdk -Co쉦swyV {EfH5 hvB ^ۃp;u"Dp>bL_9PM/4?/?/bDf S_.㚟oc0b.$M9'1,d>o]i*LU ɲՂ@^1&D5`N~2j7pwwL}{tnWw˾bso d13WOjDEQYaMؽhl6Q.T2قvn)=] s7  sl1p XqS?v|A9ЏZ,L-ڦT5o; t!Ȧ} ΂il-:No}*Wweߖݳgh#].ndn6 k!Ҡ"< $2Q}vIFϵ x*!÷$oy\|KXK4"1rЫ~Zo޿_b?`wٟqJzuqv-8뼢cU\9̙3G~Hiz>ٳ_sAtzzl5}q!e=2,cМ:OɄ3h <d_\8Vի'?͛9_}o9Eljժ%okC+(U "gO?F4ZjrvoVZPv*{o&ݾ )RD> ݮ\rTZ񡁩ӧOߺuKn^~ KmFv:z郞F9)SdFO>'sw=-[V~#Qviذ˪AfTTs:٭_1<*!hUC4L Xa;% n@*c h*W#~Tg>S/)%U(w 5-hMYΑ+I{-O~֩mdo3PLY99Sw&MnSM}E8M#8O _#nj MϠ_$@UOraݐcjaflSۭsAsAXw J#ߐR<+Õ*lQ6ד\)_s_o*D# naX8w,=q3,&͚J <~kwz6L&hx: j-5pU i,ݦ6RݺuThsCopB'` ᅬ={޽{i5#ِ7ߔPǏTgm:&9=f3Ŋ3U;>Czn| Oo2~(!.ҹDOAA,} V(/xHѳ֓rNg fw g٭_1䴬`WMQn  .t]1SqjM1az|M/:2hpM{FL5J'9>>^:?0ST djR&h2uyiQpy|!A{,K|,+ӹaV:cx^Ly&"\Ŏ zP&D(oi<m0v. ND6$_UO8XW Ԫۢ h[Vy>5=E?"xnD!n,.q  0`<6ѱ4 h< 7OD7\p~=g!:8mךjTI5oMkҥK7G_$cHo}] tLT׀P7v߳gmӮe ,'jߢa$`*smYy6C;8V;C!:cs:6j*!Z_h\,DsF DD;M[ 1o|ssњh'''.UP*Yi& r~ )ۚ ީh\u ~`w=/ٮmzEBz>r[mls Z_OcQ^#Bo:4@LX@v AM}4qBO_ J%_}R%SiqJ8_n֭!UbT^pF PA pn3ɾF11BLo;RNM'H;[VoHhvŕfGsCsDɘQ8K=ZVrD-\sNw$mYC @4P[FuL(CdWqn_v[{hm>t|OӔTAY~#U~}V~hg=tԮ][w.]Ӿk_Zh~[hhP;GE]vzINy4cg(D?g~cӲb>oP/+ZPrڄ͗6s H%8X ݁]Jr9pm~DXfTO f : jUnj7izzzk@!?SS뢒un䁒xcm"Mv{A_*ƋF%9u}C0v#,gH",Sdn(@scpLFk4`|JeĔ qGbK@T!=w$-t.WߚY8djc#FaX#,mFYS=eQغ7JX[!h^ GG<gI=LpqPÇg4>MQսvh*J=PihP;!$`b+Z2aFO5s;3}][tlmmQx*P=Dk*JtnӜ1iiYb.sL|Yb9 `E9!v+0/D?-["a<ͱ,~i:^ t589ڕnj7y<Ѳ-OeaN6}Acu\oX!+մ=s^ᮡ]A}k{x+):.߄3b{H~gV5:79 coM چѥ95ly_} M //zGgm8NGFs}8@S A3+zWCAtb%y q;N}MJNMBl+G!-ǢFahpbN A2_äOܱ]ň}iРIa`f'ۆT!:##Kok武_ҪU;4i"&0לVݟ%p$ǧ6K5&Mv4oz}#t.FӾӲtSaJ(s?Ghn=$j…!^Vt^ic\o^Ӝ1iǐӲj]! n4f.zZߨ0#/(c2!z,F` D^sㇲH5:;7u^"+jB4n͌yzcIUyIo!0h |SM"J~>N!HS)Eߔfd<oExѿ.@.9qS8 S9,|![e99FbcG\ ։a|T8rYx懦 }"hĬY䴈t,Cf_Fw3Fi б^ޏuNMSZMWc"$-B˲tjAxeX@!Mի㣏>gDk` zhF~As"]F*jsdm#7?4U`JPz|\n+ "or 9mF-sM6sw:hF fRJևg# =O9D@KHϒrY>t/_^VkrټΑs| -|X љ,|.3=D!c`iV &J臦V蠕1ef||W0$6 @$5OUc s}B+(,+-?@}e?ww>hQ5YHBun֫D٭z"?|T zy "vcl؋eSrvߡShӟ ]0,|W~L].O; jԨ?R%!j!b# 3:Ή?h < iVScYT7ig F {N4=E?/1i:yzd1D&#3.3MIU@4^o|_7%1xN|[\G~oUQhjtA,b:XE2Px40s-J=W)!hz w鹤 "Z"UJT nՠWTR`!@@' >2_|P(ONM1iJS$҇*r#z#7E?/bJ]XZvvvr꠼y~^l~7V@T 4+ۓ'bN:Ν`#Yح\;O s=ŝaϾAѲF ) `mZ$s׺W0RF~LͥǑ`ks# 7BJLn3'&QOr*GӐ,yǀ!!P'D.WSnyVjio` l(/>*z̹4 Rb@#+qiDX,.@H}b!*/_9@8?Zks:}: dfX,!~i[ l6ff o韛fl3C4]Ll6fl6fhh6fl6!fl6ffl6fl6flh6fl6!` Jy5qcfl6?h՛P76fF/D_dDX,b.bf0D:bX ςh <ϛ7!bX,C4C4CtN dRAӧO#tQHl pݺu yчZj2,bX ѯ7ņ7DYp2y ' Ɗ+^j6Y*(~7o+bX,iqM7Ǿ (mB\ +,bCoƽ}*:op~芐BмAl+W,m(Hϝ;eʔ/3g3D߻we˖EXXXߦL%KH"O- }pwwW bX /ک1}+~ U/= h >>rpۚ5k VBY}Yw_r'raƅ z0tRHNN9c…(QDcƍJbX,!yT^~&7*lk"m{8 wt^5kXY^ftah 0kô6<acc#믿UM4rheY)J.ׯQfRA4X,b1DWހen8/۸}wWmKbV3ýDP=iֵzuFc(鸸54DtnbX,!A 7"ΜGiҥb[DI8f&JhF9NG0?d8x'z,Y&9<|h񈔦@43bX,CBDICneƍ{]Kիwiw$H_>OV+@8[]5{A ]H\0" ɋ-fxfX,Bt-"$< @ 7ojtvWSbq5+2 h19 SQ0j'mZ(2a~## fX,b~ !:nC"&&ɖ9[n=Ůt` },q@Kbq*)!NM\!ԴMAձQm.8{+J1'r2bX,m6p? 7Cq{@|h۸r[ ~hm]pD2^MŮ9nؿfnGQgl :J>z7}WbŊr!]|e; :X,b1DmSL!x\Ǟ" *}"2Pj1lsOzZbbb E%Z3CGOՃbX,hh5&ˆO-)?Ez-qk@%`9Q>t >ijI_.SΝ.nNCMc0~2=hTTs:+O{HʗVq{CUKX,bt:UG`6UVu #( y8oA '=&@9(=8w_t?vg1zU:lcy Z 5 y>]͛bX,CthM^|9GЄ:;ngB Q'Du: tF'ݦcLۯ=BYQwf̞=hmxf~bX,C i5cbFH a'ǀwqV}d>~WAک+H6\|>ku<6k0nR6l(Gί<,b1D ?Q VżG9/9Ns)S[܅{,?Mw]B+G1eu>}nCmiӦIz%{AZ x&ZNOOGbׯ_0`>8|pru֕GϞ=qY5kZ'-7n8?^B :uϝ;'*od_xQ~,b_+HӬSb=:Fm@K=wQLy7cq80)4|o*1BD [> K9-/ۡ_eJ@zɒ%߿ .Ļヒ$&&JYMQ"okzi_UN0NK7nd T|rVN`ff&jbX,!h H`t ('%v|= JG{Ϻn0]^{ѫa<,+g͚%[mT2Mo9YТ _| {۷qddOmdA#Gߞ?^fxVBY&&Xv j`4##KFq5 }r$vqq-FÆ U0A<$''g>zBv%JdݏZ=6nȯ:,b1D鸸8,Z]gG7;E$hބ4v7((H$z Z0 φ .=U}Km/pLܦM|Gr~˖-5D;v իWt[ jMMM%S5E5 4;G*UdFbX,!h*@njC:|wG7QDk@bX,C4Ck@4bX,C4C4C4C4bX,C4!bX,!%2LY,b 4: ,bX х gxw8;D}3DX,b1DMI|Ζx1jԨ ѯR!bX,!0;l0|Ys;˖-+/=]hQ=:k!CȌ.L@+Moͪpo(YQ|yy[{=9 L:!bX,!hH /P裏0f3ff 7:zСsnŊѷo_ RJ: D.]w߽Ћ0DX,b1D?iF Y&S5\4h׮f͚j 6]<m Ӳt;:::kYOOO׆uhbX,erJA֭gzT^olnu.]uqt[ԟMi<ʿ1DX,b1D4=ԟL;;;K@&i=ݻ˾euO4 O3g%5k0DX,b1D[>}::ths"`8az_l^䌃k8$@hшNa[=-;[ۆhݬ.ܬ:!gvG:jxn ) XtEUQ֟45#`nn.+̖9r}zר/([,+yiq8C4bX,Ctw}F+9b#vGK wp&&&zذatbu8/1z 4+ ~J,)=b+,bX х+c9kZ{q3mp*f4SU+9*bT:`8x`t 5u~f_"g,k|ODK9"##Y,b D< (U8rVDZ%/3GZ?~qYnOѦ]("E>fbQݹ-8yY,b DgHHS };hfF?JϟbUUaTZ{ϰ{%ĸ%ֿ.[E/=,bX хGuEZjKY'N@f7UAo?nC=$ۈ1~s,[ a}pp6,5kmayE ,bX х1B,ú1uhX&?cem[G@Xk  ӈᭋ#ixeTh/DX,b1D&ڡeFhl\]w/_ZfϞ%KUV=$:HC`RX+ +^|1֝Ҳ8L*lbX,] LOsvˬ]+W =/XW^[¿÷W]9tߡ䗟A|obX,B 111X|9VXrTѦ ڊ9V vBưwInNjbX,] :7ߝڶB5жyCtI^饅fhbX,tBWvY,b ,bX lhbX,hWhbX,hhhbX,hhhhbX ѯD6hy|Yq ϣlٲ;vlZd[nwʔ)WM&BDY+AsaȐ!zHfzdDB!PJ׮]+/"ʕ+_O*%J@"EӧO+3qĔޥK믿~C۷/z->PK/+++4hTU/Ty={s7SWVRc,^8ϟO&B)]|ytM[BTדr]6j7n "Ç.]~Vڴi\;=}Y[[WZPvm`˞={`cc~3{}ʏ^{MWeی3PdI};J4!BH"vvv[lRn/U_9-2) = G}O9Rc*s)VNV%Y_zt%Z3}رO=TrFs7S"r~ݻ79!B DDiCEU*r~͚5>80EC$nݺ2a„,? 6EӓhMK\P16.٧.K 3O%[Jj gM-g}V 5%B!K +SB* 3%X'#w}'O<"3]%b]^=}ƳsHDEMnHof.B&B)nW;rhB!J4H[W)фB!hD,--1j(XH!Bf7!B%DB!P)єhB!J4%M&B%P !B( %B!P !B(єhJ4!B%M&BDS)єhB!J4C&BD3hB!Jtʖ-[`ii s3g.)фB!hJtlݺcƌA֭KNhު'| C]XS !B(хVE.]qơ_?Ѳ/hKWL[u#F/o}gC0uLJ4!B%pItJsC1q|,\l pq=GO"  Ŷ^t2 ӧ[P !B(_ΛN{R:w)n~<x&/^ĵkp%DEEܹs {4:uI&BDߠ9|?M~Z2za6S|ׯ֭[W#&&.\@dd$U5:˜e2Q !B(хAkm'c|g~w/$%%޽{sX\rEWI:$$X cv&R !B(хCkiA30y:8x HHHU踸8qeDGG#""BWp)ݏ!#ж8L%B!]$Ol7cU%ݻ}vJTCٳgu{15;%B!]$ffhIZsVvGt͛q^2PС Ǐz9d=ZE&BDVSUEzտطSW#R>q|||z7A#0u*%B!]$F&hv˼"*tZJxJ;B`BBxNc$B!P DW1Z+8 ԙ1},ry-OѰ(t 9%B!]$jjZZłnX,`mXeptL_IM9NIt.TI&BDR[|ߴ3\0aNމw1a9Ze! t.=QZ}SgP !B(_+W~s_wk9~uAB m:Ѓ Ϝ9][FƠu{ k؏M!B.]J=Պ+-{3h߱7GġC׿0tm4 @j-1s%B!]QJÔiD :...pvvF?ˊߡNе[oL>۷oDB!P D/^Xp#c ުz1vR-666Xnf͚ǣ_~ر# GG<(фB!Gkkk4j3v?UˀA.}1j(j mڴ1i$XYY!3%B!qrrB1b$)Sj3%B!X#/BAfJ4!B%DB!PJ4!B%M&BDS)фB!hJ4%M!B~ R)фBDSy><)єhB!P)Fd,MDB!P3hyܬDS !B(я@׮]e_Dry2d|M+V st[jЪUT=ŋ)фB!!˗Gnݴʿ*THu?Jm ڵÇ~gjۈ#k ^1cJ,r;J4!B%:Dn޶m>mggoٲEwppH }zӦM6GGGjJ4!B%@I ʔ)gY:H^ҳnH:+$͛73w)фB!'.㦶IW;rhB!J4%:+dTڔhB!JthyfiiQFqBB!Jth.M!BDS)фB!hM!Bf(фB!hM!BDS !B(хWD86Q !B(хSfNRObn$! ~ N&BD>v"{ x=nd5=znhB!J4%:-R֕$I鳪o$`wJ4!B%msVWCPdy-][P !B(_ݎd@(N '11xI߸\R-Q7/W wn;%B!]0% ;vBB"cӧq?6ovڵۀT$.<zF]%w`[j5]}hB!JthW}pr:O|]EA_sDK?ΞBmk ]~=NK--}ѪD0hB!JthWW7D!4h#y6}|]K@%!JÔLQOvW}+<1~-ŸqKy1C+'0G. 8pDB!PD;;#0,aá}. H&KHzoR5gxƭSvXYm&75OtfQ,۝ପҮ{> ˜Jn+<"DihUI h"ӧ*ʼnk8|~!hB!Jt|pU;#0&|tHm([">#Ii \Ͼ[s s7?fkc,ًv!SdS2G&BDo޿[aZ K3:&q¬YеkWËy^3.vh5[1rBD\s_o'8'@LI&BDo޸qZ\%Vyq&fLA>csXN1ig FlGoX]t a 3UOoqIe:4VLE&BDwv{oz71mM}=D$Bc_TvbLWöơX8˖m/~HGKU0'-AoS !B([9c0}S0,n!\ד>q#y;+5pөX|&s`Ke^_pEZW狖4xk0~ lD>{ T5Z;~5Z$Z:B/P !B(`NRtK)%nʁ|X/.+ʢ+"}0hJLJ(\tbn$Rl^0Js{e!%B!] $zWϼ ^^<+qHͤ9ZsPm,sTK5E-רe:Ss Wm.&i6F˔w7|+фB!hJt wc޼Qlv!P-KG m=yw`fi4i93QZ>ĉDD_,0 0 SBBmۡ^++{=djG̞NW%6X^ !s0v2G^uUJs\T}/z|0 0 PM 4tƢE֘}:^y'!CoXb;wnʶkעlٲxQ\9}vK/Æ |k᯿JoZjx?~%T%ӧO}<_~Y?6Jt%z֭ 0 -DSm۶i>|>tR цJuXίYFWjA2&M/ 4~D_W#q{{{n^%a*љ>zxgt<hJYB!''Ǐ#G˗ aaa.,cǎLoްaz)]-6Tm\6Dn'g}6663s077ܫW/ԩS' 3^Cd{ǎu?8%M&-٢P\C|Q2wN]<6mEJMv\>}%Z~;hذ]l?]$Z~AIŹM6QF6ѣֹsg}>%ֆ yua b쌢Ejm6Vݻw%hJ4%B(+mPR3;G6!#KDZq\yG<;aZlR}w1yITejժ HeL2z20PiNquA!K̄QjU=FFϡyZ^3[e0sd/iJtސ3gΝ;BZB(OR˖N]|"\~wIHH۷X\v 111tـ.ƠffXl%X桖diȫSSD1 ]_ B%IjC/+{Ht\\܃=YVVXd %"MR6lGn ,ONҧe}#d^}@{}vܔ'ZBH5(SN{3)-h*իWS… 6z+_nP-j֬װOzeH΃=bĈWdjQFD/88XP|V>T  Ѭ`B D.z5>/Sb [R*i:** o€P9hiyS)={z E΃<>tTEJ7lG-6Z6lee&=3gԗ׮][OOJ\پ}!D.o/YPx j7n?#v+_9x`*y^q6ZȪ2(U={\L~e H)SʊԶh#W_}UyIf!w3}-! HtzFkb5>+5F]M[S G@_|/^Dtth݀?xy;~\'N0y<^zRǃ^O9JW_镣{=}?h&OJH,}USɪ"r9xxxl9嗧ND_Z6?gQ1L]㣷D\"} ԩ#ҥ~<ȼ 8Cc̒"(}g( m6y6:H{-^=Q~mi%Z^$s7 ҕa䇃aS0!JtfϫcX|M[N+В~֢ϟkPzK|On`ӁvjZ8 A;7w?c5zF'Z |WPTz,4ghuQMNϟ?_o+#h&OI( r^i,\bn5v0+mj=G%qK+-JhAId.q9$&mi,˞&Mz-8ft]9|%SƑ6O RqLs $ѦzsCK}Z .̹j͝0B{..=,ЩLtb]k%g9*V)f#-"Yf͚H-֗Q) 5m4UdJ4'+Ѳ|.ʰ}n'E e#Jtzˋ-YEN-[> R ^ec䰚˂:cJo"HomKmZ/+ّ|-!Hj%>.U ^z&MwQىbڌŘ4y.-Ek0j44l AcХRYOq')[Ybiۘ>}J߇82'zذaZ IQde jx}K8rSoC;"Dg?S-}dh!ȡ%ZyʯfA (hJbH׹ 0 9ev] "䗺 &LԶzM7f}>#5}ǒ!P.і˭ewBLGW-rUš%bCt=q]}G_'ODY.Apno\ˑMiˤPD8;Y <Gկcظ)@V-ܗo%:mdf &+U+2+#< bvv~i^%i=Ѷ"HMXDZN+ѦgJssvJ   ӻy-Dxk  +[5Yyܹsgו9&#Q&ogj[+}j'/*|V$:mZBHAhXDaFѹ$-У':b.xօ-֟"G3,OuԪ7:WcvGJe+i94 $$ڵӷ6Ba {O#dС5%:]zJvx7;ʝQoDٳ+ /mBȓhUZh.1dNM Y#Fƾ} KRuU(':MOMfaJ4C~$ٵ@Wor .%(^UkxWo6C%fx~"`e唧抦D3 0LhgϜKqr:Q8Ls+ZcfꨚCA QoVY 3)v-%aa"LCΥnkh=u'W tQEsUDUߓ*U4 fSyjhJ40 \frJtvdۏbƖoǬ[Ϧak $;FhJ9+Tn5#VUץ HUgqj9X[[Saa H DswX}be ,0f5[獝.6|]Q tJe0jبfPЯ.Ufb,ڪcdJ40 0 %:JM~WfUxlQ? o1+p7vt@%jaEOEՔv67ת6+3QOcWfaWEQaa([=/`IXR|)dx Xr } h6VDXQ-]Fp||_@)튪6"¥bIrw„ ( 0 0+чp~׀UUV`ҡYtYE (َ̱Tkrt+ruh.]QRۂ1zV -֭D3 0 PD[CU- pMB fx]v끏 >(Ο2pNpkv༺mȹ$Xy'oQK}/,r ) 0 0lgs<;ނ"-&X~F~,O@zsy(nPUh5 Gp;(OV9Ia<˔ʳURaa(JeWdi,FjUW"O1Q`h1 ]}<[=c7KQ^lv#F8c2W,X 66~ha))9 %:4Z/x J"{]Gj5V v?|<}n`מ]$'˜v;Q Um Z$w): A"YM70 0chY*%: <,^n0:܃$x5v~@[q7¬Q)̶?}~\J#.*K¬U%zGDۻjv= LbӦMhcaGz@D?,p kEl=sOWO`U,wO$|+M:mNp? VvCN߁ k',Ŷp $3{w[5]@CJ4B!M~$ٱ{:̍Bp O ĨLv>> | Nua ȻX!Ç`@: 8Z:~:Oji/ϔhJ4!J4Cq,ZjNB߃Piw?+FJ-AaXnjlmmM&Bf(-;wOKC 6LebFLi_?+ޔhJ4!J4)яTeinl޼YɲmJm a#&NrUUͰηLDBD3h&Htdd$Ξ=K~$%%ݻnrY̙3sc!v>pHܹsH3lٲݞP'"oJC> e/_ƨQ|}ٗa;v/!PMKW(zbRhנv;9!$$s,,бVMj3m7Ų\D<ujfLƔȩS DAttt>4]ڵk&8>,>cXZZf[h/CRa$޽{_>pBlٲ={#f͚vUV$:e$}!Vk؆ pZ~_U: IcVˣh)dTƖ)RD!iqa&rMD(똟%:Jtڵ^zIvb%W_᭷{ァ%x&LпNeg^pS-eyV3g|E_ݳg֗7P/=˪@޸qC_ʏ5k׭VZˀJT!U@,YVVV~IԨQw֧cnĉ3n޼V+ !'(az-RܶjUQ1kj8_|kDw pW,(j2|)SF@R+7ԟƯL k9:۾}mҢE }^xA4~lH|T^C۷oD@NHgܹ3<wwVR}X"NAAAyRC e֖Ȁ:-"h߯rinݺ?~&?B\Dg$R S*7-Ҷyrŋ lܸFߥl7 mmp-~[B]%:3́ԑN_|7}ZUVJqJU˖޿=q~8M]xk)Mm^ HL IdD^'NH̳?(QBW ͍!_{CQzr޿Gvx;趄tVND… իW?MJ ɯ}"FA!iAr;C_T׮]Ooذ!~mŋu 9ymeFP'"i{"ǣ?>~U+ÿ|9e>Ǫ?@2ᨊyY( i]B;|B *RIG۔sP!r[J+=y]`>d,յ~[/"WT)EhSɪM愖_4;wNcZ!+tٲe+WN7o~!pZKPADM ˫I'*VF|0t&Ms|Fu8;m,a*r8L&Zn*A9 xr/Zz6!!A_okBHhSй)R?N|]UUKëg8Y)c,6ڪ6>99rdj=i֌jS ꜑rJt6$Z5ao]cG3|p}ҥK.9TV?UFi]Y6N\_wM+TmD /?zv L"~G^쉖履~-[f(\ɏB hCJtv%Z~<̐ M9%:2T^ѣG|ȑ?nΜ9oFRX1݋VrxYNKRD*-jcՑ\OCKsdƏoРAZ+E/KNK5P~HuQerH^F覷#{vyN.:uR t@PK?u Qy!т84iט1cWF-rTcǎїEEEeX&H#X>&BXwXV_OG;%`pz-ogwRiqgMSzrהDi92)cdpWfAAϱ|KY./o0 J{{ih֭ӭ"џƍӣG:>/_@y:j>Ƃ8P~ HA2G}y7@>}dF -C5H[ѕ.sCz-r>7ejvp#3O 駟2<?$#Ruk+BH~hØ<)磒zQ (_iчXTul}Mؽ:~TJ+;ٕ L& ^|LmPK$3?Q\ΑsPs 22SGpL%rXAa4kLNjT*цTSVJ,)o*C/v~^%/Xߐ2Æ-?dȐTrXZpҺ \$ZN5z̳M&B~PJ4%B%Mf(єhB!hJ4%MΧ0 0J4%M.-YaɫDSJthaDSJ40 05%D3 0 CD3haa8'g[؅헤 %0 0 >"^lF2aTDSaad?6t*6l0lDSaa(яXIބ0 0 %)8? 0 0chaaDSaa0 0 0haaD3 0 0 %aaa( 0 0 CD3 0 0 %aaa( 0 0 Cfaa(ц+B`Y@B M]3IcK,.B`fO֥̖ ߤiiLqXKX}{"J\e<6뾥1%b--B`Gc2'\i kgqИ!SdVQځD!v>3pR:u=g@ÑIVwB`9;EDdD4r JOXO-SdN..k* ?ٮt[#0]S 3VgA`1M C ;X!k<.n*} s"Րh fD2m@A`:ګe͠Kl<1'pf_FN~ 4~v@}3h+X.Q f V'ȁL(* D-S࿫B j'f͉@`ۜ[W,D_чߋ D-|ق@… |{||tx)O__>@Os1y|y/w!pwLa.<<\<<}ҋcQ -.z~]~\ =Xʁe#y"Q -Jk BT( Gp-čl@?9ZrMJmW30s0mXLOd/H6vp {fNoȁr`3'\C V>(9,jt=6N ԦLOi7M]3!Kxt;ߒ'oyL! |6@LD9Wo"S[%DDtT Me4S89Ҳ4&;4bOFGOL~{p}} ǷO%k1}z΀#hL|Sz )kR)W'9Jy!DZ<D[%p}"eȁXs;0׀ " Ɂ~5ɯ}"ȁs Bh0;E$ $2X&5URd])K1 x@u)))B9fLĮ>aJDy:iL^!I,z:FAxwɖD4V!Ҙ$ٕ6X@>5f0p "&mш:E=h/ r`y9j>Z7';E6r`*Ɵ up9+`4Nv҉9 CDyI`%A_x>G֐4NwJO©@&"a4d/ !0@5WYPe.eb494b*d!!0O[/_'9D!1x9! E!:6v4Ȝpݓ;mW8^xD ̜p_]`J4J t?S> fOZ%;L/,5K-?/%Gژ B؋6 hCr?O rXh̖@y|!nx_5Ҙ?O/2'\ M1Fnx#6x̜p=43R`0fہG@fN#Ln.G $A!OјV,xB r B B B B`]O3!!sCjҙ RPX7^@CxMfb} ,xV"^H5v(o]?B$,r@l͜HWw#D"ȁÜH`xځ,`!790(pt-!m9V ׼p Xi" B r`B B @҇㌜n4*CD-%h0x0B`a?-0@D!zs B`y#0ܾ)0ЊçzEIv̉D+c Mc"_0,A`!VgN$ )ƍ5҉@^ _~R`x9I IcMcfG\')0#NS`%cۊjX`ϷZ8G\+f; ڶP@`YoAk b]O {p%6s^> {>g>7Xc*"Lr㺼&T2->Nb}Kud]OaQ07Q`z5_Qn}-_8f]/ZYՑ}ku6S%+Cb w'̼kü|2Ý^9\׼ț׃|ۼݿ4<~}GSA`F`C8]M8'ғ;rt!/B!ǩ@]J[/A K(Mqqi8^!^?t_9SgueYBw~V RA`*K%!xe%P?@,.^UL}'r !:D<ף?nةR~ߧy?EW4,_,w~8z i@S 3su zG$*{&t7R1ѵ'c-ӝ4M,DؒLt<5X|;7d*]}xJ_OKҐ}N>cTϯ(.͔8ADKcFȁ *_;pl2~r;8!r ߒ>v 1is4 ہU$JG_KqQ[i*9&Q8!X@@@@@R~0 p3'Ri@!!rIENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-maxima-datapoints.png000644 001750 001750 00000026035 11544160206 026022 0ustar00synthsynth000000 000000 PNG  IHDR ?PLTEm    ) 5S^H1  #!&&%)**,,-///000112334667;;99<5(?3A=A?A>I-] '%C>_F޼ ʊDĜcԪs鶀佈ڷz}dyxvsrunmnhghccc```]]]\\\\\\[[\[[[XYZWWZWWX\WUtUC\SNSSSRSRQSQOPOMMMIJKEEECCCABA>?B7=Q,j-An.Cr2Fw2I{6K|*Vm1_BV|7>=u `2bB zjʿF+sx) u)(Mv_hl>RSaUFPSk1ԥ^/G愦]jkkoowut/w^떔~u $aw. ;{r ?^ P8 Ha`a1Mxx6$9mPr՝P6[[VuSbF?_ na=3;t/gYko61Tinv%jǯ:;B5z>4Fo20k x1,muyEiッ€Cg[aI=ituҲRҶRni.SQZ*QRBJ c%}nkG?%=(l< pAd40z ?CQct_T1D--J_& b_>=u- k6wJIټ[d"?=m_s]d)SF{Cb-)=H?&2w@L~O>|;?%4UQ;>|J7=CZ=5*G=Lfև63ڣͯ(\;+ / B~3tsBמMbzP|ӎ y[Mv~q--=^0yCsCFD^T^Z^P͔~QB,)A0m )iMJ?pKnRxKV>+7vBpj}o gAW}d_ع ŃpH/-p 'a/ a. :C+mT MlKKesuCbPMIJ{6I*w}|ͮC~6I ڵy?E{M7&o_}m8(,6GC ێ[[/І[JGJO&q~w-m9Fqiyz61go9Qz?cN?"c~~a` #?$Ko"\v?4Ls`;I7}"o%uVnA!2 Qʱ1r m8)#%| "#ܿo[W>XQZ*gnRT%+F_)?Zh~KDGσᡑ}qk᧯=^Ҽ H 5}BKdcaأX86pԆ۟ -|$?6VF׊6KϋK ѢFהM/}-ǏoD~߼0-hBSQ8vxcXJ_NHLJ>!.|5Oc '6a)U_N/ೀQ6a)Uo񈷦;6a)U:ˈrcǰ4(-s,IoQ/qtt<1+ۯkAF!;VvSKABRghIo^b1o\WW|~ƝNeJې__dkRTkKP:_БĂkFds v,mWD6Җ8>qmɆ RtS[-+qٳyߠd&٢Ek+;VZݿYq='sUkKPbjO:VmTKK#J3Uꄎf*mI]4~7+SDU|oߠ*]`n4cf}~JKom(u^t H<҈Ҷ]3VΤgZ̮QxLnώu8G{.W񾛺^r(Q=k/ίT4$7w Zőy%N"|J7$,h gQ-Cy dI5Fd^+\3xƣx$_H0ǚEskueTfKVn$"%T vAJ7?'ٚz6[ŭoUvL$oHȟOfK.ϳzmv"sxl{cK[!׌RzZng'h`1#6J+Y那} XH]ZyAI_4 {R¼M`JJ" yV4^8x*\xHJ;QcQR@4LfOEҜV[cZ]!vBM跥wMx;HA߭DJc(N&7^#ms SxRZX,;Eߤn"5`U(ŋVm sOu-Fk N_?/OAK##-'~ؔ&F+J}xAtkۯpv&Y'LQ5J`@|ӊ5k֬\ZJKH|JVU#,% 9m Hsd`Шh}ʕ. Jl4J9mfaȖN}#qN־hZ?#PSfvjۉ:i˜7Hi*_7V:EtysFccŷ~fŊ̥E׉H AH)M V6[rW59nLaҥ.Eߨx500p3]A4VYUyM;*,ɖN]#YsViZrwCTkEZ<3ɛ##ׇ:WWM"|AO4h"}8p!I K[3`/>PQ,v֋:K3m*|C'qM9sFɠLhkIq;dAV 8J>364tZTZ2z{eݤ]YWxFoUTwǬN >\,KC_(XTJDhdH.~JIƒICbziKZL˗Y늊^4JSmi2$ ;Sd˿ݚSoVki~l)4Sۜtv(m-M te%ɵLڹFinz@4JPTZSK2eQɕ?j)Ƴ_S#GJy\Ee`ñ$9EMl4~m0-^A^bon)"+*4gN[u*RyCiɚiP&-iو4װ;v; }}jjuNw}uebRxT|HwV=+]tݕ6w^i  _XKG4JRQش\=Č*m^& }+wV=G$YvaK`wsM18 wdi^g鎹s9,>3SDmWQsڪo I%9;]X!5 n)Mk1-PFΦIOoWqWkEiﴜ+TLgM_xFfPTҒЮ.ҏzG OY?Kh^^&ZzϜqd-Of#9"zsEp]L =ymxeJsܟpJڮ^^UJJ҂4ҠB~MA~J3Y&sZiÌ*M qJmvgqTliIirfʇIܺզb#cVⴾO9{ Z$dKk1e>ZOӳ+_dbte`0!LP;frx rYV;5y,WKA:!ݶwJĖ.4᫯-5;GtPGN#_s+e\b=qxc++M~Z+;]QS^? {VӠLW*qX-W؜dh_U?U;sr;=/K~o)i\g*n6ndY:F*z̴prtJ餷y _b#5ZAijt/j՗͗{ ɕQLjR1;+<- єf^|^%J!)Ms{E:0/ۯ|dnujdDLtg<=;ߊr%okȕ̌˗8dms\rmZpZV+ՖOirS|I ֯MjviIheJ˺R(;7Yٯs=W)]U)nĤS5yiq2@'cY:&"m{:㡭eai抌>?SCf}ħҪq0yG{^5@tvk٪uʕcMMtʍyy9j`~/fe2~ƹsZ9w"vdrF}Qt:=$zF^_x *:]r]e(>)кFNR}ƅjs-F+ɴb-MIe <7'(Ͷ;WJoF4yXVZ5*#mt4Ez$͡R_i*5D:o4\|' QZ?Fi(_=u}P%]ͪ?_WWYmϫJ j 9KLîsZ${\ڰ%>Pbw 7UظQUx7Ѡ3%Nrhji8u;'6*E B4Nwom6j4*BX%%鮯軥64ZRJwsmMV++ ߷uZ&7/(@Ww*[H_ֹz0D@i0g<$}㇆9(?K4[&􏘆[8?K,y̓{822bN_rqT( J>Ť*RBi( q-MDP8S5PƊF͠&2@XJCi@i4P@i43Ci\3.di( 4P( PJ( J05J8fqA KCi@i429 A+ _`§4M$; aVzW& 8K{L ({LKtm/ K/>=}Z PD?@i4P@iOMi\:3>N 4@i4P@i( 4P( ( `}q, JJCi@iFi\3.di( 4PDcQ4'@iP :( 4 4 YJ( J0Qʲ ,@iJ 4t*i3Y4^o]9(,-JBPt$), PK@iC W4<QqvLUY( @ؔFp$wBka? PDҖAl,@iqJ $ph#@@-YJdi"J0sƟїGAd Ҹ}BY`&+=J(  |JsrSh 0`јÁc>44qA4A|2@J@i4@i4S4.i4P( yJGׁрҷ‘PY@iPzҔC0>!@J@iurB( "^uPpNA+}LA ,@iJ/$HX5q0]2/VK, "ƃl_d-c!Z{n)C,ҷ1PY@iJ( JJj8f q, JJCi@iFi\3.di( 􌺳xAhd,FCidiQK(  J!fq KCi@i4P@i4PQ4 Yzf(w>hm0 K(ZRJgY˪Bka? DׅX`+`J/<G7A+]N ,@iJhXī&M tm -`YDz.[\V&Y X OC ( J( J"q5|L8> Fѥ4jiuP( 4PJhS34@JD\TC*Mg9<+4\{Uq\&~}JGFR C鰭:9f@iAps1\Ԇm j$w0e/\Wq: ؍q)-a8`߹&:ׅMiK05gP867XnKiõp }/lJ']+S%y氌ą .RZFs1Lk_ 9&[j?).ȍfiOزڰ ɴPRƊ8UP%ud/c-K1Z6\4Ű,mikB_\_1S+׌Gں0siKareAJ sذaC*(J' ,OJ+%Β(J%8y-JG҃DGďPJZc#VitO ppt*=Xs$K{[]сґpP7,x&Vr@iƤ%"D<y"( 4P( (lBKcBAEtv@u,( BSZJ(  JIAJ'4Bi0.w9iSZ΀u*]tdQ;8>}Ni8n w/ҍ|O[ Jp(Yb/bfulsm\l5oZhV=NDi??OV!-y!XOHt@i0YJgŒK_,>l87M@nܦl2uEPLTi IvpfȹE|<1+[\ӄji[-:U_>LZ&?mK6lF(mWD{ieYuBtڢN[quU6ӗ;rh4ȇKIENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-debuglog.png000644 001750 001750 00000021026 11544160206 024165 0ustar00synthsynth000000 000000 PNG  IHDRPLTE¿֨آٛӔՑԏюύʛvuuBȃ}|yutf`{]wXtgr^lViPmKjFgEeCbDcEcP]N[MZKZKZ>[tz ZWhanhM CC8+>{ֻT<|[{',>#D?Ze|֘ڬUޢ(ts1tĖm֓+,7sXf&, aK rB0_, _Ba<>ݳ },WaϽ{Iy25:'K<&{ȟ{c\%>ysysy.WzWNJq[՗ e(/1[cO oga-+y]޽% ޗ>v2V#ߓoVɥҢ^d|H1Ŗˬ @b?o_d˥#w;W%J+6r>9R%?s,QjxgVxPL½mF㚹\/:ӷF[8Z exq`듖0+^:GD#Z&~\ "Ie k-xy#wM'"[}@K~>f_O.B| / GL#tsϭ3:˕>۞ 3޽S:'߄~BNé-hإ񭭅oOS>D_,k^xx \O[GW/N"v$nU,` JCi4w4h(=T_-EtJPRJ>JSu}zF{WTi~׶~88]DiG*(KiNApINT7H ȐMCi(m12cSܰ'*)f%ACe<pT m}AQ*4 AyU5?<'6^vb%oR YJA[+M^:w#T8@*~o=ud-c{U=˫(gys_&[[ӟ84;DvSg:Gti™_uڕqqG<st~^#`R}JћB+¾JQyUN?NJ{>j땂#;x tBcW:(M4W/irm{i4yU/08~ϒބBw/=LǘwXP:&/.oZ`#)kҶR=mӗcR'6^ ֟߯YÖKa(ݰ_cj`$Wt?٦=umv9+AvE7(>EV= (^մϵ#Ol)řc߁v`WMNxdٟ_iwRaxl(Oa)7zPҼǐysMM?Rv%RXBQ$ߨ(i(Jw<\7BJ㷇ޔ$THCiPJJ( 4PJTz49Sܤ 9SV`^p@i@i4P@i4P( Ʒb@MSJ;1V>Z pA>d;kت:ak*dUJCi( 4JCi.*8m9.( [鑶^ʟ.OmM%V*T nQ|UW/JPJL^aTR\nQkJTUiX QQe=t҆m|=yC N+JRqJPOb)G"m`,ne*kPKBWjPѕ5pyMS]LgehRe,<ºl[PSP+݂)(][uVYiALJoiX$i: ] (K'l%| (*S3(jw<&)-_^a{jt"IN vfҵGFi+- *QrXx$uP,Ht5ttw Fm\BQ)F BFxSF - !߮z +]#SzT (]j J5P^&PЕwtYN}LH~]T{V Ӯ|AI{ٳҥLm'YfvtLՙ՝+/l% 8o|xۏ-GH3'klvM"kgv2?S^7K/?w>O$%g_s[٥}444Ity&׹3ثZS@$$i:yΎLphUm[=FŔ^.ڂ[Iׯ9[P&ι.88ڣlKhee%쏬k{m<'{}q>Z5zhq"S %ޤ,MCDu[k5ғHJ^AJ61ްQ;һeZ|oU QKff ONh؁cړYu1u${o5l&Е{]򭓷&ctj9c)KfY䕓's.|Ys;N׍尶X\FvlF⊹ꮌcX/MmJ$Qn2i5D֔>| +=FGg= $)mcL*8-vە>.z̪4Oe%c&OXғ~]~dr#B!9#d6O3nO ONrkeKalRNط=Tڼk;̦mQ#_:HW= ^/JjZγf[NuI=VS6o.-TK1e,% g?d)~joVڪ0GlrV踶Qqsz0#+.m)FalͿaVb~uҺ{Ie3XgtZUz*#E&A~ ~/t+mJ,k8QP ڭH5J૖m2h7X^?u]_`ޭ*}Jqr_uް(s,Y] 2jd؆z 6 GVšqVb`ɫ(],x4R<;wm%f*Tr&%$o\ʫ4*GuQ}憦thw~INkKee~ǃ+Җ/PbvM|mw(oAiPsJQ-F` >/PPna!n,1c+:p1{u2PC=l{cT*1,mcb?;88cCM=dcYZ 7yPV{H60RQc$%'ڔú{8({+0O;=wdt(M뤕>l4ZKP}*M.[CQKX^';)4 ΕPzVW?E)MӖPҹkvsKl*.}J[f"tk?x+WgyݍtJoU/-㏓n1iX=[^K+-N[Vb}t]{LfyҖjm4H;Z:S|;FfoҰrWSe#-V_Jgv)v7gҰ + 4PJCi( 4PJ(͕vT( k@iLKiL KCJCi( 4PJ( PJCi( 4PJ!( 40( JCi4xàt* j(]'? G=#>ٱgDS4**TmUe[u9 !Qk[|q{f?\tOz^P2wPi4}mK ՉZC9j(G̚Bt]F]5~/>A>5jʙOk2,''@0 >>LDB[и驄FU 64郧O{}*[{GN}0yLvOs23?]!S9=ão'ѴЪ*&ЊZC "s+J,ҥSv?c1+2#%|sOx}˶c|~fwϔ>}bw 3xS+G}¾?} <!?|}6aQO'ѧ~&c񷏟k *v},^7-.Y|C68N)45ШV5Ϋb_H_XԮ #֩'_G-{OoɿGϟ31{Ov91 w} O K#ܓ,+[3x3xD䁿Ů^obm,suJPrCr/.v^'֩DzsW#F_>/zĽxv~-}gepK5O&g_춹BB"Poˑ4o\X٭Sd1=b5Gݽ/N<xԃ̽OY_q_N|XHX)'zxҝŽB> RhMF%T]S@THߴ=u꾢l|=$ݿ?rܓOY|POO=` <'d|`Ķo}zZ vqO3B933[ۢ{]\|3Niћ7*i *#=m:ɦ/iћS4H_h :wr1@(G:뤭Sy:Lc,CѨ.iX^אHC/BDHH4DHH4DHN 7nġ+А^VIĭ u(ʬ8!%~Yl-i!K*RgI ;bRMU/M۰֠UUn>]1oH+6tHVNЭ ҫ/l3i՛;o(Xi~\(C|&~sy+eچjyd謄 d AZeu2 v$) oZڥ+l8WV rjFScTӹ-SD9_Ny.yi{^ʣT[ sfj[CZZ;ʋ7}1_Y&B@5{s C~l^vZķcb+I?__i҂R\%98EHH4DHi&i&| }DzY/ICikЯ"aARFC#]\zK.]pA_[^}CiQYc|3֜ٲ\?8#0rAWGVH9P 'B$,wG[<#u1L T"-;mقϮ] 0!DlY0gаOo+DHs\-Y_Te7e}̍ٹãڳLEYg 2_~ͲIIh窅_JD-G @@cO?YHHmoN![)o ׃Y+3ۊe4)g7ҟ]O>߮{Xi؎H[rFey#3id \ Jt ٳ6GIW>BF'ΝxAaq*Ѥ膃\^M1-g)w+ ˗/_XR{^Jg㢜helBDjM`^8!RLVZrL)JkxFz#}oȻ}r+*?>{K0lq<j1 H t:Y3\so* 1V]uDZSSg<|J*|~_2HG?J*&9I4˂]} i+"f{G,f*FuD-ϰ]z; 䄴Z /xF`w[.G =c7!-Ą'͎H냟;9Y.0$j\EX Ns.MO_yЊeeҗԁgѸ D3okʡs"gN󈚊4]4 *3]D H{.KSOcbݓm4_xbɗ&_cב1}}ˉixKre+gɘsviv)+Ktj*ӗր>{V+LHu++_iHG&L}Ȉ|mN-^uL4X}:#b[h:" {?eD1x/],Z}.F{^x4\:ew9ӌh[#]4l'&^?Sʹ1#|imH^fݐ[$f_ hr}3;Ӛ~ƨ`2YoߚJRAee{y/^SSёޖ}wލ҈-򝨣μ?m{OHio 9SNn vt<3v,fA6 Hs?i?hBŶ*f=}i~xϪOcX+HŤF4nB{GY'#b7~ytxܿmHsw9;[ՈJ+L[oE*?H`b?ؚ u!2fL,V[`6UAbV+m@Vzccw~C~x<3ɡ:q|`(&CTxaYak$t=}iD,:+Sw=uG;-$7w.V$ya~#oj[/^9YVjL߽}im]Zio~V+Ooc9RүUL[$Q5ܮjۖɉHDW[7ۥxRm}kYm i  d_;oY.KFo'&=?/-$kVY e `o(ovVJg ]!#|/~Q7#D2S9k{ȗHkn,ƒК Qntgͬi W Fݐ[e[J$':ҜϸDHcɛj,Jc8oZ/3ꞱVڳKk@G-e],(ױz̍v.9N-Hc.SdjcccŎtRztxxHɍ0p)dTܹ/w_OhdJXW0BᵭEFǛ,]Pi}sb_uTN}Yjr9;&}<o+Ѻ,3ŗf5O+bY69]ZNIl4ў<7&K,߾H$USo}}O# `ү_l[ofzz*</S_VZN(δJO\g'&r,۴r. yCLpњWmC7G^˧^GJ7XiHo]_V扫}_Wc!mI+>:غRa_<2N@3EzٝRӊ44H|ii4iiP"9j$ЋL'i!M"$!M"$!M"I$BD"I$BD"I4DHH4DHH4&i&i&$!M" _Ii \4it&$!M"$!M"$BD"I$BD"I!qJC Yr%;;%\)%^:.#RB5yuMɛOHҤm-&y̗IQlė_qc1y?.*Tt޲&书T"BL)ojHҷ625#w!mA:_ms)ޟ8FaYǒ4>+7gؗ*(IԸF)#wp u鵜-l < *)3S{$,(QW\|p| .0Ǣ$*DL;v(}~}zHaTb{@'*f3JVU?Gێ4ֺtJR~ZiL\^AZOIm$_*U+;UN ^.5:T,,H0M+Y͝_ìiS)"t\+KQؘO.%q\i>)bE%N Fm 0V&+[O#([Yri慈,%6Fe` e9s=X!8f*}*aMV*L^"LOH~IBZ:tX׎ ;iGzX(#q1dN$\˩aF+=-Xx7qegfpIN0׃}]YBeI.+%R-wFItT>/&R%bC:ScHo.3]5!=Aysr)wNwv_zCb%sq_Im( q}I[Ϭ?} o4)d;|s8F iH";F۟fq0!xl JiG/0!exAbQK8.*}\:ʯi%䴤TMpiL9/&Ҭ*7wfyfפZ❆$pWLHq%x*]i^ۢ77* `^g!Bwyu%0?KRfu1~1NkZ"dԆQRLEsH#4d٭Z5_^vTL,҄?>,-/eoLUm<jӓؐ?gJ9Vf{3PKi)iZ<]<!ҡU "ݣCToG!!M:!H+~?OA!_gPdկ׃{6ȦC"֜AK˲iR`5&:+~/=qC뺁4!VV͛8].MT^ a$45eK`/f{k& 5]$]K i_Y*^H7EuECpqݘ/Xu1XC=%ߣ ϟ/!t=1 ɢ5>>kÉRPrBEtv4c"^65H&\M`z!ZQ j:?ؑFW"Ѷ~?n6yb&n7.x"m_G;?9\tR6U#MvV\3w.q'Sp9B)Xi\7H7GzHHwi}n #ңa4tttiCZ65͈" Ҿ„4 җaBCm%!="HE3]ElF5 2ݹ/=&݆)rv<EâBC+RxLo6a1:H!lF/q N(#c!$n[1}?dV@vߺH7{4 3#|8myK#̗-E9LHnn=mm;HCvޣgO"G-->Í4]E€t,"M!'ÉJHi hTK[NB/npt`_[ i=ͮ ki {x i?A z?HcÊt@IH`HFH7zti!88ҁ@ HCGHwFVi#֞!È4#tFIH{"IǼLHEB4!=ZHi@ yo Ҿ4~@ .oC{]A.^=KwFv?#H7t3HCgHN"ik!=5/-&, #sְvn bƊ46 #|fǰ!-  ":tф!ݛΥ {\B: H 7Ev!E9jHdrH2`\"mlΑnMtWv)TȐvTKPv #]Ãt҄tn 5u# AZ~x80H!MHwp# ɳp# +-ҝ!4iA)^! Coȗ`-;i8YHCoZ _Z8% \B4BHt:ۍ4t?MBdmW[ٺ$+k 0-obce6֦;l|q5BH㺊tΦskznV b%o˹l+K9,\a!T QA:~Wua@ÆRqBlh }͙le5ύ]yT.3^mp‘^.Ce`IO,BHQhRF^Y1 ixlJ.ja.ngX$2'`%Ƿݑj&KBH_,Tu_B<[kưGG:_7<i%# _Y&z LDHwi@驴ӑ>]auWe83lѐJjH$%3K0#9/TpN!W]ZqBifjv |+b^$`?<&Dbe\(VaT n) Z'ǝ3Fޠ'4&i&i&tDH4DHH44u\ILg}wQrΒ4H#bϔ*oG+E*bϬb06Di/=bmH{e>ҙkFsV[: ^Y_랄tHn!=`x GR aЁj/jrVq?`g/ђ8w\>KFj x_ؔIZa>8SŌВW`YT]$ i }:^m H>.E`|Uv0ŷO]3`OHo޺y\Ԓn@#]Ԏ 1XF$JZbqy'n1YNL%N 4Fa+Ť}ZD5yL!݈.2ꡑD^N+ņPL-|"‡ND^h{ݳ$+=v9U4!>ʎEd+HdSF4U F9ULY}i!k5[8FVgbj1>$2މ%owϒt"f93қLW]DC:ښi!k599 Hkg֒8-zAxڢ뎇{F|y^Q(oK,\6672[4Ο퓹+*C_e\RS {yޞDFZNm ʄ WXj[H[mYNX0WN7l)1_^3H_Y,hUUeK$6RSUr(4 YkIHEo%wllOjx:Z܎-K BGKtH#tyu B :BHO4bЄ0T)iBz(Z5 Ţ42tH ݝΥ4G;4!=-4,҄WiΔ@HCyj̑5;LMX4)IJR=TgJFވBzvmIn!-)SKfX LelWLhθP3Bj7aK8lz_ K>^hoFi26^6x4GYvo4Ɍ@V$PK #)t26!-v?E_5z=A!_N-Hπsi[}bE4ԽѸ*r5:A4a[fv=OiqFb6  KG{QF(`_?9cT uѲ:z0yCNZLG쀎cH S\t4oH8'|09v-Vnx:cƵF>:BژPHt TJK1V'|U];:Fo 9IyY5f#t,aŒtοRg`o:tO_vi]:ۥzlvTn ͮԋyZP+rXR'|Ijkwk6F6z='I4DHH4DHH4#B"I$BD"IA }|Nb:`h{Cs|T'|=^Q-R~oZ+DAzc1y?H{e>ҙkEasV[: ^ٷ_"랄tZ71N\5H$ 20QW\mB*,\LU;Z ۇyiHm=ג rP4iC :XxQZ,g0 4B Oǫ 0!G%Q,5 vkq [7Z HpKゑQ!葽L1\A[V+~TY\b:./,-1q3[(#T^@cTfIYLڧET40ҍKOR.X=4WȫCJp'+|H䅖g;[H[˩ M,WvLb\A 3rQjHo0ͩbɗWSjdxFV Y6&^4- cϸwBLReHC!UAaum~@z`EDZImi!{599 Hkgݳג9-zAxڢ뎇wQFz#^/7%Q.[_-HYIρՕTSc2 {E K[<LFZNm ʄW Yk[H[mْNߕZpt3E̗׌F<3ת} 'lrD=YAa8bMkɜHEo%wl젅Ojx:Z܎-[WQ63RZ<GO]HtHOJtHxX>:A'E4$R?K5eQD||lUgCԉ]Si5`J]S_nԅmB: mK H:}i(gj#BkCFAiVBkFkbܗ6^ eX=A$ac?3x)& ݇_@[YO})δz>"MT%nC})㟲,Մt iugΠH([)CՄt7Z<!BmHFKzH[ZҔo}7C5>6؝K#0V+289z>JH`@uZw5p4v?=Cm?VlK@ګ> #m\@oxơAڟfGF!NZi p4ѩyy%ZvD?N=98nijв C c%и-! @=F&hq40VZ/m@3r+Pg_cWƶt{}P m4PkT69BmH.H^@/mZDGWCZoҾ|}d^P[F!)qNjFh dV޶>TԑF]MrDZy#fԆ_YՈgll5ZAܐF"&?4AQh'G I(b'Z09W{\ֶZO7BLwH+rpFWiui <'^ OD8%& /`o5EdoH W a@P:mv ]z ԹTkY$ mT˜z耴4Y~/L0-.qSҷ.҄ҖAlCEh6 c살pɀC kA/M:~X+֯m}|>'G脴a {m :vc 踇W+ӝm N  ҝ#&|&ha M94lYH<麹 mH +|1hCc0bc!m@bhGܐHHAZN=c*4Fw]A# 'iaic1KvDgZ[!TuP5ic!!HOaHC8v;qq0b''in#-2p@4}icI| yiPiaMic!!4x! -*{s hCu!!K y! VӪt1mޔNDm\/%4<G@w4F=clϐBd4# NHI;H{7!MiGi4t44 L~˓Hc,D Hc(6AFZ&z4 1H;yg H3Sϐ&`;a-v,G]f,'/?mNNH~@<iɞPl6Oi06X;ĥ\ H 悴8z(~K B#HP쟂8:J;  *ՒtϑVHC -#!Z`<%Wr @-!=@胿6eH isj_

    /)>gMQ|O kB]3ztFl9.+{r Q=ԦBU@c==Bvrލ,5#GgĖcO8<ҁ hUӗч,5#GgĖcO8+ hǣYkF@Έ-ޟ|qy79Uч,5#GgĖcO8>ҾTjz{<δ٫3b˱'Ȓ6WMԿ,WȱwYٳ}^Sf+M"N4$ 4vIItSU;tH #I\yʂdy)!=H4!@:;%.W*<ʐ?%0k\UNuyU 7"f`A%G"4W"Wː@優HqϬ Rj*6;u2ū0tP 0XqؑjIm/̰c)-TB: HdKLp G:˨ϢHؑǕ|҉:[fWTQEx@HM(HIit瀎)!a\(Z_J~OΠjŅJ^r@~M:toѧV>jk>Bz^_Tצ 7xM" ,HHC/QiEHi&i+H%9"N~EH!BHiBDHҤ#x)DHҤe,#Ck&ie ܺd|5><\)4M~x#}ʘHUfWG!MҘ[M;nBVn6ݐnt4s{rzj~kRW+Z-lҤn!}:Zf%yu'W]/GR6KF7c61]1VUOV/&_FYftx&u43(Ս*ƣ;h6J ;Z*Ib#__ssXn3ZːAꚕfʫ!UZ*[l8'䗑k!M"\Bf@z; rCZK+#-Y5,ҋ,j+ߨRMocj B-]NDSk7:j`u 5Y5~6^eQsRn&u8t4QFJbLMVoG< ҤN<G i!OҤQBz-%I#xD iRHo'y"}-IagZzY3MzL`¯-Y䈐@Nr4ieDshuwIVDF4D~0r\5IENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-fittedline.png000644 001750 001750 00000026725 11544160206 024537 0ustar00synthsynth000000 000000 PNG  IHDRYPLTE!* Xh=kGjHhFgEeDeDcCcCa?]=Z>YH^J^BW8S([3L6Jy1Eu/Bo,>i(:j)=g'H^8;@U$jlnnB{U}PoPnPmSkYmZqWsXtZv\w^y_zb}dflpnqrtwz{|āǃʆ̌ώѐґԒՔՕ~\oޢۢ٢٥Яĩл- ȇI`٬t~仅ǐЛѨҳҿýͯzuvxhhh___]]][][[[[WXXpVFQQQNNNDDD=>=$@>??:<345000***@QJs7 t5.tRNS.$*IDATxsGCBr%'8 THxI;&$ld{d/+;T6nH&'[Y^Bž$* b0.*-*NU6Yd\A~ebKk }{^43ɒm~ŗg> x\ -h cXE7:CXS,PVJ^ #H=2Gҿw7n.x4!BL ] FeʐnD/4C]kM/?){Fl~!TcK-ed"g~S_{U݊!BL.\ D7p;xv-Vz?b}׉?O4][qy͋ի)†dU\ݸ:+WoYU?f=+ۯvjxgſd2~w2oE66u?'dUY.rzk͓Sٰ䦧e4*[\ĸ}mgL N(k7Ǯ25l*m-M[m{aGG֜r74ذVV֍Om="6XUݰqVZIؖfa iTaGcycxayQݸ\1x4[u~-O(DHK&RѓKʖy{SWsّ>h5}Y~PaEܚ,rۓv uƦ cTnMc[ I/urkʐY<AyW5YlQEAAE.k*4!HC A@;W`G\pTdo 7zд+{8e5|}Gzu8S2qd[Upģ}Ġh=~FNr.P#7 L;qhx_z(ڣ)s8udW>#^aszg?* Bߐio mH1 G%awKu/ɥMN5ZB#AMoR|﯈PH|Cn/brKa?}SEMEW|o(=F/VH=}\3.OM<.MrXp|1o~wUM6ǽI&܉ֱF|!9 E: + u@_;=~̴7/80(Gң\&]K}CKʥ|oJMS+jF9ÐKꔌǥa#DŽcZu: QYHO(  +b؛C^I'_$, G^}]! DŽ4HHzFR1;G ȍKTvAjs6Uƣvz'Wuթ~ƥY%U%]q#ҦI )Țߒoe\:lZWZ# A^nljnڶ%oJB, 7Gb8^.}Qfxxx,KW F>#<JҾ oE۪ى.HM NW< .́)K> KV6ɥ쒶0={j,VSR2>fJ<=ZM]٠˄5Һ\:hDMaiߟ(З۷o6#})BҚC7777M<844Y#r;cůydo,WZ1 ͰPi"G̴Lͧi\.iU̟sn; +Jt.i '齟dt钒t,ָi].vB Hklt<:I 4';+*upw}_Q@7llF:<~8KM|VHu8#iLja"EG?AZr%%nir.+H%c{28ASi+^,e6'&̠),2`ry-4L\ȈLڞOS'%.sְ*v 0V096c.2w;V 'KWEӄڈt#4]p`ZuJ-YmN?Czu&>t͛U^D߼y(%W|s6vQ _.~H^zlFJDuJl]L>CUyRzXkA+FZT&, gp)! i4i:`D%cH%Ҕ iF 'D2Y3ө$Ȑh\r!ҥisA*bH"dKYNJb$;o|^B<'ha>?^yeo{siaa)t1"Ǫ~NJ;/ߪa 38^~d'EU: I;V49:(T6M ZxHLo'B97۴X(0Saݖ!~Öȭ1 ‰$fģj9ss؍9Kh&״"md:m.-+T¡!_ C>BTXx׾fh5G;Wwɓ{VkgtQ~H~=W3A~NB9b+t ]ɦ]&&907K .K Ŭ\|{>keҳd]Ĕxd1!N%3605W<& iC,ۗZDfii={(s왮pB̕F>FƜ$ozS$GsX?%!)`t+ti[ZU:0VhEׁ7w gW.6mDڠNtwvH m'k{NY$YT,_6$PQU1ƥޚ 鴹4Ww+**h.M5ԐwMz;@vRmB4XGj *6yJGuuXshwc27g!}2VQ}/a_iO0~=8ӣ1_H'o ֥\ ~J՝u^r~]z\Py]윆\zfx,<6h!VĂ}\ ToTHriKCPH: %҅xTGC64i!HC@4i! A@4i A@4iHCG6HTҐtHC@4BҐ-! pҡ#d9@:IAņt '*tI v]Cj%mT>THKuK"6E=q6Qm?@4ހ56mPx(6KCiMlh5AEH ۢĸDcgX=/ iCLiZ|+v%8<@Hi9 } [vS4x<ЗN5Ay9/xW44!HC i iTHcAa 4!HC i }HC. وGsx`I!d31HX@*F'@Ð0Di(4\א4dc&4Hc=ӗ76H*6&=Q# m3?O}9PM>;g}3KCZpq[ۉKSD.$fbR/+ihHI,ltKҐm @U!ihH2 bi~ʹ^]T2cݙܧ0ˠL$hi@E +r 4dDS9^D!C A/dIENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-tutorial-gyro-multiple.png000644 001750 001750 00000046230 11544160206 027053 0ustar00synthsynth000000 000000 PNG  IHDRM+bPLTE9׮ԟ݃HFɄ亅}جwˠnȒT" ˤ #xCn~¯߫в¾ÿۢڞڀd֑ԏҋυʀ}{wsnlj~c~_{\wXuPoSnVlHeCcDcEeFfGh2_a+Z=ZG^CX9S&Z4J{MYtorkkkfff^c^\]\[\[ZZZWXWTTTQRQQjQMNMF[FEEE0Bi*q|L 0s%ST`8~ۼLL&H‘!Z.SgwOjӳfv4=3o~R!dh,K+Pz2ԭitwݰy?vk߂@˸s /nmnFi׬Ya-[mѝc#;=]c;TI{qN8/]m/.oy`:]Mbqyٺu^KߺH{~Bw@k ڏ):i+Ih,}+Et{8."ֿD 5Y~{YNc[נS'5#oItX TVG Fsk*bnM/Ez9Rq8~F/ҥE7k$X]'moDBL_:F.[4rD4:Dŭhk+EzFItE4}e+ᕟ~l9y׿ֹ>x5z1h¢hФ'z'è!v)ҳp'3Vw<2oM8dx / w٤qm_3i4mVBe}Uu^>mM>A=M~߱p>mX=Ϟ>9~_zyiqstwOgq8]|qX]-M~.>to`QՂSdq٤MR?y9ߡ:<~_L}gNˉd{-/+$Ir %G^ye!H'q8ƯZ)x[gś/p-3߹lbjhm}~\tHߺK\ٝOzsk89;:}vvӂW]׉q9^|~GS']mvXDϦH߶Ko[:ѹsysgΝ;?Kw=ictaM}Hv9{=[4śe,xʼnWaQ¨rJ!SUxCxū겜2Rnorz%ů` 2Ry(p]XVe꼜e9el>Ab1] P]t { @A @A @4޷'d)],}j4)&Va *isVUz5dXt;'3 8DĔ{gڝ_'p& bQQPg@:Hҫ?nB{Mlܻe([*d&IT>2g}]>IH&ۛEbmހt mYd..ޱDְ);Db|3\wZ5Cвğ9SZ)&hX~lyH6Ƽm>=?p`(2@u;C+D[ɉܣ2c۳n+H=8'A:kJf)ֵ9voZewڷ'NJA[92OG#;i3Z۵if"k}e$˵Gvoe6rh8ilq~, VH[1ǮBKYH/ζy|XOAz7`Y8!hyl/ZtbE)ϏgG6ۊYý;{.',=>e:V;VecaV[1Ǯ V+V:2>JbEވvĖ]BU;Nev؝?D-&weH6bM;=-&D{=p3>IfW1{[9cbßːbx)+H\|"1 ^MM݂lڄu1fU8KDbBubwlb'Riۗ&gݾ}27 ؾ1'4] u~@"NmЎӉX+F޽Cq+=L}$\v2_:CV'j gVeP]HY&ɵF<۵yth3Bj_|ȑ B7Q9@[c9O $_X)iJtz9.\φ_VrzY?{оn?sFx55*O1@ϙ-G:i2ap…Iit'DϮ~Ϧ19 Ii7(Xi} ',qfBz`tI"'A#R]G#?:"Vћ_vDyײ|'"ȱ͵r4Kxg"}bD6L5gێഥbkLVJ }j.-󺻻*lZ\rE/`G~HC?ۍVn,Ңl˴7qLu1pVx#ɨ SEv)XG~f3)&߼%9.8|̂as$iT@:V6Ҍ/r^HtַH @7[D?~ƒSzdH;z֬3:4dyE#k|}W?""GOͳpHSl$>4 cɑrsT8j}Ij;hdH[ *wJʴ͛29@8#iH+*C L >WXJKSg̚s˭ Cx r [tum#7ahB&[?l*EzI߮]j"M0ML r/y忨z :&@wtԯ FH"L~:Ӈ_CI{VU4E-t6"l+MR_Dɭ׮]LpNE&Dc1& >-I4q+l +G-3b<4H]QC$my򿛻DI=q8F(tTQ L-`&HT\ .J:HT iM+}x$8,E}i3Um?_Y@:Laή 5>)>h#>x[7w~gő0<#}"ӔZG0(Gza[LK8Z8f44ɑ(tGyHǞȑS=w$A/)D_#M$WL2@a/Mx 0HKNR[o;~it²Iѣ$H\k]ӓ2-̙$ -ӼH?tE<:#WG;GHLxxdLj 7ns4eῩ;-3m-8p#?zK[z<9bA&#jW6҃XeV)--vF$û.:jn}Ҙ˗>dNA|SDzZsSFܷ籞&cގ5)`o6 ޯ Ռ]|k筴tﲘ>zǶ#Nhy.ԯXh VZ^3-:}v)ѵBC_Rf %wC/ݹO/~->jR7S>I񰏔:!]/mL*`&6yCKԇ8=s5Ķ֭ywUϊ"$Fl MH .[vϣcw_ Dwʟq#M /222B%QE| ;5FZ.q(FF&-q@mR9H.iJsT""_]5BND;cD+_XGF˷E{=* 4>i-"Kټ xo+LxK{ISDO{$sG6j/b!dKw2ԏّ<}32H'vؼi֭]{{|`RXcFf'kuG0bxJ\?/ƹY4) Z dr$b>#%GMK~i|vtD ֚]UdlHcg<Ԟ*\;>~n+[`*t隣Kʕ+hRi'K;h@)!^gV}, y%RF-6)h irEtG ,0^ i ?V4Ky?=kr)CեdP&"bKDs8N$_LΡ|n6 k_̗AKҠi   LM HNJN]iP(iA4H  \ A @A @A4H@4H@4ii     @A#}{HcHKi     A @R$*`w* &CZ N3֕A H[^$a2ޏxS2D_#.JFl0׌ $Px5/K_\ޏ"s2Llan>v1kD (=ܾD;AH\ NxE*!F PRt1ySF϶ *E6ʒUy.ۘ"+.;˥HB.@b'f)HWXPӨd )*.jtVq=UX`2* R3T57b-я 9E|<UJRJkKW\⁡t&]i!ҕd,NIW!Eqg!E'+-ť0]C)OVzL+B:* +ӕݥ%]H8HCNX ;HC+.uVbӡ":]aEzj^j! 1Q ɚJR:^z2+dK- ߡқ!]P\FBeSŐNct)+=Op2]U:fYMj@V4 i Hw)v49JtS t(ӥikӘH+KWR cqKK&YGiܐHOK s<8uZ5QOVV/]}NQ7(S)]Np\jATMQ ҷƳ ?1QJU"=844t((HHW:&\S&CZGLJ_~g<_2i uH+ۖt'@xzR)PVQX?]К&%HCs'7i: g: ͌\ȗ.&Ko5KHcZ/RK=UQЩa-/5xj!EtAq}2G qHitC{.ExEi:jxtZ\)*d[ iuz mȹWr}jtzYYF:M'hj6N<= MCr+]/'kxj<m~Q+z+/jMFa@;5Fqb2ӀtCSRNi@i4gY(mXR+]/=wZ\~W@x tà:TE5'WZEC']Ч<"U\mB.K &3nvoEQS+^kZdZ\$_ܤѥ6J" )i7j-cu5Tj $tJQ@'Me!6&Eڷnȍui(`—9ʑB!@H@Sik|oYz#QqY(ϓ=' (&$D KsnQQ#Qtys!c 2ԗ @ztq+Ϡ9x:d(BDM\&ΉDWghƶ`jH=/K`<4i>5qH'cN2dνC++iynV 5ҳNDܦMfG|$jⲐV'kNr^Q_I3D Gz>^f4n5H (ˈGy9QTgȎGy45-ɶRCfS Ώ߲G .+yDQ!;Jd38 j$@H@4H7HC ~Ds|+D?qs^(%@ΐFXHً'zf6Hңy6\($@ސޘt~$"Wg2? mzz8i2iHc/\i=hG|1{V4#v>]~b}M%}&_i] i] i]W^ҺZ#͇;uKgTЧi,<7onls#- iOIObV{g65K3Ri̚@ݑ\^Q`Tgp~to>.(+z1 ] Y 0򐖧3I=4Vi]( i?tUHˈ^R0+CZ|P -\41&îi %*ƘD/lAv۩e=iᵚҘg`p|o4-t1qHè#-#0zHEu_;Bn=0Wu7lu>YzeHKU;}yyҺ3g؞o_OKBXE1L~":U!}Fd:w^Q炕iH:?7j!]mF>/GYHUݗu7+ooXV4;"KN_H/C˃?H(Ҍc?S ҘJ$|ӭU!Ҝ3y B:i 4{i iq"]n:ǣ0Ŧ%芐.duP{]>"]8SgH9XiZBGHF;wKtҾXM/H{?"<*H U>a ;4w*CZ/i^mhKq"];4 ?in^ck!*>Pұ_ֽCRuH rH랔ruUHs}(Ɖi]̥E+>r1_i {x[ Ҿנo?ȍ.0^"zmKFZA!DZ41C:54+ג 9YHs1ʑeC7ttCtי.ltNN{q?j\jŷEU \D+xIƋ;! ơDHFxKWs3!-ݣspshki]=w(:d*p!\2I>xoX a~N-v(Hs0U?|4/JQ ekA _22{[ XTպo.>q$q/EH;qH3bn)RT4ƀt al4q]"]`őÉ4i6 r֕"]̥bJ4Lc#MlRu֥\X,ⷞ+ӽ *PcG_/P ?s >aҹHc#BXx}әޒ3ƎCbH녑ƀ4 17+y1tI^i_݁!-N5jH^jO_2ֽH3Eu, aғ|~c44תh*MsӥUMori&}"/SDOxőƁ#YKi H X43.neXi #ːii̞"]O1/KEӻ)>H vL 4g06VR}1%ځ~쒑f;AH뀴iq퐮`Ңrǘ2ǖkٮjʞT4^ٚ"]Fx2Wc:/Ni=H#M( 0&invxivAc͌/-i@{;G"qDdL|:C&BʀF~"]%HW7v2JWVH7 i\EGzrCε<W !'C׽"gJȓ.U@tIV w ]^tzMj> R[lG\bXmtJ!@KAEU`Ҟ?CgQFF lTtmdnlC6לl=v 7\*-OkKBZ>N>PJ HuxxFۋ_21S!FgO:mHY 4EZU:Lz @F=e'#SM HutɎ抨vcM#>%r)ҐKJ@9W4  @zH[w`Wa|C ܒDA\V:OB3伉fRCA M_yށ^5>5qYH+Γ o"i#mMncAZDI\Fkrky@#~Ůwм$A'jٔYfnX:NthZw9n :i+vlfx8ȹ1b#inxi6Ab~h8JoWĠyPI#~Ůeb(jP@HO&0ޑE DtWAi+v X*fbڨ.EAl¹iUYi+vNmo -x ҕ\p4 ]HxҀ'D5ҵA*_vtXk\44H XiwH4իvtkWGiP="V ^wHXiP]ZBwH¾hhF5XiwH6 + W_Ѷ^dҠEA?Nie3cya A`iP(4 _K &ս^Ze+ _+NH \+ _+LH VZ+M/ft iiP LGx-:q<O*fBҠőfF/ATC' MyiP" (XiԱҞ05 >tn?TV05 i@u<SӀJ{}B;`jPMLSӸH4zҸp?խa3GuҠ8]44( V}Vj_ДB`2TGѳ9`AE}int+ .*nRonXiPtqnK!a-c%*4gǣ0襖x{i J@ǣi3ӝy {󰄩iFiJҗ.4z<ʺҠ8~\24(VSӀJ{w4;`jP -;;`jP}8H~xw4 iNąfMJwF+o@B]k𥽃;&Ʈ"aZku8Hk%J 6Vei 3C65GlW]!%^=.@n$ZHkHu s*P'C)\h==$UiCfW.oHdpBڎ. 6=,Ks4nј"d8}C߇a\4Rqa#i-dHciHҭUXDͶ1h~²ߙ͚kzs7ui 2w4@pdVrÁ49Қxeo-BJ}q@ZcVaHc2;̪@C9ڋ\$MjqѸgKZ  ;מҔši ;i]w¤ɒ/Hk'襱l&uXV)%0Hx86%9J#05v]5_Lxk%]ߎ=k].̽\5<H[j\]LӸ0x1+c%({&59Ia1! `KB) R#4g[lScWLxĮʭ󖺣fl[걎asrI`[;,3"qNief=T=B[M=.sˎf4)i^_rcA,iy 1ŃӮgwqk&ʶғ̅zi~'f<(M㞾vIhb1qH˻۲U"=>5ӞkM޼GϳZγm7;\-56_ғ~Jo 93_Izߏ"fnsߎ;ziKSӒlK"t z|w)R,v9HIaMľBQiy1jI#]tX,B_x8LjKmHKZgl i%x?5hJIMN:uHɐּHK& [iUXNO&sO}GDM\pCy2?>CgvV4D 4}Ln=>瞢, Q[ItD5i1Qx Q!{D5i1[2(#Q<ٟQ!3;2dP^C8 PHiFiaۏz.Obch0n H ~<{Dt1ՌF:Cz4;F;\($@ސޘt~$Lb< ]wH?|mƉL+ ]HF釳N"PFt"=?;.{[CD&ҳJ/$C)4΍>~EFݭYp=iMY7@u.i!^4i|AbP¥ƅ@ȡED:RA!mHi@HҠ>QX H*B2"HJd m~sUi#McHt WO"}.4ßt WnҠ F|8o[-zlܾjVM8Kd HBz]]cO7$c{cNVD}6bO-U o׃OӚEsm7'<U41Bd'(%b&mY3hMU4Ü)O/FfұX]M~ґQglXUҩ.f|OoA>"=0`Ez,rbr{ZOm'A#qhDz>1H\|"XNc&NkD@MH|u<',tx>pvSU"/ZkeӠ@T5 j 5ҽb4 &z*9.,PIϦE@wHcYu@aWj2*S0&(zUAWmy#ȥH} j? DSJzym M_pˁ3IENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-zoomin.png000644 001750 001750 00000031610 11544160206 023710 0ustar00synthsynth000000 000000 PNG  IHDR PLTEw88SSDD42$"tz XC:@@>E(;e);f*=g-=i-An0Es1Gy6Jz5M5M.Q k] N h@ 0 m  ! #$$(((,,,///00111145467=9:>;;:>=6AA?BBFDDEEEFGGHIIIJJJNPNPYPQTQRSRSSSSSQnZ;a-b[MXXXXXXZ[[\[[\\[[][\`\]_]```eeeiiilllqsptyycq\lWlOdMaG\CVWUkl?x&a䧜ZSm1صM --Z.\nbx_bo^[liR\)RJY,6)QUbX1)s E+X a]1$GXPT|=?ݲ=Z+ckۈd֊zz$51ߍ&)?yoY!@;Uh۷ѾP(OA6\#ta =}?M0QZYjڵVKrωm ի^hDѸ\qĿм02W#t}|btBG8?`{4AQ'toVzq-Z^+( JzF!Kgڷ5p"h:2[Q#4ۮ}4q;ߐ3ۂ02d }ƫ(kCM q$7!h`GnGo;q ➑n;|ud6 Ց;m?}۶Hovqo VZl帶mO[u #CIF7k4ruh׺tB(l- O'-ҿmys\/\H4)~"C k $J֯oˍT*`M{"L%>z%q;l =ޅ^78oAJKmqveJo{'V^gT AL~pV ÊIFUIFy׊#Eu[.C30=}{ //nN7uo\čb#Uo9o ߻Rz}C+1+`JJ]⳿'A3EjIFiyvm4! -}+PMĹ `wM[9?aN^qqI[y%o`üĹTfsFVV*DVlL|Bnr`?_N]o/W(e ahtᚄ_zl/C刡PWWa(QE153e a-7Mc>tXk?G(b$Zn~#5 }`.ckv3jie aMA0$D Sb@FFhp_㉲#n"5)G<M9!=8>0cώ$Uɿ4mj\ 4ݸc Hŭ32kʺa?{j=+~%-)I@ZuFKO͏M_fg4y쁝`+gk4ۺ~Ks@&9\jn5 Ǒ-2H5[zΰ5]LrS`Y.h+YZn#سSZiѸѹ$A!yIh]2v*n&-RVSRޭZH6o߰H. gVDV5[Kg(^L*7-(kȨ\Qk+p~hwFuc4+H`kNJˋڍz[_Tk [isg0ϒ}:Mw*j#˚qlE/hwz2BiaYFOWe=_'% -(s$vE[],}*}tFO-'u0p6V\4ޣְy4.tJ3Zŗ,\&.ު+y}Nkuk˻ԃmgGaZ!,9_Z>CǺLa]}IQ^jaWhGs&1ڑ&0j֮kE}fl]%h7"MKnOJa/juR 5Akֶﻣ=͙u-'e3{l%jkY-(_ *>gdhO\I=EF-J:|IO],Ynb4gpɒse}wl#k ŧ3iP1s=K=^Lr-({aWݕKhk6yݵZ2:ʐ"קT 4ZeЊ}QR#9t91oQO=e+>۫{Nil)_k_R=h~\ܾqG F5$fk -rT+tCQܷZjs˖fPQ']\m玗&e󗋵򢡓,\#SҥuI6NF_|fYE϶v{dM=h3:*oܑQ͓t% 3Tz\µ|NQܗAh25 wM`CO8o`ƪuS_A5f~1${Mvш^lًb})̂h`4h`40F7[Xyx۬C69' bt_`4IG@bhbMmE)I)E Q[9IٳPt42iqΓ?~FO Fsoao2S\jxIm0iΕ/&7|mtR:K ~.`@N嘔Vjt}T"}hR TIȢeڌT&!̈́V LnBt!|E&dTN:'npvXἙRہVs%Ǐ?13]BChY,/yO3 5D]z dҹcrP }T7$`8B_h7?/R;Ԋ TgT4V2*םB3 5Zۃ^E7/6Es}3 *3 VσFJJZ,Y\gǖ2O?>;d>ӈĕR ^ ,v5W*{KnjW5;8堭eTscnMV6jGzb4ov~jݼqцo`8idq\ ]1ZG[>W_.W(5)c迵ˆ*\Κy&m}+;3k֬%~btC?^aƌ~3 S?x؊6FVV.v5u֫i*ׂ.F>S#-iV'F$`e`{?w3UZ2Zb/1d Y$cꞚunBFkh+ո2I<ƭUvyTᒸQeff3h-zf3q=VēӤVtFskLiօdh6*RlvuVUtLksyu23Z>@Fnr;>-TiHhMNΙѺ<?kܲV?}c>7-)3/تVz߁E v3g.n1od8 ܊b%kO3/J*5FYYڬĸ'ϵg^4v;gd6yyyJtLi5vas>;rngZ,&efYgy7xOg=8kL wě>ą̙33!酡+Y{+̈́҅J?1ujZgi+ȕ-i}c>SnsԪBQ9a|۰FhC8F SZ_UZKfZc*n.[4fnd4?/S2ZG>Es\(_.3_rF=zP`tO}O=Zi0iTnOF)qkC 31Kl3*d, h*+M0\[||}4QHL hUkQ1Ĺ^an4S|Z}*E{)m:xMD-gף=য়>gF|ϕ ?hӌ 홞w|x¶f s!ߧOOŜ-w߻rRiWgѵ~R_,\xHnE5V̙3;*g܁+[C6& Wr<Љs`Y!1 sC1+}aTZ:*{ǹuFg*l4Zt(/6=bt!Y~|Iz1ڕЌЋы]1zl.c-)}_ NY^ZiŖ/^JM Amф˽u1F*iH1|OIX:L:$hѥi}F/ b|&i?:z, }W4Fgx:"ҿ1?<|gDUictNkulYq(1ml*υbh *5^n/HqXW4 zuotm kC3ZqC2zSKϕuYX)3,X F]k |St<<|3Xs3/ܔEV\MSS>8tlh&+E+`F6B ,F=k7ݵ6Gyy_őoQ4c:H&`H]̳i EY %i T:1+TD 'jxŐuÄuJpkkE*w\S %/kYeYb׬%naB1ZG2t9С24Wr_YRۤ5{(;vjFÞUU,qm?sznyΜί1x"'|.^,>ђϾiYJGj JcfeSrlO.{qy /6fN§Nod((4.UrimFBwTbW|4@"yɅ6^ayjtqdʞY8FG>2h4jg_\Y>13l_ihC?i7 l'F8<_R|:rJ+tmzT?ꟶd&s|MztrkٯNzf|8!v,Vl1;,1٧q \諜cF/U({'i $8OcYyOw1:\.W|qWi>gSڤNcgaR梡}ϡvoo{eW5zgSccsgk fqKE}b%ʾ+/+ic}qrh2 ,0mss ewN&]n!H+T7M8D '|^6+=>}f;}+kbtqįвѼq> 0dYx%qqO~n*Wt5zS:ח>Lۿ9o߅yf16@8VPzhvK>!v;q-~h#žsѪ՛l4gShvؒxbJ>]7[|WݕO*,Uϼ[Y7\5ڸ@莏1Z6Zl\N3سhRfs|_aFh:k+ ƫjogZpܹl`WbS+}V|eّy`8{7i̇™&Ff^2{&`1٣g;CK*Ռ J̻[*R 6 b7*( -^_nZ7ZsTJ}=Ay{mم?]tb2Zk9"YV&DpqY{z> wA-^l3>G11Z@XIeϩ4߄OU9ҟHS5ϰ( SGh;څȒ}5gk^yҖTA Z- 0F:0UN~r3\= Od2;4y.R`a M0i aF.Vspa'DTrVGFhb?FFX4:jyb|#:/`4h`40h `40 0F FFha4h"hK:z) qE+0 F F0h(`01ZN9`4h`40ܷF,hq=0HN%PڎX0+a4LDl^hG0h`4tgF # "=`40h `40 `40F F=F;aq@Fha4h`40h `41o4h `40 0F @_\vyeVvjtIXqv)2I FMm4KiC61j ҫYgY/hF(!Ɯtk71jt"swNFVm{ ,3IZikڨwM0AuPZS^\fӆa4Q,t&.e슬GX5:`0h`40h `40 0Fh|; FFhha40hbh{"30h`40 `40 0F  ƽw :; FFhJM`hFh[FLBmFh5ZFx2 ƽw :p!x F"qg4F hBb4!u`d`4Q<2$!0DK#Yu0ĆѾ7wjEwF{a4YFS[饴1Rv;K#C2HHw&9 Au(!ޥN,΃ & -{m{K,T7'S# \i`b*h߭Zikڨwi$mKE1ul]Z2VZBiMe'~j4.`ĥ,XehFlF f@0DqցϰˣCFh7ZF y4!ѡG{@uo b& A40DhFh/F% >bt߸ `40h `40-;:r F؏J ?F2hhC1߶ hh<  zctm;aCYQktmhWy4Qn4 @ *F#u " β|^C@GYh>hn42+PAs%qhFa4YGS[饴1RI=1G{  %g1;"ttzs)1kt"swQBUٽw͎0q] Vښ6][B͍%c,,T(Ebh6 ]/J,/hFlF @:HBhFP`4nCoF  t f4Sցςxˣ=279< +@ `40 G2:Զa4h`40ėT+E1{h|ƽw :Oh|* ĕiF @ݤ F`dh  J"$<* N@0Dw&0O; *w$4Ah `40F 'r4v4nDF0F 0F }kF @; &sshu `4b4ш1hі /SftAsU30]R2V\YjІ!hFKicaF1j ҫ[jLі/Seҩ]ca3CnܣY(m{B:h0)}FFִQ*>K(̈ :JKJK()/ٳGFf4b4lG~b4U `4 F `4b4ш1h}m4;hA#wYb4@ b4шF#F b4F#F `4b4@ށhF#F j- ލ1)3hp F01Ľ1DV{ u F0"F6ڂ h$Fl4b4F}ӳ1ĿhMF[ @| h˄ƧA02ш kh1D$d- ){dI-ՓmAїusSR- Z-oe H3mF[Amcц /jҭlDA;Zٲw`e"'G EGSl85ZQGG6 ~F[<i &Ļhc蒒R?F[B4Wpo:Bq<Ռ)},ڇ[i]x(uң]m,fWLɕEŻ?1|69{oѢ;}[WtN@:Gn TE蚱B[k)ͣ'0FKicWOAo7;*gt39hp>22Nl; IxhCPH(gty֥{h͵p4BD$#pR3E䌜)0Zs0ܪ!#rR8Ȝ(g4nV{h͵p?1OF舜htNV-2g$v3dowFS`a$"ctDNJ~{I Xk"4IEiNsFS`t$IGi;4v3];짟-4'%vgsa?#Qg#~h#spyV^K;I6ɴF~RkᰟQ(gyVe!/`4hq~0:}!M|eW!̐g5uxLa7EW(F8ӚiF64txLat绔GPZ|Y9;*B/e)2`4hXF F0i4ؾ({51:RL FǢ_ `40FߏFDˆ"56,{eT& hnkɕtkFrlfFǴk^yUQ5u|}qƲSEyke)^r]cNsuz3*k~+Z‘_Y~F7 ڊ3`tm/bV(O"F\ooVc*(owu;սvBA>y<](:5đhNIguKSSO B3oR gS{&c4yf9IS~1 FǤy읷%AubY"uLEAV&umK#,=+ق-/鲵 RʦuEy+p~Sm.I&atOyfUt*#ز{`t,EwNb,wb#OG#fm΂kF\wt nrIp$}#\^h AF&WlUU\8 '&xȅIdG,n~jam94"'O1W]#?q52yHYWyGKN-*#ȿv5homڵD\lb0I1N*6-\RsIݯ]׾2I$''z(6ɲAF&uQܠ{)u'ӗ9˓Q v%]U}2S7 zN8zmRyt˲Y?{R7{i FitwRvEf\4IY6$ ]|/f糅W% ̙ n%UeL~]Yϻf֥I '7f]YUwZR5ёa~j6(^I+{+z}͜.CJ-*j`J25F ˖f i|$)rէfԉEFǨkTW[v YuQF F+V4*{).M+c*oisšjFG`.`tݳ`7^6N/,ch/NG F7`t<=SjUTgjt)GqϾ$hb=Zjv֊L{@RU 9j@h=B@c&.7e q`4P1[Z4; @#mJQP2IENDB`kst-2.0.3/docbook/kst/tutorial/Icon-kst-xymousezoom.png000644 001750 001750 00000000512 11544160206 023563 0ustar00synthsynth000000 000000 PNG  IHDRʥ pHYsnd tIMENWnIDAT8˝ Dc01*uB>M>J&L ;8I!^FF VJ =S) `dֈ)2]# ;&\A"$3cQ`j_i UM`cĐOs6Ǒ˜;&xyZ8mV~c8b@O.`س6e7\$}>.M&&J`$o,?Kfzem=8IENDB`kst-2.0.3/docbook/kst/tutorial/Screenshot-kst-eventmonitor.png000644 001750 001750 00000025743 11544160206 025140 0ustar00synthsynth000000 000000 PNG  IHDR6rPLTE    """%%%''')))+++---///222444555777999;;;7;E+;b)j-@m.Bo/Dt0Fx1Hz2I}4K6M8P[C\G]EcDcDdEeFgHiLlOnRmXmXrXt\w^y`{c~e~jmosvz{|~€ŃȈɍΎяӑԒԔՖ֞٢٤٥ўy8` tRNS5e\(IDATxLTo?'!ƐI/! (ys{{7-7&SM* yb^K- h{{ާmA`ٮeQG K&7wfsv .2993|>(T1jn9_,<SH8ʄbimu<ynwLN5d} *OZN'now=}7xгNipgMp*<,T JIip\g$K`.'.%}~ǂ"xe5_IJӏLɔ= Z/3C|e^ `Wi}H(= Pi<&S^Zn L |&/)א$;?{e=7h/1zf.x.:#d5 C>Φ0s09;G| /;}v6֜BF4ٷu{10defvvNLXRE#C>tHw੒/=/ Qn/ll?/2|޻vkמ$4r̡Y)5!/ ;)t|?qN\Ag'#}ܹsi|_٧_$xׁ+xbΉ?I)%4Y?ǝWh~F_}0i OPʓO2d}9 |P~yjs볓Wg._{s7x9L.Ϥ-;=O4d:^\$$4UO=7g%+6:GG_Q.m'?br?:%q;GΒs_G.yrk7$/?Ɠ? g/d%$/9RU)u>w<},('^mB ` ~ w,kS^ .dia2vFHȎL|4牛ͳO_tN\u|Ne]7D襙:O^<&ͩK;{w$LCI2)'{\Th?\ Ȃk$_ૐ g{2ŕajZQwPxBK0k˔;q+%?G?{ɛ09t~|Edxf/]vēm I6q3J *UMp ^B :X5]%_e06Y<ِUDjӫN/;7muLrr)wG٥+v|$wK :zb/$'d{|s?iĝ:7{$t\G4VR1cpUg|A*{_R>Qŧ^*4KI!Ir.I)۟*BdB mW'LvNN;\>Ǐ\\vEϮt]WD%$9;'/_)-'7_&M|ߕKNgJEG])9$^~O*x HP5_hB.20)qY< y!B־]$(ٵwIEwWG.WTNEEyh׾kOMvRQ׾k$IMRH}$s9Y|-!:)˯ K&3P\s _{W!%`Uy.LFO(X_9־҅I)O8<ΆtaR5zj_S.BK BS o P    A@:Z-/e Z -7ere @(e 2PA@Y]!ЧWʲG7 } \]@yQcF1֖{joޱ~c O˒H5iqIO1M%F( fg7ǝhSFoe{rdHܗP+iY[M ֪׺ȐDWZ,w_%'XtGfrj=vDTbGn'aLm0k8تJ{ݜ&i\uFpʵ&SJ%!; 2K_"@ynN?:M퉍+86i6:i vڰ8, Jضʨ]ʙDLmG}yV OE=NhN)|>LEٖ1J\%:Xx]lbFdoPQifckG_RQq?Meχ5nr+SG@K/ e1^/e{lFAFl&py,FEv^>R}ٺOat㲃z\,6-ޯP-KIϖ:2ZpEs;ަgc߰~x `̴^*:*II%-35K|C)hDy P 7>ePePePe0S[ 4#&(O2WeP@(e 2Pʠl4fz~䔍qձ3YaPL*iX]3b[yu(X1!ܤFLdPeJ!ꦛψPFSe6.hWR,N\)g$iK0b]e6c43_ڲBnˏ0 صl/ݹH_[^h!233ju!ٌbR݃o(?ر5[6 bu& Ѯ0~٘iqB|uM*nK3/U).<a<e  2,/fX^l+b)D@(e   APzʳ;'!@y]@(s x6\e e 2P@9)+AEyl(N >ʾ,ں!D2+к ꒦Jk~ ew-zOZ) d?˧Mv;4/1gYN.[ e?}Y/$ERs.g.rzt8.*Q^dDbnyϰueEHA(@F7w׿PؙoȫYʹx܋m9#̃B$<պy`r]dEA7_&eD2n z~rmT4Y{Q{&;fa- DlnYLC-yFAtȔݒHCլTޟڲwkעJ^.1偈DMo!- ?E#JgBN y wEzq-eO?z)K6&ǫYUz闷z9eH偈ȚaQS6SK3wE ;kf}dzEيꢻ%Qk{Uzm{p^"?QOpW4_Jcl>U!zxUrsvJkUSˏcl{ xduB*m=)sPQ7e-ԯSv#W39xZ|j ՠ{9걕^_EOZy]ϭe.ΡK9sіCMs~((ere?/,&e3??`[Fh]P@(C7M@(e   +IAT~I\A-o7\߼ 2P@(ex?w|]ePVغv/nfxuk6DF t#d2Ćmp:q*ZM7;M=HK QEDj0y~C$WY~QXWIνKDYuU?ʊW7c\uu,u* YcGU:eM%Ivx$ê}T;#"TeњE(bm#Lk#ۊzvʬR37PVW(+^ݶziP{yt"QnI2(Uںmq.w,AdӥL:Em*WۋIyn,g<٣,|W]#m#9jץ܈`|s..95.14>r(,(?TR/>|QI%Ƽ`ʮdz7nn^݄aOW֦yR̗sۧ4gRq+rEN~KTޱ, )mhXmٻo7(իˢ;7٣|Ŗ}W7WyDpž5xEweg:}zl__G5DR"doOuUKF9bxԄu58TpT>bhG eṷlfWuKͳ%d=2AFڦF6L)UDo>rKIus%?<ɞ؈qIvGNVviZ4N΁@<96:idy2le0&CN,ʂ /WMQ^RSƙ{zEG/e{ B#&PnG"r?;o)_Z6ަJk;QlԗKhρ)|@( ~9n΃$N4.neRi/+/-$ʳJq-wB_ᬁ k˽Dy=c%EkcbP5䟀|Dش؛xdM #{N4K?;֤a)Gl9F)XS&1b<rcc6&|C)hW(뎱}f+ÎV޲Cm=GwY!*rPDt4ǎ1ѡ yTiǑ|MxԘqN-5/i>Z{~xt䡺GP~\lϸ8jc}n<.1Ũ\S AU_!>aA|2fR/h|jrcr*|=tK͋!.)/PDRyNa1mӞ~\ۿ`3>+cͥ 'kfL\;w63 JI5:ǣE*5<e s8a'c2(2(e;E*k8<e r@R^:3~To Xc" h)_!n '?)}}H=YꄗOfv]Pko|Wt+kLvb=i'AQ17}~Bg܍4obWڂ\&rV_8F1't_M {2w8ۗcl(vX%k8-e"rV6yexEbe{2w8Lq1h|=ھ\yu` Iَ8c$8=_VÄ7~3l *Dk8Oʏ ݥ=G, 3nDY^VkWpU(&rkMX)3і'mˌ2',q2e~M*(&rEk|Ɛ@AXl)s{2ʲq/٠yNT6٣aqAAۓid,ø}L$ePPRD(ï  90c2(2(2(e y"PH8eP( (ePePePeТR^m ^6fSnETƫ AAi}'4w2@9)$QV5:qS9A7Ŝ@CÖdԤ=>(7ѭj˒کo#<|Kh(eGPRRHir*C]H 9;QeWe}GJdޚ5UNeOpU1eQF}~^<+~l)Qu\g_TFɁJNi4%O}ӽtԖϟveMUT_=U={cJeź|P>[7ʮ!r91$A-ҢlU$yQUg/,''+%FWl,kn6A?b+h x~6@J:UbηnN%eexD4\#Y2$.9T^ZQf{2^:2͉RP{ YKYo4،:J2_3TJNGw0tQ(etLZRWlBX3N|W#XԭpdUesŜoݜJ-K5mOFO}Z)XpSOt^4u({β_l=߳C-++lDurq{i/J[S~Q Gpi(+ ~7e~Y3˚ zP?RԣzNey%P.f󭟓v-I[50S}*z}gYSFdoTCm-F)Mx^ |P>ۧShI(ѥ.cZZ4ik-vl׼s^f.c#eɮqse!m~if,JDgS0βJP@(2(2(2(e AN<`GP (ePePeP-Ч<l瀧qVuB,({ =kh( P8]^BEY3jqPKyHQe] i(F D>Kx 9dG.MPnDFi0 !jA4BGrH}ڏKMYΣYwK92XCMY3A$}H%%s}gҮȫ#w(=eg!~^u5'Beg֖]9SHY:(!CKY3-;>1wk?.#eRU0B7:A8e ;T94    @(G"+ (?-2$*! W*e? ϫy8~Δ@y)){u)Xj5OsE );O F}sVu})Ih֙37ʓJv[:f:{({m`t_튍~\ nLvi{b# WnL+)3x26kٕӷ)mCpb@ e<̱0+9xrm jֶ"AyNvLqGnh#)`|QwKgj-eS@Y@;a5GL;P^5FNokIbc$$uOaݶLy1@k{i8qMesl!|"bP8"9bW\q)ʰ{ʾ>I %_ظ`Ŧ>P>7U/w5.߼.1Hf)2_cl@yϱul_SbxIݻ۳U@9h)A&A@A+`'f݃2(2P@A@Af+(eP( (ePePeP^~7W)[P^͆H/͇օgrQ6UW@]3l 6枲r;[z~ .<]֤%U 3"Iңqt1kkP~>#O/-. tK =rs{GڥZ% (/v9iޅPnC`3u$"@Xl6RGJϓ֖m|N|ze+rM 5 }m^״+nNqsWF_7Ǝc{ ^`ojB")KyٶЦ#6<̈HC||rSBPb^TRAPˏcl[nl̦;@yy(E;8)#E@2P@(erY"P(,oJKRʥd |G_\)5P^ @A@A@A@2PʠР~cVr'0 2o4*UT߸A~AP *= YȔ wg[@)"eb|?''rIENDB`kst-2.0.3/docbook/kst/debuglog-chapter.docbook000644 001750 001750 00000015040 11544160206 021667 0ustar00synthsynth000000 000000 The Debug Dialog The &kst; debug dialog can sometimes provide useful information about certain problems encountered, and contains all notices, warnings, and errors logged by &kst;. To access the debug dialog, select Debug Kst... from the Help menu. The Debug Log The debug log is located on the Log tab of the debug dialog. The following lists the different messages that can appear in the log, with brief explanations and suggested actions (where appropriate).

    The Kst Handbook

    Rick Chern <kst@kde.org>


    Revision 1.0.0

    Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

    Kst is a data plotting and manipulation program with powerful plugin support.


    Table of Contents

    1. Introduction
    What is Kst?
    Getting Started
    2. Working With Data
    Supported File Formats
    Data Source Concepts
    ASCII Input Files
    BLAST Dirfiles
    The Data Wizard
    The Data Manager
    Creating New Data Objects
    Editing and Deleting Existing Data Objects
    Data Types
    Vectors
    Curves
    Equations
    Histograms
    Power Spectra
    Plugins
    Event Monitors
    Matrices
    Images
    The Data Menu
    3. Working with Plots and Windows
    The Plot Dialog
    Content
    Axes
    Labels
    Legend
    Markers
    The Plot Context Menu
    The Label Editor
    Creating New Labels
    Editing and Deleting Existing Labels
    Moving Labels
    Data Mode
    Zooming and Scrolling
    Mouse Zoom Modes
    The Zoom Menu
    Match Axis
    The Scroll Menu
    Tied Zoom
    Working with Live Data
    Manipulating Plot Layout
    Layout Mode Context Menu
    Moving and Resizing Plots
    Selecting Multiple Plots and Grouping Plots
    Working with Windows
    MDI Modes
    Creating and Deleting Windows
    Moving Plots Between Windows
    4. Saving and Printing
    Saving Plot Definitions
    Exporting Vectors and Plots
    Exporting Vectors
    Exporting Plots
    Printing
    5. Event Monitoring
    Event Monitor Dialog
    Expression
    Kst Debug Log
    E-Mail Notification
    ELOG
    The ELOG Extension
    Server and Logging Settings
    6. Plugins, Fits, and Filters
    Adding and Removing Plugins
    Built-in Plugins
    Autocorrelation
    Bin
    Butterworth band-pass
    Butterworth band-stop
    Butterworth high-pass
    Butterworth low-pass
    Chop
    Convolution
    Crosscorrelation
    Deconvolution
    Fit exponential weighted
    Fit exponential
    Fit gaussian weighted
    Fit gaussian
    Fit gradient weighted
    Fit gradient
    Fit linear weighted
    Fit linear
    Fit lorentzian weighted
    Fit lorentzian
    Fit polynomial weighted
    Fit polynomial
    Fit sinusoid weighted
    Fit sinusoid
    Interpolation Akima spline
    Interpolation Akima spline periodic
    Interpolation cubic spline
    Interpolation cubic spline periodic
    Interpolation linear
    Interpolation polynomial
    Noise Addition
    Periodogram
    Statistics
    7. The Toolbar and Keyboard Shortcuts
    The Toolbar
    The Toolbar Menu
    Custom Shortcut Keys
    8. Licensing
    A. Command Line Usage and Examples
    Command Line Synopsis
    Command Line Examples
    B. Creating Additional Plugins
    Creating a Basic Plugin
    The XML File
    The Shared Object File
    Compiling the Plugin
    Creating Linear Fit Plugins
    Header Files
    Implementing Required Functions
    Calling the Fitting Functions
    Example
    Creating Non-linear Fit Plugins
    Header Files and Definitions
    Implementing Required Functions
    Calling the Fitting Functions
    Example
    Creating Pass Filter Plugins
    Header Files
    Required Functions
    Calling the Filter Function
    Example
    C. Supporting Additional File Formats
    Creating Datasource Readers
    The Shared Object
    The .desktop File
    Compiling and Copying
    D. The Kst DCOP Interface
    E. The Debug Dialog
    The Debug Log
    F. Installation
    Obtaining Kst
    Installing Kst from Source
    Requirements
    Optional Libraries and Packages
    Compiling and Installing

    Chapter 1. Introduction

    What is Kst?

    Kst is a data plotting and viewing program. Some of the features include:

    • Robust plotting of live "streaming" data.

    • Powerful keyboard and mouse plot manipulation.

    • Powerful plugins and extensions support.

    • Large selection of built-in plotting and data manipulation functions, such as histograms, equations, and power spectra.

    • Color mapping and contour mapping capabilities for three-dimensional data.

    • Monitoring of events and notifications support.

    • Built-in filtering and curve fitting capabilities.

    • Convenient command-line interface.

    • Powerful graphical user interface.

    Getting Started

    There are two main methods of quickly obtaining plots in Kst. The Kst command-line interface provides quick access to the main Kst features, while the graphical data wizard enables intuitive fine tuning of plot and data settings.

    We first need a data file. Copy and paste this simple 40-line set of data into a text file, and save it as simpledata.dat:

    -20 100
    -19 90.25
    -18 81
    -17 72.25
    -16 64
    -15 56.25
    -14 49
    -13 42.25
    -12 36
    -11 30.25
    -10 25
    -9 20.25
    -8 16
    -7 12.25
    -6 9
    -5 6.25
    -4 4
    -3 2.25
    -2 1
    -1 0.25
    0 0
    1 0.25
    2 1
    3 2.25
    4 4
    5 6.25
    6 9
    7 12.25
    8 16
    9 20.25
    10 25
    11 30.25
    12 36
    13 42.25
    14 49
    15 56.25
    16 64
    17 72.25
    18 81
    19 90.25
    20 100
    

    simpledata.dat is an example of an ASCII data file, one of the many file types Kst is capable of reading. For further details on file types, see Supported File Formats. To produce a simple plot using the first column (or “field”) of this file an x vector, and the second column as a y vector, enter the following:

    kst -x 1 -y 2 simpledata.dat

    Kst should start with the plot displayed:


    Simpledata plot

    Numerous other command-line options are available—using the command-line only, plots of data can be printed directly to files, and simple data manipulation such as creation of power spectra can be performed as well. For a complete list of command-line options, see Command Line Usage and Examples.

    If Kst is started without any command-line options, a QuickStart dialog is shown by default:


    The QuickStart dialog

    The QuickStart dialog provides both a convenient facility for opening previously saved Kst sessions and a shortcut to the data wizard. To open an existing Kst session, either select a file from the Recent files list, or enter a path in the textbox underneath, and click Open File. Clicking the button to the right of the textbox displays a file browser dialog that can be used to graphically browse to a Kst file. If this is your first time using Kst, you most likely will not have any saved sessions. In this case, the data wizard can be used to quickly import data and produce plots. To start the data wizard, click the Data Wizard... button. The data wizard walks through specification of a data file, selection of fields, and selection of plot options. For detailed descriptions of the data wizard options and settings, refer to the Data Wizard section.

    Tip

    If you do not want the QuickStart dialog to be displayed at startup, simply uncheck Show this dialog at startup at the bottom of the QuickStart dialog. The QuickStart dialog can also be toggled by selecting Configure Kst... from the Settings menu and clicking on Show QuickStart dialog on startup.

    Any plot displayed in Kst can be manipulated. For example, dragging a rectangle anywhere within a plot will zoom in to that section of the plot. Holding Ctrl or Shift while dragging will zoom in on the x or y axis only, respectively, and tapping the arrow keys scrolls a plot. See Working with Plots and Window for more details on manipulating plots and plot layout, as well as the different mouse modes.

    Chapter 2. Working With Data

    Supported File Formats

    Currently, Kst supports ASCII text files, BOOMERANG frame files, and BLAST dirfile files as data sources, as well as PIOLib and FITS files with the appropriate libraries. This section describes basic data source concepts common to all file types, and specifically details the ASCII and BLAST dirfile file types.

    Data Source Concepts

    A data source in Kst is simply a supported data file. The following concepts are important in understanding how Kst works with different data sources. Some terminology is also introduced in this section.

    Samples

    A sample is considered to be the fundamental unit with respect to data files. Each sample consists of one data value in the file. Note, however, that one sample may not correspond to one value in a data vector in Kst, due to the concept of frames.

    Fields

    A field usually corresponds to one vector in Kst. For example, a column in an ASCII data file is considered to be one field. Each field can have an explicit or implicit name. Datasource readers provide functions for reading and obtaining fields and field names.

    Frames

    A frame corresponds to a set number of samples, and each field in a data file can have its own ratio of samples per frame. The size of a data file is measured by the number of frames it contains. For ASCII data files, the number of samples per frame is 1, but for some data files, there may be multiple samples per frame. In the below illustration, the first 3 frames of an imaginary data file are shown. In this particular data file, Field 1 has a ratio of 5 samples per frame, Field 2 has a ratio of 2 samples per frame, Field 3 has a ratio of 3 samples per frame, and Field 4 has a ratio of 1 sample per frame.

    Depending on the specific data vector settings in Kst, data from files may be read as frames instead of samples, with either the first sample in a frame or the mean of all the samples in a frame representing the value of the frame.

    INDEX Field

    Some data files may not have a field that represents the x axis of a plot. However, Kst implicitly creates an INDEX field for all data sources. The INDEX field simply contains integers from 0 to N-1, where N is the number of frames in the data file.

    ASCII Input Files

    The simplest input file format is the ASCII text file. These files are usually human-readable and can be easily created by hand or simple scripts if desired. The following is an example of an ASCII input file.

    112.5 3776 428
    187.5 5380 429
    262.5 5245 345
    337.5 2942 184
    412.5 1861 119
    487.5 2424 138
    567.5 2520 162
    637.5 1868 144
    712.5 1736 211
    787.5 1736 211
    862.5 2172 292
    937.5 1174 377
    1000.5 499 623
    

    Each column of this file represents a field, while each row represents one frame. Columns are separated by tabs or spaces, and rows are separated by carriage returns. Note that due to their structure, ASCII files cannot have multiple samples per frame. Also, since the columns do not have labels, field names are assigned by Kst based on the order of the columns (the leftmost column has a field name of 1).

    Commented lines in ASCII files start with one of the characters in the set {#, !, /, ;, c}. All commented lines and empty lines are ignored by Kst. Valid numbers include those with decimals, negative signs, or e, to indicate scientific notation. Invalid numbers (such as english words) are replaced with 0 by Kst.

    BLAST Dirfiles

    BLAST dirfile data sources are actually directories of files. Each directory represents one data source, and each file in the directory, with the exception of a file called format, represents a single field. The file named format lists each field and its properties. Below is example of such a file:

    scount RAW f 1
    fcount RAW f 20
    sine RAW f 20
    ssine RAW f 1
    cos RAW f 20

    In this example, scount, fcount, sine, ssine, and cos are field names. RAW indicates the file is written in raw format, and the last number in each row is the number of samples per frame.

    When selecting a BLAST dirfile for use in Kst, the directory containing the field files should be selected. Kst will when automatically look for a format file, if it exists, to determine the fields and their properties.

    The Data Wizard

    The Data Wizard provides a quick and easy way of creating vectors, curves, power spectra, and plots in Kst from data files. To launch the wizard, select Data Wizard... from the Data menu. You will be prompted to select a data source. Browse to a valid data file (or enter in the path to a data file) and click Next. The following window will be displayed.


    Data Wizard Screen 2

    Select the fields you wish to import into Kst. You may filter the list of fields by entering a string to match (wildcards such as * are supported) into the text box above the list.

    The Data Range section is used to specify the range of data to read from the selected vectors in the input file. The following discussion assumes knowledge of “frames”. For a detailed description of this concept, see File Formats.

    Starting frame, Count from end, Number of frames, and Read to end

    Using these four settings, the lower and upper boundaries of the data range can be set. For example, to read from frame 10 to frame 900, enter 10 for Starting frame and 890 for Number of frames. To read from frame 500 to the end of the file, enter 500 for Starting frame and select the Read to end option. To read only the last 450 frames from the file, select the Count from end option and enter 450 for Number of frames. The combinations used in the previous two examples are often useful for reading data from a file that is being updated in real time. Subsequent additions to the file are read, causing associated vectors to be updated as well.

    Read 1 sample per N frames and Boxcar filter first

    In addition to the lower and upper range boundaries, the samples to read from the selected range can be set. If Read 1 sample per N frames (where N is the entered value) is not selected, all samples in the selected range will be read. Alternatively, frames in the data file can be skipped by selecting Read 1 sample per N frames The value of the 1 sample that is used to represent a frame depends on whether or not Boxcar filter first is selected. If Boxcar filter first is not selected, the value is the same as the value of the 1st sample in the frame. If Boxcar filter first is selected, the value is the mean (average) of all the samples in that particular frame.

    Power Spectrum and X axis settings can be specified within the Plot Types section. These settings are described below.

    XY, Power Spectrum, and XY and Power Spectrum

    Select whether to plot the power spectrum only, data (XY) only, or both. If the power spectrum is selected for plotting, additional settings in this section become available.

    X Axis Vector

    The vector to be used as the independent vector for the plots. You may select a field from your data file, or the INDEX vector. The INDEX vector is simply a vector containing elements from 0 to N-1, where N is the number of frames in the data file.

    The FFT Options subsection in the Plot Types section is available only if a power spectrum is to be plotted. The below definitions assume basic knowledge of power spectra—for further details, refer to Numerical Recipes in C: The Art of Scientific Computing, published by Cambridge University Press.

    Interleaved average and FFT Length

    The power spectrum is defined as “the square root of the absolute value of the mean of the interleaved Fast Fourier Transforms of length 2^x”, where x is the value entered in the FFT Length selection box. Selecting Interleaved average allows the length of the interleaved Fast Fourier Transforms to be specified. If Interleaved average is unchecked, Kst will determine the length based on the length of the vector.

    Data units and Rate units

    The units specified in these textboxes are used for the purpose of auto-generating axes labels for the plots.

    Sample rate

    The sample rate is used to generate the X axis of power spectrum plots.

    Appodize

    If this option is selected, the data is appodized using a Hanning window, to reduce bin-to-bin leakage.

    Remove Mean

    Select this option to remove the mean from the selected data (i.e. translate the data so that the mean is zero).

    Once you are satisfied with all the settings, click Next to advance to the next window. Select any filters you wish to apply to the data, and click Next to advance to the final window.


    Data Wizard Screen 3

    From here, you can change general plotting settings. Most of the settings are self-explanatory. A brief overview of each section is provided below.

    Curve Style

    Select whether to plot data points only, lines connecting the data points only, or both. By default, lines are continuous with weight 0, and data points are marked using crosses. Line and data point colours are chosen so that curves with identical colours are minimized. Note that the curve style settings apply to both Power Spectra and XY plots.

    Curve Placement

    Select the plots to place the new curves on. Cycle through distributes the curves on the plots by cycling through the plots. Note that the curve placement settings apply to both Power Spectra and XY plots.

    Label Generation

    Select the desired labels and legends to be placed on the plots.

    Plot Placement

    Select the desired window(s) to place the new plots on. New windows can be created for the plots by selecting In new window.

    Once you are satisfied with all the settings, click Finish and the plots will be generated.

    The Data Manager

    The Data Manager provides a central location for adding, deleting, and modifying all the data objects used in Kst. It can be accessed by selecting Data Manager from the Data menu.

    Creating New Data Objects

    To create a new data object from the Data Manager, click on one of the buttons listed under New:. A new window will be displayed, allowing options and settings for the data object to be set.

    Tip

    You can also create new curves by right-clicking on a vector and choosing Make Curve...

    Since you are creating a new data object, you may enter a unique name to identify the object. The default name can be used as well (if it is unique).

    The settings for all plottable data objects except images have two common sections—Appearance and Placement (images only have the Placement section). These sections are described below. For data-specific settings, see Data Types.



    Appearance

    The Appearance section allows you to change the appearance of the data object when it is plotted.

    Clicking this button displays a colour chooser dialog box, which can be used to change the colour of both the lines and points.

    Show points

    Selecting this checkbox shows the data points used to plot the data object. The drop-down list to the right allows the shape of the points to be changed.

    Show lines

    Selecting this checkbox shows the lines joining the data points for the data object. The thickness of the line as well as the line style can be changed.

    Placement

    The Placement section specifies the plotting location of new plottable data objects.

    Plot window

    Specify the window in which to plot the data object. You may create a new window by clicking the New... button.

    Place in existing plot, Place in new plot and Do not place in any plot

    You can choose whether or not to immediately plot the data object on a new or existing plot. If Place in new plot is selected, you can also choose to re-arrange the layout of the plots by selecting re-grid and entering the number of columns to use for the new layout grid.

    Once all the desired settings for the new data object have been set, click the OK button to create the new data object.

    Editing and Deleting Existing Data Objects

    To edit an existing data object, simply highlight it in the Data Manager window and click the Edit button. The settings window for the selected object will be displayed. This window is identical to the one displayed when creating new data objects (with the exception that the Placement section may be absent), so refer to Creating New Data Objects for more information on the settings and options.

    To delete a data object, highlight it in the Data Manager window and click the Delete button. Note that the entry in the # Used column for an object must be 0 before the object can be deleted. The # Used column indicates the number of times that a particular data object and its children (if any) are used by either other data object or by plots. Listed below are some consequences of this restriction to keep in mind when attempting to delete data objects.

    • All plottable objects (curves, equations, histograms, power spectra, and images) must be removed from plots before they can be deleted. An object can be removed from a plot by right-clicking on it in the Data Manager window and selecting the desired plot from the Remove From Plot submenu.

    • All data objects that use a particular data vector must be deleted before the data vector can be deleted.

    • All children of a parent data object must be unused before the parent data object can be deleted.

    After a sequence of deletions and removals of plottable data objects from plots, you may find that there are numerous unused data objects displayed in the Data Manager. To quickly remove these objects, you can click the Purge button.

    Data Types

    There are nine main types of data objects in Kst. Data objects can contain other data objects, as represented by the tree structure view in the Data Manager. The following diagram illustrates the relationships between the different data types.

    Kst Data Types

    As can be seen from the above diagram, the curve, equation, histogram, power spectrum and image data objects are the only data objects that are plottable. All data objects (other than vectors) have the capability of using vectors, while equations, power spectra, events, and plugins all contain slave vectors.

    Descriptions of each data type are provided below, along with overviews of the settings and options available when creating or editing each type of data object. Settings common to almost all data types have been omitted—see Creating New Data Objects for more information.

    Vectors

    Vectors are one of the most often-used data objects in Kst. As their name implies, vectors are simply ordered lists of numbers. Most often they contain the x or y coordinates of a set of data points.

    As vectors can be potentially quite large, it is a good idea to be aware of the amount of memory Kst has allocated for use. The current available memory is displayed in the lower right corner of the status bar of the main Kst window.

    Tip

    If the status bar is not available, ensure that Show Statusbar is checked in the Settings menu.

    The following is a screenshot of the window displayed when creating or editing vectors. Explanations of the settings are listed below.


    Edit Vectors

    Data Vector Parameters

    The source file and field to read can be set using the following options.

    File name

    The path to the desired data file. Clicking the button to the right displays a file browser window that can be used to graphically browse to the file.

    Field or column

    The field or column to create a vector from.

    Data Range

    This section specifies the range of data to use from the selected field for the data vector.

    Starting frame, Count from end, Number of frames, and Read to end

    Using these four settings, the lower and upper boundaries of the data range can be set. For example, to read from frame 10 to frame 900, enter 10 for Starting frame and 890 for Number of frames. To read from frame 500 to the end of the file, enter 500 for Starting frame and select the Read to end option. To read only the last 450 frames from the file, select the Count from end option and enter 450 for Number of frames. The combinations used in the previous two examples are often useful for reading data from a file that is being updated in real time. Subsequent additions to the file are read, causing associated vectors to be updated as well.

    Read 1 sample per and Boxcar filter first

    In addition to the lower and upper range boundaries, the samples to read from the selected range can be set. If Read 1 sample per is not selected, all samples in the selected range will be read. If Read 1 sample per is selected, only 1 sample per N frames will be read, where N is the number entered in selection box to the right. The value of the 1 sample that is used to represent a frame depends on whether or not Boxcar filter first is selected. If Boxcar filter first is not selected, the value is the same as the value of the 1st sample in the frame. If Boxcar filter first is selected, the value is the mean (average) of all the samples in that particular frame.

    Curves

    Curves are primarily used to create plottable objects from vectors. Curves are created from two vectors - an “X axis vector” and a “Y axis vector”, that presumably provide a set of data points. Thus, a curve can be thought of as a set of data points and the lines that connect them (even though the points or lines may not be visible on plots).

    The following is a screenshot of the window displayed when creating or editing curves. Explanations of the settings are listed below.


    Edit Curves

    Curve Contents

    The contents of the curve can be set from this section.

    X axis vector

    The vector to use for the independent (horizontal) axis.

    Y axis vector

    The vector to use for the dependent (vertical) axis.

    X error bar and Y error bar

    The vectors containing error values corresponding to the X axis vector and Y axis vector, respectively. The vectors should contain the sizes of the error bars in the same order as the data points.

    Equations

    An equation data object consists of a mathematical expression and an independent variable. The expression is built using a combination of scalars, vectors, and operators, and usually represents the values of the dependent variable. The independent variable can be an existing vector or it can be generated when the equation object is created or edited. Since an equation ultimately consists of a set of data points, an equation object is plottable.

    The following is a screenshot of the window displayed when creating or editing equations. Explanations of the settings are listed below.


    Edit Equation

    Equation

    The mathematical expression representing the dependent variable can be modified from this section.

    Operators

    A list of available operators. Choosing an operator from the list inserts the operator at the current insertion point in the Equation text box.

    Vectors

    A list of the current vector objects in Kst. Choosing a vector from the list inserts the vector at the current insertion point in the Equation text box.

    Scalars

    A list of the available scalar values. This list is composed of both the scalar values in the current Kst session as well as some built-in constants. Choosing a scalar from the list inserts the scalar at the current insertion point in the Equation text box.

    Equation

    The mathematical expression representing the independent variable. You may manually type in this text box or you may select items to insert using the above drop-down lists.

    Independent Variable

    This section is used to specify the source of the values for the independent variable.

    Use

    Select this option to use an existing vector as the independent variable. Select a vector from the drop-down list, or quickly create a new one by clicking the button to the right.

    Interpolate to highest resolution vector

    Selecting this option interpolates the selected vector to the greatest number of samples possible.

    Generate

    Select this to generate a set of values to use as the independent variable. Specify the lowest value to generate in the From field, and the highest value to generate in the to field. Set the value for Number of samples to be the number of equally spaced values to generate between the lowest value and the highest value (inclusive).

    Histograms

    A histogram data object simply represents a histogram of a particular vector. Histogram objects are plottable.

    The following is a screenshot of the window displayed when creating or editing histograms. Explanations of the settings are listed below.


    Edit Equation

    Histogram Properties

    The source vector, as well as basic histogram properties, can be modified from this section. You can either manually specify settings or use the Auto Bin button.

    Data vector

    The data vector to create the histogram from. Although a vector is needed to create a histogram, the vector is treated as an unordered set for the purposes of creating a histogram.

    From and to

    The From field contains the left bound for the leftmost bin in the histogram. The to field contains the right bound for the rightmost bin in the histogram.

    Num bins

    Enter the total number of bins to use in the Num bins field.

    Auto Bin

    Instead of specifying values for From, to, and Num bins, you can click Auto Bin to automatically generate values for all three fields based based on the lowest and highest values, as well as the number of elements found in the source vector.

    Y Axis Normalization

    This section is used to specify the type of normalization used for the y axis of the histogram.

    Number in bin

    Selecting this option causes the y axis to represent the number of elements in each bin.

    Fraction in bin

    Selecting this option causes the y axis to represent the fraction of elements in each bin out of the total number of elements.

    Percent in bin

    Selecting this option causes the y axis to represent the percentage of elements (out of the total number of elements) in each bin.

    Peak bin = 1.0

    Selecting this option causes the y axis to represent the number of elements in each bin divided by the number of elements in the largest bin (the bin with the greatest number of elements). In other words, the y axis is normalized to 1.0.

    Power Spectra

    A power spectrum data object represents the power spectrum of a vector, defined as “the square root of the absolute value of the mean of the interleaved Fast Fourier Transforms of length 2^x of the vector”, where x is the value entered in the FFT Length selection box. The below definitions assume basic knowledge of power spectra—for further details, refer to Numerical Recipes in C: The Art of Scientific Computing, published by Cambridge University Press.


    Power Spectra Window

    Curve Contents

    The source vector, as well as basic power spectrum properties, can be modified from this section.

    Data vector

    The data vector to create a power spectrum from.

    Interleaved average and FFT Length

    Selecting Interleaved average allows the length of the interleaved Fast Fourier Transforms to be specified. The length is specified as a power of 2. If Interleaved average is unchecked, Kst will determine the length based on the length of the vector.

    Data units and Rate units

    The units specified in these textboxes are used for the purpose of auto-generating axes labels for the plots.

    Sample rate

    The sample rate is used to generate the X axis of power spectrum plots.

    Appodize

    If this option is selected, the data is appodized using a Hanning window, to reduce bin-to-bin leakage.

    Remove Mean

    Select this option to remove the mean from the selected data (i.e. translate the data so that the mean is zero).

    Plugins

    A plugin data object represents a Kst plugin. All plugins have a common format, and show up as type “Plugin” in the Data Manager. For more information about plugins, please see Plugins and Filters

    Event Monitors

    An event monitor data object represents an instance of an event monitor. For more information on monitoring of events, see Event Monitoring.

    Matrices

    A matrix represents a set of three-dimensional data points (x, y, z) arranged in a two-dimensional grid. The z values of the matrix are obtained from a vector, and the grid structure is manually specified using the Edit or New Matrix dialog. The descriptions below refer to the following diagram depicting Kst's matrix structure.

    A screenshot and explanation of the matrix dialog follow.


    Matrix Window

    Vector Selection

    Z Vector

    The data vector to obtain the z values from.

    Grid Parameters

    X Minimum and Y Minimum

    The origin of the matrix is specified by the coordinates (X Minimum, Y Minimum). The location of the origin is represented by a red circle in the above diagram.

    X Step Size and Y Step Size

    These two values specify the dimensions of each rectangular cell in the matrix grid. All cells in the matrix have identical dimensions.

    Dimensions and Use maximum x length

    Enter the number of steps for the x dimension of the matrix, followed by the number of steps for the y dimension of the matrix. If Use maximum x length is checked, the x dimension of the matrix will be determined based on the length of the vector and the entered y dimension. If this option is checked and the length of the vector subsequently changes, the x dimension of the matrix will be updated accordingly.

    Note that the minimum allowed y dimension is 1, while the minimum allowed x dimension is 0.

    Images

    Images are graphical representations of Matrices. Images can be plotted as color maps, contour maps, or both.


    Image Window

    Matrix Selection

    Matrix

    Select the matrix to use for this image. New matrices can be created by clicking on the button to the right.

    Image Type

    Color Map, Contour Map, and Color Map and Contour Map

    Select the type of image to be plotted. Changing this selection enables or disables sections of the image dialog as appropriate.

    Color Map Parameters

    A color map represents the z value of each cell in the matrix using a color. This section is only available if Color Map or Color Map and Contour Map is selected under Image Type.

    Color palette

    Select the color palette to use for the color map. By default, two palettes suitable for color maps are installed by Kst—Kst Grayscale 256 (a 256 color grayscale palette) and Kst Spectrum 1021 (a 1021 color rainbow spectrum that ranges from blue to red). Additional palettes can be installed by simply copying GIMP compatible palette files to the colors subdirectory of the user configuration directory (for example, /usr/share/config/colors/). Note that saved images using a non-default palette may not be viewable by other users of Kst if they do not have the required palette. In such cases, a default grayscale palette is used instead.

    Lower Z threshold, Upper Z threshold and Auto Threshold

    Enter the lower and upper thresholds to use for the mapping of colors. Palette colors are evenly distributed between Lower Z threshold and Upper Z threshold. Any cells in the selected matrix with z values less than Lower Z threshold are mapped to the first color in the palette. Any cells in the selected matrix with z values greater than Upper Z threshold are mapped to the last color in the palette. Clicking Auto Threshold will fill in the lower and upper threshold values using the least and greatest z values found in the selected matrix.

    Contour Map Parameters

    A contour map draws a set of lines, with each line representing a certain z value. This section is only available if Contour Map or Color Map and Contour Map is selected under Image Type.

    Number of contour levels

    Select the number of contour levels to use. The contour levels will be distributed evenly between the lowest and highest z values found in the matrix.

    Color

    Select the color to use for the contour lines. Clicking this button displays a standard KDE color chooser dialog.

    Weight and Use variable line weight

    Select the weight, or “thickness” of the contour lines. If Use variable line weight is selected, contour lines representing higher elevations are drawn thicker than those representing lower elevations. Use discretion when selecting this option, as images with high contour line densities may become unreadable.

    The Data Menu

    The Data menu provides quick access to many features related to data objects in Kst. Most of the menu functions duplicate functions found elsewhere, so only brief descriptions are provided below.

    Reload

    Reloads all data vectors from their source files.

    Data Wizard...

    Displays the Data Wizard.

    Data Manager

    Displays the Data Manager.

    New [data object]

    Displays the corresponding dialog for creating the data object. Refer to Data Types for descriptions of each dialog.

    View Scalars

    Displays a dialog from which the values of all the scalars in the current Kst session can be viewed. The dialog is updated dynamically if the values change.

    View Vectors

    Displays a dialog from which the values in all the current vectors can be viewed. Select a vector to view using the drop-down list. The dialog is updated dynamically if the values change.

    View Fit Results

    Displays a dialog which shows all the resulting values from performed fits. Select a fit result to view using the drop-down list. The dialog is updated dynamically if the values change.

    Change Data File

    Displays a dialog for quickly changing data files that vectors are associated with. Select the vectors to change, and then browse to a different data file. Click Apply to save the changes.

    Chapter 3. Working with Plots and Windows

    This chapter details the concepts behind plots and windows, and provides information on viewing and manipulating the layout of plots and windows in Kst. The following diagram illustrates the relationships between windows, plots, and plottable data objects.

    Kst Window, Plot, and Curve relationships

    As can be seen from the above diagram, each window in Kst can contain zero or more plots, and each plot can contain zero or more plottable data objects.

    The Plot Dialog

    The plot dialog provides a central location for managing plots. To access it, select Edit Plots from the Plots menu. At the top of the dialog box you should see two drop-down lists:


    Top of Plot Dialog

    To modify a plot, select the window that contains the plot from the left drop-down list, and select the plot itself from the right drop-down list. New windows can be created by clicking the button in the middle.

    At the bottom of the plot dialog are four buttons. Delete deletes the currently selected plot, Apply as New applies the current plot settings to a new plot, Apply Edits applies the plot settings to the currently selected plot, and Close closes the plot dialog without applying or saving any settings.

    The plot settings available on each tab of the plot dialog are described below.

    Content

    Below is a screenshot of the Content tab.


    Plot Dialog Content Tab

    As the name implies, the settings on this tab specify the content of the plot. The following are brief explanations of the settings.

    Unique plot name

    The unique plot name is the identifier for the plot. There cannot be duplicate plot names.

    Displayed objects and Available objects

    Displayed objects lists the plottable data objects that should be plotted in the plot. Available objects lists all the current plottable data objects in Kst that are not in the Displayed objects list. To move an item from one list to the other, first highlight the desired item, and click the appropriate arrow button in between the two lists (the left arrow to move a item from Available objects to Displayed objects, and the right arrow to move a item from Displayed objects to Available objects). Alternatively, dragging and dropping the items works as well.

    Foreground and background colors

    Select the foreground and background colors to use for this plot using the standard KDE color chooser. The upper left box indicates the foreground colour, while the lower right box indicates the background colour. To edit a colour, double-click on the desired box, and a standard colour chooser dialog will appear. Click to swap the foreground and background colours. If you wish to quickly switch to a white background and black foreground, click Note that the foreground color only affects the axes lines and axes labels, and is independent of any colors used to plot data objects.

    Re-grid and Columns

    Check the Re-grid option to rearrange all plots in the selected window in a grid pattern with the specified number of columns.

    Axes

    Below is a screenshot of the Axes tab.


    Plot Dialog Axes Tab

    The settings for the plot axes are specified on this tab. The axis settings are split into two identical sections—an x axis section and a y axis section.

    Auto scale

    Select this option to let Kst automatically choose a scale for this axis based on the highest and lowest values for this axis found in the plotted objects.

    Auto up

    This option behaves similarly to Auto Scale, but the upper axis limit will only increase, and the lower axis limit will only decrease.

    Spike Insensitive Auto scale

    Select this option to let Kst automatically choose a scale for this axis that is based on the values found in the plotted objects. In general, “spikes”, or sudden short increases or decreases in the value, will be ignored when determining the scale.

    Mean-centered

    Select this option to center the axis around the mean of the values found in the plot (x values are used to calculate the mean for the x axis, and y values are used to calculate the mean for the y axis). Specify the length of the axis in the Range text box.

    Fixed

    Manually specify lower and upper limits for the axis. Enter the limits in the textboxes to the right of Range.

    Logarithmic

    Enable this checkbox if you wish to use a logarithmic scale for the axis.

    Major tick density, Minor ticks, and Auto minor

    Change the density value for the major ticks on this axis by using the Major tick density field. The number of major ticks on the axis will be approximately equal to the density value, with slight variations depending on the plot size and zoom level. Select the number of minor ticks to show in between major ticks using the Minor ticks field. If Auto minor is checked, the number of minor ticks is automatically determined based on zoom level.

    In addition to axis ticks, grid lines can be shown on plots as well. Grid lines are drawn as thin dotted lines using the specified colors.

    Show major

    Select X major to show vertical grid lines corresponding to the x axis major tick marks. Select Y major to show horizontal grid lines corresponding to the y axis major tick marks. The color of both types of major lines can be specified by clicking the button next to Color.

    Show minor

    Select X minor to show vertical grid lines corresponding to the x axis minor tick marks. Select Y minor to show horizontal grid lines corresponding to the y axis minor tick marks. The color of both types of minor lines can be specified by clicking the button next to Color.

    Labels

    Below is a screenshot of the Labels tab.


    Plot Dialog Labels Tab

    Settings for the plot labels can be specified on this tab. Brief descriptions of the settings are provided below.

    Current scalar list

    A list of the current scalars defined in Kst. This list is primarily used to quickly insert values in the label texts. Choosing an item from this list will insert the item at the current text cursor position.

    Top label

    The label located at the top of the plot. Select a font size and enter the text for the label using the controls in this row.

    Y axis

    The label located vertically next to the y axis of the plot. Select a font size and enter the text for the label using the controls in this row.

    X axis

    The label located vertically next to the x axis of the plot. Select a font size and enter the text for the label using the controls in this row.

    Numbers, X angle and Y angle

    The numbers used to label both the x axis and the y axis of the plot. The size and angles of the numbers can be specified. Positive angles rotate the text clockwise, while negative angles rotate the text counter-clockwise.

    Font family

    The font used for all labels of the plot. Select an available font using the drop-down list.

    Also Apply Font and Angle Settings To

    Select the plots to which the specified label settings (except Label Text) should be applied.

    Note

    If All other plots or All other plots in this window is selected, previous label settings for the affected plots will be lost.

    Auto Label

    Click this button to automatically generate label texts for all labels on the plot. The text for Top label will be a list of paths to the data files used in the plot. The text for Y axis will be a list of the dependent variable descriptions (e.g. “Number in Bin” for a histogram). The text for X axis will be the name of the vector used as the independent variable.

    Labels (preview)

    The preview image at the bottom of the Labels tab provides previews of all four labels at 100% zoom.

    Legend

    Below is a screenshot of the Legend tab.


    Plot Dialog Legend Tab

    Legend settings for the plot can be specified on this tab; most of these settings concern the appearance of the legend. The legend itself is optional.

    Show legend

    This option enables or disables the legend for the plot. If you wish to use a legend, you must select this checkbox.

    Display in legend box

    Select this option to display a border around the legend. Selecting this option also allows the background of the legend to be set using the color chooser located on this tab.

    Alignment

    The horizontal (left and right) alignment of the items in the legend. The available settings in the drop-down list are Right, Center, and Left.

    Font family

    The font to use for the legend text. Select a font from the drop-down list.

    Font size

    The size of the legend text. Note that the size is not specified in points, but is relative to a default size of 0.

    Colors

    This widget can be used to specify the colour of the legend text. The upper left box indicates the foreground colour, while the lower right box indicates the background colour (applicable only if Display in legend box is checked). To edit a colour, double-click on the desired box, and a standard colour chooser dialog will appear. Click to swap the foreground and background colours. If you wish to quickly return to the default colours, click

    Also Apply Settings To

    Select the plots to which the specified legend settings should be applied.

    Note

    If All other plots or All other plots in this window is selected, previous legend settings for the affected plots will be lost.

    Legend (preview)

    The image at the bottom of this tab provides a preview of the legend text at 100% zoom. Among other things, the preview can be useful in determining appropriate font sizes.

    Markers

    Below is a screenshot of the Markers tab.


    Plot Dialog Markers Tab

    Plot markers provide an easy means of flagging areas of interest on a plot. The Markers tab provides full access to plot marker settings and options. Navigation functions for plot markers are described in the Scroll Menu section.

    Tip

    To quickly create plot markers on a plot, place the mouse cursor over the plot and press the Insert key. A vertical dashed line should appear indicating the position of the plot marker.

    New and Add

    Use the New text field to manually enter a plot marker value. Values can be entered in floating point or scientific notation. Values in scientific notation must be entered in the form mEx or mex, where m is the mantissa and x is the exponent. For example, one way to enter the value 15000 in scientific notation is by typing 1.5e4.

    Click the Add button to create a new plot marker with the specified value. You will be warned if duplicate plot markers already exist, or if the entered value is not valid. Note that plot marker additions or removals made from the Markers tab are not applied unless the plot dialog settings are applied.

    Defined plot markers, Remove, and Remove All

    The list of existing plot markers for this plot are listed under Defined plot markers. To remove plot markers, highlight the desired markers in the list and click the Remove button. Multiple markers can be selected for removal by clicking and dragging within the list, or by holding down the Shift or Ctrl key and clicking on items in the list. To remove all plot markers for this plot, click the Remove All button. Note that plot marker additions or removals made from the Markers tab are not applied unless the plot dialog settings are applied.

    Automatic Marker Generation

    In addition to individually defining plot markers, curves, equations, power spectra, and histograms can be used to automatically generate plot markers as well. To use one of these data objects for plot marker generation, check the Use data object as marker source checkbox and select an item from the drop down list. Then select the criteria to use for creating plot markers. Selecting Rising edge causes plot markers to be created when the y value of the selected data object changes from zero to non-zero. Selecting Falling edge causes plot markers to be created when the y value of the selected data object changes from non-zero to zero. Selecting Both causes plot markers to be created on both rising edges and falling edges of the data object. In all cases, the x value of the point in the data object with the non-zero y value is used to create the new plot marker.

    If the selected data object is subsequently updated, additional plot markers will be created if necessary. However, plot markers will never be removed as a consequence of data object changes, so manually created plot markers will never be affected.

    The Plot Context Menu

    When working with plots, right-clicking on any plot will bring up a context menu that provides commonly used functions. The following list provides a brief overview of the menu items, often referring to other sections of this document that describe the functions in more detail.

    Delete

    Deletes the plot.

    Edit...

    Brings up the Plot Dialog, with this plot selected. See the Plot Dialog section for information on the settings.

    Maximize

    Expands the plot so that it takes up the entire area of the window. Uncheck this option to return the plot to its previous size.

    Pause

    Pauses automatic update of live data. This menu item duplicates the functionality of Pause from the Range menu. See Working with Live Data for more information.

    Zoom (submenu)

    The Zoom submenu is described in the section entitled The Zoom Menu.

    Scroll (submenu)

    This menu is described in the section entitled The Scroll Menu.

    Edit (submenu)

    This submenu displays a list of objects available for editing. Clicking on an object name from the submenu displays the Edit dialog for the object. Details on this dialog are available in the Curves.

    Fit (submenu)

    This submenu displays a list of curves, histograms, power spectra, and equations that can be fit. Selecting a name from the submenu displays the Fit Function dialog. This dialog is similar to the plugins dialog, but displays only those plugins that perform fits. The input vectors are selected based on the data object. In addition, curve appearance properties can be changed, as the Fit function creates vectors, and curves based on the vectors.

    Filter (submenu)

    This submenu displays a list of data objects that can be filtered. Selecting a name from the submenu displays the Filter Function dialog. This dialog is similar to the plugins dialog, but displays only those plugins that perform filtering. The input vector to be filtered is selected based on the curve. In addition, curve appearance properties can be changed, as the Filter function creates vectors, and curves based on the vectors.

    Remove (submenu)

    This submenu displays a list of curves currently in the plot. Clicking on a curve name from the submenu removes the curve from the plot (the curve itself, however, is not removed as a data object).

    The Label Editor

    The label editor allows custom labels to be placed in arbitrary locations in Kst plot windows, in addition to the fixed labels created as part of plots. To use the label editor, select Label Editor from the Plots menu. The mouse mode will change to label editor mode. To exit label editor mode, select another mouse mode (such as XY Mouse Zoom). The following sections describe the functions available when in label editor mode.

    Creating New Labels

    To create a new label using the label editor, click anywhere within the x and y axes of a plot where there is not already an existing label. The label editor dialog should appear:



    The following are explanations of the dialog box elements.

    Scalars

    A list of scalars currently defined in Kst. Selecting an item from the dropdown list inserts the value of the item at the current cursor position in Label text.

    Label text

    The text displayed by the label. You may enter text manually in this dialog and in combination with scalars selected from the Scalars dropdown list if you wish.

    Font

    The font to use for the label text. Select a font from the dropdown list.

    Size

    The size of the label text. 0 is the default value.

    Rotation

    The number of degrees to rotate the label. Positive values rotate the label clockwise, while negative values rotate the label counter-clockwise.

    Alignment

    The horizontal alignment of the label. Select one of Left, Center, or Right.

    Color

    Select the color to use for the label text. Clicking the button displays the standard KDE color chooser. Selecting Use plot color uses the foreground color specified for the plot.

    Once you are satisfied with the label settings, click Apply to apply the label settings without closing the label editor dialog. Click OK to apply the label settings and close the dialog. Alternatively, you can click Close to close the label editor dialog without applying any label settings.

    Editing and Deleting Existing Labels

    To edit an existing label, click on the label in the plot. The label editor dialog should be displayed. You can delete the label from the label editor dialog by clicking the Delete button.

    Moving Labels

    To move an existing label in label editor mode, simply drag the label to the desired location, anywhere within the plot.

    Data Mode

    Data mode allows precise viewing of the data points use in a plotted data object. To toggle data mode, select Data Mode from the Plots menu. Now, when the cursor is moved over a plot, a coloured dot will indicate the closest data point to the cursor, as shown in the screenshot below. The status bar will display the coordinates of the data point (in terms of the x and y vectors used to plot the data object) in status bar at the lower right corner of the Kst window. The status bar will also display the x, y, and z coordinates of any visible image. If images overlap, only the coordinates of the topmost image will be displayed. Note that all zooming functions are still available while in data mode.


    Top of Plot Dialog

    Tip

    If the status bar is not visible, make sure Show Statusbar is checked in the Status menu.

    Zooming and Scrolling

    Zooming and scrolling in plots is easy and intuitive with Kst. The following sections explain the different zooming and scrolling modes.

    Mouse Zoom Modes

    To access the different zoom modes, choose one of XY Mouse Zoom, X Mouse Zoom, or Y Mouse Zoom from the Plots menu. The different modes are described below.

    XY Mouse Zoom

    In XY Mouse Zoom mode, you can zoom into a specific rectangular area of the plot by simply clicking and dragging to draw a rectangle where desired. The x and y axes of the plot will change to reflect the new scale. This mode is often useful for quickly looking at an interesting area of the plot without having to specify exact axis scales.

    X Mouse Zoom

    In X Mouse Zoom mode, the y axis is fixed. Zooming in is performed by clicking and dragging a rectangular area; however, the upper and lower limits of the rectangle will always be equal to the current upper and lower limits of the y axis. This mode is often useful for looking at a certain time range, if the x axis happens to represent a time vector.

    Tip

    You can quickly switch to X Mouse Zoom mode by holding down Ctrl. The mouse cursor will change to indicate the new mode. Releasing Ctrl will return you to the previous mouse zoom mode.

    Y Mouse Zoom

    In Y Mouse Zoom mode, the x axis is fixed. Zooming in is performed by clicking and dragging a rectangular area; however, the left and right limits of the rectangle will always be equal to the current left and right limits of the x axis. This mode is often useful for zooming in on data that is concentrated around a horizontal line.

    Tip

    You can quickly switch to Y Mouse Zoom mode by holding down Shift. The mouse cursor will change to indicate the new mode. Releasing Shift will return you to the previous mouse zoom mode.

    The Zoom Menu

    The Zoom menu can be accessed by right-clicking on a plot and selecting the Zoom submenu from the context menu. A list of zoom actions and their corresponding keyboard shortcuts will be displayed. These actions are described below.

    Zoom ActionKeyboard ShortcutDescription
    Zoom MaximumMSets both the x axis and the y axis scales so that all data points are displayed. This is equivalent to the AutoScale setting of the Plot Dialog.
    Zoom Max Spike InsensitiveSSets both the x axis and the y axis scales so that most data points are displayed. Spikes, or sudden increases or decreases in x or y values, are excluded from the plot display.
    Zoom PreviousRReturns to the most recent zoom setting used.
    Y-Zoom Mean-centeredASets the Y axis so that the mean of the y values in the plot is centered vertically. The actual zoom level is not changed.
    X-Zoom MaximumCtrl+MSets the x axis scale such that the x values for all data points are between the minimum and maximum of the x axis. The y axis scale is unaltered.
    X-Zoom OutShift+RightFor a non-logarithmic x axis, increases the length of the x axis by a factor of approximately 0.5, without changing the midpoint of the x axis. The y axis scale is unaltered.
    X-Zoom InShift+LeftFor a non-logarithmic x axis, decreases the length of the x axis by a factor of approximately 0.5, without changing the midpoint of the x axis. The y axis scale is unaltered.
    Toggle Log X AxisGEnables or disables using a logarithmic scale for the x axis.
    Y-Zoom MaximumShift+MSets the y axis scale such that the y values for all data points are between the minimum and maximum of the y axis. The x axis scale is unaltered.
    Y-Zoom OutShift+UpFor a non-logarithmic y axis, increases the length of the y axis by a factor of approximately 0.5, without changing the midpoint of the y axis. The x axis scale is unaltered.
    Y-Zoom InShift+DownFor a non-logarithmic y axis, decreases the length of the y axis by a factor of approximately 0.5, without changing the midpoint of the y axis. The x axis scale is unaltered.
    Toggle Log Y AxisLEnables or disables using a logarithmic scale for the y axis.

    Many of the zoom actions are best used in conjunction with the various mouse zoom modes.

    Match Axis

    To quickly change the axes of a plot to match those of another plot, right-click on the plot and select a different plot name from the Match Axis... menu. Both the x and y axes scales of the current plot will change to match those of the selected plot. Note that this does not permanently tie the axes scales together; changing the zoom on either plot will unmatch the axes scales again. To tie the axes scales of two or more plots together, use the Tied Zoom feature.

    The Scroll Menu

    Functions for scrolling a plot are available by right-clicking a plot and selecting the Scroll submenu from the context menu. Most scrolling functions and their keyboard shortcuts should be self-explanatory. To quickly jump to a plot marker, select Next Plot Marker (to jump right) or Previous Plot Marker (to jump left). For more information on plot markers, see the Markers section.

    Assuming non-logarithmic axis scales are used, each function scrolls the plot in the indicated direction by 0.1 of the current length of the x axis (when scrolling left or right), or 0.25 of the current length of the y axis (when scrolling up or down).

    Tip

    You can also scroll left or right in a plot by using the mouse wheel (if available).

    Tip

    To quickly go forwards or backwards along the x axis, select Back 1 Screen or Advance 1 Screen from the Range menu. The keyboard shortcuts, Ctrl+Left and Ctrl+Right respectively, can be used as well.

    Tied Zoom

    When looking at two or more related plots (for example, two curves on separate plots both dependent on the same time vector), it can sometimes be useful to zoom or scroll the plots simultaneously. This is possible using Kst's tied zoom feature. To activate tied zoom, click the small square at the top-right corner of the plots you wish to tie together. The squares will change colour to indicate the plots are tied, as shown below.


    Top of Plot Dialog

    Zooming and scrolling actions performed on one plot in a group of tied plots will be performed on on all the plots in the group. To remove a plot from the tied group, simply click on the small square at the top-right corner of the plot again. The square will become transparent to indicate that the plot is not tied.

    Tip

    To quickly tie or untie all plots (including plots in other windows), select Tied Zoom from the Plots menu, or the corresponding icon on the Kst toolbar.

    Working with Live Data

    Kst features special zooming and scrolling functions designed to make it easy to work with “live” data, or data that is being updated while Kst is running. These features are designed to be used in conjunction with the regular zooming and scrolling functions.

    Updating Plots Automatically

    To have a plot automatically update as data is being added to a data file, choose Read From End from the Range menu. The plot will automatically scroll to the right periodically, to display new data points. The update interval can be changed by selecting Configure Kst... from the Settings menu. Specify the update interval in the Plot Update Timer field.

    Pausing Plot Updates

    To pause automatic updating of plots, select Pause from the Range menu. You can still perform zooming and scrolling functions while the updating is paused. Selecting Read From End from the Range menu will resume automatic updating.

    Changing Data Sample Ranges

    To quickly change sample range settings associated with vectors, select Change Data Sample Ranges from the Range menu. Select one or more vectors, change the desired settings for the vectors, and click Apply to save the settings. These settings are a subset of those found in the Edit Vectors dialog.

    Manipulating Plot Layout

    Plots in a Kst window are arranged in layers. Each plot is positioned on one layer, and each layer contains one plot. Thus, plots can overlap, with plots in higher layers taking precedence in visibility over those in lower ones. To change the layout of plots in Kst, layout mode must be activated. Layout mode can be toggled by selecting Layout Mode from the Plots menu.

    Layout Mode Context Menu

    While layout mode is activated, right-clicking on any plot displays a modified context menu. The selections available in this menu are listed below.

    Delete

    Deletes the plot.

    Raise

    Raises the plot one layer up.

    Lower

    Lowers the plot one layer down.

    Raise to Top

    Raises the plot to the top-most layer, guaranteeing it will be visible.

    Lower to Bottom

    Lowers the plot to the bottom-most layer.

    Rename...

    Selecting this item displays a dialog box that allows the unique name of the plot to be changed.

    Move To

    Selecting a window name from this submenu moves the plot to the window with the corresponding name.

    Cleanup Layout

    Arranges the plots in the current window in a tile type pattern, with no overlap between plots. This action applies to all plots in the current window.

    Moving and Resizing Plots

    Moving and resizing plots in layout mode is analogous to moving and resizing regular windows. To move a plot, simply click anywhere on the desired plot and drag the plot. An outline of the plot will appear, indicating where the plot will be placed. You can drag plots anywhere within the current window. To resize a plot, move the mouse cursor to any edge or corner of the plot. The cursor will change to indicate that the plot can be resized. Click and drag the outline of the plot until the plot is the desired shape and size.

    Selecting Multiple Plots and Grouping Plots

    Two or more plots can be selected together in layout mode. To select the plots, hold down the Shift key and either sequentially click on each plot you wish to select, or drag to draw a dotted rectangle around a group of plots. The selected plots will be indicated by a gray border around each plot:


    Multiple Selected Plots

    Multiple selected plots can be moved simultaneously by dragging any single plot that is part of the selection (note that resizing any plot in the selection removes the selection). In addition, the layout mode context menu contains three additional items when multiple plots are selected. These items are described below.

    Make Same

    Resizes all the selected plots in the chosen dimension(s) to match the dimension(s) of the plot from which the context menu was invoked. For example, right-clicking on a plot in the group and selecting Width from the Make Same submenu will match the width of all the plots in the group to the width of the first plot. If Size is chosen, both the width and height of each plot in the selection will change.

    Align

    Aligns all plots in the selection to the plot directly underneath the context menu. Select from Left, Right, Top, or Bottom.

    Pack (submenu)

    The Pack submenu contains two functions. Pack Horizontally divides the entire width of the plot group evenly between the individual plot widths, while Pack Vertically divides the entire height of the plot group evenly between the individual plot heights. Packing plots usually results in a staggered or “checkered” pattern. To align the plots in a grid, use the Cleanup Layout function of the layout mode context menu.

    Group Objects

    Groups all the selected plots together. A group of plots is indicated by a blue outline around the entire group. The layout of the plots within a group cannot be altered, but a group of plots can be resized or moved as a whole in the same way the layout of a single plot can be changed. Grouped plots remain grouped even when layout mode is exited, so the Maximize or Delete functions of the plot context menu can be used on an entire group.

    To ungroup a group of plots, simply right-click on the group and select Ungroup.

    Working with Windows

    Kst has a flexible window layout that makes use of Kmdi. Organizing plots on different windows allows for efficient viewing and manipulating of plots.

    MDI Modes

    There is a choice of four different MDI (Multi-Document Interface) modes available. To select a mode, choose one of the menu items from the MDI Mode... submenu of the Window menu. The selected MDI mode will take effect immediately. The sections below provide more information on each mode.

    Top Level Mode

    Top level mode is the mode traditionally used by other KDE applications. In this mode, the parent window (the window containing all the main menus, toolbars, and status bars) is a separate window from the plot windows. The plot windows, while still functionally tied to the main window, appear as separate windows on the desktop.

    To quickly switch between plot windows in top level mode, you can click the buttons on the parent window, as shown below.


    Switching windows in top level mode

    Childframe Mode

    In childframe mode, all the plot windows appear inside the main Kst window and can be individually resized. Each plot window contains buttons for minimizing, maximizing, closing, and docking themselves. The main Kst window also contains functions for arranging the plot windows. The following lists the functionality of the buttons located in the top right corner of each plot window:

    Undocks the plot window. An undocked window is not contained within the main Kst window, but is located directly on the desktop.

    Tip

    You can also undock or dock a window by selecting its name from the Dock/Undock submenu of the Window menu. This is also the only way to dock an undocked window.

    Minimizes the plot window. Since the plot window is contained within the main Kst window, clicking this button will minimize the window to a titlebar within the Kst window.

    Maximizes the plot window. The plot window will take up the entirety of the main Kst window.

    Closes the plot window.

    To quickly switch between plot windows in childframe mode, you can click the buttons on the parent window, as shown below.


    Switching windows in top level mode

    To easily organize the plot windows within the main Kst window, you can choose one of the tiling functions from the Tile... submenu of the Window menu. These functions are described below.

    Cascade Windows

    Cascades the windows starting from the top left corner, maintaining the original window sizes.

    Cascade Windows

    Cascades the windows starting from the top left corner, but resizes each window so that the bottom right corner of each window reaches the bottom right of the main Kst window.

    Expand Vertically

    Resizes each window to its maximum height. The widths of the windows are not changed.

    Expand Horizontally

    Resizes each window to its maximum width. The heights of the windows are not changed.

    Tile Non-overlapped

    Arranges the windows in a tile pattern, with no windows overlapping and each window being as close to a square as possible.

    Tile Overlapped

    Arranges the windows in three or four stacks, depending on the number of windows and the main Kst window size.

    Tile Vertically

    Arranges the windows in a tile pattern, with each window having maximum height and no windows overlapping.

    Tab Page Mode

    Tab page mode arranges each plot window on a separate tab within the main Kst window. In this mode, the plot windows are not independently resizeable or moveable—they conform to the size and shape of the main Kst window.

    To switch between plot windows in tab page mode, you can click on the tabs corresponding to each window, as shown below.


    Switching windows in tab page mode

    IDEAl Mode

    IDEAl mode seems to be identical to tab page mode.

    Creating and Deleting Windows

    New windows in Kst can be created in a number of ways. To create a new, empty, window, select New Window from the File menu. You will be prompted for a unique name for the new window. You can also create a new window while creating a new plottable data object. See Placement for the specific details.

    To delete an existing window, simply select Close from the Window menu. To delete all current windows in Kst, select Close All from the Window menu. By default, Kst prompts for confirmation before closing any window. This behaviour can be changed by selecting Configure Kst... from the Settings menu and clicking on Prompt before closing windows.

    Important

    When a window is deleted, all plots within that window are deleted as well. However, data objects, such as curves, are not deleted.

    Moving Plots Between Windows

    To move a plot from one window to another, you can use the Move To function of the layout mode context menu.

    Chapter 4. Saving and Printing

    Kst provides various methods of saving and exporting data and plots. These methods are described below.

    Saving Plot Definitions

    A plot definition is essentially a capture of a Kst session. It contains all the plots, data objects, and plot layouts that are present at the time of saving.

    To save a plot definition, simply select Save or Save As... (depending on whether or not you wish to save to a new file) from the File menu. Browse to the location you wish to save the plot definition, enter a filename, and click Save. The plot definition will be saved as a *.kst file.

    Exporting Vectors and Plots

    Vectors and plots in Kst can be exported to files. This can be useful, for example, in capturing plots of live data or using generated vectors in a different application.

    Exporting Vectors

    To export or save a vector to a file, select Save Vectors to Disk... from the File menu. The vector will be saved as an ASCII data file. The single column of the file will contain the elements of the selected vector. See below for an example of an exported vector.

    3776
    5380
    5245
    2942
    1861
    2424
    2520
    1868
    1736
    1736
    1174
    499
    

    Exporting Plots

    To export a Kst plot to a graphics file, select Export to Graphics File... from the File menu. The following dialog box will appear.


    Export to Graphics File

    The following settings and options are available when saving:

    Save location

    The path to the graphics file. Enter a location manually, or click the button to right of the text box to browse to a location.

    File Format

    The format to use for the saved graphics file. PNG is suggested if you are not sure which format to use.

    Size

    Select the dimensions, in pixels, of the graphic. Check the Square option if you wish for the length and width of the graphic to be equal.

    Windows

    Select whether to export only the plots in the current window, or all plots. If All is selected, one graphics file will be created for each window, each with filename file_n.fmt, where file is the filename specified in Save location, n is an index number assigned to each window, and fmt is an extension representing the selected file format.

    Autosave

    Check this option if you want Kst to automatically save the plot to the specified file on a specified time interval.

    Save interval

    The time interval used to perform autosave, in seconds.

    Click Save Once to immediately perform a save with the specified options and settings. Click Close to close the dialog box (autosave will still be performed at the specified intervals, if selected).

    Printing

    To print all the plots in the current window, select Print... from the File menu. A standard KDE print dialog will be displayed. There are currently no options to select for printing. The printed page will be in landscape orientation and contain the arrangement of plots in the current window. A footer containing the page number, window name, and current date is included as well.

    Chapter 5. Event Monitoring

    An event monitor data object essentially keeps track of one or more vectors or scalars, and performs a specified action when a specified condition involving the vectors or scalars is true. Event monitors are usually used in conjunction with “live”, or streaming data. For example, an event monitor could be created to monitor whether or not elements of a data vector representing temperature exceed a predefined value.

    Event Monitor Dialog

    The following is a screenshot of the window displayed when creating or editing events. Explanations of the settings are listed below.


    Event Monitor Window

    Expression

    The condition to monitor for, along with other event properties, can be modified in this section.

    Operators

    A list of available operators. Choosing an operator from the list inserts the operator at the current insertion point in the Expression text box.

    Vectors

    A list of the current vector objects in Kst. Choosing a vector from the list inserts the vector at the current insertion point in the Expression text box.

    Scalars

    A list of the available scalar values. This list is composed of both the scalar values in the current Kst session as well as some built-in constants. Choosing a scalar from the list inserts the scalar at the current insertion point in the Expression text box.

    Expression

    The expression to monitor. You may type directly in this textbox, or select items to insert using the above drop-down lists. Ensure that the expression entered in this textbox is a boolean expression (i.e. it evaluates to either true or false). This usually entails using an equality or inequality in the expression. Note that vectors entered in the textbox will be monitored according to their individual elements.

    Whenever this expression is true, the event will be triggered. The action taken upon an event trigger depends on the settings specified in the next two sections.

    Description

    This textbox is used to store a short description of the event. The description is primarily available as a method for keeping track of multiple events. You can enter any text you wish in this textbox.

    Kst Debug Log

    This section specifies settings for entries added to the Kst debug log when events are triggered.

    Log as:

    Enable this checkbox to have entries added to the Kst debug log when this event is triggered. There are three types of entries in the debug log—notices, warnings, and errors. Select the desired type of entry using the corresponding radio button.

    E-Mail Notification

    In this section, settings for sending e-mail notifications of event triggers can be specified.

    Notify

    Enable this checkbox to have Kst send e-mail notifications to the specified address when this event is triggered. Also enter in the email address you would like to appear in the “From” field of the email in the Sender textbox.

    ELOG

    Kst supports adding entries to an ELOG logbook upon event triggers. This can be useful for remotely monitoring live data, or for obtaining summaries of event activity.

    Notify

    Selecting this checkbox enables ELOG logging functionality for this event monitor. Click Configure... to specify server and logging settings.

    The ELOG Extension

    The ELOG extension allows event monitors to create logbook entries on a server running the Electronic Logbook (ELOG) application. The created logbook entries can be used, for example, to remotely monitor Kst events or to produce periodical reports on data. For information on configuring and maintaining an ELOG server, please see the official ELOG Homepage. To enable the ELOG extension in Kst, select Extensions... from the Settings menu and ensure that “ELOG Extension” is checked.

    Server and Logging Settings

    Server and logging settings should be configured if ELOG functionality is enabled for an event monitor object. To configure logging settings, click the Configure... button in the ELOG section of the Event Monitor dialog. The ELOG Event Entry dialog should be displayed:


    Event Monitor Logging Settings

    Use the three checkboxes at the bottom to select the type of information to be logged. Include Kst capture specifies that a screen capture of the currently active window should be included in the entry. Include Kst configuration file specifies that *.kst save file should be attached to the entry. Finally, if Include Kst debugging information is checked, a copy of the debug log will be attached to the entry as well.

    Additional fields will appear in this dialog once ELOG server settings are configured. To customize ELOG server settings, click the Configuration... button. The following dialog should be displayed:


    Event Monitor Server Settings

    Descriptions of the settings in this dialog follow.

    Configuration, Save, and Load

    The Configuration drop down list contains a list of saved ELOG server configurations. To load a set of configuration settings, select an item from the list and click the Load button. To save the current configuration settings in this dialog into a slot, select the desired slot and click the Save button.

    Caution

    Saving settings into a slot overwrites any existing settings in that slot.

    IP address and Port number

    Enter the IP address of the machine running the ELOG server application. The port number that the ELOG server listens on is configurable through the server, but by default it is 8080, so if you are unsure, enter 8080 as the port number.

    Logbook

    Each ELOG server can contain one or more logbooks, so the name of the logbook to write entries to must be specified. Ensure that the spelling of the logbook is correct.

    User name, User password, and Write password

    Depending on the how the ELOG server application is configured, these settings may or may not be necessary. If they are, enter the correct login credentials in the appropriate textboxes.

    Capture size

    Use this list box to select the size, in pixels, of the Kst screen capture to attach (if specified).

    Submit as HTML text

    If this checkbox is selected, HTML tags may be used in the logbook entry.

    Suppress e-mail notification

    If the logbook is configured to send e-mail notifications of new entries, selecting this checkbox will disable the notifications. Note that this option is not related to Kst's own e-mail notification setting for event monitors.

    Click the Apply button to apply the entered settings. Click Update to update the ELOG Event Entry dialog (the previous dialog). Additional fields should appear in the ELOG Event Entry dialog. These fields are unique to the selected logbook. Once you are satisfied with the settings, the Test button can be used to send a test logbook entry. Click Close to exit the dialog.

    Chapter 6. Plugins, Fits, and Filters

    Plugins provide added functionality to Kst. By default, Kst comes packaged with an extensive selection of built-in plugins. In addition, a simple and consistent interface allows for easy creation of 3rd-party plugins. Fits and Filters are simply subsets of the set of plugins, and thus behave identically to plugins, with the exception of additional convenience dialog functionality accessible from the plot context menu.

    Adding and Removing Plugins

    By default, the built-in plugins are stored in /usr/lib/kde3/kstplugins/ (this directory may vary, depending on where you installed Kst). The Plugin Manager can be used to add and remove plugins. It can be acccessed by selecting Plugins... from the Settings menu. A list of the currently installed plugins is displayed in the Plugin Manager.

    To add a plugin, click the Install... button. Browse to the directory containing both the plugin specification file (*.xml) and the object file (*.o). Click OK, and the plugin should be installed.

    To remove a plugin, simply highlight the plugin in the Plugin Manager and click Remove. You will be prompted for confirmation.

    To quickly refresh the list of plugins displayed in the Plugin Manager, click Rescan. Doing so will remove any plugins no longer present in their specified paths, and add any new plugins in the default plugins directory.

    Built-in Plugins

    To date, there are more than 25 built-in plugins available in Kst that perform functions from taking cross correlations of two vectors to producing periodograms of a data set. The settings window for every plugin consists of two main sections—an input section and an output section. Each section is composed of a set of scalars and/or vectors. The following screenshot shows the settings window for a typical plugin. The only difference between the different plugins is the set of inputs and outputs, and the mechanism for deriving the outputs from the inputs.


    Plugins Windowpluginswindow

    The following sections describe the purpose, key algorithms or formulas used to perform calculations, and inputs and outputs for each plugin. Note that fitting and filtering plugins are included in the following sections.

    Autocorrelation

    The autocorrelation plugin calculates correlation values between a series (vector) and a lagged version of itself, using lag values from floor(-(N-1)/2) to floor((N-1)/2), where N is the number of points in the data set. The time vector is not an input as it is assumed that the data is sampled at equal time intervals. The correlation value r at lag k is:

    Autocorrelation formula

    Inputs

    X Array (vector)

    The array x of values to calculate correlation values for.

    Outputs

    Step Number (vector)

    The array of step, or lag values.

    Correlation Value (vector)

    The array of correlation values calculated using the corresponding step number in the Step Number vector.

    Bin

    The bin plugin bins elements of a single data vector into bins of a specified size. The value of each bin is the mean of the elements belonging to the bin. For example, if the bin size is 3, and the input vector is [9,2,7,3,4,74,5,322,444,2,1], then the outputted bins would be [6,27,257]. Note that any elements remaining at the end of the input vector that do not form a complete bin (in this case, elements 2 and 1), are simply discarded.

    Inputs

    Input Vector (vector)

    The vector to bin.

    Bin Size (scalar)

    The size to use for each bin.

    Outputs

    Bins (vector)

    The array of means for each bin.

    Butterworth band-pass

    The Butterworth band-pass plugin filters a set of data by calculating the Fourier transform of the data and recalculating the the frequency responses using the following formula

    Autocorrelation formula

    where f is the frequency, fc is the low frequency cutoff, b is the bandwidth of the band to pass, and n is the order of the Butterworth filter. The inverse Fourier transform is then calculated using the new filtered frequency responses.

    Inputs

    X Array (vector)

    The array of values to filter.

    Order (scalar)

    The order of the Butterworth filter to use.

    Low cutoff frequency (scalar)

    The low cutoff frequency of the Butterworth band pass filter.

    Band width (scalar)

    The width of the band to pass. This should be the difference between the desired high cutoff frequency and the low cutoff frequency.

    Outputs

    X Filtered (vector)

    The array of filtered data values.

    Butterworth band-stop

    The Butterworth band-stop plugin filters a set of data by calculating the Fourier transform of the data and recalculating the the frequency responses using the following formula

    Autocorrelation formula

    where f is the frequency, fc is the low frequency cutoff, b is the bandwidth of the band to stop, and n is the order of the Butterworth filter. The inverse Fourier transform is then calculated using the new filtered frequency responses.

    Inputs

    X Array (vector)

    The array of values to filter.

    Order (scalar)

    The order of the Butterworth filter to use.

    Low cutoff frequency (scalar)

    The low cutoff frequency of the Butterworth band stop filter.

    Band width (scalar)

    The width of the band to stop. This should be the difference between the desired high cutoff frequency and the low cutoff frequency.

    Outputs

    X Filtered (vector)

    The array of filtered data values.

    Butterworth high-pass

    The Butterworth high-pass plugin filters a set of data by calculating the Fourier transform of the data and recalculating the the frequency responses using the following formula

    Autocorrelation formula

    where f is the frequency, fc is the high frequency cutoff, and n is the order of the Butterworth filter. The inverse Fourier transform is then calculated using the new filtered frequency responses.

    Inputs

    X Array (vector)

    The array of values to filter.

    Order (scalar)

    The order of the Butterworth filter to use.

    Cutoff frequency (scalar)

    The cutoff frequency of the Butterworth high pass filter.

    Outputs

    X Filtered (vector)

    The array of filtered data values.

    Butterworth low-pass

    The Butterworth low-pass plugin filters a set of data by calculating the Fourier transform of the data and recalculating the the frequency responses using the following formula

    Autocorrelation formula

    where f is the frequency, fc is the low frequency cutoff, and n is the order of the Butterworth filter. The inverse Fourier transform is then calculated using the new filtered frequency responses.

    Inputs

    X Array (vector)

    The array of values to filter.

    Order (scalar)

    The order of the Butterworth filter to use.

    Cutoff frequency (scalar)

    The cutoff frequency of the Butterworth low pass filter.

    Outputs

    X Filtered (vector)

    The array of filtered data values.

    Chop

    The chop plugin takes an input vector and divides it into two vectors. Every second element in the input vector is placed in one output vector, while all other elements from the input vector are placed in another output vector.

    Inputs

    Array (vector)

    The array of values to perform the chop on.

    Outputs

    Odd Array (vector)

    The array containing the odd part of the input array (i.e. it contains the first element of the input array).

    Even Array (vector)

    The array containing the even part of the input array (i.e. it does not contain the first element of the input array).

    Difference Array (vector)

    The array containing the elements of the odd array minus the respective elements of the even array.

    Index Array (vector)

    An index array the same length as the other three output arrays.

    Convolution

    The convolution plugin generates the convolution of one vector with another. The convolution of two functions f and g is given by:

    The order of the vectors does not matter, since f*g=g*f. In addition, the vectors do not need to be of the same size, as the plugin will automatically extrapolate the smaller vector.

    Inputs

    Array One (vector)

    One of the pair of arrays to take the convolution of.

    Array Two (vector)

    One of the pair of arrays to take the convolution of.

    Outputs

    Convolved (vector)

    The convolution of the two input vectors.

    Crosscorrelation

    The crosscorrelation plugin calculates correlation values between two series (vectors) x and y, using lag values from floor(-(N-1)/2) to floor((N-1)/2), where N is the number of elements in the longer vector. The shorter vector is padded to the length of the longer vector using 0s. The time vector is not an input as it is assumed that the data is sampled at equal time intervals. The correlation value r at lag k is:

    crosscorrelation formula

    Inputs

    X Array (vector)

    The array x used in the cross-correlation formula.

    Y Array (vector)

    The array y used in the cross-correlation formula.

    Outputs

    Step Number (vector)

    The array of step, or lag values.

    Correlation Value (vector)

    The array of correlation values calculated using the corresponding step number in the Step Number vector.

    Deconvolution

    The deconvolution plugin generates the deconvolution of one vector with another. Deconvolution is the inverse of convolution. Given the convolved vector h and another vector g, the deconvolution f is given by:

    The vectors do not need to be of the same size, as the plugin will automatically extrapolate the shorter vector. The shorter vector is assumed to be the response function g.

    Inputs

    Array One (vector)

    One of the pair of arrays to take the deconvolution of.

    Array Two (vector)

    One of the pair of arrays to take the deconvolution of.

    Outputs

    Deconvolved (vector)

    The deconvolution of the two input vectors.

    Fit exponential weighted

    The Fit exponential weighted plugin performs a weighted non-linear least-squares fit to an exponential model:

    An initial estimate of a=1.0, =0, and b=0 is used. The plugin subsequently iterates to the solution until a precision of 1.0e-4 is reached or 500 iterations have been performed.

    Inputs

    X Array (vector)

    The array of x values for the data points to be fitted.

    Y Array (vector)

    The array of y values for the data points to be fitted.

    Weights (vector)

    The array of weights to use for the fit.

    Outputs

    Y Fitted (vector)

    The array of fitted y values.

    Residuals (vector)

    The array of residuals.

    Parameters (vector)

    The best fit parameters a, , and b.

    Covariance (vector)

    The covariance matrix of the model parameters, returned row after row in the vector.

    chi^2/nu (scalar)

    The weighted sum of squares of the residuals, divided by the degrees of freedom.

    Fit exponential

    The Fit exponential plugin is identical in function to the Fit exponential weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist.

    Fit gaussian weighted

    The Fit gaussian weighted plugin performs a weighted non-linear least-squares fit to a Gaussian model:

    An initial estimate of a=(maximum of the y values), =(mean of the x values), and =(the midpoint of the x values) is used. The plugin subsequently iterates to the solution until a precision of 1.0e-4 is reached or 500 iterations have been performed.

    Inputs

    X Array (vector)

    The array of x values for the data points to be fitted.

    Y Array (vector)

    The array of y values for the data points to be fitted.

    Weights (vector)

    The array of weights to use for the fit.

    Outputs

    Y Fitted (vector)

    The array of fitted y values.

    Residuals (vector)

    The array of residuals.

    Parameters (vector)

    The best fit parameters , , and a.

    Covariance (vector)

    The covariance matrix of the model parameters, returned row after row in the vector.

    chi^2/nu (scalar)

    The weighted sum of squares of the residuals, divided by the degrees of freedom.

    Fit gaussian

    The Fit gaussian plugin is identical in function to the Fit gaussian weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist.

    Fit gradient weighted

    The gradient weighted plugin performs a weighted least-squares fit to a straight line model without a constant term:

    The best-fit is found by minimizing the weighted sum of squared residuals:

    for b, where wi is the weight at index i.

    Inputs

    X Array (vector)

    The array of x values for the data points to be fitted.

    Y Array (vector)

    The array of y values for the data points to be fitted.

    Weights (vector)

    The array containing weights to be used for the fit.

    Outputs

    Y Fitted (vector)

    The array of y values for the points representing the best-fit line.

    Residuals (vector)

    The array of residuals, or differences between the y values of the best-fit line and the y values of the data points.

    Parameters (vector)

    The parameter b of the best-fit.

    Covariance (vector)

    The estimated covariance matrix, returned row after row, starting with row 0.

    Y Lo (vector)

    The corresponding value in Y Fitted minus the standard deviation of the best-fit function at the corresponding x value.

    Y Hi (vector)

    The corresponding value in Y Fitted plus the standard deviation of the best-fit function at the corresponding x value.

    chi^2/nu (scalar)

    The value of the sum of squares of the residuals, divided by the degrees of freedom.

    Fit gradient

    The Fit linear plugin is identical in function to the Fit gradient weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist.

    Fit linear weighted

    The Fit linear weighted plugin performs a weighted least-squares fit to a straight line model:

    The best-fit is found by minimizing the weighted sum of squared residuals:

    for a and b, where wi is the weight at index i.

    Inputs

    X Array (vector)

    The array of x values for the data points to be fitted.

    Y Array (vector)

    The array of y values for the data points to be fitted.

    Weights (vector)

    The array containing weights to be used for the fit.

    Outputs

    Y Fitted (vector)

    The array of y values for the points representing the best-fit line.

    Residuals (vector)

    The array of residuals, or differences between the y values of the best-fit line and the y values of the data points.

    Parameters (vector)

    The parameters a and b of the best-fit.

    Covariance (vector)

    The estimated covariance matrix, returned row after row, starting with row 0.

    Y Lo (vector)

    The corresponding value in Y Fitted minus the standard deviation of the best-fit function at the corresponding x value.

    Y Hi (vector)

    The corresponding value in Y Fitted plus the standard deviation of the best-fit function at the corresponding x value.

    chi^2/nu (scalar)

    The value of the sum of squares of the residuals, divided by the degrees of freedom.

    Fit linear

    The Fit linear plugin is identical in function to the Fit linear weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist.

    Fit lorentzian weighted

    The Fit lorentzian weighted plugin performs a weighted non-linear least-squares fit to a Lorentzian model:

    An initial estimate of a=(maximum of the y values), x0=(mean of the x values), and =(the midpoint of the x values) is used. The plugin subsequently iterates to the solution until a precision of 1.0e-4 is reached or 500 iterations have been performed.

    Inputs

    X Array (vector)

    The array of x values for the data points to be fitted.

    Y Array (vector)

    The array of y values for the data points to be fitted.

    Weights (vector)

    The array of weights to use for the fit.

    Outputs

    Y Fitted (vector)

    The array of fitted y values.

    Residuals (vector)

    The array of residuals.

    Parameters (vector)

    The best fit parameters x0, , and a.

    Covariance (vector)

    The covariance matrix of the model parameters, returned row after row in the vector.

    chi^2/nu (scalar)

    The weighted sum of squares of the residuals, divided by the degrees of freedom.

    Fit lorentzian

    The Fit lorentzian plugin is identical in function to the Fit lorentzian weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist.

    Fit polynomial weighted

    The Fit polynomial weighted plugin performs a weighted least-squares fit to a polynomial model:

    where n is the degree of the polynomial model.

    Inputs

    X Array (vector)

    The array of x values for the data points to be fitted.

    Y Array (vector)

    The array of y values for the data points to be fitted.

    Weights (vector)

    The array of weights to use for the fit.

    Order (scalar)

    The order, or degree, of the polynomial model to use.

    Outputs

    Y Fitted (vector)

    The array of fitted y values.

    Residuals (vector)

    The array of residuals.

    Parameters (vector)

    The best fit parameters c0, c1,..., cn.

    Covariance (vector)

    The covariance matrix of the model parameters, returned row after row in the vector.

    chi^2/nu (scalar)

    The weighted sum of squares of the residuals, divided by the degrees of freedom.

    Fit polynomial

    The Fit polynomial plugin is identical in function to the Fit polynomial weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist.

    Fit sinusoid weighted

    The Fit sinusoid weighted plugin performs a least-squares fit to a sinusoid model:

    where T is the specified period, and n=2+2H, where H is the specified number of harmonics.

    Inputs

    X Array (vector)

    The array of x values for the data points to be fitted.

    Y Array (vector)

    The array of y values for the data points to be fitted.

    Weights (vector)

    The array of weights to use for the fit.

    Harmonics (scalar)

    The number of harmonics of the sinusoid to fit.

    Period (scalar)

    The period of the sinusoid to fit.

    Outputs

    Y Fitted (vector)

    The array of fitted y values.

    Residuals (vector)

    The array of residuals.

    Parameters (vector)

    The best fit parameters c0, c1,..., cn.

    Covariance (vector)

    The covariance matrix of the model parameters, returned row after row in the vector.

    chi^2/nu (scalar)

    The weighted sum of squares of the residuals, divided by the degrees of freedom.

    Fit sinusoid

    The Fit sinusoid plugin is identical in function to the Fit sinusoid weighted plugin with the exception that the weight value wi is equal to 1 for all index values i. As a result, the Weights (vector) input does not exist.

    Interpolation Akima spline

    The Interpolation Akima spline plugin generates a non-rounded Akima spline interpolation for the supplied data set, using natural boundary conditions.

    Inputs

    X Array (vector)

    The array of x values of the data points to generate the interpolation for.

    Y Array (vector)

    The array of y values of the data points to generate the interpolation for.

    X' Array (vector)

    The array of x values for which interpolated y values are desired.

    Outputs

    Y Interpolated (vector)

    The interpolated y values.

    Interpolation Akima spline periodic

    The kstinterp akima periodic plugin generates a non-rounded Akima spline interpolation for the supplied data set, using periodic boundary conditions.

    Inputs

    X Array (vector)

    The array of x values of the data points to generate the interpolation for.

    Y Array (vector)

    The array of y values of the data points to generate the interpolation for.

    X' Array (vector)

    The array of x values for which interpolated y values are desired.

    Outputs

    Y Interpolated (vector)

    The interpolated y values.

    Interpolation cubic spline

    The Interpolation cubic spline plugin generates a cubic spline interpolation for the supplied data set, using natural boundary conditions.

    Inputs

    X Array (vector)

    The array of x values of the data points to generate the interpolation for.

    Y Array (vector)

    The array of y values of the data points to generate the interpolation for.

    X' Array (vector)

    The array of x values for which interpolated y values are desired.

    Outputs

    Y Interpolated (vector)

    The interpolated y values.

    Interpolation cubic spline periodic

    The Interpolation cubic spline periodic plugin generates a cubic spline interpolation for the supplied data set, using periodic boundary conditions.

    Inputs

    X Array (vector)

    The array of x values of the data points to generate the interpolation for.

    Y Array (vector)

    The array of y values of the data points to generate the interpolation for.

    X' Array (vector)

    The array of x values for which interpolated y values are desired.

    Outputs

    Y Interpolated (vector)

    The interpolated y values.

    Interpolation linear

    The Interpolation linear plugin generates a linear interpolation for the supplied data set.

    Inputs

    X Array (vector)

    The array of x values of the data points to generate the interpolation for.

    Y Array (vector)

    The array of y values of the data points to generate the interpolation for.

    X' Array (vector)

    The array of x values for which interpolated y values are desired.

    Outputs

    Y Interpolated (vector)

    The interpolated y values.

    Interpolation polynomial

    The Interpolation polynomial plugin generates a polynomial interpolation for the supplied data set. The number of terms in the polynomial used is equal to the number of points in the supplied data set.

    Inputs

    X Array (vector)

    The array of x values of the data points to generate the interpolation for.

    Y Array (vector)

    The array of y values of the data points to generate the interpolation for.

    X' Array (vector)

    The array of x values for which interpolated y values are desired.

    Outputs

    Y Interpolated (vector)

    The interpolated y values.

    Noise Addition

    The Noise addition plugin adds a Gaussian random variable to each element of the input vector. The Gaussian distribution used has a mean of 0 and the specified standard deviation. The probability density function of a Gaussian random variable is:

    Inputs

    Array (vector)

    The array of elements to which random noise is to be added.

    Sigma (scalar)

    The standard deviation to use for the Gaussian distribution.

    Outputs

    Output Array (vector)

    The array of elements with Gaussian noise added.

    Periodogram

    The periodogram plugin produces the periodogram of a given data set. One of two algorithms is used depending on the size of the data set—a fast algorithm is used if there are greater than 100 data points, while a slower algorithm is used if there are less than or equal to 100 data points.

    Inputs

    Time Array (vector)

    The array of time values of the data points to generate the interpolation for.

    Data Array (vector)

    The array of data values, dependent on the time values, of the data points to generate the interpolation for.

    Oversampling factor (scalar)

    The factor to oversample by.

    Average Nyquist frequency factor (scalar)

    The average Nyquist frequency factor.

    Outputs

    Frequency (vector)

    The frequency vector.

    Periodogram (vector)

    The frequency response vector for the periodogram.

    Statistics

    The statistics plugin calculates statistics for a given data set. Most of the output scalars are named such that the values they represent should be apparent. Standard formulas are used to calculate the statistical values.

    Inputs

    Data Array (vector)

    The array of data values to calculate statistics for.

    Outputs

    Mean (scalar)

    The mean of the data values.

    Minimum (scalar)

    The minimum value found in the data array.

    Maximum (scalar)

    The maximum value found in the data array.

    Variance (scalar)

    The variance of the data set.

    Standard deviation (scalar)

    The standard deviation of the data set.

    Median (scalar)

    The median of the data set.

    Absolute deviation (scalar)

    The absolute deviation of the data set.

    Skewness (scalar)

    The skewness of the data set.

    Kurtosis (scalar)

    The kurtosis of the data set.

    Chapter 7. The Toolbar and Keyboard Shortcuts

    This chapter describes miscellaneous time-saving and convenience features available in Kst.

    The Toolbar

    The toolbar provides one-click access to commonly used menu functions in Kst. To toggle the toolbar, select Show Toolbar from the Settings menu.

    The Toolbar Menu

    The toolbar menu, accessible by right-clicking anywhere on the toolbar, contains functions for modifying the layout, appearance, and behaviour of the toolbar. The three submenus available are described below.

    Orientation

    The Orientation submenu contains layout options for the toolbar.

    Top, Left, Right, and Bottom

    Docks the toolbar at the corresponding edge of the Kst window.

    Flat

    Hides the toolbar and turns it into a slim bar at the top of Kst window. To unhide the toolbar, click on the “gripper” that is still visible.

    You can also move the toolbar by dragging the gripper on the edge of the toolbar. Dragging the toolbar close to an edge of the Kst window docks it. Dragging the toolbar anywhere else turns it into a floating toolbar.

    Text Position

    The Text Position submenu specifies if and how text and icons should be displayed on the toolbar.

    Icons Only

    Does not display any text labels and only displays icons. However, the text for each icon is still available as a tooltip associated with the icon (viewable by momentarily holding the cursor of the icon).

    Text Only

    Does not display any icons on the toolbar, but displays all text labels.

    Text Alongside Icons

    Displays all icons. Text labels are displayed to the right of the icons.

    Text Under Icons

    Displays all icons. Text labels are displayed underneath the icons.

    Icon Size

    The Icon Size submenu specifies the size of the icons on the toolbar. Select a size from the submenu, or select Default to use the default size (usually the same as Medium). The options in this menu do not have any effect if Text Only is selected for Text Position.

    Custom Shortcut Keys

    You can create custom shortcut keys to make working in Kst more efficient. To modify the shortcut keys, select Configure Shortcuts... from the Settings menu. The following dialog will be displayed.


    Configure Shortcuts Window

    A list of available actions and their associated shortcuts are shown in the dialog. Each action is allowed two shortcuts—a primary shortcut and an alternate shortcut. Either shortcut can be used at any time. To define or change a shortcut for an action, simply highlight the appropriate row in the shortcut list. Under Shortcut for Selected Action, there are three choices:

    None

    Select this option to disable any shortcut keys for the selected action.

    Default

    Select this option to use the default shortcut key(s) for the selected action. Note that not all actions have default shortcuts defined.

    Custom

    Select this option to define a custom shortcut for the selected action.

    If you select the Custom option, the Define Shortcut dialog will appear (alternatively, you can also click on the key-shaped button to open the dialog).


    Define Shortcut Window

    By default, the Auto-close option is checked, so once a key combination is entered, the key combination will be automatically saved and the dialog closed. You can uncheck this option if you wish to experiment with the dialog.

    To define a key combination, select Primary or Alternate. If you wish to define a key sequence, check the Multi-key option. Now enter the key combination or sequence to be used for this action. Click OK when you are done.

    Tip

    When using shortcuts defined with the multi-key option, a small menu is displayed after the first key of the shortcut is pressed, showing the possible shortcut key completions. Pressing additional keys of the shortcut further filters the list. This list can be a useful reminder of the defined shortcuts.

    Note

    The action associated with a multi-key shortcut is performed as soon as only one action matches the keys pressed so far. For example, if a multi-key shortcut of A B C is defined, and no other multi-key shortcuts are defined, the action associated with the shortcut will be performed as soon as A is pressed.

    Chapter 8. Licensing

    This documentation is licensed under the terms of the GNU Free Documentation License.

    Appendix A. Command Line Usage and Examples

    Barth Netterfield <kst@omega.astro.utoronto.ca>

    A typical use of kst is from the command line to make X-Y plots of data files. kst can read ascii data, or readdata compatible binary files.

    Command Line Synopsis

    The options are:

    kst [Qt-options] [KDE-options] [options] [file...]

    [file...]

    A .kst file, or one or more data files. Supported formats are ASCII columns, BOOMERANG frame files, or BLAST dirfile files. A .kst files stores all options that can be set by other flags. The following flags can be used to override the options set in the .kst file: -F datafile, -n NS, -s NS, -f F0, -a. The rest can not be overridden. If an override flag is given, it is applied to all vectors in the plot.

    ASCII data from stdin can be plotted by including "stdin" in the list [file...].

    -y Y

    The source for the Y axis data. For ASCII files, this is the column. For binary files, this is the field name. To plot multiple curves, this may be specified multiple times. The same source file, sample ranges, and X axis data are assumed.

    -e E

    Error bars for Y axis data. For ASCII file, refer to the column holding the data. For binary files use the field name. If multiple -y Y options are given, this may also be used multiple times. Individual Y entries are associated in order with multiple E entries.

    -x X

    The source for the X axis data. For ASCII files, this is the column. For readata files, this is the field name. If this option is not specified, the row number in the file is used. This option can only be given once.

    -p P

    The source for power spectra. For ASCII files, this is the column. For binary files, this is the field name. To plot power spectra of multiple curves, this may be specified multiple times. The same source file, sample ranges and fft lengths are used for all Power Spectra requested from the command line.

    -l P

    The length of the FFT used in power specra estimation is 2^P.

    -h H

    The source for histograms. For ASCII files, this is the column. For binary files, this is the field name. Multiple histograms can be defined from the command line.

    -m NC

    Used when multiple curves have been defined. Rather than plotting all curves in the same plot, plot each in its own plot,

    -f F0

    The starting frame number (for readdata files) or row (for ASCII files) to read.

    -n

    The number of frames (for readdata files) or rows (for ASCII files) to read.

    -s NS

    The number of frames or rows to skip each read. This is useful when working with very large data files, to speed up response and conserve memory, in the case that the data are slowly varying.

    -a

    Used in with the -s NS: rather than skipping each NS frames, average them. This provides a combination of very basic high pass filtering, and memory conservation.

    -F Datafile

    Override the file to read the data from for all vectors listed in the .kst file. Can only be used in conjunction with a kst file.

    --print psfile

    Rather than displaying the plot, export the image to a postscript file and exit. *BUG note: even though no windows are opened on screen, access to the X server is still required.*

    --png pngfile

    Rather than displaying the plot, export the image to a png file of dimensions 640x480 and exit. *BUG note: even though no windows are opened on screen, access to the X server is still required.*

    Command Line Examples

    Several examples of typical use follow.

    To plot column 1 a file (tmp.dat) of ASCII data:

    kst -y 1 tmp.dat

    To plot column 2, 3, and 4 vs. column 1 of an ASCII file, in 1 plot:

    kst -x 1 -y 2 -y 3 -y 4 tmp.dat

    To plot column 2, 3, and 4 vs. column 1 of an ASCII file, in 3 plots, arranged in 1 column:

    kst -x 1 -y 2 -y 3 -y 4 -m 1 tmp.dat

    To plot 500 rows of column 2 of an ASCII file, starting at line 100:

    kst -y 2 -f 100 -n 500 tmp.dat

    To plot the first 100,000 rows of column 2 of an ASCII file, averaging every 100 rows:

    kst -y 2 -f 0 -n 100000 -s 100 -a tmp.dat

    Appendix B. Creating Additional Plugins

    Kst has a simple and standardized interface that facilitates easy creation of additional plugins. In addition to detailing basic requirements for plugins, the following sections describe how to make use of pre-written header files to create certain types of plugins.

    Creating a Basic Plugin

    A Kst plugin consists of two files—an XML file and a shared object file.

    The XML File

    The XML file provide information about the plugin and describes its inputs and outputs. The following is an example of an XML file for a Kst plugin:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE Module SYSTEM "file:/Repository/Level2/Soft/ProC/moduledef.dtd">
    
    <module>
    
    <intro>
    <modulename name="testplugin"/>    <!-- The name of the module -->
    <author name="Rick Chern"/> <!-- The name of the author -->
    <description text="A test plugin for me"/> <!-- A description of the module -->
    <version minor="1" major="0"/>  <!-- The version number of the module -->
    <state devstate="release"/>     <!-- The development state of the module (optional)-->
    </intro>
    
    <interface>
    
    <!--inputs here-->
    <input>
    <table type="float" name="Input Vector 1" descr="The first input vector" />
    </input>
    
    <input>
    <float name="Input Scalar 1" descr="The first input scalar" />
    </input>
    
    <!--outputs here-->
    <output>
    <table type="float" name="Output Vector 1" descr="The first output vector" />
    </output>
    
    <output>
    <float name="Output Scalar 1" descr="The first output scalar" />
    </output>
    
    </interface>
    
    </module>
    

    Generally, you can use the example above as a template and modify sections to fit your needs. As can be seen from the example, the XML file consists of one module node. The module node has an intro node and an interface node. You should modify the intro node appropriately using the comments in the above XML file as guides. It is important that modulename has the name attribute set to the same name that your shared object file will use.

    The interface node describes the actual inputs and outputs of the plugin. Each input is described by an input node, and each output is described by an output node. Each input or output should have either a table or a float node as a child. The type attribute of a table must be set to "float". Note that the order of the inputs and outputs matters—the order is used to determine the index values for each input and output array of the object file, and is the same order used to display the input and output fields in the Kst plugin interface.

    Once you have completed the XML file, save it as [modulename].xml, where [modulename] is the value of the name attribute of the modulename node.

    The Shared Object File

    The shared object file contains the actual functionality of the plugin. In other words, it determines how to derive the outputs from the given inputs. The following are the requirements for the shared object file:

    • The object must export the following C linkage symbol:

      int symbol(const double *const inArrays[],
                 const int inArrayLens[],
                 const double inScalars[],
                 double *outArrays[],
                 int outArrayLens[],
                 double outScalars[])

      where symbol must be the value of the name attribute of the modulename node in the XML file. This is the only function that will be called by Kst (although you may have other functions). The following describes each argument of this function:

      const double *const inArrays[]

      The array of input arrays. Each input array corresponds to an input vector. The arrays are in the same order as the vectors are listed in the XML file, so inArrays[0] is the array representing the first input vector, inArrays[1] is the array representing the second input vector, and so on.

      const int inArraysLens[]

      The array containing array lengths for each input array. The lengths are stored in the same order as the arrays in inArrays[] (e.g. inArrayLens[0] is the length of inArrays[0]).

      const double inScalars[]

      The array of input scalars. The scalars are stored in the same order as they are listed in the XML file.

      double *outArrays[]

      The array of output arrays. Each output array corresponds to an output vector, and the arrays should be in the same order as the output vectors are listed in the XML file.

      int outArrayLens[]

      The array that should contain lengths of the output arrays. The lengths should be stored in the same order as the arrays in outArrays[].

      double outScalars[]

      The array of output scalars. The scalars should be in the same order they are listed in the XML file.

    • The function must return 0 if it executed succesfully, and -1 otherwise.

    • The code for the object file must handle unexpected inputs, such as empty input arrays (in most cases a return value of -1 would be sufficient when such situations are encountered).

    • The number and type of outputs must be exactly as specified by the XML file.

    • You will probably need to resize the arrays in outArrays[]. To do so, use the realloc() function. E.g.,

      outArrays[0]=(double*)realloc(outArrays[0], 5*sizeof(double));
      

      will allocate space for 5 doubles for outArrays[0]. Do not use any memory allocator other than realloc().

    • The input arguments must remain constant. Do not cast them to non-constant types.

    The following is an example of the shared object file source code for a simple plugin:

    #include <stdlib.h>
    
    extern "C" int testplugin(const double *const inArrays[], const int inArrayLens[],
                    const double is[],
                    double *outArrays[], int outArrayLens[],
                    double outScalars[]);
    
    int testplugin(const double *const inArrays[], const int inArrayLens[],
                    const double is[],
                    double *outArrays[], int outArrayLens[],
                    double outScalars[])
    
    //Accept 1 vector and 1 scalar. Multiply all elements of the vector by the
    //scalar, and output the resulting vector. Also output the original scalar.
    {
    	//Set the outputs
    	outArrayLens[0]=inArrayLens[0];
    
    	//resize the output arrays
    	outArrays[0]=(double*)realloc(outArrays[0], inArrayLens[0]*sizeof(double));
    
    	//multiply each element of the input vector
    	//by the scalar
    	for (int i=0; i<inArrayLens[0]; i++)
    	{
    		outArrays[0][i]=inArrays[0][i] * is[0];
    	}
    
    	//now set the output scalar
    	outScalars[0]=is[0];
    
    	return 0;
    }
    

    Compiling the Plugin

    If you are using gcc to compile your plugin, simply compile the object file:

    cc -Wall -c -o myplugin.o myplugin.c -fPIC -DPIC

    and then create the shared library:

    ld -o myplugin.so -shared myplugin.o

    The resulting *.so file and *.xml file must be put in the same directory. When you use Kst's Plugin Manager to load the XML file, it will automatically look for the shared object file in the same directory.

    Creating Linear Fit Plugins

    To create a linear fit plugin, you could implement your own fitting algorithms and output the appropriate vectors. However, Kst already comes with header files that make it easy for you to implement linear least-squares fit plugins by just providing a few functions. This section will describe how to take advantage of these files.

    Header Files

    Two header files are provided for performing linear fits, linear.h (for unweighted linear fits) and linear_weighted.h (for weighted linear fits). They are both located under kst/plugins/fits/ in the Kst source tarball. To use these files, include only one of them in the source code for your plugin:

    #include <../linear.h>
    
    or
    #include <../linear_weighted.h>
    
    (by convention, we will place the source code for the plugin one directory below where the header files are).

    Implementing Required Functions

    Given a general linear model:

    where y is a vector of n observations, X is an n by p matrix of predictor variables, and c is the vector of p best-fit parameters that are to be estimated, the header files provide functions for estimating c for a given y and X. To provide X, the following function needs to be implemented in the source code for the plugin:

    double calculate_matrix_entry( double dX, int iPos )

    This function should return the value of the entry in column iPos of the matrix of predictor variables, using x value dX. This function will be called by linear.h or linear_weighted.h. The implementation of this function depends on the model you wish to use for the fit, and is unique to each linear fit plugin. For example, to fit to a polynomial model, calculate_matrix_entry could be implemented as follows:

    double calculate_matrix_entry( double dX, int iPos ) {
      double dY;
      dY = pow( dX, (double)iPos );
      return dY;
    }
    

    Calling the Fitting Functions

    Once the appropriate header file has been included and calculate_matrix_entry has been implemented, call the appropriate fitting function included from the header file:

    kstfit_linear_unweighted( inArrays, inArrayLens,
                              outArrays, outArrayLens,
                              outScalars, iNumParams );
    
    or
    kstfit_linear_weighted( inArrays, inArrayLens,
                            outArrays, outArrayLens,
                            outScalars, iNumParams );
    

    Each function will return 0 on success, or -1 on error, so it is a good idea to set the return value of the exported C function to be equal to the return value of the fitting function. To maintain simplicity, the code for the plugin can simply pass the arguments given to the exported C function to the fitting function. Note, however, that inArrays must be structured as follows:

    • inArrays[0] must contain the array of x coordinates of the data points

    • inArrays[1] must contain the array of y coordinates of the data points

    • inArrays[2] only exists if kstfit_linear_weighted is being called, and must contain the array of weights to use for the fit.

    The easiest way to ensure that inArrays is structured correctly is to specify the correct order of input vectors in the XML file for the plugin.

    iNumParams is the number of parameters in the fitting model used, which should be equal to the number of columns in the matrix X of predictor variables. iNumParams must be set correctly before the fitting function is called.

    After kstfit_linear_unweighted or kstfit_linear_weighted is called, outArrays and outScalars will be set as follows:

    • outArrays[0] will contain the array of fitted y values.

    • outArrays[1] will contain the array of residuals.

    • outArrays[2] will contain the array of best-fit parameters that were estimated.

    • outArrays[3] will contain the covariance matrix, returned row after row in an array.

    • outScalars[0] will contain chi^2/nu, where chi^2 is the weighted sum of squares of the residuals, and nu is the degrees of freedom.

    outArrayLens will be correctly set to indicate the length of each output array.

    Ensure that the specified outputs in the XML file match those that the exported C function returns (which in most cases will simply be the outputs returned by the fitting function).

    Example

    The following is an example of the source code for a linear fit plugin.

    /*
     *  Polynomial fitting plugin for KST.
     *  Copyright 2004, The University of British Columbia
     *  Released under the terms of the GPL.
     */
    
    #include "../linear.h"
    
    double calculate_matrix_entry( double dX, int iPos ) {
      double dY;
    
      dY = pow( dX, (double)iPos );
    
      return dY;
    }
    
    extern "C" int kstfit_polynomial_unweighted(
      const double *const inArrays[],
      const int inArrayLens[],
      const double inScalars[],
      double *outArrays[], int outArrayLens[],
      double outScalars[]);
    
    int kstfit_polynomial_unweighted(
      const double *const inArrays[],
      const int inArrayLens[],
    	const double inScalars[],
    	double *outArrays[], int outArrayLens[],
    	double outScalars[])
    {
      int iRetVal = -1;
      int iNumParams;
    
      iNumParams = 1 + (int)floor( inScalars[0] );
      if( iNumParams > 0 ) {
        iRetVal = kstfit_linear_unweighted( inArrays, inArrayLens,
                                            outArrays, outArrayLens,
                                            outScalars, iNumParams );
      }
    
      return iRetVal;
    }
    

    Creating Non-linear Fit Plugins

    Kst provides header files designed to simplify the creation of non-linear least-squares fit plugins. The following sections detail the use of the header files.

    Header Files and Definitions

    The non-linear fit header files are located in kst/plugins/fits_nonlinear of the Kst source tarball. The files are named non_linear.h and non_linear_weighted.h for unweighted and weighted fits, respectively. To use these files, include only one of them in the source code for your plugin:

    #include <../non_linear.h>
    
    or
    #include <../non_linear_weighted.h>
    
    (by convention, we will place the source code for the plugin one directory below where the header files are).

    As non-linear fitting is an iterative process, you must also define the maximum number of iterations that should be performed. The non-linear fitting algorithm will stop when at least one of the following conditions is true:

    • The maximum number of iterations has been reached.

    • A precision of 10-4 has been reached.

    In addition, you need to define the number of parameters in the model, as it is not passed to the fitting function explicitly. To define these two values, include the following at the top of your source code:

    #define NUM_PARAMS [num1]
    #define MAX_NUM_ITERATIONS [num2]
    

    replacing [num1] with the number of parameters in the model, and [num2] with the maximum number of iterations to perform.

    Implementing Required Functions

    To use the header files for non-linear fits, you must provide the function to use as the model, the partial derivatives of the function with respect to each parameter, and initial estimates of the best-fit parameters. To do this, three functions must be implemented. These functions are described below.

    double function_calculate( double dX, double* pdParameters )

    This function calculates the y value of the fitting model for a given x value dX, using the supplied array of parameters pdParameters. The order of parameters in pdParameters is arbitrary, but should be consistent with the other two implemented functions. For example, for an exponential model, function_calculate could be implemented as follows:

    double function_calculate( double dX, double* pdParameters ) {
      double dScale	 = pdParameters[0];
      double dLambda = pdParameters[1];
      double dOffset = pdParameters[2];
      double dY;
    
      dY  = ( dScale * exp( -dLambda * dX ) ) + dOffset;
    
      return dY;
    }
    
    void function_derivative( double dX, double* pdParameters, double* pdDerivatives )

    This function calculates the partial derivatives of the model function for a give value of x dX. The partial derivatives should be returned in pdDerivatives. The order of the partial derivatives in the array pdDerivatives should correspond to the order of the parameters in pdParameters (i.e. if pdParameters[0] contains the parameter lambda for an exponential model, pdDerivatives[0] should contain the derivative of the model with respect to lambda).

    void function_initial_estimate( const double* pdX, const double* pdY, int iLength, double* pdParameterEstimates )

    This function provides an initial estimate of the best-fit parameters to the fitting function. The array of x values and y values of the data points are provided in pdX and pdY respectively, and the number of data points is provided by iLength. You can use any or none of these parameters at your discretion to calculate the initial estimate. The function should put the calculated initial estimates in pdParameterEstimates, with the order of the estimates corresponding to the order of the parameters in pdParameters of function_calculate and function_derivative. Keep in mind that the initial estimate is important in determining whether or not the fitting function converges to a solution.

    Calling the Fitting Functions

    Once all the required functions have been implemented, the fitting function from the included header file can be called:

    kstfit_nonlinear( inArrays, inArrayLens,
    		  inScalars, outArrays,
    		  outArrayLens, outScalars );
    
    or
    kstfit_nonlinear_weighted( inArrays, inArrayLens,
                               inScalars, outArrays,
                               outArrayLens, outScalars );
    
    depending on whether you are implementing a non-weighted fit or a weighted fit.

    The function will return 0 on success, or -1 on error, so it is simplest to set the return value of the exported C function to be equal to the return value of the fitting function. To maintain simplicity, the code for the plugin can simply pass the arguments given to the exported C function to the fitting function. Note, however, that inArrays must be structured as follows:

    • inArrays[0] must contain the array of x coordinates of the data points

    • inArrays[1] must contain the array of y coordinates of the data points

    • inArrays[2] only exists if kstfit_linear_weighted is being called, and must contain the array of weights to use for the fit.

    The easiest way to ensure that inArrays is structured correctly is to specify the correct order of input vectors in the XML file for the plugin.

    After kstfit_linear_unweighted or kstfit_linear_weighted is called, outArrays and outScalars will be set as follows:

    • outArrays[0] will contain the array of fitted y values.

    • outArrays[1] will contain the array of residuals.

    • outArrays[2] will contain the array of best-fit parameters that were estimated.

    • outArrays[3] will contain the covariance matrix, returned row after row in an array.

    • outScalars[0] will contain chi^2/nu, where chi^2 is the weighted sum of squares of the residuals, and nu is the degrees of freedom.

    outArrayLens will be correctly set to indicate the length of each output array.

    Ensure that the specified outputs in the XML file match those that the exported C function returns (which in most cases will simply be the outputs returned by the fitting function).

    Example

    The following is an example of a non-linear fit plugin that performs a fit to an exponential model.

    /*
     *  Exponential fit plugin for KST.
     *  Copyright 2004, The University of British Columbia
     *  Released under the terms of the GPL.
     */
    
    #define NUM_PARAMS 3
    #define MAX_NUM_ITERATIONS 500
    
    #include "../non_linear.h"
    
    void function_initial_estimate( const double* pdX, const double* pdY,
                                    int iLength, double* pdParameterEstimates ) {
      KST_UNUSED( pdX )
      KST_UNUSED( pdY )
      KST_UNUSED( iLength )
    
      pdParameterEstimates[0] =  1.0;
      pdParameterEstimates[1] =  0.0;
      pdParameterEstimates[2] =  0.0;
    }
    
    double function_calculate( double dX, double* pdParameters ) {
      double dScale	 = pdParameters[0];
      double dLambda = pdParameters[1];
      double dOffset = pdParameters[2];
      double dY;
    
      dY  = ( dScale * exp( -dLambda * dX ) ) + dOffset;
    
      return dY;
    }
    
    void function_derivative( double dX, double* pdParameters, double* pdDerivatives ) {
      double dScale	 = pdParameters[0];
      double dLambda = pdParameters[1];
      double dExp;  
      double ddScale;
      double ddLambda;
      double ddOffset;
      
      dExp     = exp( -dLambda * dX );
      ddScale  = dExp;
      ddLambda = -dX * dScale * dExp;
      ddOffset = 1.0;
    
      pdDerivatives[0] = ddScale;
      pdDerivatives[1] = ddLambda;
      pdDerivatives[2] = ddOffset;
    }
    
    extern "C" int kstfit_exponential(const double *const inArrays[], const int inArrayLens[],
    		const double inScalars[],
    		double *outArrays[], int outArrayLens[],
    		double outScalars[]);
    
    int kstfit_exponential(const double *const inArrays[], const int inArrayLens[],
    		const double inScalars[],
    		double *outArrays[], int outArrayLens[],
    		double outScalars[])
    {
      return kstfit_nonlinear( inArrays, inArrayLens,
                               inScalars, outArrays,
    			   outArrayLens, outScalars );
    }
    

    Creating Pass Filter Plugins

    Kst provides header files to simplify the implementation of pass filter plugins. The use of these header files is described below.

    Header Files

    The pass filter header file is located in kst/plugins/pass_filters of the Kst source tarball. The file is named filters.h To use this file, include it in the source code for your plugin:

    #include <../filters.h>
    
    (by convention, we will place the source code for the plugin one directory below where the header files are).

    Required Functions

    The filters.h header file contains a single function that calculates the Fourier transform of a supplied function, applies the supplied filter to the Fourier transform, and then calculates the inverse Fourier transform of the filtered Fourier transform. To supply the filter, the following function needs to be implemented in the source code for your plugin:

    double filter_calculate( double dFreqValue, const double inScalars[] )

    This function should calculate the filtered amplitude for the frequency dFreqValue. inScalars[] will contain the unaltered input scalars for the plugin, specified in the XML file. Most likely inScalars[] will contain cutoff frequencies or other properties of the filter. For example, to implement a Butterworth high-pass filter, filter_calculate could be implemented as follows:

    double filter_calculate( double dFreqValue, const double inScalars[] ) {
      double dValue;
      if( dFreqValue > 0.0 ) {
        dValue = 1.0 / ( 1.0 +
        		pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) );
      } else {
        dValue = 0.0;
      }
      return dValue;
    }
    

    Calling the Filter Function

    Once the required filter_calculate has been implemented, the filter function from the header file can be called:

    kst_pass_filter( inArrays,
                     inArrayLens,
                     inScalars,
                     outArrays,
                     outArrayLens,
                     outScalars );

    The arguments supplied to the exported C function can usually be passed to kst_pass_filter without modification. However, there are a few restrictions on the arguments:

    • inArrays[0] must contain the array of data to filter.

    • inScalars should contain the filter-specific parameters to be used by the filter_calculate function.

    After the function call, outArrays[0] will contain the filtered array of data, and outArrayLens will be set appropriately. The kst_pass_filter function does not use outScalars.

    Example

    The following is an example of a pass filter plugin that implements the Butterworth high-pass filter.

    /*
     *  Butterworth low pass filter plugin for KST.
     *  Copyright 2004, The University of British Columbia
     *  Released under the terms of the GPL.
     */
    
    #include <stdlib.h>
    #include <math.h>
    #include "../filters.h"
    
    extern "C" int butterworth_highpass(const double *const inArrays[], const int inArrayLens[],
    		const double inScalars[],
    		double *outArrays[], int outArrayLens[],
    		double outScalars[]);
    
    int butterworth_highpass(const double *const inArrays[], const int inArrayLens[],
    		const double inScalars[],
    		double *outArrays[], int outArrayLens[],
    		double outScalars[])
    {
      int iReturn;
    
      iReturn = kst_pass_filter( inArrays,
                                 inArrayLens,
                                 inScalars,
                                 outArrays,
                                 outArrayLens,
                                 outScalars );
    
      return iReturn;
    }
    
    double filter_calculate( double dFreqValue, const double inScalars[] ) {
      double dValue;
    
      if( dFreqValue > 0.0 ) {
        dValue = 1.0 / ( 1.0 + pow( inScalars[1] / dFreqValue, 2.0 * (double)inScalars[0] ) );
      } else {
        dValue = 0.0;
      }
    
      return dValue;
    }

    Appendix C. Supporting Additional File Formats

    This section describes how to create additional readers for unsupported file formats. If you are not already familiar with data source concepts, please read Data Source Concepts

    Creating Datasource Readers

    If you wish to use a file format other than those currently supported, you might choose to write custom datasource readers.

    All Kst datasource readers are regular KDE plugins. Like all KDE plugins, each datasource reader must have a shared object file and a *.desktop file. Before writing the reader, the library name of the plugin must be decided. This name must be a valid variable name in C, as it will be used in the function names of the shared object. For example, the library name of the reader for ASCII files is “ascii”.

    Note

    KDE plugins are not the same as the Kst plugins used to manipulate data. All references to plugins in this section are to KDE plugins.

    The Shared Object

    A datasource reader should be a subclass of the abstract KstDataSource class. Ensure that you include the header file for KstDataSource in the source code for your datasource reader:

    #include <kstdatasource.h>
    
    There are certain requirements that a datasource reader must meet. One requirement concerns the presence of exported C functions. Other requirements are consequences of the fact that datasource readers inherit from KstDataSource. Both sets of requirements, along with suggestions and general explanations, are provided in the following sections.

    Exported C Functions

    The exported C functions are listed below. In the following examples, all instances of <libname> should be replaced with the actual library name of the plugin.

    KstDataSource *create_<libname>(const QString& filename, const QString& type)

    This function should create a new datasource reader of type <libname>, where <libname> is the library name of the plugin. A pointer of type KstDataSource to the new reader should be returned.

    bool understands_<libname>(const QString& filename)

    This function should return true if the file specified by filename is of a valid type supported by this reader, and false otherwise. The function should check the contents of the file for validity, and not rely on any filename extensions.

    QStringList provides_<libname>()

    This function should return a QStringList of the file types supported by this reader. The strings returned are arbitrary, but should be descriptive of and appropriate for the actual file types.

    Protected Member Variables

    KstDataSource contains various protected member variables that the custom datasource reader can use. These variables are described below.

    bool _valid

    This variable should be true if the custom datasource reader is valid. Most likely the reader will be valid, unless there is an error condition (such as the data file being unreadable by the reader). This variable is used by the isValid() function of KstDataSource, which is usually not reimplemented in subclasses.

    QStringList _fieldList

    This variable should hold a list of the field names in the data source.

    QString _filename

    This variable should hold the name of the data file this datasource reader is associated with.

    QString _source

    This variable should hold the type name of the source.

    Virtual Functions

    The KstDataSource class contains many virtual functions that should be redefined in the custom datasource reader. These functions are in the template files template.h and template.cpp, listed in the Example Templates section. Descriptions of the functions follow.

    TemplateSource(const QString&amp; filename, const QString&amp; type)

    The constructor for the datasource reader. filename is the name of the file to read data from, and type is the type of data the file contains. This constructor should most likely invoke the KstDataSource constructor in the constructor initializer list, and probably call the update function listed below to initialize member variables. In particular, the bool _valid variable should be set appropriately.

    virtual ~TemplateSource()

    The destructor for the datasource reader. Any dynamically allocated memory should be freed.

    virtual KstObject::UpdateType update(int = -1)

    This function should read any new data entered in the data file since the last time update was called, and update the member variables appropriately. The function should return KstObject::UPDATE if the file contained changes, or KstObject::NO_CHANGE otherwise.

    virtual int readField(double *v, const QString &field, int s, int n)

    This function should read n frames of data, starting at frame s from the field specified by the field name field, and return the contents in the array v. If n is less than 0, the function should instead read 1 sample starting at frame s. The number of frames that were read should be returned.

    virtual bool isValidField(const QString &field) const

    This function should return true of the field specified by the field name field is a valid field in the current data source, or false if the field is not a valid field.

    virtual int samplesPerFrame(const QString& field)

    This function should return the ratio of samples per frame for the field specified by the field name field. For data sources that do not make use of this concept, the number of samples per frame can be set to 1.

    virtual int frameCount() const

    This function should return the total number of frames in the data source, as of the last time update was called.

    virtual QString fileType() const

    This function should return the file type of the data file currently being used, usually the same as the type parameter that was passed to the constructor. Alternatively, it can contain an error message (to indicate, for example, that the file is not valid).

    virtual void save(QTextStream &ts)

    This function should save the file description information to ts. In most cases the implementation provided by KstDataSource should be sufficient.

    Example Templates

    In general, the following two template files can be used to create new shared object files. Simply modify the function bodies as appropriate for your particular data source.

    /***************************************************************************
                      template.h  -  data source plugin template
                                 -------------------
        begin                : Fri Oct 17 2003
        copyright            : (C) 2003 The University of Toronto
        email                :
     ***************************************************************************/
    
    /***************************************************************************
     *                                                                         *
     *   This program is free software; you can redistribute it and/or modify  *
     *   it under the terms of the GNU General Public License as published by  *
     *   the Free Software Foundation; either version 2 of the License, or     *
     *   (at your option) any later version.                                   *
     *                                                                         *
     ***************************************************************************/
    
    #ifndef TEMPLATE_H
    #define TEMPLATE_H
    
    #include &lt;kstdatasource.h&gt;
    
    
    class TemplateSource : public KstDataSource {
    public:
      TemplateSource(const QString& filename, const QString& type);
    
      virtual ~TemplateSource();
    
      virtual KstObject::UpdateType update(int = -1);
    
      virtual int readField(double *v, const QString &field, int s, int n);
    
      virtual bool isValidField(const QString &field) const;
    
      virtual int samplesPerFrame(const QString &field);
    
      virtual int frameCount() const;
    
      virtual QString fileType() const;
    
      virtual void save(QTextStream &ts);
    };
    
    
    #endif
    

    /***************************************************************************
                        template.cpp  -  data source template
                                 -------------------
        begin                : Fri Oct 17 2003
        copyright            : (C) 2003 The University of Toronto
        email                :
     ***************************************************************************/
    
    /***************************************************************************
     *                                                                         *
     *   This program is free software; you can redistribute it and/or modify  *
     *   it under the terms of the GNU General Public License as published by  *
     *   the Free Software Foundation; either version 2 of the License, or     *
     *   (at your option) any later version.                                   *
     *                                                                         *
     ***************************************************************************/
    
    #include "template.h"
    
    
    TemplateSource::TemplateSource(const QString& filename, const QString& type)
    : KstDataSource(filename, type) {
    }
    
    
    TemplateSource::~TemplateSource() {
    }
    
    
    KstObject::UpdateType TemplateSource::update(int u) {
      Q_UNUSED(u)
      return KstObject::NO_CHANGE;
    }
    
    
    int TemplateSource::readField(double *v, const QString& field, int s, int n) {
      Q_UNUSED(v)
      Q_UNUSED(field)
      Q_UNUSED(s)
      Q_UNUSED(n)
      return -1;
    }
    
    
    bool TemplateSource::isValidField(const QString& field) const {
      Q_UNUSED(field)
      return false;
    }
    
    
    int TemplateSource::samplesPerFrame(const QString &field) {
      Q_UNUSED(field)
      return 0;
    }
    
    
    int TemplateSource::frameCount() const {
      return 0;
    }
    
    
    QString TemplateSource::fileType() const {
      return QString::null;
    }
    
    
    void TemplateSource::save(QTextStream &ts) {
      KstDataSource::save(ts);
    }
    
    
    extern "C" {
    KstDataSource *create_template(const QString& filename, const QString& type) {
      return new TemplateSource(filename, type);
    }
    
    QStringList provides_template() {
      QStringList rc;
      // create the stringlist
      return rc;
    }
    
    bool understands_template(const QString& filename) {
      // determine if it is an X file
      Q_UNUSED(filename)
      return false;
    }
    
    }
    

    The .desktop File

    The following is an example of a .desktop file for the template plugin:

    [Desktop Entry]
    Encoding=UTF-8
    Type=Service
    ServiceTypes=Kst Data Source
    X-KDE-ModuleType=Plugin
    X-Kst-Plugin-Library=template
    X-Kst-Plugin-Author=The University of Toronto
    Name=File Reader Template
    Comment=Long description of the file reader template.
    

    You should add translations in additional languages for the Name and Comment fields by adding additional Name and Comment fields with [xx] appended to the end of the field names, where xx is the two-letter language code. For example, to add Spanish translations, the following lines would need to be added:

    Name[es]=Plantilla de lectura de ficheros
    Comment[es]=Plantilla de código para hacer un complemento de lectura de ficheros.
    

    The field X-Kst-Plugin-Library should be exactly the same as the decided library name for the plugin.

    Compiling and Copying

    To compile and install the new custom datasource reader, create a new directory under kst/datasources of the source package. Place the source files for the object, along with the .desktop file in the new directory. Then, edit kst/datasources/Makefile.am so that SUBDIRS contains the name of the new subdirectory. For example, if the new subdirectory is called template, SUBDIRS might be changed to the following:

    SUBDIRS=ascii dirfile frame indirect template $(PIOLIB_SUBDIR) $(FITSIO_SUBDIR)
    

    After the required files are in the newly created subdirectory, a Makefile.am needs to be created in there as well. Use the following sample as a template, replacing all instances of “template” with your custom library name in kde_module_LTLIBRARIES, kstdata_template_la_SOURCES and services_DATA.

    INCLUDES=-I$(srcdir)/../.. $(all_includes)
    
    kde_module_LTLIBRARIES=kstdata_template.la
    
    kstdata_template_la_LDFLAGS=$(all_libraries) -module -avoid-version
    kstdata_template_la_SOURCES=template.cpp
    
    METASOURCES=AUTO
    
    services_DATA=kstdata_template.desktop
    servicesdir=$(kde_servicesdir)/kst
    

    Once this is done, you can compile and re-install Kst from the modified source package, or alternatively, only install the new libraries, like follows (using the “template” subdirectory as an example). First change to the root directory of the Kst source package. Then,

    ./configure --prefix=`kde-config --prefix`
    cd ./kst/datasources/template
    make
    make install

    Restart Kst and the new datasource reader should be loaded.

    Appendix D. The Kst DCOP Interface

    Kst provides an interface that acts as a client using the the KDE Desktop COmmunications Protocol (DCOP). The set of functions provided in the KstIface interface allows for easy control of Kst by other applications or scripts. For more information on DCOP, refer to this webpage.

    Appendix E. The Debug Dialog

    The Kst debug dialog can sometimes provide useful information about certain problems encountered, and contains all notices, warnings, and errors logged by Kst. To access the debug dialog, select Debug Kst... from the Help menu.

    The Debug Log

    The debug log is located on the Log tab of the debug dialog. The following lists the different messages that can appear in the log, with brief explanations and suggested actions (where appropriate).

    TypeMessageExplanation/Suggested Action 
    UnknownKst Extension %1 loadedNone. 
    UnknownError trying to load Kst extension %1. Code=%2, \"%3\"Make sure extension exists, meets the requirements for a Kst extension, and is in the correct location. 
    UnknownUnable to find required vector [%1] for data object %2.Ensure the indicated vector exists in the Data Manager. If so, try recreating the data object. 
    UnknownUnable to find required scalar [%1] for data object %2.Ensure that the indicated scalar exists (try searching in View Scalars of the Data menu. 
    UnknownError loading data-source plugin [%1]: %2A datasource reader (KDE plugin) could not be loaded. Make sure the data-source reader meets requirements described in Creating Datasource Readers and is compiled correctly. If it is a built-in datasource reader, try recompiling and installing it again from the source package. 
    UnknownScanning for data-source plugins.Kst is scanning for datasource readers. No action required. 
    UnknownNo data in file %1Make sure file is supported by one of the datasource readers, and that the data is formatted correctly and is not corrupt. 
    UnknownUnsupported element '%1' in file %2Ensure that the file is not corrupt, and meets the specifications for the file format. 
    UnknownUnable to find X vector for %2: [%1]??? 
    UnknownUnable to find Y vector for %2: [%1]??? 
    UnknownUndefined justification %1 in label \"%2\"This should not happen. Most likely it is the result of a bug. 
    UnknownInternal error: No X scale type checked in %1.None. 
    UnknownInternal error: No Y scale type checked in %1.None. 
    UnknownUnable to load plugin %1 for \"%2\"Make sure that the plugin meets the requirements described in Creating Additional Plugins. In particular, make sure the shared object and *.xml file are in the same directory. If the plugin is a built-in plugin, try re-installing the plugin from the source package.  
    UnknownInput vector [%1] for plugin %2 not found. Unable to continue.Ensure that the *.xml file for the plugin specifies all the inputs correctly and in the correct order. Check the source code for the shared object to ensure that it is using the correct arrays from the input array. Also ensure that the specified input vector still exists (check in the Data Manager). 
    UnknownOutput vector [%1] for plugin %2 not found. Unable to continue.Ensure that the *.xml file for the plugin specifies all the outputs correctly and in the correct order. Check the source code for the shared object to ensure that it is outputting the correct arrays in the output array.  
    UnknownData file for vector %1 was not opened.??? 
    UnknownError parsing XML file '%1'; skipping.Check the XML file to make sure it has correct syntax and form for the intended use. If is an XML file for a plugin, check Creating Additional Plugins for more information.  
    UnknownDetected disappearance of '%1'.None. 
    UnknownCould not parse xml file '%1'.Check the XML file to make sure it has correct syntax and form for the intended use. If is an XML file for a plugin, check Creating Additional Plugins for more information. 
    UnknownCould not find library '%1' while loading plugin.Make sure the library exists and is in the correct location. If this is a built-in plugin, try recompiling and installing the plugin again. 
    UnknownCould not find symbol '%1' in plugin %2.A required C symbol could not be found in the plugin. Make sure the plugin meets the requirements described in Creating Additional Plugins. If this is a built-in plugin, try recompiling and re-installing the plugin. 
    UnknownThe %1 font was not found and was replaced by the %2 font; as a result, some labels may not display correctly."If this causes problems, install the missing font. 

    Appendix F. Installation

    The following sections contain detailed instructions for obtaining, compiling, and installing Kst along with any optional libraries or packages. If you use a package management system, you may use it to install Kst instead.

    Obtaining Kst

    Kst is part of the kdeextragear-2 module of KDE. You can also download the latest version separately from the Kst website . If you wish to download Kst from CVS, it is available via anonymous CVS for KDE or via the KDE WebCVS repository.

    Installing Kst from Source

    The following sections detail how to compile and install Kst from source code.

    Requirements

    Kst v1.0.0 requires the KDE 3.1 libraries and Qt™ 3.1. Almost all major Linux® distributions have packages for KDE and Qt™. Since Qt™ is a dependency of KDE, having the required version of KDE should be sufficient. It is recommended that you refer to your particular distribution's documentation for KDE library installation. Note that the entire KDE desktop environment is not required—in most cases, look for packages called kdebase-* and kdelibs-*. Alternatively, more information is available on the KDE website.

    Optional Libraries and Packages

    The following libraries and packages are optional, but provide full plugin and data source functionality in Kst if installed. The installation instructions assume you have root access on your system.

    Note

    You may already have some or all of these libraries and packages installed, in which case there is no need to reinstall them. Also, check first to see if pre-compiled binaries for the libraries and packages exist in your distribution's package management system, as it may be easier to install the binary packages.

    GNU Scientific Library (GSL)

    The GNU Scientific Library provides a variety of mathematical operations for the built-in Kst plugins. Having GSL installed enables a variety of plugins such as linear and non-linear fitting, correlation, and interpolation plugins. The library can be found at ftp://ftp.gnu.org/gnu/gsl/. Alternatively, you can find GSL under /gnu/gsl on the mirrors listed at http://www.gnu.org/prep/ftp.html.

    Download gsl-[ver].tar.gz, where [ver] is the greatest version number found in the directory.

    Then unzip and untar the file:

    tar -zxvf gsl-[ver].tar.gz

    replacing [ver] with the version number of the downloaded file.

    Read the INSTALL file in the resultant directory for detailed installation instructions. For most systems, the following will work:

    cd gsl-[ver]
    ./configure
    make
    make install

    CFITSIO

    The CFITSIO library provides support for reading and writing to the FITS (Flexible Image Transport System) data format. The libary can be found at ftp://heasarc.gsfc.nasa.gov/software/fitsio/c/. You only need to install the library if you anticipate reading or writing to the FITS file format.

    Download cfitsio[ver].tar.gz, where [ver] is the greatest version number found the directory.

    Then unzip and untar the file:

    tar -zxvf cfitsio[ver].tar.gz
    replacing [ver] with the version number of the downloaded file.

    Read the README file in the resultant directory for installation instructions. For most systems, the following will work:

    cd cfitsio
    ./configure --prefix=/usr
    make
    make install

    You may need to change the directory specified for the --prefix option, but the most common directory is /usr

    Compiling and Installing

    Once all of the prerequisites have been met on your system you can compile and install Kst. It is assumed that you have already downloaded the Kst source package. If not, please see Obtaining Kst.

    The simplest way to install Kst is:

    tar -zxvf kst-[ver].tar.gz
    cd kst-[ver]
    ./configure --prefix=`kde-config --prefix`
    make
    make install
    replacing [ver] with the version of Kst you have.

    Important

    Note that kde-config --prefix is surrounded by backquotes. It is very important that the kde-config utility returns the correct path (most likely /usr), otherwise Kst will not install properly. You can double-check by running it directly:

    kde-config --prefix
    Ensure that a non-null path is displayed.

    You can read through the messages displayed by the configure script—if it reports any missing libraries (such as GSL) that should not be missing, please go back and ensure that the libraries and header files have been correctly installed in the appropriate locations.

    =a։3ۊz_v#qk=i,@,J"_Uk Z_Þ$uXl?)V,X-EdUh'UaVݾX& DdMU}q p9KRܿz~;cVY';ȯTmO)vk Yhz -":O/D"H$3+p"^^OnUӐ~@}7?aʡY13o)ayRC 11Xf=)j)_Թ:E-ohsbyX{uY`1IkGU?nv"[YLU?,P`{ ?TϿH$D"HKM}MJ$aA,vQIi3%SZ E/%KsߴHS>,"}҄Ddj,vq[m| pUja;0a^,wD$MUW]Tug i[PmuxsY@}t.5O^[˃MJ#?VދF{7vMu;s'D"H$D"- ,鋥EQP6T>Q$S֧\%.Ypile Ɉ퇲eo}3UƢ 8-TՏZZ]"/`{rqr,["\D3R TգU\:H$D"H1L^[,HWY͔9[D0:n5* ]iܵDd2FǁvkV#("ySd\`qvWb+5pq߮yr~Ap.,K11cEk}\OX~AkD"H$DH;X3_@E Mb'"JΛȨ׳/Yuʴ_Fedh\-<]S1r`E]9xOD.,5Zyc=~*]Ѵk˴LPik,;Pw{xتF"H$D"6V`dP>mӘO-fjdگjʌ2݌Uq U_Df~ jɰ쏫j.@ZR^ɶSѮyn|w/W%ʴ_F"H$D"6ю,TD0(o\%ds_U}nFTf-R+ӿ2݄fPU?UsUu-`pA $?Xϸ?ٟzh<9W̖eEZF>gH$D"H$Fڡz&ؗ!.P+!fE|)E`Y׿5c߸ c` _VntTտ ."sJ;ɢ:(q.gt͠ȱZD"H$D"m , `Et"5j7r O>l0ܐY?[T"ҧFhj_ySHZ4fF1@T"Õ0s#"+.h'{*`2ɠUy,4ϫ%Ec07N(F: "RKDCEd2}D"H$D" , ۔%ꈆ,+"['S.:nQKurYq]kըx`w~4۩Κɀqw\YV{:;݈`7Rب9To]?5?ҮysecFD"n۾4SNN >~.y]ȱ#H$D"HXühT:"ol]Oؤ`8F6Y.^'"*tX895%O[Pq㺴F 黜gJYwإ@խ+U5]6"Vx >It`pV0kY8 o=vKLܹ&1R J/.`^{fLslt6͓0 +Dd4p)}62cTg ƧXS=AƸRFkcY3PռŚo8k bq#NGD#0Eձ[F%̓Q:-AO?7m}0E|KjFD?\,{4"[6m'ӓ,Dtf#eMDfyXD֯%f!ӵ?6ڶ숹+2S{2 h殜;lN:>_ǹ.嵳{p` {Ĕ70ګ.R<1 =뤔]Y} Ld^y gsxu__yŔ W{k{<:wZz|)~%uSraJwܷ}ɐ]/k34x^c,0YU0%o"1LFmp}s`N'>A_ N7_c ^/#܈7ǣ^ yi$*+S^f)y̔e/TL9Gv7 l:fo؏%V3}Y*q*|m//)j@Ͻ7Sr}/ t)=}>Tݫoݧ:ϧտnhsf ^mĂźMܮ@=O --[CV[X {X61˗)rڻ2h+l 0Ye:ܜvM&뤌-qEWRڸxS8\ـ' \?;'rdVڽ=ԫsZ:;f,98nΜc]`Ww7)|m̈6 EZ}Sﳏja[{wu ,Фyevwlx_aqbe= i]%;u~fc'3(?d_LYJ)\17J_v=ݟÞ&Phԟa_(BX=1cU{Ik̈TJ*vB}T`5^+]X)unC lw}Wip>#ݧMW`a18rvsBp?sXQwAEEDVKMUv{#4+ a B&_ Sa|T@&7r#01Ѫ:*TTUYXA+OlnsYm" p8f8FUowϸ+'yYNSOݹecvLY+ :y~aiR㗩"<] Y{xloB͏B,֘Rۊ菘?}4!"ar (4 ~u̖uy;swDPL{Ѝ)>%"`֜Zybb=%?QDǛaʽ\;a Ec7,x:9UL_#d/̚MU "(|E"擖hM[ޛp'Rt}A.Vp`kIURD2WW٧H{&sS6 S3I m>L44TUȭXlc*(J?#f a s;/D/^{dMDfb̍K |؎g3;ɰyeͭءrt1cn vJ+"6 .ٍ6fgŔÁؼ;=6^ڛv0Ef)n#V""ObJe[TiJ*9{0_^w"/ o~-T2QG& IDATuՉrGK Ýۖo'@Eфcm=YtH,^ۆظ_LU:)U3|`n5JUFU)ܦj6<ȻL%[3Rolݡ6NV3LU+4Xǒ̄YHFnv}!6ˤPUct:@;a]n߰4iǞLY;` j׮V9Yr땼^gkh`S' O} 87%eW;v7y眔Wcq < S&#OdNqop#H>m)(u%z19ܹx25>X˹ S`eXҲZe A?dȽXgk%Z`E"HQL<,"gb_ܳaAd7_j "$Dd\Nx [?|YlD:JY '4Oe'eOH3-=-LqJ60v*yT=.411ˬ"f[RrƳ^91z˵=Wgv.YSUu.dL86q,"-s+1(1eE>eA"+ͱss`6rp4f1,pvm!;ö6fUfu~%"bY nR?rb7A۸1ϰ*6vm5N*"MDy(\/>KJe(L qP=ϷYx\D쌪/al~QDbv_YH>SN/e=*gol,FQ=?f5\Y^1 Sɭ [E<ڭA%Xbgm=sU_K,B 2dC뛳 ?uP&Oh{trnq7~(po`1W7J^0}=فks1{ )EnaL5pkPXhWg(00Cv? L!;9'{dNdq۪\穔VM>^E:=8T\+S9)xr7oVl-JK,S8yǹSd=s(d1{n2L)ϣFN~uL_#[+`P']= ~9˻{_#[_%8`f߻I H$ U}RUY}-wVխ"H:":pUUUǧɫQž"Mlwl+U}>97UJU/d'\UŬUyl!(1˅ TtU;(U[@&bd""PiQ`MygELaq7_ *l1f~Q!]P=}ǔ`_5M#"3bLyR>YʵWPU[UAUFx6.9T[^m7:AUmpUVc(&fuֵs4HN_UVՇ~FA w_T,aU}r5q1ծ^<ƤJT`E"H!;z{1z@őH%w?=N!"h!밷 h[,uUF̚l]Cb͑<<$ kNkx lm_^Y%!+x(EP 2dc$~W})uӸ(^D\0b0\}Qqv uN,d/p&Q慨OSb;P;555ӱqVDdq+i-ܚч1+`.k:|tH$D"HADdy`opz:Z0qC:4'ەSQD"H$2q0O]Ha!?U3(z ,)"k`i7U("u$L\s{X砧'#R q\&"KX1I0D"H$۞#K0Pv,͊?mm!"]OSBekn>fRrtm:BT`E"H$L<lYn(5fz-g2f\"~N ʾԋ$P/Uۢjo[}M$|f0(y%gOb6>nvz&SDnr?&&ZBp\ꡭOdDD֣&nU \˒kF3FD̅2|<H3ٿ(Q7TφqMjz\(kJ0呈,vM͓/~6 ]Dd#`yaUF_>px,ҏb-`^U'"r{W,\GUu'k^:XZ,ڴ,|UN5c Y ^HE9XmotvwhbEKX"{UBS̛@S`οj3LT]2UAM/F8 4\g#X"6w[H`+W`oGcc. hGgiqZ͓22M.Pn VTʶө@T`q"rߢnE&MަXEDW\ĕe5K9]8Ei)`-q[\DV(0go53 (Xw`E1)omU`9B Edr`Zt>/vV`-#"KucsM؍ ,e['~ns>RDZG""r)iSIyp*X$"Gjj7ongȺTӱ|Zmu:%61 c7 g2VkaA)#5pofuq_RC)45Tέ#pڏRyMz=DdS,-wx}gp]D|/FD.:%0`/'"'屢lAY`"r6 a?rܜߊ,` n{G}#"sWB""St?~"~oM-"!5n*"2ۼbnRmד9oӸDd^US7thb ,U}MD 3cW*zg]hN5o~7`9*DUmO+֗XRKꇖ~&,A[Do&~IbF_P1VZDVCR`lw%ފTԽ1`l=郥>v8q=z8zXPUbGQAـۧ;U:iIEyu7Y t}4 Uj߽DY"%Ֆ-Px۞ P7GDǞN83 ZZ&QN-5pdrYcaj,(ľ2qj0p~ v_Ubaֽ{_]Se1WgZн[3*ݵS'\ySn6:E"\T[v-=7\&튁u' "_S(E Zc.^&c=% s7l؟!"I;TMXV0"5ׇ]̙7Uu )p$<S>"0{6<`UԖ:TmJcÉ~m&} 8%Gꠔim mf. ~7{0zI"-s 6؇HAU)tWggxYS^.Yތ0xZ?NV񞅡z3+Zsu;z ]7;"r|oBU_az0C"r00ԉ&cOTuߞ}@WE$֘gsO qAU ]fp,fD קƸU*$~Z_HR^l@%IH*k[UU=HqTePŵ%}^{oxNnwzR,S&Yt>Su q_kkaO~|]sj_EbJq^_)U^C2dd./Ц/lm~!73f~PˤS0Ա)Ŕ_vԩUw<Κ^ "x+`JZu_\ȯʑYĵ9WW:\ŀ q,#]mYLS ;'kcc8lsL k?f5Emk\wJ{{L7bcX<"휖Q?֨? SfO݂)n΂Ԃu2+]f'`;Li4&z> "iAK,l)15jMi~~I,ŔO?sNw1Z'#EdEYpzM%zF[>ݵADN\/cJU *rs|Sբ['ei[s[Zޅ07~Bv#曪F:luST5W("R GKfש(OPյ#و,؏DnS%w_l\/|,P`U\DP(5NUk&p~EU$Nn, - 0ITiPyH' vᮕ͇= 7_}RG"K;'DܘBSɸxvK3cS%LX:}>j 7YxnDZΦTϋE.R h 8S^tTb8|XSrē,3ˡ{(nW?sԲhTU/6rmN8v"^fø`R:v*;}>EONKXzR~Ty Q1 Nr={sivl33W; e-H?9U  +,4 =WDf=/+LD7c&_bn!#`5[O2fjm&"{6͎섙rA>V49֤h gf] >U}݋D"H$ \P𕁇j@7cHn&X"r8K7gEd;U-ba1ADn,"wSYl"Lc׿&8)Y !"/P2Ek38 IDATYwd㸬wKU}F_VT՚5,kKZJQ"rYV`A9xGf8Xs_D~h%~ݣ=L3J4^]r#2\ ޣX<0:F;ǟ{={Tz_&)3aV_KUsƔX`!y; h~Ջ̉&O`9 o9.{ѱH$D ,Ր; vz|sDKvwS^= -6~i)zZUORSTu,U}N7pdSlSc>t͠5௘K?`%籚{R93u={4ˌX¸Sи]Uꆪ3Z?_]~ %TS^ lۑjY\F>>R)eh UPUaYW|k4h]%/k"9gePY ؄Yb`SqSZV!"s`WXzTϪzAU \'馐S\ӊD"H$R);DdôuYDn:ުJzDJ1Z`B=N2TDn~Y1 KDR&.PVUGj9Lx<ҕ_{F [=`{)~~{-p&UϹlsG #.ms'NUL79'៪֗wݽ 8Hê .[AdžQU}X`܎&Y wc楪_%CS;U+ gselYnFDb lL169ˍ}߻V "b\;j`J ])bY1Tu|݂Exۉ:g7D"HcnȫXYG8l]xE+;D1Z`͊}Zj]h;3ؽN61kf*7dA`@ysM#Z_Dͩ3dBD”5 s m5d9QǯyT42U \e: ]gif( {w9H77U}m.쬘Xp7Pc9V[#6moR^y |mrsL$D"߱ߖɚg,c `D:IUpf_=LN1㻨} U ;cP`5XRgYn[azQ9rec}Q}N`;slj T{]hEU F7Z<XPDnn)Ύ;t WU,$"A",5 R<"oاH$D"-@THU] :?{+,d̺:ﶱˑH oAuxw9Rmm2fU+Uڠ1WTe˘ٟj+<VjdBݧۘՏ:ۘOn:90gYFTugU}\I¤JBh;vbu6]c5UGaVyC!zX N%;bܮP,ޑX7]Ɇ-XUy\lge D"H$CPq>75zdD"ɤ*e?ϕ$B~J%vEskCjel4e.pAlo{Vryt›/8Tiڝ&+f$" eUhcA|`9Ϊkj?U]KUTRMݲEd9,8,:=A[5%4iH$D"HLA?0ʢ1Z-lO2!t[ʵ3CQ\v ̀5TpnI0϶W31wiPƺ% g;H$D"HL $E Fu2]g_js?hXDzj¶&f!f^LDVա.3ZhVx/C6.kWiR"H$D"HKTX&\ g'TXӹouۉ%Ս":* ,0+Kz.^g-Q7 )s׼ 5Ab. ""6H6I0qdPJ=2˳\)Tp;9[ȂT2 "T"2 L+"sjYp>. mID"H$DgRHBWfu@n8R[C:cq8>]%UxDrPՑz,HWeV#7j"үD~,ﱌ|=pL I~)[U\Rޮ8T*Agx]ܮou$D"H$I!*vT`yoצnjpPG,~VR"2PDf2AsX/}Eh02ʎH TUU=s!- <vhStUz;ۨTe H2:f-Ddk`]yI ەg26"`8ϙ*άT[&O(F"H$D"6X`{2EdwrT$!;JH) QP@TԟXh6 X& IH Ks{ߴݷ/~>Ξ[fμ3F՟M}0 غ}HU$Uu=E>Q"N""U"Yh\7.[@GDF7)*^T/s㋕VO?xty!{ 88\ng#"+DH0`B''֏0e[R]Kug[k۳R+_Dkѝm z`Jt(x mUDG|.=]b GӰ0^Q*UUhSTc4+"G`J:|qq adauCbU}s/K4+_n(h34ڴ&Qܗ kWI#3b+ƹ ĝ FԔ]wU"n>IYKqZ|h3'")"Dӝ6r4kaqʈ-$7-s-`P}3NY"2 :%8"/(v{~ȉ%~>"2t"sLC94+[ڈ_BZ06ЈNڻBZ i'EFȨ~"2S@8D U4[ռ NBS˴X@?>@fOz1&Tv,bF|8gb-ER8 eZZXDd#"Pû=DD{EwSMq3C(>vq^3Tܘ^#"9v"";FU}H1XFF}Ema0gfdQ&"G'xnT40".Xi|uD$SY!iV^7i}8rsɊGEdH,z: ׋ 325+83nDz꟣9i6d )WȑzgNc1Qv^YQ),?E䳱TDĔcæk*=REd U+W3ods|_wg5FÊꏪ6z\e]^DNToF}nC#xLAIƮ,A }c*SkzmaP(2sVNdtg,ͿIN6\jveD~2h]x8C ?v߁4_vTg`Z\Vϩ5Xs ƜS";u.Bk>%pU\FhWjC2juocpVA06S5}D^hUdFjy\x28Jfݞ侞q0d_oq$|>-de68+:t{x(X`aQu3EufKe\]DvŲM.eL3zN8Us-E-էE3Ц_x/4UB e;JUncPo-Ĵ4\[,6Uuls#[Z3]Բ~SDelYMqZ"ޥ= ;833a/@l??37eT?[q Q-{vz,=4̈́?tubN˄,bFǘy5ZiE12h117 lWnZ!Ca> _ }<ަj "҈}EW\hRDS·@s|nZq'CD.ϩݜӓ S8U> ܪWɷ9 EU}_WKT/E}E#FdUk|85kP,-}EU_c= `˜:}Yךk쫫;( qq* gt{U}P$q/< 8888ӯq8888ӯqBqqA,l[+!}Q:Dde`n߈ȜX5D wJ_Y0"" x ؖ"2 v>24^LQ՛j!o=`/` `fQX^mBvXL؎OaծU+(;e ?±XludXe\W`!7R4'l@Uoi37RAWU ',%y$T6!v|bO> \OVǍuv9 aǒKڡqf6ż4ŃغłX\chNl\VنkXΑXGWص&v= ^m.d&m#iyBkcM,jq.dÒ%oŏ}(;6mv.isyYSMZ5ϧbAӿ̛G%f9}*T, k {Y!5uZFwV$A6𧒾>W!d}.Gb3zk`!5\ s)fÎ՘0tC#[3XѦ/ak]0Q+GN Bl |f]xjg^4:˰{81k_,z\~J?4;n[N6= s]Aŋ/^xҙdo -=HfR`v )\f s#w?{v)8@d.V92!n]<dk~>,"x`sS*d.F&`:0O$ d%~h`Q`>zXhLŕDVo~\^R4߽Dv^L٘~'s)܅cׁsf 2'm*-%m)XÀsH砤& ,łD{4[ʽ1B6kw0@ˉ}q=y xŋ/^xLz%E$+Or]1҇Il+&VVs^[P-\ ɤ+=|,B6V ]0JLAJ$8AX&VLVȧ Iے_d%ھ^8wwqc)p5[֤p^7,:+>+HsY- sW~#}XD^?\O ,U2V^T!/k|^V`M,~X"\2f+!0{_FTY2% UBaX\TuflRֹ,f\V:EJ; ls,"S`]T6N EBro" Ѧ70 RT0N"HUXQOhX+x"?K!P㔊 +͙.W\_ 5d+ l]U;U}UwhVݨYe|Bi8UU eX,kѦ@ah簘skjUgZ ,qqz;X!rR_8WAP /a;1 2bŒ.zMk%"aAbY[e_UP IDATOlAVv79=8p`nhamuG4|ZűX2Z>>/"uWA VY \mivT,Dh̵?SzuRF,2W*#]#l8W`98 RDd#""`AcF1L^+I}2aUfÝ҃5~zzPjO,.NFafIuay0n0nQT5UJԡcYv&{sIɕʧ>tkӂVu`qbβW3m<""?Uۜcԟkm+c0p;NqqXZl8*s/DU>H_DC5؉f}B,}gX",Zpqy9PXΑ7uf<-ݏtUheӂNWT85=˅MI98M""*['/B]ۺT}폡9X+LqqgM2EoDdNzT#rbRWd2"4ssۚ=?C%>[ vxOYHKwפ^ΥtgRϲ/GE>S|q xHWUۉ˖G:Nas+Ƥ +3q͂YɽtW`98 B!@4 ,+`A2!~NˀæDdU}9f/L^> l\q Rm/LFFKUݚ@!(O/.=MtbKUԁS+ [/Q+[h?^14qqgpqR?f+PMۈ""23 9Ċ࣪zIn" َ`_uqiU}UUPՍE?I"Cja8T>UHc|]7g ,qqA̢ĮC/ϻs@4=qGsEdH&UmũܔC@kGUPկќn.` qWRoE*E{qs-V%"KH~,"+w{} "XDN  ۧۮ/"g |q>ctRFV\ŅQ}P@Uk!hr즶,D}0>X>/m/ȭl5fs\"hKvp^KD/"Wɪe:00q"!A ev].VȞsk1|XĹUiE${kb ^^SDd`֚ⷫ%}B#o꿓m@9"6+%boȁi4-8+F쟜83yɔ p[En:AU?_F V\>π"W{ \|'{V௽KGQgB¦E@!!71WiiĂl-"KU C짃}7~^5SkvLHpo+c_l""`qi,v">UPD ܩO0ns氜?U}CDd{aAp86qڧ_)Dd ,nour,L 89iNǶ@Q`RL{@ .ۡS)r0"Z Dd쟬MW`?&b?ƾ ,5NGya쟒83fNT+tG?}zK/)hUW="YdmnU^+:ߧo#>)o>FU,`^"_~?UM (3VȥiU ͬc+^R)j߅MCCQő4:.|TapBl>"""c+d e a0; S^=F"l`ohbxbMiox/#˾qW?LܮO{_E_d%߽uo=mZ[›O0%տTmUWz XkV({TU'Iy8o9GHcDf}>,qULU}TJW5O6_4iE>Ǩ9@l\FDvas>^d pH@+oU i0:?2^@:o*XX93q?RUOls'h[U L گEp 쫪g3qR0%υ˪a[֑o2,| n-Yw2, ͆4܅\ ǩjr,ovEm`ZȧiV>U5)4P>,>CCqrajh`ް}'oаZnٽ:,K]|Ph-Y}['o-ii{u~C`JgcUuRx_q`Tg9̅)Z2`N}iX; z|gF'Q/Ӱy<|~CUjעbC^)byBQզ" /a7Zڎ.%`oՀsbe5DUI6p|`hYGM.V.aW՗>{|!T_6Sµ]̻9FHi{qtGDXci:NU{SȑXx'PE eH,ٖzc8Uz,4}j/+nD =WoQC0[9}=`^CKo۷h5LLk8?Ssd_&lX`?9 ς)߁S"soy)myl]a?יo>&R`jGXŅ0c[1'ސ ̄"$Tu2^.8Nˈj4A17_U]J)GD`^t{.UQ)ݞK%mVwO#88 mW>CU?(ܪ+ ǨU:-Wa~Z nƙLP/!"K~8$7G_ƖImZ u"TUEZ,+AL7f=uqN̄u r f>Wڰјq3YUդ[p,¡̊dfjf"fB 0;WY>q`0}ع*ވY·x kzk)"hϋUx;)"3aKc}nq_'ogUqq;9Ѧ^U'ȿh_F{:V\Ll*N)7P`-&"+}1\N ydJo]2N_o-"y T;95#1G6( zt ,O*"M>c,Dd ̾z&"bY)"rf zsel7^Bn,[_T代4~35S;eM]G``LT vDB cbB&Οh!+G0"{ 0e졪-OqL+/$wً?qqA@7-6م6GO/ d Oc|"ޛ8 λܗ7rvYKEނYYdm?\#\Y1Kp6),50ER'@ c {uӗ^.lzSP=_:Sʷ0%IQCxzGb2,]8QDSղ{U:|X҈U붉.ݯ ‚ĬRo/"WO|Ob㣁EdvX"Uvpk̉Yl#"&֔_O88JoXURx;"ѶS>U~m)R:ߊ}98e}pWO^5:6sIrf>gƳ2!jsM]Vf>)po.p<}.u1Sdl*oVsΧEm> }I4C7*e(-y";tߩɱE>~ feDh.ǂ)\35~Wq6,i|q|HznÔXuu|Zan_ a4roEڋ/`5|ugu{^xŋnZ`-'ځ>%"˄MñEd1# >f ,]!קvƹU}[D;FpP7'uۺ@.{pSU__X/Ě)c0=S.<^>/ܲ:4-z ,EP$~EV~(>FUֹQc0VjFEp~U s8DDbØZ3EUIy=Dd.**MLVj WU=>U.&?Nڡ4JFfA4 6k gG6]EUֿb.1lqR{TqqKWXA!P"ʤ@' 7Ff$GDEt~qhGکDM+c4{'Oy 8B賐8;cZS9+fق7}^29іq f`eUZ`jGU(jiWZ&c.Usx i0wԌ+TxŤ r@U_(2!VR/T$8NCU_W0-bC]88][.SoR_"9ԗE4JY,F6 <+[$2c U:%uX;SSzCM٘O,FmmMI]Ze#M)xMTp.vP0=o9T-𻷌>N\TW}[ #LdP'MG SmBa5eQ\Df,rj~2Aq'ពqǙkdROQDF]QNc1$aA)G Vk݅@; Tu|5]IRBTvZL!ZH.'$"ñ1=sxnbO""õ9U;\{ \->ry|zo)u1'z>4COV[S42BΌn9VkZuqqg-[ȕ+25yJU}XD,""+$[!U"U`PiBRY1Y: גz}cI7=`-Y@>M`T4ƲXV¶Q{D UD,5e]Z9JY.k3WDDpa?N*D%88tnOvhﲙ̠zq4?n< "bޤ wX,|ԡ4`hRuI7 , WkuJ,iy{6@L=5c/"b1,}|vsRyJ;aVz^w^etr:883>sTMTyFܓ0Ed4L\eS4 3صRμQbKDN iFtmKjW7qՠsavgYyk`Mj_kez??`. \&"{ N쩭9J(|Ҿn5NWqqqE5,W5ќl+,`|z d+؛LAWN=J*RE!"2J OQՍ19qqq:Ɛn RAK;ʥʧ-vl""bA܂i٣ϝ'͟+9=IHIC]GU?TqE\)c.YCF:υ:qPq:ֿ888N]Q`>ZaeTȂ^z*z(Xp8%3QUPw$XcY IDATC.lFM+z^Vt?_;8`'}ѦDdL ];ߠgws>A!],XU;qqqAL7XW':I={|RUgQ[QjYUz0Կ+!"V6ݦI7Y<J\ej=$|Z@]M-GڴfT_O`!}~znQ?6.";ɋ\4?PMMiȳEDW>? Dp#ܓŭ@D +µI]k}&&=c=ba4#p+?FD~/aL}87c "s%ӬP=ND [*>o1%jL,ZPz@#"ȯD>Z ,BhsE"KI}f_D~TpGic[*$ U}`1r/O sȎQaUM}mYAO+I_OT@>R ,).?rEayDDFcDK:0B<0hX1 /E#NShh#4ʩu'D$ v6)TL&";pOt$3NUM~7i`;8"l |ȽMUo1Kq"wj$"'sbSJ"3?Fy=,U52,y/"+'Ǭ2JeU}EDv\\}YÁCoyl!,|)6;?".85wtnPד>Lk* qo煀wq.#_mft"N"r 3EwEUXj aI1s?~F$},5 xuϧ(+GWuo }ܖY,Q9~)x./ovp_%Xl^QoԜ6{lsJ\7&$򓰘Ta y:|YRsλ8wĔ7u6k0Wl%]O-aXzKqQ8y8N~ya8oE= ځ{2Qj?e":0G^xY0eu|9ʨߘCO^F~CM=\x|j~sӥX|5l:[,k\ZuQ} +ښWLs_߁=28GjbIT]s"+0` =!RL1t.{GG ^qб7[")d{^m{z}~fkCU 񯾊YUYlY%>? }+,զŹ8N ȏk孜,eϖ3bNa/Ok (2.|A}Q "`1^\M_6![Ҙ"of m+φ,ϋY=5 FUfa 0'΁el};OW Wb#"U=K4ǫ$I \XW kgUl$Y'DU},|$- [=Ḁrr~!"scg켆 (`gㅱ*,iOoV`͂_ʻkiyر=x•ZDfͧ9BUdw?NWG{t{.^:vN2xŋ/`$Qn2[فce|H¾n(mZ<3b^U^ȤjFw.{ecY_uYKQ$0jJdX7=yl\ ,w2Ap:ZDϣKNhankj6묒m+u^?<_sض>@*;? 2+bY+5X0%m 2cKnx.\[Oa n.$9aZi%|1%_f6-?&W%}yeWXjٰN<ΡW`oeq#Bk)Ǭ_L̆?E0ra;2q̚gk؋ȯwhӵ؃a \D1ŘIy%1Sfs:#)Lqf 0o݃+%jFԞ/EFEMa1,,~,U5o~/'sZ5o5L0;ty9#[EdYU}lmC#p ބ)L,6)tv^/8WCkFhMq[`kpX3ќf,q1w.{̢@^fcYZQ6ESL*v;`չn"k5vNJY6evnZˁI4_+Re|ԦW޽;ѰX,WYFPlZ:MD6Hx_T;&aB9, y$6xs fYdJzy"10;as"8;9Ƹnkмxŋ/^`ʁ2`yi~1Li ,g0Q<ǁn 8"i`H܌CL,_E3?P"10R<Ȟ̥J  v2柁 dȞU!Iwc݈,0Û_5Z}9} >ݐ#7m`1\2w>m`˂|F9?isX1[Ҧ+r39 Sčǔâs6܍[`+_΂)P1/1W)E#h\+s-y_G+ӊc̑+Oݳ^M6`{_6ˑ S}uUxŋ/^`1EOՐ_-/S`]]R-*0%Y0Wc_o)Mk*iVf2% mNNW|V,fHX1UFk=U`}3kZt1s(]o(}"?'c*ڤ Ie||z);D ˓6߬#U`M lT kj4UN83 iV( v Yno z[D~(fAKB881gULRHKUOE` D]WMj8sꁈƬ2^~_0E4Ic{N]Fy_~>?4 sRw ;faZADĬ2\ Q8OksnUW d3#c#:'Ef­0 X0 ,cQ1ZBU`V1 2 8]Uo(v̥ELiF?Wէ Ѧ)N,Ldev¯)|U_їjAI6-0qqgp@yǩ/a؊fg c'wx{Xy%QDfʑ;(ZR0~ lm)%< a}uuϤۧ/8BGU_Uw6)=3Ϊ&hw+IwU,Y_,X8UTc&DB<+[*p?3߮ͅ,yQ˄uzO zݔVOƥrpD屎X |QU:"4cV,ȀX88GϳWY>ժzs~;o\:ךOxXi̅2eSX@`ӘW~}1^U'VȤ oH됮vMD),xU[EzEzk%c VXl+`TF7ϛpMًz+Gk* U V&I==6EIljH U}&ﻬq3So:rqfGD"NhZI}L&{sIN\QA,UWUS;ZS_QR/9i_eY#$ys:O bZs&9't"VR1ԡ}i_?ʹrS]J8TDZ,EeVzuAD>[?Z,VIn+:yg%'`p0}h%"}j:@o""-XvW`98 T85==˅MI9S$  o 88U}UUPՍ &^4[^cJ=t]`ތS2?ӛJ #+qqT U:a0$5C>v>(57%)TEzf*LT$cʾi_ds'Xw%VdwO3TAU?\k,sgXC'+LK;F5֧+qq"|_DVUՇ$2iU["rB*mw>aN? UDҬymȸP n ݗ Zhʦ}MODd\">{=Dl"vW;6<"/bˤ>x5^"lWiI,Iގ6d[8c%s,VSv@OW`98 C5/}-g_``mڕOᨾzQaa>/I58{0_UbY)GDv3v ZCD֬jv6˟^9k_5n= < n;i}:Xlwc)"b%C:;Q XOOEdhae}?XR#Ѧ}aByW;4n1MSk} ,qq&u~K&rd.;Uȼ4^:h]U8& 8fimAE:'Cٙ%rRT A5-$XYT0sT?IUCP'hv9Zة|;tZhIY EN< z]EƎ kq0t;L@\ҒsHf%)Y3I$HA$,E $*A2%.MsۮP==3{g޺TխS'؟ʀ#Sv)Iwgf?cj?vjaU ~U SQ"XM~'^d%j}P`AA ,VjbfPj?b-1 3(:9,n <%4cf[GW2)_if{%T|o_ɕˍ(0G*c/5MsPm8r 2f,`D7HsT{ljl"QF|mV왩H5yZfv4VoSĜR[hOҚwW̎ ɻm1CH,JY97C'$U H!W?CKʽxpW'Ri)U'8VIo'wT2@R[-$.j3{ h4{8#~ IDATMҁ}w?_.?%e[l[l[?ȿo~߶o.8R]U픭{دXWT1 W}X۹0 ˾Hsn!&n8dzWVV=A9>Cf45\ ~0JwTHG[qe맩Ln cj"Ϻ$mf4wSo)ܧ VA'FU0J.}t&i|ƟF[π!C 7I4XҸ*zKl^7{b'>W}3?Qܙ]ois3UmB>'j)P3b`AA p:~waBaוWi I:4`Yϕj7tg`j*# /)Ҽj}F   .af_1eŠ?kXAl:B[E 1   [42&uB h{ k8ųA(   [ْi>óA_gZFl=<yS,"VAAAtG~g0:ZG+Kgf_I$ 7|}3Ji3afgw u0  K){g0'4(e% änO? _K3fi3`y$tP`AAAtdy-]ǘXFӱݽ$^̾R<"XAAA}3 ;ĂsP^3YoOHE>N(    >Md!    4    4    4    4    4    4    4    4    4  1o۱ݖ/ `H  Ό5ڛ6fC' #ilywQ$ۢl<R&K3~]{-L% ܼ<]AA5BAA().wQf`6]#mW,0hvffKR`nI  LRe  ڄ|%?U3UJAk٪Z2Sp ߳uSϏZ`*>p   EO UfE'0,?4$i,uyG-cA"X\ &VKHT sʫӁ$-iv`aLl6|l $i1\Y=1eyKzX]%.ik%[GIVkH&{?PA.,4*4]M'CҤ4:oL (B(  zl -i< KI P3vIV҇6[j0̦mX:BRP\Leܟ[%]Փq I$ѠmOXvm{O<`~^NG_tne2wKzCh`$S̀KnkHd&ikp%n%VM-&[KzZtTB SƭI 2㿄ǰ{>~W39 zP`AA 8OcvJ*j5X&95S58i"g!`Rl*3N]8J'W-R+ ) |Vܻ$vPqw0 ycGffwX<6C@)nUy(S5Ӡ}iK3U5ac-ݳA}P`AA-mA=o+ẀGһTZ"df3jF>>lղ½+~Vꥇ|)M &f6:o}cIVVIqY$yohfzϯݧ.w5*\ ꙪTEǨ\y(c{6O  6n?ksiV\ 7Ȁ՚*kI9̀* n$}2W}M;xDR>y6kgӼ`{rogDeF,#dFI[`|\kg UAAATZFAC{yKe[,VoHo5;w_K+/Ry>KQp5$ZAA02S^fvl"H# 3;XLvr q0ksI}=0w^5W H$ff.kI&V3[eIRKf5aů[nAU 4$]ؽF穭PNmS[AQ.lf0zE2?:!Fl9`T(28 #Hz~ U\9Mr#W}1]79XhQnz+Q?~~NdfC$}A D9kA`3^ҧ 3</zU%#3;8&Ù9 ¿5Xf;yM1㿗3%ڂA @B1H>gVӓ &(=R̶` Q`Ie3P`3Lr}v$XAAx%W^ wf;/NU6I埙hI53!vx Ί2ʚYSI]gJ "*>3{pOll2lFfpp =: `/3{TREx 3[ r lQEzxuJX+A4[ c$Q}JZk?  #p0S*nf{$)[}\ S2ܚ1k6ҋ%̉)yIYٝ&6CokeK̦ݔ6Jٮz3W<ҶE1g3cW`كc+zJ:{5ٿ"n@e;_`3s\Tώu\WX| |R|Zg#g}3TxIuXZKCuڭZe溌-ئmf!  RK3{X(x8ZR֭%#}Y9?4_JM,m3JlAYXL IVx\"hQx9W~% ӘOKo ,|}7-דZDef[a>->͗+U?٫;3_vȳdfŕK`~7nY+f]<ù) sS&&+Hͻ{K.K;fK4+$ajzE6af#RqI jx/   muZq/:0vAAAA%zU*8xlI>6‡OJߪLf6XUq00x]Gl()n<~O(n1O-iqHi*i @g{0``=n}{)Pi;n٥54#1pvv <;j*:cZ> -oAAdzTe#fQUsFl7#$v].篲u3YR fʹ}A;3knOv|X ~"V   bX$`"knnF&)[]=Z~1n8nŲ05p}Ku=<" g$~r{H'U)H;K}~M8.}!c]1S~!S> W^3> @bX/Ry2I?W%)SJoI=n0p*`8K:Ƹ(+.+iBYe-P}ڹ.%³ٔ8W^ \gz_W'09([ lWryd33I'א7   Af!lf/z`&N`zVX)~øHi%}X`\DZNқW#d!|Z{+1TOo?np3s.Z .`f!e$S\#ݺ>Nt%4-?eV+m[MHB3 +h- TT:;[W|\/曙m[ALEz: 883)'R ހPVhOۚ)J\ [C#    ]bv<>dEa8i.v(eZ`uB IDAT)Wi@i4FY)J2 lRM %LJ٘]7US^$%U(+&#)%NUZ/q:jhf_Ryu}w֓ҺTFj@͸%\58YI?ώTZcJw(}AAAP)UpN Ղ`f([[[@XC%H_^SSx5;)nZ=]fp׼4S_6_ygoUhK ]k)GRe]V1j e2/b5Lmmҭ5tb#;3ubE3x|٢AAA3%+To%kxqiJOOffpwǝ*7&Iz@M0:bM+I5y%]ik9ZW"^0Aqx %3LBc$3*ꑿ~o5!K3m%/:ikkA|;mc2ܼ5Tؔ];}AAA (TVC?H?X/PFKuTk<+ܴ   :BʕkmlHz-Ru|VW ˻u ƽJNf6Z`=+JN4>bxv$]ۿ,.9Jƒt-^,uOkx,KlBqly`TK_: cAA$,xk$@QN^m`\yFpG_\y3@퀩: .T ]?9WPpsjc6KYCuت!~Bz|Fт   ̾^9ᮆowR\;f6nnٖfG iDZCNTef듂_LN<ٺfvUfk&cO XI0ix)hwwfVW`Vj_u6eZz̶iԾ E sP8/hf6efOݖϺc)3;̦msS{-O]@bjjy(W25 =8 3˺Cz(/Y̞5,3$I7dl[1'Í&35'3;8Kҧ9ٶNAOvf.0s*qmaf%ׯ;$}d¹>[YnIc$of{SVuqz#yC sof;7I\g|>c$ݝ$.]0cIwdPfvT5=p[g=2=ܚZ8X?(/ſc6Ws/3J{ӀKÁ;kR&AC<  I;(_qA\x1]e OlMkN톂cN,0ָ\ 0]9.˵Ⱥff`6ˇ 2-U; ˷}{Y!:Oc~soF֙g4z|ڿ+n^ԏ~Xg{j-GM:pws xIy x)3c& g׳] u$}oUt{]S1V*jQ%KX}l\u\ѱk_+YAqD#VaE I'59(''mcoԾ.1kS(Z;$cf~mJ9`^y3qfL9_P.&yN4 ߐΟWJO f 8Jbku9&[=%qk"khj'?wp]X(m%!f 1f{!P㻔ߤ%. J@)FQoZu{|=])zyxvx_@^]q:oCqK*MfAʟP: AHO㊁pjU_?WyR%k𺤚ʯƭf-FT0K뵤523DG+:Aml$ŒeYn?JҒ956E x؄wP}:FҬ70EpKU~ka(\3Ⱦ4:\҉ݒUR,ֿdn3%afשw]a{q Iuhp#$߉:Ey{Vj%IM6p`%.$ր$=t?)I ~OG-G-$[s//4jI Oڂ $fe5mooJ&D &':yrAO½7i_ܫ 8%dAAP3̾;J֔ܙ!   |+/p}AAQ…0 `=e'ͺ=%i 3[ ,Z=>JFϥ8f,m=-,_c]Zƫ.9xx\Mjx̪5('s2x:}f6-z?OEenII.K/JzLym!| |'x?ަQwqX,{3J \;qkY<͎۫4`5`3ޚ_+c'7wU4N[l[l[g7?dӛ܋2ݜ&͉l=N ƨjzrΪ?k4$n;u\Viwl~1+5xsVݝ滺xbZOuǕ%W3E3vT?#-VMǰpm'W(([cp"dwʟoJ,fV8 }8rsVW߆VthQٻJ5h[l[lunN_-+:odKr5e+yXF pV?!sarC{t(i"?i[+gxOC ,\slKgUԶVx`]dz XJ?6WT_>xB2mפ-kM\S՘opH$`rN+^ L]:WvZW\kWrt.ϴ]W$d۟`q`JL24;9 83'KU͎+gih\iGvRiM9Xkb1|1*,_̴87c=`hvsmҩ{[q  廦Œ&fݕ}r-8E֪IU:*d/bf[gtr`1@%ΐtT]%) 35pnA#ͳ8ptj Gm%} |Wb#+%]qS=ߔ4NI$,C ođSp7/qn6+nZCu>- nX5)ؖrkWy̶}[f:_e`*̳WJZ[yօ& ¸e鮒~L|BI' `3۸ހfnyU_*1ҽ{,gO  ۊ7ո0WTͳ5W 56%.{`3[|4*Br}yj"nQI!P {eƒnhU88*1 y0$3'v 5n=Ub"nr"yf_1Vfdre1>+ W 8gu>9<3VcpEIHzE ĽENu(c cMSqz;%}F9Q_#Qis-=9 g,AAz!B*3-ef#n3rf@ây5#Rw0AL荢KkNiFhэ34~ wHR[Sj\XY1ɥxA`͘o+׋9$3{O2)rVB^)..M ;MorB/+Yu_[m(8/2lĻ=HK-Q{VVAddeUIٿ2{7~/+Ocf c&%13KtYת()U!٢©=o@k$e[.?XüDZHef_}ɮ|zzNH[\^ ?$F/%J̋;]nԌ:{יּ,[abj^{}߁5Oh{r\yB(  fڂ1-R͠%fɕz{={T5(A![(+W2Hf2S?SS~6+)\xFoR$܀} ;=nIoP7d]f>UeuX3{ 5py?{c-*o)zo]'sQZ/P`AA @%w80W̜ٗqeV*k(neBzc-1Sd{AAA>x%}^tó^{qo< f;`4x(W=w7di+.&KX8̊ĸj|*fA{rg<~<'}IJؐJpk떂烮XEL 0mݖ71i꜋v[w1묇f~A0%q /ipEz73SZEkT*!!f=V6s|ִ-fȿjHzʘMlxc`bS2m(y}q'?hpY 3;&H8/WD_]ͬC5.fY733ߓkQ.)ĮUI7up De,?:pQgPG TMZu{? IDAT/S؄|?_e?6?mP>?uf+UIw`ÀRy3;4)kʆ7heMQ.~F9.fv`iܚd {e$.a[,\lݓqsscf=BA< ,)/Ace28ʆٜA^s 4FzHzg;rKU_=.Fm3Y7֤x&/OV\yy3N%s7Dcfv/+:i̦Ɵdl}nB x'?3GJI4[XrVٿl@I%Io 3얊HX}-lV%  fv!fs*>DqTf68{lT<'rHz/Ulgv-eZ^=E{fK'jeܜ+eh8% l6?> `o3;n\ ȔҠϾE]_sSMG,)* ?ltyΠBw_3]rmAuMFR̊l[Uu۷@^ 8S6ʺQ@*/J.?*+ \Ϯ ±x&V5kA}Δt&-d1il$/ʫY:Áz=Y$/t>:D6HY ww[ hM$o779z8fH ^)j.ٌ $c+/+#ˡq~cf#j5NsS5m'<)efjlfR6ǤuBttJE;j+!onYAʵ}lZ;^rY2=jSWv15HkLIWfVnH ƼT<\k٢`g@$9Q3fNv|7ہ2U[yQU{B)NB)*]@@zGH"M?{S@zGkPZ BK9?}S}If;gf9%/gOGBKU?{-"RNTUWD뼆H "2`T i8;0Kϙ"VVD"S.~NVՃJv7bB/l{R|U}żӼT m0>Q r6y8|>{):l^V t8CUJٽSsZUuonRWBUqtw`[3wcq/Nvc1Ykb = ģU=ِZ[kf]6`?AD6üżn1c :=oy̆6UպIY ̓ fBUj /oQš΅9Bc"\kb7yc*DoY)1[ݭ%ܯ7)ȁX* ǛEb,U:Y 3NXջvFjQU?0|$"kcƋ9?V!{ԼQ9/!OL9Umg5Ϣk5U=p }= x+ vͰ׉wc>3IjY0z927 ^AK*o1&K橜m]NzoMVseK;\ 3e_f9P7a~k }?@U0DQ=ϓqlӒ$G}OR|L[uܚڑ+L0Pgr;%Zv$D1 ȢJcZ,ҁ+?"U}RDV m=va+#ݫ4?t{D0`Q%@,V򁝄yl ^5cEo*USDN ͙ K4vfBD{ +٧ Ts#j]`c$ תyH!SVEJ0~}U}qKn{YσOrϨꨂu0Y0O6r""=}ZKtBw06hNwãNQ[_`Kʺ`.cj'|XAQKӣXĦsa4`祇Vr=̊y]< $ s{K =ܵUub'] ҎJ#H$4%@3뭺E"nOp`w,؃L1O1Dxw+a8J^=2UWG58[==*gxc#Yϒ{9GEo_+k99}Nf̨&Uw^Q5i8JISMUY ص:9h8;l5-~ *뽜1p2a,̹YaB*cǰ=l_berxɈ;w2ݣ*߫%$&q-b-4,oqCJ0G#b6%{`Adkao޸?=)Vrt-hùx\UT;3VaUjp }`iN{EdUJvWao7XYMꟳMk(.Xd~<رZ;&hTo"sxVDpU[L8X)jżVƌ'Uз9ӔP=&*Yr?S $6#ޑH$DZb B[~%DbmAq#GrKPt\,1icBHޘ<ϱ c3b%YXx V' %V"==R0е~{#,19f8<4/f y,:"7_pV8{y` < ccw~XEs%qDUy}~X 遅y+~qNdҘ3]T®[Ȑ]2o3&'s+h<}2sKGoe1× >{ZIb/Ks+?D2װTi:-VFsHq{3`~U:oF 3$N~aC?_H&>U Xqyw= r= 27 ..!$ʇ [--z~ᚥ ު3 tz[.MM/ 즪f|~M"U=3xTh`;sb?VՔD7o.6y%9ajH$D"MDU?~NKо6#+2;,e#UvH$҄SՏ Qs]<6_C g@-ˁT,}!$|y{q&veqv<6NVz<kR+UB"X.G12 z$O*mg[%X=#u kbaȝi 4tRUwN#24r=5 Q / f^:& Lص?8GH$D"H$MfX\\}(Vo={_$D"H$iS]Z cJ >!ueMDz9d?0^,P_+)sL>w kVɄ7 FҊTe~Btj";'G*_ -K}nF$D"H$i1SKU/"?,l`tiU,"_PP7K>^v;'/>4'{c 0BPJ'Yt?X{ c4B $b>tCtjDDfr-mZo+i EdNl{_$D"H$iSR);3P6X8sӔ>'@*2g'.M֧.nkU"p> Z3dȷ(WQ3^j2 %F$D"H$i=ݱ aCQwN:xieN8vfY&?gs4XO7(X.{f()Wu]y~o ׯؿ_}lt>1TB!"uUGI0"H$D"HS+,>0~t$}6`,Wy+Q\Ы3/<>~="ғq݁V1U='~ME/|x 1UCYړj=Щ,,?28ЕF$D"H$i!S`y )[9+w2xoyJED\*c||aî"<?7<ȾU@c>u'R+"ae,*_U}jk1|kkNp}AR]Kñ*O7ӌԇMNM&?׿يt޷|E"H$D"ۃxP灧Uk{|AS@U'{z0oC]Ku#UDdAEdUh&Qyg, ܖeT`&6ִ s]POgپMx[>JDœqeٍGvaJ2IiU}z4Ӷ'm~ƈ`yޒo"Ns-!"+uKLH$D"H$Rր86Xޣ{pK?7UtNt@:.WNn]jX:KSa{2-AU_ o CJt5NQrCϒ"ث`y'W ŪnHU?6tfUb{uȚIުKUьmA}XJ"d̈́|xO c҄-Ed|8:5BEEdCۊ~Mj 4vDDXvn~H$DSKUVm)"̒wƠU_;H:Tũ*a(pt^أHխ:AU |/Dd YDd/` 귊SD$DD~z8`w^"!LDrfZ0f ?xn>i"28ϯZuETn*Y;Q`n;RzRU}T^1totl vfB(ϤfL{#8OjǞ-"g`l?;ui*"+QK87?Mf{,Wb:DDL3/ ۑԇo""ߺRO\?lޜ| "P3x ADdv_3w]3xy]E:Mb IDAT"HPD"/Լ7FjJeݩ"2,{9ItjU/T5,DJ "+%>TKfLҊmNns;e7wX{{k77!W?(&!Mo_&K%E4VF@nqpLx<~1`,Ɵ 3<8?#7u%F^K.c_L ʻ?*yfB9?> S'm@}<Ɣ[D<%Ů;Y0uC9ˏPy䴕_Au.+ ~."Z ="H$ED? ^3F|D QUs7hBeHg]+g$콥"84 Z32ԅVDǼc+Y*,{'s[ ?o.0z!Zx ܙB l)ݾߜؼ3Vuۚ a3|V-P!X17t $ c᧟õ ; ,}oiAq$i .̀_v?I0%#"'` sTX\V')Kq1~[$L) X׫䛴X ԊEZ4iGD=U#D"H$Rh/P#HdJH3UW!#"KH`=O^\0 6_H$D"H$D"|kYYݺ!K0D"H$D"HU#{'༯V%kD"H$2 "kc~nRwN`c,``&,GX[TfCI}z8/*V$e8jqy\ "@C"㰪գT?r" UD$-xU} ȜU}¾jqLO,O[X%绋r#,lN\XNX+ZGQDVze|~ -Wp^xO6aa=ښ ';]/7?NXƗKTM'X1coT1'7;6wT )bCg :<\/WD`b(7xތ9cݙt}%%pϬKV;&cs"dNf&ꟿ6evwhkt`{VdQmҬNn,v<:J$D"n0v;ֵw[*+68?gy1͢nx̘(楽8%qVv`]YO[XD[?j Ł[Ez|c& Wcn {x^}f ڏ%(kxZtyU}?t˱*"Kck~"N)Ije>"w`/8;?cG`|~nMEdSU}Hin܇?~h)sQ.^{0*v-ͅk턌at9/`v뉭<*"CUS큋]OcDZ}Yp\,"+юeq ]v`wz_9;y}+s_ ;ƪiʐoR>2?]1##uKaؾ":KC?"iFg g8>Xn}̐땢A%S #59Z3{j406;jR3 at?y` 0Dagk'.`xD{]E@Ǔ3Mf i]tsssf[l[lulQB~iO>πumzՂq s T4`aF2`tG}̛#{LO2Fnc¼[c|hDZ"C~z8֢k"4`u ըЀ` ;W"Xq y ?'Gi UEԇA}GA:bsfE?s6z#Ыv|$`0ÒRC}Pf : }~qH|hR iXÌZ)рd˂mlNszꞪzMUoUڭc$D"Jn>K:Dde`ko]Pwaa| DCTj ꀈ ¼><ҋ8 {nΧ{"4!)vd&RڇjIԯV0~g苅jf,g!Q"2 0 DUGcac +R!H7갼cI=m.t;yewfL_UÌm|+ny$Ņ#c9YjI}l+q{kq_`UuDAK„]B*n; C+ncJ^#siL4B4`E"H$L TįJlg|~H|NTG6:,%uoXeF-UC"3~`W ~c1RKԇI0~g eD"" KNZUJ5Jxo+yaU0UP ӮՎ ٳIO`|:7¹Gw?Ye*+U#";aĵ$?DfzBW{`\G;:X>,qsDV$D"T+"/gdQ~%"a|p01PP;1r@^&ܟA0PV0#)!eMD™CVU3T53ay|9œWUQ*t4ntfLɹJYZvQ/*_bvr{LYգA){HDJWҺ%Uv|}|OfǢ9*轂=u%U %"E={3⅜ - _bX>s+`wXjg*jYYNUV}%˟V;6o>"r3WĆoUNˁzw *"V48疷*soD%vTulV͏Ѹ3t/ B]mq/Uu+;38ȣVΐg'zb2$׃KoU ~E}b;r`/ LN=/7ҍh s/e{b_$ "l~ȁR7Y8،l!DD^n.W2kwX06lH${B ^$^'D Acho+UU9 :`܌_[U OUwnjWȅF™R֝́=7lJ9V`կ=S{LTM;.`-?x!zr~zBZؕɻuU}Eޔ{GYXU-4NW/ .G "t~eyE#Dd ?WE`j/ cVUլ*aPE(U il_TՇors}N*] ~M>V.roDHw!亄ɸ:D>iKDs?^~ Fc?/-f,{b1iyND6>g{#5G" ~y"2^y:__U=ʆؽK Tj!Hǀ~8-Hik%EdY 82湒;BX b+{2)jW?K^D~PJx{0x[>GDŠ!+UiB*Ǽ?̗&/";'tM(=E`oՅzmQ#i)TqòWEgV策Gc5Kvz*/p8{FNXk~ $\TD.37aF͉*<-"J ] {`/HDpۜDRYI/sC18 9vUyw2"2D˪z3'5d U=CbO/"{墪_9q;f {~AUqa?d!7w̖ny(\yFyAy _~kM|wܿVUc U茿cy7XtrN/8zbj޾wݪz45/0/E$}$hy5E&kTiUy-]{aqZgT EfNv)U̓ɄSsFoz> "a 'D@r̍0Cu܉ηv T kTu8$ئ3*{ Vm?@Y}b-iac/5hcwQ,C8x_>oX祌^C0Cܸ~a2>@9{ |{X[b/muGedl@[̻_78蛳kV%< k͊cς=O1$X[hccEso`YXѭ/eBK7> 3~%u:>sn6d>zwf˝1POR ^gWז8>cr^ 3$}>ׁmKp?6 e+[ XpMmKnOrwl+/|0LDﯴ-U}WD¾zG"Ԏ"20fOڿy\y YUVOD$̫ơ?al'_v o\؃Jcyp9v~Ƌrd }?{V2Hv1ϱٱcKw&=nx.lnU Mvq)ߓZq_i&.<.U]m=^S{XU ~ӮȔKwL.ðiT`ai#HdGU'!;}m1+7x=qJ|n6^q'<|,j6njVToՁ]mRǷWS1~ qcgbnwkJ*N%\F"" ??`.bnovRe0AیXނ$űCb_K6<+5W{T5ӭ;#"ca07's6}[XxrKRvX!U;`8+;s~_z.glfƮ1KθkgloIB+"{c@ӸHUwu}cUNY KnfgXlyNbucoD ,qjf^/Tu@FH?^Tuތ>S'gmU;'+9@S?OU=#9NUOM]NW TU-(#+~ "XUͬ,Ī]Y1)iyoD)*s&j( unF"H$i*a{rUW=LF91D"S0V}%y*6 !"b%=%| KS̫gEnF%׹J}V 3o=XđXΕrK7%X B`=V"[ $Kb%ٶ9]˛4[acUbՂݪ v~!"Pۚzp14f%Uuߒc.ŨƛXaA8ٯ*ۃF,Cn%W)O.3%|xbH`gY<ŲxXa^1."a^"{LbH$D"]"%~7 vªF:rfUD"&ݠ"ܦb߭U(^2`Ulq\!' ^{2V5!)O0='{d0n/7k2ʛU%>Jdz:=?ܙO ļ ќl|-UKʒ~/[)X/< a7y}>9v>ӧgc1f>3ΎRO yp;^o"`@np@ dX5a)H)} Tb#g) ϙ܏/!4mLz5s,$q慺)Vk¹[l[l5a/֒ߑ} NOv2u-a)w6p蟼ϖkMY;x`=5J-\$*\{ñƘE[,t̓1U=-S|["΂}nvPU" us,fH^UOCUsT4yY;c4(qvBW/Tul>0RiCU39IZ iƫg:[5ZPv1KX'o0;}{[Z![j9jW+X{50έmT9EUVեKRyz#fR:_`y"ުwU:\,oS_B~Uu Ly䶞\8ס(U-PL/ Hۙk]f./oU`Jv 70˛睴QzRRԻ˷p>pGU?}%6lN//zVx}뮧G"H$:^UTՇTߪzޭ#ۭ[$bJy}KUYԨK#>x#ETCǨ `ɗz˟2+OU%wq S%}@9r~QY[A"2#`veD"H$D"m$q,,Wq,J}hZf_UX09"yɾ3cHU90`52Fg_((sLBQO'ZHӉHd@Ds=Īm'Ԍk2D"H$Dbjr> ;E#C) K#u1,z`|c[8~C\#YT:&.$.yYi+Up>hŧN͜;H$D"H$%LWW1T%U]ㇺW9aTQoD;`zo_UBU*u]r~Usy X[[AZq-:*"=*TeK$D"H$}p:pnl*QDf-ciU҇0SGj}e]蹖Et)X^bF^G]1艅:E"H$D"H[TNU=@Uh.OcΩK.Tx!X?OBg_(/)ʕU ]o[ލun"ז?wE^ j>u:zM[H$D"H$t V7>6H},?_J6U}byE8vIy˻U pkӧ|~V1a!YhP XAfr%𭷼3""[xt,/X_kW˻c:x[>XDX[>*C.>v)("?V4zn@}#:9*E"H$D"H,^DvGE Y:y,QADxFW4S >EDdj)H~Xy,u'sYCU?ˑo%("СLyDd)`RկͩE׋H*PA8_W]4mwx)?QU'V35Ddt:It@D"R2DEddFkFEisl_BNt>D"S3"Yv7""ڭ_݀yxC)ުD$3.Vq~:- U[5p3q>53U c"Y֘,.P o(Q3z 8`w{ۉ*)cnKW'yfDd0f l(̈[ր-"?yFl_:G6֥Xt7pNwSndTflkE:`m`;"2c+DZi7蔌|Ә!GJH$RL_9ڨהN?kKҴ`9WD}ZHy]eDdYU}:M؅l s#"놹FWUUkNkO3 ,]ye6ZG">3[.|>W+k٘Iڊg[HxJUkފ"2]p`?3g^ߩw""=qIF 8Sc:ػ 4+Fc}\2kZn~ C $Nm(#yWUnsNKC*i>889x[F.fȫO}R1-AzfXO oSU{`T='Fu*ڒAr9@|Xx8(`3& }QDeXrKN)U遣qpΘ3NxX5*\w3I>iAK{$}? 3 ޳'hi:#L_el`4ƨ&u@U'9RBx p~PRmsQ+"b*cdsGbc@hU]DƂeJϮ{wT1"yRE^'g7lY:@ GUmh~$"b~̟<Y0bK}I>y+r2鮃1Cwp6?Ɩw!X]z/ccaOlٰ:̸yVRMnތx~- xF 8Ϫ긢M5 vsbYviN`Al-'A1u0FU;q9{1~'4* N]$CNjvvFDN^f4wt*d~DUb62X+0';O]c=V%l@-Ȑٯwb DQD##i,ʪ!3jGU_'[?_&ۂާ'|WE]a0$n88LIU `ʈȒ"B c>{g9888T XN# IaYЮnR888 lf 3Y-lG2~}88N?6]X7?#tƠ~x7M7+1ǒy/ťxq*qLDd.,s=6Qw*~fGȲئ9aq!?vZU?oV "[k-::CD/{@DVb-2[bcb6zSU}v}ogv~שK}YMqgQLNYt~6:n-h U,ڲP%I?̗||ZGP v"XȕTbf]Yuv-rw?˭͚f6k{;v ʯbcf ͌wzyIxMU_h@{b,v>cDW\ CgkX(׵(fgc{wzDOOFeۇ#7 c&;ج{ɓ'O=a?ԏbuh I?ub J?`;.m2lpaFb;֖1eu{qyY_lf.*97 yq۸'*3vλnY8Ġ=tIIkWF|m*SD`[)23䴹po6_hOvlDeHf^@UMkq7ΏmCq 6.,b'#xX^TDPՇ۩GcPZG9{ClgmMu&p=~h2#v?%xj@,"wuqb"W[`}= sI8Ha}x8gV<̌Xg,[DVs=w동k1YzbLamqpl/7ؽiu`-Dd}U_F = Cc^/q87+ pY(wv.,;6~DD]4͆_y{( IDAT2F,g&8+Nļޞ)Gv:)ϋrDVN+iLۜ1c7pG?4=yɓ'OOޣd 6%z{J Xc0%ǕO0ctrL~"P伯2H~>j'J XqH3`2Mn9zƈ1OaˬbkihD :I% c˭23~_~1ֳ,BQ1J &#دH XcB#;8\xLoQ 3&+sY H~TunϦvy<%eHUgBCj\65`O'˕{ʨQeĀ:MOժz\UP/wkqqL&Wj _!l OT2x)Rsba*͜&4;W(2UQK@Ga"uÓÿ卨2v'(㏪zI?ѳ!t a|KNWrJQ"1~#v- 0 s EqP{ʑ-\)!.wY5\6 3aS(:$5.~vmr c;Q}lTa/j]%KT^l]%0BU}E"2M%,a8:t>VRJj~WDfȑ={ U0,qqYUQ*y*ɯjr8_ v /UK+p&#C땕ᴒoME=IUW+%3 X|d٪:XνѡJ?$D>z2}Olgz3i.jDd:F)wtfN-$Qk`]U%'XFUh.LxDth6`ɣg$j L3{r"2grSl)hUQq88ΔKeyy`YAssoǨ%2& _UW*Am;M/G& Ju{KOyU-xl͘M>AR=R/2O1'TfC+x_eb(Ng+aEezAX>R"ȳc$P%66/"_RX&:~uI~cdo>h>?DdzjDzbKPYEܡU3ŖlF7^qq<خ_ bt"=m 2$tR)`=='6!Y,y7zP]JSog"]y *^H@VS5(K':8\~P7Ql0chKAUNJȸHsHgn@W]BJL)Ξo>捒'&2ye1y}$zD b[n+0+:gbEϩ׸P+DO/cE~5DZ˩/"ӅCEώZl#"֕Ih_z-D5֫  W$C'җI TɒFu@,qqBXbs#&ObƖ5dLME*"/{]D'6}2<=5*lI&-U,IIjk%^KQfE;'m/b$_S%G>/B,hw6Q>ly%%#؈`P{PUwq{q"LҲ+v?;v+UVxrb\qs0iF#6Kz߇`~qqg_@Z0U$DDf3"";ae^ /?TտygµKȓo; {έӤ}hs;U}?x4 uULFDVgRzm]M {."b{ÌV)+cA]C)ZM9fqm1(Ya|qqg`09?X5n䊈v.TUEj@H'5U=MI};wS^1Τ`} pG?(_U˂Omݩ'iUu.pnX& 'l"p9P\JUS:_\*p QOCbe*Qg[CKUʆ0lL,N}À^ƭRCU!5L "2\DmaUVD*y#صUs$j=SUHuzq@,Nf'〿4Nm<+G_?Cs[T{8f۔|CwqhƘ i} ܀8830H>m_́PI{ ;a8$>C7"2ƌIrHidYq>X" iJ } mQCoSkd,#5R; `RQr +{ Vuf#sp> -CUEP =U2^V(?ly,lz 37ߣg0wl'x!"޾wȾ ܐ#z,ܾꞕv/SkxU x/:Toc un,qqn #Y7OXDvj/ "ROXD_(?vDzaX,Kg4+p̒W&y gi;03_/z߃3Yn-@Gxjc}:߯N Dǖ!" *88tU}XDN Y؄YM0Q5GڈWG !B!v"2>|>AU eER;~ԟ/y1#V}`u94X;C1#2A~69%jHU8L:bKubTU=9zC >yGUkP=Ddu`%`Wh`azb IozwXO>/?U}#3Nl/"?^ ;cٱ ^zBm_=["_9EWO׎)UchctcȘrU7RU ,~WUՁbK j]΢|z] xWUcIǮ{7٘K`@"/Tw0 ~&K+GeFj{ b^~aiײsmP`2T&#h#̸p-=3E?vT':Ed5`PܯcFER;؎EvMD_W~^x@DN [?g-i8ٚ=Ϗ00coѪZfX1|^SD6 Q0ịxNq]fc'Oj㴊e+s0>2{X}25nT߯aTw1o% ƌt񱗁}k{?%uNExz NEOsqqЊXc^WTGT^rg;T ~zۑ@-AKTUEdOjĜ/rdb^W?üPCoaVaYccU5ONU oYA/T5w _X"-fMn^b\9Kay =3/U-[i::xT663kU5 8^lymyMO_\+Wx]̀-*%"/a^ugebKb_żfϳ׀GST_A/cơ0#1X]Y/qhU=Dy8i[`û^ǮcXaE <3sa^ba}xp~Y{1U*ȭ=?7ÖM 3dU!"[`~ RHnjo,ꞑ2vo]1I1}[$\10lc6zNqqg`#"hLĠqڥ?2’g|HUb#M1Ȱn":jeSZelRA` `ܧ9EdZUd>ZK[~ωZB]=uz ,qqΔh\&UkG~Gl9WaRUu6$jwjpџ㺏IOWe ukx|Bqqq:V{8vg`"" ZAe٥S7`988Ų?aAsco9㴁٭/e$T{qp888cUudg5rg fÜ;EGavCxwqqqq8DlgT ]?vW_K'Ã;8883%3#p ,Ml7^urqqqgCDf#4]U_s,qqqqXDd*`a`!`e9U}j9 nrqqqq߅qqqqj܀8888t5nrqqqq7`98888]qqqq X8888NW,qqqqq8888ոqqqqjtZqqg#"K7|n؟!"{40 x>9 [=UOȑr>QUO} "|>ٟtYk׏v7nrqǙC[TB9ߍ+!"GS|CU/7l_ ȗETVYT"2?)Vm0gvqyNnTzNX82܀883ey_=  ;MLVq<:88p88GDfvsU=D̗:8ӵ.88]v.=F-5EdIU}kY X _ ^U-c^K<"~bϩaalCsO "2 ar!`Vlg׀W+-lsa`ᜯ_Q՗k,ңkͪBjsy`wT&ۍu,L>=xxe"2XX $ͫH~z/tnTUo@0o0yp_v{fg}m%.I׫\u}4֦3~LHW4SDw ;xN_Uɓ'O͞wch2f ],*SN[#;~#T8} X88Q wq88dơ}˪gMj'Q#UulŲr[RgAXʞ(l0BMrzI_qJy`;M6UTRK Ks^#Ed4kU|#^U=Fr\U'L-%V>R'fl$,#k%/`={-Ȏ88Ns|3$xY墪G2ir `FDJc&fH򋊈I,>ǵJNۮ,-\$on!UTZU [J +X[jy>ѨI@W+L{_I~qln'}Xt4}+"֕ I~7`98 0Dd-`ɐBDfPrj XU+$Eh~GX,z~עy:W<(?UmnUT4 Uu7`KVƻnĘY2 0ofeM1Iw[6KJ73,qqGYrX @_^Փa;@"rfU=]Di?*Z 쪪B*" /ixtHRzJU9) X88e-n:oUc:HgQo[ӿcp]U$"? g.B`)Uu.p,MD5[dJjlazcLU<;Ew7j8S8qqg` =513miEKv.鲢mߧFKeN( a9vgUf7GF߯9'W SgpX(=/=3%?CN,qqE|ZU}CU? P;'"E,aWtB>^vl VS]SIwGQUu`s P[`E1`sϸ!to/9N8UpO,Y^8ӭ!{nUsz{\%"[!'@})"Q-W%ɧ[""?BJ}HUU@U_ ""6[䆈&"LjHQUoK335#"T,LcnR9ȵq mdN_gѳwLtKD6CںjIFSg !"3D8o"h$@#"ˉ"q)[ _M֑NT~@Qf0L"Ixn|VBUXgU5ȴX)"Dߧ:BDv<&ϩv'@AzM֢G9Zibӻ83LDSq* NPDdK&9:)[jo_3Xd7or>ذq,UXP"-pp9N F]0/1C6Z3!;mVU=+YoY6 f@~7' "=L2Q1I>}HU/ ,L3 ]>?Q?34|L.xn/|?9^"\xo{m p\܇_ 7`镣zwU&_t܀-QD~=c{UȺN(OiǵDZouL͖: {GuN#U$"'FuņŢ2T:z 7""<ê:*,\ñgMTutyW8NETLeXCQ]wT:iNk6"^O5Q~.;}>mnuj.0}ɓV'l2WR&6P%ui&t]7(竘*-fYP :uȎލ[|g&VkNJdT؊e+zlZAGi?#/a^XFQ<]`>mr4TuK\T3vTիiDdBUmd) )}qqqk ,Xb7qqqqg f VՇBP"}[V!"KayVDoS՗[Xͅ0w1ǰ`7P옛"Q񙐞,p.O`D\ݧ5Z@'M\ij:n N `Xӿ d`ϵE0 {X@;7+ vݻMַv.Xl7W1Ƿ ;884Fp ۝c,fvt|7zٛ6Jc۬V DY lgKxؼ*(^"9 M #58۱eUǩ/b;n,T^gDO-;{`M33Ku_T`:rZs4.*s^Hy],-S&9<OIk1n%U#sÌlŊVÃQg ״Qi'z` d&au&PnDtlH"?3#M{~8\Szy`Dv,:ԛrlQ2Ձ#ùͲli>8Gnq=yɓ'OD"L-*U}_cqZF̨LW1RDd#2㎲UUǔ+zgT[Z|ea hY~ļ26dFdqqq*,Ѓ!e, wڧY9"ɗQТf ᅧKB]|m_DVSd mȖ!XPAUGPϪ:6Gz0&ؽB\B6qh?bJ2Rg*{!fZQ'M/,E0-ZBi|888N!]a&bKl.( tSyDd`pnpǒ 4=ZUo.P՗UUB}ה|zѪzZm8Y1U&2DdM,VY92`12>b}?eG1\b/A{G>RVUgc2zթ}jchZZOߺR!>DdUu)H888Sn1`3L&tW'u*X쟌Uҽ|D1a %Re~$yfEd%Y?Nqbu[""92y?Q,/㧐ѡDd"ٹ>J67w]%Tz[Zz ܀^l#UxiDLY.888NiDd,8^"Xs],OK%DdeL6nIkyA1%"3a&U_Ğ9Wt|Y872~p^Ebjt3iՊJEdZl|7[w*t]TG'H,Yq0vGת 888S;?*߆y%,8zYT"2SUFU/*T6"'.1oR`Fm oSctR3>H 2MD~Xg|]㏁[CH6hݩl#U-"+cKH^!cE%l韂Ǟ888N+fN<`JI'q{:aI]>WŀZY"rA~ \V/wVjTuCNqb^Je2aj ?o7LȒ >fly|+U}KUKaަ1?wqqPt+l[cȞ7) m}"2w\y0wCLPq plɔ193 vw,n};55ǰPԝʦzv a7ΣD$ףb88 :遵;3,(p\CLwӋ\U <"r|Hhz! efh"mf( [Z pcz%WU/E/ IDAT s;خcv$Υ1;ގzߓ@%zҕޫtP"HER*UEAQzQ@齇 ^B I3˝;ow}%9g>왳3{ߞ{9DD~#d[M+ ygm[L#"k Paec๨z̚qqq1=iʖ^6XU?)J,rDd/ \6qwP7+lfN'fyKN/$\3pF̰[ؾ@U%eyz>nj5ѕ͟vjv/ GU1VNƒ,?}XD>{EdZT&pK>1CܝXR=LJqqqbzĀ-6 EBVh)GL8qY3""S3x|@}lX5˻^ñ*NoE{O̍73O&EWi$"Q3v1 h"ykȹ"P.+&NR KU'룪y,~#}/bEYLt#"r*(;tqZIיǙ*)U:.i t7odK^=NTu,j>c.K+!_9ZDJkEUnŏJޏO "sY"q"\)"ȶ=ݟ?`OmA܃a3y2ZÛEfy/ڽ\(M 'cHy$>~," U[əQID,ݘUU/EBπDdwU3Ȓ2MC%XVtkDU!rdLݩH`*~1gzkns ?tFmRz dqfFȯUuB=>93F_ ޕ3yV . D)$"Ɛ[":xU-)q_)'#B`ƃŀ_j]7Y88IU/HlY<ԛf(VZ%hxS ٔڳmD{c<ƞQ❪zZ8cDd(pD9 `nIULj֘'L=">3:)Q, ,6Iv/'"Ϫpj [+Ȅ%U}*g8 Aߜ>-2c9zǙ98;|?r9 >&"=!Oq^|ܙ?鴍a]Y8S/-#fT**61"[3{r[XpJ7Ig pC(/D&ai t}1\^Qݤ m>9tu99xԌE,m;iEGgT<41O=Xlk-efE8+Qqu=ϚwXÓ=x c=,ZoKcƺb{xe!%8#6Tlsjfz`dy^sG[umx2e0?;~}jXЖlwr1yd zr>yWJy`/y2e2WxU_wȚXi^[R8W$p-pr"><(bd./AVym."asZ,PAE|̨4ԃñ%}`/g 2Scta:NJ 5'"0%Z`fs 5xӕ8jP^*㵢;(L\O >."K`/0;al6`H3m7jvTm^>gaﶡ,=O}NP^8S9PalԄsŠs"rpXzn8YDU{}|o~s `v0T3[b3 fyUU?je_a)9 xSU_iaAE~V؛9hobЀ R`k2S݊{yJ;w67bst҆<?Čoq%Vyrk/wس{ר*h0vB,{EdUmt~{ޜyy-`Ϯ N͋/P愞/^x7g%C1B&{L5  n=_6'@4دD,nc U&^II_*yS$:b/XWB|+i dNd/_<#Di؋ڽxOG{O68>] O- M,מ)4&/|Gw\&[t? x.My\>͈݋#qTX㱿,#7 #F޽Q_U40ҍ$`si`#ُ1K//GaB_R t߼xŋ,6H䗉 XW'/6л^"_jIf$ F7W'UqI So$5,Hz@9# SևR/A~fѦ{"5`}AQ5D~ ;WW&?cqWJ Gi q0L~?Mj{]I? ?]c"h6B̀4g3O,X1d?U]3fR<CJO s#~~-#huD_*#;2ۧ97`B8NCTMU/T-v1vqo4V0cH!"]T ކ[*N~Y͑K gt $'90z[vӈ1Eow'm:C[R c/PDžUKY-_BKsUȬwMXl`!:[Qcf yK;[FX:/; ڲӣi1p3 o-H1̒'ƌ7se }uB'73kU}@A-[ X\-QՏap],d tB-I<:14>c>rY~/cK=܀883e!S#v2EUW2"^2e~""MPHnfL/c2VƂm "3dÂ'W"fq;Y#ٮ<TWUHTjhT:X̵JXU?woYXCake, MzT]^guj5qMPժȘ9xS͇y ǼuS황7jUq!7]Nɞ> vbZ1S X88SI}̙!/ ƤD9=W#XqWz"2b4B\en bIeRl7=N{RC m7=ipnSUṕ,NqqTeU%a0}63C/ۘ>ܛleCUߦcĹZHU3cIeS]Sꉤ/$ͼ1Z:Ҿ)00~AU{*\W{m)UPՉO,+ug_ !"g`A28PUk1)c,^TUM!p:D$S׆;T2ِzpc$, Y?À#Uu*p;ppҟʈȱXL0]T F۫jU[\DTwr;li* C641&c " y\>O9GD͓KZo_ulR$,"DU\POP" IDATP5>xZ""R[ryqgw;..* Q3T_p̔ʊqf|j8ߊ6e BM- qz#/,YX*sNw1qq6, <$"#TuRKT R"j`xKUO R~!BQU}?Öl#"!p30/07fP8{y>~{Y%ePwh a ;sVjK&~Dd)2˸KoeH͇y=-L=l}=6sPHJA֌ڼgǬ,6WJv-"qZTF:U0'nfn/̷OȎ{{q͖. 1/7<`/ob]D62 HvU5CU'gC['k\WliAVƚo+"w#" 5my '"cK<kw8z#UuL͇ð00wQ>:̝IDr|ڒ40"'<îXҎE|ٱXPF:,ԕ`ӑԞA+Dgѯ!{f}ɘ>ic'5Exlw_H 'vN\-"b{g``YpjawFT2 xBDNrcUUplnd˓WkaBU҂-Ҩ oq6cd,ҷ d-}ŋTȻIRp ,VQrtbuc:?GO^yD`rڍKdl9d'uKUԻd,k;)wrTwD"_\)0_cb/1ﺸ+,1]?7Dm.n|դY1d:wOAuOHu)soDR#*J6*iiC۷bNLoUڜwDq}|0KáQ==OQy0KoacedH}=j`6 w >3׫xaƯ IIzu_b˽g-7 p&}K`lα>sEZ9X88Sj^W\6X a؋LMyrpu%Pk:A:A؋Zl_?( p\ly ̆UilipRTu,yẆyǖ\74UutAcǨjFY:Ʋ*⣂cN s I7+QMBW+)N62fa8^mFZDW߆7݌G AZƴLW>"r)SmCő{\U@]T;EQ"rH{#Klf=TUnp*)t6J'ֲ]o`F˗BNmzlWl!Sl׻cb#GXqVӨ-t(m U{aΘ c5jTR¹ `?9Kvކ`c~fU`߰vṴ(92ܻe^S=N/$[AU $-}^`H`U}I+c)נcv1"r<e|?!y̖ADnbw?Į(;\X=ɿܳXJֿV)\DzkLAp{88Kt+8}d`%I;eS+ U/^Č@sc.vRUO+ѽ 6K)pcX:uK,0>RUDdv,ܷ]c_f `YBDIJǮXoS+cRwQJ 6qlN=\˞M"A"2 9$T=\y]}CkcNau U3b9X0,9ED~V埨 ,mwl<R:8Ll)"yc3,ۡL)"*K "cXfHgJ] lBi#@NH̐ur"{R޵Oo<=![v@0KZfpܤ̀ g򃰌8q;IRF\_O&6]~ }3RH$;؇i7pW06>S-k{ع-ǙBBWñ{c^jac^] A AEdSدłLggP}j UāQD,vPYv00dNbTlh7)!wwEU{ ۈx?UA|׺BB@=W bHe\붩*FU^qqe8x6-3]_h 5WTXR1Xm{c#`>x"p0>=u1`{aˬ2RO3T%lb2U}\UAr%EdFz?o(3.,i#o d{/6GnW`h}8= ؗX<\d=#x-}@d~\U~/\H?#)qqډNVTU]{OZ -},&:Jgds>NP[TuU[YX 5&Tmqvs7ڤM{}xUnыj.ܜ鹜+}63gqqq)0`=|ԥ.MeUIiӸ>yHcꪆفQ%5!'tjKgѹYRuD$ C>k̜qqqq ݀_&yr! Iv'ٮ.wȾlZ8x9D_:à Td*B"2#3=ow&2iF9RDN#iW̕y*Dd͜{U'&̝OP%5DDfk?sx0G$WMUqqq , 흫4?jf`L44dHQ1d{؀/skv;#٤%?ȥ'U;""GaJ64;W6euc-+ߘlocʼnLs 쉝ǃqe)eh888LY@S"?:޶_VCWx7v#ÀLEa VA.C <U'"U=>Ņ Ε;y+KQ_D?Ed05RU $2~QA&O+"rl88NDdTA98NG X!WjaC8pQ>"fa{7cQ:"uiEB` ʗ$vqpo" bZm*DdbEaf$H}̩Eђ}[U(O^!ED%*]8."TSR9U}z<ɡ}n.hTU@(`lU{'G؜Lڮ ]DqADE8e&,tF^)qC=tpһ 젪%rbE%Ok}%z^\U_;1oR91-s-{lө.6 l L PWfGR=+!KLD.~9[o0OoG{#SA>ߪq)hX3\d }9 ܂_X ؅zoqjBcn \E-04"2;p(op5rv2Rl<͕euzeH~qU}54y>8 JU''}C`)"`#F`4 v-7UjCYg 6?Gkc#qiGYq)FD?d`AUs=r*ASU+ǙBQlFc0cB졪V; p<0saH[K_K.nj#e\ ~O+zf6碈U~G&L`?l#rV'*"r&XP4 Lc'6mڬ]8ǘܻ؜APx^A-#X/ wgPoGUώt <Ɍ wcXP<Y?ÌS#صZ%ث$g{#̜J31uPպKDvzA9eD0`nDD6 9NQkw8o֯z8CU "R+ })1jFUu,y|}1ؒߩj~0#ρ[T5^R1ghlFQa\UUyR/-ge:N, <\\/Y"r +,P|\2,ՉrAM"vNٜ-K~""S|^^jq0` d~i=,FC/;aijЉPAi,Q88m=RDd`80fzIUIDa"s`qjX`Q̫5*^(&.`6K;X?Œ;ob$'67uUse1P9*es%7'0O7]=/f`F- [;C {8G3U\&94c&U""WR[A0AUX[H8]=ǩBoE`XhqAU/Gڡ+;fZGгZghQ\ycVϷAkz'Oj}pq>F}B#qi;=qqqqq,qqqqW:886gv5 W%ï|y4K=,-Ȳ}Q9U}+ ’K0*p~QLŐy,9c{ QYZv빓ݫH^OT0̍B>B. ""a]+gC_./4CԗikQ9l=,]`$P vtXb8aa j&SœZ`]wl avlҼeSK$vB2>s3aI`-,eUW<8Kae=|/;QU/^xŋ/}`m@jXFz{Z<+KKYKSֿ <^a|Nse\Q\>҉߷D&vK,Y]?4Ȭ`~o񼝾x@,sٜ[5ѻq hgcIʮDOM_33&poy5رۋ/[qq+f"e"stj&y|y-l -";j<^ h`^K&}3obo4R,"FU歳!f4\""k{j:A 7S$,9ڼ-` ,yU0zYCUMk$Sk86}q"86oOK`XFZssǠ/Y,6_ļVƞ!#4"Ԟ.ĮrVKEd%`_mAsqyŋ/^xi]q0k:`P/k4-3 dW<2]&-8щzff&ƹlI`H{i]gۗqz`L)<}b٣+93 E9oO'cކcgO|0_$7/=nĖ66)@IDAT)ֿp> :vo.]ɾ/Y| tT6\gU8ocuͽxҾAqqDdI'n`+U"O^Uy2 [S`UDUE}8qqbK28Q"2}{V̘gNQ[01oQTuM^b5Э!*>U}Q#U[旱q?.m sG,sZF&۟ Ws(3c~g@OWO)cUCwUq̟ȜU8N,qqlR:H8d{t6ѷO7WU"BމhەshԮwFVqi+[Jx+<{XOsSRi̞ smEᮌu`hr9 χ8B88@G1RH Kz:KҰr|$"aAʇc$soyn=4W4:5)0.,ؒ7rVv):YDަf+v繈fUsy9^K|8N X88XrIegӼߥV+7S2XmhnDo[]s*#xAE#T:ެ3F,KWG&{e&d'ˉHjK% 5q\qz7`988P`lmdimZ9>Z>>-~x3fGW gHrWF.cfRf='%n@H6O`0{cqz nrqq_56O'"SozEj^fcz ҕsS_+@|:Nꪺq^888ifs6 <||#Ucqƪ2^~)"_9.XFz{|tϓO^Ts4{&dޫ'7q>Jo['88 rx&о僝Y:WW7Ei `2)G+ۙZKEDv g8ݏqq,F' %߉>MTfനjk9@"&pfT8pPv30H^D6^(="0S،?𷁈o}l#Fp*2Hj8/VU{G_DU<%7ly"23p#5C$`{U@; oݓ797H#"Kdn{:88L %oR~."ÀaKW7<2.|ūY8wSFz uvk90Oۨ_rwhtKD[1A!`HԼzܧW6PZBZGUlh)"r04l,>+ߣTC84M<>?clG-~ Dz?<8f\̖> T1O~C-l\]~@DJ!t$26vƇ?U0ɪz@1ax>ފϏ"2-`ѽ^sn\2lqڍzŋ/^x /f$P&bI. tiT _1ؤ~1#MK?&oh\rM*i;˜O><ߦ)Ns^fmŹB W&:X0#hǁU8yHMhпјlI +vNw3~B圇g/^_qqg DDV¼'R 1HU}Y1/1Y1ǘ-T`Uզ/M0/YEuB't//̋y֌ qU`̛K1#%zkݟ8[I%X83 îز#THv%`*Vգw8RQE_cXPx,X0lI$c(  q\q27?̾gI5{B|qI`wkܝz{םngGrɼ[)4ٓٓWy:yof? mf>ΎZ'9cgO4/?NJ]\go~oTۋ`@&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`&`@sIENDB`PK 82-Pictures/10000201000004950000037264BEEAFD.pngPNG  IHDRrjsBIT|d pHYs.#.#x?vtEXtSoftwarewww.inkscape.org< IDATxw$E%,iA2$ H I 3""f""%)q Q%Q}ٹ]azyꮮ}ꔹ;"""""2lmƊF{DDdf6V3 nK/ل}Ow[DdxfﶈH}"̖xx:[ns{鐙- 9{U3;ҿuW<6q`0-&M=a~\_e#` =!A0h~az|a"""Rf){,S}&orۚڧ]MDDA=D_K:r0J"܂w"""""""9T\)(߸'ɡຽ|'-iz:u"""""""9fwD$O3WE[laBk1`QEёݟE;bl ``l<-}l ,X?Of$43~O~Ow+k lycy1z񗵭1ٶl>f\K, Lz⚚ZDd($2lN%7\V;eɂ..w]- ,QS-M˫%|&U6o{?~k["wv""-ZJ,M,ua%7,>gg@Ѿcg ]L~!Zwu1p:'Ϊ+|= kSy~_I|=0`PUB^}1|zv39=#  pt㷥 `#˩:.jwnZhђ(Zyvffz tul&`f|O똓C8!3ed^L6"<7_lfh]f&Z|5X 8~bf7ڸ3z+Lh̀sl@}c$^ ch&лqgf40|zN7f=z@h#4l[vym,Șo"k?{CaSQ|3u9C%CV ڃ#O#N=-O 9'B])R|t!דa`Mʆ]L>UfL,T+ԃ<#ǀl+wT{l/ꇁ!Қ;q`CB 8݋fbâ0CA5_ٓ~f3-3[W,e¹!bq`F;>mfyCNTVyBۗv"fA=E""ڶNw`fFx*7r"z9t.#lQw?fw! ykȿ>Eiv.=v/DJ#žFJzbN%+_LD}7sh;ϫ>m~ x]otf-Zhib"3OxJU]w~"^)?#L_U|W^qF$wؑ0f`f'?n!i„ks bf]s<lg_qÁ 7JwA4W }[zj d#:A˥ˠZ00B0D4gzج=wݿB4B=sf,6)H/Kw|gBJWf%A057XoH)$2@-]ʌY8@stYf$MH:\6vTj<4H Y`7wwjg Ou;+laH٦Y1MU?D0wwݍćV}9;~GY(( |[j[ĺ`l~Л1`wF~By#:k1m=i=^{? A,oɿx0C35?:R 3sNyEoCFpC<RPId@dyX.%t͏pqpi#<Ć|Rgf {ֽXЩ&nqkkLh 4X_"B 6]7pZ^z\ۚYsER/:{3`lrU׹5mu:ݙ BWExm&75xPjnQPIFV_ftGO>,45 &ra\(ۿ֔\jYοd7 }e?uzS{{RZ6T3uL6t2 o w8[nkybM3SYϑ-Wڳs"N LPZ6}k6,HUug=}Ry:w<Fd5KBfLVn U(xdmjvKIDJ"e2avgh8uclDوO p%MrWT[b Y* 3Ձ֔w '"u *4c/[L$LpXvafyu"uIJ6"5C\A,BzV olЄԍ#LZC1ElB8 lP);&.of˔jWf;7܄Vr1za:w0뉻K YXR<QWe\,z9fU쎥Q *?7gZbԑ RD5t/2ojs!𠙝if;86d A`X eU6f}K1t,>gfmfJq|O-'%v1WwAR7J㡵wD=1A;w(b]E>wbM4=zMA`w=3[,eKSIn_&"RBAiNkf6j ٚv-|J;Gؽhcw"~aj]2..r&n$R6Sى@g+]OM%i#5TI'hY"{K9t݀6΂ɭ72:/ޥӄ "`fa)cv`YTTo:R=*{{HA5 )U΄#i{xs_d(f3H']WDd($g~-Ye90⁧M&ec)ΚHfgŒH Ht_իH7G$fς©$M}̞zf<ᘝsfv) lyV/ofўf6?uKl?5n^`ۂ&ߠA * w?(f[jnt%} avF233SA<߳ͺz'`f'`j> ZoZ/=tѹ@,q4cf [m7S#hfw]Ot#TyݙCWq]ff*ZKM%"7&28~1R^S l%R9iONN5#酵.pDótUT`*/Sk,wi+/S$w@~lIwϛ¾=˨o-hfɩcŅfs%ފTWtH TrNۋ꬛j$7nё튆=f;9RDJ""q #Vڻ.87159w>NHV;az*&#$ ^vr A-9bȧ&En>$69 0sʪvAzf *a7axTӚ:wM~эYkv;w.)(/kfw$rF L=Edhh`9K$f3[fEkW_zl L[?Fff;KrW&APgli'*9s4<&zC^Gs63h;鬇kw]GD7{EANfy:nGF:'˟T~&+DHֵU_Y3sw&ծ%` #AmUZ ğ6GӉUe!u~1!gJmf>u'r{B@8>h}!M-/%VԓM nzrgõRyEQ3VOL.{;v5MDJ"LBp =f˻T?Ej9iwolPbCܬڲ ~a, KH)S.wOf5 CZRtC;sGݿ1M;Rߦ|Au+vToMl|6-O"p~uҭSPDJ"Do5*Qi_Y6dX'QAwWQR ˆ4j,([1$fJy-sC$_D|]̬uIrԹt+eu駬(vX; ->`ۈ72FKC%D餟cf֨7y}tـzԤlCU~=2ԍl4~UFlvB) cGOl'i{.R7>!wkRyl#u=1wOCRJv$ć !`*oH)$2 o%VzCRk֨3V7-ךY2׌-ff,oI(_4VR]|G͑|Eynp_F(XaC9@Dt~O# YnzVDsf,i==Ԑ =uv}r^,"ŋ0z(K/zncfE)p4o'ʶo0\*o .]S>7^ IDAT }a`; ;Q잉_NѿTKDd($2Kw!auT/H`նמgUt-Pؐ:Sfa9"< r8z,Z-J0b(z-gb@|VXp/3:7aNG m/}G& d\s:ڵU7#m3[[ԭ;!5U^DRnw^DJ".˙ʃ4\+3u쫄^KiVfVNk27݄,ozسҠA7nY˲᭿gt?%D"fV8xaWP' otpbMJ~';G/mc}>Tl"sGl M"w5O6k"24J'2&d3nR?$ӜV__b>jf?!?+l3nX[ifkv42QSg;ݏ/SOeve72|2gSc#=r\ٝĭP,(<{zY/x+RD.^ݯ6/r3p}8$:>w>[ Oٛ`fwMklg̘ C){ 3 窼My\#\:Q99u^o;Q\9!nI~Ng`qYrOcdMoezEb)gcM\ v^y_sTζNMޖ(_ +>dC*bW:qz2On45QB@lwܴ C8CJFپ׮g7e 0H}x/o{B~IO\ŋ>-Yko}l*Vu>G3[t2uw%2+f=V#]xq`uBpdfOtwO%ws5 G0*B7Kf?Xe?'Wlмef?'{wXلL! ɂ2My6< RuwLs%>H8wC=f`Fs[EC<{fs =dwm ; Prʶl}ꟗ3)W%"/$2<~NxhY"_33|.[^2 SMʖ"~.yF'TƞZ/LSfvaXY'lm=WVAC w |Ymd"MMs65nH-v9)3C>@޽8ANw@v=8zbQB.G[[ ""2TY͆܉r* )G<ֳV0I͞vcZ!""""J"""$TJ&""""3MDD!f6 =twϛm"9g'RPIDD9{&*6Flb"""""UhHQJiE^8HlofKvZ|,R]w}THL.0yV`fK%o-"""" DDDkm:%3[ X)`WwԢHmofGٲlm`fnxtCEDDDDo"""1?ifv/p?!KB(抈 """c | _~ |ݟknTi- M10O= 8hy"""""PPIDDlv`=- |٪/Od݄Ws{jb *Qtݟw[DDDDDPPIDDDDDDDD*QPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD*SPIDDDDDDDD* %3{#tnqǺ-3{=bnsў*l`Ov=""" *Ȭc+n3 8 mޛ6B["ފl \օ($"٪W}nJ"RmGe""""""K *HUn{m6;fvև6Uq%0>%{齿?m1`s^_ةmܽm!bfwDoascfo#LrwTl}௑ Tef;DvwTPO%)%PX},S4~=3[ "R|? "3+RWw)CA%)ݟ5ǀ#nJ"igہY>,J3" qūrb줞BDDDDDDJA%0 /79z J}l|fH)$"9I""""""2 7LA%LA%LA%LA%LtVVޘ-f}zf6XXX ?[̖ǁ~szsO>ǁԆ7x <(,|xݟib#>%f׻mj0% b` s:3[$k璄Q~Nw_Tfz|1¹Agw?Կ:gl1f~ ̊TI0KwXdws}n UvjfGsVj]DM@lDdm[qR] |F{- " X _r>;lJi3j[=sG`q38ݏlN`7`{wP^6U۲E/@3۩nnr*k~`Kg!Vvǁsۿ:[V $6! zf7#?{3KNPIhVfWonoPst38`f{gSe] \/GH'kCw_gikѢ%zxˁyyN?gk:~PJ |E[*|^oKu$*ڞp|)oy&0W_{{ O|NG_s[ol9d[fv^nhwx?{;h p70ӍupRgC[\]~/ Gfvr V 4;|GvP>ִhѢ}QN%=gXs_1c^̽*L,Hldf 3b=ת߀$fp_3ۻ-Ms!W%Y1p-\̶$/t 2Ƙ83pa8i_ٱY1fzH~[ f33+[43۟0ӄ1N8affÏED FdV+] m\JzJ>ynDt`.M!8z0kכ&5w0ׁzM C֍r B>fzYL 5l`^`D4hBi `>wp.lKQwdNG 3{/aZ^`49}!7ڄ@-lfk7N%זXu*K}w p!N$ߩSړÇg0{=#IM,6z]*ct|6?!iHךzMUDDF3KY觵.dIIvw.%wdznߴyw7~^DHW;PQmn H$B}z &ÄE Cv ʉyX*Ӿ~0R<8srED%!j)anh*' =A6݄^K&$Ɔw±wc=wLA$ Me!w?3UGVϊ^N*?>%ߚ\!UyR7yucU΁qGvdf;Y&\aG׻13(z=ǭE^pTh#?op17p{9Mv 9#9 2pɂ _%G kqu fpAxk՟vssevNȡ}e1Y^9\ K$4?&?y33 x Np3% ZHȇ70&w:z;-Zi!>ú&< w[k׬vʩzow̩D-M$\r#t{gqZPgs;0N\0ȿo-qݟSW2Vyf'$R/w퓨{.|OFŚͫ7 9.{${0w6&`ں9WeKmMaΩt s(}\B0S=mmL^}ljf0|>ئǔ-Z]f"q;?Q䝉م5K3[p5Nw;`V9aqSTw?vbݳYՆŵ'^uCBAH\nM=m|6pH00/Os}US_/gCq2ef܎xhQ̖etVwz5ܸWxI'UafKzŜm?" VӶ!mfP:4w!S7,5\:v&*e:"VDu.ബWe%ftb}U4|>_R}""Hu#E2VJcCfv`=B5K<./xSIC!'yF?IBs,_aJvD<<7!S%fH޾0DW#SHngC9@)"24T.nԶ(J1rxlXU5(J8ੜWl~GH&{@ʬ%6Wa0VB~<>I}'wzy}3[{i0<̂80'O,w츇0CF\7KņՕo93[ PbfFXNgqO?+*$l*PIqQubU;euR!lAݯzz"/0O !!y""@A%bPO{ϣm-MX*I@cŰ.'`[*|[û,jBY!J=tzThWkQ&TS\YE^79VNMێ,dfK0c_zɉ 2E$d+("uK3 dLCy]v#= K+ } ԑ5nh{* Oc˖yAuݍ4j0>Q1^°֦tgArM])D3Pn(o:Qp*0yӶ]mmr ﶼ-&OOM˕:?N .KO3m"|̮$ {[i !H)$Rbfdfsv'5a IDAT9#]3pne3[c cfiM}?'b5-=T*f:a* 9!&e-pd.%Yڹt3WK , aj=mrߠRݓVMz8QV4m%ҽ!HMoRjn~VTtTDts?p7PPI314x&feL~P BodP)fə4qBu􅙍>|XdOu|=M^\gΗssAXgf7eEgu=p}"󧮢 S`7E8?gf{%WDd($ҙXP B'TrN7$">+ ZI9^Fe e0~mM(paIJ#C`>7e!zMN0z9}oY7eEFg~|`{3܉J"p`Ŝlvw9Wrn~]G~lwbf+1ztv*Cl'tyuF\O^9^YR-f0uw'\Fuff8_tV¬_ߢa;A: - !r*աHMɬTf;M͐94hmJ" |!"۵ThAd+r/WE_ߩhfN<ac ww3{a6"gfv *t.Tpc؍>=z$zؐ>)JtLsl| ~o=O; X{Ll/" *4'֛ha`?IOB*ޤ7ZDyA%`9apK&tWQP3aUoPs݋lmJI?+v>+O~p3[6J"I}v0 =F6ˢ=ͪ9J/'VI太f7 mK cKffM~Pk؛/uE^Ϯ͙L3{=aV_mnI 6c9LDd Ȁ+p_lw;F=-w-mfoZvMT~L&oMŘU\(K #5 VwO%(@luc"QQy'0mPR3.D̨eymjol&*2Ih-Ř]Į }$ʛ0e>/\޺^``O vͷ"N""/ *4$^HbۘyhZ^D0j}[MO,$ʚJx~ͬ&;$\S:W7}qYƘٺm/O*YӉ붫Ƅc| Օ c|s mHHC:|PF8xxo^w'D]{;lHϕv,"M&tqγ/oԞ.X"er6D^/@>,/}P@4RSAg)>Uv#'B,IfQFw %~47wsy:ڔAD<(+>wݯ6?T5}Vk.ݟ7ODVy}S2pAN*?ԒC0(;[m|639Oڬ7PPO%f]<){?:^BwVrwMF-~A ]"t;o]2+H 5٤Ӝf*]2fU%~PIhmo̿嬗:~話 3ۿ?$?"QreI)aj~([Ц63[6%o'VHS,^X3[pUwaچ[*FnaobBDQ1`ƭlŜŌ96T$?CwT:ӽVS]Yo?TUǮh|0+qy/S65$X/@MaZ;?/ÞwV*In>y,a4FB ^˞+]FxʞN2W$j%iNTfL~UN C\ ~B&)j>C6+8NFQ$[8>}9a0 aIjNI WU7v9$d OLInwvF[|?S;dc/ЍbqeN8sé.XgRU熻Nx#D7d.zP"GKZ$fBKq{?GNxǝaVjt~8O8 x :`+-w3~w󯲢l\>n<c_LFt#6=35y ؆}@-))v!(LOt>XKt#݇=sP1@ 7tS]K|2,}7 L7o5ضԯh{^<&ڑF;̽]cm>t -G1~r_v;%t#n<9nTz_>ۘ4tΧ{xp}GT<AtLUM׌KalYU''7^*)=oOŠ>^2d %}??nDߟF_ݎfkQw=غ~Yk>U { )wϫj a4//7{חg>~:/V1q}țX{s?dMoqݶ3ox{N[M3XtZg+e3`Yĕ;g_x{5=S ƾ[;f~,n{Zذ=M_B ]d:7ҿoL>On7dL^5yO1_~/TfAu|eoB+2y)0_T7e;&^k`EN/*,.'ϧ?U_PUdꫪTu}iy-|vQUEo`:l%t禴Q+UU7b[S9)OjkSY#fy'^gLUO7hUիшtS}!U SU8݅ӿKP,"tӶ&sp$4~;ImK6LW5}Vr<淦݉ndN>M7jx:t?63LLw˝g ׳ғM\F7KtfH.:YMG]%)sUu4 S<:cs>O]k%KL$iAP.tk~MF"wv GG5|+8MCKCl%#@[u?{V#5}HހvL,ݴ[5!.kEv[IrWtMɻn7,/dnto=ڀA?XQ3k=v{ +7t緥ݚ{.ݚT?˦x|7{>mUYHIQ6$I$I44T$I$Il*I$I$ih6$I$I44J$I$IM%I$I$ ͦ$I$IfSI$I$IC$I$IT$I$Il*I$I$ih6$I$I44J$I$IM%I$I$ ͦ$I$IfSI$I$IC$I$IT$I$Il*I$I$ih6$I$I44J$I$IM%I$I$ ͦ$I$IfSI$I$IC$I$IT$I$Il*I$I$ih6$I$I44J$I$IM%I$I$ ͦ$I$IfSI$I$IC$I$IT$I$Il*I$I$ih6$I$I4U[h!ɽu[$I ]U]:$I&jaN$3T`a$IҊ\ x_U]:$Inl$JIn G'IxjUuiH1 N,FZZZ$ISrTU:4% xH,s fUuU0Yd9$IҔ]ܦ:4_% 3`Y$i_Z߶m@$M8XZcCIe;5 M I>HU;!I+BSI$IZ:$%hfT$I6KZ(Vo@3 I$I$ ͦ$I$IjiB%CH$ix6A$$ _nBҢ4l*I$I7U!$-NIZGP$I$IT$I$Il*I$I$ih6$I$I44J$I$IM%I$I$ ͦ$I$IfSI$I$IC$I$IT$I$Il*I$I$ih6$+퓬:$I$i~$F<$olG$I4TtIv> .ɧ6$I$i>$K9p07~nxpt}*I$I|dSII1(pAGVsM$I4TDˀ{}~ѫ=830$I$i$oKzVջ`sNX9)I$Igl*I#,Wʇ{ݨ G~tSENI$IcSIQIxZU]٪X6plgrTI$IH$I҈4b< xOt稪;/Hƌ$I$k6 JWMy窪{址?ݬ$Iͦ4"܏n>u笪7HrW$I4TF@e^Uut]Uk,}W83{~I$IdSIZ䒬,n+>8SQU51NM򘙺I$IaSIZfܻW"LWU]JxzuI<'I$Ij˦H% ]UUqUuMU W^bW}J$Iڰ$-^vKU]=w\U^@8t}I2$I¦%xQ`d2Tǀ]{$\$I$J"z %Uu\gO%Yw$I$I M%iI^r`eHTՙ9ӒܾI(I$IҴT$ 6(] xZU]$"PU-^y$$I$i*l*ImxbOFy9^I6jJ$IJKJeҟF)^YI&$I$-.69)z%UF^vI&$I$-69g JW;VOۥZܪvzueI&$I$-69uUujTW^8$^mRI$IgSIeI,/74r/t#ޛ=$I$IC$͢$ˀ着64Ҫ]_d$I$Ǧ4K  l+xuD#w&Yg$I$I˳$͂$'{VUI1UupOcӒܮM*I$IZXl*I` d $IcSI$\UoI3.d6$I$i~$MQэP{z]HAU5yV7l&$I$6)L:xH|mi6TM_ mRI$I`SIO[nxbU](fIUl+8#Cۤ$Il*ICJf`^7UuiHeUu!8^V7l&$I$eSIB,Eˁ'J6$I$JJJ#p@t)69VUV acqUSI\]$IH$$ JOKVtS kh1Ǔ2a$ITV sjYHst#<J5=H$IJ$X+vPЈ=$4 %I$IsĦ4$'w?:$0.c6Lr6$I$iTƑduHQ$|6X}3;=KjJ$IfM%i9I|xl|&𔪺M*wUu>h`i|$[I%I$IǦtcһ `Q-Uu)ݟod6$I$ivTzxet.lI LU]SU+|>>bI$IҌ$ $ xot1uU(xpI>^I$I l$ o*`aTZc@KÒܴM*I$I64ܗngYU_kJEU <O8)-ڤ$I鳩tu?ܿnIPU lR>8}$IǦF`RjFU/M$IŦF`=>ԏ9 ثM":O=݈-ڤ$I3y )ӫڤҨmudF$I$8JZ4<xct(4c @A'pLI%I$iTҢd[cvUFWU'[F7ܺM*I$Iʦ$Ʀ] ^UgK%͎>^3ܽM*I$IȦ$_XU4$ͺ=9oލ6$I$JZl,n+>(4gcc{[HuT$IFM%-HI+^(42`g޳M*I$I¦_W>6vڪz^yU3I^&$IKIZOI̳SVXU4#5WUoKP7'hUŒ$I(I\cKk6$y^7vUuiHҼQUv.땟d6$IlHr 1@э?:͚4Rl*iHB`^:Q$iީ\WZ ڤ$In/?Nlh#IΦ$; l[UmI[fzM3ܩM*I4S8ت~<8nѳl0aSI^s`nTVUk,}W$lJ$MWo.@U]l|3pfG)i4TҼ^1sjYH҂QU+85cۤ$ISd'Uꚪzݮ'%yҜ42l*iJr;` T$7^$OiJ$ +#C7w&{};$sQy)ɺR`^UFgWM$I_sW+:fp!v[Hߕq4c|RѼdu+{壀I$-U/uRd7$OIL7z]U=N[/t {%ZS҈C$+<(I+>LKCܴM*I4$N[CUa1n'7zFJY64޻ E% +mRI$kl窪?[5En{2+i*|P3I6m:f:Q$id ?蘛_J6$IIn]}V2tk8<ɚ}Jj"z2v="I#:/^I7j׉&y`I4Òl|q.?v[gsu6JsI+ w~ȠTƼ `7I4C;}SꔹPU6[cqSM;69$-<64|7Iq4Pۉq In&$I`5VՑTEtk, ܝI<Jkv1SU]( $pn8$iJa2`= UƑXxp+IvjJ|fSIs&ɾ {?[v4 t y &$I [ ;76 XxGiTҜH m?vKHVRUC7e^I6mJ*ZtS6 mUǀ6M;$-Ϧf]OJWjF$ .vT1;I%I’dUF&7=꺶&VU`Il*i%OU^x^ `6$͆=pi,$7kJy&Ӏw|Ƒl0]ow`7l6l*iF F( xVUUTfKU-[6#%IYI>\MGMkWq,ITLm]Fy$ͲJ]ۤ$$zH3> \ |$;K!64cxv{`Q$Isd03;݁@J42lLàGUu4h|`$7mJ\1NutZQ$IsΧ{cyB<’6$I[Inle0gѪo[o$M%iTҴ Ht]UQ$ITեtGY863ڤ$in )'GU;g[g$STM%MKMCUkݫv$TUTճ7ʫKbI4  8 ū7<8 /pvM%il*i<x46w"IZji{Ձ/&yET$M.=6YثiiAˁ]qHǷM%i:l*iRI k'TK%i1Ϋ O:n$ In |fRU]WU9w|g5%il*iBI ܴW~NU(E>\+1`2gj߶z$֟NƑ$MM%+-zTՁ"IZĪp`+^I#Ij)1cMx ^.^IVkKl*F܂ߑ#UF$:x^QiIn$$i%Y8n3'UյmS-.Uu:{tiJJHrSߑaWI$iTOi|?$nJ4>L`iͰ% K^PJE|𔪺n$ifU՟wNO6$I&ɛ6UF(K7$kJ TR{zPUW4#iDUE/'%٥M*IҨHB`?_G UuȰwض$MƦHJmǜ , E4Jź?+EmRI$ѽ\ l[UhiTյUB`$OoKl*$O+] l]UlIX֠|$ooL%y rUշGYU.)t&ٯq$I㰩4I? dP ع~.$Ӂ{W'[KfBmP:Z8ȫCxSO%Yq,I=6FXGҽpB7 Uv$i|Uu-pI4$kI%IZ X ]U_hIUu*9plX_æ҈Jr'1{W!"I UIt;TW~mSI4b  l+ xED4pv|$kJ$Y8Aq쪪ɏRKUo`FI44l*$}M龀JZh1t1d6$I AѽM5mSieTյUk['vԀMrcFy$iZr`g+cJ6$I ݀VehHU6 ;Jo<Ҩ4"x~'`WH4#zW,_+|2ڤ$WI^ت.lIS4v p1$ΐ4Gl*${o ,4$I3<O_x}OSyoUUjITU6hIn64:l*-rIBv5$I> 12f_U]SUϦc=$OjKZl*-2E+6$(c6[kMBID[_n 8`g}=$mIME$ɪtk(WUUUmRIR[Uok%yzTٔdm/oH-TՁ6% jq$u]Fy$i^ &^y5$nJ4IwD^`]Uu2/#4sl*-IB7smW%I@U/z{R$%*~l`ZIE JT_Ey><W~px5ڤ$͐O~lSU6Σy <8x(lJZl*-pIv]l_UjI潪 Uʻ^TLg~)p.GHgb5 dͦ6x<XePؽnJ:cp$wlJ4I[7"4yf`kIvmJZl*-PI6_PU6$I NUQ|o!kJ4$mXsCUq$-U:9aIjIZl*-@In ,XUlI:x$^iI$$i$od IDATUuZ6$i񨪫4fuKd#D`=UƑUn㎯%eT`SiHc{oOkۤť:/^Ԡ!%I %ـt{zkHZtx|tVM%6w]Ak`۪QIZtϹWʯ$5d-ӭҶ;]ciͦe+{mF$iѫCX^+,o'ICIV ?3ܮХAł+7!ޤC ( HGz:Ċ"%p#H9ܻ=J啜\ulO*zM8a֯*s$}8UzrBJ"");B hTy`Mg͗!<Y$}rRkVYAU glEV#ﮓ*"|rz^`'+>`1TP\ *o߬ \U^ EҲuREDI{RFA< n#E=Xox8N%rReF'5Z[am? .uREDtI. \+oFt,ۗͥ%Z5TJS"IN/۾^~*cuREDt>I3Q6kH̝5lrsf]DKSIKQܔ lcz""bz' 0U^AZuREDtu;A]4liEVIo*bTQp*iJ""b~X8UTuREDt&IQF@"ED큃[噀$_)VDDG+e,5l?\9Rtkw8&Icꦊ>i* ISU>أNNv&I:!ї$mraf{$S7UHSiI p`PDQQ>TU^]RuRED ?I>r N9t7M1TF*=kו"EDDevk[0*"b4'2oN_DuqKwH`T'Ma"&[ھ^gsWJڪN'i62&1IM1T+EcE`k*"b4ۏVn6=nlO+;0vcEL4){_*w+Ebo`WʉVߐtOGD7;؀x]UQll ,ʑ"Z>!IsR6ZU>>"EDD} C$Z'UDĴt0ehۏMљl_</TI3W1T"? W(""IrukcjII1$ X_+Gho>Myn"PJC$`533"""^ r dpDt IP?e#Et('%nזtVOOU]=j &}uRED6Ig)7WR9RDW`e^ޘxMTN̤Q{Hl?,LhDkbTp)e6)+~.IM14 ){<c1K"":ŁlS9RDW=(׸,4倳xÉT/UDDJڵNIZ, |V3llLN_H%Mi =\gk?oJ""Gٞd{WJ7%!IED?kS],j{׸$"(t*NJ4E)o>RʭV=3%R'UD+IK(wپX\ҜUCE4T '>N'O[cN U[)# &MlX0 i"TZ_+>W)KDD!+ʫ7eD~rl_rJIﭛ*]JSc@fYDDĈ}'0 ]AvI望*"A3(x'` ۏUWl? @yI+U }-Mstyֈ[[%-S%TD4I;PJUїlO9`_``-*NJ>T}2Vy4pꤊ~eʣoJZNE6jDDEj^))cĥ4l2yG$NW, )HREtp6``c?)" &{f+HJO[)Iu ~VyFxIT `6@WdF#;?4GP7TFk< 7Jk^j*I3Ub$1Y , Xvẩ4sP:U })0eDL _yH1@9alᖦtmC[噀#X`^XbMX""(Βw<1y|8x+eDUCEOKSi*0U>X #)k?JpxTlI|uIsnDi>|؏rIV=*M!dx`#VybI*""UXbV9%"bپ2/KhmDg5`s$}rAi* 1ۗIZNW,X(ܚUBEDW}e љlAyI>@ eos< U[kd՚pz<exuRED7W@G%-Y7UDLK$^7U4RIl.U'UDDf§Z噀S$}NfT:xꦊɱ}7]'i#DJèV MV*""PRK" ܍4IX1>F9κۥ4l?AyVy.`ꤊ~f8`cVsEY,)/ΓGD19ӵӀSN.S5Tt4F-o3gHګNg/KG9e0Tl d pDm(K6+T~ȏ{n!阼FDH}+ep2o*"k)<|8' #:(3ϗ[Dэa6oH9&8>V9Rt4*}>0w1py뤊~լ_W.XXb:"~rZFuSE ^%LJؾXEқZ,qn<7euRED7k~ U7UDIZ |ݕ#EIS(׭{)wrW'UDDf,*"Y3x6+"Io &nReB9|s&fI+IY,;\,qX""P_ iʑ"Z3vepoT]* ;ǀՁZy6*""́Z]sX""퓁g%Fuk62^8r#)bxIVyVʇɉg<{&>uED=2WoP֘V7UD4#e~rG>mۯ~UT '"e^~`ʝ#$^Go?jd`N`i`#:I M7N~ldy˥ԁY JNGm_)NDPNJ,CYTxP=Nҡ1)z@J'[-(箓*""36)bq` ,` JcuSE&IPnX*GR} p*pE i `Vs)"zÁ%W7UDop480uE/IS9H[R伫Ne~}|*Eb_sE5KBX=A'Ӂl]9R4?wonLTы$ *d:"_>XxNDLI.<ƾ #EJSK4ϼ \*\#1$ \|Urz "bپX2aO\IM}s}iHѣT"6Nl_\$)#"bzz#`DD3`[M=)s}k\1T2'8U8^!uREDDtV  ^,&mUCEtIP" U=.M.e ೔*I3U]H>ɺረcӓKR|n%i6 ]&~Rk"o \&i:""H8Uz ,֮*H82z`+ۓꦊ~Rk&Iy]N/yTb/`g`6/QX DHSZP=_Nd\F63)"U>x2OpI+:I;ִdHGT@i,U^G뤊N$U|>Ϩ)"bؾ Xe,IMQyy+G>Ri~DY9`AIkV  sX]_)"b10 =eՒ歛*bI+G>Rо<exuREDD'h_Ul.c>)[)o"FUP!n`#EJS~6L)Z)VDDT9Ȁ[-&"GՀ P>|n'i)Mm__9R4z}// H:Y9׿ֵ\<ӭ)ppS>D/k1] |#EKS. 9"I*""F=Z()"b؞d{w`W`v؇T1$-L0pH14틁O/IZN 6hMi(=P)RDİ} 1ẻV9RĐ47m_9RR߰} ,1252EDjx)@ywP%H:C̕cELIRf( RکnGlHU^M뤊 4%}CTϼ[$S7UĴ4e*` 릊xYJ}_E V*""xy=lW)RDĈ}/t-\7U4eF]dFt4s[幀*""q򑶏)" 4.!M1$Gy~`t=.ԧll* @җꤊ!i62ݭuEDeY`#iE%^7Ukp0O` )bTc.ڀ2nߍ.>a6=""zIw|RҶcE JqSۿ)bPiZzU84X`(^GD3K)(IZ8ld#E4R,=*o4oT1%$ |UzX\їl_<  TI3WgsY)')5Ѭ^k"7IF6ңa䒈fV`>Ӕ~Ջ"Qmnʑ"HJ _M>vIﭓ*""&GhV9ʺ rIDDGo*"m]9RKS)(^oi"i:""MG $`|DDV.>!UCEߑ4'0X8>#EL4bl?FksI\P7QKS)e9`c:IڥN,*nA.Wa{흀$m]9V8INȿ ꦊzi*ū= JF0""F9('*n{A.)dljϐʑ lXDL4b>= AְFD ?I3m(">Xx 8D҉߈!#i`/葈RL1ۧkO[c%U'UDD8z3`Z'PҸ1$m*|.SYz0rsO䒈!Ϥ ~8\$E4eגuE 4b>؁ƀ$,iJ""(3h; a`Y/Bf.>FQmM1 *lf{䯊lX|Cһꦊ-`+wZR wj? &i:"":7-[,CeI`mɔR>._5TT#KCͶ숞R ۿ4~*f:"":]/Jm?2%Ald{{`>IV#Lnv IDAT6DS\9RĈHS)퇁kZ兀%*"3H8UzcO\YiwsS+$<cW#E4b5ǂע0pOW Q{F1UlN%$MIJw&ip> `S۷T1.FDS#fN:"">Mɔu ~UDDtS \"ib8Hz7p0;*Gqi*ňqer'"7W>sK""ؾ XXyb(5>r*%>FcOϵʟ.:""yqZcmcK""K~XpwMCAқ>rjT*l_<*\)fl8X^uS7IKWs;۾rRt4+PX Yf9jF@ |2S"I_/IZ8*Ghi*EdzKsmOyuREDLҌU>mۓ*""l< #ۙ):r$Ki(&|i*EWg`YV͔KI^ذy!""bپX~w*o\)i*"Izp0GۗrIDDtqex%vI 8x cʑ"RJl_D0MP%TD$I QV /*jJ"">xodԓp:"A3="AJl2Ȱ}a)@wIDҜX=$4_䒈!g2`e ս%Z7Ua`f`VTaOZQKKI@L[qg$~f(fՒ櫛IZ VTb;7c[20"I~i_1lGz+pMչ$-ˏfʑ"zBJsl? *NhCTѭU۴Jj~DDDTc`5B]"i 'JH=#MI_VyFIU]٬oO` rIDDĈ)pʲ1uSuf\X7QDoIS)z[%H,IiPለ('xpYN胤[lO|"bj= Ff*":e)B'_>i'_QW3'hc C%r6~k1T`#Z *":wS*h{ DDDt ۗP>$R7kF^<@ytʑ"zRJ7l, *)UBEDG(0U)"EDDLs(^`K`\3/43P^C#E4eꝭmٔ$M X|C*Ef QʔUOƔ[9RDOKS)+׶ 7JZNy,euEDDL?V. .uS I+gRllG#E4/~* \!i:"fn'b""4é7YЋ7R%-Eilg{\H}!M[_hgNoTQZ 1+lO /Hݮr!#iq#s_}fH}#Mk.v&ӡ+)F"z݀[)b䒈eH`S%fCZW002[]9RD_1 Ϸ;JmWED7)$$~/Vt+ǚ&梜PZ8ثnRDy]xUV*"Q3 @ME`Cw~UDDDo}+e#}6f jhl\ ,"OJ-oln@(fiJ}WEDDۿF?\Eқꦚ2͈3)K66RT)M(o怜`䯊n4ilA.Y\{ [`mTѷT ZE%2"IPZU>7+Eilyw'i?`gʓkdFD]i*E U6Uщi/v(""s؞h{'`o`.ʌm*/vlk}rRīk9"bT ͆1xILAҧZǁ5A*lX90AҢ~ВV`ek>O??"^[JS íJMo*"^AIU)RDDDױ0sX;Es#bꤩ1 l ~*]{&UDIlv)M}ST7JZy8LIsRYKm+Mid~ʳ混ond/a%n/)""ٞh{G+GIr8,I3W*"jIS)b:~X2S`C/UQSJu'ʳHyWEP4;YuEDD&g'C% i!61LT͑3J:R|=X|-mGDD =7P@L{JNwЈvi*E !ۇ/_tF|xD Z$#""{)c 0-À٥TbOnh6YDt ;~q'# >!S{H,T'UD]6nPcHlXU^IuRE!iy,^~z2CREDDDDRDh * \!SuRE,I.fmw}UH14":-o3KrT#Cy[lZ)RDDDDD4":=ᒎs$**Eא/ff*bI!V$)RD}>0w!pꤊ:*ln{bT1%TpojnXPC(׿ֱl<1TFn.uRELI{JF~R i*Et PU^ i:"-oJOclRJi*Etۏ$mZ'Uԑ*p*;륊RDeͱ,9v*bH p1,mm_W/UDDDDDL4"ICRǑlԊ(n}vH1Tbl*-i_1$i*E锦RD`mVy3ʜ'Uȑ:r]hDDDDDt4"z+7KZN4#pL|IuREDDDDPHS)G90 }vIﮓ*cZoJy"""""bCl XQpe뤊~%Zk~RBi*EVhATo$m *=Ni(=X)RDDDDD 4"zg[ـ %T'U Ikoֳ}OH1 TQ'8Uꤊ^'飔n35IV'K!Mg VyIIi"wWscJ"""""blDyVy IsIDB8`VS)RDDDDD 4"+(*(i:HrBiVLuEDDDDHHS) p_a6IKIݬy#5v]'UDDDDD4"?PK?oNi,}Nbw$EK9D (  *0>  A%ݽ?NL9gΞ}kSS]ӡj`; C*DfC$y OfJf5fv0$v`wr8%񤠒lݟ$nf{ T20G!IDDDDDƙJ"1wwI?3/ X2;&IosT$Dw03I̦X2D`^wbxaPPIDpÁw%~kf T2+3y䏺T$"DE~*f$lJ&3[8X,ItHE!SPID:%;ˇS*&3[8X!Ik-٘J"2 .I^Ndl.T`$,#)L *H)wx=$yB3{pJ% 8 Iߐ$"""""Do~':$yyblN'-ceTRPIDF l6I^8xLP[~Ev/uLDDDDD'Ddw'ɟ~mfs P$=lw H"""""2 RPIDx ۀ䝀lJlKD/2JDDDDDfE *Șps̀7ٲC)lN,8RȬJA%3~51$y-r3{pJ5{2g &ɟuT$)$"co6LW.5MSً-,$?wΐ$"""""J"2!Ibfj`fVIONDDDDDdPPIDƅ?$e^3{8l*@0I3P %"""""J"2n} |5IafXُxORyDDDDDdQPIDƝ0#I>̎29TI̾ |(I RDDDDDdQPID l<$af P $= l D"""""2)$"Cg$[2SY qwא$"""""J"2T~1p[pb85نS.~J%"""""J"2t~X{XZ8O)C*Lr *ȄoO$f85I7C*T ݟ *I8vN&bP󳀗'ɿNDDDDDdvL(I)dfs&{T"""""2PPID&_>N 6U3Mtv3`;91LX$f6pJ51!Dۀm!IDDDDDf3 *ȄVcIljl IV$"""""!Ddsw%ي(ӰgMC*̦TY$]$ \nf T^v=x_1RJA%e=D e lj|jy!IDDDDDfs *,&I^8vNƖ-,$ݏRDDDDDDTYO $ kfNƆ- 4I4Ddg/ }fNHNDDDDDDf..If6pJ5zfffI_wJDDDDD$8`$yG<3[d8I IDAT6wfH頠L }IK%)U!IDDDDDdDdpkՁ)U3f$)~됊$"""""RJA%T`$%fᔪ3{p418 ~ %"""""RAA%tI"fᔪ;3[ -0W;"tLJ,$yn3pJUVJwcT$TIgIٷ*&7fp\|2"ԢLzu`w`zWf6WTc~2I-HDDDDD>DdGO'2ʧ;f68T}>s#"""""ҔJ"2p̀́ lq.w&ݟrEA%_䵁S $ lEDDDDDAA%-D`$yR3x,mf_Ov;r""""""̖!IbfXm$=l׍DDDDDDƒJ"2rJN1,3[8x`Ww #"""""2^TٚOw݁kX ̟$OEDDDDDAA%ݿH4_dfKK%u;O@A%x6I ;3|j4gHO>3rL *$t`s$ykfTT#~$GQVaRPID$'#`7=?B J""%F`c$y%r3[|`f_vOv^P!QPIDC$'3ۺl3$Q`+ww *"""""2 *tOc*$O 4m $=l󂊈3DDzp]o's0l#nSgsKƳ""""""ea@DdVPsfv]A+yI>bTi LKwO>GDDDDDdSPID!w? x XǺ\$qHB`S$\`HDDDDDd|iL%>f!`Š""""""J""_v9DDDDDDƛTTTTTTTTTTTTTTTv&laBDDd6 """"QPmeG.Ȭ@A%bf !""J"""""/@""""""""T1Ȩ """"f.C.tJ """ҷ_"zȬB='ITrǁ]A~װ !2]Lv!DDjgA.4v]v9DDz 2B`̶crN.٩"'3{p°!"őaBk *LVfvg ,""Do]]/ޘdT$ln`_`m3_DˁˁteRPIDDDDDDDD]RPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDSPIDDDDDDDDcxGdVbfKV|?0sU|}OgfKU|?-dv_cYDf5^>XT|oc"O˄;~|h""""2js٪}c&$pm1l MQkIDFz?!` #f1˔ EǹL*٫ pp8OٜI]=Dj0)$wWO1df~$SV$]k r2k1ϟz*,5PMaYò[ܙ_8̪wfw3{\<֤|vydafOlaIDJ7ef613;8Y}5;/32p7,C~VLs( :̮sW]|z`avfAd3}`R^3; %w!k^\/)e_MJ"""+O."""""}XP gg+Z\Ȭ.nĈT*$5c*Vhfhf X6iF~۰ ;W|}_Q[ x 0^ 3Xx+yggG}}|Nl [Qgͬ{(ۀww!E5~kyO)| Xnf7tZVɲ!Չٽv;ݯ.T=wC2سb߻%Pf(-؎=Gr~Mm EW^J[ı?4k5b뭉u"b9W﬜IeG)#=t%VvWgez^Oڿ:+Nľ3'08vn~ݟ+1#sEAwnEy ND=2yOum9Al2L%~˻52,GܔifW'/1~{~Ji}UؠbOJWvV#Dk \I 6(}xsp77Qts0r؅4q\Un3{دnN."P=+=,$ppc9{m2G-E͈sƴs.s,c-uJ/)y-vZ2"ӊD9&kSK}f.Aפvhc>m2r|%Ήo/lіm3{oTvO!͈"#걇 }b81S; Dݱ@S?^ⷚ~6m+fu,D[~9:cq XErwgyq^} ۀ3z{D{8?駼2p@e*}M6֜vaO\_,W7Ka}O#֥l Q6<~]/ʔOݮ\[=k *M~e(ϻ,EklJ=h5i/?iP%*GKҟ~l};wg1=.E:_y@%{8VҴ7Qsʦ_]yQ.v=-پiE9ߕA\?*Lo%iާ~v `AgIxdY&OX2}ȒW_W1<w)Ǒ]pI15hdW+uY5~Y%c˲S&Yl{nx-?]ʹ@9z8.pIi7'ݶe3fiOХ-w> x|P] |m'Jyq.::ۑhW|Ǻul}Fݦj \]{Y&X?e>K{stkԚJ$p\6wYm؆k~0seUbg|ƢRރdUMD!v[;b'ޏ٫yyT0=O12e=֧mE^Iv&|XDrkٓ8YC\b0w` ."? EC٪^Up"P8кqD`iEa 4ge=8 9PݸRE㈻qؗV&>dB &. NfEۋ.G;w.Mfwq77N;89$B-=.v2-Ge+R3{^G/f#p,q3X'~盉a)3[7,DD`UfkE;Ն>8o@G\њⱢ]BKuᄡ{w*:هwif+猯mk[*ɴiV aEf祿́ų|>Z~Ͽ,dڗn_OPNDMqwѼ Usl+kvO7+sqq ?PcߤN= ^`[%f R5N4tA;/M.}޹rIgcj$&=jd ߲tХWѐK4XNzb>+fpKϥ5 wgȻ<{zyiVһ4+gӌEO싯".[Us.H"0z Y}@H:#븧-ߕλ=UFTK/ܐMS\߽zo}tމay/ ܝXK*5X;p{t}?|KObイwХZ6mמJYރu_;[=%_Wt1uRFnszH LyM\Xqߠfۥf0$4#znLc6@VۋʾB[y ظr˖[yA\퐕HzyO}#=Aήn7Xq]$˻xq80=I9 ֶKUuHEޅǞV~G2=щGkL>@sOS61ﴷDu^uv*o2Iiۺ}{kȟ^%!oWܟ>JDt1m(Oe9$LM="Ե1?]P)>#AVgV].3U{mYy * z>Cl],I.OeLst6V]ݮ7MGPiӮ3LSLfn"y f5C\0ܛM3Ju[I}y?EN1MTA\"I@jL?{yP"^c-c@l2"ͻEo*43{OgcTڳ^#KkTZ+[%{L vAИ($CTd݉@T˼@Հ;~cbI<24 S{.Wc;-3Ҳ_Y&n|W~1qQ3~SgC},s d|Kԕ2c*-Ӊ핊z=9+y؎^[NK??)D/1{"җk~s,@k'K㓤t}+$MޮOU]gGD<E-{|jPGgҮoDpxei9!nhTo~-Zvʛ}UiեghO3a-$X{^0h?6lUg+x^/=[݅OT |Qgx.L굇jNJѷ:5Mlri-麝@C1z^lYcwOXvmy<6,JӶ#\Ug/?[C/޵xdC8 U 7[n!<^ZS""MTWk T:{B8S6JFʚzA8YU:@/q~\XWd彵osțT4C|VWUބ4%ϹYYwel~u\Vuɛ={tTzW}TQ&LF',^'1U8DQO%}j|T71`A $NO{WGo=b2=ۢ,<.+a5=yO5IVSϻaTfe>Ӧw_|$O8{>{ jN,R/7_QAwJc?uԿGOɏLmrN&w$,@ W^H9hϽM}zrQ.GfOs?{^oZ1hUv I[b4f1 SDA]߸z~ [`zjֲ]neطƺ[7Go {/Y޾X3[EFx{ p]Jw֍Mj]:im;s Y}fv&xYE[֝o6~^˴WG.1E˃^2:Xnq5n dz[qqu|.!St|79Vu^5fC`fKmTk1;S7Tt=DD[!fGY:wvFc9vъ[f5/ޝ˟=̦לŊg/b}c<93c*5}|,#is>YgՓ)55 OXC{5 9)z㿌9I`>:/}yr}fu{&uINOٝ8G{4FqD&=īV15=-^h T|j|ĘO DܫMwfGL+?df'ssu3c\|}B _w>L4ORSMzݏV&դͬnώeM 1sϼ{5˻XVMP =Ҫw55y~|T4& }qNHPgSG27 wwv?}#M>nhe޼v}$_\e˛P 2y*ᴣs6@fy@d&GK463[xb$ĝ[y.N^dĀoxNO\KtQ{wX<;_37}LE`|:/$z[D|!`FuxufT l>;W44ą-ąD^xmaFwa4&uX~(Wb^'S~mH@Ì,ˈ' Á_s/ߢsDZྏΗh Aw/tV}x*1S$A%3[ ^K82r}i>teob٫hߩv mf#يΞSh_~NoX~W}Ө.n:͓%W>UCFjݠ]@?41xvh.=og sO7P|b0#s\y7})^t%DP˶Tr_մ0xoܽI 6HYHňf(s8䑠3~$lq{32zmfe8p$"',,^)ml%w ?= cq|j̷luc`A%w5ٯ=,{2BwA:?Ocb{gtvQ,D} wKs٢>rT\:x{I⑫27ƣ8({;ǁ49V6Hٱ\?Wxz"Vou(Dʃ"d,d%߷OJ|?mTj:[~,|;;J&Cg4&uX^~=Ⱥn:^1,%N27F1Fxz vDOKKzmBg#@qrⱎ^=:֡x I{|$i{7w?I3r(oXv}XE}%~|"a" ={mG.]|ג(?A` o6X?MռWvCAw3r Y@J Y]gɣ9X/l0mOEӑBˠu俹4yO>ȳRPipj;(+I:P׺u]GCr!:/30{l*d}Qk(y#˩QCR/=^ݯq{d>?n9x>:Yo=[ :\[=xy릯x 4pq3&|GtG{|u;?,~YX\T|qeV'۶Bl:_'Y &|3{̞5m{ߕ;h >;\u|}ev,8UV{h+ݰfmNws󡗼o(ULR+ꥧͬBz>`f.ƹK߃o8)Ko[6!Ɲ*{%}mb~9oQj|Io}+zb#~ TqZ3Izl1w;p5Q=A6O3[&) J{(.R\.s s^]?]wn`Q+&IGxS!f:Ywu!;괳kfvR/+\{3eB;ؒWsW՘sŹ/kdT**~gt>fVy9q[Nʤ/lq3; />^$5`Ҥ|%_Bg7lŚ|#7W*.fZo(.ӓJԿp]"{罒 }T6n:w#%V_;?L˲<ٲL`It1u2'p<qJ܃xۑ8x:xTͬۇH6o5ҼNyeT*Jku5c\,vR3[؜.+zS/}MW$u6SkԜ.?H?'n]eLE9]9oY'_bmBJ竆9/`٘x?^U> H+|v/oldOeľ[רdfzqW;YAzˉяNX(}Qq!]~vp_ Z1>T^},oKqIR^O1r6(DjP p/0| ߥ}~/ۋt<ʼnAL{b2eGfjfZIzUtKiz7ukY [vr U+{ohdsG%z7٪9>_XSiw&"Wnzڣ~wl|ŞҶ cY:=^Dzln 9.WV9AWhaOXҞ"/অ_CgpmM34W~S4M^w ;C\`{9,_vt׈ѭ3}+.@DtӼ;(A4d|A12[>X2&8 k,}UK?"[9* ;8G6$NfӉmz>>+C55|t=by ES{K>%nI?svɻrV[o &g,c ,\'F)rNC\T=%y7"xX-*_kg݂Sv>5]-__%y&pv=BMhZ$˶Qwξ_??3> An}vsSl>'/n}Rm}~|"`q}4j4/̢RYx U]2N%ەE"=╔K߷+r:/Ct^j@u|`QsƯ1Sxbs'KfyʯFYOsC4%iV"@c7'7&y.G>16žv~ 5e+ʻZU?IbItbhp"xvEl}YUYz>VO4UeAc$>N R|ߖmZAbY'fqb6:12wO[Nߟ?界 pI컻#cd'-b{nGo.íIsN=DPn/"0ZEI54h{ѫo5٭#4iPUo}fb-b,?mJV~'ꍣ=cdGmXԫ*oe|}6+jLB64`f:bN?GPlsEZXV<֨a1~]oAԡ/ll <6ܣDvq.cH%sj۲nl~'o#ͭm_V6AL'ŦDOMqݞ΀}D=$7+Xx EuwsV۲u(dcYvm}uKH;`ߚMt}DSv%>ߟdd}|O߿ir1~5;/%n8>:JnV,g_:7\.y_\ ͩ;qo'%СvWg@OiDyQ߈ {k`F?6?y+\b-و?7϶KtF?;]#ټȋsѵrj/yn'Ȼ e{;5w}Y1YD #/T`(b>/W^ \<^ U?$\e=,^r~`"Ay3Ul:qWTJ?7%OU+ʴ*10giJ\muۉ@5|1UNza"]`%z]rI{0yS:I>e-hqq=3<Typs3ng2Rq붌qcd9؝f)Xswl~ZU^4EfW>{;D#9 p1ĝWwHn'"Ϳ.clOnZ =iZvktU|ew{;gS[lۉ;)%O9yElm q~ IDAT ыE> <ї9^c8W+61p::Jۈ17NxX?.%Nr7Mnퟻ=^Nl; yO.i>FcuObwz:/1hf+QMV77mk˘Bs!z&/Eԋ65D[ҭR$z82DvםmM6dw<ꞧ!˚py%\S D;Ϋ6byq^X7""_xv/y6ghu]כq6 ]Xk\O=7sϯK>L3ΫŹ~w)=@<Sy+L fv#q!:ohJ"ҝDw{]L,UA%iu?@pw ťX7H)P"-J-RH;ECq$hHHBx2?f_ΞsϹްy{λLEDDDt,hD,4"""(fyy[ypJ./"ߥY3M@9>ADߊȖ9dxTt"""#-?w?/GDDDDDDDJ3zbrʢ2,|mDD{((%;UDDWꔲi>>w ,JUDDDDDDD'AT*EDDl89̄EIplYG%s[puDZ!9ymN#""""""f """WDNK"HO) UfLU"mpw`."c un:V"AF^qEDDu( zz&"$?Tc,"#Fp;b}L>&KP-LSSh\gqf`{ yCk 13CDNn͠ڢ7zNr8-%HQ NDDDD`̒4.#"RDDDׇ; [ ,NE}D#ϻco;`V1Ovw}k8<̂)/SZ[#ѽwHDDD.QRJh=#ߊRDDDDׇ x\h#"8E|>pVJFXؽDD~ǟ7jT5=>-%9sz_3'&"4DDWN8F,3ZGDDDDD9"r'0~j~""""""":k~j"": TVﶚrpQ=DW>"ԭTYDfgb("3t9{H vs߻gn6\W>"2{)"4:ߙ"KDBDfw\oJJH3o/EXy`>žeFY}:=%jXnW\~c2&q)<,<#pU쌍?""=2?"QŪ𣌬|X[c>v󍕆SUuL ݥ>"2;{kre| \ךwA}c3.|ہsU lamq=iX} [U 借e<~KU/qtsvڪgdF}퀵D>MD>W xȽ{w9#20YD?շXd!8hqQU3/߂2xU [a.-^U=2=:\%<6_oe\R#\73`CS;2vPV1f+`)+"waV Y8X9#\7͟ hgyWUYJ""obt^#"_a.LNI,QbTQFw`Wq:&Fb3ۃp1 禵a7 asN"pss|v;@/x[!Wpk]0p 6#k}YݽρgKk}w:v?ƫ".6#wVlXy#l.}<-QZ/[>3+ɮ`Q;ҮAX#|(FT:)t_`ѥf;y6um^ry{y KIi{ lZ&ߎ0Ar\wܟ XDȔ|?~ bpٺ(MF{ډ</QWAO'cÊARN2Zg?Kʡ*y/̡E]C{Y^„shҎvOTF~gt}E= ,P#?J?I')n`I!+Y)p 6y? ,R9h68^C3K|gm`^S `zࠂ:\ilOi2Nr xx-#9!Ȕw$ϋo槟wZ{9_;ײ9d?Dd{zྥ/Mqx18旜ߪnȫO@w}p"Srg)mx˗ xi/s37^]ӨX*mKհI%׹vβ~74`_1k1`.y p죪f1&,$={x<#KpVVՐ4pZ˩r}R1bǚ]"rمJϱ]kTu{X[ on)Rw,]݄lPyBUG:k51m؎u"/Y^fڴl܆|q7w @Dٻu3pNͰ6= lβ.#>ƾ ,D<k߽:u@UUDxO 9%w(&R`KafO=f{aV5OcuE*(}E/!"bu L6Yds!=^kT^-4f)Ɖg0J T,B#܎߱[TS%b}b3U}$yDu{ VOau 6=ztA{RyGΰ ƬOv55;T[, ]kbBboL|] X5Y989nNq996l/d :)0d/pUTTρ3/~Y\@łdUlX]`Ű+[wꧮ '։?Ed)LeTY:렇slf^"6G$cطZUpEkcd5la쥪קd.4jKDZRmOłLZUrC ꬬSr,o'H0 6O%xKa1!2aMLv hW] -v'QWd`"m6|RF / }VK`J1f]76Вod;3OqtS ?e|,n-QŎ她ʣMTJIj/&5RhP1!2]4i#y>-p w7ͮ:-ƺ_ЮE۝UKVvilAо kB]1[P6Ƞ_;Xfɡ%hc#t:7w#ŀw<>_Y`ހ;(Y~{&̃^>uKX/Ƹzc$Je 0?Gκ9ѮJŚdtx(cN:-+N$G梭i9{t/ 5.X`nB@=1ܥ[;[j˜Ŕ)~}N.M(sB珟6ImaoEEթ[r6űՄv0_N޳a"?ԓ~7G%WZJ1JY dP 'J _.:]U*a&K/\FSJϊ fJR ʾ0^W4vjtl` TmQ{zlo}.{MEٻJ?y>OqگT,CqWY1m]['4JQ*Mv͡-1_zq@ς4{e uwm ҬЏ"_YJz1"vX|c D1Ի?[T$cRi:&gni.QA4Se G;PtZ-[ǣɠ}ףۥ;%~T¬F,~h#՛.3Hلptwxtǖ?VٕJӱ͢K.s5HO{l 9|5./=US8Y>,F),A;uJaYCmc{/Kp9eK4:A9S:mtdzOW@.n6>'EY'GjF}ƫs]e<YYdz47tvVTu YN} :{Q1s{ĽޭL;9"bTY& H<آ>A?L [,H{bBe(p6;/Ŭ?(Q*j !"`ʘ1ˉ(B7|!kKd:3ߞF4aGcp;&'X28'P}|N3R;wk0! `Gr)*\Kv(JnQ#juN-OpSS$G,@-VPN08wi&7ѳ=Pj|gͳXDa o߸;z_zy}wLI`Ǟ4bGo a~͡em&;& Go Lt6R:8?@H UE㤪~Cu.YL7 OaN[s^=sN-؉jd T 11imF+eT+>F vKsQ2͏Dd'/Zsr5JU(#b&@e;BE]Ta}G[*y,c ݧ䘜7}Kidi"d%yDYDrvn:ާV'RJIG˂:˵ sioiM>lK]g:ǎZ_3JC{-#>t|^m]2͈k,m U2)AshCKqY㌗f %x JWՑGxlԒ O eB\]XKE#: ?rm@_꘤K)4){aWwG|mU޷pi6 C{H@{VIf }zseWǜ Jtk̡mR'idycHvÒ59)4K4_S^x8H;Iuk ShSmA%Ui.)#4Gʘ*cB1IC޻sӌ( v ,Tu;ڄ,:"1d"KЦR^;hӚm"P^+/YC˺Fy S(GEdqLQ`mkb K;gɝӝJY.P<j kQ(+sN{ eͷ@6IrpTou]# B3?zTEN "~!w-M>goo :T >>,#Gk$]9DL&J IDATEuL:-8`e*֣1VbDi^҅K0֤,'"ðox~PC_Q}4L]D,8* rC3h+YHUuQ >";C>H^{cl蒹p0#],|TBUߨvK6È:҄Z5h۞cʥ۱6AF{jB^Jc2lwE^ӅNeaoQ: - 5iAQSÂ;A?K˻:CDFcV~~iYIh 7f69,֤hևZFC8("}hWզ` lkKHp~}vѹ3ׄJ?h҈eJy~Ir!"cBwܕZMQz0oةH;-{ɸRU)2!T֡Zl>e0KM}8}'o"v*-8hȎT19|.)H:# ߣR* ,ER''°yQ@lu WHAV桞q+}QoTO;*;Ȭm׈Hٱsww89 ZDd۵IuTI|/"ǒElڼ{m$}'\,"c!үCYJ/KAg*}/MeR3F*^FRݾ&:#ik9V*yIߠ]~#{]MVjgJ O0kڳVQw TFs&?x9b&DR-J "?aq5XkZ:M1--U}\-t:FD8E:BKٱ d0m'P{EdULnj "_n:K[1ZEw_2S%fYa((KKDAhJT;(osY']EIK0 {ۅ< ؠ>B3g 2ƟcfUGD{yh̷Y1`W`[,Z5A{p2Gìr {E5QD";`oLA@&(c!UA7}jor"P$)fȡX]h;9w31gMcnsQՇQ^np s(B|ڸ~ Y F8E1Zё3 voi s(cn]DdU}N> !"nv):!`Ax;}qհywgZ !"jaimx'n"E>-N-71,Xze^ %k2w vx,":4EFy .pV!}ґpβON0k{֌~?l CΔN~Oifw “|i`Ol:<9?IKRNwʺ2, ]K3:| "2 -(A!mǯ/1v {j3|U7NffsSS7ƢY"l#v'pΏ/n,\k9~~>m9)O|a?VǛK'xZS W[O^7t}Q֟N-8|{Ĭ_igj)3mJ ߿7^d"php6J?}9r¶,r "+#4a'RH~;xi T}U=XA𱿈, 륯X6;]ԁ() `I.a͈6""x>BwkF \H"H6PW@8Nt7i(iNVzquW'U(AF3%F:YUoU>pf],\}OuoG U}PUbrT3w fkPvhrD{FN7[36 ]MV|ɕAk2m#ߵ}5_LϯBB3g/F^I'r `[5Vt5H?sTDzvj(Y(RJ pe=ҾNB|l#E/V,"GDF3P,;),^c9fBV;g?.|ȉ"pn w&;ߥY=|$6(uu :Jb"Rˮo1}1U37ܪ(#nOn7lPn "m3*EsZ9,US[kTx-/+m/,IC)y5.JkޭA"R轨|YEg[ v8 >#$'"˸2MToMs㡙㙈GRmA~*-ޭ~L* bò m[w8fkoelCX7.;u97ab'a#W٣TUZQk4e eRh"*m;m]o0xSTK,oLrtM@3JPdIg\Z-(ag Dd}]qMQ2]Q!ZD*Uo4 [e'Д3/˙ymNKfgzz$L$X/4EOdkTiK@Ua?:msicXaG2= SE'7tTd,җ+sa5M LHEdv?߲j]k7~EJXYc珆"e-\措k VkHb$%N@=B[,u8mzȵZpp#Nwaa1fpUv-@8NejY sz7%Q9gպ ]"s4b8/|lP!"93>J,6zF~nCbo4t^%\97U x|N,0DADkd W*E+ޭyi"޸ i^/ 0C-tcZya 0lDdQQ{f\l16+FY:!s"nQ ߣZL&TKL'Ga~QF9("SYP^[ `o-qXHvCDm߈;)B#$_(Nڃ0XX6 m:GmqF\^T"S\=j5 ڗ3=)tsԭJHmT•T[^fSDv~~I¨8 - zKszT[Yp(;Gq3p=)ڃS舢 .9EGRVNvjam9VwJX:yQԆ[Ǽ[y ͽ[c cޜO~De }BBjȊymM-PHt'sTYSD6.*PDVx7dd~;HeTOZUC NzoW"LB85,.h>1IZi": TiAkPHStagǷfc;`\[(珻g_R&(sv`/3h&v,Hw:.iZ?'[|o9}13v"uN{JP/7^rʸ-]`ZϕA翁^9y.)^|fPǩyc>#zt/I*^GKy40 i z 4n?Oח_HFg94X9[:T̉M <~f`&Ӂ#2 ybA X v7$ח%cvT"8)6C 6k ?xSK44Gi =[Am頠ۑ׿NgAG3X= Ekk]f<}M,9<^A7k.̅^~935)@|D#@SbqWcW+f-Vv׶txlp~K3;w{TODHd}OXc`f~[9 [< d<}Z[`XH賩^G a~y=ͥxɻ;/϶ti'zi7xg3eXף,Ѥz JsPQмE59j%Ao; "h>`gֿ _NVZI9 Hkcwx4cP,cqA]Kw4g9$=X_X;n(krNx(;lSCixҵdۄs\#of1#6؆w&R޳4C:&edJU*2~G vLp̙lBs; ݻ qgPMz?)w䉤=¬=ߟNYr}_|vFӘ,wkOT6zǗ =UcKR='|õ~uGx2X_{󔴡v:6$8;51k \9`WjXK0 D-J]7Li6kwc2b]wHuv Fa ǸocJIÔm`1A`@F~Wyqzhu??)4E&Cռ+1ڤdNβ,qL]Q9O$^U=)sVL 6 `Xz!Y?$jǶ]ch+ d]cJ8,J&Ej߉}uj6;.%_;+o9l!VI?3hw?e^sՐnwfWBŗVu c*bJ DdGzC oKa { |dʳ?6N,MeǏ9>U}>')5jϥYŇIO0{nlq:W|6Ƭi>l̻O5OprlɅ:ɣmYtyy O¾L w*3뇅h̃bavrSLpWsYž|2q%ϙ[VK;bmD1˫4{-2GNSY3,3U7s{.`gl3?YI]_"2lg:@oo=v"fNLzjoɫscc0>w'*/̓:і]W/)*.SսKI #03F:xN`Im&"A,|wuFh J͇lA% 4` UB"jD; Dd;* B;˲ϩP*C~#"""""""""penJ]Q B2'!6?SշZR3;&=\*"8s2`QK<""""""""""Dd!Q*.<.SճZRDJ΁1w#UYvwCUБ$(;O>/ , D\ࠌLJOGADvx|`}UCDDDd,@?hv A^4fvSDdŌTu'&c\@;+0EU'wsC37S:"r608)Х0]qǢό(5b<b^:5D$]GBD'"‡l X  CA.͙H`l; mѾ OG"G}X*Cg:38xKD6"ꦪϨ<2m`.X#"""Uқk5?nDWiDn,Dd2|#ʌh6Dol{t6^\c@ww"rW߶)N64vPh^1̢U]CEh|8XOU}L"U !:QDŽK+$-""""""TulT(Et2,E N0ĪIT("p9 8::*"""""T~ ٔX8*yJi-=%\DQ9p~Jf"""""4;^]RI HTJ"2K3_D")ʊHoiJ3MDfZgZg1YdЦmV&<5/] "ҧo沦y൥N3=!Xѿ|  "щ{,Mȷ[\ݺUt4:ӯ|Ԋ0xZ\$p.BDz5XSZDzE4h f}14M %E, j$"Kbv;XsT?x"VFSTu|JP {۪g8,{4oN5p>o WՏj|7ƜomN<\ DZN 7c#kUU{5`O` `qs]0.iVym4zH`Q ;x|~s|{aEzBX힍^֟Kfֿ6. ƥw| S)wzq>T+klaXps ;acXnxspF p? ۞Wj+ .p6YI;=mBbX{k/ ܳ/Uud?y|29s>țRWxα)^I[;u<녈lDsT WZz}WU/oB1ص70s \D~Y'xe^U}0uv0f94͍qñ1FzƠ4^gwUSaB+9bW$QDd9yȂ6{u'b]f_iy {o溷kͷؙjG%1( wrݜ>wmDd3@Ɲ)޸ 6 H0~%QϜwxKU/oN`GlYKgש; "sg=pVEsܭ6,q#lyZD [זE6KU=}^|]QF7'X;fhalܸ9Jfq|mUyk?އX=^ 9↬k?d&믱XJKvt?7N&,QkSUuZQY)eoܽw&yЌlƨꩵ]5w{_a%\P/E9*߽ Pժ [$^q"h59+e 'Bi^(3'2WIגa}R#c*ܽo$g{ꩀ~ ZnA`\E@-$# KwSR9{[xJ/j.l1=&O]J9@omB 9)) LP8',3Ļץl;O!HwynM!ݷXǻI`nGӒ&4 ߬q|)lTvyCJ>Q(jjOi}"oN]7)iw,HsL@ibǸmw,3.94mw7(7SOҌOi0_ MsOy_lR+cL4e uw\.K"i~|R) Ng lQ+ O3>LI^ ,戀~alcŧIƝ/RE+md 1= O5GkOyu|ZF,_6=19 Muo.k~vLO`<%ֵ2dp|kޘPT` 94d m A/j@l0݀9DdU<%16ShB< }`ֺ%\ !٩)PT[0 Wei39``հz>_%"Ϫ/silKv!bUu1<"Tv@0 MEXYjh74Z@DtŴ;N f=ruLۆӽPv>}ʻЋ/i.:ؠp% }LĄެ j/Ӏԍ"2؎bYցM<fEd3/c1{xRN̎c;/[*&I9>& @[fEdmpa%xrݫyJXUJBD~M(#', S(~ODS" pqY`e4LzwR &M~gg -f p$&NTwyN~@"`8^ʼVǥv2|}T#~Yt.UZ*l$rt`9kk0* 72(pV i nœ3.Bxx(TujߗT֘Z*N,!.Y?US003z?xNEE'¬ۋ`ж]Mz]^`&eRχ')ucu*)PeTyacGcq>KbXll"?9<<EBpۯK& [ԃЏMzbd0k4q4Dd 6&Ug`ɸ3Qy8&-k uK*ctLO)f7,`bT[ _A<CKTo;;[,H)^l5Tg0n;J"SUo7;'0Q{X0/c 7OY*Ka}"Rĸρ+LY5˙ؼz qwewI]As,GT_QYvDe̲{=KUG:YwETiyozi|KO}X2CSջS [R)KT IT VաՑ>T,> hal}2fҼ ,Aۃ85BK3)}ikeE.M〵 ک9? y^_xWkS_T?*=yB1@E>oӖ<ڕ2?rA `?,6X.YAݬEx 8(!nD#KN{0g@;+Rɟ?)(shPft{i]7 ͵TUp2v0YA6[]}e:^^@{yK;7[.P@wPWXS|˛oMSP"SiX*mm ^?kl[\_ TO!^^[*a>/#̖Q옢3 󰠍\H9>ݥ5_ba>ظDd) x<۵ShÔ>%[U` }\~)Hd)ОGdJP X8Hlcd`ATN*cʒԅ3|e\q 5:;T*)lG,<24YA\5nˠK3'c2?.TaUJJKG=WcoKG_RIh{*Rpm$O \ІGvs ^6CuP)uٕJc6+Aҗ@Kf#}#Qx``܂Y5%^"SmJ$&5_('wʡќN>M}/T{4v7 +Y{iTmٔ*J丏N4tp 0 AJsJ+WIm\տ@_>(2QcX5'!ՁwNnz[:H0cByՎ&Nu&"cAQ9K' 0!b6q9 n1oAx3u vd?ޭm%#;m;iq68/v'dMM fJu߿IUd(FIVއY\kYGC;i7+^r' :jcOW ET a;qp~ m;RM衘 &\8 zSul K#>n1q}v̷X:t+¹3Fg+cq4U\wr Tl2˜Ҵ{a QȾՒޭVX]PD0[qF7ltSY* 'vZ\-\{T*/0%OLW/ia/ VS l #>NŢe-|a"Y;6(OP0?I0s*ULUBU*?; sg#(/ah2"5>U:PD$-ϩsCI~¾O݁ K䍪~HuQ4{y[R}䜔%GAArQr$TE>DTX$ KFDIمe?gB 7ysT鮮R]U'](? Ec_@.V1x)ifK]g4Wcr U}}#ʩS>ʧJC?BBsn΂s 9:-2oH><[8qb>:3bFDSwkZp?" ;PՅM/s6VrBUv|緑I,Gp3 9[}Ł_i۰̒[pw}dtn⤢zGu־YLR*/ݧ14|+V9=פ} 殟?m*qۛpEEH3(r1NkgȤ2\N2CeSn!jvmBSV[+ iü:Gz'tz̉@͉S1H"$CDw+Uw.UZke.t5KP&Tu{Q?'c/3q"}a,8a4`% iz!軀)o'/D8[;kġh$^&-`)"=ot1[r a6&Fy6s“ckWۏ qSY& U5t|lSG4=ȟ*s}EO.z&T>wƎ$(;O pbVzM>!E +T][VT@TG#p7v ËV#mE[#B-̬7ЉZ@RiƂ4AKi-ss&FuSE#3-"""(Eb?T*MEł۱oACaDI뤥*~QI*FQ63敱(0Îd0H?\Hk <0ڜXa|Vؑw.K?e-v쩈Hz쮀9Ml$Q¨v3p u)|>Dd>KhOqJp}H[{pz%;4E|(i4sJnS ҆}p:"Rf`:ay~-12`laZB4z!Y$߇Ԙ/A9U}c|+OMD~.\=#%aQ|S]mϜ2H3~U}VDa5_'훮 xĺg9ei۪-z*BY}6\6M)bw>t|G[SZ%E7MDfq$(,;1~` ϶"r=wNDhKwFM PĠim""U>`Kˁ51U F{,8mE$\W 5̠2REJv#,.LC-Y\J g(AU_=I;Rq-d1ƽ@@2-6I)"gbNl;,آE5,:sӭD,A*܆f bmy~㿢x*L(xODWb#Dd]ҊWfgnke7< IDAT|-4:aQ[Kh ᬒ7ᘅ|4ۯ߉: "!ҁ3d I)t;,6gmA鏰 ׀BENѿ;mjlu "67k/bV},@:IOY$SW*OɁޕ`8^$} 4LYp2tҲ.~}gCPQΟLTECypgx<%JBi; wYp(WBAJS$ 1[T,9 m38ID8ԥp;LcaWo,Hkm T}GXf ?vTZVbTIUnWP(Ms}~됾V.z[lY lL3wmUNy E Ed,ՏOip<3cTbbY볛ѼpIDvRпeEDJ-#l$BTlWMJzB lDflj'wb"fV Ɣ־BX,0K|/"_eԷ cQ Yk8RI,ZVU:w6'΂)w*8_.{/PDv!x8'yPόw͉I_ BUsQHUWyhs}"GZC*U*U̥%qvը{ .CPl9|Ϭ~8ZfKEdv-on !& OZp4#J !(+$:gE >}8&RTa*B)sfsw j(F)2ަy(R\oZ֏itUm{9&1)9]?HkPձzn}SIii4r~xM FU#b[,:?vr\aI ggRd-|ﰯF]JcT2USNLYLvw? %&X)]ɄZļV:dX~gu&ߍY%#aTpI;t.6CQ-T UDU7;IU N#;tC!;3Uu ϞDoN`b}rڷ*c0*Kr]'`!wkp>y3"^Q2ӗ4N|,<YtU`/܄~W@SEIҖwSOU*`?drkPշUu_lGA2Dd6cHGٝXQՏT,χcM%/"'%}i*;,OpZ]gI; b$#-t("SȷckA?]MhO1˶؆o2qȐVyz|7rJ0x_ 4 {*z{b|L |*>w)DdNB:wSIȏS:Z㢣:c7QQ#"C/:z>a!"vrJ"/i* (q\_!Oi0 vBs[m+t XCu ;ЗʬЧ̪T)#ccEec0 ƓH.$&+t CgTUG߱ #-Ȓ"r\Cx* 9t2os&مPջ0V c d;cjH{S܅("˹rA I3TZ;3RݏsmhtX0["가k(nWvo "^{N =2Zlzic1^tY=VK9?& 8VkZ]] '|lji Y_ l~=&gcJ?.#p;qxb0"%EBk| ,ABD&"aaDdZW޹ֶ81=+X4lCcgmDӿ1"FAݠY!$Nljʰw*I;L2glҖEdz`ZLIXcv+F1{Ձ#G>+靲>V;EF4LM ?{li(pI_)‡n,pޭA"Ic2?+NX]I9]-zRw=~Ȳvw;'mqSIKcynJ-%^7Uͫ0ɾ?wk 1\IFLC#LIXTC;pcW8vȽZT5߿[/\,fʶĠ34KQ+"ww| }pL cSamUFs"yN/"1ʪvۯ'iUHt 6 8w29gqol5#ם}껺q&۽,xjp&̹۶;`3m(VKh~CZPyt$z@,/w|#Uѣ}0!e/+3sBvBU?¢$"2kw9CrL<:Eڜy9~RTSBFY5]P =YT(.£zz,OUЈ>wJ ;Q9:ɆSv[SD Ê:Eޭs x }#Tn׸_Y,F5-On͂E<ʅG{x|tB=Rh\CŻV„}"ś Q U} . kΙ=,#Uu$?m{$ʹ#ጴi*i )O);·ԝGD}̪6A/\/D4p!NwR_NP y},o[KcǪi!;X6_Mm>ӻ]NDTzf'y׆W)>iT&,Gcl")_,Y5B:&"RvWu$+1p|XV</QyPfi3{;j7=n",HN|+^eĔɳU2/?(ūx3c>u2 bl~/0[N;9! 4ȡG.\l1YKe~2Wk!M ?ɠvT 쏅٥=ţ??{>_FՃ2))o0fЏ-caN|#j^ޟKɣXv]6 ɀ'g1f~+[h2BEt_R?|,۩m v mٜ]y[9I˨#yO-Gױayty兲oR5=v394dm:^9ПѿOh{휾)deL_\B[l/ |H3`ץ059<lw_{։dwWm35/Su Ӑ>6`s|L9!CY^[ݳtI 唱iޘ6h#4M{FPP3` !Fbַ~"UȃrҜ9 Wɠɖ2xn>KaG0 '`0e6ԯ{bsv1پ4i^?~K86 4/S 2gĢ%eބ űE^w '7gziV?[w9nŬlvs6pl; wuܛ\]cP`۳Wo< 5iE8rik^ܽ_uPlyxAxL-Y9߯!m~#1MVu;~Y/{ހE[Ž* 4+1| fK*waoL`aR{/^Aqryo5{ڑULڵ՛ UNðEV7-crತ_1 isb^=^ EYf^ vtyߴ^|bw!lۋ2FY;9y 1O NZ VL Xd-M/7[A'g{i;i2x4$;Ӱϕ4t$w`OT䦤엃4>͓CV's/7_  ͟+>9=!U_ReN~㬋2>]lai_4m0hOk=͓F!`ˊyO)u{SE39`6͉U) ]f}Vv@h.,(g%m`FA1ʢ*o ndPKVI; ۔(hs94/Wh>dWv06."W?;=,W1Aڧ#ӝO)"󈼋䞥ɶF oc*|}ybw~O`H m)X>2)_?vv|'{]Uhߺm9[_LSlP9Ʒݒr1Ly*:_rF=BEq/Az>^AEE3vz?D&L9: 0֜;l6C;ߊ^[#_^H~gaQx(Ӳ[ԫ ۼ7жTQ\q7݂Y `||7gƬW?M+ ܹ_;j&|; ; h'l/LFq4팣Ұ\2Ǻ2SϑJUfFaXٰCs=gƘwZ򜪾fṉ[9y?S:1Y0&zU LJyLCsYSTUm+̷;CvllΌkN΍_(m vh4}5X.Mv69{$R0j^] }{_U==VY̌ twJ.1K\&0j9#S ۾v}8SlwU }_=l?|Srܠ_9gydQgJKKoWKň6>VD7&\[oː,{|]2"=^~- ䷱UjNbDWtQ~CzBL|&ǔ bѤ-oWrc%&7,O\7U9YpOV\DV?Eܳ8r}lO(7^cҗ"g!+y#OD!*S;hD]Us8-1>?W' I-X^cpXw2r}Q}s[?MTQF5jԈl."?u>B>dj( 'ޭQXV̐8;wQ86ŢՕ\˻j>??W!]TQF5jԈ>XAsr︞T1P0WFֿo.&QFWAx:ɻ2 ijF&gz IDAT%?` D2f=--"s+ȿ'5K |B $m?)k_( "bNW{-T^VԑkԘ$1 cE P\v5O4Jb3"2۵}oTLUH(=TuYQFDd+Pw9SU/\*I?UG ݯm߅ " nz$iyv$2`/`J޸_FUIzMPF=?%lZjL۽[9UI"*wkDcDd]m2)fUݸjK/hڞ+Dkt"2pw _woI -N&Rk Dd' ڪZefhp].[˪SUN@D~eM0g}Ƥ TO[U=wj?+PճEdiU=(sZTfmEWy] (BU '5j8L>X sn ǯ;>;rk)sO 4(O "23`;,4(QOg5-;;!.^]UͤpeS`K,|#_ˁ[]ԭؼv69A0ǣje9ǩh ü0}[We,$go)"$~P@`` ,J̘ "pppN(g1`ǜ& Y û-0ֿTDHU?pKS_/# T|~'%D،d78.*k(eFZP]`3yxMQMDd#`k`McVEn_XcY`&wc,9mϕqƗ`mzp~TN%EݧWyi&RU=,%J1<ykQظ BUH?騨LATUSű=`.`NaW3Tw[X;﹇TuLvGaf+ƃIQp6\n-? _SSDdvVՓv*WzfsbU}(C׶þ`"!pp-p~^RW|` ?o:*~| << h~,xՑʯ``-L\ ߳a|c <HNqG7Ddd CUɇ WՔ|uAT켇o9q| #+#EG]S~%uZw{# FNIaΓWF_`(aΒ0pA_  m<| - pY]R;wIr/f*o>MVv<+m`u_+gS? [іWV(kl.vٿ_A^WE "鮘1?DUpk6`>J->d~9Пضi(I3o@)|)>367Х]Ɍ ͈ mv4o<߿ES-Og:8o-(LvJI=?{r,Y^,}({Sh&`TdGJ<6O6 Ѝ(H>L~d$M97 sț{ꗮ3ZhK ~1`5-Snp>+o$Sbu\}򿏭,eYtr\_Tr;b/cJR`O98Y8ҕ'l&],^Uw[b1y}cYNYInv8^q;À}ᘀk`l2=vYl` Cxc~{4y&y[v[,d~w 'cnw[EdUWF},lDdE`ʊb}cp>'FQqβk l.-"j&S=yl!ă-WAY{؄*o~[$}yV2[ 8kqX?[U?;F a:B[l,}$fScV4x"XȒخobApprqYW,"Àyg_4g˱v'HWL\X;"mȺX({>X㗛cou2/Ix?,uRΪj)W׵}Lew %VTb<%An4"} X]uyۅ|=0`;+#kѰ{ -n[~;>X=U= ە/,Dk`?+t ml3nlL.mDڢ(6q ~??4l\0}^b5!X_9|YyìryGkqmOӘ_v:1|pwӘL Syhc`3Wvp)$S1+g6\MM4>ƬoRw7=CDS ޡ n`*޳q" ED~ ݺ!PDd67] [D6-{2p fm&V+#o̝Uٿy9llOyl ֧u&`BU}ɛcv䕡b"-ice/WC1~*pockc ulXMx{1ES:(`k?l\'"db =gaǑo}1a5l 7/1(W7Z> &mu!3a|EW4x"2fEN},:!VD-VϠcnߔLQƟ4( ܀FNk0ǀY "{H`RBYV;zÃk_f. >e|?HSi 3f`H[|FU SZ}lMh۶THx>9f4MozeBR' h')lYv}^5[d~M\Z*=W9a??KʘNc(g1ŋp[N)VzZaJ˄%yuK7Xw^9㊾A&\!X;c-ޟh?;i奿;_͠= Azi6,!'w\93^w!f7hXRH[tKu:y@F{=igyϾ,(wDuǠu!7~“AkKxPJ 9"S*81eP48~Հ:Tr}i/^EIO8EZcYĹoT”~ۜ&<7""MV*v3nl"DqsPJ%3a sDJ;T*)%l E_/j+lwcPorhOu<Ŷ\+tPlSC#ha.Qeak~Yh,jx8`` +}(>E1}g}M[l)&'y̪?>G]PRi},3f-wxtMJdԌD>IoM18&T*ǔ1`0kvZ~(_Q߃4kЇx m4~8NR/E9|T  _EŶ|9(=&sҟ{>U|j`4]cM|S%T)~՝CX ;O?01nGgD,H̕G<`fu9^wfhDd%L`[T#SQ71)vT MECG\8s{OF` Px8vlh;tjiޮtYxS:Mv4?:G]zc*hyߖIϥMP3ɿ#>5ǬxIwl=JU sBwZh_hT|l> ;\W!OO`&۱" Wj)n,#T  ,˂,;&:8x<Ʌ|7y6q,Q0]eM:_bnEunNwk,86!Lzm~/>uͬRU$tv0Ð?J}_#U{&naVF KJ%șT2gmoEUcbk1{*6EZ 'lm3 QEfiz6 aX1Ӗ'z< '`YB%H67>ɛJܢgX[`_қ{: "IOHLi,MLztwj,v7j0'/nT$C:Uқ1oѼ'irDs"tM18+ޯ#.:|뱻TԗZdUnS[87on |e䁼!63^71N_8~H".=#:7*Y@˵<צr~kt}MDC5Zh1N~B=°ϤtxchvH[$|)w-[Turig!˹ls"v%܎m{I/kvVp]h- TfyML(UӼ >qR(e HB)+B!q͒4בv<p[^>\Uc,Z"]&VQڅ@m t>k B>y`ؖȞ.D&Tcז!}r{Z#Ddn;!v:fa*I&X6c?t+M{EkyhGCS`{ .=g=+=f%e…])Zo my: 1XF_@(,*hIxk޺Ad=G[ȊNY[3)@PMVu= }F KJUrT(2UE -DZ .|1Zyɇ1C ߵZw}-&eRB* &W[` doUH/vJ#"WD*oI@;˯[x$6Hi>#$BZ!)fYwPD^+"ȑ"r("w?<©ꫤe?%q {H/|WDK*OEH,ZPR>6 nG1nAY!n CoEBޒ!"Ⱦ"r\("eo꯯ m [{ј&8˰p369~vXdFrߞѻ29gGcOUiU>ADΤlFhjZ]cYja,"UG\~Ftp^ 1}ȼ64OB;B,u֎V;JRfUY=D#,1UZol~/"?,[)y~lCzS"*yiX^nO#J^O=Y{4pPy kp,cNiyB*ps3cppR+mN?,О|TfKl|/[B/u4`U Quʕ@hбq-˹}k*Gz|~±9$ol*1 70nacbVF}i=:ɢ/):|54sZA'oX(ܱP`YVyׯIwaNE"j3Pc!vOLLJN^ yD#, =/"HmDD48TgE{"gʀd!00wY7$"`.uf"8$.(Iܸygq7"dp~M*x!LҗxҲn1ZE 1iҽqo^PP2<sp~7 дIDATv>WWNq݁T;꣯n]JGWaNDbu7:j>`}%5"01++D̖Iz޾}ڠB:{lm>-pgݞFIq l74τ},D9y4J  $:8YDĔK>v$MN8`j"R8 DXNZ,Qݡ<"2+w7E6[Z.ܑ0X$ŘY U -ZEG |Dښޔ [aG|GN: y:vs'\P,sJ'KU<5N$;}TίBڱuV*ǻ~~]@_riNٗ!,4y6(P?D~YzwDZC~ {8s6 kySp{,"2@D^o׫U{~NkC-QLѵb u#}QlHy-qpބz؄αXO딅9x>y }dg%^fJdUMv#_+G!b!x(u۝>v\|U6҂"23٪ZDDrmypdG=n *U}ؓ`2<3} P!-4H y٪ߋgtB+߱rxێ":vx<0"2[EXi ZmI[%3,w}$ B~Xu,_GCwS91*[Y&9?yדG?̽7 i=>&ZusBDB< SptbPpwWqR8Ɨ,Hsfo"<5EH "[ȹ/=B85mj:Rr{Fc~k _H;rzgaݧv{p}L q&;8Ov$-Ȝ`d`,R7',LڗӯDdzT=zuoj?Yk8!ݜTvÒؑw ܲ ҂S$7<}_U9_O0 8$-ptʢl9^czfp&8Kҹo3՜ed)5Y"KKU;1bc գTs*XEɥ>o܊Ny*""Q6A,US=Ե7kߛ8t&fdGwc.>JzjIY3&;>SU=@DOZi9?AeA@Kp}4+C36jVO"f='-, &zLJ%#H dGNBXd\8aߝ?7$QV ʔPhr@!v.Gڪ&+jeȲ.?yToO"Dۗ"YzQ$~zNg֜eDdngct ;ޭ/1MpnMYTw4;b9wk pSvHtWg)޳ icE%8t ߛZĄ{^_Q[iL?0H7ؗu^"TU|J0#.0fQIG4[/Bi{8텩 Luhiڝ'=W-; :>϶Y- QDs?)K'"u\Y1j-Cw({Ģ-:OUy]ļ;-'s^f 㞟HckDd: RxUAFۯ(]GFֳ8,qHQhXezm|Yau<)ޝ2~ݝV9jشypdǪ|L9vpG;{eLM |?v0W7'ye} L<;D?ң.#a>2>5q~T m>mF_.y]st^>7"-_<ߍUNHD6s电&&OSv᝖ x޳1ʣ!ܷ~=Ρ)+ B۽o;B1?M?ߋd̗uFRAh=n$G G{WJiv \Gih!̓CqϚt"XT;lח~ey6%?a1Hg_x{6&'M K*&nihQL6f/~_@ab٣dLm˼A{^ .Ka E^<+޳=4{_(Hs`N=~k\_]Ďˍh tjWP׊^?hc%bʜ)ch}l7W!GꄼawDwGl׳|Ô87&{@ AާcctYlJ%Hیwn9ۧUO׮FJAQ" |6+(`)H/"37&xK&~|ݻ79y+6g+fdo܂[X M b|}9͔`OWm~^ ywTrn=+|t(ib2#L/͗eCH(I; Sntiy}iŕ7#l7}r?F .\rN /`Lfӵ:oy4ʏNH+aؼl,}̟~ʈ1q]1{^YNwxex0$rIy'+斂zN1G3!7aC>޹UUqŴE[@4NCL(LX5@  xJbbLL<@%!M XBAR(:&VBȰ|3g\v֗d휳/묽Z{pYvkyi pVG՞Sn &Xۭ ~/HIW'׷Y{OŌLXKHN<ꯟ$z`^&o'u^UI;Z\)Z[E|5F7S}c $)h`0t ҼQºy%6j-NFZ=Ϙjq38$ Qz~7IS_ȅr|)mY,HKyWE1(hakm9H%*<ߒſ̽S|6r og濆`wr5M 4hsk)It1_\υ#H;4M}wX'imPKjuʅ{ Ȧ<6bQ=)mcGNEV4ocFzsyC0Qំʠ)h1o$SdzW5| !EY=,|JҼ"hL-߀+c\ibwV0pCGChhxy)EwO=]ź4l4 Ӵh}Wa;{sP*k閛"szeHږ͑7%y~]'Z:׾־<K0͙2+dj!!Ιvo26:][ظA7$i.Ftmڙq!&.4lCZ!4ZBv ]6 8 G]^d ofcKQb!%㢋̬n--{%{cifuuQQ?]{Z9 zi4fmf[mKd\t R4-aRDjRNcBA3kP]Hx,pycf6ZX7q=%Y"t$t!RB+x)!=&â"fvC63?'ujXqhGh^[! i}}sH&Y^$̞N$qfdʏyqc|2Zi^v5{5? sgɴL>"<Կ9I4^oI\of ս^9~fr Pm{u値67}D zOYe4w=o10es%WO^luQQBr(zZ]Eu9fiU*983{! 8*;8LN888Uy>uqq_\88C@M׽uqqq\88‰!oV7v:2 gqqN_;8s|^v`,%݂yrqqN\88!uWoU^qX#AIKC?NAg39po83 !,@Sd(z` 8LFO1C3Yy';qgvp(0^䵮PrqV6?-s3+?V.V,]IENDB`PK 8a -Pictures/10000201000003ED000003BBB7D11F66.pngPNG  IHDR!esBIT|d pHYs.#.#x?vtEXtSoftwarewww.inkscape.org< IDATxw^EC @b@^RD"  k@@&HDJHH $1璛7gԷ;ryOٳ;;#8|i; q:xi7qYOVUwj>NDuqNg تK72- >4y -pf}ǙwKӇ"2,p$ZEqY&ȟf*{80Gmp1w"^͜V!Uѽ ѱ֭yzZ l+"5pMzkU8N#"ˤTݤZ"'Iq8݁\۵Z:Si…VբqR !"wTݯcRy7Uogg:+|)c^=Gs +a+Y, l.Ai> N3'p죪[v!"1AUj>,BZq"p!IơW/`[~a͹=#1ia.ۊȷUAcH݂$y_*Dd@{22hBDd$p#fl }2UP@\#𩔿?b]oDd'^ٸ7g tl?sFwȶzSvC G6kcI'Yi EUU@~) LD6Swy?~JKp2I&C߮ +e$QFب>8L`䜋Dkgq>͂&='jy\DbyboUulq !"GaR= 7@jӁS ODhQn&«ux``@9U#qGz*9vqjDU'%.k` !.OA94 .fHkQuD|WWYCDVDєO&חŸE,J|BU/[΁OьUC)C=L-'"f5YC`#2x7U5vm ɵb]:{@DaFHli(03L^$}[ErG`פ癞ÎyąE+:a˨CDf+""Cg(6aF~_""`'e vr3D5/nuB7oL^e{u`!w˭'Kud7(mդ},P-flɌoH~ ڧa1hގ w=ɀh`1O"pmRKft[``K`≠6_jvcHFG" 86~>RUR 2LDv*p{@"2/3?!5<!3oj1y8/smfhFt*In 8IܡS+)0ϱwK|U%|V1{E DJUuaݭI҈ؚpZ>fw껕LLmۚp7!<>F|ͥR$e 퉡-p0WЉ"7Lk,J' v_33Rt{1(r$}V'FrgwlŌS8~jU}`%Tu: 6reu7"~k<lݶU[ QkIXWVמ2p6QvQCYe e>L ?lۂ{/6S^TR=8V<5]3"&eƵ_ڜZR}8\A:XZ@ؤe؊Lնov^H*'O?i75EŐBٿK7N8 ܻ2K9pk.~%,^@0JW`<+CU?>jh3 VUBz)PqSj%lQT46[p9ulўt$)?AJ]\Ihl /Fr$ t;/"/xx WΧ} p yǬ{G7nzm^.]ؽ| 5? :HNoq553'8aKwEd]l5fDdT"'oPsya1!lAv&:~.4'0>饀EdLAO^.,F=q7lb5G'KƮՐ[DdgU)^]~;1ƉGY z}*[l߃j|gEd~l\%` h ,L84m4p"o-Nٲ}|/y-ڝL`oX&d"'ԏ v`߯fxd ]`ڭw䷄\8eR:Dxl%gAykއ.]JZ,TPlߕǚL"}+&k2`:ODt}8;cQ셻mkH[ k;`cxتuHelƈ}+ F 'qtn{7,)S${Cr>m'3tўavKqnPBfh)f%dQGF;ڗA zZkWD &B /n{)ylpSCڨ&gf aM1ڱN!WαJ檝 ʚjF;/jz+>ߊK[j!t=2G?Fm \bYp!dϋI= XN0ڏAf(԰Nv,R‰Ey{MIJXAo:h<$Bj}*C}JȌyyRAIIRd7h-87'o ȝFɲ7)y GaGu:`*E: SDNu}M'iBUr "`ٵ-eZN,$9p.ӊUugHV*>ӧa^ i!+*/,kY~N>D'AD6&{{p6'eOCse58ldiltאA?x $^@ }o0znAyp~;X\5B.y~,@rYN$ g k%@D }6~qȍ>w$nw!犢VV^DdG\U;c4Ҋd>ƒ鬀1<lRtap̍+"27uK׊UCf+KDüB|ʀ[-eˈOD6}XD؇Uu-ȋ,M8Ddh53U$/82+`y9;T*Uu  .!w3"2ᠠ`Iݖ%!-R#d7Hw9d.>HcY5,YpvרorԎ]NQ](͡HEXKuW @D6An#Dή04jWADPTdZ?`$r&[*l"V """Y+'={{r5ЦL\tc#OrZ׊LSIdp!՜NK6o\c]ÊVƀe $#7,mcvm#ʅ amED TOǼb렮qh/Ʉ_eYZIۍz1Rp 5*".uIzXWm@U_"Ŧ8V 7'X$կՓQ!ܷ^Gj!u=/aX %񠉭R[+g@x+ <1u_#bʁHUOU_CIYXܺEDB+ީ&έeKlqi " 鹫&kI<@XNDϒl?\䐺)5,& Zm_Vq;$-C:+̚GѷF{-rHJ>b{{' kWqc UU͝6c#u (JZ]c[Xf6&=5U=a:ō>w'*|/ X>Jq6;k`׉̋;Qx5RW|- H vVǵ(1b?DEU/Y# FTX>gYPDy`m%6[keN8nR.2rvBܟ^h'!hюCDơݖ4b:M@U]MU]~$hcjI_~]𜕈索z\nOXZ"ֳH#!naZLύ_:.y݊NSUdu1)WȰ:ň^7}2R7Dʮ@D>-"G%"D`#,8,zq\_f:A~+ye3_-RWo$ Z'h⫁wjM=L$A\OqJ,jo9H7],]MgB7ǬՊ,C˩U}8r1?ތ C7K,v_򪺶n+X,n[l =@dEQNjƠȝ>848&PbuDdpUGvKk˺oyr}>Kep8S$qle*C3ڌ VhUua VEdݷP$!N+-\GG;ht >6%wV)^7ڝ,,x`Wn';IQf[M}>M2P "2h3bŦ//Oo._8m}Q_g=m#J$EUo&dl*d3Nokn05^otU-!84(^oe'blౖG]BV1W IDATlr]@DŽ+ N# 51ɺY߂vH`.'}KR9dt]i'+K!pU5?Mb݄6tإNn˨Т f5ؽ3Ym16@hN&ٓ!#CKw3=︕vYxSZKmVwݶwynSI#IA*l ьLm 9ZI6Y}OEDdLD{-jE⫭(=4!1/>-l+荜2b*tjTU;#tJbm0o_'vm:>fz\ƶ\#{{F1؉=G1]H][Y]VS>hj,9Ml>+]VȨoў;~%rH_ZHhnLP[Al c[*Ed?\Rw;% .r-b{=LFD4FĞ՛ "8~@#פ"f9TM wacd\ " =jcוb\!vhxDDJq}[ԡ_j5jpR) ݏ 'MlNc5OPĩH>":{LdR&|cA櫩. |:*6қf"u~7CF9a+JLOKgL |h|Vb1F Z6&9iw˦\Y$BltOTuDŵDNs%΍~ɓ!"-q?N<~9XU}jl,"E܈Ⱥ@:jUQGsQhKN|(qlS#9qzM/(jjC*K : =`&v{.eVdQ_pIY[GV%e. L g熂2\Cj/ ʹ*9wʹ]HmX6,p@l[>[u]f k梑>R ʜ K&o:z z `r'd%ǹ |qFtxm`06(?7S](pb6^KiNu? OqwOƶθg' wBDg#nφ72f^VM6EKy-g۲5K+\%\D T?<(gN,"/,7&Pէ  ю!#{E}s}3I{Sd%ȔSբ!s)=@57Par ^^jx}R$]ٜGY ػ̉s }y='E/C]Γc>-JV'l9ڊ.uQ% 8U}wѼw2"*pU"("E%^mZzpr{s8sN~̸lGHUD㲲 o(";A膿MBU? W{Ddiҷg1|Ǡ/25Ҟ&&6jsraSdN6FRRf+ܡ5+^H_5c#Ԋ8E%d}=gti<Ɍscظⵙ#y~eWBրS;K2wJ +IaS 2V{z==Seش,YRQW\zJՕoGdGDs8glއzϜXFw5x8r}*!wܬ+V{s#`њL;U~+{,Lܛ׺ҞMأy*zb^SdhƺpY@r}y%BhiR4^b%kb%i>]R>FOVз)F{"{%lK%#4DIBrLFy۔q),GKa6'k-sb{ޓeK\QxJX;z'M>'ҶRÂSuK0,'dO'ܿ:ʸ?!Խlhg2=. Xl #C-DKa~+&Qo6]Tpk586"hXnCF<~dC3Xܽ"r [Rh,ṡKmKu20ܴ(?a5e{EE(J7>`6n{6'}M1kˌ >S o,;Fsr;v%/-,nn/l f4M!K|?Lӱ~e {3 ٱi:^9o(郯 s/LQ^ &gZ1/݁As̼oE+dx_JyZ~/UlC\9o*j%c:`Ȼ>9S` XV9o5f|6-E2[3`5tsO|`?#ME󆑾G4נ,M8m`A6H5صstD{sƻ3؏=? m[뫑w[1ϔ}y l\q?~[;aO0Oq {.\C Qq*}b' yAyKmJN .MId͏eJ+Bz9o9fܙWK|F{OT `Pͅ,t~s`>y3XA`E1yv֧~Q`cgS ^ *~}Z,-ؤJ8\]mVpN9Wo\Ds)V ':܎`k1G< 6xSk_.&a{N# @hn5\4:5vAɶ!wy҃Y7 [, 3 u`̘H3bp“d˃X67S֜Sߩ}qzbU&B0X6G0Y bג}HI㚿D6C ѳ`*w @턂&Q "s46!( bՠb%}ɹۤqNK:#q]wyWvJ]K-3P>:-˅5^BF{J3v ̻0#06ɵڠ6 H6joO$I.VݼIiX«Rb[6h3o|cQPV6t=|?zm77gm4TDDBdGQV̋!l_p8)ScƄDu2$a1ጥi .SL"=IMRl:X ^i?ldUcї F{ ̭0S>¢,V@5 )/Pm POXHU>)5"a<4F{-+dL=-O[q-Z&OBUFhkvl0kB2V&bFQ( 7ȹ (@lE؄p!J8ph }hV.SSC}+퉌O}JGNM7ړv2S& XfJޓDìr|ͺC| V$.FD6ܫ7‚IsWT17"2;Q0WߪS%&.Qsʞ,"C$͠?ˌkBY "[`6c^Q-Gz- <80WUڟ "3Uu~<[|}m+韴!\ZaU\J&k|CU*$IJ*Ui6a.طdHS'aWl"&rk=obgFc[Ŷત͏$Y(iCT"'ȢXS0xU}~iωMV~R{;U}.1Dd}ɑ<a7~D2l?t6o;S7I_9o+leQ>=16{k5q]Uʚ[sw-b[܇ϗj(Ym$vgOE0N`Q~ [0= F{$h.VR̅Mƌ2s/|TUgADb *0 X*؞u"27\E,؊C2V7\pGb|s[bNF$:Ez':tI:4>=Fq_g}|zsQlhIl_59{k$Lc{Q{?Ǝcm͘hˡػl&&`.Ob+*cAF`+ӱkfߤcW"2f4ñq@O<3 g3,hTVUozsPvI,6AOjr}dwq 6\ =22c<OaU V"@{FzxF1MĶ|&azftBDcZwFbA$9~U}Ez-}GƞMz oK[pqqqi~qO!" ۭ8ӿ 6~ }:y:N88] oڬGA"""[q 8xZD "88Xy MQ*)[Iy_UkNIDdYR`^즪nZN!ػZTuYKkTuUrDdOU}@7q=󀡽<{N\%,{ y8 XU'P'''"2XjE/"z͜&SX_DTkӦ:s`QDdSU>Jmo W:NCUgk9?~-".#׍vq6r)~egz/l^N{`ضNezcUur޶DD- ) VaKo/D e$zyCw"4OC6[?2sl_kע2=z8N{?N2zٖ_~ DzYz9CDNlT`U} *BU U= ēwuW '?HD6j$AUDdhwi"<,﫯:"_;tsڇ &q=͍g W Tr2P75"^N;jXD{cP3 srq= XiqVy DjDsZ fNjFgfvr4i37,Z7'%mU6Զ;!goN/"čvq#"{l]L[ٱ5oOjc!$0ŌgAU'PD'XviF{rPß;r]Dkoam}nDdy,"I _VȪЉn;4X(vرc?6ڇ K/ͳN=Uɒ*;%w_1<>k%" 69< E9lu6!364y w p~PM(;m N-F|OU+=S"2 {v6'=`d#oȍ}LU߯C,r{5c^vRˊ&$1ß[$KV8|\yZܢV & Xi ySvF;ŋ/^TaG娣Dd`Dgc@Ng 39mSs{ "^Wy>݄p{EzDl9ڞD}Cjme˨ f ͊: tbn=7&5C1WEt:ks*e``u s˞XRd9~Z; %(ps@cvq&!"slc0VpZr)E2'ZH+I4j"r,3 Y8ێc=XD86~G8}lPc(Y:E١Yyȡ dmQX8xXDGÎW4dDi`W 1-ױ QտFaDd+l4`DY"ԛ$U<+i< "M:X6"#fx94X2|INl }Ի1c"2 ;wMٓ2)z@>"lɫ kz$ƳFh`&\@ ibQA:dg+ X6z:g`o,:'c,؀U;Ed:u2jnŧG 8Dd>?XȗcE# | $0Wf%lހ倛4Ed,fJV"lR|8g9.HMصi$wteVtZŋ/ߢ?=ke\>>ďQ<Feӷ7bxl k 1ƥrr,.oc9S0o=!%lVu$frCo{"M"jV@{&|k~o1saBb\M.Bz{<ׯE50Tƻs%%JoIDWSug6}{ ,x?lUllƇqrWhoZh&؀.bzR3G8EhOs"m _DG ysc{eM6//h q<4P}YT{4bOuߨeg9%8,\ dlUTՇlR=?pny]1(I*|< \^QfiDdl;M;k, &# IUCOS!eX4M ¨s"2LY$UOEd$.F8WQ9_ގLcfOj!}M6̂85!"[`<J \vlwN{H rC"2@D\wz*YSU}`@[ TޯCj ^WEFpb)6?UȷiL&NB|^D,),XOc1*ŗI4nQ;*IƺM8[[ dikL<[VK*6mZƾn;Ԁ̍RQ^}Uƍя4?`q=+P`[iUDdeuPDvuwN"VU+~iX 9ᄷDԱ:ug 2:?⧪U y3cQ l^N!1~9d %VEdNU~79o9&,  Ue94o¹8 2pbF8N ^ {}bذaçb+KY9Qiz*"e`]US/"N'rkbyijX6؀s'2_KiDȡ@h*{jyY<R U}5Ȭt,RuOy$ّCҭ)`@jg.Rט9x:}E0f]I V"ٓx iB]{|Y>n~Gc['O8IVzs*hV[-jyRU-"_U_T߫ǃgY :QDJ!;%-x}io+XߓTۈv}./!"FUoTO*mNSTu^?›y&/S=;wجH(77OogEW^rj#1\Z#uז|g!\y|)}#u seMrz{GQՉ5߷o;:>pq:ð`p`J?VrӸ=d]uk<Ё1Uu|C`),=!c"YENH_ڶ0tLUo۝UDF$.ATC@jO'Kxt` UvKʜU}NǾ!7N#_eUdm!q5ݯV(OY;rȵ5 S)6GV0O4Zw>u|F8NET%`',26rT `=lYhy@X  m=FUIs33.\/"!4:1H]+ *`c+OȮMqH'JODxP!٠V}*eS%icf Ă4I`^ "Cj9쒌fbHY.{@8]aLI"Ʈu8@UUc#&{Oi{9&L*h_a ]}P?m< $wk?ϖiݰU+RUՕTun`uݿG5[izΕ$`^,rA/2WnDd$TDD`+!NDl ӈSF{iķe1ez"y,}bPsT;ΧN8Tit$<%t<^aȡXVC,鱗NV@ks,8"rl."N+$yH8uK*NĞ !Qs[m'q7hJ2a5G6v ^YlH}Vcm&6ֶP/Hҩq3"r 31yi=wrT?O:I0I/ X( %I(AP"""eiB -PI q&ٝ;{w9Irw̦RxiZ<^5 Ϣs@ViY]'f'ǥi>P."mF4!Q:]oK'3{ʼ^[>zh 7¶ZD{(TR`aV I`4*_UE31a{9Kl U16w5Z=ef?XAz#={WΛ~~Ҷj;]EUX9{8 ,y kiԞh^̀CFy(I9{lLMOH/^2kH 0[2MrI5{10:&:&&&l杮0Q꒖d·wGK&lJ78:xLF!kI3li)f-p|KnwsvUunI/3[ñ}J \w`5JiTҞws7"@TĒ b7}>{?eܸql/Xw>TLt2pJb)q~ˀoT֭G!3=+d ˆy5~ɝgUNJA#ٓfm1R"{G\92V0M+9~j]*SNؗlFŘ3a+Jvia^1 0杍pI#A3~nF;3cy;G^(ii3|g~f/+L. V6̡խW7ͬ-z>KvY] d=.X3WnlEI9r,rMW`}[Bz1T<^Z$Hfz4wd!)ӂ;#^8-Yv#jVI{ڿudFRJw/{}]D$6# 3KZVLe>j-Ԙiwx=d;5 )UҞoݓ6{X},w=)^p *q`7D*)Bx;G>"coTqg;9loOv2a7JJ~\pjs37Wa:[3+wr><wwkRΕ>P."$HYDJMe߻Po:gbMk/"-t=q>mfy(*(U3T` ๔5Qev)v=~HMj/7W=X`tsjoNwϓ;i_-Ǿ:tTӎ8-yGIH6f!!Y+mrNV/[(DgD Uk J4s.iw" v"N`C51f6W_SiZj_hd ?߇ w3e~vZr6DD&tA,x.y欙ruwlH)3JrjWҐk~&7+HxRE%""e$~F!V[L%z}6& Zr*kqn#sJөɤE }JY-)s*w"O"o*3ے^SS_WE|-NgS/7[q{{ܭ7m`fʳR9' &-PkθCTʹ}Lltu:""5I*S K=&<&q2d/w謹LsUmomVE!l}|S7%(5Iv_^&h3kt̖t[=m9B%c:z0-⍴!.D3tS*fHdGc4Q2za)]9%E+335),/g)/'|v3OܑJڋʻќ{t`2r} N-S."0x4s\hF֢D_ݧ>t=3;7{r,*YZw,FW$*Fa lf f7}ײs PZk; r1zsf` /I(OoNy%fj늘C IDATٲMwp{GwgrgOk'@DDՑ#w*'Tg4]E15ai{V¨fvpNG41-aE͒J7V:k[34U7;\h3;(WkW4rhj7ՋYUZkf{u6'L)ߨK*Wm??N&OB)}fտֆt2"~3qnjEt229=*lf~KW*6cnDwfLklY_fpit-Ъ#ϝMftsy`wl~HWlgOޣt|. "Xf,7zLJQSҞij1p0Q#rsn`:zm Hړ3w;Rsߣ?O+W+32Pnig]D]cWgNOC`bL }JP~0:Z$.)sjv@wְ~' 3…e=f.Wu%D80鄟UI%[FHj ')]0)HXýq ;? ܌œy_&tCmDžt34."=^R(DNz(֔0YKinv,ϥwM =Tilןv4ݫޣ8C{oGP͞\sj\dk94ͯlS~GXamYtI!Q9_7z:Hf$lEH෣BnEX ܙTh=U1w/MSAَ5JC(cf ֨F6;xϷdR+QnFJY5-5msVՇvbwU3$J W̎" 4g#F %ع̩CJk BLXG>xKKnެA(u%_%躈rI%Zo&{ݧ6-Hi9fa͒5㓒Wݽ\.,Y [כ݊Q3 ~*m79o&& |F&z Z;(Vna3 U#kgf,/Z."= 7GluU9Ǡ=bzK=W?d⧄RkEDD3[mhGi]Dzdj@LzL1: 'X ]LtGLT >ai˳ Sd_ofoz̿ 7֪Q."=}DD}]SOa=C>ݏ!:`3+؞`f?DDD$ ;&_e+Wi^H|ݧU>&:8ATw(YoGIޫ [ 8!N-n7g ؜DDDdT[S5]Dz 32@ԁ/CմFQK>+PN@^p=6}/ԙQ>Eo"l1Z T."=FR~H)^ըyLԛP4d'p/ObMUlPݐ|C|Maf+ ܖ:kBH"""ҁ= lޱVM&Z."=_t&쉟+|]Kcw"P:̀msie-Ls"2J/Js ;(iIq C+bbY`S/ʏkn5&Hn86lv<"""Rv)ZO󜦵kztkfaAw$KۘaM:59pibMlw9IzwO]v6pwPifvp?{JE2-}Ր$ _#3prw~EDDDEIt[fvMɡ>1*|=44” knf+z *4i*inF1o~C18x0&Z80b倛 LDDDHwo? 7J&ok(9'DDDD]DW?4F4*(Z& aWrNDDD$GZ."ݒ jDF(zEC|M*P]ogf$pzvDLt pa㐚 س@qB= q%~ӯHHafmc =0*3 gҁNHKloHfZ."݂jf6J]?$ɘhZ:plTx"""")igfKWžy%MTLo~#&Gg QDDD:/"mn[r~G5mcMn,aZ@\rl9`ujw%FE̛Qmž %:1I1Q}Z}Q^3^~OIOmE~czצ%qXafCWDDD,Mgf+#մ&Cfmlfw8uW}HDDDZi?w]MW'  <mq= K2&S|""""H81яk4<dmlfKG9'"""]Dڏfi-C52 ,35*2M S_ˣ_陔H[1,e3& ءI[sBũtdfOs } PZ."m#]1a?Ky \g_/<^nO4."m./9_WMۘh)´Et/\Y8%kc3[8wC|"""҃h]Dɖ%6aO\v?Ddm^ׁbroDDDD2H 39p QM{otoW?+P(kd_e}f5]EDD$vi+f6D'&Z,+([oGf-p7xݟ_4=^DڊO82y1Jإ~pOLtmLTvv/c:nJ#"Ҳ̬7;Ƭc-y{ط@ZYXé/u&"""݌FE~aLa]$owD27t"ιf|HK2/Z8c휵OuSrODDDMcf|>}xI'RAљ<3WDDDڏvi9f#CմM+OlDl")(PNlaC=z"ҊsWKs,ݞl5X̛ vYD>,7"wZb5"tf!,Kh;KZ>&;&O.C(PifrUDDDZvi''w%gSLpy#}GɟϚ)6]D6-9XgH,\-WG?WK i2-Ӂuմ Q4&%vsODDDZvi*3{Q~z5b@="~`W646~MαH)i2큟ë]D(ZF;Jvc8~}Hs(i}Te^ <*Po=w[K]?_zJED [] or("2 8@qN-քi^vODDDNjH2fv]?{V]yC1*t ,Rrxy`v2fxX;9tRmhK4-^zOsju7vvJyanUb(aep&hLz -&Ainf}/ VDDD]DJX;3-8kP"c記(SDw?gydiAJEl MtY46lT`"m?1Z9M2fv-C"""#%"U&'v14AW"sm<mnpxz|"XDD25wE`iw?;CӓH+&B-H>BHT=^DZVL(f&aI366a*:(i15/,mcbu5"6nhgyto?0G"""vi3[0diوDY ̮JNukODDD2ҔS]󵄄BuDHЇ}T)%1۵HR."pa_~SmØ?!Wb R5Gc3&%p[cd]D᠒!\W뗄CD8x6&b |[-BhM^"l5]L8agp>pl'Y'E^tb@/w(HEDDdJE$wf2at wG5mb~SڍM{Ypٲ?zy)ilE6\ U8Nk%yDDDvɍr9YDO}JD*xU@-lq1`DS{U'""" щHl3ffgi%TW.ҵV.pj<@IV.%$Àof(`ݼ0>&6k މHN4=^Djff"9>1ڄsdupxb.l` pΣ_DIvn/9tTb>6hDl"Rׁ} 勺#3{<}ݟ_DEk<~0սZG]- %&.&Zg_3Jo~EDD%"R53 \<}GT6&<lֈDKCHo3;8г}L=t'/"U1a9%OQ.],>&Z~ lx}t+JEZ _ jD70<i(^Wfp?W"""BITU&&Z0u`#c`V&YCiJE!i[6;iWw l?_'8vBt"R5ml JEzbDҁ?Ot}9'""H%7YDÁc8z%y'""ꔴ|{we3vq08נD-\ =&Z!kcwo<[H&2EDD%iyD`$`uw1Ѿe ODT(ź/B0 E`w[}HG{y}9̆D%" B1J9/_*3[(~EDDZv_^I+"ҙ-11OczG(–s"""݂Nj_^hitT<'Q<&Zξ<^ ٯHP.َ҃K=ˁE$"2 b_D&ٗwt8=`""JEzK]mØG$"2~'cu6vm sy"""-ODz(3 dXMۘhI`"aJHW T8#kc3[0;8FHHoW'.E t>q1цY$w4a7f;3n1 XDD^iLb݀x3_(N3[x!od4vZL8aZb͎ED$a_40X`DS?w3 NDD^/҃jfv..F ՁBLtfL4 kcwF 8DDDꥑv%vmވDDr<0@PKc3 838Z(i!r`Ci-JD#biythfoy)""R-Ml+MŅ(a )06&">#|jfԯH ,y<˫f|!Q41E1Ѡ:*x3:va\CjDdiG< \Li(i!l3`MLtE%"e8@㬍bgRBv)+&q5`Ś ʙ/rTDDVJE)3,!WvmeLt%Wi.P|/kd)WDDD)iFl/ ?_Mۘh[j""$`ځqY%χ_!sYDDt;f p_MhA`|#ci3(SO'fxX3QDD;%"BLt)_iA(RkɴOtJEzhk5;v̎Nzݷ#8T=^͙پf6~kf;ohpJED:301&Z)jJkztJ#"m6$tm]؈DD ?VtNDD%"m*{ X;94X'U>&'eŇљm\ 8>]DDDEA|!a\vZ -C"l kf Я9%"kS2=o8""=7 1^u3q/@!.NDDz0MiSf%OG7}L5bxݴ}fmhfÀ%VpW ODDڑv$&ZxXٱtSS# 3_d٪}Z!H;Q.҃Dg7;`ŗjilf>F"#>50ED)iiff(`Yw(KhSŋtEJ?^v<]c+K4=/"uD+r`8p]l)""ݘ.EڀWr({E$""| zW+2iyJEZ掦.}L# V8Yþ-!I8DDiMH3KU6&lDl""RO K.P-Gq28%"-̖'մN"$0@qBCG<R.l5ꏸմ426 Bݑ3 gӑ&Os;ODDLIH7iv,""Rck3r"R!:df}l-TcǢ]ؿw~icg6; >TLt|rplfS.b̀;lh1cHWl'p_Ԍ01;?.+DD4=^Řف%tմ ei>{> }YE^"mippb⌬Bk x+""|ii!f"m #: %>~ldꘙˏ,=F1FY2 AC3̖'Ti$%"{{U#,1Zq L|,xď$EDJ_QLאDp>]ݴ3$^;f2sk]zބDU%n3 NDDKIHk988,C# H2zfɸςOObʓue5-? A=3W/`@NHHV6)to;W[o~P>hpiI/# <J#"mdZvʭgOasHK[x0&:/&&f0{ld Ri2%"MdfKٟ̬`f+a&y%,+WcH{VcD[ߖV_.af+ЯAEO߫mL*,Z(ČgTV66pk@Pz<'$?/PRKf0\So(""HH|Tmۘp Jإe}:}RKo`GÃm '"DJĔz8+C_5(&˺`/jjHÁDDC6v{5 7fei"%"ͱpjD+'7$*&Zֳk@$">kYdw,{zffhH %"1<ﬦQLdя󊴲9ӝ)N#""ޘ蚘h]wᛁGnfi0}Њ4lw24=RciOgd+oXo/߻At+{b;}e6M\`f#rWDD*P.$>ݫD/0膘hN_]ZɁv.bf!fqֶɴU|E.e~LvIK] 53vUZvl)1bYw:33("s϶PD3ہ]J-Zx`p#biԦ@cð> JPx{%[^| x_ΣoJ#" ffeބjU(an7꧄]$KDDyLs?13;X""S.x{<~ؿچ16G$B?HKu19 <*""Q.x;4"v:"ZmUN~-́IAV]dMlehw%01!9:Si]v"0c# R$d}V58FD̆FWHKRUO>}Yo HD:ط@ʹhi0v9XD'HHΒƘٝLba9G&zj۟]"]h¨^`fk>aW^]t3 4V!NnKIHn `fr`ܣiAڟ]- Mtt8R|Uz]wŻ˓O> /<̎M@IHl`CCQ;klߨDZMMI{"t"M5`|Lf,r!lvll]$'fPTx~}1`D(Z2Wx;SbwiPD"'牡olVm#F0vX'|Ù4iܗNNsYy-"Ҏ4.멜CHƯ3?ٲe_vAjٟ][}ԉdH͌++M'ligJEr`f;Uf6jHzv (Qh{7[mgϟ|I;J/_mfY#iJEdfFɳX~.?2Vzv%"M7^s>~.˙g3f0rHfϞ֬7p4 3DDz%";Xƶ۾sô'޾lꢨ s9SdKڭ1xC%"օS\ve 2't&LO2}CnDD`f;ʣψf}N}toN6 nҏ_AH5>,]̙V~nϞ36ڈ3gfs][‰Hv]tE#\s͛gox)h];m&҆^A}%Y9rd} 13]H?,.?~?0lъtJE22.#_zy`,X7Hrrͳ||P쩾E+{mZWcJR޷RÝ8[6lǏ<oV733s1fs9FḐRHv{{ުU8#8묳 99Sz >F O`x {ض_M+&Y4 m"R CDE;RJ~5HHWBy'7nO=׋xxWwXٰsHe4 Zvb[AÇ{)eP#S디{NO svLܠ2>,yuq'aQ̩R=FvIi+]o'O[n˽iiie޼y~}|߻RەvCJ{-,RN[{Ϳm`aI9 Gy컴cB SN .Rg`Ԝ<|)_)fkceco`"tջyRJ5 ?cZ)#WM4ٳgsA;.~_ҸG)<;ݫS*1[0%L_zFŰZ>丛v4dKs[Gx9!"z?q4v ߽.sJ)_$D` ۵aTӤ]=# 7d /[o%;;{ff$Hzmlfՙծ8͋;XyJ5"22}X6z\PC+{rQ ,,rz( :jc QJJ1f.Kjn<?^xa hV*Ev>{)r_#*ah]olh*>$ 3T y^ z,MՈ?XGv'w͙<,"sEdǺ*TOӕv\ ^9}tf~PմJŝ%4-ta 1{tTY= cB>i`ETܲ 8F\EcJ)kdܽcLtw֔Rc+ ufͮ 5͑4d Fh4|Ii`ujڷ<~/Ig=9uo_jfOk p=exSyw=pn)eG2XDwxR*ƴ<^0"("`ی1c̝@ ^4F=UQzð:ӄ=!ؿ3\ O'ȀS(YZLš | ̵fXf5ƼL,Մ])4iWjG lm'cgπH^lٽW)'";dml!T둬Chȡ`a),R!1Jy!0ti_I,Q|aه{o<`uہƘzc̥Ƙ)Ƙ['"?Edg*T<^."R||ACc:.᭖8}Òf}镊_ˏUw{|XHƁkf^\i8IWY EVķ]VJֻdNObԜ  4|j/UH߷4X Yyj5Ϫ4aOw |m {{l+T_vzVX<=c蔊3XOXyp;98-R-MڕO 5yЙN A&^ȇrg~5:8gDRF==og?ǘgǼ]Qv}=-9ƏY46`O[NX'h cVv]eƧRv`cMnnmj_ %HXsA 峛\1Ӿ1ӫ =ɜĘg~v 3NV;Y~|%k/%V3< eiy %LQ8йghi3:&)]C"rP`c>t2]eWj | >à{UgTӾ%%3~ĠeX6I)H/Uv _J&/&dB[骀1^̫t]GƮor'eJ9ֲU=5t_Uңy' 3&d>?҄]c |n!ͫg4iW1S`0szRERߓMZWux667Ed?[&2l|)hLD,^0c6k6֐( 6 xKDnrNT?J9`c |!J9um}d{œͬ@w4a=9ٜNd4Ɖad_# v]J7L褚v(cSJҮ*",]P;ixVӶe=P2<,$Yz~ɚsj{R&0uA2zMc]_ƕR{+OJ!1k pq)5|z_xMAzRiž40IRF$0F*yPDRj4iW}ݏC?t@,^*+RDO^|cw}4ڞ}+Ȟg@E,)fùdNײx"t(ƚecE=x~T4/ P.9~,ܯۛd0B&Nv1f-0X 4BTGX>aW3URE}YU63'DLlNT5`+RNvu;}Ӏ1o{RѕvX{:z{c[WZOoP9ZJRJn>&y4[["{4RѤ])""2خ.UJEm'{Sf^;Sʩg'a?X}{gWSX &SC)'6u]'D#+D(TJ2>CD,BIw08?u\J'5AZVt?Laݕu,;R*mB"S>*d_߰fH+NbitV骻Rq* 50*bsDž좌^)շiҮGGNvr)4|:hdAׯ'e0BҦlUleWW> [zAWݕc%G6֍67;c+oa4iW}BיG]z󁓱]esXĦTWTӤ] _6*uwBg*~>=PdY=@w3o=-5RV [|RJEh2&uXcck"2MDDdiJ!S&D71:gci1 O!n&P|7}j"SzYyZ5m:F[$ 9Agpw`r9fwy'2|DuU*-fRx+߮a^.2ƔG3R*J1ƘiƘ.v!T Rh^*aȜb)og!&c~!U2aY+&XwXќ#s bNTѤ]g? +b,÷zw):7)>gl냍ԿrlD?p%ƚƘ- B(MU%""2Xk8p[ Rߊ(iw9-,ZN;I1|F>?=^Cu꺈Ǝ?K?ڕe~gc3Ƽ@hYxXmJ{U$"Ou=\mq|G,uMjحt^4fY?Exe̘Ht^,7ߠ(Ψ91H)ՍVRN/"r5l FT7bKn.@v`u;%cw-t,w;P)4iW@^8hc <""Ͼ&t[id*hYmXۥL`ri!ɌO뮨hȇsIȉ?R-.X.2d_4"JnW 1eS4Bq;d8XHކFBO$t 1NX=1J)]`3nFzXGy/,~}$v...lƘRDDR1;42\yR~x|Oc]}8N]dϤ7 rsL>q-UʀkYRjOh E~0x XD>DxvpWNw:!XRw/ :4^kϷP|#J) ?XkHϓDWQΩrA{R=*6cQJ9dQ&O?]vOEubc[ұ*gpjۻ %=`)|Ƙ7 N)wҮф]nѼ# {~IL'k/(a;1UvT4mXc7(>^hҮↈdȫ"ADNv;:^ BSJBgmIL.ϕL~1tz[|>\#Բx',t;a5p#p1^5-WqCDz3XkXĦڵ>Ə۞4?}Dݻ*t\d^K@>2M-v""@xG սe|J n'"B`4`C1s::gSJeGGP!,)&yhW^gW72b9uo~_RʕJM71&o]uRqJvխD ҰK{]`ORJ) gL2жӷQזV47Xz66\[hRaR;l nc3GʕrBU˺c;kcؔR*Ruom ?.ӅH#>lgŷ*騈xKj:4q/瓐k Jř6ExH0H26H觠nk~Ež <R*rFsk\'Cnˎy^FKvXbomw+O1dL >9>|B-:h]IˊNF5Ng TD:Rّ"mढ़.olc̆(SӤ]=`.1jRտƒݗ҄E]Pβchs>!GO3;1iIߍA¶goD؟I2BwBRD2XD~d]>)իiҮbND"c2cm `10블R*fÂ)崮qs9 s-utFWO^2W޾1@MT<ք=yX- im8Tn~SJY"080,6DzӮbJDǾTDn`Є])_SQži'1%5APu^pz3lO% 3\.("蔈h[g'Wa:tA8\|bcv1f18`0!&-ljAz{6֝6VD{c1;]>? 4iWR@h_48jHbcpqSJH5|QbKFɍ٧ngUgEvV<:O[@bq7x? +aôdߤPJu+pƲ#s!`kؗ)tO h16V*#CF26r+fXXRN Cofcʾ;UT؄<W@ڄDro5?,o(ƟkJ"A^Rʚ\`kwhҮ⊍upYOǡR;[:6~e7$&_h-|J02}%{b: ˎt/?7DR18LDFw[1뼘WxI6A Ti*\/.IO IU@aos TF>#ұ-ȧ#hp$i#ڷT^?/1D]&;HyFDNy"򐈸՘dwR)gLa ;u}fv ETl{ujL$\5kmG-SRGm#, B7^nz=K6쁺 kέaQUS?}S =_!6c6 cN!lٞPvR=Mv元~ *T\xs͋"(kbͼPMS mel}1ߣ>5_S?}J1gKm4tcc!)V?'"c UҤ]y N7ƴ:dcGRJŕlnϋi'bʾ@ײh]AA4HqO4iWxzʍr@N6@D{4iWQ3R11;cc%*Ort՘"}cWP1)oFǾ6L)g=1_qk<^> B'F1)""ShҮe^!֍Y7’r6}%8ҾKR=2ncZ1W*Pǧ4iWȅ }nX c[?RnaL{eWe_R Q A$rro$ YLi_]*":)=جIRH!Uv1cƘ{1q"׮)©&vA!JG)< %n:MHd Y1 jGOl%iaCnƗ٪{vN`o#gWn' D"|G"25y&ʭG1Q@k2J)ONdY1NIs|ès#NzhYIZwq?y'~$k2i!FV)` g4-vy{m!>Jn3xz*tLUaYQƧT4iWK1;kc%*}RJE!q11| ,3d׭w\)8#Q26!2l|)݀hZp}}D[ ve8)5հʈ (I:̟GK'DRФ]~^\bU:v*TwR*.-]Mu4/v]pTsU&SyPzWAMoY|=yO>lm](ڹ,6+WJu<)6  IDAT1 }_ GƧTD4iWc6Ų5>)T,$T>AaK>x^īґhrMJ$uD6u\-d]R#5/`A`kd @'d?78hǵ,6ZsJű v1s08("2\DtR**+W1ch6PY|rl#SJ;!EYFGy=(v}Ed<&h`aI9 _u{JGzn]6L)g=;'96ֿlncʻo("gZ=&jD'""zRJe!TvY.;FJSF'0ߓ?=U:Y|pkVK{v0NDMl6UC*hYJűc\3O~B[?̫iҮ9xm)51&Q)Tɞqx:k/fL(xIS}X7,RN{ol3T"i8 3w^Sw* Ylk54y ^QE^hҮvKDfzX s:s#SJ]4=)#f#M5,9|@Wݫo!PϜ6>w_iL^p[ ߨ fKll,odƘ 5v9Pa6,B;RJEMY9@ʈZ.P|Q%Kɞ᪻4`Vj~6Æv1prOpmt;?͟!%27mnc{:cRoCTjG9cW]킍5QJ)*Ys^[mt}zwU?)L ݾeB)ÀE6%nWݍ1cƘ1;|KEeӤ]ΰ2ƼdPXYvTJ)M#M*:/%E*sM̟XNͫtVxDK'&tw?ЏX*"cS)MծcVc1Ɯmqѵ/RNbj{/N"r<՟iҮ<ѵhӱ(T#:&7u4 `HȍWSI]=nzmi~)̷\c&o|q Xa|Ҥ] "9"' `CK)THXI{ۆNmW""۽ރ.t:j.!GΑvWJųv}kƘƘLny*"R,"ZӤ]}a6nX))ΟE Ɓb?^g̳y${u#2DPR*߻>9bYh < l6ȷ=Sq+Da:U(3/RJH7y)17i컬y.07{ CߵkR+e5Ń/uU{04iD$x 6NSiPJ)"$Wu.BcI,ǀSIE5ht qT6 ƺƊ ŝx9T?I =1@k|R>4~È?9 8%m a]9FRfWn*XV)%XF21B.>4՗iҮ>vGc̟]} RJpdwM{R7Kcsy{)b߭H]x@hxG6ol,5M t>p>F*>H T!ls(\0xs~"fx:u8wY1)sI:KkUIL_ wsͬ1,q;'p)KjJy9=Ò=&i6RWNۊt>f_A'v]ҿՙ {Ł 󊶸:~;d+bUwp1gT=F~FDrE`d)w::x"6){dTBO4 NK#ywϩb >J4(оUL_/꓊'Y}}_6*Ț k((o X2xH:-C1 > iψȓ:V~Sd5XhM^ocBg`ۧ:su&9GqSUۺN>Sp0c$&]/-]ꃬGbZJj Y {?uJZ>vg#Rnpv)eF2XDNcgƧzM9x%ҫƘ㜎y`J;jTnYUw*$_I޷R}OuWԱWcNJe_{M#ڹ4/`9:ȼ-n~L~̯®4-`7+غ~!~F>KQzN8~QJs%l`}֮fuc?zMp|:`1f6i6PNUKGuu) 3[3Â崮rpJ5{,?Ěk??y aD;{'Uhw³l^89pN)eoE;dsc6D;o߿rMHJŧ+Xq4/`ѕ|*[|¨r]WYT?rxᄈ+mfٱ{N*41bsRju\qKD"њ>Le&pp1 bRqh3,\N\W[?~+oׄ:8mtߛ<ArWYV^iw}SWj:k?B)Xlc͈b5]B&pys8jl8 k~\K峽+YߕIsi>/˿UJkgydo}R)#8]^#"ȇr;1SJpE)envvy1 QqXP Y0O$K:X峝 z)y6q,9|믮sWTIL$شVZUб5oWT]uW*Ν,q;Sg98 xTѕ>LD^71ooc=Д+Ϸj}0|4Oۗdh+=u\#%о޾)W6N]PDTꃬvuUŤ辽R{=\VJ=AbiGH&u鱮;rXؔ'om`õuwR%×,H 62HGU0&K`H_;YzX;@tޖMba߽ɳƩcwElJ7X~l%M =N2}Z"S?)tNTLm.(약>s/DcB1,v^s4iD!Kgcr2Mx`:a5T̉mx`?9G3#)N wQ;uoQF+݉^Xc+8ΘVϋݟ! "Ag{ TAOº18ZVtm19asUlηWJSRʪ#@D>]j.6<mpghX`Eإ7mg"6 ӫc>GFڤi;T¶'7Y_0b9??-@In~J*cSD>HDlo8Z{IwHX;R6-QvZR(P(-,2 MI؈ لleyqNHb^ɒ}>ӧ{}cl==ܦ~=qr =m!ǬMϘ}C6'nZgŵQRc3B:6`Y.̠4ɷxZM_G0l^k]j|Mm}FvCΡeCM^ȋE3R oCkX]l4pFOCXYZ];6ܑCɹ~+iffߞNq/ij]\CRI*yǦ2nܱҺ:#3ue?FY]໾ d6F􍥸&!!/ˣ# HnZ[[ SXJv@D;B$m6BK:T=k@^+CU55o(1b*+C9t'uS>E4ic19&MԳȃ)N&/>5^ay| OKfn ٲ<.&~$BRU埋fԵM]ZZk0yEHK(N^Z?kdw.X=6Q%UؕS1J/Ό~2hroGgNw1[r%V%bf_Z"m{K>A8')q1IX4eo& 5WFfj֬<7,pEȎ? $W3:A)u(?kV`_ ',&A{/|HD(ZG\ƒ ױY=uM%[R5 ?1퉕d1XHD',;9g(4g2CcZӏaP!="o/ U5OEP<7*x!w^|tޙRj 0çj_bqZWAF@) <-ہ:zp좗 6i=ʒ=c/'.I؀ &_ֿ4RbUErpx(&%豀_~3vE Sn*`(Fٙ4կFKsPBySoxp0:XkX ̷v*'?|~:Ń;py!zu„q'KfT'>(Yh|k/!P۔iX2vc,$sZnH +'fG_<fDB?KgTвGq )8)ktO{pet:Ek=Fk}z{JKR,]0%@Ew v9B$[( ;eb3Ǖ=HbWOA,h*P|VGF?Qg2®f9\] N&~RLBZ45GgH.ypk\w.m`Rj =] FhWD2; x$_TG杵/$\*# NL7`X۲La ٤0zOϦŃ&̷w6!&~T5s[#j,蕲=xp13zp!F7F T@#x=!D|dzp7:Xk88lk'";J `RЙt Q ؅uԚ:K F=Op &#S9X[h]-WbTڠ[rE1Tg+}`KWJ "iz!6Uu!9yy 3'3͕X-Z"{=뉪m,QڋkYoK ``< ZuZN)uRQ)RPW,v A{hpMV~ j݊HZ3>O9;06Cϲ.ȵ4ܝÄط~KiE^]١-ATAݻƏ(b3,kϋjKQp||_Y-횾xZ9?֛:/t>};  zP)ibzUDD):K>(KDžZ5k/xZqi b,k_Y3W3{ĸ0 }H =eӼβ=Ƹ7 )<}7!jEwDJ\ԽƲ~N5YO9Md]v؃R; 8 JwUC]>Yk4HZ襶ֵS ,%ⳌUWhH ҉$q;KmYR;/"gfGU_i%ԖxuҮi%^v݅H`i{{=Ͷq蚖7UdžɣkE.>!D26j`~#KX*<-pEDw@R~vD9cW[X~xj$8I1S?3ls}V} Y\]~*(- =A)JW:Xp IDATgt~,Mjl];ow>i,F]Z#ԬJo2ݔPN?ֽacbvӱ}keUPNt(A_xpY1zY~( eO?8N!N^fg홊-Eo ZvE2p-U!ZA\㵔FpM._b9&HPRc@:!B)GՄctzoZ>C)Q)RĪF'Zɠ_O}w Q 2>طHJp/C]$PUUk緲reS;q1{GW[0^j|٣Mf4܆+cjxi/jz {V O>o"DVe*t'{8 XY^B*VJݫ])e&peG!z7󪝊ءs_6MmA]R \/RH\xM6#ԻnD!(sxtE!Ϭ.4Q[/Hz#=6Cz(~qM)sJ>b#W=EC.12ރ{2jBzo6;_v; rj_{M:_NriKUFx&4 [.nx EbnmSN'[m`= +uA00𮻩w)twRâ[b򒠽F:ЃA8-iHDf/43:I+&6l`,ޫM{'C\Hc^*]o6FQ5i3;V\Q̧B^c<}(!YQΙ$hAJ]Z <ʕTK%D3H,بi`]=YLݮxm=K-y5կjMj#EY]F׽Ʋ*hb,=ƸRSy=BtK("0Z ![܏xp>[^L?s}=k9ЙwHyp *B ԌIN\kn5/5 a忚zYelR/ԄY4#2&;I1icbט%]v0W5~}Y5 &~\Dd9b$0`QFj>N|#pz Lt"iPJM!\)kC/hYB$S;9Խo \ Okm>(ɫpZ4{pᒄHHmΒtήLH w5+fY1XHTi]Ÿ31[V#|)8%-+6|2" ؅V5][04n#h M8JgJJR(K"vȟK~ڷ9^Rڝl)*C[ND%gg0b2>}Yz6>Ǎ+<57GWRltgK` IO7!DL^~ڃ;?yV>i`RjߨV$hjKLL{ 6A{0tT󆹖XYŷ|F* kLx]6m_>ɤJtK[{{<)n{Dۂ,;ѝw_GƗ".>`B0..ݫH_O02Ѓ{4GW$D0C>^*1|_n"-~KZ|_0,&/,&sgm)QPzIz7/G/no$ tFM ͷ;Tvp xBh/{p?]ht#`2p]bϓ=NRˑRQKYfBdi^f^9 szW[ Ց/qN&~\s9ڵ;ScӃ}wY;<崮&_. s!DN#~сZ؁@):U)5µƝsyyw~̰v9B$mHwv2˞1sk/0W-~5YO 0,&/*mjksH^Dz=ucY5s[Y~X6ƿ]Dqq!PۃEb!uN XA) O׫ u % DwڥqXESdG/gjMȘdU/~(m3n> `=_Ӻ&=d?ķWj6.eBnDxt NTJ`޸+ p?p:"t܊pZ}vG@S3M;#ȷelN&S}P 0"R=SejizV]6O11rD g=_.b+D qqbaO1XILx{hz~ͩCdLNd.ĚLV*+.k/u :.-vߑݜJ cꎿ:.aC2g:˜W bދ^!,pp%^|OR#m'wx}Zc+hw6ƁFIɧ6e·5+ZE(B#L- =<J)$݋(_R=$AŴ>0uzr5*dL7+B4/54UU33HpE;{m5hOcKx|To]dbŤ߱B$%ܗxpw^6"`Rjw;1#A{> 8!D˝igm1XIb ԄX{a;ނM5Ԙ~?'+셈ꗣkSnBBiܣvxzs+TJŭ=[@)uRvc=`YB:{p 4v\,'5DU ?_#6^UGZuRG:t$"Tv+(#T|Vc^-Ė.(B,Rv ݀Jâ\cD$hRx_+cb BtGA xf*PL6O4E\jWW.05?|lidjYfcy(ɈBw^]mCJR1)A{Rߺ-`8cjѬ>\Z|L</nQ՘ -W2Q{ +ypL)# ݁ѹN{pY"!zS ~pYF>ؤ*!\}epq-R;'IDɫ65I*ƼX@ bA!z)Ƌ$uoAwމ]$h]>1c,^C%.ReADjvXsV5K?<+6 ^|HjFȳ1n~#!ö@çΙ̙3ꫯذa)vWK.}OQS`:|Jkܧ.0!ؠҽ`];XÑ{Un WE5Gz6ߢ(ԪY++C9d{>fLd]O7o__lh0qoRj,PެpnwC>p{8!6ˍ6;rmLyϲvϬ@L4ӲY~g0A)!zm> '1|l)r3K!h]`Ѥ2Bͻn>ۃ#˗3|ϟOSS8 xC[hKnR`PKx9Vx8{,bH!,ht0?.Y\) ʨQ q0eq1mM2ΔgI`"z`ful{táJ`!0JòC*_5j C!''cy[ne̟? u֝rʖrSJB8:7 :k堛sBETZJ2nQu ʨ[);Lx8flg~h*$wV[ P^-ж.Yj'mQ2ۅƊDU^kήum7ߖÀ+b*!轶uk(,,d̙AE4GSS|e˖| ^? #J;˶fˆHiB$5&2f!΢ªzU?FGz=l^m~HkO+ys2H Sl3Z 7~vI%4J^$PfulKkR(bģy2o!DO Wd_<άY:u*Jua ꫯ1@g_+wH('WSjt?P:;SR݄HUtrF9BR$4 oTZ OKg󱫞z6Toxk)9)mϢR%z{˪ޘg*FX@);E\FLk׮;Ԙ]>?PkvE(n Ȉv,6*!Qj,3R{Z ~ZsXfdbEb6-d2o1,1Jɐ"Z4Pϖ{;m}i9"}1y_w]6oh]ITp7/Unʦ,կIUZ)pynA𽴊Y7@5=]LW~͒iZl.y,dd_Ț!H, _3n^B(ynOl嗄B\cA;> Zڮ #|ňHkB9e7|{9@Y?kd5klN{b{dߍn0w ]ɐs$e^$P&Ԥq|! f^9oޥx񿗀`i$hR|/ŰcG)oѧl W߾ſ`m98c/zj"jk=C1v^!X6ΚY<O NF=OxQ*BfQdLT5g@]PJ+?aИ1c8p%C=۹UqL4RF.pUo3++[ _E`S[Pe6FmgTع]`ɾe'[bRK! jʚskhd'3& wA)u;pyǧ\}?p=wj)$ENhmEPpb?M'ԨBԼJ٣MԽfIU)b+g1z6^AvR9p_u!|p+8 ~nʩL>E?B!Z>KL ޅϯ]kb=}'J}mZ iiixw'OQ_`0߻37n!ĮU~7*6IUuK#׆ljzwR;0gu_N̗>IK2)<=[,P&6@soTwzժ^j!'i=A!Hd_8n+훂'F.>B@J ڻPJe]s=w?Ckۉ]pO:p衇nGќ@/b{駟~0ʬ] JM:KTY { 7.mZ xJ;];sgXe~V^MR7grOa[EQ@ m_&Q.,\-B!Ď{{R۶]ĞV@vi˅v}'No{{cGjժAK} 5eNw1bI"Nj液Nrp^| wR 1`.i`*(`zk $h[ouv xgfFvVYYɂ M߸qcO*&}\P OM1k0|R۷_f>->}1:4[!Xsa ekϱ1m}??-|{bnWe1,3 B}Q)z1o;>XRKvPJ][3g|fZkk+}Ea8l^1I;k/iaruwpߘCs3v|+Ui-^Haq\t=Z s_x]TX8 YE':DӒBa2`_)J)8kIZkKzřv s s=?ضZh"ϟς imm{gLu29o(DA({M Ű[lK2xUV|_TN\Z|Ρ)y6jL+ek=s63x6c.buن+ !I,eR̈́SZ/]$ER|ML۾oSQQau*&YL$I"QZ5e6ΆhzwZʖ(E:&epF]b.,k?.}/8hp $s2b( T·?}Z8lLg?)"ϸ͋*ROځô^:$hW6``s:dggSUU2"1!ɑ~)D_ro#z&mYl߅0gQ hRficL8ܿu5|G:&|XE'Pb2ڷ42=B! `_AJc׻<+S,ҵN4p"sZ2&;E" 4-S&*j4EFIiqiGZApۘeq|EeemDzc&DS;0+B!Rx}fdR* P=0VkE ڿJڵ;S@Թ>/!c LtRNuu;:cһ:A ǧwTjlDZ ƾQHQkf7GTRVHF63ٕ3gO]I-w5pnC֪ !D46YޛߙK>u>@=_ҋ3R"3-'Bj^$hگlZ?Bx|^7Sn&#B75ey\;/^ R:a{!);?3N+B!z3bE)*WJ&AZEZihxꗣ3-~^|M^|҅[e5*I},4m?e=bEl%!"x}`bܭ@pKָ8 Hvt:^|{0MX!Ӿ)KU/(qI`Psb'@ 3n^!#Þ[?:,+!ZGx!J]Zlي,"A5V //Ko-[BskWȵ1ڨ:aƕ{~%Nge0uy ydžwݳ<.JgKZB>3-xxZK-[E$hu]>WZ5>NB(zbY k~WoL$Gk2|F2RCRw)fw A{|,|>:d^|~/ _Ysa-j`%dXppmwc=U/{ !I\/z#: pnƛqQn*𿝾45yƷ}RT|`hR(G ic{6|gU< 4B!v /y&;=D8ZGp¨xn!\hBnfO="JtM5V.soWVCj#/渭A!H[Ύ=ؿ޳hM1%A{iZZZ|\)5@)uR`3z-'|nJ䎑"^TcWNrHh5Sh19/`~M@UΨ* B!z@,N7X {{J* N|jI^t(>ΆOr_n^z+ƗQB!D/&ǮZV,($hO]>RP3y} xWSFB!^Tkb"!"a]WedRϢ ړ;}~,Rɼ{ÂB ,'9:ԪiZh|8^֜WcFd> e+B!R5pA4h_Z6s>HОĴYRj44B)u9x%?!DqL>c^+2&;xU8hgyGfnkkGzxZ*7|κ͝I߅;޼̏D%{l0ͼ;{}{ tJz^)LV{#i]I@?VudVv_Y{R*μbaA;]i\~H4,,ZصIXRJ °z_yA'˿Vի? `^1%,ag }K؉Sk's4aWJ)54gw@Af#^ma^wOSJ2 DGѦk5z_n1_ϊUP/02w|;i\ŏMbZRjP 9YDD s48(=(=JTrG3.w4tܚK-3>/laUtJ5],YAyY׊=@WٕRJ Y9$";_sa']iv @Dp3tR* E^:<Ƣ); ΓpfM+gu$E'ePzX}jzf&J)ftDdp?]iW#"Wq s9(=ىcb N)oZXw}ڒQpT:>1鋏MtNj_lvn*<:I"AϦ7vAf/J0˧=J)T9¾ ym p1 /W ckn-4 p6wJ%'[Yu|m1I$U&B0&~Ɣ")}bɌ -^-" ]eWJ)5h |vK;O=Ƙs ,iҮ>GD+ݚ53ֹ(x\JF6]aZwәxTXqP w8ZrF&!(wBZwҲ8Ddž00]I@LRJHDڄ$2f&:RI+0^t ÁcL-M go2<ռef7ў J%kά⁖dbyTšK- 2{yIt^6^jsi=(oXt-RJ)CXw,"zS]XOv刈J72J&zRlni0vH0\_frWS_Bޡi>DkKCl}3Onrl:E'g+_sZ4iW&"O{\8o7QNE誻R [pEx$$nO_$RM+Ʉ,ml;/w#cf2#͐e'RJ nm, ] #cL/%MUH>DeC4qe&R/5'ҹ%#b{P*X@_]P kNw^2<%$]~'@}o/}R#ʡ mER%mNSeƘ*#K[1 `,kaKcWJJS듞(`ګE}wn wߟg {!SXwe%mZSI˒PšR_ 9h *JrT|1Oz1wsOb>Tߨz 6йo3d1g}j yY|3h}Q|zR-9ayY>`.+̶W:$"Àֽd[ƘMڕk{aR 1~@*49pEJ) nhfn f CbOI.b?GϫOdG%$4Ƹ7IILSY{w(J)s}A"2ջ&S"pjc\.t`7)BW}[rG3yқw ŧe2gsKS+w O~}jHaɵT?P>')r;+s Z؎oDiOcN4IXW{\H|m7Q H=BT@]| IDAT;yڿ9*f 9wH6n>9ڿ9/r|,>Tᓣiz㇢3P>J)5@t[,"Á; &S"r'  XҙD[Jк8D]5aM@T }rӓIWRh]P ˄"85y ø4ؕܯ2/s_RJ)o MڕDd K@1&2Js9!R}"Tf j'=[H1wDX*ZzgH&i}3)IR#E]4-VBU''3>o,RS,d Ѥ]BD81u.tU^ͩR_f153!Ǧ3B" 7DX~@-bO؃° zV&)#gvo6"+0"YZ*R ^dÀӌ12MU,Ƙ ZVJ hO.^1Է& VM+HJd9$k2Ɵ7P` eRJm RJ9s DY0mXOkT_nER6D_7رwz$cNسJa'%=ϓ{ߛϬ%%yjlxRJMNȱlK\=iҮ"2d'>%@bsJvWt>{[rgsLsHrvƴd<lͷ6Q~+TX؎kHpWKոHMU2Ƽ\ vN ;baSJ)<!!]ngk.痂#ҘA13ع:TRs7Y؋] x=SQL&cL}X׀ XSJ N]5֞Sj;H.qȭ"U'`:da )9=v.m\3)fqƅ"l+T[r{_?hyڛmDUwȀ1ǵ<`ιqDEJc Ts#әמ]G- Lz!;K=e`5<렂!/!sw+J)|ExN "IDsNxt]+cLv {:`okE7Zk.OԠQb=)?{+{}#vgJD` ŤR*Ēc4a5]iWqEDr!_~dt3gxP)UйYeX@I$őVâtlpwZwU8չ%ҹt~˿O|o͟X<'dHgRʑp_7ݶzIv~N'"t {}CR T>+{0'+ Zp#:O]jWN{JRJY۳ź&*:xG,ljAlJn29]Y[sI-,N^e6OwPZ&J)Տ>aYDnyț=M%~C Hcg]F;!̣kά~2""fjEY|imf-*aĥو uxFoݤߊtn֤])Nb,Q>6hҮ)RE"r, x|R*5A=ͻ~v?E[4/tpmr>:&U.3[LSٰv~=}NvάWJ)+Xow 07j_h>]„/ߪ]glzoҟ BMtdv܄`{yᠹ\ڕRoaf1mD+_3Ƭ zND`L?]Ƙ/PF!D**PgaϬym~Q߬wGXј3Gе, ZZ k&8hTXw~= ov8H&<\Ч%>vW<9_u$yU>,&k7iidJZ:PdO oRC+Ni"79ۏ&j:Xu0? "-w5|ז5S~:09ַ bY5@dc51=3\V[Xwj$ѻU]9ɮ;+ڥπK}V~ :0I1K=kwu^ >8X|J F~ȺY:\uԻ=/ae %n;aZTL.Wݻ` ,ݽnWTW!z|RJ)n۶t@^Ӥ] ZƘ1:`$0ϟ)Ww[Lv|9XeannkYb ]XOW]Ը d-藣'ӼKڷJt1%nս˾Z6i{8柳6SJ)qW{msgsASiy"r2_Hy-V B`?S"Vj`2!ç~,tEf _vEX{v.wḽM찳]5)o3y2ܭb~UpKD2j;$`RJYv˱/tp1Fs}+"Myg=f+0 (<L-B%!έt}tX'1bY7ΛV9_뛒5]>Ʒw*m\̧6 '>^@ RJz>1 Dd8Pgi(&Үc^2.0P0O=!L~_v`u/ObE3w.VXEǸ;^)ԗΏucfM(%1HCc:\^FsD;nNuNgjeQ Lz7us*m_; a?<5Uw1Ot/V&Cm誉h7E Iyy DƴdZ¯Jg[صNuWc!&%<^)D<` c̿QFi p5p9M BX4?ߛOə^'Uoe}4kaå|w'ꡤ뛏ǮSvccCQAN!4IYRJi Nρ_^da/IR.Ⱦ=.=\bit3_suAxJ%G[1e@W]oQ|J&1]fuԿC~' |{+/Q~o3ov`<ܸ1=2(>9bݑ UT ,`"Ƙ+N&J "{owyp1#7sQ Z]P<̚s} 3_/pB9kvF cj2Wf3OK%?J$VM-7Q~Oܐd4]gRKkaI&z߻uq)5,:8cW)1(HGn細Cu˜T*$ 2/L!)+)fGc{`֏B]﷒2ozwzI$Ӱfƫ}OLP6WŊWz9Mػ}Wޤ {Ҥ])137^: u>Iҙq CB<3f$3b N:Kzk)#L& N "ۦM`87:Xo\MGӀQ)5(]pr ޓTiyR11ngÀriDύ9PL۪.k~uۭ Taeٌ2I]5Ir(_sKgQ7w{ݽn0lͿm%I0,F%Kdo؎]||d wU;edGT{vӤ])`hKMuܪDu)pL4YԽN.}. M"{^ yHisoXLdJf’^6z{ӬT[)#/f9=PJ)hrIq[1IR>ہlcq;gB{wcR}$nEH Gmq m[Y7~Cd=cWD+Ot&}N&=Ugg+,ǜ $S /Mڕ v_2:o}cK)̺ {`NJ~@*ºuT?UAf/J0+UG[ڸڿD0')>UJN=.c K9IR>DrQ*|& ؔRD Ǘ;Zm/i*B`6֞SG;j#L:ѿ=(@ Eh0#"=19:q/5![I՛o1,rLC\:j_l)a{G^[ga@حƘ KIRDDWgQ:x8(Req{UbB~W!?x׹9ҽ*,%o1\2'{YT:&_uwn=@2p~\%]u@GF`m,"~,N7ƴzrGvdmG_ 3[YnSJƟ7闍Ǎ<7UHa>U4<o/:w?lFߔqT *cɻR&J394s1+cR~u(U37s_w~=[liRdWPͰzmq5~y =wA9aAݓGQ^~}pIRq@Dr}Ƙ=c2Jȋ5NTUGX: md&=^@ޕ{Nj6?1so=U:{%=Wد rk8 ׇ;H*UwA3Ѳ NH۶k${NMڕS݉<_Ƙn*t8p-TJ֥!}pے,^͈rHUEX5'7Bcc2 Laas2HDJKM㐮+1M\z˼v}4ѮmUJS.xxu#Z ͯw=~O*a _,$TG1rN[ kNu^ =1J)]4avk4iW*c1g=;3fST^̧;2*&upa|8W6й%3¦h_ȴC}s|@0oCSh_{d|O+哷߻mwc^&$-W*0<Oc\ݹQz ђbSJ,T#kh^>uIK,R<{0+'%ml3?,-e*i]3'3b$ſc`/J0bJp, { Ddcػ7RjW-"Lba?GtIcSJ,$7(9-soic+dnlOݭheӍMv ' >af RH0gױJLx$ׄ=jX}$ IDAT[vse, ;13M+D`ڀ1t;gGCc O)Շjmc͏T:}J2GwHR L0 'p~Rzmj_h㓣kv,Y6n݅lIZ\B {Qj/{e}1F%MڕJ`"; 0fcLL](~)O~_{n=w;O3$3$onneLKfž&ō`~U9PfXdUv|N,~A[*%pM0㿉<0,Z%M| ŒwɚUq_ t褝i3,UjlS ѿ""pdVcLT]J2ƴc.fe=\0 x8 R}9 surжW 7vZ'@i C49ww4U޾uɵ||x5|mUI>"(@ns:HDN`[g>+J `"2?p nCR"TJeQ/JJ. 0$>i_y RMޭ9']iWj}ׁ;1K[FTJ7:t}# {^xL:=[|=4bј{J0w`$l|x.Ϩ`0\ׄ7ۙqIZZB0S+yq"28XhyTФ]O0)y(n]J). fh%^ 0xVK4Ur qu&hx^+"]eWDMڕ]Ht/ƘZ/.t?!>R*AtG~ZХ7&![pl1Fji惊ZX:_г2wOCAj B/MڕDdO`?Mċn(tcR }MϴQBw.n )S+Np|IgaM ^>`\)E^D`1f7J b"R ,D$<v}!5`a*H$F^s0ߟϐg= {|C G؀\`%YJ{k+p}80LR%8]iWjb=} eqաtEA+B4INt2lN,~WVb2$e!VRGη?LiPuNS{\:OϢRBv99 HqƘccyDMeൠp3]/fS1Lj g4F"2gEɀЯTY ia;*7o1hO#SB?i1wz\u^ ]`(QJ ^(aO +y)17lMؕG# {9=&$V)1f%p$pnbfawXW=D)k-ΟeŞtSa3؎[Inl8mꅛ-E.>OtƘ@IR cL7cƘ=cDIDtw#udکrwK!(&Ɔ+XwK,*v`Ѿ@cj1{c&>EvԮd3ȃ"xxRj1]"֏BlѓZXg%uIR*aevTvSJ튵ӀHd"`.p-LRޡ$u40>Γft3dmdJZǺR.2."svn4iWJʕY@SkӁZ! :`O`al)" :;MyͿiy? y-KB,ݫW5b:u])>&ለ FXtxfVz=WH_0kήg&1|rR [o;("-Ƙއ♮+:,cD \%CMi<4 dC\bAU9p."A.EdaxIRW"\'aD7sYksfςTJ%I y9i/R~w3o(`]?s2b(u'`_JʼnuD_ M}0+[ࣟJ)cj1mRbn Aeb/{1R*H_h_7Ѿ˧[-4,> v]H`ғLK!%~R|rV!eWݗ  tCs1"M/TJŃa=X*"la  6TqY6icxMPJqIoqRi^QB AZM%J|+ g=^gH -ǁ1Ʀ qzՍls`ٹ)KuDt|TB8R١1;"2DsDɻR})}J2-@\,wbpd79Užwp&J1 {0ǥ_j®Ҥ])V=^>}LfaX'xR|' (pu'c`mM,XN-{>`0|"RJncځ;%J+1fq˩kaH\GcG)?N`}˅"9%WPìc~G(ǮOζ]7}{1[;Ԁ{ڕR CDRvpc;^]F}/SJZY}z3{ݒ(q&'gT|z*U4 ;+ IR*H04OƘun-4 p|DR5'GU{{ U(8:3Z*rle%I!*J`]d Nlc}L +Y B Ƙ(=x]J)ⓣ]eBWR=0ȚShj9]5L+fR nw^d`0Ƙx4iWJ "d17Q 1ZLTˆ]Tm0`6!qIK"m\qIJ ߏ߫Ye92 -W'u:HD~NtVc^.,5hҮD<=ce2J2Ro5gyR.+}: !^ZBx-WD⫝̸ @reƘNSDvYQJ)1w{Kz\Nu^ 5e)R t|24zt C:WcGߘ R4av .MhҮ01~ppZ|`s*\`|1?ۡ7_Oy@vY }Jy ic7ċ^.-WJ "2yƘ C|*8 T<+\%;o*,v>Vqta'*R>%Z_v`1.,5PiҮD~vJcN@e$o"TJH652KJH_Rn1,ZNưcne%>DN ࡫DJbUEq3m[>PJ%@0,v_5ݞ-${74Jس0"Mؕnieb&a|tR+JABD%u/Y{SbG)?VjkUOwYKkX4>-*ZTL]YAVTaĥٔ^tK=Ѳ-NL, SQHvԠ""-k*NcܵeTZ@0RyA'5϶Qһ'ʾj|rq++Òs1- 瓵חV#"ADOXl&f5xiҮD$4ƴ6 ,aDWݧ{R߄4N?o9 ߎ- C,y=Sn1 ڥuճ/\ $r}nN\ ǥ1W:X j+ "~ly\eWںY)ȪP熒1]ڕƷ;X$ JĄ J @0Hh2/fc]-mDRQC&cWDaI!;fawZW-[]J}M:/va&JBհԺ&mtlJ_@2rӄ[> rCvz~e{]skGiRS-ϣHWa(5lYC{ۚxdE"eN;l"i"GAU1s:)>s8xf1a@)YO0fAd$ѽafw\afgީ*(U oa4.KJ*z)u,0( [4o>i]MBFavb!cRlV.1v0"8h \T?ΕT4.ca,eG wJ>m7mNOVDp=yFG8U}t #oBU'zf("-"]⎛ 8A:`SrlFg񷺮zF~|V9v5]`T"$DdOf%cJaFtYNjȡ 9'̷jf欰F>zx߾\ ]`촴Rd q:Ѹ10 #:;OȠbJ\ y4a0xVGqa99Jl;o6C SN~ MOD:CrhܘnCCu+eomsyd*E|kbu%sEg쌔q܄ꫯ8yq{w ݧߔ$FŔv0dU8WY U :^&5Y5ى5qJ0P5'^86[^vǜOrceԯa٘"~q? /d633Ջ>;vV9:/o”v0{xDD3YWp3^ϔ x+~Ffu7cxgQ5 #.R;fZ-'cƌo߾y̞V4i™gg}:X a Ul<\zI)ArW`V1c,U'N/г`bm:NǒYf40jחpΌj0'_clWUUŝwɆnȰa2UTT0l0yV^9N0aJaFQiz7p%F9N|(jܾϟɂdtRv .2wxp ie :2V+Z3ыt}e&Mb_8vW_q) "wFLLi7 èT%U=ZURե"r<'"'H7l$HNJ8db9|gϞvm:uc,aVwèNVҴp ŏ=F..*nСC` {JL-sD=z>FDLi7 è!Dd=`?~`YX Y_n㣻7rK IDATmڔznj2zLɬQ]ӂma.SY{thHzl.YfqiQYYɗ_~qo߾|g 80lu\҉ a3BDv-f_$ekE3Y01z;6liy :tiyKj?i,ff=èVf9o"v#0dfa kFqmcDžG}Ħn%\y\~q)s$천0`JaF ݀Q !\~; 9YwuꪫΝ 'G '3yElFnh-E4eg=n4.̬b93p,*y F%W0E?5p3si}.U ;7w40j·]ЯeI4v10&Xo={La7j a#D9p=_U뀋saO,-;>}hѢH;ԒGt0Mz~t&Uϵ^FwI+ڍb`Os5~`,#_T0 aJaF=BDR^Eoe.]0~x:w %Kj5jT$zJ5"0jf~tf Z&iu p}%H[:\Jzuu gQ1x0e@u5A-Un ;` a!Z݌tiڶ|ڙn4㶙DUYwsga:fi7 èG.%SQ蜵S}ݗ~iow̟??;kF#>Xè̟٭iF1]inbA:A8D=ppXF\nQPǕ_=8L:;v{]Z㎋7m+5dyS Ӫ{36z k ^C7-o %8X8F nQQ8}3;[֭wM"|ծ@5-0<]OjKq+ѱhr۔q0azܹs#ܶ-F}dsx MMl4hm$?IDZ?+FK3q l U&)Dd_`_!"8\.l VՏ%Q]#r~CUIyJ`9B ;8= 'Ya ֺ!a5ˊǶecڢ=Yp)F]llYz_Uvvf vr&&~ͭ0{.޸ؐshP_?7qڥ 6L/Ykk>|xQ^0jS؍w*0 <M*(̀py /7|z5p,BܼJ:rDKkrswp )gM(KѨ 8w ŋha~Kf$\ Dd8|!Po• K*(aQ?$"E2rb) 0SXa ܚA(nfaQBH{}QY:3raJaFca c}^$&H^?aFDM|~7㶎tt"c0 q* AR+U8&Hu/(`a20n'81P5\U.PQ4q?QMa1Pɪ8' | $AT0 swBBè4SZtf{Wk\ɥ$"~qQkY3wT"kl uEb=JUjAX| |3Jw߀o7V'"Xw͋iUw,"kyUZIDX˱ ΅OsU-*JnM͡?K3;ZReOwmWHgaXX㎛ 9qe0 0O^dߠN, "s^-Xܷ"=o a ?8kq_8̠`U%":&hpsV;"7\Ԝ| 8<noH\>_쪪giEqjZcll<ŹοrFzQgE=Ŋ{`>p)nΏ~ـ' U:"~8{s<[ oFξ^-; K*xٺla$_/4)a0j=2B^?U8*ԾVDN%\MaPGɴsE?n/z>ߩz#|GtNZFaPS8(+BoY.PջUSUoI8%,EK"LNăd*엨9aW]US#YKAD-w^9K<&"s weSp׊Lεqs(5V.5N ̡mHU깸);O{ToR: /502=С J7A\sX9u 0F/>"2 QהupJ'9?SBSeED:7~38'"] )u!X^)z%P gVO)6)"gad2SA\`ɴȍSs5[Φz-)nǹi<ꭷ:-ʛ$;08%SpWa'uqY8CUqa2sDZ#P5 "+ޫlܖFG,o*uɪp=:ah81A2;mq}sa;>g6+^A Z~ZiA s "!s TSAϙCU ggD{q:_ ]ɡrcUBJADz\S|E?uZ[;oʫl7.-Cp[;-["+ tkXvPIUT1UVUw QE$_Ĝ$H~9s0 0rW 7[qR,KvQ9TYBf }"ҿ$'B:aa 7l",U0j=>^ \듎2 .َyYH:uKp|1)FQYmO\ Hpr~aK䬭kNէ~B5{# uJ)̀33E3`(0jqspQY*^ ϡi1XҞUU9c -XTTIWR n+ 2 0K 'E]ߩbuGFM| c8 %-DX Fs>=h,lY/՝;6>aP% ̼R՟D.æÛ׈8\JADR qy/1(PW|A*=Ib 3k%iaK&gsF)M+*}  }J⨚-/^.%FIfJ8d]P|pv!s @P܈7^͖ND<j0ԋGȭ8φ"ҪP\$H>XIk,0 h e10< YiP~!HM#"{Z_˄Szcu @lTuNe_+/} ʲ["k9kȡdoħի/P= XvTS`2(1ArG%e_{a $n{_zCU.XQ;Ե@t$2Ry#ʧ3~1i[ a +Uj_\\ԃ@] 9tV=Saߩk#pnMW^`U@ Œa q;<  hJX`A܄"rkr UF(7z.h8N)e:Mx/}]:jS FPcPe-O-ArH j*K0 qzdԌA,OV }#"r "WCDB:EUF5_z-2(P|ұ"rW7s[HKBmBxG?W~K{jA@wuj/,I`ݫ{5xTA`723H*$H>v4 0<&H>]D L|S=44XP|\{%d0S`<L:jУ,N8BDZE;qh"nQ)毪UK(1h_ *-E$=NWx2T+sQ=p,q$''HsHa ?SL:tq Е'ȴB""Q^O |\>l\ MTD%qo|OeؤDUsJ8*bcsmq`JeZY"T.h檯I#s`ɛBLDz;UTU꺪zR0Á'"zŌ naQ8#Aش)/9UuAƆQhJv"._?SկOjaX|G>eWDv^⣪CUa<DdmKip!ͮ(/"[ҨK6$OsDu1W TQy!T)۽쏋l_PoqS^ε/CĹ  95AP@rP4 0<$(۽:2FmID:i]?ԤObͅ-*b-D$ey?>k~<ݸE=DpUͰ&(WpAJFDVŰҹN{z؈>l M:5'"r#"]\&k$0GɎ"H#"kb3JU'ۇ˗o#qn}q9;Ο AZ+^HGvo&")A ``r nnf#xUD.TՑ^|>弿/ |*"/2,[8eF9uOq{̷|Ig}ϟ'EޫJmg\-pQk>0Zg%pp쩪m#IZI; iaT3ӁKDUǗAèH>\j<"xŠp1 bq @Җ{|.,Ks|3" "+zO꡾8Ŵoj`tY # IGx7w~Gq Ev\+Kdw_Lzip  K1]U;q_v 2o@Հ̝G\@H/L]g"@`N^>C?zL) 8;bHx+P܂HkkG:r{Y)O~AD8ZU}Gs^;fCq sDU%1#""dz}|G}p^7%caF}Gvm:d2:E!W;1ƛS #9)9JK},oOU6?xλfD~ Wo?g 펳jYpUUu"̑]>Y][U {*Aȗpۧ|AO/X!9Tg tE{לTuʿc@F_ܠrR++ IDATwa> w})h\`qw1aB>dT"3wL2p[h^}H3sHD MyV /TRp77 0&/6DDNV.a!Z2>5j}| 62:w]P":k{Xh[FM!"mq8e}"5~!bUp.ٕ6n{,'Vwy +Uŧg1o蘔2+9jaF2 ]6[Ur guFau q~J*:/aQ H|p4~kۤTvh S 0:Ÿ@PIŮ8O0 x-A2J\ |&UTeu0 è׼ X&XeT$e0 èyfC0%cuau񳪮^ؕT(ҽԱ 0X @E\fCFCǔv0 N#"RX^\(Tn4~aϛ ԶQ00 èD\-QŌSIv\v0 zSm b naW.}#"3H@/5|a.(Fa \BF}v0 )y]]$J<aKy tI߁I"ұ܂F} 0zt JUG;n%@%4 0@ q:j@{_5QU-x(1KaQ/Q߀Jyz!0q$'H^_aqv v$a;na{DdM`w`]q+h 8+0 È{  Xe0a i 04$/ ܂x:DUgS8èOna4HD/AgxU_1UR"ya4hM0)aFDDBPNj8{3 h|l ii4 X :0 ÁCۗ2nh` \;0 #|`@\]D:ȍ"r7a0KaѠEh 짪r]IEOսO93 h ysN"/^הW,è0 hШcTE("[3vX`+܂HlQo ."GV3 cv0 ""ov8[U,fJ*6,ta& _$"+_߀Tuz3zKTEdoTGkR0]XX X LELԢxuX7P58JU(fJ*VKhQo8A򆸝D ࿁TuX2O}U/q.U=&OsfmcD) ~X"ùgtZ$~COU\ʸTo]8aQV Kvaq0;Ui߂PaSs "{/kM2"r"p_~Y[ygwc8cgf#"+}U/J*gmJ0  Y;[< cYնŠH32vT=,eSڍd?""7 B`sU6QY#TW`r^IK`rkQǸ@U+0-VPre4l=>?RS<u=^Ru"DbM-auρbwDCֆa޸x8x8 FRՑ+NFDΥc@U,;k|Q 𰈼""$AR$z#,aFm86ArqN"NxEDWpѐ0UO۞!#PUG˵-ʓs5TTjaY;0ZDz: 98]lau cw'`QS 0'kjC>^gy/ ou Q?d3"@Kf10 ~4T@ "/`0 $N,u<0b1-~Q}/ |V a3z6ǹT_Zd8YXZMI@W4`2%"R/ t. =H+Ӧ5 xKU(ᬊ| |m~苻?Zqsf~_o[=6{\s_s]>e2}UU;n9ֶk+-)ۥkYWsE^X?U9Q]pgڞQpV՝L>P՟kQjCUgNJqyKQY |#"ArH%R*Q. 0&HEcY{922yEny8e"O ltl\<[x;9O֋p|s4[ <\#2sEyߗ+"r pnTrkGPDY8l(pO˗k]s~WUu&[~wT5Ep2=UY ;W٪\W]ס@Y 2fpp.8>+dمjV"